diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 00000000..9610930c --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,84 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[override]] + name = "gopkg.in/fsnotify.v1" + source = "gopkg.in/fsnotify/fsnotify.v1" + +[[override]] + name = "github.com/pressly/sup" + version = "0.5.3" + +[[constraint]] + name = "github.com/onsi/ginkgo" + version = "1.4.0" + +[[constraint]] + branch = "master" + name = "github.com/jmoiron/sqlx" + +[[constraint]] + branch = "master" + name = "github.com/lib/pq" + +[[constraint]] + name = "github.com/sirupsen/logrus" + version = "1.2.0" + +[[constraint]] + name = "github.com/spf13/cobra" + version = "0.0.1" + +[[constraint]] + name = "github.com/ethereum/go-ethereum" + source = "github.com/vulcanize/go-ethereum" + branch = "rpc_statediffing" + +[[constraint]] + name = "github.com/vulcanize/eth-block-extractor" + branch = "pair_with_syncAndPublish" + +[[constraint]] + name = "github.com/ipfs/go-ipfs" + source = "github.com/vulcanize/go-ipfs" + branch = "postgres_update" + +[[override]] + name = "github.com/dgraph-io/badger" + revision = "0ce1d2e26af1ba8b8a72ea864145a3e1e3b382cd" + +[prune] + go-tests = true + unused-packages = true + + [[prune.project]] + name = "github.com/ethereum/go-ethereum" + unused-packages = false + + [[prune.project]] + name = "github.com/karalabe/hid" + unused-packages = false + + [[prune.project]] + name = "github.com/karalabe/usb" + unused-packages = false diff --git a/pkg/geth/blockchain.go b/pkg/geth/blockchain.go index f834654a..5226c938 100644 --- a/pkg/geth/blockchain.go +++ b/pkg/geth/blockchain.go @@ -150,6 +150,10 @@ func (blockChain *BlockChain) getPOAHeader(blockNumber int64) (header core.Heade if POAHeader.Number == nil { return header, ErrEmptyHeader } + time := POAHeader.Time.ToInt() + if time == nil { + time = big.NewInt(0) + } return blockChain.headerConverter.Convert(&types.Header{ ParentHash: POAHeader.ParentHash, UncleHash: POAHeader.UncleHash, diff --git a/pkg/geth/converters/common/header_converter.go b/pkg/geth/converters/common/header_converter.go index 1a66780f..fd883424 100644 --- a/pkg/geth/converters/common/header_converter.go +++ b/pkg/geth/converters/common/header_converter.go @@ -31,6 +31,7 @@ func (converter HeaderConverter) Convert(gethHeader *types.Header, blockHash str if err != nil { panic(err) } + strInt := strconv.FormatUint(gethHeader.Time, 10) coreHeader := core.Header{ Hash: blockHash, BlockNumber: gethHeader.Number.Int64(), diff --git a/vendor/bazil.org/fuse/.gitattributes b/vendor/bazil.org/fuse/.gitattributes new file mode 100644 index 00000000..b65f2a9f --- /dev/null +++ b/vendor/bazil.org/fuse/.gitattributes @@ -0,0 +1,2 @@ +*.go filter=gofmt +*.cgo filter=gofmt diff --git a/vendor/bazil.org/fuse/.gitignore b/vendor/bazil.org/fuse/.gitignore new file mode 100644 index 00000000..53589948 --- /dev/null +++ b/vendor/bazil.org/fuse/.gitignore @@ -0,0 +1,11 @@ +*~ +.#* +## the next line needs to start with a backslash to avoid looking like +## a comment +\#*# +.*.swp + +*.test + +/clockfs +/hellofs diff --git a/vendor/bazil.org/fuse/LICENSE b/vendor/bazil.org/fuse/LICENSE new file mode 100644 index 00000000..4ac7cd83 --- /dev/null +++ b/vendor/bazil.org/fuse/LICENSE @@ -0,0 +1,93 @@ +Copyright (c) 2013-2015 Tommi Virtanen. +Copyright (c) 2009, 2011, 2012 The Go Authors. +All rights reserved. + +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. + + + +The following included software components have additional copyright +notices and license terms that may differ from the above. + + +File fuse.go: + +// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c, +// which carries this notice: +// +// The files in this directory are subject to the following license. +// +// The author of this software is Russ Cox. +// +// Copyright (c) 2006 Russ Cox +// +// Permission to use, copy, modify, and distribute this software for any +// purpose without fee is hereby granted, provided that this entire notice +// is included in all copies of any software which is or includes a copy +// or modification of this software and in all copies of the supporting +// documentation for such software. +// +// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY +// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS +// FITNESS FOR ANY PARTICULAR PURPOSE. + + +File fuse_kernel.go: + +// Derived from FUSE's fuse_kernel.h +/* + This file defines the kernel interface of FUSE + Copyright (C) 2001-2007 Miklos Szeredi + + + This -- and only this -- header file may also be distributed under + the terms of the BSD Licence as follows: + + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. 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. + + THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. +*/ diff --git a/vendor/bazil.org/fuse/README.md b/vendor/bazil.org/fuse/README.md new file mode 100644 index 00000000..8c6d556e --- /dev/null +++ b/vendor/bazil.org/fuse/README.md @@ -0,0 +1,23 @@ +bazil.org/fuse -- Filesystems in Go +=================================== + +`bazil.org/fuse` is a Go library for writing FUSE userspace +filesystems. + +It is a from-scratch implementation of the kernel-userspace +communication protocol, and does not use the C library from the +project called FUSE. `bazil.org/fuse` embraces Go fully for safety and +ease of programming. + +Here’s how to get going: + + go get bazil.org/fuse + +Website: http://bazil.org/fuse/ + +Github repository: https://github.com/bazil/fuse + +API docs: http://godoc.org/bazil.org/fuse + +Our thanks to Russ Cox for his fuse library, which this project is +based on. diff --git a/vendor/bazil.org/fuse/buffer.go b/vendor/bazil.org/fuse/buffer.go new file mode 100644 index 00000000..bb1d2b77 --- /dev/null +++ b/vendor/bazil.org/fuse/buffer.go @@ -0,0 +1,35 @@ +package fuse + +import "unsafe" + +// buffer provides a mechanism for constructing a message from +// multiple segments. +type buffer []byte + +// alloc allocates size bytes and returns a pointer to the new +// segment. +func (w *buffer) alloc(size uintptr) unsafe.Pointer { + s := int(size) + if len(*w)+s > cap(*w) { + old := *w + *w = make([]byte, len(*w), 2*cap(*w)+s) + copy(*w, old) + } + l := len(*w) + *w = (*w)[:l+s] + return unsafe.Pointer(&(*w)[l]) +} + +// reset clears out the contents of the buffer. +func (w *buffer) reset() { + for i := range (*w)[:cap(*w)] { + (*w)[i] = 0 + } + *w = (*w)[:0] +} + +func newBuffer(extra uintptr) buffer { + const hdrSize = unsafe.Sizeof(outHeader{}) + buf := make(buffer, hdrSize, hdrSize+extra) + return buf +} diff --git a/vendor/bazil.org/fuse/debug.go b/vendor/bazil.org/fuse/debug.go new file mode 100644 index 00000000..be9f900d --- /dev/null +++ b/vendor/bazil.org/fuse/debug.go @@ -0,0 +1,21 @@ +package fuse + +import ( + "runtime" +) + +func stack() string { + buf := make([]byte, 1024) + return string(buf[:runtime.Stack(buf, false)]) +} + +func nop(msg interface{}) {} + +// Debug is called to output debug messages, including protocol +// traces. The default behavior is to do nothing. +// +// The messages have human-friendly string representations and are +// safe to marshal to JSON. +// +// Implementations must not retain msg. +var Debug func(msg interface{}) = nop diff --git a/vendor/bazil.org/fuse/error_darwin.go b/vendor/bazil.org/fuse/error_darwin.go new file mode 100644 index 00000000..a3fb89ca --- /dev/null +++ b/vendor/bazil.org/fuse/error_darwin.go @@ -0,0 +1,17 @@ +package fuse + +import ( + "syscall" +) + +const ( + ENOATTR = Errno(syscall.ENOATTR) +) + +const ( + errNoXattr = ENOATTR +) + +func init() { + errnoNames[errNoXattr] = "ENOATTR" +} diff --git a/vendor/bazil.org/fuse/error_freebsd.go b/vendor/bazil.org/fuse/error_freebsd.go new file mode 100644 index 00000000..c6ea6d6e --- /dev/null +++ b/vendor/bazil.org/fuse/error_freebsd.go @@ -0,0 +1,15 @@ +package fuse + +import "syscall" + +const ( + ENOATTR = Errno(syscall.ENOATTR) +) + +const ( + errNoXattr = ENOATTR +) + +func init() { + errnoNames[errNoXattr] = "ENOATTR" +} diff --git a/vendor/bazil.org/fuse/error_linux.go b/vendor/bazil.org/fuse/error_linux.go new file mode 100644 index 00000000..6f113e71 --- /dev/null +++ b/vendor/bazil.org/fuse/error_linux.go @@ -0,0 +1,17 @@ +package fuse + +import ( + "syscall" +) + +const ( + ENODATA = Errno(syscall.ENODATA) +) + +const ( + errNoXattr = ENODATA +) + +func init() { + errnoNames[errNoXattr] = "ENODATA" +} diff --git a/vendor/bazil.org/fuse/error_std.go b/vendor/bazil.org/fuse/error_std.go new file mode 100644 index 00000000..398f43fb --- /dev/null +++ b/vendor/bazil.org/fuse/error_std.go @@ -0,0 +1,31 @@ +package fuse + +// There is very little commonality in extended attribute errors +// across platforms. +// +// getxattr return value for "extended attribute does not exist" is +// ENOATTR on OS X, and ENODATA on Linux and apparently at least +// NetBSD. There may be a #define ENOATTR on Linux too, but the value +// is ENODATA in the actual syscalls. FreeBSD and OpenBSD have no +// ENODATA, only ENOATTR. ENOATTR is not in any of the standards, +// ENODATA exists but is only used for STREAMs. +// +// Each platform will define it a errNoXattr constant, and this file +// will enforce that it implements the right interfaces and hide the +// implementation. +// +// https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/getxattr.2.html +// http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013090.html +// http://mail-index.netbsd.org/tech-kern/2012/04/30/msg013097.html +// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +// http://www.freebsd.org/cgi/man.cgi?query=extattr_get_file&sektion=2 +// http://nixdoc.net/man-pages/openbsd/man2/extattr_get_file.2.html + +// ErrNoXattr is a platform-independent error value meaning the +// extended attribute was not found. It can be used to respond to +// GetxattrRequest and such. +const ErrNoXattr = errNoXattr + +var _ error = ErrNoXattr +var _ Errno = ErrNoXattr +var _ ErrorNumber = ErrNoXattr diff --git a/vendor/bazil.org/fuse/fs/serve.go b/vendor/bazil.org/fuse/fs/serve.go new file mode 100644 index 00000000..e9fc5659 --- /dev/null +++ b/vendor/bazil.org/fuse/fs/serve.go @@ -0,0 +1,1568 @@ +// FUSE service loop, for servers that wish to use it. + +package fs // import "bazil.org/fuse/fs" + +import ( + "encoding/binary" + "fmt" + "hash/fnv" + "io" + "log" + "reflect" + "runtime" + "strings" + "sync" + "time" + + "golang.org/x/net/context" +) + +import ( + "bytes" + + "bazil.org/fuse" + "bazil.org/fuse/fuseutil" +) + +const ( + attrValidTime = 1 * time.Minute + entryValidTime = 1 * time.Minute +) + +// TODO: FINISH DOCS + +// An FS is the interface required of a file system. +// +// Other FUSE requests can be handled by implementing methods from the +// FS* interfaces, for example FSStatfser. +type FS interface { + // Root is called to obtain the Node for the file system root. + Root() (Node, error) +} + +type FSStatfser interface { + // Statfs is called to obtain file system metadata. + // It should write that data to resp. + Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error +} + +type FSDestroyer interface { + // Destroy is called when the file system is shutting down. + // + // Linux only sends this request for block device backed (fuseblk) + // filesystems, to allow them to flush writes to disk before the + // unmount completes. + Destroy() +} + +type FSInodeGenerator interface { + // GenerateInode is called to pick a dynamic inode number when it + // would otherwise be 0. + // + // Not all filesystems bother tracking inodes, but FUSE requires + // the inode to be set, and fewer duplicates in general makes UNIX + // tools work better. + // + // Operations where the nodes may return 0 inodes include Getattr, + // Setattr and ReadDir. + // + // If FS does not implement FSInodeGenerator, GenerateDynamicInode + // is used. + // + // Implementing this is useful to e.g. constrain the range of + // inode values used for dynamic inodes. + GenerateInode(parentInode uint64, name string) uint64 +} + +// A Node is the interface required of a file or directory. +// See the documentation for type FS for general information +// pertaining to all methods. +// +// A Node must be usable as a map key, that is, it cannot be a +// function, map or slice. +// +// Other FUSE requests can be handled by implementing methods from the +// Node* interfaces, for example NodeOpener. +// +// Methods returning Node should take care to return the same Node +// when the result is logically the same instance. Without this, each +// Node will get a new NodeID, causing spurious cache invalidations, +// extra lookups and aliasing anomalies. This may not matter for a +// simple, read-only filesystem. +type Node interface { + // Attr fills attr with the standard metadata for the node. + // + // Fields with reasonable defaults are prepopulated. For example, + // all times are set to a fixed moment when the program started. + // + // If Inode is left as 0, a dynamic inode number is chosen. + // + // The result may be cached for the duration set in Valid. + Attr(ctx context.Context, attr *fuse.Attr) error +} + +type NodeGetattrer interface { + // Getattr obtains the standard metadata for the receiver. + // It should store that metadata in resp. + // + // If this method is not implemented, the attributes will be + // generated based on Attr(), with zero values filled in. + Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error +} + +type NodeSetattrer interface { + // Setattr sets the standard metadata for the receiver. + // + // Note, this is also used to communicate changes in the size of + // the file, outside of Writes. + // + // req.Valid is a bitmask of what fields are actually being set. + // For example, the method should not change the mode of the file + // unless req.Valid.Mode() is true. + Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error +} + +type NodeSymlinker interface { + // Symlink creates a new symbolic link in the receiver, which must be a directory. + // + // TODO is the above true about directories? + Symlink(ctx context.Context, req *fuse.SymlinkRequest) (Node, error) +} + +// This optional request will be called only for symbolic link nodes. +type NodeReadlinker interface { + // Readlink reads a symbolic link. + Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) +} + +type NodeLinker interface { + // Link creates a new directory entry in the receiver based on an + // existing Node. Receiver must be a directory. + Link(ctx context.Context, req *fuse.LinkRequest, old Node) (Node, error) +} + +type NodeRemover interface { + // Remove removes the entry with the given name from + // the receiver, which must be a directory. The entry to be removed + // may correspond to a file (unlink) or to a directory (rmdir). + Remove(ctx context.Context, req *fuse.RemoveRequest) error +} + +type NodeAccesser interface { + // Access checks whether the calling context has permission for + // the given operations on the receiver. If so, Access should + // return nil. If not, Access should return EPERM. + // + // Note that this call affects the result of the access(2) system + // call but not the open(2) system call. If Access is not + // implemented, the Node behaves as if it always returns nil + // (permission granted), relying on checks in Open instead. + Access(ctx context.Context, req *fuse.AccessRequest) error +} + +type NodeStringLookuper interface { + // Lookup looks up a specific entry in the receiver, + // which must be a directory. Lookup should return a Node + // corresponding to the entry. If the name does not exist in + // the directory, Lookup should return ENOENT. + // + // Lookup need not to handle the names "." and "..". + Lookup(ctx context.Context, name string) (Node, error) +} + +type NodeRequestLookuper interface { + // Lookup looks up a specific entry in the receiver. + // See NodeStringLookuper for more. + Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (Node, error) +} + +type NodeMkdirer interface { + Mkdir(ctx context.Context, req *fuse.MkdirRequest) (Node, error) +} + +type NodeOpener interface { + // Open opens the receiver. After a successful open, a client + // process has a file descriptor referring to this Handle. + // + // Open can also be also called on non-files. For example, + // directories are Opened for ReadDir or fchdir(2). + // + // If this method is not implemented, the open will always + // succeed, and the Node itself will be used as the Handle. + // + // XXX note about access. XXX OpenFlags. + Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (Handle, error) +} + +type NodeCreater interface { + // Create creates a new directory entry in the receiver, which + // must be a directory. + Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (Node, Handle, error) +} + +type NodeForgetter interface { + // Forget about this node. This node will not receive further + // method calls. + // + // Forget is not necessarily seen on unmount, as all nodes are + // implicitly forgotten as part part of the unmount. + Forget() +} + +type NodeRenamer interface { + Rename(ctx context.Context, req *fuse.RenameRequest, newDir Node) error +} + +type NodeMknoder interface { + Mknod(ctx context.Context, req *fuse.MknodRequest) (Node, error) +} + +// TODO this should be on Handle not Node +type NodeFsyncer interface { + Fsync(ctx context.Context, req *fuse.FsyncRequest) error +} + +type NodeGetxattrer interface { + // Getxattr gets an extended attribute by the given name from the + // node. + // + // If there is no xattr by that name, returns fuse.ErrNoXattr. + Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error +} + +type NodeListxattrer interface { + // Listxattr lists the extended attributes recorded for the node. + Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error +} + +type NodeSetxattrer interface { + // Setxattr sets an extended attribute with the given name and + // value for the node. + Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error +} + +type NodeRemovexattrer interface { + // Removexattr removes an extended attribute for the name. + // + // If there is no xattr by that name, returns fuse.ErrNoXattr. + Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error +} + +var startTime = time.Now() + +func nodeAttr(ctx context.Context, n Node, attr *fuse.Attr) error { + attr.Valid = attrValidTime + attr.Nlink = 1 + attr.Atime = startTime + attr.Mtime = startTime + attr.Ctime = startTime + attr.Crtime = startTime + if err := n.Attr(ctx, attr); err != nil { + return err + } + return nil +} + +// A Handle is the interface required of an opened file or directory. +// See the documentation for type FS for general information +// pertaining to all methods. +// +// Other FUSE requests can be handled by implementing methods from the +// Handle* interfaces. The most common to implement are HandleReader, +// HandleReadDirer, and HandleWriter. +// +// TODO implement methods: Getlk, Setlk, Setlkw +type Handle interface { +} + +type HandleFlusher interface { + // Flush is called each time the file or directory is closed. + // Because there can be multiple file descriptors referring to a + // single opened file, Flush can be called multiple times. + Flush(ctx context.Context, req *fuse.FlushRequest) error +} + +type HandleReadAller interface { + ReadAll(ctx context.Context) ([]byte, error) +} + +type HandleReadDirAller interface { + ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) +} + +type HandleReader interface { + // Read requests to read data from the handle. + // + // There is a page cache in the kernel that normally submits only + // page-aligned reads spanning one or more pages. However, you + // should not rely on this. To see individual requests as + // submitted by the file system clients, set OpenDirectIO. + // + // Note that reads beyond the size of the file as reported by Attr + // are not even attempted (except in OpenDirectIO mode). + Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error +} + +type HandleWriter interface { + // Write requests to write data into the handle at the given offset. + // Store the amount of data written in resp.Size. + // + // There is a writeback page cache in the kernel that normally submits + // only page-aligned writes spanning one or more pages. However, + // you should not rely on this. To see individual requests as + // submitted by the file system clients, set OpenDirectIO. + // + // Writes that grow the file are expected to update the file size + // (as seen through Attr). Note that file size changes are + // communicated also through Setattr. + Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error +} + +type HandleReleaser interface { + Release(ctx context.Context, req *fuse.ReleaseRequest) error +} + +type Config struct { + // Function to send debug log messages to. If nil, use fuse.Debug. + // Note that changing this or fuse.Debug may not affect existing + // calls to Serve. + // + // See fuse.Debug for the rules that log functions must follow. + Debug func(msg interface{}) + + // Function to put things into context for processing the request. + // The returned context must have ctx as its parent. + // + // Note that changing this may not affect existing calls to Serve. + // + // Must not retain req. + WithContext func(ctx context.Context, req fuse.Request) context.Context +} + +// New returns a new FUSE server ready to serve this kernel FUSE +// connection. +// +// Config may be nil. +func New(conn *fuse.Conn, config *Config) *Server { + s := &Server{ + conn: conn, + req: map[fuse.RequestID]*serveRequest{}, + nodeRef: map[Node]fuse.NodeID{}, + dynamicInode: GenerateDynamicInode, + } + if config != nil { + s.debug = config.Debug + s.context = config.WithContext + } + if s.debug == nil { + s.debug = fuse.Debug + } + return s +} + +type Server struct { + // set in New + conn *fuse.Conn + debug func(msg interface{}) + context func(ctx context.Context, req fuse.Request) context.Context + + // set once at Serve time + fs FS + dynamicInode func(parent uint64, name string) uint64 + + // state, protected by meta + meta sync.Mutex + req map[fuse.RequestID]*serveRequest + node []*serveNode + nodeRef map[Node]fuse.NodeID + handle []*serveHandle + freeNode []fuse.NodeID + freeHandle []fuse.HandleID + nodeGen uint64 + + // Used to ensure worker goroutines finish before Serve returns + wg sync.WaitGroup +} + +// Serve serves the FUSE connection by making calls to the methods +// of fs and the Nodes and Handles it makes available. It returns only +// when the connection has been closed or an unexpected error occurs. +func (s *Server) Serve(fs FS) error { + defer s.wg.Wait() // Wait for worker goroutines to complete before return + + s.fs = fs + if dyn, ok := fs.(FSInodeGenerator); ok { + s.dynamicInode = dyn.GenerateInode + } + + root, err := fs.Root() + if err != nil { + return fmt.Errorf("cannot obtain root node: %v", err) + } + // Recognize the root node if it's ever returned from Lookup, + // passed to Invalidate, etc. + s.nodeRef[root] = 1 + s.node = append(s.node, nil, &serveNode{ + inode: 1, + generation: s.nodeGen, + node: root, + refs: 1, + }) + s.handle = append(s.handle, nil) + + for { + req, err := s.conn.ReadRequest() + if err != nil { + if err == io.EOF { + break + } + return err + } + + s.wg.Add(1) + go func() { + defer s.wg.Done() + s.serve(req) + }() + } + return nil +} + +// Serve serves a FUSE connection with the default settings. See +// Server.Serve. +func Serve(c *fuse.Conn, fs FS) error { + server := New(c, nil) + return server.Serve(fs) +} + +type nothing struct{} + +type serveRequest struct { + Request fuse.Request + cancel func() +} + +type serveNode struct { + inode uint64 + generation uint64 + node Node + refs uint64 + + // Delay freeing the NodeID until waitgroup is done. This allows + // using the NodeID for short periods of time without holding the + // Server.meta lock. + // + // Rules: + // + // - hold Server.meta while calling wg.Add, then unlock + // - do NOT try to reacquire Server.meta + wg sync.WaitGroup +} + +func (sn *serveNode) attr(ctx context.Context, attr *fuse.Attr) error { + err := nodeAttr(ctx, sn.node, attr) + if attr.Inode == 0 { + attr.Inode = sn.inode + } + return err +} + +type serveHandle struct { + handle Handle + readData []byte + nodeID fuse.NodeID +} + +// NodeRef is deprecated. It remains here to decrease code churn on +// FUSE library users. You may remove it from your program now; +// returning the same Node values are now recognized automatically, +// without needing NodeRef. +type NodeRef struct{} + +func (c *Server) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64) { + c.meta.Lock() + defer c.meta.Unlock() + + if id, ok := c.nodeRef[node]; ok { + sn := c.node[id] + sn.refs++ + return id, sn.generation + } + + sn := &serveNode{inode: inode, node: node, refs: 1} + if n := len(c.freeNode); n > 0 { + id = c.freeNode[n-1] + c.freeNode = c.freeNode[:n-1] + c.node[id] = sn + c.nodeGen++ + } else { + id = fuse.NodeID(len(c.node)) + c.node = append(c.node, sn) + } + sn.generation = c.nodeGen + c.nodeRef[node] = id + return id, sn.generation +} + +func (c *Server) saveHandle(handle Handle, nodeID fuse.NodeID) (id fuse.HandleID) { + c.meta.Lock() + shandle := &serveHandle{handle: handle, nodeID: nodeID} + if n := len(c.freeHandle); n > 0 { + id = c.freeHandle[n-1] + c.freeHandle = c.freeHandle[:n-1] + c.handle[id] = shandle + } else { + id = fuse.HandleID(len(c.handle)) + c.handle = append(c.handle, shandle) + } + c.meta.Unlock() + return +} + +type nodeRefcountDropBug struct { + N uint64 + Refs uint64 + Node fuse.NodeID +} + +func (n *nodeRefcountDropBug) String() string { + return fmt.Sprintf("bug: trying to drop %d of %d references to %v", n.N, n.Refs, n.Node) +} + +func (c *Server) dropNode(id fuse.NodeID, n uint64) (forget bool) { + c.meta.Lock() + defer c.meta.Unlock() + snode := c.node[id] + + if snode == nil { + // this should only happen if refcounts kernel<->us disagree + // *and* two ForgetRequests for the same node race each other; + // this indicates a bug somewhere + c.debug(nodeRefcountDropBug{N: n, Node: id}) + + // we may end up triggering Forget twice, but that's better + // than not even once, and that's the best we can do + return true + } + + if n > snode.refs { + c.debug(nodeRefcountDropBug{N: n, Refs: snode.refs, Node: id}) + n = snode.refs + } + + snode.refs -= n + if snode.refs == 0 { + snode.wg.Wait() + c.node[id] = nil + delete(c.nodeRef, snode.node) + c.freeNode = append(c.freeNode, id) + return true + } + return false +} + +func (c *Server) dropHandle(id fuse.HandleID) { + c.meta.Lock() + c.handle[id] = nil + c.freeHandle = append(c.freeHandle, id) + c.meta.Unlock() +} + +type missingHandle struct { + Handle fuse.HandleID + MaxHandle fuse.HandleID +} + +func (m missingHandle) String() string { + return fmt.Sprint("missing handle: ", m.Handle, m.MaxHandle) +} + +// Returns nil for invalid handles. +func (c *Server) getHandle(id fuse.HandleID) (shandle *serveHandle) { + c.meta.Lock() + defer c.meta.Unlock() + if id < fuse.HandleID(len(c.handle)) { + shandle = c.handle[uint(id)] + } + if shandle == nil { + c.debug(missingHandle{ + Handle: id, + MaxHandle: fuse.HandleID(len(c.handle)), + }) + } + return +} + +type request struct { + Op string + Request *fuse.Header + In interface{} `json:",omitempty"` +} + +func (r request) String() string { + return fmt.Sprintf("<- %s", r.In) +} + +type logResponseHeader struct { + ID fuse.RequestID +} + +func (m logResponseHeader) String() string { + return fmt.Sprintf("ID=%v", m.ID) +} + +type response struct { + Op string + Request logResponseHeader + Out interface{} `json:",omitempty"` + // Errno contains the errno value as a string, for example "EPERM". + Errno string `json:",omitempty"` + // Error may contain a free form error message. + Error string `json:",omitempty"` +} + +func (r response) errstr() string { + s := r.Errno + if r.Error != "" { + // prefix the errno constant to the long form message + s = s + ": " + r.Error + } + return s +} + +func (r response) String() string { + switch { + case r.Errno != "" && r.Out != nil: + return fmt.Sprintf("-> [%v] %v error=%s", r.Request, r.Out, r.errstr()) + case r.Errno != "": + return fmt.Sprintf("-> [%v] %s error=%s", r.Request, r.Op, r.errstr()) + case r.Out != nil: + // make sure (seemingly) empty values are readable + switch r.Out.(type) { + case string: + return fmt.Sprintf("-> [%v] %s %q", r.Request, r.Op, r.Out) + case []byte: + return fmt.Sprintf("-> [%v] %s [% x]", r.Request, r.Op, r.Out) + default: + return fmt.Sprintf("-> [%v] %v", r.Request, r.Out) + } + default: + return fmt.Sprintf("-> [%v] %s", r.Request, r.Op) + } +} + +type notification struct { + Op string + Node fuse.NodeID + Out interface{} `json:",omitempty"` + Err string `json:",omitempty"` +} + +func (n notification) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "=> %s %v", n.Op, n.Node) + if n.Out != nil { + // make sure (seemingly) empty values are readable + switch n.Out.(type) { + case string: + fmt.Fprintf(&buf, " %q", n.Out) + case []byte: + fmt.Fprintf(&buf, " [% x]", n.Out) + default: + fmt.Fprintf(&buf, " %s", n.Out) + } + } + if n.Err != "" { + fmt.Fprintf(&buf, " Err:%v", n.Err) + } + return buf.String() +} + +type logMissingNode struct { + MaxNode fuse.NodeID +} + +func opName(req fuse.Request) string { + t := reflect.Indirect(reflect.ValueOf(req)).Type() + s := t.Name() + s = strings.TrimSuffix(s, "Request") + return s +} + +type logLinkRequestOldNodeNotFound struct { + Request *fuse.Header + In *fuse.LinkRequest +} + +func (m *logLinkRequestOldNodeNotFound) String() string { + return fmt.Sprintf("In LinkRequest (request %v), node %d not found", m.Request.Hdr().ID, m.In.OldNode) +} + +type renameNewDirNodeNotFound struct { + Request *fuse.Header + In *fuse.RenameRequest +} + +func (m *renameNewDirNodeNotFound) String() string { + return fmt.Sprintf("In RenameRequest (request %v), node %d not found", m.Request.Hdr().ID, m.In.NewDir) +} + +type handlerPanickedError struct { + Request interface{} + Err interface{} +} + +var _ error = handlerPanickedError{} + +func (h handlerPanickedError) Error() string { + return fmt.Sprintf("handler panicked: %v", h.Err) +} + +var _ fuse.ErrorNumber = handlerPanickedError{} + +func (h handlerPanickedError) Errno() fuse.Errno { + if err, ok := h.Err.(fuse.ErrorNumber); ok { + return err.Errno() + } + return fuse.DefaultErrno +} + +// handlerTerminatedError happens when a handler terminates itself +// with runtime.Goexit. This is most commonly because of incorrect use +// of testing.TB.FailNow, typically via t.Fatal. +type handlerTerminatedError struct { + Request interface{} +} + +var _ error = handlerTerminatedError{} + +func (h handlerTerminatedError) Error() string { + return fmt.Sprintf("handler terminated (called runtime.Goexit)") +} + +var _ fuse.ErrorNumber = handlerTerminatedError{} + +func (h handlerTerminatedError) Errno() fuse.Errno { + return fuse.DefaultErrno +} + +type handleNotReaderError struct { + handle Handle +} + +var _ error = handleNotReaderError{} + +func (e handleNotReaderError) Error() string { + return fmt.Sprintf("handle has no Read: %T", e.handle) +} + +var _ fuse.ErrorNumber = handleNotReaderError{} + +func (e handleNotReaderError) Errno() fuse.Errno { + return fuse.ENOTSUP +} + +func initLookupResponse(s *fuse.LookupResponse) { + s.EntryValid = entryValidTime +} + +func (c *Server) serve(r fuse.Request) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + parentCtx := ctx + if c.context != nil { + ctx = c.context(ctx, r) + } + + req := &serveRequest{Request: r, cancel: cancel} + + c.debug(request{ + Op: opName(r), + Request: r.Hdr(), + In: r, + }) + var node Node + var snode *serveNode + c.meta.Lock() + hdr := r.Hdr() + if id := hdr.Node; id != 0 { + if id < fuse.NodeID(len(c.node)) { + snode = c.node[uint(id)] + } + if snode == nil { + c.meta.Unlock() + c.debug(response{ + Op: opName(r), + Request: logResponseHeader{ID: hdr.ID}, + Error: fuse.ESTALE.ErrnoName(), + // this is the only place that sets both Error and + // Out; not sure if i want to do that; might get rid + // of len(c.node) things altogether + Out: logMissingNode{ + MaxNode: fuse.NodeID(len(c.node)), + }, + }) + r.RespondError(fuse.ESTALE) + return + } + node = snode.node + } + if c.req[hdr.ID] != nil { + // This happens with OSXFUSE. Assume it's okay and + // that we'll never see an interrupt for this one. + // Otherwise everything wedges. TODO: Report to OSXFUSE? + // + // TODO this might have been because of missing done() calls + } else { + c.req[hdr.ID] = req + } + c.meta.Unlock() + + // Call this before responding. + // After responding is too late: we might get another request + // with the same ID and be very confused. + done := func(resp interface{}) { + msg := response{ + Op: opName(r), + Request: logResponseHeader{ID: hdr.ID}, + } + if err, ok := resp.(error); ok { + msg.Error = err.Error() + if ferr, ok := err.(fuse.ErrorNumber); ok { + errno := ferr.Errno() + msg.Errno = errno.ErrnoName() + if errno == err { + // it's just a fuse.Errno with no extra detail; + // skip the textual message for log readability + msg.Error = "" + } + } else { + msg.Errno = fuse.DefaultErrno.ErrnoName() + } + } else { + msg.Out = resp + } + c.debug(msg) + + c.meta.Lock() + delete(c.req, hdr.ID) + c.meta.Unlock() + } + + var responded bool + defer func() { + if rec := recover(); rec != nil { + const size = 1 << 16 + buf := make([]byte, size) + n := runtime.Stack(buf, false) + buf = buf[:n] + log.Printf("fuse: panic in handler for %v: %v\n%s", r, rec, buf) + err := handlerPanickedError{ + Request: r, + Err: rec, + } + done(err) + r.RespondError(err) + return + } + + if !responded { + err := handlerTerminatedError{ + Request: r, + } + done(err) + r.RespondError(err) + } + }() + + if err := c.handleRequest(ctx, node, snode, r, done); err != nil { + if err == context.Canceled { + select { + case <-parentCtx.Done(): + // We canceled the parent context because of an + // incoming interrupt request, so return EINTR + // to trigger the right behavior in the client app. + // + // Only do this when it's the parent context that was + // canceled, not a context controlled by the program + // using this library, so we don't return EINTR too + // eagerly -- it might cause busy loops. + // + // Decent write-up on role of EINTR: + // http://250bpm.com/blog:12 + err = fuse.EINTR + default: + // nothing + } + } + done(err) + r.RespondError(err) + } + + // disarm runtime.Goexit protection + responded = true +} + +// handleRequest will either a) call done(s) and r.Respond(s) OR b) return an error. +func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode, r fuse.Request, done func(resp interface{})) error { + switch r := r.(type) { + default: + // Note: To FUSE, ENOSYS means "this server never implements this request." + // It would be inappropriate to return ENOSYS for other operations in this + // switch that might only be unavailable in some contexts, not all. + return fuse.ENOSYS + + case *fuse.StatfsRequest: + s := &fuse.StatfsResponse{} + if fs, ok := c.fs.(FSStatfser); ok { + if err := fs.Statfs(ctx, r, s); err != nil { + return err + } + } + done(s) + r.Respond(s) + return nil + + // Node operations. + case *fuse.GetattrRequest: + s := &fuse.GetattrResponse{} + if n, ok := node.(NodeGetattrer); ok { + if err := n.Getattr(ctx, r, s); err != nil { + return err + } + } else { + if err := snode.attr(ctx, &s.Attr); err != nil { + return err + } + } + done(s) + r.Respond(s) + return nil + + case *fuse.SetattrRequest: + s := &fuse.SetattrResponse{} + if n, ok := node.(NodeSetattrer); ok { + if err := n.Setattr(ctx, r, s); err != nil { + return err + } + } + + if err := snode.attr(ctx, &s.Attr); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.SymlinkRequest: + s := &fuse.SymlinkResponse{} + initLookupResponse(&s.LookupResponse) + n, ok := node.(NodeSymlinker) + if !ok { + return fuse.EIO // XXX or EPERM like Mkdir? + } + n2, err := n.Symlink(ctx, r) + if err != nil { + return err + } + if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.NewName, n2); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.ReadlinkRequest: + n, ok := node.(NodeReadlinker) + if !ok { + return fuse.EIO /// XXX or EPERM? + } + target, err := n.Readlink(ctx, r) + if err != nil { + return err + } + done(target) + r.Respond(target) + return nil + + case *fuse.LinkRequest: + n, ok := node.(NodeLinker) + if !ok { + return fuse.EIO /// XXX or EPERM? + } + c.meta.Lock() + var oldNode *serveNode + if int(r.OldNode) < len(c.node) { + oldNode = c.node[r.OldNode] + } + c.meta.Unlock() + if oldNode == nil { + c.debug(logLinkRequestOldNodeNotFound{ + Request: r.Hdr(), + In: r, + }) + return fuse.EIO + } + n2, err := n.Link(ctx, r, oldNode.node) + if err != nil { + return err + } + s := &fuse.LookupResponse{} + initLookupResponse(s) + if err := c.saveLookup(ctx, s, snode, r.NewName, n2); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.RemoveRequest: + n, ok := node.(NodeRemover) + if !ok { + return fuse.EIO /// XXX or EPERM? + } + err := n.Remove(ctx, r) + if err != nil { + return err + } + done(nil) + r.Respond() + return nil + + case *fuse.AccessRequest: + if n, ok := node.(NodeAccesser); ok { + if err := n.Access(ctx, r); err != nil { + return err + } + } + done(nil) + r.Respond() + return nil + + case *fuse.LookupRequest: + var n2 Node + var err error + s := &fuse.LookupResponse{} + initLookupResponse(s) + if n, ok := node.(NodeStringLookuper); ok { + n2, err = n.Lookup(ctx, r.Name) + } else if n, ok := node.(NodeRequestLookuper); ok { + n2, err = n.Lookup(ctx, r, s) + } else { + return fuse.ENOENT + } + if err != nil { + return err + } + if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.MkdirRequest: + s := &fuse.MkdirResponse{} + initLookupResponse(&s.LookupResponse) + n, ok := node.(NodeMkdirer) + if !ok { + return fuse.EPERM + } + n2, err := n.Mkdir(ctx, r) + if err != nil { + return err + } + if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.OpenRequest: + s := &fuse.OpenResponse{} + var h2 Handle + if n, ok := node.(NodeOpener); ok { + hh, err := n.Open(ctx, r, s) + if err != nil { + return err + } + h2 = hh + } else { + h2 = node + } + s.Handle = c.saveHandle(h2, r.Hdr().Node) + done(s) + r.Respond(s) + return nil + + case *fuse.CreateRequest: + n, ok := node.(NodeCreater) + if !ok { + // If we send back ENOSYS, FUSE will try mknod+open. + return fuse.EPERM + } + s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}} + initLookupResponse(&s.LookupResponse) + n2, h2, err := n.Create(ctx, r, s) + if err != nil { + return err + } + if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil { + return err + } + s.Handle = c.saveHandle(h2, r.Hdr().Node) + done(s) + r.Respond(s) + return nil + + case *fuse.GetxattrRequest: + n, ok := node.(NodeGetxattrer) + if !ok { + return fuse.ENOTSUP + } + s := &fuse.GetxattrResponse{} + err := n.Getxattr(ctx, r, s) + if err != nil { + return err + } + if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) { + return fuse.ERANGE + } + done(s) + r.Respond(s) + return nil + + case *fuse.ListxattrRequest: + n, ok := node.(NodeListxattrer) + if !ok { + return fuse.ENOTSUP + } + s := &fuse.ListxattrResponse{} + err := n.Listxattr(ctx, r, s) + if err != nil { + return err + } + if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) { + return fuse.ERANGE + } + done(s) + r.Respond(s) + return nil + + case *fuse.SetxattrRequest: + n, ok := node.(NodeSetxattrer) + if !ok { + return fuse.ENOTSUP + } + err := n.Setxattr(ctx, r) + if err != nil { + return err + } + done(nil) + r.Respond() + return nil + + case *fuse.RemovexattrRequest: + n, ok := node.(NodeRemovexattrer) + if !ok { + return fuse.ENOTSUP + } + err := n.Removexattr(ctx, r) + if err != nil { + return err + } + done(nil) + r.Respond() + return nil + + case *fuse.ForgetRequest: + forget := c.dropNode(r.Hdr().Node, r.N) + if forget { + n, ok := node.(NodeForgetter) + if ok { + n.Forget() + } + } + done(nil) + r.Respond() + return nil + + // Handle operations. + case *fuse.ReadRequest: + shandle := c.getHandle(r.Handle) + if shandle == nil { + return fuse.ESTALE + } + handle := shandle.handle + + s := &fuse.ReadResponse{Data: make([]byte, 0, r.Size)} + if r.Dir { + if h, ok := handle.(HandleReadDirAller); ok { + // detect rewinddir(3) or similar seek and refresh + // contents + if r.Offset == 0 { + shandle.readData = nil + } + + if shandle.readData == nil { + dirs, err := h.ReadDirAll(ctx) + if err != nil { + return err + } + var data []byte + for _, dir := range dirs { + if dir.Inode == 0 { + dir.Inode = c.dynamicInode(snode.inode, dir.Name) + } + data = fuse.AppendDirent(data, dir) + } + shandle.readData = data + } + fuseutil.HandleRead(r, s, shandle.readData) + done(s) + r.Respond(s) + return nil + } + } else { + if h, ok := handle.(HandleReadAller); ok { + if shandle.readData == nil { + data, err := h.ReadAll(ctx) + if err != nil { + return err + } + if data == nil { + data = []byte{} + } + shandle.readData = data + } + fuseutil.HandleRead(r, s, shandle.readData) + done(s) + r.Respond(s) + return nil + } + h, ok := handle.(HandleReader) + if !ok { + err := handleNotReaderError{handle: handle} + return err + } + if err := h.Read(ctx, r, s); err != nil { + return err + } + } + done(s) + r.Respond(s) + return nil + + case *fuse.WriteRequest: + shandle := c.getHandle(r.Handle) + if shandle == nil { + return fuse.ESTALE + } + + s := &fuse.WriteResponse{} + if h, ok := shandle.handle.(HandleWriter); ok { + if err := h.Write(ctx, r, s); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + } + return fuse.EIO + + case *fuse.FlushRequest: + shandle := c.getHandle(r.Handle) + if shandle == nil { + return fuse.ESTALE + } + handle := shandle.handle + + if h, ok := handle.(HandleFlusher); ok { + if err := h.Flush(ctx, r); err != nil { + return err + } + } + done(nil) + r.Respond() + return nil + + case *fuse.ReleaseRequest: + shandle := c.getHandle(r.Handle) + if shandle == nil { + return fuse.ESTALE + } + handle := shandle.handle + + // No matter what, release the handle. + c.dropHandle(r.Handle) + + if h, ok := handle.(HandleReleaser); ok { + if err := h.Release(ctx, r); err != nil { + return err + } + } + done(nil) + r.Respond() + return nil + + case *fuse.DestroyRequest: + if fs, ok := c.fs.(FSDestroyer); ok { + fs.Destroy() + } + done(nil) + r.Respond() + return nil + + case *fuse.RenameRequest: + c.meta.Lock() + var newDirNode *serveNode + if int(r.NewDir) < len(c.node) { + newDirNode = c.node[r.NewDir] + } + c.meta.Unlock() + if newDirNode == nil { + c.debug(renameNewDirNodeNotFound{ + Request: r.Hdr(), + In: r, + }) + return fuse.EIO + } + n, ok := node.(NodeRenamer) + if !ok { + return fuse.EIO // XXX or EPERM like Mkdir? + } + err := n.Rename(ctx, r, newDirNode.node) + if err != nil { + return err + } + done(nil) + r.Respond() + return nil + + case *fuse.MknodRequest: + n, ok := node.(NodeMknoder) + if !ok { + return fuse.EIO + } + n2, err := n.Mknod(ctx, r) + if err != nil { + return err + } + s := &fuse.LookupResponse{} + initLookupResponse(s) + if err := c.saveLookup(ctx, s, snode, r.Name, n2); err != nil { + return err + } + done(s) + r.Respond(s) + return nil + + case *fuse.FsyncRequest: + n, ok := node.(NodeFsyncer) + if !ok { + return fuse.EIO + } + err := n.Fsync(ctx, r) + if err != nil { + return err + } + done(nil) + r.Respond() + return nil + + case *fuse.InterruptRequest: + c.meta.Lock() + ireq := c.req[r.IntrID] + if ireq != nil && ireq.cancel != nil { + ireq.cancel() + ireq.cancel = nil + } + c.meta.Unlock() + done(nil) + r.Respond() + return nil + + /* case *FsyncdirRequest: + return ENOSYS + + case *GetlkRequest, *SetlkRequest, *SetlkwRequest: + return ENOSYS + + case *BmapRequest: + return ENOSYS + + case *SetvolnameRequest, *GetxtimesRequest, *ExchangeRequest: + return ENOSYS + */ + } + + panic("not reached") +} + +func (c *Server) saveLookup(ctx context.Context, s *fuse.LookupResponse, snode *serveNode, elem string, n2 Node) error { + if err := nodeAttr(ctx, n2, &s.Attr); err != nil { + return err + } + if s.Attr.Inode == 0 { + s.Attr.Inode = c.dynamicInode(snode.inode, elem) + } + + s.Node, s.Generation = c.saveNode(s.Attr.Inode, n2) + return nil +} + +type invalidateNodeDetail struct { + Off int64 + Size int64 +} + +func (i invalidateNodeDetail) String() string { + return fmt.Sprintf("Off:%d Size:%d", i.Off, i.Size) +} + +func errstr(err error) string { + if err == nil { + return "" + } + return err.Error() +} + +func (s *Server) invalidateNode(node Node, off int64, size int64) error { + s.meta.Lock() + id, ok := s.nodeRef[node] + if ok { + snode := s.node[id] + snode.wg.Add(1) + defer snode.wg.Done() + } + s.meta.Unlock() + if !ok { + // This is what the kernel would have said, if we had been + // able to send this message; it's not cached. + return fuse.ErrNotCached + } + // Delay logging until after we can record the error too. We + // consider a /dev/fuse write to be instantaneous enough to not + // need separate before and after messages. + err := s.conn.InvalidateNode(id, off, size) + s.debug(notification{ + Op: "InvalidateNode", + Node: id, + Out: invalidateNodeDetail{ + Off: off, + Size: size, + }, + Err: errstr(err), + }) + return err +} + +// InvalidateNodeAttr invalidates the kernel cache of the attributes +// of node. +// +// Returns fuse.ErrNotCached if the kernel is not currently caching +// the node. +func (s *Server) InvalidateNodeAttr(node Node) error { + return s.invalidateNode(node, 0, 0) +} + +// InvalidateNodeData invalidates the kernel cache of the attributes +// and data of node. +// +// Returns fuse.ErrNotCached if the kernel is not currently caching +// the node. +func (s *Server) InvalidateNodeData(node Node) error { + return s.invalidateNode(node, 0, -1) +} + +// InvalidateNodeDataRange invalidates the kernel cache of the +// attributes and a range of the data of node. +// +// Returns fuse.ErrNotCached if the kernel is not currently caching +// the node. +func (s *Server) InvalidateNodeDataRange(node Node, off int64, size int64) error { + return s.invalidateNode(node, off, size) +} + +type invalidateEntryDetail struct { + Name string +} + +func (i invalidateEntryDetail) String() string { + return fmt.Sprintf("%q", i.Name) +} + +// InvalidateEntry invalidates the kernel cache of the directory entry +// identified by parent node and entry basename. +// +// Kernel may or may not cache directory listings. To invalidate +// those, use InvalidateNode to invalidate all of the data for a +// directory. (As of 2015-06, Linux FUSE does not cache directory +// listings.) +// +// Returns ErrNotCached if the kernel is not currently caching the +// node. +func (s *Server) InvalidateEntry(parent Node, name string) error { + s.meta.Lock() + id, ok := s.nodeRef[parent] + if ok { + snode := s.node[id] + snode.wg.Add(1) + defer snode.wg.Done() + } + s.meta.Unlock() + if !ok { + // This is what the kernel would have said, if we had been + // able to send this message; it's not cached. + return fuse.ErrNotCached + } + err := s.conn.InvalidateEntry(id, name) + s.debug(notification{ + Op: "InvalidateEntry", + Node: id, + Out: invalidateEntryDetail{ + Name: name, + }, + Err: errstr(err), + }) + return err +} + +// DataHandle returns a read-only Handle that satisfies reads +// using the given data. +func DataHandle(data []byte) Handle { + return &dataHandle{data} +} + +type dataHandle struct { + data []byte +} + +func (d *dataHandle) ReadAll(ctx context.Context) ([]byte, error) { + return d.data, nil +} + +// GenerateDynamicInode returns a dynamic inode. +// +// The parent inode and current entry name are used as the criteria +// for choosing a pseudorandom inode. This makes it likely the same +// entry will get the same inode on multiple runs. +func GenerateDynamicInode(parent uint64, name string) uint64 { + h := fnv.New64a() + var buf [8]byte + binary.LittleEndian.PutUint64(buf[:], parent) + _, _ = h.Write(buf[:]) + _, _ = h.Write([]byte(name)) + var inode uint64 + for { + inode = h.Sum64() + if inode != 0 { + break + } + // there's a tiny probability that result is zero; change the + // input a little and try again + _, _ = h.Write([]byte{'x'}) + } + return inode +} diff --git a/vendor/bazil.org/fuse/fs/tree.go b/vendor/bazil.org/fuse/fs/tree.go new file mode 100644 index 00000000..7e078045 --- /dev/null +++ b/vendor/bazil.org/fuse/fs/tree.go @@ -0,0 +1,99 @@ +// FUSE directory tree, for servers that wish to use it with the service loop. + +package fs + +import ( + "os" + pathpkg "path" + "strings" + + "golang.org/x/net/context" +) + +import ( + "bazil.org/fuse" +) + +// A Tree implements a basic read-only directory tree for FUSE. +// The Nodes contained in it may still be writable. +type Tree struct { + tree +} + +func (t *Tree) Root() (Node, error) { + return &t.tree, nil +} + +// Add adds the path to the tree, resolving to the given node. +// If path or a prefix of path has already been added to the tree, +// Add panics. +// +// Add is only safe to call before starting to serve requests. +func (t *Tree) Add(path string, node Node) { + path = pathpkg.Clean("/" + path)[1:] + elems := strings.Split(path, "/") + dir := Node(&t.tree) + for i, elem := range elems { + dt, ok := dir.(*tree) + if !ok { + panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path) + } + n := dt.lookup(elem) + if n != nil { + if i+1 == len(elems) { + panic("fuse: Tree.Add for " + path + " conflicts with " + elem) + } + dir = n + } else { + if i+1 == len(elems) { + dt.add(elem, node) + } else { + dir = &tree{} + dt.add(elem, dir) + } + } + } +} + +type treeDir struct { + name string + node Node +} + +type tree struct { + dir []treeDir +} + +func (t *tree) lookup(name string) Node { + for _, d := range t.dir { + if d.name == name { + return d.node + } + } + return nil +} + +func (t *tree) add(name string, n Node) { + t.dir = append(t.dir, treeDir{name, n}) +} + +func (t *tree) Attr(ctx context.Context, a *fuse.Attr) error { + a.Mode = os.ModeDir | 0555 + return nil +} + +func (t *tree) Lookup(ctx context.Context, name string) (Node, error) { + n := t.lookup(name) + if n != nil { + return n, nil + } + return nil, fuse.ENOENT +} + +func (t *tree) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { + var out []fuse.Dirent + for _, d := range t.dir { + out = append(out, fuse.Dirent{Name: d.name}) + } + return out, nil +} diff --git a/vendor/bazil.org/fuse/fuse.go b/vendor/bazil.org/fuse/fuse.go new file mode 100644 index 00000000..7dc70f9e --- /dev/null +++ b/vendor/bazil.org/fuse/fuse.go @@ -0,0 +1,2304 @@ +// See the file LICENSE for copyright and licensing information. + +// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c, +// which carries this notice: +// +// The files in this directory are subject to the following license. +// +// The author of this software is Russ Cox. +// +// Copyright (c) 2006 Russ Cox +// +// Permission to use, copy, modify, and distribute this software for any +// purpose without fee is hereby granted, provided that this entire notice +// is included in all copies of any software which is or includes a copy +// or modification of this software and in all copies of the supporting +// documentation for such software. +// +// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY +// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS +// FITNESS FOR ANY PARTICULAR PURPOSE. + +// Package fuse enables writing FUSE file systems on Linux, OS X, and FreeBSD. +// +// On OS X, it requires OSXFUSE (http://osxfuse.github.com/). +// +// There are two approaches to writing a FUSE file system. The first is to speak +// the low-level message protocol, reading from a Conn using ReadRequest and +// writing using the various Respond methods. This approach is closest to +// the actual interaction with the kernel and can be the simplest one in contexts +// such as protocol translators. +// +// Servers of synthesized file systems tend to share common +// bookkeeping abstracted away by the second approach, which is to +// call fs.Serve to serve the FUSE protocol using an implementation of +// the service methods in the interfaces FS* (file system), Node* (file +// or directory), and Handle* (opened file or directory). +// There are a daunting number of such methods that can be written, +// but few are required. +// The specific methods are described in the documentation for those interfaces. +// +// The hellofs subdirectory contains a simple illustration of the fs.Serve approach. +// +// Service Methods +// +// The required and optional methods for the FS, Node, and Handle interfaces +// have the general form +// +// Op(ctx context.Context, req *OpRequest, resp *OpResponse) error +// +// where Op is the name of a FUSE operation. Op reads request +// parameters from req and writes results to resp. An operation whose +// only result is the error result omits the resp parameter. +// +// Multiple goroutines may call service methods simultaneously; the +// methods being called are responsible for appropriate +// synchronization. +// +// The operation must not hold on to the request or response, +// including any []byte fields such as WriteRequest.Data or +// SetxattrRequest.Xattr. +// +// Errors +// +// Operations can return errors. The FUSE interface can only +// communicate POSIX errno error numbers to file system clients, the +// message is not visible to file system clients. The returned error +// can implement ErrorNumber to control the errno returned. Without +// ErrorNumber, a generic errno (EIO) is returned. +// +// Error messages will be visible in the debug log as part of the +// response. +// +// Interrupted Operations +// +// In some file systems, some operations +// may take an undetermined amount of time. For example, a Read waiting for +// a network message or a matching Write might wait indefinitely. If the request +// is cancelled and no longer needed, the context will be cancelled. +// Blocking operations should select on a receive from ctx.Done() and attempt to +// abort the operation early if the receive succeeds (meaning the channel is closed). +// To indicate that the operation failed because it was aborted, return fuse.EINTR. +// +// If an operation does not block for an indefinite amount of time, supporting +// cancellation is not necessary. +// +// Authentication +// +// All requests types embed a Header, meaning that the method can +// inspect req.Pid, req.Uid, and req.Gid as necessary to implement +// permission checking. The kernel FUSE layer normally prevents other +// users from accessing the FUSE file system (to change this, see +// AllowOther, AllowRoot), but does not enforce access modes (to +// change this, see DefaultPermissions). +// +// Mount Options +// +// Behavior and metadata of the mounted file system can be changed by +// passing MountOption values to Mount. +// +package fuse // import "bazil.org/fuse" + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "sync" + "syscall" + "time" + "unsafe" +) + +// A Conn represents a connection to a mounted FUSE file system. +type Conn struct { + // Ready is closed when the mount is complete or has failed. + Ready <-chan struct{} + + // MountError stores any error from the mount process. Only valid + // after Ready is closed. + MountError error + + // File handle for kernel communication. Only safe to access if + // rio or wio is held. + dev *os.File + wio sync.RWMutex + rio sync.RWMutex + + // Protocol version negotiated with InitRequest/InitResponse. + proto Protocol +} + +// MountpointDoesNotExistError is an error returned when the +// mountpoint does not exist. +type MountpointDoesNotExistError struct { + Path string +} + +var _ error = (*MountpointDoesNotExistError)(nil) + +func (e *MountpointDoesNotExistError) Error() string { + return fmt.Sprintf("mountpoint does not exist: %v", e.Path) +} + +// Mount mounts a new FUSE connection on the named directory +// and returns a connection for reading and writing FUSE messages. +// +// After a successful return, caller must call Close to free +// resources. +// +// Even on successful return, the new mount is not guaranteed to be +// visible until after Conn.Ready is closed. See Conn.MountError for +// possible errors. Incoming requests on Conn must be served to make +// progress. +func Mount(dir string, options ...MountOption) (*Conn, error) { + conf := mountConfig{ + options: make(map[string]string), + } + for _, option := range options { + if err := option(&conf); err != nil { + return nil, err + } + } + + ready := make(chan struct{}, 1) + c := &Conn{ + Ready: ready, + } + f, err := mount(dir, &conf, ready, &c.MountError) + if err != nil { + return nil, err + } + c.dev = f + + if err := initMount(c, &conf); err != nil { + c.Close() + if err == ErrClosedWithoutInit { + // see if we can provide a better error + <-c.Ready + if err := c.MountError; err != nil { + return nil, err + } + } + return nil, err + } + + return c, nil +} + +type OldVersionError struct { + Kernel Protocol + LibraryMin Protocol +} + +func (e *OldVersionError) Error() string { + return fmt.Sprintf("kernel FUSE version is too old: %v < %v", e.Kernel, e.LibraryMin) +} + +var ( + ErrClosedWithoutInit = errors.New("fuse connection closed without init") +) + +func initMount(c *Conn, conf *mountConfig) error { + req, err := c.ReadRequest() + if err != nil { + if err == io.EOF { + return ErrClosedWithoutInit + } + return err + } + r, ok := req.(*InitRequest) + if !ok { + return fmt.Errorf("missing init, got: %T", req) + } + + min := Protocol{protoVersionMinMajor, protoVersionMinMinor} + if r.Kernel.LT(min) { + req.RespondError(Errno(syscall.EPROTO)) + c.Close() + return &OldVersionError{ + Kernel: r.Kernel, + LibraryMin: min, + } + } + + proto := Protocol{protoVersionMaxMajor, protoVersionMaxMinor} + if r.Kernel.LT(proto) { + // Kernel doesn't support the latest version we have. + proto = r.Kernel + } + c.proto = proto + + s := &InitResponse{ + Library: proto, + MaxReadahead: conf.maxReadahead, + MaxWrite: maxWrite, + Flags: InitBigWrites | conf.initFlags, + } + r.Respond(s) + return nil +} + +// A Request represents a single FUSE request received from the kernel. +// Use a type switch to determine the specific kind. +// A request of unrecognized type will have concrete type *Header. +type Request interface { + // Hdr returns the Header associated with this request. + Hdr() *Header + + // RespondError responds to the request with the given error. + RespondError(error) + + String() string +} + +// A RequestID identifies an active FUSE request. +type RequestID uint64 + +func (r RequestID) String() string { + return fmt.Sprintf("%#x", uint64(r)) +} + +// A NodeID is a number identifying a directory or file. +// It must be unique among IDs returned in LookupResponses +// that have not yet been forgotten by ForgetRequests. +type NodeID uint64 + +func (n NodeID) String() string { + return fmt.Sprintf("%#x", uint64(n)) +} + +// A HandleID is a number identifying an open directory or file. +// It only needs to be unique while the directory or file is open. +type HandleID uint64 + +func (h HandleID) String() string { + return fmt.Sprintf("%#x", uint64(h)) +} + +// The RootID identifies the root directory of a FUSE file system. +const RootID NodeID = rootID + +// A Header describes the basic information sent in every request. +type Header struct { + Conn *Conn `json:"-"` // connection this request was received on + ID RequestID // unique ID for request + Node NodeID // file or directory the request is about + Uid uint32 // user ID of process making request + Gid uint32 // group ID of process making request + Pid uint32 // process ID of process making request + + // for returning to reqPool + msg *message +} + +func (h *Header) String() string { + return fmt.Sprintf("ID=%v Node=%v Uid=%d Gid=%d Pid=%d", h.ID, h.Node, h.Uid, h.Gid, h.Pid) +} + +func (h *Header) Hdr() *Header { + return h +} + +func (h *Header) noResponse() { + putMessage(h.msg) +} + +func (h *Header) respond(msg []byte) { + out := (*outHeader)(unsafe.Pointer(&msg[0])) + out.Unique = uint64(h.ID) + h.Conn.respond(msg) + putMessage(h.msg) +} + +// An ErrorNumber is an error with a specific error number. +// +// Operations may return an error value that implements ErrorNumber to +// control what specific error number (errno) to return. +type ErrorNumber interface { + // Errno returns the the error number (errno) for this error. + Errno() Errno +} + +const ( + // ENOSYS indicates that the call is not supported. + ENOSYS = Errno(syscall.ENOSYS) + + // ESTALE is used by Serve to respond to violations of the FUSE protocol. + ESTALE = Errno(syscall.ESTALE) + + ENOENT = Errno(syscall.ENOENT) + EIO = Errno(syscall.EIO) + EPERM = Errno(syscall.EPERM) + + // EINTR indicates request was interrupted by an InterruptRequest. + // See also fs.Intr. + EINTR = Errno(syscall.EINTR) + + ERANGE = Errno(syscall.ERANGE) + ENOTSUP = Errno(syscall.ENOTSUP) + EEXIST = Errno(syscall.EEXIST) +) + +// DefaultErrno is the errno used when error returned does not +// implement ErrorNumber. +const DefaultErrno = EIO + +var errnoNames = map[Errno]string{ + ENOSYS: "ENOSYS", + ESTALE: "ESTALE", + ENOENT: "ENOENT", + EIO: "EIO", + EPERM: "EPERM", + EINTR: "EINTR", + EEXIST: "EEXIST", +} + +// Errno implements Error and ErrorNumber using a syscall.Errno. +type Errno syscall.Errno + +var _ = ErrorNumber(Errno(0)) +var _ = error(Errno(0)) + +func (e Errno) Errno() Errno { + return e +} + +func (e Errno) String() string { + return syscall.Errno(e).Error() +} + +func (e Errno) Error() string { + return syscall.Errno(e).Error() +} + +// ErrnoName returns the short non-numeric identifier for this errno. +// For example, "EIO". +func (e Errno) ErrnoName() string { + s := errnoNames[e] + if s == "" { + s = fmt.Sprint(e.Errno()) + } + return s +} + +func (e Errno) MarshalText() ([]byte, error) { + s := e.ErrnoName() + return []byte(s), nil +} + +func (h *Header) RespondError(err error) { + errno := DefaultErrno + if ferr, ok := err.(ErrorNumber); ok { + errno = ferr.Errno() + } + // FUSE uses negative errors! + // TODO: File bug report against OSXFUSE: positive error causes kernel panic. + buf := newBuffer(0) + hOut := (*outHeader)(unsafe.Pointer(&buf[0])) + hOut.Error = -int32(errno) + h.respond(buf) +} + +// All requests read from the kernel, without data, are shorter than +// this. +var maxRequestSize = syscall.Getpagesize() +var bufSize = maxRequestSize + maxWrite + +// reqPool is a pool of messages. +// +// Lifetime of a logical message is from getMessage to putMessage. +// getMessage is called by ReadRequest. putMessage is called by +// Conn.ReadRequest, Request.Respond, or Request.RespondError. +// +// Messages in the pool are guaranteed to have conn and off zeroed, +// buf allocated and len==bufSize, and hdr set. +var reqPool = sync.Pool{ + New: allocMessage, +} + +func allocMessage() interface{} { + m := &message{buf: make([]byte, bufSize)} + m.hdr = (*inHeader)(unsafe.Pointer(&m.buf[0])) + return m +} + +func getMessage(c *Conn) *message { + m := reqPool.Get().(*message) + m.conn = c + return m +} + +func putMessage(m *message) { + m.buf = m.buf[:bufSize] + m.conn = nil + m.off = 0 + reqPool.Put(m) +} + +// a message represents the bytes of a single FUSE message +type message struct { + conn *Conn + buf []byte // all bytes + hdr *inHeader // header + off int // offset for reading additional fields +} + +func (m *message) len() uintptr { + return uintptr(len(m.buf) - m.off) +} + +func (m *message) data() unsafe.Pointer { + var p unsafe.Pointer + if m.off < len(m.buf) { + p = unsafe.Pointer(&m.buf[m.off]) + } + return p +} + +func (m *message) bytes() []byte { + return m.buf[m.off:] +} + +func (m *message) Header() Header { + h := m.hdr + return Header{ + Conn: m.conn, + ID: RequestID(h.Unique), + Node: NodeID(h.Nodeid), + Uid: h.Uid, + Gid: h.Gid, + Pid: h.Pid, + + msg: m, + } +} + +// fileMode returns a Go os.FileMode from a Unix mode. +func fileMode(unixMode uint32) os.FileMode { + mode := os.FileMode(unixMode & 0777) + switch unixMode & syscall.S_IFMT { + case syscall.S_IFREG: + // nothing + case syscall.S_IFDIR: + mode |= os.ModeDir + case syscall.S_IFCHR: + mode |= os.ModeCharDevice | os.ModeDevice + case syscall.S_IFBLK: + mode |= os.ModeDevice + case syscall.S_IFIFO: + mode |= os.ModeNamedPipe + case syscall.S_IFLNK: + mode |= os.ModeSymlink + case syscall.S_IFSOCK: + mode |= os.ModeSocket + default: + // no idea + mode |= os.ModeDevice + } + if unixMode&syscall.S_ISUID != 0 { + mode |= os.ModeSetuid + } + if unixMode&syscall.S_ISGID != 0 { + mode |= os.ModeSetgid + } + return mode +} + +type noOpcode struct { + Opcode uint32 +} + +func (m noOpcode) String() string { + return fmt.Sprintf("No opcode %v", m.Opcode) +} + +type malformedMessage struct { +} + +func (malformedMessage) String() string { + return "malformed message" +} + +// Close closes the FUSE connection. +func (c *Conn) Close() error { + c.wio.Lock() + defer c.wio.Unlock() + c.rio.Lock() + defer c.rio.Unlock() + return c.dev.Close() +} + +// caller must hold wio or rio +func (c *Conn) fd() int { + return int(c.dev.Fd()) +} + +func (c *Conn) Protocol() Protocol { + return c.proto +} + +// ReadRequest returns the next FUSE request from the kernel. +// +// Caller must call either Request.Respond or Request.RespondError in +// a reasonable time. Caller must not retain Request after that call. +func (c *Conn) ReadRequest() (Request, error) { + m := getMessage(c) +loop: + c.rio.RLock() + n, err := syscall.Read(c.fd(), m.buf) + c.rio.RUnlock() + if err == syscall.EINTR { + // OSXFUSE sends EINTR to userspace when a request interrupt + // completed before it got sent to userspace? + goto loop + } + if err != nil && err != syscall.ENODEV { + putMessage(m) + return nil, err + } + if n <= 0 { + putMessage(m) + return nil, io.EOF + } + m.buf = m.buf[:n] + + if n < inHeaderSize { + putMessage(m) + return nil, errors.New("fuse: message too short") + } + + // FreeBSD FUSE sends a short length in the header + // for FUSE_INIT even though the actual read length is correct. + if n == inHeaderSize+initInSize && m.hdr.Opcode == opInit && m.hdr.Len < uint32(n) { + m.hdr.Len = uint32(n) + } + + // OSXFUSE sometimes sends the wrong m.hdr.Len in a FUSE_WRITE message. + if m.hdr.Len < uint32(n) && m.hdr.Len >= uint32(unsafe.Sizeof(writeIn{})) && m.hdr.Opcode == opWrite { + m.hdr.Len = uint32(n) + } + + if m.hdr.Len != uint32(n) { + // prepare error message before returning m to pool + err := fmt.Errorf("fuse: read %d opcode %d but expected %d", n, m.hdr.Opcode, m.hdr.Len) + putMessage(m) + return nil, err + } + + m.off = inHeaderSize + + // Convert to data structures. + // Do not trust kernel to hand us well-formed data. + var req Request + switch m.hdr.Opcode { + default: + Debug(noOpcode{Opcode: m.hdr.Opcode}) + goto unrecognized + + case opLookup: + buf := m.bytes() + n := len(buf) + if n == 0 || buf[n-1] != '\x00' { + goto corrupt + } + req = &LookupRequest{ + Header: m.Header(), + Name: string(buf[:n-1]), + } + + case opForget: + in := (*forgetIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &ForgetRequest{ + Header: m.Header(), + N: in.Nlookup, + } + + case opGetattr: + switch { + case c.proto.LT(Protocol{7, 9}): + req = &GetattrRequest{ + Header: m.Header(), + } + + default: + in := (*getattrIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &GetattrRequest{ + Header: m.Header(), + Flags: GetattrFlags(in.GetattrFlags), + Handle: HandleID(in.Fh), + } + } + + case opSetattr: + in := (*setattrIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &SetattrRequest{ + Header: m.Header(), + Valid: SetattrValid(in.Valid), + Handle: HandleID(in.Fh), + Size: in.Size, + Atime: time.Unix(int64(in.Atime), int64(in.AtimeNsec)), + Mtime: time.Unix(int64(in.Mtime), int64(in.MtimeNsec)), + Mode: fileMode(in.Mode), + Uid: in.Uid, + Gid: in.Gid, + Bkuptime: in.BkupTime(), + Chgtime: in.Chgtime(), + Flags: in.Flags(), + } + + case opReadlink: + if len(m.bytes()) > 0 { + goto corrupt + } + req = &ReadlinkRequest{ + Header: m.Header(), + } + + case opSymlink: + // m.bytes() is "newName\0target\0" + names := m.bytes() + if len(names) == 0 || names[len(names)-1] != 0 { + goto corrupt + } + i := bytes.IndexByte(names, '\x00') + if i < 0 { + goto corrupt + } + newName, target := names[0:i], names[i+1:len(names)-1] + req = &SymlinkRequest{ + Header: m.Header(), + NewName: string(newName), + Target: string(target), + } + + case opLink: + in := (*linkIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + newName := m.bytes()[unsafe.Sizeof(*in):] + if len(newName) < 2 || newName[len(newName)-1] != 0 { + goto corrupt + } + newName = newName[:len(newName)-1] + req = &LinkRequest{ + Header: m.Header(), + OldNode: NodeID(in.Oldnodeid), + NewName: string(newName), + } + + case opMknod: + size := mknodInSize(c.proto) + if m.len() < size { + goto corrupt + } + in := (*mknodIn)(m.data()) + name := m.bytes()[size:] + if len(name) < 2 || name[len(name)-1] != '\x00' { + goto corrupt + } + name = name[:len(name)-1] + r := &MknodRequest{ + Header: m.Header(), + Mode: fileMode(in.Mode), + Rdev: in.Rdev, + Name: string(name), + } + if c.proto.GE(Protocol{7, 12}) { + r.Umask = fileMode(in.Umask) & os.ModePerm + } + req = r + + case opMkdir: + size := mkdirInSize(c.proto) + if m.len() < size { + goto corrupt + } + in := (*mkdirIn)(m.data()) + name := m.bytes()[size:] + i := bytes.IndexByte(name, '\x00') + if i < 0 { + goto corrupt + } + r := &MkdirRequest{ + Header: m.Header(), + Name: string(name[:i]), + // observed on Linux: mkdirIn.Mode & syscall.S_IFMT == 0, + // and this causes fileMode to go into it's "no idea" + // code branch; enforce type to directory + Mode: fileMode((in.Mode &^ syscall.S_IFMT) | syscall.S_IFDIR), + } + if c.proto.GE(Protocol{7, 12}) { + r.Umask = fileMode(in.Umask) & os.ModePerm + } + req = r + + case opUnlink, opRmdir: + buf := m.bytes() + n := len(buf) + if n == 0 || buf[n-1] != '\x00' { + goto corrupt + } + req = &RemoveRequest{ + Header: m.Header(), + Name: string(buf[:n-1]), + Dir: m.hdr.Opcode == opRmdir, + } + + case opRename: + in := (*renameIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + newDirNodeID := NodeID(in.Newdir) + oldNew := m.bytes()[unsafe.Sizeof(*in):] + // oldNew should be "old\x00new\x00" + if len(oldNew) < 4 { + goto corrupt + } + if oldNew[len(oldNew)-1] != '\x00' { + goto corrupt + } + i := bytes.IndexByte(oldNew, '\x00') + if i < 0 { + goto corrupt + } + oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1]) + req = &RenameRequest{ + Header: m.Header(), + NewDir: newDirNodeID, + OldName: oldName, + NewName: newName, + } + + case opOpendir, opOpen: + in := (*openIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &OpenRequest{ + Header: m.Header(), + Dir: m.hdr.Opcode == opOpendir, + Flags: openFlags(in.Flags), + } + + case opRead, opReaddir: + in := (*readIn)(m.data()) + if m.len() < readInSize(c.proto) { + goto corrupt + } + r := &ReadRequest{ + Header: m.Header(), + Dir: m.hdr.Opcode == opReaddir, + Handle: HandleID(in.Fh), + Offset: int64(in.Offset), + Size: int(in.Size), + } + if c.proto.GE(Protocol{7, 9}) { + r.Flags = ReadFlags(in.ReadFlags) + r.LockOwner = in.LockOwner + r.FileFlags = openFlags(in.Flags) + } + req = r + + case opWrite: + in := (*writeIn)(m.data()) + if m.len() < writeInSize(c.proto) { + goto corrupt + } + r := &WriteRequest{ + Header: m.Header(), + Handle: HandleID(in.Fh), + Offset: int64(in.Offset), + Flags: WriteFlags(in.WriteFlags), + } + if c.proto.GE(Protocol{7, 9}) { + r.LockOwner = in.LockOwner + r.FileFlags = openFlags(in.Flags) + } + buf := m.bytes()[writeInSize(c.proto):] + if uint32(len(buf)) < in.Size { + goto corrupt + } + r.Data = buf + req = r + + case opStatfs: + req = &StatfsRequest{ + Header: m.Header(), + } + + case opRelease, opReleasedir: + in := (*releaseIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &ReleaseRequest{ + Header: m.Header(), + Dir: m.hdr.Opcode == opReleasedir, + Handle: HandleID(in.Fh), + Flags: openFlags(in.Flags), + ReleaseFlags: ReleaseFlags(in.ReleaseFlags), + LockOwner: in.LockOwner, + } + + case opFsync, opFsyncdir: + in := (*fsyncIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &FsyncRequest{ + Dir: m.hdr.Opcode == opFsyncdir, + Header: m.Header(), + Handle: HandleID(in.Fh), + Flags: in.FsyncFlags, + } + + case opSetxattr: + in := (*setxattrIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + m.off += int(unsafe.Sizeof(*in)) + name := m.bytes() + i := bytes.IndexByte(name, '\x00') + if i < 0 { + goto corrupt + } + xattr := name[i+1:] + if uint32(len(xattr)) < in.Size { + goto corrupt + } + xattr = xattr[:in.Size] + req = &SetxattrRequest{ + Header: m.Header(), + Flags: in.Flags, + Position: in.position(), + Name: string(name[:i]), + Xattr: xattr, + } + + case opGetxattr: + in := (*getxattrIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + name := m.bytes()[unsafe.Sizeof(*in):] + i := bytes.IndexByte(name, '\x00') + if i < 0 { + goto corrupt + } + req = &GetxattrRequest{ + Header: m.Header(), + Name: string(name[:i]), + Size: in.Size, + Position: in.position(), + } + + case opListxattr: + in := (*getxattrIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &ListxattrRequest{ + Header: m.Header(), + Size: in.Size, + Position: in.position(), + } + + case opRemovexattr: + buf := m.bytes() + n := len(buf) + if n == 0 || buf[n-1] != '\x00' { + goto corrupt + } + req = &RemovexattrRequest{ + Header: m.Header(), + Name: string(buf[:n-1]), + } + + case opFlush: + in := (*flushIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &FlushRequest{ + Header: m.Header(), + Handle: HandleID(in.Fh), + Flags: in.FlushFlags, + LockOwner: in.LockOwner, + } + + case opInit: + in := (*initIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &InitRequest{ + Header: m.Header(), + Kernel: Protocol{in.Major, in.Minor}, + MaxReadahead: in.MaxReadahead, + Flags: InitFlags(in.Flags), + } + + case opGetlk: + panic("opGetlk") + case opSetlk: + panic("opSetlk") + case opSetlkw: + panic("opSetlkw") + + case opAccess: + in := (*accessIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &AccessRequest{ + Header: m.Header(), + Mask: in.Mask, + } + + case opCreate: + size := createInSize(c.proto) + if m.len() < size { + goto corrupt + } + in := (*createIn)(m.data()) + name := m.bytes()[size:] + i := bytes.IndexByte(name, '\x00') + if i < 0 { + goto corrupt + } + r := &CreateRequest{ + Header: m.Header(), + Flags: openFlags(in.Flags), + Mode: fileMode(in.Mode), + Name: string(name[:i]), + } + if c.proto.GE(Protocol{7, 12}) { + r.Umask = fileMode(in.Umask) & os.ModePerm + } + req = r + + case opInterrupt: + in := (*interruptIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + req = &InterruptRequest{ + Header: m.Header(), + IntrID: RequestID(in.Unique), + } + + case opBmap: + panic("opBmap") + + case opDestroy: + req = &DestroyRequest{ + Header: m.Header(), + } + + // OS X + case opSetvolname: + panic("opSetvolname") + case opGetxtimes: + panic("opGetxtimes") + case opExchange: + in := (*exchangeIn)(m.data()) + if m.len() < unsafe.Sizeof(*in) { + goto corrupt + } + oldDirNodeID := NodeID(in.Olddir) + newDirNodeID := NodeID(in.Newdir) + oldNew := m.bytes()[unsafe.Sizeof(*in):] + // oldNew should be "oldname\x00newname\x00" + if len(oldNew) < 4 { + goto corrupt + } + if oldNew[len(oldNew)-1] != '\x00' { + goto corrupt + } + i := bytes.IndexByte(oldNew, '\x00') + if i < 0 { + goto corrupt + } + oldName, newName := string(oldNew[:i]), string(oldNew[i+1:len(oldNew)-1]) + req = &ExchangeDataRequest{ + Header: m.Header(), + OldDir: oldDirNodeID, + NewDir: newDirNodeID, + OldName: oldName, + NewName: newName, + // TODO options + } + } + + return req, nil + +corrupt: + Debug(malformedMessage{}) + putMessage(m) + return nil, fmt.Errorf("fuse: malformed message") + +unrecognized: + // Unrecognized message. + // Assume higher-level code will send a "no idea what you mean" error. + h := m.Header() + return &h, nil +} + +type bugShortKernelWrite struct { + Written int64 + Length int64 + Error string + Stack string +} + +func (b bugShortKernelWrite) String() string { + return fmt.Sprintf("short kernel write: written=%d/%d error=%q stack=\n%s", b.Written, b.Length, b.Error, b.Stack) +} + +type bugKernelWriteError struct { + Error string + Stack string +} + +func (b bugKernelWriteError) String() string { + return fmt.Sprintf("kernel write error: error=%q stack=\n%s", b.Error, b.Stack) +} + +// safe to call even with nil error +func errorString(err error) string { + if err == nil { + return "" + } + return err.Error() +} + +func (c *Conn) writeToKernel(msg []byte) error { + out := (*outHeader)(unsafe.Pointer(&msg[0])) + out.Len = uint32(len(msg)) + + c.wio.RLock() + defer c.wio.RUnlock() + nn, err := syscall.Write(c.fd(), msg) + if err == nil && nn != len(msg) { + Debug(bugShortKernelWrite{ + Written: int64(nn), + Length: int64(len(msg)), + Error: errorString(err), + Stack: stack(), + }) + } + return err +} + +func (c *Conn) respond(msg []byte) { + if err := c.writeToKernel(msg); err != nil { + Debug(bugKernelWriteError{ + Error: errorString(err), + Stack: stack(), + }) + } +} + +type notCachedError struct{} + +func (notCachedError) Error() string { + return "node not cached" +} + +var _ ErrorNumber = notCachedError{} + +func (notCachedError) Errno() Errno { + // Behave just like if the original syscall.ENOENT had been passed + // straight through. + return ENOENT +} + +var ( + ErrNotCached = notCachedError{} +) + +// sendInvalidate sends an invalidate notification to kernel. +// +// A returned ENOENT is translated to a friendlier error. +func (c *Conn) sendInvalidate(msg []byte) error { + switch err := c.writeToKernel(msg); err { + case syscall.ENOENT: + return ErrNotCached + default: + return err + } +} + +// InvalidateNode invalidates the kernel cache of the attributes and a +// range of the data of a node. +// +// Giving offset 0 and size -1 means all data. To invalidate just the +// attributes, give offset 0 and size 0. +// +// Returns ErrNotCached if the kernel is not currently caching the +// node. +func (c *Conn) InvalidateNode(nodeID NodeID, off int64, size int64) error { + buf := newBuffer(unsafe.Sizeof(notifyInvalInodeOut{})) + h := (*outHeader)(unsafe.Pointer(&buf[0])) + // h.Unique is 0 + h.Error = notifyCodeInvalInode + out := (*notifyInvalInodeOut)(buf.alloc(unsafe.Sizeof(notifyInvalInodeOut{}))) + out.Ino = uint64(nodeID) + out.Off = off + out.Len = size + return c.sendInvalidate(buf) +} + +// InvalidateEntry invalidates the kernel cache of the directory entry +// identified by parent directory node ID and entry basename. +// +// Kernel may or may not cache directory listings. To invalidate +// those, use InvalidateNode to invalidate all of the data for a +// directory. (As of 2015-06, Linux FUSE does not cache directory +// listings.) +// +// Returns ErrNotCached if the kernel is not currently caching the +// node. +func (c *Conn) InvalidateEntry(parent NodeID, name string) error { + const maxUint32 = ^uint32(0) + if uint64(len(name)) > uint64(maxUint32) { + // very unlikely, but we don't want to silently truncate + return syscall.ENAMETOOLONG + } + buf := newBuffer(unsafe.Sizeof(notifyInvalEntryOut{}) + uintptr(len(name)) + 1) + h := (*outHeader)(unsafe.Pointer(&buf[0])) + // h.Unique is 0 + h.Error = notifyCodeInvalEntry + out := (*notifyInvalEntryOut)(buf.alloc(unsafe.Sizeof(notifyInvalEntryOut{}))) + out.Parent = uint64(parent) + out.Namelen = uint32(len(name)) + buf = append(buf, name...) + buf = append(buf, '\x00') + return c.sendInvalidate(buf) +} + +// An InitRequest is the first request sent on a FUSE file system. +type InitRequest struct { + Header `json:"-"` + Kernel Protocol + // Maximum readahead in bytes that the kernel plans to use. + MaxReadahead uint32 + Flags InitFlags +} + +var _ = Request(&InitRequest{}) + +func (r *InitRequest) String() string { + return fmt.Sprintf("Init [%v] %v ra=%d fl=%v", &r.Header, r.Kernel, r.MaxReadahead, r.Flags) +} + +// An InitResponse is the response to an InitRequest. +type InitResponse struct { + Library Protocol + // Maximum readahead in bytes that the kernel can use. Ignored if + // greater than InitRequest.MaxReadahead. + MaxReadahead uint32 + Flags InitFlags + // Maximum size of a single write operation. + // Linux enforces a minimum of 4 KiB. + MaxWrite uint32 +} + +func (r *InitResponse) String() string { + return fmt.Sprintf("Init %v ra=%d fl=%v w=%d", r.Library, r.MaxReadahead, r.Flags, r.MaxWrite) +} + +// Respond replies to the request with the given response. +func (r *InitRequest) Respond(resp *InitResponse) { + buf := newBuffer(unsafe.Sizeof(initOut{})) + out := (*initOut)(buf.alloc(unsafe.Sizeof(initOut{}))) + out.Major = resp.Library.Major + out.Minor = resp.Library.Minor + out.MaxReadahead = resp.MaxReadahead + out.Flags = uint32(resp.Flags) + out.MaxWrite = resp.MaxWrite + + // MaxWrite larger than our receive buffer would just lead to + // errors on large writes. + if out.MaxWrite > maxWrite { + out.MaxWrite = maxWrite + } + r.respond(buf) +} + +// A StatfsRequest requests information about the mounted file system. +type StatfsRequest struct { + Header `json:"-"` +} + +var _ = Request(&StatfsRequest{}) + +func (r *StatfsRequest) String() string { + return fmt.Sprintf("Statfs [%s]", &r.Header) +} + +// Respond replies to the request with the given response. +func (r *StatfsRequest) Respond(resp *StatfsResponse) { + buf := newBuffer(unsafe.Sizeof(statfsOut{})) + out := (*statfsOut)(buf.alloc(unsafe.Sizeof(statfsOut{}))) + out.St = kstatfs{ + Blocks: resp.Blocks, + Bfree: resp.Bfree, + Bavail: resp.Bavail, + Files: resp.Files, + Ffree: resp.Ffree, + Bsize: resp.Bsize, + Namelen: resp.Namelen, + Frsize: resp.Frsize, + } + r.respond(buf) +} + +// A StatfsResponse is the response to a StatfsRequest. +type StatfsResponse struct { + Blocks uint64 // Total data blocks in file system. + Bfree uint64 // Free blocks in file system. + Bavail uint64 // Free blocks in file system if you're not root. + Files uint64 // Total files in file system. + Ffree uint64 // Free files in file system. + Bsize uint32 // Block size + Namelen uint32 // Maximum file name length? + Frsize uint32 // Fragment size, smallest addressable data size in the file system. +} + +func (r *StatfsResponse) String() string { + return fmt.Sprintf("Statfs blocks=%d/%d/%d files=%d/%d bsize=%d frsize=%d namelen=%d", + r.Bavail, r.Bfree, r.Blocks, + r.Ffree, r.Files, + r.Bsize, + r.Frsize, + r.Namelen, + ) +} + +// An AccessRequest asks whether the file can be accessed +// for the purpose specified by the mask. +type AccessRequest struct { + Header `json:"-"` + Mask uint32 +} + +var _ = Request(&AccessRequest{}) + +func (r *AccessRequest) String() string { + return fmt.Sprintf("Access [%s] mask=%#x", &r.Header, r.Mask) +} + +// Respond replies to the request indicating that access is allowed. +// To deny access, use RespondError. +func (r *AccessRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// An Attr is the metadata for a single file or directory. +type Attr struct { + Valid time.Duration // how long Attr can be cached + + Inode uint64 // inode number + Size uint64 // size in bytes + Blocks uint64 // size in 512-byte units + Atime time.Time // time of last access + Mtime time.Time // time of last modification + Ctime time.Time // time of last inode change + Crtime time.Time // time of creation (OS X only) + Mode os.FileMode // file mode + Nlink uint32 // number of links (usually 1) + Uid uint32 // owner uid + Gid uint32 // group gid + Rdev uint32 // device numbers + Flags uint32 // chflags(2) flags (OS X only) + BlockSize uint32 // preferred blocksize for filesystem I/O +} + +func (a Attr) String() string { + return fmt.Sprintf("valid=%v ino=%v size=%d mode=%v", a.Valid, a.Inode, a.Size, a.Mode) +} + +func unix(t time.Time) (sec uint64, nsec uint32) { + nano := t.UnixNano() + sec = uint64(nano / 1e9) + nsec = uint32(nano % 1e9) + return +} + +func (a *Attr) attr(out *attr, proto Protocol) { + out.Ino = a.Inode + out.Size = a.Size + out.Blocks = a.Blocks + out.Atime, out.AtimeNsec = unix(a.Atime) + out.Mtime, out.MtimeNsec = unix(a.Mtime) + out.Ctime, out.CtimeNsec = unix(a.Ctime) + out.SetCrtime(unix(a.Crtime)) + out.Mode = uint32(a.Mode) & 0777 + switch { + default: + out.Mode |= syscall.S_IFREG + case a.Mode&os.ModeDir != 0: + out.Mode |= syscall.S_IFDIR + case a.Mode&os.ModeDevice != 0: + if a.Mode&os.ModeCharDevice != 0 { + out.Mode |= syscall.S_IFCHR + } else { + out.Mode |= syscall.S_IFBLK + } + case a.Mode&os.ModeNamedPipe != 0: + out.Mode |= syscall.S_IFIFO + case a.Mode&os.ModeSymlink != 0: + out.Mode |= syscall.S_IFLNK + case a.Mode&os.ModeSocket != 0: + out.Mode |= syscall.S_IFSOCK + } + if a.Mode&os.ModeSetuid != 0 { + out.Mode |= syscall.S_ISUID + } + if a.Mode&os.ModeSetgid != 0 { + out.Mode |= syscall.S_ISGID + } + out.Nlink = a.Nlink + out.Uid = a.Uid + out.Gid = a.Gid + out.Rdev = a.Rdev + out.SetFlags(a.Flags) + if proto.GE(Protocol{7, 9}) { + out.Blksize = a.BlockSize + } + + return +} + +// A GetattrRequest asks for the metadata for the file denoted by r.Node. +type GetattrRequest struct { + Header `json:"-"` + Flags GetattrFlags + Handle HandleID +} + +var _ = Request(&GetattrRequest{}) + +func (r *GetattrRequest) String() string { + return fmt.Sprintf("Getattr [%s] %v fl=%v", &r.Header, r.Handle, r.Flags) +} + +// Respond replies to the request with the given response. +func (r *GetattrRequest) Respond(resp *GetattrResponse) { + size := attrOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*attrOut)(buf.alloc(size)) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A GetattrResponse is the response to a GetattrRequest. +type GetattrResponse struct { + Attr Attr // file attributes +} + +func (r *GetattrResponse) String() string { + return fmt.Sprintf("Getattr %v", r.Attr) +} + +// A GetxattrRequest asks for the extended attributes associated with r.Node. +type GetxattrRequest struct { + Header `json:"-"` + + // Maximum size to return. + Size uint32 + + // Name of the attribute requested. + Name string + + // Offset within extended attributes. + // + // Only valid for OS X, and then only with the resource fork + // attribute. + Position uint32 +} + +var _ = Request(&GetxattrRequest{}) + +func (r *GetxattrRequest) String() string { + return fmt.Sprintf("Getxattr [%s] %q %d @%d", &r.Header, r.Name, r.Size, r.Position) +} + +// Respond replies to the request with the given response. +func (r *GetxattrRequest) Respond(resp *GetxattrResponse) { + if r.Size == 0 { + buf := newBuffer(unsafe.Sizeof(getxattrOut{})) + out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{}))) + out.Size = uint32(len(resp.Xattr)) + r.respond(buf) + } else { + buf := newBuffer(uintptr(len(resp.Xattr))) + buf = append(buf, resp.Xattr...) + r.respond(buf) + } +} + +// A GetxattrResponse is the response to a GetxattrRequest. +type GetxattrResponse struct { + Xattr []byte +} + +func (r *GetxattrResponse) String() string { + return fmt.Sprintf("Getxattr %x", r.Xattr) +} + +// A ListxattrRequest asks to list the extended attributes associated with r.Node. +type ListxattrRequest struct { + Header `json:"-"` + Size uint32 // maximum size to return + Position uint32 // offset within attribute list +} + +var _ = Request(&ListxattrRequest{}) + +func (r *ListxattrRequest) String() string { + return fmt.Sprintf("Listxattr [%s] %d @%d", &r.Header, r.Size, r.Position) +} + +// Respond replies to the request with the given response. +func (r *ListxattrRequest) Respond(resp *ListxattrResponse) { + if r.Size == 0 { + buf := newBuffer(unsafe.Sizeof(getxattrOut{})) + out := (*getxattrOut)(buf.alloc(unsafe.Sizeof(getxattrOut{}))) + out.Size = uint32(len(resp.Xattr)) + r.respond(buf) + } else { + buf := newBuffer(uintptr(len(resp.Xattr))) + buf = append(buf, resp.Xattr...) + r.respond(buf) + } +} + +// A ListxattrResponse is the response to a ListxattrRequest. +type ListxattrResponse struct { + Xattr []byte +} + +func (r *ListxattrResponse) String() string { + return fmt.Sprintf("Listxattr %x", r.Xattr) +} + +// Append adds an extended attribute name to the response. +func (r *ListxattrResponse) Append(names ...string) { + for _, name := range names { + r.Xattr = append(r.Xattr, name...) + r.Xattr = append(r.Xattr, '\x00') + } +} + +// A RemovexattrRequest asks to remove an extended attribute associated with r.Node. +type RemovexattrRequest struct { + Header `json:"-"` + Name string // name of extended attribute +} + +var _ = Request(&RemovexattrRequest{}) + +func (r *RemovexattrRequest) String() string { + return fmt.Sprintf("Removexattr [%s] %q", &r.Header, r.Name) +} + +// Respond replies to the request, indicating that the attribute was removed. +func (r *RemovexattrRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A SetxattrRequest asks to set an extended attribute associated with a file. +type SetxattrRequest struct { + Header `json:"-"` + + // Flags can make the request fail if attribute does/not already + // exist. Unfortunately, the constants are platform-specific and + // not exposed by Go1.2. Look for XATTR_CREATE, XATTR_REPLACE. + // + // TODO improve this later + // + // TODO XATTR_CREATE and exist -> EEXIST + // + // TODO XATTR_REPLACE and not exist -> ENODATA + Flags uint32 + + // Offset within extended attributes. + // + // Only valid for OS X, and then only with the resource fork + // attribute. + Position uint32 + + Name string + Xattr []byte +} + +var _ = Request(&SetxattrRequest{}) + +func trunc(b []byte, max int) ([]byte, string) { + if len(b) > max { + return b[:max], "..." + } + return b, "" +} + +func (r *SetxattrRequest) String() string { + xattr, tail := trunc(r.Xattr, 16) + return fmt.Sprintf("Setxattr [%s] %q %x%s fl=%v @%#x", &r.Header, r.Name, xattr, tail, r.Flags, r.Position) +} + +// Respond replies to the request, indicating that the extended attribute was set. +func (r *SetxattrRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A LookupRequest asks to look up the given name in the directory named by r.Node. +type LookupRequest struct { + Header `json:"-"` + Name string +} + +var _ = Request(&LookupRequest{}) + +func (r *LookupRequest) String() string { + return fmt.Sprintf("Lookup [%s] %q", &r.Header, r.Name) +} + +// Respond replies to the request with the given response. +func (r *LookupRequest) Respond(resp *LookupResponse) { + size := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*entryOut)(buf.alloc(size)) + out.Nodeid = uint64(resp.Node) + out.Generation = resp.Generation + out.EntryValid = uint64(resp.EntryValid / time.Second) + out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A LookupResponse is the response to a LookupRequest. +type LookupResponse struct { + Node NodeID + Generation uint64 + EntryValid time.Duration + Attr Attr +} + +func (r *LookupResponse) string() string { + return fmt.Sprintf("%v gen=%d valid=%v attr={%v}", r.Node, r.Generation, r.EntryValid, r.Attr) +} + +func (r *LookupResponse) String() string { + return fmt.Sprintf("Lookup %s", r.string()) +} + +// An OpenRequest asks to open a file or directory +type OpenRequest struct { + Header `json:"-"` + Dir bool // is this Opendir? + Flags OpenFlags +} + +var _ = Request(&OpenRequest{}) + +func (r *OpenRequest) String() string { + return fmt.Sprintf("Open [%s] dir=%v fl=%v", &r.Header, r.Dir, r.Flags) +} + +// Respond replies to the request with the given response. +func (r *OpenRequest) Respond(resp *OpenResponse) { + buf := newBuffer(unsafe.Sizeof(openOut{})) + out := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{}))) + out.Fh = uint64(resp.Handle) + out.OpenFlags = uint32(resp.Flags) + r.respond(buf) +} + +// A OpenResponse is the response to a OpenRequest. +type OpenResponse struct { + Handle HandleID + Flags OpenResponseFlags +} + +func (r *OpenResponse) string() string { + return fmt.Sprintf("%v fl=%v", r.Handle, r.Flags) +} + +func (r *OpenResponse) String() string { + return fmt.Sprintf("Open %s", r.string()) +} + +// A CreateRequest asks to create and open a file (not a directory). +type CreateRequest struct { + Header `json:"-"` + Name string + Flags OpenFlags + Mode os.FileMode + // Umask of the request. Not supported on OS X. + Umask os.FileMode +} + +var _ = Request(&CreateRequest{}) + +func (r *CreateRequest) String() string { + return fmt.Sprintf("Create [%s] %q fl=%v mode=%v umask=%v", &r.Header, r.Name, r.Flags, r.Mode, r.Umask) +} + +// Respond replies to the request with the given response. +func (r *CreateRequest) Respond(resp *CreateResponse) { + eSize := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(eSize + unsafe.Sizeof(openOut{})) + + e := (*entryOut)(buf.alloc(eSize)) + e.Nodeid = uint64(resp.Node) + e.Generation = resp.Generation + e.EntryValid = uint64(resp.EntryValid / time.Second) + e.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + e.AttrValid = uint64(resp.Attr.Valid / time.Second) + e.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&e.Attr, r.Header.Conn.proto) + + o := (*openOut)(buf.alloc(unsafe.Sizeof(openOut{}))) + o.Fh = uint64(resp.Handle) + o.OpenFlags = uint32(resp.Flags) + + r.respond(buf) +} + +// A CreateResponse is the response to a CreateRequest. +// It describes the created node and opened handle. +type CreateResponse struct { + LookupResponse + OpenResponse +} + +func (r *CreateResponse) String() string { + return fmt.Sprintf("Create {%s} {%s}", r.LookupResponse.string(), r.OpenResponse.string()) +} + +// A MkdirRequest asks to create (but not open) a directory. +type MkdirRequest struct { + Header `json:"-"` + Name string + Mode os.FileMode + // Umask of the request. Not supported on OS X. + Umask os.FileMode +} + +var _ = Request(&MkdirRequest{}) + +func (r *MkdirRequest) String() string { + return fmt.Sprintf("Mkdir [%s] %q mode=%v umask=%v", &r.Header, r.Name, r.Mode, r.Umask) +} + +// Respond replies to the request with the given response. +func (r *MkdirRequest) Respond(resp *MkdirResponse) { + size := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*entryOut)(buf.alloc(size)) + out.Nodeid = uint64(resp.Node) + out.Generation = resp.Generation + out.EntryValid = uint64(resp.EntryValid / time.Second) + out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A MkdirResponse is the response to a MkdirRequest. +type MkdirResponse struct { + LookupResponse +} + +func (r *MkdirResponse) String() string { + return fmt.Sprintf("Mkdir %v", r.LookupResponse.string()) +} + +// A ReadRequest asks to read from an open file. +type ReadRequest struct { + Header `json:"-"` + Dir bool // is this Readdir? + Handle HandleID + Offset int64 + Size int + Flags ReadFlags + LockOwner uint64 + FileFlags OpenFlags +} + +var _ = Request(&ReadRequest{}) + +func (r *ReadRequest) String() string { + return fmt.Sprintf("Read [%s] %v %d @%#x dir=%v fl=%v lock=%d ffl=%v", &r.Header, r.Handle, r.Size, r.Offset, r.Dir, r.Flags, r.LockOwner, r.FileFlags) +} + +// Respond replies to the request with the given response. +func (r *ReadRequest) Respond(resp *ReadResponse) { + buf := newBuffer(uintptr(len(resp.Data))) + buf = append(buf, resp.Data...) + r.respond(buf) +} + +// A ReadResponse is the response to a ReadRequest. +type ReadResponse struct { + Data []byte +} + +func (r *ReadResponse) String() string { + return fmt.Sprintf("Read %d", len(r.Data)) +} + +type jsonReadResponse struct { + Len uint64 +} + +func (r *ReadResponse) MarshalJSON() ([]byte, error) { + j := jsonReadResponse{ + Len: uint64(len(r.Data)), + } + return json.Marshal(j) +} + +// A ReleaseRequest asks to release (close) an open file handle. +type ReleaseRequest struct { + Header `json:"-"` + Dir bool // is this Releasedir? + Handle HandleID + Flags OpenFlags // flags from OpenRequest + ReleaseFlags ReleaseFlags + LockOwner uint32 +} + +var _ = Request(&ReleaseRequest{}) + +func (r *ReleaseRequest) String() string { + return fmt.Sprintf("Release [%s] %v fl=%v rfl=%v owner=%#x", &r.Header, r.Handle, r.Flags, r.ReleaseFlags, r.LockOwner) +} + +// Respond replies to the request, indicating that the handle has been released. +func (r *ReleaseRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A DestroyRequest is sent by the kernel when unmounting the file system. +// No more requests will be received after this one, but it should still be +// responded to. +type DestroyRequest struct { + Header `json:"-"` +} + +var _ = Request(&DestroyRequest{}) + +func (r *DestroyRequest) String() string { + return fmt.Sprintf("Destroy [%s]", &r.Header) +} + +// Respond replies to the request. +func (r *DestroyRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A ForgetRequest is sent by the kernel when forgetting about r.Node +// as returned by r.N lookup requests. +type ForgetRequest struct { + Header `json:"-"` + N uint64 +} + +var _ = Request(&ForgetRequest{}) + +func (r *ForgetRequest) String() string { + return fmt.Sprintf("Forget [%s] %d", &r.Header, r.N) +} + +// Respond replies to the request, indicating that the forgetfulness has been recorded. +func (r *ForgetRequest) Respond() { + // Don't reply to forget messages. + r.noResponse() +} + +// A Dirent represents a single directory entry. +type Dirent struct { + // Inode this entry names. + Inode uint64 + + // Type of the entry, for example DT_File. + // + // Setting this is optional. The zero value (DT_Unknown) means + // callers will just need to do a Getattr when the type is + // needed. Providing a type can speed up operations + // significantly. + Type DirentType + + // Name of the entry + Name string +} + +// Type of an entry in a directory listing. +type DirentType uint32 + +const ( + // These don't quite match os.FileMode; especially there's an + // explicit unknown, instead of zero value meaning file. They + // are also not quite syscall.DT_*; nothing says the FUSE + // protocol follows those, and even if they were, we don't + // want each fs to fiddle with syscall. + + // The shift by 12 is hardcoded in the FUSE userspace + // low-level C library, so it's safe here. + + DT_Unknown DirentType = 0 + DT_Socket DirentType = syscall.S_IFSOCK >> 12 + DT_Link DirentType = syscall.S_IFLNK >> 12 + DT_File DirentType = syscall.S_IFREG >> 12 + DT_Block DirentType = syscall.S_IFBLK >> 12 + DT_Dir DirentType = syscall.S_IFDIR >> 12 + DT_Char DirentType = syscall.S_IFCHR >> 12 + DT_FIFO DirentType = syscall.S_IFIFO >> 12 +) + +func (t DirentType) String() string { + switch t { + case DT_Unknown: + return "unknown" + case DT_Socket: + return "socket" + case DT_Link: + return "link" + case DT_File: + return "file" + case DT_Block: + return "block" + case DT_Dir: + return "dir" + case DT_Char: + return "char" + case DT_FIFO: + return "fifo" + } + return "invalid" +} + +// AppendDirent appends the encoded form of a directory entry to data +// and returns the resulting slice. +func AppendDirent(data []byte, dir Dirent) []byte { + de := dirent{ + Ino: dir.Inode, + Namelen: uint32(len(dir.Name)), + Type: uint32(dir.Type), + } + de.Off = uint64(len(data) + direntSize + (len(dir.Name)+7)&^7) + data = append(data, (*[direntSize]byte)(unsafe.Pointer(&de))[:]...) + data = append(data, dir.Name...) + n := direntSize + uintptr(len(dir.Name)) + if n%8 != 0 { + var pad [8]byte + data = append(data, pad[:8-n%8]...) + } + return data +} + +// A WriteRequest asks to write to an open file. +type WriteRequest struct { + Header + Handle HandleID + Offset int64 + Data []byte + Flags WriteFlags + LockOwner uint64 + FileFlags OpenFlags +} + +var _ = Request(&WriteRequest{}) + +func (r *WriteRequest) String() string { + return fmt.Sprintf("Write [%s] %v %d @%d fl=%v lock=%d ffl=%v", &r.Header, r.Handle, len(r.Data), r.Offset, r.Flags, r.LockOwner, r.FileFlags) +} + +type jsonWriteRequest struct { + Handle HandleID + Offset int64 + Len uint64 + Flags WriteFlags +} + +func (r *WriteRequest) MarshalJSON() ([]byte, error) { + j := jsonWriteRequest{ + Handle: r.Handle, + Offset: r.Offset, + Len: uint64(len(r.Data)), + Flags: r.Flags, + } + return json.Marshal(j) +} + +// Respond replies to the request with the given response. +func (r *WriteRequest) Respond(resp *WriteResponse) { + buf := newBuffer(unsafe.Sizeof(writeOut{})) + out := (*writeOut)(buf.alloc(unsafe.Sizeof(writeOut{}))) + out.Size = uint32(resp.Size) + r.respond(buf) +} + +// A WriteResponse replies to a write indicating how many bytes were written. +type WriteResponse struct { + Size int +} + +func (r *WriteResponse) String() string { + return fmt.Sprintf("Write %d", r.Size) +} + +// A SetattrRequest asks to change one or more attributes associated with a file, +// as indicated by Valid. +type SetattrRequest struct { + Header `json:"-"` + Valid SetattrValid + Handle HandleID + Size uint64 + Atime time.Time + Mtime time.Time + Mode os.FileMode + Uid uint32 + Gid uint32 + + // OS X only + Bkuptime time.Time + Chgtime time.Time + Crtime time.Time + Flags uint32 // see chflags(2) +} + +var _ = Request(&SetattrRequest{}) + +func (r *SetattrRequest) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "Setattr [%s]", &r.Header) + if r.Valid.Mode() { + fmt.Fprintf(&buf, " mode=%v", r.Mode) + } + if r.Valid.Uid() { + fmt.Fprintf(&buf, " uid=%d", r.Uid) + } + if r.Valid.Gid() { + fmt.Fprintf(&buf, " gid=%d", r.Gid) + } + if r.Valid.Size() { + fmt.Fprintf(&buf, " size=%d", r.Size) + } + if r.Valid.Atime() { + fmt.Fprintf(&buf, " atime=%v", r.Atime) + } + if r.Valid.AtimeNow() { + fmt.Fprintf(&buf, " atime=now") + } + if r.Valid.Mtime() { + fmt.Fprintf(&buf, " mtime=%v", r.Mtime) + } + if r.Valid.MtimeNow() { + fmt.Fprintf(&buf, " mtime=now") + } + if r.Valid.Handle() { + fmt.Fprintf(&buf, " handle=%v", r.Handle) + } else { + fmt.Fprintf(&buf, " handle=INVALID-%v", r.Handle) + } + if r.Valid.LockOwner() { + fmt.Fprintf(&buf, " lockowner") + } + if r.Valid.Crtime() { + fmt.Fprintf(&buf, " crtime=%v", r.Crtime) + } + if r.Valid.Chgtime() { + fmt.Fprintf(&buf, " chgtime=%v", r.Chgtime) + } + if r.Valid.Bkuptime() { + fmt.Fprintf(&buf, " bkuptime=%v", r.Bkuptime) + } + if r.Valid.Flags() { + fmt.Fprintf(&buf, " flags=%v", r.Flags) + } + return buf.String() +} + +// Respond replies to the request with the given response, +// giving the updated attributes. +func (r *SetattrRequest) Respond(resp *SetattrResponse) { + size := attrOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*attrOut)(buf.alloc(size)) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A SetattrResponse is the response to a SetattrRequest. +type SetattrResponse struct { + Attr Attr // file attributes +} + +func (r *SetattrResponse) String() string { + return fmt.Sprintf("Setattr %v", r.Attr) +} + +// A FlushRequest asks for the current state of an open file to be flushed +// to storage, as when a file descriptor is being closed. A single opened Handle +// may receive multiple FlushRequests over its lifetime. +type FlushRequest struct { + Header `json:"-"` + Handle HandleID + Flags uint32 + LockOwner uint64 +} + +var _ = Request(&FlushRequest{}) + +func (r *FlushRequest) String() string { + return fmt.Sprintf("Flush [%s] %v fl=%#x lk=%#x", &r.Header, r.Handle, r.Flags, r.LockOwner) +} + +// Respond replies to the request, indicating that the flush succeeded. +func (r *FlushRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A RemoveRequest asks to remove a file or directory from the +// directory r.Node. +type RemoveRequest struct { + Header `json:"-"` + Name string // name of the entry to remove + Dir bool // is this rmdir? +} + +var _ = Request(&RemoveRequest{}) + +func (r *RemoveRequest) String() string { + return fmt.Sprintf("Remove [%s] %q dir=%v", &r.Header, r.Name, r.Dir) +} + +// Respond replies to the request, indicating that the file was removed. +func (r *RemoveRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// A SymlinkRequest is a request to create a symlink making NewName point to Target. +type SymlinkRequest struct { + Header `json:"-"` + NewName, Target string +} + +var _ = Request(&SymlinkRequest{}) + +func (r *SymlinkRequest) String() string { + return fmt.Sprintf("Symlink [%s] from %q to target %q", &r.Header, r.NewName, r.Target) +} + +// Respond replies to the request, indicating that the symlink was created. +func (r *SymlinkRequest) Respond(resp *SymlinkResponse) { + size := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*entryOut)(buf.alloc(size)) + out.Nodeid = uint64(resp.Node) + out.Generation = resp.Generation + out.EntryValid = uint64(resp.EntryValid / time.Second) + out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A SymlinkResponse is the response to a SymlinkRequest. +type SymlinkResponse struct { + LookupResponse +} + +func (r *SymlinkResponse) String() string { + return fmt.Sprintf("Symlink %v", r.LookupResponse.string()) +} + +// A ReadlinkRequest is a request to read a symlink's target. +type ReadlinkRequest struct { + Header `json:"-"` +} + +var _ = Request(&ReadlinkRequest{}) + +func (r *ReadlinkRequest) String() string { + return fmt.Sprintf("Readlink [%s]", &r.Header) +} + +func (r *ReadlinkRequest) Respond(target string) { + buf := newBuffer(uintptr(len(target))) + buf = append(buf, target...) + r.respond(buf) +} + +// A LinkRequest is a request to create a hard link. +type LinkRequest struct { + Header `json:"-"` + OldNode NodeID + NewName string +} + +var _ = Request(&LinkRequest{}) + +func (r *LinkRequest) String() string { + return fmt.Sprintf("Link [%s] node %d to %q", &r.Header, r.OldNode, r.NewName) +} + +func (r *LinkRequest) Respond(resp *LookupResponse) { + size := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*entryOut)(buf.alloc(size)) + out.Nodeid = uint64(resp.Node) + out.Generation = resp.Generation + out.EntryValid = uint64(resp.EntryValid / time.Second) + out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +// A RenameRequest is a request to rename a file. +type RenameRequest struct { + Header `json:"-"` + NewDir NodeID + OldName, NewName string +} + +var _ = Request(&RenameRequest{}) + +func (r *RenameRequest) String() string { + return fmt.Sprintf("Rename [%s] from %q to dirnode %v %q", &r.Header, r.OldName, r.NewDir, r.NewName) +} + +func (r *RenameRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +type MknodRequest struct { + Header `json:"-"` + Name string + Mode os.FileMode + Rdev uint32 + // Umask of the request. Not supported on OS X. + Umask os.FileMode +} + +var _ = Request(&MknodRequest{}) + +func (r *MknodRequest) String() string { + return fmt.Sprintf("Mknod [%s] Name %q mode=%v umask=%v rdev=%d", &r.Header, r.Name, r.Mode, r.Umask, r.Rdev) +} + +func (r *MknodRequest) Respond(resp *LookupResponse) { + size := entryOutSize(r.Header.Conn.proto) + buf := newBuffer(size) + out := (*entryOut)(buf.alloc(size)) + out.Nodeid = uint64(resp.Node) + out.Generation = resp.Generation + out.EntryValid = uint64(resp.EntryValid / time.Second) + out.EntryValidNsec = uint32(resp.EntryValid % time.Second / time.Nanosecond) + out.AttrValid = uint64(resp.Attr.Valid / time.Second) + out.AttrValidNsec = uint32(resp.Attr.Valid % time.Second / time.Nanosecond) + resp.Attr.attr(&out.Attr, r.Header.Conn.proto) + r.respond(buf) +} + +type FsyncRequest struct { + Header `json:"-"` + Handle HandleID + // TODO bit 1 is datasync, not well documented upstream + Flags uint32 + Dir bool +} + +var _ = Request(&FsyncRequest{}) + +func (r *FsyncRequest) String() string { + return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags) +} + +func (r *FsyncRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} + +// An InterruptRequest is a request to interrupt another pending request. The +// response to that request should return an error status of EINTR. +type InterruptRequest struct { + Header `json:"-"` + IntrID RequestID // ID of the request to be interrupt. +} + +var _ = Request(&InterruptRequest{}) + +func (r *InterruptRequest) Respond() { + // nothing to do here + r.noResponse() +} + +func (r *InterruptRequest) String() string { + return fmt.Sprintf("Interrupt [%s] ID %v", &r.Header, r.IntrID) +} + +// An ExchangeDataRequest is a request to exchange the contents of two +// files, while leaving most metadata untouched. +// +// This request comes from OS X exchangedata(2) and represents its +// specific semantics. Crucially, it is very different from Linux +// renameat(2) RENAME_EXCHANGE. +// +// https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/exchangedata.2.html +type ExchangeDataRequest struct { + Header `json:"-"` + OldDir, NewDir NodeID + OldName, NewName string + // TODO options +} + +var _ = Request(&ExchangeDataRequest{}) + +func (r *ExchangeDataRequest) String() string { + // TODO options + return fmt.Sprintf("ExchangeData [%s] %v %q and %v %q", &r.Header, r.OldDir, r.OldName, r.NewDir, r.NewName) +} + +func (r *ExchangeDataRequest) Respond() { + buf := newBuffer(0) + r.respond(buf) +} diff --git a/vendor/bazil.org/fuse/fuse_darwin.go b/vendor/bazil.org/fuse/fuse_darwin.go new file mode 100644 index 00000000..b58dca97 --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_darwin.go @@ -0,0 +1,9 @@ +package fuse + +// Maximum file write size we are prepared to receive from the kernel. +// +// This value has to be >=16MB or OSXFUSE (3.4.0 observed) will +// forcibly close the /dev/fuse file descriptor on a Setxattr with a +// 16MB value. See TestSetxattr16MB and +// https://github.com/bazil/fuse/issues/42 +const maxWrite = 16 * 1024 * 1024 diff --git a/vendor/bazil.org/fuse/fuse_freebsd.go b/vendor/bazil.org/fuse/fuse_freebsd.go new file mode 100644 index 00000000..4aa83a0d --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_freebsd.go @@ -0,0 +1,6 @@ +package fuse + +// Maximum file write size we are prepared to receive from the kernel. +// +// This number is just a guess. +const maxWrite = 128 * 1024 diff --git a/vendor/bazil.org/fuse/fuse_kernel.go b/vendor/bazil.org/fuse/fuse_kernel.go new file mode 100644 index 00000000..87c5ca1d --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_kernel.go @@ -0,0 +1,774 @@ +// See the file LICENSE for copyright and licensing information. + +// Derived from FUSE's fuse_kernel.h, which carries this notice: +/* + This file defines the kernel interface of FUSE + Copyright (C) 2001-2007 Miklos Szeredi + + + This -- and only this -- header file may also be distributed under + the terms of the BSD Licence as follows: + + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. 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. + + THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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 fuse + +import ( + "fmt" + "syscall" + "unsafe" +) + +// The FUSE version implemented by the package. +const ( + protoVersionMinMajor = 7 + protoVersionMinMinor = 8 + protoVersionMaxMajor = 7 + protoVersionMaxMinor = 12 +) + +const ( + rootID = 1 +) + +type kstatfs struct { + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Bsize uint32 + Namelen uint32 + Frsize uint32 + _ uint32 + Spare [6]uint32 +} + +type fileLock struct { + Start uint64 + End uint64 + Type uint32 + Pid uint32 +} + +// GetattrFlags are bit flags that can be seen in GetattrRequest. +type GetattrFlags uint32 + +const ( + // Indicates the handle is valid. + GetattrFh GetattrFlags = 1 << 0 +) + +var getattrFlagsNames = []flagName{ + {uint32(GetattrFh), "GetattrFh"}, +} + +func (fl GetattrFlags) String() string { + return flagString(uint32(fl), getattrFlagsNames) +} + +// The SetattrValid are bit flags describing which fields in the SetattrRequest +// are included in the change. +type SetattrValid uint32 + +const ( + SetattrMode SetattrValid = 1 << 0 + SetattrUid SetattrValid = 1 << 1 + SetattrGid SetattrValid = 1 << 2 + SetattrSize SetattrValid = 1 << 3 + SetattrAtime SetattrValid = 1 << 4 + SetattrMtime SetattrValid = 1 << 5 + SetattrHandle SetattrValid = 1 << 6 + + // Linux only(?) + SetattrAtimeNow SetattrValid = 1 << 7 + SetattrMtimeNow SetattrValid = 1 << 8 + SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html + + // OS X only + SetattrCrtime SetattrValid = 1 << 28 + SetattrChgtime SetattrValid = 1 << 29 + SetattrBkuptime SetattrValid = 1 << 30 + SetattrFlags SetattrValid = 1 << 31 +) + +func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 } +func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 } +func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 } +func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 } +func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 } +func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 } +func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 } +func (fl SetattrValid) AtimeNow() bool { return fl&SetattrAtimeNow != 0 } +func (fl SetattrValid) MtimeNow() bool { return fl&SetattrMtimeNow != 0 } +func (fl SetattrValid) LockOwner() bool { return fl&SetattrLockOwner != 0 } +func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 } +func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 } +func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 } +func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 } + +func (fl SetattrValid) String() string { + return flagString(uint32(fl), setattrValidNames) +} + +var setattrValidNames = []flagName{ + {uint32(SetattrMode), "SetattrMode"}, + {uint32(SetattrUid), "SetattrUid"}, + {uint32(SetattrGid), "SetattrGid"}, + {uint32(SetattrSize), "SetattrSize"}, + {uint32(SetattrAtime), "SetattrAtime"}, + {uint32(SetattrMtime), "SetattrMtime"}, + {uint32(SetattrHandle), "SetattrHandle"}, + {uint32(SetattrAtimeNow), "SetattrAtimeNow"}, + {uint32(SetattrMtimeNow), "SetattrMtimeNow"}, + {uint32(SetattrLockOwner), "SetattrLockOwner"}, + {uint32(SetattrCrtime), "SetattrCrtime"}, + {uint32(SetattrChgtime), "SetattrChgtime"}, + {uint32(SetattrBkuptime), "SetattrBkuptime"}, + {uint32(SetattrFlags), "SetattrFlags"}, +} + +// Flags that can be seen in OpenRequest.Flags. +const ( + // Access modes. These are not 1-bit flags, but alternatives where + // only one can be chosen. See the IsReadOnly etc convenience + // methods. + OpenReadOnly OpenFlags = syscall.O_RDONLY + OpenWriteOnly OpenFlags = syscall.O_WRONLY + OpenReadWrite OpenFlags = syscall.O_RDWR + + // File was opened in append-only mode, all writes will go to end + // of file. OS X does not provide this information. + OpenAppend OpenFlags = syscall.O_APPEND + OpenCreate OpenFlags = syscall.O_CREAT + OpenDirectory OpenFlags = syscall.O_DIRECTORY + OpenExclusive OpenFlags = syscall.O_EXCL + OpenNonblock OpenFlags = syscall.O_NONBLOCK + OpenSync OpenFlags = syscall.O_SYNC + OpenTruncate OpenFlags = syscall.O_TRUNC +) + +// OpenAccessModeMask is a bitmask that separates the access mode +// from the other flags in OpenFlags. +const OpenAccessModeMask OpenFlags = syscall.O_ACCMODE + +// OpenFlags are the O_FOO flags passed to open/create/etc calls. For +// example, os.O_WRONLY | os.O_APPEND. +type OpenFlags uint32 + +func (fl OpenFlags) String() string { + // O_RDONLY, O_RWONLY, O_RDWR are not flags + s := accModeName(fl & OpenAccessModeMask) + flags := uint32(fl &^ OpenAccessModeMask) + if flags != 0 { + s = s + "+" + flagString(flags, openFlagNames) + } + return s +} + +// Return true if OpenReadOnly is set. +func (fl OpenFlags) IsReadOnly() bool { + return fl&OpenAccessModeMask == OpenReadOnly +} + +// Return true if OpenWriteOnly is set. +func (fl OpenFlags) IsWriteOnly() bool { + return fl&OpenAccessModeMask == OpenWriteOnly +} + +// Return true if OpenReadWrite is set. +func (fl OpenFlags) IsReadWrite() bool { + return fl&OpenAccessModeMask == OpenReadWrite +} + +func accModeName(flags OpenFlags) string { + switch flags { + case OpenReadOnly: + return "OpenReadOnly" + case OpenWriteOnly: + return "OpenWriteOnly" + case OpenReadWrite: + return "OpenReadWrite" + default: + return "" + } +} + +var openFlagNames = []flagName{ + {uint32(OpenAppend), "OpenAppend"}, + {uint32(OpenCreate), "OpenCreate"}, + {uint32(OpenDirectory), "OpenDirectory"}, + {uint32(OpenExclusive), "OpenExclusive"}, + {uint32(OpenNonblock), "OpenNonblock"}, + {uint32(OpenSync), "OpenSync"}, + {uint32(OpenTruncate), "OpenTruncate"}, +} + +// The OpenResponseFlags are returned in the OpenResponse. +type OpenResponseFlags uint32 + +const ( + OpenDirectIO OpenResponseFlags = 1 << 0 // bypass page cache for this open file + OpenKeepCache OpenResponseFlags = 1 << 1 // don't invalidate the data cache on open + OpenNonSeekable OpenResponseFlags = 1 << 2 // mark the file as non-seekable (not supported on OS X) + + OpenPurgeAttr OpenResponseFlags = 1 << 30 // OS X + OpenPurgeUBC OpenResponseFlags = 1 << 31 // OS X +) + +func (fl OpenResponseFlags) String() string { + return flagString(uint32(fl), openResponseFlagNames) +} + +var openResponseFlagNames = []flagName{ + {uint32(OpenDirectIO), "OpenDirectIO"}, + {uint32(OpenKeepCache), "OpenKeepCache"}, + {uint32(OpenNonSeekable), "OpenNonSeekable"}, + {uint32(OpenPurgeAttr), "OpenPurgeAttr"}, + {uint32(OpenPurgeUBC), "OpenPurgeUBC"}, +} + +// The InitFlags are used in the Init exchange. +type InitFlags uint32 + +const ( + InitAsyncRead InitFlags = 1 << 0 + InitPosixLocks InitFlags = 1 << 1 + InitFileOps InitFlags = 1 << 2 + InitAtomicTrunc InitFlags = 1 << 3 + InitExportSupport InitFlags = 1 << 4 + InitBigWrites InitFlags = 1 << 5 + // Do not mask file access modes with umask. Not supported on OS X. + InitDontMask InitFlags = 1 << 6 + InitSpliceWrite InitFlags = 1 << 7 + InitSpliceMove InitFlags = 1 << 8 + InitSpliceRead InitFlags = 1 << 9 + InitFlockLocks InitFlags = 1 << 10 + InitHasIoctlDir InitFlags = 1 << 11 + InitAutoInvalData InitFlags = 1 << 12 + InitDoReaddirplus InitFlags = 1 << 13 + InitReaddirplusAuto InitFlags = 1 << 14 + InitAsyncDIO InitFlags = 1 << 15 + InitWritebackCache InitFlags = 1 << 16 + InitNoOpenSupport InitFlags = 1 << 17 + + InitCaseSensitive InitFlags = 1 << 29 // OS X only + InitVolRename InitFlags = 1 << 30 // OS X only + InitXtimes InitFlags = 1 << 31 // OS X only +) + +type flagName struct { + bit uint32 + name string +} + +var initFlagNames = []flagName{ + {uint32(InitAsyncRead), "InitAsyncRead"}, + {uint32(InitPosixLocks), "InitPosixLocks"}, + {uint32(InitFileOps), "InitFileOps"}, + {uint32(InitAtomicTrunc), "InitAtomicTrunc"}, + {uint32(InitExportSupport), "InitExportSupport"}, + {uint32(InitBigWrites), "InitBigWrites"}, + {uint32(InitDontMask), "InitDontMask"}, + {uint32(InitSpliceWrite), "InitSpliceWrite"}, + {uint32(InitSpliceMove), "InitSpliceMove"}, + {uint32(InitSpliceRead), "InitSpliceRead"}, + {uint32(InitFlockLocks), "InitFlockLocks"}, + {uint32(InitHasIoctlDir), "InitHasIoctlDir"}, + {uint32(InitAutoInvalData), "InitAutoInvalData"}, + {uint32(InitDoReaddirplus), "InitDoReaddirplus"}, + {uint32(InitReaddirplusAuto), "InitReaddirplusAuto"}, + {uint32(InitAsyncDIO), "InitAsyncDIO"}, + {uint32(InitWritebackCache), "InitWritebackCache"}, + {uint32(InitNoOpenSupport), "InitNoOpenSupport"}, + + {uint32(InitCaseSensitive), "InitCaseSensitive"}, + {uint32(InitVolRename), "InitVolRename"}, + {uint32(InitXtimes), "InitXtimes"}, +} + +func (fl InitFlags) String() string { + return flagString(uint32(fl), initFlagNames) +} + +func flagString(f uint32, names []flagName) string { + var s string + + if f == 0 { + return "0" + } + + for _, n := range names { + if f&n.bit != 0 { + s += "+" + n.name + f &^= n.bit + } + } + if f != 0 { + s += fmt.Sprintf("%+#x", f) + } + return s[1:] +} + +// The ReleaseFlags are used in the Release exchange. +type ReleaseFlags uint32 + +const ( + ReleaseFlush ReleaseFlags = 1 << 0 +) + +func (fl ReleaseFlags) String() string { + return flagString(uint32(fl), releaseFlagNames) +} + +var releaseFlagNames = []flagName{ + {uint32(ReleaseFlush), "ReleaseFlush"}, +} + +// Opcodes +const ( + opLookup = 1 + opForget = 2 // no reply + opGetattr = 3 + opSetattr = 4 + opReadlink = 5 + opSymlink = 6 + opMknod = 8 + opMkdir = 9 + opUnlink = 10 + opRmdir = 11 + opRename = 12 + opLink = 13 + opOpen = 14 + opRead = 15 + opWrite = 16 + opStatfs = 17 + opRelease = 18 + opFsync = 20 + opSetxattr = 21 + opGetxattr = 22 + opListxattr = 23 + opRemovexattr = 24 + opFlush = 25 + opInit = 26 + opOpendir = 27 + opReaddir = 28 + opReleasedir = 29 + opFsyncdir = 30 + opGetlk = 31 + opSetlk = 32 + opSetlkw = 33 + opAccess = 34 + opCreate = 35 + opInterrupt = 36 + opBmap = 37 + opDestroy = 38 + opIoctl = 39 // Linux? + opPoll = 40 // Linux? + + // OS X + opSetvolname = 61 + opGetxtimes = 62 + opExchange = 63 +) + +type entryOut struct { + Nodeid uint64 // Inode ID + Generation uint64 // Inode generation + EntryValid uint64 // Cache timeout for the name + AttrValid uint64 // Cache timeout for the attributes + EntryValidNsec uint32 + AttrValidNsec uint32 + Attr attr +} + +func entryOutSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 9}): + return unsafe.Offsetof(entryOut{}.Attr) + unsafe.Offsetof(entryOut{}.Attr.Blksize) + default: + return unsafe.Sizeof(entryOut{}) + } +} + +type forgetIn struct { + Nlookup uint64 +} + +type getattrIn struct { + GetattrFlags uint32 + _ uint32 + Fh uint64 +} + +type attrOut struct { + AttrValid uint64 // Cache timeout for the attributes + AttrValidNsec uint32 + _ uint32 + Attr attr +} + +func attrOutSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 9}): + return unsafe.Offsetof(attrOut{}.Attr) + unsafe.Offsetof(attrOut{}.Attr.Blksize) + default: + return unsafe.Sizeof(attrOut{}) + } +} + +// OS X +type getxtimesOut struct { + Bkuptime uint64 + Crtime uint64 + BkuptimeNsec uint32 + CrtimeNsec uint32 +} + +type mknodIn struct { + Mode uint32 + Rdev uint32 + Umask uint32 + _ uint32 + // "filename\x00" follows. +} + +func mknodInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 12}): + return unsafe.Offsetof(mknodIn{}.Umask) + default: + return unsafe.Sizeof(mknodIn{}) + } +} + +type mkdirIn struct { + Mode uint32 + Umask uint32 + // filename follows +} + +func mkdirInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 12}): + return unsafe.Offsetof(mkdirIn{}.Umask) + 4 + default: + return unsafe.Sizeof(mkdirIn{}) + } +} + +type renameIn struct { + Newdir uint64 + // "oldname\x00newname\x00" follows +} + +// OS X +type exchangeIn struct { + Olddir uint64 + Newdir uint64 + Options uint64 + // "oldname\x00newname\x00" follows +} + +type linkIn struct { + Oldnodeid uint64 +} + +type setattrInCommon struct { + Valid uint32 + _ uint32 + Fh uint64 + Size uint64 + LockOwner uint64 // unused on OS X? + Atime uint64 + Mtime uint64 + Unused2 uint64 + AtimeNsec uint32 + MtimeNsec uint32 + Unused3 uint32 + Mode uint32 + Unused4 uint32 + Uid uint32 + Gid uint32 + Unused5 uint32 +} + +type openIn struct { + Flags uint32 + Unused uint32 +} + +type openOut struct { + Fh uint64 + OpenFlags uint32 + _ uint32 +} + +type createIn struct { + Flags uint32 + Mode uint32 + Umask uint32 + _ uint32 +} + +func createInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 12}): + return unsafe.Offsetof(createIn{}.Umask) + default: + return unsafe.Sizeof(createIn{}) + } +} + +type releaseIn struct { + Fh uint64 + Flags uint32 + ReleaseFlags uint32 + LockOwner uint32 +} + +type flushIn struct { + Fh uint64 + FlushFlags uint32 + _ uint32 + LockOwner uint64 +} + +type readIn struct { + Fh uint64 + Offset uint64 + Size uint32 + ReadFlags uint32 + LockOwner uint64 + Flags uint32 + _ uint32 +} + +func readInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 9}): + return unsafe.Offsetof(readIn{}.ReadFlags) + 4 + default: + return unsafe.Sizeof(readIn{}) + } +} + +// The ReadFlags are passed in ReadRequest. +type ReadFlags uint32 + +const ( + // LockOwner field is valid. + ReadLockOwner ReadFlags = 1 << 1 +) + +var readFlagNames = []flagName{ + {uint32(ReadLockOwner), "ReadLockOwner"}, +} + +func (fl ReadFlags) String() string { + return flagString(uint32(fl), readFlagNames) +} + +type writeIn struct { + Fh uint64 + Offset uint64 + Size uint32 + WriteFlags uint32 + LockOwner uint64 + Flags uint32 + _ uint32 +} + +func writeInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 9}): + return unsafe.Offsetof(writeIn{}.LockOwner) + default: + return unsafe.Sizeof(writeIn{}) + } +} + +type writeOut struct { + Size uint32 + _ uint32 +} + +// The WriteFlags are passed in WriteRequest. +type WriteFlags uint32 + +const ( + WriteCache WriteFlags = 1 << 0 + // LockOwner field is valid. + WriteLockOwner WriteFlags = 1 << 1 +) + +var writeFlagNames = []flagName{ + {uint32(WriteCache), "WriteCache"}, + {uint32(WriteLockOwner), "WriteLockOwner"}, +} + +func (fl WriteFlags) String() string { + return flagString(uint32(fl), writeFlagNames) +} + +const compatStatfsSize = 48 + +type statfsOut struct { + St kstatfs +} + +type fsyncIn struct { + Fh uint64 + FsyncFlags uint32 + _ uint32 +} + +type setxattrInCommon struct { + Size uint32 + Flags uint32 +} + +func (setxattrInCommon) position() uint32 { + return 0 +} + +type getxattrInCommon struct { + Size uint32 + _ uint32 +} + +func (getxattrInCommon) position() uint32 { + return 0 +} + +type getxattrOut struct { + Size uint32 + _ uint32 +} + +type lkIn struct { + Fh uint64 + Owner uint64 + Lk fileLock + LkFlags uint32 + _ uint32 +} + +func lkInSize(p Protocol) uintptr { + switch { + case p.LT(Protocol{7, 9}): + return unsafe.Offsetof(lkIn{}.LkFlags) + default: + return unsafe.Sizeof(lkIn{}) + } +} + +type lkOut struct { + Lk fileLock +} + +type accessIn struct { + Mask uint32 + _ uint32 +} + +type initIn struct { + Major uint32 + Minor uint32 + MaxReadahead uint32 + Flags uint32 +} + +const initInSize = int(unsafe.Sizeof(initIn{})) + +type initOut struct { + Major uint32 + Minor uint32 + MaxReadahead uint32 + Flags uint32 + Unused uint32 + MaxWrite uint32 +} + +type interruptIn struct { + Unique uint64 +} + +type bmapIn struct { + Block uint64 + BlockSize uint32 + _ uint32 +} + +type bmapOut struct { + Block uint64 +} + +type inHeader struct { + Len uint32 + Opcode uint32 + Unique uint64 + Nodeid uint64 + Uid uint32 + Gid uint32 + Pid uint32 + _ uint32 +} + +const inHeaderSize = int(unsafe.Sizeof(inHeader{})) + +type outHeader struct { + Len uint32 + Error int32 + Unique uint64 +} + +type dirent struct { + Ino uint64 + Off uint64 + Namelen uint32 + Type uint32 + Name [0]byte +} + +const direntSize = 8 + 8 + 4 + 4 + +const ( + notifyCodePoll int32 = 1 + notifyCodeInvalInode int32 = 2 + notifyCodeInvalEntry int32 = 3 +) + +type notifyInvalInodeOut struct { + Ino uint64 + Off int64 + Len int64 +} + +type notifyInvalEntryOut struct { + Parent uint64 + Namelen uint32 + _ uint32 +} diff --git a/vendor/bazil.org/fuse/fuse_kernel_darwin.go b/vendor/bazil.org/fuse/fuse_kernel_darwin.go new file mode 100644 index 00000000..b9873fdf --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_kernel_darwin.go @@ -0,0 +1,88 @@ +package fuse + +import ( + "time" +) + +type attr struct { + Ino uint64 + Size uint64 + Blocks uint64 + Atime uint64 + Mtime uint64 + Ctime uint64 + Crtime_ uint64 // OS X only + AtimeNsec uint32 + MtimeNsec uint32 + CtimeNsec uint32 + CrtimeNsec uint32 // OS X only + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint32 + Flags_ uint32 // OS X only; see chflags(2) + Blksize uint32 + padding uint32 +} + +func (a *attr) SetCrtime(s uint64, ns uint32) { + a.Crtime_, a.CrtimeNsec = s, ns +} + +func (a *attr) SetFlags(f uint32) { + a.Flags_ = f +} + +type setattrIn struct { + setattrInCommon + + // OS X only + Bkuptime_ uint64 + Chgtime_ uint64 + Crtime uint64 + BkuptimeNsec uint32 + ChgtimeNsec uint32 + CrtimeNsec uint32 + Flags_ uint32 // see chflags(2) +} + +func (in *setattrIn) BkupTime() time.Time { + return time.Unix(int64(in.Bkuptime_), int64(in.BkuptimeNsec)) +} + +func (in *setattrIn) Chgtime() time.Time { + return time.Unix(int64(in.Chgtime_), int64(in.ChgtimeNsec)) +} + +func (in *setattrIn) Flags() uint32 { + return in.Flags_ +} + +func openFlags(flags uint32) OpenFlags { + return OpenFlags(flags) +} + +type getxattrIn struct { + getxattrInCommon + + // OS X only + Position uint32 + Padding uint32 +} + +func (g *getxattrIn) position() uint32 { + return g.Position +} + +type setxattrIn struct { + setxattrInCommon + + // OS X only + Position uint32 + Padding uint32 +} + +func (s *setxattrIn) position() uint32 { + return s.Position +} diff --git a/vendor/bazil.org/fuse/fuse_kernel_freebsd.go b/vendor/bazil.org/fuse/fuse_kernel_freebsd.go new file mode 100644 index 00000000..b1141e41 --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_kernel_freebsd.go @@ -0,0 +1,62 @@ +package fuse + +import "time" + +type attr struct { + Ino uint64 + Size uint64 + Blocks uint64 + Atime uint64 + Mtime uint64 + Ctime uint64 + AtimeNsec uint32 + MtimeNsec uint32 + CtimeNsec uint32 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint32 + Blksize uint32 + padding uint32 +} + +func (a *attr) Crtime() time.Time { + return time.Time{} +} + +func (a *attr) SetCrtime(s uint64, ns uint32) { + // ignored on freebsd +} + +func (a *attr) SetFlags(f uint32) { + // ignored on freebsd +} + +type setattrIn struct { + setattrInCommon +} + +func (in *setattrIn) BkupTime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Chgtime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Flags() uint32 { + return 0 +} + +func openFlags(flags uint32) OpenFlags { + return OpenFlags(flags) +} + +type getxattrIn struct { + getxattrInCommon +} + +type setxattrIn struct { + setxattrInCommon +} diff --git a/vendor/bazil.org/fuse/fuse_kernel_linux.go b/vendor/bazil.org/fuse/fuse_kernel_linux.go new file mode 100644 index 00000000..d3ba8661 --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_kernel_linux.go @@ -0,0 +1,70 @@ +package fuse + +import "time" + +type attr struct { + Ino uint64 + Size uint64 + Blocks uint64 + Atime uint64 + Mtime uint64 + Ctime uint64 + AtimeNsec uint32 + MtimeNsec uint32 + CtimeNsec uint32 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint32 + Blksize uint32 + padding uint32 +} + +func (a *attr) Crtime() time.Time { + return time.Time{} +} + +func (a *attr) SetCrtime(s uint64, ns uint32) { + // Ignored on Linux. +} + +func (a *attr) SetFlags(f uint32) { + // Ignored on Linux. +} + +type setattrIn struct { + setattrInCommon +} + +func (in *setattrIn) BkupTime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Chgtime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Flags() uint32 { + return 0 +} + +func openFlags(flags uint32) OpenFlags { + // on amd64, the 32-bit O_LARGEFILE flag is always seen; + // on i386, the flag probably depends on the app + // requesting, but in any case should be utterly + // uninteresting to us here; our kernel protocol messages + // are not directly related to the client app's kernel + // API/ABI + flags &^= 0x8000 + + return OpenFlags(flags) +} + +type getxattrIn struct { + getxattrInCommon +} + +type setxattrIn struct { + setxattrInCommon +} diff --git a/vendor/bazil.org/fuse/fuse_kernel_std.go b/vendor/bazil.org/fuse/fuse_kernel_std.go new file mode 100644 index 00000000..074cfd32 --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_kernel_std.go @@ -0,0 +1 @@ +package fuse diff --git a/vendor/bazil.org/fuse/fuse_linux.go b/vendor/bazil.org/fuse/fuse_linux.go new file mode 100644 index 00000000..5fb96f9a --- /dev/null +++ b/vendor/bazil.org/fuse/fuse_linux.go @@ -0,0 +1,7 @@ +package fuse + +// Maximum file write size we are prepared to receive from the kernel. +// +// Linux 4.2.0 has been observed to cap this value at 128kB +// (FUSE_MAX_PAGES_PER_REQ=32, 4kB pages). +const maxWrite = 128 * 1024 diff --git a/vendor/bazil.org/fuse/fuseutil/fuseutil.go b/vendor/bazil.org/fuse/fuseutil/fuseutil.go new file mode 100644 index 00000000..b3f52b73 --- /dev/null +++ b/vendor/bazil.org/fuse/fuseutil/fuseutil.go @@ -0,0 +1,20 @@ +package fuseutil // import "bazil.org/fuse/fuseutil" + +import ( + "bazil.org/fuse" +) + +// HandleRead handles a read request assuming that data is the entire file content. +// It adjusts the amount returned in resp according to req.Offset and req.Size. +func HandleRead(req *fuse.ReadRequest, resp *fuse.ReadResponse, data []byte) { + if req.Offset >= int64(len(data)) { + data = nil + } else { + data = data[req.Offset:] + } + if len(data) > req.Size { + data = data[:req.Size] + } + n := copy(resp.Data[:req.Size], data) + resp.Data = resp.Data[:n] +} diff --git a/vendor/bazil.org/fuse/mount.go b/vendor/bazil.org/fuse/mount.go new file mode 100644 index 00000000..8054e902 --- /dev/null +++ b/vendor/bazil.org/fuse/mount.go @@ -0,0 +1,38 @@ +package fuse + +import ( + "bufio" + "errors" + "io" + "log" + "sync" +) + +var ( + // ErrOSXFUSENotFound is returned from Mount when the OSXFUSE + // installation is not detected. + // + // Only happens on OS X. Make sure OSXFUSE is installed, or see + // OSXFUSELocations for customization. + ErrOSXFUSENotFound = errors.New("cannot locate OSXFUSE") +) + +func neverIgnoreLine(line string) bool { + return false +} + +func lineLogger(wg *sync.WaitGroup, prefix string, ignore func(line string) bool, r io.ReadCloser) { + defer wg.Done() + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + if ignore(line) { + continue + } + log.Printf("%s: %s", prefix, line) + } + if err := scanner.Err(); err != nil { + log.Printf("%s, error reading: %v", prefix, err) + } +} diff --git a/vendor/bazil.org/fuse/mount_darwin.go b/vendor/bazil.org/fuse/mount_darwin.go new file mode 100644 index 00000000..c1c36e62 --- /dev/null +++ b/vendor/bazil.org/fuse/mount_darwin.go @@ -0,0 +1,208 @@ +package fuse + +import ( + "errors" + "fmt" + "log" + "os" + "os/exec" + "path" + "strconv" + "strings" + "sync" + "syscall" +) + +var ( + errNoAvail = errors.New("no available fuse devices") + errNotLoaded = errors.New("osxfuse is not loaded") +) + +func loadOSXFUSE(bin string) error { + cmd := exec.Command(bin) + cmd.Dir = "/" + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + return err +} + +func openOSXFUSEDev(devPrefix string) (*os.File, error) { + var f *os.File + var err error + for i := uint64(0); ; i++ { + path := devPrefix + strconv.FormatUint(i, 10) + f, err = os.OpenFile(path, os.O_RDWR, 0000) + if os.IsNotExist(err) { + if i == 0 { + // not even the first device was found -> fuse is not loaded + return nil, errNotLoaded + } + + // we've run out of kernel-provided devices + return nil, errNoAvail + } + + if err2, ok := err.(*os.PathError); ok && err2.Err == syscall.EBUSY { + // try the next one + continue + } + + if err != nil { + return nil, err + } + return f, nil + } +} + +func handleMountOSXFUSE(helperName string, errCh chan<- error) func(line string) (ignore bool) { + var noMountpointPrefix = helperName + `: ` + const noMountpointSuffix = `: No such file or directory` + return func(line string) (ignore bool) { + if strings.HasPrefix(line, noMountpointPrefix) && strings.HasSuffix(line, noMountpointSuffix) { + // re-extract it from the error message in case some layer + // changed the path + mountpoint := line[len(noMountpointPrefix) : len(line)-len(noMountpointSuffix)] + err := &MountpointDoesNotExistError{ + Path: mountpoint, + } + select { + case errCh <- err: + return true + default: + // not the first error; fall back to logging it + return false + } + } + + return false + } +} + +// isBoringMountOSXFUSEError returns whether the Wait error is +// uninteresting; exit status 64 is. +func isBoringMountOSXFUSEError(err error) bool { + if err, ok := err.(*exec.ExitError); ok && err.Exited() { + if status, ok := err.Sys().(syscall.WaitStatus); ok && status.ExitStatus() == 64 { + return true + } + } + return false +} + +func callMount(bin string, daemonVar string, dir string, conf *mountConfig, f *os.File, ready chan<- struct{}, errp *error) error { + for k, v := range conf.options { + if strings.Contains(k, ",") || strings.Contains(v, ",") { + // Silly limitation but the mount helper does not + // understand any escaping. See TestMountOptionCommaError. + return fmt.Errorf("mount options cannot contain commas on darwin: %q=%q", k, v) + } + } + cmd := exec.Command( + bin, + "-o", conf.getOptions(), + // Tell osxfuse-kext how large our buffer is. It must split + // writes larger than this into multiple writes. + // + // OSXFUSE seems to ignore InitResponse.MaxWrite, and uses + // this instead. + "-o", "iosize="+strconv.FormatUint(maxWrite, 10), + // refers to fd passed in cmd.ExtraFiles + "3", + dir, + ) + cmd.ExtraFiles = []*os.File{f} + cmd.Env = os.Environ() + // OSXFUSE <3.3.0 + cmd.Env = append(cmd.Env, "MOUNT_FUSEFS_CALL_BY_LIB=") + // OSXFUSE >=3.3.0 + cmd.Env = append(cmd.Env, "MOUNT_OSXFUSE_CALL_BY_LIB=") + + daemon := os.Args[0] + if daemonVar != "" { + cmd.Env = append(cmd.Env, daemonVar+"="+daemon) + } + + stdout, err := cmd.StdoutPipe() + if err != nil { + return fmt.Errorf("setting up mount_osxfusefs stderr: %v", err) + } + stderr, err := cmd.StderrPipe() + if err != nil { + return fmt.Errorf("setting up mount_osxfusefs stderr: %v", err) + } + + if err := cmd.Start(); err != nil { + return fmt.Errorf("mount_osxfusefs: %v", err) + } + helperErrCh := make(chan error, 1) + go func() { + var wg sync.WaitGroup + wg.Add(2) + go lineLogger(&wg, "mount helper output", neverIgnoreLine, stdout) + helperName := path.Base(bin) + go lineLogger(&wg, "mount helper error", handleMountOSXFUSE(helperName, helperErrCh), stderr) + wg.Wait() + if err := cmd.Wait(); err != nil { + // see if we have a better error to report + select { + case helperErr := <-helperErrCh: + // log the Wait error if it's not what we expected + if !isBoringMountOSXFUSEError(err) { + log.Printf("mount helper failed: %v", err) + } + // and now return what we grabbed from stderr as the real + // error + *errp = helperErr + close(ready) + return + default: + // nope, fall back to generic message + } + + *errp = fmt.Errorf("mount_osxfusefs: %v", err) + close(ready) + return + } + + *errp = nil + close(ready) + }() + return nil +} + +func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) { + locations := conf.osxfuseLocations + if locations == nil { + locations = []OSXFUSEPaths{ + OSXFUSELocationV3, + OSXFUSELocationV2, + } + } + for _, loc := range locations { + if _, err := os.Stat(loc.Mount); os.IsNotExist(err) { + // try the other locations + continue + } + + f, err := openOSXFUSEDev(loc.DevicePrefix) + if err == errNotLoaded { + err = loadOSXFUSE(loc.Load) + if err != nil { + return nil, err + } + // try again + f, err = openOSXFUSEDev(loc.DevicePrefix) + } + if err != nil { + return nil, err + } + err = callMount(loc.Mount, loc.DaemonVar, dir, conf, f, ready, errp) + if err != nil { + f.Close() + return nil, err + } + return f, nil + } + return nil, ErrOSXFUSENotFound +} diff --git a/vendor/bazil.org/fuse/mount_freebsd.go b/vendor/bazil.org/fuse/mount_freebsd.go new file mode 100644 index 00000000..70bb4102 --- /dev/null +++ b/vendor/bazil.org/fuse/mount_freebsd.go @@ -0,0 +1,111 @@ +package fuse + +import ( + "fmt" + "log" + "os" + "os/exec" + "strings" + "sync" + "syscall" +) + +func handleMountFusefsStderr(errCh chan<- error) func(line string) (ignore bool) { + return func(line string) (ignore bool) { + const ( + noMountpointPrefix = `mount_fusefs: ` + noMountpointSuffix = `: No such file or directory` + ) + if strings.HasPrefix(line, noMountpointPrefix) && strings.HasSuffix(line, noMountpointSuffix) { + // re-extract it from the error message in case some layer + // changed the path + mountpoint := line[len(noMountpointPrefix) : len(line)-len(noMountpointSuffix)] + err := &MountpointDoesNotExistError{ + Path: mountpoint, + } + select { + case errCh <- err: + return true + default: + // not the first error; fall back to logging it + return false + } + } + + return false + } +} + +// isBoringMountFusefsError returns whether the Wait error is +// uninteresting; exit status 1 is. +func isBoringMountFusefsError(err error) bool { + if err, ok := err.(*exec.ExitError); ok && err.Exited() { + if status, ok := err.Sys().(syscall.WaitStatus); ok && status.ExitStatus() == 1 { + return true + } + } + return false +} + +func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) { + for k, v := range conf.options { + if strings.Contains(k, ",") || strings.Contains(v, ",") { + // Silly limitation but the mount helper does not + // understand any escaping. See TestMountOptionCommaError. + return nil, fmt.Errorf("mount options cannot contain commas on FreeBSD: %q=%q", k, v) + } + } + + f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0000) + if err != nil { + *errp = err + return nil, err + } + + cmd := exec.Command( + "/sbin/mount_fusefs", + "--safe", + "-o", conf.getOptions(), + "3", + dir, + ) + cmd.ExtraFiles = []*os.File{f} + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("setting up mount_fusefs stderr: %v", err) + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("setting up mount_fusefs stderr: %v", err) + } + + if err := cmd.Start(); err != nil { + return nil, fmt.Errorf("mount_fusefs: %v", err) + } + helperErrCh := make(chan error, 1) + var wg sync.WaitGroup + wg.Add(2) + go lineLogger(&wg, "mount helper output", neverIgnoreLine, stdout) + go lineLogger(&wg, "mount helper error", handleMountFusefsStderr(helperErrCh), stderr) + wg.Wait() + if err := cmd.Wait(); err != nil { + // see if we have a better error to report + select { + case helperErr := <-helperErrCh: + // log the Wait error if it's not what we expected + if !isBoringMountFusefsError(err) { + log.Printf("mount helper failed: %v", err) + } + // and now return what we grabbed from stderr as the real + // error + return nil, helperErr + default: + // nope, fall back to generic message + } + return nil, fmt.Errorf("mount_fusefs: %v", err) + } + + close(ready) + return f, nil +} diff --git a/vendor/bazil.org/fuse/mount_linux.go b/vendor/bazil.org/fuse/mount_linux.go new file mode 100644 index 00000000..197d1044 --- /dev/null +++ b/vendor/bazil.org/fuse/mount_linux.go @@ -0,0 +1,150 @@ +package fuse + +import ( + "fmt" + "log" + "net" + "os" + "os/exec" + "strings" + "sync" + "syscall" +) + +func handleFusermountStderr(errCh chan<- error) func(line string) (ignore bool) { + return func(line string) (ignore bool) { + if line == `fusermount: failed to open /etc/fuse.conf: Permission denied` { + // Silence this particular message, it occurs way too + // commonly and isn't very relevant to whether the mount + // succeeds or not. + return true + } + + const ( + noMountpointPrefix = `fusermount: failed to access mountpoint ` + noMountpointSuffix = `: No such file or directory` + ) + if strings.HasPrefix(line, noMountpointPrefix) && strings.HasSuffix(line, noMountpointSuffix) { + // re-extract it from the error message in case some layer + // changed the path + mountpoint := line[len(noMountpointPrefix) : len(line)-len(noMountpointSuffix)] + err := &MountpointDoesNotExistError{ + Path: mountpoint, + } + select { + case errCh <- err: + return true + default: + // not the first error; fall back to logging it + return false + } + } + + return false + } +} + +// isBoringFusermountError returns whether the Wait error is +// uninteresting; exit status 1 is. +func isBoringFusermountError(err error) bool { + if err, ok := err.(*exec.ExitError); ok && err.Exited() { + if status, ok := err.Sys().(syscall.WaitStatus); ok && status.ExitStatus() == 1 { + return true + } + } + return false +} + +func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) { + // linux mount is never delayed + close(ready) + + fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0) + if err != nil { + return nil, fmt.Errorf("socketpair error: %v", err) + } + + writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes") + defer writeFile.Close() + + readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads") + defer readFile.Close() + + cmd := exec.Command( + "fusermount", + "-o", conf.getOptions(), + "--", + dir, + ) + cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3") + + cmd.ExtraFiles = []*os.File{writeFile} + + var wg sync.WaitGroup + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("setting up fusermount stderr: %v", err) + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("setting up fusermount stderr: %v", err) + } + + if err := cmd.Start(); err != nil { + return nil, fmt.Errorf("fusermount: %v", err) + } + helperErrCh := make(chan error, 1) + wg.Add(2) + go lineLogger(&wg, "mount helper output", neverIgnoreLine, stdout) + go lineLogger(&wg, "mount helper error", handleFusermountStderr(helperErrCh), stderr) + wg.Wait() + if err := cmd.Wait(); err != nil { + // see if we have a better error to report + select { + case helperErr := <-helperErrCh: + // log the Wait error if it's not what we expected + if !isBoringFusermountError(err) { + log.Printf("mount helper failed: %v", err) + } + // and now return what we grabbed from stderr as the real + // error + return nil, helperErr + default: + // nope, fall back to generic message + } + + return nil, fmt.Errorf("fusermount: %v", err) + } + + c, err := net.FileConn(readFile) + if err != nil { + return nil, fmt.Errorf("FileConn from fusermount socket: %v", err) + } + defer c.Close() + + uc, ok := c.(*net.UnixConn) + if !ok { + return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c) + } + + buf := make([]byte, 32) // expect 1 byte + oob := make([]byte, 32) // expect 24 bytes + _, oobn, _, _, err := uc.ReadMsgUnix(buf, oob) + scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) + if err != nil { + return nil, fmt.Errorf("ParseSocketControlMessage: %v", err) + } + if len(scms) != 1 { + return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms) + } + scm := scms[0] + gotFds, err := syscall.ParseUnixRights(&scm) + if err != nil { + return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err) + } + if len(gotFds) != 1 { + return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds) + } + f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse") + return f, nil +} diff --git a/vendor/bazil.org/fuse/options.go b/vendor/bazil.org/fuse/options.go new file mode 100644 index 00000000..65ce8a54 --- /dev/null +++ b/vendor/bazil.org/fuse/options.go @@ -0,0 +1,310 @@ +package fuse + +import ( + "errors" + "strings" +) + +func dummyOption(conf *mountConfig) error { + return nil +} + +// mountConfig holds the configuration for a mount operation. +// Use it by passing MountOption values to Mount. +type mountConfig struct { + options map[string]string + maxReadahead uint32 + initFlags InitFlags + osxfuseLocations []OSXFUSEPaths +} + +func escapeComma(s string) string { + s = strings.Replace(s, `\`, `\\`, -1) + s = strings.Replace(s, `,`, `\,`, -1) + return s +} + +// getOptions makes a string of options suitable for passing to FUSE +// mount flag `-o`. Returns an empty string if no options were set. +// Any platform specific adjustments should happen before the call. +func (m *mountConfig) getOptions() string { + var opts []string + for k, v := range m.options { + k = escapeComma(k) + if v != "" { + k += "=" + escapeComma(v) + } + opts = append(opts, k) + } + return strings.Join(opts, ",") +} + +type mountOption func(*mountConfig) error + +// MountOption is passed to Mount to change the behavior of the mount. +type MountOption mountOption + +// FSName sets the file system name (also called source) that is +// visible in the list of mounted file systems. +// +// FreeBSD ignores this option. +func FSName(name string) MountOption { + return func(conf *mountConfig) error { + conf.options["fsname"] = name + return nil + } +} + +// Subtype sets the subtype of the mount. The main type is always +// `fuse`. The type in a list of mounted file systems will look like +// `fuse.foo`. +// +// OS X ignores this option. +// FreeBSD ignores this option. +func Subtype(fstype string) MountOption { + return func(conf *mountConfig) error { + conf.options["subtype"] = fstype + return nil + } +} + +// LocalVolume sets the volume to be local (instead of network), +// changing the behavior of Finder, Spotlight, and such. +// +// OS X only. Others ignore this option. +func LocalVolume() MountOption { + return localVolume +} + +// VolumeName sets the volume name shown in Finder. +// +// OS X only. Others ignore this option. +func VolumeName(name string) MountOption { + return volumeName(name) +} + +// NoAppleDouble makes OSXFUSE disallow files with names used by OS X +// to store extended attributes on file systems that do not support +// them natively. +// +// Such file names are: +// +// ._* +// .DS_Store +// +// OS X only. Others ignore this option. +func NoAppleDouble() MountOption { + return noAppleDouble +} + +// NoAppleXattr makes OSXFUSE disallow extended attributes with the +// prefix "com.apple.". This disables persistent Finder state and +// other such information. +// +// OS X only. Others ignore this option. +func NoAppleXattr() MountOption { + return noAppleXattr +} + +// ExclCreate causes O_EXCL flag to be set for only "truly" exclusive creates, +// i.e. create calls for which the initiator explicitly set the O_EXCL flag. +// +// OSXFUSE expects all create calls to return EEXIST in case the file +// already exists, regardless of whether O_EXCL was specified or not. +// To ensure this behavior, it normally sets OpenExclusive for all +// Create calls, regardless of whether the original call had it set. +// For distributed filesystems, that may force every file create to be +// a distributed consensus action, causing undesirable delays. +// +// This option makes the FUSE filesystem see the original flag value, +// and better decide when to ensure global consensus. +// +// Note that returning EEXIST on existing file create is still +// expected with OSXFUSE, regardless of the presence of the +// OpenExclusive flag. +// +// For more information, see +// https://github.com/osxfuse/osxfuse/issues/209 +// +// OS X only. Others ignore this options. +// Requires OSXFUSE 3.4.1 or newer. +func ExclCreate() MountOption { + return exclCreate +} + +// DaemonTimeout sets the time in seconds between a request and a reply before +// the FUSE mount is declared dead. +// +// OS X and FreeBSD only. Others ignore this option. +func DaemonTimeout(name string) MountOption { + return daemonTimeout(name) +} + +var ErrCannotCombineAllowOtherAndAllowRoot = errors.New("cannot combine AllowOther and AllowRoot") + +// AllowOther allows other users to access the file system. +// +// Only one of AllowOther or AllowRoot can be used. +func AllowOther() MountOption { + return func(conf *mountConfig) error { + if _, ok := conf.options["allow_root"]; ok { + return ErrCannotCombineAllowOtherAndAllowRoot + } + conf.options["allow_other"] = "" + return nil + } +} + +// AllowRoot allows other users to access the file system. +// +// Only one of AllowOther or AllowRoot can be used. +// +// FreeBSD ignores this option. +func AllowRoot() MountOption { + return func(conf *mountConfig) error { + if _, ok := conf.options["allow_other"]; ok { + return ErrCannotCombineAllowOtherAndAllowRoot + } + conf.options["allow_root"] = "" + return nil + } +} + +// AllowDev enables interpreting character or block special devices on the +// filesystem. +func AllowDev() MountOption { + return func(conf *mountConfig) error { + conf.options["dev"] = "" + return nil + } +} + +// AllowSUID allows set-user-identifier or set-group-identifier bits to take +// effect. +func AllowSUID() MountOption { + return func(conf *mountConfig) error { + conf.options["suid"] = "" + return nil + } +} + +// DefaultPermissions makes the kernel enforce access control based on +// the file mode (as in chmod). +// +// Without this option, the Node itself decides what is and is not +// allowed. This is normally ok because FUSE file systems cannot be +// accessed by other users without AllowOther/AllowRoot. +// +// FreeBSD ignores this option. +func DefaultPermissions() MountOption { + return func(conf *mountConfig) error { + conf.options["default_permissions"] = "" + return nil + } +} + +// ReadOnly makes the mount read-only. +func ReadOnly() MountOption { + return func(conf *mountConfig) error { + conf.options["ro"] = "" + return nil + } +} + +// MaxReadahead sets the number of bytes that can be prefetched for +// sequential reads. The kernel can enforce a maximum value lower than +// this. +// +// This setting makes the kernel perform speculative reads that do not +// originate from any client process. This usually tremendously +// improves read performance. +func MaxReadahead(n uint32) MountOption { + return func(conf *mountConfig) error { + conf.maxReadahead = n + return nil + } +} + +// AsyncRead enables multiple outstanding read requests for the same +// handle. Without this, there is at most one request in flight at a +// time. +func AsyncRead() MountOption { + return func(conf *mountConfig) error { + conf.initFlags |= InitAsyncRead + return nil + } +} + +// WritebackCache enables the kernel to buffer writes before sending +// them to the FUSE server. Without this, writethrough caching is +// used. +func WritebackCache() MountOption { + return func(conf *mountConfig) error { + conf.initFlags |= InitWritebackCache + return nil + } +} + +// OSXFUSEPaths describes the paths used by an installed OSXFUSE +// version. See OSXFUSELocationV3 for typical values. +type OSXFUSEPaths struct { + // Prefix for the device file. At mount time, an incrementing + // number is suffixed until a free FUSE device is found. + DevicePrefix string + // Path of the load helper, used to load the kernel extension if + // no device files are found. + Load string + // Path of the mount helper, used for the actual mount operation. + Mount string + // Environment variable used to pass the path to the executable + // calling the mount helper. + DaemonVar string +} + +// Default paths for OSXFUSE. See OSXFUSELocations. +var ( + OSXFUSELocationV3 = OSXFUSEPaths{ + DevicePrefix: "/dev/osxfuse", + Load: "/Library/Filesystems/osxfuse.fs/Contents/Resources/load_osxfuse", + Mount: "/Library/Filesystems/osxfuse.fs/Contents/Resources/mount_osxfuse", + DaemonVar: "MOUNT_OSXFUSE_DAEMON_PATH", + } + OSXFUSELocationV2 = OSXFUSEPaths{ + DevicePrefix: "/dev/osxfuse", + Load: "/Library/Filesystems/osxfusefs.fs/Support/load_osxfusefs", + Mount: "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs", + DaemonVar: "MOUNT_FUSEFS_DAEMON_PATH", + } +) + +// OSXFUSELocations sets where to look for OSXFUSE files. The +// arguments are all the possible locations. The previous locations +// are replaced. +// +// Without this option, OSXFUSELocationV3 and OSXFUSELocationV2 are +// used. +// +// OS X only. Others ignore this option. +func OSXFUSELocations(paths ...OSXFUSEPaths) MountOption { + return func(conf *mountConfig) error { + if len(paths) == 0 { + return errors.New("must specify at least one location for OSXFUSELocations") + } + // replace previous values, but make a copy so there's no + // worries about caller mutating their slice + conf.osxfuseLocations = append(conf.osxfuseLocations[:0], paths...) + return nil + } +} + +// AllowNonEmptyMount allows the mounting over a non-empty directory. +// +// The files in it will be shadowed by the freshly created mount. By +// default these mounts are rejected to prevent accidental covering up +// of data, which could for example prevent automatic backup. +func AllowNonEmptyMount() MountOption { + return func(conf *mountConfig) error { + conf.options["nonempty"] = "" + return nil + } +} diff --git a/vendor/bazil.org/fuse/options_darwin.go b/vendor/bazil.org/fuse/options_darwin.go new file mode 100644 index 00000000..faa9d78e --- /dev/null +++ b/vendor/bazil.org/fuse/options_darwin.go @@ -0,0 +1,35 @@ +package fuse + +func localVolume(conf *mountConfig) error { + conf.options["local"] = "" + return nil +} + +func volumeName(name string) MountOption { + return func(conf *mountConfig) error { + conf.options["volname"] = name + return nil + } +} + +func daemonTimeout(name string) MountOption { + return func(conf *mountConfig) error { + conf.options["daemon_timeout"] = name + return nil + } +} + +func noAppleXattr(conf *mountConfig) error { + conf.options["noapplexattr"] = "" + return nil +} + +func noAppleDouble(conf *mountConfig) error { + conf.options["noappledouble"] = "" + return nil +} + +func exclCreate(conf *mountConfig) error { + conf.options["excl_create"] = "" + return nil +} diff --git a/vendor/bazil.org/fuse/options_freebsd.go b/vendor/bazil.org/fuse/options_freebsd.go new file mode 100644 index 00000000..7c164b13 --- /dev/null +++ b/vendor/bazil.org/fuse/options_freebsd.go @@ -0,0 +1,28 @@ +package fuse + +func localVolume(conf *mountConfig) error { + return nil +} + +func volumeName(name string) MountOption { + return dummyOption +} + +func daemonTimeout(name string) MountOption { + return func(conf *mountConfig) error { + conf.options["timeout"] = name + return nil + } +} + +func noAppleXattr(conf *mountConfig) error { + return nil +} + +func noAppleDouble(conf *mountConfig) error { + return nil +} + +func exclCreate(conf *mountConfig) error { + return nil +} diff --git a/vendor/bazil.org/fuse/options_linux.go b/vendor/bazil.org/fuse/options_linux.go new file mode 100644 index 00000000..13f0896d --- /dev/null +++ b/vendor/bazil.org/fuse/options_linux.go @@ -0,0 +1,25 @@ +package fuse + +func localVolume(conf *mountConfig) error { + return nil +} + +func volumeName(name string) MountOption { + return dummyOption +} + +func daemonTimeout(name string) MountOption { + return dummyOption +} + +func noAppleXattr(conf *mountConfig) error { + return nil +} + +func noAppleDouble(conf *mountConfig) error { + return nil +} + +func exclCreate(conf *mountConfig) error { + return nil +} diff --git a/vendor/bazil.org/fuse/protocol.go b/vendor/bazil.org/fuse/protocol.go new file mode 100644 index 00000000..a77bbf72 --- /dev/null +++ b/vendor/bazil.org/fuse/protocol.go @@ -0,0 +1,75 @@ +package fuse + +import ( + "fmt" +) + +// Protocol is a FUSE protocol version number. +type Protocol struct { + Major uint32 + Minor uint32 +} + +func (p Protocol) String() string { + return fmt.Sprintf("%d.%d", p.Major, p.Minor) +} + +// LT returns whether a is less than b. +func (a Protocol) LT(b Protocol) bool { + return a.Major < b.Major || + (a.Major == b.Major && a.Minor < b.Minor) +} + +// GE returns whether a is greater than or equal to b. +func (a Protocol) GE(b Protocol) bool { + return a.Major > b.Major || + (a.Major == b.Major && a.Minor >= b.Minor) +} + +func (a Protocol) is79() bool { + return a.GE(Protocol{7, 9}) +} + +// HasAttrBlockSize returns whether Attr.BlockSize is respected by the +// kernel. +func (a Protocol) HasAttrBlockSize() bool { + return a.is79() +} + +// HasReadWriteFlags returns whether ReadRequest/WriteRequest +// fields Flags and FileFlags are valid. +func (a Protocol) HasReadWriteFlags() bool { + return a.is79() +} + +// HasGetattrFlags returns whether GetattrRequest field Flags is +// valid. +func (a Protocol) HasGetattrFlags() bool { + return a.is79() +} + +func (a Protocol) is710() bool { + return a.GE(Protocol{7, 10}) +} + +// HasOpenNonSeekable returns whether OpenResponse field Flags flag +// OpenNonSeekable is supported. +func (a Protocol) HasOpenNonSeekable() bool { + return a.is710() +} + +func (a Protocol) is712() bool { + return a.GE(Protocol{7, 12}) +} + +// HasUmask returns whether CreateRequest/MkdirRequest/MknodRequest +// field Umask is valid. +func (a Protocol) HasUmask() bool { + return a.is712() +} + +// HasInvalidate returns whether InvalidateNode/InvalidateEntry are +// supported. +func (a Protocol) HasInvalidate() bool { + return a.is712() +} diff --git a/vendor/bazil.org/fuse/unmount.go b/vendor/bazil.org/fuse/unmount.go new file mode 100644 index 00000000..ffe3f155 --- /dev/null +++ b/vendor/bazil.org/fuse/unmount.go @@ -0,0 +1,6 @@ +package fuse + +// Unmount tries to unmount the filesystem mounted at dir. +func Unmount(dir string) error { + return unmount(dir) +} diff --git a/vendor/bazil.org/fuse/unmount_linux.go b/vendor/bazil.org/fuse/unmount_linux.go new file mode 100644 index 00000000..088f0cfe --- /dev/null +++ b/vendor/bazil.org/fuse/unmount_linux.go @@ -0,0 +1,21 @@ +package fuse + +import ( + "bytes" + "errors" + "os/exec" +) + +func unmount(dir string) error { + cmd := exec.Command("fusermount", "-u", dir) + output, err := cmd.CombinedOutput() + if err != nil { + if len(output) > 0 { + output = bytes.TrimRight(output, "\n") + msg := err.Error() + ": " + string(output) + err = errors.New(msg) + } + return err + } + return nil +} diff --git a/vendor/bazil.org/fuse/unmount_std.go b/vendor/bazil.org/fuse/unmount_std.go new file mode 100644 index 00000000..d6efe276 --- /dev/null +++ b/vendor/bazil.org/fuse/unmount_std.go @@ -0,0 +1,17 @@ +// +build !linux + +package fuse + +import ( + "os" + "syscall" +) + +func unmount(dir string) error { + err := syscall.Unmount(dir, 0) + if err != nil { + err = &os.PathError{Op: "unmount", Path: dir, Err: err} + return err + } + return nil +} diff --git a/vendor/github.com/AndreasBriese/bbloom/.travis.yml b/vendor/github.com/AndreasBriese/bbloom/.travis.yml new file mode 100644 index 00000000..4f2ee4d9 --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/.travis.yml @@ -0,0 +1 @@ +language: go diff --git a/vendor/github.com/AndreasBriese/bbloom/LICENSE b/vendor/github.com/AndreasBriese/bbloom/LICENSE new file mode 100644 index 00000000..4b20050e --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/LICENSE @@ -0,0 +1,35 @@ +bbloom.go + +// The MIT License (MIT) +// Copyright (c) 2014 Andreas Briese, eduToolbox@Bri-C GmbH, Sarstedt + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +siphash.go + +// https://github.com/dchest/siphash +// +// Written in 2012 by Dmitry Chestnykh. +// +// To the extent possible under law, the author have dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// http://creativecommons.org/publicdomain/zero/1.0/ +// +// Package siphash implements SipHash-2-4, a fast short-input PRF +// created by Jean-Philippe Aumasson and Daniel J. Bernstein. diff --git a/vendor/github.com/AndreasBriese/bbloom/README.md b/vendor/github.com/AndreasBriese/bbloom/README.md new file mode 100644 index 00000000..d7413c33 --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/README.md @@ -0,0 +1,131 @@ +## bbloom: a bitset Bloom filter for go/golang +=== + +[![Build Status](https://travis-ci.org/AndreasBriese/bbloom.png?branch=master)](http://travis-ci.org/AndreasBriese/bbloom) + +package implements a fast bloom filter with real 'bitset' and JSONMarshal/JSONUnmarshal to store/reload the Bloom filter. + +NOTE: the package uses unsafe.Pointer to set and read the bits from the bitset. If you're uncomfortable with using the unsafe package, please consider using my bloom filter package at github.com/AndreasBriese/bloom + +=== + +changelog 11/2015: new thread safe methods AddTS(), HasTS(), AddIfNotHasTS() following a suggestion from Srdjan Marinovic (github @a-little-srdjan), who used this to code a bloomfilter cache. + +This bloom filter was developed to strengthen a website-log database and was tested and optimized for this log-entry mask: "2014/%02i/%02i %02i:%02i:%02i /info.html". +Nonetheless bbloom should work with any other form of entries. + +~~Hash function is a modified Berkeley DB sdbm hash (to optimize for smaller strings). sdbm http://www.cse.yorku.ca/~oz/hash.html~~ + +Found sipHash (SipHash-2-4, a fast short-input PRF created by Jean-Philippe Aumasson and Daniel J. Bernstein.) to be about as fast. sipHash had been ported by Dimtry Chestnyk to Go (github.com/dchest/siphash ) + +Minimum hashset size is: 512 ([4]uint64; will be set automatically). + +###install + +```sh +go get github.com/AndreasBriese/bbloom +``` + +###test ++ change to folder ../bbloom ++ create wordlist in file "words.txt" (you might use `python permut.py`) ++ run 'go test -bench=.' within the folder + +```go +go test -bench=. +``` + +~~If you've installed the GOCONVEY TDD-framework http://goconvey.co/ you can run the tests automatically.~~ + +using go's testing framework now (have in mind that the op timing is related to 65536 operations of Add, Has, AddIfNotHas respectively) + +### usage + +after installation add + +```go +import ( + ... + "github.com/AndreasBriese/bbloom" + ... + ) +``` + +at your header. In the program use + +```go +// create a bloom filter for 65536 items and 1 % wrong-positive ratio +bf := bbloom.New(float64(1<<16), float64(0.01)) + +// or +// create a bloom filter with 650000 for 65536 items and 7 locs per hash explicitly +// bf = bbloom.New(float64(650000), float64(7)) +// or +bf = bbloom.New(650000.0, 7.0) + +// add one item +bf.Add([]byte("butter")) + +// Number of elements added is exposed now +// Note: ElemNum will not be included in JSON export (for compatability to older version) +nOfElementsInFilter := bf.ElemNum + +// check if item is in the filter +isIn := bf.Has([]byte("butter")) // should be true +isNotIn := bf.Has([]byte("Butter")) // should be false + +// 'add only if item is new' to the bloomfilter +added := bf.AddIfNotHas([]byte("butter")) // should be false because 'butter' is already in the set +added = bf.AddIfNotHas([]byte("buTTer")) // should be true because 'buTTer' is new + +// thread safe versions for concurrent use: AddTS, HasTS, AddIfNotHasTS +// add one item +bf.AddTS([]byte("peanutbutter")) +// check if item is in the filter +isIn = bf.HasTS([]byte("peanutbutter")) // should be true +isNotIn = bf.HasTS([]byte("peanutButter")) // should be false +// 'add only if item is new' to the bloomfilter +added = bf.AddIfNotHasTS([]byte("butter")) // should be false because 'peanutbutter' is already in the set +added = bf.AddIfNotHasTS([]byte("peanutbuTTer")) // should be true because 'penutbuTTer' is new + +// convert to JSON ([]byte) +Json := bf.JSONMarshal() + +// bloomfilters Mutex is exposed for external un-/locking +// i.e. mutex lock while doing JSON conversion +bf.Mtx.Lock() +Json = bf.JSONMarshal() +bf.Mtx.Unlock() + +// restore a bloom filter from storage +bfNew := bbloom.JSONUnmarshal(Json) + +isInNew := bfNew.Has([]byte("butter")) // should be true +isNotInNew := bfNew.Has([]byte("Butter")) // should be false + +``` + +to work with the bloom filter. + +### why 'fast'? + +It's about 3 times faster than William Fitzgeralds bitset bloom filter https://github.com/willf/bloom . And it is about so fast as my []bool set variant for Boom filters (see https://github.com/AndreasBriese/bloom ) but having a 8times smaller memory footprint: + + + Bloom filter (filter size 524288, 7 hashlocs) + github.com/AndreasBriese/bbloom 'Add' 65536 items (10 repetitions): 6595800 ns (100 ns/op) + github.com/AndreasBriese/bbloom 'Has' 65536 items (10 repetitions): 5986600 ns (91 ns/op) + github.com/AndreasBriese/bloom 'Add' 65536 items (10 repetitions): 6304684 ns (96 ns/op) + github.com/AndreasBriese/bloom 'Has' 65536 items (10 repetitions): 6568663 ns (100 ns/op) + + github.com/willf/bloom 'Add' 65536 items (10 repetitions): 24367224 ns (371 ns/op) + github.com/willf/bloom 'Test' 65536 items (10 repetitions): 21881142 ns (333 ns/op) + github.com/dataence/bloom/standard 'Add' 65536 items (10 repetitions): 23041644 ns (351 ns/op) + github.com/dataence/bloom/standard 'Check' 65536 items (10 repetitions): 19153133 ns (292 ns/op) + github.com/cabello/bloom 'Add' 65536 items (10 repetitions): 131921507 ns (2012 ns/op) + github.com/cabello/bloom 'Contains' 65536 items (10 repetitions): 131108962 ns (2000 ns/op) + +(on MBPro15 OSX10.8.5 i7 4Core 2.4Ghz) + + +With 32bit bloom filters (bloom32) using modified sdbm, bloom32 does hashing with only 2 bit shifts, one xor and one substraction per byte. smdb is about as fast as fnv64a but gives less collisions with the dataset (see mask above). bloom.New(float64(10 * 1<<16),float64(7)) populated with 1<<16 random items from the dataset (see above) and tested against the rest results in less than 0.05% collisions. diff --git a/vendor/github.com/AndreasBriese/bbloom/bbloom.go b/vendor/github.com/AndreasBriese/bbloom/bbloom.go new file mode 100644 index 00000000..3d457406 --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/bbloom.go @@ -0,0 +1,270 @@ +// The MIT License (MIT) +// Copyright (c) 2014 Andreas Briese, eduToolbox@Bri-C GmbH, Sarstedt + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package bbloom + +import ( + "bytes" + "encoding/json" + "log" + "math" + "sync" + "unsafe" +) + +// helper +var mask = []uint8{1, 2, 4, 8, 16, 32, 64, 128} + +func getSize(ui64 uint64) (size uint64, exponent uint64) { + if ui64 < uint64(512) { + ui64 = uint64(512) + } + size = uint64(1) + for size < ui64 { + size <<= 1 + exponent++ + } + return size, exponent +} + +func calcSizeByWrongPositives(numEntries, wrongs float64) (uint64, uint64) { + size := -1 * numEntries * math.Log(wrongs) / math.Pow(float64(0.69314718056), 2) + locs := math.Ceil(float64(0.69314718056) * size / numEntries) + return uint64(size), uint64(locs) +} + +// New +// returns a new bloomfilter +func New(params ...float64) (bloomfilter Bloom) { + var entries, locs uint64 + if len(params) == 2 { + if params[1] < 1 { + entries, locs = calcSizeByWrongPositives(params[0], params[1]) + } else { + entries, locs = uint64(params[0]), uint64(params[1]) + } + } else { + log.Fatal("usage: New(float64(number_of_entries), float64(number_of_hashlocations)) i.e. New(float64(1000), float64(3)) or New(float64(number_of_entries), float64(number_of_hashlocations)) i.e. New(float64(1000), float64(0.03))") + } + size, exponent := getSize(uint64(entries)) + bloomfilter = Bloom{ + sizeExp: exponent, + size: size - 1, + setLocs: locs, + shift: 64 - exponent, + } + bloomfilter.Size(size) + return bloomfilter +} + +// NewWithBoolset +// takes a []byte slice and number of locs per entry +// returns the bloomfilter with a bitset populated according to the input []byte +func NewWithBoolset(bs *[]byte, locs uint64) (bloomfilter Bloom) { + bloomfilter = New(float64(len(*bs)<<3), float64(locs)) + ptr := uintptr(unsafe.Pointer(&bloomfilter.bitset[0])) + for _, b := range *bs { + *(*uint8)(unsafe.Pointer(ptr)) = b + ptr++ + } + return bloomfilter +} + +// bloomJSONImExport +// Im/Export structure used by JSONMarshal / JSONUnmarshal +type bloomJSONImExport struct { + FilterSet []byte + SetLocs uint64 +} + +// JSONUnmarshal +// takes JSON-Object (type bloomJSONImExport) as []bytes +// returns bloom32 / bloom64 object +func JSONUnmarshal(dbData []byte) Bloom { + bloomImEx := bloomJSONImExport{} + json.Unmarshal(dbData, &bloomImEx) + buf := bytes.NewBuffer(bloomImEx.FilterSet) + bs := buf.Bytes() + bf := NewWithBoolset(&bs, bloomImEx.SetLocs) + return bf +} + +// +// Bloom filter +type Bloom struct { + Mtx sync.Mutex + ElemNum uint64 + bitset []uint64 + sizeExp uint64 + size uint64 + setLocs uint64 + shift uint64 +} + +// <--- http://www.cse.yorku.ca/~oz/hash.html +// modified Berkeley DB Hash (32bit) +// hash is casted to l, h = 16bit fragments +// func (bl Bloom) absdbm(b *[]byte) (l, h uint64) { +// hash := uint64(len(*b)) +// for _, c := range *b { +// hash = uint64(c) + (hash << 6) + (hash << bl.sizeExp) - hash +// } +// h = hash >> bl.shift +// l = hash << bl.shift >> bl.shift +// return l, h +// } + +// Update: found sipHash of Jean-Philippe Aumasson & Daniel J. Bernstein to be even faster than absdbm() +// https://131002.net/siphash/ +// siphash was implemented for Go by Dmitry Chestnykh https://github.com/dchest/siphash + +// Add +// set the bit(s) for entry; Adds an entry to the Bloom filter +func (bl *Bloom) Add(entry []byte) { + l, h := bl.sipHash(entry) + for i := uint64(0); i < (*bl).setLocs; i++ { + (*bl).Set((h + i*l) & (*bl).size) + (*bl).ElemNum++ + } +} + +// AddTS +// Thread safe: Mutex.Lock the bloomfilter for the time of processing the entry +func (bl *Bloom) AddTS(entry []byte) { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + bl.Add(entry[:]) +} + +// Has +// check if bit(s) for entry is/are set +// returns true if the entry was added to the Bloom Filter +func (bl Bloom) Has(entry []byte) bool { + l, h := bl.sipHash(entry) + for i := uint64(0); i < bl.setLocs; i++ { + switch bl.IsSet((h + i*l) & bl.size) { + case false: + return false + } + } + return true +} + +// HasTS +// Thread safe: Mutex.Lock the bloomfilter for the time of processing the entry +func (bl *Bloom) HasTS(entry []byte) bool { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + return bl.Has(entry[:]) +} + +// AddIfNotHas +// Only Add entry if it's not present in the bloomfilter +// returns true if entry was added +// returns false if entry was allready registered in the bloomfilter +func (bl Bloom) AddIfNotHas(entry []byte) (added bool) { + if bl.Has(entry[:]) { + return added + } + bl.Add(entry[:]) + return true +} + +// AddIfNotHasTS +// Tread safe: Only Add entry if it's not present in the bloomfilter +// returns true if entry was added +// returns false if entry was allready registered in the bloomfilter +func (bl *Bloom) AddIfNotHasTS(entry []byte) (added bool) { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + return bl.AddIfNotHas(entry[:]) +} + +// Size +// make Bloom filter with as bitset of size sz +func (bl *Bloom) Size(sz uint64) { + (*bl).bitset = make([]uint64, sz>>6) +} + +// Clear +// resets the Bloom filter +func (bl *Bloom) Clear() { + for i, _ := range (*bl).bitset { + (*bl).bitset[i] = 0 + } +} + +// Set +// set the bit[idx] of bitsit +func (bl *Bloom) Set(idx uint64) { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bl.bitset[idx>>6])) + uintptr((idx%64)>>3)) + *(*uint8)(ptr) |= mask[idx%8] +} + +// IsSet +// check if bit[idx] of bitset is set +// returns true/false +func (bl *Bloom) IsSet(idx uint64) bool { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bl.bitset[idx>>6])) + uintptr((idx%64)>>3)) + r := ((*(*uint8)(ptr)) >> (idx % 8)) & 1 + return r == 1 +} + +// JSONMarshal +// returns JSON-object (type bloomJSONImExport) as []byte +func (bl Bloom) JSONMarshal() []byte { + bloomImEx := bloomJSONImExport{} + bloomImEx.SetLocs = uint64(bl.setLocs) + bloomImEx.FilterSet = make([]byte, len(bl.bitset)<<3) + ptr := uintptr(unsafe.Pointer(&bl.bitset[0])) + for i := range bloomImEx.FilterSet { + bloomImEx.FilterSet[i] = *(*byte)(unsafe.Pointer(ptr)) + ptr++ + } + data, err := json.Marshal(bloomImEx) + if err != nil { + log.Fatal("json.Marshal failed: ", err) + } + return data +} + +// // alternative hashFn +// func (bl Bloom) fnv64a(b *[]byte) (l, h uint64) { +// h64 := fnv.New64a() +// h64.Write(*b) +// hash := h64.Sum64() +// h = hash >> 32 +// l = hash << 32 >> 32 +// return l, h +// } +// +// // <-- http://partow.net/programming/hashfunctions/index.html +// // citation: An algorithm proposed by Donald E. Knuth in The Art Of Computer Programming Volume 3, +// // under the topic of sorting and search chapter 6.4. +// // modified to fit with boolset-length +// func (bl Bloom) DEKHash(b *[]byte) (l, h uint64) { +// hash := uint64(len(*b)) +// for _, c := range *b { +// hash = ((hash << 5) ^ (hash >> bl.shift)) ^ uint64(c) +// } +// h = hash >> bl.shift +// l = hash << bl.sizeExp >> bl.sizeExp +// return l, h +// } diff --git a/vendor/github.com/AndreasBriese/bbloom/sipHash.go b/vendor/github.com/AndreasBriese/bbloom/sipHash.go new file mode 100644 index 00000000..a91d8199 --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/sipHash.go @@ -0,0 +1,225 @@ +// Written in 2012 by Dmitry Chestnykh. +// +// To the extent possible under law, the author have dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// http://creativecommons.org/publicdomain/zero/1.0/ +// +// Package siphash implements SipHash-2-4, a fast short-input PRF +// created by Jean-Philippe Aumasson and Daniel J. Bernstein. + +package bbloom + +// Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit +// parts of 128-bit key: k0 and k1. +func (bl Bloom) sipHash(p []byte) (l, h uint64) { + // Initialization. + v0 := uint64(8317987320269560794) // k0 ^ 0x736f6d6570736575 + v1 := uint64(7237128889637516672) // k1 ^ 0x646f72616e646f6d + v2 := uint64(7816392314733513934) // k0 ^ 0x6c7967656e657261 + v3 := uint64(8387220255325274014) // k1 ^ 0x7465646279746573 + t := uint64(len(p)) << 56 + + // Compression. + for len(p) >= 8 { + + m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | + uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 + + v3 ^= m + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + v0 ^= m + p = p[8:] + } + + // Compress last block. + switch len(p) { + case 7: + t |= uint64(p[6]) << 48 + fallthrough + case 6: + t |= uint64(p[5]) << 40 + fallthrough + case 5: + t |= uint64(p[4]) << 32 + fallthrough + case 4: + t |= uint64(p[3]) << 24 + fallthrough + case 3: + t |= uint64(p[2]) << 16 + fallthrough + case 2: + t |= uint64(p[1]) << 8 + fallthrough + case 1: + t |= uint64(p[0]) + } + + v3 ^= t + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + v0 ^= t + + // Finalization. + v2 ^= 0xff + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 3. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 4. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // return v0 ^ v1 ^ v2 ^ v3 + + hash := v0 ^ v1 ^ v2 ^ v3 + h = hash >> bl.shift + l = hash << bl.shift >> bl.shift + return l, h + +} diff --git a/vendor/github.com/AndreasBriese/bbloom/words.txt b/vendor/github.com/AndreasBriese/bbloom/words.txt new file mode 100644 index 00000000..ad86a31a --- /dev/null +++ b/vendor/github.com/AndreasBriese/bbloom/words.txt @@ -0,0 +1,140 @@ +2014/01/01 00:00:00 /info.html +2014/01/01 00:00:00 /info.html +2014/01/01 00:00:01 /info.html +2014/01/01 00:00:02 /info.html +2014/01/01 00:00:03 /info.html +2014/01/01 00:00:04 /info.html +2014/01/01 00:00:05 /info.html +2014/01/01 00:00:06 /info.html +2014/01/01 00:00:07 /info.html +2014/01/01 00:00:08 /info.html +2014/01/01 00:00:09 /info.html +2014/01/01 00:00:10 /info.html +2014/01/01 00:00:11 /info.html +2014/01/01 00:00:12 /info.html +2014/01/01 00:00:13 /info.html +2014/01/01 00:00:14 /info.html +2014/01/01 00:00:15 /info.html +2014/01/01 00:00:16 /info.html +2014/01/01 00:00:17 /info.html +2014/01/01 00:00:18 /info.html +2014/01/01 00:00:19 /info.html +2014/01/01 00:00:20 /info.html +2014/01/01 00:00:21 /info.html +2014/01/01 00:00:22 /info.html +2014/01/01 00:00:23 /info.html +2014/01/01 00:00:24 /info.html +2014/01/01 00:00:25 /info.html +2014/01/01 00:00:26 /info.html +2014/01/01 00:00:27 /info.html +2014/01/01 00:00:28 /info.html +2014/01/01 00:00:29 /info.html +2014/01/01 00:00:30 /info.html +2014/01/01 00:00:31 /info.html +2014/01/01 00:00:32 /info.html +2014/01/01 00:00:33 /info.html +2014/01/01 00:00:34 /info.html +2014/01/01 00:00:35 /info.html +2014/01/01 00:00:36 /info.html +2014/01/01 00:00:37 /info.html +2014/01/01 00:00:38 /info.html +2014/01/01 00:00:39 /info.html +2014/01/01 00:00:40 /info.html +2014/01/01 00:00:41 /info.html +2014/01/01 00:00:42 /info.html +2014/01/01 00:00:43 /info.html +2014/01/01 00:00:44 /info.html +2014/01/01 00:00:45 /info.html +2014/01/01 00:00:46 /info.html +2014/01/01 00:00:47 /info.html +2014/01/01 00:00:48 /info.html +2014/01/01 00:00:49 /info.html +2014/01/01 00:00:50 /info.html +2014/01/01 00:00:51 /info.html +2014/01/01 00:00:52 /info.html +2014/01/01 00:00:53 /info.html +2014/01/01 00:00:54 /info.html +2014/01/01 00:00:55 /info.html +2014/01/01 00:00:56 /info.html +2014/01/01 00:00:57 /info.html +2014/01/01 00:00:58 /info.html +2014/01/01 00:00:59 /info.html +2014/01/01 00:01:00 /info.html +2014/01/01 00:01:01 /info.html +2014/01/01 00:01:02 /info.html +2014/01/01 00:01:03 /info.html +2014/01/01 00:01:04 /info.html +2014/01/01 00:01:05 /info.html +2014/01/01 00:01:06 /info.html +2014/01/01 00:01:07 /info.html +2014/01/01 00:01:08 /info.html +2014/01/01 00:01:09 /info.html +2014/01/01 00:01:10 /info.html +2014/01/01 00:01:11 /info.html +2014/01/01 00:01:12 /info.html +2014/01/01 00:01:13 /info.html +2014/01/01 00:01:14 /info.html +2014/01/01 00:01:15 /info.html +2014/01/01 00:01:16 /info.html +2014/01/01 00:01:17 /info.html +2014/01/01 00:01:18 /info.html +2014/01/01 00:01:19 /info.html +2014/01/01 00:01:20 /info.html +2014/01/01 00:01:21 /info.html +2014/01/01 00:01:22 /info.html +2014/01/01 00:01:23 /info.html +2014/01/01 00:01:24 /info.html +2014/01/01 00:01:25 /info.html +2014/01/01 00:01:26 /info.html +2014/01/01 00:01:27 /info.html +2014/01/01 00:01:28 /info.html +2014/01/01 00:01:29 /info.html +2014/01/01 00:01:30 /info.html +2014/01/01 00:01:31 /info.html +2014/01/01 00:01:32 /info.html +2014/01/01 00:01:33 /info.html +2014/01/01 00:01:34 /info.html +2014/01/01 00:01:35 /info.html +2014/01/01 00:01:36 /info.html +2014/01/01 00:01:37 /info.html +2014/01/01 00:01:38 /info.html +2014/01/01 00:01:39 /info.html +2014/01/01 00:01:40 /info.html +2014/01/01 00:01:41 /info.html +2014/01/01 00:01:42 /info.html +2014/01/01 00:01:43 /info.html +2014/01/01 00:01:44 /info.html +2014/01/01 00:01:45 /info.html +2014/01/01 00:01:46 /info.html +2014/01/01 00:01:47 /info.html +2014/01/01 00:01:48 /info.html +2014/01/01 00:01:49 /info.html +2014/01/01 00:01:50 /info.html +2014/01/01 00:01:51 /info.html +2014/01/01 00:01:52 /info.html +2014/01/01 00:01:53 /info.html +2014/01/01 00:01:54 /info.html +2014/01/01 00:01:55 /info.html +2014/01/01 00:01:56 /info.html +2014/01/01 00:01:57 /info.html +2014/01/01 00:01:58 /info.html +2014/01/01 00:01:59 /info.html +2014/01/01 00:02:00 /info.html +2014/01/01 00:02:01 /info.html +2014/01/01 00:02:02 /info.html +2014/01/01 00:02:03 /info.html +2014/01/01 00:02:04 /info.html +2014/01/01 00:02:05 /info.html +2014/01/01 00:02:06 /info.html +2014/01/01 00:02:07 /info.html +2014/01/01 00:02:08 /info.html +2014/01/01 00:02:09 /info.html +2014/01/01 00:02:10 /info.html +2014/01/01 00:02:11 /info.html +2014/01/01 00:02:12 /info.html +2014/01/01 00:02:13 /info.html +2014/01/01 00:02:14 /info.html +2014/01/01 00:02:15 /info.html +2014/01/01 00:02:16 /info.html +2014/01/01 00:02:17 /info.html +2014/01/01 00:02:18 /info.html diff --git a/vendor/github.com/Stebalien/go-bitfield/LICENSE b/vendor/github.com/Stebalien/go-bitfield/LICENSE new file mode 100644 index 00000000..a55967e0 --- /dev/null +++ b/vendor/github.com/Stebalien/go-bitfield/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2018 Steven Allen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Stebalien/go-bitfield/README.md b/vendor/github.com/Stebalien/go-bitfield/README.md new file mode 100644 index 00000000..ea3037cb --- /dev/null +++ b/vendor/github.com/Stebalien/go-bitfield/README.md @@ -0,0 +1,5 @@ +# go-bitfield + +This is a simple bitfield package that's about 2-3x faster than using `big.Int`s +from the standard library. It also has a better interface (and, e.g., supports +counting ones). diff --git a/vendor/github.com/Stebalien/go-bitfield/bitfield.go b/vendor/github.com/Stebalien/go-bitfield/bitfield.go new file mode 100644 index 00000000..d6f12b06 --- /dev/null +++ b/vendor/github.com/Stebalien/go-bitfield/bitfield.go @@ -0,0 +1,114 @@ +package bitfield + +// NOTE: Don't bother replacing the divisions/modulo with shifts/ands, go is smart. + +import ( + "math/bits" +) + +// NewBitfield creates a new fixed-sized Bitfield (allocated up-front). +// +// Panics if size is not a multiple of 8. +func NewBitfield(size int) Bitfield { + if size%8 != 0 { + panic("Bitfield size must be a multiple of 8") + } + return make([]byte, size/8) +} + +// FromBytes constructs a new bitfield from a serialized bitfield. +func FromBytes(size int, bits []byte) Bitfield { + bf := NewBitfield(size) + start := len(bf) - len(bits) + if start < 0 { + panic("bitfield too small") + } + copy(bf[start:], bits) + return bf +} + +func (bf Bitfield) offset(i int) (uint, uint8) { + return uint(len(bf)) - (uint(i) / 8) - 1, uint8(i) % 8 +} + +// Bitfield is, well, a bitfield. +type Bitfield []byte + +// Bytes returns the Bitfield as a byte string. +// +// This function *does not* copy. +func (bf Bitfield) Bytes() []byte { + for i, b := range bf { + if b != 0 { + return bf[i:] + } + } + return nil +} + +// Bit returns the ith bit. +// +// Panics if the bit is out of bounds. +func (bf Bitfield) Bit(i int) bool { + idx, off := bf.offset(i) + return (bf[idx]>>off)&0x1 != 0 +} + +// SetBit sets the ith bit. +// +// Panics if the bit is out of bounds. +func (bf Bitfield) SetBit(i int) { + idx, off := bf.offset(i) + bf[idx] |= 1 << off +} + +// UnsetBit unsets the ith bit. +// +// Panics if the bit is out of bounds. +func (bf Bitfield) UnsetBit(i int) { + idx, off := bf.offset(i) + bf[idx] &= 0xFF ^ (1 << off) +} + +// SetBytes sets the bits to the given byte array. +// +// Panics if 'b' is larger than the bitfield. +func (bf Bitfield) SetBytes(b []byte) { + start := len(bf) - len(b) + if start < 0 { + panic("bitfield too small") + } + for i := range bf[:start] { + bf[i] = 0 + } + copy(bf[start:], b) +} + +// Ones returns the number of bits set. +func (bf Bitfield) Ones() int { + cnt := 0 + for _, b := range bf { + cnt += bits.OnesCount8(b) + } + return cnt +} + +// OnesBefore returns the number of bits set *before* this bit. +func (bf Bitfield) OnesBefore(i int) int { + idx, off := bf.offset(i) + cnt := bits.OnesCount8(bf[idx] << (8 - off)) + for _, b := range bf[idx+1:] { + cnt += bits.OnesCount8(b) + } + return cnt +} + +// OnesAfter returns the number of bits set *after* this bit. +func (bf Bitfield) OnesAfter(i int) int { + idx, off := bf.offset(i) + cnt := bits.OnesCount8(bf[idx] >> off) + for _, b := range bf[:idx] { + cnt += bits.OnesCount8(b) + } + return cnt +} diff --git a/vendor/github.com/Stebalien/go-bitfield/go.mod b/vendor/github.com/Stebalien/go-bitfield/go.mod new file mode 100644 index 00000000..83337723 --- /dev/null +++ b/vendor/github.com/Stebalien/go-bitfield/go.mod @@ -0,0 +1,3 @@ +module github.com/Stebalien/go-bitfield + +go 1.12 diff --git a/vendor/github.com/Stebalien/go-bitfield/package.json b/vendor/github.com/Stebalien/go-bitfield/package.json new file mode 100644 index 00000000..a8045cb2 --- /dev/null +++ b/vendor/github.com/Stebalien/go-bitfield/package.json @@ -0,0 +1,16 @@ +{ + "author": "Stebalien", + "bugs": { + "url": "https://github.com/Stebalien/go-bitfield" + }, + "gx": { + "dvcsimport": "github.com/Stebalien/go-bitfield" + }, + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-bitfield", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.3" +} + diff --git a/vendor/github.com/allegro/bigcache/.gitignore b/vendor/github.com/allegro/bigcache/.gitignore new file mode 100644 index 00000000..256d6659 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/.gitignore @@ -0,0 +1,10 @@ +.idea +.DS_Store +/server/server.exe +/server/server +/server/server_dar* +/server/server_fre* +/server/server_win* +/server/server_net* +/server/server_ope* +CHANGELOG.md diff --git a/vendor/github.com/allegro/bigcache/.travis.yml b/vendor/github.com/allegro/bigcache/.travis.yml new file mode 100644 index 00000000..cc28df6a --- /dev/null +++ b/vendor/github.com/allegro/bigcache/.travis.yml @@ -0,0 +1,31 @@ +language: go + +go: + - 1.x + - tip + +matrix: + allow_failures: + - go: tip + fast_finish: true + +before_install: + - go get github.com/modocache/gover + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover + - go get golang.org/x/tools/cmd/goimports + - go get golang.org/x/lint/golint + - go get github.com/stretchr/testify/assert + - go get github.com/gordonklaus/ineffassign + +script: + - gofiles=$(find ./ -name '*.go') && [ -z "$gofiles" ] || unformatted=$(goimports -l $gofiles) && [ -z "$unformatted" ] || (echo >&2 "Go files must be formatted with gofmt. Following files has problem:\n $unformatted" && false) + - diff <(echo -n) <(gofmt -s -d .) + - golint ./... # This won't break the build, just show warnings + - ineffassign . + - go vet ./... + - go test -race -count=1 -coverprofile=queue.coverprofile ./queue + - go test -race -count=1 -coverprofile=server.coverprofile ./server + - go test -race -count=1 -coverprofile=main.coverprofile + - $HOME/gopath/bin/gover + - $HOME/gopath/bin/goveralls -coverprofile=gover.coverprofile -service travis-ci diff --git a/vendor/github.com/allegro/bigcache/README.md b/vendor/github.com/allegro/bigcache/README.md new file mode 100644 index 00000000..c23f7f36 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/README.md @@ -0,0 +1,150 @@ +# BigCache [![Build Status](https://travis-ci.org/allegro/bigcache.svg?branch=master)](https://travis-ci.org/allegro/bigcache) [![Coverage Status](https://coveralls.io/repos/github/allegro/bigcache/badge.svg?branch=master)](https://coveralls.io/github/allegro/bigcache?branch=master) [![GoDoc](https://godoc.org/github.com/allegro/bigcache?status.svg)](https://godoc.org/github.com/allegro/bigcache) [![Go Report Card](https://goreportcard.com/badge/github.com/allegro/bigcache)](https://goreportcard.com/report/github.com/allegro/bigcache) + +Fast, concurrent, evicting in-memory cache written to keep big number of entries without impact on performance. +BigCache keeps entries on heap but omits GC for them. To achieve that operations on bytes arrays take place, +therefore entries (de)serialization in front of the cache will be needed in most use cases. + +## Usage + +### Simple initialization + +```go +import "github.com/allegro/bigcache" + +cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute)) + +cache.Set("my-unique-key", []byte("value")) + +entry, _ := cache.Get("my-unique-key") +fmt.Println(string(entry)) +``` + +### Custom initialization + +When cache load can be predicted in advance then it is better to use custom initialization because additional memory +allocation can be avoided in that way. + +```go +import ( + "log" + + "github.com/allegro/bigcache" +) + +config := bigcache.Config { + // number of shards (must be a power of 2) + Shards: 1024, + // time after which entry can be evicted + LifeWindow: 10 * time.Minute, + // rps * lifeWindow, used only in initial memory allocation + MaxEntriesInWindow: 1000 * 10 * 60, + // max entry size in bytes, used only in initial memory allocation + MaxEntrySize: 500, + // prints information about additional memory allocation + Verbose: true, + // cache will not allocate more memory than this limit, value in MB + // if value is reached then the oldest entries can be overridden for the new ones + // 0 value means no size limit + HardMaxCacheSize: 8192, + // callback fired when the oldest entry is removed because of its expiration time or no space left + // for the new entry, or because delete was called. A bitmask representing the reason will be returned. + // Default value is nil which means no callback and it prevents from unwrapping the oldest entry. + OnRemove: nil, + // OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left + // for the new entry, or because delete was called. A constant representing the reason will be passed through. + // Default value is nil which means no callback and it prevents from unwrapping the oldest entry. + // Ignored if OnRemove is specified. + OnRemoveWithReason: nil, + } + +cache, initErr := bigcache.NewBigCache(config) +if initErr != nil { + log.Fatal(initErr) +} + +cache.Set("my-unique-key", []byte("value")) + +if entry, err := cache.Get("my-unique-key"); err == nil { + fmt.Println(string(entry)) +} +``` + +## Benchmarks + +Three caches were compared: bigcache, [freecache](https://github.com/coocood/freecache) and map. +Benchmark tests were made using an i7-6700K with 32GB of RAM on Windows 10. + +### Writes and reads + +```bash +cd caches_bench; go test -bench=. -benchtime=10s ./... -timeout 30m + +BenchmarkMapSet-8 3000000 569 ns/op 202 B/op 3 allocs/op +BenchmarkConcurrentMapSet-8 1000000 1592 ns/op 347 B/op 8 allocs/op +BenchmarkFreeCacheSet-8 3000000 775 ns/op 355 B/op 2 allocs/op +BenchmarkBigCacheSet-8 3000000 640 ns/op 303 B/op 2 allocs/op +BenchmarkMapGet-8 5000000 407 ns/op 24 B/op 1 allocs/op +BenchmarkConcurrentMapGet-8 3000000 558 ns/op 24 B/op 2 allocs/op +BenchmarkFreeCacheGet-8 2000000 682 ns/op 136 B/op 2 allocs/op +BenchmarkBigCacheGet-8 3000000 512 ns/op 152 B/op 4 allocs/op +BenchmarkBigCacheSetParallel-8 10000000 225 ns/op 313 B/op 3 allocs/op +BenchmarkFreeCacheSetParallel-8 10000000 218 ns/op 341 B/op 3 allocs/op +BenchmarkConcurrentMapSetParallel-8 5000000 318 ns/op 200 B/op 6 allocs/op +BenchmarkBigCacheGetParallel-8 20000000 178 ns/op 152 B/op 4 allocs/op +BenchmarkFreeCacheGetParallel-8 20000000 295 ns/op 136 B/op 3 allocs/op +BenchmarkConcurrentMapGetParallel-8 10000000 237 ns/op 24 B/op 2 allocs/op +``` + +Writes and reads in bigcache are faster than in freecache. +Writes to map are the slowest. + +### GC pause time + +```bash +cd caches_bench; go run caches_gc_overhead_comparison.go + +Number of entries: 20000000 +GC pause for bigcache: 5.8658ms +GC pause for freecache: 32.4341ms +GC pause for map: 52.9661ms +``` + +Test shows how long are the GC pauses for caches filled with 20mln of entries. +Bigcache and freecache have very similar GC pause time. +It is clear that both reduce GC overhead in contrast to map +which GC pause time took more than 10 seconds. + +## How it works + +BigCache relies on optimization presented in 1.5 version of Go ([issue-9477](https://github.com/golang/go/issues/9477)). +This optimization states that if map without pointers in keys and values is used then GC will omit its content. +Therefore BigCache uses `map[uint64]uint32` where keys are hashed and values are offsets of entries. + +Entries are kept in bytes array, to omit GC again. +Bytes array size can grow to gigabytes without impact on performance +because GC will only see single pointer to it. + +## Bigcache vs Freecache + +Both caches provide the same core features but they reduce GC overhead in different ways. +Bigcache relies on `map[uint64]uint32`, freecache implements its own mapping built on +slices to reduce number of pointers. + +Results from benchmark tests are presented above. +One of the advantage of bigcache over freecache is that you don’t need to know +the size of the cache in advance, because when bigcache is full, +it can allocate additional memory for new entries instead of +overwriting existing ones as freecache does currently. +However hard max size in bigcache also can be set, check [HardMaxCacheSize](https://godoc.org/github.com/allegro/bigcache#Config). + +## HTTP Server + +This package also includes an easily deployable HTTP implementation of BigCache, which can be found in the [server](/server) package. + +## More + +Bigcache genesis is described in allegro.tech blog post: [writing a very fast cache service in Go](http://allegro.tech/2016/03/writing-fast-cache-service-in-go.html) + +## License + +BigCache is released under the Apache 2.0 license (see [LICENSE](LICENSE)) diff --git a/vendor/github.com/allegro/bigcache/bigcache.go b/vendor/github.com/allegro/bigcache/bigcache.go new file mode 100644 index 00000000..b3879264 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/bigcache.go @@ -0,0 +1,202 @@ +package bigcache + +import ( + "fmt" + "time" +) + +const ( + minimumEntriesInShard = 10 // Minimum number of entries in single shard +) + +// BigCache is fast, concurrent, evicting cache created to keep big number of entries without impact on performance. +// It keeps entries on heap but omits GC for them. To achieve that, operations take place on byte arrays, +// therefore entries (de)serialization in front of the cache will be needed in most use cases. +type BigCache struct { + shards []*cacheShard + lifeWindow uint64 + clock clock + hash Hasher + config Config + shardMask uint64 + maxShardSize uint32 + close chan struct{} +} + +// RemoveReason is a value used to signal to the user why a particular key was removed in the OnRemove callback. +type RemoveReason uint32 + +const ( + // Expired means the key is past its LifeWindow. + Expired RemoveReason = iota + // NoSpace means the key is the oldest and the cache size was at its maximum when Set was called, or the + // entry exceeded the maximum shard size. + NoSpace + // Deleted means Delete was called and this key was removed as a result. + Deleted +) + +// NewBigCache initialize new instance of BigCache +func NewBigCache(config Config) (*BigCache, error) { + return newBigCache(config, &systemClock{}) +} + +func newBigCache(config Config, clock clock) (*BigCache, error) { + + if !isPowerOfTwo(config.Shards) { + return nil, fmt.Errorf("Shards number must be power of two") + } + + if config.Hasher == nil { + config.Hasher = newDefaultHasher() + } + + cache := &BigCache{ + shards: make([]*cacheShard, config.Shards), + lifeWindow: uint64(config.LifeWindow.Seconds()), + clock: clock, + hash: config.Hasher, + config: config, + shardMask: uint64(config.Shards - 1), + maxShardSize: uint32(config.maximumShardSize()), + close: make(chan struct{}), + } + + var onRemove func(wrappedEntry []byte, reason RemoveReason) + if config.OnRemove != nil { + onRemove = cache.providedOnRemove + } else if config.OnRemoveWithReason != nil { + onRemove = cache.providedOnRemoveWithReason + } else { + onRemove = cache.notProvidedOnRemove + } + + for i := 0; i < config.Shards; i++ { + cache.shards[i] = initNewShard(config, onRemove, clock) + } + + if config.CleanWindow > 0 { + go func() { + ticker := time.NewTicker(config.CleanWindow) + defer ticker.Stop() + for { + select { + case t := <-ticker.C: + cache.cleanUp(uint64(t.Unix())) + case <-cache.close: + return + } + } + }() + } + + return cache, nil +} + +// Close is used to signal a shutdown of the cache when you are done with it. +// This allows the cleaning goroutines to exit and ensures references are not +// kept to the cache preventing GC of the entire cache. +func (c *BigCache) Close() error { + close(c.close) + return nil +} + +// Get reads entry for the key. +// It returns an ErrEntryNotFound when +// no entry exists for the given key. +func (c *BigCache) Get(key string) ([]byte, error) { + hashedKey := c.hash.Sum64(key) + shard := c.getShard(hashedKey) + return shard.get(key, hashedKey) +} + +// Set saves entry under the key +func (c *BigCache) Set(key string, entry []byte) error { + hashedKey := c.hash.Sum64(key) + shard := c.getShard(hashedKey) + return shard.set(key, hashedKey, entry) +} + +// Delete removes the key +func (c *BigCache) Delete(key string) error { + hashedKey := c.hash.Sum64(key) + shard := c.getShard(hashedKey) + return shard.del(key, hashedKey) +} + +// Reset empties all cache shards +func (c *BigCache) Reset() error { + for _, shard := range c.shards { + shard.reset(c.config) + } + return nil +} + +// Len computes number of entries in cache +func (c *BigCache) Len() int { + var len int + for _, shard := range c.shards { + len += shard.len() + } + return len +} + +// Capacity returns amount of bytes store in the cache. +func (c *BigCache) Capacity() int { + var len int + for _, shard := range c.shards { + len += shard.capacity() + } + return len +} + +// Stats returns cache's statistics +func (c *BigCache) Stats() Stats { + var s Stats + for _, shard := range c.shards { + tmp := shard.getStats() + s.Hits += tmp.Hits + s.Misses += tmp.Misses + s.DelHits += tmp.DelHits + s.DelMisses += tmp.DelMisses + s.Collisions += tmp.Collisions + } + return s +} + +// Iterator returns iterator function to iterate over EntryInfo's from whole cache. +func (c *BigCache) Iterator() *EntryInfoIterator { + return newIterator(c) +} + +func (c *BigCache) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func(reason RemoveReason) error) bool { + oldestTimestamp := readTimestampFromEntry(oldestEntry) + if currentTimestamp-oldestTimestamp > c.lifeWindow { + evict(Expired) + return true + } + return false +} + +func (c *BigCache) cleanUp(currentTimestamp uint64) { + for _, shard := range c.shards { + shard.cleanUp(currentTimestamp) + } +} + +func (c *BigCache) getShard(hashedKey uint64) (shard *cacheShard) { + return c.shards[hashedKey&c.shardMask] +} + +func (c *BigCache) providedOnRemove(wrappedEntry []byte, reason RemoveReason) { + c.config.OnRemove(readKeyFromEntry(wrappedEntry), readEntry(wrappedEntry)) +} + +func (c *BigCache) providedOnRemoveWithReason(wrappedEntry []byte, reason RemoveReason) { + if c.config.onRemoveFilter == 0 || (1< 0 { + c.config.OnRemoveWithReason(readKeyFromEntry(wrappedEntry), readEntry(wrappedEntry), reason) + } +} + +func (c *BigCache) notProvidedOnRemove(wrappedEntry []byte, reason RemoveReason) { +} diff --git a/vendor/github.com/allegro/bigcache/bytes.go b/vendor/github.com/allegro/bigcache/bytes.go new file mode 100644 index 00000000..3944bfe1 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/bytes.go @@ -0,0 +1,14 @@ +// +build !appengine + +package bigcache + +import ( + "reflect" + "unsafe" +) + +func bytesToString(b []byte) string { + bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + strHeader := reflect.StringHeader{Data: bytesHeader.Data, Len: bytesHeader.Len} + return *(*string)(unsafe.Pointer(&strHeader)) +} diff --git a/vendor/github.com/allegro/bigcache/bytes_appengine.go b/vendor/github.com/allegro/bigcache/bytes_appengine.go new file mode 100644 index 00000000..3892f3b5 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/bytes_appengine.go @@ -0,0 +1,7 @@ +// +build appengine + +package bigcache + +func bytesToString(b []byte) string { + return string(b) +} diff --git a/vendor/github.com/allegro/bigcache/config.go b/vendor/github.com/allegro/bigcache/config.go new file mode 100644 index 00000000..9654143a --- /dev/null +++ b/vendor/github.com/allegro/bigcache/config.go @@ -0,0 +1,86 @@ +package bigcache + +import "time" + +// Config for BigCache +type Config struct { + // Number of cache shards, value must be a power of two + Shards int + // Time after which entry can be evicted + LifeWindow time.Duration + // Interval between removing expired entries (clean up). + // If set to <= 0 then no action is performed. Setting to < 1 second is counterproductive — bigcache has a one second resolution. + CleanWindow time.Duration + // Max number of entries in life window. Used only to calculate initial size for cache shards. + // When proper value is set then additional memory allocation does not occur. + MaxEntriesInWindow int + // Max size of entry in bytes. Used only to calculate initial size for cache shards. + MaxEntrySize int + // Verbose mode prints information about new memory allocation + Verbose bool + // Hasher used to map between string keys and unsigned 64bit integers, by default fnv64 hashing is used. + Hasher Hasher + // HardMaxCacheSize is a limit for cache size in MB. Cache will not allocate more memory than this limit. + // It can protect application from consuming all available memory on machine, therefore from running OOM Killer. + // Default value is 0 which means unlimited size. When the limit is higher than 0 and reached then + // the oldest entries are overridden for the new ones. + HardMaxCacheSize int + // OnRemove is a callback fired when the oldest entry is removed because of its expiration time or no space left + // for the new entry, or because delete was called. + // Default value is nil which means no callback and it prevents from unwrapping the oldest entry. + OnRemove func(key string, entry []byte) + // OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left + // for the new entry, or because delete was called. A constant representing the reason will be passed through. + // Default value is nil which means no callback and it prevents from unwrapping the oldest entry. + // Ignored if OnRemove is specified. + OnRemoveWithReason func(key string, entry []byte, reason RemoveReason) + + onRemoveFilter int + + // Logger is a logging interface and used in combination with `Verbose` + // Defaults to `DefaultLogger()` + Logger Logger +} + +// DefaultConfig initializes config with default values. +// When load for BigCache can be predicted in advance then it is better to use custom config. +func DefaultConfig(eviction time.Duration) Config { + return Config{ + Shards: 1024, + LifeWindow: eviction, + CleanWindow: 0, + MaxEntriesInWindow: 1000 * 10 * 60, + MaxEntrySize: 500, + Verbose: true, + Hasher: newDefaultHasher(), + HardMaxCacheSize: 0, + Logger: DefaultLogger(), + } +} + +// initialShardSize computes initial shard size +func (c Config) initialShardSize() int { + return max(c.MaxEntriesInWindow/c.Shards, minimumEntriesInShard) +} + +// maximumShardSize computes maximum shard size +func (c Config) maximumShardSize() int { + maxShardSize := 0 + + if c.HardMaxCacheSize > 0 { + maxShardSize = convertMBToBytes(c.HardMaxCacheSize) / c.Shards + } + + return maxShardSize +} + +// OnRemoveFilterSet sets which remove reasons will trigger a call to OnRemoveWithReason. +// Filtering out reasons prevents bigcache from unwrapping them, which saves cpu. +func (c Config) OnRemoveFilterSet(reasons ...RemoveReason) Config { + c.onRemoveFilter = 0 + for i := range reasons { + c.onRemoveFilter |= 1 << uint(reasons[i]) + } + + return c +} diff --git a/vendor/github.com/allegro/bigcache/encoding.go b/vendor/github.com/allegro/bigcache/encoding.go new file mode 100644 index 00000000..4d434e5d --- /dev/null +++ b/vendor/github.com/allegro/bigcache/encoding.go @@ -0,0 +1,62 @@ +package bigcache + +import ( + "encoding/binary" +) + +const ( + timestampSizeInBytes = 8 // Number of bytes used for timestamp + hashSizeInBytes = 8 // Number of bytes used for hash + keySizeInBytes = 2 // Number of bytes used for size of entry key + headersSizeInBytes = timestampSizeInBytes + hashSizeInBytes + keySizeInBytes // Number of bytes used for all headers +) + +func wrapEntry(timestamp uint64, hash uint64, key string, entry []byte, buffer *[]byte) []byte { + keyLength := len(key) + blobLength := len(entry) + headersSizeInBytes + keyLength + + if blobLength > len(*buffer) { + *buffer = make([]byte, blobLength) + } + blob := *buffer + + binary.LittleEndian.PutUint64(blob, timestamp) + binary.LittleEndian.PutUint64(blob[timestampSizeInBytes:], hash) + binary.LittleEndian.PutUint16(blob[timestampSizeInBytes+hashSizeInBytes:], uint16(keyLength)) + copy(blob[headersSizeInBytes:], key) + copy(blob[headersSizeInBytes+keyLength:], entry) + + return blob[:blobLength] +} + +func readEntry(data []byte) []byte { + length := binary.LittleEndian.Uint16(data[timestampSizeInBytes+hashSizeInBytes:]) + + // copy on read + dst := make([]byte, len(data)-int(headersSizeInBytes+length)) + copy(dst, data[headersSizeInBytes+length:]) + + return dst +} + +func readTimestampFromEntry(data []byte) uint64 { + return binary.LittleEndian.Uint64(data) +} + +func readKeyFromEntry(data []byte) string { + length := binary.LittleEndian.Uint16(data[timestampSizeInBytes+hashSizeInBytes:]) + + // copy on read + dst := make([]byte, length) + copy(dst, data[headersSizeInBytes:headersSizeInBytes+length]) + + return bytesToString(dst) +} + +func readHashFromEntry(data []byte) uint64 { + return binary.LittleEndian.Uint64(data[timestampSizeInBytes:]) +} + +func resetKeyFromEntry(data []byte) { + binary.LittleEndian.PutUint64(data[timestampSizeInBytes:], 0) +} diff --git a/vendor/github.com/allegro/bigcache/entry_not_found_error.go b/vendor/github.com/allegro/bigcache/entry_not_found_error.go new file mode 100644 index 00000000..051a7123 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/entry_not_found_error.go @@ -0,0 +1,6 @@ +package bigcache + +import "errors" + +// ErrEntryNotFound is an error type struct which is returned when entry was not found for provided key +var ErrEntryNotFound = errors.New("Entry not found") diff --git a/vendor/github.com/allegro/bigcache/shard.go b/vendor/github.com/allegro/bigcache/shard.go new file mode 100644 index 00000000..67679ba1 --- /dev/null +++ b/vendor/github.com/allegro/bigcache/shard.go @@ -0,0 +1,239 @@ +package bigcache + +import ( + "fmt" + "sync" + "sync/atomic" + + "github.com/allegro/bigcache/queue" +) + +type onRemoveCallback func(wrappedEntry []byte, reason RemoveReason) + +type cacheShard struct { + hashmap map[uint64]uint32 + entries queue.BytesQueue + lock sync.RWMutex + entryBuffer []byte + onRemove onRemoveCallback + + isVerbose bool + logger Logger + clock clock + lifeWindow uint64 + + stats Stats +} + +func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) { + s.lock.RLock() + itemIndex := s.hashmap[hashedKey] + + if itemIndex == 0 { + s.lock.RUnlock() + s.miss() + return nil, ErrEntryNotFound + } + + wrappedEntry, err := s.entries.Get(int(itemIndex)) + if err != nil { + s.lock.RUnlock() + s.miss() + return nil, err + } + if entryKey := readKeyFromEntry(wrappedEntry); key != entryKey { + if s.isVerbose { + s.logger.Printf("Collision detected. Both %q and %q have the same hash %x", key, entryKey, hashedKey) + } + s.lock.RUnlock() + s.collision() + return nil, ErrEntryNotFound + } + s.lock.RUnlock() + s.hit() + return readEntry(wrappedEntry), nil +} + +func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error { + currentTimestamp := uint64(s.clock.epoch()) + + s.lock.Lock() + + if previousIndex := s.hashmap[hashedKey]; previousIndex != 0 { + if previousEntry, err := s.entries.Get(int(previousIndex)); err == nil { + resetKeyFromEntry(previousEntry) + } + } + + if oldestEntry, err := s.entries.Peek(); err == nil { + s.onEvict(oldestEntry, currentTimestamp, s.removeOldestEntry) + } + + w := wrapEntry(currentTimestamp, hashedKey, key, entry, &s.entryBuffer) + + for { + if index, err := s.entries.Push(w); err == nil { + s.hashmap[hashedKey] = uint32(index) + s.lock.Unlock() + return nil + } + if s.removeOldestEntry(NoSpace) != nil { + s.lock.Unlock() + return fmt.Errorf("entry is bigger than max shard size") + } + } +} + +func (s *cacheShard) del(key string, hashedKey uint64) error { + s.lock.RLock() + itemIndex := s.hashmap[hashedKey] + + if itemIndex == 0 { + s.lock.RUnlock() + s.delmiss() + return ErrEntryNotFound + } + + wrappedEntry, err := s.entries.Get(int(itemIndex)) + if err != nil { + s.lock.RUnlock() + s.delmiss() + return err + } + s.lock.RUnlock() + + s.lock.Lock() + { + delete(s.hashmap, hashedKey) + s.onRemove(wrappedEntry, Deleted) + resetKeyFromEntry(wrappedEntry) + } + s.lock.Unlock() + + s.delhit() + return nil +} + +func (s *cacheShard) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func(reason RemoveReason) error) bool { + oldestTimestamp := readTimestampFromEntry(oldestEntry) + if currentTimestamp-oldestTimestamp > s.lifeWindow { + evict(Expired) + return true + } + return false +} + +func (s *cacheShard) cleanUp(currentTimestamp uint64) { + s.lock.Lock() + for { + if oldestEntry, err := s.entries.Peek(); err != nil { + break + } else if evicted := s.onEvict(oldestEntry, currentTimestamp, s.removeOldestEntry); !evicted { + break + } + } + s.lock.Unlock() +} + +func (s *cacheShard) getOldestEntry() ([]byte, error) { + return s.entries.Peek() +} + +func (s *cacheShard) getEntry(index int) ([]byte, error) { + s.lock.RLock() + entry, err := s.entries.Get(index) + s.lock.RUnlock() + + return entry, err +} + +func (s *cacheShard) copyKeys() (keys []uint32, next int) { + s.lock.RLock() + keys = make([]uint32, len(s.hashmap)) + + for _, index := range s.hashmap { + keys[next] = index + next++ + } + + s.lock.RUnlock() + return keys, next +} + +func (s *cacheShard) removeOldestEntry(reason RemoveReason) error { + oldest, err := s.entries.Pop() + if err == nil { + hash := readHashFromEntry(oldest) + delete(s.hashmap, hash) + s.onRemove(oldest, reason) + return nil + } + return err +} + +func (s *cacheShard) reset(config Config) { + s.lock.Lock() + s.hashmap = make(map[uint64]uint32, config.initialShardSize()) + s.entryBuffer = make([]byte, config.MaxEntrySize+headersSizeInBytes) + s.entries.Reset() + s.lock.Unlock() +} + +func (s *cacheShard) len() int { + s.lock.RLock() + res := len(s.hashmap) + s.lock.RUnlock() + return res +} + +func (s *cacheShard) capacity() int { + s.lock.RLock() + res := s.entries.Capacity() + s.lock.RUnlock() + return res +} + +func (s *cacheShard) getStats() Stats { + var stats = Stats{ + Hits: atomic.LoadInt64(&s.stats.Hits), + Misses: atomic.LoadInt64(&s.stats.Misses), + DelHits: atomic.LoadInt64(&s.stats.DelHits), + DelMisses: atomic.LoadInt64(&s.stats.DelMisses), + Collisions: atomic.LoadInt64(&s.stats.Collisions), + } + return stats +} + +func (s *cacheShard) hit() { + atomic.AddInt64(&s.stats.Hits, 1) +} + +func (s *cacheShard) miss() { + atomic.AddInt64(&s.stats.Misses, 1) +} + +func (s *cacheShard) delhit() { + atomic.AddInt64(&s.stats.DelHits, 1) +} + +func (s *cacheShard) delmiss() { + atomic.AddInt64(&s.stats.DelMisses, 1) +} + +func (s *cacheShard) collision() { + atomic.AddInt64(&s.stats.Collisions, 1) +} + +func initNewShard(config Config, callback onRemoveCallback, clock clock) *cacheShard { + return &cacheShard{ + hashmap: make(map[uint64]uint32, config.initialShardSize()), + entries: *queue.NewBytesQueue(config.initialShardSize()*config.MaxEntrySize, config.maximumShardSize(), config.Verbose), + entryBuffer: make([]byte, config.MaxEntrySize+headersSizeInBytes), + onRemove: callback, + + isVerbose: config.Verbose, + logger: newLogger(config.Logger), + clock: clock, + lifeWindow: uint64(config.LifeWindow.Seconds()), + } +} diff --git a/vendor/github.com/bren2010/proquint/LICENSE.md b/vendor/github.com/bren2010/proquint/LICENSE.md new file mode 100644 index 00000000..e5d49487 --- /dev/null +++ b/vendor/github.com/bren2010/proquint/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2014 Brendan McMillion + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/bren2010/proquint/README.md b/vendor/github.com/bren2010/proquint/README.md new file mode 100644 index 00000000..13e7b0b5 --- /dev/null +++ b/vendor/github.com/bren2010/proquint/README.md @@ -0,0 +1,6 @@ +Proquint +------- + +Golang implementation of [Proquint Pronounceable Identifiers](https://github.com/deoxxa/proquint). + + diff --git a/vendor/github.com/bren2010/proquint/proquint.go b/vendor/github.com/bren2010/proquint/proquint.go new file mode 100644 index 00000000..60e1cf98 --- /dev/null +++ b/vendor/github.com/bren2010/proquint/proquint.go @@ -0,0 +1,123 @@ +/* +Copyright (c) 2014 Brendan McMillion + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +package proquint + +import ( + "bytes" + "strings" + "regexp" +) + +var ( + conse = [...]byte{'b', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', + 'p', 'r', 's', 't', 'v', 'z'} + vowse = [...]byte{'a', 'i', 'o', 'u'} + + consd = map[byte] uint16 { + 'b' : 0, 'd' : 1, 'f' : 2, 'g' : 3, + 'h' : 4, 'j' : 5, 'k' : 6, 'l' : 7, + 'm' : 8, 'n' : 9, 'p' : 10, 'r' : 11, + 's' : 12, 't' : 13, 'v' : 14, 'z' : 15, + } + + vowsd = map[byte] uint16 { + 'a' : 0, 'i' : 1, 'o' : 2, 'u' : 3, + } +) + +/** +* Tests if a given string is a Proquint identifier +* +* @param {string} str The candidate string. +* +* @return {bool} Whether or not it qualifies. +* @return {error} Error +*/ +func IsProquint(str string) (bool, error) { + exp := "^([abdfghijklmnoprstuvz]{5}-)*[abdfghijklmnoprstuvz]{5}$" + ok, err := regexp.MatchString(exp, str) + + return ok, err +} + +/** +* Encodes an arbitrary byte slice into an identifier. +* +* @param {[]byte} buf Slice of bytes to encode. +* +* @return {string} The given byte slice as an identifier. +*/ +func Encode(buf []byte) string { + var out bytes.Buffer + + for i := 0; i < len(buf); i = i + 2 { + var n uint16 = (uint16(buf[i]) * 256) + uint16(buf[i + 1]) + + var ( + c1 = n & 0x0f + v1 = (n >> 4) & 0x03 + c2 = (n >> 6) & 0x0f + v2 = (n >> 10) & 0x03 + c3 = (n >> 12) & 0x0f + ) + + out.WriteByte(conse[c1]) + out.WriteByte(vowse[v1]) + out.WriteByte(conse[c2]) + out.WriteByte(vowse[v2]) + out.WriteByte(conse[c3]) + + if (i + 2) < len(buf) { + out.WriteByte('-') + } + } + + return out.String() +} + +/** +* Decodes an identifier into its corresponding byte slice. +* +* @param {string} str Identifier to convert. +* +* @return {[]byte} The identifier as a byte slice. +*/ +func Decode(str string) []byte { + var ( + out bytes.Buffer + bits []string = strings.Split(str, "-") + ) + + for i := 0; i < len(bits); i++ { + var x uint16 = consd[bits[i][0]] + + (vowsd[bits[i][1]] << 4) + + (consd[bits[i][2]] << 6) + + (vowsd[bits[i][3]] << 10) + + (consd[bits[i][4]] << 12) + + out.WriteByte(byte(x >> 8)) + out.WriteByte(byte(x)) + } + + return out.Bytes() +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/signature.go b/vendor/github.com/btcsuite/btcd/btcec/signature.go new file mode 100644 index 00000000..f1c43774 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/signature.go @@ -0,0 +1,540 @@ +// Copyright (c) 2013-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/hmac" + "crypto/sha256" + "errors" + "fmt" + "hash" + "math/big" +) + +// Errors returned by canonicalPadding. +var ( + errNegativeValue = errors.New("value may be interpreted as negative") + errExcessivelyPaddedValue = errors.New("value is excessively padded") +) + +// Signature is a type representing an ecdsa signature. +type Signature struct { + R *big.Int + S *big.Int +} + +var ( + // Used in RFC6979 implementation when testing the nonce for correctness + one = big.NewInt(1) + + // oneInitializer is used to fill a byte slice with byte 0x01. It is provided + // here to avoid the need to create it multiple times. + oneInitializer = []byte{0x01} +) + +// Serialize returns the ECDSA signature in the more strict DER format. Note +// that the serialized bytes returned do not include the appended hash type +// used in Bitcoin signature scripts. +// +// encoding/asn1 is broken so we hand roll this output: +// +// 0x30 0x02 r 0x02 s +func (sig *Signature) Serialize() []byte { + // low 'S' malleability breaker + sigS := sig.S + if sigS.Cmp(S256().halfOrder) == 1 { + sigS = new(big.Int).Sub(S256().N, sigS) + } + // Ensure the encoded bytes for the r and s values are canonical and + // thus suitable for DER encoding. + rb := canonicalizeInt(sig.R) + sb := canonicalizeInt(sigS) + + // total length of returned signature is 1 byte for each magic and + // length (6 total), plus lengths of r and s + length := 6 + len(rb) + len(sb) + b := make([]byte, length) + + b[0] = 0x30 + b[1] = byte(length - 2) + b[2] = 0x02 + b[3] = byte(len(rb)) + offset := copy(b[4:], rb) + 4 + b[offset] = 0x02 + b[offset+1] = byte(len(sb)) + copy(b[offset+2:], sb) + return b +} + +// Verify calls ecdsa.Verify to verify the signature of hash using the public +// key. It returns true if the signature is valid, false otherwise. +func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool { + return ecdsa.Verify(pubKey.ToECDSA(), hash, sig.R, sig.S) +} + +// IsEqual compares this Signature instance to the one passed, returning true +// if both Signatures are equivalent. A signature is equivalent to another, if +// they both have the same scalar value for R and S. +func (sig *Signature) IsEqual(otherSig *Signature) bool { + return sig.R.Cmp(otherSig.R) == 0 && + sig.S.Cmp(otherSig.S) == 0 +} + +// MinSigLen is the minimum length of a DER encoded signature and is when both R +// and S are 1 byte each. +// 0x30 + <1-byte> + 0x02 + 0x01 + + 0x2 + 0x01 + +const MinSigLen = 8 + +func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) { + // Originally this code used encoding/asn1 in order to parse the + // signature, but a number of problems were found with this approach. + // Despite the fact that signatures are stored as DER, the difference + // between go's idea of a bignum (and that they have sign) doesn't agree + // with the openssl one (where they do not). The above is true as of + // Go 1.1. In the end it was simpler to rewrite the code to explicitly + // understand the format which is this: + // 0x30 <0x02> 0x2 + // . + + signature := &Signature{} + + if len(sigStr) < MinSigLen { + return nil, errors.New("malformed signature: too short") + } + // 0x30 + index := 0 + if sigStr[index] != 0x30 { + return nil, errors.New("malformed signature: no header magic") + } + index++ + // length of remaining message + siglen := sigStr[index] + index++ + + // siglen should be less than the entire message and greater than + // the minimal message size. + if int(siglen+2) > len(sigStr) || int(siglen+2) < MinSigLen { + return nil, errors.New("malformed signature: bad length") + } + // trim the slice we're working on so we only look at what matters. + sigStr = sigStr[:siglen+2] + + // 0x02 + if sigStr[index] != 0x02 { + return nil, + errors.New("malformed signature: no 1st int marker") + } + index++ + + // Length of signature R. + rLen := int(sigStr[index]) + // must be positive, must be able to fit in another 0x2, + // hence the -3. We assume that the length must be at least one byte. + index++ + if rLen <= 0 || rLen > len(sigStr)-index-3 { + return nil, errors.New("malformed signature: bogus R length") + } + + // Then R itself. + rBytes := sigStr[index : index+rLen] + if der { + switch err := canonicalPadding(rBytes); err { + case errNegativeValue: + return nil, errors.New("signature R is negative") + case errExcessivelyPaddedValue: + return nil, errors.New("signature R is excessively padded") + } + } + signature.R = new(big.Int).SetBytes(rBytes) + index += rLen + // 0x02. length already checked in previous if. + if sigStr[index] != 0x02 { + return nil, errors.New("malformed signature: no 2nd int marker") + } + index++ + + // Length of signature S. + sLen := int(sigStr[index]) + index++ + // S should be the rest of the string. + if sLen <= 0 || sLen > len(sigStr)-index { + return nil, errors.New("malformed signature: bogus S length") + } + + // Then S itself. + sBytes := sigStr[index : index+sLen] + if der { + switch err := canonicalPadding(sBytes); err { + case errNegativeValue: + return nil, errors.New("signature S is negative") + case errExcessivelyPaddedValue: + return nil, errors.New("signature S is excessively padded") + } + } + signature.S = new(big.Int).SetBytes(sBytes) + index += sLen + + // sanity check length parsing + if index != len(sigStr) { + return nil, fmt.Errorf("malformed signature: bad final length %v != %v", + index, len(sigStr)) + } + + // Verify also checks this, but we can be more sure that we parsed + // correctly if we verify here too. + // FWIW the ecdsa spec states that R and S must be | 1, N - 1 | + // but crypto/ecdsa only checks for Sign != 0. Mirror that. + if signature.R.Sign() != 1 { + return nil, errors.New("signature R isn't 1 or more") + } + if signature.S.Sign() != 1 { + return nil, errors.New("signature S isn't 1 or more") + } + if signature.R.Cmp(curve.Params().N) >= 0 { + return nil, errors.New("signature R is >= curve.N") + } + if signature.S.Cmp(curve.Params().N) >= 0 { + return nil, errors.New("signature S is >= curve.N") + } + + return signature, nil +} + +// ParseSignature parses a signature in BER format for the curve type `curve' +// into a Signature type, perfoming some basic sanity checks. If parsing +// according to the more strict DER format is needed, use ParseDERSignature. +func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) { + return parseSig(sigStr, curve, false) +} + +// ParseDERSignature parses a signature in DER format for the curve type +// `curve` into a Signature type. If parsing according to the less strict +// BER format is needed, use ParseSignature. +func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) { + return parseSig(sigStr, curve, true) +} + +// canonicalizeInt returns the bytes for the passed big integer adjusted as +// necessary to ensure that a big-endian encoded integer can't possibly be +// misinterpreted as a negative number. This can happen when the most +// significant bit is set, so it is padded by a leading zero byte in this case. +// Also, the returned bytes will have at least a single byte when the passed +// value is 0. This is required for DER encoding. +func canonicalizeInt(val *big.Int) []byte { + b := val.Bytes() + if len(b) == 0 { + b = []byte{0x00} + } + if b[0]&0x80 != 0 { + paddedBytes := make([]byte, len(b)+1) + copy(paddedBytes[1:], b) + b = paddedBytes + } + return b +} + +// canonicalPadding checks whether a big-endian encoded integer could +// possibly be misinterpreted as a negative number (even though OpenSSL +// treats all numbers as unsigned), or if there is any unnecessary +// leading zero padding. +func canonicalPadding(b []byte) error { + switch { + case b[0]&0x80 == 0x80: + return errNegativeValue + case len(b) > 1 && b[0] == 0x00 && b[1]&0x80 != 0x80: + return errExcessivelyPaddedValue + default: + return nil + } +} + +// hashToInt converts a hash value to an integer. There is some disagreement +// about how this is done. [NSA] suggests that this is done in the obvious +// manner, but [SECG] truncates the hash to the bit-length of the curve order +// first. We follow [SECG] because that's what OpenSSL does. Additionally, +// OpenSSL right shifts excess bits from the number if the hash is too large +// and we mirror that too. +// This is borrowed from crypto/ecdsa. +func hashToInt(hash []byte, c elliptic.Curve) *big.Int { + orderBits := c.Params().N.BitLen() + orderBytes := (orderBits + 7) / 8 + if len(hash) > orderBytes { + hash = hash[:orderBytes] + } + + ret := new(big.Int).SetBytes(hash) + excess := len(hash)*8 - orderBits + if excess > 0 { + ret.Rsh(ret, uint(excess)) + } + return ret +} + +// recoverKeyFromSignature recovers a public key from the signature "sig" on the +// given message hash "msg". Based on the algorithm found in section 5.1.5 of +// SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details +// in the inner loop in Step 1. The counter provided is actually the j parameter +// of the loop * 2 - on the first iteration of j we do the R case, else the -R +// case in step 1.6. This counter is used in the bitcoin compressed signature +// format and thus we match bitcoind's behaviour here. +func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []byte, + iter int, doChecks bool) (*PublicKey, error) { + // 1.1 x = (n * i) + r + Rx := new(big.Int).Mul(curve.Params().N, + new(big.Int).SetInt64(int64(iter/2))) + Rx.Add(Rx, sig.R) + if Rx.Cmp(curve.Params().P) != -1 { + return nil, errors.New("calculated Rx is larger than curve P") + } + + // convert 02 to point R. (step 1.2 and 1.3). If we are on an odd + // iteration then 1.6 will be done with -R, so we calculate the other + // term when uncompressing the point. + Ry, err := decompressPoint(curve, Rx, iter%2 == 1) + if err != nil { + return nil, err + } + + // 1.4 Check n*R is point at infinity + if doChecks { + nRx, nRy := curve.ScalarMult(Rx, Ry, curve.Params().N.Bytes()) + if nRx.Sign() != 0 || nRy.Sign() != 0 { + return nil, errors.New("n*R does not equal the point at infinity") + } + } + + // 1.5 calculate e from message using the same algorithm as ecdsa + // signature calculation. + e := hashToInt(msg, curve) + + // Step 1.6.1: + // We calculate the two terms sR and eG separately multiplied by the + // inverse of r (from the signature). We then add them to calculate + // Q = r^-1(sR-eG) + invr := new(big.Int).ModInverse(sig.R, curve.Params().N) + + // first term. + invrS := new(big.Int).Mul(invr, sig.S) + invrS.Mod(invrS, curve.Params().N) + sRx, sRy := curve.ScalarMult(Rx, Ry, invrS.Bytes()) + + // second term. + e.Neg(e) + e.Mod(e, curve.Params().N) + e.Mul(e, invr) + e.Mod(e, curve.Params().N) + minuseGx, minuseGy := curve.ScalarBaseMult(e.Bytes()) + + // TODO: this would be faster if we did a mult and add in one + // step to prevent the jacobian conversion back and forth. + Qx, Qy := curve.Add(sRx, sRy, minuseGx, minuseGy) + + return &PublicKey{ + Curve: curve, + X: Qx, + Y: Qy, + }, nil +} + +// SignCompact produces a compact signature of the data in hash with the given +// private key on the given koblitz curve. The isCompressed parameter should +// be used to detail if the given signature should reference a compressed +// public key or not. If successful the bytes of the compact signature will be +// returned in the format: +// <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R> +// where the R and S parameters are padde up to the bitlengh of the curve. +func SignCompact(curve *KoblitzCurve, key *PrivateKey, + hash []byte, isCompressedKey bool) ([]byte, error) { + sig, err := key.Sign(hash) + if err != nil { + return nil, err + } + + // bitcoind checks the bit length of R and S here. The ecdsa signature + // algorithm returns R and S mod N therefore they will be the bitsize of + // the curve, and thus correctly sized. + for i := 0; i < (curve.H+1)*2; i++ { + pk, err := recoverKeyFromSignature(curve, sig, hash, i, true) + if err == nil && pk.X.Cmp(key.X) == 0 && pk.Y.Cmp(key.Y) == 0 { + result := make([]byte, 1, 2*curve.byteSize+1) + result[0] = 27 + byte(i) + if isCompressedKey { + result[0] += 4 + } + // Not sure this needs rounding but safer to do so. + curvelen := (curve.BitSize + 7) / 8 + + // Pad R and S to curvelen if needed. + bytelen := (sig.R.BitLen() + 7) / 8 + if bytelen < curvelen { + result = append(result, + make([]byte, curvelen-bytelen)...) + } + result = append(result, sig.R.Bytes()...) + + bytelen = (sig.S.BitLen() + 7) / 8 + if bytelen < curvelen { + result = append(result, + make([]byte, curvelen-bytelen)...) + } + result = append(result, sig.S.Bytes()...) + + return result, nil + } + } + + return nil, errors.New("no valid solution for pubkey found") +} + +// RecoverCompact verifies the compact signature "signature" of "hash" for the +// Koblitz curve in "curve". If the signature matches then the recovered public +// key will be returned as well as a boolen if the original key was compressed +// or not, else an error will be returned. +func RecoverCompact(curve *KoblitzCurve, signature, + hash []byte) (*PublicKey, bool, error) { + bitlen := (curve.BitSize + 7) / 8 + if len(signature) != 1+bitlen*2 { + return nil, false, errors.New("invalid compact signature size") + } + + iteration := int((signature[0] - 27) & ^byte(4)) + + // format is
+ sig := &Signature{ + R: new(big.Int).SetBytes(signature[1 : bitlen+1]), + S: new(big.Int).SetBytes(signature[bitlen+1:]), + } + // The iteration used here was encoded + key, err := recoverKeyFromSignature(curve, sig, hash, iteration, false) + if err != nil { + return nil, false, err + } + + return key, ((signature[0] - 27) & 4) == 4, nil +} + +// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979 and BIP 62. +func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) { + + privkey := privateKey.ToECDSA() + N := S256().N + halfOrder := S256().halfOrder + k := nonceRFC6979(privkey.D, hash) + inv := new(big.Int).ModInverse(k, N) + r, _ := privkey.Curve.ScalarBaseMult(k.Bytes()) + r.Mod(r, N) + + if r.Sign() == 0 { + return nil, errors.New("calculated R is zero") + } + + e := hashToInt(hash, privkey.Curve) + s := new(big.Int).Mul(privkey.D, r) + s.Add(s, e) + s.Mul(s, inv) + s.Mod(s, N) + + if s.Cmp(halfOrder) == 1 { + s.Sub(N, s) + } + if s.Sign() == 0 { + return nil, errors.New("calculated S is zero") + } + return &Signature{R: r, S: s}, nil +} + +// nonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to RFC 6979. +// It takes a 32-byte hash as an input and returns 32-byte nonce to be used in ECDSA algorithm. +func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int { + + curve := S256() + q := curve.Params().N + x := privkey + alg := sha256.New + + qlen := q.BitLen() + holen := alg().Size() + rolen := (qlen + 7) >> 3 + bx := append(int2octets(x, rolen), bits2octets(hash, curve, rolen)...) + + // Step B + v := bytes.Repeat(oneInitializer, holen) + + // Step C (Go zeroes the all allocated memory) + k := make([]byte, holen) + + // Step D + k = mac(alg, k, append(append(v, 0x00), bx...)) + + // Step E + v = mac(alg, k, v) + + // Step F + k = mac(alg, k, append(append(v, 0x01), bx...)) + + // Step G + v = mac(alg, k, v) + + // Step H + for { + // Step H1 + var t []byte + + // Step H2 + for len(t)*8 < qlen { + v = mac(alg, k, v) + t = append(t, v...) + } + + // Step H3 + secret := hashToInt(t, curve) + if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 { + return secret + } + k = mac(alg, k, append(v, 0x00)) + v = mac(alg, k, v) + } +} + +// mac returns an HMAC of the given key and message. +func mac(alg func() hash.Hash, k, m []byte) []byte { + h := hmac.New(alg, k) + h.Write(m) + return h.Sum(nil) +} + +// https://tools.ietf.org/html/rfc6979#section-2.3.3 +func int2octets(v *big.Int, rolen int) []byte { + out := v.Bytes() + + // left pad with zeros if it's too short + if len(out) < rolen { + out2 := make([]byte, rolen) + copy(out2[rolen-len(out):], out) + return out2 + } + + // drop most significant bytes if it's too long + if len(out) > rolen { + out2 := make([]byte, rolen) + copy(out2, out[len(out)-rolen:]) + return out2 + } + + return out +} + +// https://tools.ietf.org/html/rfc6979#section-2.3.4 +func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte { + z1 := hashToInt(in, curve) + z2 := new(big.Int).Sub(z1, curve.Params().N) + if z2.Sign() < 0 { + return int2octets(z1, rolen) + } + return int2octets(z2, rolen) +} diff --git a/vendor/github.com/cenkalti/backoff/.gitignore b/vendor/github.com/cenkalti/backoff/.gitignore new file mode 100644 index 00000000..00268614 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/cenkalti/backoff/.travis.yml b/vendor/github.com/cenkalti/backoff/.travis.yml new file mode 100644 index 00000000..47a6a46e --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.7 + - 1.x + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/cenkalti/backoff/LICENSE b/vendor/github.com/cenkalti/backoff/LICENSE new file mode 100644 index 00000000..89b81799 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cenkalti/backoff/README.md b/vendor/github.com/cenkalti/backoff/README.md new file mode 100644 index 00000000..55ebc98f --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/README.md @@ -0,0 +1,30 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +See https://godoc.org/github.com/cenkalti/backoff#pkg-examples + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://godoc.org/github.com/cenkalti/backoff +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png +[travis]: https://travis-ci.org/cenkalti/backoff +[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master +[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master +[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master + +[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ diff --git a/vendor/github.com/cenkalti/backoff/backoff.go b/vendor/github.com/cenkalti/backoff/backoff.go new file mode 100644 index 00000000..3676ee40 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // or backoff. Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/context.go b/vendor/github.com/cenkalti/backoff/context.go new file mode 100644 index 00000000..7706faa2 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/context.go @@ -0,0 +1,63 @@ +package backoff + +import ( + "context" + "time" +) + +// BackOffContext is a backoff policy that stops retrying after the context +// is canceled. +type BackOffContext interface { + BackOff + Context() context.Context +} + +type backOffContext struct { + BackOff + ctx context.Context +} + +// WithContext returns a BackOffContext with context ctx +// +// ctx must not be nil +func WithContext(b BackOff, ctx context.Context) BackOffContext { + if ctx == nil { + panic("nil context") + } + + if b, ok := b.(*backOffContext); ok { + return &backOffContext{ + BackOff: b.BackOff, + ctx: ctx, + } + } + + return &backOffContext{ + BackOff: b, + ctx: ctx, + } +} + +func ensureContext(b BackOff) BackOffContext { + if cb, ok := b.(BackOffContext); ok { + return cb + } + return WithContext(b, context.Background()) +} + +func (b *backOffContext) Context() context.Context { + return b.ctx +} + +func (b *backOffContext) NextBackOff() time.Duration { + select { + case <-b.ctx.Done(): + return Stop + default: + } + next := b.BackOff.NextBackOff() + if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next { + return Stop + } + return next +} diff --git a/vendor/github.com/cenkalti/backoff/exponential.go b/vendor/github.com/cenkalti/backoff/exponential.go new file mode 100644 index 00000000..a031a659 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/exponential.go @@ -0,0 +1,153 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. + +The elapsed time can be reset by calling Reset(). + +Example: Given the following default arguments, for 10 tries the sequence will be, +and assuming we go over the MaxElapsedTime on the 10th try: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff stops. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + b := &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Clock: SystemClock, + } + b.Reset() + return b +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next backoff interval using the formula: +// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { + return Stop + } + defer b.incrementCurrentInterval() + return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). It is +// safe to call even while the backoff policy is used by a running +// ticker. +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/go.mod b/vendor/github.com/cenkalti/backoff/go.mod new file mode 100644 index 00000000..479e62ad --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/go.mod @@ -0,0 +1,3 @@ +module github.com/cenkalti/backoff/v3 + +go 1.12 diff --git a/vendor/github.com/cenkalti/backoff/retry.go b/vendor/github.com/cenkalti/backoff/retry.go new file mode 100644 index 00000000..e936a506 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/retry.go @@ -0,0 +1,82 @@ +package backoff + +import "time" + +// An Operation is executing by Retry() or RetryNotify(). +// The operation will be retried using a backoff policy if it returns an error. +type Operation func() error + +// Notify is a notify-on-error function. It receives an operation error and +// backoff delay if the operation failed (with an error). +// +// NOTE that if the backoff policy stated to stop retrying, +// the notify function isn't called. +type Notify func(error, time.Duration) + +// Retry the operation o until it does not return error or BackOff stops. +// o is guaranteed to be run at least once. +// +// If o returns a *PermanentError, the operation is not retried, and the +// wrapped error is returned. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } + +// RetryNotify calls notify function with the error and wait duration +// for each failed attempt before sleep. +func RetryNotify(operation Operation, b BackOff, notify Notify) error { + var err error + var next time.Duration + var t *time.Timer + + cb := ensureContext(b) + + b.Reset() + for { + if err = operation(); err == nil { + return nil + } + + if permanent, ok := err.(*PermanentError); ok { + return permanent.Err + } + + if next = cb.NextBackOff(); next == Stop { + return err + } + + if notify != nil { + notify(err, next) + } + + if t == nil { + t = time.NewTimer(next) + defer t.Stop() + } else { + t.Reset(next) + } + + select { + case <-cb.Context().Done(): + return err + case <-t.C: + } + } +} + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) *PermanentError { + return &PermanentError{ + Err: err, + } +} diff --git a/vendor/github.com/cenkalti/backoff/ticker.go b/vendor/github.com/cenkalti/backoff/ticker.go new file mode 100644 index 00000000..e41084b0 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/ticker.go @@ -0,0 +1,82 @@ +package backoff + +import ( + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOffContext + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: ensureContext(b), + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + case <-t.b.Context().Done(): + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + return time.After(next) +} diff --git a/vendor/github.com/cenkalti/backoff/tries.go b/vendor/github.com/cenkalti/backoff/tries.go new file mode 100644 index 00000000..cfeefd9b --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/tries.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +/* +WithMaxRetries creates a wrapper around another BackOff, which will +return Stop if NextBackOff() has been called too many times since +the last time Reset() was called + +Note: Implementation is not thread-safe. +*/ +func WithMaxRetries(b BackOff, max uint64) BackOff { + return &backOffTries{delegate: b, maxTries: max} +} + +type backOffTries struct { + delegate BackOff + maxTries uint64 + numTries uint64 +} + +func (b *backOffTries) NextBackOff() time.Duration { + if b.maxTries > 0 { + if b.maxTries <= b.numTries { + return Stop + } + b.numTries++ + } + return b.delegate.NextBackOff() +} + +func (b *backOffTries) Reset() { + b.numTries = 0 + b.delegate.Reset() +} diff --git a/vendor/github.com/cheekybits/genny/LICENSE b/vendor/github.com/cheekybits/genny/LICENSE new file mode 100644 index 00000000..519d7f22 --- /dev/null +++ b/vendor/github.com/cheekybits/genny/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 cheekybits + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/cheekybits/genny/generic/doc.go b/vendor/github.com/cheekybits/genny/generic/doc.go new file mode 100644 index 00000000..3bd6c869 --- /dev/null +++ b/vendor/github.com/cheekybits/genny/generic/doc.go @@ -0,0 +1,2 @@ +// Package generic contains the generic marker types. +package generic diff --git a/vendor/github.com/cheekybits/genny/generic/generic.go b/vendor/github.com/cheekybits/genny/generic/generic.go new file mode 100644 index 00000000..04a2306c --- /dev/null +++ b/vendor/github.com/cheekybits/genny/generic/generic.go @@ -0,0 +1,13 @@ +package generic + +// Type is the placeholder type that indicates a generic value. +// When genny is executed, variables of this type will be replaced with +// references to the specific types. +// var GenericType generic.Type +type Type interface{} + +// Number is the placehoder type that indiccates a generic numerical value. +// When genny is executed, variables of this type will be replaced with +// references to the specific types. +// var GenericType generic.Number +type Number float64 diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-semver/NOTICE b/vendor/github.com/coreos/go-semver/NOTICE new file mode 100644 index 00000000..23a0ada2 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go new file mode 100644 index 00000000..76cf4852 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -0,0 +1,296 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Semantic Versions http://semver.org +package semver + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +type Version struct { + Major int64 + Minor int64 + Patch int64 + PreRelease PreRelease + Metadata string +} + +type PreRelease string + +func splitOff(input *string, delim string) (val string) { + parts := strings.SplitN(*input, delim, 2) + + if len(parts) == 2 { + *input = parts[0] + val = parts[1] + } + + return val +} + +func New(version string) *Version { + return Must(NewVersion(version)) +} + +func NewVersion(version string) (*Version, error) { + v := Version{} + + if err := v.Set(version); err != nil { + return nil, err + } + + return &v, nil +} + +// Must is a helper for wrapping NewVersion and will panic if err is not nil. +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + return v +} + +// Set parses and updates v from the given version string. Implements flag.Value +func (v *Version) Set(version string) error { + metadata := splitOff(&version, "+") + preRelease := PreRelease(splitOff(&version, "-")) + dotParts := strings.SplitN(version, ".", 3) + + if len(dotParts) != 3 { + return fmt.Errorf("%s is not in dotted-tri format", version) + } + + if err := validateIdentifier(string(preRelease)); err != nil { + return fmt.Errorf("failed to validate pre-release: %v", err) + } + + if err := validateIdentifier(metadata); err != nil { + return fmt.Errorf("failed to validate metadata: %v", err) + } + + parsed := make([]int64, 3, 3) + + for i, v := range dotParts[:3] { + val, err := strconv.ParseInt(v, 10, 64) + parsed[i] = val + if err != nil { + return err + } + } + + v.Metadata = metadata + v.PreRelease = preRelease + v.Major = parsed[0] + v.Minor = parsed[1] + v.Patch = parsed[2] + return nil +} + +func (v Version) String() string { + var buffer bytes.Buffer + + fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) + + if v.PreRelease != "" { + fmt.Fprintf(&buffer, "-%s", v.PreRelease) + } + + if v.Metadata != "" { + fmt.Fprintf(&buffer, "+%s", v.Metadata) + } + + return buffer.String() +} + +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + return v.Set(data) +} + +func (v Version) MarshalJSON() ([]byte, error) { + return []byte(`"` + v.String() + `"`), nil +} + +func (v *Version) UnmarshalJSON(data []byte) error { + l := len(data) + if l == 0 || string(data) == `""` { + return nil + } + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("invalid semver string") + } + return v.Set(string(data[1 : l-1])) +} + +// Compare tests if v is less than, equal to, or greater than versionB, +// returning -1, 0, or +1 respectively. +func (v Version) Compare(versionB Version) int { + if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { + return cmp + } + return preReleaseCompare(v, versionB) +} + +// Equal tests if v is equal to versionB. +func (v Version) Equal(versionB Version) bool { + return v.Compare(versionB) == 0 +} + +// LessThan tests if v is less than versionB. +func (v Version) LessThan(versionB Version) bool { + return v.Compare(versionB) < 0 +} + +// Slice converts the comparable parts of the semver into a slice of integers. +func (v Version) Slice() []int64 { + return []int64{v.Major, v.Minor, v.Patch} +} + +func (p PreRelease) Slice() []string { + preRelease := string(p) + return strings.Split(preRelease, ".") +} + +func preReleaseCompare(versionA Version, versionB Version) int { + a := versionA.PreRelease + b := versionB.PreRelease + + /* Handle the case where if two versions are otherwise equal it is the + * one without a PreRelease that is greater */ + if len(a) == 0 && (len(b) > 0) { + return 1 + } else if len(b) == 0 && (len(a) > 0) { + return -1 + } + + // If there is a prerelease, check and compare each part. + return recursivePreReleaseCompare(a.Slice(), b.Slice()) +} + +func recursiveCompare(versionA []int64, versionB []int64) int { + if len(versionA) == 0 { + return 0 + } + + a := versionA[0] + b := versionB[0] + + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursiveCompare(versionA[1:], versionB[1:]) +} + +func recursivePreReleaseCompare(versionA []string, versionB []string) int { + // A larger set of pre-release fields has a higher precedence than a smaller set, + // if all of the preceding identifiers are equal. + if len(versionA) == 0 { + if len(versionB) > 0 { + return -1 + } + return 0 + } else if len(versionB) == 0 { + // We're longer than versionB so return 1. + return 1 + } + + a := versionA[0] + b := versionB[0] + + aInt := false + bInt := false + + aI, err := strconv.Atoi(versionA[0]) + if err == nil { + aInt = true + } + + bI, err := strconv.Atoi(versionB[0]) + if err == nil { + bInt = true + } + + // Numeric identifiers always have lower precedence than non-numeric identifiers. + if aInt && !bInt { + return -1 + } else if !aInt && bInt { + return 1 + } + + // Handle Integer Comparison + if aInt && bInt { + if aI > bI { + return 1 + } else if aI < bI { + return -1 + } + } + + // Handle String Comparison + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursivePreReleaseCompare(versionA[1:], versionB[1:]) +} + +// BumpMajor increments the Major field by 1 and resets all other fields to their default values +func (v *Version) BumpMajor() { + v.Major += 1 + v.Minor = 0 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpMinor increments the Minor field by 1 and resets all other fields to their default values +func (v *Version) BumpMinor() { + v.Minor += 1 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpPatch increments the Patch field by 1 and resets all other fields to their default values +func (v *Version) BumpPatch() { + v.Patch += 1 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// validateIdentifier makes sure the provided identifier satisfies semver spec +func validateIdentifier(id string) error { + if id != "" && !reIdentifier.MatchString(id) { + return fmt.Errorf("%s is not a valid semver identifier", id) + } + return nil +} + +// reIdentifier is a regular expression used to check that pre-release and metadata +// identifiers satisfy the spec requirements +var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go new file mode 100644 index 00000000..e256b41a --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -0,0 +1,38 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semver + +import ( + "sort" +) + +type Versions []*Version + +func (s Versions) Len() int { + return len(s) +} + +func (s Versions) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s Versions) Less(i, j int) bool { + return s[i].LessThan(*s[j]) +} + +// Sort sorts the given slice of Version +func Sort(versions []*Version) { + sort.Sort(Versions(versions)) +} diff --git a/vendor/github.com/cskr/pubsub/LICENSE b/vendor/github.com/cskr/pubsub/LICENSE new file mode 100644 index 00000000..ae195b47 --- /dev/null +++ b/vendor/github.com/cskr/pubsub/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013, Chandra Sekar S +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. 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. + +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 HOLDER 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. diff --git a/vendor/github.com/cskr/pubsub/README.md b/vendor/github.com/cskr/pubsub/README.md new file mode 100644 index 00000000..8ec08386 --- /dev/null +++ b/vendor/github.com/cskr/pubsub/README.md @@ -0,0 +1,13 @@ +[![GoDoc](https://godoc.org/github.com/cskr/pubsub?status.svg)](https://godoc.org/github.com/cskr/pubsub) + +Package pubsub implements a simple multi-topic pub-sub library. + +Install pubsub with, + + go get github.com/cskr/pubsub + +This repository is a go module and contains tagged releases. Please pin a +version for production use. + +Use of this module is governed by a BSD-style license that can be found in the +[LICENSE](LICENSE) file. diff --git a/vendor/github.com/cskr/pubsub/go.mod b/vendor/github.com/cskr/pubsub/go.mod new file mode 100644 index 00000000..18dbec9b --- /dev/null +++ b/vendor/github.com/cskr/pubsub/go.mod @@ -0,0 +1,3 @@ +module github.com/cskr/pubsub + +go 1.12 diff --git a/vendor/github.com/cskr/pubsub/pubsub.go b/vendor/github.com/cskr/pubsub/pubsub.go new file mode 100644 index 00000000..352ef6ff --- /dev/null +++ b/vendor/github.com/cskr/pubsub/pubsub.go @@ -0,0 +1,267 @@ +// Copyright 2013, Chandra Sekar S. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pubsub implements a simple multi-topic pub-sub +// library. +// +// Topics must be strings and messages of any type can be +// published. A topic can have any number of subcribers and +// all of them receive messages published on the topic. +package pubsub + +type operation int + +const ( + sub operation = iota + subOnce + subOnceEach + pub + tryPub + unsub + unsubAll + closeTopic + shutdown +) + +// PubSub is a collection of topics. +type PubSub struct { + cmdChan chan cmd + capacity int +} + +type cmd struct { + op operation + topics []string + ch chan interface{} + msg interface{} +} + +// New creates a new PubSub and starts a goroutine for handling operations. +// The capacity of the channels created by Sub and SubOnce will be as specified. +func New(capacity int) *PubSub { + ps := &PubSub{make(chan cmd), capacity} + go ps.start() + return ps +} + +// Sub returns a channel on which messages published on any of +// the specified topics can be received. +func (ps *PubSub) Sub(topics ...string) chan interface{} { + return ps.sub(sub, topics...) +} + +// SubOnce is similar to Sub, but only the first message published, after subscription, +// on any of the specified topics can be received. +func (ps *PubSub) SubOnce(topics ...string) chan interface{} { + return ps.sub(subOnce, topics...) +} + +// SubOnceEach returns a channel on which callers receive, at most, one message +// for each topic. +func (ps *PubSub) SubOnceEach(topics ...string) chan interface{} { + return ps.sub(subOnceEach, topics...) +} + +func (ps *PubSub) sub(op operation, topics ...string) chan interface{} { + ch := make(chan interface{}, ps.capacity) + ps.cmdChan <- cmd{op: op, topics: topics, ch: ch} + return ch +} + +// AddSub adds subscriptions to an existing channel. +func (ps *PubSub) AddSub(ch chan interface{}, topics ...string) { + ps.cmdChan <- cmd{op: sub, topics: topics, ch: ch} +} + +// AddSubOnceEach adds subscriptions to an existing channel with SubOnceEach +// behavior. +func (ps *PubSub) AddSubOnceEach(ch chan interface{}, topics ...string) { + ps.cmdChan <- cmd{op: subOnceEach, topics: topics, ch: ch} +} + +// Pub publishes the given message to all subscribers of +// the specified topics. +func (ps *PubSub) Pub(msg interface{}, topics ...string) { + ps.cmdChan <- cmd{op: pub, topics: topics, msg: msg} +} + +// TryPub publishes the given message to all subscribers of +// the specified topics if the topic has buffer space. +func (ps *PubSub) TryPub(msg interface{}, topics ...string) { + ps.cmdChan <- cmd{op: tryPub, topics: topics, msg: msg} +} + +// Unsub unsubscribes the given channel from the specified +// topics. If no topic is specified, it is unsubscribed +// from all topics. +// +// Unsub must be called from a goroutine that is different from the subscriber. +// The subscriber must consume messages from the channel until it reaches the +// end. Not doing so can result in a deadlock. +func (ps *PubSub) Unsub(ch chan interface{}, topics ...string) { + if len(topics) == 0 { + ps.cmdChan <- cmd{op: unsubAll, ch: ch} + return + } + + ps.cmdChan <- cmd{op: unsub, topics: topics, ch: ch} +} + +// Close closes all channels currently subscribed to the specified topics. +// If a channel is subscribed to multiple topics, some of which is +// not specified, it is not closed. +func (ps *PubSub) Close(topics ...string) { + ps.cmdChan <- cmd{op: closeTopic, topics: topics} +} + +// Shutdown closes all subscribed channels and terminates the goroutine. +func (ps *PubSub) Shutdown() { + ps.cmdChan <- cmd{op: shutdown} +} + +func (ps *PubSub) start() { + reg := registry{ + topics: make(map[string]map[chan interface{}]subType), + revTopics: make(map[chan interface{}]map[string]bool), + } + +loop: + for cmd := range ps.cmdChan { + if cmd.topics == nil { + switch cmd.op { + case unsubAll: + reg.removeChannel(cmd.ch) + + case shutdown: + break loop + } + + continue loop + } + + for _, topic := range cmd.topics { + switch cmd.op { + case sub: + reg.add(topic, cmd.ch, normal) + + case subOnce: + reg.add(topic, cmd.ch, onceAny) + + case subOnceEach: + reg.add(topic, cmd.ch, onceEach) + + case tryPub: + reg.sendNoWait(topic, cmd.msg) + + case pub: + reg.send(topic, cmd.msg) + + case unsub: + reg.remove(topic, cmd.ch) + + case closeTopic: + reg.removeTopic(topic) + } + } + } + + for topic, chans := range reg.topics { + for ch := range chans { + reg.remove(topic, ch) + } + } +} + +// registry maintains the current subscription state. It's not +// safe to access a registry from multiple goroutines simultaneously. +type registry struct { + topics map[string]map[chan interface{}]subType + revTopics map[chan interface{}]map[string]bool +} + +type subType int + +const ( + onceAny subType = iota + onceEach + normal +) + +func (reg *registry) add(topic string, ch chan interface{}, st subType) { + if reg.topics[topic] == nil { + reg.topics[topic] = make(map[chan interface{}]subType) + } + reg.topics[topic][ch] = st + + if reg.revTopics[ch] == nil { + reg.revTopics[ch] = make(map[string]bool) + } + reg.revTopics[ch][topic] = true +} + +func (reg *registry) send(topic string, msg interface{}) { + for ch, st := range reg.topics[topic] { + ch <- msg + switch st { + case onceAny: + for topic := range reg.revTopics[ch] { + reg.remove(topic, ch) + } + case onceEach: + reg.remove(topic, ch) + } + } +} + +func (reg *registry) sendNoWait(topic string, msg interface{}) { + for ch, st := range reg.topics[topic] { + select { + case ch <- msg: + switch st { + case onceAny: + for topic := range reg.revTopics[ch] { + reg.remove(topic, ch) + } + case onceEach: + reg.remove(topic, ch) + } + default: + } + + } +} + +func (reg *registry) removeTopic(topic string) { + for ch := range reg.topics[topic] { + reg.remove(topic, ch) + } +} + +func (reg *registry) removeChannel(ch chan interface{}) { + for topic := range reg.revTopics[ch] { + reg.remove(topic, ch) + } +} + +func (reg *registry) remove(topic string, ch chan interface{}) { + if _, ok := reg.topics[topic]; !ok { + return + } + + if _, ok := reg.topics[topic][ch]; !ok { + return + } + + delete(reg.topics[topic], ch) + delete(reg.revTopics[ch], topic) + + if len(reg.topics[topic]) == 0 { + delete(reg.topics, topic) + } + + if len(reg.revTopics[ch]) == 0 { + close(ch) + delete(reg.revTopics, ch) + } +} diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE new file mode 100644 index 00000000..bc52e96f --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go new file mode 100644 index 00000000..79299478 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go @@ -0,0 +1,145 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is not running on Google App Engine, compiled by GopherJS, and +// "-tags safe" is not added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// Go versions prior to 1.4 are disabled because they use a different layout +// for interfaces which make the implementation of unsafeReflectValue more complex. +// +build !js,!appengine,!safe,!disableunsafe,go1.4 + +package spew + +import ( + "reflect" + "unsafe" +) + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = false + + // ptrSize is the size of a pointer on the current arch. + ptrSize = unsafe.Sizeof((*byte)(nil)) +) + +type flag uintptr + +var ( + // flagRO indicates whether the value field of a reflect.Value + // is read-only. + flagRO flag + + // flagAddr indicates whether the address of the reflect.Value's + // value may be taken. + flagAddr flag +) + +// flagKindMask holds the bits that make up the kind +// part of the flags field. In all the supported versions, +// it is in the lower 5 bits. +const flagKindMask = flag(0x1f) + +// Different versions of Go have used different +// bit layouts for the flags type. This table +// records the known combinations. +var okFlags = []struct { + ro, addr flag +}{{ + // From Go 1.4 to 1.5 + ro: 1 << 5, + addr: 1 << 7, +}, { + // Up to Go tip. + ro: 1<<5 | 1<<6, + addr: 1 << 8, +}} + +var flagValOffset = func() uintptr { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + return field.Offset +}() + +// flagField returns a pointer to the flag field of a reflect.Value. +func flagField(v *reflect.Value) *flag { + return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) +} + +// unsafeReflectValue converts the passed reflect.Value into a one that bypasses +// the typical safety restrictions preventing access to unaddressable and +// unexported data. It works by digging the raw pointer to the underlying +// value out of the protected value and generating a new unprotected (unsafe) +// reflect.Value to it. +// +// This allows us to check for implementations of the Stringer and error +// interfaces to be used for pretty printing ordinarily unaddressable and +// inaccessible values such as unexported struct fields. +func unsafeReflectValue(v reflect.Value) reflect.Value { + if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { + return v + } + flagFieldPtr := flagField(&v) + *flagFieldPtr &^= flagRO + *flagFieldPtr |= flagAddr + return v +} + +// Sanity checks against future reflect package changes +// to the type or semantics of the Value.flag field. +func init() { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { + panic("reflect.Value flag field has changed kind") + } + type t0 int + var t struct { + A t0 + // t0 will have flagEmbedRO set. + t0 + // a will have flagStickyRO set + a t0 + } + vA := reflect.ValueOf(t).FieldByName("A") + va := reflect.ValueOf(t).FieldByName("a") + vt0 := reflect.ValueOf(t).FieldByName("t0") + + // Infer flagRO from the difference between the flags + // for the (otherwise identical) fields in t. + flagPublic := *flagField(&vA) + flagWithRO := *flagField(&va) | *flagField(&vt0) + flagRO = flagPublic ^ flagWithRO + + // Infer flagAddr from the difference between a value + // taken from a pointer and not. + vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") + flagNoPtr := *flagField(&vA) + flagPtr := *flagField(&vPtrA) + flagAddr = flagNoPtr ^ flagPtr + + // Check that the inferred flags tally with one of the known versions. + for _, f := range okFlags { + if flagRO == f.ro && flagAddr == f.addr { + return + } + } + panic("reflect.Value read-only flag has changed semantics") +} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go new file mode 100644 index 00000000..205c28d6 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go @@ -0,0 +1,38 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is running on Google App Engine, compiled by GopherJS, or +// "-tags safe" is added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// +build js appengine safe disableunsafe !go1.4 + +package spew + +import "reflect" + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = true +) + +// unsafeReflectValue typically converts the passed reflect.Value into a one +// that bypasses the typical safety restrictions preventing access to +// unaddressable and unexported data. However, doing this relies on access to +// the unsafe package. This is a stub version which simply returns the passed +// reflect.Value when the unsafe package is not available. +func unsafeReflectValue(v reflect.Value) reflect.Value { + return v +} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go new file mode 100644 index 00000000..1be8ce94 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/common.go @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "reflect" + "sort" + "strconv" +) + +// Some constants in the form of bytes to avoid string overhead. This mirrors +// the technique used in the fmt package. +var ( + panicBytes = []byte("(PANIC=") + plusBytes = []byte("+") + iBytes = []byte("i") + trueBytes = []byte("true") + falseBytes = []byte("false") + interfaceBytes = []byte("(interface {})") + commaNewlineBytes = []byte(",\n") + newlineBytes = []byte("\n") + openBraceBytes = []byte("{") + openBraceNewlineBytes = []byte("{\n") + closeBraceBytes = []byte("}") + asteriskBytes = []byte("*") + colonBytes = []byte(":") + colonSpaceBytes = []byte(": ") + openParenBytes = []byte("(") + closeParenBytes = []byte(")") + spaceBytes = []byte(" ") + pointerChainBytes = []byte("->") + nilAngleBytes = []byte("") + maxNewlineBytes = []byte("\n") + maxShortBytes = []byte("") + circularBytes = []byte("") + circularShortBytes = []byte("") + invalidAngleBytes = []byte("") + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + percentBytes = []byte("%") + precisionBytes = []byte(".") + openAngleBytes = []byte("<") + closeAngleBytes = []byte(">") + openMapBytes = []byte("map[") + closeMapBytes = []byte("]") + lenEqualsBytes = []byte("len=") + capEqualsBytes = []byte("cap=") +) + +// hexDigits is used to map a decimal value to a hex digit. +var hexDigits = "0123456789abcdef" + +// catchPanic handles any panics that might occur during the handleMethods +// calls. +func catchPanic(w io.Writer, v reflect.Value) { + if err := recover(); err != nil { + w.Write(panicBytes) + fmt.Fprintf(w, "%v", err) + w.Write(closeParenBytes) + } +} + +// handleMethods attempts to call the Error and String methods on the underlying +// type the passed reflect.Value represents and outputes the result to Writer w. +// +// It handles panics in any called methods by catching and displaying the error +// as the formatted value. +func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { + // We need an interface to check if the type implements the error or + // Stringer interface. However, the reflect package won't give us an + // interface on certain things like unexported struct fields in order + // to enforce visibility rules. We use unsafe, when it's available, + // to bypass these restrictions since this package does not mutate the + // values. + if !v.CanInterface() { + if UnsafeDisabled { + return false + } + + v = unsafeReflectValue(v) + } + + // Choose whether or not to do error and Stringer interface lookups against + // the base type or a pointer to the base type depending on settings. + // Technically calling one of these methods with a pointer receiver can + // mutate the value, however, types which choose to satisify an error or + // Stringer interface with a pointer receiver should not be mutating their + // state inside these interface methods. + if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { + v = unsafeReflectValue(v) + } + if v.CanAddr() { + v = v.Addr() + } + + // Is it an error or Stringer? + switch iface := v.Interface().(type) { + case error: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.Error())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + + w.Write([]byte(iface.Error())) + return true + + case fmt.Stringer: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.String())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + w.Write([]byte(iface.String())) + return true + } + return false +} + +// printBool outputs a boolean value as true or false to Writer w. +func printBool(w io.Writer, val bool) { + if val { + w.Write(trueBytes) + } else { + w.Write(falseBytes) + } +} + +// printInt outputs a signed integer value to Writer w. +func printInt(w io.Writer, val int64, base int) { + w.Write([]byte(strconv.FormatInt(val, base))) +} + +// printUint outputs an unsigned integer value to Writer w. +func printUint(w io.Writer, val uint64, base int) { + w.Write([]byte(strconv.FormatUint(val, base))) +} + +// printFloat outputs a floating point value using the specified precision, +// which is expected to be 32 or 64bit, to Writer w. +func printFloat(w io.Writer, val float64, precision int) { + w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) +} + +// printComplex outputs a complex value using the specified float precision +// for the real and imaginary parts to Writer w. +func printComplex(w io.Writer, c complex128, floatPrecision int) { + r := real(c) + w.Write(openParenBytes) + w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) + i := imag(c) + if i >= 0 { + w.Write(plusBytes) + } + w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) + w.Write(iBytes) + w.Write(closeParenBytes) +} + +// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' +// prefix to Writer w. +func printHexPtr(w io.Writer, p uintptr) { + // Null pointer. + num := uint64(p) + if num == 0 { + w.Write(nilAngleBytes) + return + } + + // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix + buf := make([]byte, 18) + + // It's simpler to construct the hex string right to left. + base := uint64(16) + i := len(buf) - 1 + for num >= base { + buf[i] = hexDigits[num%base] + num /= base + i-- + } + buf[i] = hexDigits[num] + + // Add '0x' prefix. + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + + // Strip unused leading bytes. + buf = buf[i:] + w.Write(buf) +} + +// valuesSorter implements sort.Interface to allow a slice of reflect.Value +// elements to be sorted. +type valuesSorter struct { + values []reflect.Value + strings []string // either nil or same len and values + cs *ConfigState +} + +// newValuesSorter initializes a valuesSorter instance, which holds a set of +// surrogate keys on which the data should be sorted. It uses flags in +// ConfigState to decide if and how to populate those surrogate keys. +func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { + vs := &valuesSorter{values: values, cs: cs} + if canSortSimply(vs.values[0].Kind()) { + return vs + } + if !cs.DisableMethods { + vs.strings = make([]string, len(values)) + for i := range vs.values { + b := bytes.Buffer{} + if !handleMethods(cs, &b, vs.values[i]) { + vs.strings = nil + break + } + vs.strings[i] = b.String() + } + } + if vs.strings == nil && cs.SpewKeys { + vs.strings = make([]string, len(values)) + for i := range vs.values { + vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) + } + } + return vs +} + +// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted +// directly, or whether it should be considered for sorting by surrogate keys +// (if the ConfigState allows it). +func canSortSimply(kind reflect.Kind) bool { + // This switch parallels valueSortLess, except for the default case. + switch kind { + case reflect.Bool: + return true + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return true + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Uintptr: + return true + case reflect.Array: + return true + } + return false +} + +// Len returns the number of values in the slice. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Len() int { + return len(s.values) +} + +// Swap swaps the values at the passed indices. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Swap(i, j int) { + s.values[i], s.values[j] = s.values[j], s.values[i] + if s.strings != nil { + s.strings[i], s.strings[j] = s.strings[j], s.strings[i] + } +} + +// valueSortLess returns whether the first value should sort before the second +// value. It is used by valueSorter.Less as part of the sort.Interface +// implementation. +func valueSortLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Bool: + return !a.Bool() && b.Bool() + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return a.Int() < b.Int() + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return a.Uint() < b.Uint() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.String: + return a.String() < b.String() + case reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Array: + // Compare the contents of both arrays. + l := a.Len() + for i := 0; i < l; i++ { + av := a.Index(i) + bv := b.Index(i) + if av.Interface() == bv.Interface() { + continue + } + return valueSortLess(av, bv) + } + } + return a.String() < b.String() +} + +// Less returns whether the value at index i should sort before the +// value at index j. It is part of the sort.Interface implementation. +func (s *valuesSorter) Less(i, j int) bool { + if s.strings == nil { + return valueSortLess(s.values[i], s.values[j]) + } + return s.strings[i] < s.strings[j] +} + +// sortValues is a sort function that handles both native types and any type that +// can be converted to error or Stringer. Other inputs are sorted according to +// their Value.String() value to ensure display stability. +func sortValues(values []reflect.Value, cs *ConfigState) { + if len(values) == 0 { + return + } + sort.Sort(newValuesSorter(values, cs)) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go new file mode 100644 index 00000000..2e3d22f3 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/config.go @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// ConfigState houses the configuration options used by spew to format and +// display values. There is a global instance, Config, that is used to control +// all top-level Formatter and Dump functionality. Each ConfigState instance +// provides methods equivalent to the top-level functions. +// +// The zero value for ConfigState provides no indentation. You would typically +// want to set it to a space or a tab. +// +// Alternatively, you can use NewDefaultConfig to get a ConfigState instance +// with default settings. See the documentation of NewDefaultConfig for default +// values. +type ConfigState struct { + // Indent specifies the string to use for each indentation level. The + // global config instance that all top-level functions use set this to a + // single space by default. If you would like more indentation, you might + // set this to a tab with "\t" or perhaps two spaces with " ". + Indent string + + // MaxDepth controls the maximum number of levels to descend into nested + // data structures. The default, 0, means there is no limit. + // + // NOTE: Circular data structures are properly detected, so it is not + // necessary to set this value unless you specifically want to limit deeply + // nested data structures. + MaxDepth int + + // DisableMethods specifies whether or not error and Stringer interfaces are + // invoked for types that implement them. + DisableMethods bool + + // DisablePointerMethods specifies whether or not to check for and invoke + // error and Stringer interfaces on types which only accept a pointer + // receiver when the current type is not a pointer. + // + // NOTE: This might be an unsafe action since calling one of these methods + // with a pointer receiver could technically mutate the value, however, + // in practice, types which choose to satisify an error or Stringer + // interface with a pointer receiver should not be mutating their state + // inside these interface methods. As a result, this option relies on + // access to the unsafe package, so it will not have any effect when + // running in environments without access to the unsafe package such as + // Google App Engine or with the "safe" build tag specified. + DisablePointerMethods bool + + // DisablePointerAddresses specifies whether to disable the printing of + // pointer addresses. This is useful when diffing data structures in tests. + DisablePointerAddresses bool + + // DisableCapacities specifies whether to disable the printing of capacities + // for arrays, slices, maps and channels. This is useful when diffing + // data structures in tests. + DisableCapacities bool + + // ContinueOnMethod specifies whether or not recursion should continue once + // a custom error or Stringer interface is invoked. The default, false, + // means it will print the results of invoking the custom error or Stringer + // interface and return immediately instead of continuing to recurse into + // the internals of the data type. + // + // NOTE: This flag does not have any effect if method invocation is disabled + // via the DisableMethods or DisablePointerMethods options. + ContinueOnMethod bool + + // SortKeys specifies map keys should be sorted before being printed. Use + // this to have a more deterministic, diffable output. Note that only + // native types (bool, int, uint, floats, uintptr and string) and types + // that support the error or Stringer interfaces (if methods are + // enabled) are supported, with other types sorted according to the + // reflect.Value.String() output which guarantees display stability. + SortKeys bool + + // SpewKeys specifies that, as a last resort attempt, map keys should + // be spewed to strings and sorted by those strings. This is only + // considered if SortKeys is true. + SpewKeys bool +} + +// Config is the active configuration of the top-level functions. +// The configuration can be changed by modifying the contents of spew.Config. +var Config = ConfigState{Indent: " "} + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the formatted string as a value that satisfies error. See NewFormatter +// for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, c.convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, c.convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, c.convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a Formatter interface returned by c.NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Print(a ...interface{}) (n int, err error) { + return fmt.Print(c.convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, c.convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Println(a ...interface{}) (n int, err error) { + return fmt.Println(c.convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprint(a ...interface{}) string { + return fmt.Sprint(c.convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, c.convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a Formatter interface returned by c.NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintln(a ...interface{}) string { + return fmt.Sprintln(c.convertArgs(a)...) +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +c.Printf, c.Println, or c.Printf. +*/ +func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(c, v) +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { + fdump(c, w, a...) +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by modifying the public members +of c. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func (c *ConfigState) Dump(a ...interface{}) { + fdump(c, os.Stdout, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func (c *ConfigState) Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(c, &buf, a...) + return buf.String() +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a spew Formatter interface using +// the ConfigState associated with s. +func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = newFormatter(c, arg) + } + return formatters +} + +// NewDefaultConfig returns a ConfigState with the following default settings. +// +// Indent: " " +// MaxDepth: 0 +// DisableMethods: false +// DisablePointerMethods: false +// ContinueOnMethod: false +// SortKeys: false +func NewDefaultConfig() *ConfigState { + return &ConfigState{Indent: " "} +} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go new file mode 100644 index 00000000..aacaac6f --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/doc.go @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package spew implements a deep pretty printer for Go data structures to aid in +debugging. + +A quick overview of the additional features spew provides over the built-in +printing facilities for Go data types are as follows: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output (only when using + Dump style) + +There are two different approaches spew allows for dumping Go data structures: + + * Dump style which prints with newlines, customizable indentation, + and additional debug information such as types and all pointer addresses + used to indirect to the final value + * A custom Formatter interface that integrates cleanly with the standard fmt + package and replaces %v, %+v, %#v, and %#+v to provide inline printing + similar to the default %v while providing the additional functionality + outlined above and passing unsupported format verbs such as %x and %q + along to fmt + +Quick Start + +This section demonstrates how to quickly get started with spew. See the +sections below for further details on formatting and configuration options. + +To dump a variable with full newlines, indentation, type, and pointer +information use Dump, Fdump, or Sdump: + spew.Dump(myVar1, myVar2, ...) + spew.Fdump(someWriter, myVar1, myVar2, ...) + str := spew.Sdump(myVar1, myVar2, ...) + +Alternatively, if you would prefer to use format strings with a compacted inline +printing style, use the convenience wrappers Printf, Fprintf, etc with +%v (most compact), %+v (adds pointer addresses), %#v (adds types), or +%#+v (adds types and pointer addresses): + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +Configuration Options + +Configuration of spew is handled by fields in the ConfigState type. For +convenience, all of the top-level functions use a global state available +via the spew.Config global. + +It is also possible to create a ConfigState instance that provides methods +equivalent to the top-level functions. This allows concurrent configuration +options. See the ConfigState documentation for more details. + +The following configuration options are available: + * Indent + String to use for each indentation level for Dump functions. + It is a single space by default. A popular alternative is "\t". + + * MaxDepth + Maximum number of levels to descend into nested data structures. + There is no limit by default. + + * DisableMethods + Disables invocation of error and Stringer interface methods. + Method invocation is enabled by default. + + * DisablePointerMethods + Disables invocation of error and Stringer interface methods on types + which only accept pointer receivers from non-pointer variables. + Pointer method invocation is enabled by default. + + * DisablePointerAddresses + DisablePointerAddresses specifies whether to disable the printing of + pointer addresses. This is useful when diffing data structures in tests. + + * DisableCapacities + DisableCapacities specifies whether to disable the printing of + capacities for arrays, slices, maps and channels. This is useful when + diffing data structures in tests. + + * ContinueOnMethod + Enables recursion into types after invoking error and Stringer interface + methods. Recursion after method invocation is disabled by default. + + * SortKeys + Specifies map keys should be sorted before being printed. Use + this to have a more deterministic, diffable output. Note that + only native types (bool, int, uint, floats, uintptr and string) + and types which implement error or Stringer interfaces are + supported with other types sorted according to the + reflect.Value.String() output which guarantees display + stability. Natural map order is used by default. + + * SpewKeys + Specifies that, as a last resort attempt, map keys should be + spewed to strings and sorted by those strings. This is only + considered if SortKeys is true. + +Dump Usage + +Simply call spew.Dump with a list of variables you want to dump: + + spew.Dump(myVar1, myVar2, ...) + +You may also call spew.Fdump if you would prefer to output to an arbitrary +io.Writer. For example, to dump to standard error: + + spew.Fdump(os.Stderr, myVar1, myVar2, ...) + +A third option is to call spew.Sdump to get the formatted output as a string: + + str := spew.Sdump(myVar1, myVar2, ...) + +Sample Dump Output + +See the Dump example for details on the setup of the types and variables being +shown here. + + (main.Foo) { + unexportedField: (*main.Bar)(0xf84002e210)({ + flag: (main.Flag) flagTwo, + data: (uintptr) + }), + ExportedField: (map[interface {}]interface {}) (len=1) { + (string) (len=3) "one": (bool) true + } + } + +Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C +command as shown. + ([]uint8) (len=32 cap=32) { + 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | + 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| + 00000020 31 32 |12| + } + +Custom Formatter + +Spew provides a custom formatter that implements the fmt.Formatter interface +so that it integrates cleanly with standard fmt package printing functions. The +formatter is useful for inline printing of smaller data types similar to the +standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Custom Formatter Usage + +The simplest way to make use of the spew custom formatter is to call one of the +convenience functions such as spew.Printf, spew.Println, or spew.Printf. The +functions have syntax you are most likely already familiar with: + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Println(myVar, myVar2) + spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +See the Index for the full list convenience functions. + +Sample Formatter Output + +Double pointer to a uint8: + %v: <**>5 + %+v: <**>(0xf8400420d0->0xf8400420c8)5 + %#v: (**uint8)5 + %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 + +Pointer to circular struct with a uint8 field and a pointer to itself: + %v: <*>{1 <*>} + %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} + %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} + %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} + +See the Printf example for details on the setup of variables being shown +here. + +Errors + +Since it is possible for custom Stringer/error interfaces to panic, spew +detects them and handles them internally by printing the panic information +inline with the output. Since spew is intended to provide deep pretty printing +capabilities on structures, it intentionally does not return any errors. +*/ +package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go new file mode 100644 index 00000000..f78d89fc --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/dump.go @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + // uint8Type is a reflect.Type representing a uint8. It is used to + // convert cgo types to uint8 slices for hexdumping. + uint8Type = reflect.TypeOf(uint8(0)) + + // cCharRE is a regular expression that matches a cgo char. + // It is used to detect character arrays to hexdump them. + cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) + + // cUnsignedCharRE is a regular expression that matches a cgo unsigned + // char. It is used to detect unsigned character arrays to hexdump + // them. + cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) + + // cUint8tCharRE is a regular expression that matches a cgo uint8_t. + // It is used to detect uint8_t arrays to hexdump them. + cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) +) + +// dumpState contains information about the state of a dump operation. +type dumpState struct { + w io.Writer + depth int + pointers map[uintptr]int + ignoreNextType bool + ignoreNextIndent bool + cs *ConfigState +} + +// indent performs indentation according to the depth level and cs.Indent +// option. +func (d *dumpState) indent() { + if d.ignoreNextIndent { + d.ignoreNextIndent = false + return + } + d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) +} + +// unpackValue returns values inside of non-nil interfaces when possible. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface && !v.IsNil() { + v = v.Elem() + } + return v +} + +// dumpPtr handles formatting of pointers by indirecting them as necessary. +func (d *dumpState) dumpPtr(v reflect.Value) { + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range d.pointers { + if depth >= d.depth { + delete(d.pointers, k) + } + } + + // Keep list of all dereferenced pointers to show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by dereferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := d.pointers[addr]; ok && pd < d.depth { + cycleFound = true + indirects-- + break + } + d.pointers[addr] = d.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type information. + d.w.Write(openParenBytes) + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) + d.w.Write([]byte(ve.Type().String())) + d.w.Write(closeParenBytes) + + // Display pointer information. + if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { + d.w.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + d.w.Write(pointerChainBytes) + } + printHexPtr(d.w, addr) + } + d.w.Write(closeParenBytes) + } + + // Display dereferenced value. + d.w.Write(openParenBytes) + switch { + case nilFound: + d.w.Write(nilAngleBytes) + + case cycleFound: + d.w.Write(circularBytes) + + default: + d.ignoreNextType = true + d.dump(ve) + } + d.w.Write(closeParenBytes) +} + +// dumpSlice handles formatting of arrays and slices. Byte (uint8 under +// reflection) arrays and slices are dumped in hexdump -C fashion. +func (d *dumpState) dumpSlice(v reflect.Value) { + // Determine whether this type should be hex dumped or not. Also, + // for types which should be hexdumped, try to use the underlying data + // first, then fall back to trying to convert them to a uint8 slice. + var buf []uint8 + doConvert := false + doHexDump := false + numEntries := v.Len() + if numEntries > 0 { + vt := v.Index(0).Type() + vts := vt.String() + switch { + // C types that need to be converted. + case cCharRE.MatchString(vts): + fallthrough + case cUnsignedCharRE.MatchString(vts): + fallthrough + case cUint8tCharRE.MatchString(vts): + doConvert = true + + // Try to use existing uint8 slices and fall back to converting + // and copying if that fails. + case vt.Kind() == reflect.Uint8: + // We need an addressable interface to convert the type + // to a byte slice. However, the reflect package won't + // give us an interface on certain things like + // unexported struct fields in order to enforce + // visibility rules. We use unsafe, when available, to + // bypass these restrictions since this package does not + // mutate the values. + vs := v + if !vs.CanInterface() || !vs.CanAddr() { + vs = unsafeReflectValue(vs) + } + if !UnsafeDisabled { + vs = vs.Slice(0, numEntries) + + // Use the existing uint8 slice if it can be + // type asserted. + iface := vs.Interface() + if slice, ok := iface.([]uint8); ok { + buf = slice + doHexDump = true + break + } + } + + // The underlying data needs to be converted if it can't + // be type asserted to a uint8 slice. + doConvert = true + } + + // Copy and convert the underlying type if needed. + if doConvert && vt.ConvertibleTo(uint8Type) { + // Convert and copy each element into a uint8 byte + // slice. + buf = make([]uint8, numEntries) + for i := 0; i < numEntries; i++ { + vv := v.Index(i) + buf[i] = uint8(vv.Convert(uint8Type).Uint()) + } + doHexDump = true + } + } + + // Hexdump the entire slice as needed. + if doHexDump { + indent := strings.Repeat(d.cs.Indent, d.depth) + str := indent + hex.Dump(buf) + str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.TrimRight(str, d.cs.Indent) + d.w.Write([]byte(str)) + return + } + + // Recursively call dump for each item. + for i := 0; i < numEntries; i++ { + d.dump(d.unpackValue(v.Index(i))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } +} + +// dump is the main workhorse for dumping a value. It uses the passed reflect +// value to figure out what kind of object we are dealing with and formats it +// appropriately. It is a recursive function, however circular data structures +// are detected and handled properly. +func (d *dumpState) dump(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + d.w.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + d.indent() + d.dumpPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !d.ignoreNextType { + d.indent() + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + d.ignoreNextType = false + + // Display length and capacity if the built-in len and cap functions + // work with the value's kind and the len/cap itself is non-zero. + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() + } + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { + d.w.Write(openParenBytes) + if valueLen != 0 { + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) + } + if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + + // Call Stringer/error interfaces if they exist and the handle methods flag + // is enabled + if !d.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(d.cs, d.w, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(d.w, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(d.w, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(d.w, v.Uint(), 10) + + case reflect.Float32: + printFloat(d.w, v.Float(), 32) + + case reflect.Float64: + printFloat(d.w, v.Float(), 64) + + case reflect.Complex64: + printComplex(d.w, v.Complex(), 32) + + case reflect.Complex128: + printComplex(d.w, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + d.dumpSlice(v) + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.String: + d.w.Write([]byte(strconv.Quote(v.String()))) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + d.w.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + numEntries := v.Len() + keys := v.MapKeys() + if d.cs.SortKeys { + sortValues(keys, d.cs) + } + for i, key := range keys { + d.dump(d.unpackValue(key)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.MapIndex(key))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Struct: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + vt := v.Type() + numFields := v.NumField() + for i := 0; i < numFields; i++ { + d.indent() + vtf := vt.Field(i) + d.w.Write([]byte(vtf.Name)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.Field(i))) + if i < (numFields - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(d.w, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(d.w, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it in case any new + // types are added. + default: + if v.CanInterface() { + fmt.Fprintf(d.w, "%v", v.Interface()) + } else { + fmt.Fprintf(d.w, "%v", v.String()) + } + } +} + +// fdump is a helper function to consolidate the logic from the various public +// methods which take varying writers and config states. +func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { + for _, arg := range a { + if arg == nil { + w.Write(interfaceBytes) + w.Write(spaceBytes) + w.Write(nilAngleBytes) + w.Write(newlineBytes) + continue + } + + d := dumpState{w: w, cs: cs} + d.pointers = make(map[uintptr]int) + d.dump(reflect.ValueOf(arg)) + d.w.Write(newlineBytes) + } +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func Fdump(w io.Writer, a ...interface{}) { + fdump(&Config, w, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(&Config, &buf, a...) + return buf.String() +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + * Pointers are dereferenced and followed + * Circular data structures are detected and handled properly + * Custom Stringer/error interfaces are optionally invoked, including + on unexported types + * Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + * Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by an exported package global, +spew.Config. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func Dump(a ...interface{}) { + fdump(&Config, os.Stdout, a...) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go new file mode 100644 index 00000000..b04edb7d --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/format.go @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" +) + +// supportedFlags is a list of all the character flags supported by fmt package. +const supportedFlags = "0-+# " + +// formatState implements the fmt.Formatter interface and contains information +// about the state of a formatting operation. The NewFormatter function can +// be used to get a new Formatter which can be used directly as arguments +// in standard fmt package printing calls. +type formatState struct { + value interface{} + fs fmt.State + depth int + pointers map[uintptr]int + ignoreNextType bool + cs *ConfigState +} + +// buildDefaultFormat recreates the original format string without precision +// and width information to pass in to fmt.Sprintf in the case of an +// unrecognized type. Unless new types are added to the language, this +// function won't ever be called. +func (f *formatState) buildDefaultFormat() (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + buf.WriteRune('v') + + format = buf.String() + return format +} + +// constructOrigFormat recreates the original format string including precision +// and width information to pass along to the standard fmt package. This allows +// automatic deferral of all format strings this package doesn't support. +func (f *formatState) constructOrigFormat(verb rune) (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + if width, ok := f.fs.Width(); ok { + buf.WriteString(strconv.Itoa(width)) + } + + if precision, ok := f.fs.Precision(); ok { + buf.Write(precisionBytes) + buf.WriteString(strconv.Itoa(precision)) + } + + buf.WriteRune(verb) + + format = buf.String() + return format +} + +// unpackValue returns values inside of non-nil interfaces when possible and +// ensures that types for values which have been unpacked from an interface +// are displayed when the show types flag is also set. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (f *formatState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface { + f.ignoreNextType = false + if !v.IsNil() { + v = v.Elem() + } + } + return v +} + +// formatPtr handles formatting of pointers by indirecting them as necessary. +func (f *formatState) formatPtr(v reflect.Value) { + // Display nil if top level pointer is nil. + showTypes := f.fs.Flag('#') + if v.IsNil() && (!showTypes || f.ignoreNextType) { + f.fs.Write(nilAngleBytes) + return + } + + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range f.pointers { + if depth >= f.depth { + delete(f.pointers, k) + } + } + + // Keep list of all dereferenced pointers to possibly show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by derferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := f.pointers[addr]; ok && pd < f.depth { + cycleFound = true + indirects-- + break + } + f.pointers[addr] = f.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type or indirection level depending on flags. + if showTypes && !f.ignoreNextType { + f.fs.Write(openParenBytes) + f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) + f.fs.Write([]byte(ve.Type().String())) + f.fs.Write(closeParenBytes) + } else { + if nilFound || cycleFound { + indirects += strings.Count(ve.Type().String(), "*") + } + f.fs.Write(openAngleBytes) + f.fs.Write([]byte(strings.Repeat("*", indirects))) + f.fs.Write(closeAngleBytes) + } + + // Display pointer information depending on flags. + if f.fs.Flag('+') && (len(pointerChain) > 0) { + f.fs.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + f.fs.Write(pointerChainBytes) + } + printHexPtr(f.fs, addr) + } + f.fs.Write(closeParenBytes) + } + + // Display dereferenced value. + switch { + case nilFound: + f.fs.Write(nilAngleBytes) + + case cycleFound: + f.fs.Write(circularShortBytes) + + default: + f.ignoreNextType = true + f.format(ve) + } +} + +// format is the main workhorse for providing the Formatter interface. It +// uses the passed reflect value to figure out what kind of object we are +// dealing with and formats it appropriately. It is a recursive function, +// however circular data structures are detected and handled properly. +func (f *formatState) format(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + f.fs.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + f.formatPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !f.ignoreNextType && f.fs.Flag('#') { + f.fs.Write(openParenBytes) + f.fs.Write([]byte(v.Type().String())) + f.fs.Write(closeParenBytes) + } + f.ignoreNextType = false + + // Call Stringer/error interfaces if they exist and the handle methods + // flag is enabled. + if !f.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(f.cs, f.fs, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(f.fs, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(f.fs, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(f.fs, v.Uint(), 10) + + case reflect.Float32: + printFloat(f.fs, v.Float(), 32) + + case reflect.Float64: + printFloat(f.fs, v.Float(), 64) + + case reflect.Complex64: + printComplex(f.fs, v.Complex(), 32) + + case reflect.Complex128: + printComplex(f.fs, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + f.fs.Write(openBracketBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + numEntries := v.Len() + for i := 0; i < numEntries; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(v.Index(i))) + } + } + f.depth-- + f.fs.Write(closeBracketBytes) + + case reflect.String: + f.fs.Write([]byte(v.String())) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + f.fs.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + + f.fs.Write(openMapBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + keys := v.MapKeys() + if f.cs.SortKeys { + sortValues(keys, f.cs) + } + for i, key := range keys { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(key)) + f.fs.Write(colonBytes) + f.ignoreNextType = true + f.format(f.unpackValue(v.MapIndex(key))) + } + } + f.depth-- + f.fs.Write(closeMapBytes) + + case reflect.Struct: + numFields := v.NumField() + f.fs.Write(openBraceBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + vt := v.Type() + for i := 0; i < numFields; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + vtf := vt.Field(i) + if f.fs.Flag('+') || f.fs.Flag('#') { + f.fs.Write([]byte(vtf.Name)) + f.fs.Write(colonBytes) + } + f.format(f.unpackValue(v.Field(i))) + } + } + f.depth-- + f.fs.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(f.fs, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(f.fs, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it if any get added. + default: + format := f.buildDefaultFormat() + if v.CanInterface() { + fmt.Fprintf(f.fs, format, v.Interface()) + } else { + fmt.Fprintf(f.fs, format, v.String()) + } + } +} + +// Format satisfies the fmt.Formatter interface. See NewFormatter for usage +// details. +func (f *formatState) Format(fs fmt.State, verb rune) { + f.fs = fs + + // Use standard formatting for verbs that are not v. + if verb != 'v' { + format := f.constructOrigFormat(verb) + fmt.Fprintf(fs, format, f.value) + return + } + + if f.value == nil { + if fs.Flag('#') { + fs.Write(interfaceBytes) + } + fs.Write(nilAngleBytes) + return + } + + f.format(reflect.ValueOf(f.value)) +} + +// newFormatter is a helper function to consolidate the logic from the various +// public methods which take varying config states. +func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { + fs := &formatState{value: v, cs: cs} + fs.pointers = make(map[uintptr]int) + return fs +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +Printf, Println, or Fprintf. +*/ +func NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(&Config, v) +} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go new file mode 100644 index 00000000..32c0e338 --- /dev/null +++ b/vendor/github.com/davecgh/go-spew/spew/spew.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "fmt" + "io" +) + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the formatted string as a value that satisfies error. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a default Formatter interface returned by NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) +func Print(a ...interface{}) (n int, err error) { + return fmt.Print(convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) +func Println(a ...interface{}) (n int, err error) { + return fmt.Println(convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprint(a ...interface{}) string { + return fmt.Sprint(convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintln(a ...interface{}) string { + return fmt.Sprintln(convertArgs(a)...) +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a default spew Formatter interface. +func convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = NewFormatter(arg) + } + return formatters +} diff --git a/vendor/github.com/davidlazar/go-crypto/LICENSE b/vendor/github.com/davidlazar/go-crypto/LICENSE new file mode 100644 index 00000000..a91035e1 --- /dev/null +++ b/vendor/github.com/davidlazar/go-crypto/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 David Lazar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/davidlazar/go-crypto/drbg/LICENSE b/vendor/github.com/davidlazar/go-crypto/drbg/LICENSE new file mode 100644 index 00000000..b5c6032f --- /dev/null +++ b/vendor/github.com/davidlazar/go-crypto/drbg/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 David Lazar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/davidlazar/go-crypto/salsa20/salsa20.go b/vendor/github.com/davidlazar/go-crypto/salsa20/salsa20.go new file mode 100644 index 00000000..4942dfee --- /dev/null +++ b/vendor/github.com/davidlazar/go-crypto/salsa20/salsa20.go @@ -0,0 +1,85 @@ +package salsa20 + +import ( + "crypto/cipher" + "encoding/binary" + + "golang.org/x/crypto/salsa20/salsa" +) + +const BlockSize = 64 + +type salsaCipher struct { + key *[32]byte + nonce [8]byte + x [BlockSize]byte + nx int + counter uint64 +} + +func New(key *[32]byte, nonce []byte) cipher.Stream { + c := new(salsaCipher) + + if len(nonce) == 24 { + var subKey [32]byte + var hNonce [16]byte + copy(hNonce[:], nonce[:16]) + salsa.HSalsa20(&subKey, &hNonce, key, &salsa.Sigma) + copy(c.nonce[:], nonce[16:]) + c.key = &subKey + } else if len(nonce) == 8 { + c.key = key + copy(c.nonce[:], nonce) + } else { + panic("salsa20: nonce must be 8 or 24 bytes") + } + return c +} + +func (c *salsaCipher) XORKeyStream(dst, src []byte) { + if len(dst) < len(src) { + src = src[:len(dst)] + } + if c.nx > 0 { + n := xorBytes(dst, src, c.x[c.nx:]) + c.nx += n + if c.nx == BlockSize { + c.nx = 0 + } + src = src[n:] + dst = dst[n:] + } + if len(src) > BlockSize { + n := len(src) &^ (BlockSize - 1) + c.blocks(dst, src[:n]) + src = src[n:] + dst = dst[n:] + } + if len(src) > 0 { + c.nx = copy(c.x[:], src) + for i := c.nx; i < len(c.x); i++ { + c.x[i] = 0 + } + c.blocks(c.x[:], c.x[:]) + copy(dst, c.x[:c.nx]) + } +} + +func (c *salsaCipher) blocks(dst, src []byte) { + var nonce [16]byte + copy(nonce[:], c.nonce[:]) + binary.LittleEndian.PutUint64(nonce[8:], c.counter) + salsa.XORKeyStream(dst, src, &nonce, c.key) + c.counter += uint64(len(src)) / 64 +} + +func xorBytes(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + for i := 0; i < n; i++ { + dst[i] = a[i] ^ b[i] + } + return n +} diff --git a/vendor/github.com/dgraph-io/badger/.gitignore b/vendor/github.com/dgraph-io/badger/.gitignore new file mode 100644 index 00000000..11b9bcb1 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/.gitignore @@ -0,0 +1 @@ +p/ diff --git a/vendor/github.com/dgraph-io/badger/.golangci.yml b/vendor/github.com/dgraph-io/badger/.golangci.yml new file mode 100644 index 00000000..22f245f2 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/.golangci.yml @@ -0,0 +1,20 @@ +run: + tests: false + +linters-settings: + lll: + line-length: 100 + +linters: + disable-all: true + enable: + - errcheck + - ineffassign + - gas + - gofmt + - golint + - gosimple + - govet + - lll + - varcheck + - unused diff --git a/vendor/github.com/dgraph-io/badger/.travis.yml b/vendor/github.com/dgraph-io/badger/.travis.yml new file mode 100644 index 00000000..43bf4cdc --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/.travis.yml @@ -0,0 +1,25 @@ +language: go + +go: + - "1.9" + - "1.10" + - "1.11" + +matrix: + include: + - os: osx +notifications: + email: false + slack: + secure: X7uBLWYbuUhf8QFE16CoS5z7WvFR8EN9j6cEectMW6mKZ3vwXGwVXRIPsgUq/606DsQdCCx34MR8MRWYGlu6TBolbSe9y0EP0i46yipPz22YtuT7umcVUbGEyx8MZKgG0v1u/zA0O4aCsOBpGAA3gxz8h3JlEHDt+hv6U8xRsSllVLzLSNb5lwxDtcfEDxVVqP47GMEgjLPM28Pyt5qwjk7o5a4YSVzkfdxBXxd3gWzFUWzJ5E3cTacli50dK4GVfiLcQY2aQYoYO7AAvDnvP+TPfjDkBlUEE4MUz5CDIN51Xb+WW33sX7g+r3Bj7V5IRcF973RiYkpEh+3eoiPnyWyxhDZBYilty3b+Hysp6d4Ov/3I3ll7Bcny5+cYjakjkMH3l9w3gs6Y82GlpSLSJshKWS8vPRsxFe0Pstj6QSJXTd9EBaFr+l1ScXjJv/Sya9j8N9FfTuOTESWuaL1auX4Y7zEEVHlA8SCNOO8K0eTfxGZnC/YcIHsR8rePEAcFxfOYQppkyLF/XvAtnb/LMUuu0g4y2qNdme6Oelvyar1tFEMRtbl4mRCdu/krXBFtkrsfUaVY6WTPdvXAGotsFJ0wuA53zGVhlcd3+xAlSlR3c1QX95HIMeivJKb5L4nTjP+xnrmQNtnVk+tG4LSH2ltuwcZSSczModtcBmRefrk= + +env: + global: + - secure: CRkV2+/jlO0gXzzS50XGxfMS117FNwiVjxNY/LeWq06RKD+dDCPxTJl3JCNe3l0cYEPAglV2uMMYukDiTqJ7e+HI4nh4N4mv6lwx39N8dAvJe1x5ITS2T4qk4kTjuQb1Q1vw/ZOxoQqmvNKj2uRmBdJ/HHmysbRJ1OzCWML3OXdUwJf0AYlJzTjpMfkOKr7sTtE4rwyyQtd4tKH1fGdurgI9ZuFd9qvYxK2qcJhsQ6CNqMXt+7FkVkN1rIPmofjjBTNryzUr4COFXuWH95aDAif19DeBW4lbNgo1+FpDsrgmqtuhl6NAuptI8q/imow2KXBYJ8JPXsxW8DVFj0IIp0RCd3GjaEnwBEbxAyiIHLfW7AudyTS/dJOvZffPqXnuJ8xj3OPIdNe4xY0hWl8Ju2HhKfLOAHq7VadHZWd3IHLil70EiL4/JLD1rNbMImUZisFaA8pyrcIvYYebjOnk4TscwKFLedClRSX1XsMjWWd0oykQtrdkHM2IxknnBpaLu7mFnfE07f6dkG0nlpyu4SCLey7hr5FdcEmljA0nIxTSYDg6035fQkBEAbe7hlESOekkVNT9IZPwG+lmt3vU4ofi6NqNbJecOuSB+h36IiZ9s4YQtxYNnLgW14zjuFGGyT5smc3IjBT7qngDjKIgyrSVoRkY/8udy9qbUgvBeW8= + +before_script: +- go get github.com/mattn/goveralls +script: +- bash contrib/cover.sh $HOME/build coverage.out || travis_terminate 1 +- goveralls -service=travis-ci -coverprofile=coverage.out || true +- goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/vendor/github.com/dgraph-io/badger/CHANGELOG.md b/vendor/github.com/dgraph-io/badger/CHANGELOG.md new file mode 100644 index 00000000..550b66e2 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/CHANGELOG.md @@ -0,0 +1,100 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.5.3] - 2018-07-11 +Bug Fixes: +* Fix a panic caused due to item.vptr not copying over vs.Value, when looking + for a move key. + +## [1.5.2] - 2018-06-19 +Bug Fixes: +* Fix the way move key gets generated. +* If a transaction has unclosed, or multiple iterators running simultaneously, + throw a panic. Every iterator must be properly closed. At any point in time, + only one iterator per transaction can be running. This is to avoid bugs in a + transaction data structure which is thread unsafe. + +* *Warning: This change might cause panics in user code. Fix is to properly + close your iterators, and only have one running at a time per transaction.* + +## [1.5.1] - 2018-06-04 +Bug Fixes: +* Fix for infinite yieldItemValue recursion. #503 +* Fix recursive addition of `badgerMove` prefix. https://github.com/dgraph-io/badger/commit/2e3a32f0ccac3066fb4206b28deb39c210c5266f +* Use file size based window size for sampling, instead of fixing it to 10MB. #501 + +Cleanup: +* Clarify comments and documentation. +* Move badger tool one directory level up. + +## [1.5.0] - 2018-05-08 +* Introduce `NumVersionsToKeep` option. This option is used to discard many + versions of the same key, which saves space. +* Add a new `SetWithDiscard` method, which would indicate that all the older + versions of the key are now invalid. Those versions would be discarded during + compactions. +* Value log GC moves are now bound to another keyspace to ensure latest versions + of data are always at the top in LSM tree. +* Introduce `ValueLogMaxEntries` to restrict the number of key-value pairs per + value log file. This helps bound the time it takes to garbage collect one + file. + +## [1.4.0] - 2018-05-04 +* Make mmap-ing of value log optional. +* Run GC multiple times, based on recorded discard statistics. +* Add MergeOperator. +* Force compact L0 on clsoe (#439). +* Add truncate option to warn about data loss (#452). +* Discard key versions during compaction (#464). +* Introduce new `LSMOnlyOptions`, to make Badger act like a typical LSM based DB. + +Bug fix: +* (Temporary) Check max version across all tables in Get (removed in next + release). +* Update commit and read ts while loading from backup. +* Ensure all transaction entries are part of the same value log file. +* On commit, run unlock callbacks before doing writes (#413). +* Wait for goroutines to finish before closing iterators (#421). + +## [1.3.0] - 2017-12-12 +* Add `DB.NextSequence()` method to generate monotonically increasing integer + sequences. +* Add `DB.Size()` method to return the size of LSM and value log files. +* Tweaked mmap code to make Windows 32-bit builds work. +* Tweaked build tags on some files to make iOS builds work. +* Fix `DB.PurgeOlderVersions()` to not violate some constraints. + +## [1.2.0] - 2017-11-30 +* Expose a `Txn.SetEntry()` method to allow setting the key-value pair + and all the metadata at the same time. + +## [1.1.1] - 2017-11-28 +* Fix bug where txn.Get was returing key deleted in same transaction. +* Fix race condition while decrementing reference in oracle. +* Update doneCommit in the callback for CommitAsync. +* Iterator see writes of current txn. + +## [1.1.0] - 2017-11-13 +* Create Badger directory if it does not exist when `badger.Open` is called. +* Added `Item.ValueCopy()` to avoid deadlocks in long-running iterations +* Fixed 64-bit alignment issues to make Badger run on Arm v7 + +## [1.0.1] - 2017-11-06 +* Fix an uint16 overflow when resizing key slice + +[Unreleased]: https://github.com/dgraph-io/badger/compare/v1.5.3...HEAD +[1.5.3]: https://github.com/dgraph-io/badger/compare/v1.5.2...v1.5.3 +[1.5.2]: https://github.com/dgraph-io/badger/compare/v1.5.1...v1.5.2 +[1.5.1]: https://github.com/dgraph-io/badger/compare/v1.5.0...v1.5.1 +[1.5.0]: https://github.com/dgraph-io/badger/compare/v1.4.0...v1.5.0 +[1.4.0]: https://github.com/dgraph-io/badger/compare/v1.3.0...v1.4.0 +[1.3.0]: https://github.com/dgraph-io/badger/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/dgraph-io/badger/compare/v1.1.1...v1.2.0 +[1.1.1]: https://github.com/dgraph-io/badger/compare/v1.1.0...v1.1.1 +[1.1.0]: https://github.com/dgraph-io/badger/compare/v1.0.1...v1.1.0 +[1.0.1]: https://github.com/dgraph-io/badger/compare/v1.0.0...v1.0.1 diff --git a/vendor/github.com/dgraph-io/badger/CODE_OF_CONDUCT.md b/vendor/github.com/dgraph-io/badger/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..bf7bbc29 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/CODE_OF_CONDUCT.md @@ -0,0 +1,5 @@ +# Code of Conduct + +Our Code of Conduct can be found here: + +https://dgraph.io/conduct diff --git a/vendor/github.com/dgraph-io/badger/LICENSE b/vendor/github.com/dgraph-io/badger/LICENSE new file mode 100644 index 00000000..d9a10c0d --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/vendor/github.com/dgraph-io/badger/README.md b/vendor/github.com/dgraph-io/badger/README.md new file mode 100644 index 00000000..a25d8e1f --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/README.md @@ -0,0 +1,776 @@ +# BadgerDB [![GoDoc](https://godoc.org/github.com/dgraph-io/badger?status.svg)](https://godoc.org/github.com/dgraph-io/badger) [![Go Report Card](https://goreportcard.com/badge/github.com/dgraph-io/badger)](https://goreportcard.com/report/github.com/dgraph-io/badger) [![Sourcegraph](https://sourcegraph.com/github.com/dgraph-io/badger/-/badge.svg)](https://sourcegraph.com/github.com/dgraph-io/badger?badge) [![Build Status](https://teamcity.dgraph.io/guestAuth/app/rest/builds/buildType:(id:Badger_UnitTests)/statusIcon.svg)](https://teamcity.dgraph.io/viewLog.html?buildTypeId=Badger_UnitTests&buildId=lastFinished&guest=1) ![Appveyor](https://ci.appveyor.com/api/projects/status/github/dgraph-io/badger?branch=master&svg=true) [![Coverage Status](https://coveralls.io/repos/github/dgraph-io/badger/badge.svg?branch=master)](https://coveralls.io/github/dgraph-io/badger?branch=master) + +![Badger mascot](images/diggy-shadow.png) + +BadgerDB is an embeddable, persistent and fast key-value (KV) database +written in pure Go. It's meant to be a performant alternative to non-Go-based +key-value stores like [RocksDB](https://github.com/facebook/rocksdb). + +## Project Status [Oct 27, 2018] + +Badger is stable and is being used to serve data sets worth hundreds of +terabytes. Badger supports concurrent ACID transactions with serializable +snapshot isolation (SSI) guarantees. A Jepsen-style bank test runs nightly for +8h, with `--race` flag and ensures maintainance of transactional guarantees. +Badger has also been tested to work with filesystem level anomalies, to ensure +persistence and consistency. + +Badger v1.0 was released in Nov 2017, with a Badger v2.0 release coming up in a +few months. The [Changelog] is kept fairly up-to-date. + +[Changelog]:https://github.com/dgraph-io/badger/blob/master/CHANGELOG.md + +## Table of Contents + * [Getting Started](#getting-started) + + [Installing](#installing) + + [Opening a database](#opening-a-database) + + [Transactions](#transactions) + - [Read-only transactions](#read-only-transactions) + - [Read-write transactions](#read-write-transactions) + - [Managing transactions manually](#managing-transactions-manually) + + [Using key/value pairs](#using-keyvalue-pairs) + + [Monotonically increasing integers](#monotonically-increasing-integers) + * [Merge Operations](#merge-operations) + + [Setting Time To Live(TTL) and User Metadata on Keys](#setting-time-to-livettl-and-user-metadata-on-keys) + + [Iterating over keys](#iterating-over-keys) + - [Prefix scans](#prefix-scans) + - [Key-only iteration](#key-only-iteration) + + [Stream](#stream) + + [Garbage Collection](#garbage-collection) + + [Database backup](#database-backup) + + [Memory usage](#memory-usage) + + [Statistics](#statistics) + * [Resources](#resources) + + [Blog Posts](#blog-posts) + * [Contact](#contact) + * [Design](#design) + + [Comparisons](#comparisons) + + [Benchmarks](#benchmarks) + * [Other Projects Using Badger](#other-projects-using-badger) + * [Frequently Asked Questions](#frequently-asked-questions) + +## Getting Started + +### Installing +To start using Badger, install Go 1.8 or above and run `go get`: + +```sh +$ go get github.com/dgraph-io/badger/... +``` + +This will retrieve the library and install the `badger` command line +utility into your `$GOBIN` path. + + +### Opening a database +The top-level object in Badger is a `DB`. It represents multiple files on disk +in specific directories, which contain the data for a single database. + +To open your database, use the `badger.Open()` function, with the appropriate +options. The `Dir` and `ValueDir` options are mandatory and must be +specified by the client. They can be set to the same value to simplify things. + +```go +package main + +import ( + "log" + + "github.com/dgraph-io/badger" +) + +func main() { + // Open the Badger database located in the /tmp/badger directory. + // It will be created if it doesn't exist. + opts := badger.DefaultOptions + opts.Dir = "/tmp/badger" + opts.ValueDir = "/tmp/badger" + db, err := badger.Open(opts) + if err != nil { + log.Fatal(err) + } + defer db.Close() +  // Your code here… +} +``` + +Please note that Badger obtains a lock on the directories so multiple processes +cannot open the same database at the same time. + +### Transactions + +#### Read-only transactions +To start a read-only transaction, you can use the `DB.View()` method: + +```go +err := db.View(func(txn *badger.Txn) error { +  // Your code here… +  return nil +}) +``` + +You cannot perform any writes or deletes within this transaction. Badger +ensures that you get a consistent view of the database within this closure. Any +writes that happen elsewhere after the transaction has started, will not be +seen by calls made within the closure. + +#### Read-write transactions +To start a read-write transaction, you can use the `DB.Update()` method: + +```go +err := db.Update(func(txn *badger.Txn) error { +  // Your code here… +  return nil +}) +``` + +All database operations are allowed inside a read-write transaction. + +Always check the returned error value. If you return an error +within your closure it will be passed through. + +An `ErrConflict` error will be reported in case of a conflict. Depending on the state +of your application, you have the option to retry the operation if you receive +this error. + +An `ErrTxnTooBig` will be reported in case the number of pending writes/deletes in +the transaction exceed a certain limit. In that case, it is best to commit the +transaction and start a new transaction immediately. Here is an example (we are +not checking for errors in some places for simplicity): + +```go +updates := make(map[string]string) +txn := db.NewTransaction(true) +for k,v := range updates { + if err := txn.Set([]byte(k),[]byte(v)); err == ErrTxnTooBig { + _ = txn.Commit() + txn = db.NewTransaction(true) + _ = txn.Set([]byte(k),[]byte(v)) + } +} +_ = txn.Commit() +``` + +#### Managing transactions manually +The `DB.View()` and `DB.Update()` methods are wrappers around the +`DB.NewTransaction()` and `Txn.Commit()` methods (or `Txn.Discard()` in case of +read-only transactions). These helper methods will start the transaction, +execute a function, and then safely discard your transaction if an error is +returned. This is the recommended way to use Badger transactions. + +However, sometimes you may want to manually create and commit your +transactions. You can use the `DB.NewTransaction()` function directly, which +takes in a boolean argument to specify whether a read-write transaction is +required. For read-write transactions, it is necessary to call `Txn.Commit()` +to ensure the transaction is committed. For read-only transactions, calling +`Txn.Discard()` is sufficient. `Txn.Commit()` also calls `Txn.Discard()` +internally to cleanup the transaction, so just calling `Txn.Commit()` is +sufficient for read-write transaction. However, if your code doesn’t call +`Txn.Commit()` for some reason (for e.g it returns prematurely with an error), +then please make sure you call `Txn.Discard()` in a `defer` block. Refer to the +code below. + +```go +// Start a writable transaction. +txn := db.NewTransaction(true) +defer txn.Discard() + +// Use the transaction... +err := txn.Set([]byte("answer"), []byte("42")) +if err != nil { + return err +} + +// Commit the transaction and check for error. +if err := txn.Commit(); err != nil { + return err +} +``` + +The first argument to `DB.NewTransaction()` is a boolean stating if the transaction +should be writable. + +Badger allows an optional callback to the `Txn.Commit()` method. Normally, the +callback can be set to `nil`, and the method will return after all the writes +have succeeded. However, if this callback is provided, the `Txn.Commit()` +method returns as soon as it has checked for any conflicts. The actual writing +to the disk happens asynchronously, and the callback is invoked once the +writing has finished, or an error has occurred. This can improve the throughput +of the application in some cases. But it also means that a transaction is not +durable until the callback has been invoked with a `nil` error value. + +### Using key/value pairs +To save a key/value pair, use the `Txn.Set()` method: + +```go +err := db.Update(func(txn *badger.Txn) error { + err := txn.Set([]byte("answer"), []byte("42")) + return err +}) +``` + +This will set the value of the `"answer"` key to `"42"`. To retrieve this +value, we can use the `Txn.Get()` method: + +```go +err := db.View(func(txn *badger.Txn) error { + item, err := txn.Get([]byte("answer")) + handle(err) + + var valNot, valCopy []byte + err := item.Value(func(val []byte) error { + // This func with val would only be called if item.Value encounters no error. + + // Accessing val here is valid. + fmt.Printf("The answer is: %s\n", val) + + // Copying or parsing val is valid. + valCopy = append([]byte{}, val...) + + // Assigning val slice to another variable is NOT OK. + valNot = val // Do not do this. + return nil + }) + handle(err) + + // DO NOT access val here. It is the most common cause of bugs. + fmt.Printf("NEVER do this. %s\n", valNot) + + // You must copy it to use it outside item.Value(...). + fmt.Printf("The answer is: %s\n", valCopy) + + // Alternatively, you could also use item.ValueCopy(). + valCopy, err = item.ValueCopy(nil) + handle(err) + fmt.Printf("The answer is: %s\n", valCopy) + + return nil +}) +``` + +`Txn.Get()` returns `ErrKeyNotFound` if the value is not found. + +Please note that values returned from `Get()` are only valid while the +transaction is open. If you need to use a value outside of the transaction +then you must use `copy()` to copy it to another byte slice. + +Use the `Txn.Delete()` method to delete a key. + +### Monotonically increasing integers + +To get unique monotonically increasing integers with strong durability, you can +use the `DB.GetSequence` method. This method returns a `Sequence` object, which +is thread-safe and can be used concurrently via various goroutines. + +Badger would lease a range of integers to hand out from memory, with the +bandwidth provided to `DB.GetSequence`. The frequency at which disk writes are +done is determined by this lease bandwidth and the frequency of `Next` +invocations. Setting a bandwith too low would do more disk writes, setting it +too high would result in wasted integers if Badger is closed or crashes. +To avoid wasted integers, call `Release` before closing Badger. + +```go +seq, err := db.GetSequence(key, 1000) +defer seq.Release() +for { + num, err := seq.Next() +} +``` + +### Merge Operations +Badger provides support for unordered merge operations. You can define a func +of type `MergeFunc` which takes in an existing value, and a value to be +_merged_ with it. It returns a new value which is the result of the _merge_ +operation. All values are specified in byte arrays. For e.g., here is a merge +function (`add`) which adds a `uint64` value to an existing `uint64` value. + +```Go +func uint64ToBytes(i uint64) []byte { + var buf [8]byte + binary.BigEndian.PutUint64(buf[:], i) + return buf[:] +} + +func bytesToUint64(b []byte) uint64 { + return binary.BigEndian.Uint64(b) +} + +// Merge function to add two uint64 numbers +func add(existing, new []byte) []byte { + return uint64ToBytes(bytesToUint64(existing) + bytesToUint64(new)) +} +``` + +This function can then be passed to the `DB.GetMergeOperator()` method, along +with a key, and a duration value. The duration specifies how often the merge +function is run on values that have been added using the `MergeOperator.Add()` +method. + +`MergeOperator.Get()` method can be used to retrieve the cumulative value of the key +associated with the merge operation. + +```Go +key := []byte("merge") +m := db.GetMergeOperator(key, add, 200*time.Millisecond) +defer m.Stop() + +m.Add(uint64ToBytes(1)) +m.Add(uint64ToBytes(2)) +m.Add(uint64ToBytes(3)) + +res, err := m.Get() // res should have value 6 encoded +fmt.Println(bytesToUint64(res)) +``` + +### Setting Time To Live(TTL) and User Metadata on Keys +Badger allows setting an optional Time to Live (TTL) value on keys. Once the TTL has +elapsed, the key will no longer be retrievable and will be eligible for garbage +collection. A TTL can be set as a `time.Duration` value using the `Txn.SetWithTTL()` +API method. + +An optional user metadata value can be set on each key. A user metadata value +is represented by a single byte. It can be used to set certain bits along +with the key to aid in interpreting or decoding the key-value pair. User +metadata can be set using the `Txn.SetWithMeta()` API method. + +`Txn.SetEntry()` can be used to set the key, value, user metatadata and TTL, +all at once. + +### Iterating over keys +To iterate over keys, we can use an `Iterator`, which can be obtained using the +`Txn.NewIterator()` method. Iteration happens in byte-wise lexicographical sorting +order. + + +```go +err := db.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchSize = 10 + it := txn.NewIterator(opts) + defer it.Close() + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + k := item.Key() + err := item.Value(func(v []byte) error { + fmt.Printf("key=%s, value=%s\n", k, v) + return nil + }) + if err != nil { + return err + } + } + return nil +}) +``` + +The iterator allows you to move to a specific point in the list of keys and move +forward or backward through the keys one at a time. + +By default, Badger prefetches the values of the next 100 items. You can adjust +that with the `IteratorOptions.PrefetchSize` field. However, setting it to +a value higher than GOMAXPROCS (which we recommend to be 128 or higher) +shouldn’t give any additional benefits. You can also turn off the fetching of +values altogether. See section below on key-only iteration. + +#### Prefix scans +To iterate over a key prefix, you can combine `Seek()` and `ValidForPrefix()`: + +```go +db.View(func(txn *badger.Txn) error { + it := txn.NewIterator(badger.DefaultIteratorOptions) + defer it.Close() + prefix := []byte("1234") + for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() { + item := it.Item() + k := item.Key() + err := item.Value(func(v []byte) error { + fmt.Printf("key=%s, value=%s\n", k, v) + return nil + }) + if err != nil { + return err + } + } + return nil +}) +``` + +#### Key-only iteration +Badger supports a unique mode of iteration called _key-only_ iteration. It is +several order of magnitudes faster than regular iteration, because it involves +access to the LSM-tree only, which is usually resident entirely in RAM. To +enable key-only iteration, you need to set the `IteratorOptions.PrefetchValues` +field to `false`. This can also be used to do sparse reads for selected keys +during an iteration, by calling `item.Value()` only when required. + +```go +err := db.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchValues = false + it := txn.NewIterator(opts) + defer it.Close() + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + k := item.Key() + fmt.Printf("key=%s\n", k) + } + return nil +}) +``` + +### Stream +Badger provides a Stream framework, which concurrently iterates over all or a +portion of the DB, converting data into custom key-values, and streams it out +serially to be sent over network, written to disk, or even written back to +Badger. This is a lot faster way to iterate over Badger than using a single +Iterator. Stream supports Badger in both managed and normal mode. + +Stream uses the natural boundaries created by SSTables within the LSM tree, to +quickly generate key ranges. Each goroutine then picks a range and runs an +iterator to iterate over it. Each iterator iterates over all versions of values +and is created from the same transaction, thus working over a snapshot of the +DB. Every time a new key is encountered, it calls `ChooseKey(item)`, followed +by `KeyToList(key, itr)`. This allows a user to select or reject that key, and +if selected, convert the value versions into custom key-values. The goroutine +batches up 4MB worth of key-values, before sending it over to a channel. +Another goroutine further batches up data from this channel using *smart +batching* algorithm and calls `Send` serially. + +This framework is designed for high throughput key-value iteration, spreading +the work of iteration across many goroutines. `DB.Backup` uses this framework to +provide full and incremental backups quickly. Dgraph is a heavy user of this +framework. In fact, this framework was developed and used within Dgraph, before +getting ported over to Badger. + +```go +stream := db.NewStream() +// db.NewStreamAt(readTs) for managed mode. + +// -- Optional settings +stream.NumGo = 16 // Set number of goroutines to use for iteration. +stream.Prefix = []byte("some-prefix") // Leave nil for iteration over the whole DB. +stream.LogPrefix = "Badger.Streaming" // For identifying stream logs. Outputs to Logger. + +// ChooseKey is called concurrently for every key. If left nil, assumes true by default. +stream.ChooseKey = func(item *badger.Item) bool { + return bytes.HasSuffix(item.Key(), []byte("er")) +} + +// KeyToList is called concurrently for chosen keys. This can be used to convert +// Badger data into custom key-values. If nil, uses stream.ToList, a default +// implementation, which picks all valid key-values. +stream.KeyToList = nil + +// -- End of optional settings. + +// Send is called serially, while Stream.Orchestrate is running. +stream.Send = func(list *pb.KVList) error { + return proto.MarshalText(w, list) // Write to w. +} + +// Run the stream +if err := stream.Orchestrate(context.Background()); err != nil { + return err +} +// Done. +``` + +### Garbage Collection +Badger values need to be garbage collected, because of two reasons: + +* Badger keeps values separately from the LSM tree. This means that the compaction operations +that clean up the LSM tree do not touch the values at all. Values need to be cleaned up +separately. + +* Concurrent read/write transactions could leave behind multiple values for a single key, because they +are stored with different versions. These could accumulate, and take up unneeded space beyond the +time these older versions are needed. + +Badger relies on the client to perform garbage collection at a time of their choosing. It provides +the following method, which can be invoked at an appropriate time: + +* `DB.RunValueLogGC()`: This method is designed to do garbage collection while + Badger is online. Along with randomly picking a file, it uses statistics generated by the + LSM-tree compactions to pick files that are likely to lead to maximum space + reclamation. It is recommended to be called during periods of low activity in + your system, or periodically. One call would only result in removal of at max + one log file. As an optimization, you could also immediately re-run it whenever + it returns nil error (indicating a successful value log GC), as shown below. + + ```go + ticker := time.NewTicker(5 * time.Minute) + defer ticker.Stop() + for range ticker.C { + again: + err := db.RunValueLogGC(0.7) + if err == nil { + goto again + } + } + ``` + +* `DB.PurgeOlderVersions()`: This method is **DEPRECATED** since v1.5.0. Now, Badger's LSM tree automatically discards older/invalid versions of keys. + +**Note: The RunValueLogGC method would not garbage collect the latest value log.** + +### Database backup +There are two public API methods `DB.Backup()` and `DB.Load()` which can be +used to do online backups and restores. Badger v0.9 provides a CLI tool +`badger`, which can do offline backup/restore. Make sure you have `$GOPATH/bin` +in your PATH to use this tool. + +The command below will create a version-agnostic backup of the database, to a +file `badger.bak` in the current working directory + +``` +badger backup --dir +``` + +To restore `badger.bak` in the current working directory to a new database: + +``` +badger restore --dir +``` + +See `badger --help` for more details. + +If you have a Badger database that was created using v0.8 (or below), you can +use the `badger_backup` tool provided in v0.8.1, and then restore it using the +command above to upgrade your database to work with the latest version. + +``` +badger_backup --dir --backup-file badger.bak +``` + +We recommend all users to use the `Backup` and `Restore` APIs and tools. However, +Badger is also rsync-friendly because all files are immutable, barring the +latest value log which is append-only. So, rsync can be used as rudimentary way +to perform a backup. In the following script, we repeat rsync to ensure that the +LSM tree remains consistent with the MANIFEST file while doing a full backup. + +``` +#!/bin/bash +set -o history +set -o histexpand +# Makes a complete copy of a Badger database directory. +# Repeat rsync if the MANIFEST and SSTables are updated. +rsync -avz --delete db/ dst +while !! | grep -q "(MANIFEST\|\.sst)$"; do :; done +``` + +### Memory usage +Badger's memory usage can be managed by tweaking several options available in +the `Options` struct that is passed in when opening the database using +`DB.Open`. + +- `Options.ValueLogLoadingMode` can be set to `options.FileIO` (instead of the + default `options.MemoryMap`) to avoid memory-mapping log files. This can be + useful in environments with low RAM. +- Number of memtables (`Options.NumMemtables`) + - If you modify `Options.NumMemtables`, also adjust `Options.NumLevelZeroTables` and + `Options.NumLevelZeroTablesStall` accordingly. +- Number of concurrent compactions (`Options.NumCompactors`) +- Mode in which LSM tree is loaded (`Options.TableLoadingMode`) +- Size of table (`Options.MaxTableSize`) +- Size of value log file (`Options.ValueLogFileSize`) + +If you want to decrease the memory usage of Badger instance, tweak these +options (ideally one at a time) until you achieve the desired +memory usage. + +### Statistics +Badger records metrics using the [expvar] package, which is included in the Go +standard library. All the metrics are documented in [y/metrics.go][metrics] +file. + +`expvar` package adds a handler in to the default HTTP server (which has to be +started explicitly), and serves up the metrics at the `/debug/vars` endpoint. +These metrics can then be collected by a system like [Prometheus], to get +better visibility into what Badger is doing. + +[expvar]: https://golang.org/pkg/expvar/ +[metrics]: https://github.com/dgraph-io/badger/blob/master/y/metrics.go +[Prometheus]: https://prometheus.io/ + +## Resources + +### Blog Posts +1. [Introducing Badger: A fast key-value store written natively in +Go](https://open.dgraph.io/post/badger/) +2. [Make Badger crash resilient with ALICE](https://blog.dgraph.io/post/alice/) +3. [Badger vs LMDB vs BoltDB: Benchmarking key-value databases in Go](https://blog.dgraph.io/post/badger-lmdb-boltdb/) +4. [Concurrent ACID Transactions in Badger](https://blog.dgraph.io/post/badger-txn/) + +## Design +Badger was written with these design goals in mind: + +- Write a key-value database in pure Go. +- Use latest research to build the fastest KV database for data sets spanning terabytes. +- Optimize for SSDs. + +Badger’s design is based on a paper titled _[WiscKey: Separating Keys from +Values in SSD-conscious Storage][wisckey]_. + +[wisckey]: https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf + +### Comparisons +| Feature | Badger | RocksDB | BoltDB | +| ------- | ------ | ------- | ------ | +| Design | LSM tree with value log | LSM tree only | B+ tree | +| High Read throughput | Yes | No | Yes | +| High Write throughput | Yes | Yes | No | +| Designed for SSDs | Yes (with latest research 1) | Not specifically 2 | No | +| Embeddable | Yes | Yes | Yes | +| Sorted KV access | Yes | Yes | Yes | +| Pure Go (no Cgo) | Yes | No | Yes | +| Transactions | Yes, ACID, concurrent with SSI3 | Yes (but non-ACID) | Yes, ACID | +| Snapshots | Yes | Yes | Yes | +| TTL support | Yes | Yes | No | +| 3D access (key-value-version) | Yes4 | No | No | + +1 The [WISCKEY paper][wisckey] (on which Badger is based) saw big +wins with separating values from keys, significantly reducing the write +amplification compared to a typical LSM tree. + +2 RocksDB is an SSD optimized version of LevelDB, which was designed specifically for rotating disks. +As such RocksDB's design isn't aimed at SSDs. + +3 SSI: Serializable Snapshot Isolation. For more details, see the blog post [Concurrent ACID Transactions in Badger](https://blog.dgraph.io/post/badger-txn/) + +4 Badger provides direct access to value versions via its Iterator API. +Users can also specify how many versions to keep per key via Options. + +### Benchmarks +We have run comprehensive benchmarks against RocksDB, Bolt and LMDB. The +benchmarking code, and the detailed logs for the benchmarks can be found in the +[badger-bench] repo. More explanation, including graphs can be found the blog posts (linked +above). + +[badger-bench]: https://github.com/dgraph-io/badger-bench + +## Other Projects Using Badger +Below is a list of known projects that use Badger: + +* [0-stor](https://github.com/zero-os/0-stor) - Single device object store. +* [Dgraph](https://github.com/dgraph-io/dgraph) - Distributed graph database. +* [Dispatch Protocol](https://github.com/dispatchlabs/disgo) - Blockchain protocol for distributed application data analytics. +* [Sandglass](https://github.com/celrenheit/sandglass) - distributed, horizontally scalable, persistent, time sorted message queue. +* [Usenet Express](https://usenetexpress.com/) - Serving over 300TB of data with Badger. +* [go-ipfs](https://github.com/ipfs/go-ipfs) - Go client for the InterPlanetary File System (IPFS), a new hypermedia distribution protocol. +* [gorush](https://github.com/appleboy/gorush) - A push notification server written in Go. +* [emitter](https://github.com/emitter-io/emitter) - Scalable, low latency, distributed pub/sub broker with message storage, uses MQTT, gossip and badger. +* [GarageMQ](https://github.com/valinurovam/garagemq) - AMQP server written in Go. +* [RedixDB](https://alash3al.github.io/redix/) - A real-time persistent key-value store with the same redis protocol. +* [BBVA](https://github.com/BBVA/raft-badger) - Raft backend implementation using BadgerDB for Hashicorp raft. +* [Riot](https://github.com/go-ego/riot) - An open-source, distributed search engine. +* [Fantom](https://github.com/Fantom-foundation/go-lachesis) - aBFT Consensus platform for distributed applications. +* [decred](https://github.com/decred/dcrdata) - An open, progressive, and self-funding cryptocurrency with a system of community-based governance integrated into its blockchain. +* [OpenNetSys](https://github.com/opennetsys/c3-go) - Create useful dApps in any software language. +* [HoneyTrap](https://github.com/honeytrap/honeytrap) - An extensible and opensource system for running, monitoring and managing honeypots. +* [Insolar](https://github.com/insolar/insolar) - Enterprise-ready blockchain platform. +* [IoTeX](https://github.com/iotexproject/iotex-core) - The next generation of the decentralized network for IoT powered by scalability- and privacy-centric blockchains. +* [go-sessions](https://github.com/kataras/go-sessions) - The sessions manager for Go net/http and fasthttp. +* [Babble](https://github.com/mosaicnetworks/babble) - BFT Consensus platform for distributed applications. +* [Tormenta](https://github.com/jpincas/tormenta) - Embedded object-persistence layer / simple JSON database for Go projects. +* [BadgerHold](https://github.com/timshannon/badgerhold) - An embeddable NoSQL store for querying Go types built on Badger +* [Goblero](https://github.com/didil/goblero) - Pure Go embedded persistent job queue backed by BadgerDB +* [Surfline](https://www.surfline.com) - Serving global wave and weather forecast data with Badger. +* [Cete](https://github.com/mosuka/cete) - Simple and highly available distributed key-value store built on Badger. Makes it easy bringing up a cluster of Badger with Raft consensus algorithm by hashicorp/raft. + +If you are using Badger in a project please send a pull request to add it to the list. + +## Frequently Asked Questions +- **My writes are getting stuck. Why?** + +**Update: With the new `Value(func(v []byte))` API, this deadlock can no longer +happen.** + +The following is true for users on Badger v1.x. + +This can happen if a long running iteration with `Prefetch` is set to false, but +a `Item::Value` call is made internally in the loop. That causes Badger to +acquire read locks over the value log files to avoid value log GC removing the +file from underneath. As a side effect, this also blocks a new value log GC +file from being created, when the value log file boundary is hit. + +Please see Github issues [#293](https://github.com/dgraph-io/badger/issues/293) +and [#315](https://github.com/dgraph-io/badger/issues/315). + +There are multiple workarounds during iteration: + +1. Use `Item::ValueCopy` instead of `Item::Value` when retrieving value. +1. Set `Prefetch` to true. Badger would then copy over the value and release the + file lock immediately. +1. When `Prefetch` is false, don't call `Item::Value` and do a pure key-only + iteration. This might be useful if you just want to delete a lot of keys. +1. Do the writes in a separate transaction after the reads. + +- **My writes are really slow. Why?** + +Are you creating a new transaction for every single key update, and waiting for +it to `Commit` fully before creating a new one? This will lead to very low +throughput. + +We have created `WriteBatch` API which provides a way to batch up +many updates into a single transaction and `Commit` that transaction using +callbacks to avoid blocking. This amortizes the cost of a transaction really +well, and provides the most efficient way to do bulk writes. + +```go +wb := db.NewWriteBatch() +defer wb.Cancel() + +for i := 0; i < N; i++ { + err := wb.Set(key(i), value(i), 0) // Will create txns as needed. + handle(err) +} +handle(wb.Flush()) // Wait for all txns to finish. +``` + +Note that `WriteBatch` API does not allow any reads. For read-modify-write +workloads, you should be using the `Transaction` API. + +- **I don't see any disk write. Why?** + +If you're using Badger with `SyncWrites=false`, then your writes might not be written to value log +and won't get synced to disk immediately. Writes to LSM tree are done inmemory first, before they +get compacted to disk. The compaction would only happen once `MaxTableSize` has been reached. So, if +you're doing a few writes and then checking, you might not see anything on disk. Once you `Close` +the database, you'll see these writes on disk. + +- **Reverse iteration doesn't give me the right results.** + +Just like forward iteration goes to the first key which is equal or greater than the SEEK key, reverse iteration goes to the first key which is equal or lesser than the SEEK key. Therefore, SEEK key would not be part of the results. You can typically add a `0xff` byte as a suffix to the SEEK key to include it in the results. See the following issues: [#436](https://github.com/dgraph-io/badger/issues/436) and [#347](https://github.com/dgraph-io/badger/issues/347). + +- **Which instances should I use for Badger?** + +We recommend using instances which provide local SSD storage, without any limit +on the maximum IOPS. In AWS, these are storage optimized instances like i3. They +provide local SSDs which clock 100K IOPS over 4KB blocks easily. + +- **I'm getting a closed channel error. Why?** + +``` +panic: close of closed channel +panic: send on closed channel +``` + +If you're seeing panics like above, this would be because you're operating on a closed DB. This can happen, if you call `Close()` before sending a write, or multiple times. You should ensure that you only call `Close()` once, and all your read/write operations finish before closing. + +- **Are there any Go specific settings that I should use?** + +We *highly* recommend setting a high number for GOMAXPROCS, which allows Go to +observe the full IOPS throughput provided by modern SSDs. In Dgraph, we have set +it to 128. For more details, [see this +thread](https://groups.google.com/d/topic/golang-nuts/jPb_h3TvlKE/discussion). + +- **Are there any linux specific settings that I should use?** + +We recommend setting max file descriptors to a high number depending upon the expected size of you data. + +## Contact +- Please use [discuss.dgraph.io](https://discuss.dgraph.io) for questions, feature requests and discussions. +- Please use [Github issue tracker](https://github.com/dgraph-io/badger/issues) for filing bugs or feature requests. +- Join [![Slack Status](http://slack.dgraph.io/badge.svg)](http://slack.dgraph.io). +- Follow us on Twitter [@dgraphlabs](https://twitter.com/dgraphlabs). + diff --git a/vendor/github.com/dgraph-io/badger/appveyor.yml b/vendor/github.com/dgraph-io/badger/appveyor.yml new file mode 100644 index 00000000..79dac338 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/appveyor.yml @@ -0,0 +1,48 @@ +# version format +version: "{build}" + +# Operating system (build VM template) +os: Windows Server 2012 R2 + +# Platform. +platform: x64 + +clone_folder: c:\gopath\src\github.com\dgraph-io\badger + +# Environment variables +environment: + GOVERSION: 1.8.3 + GOPATH: c:\gopath + +# scripts that run after cloning repository +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version + - go env + - python --version + +# To run your custom scripts instead of automatic MSBuild +build_script: + # We need to disable firewall - https://github.com/appveyor/ci/issues/1579#issuecomment-309830648 + - ps: Disable-NetFirewallRule -DisplayName 'File and Printer Sharing (SMB-Out)' + - cd c:\gopath\src\github.com\dgraph-io\badger + - git branch + - go get -t ./... + +# To run your custom scripts instead of automatic tests +test_script: + # Unit tests + - ps: Add-AppveyorTest "Unit Tests" -Outcome Running + - go test -v github.com/dgraph-io/badger/... + - go test -v -vlog_mmap=false github.com/dgraph-io/badger/... + - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed + +notifications: + - provider: Email + to: + - pawan@dgraph.io + on_build_failure: true + on_build_status_changed: true +# to disable deployment +deploy: off + diff --git a/vendor/github.com/dgraph-io/badger/backup.go b/vendor/github.com/dgraph-io/badger/backup.go new file mode 100644 index 00000000..0bc3b328 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/backup.go @@ -0,0 +1,237 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bufio" + "bytes" + "context" + "encoding/binary" + "io" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/y" +) + +// Backup is a wrapper function over Stream.Backup to generate full and incremental backups of the +// DB. For more control over how many goroutines are used to generate the backup, or if you wish to +// backup only a certain range of keys, use Stream.Backup directly. +func (db *DB) Backup(w io.Writer, since uint64) (uint64, error) { + stream := db.NewStream() + stream.LogPrefix = "DB.Backup" + return stream.Backup(w, since) +} + +// Backup dumps a protobuf-encoded list of all entries in the database into the +// given writer, that are newer than the specified version. It returns a +// timestamp indicating when the entries were dumped which can be passed into a +// later invocation to generate an incremental dump, of entries that have been +// added/modified since the last invocation of Stream.Backup(). +// +// This can be used to backup the data in a database at a given point in time. +func (stream *Stream) Backup(w io.Writer, since uint64) (uint64, error) { + stream.KeyToList = func(key []byte, itr *Iterator) (*pb.KVList, error) { + list := &pb.KVList{} + for ; itr.Valid(); itr.Next() { + item := itr.Item() + if !bytes.Equal(item.Key(), key) { + return list, nil + } + if item.Version() < since { + // Ignore versions less than given timestamp, or skip older + // versions of the given key. + return list, nil + } + + var valCopy []byte + if !item.IsDeletedOrExpired() { + // No need to copy value, if item is deleted or expired. + var err error + valCopy, err = item.ValueCopy(nil) + if err != nil { + stream.db.opt.Errorf("Key [%x, %d]. Error while fetching value [%v]\n", + item.Key(), item.Version(), err) + return nil, err + } + } + + // clear txn bits + meta := item.meta &^ (bitTxn | bitFinTxn) + kv := &pb.KV{ + Key: item.KeyCopy(nil), + Value: valCopy, + UserMeta: []byte{item.UserMeta()}, + Version: item.Version(), + ExpiresAt: item.ExpiresAt(), + Meta: []byte{meta}, + } + list.Kv = append(list.Kv, kv) + + switch { + case item.DiscardEarlierVersions(): + // If we need to discard earlier versions of this item, add a delete + // marker just below the current version. + list.Kv = append(list.Kv, &pb.KV{ + Key: item.KeyCopy(nil), + Version: item.Version() - 1, + Meta: []byte{bitDelete}, + }) + return list, nil + + case item.IsDeletedOrExpired(): + return list, nil + } + } + return list, nil + } + + var maxVersion uint64 + stream.Send = func(list *pb.KVList) error { + for _, kv := range list.Kv { + if maxVersion < kv.Version { + maxVersion = kv.Version + } + } + return writeTo(list, w) + } + + if err := stream.Orchestrate(context.Background()); err != nil { + return 0, err + } + return maxVersion, nil +} + +func writeTo(list *pb.KVList, w io.Writer) error { + if err := binary.Write(w, binary.LittleEndian, uint64(list.Size())); err != nil { + return err + } + buf, err := list.Marshal() + if err != nil { + return err + } + _, err = w.Write(buf) + return err +} + +type loader struct { + db *DB + throttle *y.Throttle + entries []*Entry +} + +func (db *DB) newLoader(maxPendingWrites int) *loader { + return &loader{ + db: db, + throttle: y.NewThrottle(maxPendingWrites), + } +} + +func (l *loader) set(kv *pb.KV) error { + var userMeta, meta byte + if len(kv.UserMeta) > 0 { + userMeta = kv.UserMeta[0] + } + if len(kv.Meta) > 0 { + meta = kv.Meta[0] + } + + l.entries = append(l.entries, &Entry{ + Key: y.KeyWithTs(kv.Key, kv.Version), + Value: kv.Value, + UserMeta: userMeta, + ExpiresAt: kv.ExpiresAt, + meta: meta, + }) + if len(l.entries) >= 1000 { + return l.send() + } + return nil +} + +func (l *loader) send() error { + if err := l.throttle.Do(); err != nil { + return err + } + l.db.batchSetAsync(l.entries, func(err error) { + l.throttle.Done(err) + }) + + l.entries = make([]*Entry, 0, 1000) + return nil +} + +func (l *loader) finish() error { + if len(l.entries) > 0 { + if err := l.send(); err != nil { + return err + } + } + return l.throttle.Finish() +} + +// Load reads a protobuf-encoded list of all entries from a reader and writes +// them to the database. This can be used to restore the database from a backup +// made by calling DB.Backup(). +// +// DB.Load() should be called on a database that is not running any other +// concurrent transactions while it is running. +func (db *DB) Load(r io.Reader, maxPendingWrites int) error { + br := bufio.NewReaderSize(r, 16<<10) + unmarshalBuf := make([]byte, 1<<10) + + ldr := db.newLoader(maxPendingWrites) + for { + var sz uint64 + err := binary.Read(br, binary.LittleEndian, &sz) + if err == io.EOF { + break + } else if err != nil { + return err + } + + if cap(unmarshalBuf) < int(sz) { + unmarshalBuf = make([]byte, sz) + } + + if _, err = io.ReadFull(br, unmarshalBuf[:sz]); err != nil { + return err + } + + list := &pb.KVList{} + if err := list.Unmarshal(unmarshalBuf[:sz]); err != nil { + return err + } + + for _, kv := range list.Kv { + if err := ldr.set(kv); err != nil { + return err + } + + // Update nextTxnTs, memtable stores this + // timestamp in badger head when flushed. + if kv.Version >= db.orc.nextTxnTs { + db.orc.nextTxnTs = kv.Version + 1 + } + } + } + + if err := ldr.finish(); err != nil { + return err + } + db.orc.txnMark.Done(db.orc.nextTxnTs - 1) + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/batch.go b/vendor/github.com/dgraph-io/badger/batch.go new file mode 100644 index 00000000..bfbc239b --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/batch.go @@ -0,0 +1,170 @@ +/* + * Copyright 2018 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "sync" + "time" + + "github.com/dgraph-io/badger/y" +) + +// WriteBatch holds the necessary info to perform batched writes. +type WriteBatch struct { + sync.Mutex + txn *Txn + db *DB + throttle *y.Throttle + err error +} + +// NewWriteBatch creates a new WriteBatch. This provides a way to conveniently do a lot of writes, +// batching them up as tightly as possible in a single transaction and using callbacks to avoid +// waiting for them to commit, thus achieving good performance. This API hides away the logic of +// creating and committing transactions. Due to the nature of SSI guaratees provided by Badger, +// blind writes can never encounter transaction conflicts (ErrConflict). +func (db *DB) NewWriteBatch() *WriteBatch { + return &WriteBatch{ + db: db, + txn: db.newTransaction(true, true), + throttle: y.NewThrottle(16), + } +} + +// SetMaxPendingTxns sets a limit on maximum number of pending transactions while writing batches. +// This function should be called before using WriteBatch. Default value of MaxPendingTxns is +// 16 to minimise memory usage. +func (wb *WriteBatch) SetMaxPendingTxns(max int) { + wb.throttle = y.NewThrottle(max) +} + +// Cancel function must be called if there's a chance that Flush might not get +// called. If neither Flush or Cancel is called, the transaction oracle would +// never get a chance to clear out the row commit timestamp map, thus causing an +// unbounded memory consumption. Typically, you can call Cancel as a defer +// statement right after NewWriteBatch is called. +// +// Note that any committed writes would still go through despite calling Cancel. +func (wb *WriteBatch) Cancel() { + if err := wb.throttle.Finish(); err != nil { + wb.db.opt.Errorf("WatchBatch.Cancel error while finishing: %v", err) + } + wb.txn.Discard() +} + +func (wb *WriteBatch) callback(err error) { + // sync.WaitGroup is thread-safe, so it doesn't need to be run inside wb.Lock. + defer wb.throttle.Done(err) + if err == nil { + return + } + + wb.Lock() + defer wb.Unlock() + if wb.err != nil { + return + } + wb.err = err +} + +// SetEntry is the equivalent of Txn.SetEntry. +func (wb *WriteBatch) SetEntry(e *Entry) error { + wb.Lock() + defer wb.Unlock() + + if err := wb.txn.SetEntry(e); err != ErrTxnTooBig { + return err + } + // Txn has reached it's zenith. Commit now. + if cerr := wb.commit(); cerr != nil { + return cerr + } + // This time the error must not be ErrTxnTooBig, otherwise, we make the + // error permanent. + if err := wb.txn.SetEntry(e); err != nil { + wb.err = err + return err + } + return nil +} + +// Set is equivalent of Txn.SetWithMeta. +func (wb *WriteBatch) Set(k, v []byte, meta byte) error { + e := &Entry{Key: k, Value: v, UserMeta: meta} + return wb.SetEntry(e) +} + +// SetWithTTL is equivalent of Txn.SetWithTTL. +func (wb *WriteBatch) SetWithTTL(key, val []byte, dur time.Duration) error { + expire := time.Now().Add(dur).Unix() + e := &Entry{Key: key, Value: val, ExpiresAt: uint64(expire)} + return wb.SetEntry(e) +} + +// Delete is equivalent of Txn.Delete. +func (wb *WriteBatch) Delete(k []byte) error { + wb.Lock() + defer wb.Unlock() + + if err := wb.txn.Delete(k); err != ErrTxnTooBig { + return err + } + if err := wb.commit(); err != nil { + return err + } + if err := wb.txn.Delete(k); err != nil { + wb.err = err + return err + } + return nil +} + +// Caller to commit must hold a write lock. +func (wb *WriteBatch) commit() error { + if wb.err != nil { + return wb.err + } + if err := wb.throttle.Do(); err != nil { + return err + } + wb.txn.CommitWith(wb.callback) + wb.txn = wb.db.newTransaction(true, true) + wb.txn.readTs = 0 // We're not reading anything. + return wb.err +} + +// Flush must be called at the end to ensure that any pending writes get committed to Badger. Flush +// returns any error stored by WriteBatch. +func (wb *WriteBatch) Flush() error { + wb.Lock() + _ = wb.commit() + wb.txn.Discard() + wb.Unlock() + + if err := wb.throttle.Finish(); err != nil { + return err + } + + return wb.err +} + +// Error returns any errors encountered so far. No commits would be run once an error is detected. +func (wb *WriteBatch) Error() error { + wb.Lock() + defer wb.Unlock() + return wb.err +} diff --git a/vendor/github.com/dgraph-io/badger/compaction.go b/vendor/github.com/dgraph-io/badger/compaction.go new file mode 100644 index 00000000..931d5666 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/compaction.go @@ -0,0 +1,210 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "fmt" + "log" + "math" + "sync" + + "golang.org/x/net/trace" + + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" +) + +type keyRange struct { + left []byte + right []byte + inf bool +} + +var infRange = keyRange{inf: true} + +func (r keyRange) String() string { + return fmt.Sprintf("[left=%x, right=%x, inf=%v]", r.left, r.right, r.inf) +} + +func (r keyRange) equals(dst keyRange) bool { + return bytes.Equal(r.left, dst.left) && + bytes.Equal(r.right, dst.right) && + r.inf == dst.inf +} + +func (r keyRange) overlapsWith(dst keyRange) bool { + if r.inf || dst.inf { + return true + } + + // If my left is greater than dst right, we have no overlap. + if y.CompareKeys(r.left, dst.right) > 0 { + return false + } + // If my right is less than dst left, we have no overlap. + if y.CompareKeys(r.right, dst.left) < 0 { + return false + } + // We have overlap. + return true +} + +func getKeyRange(tables []*table.Table) keyRange { + if len(tables) == 0 { + return keyRange{} + } + smallest := tables[0].Smallest() + biggest := tables[0].Biggest() + for i := 1; i < len(tables); i++ { + if y.CompareKeys(tables[i].Smallest(), smallest) < 0 { + smallest = tables[i].Smallest() + } + if y.CompareKeys(tables[i].Biggest(), biggest) > 0 { + biggest = tables[i].Biggest() + } + } + return keyRange{ + left: y.KeyWithTs(y.ParseKey(smallest), math.MaxUint64), + right: y.KeyWithTs(y.ParseKey(biggest), 0), + } +} + +type levelCompactStatus struct { + ranges []keyRange + delSize int64 +} + +func (lcs *levelCompactStatus) debug() string { + var b bytes.Buffer + for _, r := range lcs.ranges { + b.WriteString(r.String()) + } + return b.String() +} + +func (lcs *levelCompactStatus) overlapsWith(dst keyRange) bool { + for _, r := range lcs.ranges { + if r.overlapsWith(dst) { + return true + } + } + return false +} + +func (lcs *levelCompactStatus) remove(dst keyRange) bool { + final := lcs.ranges[:0] + var found bool + for _, r := range lcs.ranges { + if !r.equals(dst) { + final = append(final, r) + } else { + found = true + } + } + lcs.ranges = final + return found +} + +type compactStatus struct { + sync.RWMutex + levels []*levelCompactStatus +} + +func (cs *compactStatus) toLog(tr trace.Trace) { + cs.RLock() + defer cs.RUnlock() + + tr.LazyPrintf("Compaction status:") + for i, l := range cs.levels { + if l.debug() == "" { + continue + } + tr.LazyPrintf("[%d] %s", i, l.debug()) + } +} + +func (cs *compactStatus) overlapsWith(level int, this keyRange) bool { + cs.RLock() + defer cs.RUnlock() + + thisLevel := cs.levels[level] + return thisLevel.overlapsWith(this) +} + +func (cs *compactStatus) delSize(l int) int64 { + cs.RLock() + defer cs.RUnlock() + return cs.levels[l].delSize +} + +type thisAndNextLevelRLocked struct{} + +// compareAndAdd will check whether we can run this compactDef. That it doesn't overlap with any +// other running compaction. If it can be run, it would store this run in the compactStatus state. +func (cs *compactStatus) compareAndAdd(_ thisAndNextLevelRLocked, cd compactDef) bool { + cs.Lock() + defer cs.Unlock() + + level := cd.thisLevel.level + + y.AssertTruef(level < len(cs.levels)-1, "Got level %d. Max levels: %d", level, len(cs.levels)) + thisLevel := cs.levels[level] + nextLevel := cs.levels[level+1] + + if thisLevel.overlapsWith(cd.thisRange) { + return false + } + if nextLevel.overlapsWith(cd.nextRange) { + return false + } + // Check whether this level really needs compaction or not. Otherwise, we'll end up + // running parallel compactions for the same level. + // Update: We should not be checking size here. Compaction priority already did the size checks. + // Here we should just be executing the wish of others. + + thisLevel.ranges = append(thisLevel.ranges, cd.thisRange) + nextLevel.ranges = append(nextLevel.ranges, cd.nextRange) + thisLevel.delSize += cd.thisSize + return true +} + +func (cs *compactStatus) delete(cd compactDef) { + cs.Lock() + defer cs.Unlock() + + level := cd.thisLevel.level + y.AssertTruef(level < len(cs.levels)-1, "Got level %d. Max levels: %d", level, len(cs.levels)) + + thisLevel := cs.levels[level] + nextLevel := cs.levels[level+1] + + thisLevel.delSize -= cd.thisSize + found := thisLevel.remove(cd.thisRange) + found = nextLevel.remove(cd.nextRange) && found + + if !found { + this := cd.thisRange + next := cd.nextRange + fmt.Printf("Looking for: [%q, %q, %v] in this level.\n", this.left, this.right, this.inf) + fmt.Printf("This Level:\n%s\n", thisLevel.debug()) + fmt.Println() + fmt.Printf("Looking for: [%q, %q, %v] in next level.\n", next.left, next.right, next.inf) + fmt.Printf("Next Level:\n%s\n", nextLevel.debug()) + log.Fatal("keyRange not found") + } +} diff --git a/vendor/github.com/dgraph-io/badger/db.go b/vendor/github.com/dgraph-io/badger/db.go new file mode 100644 index 00000000..24e7b1a4 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/db.go @@ -0,0 +1,1479 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/hex" + "expvar" + "io" + "math" + "os" + "path/filepath" + "sort" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/options" + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/skl" + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" + humanize "github.com/dustin/go-humanize" + "github.com/pkg/errors" + "golang.org/x/net/trace" +) + +var ( + badgerPrefix = []byte("!badger!") // Prefix for internal keys used by badger. + head = []byte("!badger!head") // For storing value offset for replay. + txnKey = []byte("!badger!txn") // For indicating end of entries in txn. + badgerMove = []byte("!badger!move") // For key-value pairs which got moved during GC. + lfDiscardStatsKey = []byte("!badger!discard") // For storing lfDiscardStats +) + +type closers struct { + updateSize *y.Closer + compactors *y.Closer + memtable *y.Closer + writes *y.Closer + valueGC *y.Closer + pub *y.Closer +} + +type callback func(kv *pb.KVList) + +// DB provides the various functions required to interact with Badger. +// DB is thread-safe. +type DB struct { + sync.RWMutex // Guards list of inmemory tables, not individual reads and writes. + + dirLockGuard *directoryLockGuard + // nil if Dir and ValueDir are the same + valueDirGuard *directoryLockGuard + + closers closers + elog trace.EventLog + mt *skl.Skiplist // Our latest (actively written) in-memory table + imm []*skl.Skiplist // Add here only AFTER pushing to flushChan. + opt Options + manifest *manifestFile + lc *levelsController + vlog valueLog + vhead valuePointer // less than or equal to a pointer to the last vlog value put into mt + writeCh chan *request + flushChan chan flushTask // For flushing memtables. + closeOnce sync.Once // For closing DB only once. + + // Number of log rotates since the last memtable flush. We will access this field via atomic + // functions. Since we are not going to use any 64bit atomic functions, there is no need for + // 64 bit alignment of this struct(see #311). + logRotates int32 + + blockWrites int32 + + orc *oracle + + pub *publisher +} + +const ( + kvWriteChCapacity = 1000 +) + +func (db *DB) replayFunction() func(Entry, valuePointer) error { + type txnEntry struct { + nk []byte + v y.ValueStruct + } + + var txn []txnEntry + var lastCommit uint64 + + toLSM := func(nk []byte, vs y.ValueStruct) { + for err := db.ensureRoomForWrite(); err != nil; err = db.ensureRoomForWrite() { + db.elog.Printf("Replay: Making room for writes") + time.Sleep(10 * time.Millisecond) + } + db.mt.Put(nk, vs) + } + + first := true + return func(e Entry, vp valuePointer) error { // Function for replaying. + if first { + db.elog.Printf("First key=%q\n", e.Key) + } + first = false + + if db.orc.nextTxnTs < y.ParseTs(e.Key) { + db.orc.nextTxnTs = y.ParseTs(e.Key) + } + + nk := make([]byte, len(e.Key)) + copy(nk, e.Key) + var nv []byte + meta := e.meta + if db.shouldWriteValueToLSM(e) { + nv = make([]byte, len(e.Value)) + copy(nv, e.Value) + } else { + nv = make([]byte, vptrSize) + vp.Encode(nv) + meta = meta | bitValuePointer + } + + v := y.ValueStruct{ + Value: nv, + Meta: meta, + UserMeta: e.UserMeta, + ExpiresAt: e.ExpiresAt, + } + + if e.meta&bitFinTxn > 0 { + txnTs, err := strconv.ParseUint(string(e.Value), 10, 64) + if err != nil { + return errors.Wrapf(err, "Unable to parse txn fin: %q", e.Value) + } + y.AssertTrue(lastCommit == txnTs) + y.AssertTrue(len(txn) > 0) + // Got the end of txn. Now we can store them. + for _, t := range txn { + toLSM(t.nk, t.v) + } + txn = txn[:0] + lastCommit = 0 + + } else if e.meta&bitTxn > 0 { + txnTs := y.ParseTs(nk) + if lastCommit == 0 { + lastCommit = txnTs + } + if lastCommit != txnTs { + db.opt.Warningf("Found an incomplete txn at timestamp %d. Discarding it.\n", + lastCommit) + txn = txn[:0] + lastCommit = txnTs + } + te := txnEntry{nk: nk, v: v} + txn = append(txn, te) + + } else { + // This entry is from a rewrite. + toLSM(nk, v) + + // We shouldn't get this entry in the middle of a transaction. + y.AssertTrue(lastCommit == 0) + y.AssertTrue(len(txn) == 0) + } + return nil + } +} + +// Open returns a new DB object. +func Open(opt Options) (db *DB, err error) { + opt.maxBatchSize = (15 * opt.MaxTableSize) / 100 + opt.maxBatchCount = opt.maxBatchSize / int64(skl.MaxNodeSize) + + if opt.ValueThreshold > math.MaxUint16-16 { + return nil, ErrValueThreshold + } + + if opt.ReadOnly { + // Can't truncate if the DB is read only. + opt.Truncate = false + // Do not perform compaction in read only mode. + opt.CompactL0OnClose = false + } + + for _, path := range []string{opt.Dir, opt.ValueDir} { + dirExists, err := exists(path) + if err != nil { + return nil, y.Wrapf(err, "Invalid Dir: %q", path) + } + if !dirExists { + if opt.ReadOnly { + return nil, y.Wrapf(err, "Cannot find Dir for read-only open: %q", path) + } + // Try to create the directory + err = os.Mkdir(path, 0700) + if err != nil { + return nil, y.Wrapf(err, "Error Creating Dir: %q", path) + } + } + } + absDir, err := filepath.Abs(opt.Dir) + if err != nil { + return nil, err + } + absValueDir, err := filepath.Abs(opt.ValueDir) + if err != nil { + return nil, err + } + var dirLockGuard, valueDirLockGuard *directoryLockGuard + dirLockGuard, err = acquireDirectoryLock(opt.Dir, lockFile, opt.ReadOnly) + if err != nil { + return nil, err + } + defer func() { + if dirLockGuard != nil { + _ = dirLockGuard.release() + } + }() + if absValueDir != absDir { + valueDirLockGuard, err = acquireDirectoryLock(opt.ValueDir, lockFile, opt.ReadOnly) + if err != nil { + return nil, err + } + defer func() { + if valueDirLockGuard != nil { + _ = valueDirLockGuard.release() + } + }() + } + if !(opt.ValueLogFileSize <= 2<<30 && opt.ValueLogFileSize >= 1<<20) { + return nil, ErrValueLogSize + } + if !(opt.ValueLogLoadingMode == options.FileIO || + opt.ValueLogLoadingMode == options.MemoryMap) { + return nil, ErrInvalidLoadingMode + } + manifestFile, manifest, err := openOrCreateManifestFile(opt.Dir, opt.ReadOnly) + if err != nil { + return nil, err + } + defer func() { + if manifestFile != nil { + _ = manifestFile.close() + } + }() + + db = &DB{ + imm: make([]*skl.Skiplist, 0, opt.NumMemtables), + flushChan: make(chan flushTask, opt.NumMemtables), + writeCh: make(chan *request, kvWriteChCapacity), + opt: opt, + manifest: manifestFile, + elog: trace.NewEventLog("Badger", "DB"), + dirLockGuard: dirLockGuard, + valueDirGuard: valueDirLockGuard, + orc: newOracle(opt), + pub: newPublisher(), + } + + // Calculate initial size. + db.calculateSize() + db.closers.updateSize = y.NewCloser(1) + go db.updateSize(db.closers.updateSize) + db.mt = skl.NewSkiplist(arenaSize(opt)) + + // newLevelsController potentially loads files in directory. + if db.lc, err = newLevelsController(db, &manifest); err != nil { + return nil, err + } + + if !opt.ReadOnly { + db.closers.compactors = y.NewCloser(1) + db.lc.startCompact(db.closers.compactors) + + db.closers.memtable = y.NewCloser(1) + go db.flushMemtable(db.closers.memtable) // Need levels controller to be up. + } + + headKey := y.KeyWithTs(head, math.MaxUint64) + // Need to pass with timestamp, lsm get removes the last 8 bytes and compares key + vs, err := db.get(headKey) + if err != nil { + return nil, errors.Wrap(err, "Retrieving head") + } + db.orc.nextTxnTs = vs.Version + var vptr valuePointer + if len(vs.Value) > 0 { + vptr.Decode(vs.Value) + } + + replayCloser := y.NewCloser(1) + go db.doWrites(replayCloser) + + if err = db.vlog.open(db, vptr, db.replayFunction()); err != nil { + return db, err + } + replayCloser.SignalAndWait() // Wait for replay to be applied first. + + // Let's advance nextTxnTs to one more than whatever we observed via + // replaying the logs. + db.orc.txnMark.Done(db.orc.nextTxnTs) + // In normal mode, we must update readMark so older versions of keys can be removed during + // compaction when run in offline mode via the flatten tool. + db.orc.readMark.Done(db.orc.nextTxnTs) + db.orc.incrementNextTs() + + db.writeCh = make(chan *request, kvWriteChCapacity) + db.closers.writes = y.NewCloser(1) + go db.doWrites(db.closers.writes) + + db.closers.valueGC = y.NewCloser(1) + go db.vlog.waitOnGC(db.closers.valueGC) + + db.closers.pub = y.NewCloser(1) + go db.pub.listenForUpdates(db.closers.pub) + + valueDirLockGuard = nil + dirLockGuard = nil + manifestFile = nil + return db, nil +} + +// Close closes a DB. It's crucial to call it to ensure all the pending updates make their way to +// disk. Calling DB.Close() multiple times would still only close the DB once. +func (db *DB) Close() error { + var err error + db.closeOnce.Do(func() { + err = db.close() + }) + return err +} + +func (db *DB) close() (err error) { + db.elog.Printf("Closing database") + atomic.StoreInt32(&db.blockWrites, 1) + + // Stop value GC first. + db.closers.valueGC.SignalAndWait() + + // Stop writes next. + db.closers.writes.SignalAndWait() + + db.closers.pub.SignalAndWait() + + // Now close the value log. + if vlogErr := db.vlog.Close(); vlogErr != nil { + err = errors.Wrap(vlogErr, "DB.Close") + } + + // Make sure that block writer is done pushing stuff into memtable! + // Otherwise, you will have a race condition: we are trying to flush memtables + // and remove them completely, while the block / memtable writer is still + // trying to push stuff into the memtable. This will also resolve the value + // offset problem: as we push into memtable, we update value offsets there. + if !db.mt.Empty() { + db.elog.Printf("Flushing memtable") + for { + pushedFlushTask := func() bool { + db.Lock() + defer db.Unlock() + y.AssertTrue(db.mt != nil) + select { + case db.flushChan <- flushTask{mt: db.mt, vptr: db.vhead}: + db.imm = append(db.imm, db.mt) // Flusher will attempt to remove this from s.imm. + db.mt = nil // Will segfault if we try writing! + db.elog.Printf("pushed to flush chan\n") + return true + default: + // If we fail to push, we need to unlock and wait for a short while. + // The flushing operation needs to update s.imm. Otherwise, we have a deadlock. + // TODO: Think about how to do this more cleanly, maybe without any locks. + } + return false + }() + if pushedFlushTask { + break + } + time.Sleep(10 * time.Millisecond) + } + } + db.stopCompactions() + + // Force Compact L0 + // We don't need to care about cstatus since no parallel compaction is running. + if db.opt.CompactL0OnClose { + err := db.lc.doCompact(compactionPriority{level: 0, score: 1.73}) + switch err { + case errFillTables: + // This error only means that there might be enough tables to do a compaction. So, we + // should not report it to the end user to avoid confusing them. + case nil: + db.opt.Infof("Force compaction on level 0 done") + default: + db.opt.Warningf("While forcing compaction on level 0: %v", err) + } + } + + if lcErr := db.lc.close(); err == nil { + err = errors.Wrap(lcErr, "DB.Close") + } + db.elog.Printf("Waiting for closer") + db.closers.updateSize.SignalAndWait() + db.orc.Stop() + + db.elog.Finish() + + if db.dirLockGuard != nil { + if guardErr := db.dirLockGuard.release(); err == nil { + err = errors.Wrap(guardErr, "DB.Close") + } + } + if db.valueDirGuard != nil { + if guardErr := db.valueDirGuard.release(); err == nil { + err = errors.Wrap(guardErr, "DB.Close") + } + } + if manifestErr := db.manifest.close(); err == nil { + err = errors.Wrap(manifestErr, "DB.Close") + } + + // Fsync directories to ensure that lock file, and any other removed files whose directory + // we haven't specifically fsynced, are guaranteed to have their directory entry removal + // persisted to disk. + if syncErr := syncDir(db.opt.Dir); err == nil { + err = errors.Wrap(syncErr, "DB.Close") + } + if syncErr := syncDir(db.opt.ValueDir); err == nil { + err = errors.Wrap(syncErr, "DB.Close") + } + + return err +} + +const ( + lockFile = "LOCK" +) + +// Sync syncs database content to disk. This function provides +// more control to user to sync data whenever required. +func (db *DB) Sync() error { + return db.vlog.sync(math.MaxUint32) +} + +// When you create or delete a file, you have to ensure the directory entry for the file is synced +// in order to guarantee the file is visible (if the system crashes). (See the man page for fsync, +// or see https://github.com/coreos/etcd/issues/6368 for an example.) +func syncDir(dir string) error { + f, err := openDir(dir) + if err != nil { + return errors.Wrapf(err, "While opening directory: %s.", dir) + } + err = f.Sync() + closeErr := f.Close() + if err != nil { + return errors.Wrapf(err, "While syncing directory: %s.", dir) + } + return errors.Wrapf(closeErr, "While closing directory: %s.", dir) +} + +// getMemtables returns the current memtables and get references. +func (db *DB) getMemTables() ([]*skl.Skiplist, func()) { + db.RLock() + defer db.RUnlock() + + tables := make([]*skl.Skiplist, len(db.imm)+1) + + // Get mutable memtable. + tables[0] = db.mt + tables[0].IncrRef() + + // Get immutable memtables. + last := len(db.imm) - 1 + for i := range db.imm { + tables[i+1] = db.imm[last-i] + tables[i+1].IncrRef() + } + return tables, func() { + for _, tbl := range tables { + tbl.DecrRef() + } + } +} + +// get returns the value in memtable or disk for given key. +// Note that value will include meta byte. +// +// IMPORTANT: We should never write an entry with an older timestamp for the same key, We need to +// maintain this invariant to search for the latest value of a key, or else we need to search in all +// tables and find the max version among them. To maintain this invariant, we also need to ensure +// that all versions of a key are always present in the same table from level 1, because compaction +// can push any table down. +// +// Update (Sep 22, 2018): To maintain the above invariant, and to allow keys to be moved from one +// value log to another (while reclaiming space during value log GC), we have logically moved this +// need to write "old versions after new versions" to the badgerMove keyspace. Thus, for normal +// gets, we can stop going down the LSM tree once we find any version of the key (note however that +// we will ALWAYS skip versions with ts greater than the key version). However, if that key has +// been moved, then for the corresponding movekey, we'll look through all the levels of the tree +// to ensure that we pick the highest version of the movekey present. +func (db *DB) get(key []byte) (y.ValueStruct, error) { + tables, decr := db.getMemTables() // Lock should be released. + defer decr() + + var maxVs *y.ValueStruct + var version uint64 + if bytes.HasPrefix(key, badgerMove) { + // If we are checking badgerMove key, we should look into all the + // levels, so we can pick up the newer versions, which might have been + // compacted down the tree. + maxVs = &y.ValueStruct{} + version = y.ParseTs(key) + } + + y.NumGets.Add(1) + for i := 0; i < len(tables); i++ { + vs := tables[i].Get(key) + y.NumMemtableGets.Add(1) + if vs.Meta == 0 && vs.Value == nil { + continue + } + // Found a version of the key. For user keyspace, return immediately. For move keyspace, + // continue iterating, unless we found a version == given key version. + if maxVs == nil || vs.Version == version { + return vs, nil + } + if maxVs.Version < vs.Version { + *maxVs = vs + } + } + return db.lc.get(key, maxVs) +} + +func (db *DB) updateHead(ptrs []valuePointer) { + var ptr valuePointer + for i := len(ptrs) - 1; i >= 0; i-- { + p := ptrs[i] + if !p.IsZero() { + ptr = p + break + } + } + if ptr.IsZero() { + return + } + + db.Lock() + defer db.Unlock() + y.AssertTrue(!ptr.Less(db.vhead)) + db.vhead = ptr +} + +var requestPool = sync.Pool{ + New: func() interface{} { + return new(request) + }, +} + +func (db *DB) shouldWriteValueToLSM(e Entry) bool { + return len(e.Value) < db.opt.ValueThreshold +} + +func (db *DB) writeToLSM(b *request) error { + if len(b.Ptrs) != len(b.Entries) { + return errors.Errorf("Ptrs and Entries don't match: %+v", b) + } + + for i, entry := range b.Entries { + if entry.meta&bitFinTxn != 0 { + continue + } + if db.shouldWriteValueToLSM(*entry) { // Will include deletion / tombstone case. + db.mt.Put(entry.Key, + y.ValueStruct{ + Value: entry.Value, + Meta: entry.meta, + UserMeta: entry.UserMeta, + ExpiresAt: entry.ExpiresAt, + }) + } else { + var offsetBuf [vptrSize]byte + db.mt.Put(entry.Key, + y.ValueStruct{ + Value: b.Ptrs[i].Encode(offsetBuf[:]), + Meta: entry.meta | bitValuePointer, + UserMeta: entry.UserMeta, + ExpiresAt: entry.ExpiresAt, + }) + } + } + return nil +} + +// writeRequests is called serially by only one goroutine. +func (db *DB) writeRequests(reqs []*request) error { + if len(reqs) == 0 { + return nil + } + + done := func(err error) { + for _, r := range reqs { + r.Err = err + r.Wg.Done() + } + } + db.elog.Printf("writeRequests called. Writing to value log") + + err := db.vlog.write(reqs) + if err != nil { + done(err) + return err + } + + db.elog.Printf("Sending updates to subscribers") + db.pub.sendUpdates(reqs) + db.elog.Printf("Writing to memtable") + var count int + for _, b := range reqs { + if len(b.Entries) == 0 { + continue + } + count += len(b.Entries) + var i uint64 + for err = db.ensureRoomForWrite(); err == errNoRoom; err = db.ensureRoomForWrite() { + i++ + if i%100 == 0 { + db.elog.Printf("Making room for writes") + } + // We need to poll a bit because both hasRoomForWrite and the flusher need access to s.imm. + // When flushChan is full and you are blocked there, and the flusher is trying to update s.imm, + // you will get a deadlock. + time.Sleep(10 * time.Millisecond) + } + if err != nil { + done(err) + return errors.Wrap(err, "writeRequests") + } + if err := db.writeToLSM(b); err != nil { + done(err) + return errors.Wrap(err, "writeRequests") + } + db.updateHead(b.Ptrs) + } + done(nil) + db.elog.Printf("%d entries written", count) + return nil +} + +func (db *DB) sendToWriteCh(entries []*Entry) (*request, error) { + if atomic.LoadInt32(&db.blockWrites) == 1 { + return nil, ErrBlockedWrites + } + var count, size int64 + for _, e := range entries { + size += int64(e.estimateSize(db.opt.ValueThreshold)) + count++ + } + if count >= db.opt.maxBatchCount || size >= db.opt.maxBatchSize { + return nil, ErrTxnTooBig + } + + // We can only service one request because we need each txn to be stored in a contigous section. + // Txns should not interleave among other txns or rewrites. + req := requestPool.Get().(*request) + req.Entries = entries + req.Wg = sync.WaitGroup{} + req.Wg.Add(1) + req.IncrRef() // for db write + req.IncrRef() // for publisher updates + db.writeCh <- req // Handled in doWrites. + y.NumPuts.Add(int64(len(entries))) + + return req, nil +} + +func (db *DB) doWrites(lc *y.Closer) { + defer lc.Done() + pendingCh := make(chan struct{}, 1) + + writeRequests := func(reqs []*request) { + if err := db.writeRequests(reqs); err != nil { + db.opt.Errorf("writeRequests: %v", err) + } + <-pendingCh + } + + // This variable tracks the number of pending writes. + reqLen := new(expvar.Int) + y.PendingWrites.Set(db.opt.Dir, reqLen) + + reqs := make([]*request, 0, 10) + for { + var r *request + select { + case r = <-db.writeCh: + case <-lc.HasBeenClosed(): + goto closedCase + } + + for { + reqs = append(reqs, r) + reqLen.Set(int64(len(reqs))) + + if len(reqs) >= 3*kvWriteChCapacity { + pendingCh <- struct{}{} // blocking. + goto writeCase + } + + select { + // Either push to pending, or continue to pick from writeCh. + case r = <-db.writeCh: + case pendingCh <- struct{}{}: + goto writeCase + case <-lc.HasBeenClosed(): + goto closedCase + } + } + + closedCase: + close(db.writeCh) + for r := range db.writeCh { // Flush the channel. + reqs = append(reqs, r) + } + + pendingCh <- struct{}{} // Push to pending before doing a write. + writeRequests(reqs) + return + + writeCase: + go writeRequests(reqs) + reqs = make([]*request, 0, 10) + reqLen.Set(0) + } +} + +// batchSet applies a list of badger.Entry. If a request level error occurs it +// will be returned. +// Check(kv.BatchSet(entries)) +func (db *DB) batchSet(entries []*Entry) error { + req, err := db.sendToWriteCh(entries) + if err != nil { + return err + } + + return req.Wait() +} + +// batchSetAsync is the asynchronous version of batchSet. It accepts a callback +// function which is called when all the sets are complete. If a request level +// error occurs, it will be passed back via the callback. +// err := kv.BatchSetAsync(entries, func(err error)) { +// Check(err) +// } +func (db *DB) batchSetAsync(entries []*Entry, f func(error)) error { + req, err := db.sendToWriteCh(entries) + if err != nil { + return err + } + go func() { + err := req.Wait() + // Write is complete. Let's call the callback function now. + f(err) + }() + return nil +} + +var errNoRoom = errors.New("No room for write") + +// ensureRoomForWrite is always called serially. +func (db *DB) ensureRoomForWrite() error { + var err error + db.Lock() + defer db.Unlock() + + // Here we determine if we need to force flush memtable. Given we rotated log file, it would + // make sense to force flush a memtable, so the updated value head would have a chance to be + // pushed to L0. Otherwise, it would not go to L0, until the memtable has been fully filled, + // which can take a lot longer if the write load has fewer keys and larger values. This force + // flush, thus avoids the need to read through a lot of log files on a crash and restart. + // Above approach is quite simple with small drawback. We are calling ensureRoomForWrite before + // inserting every entry in Memtable. We will get latest db.head after all entries for a request + // are inserted in Memtable. If we have done >= db.logRotates rotations, then while inserting + // first entry in Memtable, below condition will be true and we will endup flushing old value of + // db.head. Hence we are limiting no of value log files to be read to db.logRotates only. + forceFlush := atomic.LoadInt32(&db.logRotates) >= db.opt.LogRotatesToFlush + + if !forceFlush && db.mt.MemSize() < db.opt.MaxTableSize { + return nil + } + + y.AssertTrue(db.mt != nil) // A nil mt indicates that DB is being closed. + select { + case db.flushChan <- flushTask{mt: db.mt, vptr: db.vhead}: + // After every memtable flush, let's reset the counter. + atomic.StoreInt32(&db.logRotates, 0) + + // Ensure value log is synced to disk so this memtable's contents wouldn't be lost. + err = db.vlog.sync(db.vhead.Fid) + if err != nil { + return err + } + + db.opt.Debugf("Flushing memtable, mt.size=%d size of flushChan: %d\n", + db.mt.MemSize(), len(db.flushChan)) + // We manage to push this task. Let's modify imm. + db.imm = append(db.imm, db.mt) + db.mt = skl.NewSkiplist(arenaSize(db.opt)) + // New memtable is empty. We certainly have room. + return nil + default: + // We need to do this to unlock and allow the flusher to modify imm. + return errNoRoom + } +} + +func arenaSize(opt Options) int64 { + return opt.MaxTableSize + opt.maxBatchSize + opt.maxBatchCount*int64(skl.MaxNodeSize) +} + +// WriteLevel0Table flushes memtable. +func writeLevel0Table(ft flushTask, f io.Writer) error { + iter := ft.mt.NewIterator() + defer iter.Close() + b := table.NewTableBuilder() + defer b.Close() + for iter.SeekToFirst(); iter.Valid(); iter.Next() { + if len(ft.dropPrefix) > 0 && bytes.HasPrefix(iter.Key(), ft.dropPrefix) { + continue + } + if err := b.Add(iter.Key(), iter.Value()); err != nil { + return err + } + } + _, err := f.Write(b.Finish()) + return err +} + +type flushTask struct { + mt *skl.Skiplist + vptr valuePointer + dropPrefix []byte +} + +// handleFlushTask must be run serially. +func (db *DB) handleFlushTask(ft flushTask) error { + // There can be a scnerio, when empty memtable is flushed. For example, memtable is empty and + // after writing request to value log, rotation count exceeds db.LogRotatesToFlush. + if ft.mt.Empty() { + return nil + } + + // Store badger head even if vptr is zero, need it for readTs + db.opt.Debugf("Storing value log head: %+v\n", ft.vptr) + db.elog.Printf("Storing offset: %+v\n", ft.vptr) + offset := make([]byte, vptrSize) + ft.vptr.Encode(offset) + + // Pick the max commit ts, so in case of crash, our read ts would be higher than all the + // commits. + headTs := y.KeyWithTs(head, db.orc.nextTs()) + ft.mt.Put(headTs, y.ValueStruct{Value: offset}) + + // Also store lfDiscardStats before flushing memtables + discardStatsKey := y.KeyWithTs(lfDiscardStatsKey, 1) + ft.mt.Put(discardStatsKey, y.ValueStruct{Value: db.vlog.encodedDiscardStats()}) + + fileID := db.lc.reserveFileID() + fd, err := y.CreateSyncedFile(table.NewFilename(fileID, db.opt.Dir), true) + if err != nil { + return y.Wrap(err) + } + + // Don't block just to sync the directory entry. + dirSyncCh := make(chan error) + go func() { dirSyncCh <- syncDir(db.opt.Dir) }() + + err = writeLevel0Table(ft, fd) + dirSyncErr := <-dirSyncCh + + if err != nil { + db.elog.Errorf("ERROR while writing to level 0: %v", err) + return err + } + if dirSyncErr != nil { + // Do dir sync as best effort. No need to return due to an error there. + db.elog.Errorf("ERROR while syncing level directory: %v", dirSyncErr) + } + + tbl, err := table.OpenTable(fd, db.opt.TableLoadingMode, nil) + if err != nil { + db.elog.Printf("ERROR while opening table: %v", err) + return err + } + // We own a ref on tbl. + err = db.lc.addLevel0Table(tbl) // This will incrRef (if we don't error, sure) + tbl.DecrRef() // Releases our ref. + return err +} + +// flushMemtable must keep running until we send it an empty flushTask. If there +// are errors during handling the flush task, we'll retry indefinitely. +func (db *DB) flushMemtable(lc *y.Closer) error { + defer lc.Done() + + for ft := range db.flushChan { + if ft.mt == nil { + // We close db.flushChan now, instead of sending a nil ft.mt. + continue + } + for { + err := db.handleFlushTask(ft) + if err == nil { + // Update s.imm. Need a lock. + db.Lock() + // This is a single-threaded operation. ft.mt corresponds to the head of + // db.imm list. Once we flush it, we advance db.imm. The next ft.mt + // which would arrive here would match db.imm[0], because we acquire a + // lock over DB when pushing to flushChan. + // TODO: This logic is dirty AF. Any change and this could easily break. + y.AssertTrue(ft.mt == db.imm[0]) + db.imm = db.imm[1:] + ft.mt.DecrRef() // Return memory. + db.Unlock() + + break + } + // Encountered error. Retry indefinitely. + db.opt.Errorf("Failure while flushing memtable to disk: %v. Retrying...\n", err) + time.Sleep(time.Second) + } + } + return nil +} + +func exists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return true, err +} + +// This function does a filewalk, calculates the size of vlog and sst files and stores it in +// y.LSMSize and y.VlogSize. +func (db *DB) calculateSize() { + newInt := func(val int64) *expvar.Int { + v := new(expvar.Int) + v.Add(val) + return v + } + + totalSize := func(dir string) (int64, int64) { + var lsmSize, vlogSize int64 + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + ext := filepath.Ext(path) + if ext == ".sst" { + lsmSize += info.Size() + } else if ext == ".vlog" { + vlogSize += info.Size() + } + return nil + }) + if err != nil { + db.elog.Printf("Got error while calculating total size of directory: %s", dir) + } + return lsmSize, vlogSize + } + + lsmSize, vlogSize := totalSize(db.opt.Dir) + y.LSMSize.Set(db.opt.Dir, newInt(lsmSize)) + // If valueDir is different from dir, we'd have to do another walk. + if db.opt.ValueDir != db.opt.Dir { + _, vlogSize = totalSize(db.opt.ValueDir) + } + y.VlogSize.Set(db.opt.Dir, newInt(vlogSize)) +} + +func (db *DB) updateSize(lc *y.Closer) { + defer lc.Done() + + metricsTicker := time.NewTicker(time.Minute) + defer metricsTicker.Stop() + + for { + select { + case <-metricsTicker.C: + db.calculateSize() + case <-lc.HasBeenClosed(): + return + } + } +} + +// RunValueLogGC triggers a value log garbage collection. +// +// It picks value log files to perform GC based on statistics that are collected +// duing compactions. If no such statistics are available, then log files are +// picked in random order. The process stops as soon as the first log file is +// encountered which does not result in garbage collection. +// +// When a log file is picked, it is first sampled. If the sample shows that we +// can discard at least discardRatio space of that file, it would be rewritten. +// +// If a call to RunValueLogGC results in no rewrites, then an ErrNoRewrite is +// thrown indicating that the call resulted in no file rewrites. +// +// We recommend setting discardRatio to 0.5, thus indicating that a file be +// rewritten if half the space can be discarded. This results in a lifetime +// value log write amplification of 2 (1 from original write + 0.5 rewrite + +// 0.25 + 0.125 + ... = 2). Setting it to higher value would result in fewer +// space reclaims, while setting it to a lower value would result in more space +// reclaims at the cost of increased activity on the LSM tree. discardRatio +// must be in the range (0.0, 1.0), both endpoints excluded, otherwise an +// ErrInvalidRequest is returned. +// +// Only one GC is allowed at a time. If another value log GC is running, or DB +// has been closed, this would return an ErrRejected. +// +// Note: Every time GC is run, it would produce a spike of activity on the LSM +// tree. +func (db *DB) RunValueLogGC(discardRatio float64) error { + if discardRatio >= 1.0 || discardRatio <= 0.0 { + return ErrInvalidRequest + } + + // Find head on disk + headKey := y.KeyWithTs(head, math.MaxUint64) + // Need to pass with timestamp, lsm get removes the last 8 bytes and compares key + val, err := db.lc.get(headKey, nil) + if err != nil { + return errors.Wrap(err, "Retrieving head from on-disk LSM") + } + + var head valuePointer + if len(val.Value) > 0 { + head.Decode(val.Value) + } + + // Pick a log file and run GC + return db.vlog.runGC(discardRatio, head) +} + +// Size returns the size of lsm and value log files in bytes. It can be used to decide how often to +// call RunValueLogGC. +func (db *DB) Size() (lsm, vlog int64) { + if y.LSMSize.Get(db.opt.Dir) == nil { + lsm, vlog = 0, 0 + return + } + lsm = y.LSMSize.Get(db.opt.Dir).(*expvar.Int).Value() + vlog = y.VlogSize.Get(db.opt.Dir).(*expvar.Int).Value() + return +} + +// Sequence represents a Badger sequence. +type Sequence struct { + sync.Mutex + db *DB + key []byte + next uint64 + leased uint64 + bandwidth uint64 +} + +// Next would return the next integer in the sequence, updating the lease by running a transaction +// if needed. +func (seq *Sequence) Next() (uint64, error) { + seq.Lock() + defer seq.Unlock() + if seq.next >= seq.leased { + if err := seq.updateLease(); err != nil { + return 0, err + } + } + val := seq.next + seq.next++ + return val, nil +} + +// Release the leased sequence to avoid wasted integers. This should be done right +// before closing the associated DB. However it is valid to use the sequence after +// it was released, causing a new lease with full bandwidth. +func (seq *Sequence) Release() error { + seq.Lock() + defer seq.Unlock() + err := seq.db.Update(func(txn *Txn) error { + var buf [8]byte + binary.BigEndian.PutUint64(buf[:], seq.next) + return txn.Set(seq.key, buf[:]) + }) + if err != nil { + return err + } + seq.leased = seq.next + return nil +} + +func (seq *Sequence) updateLease() error { + return seq.db.Update(func(txn *Txn) error { + item, err := txn.Get(seq.key) + if err == ErrKeyNotFound { + seq.next = 0 + } else if err != nil { + return err + } else { + var num uint64 + if err := item.Value(func(v []byte) error { + num = binary.BigEndian.Uint64(v) + return nil + }); err != nil { + return err + } + seq.next = num + } + + lease := seq.next + seq.bandwidth + var buf [8]byte + binary.BigEndian.PutUint64(buf[:], lease) + if err = txn.Set(seq.key, buf[:]); err != nil { + return err + } + seq.leased = lease + return nil + }) +} + +// GetSequence would initiate a new sequence object, generating it from the stored lease, if +// available, in the database. Sequence can be used to get a list of monotonically increasing +// integers. Multiple sequences can be created by providing different keys. Bandwidth sets the +// size of the lease, determining how many Next() requests can be served from memory. +// +// GetSequence is not supported on ManagedDB. Calling this would result in a panic. +func (db *DB) GetSequence(key []byte, bandwidth uint64) (*Sequence, error) { + if db.opt.managedTxns { + panic("Cannot use GetSequence with managedDB=true.") + } + + switch { + case len(key) == 0: + return nil, ErrEmptyKey + case bandwidth == 0: + return nil, ErrZeroBandwidth + } + seq := &Sequence{ + db: db, + key: key, + next: 0, + leased: 0, + bandwidth: bandwidth, + } + err := seq.updateLease() + return seq, err +} + +// Tables gets the TableInfo objects from the level controller. If withKeysCount +// is true, TableInfo objects also contain counts of keys for the tables. +func (db *DB) Tables(withKeysCount bool) []TableInfo { + return db.lc.getTableInfo(withKeysCount) +} + +// KeySplits can be used to get rough key ranges to divide up iteration over +// the DB. +func (db *DB) KeySplits(prefix []byte) []string { + var splits []string + // We just want table ranges here and not keys count. + for _, ti := range db.Tables(false) { + // We don't use ti.Left, because that has a tendency to store !badger + // keys. + if bytes.HasPrefix(ti.Right, prefix) { + splits = append(splits, string(ti.Right)) + } + } + sort.Strings(splits) + return splits +} + +// MaxBatchCount returns max possible entries in batch +func (db *DB) MaxBatchCount() int64 { + return db.opt.maxBatchCount +} + +// MaxBatchSize returns max possible batch size +func (db *DB) MaxBatchSize() int64 { + return db.opt.maxBatchSize +} + +func (db *DB) stopCompactions() { + // Stop memtable flushes. + if db.closers.memtable != nil { + close(db.flushChan) + db.closers.memtable.SignalAndWait() + } + // Stop compactions. + if db.closers.compactors != nil { + db.closers.compactors.SignalAndWait() + } +} + +func (db *DB) startCompactions() { + // Resume compactions. + if db.closers.compactors != nil { + db.closers.compactors = y.NewCloser(1) + db.lc.startCompact(db.closers.compactors) + } + if db.closers.memtable != nil { + db.flushChan = make(chan flushTask, db.opt.NumMemtables) + db.closers.memtable = y.NewCloser(1) + go db.flushMemtable(db.closers.memtable) + } +} + +// Flatten can be used to force compactions on the LSM tree so all the tables fall on the same +// level. This ensures that all the versions of keys are colocated and not split across multiple +// levels, which is necessary after a restore from backup. During Flatten, live compactions are +// stopped. Ideally, no writes are going on during Flatten. Otherwise, it would create competition +// between flattening the tree and new tables being created at level zero. +func (db *DB) Flatten(workers int) error { + db.stopCompactions() + defer db.startCompactions() + + compactAway := func(cp compactionPriority) error { + db.opt.Infof("Attempting to compact with %+v\n", cp) + errCh := make(chan error, 1) + for i := 0; i < workers; i++ { + go func() { + errCh <- db.lc.doCompact(cp) + }() + } + var success int + var rerr error + for i := 0; i < workers; i++ { + err := <-errCh + if err != nil { + rerr = err + db.opt.Warningf("While running doCompact with %+v. Error: %v\n", cp, err) + } else { + success++ + } + } + if success == 0 { + return rerr + } + // We could do at least one successful compaction. So, we'll consider this a success. + db.opt.Infof("%d compactor(s) succeeded. One or more tables from level %d compacted.\n", + success, cp.level) + return nil + } + + hbytes := func(sz int64) string { + return humanize.Bytes(uint64(sz)) + } + + for { + db.opt.Infof("\n") + var levels []int + for i, l := range db.lc.levels { + sz := l.getTotalSize() + db.opt.Infof("Level: %d. %8s Size. %8s Max.\n", + i, hbytes(l.getTotalSize()), hbytes(l.maxTotalSize)) + if sz > 0 { + levels = append(levels, i) + } + } + if len(levels) <= 1 { + prios := db.lc.pickCompactLevels() + if len(prios) == 0 || prios[0].score <= 1.0 { + db.opt.Infof("All tables consolidated into one level. Flattening done.\n") + return nil + } + if err := compactAway(prios[0]); err != nil { + return err + } + continue + } + // Create an artificial compaction priority, to ensure that we compact the level. + cp := compactionPriority{level: levels[0], score: 1.71} + if err := compactAway(cp); err != nil { + return err + } + } +} + +func (db *DB) prepareToDrop() func() { + if db.opt.ReadOnly { + panic("Attempting to drop data in read-only mode.") + } + // Stop accepting new writes. + atomic.StoreInt32(&db.blockWrites, 1) + + // Make all pending writes finish. The following will also close writeCh. + db.closers.writes.SignalAndWait() + db.opt.Infof("Writes flushed. Stopping compactions now...") + + // Stop all compactions. + db.stopCompactions() + return func() { + db.opt.Infof("Resuming writes") + db.startCompactions() + + db.writeCh = make(chan *request, kvWriteChCapacity) + db.closers.writes = y.NewCloser(1) + go db.doWrites(db.closers.writes) + + // Resume writes. + atomic.StoreInt32(&db.blockWrites, 0) + } +} + +// DropAll would drop all the data stored in Badger. It does this in the following way. +// - Stop accepting new writes. +// - Pause memtable flushes and compactions. +// - Pick all tables from all levels, create a changeset to delete all these +// tables and apply it to manifest. +// - Pick all log files from value log, and delete all of them. Restart value log files from zero. +// - Resume memtable flushes and compactions. +// +// NOTE: DropAll is resilient to concurrent writes, but not to reads. It is up to the user to not do +// any reads while DropAll is going on, otherwise they may result in panics. Ideally, both reads and +// writes are paused before running DropAll, and resumed after it is finished. +func (db *DB) DropAll() error { + f, err := db.dropAll() + if err != nil { + return err + } + if f == nil { + panic("both error and returned function cannot be nil in DropAll") + } + f() + return nil +} + +func (db *DB) dropAll() (func(), error) { + db.opt.Infof("DropAll called. Blocking writes...") + f := db.prepareToDrop() + + // Block all foreign interactions with memory tables. + db.Lock() + defer db.Unlock() + + // Remove inmemory tables. Calling DecrRef for safety. Not sure if they're absolutely needed. + db.mt.DecrRef() + for _, mt := range db.imm { + mt.DecrRef() + } + db.imm = db.imm[:0] + db.mt = skl.NewSkiplist(arenaSize(db.opt)) // Set it up for future writes. + + num, err := db.lc.dropTree() + if err != nil { + return nil, err + } + db.opt.Infof("Deleted %d SSTables. Now deleting value logs...\n", num) + + num, err = db.vlog.dropAll() + if err != nil { + return nil, err + } + db.vhead = valuePointer{} // Zero it out. + db.lc.nextFileID = 1 + db.opt.Infof("Deleted %d value log files. DropAll done.\n", num) + return f, nil +} + +// DropPrefix would drop all the keys with the provided prefix. It does this in the following way: +// - Stop accepting new writes. +// - Stop memtable flushes and compactions. +// - Flush out all memtables, skipping over keys with the given prefix, Kp. +// - Write out the value log header to memtables when flushing, so we don't accidentally bring Kp +// back after a restart. +// - Compact L0->L1, skipping over Kp. +// - Compact rest of the levels, Li->Li, picking tables which have Kp. +// - Resume memtable flushes, compactions and writes. +func (db *DB) DropPrefix(prefix []byte) error { + db.opt.Infof("DropPrefix called on %s. Blocking writes...", hex.Dump(prefix)) + f := db.prepareToDrop() + defer f() + + // Block all foreign interactions with memory tables. + db.Lock() + defer db.Unlock() + + db.imm = append(db.imm, db.mt) + for _, memtable := range db.imm { + if memtable.Empty() { + memtable.DecrRef() + continue + } + task := flushTask{ + mt: memtable, + // Ensure that the head of value log gets persisted to disk. + vptr: db.vhead, + dropPrefix: prefix, + } + db.opt.Debugf("Flushing memtable") + if err := db.handleFlushTask(task); err != nil { + db.opt.Errorf("While trying to flush memtable: %v", err) + return err + } + memtable.DecrRef() + } + db.imm = db.imm[:0] + db.mt = skl.NewSkiplist(arenaSize(db.opt)) + + // Drop prefixes from the levels. + if err := db.lc.dropPrefix(prefix); err != nil { + return err + } + db.opt.Infof("DropPrefix done") + return nil +} + +// Subscribe can be used watch key changes for the given key prefix. +func (db *DB) Subscribe(ctx context.Context, cb callback, prefix []byte, prefixes ...[]byte) error { + if cb == nil { + return ErrNilCallback + } + prefixes = append(prefixes, prefix) + c := y.NewCloser(1) + recvCh, id := db.pub.newSubscriber(c, prefixes...) + slurp := func(batch *pb.KVList) { + defer func() { + if len(batch.GetKv()) > 0 { + cb(batch) + } + }() + for { + select { + case kvs := <-recvCh: + batch.Kv = append(batch.Kv, kvs.Kv...) + default: + return + } + } + } + for { + select { + case <-c.HasBeenClosed(): + slurp(new(pb.KVList)) + // Drain if any pending updates. + c.Done() + // No need to delete here. Closer will be called only while + // closing DB. Subscriber will be deleted by cleanSubscribers. + return nil + case <-ctx.Done(): + c.Done() + db.pub.deleteSubscriber(id) + // Delete the subscriber to avoid further updates. + return ctx.Err() + case batch := <-recvCh: + slurp(batch) + } + } +} diff --git a/vendor/github.com/dgraph-io/badger/dir_unix.go b/vendor/github.com/dgraph-io/badger/dir_unix.go new file mode 100644 index 00000000..a5e0fa33 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/dir_unix.go @@ -0,0 +1,100 @@ +// +build !windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/pkg/errors" + "golang.org/x/sys/unix" +) + +// directoryLockGuard holds a lock on a directory and a pid file inside. The pid file isn't part +// of the locking mechanism, it's just advisory. +type directoryLockGuard struct { + // File handle on the directory, which we've flocked. + f *os.File + // The absolute path to our pid file. + path string + // Was this a shared lock for a read-only database? + readOnly bool +} + +// acquireDirectoryLock gets a lock on the directory (using flock). If +// this is not read-only, it will also write our pid to +// dirPath/pidFileName for convenience. +func acquireDirectoryLock(dirPath string, pidFileName string, readOnly bool) (*directoryLockGuard, error) { + // Convert to absolute path so that Release still works even if we do an unbalanced + // chdir in the meantime. + absPidFilePath, err := filepath.Abs(filepath.Join(dirPath, pidFileName)) + if err != nil { + return nil, errors.Wrap(err, "cannot get absolute path for pid lock file") + } + f, err := os.Open(dirPath) + if err != nil { + return nil, errors.Wrapf(err, "cannot open directory %q", dirPath) + } + opts := unix.LOCK_EX | unix.LOCK_NB + if readOnly { + opts = unix.LOCK_SH | unix.LOCK_NB + } + + err = unix.Flock(int(f.Fd()), opts) + if err != nil { + f.Close() + return nil, errors.Wrapf(err, + "Cannot acquire directory lock on %q. Another process is using this Badger database.", + dirPath) + } + + if !readOnly { + // Yes, we happily overwrite a pre-existing pid file. We're the + // only read-write badger process using this directory. + err = ioutil.WriteFile(absPidFilePath, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0666) + if err != nil { + f.Close() + return nil, errors.Wrapf(err, + "Cannot write pid file %q", absPidFilePath) + } + } + return &directoryLockGuard{f, absPidFilePath, readOnly}, nil +} + +// Release deletes the pid file and releases our lock on the directory. +func (guard *directoryLockGuard) release() error { + var err error + if !guard.readOnly { + // It's important that we remove the pid file first. + err = os.Remove(guard.path) + } + + if closeErr := guard.f.Close(); err == nil { + err = closeErr + } + guard.path = "" + guard.f = nil + + return err +} + +// openDir opens a directory for syncing. +func openDir(path string) (*os.File, error) { return os.Open(path) } diff --git a/vendor/github.com/dgraph-io/badger/dir_windows.go b/vendor/github.com/dgraph-io/badger/dir_windows.go new file mode 100644 index 00000000..28ccb7aa --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/dir_windows.go @@ -0,0 +1,106 @@ +// +build windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +// OpenDir opens a directory in windows with write access for syncing. +import ( + "os" + "path/filepath" + "syscall" + + "github.com/pkg/errors" +) + +// FILE_ATTRIBUTE_TEMPORARY - A file that is being used for temporary storage. +// FILE_FLAG_DELETE_ON_CLOSE - The file is to be deleted immediately after all of its handles are +// closed, which includes the specified handle and any other open or duplicated handles. +// See: https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-attribute-constants +// NOTE: Added here to avoid importing golang.org/x/sys/windows +const ( + FILE_ATTRIBUTE_TEMPORARY = 0x00000100 + FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 +) + +func openDir(path string) (*os.File, error) { + fd, err := openDirWin(path) + if err != nil { + return nil, err + } + return os.NewFile(uintptr(fd), path), nil +} + +func openDirWin(path string) (fd syscall.Handle, err error) { + if len(path) == 0 { + return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND + } + pathp, err := syscall.UTF16PtrFromString(path) + if err != nil { + return syscall.InvalidHandle, err + } + access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE) + sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE) + createmode := uint32(syscall.OPEN_EXISTING) + fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS) + return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0) +} + +// DirectoryLockGuard holds a lock on the directory. +type directoryLockGuard struct { + h syscall.Handle + path string +} + +// AcquireDirectoryLock acquires exclusive access to a directory. +func acquireDirectoryLock(dirPath string, pidFileName string, readOnly bool) (*directoryLockGuard, error) { + if readOnly { + return nil, ErrWindowsNotSupported + } + + // Convert to absolute path so that Release still works even if we do an unbalanced + // chdir in the meantime. + absLockFilePath, err := filepath.Abs(filepath.Join(dirPath, pidFileName)) + if err != nil { + return nil, errors.Wrap(err, "Cannot get absolute path for pid lock file") + } + + // This call creates a file handler in memory that only one process can use at a time. When + // that process ends, the file is deleted by the system. + // FILE_ATTRIBUTE_TEMPORARY is used to tell Windows to try to create the handle in memory. + // FILE_FLAG_DELETE_ON_CLOSE is not specified in syscall_windows.go but tells Windows to delete + // the file when all processes holding the handler are closed. + // XXX: this works but it's a bit klunky. i'd prefer to use LockFileEx but it needs unsafe pkg. + h, err := syscall.CreateFile( + syscall.StringToUTF16Ptr(absLockFilePath), 0, 0, nil, + syscall.OPEN_ALWAYS, + uint32(FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE), + 0) + if err != nil { + return nil, errors.Wrapf(err, + "Cannot create lock file %q. Another process is using this Badger database", + absLockFilePath) + } + + return &directoryLockGuard{h: h, path: absLockFilePath}, nil +} + +// Release removes the directory lock. +func (g *directoryLockGuard) release() error { + g.path = "" + return syscall.CloseHandle(g.h) +} diff --git a/vendor/github.com/dgraph-io/badger/doc.go b/vendor/github.com/dgraph-io/badger/doc.go new file mode 100644 index 00000000..83dc9a28 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/doc.go @@ -0,0 +1,28 @@ +/* +Package badger implements an embeddable, simple and fast key-value database, +written in pure Go. It is designed to be highly performant for both reads and +writes simultaneously. Badger uses Multi-Version Concurrency Control (MVCC), and +supports transactions. It runs transactions concurrently, with serializable +snapshot isolation guarantees. + +Badger uses an LSM tree along with a value log to separate keys from values, +hence reducing both write amplification and the size of the LSM tree. This +allows LSM tree to be served entirely from RAM, while the values are served +from SSD. + + +Usage + +Badger has the following main types: DB, Txn, Item and Iterator. DB contains +keys that are associated with values. It must be opened with the appropriate +options before it can be accessed. + +All operations happen inside a Txn. Txn represents a transaction, which can +be read-only or read-write. Read-only transactions can read values for a +given key (which are returned inside an Item), or iterate over a set of +key-value pairs using an Iterator (which are returned as Item type values as +well). Read-write transactions can also update and delete keys from the DB. + +See the examples for more usage details. +*/ +package badger diff --git a/vendor/github.com/dgraph-io/badger/errors.go b/vendor/github.com/dgraph-io/badger/errors.go new file mode 100644 index 00000000..cad66cb1 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/errors.go @@ -0,0 +1,108 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "github.com/pkg/errors" +) + +var ( + // ErrValueLogSize is returned when opt.ValueLogFileSize option is not within the valid + // range. + ErrValueLogSize = errors.New("Invalid ValueLogFileSize, must be between 1MB and 2GB") + + // ErrValueThreshold is returned when ValueThreshold is set to a value close to or greater than + // uint16. + ErrValueThreshold = errors.New("Invalid ValueThreshold, must be lower than uint16") + + // ErrKeyNotFound is returned when key isn't found on a txn.Get. + ErrKeyNotFound = errors.New("Key not found") + + // ErrTxnTooBig is returned if too many writes are fit into a single transaction. + ErrTxnTooBig = errors.New("Txn is too big to fit into one request") + + // ErrConflict is returned when a transaction conflicts with another transaction. This can happen if + // the read rows had been updated concurrently by another transaction. + ErrConflict = errors.New("Transaction Conflict. Please retry") + + // ErrReadOnlyTxn is returned if an update function is called on a read-only transaction. + ErrReadOnlyTxn = errors.New("No sets or deletes are allowed in a read-only transaction") + + // ErrDiscardedTxn is returned if a previously discarded transaction is re-used. + ErrDiscardedTxn = errors.New("This transaction has been discarded. Create a new one") + + // ErrEmptyKey is returned if an empty key is passed on an update function. + ErrEmptyKey = errors.New("Key cannot be empty") + + // ErrInvalidKey is returned if the key has a special !badger! prefix, + // reserved for internal usage. + ErrInvalidKey = errors.New("Key is using a reserved !badger! prefix") + + // ErrRetry is returned when a log file containing the value is not found. + // This usually indicates that it may have been garbage collected, and the + // operation needs to be retried. + ErrRetry = errors.New("Unable to find log file. Please retry") + + // ErrThresholdZero is returned if threshold is set to zero, and value log GC is called. + // In such a case, GC can't be run. + ErrThresholdZero = errors.New( + "Value log GC can't run because threshold is set to zero") + + // ErrNoRewrite is returned if a call for value log GC doesn't result in a log file rewrite. + ErrNoRewrite = errors.New( + "Value log GC attempt didn't result in any cleanup") + + // ErrRejected is returned if a value log GC is called either while another GC is running, or + // after DB::Close has been called. + ErrRejected = errors.New("Value log GC request rejected") + + // ErrInvalidRequest is returned if the user request is invalid. + ErrInvalidRequest = errors.New("Invalid request") + + // ErrManagedTxn is returned if the user tries to use an API which isn't + // allowed due to external management of transactions, when using ManagedDB. + ErrManagedTxn = errors.New( + "Invalid API request. Not allowed to perform this action using ManagedDB") + + // ErrInvalidDump if a data dump made previously cannot be loaded into the database. + ErrInvalidDump = errors.New("Data dump cannot be read") + + // ErrZeroBandwidth is returned if the user passes in zero bandwidth for sequence. + ErrZeroBandwidth = errors.New("Bandwidth must be greater than zero") + + // ErrInvalidLoadingMode is returned when opt.ValueLogLoadingMode option is not + // within the valid range + ErrInvalidLoadingMode = errors.New("Invalid ValueLogLoadingMode, must be FileIO or MemoryMap") + + // ErrReplayNeeded is returned when opt.ReadOnly is set but the + // database requires a value log replay. + ErrReplayNeeded = errors.New("Database was not properly closed, cannot open read-only") + + // ErrWindowsNotSupported is returned when opt.ReadOnly is used on Windows + ErrWindowsNotSupported = errors.New("Read-only mode is not supported on Windows") + + // ErrTruncateNeeded is returned when the value log gets corrupt, and requires truncation of + // corrupt data to allow Badger to run properly. + ErrTruncateNeeded = errors.New("Value log truncate required to run DB. This might result in data loss") + + // ErrBlockedWrites is returned if the user called DropAll. During the process of dropping all + // data from Badger, we stop accepting new writes, by returning this error. + ErrBlockedWrites = errors.New("Writes are blocked, possibly due to DropAll or Close") + + // ErrNilCallback is returned when subscriber's callback is nil. + ErrNilCallback = errors.New("Callback cannot be nil") +) diff --git a/vendor/github.com/dgraph-io/badger/histogram.go b/vendor/github.com/dgraph-io/badger/histogram.go new file mode 100644 index 00000000..d8c94bb7 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/histogram.go @@ -0,0 +1,169 @@ +/* + * Copyright 2019 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "fmt" + "math" +) + +// PrintHistogram builds and displays the key-value size histogram. +// When keyPrefix is set, only the keys that have prefix "keyPrefix" are +// considered for creating the histogram +func (db *DB) PrintHistogram(keyPrefix []byte) { + if db == nil { + fmt.Println("\nCannot build histogram: DB is nil.") + return + } + histogram := db.buildHistogram(keyPrefix) + fmt.Printf("Histogram of key sizes (in bytes)\n") + histogram.keySizeHistogram.printHistogram() + fmt.Printf("Histogram of value sizes (in bytes)\n") + histogram.valueSizeHistogram.printHistogram() +} + +// histogramData stores information about a histogram +type histogramData struct { + bins []int64 + countPerBin []int64 + totalCount int64 + min int64 + max int64 + sum int64 +} + +// sizeHistogram contains keySize histogram and valueSize histogram +type sizeHistogram struct { + keySizeHistogram, valueSizeHistogram histogramData +} + +// newSizeHistogram returns a new instance of keyValueSizeHistogram with +// properly initialized fields. +func newSizeHistogram() *sizeHistogram { + // TODO(ibrahim): find appropriate bin size. + keyBins := createHistogramBins(1, 16) + valueBins := createHistogramBins(1, 30) + return &sizeHistogram{ + keySizeHistogram: histogramData{ + bins: keyBins, + countPerBin: make([]int64, len(keyBins)+1), + max: math.MinInt64, + min: math.MaxInt64, + sum: 0, + }, + valueSizeHistogram: histogramData{ + bins: valueBins, + countPerBin: make([]int64, len(valueBins)+1), + max: math.MinInt64, + min: math.MaxInt64, + sum: 0, + }, + } +} + +// createHistogramBins creates bins for an histogram. The bin sizes are powers +// of two of the form [2^min_exponent, ..., 2^max_exponent]. +func createHistogramBins(minExponent, maxExponent uint32) []int64 { + var bins []int64 + for i := minExponent; i <= maxExponent; i++ { + bins = append(bins, int64(1)< histogram.max { + histogram.max = value + } + if value < histogram.min { + histogram.min = value + } + + histogram.sum += value + histogram.totalCount++ + + for index := 0; index <= len(histogram.bins); index++ { + // Allocate value in the last buckets if we reached the end of the Bounds array. + if index == len(histogram.bins) { + histogram.countPerBin[index]++ + break + } + + // Check if the value should be added to the "index" bin + if value < int64(histogram.bins[index]) { + histogram.countPerBin[index]++ + break + } + } +} + +// buildHistogram builds the key-value size histogram. +// When keyPrefix is set, only the keys that have prefix "keyPrefix" are +// considered for creating the histogram +func (db *DB) buildHistogram(keyPrefix []byte) *sizeHistogram { + txn := db.NewTransaction(false) + defer txn.Discard() + + itr := txn.NewIterator(DefaultIteratorOptions) + defer itr.Close() + + badgerHistogram := newSizeHistogram() + + // Collect key and value sizes. + for itr.Seek(keyPrefix); itr.ValidForPrefix(keyPrefix); itr.Next() { + item := itr.Item() + badgerHistogram.keySizeHistogram.Update(item.KeySize()) + badgerHistogram.valueSizeHistogram.Update(item.ValueSize()) + } + return badgerHistogram +} + +// printHistogram prints the histogram data in a human-readable format. +func (histogram histogramData) printHistogram() { + fmt.Printf("Total count: %d\n", histogram.totalCount) + fmt.Printf("Min value: %d\n", histogram.min) + fmt.Printf("Max value: %d\n", histogram.max) + fmt.Printf("Mean: %.2f\n", float64(histogram.sum)/float64(histogram.totalCount)) + fmt.Printf("%24s %9s\n", "Range", "Count") + + numBins := len(histogram.bins) + for index, count := range histogram.countPerBin { + if count == 0 { + continue + } + + // The last bin represents the bin that contains the range from + // the last bin up to infinity so it's processed differently than the + // other bins. + if index == len(histogram.countPerBin)-1 { + lowerBound := int(histogram.bins[numBins-1]) + fmt.Printf("[%10d, %10s) %9d\n", lowerBound, "infinity", count) + continue + } + + upperBound := int(histogram.bins[index]) + lowerBound := 0 + if index > 0 { + lowerBound = int(histogram.bins[index-1]) + } + + fmt.Printf("[%10d, %10d) %9d\n", lowerBound, upperBound, count) + } + fmt.Println() +} diff --git a/vendor/github.com/dgraph-io/badger/iterator.go b/vendor/github.com/dgraph-io/badger/iterator.go new file mode 100644 index 00000000..c071324d --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/iterator.go @@ -0,0 +1,684 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "fmt" + "hash/crc32" + "sync" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/options" + "github.com/dgraph-io/badger/table" + + "github.com/dgraph-io/badger/y" +) + +type prefetchStatus uint8 + +const ( + prefetched prefetchStatus = iota + 1 +) + +// Item is returned during iteration. Both the Key() and Value() output is only valid until +// iterator.Next() is called. +type Item struct { + status prefetchStatus + err error + wg sync.WaitGroup + db *DB + key []byte + vptr []byte + meta byte // We need to store meta to know about bitValuePointer. + userMeta byte + expiresAt uint64 + val []byte + slice *y.Slice // Used only during prefetching. + next *Item + version uint64 + txn *Txn +} + +// String returns a string representation of Item +func (item *Item) String() string { + return fmt.Sprintf("key=%q, version=%d, meta=%x", item.Key(), item.Version(), item.meta) +} + +// Key returns the key. +// +// Key is only valid as long as item is valid, or transaction is valid. If you need to use it +// outside its validity, please use KeyCopy. +func (item *Item) Key() []byte { + return item.key +} + +// KeyCopy returns a copy of the key of the item, writing it to dst slice. +// If nil is passed, or capacity of dst isn't sufficient, a new slice would be allocated and +// returned. +func (item *Item) KeyCopy(dst []byte) []byte { + return y.SafeCopy(dst, item.key) +} + +// Version returns the commit timestamp of the item. +func (item *Item) Version() uint64 { + return item.version +} + +// Value retrieves the value of the item from the value log. +// +// This method must be called within a transaction. Calling it outside a +// transaction is considered undefined behavior. If an iterator is being used, +// then Item.Value() is defined in the current iteration only, because items are +// reused. +// +// If you need to use a value outside a transaction, please use Item.ValueCopy +// instead, or copy it yourself. Value might change once discard or commit is called. +// Use ValueCopy if you want to do a Set after Get. +func (item *Item) Value(fn func(val []byte) error) error { + item.wg.Wait() + if item.status == prefetched { + if item.err == nil && fn != nil { + if err := fn(item.val); err != nil { + return err + } + } + return item.err + } + buf, cb, err := item.yieldItemValue() + defer runCallback(cb) + if err != nil { + return err + } + if fn != nil { + return fn(buf) + } + return nil +} + +// ValueCopy returns a copy of the value of the item from the value log, writing it to dst slice. +// If nil is passed, or capacity of dst isn't sufficient, a new slice would be allocated and +// returned. Tip: It might make sense to reuse the returned slice as dst argument for the next call. +// +// This function is useful in long running iterate/update transactions to avoid a write deadlock. +// See Github issue: https://github.com/dgraph-io/badger/issues/315 +func (item *Item) ValueCopy(dst []byte) ([]byte, error) { + item.wg.Wait() + if item.status == prefetched { + return y.SafeCopy(dst, item.val), item.err + } + buf, cb, err := item.yieldItemValue() + defer runCallback(cb) + return y.SafeCopy(dst, buf), err +} + +func (item *Item) hasValue() bool { + if item.meta == 0 && item.vptr == nil { + // key not found + return false + } + return true +} + +// IsDeletedOrExpired returns true if item contains deleted or expired value. +func (item *Item) IsDeletedOrExpired() bool { + return isDeletedOrExpired(item.meta, item.expiresAt) +} + +// DiscardEarlierVersions returns whether the item was created with the +// option to discard earlier versions of a key when multiple are available. +func (item *Item) DiscardEarlierVersions() bool { + return item.meta&bitDiscardEarlierVersions > 0 +} + +func (item *Item) yieldItemValue() ([]byte, func(), error) { + key := item.Key() // No need to copy. + for { + if !item.hasValue() { + return nil, nil, nil + } + + if item.slice == nil { + item.slice = new(y.Slice) + } + + if (item.meta & bitValuePointer) == 0 { + val := item.slice.Resize(len(item.vptr)) + copy(val, item.vptr) + return val, nil, nil + } + + var vp valuePointer + vp.Decode(item.vptr) + result, cb, err := item.db.vlog.Read(vp, item.slice) + if err != ErrRetry { + return result, cb, err + } + if bytes.HasPrefix(key, badgerMove) { + // err == ErrRetry + // Error is retry even after checking the move keyspace. So, let's + // just assume that value is not present. + return nil, cb, nil + } + + // The value pointer is pointing to a deleted value log. Look for the + // move key and read that instead. + runCallback(cb) + // Do not put badgerMove on the left in append. It seems to cause some sort of manipulation. + keyTs := y.KeyWithTs(item.Key(), item.Version()) + key = make([]byte, len(badgerMove)+len(keyTs)) + n := copy(key, badgerMove) + copy(key[n:], keyTs) + // Note that we can't set item.key to move key, because that would + // change the key user sees before and after this call. Also, this move + // logic is internal logic and should not impact the external behavior + // of the retrieval. + vs, err := item.db.get(key) + if err != nil { + return nil, nil, err + } + if vs.Version != item.Version() { + return nil, nil, nil + } + // Bug fix: Always copy the vs.Value into vptr here. Otherwise, when item is reused this + // slice gets overwritten. + item.vptr = y.SafeCopy(item.vptr, vs.Value) + item.meta &^= bitValuePointer // Clear the value pointer bit. + if vs.Meta&bitValuePointer > 0 { + item.meta |= bitValuePointer // This meta would only be about value pointer. + } + } +} + +func runCallback(cb func()) { + if cb != nil { + cb() + } +} + +func (item *Item) prefetchValue() { + val, cb, err := item.yieldItemValue() + defer runCallback(cb) + + item.err = err + item.status = prefetched + if val == nil { + return + } + if item.db.opt.ValueLogLoadingMode == options.MemoryMap { + buf := item.slice.Resize(len(val)) + copy(buf, val) + item.val = buf + } else { + item.val = val + } +} + +// EstimatedSize returns the approximate size of the key-value pair. +// +// This can be called while iterating through a store to quickly estimate the +// size of a range of key-value pairs (without fetching the corresponding +// values). +func (item *Item) EstimatedSize() int64 { + if !item.hasValue() { + return 0 + } + if (item.meta & bitValuePointer) == 0 { + return int64(len(item.key) + len(item.vptr)) + } + var vp valuePointer + vp.Decode(item.vptr) + return int64(vp.Len) // includes key length. +} + +// KeySize returns the size of the key. +// Exact size of the key is key + 8 bytes of timestamp +func (item *Item) KeySize() int64 { + return int64(len(item.key)) +} + +// ValueSize returns the exact size of the value. +// +// This can be called to quickly estimate the size of a value without fetching +// it. +func (item *Item) ValueSize() int64 { + if !item.hasValue() { + return 0 + } + if (item.meta & bitValuePointer) == 0 { + return int64(len(item.vptr)) + } + var vp valuePointer + vp.Decode(item.vptr) + + klen := int64(len(item.key) + 8) // 8 bytes for timestamp. + return int64(vp.Len) - klen - headerBufSize - crc32.Size +} + +// UserMeta returns the userMeta set by the user. Typically, this byte, optionally set by the user +// is used to interpret the value. +func (item *Item) UserMeta() byte { + return item.userMeta +} + +// ExpiresAt returns a Unix time value indicating when the item will be +// considered expired. 0 indicates that the item will never expire. +func (item *Item) ExpiresAt() uint64 { + return item.expiresAt +} + +// TODO: Switch this to use linked list container in Go. +type list struct { + head *Item + tail *Item +} + +func (l *list) push(i *Item) { + i.next = nil + if l.tail == nil { + l.head = i + l.tail = i + return + } + l.tail.next = i + l.tail = i +} + +func (l *list) pop() *Item { + if l.head == nil { + return nil + } + i := l.head + if l.head == l.tail { + l.tail = nil + l.head = nil + } else { + l.head = i.next + } + i.next = nil + return i +} + +// IteratorOptions is used to set options when iterating over Badger key-value +// stores. +// +// This package provides DefaultIteratorOptions which contains options that +// should work for most applications. Consider using that as a starting point +// before customizing it for your own needs. +type IteratorOptions struct { + // Indicates whether we should prefetch values during iteration and store them. + PrefetchValues bool + // How many KV pairs to prefetch while iterating. Valid only if PrefetchValues is true. + PrefetchSize int + Reverse bool // Direction of iteration. False is forward, true is backward. + AllVersions bool // Fetch all valid versions of the same key. + + // The following option is used to narrow down the SSTables that iterator picks up. If + // Prefix is specified, only tables which could have this prefix are picked based on their range + // of keys. + Prefix []byte // Only iterate over this given prefix. + prefixIsKey bool // If set, use the prefix for bloom filter lookup. + + internalAccess bool // Used to allow internal access to badger keys. +} + +func (opt *IteratorOptions) pickTable(t table.TableInterface) bool { + if len(opt.Prefix) == 0 { + return true + } + trim := func(key []byte) []byte { + if len(key) > len(opt.Prefix) { + return key[:len(opt.Prefix)] + } + return key + } + if bytes.Compare(trim(t.Smallest()), opt.Prefix) > 0 { + return false + } + if bytes.Compare(trim(t.Biggest()), opt.Prefix) < 0 { + return false + } + // Bloom filter lookup would only work if opt.Prefix does NOT have the read + // timestamp as part of the key. + if opt.prefixIsKey && t.DoesNotHave(opt.Prefix) { + return false + } + return true +} + +// DefaultIteratorOptions contains default options when iterating over Badger key-value stores. +var DefaultIteratorOptions = IteratorOptions{ + PrefetchValues: true, + PrefetchSize: 100, + Reverse: false, + AllVersions: false, +} + +// Iterator helps iterating over the KV pairs in a lexicographically sorted order. +type Iterator struct { + iitr *y.MergeIterator + txn *Txn + readTs uint64 + + opt IteratorOptions + item *Item + data list + waste list + + lastKey []byte // Used to skip over multiple versions of the same key. + + closed bool +} + +// NewIterator returns a new iterator. Depending upon the options, either only keys, or both +// key-value pairs would be fetched. The keys are returned in lexicographically sorted order. +// Using prefetch is recommended if you're doing a long running iteration, for performance. +// +// Multiple Iterators: +// For a read-only txn, multiple iterators can be running simultaneously. However, for a read-write +// txn, only one can be running at one time to avoid race conditions, because Txn is thread-unsafe. +func (txn *Txn) NewIterator(opt IteratorOptions) *Iterator { + if txn.discarded { + panic("Transaction has already been discarded") + } + // Do not change the order of the next if. We must track the number of running iterators. + if atomic.AddInt32(&txn.numIterators, 1) > 1 && txn.update { + atomic.AddInt32(&txn.numIterators, -1) + panic("Only one iterator can be active at one time, for a RW txn.") + } + + // TODO: If Prefix is set, only pick those memtables which have keys with + // the prefix. + tables, decr := txn.db.getMemTables() + defer decr() + txn.db.vlog.incrIteratorCount() + var iters []y.Iterator + if itr := txn.newPendingWritesIterator(opt.Reverse); itr != nil { + iters = append(iters, itr) + } + for i := 0; i < len(tables); i++ { + iters = append(iters, tables[i].NewUniIterator(opt.Reverse)) + } + iters = txn.db.lc.appendIterators(iters, &opt) // This will increment references. + res := &Iterator{ + txn: txn, + iitr: y.NewMergeIterator(iters, opt.Reverse), + opt: opt, + readTs: txn.readTs, + } + return res +} + +// NewKeyIterator is just like NewIterator, but allows the user to iterate over all versions of a +// single key. Internally, it sets the Prefix option in provided opt, and uses that prefix to +// additionally run bloom filter lookups before picking tables from the LSM tree. +func (txn *Txn) NewKeyIterator(key []byte, opt IteratorOptions) *Iterator { + if len(opt.Prefix) > 0 { + panic("opt.Prefix should be nil for NewKeyIterator.") + } + opt.Prefix = key // This key must be without the timestamp. + opt.prefixIsKey = true + return txn.NewIterator(opt) +} + +func (it *Iterator) newItem() *Item { + item := it.waste.pop() + if item == nil { + item = &Item{slice: new(y.Slice), db: it.txn.db, txn: it.txn} + } + return item +} + +// Item returns pointer to the current key-value pair. +// This item is only valid until it.Next() gets called. +func (it *Iterator) Item() *Item { + tx := it.txn + tx.addReadKey(it.item.Key()) + return it.item +} + +// Valid returns false when iteration is done. +func (it *Iterator) Valid() bool { + if it.item == nil { + return false + } + return bytes.HasPrefix(it.item.key, it.opt.Prefix) +} + +// ValidForPrefix returns false when iteration is done +// or when the current key is not prefixed by the specified prefix. +func (it *Iterator) ValidForPrefix(prefix []byte) bool { + return it.Valid() && bytes.HasPrefix(it.item.key, prefix) +} + +// Close would close the iterator. It is important to call this when you're done with iteration. +func (it *Iterator) Close() { + if it.closed { + return + } + it.closed = true + + it.iitr.Close() + // It is important to wait for the fill goroutines to finish. Otherwise, we might leave zombie + // goroutines behind, which are waiting to acquire file read locks after DB has been closed. + waitFor := func(l list) { + item := l.pop() + for item != nil { + item.wg.Wait() + item = l.pop() + } + } + waitFor(it.waste) + waitFor(it.data) + + // TODO: We could handle this error. + _ = it.txn.db.vlog.decrIteratorCount() + atomic.AddInt32(&it.txn.numIterators, -1) +} + +// Next would advance the iterator by one. Always check it.Valid() after a Next() +// to ensure you have access to a valid it.Item(). +func (it *Iterator) Next() { + // Reuse current item + it.item.wg.Wait() // Just cleaner to wait before pushing to avoid doing ref counting. + it.waste.push(it.item) + + // Set next item to current + it.item = it.data.pop() + + for it.iitr.Valid() { + if it.parseItem() { + // parseItem calls one extra next. + // This is used to deal with the complexity of reverse iteration. + break + } + } +} + +func isDeletedOrExpired(meta byte, expiresAt uint64) bool { + if meta&bitDelete > 0 { + return true + } + if expiresAt == 0 { + return false + } + return expiresAt <= uint64(time.Now().Unix()) +} + +// parseItem is a complex function because it needs to handle both forward and reverse iteration +// implementation. We store keys such that their versions are sorted in descending order. This makes +// forward iteration efficient, but revese iteration complicated. This tradeoff is better because +// forward iteration is more common than reverse. +// +// This function advances the iterator. +func (it *Iterator) parseItem() bool { + mi := it.iitr + key := mi.Key() + + setItem := func(item *Item) { + if it.item == nil { + it.item = item + } else { + it.data.push(item) + } + } + + // Skip badger keys. + if !it.opt.internalAccess && bytes.HasPrefix(key, badgerPrefix) { + mi.Next() + return false + } + + // Skip any versions which are beyond the readTs. + version := y.ParseTs(key) + if version > it.readTs { + mi.Next() + return false + } + + if it.opt.AllVersions { + // Return deleted or expired values also, otherwise user can't figure out + // whether the key was deleted. + item := it.newItem() + it.fill(item) + setItem(item) + mi.Next() + return true + } + + // If iterating in forward direction, then just checking the last key against current key would + // be sufficient. + if !it.opt.Reverse { + if y.SameKey(it.lastKey, key) { + mi.Next() + return false + } + // Only track in forward direction. + // We should update lastKey as soon as we find a different key in our snapshot. + // Consider keys: a 5, b 7 (del), b 5. When iterating, lastKey = a. + // Then we see b 7, which is deleted. If we don't store lastKey = b, we'll then return b 5, + // which is wrong. Therefore, update lastKey here. + it.lastKey = y.SafeCopy(it.lastKey, mi.Key()) + } + +FILL: + // If deleted, advance and return. + vs := mi.Value() + if isDeletedOrExpired(vs.Meta, vs.ExpiresAt) { + mi.Next() + return false + } + + item := it.newItem() + it.fill(item) + // fill item based on current cursor position. All Next calls have returned, so reaching here + // means no Next was called. + + mi.Next() // Advance but no fill item yet. + if !it.opt.Reverse || !mi.Valid() { // Forward direction, or invalid. + setItem(item) + return true + } + + // Reverse direction. + nextTs := y.ParseTs(mi.Key()) + mik := y.ParseKey(mi.Key()) + if nextTs <= it.readTs && bytes.Equal(mik, item.key) { + // This is a valid potential candidate. + goto FILL + } + // Ignore the next candidate. Return the current one. + setItem(item) + return true +} + +func (it *Iterator) fill(item *Item) { + vs := it.iitr.Value() + item.meta = vs.Meta + item.userMeta = vs.UserMeta + item.expiresAt = vs.ExpiresAt + + item.version = y.ParseTs(it.iitr.Key()) + item.key = y.SafeCopy(item.key, y.ParseKey(it.iitr.Key())) + + item.vptr = y.SafeCopy(item.vptr, vs.Value) + item.val = nil + if it.opt.PrefetchValues { + item.wg.Add(1) + go func() { + // FIXME we are not handling errors here. + item.prefetchValue() + item.wg.Done() + }() + } +} + +func (it *Iterator) prefetch() { + prefetchSize := 2 + if it.opt.PrefetchValues && it.opt.PrefetchSize > 1 { + prefetchSize = it.opt.PrefetchSize + } + + i := it.iitr + var count int + it.item = nil + for i.Valid() { + if !it.parseItem() { + continue + } + count++ + if count == prefetchSize { + break + } + } +} + +// Seek would seek to the provided key if present. If absent, it would seek to the next smallest key +// greater than the provided key if iterating in the forward direction. Behavior would be reversed if +// iterating backwards. +func (it *Iterator) Seek(key []byte) { + for i := it.data.pop(); i != nil; i = it.data.pop() { + i.wg.Wait() + it.waste.push(i) + } + + it.lastKey = it.lastKey[:0] + if len(key) == 0 { + key = it.opt.Prefix + } + if len(key) == 0 { + it.iitr.Rewind() + it.prefetch() + return + } + + if !it.opt.Reverse { + key = y.KeyWithTs(key, it.txn.readTs) + } else { + key = y.KeyWithTs(key, 0) + } + it.iitr.Seek(key) + it.prefetch() +} + +// Rewind would rewind the iterator cursor all the way to zero-th position, which would be the +// smallest key if iterating forward, and largest if iterating backward. It does not keep track of +// whether the cursor started with a Seek(). +func (it *Iterator) Rewind() { + it.Seek(nil) +} diff --git a/vendor/github.com/dgraph-io/badger/level_handler.go b/vendor/github.com/dgraph-io/badger/level_handler.go new file mode 100644 index 00000000..147967fb --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/level_handler.go @@ -0,0 +1,299 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "fmt" + "sort" + "sync" + + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +type levelHandler struct { + // Guards tables, totalSize. + sync.RWMutex + + // For level >= 1, tables are sorted by key ranges, which do not overlap. + // For level 0, tables are sorted by time. + // For level 0, newest table are at the back. Compact the oldest one first, which is at the front. + tables []*table.Table + totalSize int64 + + // The following are initialized once and const. + level int + strLevel string + maxTotalSize int64 + db *DB +} + +func (s *levelHandler) getTotalSize() int64 { + s.RLock() + defer s.RUnlock() + return s.totalSize +} + +// initTables replaces s.tables with given tables. This is done during loading. +func (s *levelHandler) initTables(tables []*table.Table) { + s.Lock() + defer s.Unlock() + + s.tables = tables + s.totalSize = 0 + for _, t := range tables { + s.totalSize += t.Size() + } + + if s.level == 0 { + // Key range will overlap. Just sort by fileID in ascending order + // because newer tables are at the end of level 0. + sort.Slice(s.tables, func(i, j int) bool { + return s.tables[i].ID() < s.tables[j].ID() + }) + } else { + // Sort tables by keys. + sort.Slice(s.tables, func(i, j int) bool { + return y.CompareKeys(s.tables[i].Smallest(), s.tables[j].Smallest()) < 0 + }) + } +} + +// deleteTables remove tables idx0, ..., idx1-1. +func (s *levelHandler) deleteTables(toDel []*table.Table) error { + s.Lock() // s.Unlock() below + + toDelMap := make(map[uint64]struct{}) + for _, t := range toDel { + toDelMap[t.ID()] = struct{}{} + } + + // Make a copy as iterators might be keeping a slice of tables. + var newTables []*table.Table + for _, t := range s.tables { + _, found := toDelMap[t.ID()] + if !found { + newTables = append(newTables, t) + continue + } + s.totalSize -= t.Size() + } + s.tables = newTables + + s.Unlock() // Unlock s _before_ we DecrRef our tables, which can be slow. + + return decrRefs(toDel) +} + +// replaceTables will replace tables[left:right] with newTables. Note this EXCLUDES tables[right]. +// You must call decr() to delete the old tables _after_ writing the update to the manifest. +func (s *levelHandler) replaceTables(toDel, toAdd []*table.Table) error { + // Need to re-search the range of tables in this level to be replaced as other goroutines might + // be changing it as well. (They can't touch our tables, but if they add/remove other tables, + // the indices get shifted around.) + s.Lock() // We s.Unlock() below. + + toDelMap := make(map[uint64]struct{}) + for _, t := range toDel { + toDelMap[t.ID()] = struct{}{} + } + var newTables []*table.Table + for _, t := range s.tables { + _, found := toDelMap[t.ID()] + if !found { + newTables = append(newTables, t) + continue + } + s.totalSize -= t.Size() + } + + // Increase totalSize first. + for _, t := range toAdd { + s.totalSize += t.Size() + t.IncrRef() + newTables = append(newTables, t) + } + + // Assign tables. + s.tables = newTables + sort.Slice(s.tables, func(i, j int) bool { + return y.CompareKeys(s.tables[i].Smallest(), s.tables[j].Smallest()) < 0 + }) + s.Unlock() // s.Unlock before we DecrRef tables -- that can be slow. + return decrRefs(toDel) +} + +func decrRefs(tables []*table.Table) error { + for _, table := range tables { + if err := table.DecrRef(); err != nil { + return err + } + } + return nil +} + +func newLevelHandler(db *DB, level int) *levelHandler { + return &levelHandler{ + level: level, + strLevel: fmt.Sprintf("l%d", level), + db: db, + } +} + +// tryAddLevel0Table returns true if ok and no stalling. +func (s *levelHandler) tryAddLevel0Table(t *table.Table) bool { + y.AssertTrue(s.level == 0) + // Need lock as we may be deleting the first table during a level 0 compaction. + s.Lock() + defer s.Unlock() + if len(s.tables) >= s.db.opt.NumLevelZeroTablesStall { + return false + } + + s.tables = append(s.tables, t) + t.IncrRef() + s.totalSize += t.Size() + + return true +} + +func (s *levelHandler) numTables() int { + s.RLock() + defer s.RUnlock() + return len(s.tables) +} + +func (s *levelHandler) close() error { + s.RLock() + defer s.RUnlock() + var err error + for _, t := range s.tables { + if closeErr := t.Close(); closeErr != nil && err == nil { + err = closeErr + } + } + return errors.Wrap(err, "levelHandler.close") +} + +// getTableForKey acquires a read-lock to access s.tables. It returns a list of tableHandlers. +func (s *levelHandler) getTableForKey(key []byte) ([]*table.Table, func() error) { + s.RLock() + defer s.RUnlock() + + if s.level == 0 { + // For level 0, we need to check every table. Remember to make a copy as s.tables may change + // once we exit this function, and we don't want to lock s.tables while seeking in tables. + // CAUTION: Reverse the tables. + out := make([]*table.Table, 0, len(s.tables)) + for i := len(s.tables) - 1; i >= 0; i-- { + out = append(out, s.tables[i]) + s.tables[i].IncrRef() + } + return out, func() error { + for _, t := range out { + if err := t.DecrRef(); err != nil { + return err + } + } + return nil + } + } + // For level >= 1, we can do a binary search as key range does not overlap. + idx := sort.Search(len(s.tables), func(i int) bool { + return y.CompareKeys(s.tables[i].Biggest(), key) >= 0 + }) + if idx >= len(s.tables) { + // Given key is strictly > than every element we have. + return nil, func() error { return nil } + } + tbl := s.tables[idx] + tbl.IncrRef() + return []*table.Table{tbl}, tbl.DecrRef +} + +// get returns value for a given key or the key after that. If not found, return nil. +func (s *levelHandler) get(key []byte) (y.ValueStruct, error) { + tables, decr := s.getTableForKey(key) + keyNoTs := y.ParseKey(key) + + var maxVs y.ValueStruct + for _, th := range tables { + if th.DoesNotHave(keyNoTs) { + y.NumLSMBloomHits.Add(s.strLevel, 1) + continue + } + + it := th.NewIterator(false) + defer it.Close() + + y.NumLSMGets.Add(s.strLevel, 1) + it.Seek(key) + if !it.Valid() { + continue + } + if y.SameKey(key, it.Key()) { + if version := y.ParseTs(it.Key()); maxVs.Version < version { + maxVs = it.Value() + maxVs.Version = version + } + } + } + return maxVs, decr() +} + +// appendIterators appends iterators to an array of iterators, for merging. +// Note: This obtains references for the table handlers. Remember to close these iterators. +func (s *levelHandler) appendIterators(iters []y.Iterator, opt *IteratorOptions) []y.Iterator { + s.RLock() + defer s.RUnlock() + + tables := make([]*table.Table, 0, len(s.tables)) + for _, t := range s.tables { + if opt.pickTable(t) { + tables = append(tables, t) + } + } + if len(tables) == 0 { + return iters + } + + if s.level == 0 { + // Remember to add in reverse order! + // The newer table at the end of s.tables should be added first as it takes precedence. + return appendIteratorsReversed(iters, tables, opt.Reverse) + } + return append(iters, table.NewConcatIterator(tables, opt.Reverse)) +} + +type levelHandlerRLocked struct{} + +// overlappingTables returns the tables that intersect with key range. Returns a half-interval. +// This function should already have acquired a read lock, and this is so important the caller must +// pass an empty parameter declaring such. +func (s *levelHandler) overlappingTables(_ levelHandlerRLocked, kr keyRange) (int, int) { + if len(kr.left) == 0 || len(kr.right) == 0 { + return 0, 0 + } + left := sort.Search(len(s.tables), func(i int) bool { + return y.CompareKeys(kr.left, s.tables[i].Biggest()) <= 0 + }) + right := sort.Search(len(s.tables), func(i int) bool { + return y.CompareKeys(kr.right, s.tables[i].Smallest()) < 0 + }) + return left, right +} diff --git a/vendor/github.com/dgraph-io/badger/levels.go b/vendor/github.com/dgraph-io/badger/levels.go new file mode 100644 index 00000000..df90164c --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/levels.go @@ -0,0 +1,986 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "fmt" + "math" + "math/rand" + "os" + "sort" + "strings" + "sync" + "sync/atomic" + "time" + + "golang.org/x/net/trace" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +type levelsController struct { + nextFileID uint64 // Atomic + elog trace.EventLog + + // The following are initialized once and const. + levels []*levelHandler + kv *DB + + cstatus compactStatus +} + +var ( + // This is for getting timings between stalls. + lastUnstalled time.Time +) + +// revertToManifest checks that all necessary table files exist and removes all table files not +// referenced by the manifest. idMap is a set of table file id's that were read from the directory +// listing. +func revertToManifest(kv *DB, mf *Manifest, idMap map[uint64]struct{}) error { + // 1. Check all files in manifest exist. + for id := range mf.Tables { + if _, ok := idMap[id]; !ok { + return fmt.Errorf("file does not exist for table %d", id) + } + } + + // 2. Delete files that shouldn't exist. + for id := range idMap { + if _, ok := mf.Tables[id]; !ok { + kv.elog.Printf("Table file %d not referenced in MANIFEST\n", id) + filename := table.NewFilename(id, kv.opt.Dir) + if err := os.Remove(filename); err != nil { + return y.Wrapf(err, "While removing table %d", id) + } + } + } + + return nil +} + +func newLevelsController(db *DB, mf *Manifest) (*levelsController, error) { + y.AssertTrue(db.opt.NumLevelZeroTablesStall > db.opt.NumLevelZeroTables) + s := &levelsController{ + kv: db, + elog: db.elog, + levels: make([]*levelHandler, db.opt.MaxLevels), + } + s.cstatus.levels = make([]*levelCompactStatus, db.opt.MaxLevels) + + for i := 0; i < db.opt.MaxLevels; i++ { + s.levels[i] = newLevelHandler(db, i) + if i == 0 { + // Do nothing. + } else if i == 1 { + // Level 1 probably shouldn't be too much bigger than level 0. + s.levels[i].maxTotalSize = db.opt.LevelOneSize + } else { + s.levels[i].maxTotalSize = s.levels[i-1].maxTotalSize * int64(db.opt.LevelSizeMultiplier) + } + s.cstatus.levels[i] = new(levelCompactStatus) + } + + // Compare manifest against directory, check for existent/non-existent files, and remove. + if err := revertToManifest(db, mf, getIDMap(db.opt.Dir)); err != nil { + return nil, err + } + + // Some files may be deleted. Let's reload. + var flags uint32 = y.Sync + if db.opt.ReadOnly { + flags |= y.ReadOnly + } + + var mu sync.Mutex + tables := make([][]*table.Table, db.opt.MaxLevels) + var maxFileID uint64 + + // We found that using 3 goroutines allows disk throughput to be utilized to its max. + // Disk utilization is the main thing we should focus on, while trying to read the data. That's + // the one factor that remains constant between HDD and SSD. + throttle := y.NewThrottle(3) + + start := time.Now() + var numOpened int32 + tick := time.NewTicker(3 * time.Second) + defer tick.Stop() + + for fileID, tf := range mf.Tables { + fname := table.NewFilename(fileID, db.opt.Dir) + select { + case <-tick.C: + db.opt.Infof("%d tables out of %d opened in %s\n", atomic.LoadInt32(&numOpened), + len(mf.Tables), time.Since(start).Round(time.Millisecond)) + default: + } + if err := throttle.Do(); err != nil { + closeAllTables(tables) + return nil, err + } + if fileID > maxFileID { + maxFileID = fileID + } + go func(fname string, tf TableManifest) { + var rerr error + defer func() { + throttle.Done(rerr) + atomic.AddInt32(&numOpened, 1) + }() + fd, err := y.OpenExistingFile(fname, flags) + if err != nil { + rerr = errors.Wrapf(err, "Opening file: %q", fname) + return + } + + t, err := table.OpenTable(fd, db.opt.TableLoadingMode, tf.Checksum) + if err != nil { + if strings.HasPrefix(err.Error(), "CHECKSUM_MISMATCH:") { + db.opt.Errorf(err.Error()) + db.opt.Errorf("Ignoring table %s", fd.Name()) + // Do not set rerr. We will continue without this table. + } else { + rerr = errors.Wrapf(err, "Opening table: %q", fname) + } + return + } + + mu.Lock() + tables[tf.Level] = append(tables[tf.Level], t) + mu.Unlock() + }(fname, tf) + } + if err := throttle.Finish(); err != nil { + closeAllTables(tables) + return nil, err + } + db.opt.Infof("All %d tables opened in %s\n", atomic.LoadInt32(&numOpened), + time.Since(start).Round(time.Millisecond)) + s.nextFileID = maxFileID + 1 + for i, tbls := range tables { + s.levels[i].initTables(tbls) + } + + // Make sure key ranges do not overlap etc. + if err := s.validate(); err != nil { + _ = s.cleanupLevels() + return nil, errors.Wrap(err, "Level validation") + } + + // Sync directory (because we have at least removed some files, or previously created the + // manifest file). + if err := syncDir(db.opt.Dir); err != nil { + _ = s.close() + return nil, err + } + + return s, nil +} + +// Closes the tables, for cleanup in newLevelsController. (We Close() instead of using DecrRef() +// because that would delete the underlying files.) We ignore errors, which is OK because tables +// are read-only. +func closeAllTables(tables [][]*table.Table) { + for _, tableSlice := range tables { + for _, table := range tableSlice { + _ = table.Close() + } + } +} + +func (s *levelsController) cleanupLevels() error { + var firstErr error + for _, l := range s.levels { + if err := l.close(); err != nil && firstErr == nil { + firstErr = err + } + } + return firstErr +} + +// dropTree picks all tables from all levels, creates a manifest changeset, +// applies it, and then decrements the refs of these tables, which would result +// in their deletion. +func (s *levelsController) dropTree() (int, error) { + // First pick all tables, so we can create a manifest changelog. + var all []*table.Table + for _, l := range s.levels { + l.RLock() + all = append(all, l.tables...) + l.RUnlock() + } + if len(all) == 0 { + return 0, nil + } + + // Generate the manifest changes. + changes := []*pb.ManifestChange{} + for _, table := range all { + changes = append(changes, newDeleteChange(table.ID())) + } + changeSet := pb.ManifestChangeSet{Changes: changes} + if err := s.kv.manifest.addChanges(changeSet.Changes); err != nil { + return 0, err + } + + // Now that manifest has been successfully written, we can delete the tables. + for _, l := range s.levels { + l.Lock() + l.totalSize = 0 + l.tables = l.tables[:0] + l.Unlock() + } + for _, table := range all { + if err := table.DecrRef(); err != nil { + return 0, err + } + } + return len(all), nil +} + +// dropPrefix runs a L0->L1 compaction, and then runs same level compaction on the rest of the +// levels. For L0->L1 compaction, it runs compactions normally, but skips over all the keys with the +// provided prefix. For Li->Li compactions, it picks up the tables which would have the prefix. The +// tables who only have keys with this prefix are quickly dropped. The ones which have other keys +// are run through MergeIterator and compacted to create new tables. All the mechanisms of +// compactions apply, i.e. level sizes and MANIFEST are updated as in the normal flow. +func (s *levelsController) dropPrefix(prefix []byte) error { + opt := s.kv.opt + for _, l := range s.levels { + l.RLock() + if l.level == 0 { + size := len(l.tables) + l.RUnlock() + + if size > 0 { + cp := compactionPriority{ + level: 0, + score: 1.74, + // A unique number greater than 1.0 does two things. Helps identify this + // function in logs, and forces a compaction. + dropPrefix: prefix, + } + if err := s.doCompact(cp); err != nil { + opt.Warningf("While compacting level 0: %v", err) + return nil + } + } + continue + } + + var tables []*table.Table + for _, table := range l.tables { + var absent bool + switch { + case bytes.HasPrefix(table.Smallest(), prefix): + case bytes.HasPrefix(table.Biggest(), prefix): + case bytes.Compare(prefix, table.Smallest()) > 0 && + bytes.Compare(prefix, table.Biggest()) < 0: + default: + absent = true + } + if !absent { + tables = append(tables, table) + } + } + l.RUnlock() + if len(tables) == 0 { + continue + } + + cd := compactDef{ + elog: trace.New(fmt.Sprintf("Badger.L%d", l.level), "Compact"), + thisLevel: l, + nextLevel: l, + top: []*table.Table{}, + bot: tables, + dropPrefix: prefix, + } + if err := s.runCompactDef(l.level, cd); err != nil { + opt.Warningf("While running compact def: %+v. Error: %v", cd, err) + return err + } + } + return nil +} + +func (s *levelsController) startCompact(lc *y.Closer) { + n := s.kv.opt.NumCompactors + lc.AddRunning(n - 1) + for i := 0; i < n; i++ { + go s.runWorker(lc) + } +} + +func (s *levelsController) runWorker(lc *y.Closer) { + defer lc.Done() + + randomDelay := time.NewTimer(time.Duration(rand.Int31n(1000)) * time.Millisecond) + select { + case <-randomDelay.C: + case <-lc.HasBeenClosed(): + randomDelay.Stop() + return + } + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + select { + // Can add a done channel or other stuff. + case <-ticker.C: + prios := s.pickCompactLevels() + for _, p := range prios { + if err := s.doCompact(p); err == nil { + break + } else if err == errFillTables { + // pass + } else { + s.kv.opt.Warningf("While running doCompact: %v\n", err) + } + } + case <-lc.HasBeenClosed(): + return + } + } +} + +// Returns true if level zero may be compacted, without accounting for compactions that already +// might be happening. +func (s *levelsController) isLevel0Compactable() bool { + return s.levels[0].numTables() >= s.kv.opt.NumLevelZeroTables +} + +// Returns true if the non-zero level may be compacted. delSize provides the size of the tables +// which are currently being compacted so that we treat them as already having started being +// compacted (because they have been, yet their size is already counted in getTotalSize). +func (l *levelHandler) isCompactable(delSize int64) bool { + return l.getTotalSize()-delSize >= l.maxTotalSize +} + +type compactionPriority struct { + level int + score float64 + dropPrefix []byte +} + +// pickCompactLevel determines which level to compact. +// Based on: https://github.com/facebook/rocksdb/wiki/Leveled-Compaction +func (s *levelsController) pickCompactLevels() (prios []compactionPriority) { + // This function must use identical criteria for guaranteeing compaction's progress that + // addLevel0Table uses. + + // cstatus is checked to see if level 0's tables are already being compacted + if !s.cstatus.overlapsWith(0, infRange) && s.isLevel0Compactable() { + pri := compactionPriority{ + level: 0, + score: float64(s.levels[0].numTables()) / float64(s.kv.opt.NumLevelZeroTables), + } + prios = append(prios, pri) + } + + for i, l := range s.levels[1:] { + // Don't consider those tables that are already being compacted right now. + delSize := s.cstatus.delSize(i + 1) + + if l.isCompactable(delSize) { + pri := compactionPriority{ + level: i + 1, + score: float64(l.getTotalSize()-delSize) / float64(l.maxTotalSize), + } + prios = append(prios, pri) + } + } + sort.Slice(prios, func(i, j int) bool { + return prios[i].score > prios[j].score + }) + return prios +} + +// compactBuildTables merge topTables and botTables to form a list of new tables. +func (s *levelsController) compactBuildTables( + lev int, cd compactDef) ([]*table.Table, func() error, error) { + topTables := cd.top + botTables := cd.bot + + var hasOverlap bool + { + kr := getKeyRange(cd.top) + for i, lh := range s.levels { + if i <= lev { // Skip upper levels. + continue + } + lh.RLock() + left, right := lh.overlappingTables(levelHandlerRLocked{}, kr) + lh.RUnlock() + if right-left > 0 { + hasOverlap = true + break + } + } + } + + // Try to collect stats so that we can inform value log about GC. That would help us find which + // value log file should be GCed. + discardStats := make(map[uint32]int64) + updateStats := func(vs y.ValueStruct) { + if vs.Meta&bitValuePointer > 0 { + var vp valuePointer + vp.Decode(vs.Value) + discardStats[vp.Fid] += int64(vp.Len) + } + } + + // Create iterators across all the tables involved first. + var iters []y.Iterator + if lev == 0 { + iters = appendIteratorsReversed(iters, topTables, false) + } else if len(topTables) > 0 { + y.AssertTrue(len(topTables) == 1) + iters = []y.Iterator{topTables[0].NewIterator(false)} + } + + // Next level has level>=1 and we can use ConcatIterator as key ranges do not overlap. + var valid []*table.Table + for _, table := range botTables { + if len(cd.dropPrefix) > 0 && + bytes.HasPrefix(table.Smallest(), cd.dropPrefix) && + bytes.HasPrefix(table.Biggest(), cd.dropPrefix) { + // All the keys in this table have the dropPrefix. So, this table does not need to be + // in the iterator and can be dropped immediately. + continue + } + valid = append(valid, table) + } + iters = append(iters, table.NewConcatIterator(valid, false)) + it := y.NewMergeIterator(iters, false) + defer it.Close() // Important to close the iterator to do ref counting. + + it.Rewind() + + // Pick a discard ts, so we can discard versions below this ts. We should + // never discard any versions starting from above this timestamp, because + // that would affect the snapshot view guarantee provided by transactions. + discardTs := s.kv.orc.discardAtOrBelow() + + // Start generating new tables. + type newTableResult struct { + table *table.Table + err error + } + resultCh := make(chan newTableResult) + var numBuilds, numVersions int + var lastKey, skipKey []byte + for it.Valid() { + timeStart := time.Now() + builder := table.NewTableBuilder() + var numKeys, numSkips uint64 + for ; it.Valid(); it.Next() { + // See if we need to skip the prefix. + if len(cd.dropPrefix) > 0 && bytes.HasPrefix(it.Key(), cd.dropPrefix) { + numSkips++ + updateStats(it.Value()) + continue + } + + // See if we need to skip this key. + if len(skipKey) > 0 { + if y.SameKey(it.Key(), skipKey) { + numSkips++ + updateStats(it.Value()) + continue + } else { + skipKey = skipKey[:0] + } + } + + if !y.SameKey(it.Key(), lastKey) { + if builder.ReachedCapacity(s.kv.opt.MaxTableSize) { + // Only break if we are on a different key, and have reached capacity. We want + // to ensure that all versions of the key are stored in the same sstable, and + // not divided across multiple tables at the same level. + break + } + lastKey = y.SafeCopy(lastKey, it.Key()) + numVersions = 0 + } + + vs := it.Value() + version := y.ParseTs(it.Key()) + // Do not discard entries inserted by merge operator. These entries will be discarded once they're merged + if version <= discardTs && vs.Meta&bitMergeEntry == 0 { + // Keep track of the number of versions encountered for this key. Only consider the + // versions which are below the minReadTs, otherwise, we might end up discarding the + // only valid version for a running transaction. + numVersions++ + lastValidVersion := vs.Meta&bitDiscardEarlierVersions > 0 + if isDeletedOrExpired(vs.Meta, vs.ExpiresAt) || + numVersions > s.kv.opt.NumVersionsToKeep || + lastValidVersion { + // If this version of the key is deleted or expired, skip all the rest of the + // versions. Ensure that we're only removing versions below readTs. + skipKey = y.SafeCopy(skipKey, it.Key()) + + if lastValidVersion { + // Add this key. We have set skipKey, so the following key versions + // would be skipped. + } else if hasOverlap { + // If this key range has overlap with lower levels, then keep the deletion + // marker with the latest version, discarding the rest. We have set skipKey, + // so the following key versions would be skipped. + } else { + // If no overlap, we can skip all the versions, by continuing here. + numSkips++ + updateStats(vs) + continue // Skip adding this key. + } + } + } + numKeys++ + y.Check(builder.Add(it.Key(), it.Value())) + } + // It was true that it.Valid() at least once in the loop above, which means we + // called Add() at least once, and builder is not Empty(). + s.kv.opt.Debugf("LOG Compact. Added %d keys. Skipped %d keys. Iteration took: %v", + numKeys, numSkips, time.Since(timeStart)) + if !builder.Empty() { + numBuilds++ + fileID := s.reserveFileID() + go func(builder *table.Builder) { + defer builder.Close() + + fd, err := y.CreateSyncedFile(table.NewFilename(fileID, s.kv.opt.Dir), true) + if err != nil { + resultCh <- newTableResult{nil, errors.Wrapf(err, "While opening new table: %d", fileID)} + return + } + + if _, err := fd.Write(builder.Finish()); err != nil { + resultCh <- newTableResult{nil, errors.Wrapf(err, "Unable to write to file: %d", fileID)} + return + } + + tbl, err := table.OpenTable(fd, s.kv.opt.TableLoadingMode, nil) + // decrRef is added below. + resultCh <- newTableResult{tbl, errors.Wrapf(err, "Unable to open table: %q", fd.Name())} + }(builder) + } + } + + newTables := make([]*table.Table, 0, 20) + // Wait for all table builders to finish. + var firstErr error + for x := 0; x < numBuilds; x++ { + res := <-resultCh + newTables = append(newTables, res.table) + if firstErr == nil { + firstErr = res.err + } + } + + if firstErr == nil { + // Ensure created files' directory entries are visible. We don't mind the extra latency + // from not doing this ASAP after all file creation has finished because this is a + // background operation. + firstErr = syncDir(s.kv.opt.Dir) + } + + if firstErr != nil { + // An error happened. Delete all the newly created table files (by calling DecrRef + // -- we're the only holders of a ref). + for j := 0; j < numBuilds; j++ { + if newTables[j] != nil { + newTables[j].DecrRef() + } + } + errorReturn := errors.Wrapf(firstErr, "While running compaction for: %+v", cd) + return nil, nil, errorReturn + } + + sort.Slice(newTables, func(i, j int) bool { + return y.CompareKeys(newTables[i].Biggest(), newTables[j].Biggest()) < 0 + }) + s.kv.vlog.updateDiscardStats(discardStats) + s.kv.opt.Debugf("Discard stats: %v", discardStats) + return newTables, func() error { return decrRefs(newTables) }, nil +} + +func buildChangeSet(cd *compactDef, newTables []*table.Table) pb.ManifestChangeSet { + changes := []*pb.ManifestChange{} + for _, table := range newTables { + changes = append(changes, + newCreateChange(table.ID(), cd.nextLevel.level, table.Checksum)) + } + for _, table := range cd.top { + changes = append(changes, newDeleteChange(table.ID())) + } + for _, table := range cd.bot { + changes = append(changes, newDeleteChange(table.ID())) + } + return pb.ManifestChangeSet{Changes: changes} +} + +type compactDef struct { + elog trace.Trace + + thisLevel *levelHandler + nextLevel *levelHandler + + top []*table.Table + bot []*table.Table + + thisRange keyRange + nextRange keyRange + + thisSize int64 + + dropPrefix []byte +} + +func (cd *compactDef) lockLevels() { + cd.thisLevel.RLock() + cd.nextLevel.RLock() +} + +func (cd *compactDef) unlockLevels() { + cd.nextLevel.RUnlock() + cd.thisLevel.RUnlock() +} + +func (s *levelsController) fillTablesL0(cd *compactDef) bool { + cd.lockLevels() + defer cd.unlockLevels() + + cd.top = make([]*table.Table, len(cd.thisLevel.tables)) + copy(cd.top, cd.thisLevel.tables) + if len(cd.top) == 0 { + return false + } + cd.thisRange = infRange + + kr := getKeyRange(cd.top) + left, right := cd.nextLevel.overlappingTables(levelHandlerRLocked{}, kr) + cd.bot = make([]*table.Table, right-left) + copy(cd.bot, cd.nextLevel.tables[left:right]) + + if len(cd.bot) == 0 { + cd.nextRange = kr + } else { + cd.nextRange = getKeyRange(cd.bot) + } + + if !s.cstatus.compareAndAdd(thisAndNextLevelRLocked{}, *cd) { + return false + } + + return true +} + +func (s *levelsController) fillTables(cd *compactDef) bool { + cd.lockLevels() + defer cd.unlockLevels() + + tbls := make([]*table.Table, len(cd.thisLevel.tables)) + copy(tbls, cd.thisLevel.tables) + if len(tbls) == 0 { + return false + } + + // Find the biggest table, and compact that first. + // TODO: Try other table picking strategies. + sort.Slice(tbls, func(i, j int) bool { + return tbls[i].Size() > tbls[j].Size() + }) + + for _, t := range tbls { + cd.thisSize = t.Size() + cd.thisRange = keyRange{ + // We pick all the versions of the smallest and the biggest key. + left: y.KeyWithTs(y.ParseKey(t.Smallest()), math.MaxUint64), + // Note that version zero would be the rightmost key. + right: y.KeyWithTs(y.ParseKey(t.Biggest()), 0), + } + if s.cstatus.overlapsWith(cd.thisLevel.level, cd.thisRange) { + continue + } + cd.top = []*table.Table{t} + left, right := cd.nextLevel.overlappingTables(levelHandlerRLocked{}, cd.thisRange) + + cd.bot = make([]*table.Table, right-left) + copy(cd.bot, cd.nextLevel.tables[left:right]) + + if len(cd.bot) == 0 { + cd.bot = []*table.Table{} + cd.nextRange = cd.thisRange + if !s.cstatus.compareAndAdd(thisAndNextLevelRLocked{}, *cd) { + continue + } + return true + } + cd.nextRange = getKeyRange(cd.bot) + + if s.cstatus.overlapsWith(cd.nextLevel.level, cd.nextRange) { + continue + } + if !s.cstatus.compareAndAdd(thisAndNextLevelRLocked{}, *cd) { + continue + } + return true + } + return false +} + +func (s *levelsController) runCompactDef(l int, cd compactDef) (err error) { + timeStart := time.Now() + + thisLevel := cd.thisLevel + nextLevel := cd.nextLevel + + // Table should never be moved directly between levels, always be rewritten to allow discarding + // invalid versions. + + newTables, decr, err := s.compactBuildTables(l, cd) + if err != nil { + return err + } + defer func() { + // Only assign to err, if it's not already nil. + if decErr := decr(); err == nil { + err = decErr + } + }() + changeSet := buildChangeSet(&cd, newTables) + + // We write to the manifest _before_ we delete files (and after we created files) + if err := s.kv.manifest.addChanges(changeSet.Changes); err != nil { + return err + } + + // See comment earlier in this function about the ordering of these ops, and the order in which + // we access levels when reading. + if err := nextLevel.replaceTables(cd.bot, newTables); err != nil { + return err + } + if err := thisLevel.deleteTables(cd.top); err != nil { + return err + } + + // Note: For level 0, while doCompact is running, it is possible that new tables are added. + // However, the tables are added only to the end, so it is ok to just delete the first table. + + s.kv.opt.Infof("LOG Compact %d->%d, del %d tables, add %d tables, took %v\n", + thisLevel.level, nextLevel.level, len(cd.top)+len(cd.bot), + len(newTables), time.Since(timeStart)) + return nil +} + +var errFillTables = errors.New("Unable to fill tables") + +// doCompact picks some table on level l and compacts it away to the next level. +func (s *levelsController) doCompact(p compactionPriority) error { + l := p.level + y.AssertTrue(l+1 < s.kv.opt.MaxLevels) // Sanity check. + + cd := compactDef{ + elog: trace.New(fmt.Sprintf("Badger.L%d", l), "Compact"), + thisLevel: s.levels[l], + nextLevel: s.levels[l+1], + dropPrefix: p.dropPrefix, + } + cd.elog.SetMaxEvents(100) + defer cd.elog.Finish() + + s.kv.opt.Infof("Got compaction priority: %+v", p) + + // While picking tables to be compacted, both levels' tables are expected to + // remain unchanged. + if l == 0 { + if !s.fillTablesL0(&cd) { + return errFillTables + } + + } else { + if !s.fillTables(&cd) { + return errFillTables + } + } + defer s.cstatus.delete(cd) // Remove the ranges from compaction status. + + s.kv.opt.Infof("Running for level: %d\n", cd.thisLevel.level) + s.cstatus.toLog(cd.elog) + if err := s.runCompactDef(l, cd); err != nil { + // This compaction couldn't be done successfully. + s.kv.opt.Warningf("LOG Compact FAILED with error: %+v: %+v", err, cd) + return err + } + + s.cstatus.toLog(cd.elog) + s.kv.opt.Infof("Compaction for level: %d DONE", cd.thisLevel.level) + return nil +} + +func (s *levelsController) addLevel0Table(t *table.Table) error { + // We update the manifest _before_ the table becomes part of a levelHandler, because at that + // point it could get used in some compaction. This ensures the manifest file gets updated in + // the proper order. (That means this update happens before that of some compaction which + // deletes the table.) + err := s.kv.manifest.addChanges([]*pb.ManifestChange{ + newCreateChange(t.ID(), 0, t.Checksum), + }) + if err != nil { + return err + } + + for !s.levels[0].tryAddLevel0Table(t) { + // Stall. Make sure all levels are healthy before we unstall. + var timeStart time.Time + { + s.elog.Printf("STALLED STALLED STALLED: %v\n", time.Since(lastUnstalled)) + s.cstatus.RLock() + for i := 0; i < s.kv.opt.MaxLevels; i++ { + s.elog.Printf("level=%d. Status=%s Size=%d\n", + i, s.cstatus.levels[i].debug(), s.levels[i].getTotalSize()) + } + s.cstatus.RUnlock() + timeStart = time.Now() + } + // Before we unstall, we need to make sure that level 0 and 1 are healthy. Otherwise, we + // will very quickly fill up level 0 again and if the compaction strategy favors level 0, + // then level 1 is going to super full. + for i := 0; ; i++ { + // Passing 0 for delSize to compactable means we're treating incomplete compactions as + // not having finished -- we wait for them to finish. Also, it's crucial this behavior + // replicates pickCompactLevels' behavior in computing compactability in order to + // guarantee progress. + if !s.isLevel0Compactable() && !s.levels[1].isCompactable(0) { + break + } + time.Sleep(10 * time.Millisecond) + if i%100 == 0 { + prios := s.pickCompactLevels() + s.elog.Printf("Waiting to add level 0 table. Compaction priorities: %+v\n", prios) + i = 0 + } + } + { + s.elog.Printf("UNSTALLED UNSTALLED UNSTALLED: %v\n", time.Since(timeStart)) + lastUnstalled = time.Now() + } + } + + return nil +} + +func (s *levelsController) close() error { + err := s.cleanupLevels() + return errors.Wrap(err, "levelsController.Close") +} + +// get returns the found value if any. If not found, we return nil. +func (s *levelsController) get(key []byte, maxVs *y.ValueStruct) (y.ValueStruct, error) { + // It's important that we iterate the levels from 0 on upward. The reason is, if we iterated + // in opposite order, or in parallel (naively calling all the h.RLock() in some order) we could + // read level L's tables post-compaction and level L+1's tables pre-compaction. (If we do + // parallelize this, we will need to call the h.RLock() function by increasing order of level + // number.) + version := y.ParseTs(key) + for _, h := range s.levels { + vs, err := h.get(key) // Calls h.RLock() and h.RUnlock(). + if err != nil { + return y.ValueStruct{}, errors.Wrapf(err, "get key: %q", key) + } + if vs.Value == nil && vs.Meta == 0 { + continue + } + if maxVs == nil || vs.Version == version { + return vs, nil + } + if maxVs.Version < vs.Version { + *maxVs = vs + } + } + if maxVs != nil { + return *maxVs, nil + } + return y.ValueStruct{}, nil +} + +func appendIteratorsReversed(out []y.Iterator, th []*table.Table, reversed bool) []y.Iterator { + for i := len(th) - 1; i >= 0; i-- { + // This will increment the reference of the table handler. + out = append(out, th[i].NewIterator(reversed)) + } + return out +} + +// appendIterators appends iterators to an array of iterators, for merging. +// Note: This obtains references for the table handlers. Remember to close these iterators. +func (s *levelsController) appendIterators( + iters []y.Iterator, opt *IteratorOptions) []y.Iterator { + // Just like with get, it's important we iterate the levels from 0 on upward, to avoid missing + // data when there's a compaction. + for _, level := range s.levels { + iters = level.appendIterators(iters, opt) + } + return iters +} + +// TableInfo represents the information about a table. +type TableInfo struct { + ID uint64 + Level int + Left []byte + Right []byte + KeyCount uint64 // Number of keys in the table +} + +func (s *levelsController) getTableInfo(withKeysCount bool) (result []TableInfo) { + for _, l := range s.levels { + l.RLock() + for _, t := range l.tables { + var count uint64 + if withKeysCount { + it := t.NewIterator(false) + for it.Rewind(); it.Valid(); it.Next() { + count++ + } + } + + info := TableInfo{ + ID: t.ID(), + Level: l.level, + Left: t.Smallest(), + Right: t.Biggest(), + KeyCount: count, + } + result = append(result, info) + } + l.RUnlock() + } + sort.Slice(result, func(i, j int) bool { + if result[i].Level != result[j].Level { + return result[i].Level < result[j].Level + } + return result[i].ID < result[j].ID + }) + return +} diff --git a/vendor/github.com/dgraph-io/badger/logger.go b/vendor/github.com/dgraph-io/badger/logger.go new file mode 100644 index 00000000..3a9b8a33 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/logger.go @@ -0,0 +1,85 @@ +/* + * Copyright 2018 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "log" + "os" +) + +// Logger is implemented by any logging system that is used for standard logs. +type Logger interface { + Errorf(string, ...interface{}) + Warningf(string, ...interface{}) + Infof(string, ...interface{}) + Debugf(string, ...interface{}) +} + +// Errorf logs an ERROR log message to the logger specified in opts or to the +// global logger if no logger is specified in opts. +func (opt *Options) Errorf(format string, v ...interface{}) { + if opt.Logger == nil { + return + } + opt.Logger.Errorf(format, v...) +} + +// Infof logs an INFO message to the logger specified in opts. +func (opt *Options) Infof(format string, v ...interface{}) { + if opt.Logger == nil { + return + } + opt.Logger.Infof(format, v...) +} + +// Warningf logs a WARNING message to the logger specified in opts. +func (opt *Options) Warningf(format string, v ...interface{}) { + if opt.Logger == nil { + return + } + opt.Logger.Warningf(format, v...) +} + +// Debugf logs a DEBUG message to the logger specified in opts. +func (opt *Options) Debugf(format string, v ...interface{}) { + if opt.Logger == nil { + return + } + opt.Logger.Debugf(format, v...) +} + +type defaultLog struct { + *log.Logger +} + +var defaultLogger = &defaultLog{Logger: log.New(os.Stderr, "badger ", log.LstdFlags)} + +func (l *defaultLog) Errorf(f string, v ...interface{}) { + l.Printf("ERROR: "+f, v...) +} + +func (l *defaultLog) Warningf(f string, v ...interface{}) { + l.Printf("WARNING: "+f, v...) +} + +func (l *defaultLog) Infof(f string, v ...interface{}) { + l.Printf("INFO: "+f, v...) +} + +func (l *defaultLog) Debugf(f string, v ...interface{}) { + l.Printf("DEBUG: "+f, v...) +} diff --git a/vendor/github.com/dgraph-io/badger/managed_db.go b/vendor/github.com/dgraph-io/badger/managed_db.go new file mode 100644 index 00000000..4de226ae --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/managed_db.go @@ -0,0 +1,68 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +// OpenManaged returns a new DB, which allows more control over setting +// transaction timestamps, aka managed mode. +// +// This is only useful for databases built on top of Badger (like Dgraph), and +// can be ignored by most users. +func OpenManaged(opts Options) (*DB, error) { + opts.managedTxns = true + return Open(opts) +} + +// NewTransactionAt follows the same logic as DB.NewTransaction(), but uses the +// provided read timestamp. +// +// This is only useful for databases built on top of Badger (like Dgraph), and +// can be ignored by most users. +func (db *DB) NewTransactionAt(readTs uint64, update bool) *Txn { + if !db.opt.managedTxns { + panic("Cannot use NewTransactionAt with managedDB=false. Use NewTransaction instead.") + } + txn := db.newTransaction(update, true) + txn.readTs = readTs + return txn +} + +// CommitAt commits the transaction, following the same logic as Commit(), but +// at the given commit timestamp. This will panic if not used with managed transactions. +// +// This is only useful for databases built on top of Badger (like Dgraph), and +// can be ignored by most users. +func (txn *Txn) CommitAt(commitTs uint64, callback func(error)) error { + if !txn.db.opt.managedTxns { + panic("Cannot use CommitAt with managedDB=false. Use Commit instead.") + } + txn.commitTs = commitTs + if callback == nil { + return txn.Commit() + } + txn.CommitWith(callback) + return nil +} + +// SetDiscardTs sets a timestamp at or below which, any invalid or deleted +// versions can be discarded from the LSM tree, and thence from the value log to +// reclaim disk space. Can only be used with managed transactions. +func (db *DB) SetDiscardTs(ts uint64) { + if !db.opt.managedTxns { + panic("Cannot use SetDiscardTs with managedDB=false.") + } + db.orc.setDiscardTs(ts) +} diff --git a/vendor/github.com/dgraph-io/badger/manifest.go b/vendor/github.com/dgraph-io/badger/manifest.go new file mode 100644 index 00000000..34ce1217 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/manifest.go @@ -0,0 +1,436 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "hash/crc32" + "io" + "os" + "path/filepath" + "sync" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +// Manifest represents the contents of the MANIFEST file in a Badger store. +// +// The MANIFEST file describes the startup state of the db -- all LSM files and what level they're +// at. +// +// It consists of a sequence of ManifestChangeSet objects. Each of these is treated atomically, +// and contains a sequence of ManifestChange's (file creations/deletions) which we use to +// reconstruct the manifest at startup. +type Manifest struct { + Levels []levelManifest + Tables map[uint64]TableManifest + + // Contains total number of creation and deletion changes in the manifest -- used to compute + // whether it'd be useful to rewrite the manifest. + Creations int + Deletions int +} + +func createManifest() Manifest { + levels := make([]levelManifest, 0) + return Manifest{ + Levels: levels, + Tables: make(map[uint64]TableManifest), + } +} + +// levelManifest contains information about LSM tree levels +// in the MANIFEST file. +type levelManifest struct { + Tables map[uint64]struct{} // Set of table id's +} + +// TableManifest contains information about a specific level +// in the LSM tree. +type TableManifest struct { + Level uint8 + Checksum []byte +} + +// manifestFile holds the file pointer (and other info) about the manifest file, which is a log +// file we append to. +type manifestFile struct { + fp *os.File + directory string + // We make this configurable so that unit tests can hit rewrite() code quickly + deletionsRewriteThreshold int + + // Guards appends, which includes access to the manifest field. + appendLock sync.Mutex + + // Used to track the current state of the manifest, used when rewriting. + manifest Manifest +} + +const ( + // ManifestFilename is the filename for the manifest file. + ManifestFilename = "MANIFEST" + manifestRewriteFilename = "MANIFEST-REWRITE" + manifestDeletionsRewriteThreshold = 10000 + manifestDeletionsRatio = 10 +) + +// asChanges returns a sequence of changes that could be used to recreate the Manifest in its +// present state. +func (m *Manifest) asChanges() []*pb.ManifestChange { + changes := make([]*pb.ManifestChange, 0, len(m.Tables)) + for id, tm := range m.Tables { + changes = append(changes, newCreateChange(id, int(tm.Level), tm.Checksum)) + } + return changes +} + +func (m *Manifest) clone() Manifest { + changeSet := pb.ManifestChangeSet{Changes: m.asChanges()} + ret := createManifest() + y.Check(applyChangeSet(&ret, &changeSet)) + return ret +} + +// openOrCreateManifestFile opens a Badger manifest file if it exists, or creates on if +// one doesn’t. +func openOrCreateManifestFile(dir string, readOnly bool) (ret *manifestFile, result Manifest, err error) { + return helpOpenOrCreateManifestFile(dir, readOnly, manifestDeletionsRewriteThreshold) +} + +func helpOpenOrCreateManifestFile(dir string, readOnly bool, deletionsThreshold int) (ret *manifestFile, result Manifest, err error) { + path := filepath.Join(dir, ManifestFilename) + var flags uint32 + if readOnly { + flags |= y.ReadOnly + } + fp, err := y.OpenExistingFile(path, flags) // We explicitly sync in addChanges, outside the lock. + if err != nil { + if !os.IsNotExist(err) { + return nil, Manifest{}, err + } + if readOnly { + return nil, Manifest{}, fmt.Errorf("no manifest found, required for read-only db") + } + m := createManifest() + fp, netCreations, err := helpRewrite(dir, &m) + if err != nil { + return nil, Manifest{}, err + } + y.AssertTrue(netCreations == 0) + mf := &manifestFile{ + fp: fp, + directory: dir, + manifest: m.clone(), + deletionsRewriteThreshold: deletionsThreshold, + } + return mf, m, nil + } + + manifest, truncOffset, err := ReplayManifestFile(fp) + if err != nil { + _ = fp.Close() + return nil, Manifest{}, err + } + + if !readOnly { + // Truncate file so we don't have a half-written entry at the end. + if err := fp.Truncate(truncOffset); err != nil { + _ = fp.Close() + return nil, Manifest{}, err + } + } + if _, err = fp.Seek(0, io.SeekEnd); err != nil { + _ = fp.Close() + return nil, Manifest{}, err + } + + mf := &manifestFile{ + fp: fp, + directory: dir, + manifest: manifest.clone(), + deletionsRewriteThreshold: deletionsThreshold, + } + return mf, manifest, nil +} + +func (mf *manifestFile) close() error { + return mf.fp.Close() +} + +// addChanges writes a batch of changes, atomically, to the file. By "atomically" that means when +// we replay the MANIFEST file, we'll either replay all the changes or none of them. (The truth of +// this depends on the filesystem -- some might append garbage data if a system crash happens at +// the wrong time.) +func (mf *manifestFile) addChanges(changesParam []*pb.ManifestChange) error { + changes := pb.ManifestChangeSet{Changes: changesParam} + buf, err := changes.Marshal() + if err != nil { + return err + } + + // Maybe we could use O_APPEND instead (on certain file systems) + mf.appendLock.Lock() + if err := applyChangeSet(&mf.manifest, &changes); err != nil { + mf.appendLock.Unlock() + return err + } + // Rewrite manifest if it'd shrink by 1/10 and it's big enough to care + if mf.manifest.Deletions > mf.deletionsRewriteThreshold && + mf.manifest.Deletions > manifestDeletionsRatio*(mf.manifest.Creations-mf.manifest.Deletions) { + if err := mf.rewrite(); err != nil { + mf.appendLock.Unlock() + return err + } + } else { + var lenCrcBuf [8]byte + binary.BigEndian.PutUint32(lenCrcBuf[0:4], uint32(len(buf))) + binary.BigEndian.PutUint32(lenCrcBuf[4:8], crc32.Checksum(buf, y.CastagnoliCrcTable)) + buf = append(lenCrcBuf[:], buf...) + if _, err := mf.fp.Write(buf); err != nil { + mf.appendLock.Unlock() + return err + } + } + + mf.appendLock.Unlock() + return mf.fp.Sync() +} + +// Has to be 4 bytes. The value can never change, ever, anyway. +var magicText = [4]byte{'B', 'd', 'g', 'r'} + +// The magic version number. +const magicVersion = 4 + +func helpRewrite(dir string, m *Manifest) (*os.File, int, error) { + rewritePath := filepath.Join(dir, manifestRewriteFilename) + // We explicitly sync. + fp, err := y.OpenTruncFile(rewritePath, false) + if err != nil { + return nil, 0, err + } + + buf := make([]byte, 8) + copy(buf[0:4], magicText[:]) + binary.BigEndian.PutUint32(buf[4:8], magicVersion) + + netCreations := len(m.Tables) + changes := m.asChanges() + set := pb.ManifestChangeSet{Changes: changes} + + changeBuf, err := set.Marshal() + if err != nil { + fp.Close() + return nil, 0, err + } + var lenCrcBuf [8]byte + binary.BigEndian.PutUint32(lenCrcBuf[0:4], uint32(len(changeBuf))) + binary.BigEndian.PutUint32(lenCrcBuf[4:8], crc32.Checksum(changeBuf, y.CastagnoliCrcTable)) + buf = append(buf, lenCrcBuf[:]...) + buf = append(buf, changeBuf...) + if _, err := fp.Write(buf); err != nil { + fp.Close() + return nil, 0, err + } + if err := fp.Sync(); err != nil { + fp.Close() + return nil, 0, err + } + + // In Windows the files should be closed before doing a Rename. + if err = fp.Close(); err != nil { + return nil, 0, err + } + manifestPath := filepath.Join(dir, ManifestFilename) + if err := os.Rename(rewritePath, manifestPath); err != nil { + return nil, 0, err + } + fp, err = y.OpenExistingFile(manifestPath, 0) + if err != nil { + return nil, 0, err + } + if _, err := fp.Seek(0, io.SeekEnd); err != nil { + fp.Close() + return nil, 0, err + } + if err := syncDir(dir); err != nil { + fp.Close() + return nil, 0, err + } + + return fp, netCreations, nil +} + +// Must be called while appendLock is held. +func (mf *manifestFile) rewrite() error { + // In Windows the files should be closed before doing a Rename. + if err := mf.fp.Close(); err != nil { + return err + } + fp, netCreations, err := helpRewrite(mf.directory, &mf.manifest) + if err != nil { + return err + } + mf.fp = fp + mf.manifest.Creations = netCreations + mf.manifest.Deletions = 0 + + return nil +} + +type countingReader struct { + wrapped *bufio.Reader + count int64 +} + +func (r *countingReader) Read(p []byte) (n int, err error) { + n, err = r.wrapped.Read(p) + r.count += int64(n) + return +} + +func (r *countingReader) ReadByte() (b byte, err error) { + b, err = r.wrapped.ReadByte() + if err == nil { + r.count++ + } + return +} + +var ( + errBadMagic = errors.New("manifest has bad magic") +) + +// ReplayManifestFile reads the manifest file and constructs two manifest objects. (We need one +// immutable copy and one mutable copy of the manifest. Easiest way is to construct two of them.) +// Also, returns the last offset after a completely read manifest entry -- the file must be +// truncated at that point before further appends are made (if there is a partial entry after +// that). In normal conditions, truncOffset is the file size. +func ReplayManifestFile(fp *os.File) (ret Manifest, truncOffset int64, err error) { + r := countingReader{wrapped: bufio.NewReader(fp)} + + var magicBuf [8]byte + if _, err := io.ReadFull(&r, magicBuf[:]); err != nil { + return Manifest{}, 0, errBadMagic + } + if !bytes.Equal(magicBuf[0:4], magicText[:]) { + return Manifest{}, 0, errBadMagic + } + version := binary.BigEndian.Uint32(magicBuf[4:8]) + if version != magicVersion { + return Manifest{}, 0, + fmt.Errorf("manifest has unsupported version: %d (we support %d)", version, magicVersion) + } + + build := createManifest() + var offset int64 + for { + offset = r.count + var lenCrcBuf [8]byte + _, err := io.ReadFull(&r, lenCrcBuf[:]) + if err != nil { + if err == io.EOF || err == io.ErrUnexpectedEOF { + break + } + return Manifest{}, 0, err + } + length := binary.BigEndian.Uint32(lenCrcBuf[0:4]) + var buf = make([]byte, length) + if _, err := io.ReadFull(&r, buf); err != nil { + if err == io.EOF || err == io.ErrUnexpectedEOF { + break + } + return Manifest{}, 0, err + } + if crc32.Checksum(buf, y.CastagnoliCrcTable) != binary.BigEndian.Uint32(lenCrcBuf[4:8]) { + break + } + + var changeSet pb.ManifestChangeSet + if err := changeSet.Unmarshal(buf); err != nil { + return Manifest{}, 0, err + } + + if err := applyChangeSet(&build, &changeSet); err != nil { + return Manifest{}, 0, err + } + } + + return build, offset, err +} + +func applyManifestChange(build *Manifest, tc *pb.ManifestChange) error { + switch tc.Op { + case pb.ManifestChange_CREATE: + if _, ok := build.Tables[tc.Id]; ok { + return fmt.Errorf("MANIFEST invalid, table %d exists", tc.Id) + } + build.Tables[tc.Id] = TableManifest{ + Level: uint8(tc.Level), + Checksum: append([]byte{}, tc.Checksum...), + } + for len(build.Levels) <= int(tc.Level) { + build.Levels = append(build.Levels, levelManifest{make(map[uint64]struct{})}) + } + build.Levels[tc.Level].Tables[tc.Id] = struct{}{} + build.Creations++ + case pb.ManifestChange_DELETE: + tm, ok := build.Tables[tc.Id] + if !ok { + return fmt.Errorf("MANIFEST removes non-existing table %d", tc.Id) + } + delete(build.Levels[tm.Level].Tables, tc.Id) + delete(build.Tables, tc.Id) + build.Deletions++ + default: + return fmt.Errorf("MANIFEST file has invalid manifestChange op") + } + return nil +} + +// This is not a "recoverable" error -- opening the KV store fails because the MANIFEST file is +// just plain broken. +func applyChangeSet(build *Manifest, changeSet *pb.ManifestChangeSet) error { + for _, change := range changeSet.Changes { + if err := applyManifestChange(build, change); err != nil { + return err + } + } + return nil +} + +func newCreateChange(id uint64, level int, checksum []byte) *pb.ManifestChange { + return &pb.ManifestChange{ + Id: id, + Op: pb.ManifestChange_CREATE, + Level: uint32(level), + Checksum: checksum, + } +} + +func newDeleteChange(id uint64) *pb.ManifestChange { + return &pb.ManifestChange{ + Id: id, + Op: pb.ManifestChange_DELETE, + } +} diff --git a/vendor/github.com/dgraph-io/badger/merge.go b/vendor/github.com/dgraph-io/badger/merge.go new file mode 100644 index 00000000..7bca447a --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/merge.go @@ -0,0 +1,173 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "sync" + "time" + + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +// MergeOperator represents a Badger merge operator. +type MergeOperator struct { + sync.RWMutex + f MergeFunc + db *DB + key []byte + closer *y.Closer +} + +// MergeFunc accepts two byte slices, one representing an existing value, and +// another representing a new value that needs to be ‘merged’ into it. MergeFunc +// contains the logic to perform the ‘merge’ and return an updated value. +// MergeFunc could perform operations like integer addition, list appends etc. +// Note that the ordering of the operands is unspecified, so the merge func +// should either be agnostic to ordering or do additional handling if ordering +// is required. +type MergeFunc func(existing, val []byte) []byte + +// GetMergeOperator creates a new MergeOperator for a given key and returns a +// pointer to it. It also fires off a goroutine that performs a compaction using +// the merge function that runs periodically, as specified by dur. +func (db *DB) GetMergeOperator(key []byte, + f MergeFunc, dur time.Duration) *MergeOperator { + op := &MergeOperator{ + f: f, + db: db, + key: key, + closer: y.NewCloser(1), + } + + go op.runCompactions(dur) + return op +} + +var errNoMerge = errors.New("No need for merge") + +func (op *MergeOperator) iterateAndMerge(txn *Txn) (val []byte, err error) { + opt := DefaultIteratorOptions + opt.AllVersions = true + it := txn.NewKeyIterator(op.key, opt) + defer it.Close() + + var numVersions int + for it.Rewind(); it.Valid(); it.Next() { + item := it.Item() + numVersions++ + if numVersions == 1 { + val, err = item.ValueCopy(val) + if err != nil { + return nil, err + } + } else { + if err := item.Value(func(newVal []byte) error { + val = op.f(val, newVal) + return nil + }); err != nil { + return nil, err + } + } + if item.DiscardEarlierVersions() { + break + } + } + if numVersions == 0 { + return nil, ErrKeyNotFound + } else if numVersions == 1 { + return val, errNoMerge + } + return val, nil +} + +func (op *MergeOperator) compact() error { + op.Lock() + defer op.Unlock() + err := op.db.Update(func(txn *Txn) error { + var ( + val []byte + err error + ) + val, err = op.iterateAndMerge(txn) + if err != nil { + return err + } + // Write value back to the DB. It is important that we do not set the bitMergeEntry bit + // here. When compaction happens, all the older merged entries will be removed. + return txn.SetWithDiscard(op.key, val, 0) + }) + + if err == ErrKeyNotFound || err == errNoMerge { + // pass. + } else if err != nil { + return err + } + return nil +} + +func (op *MergeOperator) runCompactions(dur time.Duration) { + ticker := time.NewTicker(dur) + defer op.closer.Done() + var stop bool + for { + select { + case <-op.closer.HasBeenClosed(): + stop = true + case <-ticker.C: // wait for tick + } + if err := op.compact(); err != nil { + op.db.opt.Errorf("failure while running merge operation: %s", err) + } + if stop { + ticker.Stop() + break + } + } +} + +// Add records a value in Badger which will eventually be merged by a background +// routine into the values that were recorded by previous invocations to Add(). +func (op *MergeOperator) Add(val []byte) error { + return op.db.Update(func(txn *Txn) error { + return txn.setMergeEntry(op.key, val) + }) +} + +// Get returns the latest value for the merge operator, which is derived by +// applying the merge function to all the values added so far. +// +// If Add has not been called even once, Get will return ErrKeyNotFound. +func (op *MergeOperator) Get() ([]byte, error) { + op.RLock() + defer op.RUnlock() + var existing []byte + err := op.db.View(func(txn *Txn) (err error) { + existing, err = op.iterateAndMerge(txn) + return err + }) + if err == errNoMerge { + return existing, nil + } + return existing, err +} + +// Stop waits for any pending merge to complete and then stops the background +// goroutine. +func (op *MergeOperator) Stop() { + op.closer.SignalAndWait() +} diff --git a/vendor/github.com/dgraph-io/badger/options.go b/vendor/github.com/dgraph-io/badger/options.go new file mode 100644 index 00000000..560b65b2 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/options.go @@ -0,0 +1,174 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "github.com/dgraph-io/badger/options" +) + +// NOTE: Keep the comments in the following to 75 chars width, so they +// format nicely in godoc. + +// Options are params for creating DB object. +// +// This package provides DefaultOptions which contains options that should +// work for most applications. Consider using that as a starting point before +// customizing it for your own needs. +type Options struct { + // 1. Mandatory flags + // ------------------- + // Directory to store the data in. If it doesn't exist, Badger will + // try to create it for you. + Dir string + // Directory to store the value log in. Can be the same as Dir. If it + // doesn't exist, Badger will try to create it for you. + ValueDir string + + // 2. Frequently modified flags + // ----------------------------- + // Sync all writes to disk. Setting this to false would achieve better + // performance, but may cause data to be lost. + SyncWrites bool + + // How should LSM tree be accessed. + TableLoadingMode options.FileLoadingMode + + // How should value log be accessed. + ValueLogLoadingMode options.FileLoadingMode + + // How many versions to keep per key. + NumVersionsToKeep int + + // Open the DB as read-only. With this set, multiple processes can + // open the same Badger DB. Note: if the DB being opened had crashed + // before and has vlog data to be replayed, ReadOnly will cause Open + // to fail with an appropriate message. + ReadOnly bool + + // Truncate value log to delete corrupt data, if any. Would not truncate if ReadOnly is set. + Truncate bool + + // DB-specific logger which will override the global logger. + Logger Logger + + // 3. Flags that user might want to review + // ---------------------------------------- + // The following affect all levels of LSM tree. + MaxTableSize int64 // Each table (or file) is at most this size. + LevelSizeMultiplier int // Equals SizeOf(Li+1)/SizeOf(Li). + MaxLevels int // Maximum number of levels of compaction. + // If value size >= this threshold, only store value offsets in tree. + ValueThreshold int + // Maximum number of tables to keep in memory, before stalling. + NumMemtables int + // The following affect how we handle LSM tree L0. + // Maximum number of Level 0 tables before we start compacting. + NumLevelZeroTables int + + // If we hit this number of Level 0 tables, we will stall until L0 is + // compacted away. + NumLevelZeroTablesStall int + + // Maximum total size for L1. + LevelOneSize int64 + + // Size of single value log file. + ValueLogFileSize int64 + + // Max number of entries a value log file can hold (approximately). A value log file would be + // determined by the smaller of its file size and max entries. + ValueLogMaxEntries uint32 + + // Number of compaction workers to run concurrently. Setting this to zero would stop compactions + // to happen within LSM tree. If set to zero, writes could block forever. + NumCompactors int + + // When closing the DB, force compact Level 0. This ensures that both reads and writes are + // efficient when the DB is opened later. + CompactL0OnClose bool + + // After this many number of value log file rotates, there would be a force flushing of memtable + // to disk. This is useful in write loads with fewer keys and larger values. This work load + // would fill up the value logs quickly, while not filling up the Memtables. Thus, on a crash + // and restart, the value log head could cause the replay of a good number of value log files + // which can slow things on start. + LogRotatesToFlush int32 + + // Transaction start and commit timestamps are managed by end-user. + // This is only useful for databases built on top of Badger (like Dgraph). + // Not recommended for most users. + managedTxns bool + + // 4. Flags for testing purposes + // ------------------------------ + maxBatchCount int64 // max entries in batch + maxBatchSize int64 // max batch size in bytes + +} + +// DefaultOptions sets a list of recommended options for good performance. +// Feel free to modify these to suit your needs. +var DefaultOptions = Options{ + LevelOneSize: 256 << 20, + LevelSizeMultiplier: 10, + TableLoadingMode: options.MemoryMap, + ValueLogLoadingMode: options.MemoryMap, + // table.MemoryMap to mmap() the tables. + // table.Nothing to not preload the tables. + MaxLevels: 7, + MaxTableSize: 64 << 20, + NumCompactors: 2, // Compactions can be expensive. Only run 2. + NumLevelZeroTables: 5, + NumLevelZeroTablesStall: 10, + NumMemtables: 5, + SyncWrites: true, + NumVersionsToKeep: 1, + CompactL0OnClose: true, + // Nothing to read/write value log using standard File I/O + // MemoryMap to mmap() the value log files + // (2^30 - 1)*2 when mmapping < 2^31 - 1, max int32. + // -1 so 2*ValueLogFileSize won't overflow on 32-bit systems. + ValueLogFileSize: 1<<30 - 1, + + ValueLogMaxEntries: 1000000, + ValueThreshold: 32, + Truncate: false, + Logger: defaultLogger, + LogRotatesToFlush: 2, +} + +// LSMOnlyOptions follows from DefaultOptions, but sets a higher ValueThreshold +// so values would be colocated with the LSM tree, with value log largely acting +// as a write-ahead log only. These options would reduce the disk usage of value +// log, and make Badger act more like a typical LSM tree. +var LSMOnlyOptions = Options{} + +func init() { + LSMOnlyOptions = DefaultOptions + + LSMOnlyOptions.ValueThreshold = 65500 // Max value length which fits in uint16. + // Let's not set any other options, because they can cause issues with the + // size of key-value a user can pass to Badger. For e.g., if we set + // ValueLogFileSize to 64MB, a user can't pass a value more than that. + // Setting it to ValueLogMaxEntries to 1000, can generate too many files. + // These options are better configured on a usage basis, than broadly here. + // The ValueThreshold is the most important setting a user needs to do to + // achieve a heavier usage of LSM tree. + // NOTE: If a user does not want to set 64KB as the ValueThreshold because + // of performance reasons, 1KB would be a good option too, allowing + // values smaller than 1KB to be colocated with the keys in the LSM tree. +} diff --git a/vendor/github.com/dgraph-io/badger/options/options.go b/vendor/github.com/dgraph-io/badger/options/options.go new file mode 100644 index 00000000..06c8b1b7 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/options/options.go @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package options + +// FileLoadingMode specifies how data in LSM table files and value log files should +// be loaded. +type FileLoadingMode int + +const ( + // FileIO indicates that files must be loaded using standard I/O + FileIO FileLoadingMode = iota + // LoadToRAM indicates that file must be loaded into RAM + LoadToRAM + // MemoryMap indicates that that the file must be memory-mapped + MemoryMap +) diff --git a/vendor/github.com/dgraph-io/badger/pb/gen.sh b/vendor/github.com/dgraph-io/badger/pb/gen.sh new file mode 100755 index 00000000..49b44ff4 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/pb/gen.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# You might need to go get -v github.com/gogo/protobuf/... + +protos=${GOPATH-$HOME/go}/src/github.com/dgraph-io/badger/pb +pushd $protos > /dev/null +protoc --gofast_out=plugins=grpc:. -I=. pb.proto diff --git a/vendor/github.com/dgraph-io/badger/pb/pb.pb.go b/vendor/github.com/dgraph-io/badger/pb/pb.pb.go new file mode 100644 index 00000000..f9a2c6ee --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/pb/pb.pb.go @@ -0,0 +1,1313 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pb.proto + +package pb + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type ManifestChange_Operation int32 + +const ( + ManifestChange_CREATE ManifestChange_Operation = 0 + ManifestChange_DELETE ManifestChange_Operation = 1 +) + +var ManifestChange_Operation_name = map[int32]string{ + 0: "CREATE", + 1: "DELETE", +} + +var ManifestChange_Operation_value = map[string]int32{ + "CREATE": 0, + "DELETE": 1, +} + +func (x ManifestChange_Operation) String() string { + return proto.EnumName(ManifestChange_Operation_name, int32(x)) +} + +func (ManifestChange_Operation) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{3, 0} +} + +type KV struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + UserMeta []byte `protobuf:"bytes,3,opt,name=user_meta,json=userMeta,proto3" json:"user_meta,omitempty"` + Version uint64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` + ExpiresAt uint64 `protobuf:"varint,5,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + Meta []byte `protobuf:"bytes,6,opt,name=meta,proto3" json:"meta,omitempty"` + // Stream id is used to identify which stream the KV came from. + StreamId uint32 `protobuf:"varint,10,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *KV) Reset() { *m = KV{} } +func (m *KV) String() string { return proto.CompactTextString(m) } +func (*KV) ProtoMessage() {} +func (*KV) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{0} +} +func (m *KV) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KV) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KV.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *KV) XXX_Merge(src proto.Message) { + xxx_messageInfo_KV.Merge(m, src) +} +func (m *KV) XXX_Size() int { + return m.Size() +} +func (m *KV) XXX_DiscardUnknown() { + xxx_messageInfo_KV.DiscardUnknown(m) +} + +var xxx_messageInfo_KV proto.InternalMessageInfo + +func (m *KV) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *KV) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *KV) GetUserMeta() []byte { + if m != nil { + return m.UserMeta + } + return nil +} + +func (m *KV) GetVersion() uint64 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *KV) GetExpiresAt() uint64 { + if m != nil { + return m.ExpiresAt + } + return 0 +} + +func (m *KV) GetMeta() []byte { + if m != nil { + return m.Meta + } + return nil +} + +func (m *KV) GetStreamId() uint32 { + if m != nil { + return m.StreamId + } + return 0 +} + +type KVList struct { + Kv []*KV `protobuf:"bytes,1,rep,name=kv,proto3" json:"kv,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *KVList) Reset() { *m = KVList{} } +func (m *KVList) String() string { return proto.CompactTextString(m) } +func (*KVList) ProtoMessage() {} +func (*KVList) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{1} +} +func (m *KVList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KVList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KVList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *KVList) XXX_Merge(src proto.Message) { + xxx_messageInfo_KVList.Merge(m, src) +} +func (m *KVList) XXX_Size() int { + return m.Size() +} +func (m *KVList) XXX_DiscardUnknown() { + xxx_messageInfo_KVList.DiscardUnknown(m) +} + +var xxx_messageInfo_KVList proto.InternalMessageInfo + +func (m *KVList) GetKv() []*KV { + if m != nil { + return m.Kv + } + return nil +} + +type ManifestChangeSet struct { + // A set of changes that are applied atomically. + Changes []*ManifestChange `protobuf:"bytes,1,rep,name=changes,proto3" json:"changes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ManifestChangeSet) Reset() { *m = ManifestChangeSet{} } +func (m *ManifestChangeSet) String() string { return proto.CompactTextString(m) } +func (*ManifestChangeSet) ProtoMessage() {} +func (*ManifestChangeSet) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{2} +} +func (m *ManifestChangeSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ManifestChangeSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ManifestChangeSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ManifestChangeSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_ManifestChangeSet.Merge(m, src) +} +func (m *ManifestChangeSet) XXX_Size() int { + return m.Size() +} +func (m *ManifestChangeSet) XXX_DiscardUnknown() { + xxx_messageInfo_ManifestChangeSet.DiscardUnknown(m) +} + +var xxx_messageInfo_ManifestChangeSet proto.InternalMessageInfo + +func (m *ManifestChangeSet) GetChanges() []*ManifestChange { + if m != nil { + return m.Changes + } + return nil +} + +type ManifestChange struct { + Id uint64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` + Op ManifestChange_Operation `protobuf:"varint,2,opt,name=Op,proto3,enum=pb.ManifestChange_Operation" json:"Op,omitempty"` + Level uint32 `protobuf:"varint,3,opt,name=Level,proto3" json:"Level,omitempty"` + Checksum []byte `protobuf:"bytes,4,opt,name=Checksum,proto3" json:"Checksum,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ManifestChange) Reset() { *m = ManifestChange{} } +func (m *ManifestChange) String() string { return proto.CompactTextString(m) } +func (*ManifestChange) ProtoMessage() {} +func (*ManifestChange) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{3} +} +func (m *ManifestChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ManifestChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ManifestChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ManifestChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_ManifestChange.Merge(m, src) +} +func (m *ManifestChange) XXX_Size() int { + return m.Size() +} +func (m *ManifestChange) XXX_DiscardUnknown() { + xxx_messageInfo_ManifestChange.DiscardUnknown(m) +} + +var xxx_messageInfo_ManifestChange proto.InternalMessageInfo + +func (m *ManifestChange) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *ManifestChange) GetOp() ManifestChange_Operation { + if m != nil { + return m.Op + } + return ManifestChange_CREATE +} + +func (m *ManifestChange) GetLevel() uint32 { + if m != nil { + return m.Level + } + return 0 +} + +func (m *ManifestChange) GetChecksum() []byte { + if m != nil { + return m.Checksum + } + return nil +} + +func init() { + proto.RegisterEnum("pb.ManifestChange_Operation", ManifestChange_Operation_name, ManifestChange_Operation_value) + proto.RegisterType((*KV)(nil), "pb.KV") + proto.RegisterType((*KVList)(nil), "pb.KVList") + proto.RegisterType((*ManifestChangeSet)(nil), "pb.ManifestChangeSet") + proto.RegisterType((*ManifestChange)(nil), "pb.ManifestChange") +} + +func init() { proto.RegisterFile("pb.proto", fileDescriptor_f80abaa17e25ccc8) } + +var fileDescriptor_f80abaa17e25ccc8 = []byte{ + // 365 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0x4f, 0x8a, 0xdb, 0x30, + 0x14, 0xc6, 0x47, 0x8a, 0xc7, 0xe3, 0xbc, 0xce, 0x04, 0x57, 0x94, 0x22, 0xfa, 0xc7, 0x18, 0x77, + 0xe3, 0xc5, 0xe0, 0xc5, 0xf4, 0x04, 0x69, 0xea, 0x45, 0x48, 0x42, 0x40, 0x0d, 0xd9, 0x06, 0x39, + 0x7e, 0x6d, 0x8c, 0x13, 0x5b, 0x58, 0x8a, 0x69, 0x6f, 0xd2, 0x0b, 0xf4, 0x04, 0xbd, 0x44, 0x97, + 0x3d, 0x42, 0x49, 0x2f, 0x52, 0xac, 0xfc, 0x81, 0xd0, 0xdd, 0xfb, 0xbe, 0xef, 0xbd, 0x4f, 0xf0, + 0x13, 0x78, 0x2a, 0x4b, 0x54, 0x53, 0x9b, 0x9a, 0x51, 0x95, 0x45, 0x3f, 0x09, 0xd0, 0xc9, 0x92, + 0xf9, 0xd0, 0x2b, 0xf1, 0x1b, 0x27, 0x21, 0x89, 0xef, 0x45, 0x37, 0xb2, 0x17, 0x70, 0xdb, 0xca, + 0xed, 0x1e, 0x39, 0xb5, 0xde, 0x51, 0xb0, 0xd7, 0xd0, 0xdf, 0x6b, 0x6c, 0x56, 0x3b, 0x34, 0x92, + 0xf7, 0x6c, 0xe2, 0x75, 0xc6, 0x0c, 0x8d, 0x64, 0x1c, 0xee, 0x5a, 0x6c, 0x74, 0x51, 0x57, 0xdc, + 0x09, 0x49, 0xec, 0x88, 0xb3, 0x64, 0x6f, 0x01, 0xf0, 0xab, 0x2a, 0x1a, 0xd4, 0x2b, 0x69, 0xf8, + 0xad, 0x0d, 0xfb, 0x27, 0x67, 0x68, 0x18, 0x03, 0xc7, 0x16, 0xba, 0xb6, 0xd0, 0xce, 0xdd, 0x4b, + 0xda, 0x34, 0x28, 0x77, 0xab, 0x22, 0xe7, 0x10, 0x92, 0xf8, 0x41, 0x78, 0x47, 0x63, 0x9c, 0x47, + 0x21, 0xb8, 0x93, 0xe5, 0xb4, 0xd0, 0x86, 0xbd, 0x04, 0x5a, 0xb6, 0x9c, 0x84, 0xbd, 0xf8, 0xd9, + 0x93, 0x9b, 0xa8, 0x2c, 0x99, 0x2c, 0x05, 0x2d, 0xdb, 0x68, 0x08, 0xcf, 0x67, 0xb2, 0x2a, 0x3e, + 0xa3, 0x36, 0xa3, 0x8d, 0xac, 0xbe, 0xe0, 0x27, 0x34, 0xec, 0x11, 0xee, 0xd6, 0x56, 0xe8, 0xd3, + 0x05, 0xeb, 0x2e, 0xae, 0xf7, 0xc4, 0x79, 0x25, 0xfa, 0x41, 0x60, 0x70, 0x9d, 0xb1, 0x01, 0xd0, + 0x71, 0x6e, 0x29, 0x39, 0x82, 0x8e, 0x73, 0xf6, 0x08, 0x74, 0xae, 0x2c, 0xa1, 0xc1, 0xd3, 0x9b, + 0xff, 0xbb, 0x92, 0xb9, 0xc2, 0x46, 0x9a, 0xa2, 0xae, 0x04, 0x9d, 0xab, 0x0e, 0xe9, 0x14, 0x5b, + 0xdc, 0x5a, 0x70, 0x0f, 0xe2, 0x28, 0xd8, 0x2b, 0xf0, 0x46, 0x1b, 0x5c, 0x97, 0x7a, 0xbf, 0xb3, + 0xd8, 0xee, 0xc5, 0x45, 0x47, 0xef, 0xa0, 0x7f, 0xa9, 0x60, 0x00, 0xee, 0x48, 0xa4, 0xc3, 0x45, + 0xea, 0xdf, 0x74, 0xf3, 0xc7, 0x74, 0x9a, 0x2e, 0x52, 0x9f, 0x7c, 0xf0, 0x7f, 0x1d, 0x02, 0xf2, + 0xfb, 0x10, 0x90, 0x3f, 0x87, 0x80, 0x7c, 0xff, 0x1b, 0xdc, 0x64, 0xae, 0xfd, 0xdf, 0xf7, 0xff, + 0x02, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x28, 0x5d, 0xcf, 0xeb, 0x01, 0x00, 0x00, +} + +func (m *KV) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KV) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Key) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintPb(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintPb(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if len(m.UserMeta) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPb(dAtA, i, uint64(len(m.UserMeta))) + i += copy(dAtA[i:], m.UserMeta) + } + if m.Version != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.Version)) + } + if m.ExpiresAt != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.ExpiresAt)) + } + if len(m.Meta) > 0 { + dAtA[i] = 0x32 + i++ + i = encodeVarintPb(dAtA, i, uint64(len(m.Meta))) + i += copy(dAtA[i:], m.Meta) + } + if m.StreamId != 0 { + dAtA[i] = 0x50 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.StreamId)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *KVList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KVList) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kv) > 0 { + for _, msg := range m.Kv { + dAtA[i] = 0xa + i++ + i = encodeVarintPb(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ManifestChangeSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ManifestChangeSet) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Changes) > 0 { + for _, msg := range m.Changes { + dAtA[i] = 0xa + i++ + i = encodeVarintPb(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ManifestChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ManifestChange) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.Id)) + } + if m.Op != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.Op)) + } + if m.Level != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintPb(dAtA, i, uint64(m.Level)) + } + if len(m.Checksum) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintPb(dAtA, i, uint64(len(m.Checksum))) + i += copy(dAtA[i:], m.Checksum) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintPb(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *KV) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + l = len(m.UserMeta) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + if m.Version != 0 { + n += 1 + sovPb(uint64(m.Version)) + } + if m.ExpiresAt != 0 { + n += 1 + sovPb(uint64(m.ExpiresAt)) + } + l = len(m.Meta) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + if m.StreamId != 0 { + n += 1 + sovPb(uint64(m.StreamId)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *KVList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Kv) > 0 { + for _, e := range m.Kv { + l = e.Size() + n += 1 + l + sovPb(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ManifestChangeSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Changes) > 0 { + for _, e := range m.Changes { + l = e.Size() + n += 1 + l + sovPb(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ManifestChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovPb(uint64(m.Id)) + } + if m.Op != 0 { + n += 1 + sovPb(uint64(m.Op)) + } + if m.Level != 0 { + n += 1 + sovPb(uint64(m.Level)) + } + l = len(m.Checksum) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovPb(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPb(x uint64) (n int) { + return sovPb(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *KV) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KV: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KV: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMeta", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserMeta = append(m.UserMeta[:0], dAtA[iNdEx:postIndex]...) + if m.UserMeta == nil { + m.UserMeta = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpiresAt", wireType) + } + m.ExpiresAt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExpiresAt |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Meta = append(m.Meta[:0], dAtA[iNdEx:postIndex]...) + if m.Meta == nil { + m.Meta = []byte{} + } + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StreamId", wireType) + } + m.StreamId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StreamId |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KVList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KVList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KVList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kv", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kv = append(m.Kv, &KV{}) + if err := m.Kv[len(m.Kv)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ManifestChangeSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ManifestChangeSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ManifestChangeSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Changes = append(m.Changes, &ManifestChange{}) + if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ManifestChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ManifestChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ManifestChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) + } + m.Op = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Op |= ManifestChange_Operation(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Level", wireType) + } + m.Level = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Level |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Checksum", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Checksum = append(m.Checksum[:0], dAtA[iNdEx:postIndex]...) + if m.Checksum == nil { + m.Checksum = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPb(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPb + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPb + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPb + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPb + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthPb + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPb + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipPb(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthPb + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthPb = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPb = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/dgraph-io/badger/pb/pb.proto b/vendor/github.com/dgraph-io/badger/pb/pb.proto new file mode 100644 index 00000000..c6e7f413 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/pb/pb.proto @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Use protos/gen.sh to generate .pb.go files. +syntax = "proto3"; + +package pb; + +message KV { + bytes key = 1; + bytes value = 2; + bytes user_meta = 3; + uint64 version = 4; + uint64 expires_at = 5; + bytes meta = 6; + + // Stream id is used to identify which stream the KV came from. + uint32 stream_id = 10; +} + +message KVList { + repeated KV kv = 1; +} + +message ManifestChangeSet { + // A set of changes that are applied atomically. + repeated ManifestChange changes = 1; +} + +message ManifestChange { + uint64 Id = 1; + enum Operation { + CREATE = 0; + DELETE = 1; + } + Operation Op = 2; + uint32 Level = 3; // Only used for CREATE + bytes Checksum = 4; // Only used for CREATE +} diff --git a/vendor/github.com/dgraph-io/badger/publisher.go b/vendor/github.com/dgraph-io/badger/publisher.go new file mode 100644 index 00000000..60f4fc90 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/publisher.go @@ -0,0 +1,151 @@ +/* + * Copyright 2019 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package badger + +import ( + "bytes" + "sync" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/y" +) + +type subscriber struct { + prefixes [][]byte + sendCh chan<- *pb.KVList + subCloser *y.Closer +} + +type publisher struct { + sync.Mutex + pubCh chan requests + subscribers map[uint64]subscriber + nextID uint64 +} + +func newPublisher() *publisher { + return &publisher{ + pubCh: make(chan requests, 1000), + subscribers: make(map[uint64]subscriber), + nextID: 0, + } +} + +func (p *publisher) listenForUpdates(c *y.Closer) { + defer func() { + p.cleanSubscribers() + c.Done() + }() + slurp := func(batch []*request) { + for { + select { + case reqs := <-p.pubCh: + batch = append(batch, reqs...) + default: + p.publishUpdates(batch) + return + } + } + } + for { + select { + case <-c.HasBeenClosed(): + return + case reqs := <-p.pubCh: + slurp(reqs) + } + } +} + +func (p *publisher) publishUpdates(reqs requests) { + kvs := &pb.KVList{} + p.Lock() + defer func() { + p.Unlock() + // Release all the request. + reqs.DecrRef() + }() + for _, s := range p.subscribers { + for _, prefix := range s.prefixes { + for _, req := range reqs { + for _, e := range req.Entries { + // TODO: Use trie to find subscribers. + if bytes.HasPrefix(e.Key, prefix) { + k := y.SafeCopy(nil, e.Key) + kv := &pb.KV{ + Key: y.ParseKey(k), + Value: y.SafeCopy(nil, e.Value), + Meta: []byte{e.UserMeta}, + ExpiresAt: e.ExpiresAt, + Version: y.ParseTs(k), + } + kvs.Kv = append(kvs.Kv, kv) + } + } + } + } + if len(kvs.GetKv()) > 0 { + s.sendCh <- kvs + } + } +} + +func (p *publisher) newSubscriber(c *y.Closer, prefixes ...[]byte) (<-chan *pb.KVList, uint64) { + p.Lock() + defer p.Unlock() + ch := make(chan *pb.KVList, 1000) + id := p.nextID + // Increment next ID. + p.nextID++ + p.subscribers[id] = subscriber{ + prefixes: prefixes, + sendCh: ch, + subCloser: c, + } + return ch, id +} + +// cleanSubscribers stops all the subscribers. Ideally, It should be called while closing DB. +func (p *publisher) cleanSubscribers() { + p.Lock() + defer p.Unlock() + for id, s := range p.subscribers { + delete(p.subscribers, id) + s.subCloser.SignalAndWait() + } +} + +func (p *publisher) deleteSubscriber(id uint64) { + p.Lock() + defer p.Unlock() + if _, ok := p.subscribers[id]; !ok { + return + } + delete(p.subscribers, id) +} + +func (p *publisher) sendUpdates(reqs []*request) { + // TODO: Prefix check before pushing into pubCh. + if p.noOfSubscribers() != 0 { + p.pubCh <- reqs + } +} + +func (p *publisher) noOfSubscribers() int { + p.Lock() + defer p.Unlock() + return len(p.subscribers) +} diff --git a/vendor/github.com/dgraph-io/badger/skl/README.md b/vendor/github.com/dgraph-io/badger/skl/README.md new file mode 100644 index 00000000..92fa68bb --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/skl/README.md @@ -0,0 +1,113 @@ +This is much better than `skiplist` and `slist`. + +``` +BenchmarkReadWrite/frac_0-8 3000000 537 ns/op +BenchmarkReadWrite/frac_1-8 3000000 503 ns/op +BenchmarkReadWrite/frac_2-8 3000000 492 ns/op +BenchmarkReadWrite/frac_3-8 3000000 475 ns/op +BenchmarkReadWrite/frac_4-8 3000000 440 ns/op +BenchmarkReadWrite/frac_5-8 5000000 442 ns/op +BenchmarkReadWrite/frac_6-8 5000000 380 ns/op +BenchmarkReadWrite/frac_7-8 5000000 338 ns/op +BenchmarkReadWrite/frac_8-8 5000000 294 ns/op +BenchmarkReadWrite/frac_9-8 10000000 268 ns/op +BenchmarkReadWrite/frac_10-8 100000000 26.3 ns/op +``` + +And even better than a simple map with read-write lock: + +``` +BenchmarkReadWriteMap/frac_0-8 2000000 774 ns/op +BenchmarkReadWriteMap/frac_1-8 2000000 647 ns/op +BenchmarkReadWriteMap/frac_2-8 3000000 605 ns/op +BenchmarkReadWriteMap/frac_3-8 3000000 603 ns/op +BenchmarkReadWriteMap/frac_4-8 3000000 556 ns/op +BenchmarkReadWriteMap/frac_5-8 3000000 472 ns/op +BenchmarkReadWriteMap/frac_6-8 3000000 476 ns/op +BenchmarkReadWriteMap/frac_7-8 3000000 457 ns/op +BenchmarkReadWriteMap/frac_8-8 5000000 444 ns/op +BenchmarkReadWriteMap/frac_9-8 5000000 361 ns/op +BenchmarkReadWriteMap/frac_10-8 10000000 212 ns/op +``` + +# Node Pooling + +Command used + +``` +rm -Rf tmp && /usr/bin/time -l ./populate -keys_mil 10 +``` + +For pprof results, we run without using /usr/bin/time. There are four runs below. + +Results seem to vary quite a bit between runs. + +## Before node pooling + +``` +1311.53MB of 1338.69MB total (97.97%) +Dropped 30 nodes (cum <= 6.69MB) +Showing top 10 nodes out of 37 (cum >= 12.50MB) + flat flat% sum% cum cum% + 523.04MB 39.07% 39.07% 523.04MB 39.07% github.com/dgraph-io/badger/skl.(*Skiplist).Put + 184.51MB 13.78% 52.85% 184.51MB 13.78% runtime.stringtoslicebyte + 166.01MB 12.40% 65.25% 689.04MB 51.47% github.com/dgraph-io/badger/mem.(*Table).Put + 165MB 12.33% 77.58% 165MB 12.33% runtime.convT2E + 116.92MB 8.73% 86.31% 116.92MB 8.73% bytes.makeSlice + 62.50MB 4.67% 90.98% 62.50MB 4.67% main.newValue + 34.50MB 2.58% 93.56% 34.50MB 2.58% github.com/dgraph-io/badger/table.(*BlockIterator).parseKV + 25.50MB 1.90% 95.46% 100.06MB 7.47% github.com/dgraph-io/badger/y.(*MergeIterator).Next + 21.06MB 1.57% 97.04% 21.06MB 1.57% github.com/dgraph-io/badger/table.(*Table).read + 12.50MB 0.93% 97.97% 12.50MB 0.93% github.com/dgraph-io/badger/table.header.Encode + + 128.31 real 329.37 user 17.11 sys +3355660288 maximum resident set size + 0 average shared memory size + 0 average unshared data size + 0 average unshared stack size + 2203080 page reclaims + 764 page faults + 0 swaps + 275 block input operations + 76 block output operations + 0 messages sent + 0 messages received + 0 signals received + 49173 voluntary context switches + 599922 involuntary context switches +``` + +## After node pooling + +``` +1963.13MB of 2026.09MB total (96.89%) +Dropped 29 nodes (cum <= 10.13MB) +Showing top 10 nodes out of 41 (cum >= 185.62MB) + flat flat% sum% cum cum% + 658.05MB 32.48% 32.48% 658.05MB 32.48% github.com/dgraph-io/badger/skl.glob..func1 + 297.51MB 14.68% 47.16% 297.51MB 14.68% runtime.convT2E + 257.51MB 12.71% 59.87% 257.51MB 12.71% runtime.stringtoslicebyte + 249.01MB 12.29% 72.16% 1007.06MB 49.70% github.com/dgraph-io/badger/mem.(*Table).Put + 142.43MB 7.03% 79.19% 142.43MB 7.03% bytes.makeSlice + 100MB 4.94% 84.13% 758.05MB 37.41% github.com/dgraph-io/badger/skl.newNode + 99.50MB 4.91% 89.04% 99.50MB 4.91% main.newValue + 75MB 3.70% 92.74% 75MB 3.70% github.com/dgraph-io/badger/table.(*BlockIterator).parseKV + 44.62MB 2.20% 94.94% 44.62MB 2.20% github.com/dgraph-io/badger/table.(*Table).read + 39.50MB 1.95% 96.89% 185.62MB 9.16% github.com/dgraph-io/badger/y.(*MergeIterator).Next + + 135.58 real 374.29 user 17.65 sys +3740614656 maximum resident set size + 0 average shared memory size + 0 average unshared data size + 0 average unshared stack size + 2276566 page reclaims + 770 page faults + 0 swaps + 128 block input operations + 90 block output operations + 0 messages sent + 0 messages received + 0 signals received + 46434 voluntary context switches + 597049 involuntary context switches +``` \ No newline at end of file diff --git a/vendor/github.com/dgraph-io/badger/skl/arena.go b/vendor/github.com/dgraph-io/badger/skl/arena.go new file mode 100644 index 00000000..def55071 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/skl/arena.go @@ -0,0 +1,136 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package skl + +import ( + "sync/atomic" + "unsafe" + + "github.com/dgraph-io/badger/y" +) + +const ( + offsetSize = int(unsafe.Sizeof(uint32(0))) + + // Always align nodes on 64-bit boundaries, even on 32-bit architectures, + // so that the node.value field is 64-bit aligned. This is necessary because + // node.getValueOffset uses atomic.LoadUint64, which expects its input + // pointer to be 64-bit aligned. + nodeAlign = int(unsafe.Sizeof(uint64(0))) - 1 +) + +// Arena should be lock-free. +type Arena struct { + n uint32 + buf []byte +} + +// newArena returns a new arena. +func newArena(n int64) *Arena { + // Don't store data at position 0 in order to reserve offset=0 as a kind + // of nil pointer. + out := &Arena{ + n: 1, + buf: make([]byte, n), + } + return out +} + +func (s *Arena) size() int64 { + return int64(atomic.LoadUint32(&s.n)) +} + +func (s *Arena) reset() { + atomic.StoreUint32(&s.n, 0) +} + +// putNode allocates a node in the arena. The node is aligned on a pointer-sized +// boundary. The arena offset of the node is returned. +func (s *Arena) putNode(height int) uint32 { + // Compute the amount of the tower that will never be used, since the height + // is less than maxHeight. + unusedSize := (maxHeight - height) * offsetSize + + // Pad the allocation with enough bytes to ensure pointer alignment. + l := uint32(MaxNodeSize - unusedSize + nodeAlign) + n := atomic.AddUint32(&s.n, l) + y.AssertTruef(int(n) <= len(s.buf), + "Arena too small, toWrite:%d newTotal:%d limit:%d", + l, n, len(s.buf)) + + // Return the aligned offset. + m := (n - l + uint32(nodeAlign)) & ^uint32(nodeAlign) + return m +} + +// Put will *copy* val into arena. To make better use of this, reuse your input +// val buffer. Returns an offset into buf. User is responsible for remembering +// size of val. We could also store this size inside arena but the encoding and +// decoding will incur some overhead. +func (s *Arena) putVal(v y.ValueStruct) uint32 { + l := uint32(v.EncodedSize()) + n := atomic.AddUint32(&s.n, l) + y.AssertTruef(int(n) <= len(s.buf), + "Arena too small, toWrite:%d newTotal:%d limit:%d", + l, n, len(s.buf)) + m := n - l + v.Encode(s.buf[m:]) + return m +} + +func (s *Arena) putKey(key []byte) uint32 { + l := uint32(len(key)) + n := atomic.AddUint32(&s.n, l) + y.AssertTruef(int(n) <= len(s.buf), + "Arena too small, toWrite:%d newTotal:%d limit:%d", + l, n, len(s.buf)) + m := n - l + y.AssertTrue(len(key) == copy(s.buf[m:n], key)) + return m +} + +// getNode returns a pointer to the node located at offset. If the offset is +// zero, then the nil node pointer is returned. +func (s *Arena) getNode(offset uint32) *node { + if offset == 0 { + return nil + } + + return (*node)(unsafe.Pointer(&s.buf[offset])) +} + +// getKey returns byte slice at offset. +func (s *Arena) getKey(offset uint32, size uint16) []byte { + return s.buf[offset : offset+uint32(size)] +} + +// getVal returns byte slice at offset. The given size should be just the value +// size and should NOT include the meta bytes. +func (s *Arena) getVal(offset uint32, size uint16) (ret y.ValueStruct) { + ret.Decode(s.buf[offset : offset+uint32(size)]) + return +} + +// getNodeOffset returns the offset of node in the arena. If the node pointer is +// nil, then the zero offset is returned. +func (s *Arena) getNodeOffset(nd *node) uint32 { + if nd == nil { + return 0 + } + + return uint32(uintptr(unsafe.Pointer(nd)) - uintptr(unsafe.Pointer(&s.buf[0]))) +} diff --git a/vendor/github.com/dgraph-io/badger/skl/skl.go b/vendor/github.com/dgraph-io/badger/skl/skl.go new file mode 100644 index 00000000..b465b09e --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/skl/skl.go @@ -0,0 +1,516 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +Adapted from RocksDB inline skiplist. + +Key differences: +- No optimization for sequential inserts (no "prev"). +- No custom comparator. +- Support overwrites. This requires care when we see the same key when inserting. + For RocksDB or LevelDB, overwrites are implemented as a newer sequence number in the key, so + there is no need for values. We don't intend to support versioning. In-place updates of values + would be more efficient. +- We discard all non-concurrent code. +- We do not support Splices. This simplifies the code a lot. +- No AllocateNode or other pointer arithmetic. +- We combine the findLessThan, findGreaterOrEqual, etc into one function. +*/ + +package skl + +import ( + "math" + "math/rand" + "sync/atomic" + "unsafe" + + "github.com/dgraph-io/badger/y" +) + +const ( + maxHeight = 20 + heightIncrease = math.MaxUint32 / 3 +) + +// MaxNodeSize is the memory footprint of a node of maximum height. +const MaxNodeSize = int(unsafe.Sizeof(node{})) + +type node struct { + // Multiple parts of the value are encoded as a single uint64 so that it + // can be atomically loaded and stored: + // value offset: uint32 (bits 0-31) + // value size : uint16 (bits 32-47) + value uint64 + + // A byte slice is 24 bytes. We are trying to save space here. + keyOffset uint32 // Immutable. No need to lock to access key. + keySize uint16 // Immutable. No need to lock to access key. + + // Height of the tower. + height uint16 + + // Most nodes do not need to use the full height of the tower, since the + // probability of each successive level decreases exponentially. Because + // these elements are never accessed, they do not need to be allocated. + // Therefore, when a node is allocated in the arena, its memory footprint + // is deliberately truncated to not include unneeded tower elements. + // + // All accesses to elements should use CAS operations, with no need to lock. + tower [maxHeight]uint32 +} + +// Skiplist maps keys to values (in memory) +type Skiplist struct { + height int32 // Current height. 1 <= height <= kMaxHeight. CAS. + head *node + ref int32 + arena *Arena +} + +// IncrRef increases the refcount +func (s *Skiplist) IncrRef() { + atomic.AddInt32(&s.ref, 1) +} + +// DecrRef decrements the refcount, deallocating the Skiplist when done using it +func (s *Skiplist) DecrRef() { + newRef := atomic.AddInt32(&s.ref, -1) + if newRef > 0 { + return + } + + s.arena.reset() + // Indicate we are closed. Good for testing. Also, lets GC reclaim memory. Race condition + // here would suggest we are accessing skiplist when we are supposed to have no reference! + s.arena = nil +} + +func (s *Skiplist) valid() bool { return s.arena != nil } + +func newNode(arena *Arena, key []byte, v y.ValueStruct, height int) *node { + // The base level is already allocated in the node struct. + offset := arena.putNode(height) + node := arena.getNode(offset) + node.keyOffset = arena.putKey(key) + node.keySize = uint16(len(key)) + node.height = uint16(height) + node.value = encodeValue(arena.putVal(v), v.EncodedSize()) + return node +} + +func encodeValue(valOffset uint32, valSize uint16) uint64 { + return uint64(valSize)<<32 | uint64(valOffset) +} + +func decodeValue(value uint64) (valOffset uint32, valSize uint16) { + valOffset = uint32(value) + valSize = uint16(value >> 32) + return +} + +// NewSkiplist makes a new empty skiplist, with a given arena size +func NewSkiplist(arenaSize int64) *Skiplist { + arena := newArena(arenaSize) + head := newNode(arena, nil, y.ValueStruct{}, maxHeight) + return &Skiplist{ + height: 1, + head: head, + arena: arena, + ref: 1, + } +} + +func (s *node) getValueOffset() (uint32, uint16) { + value := atomic.LoadUint64(&s.value) + return decodeValue(value) +} + +func (s *node) key(arena *Arena) []byte { + return arena.getKey(s.keyOffset, s.keySize) +} + +func (s *node) setValue(arena *Arena, v y.ValueStruct) { + valOffset := arena.putVal(v) + value := encodeValue(valOffset, v.EncodedSize()) + atomic.StoreUint64(&s.value, value) +} + +func (s *node) getNextOffset(h int) uint32 { + return atomic.LoadUint32(&s.tower[h]) +} + +func (s *node) casNextOffset(h int, old, val uint32) bool { + return atomic.CompareAndSwapUint32(&s.tower[h], old, val) +} + +// Returns true if key is strictly > n.key. +// If n is nil, this is an "end" marker and we return false. +//func (s *Skiplist) keyIsAfterNode(key []byte, n *node) bool { +// y.AssertTrue(n != s.head) +// return n != nil && y.CompareKeys(key, n.key) > 0 +//} + +func randomHeight() int { + h := 1 + for h < maxHeight && rand.Uint32() <= heightIncrease { + h++ + } + return h +} + +func (s *Skiplist) getNext(nd *node, height int) *node { + return s.arena.getNode(nd.getNextOffset(height)) +} + +// findNear finds the node near to key. +// If less=true, it finds rightmost node such that node.key < key (if allowEqual=false) or +// node.key <= key (if allowEqual=true). +// If less=false, it finds leftmost node such that node.key > key (if allowEqual=false) or +// node.key >= key (if allowEqual=true). +// Returns the node found. The bool returned is true if the node has key equal to given key. +func (s *Skiplist) findNear(key []byte, less bool, allowEqual bool) (*node, bool) { + x := s.head + level := int(s.getHeight() - 1) + for { + // Assume x.key < key. + next := s.getNext(x, level) + if next == nil { + // x.key < key < END OF LIST + if level > 0 { + // Can descend further to iterate closer to the end. + level-- + continue + } + // Level=0. Cannot descend further. Let's return something that makes sense. + if !less { + return nil, false + } + // Try to return x. Make sure it is not a head node. + if x == s.head { + return nil, false + } + return x, false + } + + nextKey := next.key(s.arena) + cmp := y.CompareKeys(key, nextKey) + if cmp > 0 { + // x.key < next.key < key. We can continue to move right. + x = next + continue + } + if cmp == 0 { + // x.key < key == next.key. + if allowEqual { + return next, true + } + if !less { + // We want >, so go to base level to grab the next bigger note. + return s.getNext(next, 0), false + } + // We want <. If not base level, we should go closer in the next level. + if level > 0 { + level-- + continue + } + // On base level. Return x. + if x == s.head { + return nil, false + } + return x, false + } + // cmp < 0. In other words, x.key < key < next. + if level > 0 { + level-- + continue + } + // At base level. Need to return something. + if !less { + return next, false + } + // Try to return x. Make sure it is not a head node. + if x == s.head { + return nil, false + } + return x, false + } +} + +// findSpliceForLevel returns (outBefore, outAfter) with outBefore.key <= key <= outAfter.key. +// The input "before" tells us where to start looking. +// If we found a node with the same key, then we return outBefore = outAfter. +// Otherwise, outBefore.key < key < outAfter.key. +func (s *Skiplist) findSpliceForLevel(key []byte, before *node, level int) (*node, *node) { + for { + // Assume before.key < key. + next := s.getNext(before, level) + if next == nil { + return before, next + } + nextKey := next.key(s.arena) + cmp := y.CompareKeys(key, nextKey) + if cmp == 0 { + // Equality case. + return next, next + } + if cmp < 0 { + // before.key < key < next.key. We are done for this level. + return before, next + } + before = next // Keep moving right on this level. + } +} + +func (s *Skiplist) getHeight() int32 { + return atomic.LoadInt32(&s.height) +} + +// Put inserts the key-value pair. +func (s *Skiplist) Put(key []byte, v y.ValueStruct) { + // Since we allow overwrite, we may not need to create a new node. We might not even need to + // increase the height. Let's defer these actions. + + listHeight := s.getHeight() + var prev [maxHeight + 1]*node + var next [maxHeight + 1]*node + prev[listHeight] = s.head + next[listHeight] = nil + for i := int(listHeight) - 1; i >= 0; i-- { + // Use higher level to speed up for current level. + prev[i], next[i] = s.findSpliceForLevel(key, prev[i+1], i) + if prev[i] == next[i] { + prev[i].setValue(s.arena, v) + return + } + } + + // We do need to create a new node. + height := randomHeight() + x := newNode(s.arena, key, v, height) + + // Try to increase s.height via CAS. + listHeight = s.getHeight() + for height > int(listHeight) { + if atomic.CompareAndSwapInt32(&s.height, listHeight, int32(height)) { + // Successfully increased skiplist.height. + break + } + listHeight = s.getHeight() + } + + // We always insert from the base level and up. After you add a node in base level, we cannot + // create a node in the level above because it would have discovered the node in the base level. + for i := 0; i < height; i++ { + for { + if prev[i] == nil { + y.AssertTrue(i > 1) // This cannot happen in base level. + // We haven't computed prev, next for this level because height exceeds old listHeight. + // For these levels, we expect the lists to be sparse, so we can just search from head. + prev[i], next[i] = s.findSpliceForLevel(key, s.head, i) + // Someone adds the exact same key before we are able to do so. This can only happen on + // the base level. But we know we are not on the base level. + y.AssertTrue(prev[i] != next[i]) + } + nextOffset := s.arena.getNodeOffset(next[i]) + x.tower[i] = nextOffset + if prev[i].casNextOffset(i, nextOffset, s.arena.getNodeOffset(x)) { + // Managed to insert x between prev[i] and next[i]. Go to the next level. + break + } + // CAS failed. We need to recompute prev and next. + // It is unlikely to be helpful to try to use a different level as we redo the search, + // because it is unlikely that lots of nodes are inserted between prev[i] and next[i]. + prev[i], next[i] = s.findSpliceForLevel(key, prev[i], i) + if prev[i] == next[i] { + y.AssertTruef(i == 0, "Equality can happen only on base level: %d", i) + prev[i].setValue(s.arena, v) + return + } + } + } +} + +// Empty returns if the Skiplist is empty. +func (s *Skiplist) Empty() bool { + return s.findLast() == nil +} + +// findLast returns the last element. If head (empty list), we return nil. All the find functions +// will NEVER return the head nodes. +func (s *Skiplist) findLast() *node { + n := s.head + level := int(s.getHeight()) - 1 + for { + next := s.getNext(n, level) + if next != nil { + n = next + continue + } + if level == 0 { + if n == s.head { + return nil + } + return n + } + level-- + } +} + +// Get gets the value associated with the key. It returns a valid value if it finds equal or earlier +// version of the same key. +func (s *Skiplist) Get(key []byte) y.ValueStruct { + n, _ := s.findNear(key, false, true) // findGreaterOrEqual. + if n == nil { + return y.ValueStruct{} + } + + nextKey := s.arena.getKey(n.keyOffset, n.keySize) + if !y.SameKey(key, nextKey) { + return y.ValueStruct{} + } + + valOffset, valSize := n.getValueOffset() + vs := s.arena.getVal(valOffset, valSize) + vs.Version = y.ParseTs(nextKey) + return vs +} + +// NewIterator returns a skiplist iterator. You have to Close() the iterator. +func (s *Skiplist) NewIterator() *Iterator { + s.IncrRef() + return &Iterator{list: s} +} + +// MemSize returns the size of the Skiplist in terms of how much memory is used within its internal +// arena. +func (s *Skiplist) MemSize() int64 { return s.arena.size() } + +// Iterator is an iterator over skiplist object. For new objects, you just +// need to initialize Iterator.list. +type Iterator struct { + list *Skiplist + n *node +} + +// Close frees the resources held by the iterator +func (s *Iterator) Close() error { + s.list.DecrRef() + return nil +} + +// Valid returns true iff the iterator is positioned at a valid node. +func (s *Iterator) Valid() bool { return s.n != nil } + +// Key returns the key at the current position. +func (s *Iterator) Key() []byte { + return s.list.arena.getKey(s.n.keyOffset, s.n.keySize) +} + +// Value returns value. +func (s *Iterator) Value() y.ValueStruct { + valOffset, valSize := s.n.getValueOffset() + return s.list.arena.getVal(valOffset, valSize) +} + +// Next advances to the next position. +func (s *Iterator) Next() { + y.AssertTrue(s.Valid()) + s.n = s.list.getNext(s.n, 0) +} + +// Prev advances to the previous position. +func (s *Iterator) Prev() { + y.AssertTrue(s.Valid()) + s.n, _ = s.list.findNear(s.Key(), true, false) // find <. No equality allowed. +} + +// Seek advances to the first entry with a key >= target. +func (s *Iterator) Seek(target []byte) { + s.n, _ = s.list.findNear(target, false, true) // find >=. +} + +// SeekForPrev finds an entry with key <= target. +func (s *Iterator) SeekForPrev(target []byte) { + s.n, _ = s.list.findNear(target, true, true) // find <=. +} + +// SeekToFirst seeks position at the first entry in list. +// Final state of iterator is Valid() iff list is not empty. +func (s *Iterator) SeekToFirst() { + s.n = s.list.getNext(s.list.head, 0) +} + +// SeekToLast seeks position at the last entry in list. +// Final state of iterator is Valid() iff list is not empty. +func (s *Iterator) SeekToLast() { + s.n = s.list.findLast() +} + +// UniIterator is a unidirectional memtable iterator. It is a thin wrapper around +// Iterator. We like to keep Iterator as before, because it is more powerful and +// we might support bidirectional iterators in the future. +type UniIterator struct { + iter *Iterator + reversed bool +} + +// NewUniIterator returns a UniIterator. +func (s *Skiplist) NewUniIterator(reversed bool) *UniIterator { + return &UniIterator{ + iter: s.NewIterator(), + reversed: reversed, + } +} + +// Next implements y.Interface +func (s *UniIterator) Next() { + if !s.reversed { + s.iter.Next() + } else { + s.iter.Prev() + } +} + +// Rewind implements y.Interface +func (s *UniIterator) Rewind() { + if !s.reversed { + s.iter.SeekToFirst() + } else { + s.iter.SeekToLast() + } +} + +// Seek implements y.Interface +func (s *UniIterator) Seek(key []byte) { + if !s.reversed { + s.iter.Seek(key) + } else { + s.iter.SeekForPrev(key) + } +} + +// Key implements y.Interface +func (s *UniIterator) Key() []byte { return s.iter.Key() } + +// Value implements y.Interface +func (s *UniIterator) Value() y.ValueStruct { return s.iter.Value() } + +// Valid implements y.Interface +func (s *UniIterator) Valid() bool { return s.iter.Valid() } + +// Close implements y.Interface (and frees up the iter's resources) +func (s *UniIterator) Close() error { return s.iter.Close() } diff --git a/vendor/github.com/dgraph-io/badger/stream.go b/vendor/github.com/dgraph-io/badger/stream.go new file mode 100644 index 00000000..f0841a6a --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/stream.go @@ -0,0 +1,385 @@ +/* + * Copyright 2018 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "context" + "math" + "sync" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/y" + humanize "github.com/dustin/go-humanize" +) + +const pageSize = 4 << 20 // 4MB + +// Stream provides a framework to concurrently iterate over a snapshot of Badger, pick up +// key-values, batch them up and call Send. Stream does concurrent iteration over many smaller key +// ranges. It does NOT send keys in lexicographical sorted order. To get keys in sorted +// order, use Iterator. +type Stream struct { + // Prefix to only iterate over certain range of keys. If set to nil (default), Stream would + // iterate over the entire DB. + Prefix []byte + + // Number of goroutines to use for iterating over key ranges. Defaults to 16. + NumGo int + + // Badger would produce log entries in Infof to indicate the progress of Stream. LogPrefix can + // be used to help differentiate them from other activities. Default is "Badger.Stream". + LogPrefix string + + // ChooseKey is invoked each time a new key is encountered. Note that this is not called + // on every version of the value, only the first encountered version (i.e. the highest version + // of the value a key has). ChooseKey can be left nil to select all keys. + // + // Note: Calls to ChooseKey are concurrent. + ChooseKey func(item *Item) bool + + // KeyToList, similar to ChooseKey, is only invoked on the highest version of the value. It + // is upto the caller to iterate over the versions and generate zero, one or more KVs. It + // is expected that the user would advance the iterator to go through the versions of the + // values. However, the user MUST immediately return from this function on the first encounter + // with a mismatching key. See example usage in ToList function. Can be left nil to use ToList + // function by default. + // + // Note: Calls to KeyToList are concurrent. + KeyToList func(key []byte, itr *Iterator) (*pb.KVList, error) + + // This is the method where Stream sends the final output. All calls to Send are done by a + // single goroutine, i.e. logic within Send method can expect single threaded execution. + Send func(*pb.KVList) error + + readTs uint64 + db *DB + rangeCh chan keyRange + kvChan chan *pb.KVList + nextStreamId uint32 +} + +// ToList is a default implementation of KeyToList. It picks up all valid versions of the key, +// skipping over deleted or expired keys. +func (st *Stream) ToList(key []byte, itr *Iterator) (*pb.KVList, error) { + list := &pb.KVList{} + for ; itr.Valid(); itr.Next() { + item := itr.Item() + if item.IsDeletedOrExpired() { + break + } + if !bytes.Equal(key, item.Key()) { + // Break out on the first encounter with another key. + break + } + + valCopy, err := item.ValueCopy(nil) + if err != nil { + return nil, err + } + kv := &pb.KV{ + Key: item.KeyCopy(nil), + Value: valCopy, + UserMeta: []byte{item.UserMeta()}, + Version: item.Version(), + ExpiresAt: item.ExpiresAt(), + } + list.Kv = append(list.Kv, kv) + if st.db.opt.NumVersionsToKeep == 1 { + break + } + + if item.DiscardEarlierVersions() { + break + } + } + return list, nil +} + +// keyRange is [start, end), including start, excluding end. Do ensure that the start, +// end byte slices are owned by keyRange struct. +func (st *Stream) produceRanges(ctx context.Context) { + splits := st.db.KeySplits(st.Prefix) + + // We don't need to create more key ranges than NumGo goroutines. This way, we will have limited + // number of "streams" coming out, which then helps limit the memory used by SSWriter. + { + pickEvery := int(math.Floor(float64(len(splits)) / float64(st.NumGo))) + if pickEvery < 1 { + pickEvery = 1 + } + filtered := splits[:0] + for i, split := range splits { + if (i+1)%pickEvery == 0 { + filtered = append(filtered, split) + } + } + splits = filtered + } + + start := y.SafeCopy(nil, st.Prefix) + for _, key := range splits { + st.rangeCh <- keyRange{left: start, right: y.SafeCopy(nil, []byte(key))} + start = y.SafeCopy(nil, []byte(key)) + } + // Edge case: prefix is empty and no splits exist. In that case, we should have at least one + // keyRange output. + st.rangeCh <- keyRange{left: start} + close(st.rangeCh) +} + +// produceKVs picks up ranges from rangeCh, generates KV lists and sends them to kvChan. +func (st *Stream) produceKVs(ctx context.Context) error { + var size int + var txn *Txn + if st.readTs > 0 { + txn = st.db.NewTransactionAt(st.readTs, false) + } else { + txn = st.db.NewTransaction(false) + } + defer txn.Discard() + + iterate := func(kr keyRange) error { + iterOpts := DefaultIteratorOptions + iterOpts.AllVersions = true + iterOpts.Prefix = st.Prefix + iterOpts.PrefetchValues = false + itr := txn.NewIterator(iterOpts) + defer itr.Close() + + // This unique stream id is used to identify all the keys from this iteration. + streamId := atomic.AddUint32(&st.nextStreamId, 1) + + outList := new(pb.KVList) + var prevKey []byte + for itr.Seek(kr.left); itr.Valid(); { + // it.Valid would only return true for keys with the provided Prefix in iterOpts. + item := itr.Item() + if bytes.Equal(item.Key(), prevKey) { + itr.Next() + continue + } + prevKey = append(prevKey[:0], item.Key()...) + + // Check if we reached the end of the key range. + if len(kr.right) > 0 && bytes.Compare(item.Key(), kr.right) >= 0 { + break + } + // Check if we should pick this key. + if st.ChooseKey != nil && !st.ChooseKey(item) { + continue + } + + // Now convert to key value. + list, err := st.KeyToList(item.KeyCopy(nil), itr) + if err != nil { + return err + } + if list == nil || len(list.Kv) == 0 { + continue + } + outList.Kv = append(outList.Kv, list.Kv...) + size += list.Size() + if size >= pageSize { + for _, kv := range outList.Kv { + kv.StreamId = streamId + } + select { + case st.kvChan <- outList: + case <-ctx.Done(): + return ctx.Err() + } + outList = new(pb.KVList) + size = 0 + } + } + if len(outList.Kv) > 0 { + for _, kv := range outList.Kv { + kv.StreamId = streamId + } + // TODO: Think of a way to indicate that a stream is over. + select { + case st.kvChan <- outList: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil + } + + for { + select { + case kr, ok := <-st.rangeCh: + if !ok { + // Done with the keys. + return nil + } + if err := iterate(kr); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (st *Stream) streamKVs(ctx context.Context) error { + var count int + var bytesSent uint64 + t := time.NewTicker(time.Second) + defer t.Stop() + now := time.Now() + + slurp := func(batch *pb.KVList) error { + loop: + for { + select { + case kvs, ok := <-st.kvChan: + if !ok { + break loop + } + y.AssertTrue(kvs != nil) + batch.Kv = append(batch.Kv, kvs.Kv...) + default: + break loop + } + } + sz := uint64(batch.Size()) + bytesSent += sz + count += len(batch.Kv) + t := time.Now() + if err := st.Send(batch); err != nil { + return err + } + st.db.opt.Infof("%s Created batch of size: %s in %s.\n", + st.LogPrefix, humanize.Bytes(sz), time.Since(t)) + return nil + } + +outer: + for { + var batch *pb.KVList + select { + case <-ctx.Done(): + return ctx.Err() + + case <-t.C: + dur := time.Since(now) + durSec := uint64(dur.Seconds()) + if durSec == 0 { + continue + } + speed := bytesSent / durSec + st.db.opt.Infof("%s Time elapsed: %s, bytes sent: %s, speed: %s/sec\n", st.LogPrefix, + y.FixedDuration(dur), humanize.Bytes(bytesSent), humanize.Bytes(speed)) + + case kvs, ok := <-st.kvChan: + if !ok { + break outer + } + y.AssertTrue(kvs != nil) + batch = kvs + if err := slurp(batch); err != nil { + return err + } + } + } + + st.db.opt.Infof("%s Sent %d keys\n", st.LogPrefix, count) + return nil +} + +// Orchestrate runs Stream. It picks up ranges from the SSTables, then runs NumGo number of +// goroutines to iterate over these ranges and batch up KVs in lists. It concurrently runs a single +// goroutine to pick these lists, batch them up further and send to Output.Send. Orchestrate also +// spits logs out to Infof, using provided LogPrefix. Note that all calls to Output.Send +// are serial. In case any of these steps encounter an error, Orchestrate would stop execution and +// return that error. Orchestrate can be called multiple times, but in serial order. +func (st *Stream) Orchestrate(ctx context.Context) error { + st.rangeCh = make(chan keyRange, 3) // Contains keys for posting lists. + + // kvChan should only have a small capacity to ensure that we don't buffer up too much data if + // sending is slow. Page size is set to 4MB, which is used to lazily cap the size of each + // KVList. To get 128MB buffer, we can set the channel size to 32. + st.kvChan = make(chan *pb.KVList, 32) + + if st.KeyToList == nil { + st.KeyToList = st.ToList + } + + // Picks up ranges from Badger, and sends them to rangeCh. + go st.produceRanges(ctx) + + errCh := make(chan error, 1) // Stores error by consumeKeys. + var wg sync.WaitGroup + for i := 0; i < st.NumGo; i++ { + wg.Add(1) + go func() { + defer wg.Done() + // Picks up ranges from rangeCh, generates KV lists, and sends them to kvChan. + if err := st.produceKVs(ctx); err != nil { + select { + case errCh <- err: + default: + } + } + }() + } + + // Pick up key-values from kvChan and send to stream. + kvErr := make(chan error, 1) + go func() { + // Picks up KV lists from kvChan, and sends them to Output. + kvErr <- st.streamKVs(ctx) + }() + wg.Wait() // Wait for produceKVs to be over. + close(st.kvChan) // Now we can close kvChan. + + select { + case err := <-errCh: // Check error from produceKVs. + return err + default: + } + + // Wait for key streaming to be over. + err := <-kvErr + return err +} + +func (db *DB) newStream() *Stream { + return &Stream{db: db, NumGo: 16, LogPrefix: "Badger.Stream"} +} + +// NewStream creates a new Stream. +func (db *DB) NewStream() *Stream { + if db.opt.managedTxns { + panic("This API can not be called in managed mode.") + } + return db.newStream() +} + +// NewStreamAt creates a new Stream at a particular timestamp. Should only be used with managed DB. +func (db *DB) NewStreamAt(readTs uint64) *Stream { + if !db.opt.managedTxns { + panic("This API can only be called in managed mode.") + } + stream := db.newStream() + stream.readTs = readTs + return stream +} diff --git a/vendor/github.com/dgraph-io/badger/stream_writer.go b/vendor/github.com/dgraph-io/badger/stream_writer.go new file mode 100644 index 00000000..cdf8849c --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/stream_writer.go @@ -0,0 +1,311 @@ +/* + * Copyright 2019 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "math" + + "github.com/dgraph-io/badger/pb" + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" + humanize "github.com/dustin/go-humanize" + "github.com/pkg/errors" +) + +const headStreamId uint32 = math.MaxUint32 + +// StreamWriter is used to write data coming from multiple streams. The streams must not have any +// overlapping key ranges. Within each stream, the keys must be sorted. Badger Stream framework is +// capable of generating such an output. So, this StreamWriter can be used at the other end to build +// BadgerDB at a much faster pace by writing SSTables (and value logs) directly to LSM tree levels +// without causing any compactions at all. This is way faster than using batched writer or using +// transactions, but only applicable in situations where the keys are pre-sorted and the DB is being +// bootstrapped. Existing data would get deleted when using this writer. So, this is only useful +// when restoring from backup or replicating DB across servers. +// +// StreamWriter should not be called on in-use DB instances. It is designed only to bootstrap new +// DBs. +type StreamWriter struct { + db *DB + done func() + throttle *y.Throttle + head valuePointer + maxVersion uint64 + writers map[uint32]*sortedWriter +} + +// NewStreamWriter creates a StreamWriter. Right after creating StreamWriter, Prepare must be +// called. The memory usage of a StreamWriter is directly proportional to the number of streams +// possible. So, efforts must be made to keep the number of streams low. Stream framework would +// typically use 16 goroutines and hence create 16 streams. +func (db *DB) NewStreamWriter() *StreamWriter { + return &StreamWriter{ + db: db, + // throttle shouldn't make much difference. Memory consumption is based on the number of + // concurrent streams being processed. + throttle: y.NewThrottle(16), + writers: make(map[uint32]*sortedWriter), + } +} + +// Prepare should be called before writing any entry to StreamWriter. It deletes all data present in +// existing DB, stops compactions and any writes being done by other means. Be very careful when +// calling Prepare, because it could result in permanent data loss. Not calling Prepare would result +// in a corrupt Badger instance. +func (sw *StreamWriter) Prepare() error { + var err error + sw.done, err = sw.db.dropAll() + return err +} + +// Write writes KVList to DB. Each KV within the list contains the stream id which StreamWriter +// would use to demux the writes. +func (sw *StreamWriter) Write(kvs *pb.KVList) error { + var entries []*Entry + for _, kv := range kvs.Kv { + var meta, userMeta byte + if len(kv.Meta) > 0 { + meta = kv.Meta[0] + } + if len(kv.UserMeta) > 0 { + userMeta = kv.UserMeta[0] + } + if sw.maxVersion < kv.Version { + sw.maxVersion = kv.Version + } + e := &Entry{ + Key: y.KeyWithTs(kv.Key, kv.Version), + Value: kv.Value, + UserMeta: userMeta, + ExpiresAt: kv.ExpiresAt, + meta: meta, + } + // If the value can be colocated with the key in LSM tree, we can skip + // writing the value to value log. + e.skipVlog = sw.db.shouldWriteValueToLSM(*e) + entries = append(entries, e) + } + req := &request{ + Entries: entries, + } + y.AssertTrue(len(kvs.Kv) == len(req.Entries)) + if err := sw.db.vlog.write([]*request{req}); err != nil { + return err + } + + for i, kv := range kvs.Kv { + e := req.Entries[i] + vptr := req.Ptrs[i] + if !vptr.IsZero() { + y.AssertTrue(sw.head.Less(vptr)) + sw.head = vptr + } + + writer, ok := sw.writers[kv.StreamId] + if !ok { + writer = sw.newWriter(kv.StreamId) + sw.writers[kv.StreamId] = writer + } + + var vs y.ValueStruct + if e.skipVlog { + vs = y.ValueStruct{ + Value: e.Value, + Meta: e.meta, + UserMeta: e.UserMeta, + ExpiresAt: e.ExpiresAt, + } + } else { + vbuf := make([]byte, vptrSize) + vs = y.ValueStruct{ + Value: vptr.Encode(vbuf), + Meta: e.meta | bitValuePointer, + UserMeta: e.UserMeta, + ExpiresAt: e.ExpiresAt, + } + } + if err := writer.Add(e.Key, vs); err != nil { + return err + } + } + return nil +} + +// Flush is called once we are done writing all the entries. It syncs DB directories. It also +// updates Oracle with maxVersion found in all entries (if DB is not managed). +func (sw *StreamWriter) Flush() error { + defer sw.done() + for _, writer := range sw.writers { + if err := writer.Done(); err != nil { + return err + } + } + + // Encode and write the value log head into a new table. + data := make([]byte, vptrSize) + sw.head.Encode(data) + headWriter := sw.newWriter(headStreamId) + if err := headWriter.Add( + y.KeyWithTs(head, sw.maxVersion), + y.ValueStruct{Value: data}); err != nil { + return err + } + if err := headWriter.Done(); err != nil { + return err + } + + if !sw.db.opt.managedTxns { + sw.db.orc = newOracle(sw.db.opt) + sw.db.orc.nextTxnTs = sw.maxVersion + sw.db.orc.txnMark.Done(sw.maxVersion) + sw.db.orc.readMark.Done(sw.maxVersion) + sw.db.orc.incrementNextTs() + } + + // Wait for all files to be written. + if err := sw.throttle.Finish(); err != nil { + return err + } + + // Now sync the directories, so all the files are registered. + if sw.db.opt.ValueDir != sw.db.opt.Dir { + if err := syncDir(sw.db.opt.ValueDir); err != nil { + return err + } + } + return syncDir(sw.db.opt.Dir) +} + +type sortedWriter struct { + db *DB + throttle *y.Throttle + + builder *table.Builder + lastKey []byte + streamId uint32 +} + +func (sw *StreamWriter) newWriter(streamId uint32) *sortedWriter { + return &sortedWriter{ + db: sw.db, + streamId: streamId, + throttle: sw.throttle, + builder: table.NewTableBuilder(), + } +} + +// ErrUnsortedKey is returned when any out of order key arrives at sortedWriter during call to Add. +var ErrUnsortedKey = errors.New("Keys not in sorted order") + +// Add adds key and vs to sortedWriter. +func (w *sortedWriter) Add(key []byte, vs y.ValueStruct) error { + if bytes.Compare(key, w.lastKey) <= 0 { + return ErrUnsortedKey + } + sameKey := y.SameKey(key, w.lastKey) + w.lastKey = y.SafeCopy(w.lastKey, key) + + if err := w.builder.Add(key, vs); err != nil { + return err + } + // Same keys should go into the same SSTable. + if !sameKey && w.builder.ReachedCapacity(w.db.opt.MaxTableSize) { + return w.send() + } + return nil +} + +func (w *sortedWriter) send() error { + if err := w.throttle.Do(); err != nil { + return err + } + go func(builder *table.Builder) { + data := builder.Finish() + err := w.createTable(data) + w.throttle.Done(err) + }(w.builder) + w.builder = table.NewTableBuilder() + return nil +} + +// Done is called once we are done writing all keys and valueStructs +// to sortedWriter. It completes writing current SST to disk. +func (w *sortedWriter) Done() error { + if w.builder.Empty() { + return nil + } + return w.send() +} + +func (w *sortedWriter) createTable(data []byte) error { + if len(data) == 0 { + return nil + } + fileID := w.db.lc.reserveFileID() + fd, err := y.CreateSyncedFile(table.NewFilename(fileID, w.db.opt.Dir), true) + if err != nil { + return err + } + if _, err := fd.Write(data); err != nil { + return err + } + tbl, err := table.OpenTable(fd, w.db.opt.TableLoadingMode, nil) + if err != nil { + return err + } + lc := w.db.lc + + var lhandler *levelHandler + // We should start the levels from 1, because we need level 0 to set the !badger!head key. We + // cannot mix up this key with other keys from the DB, otherwise we would introduce a range + // overlap violation. + y.AssertTrue(len(lc.levels) > 1) + for _, l := range lc.levels[1:] { + ratio := float64(l.getTotalSize()) / float64(l.maxTotalSize) + if ratio < 1.0 { + lhandler = l + break + } + } + if lhandler == nil { + // If we're exceeding the size of the lowest level, shove it in the lowest level. Can't do + // better than that. + lhandler = lc.levels[len(lc.levels)-1] + } + if w.streamId == headStreamId { + // This is a special !badger!head key. We should store it at level 0, separate from all the + // other keys to avoid an overlap. + lhandler = lc.levels[0] + } + // Now that table can be opened successfully, let's add this to the MANIFEST. + change := &pb.ManifestChange{ + Id: tbl.ID(), + Op: pb.ManifestChange_CREATE, + Level: uint32(lhandler.level), + Checksum: tbl.Checksum, + } + if err := w.db.manifest.addChanges([]*pb.ManifestChange{change}); err != nil { + return err + } + if err := lhandler.replaceTables([]*table.Table{}, []*table.Table{tbl}); err != nil { + return err + } + w.db.opt.Infof("Table created: %d at level: %d for stream: %d. Size: %s\n", + fileID, lhandler.level, w.streamId, humanize.Bytes(uint64(tbl.Size()))) + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/structs.go b/vendor/github.com/dgraph-io/badger/structs.go new file mode 100644 index 00000000..2161b7f3 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/structs.go @@ -0,0 +1,133 @@ +package badger + +import ( + "bytes" + "encoding/binary" + "fmt" + "hash/crc32" + + "github.com/dgraph-io/badger/y" +) + +type valuePointer struct { + Fid uint32 + Len uint32 + Offset uint32 +} + +func (p valuePointer) Less(o valuePointer) bool { + if p.Fid != o.Fid { + return p.Fid < o.Fid + } + if p.Offset != o.Offset { + return p.Offset < o.Offset + } + return p.Len < o.Len +} + +func (p valuePointer) IsZero() bool { + return p.Fid == 0 && p.Offset == 0 && p.Len == 0 +} + +const vptrSize = 12 + +// Encode encodes Pointer into byte buffer. +func (p valuePointer) Encode(b []byte) []byte { + binary.BigEndian.PutUint32(b[:4], p.Fid) + binary.BigEndian.PutUint32(b[4:8], p.Len) + binary.BigEndian.PutUint32(b[8:12], p.Offset) + return b[:vptrSize] +} + +func (p *valuePointer) Decode(b []byte) { + p.Fid = binary.BigEndian.Uint32(b[:4]) + p.Len = binary.BigEndian.Uint32(b[4:8]) + p.Offset = binary.BigEndian.Uint32(b[8:12]) +} + +// header is used in value log as a header before Entry. +type header struct { + klen uint32 + vlen uint32 + expiresAt uint64 + meta byte + userMeta byte +} + +const ( + headerBufSize = 18 +) + +func (h header) Encode(out []byte) { + y.AssertTrue(len(out) >= headerBufSize) + binary.BigEndian.PutUint32(out[0:4], h.klen) + binary.BigEndian.PutUint32(out[4:8], h.vlen) + binary.BigEndian.PutUint64(out[8:16], h.expiresAt) + out[16] = h.meta + out[17] = h.userMeta +} + +// Decodes h from buf. +func (h *header) Decode(buf []byte) { + h.klen = binary.BigEndian.Uint32(buf[0:4]) + h.vlen = binary.BigEndian.Uint32(buf[4:8]) + h.expiresAt = binary.BigEndian.Uint64(buf[8:16]) + h.meta = buf[16] + h.userMeta = buf[17] +} + +// Entry provides Key, Value, UserMeta and ExpiresAt. This struct can be used by the user to set data. +type Entry struct { + Key []byte + Value []byte + UserMeta byte + ExpiresAt uint64 // time.Unix + meta byte + + // Fields maintained internally. + offset uint32 + skipVlog bool +} + +func (e *Entry) estimateSize(threshold int) int { + if len(e.Value) < threshold { + return len(e.Key) + len(e.Value) + 2 // Meta, UserMeta + } + return len(e.Key) + 12 + 2 // 12 for ValuePointer, 2 for metas. +} + +// Encodes e to buf. Returns number of bytes written. +func encodeEntry(e *Entry, buf *bytes.Buffer) (int, error) { + h := header{ + klen: uint32(len(e.Key)), + vlen: uint32(len(e.Value)), + expiresAt: e.ExpiresAt, + meta: e.meta, + userMeta: e.UserMeta, + } + + var headerEnc [headerBufSize]byte + h.Encode(headerEnc[:]) + + hash := crc32.New(y.CastagnoliCrcTable) + + buf.Write(headerEnc[:]) + hash.Write(headerEnc[:]) + + buf.Write(e.Key) + hash.Write(e.Key) + + buf.Write(e.Value) + hash.Write(e.Value) + + var crcBuf [crc32.Size]byte + binary.BigEndian.PutUint32(crcBuf[:], hash.Sum32()) + buf.Write(crcBuf[:]) + + return len(headerEnc) + len(e.Key) + len(e.Value) + len(crcBuf), nil +} + +func (e Entry) print(prefix string) { + fmt.Printf("%s Key: %s Meta: %d UserMeta: %d Offset: %d len(val)=%d", + prefix, e.Key, e.meta, e.UserMeta, e.offset, len(e.Value)) +} diff --git a/vendor/github.com/dgraph-io/badger/table/README.md b/vendor/github.com/dgraph-io/badger/table/README.md new file mode 100644 index 00000000..5d33e96a --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/table/README.md @@ -0,0 +1,51 @@ +# BenchmarkRead + +``` +$ go test -bench Read$ -count 3 + +Size of table: 105843444 +BenchmarkRead-8 3 343846914 ns/op +BenchmarkRead-8 3 351790907 ns/op +BenchmarkRead-8 3 351762823 ns/op +``` + +Size of table is 105,843,444 bytes, which is ~101M. + +The rate is ~287M/s which matches our read speed. This is using mmap. + +To read a 64M table, this would take ~0.22s, which is negligible. + +``` +$ go test -bench BenchmarkReadAndBuild -count 3 + +BenchmarkReadAndBuild-8 1 2341034225 ns/op +BenchmarkReadAndBuild-8 1 2346349671 ns/op +BenchmarkReadAndBuild-8 1 2364064576 ns/op +``` + +The rate is ~43M/s. To build a ~64M table, this would take ~1.5s. Note that this +does NOT include the flushing of the table to disk. All we are doing above is +to read one table (mmaped) and write one table in memory. + +The table building takes 1.5-0.22 ~ 1.3s. + +If we are writing out up to 10 tables, this would take 1.5*10 ~ 15s, and ~13s +is spent building the tables. + +When running populate, building one table in memory tends to take ~1.5s to ~2.5s +on my system. Where does this overhead come from? Let's investigate the merging. + +Below, we merge 5 tables. The total size remains unchanged at ~101M. + +``` +$ go test -bench ReadMerged -count 3 +BenchmarkReadMerged-8 1 1321190264 ns/op +BenchmarkReadMerged-8 1 1296958737 ns/op +BenchmarkReadMerged-8 1 1314381178 ns/op +``` + +The rate is ~76M/s. To build a 64M table, this would take ~0.84s. The writing +takes ~1.3s as we saw above. So in total, we expect around 0.84+1.3 ~ 2.1s. +This roughly matches what we observe when running populate. There might be +some additional overhead due to the concurrent writes going on, in flushing the +table to disk. Also, the tables tend to be slightly bigger than 64M/s. \ No newline at end of file diff --git a/vendor/github.com/dgraph-io/badger/table/builder.go b/vendor/github.com/dgraph-io/badger/table/builder.go new file mode 100644 index 00000000..43e65622 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/table/builder.go @@ -0,0 +1,235 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package table + +import ( + "bytes" + "encoding/binary" + "io" + "math" + + "github.com/AndreasBriese/bbloom" + "github.com/dgraph-io/badger/y" +) + +var ( + restartInterval = 100 // Might want to change this to be based on total size instead of numKeys. +) + +func newBuffer(sz int) *bytes.Buffer { + b := new(bytes.Buffer) + b.Grow(sz) + return b +} + +type header struct { + plen uint16 // Overlap with base key. + klen uint16 // Length of the diff. + vlen uint16 // Length of value. + prev uint32 // Offset for the previous key-value pair. The offset is relative to block base offset. +} + +// Encode encodes the header. +func (h header) Encode(b []byte) { + binary.BigEndian.PutUint16(b[0:2], h.plen) + binary.BigEndian.PutUint16(b[2:4], h.klen) + binary.BigEndian.PutUint16(b[4:6], h.vlen) + binary.BigEndian.PutUint32(b[6:10], h.prev) +} + +// Decode decodes the header. +func (h *header) Decode(buf []byte) int { + h.plen = binary.BigEndian.Uint16(buf[0:2]) + h.klen = binary.BigEndian.Uint16(buf[2:4]) + h.vlen = binary.BigEndian.Uint16(buf[4:6]) + h.prev = binary.BigEndian.Uint32(buf[6:10]) + return h.Size() +} + +// Size returns size of the header. Currently it's just a constant. +func (h header) Size() int { return 10 } + +// Builder is used in building a table. +type Builder struct { + counter int // Number of keys written for the current block. + + // Typically tens or hundreds of meg. This is for one single file. + buf *bytes.Buffer + + baseKey []byte // Base key for the current block. + baseOffset uint32 // Offset for the current block. + + restarts []uint32 // Base offsets of every block. + + // Tracks offset for the previous key-value pair. Offset is relative to block base offset. + prevOffset uint32 + + keyBuf *bytes.Buffer + keyCount int +} + +// NewTableBuilder makes a new TableBuilder. +func NewTableBuilder() *Builder { + return &Builder{ + keyBuf: newBuffer(1 << 20), + buf: newBuffer(1 << 20), + prevOffset: math.MaxUint32, // Used for the first element! + } +} + +// Close closes the TableBuilder. +func (b *Builder) Close() {} + +// Empty returns whether it's empty. +func (b *Builder) Empty() bool { return b.buf.Len() == 0 } + +// keyDiff returns a suffix of newKey that is different from b.baseKey. +func (b Builder) keyDiff(newKey []byte) []byte { + var i int + for i = 0; i < len(newKey) && i < len(b.baseKey); i++ { + if newKey[i] != b.baseKey[i] { + break + } + } + return newKey[i:] +} + +func (b *Builder) addHelper(key []byte, v y.ValueStruct) { + // Add key to bloom filter. + if len(key) > 0 { + var klen [2]byte + keyNoTs := y.ParseKey(key) + binary.BigEndian.PutUint16(klen[:], uint16(len(keyNoTs))) + b.keyBuf.Write(klen[:]) + b.keyBuf.Write(keyNoTs) + b.keyCount++ + } + + // diffKey stores the difference of key with baseKey. + var diffKey []byte + if len(b.baseKey) == 0 { + // Make a copy. Builder should not keep references. Otherwise, caller has to be very careful + // and will have to make copies of keys every time they add to builder, which is even worse. + b.baseKey = append(b.baseKey[:0], key...) + diffKey = key + } else { + diffKey = b.keyDiff(key) + } + + h := header{ + plen: uint16(len(key) - len(diffKey)), + klen: uint16(len(diffKey)), + vlen: uint16(v.EncodedSize()), + prev: b.prevOffset, // prevOffset is the location of the last key-value added. + } + b.prevOffset = uint32(b.buf.Len()) - b.baseOffset // Remember current offset for the next Add call. + + // Layout: header, diffKey, value. + var hbuf [10]byte + h.Encode(hbuf[:]) + b.buf.Write(hbuf[:]) + b.buf.Write(diffKey) // We only need to store the key difference. + + v.EncodeTo(b.buf) + b.counter++ // Increment number of keys added for this current block. +} + +func (b *Builder) finishBlock() { + // When we are at the end of the block and Valid=false, and the user wants to do a Prev, + // we need a dummy header to tell us the offset of the previous key-value pair. + b.addHelper([]byte{}, y.ValueStruct{}) +} + +// Add adds a key-value pair to the block. +// If doNotRestart is true, we will not restart even if b.counter >= restartInterval. +func (b *Builder) Add(key []byte, value y.ValueStruct) error { + if b.counter >= restartInterval { + b.finishBlock() + // Start a new block. Initialize the block. + b.restarts = append(b.restarts, uint32(b.buf.Len())) + b.counter = 0 + b.baseKey = []byte{} + b.baseOffset = uint32(b.buf.Len()) + b.prevOffset = math.MaxUint32 // First key-value pair of block has header.prev=MaxInt. + } + b.addHelper(key, value) + return nil // Currently, there is no meaningful error. +} + +// TODO: vvv this was the comment on ReachedCapacity. +// FinalSize returns the *rough* final size of the array, counting the header which is not yet written. +// TODO: Look into why there is a discrepancy. I suspect it is because of Write(empty, empty) +// at the end. The diff can vary. + +// ReachedCapacity returns true if we... roughly (?) reached capacity? +func (b *Builder) ReachedCapacity(cap int64) bool { + estimateSz := b.buf.Len() + 8 /* empty header */ + 4*len(b.restarts) + 8 // 8 = end of buf offset + len(restarts). + return int64(estimateSz) > cap +} + +// blockIndex generates the block index for the table. +// It is mainly a list of all the block base offsets. +func (b *Builder) blockIndex() []byte { + // Store the end offset, so we know the length of the final block. + b.restarts = append(b.restarts, uint32(b.buf.Len())) + + // Add 4 because we want to write out number of restarts at the end. + sz := 4*len(b.restarts) + 4 + out := make([]byte, sz) + buf := out + for _, r := range b.restarts { + binary.BigEndian.PutUint32(buf[:4], r) + buf = buf[4:] + } + binary.BigEndian.PutUint32(buf[:4], uint32(len(b.restarts))) + return out +} + +// Finish finishes the table by appending the index. +func (b *Builder) Finish() []byte { + bf := bbloom.New(float64(b.keyCount), 0.01) + var klen [2]byte + key := make([]byte, 1024) + for { + if _, err := b.keyBuf.Read(klen[:]); err == io.EOF { + break + } else if err != nil { + y.Check(err) + } + kl := int(binary.BigEndian.Uint16(klen[:])) + if cap(key) < kl { + key = make([]byte, 2*int(kl)) // 2 * uint16 will overflow + } + key = key[:kl] + y.Check2(b.keyBuf.Read(key)) + bf.Add(key) + } + + b.finishBlock() // This will never start a new block. + index := b.blockIndex() + b.buf.Write(index) + + // Write bloom filter. + bdata := bf.JSONMarshal() + n, err := b.buf.Write(bdata) + y.Check(err) + var buf [4]byte + binary.BigEndian.PutUint32(buf[:], uint32(n)) + b.buf.Write(buf[:]) + + return b.buf.Bytes() +} diff --git a/vendor/github.com/dgraph-io/badger/table/iterator.go b/vendor/github.com/dgraph-io/badger/table/iterator.go new file mode 100644 index 00000000..0eb5ed01 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/table/iterator.go @@ -0,0 +1,539 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package table + +import ( + "bytes" + "io" + "math" + "sort" + + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +type blockIterator struct { + data []byte + pos uint32 + err error + baseKey []byte + + key []byte + val []byte + init bool + + last header // The last header we saw. +} + +func (itr *blockIterator) Reset() { + itr.pos = 0 + itr.err = nil + itr.baseKey = []byte{} + itr.key = []byte{} + itr.val = []byte{} + itr.init = false + itr.last = header{} +} + +func (itr *blockIterator) Init() { + if !itr.init { + itr.Next() + } +} + +func (itr *blockIterator) Valid() bool { + return itr != nil && itr.err == nil +} + +func (itr *blockIterator) Error() error { + return itr.err +} + +func (itr *blockIterator) Close() {} + +var ( + origin = 0 + current = 1 +) + +// Seek brings us to the first block element that is >= input key. +func (itr *blockIterator) Seek(key []byte, whence int) { + itr.err = nil + + switch whence { + case origin: + itr.Reset() + case current: + } + + var done bool + for itr.Init(); itr.Valid(); itr.Next() { + k := itr.Key() + if y.CompareKeys(k, key) >= 0 { + // We are done as k is >= key. + done = true + break + } + } + if !done { + itr.err = io.EOF + } +} + +func (itr *blockIterator) SeekToFirst() { + itr.err = nil + itr.Init() +} + +// SeekToLast brings us to the last element. Valid should return true. +func (itr *blockIterator) SeekToLast() { + itr.err = nil + for itr.Init(); itr.Valid(); itr.Next() { + } + itr.Prev() +} + +// parseKV would allocate a new byte slice for key and for value. +func (itr *blockIterator) parseKV(h header) { + if cap(itr.key) < int(h.plen+h.klen) { + sz := int(h.plen) + int(h.klen) // Convert to int before adding to avoid uint16 overflow. + itr.key = make([]byte, 2*sz) + } + itr.key = itr.key[:h.plen+h.klen] + copy(itr.key, itr.baseKey[:h.plen]) + copy(itr.key[h.plen:], itr.data[itr.pos:itr.pos+uint32(h.klen)]) + itr.pos += uint32(h.klen) + + if itr.pos+uint32(h.vlen) > uint32(len(itr.data)) { + itr.err = errors.Errorf("Value exceeded size of block: %d %d %d %d %v", + itr.pos, h.klen, h.vlen, len(itr.data), h) + return + } + itr.val = y.SafeCopy(itr.val, itr.data[itr.pos:itr.pos+uint32(h.vlen)]) + itr.pos += uint32(h.vlen) +} + +func (itr *blockIterator) Next() { + itr.init = true + itr.err = nil + if itr.pos >= uint32(len(itr.data)) { + itr.err = io.EOF + return + } + + var h header + itr.pos += uint32(h.Decode(itr.data[itr.pos:])) + itr.last = h // Store the last header. + + if h.klen == 0 && h.plen == 0 { + // Last entry in the table. + itr.err = io.EOF + return + } + + // Populate baseKey if it isn't set yet. This would only happen for the first Next. + if len(itr.baseKey) == 0 { + // This should be the first Next() for this block. Hence, prefix length should be zero. + y.AssertTrue(h.plen == 0) + itr.baseKey = itr.data[itr.pos : itr.pos+uint32(h.klen)] + } + itr.parseKV(h) +} + +func (itr *blockIterator) Prev() { + if !itr.init { + return + } + itr.err = nil + if itr.last.prev == math.MaxUint32 { + // This is the first element of the block! + itr.err = io.EOF + itr.pos = 0 + return + } + + // Move back using current header's prev. + itr.pos = itr.last.prev + + var h header + y.AssertTruef(itr.pos < uint32(len(itr.data)), "%d %d", itr.pos, len(itr.data)) + itr.pos += uint32(h.Decode(itr.data[itr.pos:])) + itr.parseKV(h) + itr.last = h +} + +func (itr *blockIterator) Key() []byte { + if itr.err != nil { + return nil + } + return itr.key +} + +func (itr *blockIterator) Value() []byte { + if itr.err != nil { + return nil + } + return itr.val +} + +// Iterator is an iterator for a Table. +type Iterator struct { + t *Table + bpos int + bi *blockIterator + err error + + // Internally, Iterator is bidirectional. However, we only expose the + // unidirectional functionality for now. + reversed bool +} + +// NewIterator returns a new iterator of the Table +func (t *Table) NewIterator(reversed bool) *Iterator { + t.IncrRef() // Important. + ti := &Iterator{t: t, reversed: reversed} + ti.next() + return ti +} + +// Close closes the iterator (and it must be called). +func (itr *Iterator) Close() error { + return itr.t.DecrRef() +} + +func (itr *Iterator) reset() { + itr.bpos = 0 + itr.err = nil +} + +// Valid follows the y.Iterator interface +func (itr *Iterator) Valid() bool { + return itr.err == nil +} + +func (itr *Iterator) seekToFirst() { + numBlocks := len(itr.t.blockIndex) + if numBlocks == 0 { + itr.err = io.EOF + return + } + itr.bpos = 0 + block, err := itr.t.block(itr.bpos) + if err != nil { + itr.err = err + return + } + itr.bi = block.NewIterator() + itr.bi.SeekToFirst() + itr.err = itr.bi.Error() +} + +func (itr *Iterator) seekToLast() { + numBlocks := len(itr.t.blockIndex) + if numBlocks == 0 { + itr.err = io.EOF + return + } + itr.bpos = numBlocks - 1 + block, err := itr.t.block(itr.bpos) + if err != nil { + itr.err = err + return + } + itr.bi = block.NewIterator() + itr.bi.SeekToLast() + itr.err = itr.bi.Error() +} + +func (itr *Iterator) seekHelper(blockIdx int, key []byte) { + itr.bpos = blockIdx + block, err := itr.t.block(blockIdx) + if err != nil { + itr.err = err + return + } + itr.bi = block.NewIterator() + itr.bi.Seek(key, origin) + itr.err = itr.bi.Error() +} + +// seekFrom brings us to a key that is >= input key. +func (itr *Iterator) seekFrom(key []byte, whence int) { + itr.err = nil + switch whence { + case origin: + itr.reset() + case current: + } + + idx := sort.Search(len(itr.t.blockIndex), func(idx int) bool { + ko := itr.t.blockIndex[idx] + return y.CompareKeys(ko.key, key) > 0 + }) + if idx == 0 { + // The smallest key in our table is already strictly > key. We can return that. + // This is like a SeekToFirst. + itr.seekHelper(0, key) + return + } + + // block[idx].smallest is > key. + // Since idx>0, we know block[idx-1].smallest is <= key. + // There are two cases. + // 1) Everything in block[idx-1] is strictly < key. In this case, we should go to the first + // element of block[idx]. + // 2) Some element in block[idx-1] is >= key. We should go to that element. + itr.seekHelper(idx-1, key) + if itr.err == io.EOF { + // Case 1. Need to visit block[idx]. + if idx == len(itr.t.blockIndex) { + // If idx == len(itr.t.blockIndex), then input key is greater than ANY element of table. + // There's nothing we can do. Valid() should return false as we seek to end of table. + return + } + // Since block[idx].smallest is > key. This is essentially a block[idx].SeekToFirst. + itr.seekHelper(idx, key) + } + // Case 2: No need to do anything. We already did the seek in block[idx-1]. +} + +// seek will reset iterator and seek to >= key. +func (itr *Iterator) seek(key []byte) { + itr.seekFrom(key, origin) +} + +// seekForPrev will reset iterator and seek to <= key. +func (itr *Iterator) seekForPrev(key []byte) { + // TODO: Optimize this. We shouldn't have to take a Prev step. + itr.seekFrom(key, origin) + if !bytes.Equal(itr.Key(), key) { + itr.prev() + } +} + +func (itr *Iterator) next() { + itr.err = nil + + if itr.bpos >= len(itr.t.blockIndex) { + itr.err = io.EOF + return + } + + if itr.bi == nil { + block, err := itr.t.block(itr.bpos) + if err != nil { + itr.err = err + return + } + itr.bi = block.NewIterator() + itr.bi.SeekToFirst() + itr.err = itr.bi.Error() + return + } + + itr.bi.Next() + if !itr.bi.Valid() { + itr.bpos++ + itr.bi = nil + itr.next() + return + } +} + +func (itr *Iterator) prev() { + itr.err = nil + if itr.bpos < 0 { + itr.err = io.EOF + return + } + + if itr.bi == nil { + block, err := itr.t.block(itr.bpos) + if err != nil { + itr.err = err + return + } + itr.bi = block.NewIterator() + itr.bi.SeekToLast() + itr.err = itr.bi.Error() + return + } + + itr.bi.Prev() + if !itr.bi.Valid() { + itr.bpos-- + itr.bi = nil + itr.prev() + return + } +} + +// Key follows the y.Iterator interface +func (itr *Iterator) Key() []byte { + return itr.bi.Key() +} + +// Value follows the y.Iterator interface +func (itr *Iterator) Value() (ret y.ValueStruct) { + ret.Decode(itr.bi.Value()) + return +} + +// Next follows the y.Iterator interface +func (itr *Iterator) Next() { + if !itr.reversed { + itr.next() + } else { + itr.prev() + } +} + +// Rewind follows the y.Iterator interface +func (itr *Iterator) Rewind() { + if !itr.reversed { + itr.seekToFirst() + } else { + itr.seekToLast() + } +} + +// Seek follows the y.Iterator interface +func (itr *Iterator) Seek(key []byte) { + if !itr.reversed { + itr.seek(key) + } else { + itr.seekForPrev(key) + } +} + +// ConcatIterator concatenates the sequences defined by several iterators. (It only works with +// TableIterators, probably just because it's faster to not be so generic.) +type ConcatIterator struct { + idx int // Which iterator is active now. + cur *Iterator + iters []*Iterator // Corresponds to tables. + tables []*Table // Disregarding reversed, this is in ascending order. + reversed bool +} + +// NewConcatIterator creates a new concatenated iterator +func NewConcatIterator(tbls []*Table, reversed bool) *ConcatIterator { + iters := make([]*Iterator, len(tbls)) + for i := 0; i < len(tbls); i++ { + iters[i] = tbls[i].NewIterator(reversed) + } + return &ConcatIterator{ + reversed: reversed, + iters: iters, + tables: tbls, + idx: -1, // Not really necessary because s.it.Valid()=false, but good to have. + } +} + +func (s *ConcatIterator) setIdx(idx int) { + s.idx = idx + if idx < 0 || idx >= len(s.iters) { + s.cur = nil + } else { + s.cur = s.iters[s.idx] + } +} + +// Rewind implements y.Interface +func (s *ConcatIterator) Rewind() { + if len(s.iters) == 0 { + return + } + if !s.reversed { + s.setIdx(0) + } else { + s.setIdx(len(s.iters) - 1) + } + s.cur.Rewind() +} + +// Valid implements y.Interface +func (s *ConcatIterator) Valid() bool { + return s.cur != nil && s.cur.Valid() +} + +// Key implements y.Interface +func (s *ConcatIterator) Key() []byte { + return s.cur.Key() +} + +// Value implements y.Interface +func (s *ConcatIterator) Value() y.ValueStruct { + return s.cur.Value() +} + +// Seek brings us to element >= key if reversed is false. Otherwise, <= key. +func (s *ConcatIterator) Seek(key []byte) { + var idx int + if !s.reversed { + idx = sort.Search(len(s.tables), func(i int) bool { + return y.CompareKeys(s.tables[i].Biggest(), key) >= 0 + }) + } else { + n := len(s.tables) + idx = n - 1 - sort.Search(n, func(i int) bool { + return y.CompareKeys(s.tables[n-1-i].Smallest(), key) <= 0 + }) + } + if idx >= len(s.tables) || idx < 0 { + s.setIdx(-1) + return + } + // For reversed=false, we know s.tables[i-1].Biggest() < key. Thus, the + // previous table cannot possibly contain key. + s.setIdx(idx) + s.cur.Seek(key) +} + +// Next advances our concat iterator. +func (s *ConcatIterator) Next() { + s.cur.Next() + if s.cur.Valid() { + // Nothing to do. Just stay with the current table. + return + } + for { // In case there are empty tables. + if !s.reversed { + s.setIdx(s.idx + 1) + } else { + s.setIdx(s.idx - 1) + } + if s.cur == nil { + // End of list. Valid will become false. + return + } + s.cur.Rewind() + if s.cur.Valid() { + break + } + } +} + +// Close implements y.Interface. +func (s *ConcatIterator) Close() error { + for _, it := range s.iters { + if err := it.Close(); err != nil { + return errors.Wrap(err, "ConcatIterator") + } + } + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/table/table.go b/vendor/github.com/dgraph-io/badger/table/table.go new file mode 100644 index 00000000..9650c08e --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/table/table.go @@ -0,0 +1,356 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package table + +import ( + "bytes" + "crypto/sha256" + "encoding/binary" + "fmt" + "io" + "os" + "path" + "path/filepath" + "strconv" + "strings" + "sync" + "sync/atomic" + + "github.com/AndreasBriese/bbloom" + "github.com/dgraph-io/badger/options" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +const fileSuffix = ".sst" + +type keyOffset struct { + key []byte + offset int + len int +} + +// TableInterface is useful for testing. +type TableInterface interface { + Smallest() []byte + Biggest() []byte + DoesNotHave(key []byte) bool +} + +// Table represents a loaded table file with the info we have about it +type Table struct { + sync.Mutex + + fd *os.File // Own fd. + tableSize int // Initialized in OpenTable, using fd.Stat(). + + blockIndex []keyOffset + ref int32 // For file garbage collection. Atomic. + + loadingMode options.FileLoadingMode + mmap []byte // Memory mapped. + + // The following are initialized once and const. + smallest, biggest []byte // Smallest and largest keys. + id uint64 // file id, part of filename + + bf bbloom.Bloom + + Checksum []byte +} + +// IncrRef increments the refcount (having to do with whether the file should be deleted) +func (t *Table) IncrRef() { + atomic.AddInt32(&t.ref, 1) +} + +// DecrRef decrements the refcount and possibly deletes the table +func (t *Table) DecrRef() error { + newRef := atomic.AddInt32(&t.ref, -1) + if newRef == 0 { + // We can safely delete this file, because for all the current files, we always have + // at least one reference pointing to them. + + // It's necessary to delete windows files + if t.loadingMode == options.MemoryMap { + y.Munmap(t.mmap) + } + if err := t.fd.Truncate(0); err != nil { + // This is very important to let the FS know that the file is deleted. + return err + } + filename := t.fd.Name() + if err := t.fd.Close(); err != nil { + return err + } + if err := os.Remove(filename); err != nil { + return err + } + } + return nil +} + +type block struct { + offset int + data []byte +} + +func (b block) NewIterator() *blockIterator { + return &blockIterator{data: b.data} +} + +// OpenTable assumes file has only one table and opens it. Takes ownership of fd upon function +// entry. Returns a table with one reference count on it (decrementing which may delete the file! +// -- consider t.Close() instead). The fd has to writeable because we call Truncate on it before +// deleting. +func OpenTable(fd *os.File, mode options.FileLoadingMode, cksum []byte) (*Table, error) { + fileInfo, err := fd.Stat() + if err != nil { + // It's OK to ignore fd.Close() errs in this function because we have only read + // from the file. + _ = fd.Close() + return nil, y.Wrap(err) + } + + filename := fileInfo.Name() + id, ok := ParseFileID(filename) + if !ok { + _ = fd.Close() + return nil, errors.Errorf("Invalid filename: %s", filename) + } + t := &Table{ + fd: fd, + ref: 1, // Caller is given one reference. + id: id, + loadingMode: mode, + } + + t.tableSize = int(fileInfo.Size()) + + // We first load to RAM, so we can read the index and do checksum. + if err := t.loadToRAM(); err != nil { + return nil, err + } + // Enforce checksum before we read index. Otherwise, if the file was + // truncated, we'd end up with panics in readIndex. + if len(cksum) > 0 && !bytes.Equal(t.Checksum, cksum) { + return nil, fmt.Errorf( + "CHECKSUM_MISMATCH: Table checksum does not match checksum in MANIFEST."+ + " NOT including table %s. This would lead to missing data."+ + "\n sha256 %x Expected\n sha256 %x Found\n", filename, cksum, t.Checksum) + } + if err := t.readIndex(); err != nil { + return nil, y.Wrap(err) + } + + it := t.NewIterator(false) + defer it.Close() + it.Rewind() + if it.Valid() { + t.smallest = it.Key() + } + + it2 := t.NewIterator(true) + defer it2.Close() + it2.Rewind() + if it2.Valid() { + t.biggest = it2.Key() + } + + switch mode { + case options.LoadToRAM: + // No need to do anything. t.mmap is already filled. + case options.MemoryMap: + t.mmap, err = y.Mmap(fd, false, fileInfo.Size()) + if err != nil { + _ = fd.Close() + return nil, y.Wrapf(err, "Unable to map file") + } + case options.FileIO: + t.mmap = nil + default: + panic(fmt.Sprintf("Invalid loading mode: %v", mode)) + } + return t, nil +} + +// Close closes the open table. (Releases resources back to the OS.) +func (t *Table) Close() error { + if t.loadingMode == options.MemoryMap { + y.Munmap(t.mmap) + } + + return t.fd.Close() +} + +func (t *Table) read(off, sz int) ([]byte, error) { + if len(t.mmap) > 0 { + if len(t.mmap[off:]) < sz { + return nil, y.ErrEOF + } + return t.mmap[off : off+sz], nil + } + + res := make([]byte, sz) + nbr, err := t.fd.ReadAt(res, int64(off)) + y.NumReads.Add(1) + y.NumBytesRead.Add(int64(nbr)) + return res, err +} + +func (t *Table) readNoFail(off, sz int) []byte { + res, err := t.read(off, sz) + y.Check(err) + return res +} + +func (t *Table) readIndex() error { + if len(t.mmap) != t.tableSize { + panic("Table size does not match the read bytes") + } + readPos := t.tableSize + + // Read bloom filter. + readPos -= 4 + buf := t.readNoFail(readPos, 4) + bloomLen := int(binary.BigEndian.Uint32(buf)) + readPos -= bloomLen + data := t.readNoFail(readPos, bloomLen) + t.bf = bbloom.JSONUnmarshal(data) + + readPos -= 4 + buf = t.readNoFail(readPos, 4) + restartsLen := int(binary.BigEndian.Uint32(buf)) + + readPos -= 4 * restartsLen + buf = t.readNoFail(readPos, 4*restartsLen) + + offsets := make([]int, restartsLen) + for i := 0; i < restartsLen; i++ { + offsets[i] = int(binary.BigEndian.Uint32(buf[:4])) + buf = buf[4:] + } + + // The last offset stores the end of the last block. + for i := 0; i < len(offsets); i++ { + var o int + if i == 0 { + o = 0 + } else { + o = offsets[i-1] + } + + ko := keyOffset{ + offset: o, + len: offsets[i] - o, + } + t.blockIndex = append(t.blockIndex, ko) + } + + // Execute this index read serially, because we already have table data in memory. + var h header + for idx := range t.blockIndex { + ko := &t.blockIndex[idx] + + hbuf := t.readNoFail(ko.offset, h.Size()) + h.Decode(hbuf) + y.AssertTrue(h.plen == 0) + + key := t.readNoFail(ko.offset+len(hbuf), int(h.klen)) + ko.key = append([]byte{}, key...) + } + + return nil +} + +func (t *Table) block(idx int) (block, error) { + y.AssertTruef(idx >= 0, "idx=%d", idx) + if idx >= len(t.blockIndex) { + return block{}, errors.New("block out of index") + } + + ko := t.blockIndex[idx] + blk := block{ + offset: ko.offset, + } + var err error + blk.data, err = t.read(blk.offset, ko.len) + return blk, err +} + +// Size is its file size in bytes +func (t *Table) Size() int64 { return int64(t.tableSize) } + +// Smallest is its smallest key, or nil if there are none +func (t *Table) Smallest() []byte { return t.smallest } + +// Biggest is its biggest key, or nil if there are none +func (t *Table) Biggest() []byte { return t.biggest } + +// Filename is NOT the file name. Just kidding, it is. +func (t *Table) Filename() string { return t.fd.Name() } + +// ID is the table's ID number (used to make the file name). +func (t *Table) ID() uint64 { return t.id } + +// DoesNotHave returns true if (but not "only if") the table does not have the key. It does a +// bloom filter lookup. +func (t *Table) DoesNotHave(key []byte) bool { return !t.bf.Has(key) } + +// ParseFileID reads the file id out of a filename. +func ParseFileID(name string) (uint64, bool) { + name = path.Base(name) + if !strings.HasSuffix(name, fileSuffix) { + return 0, false + } + // suffix := name[len(fileSuffix):] + name = strings.TrimSuffix(name, fileSuffix) + id, err := strconv.Atoi(name) + if err != nil { + return 0, false + } + y.AssertTrue(id >= 0) + return uint64(id), true +} + +// IDToFilename does the inverse of ParseFileID +func IDToFilename(id uint64) string { + return fmt.Sprintf("%06d", id) + fileSuffix +} + +// NewFilename should be named TableFilepath -- it combines the dir with the ID to make a table +// filepath. +func NewFilename(id uint64, dir string) string { + return filepath.Join(dir, IDToFilename(id)) +} + +func (t *Table) loadToRAM() error { + if _, err := t.fd.Seek(0, io.SeekStart); err != nil { + return err + } + t.mmap = make([]byte, t.tableSize) + sum := sha256.New() + tee := io.TeeReader(t.fd, sum) + read, err := tee.Read(t.mmap) + if err != nil || read != t.tableSize { + return y.Wrapf(err, "Unable to load file in memory. Table file: %s", t.Filename()) + } + t.Checksum = sum.Sum(nil) + y.NumReads.Add(1) + y.NumBytesRead.Add(int64(read)) + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/test.sh b/vendor/github.com/dgraph-io/badger/test.sh new file mode 100755 index 00000000..e2df230e --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/test.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +# Ensure that we can compile the binary. +pushd badger +go build -v . +popd + +# Run the memory intensive tests first. +go test -v --manual=true -run='TestBigKeyValuePairs$' +go test -v --manual=true -run='TestPushValueLogLimit' + +# Run the special Truncate test. +rm -R p || true +go test -v --manual=true -run='TestTruncateVlogNoClose$' . +truncate --size=4096 p/000000.vlog +go test -v --manual=true -run='TestTruncateVlogNoClose2$' . +go test -v --manual=true -run='TestTruncateVlogNoClose3$' . +rm -R p || true + +# Then the normal tests. +echo +echo "==> Starting tests with value log mmapped..." +sleep 5 +go test -v --vlog_mmap=true -race ./... + +echo +echo "==> Starting tests with value log not mmapped..." +sleep 5 +go test -v --vlog_mmap=false -race ./... diff --git a/vendor/github.com/dgraph-io/badger/txn.go b/vendor/github.com/dgraph-io/badger/txn.go new file mode 100644 index 00000000..f6faa926 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/txn.go @@ -0,0 +1,765 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bytes" + "context" + "encoding/hex" + "math" + "sort" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/y" + farm "github.com/dgryski/go-farm" + "github.com/pkg/errors" +) + +type oracle struct { + // A 64-bit integer must be at the top for memory alignment. See issue #311. + refCount int64 + isManaged bool // Does not change value, so no locking required. + + sync.Mutex // For nextTxnTs and commits. + // writeChLock lock is for ensuring that transactions go to the write + // channel in the same order as their commit timestamps. + writeChLock sync.Mutex + nextTxnTs uint64 + + // Used to block NewTransaction, so all previous commits are visible to a new read. + txnMark *y.WaterMark + + // Either of these is used to determine which versions can be permanently + // discarded during compaction. + discardTs uint64 // Used by ManagedDB. + readMark *y.WaterMark // Used by DB. + + // commits stores a key fingerprint and latest commit counter for it. + // refCount is used to clear out commits map to avoid a memory blowup. + commits map[uint64]uint64 + + // closer is used to stop watermarks. + closer *y.Closer +} + +func newOracle(opt Options) *oracle { + orc := &oracle{ + isManaged: opt.managedTxns, + commits: make(map[uint64]uint64), + // We're not initializing nextTxnTs and readOnlyTs. It would be done after replay in Open. + // + // WaterMarks must be 64-bit aligned for atomic package, hence we must use pointers here. + // See https://golang.org/pkg/sync/atomic/#pkg-note-BUG. + readMark: &y.WaterMark{Name: "badger.PendingReads"}, + txnMark: &y.WaterMark{Name: "badger.TxnTimestamp"}, + closer: y.NewCloser(2), + } + orc.readMark.Init(orc.closer) + orc.txnMark.Init(orc.closer) + return orc +} + +func (o *oracle) Stop() { + o.closer.SignalAndWait() +} + +func (o *oracle) addRef() { + atomic.AddInt64(&o.refCount, 1) +} + +func (o *oracle) decrRef() { + if atomic.AddInt64(&o.refCount, -1) != 0 { + return + } + + // Clear out commits maps to release memory. + o.Lock() + defer o.Unlock() + // Avoids the race where something new is added to commitsMap + // after we check refCount and before we take Lock. + if atomic.LoadInt64(&o.refCount) != 0 { + return + } + if len(o.commits) >= 1000 { // If the map is still small, let it slide. + o.commits = make(map[uint64]uint64) + } +} + +func (o *oracle) readTs() uint64 { + if o.isManaged { + panic("ReadTs should not be retrieved for managed DB") + } + + var readTs uint64 + o.Lock() + readTs = o.nextTxnTs - 1 + o.readMark.Begin(readTs) + o.Unlock() + + // Wait for all txns which have no conflicts, have been assigned a commit + // timestamp and are going through the write to value log and LSM tree + // process. Not waiting here could mean that some txns which have been + // committed would not be read. + y.Check(o.txnMark.WaitForMark(context.Background(), readTs)) + return readTs +} + +func (o *oracle) nextTs() uint64 { + o.Lock() + defer o.Unlock() + return o.nextTxnTs +} + +func (o *oracle) incrementNextTs() { + o.Lock() + defer o.Unlock() + o.nextTxnTs++ +} + +// Any deleted or invalid versions at or below ts would be discarded during +// compaction to reclaim disk space in LSM tree and thence value log. +func (o *oracle) setDiscardTs(ts uint64) { + o.Lock() + defer o.Unlock() + o.discardTs = ts +} + +func (o *oracle) discardAtOrBelow() uint64 { + if o.isManaged { + o.Lock() + defer o.Unlock() + return o.discardTs + } + return o.readMark.DoneUntil() +} + +// hasConflict must be called while having a lock. +func (o *oracle) hasConflict(txn *Txn) bool { + if len(txn.reads) == 0 { + return false + } + for _, ro := range txn.reads { + // A commit at the read timestamp is expected. + // But, any commit after the read timestamp should cause a conflict. + if ts, has := o.commits[ro]; has && ts > txn.readTs { + return true + } + } + return false +} + +func (o *oracle) newCommitTs(txn *Txn) uint64 { + o.Lock() + defer o.Unlock() + + if o.hasConflict(txn) { + return 0 + } + + var ts uint64 + if !o.isManaged { + // This is the general case, when user doesn't specify the read and commit ts. + ts = o.nextTxnTs + o.nextTxnTs++ + o.txnMark.Begin(ts) + + } else { + // If commitTs is set, use it instead. + ts = txn.commitTs + } + + for _, w := range txn.writes { + o.commits[w] = ts // Update the commitTs. + } + return ts +} + +func (o *oracle) doneCommit(cts uint64) { + if o.isManaged { + // No need to update anything. + return + } + o.txnMark.Done(cts) +} + +// Txn represents a Badger transaction. +type Txn struct { + readTs uint64 + commitTs uint64 + + update bool // update is used to conditionally keep track of reads. + reads []uint64 // contains fingerprints of keys read. + writes []uint64 // contains fingerprints of keys written. + + pendingWrites map[string]*Entry // cache stores any writes done by txn. + + db *DB + discarded bool + + size int64 + count int64 + numIterators int32 +} + +type pendingWritesIterator struct { + entries []*Entry + nextIdx int + readTs uint64 + reversed bool +} + +func (pi *pendingWritesIterator) Next() { + pi.nextIdx++ +} + +func (pi *pendingWritesIterator) Rewind() { + pi.nextIdx = 0 +} + +func (pi *pendingWritesIterator) Seek(key []byte) { + key = y.ParseKey(key) + pi.nextIdx = sort.Search(len(pi.entries), func(idx int) bool { + cmp := bytes.Compare(pi.entries[idx].Key, key) + if !pi.reversed { + return cmp >= 0 + } + return cmp <= 0 + }) +} + +func (pi *pendingWritesIterator) Key() []byte { + y.AssertTrue(pi.Valid()) + entry := pi.entries[pi.nextIdx] + return y.KeyWithTs(entry.Key, pi.readTs) +} + +func (pi *pendingWritesIterator) Value() y.ValueStruct { + y.AssertTrue(pi.Valid()) + entry := pi.entries[pi.nextIdx] + return y.ValueStruct{ + Value: entry.Value, + Meta: entry.meta, + UserMeta: entry.UserMeta, + ExpiresAt: entry.ExpiresAt, + Version: pi.readTs, + } +} + +func (pi *pendingWritesIterator) Valid() bool { + return pi.nextIdx < len(pi.entries) +} + +func (pi *pendingWritesIterator) Close() error { + return nil +} + +func (txn *Txn) newPendingWritesIterator(reversed bool) *pendingWritesIterator { + if !txn.update || len(txn.pendingWrites) == 0 { + return nil + } + entries := make([]*Entry, 0, len(txn.pendingWrites)) + for _, e := range txn.pendingWrites { + entries = append(entries, e) + } + // Number of pending writes per transaction shouldn't be too big in general. + sort.Slice(entries, func(i, j int) bool { + cmp := bytes.Compare(entries[i].Key, entries[j].Key) + if !reversed { + return cmp < 0 + } + return cmp > 0 + }) + return &pendingWritesIterator{ + readTs: txn.readTs, + entries: entries, + reversed: reversed, + } +} + +func (txn *Txn) checkSize(e *Entry) error { + count := txn.count + 1 + // Extra bytes for version in key. + size := txn.size + int64(e.estimateSize(txn.db.opt.ValueThreshold)) + 10 + if count >= txn.db.opt.maxBatchCount || size >= txn.db.opt.maxBatchSize { + return ErrTxnTooBig + } + txn.count, txn.size = count, size + return nil +} + +// Set adds a key-value pair to the database. +// +// It will return ErrReadOnlyTxn if update flag was set to false when creating the +// transaction. +// +// The current transaction keeps a reference to the key and val byte slice +// arguments. Users must not modify key and val until the end of the transaction. +func (txn *Txn) Set(key, val []byte) error { + e := &Entry{ + Key: key, + Value: val, + } + return txn.SetEntry(e) +} + +// SetWithMeta adds a key-value pair to the database, along with a metadata +// byte. +// +// This byte is stored alongside the key, and can be used as an aid to +// interpret the value or store other contextual bits corresponding to the +// key-value pair. +// +// The current transaction keeps a reference to the key and val byte slice +// arguments. Users must not modify key and val until the end of the transaction. +func (txn *Txn) SetWithMeta(key, val []byte, meta byte) error { + e := &Entry{Key: key, Value: val, UserMeta: meta} + return txn.SetEntry(e) +} + +// SetWithDiscard acts like SetWithMeta, but adds a marker to discard earlier +// versions of the key. +// +// This method is only useful if you have set a higher limit for +// options.NumVersionsToKeep. The default setting is 1, in which case, this +// function doesn't add any more benefit than just calling the normal +// SetWithMeta (or Set) function. If however, you have a higher setting for +// NumVersionsToKeep (in Dgraph, we set it to infinity), you can use this method +// to indicate that all the older versions can be discarded and removed during +// compactions. +// +// The current transaction keeps a reference to the key and val byte slice +// arguments. Users must not modify key and val until the end of the +// transaction. +func (txn *Txn) SetWithDiscard(key, val []byte, meta byte) error { + e := &Entry{ + Key: key, + Value: val, + UserMeta: meta, + meta: bitDiscardEarlierVersions, + } + return txn.SetEntry(e) +} + +// SetWithTTL adds a key-value pair to the database, along with a time-to-live +// (TTL) setting. A key stored with a TTL would automatically expire after the +// time has elapsed, and be eligible for garbage collection. +// +// The current transaction keeps a reference to the key and val byte slice +// arguments. Users must not modify key and val until the end of the +// transaction. +func (txn *Txn) SetWithTTL(key, val []byte, dur time.Duration) error { + expire := time.Now().Add(dur).Unix() + e := &Entry{Key: key, Value: val, ExpiresAt: uint64(expire)} + return txn.SetEntry(e) +} + +// setMergeEntry is similar to SetEntry but it sets the bitMergeEntry flag +func (txn *Txn) setMergeEntry(key, val []byte) error { + e := &Entry{Key: key, Value: val, meta: bitMergeEntry} + return txn.SetEntry(e) +} + +func exceedsSize(prefix string, max int64, key []byte) error { + return errors.Errorf("%s with size %d exceeded %d limit. %s:\n%s", + prefix, len(key), max, prefix, hex.Dump(key[:1<<10])) +} + +func (txn *Txn) modify(e *Entry) error { + const maxKeySize = 65000 + + switch { + case !txn.update: + return ErrReadOnlyTxn + case txn.discarded: + return ErrDiscardedTxn + case len(e.Key) == 0: + return ErrEmptyKey + case bytes.HasPrefix(e.Key, badgerPrefix): + return ErrInvalidKey + case len(e.Key) > maxKeySize: + // Key length can't be more than uint16, as determined by table::header. To + // keep things safe and allow badger move prefix and a timestamp suffix, let's + // cut it down to 65000, instead of using 65536. + return exceedsSize("Key", maxKeySize, e.Key) + case int64(len(e.Value)) > txn.db.opt.ValueLogFileSize: + return exceedsSize("Value", txn.db.opt.ValueLogFileSize, e.Value) + } + + if err := txn.checkSize(e); err != nil { + return err + } + fp := farm.Fingerprint64(e.Key) // Avoid dealing with byte arrays. + txn.writes = append(txn.writes, fp) + txn.pendingWrites[string(e.Key)] = e + return nil +} + +// SetEntry takes an Entry struct and adds the key-value pair in the struct, +// along with other metadata to the database. +// +// The current transaction keeps a reference to the entry passed in argument. +// Users must not modify the entry until the end of the transaction. +func (txn *Txn) SetEntry(e *Entry) error { + return txn.modify(e) +} + +// Delete deletes a key. +// +// This is done by adding a delete marker for the key at commit timestamp. Any +// reads happening before this timestamp would be unaffected. Any reads after +// this commit would see the deletion. +// +// The current transaction keeps a reference to the key byte slice argument. +// Users must not modify the key until the end of the transaction. +func (txn *Txn) Delete(key []byte) error { + e := &Entry{ + Key: key, + meta: bitDelete, + } + return txn.modify(e) +} + +// Get looks for key and returns corresponding Item. +// If key is not found, ErrKeyNotFound is returned. +func (txn *Txn) Get(key []byte) (item *Item, rerr error) { + if len(key) == 0 { + return nil, ErrEmptyKey + } else if txn.discarded { + return nil, ErrDiscardedTxn + } + + item = new(Item) + if txn.update { + if e, has := txn.pendingWrites[string(key)]; has && bytes.Equal(key, e.Key) { + if isDeletedOrExpired(e.meta, e.ExpiresAt) { + return nil, ErrKeyNotFound + } + // Fulfill from cache. + item.meta = e.meta + item.val = e.Value + item.userMeta = e.UserMeta + item.key = key + item.status = prefetched + item.version = txn.readTs + item.expiresAt = e.ExpiresAt + // We probably don't need to set db on item here. + return item, nil + } + // Only track reads if this is update txn. No need to track read if txn serviced it + // internally. + txn.addReadKey(key) + } + + seek := y.KeyWithTs(key, txn.readTs) + vs, err := txn.db.get(seek) + if err != nil { + return nil, errors.Wrapf(err, "DB::Get key: %q", key) + } + if vs.Value == nil && vs.Meta == 0 { + return nil, ErrKeyNotFound + } + if isDeletedOrExpired(vs.Meta, vs.ExpiresAt) { + return nil, ErrKeyNotFound + } + + item.key = key + item.version = vs.Version + item.meta = vs.Meta + item.userMeta = vs.UserMeta + item.db = txn.db + item.vptr = vs.Value // TODO: Do we need to copy this over? + item.txn = txn + item.expiresAt = vs.ExpiresAt + return item, nil +} + +func (txn *Txn) addReadKey(key []byte) { + if txn.update { + fp := farm.Fingerprint64(key) + txn.reads = append(txn.reads, fp) + } +} + +// Discard discards a created transaction. This method is very important and must be called. Commit +// method calls this internally, however, calling this multiple times doesn't cause any issues. So, +// this can safely be called via a defer right when transaction is created. +// +// NOTE: If any operations are run on a discarded transaction, ErrDiscardedTxn is returned. +func (txn *Txn) Discard() { + if txn.discarded { // Avoid a re-run. + return + } + if atomic.LoadInt32(&txn.numIterators) > 0 { + panic("Unclosed iterator at time of Txn.Discard.") + } + txn.discarded = true + if !txn.db.orc.isManaged { + txn.db.orc.readMark.Done(txn.readTs) + } + if txn.update { + txn.db.orc.decrRef() + } +} + +func (txn *Txn) commitAndSend() (func() error, error) { + orc := txn.db.orc + // Ensure that the order in which we get the commit timestamp is the same as + // the order in which we push these updates to the write channel. So, we + // acquire a writeChLock before getting a commit timestamp, and only release + // it after pushing the entries to it. + orc.writeChLock.Lock() + defer orc.writeChLock.Unlock() + + commitTs := orc.newCommitTs(txn) + if commitTs == 0 { + return nil, ErrConflict + } + + // The following debug information is what led to determining the cause of + // bank txn violation bug, and it took a whole bunch of effort to narrow it + // down to here. So, keep this around for at least a couple of months. + // var b strings.Builder + // fmt.Fprintf(&b, "Read: %d. Commit: %d. reads: %v. writes: %v. Keys: ", + // txn.readTs, commitTs, txn.reads, txn.writes) + entries := make([]*Entry, 0, len(txn.pendingWrites)+1) + for _, e := range txn.pendingWrites { + // fmt.Fprintf(&b, "[%q : %q], ", e.Key, e.Value) + + // Suffix the keys with commit ts, so the key versions are sorted in + // descending order of commit timestamp. + e.Key = y.KeyWithTs(e.Key, commitTs) + e.meta |= bitTxn + entries = append(entries, e) + } + // log.Printf("%s\n", b.String()) + e := &Entry{ + Key: y.KeyWithTs(txnKey, commitTs), + Value: []byte(strconv.FormatUint(commitTs, 10)), + meta: bitFinTxn, + } + entries = append(entries, e) + + req, err := txn.db.sendToWriteCh(entries) + if err != nil { + orc.doneCommit(commitTs) + return nil, err + } + ret := func() error { + err := req.Wait() + // Wait before marking commitTs as done. + // We can't defer doneCommit above, because it is being called from a + // callback here. + orc.doneCommit(commitTs) + return err + } + return ret, nil +} + +func (txn *Txn) commitPrecheck() { + if txn.commitTs == 0 && txn.db.opt.managedTxns { + panic("Commit cannot be called with managedDB=true. Use CommitAt.") + } + if txn.discarded { + panic("Trying to commit a discarded txn") + } +} + +// Commit commits the transaction, following these steps: +// +// 1. If there are no writes, return immediately. +// +// 2. Check if read rows were updated since txn started. If so, return ErrConflict. +// +// 3. If no conflict, generate a commit timestamp and update written rows' commit ts. +// +// 4. Batch up all writes, write them to value log and LSM tree. +// +// 5. If callback is provided, Badger will return immediately after checking +// for conflicts. Writes to the database will happen in the background. If +// there is a conflict, an error will be returned and the callback will not +// run. If there are no conflicts, the callback will be called in the +// background upon successful completion of writes or any error during write. +// +// If error is nil, the transaction is successfully committed. In case of a non-nil error, the LSM +// tree won't be updated, so there's no need for any rollback. +func (txn *Txn) Commit() error { + txn.commitPrecheck() // Precheck before discarding txn. + defer txn.Discard() + + if len(txn.writes) == 0 { + return nil // Nothing to do. + } + + txnCb, err := txn.commitAndSend() + if err != nil { + return err + } + // If batchSet failed, LSM would not have been updated. So, no need to rollback anything. + + // TODO: What if some of the txns successfully make it to value log, but others fail. + // Nothing gets updated to LSM, until a restart happens. + return txnCb() +} + +type txnCb struct { + commit func() error + user func(error) + err error +} + +func runTxnCallback(cb *txnCb) { + switch { + case cb == nil: + panic("txn callback is nil") + case cb.user == nil: + panic("Must have caught a nil callback for txn.CommitWith") + case cb.err != nil: + cb.user(cb.err) + case cb.commit != nil: + err := cb.commit() + cb.user(err) + default: + cb.user(nil) + } +} + +// CommitWith acts like Commit, but takes a callback, which gets run via a +// goroutine to avoid blocking this function. The callback is guaranteed to run, +// so it is safe to increment sync.WaitGroup before calling CommitWith, and +// decrementing it in the callback; to block until all callbacks are run. +func (txn *Txn) CommitWith(cb func(error)) { + txn.commitPrecheck() // Precheck before discarding txn. + defer txn.Discard() + + if cb == nil { + panic("Nil callback provided to CommitWith") + } + + if len(txn.writes) == 0 { + // Do not run these callbacks from here, because the CommitWith and the + // callback might be acquiring the same locks. Instead run the callback + // from another goroutine. + go runTxnCallback(&txnCb{user: cb, err: nil}) + return + } + + commitCb, err := txn.commitAndSend() + if err != nil { + go runTxnCallback(&txnCb{user: cb, err: err}) + return + } + + go runTxnCallback(&txnCb{user: cb, commit: commitCb}) +} + +// ReadTs returns the read timestamp of the transaction. +func (txn *Txn) ReadTs() uint64 { + return txn.readTs +} + +// NewTransaction creates a new transaction. Badger supports concurrent execution of transactions, +// providing serializable snapshot isolation, avoiding write skews. Badger achieves this by tracking +// the keys read and at Commit time, ensuring that these read keys weren't concurrently modified by +// another transaction. +// +// For read-only transactions, set update to false. In this mode, we don't track the rows read for +// any changes. Thus, any long running iterations done in this mode wouldn't pay this overhead. +// +// Running transactions concurrently is OK. However, a transaction itself isn't thread safe, and +// should only be run serially. It doesn't matter if a transaction is created by one goroutine and +// passed down to other, as long as the Txn APIs are called serially. +// +// When you create a new transaction, it is absolutely essential to call +// Discard(). This should be done irrespective of what the update param is set +// to. Commit API internally runs Discard, but running it twice wouldn't cause +// any issues. +// +// txn := db.NewTransaction(false) +// defer txn.Discard() +// // Call various APIs. +func (db *DB) NewTransaction(update bool) *Txn { + return db.newTransaction(update, false) +} + +func (db *DB) newTransaction(update, isManaged bool) *Txn { + if db.opt.ReadOnly && update { + // DB is read-only, force read-only transaction. + update = false + } + + txn := &Txn{ + update: update, + db: db, + count: 1, // One extra entry for BitFin. + size: int64(len(txnKey) + 10), // Some buffer for the extra entry. + } + if update { + txn.pendingWrites = make(map[string]*Entry) + txn.db.orc.addRef() + } + // It is important that the oracle addRef happens BEFORE we retrieve a read + // timestamp. Otherwise, it is possible that the oracle commit map would + // become nil after we get the read timestamp. + // The sequence of events can be: + // 1. This txn gets a read timestamp. + // 2. Another txn working on the same keyset commits them, and decrements + // the reference to oracle. + // 3. Oracle ref reaches zero, resetting commit map. + // 4. This txn increments the oracle reference. + // 5. Now this txn would go on to commit the keyset, and no conflicts + // would be detected. + // See issue: https://github.com/dgraph-io/badger/issues/574 + if !isManaged { + txn.readTs = db.orc.readTs() + } + return txn +} + +// View executes a function creating and managing a read-only transaction for the user. Error +// returned by the function is relayed by the View method. +// If View is used with managed transactions, it would assume a read timestamp of MaxUint64. +func (db *DB) View(fn func(txn *Txn) error) error { + var txn *Txn + if db.opt.managedTxns { + txn = db.NewTransactionAt(math.MaxUint64, false) + } else { + txn = db.NewTransaction(false) + } + defer txn.Discard() + + return fn(txn) +} + +// Update executes a function, creating and managing a read-write transaction +// for the user. Error returned by the function is relayed by the Update method. +// Update cannot be used with managed transactions. +func (db *DB) Update(fn func(txn *Txn) error) error { + if db.opt.managedTxns { + panic("Update can only be used with managedDB=false.") + } + txn := db.NewTransaction(true) + defer txn.Discard() + + if err := fn(txn); err != nil { + return err + } + + return txn.Commit() +} diff --git a/vendor/github.com/dgraph-io/badger/util.go b/vendor/github.com/dgraph-io/badger/util.go new file mode 100644 index 00000000..02952a80 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/util.go @@ -0,0 +1,141 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "encoding/hex" + "io/ioutil" + "math/rand" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/table" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" +) + +// summary is produced when DB is closed. Currently it is used only for testing. +type summary struct { + fileIDs map[uint64]bool +} + +func (s *levelsController) getSummary() *summary { + out := &summary{ + fileIDs: make(map[uint64]bool), + } + for _, l := range s.levels { + l.getSummary(out) + } + return out +} + +func (s *levelHandler) getSummary(sum *summary) { + s.RLock() + defer s.RUnlock() + for _, t := range s.tables { + sum.fileIDs[t.ID()] = true + } +} + +func (s *DB) validate() error { return s.lc.validate() } + +func (s *levelsController) validate() error { + for _, l := range s.levels { + if err := l.validate(); err != nil { + return errors.Wrap(err, "Levels Controller") + } + } + return nil +} + +// Check does some sanity check on one level of data or in-memory index. +func (s *levelHandler) validate() error { + if s.level == 0 { + return nil + } + + s.RLock() + defer s.RUnlock() + numTables := len(s.tables) + for j := 1; j < numTables; j++ { + if j >= len(s.tables) { + return errors.Errorf("Level %d, j=%d numTables=%d", s.level, j, numTables) + } + + if y.CompareKeys(s.tables[j-1].Biggest(), s.tables[j].Smallest()) >= 0 { + return errors.Errorf( + "Inter: Biggest(j-1) \n%s\n vs Smallest(j): \n%s\n: level=%d j=%d numTables=%d", + hex.Dump(s.tables[j-1].Biggest()), hex.Dump(s.tables[j].Smallest()), + s.level, j, numTables) + } + + if y.CompareKeys(s.tables[j].Smallest(), s.tables[j].Biggest()) > 0 { + return errors.Errorf( + "Intra: %q vs %q: level=%d j=%d numTables=%d", + s.tables[j].Smallest(), s.tables[j].Biggest(), s.level, j, numTables) + } + } + return nil +} + +// func (s *KV) debugPrintMore() { s.lc.debugPrintMore() } + +// // debugPrintMore shows key ranges of each level. +// func (s *levelsController) debugPrintMore() { +// s.Lock() +// defer s.Unlock() +// for i := 0; i < s.kv.opt.MaxLevels; i++ { +// s.levels[i].debugPrintMore() +// } +// } + +// func (s *levelHandler) debugPrintMore() { +// s.RLock() +// defer s.RUnlock() +// s.elog.Printf("Level %d:", s.level) +// for _, t := range s.tables { +// y.Printf(" [%s, %s]", t.Smallest(), t.Biggest()) +// } +// y.Printf("\n") +// } + +// reserveFileID reserves a unique file id. +func (s *levelsController) reserveFileID() uint64 { + id := atomic.AddUint64(&s.nextFileID, 1) + return id - 1 +} + +func getIDMap(dir string) map[uint64]struct{} { + fileInfos, err := ioutil.ReadDir(dir) + y.Check(err) + idMap := make(map[uint64]struct{}) + for _, info := range fileInfos { + if info.IsDir() { + continue + } + fileID, ok := table.ParseFileID(info.Name()) + if !ok { + continue + } + idMap[fileID] = struct{}{} + } + return idMap +} + +func init() { + rand.Seed(time.Now().UnixNano()) +} diff --git a/vendor/github.com/dgraph-io/badger/value.go b/vendor/github.com/dgraph-io/badger/value.go new file mode 100644 index 00000000..77cdc185 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/value.go @@ -0,0 +1,1396 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package badger + +import ( + "bufio" + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "hash/crc32" + "io" + "io/ioutil" + "math" + "math/rand" + "os" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/dgraph-io/badger/options" + "github.com/dgraph-io/badger/y" + "github.com/pkg/errors" + "golang.org/x/net/trace" +) + +// Values have their first byte being byteData or byteDelete. This helps us distinguish between +// a key that has never been seen and a key that has been explicitly deleted. +const ( + bitDelete byte = 1 << 0 // Set if the key has been deleted. + bitValuePointer byte = 1 << 1 // Set if the value is NOT stored directly next to key. + bitDiscardEarlierVersions byte = 1 << 2 // Set if earlier versions can be discarded. + // Set if item shouldn't be discarded via compactions (used by merge operator) + bitMergeEntry byte = 1 << 3 + // The MSB 2 bits are for transactions. + bitTxn byte = 1 << 6 // Set if the entry is part of a txn. + bitFinTxn byte = 1 << 7 // Set if the entry is to indicate end of txn in value log. + + mi int64 = 1 << 20 +) + +type logFile struct { + path string + // This is a lock on the log file. It guards the fd’s value, the file’s + // existence and the file’s memory map. + // + // Use shared ownership when reading/writing the file or memory map, use + // exclusive ownership to open/close the descriptor, unmap or remove the file. + lock sync.RWMutex + fd *os.File + fid uint32 + fmap []byte + size uint32 + loadingMode options.FileLoadingMode +} + +// openReadOnly assumes that we have a write lock on logFile. +func (lf *logFile) openReadOnly() error { + var err error + lf.fd, err = os.OpenFile(lf.path, os.O_RDONLY, 0666) + if err != nil { + return errors.Wrapf(err, "Unable to open %q as RDONLY.", lf.path) + } + + fi, err := lf.fd.Stat() + if err != nil { + return errors.Wrapf(err, "Unable to check stat for %q", lf.path) + } + y.AssertTrue(fi.Size() <= math.MaxUint32) + lf.size = uint32(fi.Size()) + + if err = lf.mmap(fi.Size()); err != nil { + _ = lf.fd.Close() + return y.Wrapf(err, "Unable to map file") + } + + return nil +} + +func (lf *logFile) mmap(size int64) (err error) { + if lf.loadingMode != options.MemoryMap { + // Nothing to do + return nil + } + lf.fmap, err = y.Mmap(lf.fd, false, size) + if err == nil { + err = y.Madvise(lf.fmap, false) // Disable readahead + } + return err +} + +func (lf *logFile) munmap() (err error) { + if lf.loadingMode != options.MemoryMap { + // Nothing to do + return nil + } + if err := y.Munmap(lf.fmap); err != nil { + return errors.Wrapf(err, "Unable to munmap value log: %q", lf.path) + } + return nil +} + +// Acquire lock on mmap/file if you are calling this +func (lf *logFile) read(p valuePointer, s *y.Slice) (buf []byte, err error) { + var nbr int64 + offset := p.Offset + if lf.loadingMode == options.FileIO { + buf = s.Resize(int(p.Len)) + var n int + n, err = lf.fd.ReadAt(buf, int64(offset)) + nbr = int64(n) + } else { + // Do not convert size to uint32, because the lf.fmap can be of size + // 4GB, which overflows the uint32 during conversion to make the size 0, + // causing the read to fail with ErrEOF. See issue #585. + size := int64(len(lf.fmap)) + valsz := p.Len + if int64(offset) >= size || int64(offset+valsz) > size { + err = y.ErrEOF + } else { + buf = lf.fmap[offset : offset+valsz] + nbr = int64(valsz) + } + } + y.NumReads.Add(1) + y.NumBytesRead.Add(nbr) + return buf, err +} + +func (lf *logFile) doneWriting(offset uint32) error { + // Sync before acquiring lock. (We call this from write() and thus know we have shared access + // to the fd.) + if err := lf.fd.Sync(); err != nil { + return errors.Wrapf(err, "Unable to sync value log: %q", lf.path) + } + // Close and reopen the file read-only. Acquire lock because fd will become invalid for a bit. + // Acquiring the lock is bad because, while we don't hold the lock for a long time, it forces + // one batch of readers wait for the preceding batch of readers to finish. + // + // If there's a benefit to reopening the file read-only, it might be on Windows. I don't know + // what the benefit is. Consider keeping the file read-write, or use fcntl to change + // permissions. + lf.lock.Lock() + defer lf.lock.Unlock() + if err := lf.munmap(); err != nil { + return err + } + // TODO: Confirm if we need to run a file sync after truncation. + // Truncation must run after unmapping, otherwise Windows would crap itself. + if err := lf.fd.Truncate(int64(offset)); err != nil { + return errors.Wrapf(err, "Unable to truncate file: %q", lf.path) + } + if err := lf.fd.Close(); err != nil { + return errors.Wrapf(err, "Unable to close value log: %q", lf.path) + } + + return lf.openReadOnly() +} + +// You must hold lf.lock to sync() +func (lf *logFile) sync() error { + return lf.fd.Sync() +} + +var errStop = errors.New("Stop iteration") +var errTruncate = errors.New("Do truncate") + +type logEntry func(e Entry, vp valuePointer) error + +type safeRead struct { + k []byte + v []byte + + recordOffset uint32 +} + +func (r *safeRead) Entry(reader *bufio.Reader) (*Entry, error) { + var hbuf [headerBufSize]byte + var err error + + hash := crc32.New(y.CastagnoliCrcTable) + tee := io.TeeReader(reader, hash) + if _, err = io.ReadFull(tee, hbuf[:]); err != nil { + return nil, err + } + + var h header + h.Decode(hbuf[:]) + if h.klen > uint32(1<<16) { // Key length must be below uint16. + return nil, errTruncate + } + kl := int(h.klen) + if cap(r.k) < kl { + r.k = make([]byte, 2*kl) + } + vl := int(h.vlen) + if cap(r.v) < vl { + r.v = make([]byte, 2*vl) + } + + e := &Entry{} + e.offset = r.recordOffset + e.Key = r.k[:kl] + e.Value = r.v[:vl] + + if _, err = io.ReadFull(tee, e.Key); err != nil { + if err == io.EOF { + err = errTruncate + } + return nil, err + } + if _, err = io.ReadFull(tee, e.Value); err != nil { + if err == io.EOF { + err = errTruncate + } + return nil, err + } + var crcBuf [4]byte + if _, err = io.ReadFull(reader, crcBuf[:]); err != nil { + if err == io.EOF { + err = errTruncate + } + return nil, err + } + crc := binary.BigEndian.Uint32(crcBuf[:]) + if crc != hash.Sum32() { + return nil, errTruncate + } + e.meta = h.meta + e.UserMeta = h.userMeta + e.ExpiresAt = h.expiresAt + return e, nil +} + +// iterate iterates over log file. It doesn't not allocate new memory for every kv pair. +// Therefore, the kv pair is only valid for the duration of fn call. +func (vlog *valueLog) iterate(lf *logFile, offset uint32, fn logEntry) (uint32, error) { + fi, err := lf.fd.Stat() + if err != nil { + return 0, err + } + if int64(offset) == fi.Size() { + // We're at the end of the file already. No need to do anything. + return offset, nil + } + if vlog.opt.ReadOnly { + // We're not at the end of the file. We'd need to replay the entries, or + // possibly truncate the file. + return 0, ErrReplayNeeded + } + + // We're not at the end of the file. Let's Seek to the offset and start reading. + if _, err := lf.fd.Seek(int64(offset), io.SeekStart); err != nil { + return 0, errFile(err, lf.path, "Unable to seek") + } + + reader := bufio.NewReader(lf.fd) + read := &safeRead{ + k: make([]byte, 10), + v: make([]byte, 10), + recordOffset: offset, + } + + var lastCommit uint64 + var validEndOffset uint32 + for { + e, err := read.Entry(reader) + if err == io.EOF { + break + } else if err == io.ErrUnexpectedEOF || err == errTruncate { + break + } else if err != nil { + return 0, err + } else if e == nil { + continue + } + + var vp valuePointer + vp.Len = uint32(headerBufSize + len(e.Key) + len(e.Value) + crc32.Size) + read.recordOffset += vp.Len + + vp.Offset = e.offset + vp.Fid = lf.fid + + if e.meta&bitTxn > 0 { + txnTs := y.ParseTs(e.Key) + if lastCommit == 0 { + lastCommit = txnTs + } + if lastCommit != txnTs { + break + } + + } else if e.meta&bitFinTxn > 0 { + txnTs, err := strconv.ParseUint(string(e.Value), 10, 64) + if err != nil || lastCommit != txnTs { + break + } + // Got the end of txn. Now we can store them. + lastCommit = 0 + validEndOffset = read.recordOffset + + } else { + if lastCommit != 0 { + // This is most likely an entry which was moved as part of GC. + // We shouldn't get this entry in the middle of a transaction. + break + } + validEndOffset = read.recordOffset + } + + if err := fn(*e, vp); err != nil { + if err == errStop { + break + } + return 0, errFile(err, lf.path, "Iteration function") + } + } + return validEndOffset, nil +} + +func (vlog *valueLog) rewrite(f *logFile, tr trace.Trace) error { + maxFid := atomic.LoadUint32(&vlog.maxFid) + y.AssertTruef(uint32(f.fid) < maxFid, "fid to move: %d. Current max fid: %d", f.fid, maxFid) + tr.LazyPrintf("Rewriting fid: %d", f.fid) + + wb := make([]*Entry, 0, 1000) + var size int64 + + y.AssertTrue(vlog.db != nil) + var count, moved int + fe := func(e Entry) error { + count++ + if count%100000 == 0 { + tr.LazyPrintf("Processing entry %d", count) + } + + vs, err := vlog.db.get(e.Key) + if err != nil { + return err + } + if discardEntry(e, vs) { + return nil + } + + // Value is still present in value log. + if len(vs.Value) == 0 { + return errors.Errorf("Empty value: %+v", vs) + } + var vp valuePointer + vp.Decode(vs.Value) + + if vp.Fid > f.fid { + return nil + } + if vp.Offset > e.offset { + return nil + } + if vp.Fid == f.fid && vp.Offset == e.offset { + moved++ + // This new entry only contains the key, and a pointer to the value. + ne := new(Entry) + ne.meta = 0 // Remove all bits. Different keyspace doesn't need these bits. + ne.UserMeta = e.UserMeta + + // Create a new key in a separate keyspace, prefixed by moveKey. We are not + // allowed to rewrite an older version of key in the LSM tree, because then this older + // version would be at the top of the LSM tree. To work correctly, reads expect the + // latest versions to be at the top, and the older versions at the bottom. + if bytes.HasPrefix(e.Key, badgerMove) { + ne.Key = append([]byte{}, e.Key...) + } else { + ne.Key = make([]byte, len(badgerMove)+len(e.Key)) + n := copy(ne.Key, badgerMove) + copy(ne.Key[n:], e.Key) + } + + ne.Value = append([]byte{}, e.Value...) + wb = append(wb, ne) + size += int64(e.estimateSize(vlog.opt.ValueThreshold)) + if size >= 64*mi { + tr.LazyPrintf("request has %d entries, size %d", len(wb), size) + if err := vlog.db.batchSet(wb); err != nil { + return err + } + size = 0 + wb = wb[:0] + } + } else { + vlog.db.opt.Warningf("This entry should have been caught. %+v\n", e) + } + return nil + } + + _, err := vlog.iterate(f, 0, func(e Entry, vp valuePointer) error { + return fe(e) + }) + if err != nil { + return err + } + + tr.LazyPrintf("request has %d entries, size %d", len(wb), size) + batchSize := 1024 + var loops int + for i := 0; i < len(wb); { + loops++ + if batchSize == 0 { + vlog.db.opt.Warningf("We shouldn't reach batch size of zero.") + return ErrNoRewrite + } + end := i + batchSize + if end > len(wb) { + end = len(wb) + } + if err := vlog.db.batchSet(wb[i:end]); err != nil { + if err == ErrTxnTooBig { + // Decrease the batch size to half. + batchSize = batchSize / 2 + tr.LazyPrintf("Dropped batch size to %d", batchSize) + continue + } + return err + } + i += batchSize + } + tr.LazyPrintf("Processed %d entries in %d loops", len(wb), loops) + tr.LazyPrintf("Total entries: %d. Moved: %d", count, moved) + tr.LazyPrintf("Removing fid: %d", f.fid) + var deleteFileNow bool + // Entries written to LSM. Remove the older file now. + { + vlog.filesLock.Lock() + // Just a sanity-check. + if _, ok := vlog.filesMap[f.fid]; !ok { + vlog.filesLock.Unlock() + return errors.Errorf("Unable to find fid: %d", f.fid) + } + if vlog.iteratorCount() == 0 { + delete(vlog.filesMap, f.fid) + deleteFileNow = true + } else { + vlog.filesToBeDeleted = append(vlog.filesToBeDeleted, f.fid) + } + vlog.filesLock.Unlock() + } + + if deleteFileNow { + vlog.deleteLogFile(f) + } + + return nil +} + +func (vlog *valueLog) deleteMoveKeysFor(fid uint32, tr trace.Trace) error { + db := vlog.db + var result []*Entry + var count, pointers uint64 + tr.LazyPrintf("Iterating over move keys to find invalids for fid: %d", fid) + err := db.View(func(txn *Txn) error { + opt := DefaultIteratorOptions + opt.internalAccess = true + opt.PrefetchValues = false + itr := txn.NewIterator(opt) + defer itr.Close() + + for itr.Seek(badgerMove); itr.ValidForPrefix(badgerMove); itr.Next() { + count++ + item := itr.Item() + if item.meta&bitValuePointer == 0 { + continue + } + pointers++ + var vp valuePointer + vp.Decode(item.vptr) + if vp.Fid == fid { + e := &Entry{Key: y.KeyWithTs(item.Key(), item.Version()), meta: bitDelete} + result = append(result, e) + } + } + return nil + }) + if err != nil { + tr.LazyPrintf("Got error while iterating move keys: %v", err) + tr.SetError() + return err + } + tr.LazyPrintf("Num total move keys: %d. Num pointers: %d", count, pointers) + tr.LazyPrintf("Number of invalid move keys found: %d", len(result)) + batchSize := 10240 + for i := 0; i < len(result); { + end := i + batchSize + if end > len(result) { + end = len(result) + } + if err := db.batchSet(result[i:end]); err != nil { + if err == ErrTxnTooBig { + batchSize /= 2 + tr.LazyPrintf("Dropped batch size to %d", batchSize) + continue + } + tr.LazyPrintf("Error while doing batchSet: %v", err) + tr.SetError() + return err + } + i += batchSize + } + tr.LazyPrintf("Move keys deletion done.") + return nil +} + +func (vlog *valueLog) incrIteratorCount() { + atomic.AddInt32(&vlog.numActiveIterators, 1) +} + +func (vlog *valueLog) iteratorCount() int { + return int(atomic.LoadInt32(&vlog.numActiveIterators)) +} + +func (vlog *valueLog) decrIteratorCount() error { + num := atomic.AddInt32(&vlog.numActiveIterators, -1) + if num != 0 { + return nil + } + + vlog.filesLock.Lock() + lfs := make([]*logFile, 0, len(vlog.filesToBeDeleted)) + for _, id := range vlog.filesToBeDeleted { + lfs = append(lfs, vlog.filesMap[id]) + delete(vlog.filesMap, id) + } + vlog.filesToBeDeleted = nil + vlog.filesLock.Unlock() + + for _, lf := range lfs { + if err := vlog.deleteLogFile(lf); err != nil { + return err + } + } + return nil +} + +func (vlog *valueLog) deleteLogFile(lf *logFile) error { + if lf == nil { + return nil + } + path := vlog.fpath(lf.fid) + if err := lf.munmap(); err != nil { + _ = lf.fd.Close() + return err + } + if err := lf.fd.Close(); err != nil { + return err + } + return os.Remove(path) +} + +func (vlog *valueLog) dropAll() (int, error) { + // We don't want to block dropAll on any pending transactions. So, don't worry about iterator + // count. + var count int + deleteAll := func() error { + vlog.filesLock.Lock() + defer vlog.filesLock.Unlock() + for _, lf := range vlog.filesMap { + if err := vlog.deleteLogFile(lf); err != nil { + return err + } + count++ + } + vlog.filesMap = make(map[uint32]*logFile) + return nil + } + if err := deleteAll(); err != nil { + return count, err + } + + vlog.db.opt.Infof("Value logs deleted. Creating value log file: 0") + if _, err := vlog.createVlogFile(0); err != nil { + return count, err + } + atomic.StoreUint32(&vlog.maxFid, 0) + return count, nil +} + +// lfDiscardStats keeps track of the amount of data that could be discarded for +// a given logfile. +type lfDiscardStats struct { + sync.Mutex + m map[uint32]int64 +} + +type valueLog struct { + dirPath string + elog trace.EventLog + + // guards our view of which files exist, which to be deleted, how many active iterators + filesLock sync.RWMutex + filesMap map[uint32]*logFile + filesToBeDeleted []uint32 + // A refcount of iterators -- when this hits zero, we can delete the filesToBeDeleted. + numActiveIterators int32 + + db *DB + maxFid uint32 // accessed via atomics. + writableLogOffset uint32 // read by read, written by write. Must access via atomics. + numEntriesWritten uint32 + opt Options + + garbageCh chan struct{} + lfDiscardStats *lfDiscardStats +} + +func vlogFilePath(dirPath string, fid uint32) string { + return fmt.Sprintf("%s%s%06d.vlog", dirPath, string(os.PathSeparator), fid) +} + +func (vlog *valueLog) fpath(fid uint32) string { + return vlogFilePath(vlog.dirPath, fid) +} + +func (vlog *valueLog) populateFilesMap() error { + vlog.filesMap = make(map[uint32]*logFile) + + files, err := ioutil.ReadDir(vlog.dirPath) + if err != nil { + return errFile(err, vlog.dirPath, "Unable to open log dir.") + } + + found := make(map[uint64]struct{}) + for _, file := range files { + if !strings.HasSuffix(file.Name(), ".vlog") { + continue + } + fsz := len(file.Name()) + fid, err := strconv.ParseUint(file.Name()[:fsz-5], 10, 32) + if err != nil { + return errFile(err, file.Name(), "Unable to parse log id.") + } + if _, ok := found[fid]; ok { + return errFile(err, file.Name(), "Duplicate file found. Please delete one.") + } + found[fid] = struct{}{} + + lf := &logFile{ + fid: uint32(fid), + path: vlog.fpath(uint32(fid)), + loadingMode: vlog.opt.ValueLogLoadingMode, + } + vlog.filesMap[uint32(fid)] = lf + if vlog.maxFid < uint32(fid) { + vlog.maxFid = uint32(fid) + } + } + return nil +} + +func (vlog *valueLog) createVlogFile(fid uint32) (*logFile, error) { + path := vlog.fpath(fid) + lf := &logFile{ + fid: fid, + path: path, + loadingMode: vlog.opt.ValueLogLoadingMode, + } + // writableLogOffset is only written by write func, by read by Read func. + // To avoid a race condition, all reads and updates to this variable must be + // done via atomics. + atomic.StoreUint32(&vlog.writableLogOffset, 0) + vlog.numEntriesWritten = 0 + + var err error + if lf.fd, err = y.CreateSyncedFile(path, vlog.opt.SyncWrites); err != nil { + return nil, errFile(err, lf.path, "Create value log file") + } + if err = syncDir(vlog.dirPath); err != nil { + return nil, errFile(err, vlog.dirPath, "Sync value log dir") + } + if err = lf.mmap(2 * vlog.opt.ValueLogFileSize); err != nil { + return nil, errFile(err, lf.path, "Mmap value log file") + } + + vlog.filesLock.Lock() + vlog.filesMap[fid] = lf + vlog.filesLock.Unlock() + + return lf, nil +} + +func errFile(err error, path string, msg string) error { + return fmt.Errorf("%s. Path=%s. Error=%v", msg, path, err) +} + +func (vlog *valueLog) replayLog(lf *logFile, offset uint32, replayFn logEntry) error { + var err error + mode := os.O_RDONLY + if vlog.opt.Truncate { + // We should open the file in RW mode, so it can be truncated. + mode = os.O_RDWR + } + lf.fd, err = os.OpenFile(lf.path, mode, 0) + if err != nil { + return errFile(err, lf.path, "Open file") + } + defer lf.fd.Close() + + fi, err := lf.fd.Stat() + if err != nil { + return errFile(err, lf.path, "Unable to run file.Stat") + } + + // Alright, let's iterate now. + endOffset, err := vlog.iterate(lf, offset, replayFn) + if err != nil { + return errFile(err, lf.path, "Unable to replay logfile") + } + if int64(endOffset) == fi.Size() { + return nil + } + + // End offset is different from file size. So, we should truncate the file + // to that size. + y.AssertTrue(int64(endOffset) <= fi.Size()) + if !vlog.opt.Truncate { + return ErrTruncateNeeded + } + + if err := lf.fd.Truncate(int64(endOffset)); err != nil { + return errFile(err, lf.path, fmt.Sprintf( + "Truncation needed at offset %d. Can be done manually as well.", endOffset)) + } + return nil +} + +func (vlog *valueLog) open(db *DB, ptr valuePointer, replayFn logEntry) error { + opt := db.opt + vlog.opt = opt + vlog.dirPath = opt.ValueDir + vlog.db = db + vlog.elog = trace.NewEventLog("Badger", "Valuelog") + vlog.garbageCh = make(chan struct{}, 1) // Only allow one GC at a time. + + if err := vlog.populateDiscardStats(); err != nil { + return err + } + + if err := vlog.populateFilesMap(); err != nil { + return err + } + // If no files are found, then create a new file. + if len(vlog.filesMap) == 0 { + _, err := vlog.createVlogFile(0) + return err + } + + fids := vlog.sortedFids() + for _, fid := range fids { + lf, ok := vlog.filesMap[fid] + y.AssertTrue(ok) + + // This file is before the value head pointer. So, we don't need to + // replay it, and can just open it in readonly mode. + if fid < ptr.Fid { + if err := lf.openReadOnly(); err != nil { + return err + } + continue + } + + var offset uint32 + if fid == ptr.Fid { + offset = ptr.Offset + ptr.Len + } + vlog.db.opt.Infof("Replaying file id: %d at offset: %d\n", fid, offset) + now := time.Now() + // Replay and possible truncation done. Now we can open the file as per + // user specified options. + if err := vlog.replayLog(lf, offset, replayFn); err != nil { + return err + } + vlog.db.opt.Infof("Replay took: %s\n", time.Since(now)) + + if fid < vlog.maxFid { + if err := lf.openReadOnly(); err != nil { + return err + } + } else { + var flags uint32 + switch { + case vlog.opt.ReadOnly: + // If we have read only, we don't need SyncWrites. + flags |= y.ReadOnly + case vlog.opt.SyncWrites: + flags |= y.Sync + } + var err error + if lf.fd, err = y.OpenExistingFile(vlog.fpath(fid), flags); err != nil { + return errFile(err, lf.path, "Open existing file") + } + } + } + + // Seek to the end to start writing. + last, ok := vlog.filesMap[vlog.maxFid] + y.AssertTrue(ok) + lastOffset, err := last.fd.Seek(0, io.SeekEnd) + if err != nil { + return errFile(err, last.path, "file.Seek to end") + } + vlog.writableLogOffset = uint32(lastOffset) + + // Update the head to point to the updated tail. Otherwise, even after doing a successful + // replay and closing the DB, the value log head does not get updated, which causes the replay + // to happen repeatedly. + vlog.db.vhead = valuePointer{Fid: vlog.maxFid, Offset: uint32(lastOffset)} + + // Map the file if needed. When we create a file, it is automatically mapped. + if err = last.mmap(2 * opt.ValueLogFileSize); err != nil { + return errFile(err, last.path, "Map log file") + } + return nil +} + +func (vlog *valueLog) Close() error { + vlog.elog.Printf("Stopping garbage collection of values.") + defer vlog.elog.Finish() + + var err error + for id, f := range vlog.filesMap { + f.lock.Lock() // We won’t release the lock. + if munmapErr := f.munmap(); munmapErr != nil && err == nil { + err = munmapErr + } + + maxFid := atomic.LoadUint32(&vlog.maxFid) + if !vlog.opt.ReadOnly && id == maxFid { + // truncate writable log file to correct offset. + if truncErr := f.fd.Truncate( + int64(vlog.woffset())); truncErr != nil && err == nil { + err = truncErr + } + } + + if closeErr := f.fd.Close(); closeErr != nil && err == nil { + err = closeErr + } + } + return err +} + +// sortedFids returns the file id's not pending deletion, sorted. Assumes we have shared access to +// filesMap. +func (vlog *valueLog) sortedFids() []uint32 { + toBeDeleted := make(map[uint32]struct{}) + for _, fid := range vlog.filesToBeDeleted { + toBeDeleted[fid] = struct{}{} + } + ret := make([]uint32, 0, len(vlog.filesMap)) + for fid := range vlog.filesMap { + if _, ok := toBeDeleted[fid]; !ok { + ret = append(ret, fid) + } + } + sort.Slice(ret, func(i, j int) bool { + return ret[i] < ret[j] + }) + return ret +} + +type request struct { + // Input values + Entries []*Entry + // Output values and wait group stuff below + Ptrs []valuePointer + Wg sync.WaitGroup + Err error + ref int32 +} + +func (req *request) IncrRef() { + atomic.AddInt32(&req.ref, 1) +} + +func (req *request) DecrRef() { + nRef := atomic.AddInt32(&req.ref, -1) + if nRef > 0 { + return + } + req.Entries = nil + requestPool.Put(req) +} + +func (req *request) Wait() error { + req.Wg.Wait() + err := req.Err + req.DecrRef() // DecrRef after writing to DB. + return err +} + +type requests []*request + +func (reqs requests) DecrRef() { + for _, req := range reqs { + req.DecrRef() + } +} + +// sync function syncs content of latest value log file to disk. Syncing of value log directory is +// not required here as it happens every time a value log file rotation happens(check createVlogFile +// function). During rotation, previous value log file also gets synced to disk. It only syncs file +// if fid >= vlog.maxFid. In some cases such as replay(while openning db), it might be called with +// fid < vlog.maxFid. To sync irrespective of file id just call it with math.MaxUint32. +func (vlog *valueLog) sync(fid uint32) error { + if vlog.opt.SyncWrites { + return nil + } + + vlog.filesLock.RLock() + maxFid := atomic.LoadUint32(&vlog.maxFid) + // During replay it is possible to get sync call with fid less than maxFid. + // Because older file has already been synced, we can return from here. + if fid < maxFid || len(vlog.filesMap) == 0 { + vlog.filesLock.RUnlock() + return nil + } + curlf := vlog.filesMap[maxFid] + // Sometimes it is possible that vlog.maxFid has been increased but file creation + // with same id is still in progress and this function is called. In those cases + // entry for the file might not be present in vlog.filesMap. + if curlf == nil { + vlog.filesLock.RUnlock() + return nil + } + curlf.lock.RLock() + vlog.filesLock.RUnlock() + + err := curlf.sync() + curlf.lock.RUnlock() + return err +} + +func (vlog *valueLog) woffset() uint32 { + return atomic.LoadUint32(&vlog.writableLogOffset) +} + +// write is thread-unsafe by design and should not be called concurrently. +func (vlog *valueLog) write(reqs []*request) error { + vlog.filesLock.RLock() + maxFid := atomic.LoadUint32(&vlog.maxFid) + curlf := vlog.filesMap[maxFid] + vlog.filesLock.RUnlock() + + var buf bytes.Buffer + toDisk := func() error { + if buf.Len() == 0 { + return nil + } + vlog.elog.Printf("Flushing %d blocks of total size: %d", len(reqs), buf.Len()) + n, err := curlf.fd.Write(buf.Bytes()) + if err != nil { + return errors.Wrapf(err, "Unable to write to value log file: %q", curlf.path) + } + buf.Reset() + y.NumWrites.Add(1) + y.NumBytesWritten.Add(int64(n)) + vlog.elog.Printf("Done") + atomic.AddUint32(&vlog.writableLogOffset, uint32(n)) + + if vlog.woffset() > uint32(vlog.opt.ValueLogFileSize) || + vlog.numEntriesWritten > vlog.opt.ValueLogMaxEntries { + var err error + if err = curlf.doneWriting(vlog.woffset()); err != nil { + return err + } + + newid := atomic.AddUint32(&vlog.maxFid, 1) + y.AssertTruef(newid > 0, "newid has overflown uint32: %v", newid) + newlf, err := vlog.createVlogFile(newid) + if err != nil { + return err + } + curlf = newlf + atomic.AddInt32(&vlog.db.logRotates, 1) + } + return nil + } + + for i := range reqs { + b := reqs[i] + b.Ptrs = b.Ptrs[:0] + var written int + for j := range b.Entries { + e := b.Entries[j] + if e.skipVlog { + b.Ptrs = append(b.Ptrs, valuePointer{}) + continue + } + var p valuePointer + + p.Fid = curlf.fid + // Use the offset including buffer length so far. + p.Offset = vlog.woffset() + uint32(buf.Len()) + plen, err := encodeEntry(e, &buf) // Now encode the entry into buffer. + if err != nil { + return err + } + p.Len = uint32(plen) + b.Ptrs = append(b.Ptrs, p) + written++ + } + vlog.numEntriesWritten += uint32(written) + // We write to disk here so that all entries that are part of the same transaction are + // written to the same vlog file. + writeNow := + vlog.woffset()+uint32(buf.Len()) > uint32(vlog.opt.ValueLogFileSize) || + vlog.numEntriesWritten > uint32(vlog.opt.ValueLogMaxEntries) + if writeNow { + if err := toDisk(); err != nil { + return err + } + } + } + return toDisk() +} + +// Gets the logFile and acquires and RLock() for the mmap. You must call RUnlock on the file +// (if non-nil) +func (vlog *valueLog) getFileRLocked(fid uint32) (*logFile, error) { + vlog.filesLock.RLock() + defer vlog.filesLock.RUnlock() + ret, ok := vlog.filesMap[fid] + if !ok { + // log file has gone away, will need to retry the operation. + return nil, ErrRetry + } + ret.lock.RLock() + return ret, nil +} + +// Read reads the value log at a given location. +// TODO: Make this read private. +func (vlog *valueLog) Read(vp valuePointer, s *y.Slice) ([]byte, func(), error) { + // Check for valid offset if we are reading to writable log. + maxFid := atomic.LoadUint32(&vlog.maxFid) + if vp.Fid == maxFid && vp.Offset >= vlog.woffset() { + return nil, nil, errors.Errorf( + "Invalid value pointer offset: %d greater than current offset: %d", + vp.Offset, vlog.woffset()) + } + + buf, cb, err := vlog.readValueBytes(vp, s) + if err != nil { + return nil, cb, err + } + var h header + h.Decode(buf) + n := uint32(headerBufSize) + h.klen + return buf[n : n+h.vlen], cb, nil +} + +func (vlog *valueLog) readValueBytes(vp valuePointer, s *y.Slice) ([]byte, func(), error) { + lf, err := vlog.getFileRLocked(vp.Fid) + if err != nil { + return nil, nil, err + } + + buf, err := lf.read(vp, s) + if vlog.opt.ValueLogLoadingMode == options.MemoryMap { + return buf, lf.lock.RUnlock, err + } + // If we are using File I/O we unlock the file immediately + // and return an empty function as callback. + lf.lock.RUnlock() + return buf, nil, err +} + +// Test helper +func valueBytesToEntry(buf []byte) (e Entry) { + var h header + h.Decode(buf) + n := uint32(headerBufSize) + + e.Key = buf[n : n+h.klen] + n += h.klen + e.meta = h.meta + e.UserMeta = h.userMeta + e.Value = buf[n : n+h.vlen] + return +} + +func (vlog *valueLog) pickLog(head valuePointer, tr trace.Trace) (files []*logFile) { + vlog.filesLock.RLock() + defer vlog.filesLock.RUnlock() + fids := vlog.sortedFids() + if len(fids) <= 1 { + tr.LazyPrintf("Only one or less value log file.") + return nil + } else if head.Fid == 0 { + tr.LazyPrintf("Head pointer is at zero.") + return nil + } + + // Pick a candidate that contains the largest amount of discardable data + candidate := struct { + fid uint32 + discard int64 + }{math.MaxUint32, 0} + vlog.lfDiscardStats.Lock() + for _, fid := range fids { + if fid >= head.Fid { + break + } + if vlog.lfDiscardStats.m[fid] > candidate.discard { + candidate.fid = fid + candidate.discard = vlog.lfDiscardStats.m[fid] + } + } + vlog.lfDiscardStats.Unlock() + + if candidate.fid != math.MaxUint32 { // Found a candidate + tr.LazyPrintf("Found candidate via discard stats: %v", candidate) + files = append(files, vlog.filesMap[candidate.fid]) + } else { + tr.LazyPrintf("Could not find candidate via discard stats. Randomly picking one.") + } + + // Fallback to randomly picking a log file + var idxHead int + for i, fid := range fids { + if fid == head.Fid { + idxHead = i + break + } + } + if idxHead == 0 { // Not found or first file + tr.LazyPrintf("Could not find any file.") + return nil + } + idx := rand.Intn(idxHead) // Don’t include head.Fid. We pick a random file before it. + if idx > 0 { + idx = rand.Intn(idx + 1) // Another level of rand to favor smaller fids. + } + tr.LazyPrintf("Randomly chose fid: %d", fids[idx]) + files = append(files, vlog.filesMap[fids[idx]]) + return files +} + +func discardEntry(e Entry, vs y.ValueStruct) bool { + if vs.Version != y.ParseTs(e.Key) { + // Version not found. Discard. + return true + } + if isDeletedOrExpired(vs.Meta, vs.ExpiresAt) { + return true + } + if (vs.Meta & bitValuePointer) == 0 { + // Key also stores the value in LSM. Discard. + return true + } + if (vs.Meta & bitFinTxn) > 0 { + // Just a txn finish entry. Discard. + return true + } + return false +} + +func (vlog *valueLog) doRunGC(lf *logFile, discardRatio float64, tr trace.Trace) (err error) { + // Update stats before exiting + defer func() { + if err == nil { + vlog.lfDiscardStats.Lock() + delete(vlog.lfDiscardStats.m, lf.fid) + vlog.lfDiscardStats.Unlock() + } + }() + + type reason struct { + total float64 + discard float64 + count int + } + + fi, err := lf.fd.Stat() + if err != nil { + tr.LazyPrintf("Error while finding file size: %v", err) + tr.SetError() + return err + } + + // Set up the sampling window sizes. + sizeWindow := float64(fi.Size()) * 0.1 // 10% of the file as window. + sizeWindowM := sizeWindow / (1 << 20) // in MBs. + countWindow := int(float64(vlog.opt.ValueLogMaxEntries) * 0.01) // 1% of num entries. + tr.LazyPrintf("Size window: %5.2f. Count window: %d.", sizeWindow, countWindow) + + // Pick a random start point for the log. + skipFirstM := float64(rand.Int63n(fi.Size())) // Pick a random starting location. + skipFirstM -= sizeWindow // Avoid hitting EOF by moving back by window. + skipFirstM /= float64(mi) // Convert to MBs. + tr.LazyPrintf("Skip first %5.2f MB of file of size: %d MB", skipFirstM, fi.Size()/mi) + var skipped float64 + + var r reason + start := time.Now() + y.AssertTrue(vlog.db != nil) + s := new(y.Slice) + var numIterations int + _, err = vlog.iterate(lf, 0, func(e Entry, vp valuePointer) error { + numIterations++ + esz := float64(vp.Len) / (1 << 20) // in MBs. + if skipped < skipFirstM { + skipped += esz + return nil + } + + // Sample until we reach the window sizes or exceed 10 seconds. + if r.count > countWindow { + tr.LazyPrintf("Stopping sampling after %d entries.", countWindow) + return errStop + } + if r.total > sizeWindowM { + tr.LazyPrintf("Stopping sampling after reaching window size.") + return errStop + } + if time.Since(start) > 10*time.Second { + tr.LazyPrintf("Stopping sampling after 10 seconds.") + return errStop + } + r.total += esz + r.count++ + + vs, err := vlog.db.get(e.Key) + if err != nil { + return err + } + if discardEntry(e, vs) { + r.discard += esz + return nil + } + + // Value is still present in value log. + y.AssertTrue(len(vs.Value) > 0) + vp.Decode(vs.Value) + + if vp.Fid > lf.fid { + // Value is present in a later log. Discard. + r.discard += esz + return nil + } + if vp.Offset > e.offset { + // Value is present in a later offset, but in the same log. + r.discard += esz + return nil + } + if vp.Fid == lf.fid && vp.Offset == e.offset { + // This is still the active entry. This would need to be rewritten. + + } else { + vlog.elog.Printf("Reason=%+v\n", r) + + buf, cb, err := vlog.readValueBytes(vp, s) + if err != nil { + return errStop + } + ne := valueBytesToEntry(buf) + ne.offset = vp.Offset + ne.print("Latest Entry Header in LSM") + e.print("Latest Entry in Log") + runCallback(cb) + return errors.Errorf("This shouldn't happen. Latest Pointer:%+v. Meta:%v.", + vp, vs.Meta) + } + return nil + }) + + if err != nil { + tr.LazyPrintf("Error while iterating for RunGC: %v", err) + tr.SetError() + return err + } + tr.LazyPrintf("Fid: %d. Skipped: %5.2fMB Num iterations: %d. Data status=%+v\n", + lf.fid, skipped, numIterations, r) + + // If we couldn't sample at least a 1000 KV pairs or at least 75% of the window size, + // and what we can discard is below the threshold, we should skip the rewrite. + if (r.count < countWindow && r.total < sizeWindowM*0.75) || r.discard < discardRatio*r.total { + tr.LazyPrintf("Skipping GC on fid: %d", lf.fid) + return ErrNoRewrite + } + if err = vlog.rewrite(lf, tr); err != nil { + return err + } + tr.LazyPrintf("Done rewriting.") + return nil +} + +func (vlog *valueLog) waitOnGC(lc *y.Closer) { + defer lc.Done() + + <-lc.HasBeenClosed() // Wait for lc to be closed. + + // Block any GC in progress to finish, and don't allow any more writes to runGC by filling up + // the channel of size 1. + vlog.garbageCh <- struct{}{} +} + +func (vlog *valueLog) runGC(discardRatio float64, head valuePointer) error { + select { + case vlog.garbageCh <- struct{}{}: + // Pick a log file for GC. + tr := trace.New("Badger.ValueLog", "GC") + tr.SetMaxEvents(100) + defer func() { + tr.Finish() + <-vlog.garbageCh + }() + + var err error + files := vlog.pickLog(head, tr) + if len(files) == 0 { + tr.LazyPrintf("PickLog returned zero results.") + return ErrNoRewrite + } + tried := make(map[uint32]bool) + for _, lf := range files { + if _, done := tried[lf.fid]; done { + continue + } + tried[lf.fid] = true + err = vlog.doRunGC(lf, discardRatio, tr) + if err == nil { + return vlog.deleteMoveKeysFor(lf.fid, tr) + } + } + return err + default: + return ErrRejected + } +} + +func (vlog *valueLog) updateDiscardStats(stats map[uint32]int64) { + vlog.lfDiscardStats.Lock() + for fid, sz := range stats { + vlog.lfDiscardStats.m[fid] += sz + } + vlog.lfDiscardStats.Unlock() +} + +// encodedDiscardStats returns []byte representation of lfDiscardStats +// This will be called while storing stats in BadgerDB +func (vlog *valueLog) encodedDiscardStats() []byte { + vlog.lfDiscardStats.Lock() + defer vlog.lfDiscardStats.Unlock() + + encodedStats, _ := json.Marshal(vlog.lfDiscardStats.m) + return encodedStats +} + +// populateDiscardStats populates vlog.lfDiscardStats +// This function will be called while initializing valueLog +func (vlog *valueLog) populateDiscardStats() error { + discardStatsKey := y.KeyWithTs(lfDiscardStatsKey, math.MaxUint64) + vs, err := vlog.db.get(discardStatsKey) + if err != nil { + return err + } + + // check if value is Empty + if vs.Value == nil || len(vs.Value) == 0 { + vlog.lfDiscardStats = &lfDiscardStats{m: make(map[uint32]int64)} + return nil + } + + var statsMap map[uint32]int64 + if err := json.Unmarshal(vs.Value, &statsMap); err != nil { + return err + } + vlog.opt.Debugf("Value Log Discard stats: %v", statsMap) + vlog.lfDiscardStats = &lfDiscardStats{m: statsMap} + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/y/error.go b/vendor/github.com/dgraph-io/badger/y/error.go new file mode 100644 index 00000000..59bb2835 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/error.go @@ -0,0 +1,83 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +// This file contains some functions for error handling. Note that we are moving +// towards using x.Trace, i.e., rpc tracing using net/tracer. But for now, these +// functions are useful for simple checks logged on one machine. +// Some common use cases are: +// (1) You receive an error from external lib, and would like to check/log fatal. +// For this, use x.Check, x.Checkf. These will check for err != nil, which is +// more common in Go. If you want to check for boolean being true, use +// x.Assert, x.Assertf. +// (2) You receive an error from external lib, and would like to pass on with some +// stack trace information. In this case, use x.Wrap or x.Wrapf. +// (3) You want to generate a new error with stack trace info. Use x.Errorf. + +import ( + "fmt" + "log" + + "github.com/pkg/errors" +) + +var debugMode = true + +// Check logs fatal if err != nil. +func Check(err error) { + if err != nil { + log.Fatalf("%+v", Wrap(err)) + } +} + +// Check2 acts as convenience wrapper around Check, using the 2nd argument as error. +func Check2(_ interface{}, err error) { + Check(err) +} + +// AssertTrue asserts that b is true. Otherwise, it would log fatal. +func AssertTrue(b bool) { + if !b { + log.Fatalf("%+v", errors.Errorf("Assert failed")) + } +} + +// AssertTruef is AssertTrue with extra info. +func AssertTruef(b bool, format string, args ...interface{}) { + if !b { + log.Fatalf("%+v", errors.Errorf(format, args...)) + } +} + +// Wrap wraps errors from external lib. +func Wrap(err error) error { + if !debugMode { + return err + } + return errors.Wrap(err, "") +} + +// Wrapf is Wrap with extra info. +func Wrapf(err error, format string, args ...interface{}) error { + if !debugMode { + if err == nil { + return nil + } + return fmt.Errorf(format+" error: %+v", append(args, err)...) + } + return errors.Wrapf(err, format, args...) +} diff --git a/vendor/github.com/dgraph-io/badger/y/file_dsync.go b/vendor/github.com/dgraph-io/badger/y/file_dsync.go new file mode 100644 index 00000000..3f3445e2 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/file_dsync.go @@ -0,0 +1,25 @@ +// +build !dragonfly,!freebsd,!windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import "golang.org/x/sys/unix" + +func init() { + datasyncFileFlag = unix.O_DSYNC +} diff --git a/vendor/github.com/dgraph-io/badger/y/file_nodsync.go b/vendor/github.com/dgraph-io/badger/y/file_nodsync.go new file mode 100644 index 00000000..b68be7ab --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/file_nodsync.go @@ -0,0 +1,25 @@ +// +build dragonfly freebsd windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import "syscall" + +func init() { + datasyncFileFlag = syscall.O_SYNC +} diff --git a/vendor/github.com/dgraph-io/badger/y/iterator.go b/vendor/github.com/dgraph-io/badger/y/iterator.go new file mode 100644 index 00000000..719e8ec8 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/iterator.go @@ -0,0 +1,264 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import ( + "bytes" + "container/heap" + "encoding/binary" + + "github.com/pkg/errors" +) + +// ValueStruct represents the value info that can be associated with a key, but also the internal +// Meta field. +type ValueStruct struct { + Meta byte + UserMeta byte + ExpiresAt uint64 + Value []byte + + Version uint64 // This field is not serialized. Only for internal usage. +} + +func sizeVarint(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} + +// EncodedSize is the size of the ValueStruct when encoded +func (v *ValueStruct) EncodedSize() uint16 { + sz := len(v.Value) + 2 // meta, usermeta. + if v.ExpiresAt == 0 { + return uint16(sz + 1) + } + + enc := sizeVarint(v.ExpiresAt) + return uint16(sz + enc) +} + +// Decode uses the length of the slice to infer the length of the Value field. +func (v *ValueStruct) Decode(b []byte) { + v.Meta = b[0] + v.UserMeta = b[1] + var sz int + v.ExpiresAt, sz = binary.Uvarint(b[2:]) + v.Value = b[2+sz:] +} + +// Encode expects a slice of length at least v.EncodedSize(). +func (v *ValueStruct) Encode(b []byte) { + b[0] = v.Meta + b[1] = v.UserMeta + sz := binary.PutUvarint(b[2:], v.ExpiresAt) + copy(b[2+sz:], v.Value) +} + +// EncodeTo should be kept in sync with the Encode function above. The reason +// this function exists is to avoid creating byte arrays per key-value pair in +// table/builder.go. +func (v *ValueStruct) EncodeTo(buf *bytes.Buffer) { + buf.WriteByte(v.Meta) + buf.WriteByte(v.UserMeta) + var enc [binary.MaxVarintLen64]byte + sz := binary.PutUvarint(enc[:], v.ExpiresAt) + buf.Write(enc[:sz]) + buf.Write(v.Value) +} + +// Iterator is an interface for a basic iterator. +type Iterator interface { + Next() + Rewind() + Seek(key []byte) + Key() []byte + Value() ValueStruct + Valid() bool + + // All iterators should be closed so that file garbage collection works. + Close() error +} + +type elem struct { + itr Iterator + nice int + reversed bool +} + +type elemHeap []*elem + +func (eh elemHeap) Len() int { return len(eh) } +func (eh elemHeap) Swap(i, j int) { eh[i], eh[j] = eh[j], eh[i] } +func (eh *elemHeap) Push(x interface{}) { *eh = append(*eh, x.(*elem)) } +func (eh *elemHeap) Pop() interface{} { + // Remove the last element, because Go has already swapped 0th elem <-> last. + old := *eh + n := len(old) + x := old[n-1] + *eh = old[0 : n-1] + return x +} +func (eh elemHeap) Less(i, j int) bool { + cmp := CompareKeys(eh[i].itr.Key(), eh[j].itr.Key()) + if cmp < 0 { + return !eh[i].reversed + } + if cmp > 0 { + return eh[i].reversed + } + // The keys are equal. In this case, lower nice take precedence. This is important. + return eh[i].nice < eh[j].nice +} + +// MergeIterator merges multiple iterators. +// NOTE: MergeIterator owns the array of iterators and is responsible for closing them. +type MergeIterator struct { + h elemHeap + curKey []byte + reversed bool + + all []Iterator +} + +// NewMergeIterator returns a new MergeIterator from a list of Iterators. +func NewMergeIterator(iters []Iterator, reversed bool) *MergeIterator { + m := &MergeIterator{all: iters, reversed: reversed} + m.h = make(elemHeap, 0, len(iters)) + m.initHeap() + return m +} + +func (s *MergeIterator) storeKey(smallest Iterator) { + if cap(s.curKey) < len(smallest.Key()) { + s.curKey = make([]byte, 2*len(smallest.Key())) + } + s.curKey = s.curKey[:len(smallest.Key())] + copy(s.curKey, smallest.Key()) +} + +// initHeap checks all iterators and initializes our heap and array of keys. +// Whenever we reverse direction, we need to run this. +func (s *MergeIterator) initHeap() { + s.h = s.h[:0] + for idx, itr := range s.all { + if !itr.Valid() { + continue + } + e := &elem{itr: itr, nice: idx, reversed: s.reversed} + s.h = append(s.h, e) + } + heap.Init(&s.h) + for len(s.h) > 0 { + it := s.h[0].itr + if it == nil || !it.Valid() { + heap.Pop(&s.h) + continue + } + s.storeKey(s.h[0].itr) + break + } +} + +// Valid returns whether the MergeIterator is at a valid element. +func (s *MergeIterator) Valid() bool { + if s == nil { + return false + } + if len(s.h) == 0 { + return false + } + return s.h[0].itr.Valid() +} + +// Key returns the key associated with the current iterator +func (s *MergeIterator) Key() []byte { + if len(s.h) == 0 { + return nil + } + return s.h[0].itr.Key() +} + +// Value returns the value associated with the iterator. +func (s *MergeIterator) Value() ValueStruct { + if len(s.h) == 0 { + return ValueStruct{} + } + return s.h[0].itr.Value() +} + +// Next returns the next element. If it is the same as the current key, ignore it. +func (s *MergeIterator) Next() { + if len(s.h) == 0 { + return + } + + smallest := s.h[0].itr + smallest.Next() + + for len(s.h) > 0 { + smallest = s.h[0].itr + if !smallest.Valid() { + heap.Pop(&s.h) + continue + } + + heap.Fix(&s.h, 0) + smallest = s.h[0].itr + if smallest.Valid() { + if !bytes.Equal(smallest.Key(), s.curKey) { + break + } + smallest.Next() + } + } + if !smallest.Valid() { + return + } + s.storeKey(smallest) +} + +// Rewind seeks to first element (or last element for reverse iterator). +func (s *MergeIterator) Rewind() { + for _, itr := range s.all { + itr.Rewind() + } + s.initHeap() +} + +// Seek brings us to element with key >= given key. +func (s *MergeIterator) Seek(key []byte) { + for _, itr := range s.all { + itr.Seek(key) + } + s.initHeap() +} + +// Close implements y.Iterator +func (s *MergeIterator) Close() error { + for _, itr := range s.all { + if err := itr.Close(); err != nil { + return errors.Wrap(err, "MergeIterator") + } + } + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/y/metrics.go b/vendor/github.com/dgraph-io/badger/y/metrics.go new file mode 100644 index 00000000..2de17d10 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/metrics.go @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import "expvar" + +var ( + // LSMSize has size of the LSM in bytes + LSMSize *expvar.Map + // VlogSize has size of the value log in bytes + VlogSize *expvar.Map + // PendingWrites tracks the number of pending writes. + PendingWrites *expvar.Map + + // These are cumulative + + // NumReads has cumulative number of reads + NumReads *expvar.Int + // NumWrites has cumulative number of writes + NumWrites *expvar.Int + // NumBytesRead has cumulative number of bytes read + NumBytesRead *expvar.Int + // NumBytesWritten has cumulative number of bytes written + NumBytesWritten *expvar.Int + // NumLSMGets is number of LMS gets + NumLSMGets *expvar.Map + // NumLSMBloomHits is number of LMS bloom hits + NumLSMBloomHits *expvar.Map + // NumGets is number of gets + NumGets *expvar.Int + // NumPuts is number of puts + NumPuts *expvar.Int + // NumBlockedPuts is number of blocked puts + NumBlockedPuts *expvar.Int + // NumMemtableGets is number of memtable gets + NumMemtableGets *expvar.Int +) + +// These variables are global and have cumulative values for all kv stores. +func init() { + NumReads = expvar.NewInt("badger_disk_reads_total") + NumWrites = expvar.NewInt("badger_disk_writes_total") + NumBytesRead = expvar.NewInt("badger_read_bytes") + NumBytesWritten = expvar.NewInt("badger_written_bytes") + NumLSMGets = expvar.NewMap("badger_lsm_level_gets_total") + NumLSMBloomHits = expvar.NewMap("badger_lsm_bloom_hits_total") + NumGets = expvar.NewInt("badger_gets_total") + NumPuts = expvar.NewInt("badger_puts_total") + NumBlockedPuts = expvar.NewInt("badger_blocked_puts_total") + NumMemtableGets = expvar.NewInt("badger_memtable_gets_total") + LSMSize = expvar.NewMap("badger_lsm_size_bytes") + VlogSize = expvar.NewMap("badger_vlog_size_bytes") + PendingWrites = expvar.NewMap("badger_pending_writes_total") +} diff --git a/vendor/github.com/dgraph-io/badger/y/mmap_unix.go b/vendor/github.com/dgraph-io/badger/y/mmap_unix.go new file mode 100644 index 00000000..f9203a01 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/mmap_unix.go @@ -0,0 +1,63 @@ +// +build !windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import ( + "os" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +// Mmap uses the mmap system call to memory-map a file. If writable is true, +// memory protection of the pages is set so that they may be written to as well. +func Mmap(fd *os.File, writable bool, size int64) ([]byte, error) { + mtype := unix.PROT_READ + if writable { + mtype |= unix.PROT_WRITE + } + return unix.Mmap(int(fd.Fd()), 0, int(size), mtype, unix.MAP_SHARED) +} + +// Munmap unmaps a previously mapped slice. +func Munmap(b []byte) error { + return unix.Munmap(b) +} + +// Madvise uses the madvise system call to give advise about the use of memory +// when using a slice that is memory-mapped to a file. Set the readahead flag to +// false if page references are expected in random order. +func Madvise(b []byte, readahead bool) error { + flags := unix.MADV_NORMAL + if !readahead { + flags = unix.MADV_RANDOM + } + return madvise(b, flags) +} + +// This is required because the unix package does not support the madvise system call on OS X. +func madvise(b []byte, advice int) (err error) { + _, _, e1 := syscall.Syscall(syscall.SYS_MADVISE, uintptr(unsafe.Pointer(&b[0])), + uintptr(len(b)), uintptr(advice)) + if e1 != 0 { + err = e1 + } + return +} diff --git a/vendor/github.com/dgraph-io/badger/y/mmap_windows.go b/vendor/github.com/dgraph-io/badger/y/mmap_windows.go new file mode 100644 index 00000000..0efb2d0f --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/mmap_windows.go @@ -0,0 +1,90 @@ +// +build windows + +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import ( + "fmt" + "os" + "syscall" + "unsafe" +) + +func Mmap(fd *os.File, write bool, size int64) ([]byte, error) { + protect := syscall.PAGE_READONLY + access := syscall.FILE_MAP_READ + + if write { + protect = syscall.PAGE_READWRITE + access = syscall.FILE_MAP_WRITE + } + fi, err := fd.Stat() + if err != nil { + return nil, err + } + + // Truncate the database to the size of the mmap. + if fi.Size() < size { + if err := fd.Truncate(size); err != nil { + return nil, fmt.Errorf("truncate: %s", err) + } + } + + // Open a file mapping handle. + sizelo := uint32(size >> 32) + sizehi := uint32(size) & 0xffffffff + + handler, err := syscall.CreateFileMapping(syscall.Handle(fd.Fd()), nil, + uint32(protect), sizelo, sizehi, nil) + if err != nil { + return nil, os.NewSyscallError("CreateFileMapping", err) + } + + // Create the memory map. + addr, err := syscall.MapViewOfFile(handler, uint32(access), 0, 0, uintptr(size)) + if addr == 0 { + return nil, os.NewSyscallError("MapViewOfFile", err) + } + + // Close mapping handle. + if err := syscall.CloseHandle(syscall.Handle(handler)); err != nil { + return nil, os.NewSyscallError("CloseHandle", err) + } + + // Slice memory layout + // Copied this snippet from golang/sys package + var sl = struct { + addr uintptr + len int + cap int + }{addr, int(size), int(size)} + + // Use unsafe to turn sl into a []byte. + data := *(*[]byte)(unsafe.Pointer(&sl)) + + return data, nil +} + +func Munmap(b []byte) error { + return syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&b[0]))) +} + +func Madvise(b []byte, readahead bool) error { + // Do Nothing. We don’t care about this setting on Windows + return nil +} diff --git a/vendor/github.com/dgraph-io/badger/y/watermark.go b/vendor/github.com/dgraph-io/badger/y/watermark.go new file mode 100644 index 00000000..c0bbb194 --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/watermark.go @@ -0,0 +1,233 @@ +/* + * Copyright 2016-2018 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import ( + "container/heap" + "context" + "sync/atomic" + + "golang.org/x/net/trace" +) + +type uint64Heap []uint64 + +func (u uint64Heap) Len() int { return len(u) } +func (u uint64Heap) Less(i, j int) bool { return u[i] < u[j] } +func (u uint64Heap) Swap(i, j int) { u[i], u[j] = u[j], u[i] } +func (u *uint64Heap) Push(x interface{}) { *u = append(*u, x.(uint64)) } +func (u *uint64Heap) Pop() interface{} { + old := *u + n := len(old) + x := old[n-1] + *u = old[0 : n-1] + return x +} + +// mark contains one of more indices, along with a done boolean to indicate the +// status of the index: begin or done. It also contains waiters, who could be +// waiting for the watermark to reach >= a certain index. +type mark struct { + // Either this is an (index, waiter) pair or (index, done) or (indices, done). + index uint64 + waiter chan struct{} + indices []uint64 + done bool // Set to true if the index is done. +} + +// WaterMark is used to keep track of the minimum un-finished index. Typically, an index k becomes +// finished or "done" according to a WaterMark once Done(k) has been called +// 1. as many times as Begin(k) has, AND +// 2. a positive number of times. +// +// An index may also become "done" by calling SetDoneUntil at a time such that it is not +// inter-mingled with Begin/Done calls. +// +// Since doneUntil and lastIndex addresses are passed to sync/atomic packages, we ensure that they +// are 64-bit aligned by putting them at the beginning of the structure. +type WaterMark struct { + doneUntil uint64 + lastIndex uint64 + Name string + markCh chan mark + elog trace.EventLog +} + +// Init initializes a WaterMark struct. MUST be called before using it. +func (w *WaterMark) Init(closer *Closer) { + w.markCh = make(chan mark, 100) + w.elog = trace.NewEventLog("Watermark", w.Name) + go w.process(closer) +} + +// Begin sets the last index to the given value. +func (w *WaterMark) Begin(index uint64) { + atomic.StoreUint64(&w.lastIndex, index) + w.markCh <- mark{index: index, done: false} +} + +// BeginMany works like Begin but accepts multiple indices. +func (w *WaterMark) BeginMany(indices []uint64) { + atomic.StoreUint64(&w.lastIndex, indices[len(indices)-1]) + w.markCh <- mark{index: 0, indices: indices, done: false} +} + +// Done sets a single index as done. +func (w *WaterMark) Done(index uint64) { + w.markCh <- mark{index: index, done: true} +} + +// DoneMany works like Done but accepts multiple indices. +func (w *WaterMark) DoneMany(indices []uint64) { + w.markCh <- mark{index: 0, indices: indices, done: true} +} + +// DoneUntil returns the maximum index that has the property that all indices +// less than or equal to it are done. +func (w *WaterMark) DoneUntil() uint64 { + return atomic.LoadUint64(&w.doneUntil) +} + +// SetDoneUntil sets the maximum index that has the property that all indices +// less than or equal to it are done. +func (w *WaterMark) SetDoneUntil(val uint64) { + atomic.StoreUint64(&w.doneUntil, val) +} + +// LastIndex returns the last index for which Begin has been called. +func (w *WaterMark) LastIndex() uint64 { + return atomic.LoadUint64(&w.lastIndex) +} + +// WaitForMark waits until the given index is marked as done. +func (w *WaterMark) WaitForMark(ctx context.Context, index uint64) error { + if w.DoneUntil() >= index { + return nil + } + waitCh := make(chan struct{}) + w.markCh <- mark{index: index, waiter: waitCh} + + select { + case <-ctx.Done(): + return ctx.Err() + case <-waitCh: + return nil + } +} + +// process is used to process the Mark channel. This is not thread-safe, +// so only run one goroutine for process. One is sufficient, because +// all goroutine ops use purely memory and cpu. +// Each index has to emit atleast one begin watermark in serial order otherwise waiters +// can get blocked idefinitely. Example: We had an watermark at 100 and a waiter at 101, +// if no watermark is emitted at index 101 then waiter would get stuck indefinitely as it +// can't decide whether the task at 101 has decided not to emit watermark or it didn't get +// scheduled yet. +func (w *WaterMark) process(closer *Closer) { + defer closer.Done() + + var indices uint64Heap + // pending maps raft proposal index to the number of pending mutations for this proposal. + pending := make(map[uint64]int) + waiters := make(map[uint64][]chan struct{}) + + heap.Init(&indices) + var loop uint64 + + processOne := func(index uint64, done bool) { + // If not already done, then set. Otherwise, don't undo a done entry. + prev, present := pending[index] + if !present { + heap.Push(&indices, index) + } + + delta := 1 + if done { + delta = -1 + } + pending[index] = prev + delta + + loop++ + if len(indices) > 0 && loop%10000 == 0 { + min := indices[0] + w.elog.Printf("WaterMark %s: Done entry %4d. Size: %4d Watermark: %-4d Looking for: %-4d. Value: %d\n", + w.Name, index, len(indices), w.DoneUntil(), min, pending[min]) + } + + // Update mark by going through all indices in order; and checking if they have + // been done. Stop at the first index, which isn't done. + doneUntil := w.DoneUntil() + if doneUntil > index { + AssertTruef(false, "Name: %s doneUntil: %d. Index: %d", w.Name, doneUntil, index) + } + + until := doneUntil + loops := 0 + + for len(indices) > 0 { + min := indices[0] + if done := pending[min]; done > 0 { + break // len(indices) will be > 0. + } + // Even if done is called multiple times causing it to become + // negative, we should still pop the index. + heap.Pop(&indices) + delete(pending, min) + until = min + loops++ + } + for i := doneUntil + 1; i <= until; i++ { + toNotify := waiters[i] + for _, ch := range toNotify { + close(ch) + } + delete(waiters, i) // Release the memory back. + } + if until != doneUntil { + AssertTrue(atomic.CompareAndSwapUint64(&w.doneUntil, doneUntil, until)) + w.elog.Printf("%s: Done until %d. Loops: %d\n", w.Name, until, loops) + } + } + + for { + select { + case <-closer.HasBeenClosed(): + return + case mark := <-w.markCh: + if mark.waiter != nil { + doneUntil := atomic.LoadUint64(&w.doneUntil) + if doneUntil >= mark.index { + close(mark.waiter) + } else { + ws, ok := waiters[mark.index] + if !ok { + waiters[mark.index] = []chan struct{}{mark.waiter} + } else { + waiters[mark.index] = append(ws, mark.waiter) + } + } + } else { + if mark.index > 0 { + processOne(mark.index, mark.done) + } + for _, index := range mark.indices { + processOne(index, mark.done) + } + } + } + } +} diff --git a/vendor/github.com/dgraph-io/badger/y/y.go b/vendor/github.com/dgraph-io/badger/y/y.go new file mode 100644 index 00000000..4948315a --- /dev/null +++ b/vendor/github.com/dgraph-io/badger/y/y.go @@ -0,0 +1,302 @@ +/* + * Copyright 2017 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package y + +import ( + "bytes" + "encoding/binary" + "fmt" + "hash/crc32" + "math" + "os" + "sync" + "time" + + "github.com/pkg/errors" +) + +// ErrEOF indicates an end of file when trying to read from a memory mapped file +// and encountering the end of slice. +var ErrEOF = errors.New("End of mapped region") + +const ( + // Sync indicates that O_DSYNC should be set on the underlying file, + // ensuring that data writes do not return until the data is flushed + // to disk. + Sync = 1 << iota + // ReadOnly opens the underlying file on a read-only basis. + ReadOnly +) + +var ( + // This is O_DSYNC (datasync) on platforms that support it -- see file_unix.go + datasyncFileFlag = 0x0 + + // CastagnoliCrcTable is a CRC32 polynomial table + CastagnoliCrcTable = crc32.MakeTable(crc32.Castagnoli) + + // Dummy channel for nil closers. + dummyCloserChan = make(chan struct{}) +) + +// OpenExistingFile opens an existing file, errors if it doesn't exist. +func OpenExistingFile(filename string, flags uint32) (*os.File, error) { + openFlags := os.O_RDWR + if flags&ReadOnly != 0 { + openFlags = os.O_RDONLY + } + + if flags&Sync != 0 { + openFlags |= datasyncFileFlag + } + return os.OpenFile(filename, openFlags, 0) +} + +// CreateSyncedFile creates a new file (using O_EXCL), errors if it already existed. +func CreateSyncedFile(filename string, sync bool) (*os.File, error) { + flags := os.O_RDWR | os.O_CREATE | os.O_EXCL + if sync { + flags |= datasyncFileFlag + } + return os.OpenFile(filename, flags, 0666) +} + +// OpenSyncedFile creates the file if one doesn't exist. +func OpenSyncedFile(filename string, sync bool) (*os.File, error) { + flags := os.O_RDWR | os.O_CREATE + if sync { + flags |= datasyncFileFlag + } + return os.OpenFile(filename, flags, 0666) +} + +// OpenTruncFile opens the file with O_RDWR | O_CREATE | O_TRUNC +func OpenTruncFile(filename string, sync bool) (*os.File, error) { + flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC + if sync { + flags |= datasyncFileFlag + } + return os.OpenFile(filename, flags, 0666) +} + +// SafeCopy does append(a[:0], src...). +func SafeCopy(a, src []byte) []byte { + return append(a[:0], src...) +} + +// Copy copies a byte slice and returns the copied slice. +func Copy(a []byte) []byte { + b := make([]byte, len(a)) + copy(b, a) + return b +} + +// KeyWithTs generates a new key by appending ts to key. +func KeyWithTs(key []byte, ts uint64) []byte { + out := make([]byte, len(key)+8) + copy(out, key) + binary.BigEndian.PutUint64(out[len(key):], math.MaxUint64-ts) + return out +} + +// ParseTs parses the timestamp from the key bytes. +func ParseTs(key []byte) uint64 { + if len(key) <= 8 { + return 0 + } + return math.MaxUint64 - binary.BigEndian.Uint64(key[len(key)-8:]) +} + +// CompareKeys checks the key without timestamp and checks the timestamp if keyNoTs +// is same. +// a would be sorted higher than aa if we use bytes.compare +// All keys should have timestamp. +func CompareKeys(key1, key2 []byte) int { + AssertTrue(len(key1) > 8 && len(key2) > 8) + if cmp := bytes.Compare(key1[:len(key1)-8], key2[:len(key2)-8]); cmp != 0 { + return cmp + } + return bytes.Compare(key1[len(key1)-8:], key2[len(key2)-8:]) +} + +// ParseKey parses the actual key from the key bytes. +func ParseKey(key []byte) []byte { + if key == nil { + return nil + } + + AssertTrue(len(key) > 8) + return key[:len(key)-8] +} + +// SameKey checks for key equality ignoring the version timestamp suffix. +func SameKey(src, dst []byte) bool { + if len(src) != len(dst) { + return false + } + return bytes.Equal(ParseKey(src), ParseKey(dst)) +} + +// Slice holds a reusable buf, will reallocate if you request a larger size than ever before. +// One problem is with n distinct sizes in random order it'll reallocate log(n) times. +type Slice struct { + buf []byte +} + +// Resize reuses the Slice's buffer (or makes a new one) and returns a slice in that buffer of +// length sz. +func (s *Slice) Resize(sz int) []byte { + if cap(s.buf) < sz { + s.buf = make([]byte, sz) + } + return s.buf[0:sz] +} + +// FixedDuration returns a string representation of the given duration with the +// hours, minutes, and seconds. +func FixedDuration(d time.Duration) string { + str := fmt.Sprintf("%02ds", int(d.Seconds())%60) + if d >= time.Minute { + str = fmt.Sprintf("%02dm", int(d.Minutes())%60) + str + } + if d >= time.Hour { + str = fmt.Sprintf("%02dh", int(d.Hours())) + str + } + return str +} + +// Closer holds the two things we need to close a goroutine and wait for it to finish: a chan +// to tell the goroutine to shut down, and a WaitGroup with which to wait for it to finish shutting +// down. +type Closer struct { + closed chan struct{} + waiting sync.WaitGroup +} + +// NewCloser constructs a new Closer, with an initial count on the WaitGroup. +func NewCloser(initial int) *Closer { + ret := &Closer{closed: make(chan struct{})} + ret.waiting.Add(initial) + return ret +} + +// AddRunning Add()'s delta to the WaitGroup. +func (lc *Closer) AddRunning(delta int) { + lc.waiting.Add(delta) +} + +// Signal signals the HasBeenClosed signal. +func (lc *Closer) Signal() { + close(lc.closed) +} + +// HasBeenClosed gets signaled when Signal() is called. +func (lc *Closer) HasBeenClosed() <-chan struct{} { + if lc == nil { + return dummyCloserChan + } + return lc.closed +} + +// Done calls Done() on the WaitGroup. +func (lc *Closer) Done() { + if lc == nil { + return + } + lc.waiting.Done() +} + +// Wait waits on the WaitGroup. (It waits for NewCloser's initial value, AddRunning, and Done +// calls to balance out.) +func (lc *Closer) Wait() { + lc.waiting.Wait() +} + +// SignalAndWait calls Signal(), then Wait(). +func (lc *Closer) SignalAndWait() { + lc.Signal() + lc.Wait() +} + +// Throttle allows a limited number of workers to run at a time. It also +// provides a mechanism to check for errors encountered by workers and wait for +// them to finish. +type Throttle struct { + once sync.Once + wg sync.WaitGroup + ch chan struct{} + errCh chan error + finishErr error +} + +// NewThrottle creates a new throttle with a max number of workers. +func NewThrottle(max int) *Throttle { + return &Throttle{ + ch: make(chan struct{}, max), + errCh: make(chan error, max), + } +} + +// Do should be called by workers before they start working. It blocks if there +// are already maximum number of workers working. If it detects an error from +// previously Done workers, it would return it. +func (t *Throttle) Do() error { + for { + select { + case t.ch <- struct{}{}: + t.wg.Add(1) + return nil + case err := <-t.errCh: + if err != nil { + return err + } + } + } +} + +// Done should be called by workers when they finish working. They can also +// pass the error status of work done. +func (t *Throttle) Done(err error) { + if err != nil { + t.errCh <- err + } + select { + case <-t.ch: + default: + panic("Throttle Do Done mismatch") + } + t.wg.Done() +} + +// Finish waits until all workers have finished working. It would return any error passed by Done. +// If Finish is called multiple time, it will wait for workers to finish only once(first time). +// From next calls, it will return same error as found on first call. +func (t *Throttle) Finish() error { + t.once.Do(func() { + t.wg.Wait() + close(t.ch) + close(t.errCh) + for err := range t.errCh { + if err != nil { + t.finishErr = err + return + } + } + }) + + return t.finishErr +} diff --git a/vendor/github.com/dgryski/go-farm/.gitignore b/vendor/github.com/dgryski/go-farm/.gitignore new file mode 100644 index 00000000..36029ab5 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +*.exe +*.test +*.prof + +target diff --git a/vendor/github.com/dgryski/go-farm/.travis.yml b/vendor/github.com/dgryski/go-farm/.travis.yml new file mode 100644 index 00000000..bc89a55d --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/.travis.yml @@ -0,0 +1,39 @@ +language: go + +sudo: false + +branches: + except: + - release + +branches: + only: + - master + - develop + - travis + +go: + - 1.11.x + - 1.12.x + - tip + +matrix: + allow_failures: + - go: tip + +before_install: + - if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi; + - if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi; + - go get github.com/mattn/goveralls + +before_script: + - make deps + +script: + - make qa + +after_failure: + - cat ./target/test/report.xml + +after_success: + - if [ "$TRAVIS_GO_VERSION" = "1.9" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi; diff --git a/vendor/github.com/dgryski/go-farm/LICENSE b/vendor/github.com/dgryski/go-farm/LICENSE new file mode 100644 index 00000000..3d07f666 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/LICENSE @@ -0,0 +1,23 @@ +As this is a highly derivative work, I have placed it under the same license as the original implementation: + +Copyright (c) 2014-2017 Damian Gryski +Copyright (c) 2016-2017 Nicola Asuni - Tecnick.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/github.com/dgryski/go-farm/Makefile b/vendor/github.com/dgryski/go-farm/Makefile new file mode 100644 index 00000000..c189c95d --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/Makefile @@ -0,0 +1,203 @@ +# MAKEFILE +# +# @author Nicola Asuni +# @link https://github.com/dgryski/go-farm +# +# This file is intended to be executed in a Linux-compatible system. +# It also assumes that the project has been cloned in the right path under GOPATH: +# $GOPATH/src/github.com/dgryski/go-farm +# +# ------------------------------------------------------------------------------ + +# List special make targets that are not associated with files +.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan qa deps clean nuke + +# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS). +SHELL=/bin/bash + +# CVS path (path to the parent dir containing the project) +CVSPATH=github.com/dgryski + +# Project owner +OWNER=dgryski + +# Project vendor +VENDOR=dgryski + +# Project name +PROJECT=go-farm + +# Project version +VERSION=$(shell cat VERSION) + +# Name of RPM or DEB package +PKGNAME=${VENDOR}-${PROJECT} + +# Current directory +CURRENTDIR=$(shell pwd) + +# GO lang path +ifneq ($(GOPATH),) + ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),) + # the defined GOPATH is not valid + GOPATH= + endif +endif +ifeq ($(GOPATH),) + # extract the GOPATH + GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR))) +endif + +# --- MAKE TARGETS --- + +# Display general help about this command +help: + @echo "" + @echo "$(PROJECT) Makefile." + @echo "GOPATH=$(GOPATH)" + @echo "The following commands are available:" + @echo "" + @echo " make qa : Run all the tests" + @echo " make test : Run the unit tests" + @echo "" + @echo " make format : Format the source code" + @echo " make fmtcheck : Check if the source code has been formatted" + @echo " make vet : Check for suspicious constructs" + @echo " make lint : Check for style errors" + @echo " make coverage : Generate the coverage report" + @echo " make cyclo : Generate the cyclomatic complexity report" + @echo " make ineffassign : Detect ineffectual assignments" + @echo " make misspell : Detect commonly misspelled words in source files" + @echo " make structcheck : Find unused struct fields" + @echo " make varcheck : Find unused global variables and constants" + @echo " make errcheck : Check that error return values are used" + @echo " make gosimple : Suggest code simplifications" + @echo " make astscan : GO AST scanner" + @echo "" + @echo " make docs : Generate source code documentation" + @echo "" + @echo " make deps : Get the dependencies" + @echo " make clean : Remove any build artifact" + @echo " make nuke : Deletes any intermediate file" + @echo "" + + +# Alias for help target +all: help + +# Run the unit tests +test: + @mkdir -p target/test + @mkdir -p target/report + GOPATH=$(GOPATH) \ + go test \ + -covermode=atomic \ + -bench=. \ + -race \ + -cpuprofile=target/report/cpu.out \ + -memprofile=target/report/mem.out \ + -mutexprofile=target/report/mutex.out \ + -coverprofile=target/report/coverage.out \ + -v ./... | \ + tee >(PATH=$(GOPATH)/bin:$(PATH) go-junit-report > target/test/report.xml); \ + test $${PIPESTATUS[0]} -eq 0 + +# Format the source code +format: + @find . -type f -name "*.go" -exec gofmt -s -w {} \; + +# Check if the source code has been formatted +fmtcheck: + @mkdir -p target + @find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff + @test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; } + +# Check for syntax errors +vet: + GOPATH=$(GOPATH) go vet . + +# Check for style errors +lint: + GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint . + +# Generate the coverage report +coverage: + @mkdir -p target/report + GOPATH=$(GOPATH) \ + go tool cover -html=target/report/coverage.out -o target/report/coverage.html + +# Report cyclomatic complexity +cyclo: + @mkdir -p target/report + GOPATH=$(GOPATH) gocyclo -avg ./ | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0 + +# Detect ineffectual assignments +ineffassign: + @mkdir -p target/report + GOPATH=$(GOPATH) ineffassign ./ | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0 + +# Detect commonly misspelled words in source files +misspell: + @mkdir -p target/report + GOPATH=$(GOPATH) misspell -error ./ | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0 + +# Find unused struct fields +structcheck: + @mkdir -p target/report + GOPATH=$(GOPATH) structcheck -a ./ | tee target/report/structcheck.txt + +# Find unused global variables and constants +varcheck: + @mkdir -p target/report + GOPATH=$(GOPATH) varcheck -e ./ | tee target/report/varcheck.txt + +# Check that error return values are used +errcheck: + @mkdir -p target/report + GOPATH=$(GOPATH) errcheck ./ | tee target/report/errcheck.txt + +# Suggest code simplifications +gosimple: + @mkdir -p target/report + GOPATH=$(GOPATH) gosimple ./ | tee target/report/gosimple.txt + +# AST scanner +astscan: + @mkdir -p target/report + GOPATH=$(GOPATH) gas .//*.go | tee target/report/astscan.txt + +# Generate source docs +docs: + @mkdir -p target/docs + nohup sh -c 'GOPATH=$(GOPATH) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 & + wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060` + @echo ''${PKGNAME}' Documentation ...' > target/docs/index.html + +# Alias to run all quality-assurance checks +qa: fmtcheck test vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan + +# --- INSTALL --- + +# Get the dependencies +deps: + GOPATH=$(GOPATH) go get ./... + GOPATH=$(GOPATH) go get golang.org/x/lint/golint + GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report + GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov + GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo + GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign + GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell + GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/structcheck + GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/varcheck + GOPATH=$(GOPATH) go get github.com/kisielk/errcheck + GOPATH=$(GOPATH) go get honnef.co/go/tools/cmd/gosimple + GOPATH=$(GOPATH) go get github.com/GoASTScanner/gas + +# Remove any build artifact +clean: + GOPATH=$(GOPATH) go clean ./... + +# Deletes any intermediate file +nuke: + rm -rf ./target + GOPATH=$(GOPATH) go clean -i ./... diff --git a/vendor/github.com/dgryski/go-farm/README.md b/vendor/github.com/dgryski/go-farm/README.md new file mode 100644 index 00000000..dd07d6f9 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/README.md @@ -0,0 +1,41 @@ +# go-farm + +*Google's FarmHash hash functions implemented in Go* + +[![Master Branch](https://img.shields.io/badge/-master:-gray.svg)](https://github.com/dgryski/go-farm/tree/master) +[![Master Build Status](https://secure.travis-ci.org/dgryski/go-farm.png?branch=master)](https://travis-ci.org/dgryski/go-farm?branch=master) +[![Master Coverage Status](https://coveralls.io/repos/dgryski/go-farm/badge.svg?branch=master&service=github)](https://coveralls.io/github/dgryski/go-farm?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/dgryski/go-farm)](https://goreportcard.com/report/github.com/dgryski/go-farm) +[![GoDoc](https://godoc.org/github.com/dgryski/go-farm?status.svg)](http://godoc.org/github.com/dgryski/go-farm) + +## Description + +FarmHash, a family of hash functions. + +This is a (mechanical) translation of the non-SSE4/non-AESNI hash functions from Google's FarmHash (https://github.com/google/farmhash). + + +FarmHash provides hash functions for strings and other data. +The functions mix the input bits thoroughly but are not suitable for cryptography. + +All members of the FarmHash family were designed with heavy reliance on previous work by Jyrki Alakuijala, Austin Appleby, Bob Jenkins, and others. + +For more information please consult https://github.com/google/farmhash + + +## Getting started + +This application is written in Go language, please refer to the guides in https://golang.org for getting started. + +This project include a Makefile that allows you to test and build the project with simple commands. +To see all available options: +```bash +make help +``` + +## Running all tests + +Before committing the code, please check if it passes all tests using +```bash +make qa +``` diff --git a/vendor/github.com/dgryski/go-farm/VERSION b/vendor/github.com/dgryski/go-farm/VERSION new file mode 100644 index 00000000..38f77a65 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/VERSION @@ -0,0 +1 @@ +2.0.1 diff --git a/vendor/github.com/dgryski/go-farm/asm.go b/vendor/github.com/dgryski/go-farm/asm.go new file mode 100644 index 00000000..1d69eebb --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/asm.go @@ -0,0 +1,898 @@ +// +build ignore + +package main + +import ( + "flag" + + . "github.com/mmcloughlin/avo/build" + . "github.com/mmcloughlin/avo/operand" + . "github.com/mmcloughlin/avo/reg" +) + +const k0 uint64 = 0xc3a5c85c97cb3127 +const k1 uint64 = 0xb492b66fbe98f273 +const k2 uint64 = 0x9ae16a3b2f90404f + +const c1 uint32 = 0xcc9e2d51 +const c2 uint32 = 0x1b873593 + +func shiftMix(val GPVirtual) GPVirtual { + r := GP64() + MOVQ(val, r) + SHRQ(Imm(47), r) + XORQ(val, r) + return r +} + +func shiftMix64(val uint64) uint64 { + return val ^ (val >> 47) +} + +func hashLen16MulLine(a, b, c, d, k, mul GPVirtual) GPVirtual { + tmpa := GP64() + MOVQ(a, tmpa) + + ADDQ(b, tmpa) + RORQ(Imm(43), tmpa) + ADDQ(d, tmpa) + tmpc := GP64() + MOVQ(c, tmpc) + RORQ(Imm(30), tmpc) + ADDQ(tmpc, tmpa) + + ADDQ(c, a) + ADDQ(k, b) + RORQ(Imm(18), b) + ADDQ(b, a) + + r := hashLen16Mul(tmpa, a, mul) + return r +} + +func hashLen16Mul(u, v, mul GPVirtual) GPVirtual { + XORQ(v, u) + IMULQ(mul, u) + a := shiftMix(u) + + XORQ(a, v) + IMULQ(mul, v) + b := shiftMix(v) + + IMULQ(mul, b) + + return b +} + +func hashLen0to16(sbase, slen GPVirtual) { + CMPQ(slen, Imm(8)) + JL(LabelRef("check4")) + { + a := GP64() + MOVQ(Mem{Base: sbase}, a) + + b := GP64() + t := GP64() + MOVQ(slen, t) + SUBQ(Imm(8), t) + ADDQ(sbase, t) + MOVQ(Mem{Base: t}, b) + + rk2 := GP64() + MOVQ(Imm(k2), rk2) + + ADDQ(rk2, a) + + mul := slen + SHLQ(Imm(1), mul) + ADDQ(rk2, mul) + + c := GP64() + MOVQ(b, c) + RORQ(Imm(37), c) + IMULQ(mul, c) + ADDQ(a, c) + + d := GP64() + MOVQ(a, d) + RORQ(Imm(25), d) + ADDQ(b, d) + IMULQ(mul, d) + + r := hashLen16Mul(c, d, mul) + Store(r, ReturnIndex(0)) + RET() + } + + Label("check4") + + CMPQ(slen, Imm(4)) + JL(LabelRef("check0")) + { + rk2 := GP64() + MOVQ(Imm(k2), rk2) + + mul := GP64() + MOVQ(slen, mul) + SHLQ(Imm(1), mul) + ADDQ(rk2, mul) + + a := GP64() + MOVL(Mem{Base: sbase}, a.As32()) + + SHLQ(Imm(3), a) + ADDQ(slen, a) + + b := GP64() + SUBQ(Imm(4), slen) + ADDQ(slen, sbase) + MOVL(Mem{Base: sbase}, b.As32()) + r := hashLen16Mul(a, b, mul) + + Store(r, ReturnIndex(0)) + RET() + } + + Label("check0") + TESTQ(slen, slen) + JZ(LabelRef("empty")) + { + + a := GP64() + MOVBQZX(Mem{Base: sbase}, a) + + base := GP64() + MOVQ(slen, base) + SHRQ(Imm(1), base) + + b := GP64() + ADDQ(sbase, base) + MOVBQZX(Mem{Base: base}, b) + + MOVQ(slen, base) + SUBQ(Imm(1), base) + c := GP64() + ADDQ(sbase, base) + MOVBQZX(Mem{Base: base}, c) + + SHLQ(Imm(8), b) + ADDQ(b, a) + y := a + + SHLQ(Imm(2), c) + ADDQ(c, slen) + z := slen + + rk0 := GP64() + MOVQ(Imm(k0), rk0) + IMULQ(rk0, z) + + rk2 := GP64() + MOVQ(Imm(k2), rk2) + + IMULQ(rk2, y) + XORQ(y, z) + + r := shiftMix(z) + IMULQ(rk2, r) + + Store(r, ReturnIndex(0)) + RET() + } + + Label("empty") + + ret := GP64() + MOVQ(Imm(k2), ret) + Store(ret, ReturnIndex(0)) + RET() +} + +func hashLen17to32(sbase, slen GPVirtual) { + mul := GP64() + MOVQ(slen, mul) + SHLQ(Imm(1), mul) + + rk2 := GP64() + MOVQ(Imm(k2), rk2) + ADDQ(rk2, mul) + + a := GP64() + MOVQ(Mem{Base: sbase}, a) + + rk1 := GP64() + MOVQ(Imm(k1), rk1) + IMULQ(rk1, a) + + b := GP64() + MOVQ(Mem{Base: sbase, Disp: 8}, b) + + base := GP64() + MOVQ(slen, base) + SUBQ(Imm(16), base) + ADDQ(sbase, base) + + c := GP64() + MOVQ(Mem{Base: base, Disp: 8}, c) + IMULQ(mul, c) + + d := GP64() + MOVQ(Mem{Base: base}, d) + IMULQ(rk2, d) + + r := hashLen16MulLine(a, b, c, d, rk2, mul) + Store(r, ReturnIndex(0)) + RET() +} + +// Return an 8-byte hash for 33 to 64 bytes. +func hashLen33to64(sbase, slen GPVirtual) { + mul := GP64() + MOVQ(slen, mul) + SHLQ(Imm(1), mul) + + rk2 := GP64() + MOVQ(Imm(k2), rk2) + ADDQ(rk2, mul) + + a := GP64() + MOVQ(Mem{Base: sbase}, a) + IMULQ(rk2, a) + + b := GP64() + MOVQ(Mem{Base: sbase, Disp: 8}, b) + + base := GP64() + MOVQ(slen, base) + SUBQ(Imm(16), base) + ADDQ(sbase, base) + + c := GP64() + MOVQ(Mem{Base: base, Disp: 8}, c) + IMULQ(mul, c) + + d := GP64() + MOVQ(Mem{Base: base}, d) + IMULQ(rk2, d) + + y := GP64() + MOVQ(a, y) + + ADDQ(b, y) + RORQ(Imm(43), y) + ADDQ(d, y) + tmpc := GP64() + MOVQ(c, tmpc) + RORQ(Imm(30), tmpc) + ADDQ(tmpc, y) + + ADDQ(a, c) + ADDQ(rk2, b) + RORQ(Imm(18), b) + ADDQ(b, c) + + tmpy := GP64() + MOVQ(y, tmpy) + z := hashLen16Mul(tmpy, c, mul) + + e := GP64() + MOVQ(Mem{Base: sbase, Disp: 16}, e) + IMULQ(mul, e) + + f := GP64() + MOVQ(Mem{Base: sbase, Disp: 24}, f) + + base = GP64() + MOVQ(slen, base) + SUBQ(Imm(32), base) + ADDQ(sbase, base) + g := GP64() + MOVQ(Mem{Base: base}, g) + ADDQ(y, g) + IMULQ(mul, g) + + h := GP64() + MOVQ(Mem{Base: base, Disp: 8}, h) + ADDQ(z, h) + IMULQ(mul, h) + + r := hashLen16MulLine(e, f, g, h, a, mul) + Store(r, ReturnIndex(0)) + RET() +} + +// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. +func weakHashLen32WithSeeds(sbase GPVirtual, disp int, a, b GPVirtual) { + + w := Mem{Base: sbase, Disp: disp + 0} + x := Mem{Base: sbase, Disp: disp + 8} + y := Mem{Base: sbase, Disp: disp + 16} + z := Mem{Base: sbase, Disp: disp + 24} + + // a += w + ADDQ(w, a) + + // b = bits.RotateLeft64(b+a+z, -21) + ADDQ(a, b) + ADDQ(z, b) + RORQ(Imm(21), b) + + // c := a + c := GP64() + MOVQ(a, c) + + // a += x + // a += y + ADDQ(x, a) + ADDQ(y, a) + + // b += bits.RotateLeft64(a, -44) + atmp := GP64() + MOVQ(a, atmp) + RORQ(Imm(44), atmp) + ADDQ(atmp, b) + + // a += z + // b += c + ADDQ(z, a) + ADDQ(c, b) + + XCHGQ(a, b) +} + +func hashLoopBody(x, y, z, vlo, vhi, wlo, whi, sbase GPVirtual, mul1 GPVirtual, mul2 uint64) { + ADDQ(y, x) + ADDQ(vlo, x) + ADDQ(Mem{Base: sbase, Disp: 8}, x) + RORQ(Imm(37), x) + + IMULQ(mul1, x) + + ADDQ(vhi, y) + ADDQ(Mem{Base: sbase, Disp: 48}, y) + RORQ(Imm(42), y) + IMULQ(mul1, y) + + if mul2 != 1 { + t := GP64() + MOVQ(U32(mul2), t) + IMULQ(whi, t) + XORQ(t, x) + } else { + XORQ(whi, x) + } + + if mul2 != 1 { + t := GP64() + MOVQ(U32(mul2), t) + IMULQ(vlo, t) + ADDQ(t, y) + } else { + ADDQ(vlo, y) + } + + ADDQ(Mem{Base: sbase, Disp: 40}, y) + + ADDQ(wlo, z) + RORQ(Imm(33), z) + IMULQ(mul1, z) + + { + IMULQ(mul1, vhi) + MOVQ(x, vlo) + ADDQ(wlo, vlo) + weakHashLen32WithSeeds(sbase, 0, vhi, vlo) + } + + { + ADDQ(z, whi) + MOVQ(y, wlo) + ADDQ(Mem{Base: sbase, Disp: 16}, wlo) + weakHashLen32WithSeeds(sbase, 32, whi, wlo) + } + + XCHGQ(z, x) +} + +func fp64() { + + TEXT("Fingerprint64", NOSPLIT, "func(s []byte) uint64") + + slen := GP64() + sbase := GP64() + + Load(Param("s").Base(), sbase) + Load(Param("s").Len(), slen) + + CMPQ(slen, Imm(16)) + JG(LabelRef("check32")) + hashLen0to16(sbase, slen) + + Label("check32") + CMPQ(slen, Imm(32)) + JG(LabelRef("check64")) + hashLen17to32(sbase, slen) + + Label("check64") + CMPQ(slen, Imm(64)) + JG(LabelRef("long")) + hashLen33to64(sbase, slen) + + Label("long") + + seed := uint64(81) + + vlo, vhi, wlo, whi := GP64(), GP64(), GP64(), GP64() + XORQ(vlo, vlo) + XORQ(vhi, vhi) + XORQ(wlo, wlo) + XORQ(whi, whi) + + x := GP64() + + eightOne := uint64(81) + + MOVQ(Imm(eightOne*k2), x) + ADDQ(Mem{Base: sbase}, x) + + y := GP64() + y64 := uint64(seed*k1) + 113 + MOVQ(Imm(y64), y) + + z := GP64() + MOVQ(Imm(shiftMix64(y64*k2+113)*k2), z) + + endIdx := GP64() + MOVQ(slen, endIdx) + tmp := GP64() + SUBQ(Imm(1), endIdx) + MOVQ(U64(^uint64(63)), tmp) + ANDQ(tmp, endIdx) + last64Idx := GP64() + MOVQ(slen, last64Idx) + SUBQ(Imm(1), last64Idx) + ANDQ(Imm(63), last64Idx) + SUBQ(Imm(63), last64Idx) + ADDQ(endIdx, last64Idx) + + last64 := GP64() + MOVQ(last64Idx, last64) + ADDQ(sbase, last64) + + end := GP64() + MOVQ(slen, end) + + Label("loop") + + rk1 := GP64() + MOVQ(Imm(k1), rk1) + + hashLoopBody(x, y, z, vlo, vhi, wlo, whi, sbase, rk1, 1) + + ADDQ(Imm(64), sbase) + SUBQ(Imm(64), end) + CMPQ(end, Imm(64)) + JG(LabelRef("loop")) + + MOVQ(last64, sbase) + + mul := GP64() + MOVQ(z, mul) + ANDQ(Imm(0xff), mul) + SHLQ(Imm(1), mul) + ADDQ(rk1, mul) + + MOVQ(last64, sbase) + + SUBQ(Imm(1), slen) + ANDQ(Imm(63), slen) + ADDQ(slen, wlo) + + ADDQ(wlo, vlo) + ADDQ(vlo, wlo) + + hashLoopBody(x, y, z, vlo, vhi, wlo, whi, sbase, mul, 9) + + { + a := hashLen16Mul(vlo, wlo, mul) + ADDQ(z, a) + b := shiftMix(y) + rk0 := GP64() + MOVQ(Imm(k0), rk0) + IMULQ(rk0, b) + ADDQ(b, a) + + c := hashLen16Mul(vhi, whi, mul) + ADDQ(x, c) + + r := hashLen16Mul(a, c, mul) + Store(r, ReturnIndex(0)) + } + + RET() +} + +func fmix(h GPVirtual) GPVirtual { + h2 := GP32() + MOVL(h, h2) + SHRL(Imm(16), h2) + XORL(h2, h) + + MOVL(Imm(0x85ebca6b), h2) + IMULL(h2, h) + + MOVL(h, h2) + SHRL(Imm(13), h2) + XORL(h2, h) + + MOVL(Imm(0xc2b2ae35), h2) + IMULL(h2, h) + + MOVL(h, h2) + SHRL(Imm(16), h2) + XORL(h2, h) + return h +} + +func mur(a, h GPVirtual) GPVirtual { + imul3l(c1, a, a) + RORL(Imm(17), a) + imul3l(c2, a, a) + XORL(a, h) + RORL(Imm(19), h) + + LEAL(Mem{Base: h, Index: h, Scale: 4}, a) + LEAL(Mem{Base: a, Disp: 0xe6546b64}, h) + + return h +} + +func hash32Len5to12(sbase, slen GPVirtual) { + + a := GP32() + MOVL(slen.As32(), a) + b := GP32() + MOVL(a, b) + SHLL(Imm(2), b) + ADDL(a, b) + + c := GP32() + MOVL(U32(9), c) + + d := GP32() + MOVL(b, d) + + ADDL(Mem{Base: sbase, Disp: 0}, a) + + t := GP64() + MOVQ(slen, t) + SUBQ(Imm(4), t) + ADDQ(sbase, t) + ADDL(Mem{Base: t}, b) + + MOVQ(slen, t) + SHRQ(Imm(1), t) + ANDQ(Imm(4), t) + ADDQ(sbase, t) + ADDL(Mem{Base: t}, c) + + t = mur(a, d) + t = mur(b, t) + t = mur(c, t) + t = fmix(t) + + Store(t, ReturnIndex(0)) + RET() +} + +func hash32Len13to24Seed(sbase, slen GPVirtual) { + slen2 := GP64() + MOVQ(slen, slen2) + SHRQ(Imm(1), slen2) + ADDQ(sbase, slen2) + + a := GP32() + MOVL(Mem{Base: slen2, Disp: -4}, a) + + b := GP32() + MOVL(Mem{Base: sbase, Disp: 4}, b) + + send := GP64() + MOVQ(slen, send) + ADDQ(sbase, send) + + c := GP32() + MOVL(Mem{Base: send, Disp: -8}, c) + + d := GP32() + MOVL(Mem{Base: slen2}, d) + + e := GP32() + MOVL(Mem{Base: sbase}, e) + + f := GP32() + MOVL(Mem{Base: send, Disp: -4}, f) + + h := GP32() + MOVL(U32(c1), h) + IMULL(d, h) + ADDL(slen.As32(), h) + + RORL(Imm(12), a) + ADDL(f, a) + + ctmp := GP32() + MOVL(c, ctmp) + h = mur(ctmp, h) + ADDL(a, h) + + RORL(Imm(3), a) + ADDL(c, a) + + h = mur(e, h) + ADDL(a, h) + + ADDL(f, a) + RORL(Imm(12), a) + ADDL(d, a) + + h = mur(b, h) + ADDL(a, h) + + h = fmix(h) + + Store(h, ReturnIndex(0)) + RET() +} + +func hash32Len0to4(sbase, slen GPVirtual) { + b := GP32() + c := GP32() + + XORL(b, b) + MOVL(U32(9), c) + + TESTQ(slen, slen) + JZ(LabelRef("done")) + + l := GP64() + v := GP32() + MOVQ(slen, l) + + c1reg := GP32() + MOVL(U32(c1), c1reg) + + for i := 0; i < 4; i++ { + IMULL(c1reg, b) + MOVBLSX(Mem{Base: sbase, Disp: i}, v) + ADDL(v, b) + XORL(b, c) + SUBQ(Imm(1), l) + TESTQ(l, l) + JZ(LabelRef("done")) + } + + Label("done") + + s32 := GP32() + MOVL(slen.As32(), s32) + r := mur(s32, c) + r = mur(b, r) + r = fmix(r) + + Store(r, ReturnIndex(0)) + RET() +} + +func fp32() { + + TEXT("Fingerprint32", NOSPLIT, "func(s []byte) uint32") + + sbase := GP64() + slen := GP64() + + Load(Param("s").Base(), sbase) + Load(Param("s").Len(), slen) + + CMPQ(slen, Imm(24)) + JG(LabelRef("long")) + + CMPQ(slen, Imm(12)) + JG(LabelRef("hash_13_24")) + + CMPQ(slen, Imm(4)) + JG(LabelRef("hash_5_12")) + hash32Len0to4(sbase, slen) + + Label("hash_5_12") + hash32Len5to12(sbase, slen) + + Label("hash_13_24") + hash32Len13to24Seed(sbase, slen) + + Label("long") + + h := GP32() + MOVL(slen.As32(), h) + + g := GP32() + MOVL(U32(c1), g) + IMULL(h, g) + + f := GP32() + MOVL(g, f) + + // len > 24 + + send := GP64() + MOVQ(slen, send) + ADDQ(sbase, send) + c1reg := GP32() + MOVL(U32(c1), c1reg) + c2reg := GP32() + MOVL(U32(c2), c2reg) + + shuf := func(r GPVirtual, disp int) { + a := GP32() + MOVL(Mem{Base: send, Disp: disp}, a) + IMULL(c1reg, a) + RORL(Imm(17), a) + IMULL(c2reg, a) + XORL(a, r) + RORL(Imm(19), r) + MOVL(r, a) + SHLL(Imm(2), a) + ADDL(a, r) + ADDL(Imm(0xe6546b64), r) + } + + shuf(h, -4) + shuf(g, -8) + shuf(h, -16) + shuf(g, -12) + + PREFETCHT0(Mem{Base: sbase}) + { + a := GP32() + MOVL(Mem{Base: send, Disp: -20}, a) + IMULL(c1reg, a) + RORL(Imm(17), a) + IMULL(c2reg, a) + + ADDL(a, f) + RORL(Imm(19), f) + ADDL(Imm(113), f) + + } + + loop32Body := func(f, g, h, sbase, slen GPVirtual, disp int) { + a, b, c, d, e := GP32(), GP32(), GP32(), GP32(), GP32() + + MOVL(Mem{Base: sbase, Disp: disp + 0}, a) + ADDL(a, h) + + MOVL(Mem{Base: sbase, Disp: disp + 4}, b) + ADDL(b, g) + + MOVL(Mem{Base: sbase, Disp: disp + 8}, c) + ADDL(c, f) + + MOVL(Mem{Base: sbase, Disp: disp + 12}, d) + t := GP32() + MOVL(d, t) + h = mur(t, h) + + MOVL(Mem{Base: sbase, Disp: disp + 16}, e) + ADDL(e, h) + + MOVL(c, t) + g = mur(t, g) + ADDL(a, g) + + imul3l(c1, e, t) + ADDL(b, t) + f = mur(t, f) + ADDL(d, f) + + ADDL(g, f) + ADDL(f, g) + } + + Label("loop80") + CMPQ(slen, Imm(80+20)) + JL(LabelRef("loop20")) + { + PREFETCHT0(Mem{Base: sbase, Disp: 20}) + loop32Body(f, g, h, sbase, slen, 0) + PREFETCHT0(Mem{Base: sbase, Disp: 40}) + loop32Body(f, g, h, sbase, slen, 20) + PREFETCHT0(Mem{Base: sbase, Disp: 60}) + loop32Body(f, g, h, sbase, slen, 40) + PREFETCHT0(Mem{Base: sbase, Disp: 80}) + loop32Body(f, g, h, sbase, slen, 60) + + ADDQ(Imm(80), sbase) + SUBQ(Imm(80), slen) + JMP(LabelRef("loop80")) + } + + Label("loop20") + CMPQ(slen, Imm(20)) + JLE(LabelRef("after")) + { + loop32Body(f, g, h, sbase, slen, 0) + + ADDQ(Imm(20), sbase) + SUBQ(Imm(20), slen) + JMP(LabelRef("loop20")) + } + + Label("after") + + c1reg = GP32() + MOVL(U32(c1), c1reg) + + RORL(Imm(11), g) + IMULL(c1reg, g) + + RORL(Imm(17), g) + IMULL(c1reg, g) + + RORL(Imm(11), f) + IMULL(c1reg, f) + + RORL(Imm(17), f) + IMULL(c1reg, f) + + ADDL(g, h) + RORL(Imm(19), h) + + t := GP32() + MOVL(h, t) + SHLL(Imm(2), t) + ADDL(t, h) + ADDL(Imm(0xe6546b64), h) + + RORL(Imm(17), h) + IMULL(c1reg, h) + + ADDL(f, h) + RORL(Imm(19), h) + + t = GP32() + MOVL(h, t) + SHLL(Imm(2), t) + ADDL(t, h) + ADDL(Imm(0xe6546b64), h) + + RORL(Imm(17), h) + IMULL(c1reg, h) + + Store(h, ReturnIndex(0)) + RET() +} + +var go111 = flag.Bool("go111", true, "use assembly instructions present in go1.11 and later") + +func imul3l(m uint32, x, y Register) { + if *go111 { + IMUL3L(U32(m), x, y) + } else { + t := GP32() + MOVL(U32(m), t) + IMULL(t, x) + MOVL(x, y) + } +} + +func main() { + + flag.Parse() + + ConstraintExpr("amd64,!purego") + + fp64() + fp32() + + Generate() +} diff --git a/vendor/github.com/dgryski/go-farm/basics.go b/vendor/github.com/dgryski/go-farm/basics.go new file mode 100644 index 00000000..ec7076c0 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/basics.go @@ -0,0 +1,32 @@ +package farm + +import "math/bits" + +// Some primes between 2^63 and 2^64 for various uses. +const k0 uint64 = 0xc3a5c85c97cb3127 +const k1 uint64 = 0xb492b66fbe98f273 +const k2 uint64 = 0x9ae16a3b2f90404f + +// Magic numbers for 32-bit hashing. Copied from Murmur3. +const c1 uint32 = 0xcc9e2d51 +const c2 uint32 = 0x1b873593 + +// A 32-bit to 32-bit integer hash copied from Murmur3. +func fmix(h uint32) uint32 { + h ^= h >> 16 + h *= 0x85ebca6b + h ^= h >> 13 + h *= 0xc2b2ae35 + h ^= h >> 16 + return h +} + +func mur(a, h uint32) uint32 { + // Helper from Murmur3 for combining two 32-bit values. + a *= c1 + a = bits.RotateLeft32(a, -17) + a *= c2 + h ^= a + h = bits.RotateLeft32(h, -19) + return h*5 + 0xe6546b64 +} diff --git a/vendor/github.com/dgryski/go-farm/farmhashcc.go b/vendor/github.com/dgryski/go-farm/farmhashcc.go new file mode 100644 index 00000000..3e68ae3a --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/farmhashcc.go @@ -0,0 +1,194 @@ +package farm + +import ( + "encoding/binary" + "math/bits" +) + +// This file provides a 32-bit hash equivalent to CityHash32 (v1.1.1) +// and a 128-bit hash equivalent to CityHash128 (v1.1.1). It also provides +// a seeded 32-bit hash function similar to CityHash32. + +func hash32Len13to24Seed(s []byte, seed uint32) uint32 { + slen := len(s) + a := binary.LittleEndian.Uint32(s[-4+(slen>>1) : -4+(slen>>1)+4]) + b := binary.LittleEndian.Uint32(s[4 : 4+4]) + c := binary.LittleEndian.Uint32(s[slen-8 : slen-8+4]) + d := binary.LittleEndian.Uint32(s[(slen >> 1) : (slen>>1)+4]) + e := binary.LittleEndian.Uint32(s[0 : 0+4]) + f := binary.LittleEndian.Uint32(s[slen-4 : slen-4+4]) + h := d*c1 + uint32(slen) + seed + a = bits.RotateLeft32(a, -12) + f + h = mur(c, h) + a + a = bits.RotateLeft32(a, -3) + c + h = mur(e, h) + a + a = bits.RotateLeft32(a+f, -12) + d + h = mur(b^seed, h) + a + return fmix(h) +} + +func hash32Len0to4(s []byte, seed uint32) uint32 { + slen := len(s) + b := seed + c := uint32(9) + for i := 0; i < slen; i++ { + v := int8(s[i]) + b = (b * c1) + uint32(v) + c ^= b + } + return fmix(mur(b, mur(uint32(slen), c))) +} + +func hash128to64(x uint128) uint64 { + // Murmur-inspired hashing. + const mul uint64 = 0x9ddfea08eb382d69 + a := (x.lo ^ x.hi) * mul + a ^= (a >> 47) + b := (x.hi ^ a) * mul + b ^= (b >> 47) + b *= mul + return b +} + +type uint128 struct { + lo uint64 + hi uint64 +} + +// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings +// of any length representable in signed long. Based on City and Murmur. +func cityMurmur(s []byte, seed uint128) uint128 { + slen := len(s) + a := seed.lo + b := seed.hi + var c uint64 + var d uint64 + l := slen - 16 + if l <= 0 { // len <= 16 + a = shiftMix(a*k1) * k1 + c = b*k1 + hashLen0to16(s) + if slen >= 8 { + d = shiftMix(a + binary.LittleEndian.Uint64(s[0:0+8])) + } else { + d = shiftMix(a + c) + } + } else { // len > 16 + c = hashLen16(binary.LittleEndian.Uint64(s[slen-8:slen-8+8])+k1, a) + d = hashLen16(b+uint64(slen), c+binary.LittleEndian.Uint64(s[slen-16:slen-16+8])) + a += d + for { + a ^= shiftMix(binary.LittleEndian.Uint64(s[0:0+8])*k1) * k1 + a *= k1 + b ^= a + c ^= shiftMix(binary.LittleEndian.Uint64(s[8:8+8])*k1) * k1 + c *= k1 + d ^= c + s = s[16:] + l -= 16 + if l <= 0 { + break + } + } + } + a = hashLen16(a, c) + b = hashLen16(d, b) + return uint128{a ^ b, hashLen16(b, a)} +} + +func cityHash128WithSeed(s []byte, seed uint128) uint128 { + slen := len(s) + if slen < 128 { + return cityMurmur(s, seed) + } + + endIdx := ((slen - 1) / 128) * 128 + lastBlockIdx := endIdx + ((slen - 1) & 127) - 127 + last := s[lastBlockIdx:] + + // We expect len >= 128 to be the common case. Keep 56 bytes of state: + // v, w, x, y, and z. + var v1, v2 uint64 + var w1, w2 uint64 + x := seed.lo + y := seed.hi + z := uint64(slen) * k1 + v1 = bits.RotateLeft64(y^k1, -49)*k1 + binary.LittleEndian.Uint64(s[0:0+8]) + v2 = bits.RotateLeft64(v1, -42)*k1 + binary.LittleEndian.Uint64(s[8:8+8]) + w1 = bits.RotateLeft64(y+z, -35)*k1 + x + w2 = bits.RotateLeft64(x+binary.LittleEndian.Uint64(s[88:88+8]), -53) * k1 + + // This is the same inner loop as CityHash64(), manually unrolled. + for { + x = bits.RotateLeft64(x+y+v1+binary.LittleEndian.Uint64(s[8:8+8]), -37) * k1 + y = bits.RotateLeft64(y+v2+binary.LittleEndian.Uint64(s[48:48+8]), -42) * k1 + x ^= w2 + y += v1 + binary.LittleEndian.Uint64(s[40:40+8]) + z = bits.RotateLeft64(z+w1, -33) * k1 + v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1) + w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+binary.LittleEndian.Uint64(s[16:16+8])) + z, x = x, z + s = s[64:] + x = bits.RotateLeft64(x+y+v1+binary.LittleEndian.Uint64(s[8:8+8]), -37) * k1 + y = bits.RotateLeft64(y+v2+binary.LittleEndian.Uint64(s[48:48+8]), -42) * k1 + x ^= w2 + y += v1 + binary.LittleEndian.Uint64(s[40:40+8]) + z = bits.RotateLeft64(z+w1, -33) * k1 + v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1) + w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+binary.LittleEndian.Uint64(s[16:16+8])) + z, x = x, z + s = s[64:] + slen -= 128 + if slen < 128 { + break + } + } + x += bits.RotateLeft64(v1+z, -49) * k0 + y = y*k0 + bits.RotateLeft64(w2, -37) + z = z*k0 + bits.RotateLeft64(w1, -27) + w1 *= 9 + v1 *= k0 + // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. + for tailDone := 0; tailDone < slen; { + tailDone += 32 + y = bits.RotateLeft64(x+y, -42)*k0 + v2 + w1 += binary.LittleEndian.Uint64(last[128-tailDone+16 : 128-tailDone+16+8]) + x = x*k0 + w1 + z += w2 + binary.LittleEndian.Uint64(last[128-tailDone:128-tailDone+8]) + w2 += v1 + v1, v2 = weakHashLen32WithSeeds(last[128-tailDone:], v1+z, v2) + v1 *= k0 + } + + // At this point our 56 bytes of state should contain more than + // enough information for a strong 128-bit hash. We use two + // different 56-byte-to-8-byte hashes to get a 16-byte final result. + x = hashLen16(x, v1) + y = hashLen16(y+z, w1) + return uint128{hashLen16(x+v2, w2) + y, + hashLen16(x+w2, y+v2)} +} + +func cityHash128(s []byte) uint128 { + slen := len(s) + if slen >= 16 { + return cityHash128WithSeed(s[16:], uint128{binary.LittleEndian.Uint64(s[0 : 0+8]), binary.LittleEndian.Uint64(s[8:8+8]) + k0}) + } + return cityHash128WithSeed(s, uint128{k0, k1}) +} + +// Fingerprint128 is a 128-bit fingerprint function for byte-slices +func Fingerprint128(s []byte) (lo, hi uint64) { + h := cityHash128(s) + return h.lo, h.hi +} + +// Hash128 is a 128-bit hash function for byte-slices +func Hash128(s []byte) (lo, hi uint64) { + return Fingerprint128(s) +} + +// Hash128WithSeed is a 128-bit hash function for byte-slices and a 128-bit seed +func Hash128WithSeed(s []byte, seed0, seed1 uint64) (lo, hi uint64) { + h := cityHash128WithSeed(s, uint128{seed0, seed1}) + return h.lo, h.hi +} diff --git a/vendor/github.com/dgryski/go-farm/farmhashmk.go b/vendor/github.com/dgryski/go-farm/farmhashmk.go new file mode 100644 index 00000000..8e4c7428 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/farmhashmk.go @@ -0,0 +1,102 @@ +package farm + +import ( + "encoding/binary" + "math/bits" +) + +func hash32Len5to12(s []byte, seed uint32) uint32 { + slen := len(s) + a := uint32(len(s)) + b := uint32(len(s) * 5) + c := uint32(9) + d := b + seed + a += binary.LittleEndian.Uint32(s[0 : 0+4]) + b += binary.LittleEndian.Uint32(s[slen-4 : slen-4+4]) + c += binary.LittleEndian.Uint32(s[((slen >> 1) & 4) : ((slen>>1)&4)+4]) + return fmix(seed ^ mur(c, mur(b, mur(a, d)))) +} + +// Hash32 hashes a byte slice and returns a uint32 hash value +func Hash32(s []byte) uint32 { + + slen := len(s) + + if slen <= 24 { + if slen <= 12 { + if slen <= 4 { + return hash32Len0to4(s, 0) + } + return hash32Len5to12(s, 0) + } + return hash32Len13to24Seed(s, 0) + } + + // len > 24 + h := uint32(slen) + g := c1 * uint32(slen) + f := g + a0 := bits.RotateLeft32(binary.LittleEndian.Uint32(s[slen-4:slen-4+4])*c1, -17) * c2 + a1 := bits.RotateLeft32(binary.LittleEndian.Uint32(s[slen-8:slen-8+4])*c1, -17) * c2 + a2 := bits.RotateLeft32(binary.LittleEndian.Uint32(s[slen-16:slen-16+4])*c1, -17) * c2 + a3 := bits.RotateLeft32(binary.LittleEndian.Uint32(s[slen-12:slen-12+4])*c1, -17) * c2 + a4 := bits.RotateLeft32(binary.LittleEndian.Uint32(s[slen-20:slen-20+4])*c1, -17) * c2 + h ^= a0 + h = bits.RotateLeft32(h, -19) + h = h*5 + 0xe6546b64 + h ^= a2 + h = bits.RotateLeft32(h, -19) + h = h*5 + 0xe6546b64 + g ^= a1 + g = bits.RotateLeft32(g, -19) + g = g*5 + 0xe6546b64 + g ^= a3 + g = bits.RotateLeft32(g, -19) + g = g*5 + 0xe6546b64 + f += a4 + f = bits.RotateLeft32(f, -19) + 113 + for len(s) > 20 { + a := binary.LittleEndian.Uint32(s[0 : 0+4]) + b := binary.LittleEndian.Uint32(s[4 : 4+4]) + c := binary.LittleEndian.Uint32(s[8 : 8+4]) + d := binary.LittleEndian.Uint32(s[12 : 12+4]) + e := binary.LittleEndian.Uint32(s[16 : 16+4]) + h += a + g += b + f += c + h = mur(d, h) + e + g = mur(c, g) + a + f = mur(b+e*c1, f) + d + f += g + g += f + s = s[20:] + } + g = bits.RotateLeft32(g, -11) * c1 + g = bits.RotateLeft32(g, -17) * c1 + f = bits.RotateLeft32(f, -11) * c1 + f = bits.RotateLeft32(f, -17) * c1 + h = bits.RotateLeft32(h+g, -19) + h = h*5 + 0xe6546b64 + h = bits.RotateLeft32(h, -17) * c1 + h = bits.RotateLeft32(h+f, -19) + h = h*5 + 0xe6546b64 + h = bits.RotateLeft32(h, -17) * c1 + return h +} + +// Hash32WithSeed hashes a byte slice and a uint32 seed and returns a uint32 hash value +func Hash32WithSeed(s []byte, seed uint32) uint32 { + slen := len(s) + + if slen <= 24 { + if slen >= 13 { + return hash32Len13to24Seed(s, seed*c1) + } + if slen >= 5 { + return hash32Len5to12(s, seed) + } + return hash32Len0to4(s, seed) + } + h := hash32Len13to24Seed(s[:24], seed^uint32(slen)) + return mur(Hash32(s[24:])+seed, h) +} diff --git a/vendor/github.com/dgryski/go-farm/farmhashna.go b/vendor/github.com/dgryski/go-farm/farmhashna.go new file mode 100644 index 00000000..ac62edd3 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/farmhashna.go @@ -0,0 +1,161 @@ +package farm + +import ( + "encoding/binary" + "math/bits" +) + +func shiftMix(val uint64) uint64 { + return val ^ (val >> 47) +} + +func hashLen16(u, v uint64) uint64 { + return hash128to64(uint128{u, v}) +} + +func hashLen16Mul(u, v, mul uint64) uint64 { + // Murmur-inspired hashing. + a := (u ^ v) * mul + a ^= (a >> 47) + b := (v ^ a) * mul + b ^= (b >> 47) + b *= mul + return b +} + +func hashLen0to16(s []byte) uint64 { + slen := uint64(len(s)) + if slen >= 8 { + mul := k2 + slen*2 + a := binary.LittleEndian.Uint64(s[0:0+8]) + k2 + b := binary.LittleEndian.Uint64(s[int(slen-8) : int(slen-8)+8]) + c := bits.RotateLeft64(b, -37)*mul + a + d := (bits.RotateLeft64(a, -25) + b) * mul + return hashLen16Mul(c, d, mul) + } + + if slen >= 4 { + mul := k2 + slen*2 + a := binary.LittleEndian.Uint32(s[0 : 0+4]) + return hashLen16Mul(slen+(uint64(a)<<3), uint64(binary.LittleEndian.Uint32(s[int(slen-4):int(slen-4)+4])), mul) + } + if slen > 0 { + a := s[0] + b := s[slen>>1] + c := s[slen-1] + y := uint32(a) + (uint32(b) << 8) + z := uint32(slen) + (uint32(c) << 2) + return shiftMix(uint64(y)*k2^uint64(z)*k0) * k2 + } + return k2 +} + +// This probably works well for 16-byte strings as well, but it may be overkill +// in that case. +func hashLen17to32(s []byte) uint64 { + slen := len(s) + mul := k2 + uint64(slen*2) + a := binary.LittleEndian.Uint64(s[0:0+8]) * k1 + b := binary.LittleEndian.Uint64(s[8 : 8+8]) + c := binary.LittleEndian.Uint64(s[slen-8:slen-8+8]) * mul + d := binary.LittleEndian.Uint64(s[slen-16:slen-16+8]) * k2 + return hashLen16Mul(bits.RotateLeft64(a+b, -43)+bits.RotateLeft64(c, -30)+d, a+bits.RotateLeft64(b+k2, -18)+c, mul) +} + +// Return a 16-byte hash for 48 bytes. Quick and dirty. +// Callers do best to use "random-looking" values for a and b. +func weakHashLen32WithSeedsWords(w, x, y, z, a, b uint64) (uint64, uint64) { + a += w + b = bits.RotateLeft64(b+a+z, -21) + c := a + a += x + a += y + b += bits.RotateLeft64(a, -44) + return a + z, b + c +} + +// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. +func weakHashLen32WithSeeds(s []byte, a, b uint64) (uint64, uint64) { + return weakHashLen32WithSeedsWords(binary.LittleEndian.Uint64(s[0:0+8]), + binary.LittleEndian.Uint64(s[8:8+8]), + binary.LittleEndian.Uint64(s[16:16+8]), + binary.LittleEndian.Uint64(s[24:24+8]), + a, + b) +} + +// Return an 8-byte hash for 33 to 64 bytes. +func hashLen33to64(s []byte) uint64 { + slen := len(s) + mul := k2 + uint64(slen)*2 + a := binary.LittleEndian.Uint64(s[0:0+8]) * k2 + b := binary.LittleEndian.Uint64(s[8 : 8+8]) + c := binary.LittleEndian.Uint64(s[slen-8:slen-8+8]) * mul + d := binary.LittleEndian.Uint64(s[slen-16:slen-16+8]) * k2 + y := bits.RotateLeft64(a+b, -43) + bits.RotateLeft64(c, -30) + d + z := hashLen16Mul(y, a+bits.RotateLeft64(b+k2, -18)+c, mul) + e := binary.LittleEndian.Uint64(s[16:16+8]) * mul + f := binary.LittleEndian.Uint64(s[24 : 24+8]) + g := (y + binary.LittleEndian.Uint64(s[slen-32:slen-32+8])) * mul + h := (z + binary.LittleEndian.Uint64(s[slen-24:slen-24+8])) * mul + return hashLen16Mul(bits.RotateLeft64(e+f, -43)+bits.RotateLeft64(g, -30)+h, e+bits.RotateLeft64(f+a, -18)+g, mul) +} + +func naHash64(s []byte) uint64 { + slen := len(s) + var seed uint64 = 81 + if slen <= 32 { + if slen <= 16 { + return hashLen0to16(s) + } + return hashLen17to32(s) + } + if slen <= 64 { + return hashLen33to64(s) + } + // For strings over 64 bytes we loop. + // Internal state consists of 56 bytes: v, w, x, y, and z. + v := uint128{0, 0} + w := uint128{0, 0} + x := seed*k2 + binary.LittleEndian.Uint64(s[0:0+8]) + y := seed*k1 + 113 + z := shiftMix(y*k2+113) * k2 + // Set end so that after the loop we have 1 to 64 bytes left to process. + endIdx := ((slen - 1) / 64) * 64 + last64Idx := endIdx + ((slen - 1) & 63) - 63 + last64 := s[last64Idx:] + for len(s) > 64 { + x = bits.RotateLeft64(x+y+v.lo+binary.LittleEndian.Uint64(s[8:8+8]), -37) * k1 + y = bits.RotateLeft64(y+v.hi+binary.LittleEndian.Uint64(s[48:48+8]), -42) * k1 + x ^= w.hi + y += v.lo + binary.LittleEndian.Uint64(s[40:40+8]) + z = bits.RotateLeft64(z+w.lo, -33) * k1 + v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*k1, x+w.lo) + w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+binary.LittleEndian.Uint64(s[16:16+8])) + x, z = z, x + s = s[64:] + } + mul := k1 + ((z & 0xff) << 1) + // Make s point to the last 64 bytes of input. + s = last64 + w.lo += (uint64(slen-1) & 63) + v.lo += w.lo + w.lo += v.lo + x = bits.RotateLeft64(x+y+v.lo+binary.LittleEndian.Uint64(s[8:8+8]), -37) * mul + y = bits.RotateLeft64(y+v.hi+binary.LittleEndian.Uint64(s[48:48+8]), -42) * mul + x ^= w.hi * 9 + y += v.lo*9 + binary.LittleEndian.Uint64(s[40:40+8]) + z = bits.RotateLeft64(z+w.lo, -33) * mul + v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*mul, x+w.lo) + w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+binary.LittleEndian.Uint64(s[16:16+8])) + x, z = z, x + return hashLen16Mul(hashLen16Mul(v.lo, w.lo, mul)+shiftMix(y)*k0+z, hashLen16Mul(v.hi, w.hi, mul)+x, mul) +} + +func naHash64WithSeed(s []byte, seed uint64) uint64 { + return naHash64WithSeeds(s, k2, seed) +} + +func naHash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 { + return hashLen16(naHash64(s)-seed0, seed1) +} diff --git a/vendor/github.com/dgryski/go-farm/farmhashuo.go b/vendor/github.com/dgryski/go-farm/farmhashuo.go new file mode 100644 index 00000000..474b74e0 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/farmhashuo.go @@ -0,0 +1,122 @@ +package farm + +import ( + "encoding/binary" + "math/bits" +) + +func uoH(x, y, mul uint64, r uint) uint64 { + a := (x ^ y) * mul + a ^= (a >> 47) + b := (y ^ a) * mul + return bits.RotateLeft64(b, -int(r)) * mul +} + +// Hash64WithSeeds hashes a byte slice and two uint64 seeds and returns a uint64 hash value +func Hash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 { + slen := len(s) + if slen <= 64 { + return naHash64WithSeeds(s, seed0, seed1) + } + + // For strings over 64 bytes we loop. + // Internal state consists of 64 bytes: u, v, w, x, y, and z. + x := seed0 + y := seed1*k2 + 113 + z := shiftMix(y*k2) * k2 + v := uint128{seed0, seed1} + var w uint128 + u := x - z + x *= k2 + mul := k2 + (u & 0x82) + + // Set end so that after the loop we have 1 to 64 bytes left to process. + endIdx := ((slen - 1) / 64) * 64 + last64Idx := endIdx + ((slen - 1) & 63) - 63 + last64 := s[last64Idx:] + + for len(s) > 64 { + a0 := binary.LittleEndian.Uint64(s[0 : 0+8]) + a1 := binary.LittleEndian.Uint64(s[8 : 8+8]) + a2 := binary.LittleEndian.Uint64(s[16 : 16+8]) + a3 := binary.LittleEndian.Uint64(s[24 : 24+8]) + a4 := binary.LittleEndian.Uint64(s[32 : 32+8]) + a5 := binary.LittleEndian.Uint64(s[40 : 40+8]) + a6 := binary.LittleEndian.Uint64(s[48 : 48+8]) + a7 := binary.LittleEndian.Uint64(s[56 : 56+8]) + x += a0 + a1 + y += a2 + z += a3 + v.lo += a4 + v.hi += a5 + a1 + w.lo += a6 + w.hi += a7 + + x = bits.RotateLeft64(x, -26) + x *= 9 + y = bits.RotateLeft64(y, -29) + z *= mul + v.lo = bits.RotateLeft64(v.lo, -33) + v.hi = bits.RotateLeft64(v.hi, -30) + w.lo ^= x + w.lo *= 9 + z = bits.RotateLeft64(z, -32) + z += w.hi + w.hi += z + z *= 9 + u, y = y, u + + z += a0 + a6 + v.lo += a2 + v.hi += a3 + w.lo += a4 + w.hi += a5 + a6 + x += a1 + y += a7 + + y += v.lo + v.lo += x - y + v.hi += w.lo + w.lo += v.hi + w.hi += x - y + x += w.hi + w.hi = bits.RotateLeft64(w.hi, -34) + u, z = z, u + s = s[64:] + } + // Make s point to the last 64 bytes of input. + s = last64 + u *= 9 + v.hi = bits.RotateLeft64(v.hi, -28) + v.lo = bits.RotateLeft64(v.lo, -20) + w.lo += (uint64(slen-1) & 63) + u += y + y += u + x = bits.RotateLeft64(y-x+v.lo+binary.LittleEndian.Uint64(s[8:8+8]), -37) * mul + y = bits.RotateLeft64(y^v.hi^binary.LittleEndian.Uint64(s[48:48+8]), -42) * mul + x ^= w.hi * 9 + y += v.lo + binary.LittleEndian.Uint64(s[40:40+8]) + z = bits.RotateLeft64(z+w.lo, -33) * mul + v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*mul, x+w.lo) + w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+binary.LittleEndian.Uint64(s[16:16+8])) + return uoH(hashLen16Mul(v.lo+x, w.lo^y, mul)+z-u, + uoH(v.hi+y, w.hi+z, k2, 30)^x, + k2, + 31) +} + +// Hash64WithSeed hashes a byte slice and a uint64 seed and returns a uint64 hash value +func Hash64WithSeed(s []byte, seed uint64) uint64 { + if len(s) <= 64 { + return naHash64WithSeed(s, seed) + } + return Hash64WithSeeds(s, 0, seed) +} + +// Hash64 hashes a byte slice and returns a uint64 hash value +func Hash64(s []byte) uint64 { + if len(s) <= 64 { + return naHash64(s) + } + return Hash64WithSeeds(s, 81, 0) +} diff --git a/vendor/github.com/dgryski/go-farm/fp_amd64.s b/vendor/github.com/dgryski/go-farm/fp_amd64.s new file mode 100644 index 00000000..2b8fa324 --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/fp_amd64.s @@ -0,0 +1,951 @@ +// Code generated by command: go run asm.go -out=fp_amd64.s -go111=false. DO NOT EDIT. + +// +build amd64,!purego + +#include "textflag.h" + +// func Fingerprint64(s []byte) uint64 +TEXT ·Fingerprint64(SB), NOSPLIT, $0-32 + MOVQ s_base+0(FP), CX + MOVQ s_len+8(FP), AX + CMPQ AX, $0x10 + JG check32 + CMPQ AX, $0x08 + JL check4 + MOVQ (CX), DX + MOVQ AX, BX + SUBQ $0x08, BX + ADDQ CX, BX + MOVQ (BX), BX + MOVQ $0x9ae16a3b2f90404f, BP + ADDQ BP, DX + SHLQ $0x01, AX + ADDQ BP, AX + MOVQ BX, BP + RORQ $0x25, BP + IMULQ AX, BP + ADDQ DX, BP + RORQ $0x19, DX + ADDQ BX, DX + IMULQ AX, DX + XORQ DX, BP + IMULQ AX, BP + MOVQ BP, BX + SHRQ $0x2f, BX + XORQ BP, BX + XORQ BX, DX + IMULQ AX, DX + MOVQ DX, BX + SHRQ $0x2f, BX + XORQ DX, BX + IMULQ AX, BX + MOVQ BX, ret+24(FP) + RET + +check4: + CMPQ AX, $0x04 + JL check0 + MOVQ $0x9ae16a3b2f90404f, DX + MOVQ AX, BX + SHLQ $0x01, BX + ADDQ DX, BX + MOVL (CX), SI + SHLQ $0x03, SI + ADDQ AX, SI + SUBQ $0x04, AX + ADDQ AX, CX + MOVL (CX), DI + XORQ DI, SI + IMULQ BX, SI + MOVQ SI, DX + SHRQ $0x2f, DX + XORQ SI, DX + XORQ DX, DI + IMULQ BX, DI + MOVQ DI, DX + SHRQ $0x2f, DX + XORQ DI, DX + IMULQ BX, DX + MOVQ DX, ret+24(FP) + RET + +check0: + TESTQ AX, AX + JZ empty + MOVBQZX (CX), DX + MOVQ AX, BX + SHRQ $0x01, BX + ADDQ CX, BX + MOVBQZX (BX), BP + MOVQ AX, BX + SUBQ $0x01, BX + ADDQ CX, BX + MOVBQZX (BX), BX + SHLQ $0x08, BP + ADDQ BP, DX + SHLQ $0x02, BX + ADDQ BX, AX + MOVQ $0xc3a5c85c97cb3127, BX + IMULQ BX, AX + MOVQ $0x9ae16a3b2f90404f, BX + IMULQ BX, DX + XORQ DX, AX + MOVQ AX, DX + SHRQ $0x2f, DX + XORQ AX, DX + IMULQ BX, DX + MOVQ DX, ret+24(FP) + RET + +empty: + MOVQ $0x9ae16a3b2f90404f, DX + MOVQ DX, ret+24(FP) + RET + +check32: + CMPQ AX, $0x20 + JG check64 + MOVQ AX, DX + SHLQ $0x01, DX + MOVQ $0x9ae16a3b2f90404f, BX + ADDQ BX, DX + MOVQ (CX), BP + MOVQ $0xb492b66fbe98f273, SI + IMULQ SI, BP + MOVQ 8(CX), SI + MOVQ AX, DI + SUBQ $0x10, DI + ADDQ CX, DI + MOVQ 8(DI), R12 + IMULQ DX, R12 + MOVQ (DI), DI + IMULQ BX, DI + MOVQ BP, R13 + ADDQ SI, R13 + RORQ $0x2b, R13 + ADDQ DI, R13 + MOVQ R12, DI + RORQ $0x1e, DI + ADDQ DI, R13 + ADDQ R12, BP + ADDQ BX, SI + RORQ $0x12, SI + ADDQ SI, BP + XORQ BP, R13 + IMULQ DX, R13 + MOVQ R13, BX + SHRQ $0x2f, BX + XORQ R13, BX + XORQ BX, BP + IMULQ DX, BP + MOVQ BP, BX + SHRQ $0x2f, BX + XORQ BP, BX + IMULQ DX, BX + MOVQ BX, ret+24(FP) + RET + +check64: + CMPQ AX, $0x40 + JG long + MOVQ AX, DX + SHLQ $0x01, DX + MOVQ $0x9ae16a3b2f90404f, BX + ADDQ BX, DX + MOVQ (CX), BP + IMULQ BX, BP + MOVQ 8(CX), SI + MOVQ AX, DI + SUBQ $0x10, DI + ADDQ CX, DI + MOVQ 8(DI), R12 + IMULQ DX, R12 + MOVQ (DI), DI + IMULQ BX, DI + MOVQ BP, R13 + ADDQ SI, R13 + RORQ $0x2b, R13 + ADDQ DI, R13 + MOVQ R12, DI + RORQ $0x1e, DI + ADDQ DI, R13 + ADDQ BP, R12 + ADDQ BX, SI + RORQ $0x12, SI + ADDQ SI, R12 + MOVQ R13, BX + XORQ R12, BX + IMULQ DX, BX + MOVQ BX, SI + SHRQ $0x2f, SI + XORQ BX, SI + XORQ SI, R12 + IMULQ DX, R12 + MOVQ R12, BX + SHRQ $0x2f, BX + XORQ R12, BX + IMULQ DX, BX + MOVQ 16(CX), SI + IMULQ DX, SI + MOVQ 24(CX), DI + MOVQ AX, R12 + SUBQ $0x20, R12 + ADDQ CX, R12 + MOVQ (R12), R14 + ADDQ R13, R14 + IMULQ DX, R14 + MOVQ 8(R12), R12 + ADDQ BX, R12 + IMULQ DX, R12 + MOVQ SI, BX + ADDQ DI, BX + RORQ $0x2b, BX + ADDQ R12, BX + MOVQ R14, R12 + RORQ $0x1e, R12 + ADDQ R12, BX + ADDQ R14, SI + ADDQ BP, DI + RORQ $0x12, DI + ADDQ DI, SI + XORQ SI, BX + IMULQ DX, BX + MOVQ BX, BP + SHRQ $0x2f, BP + XORQ BX, BP + XORQ BP, SI + IMULQ DX, SI + MOVQ SI, BX + SHRQ $0x2f, BX + XORQ SI, BX + IMULQ DX, BX + MOVQ BX, ret+24(FP) + RET + +long: + XORQ R8, R8 + XORQ R9, R9 + XORQ R10, R10 + XORQ R11, R11 + MOVQ $0x01529cba0ca458ff, DX + ADDQ (CX), DX + MOVQ $0x226bb95b4e64b6d4, BX + MOVQ $0x134a747f856d0526, BP + MOVQ AX, SI + SUBQ $0x01, SI + MOVQ $0xffffffffffffffc0, DI + ANDQ DI, SI + MOVQ AX, DI + SUBQ $0x01, DI + ANDQ $0x3f, DI + SUBQ $0x3f, DI + ADDQ SI, DI + MOVQ DI, SI + ADDQ CX, SI + MOVQ AX, DI + +loop: + MOVQ $0xb492b66fbe98f273, R12 + ADDQ BX, DX + ADDQ R8, DX + ADDQ 8(CX), DX + RORQ $0x25, DX + IMULQ R12, DX + ADDQ R9, BX + ADDQ 48(CX), BX + RORQ $0x2a, BX + IMULQ R12, BX + XORQ R11, DX + ADDQ R8, BX + ADDQ 40(CX), BX + ADDQ R10, BP + RORQ $0x21, BP + IMULQ R12, BP + IMULQ R12, R9 + MOVQ DX, R8 + ADDQ R10, R8 + ADDQ (CX), R9 + ADDQ R9, R8 + ADDQ 24(CX), R8 + RORQ $0x15, R8 + MOVQ R9, R10 + ADDQ 8(CX), R9 + ADDQ 16(CX), R9 + MOVQ R9, R13 + RORQ $0x2c, R13 + ADDQ R13, R8 + ADDQ 24(CX), R9 + ADDQ R10, R8 + XCHGQ R9, R8 + ADDQ BP, R11 + MOVQ BX, R10 + ADDQ 16(CX), R10 + ADDQ 32(CX), R11 + ADDQ R11, R10 + ADDQ 56(CX), R10 + RORQ $0x15, R10 + MOVQ R11, R13 + ADDQ 40(CX), R11 + ADDQ 48(CX), R11 + MOVQ R11, R14 + RORQ $0x2c, R14 + ADDQ R14, R10 + ADDQ 56(CX), R11 + ADDQ R13, R10 + XCHGQ R11, R10 + XCHGQ BP, DX + ADDQ $0x40, CX + SUBQ $0x40, DI + CMPQ DI, $0x40 + JG loop + MOVQ SI, CX + MOVQ BP, DI + ANDQ $0xff, DI + SHLQ $0x01, DI + ADDQ R12, DI + MOVQ SI, CX + SUBQ $0x01, AX + ANDQ $0x3f, AX + ADDQ AX, R10 + ADDQ R10, R8 + ADDQ R8, R10 + ADDQ BX, DX + ADDQ R8, DX + ADDQ 8(CX), DX + RORQ $0x25, DX + IMULQ DI, DX + ADDQ R9, BX + ADDQ 48(CX), BX + RORQ $0x2a, BX + IMULQ DI, BX + MOVQ $0x00000009, AX + IMULQ R11, AX + XORQ AX, DX + MOVQ $0x00000009, AX + IMULQ R8, AX + ADDQ AX, BX + ADDQ 40(CX), BX + ADDQ R10, BP + RORQ $0x21, BP + IMULQ DI, BP + IMULQ DI, R9 + MOVQ DX, R8 + ADDQ R10, R8 + ADDQ (CX), R9 + ADDQ R9, R8 + ADDQ 24(CX), R8 + RORQ $0x15, R8 + MOVQ R9, AX + ADDQ 8(CX), R9 + ADDQ 16(CX), R9 + MOVQ R9, SI + RORQ $0x2c, SI + ADDQ SI, R8 + ADDQ 24(CX), R9 + ADDQ AX, R8 + XCHGQ R9, R8 + ADDQ BP, R11 + MOVQ BX, R10 + ADDQ 16(CX), R10 + ADDQ 32(CX), R11 + ADDQ R11, R10 + ADDQ 56(CX), R10 + RORQ $0x15, R10 + MOVQ R11, AX + ADDQ 40(CX), R11 + ADDQ 48(CX), R11 + MOVQ R11, SI + RORQ $0x2c, SI + ADDQ SI, R10 + ADDQ 56(CX), R11 + ADDQ AX, R10 + XCHGQ R11, R10 + XCHGQ BP, DX + XORQ R10, R8 + IMULQ DI, R8 + MOVQ R8, AX + SHRQ $0x2f, AX + XORQ R8, AX + XORQ AX, R10 + IMULQ DI, R10 + MOVQ R10, AX + SHRQ $0x2f, AX + XORQ R10, AX + IMULQ DI, AX + ADDQ BP, AX + MOVQ BX, CX + SHRQ $0x2f, CX + XORQ BX, CX + MOVQ $0xc3a5c85c97cb3127, BX + IMULQ BX, CX + ADDQ CX, AX + XORQ R11, R9 + IMULQ DI, R9 + MOVQ R9, CX + SHRQ $0x2f, CX + XORQ R9, CX + XORQ CX, R11 + IMULQ DI, R11 + MOVQ R11, CX + SHRQ $0x2f, CX + XORQ R11, CX + IMULQ DI, CX + ADDQ DX, CX + XORQ CX, AX + IMULQ DI, AX + MOVQ AX, DX + SHRQ $0x2f, DX + XORQ AX, DX + XORQ DX, CX + IMULQ DI, CX + MOVQ CX, AX + SHRQ $0x2f, AX + XORQ CX, AX + IMULQ DI, AX + MOVQ AX, ret+24(FP) + RET + +// func Fingerprint32(s []byte) uint32 +TEXT ·Fingerprint32(SB), NOSPLIT, $0-28 + MOVQ s_base+0(FP), AX + MOVQ s_len+8(FP), CX + CMPQ CX, $0x18 + JG long + CMPQ CX, $0x0c + JG hash_13_24 + CMPQ CX, $0x04 + JG hash_5_12 + XORL DX, DX + MOVL $0x00000009, BX + TESTQ CX, CX + JZ done + MOVQ CX, BP + MOVL $0xcc9e2d51, DI + IMULL DI, DX + MOVBLSX (AX), SI + ADDL SI, DX + XORL DX, BX + SUBQ $0x01, BP + TESTQ BP, BP + JZ done + IMULL DI, DX + MOVBLSX 1(AX), SI + ADDL SI, DX + XORL DX, BX + SUBQ $0x01, BP + TESTQ BP, BP + JZ done + IMULL DI, DX + MOVBLSX 2(AX), SI + ADDL SI, DX + XORL DX, BX + SUBQ $0x01, BP + TESTQ BP, BP + JZ done + IMULL DI, DX + MOVBLSX 3(AX), SI + ADDL SI, DX + XORL DX, BX + SUBQ $0x01, BP + TESTQ BP, BP + JZ done + +done: + MOVL CX, BP + MOVL $0xcc9e2d51, SI + IMULL SI, BP + RORL $0x11, BP + MOVL $0x1b873593, SI + IMULL SI, BP + XORL BP, BX + RORL $0x13, BX + LEAL (BX)(BX*4), BP + LEAL 3864292196(BP), BX + MOVL $0xcc9e2d51, BP + IMULL BP, DX + RORL $0x11, DX + MOVL $0x1b873593, BP + IMULL BP, DX + XORL DX, BX + RORL $0x13, BX + LEAL (BX)(BX*4), DX + LEAL 3864292196(DX), BX + MOVL BX, DX + SHRL $0x10, DX + XORL DX, BX + MOVL $0x85ebca6b, DX + IMULL DX, BX + MOVL BX, DX + SHRL $0x0d, DX + XORL DX, BX + MOVL $0xc2b2ae35, DX + IMULL DX, BX + MOVL BX, DX + SHRL $0x10, DX + XORL DX, BX + MOVL BX, ret+24(FP) + RET + +hash_5_12: + MOVL CX, DX + MOVL DX, BX + SHLL $0x02, BX + ADDL DX, BX + MOVL $0x00000009, BP + MOVL BX, SI + ADDL (AX), DX + MOVQ CX, DI + SUBQ $0x04, DI + ADDQ AX, DI + ADDL (DI), BX + MOVQ CX, DI + SHRQ $0x01, DI + ANDQ $0x04, DI + ADDQ AX, DI + ADDL (DI), BP + MOVL $0xcc9e2d51, DI + IMULL DI, DX + RORL $0x11, DX + MOVL $0x1b873593, DI + IMULL DI, DX + XORL DX, SI + RORL $0x13, SI + LEAL (SI)(SI*4), DX + LEAL 3864292196(DX), SI + MOVL $0xcc9e2d51, DX + IMULL DX, BX + RORL $0x11, BX + MOVL $0x1b873593, DX + IMULL DX, BX + XORL BX, SI + RORL $0x13, SI + LEAL (SI)(SI*4), BX + LEAL 3864292196(BX), SI + MOVL $0xcc9e2d51, DX + IMULL DX, BP + RORL $0x11, BP + MOVL $0x1b873593, DX + IMULL DX, BP + XORL BP, SI + RORL $0x13, SI + LEAL (SI)(SI*4), BP + LEAL 3864292196(BP), SI + MOVL SI, DX + SHRL $0x10, DX + XORL DX, SI + MOVL $0x85ebca6b, DX + IMULL DX, SI + MOVL SI, DX + SHRL $0x0d, DX + XORL DX, SI + MOVL $0xc2b2ae35, DX + IMULL DX, SI + MOVL SI, DX + SHRL $0x10, DX + XORL DX, SI + MOVL SI, ret+24(FP) + RET + +hash_13_24: + MOVQ CX, DX + SHRQ $0x01, DX + ADDQ AX, DX + MOVL -4(DX), BX + MOVL 4(AX), BP + MOVQ CX, SI + ADDQ AX, SI + MOVL -8(SI), DI + MOVL (DX), DX + MOVL (AX), R8 + MOVL -4(SI), SI + MOVL $0xcc9e2d51, R9 + IMULL DX, R9 + ADDL CX, R9 + RORL $0x0c, BX + ADDL SI, BX + MOVL DI, R10 + MOVL $0xcc9e2d51, R11 + IMULL R11, R10 + RORL $0x11, R10 + MOVL $0x1b873593, R11 + IMULL R11, R10 + XORL R10, R9 + RORL $0x13, R9 + LEAL (R9)(R9*4), R10 + LEAL 3864292196(R10), R9 + ADDL BX, R9 + RORL $0x03, BX + ADDL DI, BX + MOVL $0xcc9e2d51, DI + IMULL DI, R8 + RORL $0x11, R8 + MOVL $0x1b873593, DI + IMULL DI, R8 + XORL R8, R9 + RORL $0x13, R9 + LEAL (R9)(R9*4), R8 + LEAL 3864292196(R8), R9 + ADDL BX, R9 + ADDL SI, BX + RORL $0x0c, BX + ADDL DX, BX + MOVL $0xcc9e2d51, DX + IMULL DX, BP + RORL $0x11, BP + MOVL $0x1b873593, DX + IMULL DX, BP + XORL BP, R9 + RORL $0x13, R9 + LEAL (R9)(R9*4), BP + LEAL 3864292196(BP), R9 + ADDL BX, R9 + MOVL R9, DX + SHRL $0x10, DX + XORL DX, R9 + MOVL $0x85ebca6b, DX + IMULL DX, R9 + MOVL R9, DX + SHRL $0x0d, DX + XORL DX, R9 + MOVL $0xc2b2ae35, DX + IMULL DX, R9 + MOVL R9, DX + SHRL $0x10, DX + XORL DX, R9 + MOVL R9, ret+24(FP) + RET + +long: + MOVL CX, DX + MOVL $0xcc9e2d51, BX + IMULL DX, BX + MOVL BX, BP + MOVQ CX, SI + ADDQ AX, SI + MOVL $0xcc9e2d51, DI + MOVL $0x1b873593, R8 + MOVL -4(SI), R9 + IMULL DI, R9 + RORL $0x11, R9 + IMULL R8, R9 + XORL R9, DX + RORL $0x13, DX + MOVL DX, R9 + SHLL $0x02, R9 + ADDL R9, DX + ADDL $0xe6546b64, DX + MOVL -8(SI), R9 + IMULL DI, R9 + RORL $0x11, R9 + IMULL R8, R9 + XORL R9, BX + RORL $0x13, BX + MOVL BX, R9 + SHLL $0x02, R9 + ADDL R9, BX + ADDL $0xe6546b64, BX + MOVL -16(SI), R9 + IMULL DI, R9 + RORL $0x11, R9 + IMULL R8, R9 + XORL R9, DX + RORL $0x13, DX + MOVL DX, R9 + SHLL $0x02, R9 + ADDL R9, DX + ADDL $0xe6546b64, DX + MOVL -12(SI), R9 + IMULL DI, R9 + RORL $0x11, R9 + IMULL R8, R9 + XORL R9, BX + RORL $0x13, BX + MOVL BX, R9 + SHLL $0x02, R9 + ADDL R9, BX + ADDL $0xe6546b64, BX + PREFETCHT0 (AX) + MOVL -20(SI), SI + IMULL DI, SI + RORL $0x11, SI + IMULL R8, SI + ADDL SI, BP + RORL $0x13, BP + ADDL $0x71, BP + +loop80: + CMPQ CX, $0x64 + JL loop20 + PREFETCHT0 20(AX) + MOVL (AX), SI + ADDL SI, DX + MOVL 4(AX), DI + ADDL DI, BX + MOVL 8(AX), R8 + ADDL R8, BP + MOVL 12(AX), R9 + MOVL R9, R11 + MOVL $0xcc9e2d51, R10 + IMULL R10, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R10 + IMULL R10, R11 + XORL R11, DX + RORL $0x13, DX + LEAL (DX)(DX*4), R11 + LEAL 3864292196(R11), DX + MOVL 16(AX), R10 + ADDL R10, DX + MOVL R8, R11 + MOVL $0xcc9e2d51, R8 + IMULL R8, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R8 + IMULL R8, R11 + XORL R11, BX + RORL $0x13, BX + LEAL (BX)(BX*4), R11 + LEAL 3864292196(R11), BX + ADDL SI, BX + MOVL $0xcc9e2d51, SI + IMULL SI, R10 + MOVL R10, R11 + ADDL DI, R11 + MOVL $0xcc9e2d51, SI + IMULL SI, R11 + RORL $0x11, R11 + MOVL $0x1b873593, SI + IMULL SI, R11 + XORL R11, BP + RORL $0x13, BP + LEAL (BP)(BP*4), R11 + LEAL 3864292196(R11), BP + ADDL R9, BP + ADDL BX, BP + ADDL BP, BX + PREFETCHT0 40(AX) + MOVL 20(AX), SI + ADDL SI, DX + MOVL 24(AX), DI + ADDL DI, BX + MOVL 28(AX), R8 + ADDL R8, BP + MOVL 32(AX), R9 + MOVL R9, R11 + MOVL $0xcc9e2d51, R10 + IMULL R10, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R10 + IMULL R10, R11 + XORL R11, DX + RORL $0x13, DX + LEAL (DX)(DX*4), R11 + LEAL 3864292196(R11), DX + MOVL 36(AX), R10 + ADDL R10, DX + MOVL R8, R11 + MOVL $0xcc9e2d51, R8 + IMULL R8, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R8 + IMULL R8, R11 + XORL R11, BX + RORL $0x13, BX + LEAL (BX)(BX*4), R11 + LEAL 3864292196(R11), BX + ADDL SI, BX + MOVL $0xcc9e2d51, SI + IMULL SI, R10 + MOVL R10, R11 + ADDL DI, R11 + MOVL $0xcc9e2d51, SI + IMULL SI, R11 + RORL $0x11, R11 + MOVL $0x1b873593, SI + IMULL SI, R11 + XORL R11, BP + RORL $0x13, BP + LEAL (BP)(BP*4), R11 + LEAL 3864292196(R11), BP + ADDL R9, BP + ADDL BX, BP + ADDL BP, BX + PREFETCHT0 60(AX) + MOVL 40(AX), SI + ADDL SI, DX + MOVL 44(AX), DI + ADDL DI, BX + MOVL 48(AX), R8 + ADDL R8, BP + MOVL 52(AX), R9 + MOVL R9, R11 + MOVL $0xcc9e2d51, R10 + IMULL R10, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R10 + IMULL R10, R11 + XORL R11, DX + RORL $0x13, DX + LEAL (DX)(DX*4), R11 + LEAL 3864292196(R11), DX + MOVL 56(AX), R10 + ADDL R10, DX + MOVL R8, R11 + MOVL $0xcc9e2d51, R8 + IMULL R8, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R8 + IMULL R8, R11 + XORL R11, BX + RORL $0x13, BX + LEAL (BX)(BX*4), R11 + LEAL 3864292196(R11), BX + ADDL SI, BX + MOVL $0xcc9e2d51, SI + IMULL SI, R10 + MOVL R10, R11 + ADDL DI, R11 + MOVL $0xcc9e2d51, SI + IMULL SI, R11 + RORL $0x11, R11 + MOVL $0x1b873593, SI + IMULL SI, R11 + XORL R11, BP + RORL $0x13, BP + LEAL (BP)(BP*4), R11 + LEAL 3864292196(R11), BP + ADDL R9, BP + ADDL BX, BP + ADDL BP, BX + PREFETCHT0 80(AX) + MOVL 60(AX), SI + ADDL SI, DX + MOVL 64(AX), DI + ADDL DI, BX + MOVL 68(AX), R8 + ADDL R8, BP + MOVL 72(AX), R9 + MOVL R9, R11 + MOVL $0xcc9e2d51, R10 + IMULL R10, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R10 + IMULL R10, R11 + XORL R11, DX + RORL $0x13, DX + LEAL (DX)(DX*4), R11 + LEAL 3864292196(R11), DX + MOVL 76(AX), R10 + ADDL R10, DX + MOVL R8, R11 + MOVL $0xcc9e2d51, R8 + IMULL R8, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R8 + IMULL R8, R11 + XORL R11, BX + RORL $0x13, BX + LEAL (BX)(BX*4), R11 + LEAL 3864292196(R11), BX + ADDL SI, BX + MOVL $0xcc9e2d51, SI + IMULL SI, R10 + MOVL R10, R11 + ADDL DI, R11 + MOVL $0xcc9e2d51, SI + IMULL SI, R11 + RORL $0x11, R11 + MOVL $0x1b873593, SI + IMULL SI, R11 + XORL R11, BP + RORL $0x13, BP + LEAL (BP)(BP*4), R11 + LEAL 3864292196(R11), BP + ADDL R9, BP + ADDL BX, BP + ADDL BP, BX + ADDQ $0x50, AX + SUBQ $0x50, CX + JMP loop80 + +loop20: + CMPQ CX, $0x14 + JLE after + MOVL (AX), SI + ADDL SI, DX + MOVL 4(AX), DI + ADDL DI, BX + MOVL 8(AX), R8 + ADDL R8, BP + MOVL 12(AX), R9 + MOVL R9, R11 + MOVL $0xcc9e2d51, R10 + IMULL R10, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R10 + IMULL R10, R11 + XORL R11, DX + RORL $0x13, DX + LEAL (DX)(DX*4), R11 + LEAL 3864292196(R11), DX + MOVL 16(AX), R10 + ADDL R10, DX + MOVL R8, R11 + MOVL $0xcc9e2d51, R8 + IMULL R8, R11 + RORL $0x11, R11 + MOVL $0x1b873593, R8 + IMULL R8, R11 + XORL R11, BX + RORL $0x13, BX + LEAL (BX)(BX*4), R11 + LEAL 3864292196(R11), BX + ADDL SI, BX + MOVL $0xcc9e2d51, SI + IMULL SI, R10 + MOVL R10, R11 + ADDL DI, R11 + MOVL $0xcc9e2d51, SI + IMULL SI, R11 + RORL $0x11, R11 + MOVL $0x1b873593, SI + IMULL SI, R11 + XORL R11, BP + RORL $0x13, BP + LEAL (BP)(BP*4), R11 + LEAL 3864292196(R11), BP + ADDL R9, BP + ADDL BX, BP + ADDL BP, BX + ADDQ $0x14, AX + SUBQ $0x14, CX + JMP loop20 + +after: + MOVL $0xcc9e2d51, AX + RORL $0x0b, BX + IMULL AX, BX + RORL $0x11, BX + IMULL AX, BX + RORL $0x0b, BP + IMULL AX, BP + RORL $0x11, BP + IMULL AX, BP + ADDL BX, DX + RORL $0x13, DX + MOVL DX, CX + SHLL $0x02, CX + ADDL CX, DX + ADDL $0xe6546b64, DX + RORL $0x11, DX + IMULL AX, DX + ADDL BP, DX + RORL $0x13, DX + MOVL DX, CX + SHLL $0x02, CX + ADDL CX, DX + ADDL $0xe6546b64, DX + RORL $0x11, DX + IMULL AX, DX + MOVL DX, ret+24(FP) + RET diff --git a/vendor/github.com/dgryski/go-farm/fp_generic.go b/vendor/github.com/dgryski/go-farm/fp_generic.go new file mode 100644 index 00000000..2cfa1b9d --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/fp_generic.go @@ -0,0 +1,13 @@ +// +build !amd64 purego + +package farm + +// Fingerprint64 is a 64-bit fingerprint function for byte-slices +func Fingerprint64(s []byte) uint64 { + return naHash64(s) +} + +// Fingerprint32 is a 32-bit fingerprint function for byte-slices +func Fingerprint32(s []byte) uint32 { + return Hash32(s) +} diff --git a/vendor/github.com/dgryski/go-farm/fp_stub.go b/vendor/github.com/dgryski/go-farm/fp_stub.go new file mode 100644 index 00000000..94fff8de --- /dev/null +++ b/vendor/github.com/dgryski/go-farm/fp_stub.go @@ -0,0 +1,9 @@ +// Code generated by command: go run asm.go -out=fp_amd64.s -stubs=fp_stub.go. DO NOT EDIT. + +// +build amd64,!purego + +package farm + +func Fingerprint64(s []byte) uint64 + +func Fingerprint32(s []byte) uint32 diff --git a/vendor/github.com/dustin/go-humanize/.travis.yml b/vendor/github.com/dustin/go-humanize/.travis.yml new file mode 100644 index 00000000..ba95cdd1 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/.travis.yml @@ -0,0 +1,21 @@ +sudo: false +language: go +go: + - 1.3.x + - 1.5.x + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - master +matrix: + allow_failures: + - go: master + fast_finish: true +install: + - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). +script: + - go get -t -v ./... + - diff -u <(echo -n) <(gofmt -d -s .) + - go tool vet . + - go test -v -race ./... diff --git a/vendor/github.com/dustin/go-humanize/LICENSE b/vendor/github.com/dustin/go-humanize/LICENSE new file mode 100644 index 00000000..8d9a94a9 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2005-2008 Dustin Sallings + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/vendor/github.com/dustin/go-humanize/README.markdown b/vendor/github.com/dustin/go-humanize/README.markdown new file mode 100644 index 00000000..91b4ae56 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/README.markdown @@ -0,0 +1,124 @@ +# Humane Units [![Build Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize) [![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize) + +Just a few functions for helping humanize times and sizes. + +`go get` it as `github.com/dustin/go-humanize`, import it as +`"github.com/dustin/go-humanize"`, use it as `humanize`. + +See [godoc](https://godoc.org/github.com/dustin/go-humanize) for +complete documentation. + +## Sizes + +This lets you take numbers like `82854982` and convert them to useful +strings like, `83 MB` or `79 MiB` (whichever you prefer). + +Example: + +```go +fmt.Printf("That file is %s.", humanize.Bytes(82854982)) // That file is 83 MB. +``` + +## Times + +This lets you take a `time.Time` and spit it out in relative terms. +For example, `12 seconds ago` or `3 days from now`. + +Example: + +```go +fmt.Printf("This was touched %s.", humanize.Time(someTimeInstance)) // This was touched 7 hours ago. +``` + +Thanks to Kyle Lemons for the time implementation from an IRC +conversation one day. It's pretty neat. + +## Ordinals + +From a [mailing list discussion][odisc] where a user wanted to be able +to label ordinals. + + 0 -> 0th + 1 -> 1st + 2 -> 2nd + 3 -> 3rd + 4 -> 4th + [...] + +Example: + +```go +fmt.Printf("You're my %s best friend.", humanize.Ordinal(193)) // You are my 193rd best friend. +``` + +## Commas + +Want to shove commas into numbers? Be my guest. + + 0 -> 0 + 100 -> 100 + 1000 -> 1,000 + 1000000000 -> 1,000,000,000 + -100000 -> -100,000 + +Example: + +```go +fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) // You owe $6,582,491. +``` + +## Ftoa + +Nicer float64 formatter that removes trailing zeros. + +```go +fmt.Printf("%f", 2.24) // 2.240000 +fmt.Printf("%s", humanize.Ftoa(2.24)) // 2.24 +fmt.Printf("%f", 2.0) // 2.000000 +fmt.Printf("%s", humanize.Ftoa(2.0)) // 2 +``` + +## SI notation + +Format numbers with [SI notation][sinotation]. + +Example: + +```go +humanize.SI(0.00000000223, "M") // 2.23 nM +``` + +## English-specific functions + +The following functions are in the `humanize/english` subpackage. + +### Plurals + +Simple English pluralization + +```go +english.PluralWord(1, "object", "") // object +english.PluralWord(42, "object", "") // objects +english.PluralWord(2, "bus", "") // buses +english.PluralWord(99, "locus", "loci") // loci + +english.Plural(1, "object", "") // 1 object +english.Plural(42, "object", "") // 42 objects +english.Plural(2, "bus", "") // 2 buses +english.Plural(99, "locus", "loci") // 99 loci +``` + +### Word series + +Format comma-separated words lists with conjuctions: + +```go +english.WordSeries([]string{"foo"}, "and") // foo +english.WordSeries([]string{"foo", "bar"}, "and") // foo and bar +english.WordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar and baz + +english.OxfordWordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar, and baz +``` + +[odisc]: https://groups.google.com/d/topic/golang-nuts/l8NhI74jl-4/discussion +[sinotation]: http://en.wikipedia.org/wiki/Metric_prefix diff --git a/vendor/github.com/dustin/go-humanize/big.go b/vendor/github.com/dustin/go-humanize/big.go new file mode 100644 index 00000000..f49dc337 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/big.go @@ -0,0 +1,31 @@ +package humanize + +import ( + "math/big" +) + +// order of magnitude (to a max order) +func oomm(n, b *big.Int, maxmag int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + if mag == maxmag && maxmag >= 0 { + break + } + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} + +// total order of magnitude +// (same as above, but with no upper limit) +func oom(n, b *big.Int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} diff --git a/vendor/github.com/dustin/go-humanize/bigbytes.go b/vendor/github.com/dustin/go-humanize/bigbytes.go new file mode 100644 index 00000000..1a2bf617 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bigbytes.go @@ -0,0 +1,173 @@ +package humanize + +import ( + "fmt" + "math/big" + "strings" + "unicode" +) + +var ( + bigIECExp = big.NewInt(1024) + + // BigByte is one byte in bit.Ints + BigByte = big.NewInt(1) + // BigKiByte is 1,024 bytes in bit.Ints + BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp) + // BigMiByte is 1,024 k bytes in bit.Ints + BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp) + // BigGiByte is 1,024 m bytes in bit.Ints + BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp) + // BigTiByte is 1,024 g bytes in bit.Ints + BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp) + // BigPiByte is 1,024 t bytes in bit.Ints + BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp) + // BigEiByte is 1,024 p bytes in bit.Ints + BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp) + // BigZiByte is 1,024 e bytes in bit.Ints + BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp) + // BigYiByte is 1,024 z bytes in bit.Ints + BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp) +) + +var ( + bigSIExp = big.NewInt(1000) + + // BigSIByte is one SI byte in big.Ints + BigSIByte = big.NewInt(1) + // BigKByte is 1,000 SI bytes in big.Ints + BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp) + // BigMByte is 1,000 SI k bytes in big.Ints + BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp) + // BigGByte is 1,000 SI m bytes in big.Ints + BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp) + // BigTByte is 1,000 SI g bytes in big.Ints + BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp) + // BigPByte is 1,000 SI t bytes in big.Ints + BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp) + // BigEByte is 1,000 SI p bytes in big.Ints + BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp) + // BigZByte is 1,000 SI e bytes in big.Ints + BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp) + // BigYByte is 1,000 SI z bytes in big.Ints + BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp) +) + +var bigBytesSizeTable = map[string]*big.Int{ + "b": BigByte, + "kib": BigKiByte, + "kb": BigKByte, + "mib": BigMiByte, + "mb": BigMByte, + "gib": BigGiByte, + "gb": BigGByte, + "tib": BigTiByte, + "tb": BigTByte, + "pib": BigPiByte, + "pb": BigPByte, + "eib": BigEiByte, + "eb": BigEByte, + "zib": BigZiByte, + "zb": BigZByte, + "yib": BigYiByte, + "yb": BigYByte, + // Without suffix + "": BigByte, + "ki": BigKiByte, + "k": BigKByte, + "mi": BigMiByte, + "m": BigMByte, + "gi": BigGiByte, + "g": BigGByte, + "ti": BigTiByte, + "t": BigTByte, + "pi": BigPiByte, + "p": BigPByte, + "ei": BigEiByte, + "e": BigEByte, + "z": BigZByte, + "zi": BigZiByte, + "y": BigYByte, + "yi": BigYiByte, +} + +var ten = big.NewInt(10) + +func humanateBigBytes(s, base *big.Int, sizes []string) string { + if s.Cmp(ten) < 0 { + return fmt.Sprintf("%d B", s) + } + c := (&big.Int{}).Set(s) + val, mag := oomm(c, base, len(sizes)-1) + suffix := sizes[mag] + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) + +} + +// BigBytes produces a human readable representation of an SI size. +// +// See also: ParseBigBytes. +// +// BigBytes(82854982) -> 83 MB +func BigBytes(s *big.Int) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + return humanateBigBytes(s, bigSIExp, sizes) +} + +// BigIBytes produces a human readable representation of an IEC size. +// +// See also: ParseBigBytes. +// +// BigIBytes(82854982) -> 79 MiB +func BigIBytes(s *big.Int) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + return humanateBigBytes(s, bigIECExp, sizes) +} + +// ParseBigBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See also: BigBytes, BigIBytes. +// +// ParseBigBytes("42 MB") -> 42000000, nil +// ParseBigBytes("42 mib") -> 44040192, nil +func ParseBigBytes(s string) (*big.Int, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + val := &big.Rat{} + _, err := fmt.Sscanf(num, "%f", val) + if err != nil { + return nil, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bigBytesSizeTable[extra]; ok { + mv := (&big.Rat{}).SetInt(m) + val.Mul(val, mv) + rv := &big.Int{} + rv.Div(val.Num(), val.Denom()) + return rv, nil + } + + return nil, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go new file mode 100644 index 00000000..0b498f48 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bytes.go @@ -0,0 +1,143 @@ +package humanize + +import ( + "fmt" + "math" + "strconv" + "strings" + "unicode" +) + +// IEC Sizes. +// kibis of bits +const ( + Byte = 1 << (iota * 10) + KiByte + MiByte + GiByte + TiByte + PiByte + EiByte +) + +// SI Sizes. +const ( + IByte = 1 + KByte = IByte * 1000 + MByte = KByte * 1000 + GByte = MByte * 1000 + TByte = GByte * 1000 + PByte = TByte * 1000 + EByte = PByte * 1000 +) + +var bytesSizeTable = map[string]uint64{ + "b": Byte, + "kib": KiByte, + "kb": KByte, + "mib": MiByte, + "mb": MByte, + "gib": GiByte, + "gb": GByte, + "tib": TiByte, + "tb": TByte, + "pib": PiByte, + "pb": PByte, + "eib": EiByte, + "eb": EByte, + // Without suffix + "": Byte, + "ki": KiByte, + "k": KByte, + "mi": MiByte, + "m": MByte, + "gi": GiByte, + "g": GByte, + "ti": TiByte, + "t": TByte, + "pi": PiByte, + "p": PByte, + "ei": EiByte, + "e": EByte, +} + +func logn(n, b float64) float64 { + return math.Log(n) / math.Log(b) +} + +func humanateBytes(s uint64, base float64, sizes []string) string { + if s < 10 { + return fmt.Sprintf("%d B", s) + } + e := math.Floor(logn(float64(s), base)) + suffix := sizes[int(e)] + val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) +} + +// Bytes produces a human readable representation of an SI size. +// +// See also: ParseBytes. +// +// Bytes(82854982) -> 83 MB +func Bytes(s uint64) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"} + return humanateBytes(s, 1000, sizes) +} + +// IBytes produces a human readable representation of an IEC size. +// +// See also: ParseBytes. +// +// IBytes(82854982) -> 79 MiB +func IBytes(s uint64) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"} + return humanateBytes(s, 1024, sizes) +} + +// ParseBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See Also: Bytes, IBytes. +// +// ParseBytes("42 MB") -> 42000000, nil +// ParseBytes("42 mib") -> 44040192, nil +func ParseBytes(s string) (uint64, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + f, err := strconv.ParseFloat(num, 64) + if err != nil { + return 0, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bytesSizeTable[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + + return 0, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/comma.go b/vendor/github.com/dustin/go-humanize/comma.go new file mode 100644 index 00000000..520ae3e5 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/comma.go @@ -0,0 +1,116 @@ +package humanize + +import ( + "bytes" + "math" + "math/big" + "strconv" + "strings" +) + +// Comma produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Comma(834142) -> 834,142 +func Comma(v int64) string { + sign := "" + + // Min int64 can't be negated to a usable value, so it has to be special cased. + if v == math.MinInt64 { + return "-9,223,372,036,854,775,808" + } + + if v < 0 { + sign = "-" + v = 0 - v + } + + parts := []string{"", "", "", "", "", "", ""} + j := len(parts) - 1 + + for v > 999 { + parts[j] = strconv.FormatInt(v%1000, 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + v = v / 1000 + j-- + } + parts[j] = strconv.Itoa(int(v)) + return sign + strings.Join(parts[j:], ",") +} + +// Commaf produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Commaf(834142.32) -> 834,142.32 +func Commaf(v float64) string { + buf := &bytes.Buffer{} + if v < 0 { + buf.Write([]byte{'-'}) + v = 0 - v + } + + comma := []byte{','} + + parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} + +// CommafWithDigits works like the Commaf but limits the resulting +// string to the given number of decimal places. +// +// e.g. CommafWithDigits(834142.32, 1) -> 834,142.3 +func CommafWithDigits(f float64, decimals int) string { + return stripTrailingDigits(Commaf(f), decimals) +} + +// BigComma produces a string form of the given big.Int in base 10 +// with commas after every three orders of magnitude. +func BigComma(b *big.Int) string { + sign := "" + if b.Sign() < 0 { + sign = "-" + b.Abs(b) + } + + athousand := big.NewInt(1000) + c := (&big.Int{}).Set(b) + _, m := oom(c, athousand) + parts := make([]string, m+1) + j := len(parts) - 1 + + mod := &big.Int{} + for b.Cmp(athousand) >= 0 { + b.DivMod(b, athousand, mod) + parts[j] = strconv.FormatInt(mod.Int64(), 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + j-- + } + parts[j] = strconv.Itoa(int(b.Int64())) + return sign + strings.Join(parts[j:], ",") +} diff --git a/vendor/github.com/dustin/go-humanize/commaf.go b/vendor/github.com/dustin/go-humanize/commaf.go new file mode 100644 index 00000000..620690de --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/commaf.go @@ -0,0 +1,40 @@ +// +build go1.6 + +package humanize + +import ( + "bytes" + "math/big" + "strings" +) + +// BigCommaf produces a string form of the given big.Float in base 10 +// with commas after every three orders of magnitude. +func BigCommaf(v *big.Float) string { + buf := &bytes.Buffer{} + if v.Sign() < 0 { + buf.Write([]byte{'-'}) + v.Abs(v) + } + + comma := []byte{','} + + parts := strings.Split(v.Text('f', -1), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} diff --git a/vendor/github.com/dustin/go-humanize/ftoa.go b/vendor/github.com/dustin/go-humanize/ftoa.go new file mode 100644 index 00000000..1c62b640 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ftoa.go @@ -0,0 +1,46 @@ +package humanize + +import ( + "strconv" + "strings" +) + +func stripTrailingZeros(s string) string { + offset := len(s) - 1 + for offset > 0 { + if s[offset] == '.' { + offset-- + break + } + if s[offset] != '0' { + break + } + offset-- + } + return s[:offset+1] +} + +func stripTrailingDigits(s string, digits int) string { + if i := strings.Index(s, "."); i >= 0 { + if digits <= 0 { + return s[:i] + } + i++ + if i+digits >= len(s) { + return s + } + return s[:i+digits] + } + return s +} + +// Ftoa converts a float to a string with no trailing zeros. +func Ftoa(num float64) string { + return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64)) +} + +// FtoaWithDigits converts a float to a string but limits the resulting string +// to the given number of decimal places, and no trailing zeros. +func FtoaWithDigits(num float64, digits int) string { + return stripTrailingZeros(stripTrailingDigits(strconv.FormatFloat(num, 'f', 6, 64), digits)) +} diff --git a/vendor/github.com/dustin/go-humanize/humanize.go b/vendor/github.com/dustin/go-humanize/humanize.go new file mode 100644 index 00000000..a2c2da31 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/humanize.go @@ -0,0 +1,8 @@ +/* +Package humanize converts boring ugly numbers to human-friendly strings and back. + +Durations can be turned into strings such as "3 days ago", numbers +representing sizes like 82854982 into useful strings like, "83 MB" or +"79 MiB" (whichever you prefer). +*/ +package humanize diff --git a/vendor/github.com/dustin/go-humanize/number.go b/vendor/github.com/dustin/go-humanize/number.go new file mode 100644 index 00000000..dec61865 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/number.go @@ -0,0 +1,192 @@ +package humanize + +/* +Slightly adapted from the source to fit go-humanize. + +Author: https://github.com/gorhill +Source: https://gist.github.com/gorhill/5285193 + +*/ + +import ( + "math" + "strconv" +) + +var ( + renderFloatPrecisionMultipliers = [...]float64{ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + } + + renderFloatPrecisionRounders = [...]float64{ + 0.5, + 0.05, + 0.005, + 0.0005, + 0.00005, + 0.000005, + 0.0000005, + 0.00000005, + 0.000000005, + 0.0000000005, + } +) + +// FormatFloat produces a formatted number as string based on the following user-specified criteria: +// * thousands separator +// * decimal separator +// * decimal precision +// +// Usage: s := RenderFloat(format, n) +// The format parameter tells how to render the number n. +// +// See examples: http://play.golang.org/p/LXc1Ddm1lJ +// +// Examples of format strings, given n = 12345.6789: +// "#,###.##" => "12,345.67" +// "#,###." => "12,345" +// "#,###" => "12345,678" +// "#\u202F###,##" => "12 345,68" +// "#.###,###### => 12.345,678900 +// "" (aka default format) => 12,345.67 +// +// The highest precision allowed is 9 digits after the decimal symbol. +// There is also a version for integer number, FormatInteger(), +// which is convenient for calls within template. +func FormatFloat(format string, n float64) string { + // Special cases: + // NaN = "NaN" + // +Inf = "+Infinity" + // -Inf = "-Infinity" + if math.IsNaN(n) { + return "NaN" + } + if n > math.MaxFloat64 { + return "Infinity" + } + if n < -math.MaxFloat64 { + return "-Infinity" + } + + // default format + precision := 2 + decimalStr := "." + thousandStr := "," + positiveStr := "" + negativeStr := "-" + + if len(format) > 0 { + format := []rune(format) + + // If there is an explicit format directive, + // then default values are these: + precision = 9 + thousandStr = "" + + // collect indices of meaningful formatting directives + formatIndx := []int{} + for i, char := range format { + if char != '#' && char != '0' { + formatIndx = append(formatIndx, i) + } + } + + if len(formatIndx) > 0 { + // Directive at index 0: + // Must be a '+' + // Raise an error if not the case + // index: 0123456789 + // +0.000,000 + // +000,000.0 + // +0000.00 + // +0000 + if formatIndx[0] == 0 { + if format[formatIndx[0]] != '+' { + panic("RenderFloat(): invalid positive sign directive") + } + positiveStr = "+" + formatIndx = formatIndx[1:] + } + + // Two directives: + // First is thousands separator + // Raise an error if not followed by 3-digit + // 0123456789 + // 0.000,000 + // 000,000.00 + if len(formatIndx) == 2 { + if (formatIndx[1] - formatIndx[0]) != 4 { + panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers") + } + thousandStr = string(format[formatIndx[0]]) + formatIndx = formatIndx[1:] + } + + // One directive: + // Directive is decimal separator + // The number of digit-specifier following the separator indicates wanted precision + // 0123456789 + // 0.00 + // 000,0000 + if len(formatIndx) == 1 { + decimalStr = string(format[formatIndx[0]]) + precision = len(format) - formatIndx[0] - 1 + } + } + } + + // generate sign part + var signStr string + if n >= 0.000000001 { + signStr = positiveStr + } else if n <= -0.000000001 { + signStr = negativeStr + n = -n + } else { + signStr = "" + n = 0.0 + } + + // split number into integer and fractional parts + intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision]) + + // generate integer part string + intStr := strconv.FormatInt(int64(intf), 10) + + // add thousand separator if required + if len(thousandStr) > 0 { + for i := len(intStr); i > 3; { + i -= 3 + intStr = intStr[:i] + thousandStr + intStr[i:] + } + } + + // no fractional part, we can leave now + if precision == 0 { + return signStr + intStr + } + + // generate fractional part + fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision])) + // may need padding + if len(fracStr) < precision { + fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr + } + + return signStr + intStr + decimalStr + fracStr +} + +// FormatInteger produces a formatted number as string. +// See FormatFloat. +func FormatInteger(format string, n int) string { + return FormatFloat(format, float64(n)) +} diff --git a/vendor/github.com/dustin/go-humanize/ordinals.go b/vendor/github.com/dustin/go-humanize/ordinals.go new file mode 100644 index 00000000..43d88a86 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ordinals.go @@ -0,0 +1,25 @@ +package humanize + +import "strconv" + +// Ordinal gives you the input number in a rank/ordinal format. +// +// Ordinal(3) -> 3rd +func Ordinal(x int) string { + suffix := "th" + switch x % 10 { + case 1: + if x%100 != 11 { + suffix = "st" + } + case 2: + if x%100 != 12 { + suffix = "nd" + } + case 3: + if x%100 != 13 { + suffix = "rd" + } + } + return strconv.Itoa(x) + suffix +} diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go new file mode 100644 index 00000000..ae659e0e --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/si.go @@ -0,0 +1,123 @@ +package humanize + +import ( + "errors" + "math" + "regexp" + "strconv" +) + +var siPrefixTable = map[float64]string{ + -24: "y", // yocto + -21: "z", // zepto + -18: "a", // atto + -15: "f", // femto + -12: "p", // pico + -9: "n", // nano + -6: "µ", // micro + -3: "m", // milli + 0: "", + 3: "k", // kilo + 6: "M", // mega + 9: "G", // giga + 12: "T", // tera + 15: "P", // peta + 18: "E", // exa + 21: "Z", // zetta + 24: "Y", // yotta +} + +var revSIPrefixTable = revfmap(siPrefixTable) + +// revfmap reverses the map and precomputes the power multiplier +func revfmap(in map[float64]string) map[string]float64 { + rv := map[string]float64{} + for k, v := range in { + rv[v] = math.Pow(10, k) + } + return rv +} + +var riParseRegex *regexp.Regexp + +func init() { + ri := `^([\-0-9.]+)\s?([` + for _, v := range siPrefixTable { + ri += v + } + ri += `]?)(.*)` + + riParseRegex = regexp.MustCompile(ri) +} + +// ComputeSI finds the most appropriate SI prefix for the given number +// and returns the prefix along with the value adjusted to be within +// that prefix. +// +// See also: SI, ParseSI. +// +// e.g. ComputeSI(2.2345e-12) -> (2.2345, "p") +func ComputeSI(input float64) (float64, string) { + if input == 0 { + return 0, "" + } + mag := math.Abs(input) + exponent := math.Floor(logn(mag, 10)) + exponent = math.Floor(exponent/3) * 3 + + value := mag / math.Pow(10, exponent) + + // Handle special case where value is exactly 1000.0 + // Should return 1 M instead of 1000 k + if value == 1000.0 { + exponent += 3 + value = mag / math.Pow(10, exponent) + } + + value = math.Copysign(value, input) + + prefix := siPrefixTable[exponent] + return value, prefix +} + +// SI returns a string with default formatting. +// +// SI uses Ftoa to format float value, removing trailing zeros. +// +// See also: ComputeSI, ParseSI. +// +// e.g. SI(1000000, "B") -> 1 MB +// e.g. SI(2.2345e-12, "F") -> 2.2345 pF +func SI(input float64, unit string) string { + value, prefix := ComputeSI(input) + return Ftoa(value) + " " + prefix + unit +} + +// SIWithDigits works like SI but limits the resulting string to the +// given number of decimal places. +// +// e.g. SIWithDigits(1000000, 0, "B") -> 1 MB +// e.g. SIWithDigits(2.2345e-12, 2, "F") -> 2.23 pF +func SIWithDigits(input float64, decimals int, unit string) string { + value, prefix := ComputeSI(input) + return FtoaWithDigits(value, decimals) + " " + prefix + unit +} + +var errInvalid = errors.New("invalid input") + +// ParseSI parses an SI string back into the number and unit. +// +// See also: SI, ComputeSI. +// +// e.g. ParseSI("2.2345 pF") -> (2.2345e-12, "F", nil) +func ParseSI(input string) (float64, string, error) { + found := riParseRegex.FindStringSubmatch(input) + if len(found) != 4 { + return 0, "", errInvalid + } + mag := revSIPrefixTable[found[2]] + unit := found[3] + + base, err := strconv.ParseFloat(found[1], 64) + return base * mag, unit, err +} diff --git a/vendor/github.com/dustin/go-humanize/times.go b/vendor/github.com/dustin/go-humanize/times.go new file mode 100644 index 00000000..dd3fbf5e --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/times.go @@ -0,0 +1,117 @@ +package humanize + +import ( + "fmt" + "math" + "sort" + "time" +) + +// Seconds-based time units +const ( + Day = 24 * time.Hour + Week = 7 * Day + Month = 30 * Day + Year = 12 * Month + LongTime = 37 * Year +) + +// Time formats a time into a relative string. +// +// Time(someT) -> "3 weeks ago" +func Time(then time.Time) string { + return RelTime(then, time.Now(), "ago", "from now") +} + +// A RelTimeMagnitude struct contains a relative time point at which +// the relative format of time will switch to a new format string. A +// slice of these in ascending order by their "D" field is passed to +// CustomRelTime to format durations. +// +// The Format field is a string that may contain a "%s" which will be +// replaced with the appropriate signed label (e.g. "ago" or "from +// now") and a "%d" that will be replaced by the quantity. +// +// The DivBy field is the amount of time the time difference must be +// divided by in order to display correctly. +// +// e.g. if D is 2*time.Minute and you want to display "%d minutes %s" +// DivBy should be time.Minute so whatever the duration is will be +// expressed in minutes. +type RelTimeMagnitude struct { + D time.Duration + Format string + DivBy time.Duration +} + +var defaultMagnitudes = []RelTimeMagnitude{ + {time.Second, "now", time.Second}, + {2 * time.Second, "1 second %s", 1}, + {time.Minute, "%d seconds %s", time.Second}, + {2 * time.Minute, "1 minute %s", 1}, + {time.Hour, "%d minutes %s", time.Minute}, + {2 * time.Hour, "1 hour %s", 1}, + {Day, "%d hours %s", time.Hour}, + {2 * Day, "1 day %s", 1}, + {Week, "%d days %s", Day}, + {2 * Week, "1 week %s", 1}, + {Month, "%d weeks %s", Week}, + {2 * Month, "1 month %s", 1}, + {Year, "%d months %s", Month}, + {18 * Month, "1 year %s", 1}, + {2 * Year, "2 years %s", 1}, + {LongTime, "%d years %s", Year}, + {math.MaxInt64, "a long while %s", 1}, +} + +// RelTime formats a time into a relative string. +// +// It takes two times and two labels. In addition to the generic time +// delta string (e.g. 5 minutes), the labels are used applied so that +// the label corresponding to the smaller time is applied. +// +// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier" +func RelTime(a, b time.Time, albl, blbl string) string { + return CustomRelTime(a, b, albl, blbl, defaultMagnitudes) +} + +// CustomRelTime formats a time into a relative string. +// +// It takes two times two labels and a table of relative time formats. +// In addition to the generic time delta string (e.g. 5 minutes), the +// labels are used applied so that the label corresponding to the +// smaller time is applied. +func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string { + lbl := albl + diff := b.Sub(a) + + if a.After(b) { + lbl = blbl + diff = a.Sub(b) + } + + n := sort.Search(len(magnitudes), func(i int) bool { + return magnitudes[i].D > diff + }) + + if n >= len(magnitudes) { + n = len(magnitudes) - 1 + } + mag := magnitudes[n] + args := []interface{}{} + escaped := false + for _, ch := range mag.Format { + if escaped { + switch ch { + case 's': + args = append(args, lbl) + case 'd': + args = append(args, diff/mag.DivBy) + } + escaped = false + } else { + escaped = ch == '%' + } + } + return fmt.Sprintf(mag.Format, args...) +} diff --git a/vendor/github.com/edsrzf/mmap-go/.gitignore b/vendor/github.com/edsrzf/mmap-go/.gitignore new file mode 100644 index 00000000..9aa02c1e --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/.gitignore @@ -0,0 +1,8 @@ +*.out +*.5 +*.6 +*.8 +*.swp +_obj +_test +testdata diff --git a/vendor/github.com/edsrzf/mmap-go/LICENSE b/vendor/github.com/edsrzf/mmap-go/LICENSE new file mode 100644 index 00000000..8f05f338 --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2011, Evan Shaw +All rights reserved. + +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 the copyright holder 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 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. + diff --git a/vendor/github.com/edsrzf/mmap-go/README.md b/vendor/github.com/edsrzf/mmap-go/README.md new file mode 100644 index 00000000..4cc2bfe1 --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/README.md @@ -0,0 +1,12 @@ +mmap-go +======= + +mmap-go is a portable mmap package for the [Go programming language](http://golang.org). +It has been tested on Linux (386, amd64), OS X, and Windows (386). It should also +work on other Unix-like platforms, but hasn't been tested with them. I'm interested +to hear about the results. + +I haven't been able to add more features without adding significant complexity, +so mmap-go doesn't support mprotect, mincore, and maybe a few other things. +If you're running on a Unix-like platform and need some of these features, +I suggest Gustavo Niemeyer's [gommap](http://labix.org/gommap). diff --git a/vendor/github.com/edsrzf/mmap-go/mmap.go b/vendor/github.com/edsrzf/mmap-go/mmap.go new file mode 100644 index 00000000..29655bd2 --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/mmap.go @@ -0,0 +1,117 @@ +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file defines the common package interface and contains a little bit of +// factored out logic. + +// Package mmap allows mapping files into memory. It tries to provide a simple, reasonably portable interface, +// but doesn't go out of its way to abstract away every little platform detail. +// This specifically means: +// * forked processes may or may not inherit mappings +// * a file's timestamp may or may not be updated by writes through mappings +// * specifying a size larger than the file's actual size can increase the file's size +// * If the mapped file is being modified by another process while your program's running, don't expect consistent results between platforms +package mmap + +import ( + "errors" + "os" + "reflect" + "unsafe" +) + +const ( + // RDONLY maps the memory read-only. + // Attempts to write to the MMap object will result in undefined behavior. + RDONLY = 0 + // RDWR maps the memory as read-write. Writes to the MMap object will update the + // underlying file. + RDWR = 1 << iota + // COPY maps the memory as copy-on-write. Writes to the MMap object will affect + // memory, but the underlying file will remain unchanged. + COPY + // If EXEC is set, the mapped memory is marked as executable. + EXEC +) + +const ( + // If the ANON flag is set, the mapped memory will not be backed by a file. + ANON = 1 << iota +) + +// MMap represents a file mapped into memory. +type MMap []byte + +// Map maps an entire file into memory. +// If ANON is set in flags, f is ignored. +func Map(f *os.File, prot, flags int) (MMap, error) { + return MapRegion(f, -1, prot, flags, 0) +} + +// MapRegion maps part of a file into memory. +// The offset parameter must be a multiple of the system's page size. +// If length < 0, the entire file will be mapped. +// If ANON is set in flags, f is ignored. +func MapRegion(f *os.File, length int, prot, flags int, offset int64) (MMap, error) { + if offset%int64(os.Getpagesize()) != 0 { + return nil, errors.New("offset parameter must be a multiple of the system's page size") + } + + var fd uintptr + if flags&ANON == 0 { + fd = uintptr(f.Fd()) + if length < 0 { + fi, err := f.Stat() + if err != nil { + return nil, err + } + length = int(fi.Size()) + } + } else { + if length <= 0 { + return nil, errors.New("anonymous mapping requires non-zero length") + } + fd = ^uintptr(0) + } + return mmap(length, uintptr(prot), uintptr(flags), fd, offset) +} + +func (m *MMap) header() *reflect.SliceHeader { + return (*reflect.SliceHeader)(unsafe.Pointer(m)) +} + +func (m *MMap) addrLen() (uintptr, uintptr) { + header := m.header() + return header.Data, uintptr(header.Len) +} + +// Lock keeps the mapped region in physical memory, ensuring that it will not be +// swapped out. +func (m MMap) Lock() error { + return m.lock() +} + +// Unlock reverses the effect of Lock, allowing the mapped region to potentially +// be swapped out. +// If m is already unlocked, aan error will result. +func (m MMap) Unlock() error { + return m.unlock() +} + +// Flush synchronizes the mapping's contents to the file's contents on disk. +func (m MMap) Flush() error { + return m.flush() +} + +// Unmap deletes the memory mapped region, flushes any remaining changes, and sets +// m to nil. +// Trying to read or write any remaining references to m after Unmap is called will +// result in undefined behavior. +// Unmap should only be called on the slice value that was originally returned from +// a call to Map. Calling Unmap on a derived slice may cause errors. +func (m *MMap) Unmap() error { + err := m.unmap() + *m = nil + return err +} diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_unix.go b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go new file mode 100644 index 00000000..25b13e51 --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go @@ -0,0 +1,51 @@ +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux openbsd solaris netbsd + +package mmap + +import ( + "golang.org/x/sys/unix" +) + +func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) { + flags := unix.MAP_SHARED + prot := unix.PROT_READ + switch { + case inprot© != 0: + prot |= unix.PROT_WRITE + flags = unix.MAP_PRIVATE + case inprot&RDWR != 0: + prot |= unix.PROT_WRITE + } + if inprot&EXEC != 0 { + prot |= unix.PROT_EXEC + } + if inflags&ANON != 0 { + flags |= unix.MAP_ANON + } + + b, err := unix.Mmap(int(fd), off, len, prot, flags) + if err != nil { + return nil, err + } + return b, nil +} + +func (m MMap) flush() error { + return unix.Msync([]byte(m), unix.MS_SYNC) +} + +func (m MMap) lock() error { + return unix.Mlock([]byte(m)) +} + +func (m MMap) unlock() error { + return unix.Munlock([]byte(m)) +} + +func (m MMap) unmap() error { + return unix.Munmap([]byte(m)) +} diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_windows.go b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go new file mode 100644 index 00000000..7910da25 --- /dev/null +++ b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go @@ -0,0 +1,143 @@ +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mmap + +import ( + "errors" + "os" + "sync" + + "golang.org/x/sys/windows" +) + +// mmap on Windows is a two-step process. +// First, we call CreateFileMapping to get a handle. +// Then, we call MapviewToFile to get an actual pointer into memory. +// Because we want to emulate a POSIX-style mmap, we don't want to expose +// the handle -- only the pointer. We also want to return only a byte slice, +// not a struct, so it's convenient to manipulate. + +// We keep this map so that we can get back the original handle from the memory address. + +type addrinfo struct { + file windows.Handle + mapview windows.Handle +} + +var handleLock sync.Mutex +var handleMap = map[uintptr]*addrinfo{} + +func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { + flProtect := uint32(windows.PAGE_READONLY) + dwDesiredAccess := uint32(windows.FILE_MAP_READ) + switch { + case prot© != 0: + flProtect = windows.PAGE_WRITECOPY + dwDesiredAccess = windows.FILE_MAP_COPY + case prot&RDWR != 0: + flProtect = windows.PAGE_READWRITE + dwDesiredAccess = windows.FILE_MAP_WRITE + } + if prot&EXEC != 0 { + flProtect <<= 4 + dwDesiredAccess |= windows.FILE_MAP_EXECUTE + } + + // The maximum size is the area of the file, starting from 0, + // that we wish to allow to be mappable. It is the sum of + // the length the user requested, plus the offset where that length + // is starting from. This does not map the data into memory. + maxSizeHigh := uint32((off + int64(len)) >> 32) + maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) + // TODO: Do we need to set some security attributes? It might help portability. + h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) + if h == 0 { + return nil, os.NewSyscallError("CreateFileMapping", errno) + } + + // Actually map a view of the data into memory. The view's size + // is the length the user requested. + fileOffsetHigh := uint32(off >> 32) + fileOffsetLow := uint32(off & 0xFFFFFFFF) + addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) + if addr == 0 { + return nil, os.NewSyscallError("MapViewOfFile", errno) + } + handleLock.Lock() + handleMap[addr] = &addrinfo{ + file: windows.Handle(hfile), + mapview: h, + } + handleLock.Unlock() + + m := MMap{} + dh := m.header() + dh.Data = addr + dh.Len = len + dh.Cap = dh.Len + + return m, nil +} + +func (m MMap) flush() error { + addr, len := m.addrLen() + errno := windows.FlushViewOfFile(addr, len) + if errno != nil { + return os.NewSyscallError("FlushViewOfFile", errno) + } + + handleLock.Lock() + defer handleLock.Unlock() + handle, ok := handleMap[addr] + if !ok { + // should be impossible; we would've errored above + return errors.New("unknown base address") + } + + errno = windows.FlushFileBuffers(handle.file) + return os.NewSyscallError("FlushFileBuffers", errno) +} + +func (m MMap) lock() error { + addr, len := m.addrLen() + errno := windows.VirtualLock(addr, len) + return os.NewSyscallError("VirtualLock", errno) +} + +func (m MMap) unlock() error { + addr, len := m.addrLen() + errno := windows.VirtualUnlock(addr, len) + return os.NewSyscallError("VirtualUnlock", errno) +} + +func (m MMap) unmap() error { + err := m.flush() + if err != nil { + return err + } + + addr := m.header().Data + // Lock the UnmapViewOfFile along with the handleMap deletion. + // As soon as we unmap the view, the OS is free to give the + // same addr to another new map. We don't want another goroutine + // to insert and remove the same addr into handleMap while + // we're trying to remove our old addr/handle pair. + handleLock.Lock() + defer handleLock.Unlock() + err = windows.UnmapViewOfFile(addr) + if err != nil { + return err + } + + handle, ok := handleMap[addr] + if !ok { + // should be impossible; we would've errored above + return errors.New("unknown base address") + } + delete(handleMap, addr) + + e := windows.CloseHandle(windows.Handle(handle.mapview)) + return os.NewSyscallError("CloseHandle", e) +} diff --git a/vendor/github.com/elastic/gosigar/.appveyor.yml b/vendor/github.com/elastic/gosigar/.appveyor.yml new file mode 100644 index 00000000..ff467086 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/.appveyor.yml @@ -0,0 +1,84 @@ +# Version format +version: "{build}" + +# Operating system (build VM template) +os: Windows Server 2012 R2 + +# Environment variables +environment: + GOPATH: c:\gopath + GVM_GO_VERSION: 1.8.3 + GVM_DL: https://github.com/andrewkroh/gvm/releases/download/v0.0.1/gvm-windows-amd64.exe + +# Custom clone folder (variables are not expanded here). +clone_folder: c:\gopath\src\github.com\elastic\gosigar + +# Cache mingw install until appveyor.yml is modified. +cache: +- C:\ProgramData\chocolatey\bin -> .appveyor.yml +- C:\ProgramData\chocolatey\lib -> .appveyor.yml +- C:\Users\appveyor\.gvm -> .appveyor.yml +- C:\Windows\System32\gvm.exe -> .appveyor.yml +- C:\tools\mingw64 -> .appveyor.yml + +# Scripts that run after cloning repository +install: + - ps: >- + if(!(Test-Path "C:\Windows\System32\gvm.exe")) { + wget "$env:GVM_DL" -Outfile C:\Windows\System32\gvm.exe + } + - ps: gvm --format=powershell "$env:GVM_GO_VERSION" | Invoke-Expression + # AppVeyor installed mingw is 32-bit only so install 64-bit version. + - ps: >- + if(!(Test-Path "C:\tools\mingw64\bin\gcc.exe")) { + cinst mingw > mingw-install.txt + Push-AppveyorArtifact mingw-install.txt + } + - set PATH=C:\tools\mingw64\bin;%GOROOT%\bin;%PATH% + - set PATH=%GOPATH%\bin;%PATH% + - go version + - go env + - python --version + - go get github.com/elastic/beats/vendor/github.com/pierrre/gotestcover + +# To run your custom scripts instead of automatic MSBuild +build_script: + # Compile + - appveyor AddCompilationMessage "Starting Compile" + - cd c:\gopath\src\github.com\elastic\gosigar + - go get -v -t -d ./... + - go build + - go build -o examples/df/df.exe ./examples/df + - go build -o examples/free/free.exe ./examples/free + - go build -o examples/ps/ps.exe ./examples/ps + - go build -o examples/uptime/uptime.exe ./examples/uptime + - appveyor AddCompilationMessage "Compile Success" + +# To run your custom scripts instead of automatic tests +test_script: + # Unit tests + - ps: Add-AppveyorTest "Unit Tests" -Outcome Running + - mkdir build\coverage + - gotestcover -v -coverprofile=build/coverage/unit.cov github.com/elastic/gosigar/... + - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed + - ps: Add-AppveyorTest "Running Examples" -Outcome Running + - .\examples\df\df.exe + - .\examples\free\free.exe + - .\examples\ps\ps.exe + - .\examples\uptime\uptime.exe + - ps: Update-AppveyorTest "Running Examples" -Outcome Passed + +after_test: + - go tool cover -html=build\coverage\unit.cov -o build\coverage\unit.html + - ps: Push-AppveyorArtifact build\coverage\unit.cov + - ps: Push-AppveyorArtifact build\coverage\unit.html + # Upload coverage report. + - "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%" + - pip install codecov + - codecov -X gcov -f "build\coverage\unit.cov" + +# To disable deployment +deploy: off + +# Notifications should only be setup using the AppVeyor UI so that +# forks can be created without inheriting the settings. diff --git a/vendor/github.com/elastic/gosigar/.gitignore b/vendor/github.com/elastic/gosigar/.gitignore new file mode 100644 index 00000000..6f145056 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/.gitignore @@ -0,0 +1,41 @@ +# Directories +/.vagrant +/.idea +/build + +# Files +.DS_Store +/*.iml +*.h + +# Editor swap files +*.swp +*.swo +*.swn + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so +*.exe +*.test +*.prof +*.pyc +*.swp + +# Example binaries +examples/df/df +examples/df/df.exe +examples/free/free +examples/free/free.exe +examples/ps/ps +examples/ps/ps.exe +examples/ss/ss +examples/ss/ss.exe +examples/uptime/uptime +examples/uptime/uptime.exe + +# Test Data +cgroup/testdata/* +!cgroup/testdata/*.zip + diff --git a/vendor/github.com/elastic/gosigar/.travis.yml b/vendor/github.com/elastic/gosigar/.travis.yml new file mode 100644 index 00000000..fe804624 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/.travis.yml @@ -0,0 +1,37 @@ +language: go + +os: + - linux + - osx + +go: + - 1.8.x + - 1.10.x + +env: + global: + - PROJ="github.com/elastic/gosigar" + +sudo: false + +before_install: + # Put project into proper GOPATH location (important for forks). + - mkdir -p $HOME/gopath/src/${PROJ} + - rsync -az ${TRAVIS_BUILD_DIR}/ $HOME/gopath/src/${PROJ}/ + - export TRAVIS_BUILD_DIR=$HOME/gopath/src/${PROJ} + - cd $HOME/gopath/src/${PROJ} + +install: + - go get -v -t -d ./... + - go get github.com/elastic/beats/vendor/github.com/pierrre/gotestcover + +script: + - gofmt -l . | read && echo "Code differs from gofmt's style. Run 'gofmt -w .'" 1>&2 && exit 1 || true + - go vet + - go build + - mkdir -p build/coverage + - gotestcover -v -coverprofile=build/coverage/unit.cov github.com/elastic/gosigar/... + - for i in $(ls examples); do go build -o examples/$i/$i ./examples/$i; ./examples/$i/$i; done + +after_success: + - bash <(curl -s https://codecov.io/bash) -f build/coverage/unit.cov diff --git a/vendor/github.com/elastic/gosigar/CHANGELOG.md b/vendor/github.com/elastic/gosigar/CHANGELOG.md new file mode 100644 index 00000000..0ce0fad6 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/CHANGELOG.md @@ -0,0 +1,135 @@ +# Change Log +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +## [Unreleased] + +### Added + +### Fixed + +### Changed + +### Deprecated + +## [0.10.3] + +### Fixed +- ProcState.Get() doesn't fail under Windows when it cannot obtain process ownership information. #121 + +## [0.10.2] + +### Fixed +- Fix memory leak when getting process arguments. #119 + +## [0.10.1] + +### Fixed +- Replaced the WMI queries with win32 apis due to high CPU usage. #116 + +## [0.10.0] + +### Added +- List filesystems on Windows that have an access path but not an assigned letter. #112 + +### Fixed +- Added missing runtime import for FreeBSD. #104 +- Handle nil command line in Windows processes. #110 + +## [0.9.0] + +### Added +- Added support for huge TLB pages on Linux #97 +- Added support for big endian platform #100 + +### Fixed +- Add missing method for OpenBSD #99 + +## [0.8.0] + +### Added +- Added partial `getrusage` support for Windows to retrieve system CPU time and user CPU time. #95 +- Added full `getrusage` support for Unix. #95 + +## [0.7.0] + +### Added +- Added method stubs for process handling for operating system that are not supported + by gosigar. All methods return `ErrNotImplemented` on such systems. #88 + +### Fixed +- Fix freebsd build by using the common version of Get(pid). #91 + +### Changed +- Fixed issues in cgroup package by adding missing error checks and closing + file handles. #92 + +## [0.6.0] + +### Added +- Added method stubs to enable compilation for operating systems that are not + supported by gosigar. All methods return `ErrNotImplemented` on these unsupported + operating systems. #83 +- FreeBSD returns `ErrNotImplemented` for `ProcTime.Get`. #83 + +### Changed +- OpenBSD returns `ErrNotImplemented` for `ProcTime.Get` instead of `nil`. #83 +- Fixed incorrect `Mem.Used` calculation under linux. #82 +- Fixed `ProcState` on Linux and FreeBSD when process names contain parentheses. #81 + +### Removed +- Remove NetBSD build from sigar_unix.go as it is not supported by gosigar. #83 + +## [0.5.0] + +### Changed +- Fixed Trim environment variables when comparing values in the test suite. #79 +- Make `kern_procargs` more robust under darwin when we cannot retrieve + all the information about a process. #78 + +## [0.4.0] + +### Changed +- Fixed Windows issue that caused a hang during `init()` if WMI wasn't ready. #74 + +## [0.3.0] + +### Added +- Read `MemAvailable` value for kernel 3.14+ #71 + +## [0.2.0] + +### Added +- Added `ErrCgroupsMissing` to indicate that /proc/cgroups is missing which is + an indicator that cgroups were disabled at compile time. #64 + +### Changed +- Changed `cgroup.SupportedSubsystems()` to honor the "enabled" column in the + /proc/cgroups file. #64 + +## [0.1.0] + +### Added +- Added `CpuList` implementation for Windows that returns CPU timing information + on a per CPU basis. #55 +- Added `Uptime` implementation for Windows. #55 +- Added `Swap` implementation for Windows based on page file metrics. #55 +- Added support to `github.com/gosigar/sys/windows` for querying and enabling + privileges in a process token. +- Added utility code for interfacing with linux NETLINK_INET_DIAG. #60 +- Added `ProcEnv` for getting a process's environment variables. #61 + +### Changed +- Changed several `OpenProcess` calls on Windows to request the lowest possible + access privileges. #50 +- Removed cgo usage from Windows code. +- Added OS version checks to `ProcArgs.Get` on Windows because the + `Win32_Process` WMI query is not available prior to Windows vista. On XP and + Windows 2003, this method returns `ErrNotImplemented`. #55 + +### Fixed +- Fixed value of `Mem.ActualFree` and `Mem.ActualUsed` on Windows. #49 +- Fixed `ProcTime.StartTime` on Windows to report value in milliseconds since + Unix epoch. #51 +- Fixed `ProcStatus.PPID` value is wrong on Windows. #55 +- Fixed `ProcStatus.Username` error on Windows XP #56 diff --git a/vendor/github.com/elastic/gosigar/LICENSE b/vendor/github.com/elastic/gosigar/LICENSE new file mode 100644 index 00000000..11069edd --- /dev/null +++ b/vendor/github.com/elastic/gosigar/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/elastic/gosigar/NOTICE b/vendor/github.com/elastic/gosigar/NOTICE new file mode 100644 index 00000000..fda553b5 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/NOTICE @@ -0,0 +1,9 @@ +Copyright (c) [2009-2011] VMware, Inc. All Rights Reserved. + +This product is licensed to you under the Apache License, Version 2.0 (the "License"). +You may not use this product except in compliance with the License. + +This product includes a number of subcomponents with +separate copyright notices and license terms. Your use of these +subcomponents is subject to the terms and conditions of the +subcomponent's license, as noted in the LICENSE file. \ No newline at end of file diff --git a/vendor/github.com/elastic/gosigar/README.md b/vendor/github.com/elastic/gosigar/README.md new file mode 100644 index 00000000..ecdfc1c3 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/README.md @@ -0,0 +1,58 @@ +# Go sigar [![Build Status](https://travis-ci.org/elastic/gosigar.svg?branch=master)](https://travis-ci.org/elastic/gosigar) [![Build status](https://ci.appveyor.com/api/projects/status/4yh6sa7u97ek5uib/branch/master?svg=true)](https://ci.appveyor.com/project/elastic-beats/gosigar/branch/master) + + +## Overview + +Go sigar is a golang implementation of the +[sigar API](https://github.com/hyperic/sigar). The Go version of +sigar has a very similar interface, but is being written from scratch +in pure go/cgo, rather than cgo bindings for libsigar. + +## Test drive + + $ go get github.com/elastic/gosigar + $ cd $GOPATH/src/github.com/elastic/gosigar/examples/ps + $ go build + $ ./ps + +## Supported platforms + +The features vary by operating system. + +| Feature | Linux | Darwin | Windows | OpenBSD | FreeBSD | +|-----------------|:-----:|:------:|:-------:|:-------:|:-------:| +| Cpu | X | X | X | X | X | +| CpuList | X | X | | X | X | +| FDUsage | X | | | | X | +| FileSystemList | X | X | X | X | X | +| FileSystemUsage | X | X | X | X | X | +| HugeTLBPages | X | | | | | +| LoadAverage | X | X | | X | X | +| Mem | X | X | X | X | X | +| ProcArgs | X | X | X | | X | +| ProcEnv | X | X | | | X | +| ProcExe | X | X | | | X | +| ProcFDUsage | X | | | | X | +| ProcList | X | X | X | | X | +| ProcMem | X | X | X | | X | +| ProcState | X | X | X | | X | +| ProcTime | X | X | X | | X | +| Swap | X | X | | X | X | +| Uptime | X | X | | X | X | + +## OS Specific Notes + +### FreeBSD + +Mount both `linprocfs` and `procfs` for compatability. Consider adding these +mounts to your `/etc/fstab` file so they are mounted automatically at boot. + +``` +sudo mount -t procfs proc /proc +sudo mkdir -p /compat/linux/proc +sudo mount -t linprocfs /dev/null /compat/linux/proc +``` + +## License + +Apache 2.0 diff --git a/vendor/github.com/elastic/gosigar/codecov.yml b/vendor/github.com/elastic/gosigar/codecov.yml new file mode 100644 index 00000000..76ade0fd --- /dev/null +++ b/vendor/github.com/elastic/gosigar/codecov.yml @@ -0,0 +1,21 @@ +# Enable coverage report message for diff on commit +coverage: + status: + project: off + patch: + default: + # basic + target: auto + threshold: null + base: auto + # advanced + branches: null + if_no_uploads: error + if_not_found: success + if_ci_failed: error + only_pulls: false + flags: null + paths: null + +# Disable comments on Pull Requests +comment: false diff --git a/vendor/github.com/elastic/gosigar/concrete_sigar.go b/vendor/github.com/elastic/gosigar/concrete_sigar.go new file mode 100644 index 00000000..e3ee80a9 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/concrete_sigar.go @@ -0,0 +1,89 @@ +package gosigar + +import ( + "time" +) + +type ConcreteSigar struct{} + +func (c *ConcreteSigar) CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) { + // samplesCh is buffered to 1 value to immediately return first CPU sample + samplesCh := make(chan Cpu, 1) + + stopCh := make(chan struct{}) + + go func() { + var cpuUsage Cpu + + // Immediately provide non-delta value. + // samplesCh is buffered to 1 value, so it will not block. + cpuUsage.Get() + samplesCh <- cpuUsage + + ticker := time.NewTicker(collectionInterval) + + for { + select { + case <-ticker.C: + previousCpuUsage := cpuUsage + + cpuUsage.Get() + + select { + case samplesCh <- cpuUsage.Delta(previousCpuUsage): + default: + // Include default to avoid channel blocking + } + + case <-stopCh: + return + } + } + }() + + return samplesCh, stopCh +} + +func (c *ConcreteSigar) GetLoadAverage() (LoadAverage, error) { + l := LoadAverage{} + err := l.Get() + return l, err +} + +func (c *ConcreteSigar) GetMem() (Mem, error) { + m := Mem{} + err := m.Get() + return m, err +} + +func (c *ConcreteSigar) GetSwap() (Swap, error) { + s := Swap{} + err := s.Get() + return s, err +} + +func (c *ConcreteSigar) GetHugeTLBPages() (HugeTLBPages, error) { + p := HugeTLBPages{} + err := p.Get() + return p, err +} + +func (c *ConcreteSigar) GetFileSystemUsage(path string) (FileSystemUsage, error) { + f := FileSystemUsage{} + err := f.Get(path) + return f, err +} + +func (c *ConcreteSigar) GetFDUsage() (FDUsage, error) { + fd := FDUsage{} + err := fd.Get() + return fd, err +} + +// GetRusage return the resource usage of the process +// Possible params: 0 = RUSAGE_SELF, 1 = RUSAGE_CHILDREN, 2 = RUSAGE_THREAD +func (c *ConcreteSigar) GetRusage(who int) (Rusage, error) { + r := Rusage{} + err := r.Get(who) + return r, err +} diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin.go b/vendor/github.com/elastic/gosigar/sigar_darwin.go new file mode 100644 index 00000000..a90b998c --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_darwin.go @@ -0,0 +1,498 @@ +// Copyright (c) 2012 VMware, Inc. + +package gosigar + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "os/user" + "runtime" + "strconv" + "syscall" + "time" + "unsafe" +) + +func (self *LoadAverage) Get() error { + avg := []C.double{0, 0, 0} + + C.getloadavg(&avg[0], C.int(len(avg))) + + self.One = float64(avg[0]) + self.Five = float64(avg[1]) + self.Fifteen = float64(avg[2]) + + return nil +} + +func (self *Uptime) Get() error { + tv := syscall.Timeval32{} + + if err := sysctlbyname("kern.boottime", &tv); err != nil { + return err + } + + self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds() + + return nil +} + +func (self *Mem) Get() error { + var vmstat C.vm_statistics_data_t + + if err := sysctlbyname("hw.memsize", &self.Total); err != nil { + return err + } + + if err := vm_info(&vmstat); err != nil { + return err + } + + kern := uint64(vmstat.inactive_count) << 12 + self.Free = uint64(vmstat.free_count) << 12 + + self.Used = self.Total - self.Free + self.ActualFree = self.Free + kern + self.ActualUsed = self.Used - kern + + return nil +} + +type xsw_usage struct { + Total, Avail, Used uint64 +} + +func (self *Swap) Get() error { + sw_usage := xsw_usage{} + + if err := sysctlbyname("vm.swapusage", &sw_usage); err != nil { + return err + } + + self.Total = sw_usage.Total + self.Used = sw_usage.Used + self.Free = sw_usage.Avail + + return nil +} + +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Cpu) Get() error { + var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT + var cpuload C.host_cpu_load_info_data_t + + status := C.host_statistics(C.host_t(C.mach_host_self()), + C.HOST_CPU_LOAD_INFO, + C.host_info_t(unsafe.Pointer(&cpuload)), + &count) + + if status != C.KERN_SUCCESS { + return fmt.Errorf("host_statistics error=%d", status) + } + + self.User = uint64(cpuload.cpu_ticks[C.CPU_STATE_USER]) + self.Sys = uint64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) + self.Idle = uint64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) + self.Nice = uint64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) + + return nil +} + +func (self *CpuList) Get() error { + var count C.mach_msg_type_number_t + var cpuload *C.processor_cpu_load_info_data_t + var ncpu C.natural_t + + status := C.host_processor_info(C.host_t(C.mach_host_self()), + C.PROCESSOR_CPU_LOAD_INFO, + &ncpu, + (*C.processor_info_array_t)(unsafe.Pointer(&cpuload)), + &count) + + if status != C.KERN_SUCCESS { + return fmt.Errorf("host_processor_info error=%d", status) + } + + // jump through some cgo casting hoops and ensure we properly free + // the memory that cpuload points to + target := C.vm_map_t(C.mach_task_self_) + address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload))) + defer C.vm_deallocate(target, address, C.vm_size_t(ncpu)) + + // the body of struct processor_cpu_load_info + // aka processor_cpu_load_info_data_t + var cpu_ticks [C.CPU_STATE_MAX]uint32 + + // copy the cpuload array to a []byte buffer + // where we can binary.Read the data + size := int(ncpu) * binary.Size(cpu_ticks) + buf := C.GoBytes(unsafe.Pointer(cpuload), C.int(size)) + + bbuf := bytes.NewBuffer(buf) + + self.List = make([]Cpu, 0, ncpu) + + for i := 0; i < int(ncpu); i++ { + cpu := Cpu{} + + err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks) + if err != nil { + return err + } + + cpu.User = uint64(cpu_ticks[C.CPU_STATE_USER]) + cpu.Sys = uint64(cpu_ticks[C.CPU_STATE_SYSTEM]) + cpu.Idle = uint64(cpu_ticks[C.CPU_STATE_IDLE]) + cpu.Nice = uint64(cpu_ticks[C.CPU_STATE_NICE]) + + self.List = append(self.List, cpu) + } + + return nil +} + +func (self *FDUsage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *FileSystemList) Get() error { + num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT) + if err != nil { + return err + } + + buf := make([]syscall.Statfs_t, num) + + _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT) + if err != nil { + return err + } + + fslist := make([]FileSystem, 0, num) + + for i := 0; i < num; i++ { + fs := FileSystem{} + + fs.DirName = bytePtrToString(&buf[i].Mntonname[0]) + fs.DevName = bytePtrToString(&buf[i].Mntfromname[0]) + fs.SysTypeName = bytePtrToString(&buf[i].Fstypename[0]) + + fslist = append(fslist, fs) + } + + self.List = fslist + + return err +} + +func (self *ProcList) Get() error { + n := C.proc_listpids(C.PROC_ALL_PIDS, 0, nil, 0) + if n <= 0 { + return syscall.EINVAL + } + buf := make([]byte, n) + n = C.proc_listpids(C.PROC_ALL_PIDS, 0, unsafe.Pointer(&buf[0]), n) + if n <= 0 { + return syscall.ENOMEM + } + + var pid int32 + num := int(n) / binary.Size(pid) + list := make([]int, 0, num) + bbuf := bytes.NewBuffer(buf) + + for i := 0; i < num; i++ { + if err := binary.Read(bbuf, binary.LittleEndian, &pid); err != nil { + return err + } + if pid == 0 { + continue + } + + list = append(list, int(pid)) + } + + self.List = list + + return nil +} + +func (self *ProcState) Get(pid int) error { + info := C.struct_proc_taskallinfo{} + + if err := task_info(pid, &info); err != nil { + return err + } + + self.Name = C.GoString(&info.pbsd.pbi_comm[0]) + + switch info.pbsd.pbi_status { + case C.SIDL: + self.State = RunStateIdle + case C.SRUN: + self.State = RunStateRun + case C.SSLEEP: + self.State = RunStateSleep + case C.SSTOP: + self.State = RunStateStop + case C.SZOMB: + self.State = RunStateZombie + default: + self.State = RunStateUnknown + } + + self.Ppid = int(info.pbsd.pbi_ppid) + + self.Pgid = int(info.pbsd.pbi_pgid) + + self.Tty = int(info.pbsd.e_tdev) + + self.Priority = int(info.ptinfo.pti_priority) + + self.Nice = int(info.pbsd.pbi_nice) + + // Get process username. Fallback to UID if username is not available. + uid := strconv.Itoa(int(info.pbsd.pbi_uid)) + user, err := user.LookupId(uid) + if err == nil && user.Username != "" { + self.Username = user.Username + } else { + self.Username = uid + } + + return nil +} + +func (self *ProcMem) Get(pid int) error { + info := C.struct_proc_taskallinfo{} + + if err := task_info(pid, &info); err != nil { + return err + } + + self.Size = uint64(info.ptinfo.pti_virtual_size) + self.Resident = uint64(info.ptinfo.pti_resident_size) + self.PageFaults = uint64(info.ptinfo.pti_faults) + + return nil +} + +func (self *ProcTime) Get(pid int) error { + info := C.struct_proc_taskallinfo{} + + if err := task_info(pid, &info); err != nil { + return err + } + + self.User = + uint64(info.ptinfo.pti_total_user) / uint64(time.Millisecond) + + self.Sys = + uint64(info.ptinfo.pti_total_system) / uint64(time.Millisecond) + + self.Total = self.User + self.Sys + + self.StartTime = (uint64(info.pbsd.pbi_start_tvsec) * 1000) + + (uint64(info.pbsd.pbi_start_tvusec) / 1000) + + return nil +} + +func (self *ProcArgs) Get(pid int) error { + var args []string + + argv := func(arg string) { + args = append(args, arg) + } + + err := kern_procargs(pid, nil, argv, nil) + + self.List = args + + return err +} + +func (self *ProcEnv) Get(pid int) error { + if self.Vars == nil { + self.Vars = map[string]string{} + } + + env := func(k, v string) { + self.Vars[k] = v + } + + return kern_procargs(pid, nil, nil, env) +} + +func (self *ProcExe) Get(pid int) error { + exe := func(arg string) { + self.Name = arg + } + + return kern_procargs(pid, exe, nil, nil) +} + +func (self *ProcFDUsage) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +// wrapper around sysctl KERN_PROCARGS2 +// callbacks params are optional, +// up to the caller as to which pieces of data they want +func kern_procargs(pid int, + exe func(string), + argv func(string), + env func(string, string)) error { + + mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)} + argmax := uintptr(C.ARG_MAX) + buf := make([]byte, argmax) + err := sysctl(mib, &buf[0], &argmax, nil, 0) + if err != nil { + return nil + } + + bbuf := bytes.NewBuffer(buf) + bbuf.Truncate(int(argmax)) + + var argc int32 + binary.Read(bbuf, binary.LittleEndian, &argc) + + path, err := bbuf.ReadBytes(0) + if err != nil { + return fmt.Errorf("Error reading the argv[0]: %v", err) + } + if exe != nil { + exe(string(chop(path))) + } + + // skip trailing \0's + for { + c, err := bbuf.ReadByte() + if err != nil { + return fmt.Errorf("Error skipping nils: %v", err) + } + if c != 0 { + bbuf.UnreadByte() + break // start of argv[0] + } + } + + for i := 0; i < int(argc); i++ { + arg, err := bbuf.ReadBytes(0) + if err == io.EOF { + break + } + if err != nil { + return fmt.Errorf("Error reading args: %v", err) + } + if argv != nil { + argv(string(chop(arg))) + } + } + + if env == nil { + return nil + } + + delim := []byte{61} // "=" + + for { + line, err := bbuf.ReadBytes(0) + if err == io.EOF || line[0] == 0 { + break + } + if err != nil { + return fmt.Errorf("Error reading args: %v", err) + } + pair := bytes.SplitN(chop(line), delim, 2) + + if len(pair) != 2 { + return fmt.Errorf("Error reading process information for PID: %d", pid) + } + + env(string(pair[0]), string(pair[1])) + } + + return nil +} + +// XXX copied from zsyscall_darwin_amd64.go +func sysctl(mib []C.int, old *byte, oldlen *uintptr, + new *byte, newlen uintptr) (err error) { + var p0 unsafe.Pointer + p0 = unsafe.Pointer(&mib[0]) + _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p0), + uintptr(len(mib)), + uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), + uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = e1 + } + return +} + +func vm_info(vmstat *C.vm_statistics_data_t) error { + var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT + + status := C.host_statistics( + C.host_t(C.mach_host_self()), + C.HOST_VM_INFO, + C.host_info_t(unsafe.Pointer(vmstat)), + &count) + + if status != C.KERN_SUCCESS { + return fmt.Errorf("host_statistics=%d", status) + } + + return nil +} + +// generic Sysctl buffer unmarshalling +func sysctlbyname(name string, data interface{}) (err error) { + val, err := syscall.Sysctl(name) + if err != nil { + return err + } + + buf := []byte(val) + + switch v := data.(type) { + case *uint64: + *v = *(*uint64)(unsafe.Pointer(&buf[0])) + return + } + + bbuf := bytes.NewBuffer([]byte(val)) + return binary.Read(bbuf, binary.LittleEndian, data) +} + +func task_info(pid int, info *C.struct_proc_taskallinfo) error { + size := C.int(unsafe.Sizeof(*info)) + ptr := unsafe.Pointer(info) + + n := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size) + if n != size { + return fmt.Errorf("Could not read process info for pid %d", pid) + } + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_format.go b/vendor/github.com/elastic/gosigar/sigar_format.go new file mode 100644 index 00000000..ac56c987 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_format.go @@ -0,0 +1,126 @@ +// Copyright (c) 2012 VMware, Inc. + +package gosigar + +import ( + "bufio" + "bytes" + "fmt" + "strconv" + "time" +) + +// Go version of apr_strfsize +func FormatSize(size uint64) string { + ord := []string{"K", "M", "G", "T", "P", "E"} + o := 0 + buf := new(bytes.Buffer) + w := bufio.NewWriter(buf) + + if size < 973 { + fmt.Fprintf(w, "%3d ", size) + w.Flush() + return buf.String() + } + + for { + remain := size & 1023 + size >>= 10 + + if size >= 973 { + o++ + continue + } + + if size < 9 || (size == 9 && remain < 973) { + remain = ((remain * 5) + 256) / 512 + if remain >= 10 { + size++ + remain = 0 + } + + fmt.Fprintf(w, "%d.%d%s", size, remain, ord[o]) + break + } + + if remain >= 512 { + size++ + } + + fmt.Fprintf(w, "%3d%s", size, ord[o]) + break + } + + w.Flush() + return buf.String() +} + +func FormatPercent(percent float64) string { + return strconv.FormatFloat(percent, 'f', -1, 64) + "%" +} + +func (self *FileSystemUsage) UsePercent() float64 { + b_used := (self.Total - self.Free) / 1024 + b_avail := self.Avail / 1024 + utotal := b_used + b_avail + used := b_used + + if utotal != 0 { + u100 := used * 100 + pct := u100 / utotal + if u100%utotal != 0 { + pct += 1 + } + return (float64(pct) / float64(100)) * 100.0 + } + + return 0.0 +} + +func (self *Uptime) Format() string { + buf := new(bytes.Buffer) + w := bufio.NewWriter(buf) + uptime := uint64(self.Length) + + days := uptime / (60 * 60 * 24) + + if days != 0 { + s := "" + if days > 1 { + s = "s" + } + fmt.Fprintf(w, "%d day%s, ", days, s) + } + + minutes := uptime / 60 + hours := minutes / 60 + hours %= 24 + minutes %= 60 + + fmt.Fprintf(w, "%2d:%02d", hours, minutes) + + w.Flush() + return buf.String() +} + +func (self *ProcTime) FormatStartTime() string { + if self.StartTime == 0 { + return "00:00" + } + start := time.Unix(int64(self.StartTime)/1000, 0) + format := "Jan02" + if time.Since(start).Seconds() < (60 * 60 * 24) { + format = "15:04" + } + return start.Format(format) +} + +func (self *ProcTime) FormatTotal() string { + t := self.Total / 1000 + ss := t % 60 + t /= 60 + mm := t % 60 + t /= 60 + hh := t % 24 + return fmt.Sprintf("%02d:%02d:%02d", hh, mm, ss) +} diff --git a/vendor/github.com/elastic/gosigar/sigar_freebsd.go b/vendor/github.com/elastic/gosigar/sigar_freebsd.go new file mode 100644 index 00000000..51dd84aa --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_freebsd.go @@ -0,0 +1,158 @@ +// Copied and modified from sigar_linux.go. + +package gosigar + +import ( + "io/ioutil" + "runtime" + "strconv" + "strings" + "unsafe" +) + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +func init() { + system.ticks = uint64(C.sysconf(C._SC_CLK_TCK)) + + Procd = "/compat/linux/proc" + + getLinuxBootTime() +} + +func getMountTableFileName() string { + return Procd + "/mtab" +} + +func (self *Uptime) Get() error { + ts := C.struct_timespec{} + + if _, err := C.clock_gettime(C.CLOCK_UPTIME, &ts); err != nil { + return err + } + + self.Length = float64(ts.tv_sec) + 1e-9*float64(ts.tv_nsec) + + return nil +} + +func (self *FDUsage) Get() error { + val := C.uint32_t(0) + sc := C.size_t(4) + + name := C.CString("kern.openfiles") + _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + self.Open = uint64(val) + + name = C.CString("kern.maxfiles") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + self.Max = uint64(val) + + self.Unused = self.Max - self.Open + + return nil +} + +func (self *ProcFDUsage) Get(pid int) error { + err := readFile("/proc/"+strconv.Itoa(pid)+"/rlimit", func(line string) bool { + if strings.HasPrefix(line, "nofile") { + fields := strings.Fields(line) + if len(fields) == 3 { + self.SoftLimit, _ = strconv.ParseUint(fields[1], 10, 64) + self.HardLimit, _ = strconv.ParseUint(fields[2], 10, 64) + } + return false + } + return true + }) + if err != nil { + return err + } + + // linprocfs only provides this information for this process (self). + fds, err := ioutil.ReadDir(procFileName(pid, "fd")) + if err != nil { + return err + } + self.Open = uint64(len(fds)) + + return nil +} + +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func parseCpuStat(self *Cpu, line string) error { + fields := strings.Fields(line) + + self.User, _ = strtoull(fields[1]) + self.Nice, _ = strtoull(fields[2]) + self.Sys, _ = strtoull(fields[3]) + self.Idle, _ = strtoull(fields[4]) + return nil +} + +func (self *Mem) Get() error { + val := C.uint32_t(0) + sc := C.size_t(4) + + name := C.CString("vm.stats.vm.v_page_count") + _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + pagecount := uint64(val) + + name = C.CString("vm.stats.vm.v_page_size") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + pagesize := uint64(val) + + name = C.CString("vm.stats.vm.v_free_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + self.Free = uint64(val) * pagesize + + name = C.CString("vm.stats.vm.v_inactive_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + kern := uint64(val) + + self.Total = uint64(pagecount * pagesize) + + self.Used = self.Total - self.Free + self.ActualFree = self.Free + (kern * pagesize) + self.ActualUsed = self.Used - (kern * pagesize) + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_interface.go b/vendor/github.com/elastic/gosigar/sigar_interface.go new file mode 100644 index 00000000..df79ae08 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_interface.go @@ -0,0 +1,207 @@ +package gosigar + +import ( + "time" +) + +type ErrNotImplemented struct { + OS string +} + +func (e ErrNotImplemented) Error() string { + return "not implemented on " + e.OS +} + +func IsNotImplemented(err error) bool { + switch err.(type) { + case ErrNotImplemented, *ErrNotImplemented: + return true + default: + return false + } +} + +type Sigar interface { + CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) + GetLoadAverage() (LoadAverage, error) + GetMem() (Mem, error) + GetSwap() (Swap, error) + GetHugeTLBPages(HugeTLBPages, error) + GetFileSystemUsage(string) (FileSystemUsage, error) + GetFDUsage() (FDUsage, error) + GetRusage(who int) (Rusage, error) +} + +type Cpu struct { + User uint64 + Nice uint64 + Sys uint64 + Idle uint64 + Wait uint64 + Irq uint64 + SoftIrq uint64 + Stolen uint64 +} + +func (cpu *Cpu) Total() uint64 { + return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle + + cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen +} + +func (cpu Cpu) Delta(other Cpu) Cpu { + return Cpu{ + User: cpu.User - other.User, + Nice: cpu.Nice - other.Nice, + Sys: cpu.Sys - other.Sys, + Idle: cpu.Idle - other.Idle, + Wait: cpu.Wait - other.Wait, + Irq: cpu.Irq - other.Irq, + SoftIrq: cpu.SoftIrq - other.SoftIrq, + Stolen: cpu.Stolen - other.Stolen, + } +} + +type LoadAverage struct { + One, Five, Fifteen float64 +} + +type Uptime struct { + Length float64 +} + +type Mem struct { + Total uint64 + Used uint64 + Free uint64 + ActualFree uint64 + ActualUsed uint64 +} + +type Swap struct { + Total uint64 + Used uint64 + Free uint64 +} + +type HugeTLBPages struct { + Total uint64 + Free uint64 + Reserved uint64 + Surplus uint64 + DefaultSize uint64 + TotalAllocatedSize uint64 +} + +type CpuList struct { + List []Cpu +} + +type FDUsage struct { + Open uint64 + Unused uint64 + Max uint64 +} + +type FileSystem struct { + DirName string + DevName string + TypeName string + SysTypeName string + Options string + Flags uint32 +} + +type FileSystemList struct { + List []FileSystem +} + +type FileSystemUsage struct { + Total uint64 + Used uint64 + Free uint64 + Avail uint64 + Files uint64 + FreeFiles uint64 +} + +type ProcList struct { + List []int +} + +type RunState byte + +const ( + RunStateSleep = 'S' + RunStateRun = 'R' + RunStateStop = 'T' + RunStateZombie = 'Z' + RunStateIdle = 'D' + RunStateUnknown = '?' +) + +type ProcState struct { + Name string + Username string + State RunState + Ppid int + Pgid int + Tty int + Priority int + Nice int + Processor int +} + +type ProcMem struct { + Size uint64 + Resident uint64 + Share uint64 + MinorFaults uint64 + MajorFaults uint64 + PageFaults uint64 +} + +type ProcTime struct { + StartTime uint64 + User uint64 + Sys uint64 + Total uint64 +} + +type ProcArgs struct { + List []string +} + +type ProcEnv struct { + Vars map[string]string +} + +type ProcExe struct { + Name string + Cwd string + Root string +} + +type ProcFDUsage struct { + Open uint64 + SoftLimit uint64 + HardLimit uint64 +} + +type Rusage struct { + Utime time.Duration + Stime time.Duration + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} diff --git a/vendor/github.com/elastic/gosigar/sigar_linux.go b/vendor/github.com/elastic/gosigar/sigar_linux.go new file mode 100644 index 00000000..e04e8a97 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_linux.go @@ -0,0 +1,133 @@ +// Copyright (c) 2012 VMware, Inc. + +package gosigar + +import ( + "io/ioutil" + "strconv" + "strings" + "syscall" +) + +func init() { + system.ticks = 100 // C.sysconf(C._SC_CLK_TCK) + + Procd = "/proc" + + getLinuxBootTime() +} + +func getMountTableFileName() string { + return "/etc/mtab" +} + +func (self *Uptime) Get() error { + sysinfo := syscall.Sysinfo_t{} + + if err := syscall.Sysinfo(&sysinfo); err != nil { + return err + } + + self.Length = float64(sysinfo.Uptime) + + return nil +} + +func (self *FDUsage) Get() error { + return readFile(Procd+"/sys/fs/file-nr", func(line string) bool { + fields := strings.Fields(line) + if len(fields) == 3 { + self.Open, _ = strconv.ParseUint(fields[0], 10, 64) + self.Unused, _ = strconv.ParseUint(fields[1], 10, 64) + self.Max, _ = strconv.ParseUint(fields[2], 10, 64) + } + return false + }) +} + +func (self *HugeTLBPages) Get() error { + table, err := parseMeminfo() + if err != nil { + return err + } + + self.Total, _ = table["HugePages_Total"] + self.Free, _ = table["HugePages_Free"] + self.Reserved, _ = table["HugePages_Rsvd"] + self.Surplus, _ = table["HugePages_Surp"] + self.DefaultSize, _ = table["Hugepagesize"] + + if totalSize, found := table["Hugetlb"]; found { + self.TotalAllocatedSize = totalSize + } else { + // If Hugetlb is not present, or huge pages of different sizes + // are used, this figure can be unaccurate. + // TODO (jsoriano): Extract information from /sys/kernel/mm/hugepages too + self.TotalAllocatedSize = (self.Total - self.Free + self.Reserved) * self.DefaultSize + } + + return nil +} + +func (self *ProcFDUsage) Get(pid int) error { + err := readFile(procFileName(pid, "limits"), func(line string) bool { + if strings.HasPrefix(line, "Max open files") { + fields := strings.Fields(line) + if len(fields) == 6 { + self.SoftLimit, _ = strconv.ParseUint(fields[3], 10, 64) + self.HardLimit, _ = strconv.ParseUint(fields[4], 10, 64) + } + return false + } + return true + }) + if err != nil { + return err + } + fds, err := ioutil.ReadDir(procFileName(pid, "fd")) + if err != nil { + return err + } + self.Open = uint64(len(fds)) + return nil +} + +func parseCpuStat(self *Cpu, line string) error { + fields := strings.Fields(line) + + self.User, _ = strtoull(fields[1]) + self.Nice, _ = strtoull(fields[2]) + self.Sys, _ = strtoull(fields[3]) + self.Idle, _ = strtoull(fields[4]) + self.Wait, _ = strtoull(fields[5]) + self.Irq, _ = strtoull(fields[6]) + self.SoftIrq, _ = strtoull(fields[7]) + self.Stolen, _ = strtoull(fields[8]) + + return nil +} + +func (self *Mem) Get() error { + + table, err := parseMeminfo() + if err != nil { + return err + } + + self.Total, _ = table["MemTotal"] + self.Free, _ = table["MemFree"] + buffers, _ := table["Buffers"] + cached, _ := table["Cached"] + + if available, ok := table["MemAvailable"]; ok { + // MemAvailable is in /proc/meminfo (kernel 3.14+) + self.ActualFree = available + } else { + self.ActualFree = self.Free + buffers + cached + } + + self.Used = self.Total - self.Free + self.ActualUsed = self.Total - self.ActualFree + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_linux_common.go b/vendor/github.com/elastic/gosigar/sigar_linux_common.go new file mode 100644 index 00000000..e2c5e246 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_linux_common.go @@ -0,0 +1,457 @@ +// Copyright (c) 2012 VMware, Inc. + +// +build freebsd linux + +package gosigar + +import ( + "bufio" + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + "os/user" + "path/filepath" + "strconv" + "strings" + "syscall" +) + +var system struct { + ticks uint64 + btime uint64 +} + +var Procd string + +func getLinuxBootTime() { + // grab system boot time + readFile(Procd+"/stat", func(line string) bool { + if strings.HasPrefix(line, "btime") { + system.btime, _ = strtoull(line[6:]) + return false // stop reading + } + return true + }) +} + +func (self *LoadAverage) Get() error { + line, err := ioutil.ReadFile(Procd + "/loadavg") + if err != nil { + return nil + } + + fields := strings.Fields(string(line)) + + self.One, _ = strconv.ParseFloat(fields[0], 64) + self.Five, _ = strconv.ParseFloat(fields[1], 64) + self.Fifteen, _ = strconv.ParseFloat(fields[2], 64) + + return nil +} + +func (self *Swap) Get() error { + + table, err := parseMeminfo() + if err != nil { + return err + } + self.Total, _ = table["SwapTotal"] + self.Free, _ = table["SwapFree"] + + self.Used = self.Total - self.Free + return nil +} + +func (self *Cpu) Get() error { + return readFile(Procd+"/stat", func(line string) bool { + if len(line) > 4 && line[0:4] == "cpu " { + parseCpuStat(self, line) + return false + } + return true + + }) +} + +func (self *CpuList) Get() error { + capacity := len(self.List) + if capacity == 0 { + capacity = 4 + } + list := make([]Cpu, 0, capacity) + + err := readFile(Procd+"/stat", func(line string) bool { + if len(line) > 3 && line[0:3] == "cpu" && line[3] != ' ' { + cpu := Cpu{} + parseCpuStat(&cpu, line) + list = append(list, cpu) + } + return true + }) + + self.List = list + + return err +} + +func (self *FileSystemList) Get() error { + capacity := len(self.List) + if capacity == 0 { + capacity = 10 + } + fslist := make([]FileSystem, 0, capacity) + + err := readFile(getMountTableFileName(), func(line string) bool { + fields := strings.Fields(line) + + fs := FileSystem{} + fs.DevName = fields[0] + fs.DirName = fields[1] + fs.SysTypeName = fields[2] + fs.Options = fields[3] + + fslist = append(fslist, fs) + + return true + }) + + self.List = fslist + + return err +} + +func (self *ProcList) Get() error { + dir, err := os.Open(Procd) + if err != nil { + return err + } + defer dir.Close() + + const readAllDirnames = -1 // see os.File.Readdirnames doc + + names, err := dir.Readdirnames(readAllDirnames) + if err != nil { + return err + } + + capacity := len(names) + list := make([]int, 0, capacity) + + for _, name := range names { + if name[0] < '0' || name[0] > '9' { + continue + } + pid, err := strconv.Atoi(name) + if err == nil { + list = append(list, pid) + } + } + + self.List = list + + return nil +} + +func (self *ProcState) Get(pid int) error { + data, err := readProcFile(pid, "stat") + if err != nil { + return err + } + + // Extract the comm value with is surrounded by parentheses. + lIdx := bytes.Index(data, []byte("(")) + rIdx := bytes.LastIndex(data, []byte(")")) + if lIdx < 0 || rIdx < 0 || lIdx >= rIdx || rIdx+2 >= len(data) { + return fmt.Errorf("failed to extract comm for pid %d from '%v'", pid, string(data)) + } + self.Name = string(data[lIdx+1 : rIdx]) + + // Extract the rest of the fields that we are interested in. + fields := bytes.Fields(data[rIdx+2:]) + if len(fields) <= 36 { + return fmt.Errorf("expected more stat fields for pid %d from '%v'", pid, string(data)) + } + + interests := bytes.Join([][]byte{ + fields[0], // state + fields[1], // ppid + fields[2], // pgrp + fields[4], // tty_nr + fields[15], // priority + fields[16], // nice + fields[36], // processor (last processor executed on) + }, []byte(" ")) + + var state string + _, err = fmt.Fscan(bytes.NewBuffer(interests), + &state, + &self.Ppid, + &self.Pgid, + &self.Tty, + &self.Priority, + &self.Nice, + &self.Processor, + ) + if err != nil { + return fmt.Errorf("failed to parse stat fields for pid %d from '%v': %v", pid, string(data), err) + } + self.State = RunState(state[0]) + + // Read /proc/[pid]/status to get the uid, then lookup uid to get username. + status, err := getProcStatus(pid) + if err != nil { + return fmt.Errorf("failed to read process status for pid %d: %v", pid, err) + } + uids, err := getUIDs(status) + if err != nil { + return fmt.Errorf("failed to read process status for pid %d: %v", pid, err) + } + user, err := user.LookupId(uids[0]) + if err == nil { + self.Username = user.Username + } else { + self.Username = uids[0] + } + + return nil +} + +func (self *ProcMem) Get(pid int) error { + contents, err := readProcFile(pid, "statm") + if err != nil { + return err + } + + fields := strings.Fields(string(contents)) + + size, _ := strtoull(fields[0]) + self.Size = size << 12 + + rss, _ := strtoull(fields[1]) + self.Resident = rss << 12 + + share, _ := strtoull(fields[2]) + self.Share = share << 12 + + contents, err = readProcFile(pid, "stat") + if err != nil { + return err + } + + fields = strings.Fields(string(contents)) + + self.MinorFaults, _ = strtoull(fields[10]) + self.MajorFaults, _ = strtoull(fields[12]) + self.PageFaults = self.MinorFaults + self.MajorFaults + + return nil +} + +func (self *ProcTime) Get(pid int) error { + contents, err := readProcFile(pid, "stat") + if err != nil { + return err + } + + fields := strings.Fields(string(contents)) + + user, _ := strtoull(fields[13]) + sys, _ := strtoull(fields[14]) + // convert to millis + self.User = user * (1000 / system.ticks) + self.Sys = sys * (1000 / system.ticks) + self.Total = self.User + self.Sys + + // convert to millis + self.StartTime, _ = strtoull(fields[21]) + self.StartTime /= system.ticks + self.StartTime += system.btime + self.StartTime *= 1000 + + return nil +} + +func (self *ProcArgs) Get(pid int) error { + contents, err := readProcFile(pid, "cmdline") + if err != nil { + return err + } + + bbuf := bytes.NewBuffer(contents) + + var args []string + + for { + arg, err := bbuf.ReadBytes(0) + if err == io.EOF { + break + } + args = append(args, string(chop(arg))) + } + + self.List = args + + return nil +} + +func (self *ProcEnv) Get(pid int) error { + contents, err := readProcFile(pid, "environ") + if err != nil { + return err + } + + if self.Vars == nil { + self.Vars = map[string]string{} + } + + pairs := bytes.Split(contents, []byte{0}) + for _, kv := range pairs { + parts := bytes.SplitN(kv, []byte{'='}, 2) + if len(parts) != 2 { + continue + } + + key := string(bytes.TrimSpace(parts[0])) + if key == "" { + continue + } + + self.Vars[key] = string(bytes.TrimSpace(parts[1])) + } + + return nil +} + +func (self *ProcExe) Get(pid int) error { + fields := map[string]*string{ + "exe": &self.Name, + "cwd": &self.Cwd, + "root": &self.Root, + } + + for name, field := range fields { + val, err := os.Readlink(procFileName(pid, name)) + + if err != nil { + return err + } + + *field = val + } + + return nil +} + +func parseMeminfo() (map[string]uint64, error) { + table := map[string]uint64{} + + err := readFile(Procd+"/meminfo", func(line string) bool { + fields := strings.Split(line, ":") + + if len(fields) != 2 { + return true // skip on errors + } + + valueUnit := strings.Fields(fields[1]) + value, err := strtoull(valueUnit[0]) + if err != nil { + return true // skip on errors + } + + if len(valueUnit) > 1 && valueUnit[1] == "kB" { + value *= 1024 + } + table[fields[0]] = value + + return true + }) + return table, err +} + +func readFile(file string, handler func(string) bool) error { + contents, err := ioutil.ReadFile(file) + if err != nil { + return err + } + + reader := bufio.NewReader(bytes.NewBuffer(contents)) + + for { + line, _, err := reader.ReadLine() + if err == io.EOF { + break + } + if !handler(string(line)) { + break + } + } + + return nil +} + +func strtoull(val string) (uint64, error) { + return strconv.ParseUint(val, 10, 64) +} + +func procFileName(pid int, name string) string { + return Procd + "/" + strconv.Itoa(pid) + "/" + name +} + +func readProcFile(pid int, name string) (content []byte, err error) { + path := procFileName(pid, name) + + // Panics have been reported when reading proc files, let's recover and + // report the path if this happens + // See https://github.com/elastic/beats/issues/6692 + defer func() { + if r := recover(); r != nil { + content = nil + err = fmt.Errorf("recovered panic when reading proc file '%s': %v", path, r) + } + }() + contents, err := ioutil.ReadFile(path) + + if err != nil { + if perr, ok := err.(*os.PathError); ok { + if perr.Err == syscall.ENOENT { + return nil, syscall.ESRCH + } + } + } + + return contents, err +} + +// getProcStatus reads /proc/[pid]/status which contains process status +// information in human readable form. +func getProcStatus(pid int) (map[string]string, error) { + status := make(map[string]string, 42) + path := filepath.Join(Procd, strconv.Itoa(pid), "status") + err := readFile(path, func(line string) bool { + fields := strings.SplitN(line, ":", 2) + if len(fields) == 2 { + status[fields[0]] = strings.TrimSpace(fields[1]) + } + + return true + }) + return status, err +} + +// getUIDs reads the "Uid" value from status and splits it into four values -- +// real, effective, saved set, and file system UIDs. +func getUIDs(status map[string]string) ([]string, error) { + uidLine, ok := status["Uid"] + if !ok { + return nil, fmt.Errorf("Uid not found in proc status") + } + + uidStrs := strings.Fields(uidLine) + if len(uidStrs) != 4 { + return nil, fmt.Errorf("Uid line ('%s') did not contain four values", uidLine) + } + + return uidStrs, nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_openbsd.go b/vendor/github.com/elastic/gosigar/sigar_openbsd.go new file mode 100644 index 00000000..e4371b8b --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_openbsd.go @@ -0,0 +1,426 @@ +// Copyright (c) 2016 Jasper Lievisse Adriaanse . + +// +build openbsd + +package gosigar + +/* +#include +#include +#include +#include +#include +#include +#include +#include +*/ +import "C" + +//import "github.com/davecgh/go-spew/spew" + +import ( + "runtime" + "syscall" + "time" + "unsafe" +) + +type Uvmexp struct { + pagesize uint32 + pagemask uint32 + pageshift uint32 + npages uint32 + free uint32 + active uint32 + inactive uint32 + paging uint32 + wired uint32 + zeropages uint32 + reserve_pagedaemon uint32 + reserve_kernel uint32 + anonpages uint32 + vnodepages uint32 + vtextpages uint32 + freemin uint32 + freetarg uint32 + inactarg uint32 + wiredmax uint32 + anonmin uint32 + vtextmin uint32 + vnodemin uint32 + anonminpct uint32 + vtextmi uint32 + npct uint32 + vnodeminpct uint32 + nswapdev uint32 + swpages uint32 + swpginuse uint32 + swpgonly uint32 + nswget uint32 + nanon uint32 + nanonneeded uint32 + nfreeanon uint32 + faults uint32 + traps uint32 + intrs uint32 + swtch uint32 + softs uint32 + syscalls uint32 + pageins uint32 + obsolete_swapins uint32 + obsolete_swapouts uint32 + pgswapin uint32 + pgswapout uint32 + forks uint32 + forks_ppwait uint32 + forks_sharevm uint32 + pga_zerohit uint32 + pga_zeromiss uint32 + zeroaborts uint32 + fltnoram uint32 + fltnoanon uint32 + fltpgwait uint32 + fltpgrele uint32 + fltrelck uint32 + fltrelckok uint32 + fltanget uint32 + fltanretry uint32 + fltamcopy uint32 + fltnamap uint32 + fltnomap uint32 + fltlget uint32 + fltget uint32 + flt_anon uint32 + flt_acow uint32 + flt_obj uint32 + flt_prcopy uint32 + flt_przero uint32 + pdwoke uint32 + pdrevs uint32 + pdswout uint32 + pdfreed uint32 + pdscans uint32 + pdanscan uint32 + pdobscan uint32 + pdreact uint32 + pdbusy uint32 + pdpageouts uint32 + pdpending uint32 + pddeact uint32 + pdreanon uint32 + pdrevnode uint32 + pdrevtext uint32 + fpswtch uint32 + kmapent uint32 +} + +type Bcachestats struct { + numbufs uint64 + numbufpages uint64 + numdirtypages uint64 + numcleanpages uint64 + pendingwrites uint64 + pendingreads uint64 + numwrites uint64 + numreads uint64 + cachehits uint64 + busymapped uint64 + dmapages uint64 + highpages uint64 + delwribufs uint64 + kvaslots uint64 + kvaslots_avail uint64 +} + +type Swapent struct { + se_dev C.dev_t + se_flags int32 + se_nblks int32 + se_inuse int32 + se_priority int32 + sw_path []byte +} + +func (self *FileSystemList) Get() error { + num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT) + if err != nil { + return err + } + + buf := make([]syscall.Statfs_t, num) + + _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT) + if err != nil { + return err + } + + fslist := make([]FileSystem, 0, num) + + for i := 0; i < num; i++ { + fs := FileSystem{} + + fs.DirName = bytePtrToString(&buf[i].F_mntonname[0]) + fs.DevName = bytePtrToString(&buf[i].F_mntfromname[0]) + fs.SysTypeName = bytePtrToString(&buf[i].F_fstypename[0]) + + fslist = append(fslist, fs) + } + + self.List = fslist + + return err +} + +func (self *FileSystemUsage) Get(path string) error { + stat := syscall.Statfs_t{} + err := syscall.Statfs(path, &stat) + if err != nil { + return err + } + + self.Total = uint64(stat.F_blocks) * uint64(stat.F_bsize) + self.Free = uint64(stat.F_bfree) * uint64(stat.F_bsize) + self.Avail = uint64(stat.F_bavail) * uint64(stat.F_bsize) + self.Used = self.Total - self.Free + self.Files = stat.F_files + self.FreeFiles = stat.F_ffree + + return nil +} + +func (self *FDUsage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *LoadAverage) Get() error { + avg := []C.double{0, 0, 0} + + C.getloadavg(&avg[0], C.int(len(avg))) + + self.One = float64(avg[0]) + self.Five = float64(avg[1]) + self.Fifteen = float64(avg[2]) + + return nil +} + +func (self *Uptime) Get() error { + tv := syscall.Timeval{} + mib := [2]int32{C.CTL_KERN, C.KERN_BOOTTIME} + + n := uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + + if errno != 0 || n == 0 { + return nil + } + + // Now perform the actual sysctl(3) call, storing the result in tv + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&tv)), uintptr(unsafe.Pointer(&n)), 0, 0) + + if errno != 0 || n == 0 { + return nil + } + + self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds() + + return nil +} + +func (self *Mem) Get() error { + n := uintptr(0) + + var uvmexp Uvmexp + mib := [2]int32{C.CTL_VM, C.VM_UVMEXP} + n = uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + var bcachestats Bcachestats + mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT} + n = uintptr(0) + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + self.Total = uint64(uvmexp.npages) << uvmexp.pageshift + self.Used = uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift + self.Free = uint64(uvmexp.free) << uvmexp.pageshift + + self.ActualFree = self.Free + (uint64(bcachestats.numbufpages) << uvmexp.pageshift) + self.ActualUsed = self.Used - (uint64(bcachestats.numbufpages) << uvmexp.pageshift) + + return nil +} + +func (self *Swap) Get() error { + nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0) + + // If there are no swap devices, nothing to do here. + if nswap == 0 { + return nil + } + + swdev := make([]Swapent, nswap) + + rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap) + if rnswap == 0 { + return nil + } + + for i := 0; i < int(nswap); i++ { + if swdev[i].se_flags&C.SWF_ENABLE == 2 { + self.Used = self.Used + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE)) + self.Total = self.Total + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE)) + } + } + + self.Free = self.Total - self.Used + + return nil +} + +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Cpu) Get() error { + load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE} + + mib := [2]int32{C.CTL_KERN, C.KERN_CPTIME} + n := uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&load)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + self.User = uint64(load[0]) + self.Nice = uint64(load[1]) + self.Sys = uint64(load[2]) + self.Irq = uint64(load[3]) + self.Idle = uint64(load[4]) + + return nil +} + +func (self *CpuList) Get() error { + mib := [2]int32{C.CTL_HW, C.HW_NCPU} + var ncpu int + + n := uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) + + if errno != 0 || n == 0 { + return nil + } + + // Now perform the actual sysctl(3) call, storing the result in ncpu + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&n)), 0, 0) + + if errno != 0 || n == 0 { + return nil + } + + load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE} + + self.List = make([]Cpu, ncpu) + for curcpu := range self.List { + sysctlCptime(ncpu, curcpu, &load) + fillCpu(&self.List[curcpu], load) + } + + return nil +} + +func (self *ProcList) Get() error { + return nil +} + +func (self *ProcArgs) Get(pid int) error { + return nil +} + +func (self *ProcEnv) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *ProcState) Get(pid int) error { + return nil +} + +func (self *ProcMem) Get(pid int) error { + return nil +} + +func (self *ProcTime) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *ProcExe) Get(pid int) error { + return nil +} + +func (self *ProcFDUsage) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Rusage) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) { + cpu.User = uint64(load[0]) + cpu.Nice = uint64(load[1]) + cpu.Sys = uint64(load[2]) + cpu.Irq = uint64(load[3]) + cpu.Idle = uint64(load[4]) +} + +func sysctlCptime(ncpu int, curcpu int, load *[C.CPUSTATES]C.long) error { + var mib []int32 + + // Use the correct mib based on the number of CPUs and fill out the + // current CPU number in case of SMP. (0 indexed cf. self.List) + if ncpu == 0 { + mib = []int32{C.CTL_KERN, C.KERN_CPTIME} + } else { + mib = []int32{C.CTL_KERN, C.KERN_CPTIME2, int32(curcpu)} + } + + len := len(mib) + + n := uintptr(0) + // First we determine how much memory we'll need to pass later on (via `n`) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), 0, uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), uintptr(unsafe.Pointer(load)), uintptr(unsafe.Pointer(&n)), 0, 0) + if errno != 0 || n == 0 { + return nil + } + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_stub.go b/vendor/github.com/elastic/gosigar/sigar_stub.go new file mode 100644 index 00000000..de9565ae --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_stub.go @@ -0,0 +1,75 @@ +// +build !darwin,!freebsd,!linux,!openbsd,!windows + +package gosigar + +import ( + "runtime" +) + +func (c *Cpu) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (l *LoadAverage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (m *Mem) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (s *Swap) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (s *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (f *FDUsage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcTime) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *FileSystemUsage) Get(path string) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *CpuList) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcState) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcExe) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcMem) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcFDUsage) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcEnv) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcList) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (p *ProcArgs) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Rusage) Get(int) error { + return ErrNotImplemented{runtime.GOOS} +} diff --git a/vendor/github.com/elastic/gosigar/sigar_unix.go b/vendor/github.com/elastic/gosigar/sigar_unix.go new file mode 100644 index 00000000..3f3a9f7f --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_unix.go @@ -0,0 +1,69 @@ +// Copyright (c) 2012 VMware, Inc. + +// +build darwin freebsd linux + +package gosigar + +import ( + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +func (self *FileSystemUsage) Get(path string) error { + stat := syscall.Statfs_t{} + err := syscall.Statfs(path, &stat) + if err != nil { + return err + } + + self.Total = uint64(stat.Blocks) * uint64(stat.Bsize) + self.Free = uint64(stat.Bfree) * uint64(stat.Bsize) + self.Avail = uint64(stat.Bavail) * uint64(stat.Bsize) + self.Used = self.Total - self.Free + self.Files = stat.Files + self.FreeFiles = uint64(stat.Ffree) + + return nil +} + +func (r *Rusage) Get(who int) error { + ru, err := getResourceUsage(who) + if err != nil { + return err + } + + uTime := convertRtimeToDur(ru.Utime) + sTime := convertRtimeToDur(ru.Stime) + + r.Utime = uTime + r.Stime = sTime + r.Maxrss = int64(ru.Maxrss) + r.Ixrss = int64(ru.Ixrss) + r.Idrss = int64(ru.Idrss) + r.Isrss = int64(ru.Isrss) + r.Minflt = int64(ru.Minflt) + r.Majflt = int64(ru.Majflt) + r.Nswap = int64(ru.Nswap) + r.Inblock = int64(ru.Inblock) + r.Oublock = int64(ru.Oublock) + r.Msgsnd = int64(ru.Msgsnd) + r.Msgrcv = int64(ru.Msgrcv) + r.Nsignals = int64(ru.Nsignals) + r.Nvcsw = int64(ru.Nvcsw) + r.Nivcsw = int64(ru.Nivcsw) + + return nil +} + +func getResourceUsage(who int) (unix.Rusage, error) { + r := unix.Rusage{} + err := unix.Getrusage(who, &r) + + return r, err +} + +func convertRtimeToDur(t unix.Timeval) time.Duration { + return time.Duration(t.Nano()) +} diff --git a/vendor/github.com/elastic/gosigar/sigar_util.go b/vendor/github.com/elastic/gosigar/sigar_util.go new file mode 100644 index 00000000..bf93b02b --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_util.go @@ -0,0 +1,22 @@ +// Copyright (c) 2012 VMware, Inc. + +package gosigar + +import ( + "unsafe" +) + +func bytePtrToString(ptr *int8) string { + bytes := (*[10000]byte)(unsafe.Pointer(ptr)) + + n := 0 + for bytes[n] != 0 { + n++ + } + + return string(bytes[0:n]) +} + +func chop(buf []byte) []byte { + return buf[0 : len(buf)-1] +} diff --git a/vendor/github.com/elastic/gosigar/sigar_windows.go b/vendor/github.com/elastic/gosigar/sigar_windows.go new file mode 100644 index 00000000..fc868daf --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sigar_windows.go @@ -0,0 +1,409 @@ +// Copyright (c) 2012 VMware, Inc. + +package gosigar + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + "syscall" + "time" + + "github.com/elastic/gosigar/sys/windows" + "github.com/pkg/errors" +) + +var ( + // version is Windows version of the host OS. + version = windows.GetWindowsVersion() + + // processQueryLimitedInfoAccess is set to PROCESS_QUERY_INFORMATION for Windows + // 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer + // OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION. + processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION + + // bootTime is the time when the OS was last booted. This value may be nil + // on operating systems that do not support the WMI query used to obtain it. + bootTime *time.Time + bootTimeLock sync.Mutex +) + +func init() { + if !version.IsWindowsVistaOrGreater() { + // PROCESS_QUERY_LIMITED_INFORMATION cannot be used on 2003 or XP. + processQueryLimitedInfoAccess = syscall.PROCESS_QUERY_INFORMATION + } +} + +func (self *LoadAverage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *FDUsage) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *ProcEnv) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *ProcExe) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *ProcFDUsage) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Uptime) Get() error { + // Minimum supported OS is Windows Vista. + if !version.IsWindowsVistaOrGreater() { + return ErrNotImplemented{runtime.GOOS} + } + + bootTimeLock.Lock() + defer bootTimeLock.Unlock() + if bootTime == nil { + uptime, err := windows.GetTickCount64() + if err != nil { + return errors.Wrap(err, "failed to get boot time using win32 api") + } + var boot = time.Unix(int64(uptime), 0) + bootTime = &boot + } + + self.Length = time.Since(*bootTime).Seconds() + return nil +} + +func (self *Mem) Get() error { + memoryStatusEx, err := windows.GlobalMemoryStatusEx() + if err != nil { + return errors.Wrap(err, "GlobalMemoryStatusEx failed") + } + + self.Total = memoryStatusEx.TotalPhys + self.Free = memoryStatusEx.AvailPhys + self.Used = self.Total - self.Free + self.ActualFree = self.Free + self.ActualUsed = self.Used + return nil +} + +func (self *Swap) Get() error { + memoryStatusEx, err := windows.GlobalMemoryStatusEx() + if err != nil { + return errors.Wrap(err, "GlobalMemoryStatusEx failed") + } + + self.Total = memoryStatusEx.TotalPageFile + self.Free = memoryStatusEx.AvailPageFile + self.Used = self.Total - self.Free + return nil +} + +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + +func (self *Cpu) Get() error { + idle, kernel, user, err := windows.GetSystemTimes() + if err != nil { + return errors.Wrap(err, "GetSystemTimes failed") + } + + // CPU times are reported in milliseconds by gosigar. + self.Idle = uint64(idle / time.Millisecond) + self.Sys = uint64(kernel / time.Millisecond) + self.User = uint64(user / time.Millisecond) + return nil +} + +func (self *CpuList) Get() error { + cpus, err := windows.NtQuerySystemProcessorPerformanceInformation() + if err != nil { + return errors.Wrap(err, "NtQuerySystemProcessorPerformanceInformation failed") + } + + self.List = make([]Cpu, 0, len(cpus)) + for _, cpu := range cpus { + self.List = append(self.List, Cpu{ + Idle: uint64(cpu.IdleTime / time.Millisecond), + Sys: uint64(cpu.KernelTime / time.Millisecond), + User: uint64(cpu.UserTime / time.Millisecond), + }) + } + return nil +} + +func (self *FileSystemList) Get() error { + drives, err := windows.GetAccessPaths() + if err != nil { + return errors.Wrap(err, "GetAccessPaths failed") + } + + for _, drive := range drives { + dt, err := windows.GetDriveType(drive) + if err != nil { + return errors.Wrapf(err, "GetDriveType failed") + } + + self.List = append(self.List, FileSystem{ + DirName: drive, + DevName: drive, + TypeName: dt.String(), + }) + } + return nil +} + +// Get retrieves a list of all process identifiers (PIDs) in the system. +func (self *ProcList) Get() error { + pids, err := windows.EnumProcesses() + if err != nil { + return errors.Wrap(err, "EnumProcesses failed") + } + + // Convert uint32 PIDs to int. + self.List = make([]int, 0, len(pids)) + for _, pid := range pids { + self.List = append(self.List, int(pid)) + } + return nil +} + +func (self *ProcState) Get(pid int) error { + var errs []error + + var err error + self.Name, err = getProcName(pid) + if err != nil { + errs = append(errs, errors.Wrap(err, "getProcName failed")) + } + + self.State, err = getProcStatus(pid) + if err != nil { + errs = append(errs, errors.Wrap(err, "getProcStatus failed")) + } + + self.Ppid, err = getParentPid(pid) + if err != nil { + errs = append(errs, errors.Wrap(err, "getParentPid failed")) + } + + // getProcCredName will often fail when run as a non-admin user. This is + // caused by strict ACL of the process token belonging to other users. + // Instead of failing completely, ignore this error and still return most + // data with an empty Username. + self.Username, _ = getProcCredName(pid) + + if len(errs) > 0 { + errStrs := make([]string, 0, len(errs)) + for _, e := range errs { + errStrs = append(errStrs, e.Error()) + } + return errors.New(strings.Join(errStrs, "; ")) + } + return nil +} + +// getProcName returns the process name associated with the PID. +func getProcName(pid int) (string, error) { + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) + if err != nil { + return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + filename, err := windows.GetProcessImageFileName(handle) + if err != nil { + return "", errors.Wrapf(err, "GetProcessImageFileName failed for pid=%v", pid) + } + + return filepath.Base(filename), nil +} + +// getProcStatus returns the status of a process. +func getProcStatus(pid int) (RunState, error) { + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) + if err != nil { + return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + var exitCode uint32 + err = syscall.GetExitCodeProcess(handle, &exitCode) + if err != nil { + return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v", pid) + } + + if exitCode == 259 { //still active + return RunStateRun, nil + } + return RunStateSleep, nil +} + +// getParentPid returns the parent process ID of a process. +func getParentPid(pid int) (int, error) { + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) + if err != nil { + return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + procInfo, err := windows.NtQueryProcessBasicInformation(handle) + if err != nil { + return 0, errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) + } + + return int(procInfo.InheritedFromUniqueProcessID), nil +} + +func getProcCredName(pid int) (string, error) { + handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) + if err != nil { + return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + // Find process token via win32. + var token syscall.Token + err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token) + if err != nil { + return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid) + } + // Close token to prevent handle leaks. + defer token.Close() + + // Find the token user. + tokenUser, err := token.GetTokenUser() + if err != nil { + return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid) + } + + // Look up domain account by SID. + account, domain, _, err := tokenUser.User.Sid.LookupAccount("") + if err != nil { + sid, sidErr := tokenUser.User.Sid.String() + if sidErr != nil { + return "", errors.Wrapf(err, "failed while looking up account name for pid=%v", pid) + } + return "", errors.Wrapf(err, "failed while looking up account name for SID=%v of pid=%v", sid, pid) + } + + return fmt.Sprintf(`%s\%s`, domain, account), nil +} + +func (self *ProcMem) Get(pid int) error { + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) + if err != nil { + return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + counters, err := windows.GetProcessMemoryInfo(handle) + if err != nil { + return errors.Wrapf(err, "GetProcessMemoryInfo failed for pid=%v", pid) + } + + self.Resident = uint64(counters.WorkingSetSize) + self.Size = uint64(counters.PrivateUsage) + return nil +} + +func (self *ProcTime) Get(pid int) error { + cpu, err := getProcTimes(pid) + if err != nil { + return err + } + + // Windows epoch times are expressed as time elapsed since midnight on + // January 1, 1601 at Greenwich, England. This converts the Filetime to + // unix epoch in milliseconds. + self.StartTime = uint64(cpu.CreationTime.Nanoseconds() / 1e6) + + // Convert to millis. + self.User = uint64(windows.FiletimeToDuration(&cpu.UserTime).Nanoseconds() / 1e6) + self.Sys = uint64(windows.FiletimeToDuration(&cpu.KernelTime).Nanoseconds() / 1e6) + self.Total = self.User + self.Sys + + return nil +} + +func getProcTimes(pid int) (*syscall.Rusage, error) { + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) + if err != nil { + return nil, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + + var cpu syscall.Rusage + if err := syscall.GetProcessTimes(handle, &cpu.CreationTime, &cpu.ExitTime, &cpu.KernelTime, &cpu.UserTime); err != nil { + return nil, errors.Wrapf(err, "GetProcessTimes failed for pid=%v", pid) + } + + return &cpu, nil +} + +func (self *ProcArgs) Get(pid int) error { + // The minimum supported client for Win32_Process is Windows Vista. + if !version.IsWindowsVistaOrGreater() { + return ErrNotImplemented{runtime.GOOS} + } + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) + if err != nil { + return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + pbi, err := windows.NtQueryProcessBasicInformation(handle) + if err != nil { + return errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) + } + if err != nil { + return nil + } + userProcParams, err := windows.GetUserProcessParams(handle, pbi) + if err != nil { + return nil + } + if argsW, err := windows.ReadProcessUnicodeString(handle, &userProcParams.CommandLine); err == nil { + self.List, err = windows.ByteSliceToStringSlice(argsW) + if err != nil { + return err + } + } + return nil +} + +func (self *FileSystemUsage) Get(path string) error { + freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, err := windows.GetDiskFreeSpaceEx(path) + if err != nil { + return errors.Wrap(err, "GetDiskFreeSpaceEx failed") + } + + self.Total = totalNumberOfBytes + self.Free = totalNumberOfFreeBytes + self.Used = self.Total - self.Free + self.Avail = freeBytesAvailable + return nil +} + +func (self *Rusage) Get(who int) error { + if who != 0 { + return ErrNotImplemented{runtime.GOOS} + } + + pid := os.Getpid() + cpu, err := getProcTimes(pid) + if err != nil { + return err + } + + self.Utime = windows.FiletimeToDuration(&cpu.UserTime) + self.Stime = windows.FiletimeToDuration(&cpu.KernelTime) + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sys/windows/doc.go b/vendor/github.com/elastic/gosigar/sys/windows/doc.go new file mode 100644 index 00000000..dda57aa8 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/doc.go @@ -0,0 +1,2 @@ +// Package windows contains various Windows system call. +package windows diff --git a/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go b/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go new file mode 100644 index 00000000..85de365e --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go @@ -0,0 +1,132 @@ +// +build windows + +package windows + +import ( + "bytes" + "encoding/binary" + "io" + "runtime" + "syscall" + "time" + "unsafe" + + "github.com/pkg/errors" +) + +// On both 32-bit and 64-bit systems NtQuerySystemInformation expects the +// size of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION to be 48. +const sizeofSystemProcessorPerformanceInformation = 48 + +// ProcessBasicInformation is an equivalent representation of +// PROCESS_BASIC_INFORMATION in the Windows API. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx +type ProcessBasicInformation struct { + ExitStatus uint + PebBaseAddress uintptr + AffinityMask uint + BasePriority uint + UniqueProcessID uint + InheritedFromUniqueProcessID uint +} + +// NtQueryProcessBasicInformation queries basic information about the process +// associated with the given handle (provided by OpenProcess). It uses the +// NtQueryInformationProcess function to collect the data. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx +func NtQueryProcessBasicInformation(handle syscall.Handle) (ProcessBasicInformation, error) { + var processBasicInfo ProcessBasicInformation + processBasicInfoPtr := (*byte)(unsafe.Pointer(&processBasicInfo)) + size := uint32(unsafe.Sizeof(processBasicInfo)) + ntStatus, _ := _NtQueryInformationProcess(handle, 0, processBasicInfoPtr, size, nil) + if ntStatus != 0 { + return ProcessBasicInformation{}, errors.Errorf("NtQueryInformationProcess failed, NTSTATUS=0x%X", ntStatus) + } + + return processBasicInfo, nil +} + +// SystemProcessorPerformanceInformation contains CPU performance information +// for a single CPU. +type SystemProcessorPerformanceInformation struct { + IdleTime time.Duration // Amount of time spent idle. + KernelTime time.Duration // Kernel time does NOT include time spent in idle. + UserTime time.Duration // Amount of time spent executing in user mode. +} + +// _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION is an equivalent representation of +// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION in the Windows API. This struct is +// used internally with NtQuerySystemInformation call and is not exported. The +// exported equivalent is SystemProcessorPerformanceInformation. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx +type _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION struct { + IdleTime int64 + KernelTime int64 + UserTime int64 + Reserved1 [2]int64 + Reserved2 uint32 +} + +// NtQuerySystemProcessorPerformanceInformation queries CPU performance +// information for each CPU. It uses the NtQuerySystemInformation function to +// collect the SystemProcessorPerformanceInformation. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx +func NtQuerySystemProcessorPerformanceInformation() ([]SystemProcessorPerformanceInformation, error) { + // NTSTATUS code for success. + // https://msdn.microsoft.com/en-us/library/cc704588.aspx + const STATUS_SUCCESS = 0 + + // From the _SYSTEM_INFORMATION_CLASS enum. + // http://processhacker.sourceforge.net/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0 + const systemProcessorPerformanceInformation = 8 + + // Create a buffer large enough to hold an entry for each processor. + b := make([]byte, runtime.NumCPU()*sizeofSystemProcessorPerformanceInformation) + + // Query the performance information. Note that this function uses 0 to + // indicate success. Most other Windows functions use non-zero for success. + var returnLength uint32 + ntStatus, _ := _NtQuerySystemInformation(systemProcessorPerformanceInformation, &b[0], uint32(len(b)), &returnLength) + if ntStatus != STATUS_SUCCESS { + return nil, errors.Errorf("NtQuerySystemInformation failed, NTSTATUS=0x%X, bufLength=%v, returnLength=%v", ntStatus, len(b), returnLength) + } + + return readSystemProcessorPerformanceInformationBuffer(b) +} + +// readSystemProcessorPerformanceInformationBuffer reads from a buffer +// containing SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION data. The buffer should +// contain one entry for each CPU. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx +func readSystemProcessorPerformanceInformationBuffer(b []byte) ([]SystemProcessorPerformanceInformation, error) { + n := len(b) / sizeofSystemProcessorPerformanceInformation + r := bytes.NewReader(b) + + rtn := make([]SystemProcessorPerformanceInformation, 0, n) + for i := 0; i < n; i++ { + _, err := r.Seek(int64(i*sizeofSystemProcessorPerformanceInformation), io.SeekStart) + if err != nil { + return nil, errors.Wrapf(err, "failed to seek to cpuN=%v in buffer", i) + } + + times := make([]uint64, 3) + for j := range times { + err := binary.Read(r, binary.LittleEndian, ×[j]) + if err != nil { + return nil, errors.Wrapf(err, "failed reading cpu times for cpuN=%v", i) + } + } + + idleTime := time.Duration(times[0] * 100) + kernelTime := time.Duration(times[1] * 100) + userTime := time.Duration(times[2] * 100) + + rtn = append(rtn, SystemProcessorPerformanceInformation{ + IdleTime: idleTime, + KernelTime: kernelTime - idleTime, // Subtract out idle time from kernel time. + UserTime: userTime, + }) + } + + return rtn, nil +} diff --git a/vendor/github.com/elastic/gosigar/sys/windows/privileges.go b/vendor/github.com/elastic/gosigar/sys/windows/privileges.go new file mode 100644 index 00000000..28c78fd2 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/privileges.go @@ -0,0 +1,272 @@ +// +build windows + +package windows + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "runtime" + "strings" + "sync" + "syscall" + + "github.com/pkg/errors" + "golang.org/x/sys/windows" +) + +// Cache of privilege names to LUIDs. +var ( + privNames = make(map[string]int64) + privNameMutex sync.Mutex +) + +const ( + // SeDebugPrivilege is the name of the privilege used to debug programs. + SeDebugPrivilege = "SeDebugPrivilege" +) + +// Errors returned by AdjustTokenPrivileges. +const ( + ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 +) + +// Attribute bits for privileges. +const ( + _SE_PRIVILEGE_ENABLED_BY_DEFAULT uint32 = 0x00000001 + _SE_PRIVILEGE_ENABLED uint32 = 0x00000002 + _SE_PRIVILEGE_REMOVED uint32 = 0x00000004 + _SE_PRIVILEGE_USED_FOR_ACCESS uint32 = 0x80000000 +) + +// Privilege contains information about a single privilege associated with a +// Token. +type Privilege struct { + LUID int64 `json:"-"` // Locally unique identifier (guaranteed only until the system is restarted). + Name string `json:"-"` + EnabledByDefault bool `json:"enabled_by_default,omitempty"` + Enabled bool `json:"enabled"` + Removed bool `json:"removed,omitempty"` + Used bool `json:"used,omitempty"` +} + +func (p Privilege) String() string { + var buf bytes.Buffer + buf.WriteString(p.Name) + buf.WriteString("=(") + + opts := make([]string, 0, 4) + if p.EnabledByDefault { + opts = append(opts, "Default") + } + if p.Enabled { + opts = append(opts, "Enabled") + } + if !p.EnabledByDefault && !p.Enabled { + opts = append(opts, "Disabled") + } + if p.Removed { + opts = append(opts, "Removed") + } + if p.Used { + opts = append(opts, "Used") + } + + buf.WriteString(strings.Join(opts, ", ")) + buf.WriteString(")") + + // Example: SeDebugPrivilege=(Default, Enabled) + return buf.String() +} + +// User represent the information about a Windows account. +type User struct { + SID string + Account string + Domain string + Type uint32 +} + +func (u User) String() string { + return fmt.Sprintf(`User:%v\%v, SID:%v, Type:%v`, u.Domain, u.Account, u.SID, u.Type) +} + +// DebugInfo contains general debug info about the current process. +type DebugInfo struct { + OSVersion Version // OS version info. + Arch string // Architecture of the machine. + NumCPU int // Number of CPUs. + User User // User that this process is running as. + ProcessPrivs map[string]Privilege // Privileges held by the process. +} + +func (d DebugInfo) String() string { + bytes, _ := json.Marshal(d) + return string(bytes) +} + +// LookupPrivilegeName looks up a privilege name given a LUID value. +func LookupPrivilegeName(systemName string, luid int64) (string, error) { + buf := make([]uint16, 256) + bufSize := uint32(len(buf)) + err := _LookupPrivilegeName(systemName, &luid, &buf[0], &bufSize) + if err != nil { + return "", errors.Wrapf(err, "LookupPrivilegeName failed for luid=%v", luid) + } + + return syscall.UTF16ToString(buf), nil +} + +// mapPrivileges maps privilege names to LUID values. +func mapPrivileges(names []string) ([]int64, error) { + var privileges []int64 + privNameMutex.Lock() + defer privNameMutex.Unlock() + for _, name := range names { + p, ok := privNames[name] + if !ok { + err := _LookupPrivilegeValue("", name, &p) + if err != nil { + return nil, errors.Wrapf(err, "LookupPrivilegeValue failed on '%v'", name) + } + privNames[name] = p + } + privileges = append(privileges, p) + } + return privileges, nil +} + +// EnableTokenPrivileges enables the specified privileges in the given +// Token. The token must have TOKEN_ADJUST_PRIVILEGES access. If the token +// does not already contain the privilege it cannot be enabled. +func EnableTokenPrivileges(token syscall.Token, privileges ...string) error { + privValues, err := mapPrivileges(privileges) + if err != nil { + return err + } + + var b bytes.Buffer + binary.Write(&b, binary.LittleEndian, uint32(len(privValues))) + for _, p := range privValues { + binary.Write(&b, binary.LittleEndian, p) + binary.Write(&b, binary.LittleEndian, uint32(_SE_PRIVILEGE_ENABLED)) + } + + success, err := _AdjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(b.Len()), nil, nil) + if !success { + return err + } + if err == ERROR_NOT_ALL_ASSIGNED { + return errors.Wrap(err, "error not all privileges were assigned") + } + + return nil +} + +// GetTokenPrivileges returns a list of privileges associated with a token. +// The provided token must have at a minimum TOKEN_QUERY access. This is a +// wrapper around the GetTokenInformation function. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx +func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) { + // Determine the required buffer size. + var size uint32 + syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size) + + // This buffer will receive a TOKEN_PRIVILEGE structure. + b := bytes.NewBuffer(make([]byte, size)) + err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size) + if err != nil { + return nil, errors.Wrap(err, "GetTokenInformation failed") + } + + var privilegeCount uint32 + err = binary.Read(b, binary.LittleEndian, &privilegeCount) + if err != nil { + return nil, errors.Wrap(err, "failed to read PrivilegeCount") + } + + rtn := make(map[string]Privilege, privilegeCount) + for i := 0; i < int(privilegeCount); i++ { + var luid int64 + err = binary.Read(b, binary.LittleEndian, &luid) + if err != nil { + return nil, errors.Wrap(err, "failed to read LUID value") + } + + var attributes uint32 + err = binary.Read(b, binary.LittleEndian, &attributes) + if err != nil { + return nil, errors.Wrap(err, "failed to read attributes") + } + + name, err := LookupPrivilegeName("", luid) + if err != nil { + return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid) + } + + rtn[name] = Privilege{ + LUID: luid, + Name: name, + EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0, + Enabled: (attributes & _SE_PRIVILEGE_ENABLED) > 0, + Removed: (attributes & _SE_PRIVILEGE_REMOVED) > 0, + Used: (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0, + } + } + + return rtn, nil +} + +// GetTokenUser returns the User associated with the given Token. +func GetTokenUser(token syscall.Token) (User, error) { + tokenUser, err := token.GetTokenUser() + if err != nil { + return User{}, errors.Wrap(err, "GetTokenUser failed") + } + + var user User + user.SID, err = tokenUser.User.Sid.String() + if err != nil { + return user, errors.Wrap(err, "ConvertSidToStringSid failed") + } + + user.Account, user.Domain, user.Type, err = tokenUser.User.Sid.LookupAccount("") + if err != nil { + return user, errors.Wrap(err, "LookupAccountSid failed") + } + + return user, nil +} + +// GetDebugInfo returns general debug info about the current process. +func GetDebugInfo() (*DebugInfo, error) { + h, err := windows.GetCurrentProcess() + if err != nil { + return nil, err + } + + var token syscall.Token + err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token) + if err != nil { + return nil, err + } + + privs, err := GetTokenPrivileges(token) + if err != nil { + return nil, err + } + + user, err := GetTokenUser(token) + if err != nil { + return nil, err + } + + return &DebugInfo{ + User: user, + ProcessPrivs: privs, + OSVersion: GetWindowsVersion(), + Arch: runtime.GOARCH, + NumCPU: runtime.NumCPU(), + }, nil +} diff --git a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go new file mode 100644 index 00000000..7da8a071 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go @@ -0,0 +1,588 @@ +package windows + +import ( + "fmt" + "syscall" + "time" + "unsafe" + + "github.com/pkg/errors" +) + +var ( + sizeofUint32 = 4 + sizeofProcessEntry32 = uint32(unsafe.Sizeof(ProcessEntry32{})) + sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{})) + sizeofMemoryStatusEx = uint32(unsafe.Sizeof(MemoryStatusEx{})) +) + +// Process-specific access rights. Others are declared in the syscall package. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx +const ( + PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000 + PROCESS_VM_READ uint32 = 0x0010 +) + +// SizeOfRtlUserProcessParameters gives the size +// of the RtlUserProcessParameters struct. +const SizeOfRtlUserProcessParameters = unsafe.Sizeof(RtlUserProcessParameters{}) + +// MAX_PATH is the maximum length for a path in Windows. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx +const MAX_PATH = 260 + +// DriveType represents a type of drive (removable, fixed, CD-ROM, RAM disk, or +// network drive). +type DriveType uint32 + +// Drive types as returned by GetDriveType. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx +const ( + DRIVE_UNKNOWN DriveType = iota + DRIVE_NO_ROOT_DIR + DRIVE_REMOVABLE + DRIVE_FIXED + DRIVE_REMOTE + DRIVE_CDROM + DRIVE_RAMDISK +) + +// UnicodeString is Go's equivalent for the _UNICODE_STRING struct. +type UnicodeString struct { + Size uint16 + MaximumLength uint16 + Buffer uintptr +} + +// RtlUserProcessParameters is Go's equivalent for the +// _RTL_USER_PROCESS_PARAMETERS struct. +// A few undocumented fields are exposed. +type RtlUserProcessParameters struct { + Reserved1 [16]byte + Reserved2 [5]uintptr + CurrentDirectoryPath UnicodeString + CurrentDirectoryHandle uintptr + DllPath UnicodeString + ImagePathName UnicodeString + CommandLine UnicodeString +} + +func (dt DriveType) String() string { + names := map[DriveType]string{ + DRIVE_UNKNOWN: "unknown", + DRIVE_NO_ROOT_DIR: "invalid", + DRIVE_REMOVABLE: "removable", + DRIVE_FIXED: "fixed", + DRIVE_REMOTE: "remote", + DRIVE_CDROM: "cdrom", + DRIVE_RAMDISK: "ramdisk", + } + + name, found := names[dt] + if !found { + return "unknown DriveType value" + } + return name +} + +// Flags that can be used with CreateToolhelp32Snapshot. +const ( + TH32CS_INHERIT uint32 = 0x80000000 // Indicates that the snapshot handle is to be inheritable. + TH32CS_SNAPHEAPLIST uint32 = 0x00000001 // Includes all heaps of the process specified in th32ProcessID in the snapshot. + TH32CS_SNAPMODULE uint32 = 0x00000008 // Includes all modules of the process specified in th32ProcessID in the snapshot. + TH32CS_SNAPMODULE32 uint32 = 0x00000010 // Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process. + TH32CS_SNAPPROCESS uint32 = 0x00000002 // Includes all processes in the system in the snapshot. + TH32CS_SNAPTHREAD uint32 = 0x00000004 // Includes all threads in the system in the snapshot. +) + +// ProcessEntry32 is an equivalent representation of PROCESSENTRY32 in the +// Windows API. It contains a process's information. Do not modify or reorder. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx +type ProcessEntry32 struct { + size uint32 + CntUsage uint32 + ProcessID uint32 + DefaultHeapID uintptr + ModuleID uint32 + CntThreads uint32 + ParentProcessID uint32 + PriorityClassBase int32 + Flags uint32 + exeFile [MAX_PATH]uint16 +} + +// ExeFile returns the name of the executable file for the process. It does +// not contain the full path. +func (p ProcessEntry32) ExeFile() string { + return syscall.UTF16ToString(p.exeFile[:]) +} + +func (p ProcessEntry32) String() string { + return fmt.Sprintf("{CntUsage:%v ProcessID:%v DefaultHeapID:%v ModuleID:%v "+ + "CntThreads:%v ParentProcessID:%v PriorityClassBase:%v Flags:%v ExeFile:%v", + p.CntUsage, p.ProcessID, p.DefaultHeapID, p.ModuleID, p.CntThreads, + p.ParentProcessID, p.PriorityClassBase, p.Flags, p.ExeFile()) +} + +// MemoryStatusEx is an equivalent representation of MEMORYSTATUSEX in the +// Windows API. It contains information about the current state of both physical +// and virtual memory, including extended memory. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770 +type MemoryStatusEx struct { + length uint32 + MemoryLoad uint32 + TotalPhys uint64 + AvailPhys uint64 + TotalPageFile uint64 + AvailPageFile uint64 + TotalVirtual uint64 + AvailVirtual uint64 + AvailExtendedVirtual uint64 +} + +// ProcessMemoryCountersEx is an equivalent representation of +// PROCESS_MEMORY_COUNTERS_EX in the Windows API. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx +type ProcessMemoryCountersEx struct { + cb uint32 + PageFaultCount uint32 + PeakWorkingSetSize uintptr + WorkingSetSize uintptr + QuotaPeakPagedPoolUsage uintptr + QuotaPagedPoolUsage uintptr + QuotaPeakNonPagedPoolUsage uintptr + QuotaNonPagedPoolUsage uintptr + PagefileUsage uintptr + PeakPagefileUsage uintptr + PrivateUsage uintptr +} + +// GetLogicalDriveStrings returns a list of drives in the system. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364975(v=vs.85).aspx +func GetLogicalDriveStrings() ([]string, error) { + // Determine the size of the buffer required to receive all drives. + bufferLength, err := _GetLogicalDriveStringsW(0, nil) + if err != nil { + return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed to get buffer length") + } + if bufferLength < 0 { + return nil, errors.New("GetLogicalDriveStringsW returned an invalid buffer length") + } + + buffer := make([]uint16, bufferLength) + _, err = _GetLogicalDriveStringsW(uint32(len(buffer)), &buffer[0]) + if err != nil { + return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed") + } + + return UTF16SliceToStringSlice(buffer), nil +} + +// GetAccessPaths returns the list of access paths for volumes in the system. +func GetAccessPaths() ([]string, error) { + volumes, err := GetVolumes() + if err != nil { + return nil, errors.Wrap(err, "GetVolumes failed") + } + + var paths []string + for _, volumeName := range volumes { + volumePaths, err := GetVolumePathsForVolume(volumeName) + if err != nil { + return nil, errors.Wrapf(err, "failed to get list of access paths for volume '%s'", volumeName) + } + if len(volumePaths) == 0 { + continue + } + + // Get only the first path + paths = append(paths, volumePaths[0]) + } + + return paths, nil +} + +// GetVolumes returs the list of volumes in the system. +// https://docs.microsoft.com/es-es/windows/desktop/api/fileapi/nf-fileapi-findfirstvolumew +func GetVolumes() ([]string, error) { + buffer := make([]uint16, MAX_PATH+1) + + var volumes []string + + h, err := _FindFirstVolume(&buffer[0], uint32(len(buffer))) + if err != nil { + return nil, errors.Wrap(err, "FindFirstVolumeW failed") + } + defer _FindVolumeClose(h) + + for { + volumes = append(volumes, syscall.UTF16ToString(buffer)) + + err = _FindNextVolume(h, &buffer[0], uint32(len(buffer))) + if err != nil { + if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES { + break + } + return nil, errors.Wrap(err, "FindNextVolumeW failed") + } + } + + return volumes, nil +} + +// GetVolumePathsForVolume returns the list of volume paths for a volume. +// https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-getvolumepathnamesforvolumenamew +func GetVolumePathsForVolume(volumeName string) ([]string, error) { + var length uint32 + err := _GetVolumePathNamesForVolumeName(volumeName, nil, 0, &length) + if errors.Cause(err) != syscall.ERROR_MORE_DATA { + return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed to get needed buffer length") + } + if length == 0 { + // Not mounted, no paths, that's ok + return nil, nil + } + + buffer := make([]uint16, length*(MAX_PATH+1)) + err = _GetVolumePathNamesForVolumeName(volumeName, &buffer[0], length, &length) + if err != nil { + return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed") + } + + return UTF16SliceToStringSlice(buffer), nil +} + +// GlobalMemoryStatusEx retrieves information about the system's current usage +// of both physical and virtual memory. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx +func GlobalMemoryStatusEx() (MemoryStatusEx, error) { + memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx} + err := _GlobalMemoryStatusEx(&memoryStatusEx) + if err != nil { + return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed") + } + + return memoryStatusEx, nil +} + +// GetProcessMemoryInfo retrieves information about the memory usage of the +// specified process. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx +func GetProcessMemoryInfo(handle syscall.Handle) (ProcessMemoryCountersEx, error) { + processMemoryCountersEx := ProcessMemoryCountersEx{cb: sizeofProcessMemoryCountersEx} + err := _GetProcessMemoryInfo(handle, &processMemoryCountersEx, processMemoryCountersEx.cb) + if err != nil { + return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed") + } + + return processMemoryCountersEx, nil +} + +// GetProcessImageFileName Retrieves the name of the executable file for the +// specified process. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx +func GetProcessImageFileName(handle syscall.Handle) (string, error) { + buffer := make([]uint16, MAX_PATH) + _, err := _GetProcessImageFileName(handle, &buffer[0], uint32(len(buffer))) + if err != nil { + return "", errors.Wrap(err, "GetProcessImageFileName failed") + } + + return syscall.UTF16ToString(buffer), nil +} + +// GetSystemTimes retrieves system timing information. On a multiprocessor +// system, the values returned are the sum of the designated times across all +// processors. The returned kernel time does not include the system idle time. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx +func GetSystemTimes() (idle, kernel, user time.Duration, err error) { + var idleTime, kernelTime, userTime syscall.Filetime + err = _GetSystemTimes(&idleTime, &kernelTime, &userTime) + if err != nil { + return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed") + } + + idle = FiletimeToDuration(&idleTime) + kernel = FiletimeToDuration(&kernelTime) // Kernel time includes idle time so we subtract it out. + user = FiletimeToDuration(&userTime) + + return idle, kernel - idle, user, nil +} + +// FiletimeToDuration converts a Filetime to a time.Duration. Do not use this +// method to convert a Filetime to an actual clock time, for that use +// Filetime.Nanosecond(). +func FiletimeToDuration(ft *syscall.Filetime) time.Duration { + n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals + return time.Duration(n * 100) +} + +// GetDriveType Determines whether a disk drive is a removable, fixed, CD-ROM, +// RAM disk, or network drive. A trailing backslash is required on the +// rootPathName. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939 +func GetDriveType(rootPathName string) (DriveType, error) { + rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) + if err != nil { + return DRIVE_UNKNOWN, errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) + } + + dt, err := _GetDriveType(rootPathNamePtr) + if err != nil { + return DRIVE_UNKNOWN, errors.Wrapf(err, "GetDriveType failed for rootPathName=%v", rootPathName) + } + + return dt, nil +} + +// EnumProcesses retrieves the process identifier for each process object in the +// system. This function can return a max of 65536 PIDs. If there are more +// processes than that then this will not return them all. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx +func EnumProcesses() ([]uint32, error) { + enumProcesses := func(size int) ([]uint32, error) { + var ( + pids = make([]uint32, size) + sizeBytes = len(pids) * sizeofUint32 + bytesWritten uint32 + ) + + err := _EnumProcesses(&pids[0], uint32(sizeBytes), &bytesWritten) + + pidsWritten := int(bytesWritten) / sizeofUint32 + if int(bytesWritten)%sizeofUint32 != 0 || pidsWritten > len(pids) { + return nil, errors.Errorf("EnumProcesses returned an invalid bytesWritten value of %v", bytesWritten) + } + pids = pids[:pidsWritten] + + return pids, err + } + + // Retry the EnumProcesses call with larger arrays if needed. + size := 2048 + var pids []uint32 + for tries := 0; tries < 5; tries++ { + var err error + pids, err = enumProcesses(size) + if err != nil { + return nil, errors.Wrap(err, "EnumProcesses failed") + } + + if len(pids) < size { + break + } + + // Increase the size the pids array and retry the enumProcesses call + // because the array wasn't large enough to hold all of the processes. + size *= 2 + } + + return pids, nil +} + +// GetDiskFreeSpaceEx retrieves information about the amount of space that is +// available on a disk volume, which is the total amount of space, the total +// amount of free space, and the total amount of free space available to the +// user that is associated with the calling thread. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx +func GetDiskFreeSpaceEx(directoryName string) (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64, err error) { + directoryNamePtr, err := syscall.UTF16PtrFromString(directoryName) + if err != nil { + return 0, 0, 0, errors.Wrapf(err, "UTF16PtrFromString failed for directoryName=%v", directoryName) + } + + err = _GetDiskFreeSpaceEx(directoryNamePtr, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes) + if err != nil { + return 0, 0, 0, err + } + + return freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, nil +} + +// CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well +// as the heaps, modules, and threads used by these processes. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx +func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) { + h, err := _CreateToolhelp32Snapshot(flags, pid) + if err != nil { + return syscall.InvalidHandle, err + } + if h == syscall.InvalidHandle { + return syscall.InvalidHandle, syscall.GetLastError() + } + + return h, nil +} + +// Process32First retrieves information about the first process encountered in a +// system snapshot. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834 +func Process32First(handle syscall.Handle) (ProcessEntry32, error) { + processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} + err := _Process32First(handle, &processEntry32) + if err != nil { + return ProcessEntry32{}, errors.Wrap(err, "Process32First failed") + } + + return processEntry32, nil +} + +// Process32Next retrieves information about the next process recorded in a +// system snapshot. When there are no more processes to iterate then +// syscall.ERROR_NO_MORE_FILES is returned (use errors.Cause() to unwrap). +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684836 +func Process32Next(handle syscall.Handle) (ProcessEntry32, error) { + processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} + err := _Process32Next(handle, &processEntry32) + if err != nil { + return ProcessEntry32{}, errors.Wrap(err, "Process32Next failed") + } + + return processEntry32, nil +} + +// UTF16SliceToStringSlice converts slice of uint16 containing a list of UTF16 +// strings to a slice of strings. +func UTF16SliceToStringSlice(buffer []uint16) []string { + // Split the uint16 slice at null-terminators. + var startIdx int + var stringsUTF16 [][]uint16 + for i, value := range buffer { + if value == 0 { + stringsUTF16 = append(stringsUTF16, buffer[startIdx:i]) + startIdx = i + 1 + } + } + + // Convert the utf16 slices to strings. + result := make([]string, 0, len(stringsUTF16)) + for _, stringUTF16 := range stringsUTF16 { + if len(stringUTF16) > 0 { + result = append(result, syscall.UTF16ToString(stringUTF16)) + } + } + + return result +} + +func GetUserProcessParams(handle syscall.Handle, pbi ProcessBasicInformation) (params RtlUserProcessParameters, err error) { + const is32bitProc = unsafe.Sizeof(uintptr(0)) == 4 + + // Offset of params field within PEB structure. + // This structure is different in 32 and 64 bit. + paramsOffset := 0x20 + if is32bitProc { + paramsOffset = 0x10 + } + + // Read the PEB from the target process memory + pebSize := paramsOffset + 8 + peb := make([]byte, pebSize) + nRead, err := ReadProcessMemory(handle, pbi.PebBaseAddress, peb) + if err != nil { + return params, err + } + if nRead != uintptr(pebSize) { + return params, errors.Errorf("PEB: short read (%d/%d)", nRead, pebSize) + } + + // Get the RTL_USER_PROCESS_PARAMETERS struct pointer from the PEB + paramsAddr := *(*uintptr)(unsafe.Pointer(&peb[paramsOffset])) + + // Read the RTL_USER_PROCESS_PARAMETERS from the target process memory + paramsBuf := make([]byte, SizeOfRtlUserProcessParameters) + nRead, err = ReadProcessMemory(handle, paramsAddr, paramsBuf) + if err != nil { + return params, err + } + if nRead != uintptr(SizeOfRtlUserProcessParameters) { + return params, errors.Errorf("RTL_USER_PROCESS_PARAMETERS: short read (%d/%d)", nRead, SizeOfRtlUserProcessParameters) + } + + params = *(*RtlUserProcessParameters)(unsafe.Pointer(¶msBuf[0])) + return params, nil +} + +func ReadProcessUnicodeString(handle syscall.Handle, s *UnicodeString) ([]byte, error) { + buf := make([]byte, s.Size) + nRead, err := ReadProcessMemory(handle, s.Buffer, buf) + if err != nil { + return nil, err + } + if nRead != uintptr(s.Size) { + return nil, errors.Errorf("unicode string: short read: (%d/%d)", nRead, s.Size) + } + return buf, nil +} + +// Use Windows' CommandLineToArgv API to split an UTF-16 command line string +// into a list of parameters. +func ByteSliceToStringSlice(utf16 []byte) ([]string, error) { + if len(utf16) == 0 { + return nil, nil + } + var numArgs int32 + argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs) + if err != nil { + return nil, err + } + + // Free memory allocated for CommandLineToArgvW arguments. + defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(argsWide))) + + args := make([]string, numArgs) + for idx := range args { + args[idx] = syscall.UTF16ToString(argsWide[idx][:]) + } + return args, nil +} + +// ReadProcessMemory reads from another process memory. The Handle needs to have +// the PROCESS_VM_READ right. +// A zero-byte read is a no-op, no error is returned. +func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) { + n := len(dest) + if n == 0 { + return 0, nil + } + if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil { + return 0, err + } + return numRead, nil +} + +func GetTickCount64() (uptime uint64, err error) { + if uptime, err = _GetTickCount64(); err != nil { + return 0, err + } + return uptime, nil +} + +// Use "GOOS=windows go generate -v -x ." to generate the source. + +// Add -trace to enable debug prints around syscalls. +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=false -output zsyscall_windows.go syscall_windows.go + +// Windows API calls +//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx +//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW +//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo +//sys _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW +//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes +//sys _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW +//sys _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses +//sys _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW +//sys _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW +//sys _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32NextW +//sys _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) = kernel32.CreateToolhelp32Snapshot +//sys _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQuerySystemInformation +//sys _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQueryInformationProcess +//sys _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW +//sys _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW +//sys _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges +//sys _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) = kernel32.FindFirstVolumeW +//sys _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) = kernel32.FindNextVolumeW +//sys _FindVolumeClose(handle syscall.Handle) (err error) = kernel32.FindVolumeClose +//sys _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) = kernel32.GetVolumePathNamesForVolumeNameW +//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory +//sys _GetTickCount64() (uptime uint64, err error) = kernel32.GetTickCount64 diff --git a/vendor/github.com/elastic/gosigar/sys/windows/version.go b/vendor/github.com/elastic/gosigar/sys/windows/version.go new file mode 100644 index 00000000..d0bca89c --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/version.go @@ -0,0 +1,43 @@ +// +build windows + +package windows + +import ( + "fmt" + "syscall" +) + +// Version identifies a Windows version by major, minor, and build number. +type Version struct { + Major int + Minor int + Build int +} + +// GetWindowsVersion returns the Windows version information. Applications not +// manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version +// value (6.2). +// +// For a table of version numbers see: +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx +func GetWindowsVersion() Version { + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx + ver, err := syscall.GetVersion() + if err != nil { + // GetVersion should never return an error. + panic(fmt.Errorf("GetVersion failed: %v", err)) + } + + return Version{ + Major: int(ver & 0xFF), + Minor: int(ver >> 8 & 0xFF), + Build: int(ver >> 16), + } +} + +// IsWindowsVistaOrGreater returns true if the Windows version is Vista or +// greater. +func (v Version) IsWindowsVistaOrGreater() bool { + // Vista is 6.0. + return v.Major >= 6 && v.Minor >= 0 +} diff --git a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go new file mode 100644 index 00000000..cd5d9ca3 --- /dev/null +++ b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go @@ -0,0 +1,376 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package windows + +import ( + "syscall" + "unsafe" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + modpsapi = syscall.NewLazyDLL("psapi.dll") + modntdll = syscall.NewLazyDLL("ntdll.dll") + modadvapi32 = syscall.NewLazyDLL("advapi32.dll") + + procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") + procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") + procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procEnumProcesses = modpsapi.NewProc("EnumProcesses") + procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") + procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") +) + +func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { + r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + length = uint32(r0) + if length == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size)) + length = uint32(r0) + if length == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) { + r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { + r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + dt = DriveType(r0) + if dt == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { + r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0) + handle = syscall.Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { + r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + ntstatus = uint32(r0) + if ntstatus == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { + r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0) + ntstatus = uint32(r0) + if ntstatus == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return + } + return __LookupPrivilegeName(_p0, luid, buffer, size) +} + +func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return + } + var _p1 *uint16 + _p1, err = syscall.UTF16PtrFromString(name) + if err != nil { + return + } + return __LookupPrivilegeValue(_p0, _p1, luid) +} + +func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) { + r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { + var _p0 uint32 + if releaseAll { + _p0 = 1 + } else { + _p0 = 0 + } + r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) + success = r0 != 0 + if true { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) + handle = syscall.Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindVolumeClose(handle syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(volumeName) + if err != nil { + return + } + return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) +} + +func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetTickCount64() (uptime uint64, err error) { + r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + uptime = uint64(r0) + if uptime == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/vendor/github.com/ethereum/go-ethereum/.dockerignore b/vendor/github.com/ethereum/go-ethereum/.dockerignore new file mode 100644 index 00000000..0c013d18 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/.dockerignore @@ -0,0 +1,5 @@ +**/*_test.go + +build/_workspace +build/_bin +tests/testdata diff --git a/vendor/github.com/ethereum/go-ethereum/.github/CODEOWNERS b/vendor/github.com/ethereum/go-ethereum/.github/CODEOWNERS new file mode 100644 index 00000000..6286617d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/.github/CODEOWNERS @@ -0,0 +1,23 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. + +accounts/usbwallet @karalabe +accounts/scwallet @gballet +accounts/abi @gballet +cmd/clef @holiman +cmd/puppeth @karalabe +consensus @karalabe +core/ @karalabe @holiman @rjl493456442 +dashboard/ @kurkomisi +eth/ @karalabe @holiman @rjl493456442 +graphql/ @gballet +les/ @zsfelfoldi @rjl493456442 +light/ @zsfelfoldi @rjl493456442 +mobile/ @karalabe @ligi +p2p/ @fjl @zsfelfoldi +rpc/ @fjl @holiman +p2p/simulations @zelig @nonsense @janos @justelad +p2p/protocols @zelig @nonsense @janos @justelad +p2p/testing @zelig @nonsense @janos @justelad +signer/ @holiman +whisper/ @gballet @gluk256 diff --git a/vendor/github.com/ethereum/go-ethereum/.travis.yml b/vendor/github.com/ethereum/go-ethereum/.travis.yml new file mode 100644 index 00000000..36defe30 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/.travis.yml @@ -0,0 +1,214 @@ +language: go +go_import_path: github.com/ethereum/go-ethereum +sudo: false +matrix: + include: + - os: linux + dist: xenial + go: 1.10.x + script: + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + - os: linux + dist: xenial + go: 1.11.x + script: + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + # These are the latest Go versions. + - os: linux + dist: xenial + go: 1.12.x + script: + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + - os: osx + go: 1.12.x + script: + - echo "Increase the maximum number of open file descriptors on macOS" + - NOFILE=20480 + - sudo sysctl -w kern.maxfiles=$NOFILE + - sudo sysctl -w kern.maxfilesperproc=$NOFILE + - sudo launchctl limit maxfiles $NOFILE $NOFILE + - sudo launchctl limit maxfiles + - ulimit -S -n $NOFILE + - ulimit -n + - unset -f cd # workaround for https://github.com/travis-ci/travis-ci/issues/8703 + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + # This builder only tests code linters on latest version of Go + - os: linux + dist: xenial + go: 1.12.x + env: + - lint + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go lint + + # This builder does the Ubuntu PPA upload + - if: type = push + os: linux + dist: xenial + go: 1.12.x + env: + - ubuntu-ppa + git: + submodules: false # avoid cloning ethereum/tests + addons: + apt: + packages: + - devscripts + - debhelper + - dput + - fakeroot + - python-bzrlib + - python-paramiko + script: + - echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts + - go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder " + + # This builder does the Linux Azure uploads + - if: type = push + os: linux + dist: xenial + sudo: required + go: 1.12.x + env: + - azure-linux + git: + submodules: false # avoid cloning ethereum/tests + addons: + apt: + packages: + - gcc-multilib + script: + # Build for the primary platforms that Trusty can manage + - go run build/ci.go install + - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go install -arch 386 + - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # Switch over GCC to cross compilation (breaks 386, hence why do it here only) + - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross + - sudo ln -s /usr/include/asm-generic /usr/include/asm + + - GOARM=5 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc + - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=6 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc + - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=7 go run build/ci.go install -arch arm -cc arm-linux-gnueabihf-gcc + - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go install -arch arm64 -cc aarch64-linux-gnu-gcc + - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # This builder does the Linux Azure MIPS xgo uploads + - if: type = push + os: linux + dist: xenial + services: + - docker + go: 1.12.x + env: + - azure-linux-mips + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done + - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done + - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done + - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done + - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # This builder does the Android Maven and Azure uploads + - if: type = push + os: linux + dist: xenial + addons: + apt: + packages: + - oracle-java8-installer + - oracle-java8-set-default + language: android + android: + components: + - platform-tools + - tools + - android-15 + - android-19 + - android-24 + env: + - azure-android + - maven-android + git: + submodules: false # avoid cloning ethereum/tests + before_install: + - curl https://dl.google.com/go/go1.12.linux-amd64.tar.gz | tar -xz + - export PATH=`pwd`/go/bin:$PATH + - export GOROOT=`pwd`/go + - export GOPATH=$HOME/go + script: + # Build the Android archive and upload it to Maven Central and Azure + - curl https://dl.google.com/android/repository/android-ndk-r19b-linux-x86_64.zip -o android-ndk-r19b.zip + - unzip -q android-ndk-r19b.zip && rm android-ndk-r19b.zip + - mv android-ndk-r19b $ANDROID_HOME/ndk-bundle + + - mkdir -p $GOPATH/src/github.com/ethereum + - ln -s `pwd` $GOPATH/src/github.com/ethereum/go-ethereum + - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds + + # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads + - if: type = push + os: osx + go: 1.12.x + env: + - azure-osx + - azure-ios + - cocoapods-ios + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go install + - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds + + # Build the iOS framework and upload it to CocoaPods and Azure + - gem uninstall cocoapods -a -x + - gem install cocoapods + + - mv ~/.cocoapods/repos/master ~/.cocoapods/repos/master.bak + - sed -i '.bak' 's/repo.join/!repo.join/g' $(dirname `gem which cocoapods`)/cocoapods/sources_manager.rb + - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then git clone --depth=1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master && pod setup --verbose; fi + + - xctool -version + - xcrun simctl list + + # Workaround for https://github.com/golang/go/issues/23749 + - export CGO_CFLAGS_ALLOW='-fmodules|-fblocks|-fobjc-arc' + - go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds + + # This builder does the Azure archive purges to avoid accumulating junk + - if: type = cron + os: linux + dist: xenial + go: 1.12.x + env: + - azure-purge + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go purge -store gethstore/builds -days 14 diff --git a/vendor/github.com/ethereum/go-ethereum/Dockerfile b/vendor/github.com/ethereum/go-ethereum/Dockerfile new file mode 100644 index 00000000..c766576a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/Dockerfile @@ -0,0 +1,16 @@ +# Build Geth in a stock Go builder container +FROM golang:1.12-alpine as builder + +RUN apk add --no-cache make gcc musl-dev linux-headers git + +ADD . /go-ethereum +RUN cd /go-ethereum && make geth + +# Pull Geth into a second stage deploy alpine container +FROM alpine:latest + +RUN apk add --no-cache ca-certificates +COPY --from=builder /go-ethereum/build/bin/geth /usr/local/bin/ + +EXPOSE 8545 8546 30303 30303/udp +ENTRYPOINT ["geth"] diff --git a/vendor/github.com/ethereum/go-ethereum/Dockerfile.alltools b/vendor/github.com/ethereum/go-ethereum/Dockerfile.alltools new file mode 100644 index 00000000..a4adba9d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/Dockerfile.alltools @@ -0,0 +1,15 @@ +# Build Geth in a stock Go builder container +FROM golang:1.12-alpine as builder + +RUN apk add --no-cache make gcc musl-dev linux-headers git + +ADD . /go-ethereum +RUN cd /go-ethereum && make all + +# Pull all binaries into a second stage deploy alpine container +FROM alpine:latest + +RUN apk add --no-cache ca-certificates +COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/ + +EXPOSE 8545 8546 30303 30303/udp diff --git a/vendor/github.com/ethereum/go-ethereum/Makefile b/vendor/github.com/ethereum/go-ethereum/Makefile new file mode 100644 index 00000000..4bf52f5c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/Makefile @@ -0,0 +1,145 @@ +# This Makefile is meant to be used by people that do not usually work +# with Go source code. If you know what GOPATH is then you probably +# don't need to bother with make. + +.PHONY: geth android ios geth-cross evm all test clean +.PHONY: geth-linux geth-linux-386 geth-linux-amd64 geth-linux-mips64 geth-linux-mips64le +.PHONY: geth-linux-arm geth-linux-arm-5 geth-linux-arm-6 geth-linux-arm-7 geth-linux-arm64 +.PHONY: geth-darwin geth-darwin-386 geth-darwin-amd64 +.PHONY: geth-windows geth-windows-386 geth-windows-amd64 + +GOBIN = $(shell pwd)/build/bin +GO ?= latest + +geth: + build/env.sh go run build/ci.go install ./cmd/geth + @echo "Done building." + @echo "Run \"$(GOBIN)/geth\" to launch geth." + +all: + build/env.sh go run build/ci.go install + +android: + build/env.sh go run build/ci.go aar --local + @echo "Done building." + @echo "Import \"$(GOBIN)/geth.aar\" to use the library." + +ios: + build/env.sh go run build/ci.go xcode --local + @echo "Done building." + @echo "Import \"$(GOBIN)/Geth.framework\" to use the library." + +test: all + build/env.sh go run build/ci.go test + +lint: ## Run linters. + build/env.sh go run build/ci.go lint + +clean: + ./build/clean_go_build_cache.sh + rm -fr build/_workspace/pkg/ $(GOBIN)/* + +# The devtools target installs tools required for 'go generate'. +# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'. + +devtools: + env GOBIN= go get -u golang.org/x/tools/cmd/stringer + env GOBIN= go get -u github.com/kevinburke/go-bindata/go-bindata + env GOBIN= go get -u github.com/fjl/gencodec + env GOBIN= go get -u github.com/golang/protobuf/protoc-gen-go + env GOBIN= go install ./cmd/abigen + @type "npm" 2> /dev/null || echo 'Please install node.js and npm' + @type "solc" 2> /dev/null || echo 'Please install solc' + @type "protoc" 2> /dev/null || echo 'Please install protoc' + +# Cross Compilation Targets (xgo) + +geth-cross: geth-linux geth-darwin geth-windows geth-android geth-ios + @echo "Full cross compilation done:" + @ls -ld $(GOBIN)/geth-* + +geth-linux: geth-linux-386 geth-linux-amd64 geth-linux-arm geth-linux-mips64 geth-linux-mips64le + @echo "Linux cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* + +geth-linux-386: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/386 -v ./cmd/geth + @echo "Linux 386 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep 386 + +geth-linux-amd64: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/amd64 -v ./cmd/geth + @echo "Linux amd64 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep amd64 + +geth-linux-arm: geth-linux-arm-5 geth-linux-arm-6 geth-linux-arm-7 geth-linux-arm64 + @echo "Linux ARM cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep arm + +geth-linux-arm-5: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-5 -v ./cmd/geth + @echo "Linux ARMv5 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep arm-5 + +geth-linux-arm-6: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-6 -v ./cmd/geth + @echo "Linux ARMv6 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep arm-6 + +geth-linux-arm-7: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-7 -v ./cmd/geth + @echo "Linux ARMv7 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep arm-7 + +geth-linux-arm64: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm64 -v ./cmd/geth + @echo "Linux ARM64 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep arm64 + +geth-linux-mips: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/mips --ldflags '-extldflags "-static"' -v ./cmd/geth + @echo "Linux MIPS cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep mips + +geth-linux-mipsle: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/mipsle --ldflags '-extldflags "-static"' -v ./cmd/geth + @echo "Linux MIPSle cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep mipsle + +geth-linux-mips64: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/mips64 --ldflags '-extldflags "-static"' -v ./cmd/geth + @echo "Linux MIPS64 cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep mips64 + +geth-linux-mips64le: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/mips64le --ldflags '-extldflags "-static"' -v ./cmd/geth + @echo "Linux MIPS64le cross compilation done:" + @ls -ld $(GOBIN)/geth-linux-* | grep mips64le + +geth-darwin: geth-darwin-386 geth-darwin-amd64 + @echo "Darwin cross compilation done:" + @ls -ld $(GOBIN)/geth-darwin-* + +geth-darwin-386: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=darwin/386 -v ./cmd/geth + @echo "Darwin 386 cross compilation done:" + @ls -ld $(GOBIN)/geth-darwin-* | grep 386 + +geth-darwin-amd64: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=darwin/amd64 -v ./cmd/geth + @echo "Darwin amd64 cross compilation done:" + @ls -ld $(GOBIN)/geth-darwin-* | grep amd64 + +geth-windows: geth-windows-386 geth-windows-amd64 + @echo "Windows cross compilation done:" + @ls -ld $(GOBIN)/geth-windows-* + +geth-windows-386: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=windows/386 -v ./cmd/geth + @echo "Windows 386 cross compilation done:" + @ls -ld $(GOBIN)/geth-windows-* | grep 386 + +geth-windows-amd64: + build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=windows/amd64 -v ./cmd/geth + @echo "Windows amd64 cross compilation done:" + @ls -ld $(GOBIN)/geth-windows-* | grep amd64 diff --git a/vendor/github.com/ethereum/go-ethereum/README.md b/vendor/github.com/ethereum/go-ethereum/README.md new file mode 100644 index 00000000..5ae8e7a6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/README.md @@ -0,0 +1,310 @@ +## Go Ethereum + +Official Golang implementation of the Ethereum protocol. + +[![API Reference]( +https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667 +)](https://godoc.org/github.com/ethereum/go-ethereum) +[![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) +[![Travis](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) +[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) + +Automated builds are available for stable releases and the unstable master branch. +Binary archives are published at https://geth.ethereum.org/downloads/. + +## Building the source + +For prerequisites and detailed build instructions please read the +[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum) +on the wiki. + +Building geth requires both a Go (version 1.10 or later) and a C compiler. +You can install them using your favourite package manager. +Once the dependencies are installed, run + + make geth + +or, to build the full suite of utilities: + + make all + +## Executables + +The go-ethereum project comes with several wrappers/executables found in the `cmd` directory. + +| Command | Description | +| :-----------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) for command line options. | +| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | +| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. | +| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). | +| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | +| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user-friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | +| `puppeth` | a CLI wizard that aids in creating a new Ethereum network. | + +## Running geth + +Going through all the possible command line flags is out of scope here (please consult our +[CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)), but we've +enumerated a few common parameter combos to get you up to speed quickly on how you can run your +own Geth instance. + +### Full node on the main Ethereum network + +By far the most common scenario is people wanting to simply interact with the Ethereum network: +create accounts; transfer funds; deploy and interact with contracts. For this particular use-case +the user doesn't care about years-old historical data, so we can fast-sync quickly to the current +state of the network. To do so: + +``` +$ geth console +``` + +This command will: + + * Start geth in fast sync mode (default, can be changed with the `--syncmode` flag), causing it to + download more data in exchange for avoiding processing the entire history of the Ethereum network, + which is very CPU intensive. + * Start up Geth's built-in interactive [JavaScript console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console), + (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API) + as well as Geth's own [management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs). + This tool is optional and if you leave it out you can always attach to an already running Geth instance + with `geth attach`. + +### A Full node on the Ethereum test network + +Transitioning towards developers, if you'd like to play around with creating Ethereum contracts, you +almost certainly would like to do that without any real money involved until you get the hang of the +entire system. In other words, instead of attaching to the main network, you want to join the **test** +network with your node, which is fully equivalent to the main network, but with play-Ether only. + +``` +$ geth --testnet console +``` + +The `console` subcommand has the exact same meaning as above and they are equally useful on the +testnet too. Please see above for their explanations if you've skipped here. + +Specifying the `--testnet` flag, however, will reconfigure your Geth instance a bit: + + * Instead of using the default data directory (`~/.ethereum` on Linux for example), Geth will nest + itself one level deeper into a `testnet` subfolder (`~/.ethereum/testnet` on Linux). Note, on OSX + and Linux this also means that attaching to a running testnet node requires the use of a custom + endpoint since `geth attach` will try to attach to a production node endpoint by default. E.g. + `geth attach /testnet/geth.ipc`. Windows users are not affected by this. + * Instead of connecting the main Ethereum network, the client will connect to the test network, + which uses different P2P bootnodes, different network IDs and genesis states. + +*Note: Although there are some internal protective measures to prevent transactions from crossing +over between the main network and test network, you should make sure to always use separate accounts +for play-money and real-money. Unless you manually move accounts, Geth will by default correctly +separate the two networks and will not make any accounts available between them.* + +### Full node on the Rinkeby test network + +The above test network is a cross-client one based on the ethash proof-of-work consensus algorithm. As such, it has certain extra overhead and is more susceptible to reorganization attacks due to the network's low difficulty/security. Go Ethereum also supports connecting to a proof-of-authority based test network called [*Rinkeby*](https://www.rinkeby.io) (operated by members of the community). This network is lighter, more secure, but is only supported by go-ethereum. + +``` +$ geth --rinkeby console +``` + +### Configuration + +As an alternative to passing the numerous flags to the `geth` binary, you can also pass a configuration file via: + +``` +$ geth --config /path/to/your_config.toml +``` + +To get an idea how the file should look like you can use the `dumpconfig` subcommand to export your existing configuration: + +``` +$ geth --your-favourite-flags dumpconfig +``` + +*Note: This works only with geth v1.6.0 and above.* + +#### Docker quick start + +One of the quickest ways to get Ethereum up and running on your machine is by using Docker: + +``` +docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ + -p 8545:8545 -p 30303:30303 \ + ethereum/client-go +``` + +This will start geth in fast-sync mode with a DB memory allowance of 1GB just as the above command does. It will also create a persistent volume in your home directory for saving your blockchain as well as map the default ports. There is also an `alpine` tag available for a slim version of the image. + +Do not forget `--rpcaddr 0.0.0.0`, if you want to access RPC from other containers and/or hosts. By default, `geth` binds to the local interface and RPC endpoints is not accessible from the outside. + +### Programmatically interfacing Geth nodes + +As a developer, sooner rather than later you'll want to start interacting with Geth and the Ethereum +network via your own programs and not manually through the console. To aid this, Geth has built-in +support for a JSON-RPC based APIs ([standard APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) and +[Geth specific APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs)). These can be +exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based platforms, and named pipes on Windows). + +The IPC interface is enabled by default and exposes all the APIs supported by Geth, whereas the HTTP +and WS interfaces need to manually be enabled and only expose a subset of APIs due to security reasons. +These can be turned on/off and configured as you'd expect. + +HTTP based JSON-RPC API options: + + * `--rpc` Enable the HTTP-RPC server + * `--rpcaddr` HTTP-RPC server listening interface (default: "localhost") + * `--rpcport` HTTP-RPC server listening port (default: 8545) + * `--rpcapi` API's offered over the HTTP-RPC interface (default: "eth,net,web3") + * `--rpccorsdomain` Comma separated list of domains from which to accept cross origin requests (browser enforced) + * `--ws` Enable the WS-RPC server + * `--wsaddr` WS-RPC server listening interface (default: "localhost") + * `--wsport` WS-RPC server listening port (default: 8546) + * `--wsapi` API's offered over the WS-RPC interface (default: "eth,net,web3") + * `--wsorigins` Origins from which to accept websockets requests + * `--ipcdisable` Disable the IPC-RPC server + * `--ipcapi` API's offered over the IPC-RPC interface (default: "admin,debug,eth,miner,net,personal,shh,txpool,web3") + * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) + +You'll need to use your own programming environments' capabilities (libraries, tools, etc) to connect +via HTTP, WS or IPC to a Geth node configured with the above flags and you'll need to speak [JSON-RPC](https://www.jsonrpc.org/specification) +on all transports. You can reuse the same connection for multiple requests! + +**Note: Please understand the security implications of opening up an HTTP/WS based transport before +doing so! Hackers on the internet are actively trying to subvert Ethereum nodes with exposed APIs! +Further, all browser tabs can access locally running web servers, so malicious web pages could try to +subvert locally available APIs!** + +### Operating a private network + +Maintaining your own private network is more involved as a lot of configurations taken for granted in +the official networks need to be manually set up. + +#### Defining the private genesis state + +First, you'll need to create the genesis state of your networks, which all nodes need to be aware of +and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): + +```json +{ + "config": { + "chainId": 0, + "homesteadBlock": 0, + "eip155Block": 0, + "eip158Block": 0 + }, + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00" +} +``` + +The above fields should be fine for most purposes, although we'd recommend changing the `nonce` to +some random value so you prevent unknown remote nodes from being able to connect to you. If you'd +like to pre-fund some accounts for easier testing, you can populate the `alloc` field with account +configs: + +```json +"alloc": { + "0x0000000000000000000000000000000000000001": {"balance": "111111111"}, + "0x0000000000000000000000000000000000000002": {"balance": "222222222"} +} +``` + +With the genesis state defined in the above JSON file, you'll need to initialize **every** Geth node +with it prior to starting it up to ensure all blockchain parameters are correctly set: + +``` +$ geth init path/to/genesis.json +``` + +#### Creating the rendezvous point + +With all nodes that you want to run initialized to the desired genesis state, you'll need to start a +bootstrap node that others can use to find each other in your network and/or over the internet. The +clean way is to configure and run a dedicated bootnode: + +``` +$ bootnode --genkey=boot.key +$ bootnode --nodekey=boot.key +``` + +With the bootnode online, it will display an [`enode` URL](https://github.com/ethereum/wiki/wiki/enode-url-format) +that other nodes can use to connect to it and exchange peer information. Make sure to replace the +displayed IP address information (most probably `[::]`) with your externally accessible IP to get the +actual `enode` URL. + +*Note: You could also use a full-fledged Geth node as a bootnode, but it's the less recommended way.* + +#### Starting up your member nodes + +With the bootnode operational and externally reachable (you can try `telnet ` to ensure +it's indeed reachable), start every subsequent Geth node pointed to the bootnode for peer discovery +via the `--bootnodes` flag. It will probably also be desirable to keep the data directory of your +private network separated, so do also specify a custom `--datadir` flag. + +``` +$ geth --datadir=path/to/custom/data/folder --bootnodes= +``` + +*Note: Since your network will be completely cut off from the main and test networks, you'll also +need to configure a miner to process transactions and create new blocks for you.* + +#### Running a private miner + +Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, requiring +an OpenCL or CUDA enabled `ethminer` instance. For information on such a setup, please consult the +[EtherMining subreddit](https://www.reddit.com/r/EtherMining/) and the [Genoil miner](https://github.com/Genoil/cpp-ethereum) +repository. + +In a private network setting, however a single CPU miner instance is more than enough for practical +purposes as it can produce a stable stream of blocks at the correct intervals without needing heavy +resources (consider running on a single thread, no need for multiple ones either). To start a Geth +instance for mining, run it with all your usual flags, extended by: + +``` +$ geth --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000 +``` + +Which will start mining blocks and transactions on a single CPU thread, crediting all proceedings to +the account specified by `--etherbase`. You can further tune the mining by changing the default gas +limit blocks converge to (`--targetgaslimit`) and the price transactions are accepted at (`--gasprice`). + +## Contribution + +Thank you for considering to help out with the source code! We welcome contributions from +anyone on the internet, and are grateful for even the smallest of fixes! + +If you'd like to contribute to go-ethereum, please fork, fix, commit and send a pull request +for the maintainers to review and merge into the main code base. If you wish to submit more +complex changes though, please check up with the core devs first on [our gitter channel](https://gitter.im/ethereum/go-ethereum) +to ensure those changes are in line with the general philosophy of the project and/or get some +early feedback which can make both your efforts much lighter as well as our review and merge +procedures quick and simple. + +Please make sure your contributions adhere to our coding guidelines: + + * Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). + * Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. + * Pull requests need to be based on and opened against the `master` branch. + * Commit messages should be prefixed with the package(s) they modify. + * E.g. "eth, rpc: make trace configs optional" + +Please see the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide) +for more details on configuring your environment, managing project dependencies, and testing procedures. + +## License + +The go-ethereum library (i.e. all code outside of the `cmd` directory) is licensed under the +[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html), also +included in our repository in the `COPYING.LESSER` file. + +The go-ethereum binaries (i.e. all code inside of the `cmd` directory) is licensed under the +[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also included +in our repository in the `COPYING` file. diff --git a/vendor/github.com/ethereum/go-ethereum/SECURITY.md b/vendor/github.com/ethereum/go-ethereum/SECURITY.md new file mode 100644 index 00000000..bc54ede4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/SECURITY.md @@ -0,0 +1,120 @@ +# Security Policy + +## Supported Versions + +Please see Releases. We recommend to use the most recent released version. + +## Audit reports + +Audit reports are published in the `docs` folder: https://github.com/ethereum/go-ethereum/tree/master/docs/audits + + +| Scope | Date | Report Link | +| ------- | ------- | ----------- | +| `geth` | 20170425 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2017-04-25_Geth-audit_Truesec.pdf) | +| `clef` | 20180914 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2018-09-14_Clef-audit_NCC.pdf) | + + + +## Reporting a Vulnerability + +**Please do not file a public ticket** mentioning the vulnerability. + +To find out how to disclose a vulnerability in Ethereum visit [https://bounty.ethereum.org](https://bounty.ethereum.org) or email bounty@ethereum.org. + +The following key may be used to communicate sensitive information to developers. + +Fingerprint: `AE96 ED96 9E47 9B00 84F3 E17F E88D 3334 FA5F 6A0A` + + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBFgl3tgBEAC8A1tUBkD9YV+eLrOmtgy+/JS/H9RoZvkg3K1WZ8IYfj6iIRaY +neAk3Bp182GUPVz/zhKr2g0tMXIScDR3EnaDsY+Qg+JqQl8NOG+Cikr1nnkG2on9 +L8c8yiqry1ZTCmYMqCa2acTFqnyuXJ482aZNtB4QG2BpzfhW4k8YThpegk/EoRUi +m+y7buJDtoNf7YILlhDQXN8qlHB02DWOVUihph9tUIFsPK6BvTr9SIr/eG6j6k0b +fUo9pexOn7LS4SojoJmsm/5dp6AoKlac48cZU5zwR9AYcq/nvkrfmf2WkObg/xRd +EvKZzn05jRopmAIwmoC3CiLmqCHPmT5a29vEob/yPFE335k+ujjZCPOu7OwjzDk7 +M0zMSfnNfDq8bXh16nn+ueBxJ0NzgD1oC6c2PhM+XRQCXChoyI8vbfp4dGvCvYqv +QAE1bWjqnumZ/7vUPgZN6gDfiAzG2mUxC2SeFBhacgzDvtQls+uuvm+FnQOUgg2H +h8x2zgoZ7kqV29wjaUPFREuew7e+Th5BxielnzOfVycVXeSuvvIn6cd3g/s8mX1c +2kLSXJR7+KdWDrIrR5Az0kwAqFZt6B6QTlDrPswu3mxsm5TzMbny0PsbL/HBM+GZ +EZCjMXxB8bqV2eSaktjnSlUNX1VXxyOxXA+ZG2jwpr51egi57riVRXokrQARAQAB +tDlFdGhlcmV1bSBGb3VuZGF0aW9uIFNlY3VyaXR5IFRlYW0gPHNlY3VyaXR5QGV0 +aGVyZXVtLm9yZz6JAj4EEwECACgCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA +BQJaCWH6BQkFo2BYAAoJEOiNMzT6X2oK+DEP/3H6dxkm0hvHZKoHLVuuxcu3EHYo +k5sd3MMWPrZSN8qzZnY7ayEDMxnarWOizc+2jfOxfJlzX/g8lR1/fsHdWPFPhPoV +Qk8ygrHn1H8U8+rpw/U03BqmqHpYCDzJ+CIis9UWROniqXw1nuqu/FtWOsdWxNKh +jUo6k/0EsaXsxRPzgJv7fEUcVcQ7as/C3x9sy3muc2gvgA4/BKoGPb1/U0GuA8lV +fDIDshAggmnSUAg+TuYSAAdoFQ1sKwFMPigcLJF2eyKuK3iUyixJrec/c4LSf3wA +cGghbeuqI8INP0Y2zvXDQN2cByxsFAuoZG+m0cyKGaDH2MVUvOKKYqn/03qvrf15 +AWAsW0l0yQwOTCo3FbsNzemClm5Bj/xH0E4XuwXwChcMCMOWJrFoxyvCEI+keoQc +c08/a8/MtS7vBAABXwOziSmm6CNqmzpWrh/fDrjlJlba9U3MxzvqU3IFlTdMratv +6V+SgX+L25lCzW4NxxUavoB8fAlvo8lxpHKo24FP+RcLQ8XqkU3RiUsgRjQRFOqQ +TaJcsp8mimmiYyf24mNu6b48pi+a5c/eQR9w59emeEUZqsJU+nqv8BWIIp7o4Agh +NYnKjkhPlY5e1fLVfAHIADZFynWwRPkPMJSrBiP5EtcOFxQGHGjRxU/KjXkvE0hV +xYb1PB8pWMTu/beeiQI+BBMBAgAoBQJYJd7YAhsDBQkB4TOABgsJCAcDAgYVCAIJ +CgsEFgIDAQIeAQIXgAAKCRDojTM0+l9qCplDD/9IZ2i+m1cnqQKtiyHbyFGx32oL +fzqPylX2bOG5DPsSTorSUdJMGVfT04oVxXc4S/2DVnNvi7RAbSiLapCWSplgtBOj +j1xlblOoXxT3m7s1XHGCX5tENxI9fVSSPVKJn+fQaWpPB2MhBA+1lUI6GJ+11T7K +J8LrP/fiw1/nOb7rW61HW44Gtyox23sA/d1+DsFVaF8hxJlNj5coPKr8xWzQ8pQl +juzdjHDukjevuw4rRmRq9vozvj9keEU9XJ5dldyEVXFmdDk7KT0p0Rla9nxYhzf/ +r/Bv8Bzy0HCWRb2D31BjXXGG05oVnYmNGxGFxYja4MwgrMmne3ilEVjfUJsapsqi +w41BAyQgIdfREulYN7ahsF5PrjVAqBd9IGtE8ULelF2SQxEBQBngEkP0ahP6tRAL +i7/CBjPKOyKijtqVny7qrGOnU2ygcA88/WDibexDhrjz0Gx8WmErU7rIWZiZ5u4Y +vJYVRo0+6rBCXRPeSJfiP5h1p17Anr2l42boAYslfcrzquB8MHtrNcyn650OLtHG +nbxgIdniKrpuzGN6Opw+O2id2JhD1/1p4SOemwAmthplr1MIyOHNP3q93rEj2J7h +5zPS/AJuKkMDFUpslPNLQjCOwPXtdzL7/kUZGBSyez1T3TaW1uY6l9XaJJRaSn+v +1zPgfp4GJ3lPs4AlAbQ0RXRoZXJldW0gRm91bmRhdGlvbiBCdWcgQm91bnR5IDxi +b3VudHlAZXRoZXJldW0ub3JnPokCPgQTAQIAKAIbAwYLCQgHAwIGFQgCCQoLBBYC +AwECHgECF4AFAloJYfoFCQWjYFgACgkQ6I0zNPpfagoENg/+LnSaVeMxiGVtcjWl +b7Xd73yrEy4uxiESS1AalW9mMf7oZzfI05f7QIQlaLAkNac74vZDJbPKjtb7tpMO +RFhRZMCveq6CPKU6pd1SI8IUVUKwpEe6AJP3lHdVP57dquieFE2HlYKm6uHbCGWU +0cjyTA+uu2KbgCHGmofsPY/xOcZLGEHTHqa5w60JJAQm+BSDKnw8wTyrxGvA3EK/ +ePSvOZMYa+iw6vYuZeBIMbdiXR/A2keBi3GuvqB8tDMj7P22TrH5mVDm3zNqGYD6 +amDPeiWp4cztY3aZyLcgYotqXPpDceZzDn+HopBPzAb/llCdE7bVswKRhphVMw4b +bhL0R/TQY7Sf6TK2LKSBrjv0DWOSijikE71SJcBnJvHU7EpKrQQ0lMGclm3ynyji +Nf0YTPXQt4I+fwTmOew2GFeK3UytNWbWI7oXX7Nm4bj9bhf3IJ0kmZb/Gs73+xII +e7Rz52Mby436tWyQIQiF9ITYNGvNf53TwBBZMn0pKPiTyr3Ur7FHEotkEOFNh1// +4zQY10XxuBdLrYGyZ4V8xHJM+oKre8Eg2R9qHXVbjvErHE+7CvgnV7YUip0criPr +BlKRvuoJaSliH2JFhSjWVrkPmFGrWN0BAx10yIqMnEplfKeHf4P9Elek3oInS8WP +G1zJG6s/t5+hQK0X37+TB+6rd3GJAj4EEwECACgFAlgl4TsCGwMFCQHhM4AGCwkI +BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOiNMzT6X2oKzf8P/iIKd77WHTbp4pMN +8h52HyZJtDJmjA1DPZrbGl1TesW/Z9uTd12txlgqZnbG2GfN9+LSP6EOPzR6v2xC +OVhR+RdWhZDJJuQCVS7lJIqQrZgmeTZG0TyQPZdLjVFBOrrhVwYX+HXbu429IzHr +URf5InyR1QgqOXyElDYS6e28HFqvaoA0DWTWDDqOLPVl+U5fuceIE2XXdv3AGLeP +Yf8J5MPobjPiZtBqI6S6iENY2Yn35qLX+axeC/iYSCHVtFuCCIdb/QYR1ZZV8Ps/ +aI9DwC7LU+YfPw7iqCIoqxSeA3o1PORkdSigEg3jtfRv5UqVo9a0oBb9jdoADsat +F/gW0E7mto3XGOiaR0eB9SSdsM3x7Bz4A0HIGNaxpZo1RWqlO91leP4c13Px7ISv +5OGXfLg+M8qb+qxbGd1HpitGi9s1y1aVfEj1kOtZ0tN8eu+Upg5WKwPNBDX3ar7J +9NCULgVSL+E79FG+zXw62gxiQrLfKzm4wU/9L5wVkwQnm29hLJ0tokrSBZFnc/1l +7OC+GM63tYicKkY4rqmoWUeYx7IwFH9mtDtvR1RxO85RbQhZizwpZpdpRkH0DqZu +ZJRmRa5r7rPqmfa7d+VIFhz2Xs8pJMLVqxTsLKcLglmjw7aOrYG0SWeH7YraXWGD +N3SlvSBiVwcK7QUKzLLvpadLwxfsuQINBFgl3tgBEACbgq6HTN5gEBi0lkD/MafI +nmNi+59U5gRGYqk46WlfRjhHudXjDpgD0lolGb4hYontkMaKRlCg2Rvgjvk3Zve0 +PKWjKw7gr8YBa9fMFY8BhAXI32OdyI9rFhxEZFfWAfwKVmT19BdeAQRFvcfd+8w8 +f1XVc+zddULMJFBTr+xKDlIRWwTkdLPQeWbjo0eHl/g4tuLiLrTxVbnj26bf+2+1 +DbM/w5VavzPrkviHqvKe/QP/gay4QDViWvFgLb90idfAHIdsPgflp0VDS5rVHFL6 +D73rSRdIRo3I8c8mYoNjSR4XDuvgOkAKW9LR3pvouFHHjp6Fr0GesRbrbb2EG66i +PsR99MQ7FqIL9VMHPm2mtR+XvbnKkH2rYyEqaMbSdk29jGapkAWle4sIhSKk749A +4tGkHl08KZ2N9o6GrfUehP/V2eJLaph2DioFL1HxRryrKy80QQKLMJRekxigq8gr +eW8xB4zuf9Mkuou+RHNmo8PebHjFstLigiD6/zP2e+4tUmrT0/JTGOShoGMl8Rt0 +VRxdPImKun+4LOXbfOxArOSkY6i35+gsgkkSy1gTJE0BY3S9auT6+YrglY/TWPQ9 +IJxWVOKlT+3WIp5wJu2bBKQ420VLqDYzkoWytel/bM1ACUtipMiIVeUs2uFiRjpz +A1Wy0QHKPTdSuGlJPRrfcQARAQABiQIlBBgBAgAPAhsMBQJaCWIIBQkFo2BYAAoJ +EOiNMzT6X2oKgSwQAKKs7BGF8TyZeIEO2EUK7R2bdQDCdSGZY06tqLFg3IHMGxDM +b/7FVoa2AEsFgv6xpoebxBB5zkhUk7lslgxvKiSLYjxfNjTBltfiFJ+eQnf+OTs8 +KeR51lLa66rvIH2qUzkNDCCTF45H4wIDpV05AXhBjKYkrDCrtey1rQyFp5fxI+0I +Q1UKKXvzZK4GdxhxDbOUSd38MYy93nqcmclGSGK/gF8XiyuVjeifDCM6+T1NQTX0 +K9lneidcqtBDvlggJTLJtQPO33o5EHzXSiud+dKth1uUhZOFEaYRZoye1YE3yB0T +NOOE8fXlvu8iuIAMBSDL9ep6sEIaXYwoD60I2gHdWD0lkP0DOjGQpi4ouXM3Edsd +5MTi0MDRNTij431kn8T/D0LCgmoUmYYMBgbwFhXr67axPZlKjrqR0z3F/Elv0ZPP +cVg1tNznsALYQ9Ovl6b5M3cJ5GapbbvNWC7yEE1qScl9HiMxjt/H6aPastH63/7w +cN0TslW+zRBy05VNJvpWGStQXcngsSUeJtI1Gd992YNjUJq4/Lih6Z1TlwcFVap+ +cTcDptoUvXYGg/9mRNNPZwErSfIJ0Ibnx9wPVuRN6NiCLOt2mtKp2F1pM6AOQPpZ +85vEh6I8i6OaO0w/Z0UHBwvpY6jDUliaROsWUQsqz78Z34CVj4cy6vPW2EF4 +=r6KK +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/auth.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/auth.go new file mode 100644 index 00000000..5d5ad003 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/auth.go @@ -0,0 +1,81 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bind + +import ( + "crypto/ecdsa" + "errors" + "io" + "io/ioutil" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +// NewTransactor is a utility method to easily create a transaction signer from +// an encrypted json key stream and the associated passphrase. +func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { + json, err := ioutil.ReadAll(keyin) + if err != nil { + return nil, err + } + key, err := keystore.DecryptKey(json, passphrase) + if err != nil { + return nil, err + } + return NewKeyedTransactor(key.PrivateKey), nil +} + +// NewKeystoreTransactor is a utility method to easily create a transaction signer from +// an decrypted key from a keystore +func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { + return &TransactOpts{ + From: account.Address, + Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, errors.New("not authorized to sign this account") + } + signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + }, nil +} + +// NewKeyedTransactor is a utility method to easily create a transaction signer +// from a single private key. +func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { + keyAddr := crypto.PubkeyToAddress(key.PublicKey) + return &TransactOpts{ + From: keyAddr, + Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != keyAddr { + return nil, errors.New("not authorized to sign this account") + } + signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/backends/simulated.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/backends/simulated.go new file mode 100644 index 00000000..ac4602fe --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/backends/simulated.go @@ -0,0 +1,505 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backends + +import ( + "context" + "errors" + "fmt" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend. +var _ bind.ContractBackend = (*SimulatedBackend)(nil) + +var errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") +var errGasEstimationFailed = errors.New("gas required exceeds allowance or always failing transaction") + +// SimulatedBackend implements bind.ContractBackend, simulating a blockchain in +// the background. Its main purpose is to allow easily testing contract bindings. +type SimulatedBackend struct { + database ethdb.Database // In memory database to store our testing data + blockchain *core.BlockChain // Ethereum blockchain to handle the consensus + + mu sync.Mutex + pendingBlock *types.Block // Currently pending block that will be imported on request + pendingState *state.StateDB // Currently pending state that will be the active on on request + + events *filters.EventSystem // Event system for filtering log events live + + config *params.ChainConfig +} + +// NewSimulatedBackend creates a new binding backend using a simulated blockchain +// for testing purposes. +func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { + database := rawdb.NewMemoryDatabase() + genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} + genesis.MustCommit(database) + blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil) + + backend := &SimulatedBackend{ + database: database, + blockchain: blockchain, + config: genesis.Config, + events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{database, blockchain}, false), + } + backend.rollback() + return backend +} + +// Commit imports all the pending transactions as a single block and starts a +// fresh new state. +func (b *SimulatedBackend) Commit() { + b.mu.Lock() + defer b.mu.Unlock() + + if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil { + panic(err) // This cannot happen unless the simulator is wrong, fail in that case + } + b.rollback() +} + +// Rollback aborts all pending transactions, reverting to the last committed state. +func (b *SimulatedBackend) Rollback() { + b.mu.Lock() + defer b.mu.Unlock() + + b.rollback() +} + +func (b *SimulatedBackend) rollback() { + blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {}) + statedb, _ := b.blockchain.State() + + b.pendingBlock = blocks[0] + b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) +} + +// CodeAt returns the code associated with a certain account in the blockchain. +func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return nil, errBlockNumberUnsupported + } + statedb, _ := b.blockchain.State() + return statedb.GetCode(contract), nil +} + +// BalanceAt returns the wei balance of a certain account in the blockchain. +func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return nil, errBlockNumberUnsupported + } + statedb, _ := b.blockchain.State() + return statedb.GetBalance(contract), nil +} + +// NonceAt returns the nonce of a certain account in the blockchain. +func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (uint64, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return 0, errBlockNumberUnsupported + } + statedb, _ := b.blockchain.State() + return statedb.GetNonce(contract), nil +} + +// StorageAt returns the value of key in the storage of an account in the blockchain. +func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return nil, errBlockNumberUnsupported + } + statedb, _ := b.blockchain.State() + val := statedb.GetState(contract, key) + return val[:], nil +} + +// TransactionReceipt returns the receipt of a transaction. +func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config) + return receipt, nil +} + +// TransactionByHash checks the pool of pending transactions in addition to the +// blockchain. The isPending return value indicates whether the transaction has been +// mined yet. Note that the transaction may not be part of the canonical chain even if +// it's not pending. +func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { + b.mu.Lock() + defer b.mu.Unlock() + + tx := b.pendingBlock.Transaction(txHash) + if tx != nil { + return tx, true, nil + } + tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash) + if tx != nil { + return tx, false, nil + } + return nil, false, ethereum.NotFound +} + +// PendingCodeAt returns the code associated with an account in the pending state. +func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + return b.pendingState.GetCode(contract), nil +} + +// CallContract executes a contract call. +func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { + return nil, errBlockNumberUnsupported + } + state, err := b.blockchain.State() + if err != nil { + return nil, err + } + rval, _, _, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) + return rval, err +} + +// PendingCallContract executes a contract call on the pending state. +func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot()) + + rval, _, _, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + return rval, err +} + +// PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving +// the nonce currently pending for the account. +func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { + b.mu.Lock() + defer b.mu.Unlock() + + return b.pendingState.GetOrNewStateObject(account).Nonce(), nil +} + +// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated +// chain doesn't have miners, we just return a gas price of 1 for any call. +func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + return big.NewInt(1), nil +} + +// EstimateGas executes the requested code against the currently pending block/state and +// returns the used amount of gas. +func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { + b.mu.Lock() + defer b.mu.Unlock() + + // Determine the lowest and highest possible gas limits to binary search in between + var ( + lo uint64 = params.TxGas - 1 + hi uint64 + cap uint64 + ) + if call.Gas >= params.TxGas { + hi = call.Gas + } else { + hi = b.pendingBlock.GasLimit() + } + cap = hi + + // Create a helper to check if a gas allowance results in an executable transaction + executable := func(gas uint64) bool { + call.Gas = gas + + snapshot := b.pendingState.Snapshot() + _, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + b.pendingState.RevertToSnapshot(snapshot) + + if err != nil || failed { + return false + } + return true + } + // Execute the binary search and hone in on an executable gas limit + for lo+1 < hi { + mid := (hi + lo) / 2 + if !executable(mid) { + lo = mid + } else { + hi = mid + } + } + // Reject the transaction as invalid if it still fails at the highest allowance + if hi == cap { + if !executable(hi) { + return 0, errGasEstimationFailed + } + } + return hi, nil +} + +// callContract implements common code between normal and pending contract calls. +// state is modified during execution, make sure to copy it if necessary. +func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) { + // Ensure message is initialized properly. + if call.GasPrice == nil { + call.GasPrice = big.NewInt(1) + } + if call.Gas == 0 { + call.Gas = 50000000 + } + if call.Value == nil { + call.Value = new(big.Int) + } + // Set infinite balance to the fake caller account. + from := statedb.GetOrNewStateObject(call.From) + from.SetBalance(math.MaxBig256) + // Execute the call. + msg := callmsg{call} + + evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil) + // Create a new environment which holds all relevant information + // about the transaction and calling mechanisms. + vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) + gaspool := new(core.GasPool).AddGas(math.MaxUint64) + + return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() +} + +// SendTransaction updates the pending block to include the given transaction. +// It panics if the transaction is invalid. +func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { + b.mu.Lock() + defer b.mu.Unlock() + + sender, err := types.Sender(types.HomesteadSigner{}, tx) + if err != nil { + panic(fmt.Errorf("invalid transaction: %v", err)) + } + nonce := b.pendingState.GetNonce(sender) + if tx.Nonce() != nonce { + panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)) + } + + blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { + for _, tx := range b.pendingBlock.Transactions() { + block.AddTxWithChain(b.blockchain, tx) + } + block.AddTxWithChain(b.blockchain, tx) + }) + statedb, _ := b.blockchain.State() + + b.pendingBlock = blocks[0] + b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) + return nil +} + +// FilterLogs executes a log filter operation, blocking during execution and +// returning all the results in one batch. +// +// TODO(karalabe): Deprecate when the subscription one can return past data too. +func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { + var filter *filters.Filter + if query.BlockHash != nil { + // Block filter requested, construct a single-shot filter + filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) + } else { + // Initialize unset filter boundaried to run from genesis to chain head + from := int64(0) + if query.FromBlock != nil { + from = query.FromBlock.Int64() + } + to := int64(-1) + if query.ToBlock != nil { + to = query.ToBlock.Int64() + } + // Construct the range filter + filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) + } + // Run the filter and return all the logs + logs, err := filter.Logs(ctx) + if err != nil { + return nil, err + } + res := make([]types.Log, len(logs)) + for i, log := range logs { + res[i] = *log + } + return res, nil +} + +// SubscribeFilterLogs creates a background log filtering operation, returning a +// subscription immediately, which can be used to stream the found events. +func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { + // Subscribe to contract events + sink := make(chan []*types.Log) + + sub, err := b.events.SubscribeLogs(query, sink) + if err != nil { + return nil, err + } + // Since we're getting logs in batches, we need to flatten them into a plain stream + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case logs := <-sink: + for _, log := range logs { + select { + case ch <- *log: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// AdjustTime adds a time shift to the simulated clock. +func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { + b.mu.Lock() + defer b.mu.Unlock() + blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { + for _, tx := range b.pendingBlock.Transactions() { + block.AddTx(tx) + } + block.OffsetTime(int64(adjustment.Seconds())) + }) + statedb, _ := b.blockchain.State() + + b.pendingBlock = blocks[0] + b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) + + return nil +} + +// callmsg implements core.Message to allow passing it as a transaction simulator. +type callmsg struct { + ethereum.CallMsg +} + +func (m callmsg) From() common.Address { return m.CallMsg.From } +func (m callmsg) Nonce() uint64 { return 0 } +func (m callmsg) CheckNonce() bool { return false } +func (m callmsg) To() *common.Address { return m.CallMsg.To } +func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } +func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } +func (m callmsg) Value() *big.Int { return m.CallMsg.Value } +func (m callmsg) Data() []byte { return m.CallMsg.Data } + +// filterBackend implements filters.Backend to support filtering for logs without +// taking bloom-bits acceleration structures into account. +type filterBackend struct { + db ethdb.Database + bc *core.BlockChain +} + +func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } +func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } + +func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { + if block == rpc.LatestBlockNumber { + return fb.bc.CurrentHeader(), nil + } + return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil +} + +func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return fb.bc.GetHeaderByHash(hash), nil +} + +func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { + number := rawdb.ReadHeaderNumber(fb.db, hash) + if number == nil { + return nil, nil + } + return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil +} + +func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { + number := rawdb.ReadHeaderNumber(fb.db, hash) + if number == nil { + return nil, nil + } + receipts := rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()) + if receipts == nil { + return nil, nil + } + logs := make([][]*types.Log, len(receipts)) + for i, receipt := range receipts { + logs[i] = receipt.Logs + } + return logs, nil +} + +func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { + return event.NewSubscription(func(quit <-chan struct{}) error { + <-quit + return nil + }) +} +func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + return fb.bc.SubscribeChainEvent(ch) +} +func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { + return fb.bc.SubscribeRemovedLogsEvent(ch) +} +func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + return fb.bc.SubscribeLogsEvent(ch) +} + +func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 } +func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) { + panic("not supported") +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/method.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/method.go new file mode 100644 index 00000000..d3c02599 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/method.go @@ -0,0 +1,77 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package abi + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/crypto" +) + +// Method represents a callable given a `Name` and whether the method is a constant. +// If the method is `Const` no transaction needs to be created for this +// particular Method call. It can easily be simulated using a local VM. +// For example a `Balance()` method only needs to retrieve something +// from the storage and therefore requires no Tx to be send to the +// network. A method such as `Transact` does require a Tx and thus will +// be flagged `false`. +// Input specifies the required input parameters for this gives method. +type Method struct { + Name string + Const bool + Inputs Arguments + Outputs Arguments +} + +// Sig returns the methods string signature according to the ABI spec. +// +// Example +// +// function foo(uint32 a, int b) = "foo(uint32,int256)" +// +// Please note that "int" is substitute for its canonical representation "int256" +func (method Method) Sig() string { + types := make([]string, len(method.Inputs)) + for i, input := range method.Inputs { + types[i] = input.Type.String() + } + return fmt.Sprintf("%v(%v)", method.Name, strings.Join(types, ",")) +} + +func (method Method) String() string { + inputs := make([]string, len(method.Inputs)) + for i, input := range method.Inputs { + inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name) + } + outputs := make([]string, len(method.Outputs)) + for i, output := range method.Outputs { + outputs[i] = output.Type.String() + if len(output.Name) > 0 { + outputs[i] += fmt.Sprintf(" %v", output.Name) + } + } + constant := "" + if method.Const { + constant = "constant " + } + return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) +} + +func (method Method) Id() []byte { + return crypto.Keccak256([]byte(method.Sig()))[:4] +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/accounts.go b/vendor/github.com/ethereum/go-ethereum/accounts/accounts.go new file mode 100644 index 00000000..bf5190ad --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/accounts.go @@ -0,0 +1,222 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package accounts implements high level Ethereum account management. +package accounts + +import ( + "fmt" + "math/big" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "golang.org/x/crypto/sha3" +) + +// Account represents an Ethereum account located at a specific location defined +// by the optional URL field. +type Account struct { + Address common.Address `json:"address"` // Ethereum account address derived from the key + URL URL `json:"url"` // Optional resource locator within a backend +} + +const ( + MimetypeDataWithValidator = "data/validator" + MimetypeTypedData = "data/typed" + MimetypeClique = "application/x-clique-header" + MimetypeTextPlain = "text/plain" +) + +// Wallet represents a software or hardware wallet that might contain one or more +// accounts (derived from the same seed). +type Wallet interface { + // URL retrieves the canonical path under which this wallet is reachable. It is + // user by upper layers to define a sorting order over all wallets from multiple + // backends. + URL() URL + + // Status returns a textual status to aid the user in the current state of the + // wallet. It also returns an error indicating any failure the wallet might have + // encountered. + Status() (string, error) + + // Open initializes access to a wallet instance. It is not meant to unlock or + // decrypt account keys, rather simply to establish a connection to hardware + // wallets and/or to access derivation seeds. + // + // The passphrase parameter may or may not be used by the implementation of a + // particular wallet instance. The reason there is no passwordless open method + // is to strive towards a uniform wallet handling, oblivious to the different + // backend providers. + // + // Please note, if you open a wallet, you must close it to release any allocated + // resources (especially important when working with hardware wallets). + Open(passphrase string) error + + // Close releases any resources held by an open wallet instance. + Close() error + + // Accounts retrieves the list of signing accounts the wallet is currently aware + // of. For hierarchical deterministic wallets, the list will not be exhaustive, + // rather only contain the accounts explicitly pinned during account derivation. + Accounts() []Account + + // Contains returns whether an account is part of this particular wallet or not. + Contains(account Account) bool + + // Derive attempts to explicitly derive a hierarchical deterministic account at + // the specified derivation path. If requested, the derived account will be added + // to the wallet's tracked account list. + Derive(path DerivationPath, pin bool) (Account, error) + + // SelfDerive sets a base account derivation path from which the wallet attempts + // to discover non zero accounts and automatically add them to list of tracked + // accounts. + // + // Note, self derivaton will increment the last component of the specified path + // opposed to decending into a child path to allow discovering accounts starting + // from non zero components. + // + // Some hardware wallets switched derivation paths through their evolution, so + // this method supports providing multiple bases to discover old user accounts + // too. Only the last base will be used to derive the next empty account. + // + // You can disable automatic account discovery by calling SelfDerive with a nil + // chain state reader. + SelfDerive(bases []DerivationPath, chain ethereum.ChainStateReader) + + // SignData requests the wallet to sign the hash of the given data + // It looks up the account specified either solely via its address contained within, + // or optionally with the aid of any location metadata from the embedded URL field. + // + // If the wallet requires additional authentication to sign the request (e.g. + // a password to decrypt the account, or a PIN code o verify the transaction), + // an AuthNeededError instance will be returned, containing infos for the user + // about which fields or actions are needed. The user may retry by providing + // the needed details via SignDataWithPassphrase, or by other means (e.g. unlock + // the account in a keystore). + SignData(account Account, mimeType string, data []byte) ([]byte, error) + + // SignDataWithPassphrase is identical to SignData, but also takes a password + // NOTE: there's an chance that an erroneous call might mistake the two strings, and + // supply password in the mimetype field, or vice versa. Thus, an implementation + // should never echo the mimetype or return the mimetype in the error-response + SignDataWithPassphrase(account Account, passphrase, mimeType string, data []byte) ([]byte, error) + + // SignText requests the wallet to sign the hash of a given piece of data, prefixed + // by the Ethereum prefix scheme + // It looks up the account specified either solely via its address contained within, + // or optionally with the aid of any location metadata from the embedded URL field. + // + // If the wallet requires additional authentication to sign the request (e.g. + // a password to decrypt the account, or a PIN code o verify the transaction), + // an AuthNeededError instance will be returned, containing infos for the user + // about which fields or actions are needed. The user may retry by providing + // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock + // the account in a keystore). + SignText(account Account, text []byte) ([]byte, error) + + // SignTextWithPassphrase is identical to Signtext, but also takes a password + SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) + + // SignTx requests the wallet to sign the given transaction. + // + // It looks up the account specified either solely via its address contained within, + // or optionally with the aid of any location metadata from the embedded URL field. + // + // If the wallet requires additional authentication to sign the request (e.g. + // a password to decrypt the account, or a PIN code to verify the transaction), + // an AuthNeededError instance will be returned, containing infos for the user + // about which fields or actions are needed. The user may retry by providing + // the needed details via SignTxWithPassphrase, or by other means (e.g. unlock + // the account in a keystore). + SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) + + // SignTxWithPassphrase is identical to SignTx, but also takes a password + SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) +} + +// Backend is a "wallet provider" that may contain a batch of accounts they can +// sign transactions with and upon request, do so. +type Backend interface { + // Wallets retrieves the list of wallets the backend is currently aware of. + // + // The returned wallets are not opened by default. For software HD wallets this + // means that no base seeds are decrypted, and for hardware wallets that no actual + // connection is established. + // + // The resulting wallet list will be sorted alphabetically based on its internal + // URL assigned by the backend. Since wallets (especially hardware) may come and + // go, the same wallet might appear at a different positions in the list during + // subsequent retrievals. + Wallets() []Wallet + + // Subscribe creates an async subscription to receive notifications when the + // backend detects the arrival or departure of a wallet. + Subscribe(sink chan<- WalletEvent) event.Subscription +} + +// TextHash is a helper function that calculates a hash for the given message that can be +// safely used to calculate a signature from. +// +// The hash is calulcated as +// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). +// +// This gives context to the signed message and prevents signing of transactions. +func TextHash(data []byte) []byte { + hash, _ := TextAndHash(data) + return hash +} + +// TextAndHash is a helper function that calculates a hash for the given message that can be +// safely used to calculate a signature from. +// +// The hash is calulcated as +// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). +// +// This gives context to the signed message and prevents signing of transactions. +func TextAndHash(data []byte) ([]byte, string) { + msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data)) + hasher := sha3.NewLegacyKeccak256() + hasher.Write([]byte(msg)) + return hasher.Sum(nil), msg +} + +// WalletEventType represents the different event types that can be fired by +// the wallet subscription subsystem. +type WalletEventType int + +const ( + // WalletArrived is fired when a new wallet is detected either via USB or via + // a filesystem event in the keystore. + WalletArrived WalletEventType = iota + + // WalletOpened is fired when a wallet is successfully opened with the purpose + // of starting any background processes such as automatic key derivation. + WalletOpened + + // WalletDropped + WalletDropped +) + +// WalletEvent is an event fired by an account backend when a wallet arrival or +// departure is detected. +type WalletEvent struct { + Wallet Wallet // Wallet instance arrived or departed + Kind WalletEventType // Event type that happened in the system +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/external/backend.go b/vendor/github.com/ethereum/go-ethereum/accounts/external/backend.go new file mode 100644 index 00000000..23037f52 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/external/backend.go @@ -0,0 +1,228 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package external + +import ( + "fmt" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/signer/core" +) + +type ExternalBackend struct { + signers []accounts.Wallet +} + +func (eb *ExternalBackend) Wallets() []accounts.Wallet { + return eb.signers +} + +func NewExternalBackend(endpoint string) (*ExternalBackend, error) { + signer, err := NewExternalSigner(endpoint) + if err != nil { + return nil, err + } + return &ExternalBackend{ + signers: []accounts.Wallet{signer}, + }, nil +} + +func (eb *ExternalBackend) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { + return event.NewSubscription(func(quit <-chan struct{}) error { + <-quit + return nil + }) +} + +// ExternalSigner provides an API to interact with an external signer (clef) +// It proxies request to the external signer while forwarding relevant +// request headers +type ExternalSigner struct { + client *rpc.Client + endpoint string + status string + cacheMu sync.RWMutex + cache []accounts.Account +} + +func NewExternalSigner(endpoint string) (*ExternalSigner, error) { + client, err := rpc.Dial(endpoint) + if err != nil { + return nil, err + } + extsigner := &ExternalSigner{ + client: client, + endpoint: endpoint, + } + // Check if reachable + version, err := extsigner.pingVersion() + if err != nil { + return nil, err + } + extsigner.status = fmt.Sprintf("ok [version=%v]", version) + return extsigner, nil +} + +func (api *ExternalSigner) URL() accounts.URL { + return accounts.URL{ + Scheme: "extapi", + Path: api.endpoint, + } +} + +func (api *ExternalSigner) Status() (string, error) { + return api.status, nil +} + +func (api *ExternalSigner) Open(passphrase string) error { + return fmt.Errorf("operation not supported on external signers") +} + +func (api *ExternalSigner) Close() error { + return fmt.Errorf("operation not supported on external signers") +} + +func (api *ExternalSigner) Accounts() []accounts.Account { + var accnts []accounts.Account + res, err := api.listAccounts() + if err != nil { + log.Error("account listing failed", "error", err) + return accnts + } + for _, addr := range res { + accnts = append(accnts, accounts.Account{ + URL: accounts.URL{ + Scheme: "extapi", + Path: api.endpoint, + }, + Address: addr, + }) + } + api.cacheMu.Lock() + api.cache = accnts + api.cacheMu.Unlock() + return accnts +} + +func (api *ExternalSigner) Contains(account accounts.Account) bool { + api.cacheMu.RLock() + defer api.cacheMu.RUnlock() + for _, a := range api.cache { + if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()) { + return true + } + } + return false +} + +func (api *ExternalSigner) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + return accounts.Account{}, fmt.Errorf("operation not supported on external signers") +} + +func (api *ExternalSigner) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { + log.Error("operation SelfDerive not supported on external signers") +} + +func (api *ExternalSigner) signHash(account accounts.Account, hash []byte) ([]byte, error) { + return []byte{}, fmt.Errorf("operation not supported on external signers") +} + +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + var res hexutil.Bytes + var signAddress = common.NewMixedcaseAddress(account.Address) + if err := api.client.Call(&res, "account_signData", + mimeType, + &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined + hexutil.Encode(data)); err != nil { + return nil, err + } + // If V is on 27/28-form, convert to to 0/1 for Clique + if mimeType == accounts.MimetypeClique && (res[64] == 27 || res[64] == 28) { + res[64] -= 27 // Transform V from 27/28 to 0/1 for Clique use + } + return res, nil +} + +func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) { + var res hexutil.Bytes + var signAddress = common.NewMixedcaseAddress(account.Address) + if err := api.client.Call(&res, "account_signData", + accounts.MimetypeTextPlain, + &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined + hexutil.Encode(text)); err != nil { + return nil, err + } + return res, nil +} + +func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + res := ethapi.SignTransactionResult{} + to := common.NewMixedcaseAddress(*tx.To()) + data := hexutil.Bytes(tx.Data()) + args := &core.SendTxArgs{ + Data: &data, + Nonce: hexutil.Uint64(tx.Nonce()), + Value: hexutil.Big(*tx.Value()), + Gas: hexutil.Uint64(tx.Gas()), + GasPrice: hexutil.Big(*tx.GasPrice()), + To: &to, + From: common.NewMixedcaseAddress(account.Address), + } + + if err := api.client.Call(&res, "account_signTransaction", args); err != nil { + return nil, err + } + return res.Tx, nil +} + +func (api *ExternalSigner) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return []byte{}, fmt.Errorf("passphrase-operations not supported on external signers") +} + +func (api *ExternalSigner) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + return nil, fmt.Errorf("passphrase-operations not supported on external signers") +} +func (api *ExternalSigner) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + return nil, fmt.Errorf("passphrase-operations not supported on external signers") +} + +func (api *ExternalSigner) listAccounts() ([]common.Address, error) { + var res []common.Address + if err := api.client.Call(&res, "account_list"); err != nil { + return nil, err + } + return res, nil +} + +func (api *ExternalSigner) pingVersion() (string, error) { + var v string + if err := api.client.Call(&v, "account_version"); err != nil { + return "", err + } + return v, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/hd.go b/vendor/github.com/ethereum/go-ethereum/accounts/hd.go new file mode 100644 index 00000000..75c47611 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/hd.go @@ -0,0 +1,152 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package accounts + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "math/big" + "strings" +) + +// DefaultRootDerivationPath is the root path to which custom derivation endpoints +// are appended. As such, the first account will be at m/44'/60'/0'/0, the second +// at m/44'/60'/0'/1, etc. +var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} + +// DefaultBaseDerivationPath is the base path from which custom derivation endpoints +// are incremented. As such, the first account will be at m/44'/60'/0'/0/0, the second +// at m/44'/60'/0'/0/1, etc. +var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0} + +// LegacyLedgerBaseDerivationPath is the legacy base path from which custom derivation +// endpoints are incremented. As such, the first account will be at m/44'/60'/0'/0, the +// second at m/44'/60'/0'/1, etc. +var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} + +// DerivationPath represents the computer friendly version of a hierarchical +// deterministic wallet account derivaion path. +// +// The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +// defines derivation paths to be of the form: +// +// m / purpose' / coin_type' / account' / change / address_index +// +// The BIP-44 spec https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki +// defines that the `purpose` be 44' (or 0x8000002C) for crypto currencies, and +// SLIP-44 https://github.com/satoshilabs/slips/blob/master/slip-0044.md assigns +// the `coin_type` 60' (or 0x8000003C) to Ethereum. +// +// The root path for Ethereum is m/44'/60'/0'/0 according to the specification +// from https://github.com/ethereum/EIPs/issues/84, albeit it's not set in stone +// yet whether accounts should increment the last component or the children of +// that. We will go with the simpler approach of incrementing the last component. +type DerivationPath []uint32 + +// ParseDerivationPath converts a user specified derivation path string to the +// internal binary representation. +// +// Full derivation paths need to start with the `m/` prefix, relative derivation +// paths (which will get appended to the default root path) must not have prefixes +// in front of the first element. Whitespace is ignored. +func ParseDerivationPath(path string) (DerivationPath, error) { + var result DerivationPath + + // Handle absolute or relative paths + components := strings.Split(path, "/") + switch { + case len(components) == 0: + return nil, errors.New("empty derivation path") + + case strings.TrimSpace(components[0]) == "": + return nil, errors.New("ambiguous path: use 'm/' prefix for absolute paths, or no leading '/' for relative ones") + + case strings.TrimSpace(components[0]) == "m": + components = components[1:] + + default: + result = append(result, DefaultRootDerivationPath...) + } + // All remaining components are relative, append one by one + if len(components) == 0 { + return nil, errors.New("empty derivation path") // Empty relative paths + } + for _, component := range components { + // Ignore any user added whitespace + component = strings.TrimSpace(component) + var value uint32 + + // Handle hardened paths + if strings.HasSuffix(component, "'") { + value = 0x80000000 + component = strings.TrimSpace(strings.TrimSuffix(component, "'")) + } + // Handle the non hardened component + bigval, ok := new(big.Int).SetString(component, 0) + if !ok { + return nil, fmt.Errorf("invalid component: %s", component) + } + max := math.MaxUint32 - value + if bigval.Sign() < 0 || bigval.Cmp(big.NewInt(int64(max))) > 0 { + if value == 0 { + return nil, fmt.Errorf("component %v out of allowed range [0, %d]", bigval, max) + } + return nil, fmt.Errorf("component %v out of allowed hardened range [0, %d]", bigval, max) + } + value += uint32(bigval.Uint64()) + + // Append and repeat + result = append(result, value) + } + return result, nil +} + +// String implements the stringer interface, converting a binary derivation path +// to its canonical representation. +func (path DerivationPath) String() string { + result := "m" + for _, component := range path { + var hardened bool + if component >= 0x80000000 { + component -= 0x80000000 + hardened = true + } + result = fmt.Sprintf("%s/%d", result, component) + if hardened { + result += "'" + } + } + return result +} + +// MarshalJSON turns a derivation path into its json-serialized string +func (path DerivationPath) MarshalJSON() ([]byte, error) { + return json.Marshal(path.String()) +} + +// UnmarshalJSON a json-serialized string back into a derivation path +func (path *DerivationPath) UnmarshalJSON(b []byte) error { + var dp string + var err error + if err = json.Unmarshal(b, &dp); err != nil { + return err + } + *path, err = ParseDerivationPath(dp) + return err +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/keystore/passphrase.go b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/passphrase.go new file mode 100644 index 00000000..1ced41e9 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/passphrase.go @@ -0,0 +1,356 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +/* + +This key store behaves as KeyStorePlain with the difference that +the private key is encrypted and on disk uses another JSON encoding. + +The crypto is documented at https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition + +*/ + +package keystore + +import ( + "bytes" + "crypto/aes" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" + "github.com/pborman/uuid" + "golang.org/x/crypto/pbkdf2" + "golang.org/x/crypto/scrypt" +) + +const ( + keyHeaderKDF = "scrypt" + + // StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB + // memory and taking approximately 1s CPU time on a modern processor. + StandardScryptN = 1 << 18 + + // StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB + // memory and taking approximately 1s CPU time on a modern processor. + StandardScryptP = 1 + + // LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB + // memory and taking approximately 100ms CPU time on a modern processor. + LightScryptN = 1 << 12 + + // LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB + // memory and taking approximately 100ms CPU time on a modern processor. + LightScryptP = 6 + + scryptR = 8 + scryptDKLen = 32 +) + +type keyStorePassphrase struct { + keysDirPath string + scryptN int + scryptP int + // skipKeyFileVerification disables the security-feature which does + // reads and decrypts any newly created keyfiles. This should be 'false' in all + // cases except tests -- setting this to 'true' is not recommended. + skipKeyFileVerification bool +} + +func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { + // Load the key from the keystore and decrypt its contents + keyjson, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + key, err := DecryptKey(keyjson, auth) + if err != nil { + return nil, err + } + // Make sure we're really operating on the requested key (no swap attacks) + if key.Address != addr { + return nil, fmt.Errorf("key content mismatch: have account %x, want %x", key.Address, addr) + } + return key, nil +} + +// StoreKey generates a key, encrypts with 'auth' and stores in the given directory +func StoreKey(dir, auth string, scryptN, scryptP int) (accounts.Account, error) { + _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP, false}, rand.Reader, auth) + return a, err +} + +func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { + keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP) + if err != nil { + return err + } + // Write into temporary file + tmpName, err := writeTemporaryKeyFile(filename, keyjson) + if err != nil { + return err + } + if !ks.skipKeyFileVerification { + // Verify that we can decrypt the file with the given password. + _, err = ks.GetKey(key.Address, tmpName, auth) + if err != nil { + msg := "An error was encountered when saving and verifying the keystore file. \n" + + "This indicates that the keystore is corrupted. \n" + + "The corrupted file is stored at \n%v\n" + + "Please file a ticket at:\n\n" + + "https://github.com/ethereum/go-ethereum/issues." + + "The error was : %s" + return fmt.Errorf(msg, tmpName, err) + } + } + return os.Rename(tmpName, filename) +} + +func (ks keyStorePassphrase) JoinPath(filename string) string { + if filepath.IsAbs(filename) { + return filename + } + return filepath.Join(ks.keysDirPath, filename) +} + +// Encryptdata encrypts the data given as 'data' with the password 'auth'. +func EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) { + + salt := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, salt); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } + derivedKey, err := scrypt.Key(auth, salt, scryptN, scryptR, scryptP, scryptDKLen) + if err != nil { + return CryptoJSON{}, err + } + encryptKey := derivedKey[:16] + + iv := make([]byte, aes.BlockSize) // 16 + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } + cipherText, err := aesCTRXOR(encryptKey, data, iv) + if err != nil { + return CryptoJSON{}, err + } + mac := crypto.Keccak256(derivedKey[16:32], cipherText) + + scryptParamsJSON := make(map[string]interface{}, 5) + scryptParamsJSON["n"] = scryptN + scryptParamsJSON["r"] = scryptR + scryptParamsJSON["p"] = scryptP + scryptParamsJSON["dklen"] = scryptDKLen + scryptParamsJSON["salt"] = hex.EncodeToString(salt) + cipherParamsJSON := cipherparamsJSON{ + IV: hex.EncodeToString(iv), + } + + cryptoStruct := CryptoJSON{ + Cipher: "aes-128-ctr", + CipherText: hex.EncodeToString(cipherText), + CipherParams: cipherParamsJSON, + KDF: keyHeaderKDF, + KDFParams: scryptParamsJSON, + MAC: hex.EncodeToString(mac), + } + return cryptoStruct, nil +} + +// EncryptKey encrypts a key using the specified scrypt parameters into a json +// blob that can be decrypted later on. +func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { + keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) + cryptoStruct, err := EncryptDataV3(keyBytes, []byte(auth), scryptN, scryptP) + if err != nil { + return nil, err + } + encryptedKeyJSONV3 := encryptedKeyJSONV3{ + hex.EncodeToString(key.Address[:]), + cryptoStruct, + key.Id.String(), + version, + } + return json.Marshal(encryptedKeyJSONV3) +} + +// DecryptKey decrypts a key from a json blob, returning the private key itself. +func DecryptKey(keyjson []byte, auth string) (*Key, error) { + // Parse the json into a simple map to fetch the key version + m := make(map[string]interface{}) + if err := json.Unmarshal(keyjson, &m); err != nil { + return nil, err + } + // Depending on the version try to parse one way or another + var ( + keyBytes, keyId []byte + err error + ) + if version, ok := m["version"].(string); ok && version == "1" { + k := new(encryptedKeyJSONV1) + if err := json.Unmarshal(keyjson, k); err != nil { + return nil, err + } + keyBytes, keyId, err = decryptKeyV1(k, auth) + } else { + k := new(encryptedKeyJSONV3) + if err := json.Unmarshal(keyjson, k); err != nil { + return nil, err + } + keyBytes, keyId, err = decryptKeyV3(k, auth) + } + // Handle any decryption errors and return the key + if err != nil { + return nil, err + } + key := crypto.ToECDSAUnsafe(keyBytes) + + return &Key{ + Id: uuid.UUID(keyId), + Address: crypto.PubkeyToAddress(key.PublicKey), + PrivateKey: key, + }, nil +} + +func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { + if cryptoJson.Cipher != "aes-128-ctr" { + return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher) + } + mac, err := hex.DecodeString(cryptoJson.MAC) + if err != nil { + return nil, err + } + + iv, err := hex.DecodeString(cryptoJson.CipherParams.IV) + if err != nil { + return nil, err + } + + cipherText, err := hex.DecodeString(cryptoJson.CipherText) + if err != nil { + return nil, err + } + + derivedKey, err := getKDFKey(cryptoJson, auth) + if err != nil { + return nil, err + } + + calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText) + if !bytes.Equal(calculatedMAC, mac) { + return nil, ErrDecrypt + } + + plainText, err := aesCTRXOR(derivedKey[:16], cipherText, iv) + if err != nil { + return nil, err + } + return plainText, err +} + +func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { + if keyProtected.Version != version { + return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version) + } + keyId = uuid.Parse(keyProtected.Id) + plainText, err := DecryptDataV3(keyProtected.Crypto, auth) + if err != nil { + return nil, nil, err + } + return plainText, keyId, err +} + +func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byte, keyId []byte, err error) { + keyId = uuid.Parse(keyProtected.Id) + mac, err := hex.DecodeString(keyProtected.Crypto.MAC) + if err != nil { + return nil, nil, err + } + + iv, err := hex.DecodeString(keyProtected.Crypto.CipherParams.IV) + if err != nil { + return nil, nil, err + } + + cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText) + if err != nil { + return nil, nil, err + } + + derivedKey, err := getKDFKey(keyProtected.Crypto, auth) + if err != nil { + return nil, nil, err + } + + calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText) + if !bytes.Equal(calculatedMAC, mac) { + return nil, nil, ErrDecrypt + } + + plainText, err := aesCBCDecrypt(crypto.Keccak256(derivedKey[:16])[:16], cipherText, iv) + if err != nil { + return nil, nil, err + } + return plainText, keyId, err +} + +func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) { + authArray := []byte(auth) + salt, err := hex.DecodeString(cryptoJSON.KDFParams["salt"].(string)) + if err != nil { + return nil, err + } + dkLen := ensureInt(cryptoJSON.KDFParams["dklen"]) + + if cryptoJSON.KDF == keyHeaderKDF { + n := ensureInt(cryptoJSON.KDFParams["n"]) + r := ensureInt(cryptoJSON.KDFParams["r"]) + p := ensureInt(cryptoJSON.KDFParams["p"]) + return scrypt.Key(authArray, salt, n, r, p, dkLen) + + } else if cryptoJSON.KDF == "pbkdf2" { + c := ensureInt(cryptoJSON.KDFParams["c"]) + prf := cryptoJSON.KDFParams["prf"].(string) + if prf != "hmac-sha256" { + return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf) + } + key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New) + return key, nil + } + + return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF) +} + +// TODO: can we do without this when unmarshalling dynamic JSON? +// why do integers in KDF params end up as float64 and not int after +// unmarshal? +func ensureInt(x interface{}) int { + res, ok := x.(int) + if !ok { + res = int(x.(float64)) + } + return res +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/keystore/wallet.go b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/wallet.go new file mode 100644 index 00000000..498067d4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/wallet.go @@ -0,0 +1,148 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package keystore + +import ( + "math/big" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +// keystoreWallet implements the accounts.Wallet interface for the original +// keystore. +type keystoreWallet struct { + account accounts.Account // Single account contained in this wallet + keystore *KeyStore // Keystore where the account originates from +} + +// URL implements accounts.Wallet, returning the URL of the account within. +func (w *keystoreWallet) URL() accounts.URL { + return w.account.URL +} + +// Status implements accounts.Wallet, returning whether the account held by the +// keystore wallet is unlocked or not. +func (w *keystoreWallet) Status() (string, error) { + w.keystore.mu.RLock() + defer w.keystore.mu.RUnlock() + + if _, ok := w.keystore.unlocked[w.account.Address]; ok { + return "Unlocked", nil + } + return "Locked", nil +} + +// Open implements accounts.Wallet, but is a noop for plain wallets since there +// is no connection or decryption step necessary to access the list of accounts. +func (w *keystoreWallet) Open(passphrase string) error { return nil } + +// Close implements accounts.Wallet, but is a noop for plain wallets since there +// is no meaningful open operation. +func (w *keystoreWallet) Close() error { return nil } + +// Accounts implements accounts.Wallet, returning an account list consisting of +// a single account that the plain kestore wallet contains. +func (w *keystoreWallet) Accounts() []accounts.Account { + return []accounts.Account{w.account} +} + +// Contains implements accounts.Wallet, returning whether a particular account is +// or is not wrapped by this wallet instance. +func (w *keystoreWallet) Contains(account accounts.Account) bool { + return account.Address == w.account.Address && (account.URL == (accounts.URL{}) || account.URL == w.account.URL) +} + +// Derive implements accounts.Wallet, but is a noop for plain wallets since there +// is no notion of hierarchical account derivation for plain keystore accounts. +func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + return accounts.Account{}, accounts.ErrNotSupported +} + +// SelfDerive implements accounts.Wallet, but is a noop for plain wallets since +// there is no notion of hierarchical account derivation for plain keystore accounts. +func (w *keystoreWallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { +} + +// signHash attempts to sign the given hash with +// the given account. If the wallet does not wrap this particular account, an +// error is returned to avoid account leakage (even though in theory we may be +// able to sign via our shared keystore backend). +func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignHash(account, hash) +} + +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.signHash(account, crypto.Keccak256(data)) +} + +// SignDataWithPassphrase signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *keystoreWallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) +} + +func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.signHash(account, accounts.TextHash(text)) +} + +// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the +// given hash with the given account using passphrase as extra authentication. +func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignHashWithPassphrase(account, passphrase, accounts.TextHash(text)) +} + +// SignTx implements accounts.Wallet, attempting to sign the given transaction +// with the given account. If the wallet does not wrap this particular account, +// an error is returned to avoid account leakage (even though in theory we may +// be able to sign via our shared keystore backend). +func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignTx(account, tx, chainID) +} + +// SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given +// transaction with the given account using passphrase as extra authentication. +func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID) +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch.go b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch.go new file mode 100644 index 00000000..d6ef5332 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch.go @@ -0,0 +1,108 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build darwin,!ios,cgo freebsd linux,!arm64 netbsd solaris + +package keystore + +import ( + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/rjeczalik/notify" +) + +type watcher struct { + ac *accountCache + starting bool + running bool + ev chan notify.EventInfo + quit chan struct{} +} + +func newWatcher(ac *accountCache) *watcher { + return &watcher{ + ac: ac, + ev: make(chan notify.EventInfo, 10), + quit: make(chan struct{}), + } +} + +// starts the watcher loop in the background. +// Start a watcher in the background if that's not already in progress. +// The caller must hold w.ac.mu. +func (w *watcher) start() { + if w.starting || w.running { + return + } + w.starting = true + go w.loop() +} + +func (w *watcher) close() { + close(w.quit) +} + +func (w *watcher) loop() { + defer func() { + w.ac.mu.Lock() + w.running = false + w.starting = false + w.ac.mu.Unlock() + }() + logger := log.New("path", w.ac.keydir) + + if err := notify.Watch(w.ac.keydir, w.ev, notify.All); err != nil { + logger.Trace("Failed to watch keystore folder", "err", err) + return + } + defer notify.Stop(w.ev) + logger.Trace("Started watching keystore folder") + defer logger.Trace("Stopped watching keystore folder") + + w.ac.mu.Lock() + w.running = true + w.ac.mu.Unlock() + + // Wait for file system events and reload. + // When an event occurs, the reload call is delayed a bit so that + // multiple events arriving quickly only cause a single reload. + var ( + debounceDuration = 500 * time.Millisecond + rescanTriggered = false + debounce = time.NewTimer(0) + ) + // Ignore initial trigger + if !debounce.Stop() { + <-debounce.C + } + defer debounce.Stop() + for { + select { + case <-w.quit: + return + case <-w.ev: + // Trigger the scan (with delay), if not already triggered + if !rescanTriggered { + debounce.Reset(debounceDuration) + rescanTriggered = true + } + case <-debounce.C: + w.ac.scanAccounts() + rescanTriggered = false + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch_fallback.go b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch_fallback.go new file mode 100644 index 00000000..de0e87f8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/keystore/watch_fallback.go @@ -0,0 +1,28 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build darwin,!cgo ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris + +// This is the fallback implementation of directory watching. +// It is used on unsupported platforms. + +package keystore + +type watcher struct{ running bool } + +func newWatcher(*accountCache) *watcher { return new(watcher) } +func (*watcher) start() {} +func (*watcher) close() {} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/manager.go b/vendor/github.com/ethereum/go-ethereum/accounts/manager.go new file mode 100644 index 00000000..3cf3422e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/manager.go @@ -0,0 +1,214 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package accounts + +import ( + "reflect" + "sort" + "sync" + + "github.com/ethereum/go-ethereum/event" +) + +// Config contains the settings of the global account manager. +// +// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management +// is removed in favor of Clef. +type Config struct { + InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed +} + +// Manager is an overarching account manager that can communicate with various +// backends for signing transactions. +type Manager struct { + config *Config // Global account manager configurations + backends map[reflect.Type][]Backend // Index of backends currently registered + updaters []event.Subscription // Wallet update subscriptions for all backends + updates chan WalletEvent // Subscription sink for backend wallet changes + wallets []Wallet // Cache of all wallets from all registered backends + + feed event.Feed // Wallet feed notifying of arrivals/departures + + quit chan chan error + lock sync.RWMutex +} + +// NewManager creates a generic account manager to sign transaction via various +// supported backends. +func NewManager(config *Config, backends ...Backend) *Manager { + // Retrieve the initial list of wallets from the backends and sort by URL + var wallets []Wallet + for _, backend := range backends { + wallets = merge(wallets, backend.Wallets()...) + } + // Subscribe to wallet notifications from all backends + updates := make(chan WalletEvent, 4*len(backends)) + + subs := make([]event.Subscription, len(backends)) + for i, backend := range backends { + subs[i] = backend.Subscribe(updates) + } + // Assemble the account manager and return + am := &Manager{ + config: config, + backends: make(map[reflect.Type][]Backend), + updaters: subs, + updates: updates, + wallets: wallets, + quit: make(chan chan error), + } + for _, backend := range backends { + kind := reflect.TypeOf(backend) + am.backends[kind] = append(am.backends[kind], backend) + } + go am.update() + + return am +} + +// Close terminates the account manager's internal notification processes. +func (am *Manager) Close() error { + errc := make(chan error) + am.quit <- errc + return <-errc +} + +// Config returns the configuration of account manager. +func (am *Manager) Config() *Config { + return am.config +} + +// update is the wallet event loop listening for notifications from the backends +// and updating the cache of wallets. +func (am *Manager) update() { + // Close all subscriptions when the manager terminates + defer func() { + am.lock.Lock() + for _, sub := range am.updaters { + sub.Unsubscribe() + } + am.updaters = nil + am.lock.Unlock() + }() + + // Loop until termination + for { + select { + case event := <-am.updates: + // Wallet event arrived, update local cache + am.lock.Lock() + switch event.Kind { + case WalletArrived: + am.wallets = merge(am.wallets, event.Wallet) + case WalletDropped: + am.wallets = drop(am.wallets, event.Wallet) + } + am.lock.Unlock() + + // Notify any listeners of the event + am.feed.Send(event) + + case errc := <-am.quit: + // Manager terminating, return + errc <- nil + return + } + } +} + +// Backends retrieves the backend(s) with the given type from the account manager. +func (am *Manager) Backends(kind reflect.Type) []Backend { + return am.backends[kind] +} + +// Wallets returns all signer accounts registered under this account manager. +func (am *Manager) Wallets() []Wallet { + am.lock.RLock() + defer am.lock.RUnlock() + + cpy := make([]Wallet, len(am.wallets)) + copy(cpy, am.wallets) + return cpy +} + +// Wallet retrieves the wallet associated with a particular URL. +func (am *Manager) Wallet(url string) (Wallet, error) { + am.lock.RLock() + defer am.lock.RUnlock() + + parsed, err := parseURL(url) + if err != nil { + return nil, err + } + for _, wallet := range am.Wallets() { + if wallet.URL() == parsed { + return wallet, nil + } + } + return nil, ErrUnknownWallet +} + +// Find attempts to locate the wallet corresponding to a specific account. Since +// accounts can be dynamically added to and removed from wallets, this method has +// a linear runtime in the number of wallets. +func (am *Manager) Find(account Account) (Wallet, error) { + am.lock.RLock() + defer am.lock.RUnlock() + + for _, wallet := range am.wallets { + if wallet.Contains(account) { + return wallet, nil + } + } + return nil, ErrUnknownAccount +} + +// Subscribe creates an async subscription to receive notifications when the +// manager detects the arrival or departure of a wallet from any of its backends. +func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription { + return am.feed.Subscribe(sink) +} + +// merge is a sorted analogue of append for wallets, where the ordering of the +// origin list is preserved by inserting new wallets at the correct position. +// +// The original slice is assumed to be already sorted by URL. +func merge(slice []Wallet, wallets ...Wallet) []Wallet { + for _, wallet := range wallets { + n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) + if n == len(slice) { + slice = append(slice, wallet) + continue + } + slice = append(slice[:n], append([]Wallet{wallet}, slice[n:]...)...) + } + return slice +} + +// drop is the couterpart of merge, which looks up wallets from within the sorted +// cache and removes the ones specified. +func drop(slice []Wallet, wallets ...Wallet) []Wallet { + for _, wallet := range wallets { + n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) + if n == len(slice) { + // Wallet not found, may happen during startup + continue + } + slice = append(slice[:n], slice[n+1:]...) + } + return slice +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/README.md b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/README.md new file mode 100644 index 00000000..cfca916b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/README.md @@ -0,0 +1,102 @@ +# Using the smartcard wallet + +## Requirements + + * A USB smartcard reader + * A keycard that supports the status app + * PCSCD version 4.3 running on your system **Only version 4.3 is currently supported** + +## Preparing the smartcard + + **WARNING: FOILLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** + + You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get _at least_ version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.2.1/keycard_v2.2.1.cap) + + You also need to make sure that the PCSC daemon is running on your system. + + Then, you can install the application to the card by typing: + + ``` + keycard install -a keycard_v2.2.1.cap && keycard init + ``` + + At the end of this process, you will be provided with a PIN, a PUK and a pairing password. Write them down, you'll need them shortly. + + Start `geth` with the `console` command. You will notice the following warning: + + ``` + WARN [04-09|16:58:38.898] Failed to open wallet url=keycard://044def09 err="smartcard: pairing password needed" + ``` + + Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet: + + ``` + > personal.openWallet("keycard://044def09") + Please enter the pairing password: + ``` + + Enter the pairing password that you have received during card initialization. Same with the PIN that you will subsequently be + asked for. + + If everything goes well, you should see your new account when typing `personal` on the console: + + ``` + > personal + WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=keycard://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985" + { + listAccounts: [], + listWallets: [{ + status: "Empty, waiting for initialization", + url: "keycard://044def09" + }], + ... + } + ``` + + So the communication with the card is working, but there is no key associated with this wallet. Let's create it: + + ``` + > personal.initializeWallet("keycard://044def09") + "tilt ... impact" + ``` + + You should get a list of words, this is your seed so write them down. Your wallet should now be initialized: + + ``` + > personal.listWallets + [{ + accounts: [{ + address: "0x678b7cd55c61917defb23546a41803c5bfefbc7a", + url: "keycard://044d/m/44'/60'/0'/0/0" + }], + status: "Online", + url: "keycard://044def09" + }] + ``` + + You're all set! + +## Usage + + 1. Start `geth` with the `console` command + 2. Check the card's URL by checking `personal.listWallets`: + +``` + listWallets: [{ + status: "Online, can derive public keys", + url: "keycard://a4d73015" + }] +``` + + 3. Open the wallet, you will be prompted for your pairing password, then PIN: + +``` +personal.openWallet("keycard://a4d73015") +``` + + 4. Check that creation was successful by typing e.g. `personal`. Then use it like a regular wallet. + +## Known issues + + * Starting geth with a valid card seems to make firefox crash. + * PCSC version 4.4 should work, but is currently untested diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/apdu.go b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/apdu.go new file mode 100644 index 00000000..bd366060 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/apdu.go @@ -0,0 +1,87 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package scwallet + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +// commandAPDU represents an application data unit sent to a smartcard. +type commandAPDU struct { + Cla, Ins, P1, P2 uint8 // Class, Instruction, Parameter 1, Parameter 2 + Data []byte // Command data + Le uint8 // Command data length +} + +// serialize serializes a command APDU. +func (ca commandAPDU) serialize() ([]byte, error) { + buf := new(bytes.Buffer) + + if err := binary.Write(buf, binary.BigEndian, ca.Cla); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.Ins); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.P1); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.P2); err != nil { + return nil, err + } + if len(ca.Data) > 0 { + if err := binary.Write(buf, binary.BigEndian, uint8(len(ca.Data))); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.Data); err != nil { + return nil, err + } + } + if err := binary.Write(buf, binary.BigEndian, ca.Le); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// responseAPDU represents an application data unit received from a smart card. +type responseAPDU struct { + Data []byte // response data + Sw1, Sw2 uint8 // status words 1 and 2 +} + +// deserialize deserializes a response APDU. +func (ra *responseAPDU) deserialize(data []byte) error { + if len(data) < 2 { + return fmt.Errorf("can not deserialize data: payload too short (%d < 2)", len(data)) + } + + ra.Data = make([]byte, len(data)-2) + + buf := bytes.NewReader(data) + if err := binary.Read(buf, binary.BigEndian, &ra.Data); err != nil { + return err + } + if err := binary.Read(buf, binary.BigEndian, &ra.Sw1); err != nil { + return err + } + if err := binary.Read(buf, binary.BigEndian, &ra.Sw2); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/hub.go b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/hub.go new file mode 100644 index 00000000..5f939c65 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/hub.go @@ -0,0 +1,302 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// This package implements support for smartcard-based hardware wallets such as +// the one written by Status: https://github.com/status-im/hardware-wallet +// +// This implementation of smartcard wallets have a different interaction process +// to other types of hardware wallet. The process works like this: +// +// 1. (First use with a given client) Establish a pairing between hardware +// wallet and client. This requires a secret value called a 'pairing password'. +// You can pair with an unpaired wallet with `personal.openWallet(URI, pairing password)`. +// 2. (First use only) Initialize the wallet, which generates a keypair, stores +// it on the wallet, and returns it so the user can back it up. You can +// initialize a wallet with `personal.initializeWallet(URI)`. +// 3. Connect to the wallet using the pairing information established in step 1. +// You can connect to a paired wallet with `personal.openWallet(URI, PIN)`. +// 4. Interact with the wallet as normal. + +package scwallet + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "sort" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + pcsc "github.com/gballet/go-libpcsclite" +) + +// Scheme is the URI prefix for smartcard wallets. +const Scheme = "keycard" + +// refreshCycle is the maximum time between wallet refreshes (if USB hotplug +// notifications don't work). +const refreshCycle = time.Second + +// refreshThrottling is the minimum time between wallet refreshes to avoid thrashing. +const refreshThrottling = 500 * time.Millisecond + +// smartcardPairing contains information about a smart card we have paired with +// or might pair with the hub. +type smartcardPairing struct { + PublicKey []byte `json:"publicKey"` + PairingIndex uint8 `json:"pairingIndex"` + PairingKey []byte `json:"pairingKey"` + Accounts map[common.Address]accounts.DerivationPath `json:"accounts"` +} + +// Hub is a accounts.Backend that can find and handle generic PC/SC hardware wallets. +type Hub struct { + scheme string // Protocol scheme prefixing account and wallet URLs. + + context *pcsc.Client + datadir string + pairings map[string]smartcardPairing + + refreshed time.Time // Time instance when the list of wallets was last refreshed + wallets map[string]*Wallet // Mapping from reader names to wallet instances + updateFeed event.Feed // Event feed to notify wallet additions/removals + updateScope event.SubscriptionScope // Subscription scope tracking current live listeners + updating bool // Whether the event notification loop is running + + quit chan chan error + + stateLock sync.RWMutex // Protects the internals of the hub from racey access +} + +func (hub *Hub) readPairings() error { + hub.pairings = make(map[string]smartcardPairing) + pairingFile, err := os.Open(filepath.Join(hub.datadir, "smartcards.json")) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + pairingData, err := ioutil.ReadAll(pairingFile) + if err != nil { + return err + } + var pairings []smartcardPairing + if err := json.Unmarshal(pairingData, &pairings); err != nil { + return err + } + + for _, pairing := range pairings { + hub.pairings[string(pairing.PublicKey)] = pairing + } + return nil +} + +func (hub *Hub) writePairings() error { + pairingFile, err := os.OpenFile(filepath.Join(hub.datadir, "smartcards.json"), os.O_RDWR|os.O_CREATE, 0755) + if err != nil { + return err + } + defer pairingFile.Close() + + pairings := make([]smartcardPairing, 0, len(hub.pairings)) + for _, pairing := range hub.pairings { + pairings = append(pairings, pairing) + } + + pairingData, err := json.Marshal(pairings) + if err != nil { + return err + } + + if _, err := pairingFile.Write(pairingData); err != nil { + return err + } + + return nil +} + +func (hub *Hub) pairing(wallet *Wallet) *smartcardPairing { + if pairing, ok := hub.pairings[string(wallet.PublicKey)]; ok { + return &pairing + } + return nil +} + +func (hub *Hub) setPairing(wallet *Wallet, pairing *smartcardPairing) error { + if pairing == nil { + delete(hub.pairings, string(wallet.PublicKey)) + } else { + hub.pairings[string(wallet.PublicKey)] = *pairing + } + return hub.writePairings() +} + +// NewHub creates a new hardware wallet manager for smartcards. +func NewHub(daemonPath string, scheme string, datadir string) (*Hub, error) { + context, err := pcsc.EstablishContext(daemonPath, pcsc.ScopeSystem) + if err != nil { + return nil, err + } + hub := &Hub{ + scheme: scheme, + context: context, + datadir: datadir, + wallets: make(map[string]*Wallet), + quit: make(chan chan error), + } + if err := hub.readPairings(); err != nil { + return nil, err + } + hub.refreshWallets() + return hub, nil +} + +// Wallets implements accounts.Backend, returning all the currently tracked smart +// cards that appear to be hardware wallets. +func (hub *Hub) Wallets() []accounts.Wallet { + // Make sure the list of wallets is up to date + hub.refreshWallets() + + hub.stateLock.RLock() + defer hub.stateLock.RUnlock() + + cpy := make([]accounts.Wallet, 0, len(hub.wallets)) + for _, wallet := range hub.wallets { + cpy = append(cpy, wallet) + } + sort.Sort(accounts.WalletsByURL(cpy)) + return cpy +} + +// refreshWallets scans the devices attached to the machine and updates the +// list of wallets based on the found devices. +func (hub *Hub) refreshWallets() { + // Don't scan the USB like crazy it the user fetches wallets in a loop + hub.stateLock.RLock() + elapsed := time.Since(hub.refreshed) + hub.stateLock.RUnlock() + + if elapsed < refreshThrottling { + return + } + // Retrieve all the smart card reader to check for cards + readers, err := hub.context.ListReaders() + if err != nil { + // This is a perverted hack, the scard library returns an error if no card + // readers are present instead of simply returning an empty list. We don't + // want to fill the user's log with errors, so filter those out. + if err.Error() != "scard: Cannot find a smart card reader." { + log.Error("Failed to enumerate smart card readers", "err", err) + return + } + } + // Transform the current list of wallets into the new one + hub.stateLock.Lock() + + events := []accounts.WalletEvent{} + seen := make(map[string]struct{}) + + for _, reader := range readers { + // Mark the reader as present + seen[reader] = struct{}{} + + // If we alreay know about this card, skip to the next reader, otherwise clean up + if wallet, ok := hub.wallets[reader]; ok { + if err := wallet.ping(); err == nil { + continue + } + wallet.Close() + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) + delete(hub.wallets, reader) + } + // New card detected, try to connect to it + card, err := hub.context.Connect(reader, pcsc.ShareShared, pcsc.ProtocolAny) + if err != nil { + log.Debug("Failed to open smart card", "reader", reader, "err", err) + continue + } + wallet := NewWallet(hub, card) + if err = wallet.connect(); err != nil { + log.Debug("Failed to connect to smart card", "reader", reader, "err", err) + card.Disconnect(pcsc.LeaveCard) + continue + } + // Card connected, start tracking in amongs the wallets + hub.wallets[reader] = wallet + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) + } + // Remove any wallets no longer present + for reader, wallet := range hub.wallets { + if _, ok := seen[reader]; !ok { + wallet.Close() + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) + delete(hub.wallets, reader) + } + } + hub.refreshed = time.Now() + hub.stateLock.Unlock() + + for _, event := range events { + hub.updateFeed.Send(event) + } +} + +// Subscribe implements accounts.Backend, creating an async subscription to +// receive notifications on the addition or removal of smart card wallets. +func (hub *Hub) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { + // We need the mutex to reliably start/stop the update loop + hub.stateLock.Lock() + defer hub.stateLock.Unlock() + + // Subscribe the caller and track the subscriber count + sub := hub.updateScope.Track(hub.updateFeed.Subscribe(sink)) + + // Subscribers require an active notification loop, start it + if !hub.updating { + hub.updating = true + go hub.updater() + } + return sub +} + +// updater is responsible for maintaining an up-to-date list of wallets managed +// by the smart card hub, and for firing wallet addition/removal events. +func (hub *Hub) updater() { + for { + // TODO: Wait for a USB hotplug event (not supported yet) or a refresh timeout + // <-hub.changes + time.Sleep(refreshCycle) + + // Run the wallet refresher + hub.refreshWallets() + + // If all our subscribers left, stop the updater + hub.stateLock.Lock() + if hub.updateScope.Count() == 0 { + hub.updating = false + hub.stateLock.Unlock() + return + } + hub.stateLock.Unlock() + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/securechannel.go b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/securechannel.go new file mode 100644 index 00000000..fad876a0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/securechannel.go @@ -0,0 +1,346 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package scwallet + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "crypto/sha512" + "fmt" + + "github.com/ethereum/go-ethereum/crypto" + pcsc "github.com/gballet/go-libpcsclite" + "github.com/wsddn/go-ecdh" + "golang.org/x/crypto/pbkdf2" + "golang.org/x/text/unicode/norm" +) + +const ( + maxPayloadSize = 223 + pairP1FirstStep = 0 + pairP1LastStep = 1 + + scSecretLength = 32 + scBlockSize = 16 + + insOpenSecureChannel = 0x10 + insMutuallyAuthenticate = 0x11 + insPair = 0x12 + insUnpair = 0x13 + + pairingSalt = "Keycard Pairing Password Salt" +) + +// SecureChannelSession enables secure communication with a hardware wallet. +type SecureChannelSession struct { + card *pcsc.Card // A handle to the smartcard for communication + secret []byte // A shared secret generated from our ECDSA keys + publicKey []byte // Our own ephemeral public key + PairingKey []byte // A permanent shared secret for a pairing, if present + sessionEncKey []byte // The current session encryption key + sessionMacKey []byte // The current session MAC key + iv []byte // The current IV + PairingIndex uint8 // The pairing index +} + +// NewSecureChannelSession creates a new secure channel for the given card and public key. +func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSession, error) { + // Generate an ECDSA keypair for ourselves + gen := ecdh.NewEllipticECDH(crypto.S256()) + private, public, err := gen.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + + cardPublic, ok := gen.Unmarshal(keyData) + if !ok { + return nil, fmt.Errorf("Could not unmarshal public key from card") + } + + secret, err := gen.GenerateSharedSecret(private, cardPublic) + if err != nil { + return nil, err + } + + return &SecureChannelSession{ + card: card, + secret: secret, + publicKey: gen.Marshal(public), + }, nil +} + +// Pair establishes a new pairing with the smartcard. +func (s *SecureChannelSession) Pair(pairingPassword []byte) error { + secretHash := pbkdf2.Key(norm.NFKD.Bytes(pairingPassword), norm.NFKD.Bytes([]byte(pairingSalt)), 50000, 32, sha256.New) + + challenge := make([]byte, 32) + if _, err := rand.Read(challenge); err != nil { + return err + } + + response, err := s.pair(pairP1FirstStep, challenge) + if err != nil { + return err + } + + md := sha256.New() + md.Write(secretHash[:]) + md.Write(challenge) + + expectedCryptogram := md.Sum(nil) + cardCryptogram := response.Data[:32] + cardChallenge := response.Data[32:64] + + if !bytes.Equal(expectedCryptogram, cardCryptogram) { + return fmt.Errorf("Invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram) + } + + md.Reset() + md.Write(secretHash[:]) + md.Write(cardChallenge) + response, err = s.pair(pairP1LastStep, md.Sum(nil)) + if err != nil { + return err + } + + md.Reset() + md.Write(secretHash[:]) + md.Write(response.Data[1:]) + s.PairingKey = md.Sum(nil) + s.PairingIndex = response.Data[0] + + return nil +} + +// Unpair disestablishes an existing pairing. +func (s *SecureChannelSession) Unpair() error { + if s.PairingKey == nil { + return fmt.Errorf("Cannot unpair: not paired") + } + + _, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{}) + if err != nil { + return err + } + s.PairingKey = nil + // Close channel + s.iv = nil + return nil +} + +// Open initializes the secure channel. +func (s *SecureChannelSession) Open() error { + if s.iv != nil { + return fmt.Errorf("Session already opened") + } + + response, err := s.open() + if err != nil { + return err + } + + // Generate the encryption/mac key by hashing our shared secret, + // pairing key, and the first bytes returned from the Open APDU. + md := sha512.New() + md.Write(s.secret) + md.Write(s.PairingKey) + md.Write(response.Data[:scSecretLength]) + keyData := md.Sum(nil) + s.sessionEncKey = keyData[:scSecretLength] + s.sessionMacKey = keyData[scSecretLength : scSecretLength*2] + + // The IV is the last bytes returned from the Open APDU. + s.iv = response.Data[scSecretLength:] + + return s.mutuallyAuthenticate() +} + +// mutuallyAuthenticate is an internal method to authenticate both ends of the +// connection. +func (s *SecureChannelSession) mutuallyAuthenticate() error { + data := make([]byte, scSecretLength) + if _, err := rand.Read(data); err != nil { + return err + } + + response, err := s.transmitEncrypted(claSCWallet, insMutuallyAuthenticate, 0, 0, data) + if err != nil { + return err + } + if response.Sw1 != 0x90 || response.Sw2 != 0x00 { + return fmt.Errorf("Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2) + } + + if len(response.Data) != scSecretLength { + return fmt.Errorf("Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength) + } + + return nil +} + +// open is an internal method that sends an open APDU. +func (s *SecureChannelSession) open() (*responseAPDU, error) { + return transmit(s.card, &commandAPDU{ + Cla: claSCWallet, + Ins: insOpenSecureChannel, + P1: s.PairingIndex, + P2: 0, + Data: s.publicKey, + Le: 0, + }) +} + +// pair is an internal method that sends a pair APDU. +func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error) { + return transmit(s.card, &commandAPDU{ + Cla: claSCWallet, + Ins: insPair, + P1: p1, + P2: 0, + Data: data, + Le: 0, + }) +} + +// transmitEncrypted sends an encrypted message, and decrypts and returns the response. +func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) { + if s.iv == nil { + return nil, fmt.Errorf("Channel not open") + } + + data, err := s.encryptAPDU(data) + if err != nil { + return nil, err + } + meta := [16]byte{cla, ins, p1, p2, byte(len(data) + scBlockSize)} + if err = s.updateIV(meta[:], data); err != nil { + return nil, err + } + + fulldata := make([]byte, len(s.iv)+len(data)) + copy(fulldata, s.iv) + copy(fulldata[len(s.iv):], data) + + response, err := transmit(s.card, &commandAPDU{ + Cla: cla, + Ins: ins, + P1: p1, + P2: p2, + Data: fulldata, + }) + if err != nil { + return nil, err + } + + rmeta := [16]byte{byte(len(response.Data))} + rmac := response.Data[:len(s.iv)] + rdata := response.Data[len(s.iv):] + plainData, err := s.decryptAPDU(rdata) + if err != nil { + return nil, err + } + + if err = s.updateIV(rmeta[:], rdata); err != nil { + return nil, err + } + if !bytes.Equal(s.iv, rmac) { + return nil, fmt.Errorf("Invalid MAC in response") + } + + rapdu := &responseAPDU{} + rapdu.deserialize(plainData) + + if rapdu.Sw1 != sw1Ok { + return nil, fmt.Errorf("Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) + } + + return rapdu, nil +} + +// encryptAPDU is an internal method that serializes and encrypts an APDU. +func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) { + if len(data) > maxPayloadSize { + return nil, fmt.Errorf("Payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize) + } + data = pad(data, 0x80) + + ret := make([]byte, len(data)) + + a, err := aes.NewCipher(s.sessionEncKey) + if err != nil { + return nil, err + } + crypter := cipher.NewCBCEncrypter(a, s.iv) + crypter.CryptBlocks(ret, data) + return ret, nil +} + +// pad applies message padding to a 16 byte boundary. +func pad(data []byte, terminator byte) []byte { + padded := make([]byte, (len(data)/16+1)*16) + copy(padded, data) + padded[len(data)] = terminator + return padded +} + +// decryptAPDU is an internal method that decrypts and deserializes an APDU. +func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) { + a, err := aes.NewCipher(s.sessionEncKey) + if err != nil { + return nil, err + } + + ret := make([]byte, len(data)) + + crypter := cipher.NewCBCDecrypter(a, s.iv) + crypter.CryptBlocks(ret, data) + return unpad(ret, 0x80) +} + +// unpad strips padding from a message. +func unpad(data []byte, terminator byte) ([]byte, error) { + for i := 1; i <= 16; i++ { + switch data[len(data)-i] { + case 0: + continue + case terminator: + return data[:len(data)-i], nil + default: + return nil, fmt.Errorf("Expected end of padding, got %d", data[len(data)-i]) + } + } + return nil, fmt.Errorf("Expected end of padding, got 0") +} + +// updateIV is an internal method that updates the initialization vector after +// each message exchanged. +func (s *SecureChannelSession) updateIV(meta, data []byte) error { + data = pad(data, 0) + a, err := aes.NewCipher(s.sessionMacKey) + if err != nil { + return err + } + crypter := cipher.NewCBCEncrypter(a, make([]byte, 16)) + crypter.CryptBlocks(meta, meta) + crypter.CryptBlocks(data, data) + // The first 16 bytes of the last block is the MAC + s.iv = data[len(data)-32 : len(data)-16] + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/wallet.go b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/wallet.go new file mode 100644 index 00000000..57b59770 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/scwallet/wallet.go @@ -0,0 +1,1082 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package scwallet + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "encoding/asn1" + "encoding/binary" + "errors" + "fmt" + "math/big" + "regexp" + "sort" + "strings" + "sync" + "time" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + pcsc "github.com/gballet/go-libpcsclite" + "github.com/status-im/keycard-go/derivationpath" +) + +// ErrPairingPasswordNeeded is returned if opening the smart card requires pairing with a pairing +// password. In this case, the calling application should request user input to enter +// the pairing password and send it back. +var ErrPairingPasswordNeeded = errors.New("smartcard: pairing password needed") + +// ErrPINNeeded is returned if opening the smart card requires a PIN code. In +// this case, the calling application should request user input to enter the PIN +// and send it back. +var ErrPINNeeded = errors.New("smartcard: pin needed") + +// ErrPINUnblockNeeded is returned if opening the smart card requires a PIN code, +// but all PIN attempts have already been exhausted. In this case the calling +// application should request user input for the PUK and a new PIN code to set +// fo the card. +var ErrPINUnblockNeeded = errors.New("smartcard: pin unblock needed") + +// ErrAlreadyOpen is returned if the smart card is attempted to be opened, but +// there is already a paired and unlocked session. +var ErrAlreadyOpen = errors.New("smartcard: already open") + +// ErrPubkeyMismatch is returned if the public key recovered from a signature +// does not match the one expected by the user. +var ErrPubkeyMismatch = errors.New("smartcard: recovered public key mismatch") + +var ( + appletAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01, 0x01} + // DerivationSignatureHash is used to derive the public key from the signature of this hash + DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes()) +) + +// List of APDU command-related constants +const ( + claISO7816 = 0 + claSCWallet = 0x80 + + insSelect = 0xA4 + insGetResponse = 0xC0 + sw1GetResponse = 0x61 + sw1Ok = 0x90 + + insVerifyPin = 0x20 + insUnblockPin = 0x22 + insExportKey = 0xC2 + insSign = 0xC0 + insLoadKey = 0xD0 + insDeriveKey = 0xD1 + insStatus = 0xF2 +) + +// List of ADPU command parameters +const ( + P1DeriveKeyFromMaster = uint8(0x00) + P1DeriveKeyFromParent = uint8(0x01) + P1DeriveKeyFromCurrent = uint8(0x10) + statusP1WalletStatus = uint8(0x00) + statusP1Path = uint8(0x01) + signP1PrecomputedHash = uint8(0x01) + signP2OnlyBlock = uint8(0x81) + exportP1Any = uint8(0x00) + exportP2Pubkey = uint8(0x01) +) + +// Minimum time to wait between self derivation attempts, even it the user is +// requesting accounts like crazy. +const selfDeriveThrottling = time.Second + +// Wallet represents a smartcard wallet instance. +type Wallet struct { + Hub *Hub // A handle to the Hub that instantiated this wallet. + PublicKey []byte // The wallet's public key (used for communication and identification, not signing!) + + lock sync.Mutex // Lock that gates access to struct fields and communication with the card + card *pcsc.Card // A handle to the smartcard interface for the wallet. + session *Session // The secure communication session with the card + log log.Logger // Contextual logger to tag the base with its id + + deriveNextPaths []accounts.DerivationPath // Next derivation paths for account auto-discovery (multiple bases supported) + deriveNextAddrs []common.Address // Next derived account addresses for auto-discovery (multiple bases supported) + deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with + deriveReq chan chan struct{} // Channel to request a self-derivation on + deriveQuit chan chan error // Channel to terminate the self-deriver with +} + +// NewWallet constructs and returns a new Wallet instance. +func NewWallet(hub *Hub, card *pcsc.Card) *Wallet { + wallet := &Wallet{ + Hub: hub, + card: card, + } + return wallet +} + +// transmit sends an APDU to the smartcard and receives and decodes the response. +// It automatically handles requests by the card to fetch the return data separately, +// and returns an error if the response status code is not success. +func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) { + data, err := command.serialize() + if err != nil { + return nil, err + } + + responseData, _, err := card.Transmit(data) + if err != nil { + return nil, err + } + + response := new(responseAPDU) + if err = response.deserialize(responseData); err != nil { + return nil, err + } + + // Are we being asked to fetch the response separately? + if response.Sw1 == sw1GetResponse && (command.Cla != claISO7816 || command.Ins != insGetResponse) { + return transmit(card, &commandAPDU{ + Cla: claISO7816, + Ins: insGetResponse, + P1: 0, + P2: 0, + Data: nil, + Le: response.Sw2, + }) + } + + if response.Sw1 != sw1Ok { + return nil, fmt.Errorf("Unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) + } + + return response, nil +} + +// applicationInfo encodes information about the smartcard application - its +// instance UID and public key. +type applicationInfo struct { + InstanceUID []byte `asn1:"tag:15"` + PublicKey []byte `asn1:"tag:0"` +} + +// connect connects to the wallet application and establishes a secure channel with it. +// must be called before any other interaction with the wallet. +func (w *Wallet) connect() error { + w.lock.Lock() + defer w.lock.Unlock() + + appinfo, err := w.doselect() + if err != nil { + return err + } + + channel, err := NewSecureChannelSession(w.card, appinfo.PublicKey) + if err != nil { + return err + } + + w.PublicKey = appinfo.PublicKey + w.log = log.New("url", w.URL()) + w.session = &Session{ + Wallet: w, + Channel: channel, + } + return nil +} + +// doselect is an internal (unlocked) function to send a SELECT APDU to the card. +func (w *Wallet) doselect() (*applicationInfo, error) { + response, err := transmit(w.card, &commandAPDU{ + Cla: claISO7816, + Ins: insSelect, + P1: 4, + P2: 0, + Data: appletAID, + }) + if err != nil { + return nil, err + } + + appinfo := new(applicationInfo) + if _, err := asn1.UnmarshalWithParams(response.Data, appinfo, "tag:4"); err != nil { + return nil, err + } + return appinfo, nil +} + +// ping checks the card's status and returns an error if unsuccessful. +func (w *Wallet) ping() error { + w.lock.Lock() + defer w.lock.Unlock() + + // We can't ping if not paired + if !w.session.paired() { + return nil + } + if _, err := w.session.walletStatus(); err != nil { + return err + } + return nil +} + +// release releases any resources held by an open wallet instance. +func (w *Wallet) release() error { + if w.session != nil { + return w.session.release() + } + return nil +} + +// pair is an internal (unlocked) function for establishing a new pairing +// with the wallet. +func (w *Wallet) pair(puk []byte) error { + if w.session.paired() { + return fmt.Errorf("Wallet already paired") + } + pairing, err := w.session.pair(puk) + if err != nil { + return err + } + if err = w.Hub.setPairing(w, &pairing); err != nil { + return err + } + return w.session.authenticate(pairing) +} + +// Unpair deletes an existing wallet pairing. +func (w *Wallet) Unpair(pin []byte) error { + w.lock.Lock() + defer w.lock.Unlock() + + if !w.session.paired() { + return fmt.Errorf("wallet %x not paired", w.PublicKey) + } + if err := w.session.verifyPin(pin); err != nil { + return fmt.Errorf("failed to verify pin: %s", err) + } + if err := w.session.unpair(); err != nil { + return fmt.Errorf("failed to unpair: %s", err) + } + if err := w.Hub.setPairing(w, nil); err != nil { + return err + } + return nil +} + +// URL retrieves the canonical path under which this wallet is reachable. It is +// user by upper layers to define a sorting order over all wallets from multiple +// backends. +func (w *Wallet) URL() accounts.URL { + return accounts.URL{ + Scheme: w.Hub.scheme, + Path: fmt.Sprintf("%x", w.PublicKey[1:5]), // Byte #0 isn't unique; 1:5 covers << 64K cards, bump to 1:9 for << 4M + } +} + +// Status returns a textual status to aid the user in the current state of the +// wallet. It also returns an error indicating any failure the wallet might have +// encountered. +func (w *Wallet) Status() (string, error) { + w.lock.Lock() + defer w.lock.Unlock() + + // If the card is not paired, we can only wait + if !w.session.paired() { + return "Unpaired, waiting for pairing password", nil + } + // Yay, we have an encrypted session, retrieve the actual status + status, err := w.session.walletStatus() + if err != nil { + return fmt.Sprintf("Failed: %v", err), err + } + switch { + case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0: + return fmt.Sprintf("Bricked, waiting for full wipe"), nil + case !w.session.verified && status.PinRetryCount == 0: + return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil + case !w.session.verified: + return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil + case !status.Initialized: + return fmt.Sprintf("Empty, waiting for initialization"), nil + default: + return fmt.Sprintf("Online"), nil + } +} + +// Open initializes access to a wallet instance. It is not meant to unlock or +// decrypt account keys, rather simply to establish a connection to hardware +// wallets and/or to access derivation seeds. +// +// The passphrase parameter may or may not be used by the implementation of a +// particular wallet instance. The reason there is no passwordless open method +// is to strive towards a uniform wallet handling, oblivious to the different +// backend providers. +// +// Please note, if you open a wallet, you must close it to release any allocated +// resources (especially important when working with hardware wallets). +func (w *Wallet) Open(passphrase string) error { + w.lock.Lock() + defer w.lock.Unlock() + + // If the session is already open, bail out + if w.session.verified { + return ErrAlreadyOpen + } + // If the smart card is not yet paired, attempt to do so either from a previous + // pairing key or form the supplied PUK code. + if !w.session.paired() { + // If a previous pairing exists, only ever try to use that + if pairing := w.Hub.pairing(w); pairing != nil { + if err := w.session.authenticate(*pairing); err != nil { + return fmt.Errorf("failed to authenticate card %x: %s", w.PublicKey[:4], err) + } + // Pairing still ok, fall through to PIN checks + } else { + // If no passphrase was supplied, request the PUK from the user + if passphrase == "" { + return ErrPairingPasswordNeeded + } + // Attempt to pair the smart card with the user supplied PUK + if err := w.pair([]byte(passphrase)); err != nil { + return err + } + // Pairing succeeded, fall through to PIN checks. This will of course fail, + // but we can't return ErrPINNeeded directly here becase we don't know whether + // a PIN check or a PIN reset is needed. + passphrase = "" + } + } + // The smart card was successfully paired, retrieve its status to check whether + // PIN verification or unblocking is needed. + status, err := w.session.walletStatus() + if err != nil { + return err + } + // Request the appropriate next authentication data, or use the one supplied + switch { + case passphrase == "" && status.PinRetryCount > 0: + return ErrPINNeeded + case passphrase == "": + return ErrPINUnblockNeeded + case status.PinRetryCount > 0: + if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) { + w.log.Error("PIN needs to be at least 6 digits") + return ErrPINNeeded + } + if err := w.session.verifyPin([]byte(passphrase)); err != nil { + return err + } + default: + if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) { + w.log.Error("PUK needs to be at least 12 digits") + return ErrPINUnblockNeeded + } + if err := w.session.unblockPin([]byte(passphrase)); err != nil { + return err + } + } + // Smart card paired and unlocked, initialize and register + w.deriveReq = make(chan chan struct{}) + w.deriveQuit = make(chan chan error) + + go w.selfDerive() + + // Notify anyone listening for wallet events that a new device is accessible + go w.Hub.updateFeed.Send(accounts.WalletEvent{Wallet: w, Kind: accounts.WalletOpened}) + + return nil +} + +// Close stops and closes the wallet, freeing any resources. +func (w *Wallet) Close() error { + // Ensure the wallet was opened + w.lock.Lock() + dQuit := w.deriveQuit + w.lock.Unlock() + + // Terminate the self-derivations + var derr error + if dQuit != nil { + errc := make(chan error) + dQuit <- errc + derr = <-errc // Save for later, we *must* close the USB + } + // Terminate the device connection + w.lock.Lock() + defer w.lock.Unlock() + + w.deriveQuit = nil + w.deriveReq = nil + + if err := w.release(); err != nil { + return err + } + return derr +} + +// selfDerive is an account derivation loop that upon request attempts to find +// new non-zero accounts. +func (w *Wallet) selfDerive() { + w.log.Debug("Smart card wallet self-derivation started") + defer w.log.Debug("Smart card wallet self-derivation stopped") + + // Execute self-derivations until termination or error + var ( + reqc chan struct{} + errc chan error + err error + ) + for errc == nil && err == nil { + // Wait until either derivation or termination is requested + select { + case errc = <-w.deriveQuit: + // Termination requested + continue + case reqc = <-w.deriveReq: + // Account discovery requested + } + // Derivation needs a chain and device access, skip if either unavailable + w.lock.Lock() + if w.session == nil || w.deriveChain == nil { + w.lock.Unlock() + reqc <- struct{}{} + continue + } + pairing := w.Hub.pairing(w) + + // Device lock obtained, derive the next batch of accounts + var ( + paths []accounts.DerivationPath + nextAcc accounts.Account + + nextPaths = append([]accounts.DerivationPath{}, w.deriveNextPaths...) + nextAddrs = append([]common.Address{}, w.deriveNextAddrs...) + + context = context.Background() + ) + for i := 0; i < len(nextAddrs); i++ { + for empty := false; !empty; { + // Retrieve the next derived Ethereum account + if nextAddrs[i] == (common.Address{}) { + if nextAcc, err = w.session.derive(nextPaths[i]); err != nil { + w.log.Warn("Smartcard wallet account derivation failed", "err", err) + break + } + nextAddrs[i] = nextAcc.Address + } + // Check the account's status against the current chain state + var ( + balance *big.Int + nonce uint64 + ) + balance, err = w.deriveChain.BalanceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("Smartcard wallet balance retrieval failed", "err", err) + break + } + nonce, err = w.deriveChain.NonceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("Smartcard wallet nonce retrieval failed", "err", err) + break + } + // If the next account is empty, stop self-derivation, but add for the last base path + if balance.Sign() == 0 && nonce == 0 { + empty = true + if i < len(nextAddrs)-1 { + break + } + } + // We've just self-derived a new account, start tracking it locally + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) + paths = append(paths, path) + + // Display a log message to the user for new (or previously empty accounts) + if _, known := pairing.Accounts[nextAddrs[i]]; !known || !empty || nextAddrs[i] != w.deriveNextAddrs[i] { + w.log.Info("Smartcard wallet discovered new account", "address", nextAddrs[i], "path", path, "balance", balance, "nonce", nonce) + } + pairing.Accounts[nextAddrs[i]] = path + + // Fetch the next potential account + if !empty { + nextAddrs[i] = common.Address{} + nextPaths[i][len(nextPaths[i])-1]++ + } + } + } + // If there are new accounts, write them out + if len(paths) > 0 { + err = w.Hub.setPairing(w, pairing) + } + // Shift the self-derivation forward + w.deriveNextAddrs = nextAddrs + w.deriveNextPaths = nextPaths + + // Self derivation complete, release device lock + w.lock.Unlock() + + // Notify the user of termination and loop after a bit of time (to avoid trashing) + reqc <- struct{}{} + if err == nil { + select { + case errc = <-w.deriveQuit: + // Termination requested, abort + case <-time.After(selfDeriveThrottling): + // Waited enough, willing to self-derive again + } + } + } + // In case of error, wait for termination + if err != nil { + w.log.Debug("Smartcard wallet self-derivation failed", "err", err) + errc = <-w.deriveQuit + } + errc <- err +} + +// Accounts retrieves the list of signing accounts the wallet is currently aware +// of. For hierarchical deterministic wallets, the list will not be exhaustive, +// rather only contain the accounts explicitly pinned during account derivation. +func (w *Wallet) Accounts() []accounts.Account { + // Attempt self-derivation if it's running + reqc := make(chan struct{}, 1) + select { + case w.deriveReq <- reqc: + // Self-derivation request accepted, wait for it + <-reqc + default: + // Self-derivation offline, throttled or busy, skip + } + + w.lock.Lock() + defer w.lock.Unlock() + + if pairing := w.Hub.pairing(w); pairing != nil { + ret := make([]accounts.Account, 0, len(pairing.Accounts)) + for address, path := range pairing.Accounts { + ret = append(ret, w.makeAccount(address, path)) + } + sort.Sort(accounts.AccountsByURL(ret)) + return ret + } + return nil +} + +func (w *Wallet) makeAccount(address common.Address, path accounts.DerivationPath) accounts.Account { + return accounts.Account{ + Address: address, + URL: accounts.URL{ + Scheme: w.Hub.scheme, + Path: fmt.Sprintf("%x/%s", w.PublicKey[1:3], path.String()), + }, + } +} + +// Contains returns whether an account is part of this particular wallet or not. +func (w *Wallet) Contains(account accounts.Account) bool { + if pairing := w.Hub.pairing(w); pairing != nil { + _, ok := pairing.Accounts[account.Address] + return ok + } + return false +} + +// Initialize installs a keypair generated from the provided key into the wallet. +func (w *Wallet) Initialize(seed []byte) error { + go w.selfDerive() + // DO NOT lock at this stage, as the initialize + // function relies on Status() + return w.session.initialize(seed) +} + +// Derive attempts to explicitly derive a hierarchical deterministic account at +// the specified derivation path. If requested, the derived account will be added +// to the wallet's tracked account list. +func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + w.lock.Lock() + defer w.lock.Unlock() + + account, err := w.session.derive(path) + if err != nil { + return accounts.Account{}, err + } + + if pin { + pairing := w.Hub.pairing(w) + pairing.Accounts[account.Address] = path + if err := w.Hub.setPairing(w, pairing); err != nil { + return accounts.Account{}, err + } + } + + return account, nil +} + +// SelfDerive sets a base account derivation path from which the wallet attempts +// to discover non zero accounts and automatically add them to list of tracked +// accounts. +// +// Note, self derivaton will increment the last component of the specified path +// opposed to decending into a child path to allow discovering accounts starting +// from non zero components. +// +// Some hardware wallets switched derivation paths through their evolution, so +// this method supports providing multiple bases to discover old user accounts +// too. Only the last base will be used to derive the next empty account. +// +// You can disable automatic account discovery by calling SelfDerive with a nil +// chain state reader. +func (w *Wallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { + w.lock.Lock() + defer w.lock.Unlock() + + w.deriveNextPaths = make([]accounts.DerivationPath, len(bases)) + for i, base := range bases { + w.deriveNextPaths[i] = make(accounts.DerivationPath, len(base)) + copy(w.deriveNextPaths[i][:], base[:]) + } + w.deriveNextAddrs = make([]common.Address, len(bases)) + w.deriveChain = chain +} + +// SignData requests the wallet to sign the hash of the given data. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignDataWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.signHash(account, crypto.Keccak256(data)) +} + +func (w *Wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { + w.lock.Lock() + defer w.lock.Unlock() + + path, err := w.findAccountPath(account) + if err != nil { + return nil, err + } + + return w.session.sign(path, hash) +} + +// SignTx requests the wallet to sign the given transaction. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignTxWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + signer := types.NewEIP155Signer(chainID) + hash := signer.Hash(tx) + sig, err := w.signHash(account, hash[:]) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, sig) +} + +// SignDataWithPassphrase requests the wallet to sign the given hash with the +// given passphrase as extra authentication information. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +func (w *Wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) +} + +func (w *Wallet) signHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { + if !w.session.verified { + if err := w.Open(passphrase); err != nil { + return nil, err + } + } + + return w.signHash(account, hash) +} + +// SignText requests the wallet to sign the hash of a given piece of data, prefixed +// by the Ethereum prefix scheme +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.signHash(account, accounts.TextHash(text)) +} + +// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the +// given hash with the given account using passphrase as extra authentication +func (w *Wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(accounts.TextHash(text))) +} + +// SignTxWithPassphrase requests the wallet to sign the given transaction, with the +// given passphrase as extra authentication information. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +func (w *Wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + if !w.session.verified { + if err := w.Open(passphrase); err != nil { + return nil, err + } + } + return w.SignTx(account, tx, chainID) +} + +// findAccountPath returns the derivation path for the provided account. +// It first checks for the address in the list of pinned accounts, and if it is +// not found, attempts to parse the derivation path from the account's URL. +func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) { + pairing := w.Hub.pairing(w) + if path, ok := pairing.Accounts[account.Address]; ok { + return path, nil + } + + // Look for the path in the URL + if account.URL.Scheme != w.Hub.scheme { + return nil, fmt.Errorf("Scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) + } + + parts := strings.SplitN(account.URL.Path, "/", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("Invalid URL format: %s", account.URL) + } + + if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) { + return nil, fmt.Errorf("URL %s is not for this wallet", account.URL) + } + + return accounts.ParseDerivationPath(parts[1]) +} + +// Session represents a secured communication session with the wallet. +type Session struct { + Wallet *Wallet // A handle to the wallet that opened the session + Channel *SecureChannelSession // A secure channel for encrypted messages + verified bool // Whether the pin has been verified in this session. +} + +// pair establishes a new pairing over this channel, using the provided secret. +func (s *Session) pair(secret []byte) (smartcardPairing, error) { + err := s.Channel.Pair(secret) + if err != nil { + return smartcardPairing{}, err + } + + return smartcardPairing{ + PublicKey: s.Wallet.PublicKey, + PairingIndex: s.Channel.PairingIndex, + PairingKey: s.Channel.PairingKey, + Accounts: make(map[common.Address]accounts.DerivationPath), + }, nil +} + +// unpair deletes an existing pairing. +func (s *Session) unpair() error { + if !s.verified { + return fmt.Errorf("Unpair requires that the PIN be verified") + } + return s.Channel.Unpair() +} + +// verifyPin unlocks a wallet with the provided pin. +func (s *Session) verifyPin(pin []byte) error { + if _, err := s.Channel.transmitEncrypted(claSCWallet, insVerifyPin, 0, 0, pin); err != nil { + return err + } + s.verified = true + return nil +} + +// unblockPin unblocks a wallet with the provided puk and resets the pin to the +// new one specified. +func (s *Session) unblockPin(pukpin []byte) error { + if _, err := s.Channel.transmitEncrypted(claSCWallet, insUnblockPin, 0, 0, pukpin); err != nil { + return err + } + s.verified = true + return nil +} + +// release releases resources associated with the channel. +func (s *Session) release() error { + return s.Wallet.card.Disconnect(pcsc.LeaveCard) +} + +// paired returns true if a valid pairing exists. +func (s *Session) paired() bool { + return s.Channel.PairingKey != nil +} + +// authenticate uses an existing pairing to establish a secure channel. +func (s *Session) authenticate(pairing smartcardPairing) error { + if !bytes.Equal(s.Wallet.PublicKey, pairing.PublicKey) { + return fmt.Errorf("Cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey) + } + s.Channel.PairingKey = pairing.PairingKey + s.Channel.PairingIndex = pairing.PairingIndex + return s.Channel.Open() +} + +// walletStatus describes a smartcard wallet's status information. +type walletStatus struct { + PinRetryCount int // Number of remaining PIN retries + PukRetryCount int // Number of remaining PUK retries + Initialized bool // Whether the card has been initialized with a private key +} + +// walletStatus fetches the wallet's status from the card. +func (s *Session) walletStatus() (*walletStatus, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1WalletStatus, 0, nil) + if err != nil { + return nil, err + } + + status := new(walletStatus) + if _, err := asn1.UnmarshalWithParams(response.Data, status, "tag:3"); err != nil { + return nil, err + } + return status, nil +} + +// derivationPath fetches the wallet's current derivation path from the card. +func (s *Session) derivationPath() (accounts.DerivationPath, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) + if err != nil { + return nil, err + } + buf := bytes.NewReader(response.Data) + path := make(accounts.DerivationPath, len(response.Data)/4) + return path, binary.Read(buf, binary.BigEndian, &path) +} + +// initializeData contains data needed to initialize the smartcard wallet. +type initializeData struct { + PublicKey []byte `asn1:"tag:0"` + PrivateKey []byte `asn1:"tag:1"` + ChainCode []byte `asn1:"tag:2"` +} + +// initialize initializes the card with new key data. +func (s *Session) initialize(seed []byte) error { + // Check that the wallet isn't currently initialized, + // otherwise the key would be overwritten. + status, err := s.Wallet.Status() + if err != nil { + return err + } + if status == "Online" { + return fmt.Errorf("card is already initialized, cowardly refusing to proceed") + } + + s.Wallet.lock.Lock() + defer s.Wallet.lock.Unlock() + + // HMAC the seed to produce the private key and chain code + mac := hmac.New(sha512.New, []byte("Bitcoin seed")) + mac.Write(seed) + seed = mac.Sum(nil) + + key, err := crypto.ToECDSA(seed[:32]) + if err != nil { + return err + } + + id := initializeData{} + id.PublicKey = crypto.FromECDSAPub(&key.PublicKey) + id.PrivateKey = seed[:32] + id.ChainCode = seed[32:] + data, err := asn1.Marshal(id) + if err != nil { + return err + } + + // Nasty hack to force the top-level struct tag to be context-specific + data[0] = 0xA1 + + _, err = s.Channel.transmitEncrypted(claSCWallet, insLoadKey, 0x02, 0, data) + return err +} + +// derive derives a new HD key path on the card. +func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) { + startingPoint, path, err := derivationpath.Decode(path.String()) + if err != nil { + return accounts.Account{}, err + } + + var p1 uint8 + switch startingPoint { + case derivationpath.StartingPointMaster: + p1 = P1DeriveKeyFromMaster + case derivationpath.StartingPointParent: + p1 = P1DeriveKeyFromParent + case derivationpath.StartingPointCurrent: + p1 = P1DeriveKeyFromCurrent + default: + return accounts.Account{}, fmt.Errorf("invalid startingPoint %d", startingPoint) + } + + data := new(bytes.Buffer) + for _, segment := range path { + if err := binary.Write(data, binary.BigEndian, segment); err != nil { + return accounts.Account{}, err + } + } + + _, err = s.Channel.transmitEncrypted(claSCWallet, insDeriveKey, p1, 0, data.Bytes()) + if err != nil { + return accounts.Account{}, err + } + + response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, 0, 0, DerivationSignatureHash[:]) + if err != nil { + return accounts.Account{}, err + } + + sigdata := new(signatureData) + if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { + return accounts.Account{}, err + } + rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() + sig := make([]byte, 65) + copy(sig[32-len(rbytes):32], rbytes) + copy(sig[64-len(sbytes):64], sbytes) + + if err := confirmPublicKey(sig, sigdata.PublicKey); err != nil { + return accounts.Account{}, err + } + pub, err := crypto.UnmarshalPubkey(sigdata.PublicKey) + if err != nil { + return accounts.Account{}, err + } + return s.Wallet.makeAccount(crypto.PubkeyToAddress(*pub), path), nil +} + +// keyExport contains information on an exported keypair. +type keyExport struct { + PublicKey []byte `asn1:"tag:0"` + PrivateKey []byte `asn1:"tag:1,optional"` +} + +// publicKey returns the public key for the current derivation path. +func (s *Session) publicKey() ([]byte, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) + if err != nil { + return nil, err + } + keys := new(keyExport) + if _, err := asn1.UnmarshalWithParams(response.Data, keys, "tag:1"); err != nil { + return nil, err + } + return keys.PublicKey, nil +} + +// signatureData contains information on a signature - the signature itself and +// the corresponding public key. +type signatureData struct { + PublicKey []byte `asn1:"tag:0"` + Signature struct { + R *big.Int + S *big.Int + } +} + +// sign asks the card to sign a message, and returns a valid signature after +// recovering the v value. +func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error) { + startTime := time.Now() + _, err := s.derive(path) + if err != nil { + return nil, err + } + deriveTime := time.Now() + + response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, signP1PrecomputedHash, signP2OnlyBlock, hash) + if err != nil { + return nil, err + } + sigdata := new(signatureData) + if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { + return nil, err + } + // Serialize the signature + rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() + sig := make([]byte, 65) + copy(sig[32-len(rbytes):32], rbytes) + copy(sig[64-len(sbytes):64], sbytes) + + // Recover the V value. + sig, err = makeRecoverableSignature(hash, sig, sigdata.PublicKey) + if err != nil { + return nil, err + } + log.Debug("Signed using smartcard", "deriveTime", deriveTime.Sub(startTime), "signingTime", time.Since(deriveTime)) + + return sig, nil +} + +// confirmPublicKey confirms that the given signature belongs to the specified key. +func confirmPublicKey(sig, pubkey []byte) error { + _, err := makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkey) + return err +} + +// makeRecoverableSignature uses a signature and an expected public key to +// recover the v value and produce a recoverable signature. +func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) { + var libraryError error + for v := 0; v < 2; v++ { + sig[64] = byte(v) + if pubkey, err := crypto.Ecrecover(hash, sig); err == nil { + if bytes.Equal(pubkey, expectedPubkey) { + return sig, nil + } + } else { + libraryError = err + } + } + if libraryError != nil { + return nil, libraryError + } + return nil, ErrPubkeyMismatch +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/sort.go b/vendor/github.com/ethereum/go-ethereum/accounts/sort.go new file mode 100644 index 00000000..f4676211 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/sort.go @@ -0,0 +1,31 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package accounts + +// AccountsByURL implements sort.Interface for []Account based on the URL field. +type AccountsByURL []Account + +func (a AccountsByURL) Len() int { return len(a) } +func (a AccountsByURL) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a AccountsByURL) Less(i, j int) bool { return a[i].URL.Cmp(a[j].URL) < 0 } + +// WalletsByURL implements sort.Interface for []Wallet based on the URL field. +type WalletsByURL []Wallet + +func (w WalletsByURL) Len() int { return len(w) } +func (w WalletsByURL) Swap(i, j int) { w[i], w[j] = w[j], w[i] } +func (w WalletsByURL) Less(i, j int) bool { return w[i].URL().Cmp(w[j].URL()) < 0 } diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/hub.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/hub.go new file mode 100644 index 00000000..23be98a0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/hub.go @@ -0,0 +1,279 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package usbwallet + +import ( + "errors" + "runtime" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/karalabe/usb" +) + +// LedgerScheme is the protocol scheme prefixing account and wallet URLs. +const LedgerScheme = "ledger" + +// TrezorScheme is the protocol scheme prefixing account and wallet URLs. +const TrezorScheme = "trezor" + +// refreshCycle is the maximum time between wallet refreshes (if USB hotplug +// notifications don't work). +const refreshCycle = time.Second + +// refreshThrottling is the minimum time between wallet refreshes to avoid USB +// trashing. +const refreshThrottling = 500 * time.Millisecond + +// Hub is a accounts.Backend that can find and handle generic USB hardware wallets. +type Hub struct { + scheme string // Protocol scheme prefixing account and wallet URLs. + vendorID uint16 // USB vendor identifier used for device discovery + productIDs []uint16 // USB product identifiers used for device discovery + usageID uint16 // USB usage page identifier used for macOS device discovery + endpointID int // USB endpoint identifier used for non-macOS device discovery + makeDriver func(log.Logger) driver // Factory method to construct a vendor specific driver + + refreshed time.Time // Time instance when the list of wallets was last refreshed + wallets []accounts.Wallet // List of USB wallet devices currently tracking + updateFeed event.Feed // Event feed to notify wallet additions/removals + updateScope event.SubscriptionScope // Subscription scope tracking current live listeners + updating bool // Whether the event notification loop is running + + quit chan chan error + + stateLock sync.RWMutex // Protects the internals of the hub from racey access + + // TODO(karalabe): remove if hotplug lands on Windows + commsPend int // Number of operations blocking enumeration + commsLock sync.Mutex // Lock protecting the pending counter and enumeration + enumFails uint32 // Number of times enumeration has failed +} + +// NewLedgerHub creates a new hardware wallet manager for Ledger devices. +func NewLedgerHub() (*Hub, error) { + return newHub(LedgerScheme, 0x2c97, []uint16{ + // Original product IDs + 0x0000, /* Ledger Blue */ + 0x0001, /* Ledger Nano S */ + 0x0004, /* Ledger Nano X */ + + // Upcoming product IDs: https://www.ledger.com/2019/05/17/windows-10-update-sunsetting-u2f-tunnel-transport-for-ledger-devices/ + 0x0015, /* HID + U2F + WebUSB Ledger Blue */ + 0x1015, /* HID + U2F + WebUSB Ledger Nano S */ + 0x4015, /* HID + U2F + WebUSB Ledger Nano X */ + 0x0011, /* HID + WebUSB Ledger Blue */ + 0x1011, /* HID + WebUSB Ledger Nano S */ + 0x4011, /* HID + WebUSB Ledger Nano X */ + }, 0xffa0, 0, newLedgerDriver) +} + +// NewTrezorHubWithHID creates a new hardware wallet manager for Trezor devices. +func NewTrezorHubWithHID() (*Hub, error) { + return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor HID */}, 0xff00, 0, newTrezorDriver) +} + +// NewTrezorHubWithWebUSB creates a new hardware wallet manager for Trezor devices with +// firmware version > 1.8.0 +func NewTrezorHubWithWebUSB() (*Hub, error) { + return newHub(TrezorScheme, 0x1209, []uint16{0x53c1 /* Trezor WebUSB */}, 0xffff /* No usage id on webusb, don't match unset (0) */, 0, newTrezorDriver) +} + +// newHub creates a new hardware wallet manager for generic USB devices. +func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) { + if !usb.Supported() { + return nil, errors.New("unsupported platform") + } + hub := &Hub{ + scheme: scheme, + vendorID: vendorID, + productIDs: productIDs, + usageID: usageID, + endpointID: endpointID, + makeDriver: makeDriver, + quit: make(chan chan error), + } + hub.refreshWallets() + return hub, nil +} + +// Wallets implements accounts.Backend, returning all the currently tracked USB +// devices that appear to be hardware wallets. +func (hub *Hub) Wallets() []accounts.Wallet { + // Make sure the list of wallets is up to date + hub.refreshWallets() + + hub.stateLock.RLock() + defer hub.stateLock.RUnlock() + + cpy := make([]accounts.Wallet, len(hub.wallets)) + copy(cpy, hub.wallets) + return cpy +} + +// refreshWallets scans the USB devices attached to the machine and updates the +// list of wallets based on the found devices. +func (hub *Hub) refreshWallets() { + // Don't scan the USB like crazy it the user fetches wallets in a loop + hub.stateLock.RLock() + elapsed := time.Since(hub.refreshed) + hub.stateLock.RUnlock() + + if elapsed < refreshThrottling { + return + } + // If USB enumeration is continually failing, don't keep trying indefinitely + if atomic.LoadUint32(&hub.enumFails) > 2 { + return + } + // Retrieve the current list of USB wallet devices + var devices []usb.DeviceInfo + + if runtime.GOOS == "linux" { + // hidapi on Linux opens the device during enumeration to retrieve some infos, + // breaking the Ledger protocol if that is waiting for user confirmation. This + // is a bug acknowledged at Ledger, but it won't be fixed on old devices so we + // need to prevent concurrent comms ourselves. The more elegant solution would + // be to ditch enumeration in favor of hotplug events, but that don't work yet + // on Windows so if we need to hack it anyway, this is more elegant for now. + hub.commsLock.Lock() + if hub.commsPend > 0 { // A confirmation is pending, don't refresh + hub.commsLock.Unlock() + return + } + } + infos, err := usb.Enumerate(hub.vendorID, 0) + if err != nil { + failcount := atomic.AddUint32(&hub.enumFails, 1) + if runtime.GOOS == "linux" { + // See rationale before the enumeration why this is needed and only on Linux. + hub.commsLock.Unlock() + } + log.Error("Failed to enumerate USB devices", "hub", hub.scheme, + "vendor", hub.vendorID, "failcount", failcount, "err", err) + return + } + atomic.StoreUint32(&hub.enumFails, 0) + + for _, info := range infos { + for _, id := range hub.productIDs { + // Windows and Macos use UsageID matching, Linux uses Interface matching + if info.ProductID == id && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) { + devices = append(devices, info) + break + } + } + } + if runtime.GOOS == "linux" { + // See rationale before the enumeration why this is needed and only on Linux. + hub.commsLock.Unlock() + } + // Transform the current list of wallets into the new one + hub.stateLock.Lock() + + var ( + wallets = make([]accounts.Wallet, 0, len(devices)) + events []accounts.WalletEvent + ) + + for _, device := range devices { + url := accounts.URL{Scheme: hub.scheme, Path: device.Path} + + // Drop wallets in front of the next device or those that failed for some reason + for len(hub.wallets) > 0 { + // Abort if we're past the current device and found an operational one + _, failure := hub.wallets[0].Status() + if hub.wallets[0].URL().Cmp(url) >= 0 || failure == nil { + break + } + // Drop the stale and failed devices + events = append(events, accounts.WalletEvent{Wallet: hub.wallets[0], Kind: accounts.WalletDropped}) + hub.wallets = hub.wallets[1:] + } + // If there are no more wallets or the device is before the next, wrap new wallet + if len(hub.wallets) == 0 || hub.wallets[0].URL().Cmp(url) > 0 { + logger := log.New("url", url) + wallet := &wallet{hub: hub, driver: hub.makeDriver(logger), url: &url, info: device, log: logger} + + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) + wallets = append(wallets, wallet) + continue + } + // If the device is the same as the first wallet, keep it + if hub.wallets[0].URL().Cmp(url) == 0 { + wallets = append(wallets, hub.wallets[0]) + hub.wallets = hub.wallets[1:] + continue + } + } + // Drop any leftover wallets and set the new batch + for _, wallet := range hub.wallets { + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) + } + hub.refreshed = time.Now() + hub.wallets = wallets + hub.stateLock.Unlock() + + // Fire all wallet events and return + for _, event := range events { + hub.updateFeed.Send(event) + } +} + +// Subscribe implements accounts.Backend, creating an async subscription to +// receive notifications on the addition or removal of USB wallets. +func (hub *Hub) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { + // We need the mutex to reliably start/stop the update loop + hub.stateLock.Lock() + defer hub.stateLock.Unlock() + + // Subscribe the caller and track the subscriber count + sub := hub.updateScope.Track(hub.updateFeed.Subscribe(sink)) + + // Subscribers require an active notification loop, start it + if !hub.updating { + hub.updating = true + go hub.updater() + } + return sub +} + +// updater is responsible for maintaining an up-to-date list of wallets managed +// by the USB hub, and for firing wallet addition/removal events. +func (hub *Hub) updater() { + for { + // TODO: Wait for a USB hotplug event (not supported yet) or a refresh timeout + // <-hub.changes + time.Sleep(refreshCycle) + + // Run the wallet refresher + hub.refreshWallets() + + // If all our subscribers left, stop the updater + hub.stateLock.Lock() + if hub.updateScope.Count() == 0 { + hub.updating = false + hub.stateLock.Unlock() + return + } + hub.stateLock.Unlock() + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor.go new file mode 100644 index 00000000..1892097b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor.go @@ -0,0 +1,365 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// This file contains the implementation for interacting with the Trezor hardware +// wallets. The wire protocol spec can be found on the SatoshiLabs website: +// https://doc.satoshilabs.com/trezor-tech/api-protobuf.html + +package usbwallet + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/golang/protobuf/proto" +) + +// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In +// this case, the calling application should display a pinpad and send back the +// encoded passphrase. +var ErrTrezorPINNeeded = errors.New("trezor: pin needed") + +// ErrTrezorPassphraseNeeded is returned if opening the trezor requires a passphrase +var ErrTrezorPassphraseNeeded = errors.New("trezor: passphrase needed") + +// errTrezorReplyInvalidHeader is the error message returned by a Trezor data exchange +// if the device replies with a mismatching header. This usually means the device +// is in browser mode. +var errTrezorReplyInvalidHeader = errors.New("trezor: invalid reply header") + +// trezorDriver implements the communication with a Trezor hardware wallet. +type trezorDriver struct { + device io.ReadWriter // USB device connection to communicate through + version [3]uint32 // Current version of the Trezor firmware + label string // Current textual label of the Trezor device + pinwait bool // Flags whether the device is waiting for PIN entry + passphrasewait bool // Flags whether the device is waiting for passphrase entry + failure error // Any failure that would make the device unusable + log log.Logger // Contextual logger to tag the trezor with its id +} + +// newTrezorDriver creates a new instance of a Trezor USB protocol driver. +func newTrezorDriver(logger log.Logger) driver { + return &trezorDriver{ + log: logger, + } +} + +// Status implements accounts.Wallet, always whether the Trezor is opened, closed +// or whether the Ethereum app was not started on it. +func (w *trezorDriver) Status() (string, error) { + if w.failure != nil { + return fmt.Sprintf("Failed: %v", w.failure), w.failure + } + if w.device == nil { + return "Closed", w.failure + } + if w.pinwait { + return fmt.Sprintf("Trezor v%d.%d.%d '%s' waiting for PIN", w.version[0], w.version[1], w.version[2], w.label), w.failure + } + return fmt.Sprintf("Trezor v%d.%d.%d '%s' online", w.version[0], w.version[1], w.version[2], w.label), w.failure +} + +// Open implements usbwallet.driver, attempting to initialize the connection to +// the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation: +// * The first phase is to initialize the connection and read the wallet's +// features. This phase is invoked if the provided passphrase is empty. The +// device will display the pinpad as a result and will return an appropriate +// error to notify the user that a second open phase is needed. +// * The second phase is to unlock access to the Trezor, which is done by the +// user actually providing a passphrase mapping a keyboard keypad to the pin +// number of the user (shuffled according to the pinpad displayed). +// * If needed the device will ask for passphrase which will require calling +// open again with the actual passphrase (3rd phase) +func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { + w.device, w.failure = device, nil + + // If phase 1 is requested, init the connection and wait for user callback + if passphrase == "" && !w.passphrasewait { + // If we're already waiting for a PIN entry, insta-return + if w.pinwait { + return ErrTrezorPINNeeded + } + // Initialize a connection to the device + features := new(trezor.Features) + if _, err := w.trezorExchange(&trezor.Initialize{}, features); err != nil { + return err + } + w.version = [3]uint32{features.GetMajorVersion(), features.GetMinorVersion(), features.GetPatchVersion()} + w.label = features.GetLabel() + + // Do a manual ping, forcing the device to ask for its PIN and Passphrase + askPin := true + askPassphrase := true + res, err := w.trezorExchange(&trezor.Ping{PinProtection: &askPin, PassphraseProtection: &askPassphrase}, new(trezor.PinMatrixRequest), new(trezor.PassphraseRequest), new(trezor.Success)) + if err != nil { + return err + } + // Only return the PIN request if the device wasn't unlocked until now + switch res { + case 0: + w.pinwait = true + return ErrTrezorPINNeeded + case 1: + w.pinwait = false + w.passphrasewait = true + return ErrTrezorPassphraseNeeded + case 2: + return nil // responded with trezor.Success + } + } + // Phase 2 requested with actual PIN entry + if w.pinwait { + w.pinwait = false + res, err := w.trezorExchange(&trezor.PinMatrixAck{Pin: &passphrase}, new(trezor.Success), new(trezor.PassphraseRequest)) + if err != nil { + w.failure = err + return err + } + if res == 1 { + w.passphrasewait = true + return ErrTrezorPassphraseNeeded + } + } else if w.passphrasewait { + w.passphrasewait = false + if _, err := w.trezorExchange(&trezor.PassphraseAck{Passphrase: &passphrase}, new(trezor.Success)); err != nil { + w.failure = err + return err + } + } + + return nil +} + +// Close implements usbwallet.driver, cleaning up and metadata maintained within +// the Trezor driver. +func (w *trezorDriver) Close() error { + w.version, w.label, w.pinwait = [3]uint32{}, "", false + return nil +} + +// Heartbeat implements usbwallet.driver, performing a sanity check against the +// Trezor to see if it's still online. +func (w *trezorDriver) Heartbeat() error { + if _, err := w.trezorExchange(&trezor.Ping{}, new(trezor.Success)); err != nil { + w.failure = err + return err + } + return nil +} + +// Derive implements usbwallet.driver, sending a derivation request to the Trezor +// and returning the Ethereum address located on that derivation path. +func (w *trezorDriver) Derive(path accounts.DerivationPath) (common.Address, error) { + return w.trezorDerive(path) +} + +// SignTx implements usbwallet.driver, sending the transaction to the Trezor and +// waiting for the user to confirm or deny the transaction. +func (w *trezorDriver) SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { + if w.device == nil { + return common.Address{}, nil, accounts.ErrWalletClosed + } + return w.trezorSign(path, tx, chainID) +} + +// trezorDerive sends a derivation request to the Trezor device and returns the +// Ethereum address located on that path. +func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, error) { + address := new(trezor.EthereumAddress) + if _, err := w.trezorExchange(&trezor.EthereumGetAddress{AddressN: derivationPath}, address); err != nil { + return common.Address{}, err + } + if addr := address.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary fomats + return common.BytesToAddress(addr), nil + } + if addr := address.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal fomats + return common.HexToAddress(addr), nil + } + return common.Address{}, errors.New("missing derived address") +} + +// trezorSign sends the transaction to the Trezor wallet, and waits for the user +// to confirm or deny the transaction. +func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) { + // Create the transaction initiation message + data := tx.Data() + length := uint32(len(data)) + + request := &trezor.EthereumSignTx{ + AddressN: derivationPath, + Nonce: new(big.Int).SetUint64(tx.Nonce()).Bytes(), + GasPrice: tx.GasPrice().Bytes(), + GasLimit: new(big.Int).SetUint64(tx.Gas()).Bytes(), + Value: tx.Value().Bytes(), + DataLength: &length, + } + if to := tx.To(); to != nil { + // Non contract deploy, set recipient explicitly + hex := to.Hex() + request.ToHex = &hex // Newer firmwares (old will ignore) + request.ToBin = (*to)[:] // Older firmwares (new will ignore) + } + if length > 1024 { // Send the data chunked if that was requested + request.DataInitialChunk, data = data[:1024], data[1024:] + } else { + request.DataInitialChunk, data = data, nil + } + if chainID != nil { // EIP-155 transaction, set chain ID explicitly (only 32 bit is supported!?) + id := uint32(chainID.Int64()) + request.ChainId = &id + } + // Send the initiation message and stream content until a signature is returned + response := new(trezor.EthereumTxRequest) + if _, err := w.trezorExchange(request, response); err != nil { + return common.Address{}, nil, err + } + for response.DataLength != nil && int(*response.DataLength) <= len(data) { + chunk := data[:*response.DataLength] + data = data[*response.DataLength:] + + if _, err := w.trezorExchange(&trezor.EthereumTxAck{DataChunk: chunk}, response); err != nil { + return common.Address{}, nil, err + } + } + // Extract the Ethereum signature and do a sanity validation + if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 || response.GetSignatureV() == 0 { + return common.Address{}, nil, errors.New("reply lacks signature") + } + signature := append(append(response.GetSignatureR(), response.GetSignatureS()...), byte(response.GetSignatureV())) + + // Create the correct signer and signature transform based on the chain ID + var signer types.Signer + if chainID == nil { + signer = new(types.HomesteadSigner) + } else { + signer = types.NewEIP155Signer(chainID) + signature[64] -= byte(chainID.Uint64()*2 + 35) + } + // Inject the final signature into the transaction and sanity check the sender + signed, err := tx.WithSignature(signer, signature) + if err != nil { + return common.Address{}, nil, err + } + sender, err := types.Sender(signer, signed) + if err != nil { + return common.Address{}, nil, err + } + return sender, signed, nil +} + +// trezorExchange performs a data exchange with the Trezor wallet, sending it a +// message and retrieving the response. If multiple responses are possible, the +// method will also return the index of the destination object used. +func (w *trezorDriver) trezorExchange(req proto.Message, results ...proto.Message) (int, error) { + // Construct the original message payload to chunk up + data, err := proto.Marshal(req) + if err != nil { + return 0, err + } + payload := make([]byte, 8+len(data)) + copy(payload, []byte{0x23, 0x23}) + binary.BigEndian.PutUint16(payload[2:], trezor.Type(req)) + binary.BigEndian.PutUint32(payload[4:], uint32(len(data))) + copy(payload[8:], data) + + // Stream all the chunks to the device + chunk := make([]byte, 64) + chunk[0] = 0x3f // Report ID magic number + + for len(payload) > 0 { + // Construct the new message to stream, padding with zeroes if needed + if len(payload) > 63 { + copy(chunk[1:], payload[:63]) + payload = payload[63:] + } else { + copy(chunk[1:], payload) + copy(chunk[1+len(payload):], make([]byte, 63-len(payload))) + payload = nil + } + // Send over to the device + w.log.Trace("Data chunk sent to the Trezor", "chunk", hexutil.Bytes(chunk)) + if _, err := w.device.Write(chunk); err != nil { + return 0, err + } + } + // Stream the reply back from the wallet in 64 byte chunks + var ( + kind uint16 + reply []byte + ) + for { + // Read the next chunk from the Trezor wallet + if _, err := io.ReadFull(w.device, chunk); err != nil { + return 0, err + } + w.log.Trace("Data chunk received from the Trezor", "chunk", hexutil.Bytes(chunk)) + + // Make sure the transport header matches + if chunk[0] != 0x3f || (len(reply) == 0 && (chunk[1] != 0x23 || chunk[2] != 0x23)) { + return 0, errTrezorReplyInvalidHeader + } + // If it's the first chunk, retrieve the reply message type and total message length + var payload []byte + + if len(reply) == 0 { + kind = binary.BigEndian.Uint16(chunk[3:5]) + reply = make([]byte, 0, int(binary.BigEndian.Uint32(chunk[5:9]))) + payload = chunk[9:] + } else { + payload = chunk[1:] + } + // Append to the reply and stop when filled up + if left := cap(reply) - len(reply); left > len(payload) { + reply = append(reply, payload...) + } else { + reply = append(reply, payload[:left]...) + break + } + } + // Try to parse the reply into the requested reply message + if kind == uint16(trezor.MessageType_MessageType_Failure) { + // Trezor returned a failure, extract and return the message + failure := new(trezor.Failure) + if err := proto.Unmarshal(reply, failure); err != nil { + return 0, err + } + return 0, errors.New("trezor: " + failure.GetMessage()) + } + if kind == uint16(trezor.MessageType_MessageType_ButtonRequest) { + // Trezor is waiting for user confirmation, ack and wait for the next message + return w.trezorExchange(&trezor.ButtonAck{}, results...) + } + for i, res := range results { + if trezor.Type(res) == kind { + return i, proto.Unmarshal(reply, res) + } + } + expected := make([]string, len(results)) + for i, res := range results { + expected[i] = trezor.Name(trezor.Type(res)) + } + return 0, fmt.Errorf("trezor: expected reply types %s, got %s", expected, trezor.Name(kind)) +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.pb.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.pb.go new file mode 100644 index 00000000..304bec0e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.pb.go @@ -0,0 +1,811 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-common.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Failure_FailureType int32 + +const ( + Failure_Failure_UnexpectedMessage Failure_FailureType = 1 + Failure_Failure_ButtonExpected Failure_FailureType = 2 + Failure_Failure_DataError Failure_FailureType = 3 + Failure_Failure_ActionCancelled Failure_FailureType = 4 + Failure_Failure_PinExpected Failure_FailureType = 5 + Failure_Failure_PinCancelled Failure_FailureType = 6 + Failure_Failure_PinInvalid Failure_FailureType = 7 + Failure_Failure_InvalidSignature Failure_FailureType = 8 + Failure_Failure_ProcessError Failure_FailureType = 9 + Failure_Failure_NotEnoughFunds Failure_FailureType = 10 + Failure_Failure_NotInitialized Failure_FailureType = 11 + Failure_Failure_PinMismatch Failure_FailureType = 12 + Failure_Failure_FirmwareError Failure_FailureType = 99 +) + +var Failure_FailureType_name = map[int32]string{ + 1: "Failure_UnexpectedMessage", + 2: "Failure_ButtonExpected", + 3: "Failure_DataError", + 4: "Failure_ActionCancelled", + 5: "Failure_PinExpected", + 6: "Failure_PinCancelled", + 7: "Failure_PinInvalid", + 8: "Failure_InvalidSignature", + 9: "Failure_ProcessError", + 10: "Failure_NotEnoughFunds", + 11: "Failure_NotInitialized", + 12: "Failure_PinMismatch", + 99: "Failure_FirmwareError", +} + +var Failure_FailureType_value = map[string]int32{ + "Failure_UnexpectedMessage": 1, + "Failure_ButtonExpected": 2, + "Failure_DataError": 3, + "Failure_ActionCancelled": 4, + "Failure_PinExpected": 5, + "Failure_PinCancelled": 6, + "Failure_PinInvalid": 7, + "Failure_InvalidSignature": 8, + "Failure_ProcessError": 9, + "Failure_NotEnoughFunds": 10, + "Failure_NotInitialized": 11, + "Failure_PinMismatch": 12, + "Failure_FirmwareError": 99, +} + +func (x Failure_FailureType) Enum() *Failure_FailureType { + p := new(Failure_FailureType) + *p = x + return p +} + +func (x Failure_FailureType) String() string { + return proto.EnumName(Failure_FailureType_name, int32(x)) +} + +func (x *Failure_FailureType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Failure_FailureType_value, data, "Failure_FailureType") + if err != nil { + return err + } + *x = Failure_FailureType(value) + return nil +} + +func (Failure_FailureType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{1, 0} +} + +//* +// Type of button request +type ButtonRequest_ButtonRequestType int32 + +const ( + ButtonRequest_ButtonRequest_Other ButtonRequest_ButtonRequestType = 1 + ButtonRequest_ButtonRequest_FeeOverThreshold ButtonRequest_ButtonRequestType = 2 + ButtonRequest_ButtonRequest_ConfirmOutput ButtonRequest_ButtonRequestType = 3 + ButtonRequest_ButtonRequest_ResetDevice ButtonRequest_ButtonRequestType = 4 + ButtonRequest_ButtonRequest_ConfirmWord ButtonRequest_ButtonRequestType = 5 + ButtonRequest_ButtonRequest_WipeDevice ButtonRequest_ButtonRequestType = 6 + ButtonRequest_ButtonRequest_ProtectCall ButtonRequest_ButtonRequestType = 7 + ButtonRequest_ButtonRequest_SignTx ButtonRequest_ButtonRequestType = 8 + ButtonRequest_ButtonRequest_FirmwareCheck ButtonRequest_ButtonRequestType = 9 + ButtonRequest_ButtonRequest_Address ButtonRequest_ButtonRequestType = 10 + ButtonRequest_ButtonRequest_PublicKey ButtonRequest_ButtonRequestType = 11 + ButtonRequest_ButtonRequest_MnemonicWordCount ButtonRequest_ButtonRequestType = 12 + ButtonRequest_ButtonRequest_MnemonicInput ButtonRequest_ButtonRequestType = 13 + ButtonRequest_ButtonRequest_PassphraseType ButtonRequest_ButtonRequestType = 14 + ButtonRequest_ButtonRequest_UnknownDerivationPath ButtonRequest_ButtonRequestType = 15 +) + +var ButtonRequest_ButtonRequestType_name = map[int32]string{ + 1: "ButtonRequest_Other", + 2: "ButtonRequest_FeeOverThreshold", + 3: "ButtonRequest_ConfirmOutput", + 4: "ButtonRequest_ResetDevice", + 5: "ButtonRequest_ConfirmWord", + 6: "ButtonRequest_WipeDevice", + 7: "ButtonRequest_ProtectCall", + 8: "ButtonRequest_SignTx", + 9: "ButtonRequest_FirmwareCheck", + 10: "ButtonRequest_Address", + 11: "ButtonRequest_PublicKey", + 12: "ButtonRequest_MnemonicWordCount", + 13: "ButtonRequest_MnemonicInput", + 14: "ButtonRequest_PassphraseType", + 15: "ButtonRequest_UnknownDerivationPath", +} + +var ButtonRequest_ButtonRequestType_value = map[string]int32{ + "ButtonRequest_Other": 1, + "ButtonRequest_FeeOverThreshold": 2, + "ButtonRequest_ConfirmOutput": 3, + "ButtonRequest_ResetDevice": 4, + "ButtonRequest_ConfirmWord": 5, + "ButtonRequest_WipeDevice": 6, + "ButtonRequest_ProtectCall": 7, + "ButtonRequest_SignTx": 8, + "ButtonRequest_FirmwareCheck": 9, + "ButtonRequest_Address": 10, + "ButtonRequest_PublicKey": 11, + "ButtonRequest_MnemonicWordCount": 12, + "ButtonRequest_MnemonicInput": 13, + "ButtonRequest_PassphraseType": 14, + "ButtonRequest_UnknownDerivationPath": 15, +} + +func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType { + p := new(ButtonRequest_ButtonRequestType) + *p = x + return p +} + +func (x ButtonRequest_ButtonRequestType) String() string { + return proto.EnumName(ButtonRequest_ButtonRequestType_name, int32(x)) +} + +func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ButtonRequest_ButtonRequestType_value, data, "ButtonRequest_ButtonRequestType") + if err != nil { + return err + } + *x = ButtonRequest_ButtonRequestType(value) + return nil +} + +func (ButtonRequest_ButtonRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{2, 0} +} + +//* +// Type of PIN request +type PinMatrixRequest_PinMatrixRequestType int32 + +const ( + PinMatrixRequest_PinMatrixRequestType_Current PinMatrixRequest_PinMatrixRequestType = 1 + PinMatrixRequest_PinMatrixRequestType_NewFirst PinMatrixRequest_PinMatrixRequestType = 2 + PinMatrixRequest_PinMatrixRequestType_NewSecond PinMatrixRequest_PinMatrixRequestType = 3 +) + +var PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ + 1: "PinMatrixRequestType_Current", + 2: "PinMatrixRequestType_NewFirst", + 3: "PinMatrixRequestType_NewSecond", +} + +var PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ + "PinMatrixRequestType_Current": 1, + "PinMatrixRequestType_NewFirst": 2, + "PinMatrixRequestType_NewSecond": 3, +} + +func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatrixRequestType { + p := new(PinMatrixRequest_PinMatrixRequestType) + *p = x + return p +} + +func (x PinMatrixRequest_PinMatrixRequestType) String() string { + return proto.EnumName(PinMatrixRequest_PinMatrixRequestType_name, int32(x)) +} + +func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(PinMatrixRequest_PinMatrixRequestType_value, data, "PinMatrixRequest_PinMatrixRequestType") + if err != nil { + return err + } + *x = PinMatrixRequest_PinMatrixRequestType(value) + return nil +} + +func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{4, 0} +} + +//* +// Response: Success of the previous request +// @end +type Success struct { + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Success) Reset() { *m = Success{} } +func (m *Success) String() string { return proto.CompactTextString(m) } +func (*Success) ProtoMessage() {} +func (*Success) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{0} +} + +func (m *Success) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Success.Unmarshal(m, b) +} +func (m *Success) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Success.Marshal(b, m, deterministic) +} +func (m *Success) XXX_Merge(src proto.Message) { + xxx_messageInfo_Success.Merge(m, src) +} +func (m *Success) XXX_Size() int { + return xxx_messageInfo_Success.Size(m) +} +func (m *Success) XXX_DiscardUnknown() { + xxx_messageInfo_Success.DiscardUnknown(m) +} + +var xxx_messageInfo_Success proto.InternalMessageInfo + +func (m *Success) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +//* +// Response: Failure of the previous request +// @end +type Failure struct { + Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` + Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Failure) Reset() { *m = Failure{} } +func (m *Failure) String() string { return proto.CompactTextString(m) } +func (*Failure) ProtoMessage() {} +func (*Failure) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{1} +} + +func (m *Failure) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Failure.Unmarshal(m, b) +} +func (m *Failure) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Failure.Marshal(b, m, deterministic) +} +func (m *Failure) XXX_Merge(src proto.Message) { + xxx_messageInfo_Failure.Merge(m, src) +} +func (m *Failure) XXX_Size() int { + return xxx_messageInfo_Failure.Size(m) +} +func (m *Failure) XXX_DiscardUnknown() { + xxx_messageInfo_Failure.DiscardUnknown(m) +} + +var xxx_messageInfo_Failure proto.InternalMessageInfo + +func (m *Failure) GetCode() Failure_FailureType { + if m != nil && m.Code != nil { + return *m.Code + } + return Failure_Failure_UnexpectedMessage +} + +func (m *Failure) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +//* +// Response: Device is waiting for HW button press. +// @auxstart +// @next ButtonAck +type ButtonRequest struct { + Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` + Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } +func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } +func (*ButtonRequest) ProtoMessage() {} +func (*ButtonRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{2} +} + +func (m *ButtonRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ButtonRequest.Unmarshal(m, b) +} +func (m *ButtonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ButtonRequest.Marshal(b, m, deterministic) +} +func (m *ButtonRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ButtonRequest.Merge(m, src) +} +func (m *ButtonRequest) XXX_Size() int { + return xxx_messageInfo_ButtonRequest.Size(m) +} +func (m *ButtonRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ButtonRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ButtonRequest proto.InternalMessageInfo + +func (m *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { + if m != nil && m.Code != nil { + return *m.Code + } + return ButtonRequest_ButtonRequest_Other +} + +func (m *ButtonRequest) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +//* +// Request: Computer agrees to wait for HW button press +// @auxend +type ButtonAck struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ButtonAck) Reset() { *m = ButtonAck{} } +func (m *ButtonAck) String() string { return proto.CompactTextString(m) } +func (*ButtonAck) ProtoMessage() {} +func (*ButtonAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{3} +} + +func (m *ButtonAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ButtonAck.Unmarshal(m, b) +} +func (m *ButtonAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ButtonAck.Marshal(b, m, deterministic) +} +func (m *ButtonAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_ButtonAck.Merge(m, src) +} +func (m *ButtonAck) XXX_Size() int { + return xxx_messageInfo_ButtonAck.Size(m) +} +func (m *ButtonAck) XXX_DiscardUnknown() { + xxx_messageInfo_ButtonAck.DiscardUnknown(m) +} + +var xxx_messageInfo_ButtonAck proto.InternalMessageInfo + +//* +// Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme +// @auxstart +// @next PinMatrixAck +type PinMatrixRequest struct { + Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } +func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } +func (*PinMatrixRequest) ProtoMessage() {} +func (*PinMatrixRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{4} +} + +func (m *PinMatrixRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PinMatrixRequest.Unmarshal(m, b) +} +func (m *PinMatrixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PinMatrixRequest.Marshal(b, m, deterministic) +} +func (m *PinMatrixRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PinMatrixRequest.Merge(m, src) +} +func (m *PinMatrixRequest) XXX_Size() int { + return xxx_messageInfo_PinMatrixRequest.Size(m) +} +func (m *PinMatrixRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PinMatrixRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PinMatrixRequest proto.InternalMessageInfo + +func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { + if m != nil && m.Type != nil { + return *m.Type + } + return PinMatrixRequest_PinMatrixRequestType_Current +} + +//* +// Request: Computer responds with encoded PIN +// @auxend +type PinMatrixAck struct { + Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } +func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } +func (*PinMatrixAck) ProtoMessage() {} +func (*PinMatrixAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{5} +} + +func (m *PinMatrixAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PinMatrixAck.Unmarshal(m, b) +} +func (m *PinMatrixAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PinMatrixAck.Marshal(b, m, deterministic) +} +func (m *PinMatrixAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PinMatrixAck.Merge(m, src) +} +func (m *PinMatrixAck) XXX_Size() int { + return xxx_messageInfo_PinMatrixAck.Size(m) +} +func (m *PinMatrixAck) XXX_DiscardUnknown() { + xxx_messageInfo_PinMatrixAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PinMatrixAck proto.InternalMessageInfo + +func (m *PinMatrixAck) GetPin() string { + if m != nil && m.Pin != nil { + return *m.Pin + } + return "" +} + +//* +// Response: Device awaits encryption passphrase +// @auxstart +// @next PassphraseAck +type PassphraseRequest struct { + OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } +func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } +func (*PassphraseRequest) ProtoMessage() {} +func (*PassphraseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{6} +} + +func (m *PassphraseRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseRequest.Unmarshal(m, b) +} +func (m *PassphraseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseRequest.Marshal(b, m, deterministic) +} +func (m *PassphraseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseRequest.Merge(m, src) +} +func (m *PassphraseRequest) XXX_Size() int { + return xxx_messageInfo_PassphraseRequest.Size(m) +} +func (m *PassphraseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseRequest proto.InternalMessageInfo + +func (m *PassphraseRequest) GetOnDevice() bool { + if m != nil && m.OnDevice != nil { + return *m.OnDevice + } + return false +} + +//* +// Request: Send passphrase back +// @next PassphraseStateRequest +type PassphraseAck struct { + Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } +func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } +func (*PassphraseAck) ProtoMessage() {} +func (*PassphraseAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{7} +} + +func (m *PassphraseAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseAck.Unmarshal(m, b) +} +func (m *PassphraseAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseAck.Marshal(b, m, deterministic) +} +func (m *PassphraseAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseAck.Merge(m, src) +} +func (m *PassphraseAck) XXX_Size() int { + return xxx_messageInfo_PassphraseAck.Size(m) +} +func (m *PassphraseAck) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseAck proto.InternalMessageInfo + +func (m *PassphraseAck) GetPassphrase() string { + if m != nil && m.Passphrase != nil { + return *m.Passphrase + } + return "" +} + +func (m *PassphraseAck) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +//* +// Response: Device awaits passphrase state +// @next PassphraseStateAck +type PassphraseStateRequest struct { + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseStateRequest) Reset() { *m = PassphraseStateRequest{} } +func (m *PassphraseStateRequest) String() string { return proto.CompactTextString(m) } +func (*PassphraseStateRequest) ProtoMessage() {} +func (*PassphraseStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{8} +} + +func (m *PassphraseStateRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseStateRequest.Unmarshal(m, b) +} +func (m *PassphraseStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseStateRequest.Marshal(b, m, deterministic) +} +func (m *PassphraseStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseStateRequest.Merge(m, src) +} +func (m *PassphraseStateRequest) XXX_Size() int { + return xxx_messageInfo_PassphraseStateRequest.Size(m) +} +func (m *PassphraseStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseStateRequest proto.InternalMessageInfo + +func (m *PassphraseStateRequest) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +//* +// Request: Send passphrase state back +// @auxend +type PassphraseStateAck struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseStateAck) Reset() { *m = PassphraseStateAck{} } +func (m *PassphraseStateAck) String() string { return proto.CompactTextString(m) } +func (*PassphraseStateAck) ProtoMessage() {} +func (*PassphraseStateAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{9} +} + +func (m *PassphraseStateAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseStateAck.Unmarshal(m, b) +} +func (m *PassphraseStateAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseStateAck.Marshal(b, m, deterministic) +} +func (m *PassphraseStateAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseStateAck.Merge(m, src) +} +func (m *PassphraseStateAck) XXX_Size() int { + return xxx_messageInfo_PassphraseStateAck.Size(m) +} +func (m *PassphraseStateAck) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseStateAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseStateAck proto.InternalMessageInfo + +//* +// Structure representing BIP32 (hierarchical deterministic) node +// Used for imports of private key into the device and exporting public key out of device +// @embed +type HDNodeType struct { + Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` + Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` + ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` + ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` + PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` + PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HDNodeType) Reset() { *m = HDNodeType{} } +func (m *HDNodeType) String() string { return proto.CompactTextString(m) } +func (*HDNodeType) ProtoMessage() {} +func (*HDNodeType) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{10} +} + +func (m *HDNodeType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HDNodeType.Unmarshal(m, b) +} +func (m *HDNodeType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HDNodeType.Marshal(b, m, deterministic) +} +func (m *HDNodeType) XXX_Merge(src proto.Message) { + xxx_messageInfo_HDNodeType.Merge(m, src) +} +func (m *HDNodeType) XXX_Size() int { + return xxx_messageInfo_HDNodeType.Size(m) +} +func (m *HDNodeType) XXX_DiscardUnknown() { + xxx_messageInfo_HDNodeType.DiscardUnknown(m) +} + +var xxx_messageInfo_HDNodeType proto.InternalMessageInfo + +func (m *HDNodeType) GetDepth() uint32 { + if m != nil && m.Depth != nil { + return *m.Depth + } + return 0 +} + +func (m *HDNodeType) GetFingerprint() uint32 { + if m != nil && m.Fingerprint != nil { + return *m.Fingerprint + } + return 0 +} + +func (m *HDNodeType) GetChildNum() uint32 { + if m != nil && m.ChildNum != nil { + return *m.ChildNum + } + return 0 +} + +func (m *HDNodeType) GetChainCode() []byte { + if m != nil { + return m.ChainCode + } + return nil +} + +func (m *HDNodeType) GetPrivateKey() []byte { + if m != nil { + return m.PrivateKey + } + return nil +} + +func (m *HDNodeType) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func init() { + proto.RegisterEnum("hw.trezor.messages.common.Failure_FailureType", Failure_FailureType_name, Failure_FailureType_value) + proto.RegisterEnum("hw.trezor.messages.common.ButtonRequest_ButtonRequestType", ButtonRequest_ButtonRequestType_name, ButtonRequest_ButtonRequestType_value) + proto.RegisterEnum("hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType", PinMatrixRequest_PinMatrixRequestType_name, PinMatrixRequest_PinMatrixRequestType_value) + proto.RegisterType((*Success)(nil), "hw.trezor.messages.common.Success") + proto.RegisterType((*Failure)(nil), "hw.trezor.messages.common.Failure") + proto.RegisterType((*ButtonRequest)(nil), "hw.trezor.messages.common.ButtonRequest") + proto.RegisterType((*ButtonAck)(nil), "hw.trezor.messages.common.ButtonAck") + proto.RegisterType((*PinMatrixRequest)(nil), "hw.trezor.messages.common.PinMatrixRequest") + proto.RegisterType((*PinMatrixAck)(nil), "hw.trezor.messages.common.PinMatrixAck") + proto.RegisterType((*PassphraseRequest)(nil), "hw.trezor.messages.common.PassphraseRequest") + proto.RegisterType((*PassphraseAck)(nil), "hw.trezor.messages.common.PassphraseAck") + proto.RegisterType((*PassphraseStateRequest)(nil), "hw.trezor.messages.common.PassphraseStateRequest") + proto.RegisterType((*PassphraseStateAck)(nil), "hw.trezor.messages.common.PassphraseStateAck") + proto.RegisterType((*HDNodeType)(nil), "hw.trezor.messages.common.HDNodeType") +} + +func init() { proto.RegisterFile("messages-common.proto", fileDescriptor_aaf30d059fdbc38d) } + +var fileDescriptor_aaf30d059fdbc38d = []byte{ + // 846 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x52, 0x23, 0x37, + 0x10, 0x2e, 0xff, 0x80, 0xed, 0xb6, 0xd9, 0x08, 0xc5, 0x80, 0x09, 0xb0, 0x38, 0xc3, 0x21, 0x5c, + 0xe2, 0x4a, 0xe5, 0x98, 0x53, 0x58, 0x83, 0x2b, 0xd4, 0x16, 0x86, 0x1a, 0xd8, 0xda, 0xa3, 0x4b, + 0xd1, 0xf4, 0x32, 0x2a, 0xcf, 0x48, 0x13, 0x8d, 0x06, 0xf0, 0x5e, 0xf2, 0x6a, 0x79, 0x89, 0xbc, + 0x42, 0xaa, 0x52, 0xb9, 0xe4, 0x11, 0xb6, 0x34, 0x3f, 0x78, 0xc6, 0x66, 0x39, 0xcd, 0xe8, 0xfb, + 0xbe, 0xee, 0x96, 0xba, 0x3f, 0x09, 0x76, 0x42, 0x8c, 0x63, 0x76, 0x8f, 0xf1, 0x8f, 0x5c, 0x85, + 0xa1, 0x92, 0xa3, 0x48, 0x2b, 0xa3, 0xe8, 0xbe, 0xff, 0x38, 0x32, 0x1a, 0x3f, 0x2b, 0x3d, 0x2a, + 0x04, 0xa3, 0x4c, 0xe0, 0x9c, 0x40, 0xeb, 0x36, 0xe1, 0x1c, 0xe3, 0x98, 0x0e, 0xa0, 0x95, 0xb3, + 0x83, 0xda, 0xb0, 0x76, 0xda, 0x71, 0x8b, 0xa5, 0xf3, 0x77, 0x03, 0x5a, 0x13, 0x26, 0x82, 0x44, + 0x23, 0x7d, 0x07, 0x4d, 0xae, 0xbc, 0x4c, 0xf2, 0xe6, 0xe7, 0xd1, 0xe8, 0xab, 0xa9, 0x47, 0x79, + 0x44, 0xf1, 0xbd, 0x5b, 0x44, 0xe8, 0xa6, 0xb1, 0xe5, 0x4a, 0xf5, 0x6a, 0xa5, 0xff, 0xea, 0xd0, + 0x2d, 0xe9, 0xe9, 0x11, 0xec, 0xe7, 0xcb, 0xd9, 0x07, 0x89, 0x4f, 0x11, 0x72, 0x83, 0xde, 0x55, + 0x26, 0x26, 0x35, 0xfa, 0x1d, 0xec, 0x16, 0xf4, 0xbb, 0xc4, 0x18, 0x25, 0x2f, 0x72, 0x09, 0xa9, + 0xd3, 0x1d, 0xd8, 0x2e, 0xb8, 0x73, 0x66, 0xd8, 0x85, 0xd6, 0x4a, 0x93, 0x06, 0x3d, 0x80, 0xbd, + 0x02, 0x3e, 0xe3, 0x46, 0x28, 0x39, 0x66, 0x92, 0x63, 0x10, 0xa0, 0x47, 0x9a, 0x74, 0x0f, 0xbe, + 0x2d, 0xc8, 0x1b, 0xb1, 0x4c, 0xb6, 0x41, 0x07, 0xd0, 0x2f, 0x11, 0xcb, 0x90, 0x4d, 0xba, 0x0b, + 0xb4, 0xc4, 0x5c, 0xca, 0x07, 0x16, 0x08, 0x8f, 0xb4, 0xe8, 0x21, 0x0c, 0x0a, 0x3c, 0x07, 0x6f, + 0xc5, 0xbd, 0x64, 0x26, 0xd1, 0x48, 0xda, 0x95, 0x7c, 0x5a, 0xd9, 0xf6, 0x67, 0xfb, 0xeb, 0x94, + 0x8f, 0x34, 0x55, 0xe6, 0x42, 0xaa, 0xe4, 0xde, 0x9f, 0x24, 0xd2, 0x8b, 0x09, 0xac, 0x70, 0x97, + 0x52, 0x18, 0xc1, 0x02, 0xf1, 0x19, 0x3d, 0xd2, 0x5d, 0xd9, 0xfa, 0x95, 0x88, 0x43, 0x66, 0xb8, + 0x4f, 0x7a, 0x74, 0x1f, 0x76, 0x0a, 0x62, 0x22, 0x74, 0xf8, 0xc8, 0x34, 0x66, 0xb5, 0xb8, 0xf3, + 0x4f, 0x13, 0xb6, 0xb2, 0xbe, 0xb9, 0xf8, 0x47, 0x82, 0xb1, 0xa1, 0xd3, 0xca, 0x74, 0x7f, 0x79, + 0x65, 0xba, 0x95, 0xb8, 0xea, 0xaa, 0x34, 0x69, 0x0a, 0x4d, 0x8f, 0x19, 0x96, 0x8f, 0x39, 0xfd, + 0x77, 0xfe, 0x6f, 0xc0, 0xf6, 0x9a, 0xde, 0xee, 0xbf, 0x02, 0xce, 0xae, 0x8d, 0x8f, 0x9a, 0xd4, + 0xa8, 0x03, 0x6f, 0xab, 0xc4, 0x04, 0xf1, 0xfa, 0x01, 0xf5, 0x9d, 0xaf, 0x31, 0xf6, 0x55, 0x60, + 0x67, 0x7d, 0x0c, 0x07, 0x55, 0xcd, 0x58, 0xc9, 0x4f, 0x42, 0x87, 0xd7, 0x89, 0x89, 0x12, 0x43, + 0x1a, 0xd6, 0x47, 0x55, 0x81, 0x8b, 0x31, 0x9a, 0x73, 0x7c, 0x10, 0x1c, 0x49, 0x73, 0x9d, 0xce, + 0xe3, 0x3f, 0x2a, 0x6d, 0xa7, 0x7f, 0x08, 0x83, 0x2a, 0xfd, 0x51, 0x44, 0x98, 0x07, 0x6f, 0xae, + 0x07, 0xdf, 0x68, 0x65, 0x90, 0x9b, 0x31, 0x0b, 0x02, 0xd2, 0xb2, 0xa3, 0xae, 0xd2, 0xd6, 0x07, + 0x77, 0x4f, 0xa4, 0xbd, 0xbe, 0xeb, 0x62, 0x3e, 0x63, 0x1f, 0xf9, 0x9c, 0x74, 0xec, 0xe8, 0xaa, + 0x82, 0x33, 0xcf, 0xd3, 0x18, 0x5b, 0x2b, 0x1c, 0xc0, 0xde, 0x4a, 0xd1, 0xe4, 0xf7, 0x40, 0xf0, + 0xf7, 0xb8, 0x20, 0x5d, 0x7a, 0x02, 0xc7, 0x55, 0xf2, 0x4a, 0x62, 0xa8, 0xa4, 0xe0, 0xf6, 0x3c, + 0x63, 0x95, 0x48, 0x43, 0x7a, 0xeb, 0xd5, 0x0b, 0xd1, 0xa5, 0xb4, 0x3d, 0xdb, 0xa2, 0x43, 0x38, + 0x5c, 0x29, 0xc1, 0xe2, 0x38, 0xf2, 0x35, 0x8b, 0xd3, 0xbb, 0x49, 0xde, 0xd0, 0x1f, 0xe0, 0xa4, + 0xaa, 0xf8, 0x20, 0xe7, 0x52, 0x3d, 0xca, 0x73, 0xd4, 0xe2, 0x81, 0xd9, 0xcb, 0x75, 0xc3, 0x8c, + 0x4f, 0xbe, 0x71, 0xba, 0xd0, 0xc9, 0x84, 0x67, 0x7c, 0xee, 0xfc, 0x5b, 0x03, 0x62, 0x2d, 0xca, + 0x8c, 0x16, 0x4f, 0x85, 0xf1, 0xee, 0xa0, 0x69, 0x16, 0x51, 0x61, 0xbc, 0x5f, 0x5f, 0x31, 0xde, + 0x6a, 0xe8, 0x1a, 0x90, 0xd9, 0xcf, 0x66, 0x73, 0xfe, 0x84, 0xfe, 0x4b, 0xac, 0x3d, 0xda, 0x4b, + 0xf8, 0x6c, 0x9c, 0x68, 0x8d, 0xd2, 0x90, 0x1a, 0xfd, 0x1e, 0x8e, 0x5e, 0x54, 0x4c, 0xf1, 0x71, + 0x22, 0x74, 0x6c, 0x48, 0xdd, 0x1a, 0xf3, 0x6b, 0x92, 0x5b, 0xe4, 0x4a, 0x7a, 0xa4, 0xe1, 0x0c, + 0xa1, 0xf7, 0xac, 0x39, 0xe3, 0x73, 0x4a, 0xa0, 0x11, 0x09, 0x39, 0xa8, 0x0d, 0xeb, 0xa7, 0x1d, + 0xd7, 0xfe, 0x3a, 0x3f, 0xc1, 0xf6, 0xb2, 0xaf, 0x45, 0x37, 0x0e, 0xa0, 0xa3, 0xe4, 0xcc, 0x4b, + 0x1d, 0x96, 0xb6, 0xa4, 0xed, 0xb6, 0x95, 0xcc, 0x1c, 0xe7, 0x5c, 0xc0, 0xd6, 0x32, 0xc2, 0x26, + 0x7d, 0x0b, 0x10, 0x3d, 0x03, 0xf9, 0xdb, 0x5d, 0x42, 0x68, 0x1f, 0x36, 0x62, 0xc3, 0x4c, 0xf6, + 0xd8, 0xf6, 0xdc, 0x6c, 0xe1, 0x8c, 0x60, 0x77, 0x99, 0xe6, 0xd6, 0x42, 0x45, 0xf5, 0x67, 0x7d, + 0xad, 0xac, 0xef, 0x03, 0x5d, 0xd1, 0xdb, 0x61, 0xfe, 0x55, 0x03, 0xf8, 0xed, 0x7c, 0xaa, 0xbc, + 0xec, 0xbd, 0xee, 0xc3, 0x86, 0x87, 0x91, 0xf1, 0xd3, 0x13, 0x6e, 0xb9, 0xd9, 0x82, 0x0e, 0xa1, + 0xfb, 0x49, 0xc8, 0x7b, 0xd4, 0x91, 0x16, 0xd2, 0x0c, 0xea, 0x29, 0x57, 0x86, 0xec, 0x81, 0xb9, + 0x2f, 0x02, 0x6f, 0x26, 0x93, 0x70, 0xd0, 0x48, 0xf9, 0x76, 0x0a, 0x4c, 0x93, 0x90, 0x1e, 0x01, + 0x70, 0x9f, 0x09, 0x39, 0x4b, 0x9f, 0xa6, 0xe6, 0xb0, 0x7e, 0xda, 0x73, 0x3b, 0x29, 0x32, 0xb6, + 0x6f, 0xcc, 0x31, 0x74, 0xa3, 0xd4, 0x6f, 0x38, 0x9b, 0xe3, 0x62, 0xb0, 0x91, 0x6e, 0x1a, 0x72, + 0xe8, 0x3d, 0x2e, 0x6c, 0x7c, 0x94, 0xde, 0x8e, 0x94, 0xdf, 0x4c, 0xf9, 0x4e, 0x54, 0xdc, 0x97, + 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x7d, 0x20, 0xa6, 0x35, 0x07, 0x00, 0x00, +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.proto b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.proto new file mode 100644 index 00000000..75a983b0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-common.proto @@ -0,0 +1,147 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.common; + +/** + * Response: Success of the previous request + * @end + */ +message Success { + optional string message = 1; // human readable description of action or request-specific payload +} + +/** + * Response: Failure of the previous request + * @end + */ +message Failure { + optional FailureType code = 1; // computer-readable definition of the error state + optional string message = 2; // human-readable message of the error state + enum FailureType { + Failure_UnexpectedMessage = 1; + Failure_ButtonExpected = 2; + Failure_DataError = 3; + Failure_ActionCancelled = 4; + Failure_PinExpected = 5; + Failure_PinCancelled = 6; + Failure_PinInvalid = 7; + Failure_InvalidSignature = 8; + Failure_ProcessError = 9; + Failure_NotEnoughFunds = 10; + Failure_NotInitialized = 11; + Failure_PinMismatch = 12; + Failure_FirmwareError = 99; + } +} + +/** + * Response: Device is waiting for HW button press. + * @auxstart + * @next ButtonAck + */ +message ButtonRequest { + optional ButtonRequestType code = 1; + optional string data = 2; + /** + * Type of button request + */ + enum ButtonRequestType { + ButtonRequest_Other = 1; + ButtonRequest_FeeOverThreshold = 2; + ButtonRequest_ConfirmOutput = 3; + ButtonRequest_ResetDevice = 4; + ButtonRequest_ConfirmWord = 5; + ButtonRequest_WipeDevice = 6; + ButtonRequest_ProtectCall = 7; + ButtonRequest_SignTx = 8; + ButtonRequest_FirmwareCheck = 9; + ButtonRequest_Address = 10; + ButtonRequest_PublicKey = 11; + ButtonRequest_MnemonicWordCount = 12; + ButtonRequest_MnemonicInput = 13; + ButtonRequest_PassphraseType = 14; + ButtonRequest_UnknownDerivationPath = 15; + } +} + +/** + * Request: Computer agrees to wait for HW button press + * @auxend + */ +message ButtonAck { +} + +/** + * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme + * @auxstart + * @next PinMatrixAck + */ +message PinMatrixRequest { + optional PinMatrixRequestType type = 1; + /** + * Type of PIN request + */ + enum PinMatrixRequestType { + PinMatrixRequestType_Current = 1; + PinMatrixRequestType_NewFirst = 2; + PinMatrixRequestType_NewSecond = 3; + } +} + +/** + * Request: Computer responds with encoded PIN + * @auxend + */ +message PinMatrixAck { + required string pin = 1; // matrix encoded PIN entered by user +} + +/** + * Response: Device awaits encryption passphrase + * @auxstart + * @next PassphraseAck + */ +message PassphraseRequest { + optional bool on_device = 1; // passphrase is being entered on the device +} + +/** + * Request: Send passphrase back + * @next PassphraseStateRequest + */ +message PassphraseAck { + optional string passphrase = 1; + optional bytes state = 2; // expected device state +} + +/** + * Response: Device awaits passphrase state + * @next PassphraseStateAck + */ +message PassphraseStateRequest { + optional bytes state = 1; // actual device state +} + +/** + * Request: Send passphrase state back + * @auxend + */ +message PassphraseStateAck { +} + +/** + * Structure representing BIP32 (hierarchical deterministic) node + * Used for imports of private key into the device and exporting public key out of device + * @embed + */ +message HDNodeType { + required uint32 depth = 1; + required uint32 fingerprint = 2; + required uint32 child_num = 3; + required bytes chain_code = 4; + optional bytes private_key = 5; + optional bytes public_key = 6; +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.pb.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.pb.go new file mode 100644 index 00000000..5d664f5b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -0,0 +1,698 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-ethereum.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Request: Ask device for public key corresponding to address_n path +// @start +// @next EthereumPublicKey +// @next Failure +type EthereumGetPublicKey struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumGetPublicKey) Reset() { *m = EthereumGetPublicKey{} } +func (m *EthereumGetPublicKey) String() string { return proto.CompactTextString(m) } +func (*EthereumGetPublicKey) ProtoMessage() {} +func (*EthereumGetPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{0} +} + +func (m *EthereumGetPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumGetPublicKey.Unmarshal(m, b) +} +func (m *EthereumGetPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumGetPublicKey.Marshal(b, m, deterministic) +} +func (m *EthereumGetPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumGetPublicKey.Merge(m, src) +} +func (m *EthereumGetPublicKey) XXX_Size() int { + return xxx_messageInfo_EthereumGetPublicKey.Size(m) +} +func (m *EthereumGetPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumGetPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumGetPublicKey proto.InternalMessageInfo + +func (m *EthereumGetPublicKey) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumGetPublicKey) GetShowDisplay() bool { + if m != nil && m.ShowDisplay != nil { + return *m.ShowDisplay + } + return false +} + +//* +// Response: Contains public key derived from device private seed +// @end +type EthereumPublicKey struct { + Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` + Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumPublicKey) Reset() { *m = EthereumPublicKey{} } +func (m *EthereumPublicKey) String() string { return proto.CompactTextString(m) } +func (*EthereumPublicKey) ProtoMessage() {} +func (*EthereumPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{1} +} + +func (m *EthereumPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumPublicKey.Unmarshal(m, b) +} +func (m *EthereumPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumPublicKey.Marshal(b, m, deterministic) +} +func (m *EthereumPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumPublicKey.Merge(m, src) +} +func (m *EthereumPublicKey) XXX_Size() int { + return xxx_messageInfo_EthereumPublicKey.Size(m) +} +func (m *EthereumPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumPublicKey proto.InternalMessageInfo + +func (m *EthereumPublicKey) GetNode() *HDNodeType { + if m != nil { + return m.Node + } + return nil +} + +func (m *EthereumPublicKey) GetXpub() string { + if m != nil && m.Xpub != nil { + return *m.Xpub + } + return "" +} + +//* +// Request: Ask device for Ethereum address corresponding to address_n path +// @start +// @next EthereumAddress +// @next Failure +type EthereumGetAddress struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } +func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } +func (*EthereumGetAddress) ProtoMessage() {} +func (*EthereumGetAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{2} +} + +func (m *EthereumGetAddress) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumGetAddress.Unmarshal(m, b) +} +func (m *EthereumGetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumGetAddress.Marshal(b, m, deterministic) +} +func (m *EthereumGetAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumGetAddress.Merge(m, src) +} +func (m *EthereumGetAddress) XXX_Size() int { + return xxx_messageInfo_EthereumGetAddress.Size(m) +} +func (m *EthereumGetAddress) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumGetAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumGetAddress proto.InternalMessageInfo + +func (m *EthereumGetAddress) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumGetAddress) GetShowDisplay() bool { + if m != nil && m.ShowDisplay != nil { + return *m.ShowDisplay + } + return false +} + +//* +// Response: Contains an Ethereum address derived from device private seed +// @end +type EthereumAddress struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } +func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } +func (*EthereumAddress) ProtoMessage() {} +func (*EthereumAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{3} +} + +func (m *EthereumAddress) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumAddress.Unmarshal(m, b) +} +func (m *EthereumAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumAddress.Marshal(b, m, deterministic) +} +func (m *EthereumAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumAddress.Merge(m, src) +} +func (m *EthereumAddress) XXX_Size() int { + return xxx_messageInfo_EthereumAddress.Size(m) +} +func (m *EthereumAddress) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumAddress proto.InternalMessageInfo + +func (m *EthereumAddress) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumAddress) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +//* +// Request: Ask device to sign transaction +// All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. +// Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. +// @start +// @next EthereumTxRequest +// @next Failure +type EthereumSignTx struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` + GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` + GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` + ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` + ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` + Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` + DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` + DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` + ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` + TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } +func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } +func (*EthereumSignTx) ProtoMessage() {} +func (*EthereumSignTx) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{4} +} + +func (m *EthereumSignTx) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumSignTx.Unmarshal(m, b) +} +func (m *EthereumSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumSignTx.Marshal(b, m, deterministic) +} +func (m *EthereumSignTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumSignTx.Merge(m, src) +} +func (m *EthereumSignTx) XXX_Size() int { + return xxx_messageInfo_EthereumSignTx.Size(m) +} +func (m *EthereumSignTx) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumSignTx.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumSignTx proto.InternalMessageInfo + +func (m *EthereumSignTx) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumSignTx) GetNonce() []byte { + if m != nil { + return m.Nonce + } + return nil +} + +func (m *EthereumSignTx) GetGasPrice() []byte { + if m != nil { + return m.GasPrice + } + return nil +} + +func (m *EthereumSignTx) GetGasLimit() []byte { + if m != nil { + return m.GasLimit + } + return nil +} + +func (m *EthereumSignTx) GetToBin() []byte { + if m != nil { + return m.ToBin + } + return nil +} + +func (m *EthereumSignTx) GetToHex() string { + if m != nil && m.ToHex != nil { + return *m.ToHex + } + return "" +} + +func (m *EthereumSignTx) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *EthereumSignTx) GetDataInitialChunk() []byte { + if m != nil { + return m.DataInitialChunk + } + return nil +} + +func (m *EthereumSignTx) GetDataLength() uint32 { + if m != nil && m.DataLength != nil { + return *m.DataLength + } + return 0 +} + +func (m *EthereumSignTx) GetChainId() uint32 { + if m != nil && m.ChainId != nil { + return *m.ChainId + } + return 0 +} + +func (m *EthereumSignTx) GetTxType() uint32 { + if m != nil && m.TxType != nil { + return *m.TxType + } + return 0 +} + +//* +// Response: Device asks for more data from transaction payload, or returns the signature. +// If data_length is set, device awaits that many more bytes of payload. +// Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. +// @end +// @next EthereumTxAck +type EthereumTxRequest struct { + DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` + SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` + SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` + SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } +func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } +func (*EthereumTxRequest) ProtoMessage() {} +func (*EthereumTxRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{5} +} + +func (m *EthereumTxRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumTxRequest.Unmarshal(m, b) +} +func (m *EthereumTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumTxRequest.Marshal(b, m, deterministic) +} +func (m *EthereumTxRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumTxRequest.Merge(m, src) +} +func (m *EthereumTxRequest) XXX_Size() int { + return xxx_messageInfo_EthereumTxRequest.Size(m) +} +func (m *EthereumTxRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumTxRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumTxRequest proto.InternalMessageInfo + +func (m *EthereumTxRequest) GetDataLength() uint32 { + if m != nil && m.DataLength != nil { + return *m.DataLength + } + return 0 +} + +func (m *EthereumTxRequest) GetSignatureV() uint32 { + if m != nil && m.SignatureV != nil { + return *m.SignatureV + } + return 0 +} + +func (m *EthereumTxRequest) GetSignatureR() []byte { + if m != nil { + return m.SignatureR + } + return nil +} + +func (m *EthereumTxRequest) GetSignatureS() []byte { + if m != nil { + return m.SignatureS + } + return nil +} + +//* +// Request: Transaction payload data. +// @next EthereumTxRequest +type EthereumTxAck struct { + DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } +func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } +func (*EthereumTxAck) ProtoMessage() {} +func (*EthereumTxAck) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{6} +} + +func (m *EthereumTxAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumTxAck.Unmarshal(m, b) +} +func (m *EthereumTxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumTxAck.Marshal(b, m, deterministic) +} +func (m *EthereumTxAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumTxAck.Merge(m, src) +} +func (m *EthereumTxAck) XXX_Size() int { + return xxx_messageInfo_EthereumTxAck.Size(m) +} +func (m *EthereumTxAck) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumTxAck.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumTxAck proto.InternalMessageInfo + +func (m *EthereumTxAck) GetDataChunk() []byte { + if m != nil { + return m.DataChunk + } + return nil +} + +//* +// Request: Ask device to sign message +// @start +// @next EthereumMessageSignature +// @next Failure +type EthereumSignMessage struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } +func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } +func (*EthereumSignMessage) ProtoMessage() {} +func (*EthereumSignMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{7} +} + +func (m *EthereumSignMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumSignMessage.Unmarshal(m, b) +} +func (m *EthereumSignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumSignMessage.Marshal(b, m, deterministic) +} +func (m *EthereumSignMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumSignMessage.Merge(m, src) +} +func (m *EthereumSignMessage) XXX_Size() int { + return xxx_messageInfo_EthereumSignMessage.Size(m) +} +func (m *EthereumSignMessage) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumSignMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumSignMessage proto.InternalMessageInfo + +func (m *EthereumSignMessage) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumSignMessage) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +//* +// Response: Signed message +// @end +type EthereumMessageSignature struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } +func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } +func (*EthereumMessageSignature) ProtoMessage() {} +func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{8} +} + +func (m *EthereumMessageSignature) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumMessageSignature.Unmarshal(m, b) +} +func (m *EthereumMessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumMessageSignature.Marshal(b, m, deterministic) +} +func (m *EthereumMessageSignature) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumMessageSignature.Merge(m, src) +} +func (m *EthereumMessageSignature) XXX_Size() int { + return xxx_messageInfo_EthereumMessageSignature.Size(m) +} +func (m *EthereumMessageSignature) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumMessageSignature.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumMessageSignature proto.InternalMessageInfo + +func (m *EthereumMessageSignature) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumMessageSignature) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *EthereumMessageSignature) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +//* +// Request: Ask device to verify message +// @start +// @next Success +// @next Failure +type EthereumVerifyMessage struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` + AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } +func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } +func (*EthereumVerifyMessage) ProtoMessage() {} +func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{9} +} + +func (m *EthereumVerifyMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumVerifyMessage.Unmarshal(m, b) +} +func (m *EthereumVerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumVerifyMessage.Marshal(b, m, deterministic) +} +func (m *EthereumVerifyMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumVerifyMessage.Merge(m, src) +} +func (m *EthereumVerifyMessage) XXX_Size() int { + return xxx_messageInfo_EthereumVerifyMessage.Size(m) +} +func (m *EthereumVerifyMessage) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumVerifyMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumVerifyMessage proto.InternalMessageInfo + +func (m *EthereumVerifyMessage) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumVerifyMessage) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *EthereumVerifyMessage) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (m *EthereumVerifyMessage) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +func init() { + proto.RegisterType((*EthereumGetPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumGetPublicKey") + proto.RegisterType((*EthereumPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumPublicKey") + proto.RegisterType((*EthereumGetAddress)(nil), "hw.trezor.messages.ethereum.EthereumGetAddress") + proto.RegisterType((*EthereumAddress)(nil), "hw.trezor.messages.ethereum.EthereumAddress") + proto.RegisterType((*EthereumSignTx)(nil), "hw.trezor.messages.ethereum.EthereumSignTx") + proto.RegisterType((*EthereumTxRequest)(nil), "hw.trezor.messages.ethereum.EthereumTxRequest") + proto.RegisterType((*EthereumTxAck)(nil), "hw.trezor.messages.ethereum.EthereumTxAck") + proto.RegisterType((*EthereumSignMessage)(nil), "hw.trezor.messages.ethereum.EthereumSignMessage") + proto.RegisterType((*EthereumMessageSignature)(nil), "hw.trezor.messages.ethereum.EthereumMessageSignature") + proto.RegisterType((*EthereumVerifyMessage)(nil), "hw.trezor.messages.ethereum.EthereumVerifyMessage") +} + +func init() { proto.RegisterFile("messages-ethereum.proto", fileDescriptor_cb33f46ba915f15c) } + +var fileDescriptor_cb33f46ba915f15c = []byte{ + // 593 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0x95, 0x9b, 0xb4, 0x49, 0x26, 0x0d, 0x1f, 0xa6, 0x55, 0x17, 0x0a, 0x34, 0x18, 0x21, 0xe5, + 0x00, 0x3e, 0x70, 0x43, 0xe2, 0xd2, 0x52, 0x44, 0x2b, 0x4a, 0x55, 0xdc, 0xa8, 0x57, 0x6b, 0x63, + 0x6f, 0xe3, 0x55, 0x9d, 0xdd, 0xe0, 0x5d, 0xb7, 0x0e, 0x7f, 0x82, 0x23, 0xff, 0x87, 0x5f, 0x86, + 0xf6, 0x2b, 0x71, 0x52, 0x54, 0x0e, 0xbd, 0x65, 0xde, 0xbc, 0x7d, 0xf3, 0x66, 0xf4, 0x62, 0xd8, + 0x99, 0x10, 0x21, 0xf0, 0x98, 0x88, 0x77, 0x44, 0x66, 0xa4, 0x20, 0xe5, 0x24, 0x9c, 0x16, 0x5c, + 0x72, 0x7f, 0x37, 0xbb, 0x09, 0x65, 0x41, 0x7e, 0xf2, 0x22, 0x74, 0x94, 0xd0, 0x51, 0x9e, 0x6d, + 0xcf, 0x5f, 0x25, 0x7c, 0x32, 0xe1, 0xcc, 0xbc, 0x09, 0x2e, 0x60, 0xeb, 0xb3, 0xa5, 0x7c, 0x21, + 0xf2, 0xac, 0x1c, 0xe5, 0x34, 0xf9, 0x4a, 0x66, 0xfe, 0x2e, 0x74, 0x70, 0x9a, 0x16, 0x44, 0x88, + 0x98, 0x21, 0xaf, 0xdf, 0x18, 0xf4, 0xa2, 0xb6, 0x05, 0x4e, 0xfd, 0x57, 0xb0, 0x29, 0x32, 0x7e, + 0x13, 0xa7, 0x54, 0x4c, 0x73, 0x3c, 0x43, 0x6b, 0x7d, 0x6f, 0xd0, 0x8e, 0xba, 0x0a, 0x3b, 0x34, + 0x50, 0x30, 0x82, 0xc7, 0x4e, 0x77, 0x21, 0xfa, 0x01, 0x9a, 0x8c, 0xa7, 0x04, 0x79, 0x7d, 0x6f, + 0xd0, 0x7d, 0xff, 0x26, 0xfc, 0x87, 0x5f, 0x6b, 0xee, 0xe8, 0xf0, 0x94, 0xa7, 0x64, 0x38, 0x9b, + 0x92, 0x48, 0x3f, 0xf1, 0x7d, 0x68, 0x56, 0xd3, 0x72, 0xa4, 0x47, 0x75, 0x22, 0xfd, 0x3b, 0x18, + 0x82, 0x5f, 0xf3, 0xbe, 0x6f, 0xdc, 0xdd, 0xdb, 0xf9, 0x77, 0x78, 0xe8, 0x54, 0x9d, 0xe4, 0x4b, + 0x00, 0xab, 0x70, 0x40, 0x99, 0x76, 0xbf, 0x19, 0xd5, 0x90, 0x5a, 0xff, 0x88, 0x54, 0xd6, 0x62, + 0x0d, 0x09, 0xfe, 0xac, 0xc1, 0x03, 0xa7, 0x79, 0x4e, 0xc7, 0x6c, 0x58, 0xdd, 0xed, 0x72, 0x0b, + 0xd6, 0x19, 0x67, 0x09, 0xd1, 0x52, 0x9b, 0x91, 0x29, 0xd4, 0x93, 0x31, 0x16, 0xf1, 0xb4, 0xa0, + 0x09, 0x41, 0x0d, 0xdd, 0x69, 0x8f, 0xb1, 0x38, 0x53, 0xb5, 0x6b, 0xe6, 0x74, 0x42, 0x25, 0x6a, + 0xce, 0x9b, 0x27, 0xaa, 0x56, 0x7a, 0x92, 0x2b, 0xeb, 0xeb, 0x46, 0x4f, 0x17, 0x06, 0x55, 0x86, + 0xbb, 0xda, 0xb0, 0x29, 0x14, 0x7a, 0x8d, 0xf3, 0x92, 0xa0, 0x0d, 0xc3, 0xd5, 0x85, 0xff, 0x16, + 0xfc, 0x14, 0x4b, 0x1c, 0x53, 0x46, 0x25, 0xc5, 0x79, 0x9c, 0x64, 0x25, 0xbb, 0x42, 0x2d, 0x4d, + 0x79, 0xa4, 0x3a, 0xc7, 0xa6, 0xf1, 0x49, 0xe1, 0xfe, 0x1e, 0x74, 0x35, 0x3b, 0x27, 0x6c, 0x2c, + 0x33, 0xd4, 0xee, 0x7b, 0x83, 0x5e, 0x04, 0x0a, 0x3a, 0xd1, 0x88, 0xff, 0x14, 0xda, 0x49, 0x86, + 0x29, 0x8b, 0x69, 0x8a, 0x3a, 0xba, 0xdb, 0xd2, 0xf5, 0x71, 0xea, 0xef, 0x40, 0x4b, 0x56, 0xb1, + 0x9c, 0x4d, 0x09, 0x02, 0xdd, 0xd9, 0x90, 0x95, 0xca, 0x41, 0xf0, 0xdb, 0x5b, 0x44, 0x6a, 0x58, + 0x45, 0xe4, 0x47, 0x49, 0x84, 0x5c, 0x1d, 0xe5, 0xdd, 0x1a, 0xb5, 0x07, 0x5d, 0x41, 0xc7, 0x0c, + 0xcb, 0xb2, 0x20, 0xf1, 0xb5, 0xbe, 0x68, 0x2f, 0x82, 0x39, 0x74, 0xb1, 0x4c, 0x28, 0xec, 0x61, + 0x17, 0x84, 0x68, 0x99, 0x20, 0xec, 0x71, 0x17, 0x84, 0xf3, 0x20, 0x84, 0xde, 0xc2, 0xd8, 0x7e, + 0x72, 0xe5, 0xbf, 0x00, 0xed, 0xc0, 0x5e, 0xc9, 0xe4, 0xa5, 0xa3, 0x10, 0x7d, 0x9e, 0xe0, 0x04, + 0x9e, 0xd4, 0xd3, 0xf0, 0xcd, 0x64, 0xff, 0xee, 0x48, 0x20, 0x68, 0xd9, 0xff, 0x88, 0x0d, 0x85, + 0x2b, 0x83, 0x0a, 0x90, 0x53, 0xb3, 0x4a, 0xe7, 0xce, 0xda, 0x7f, 0x83, 0xfb, 0x1c, 0x3a, 0xf3, + 0x3d, 0xac, 0xee, 0x02, 0x58, 0x89, 0x75, 0xe3, 0x56, 0xac, 0x7f, 0x79, 0xb0, 0xed, 0x46, 0x5f, + 0x90, 0x82, 0x5e, 0xce, 0xdc, 0x2a, 0xf7, 0x9b, 0x5b, 0xdb, 0xb5, 0xb1, 0xb4, 0xeb, 0x8a, 0xa3, + 0xe6, 0xaa, 0xa3, 0x83, 0x8f, 0xf0, 0x3a, 0xe1, 0x93, 0x50, 0x60, 0xc9, 0x45, 0x46, 0x73, 0x3c, + 0x12, 0xee, 0x03, 0x93, 0xd3, 0x91, 0xf9, 0xe2, 0x8d, 0xca, 0xcb, 0x83, 0xed, 0xa1, 0x06, 0xad, + 0x5b, 0xb7, 0xc2, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xce, 0x81, 0xc8, 0x59, 0x05, 0x00, + 0x00, +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.proto b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.proto new file mode 100644 index 00000000..096bed2e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-ethereum.proto @@ -0,0 +1,131 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.ethereum; + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessageEthereum"; + +import "messages-common.proto"; + + +/** + * Request: Ask device for public key corresponding to address_n path + * @start + * @next EthereumPublicKey + * @next Failure + */ +message EthereumGetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains public key derived from device private seed + * @end + */ +message EthereumPublicKey { + optional hw.trezor.messages.common.HDNodeType node = 1; // BIP32 public node + optional string xpub = 2; // serialized form of public node +} + +/** + * Request: Ask device for Ethereum address corresponding to address_n path + * @start + * @next EthereumAddress + * @next Failure + */ +message EthereumGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains an Ethereum address derived from device private seed + * @end + */ +message EthereumAddress { + optional bytes addressBin = 1; // Ethereum address as 20 bytes (legacy firmwares) + optional string addressHex = 2; // Ethereum address as hex string (newer firmwares) +} + +/** + * Request: Ask device to sign transaction + * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. + * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. + * @start + * @next EthereumTxRequest + * @next Failure + */ +message EthereumSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes nonce = 2; // <=256 bit unsigned big endian + optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) + optional bytes gas_limit = 4; // <=256 bit unsigned big endian + optional bytes toBin = 5; // recipient address (20 bytes, legacy firmware) + optional string toHex = 11; // recipient address (hex string, newer firmware) + optional bytes value = 6; // <=256 bit unsigned big endian (in wei) + optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) + optional uint32 data_length = 8; // Length of transaction payload + optional uint32 chain_id = 9; // Chain Id for EIP 155 + optional uint32 tx_type = 10; // (only for Wanchain) +} + +/** + * Response: Device asks for more data from transaction payload, or returns the signature. + * If data_length is set, device awaits that many more bytes of payload. + * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. + * @end + * @next EthereumTxAck + */ +message EthereumTxRequest { + optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) + optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) + optional bytes signature_r = 3; // Computed signature R component (256 bit) + optional bytes signature_s = 4; // Computed signature S component (256 bit) +} + +/** + * Request: Transaction payload data. + * @next EthereumTxRequest + */ +message EthereumTxAck { + optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) +} + +/** + * Request: Ask device to sign message + * @start + * @next EthereumMessageSignature + * @next Failure + */ +message EthereumSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes message = 2; // message to be signed +} + +/** + * Response: Signed message + * @end + */ +message EthereumMessageSignature { + optional bytes addressBin = 1; // address used to sign the message (20 bytes, legacy firmware) + optional bytes signature = 2; // signature of the message + optional string addressHex = 3; // address used to sign the message (hex string, newer firmware) +} + +/** + * Request: Ask device to verify message + * @start + * @next Success + * @next Failure + */ +message EthereumVerifyMessage { + optional bytes addressBin = 1; // address to verify (20 bytes, legacy firmware) + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify + optional string addressHex = 4; // address to verify (hex string, newer firmware) +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.pb.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.pb.go new file mode 100644 index 00000000..f5c872f1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.pb.go @@ -0,0 +1,1621 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-management.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Structure representing passphrase source +type ApplySettings_PassphraseSourceType int32 + +const ( + ApplySettings_ASK ApplySettings_PassphraseSourceType = 0 + ApplySettings_DEVICE ApplySettings_PassphraseSourceType = 1 + ApplySettings_HOST ApplySettings_PassphraseSourceType = 2 +) + +var ApplySettings_PassphraseSourceType_name = map[int32]string{ + 0: "ASK", + 1: "DEVICE", + 2: "HOST", +} + +var ApplySettings_PassphraseSourceType_value = map[string]int32{ + "ASK": 0, + "DEVICE": 1, + "HOST": 2, +} + +func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSourceType { + p := new(ApplySettings_PassphraseSourceType) + *p = x + return p +} + +func (x ApplySettings_PassphraseSourceType) String() string { + return proto.EnumName(ApplySettings_PassphraseSourceType_name, int32(x)) +} + +func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ApplySettings_PassphraseSourceType_value, data, "ApplySettings_PassphraseSourceType") + if err != nil { + return err + } + *x = ApplySettings_PassphraseSourceType(value) + return nil +} + +func (ApplySettings_PassphraseSourceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{4, 0} +} + +//* +// Type of recovery procedure. These should be used as bitmask, e.g., +// `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` +// listing every method supported by the host computer. +// +// Note that ScrambledWords must be supported by every implementation +// for backward compatibility; there is no way to not support it. +type RecoveryDevice_RecoveryDeviceType int32 + +const ( + // use powers of two when extending this field + RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 + RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 +) + +var RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ + 0: "RecoveryDeviceType_ScrambledWords", + 1: "RecoveryDeviceType_Matrix", +} + +var RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ + "RecoveryDeviceType_ScrambledWords": 0, + "RecoveryDeviceType_Matrix": 1, +} + +func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDeviceType { + p := new(RecoveryDevice_RecoveryDeviceType) + *p = x + return p +} + +func (x RecoveryDevice_RecoveryDeviceType) String() string { + return proto.EnumName(RecoveryDevice_RecoveryDeviceType_name, int32(x)) +} + +func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RecoveryDevice_RecoveryDeviceType_value, data, "RecoveryDevice_RecoveryDeviceType") + if err != nil { + return err + } + *x = RecoveryDevice_RecoveryDeviceType(value) + return nil +} + +func (RecoveryDevice_RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{17, 0} +} + +//* +// Type of Recovery Word request +type WordRequest_WordRequestType int32 + +const ( + WordRequest_WordRequestType_Plain WordRequest_WordRequestType = 0 + WordRequest_WordRequestType_Matrix9 WordRequest_WordRequestType = 1 + WordRequest_WordRequestType_Matrix6 WordRequest_WordRequestType = 2 +) + +var WordRequest_WordRequestType_name = map[int32]string{ + 0: "WordRequestType_Plain", + 1: "WordRequestType_Matrix9", + 2: "WordRequestType_Matrix6", +} + +var WordRequest_WordRequestType_value = map[string]int32{ + "WordRequestType_Plain": 0, + "WordRequestType_Matrix9": 1, + "WordRequestType_Matrix6": 2, +} + +func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { + p := new(WordRequest_WordRequestType) + *p = x + return p +} + +func (x WordRequest_WordRequestType) String() string { + return proto.EnumName(WordRequest_WordRequestType_name, int32(x)) +} + +func (x *WordRequest_WordRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(WordRequest_WordRequestType_value, data, "WordRequest_WordRequestType") + if err != nil { + return err + } + *x = WordRequest_WordRequestType(value) + return nil +} + +func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{18, 0} +} + +//* +// Request: Reset device to default state and ask for device details +// @start +// @next Features +type Initialize struct { + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` + SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Initialize) Reset() { *m = Initialize{} } +func (m *Initialize) String() string { return proto.CompactTextString(m) } +func (*Initialize) ProtoMessage() {} +func (*Initialize) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{0} +} + +func (m *Initialize) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Initialize.Unmarshal(m, b) +} +func (m *Initialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Initialize.Marshal(b, m, deterministic) +} +func (m *Initialize) XXX_Merge(src proto.Message) { + xxx_messageInfo_Initialize.Merge(m, src) +} +func (m *Initialize) XXX_Size() int { + return xxx_messageInfo_Initialize.Size(m) +} +func (m *Initialize) XXX_DiscardUnknown() { + xxx_messageInfo_Initialize.DiscardUnknown(m) +} + +var xxx_messageInfo_Initialize proto.InternalMessageInfo + +func (m *Initialize) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +func (m *Initialize) GetSkipPassphrase() bool { + if m != nil && m.SkipPassphrase != nil { + return *m.SkipPassphrase + } + return false +} + +//* +// Request: Ask for device details (no device reset) +// @start +// @next Features +type GetFeatures struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetFeatures) Reset() { *m = GetFeatures{} } +func (m *GetFeatures) String() string { return proto.CompactTextString(m) } +func (*GetFeatures) ProtoMessage() {} +func (*GetFeatures) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{1} +} + +func (m *GetFeatures) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetFeatures.Unmarshal(m, b) +} +func (m *GetFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetFeatures.Marshal(b, m, deterministic) +} +func (m *GetFeatures) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetFeatures.Merge(m, src) +} +func (m *GetFeatures) XXX_Size() int { + return xxx_messageInfo_GetFeatures.Size(m) +} +func (m *GetFeatures) XXX_DiscardUnknown() { + xxx_messageInfo_GetFeatures.DiscardUnknown(m) +} + +var xxx_messageInfo_GetFeatures proto.InternalMessageInfo + +//* +// Response: Reports various information about the device +// @end +type Features struct { + Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` + MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` + MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` + PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` + BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` + DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` + PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` + Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` + Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` + BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` + Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` + PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` + PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` + FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` + NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` + Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` + Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` + FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` + FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` + FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` + FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` + FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` + UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` + NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Features) Reset() { *m = Features{} } +func (m *Features) String() string { return proto.CompactTextString(m) } +func (*Features) ProtoMessage() {} +func (*Features) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{2} +} + +func (m *Features) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Features.Unmarshal(m, b) +} +func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Features.Marshal(b, m, deterministic) +} +func (m *Features) XXX_Merge(src proto.Message) { + xxx_messageInfo_Features.Merge(m, src) +} +func (m *Features) XXX_Size() int { + return xxx_messageInfo_Features.Size(m) +} +func (m *Features) XXX_DiscardUnknown() { + xxx_messageInfo_Features.DiscardUnknown(m) +} + +var xxx_messageInfo_Features proto.InternalMessageInfo + +func (m *Features) GetVendor() string { + if m != nil && m.Vendor != nil { + return *m.Vendor + } + return "" +} + +func (m *Features) GetMajorVersion() uint32 { + if m != nil && m.MajorVersion != nil { + return *m.MajorVersion + } + return 0 +} + +func (m *Features) GetMinorVersion() uint32 { + if m != nil && m.MinorVersion != nil { + return *m.MinorVersion + } + return 0 +} + +func (m *Features) GetPatchVersion() uint32 { + if m != nil && m.PatchVersion != nil { + return *m.PatchVersion + } + return 0 +} + +func (m *Features) GetBootloaderMode() bool { + if m != nil && m.BootloaderMode != nil { + return *m.BootloaderMode + } + return false +} + +func (m *Features) GetDeviceId() string { + if m != nil && m.DeviceId != nil { + return *m.DeviceId + } + return "" +} + +func (m *Features) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *Features) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *Features) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return "" +} + +func (m *Features) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *Features) GetInitialized() bool { + if m != nil && m.Initialized != nil { + return *m.Initialized + } + return false +} + +func (m *Features) GetRevision() []byte { + if m != nil { + return m.Revision + } + return nil +} + +func (m *Features) GetBootloaderHash() []byte { + if m != nil { + return m.BootloaderHash + } + return nil +} + +func (m *Features) GetImported() bool { + if m != nil && m.Imported != nil { + return *m.Imported + } + return false +} + +func (m *Features) GetPinCached() bool { + if m != nil && m.PinCached != nil { + return *m.PinCached + } + return false +} + +func (m *Features) GetPassphraseCached() bool { + if m != nil && m.PassphraseCached != nil { + return *m.PassphraseCached + } + return false +} + +func (m *Features) GetFirmwarePresent() bool { + if m != nil && m.FirmwarePresent != nil { + return *m.FirmwarePresent + } + return false +} + +func (m *Features) GetNeedsBackup() bool { + if m != nil && m.NeedsBackup != nil { + return *m.NeedsBackup + } + return false +} + +func (m *Features) GetFlags() uint32 { + if m != nil && m.Flags != nil { + return *m.Flags + } + return 0 +} + +func (m *Features) GetModel() string { + if m != nil && m.Model != nil { + return *m.Model + } + return "" +} + +func (m *Features) GetFwMajor() uint32 { + if m != nil && m.FwMajor != nil { + return *m.FwMajor + } + return 0 +} + +func (m *Features) GetFwMinor() uint32 { + if m != nil && m.FwMinor != nil { + return *m.FwMinor + } + return 0 +} + +func (m *Features) GetFwPatch() uint32 { + if m != nil && m.FwPatch != nil { + return *m.FwPatch + } + return 0 +} + +func (m *Features) GetFwVendor() string { + if m != nil && m.FwVendor != nil { + return *m.FwVendor + } + return "" +} + +func (m *Features) GetFwVendorKeys() []byte { + if m != nil { + return m.FwVendorKeys + } + return nil +} + +func (m *Features) GetUnfinishedBackup() bool { + if m != nil && m.UnfinishedBackup != nil { + return *m.UnfinishedBackup + } + return false +} + +func (m *Features) GetNoBackup() bool { + if m != nil && m.NoBackup != nil { + return *m.NoBackup + } + return false +} + +//* +// Request: clear session (removes cached PIN, passphrase, etc). +// @start +// @next Success +type ClearSession struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClearSession) Reset() { *m = ClearSession{} } +func (m *ClearSession) String() string { return proto.CompactTextString(m) } +func (*ClearSession) ProtoMessage() {} +func (*ClearSession) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{3} +} + +func (m *ClearSession) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClearSession.Unmarshal(m, b) +} +func (m *ClearSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClearSession.Marshal(b, m, deterministic) +} +func (m *ClearSession) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClearSession.Merge(m, src) +} +func (m *ClearSession) XXX_Size() int { + return xxx_messageInfo_ClearSession.Size(m) +} +func (m *ClearSession) XXX_DiscardUnknown() { + xxx_messageInfo_ClearSession.DiscardUnknown(m) +} + +var xxx_messageInfo_ClearSession proto.InternalMessageInfo + +//* +// Request: change language and/or label of the device +// @start +// @next Success +// @next Failure +type ApplySettings struct { + Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` + UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` + Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` + PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` + AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` + DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplySettings) Reset() { *m = ApplySettings{} } +func (m *ApplySettings) String() string { return proto.CompactTextString(m) } +func (*ApplySettings) ProtoMessage() {} +func (*ApplySettings) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{4} +} + +func (m *ApplySettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApplySettings.Unmarshal(m, b) +} +func (m *ApplySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApplySettings.Marshal(b, m, deterministic) +} +func (m *ApplySettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplySettings.Merge(m, src) +} +func (m *ApplySettings) XXX_Size() int { + return xxx_messageInfo_ApplySettings.Size(m) +} +func (m *ApplySettings) XXX_DiscardUnknown() { + xxx_messageInfo_ApplySettings.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplySettings proto.InternalMessageInfo + +func (m *ApplySettings) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return "" +} + +func (m *ApplySettings) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *ApplySettings) GetUsePassphrase() bool { + if m != nil && m.UsePassphrase != nil { + return *m.UsePassphrase + } + return false +} + +func (m *ApplySettings) GetHomescreen() []byte { + if m != nil { + return m.Homescreen + } + return nil +} + +func (m *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { + if m != nil && m.PassphraseSource != nil { + return *m.PassphraseSource + } + return ApplySettings_ASK +} + +func (m *ApplySettings) GetAutoLockDelayMs() uint32 { + if m != nil && m.AutoLockDelayMs != nil { + return *m.AutoLockDelayMs + } + return 0 +} + +func (m *ApplySettings) GetDisplayRotation() uint32 { + if m != nil && m.DisplayRotation != nil { + return *m.DisplayRotation + } + return 0 +} + +//* +// Request: set flags of the device +// @start +// @next Success +// @next Failure +type ApplyFlags struct { + Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } +func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } +func (*ApplyFlags) ProtoMessage() {} +func (*ApplyFlags) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{5} +} + +func (m *ApplyFlags) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApplyFlags.Unmarshal(m, b) +} +func (m *ApplyFlags) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApplyFlags.Marshal(b, m, deterministic) +} +func (m *ApplyFlags) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplyFlags.Merge(m, src) +} +func (m *ApplyFlags) XXX_Size() int { + return xxx_messageInfo_ApplyFlags.Size(m) +} +func (m *ApplyFlags) XXX_DiscardUnknown() { + xxx_messageInfo_ApplyFlags.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplyFlags proto.InternalMessageInfo + +func (m *ApplyFlags) GetFlags() uint32 { + if m != nil && m.Flags != nil { + return *m.Flags + } + return 0 +} + +//* +// Request: Starts workflow for setting/changing/removing the PIN +// @start +// @next Success +// @next Failure +type ChangePin struct { + Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangePin) Reset() { *m = ChangePin{} } +func (m *ChangePin) String() string { return proto.CompactTextString(m) } +func (*ChangePin) ProtoMessage() {} +func (*ChangePin) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{6} +} + +func (m *ChangePin) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ChangePin.Unmarshal(m, b) +} +func (m *ChangePin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ChangePin.Marshal(b, m, deterministic) +} +func (m *ChangePin) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangePin.Merge(m, src) +} +func (m *ChangePin) XXX_Size() int { + return xxx_messageInfo_ChangePin.Size(m) +} +func (m *ChangePin) XXX_DiscardUnknown() { + xxx_messageInfo_ChangePin.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangePin proto.InternalMessageInfo + +func (m *ChangePin) GetRemove() bool { + if m != nil && m.Remove != nil { + return *m.Remove + } + return false +} + +//* +// Request: Test if the device is alive, device sends back the message in Success response +// @start +// @next Success +type Ping struct { + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ping) Reset() { *m = Ping{} } +func (m *Ping) String() string { return proto.CompactTextString(m) } +func (*Ping) ProtoMessage() {} +func (*Ping) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{7} +} + +func (m *Ping) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ping.Unmarshal(m, b) +} +func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ping.Marshal(b, m, deterministic) +} +func (m *Ping) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ping.Merge(m, src) +} +func (m *Ping) XXX_Size() int { + return xxx_messageInfo_Ping.Size(m) +} +func (m *Ping) XXX_DiscardUnknown() { + xxx_messageInfo_Ping.DiscardUnknown(m) +} + +var xxx_messageInfo_Ping proto.InternalMessageInfo + +func (m *Ping) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +func (m *Ping) GetButtonProtection() bool { + if m != nil && m.ButtonProtection != nil { + return *m.ButtonProtection + } + return false +} + +func (m *Ping) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *Ping) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +//* +// Request: Abort last operation that required user interaction +// @start +// @next Failure +type Cancel struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Cancel) Reset() { *m = Cancel{} } +func (m *Cancel) String() string { return proto.CompactTextString(m) } +func (*Cancel) ProtoMessage() {} +func (*Cancel) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{8} +} + +func (m *Cancel) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Cancel.Unmarshal(m, b) +} +func (m *Cancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Cancel.Marshal(b, m, deterministic) +} +func (m *Cancel) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cancel.Merge(m, src) +} +func (m *Cancel) XXX_Size() int { + return xxx_messageInfo_Cancel.Size(m) +} +func (m *Cancel) XXX_DiscardUnknown() { + xxx_messageInfo_Cancel.DiscardUnknown(m) +} + +var xxx_messageInfo_Cancel proto.InternalMessageInfo + +//* +// Request: Request a sample of random data generated by hardware RNG. May be used for testing. +// @start +// @next Entropy +// @next Failure +type GetEntropy struct { + Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetEntropy) Reset() { *m = GetEntropy{} } +func (m *GetEntropy) String() string { return proto.CompactTextString(m) } +func (*GetEntropy) ProtoMessage() {} +func (*GetEntropy) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{9} +} + +func (m *GetEntropy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetEntropy.Unmarshal(m, b) +} +func (m *GetEntropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetEntropy.Marshal(b, m, deterministic) +} +func (m *GetEntropy) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetEntropy.Merge(m, src) +} +func (m *GetEntropy) XXX_Size() int { + return xxx_messageInfo_GetEntropy.Size(m) +} +func (m *GetEntropy) XXX_DiscardUnknown() { + xxx_messageInfo_GetEntropy.DiscardUnknown(m) +} + +var xxx_messageInfo_GetEntropy proto.InternalMessageInfo + +func (m *GetEntropy) GetSize() uint32 { + if m != nil && m.Size != nil { + return *m.Size + } + return 0 +} + +//* +// Response: Reply with random data generated by internal RNG +// @end +type Entropy struct { + Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Entropy) Reset() { *m = Entropy{} } +func (m *Entropy) String() string { return proto.CompactTextString(m) } +func (*Entropy) ProtoMessage() {} +func (*Entropy) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{10} +} + +func (m *Entropy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Entropy.Unmarshal(m, b) +} +func (m *Entropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Entropy.Marshal(b, m, deterministic) +} +func (m *Entropy) XXX_Merge(src proto.Message) { + xxx_messageInfo_Entropy.Merge(m, src) +} +func (m *Entropy) XXX_Size() int { + return xxx_messageInfo_Entropy.Size(m) +} +func (m *Entropy) XXX_DiscardUnknown() { + xxx_messageInfo_Entropy.DiscardUnknown(m) +} + +var xxx_messageInfo_Entropy proto.InternalMessageInfo + +func (m *Entropy) GetEntropy() []byte { + if m != nil { + return m.Entropy + } + return nil +} + +//* +// Request: Request device to wipe all sensitive data and settings +// @start +// @next Success +// @next Failure +type WipeDevice struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WipeDevice) Reset() { *m = WipeDevice{} } +func (m *WipeDevice) String() string { return proto.CompactTextString(m) } +func (*WipeDevice) ProtoMessage() {} +func (*WipeDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{11} +} + +func (m *WipeDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WipeDevice.Unmarshal(m, b) +} +func (m *WipeDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WipeDevice.Marshal(b, m, deterministic) +} +func (m *WipeDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_WipeDevice.Merge(m, src) +} +func (m *WipeDevice) XXX_Size() int { + return xxx_messageInfo_WipeDevice.Size(m) +} +func (m *WipeDevice) XXX_DiscardUnknown() { + xxx_messageInfo_WipeDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_WipeDevice proto.InternalMessageInfo + +//* +// Request: Load seed and related internal settings from the computer +// @start +// @next Success +// @next Failure +type LoadDevice struct { + Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` + Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` + Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` + SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` + U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LoadDevice) Reset() { *m = LoadDevice{} } +func (m *LoadDevice) String() string { return proto.CompactTextString(m) } +func (*LoadDevice) ProtoMessage() {} +func (*LoadDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{12} +} + +func (m *LoadDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LoadDevice.Unmarshal(m, b) +} +func (m *LoadDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LoadDevice.Marshal(b, m, deterministic) +} +func (m *LoadDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_LoadDevice.Merge(m, src) +} +func (m *LoadDevice) XXX_Size() int { + return xxx_messageInfo_LoadDevice.Size(m) +} +func (m *LoadDevice) XXX_DiscardUnknown() { + xxx_messageInfo_LoadDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_LoadDevice proto.InternalMessageInfo + +const Default_LoadDevice_Language string = "english" + +func (m *LoadDevice) GetMnemonic() string { + if m != nil && m.Mnemonic != nil { + return *m.Mnemonic + } + return "" +} + +func (m *LoadDevice) GetNode() *HDNodeType { + if m != nil { + return m.Node + } + return nil +} + +func (m *LoadDevice) GetPin() string { + if m != nil && m.Pin != nil { + return *m.Pin + } + return "" +} + +func (m *LoadDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *LoadDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_LoadDevice_Language +} + +func (m *LoadDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *LoadDevice) GetSkipChecksum() bool { + if m != nil && m.SkipChecksum != nil { + return *m.SkipChecksum + } + return false +} + +func (m *LoadDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +//* +// Request: Ask device to do initialization involving user interaction +// @start +// @next EntropyRequest +// @next Failure +type ResetDevice struct { + DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` + Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` + PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` + U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` + NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResetDevice) Reset() { *m = ResetDevice{} } +func (m *ResetDevice) String() string { return proto.CompactTextString(m) } +func (*ResetDevice) ProtoMessage() {} +func (*ResetDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{13} +} + +func (m *ResetDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResetDevice.Unmarshal(m, b) +} +func (m *ResetDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResetDevice.Marshal(b, m, deterministic) +} +func (m *ResetDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetDevice.Merge(m, src) +} +func (m *ResetDevice) XXX_Size() int { + return xxx_messageInfo_ResetDevice.Size(m) +} +func (m *ResetDevice) XXX_DiscardUnknown() { + xxx_messageInfo_ResetDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_ResetDevice proto.InternalMessageInfo + +const Default_ResetDevice_Strength uint32 = 256 +const Default_ResetDevice_Language string = "english" + +func (m *ResetDevice) GetDisplayRandom() bool { + if m != nil && m.DisplayRandom != nil { + return *m.DisplayRandom + } + return false +} + +func (m *ResetDevice) GetStrength() uint32 { + if m != nil && m.Strength != nil { + return *m.Strength + } + return Default_ResetDevice_Strength +} + +func (m *ResetDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *ResetDevice) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *ResetDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_ResetDevice_Language +} + +func (m *ResetDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *ResetDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func (m *ResetDevice) GetSkipBackup() bool { + if m != nil && m.SkipBackup != nil { + return *m.SkipBackup + } + return false +} + +func (m *ResetDevice) GetNoBackup() bool { + if m != nil && m.NoBackup != nil { + return *m.NoBackup + } + return false +} + +//* +// Request: Perform backup of the device seed if not backed up using ResetDevice +// @start +// @next Success +type BackupDevice struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BackupDevice) Reset() { *m = BackupDevice{} } +func (m *BackupDevice) String() string { return proto.CompactTextString(m) } +func (*BackupDevice) ProtoMessage() {} +func (*BackupDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{14} +} + +func (m *BackupDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BackupDevice.Unmarshal(m, b) +} +func (m *BackupDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BackupDevice.Marshal(b, m, deterministic) +} +func (m *BackupDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupDevice.Merge(m, src) +} +func (m *BackupDevice) XXX_Size() int { + return xxx_messageInfo_BackupDevice.Size(m) +} +func (m *BackupDevice) XXX_DiscardUnknown() { + xxx_messageInfo_BackupDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_BackupDevice proto.InternalMessageInfo + +//* +// Response: Ask for additional entropy from host computer +// @next EntropyAck +type EntropyRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } +func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } +func (*EntropyRequest) ProtoMessage() {} +func (*EntropyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{15} +} + +func (m *EntropyRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntropyRequest.Unmarshal(m, b) +} +func (m *EntropyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntropyRequest.Marshal(b, m, deterministic) +} +func (m *EntropyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntropyRequest.Merge(m, src) +} +func (m *EntropyRequest) XXX_Size() int { + return xxx_messageInfo_EntropyRequest.Size(m) +} +func (m *EntropyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EntropyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo + +//* +// Request: Provide additional entropy for seed generation function +// @next Success +type EntropyAck struct { + Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntropyAck) Reset() { *m = EntropyAck{} } +func (m *EntropyAck) String() string { return proto.CompactTextString(m) } +func (*EntropyAck) ProtoMessage() {} +func (*EntropyAck) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{16} +} + +func (m *EntropyAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntropyAck.Unmarshal(m, b) +} +func (m *EntropyAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntropyAck.Marshal(b, m, deterministic) +} +func (m *EntropyAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntropyAck.Merge(m, src) +} +func (m *EntropyAck) XXX_Size() int { + return xxx_messageInfo_EntropyAck.Size(m) +} +func (m *EntropyAck) XXX_DiscardUnknown() { + xxx_messageInfo_EntropyAck.DiscardUnknown(m) +} + +var xxx_messageInfo_EntropyAck proto.InternalMessageInfo + +func (m *EntropyAck) GetEntropy() []byte { + if m != nil { + return m.Entropy + } + return nil +} + +//* +// Request: Start recovery workflow asking user for specific words of mnemonic +// Used to recovery device safely even on untrusted computer. +// @start +// @next WordRequest +type RecoveryDevice struct { + WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` + PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` + EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` + // 7 reserved for unused recovery method + Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` + U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } +func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } +func (*RecoveryDevice) ProtoMessage() {} +func (*RecoveryDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{17} +} + +func (m *RecoveryDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RecoveryDevice.Unmarshal(m, b) +} +func (m *RecoveryDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RecoveryDevice.Marshal(b, m, deterministic) +} +func (m *RecoveryDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_RecoveryDevice.Merge(m, src) +} +func (m *RecoveryDevice) XXX_Size() int { + return xxx_messageInfo_RecoveryDevice.Size(m) +} +func (m *RecoveryDevice) XXX_DiscardUnknown() { + xxx_messageInfo_RecoveryDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_RecoveryDevice proto.InternalMessageInfo + +const Default_RecoveryDevice_Language string = "english" + +func (m *RecoveryDevice) GetWordCount() uint32 { + if m != nil && m.WordCount != nil { + return *m.WordCount + } + return 0 +} + +func (m *RecoveryDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *RecoveryDevice) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *RecoveryDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_RecoveryDevice_Language +} + +func (m *RecoveryDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *RecoveryDevice) GetEnforceWordlist() bool { + if m != nil && m.EnforceWordlist != nil { + return *m.EnforceWordlist + } + return false +} + +func (m *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { + if m != nil && m.Type != nil { + return *m.Type + } + return RecoveryDevice_RecoveryDeviceType_ScrambledWords +} + +func (m *RecoveryDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func (m *RecoveryDevice) GetDryRun() bool { + if m != nil && m.DryRun != nil { + return *m.DryRun + } + return false +} + +//* +// Response: Device is waiting for user to enter word of the mnemonic +// Its position is shown only on device's internal display. +// @next WordAck +type WordRequest struct { + Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WordRequest) Reset() { *m = WordRequest{} } +func (m *WordRequest) String() string { return proto.CompactTextString(m) } +func (*WordRequest) ProtoMessage() {} +func (*WordRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{18} +} + +func (m *WordRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WordRequest.Unmarshal(m, b) +} +func (m *WordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WordRequest.Marshal(b, m, deterministic) +} +func (m *WordRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WordRequest.Merge(m, src) +} +func (m *WordRequest) XXX_Size() int { + return xxx_messageInfo_WordRequest.Size(m) +} +func (m *WordRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WordRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WordRequest proto.InternalMessageInfo + +func (m *WordRequest) GetType() WordRequest_WordRequestType { + if m != nil && m.Type != nil { + return *m.Type + } + return WordRequest_WordRequestType_Plain +} + +//* +// Request: Computer replies with word from the mnemonic +// @next WordRequest +// @next Success +// @next Failure +type WordAck struct { + Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WordAck) Reset() { *m = WordAck{} } +func (m *WordAck) String() string { return proto.CompactTextString(m) } +func (*WordAck) ProtoMessage() {} +func (*WordAck) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{19} +} + +func (m *WordAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WordAck.Unmarshal(m, b) +} +func (m *WordAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WordAck.Marshal(b, m, deterministic) +} +func (m *WordAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_WordAck.Merge(m, src) +} +func (m *WordAck) XXX_Size() int { + return xxx_messageInfo_WordAck.Size(m) +} +func (m *WordAck) XXX_DiscardUnknown() { + xxx_messageInfo_WordAck.DiscardUnknown(m) +} + +var xxx_messageInfo_WordAck proto.InternalMessageInfo + +func (m *WordAck) GetWord() string { + if m != nil && m.Word != nil { + return *m.Word + } + return "" +} + +//* +// Request: Set U2F counter +// @start +// @next Success +type SetU2FCounter struct { + U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } +func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } +func (*SetU2FCounter) ProtoMessage() {} +func (*SetU2FCounter) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{20} +} + +func (m *SetU2FCounter) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetU2FCounter.Unmarshal(m, b) +} +func (m *SetU2FCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetU2FCounter.Marshal(b, m, deterministic) +} +func (m *SetU2FCounter) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetU2FCounter.Merge(m, src) +} +func (m *SetU2FCounter) XXX_Size() int { + return xxx_messageInfo_SetU2FCounter.Size(m) +} +func (m *SetU2FCounter) XXX_DiscardUnknown() { + xxx_messageInfo_SetU2FCounter.DiscardUnknown(m) +} + +var xxx_messageInfo_SetU2FCounter proto.InternalMessageInfo + +func (m *SetU2FCounter) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func init() { + proto.RegisterEnum("hw.trezor.messages.management.ApplySettings_PassphraseSourceType", ApplySettings_PassphraseSourceType_name, ApplySettings_PassphraseSourceType_value) + proto.RegisterEnum("hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType", RecoveryDevice_RecoveryDeviceType_name, RecoveryDevice_RecoveryDeviceType_value) + proto.RegisterEnum("hw.trezor.messages.management.WordRequest_WordRequestType", WordRequest_WordRequestType_name, WordRequest_WordRequestType_value) + proto.RegisterType((*Initialize)(nil), "hw.trezor.messages.management.Initialize") + proto.RegisterType((*GetFeatures)(nil), "hw.trezor.messages.management.GetFeatures") + proto.RegisterType((*Features)(nil), "hw.trezor.messages.management.Features") + proto.RegisterType((*ClearSession)(nil), "hw.trezor.messages.management.ClearSession") + proto.RegisterType((*ApplySettings)(nil), "hw.trezor.messages.management.ApplySettings") + proto.RegisterType((*ApplyFlags)(nil), "hw.trezor.messages.management.ApplyFlags") + proto.RegisterType((*ChangePin)(nil), "hw.trezor.messages.management.ChangePin") + proto.RegisterType((*Ping)(nil), "hw.trezor.messages.management.Ping") + proto.RegisterType((*Cancel)(nil), "hw.trezor.messages.management.Cancel") + proto.RegisterType((*GetEntropy)(nil), "hw.trezor.messages.management.GetEntropy") + proto.RegisterType((*Entropy)(nil), "hw.trezor.messages.management.Entropy") + proto.RegisterType((*WipeDevice)(nil), "hw.trezor.messages.management.WipeDevice") + proto.RegisterType((*LoadDevice)(nil), "hw.trezor.messages.management.LoadDevice") + proto.RegisterType((*ResetDevice)(nil), "hw.trezor.messages.management.ResetDevice") + proto.RegisterType((*BackupDevice)(nil), "hw.trezor.messages.management.BackupDevice") + proto.RegisterType((*EntropyRequest)(nil), "hw.trezor.messages.management.EntropyRequest") + proto.RegisterType((*EntropyAck)(nil), "hw.trezor.messages.management.EntropyAck") + proto.RegisterType((*RecoveryDevice)(nil), "hw.trezor.messages.management.RecoveryDevice") + proto.RegisterType((*WordRequest)(nil), "hw.trezor.messages.management.WordRequest") + proto.RegisterType((*WordAck)(nil), "hw.trezor.messages.management.WordAck") + proto.RegisterType((*SetU2FCounter)(nil), "hw.trezor.messages.management.SetU2FCounter") +} + +func init() { proto.RegisterFile("messages-management.proto", fileDescriptor_0c720c20d27aa029) } + +var fileDescriptor_0c720c20d27aa029 = []byte{ + // 1393 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xdd, 0x6e, 0xdb, 0xc8, + 0x15, 0x8e, 0x7e, 0x62, 0x49, 0xc7, 0xfa, 0xcb, 0xd4, 0x8e, 0xe9, 0xb8, 0x6e, 0x1c, 0xba, 0x6e, + 0x12, 0x04, 0x15, 0x0a, 0x17, 0x09, 0x90, 0x5c, 0x14, 0x75, 0xec, 0xfc, 0x21, 0x71, 0x6a, 0xd0, + 0x6e, 0x02, 0xf4, 0x86, 0x18, 0x91, 0x47, 0xd2, 0xd4, 0xe4, 0x0c, 0xcb, 0x19, 0xda, 0x55, 0x5e, + 0x60, 0x6f, 0xf6, 0x45, 0x16, 0xfb, 0x1c, 0x7b, 0xb5, 0xcf, 0xb0, 0xef, 0xb2, 0x98, 0x19, 0x52, + 0xa2, 0x65, 0x3b, 0x46, 0x76, 0xef, 0xe6, 0x7c, 0xe7, 0xe3, 0x68, 0xce, 0x77, 0xbe, 0x39, 0x63, + 0xc3, 0x7a, 0x8c, 0x52, 0xd2, 0x31, 0xca, 0xbf, 0xc6, 0x94, 0xd3, 0x31, 0xc6, 0xc8, 0xd5, 0x20, + 0x49, 0x85, 0x12, 0x64, 0x73, 0x72, 0x3e, 0x50, 0x29, 0x7e, 0x11, 0xe9, 0xa0, 0x20, 0x0d, 0xe6, + 0xa4, 0x7b, 0xab, 0xb3, 0x2f, 0x03, 0x11, 0xc7, 0x82, 0xdb, 0xaf, 0xdc, 0xf7, 0x00, 0xef, 0x38, + 0x53, 0x8c, 0x46, 0xec, 0x0b, 0x92, 0x15, 0xb8, 0x2d, 0x15, 0x55, 0xe8, 0x54, 0xb6, 0x2a, 0x8f, + 0xda, 0x9e, 0x0d, 0xc8, 0x43, 0xe8, 0xc9, 0x53, 0x96, 0xf8, 0x09, 0x95, 0x32, 0x99, 0xa4, 0x54, + 0xa2, 0x53, 0xdd, 0xaa, 0x3c, 0x6a, 0x7a, 0x5d, 0x0d, 0x1f, 0xcd, 0x50, 0xb7, 0x03, 0xcb, 0x6f, + 0x50, 0xbd, 0x46, 0xaa, 0xb2, 0x14, 0xa5, 0xfb, 0x7d, 0x03, 0x9a, 0x45, 0x40, 0xee, 0xc2, 0xd2, + 0x19, 0xf2, 0x50, 0xa4, 0x66, 0xef, 0x96, 0x97, 0x47, 0x64, 0x1b, 0x3a, 0x31, 0xfd, 0xaf, 0x48, + 0xfd, 0x33, 0x4c, 0x25, 0x13, 0xdc, 0x6c, 0xdd, 0xf1, 0xda, 0x06, 0xfc, 0x64, 0x31, 0x43, 0x62, + 0xbc, 0x44, 0xaa, 0xe5, 0x24, 0x0d, 0x96, 0x48, 0x09, 0x55, 0xc1, 0x64, 0x46, 0xaa, 0x5b, 0x92, + 0x01, 0x0b, 0xd2, 0x43, 0xe8, 0x0d, 0x85, 0x50, 0x91, 0xa0, 0x21, 0xa6, 0x7e, 0x2c, 0x42, 0x74, + 0x6e, 0xdb, 0x5a, 0xe6, 0xf0, 0xa1, 0x08, 0x91, 0x6c, 0x40, 0x2b, 0xc4, 0x33, 0x16, 0xa0, 0xcf, + 0x42, 0x67, 0xc9, 0x1c, 0xb9, 0x69, 0x81, 0x77, 0x21, 0xd9, 0x81, 0x6e, 0xc2, 0xb8, 0xaf, 0x25, + 0xc4, 0x40, 0xe9, 0xdf, 0x6a, 0x98, 0x4d, 0x3a, 0x09, 0xe3, 0x47, 0x33, 0x90, 0xfc, 0x1d, 0x56, + 0xe7, 0x9a, 0x95, 0xd9, 0x4d, 0xc3, 0x5e, 0x99, 0x27, 0x4b, 0x1f, 0xdd, 0x83, 0x66, 0x44, 0xf9, + 0x38, 0xa3, 0x63, 0x74, 0x5a, 0xf6, 0x77, 0x8b, 0x58, 0xf7, 0x27, 0xa2, 0x43, 0x8c, 0x1c, 0x30, + 0x09, 0x1b, 0x90, 0x2d, 0x58, 0x66, 0xb3, 0x1e, 0x86, 0x4e, 0xdb, 0x6c, 0x5e, 0x86, 0xf4, 0x9e, + 0x29, 0x9e, 0x31, 0xa3, 0x4a, 0xc7, 0xb4, 0x76, 0x16, 0x2f, 0x28, 0x32, 0xa1, 0x72, 0xe2, 0x74, + 0x0d, 0xa5, 0xa4, 0xc8, 0x5b, 0x2a, 0x27, 0x7a, 0x13, 0x16, 0x27, 0x22, 0x55, 0x18, 0x3a, 0x3d, + 0xf3, 0x1b, 0xb3, 0x98, 0x6c, 0x02, 0x68, 0x41, 0x02, 0x1a, 0x4c, 0x30, 0x74, 0xfa, 0x26, 0xdb, + 0x4a, 0x18, 0xdf, 0x37, 0x00, 0x79, 0x02, 0x77, 0x4a, 0x42, 0xe4, 0xac, 0x3b, 0x86, 0xd5, 0x9f, + 0x27, 0x72, 0xf2, 0x63, 0xe8, 0x8f, 0x58, 0x1a, 0x9f, 0xd3, 0x54, 0x6b, 0x86, 0x12, 0xb9, 0x72, + 0x88, 0xe1, 0xf6, 0x0a, 0xfc, 0xc8, 0xc2, 0xe4, 0x01, 0xb4, 0x39, 0x62, 0x28, 0xfd, 0x21, 0x0d, + 0x4e, 0xb3, 0xc4, 0xf9, 0x83, 0x2d, 0xdd, 0x60, 0x2f, 0x0d, 0xa4, 0x25, 0x1b, 0x45, 0x74, 0x2c, + 0x9d, 0x15, 0xe3, 0x06, 0x1b, 0x68, 0x54, 0xf7, 0x3e, 0x72, 0x56, 0xad, 0x90, 0x26, 0x20, 0xeb, + 0xd0, 0x1c, 0x9d, 0xfb, 0xc6, 0x79, 0xce, 0x5d, 0x43, 0x6f, 0x8c, 0xce, 0x0f, 0x75, 0x58, 0xa4, + 0xb4, 0xdf, 0x9c, 0xb5, 0x59, 0x4a, 0x87, 0x79, 0xca, 0xb8, 0xcc, 0x71, 0x8a, 0xd4, 0x91, 0x0e, + 0xb5, 0x89, 0x46, 0xe7, 0x7e, 0xee, 0xfb, 0x75, 0xdb, 0xcc, 0xd1, 0xf9, 0x27, 0xeb, 0xfc, 0x3f, + 0x43, 0x77, 0x96, 0xf4, 0x4f, 0x71, 0x2a, 0x9d, 0x7b, 0x46, 0xf7, 0x76, 0xc1, 0x78, 0x8f, 0x53, + 0xa9, 0xa5, 0xcb, 0xf8, 0x88, 0x71, 0x26, 0x27, 0x18, 0x16, 0x75, 0x6e, 0x58, 0xe9, 0xe6, 0x89, + 0xbc, 0xd8, 0x0d, 0x68, 0x71, 0x51, 0x90, 0xfe, 0x68, 0x7b, 0xc4, 0x85, 0x4d, 0xba, 0x5d, 0x68, + 0xef, 0x47, 0x48, 0xd3, 0x63, 0x94, 0xba, 0xf1, 0xee, 0x77, 0x35, 0xe8, 0xec, 0x25, 0x49, 0x34, + 0x3d, 0x46, 0xa5, 0x18, 0x1f, 0xcb, 0x0b, 0xd6, 0xab, 0x5c, 0x67, 0xbd, 0x6a, 0xd9, 0x7a, 0x3b, + 0xd0, 0xcd, 0xb4, 0xb5, 0xe7, 0x93, 0xa1, 0x66, 0x2f, 0x42, 0x26, 0x71, 0x3e, 0x18, 0xc8, 0x9f, + 0x00, 0x26, 0x22, 0x46, 0x19, 0xa4, 0x88, 0xf6, 0x5e, 0xb6, 0xbd, 0x12, 0x42, 0xf8, 0x05, 0x7f, + 0x48, 0x91, 0xa5, 0x81, 0xbd, 0x97, 0xdd, 0xdd, 0xbd, 0xc1, 0x57, 0xe7, 0xda, 0xe0, 0x42, 0x05, + 0x83, 0xf9, 0x6f, 0x1e, 0x9b, 0x4d, 0x4e, 0xa6, 0x09, 0x96, 0x2d, 0x66, 0x51, 0xf2, 0x04, 0x08, + 0xcd, 0x94, 0xf0, 0x23, 0x11, 0x9c, 0xfa, 0x21, 0x46, 0x74, 0xea, 0xc7, 0xd2, 0xdc, 0xf2, 0x8e, + 0xd7, 0xd3, 0x99, 0x0f, 0x22, 0x38, 0x3d, 0xd0, 0xf8, 0xa1, 0xd4, 0x7e, 0x0c, 0x99, 0x4c, 0x34, + 0x29, 0x15, 0x8a, 0xce, 0xae, 0x7b, 0xc7, 0xeb, 0xe5, 0xb8, 0x97, 0xc3, 0xee, 0x53, 0x58, 0xb9, + 0xea, 0x04, 0xa4, 0x01, 0xb5, 0xbd, 0xe3, 0xf7, 0xfd, 0x5b, 0x04, 0x60, 0xe9, 0xe0, 0xd5, 0xa7, + 0x77, 0xfb, 0xaf, 0xfa, 0x15, 0xd2, 0x84, 0xfa, 0xdb, 0x7f, 0x1d, 0x9f, 0xf4, 0xab, 0xae, 0x0b, + 0x60, 0xca, 0x78, 0x5d, 0x78, 0xd3, 0x3a, 0xb6, 0x52, 0x72, 0xac, 0xbb, 0x0d, 0xad, 0xfd, 0x09, + 0xe5, 0x63, 0x3c, 0x62, 0x5c, 0x0f, 0xd3, 0x14, 0x63, 0x71, 0x66, 0xdb, 0xd4, 0xf4, 0xf2, 0xc8, + 0xfd, 0xa1, 0x02, 0xf5, 0x23, 0xc6, 0xc7, 0xc4, 0x81, 0x46, 0x2e, 0x56, 0xde, 0xc8, 0x22, 0xd4, + 0x7e, 0x1a, 0x66, 0x4a, 0x89, 0x0b, 0xd3, 0xcb, 0x8e, 0xf3, 0xbe, 0x4d, 0x94, 0x66, 0xd1, 0xe5, + 0x39, 0x57, 0xfb, 0xa6, 0x39, 0x57, 0xbf, 0x7e, 0xce, 0xb9, 0x4d, 0x58, 0xda, 0xa7, 0x3c, 0xc0, + 0xc8, 0xdd, 0x02, 0x78, 0x83, 0xea, 0x15, 0x57, 0xa9, 0x48, 0xa6, 0x84, 0x40, 0x5d, 0xb2, 0x2f, + 0xfa, 0xdc, 0xd5, 0x47, 0x1d, 0xcf, 0xac, 0xdd, 0x6d, 0x68, 0x14, 0x69, 0x07, 0x1a, 0x68, 0x97, + 0x86, 0xd1, 0xf6, 0x8a, 0xd0, 0x6d, 0x03, 0x7c, 0x66, 0x09, 0x1e, 0x98, 0x21, 0xed, 0xfe, 0x58, + 0x05, 0xf8, 0x20, 0x68, 0x68, 0x43, 0x6d, 0xed, 0x98, 0x63, 0x2c, 0x38, 0x0b, 0x0a, 0x6b, 0x17, + 0x31, 0x79, 0x0e, 0x75, 0xae, 0x1f, 0x02, 0xad, 0xc2, 0xf2, 0xee, 0xce, 0x55, 0x86, 0xcb, 0xdf, + 0xcc, 0xb7, 0x07, 0x1f, 0x45, 0x68, 0x4d, 0x65, 0x3e, 0x21, 0x7d, 0xa8, 0x25, 0xcc, 0xaa, 0xd2, + 0xf2, 0xf4, 0xf2, 0x37, 0x69, 0x41, 0xb6, 0x4b, 0x17, 0x4f, 0xdb, 0xbe, 0xf5, 0xa2, 0x81, 0x7c, + 0x1c, 0x31, 0x39, 0xb9, 0xea, 0x06, 0x2e, 0x95, 0x6f, 0xe0, 0x36, 0x74, 0xcc, 0xe3, 0x1c, 0x4c, + 0x30, 0x38, 0x95, 0x59, 0x9c, 0xbf, 0x44, 0x6d, 0x0d, 0xee, 0xe7, 0x18, 0xb9, 0x0f, 0xcb, 0xd9, + 0xee, 0xc8, 0x0f, 0x44, 0xc6, 0x15, 0xa6, 0xe6, 0xf9, 0xe9, 0x78, 0x90, 0xed, 0x8e, 0xf6, 0x2d, + 0xe2, 0xfe, 0x5c, 0x85, 0x65, 0x0f, 0x25, 0xaa, 0x5c, 0xae, 0x1d, 0xe8, 0xce, 0x3c, 0x4f, 0x79, + 0x28, 0xe2, 0xdc, 0x68, 0x9d, 0xc2, 0xf1, 0x06, 0x24, 0xf7, 0xa1, 0x29, 0x55, 0x8a, 0x7c, 0xac, + 0x26, 0xf6, 0xdd, 0x7e, 0x51, 0xdb, 0x7d, 0xfa, 0xcc, 0x9b, 0x81, 0xd7, 0xab, 0x51, 0xfb, 0x8a, + 0x1a, 0x97, 0x5d, 0x57, 0xbf, 0xca, 0x75, 0xbf, 0x43, 0xb4, 0x05, 0x3d, 0x1a, 0x8b, 0x7a, 0x68, + 0x82, 0x51, 0x35, 0x1f, 0xa5, 0xf6, 0xbd, 0x06, 0x0d, 0x5d, 0x35, 0x69, 0x5b, 0x97, 0x27, 0xad, + 0x5d, 0xe5, 0x5e, 0xec, 0x43, 0x37, 0xb7, 0xaf, 0x87, 0xff, 0xcb, 0x50, 0x2a, 0xf7, 0x2f, 0x00, + 0x39, 0xb2, 0x17, 0x9c, 0x5e, 0xf4, 0x74, 0xa5, 0xec, 0xe9, 0x5f, 0x6a, 0xd0, 0xf5, 0x30, 0x10, + 0x67, 0x98, 0x4e, 0xf3, 0xd6, 0x6c, 0x02, 0x9c, 0x8b, 0x34, 0xb4, 0x87, 0xcf, 0x67, 0x44, 0x4b, + 0x23, 0xe6, 0xec, 0xd7, 0x2b, 0x5e, 0xfd, 0x26, 0xc5, 0x6b, 0x37, 0x29, 0x5e, 0xbf, 0x51, 0xf1, + 0xdb, 0x65, 0xc5, 0x1f, 0x43, 0x1f, 0xf9, 0x48, 0xa4, 0x01, 0xfa, 0xfa, 0xac, 0x11, 0x93, 0xca, + 0xb4, 0xa4, 0xe9, 0xf5, 0x72, 0xfc, 0x73, 0x0e, 0x93, 0x13, 0xa8, 0xab, 0x69, 0x82, 0x46, 0xf4, + 0xee, 0xee, 0x3f, 0x6f, 0x98, 0xff, 0x17, 0xd5, 0x59, 0x08, 0xed, 0x4d, 0xd5, 0xbb, 0x2d, 0xb6, + 0xbc, 0x75, 0xa9, 0xe5, 0x6b, 0xd0, 0x08, 0xd3, 0xa9, 0x9f, 0x66, 0xdc, 0xfc, 0x75, 0xd5, 0xf4, + 0x96, 0xc2, 0x74, 0xea, 0x65, 0xdc, 0xfd, 0x0f, 0x90, 0xcb, 0xbb, 0x92, 0x1d, 0x78, 0x70, 0x19, + 0xf5, 0x8f, 0x83, 0x94, 0xc6, 0xc3, 0x08, 0x43, 0x5d, 0x8d, 0xec, 0xdf, 0x22, 0x9b, 0xb0, 0x7e, + 0x05, 0xed, 0x90, 0xaa, 0x94, 0xfd, 0xbf, 0x5f, 0x71, 0x7f, 0xaa, 0xc0, 0xb2, 0xa6, 0xe6, 0xbe, + 0x20, 0x1f, 0xf3, 0xda, 0x2b, 0xa6, 0xf6, 0x17, 0x37, 0xd4, 0x5e, 0xfa, 0xb2, 0xbc, 0x9e, 0x57, + 0xed, 0x8e, 0xa0, 0xb7, 0x90, 0x20, 0xeb, 0xb0, 0xba, 0x00, 0xf9, 0x47, 0x11, 0x65, 0xbc, 0x7f, + 0x8b, 0x6c, 0xc0, 0xda, 0x62, 0xca, 0x9e, 0xf4, 0x79, 0xbf, 0x72, 0x7d, 0xf2, 0x59, 0xbf, 0xea, + 0x6e, 0x42, 0x43, 0x27, 0xb5, 0x99, 0x09, 0xd4, 0x75, 0x87, 0xcd, 0x74, 0x6e, 0x79, 0x66, 0xed, + 0xfe, 0x0d, 0x3a, 0xc7, 0xa8, 0xfe, 0xbd, 0xfb, 0xba, 0x74, 0xbf, 0xca, 0xdd, 0xa8, 0x2c, 0x76, + 0xe3, 0xe5, 0x3f, 0x60, 0x3b, 0x10, 0xf1, 0x40, 0x52, 0x25, 0xe4, 0x84, 0x45, 0x74, 0x28, 0x0b, + 0x21, 0x22, 0x36, 0xb4, 0xff, 0xbb, 0x0c, 0xb3, 0xd1, 0xcb, 0xb5, 0x13, 0x03, 0x1e, 0x5a, 0x71, + 0x0e, 0x67, 0xd2, 0xfc, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0xfc, 0x59, 0x29, 0x0d, 0x00, + 0x00, +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.proto b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.proto new file mode 100644 index 00000000..0ab825a1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages-management.proto @@ -0,0 +1,289 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-management.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.management; + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessageManagement"; + +import "messages-common.proto"; + +/** + * Request: Reset device to default state and ask for device details + * @start + * @next Features + */ +message Initialize { + optional bytes state = 1; // assumed device state, clear session if set and different + optional bool skip_passphrase = 2; // this session should always assume empty passphrase +} + +/** + * Request: Ask for device details (no device reset) + * @start + * @next Features + */ +message GetFeatures { +} + +/** + * Response: Reports various information about the device + * @end + */ +message Features { + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" + optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 + optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 + optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 + optional bool bootloader_mode = 5; // is device in bootloader mode? + optional string device_id = 6; // device's unique identifier + optional bool pin_protection = 7; // is device protected by PIN? + optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? + optional string language = 9; // device language + optional string label = 10; // device description label + optional bool initialized = 12; // does device contain seed? + optional bytes revision = 13; // SCM revision of firmware + optional bytes bootloader_hash = 14; // hash of the bootloader + optional bool imported = 15; // was storage imported from an external source? + optional bool pin_cached = 16; // is PIN already cached in session? + optional bool passphrase_cached = 17; // is passphrase already cached in session? + optional bool firmware_present = 18; // is valid firmware loaded? + optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) + optional uint32 flags = 20; // device flags (equals to Storage.flags) + optional string model = 21; // device hardware model + optional uint32 fw_major = 22; // reported firmware version if in bootloader mode + optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode + optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode + optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode + optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) + optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup) + optional bool no_backup = 28; // report no backup (equals to Storage.no_backup) +} + +/** + * Request: clear session (removes cached PIN, passphrase, etc). + * @start + * @next Success + */ +message ClearSession { +} + +/** + * Request: change language and/or label of the device + * @start + * @next Success + * @next Failure + */ +message ApplySettings { + optional string language = 1; + optional string label = 2; + optional bool use_passphrase = 3; + optional bytes homescreen = 4; + optional PassphraseSourceType passphrase_source = 5; + optional uint32 auto_lock_delay_ms = 6; + optional uint32 display_rotation = 7; // in degrees from North + /** + * Structure representing passphrase source + */ + enum PassphraseSourceType { + ASK = 0; + DEVICE = 1; + HOST = 2; + } +} + +/** + * Request: set flags of the device + * @start + * @next Success + * @next Failure + */ +message ApplyFlags { + optional uint32 flags = 1; // bitmask, can only set bits, not unset +} + +/** + * Request: Starts workflow for setting/changing/removing the PIN + * @start + * @next Success + * @next Failure + */ +message ChangePin { + optional bool remove = 1; // is PIN removal requested? +} + +/** + * Request: Test if the device is alive, device sends back the message in Success response + * @start + * @next Success + */ +message Ping { + optional string message = 1; // message to send back in Success message + optional bool button_protection = 2; // ask for button press + optional bool pin_protection = 3; // ask for PIN if set in device + optional bool passphrase_protection = 4; // ask for passphrase if set in device +} + +/** + * Request: Abort last operation that required user interaction + * @start + * @next Failure + */ +message Cancel { +} + +/** + * Request: Request a sample of random data generated by hardware RNG. May be used for testing. + * @start + * @next Entropy + * @next Failure + */ +message GetEntropy { + required uint32 size = 1; // size of requested entropy +} + +/** + * Response: Reply with random data generated by internal RNG + * @end + */ +message Entropy { + required bytes entropy = 1; // chunk of random generated bytes +} + +/** + * Request: Request device to wipe all sensitive data and settings + * @start + * @next Success + * @next Failure + */ +message WipeDevice { +} + +/** + * Request: Load seed and related internal settings from the computer + * @start + * @next Success + * @next Failure + */ +message LoadDevice { + optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + optional hw.trezor.messages.common.HDNodeType node = 2; // BIP-32 node + optional string pin = 3; // set PIN protection + optional bool passphrase_protection = 4; // enable master node encryption using passphrase + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum + optional uint32 u2f_counter = 8; // U2F counter +} + +/** + * Request: Ask device to do initialization involving user interaction + * @start + * @next EntropyRequest + * @next Failure + */ +message ResetDevice { + optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy + optional uint32 strength = 2 [default=256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow + optional bool no_backup = 9; // indicate that no backup is going to be made +} + +/** + * Request: Perform backup of the device seed if not backed up using ResetDevice + * @start + * @next Success + */ +message BackupDevice { +} + +/** + * Response: Ask for additional entropy from host computer + * @next EntropyAck + */ +message EntropyRequest { +} + +/** + * Request: Provide additional entropy for seed generation function + * @next Success + */ +message EntropyAck { + optional bytes entropy = 1; // 256 bits (32 bytes) of random data +} + +/** + * Request: Start recovery workflow asking user for specific words of mnemonic + * Used to recovery device safely even on untrusted computer. + * @start + * @next WordRequest + */ +message RecoveryDevice { + optional uint32 word_count = 1; // number of words in BIP-39 mnemonic + optional bool passphrase_protection = 2; // enable master node encryption using passphrase + optional bool pin_protection = 3; // enable PIN protection + optional string language = 4 [default='english']; // device language + optional string label = 5; // device label + optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process + // 7 reserved for unused recovery method + optional RecoveryDeviceType type = 8; // supported recovery type + optional uint32 u2f_counter = 9; // U2F counter + optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) + /** + * Type of recovery procedure. These should be used as bitmask, e.g., + * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` + * listing every method supported by the host computer. + * + * Note that ScrambledWords must be supported by every implementation + * for backward compatibility; there is no way to not support it. + */ + enum RecoveryDeviceType { + // use powers of two when extending this field + RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order + RecoveryDeviceType_Matrix = 1; // matrix recovery type + } +} + +/** + * Response: Device is waiting for user to enter word of the mnemonic + * Its position is shown only on device's internal display. + * @next WordAck + */ +message WordRequest { + optional WordRequestType type = 1; + /** + * Type of Recovery Word request + */ + enum WordRequestType { + WordRequestType_Plain = 0; + WordRequestType_Matrix9 = 1; + WordRequestType_Matrix6 = 2; + } +} + +/** + * Request: Computer replies with word from the mnemonic + * @next WordRequest + * @next Success + * @next Failure + */ +message WordAck { + required string word = 1; // one word of mnemonic on asked position +} + +/** + * Request: Set U2F counter + * @start + * @next Success + */ +message SetU2FCounter { + optional uint32 u2f_counter = 1; // counter +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.pb.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.pb.go new file mode 100644 index 00000000..6278bd8e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.pb.go @@ -0,0 +1,889 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +// 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Mapping between TREZOR wire identifier (uint) and a protobuf message +type MessageType int32 + +const ( + // Management + MessageType_MessageType_Initialize MessageType = 0 + MessageType_MessageType_Ping MessageType = 1 + MessageType_MessageType_Success MessageType = 2 + MessageType_MessageType_Failure MessageType = 3 + MessageType_MessageType_ChangePin MessageType = 4 + MessageType_MessageType_WipeDevice MessageType = 5 + MessageType_MessageType_GetEntropy MessageType = 9 + MessageType_MessageType_Entropy MessageType = 10 + MessageType_MessageType_LoadDevice MessageType = 13 + MessageType_MessageType_ResetDevice MessageType = 14 + MessageType_MessageType_Features MessageType = 17 + MessageType_MessageType_PinMatrixRequest MessageType = 18 + MessageType_MessageType_PinMatrixAck MessageType = 19 + MessageType_MessageType_Cancel MessageType = 20 + MessageType_MessageType_ClearSession MessageType = 24 + MessageType_MessageType_ApplySettings MessageType = 25 + MessageType_MessageType_ButtonRequest MessageType = 26 + MessageType_MessageType_ButtonAck MessageType = 27 + MessageType_MessageType_ApplyFlags MessageType = 28 + MessageType_MessageType_BackupDevice MessageType = 34 + MessageType_MessageType_EntropyRequest MessageType = 35 + MessageType_MessageType_EntropyAck MessageType = 36 + MessageType_MessageType_PassphraseRequest MessageType = 41 + MessageType_MessageType_PassphraseAck MessageType = 42 + MessageType_MessageType_PassphraseStateRequest MessageType = 77 + MessageType_MessageType_PassphraseStateAck MessageType = 78 + MessageType_MessageType_RecoveryDevice MessageType = 45 + MessageType_MessageType_WordRequest MessageType = 46 + MessageType_MessageType_WordAck MessageType = 47 + MessageType_MessageType_GetFeatures MessageType = 55 + MessageType_MessageType_SetU2FCounter MessageType = 63 + // Bootloader + MessageType_MessageType_FirmwareErase MessageType = 6 + MessageType_MessageType_FirmwareUpload MessageType = 7 + MessageType_MessageType_FirmwareRequest MessageType = 8 + MessageType_MessageType_SelfTest MessageType = 32 + // Bitcoin + MessageType_MessageType_GetPublicKey MessageType = 11 + MessageType_MessageType_PublicKey MessageType = 12 + MessageType_MessageType_SignTx MessageType = 15 + MessageType_MessageType_TxRequest MessageType = 21 + MessageType_MessageType_TxAck MessageType = 22 + MessageType_MessageType_GetAddress MessageType = 29 + MessageType_MessageType_Address MessageType = 30 + MessageType_MessageType_SignMessage MessageType = 38 + MessageType_MessageType_VerifyMessage MessageType = 39 + MessageType_MessageType_MessageSignature MessageType = 40 + // Crypto + MessageType_MessageType_CipherKeyValue MessageType = 23 + MessageType_MessageType_CipheredKeyValue MessageType = 48 + MessageType_MessageType_SignIdentity MessageType = 53 + MessageType_MessageType_SignedIdentity MessageType = 54 + MessageType_MessageType_GetECDHSessionKey MessageType = 61 + MessageType_MessageType_ECDHSessionKey MessageType = 62 + MessageType_MessageType_CosiCommit MessageType = 71 + MessageType_MessageType_CosiCommitment MessageType = 72 + MessageType_MessageType_CosiSign MessageType = 73 + MessageType_MessageType_CosiSignature MessageType = 74 + // Debug + MessageType_MessageType_DebugLinkDecision MessageType = 100 + MessageType_MessageType_DebugLinkGetState MessageType = 101 + MessageType_MessageType_DebugLinkState MessageType = 102 + MessageType_MessageType_DebugLinkStop MessageType = 103 + MessageType_MessageType_DebugLinkLog MessageType = 104 + MessageType_MessageType_DebugLinkMemoryRead MessageType = 110 + MessageType_MessageType_DebugLinkMemory MessageType = 111 + MessageType_MessageType_DebugLinkMemoryWrite MessageType = 112 + MessageType_MessageType_DebugLinkFlashErase MessageType = 113 + // Ethereum + MessageType_MessageType_EthereumGetPublicKey MessageType = 450 + MessageType_MessageType_EthereumPublicKey MessageType = 451 + MessageType_MessageType_EthereumGetAddress MessageType = 56 + MessageType_MessageType_EthereumAddress MessageType = 57 + MessageType_MessageType_EthereumSignTx MessageType = 58 + MessageType_MessageType_EthereumTxRequest MessageType = 59 + MessageType_MessageType_EthereumTxAck MessageType = 60 + MessageType_MessageType_EthereumSignMessage MessageType = 64 + MessageType_MessageType_EthereumVerifyMessage MessageType = 65 + MessageType_MessageType_EthereumMessageSignature MessageType = 66 + // NEM + MessageType_MessageType_NEMGetAddress MessageType = 67 + MessageType_MessageType_NEMAddress MessageType = 68 + MessageType_MessageType_NEMSignTx MessageType = 69 + MessageType_MessageType_NEMSignedTx MessageType = 70 + MessageType_MessageType_NEMDecryptMessage MessageType = 75 + MessageType_MessageType_NEMDecryptedMessage MessageType = 76 + // Lisk + MessageType_MessageType_LiskGetAddress MessageType = 114 + MessageType_MessageType_LiskAddress MessageType = 115 + MessageType_MessageType_LiskSignTx MessageType = 116 + MessageType_MessageType_LiskSignedTx MessageType = 117 + MessageType_MessageType_LiskSignMessage MessageType = 118 + MessageType_MessageType_LiskMessageSignature MessageType = 119 + MessageType_MessageType_LiskVerifyMessage MessageType = 120 + MessageType_MessageType_LiskGetPublicKey MessageType = 121 + MessageType_MessageType_LiskPublicKey MessageType = 122 + // Tezos + MessageType_MessageType_TezosGetAddress MessageType = 150 + MessageType_MessageType_TezosAddress MessageType = 151 + MessageType_MessageType_TezosSignTx MessageType = 152 + MessageType_MessageType_TezosSignedTx MessageType = 153 + MessageType_MessageType_TezosGetPublicKey MessageType = 154 + MessageType_MessageType_TezosPublicKey MessageType = 155 + // Stellar + MessageType_MessageType_StellarSignTx MessageType = 202 + MessageType_MessageType_StellarTxOpRequest MessageType = 203 + MessageType_MessageType_StellarGetAddress MessageType = 207 + MessageType_MessageType_StellarAddress MessageType = 208 + MessageType_MessageType_StellarCreateAccountOp MessageType = 210 + MessageType_MessageType_StellarPaymentOp MessageType = 211 + MessageType_MessageType_StellarPathPaymentOp MessageType = 212 + MessageType_MessageType_StellarManageOfferOp MessageType = 213 + MessageType_MessageType_StellarCreatePassiveOfferOp MessageType = 214 + MessageType_MessageType_StellarSetOptionsOp MessageType = 215 + MessageType_MessageType_StellarChangeTrustOp MessageType = 216 + MessageType_MessageType_StellarAllowTrustOp MessageType = 217 + MessageType_MessageType_StellarAccountMergeOp MessageType = 218 + // omitted: StellarInflationOp is not a supported operation, would be 219 + MessageType_MessageType_StellarManageDataOp MessageType = 220 + MessageType_MessageType_StellarBumpSequenceOp MessageType = 221 + MessageType_MessageType_StellarSignedTx MessageType = 230 + // TRON + MessageType_MessageType_TronGetAddress MessageType = 250 + MessageType_MessageType_TronAddress MessageType = 251 + MessageType_MessageType_TronSignTx MessageType = 252 + MessageType_MessageType_TronSignedTx MessageType = 253 + // Cardano + // dropped Sign/VerifyMessage ids 300-302 + MessageType_MessageType_CardanoSignTx MessageType = 303 + MessageType_MessageType_CardanoTxRequest MessageType = 304 + MessageType_MessageType_CardanoGetPublicKey MessageType = 305 + MessageType_MessageType_CardanoPublicKey MessageType = 306 + MessageType_MessageType_CardanoGetAddress MessageType = 307 + MessageType_MessageType_CardanoAddress MessageType = 308 + MessageType_MessageType_CardanoTxAck MessageType = 309 + MessageType_MessageType_CardanoSignedTx MessageType = 310 + // Ontology + MessageType_MessageType_OntologyGetAddress MessageType = 350 + MessageType_MessageType_OntologyAddress MessageType = 351 + MessageType_MessageType_OntologyGetPublicKey MessageType = 352 + MessageType_MessageType_OntologyPublicKey MessageType = 353 + MessageType_MessageType_OntologySignTransfer MessageType = 354 + MessageType_MessageType_OntologySignedTransfer MessageType = 355 + MessageType_MessageType_OntologySignWithdrawOng MessageType = 356 + MessageType_MessageType_OntologySignedWithdrawOng MessageType = 357 + MessageType_MessageType_OntologySignOntIdRegister MessageType = 358 + MessageType_MessageType_OntologySignedOntIdRegister MessageType = 359 + MessageType_MessageType_OntologySignOntIdAddAttributes MessageType = 360 + MessageType_MessageType_OntologySignedOntIdAddAttributes MessageType = 361 + // Ripple + MessageType_MessageType_RippleGetAddress MessageType = 400 + MessageType_MessageType_RippleAddress MessageType = 401 + MessageType_MessageType_RippleSignTx MessageType = 402 + MessageType_MessageType_RippleSignedTx MessageType = 403 + // Monero + MessageType_MessageType_MoneroTransactionInitRequest MessageType = 501 + MessageType_MessageType_MoneroTransactionInitAck MessageType = 502 + MessageType_MessageType_MoneroTransactionSetInputRequest MessageType = 503 + MessageType_MessageType_MoneroTransactionSetInputAck MessageType = 504 + MessageType_MessageType_MoneroTransactionInputsPermutationRequest MessageType = 505 + MessageType_MessageType_MoneroTransactionInputsPermutationAck MessageType = 506 + MessageType_MessageType_MoneroTransactionInputViniRequest MessageType = 507 + MessageType_MessageType_MoneroTransactionInputViniAck MessageType = 508 + MessageType_MessageType_MoneroTransactionAllInputsSetRequest MessageType = 509 + MessageType_MessageType_MoneroTransactionAllInputsSetAck MessageType = 510 + MessageType_MessageType_MoneroTransactionSetOutputRequest MessageType = 511 + MessageType_MessageType_MoneroTransactionSetOutputAck MessageType = 512 + MessageType_MessageType_MoneroTransactionAllOutSetRequest MessageType = 513 + MessageType_MessageType_MoneroTransactionAllOutSetAck MessageType = 514 + MessageType_MessageType_MoneroTransactionSignInputRequest MessageType = 515 + MessageType_MessageType_MoneroTransactionSignInputAck MessageType = 516 + MessageType_MessageType_MoneroTransactionFinalRequest MessageType = 517 + MessageType_MessageType_MoneroTransactionFinalAck MessageType = 518 + MessageType_MessageType_MoneroKeyImageExportInitRequest MessageType = 530 + MessageType_MessageType_MoneroKeyImageExportInitAck MessageType = 531 + MessageType_MessageType_MoneroKeyImageSyncStepRequest MessageType = 532 + MessageType_MessageType_MoneroKeyImageSyncStepAck MessageType = 533 + MessageType_MessageType_MoneroKeyImageSyncFinalRequest MessageType = 534 + MessageType_MessageType_MoneroKeyImageSyncFinalAck MessageType = 535 + MessageType_MessageType_MoneroGetAddress MessageType = 540 + MessageType_MessageType_MoneroAddress MessageType = 541 + MessageType_MessageType_MoneroGetWatchKey MessageType = 542 + MessageType_MessageType_MoneroWatchKey MessageType = 543 + MessageType_MessageType_DebugMoneroDiagRequest MessageType = 546 + MessageType_MessageType_DebugMoneroDiagAck MessageType = 547 + MessageType_MessageType_MoneroGetTxKeyRequest MessageType = 550 + MessageType_MessageType_MoneroGetTxKeyAck MessageType = 551 + MessageType_MessageType_MoneroLiveRefreshStartRequest MessageType = 552 + MessageType_MessageType_MoneroLiveRefreshStartAck MessageType = 553 + MessageType_MessageType_MoneroLiveRefreshStepRequest MessageType = 554 + MessageType_MessageType_MoneroLiveRefreshStepAck MessageType = 555 + MessageType_MessageType_MoneroLiveRefreshFinalRequest MessageType = 556 + MessageType_MessageType_MoneroLiveRefreshFinalAck MessageType = 557 + // EOS + MessageType_MessageType_EosGetPublicKey MessageType = 600 + MessageType_MessageType_EosPublicKey MessageType = 601 + MessageType_MessageType_EosSignTx MessageType = 602 + MessageType_MessageType_EosTxActionRequest MessageType = 603 + MessageType_MessageType_EosTxActionAck MessageType = 604 + MessageType_MessageType_EosSignedTx MessageType = 605 + // Binance + MessageType_MessageType_BinanceGetAddress MessageType = 700 + MessageType_MessageType_BinanceAddress MessageType = 701 + MessageType_MessageType_BinanceGetPublicKey MessageType = 702 + MessageType_MessageType_BinancePublicKey MessageType = 703 + MessageType_MessageType_BinanceSignTx MessageType = 704 + MessageType_MessageType_BinanceTxRequest MessageType = 705 + MessageType_MessageType_BinanceTransferMsg MessageType = 706 + MessageType_MessageType_BinanceOrderMsg MessageType = 707 + MessageType_MessageType_BinanceCancelMsg MessageType = 708 + MessageType_MessageType_BinanceSignedTx MessageType = 709 +) + +var MessageType_name = map[int32]string{ + 0: "MessageType_Initialize", + 1: "MessageType_Ping", + 2: "MessageType_Success", + 3: "MessageType_Failure", + 4: "MessageType_ChangePin", + 5: "MessageType_WipeDevice", + 9: "MessageType_GetEntropy", + 10: "MessageType_Entropy", + 13: "MessageType_LoadDevice", + 14: "MessageType_ResetDevice", + 17: "MessageType_Features", + 18: "MessageType_PinMatrixRequest", + 19: "MessageType_PinMatrixAck", + 20: "MessageType_Cancel", + 24: "MessageType_ClearSession", + 25: "MessageType_ApplySettings", + 26: "MessageType_ButtonRequest", + 27: "MessageType_ButtonAck", + 28: "MessageType_ApplyFlags", + 34: "MessageType_BackupDevice", + 35: "MessageType_EntropyRequest", + 36: "MessageType_EntropyAck", + 41: "MessageType_PassphraseRequest", + 42: "MessageType_PassphraseAck", + 77: "MessageType_PassphraseStateRequest", + 78: "MessageType_PassphraseStateAck", + 45: "MessageType_RecoveryDevice", + 46: "MessageType_WordRequest", + 47: "MessageType_WordAck", + 55: "MessageType_GetFeatures", + 63: "MessageType_SetU2FCounter", + 6: "MessageType_FirmwareErase", + 7: "MessageType_FirmwareUpload", + 8: "MessageType_FirmwareRequest", + 32: "MessageType_SelfTest", + 11: "MessageType_GetPublicKey", + 12: "MessageType_PublicKey", + 15: "MessageType_SignTx", + 21: "MessageType_TxRequest", + 22: "MessageType_TxAck", + 29: "MessageType_GetAddress", + 30: "MessageType_Address", + 38: "MessageType_SignMessage", + 39: "MessageType_VerifyMessage", + 40: "MessageType_MessageSignature", + 23: "MessageType_CipherKeyValue", + 48: "MessageType_CipheredKeyValue", + 53: "MessageType_SignIdentity", + 54: "MessageType_SignedIdentity", + 61: "MessageType_GetECDHSessionKey", + 62: "MessageType_ECDHSessionKey", + 71: "MessageType_CosiCommit", + 72: "MessageType_CosiCommitment", + 73: "MessageType_CosiSign", + 74: "MessageType_CosiSignature", + 100: "MessageType_DebugLinkDecision", + 101: "MessageType_DebugLinkGetState", + 102: "MessageType_DebugLinkState", + 103: "MessageType_DebugLinkStop", + 104: "MessageType_DebugLinkLog", + 110: "MessageType_DebugLinkMemoryRead", + 111: "MessageType_DebugLinkMemory", + 112: "MessageType_DebugLinkMemoryWrite", + 113: "MessageType_DebugLinkFlashErase", + 450: "MessageType_EthereumGetPublicKey", + 451: "MessageType_EthereumPublicKey", + 56: "MessageType_EthereumGetAddress", + 57: "MessageType_EthereumAddress", + 58: "MessageType_EthereumSignTx", + 59: "MessageType_EthereumTxRequest", + 60: "MessageType_EthereumTxAck", + 64: "MessageType_EthereumSignMessage", + 65: "MessageType_EthereumVerifyMessage", + 66: "MessageType_EthereumMessageSignature", + 67: "MessageType_NEMGetAddress", + 68: "MessageType_NEMAddress", + 69: "MessageType_NEMSignTx", + 70: "MessageType_NEMSignedTx", + 75: "MessageType_NEMDecryptMessage", + 76: "MessageType_NEMDecryptedMessage", + 114: "MessageType_LiskGetAddress", + 115: "MessageType_LiskAddress", + 116: "MessageType_LiskSignTx", + 117: "MessageType_LiskSignedTx", + 118: "MessageType_LiskSignMessage", + 119: "MessageType_LiskMessageSignature", + 120: "MessageType_LiskVerifyMessage", + 121: "MessageType_LiskGetPublicKey", + 122: "MessageType_LiskPublicKey", + 150: "MessageType_TezosGetAddress", + 151: "MessageType_TezosAddress", + 152: "MessageType_TezosSignTx", + 153: "MessageType_TezosSignedTx", + 154: "MessageType_TezosGetPublicKey", + 155: "MessageType_TezosPublicKey", + 202: "MessageType_StellarSignTx", + 203: "MessageType_StellarTxOpRequest", + 207: "MessageType_StellarGetAddress", + 208: "MessageType_StellarAddress", + 210: "MessageType_StellarCreateAccountOp", + 211: "MessageType_StellarPaymentOp", + 212: "MessageType_StellarPathPaymentOp", + 213: "MessageType_StellarManageOfferOp", + 214: "MessageType_StellarCreatePassiveOfferOp", + 215: "MessageType_StellarSetOptionsOp", + 216: "MessageType_StellarChangeTrustOp", + 217: "MessageType_StellarAllowTrustOp", + 218: "MessageType_StellarAccountMergeOp", + 220: "MessageType_StellarManageDataOp", + 221: "MessageType_StellarBumpSequenceOp", + 230: "MessageType_StellarSignedTx", + 250: "MessageType_TronGetAddress", + 251: "MessageType_TronAddress", + 252: "MessageType_TronSignTx", + 253: "MessageType_TronSignedTx", + 303: "MessageType_CardanoSignTx", + 304: "MessageType_CardanoTxRequest", + 305: "MessageType_CardanoGetPublicKey", + 306: "MessageType_CardanoPublicKey", + 307: "MessageType_CardanoGetAddress", + 308: "MessageType_CardanoAddress", + 309: "MessageType_CardanoTxAck", + 310: "MessageType_CardanoSignedTx", + 350: "MessageType_OntologyGetAddress", + 351: "MessageType_OntologyAddress", + 352: "MessageType_OntologyGetPublicKey", + 353: "MessageType_OntologyPublicKey", + 354: "MessageType_OntologySignTransfer", + 355: "MessageType_OntologySignedTransfer", + 356: "MessageType_OntologySignWithdrawOng", + 357: "MessageType_OntologySignedWithdrawOng", + 358: "MessageType_OntologySignOntIdRegister", + 359: "MessageType_OntologySignedOntIdRegister", + 360: "MessageType_OntologySignOntIdAddAttributes", + 361: "MessageType_OntologySignedOntIdAddAttributes", + 400: "MessageType_RippleGetAddress", + 401: "MessageType_RippleAddress", + 402: "MessageType_RippleSignTx", + 403: "MessageType_RippleSignedTx", + 501: "MessageType_MoneroTransactionInitRequest", + 502: "MessageType_MoneroTransactionInitAck", + 503: "MessageType_MoneroTransactionSetInputRequest", + 504: "MessageType_MoneroTransactionSetInputAck", + 505: "MessageType_MoneroTransactionInputsPermutationRequest", + 506: "MessageType_MoneroTransactionInputsPermutationAck", + 507: "MessageType_MoneroTransactionInputViniRequest", + 508: "MessageType_MoneroTransactionInputViniAck", + 509: "MessageType_MoneroTransactionAllInputsSetRequest", + 510: "MessageType_MoneroTransactionAllInputsSetAck", + 511: "MessageType_MoneroTransactionSetOutputRequest", + 512: "MessageType_MoneroTransactionSetOutputAck", + 513: "MessageType_MoneroTransactionAllOutSetRequest", + 514: "MessageType_MoneroTransactionAllOutSetAck", + 515: "MessageType_MoneroTransactionSignInputRequest", + 516: "MessageType_MoneroTransactionSignInputAck", + 517: "MessageType_MoneroTransactionFinalRequest", + 518: "MessageType_MoneroTransactionFinalAck", + 530: "MessageType_MoneroKeyImageExportInitRequest", + 531: "MessageType_MoneroKeyImageExportInitAck", + 532: "MessageType_MoneroKeyImageSyncStepRequest", + 533: "MessageType_MoneroKeyImageSyncStepAck", + 534: "MessageType_MoneroKeyImageSyncFinalRequest", + 535: "MessageType_MoneroKeyImageSyncFinalAck", + 540: "MessageType_MoneroGetAddress", + 541: "MessageType_MoneroAddress", + 542: "MessageType_MoneroGetWatchKey", + 543: "MessageType_MoneroWatchKey", + 546: "MessageType_DebugMoneroDiagRequest", + 547: "MessageType_DebugMoneroDiagAck", + 550: "MessageType_MoneroGetTxKeyRequest", + 551: "MessageType_MoneroGetTxKeyAck", + 552: "MessageType_MoneroLiveRefreshStartRequest", + 553: "MessageType_MoneroLiveRefreshStartAck", + 554: "MessageType_MoneroLiveRefreshStepRequest", + 555: "MessageType_MoneroLiveRefreshStepAck", + 556: "MessageType_MoneroLiveRefreshFinalRequest", + 557: "MessageType_MoneroLiveRefreshFinalAck", + 600: "MessageType_EosGetPublicKey", + 601: "MessageType_EosPublicKey", + 602: "MessageType_EosSignTx", + 603: "MessageType_EosTxActionRequest", + 604: "MessageType_EosTxActionAck", + 605: "MessageType_EosSignedTx", + 700: "MessageType_BinanceGetAddress", + 701: "MessageType_BinanceAddress", + 702: "MessageType_BinanceGetPublicKey", + 703: "MessageType_BinancePublicKey", + 704: "MessageType_BinanceSignTx", + 705: "MessageType_BinanceTxRequest", + 706: "MessageType_BinanceTransferMsg", + 707: "MessageType_BinanceOrderMsg", + 708: "MessageType_BinanceCancelMsg", + 709: "MessageType_BinanceSignedTx", +} + +var MessageType_value = map[string]int32{ + "MessageType_Initialize": 0, + "MessageType_Ping": 1, + "MessageType_Success": 2, + "MessageType_Failure": 3, + "MessageType_ChangePin": 4, + "MessageType_WipeDevice": 5, + "MessageType_GetEntropy": 9, + "MessageType_Entropy": 10, + "MessageType_LoadDevice": 13, + "MessageType_ResetDevice": 14, + "MessageType_Features": 17, + "MessageType_PinMatrixRequest": 18, + "MessageType_PinMatrixAck": 19, + "MessageType_Cancel": 20, + "MessageType_ClearSession": 24, + "MessageType_ApplySettings": 25, + "MessageType_ButtonRequest": 26, + "MessageType_ButtonAck": 27, + "MessageType_ApplyFlags": 28, + "MessageType_BackupDevice": 34, + "MessageType_EntropyRequest": 35, + "MessageType_EntropyAck": 36, + "MessageType_PassphraseRequest": 41, + "MessageType_PassphraseAck": 42, + "MessageType_PassphraseStateRequest": 77, + "MessageType_PassphraseStateAck": 78, + "MessageType_RecoveryDevice": 45, + "MessageType_WordRequest": 46, + "MessageType_WordAck": 47, + "MessageType_GetFeatures": 55, + "MessageType_SetU2FCounter": 63, + "MessageType_FirmwareErase": 6, + "MessageType_FirmwareUpload": 7, + "MessageType_FirmwareRequest": 8, + "MessageType_SelfTest": 32, + "MessageType_GetPublicKey": 11, + "MessageType_PublicKey": 12, + "MessageType_SignTx": 15, + "MessageType_TxRequest": 21, + "MessageType_TxAck": 22, + "MessageType_GetAddress": 29, + "MessageType_Address": 30, + "MessageType_SignMessage": 38, + "MessageType_VerifyMessage": 39, + "MessageType_MessageSignature": 40, + "MessageType_CipherKeyValue": 23, + "MessageType_CipheredKeyValue": 48, + "MessageType_SignIdentity": 53, + "MessageType_SignedIdentity": 54, + "MessageType_GetECDHSessionKey": 61, + "MessageType_ECDHSessionKey": 62, + "MessageType_CosiCommit": 71, + "MessageType_CosiCommitment": 72, + "MessageType_CosiSign": 73, + "MessageType_CosiSignature": 74, + "MessageType_DebugLinkDecision": 100, + "MessageType_DebugLinkGetState": 101, + "MessageType_DebugLinkState": 102, + "MessageType_DebugLinkStop": 103, + "MessageType_DebugLinkLog": 104, + "MessageType_DebugLinkMemoryRead": 110, + "MessageType_DebugLinkMemory": 111, + "MessageType_DebugLinkMemoryWrite": 112, + "MessageType_DebugLinkFlashErase": 113, + "MessageType_EthereumGetPublicKey": 450, + "MessageType_EthereumPublicKey": 451, + "MessageType_EthereumGetAddress": 56, + "MessageType_EthereumAddress": 57, + "MessageType_EthereumSignTx": 58, + "MessageType_EthereumTxRequest": 59, + "MessageType_EthereumTxAck": 60, + "MessageType_EthereumSignMessage": 64, + "MessageType_EthereumVerifyMessage": 65, + "MessageType_EthereumMessageSignature": 66, + "MessageType_NEMGetAddress": 67, + "MessageType_NEMAddress": 68, + "MessageType_NEMSignTx": 69, + "MessageType_NEMSignedTx": 70, + "MessageType_NEMDecryptMessage": 75, + "MessageType_NEMDecryptedMessage": 76, + "MessageType_LiskGetAddress": 114, + "MessageType_LiskAddress": 115, + "MessageType_LiskSignTx": 116, + "MessageType_LiskSignedTx": 117, + "MessageType_LiskSignMessage": 118, + "MessageType_LiskMessageSignature": 119, + "MessageType_LiskVerifyMessage": 120, + "MessageType_LiskGetPublicKey": 121, + "MessageType_LiskPublicKey": 122, + "MessageType_TezosGetAddress": 150, + "MessageType_TezosAddress": 151, + "MessageType_TezosSignTx": 152, + "MessageType_TezosSignedTx": 153, + "MessageType_TezosGetPublicKey": 154, + "MessageType_TezosPublicKey": 155, + "MessageType_StellarSignTx": 202, + "MessageType_StellarTxOpRequest": 203, + "MessageType_StellarGetAddress": 207, + "MessageType_StellarAddress": 208, + "MessageType_StellarCreateAccountOp": 210, + "MessageType_StellarPaymentOp": 211, + "MessageType_StellarPathPaymentOp": 212, + "MessageType_StellarManageOfferOp": 213, + "MessageType_StellarCreatePassiveOfferOp": 214, + "MessageType_StellarSetOptionsOp": 215, + "MessageType_StellarChangeTrustOp": 216, + "MessageType_StellarAllowTrustOp": 217, + "MessageType_StellarAccountMergeOp": 218, + "MessageType_StellarManageDataOp": 220, + "MessageType_StellarBumpSequenceOp": 221, + "MessageType_StellarSignedTx": 230, + "MessageType_TronGetAddress": 250, + "MessageType_TronAddress": 251, + "MessageType_TronSignTx": 252, + "MessageType_TronSignedTx": 253, + "MessageType_CardanoSignTx": 303, + "MessageType_CardanoTxRequest": 304, + "MessageType_CardanoGetPublicKey": 305, + "MessageType_CardanoPublicKey": 306, + "MessageType_CardanoGetAddress": 307, + "MessageType_CardanoAddress": 308, + "MessageType_CardanoTxAck": 309, + "MessageType_CardanoSignedTx": 310, + "MessageType_OntologyGetAddress": 350, + "MessageType_OntologyAddress": 351, + "MessageType_OntologyGetPublicKey": 352, + "MessageType_OntologyPublicKey": 353, + "MessageType_OntologySignTransfer": 354, + "MessageType_OntologySignedTransfer": 355, + "MessageType_OntologySignWithdrawOng": 356, + "MessageType_OntologySignedWithdrawOng": 357, + "MessageType_OntologySignOntIdRegister": 358, + "MessageType_OntologySignedOntIdRegister": 359, + "MessageType_OntologySignOntIdAddAttributes": 360, + "MessageType_OntologySignedOntIdAddAttributes": 361, + "MessageType_RippleGetAddress": 400, + "MessageType_RippleAddress": 401, + "MessageType_RippleSignTx": 402, + "MessageType_RippleSignedTx": 403, + "MessageType_MoneroTransactionInitRequest": 501, + "MessageType_MoneroTransactionInitAck": 502, + "MessageType_MoneroTransactionSetInputRequest": 503, + "MessageType_MoneroTransactionSetInputAck": 504, + "MessageType_MoneroTransactionInputsPermutationRequest": 505, + "MessageType_MoneroTransactionInputsPermutationAck": 506, + "MessageType_MoneroTransactionInputViniRequest": 507, + "MessageType_MoneroTransactionInputViniAck": 508, + "MessageType_MoneroTransactionAllInputsSetRequest": 509, + "MessageType_MoneroTransactionAllInputsSetAck": 510, + "MessageType_MoneroTransactionSetOutputRequest": 511, + "MessageType_MoneroTransactionSetOutputAck": 512, + "MessageType_MoneroTransactionAllOutSetRequest": 513, + "MessageType_MoneroTransactionAllOutSetAck": 514, + "MessageType_MoneroTransactionSignInputRequest": 515, + "MessageType_MoneroTransactionSignInputAck": 516, + "MessageType_MoneroTransactionFinalRequest": 517, + "MessageType_MoneroTransactionFinalAck": 518, + "MessageType_MoneroKeyImageExportInitRequest": 530, + "MessageType_MoneroKeyImageExportInitAck": 531, + "MessageType_MoneroKeyImageSyncStepRequest": 532, + "MessageType_MoneroKeyImageSyncStepAck": 533, + "MessageType_MoneroKeyImageSyncFinalRequest": 534, + "MessageType_MoneroKeyImageSyncFinalAck": 535, + "MessageType_MoneroGetAddress": 540, + "MessageType_MoneroAddress": 541, + "MessageType_MoneroGetWatchKey": 542, + "MessageType_MoneroWatchKey": 543, + "MessageType_DebugMoneroDiagRequest": 546, + "MessageType_DebugMoneroDiagAck": 547, + "MessageType_MoneroGetTxKeyRequest": 550, + "MessageType_MoneroGetTxKeyAck": 551, + "MessageType_MoneroLiveRefreshStartRequest": 552, + "MessageType_MoneroLiveRefreshStartAck": 553, + "MessageType_MoneroLiveRefreshStepRequest": 554, + "MessageType_MoneroLiveRefreshStepAck": 555, + "MessageType_MoneroLiveRefreshFinalRequest": 556, + "MessageType_MoneroLiveRefreshFinalAck": 557, + "MessageType_EosGetPublicKey": 600, + "MessageType_EosPublicKey": 601, + "MessageType_EosSignTx": 602, + "MessageType_EosTxActionRequest": 603, + "MessageType_EosTxActionAck": 604, + "MessageType_EosSignedTx": 605, + "MessageType_BinanceGetAddress": 700, + "MessageType_BinanceAddress": 701, + "MessageType_BinanceGetPublicKey": 702, + "MessageType_BinancePublicKey": 703, + "MessageType_BinanceSignTx": 704, + "MessageType_BinanceTxRequest": 705, + "MessageType_BinanceTransferMsg": 706, + "MessageType_BinanceOrderMsg": 707, + "MessageType_BinanceCancelMsg": 708, + "MessageType_BinanceSignedTx": 709, +} + +func (x MessageType) Enum() *MessageType { + p := new(MessageType) + *p = x + return p +} + +func (x MessageType) String() string { + return proto.EnumName(MessageType_name, int32(x)) +} + +func (x *MessageType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType") + if err != nil { + return err + } + *x = MessageType(value) + return nil +} + +func (MessageType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{0} +} + +var E_WireIn = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50002, + Name: "hw.trezor.messages.wire_in", + Tag: "varint,50002,opt,name=wire_in", + Filename: "messages.proto", +} + +var E_WireOut = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50003, + Name: "hw.trezor.messages.wire_out", + Tag: "varint,50003,opt,name=wire_out", + Filename: "messages.proto", +} + +var E_WireDebugIn = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50004, + Name: "hw.trezor.messages.wire_debug_in", + Tag: "varint,50004,opt,name=wire_debug_in", + Filename: "messages.proto", +} + +var E_WireDebugOut = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50005, + Name: "hw.trezor.messages.wire_debug_out", + Tag: "varint,50005,opt,name=wire_debug_out", + Filename: "messages.proto", +} + +var E_WireTiny = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50006, + Name: "hw.trezor.messages.wire_tiny", + Tag: "varint,50006,opt,name=wire_tiny", + Filename: "messages.proto", +} + +var E_WireBootloader = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50007, + Name: "hw.trezor.messages.wire_bootloader", + Tag: "varint,50007,opt,name=wire_bootloader", + Filename: "messages.proto", +} + +var E_WireNoFsm = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50008, + Name: "hw.trezor.messages.wire_no_fsm", + Tag: "varint,50008,opt,name=wire_no_fsm", + Filename: "messages.proto", +} + +func init() { + proto.RegisterEnum("hw.trezor.messages.MessageType", MessageType_name, MessageType_value) + proto.RegisterExtension(E_WireIn) + proto.RegisterExtension(E_WireOut) + proto.RegisterExtension(E_WireDebugIn) + proto.RegisterExtension(E_WireDebugOut) + proto.RegisterExtension(E_WireTiny) + proto.RegisterExtension(E_WireBootloader) + proto.RegisterExtension(E_WireNoFsm) +} + +func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } + +var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ + // 2430 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x9a, 0xd9, 0x73, 0x1c, 0xc5, + 0x1d, 0xc7, 0xb3, 0xab, 0x11, 0x88, 0xf6, 0x41, 0x23, 0xb0, 0x2d, 0xaf, 0x2f, 0xf9, 0xc0, 0x96, + 0x2f, 0xd9, 0x10, 0x0c, 0x44, 0x38, 0x60, 0x69, 0xb5, 0x12, 0x8a, 0xb5, 0x5a, 0x97, 0x76, 0xb1, + 0x1f, 0x5d, 0xa3, 0x9d, 0xd6, 0x6e, 0x97, 0x67, 0x67, 0x86, 0x9e, 0x1e, 0x49, 0xeb, 0xa7, 0x9c, + 0x3c, 0x13, 0x48, 0xc0, 0xb9, 0xa9, 0xa4, 0x2a, 0x21, 0x57, 0x85, 0x1c, 0x4e, 0x25, 0x55, 0x39, + 0x08, 0x24, 0x2f, 0xc9, 0x43, 0x52, 0x9c, 0x86, 0x40, 0xee, 0x90, 0xe4, 0x0f, 0xc8, 0xc5, 0x91, + 0xa4, 0x7a, 0xa6, 0xbb, 0xe7, 0xd8, 0xdf, 0xae, 0x36, 0x6f, 0x58, 0xf3, 0xf9, 0x7d, 0x7f, 0x47, + 0xff, 0xfa, 0x37, 0xdd, 0xb3, 0xa0, 0xcd, 0x2d, 0xe2, 0xfb, 0x66, 0x83, 0xf8, 0xe3, 0x1e, 0x73, + 0xb9, 0x3b, 0x3c, 0xdc, 0x5c, 0x1d, 0xe7, 0x8c, 0x5c, 0x76, 0xd9, 0xb8, 0x7a, 0x52, 0x18, 0x6d, + 0xb8, 0x6e, 0xc3, 0x26, 0x27, 0x42, 0x62, 0x29, 0x58, 0x3e, 0x61, 0x11, 0xbf, 0xce, 0xa8, 0xc7, + 0x5d, 0x16, 0x59, 0x1d, 0xf9, 0xfe, 0x7d, 0x68, 0x43, 0x39, 0xc2, 0x6b, 0x6d, 0x8f, 0x0c, 0x1f, + 0x40, 0x5b, 0x13, 0xff, 0xbc, 0x38, 0xe7, 0x50, 0x4e, 0x4d, 0x9b, 0x5e, 0x26, 0xf8, 0x5d, 0x85, + 0xa1, 0x87, 0xaf, 0x8e, 0xe4, 0x9e, 0xba, 0x3a, 0x92, 0x1b, 0x2e, 0x20, 0x9c, 0xa4, 0xce, 0x51, + 0xa7, 0x81, 0x73, 0x05, 0x43, 0x3c, 0x1f, 0xde, 0x85, 0x6e, 0x4e, 0x3e, 0xab, 0x06, 0xf5, 0x3a, + 0xf1, 0x7d, 0x9c, 0x2f, 0x18, 0x57, 0x80, 0xc7, 0x33, 0x26, 0xb5, 0x03, 0x46, 0xf0, 0x80, 0x7c, + 0xbc, 0x07, 0x6d, 0x49, 0x3e, 0x2e, 0x36, 0x4d, 0xa7, 0x41, 0xce, 0x51, 0x07, 0x1b, 0x52, 0x7e, + 0x34, 0x1d, 0xe0, 0x05, 0xea, 0x91, 0x69, 0xb2, 0x42, 0xeb, 0x04, 0x0f, 0xc2, 0xc4, 0x2c, 0xe1, + 0x25, 0x87, 0x33, 0xd7, 0x6b, 0xe3, 0x1b, 0xe0, 0x10, 0xd5, 0x63, 0x24, 0x63, 0xc8, 0x08, 0xcc, + 0xbb, 0xa6, 0x25, 0x5d, 0x6c, 0x92, 0x02, 0x7b, 0xd1, 0xb6, 0x24, 0xb1, 0x48, 0x7c, 0xc2, 0x25, + 0xb2, 0x59, 0x22, 0xbb, 0xd1, 0x2d, 0xa9, 0x3c, 0x89, 0xc9, 0x03, 0x46, 0x7c, 0x7c, 0x93, 0x74, + 0x72, 0x10, 0xed, 0xcc, 0x94, 0xb0, 0x6c, 0x72, 0x46, 0xd7, 0x16, 0xc9, 0x83, 0x01, 0xf1, 0x39, + 0x1e, 0x96, 0xdc, 0x11, 0x34, 0x02, 0x72, 0x93, 0xf5, 0x4b, 0xf8, 0xe6, 0xc2, 0x46, 0xb5, 0x24, + 0x4f, 0x47, 0x81, 0x0f, 0xa7, 0x8a, 0x67, 0x3a, 0x75, 0x62, 0xe3, 0x5b, 0x12, 0x0b, 0xb7, 0x2f, + 0xad, 0x56, 0xb4, 0x89, 0xc9, 0xaa, 0xc4, 0xf7, 0xa9, 0xeb, 0xe0, 0x11, 0x19, 0xf9, 0x7e, 0xb4, + 0x3d, 0xc9, 0x4c, 0x7a, 0x9e, 0xdd, 0xae, 0x12, 0xce, 0xa9, 0xd3, 0xf0, 0xf1, 0x76, 0x18, 0x9a, + 0x0a, 0x38, 0x77, 0x1d, 0x15, 0x7b, 0x41, 0xc6, 0x7e, 0x28, 0xbd, 0x98, 0x11, 0x24, 0x02, 0xdf, + 0xd1, 0x11, 0xf8, 0xd6, 0x0e, 0x97, 0x33, 0xb6, 0xd9, 0xf0, 0xf1, 0x4e, 0xe9, 0x2f, 0x13, 0xf8, + 0x94, 0x59, 0xbf, 0x14, 0x78, 0xb2, 0xe4, 0xfb, 0x24, 0x73, 0x00, 0x15, 0x80, 0x65, 0x55, 0x41, + 0xed, 0x87, 0x57, 0x57, 0x52, 0x22, 0xaa, 0x03, 0x52, 0xe7, 0x10, 0xda, 0x95, 0x2a, 0xb9, 0xe9, + 0xfb, 0x5e, 0x93, 0x99, 0x3e, 0x51, 0x52, 0x87, 0xa5, 0xd4, 0xd1, 0x74, 0x11, 0x62, 0x50, 0xa8, + 0x1d, 0xc9, 0xe4, 0x78, 0x0c, 0xed, 0x83, 0xe1, 0x2a, 0x37, 0xb9, 0x96, 0x2e, 0x4b, 0xe9, 0x93, + 0x68, 0x77, 0x0f, 0x5a, 0xe8, 0x2f, 0x64, 0xf4, 0x33, 0xd9, 0x2f, 0x92, 0xba, 0xbb, 0x42, 0x58, + 0x5b, 0xd6, 0xe8, 0x38, 0xdc, 0xb9, 0x17, 0x5c, 0x66, 0x29, 0xd7, 0xe3, 0xf0, 0x0e, 0x15, 0x88, + 0xf0, 0x77, 0x02, 0x56, 0x98, 0x25, 0x5c, 0xf7, 0xf6, 0x5d, 0x70, 0x73, 0x54, 0x09, 0x7f, 0xe0, + 0xf6, 0x99, 0xa2, 0x1b, 0x38, 0x9c, 0x30, 0x7c, 0x9f, 0xae, 0x72, 0x0a, 0x9a, 0xa1, 0xac, 0xb5, + 0x6a, 0x32, 0x52, 0x12, 0x49, 0xe2, 0xeb, 0xa2, 0x9e, 0xfd, 0x9e, 0x00, 0xc7, 0xd2, 0x89, 0x29, + 0xf0, 0x01, 0xcf, 0x76, 0x4d, 0x0b, 0x5f, 0x9f, 0x20, 0x0f, 0xa3, 0x1d, 0x10, 0xa9, 0x12, 0x1c, + 0x2a, 0x0c, 0x5d, 0x51, 0xe8, 0xbe, 0xf4, 0xf6, 0xac, 0x12, 0x7b, 0xb9, 0x26, 0x98, 0xd1, 0x84, + 0x5c, 0xa6, 0xe7, 0x66, 0x09, 0x3f, 0x17, 0x2c, 0xd9, 0xb4, 0x7e, 0x96, 0xb4, 0xf1, 0x06, 0x99, + 0x45, 0x66, 0x5e, 0xc5, 0xc0, 0x46, 0x59, 0xcd, 0x9d, 0xe9, 0x3d, 0x59, 0xa5, 0x0d, 0xa7, 0xb6, + 0x86, 0x6f, 0x84, 0xcd, 0x6b, 0x7a, 0xfb, 0x6f, 0x91, 0xe6, 0x3b, 0xd0, 0x4d, 0x69, 0x40, 0x2c, + 0xc5, 0xd6, 0xae, 0x93, 0x6e, 0xd2, 0xb2, 0x98, 0x98, 0xb6, 0xbb, 0xe0, 0x49, 0xa7, 0x1e, 0xef, + 0x96, 0xea, 0x99, 0xb5, 0x14, 0xc1, 0xc9, 0x7f, 0xe3, 0x83, 0xf0, 0x5a, 0x9e, 0x27, 0x8c, 0x2e, + 0xb7, 0x15, 0x74, 0x48, 0x42, 0x99, 0x61, 0x26, 0xff, 0x5b, 0xc8, 0x85, 0x9d, 0x81, 0xc7, 0xa4, + 0xbf, 0x4c, 0x8f, 0x16, 0xa9, 0xd7, 0x24, 0xec, 0x2c, 0x69, 0x9f, 0x37, 0xed, 0x80, 0xe0, 0x6d, + 0xb0, 0x5a, 0x44, 0x11, 0x4b, 0x73, 0x27, 0xa5, 0x5a, 0x66, 0x7d, 0x84, 0xbb, 0x39, 0x8b, 0x38, + 0x9c, 0xf2, 0x36, 0x3e, 0x05, 0xcf, 0x04, 0xc1, 0x10, 0x4b, 0x53, 0x77, 0xea, 0x41, 0xb5, 0x2b, + 0xfb, 0xca, 0x28, 0x4e, 0xdf, 0x2f, 0x07, 0xa3, 0x58, 0xcd, 0xf7, 0x76, 0x19, 0x31, 0x69, 0xea, + 0x5e, 0x78, 0xc4, 0x14, 0x5d, 0x9f, 0x16, 0xdd, 0x56, 0x8b, 0x72, 0x3c, 0x0b, 0xeb, 0xc4, 0x44, + 0x8b, 0x38, 0x1c, 0xdf, 0x2f, 0x75, 0x32, 0xef, 0x10, 0x41, 0x89, 0x04, 0xf0, 0x1c, 0xbc, 0x36, + 0xea, 0x79, 0x54, 0xf3, 0xf7, 0x49, 0x91, 0x13, 0xe9, 0xdc, 0xa6, 0xc9, 0x52, 0xd0, 0x98, 0xa7, + 0xce, 0xa5, 0x69, 0x52, 0xa7, 0xe1, 0xdc, 0xb7, 0x0a, 0x1b, 0x9f, 0x48, 0x0e, 0x92, 0xa3, 0x5d, + 0x0c, 0x66, 0x09, 0x0f, 0x87, 0x0f, 0x26, 0x85, 0x21, 0x65, 0x90, 0x4d, 0x44, 0xc3, 0x11, 0xb9, + 0x5c, 0x30, 0x9e, 0x04, 0x02, 0x4d, 0x50, 0xae, 0x87, 0x1b, 0x05, 0xe3, 0x09, 0x60, 0x39, 0x35, + 0x34, 0xef, 0x36, 0x70, 0x53, 0x0a, 0x1d, 0x46, 0x7b, 0x40, 0xa6, 0x4c, 0x5a, 0x2e, 0x6b, 0x2f, + 0x12, 0xd3, 0xc2, 0x8e, 0x94, 0xbb, 0x35, 0x3d, 0x0c, 0x32, 0x28, 0x76, 0xa5, 0xe2, 0x11, 0x34, + 0xda, 0x03, 0xbb, 0xc0, 0x28, 0x27, 0xd8, 0x93, 0x92, 0xdd, 0xbc, 0xcf, 0xd8, 0xa6, 0xdf, 0x8c, + 0x06, 0xd7, 0x83, 0x12, 0x3d, 0x9a, 0x96, 0x2d, 0x71, 0xd1, 0xc2, 0x41, 0x2b, 0x35, 0x43, 0x9e, + 0x19, 0x90, 0xeb, 0x38, 0x96, 0xae, 0xb8, 0x82, 0x63, 0xf2, 0x59, 0x75, 0x3c, 0x1a, 0x4b, 0xbf, + 0x16, 0x12, 0xb2, 0x6a, 0x6b, 0xdf, 0x2d, 0x35, 0x33, 0xe9, 0x2b, 0x52, 0x61, 0xef, 0x81, 0x77, + 0xa4, 0xc2, 0xe4, 0x98, 0x9a, 0x80, 0xdf, 0x88, 0x8a, 0x8a, 0xc7, 0xd5, 0x3d, 0x52, 0x2e, 0xb3, + 0xd0, 0x31, 0x28, 0xc6, 0xd6, 0x69, 0xa9, 0x96, 0x29, 0x63, 0xd2, 0xa7, 0x1a, 0x2c, 0x67, 0x24, + 0x7a, 0x14, 0xed, 0x85, 0xd0, 0xf4, 0x14, 0x9a, 0x94, 0xf0, 0x38, 0x3a, 0x00, 0xc1, 0x1d, 0xd3, + 0x68, 0x0a, 0x0e, 0x76, 0xa1, 0x54, 0x4e, 0xd4, 0xb1, 0x08, 0xcf, 0xd8, 0x85, 0x52, 0x59, 0x11, + 0xd3, 0xf0, 0x91, 0x75, 0xa1, 0x54, 0x96, 0xd5, 0x2b, 0xc1, 0x6f, 0x4c, 0x09, 0x10, 0xab, 0xb6, + 0x86, 0x67, 0xe0, 0x01, 0xb4, 0x50, 0x2a, 0x4f, 0x93, 0x3a, 0x6b, 0x7b, 0x5c, 0xe5, 0x78, 0x16, + 0xae, 0x5d, 0x0c, 0x12, 0x4b, 0xa1, 0xf3, 0xf0, 0xd2, 0xce, 0x53, 0xff, 0x52, 0x22, 0x3f, 0x06, + 0x07, 0x27, 0x28, 0x85, 0xf8, 0x5d, 0xce, 0xc3, 0xd4, 0xbf, 0x24, 0x33, 0xe4, 0xf0, 0xe9, 0x4c, + 0x11, 0x61, 0x8a, 0x81, 0x54, 0xc9, 0x34, 0xa4, 0x62, 0x54, 0xd4, 0x2b, 0x52, 0x2a, 0xb3, 0x1f, + 0x05, 0xd6, 0xb1, 0x80, 0xab, 0x70, 0xd5, 0x04, 0x9b, 0xee, 0x8c, 0x35, 0xf8, 0x8d, 0x22, 0x4b, + 0x11, 0xef, 0xaf, 0x36, 0x3c, 0x50, 0x05, 0x17, 0x43, 0x97, 0xf5, 0xc9, 0x3d, 0x95, 0x48, 0x8d, + 0x5c, 0x76, 0xfd, 0x44, 0x61, 0x1f, 0xcb, 0x69, 0xb1, 0x91, 0x0e, 0x4e, 0x41, 0x8f, 0xe7, 0xf4, + 0x3b, 0x6c, 0x5b, 0x07, 0x24, 0x8b, 0x7b, 0x25, 0xa7, 0x5f, 0x16, 0xdb, 0x41, 0x26, 0x2c, 0xef, + 0x27, 0x72, 0x7a, 0x34, 0xec, 0x82, 0xc2, 0x8a, 0xe3, 0xff, 0x64, 0x4e, 0x8f, 0x86, 0x42, 0x07, + 0x19, 0x63, 0x9f, 0xca, 0xe9, 0xfe, 0x49, 0x9f, 0xe2, 0x38, 0xb1, 0x6d, 0x93, 0xc9, 0xe0, 0x7e, + 0x9e, 0xd3, 0x0d, 0xb9, 0x1b, 0xa0, 0x6a, 0x6b, 0x15, 0x4f, 0xcd, 0x86, 0x5f, 0x74, 0x89, 0x50, + 0xa2, 0x89, 0xd2, 0xfd, 0xb2, 0x4b, 0x84, 0x92, 0x54, 0xd8, 0xaf, 0x94, 0xe0, 0xf1, 0xf4, 0x91, + 0x5a, 0x62, 0x45, 0x46, 0xc2, 0x23, 0x72, 0x5d, 0x1c, 0x38, 0x2b, 0x1e, 0x7e, 0x2e, 0xa7, 0xa7, + 0xd8, 0x4e, 0x00, 0x3f, 0x67, 0xb6, 0xc5, 0x4b, 0xb7, 0xe2, 0xe1, 0xe7, 0x73, 0x7a, 0xea, 0x8c, + 0x82, 0x20, 0x6f, 0xc6, 0xf0, 0x0b, 0xbd, 0xe1, 0xb2, 0xe9, 0x98, 0x0d, 0x52, 0x59, 0x5e, 0x26, + 0xac, 0xe2, 0xe1, 0x17, 0x15, 0x7c, 0x3b, 0x3a, 0xd4, 0x35, 0x62, 0x71, 0xc6, 0xa7, 0x2b, 0xda, + 0xe6, 0xa5, 0x9c, 0xde, 0x11, 0x7b, 0xa0, 0x75, 0x20, 0xbc, 0xe2, 0x71, 0xea, 0x3a, 0x7e, 0xc5, + 0xc3, 0x2f, 0xf7, 0x0e, 0x26, 0xba, 0x45, 0xd7, 0x58, 0xe0, 0x8b, 0xc8, 0xaf, 0xf5, 0x16, 0x9e, + 0xb4, 0x6d, 0x77, 0x55, 0xb1, 0xaf, 0x28, 0xf6, 0x58, 0x7a, 0x10, 0x2b, 0x36, 0x2a, 0x72, 0x99, + 0xb0, 0x06, 0xa9, 0x78, 0xf8, 0xd5, 0xde, 0xca, 0x51, 0x4d, 0xa6, 0x4d, 0x6e, 0x56, 0x3c, 0xfc, + 0x5a, 0x6f, 0xe5, 0xa9, 0xa0, 0xe5, 0x55, 0x45, 0x03, 0x39, 0x75, 0xa1, 0xfc, 0x7a, 0x4e, 0xef, + 0xe4, 0x1d, 0x5d, 0x9a, 0x32, 0xdc, 0x0d, 0x6f, 0xe4, 0xf4, 0xb4, 0x49, 0xf7, 0x38, 0x73, 0x9d, + 0x44, 0xa3, 0xbd, 0x99, 0xd3, 0x83, 0x6b, 0x5b, 0x16, 0x53, 0xcc, 0x5b, 0x39, 0x7d, 0x48, 0xde, + 0x9a, 0x65, 0xe4, 0x26, 0x78, 0xbb, 0xdb, 0x56, 0x97, 0x48, 0x18, 0xd2, 0x3b, 0x5d, 0xf6, 0x53, + 0xd1, 0x64, 0x96, 0xe9, 0xb8, 0x52, 0xea, 0x1b, 0x79, 0xb8, 0x49, 0x25, 0x15, 0xbf, 0x69, 0x9f, + 0xca, 0xeb, 0x0f, 0x03, 0x7b, 0x00, 0x30, 0xb5, 0xe3, 0xbf, 0xd9, 0x5b, 0x34, 0x06, 0xbf, 0x95, + 0x87, 0xb7, 0x68, 0x2c, 0xaa, 0xaa, 0xf2, 0xed, 0x3c, 0xbc, 0x45, 0x25, 0xa9, 0xb0, 0xef, 0xe4, + 0xf5, 0x3b, 0x76, 0x04, 0x4c, 0x47, 0x9c, 0x07, 0xae, 0xe6, 0xe1, 0x45, 0x4d, 0x54, 0x26, 0xac, + 0xe0, 0x77, 0x95, 0x58, 0x66, 0xd6, 0x54, 0x1c, 0xee, 0xda, 0x6e, 0xa3, 0x9d, 0x08, 0xef, 0x37, + 0x5d, 0x24, 0x15, 0xaa, 0xb8, 0xdf, 0xe6, 0xf5, 0x15, 0x7e, 0xb4, 0x8b, 0x64, 0x5c, 0x9d, 0xdf, + 0xe5, 0xe1, 0x73, 0x9a, 0x82, 0x63, 0xf2, 0xf7, 0xeb, 0xc8, 0x86, 0x8b, 0xcd, 0x4c, 0xc7, 0x5f, + 0x26, 0x0c, 0xff, 0x41, 0xc9, 0x66, 0xc6, 0x58, 0x12, 0x26, 0x96, 0xc6, 0xff, 0xa8, 0xb4, 0xc7, + 0xd1, 0xfe, 0x6e, 0xf8, 0x05, 0xca, 0x9b, 0x16, 0x33, 0x57, 0x2b, 0x4e, 0x03, 0xff, 0x49, 0xc9, + 0x9f, 0x44, 0xb7, 0x76, 0x97, 0x4f, 0x5a, 0xfc, 0x39, 0xaf, 0x3f, 0x3e, 0x74, 0xb5, 0xa8, 0x38, + 0x7c, 0xce, 0x5a, 0x24, 0x0d, 0xea, 0x8b, 0xbb, 0xfc, 0x1b, 0x79, 0x78, 0xae, 0xa5, 0x7d, 0xa4, + 0x6d, 0xfe, 0xa2, 0xbc, 0x9c, 0x42, 0x47, 0x7a, 0x7a, 0x99, 0xb4, 0xac, 0x49, 0xce, 0x19, 0x5d, + 0x0a, 0x38, 0xf1, 0xf1, 0x5f, 0x95, 0xab, 0xbb, 0xd0, 0xb1, 0x75, 0x5c, 0xa5, 0x0d, 0xff, 0x96, + 0xd7, 0xa7, 0x85, 0xd4, 0x26, 0x58, 0xa4, 0x9e, 0x67, 0x93, 0x44, 0xef, 0x3c, 0x3c, 0x00, 0xbf, + 0x6f, 0x23, 0x50, 0x51, 0x1f, 0x1d, 0x80, 0x3b, 0x3b, 0xa2, 0xe4, 0x6e, 0x7e, 0x64, 0x00, 0xde, + 0x25, 0x31, 0x14, 0x36, 0xf6, 0xa3, 0x0a, 0x7b, 0x37, 0x1a, 0x4b, 0xdd, 0x9f, 0x5d, 0x87, 0x30, + 0x37, 0x5c, 0x79, 0xb3, 0x2e, 0x66, 0xfc, 0x9c, 0x43, 0xb9, 0x1a, 0x00, 0x7f, 0x1f, 0xd0, 0x17, + 0xbb, 0x03, 0xeb, 0x1a, 0x89, 0x6d, 0xf6, 0x0f, 0x65, 0x90, 0xa9, 0x5c, 0x87, 0x41, 0x95, 0xf0, + 0x39, 0xc7, 0x0b, 0xb4, 0xa7, 0x7f, 0x2a, 0xc3, 0xf5, 0xc2, 0x53, 0x86, 0xc2, 0xdb, 0xbf, 0x94, + 0xd1, 0x19, 0x74, 0x6a, 0x9d, 0xf0, 0xbc, 0x80, 0xfb, 0xe7, 0x08, 0x6b, 0x05, 0xdc, 0x14, 0x7f, + 0x50, 0x6e, 0xff, 0xad, 0x14, 0x4e, 0xa3, 0xdb, 0xfe, 0x3f, 0x05, 0xe1, 0xff, 0x4d, 0x65, 0x7d, + 0x37, 0x3a, 0xbe, 0xbe, 0xf5, 0x79, 0xea, 0x50, 0xe5, 0xf7, 0x2d, 0x65, 0x79, 0x07, 0x3a, 0xdc, + 0x9f, 0xa5, 0xf0, 0xf7, 0xb6, 0xb2, 0xba, 0x07, 0x9d, 0xec, 0x69, 0x35, 0x69, 0xdb, 0x51, 0xc0, + 0x55, 0xa2, 0x2b, 0xfc, 0x4e, 0xbf, 0x4b, 0x93, 0x34, 0x16, 0x5e, 0xff, 0xd3, 0x6f, 0x96, 0xe2, + 0x98, 0x10, 0xf0, 0xc4, 0xa2, 0xfe, 0xb7, 0xdf, 0x2c, 0xb5, 0xa5, 0xf0, 0xf7, 0x7e, 0xa3, 0x4f, + 0x7f, 0x93, 0xb6, 0x5d, 0x09, 0x78, 0x22, 0xc5, 0x0f, 0x18, 0x7d, 0xfa, 0xd3, 0x96, 0xc2, 0xdf, + 0x07, 0xfb, 0xf5, 0x17, 0x7e, 0xf4, 0x49, 0x36, 0xed, 0x87, 0xfa, 0xf5, 0xa7, 0x2d, 0x85, 0xbf, + 0x0f, 0xf7, 0x6b, 0x35, 0x43, 0x1d, 0xd3, 0x56, 0xbe, 0x3e, 0x62, 0xc0, 0x03, 0x13, 0xb6, 0x12, + 0x7e, 0x1e, 0x52, 0x16, 0x77, 0xa2, 0xa3, 0x9d, 0x16, 0x67, 0x49, 0x7b, 0xae, 0x65, 0x36, 0x48, + 0x69, 0xcd, 0x73, 0x19, 0x4f, 0x6e, 0xfa, 0x47, 0x94, 0x5d, 0x66, 0xd0, 0x76, 0xb3, 0x13, 0xbe, + 0x1e, 0xed, 0x99, 0x93, 0xb2, 0xa9, 0xb6, 0x9d, 0x7a, 0x95, 0x13, 0x7d, 0x5a, 0xff, 0x58, 0xcf, + 0x9c, 0xb2, 0x56, 0xc2, 0xcf, 0xc7, 0x0d, 0x78, 0xa0, 0x77, 0x5a, 0xa4, 0x8a, 0xf7, 0x98, 0x32, + 0xbb, 0x0d, 0x1d, 0xec, 0xc3, 0x4c, 0x78, 0x7a, 0xdc, 0x80, 0x47, 0x79, 0x64, 0x92, 0x18, 0xe5, + 0x9f, 0x36, 0xe0, 0x51, 0x1e, 0x81, 0x8a, 0xfa, 0x8c, 0x01, 0x9f, 0x7a, 0xb4, 0xdc, 0x05, 0x93, + 0xd7, 0x9b, 0xe2, 0xbd, 0xfe, 0x59, 0x03, 0x9e, 0xe7, 0x11, 0xa9, 0xb1, 0xcf, 0x19, 0xf0, 0xc5, + 0x24, 0xfc, 0x50, 0x14, 0xb1, 0xd3, 0xd4, 0x6c, 0xa8, 0x0a, 0x7c, 0xde, 0x80, 0xef, 0x50, 0x19, + 0x5c, 0x64, 0xfe, 0x05, 0xa5, 0x9c, 0x39, 0x2d, 0xeb, 0x50, 0x6b, 0x6b, 0x67, 0x89, 0xfe, 0xa9, + 0xe3, 0x8b, 0x06, 0x7c, 0x60, 0x49, 0xd3, 0x42, 0xf7, 0x4b, 0x3d, 0x7b, 0x64, 0x9e, 0xae, 0x90, + 0x45, 0xb2, 0xcc, 0x88, 0xdf, 0xac, 0x72, 0x93, 0xe9, 0x6e, 0x7c, 0xd2, 0x80, 0x8f, 0x16, 0xb0, + 0x95, 0xf0, 0xf3, 0x65, 0xa3, 0xd7, 0xab, 0x24, 0x65, 0x11, 0xb7, 0xe2, 0x57, 0x94, 0x1b, 0xf0, + 0x4d, 0x97, 0x31, 0x12, 0x5e, 0xbe, 0xda, 0x6f, 0x36, 0xa9, 0x46, 0xfc, 0x5a, 0xbf, 0xd9, 0xe8, + 0x3e, 0xfc, 0xba, 0x01, 0x7f, 0x0a, 0x28, 0x65, 0x6e, 0xdc, 0xd7, 0x0c, 0xf8, 0x7e, 0x50, 0x4a, + 0xde, 0xb7, 0x5f, 0x31, 0xf4, 0x67, 0x96, 0x2d, 0x19, 0x48, 0x9e, 0x26, 0x5e, 0xed, 0xd2, 0x27, + 0x25, 0xd7, 0x17, 0x07, 0xe9, 0xe4, 0xbb, 0xf3, 0xd7, 0x06, 0x7c, 0xff, 0x49, 0xa0, 0x22, 0x81, + 0xd7, 0x0c, 0xf8, 0xfe, 0x53, 0x4a, 0x7c, 0x58, 0x78, 0xbd, 0xcb, 0xee, 0x98, 0xa2, 0x8e, 0xe9, + 0xd4, 0x93, 0x07, 0xa7, 0x1f, 0x0c, 0xc2, 0xbb, 0x43, 0x92, 0x0a, 0xfb, 0xe1, 0x20, 0x7c, 0x73, + 0x89, 0x05, 0xe3, 0xa2, 0xfc, 0x68, 0x10, 0xbe, 0xb9, 0x48, 0x36, 0x06, 0x7f, 0x3c, 0x08, 0xdf, + 0xae, 0x24, 0x28, 0x2b, 0xf8, 0x74, 0x6f, 0xb9, 0xf8, 0x76, 0xf5, 0x93, 0x41, 0xf8, 0xaa, 0xa1, + 0x40, 0x79, 0x18, 0x2f, 0xfb, 0x0d, 0xfc, 0xcc, 0x20, 0x7c, 0xd5, 0x90, 0x68, 0x85, 0x59, 0x11, + 0xf7, 0x6c, 0x6f, 0xdf, 0xd1, 0x8f, 0xb4, 0x02, 0xfc, 0x69, 0x6f, 0x41, 0xbd, 0x30, 0x3f, 0x93, + 0x31, 0x4e, 0x9c, 0x46, 0xd7, 0xaf, 0x52, 0x46, 0x2e, 0x52, 0x67, 0x78, 0xef, 0x78, 0xf4, 0x4b, + 0xff, 0xb8, 0xfa, 0xa5, 0x7f, 0xbc, 0xe4, 0x04, 0xad, 0xf0, 0xe7, 0x12, 0xf9, 0x95, 0x60, 0xe4, + 0xb9, 0x87, 0x06, 0x46, 0x73, 0x63, 0x43, 0x8b, 0xd7, 0x09, 0x9b, 0x39, 0x67, 0xe2, 0x5e, 0x34, + 0x14, 0x5a, 0xbb, 0x01, 0xef, 0xc7, 0xfc, 0x79, 0x69, 0x1e, 0xba, 0xac, 0x04, 0x7c, 0x62, 0x16, + 0x6d, 0x0a, 0xed, 0x2d, 0x31, 0xad, 0xfa, 0x8c, 0xe1, 0x05, 0x29, 0xb2, 0x41, 0x58, 0x86, 0x63, + 0x6e, 0xce, 0x99, 0x98, 0x43, 0x9b, 0x13, 0x42, 0x7d, 0x86, 0xf3, 0xa2, 0x54, 0xda, 0xa8, 0x95, + 0x44, 0x4c, 0x67, 0xd0, 0x0d, 0xa1, 0x14, 0xa7, 0x4e, 0xbb, 0x1f, 0x95, 0x97, 0xa4, 0x4a, 0x58, + 0x89, 0x1a, 0x75, 0xda, 0x13, 0xf3, 0xe8, 0xc6, 0x50, 0x61, 0xc9, 0x75, 0xb9, 0xed, 0x9a, 0x16, + 0x61, 0xfd, 0xe8, 0xbc, 0x2c, 0x75, 0xc2, 0x44, 0xa6, 0xb4, 0xe9, 0x44, 0x11, 0x85, 0x99, 0x5e, + 0x74, 0xdc, 0x8b, 0xcb, 0x7e, 0xab, 0x1f, 0xa5, 0x6b, 0x52, 0x29, 0xcc, 0x63, 0xc1, 0x9d, 0xf1, + 0x5b, 0x53, 0x77, 0xa0, 0xfd, 0x75, 0xb7, 0x35, 0xee, 0x9b, 0xdc, 0xf5, 0x9b, 0xd4, 0x36, 0x97, + 0x7c, 0xf5, 0xff, 0x79, 0xd8, 0x74, 0x49, 0x4b, 0x4d, 0x6d, 0xaa, 0x85, 0x7f, 0x94, 0x9d, 0xf3, + 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x69, 0x67, 0x5d, 0x1f, 0x22, 0x00, 0x00, +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.proto b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.proto new file mode 100644 index 00000000..3e0482e3 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/messages.proto @@ -0,0 +1,264 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages; + +/** + * Messages for TREZOR communication + */ + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessage"; + +import "google/protobuf/descriptor.proto"; + +/** + * Options for specifying message direction and type of wire (normal/debug) + */ +extend google.protobuf.EnumValueOptions { + optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR + optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC + optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader + optional bool wire_no_fsm = 50008; // message is not handled by TREZOR unless the USB stack is in tiny mode +} + +/** + * Mapping between TREZOR wire identifier (uint) and a protobuf message + */ +enum MessageType { + + // Management + MessageType_Initialize = 0 [(wire_in) = true, (wire_tiny) = true]; + MessageType_Ping = 1 [(wire_in) = true]; + MessageType_Success = 2 [(wire_out) = true]; + MessageType_Failure = 3 [(wire_out) = true]; + MessageType_ChangePin = 4 [(wire_in) = true]; + MessageType_WipeDevice = 5 [(wire_in) = true]; + MessageType_GetEntropy = 9 [(wire_in) = true]; + MessageType_Entropy = 10 [(wire_out) = true]; + MessageType_LoadDevice = 13 [(wire_in) = true]; + MessageType_ResetDevice = 14 [(wire_in) = true]; + MessageType_Features = 17 [(wire_out) = true]; + MessageType_PinMatrixRequest = 18 [(wire_out) = true]; + MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_Cancel = 20 [(wire_in) = true, (wire_tiny) = true]; + MessageType_ClearSession = 24 [(wire_in) = true]; + MessageType_ApplySettings = 25 [(wire_in) = true]; + MessageType_ButtonRequest = 26 [(wire_out) = true]; + MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_ApplyFlags = 28 [(wire_in) = true]; + MessageType_BackupDevice = 34 [(wire_in) = true]; + MessageType_EntropyRequest = 35 [(wire_out) = true]; + MessageType_EntropyAck = 36 [(wire_in) = true]; + MessageType_PassphraseRequest = 41 [(wire_out) = true]; + MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_PassphraseStateRequest = 77 [(wire_out) = true]; + MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_RecoveryDevice = 45 [(wire_in) = true]; + MessageType_WordRequest = 46 [(wire_out) = true]; + MessageType_WordAck = 47 [(wire_in) = true]; + MessageType_GetFeatures = 55 [(wire_in) = true]; + MessageType_SetU2FCounter = 63 [(wire_in) = true]; + + // Bootloader + MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; + MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; + + // Bitcoin + MessageType_GetPublicKey = 11 [(wire_in) = true]; + MessageType_PublicKey = 12 [(wire_out) = true]; + MessageType_SignTx = 15 [(wire_in) = true]; + MessageType_TxRequest = 21 [(wire_out) = true]; + MessageType_TxAck = 22 [(wire_in) = true]; + MessageType_GetAddress = 29 [(wire_in) = true]; + MessageType_Address = 30 [(wire_out) = true]; + MessageType_SignMessage = 38 [(wire_in) = true]; + MessageType_VerifyMessage = 39 [(wire_in) = true]; + MessageType_MessageSignature = 40 [(wire_out) = true]; + + // Crypto + MessageType_CipherKeyValue = 23 [(wire_in) = true]; + MessageType_CipheredKeyValue = 48 [(wire_out) = true]; + MessageType_SignIdentity = 53 [(wire_in) = true]; + MessageType_SignedIdentity = 54 [(wire_out) = true]; + MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; + MessageType_ECDHSessionKey = 62 [(wire_out) = true]; + MessageType_CosiCommit = 71 [(wire_in) = true]; + MessageType_CosiCommitment = 72 [(wire_out) = true]; + MessageType_CosiSign = 73 [(wire_in) = true]; + MessageType_CosiSignature = 74 [(wire_out) = true]; + + // Debug + MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true, (wire_tiny) = true]; + MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; + MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; + MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; + MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; + MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; + + // Ethereum + MessageType_EthereumGetPublicKey = 450 [(wire_in) = true]; + MessageType_EthereumPublicKey = 451 [(wire_out) = true]; + MessageType_EthereumGetAddress = 56 [(wire_in) = true]; + MessageType_EthereumAddress = 57 [(wire_out) = true]; + MessageType_EthereumSignTx = 58 [(wire_in) = true]; + MessageType_EthereumTxRequest = 59 [(wire_out) = true]; + MessageType_EthereumTxAck = 60 [(wire_in) = true]; + MessageType_EthereumSignMessage = 64 [(wire_in) = true]; + MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; + MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; + + // NEM + MessageType_NEMGetAddress = 67 [(wire_in) = true]; + MessageType_NEMAddress = 68 [(wire_out) = true]; + MessageType_NEMSignTx = 69 [(wire_in) = true]; + MessageType_NEMSignedTx = 70 [(wire_out) = true]; + MessageType_NEMDecryptMessage = 75 [(wire_in) = true]; + MessageType_NEMDecryptedMessage = 76 [(wire_out) = true]; + + // Lisk + MessageType_LiskGetAddress = 114 [(wire_in) = true]; + MessageType_LiskAddress = 115 [(wire_out) = true]; + MessageType_LiskSignTx = 116 [(wire_in) = true]; + MessageType_LiskSignedTx = 117 [(wire_out) = true]; + MessageType_LiskSignMessage = 118 [(wire_in) = true]; + MessageType_LiskMessageSignature = 119 [(wire_out) = true]; + MessageType_LiskVerifyMessage = 120 [(wire_in) = true]; + MessageType_LiskGetPublicKey = 121 [(wire_in) = true]; + MessageType_LiskPublicKey = 122 [(wire_out) = true]; + + // Tezos + MessageType_TezosGetAddress = 150 [(wire_in) = true]; + MessageType_TezosAddress = 151 [(wire_out) = true]; + MessageType_TezosSignTx = 152 [(wire_in) = true]; + MessageType_TezosSignedTx = 153 [(wire_out) = true]; + MessageType_TezosGetPublicKey = 154 [(wire_in) = true]; + MessageType_TezosPublicKey = 155 [(wire_out) = true]; + + // Stellar + MessageType_StellarSignTx = 202 [(wire_in) = true]; + MessageType_StellarTxOpRequest = 203 [(wire_out) = true]; + MessageType_StellarGetAddress = 207 [(wire_in) = true]; + MessageType_StellarAddress = 208 [(wire_out) = true]; + MessageType_StellarCreateAccountOp = 210 [(wire_in) = true]; + MessageType_StellarPaymentOp = 211 [(wire_in) = true]; + MessageType_StellarPathPaymentOp = 212 [(wire_in) = true]; + MessageType_StellarManageOfferOp = 213 [(wire_in) = true]; + MessageType_StellarCreatePassiveOfferOp = 214 [(wire_in) = true]; + MessageType_StellarSetOptionsOp = 215 [(wire_in) = true]; + MessageType_StellarChangeTrustOp = 216 [(wire_in) = true]; + MessageType_StellarAllowTrustOp = 217 [(wire_in) = true]; + MessageType_StellarAccountMergeOp = 218 [(wire_in) = true]; + // omitted: StellarInflationOp is not a supported operation, would be 219 + MessageType_StellarManageDataOp = 220 [(wire_in) = true]; + MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; + MessageType_StellarSignedTx = 230 [(wire_out) = true]; + + // TRON + MessageType_TronGetAddress = 250 [(wire_in) = true]; + MessageType_TronAddress = 251 [(wire_out) = true]; + MessageType_TronSignTx = 252 [(wire_in) = true]; + MessageType_TronSignedTx = 253 [(wire_out) = true]; + + // Cardano + // dropped Sign/VerifyMessage ids 300-302 + MessageType_CardanoSignTx = 303 [(wire_in) = true]; + MessageType_CardanoTxRequest = 304 [(wire_out) = true]; + MessageType_CardanoGetPublicKey = 305 [(wire_in) = true]; + MessageType_CardanoPublicKey = 306 [(wire_out) = true]; + MessageType_CardanoGetAddress = 307 [(wire_in) = true]; + MessageType_CardanoAddress = 308 [(wire_out) = true]; + MessageType_CardanoTxAck = 309 [(wire_in) = true]; + MessageType_CardanoSignedTx = 310 [(wire_out) = true]; + + // Ontology + MessageType_OntologyGetAddress = 350 [(wire_in) = true]; + MessageType_OntologyAddress = 351 [(wire_out) = true]; + MessageType_OntologyGetPublicKey = 352 [(wire_in) = true]; + MessageType_OntologyPublicKey = 353 [(wire_out) = true]; + MessageType_OntologySignTransfer = 354 [(wire_in) = true]; + MessageType_OntologySignedTransfer = 355 [(wire_out) = true]; + MessageType_OntologySignWithdrawOng = 356 [(wire_in) = true]; + MessageType_OntologySignedWithdrawOng = 357 [(wire_out) = true]; + MessageType_OntologySignOntIdRegister = 358 [(wire_in) = true]; + MessageType_OntologySignedOntIdRegister = 359 [(wire_out) = true]; + MessageType_OntologySignOntIdAddAttributes = 360 [(wire_in) = true]; + MessageType_OntologySignedOntIdAddAttributes = 361 [(wire_out) = true]; + + // Ripple + MessageType_RippleGetAddress = 400 [(wire_in) = true]; + MessageType_RippleAddress = 401 [(wire_out) = true]; + MessageType_RippleSignTx = 402 [(wire_in) = true]; + MessageType_RippleSignedTx = 403 [(wire_in) = true]; + + // Monero + MessageType_MoneroTransactionInitRequest = 501 [(wire_out) = true]; + MessageType_MoneroTransactionInitAck = 502 [(wire_out) = true]; + MessageType_MoneroTransactionSetInputRequest = 503 [(wire_out) = true]; + MessageType_MoneroTransactionSetInputAck = 504 [(wire_out) = true]; + MessageType_MoneroTransactionInputsPermutationRequest = 505 [(wire_out) = true]; + MessageType_MoneroTransactionInputsPermutationAck = 506 [(wire_out) = true]; + MessageType_MoneroTransactionInputViniRequest = 507 [(wire_out) = true]; + MessageType_MoneroTransactionInputViniAck = 508 [(wire_out) = true]; + MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_out) = true]; + MessageType_MoneroTransactionAllInputsSetAck = 510 [(wire_out) = true]; + MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_out) = true]; + MessageType_MoneroTransactionSetOutputAck = 512 [(wire_out) = true]; + MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_out) = true]; + MessageType_MoneroTransactionAllOutSetAck = 514 [(wire_out) = true]; + MessageType_MoneroTransactionSignInputRequest = 515 [(wire_out) = true]; + MessageType_MoneroTransactionSignInputAck = 516 [(wire_out) = true]; + MessageType_MoneroTransactionFinalRequest = 517 [(wire_out) = true]; + MessageType_MoneroTransactionFinalAck = 518 [(wire_out) = true]; + MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_out) = true]; + MessageType_MoneroKeyImageExportInitAck = 531 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncStepAck = 533 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncFinalAck = 535 [(wire_out) = true]; + MessageType_MoneroGetAddress = 540 [(wire_in) = true]; + MessageType_MoneroAddress = 541 [(wire_out) = true]; + MessageType_MoneroGetWatchKey = 542 [(wire_in) = true]; + MessageType_MoneroWatchKey = 543 [(wire_out) = true]; + MessageType_DebugMoneroDiagRequest = 546 [(wire_in) = true]; + MessageType_DebugMoneroDiagAck = 547 [(wire_out) = true]; + MessageType_MoneroGetTxKeyRequest = 550 [(wire_in) = true]; + MessageType_MoneroGetTxKeyAck = 551 [(wire_out) = true]; + MessageType_MoneroLiveRefreshStartRequest = 552 [(wire_in) = true]; + MessageType_MoneroLiveRefreshStartAck = 553 [(wire_out) = true]; + MessageType_MoneroLiveRefreshStepRequest = 554 [(wire_in) = true]; + MessageType_MoneroLiveRefreshStepAck = 555 [(wire_out) = true]; + MessageType_MoneroLiveRefreshFinalRequest = 556 [(wire_in) = true]; + MessageType_MoneroLiveRefreshFinalAck = 557 [(wire_out) = true]; + + // EOS + MessageType_EosGetPublicKey = 600 [(wire_in) = true]; + MessageType_EosPublicKey = 601 [(wire_out) = true]; + MessageType_EosSignTx = 602 [(wire_in) = true]; + MessageType_EosTxActionRequest = 603 [(wire_out) = true]; + MessageType_EosTxActionAck = 604 [(wire_in) = true]; + MessageType_EosSignedTx = 605 [(wire_out) = true]; + + // Binance + MessageType_BinanceGetAddress = 700 [(wire_in) = true]; + MessageType_BinanceAddress = 701 [(wire_out) = true]; + MessageType_BinanceGetPublicKey = 702 [(wire_in) = true]; + MessageType_BinancePublicKey = 703 [(wire_out) = true]; + MessageType_BinanceSignTx = 704 [(wire_in) = true]; + MessageType_BinanceTxRequest = 705 [(wire_out) = true]; + MessageType_BinanceTransferMsg = 706 [(wire_in) = true]; + MessageType_BinanceOrderMsg = 707 [(wire_in) = true]; + MessageType_BinanceCancelMsg = 708 [(wire_in) = true]; + MessageType_BinanceSignedTx = 709 [(wire_out) = true]; +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/trezor.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/trezor.go new file mode 100644 index 00000000..a259c1dc --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/trezor/trezor.go @@ -0,0 +1,70 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// This file contains the implementation for interacting with the Trezor hardware +// wallets. The wire protocol spec can be found on the SatoshiLabs website: +// https://wiki.trezor.io/Developers_guide-Message_Workflows + +// !!! STAHP !!! +// +// Before you touch the protocol files, you need to be aware of a breaking change +// that occurred between firmware versions 1.7.3->1.8.0 (Model One) and 2.0.10-> +// 2.1.0 (Model T). The Ethereum address representation was changed from the 20 +// byte binary blob to a 42 byte hex string. The upstream protocol buffer files +// only support the new format, so blindly pulling in a new spec will break old +// devices! +// +// The Trezor devs had the foresight to add the string version as a new message +// code instead of replacing the binary one. This means that the proto file can +// actually define both the old and the new versions as optional. Please ensure +// that you add back the old addresses everywhere (to avoid name clash. use the +// addressBin and addressHex names). +// +// If in doubt, reach out to @karalabe. + +// To regenerate the protocol files in this package: +// - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases +// - Build with the usual `./configure && make` and ensure it's on your $PATH +// - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor +// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go` +// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...` + +//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto + +// Package trezor contains the wire protocol. +package trezor + +import ( + "reflect" + + "github.com/golang/protobuf/proto" +) + +// Type returns the protocol buffer type number of a specific message. If the +// message is nil, this method panics! +func Type(msg proto.Message) uint16 { + return uint16(MessageType_value["MessageType_"+reflect.TypeOf(msg).Elem().Name()]) +} + +// Name returns the friendly message type name of a specific protocol buffer +// type number. +func Name(kind uint16) string { + name := MessageType_name[int32(kind)] + if len(name) < 12 { + return name + } + return name[12:] +} diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/wallet.go b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/wallet.go new file mode 100644 index 00000000..ed786d9b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/accounts/usbwallet/wallet.go @@ -0,0 +1,594 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package usbwallet implements support for USB hardware wallets. +package usbwallet + +import ( + "context" + "fmt" + "io" + "math/big" + "sync" + "time" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/karalabe/usb" +) + +// Maximum time between wallet health checks to detect USB unplugs. +const heartbeatCycle = time.Second + +// Minimum time to wait between self derivation attempts, even it the user is +// requesting accounts like crazy. +const selfDeriveThrottling = time.Second + +// driver defines the vendor specific functionality hardware wallets instances +// must implement to allow using them with the wallet lifecycle management. +type driver interface { + // Status returns a textual status to aid the user in the current state of the + // wallet. It also returns an error indicating any failure the wallet might have + // encountered. + Status() (string, error) + + // Open initializes access to a wallet instance. The passphrase parameter may + // or may not be used by the implementation of a particular wallet instance. + Open(device io.ReadWriter, passphrase string) error + + // Close releases any resources held by an open wallet instance. + Close() error + + // Heartbeat performs a sanity check against the hardware wallet to see if it + // is still online and healthy. + Heartbeat() error + + // Derive sends a derivation request to the USB device and returns the Ethereum + // address located on that path. + Derive(path accounts.DerivationPath) (common.Address, error) + + // SignTx sends the transaction to the USB device and waits for the user to confirm + // or deny the transaction. + SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) +} + +// wallet represents the common functionality shared by all USB hardware +// wallets to prevent reimplementing the same complex maintenance mechanisms +// for different vendors. +type wallet struct { + hub *Hub // USB hub scanning + driver driver // Hardware implementation of the low level device operations + url *accounts.URL // Textual URL uniquely identifying this wallet + + info usb.DeviceInfo // Known USB device infos about the wallet + device usb.Device // USB device advertising itself as a hardware wallet + + accounts []accounts.Account // List of derive accounts pinned on the hardware wallet + paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations + + deriveNextPaths []accounts.DerivationPath // Next derivation paths for account auto-discovery (multiple bases supported) + deriveNextAddrs []common.Address // Next derived account addresses for auto-discovery (multiple bases supported) + deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with + deriveReq chan chan struct{} // Channel to request a self-derivation on + deriveQuit chan chan error // Channel to terminate the self-deriver with + + healthQuit chan chan error + + // Locking a hardware wallet is a bit special. Since hardware devices are lower + // performing, any communication with them might take a non negligible amount of + // time. Worse still, waiting for user confirmation can take arbitrarily long, + // but exclusive communication must be upheld during. Locking the entire wallet + // in the mean time however would stall any parts of the system that don't want + // to communicate, just read some state (e.g. list the accounts). + // + // As such, a hardware wallet needs two locks to function correctly. A state + // lock can be used to protect the wallet's software-side internal state, which + // must not be held exclusively during hardware communication. A communication + // lock can be used to achieve exclusive access to the device itself, this one + // however should allow "skipping" waiting for operations that might want to + // use the device, but can live without too (e.g. account self-derivation). + // + // Since we have two locks, it's important to know how to properly use them: + // - Communication requires the `device` to not change, so obtaining the + // commsLock should be done after having a stateLock. + // - Communication must not disable read access to the wallet state, so it + // must only ever hold a *read* lock to stateLock. + commsLock chan struct{} // Mutex (buf=1) for the USB comms without keeping the state locked + stateLock sync.RWMutex // Protects read and write access to the wallet struct fields + + log log.Logger // Contextual logger to tag the base with its id +} + +// URL implements accounts.Wallet, returning the URL of the USB hardware device. +func (w *wallet) URL() accounts.URL { + return *w.url // Immutable, no need for a lock +} + +// Status implements accounts.Wallet, returning a custom status message from the +// underlying vendor-specific hardware wallet implementation. +func (w *wallet) Status() (string, error) { + w.stateLock.RLock() // No device communication, state lock is enough + defer w.stateLock.RUnlock() + + status, failure := w.driver.Status() + if w.device == nil { + return "Closed", failure + } + return status, failure +} + +// Open implements accounts.Wallet, attempting to open a USB connection to the +// hardware wallet. +func (w *wallet) Open(passphrase string) error { + w.stateLock.Lock() // State lock is enough since there's no connection yet at this point + defer w.stateLock.Unlock() + + // If the device was already opened once, refuse to try again + if w.paths != nil { + return accounts.ErrWalletAlreadyOpen + } + // Make sure the actual device connection is done only once + if w.device == nil { + device, err := w.info.Open() + if err != nil { + return err + } + w.device = device + w.commsLock = make(chan struct{}, 1) + w.commsLock <- struct{}{} // Enable lock + } + // Delegate device initialization to the underlying driver + if err := w.driver.Open(w.device, passphrase); err != nil { + return err + } + // Connection successful, start life-cycle management + w.paths = make(map[common.Address]accounts.DerivationPath) + + w.deriveReq = make(chan chan struct{}) + w.deriveQuit = make(chan chan error) + w.healthQuit = make(chan chan error) + + go w.heartbeat() + go w.selfDerive() + + // Notify anyone listening for wallet events that a new device is accessible + go w.hub.updateFeed.Send(accounts.WalletEvent{Wallet: w, Kind: accounts.WalletOpened}) + + return nil +} + +// heartbeat is a health check loop for the USB wallets to periodically verify +// whether they are still present or if they malfunctioned. +func (w *wallet) heartbeat() { + w.log.Debug("USB wallet health-check started") + defer w.log.Debug("USB wallet health-check stopped") + + // Execute heartbeat checks until termination or error + var ( + errc chan error + err error + ) + for errc == nil && err == nil { + // Wait until termination is requested or the heartbeat cycle arrives + select { + case errc = <-w.healthQuit: + // Termination requested + continue + case <-time.After(heartbeatCycle): + // Heartbeat time + } + // Execute a tiny data exchange to see responsiveness + w.stateLock.RLock() + if w.device == nil { + // Terminated while waiting for the lock + w.stateLock.RUnlock() + continue + } + <-w.commsLock // Don't lock state while resolving version + err = w.driver.Heartbeat() + w.commsLock <- struct{}{} + w.stateLock.RUnlock() + + if err != nil { + w.stateLock.Lock() // Lock state to tear the wallet down + w.close() + w.stateLock.Unlock() + } + // Ignore non hardware related errors + err = nil + } + // In case of error, wait for termination + if err != nil { + w.log.Debug("USB wallet health-check failed", "err", err) + errc = <-w.healthQuit + } + errc <- err +} + +// Close implements accounts.Wallet, closing the USB connection to the device. +func (w *wallet) Close() error { + // Ensure the wallet was opened + w.stateLock.RLock() + hQuit, dQuit := w.healthQuit, w.deriveQuit + w.stateLock.RUnlock() + + // Terminate the health checks + var herr error + if hQuit != nil { + errc := make(chan error) + hQuit <- errc + herr = <-errc // Save for later, we *must* close the USB + } + // Terminate the self-derivations + var derr error + if dQuit != nil { + errc := make(chan error) + dQuit <- errc + derr = <-errc // Save for later, we *must* close the USB + } + // Terminate the device connection + w.stateLock.Lock() + defer w.stateLock.Unlock() + + w.healthQuit = nil + w.deriveQuit = nil + w.deriveReq = nil + + if err := w.close(); err != nil { + return err + } + if herr != nil { + return herr + } + return derr +} + +// close is the internal wallet closer that terminates the USB connection and +// resets all the fields to their defaults. +// +// Note, close assumes the state lock is held! +func (w *wallet) close() error { + // Allow duplicate closes, especially for health-check failures + if w.device == nil { + return nil + } + // Close the device, clear everything, then return + w.device.Close() + w.device = nil + + w.accounts, w.paths = nil, nil + return w.driver.Close() +} + +// Accounts implements accounts.Wallet, returning the list of accounts pinned to +// the USB hardware wallet. If self-derivation was enabled, the account list is +// periodically expanded based on current chain state. +func (w *wallet) Accounts() []accounts.Account { + // Attempt self-derivation if it's running + reqc := make(chan struct{}, 1) + select { + case w.deriveReq <- reqc: + // Self-derivation request accepted, wait for it + <-reqc + default: + // Self-derivation offline, throttled or busy, skip + } + // Return whatever account list we ended up with + w.stateLock.RLock() + defer w.stateLock.RUnlock() + + cpy := make([]accounts.Account, len(w.accounts)) + copy(cpy, w.accounts) + return cpy +} + +// selfDerive is an account derivation loop that upon request attempts to find +// new non-zero accounts. +func (w *wallet) selfDerive() { + w.log.Debug("USB wallet self-derivation started") + defer w.log.Debug("USB wallet self-derivation stopped") + + // Execute self-derivations until termination or error + var ( + reqc chan struct{} + errc chan error + err error + ) + for errc == nil && err == nil { + // Wait until either derivation or termination is requested + select { + case errc = <-w.deriveQuit: + // Termination requested + continue + case reqc = <-w.deriveReq: + // Account discovery requested + } + // Derivation needs a chain and device access, skip if either unavailable + w.stateLock.RLock() + if w.device == nil || w.deriveChain == nil { + w.stateLock.RUnlock() + reqc <- struct{}{} + continue + } + select { + case <-w.commsLock: + default: + w.stateLock.RUnlock() + reqc <- struct{}{} + continue + } + // Device lock obtained, derive the next batch of accounts + var ( + accs []accounts.Account + paths []accounts.DerivationPath + + nextPaths = append([]accounts.DerivationPath{}, w.deriveNextPaths...) + nextAddrs = append([]common.Address{}, w.deriveNextAddrs...) + + context = context.Background() + ) + for i := 0; i < len(nextAddrs); i++ { + for empty := false; !empty; { + // Retrieve the next derived Ethereum account + if nextAddrs[i] == (common.Address{}) { + if nextAddrs[i], err = w.driver.Derive(nextPaths[i]); err != nil { + w.log.Warn("USB wallet account derivation failed", "err", err) + break + } + } + // Check the account's status against the current chain state + var ( + balance *big.Int + nonce uint64 + ) + balance, err = w.deriveChain.BalanceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("USB wallet balance retrieval failed", "err", err) + break + } + nonce, err = w.deriveChain.NonceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("USB wallet nonce retrieval failed", "err", err) + break + } + // If the next account is empty, stop self-derivation, but add for the last base path + if balance.Sign() == 0 && nonce == 0 { + empty = true + if i < len(nextAddrs)-1 { + break + } + } + // We've just self-derived a new account, start tracking it locally + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) + paths = append(paths, path) + + account := accounts.Account{ + Address: nextAddrs[i], + URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, + } + accs = append(accs, account) + + // Display a log message to the user for new (or previously empty accounts) + if _, known := w.paths[nextAddrs[i]]; !known || (!empty && nextAddrs[i] == w.deriveNextAddrs[i]) { + w.log.Info("USB wallet discovered new account", "address", nextAddrs[i], "path", path, "balance", balance, "nonce", nonce) + } + // Fetch the next potential account + if !empty { + nextAddrs[i] = common.Address{} + nextPaths[i][len(nextPaths[i])-1]++ + } + } + } + // Self derivation complete, release device lock + w.commsLock <- struct{}{} + w.stateLock.RUnlock() + + // Insert any accounts successfully derived + w.stateLock.Lock() + for i := 0; i < len(accs); i++ { + if _, ok := w.paths[accs[i].Address]; !ok { + w.accounts = append(w.accounts, accs[i]) + w.paths[accs[i].Address] = paths[i] + } + } + // Shift the self-derivation forward + // TODO(karalabe): don't overwrite changes from wallet.SelfDerive + w.deriveNextAddrs = nextAddrs + w.deriveNextPaths = nextPaths + w.stateLock.Unlock() + + // Notify the user of termination and loop after a bit of time (to avoid trashing) + reqc <- struct{}{} + if err == nil { + select { + case errc = <-w.deriveQuit: + // Termination requested, abort + case <-time.After(selfDeriveThrottling): + // Waited enough, willing to self-derive again + } + } + } + // In case of error, wait for termination + if err != nil { + w.log.Debug("USB wallet self-derivation failed", "err", err) + errc = <-w.deriveQuit + } + errc <- err +} + +// Contains implements accounts.Wallet, returning whether a particular account is +// or is not pinned into this wallet instance. Although we could attempt to resolve +// unpinned accounts, that would be an non-negligible hardware operation. +func (w *wallet) Contains(account accounts.Account) bool { + w.stateLock.RLock() + defer w.stateLock.RUnlock() + + _, exists := w.paths[account.Address] + return exists +} + +// Derive implements accounts.Wallet, deriving a new account at the specific +// derivation path. If pin is set to true, the account will be added to the list +// of tracked accounts. +func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + // Try to derive the actual account and update its URL if successful + w.stateLock.RLock() // Avoid device disappearing during derivation + + if w.device == nil { + w.stateLock.RUnlock() + return accounts.Account{}, accounts.ErrWalletClosed + } + <-w.commsLock // Avoid concurrent hardware access + address, err := w.driver.Derive(path) + w.commsLock <- struct{}{} + + w.stateLock.RUnlock() + + // If an error occurred or no pinning was requested, return + if err != nil { + return accounts.Account{}, err + } + account := accounts.Account{ + Address: address, + URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, + } + if !pin { + return account, nil + } + // Pinning needs to modify the state + w.stateLock.Lock() + defer w.stateLock.Unlock() + + if _, ok := w.paths[address]; !ok { + w.accounts = append(w.accounts, account) + w.paths[address] = path + } + return account, nil +} + +// SelfDerive sets a base account derivation path from which the wallet attempts +// to discover non zero accounts and automatically add them to list of tracked +// accounts. +// +// Note, self derivaton will increment the last component of the specified path +// opposed to decending into a child path to allow discovering accounts starting +// from non zero components. +// +// Some hardware wallets switched derivation paths through their evolution, so +// this method supports providing multiple bases to discover old user accounts +// too. Only the last base will be used to derive the next empty account. +// +// You can disable automatic account discovery by calling SelfDerive with a nil +// chain state reader. +func (w *wallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { + w.stateLock.Lock() + defer w.stateLock.Unlock() + + w.deriveNextPaths = make([]accounts.DerivationPath, len(bases)) + for i, base := range bases { + w.deriveNextPaths[i] = make(accounts.DerivationPath, len(base)) + copy(w.deriveNextPaths[i][:], base[:]) + } + w.deriveNextAddrs = make([]common.Address, len(bases)) + w.deriveChain = chain +} + +// signHash implements accounts.Wallet, however signing arbitrary data is not +// supported for hardware wallets, so this method will always return an error. +func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { + return nil, accounts.ErrNotSupported +} + +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.signHash(account, crypto.Keccak256(data)) +} + +// SignDataWithPassphrase implements accounts.Wallet, attempting to sign the given +// data with the given account using passphrase as extra authentication. +// Since USB wallets don't rely on passphrases, these are silently ignored. +func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + return w.SignData(account, mimeType, data) +} + +func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.signHash(account, accounts.TextHash(text)) +} + +// SignTx implements accounts.Wallet. It sends the transaction over to the Ledger +// wallet to request a confirmation from the user. It returns either the signed +// transaction or a failure if the user denied the transaction. +// +// Note, if the version of the Ethereum application running on the Ledger wallet is +// too old to sign EIP-155 transactions, but such is requested nonetheless, an error +// will be returned opposed to silently signing in Homestead mode. +func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + w.stateLock.RLock() // Comms have own mutex, this is for the state fields + defer w.stateLock.RUnlock() + + // If the wallet is closed, abort + if w.device == nil { + return nil, accounts.ErrWalletClosed + } + // Make sure the requested account is contained within + path, ok := w.paths[account.Address] + if !ok { + return nil, accounts.ErrUnknownAccount + } + // All infos gathered and metadata checks out, request signing + <-w.commsLock + defer func() { w.commsLock <- struct{}{} }() + + // Ensure the device isn't screwed with while user confirmation is pending + // TODO(karalabe): remove if hotplug lands on Windows + w.hub.commsLock.Lock() + w.hub.commsPend++ + w.hub.commsLock.Unlock() + + defer func() { + w.hub.commsLock.Lock() + w.hub.commsPend-- + w.hub.commsLock.Unlock() + }() + // Sign the transaction and verify the sender to avoid hardware fault surprises + sender, signed, err := w.driver.SignTx(path, tx, chainID) + if err != nil { + return nil, err + } + if sender != account.Address { + return nil, fmt.Errorf("signer mismatch: expected %s, got %s", account.Address.Hex(), sender.Hex()) + } + return signed, nil +} + +// SignHashWithPassphrase implements accounts.Wallet, however signing arbitrary +// data is not supported for Ledger wallets, so this method will always return +// an error. +func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return w.SignText(account, accounts.TextHash(text)) +} + +// SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given +// transaction with the given account using passphrase as extra authentication. +// Since USB wallets don't rely on passphrases, these are silently ignored. +func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + return w.SignTx(account, tx, chainID) +} diff --git a/vendor/github.com/ethereum/go-ethereum/appveyor.yml b/vendor/github.com/ethereum/go-ethereum/appveyor.yml new file mode 100644 index 00000000..d3ed3785 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/appveyor.yml @@ -0,0 +1,40 @@ +os: Visual Studio 2015 + +# Clone directly into GOPATH. +clone_folder: C:\gopath\src\github.com\ethereum\go-ethereum +clone_depth: 5 +version: "{branch}.{build}" +environment: + global: + GOPATH: C:\gopath + CC: gcc.exe + matrix: + - GETH_ARCH: amd64 + MSYS2_ARCH: x86_64 + MSYS2_BITS: 64 + MSYSTEM: MINGW64 + PATH: C:\msys64\mingw64\bin\;C:\Program Files (x86)\NSIS\;%PATH% + - GETH_ARCH: 386 + MSYS2_ARCH: i686 + MSYS2_BITS: 32 + MSYSTEM: MINGW32 + PATH: C:\msys64\mingw32\bin\;C:\Program Files (x86)\NSIS\;%PATH% + +install: + - git submodule update --init + - rmdir C:\go /s /q + - appveyor DownloadFile https://dl.google.com/go/go1.12.5.windows-%GETH_ARCH%.zip + - 7z x go1.12.5.windows-%GETH_ARCH%.zip -y -oC:\ > NUL + - go version + - gcc --version + +build_script: + - go run build\ci.go install + +after_build: + - go run build\ci.go archive -type zip -signer WINDOWS_SIGNING_KEY -upload gethstore/builds + - go run build\ci.go nsis -signer WINDOWS_SIGNING_KEY -upload gethstore/builds + +test_script: + - set CGO_ENABLED=1 + - go run build\ci.go test -coverage diff --git a/vendor/github.com/ethereum/go-ethereum/build/ci.go b/vendor/github.com/ethereum/go-ethereum/build/ci.go new file mode 100644 index 00000000..8be52338 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/build/ci.go @@ -0,0 +1,1078 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build none + +/* +The ci command is called from Continuous Integration scripts. + +Usage: go run build/ci.go + +Available commands are: + + install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables + test [ -coverage ] [ packages... ] -- runs the tests + lint -- runs certain pre-selected linters + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artifacts + importkeys -- imports signing keys from env + debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package + nsis -- creates a Windows NSIS installer + aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive + xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework + xgo [ -alltools ] [ options ] -- cross builds according to options + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore + +For all commands, -n prevents execution of external programs (dry run mode). + +*/ +package main + +import ( + "bufio" + "bytes" + "encoding/base64" + "flag" + "fmt" + "go/parser" + "go/token" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "runtime" + "strings" + "time" + + "github.com/ethereum/go-ethereum/internal/build" + "github.com/ethereum/go-ethereum/params" +) + +var ( + // Files that end up in the geth*.zip archive. + gethArchiveFiles = []string{ + "COPYING", + executablePath("geth"), + } + + // Files that end up in the geth-alltools*.zip archive. + allToolsArchiveFiles = []string{ + "COPYING", + executablePath("abigen"), + executablePath("bootnode"), + executablePath("evm"), + executablePath("geth"), + executablePath("puppeth"), + executablePath("rlpdump"), + executablePath("wnode"), + executablePath("clef"), + } + + // A debian package is created for all executables listed here. + debExecutables = []debExecutable{ + { + BinaryName: "abigen", + Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", + }, + { + BinaryName: "bootnode", + Description: "Ethereum bootnode.", + }, + { + BinaryName: "evm", + Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", + }, + { + BinaryName: "geth", + Description: "Ethereum CLI client.", + }, + { + BinaryName: "puppeth", + Description: "Ethereum private network manager.", + }, + { + BinaryName: "rlpdump", + Description: "Developer utility tool that prints RLP structures.", + }, + { + BinaryName: "wnode", + Description: "Ethereum Whisper diagnostic tool", + }, + { + BinaryName: "clef", + Description: "Ethereum account management tool.", + }, + } + + // A debian package is created for all executables listed here. + + debEthereum = debPackage{ + Name: "ethereum", + Version: params.Version, + Executables: debExecutables, + } + + // Debian meta packages to build and push to Ubuntu PPA + debPackages = []debPackage{ + debEthereum, + } + + // Distros for which packages are created. + // Note: vivid is unsupported because there is no golang-1.6 package for it. + // Note: wily is unsupported because it was officially deprecated on Launchpad. + // Note: yakkety is unsupported because it was officially deprecated on Launchpad. + // Note: zesty is unsupported because it was officially deprecated on Launchpad. + // Note: artful is unsupported because it was officially deprecated on Launchpad. + debDistros = []string{"trusty", "xenial", "bionic", "cosmic", "disco"} +) + +var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) + +func executablePath(name string) string { + if runtime.GOOS == "windows" { + name += ".exe" + } + return filepath.Join(GOBIN, name) +} + +func main() { + log.SetFlags(log.Lshortfile) + + if _, err := os.Stat(filepath.Join("build", "ci.go")); os.IsNotExist(err) { + log.Fatal("this script must be run from the root of the repository") + } + if len(os.Args) < 2 { + log.Fatal("need subcommand as first argument") + } + switch os.Args[1] { + case "install": + doInstall(os.Args[2:]) + case "test": + doTest(os.Args[2:]) + case "lint": + doLint(os.Args[2:]) + case "archive": + doArchive(os.Args[2:]) + case "debsrc": + doDebianSource(os.Args[2:]) + case "nsis": + doWindowsInstaller(os.Args[2:]) + case "aar": + doAndroidArchive(os.Args[2:]) + case "xcode": + doXCodeFramework(os.Args[2:]) + case "xgo": + doXgo(os.Args[2:]) + case "purge": + doPurge(os.Args[2:]) + default: + log.Fatal("unknown command ", os.Args[1]) + } +} + +// Compiling + +func doInstall(cmdline []string) { + var ( + arch = flag.String("arch", "", "Architecture to cross build for") + cc = flag.String("cc", "", "C compiler to cross build with") + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Check Go version. People regularly open issues about compilation + // failure with outdated Go. This should save them the trouble. + if !strings.Contains(runtime.Version(), "devel") { + // Figure out the minor version number since we can't textually compare (1.10 < 1.9) + var minor int + fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor) + + if minor < 9 { + log.Println("You have Go version", runtime.Version()) + log.Println("go-ethereum requires at least Go version 1.9 and cannot") + log.Println("be compiled with an earlier version. Please upgrade your Go installation.") + os.Exit(1) + } + } + // Compile packages given as arguments, or everything if there are no arguments. + packages := []string{"./..."} + if flag.NArg() > 0 { + packages = flag.Args() + } + packages = build.ExpandPackagesNoVendor(packages) + + if *arch == "" || *arch == runtime.GOARCH { + goinstall := goTool("install", buildFlags(env)...) + goinstall.Args = append(goinstall.Args, "-v") + goinstall.Args = append(goinstall.Args, packages...) + build.MustRun(goinstall) + return + } + // If we are cross compiling to ARMv5 ARMv6 or ARMv7, clean any previous builds + if *arch == "arm" { + os.RemoveAll(filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_arm")) + for _, path := range filepath.SplitList(build.GOPATH()) { + os.RemoveAll(filepath.Join(path, "pkg", runtime.GOOS+"_arm")) + } + } + // Seems we are cross compiling, work around forbidden GOBIN + goinstall := goToolArch(*arch, *cc, "install", buildFlags(env)...) + goinstall.Args = append(goinstall.Args, "-v") + goinstall.Args = append(goinstall.Args, []string{"-buildmode", "archive"}...) + goinstall.Args = append(goinstall.Args, packages...) + build.MustRun(goinstall) + + if cmds, err := ioutil.ReadDir("cmd"); err == nil { + for _, cmd := range cmds { + pkgs, err := parser.ParseDir(token.NewFileSet(), filepath.Join(".", "cmd", cmd.Name()), nil, parser.PackageClauseOnly) + if err != nil { + log.Fatal(err) + } + for name := range pkgs { + if name == "main" { + gobuild := goToolArch(*arch, *cc, "build", buildFlags(env)...) + gobuild.Args = append(gobuild.Args, "-v") + gobuild.Args = append(gobuild.Args, []string{"-o", executablePath(cmd.Name())}...) + gobuild.Args = append(gobuild.Args, "."+string(filepath.Separator)+filepath.Join("cmd", cmd.Name())) + build.MustRun(gobuild) + break + } + } + } + } +} + +func buildFlags(env build.Environment) (flags []string) { + var ld []string + if env.Commit != "" { + ld = append(ld, "-X", "main.gitCommit="+env.Commit) + ld = append(ld, "-X", "main.gitDate="+env.Date) + } + if runtime.GOOS == "darwin" { + ld = append(ld, "-s") + } + + if len(ld) > 0 { + flags = append(flags, "-ldflags", strings.Join(ld, " ")) + } + return flags +} + +func goTool(subcmd string, args ...string) *exec.Cmd { + return goToolArch(runtime.GOARCH, os.Getenv("CC"), subcmd, args...) +} + +func goToolArch(arch string, cc string, subcmd string, args ...string) *exec.Cmd { + cmd := build.GoTool(subcmd, args...) + cmd.Env = []string{"GOPATH=" + build.GOPATH()} + if arch == "" || arch == runtime.GOARCH { + cmd.Env = append(cmd.Env, "GOBIN="+GOBIN) + } else { + cmd.Env = append(cmd.Env, "CGO_ENABLED=1") + cmd.Env = append(cmd.Env, "GOARCH="+arch) + } + if cc != "" { + cmd.Env = append(cmd.Env, "CC="+cc) + } + for _, e := range os.Environ() { + if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { + continue + } + cmd.Env = append(cmd.Env, e) + } + return cmd +} + +// Running The Tests +// +// "tests" also includes static analysis tools such as vet. + +func doTest(cmdline []string) { + coverage := flag.Bool("coverage", false, "Whether to record code coverage") + flag.CommandLine.Parse(cmdline) + env := build.Env() + + packages := []string{"./..."} + if len(flag.CommandLine.Args()) > 0 { + packages = flag.CommandLine.Args() + } + packages = build.ExpandPackagesNoVendor(packages) + + // Run the actual tests. + // Test a single package at a time. CI builders are slow + // and some tests run into timeouts under load. + gotest := goTool("test", buildFlags(env)...) + gotest.Args = append(gotest.Args, "-p", "1", "-timeout", "5m") + if *coverage { + gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover") + } + + gotest.Args = append(gotest.Args, packages...) + build.MustRun(gotest) +} + +// runs gometalinter on requested packages +func doLint(cmdline []string) { + flag.CommandLine.Parse(cmdline) + + packages := []string{"./..."} + if len(flag.CommandLine.Args()) > 0 { + packages = flag.CommandLine.Args() + } + // Get metalinter and install all supported linters + build.MustRun(goTool("get", "gopkg.in/alecthomas/gometalinter.v2")) + build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), "--install") + + // Run fast linters batched together + configs := []string{ + "--vendor", + "--tests", + "--deadline=2m", + "--disable-all", + "--enable=goimports", + "--enable=varcheck", + "--enable=vet", + "--enable=gofmt", + "--enable=misspell", + "--enable=goconst", + "--min-occurrences=6", // for goconst + } + build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...) + + // Run slow linters one by one + for _, linter := range []string{"unconvert", "gosimple"} { + configs = []string{"--vendor", "--tests", "--deadline=10m", "--disable-all", "--enable=" + linter} + build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...) + } +} + +// Release Packaging +func doArchive(cmdline []string) { + var ( + arch = flag.String("arch", runtime.GOARCH, "Architecture cross packaging") + atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + ext string + ) + flag.CommandLine.Parse(cmdline) + switch *atype { + case "zip": + ext = ".zip" + case "tar": + ext = ".tar.gz" + default: + log.Fatal("unknown archive type: ", atype) + } + + var ( + env = build.Env() + + basegeth = archiveBasename(*arch, params.ArchiveVersion(env.Commit)) + geth = "geth-" + basegeth + ext + alltools = "geth-alltools-" + basegeth + ext + ) + maybeSkipArchive(env) + if err := build.WriteArchive(geth, gethArchiveFiles); err != nil { + log.Fatal(err) + } + if err := build.WriteArchive(alltools, allToolsArchiveFiles); err != nil { + log.Fatal(err) + } + for _, archive := range []string{geth, alltools} { + if err := archiveUpload(archive, *upload, *signer); err != nil { + log.Fatal(err) + } + } +} + +func archiveBasename(arch string, archiveVersion string) string { + platform := runtime.GOOS + "-" + arch + if arch == "arm" { + platform += os.Getenv("GOARM") + } + if arch == "android" { + platform = "android-all" + } + if arch == "ios" { + platform = "ios-all" + } + return platform + "-" + archiveVersion +} + +func archiveUpload(archive string, blobstore string, signer string) error { + // If signing was requested, generate the signature files + if signer != "" { + key := getenvBase64(signer) + if err := build.PGPSignFile(archive, archive+".asc", string(key)); err != nil { + return err + } + } + // If uploading to Azure was requested, push the archive possibly with its signature + if blobstore != "" { + auth := build.AzureBlobstoreConfig{ + Account: strings.Split(blobstore, "/")[0], + Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), + Container: strings.SplitN(blobstore, "/", 2)[1], + } + if err := build.AzureBlobstoreUpload(archive, filepath.Base(archive), auth); err != nil { + return err + } + if signer != "" { + if err := build.AzureBlobstoreUpload(archive+".asc", filepath.Base(archive+".asc"), auth); err != nil { + return err + } + } + } + return nil +} + +// skips archiving for some build configurations. +func maybeSkipArchive(env build.Environment) { + if env.IsPullRequest { + log.Printf("skipping because this is a PR build") + os.Exit(0) + } + if env.IsCronJob { + log.Printf("skipping because this is a cron job") + os.Exit(0) + } + if env.Branch != "master" && !strings.HasPrefix(env.Tag, "v1.") { + log.Printf("skipping because branch %q, tag %q is not on the whitelist", env.Branch, env.Tag) + os.Exit(0) + } +} + +// Debian Packaging +func doDebianSource(cmdline []string) { + var ( + signer = flag.String("signer", "", `Signing key name, also used as package author`) + upload = flag.String("upload", "", `Where to upload the source package (usually "ethereum/ethereum")`) + sshUser = flag.String("sftp-user", "", `Username for SFTP upload (usually "geth-ci")`) + workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) + now = time.Now() + ) + flag.CommandLine.Parse(cmdline) + *workdir = makeWorkdir(*workdir) + env := build.Env() + maybeSkipArchive(env) + + // Import the signing key. + if key := getenvBase64("PPA_SIGNING_KEY"); len(key) > 0 { + gpg := exec.Command("gpg", "--import") + gpg.Stdin = bytes.NewReader(key) + build.MustRun(gpg) + } + + // Create Debian packages and upload them + for _, pkg := range debPackages { + for _, distro := range debDistros { + meta := newDebMetadata(distro, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables) + pkgdir := stageDebianSource(*workdir, meta) + debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc", "-d", "-Zxz") + debuild.Dir = pkgdir + build.MustRun(debuild) + + var ( + basename = fmt.Sprintf("%s_%s", meta.Name(), meta.VersionString()) + source = filepath.Join(*workdir, basename+".tar.xz") + dsc = filepath.Join(*workdir, basename+".dsc") + changes = filepath.Join(*workdir, basename+"_source.changes") + ) + if *signer != "" { + build.MustRunCommand("debsign", changes) + } + if *upload != "" { + ppaUpload(*workdir, *upload, *sshUser, []string{source, dsc, changes}) + } + } + } +} + +func ppaUpload(workdir, ppa, sshUser string, files []string) { + p := strings.Split(ppa, "/") + if len(p) != 2 { + log.Fatal("-upload PPA name must contain single /") + } + if sshUser == "" { + sshUser = p[0] + } + incomingDir := fmt.Sprintf("~%s/ubuntu/%s", p[0], p[1]) + // Create the SSH identity file if it doesn't exist. + var idfile string + if sshkey := getenvBase64("PPA_SSH_KEY"); len(sshkey) > 0 { + idfile = filepath.Join(workdir, "sshkey") + if _, err := os.Stat(idfile); os.IsNotExist(err) { + ioutil.WriteFile(idfile, sshkey, 0600) + } + } + // Upload + dest := sshUser + "@ppa.launchpad.net" + if err := build.UploadSFTP(idfile, dest, incomingDir, files); err != nil { + log.Fatal(err) + } +} + +func getenvBase64(variable string) []byte { + dec, err := base64.StdEncoding.DecodeString(os.Getenv(variable)) + if err != nil { + log.Fatal("invalid base64 " + variable) + } + return []byte(dec) +} + +func makeWorkdir(wdflag string) string { + var err error + if wdflag != "" { + err = os.MkdirAll(wdflag, 0744) + } else { + wdflag, err = ioutil.TempDir("", "geth-build-") + } + if err != nil { + log.Fatal(err) + } + return wdflag +} + +func isUnstableBuild(env build.Environment) bool { + if env.Tag != "" { + return false + } + return true +} + +type debPackage struct { + Name string // the name of the Debian package to produce, e.g. "ethereum" + Version string // the clean version of the debPackage, e.g. 1.8.12, without any metadata + Executables []debExecutable // executables to be included in the package +} + +type debMetadata struct { + Env build.Environment + + PackageName string + + // go-ethereum version being built. Note that this + // is not the debian package version. The package version + // is constructed by VersionString. + Version string + + Author string // "name ", also selects signing key + Distro, Time string + Executables []debExecutable +} + +type debExecutable struct { + PackageName string + BinaryName string + Description string +} + +// Package returns the name of the package if present, or +// fallbacks to BinaryName +func (d debExecutable) Package() string { + if d.PackageName != "" { + return d.PackageName + } + return d.BinaryName +} + +func newDebMetadata(distro, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata { + if author == "" { + // No signing key, use default author. + author = "Ethereum Builds " + } + return debMetadata{ + PackageName: name, + Env: env, + Author: author, + Distro: distro, + Version: version, + Time: t.Format(time.RFC1123Z), + Executables: exes, + } +} + +// Name returns the name of the metapackage that depends +// on all executable packages. +func (meta debMetadata) Name() string { + if isUnstableBuild(meta.Env) { + return meta.PackageName + "-unstable" + } + return meta.PackageName +} + +// VersionString returns the debian version of the packages. +func (meta debMetadata) VersionString() string { + vsn := meta.Version + if meta.Env.Buildnum != "" { + vsn += "+build" + meta.Env.Buildnum + } + if meta.Distro != "" { + vsn += "+" + meta.Distro + } + return vsn +} + +// ExeList returns the list of all executable packages. +func (meta debMetadata) ExeList() string { + names := make([]string, len(meta.Executables)) + for i, e := range meta.Executables { + names[i] = meta.ExeName(e) + } + return strings.Join(names, ", ") +} + +// ExeName returns the package name of an executable package. +func (meta debMetadata) ExeName(exe debExecutable) string { + if isUnstableBuild(meta.Env) { + return exe.Package() + "-unstable" + } + return exe.Package() +} + +// ExeConflicts returns the content of the Conflicts field +// for executable packages. +func (meta debMetadata) ExeConflicts(exe debExecutable) string { + if isUnstableBuild(meta.Env) { + // Set up the conflicts list so that the *-unstable packages + // cannot be installed alongside the regular version. + // + // https://www.debian.org/doc/debian-policy/ch-relationships.html + // is very explicit about Conflicts: and says that Breaks: should + // be preferred and the conflicting files should be handled via + // alternates. We might do this eventually but using a conflict is + // easier now. + return "ethereum, " + exe.Package() + } + return "" +} + +func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) { + pkg := meta.Name() + "-" + meta.VersionString() + pkgdir = filepath.Join(tmpdir, pkg) + if err := os.Mkdir(pkgdir, 0755); err != nil { + log.Fatal(err) + } + + // Copy the source code. + build.MustRunCommand("git", "checkout-index", "-a", "--prefix", pkgdir+string(filepath.Separator)) + + // Put the debian build files in place. + debian := filepath.Join(pkgdir, "debian") + build.Render("build/deb/"+meta.PackageName+"/deb.rules", filepath.Join(debian, "rules"), 0755, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.changelog", filepath.Join(debian, "changelog"), 0644, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.control", filepath.Join(debian, "control"), 0644, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.copyright", filepath.Join(debian, "copyright"), 0644, meta) + build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta) + build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta) + for _, exe := range meta.Executables { + install := filepath.Join(debian, meta.ExeName(exe)+".install") + docs := filepath.Join(debian, meta.ExeName(exe)+".docs") + build.Render("build/deb/"+meta.PackageName+"/deb.install", install, 0644, exe) + build.Render("build/deb/"+meta.PackageName+"/deb.docs", docs, 0644, exe) + } + + return pkgdir +} + +// Windows installer +func doWindowsInstaller(cmdline []string) { + // Parse the flags and make skip installer generation on PRs + var ( + arch = flag.String("arch", runtime.GOARCH, "Architecture for cross build packaging") + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. WINDOWS_SIGNING_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) + ) + flag.CommandLine.Parse(cmdline) + *workdir = makeWorkdir(*workdir) + env := build.Env() + maybeSkipArchive(env) + + // Aggregate binaries that are included in the installer + var ( + devTools []string + allTools []string + gethTool string + ) + for _, file := range allToolsArchiveFiles { + if file == "COPYING" { // license, copied later + continue + } + allTools = append(allTools, filepath.Base(file)) + if filepath.Base(file) == "geth.exe" { + gethTool = file + } else { + devTools = append(devTools, file) + } + } + + // Render NSIS scripts: Installer NSIS contains two installer sections, + // first section contains the geth binary, second section holds the dev tools. + templateData := map[string]interface{}{ + "License": "COPYING", + "Geth": gethTool, + "DevTools": devTools, + } + build.Render("build/nsis.geth.nsi", filepath.Join(*workdir, "geth.nsi"), 0644, nil) + build.Render("build/nsis.install.nsh", filepath.Join(*workdir, "install.nsh"), 0644, templateData) + build.Render("build/nsis.uninstall.nsh", filepath.Join(*workdir, "uninstall.nsh"), 0644, allTools) + build.Render("build/nsis.pathupdate.nsh", filepath.Join(*workdir, "PathUpdate.nsh"), 0644, nil) + build.Render("build/nsis.envvarupdate.nsh", filepath.Join(*workdir, "EnvVarUpdate.nsh"), 0644, nil) + build.CopyFile(filepath.Join(*workdir, "SimpleFC.dll"), "build/nsis.simplefc.dll", 0755) + build.CopyFile(filepath.Join(*workdir, "COPYING"), "COPYING", 0755) + + // Build the installer. This assumes that all the needed files have been previously + // built (don't mix building and packaging to keep cross compilation complexity to a + // minimum). + version := strings.Split(params.Version, ".") + if env.Commit != "" { + version[2] += "-" + env.Commit[:8] + } + installer, _ := filepath.Abs("geth-" + archiveBasename(*arch, params.ArchiveVersion(env.Commit)) + ".exe") + build.MustRunCommand("makensis.exe", + "/DOUTPUTFILE="+installer, + "/DMAJORVERSION="+version[0], + "/DMINORVERSION="+version[1], + "/DBUILDVERSION="+version[2], + "/DARCH="+*arch, + filepath.Join(*workdir, "geth.nsi"), + ) + + // Sign and publish installer. + if err := archiveUpload(installer, *upload, *signer); err != nil { + log.Fatal(err) + } +} + +// Android archives + +func doAndroidArchive(cmdline []string) { + var ( + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`) + upload = flag.String("upload", "", `Destination to upload the archive (usually "gethstore/builds")`) + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Sanity check that the SDK and NDK are installed and set + if os.Getenv("ANDROID_HOME") == "" { + log.Fatal("Please ensure ANDROID_HOME points to your Android SDK") + } + // Build the Android archive and Maven resources + build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) + build.MustRun(gomobileTool("bind", "-ldflags", "-s -w", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/ethereum/go-ethereum/mobile")) + + if *local { + // If we're building locally, copy bundle to build dir and skip Maven + os.Rename("geth.aar", filepath.Join(GOBIN, "geth.aar")) + return + } + meta := newMavenMetadata(env) + build.Render("build/mvn.pom", meta.Package+".pom", 0755, meta) + + // Skip Maven deploy and Azure upload for PR builds + maybeSkipArchive(env) + + // Sign and upload the archive to Azure + archive := "geth-" + archiveBasename("android", params.ArchiveVersion(env.Commit)) + ".aar" + os.Rename("geth.aar", archive) + + if err := archiveUpload(archive, *upload, *signer); err != nil { + log.Fatal(err) + } + // Sign and upload all the artifacts to Maven Central + os.Rename(archive, meta.Package+".aar") + if *signer != "" && *deploy != "" { + // Import the signing key into the local GPG instance + key := getenvBase64(*signer) + gpg := exec.Command("gpg", "--import") + gpg.Stdin = bytes.NewReader(key) + build.MustRun(gpg) + keyID, err := build.PGPKeyID(string(key)) + if err != nil { + log.Fatal(err) + } + // Upload the artifacts to Sonatype and/or Maven Central + repo := *deploy + "/service/local/staging/deploy/maven2" + if meta.Develop { + repo = *deploy + "/content/repositories/snapshots" + } + build.MustRunCommand("mvn", "gpg:sign-and-deploy-file", "-e", "-X", + "-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh", + "-Dgpg.keyname="+keyID, + "-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar") + } +} + +func gomobileTool(subcmd string, args ...string) *exec.Cmd { + cmd := exec.Command(filepath.Join(GOBIN, "gomobile"), subcmd) + cmd.Args = append(cmd.Args, args...) + cmd.Env = []string{ + "GOPATH=" + build.GOPATH(), + "PATH=" + GOBIN + string(os.PathListSeparator) + os.Getenv("PATH"), + } + for _, e := range os.Environ() { + if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "PATH=") { + continue + } + cmd.Env = append(cmd.Env, e) + } + return cmd +} + +type mavenMetadata struct { + Version string + Package string + Develop bool + Contributors []mavenContributor +} + +type mavenContributor struct { + Name string + Email string +} + +func newMavenMetadata(env build.Environment) mavenMetadata { + // Collect the list of authors from the repo root + contribs := []mavenContributor{} + if authors, err := os.Open("AUTHORS"); err == nil { + defer authors.Close() + + scanner := bufio.NewScanner(authors) + for scanner.Scan() { + // Skip any whitespace from the authors list + line := strings.TrimSpace(scanner.Text()) + if line == "" || line[0] == '#' { + continue + } + // Split the author and insert as a contributor + re := regexp.MustCompile("([^<]+) <(.+)>") + parts := re.FindStringSubmatch(line) + if len(parts) == 3 { + contribs = append(contribs, mavenContributor{Name: parts[1], Email: parts[2]}) + } + } + } + // Render the version and package strings + version := params.Version + if isUnstableBuild(env) { + version += "-SNAPSHOT" + } + return mavenMetadata{ + Version: version, + Package: "geth-" + version, + Develop: isUnstableBuild(env), + Contributors: contribs, + } +} + +// XCode frameworks + +func doXCodeFramework(cmdline []string) { + var ( + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Build the iOS XCode framework + build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) + build.MustRun(gomobileTool("init")) + bind := gomobileTool("bind", "-ldflags", "-s -w", "--target", "ios", "--tags", "ios", "-v", "github.com/ethereum/go-ethereum/mobile") + + if *local { + // If we're building locally, use the build folder and stop afterwards + bind.Dir, _ = filepath.Abs(GOBIN) + build.MustRun(bind) + return + } + archive := "geth-" + archiveBasename("ios", params.ArchiveVersion(env.Commit)) + if err := os.Mkdir(archive, os.ModePerm); err != nil { + log.Fatal(err) + } + bind.Dir, _ = filepath.Abs(archive) + build.MustRun(bind) + build.MustRunCommand("tar", "-zcvf", archive+".tar.gz", archive) + + // Skip CocoaPods deploy and Azure upload for PR builds + maybeSkipArchive(env) + + // Sign and upload the framework to Azure + if err := archiveUpload(archive+".tar.gz", *upload, *signer); err != nil { + log.Fatal(err) + } + // Prepare and upload a PodSpec to CocoaPods + if *deploy != "" { + meta := newPodMetadata(env, archive) + build.Render("build/pod.podspec", "Geth.podspec", 0755, meta) + build.MustRunCommand("pod", *deploy, "push", "Geth.podspec", "--allow-warnings", "--verbose") + } +} + +type podMetadata struct { + Version string + Commit string + Archive string + Contributors []podContributor +} + +type podContributor struct { + Name string + Email string +} + +func newPodMetadata(env build.Environment, archive string) podMetadata { + // Collect the list of authors from the repo root + contribs := []podContributor{} + if authors, err := os.Open("AUTHORS"); err == nil { + defer authors.Close() + + scanner := bufio.NewScanner(authors) + for scanner.Scan() { + // Skip any whitespace from the authors list + line := strings.TrimSpace(scanner.Text()) + if line == "" || line[0] == '#' { + continue + } + // Split the author and insert as a contributor + re := regexp.MustCompile("([^<]+) <(.+)>") + parts := re.FindStringSubmatch(line) + if len(parts) == 3 { + contribs = append(contribs, podContributor{Name: parts[1], Email: parts[2]}) + } + } + } + version := params.Version + if isUnstableBuild(env) { + version += "-unstable." + env.Buildnum + } + return podMetadata{ + Archive: archive, + Version: version, + Commit: env.Commit, + Contributors: contribs, + } +} + +// Cross compilation + +func doXgo(cmdline []string) { + var ( + alltools = flag.Bool("alltools", false, `Flag whether we're building all known tools, or only on in particular`) + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Make sure xgo is available for cross compilation + gogetxgo := goTool("get", "github.com/karalabe/xgo") + build.MustRun(gogetxgo) + + // If all tools building is requested, build everything the builder wants + args := append(buildFlags(env), flag.Args()...) + + if *alltools { + args = append(args, []string{"--dest", GOBIN}...) + for _, res := range allToolsArchiveFiles { + if strings.HasPrefix(res, GOBIN) { + // Binary tool found, cross build it explicitly + args = append(args, "./"+filepath.Join("cmd", filepath.Base(res))) + xgo := xgoTool(args) + build.MustRun(xgo) + args = args[:len(args)-1] + } + } + return + } + // Otherwise xxecute the explicit cross compilation + path := args[len(args)-1] + args = append(args[:len(args)-1], []string{"--dest", GOBIN, path}...) + + xgo := xgoTool(args) + build.MustRun(xgo) +} + +func xgoTool(args []string) *exec.Cmd { + cmd := exec.Command(filepath.Join(GOBIN, "xgo"), args...) + cmd.Env = []string{ + "GOPATH=" + build.GOPATH(), + "GOBIN=" + GOBIN, + } + for _, e := range os.Environ() { + if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { + continue + } + cmd.Env = append(cmd.Env, e) + } + return cmd +} + +// Binary distribution cleanups + +func doPurge(cmdline []string) { + var ( + store = flag.String("store", "", `Destination from where to purge archives (usually "gethstore/builds")`) + limit = flag.Int("days", 30, `Age threshold above which to delete unstable archives`) + ) + flag.CommandLine.Parse(cmdline) + + if env := build.Env(); !env.IsCronJob { + log.Printf("skipping because not a cron job") + os.Exit(0) + } + // Create the azure authentication and list the current archives + auth := build.AzureBlobstoreConfig{ + Account: strings.Split(*store, "/")[0], + Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), + Container: strings.SplitN(*store, "/", 2)[1], + } + blobs, err := build.AzureBlobstoreList(auth) + if err != nil { + log.Fatal(err) + } + // Iterate over the blobs, collect and sort all unstable builds + for i := 0; i < len(blobs); i++ { + if !strings.Contains(blobs[i].Name, "unstable") { + blobs = append(blobs[:i], blobs[i+1:]...) + i-- + } + } + for i := 0; i < len(blobs); i++ { + for j := i + 1; j < len(blobs); j++ { + if blobs[i].Properties.LastModified.After(blobs[j].Properties.LastModified) { + blobs[i], blobs[j] = blobs[j], blobs[i] + } + } + } + // Filter out all archives more recent that the given threshold + for i, blob := range blobs { + if time.Since(blob.Properties.LastModified) < time.Duration(*limit)*24*time.Hour { + blobs = blobs[:i] + break + } + } + // Delete all marked as such and return + if err := build.AzureBlobstoreDelete(auth, blobs); err != nil { + log.Fatal(err) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/build/deb/ethereum/deb.control b/vendor/github.com/ethereum/go-ethereum/build/deb/ethereum/deb.control new file mode 100644 index 00000000..5b3ff935 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/build/deb/ethereum/deb.control @@ -0,0 +1,25 @@ +Source: {{.Name}} +Section: science +Priority: extra +Maintainer: {{.Author}} +Build-Depends: debhelper (>= 8.0.0), golang-1.11 +Standards-Version: 3.9.5 +Homepage: https://ethereum.org +Vcs-Git: git://github.com/ethereum/go-ethereum.git +Vcs-Browser: https://github.com/ethereum/go-ethereum + +Package: {{.Name}} +Architecture: any +Depends: ${misc:Depends}, {{.ExeList}} +Description: Meta-package to install geth and other tools + Meta-package to install geth and other tools + +{{range .Executables}} +Package: {{$.ExeName .}} +Conflicts: {{$.ExeConflicts .}} +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Built-Using: ${misc:Built-Using} +Description: {{.Description}} + {{.Description}} +{{end}} diff --git a/vendor/github.com/ethereum/go-ethereum/build/update-license.go b/vendor/github.com/ethereum/go-ethereum/build/update-license.go new file mode 100644 index 00000000..0ce82923 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/build/update-license.go @@ -0,0 +1,409 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build none + +/* +This command generates GPL license headers on top of all source files. +You can run it once per month, before cutting a release or just +whenever you feel like it. + + go run update-license.go + +All authors (people who have contributed code) are listed in the +AUTHORS file. The author names are mapped and deduplicated using the +.mailmap file. You can use .mailmap to set the canonical name and +address for each author. See git-shortlog(1) for an explanation of the +.mailmap format. + +Please review the resulting diff to check whether the correct +copyright assignments are performed. +*/ + +package main + +import ( + "bufio" + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "text/template" + "time" +) + +var ( + // only files with these extensions will be considered + extensions = []string{".go", ".js", ".qml"} + + // paths with any of these prefixes will be skipped + skipPrefixes = []string{ + // boring stuff + "vendor/", "tests/testdata/", "build/", + // don't relicense vendored sources + "cmd/internal/browser", + "consensus/ethash/xor.go", + "crypto/bn256/", + "crypto/ecies/", + "crypto/secp256k1/curve.go", + "crypto/sha3/", + "internal/jsre/deps", + "log/", + "common/bitutil/bitutil", + } + + // paths with this prefix are licensed as GPL. all other files are LGPL. + gplPrefixes = []string{"cmd/"} + + // this regexp must match the entire license comment at the + // beginning of each file. + licenseCommentRE = regexp.MustCompile(`^//\s*(Copyright|This file is part of).*?\n(?://.*?\n)*\n*`) + + // this text appears at the start of AUTHORS + authorsFileHeader = "# This is the official list of go-ethereum authors for copyright purposes.\n\n" +) + +// this template generates the license comment. +// its input is an info structure. +var licenseT = template.Must(template.New("").Parse(` +// Copyright {{.Year}} The go-ethereum Authors +// This file is part of {{.Whole false}}. +// +// {{.Whole true}} is free software: you can redistribute it and/or modify +// it under the terms of the GNU {{.License}} as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// {{.Whole true}} is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU {{.License}} for more details. +// +// You should have received a copy of the GNU {{.License}} +// along with {{.Whole false}}. If not, see . + +`[1:])) + +type info struct { + file string + Year int64 +} + +func (i info) License() string { + if i.gpl() { + return "General Public License" + } + return "Lesser General Public License" +} + +func (i info) ShortLicense() string { + if i.gpl() { + return "GPL" + } + return "LGPL" +} + +func (i info) Whole(startOfSentence bool) string { + if i.gpl() { + return "go-ethereum" + } + if startOfSentence { + return "The go-ethereum library" + } + return "the go-ethereum library" +} + +func (i info) gpl() bool { + for _, p := range gplPrefixes { + if strings.HasPrefix(i.file, p) { + return true + } + } + return false +} + +func main() { + var ( + files = getFiles() + filec = make(chan string) + infoc = make(chan *info, 20) + wg sync.WaitGroup + ) + + writeAuthors(files) + + go func() { + for _, f := range files { + filec <- f + } + close(filec) + }() + for i := runtime.NumCPU(); i >= 0; i-- { + // getting file info is slow and needs to be parallel. + // it traverses git history for each file. + wg.Add(1) + go getInfo(filec, infoc, &wg) + } + go func() { + wg.Wait() + close(infoc) + }() + writeLicenses(infoc) +} + +func skipFile(path string) bool { + if strings.Contains(path, "/testdata/") { + return true + } + for _, p := range skipPrefixes { + if strings.HasPrefix(path, p) { + return true + } + } + return false +} + +func getFiles() []string { + cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD") + var files []string + err := doLines(cmd, func(line string) { + if skipFile(line) { + return + } + ext := filepath.Ext(line) + for _, wantExt := range extensions { + if ext == wantExt { + goto keep + } + } + return + keep: + files = append(files, line) + }) + if err != nil { + log.Fatal("error getting files:", err) + } + return files +} + +var authorRegexp = regexp.MustCompile(`\s*[0-9]+\s*(.*)`) + +func gitAuthors(files []string) []string { + cmds := []string{"shortlog", "-s", "-n", "-e", "HEAD", "--"} + cmds = append(cmds, files...) + cmd := exec.Command("git", cmds...) + var authors []string + err := doLines(cmd, func(line string) { + m := authorRegexp.FindStringSubmatch(line) + if len(m) > 1 { + authors = append(authors, m[1]) + } + }) + if err != nil { + log.Fatalln("error getting authors:", err) + } + return authors +} + +func readAuthors() []string { + content, err := ioutil.ReadFile("AUTHORS") + if err != nil && !os.IsNotExist(err) { + log.Fatalln("error reading AUTHORS:", err) + } + var authors []string + for _, a := range bytes.Split(content, []byte("\n")) { + if len(a) > 0 && a[0] != '#' { + authors = append(authors, string(a)) + } + } + // Retranslate existing authors through .mailmap. + // This should catch email address changes. + authors = mailmapLookup(authors) + return authors +} + +func mailmapLookup(authors []string) []string { + if len(authors) == 0 { + return nil + } + cmds := []string{"check-mailmap", "--"} + cmds = append(cmds, authors...) + cmd := exec.Command("git", cmds...) + var translated []string + err := doLines(cmd, func(line string) { + translated = append(translated, line) + }) + if err != nil { + log.Fatalln("error translating authors:", err) + } + return translated +} + +func writeAuthors(files []string) { + merge := make(map[string]bool) + // Add authors that Git reports as contributorxs. + // This is the primary source of author information. + for _, a := range gitAuthors(files) { + merge[a] = true + } + // Add existing authors from the file. This should ensure that we + // never lose authors, even if Git stops listing them. We can also + // add authors manually this way. + for _, a := range readAuthors() { + merge[a] = true + } + // Write sorted list of authors back to the file. + var result []string + for a := range merge { + result = append(result, a) + } + sort.Strings(result) + content := new(bytes.Buffer) + content.WriteString(authorsFileHeader) + for _, a := range result { + content.WriteString(a) + content.WriteString("\n") + } + fmt.Println("writing AUTHORS") + if err := ioutil.WriteFile("AUTHORS", content.Bytes(), 0644); err != nil { + log.Fatalln(err) + } +} + +func getInfo(files <-chan string, out chan<- *info, wg *sync.WaitGroup) { + for file := range files { + stat, err := os.Lstat(file) + if err != nil { + fmt.Printf("ERROR %s: %v\n", file, err) + continue + } + if !stat.Mode().IsRegular() { + continue + } + if isGenerated(file) { + continue + } + info, err := fileInfo(file) + if err != nil { + fmt.Printf("ERROR %s: %v\n", file, err) + continue + } + out <- info + } + wg.Done() +} + +func isGenerated(file string) bool { + fd, err := os.Open(file) + if err != nil { + return false + } + defer fd.Close() + buf := make([]byte, 2048) + n, _ := fd.Read(buf) + buf = buf[:n] + for _, l := range bytes.Split(buf, []byte("\n")) { + if bytes.HasPrefix(l, []byte("// Code generated")) { + return true + } + } + return false +} + +// fileInfo finds the lowest year in which the given file was committed. +func fileInfo(file string) (*info, error) { + info := &info{file: file, Year: int64(time.Now().Year())} + cmd := exec.Command("git", "log", "--follow", "--find-renames=80", "--find-copies=80", "--pretty=format:%ai", "--", file) + err := doLines(cmd, func(line string) { + y, err := strconv.ParseInt(line[:4], 10, 64) + if err != nil { + fmt.Printf("cannot parse year: %q", line[:4]) + } + if y < info.Year { + info.Year = y + } + }) + return info, err +} + +func writeLicenses(infos <-chan *info) { + for i := range infos { + writeLicense(i) + } +} + +func writeLicense(info *info) { + fi, err := os.Stat(info.file) + if os.IsNotExist(err) { + fmt.Println("skipping (does not exist)", info.file) + return + } + if err != nil { + log.Fatalf("error stat'ing %s: %v\n", info.file, err) + } + content, err := ioutil.ReadFile(info.file) + if err != nil { + log.Fatalf("error reading %s: %v\n", info.file, err) + } + // Construct new file content. + buf := new(bytes.Buffer) + licenseT.Execute(buf, info) + if m := licenseCommentRE.FindIndex(content); m != nil && m[0] == 0 { + buf.Write(content[:m[0]]) + buf.Write(content[m[1]:]) + } else { + buf.Write(content) + } + // Write it to the file. + if bytes.Equal(content, buf.Bytes()) { + fmt.Println("skipping (no changes)", info.file) + return + } + fmt.Println("writing", info.ShortLicense(), info.file) + if err := ioutil.WriteFile(info.file, buf.Bytes(), fi.Mode()); err != nil { + log.Fatalf("error writing %s: %v", info.file, err) + } +} + +func doLines(cmd *exec.Cmd, f func(string)) error { + stdout, err := cmd.StdoutPipe() + if err != nil { + return err + } + if err := cmd.Start(); err != nil { + return err + } + s := bufio.NewScanner(stdout) + for s.Scan() { + f(s.Text()) + } + if s.Err() != nil { + return s.Err() + } + if err := cmd.Wait(); err != nil { + return fmt.Errorf("%v (for %s)", err, strings.Join(cmd.Args, " ")) + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/abigen/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/abigen/main.go new file mode 100644 index 00000000..461c2946 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/abigen/main.go @@ -0,0 +1,178 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common/compiler" +) + +var ( + abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind, - for STDIN") + binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") + typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") + + solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") + solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") + excFlag = flag.String("exc", "", "Comma separated types to exclude from binding") + + vyFlag = flag.String("vy", "", "Path to the Ethereum contract Vyper source to build and bind") + vyperFlag = flag.String("vyper", "vyper", "Vyper compiler to use if source builds are requested") + + pkgFlag = flag.String("pkg", "", "Package name to generate the binding into") + outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)") + langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)") +) + +func main() { + // Parse and ensure all needed inputs are specified + flag.Parse() + + if *abiFlag == "" && *solFlag == "" && *vyFlag == "" { + fmt.Printf("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n") + os.Exit(-1) + } else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && (*solFlag != "" || *vyFlag != "") { + fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n") + os.Exit(-1) + } else if *solFlag != "" && *vyFlag != "" { + fmt.Printf("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n") + os.Exit(-1) + } + if *pkgFlag == "" { + fmt.Printf("No destination package specified (--pkg)\n") + os.Exit(-1) + } + var lang bind.Lang + switch *langFlag { + case "go": + lang = bind.LangGo + case "java": + lang = bind.LangJava + case "objc": + lang = bind.LangObjC + default: + fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag) + os.Exit(-1) + } + // If the entire solidity code was specified, build and bind based on that + var ( + abis []string + bins []string + types []string + ) + if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" { + // Generate the list of types to exclude from binding + exclude := make(map[string]bool) + for _, kind := range strings.Split(*excFlag, ",") { + exclude[strings.ToLower(kind)] = true + } + + var contracts map[string]*compiler.Contract + var err error + + switch { + case *solFlag != "": + contracts, err = compiler.CompileSolidity(*solcFlag, *solFlag) + if err != nil { + fmt.Printf("Failed to build Solidity contract: %v\n", err) + os.Exit(-1) + } + case *vyFlag != "": + contracts, err = compiler.CompileVyper(*vyperFlag, *vyFlag) + if err != nil { + fmt.Printf("Failed to build Vyper contract: %v\n", err) + os.Exit(-1) + } + default: + contracts, err = contractsFromStdin() + if err != nil { + fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err) + os.Exit(-1) + } + } + // Gather all non-excluded contract for binding + for name, contract := range contracts { + if exclude[strings.ToLower(name)] { + continue + } + abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse + if err != nil { + fmt.Printf("Failed to parse ABIs from compiler output: %v\n", err) + os.Exit(-1) + } + abis = append(abis, string(abi)) + bins = append(bins, contract.Code) + + nameParts := strings.Split(name, ":") + types = append(types, nameParts[len(nameParts)-1]) + } + } else { + // Otherwise load up the ABI, optional bytecode and type name from the parameters + abi, err := ioutil.ReadFile(*abiFlag) + + if err != nil { + fmt.Printf("Failed to read input ABI: %v\n", err) + os.Exit(-1) + } + abis = append(abis, string(abi)) + + var bin []byte + if *binFlag != "" { + if bin, err = ioutil.ReadFile(*binFlag); err != nil { + fmt.Printf("Failed to read input bytecode: %v\n", err) + os.Exit(-1) + } + } + bins = append(bins, string(bin)) + + kind := *typFlag + if kind == "" { + kind = *pkgFlag + } + types = append(types, kind) + } + // Generate the contract binding + code, err := bind.Bind(types, abis, bins, *pkgFlag, lang) + if err != nil { + fmt.Printf("Failed to generate ABI binding: %v\n", err) + os.Exit(-1) + } + // Either flush it out to a file or display on the standard output + if *outFlag == "" { + fmt.Printf("%s\n", code) + return + } + if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil { + fmt.Printf("Failed to write ABI binding: %v\n", err) + os.Exit(-1) + } +} + +func contractsFromStdin() (map[string]*compiler.Contract, error) { + bytes, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return nil, err + } + return compiler.ParseCombinedJSON(bytes, "", "", "", "") +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/bootnode/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/bootnode/main.go new file mode 100644 index 00000000..2f9bba11 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/bootnode/main.go @@ -0,0 +1,149 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// bootnode runs a bootstrap node for the Ethereum Discovery Protocol. +package main + +import ( + "crypto/ecdsa" + "flag" + "fmt" + "net" + "os" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +func main() { + var ( + listenAddr = flag.String("addr", ":30301", "listen address") + genKey = flag.String("genkey", "", "generate a node key") + writeAddr = flag.Bool("writeaddress", false, "write out the node's public key and quit") + nodeKeyFile = flag.String("nodekey", "", "private key filename") + nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") + natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:)") + netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") + runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") + verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") + vmodule = flag.String("vmodule", "", "log verbosity pattern") + + nodeKey *ecdsa.PrivateKey + err error + ) + flag.Parse() + + glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) + glogger.Verbosity(log.Lvl(*verbosity)) + glogger.Vmodule(*vmodule) + log.Root().SetHandler(glogger) + + natm, err := nat.Parse(*natdesc) + if err != nil { + utils.Fatalf("-nat: %v", err) + } + switch { + case *genKey != "": + nodeKey, err = crypto.GenerateKey() + if err != nil { + utils.Fatalf("could not generate key: %v", err) + } + if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil { + utils.Fatalf("%v", err) + } + return + case *nodeKeyFile == "" && *nodeKeyHex == "": + utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") + case *nodeKeyFile != "" && *nodeKeyHex != "": + utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive") + case *nodeKeyFile != "": + if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { + utils.Fatalf("-nodekey: %v", err) + } + case *nodeKeyHex != "": + if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { + utils.Fatalf("-nodekeyhex: %v", err) + } + } + + if *writeAddr { + fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:]) + os.Exit(0) + } + + var restrictList *netutil.Netlist + if *netrestrict != "" { + restrictList, err = netutil.ParseNetlist(*netrestrict) + if err != nil { + utils.Fatalf("-netrestrict: %v", err) + } + } + + addr, err := net.ResolveUDPAddr("udp", *listenAddr) + if err != nil { + utils.Fatalf("-ResolveUDPAddr: %v", err) + } + conn, err := net.ListenUDP("udp", addr) + if err != nil { + utils.Fatalf("-ListenUDP: %v", err) + } + + realaddr := conn.LocalAddr().(*net.UDPAddr) + if natm != nil { + if !realaddr.IP.IsLoopback() { + go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") + } + if ext, err := natm.ExternalIP(); err == nil { + realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port} + } + } + + printNotice(&nodeKey.PublicKey, *realaddr) + + if *runv5 { + if _, err := discv5.ListenUDP(nodeKey, conn, "", restrictList); err != nil { + utils.Fatalf("%v", err) + } + } else { + db, _ := enode.OpenDB("") + ln := enode.NewLocalNode(db, nodeKey) + cfg := discover.Config{ + PrivateKey: nodeKey, + NetRestrict: restrictList, + } + if _, err := discover.ListenUDP(conn, ln, cfg); err != nil { + utils.Fatalf("%v", err) + } + } + + select {} +} + +func printNotice(nodeKey *ecdsa.PublicKey, addr net.UDPAddr) { + if addr.IP.IsUnspecified() { + addr.IP = net.IP{127, 0, 0, 1} + } + n := enode.NewV4(nodeKey, addr.IP, 0, addr.Port) + fmt.Println(n.URLv4()) + fmt.Println("Note: you're using cmd/bootnode, a developer tool.") + fmt.Println("We recommend using a regular node as bootstrap node for production deployments.") +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/clef/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/clef/main.go new file mode 100644 index 00000000..0ea6f36f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/clef/main.go @@ -0,0 +1,1010 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "bufio" + "context" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "math/big" + "os" + "os/signal" + "os/user" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/signer/core" + "github.com/ethereum/go-ethereum/signer/fourbyte" + "github.com/ethereum/go-ethereum/signer/rules" + "github.com/ethereum/go-ethereum/signer/storage" + "gopkg.in/urfave/cli.v1" +) + +const legalWarning = ` +WARNING! + +Clef is an account management tool. It may, like any software, contain bugs. + +Please take care to +- backup your keystore files, +- verify that the keystore(s) can be opened with your password. + +Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. +` + +var ( + logLevelFlag = cli.IntFlag{ + Name: "loglevel", + Value: 4, + Usage: "log level to emit to the screen", + } + advancedMode = cli.BoolFlag{ + Name: "advanced", + Usage: "If enabled, issues warnings instead of rejections for suspicious requests. Default off", + } + keystoreFlag = cli.StringFlag{ + Name: "keystore", + Value: filepath.Join(node.DefaultDataDir(), "keystore"), + Usage: "Directory for the keystore", + } + configdirFlag = cli.StringFlag{ + Name: "configdir", + Value: DefaultConfigDir(), + Usage: "Directory for Clef configuration", + } + chainIdFlag = cli.Int64Flag{ + Name: "chainid", + Value: params.MainnetChainConfig.ChainID.Int64(), + Usage: "Chain id to use for signing (1=mainnet, 3=ropsten, 4=rinkeby, 5=Goerli)", + } + rpcPortFlag = cli.IntFlag{ + Name: "rpcport", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort + 5, + } + signerSecretFlag = cli.StringFlag{ + Name: "signersecret", + Usage: "A file containing the (encrypted) master seed to encrypt Clef data, e.g. keystore credentials and ruleset hash", + } + customDBFlag = cli.StringFlag{ + Name: "4bytedb-custom", + Usage: "File used for writing new 4byte-identifiers submitted via API", + Value: "./4byte-custom.json", + } + auditLogFlag = cli.StringFlag{ + Name: "auditlog", + Usage: "File used to emit audit logs. Set to \"\" to disable", + Value: "audit.log", + } + ruleFlag = cli.StringFlag{ + Name: "rules", + Usage: "Enable rule-engine", + Value: "", + } + stdiouiFlag = cli.BoolFlag{ + Name: "stdio-ui", + Usage: "Use STDIN/STDOUT as a channel for an external UI. " + + "This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user " + + "interface, and can be used when Clef is started by an external process.", + } + testFlag = cli.BoolFlag{ + Name: "stdio-ui-test", + Usage: "Mechanism to test interface between Clef and UI. Requires 'stdio-ui'.", + } + app = cli.NewApp() + initCommand = cli.Command{ + Action: utils.MigrateFlags(initializeSecrets), + Name: "init", + Usage: "Initialize the signer, generate secret storage", + ArgsUsage: "", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + }, + Description: ` +The init command generates a master seed which Clef can use to store credentials and data needed for +the rule-engine to work.`, + } + attestCommand = cli.Command{ + Action: utils.MigrateFlags(attestFile), + Name: "attest", + Usage: "Attest that a js-file is to be used", + ArgsUsage: "", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + signerSecretFlag, + }, + Description: ` +The attest command stores the sha256 of the rule.js-file that you want to use for automatic processing of +incoming requests. + +Whenever you make an edit to the rule file, you need to use attestation to tell +Clef that the file is 'safe' to execute.`, + } + + setCredentialCommand = cli.Command{ + Action: utils.MigrateFlags(setCredential), + Name: "setpw", + Usage: "Store a credential for a keystore file", + ArgsUsage: "
", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + signerSecretFlag, + }, + Description: ` +The setpw command stores a password for a given address (keyfile). If you enter a blank passphrase, it will +remove any stored credential for that address (keyfile) +`} + gendocCommand = cli.Command{ + Action: GenDoc, + Name: "gendoc", + Usage: "Generate documentation about json-rpc format", + Description: ` +The gendoc generates example structures of the json-rpc communication types. +`} +) + +func init() { + app.Name = "Clef" + app.Usage = "Manage Ethereum account operations" + app.Flags = []cli.Flag{ + logLevelFlag, + keystoreFlag, + configdirFlag, + chainIdFlag, + utils.LightKDFFlag, + utils.NoUSBFlag, + utils.SmartCardDaemonPathFlag, + utils.RPCListenAddrFlag, + utils.RPCVirtualHostsFlag, + utils.IPCDisabledFlag, + utils.IPCPathFlag, + utils.RPCEnabledFlag, + rpcPortFlag, + signerSecretFlag, + customDBFlag, + auditLogFlag, + ruleFlag, + stdiouiFlag, + testFlag, + advancedMode, + } + app.Action = signer + app.Commands = []cli.Command{initCommand, attestCommand, setCredentialCommand, gendocCommand} + +} +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func initializeSecrets(c *cli.Context) error { + if err := initialize(c); err != nil { + return err + } + configDir := c.GlobalString(configdirFlag.Name) + + masterSeed := make([]byte, 256) + num, err := io.ReadFull(rand.Reader, masterSeed) + if err != nil { + return err + } + if num != len(masterSeed) { + return fmt.Errorf("failed to read enough random") + } + + n, p := keystore.StandardScryptN, keystore.StandardScryptP + if c.GlobalBool(utils.LightKDFFlag.Name) { + n, p = keystore.LightScryptN, keystore.LightScryptP + } + text := "The master seed of clef is locked with a password. Please give a password. Do not forget this password." + var password string + for { + password = getPassPhrase(text, true) + if err := core.ValidatePasswordFormat(password); err != nil { + fmt.Printf("invalid password: %v\n", err) + } else { + break + } + } + cipherSeed, err := encryptSeed(masterSeed, []byte(password), n, p) + if err != nil { + return fmt.Errorf("failed to encrypt master seed: %v", err) + } + + err = os.Mkdir(configDir, 0700) + if err != nil && !os.IsExist(err) { + return err + } + location := filepath.Join(configDir, "masterseed.json") + if _, err := os.Stat(location); err == nil { + return fmt.Errorf("file %v already exists, will not overwrite", location) + } + err = ioutil.WriteFile(location, cipherSeed, 0400) + if err != nil { + return err + } + fmt.Printf("A master seed has been generated into %s\n", location) + fmt.Printf(` +This is required to be able to store credentials, such as : +* Passwords for keystores (used by rule engine) +* Storage for javascript rules +* Hash of rule-file + +You should treat that file with utmost secrecy, and make a backup of it. +NOTE: This file does not contain your accounts. Those need to be backed up separately! + +`) + return nil +} +func attestFile(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + if err := initialize(ctx); err != nil { + return err + } + + stretchedKey, err := readMasterKey(ctx, nil) + if err != nil { + utils.Fatalf(err.Error()) + } + configDir := ctx.GlobalString(configdirFlag.Name) + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + confKey := crypto.Keccak256([]byte("config"), stretchedKey) + + // Initialize the encrypted storages + configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confKey) + val := ctx.Args().First() + configStorage.Put("ruleset_sha256", val) + log.Info("Ruleset attestation updated", "sha256", val) + return nil +} + +func setCredential(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an address to be passed as an argument.") + } + if err := initialize(ctx); err != nil { + return err + } + + address := ctx.Args().First() + password := getPassPhrase("Enter a passphrase to store with this address.", true) + + stretchedKey, err := readMasterKey(ctx, nil) + if err != nil { + utils.Fatalf(err.Error()) + } + configDir := ctx.GlobalString(configdirFlag.Name) + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) + + // Initialize the encrypted storages + pwStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey) + pwStorage.Put(address, password) + log.Info("Credential store updated", "key", address) + return nil +} + +func initialize(c *cli.Context) error { + // Set up the logger to print everything + logOutput := os.Stdout + if c.GlobalBool(stdiouiFlag.Name) { + logOutput = os.Stderr + // If using the stdioui, we can't do the 'confirm'-flow + fmt.Fprintf(logOutput, legalWarning) + } else { + if !confirm(legalWarning) { + return fmt.Errorf("aborted by user") + } + } + + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(c.Int(logLevelFlag.Name)), log.StreamHandler(logOutput, log.TerminalFormat(true)))) + return nil +} + +func signer(c *cli.Context) error { + if err := initialize(c); err != nil { + return err + } + var ( + ui core.UIClientAPI + ) + if c.GlobalBool(stdiouiFlag.Name) { + log.Info("Using stdin/stdout as UI-channel") + ui = core.NewStdIOUI() + } else { + log.Info("Using CLI as UI-channel") + ui = core.NewCommandlineUI() + } + // 4bytedb data + fourByteLocal := c.GlobalString(customDBFlag.Name) + db, err := fourbyte.NewWithFile(fourByteLocal) + if err != nil { + utils.Fatalf(err.Error()) + } + embeds, locals := db.Size() + log.Info("Loaded 4byte database", "embeds", embeds, "locals", locals, "local", fourByteLocal) + + var ( + api core.ExternalAPI + pwStorage storage.Storage = &storage.NoStorage{} + ) + + configDir := c.GlobalString(configdirFlag.Name) + if stretchedKey, err := readMasterKey(c, ui); err != nil { + log.Info("No master seed provided, rules disabled", "error", err) + } else { + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + + // Generate domain specific keys + pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) + jskey := crypto.Keccak256([]byte("jsstorage"), stretchedKey) + confkey := crypto.Keccak256([]byte("config"), stretchedKey) + + // Initialize the encrypted storages + pwStorage = storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey) + jsStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "jsstorage.json"), jskey) + configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confkey) + + //Do we have a rule-file? + if ruleFile := c.GlobalString(ruleFlag.Name); ruleFile != "" { + ruleJS, err := ioutil.ReadFile(c.GlobalString(ruleFile)) + if err != nil { + log.Info("Could not load rulefile, rules not enabled", "file", "rulefile") + } else { + shasum := sha256.Sum256(ruleJS) + foundShaSum := hex.EncodeToString(shasum[:]) + storedShasum := configStorage.Get("ruleset_sha256") + if storedShasum != foundShaSum { + log.Info("Could not validate ruleset hash, rules not enabled", "got", foundShaSum, "expected", storedShasum) + } else { + // Initialize rules + ruleEngine, err := rules.NewRuleEvaluator(ui, jsStorage) + if err != nil { + utils.Fatalf(err.Error()) + } + ruleEngine.Init(string(ruleJS)) + ui = ruleEngine + log.Info("Rule engine configured", "file", c.String(ruleFlag.Name)) + } + } + } + } + var ( + chainId = c.GlobalInt64(chainIdFlag.Name) + ksLoc = c.GlobalString(keystoreFlag.Name) + lightKdf = c.GlobalBool(utils.LightKDFFlag.Name) + advanced = c.GlobalBool(advancedMode.Name) + nousb = c.GlobalBool(utils.NoUSBFlag.Name) + scpath = c.GlobalString(utils.SmartCardDaemonPathFlag.Name) + ) + log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc, + "light-kdf", lightKdf, "advanced", advanced) + am := core.StartClefAccountManager(ksLoc, nousb, lightKdf, scpath) + apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage) + + // Establish the bidirectional communication, by creating a new UI backend and registering + // it with the UI. + ui.RegisterUIServer(core.NewUIServerAPI(apiImpl)) + api = apiImpl + // Audit logging + if logfile := c.GlobalString(auditLogFlag.Name); logfile != "" { + api, err = core.NewAuditLogger(logfile, api) + if err != nil { + utils.Fatalf(err.Error()) + } + log.Info("Audit logs configured", "file", logfile) + } + // register signer API with server + var ( + extapiURL = "n/a" + ipcapiURL = "n/a" + ) + rpcAPI := []rpc.API{ + { + Namespace: "account", + Public: true, + Service: api, + Version: "1.0"}, + } + if c.GlobalBool(utils.RPCEnabledFlag.Name) { + + vhosts := splitAndTrim(c.GlobalString(utils.RPCVirtualHostsFlag.Name)) + cors := splitAndTrim(c.GlobalString(utils.RPCCORSDomainFlag.Name)) + + // start http server + httpEndpoint := fmt.Sprintf("%s:%d", c.GlobalString(utils.RPCListenAddrFlag.Name), c.Int(rpcPortFlag.Name)) + listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"account"}, cors, vhosts, rpc.DefaultHTTPTimeouts) + if err != nil { + utils.Fatalf("Could not start RPC api: %v", err) + } + extapiURL = fmt.Sprintf("http://%s", httpEndpoint) + log.Info("HTTP endpoint opened", "url", extapiURL) + + defer func() { + listener.Close() + log.Info("HTTP endpoint closed", "url", httpEndpoint) + }() + + } + if !c.GlobalBool(utils.IPCDisabledFlag.Name) { + if c.IsSet(utils.IPCPathFlag.Name) { + ipcapiURL = c.GlobalString(utils.IPCPathFlag.Name) + } else { + ipcapiURL = filepath.Join(configDir, "clef.ipc") + } + + listener, _, err := rpc.StartIPCEndpoint(ipcapiURL, rpcAPI) + if err != nil { + utils.Fatalf("Could not start IPC api: %v", err) + } + log.Info("IPC endpoint opened", "url", ipcapiURL) + defer func() { + listener.Close() + log.Info("IPC endpoint closed", "url", ipcapiURL) + }() + + } + + if c.GlobalBool(testFlag.Name) { + log.Info("Performing UI test") + go testExternalUI(apiImpl) + } + ui.OnSignerStartup(core.StartupInfo{ + Info: map[string]interface{}{ + "extapi_version": core.ExternalAPIVersion, + "intapi_version": core.InternalAPIVersion, + "extapi_http": extapiURL, + "extapi_ipc": ipcapiURL, + }, + }) + + abortChan := make(chan os.Signal) + signal.Notify(abortChan, os.Interrupt) + + sig := <-abortChan + log.Info("Exiting...", "signal", sig) + + return nil +} + +// splitAndTrim splits input separated by a comma +// and trims excessive white space from the substrings. +func splitAndTrim(input string) []string { + result := strings.Split(input, ",") + for i, r := range result { + result[i] = strings.TrimSpace(r) + } + return result +} + +// DefaultConfigDir is the default config directory to use for the vaults and other +// persistence requirements. +func DefaultConfigDir() string { + // Try to place the data folder in the user's home dir + home := homeDir() + if home != "" { + if runtime.GOOS == "darwin" { + return filepath.Join(home, "Library", "Signer") + } else if runtime.GOOS == "windows" { + appdata := os.Getenv("APPDATA") + if appdata != "" { + return filepath.Join(appdata, "Signer") + } else { + return filepath.Join(home, "AppData", "Roaming", "Signer") + } + } else { + return filepath.Join(home, ".clef") + } + } + // As we cannot guess a stable location, return empty and handle later + return "" +} + +func homeDir() string { + if home := os.Getenv("HOME"); home != "" { + return home + } + if usr, err := user.Current(); err == nil { + return usr.HomeDir + } + return "" +} +func readMasterKey(ctx *cli.Context, ui core.UIClientAPI) ([]byte, error) { + var ( + file string + configDir = ctx.GlobalString(configdirFlag.Name) + ) + if ctx.GlobalIsSet(signerSecretFlag.Name) { + file = ctx.GlobalString(signerSecretFlag.Name) + } else { + file = filepath.Join(configDir, "masterseed.json") + } + if err := checkFile(file); err != nil { + return nil, err + } + cipherKey, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + var password string + // If ui is not nil, get the password from ui. + if ui != nil { + resp, err := ui.OnInputRequired(core.UserInputRequest{ + Title: "Master Password", + Prompt: "Please enter the password to decrypt the master seed", + IsPassword: true}) + if err != nil { + return nil, err + } + password = resp.Text + } else { + password = getPassPhrase("Decrypt master seed of clef", false) + } + masterSeed, err := decryptSeed(cipherKey, password) + if err != nil { + return nil, fmt.Errorf("failed to decrypt the master seed of clef") + } + if len(masterSeed) < 256 { + return nil, fmt.Errorf("master seed of insufficient length, expected >255 bytes, got %d", len(masterSeed)) + } + + // Create vault location + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), masterSeed)[:10])) + err = os.Mkdir(vaultLocation, 0700) + if err != nil && !os.IsExist(err) { + return nil, err + } + return masterSeed, nil +} + +// checkFile is a convenience function to check if a file +// * exists +// * is mode 0400 +func checkFile(filename string) error { + info, err := os.Stat(filename) + if err != nil { + return fmt.Errorf("failed stat on %s: %v", filename, err) + } + // Check the unix permission bits + if info.Mode().Perm()&0377 != 0 { + return fmt.Errorf("file (%v) has insecure file permissions (%v)", filename, info.Mode().String()) + } + return nil +} + +// confirm displays a text and asks for user confirmation +func confirm(text string) bool { + fmt.Printf(text) + fmt.Printf("\nEnter 'ok' to proceed:\n>") + + text, err := bufio.NewReader(os.Stdin).ReadString('\n') + if err != nil { + log.Crit("Failed to read user input", "err", err) + } + + if text := strings.TrimSpace(text); text == "ok" { + return true + } + return false +} + +func testExternalUI(api *core.SignerAPI) { + + ctx := context.WithValue(context.Background(), "remote", "clef binary") + ctx = context.WithValue(ctx, "scheme", "in-proc") + ctx = context.WithValue(ctx, "local", "main") + errs := make([]string, 0) + + a := common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef") + addErr := func(errStr string) { + log.Info("Test error", "error", errStr) + errs = append(errs, errStr) + } + + queryUser := func(q string) string { + resp, err := api.UI.OnInputRequired(core.UserInputRequest{ + Title: "Testing", + Prompt: q, + }) + if err != nil { + addErr(err.Error()) + } + return resp.Text + } + expectResponse := func(testcase, question, expect string) { + if got := queryUser(question); got != expect { + addErr(fmt.Sprintf("%s: got %v, expected %v", testcase, got, expect)) + } + } + expectApprove := func(testcase string, err error) { + if err == nil || err == accounts.ErrUnknownAccount { + return + } + addErr(fmt.Sprintf("%v: expected no error, got %v", testcase, err.Error())) + } + expectDeny := func(testcase string, err error) { + if err == nil || err != core.ErrRequestDenied { + addErr(fmt.Sprintf("%v: expected ErrRequestDenied, got %v", testcase, err)) + } + } + var delay = 1 * time.Second + // Test display of info and error + { + api.UI.ShowInfo("If you see this message, enter 'yes' to next question") + time.Sleep(delay) + expectResponse("showinfo", "Did you see the message? [yes/no]", "yes") + api.UI.ShowError("If you see this message, enter 'yes' to the next question") + time.Sleep(delay) + expectResponse("showerror", "Did you see the message? [yes/no]", "yes") + } + { // Sign data test - clique header + api.UI.ShowInfo("Please approve the next request for signing a clique header") + time.Sleep(delay) + cliqueHeader := types.Header{ + common.HexToHash("0000H45H"), + common.HexToHash("0000H45H"), + common.HexToAddress("0000H45H"), + common.HexToHash("0000H00H"), + common.HexToHash("0000H45H"), + common.HexToHash("0000H45H"), + types.Bloom{}, + big.NewInt(1337), + big.NewInt(1337), + 1338, + 1338, + 1338, + []byte("Extra data Extra data Extra data Extra data Extra data Extra data Extra data Extra data"), + common.HexToHash("0x0000H45H"), + types.BlockNonce{}, + } + cliqueRlp, err := rlp.EncodeToBytes(cliqueHeader) + if err != nil { + utils.Fatalf("Should not error: %v", err) + } + addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") + _, err = api.SignData(ctx, accounts.MimetypeClique, *addr, hexutil.Encode(cliqueRlp)) + expectApprove("signdata - clique header", err) + } + { // Sign data test - typed data + api.UI.ShowInfo("Please approve the next request for signing EIP-712 typed data") + time.Sleep(delay) + addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") + data := `{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"test","type":"uint8"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":"1","verifyingContract":"0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","test":"3","wallet":"0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB","test":"2"},"contents":"Hello, Bob!"}}` + //_, err := api.SignData(ctx, accounts.MimetypeTypedData, *addr, hexutil.Encode([]byte(data))) + var typedData core.TypedData + err := json.Unmarshal([]byte(data), &typedData) + _, err = api.SignTypedData(ctx, *addr, typedData) + expectApprove("sign 712 typed data", err) + } + { // Sign data test - plain text + api.UI.ShowInfo("Please approve the next request for signing text") + time.Sleep(delay) + addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") + _, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) + expectApprove("signdata - text", err) + } + { // Sign data test - plain text reject + api.UI.ShowInfo("Please deny the next request for signing text") + time.Sleep(delay) + addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") + _, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) + expectDeny("signdata - text", err) + } + { // Sign transaction + + api.UI.ShowInfo("Please reject next transaction") + time.Sleep(delay) + data := hexutil.Bytes([]byte{}) + to := common.NewMixedcaseAddress(a) + tx := core.SendTxArgs{ + Data: &data, + Nonce: 0x1, + Value: hexutil.Big(*big.NewInt(6)), + From: common.NewMixedcaseAddress(a), + To: &to, + GasPrice: hexutil.Big(*big.NewInt(5)), + Gas: 1000, + Input: nil, + } + _, err := api.SignTransaction(ctx, tx, nil) + expectDeny("signtransaction [1]", err) + expectResponse("signtransaction [2]", "Did you see any warnings for the last transaction? (yes/no)", "no") + } + { // Listing + api.UI.ShowInfo("Please reject listing-request") + time.Sleep(delay) + _, err := api.List(ctx) + expectDeny("list", err) + } + { // Import + api.UI.ShowInfo("Please reject new account-request") + time.Sleep(delay) + _, err := api.New(ctx) + expectDeny("newaccount", err) + } + { // Metadata + api.UI.ShowInfo("Please check if you see the Origin in next listing (approve or deny)") + time.Sleep(delay) + api.List(context.WithValue(ctx, "Origin", "origin.com")) + expectResponse("metadata - origin", "Did you see origin (origin.com)? [yes/no] ", "yes") + } + + for _, e := range errs { + log.Error(e) + } + result := fmt.Sprintf("Tests completed. %d errors:\n%s\n", len(errs), strings.Join(errs, "\n")) + api.UI.ShowInfo(result) + +} + +// getPassPhrase retrieves the password associated with clef, either fetched +// from a list of preloaded passphrases, or requested interactively from the user. +// TODO: there are many `getPassPhrase` functions, it will be better to abstract them into one. +func getPassPhrase(prompt string, confirmation bool) string { + fmt.Println(prompt) + password, err := console.Stdin.PromptPassword("Passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase: %v", err) + } + if confirmation { + confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase confirmation: %v", err) + } + if password != confirm { + utils.Fatalf("Passphrases do not match") + } + } + return password +} + +type encryptedSeedStorage struct { + Description string `json:"description"` + Version int `json:"version"` + Params keystore.CryptoJSON `json:"params"` +} + +// encryptSeed uses a similar scheme as the keystore uses, but with a different wrapping, +// to encrypt the master seed +func encryptSeed(seed []byte, auth []byte, scryptN, scryptP int) ([]byte, error) { + cryptoStruct, err := keystore.EncryptDataV3(seed, auth, scryptN, scryptP) + if err != nil { + return nil, err + } + return json.Marshal(&encryptedSeedStorage{"Clef seed", 1, cryptoStruct}) +} + +// decryptSeed decrypts the master seed +func decryptSeed(keyjson []byte, auth string) ([]byte, error) { + var encSeed encryptedSeedStorage + if err := json.Unmarshal(keyjson, &encSeed); err != nil { + return nil, err + } + if encSeed.Version != 1 { + log.Warn(fmt.Sprintf("unsupported encryption format of seed: %d, operation will likely fail", encSeed.Version)) + } + seed, err := keystore.DecryptDataV3(encSeed.Params, auth) + if err != nil { + return nil, err + } + return seed, err +} + +// GenDoc outputs examples of all structures used in json-rpc communication +func GenDoc(ctx *cli.Context) { + + var ( + a = common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef") + b = common.HexToAddress("0x1111111122222222222233333333334444444444") + meta = core.Metadata{ + Scheme: "http", + Local: "localhost:8545", + Origin: "www.malicious.ru", + Remote: "localhost:9999", + UserAgent: "Firefox 3.2", + } + output []string + add = func(name, desc string, v interface{}) { + if data, err := json.MarshalIndent(v, "", " "); err == nil { + output = append(output, fmt.Sprintf("### %s\n\n%s\n\nExample:\n```json\n%s\n```", name, desc, data)) + } else { + log.Error("Error generating output", err) + } + } + ) + + { // Sign plain text request + desc := "SignDataRequest contains information about a pending request to sign some data. " + + "The data to be signed can be of various types, defined by content-type. Clef has done most " + + "of the work in canonicalizing and making sense of the data, and it's up to the UI to present" + + "the user with the contents of the `message`" + sighash, msg := accounts.TextAndHash([]byte("hello world")) + message := []*core.NameValueType{{"message", msg, accounts.MimetypeTextPlain}} + + add("SignDataRequest", desc, &core.SignDataRequest{ + Address: common.NewMixedcaseAddress(a), + Meta: meta, + ContentType: accounts.MimetypeTextPlain, + Rawdata: []byte(msg), + Message: message, + Hash: sighash}) + } + { // Sign plain text response + add("SignDataResponse - approve", "Response to SignDataRequest", + &core.SignDataResponse{Approved: true}) + add("SignDataResponse - deny", "Response to SignDataRequest", + &core.SignDataResponse{}) + } + { // Sign transaction request + desc := "SignTxRequest contains information about a pending request to sign a transaction. " + + "Aside from the transaction itself, there is also a `call_info`-struct. That struct contains " + + "messages of various types, that the user should be informed of." + + "\n\n" + + "As in any request, it's important to consider that the `meta` info also contains untrusted data." + + "\n\n" + + "The `transaction` (on input into clef) can have either `data` or `input` -- if both are set, " + + "they must be identical, otherwise an error is generated. " + + "However, Clef will always use `data` when passing this struct on (if Clef does otherwise, please file a ticket)" + + data := hexutil.Bytes([]byte{0x01, 0x02, 0x03, 0x04}) + add("SignTxRequest", desc, &core.SignTxRequest{ + Meta: meta, + Callinfo: []core.ValidationInfo{ + {"Warning", "Something looks odd, show this message as a warning"}, + {"Info", "User should see this aswell"}, + }, + Transaction: core.SendTxArgs{ + Data: &data, + Nonce: 0x1, + Value: hexutil.Big(*big.NewInt(6)), + From: common.NewMixedcaseAddress(a), + To: nil, + GasPrice: hexutil.Big(*big.NewInt(5)), + Gas: 1000, + Input: nil, + }}) + } + { // Sign tx response + data := hexutil.Bytes([]byte{0x04, 0x03, 0x02, 0x01}) + add("SignTxResponse - approve", "Response to request to sign a transaction. This response needs to contain the `transaction`"+ + ", because the UI is free to make modifications to the transaction.", + &core.SignTxResponse{Approved: true, + Transaction: core.SendTxArgs{ + Data: &data, + Nonce: 0x4, + Value: hexutil.Big(*big.NewInt(6)), + From: common.NewMixedcaseAddress(a), + To: nil, + GasPrice: hexutil.Big(*big.NewInt(5)), + Gas: 1000, + Input: nil, + }}) + add("SignTxResponse - deny", "Response to SignTxRequest. When denying a request, there's no need to "+ + "provide the transaction in return", + &core.SignTxResponse{}) + } + { // WHen a signed tx is ready to go out + desc := "SignTransactionResult is used in the call `clef` -> `OnApprovedTx(result)`" + + "\n\n" + + "This occurs _after_ successful completion of the entire signing procedure, but right before the signed " + + "transaction is passed to the external caller. This method (and data) can be used by the UI to signal " + + "to the user that the transaction was signed, but it is primarily useful for ruleset implementations." + + "\n\n" + + "A ruleset that implements a rate limitation needs to know what transactions are sent out to the external " + + "interface. By hooking into this methods, the ruleset can maintain track of that count." + + "\n\n" + + "**OBS:** Note that if an attacker can restore your `clef` data to a previous point in time" + + " (e.g through a backup), the attacker can reset such windows, even if he/she is unable to decrypt the content. " + + "\n\n" + + "The `OnApproved` method cannot be responded to, it's purely informative" + + rlpdata := common.FromHex("0xf85d640101948a8eafb1cf62bfbeb1741769dae1a9dd47996192018026a0716bd90515acb1e68e5ac5867aa11a1e65399c3349d479f5fb698554ebc6f293a04e8a4ebfff434e971e0ef12c5bf3a881b06fd04fc3f8b8a7291fb67a26a1d4ed") + var tx types.Transaction + rlp.DecodeBytes(rlpdata, &tx) + add("OnApproved - SignTransactionResult", desc, ðapi.SignTransactionResult{Raw: rlpdata, Tx: &tx}) + + } + { // User input + add("UserInputRequest", "Sent when clef needs the user to provide data. If 'password' is true, the input field should be treated accordingly (echo-free)", + &core.UserInputRequest{IsPassword: true, Title: "The title here", Prompt: "The question to ask the user"}) + add("UserInputResponse", "Response to UserInputRequest", + &core.UserInputResponse{Text: "The textual response from user"}) + } + { // List request + add("ListRequest", "Sent when a request has been made to list addresses. The UI is provided with the "+ + "full `account`s, including local directory names. Note: this information is not passed back to the external caller, "+ + "who only sees the `address`es. ", + &core.ListRequest{ + Meta: meta, + Accounts: []accounts.Account{ + {a, accounts.URL{Scheme: "keystore", Path: "/path/to/keyfile/a"}}, + {b, accounts.URL{Scheme: "keystore", Path: "/path/to/keyfile/b"}}}, + }) + + add("ListResponse", "Response to list request. The response contains a list of all addresses to show to the caller. "+ + "Note: the UI is free to respond with any address the caller, regardless of whether it exists or not", + &core.ListResponse{ + Accounts: []accounts.Account{ + {common.HexToAddress("0xcowbeef000000cowbeef00000000000000000c0w"), accounts.URL{Path: ".. ignored .."}}, + {common.HexToAddress("0xffffffffffffffffffffffffffffffffffffffff"), accounts.URL{}}, + }}) + } + + fmt.Println(`## UI Client interface + +These data types are defined in the channel between clef and the UI`) + for _, elem := range output { + fmt.Println(elem) + } +} + +/** +//Create Account + +curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_new","params":["test"],"id":67}' localhost:8550 + +// List accounts + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_list","params":[""],"id":67}' http://localhost:8550/ + +// Make Transaction +// safeSend(0x12) +// 4401a6e40000000000000000000000000000000000000000000000000000000000000012 + +// supplied abi +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x82A2A876D39022B3019932D30Cd9c97ad5616813","gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"test"],"id":67}' http://localhost:8550/ + +// Not supplied +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x82A2A876D39022B3019932D30Cd9c97ad5616813","gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"}],"id":67}' http://localhost:8550/ + +// Sign data + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_sign","params":["0x694267f14675d7e1b9494fd8d72fefe1755710fa","bazonk gaz baz"],"id":67}' http://localhost:8550/ + + +**/ diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/discv4cmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/discv4cmd.go new file mode 100644 index 00000000..1e56687a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/discv4cmd.go @@ -0,0 +1,166 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "fmt" + "net" + "sort" + "strings" + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" + "gopkg.in/urfave/cli.v1" +) + +var ( + discv4Command = cli.Command{ + Name: "discv4", + Usage: "Node Discovery v4 tools", + Subcommands: []cli.Command{ + discv4PingCommand, + discv4RequestRecordCommand, + discv4ResolveCommand, + }, + } + discv4PingCommand = cli.Command{ + Name: "ping", + Usage: "Sends ping to a node", + Action: discv4Ping, + } + discv4RequestRecordCommand = cli.Command{ + Name: "requestenr", + Usage: "Requests a node record using EIP-868 enrRequest", + Action: discv4RequestRecord, + } + discv4ResolveCommand = cli.Command{ + Name: "resolve", + Usage: "Finds a node in the DHT", + Action: discv4Resolve, + Flags: []cli.Flag{bootnodesFlag}, + } +) + +var bootnodesFlag = cli.StringFlag{ + Name: "bootnodes", + Usage: "Comma separated nodes used for bootstrapping", +} + +func discv4Ping(ctx *cli.Context) error { + n, disc, err := getNodeArgAndStartV4(ctx) + if err != nil { + return err + } + defer disc.Close() + + start := time.Now() + if err := disc.Ping(n); err != nil { + return fmt.Errorf("node didn't respond: %v", err) + } + fmt.Printf("node responded to ping (RTT %v).\n", time.Since(start)) + return nil +} + +func discv4RequestRecord(ctx *cli.Context) error { + n, disc, err := getNodeArgAndStartV4(ctx) + if err != nil { + return err + } + defer disc.Close() + + respN, err := disc.RequestENR(n) + if err != nil { + return fmt.Errorf("can't retrieve record: %v", err) + } + fmt.Println(respN.String()) + return nil +} + +func discv4Resolve(ctx *cli.Context) error { + n, disc, err := getNodeArgAndStartV4(ctx) + if err != nil { + return err + } + defer disc.Close() + + fmt.Println(disc.Resolve(n).String()) + return nil +} + +func getNodeArgAndStartV4(ctx *cli.Context) (*enode.Node, *discover.UDPv4, error) { + if ctx.NArg() != 1 { + return nil, nil, fmt.Errorf("missing node as command-line argument") + } + n, err := parseNode(ctx.Args()[0]) + if err != nil { + return nil, nil, err + } + var bootnodes []*enode.Node + if commandHasFlag(ctx, bootnodesFlag) { + bootnodes, err = parseBootnodes(ctx) + if err != nil { + return nil, nil, err + } + } + disc, err := startV4(bootnodes) + return n, disc, err +} + +func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { + s := params.RinkebyBootnodes + if ctx.IsSet(bootnodesFlag.Name) { + s = strings.Split(ctx.String(bootnodesFlag.Name), ",") + } + nodes := make([]*enode.Node, len(s)) + var err error + for i, record := range s { + nodes[i], err = parseNode(record) + if err != nil { + return nil, fmt.Errorf("invalid bootstrap node: %v", err) + } + } + return nodes, nil +} + +// commandHasFlag returns true if the current command supports the given flag. +func commandHasFlag(ctx *cli.Context, flag cli.Flag) bool { + flags := ctx.FlagNames() + sort.Strings(flags) + i := sort.SearchStrings(flags, flag.GetName()) + return i != len(flags) && flags[i] == flag.GetName() +} + +// startV4 starts an ephemeral discovery V4 node. +func startV4(bootnodes []*enode.Node) (*discover.UDPv4, error) { + var cfg discover.Config + cfg.Bootnodes = bootnodes + cfg.PrivateKey, _ = crypto.GenerateKey() + db, _ := enode.OpenDB("") + ln := enode.NewLocalNode(db, cfg.PrivateKey) + + socket, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IP{0, 0, 0, 0}}) + if err != nil { + return nil, err + } + addr := socket.LocalAddr().(*net.UDPAddr) + ln.SetFallbackIP(net.IP{127, 0, 0, 1}) + ln.SetFallbackUDP(addr.Port) + return discover.ListenUDP(socket, ln, cfg) +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/enrcmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/enrcmd.go new file mode 100644 index 00000000..15d77dd0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/enrcmd.go @@ -0,0 +1,198 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "bytes" + "encoding/base64" + "encoding/hex" + "fmt" + "io/ioutil" + "net" + "os" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/rlp" + "gopkg.in/urfave/cli.v1" +) + +var enrdumpCommand = cli.Command{ + Name: "enrdump", + Usage: "Pretty-prints node records", + Action: enrdump, + Flags: []cli.Flag{ + cli.StringFlag{Name: "file"}, + }, +} + +func enrdump(ctx *cli.Context) error { + var source string + if file := ctx.String("file"); file != "" { + if ctx.NArg() != 0 { + return fmt.Errorf("can't dump record from command-line argument in -file mode") + } + var b []byte + var err error + if file == "-" { + b, err = ioutil.ReadAll(os.Stdin) + } else { + b, err = ioutil.ReadFile(file) + } + if err != nil { + return err + } + source = string(b) + } else if ctx.NArg() == 1 { + source = ctx.Args()[0] + } else { + return fmt.Errorf("need record as argument") + } + + r, err := parseRecord(source) + if err != nil { + return fmt.Errorf("INVALID: %v", err) + } + fmt.Print(dumpRecord(r)) + return nil +} + +// dumpRecord creates a human-readable description of the given node record. +func dumpRecord(r *enr.Record) string { + out := new(bytes.Buffer) + if n, err := enode.New(enode.ValidSchemes, r); err != nil { + fmt.Fprintf(out, "INVALID: %v\n", err) + } else { + fmt.Fprintf(out, "Node ID: %v\n", n.ID()) + } + kv := r.AppendElements(nil)[1:] + fmt.Fprintf(out, "Record has sequence number %d and %d key/value pairs.\n", r.Seq(), len(kv)/2) + fmt.Fprint(out, dumpRecordKV(kv, 2)) + return out.String() +} + +func dumpRecordKV(kv []interface{}, indent int) string { + // Determine the longest key name for alignment. + var out string + var longestKey = 0 + for i := 0; i < len(kv); i += 2 { + key := kv[i].(string) + if len(key) > longestKey { + longestKey = len(key) + } + } + // Print the keys, invoking formatters for known keys. + for i := 0; i < len(kv); i += 2 { + key := kv[i].(string) + val := kv[i+1].(rlp.RawValue) + pad := longestKey - len(key) + out += strings.Repeat(" ", indent) + strconv.Quote(key) + strings.Repeat(" ", pad+1) + formatter := attrFormatters[key] + if formatter == nil { + formatter = formatAttrRaw + } + fmtval, ok := formatter(val) + if ok { + out += fmtval + "\n" + } else { + out += hex.EncodeToString(val) + " (!)\n" + } + } + return out +} + +// parseNode parses a node record and verifies its signature. +func parseNode(source string) (*enode.Node, error) { + if strings.HasPrefix(source, "enode://") { + return enode.ParseV4(source) + } + r, err := parseRecord(source) + if err != nil { + return nil, err + } + return enode.New(enode.ValidSchemes, r) +} + +// parseRecord parses a node record from hex, base64, or raw binary input. +func parseRecord(source string) (*enr.Record, error) { + bin := []byte(source) + if d, ok := decodeRecordHex(bytes.TrimSpace(bin)); ok { + bin = d + } else if d, ok := decodeRecordBase64(bytes.TrimSpace(bin)); ok { + bin = d + } + var r enr.Record + err := rlp.DecodeBytes(bin, &r) + return &r, err +} + +func decodeRecordHex(b []byte) ([]byte, bool) { + if bytes.HasPrefix(b, []byte("0x")) { + b = b[2:] + } + dec := make([]byte, hex.DecodedLen(len(b))) + _, err := hex.Decode(dec, b) + return dec, err == nil +} + +func decodeRecordBase64(b []byte) ([]byte, bool) { + if bytes.HasPrefix(b, []byte("enr:")) { + b = b[4:] + } + dec := make([]byte, base64.RawURLEncoding.DecodedLen(len(b))) + n, err := base64.RawURLEncoding.Decode(dec, b) + return dec[:n], err == nil +} + +// attrFormatters contains formatting functions for well-known ENR keys. +var attrFormatters = map[string]func(rlp.RawValue) (string, bool){ + "id": formatAttrString, + "ip": formatAttrIP, + "ip6": formatAttrIP, + "tcp": formatAttrUint, + "tcp6": formatAttrUint, + "udp": formatAttrUint, + "udp6": formatAttrUint, +} + +func formatAttrRaw(v rlp.RawValue) (string, bool) { + s := hex.EncodeToString(v) + return s, true +} + +func formatAttrString(v rlp.RawValue) (string, bool) { + content, _, err := rlp.SplitString(v) + return strconv.Quote(string(content)), err == nil +} + +func formatAttrIP(v rlp.RawValue) (string, bool) { + content, _, err := rlp.SplitString(v) + if err != nil || len(content) != 4 && len(content) != 6 { + return "", false + } + return net.IP(content).String(), true +} + +func formatAttrUint(v rlp.RawValue) (string, bool) { + var x uint64 + if err := rlp.DecodeBytes(v, &x); err != nil { + return "", false + } + return strconv.FormatUint(x, 10), true +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/main.go new file mode 100644 index 00000000..4532ab96 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/devp2p/main.go @@ -0,0 +1,68 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/params" + "gopkg.in/urfave/cli.v1" +) + +var ( + // Git information set by linker when building with ci.go. + gitCommit string + gitDate string + app = &cli.App{ + Name: filepath.Base(os.Args[0]), + Usage: "go-ethereum devp2p tool", + Version: params.VersionWithCommit(gitCommit, gitDate), + Writer: os.Stdout, + HideVersion: true, + } +) + +func init() { + // Set up the CLI app. + app.Flags = append(app.Flags, debug.Flags...) + app.Before = func(ctx *cli.Context) error { + return debug.Setup(ctx, "") + } + app.After = func(ctx *cli.Context) error { + debug.Exit() + return nil + } + app.CommandNotFound = func(ctx *cli.Context, cmd string) { + fmt.Fprintf(os.Stderr, "No such command: %s\n", cmd) + os.Exit(1) + } + // Add subcommands. + app.Commands = []cli.Command{ + enrdumpCommand, + discv4Command, + } +} + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/ethkey/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/ethkey/main.go new file mode 100644 index 00000000..a8399ad7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/ethkey/main.go @@ -0,0 +1,65 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "fmt" + "os" + + "github.com/ethereum/go-ethereum/cmd/utils" + "gopkg.in/urfave/cli.v1" +) + +const ( + defaultKeyfileName = "keyfile.json" +) + +// Git SHA1 commit hash of the release (set via linker flags) +var gitCommit = "" +var gitDate = "" + +var app *cli.App + +func init() { + app = utils.NewApp(gitCommit, gitDate, "an Ethereum key manager") + app.Commands = []cli.Command{ + commandGenerate, + commandInspect, + commandChangePassphrase, + commandSignMessage, + commandVerifyMessage, + } +} + +// Commonly used command line flags. +var ( + passphraseFlag = cli.StringFlag{ + Name: "passwordfile", + Usage: "the file that contains the passphrase for the keyfile", + } + jsonFlag = cli.BoolFlag{ + Name: "json", + Usage: "output JSON instead of human-readable format", + } +) + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/evm/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/evm/main.go new file mode 100644 index 00000000..a5159c6b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/evm/main.go @@ -0,0 +1,157 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// evm executes EVM code snippets. +package main + +import ( + "fmt" + "math/big" + "os" + + "github.com/ethereum/go-ethereum/cmd/utils" + "gopkg.in/urfave/cli.v1" +) + +var gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) +var gitDate = "" + +var ( + app = utils.NewApp(gitCommit, gitDate, "the evm command line interface") + + DebugFlag = cli.BoolFlag{ + Name: "debug", + Usage: "output full trace logs", + } + MemProfileFlag = cli.StringFlag{ + Name: "memprofile", + Usage: "creates a memory profile at the given path", + } + CPUProfileFlag = cli.StringFlag{ + Name: "cpuprofile", + Usage: "creates a CPU profile at the given path", + } + StatDumpFlag = cli.BoolFlag{ + Name: "statdump", + Usage: "displays stack and heap memory information", + } + CodeFlag = cli.StringFlag{ + Name: "code", + Usage: "EVM code", + } + CodeFileFlag = cli.StringFlag{ + Name: "codefile", + Usage: "File containing EVM code. If '-' is specified, code is read from stdin ", + } + GasFlag = cli.Uint64Flag{ + Name: "gas", + Usage: "gas limit for the evm", + Value: 10000000000, + } + PriceFlag = utils.BigFlag{ + Name: "price", + Usage: "price set for the evm", + Value: new(big.Int), + } + ValueFlag = utils.BigFlag{ + Name: "value", + Usage: "value set for the evm", + Value: new(big.Int), + } + DumpFlag = cli.BoolFlag{ + Name: "dump", + Usage: "dumps the state after the run", + } + InputFlag = cli.StringFlag{ + Name: "input", + Usage: "input for the EVM", + } + VerbosityFlag = cli.IntFlag{ + Name: "verbosity", + Usage: "sets the verbosity level", + } + CreateFlag = cli.BoolFlag{ + Name: "create", + Usage: "indicates the action should be create rather than call", + } + GenesisFlag = cli.StringFlag{ + Name: "prestate", + Usage: "JSON file with prestate (genesis) config", + } + MachineFlag = cli.BoolFlag{ + Name: "json", + Usage: "output trace logs in machine readable format (json)", + } + SenderFlag = cli.StringFlag{ + Name: "sender", + Usage: "The transaction origin", + } + ReceiverFlag = cli.StringFlag{ + Name: "receiver", + Usage: "The transaction receiver (execution context)", + } + DisableMemoryFlag = cli.BoolFlag{ + Name: "nomemory", + Usage: "disable memory output", + } + DisableStackFlag = cli.BoolFlag{ + Name: "nostack", + Usage: "disable stack output", + } + EVMInterpreterFlag = cli.StringFlag{ + Name: "vm.evm", + Usage: "External EVM configuration (default = built-in interpreter)", + Value: "", + } +) + +func init() { + app.Flags = []cli.Flag{ + CreateFlag, + DebugFlag, + VerbosityFlag, + CodeFlag, + CodeFileFlag, + GasFlag, + PriceFlag, + ValueFlag, + DumpFlag, + InputFlag, + MemProfileFlag, + CPUProfileFlag, + StatDumpFlag, + GenesisFlag, + MachineFlag, + SenderFlag, + ReceiverFlag, + DisableMemoryFlag, + DisableStackFlag, + EVMInterpreterFlag, + } + app.Commands = []cli.Command{ + compileCommand, + disasmCommand, + runCommand, + stateTestCommand, + } +} + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.go b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.go new file mode 100644 index 00000000..f8092084 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.go @@ -0,0 +1,754 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// faucet is a Ether faucet backed by a light client. +package main + +//go:generate go-bindata -nometadata -o website.go faucet.html +//go:generate gofmt -w -s website.go + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "flag" + "fmt" + "html/template" + "io/ioutil" + "math" + "math/big" + "net/http" + "net/url" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/les" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/params" + "golang.org/x/net/websocket" +) + +var ( + genesisFlag = flag.String("genesis", "", "Genesis json file to seed the chain with") + apiPortFlag = flag.Int("apiport", 8080, "Listener port for the HTTP API connection") + ethPortFlag = flag.Int("ethport", 30303, "Listener port for the devp2p connection") + bootFlag = flag.String("bootnodes", "", "Comma separated bootnode enode URLs to seed with") + netFlag = flag.Uint64("network", 0, "Network ID to use for the Ethereum protocol") + statsFlag = flag.String("ethstats", "", "Ethstats network monitoring auth string") + + netnameFlag = flag.String("faucet.name", "", "Network name to assign to the faucet") + payoutFlag = flag.Int("faucet.amount", 1, "Number of Ethers to pay out per user request") + minutesFlag = flag.Int("faucet.minutes", 1440, "Number of minutes to wait between funding rounds") + tiersFlag = flag.Int("faucet.tiers", 3, "Number of funding tiers to enable (x3 time, x2.5 funds)") + + accJSONFlag = flag.String("account.json", "", "Key json file to fund user requests with") + accPassFlag = flag.String("account.pass", "", "Decryption password to access faucet funds") + + captchaToken = flag.String("captcha.token", "", "Recaptcha site key to authenticate client side") + captchaSecret = flag.String("captcha.secret", "", "Recaptcha secret key to authenticate server side") + + noauthFlag = flag.Bool("noauth", false, "Enables funding requests without authentication") + logFlag = flag.Int("loglevel", 3, "Log level to use for Ethereum and the faucet") +) + +var ( + ether = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil) +) + +var ( + gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) + gitDate = "" // Git commit date YYYYMMDD of the release (set via linker flags) +) + +func main() { + // Parse the flags and set up the logger to print everything requested + flag.Parse() + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*logFlag), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + + // Construct the payout tiers + amounts := make([]string, *tiersFlag) + periods := make([]string, *tiersFlag) + for i := 0; i < *tiersFlag; i++ { + // Calculate the amount for the next tier and format it + amount := float64(*payoutFlag) * math.Pow(2.5, float64(i)) + amounts[i] = fmt.Sprintf("%s Ethers", strconv.FormatFloat(amount, 'f', -1, 64)) + if amount == 1 { + amounts[i] = strings.TrimSuffix(amounts[i], "s") + } + // Calculate the period for the next tier and format it + period := *minutesFlag * int(math.Pow(3, float64(i))) + periods[i] = fmt.Sprintf("%d mins", period) + if period%60 == 0 { + period /= 60 + periods[i] = fmt.Sprintf("%d hours", period) + + if period%24 == 0 { + period /= 24 + periods[i] = fmt.Sprintf("%d days", period) + } + } + if period == 1 { + periods[i] = strings.TrimSuffix(periods[i], "s") + } + } + // Load up and render the faucet website + tmpl, err := Asset("faucet.html") + if err != nil { + log.Crit("Failed to load the faucet template", "err", err) + } + website := new(bytes.Buffer) + err = template.Must(template.New("").Parse(string(tmpl))).Execute(website, map[string]interface{}{ + "Network": *netnameFlag, + "Amounts": amounts, + "Periods": periods, + "Recaptcha": *captchaToken, + "NoAuth": *noauthFlag, + }) + if err != nil { + log.Crit("Failed to render the faucet template", "err", err) + } + // Load and parse the genesis block requested by the user + blob, err := ioutil.ReadFile(*genesisFlag) + if err != nil { + log.Crit("Failed to read genesis block contents", "genesis", *genesisFlag, "err", err) + } + genesis := new(core.Genesis) + if err = json.Unmarshal(blob, genesis); err != nil { + log.Crit("Failed to parse genesis block json", "err", err) + } + // Convert the bootnodes to internal enode representations + var enodes []*discv5.Node + for _, boot := range strings.Split(*bootFlag, ",") { + if url, err := discv5.ParseNode(boot); err == nil { + enodes = append(enodes, url) + } else { + log.Error("Failed to parse bootnode URL", "url", boot, "err", err) + } + } + // Load up the account key and decrypt its password + if blob, err = ioutil.ReadFile(*accPassFlag); err != nil { + log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err) + } + // Delete trailing newline in password + pass := strings.TrimSuffix(string(blob), "\n") + + ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP) + if blob, err = ioutil.ReadFile(*accJSONFlag); err != nil { + log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err) + } + acc, err := ks.Import(blob, pass, pass) + if err != nil { + log.Crit("Failed to import faucet signer account", "err", err) + } + ks.Unlock(acc, pass) + + // Assemble and start the faucet light service + faucet, err := newFaucet(genesis, *ethPortFlag, enodes, *netFlag, *statsFlag, ks, website.Bytes()) + if err != nil { + log.Crit("Failed to start faucet", "err", err) + } + defer faucet.close() + + if err := faucet.listenAndServe(*apiPortFlag); err != nil { + log.Crit("Failed to launch faucet API", "err", err) + } +} + +// request represents an accepted funding request. +type request struct { + Avatar string `json:"avatar"` // Avatar URL to make the UI nicer + Account common.Address `json:"account"` // Ethereum address being funded + Time time.Time `json:"time"` // Timestamp when the request was accepted + Tx *types.Transaction `json:"tx"` // Transaction funding the account +} + +// faucet represents a crypto faucet backed by an Ethereum light client. +type faucet struct { + config *params.ChainConfig // Chain configurations for signing + stack *node.Node // Ethereum protocol stack + client *ethclient.Client // Client connection to the Ethereum chain + index []byte // Index page to serve up on the web + + keystore *keystore.KeyStore // Keystore containing the single signer + account accounts.Account // Account funding user faucet requests + head *types.Header // Current head header of the faucet + balance *big.Int // Current balance of the faucet + nonce uint64 // Current pending nonce of the faucet + price *big.Int // Current gas price to issue funds with + + conns []*websocket.Conn // Currently live websocket connections + timeouts map[string]time.Time // History of users and their funding timeouts + reqs []*request // Currently pending funding requests + update chan struct{} // Channel to signal request updates + + lock sync.RWMutex // Lock protecting the faucet's internals +} + +func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network uint64, stats string, ks *keystore.KeyStore, index []byte) (*faucet, error) { + // Assemble the raw devp2p protocol stack + stack, err := node.New(&node.Config{ + Name: "geth", + Version: params.VersionWithCommit(gitCommit, gitDate), + DataDir: filepath.Join(os.Getenv("HOME"), ".faucet"), + P2P: p2p.Config{ + NAT: nat.Any(), + NoDiscovery: true, + DiscoveryV5: true, + ListenAddr: fmt.Sprintf(":%d", port), + MaxPeers: 25, + BootstrapNodesV5: enodes, + }, + }) + if err != nil { + return nil, err + } + // Assemble the Ethereum light client protocol + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + cfg := eth.DefaultConfig + cfg.SyncMode = downloader.LightSync + cfg.NetworkId = network + cfg.Genesis = genesis + return les.New(ctx, &cfg) + }); err != nil { + return nil, err + } + // Assemble the ethstats monitoring and reporting service' + if stats != "" { + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + var serv *les.LightEthereum + ctx.Service(&serv) + return ethstats.New(stats, nil, serv) + }); err != nil { + return nil, err + } + } + // Boot up the client and ensure it connects to bootnodes + if err := stack.Start(); err != nil { + return nil, err + } + for _, boot := range enodes { + old, err := enode.Parse(enode.ValidSchemes, boot.String()) + if err == nil { + stack.Server().AddPeer(old) + } + } + // Attach to the client and retrieve and interesting metadatas + api, err := stack.Attach() + if err != nil { + stack.Stop() + return nil, err + } + client := ethclient.NewClient(api) + + return &faucet{ + config: genesis.Config, + stack: stack, + client: client, + index: index, + keystore: ks, + account: ks.Accounts()[0], + timeouts: make(map[string]time.Time), + update: make(chan struct{}, 1), + }, nil +} + +// close terminates the Ethereum connection and tears down the faucet. +func (f *faucet) close() error { + return f.stack.Close() +} + +// listenAndServe registers the HTTP handlers for the faucet and boots it up +// for service user funding requests. +func (f *faucet) listenAndServe(port int) error { + go f.loop() + + http.HandleFunc("/", f.webHandler) + http.Handle("/api", websocket.Handler(f.apiHandler)) + + return http.ListenAndServe(fmt.Sprintf(":%d", port), nil) +} + +// webHandler handles all non-api requests, simply flattening and returning the +// faucet website. +func (f *faucet) webHandler(w http.ResponseWriter, r *http.Request) { + w.Write(f.index) +} + +// apiHandler handles requests for Ether grants and transaction statuses. +func (f *faucet) apiHandler(conn *websocket.Conn) { + // Start tracking the connection and drop at the end + defer conn.Close() + + f.lock.Lock() + f.conns = append(f.conns, conn) + f.lock.Unlock() + + defer func() { + f.lock.Lock() + for i, c := range f.conns { + if c == conn { + f.conns = append(f.conns[:i], f.conns[i+1:]...) + break + } + } + f.lock.Unlock() + }() + // Gather the initial stats from the network to report + var ( + head *types.Header + balance *big.Int + nonce uint64 + err error + ) + for head == nil || balance == nil { + // Retrieve the current stats cached by the faucet + f.lock.RLock() + if f.head != nil { + head = types.CopyHeader(f.head) + } + if f.balance != nil { + balance = new(big.Int).Set(f.balance) + } + nonce = f.nonce + f.lock.RUnlock() + + if head == nil || balance == nil { + // Report the faucet offline until initial stats are ready + if err = sendError(conn, errors.New("Faucet offline")); err != nil { + log.Warn("Failed to send faucet error to client", "err", err) + return + } + time.Sleep(3 * time.Second) + } + } + // Send over the initial stats and the latest header + if err = send(conn, map[string]interface{}{ + "funds": new(big.Int).Div(balance, ether), + "funded": nonce, + "peers": f.stack.Server().PeerCount(), + "requests": f.reqs, + }, 3*time.Second); err != nil { + log.Warn("Failed to send initial stats to client", "err", err) + return + } + if err = send(conn, head, 3*time.Second); err != nil { + log.Warn("Failed to send initial header to client", "err", err) + return + } + // Keep reading requests from the websocket until the connection breaks + for { + // Fetch the next funding request and validate against github + var msg struct { + URL string `json:"url"` + Tier uint `json:"tier"` + Captcha string `json:"captcha"` + } + if err = websocket.JSON.Receive(conn, &msg); err != nil { + return + } + if !*noauthFlag && !strings.HasPrefix(msg.URL, "https://gist.github.com/") && !strings.HasPrefix(msg.URL, "https://twitter.com/") && + !strings.HasPrefix(msg.URL, "https://plus.google.com/") && !strings.HasPrefix(msg.URL, "https://www.facebook.com/") { + if err = sendError(conn, errors.New("URL doesn't link to supported services")); err != nil { + log.Warn("Failed to send URL error to client", "err", err) + return + } + continue + } + if msg.Tier >= uint(*tiersFlag) { + if err = sendError(conn, errors.New("Invalid funding tier requested")); err != nil { + log.Warn("Failed to send tier error to client", "err", err) + return + } + continue + } + log.Info("Faucet funds requested", "url", msg.URL, "tier", msg.Tier) + + // If captcha verifications are enabled, make sure we're not dealing with a robot + if *captchaToken != "" { + form := url.Values{} + form.Add("secret", *captchaSecret) + form.Add("response", msg.Captcha) + + res, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify", form) + if err != nil { + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha post error to client", "err", err) + return + } + continue + } + var result struct { + Success bool `json:"success"` + Errors json.RawMessage `json:"error-codes"` + } + err = json.NewDecoder(res.Body).Decode(&result) + res.Body.Close() + if err != nil { + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha decode error to client", "err", err) + return + } + continue + } + if !result.Success { + log.Warn("Captcha verification failed", "err", string(result.Errors)) + if err = sendError(conn, errors.New("Beep-bop, you're a robot!")); err != nil { + log.Warn("Failed to send captcha failure to client", "err", err) + return + } + continue + } + } + // Retrieve the Ethereum address to fund, the requesting user and a profile picture + var ( + username string + avatar string + address common.Address + ) + switch { + case strings.HasPrefix(msg.URL, "https://gist.github.com/"): + if err = sendError(conn, errors.New("GitHub authentication discontinued at the official request of GitHub")); err != nil { + log.Warn("Failed to send GitHub deprecation to client", "err", err) + return + } + continue + case strings.HasPrefix(msg.URL, "https://plus.google.com/"): + if err = sendError(conn, errors.New("Google+ authentication discontinued as the service was sunset")); err != nil { + log.Warn("Failed to send Google+ deprecation to client", "err", err) + return + } + continue + case strings.HasPrefix(msg.URL, "https://twitter.com/"): + username, avatar, address, err = authTwitter(msg.URL) + case strings.HasPrefix(msg.URL, "https://www.facebook.com/"): + username, avatar, address, err = authFacebook(msg.URL) + case *noauthFlag: + username, avatar, address, err = authNoAuth(msg.URL) + default: + err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum/go-ethereum/issues") + } + if err != nil { + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send prefix error to client", "err", err) + return + } + continue + } + log.Info("Faucet request valid", "url", msg.URL, "tier", msg.Tier, "user", username, "address", address) + + // Ensure the user didn't request funds too recently + f.lock.Lock() + var ( + fund bool + timeout time.Time + ) + if timeout = f.timeouts[username]; time.Now().After(timeout) { + // User wasn't funded recently, create the funding transaction + amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether) + amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil)) + amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil)) + + tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil) + signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID) + if err != nil { + f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction creation error to client", "err", err) + return + } + continue + } + // Submit the transaction and mark as funded if successful + if err := f.client.SendTransaction(context.Background(), signed); err != nil { + f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction transmission error to client", "err", err) + return + } + continue + } + f.reqs = append(f.reqs, &request{ + Avatar: avatar, + Account: address, + Time: time.Now(), + Tx: signed, + }) + f.timeouts[username] = time.Now().Add(time.Duration(*minutesFlag*int(math.Pow(3, float64(msg.Tier)))) * time.Minute) + fund = true + } + f.lock.Unlock() + + // Send an error if too frequent funding, othewise a success + if !fund { + if err = sendError(conn, fmt.Errorf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))); err != nil { // nolint: gosimple + log.Warn("Failed to send funding error to client", "err", err) + return + } + continue + } + if err = sendSuccess(conn, fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())); err != nil { + log.Warn("Failed to send funding success to client", "err", err) + return + } + select { + case f.update <- struct{}{}: + default: + } + } +} + +// refresh attempts to retrieve the latest header from the chain and extract the +// associated faucet balance and nonce for connectivity caching. +func (f *faucet) refresh(head *types.Header) error { + // Ensure a state update does not run for too long + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + // If no header was specified, use the current chain head + var err error + if head == nil { + if head, err = f.client.HeaderByNumber(ctx, nil); err != nil { + return err + } + } + // Retrieve the balance, nonce and gas price from the current head + var ( + balance *big.Int + nonce uint64 + price *big.Int + ) + if balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number); err != nil { + return err + } + if nonce, err = f.client.NonceAt(ctx, f.account.Address, head.Number); err != nil { + return err + } + if price, err = f.client.SuggestGasPrice(ctx); err != nil { + return err + } + // Everything succeeded, update the cached stats and eject old requests + f.lock.Lock() + f.head, f.balance = head, balance + f.price, f.nonce = price, nonce + for len(f.reqs) > 0 && f.reqs[0].Tx.Nonce() < f.nonce { + f.reqs = f.reqs[1:] + } + f.lock.Unlock() + + return nil +} + +// loop keeps waiting for interesting events and pushes them out to connected +// websockets. +func (f *faucet) loop() { + // Wait for chain events and push them to clients + heads := make(chan *types.Header, 16) + sub, err := f.client.SubscribeNewHead(context.Background(), heads) + if err != nil { + log.Crit("Failed to subscribe to head events", "err", err) + } + defer sub.Unsubscribe() + + // Start a goroutine to update the state from head notifications in the background + update := make(chan *types.Header) + + go func() { + for head := range update { + // New chain head arrived, query the current stats and stream to clients + timestamp := time.Unix(int64(head.Time), 0) + if time.Since(timestamp) > time.Hour { + log.Warn("Skipping faucet refresh, head too old", "number", head.Number, "hash", head.Hash(), "age", common.PrettyAge(timestamp)) + continue + } + if err := f.refresh(head); err != nil { + log.Warn("Failed to update faucet state", "block", head.Number, "hash", head.Hash(), "err", err) + continue + } + // Faucet state retrieved, update locally and send to clients + f.lock.RLock() + log.Info("Updated faucet state", "number", head.Number, "hash", head.Hash(), "age", common.PrettyAge(timestamp), "balance", f.balance, "nonce", f.nonce, "price", f.price) + + balance := new(big.Int).Div(f.balance, ether) + peers := f.stack.Server().PeerCount() + + for _, conn := range f.conns { + if err := send(conn, map[string]interface{}{ + "funds": balance, + "funded": f.nonce, + "peers": peers, + "requests": f.reqs, + }, time.Second); err != nil { + log.Warn("Failed to send stats to client", "err", err) + conn.Close() + continue + } + if err := send(conn, head, time.Second); err != nil { + log.Warn("Failed to send header to client", "err", err) + conn.Close() + } + } + f.lock.RUnlock() + } + }() + // Wait for various events and assing to the appropriate background threads + for { + select { + case head := <-heads: + // New head arrived, send if for state update if there's none running + select { + case update <- head: + default: + } + + case <-f.update: + // Pending requests updated, stream to clients + f.lock.RLock() + for _, conn := range f.conns { + if err := send(conn, map[string]interface{}{"requests": f.reqs}, time.Second); err != nil { + log.Warn("Failed to send requests to client", "err", err) + conn.Close() + } + } + f.lock.RUnlock() + } + } +} + +// sends transmits a data packet to the remote end of the websocket, but also +// setting a write deadline to prevent waiting forever on the node. +func send(conn *websocket.Conn, value interface{}, timeout time.Duration) error { + if timeout == 0 { + timeout = 60 * time.Second + } + conn.SetWriteDeadline(time.Now().Add(timeout)) + return websocket.JSON.Send(conn, value) +} + +// sendError transmits an error to the remote end of the websocket, also setting +// the write deadline to 1 second to prevent waiting forever. +func sendError(conn *websocket.Conn, err error) error { + return send(conn, map[string]string{"error": err.Error()}, time.Second) +} + +// sendSuccess transmits a success message to the remote end of the websocket, also +// setting the write deadline to 1 second to prevent waiting forever. +func sendSuccess(conn *websocket.Conn, msg string) error { + return send(conn, map[string]string{"success": msg}, time.Second) +} + +// authTwitter tries to authenticate a faucet request using Twitter posts, returning +// the username, avatar URL and Ethereum address to fund on success. +func authTwitter(url string) (string, string, common.Address, error) { + // Ensure the user specified a meaningful URL, no fancy nonsense + parts := strings.Split(url, "/") + if len(parts) < 4 || parts[len(parts)-2] != "status" { + return "", "", common.Address{}, errors.New("Invalid Twitter status URL") + } + // Twitter's API isn't really friendly with direct links. Still, we don't + // want to do ask read permissions from users, so just load the public posts and + // scrape it for the Ethereum address and profile URL. + res, err := http.Get(url) + if err != nil { + return "", "", common.Address{}, err + } + defer res.Body.Close() + + // Resolve the username from the final redirect, no intermediate junk + parts = strings.Split(res.Request.URL.String(), "/") + if len(parts) < 4 || parts[len(parts)-2] != "status" { + return "", "", common.Address{}, errors.New("Invalid Twitter status URL") + } + username := parts[len(parts)-3] + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", "", common.Address{}, err + } + address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + var avatar string + if parts = regexp.MustCompile("src=\"([^\"]+twimg.com/profile_images[^\"]+)\"").FindStringSubmatch(string(body)); len(parts) == 2 { + avatar = parts[1] + } + return username + "@twitter", avatar, address, nil +} + +// authFacebook tries to authenticate a faucet request using Facebook posts, +// returning the username, avatar URL and Ethereum address to fund on success. +func authFacebook(url string) (string, string, common.Address, error) { + // Ensure the user specified a meaningful URL, no fancy nonsense + parts := strings.Split(url, "/") + if len(parts) < 4 || parts[len(parts)-2] != "posts" { + return "", "", common.Address{}, errors.New("Invalid Facebook post URL") + } + username := parts[len(parts)-3] + + // Facebook's Graph API isn't really friendly with direct links. Still, we don't + // want to do ask read permissions from users, so just load the public posts and + // scrape it for the Ethereum address and profile URL. + res, err := http.Get(url) + if err != nil { + return "", "", common.Address{}, err + } + defer res.Body.Close() + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", "", common.Address{}, err + } + address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + var avatar string + if parts = regexp.MustCompile("src=\"([^\"]+fbcdn.net[^\"]+)\"").FindStringSubmatch(string(body)); len(parts) == 2 { + avatar = parts[1] + } + return username + "@facebook", avatar, address, nil +} + +// authNoAuth tries to interpret a faucet request as a plain Ethereum address, +// without actually performing any remote authentication. This mode is prone to +// Byzantine attack, so only ever use for truly private networks. +func authNoAuth(url string) (string, string, common.Address, error) { + address := common.HexToAddress(regexp.MustCompile("0x[0-9a-fA-F]{40}").FindString(url)) + if address == (common.Address{}) { + return "", "", common.Address{}, errors.New("No Ethereum address found to fund") + } + return address.Hex() + "@noauth", "", address, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.html b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.html new file mode 100644 index 00000000..314b19e1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/faucet.html @@ -0,0 +1,233 @@ + + + + + + + + {{.Network}}: Authenticated Faucet + + + + + + + + + + + + + +
+
+
+
+

{{.Network}} Authenticated Faucet

+
+
+
+
+
+ + + + + +
{{if .Recaptcha}} +
{{end}} +
+
+
+
+
+
+
+
+ +
+
+
+
+
+

How does this work?

+

This Ether faucet is running on the {{.Network}} network. To prevent malicious actors from exhausting all available funds or accumulating enough Ether to mount long running spam attacks, requests are tied to common 3rd party social network accounts. Anyone having a Twitter or Facebook account may request funds within the permitted limits.

+
+
+
To request funds via Twitter, make a tweet with your Ethereum address pasted into the contents (surrounding text doesn't matter).
Copy-paste the tweets URL into the above input box and fire away!
+ +
+
To request funds via Facebook, publish a new public post with your Ethereum address embedded into the content (surrounding text doesn't matter).
Copy-paste the posts URL into the above input box and fire away!
+ + {{if .NoAuth}} +
+
To request funds without authentication, simply copy-paste your Ethereum address into the above input box (surrounding text doesn't matter) and fire away.
This mode is susceptible to Byzantine attacks. Only use for debugging or private networks!
+ {{end}} +
+

You can track the current pending requests below the input field to see how much you have to wait until your turn comes.

+ {{if .Recaptcha}}The faucet is running invisible reCaptcha protection against bots.{{end}} +
+
+
+
+ + {{if .Recaptcha}} + {{end}} + + diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/faucet/website.go b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/website.go new file mode 100644 index 00000000..a091d249 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/faucet/website.go @@ -0,0 +1,271 @@ +// Code generated by go-bindata. DO NOT EDIT. +// sources: +// faucet.html (11.27kB) + +package main + +import ( + "bytes" + "compress/gzip" + "crypto/sha256" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo + digest [sha256.Size]byte +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x6d\x93\xdb\x36\x92\xfe\x3c\xfe\x15\x1d\x9e\xbd\x92\xce\x43\x52\x33\x63\x7b\x7d\x12\xa9\x94\xd7\x9b\xdd\xf3\xd5\x5d\x92\x4a\x9c\xba\xdb\xca\xa6\xae\x40\xb2\x25\xc2\x03\x02\x0c\x00\x4a\xa3\x4c\xe9\xbf\x5f\x35\x40\x52\xd4\xcb\x4c\xec\xb5\xaf\x6a\xfd\x61\x4c\x02\x8d\x46\xa3\xfb\x69\xf4\x0b\x95\x7c\xf5\xe7\xef\xde\xbe\xff\xdb\xf7\xdf\x40\x69\x2b\xb1\x78\x92\xd0\x7f\x20\x98\x5c\xa5\x01\xca\x60\xf1\xe4\x22\x29\x91\x15\x8b\x27\x17\x17\x49\x85\x96\x41\x5e\x32\x6d\xd0\xa6\x41\x63\x97\xe1\xeb\x60\x3f\x51\x5a\x5b\x87\xf8\x6b\xc3\xd7\x69\xf0\x3f\xe1\x4f\x6f\xc2\xb7\xaa\xaa\x99\xe5\x99\xc0\x00\x72\x25\x2d\x4a\x9b\x06\xef\xbe\x49\xb1\x58\xe1\x60\x9d\x64\x15\xa6\xc1\x9a\xe3\xa6\x56\xda\x0e\x48\x37\xbc\xb0\x65\x5a\xe0\x9a\xe7\x18\xba\x97\x4b\xe0\x92\x5b\xce\x44\x68\x72\x26\x30\xbd\x0a\x16\x4f\x88\x8f\xe5\x56\xe0\xe2\xfe\x3e\xfa\x16\xed\x46\xe9\xdb\xdd\x6e\x06\x6f\x1a\x5b\xa2\xb4\x3c\x67\x16\x0b\xf8\x0b\x6b\x72\xb4\x49\xec\x29\xdd\x22\xc1\xe5\x2d\x94\x1a\x97\x69\x40\xa2\x9b\x59\x1c\xe7\x85\xfc\x60\xa2\x5c\xa8\xa6\x58\x0a\xa6\x31\xca\x55\x15\xb3\x0f\xec\x2e\x16\x3c\x33\xb1\xdd\x70\x6b\x51\x87\x99\x52\xd6\x58\xcd\xea\xf8\x26\xba\x89\xfe\x18\xe7\xc6\xc4\xfd\x58\x54\x71\x19\xe5\xc6\x04\xa0\x51\xa4\x81\xb1\x5b\x81\xa6\x44\xb4\x01\xc4\x8b\x7f\x6c\xdf\xa5\x92\x36\x64\x1b\x34\xaa\xc2\xf8\x45\xf4\xc7\x68\xea\xb6\x1c\x0e\x3f\xbe\x2b\x6d\x6b\x72\xcd\x6b\x0b\x46\xe7\x1f\xbd\xef\x87\x5f\x1b\xd4\xdb\xf8\x26\xba\x8a\xae\xda\x17\xb7\xcf\x07\x13\x2c\x92\xd8\x33\x5c\x7c\x16\xef\x50\x2a\xbb\x8d\xaf\xa3\x17\xd1\x55\x5c\xb3\xfc\x96\xad\xb0\xe8\x76\xa2\xa9\xa8\x1b\xfc\x62\xfb\x3e\x64\xc3\x0f\xc7\x26\xfc\x12\x9b\x55\xaa\x42\x69\xa3\x0f\x26\xbe\x8e\xae\x5e\x47\xd3\x6e\xe0\x94\xbf\xdb\x80\x8c\x46\x5b\x5d\x44\x6b\xd4\x84\x5c\x11\xe6\x28\x2d\x6a\xb8\xa7\xd1\x8b\x8a\xcb\xb0\x44\xbe\x2a\xed\x0c\xae\xa6\xd3\x67\xf3\x73\xa3\xeb\xd2\x0f\x17\xdc\xd4\x82\x6d\x67\xb0\x14\x78\xe7\x87\x98\xe0\x2b\x19\x72\x8b\x95\x99\x81\xe7\xec\x26\x76\x6e\xcf\x5a\xab\x95\x46\x63\xda\xcd\x6a\x65\xb8\xe5\x4a\xce\x08\x51\xcc\xf2\x35\x9e\xa3\x35\x35\x93\x27\x0b\x58\x66\x94\x68\x2c\x1e\x09\x92\x09\x95\xdf\xfa\x31\xe7\xcd\xc3\x43\xe4\x4a\x28\x3d\x83\x4d\xc9\xdb\x65\xe0\x36\x82\x5a\x63\xcb\x1e\x6a\x56\x14\x5c\xae\x66\xf0\xaa\x6e\xcf\x03\x15\xd3\x2b\x2e\x67\x30\xdd\x2f\x49\xe2\x4e\x8d\x49\xec\x2f\xae\x27\x17\x49\xa6\x8a\xad\xb3\x61\xc1\xd7\x90\x0b\x66\x4c\x1a\x1c\xa9\xd8\x5d\x48\x07\x04\x74\x0f\x31\x2e\xbb\xa9\x83\x39\xad\x36\x01\xb8\x8d\xd2\xc0\x0b\x11\x66\xca\x5a\x55\xcd\xe0\x8a\xc4\x6b\x97\x1c\xf1\x13\xa1\x58\x85\x57\xd7\xdd\xe4\x45\x52\x5e\x75\x4c\x2c\xde\xd9\xd0\xd9\xa7\xb7\x4c\xb0\x48\x78\xb7\x76\xc9\x60\xc9\xc2\x8c\xd9\x32\x00\xa6\x39\x0b\x4b\x5e\x14\x28\xd3\xc0\xea\x06\x09\x47\x7c\x01\xc3\xeb\xef\x81\xdb\xaf\xbc\xea\xe4\x8a\x0b\xbe\x6e\x8f\x35\x78\x3c\x3a\xe1\xc3\x87\x78\x0d\xed\x83\x5a\x2e\x0d\xda\x70\x70\xa6\x01\x31\x97\x75\x63\xc3\x95\x56\x4d\xdd\xcf\x5f\x24\x6e\x14\x78\x91\x06\x8d\x16\x41\x7b\xfd\xbb\x47\xbb\xad\x5b\x55\x04\xfd\xc1\x95\xae\x42\xb2\x84\x56\x22\x80\x5a\xb0\x1c\x4b\x25\x0a\xd4\x69\xf0\xa3\xca\x39\x13\x20\xfd\x99\xe1\xa7\x1f\xfe\x13\x5a\x93\x71\xb9\x82\xad\x6a\x34\x7c\x63\x4b\xd4\xd8\x54\xc0\x8a\x82\xe0\x1a\x45\xd1\x40\x10\x87\xdd\x53\x51\xc3\xcc\xca\x3d\xd5\x45\x92\x35\xd6\xaa\x9e\x30\xb3\x12\x32\x2b\xc3\x02\x97\xac\x11\x16\x0a\xad\xea\x42\x6d\x64\x68\xd5\x6a\x45\x91\xce\x1f\xc2\x2f\x0a\xa0\x60\x96\xb5\x53\x69\xd0\xd1\x76\x36\x64\xa6\x56\x75\x53\xb7\x56\xf4\x83\x78\x57\x33\x59\x60\x41\x36\x17\x06\x83\xc5\x5f\xf9\x1a\xa1\x42\x7f\x96\x8b\x63\x48\xe4\x4c\xa3\x0d\x87\x4c\x4f\x80\x91\xc4\x5e\x18\x7f\x24\x68\xff\x25\x8d\xe8\x38\xf5\x47\xa8\x50\x36\x70\xf0\x16\x6a\xba\x57\x82\xc5\xfd\xbd\x66\x72\x85\xf0\x94\x17\x77\x97\xf0\x94\x55\xaa\x91\x16\x66\x29\x44\x6f\xdc\xa3\xd9\xed\x0e\xb8\x03\x24\x82\x2f\x12\xf6\x18\xbc\x41\xc9\x5c\xf0\xfc\x36\x0d\x2c\x47\x9d\xde\xdf\x13\xf3\xdd\x6e\x0e\xf7\xf7\x7c\x09\x4f\xa3\x1f\x30\x67\xb5\xcd\x4b\xb6\xdb\xad\x74\xf7\x1c\xe1\x1d\xe6\x8d\xc5\xf1\xe4\xfe\x1e\x85\xc1\xdd\xce\x34\x59\xc5\xed\xb8\x5b\x4e\xe3\xb2\xd8\xed\x48\xe6\x56\xce\xdd\x0e\x62\x62\x2a\x0b\xbc\x83\xa7\xd1\xf7\xa8\xb9\x2a\x0c\x78\xfa\x24\x66\x8b\x24\x16\x7c\xd1\xae\x3b\x54\x52\xdc\x88\x3d\x5e\x62\x02\x4c\x8f\x73\xe7\x36\x4e\xd4\xa1\xa4\x67\xbc\x60\x15\xf6\xd2\xb7\x78\x30\xdc\xe2\x2d\x6e\xd3\xe0\xfe\x7e\xb8\xb6\x9d\xcd\x99\x10\x19\x23\xbd\xf8\xa3\xf5\x8b\x7e\x43\xc2\xe9\x9a\x1b\x97\x52\x2d\x3a\x09\xf6\x62\x7f\xa4\x5b\x1f\x5d\x5c\x56\xd5\x33\xb8\xb9\x1e\xdc\x5a\xe7\x3c\xfe\xd5\x91\xc7\xdf\x9c\x25\xae\x99\x44\x01\xee\x6f\x68\x2a\x26\xba\xe7\xd6\x5b\x06\xce\x77\xbc\x28\xa4\x3b\xba\x17\xad\xbf\xeb\xa7\x73\x50\x6b\xd4\x4b\xa1\x36\x33\x60\x8d\x55\x73\xa8\xd8\x5d\x1f\xef\x6e\xa6\xd3\xa1\xdc\x94\x0a\xb2\x4c\xa0\xbb\x5d\x34\xfe\xda\xa0\xb1\xa6\xbf\x4b\xfc\x94\xfb\x4b\x57\x4a\x81\xd2\x60\x71\xa4\x0d\xda\x91\x54\xeb\xa8\x06\xa6\xef\x95\x79\x56\xf6\xa5\x52\x7d\x08\x19\x8a\xd1\xb2\x1e\x44\xbb\x60\x91\x58\xbd\xa7\xbb\x48\x6c\xf1\x49\x21\x40\x53\x8a\xf7\x50\x04\xf0\x37\x1a\x9d\xbd\x46\xd4\x3e\xbf\x20\xc8\x82\x7b\x4d\x62\x5b\x7c\xc6\xce\x04\xc2\x8c\x19\xfc\x98\xed\x5d\xa4\xdf\x6f\xef\x5e\x3f\x77\xff\x12\x99\xb6\x19\x32\xfb\x31\x02\x2c\x1b\x59\x0c\xce\xef\xee\xce\xcf\x15\xa0\x91\x7c\x8d\xda\x70\xbb\xfd\x58\x09\xb0\xd8\x8b\xe0\xdf\x0f\x45\x48\x62\xab\x1f\xc7\xda\xf0\xe5\x0b\x39\xf7\xef\xa5\x24\x37\x8b\x7f\x57\x1b\x28\x14\x1a\xb0\x25\x37\x40\xc1\xf5\xeb\x24\x2e\x6f\x7a\x92\x7a\xf1\x9e\x26\x9c\x52\x61\xe9\x52\x0b\xe0\x06\x74\x23\x5d\xe4\x55\x12\x6c\x89\x87\xe9\x48\x1b\xa4\x23\x78\xaf\x28\xa5\x5b\xa3\xb4\x50\x31\xc1\x73\xae\x1a\x03\x2c\xb7\x4a\x1b\x58\x6a\x55\x01\xde\x95\xac\x31\x96\x18\xd1\xf5\xc1\xd6\x8c\x0b\xe7\x4b\xce\xa4\xa0\x34\xb0\x3c\x6f\xaa\x86\x52\x52\xb9\x02\x94\xaa\x59\x95\xad\x2c\x56\x81\x0f\x4c\x42\xc9\x55\x2f\x8f\xa9\x59\x05\xcc\x5a\x96\xdf\x9a\x4b\xe8\x6e\x05\x60\x1a\xc1\x72\x2c\x68\x55\xae\xaa\x4a\x49\xb8\xd1\x05\xd4\x4c\xdb\x2d\x98\xc3\xdc\x82\xe5\xb9\x8b\x72\x11\xbc\x91\x5b\x25\x11\x4a\xb6\x76\x12\xc2\x7b\x5f\x4e\x90\x5c\x7f\x61\x39\x66\x4a\xf5\xd4\x50\xb1\x6d\xb7\x5d\x2b\xfd\x86\xdb\x92\x7b\xf5\xd4\xa8\x2b\x5a\x5a\x80\xe0\x15\xb7\x26\x4a\xe2\x7a\x7f\xa3\xee\x63\xb3\x08\x4b\xa5\xf9\x6f\x94\xd8\x88\xe1\xf5\x69\x8f\x2e\x97\xee\x6e\x74\x56\x17\xb8\xb4\x33\x78\xe1\xef\xc6\x63\x1c\xb7\x15\xd0\x39\x10\x77\x3c\x5d\x65\x49\x01\x67\x06\x37\x3e\x9d\xf5\x89\x44\x61\x07\x12\x14\x47\x50\xf3\x9b\xbe\x7e\x5d\xdf\xf5\x72\xf4\x39\xf1\xb4\x67\x42\x08\x38\x54\xca\x9a\xf7\x6a\xbc\x84\x8a\xdd\x22\x30\x48\xd8\x51\x85\xdc\x0a\xed\xea\x2b\xee\xfa\x03\xb1\xdd\x20\xda\xaf\xc9\x75\xd3\x1f\x3c\x43\x2e\x57\xcf\xae\xa7\x1e\x91\xf4\x40\xec\x9f\x5d\x4f\xb9\xb4\xea\xd9\xf5\x74\x7a\x37\xfd\xc8\x7f\xcf\xae\xa7\x4a\x3e\xbb\x9e\xda\x12\x9f\x5d\x4f\x9f\x5d\xdf\x0c\xb1\xec\x47\xba\xcc\x92\xa8\xd0\xd0\x6e\x1d\xc4\x03\xb0\x4c\xaf\xd0\xa6\xc1\xff\xb2\x4c\x35\x76\x96\x09\x26\x6f\x83\x85\x13\x97\xb2\x0d\x87\x82\xf3\xf9\x29\xd4\xcc\x10\x24\x48\x62\x87\x92\xb6\x17\x62\x60\x6c\x1a\xad\x55\x23\x29\x2a\x02\x9d\xd9\x79\xa8\x1c\x11\xca\x48\x31\x93\x28\xc9\x74\xbc\x78\xab\xea\x6d\xe8\x98\xb8\xe5\x27\x6a\x34\x4d\x5d\x2b\x6d\xa3\xa1\x3a\x19\xd5\x41\x02\x4d\xfc\x7a\xfa\xf2\xf5\xab\x47\xc5\x37\x94\x65\xbb\x33\xf4\x12\xb2\x4c\xad\x11\x7c\x4e\x9f\xa9\x3b\x60\xb2\x80\x25\xd7\x08\x6c\xc3\xb6\x5f\x25\x71\xe1\x2a\xb0\xcf\x47\xed\xb2\xf5\xae\x7f\x2a\xd8\x76\x2e\x7f\x09\x75\x93\x09\x6e\x4a\x60\x20\x71\x03\x89\xb1\x5a\xc9\xd5\xc2\x8d\xe6\x54\x92\xba\x57\xa8\x95\xb1\x8f\x99\x1f\xab\x0c\x8b\xe2\x0c\x00\xbe\x94\xfd\x37\x9b\x4d\xd4\x69\xd2\x19\xbf\x44\x51\xc7\x74\xfd\x35\x92\xdb\x6d\xec\xdd\x48\xc9\xf8\x6b\x5e\xa4\xd7\xaf\xaf\x5f\xbd\xba\x7e\xf1\x6f\xaf\x5f\xbe\xbc\x7e\xfd\xe2\xe5\x43\xc8\xa0\x43\x7d\x26\x30\x7c\x1a\xfd\xad\xa2\xaa\xb5\xcf\xa1\x3d\x5e\xba\xdc\x8d\x22\x74\x41\x35\x88\x0e\xfe\x61\x0c\x35\x92\x12\x91\x90\x89\xb3\x39\xc4\x27\xa0\xc8\xc1\xe8\x11\xc9\x3e\x13\x5a\x1d\x7c\x08\x29\xaa\xb1\x74\xc2\xae\x98\xe7\x4a\xf6\x70\xba\x04\xc3\xab\x5a\x6c\x21\xdf\x5b\xfd\x3c\xae\x1e\x34\xca\xef\xc2\xea\xd0\x6c\x1e\x64\x2e\xfa\x57\xaa\x40\x8a\xfa\xa6\x31\x39\xd6\xae\xcb\x4b\x91\xf4\x4f\xdb\xdf\x98\xb4\x5c\x62\x17\x71\x23\xf8\x4e\x8a\x2d\x34\x06\x61\xa9\x34\x14\x98\x35\xab\x95\x4b\x13\x34\xd4\x9a\xaf\x99\xc5\x2e\xcc\x9a\x16\x15\x3d\x28\x06\x95\x0d\xa5\x3c\x62\x90\x81\xfc\x4d\x35\x90\x33\x09\x56\xb3\xfc\xd6\x7b\x4a\xa3\x35\x79\x4a\x8d\xfe\x34\x7d\xa0\xcf\x50\xa8\x8d\x23\xf1\xe7\x5e\x72\x14\x2e\xea\x1b\x44\x28\xd5\x06\xaa\x26\x77\x0e\x49\x51\xdd\x1d\x62\xc3\xb8\x85\x46\x5a\x2e\xbc\x3e\x6d\xa3\x25\xe5\x08\x78\x10\xa5\x4f\x6a\xbf\x04\xab\xc5\xfb\x12\xcf\xa4\x44\x7d\xd5\x06\x1a\xdf\x7a\x72\xa8\xb5\xb2\x98\x93\x41\x81\xad\x18\x97\x86\x2c\xe2\xf2\x00\xac\x3e\xa2\xaa\xeb\x9f\xda\x87\x7d\x87\xd2\x4d\xc7\x31\xfc\x55\xa8\x8c\x09\x58\x13\xd2\x33\x41\xe9\x9c\x82\x52\xd1\xd1\x07\xda\x32\x96\xd9\xc6\x80\x5a\xba\x51\x2f\x39\xad\x5f\x33\x4d\x16\xc4\xaa\xb6\x90\xb6\xfd\x35\x1a\x33\xa8\xd7\x6d\xd7\x90\x5e\xa9\x72\x3f\x98\xef\xb5\x9e\xc2\xcf\xbf\xcc\x9f\xb4\xa2\xfc\x19\x97\x0e\x12\x84\x6f\x7f\x64\x5b\x32\x0b\xb9\x46\x66\xd1\x40\x2e\x94\x69\xb4\x97\xb0\xd0\xaa\x06\x92\xb2\xe3\xd4\x71\xa6\x89\xda\xed\xd6\x31\x19\x97\xcc\x94\x93\xb6\x3d\xa8\xd1\x59\xa9\x9f\xeb\xc6\x2f\x08\x75\x63\x62\xc0\xd3\xe9\x1c\x78\xd2\xf1\x8d\x04\xca\x95\x2d\xe7\xc0\x9f\x3f\xef\x89\x2f\xf8\x12\xc6\x1d\xc5\xcf\xfc\x97\xc8\xde\x45\xb4\x0b\xa4\x29\x0c\x77\x73\x1b\xb6\x7c\x4c\x2d\x78\x8e\x63\x7e\x09\x57\x93\x79\x37\x9b\x69\x64\xb7\xdd\x5b\x6b\x47\xff\x9f\xfb\xbb\x9b\x1f\x6a\xc6\x29\xff\x40\x37\xbe\xf6\x37\xc0\x60\xc5\x8d\x85\x46\x0b\x68\x7d\xd8\x9b\xa0\x37\x88\xa3\x1b\x6a\xe5\x04\x97\xed\x43\x8b\xa9\xee\x08\x9e\x4d\x64\x50\x16\xe3\xff\xf8\xf1\xbb\x6f\x23\x63\x35\x97\x2b\xbe\xdc\x8e\xef\x1b\x2d\x66\xf0\x74\x1c\xfc\x4b\xa3\x45\x30\xf9\x79\xfa\x4b\xb4\x66\xa2\xc1\x4b\x67\xef\x99\xfb\x7b\xb2\xcb\x25\xb4\x8f\x33\x38\xdc\x70\x37\x99\xcc\xcf\xf7\x49\x06\x6d\x1d\x8d\x06\xed\x98\x08\x7b\xe0\x1f\xeb\x88\x41\x85\xb6\x54\xce\x75\x35\xe6\x4a\x4a\xcc\x2d\x34\xb5\x92\xad\x4a\x40\x28\x63\xf6\x40\xec\x28\xd2\x53\x50\xb4\xf4\xa9\x0b\xd6\xff\x8d\xd9\x8f\x2a\xbf\x45\x3b\x1e\x8f\x37\x5c\x16\x6a\x13\x09\xe5\xaf\xda\x88\x9c\x54\xe5\x4a\x40\x9a\xa6\xd0\x46\xd1\x60\x02\x5f\x43\xb0\x31\x14\x4f\x03\x98\xd1\x23\x3d\x4d\xe0\x39\x1c\x2f\x2f\x29\xde\x3f\x87\x20\x66\x35\x0f\x26\xde\x1d\x3a\xc5\x2b\x59\xa1\x31\x6c\x85\x43\x01\x5d\x65\xd4\x83\x8c\xce\x51\x99\x15\xa4\xe0\x0c\x54\x33\x6d\xd0\x93\x44\x54\x8d\x77\x68\x23\xcc\x3a\xb2\x34\x05\xd9\x08\xb1\x07\xa9\x77\x8a\x79\x07\xbf\x03\xf2\xc8\xc7\x9a\xaf\xd2\x14\xa8\x34\x25\x15\x17\xfb\x95\x64\x7c\x5f\x44\x4f\x22\x8a\x0b\xfb\x15\x93\xf9\x10\xcd\x07\xdc\xb0\xf8\x3d\x76\x58\x1c\xf3\xc3\xe2\x01\x86\xae\x67\xf1\x18\x3f\xdf\xe3\x18\xb0\x73\x03\x0f\x70\x93\x4d\x95\xa1\x7e\x8c\x9d\xef\x59\xb4\xec\x9c\xaa\xdf\x49\x3b\x58\x7b\x09\x57\xaf\x26\x0f\x70\x47\xad\xd5\x83\xcc\xa5\xb2\xdb\xf1\xbd\x60\x5b\xca\x99\x60\x64\x55\xfd\xd6\xb5\x18\x46\x97\x2e\xe2\xce\xa0\xe7\x70\xe9\x9a\xc7\x33\x18\xb9\x37\x9a\xe7\x15\xba\x55\x2f\xa7\xd3\xe9\x25\x74\x5f\x5d\xfe\xc4\xc8\x09\x75\x83\xbb\x07\xe4\x31\x4d\x9e\x53\xdc\xff\x1c\x89\x5a\x1e\xbd\x4c\xed\xfb\x67\x48\xd5\xc7\x86\x03\xb1\xe0\x0f\x7f\x80\x93\xd9\x43\x18\xc7\x31\xfc\x17\xa3\x32\x5c\x08\xd7\x3d\x70\x4d\x83\x9e\xbe\xe2\xc6\xb8\x62\xdc\x40\xa1\x24\xb6\x6b\x3e\xed\xda\x3f\x91\xb1\x25\x83\x05\x4c\x8f\x05\xa4\xeb\x70\x10\x16\xce\x44\x8b\x01\xdf\xc3\x40\x70\xb1\x1b\xee\x77\xb0\x92\x57\x08\x5f\xa5\x10\x04\xc3\xc5\x27\x14\x44\xd0\x33\xbb\x30\x68\xdf\x7b\x5b\x8c\xdb\xe8\x78\x2e\x76\x4d\x2e\xe1\x66\x3a\x9d\x4e\x4e\x84\xd8\xed\xd5\xfb\xa6\xa6\xb4\x09\x98\xdc\xba\x2b\xb1\xd7\xad\x4b\x1c\x29\x05\xa2\x2b\x4d\x40\xae\x84\xf0\x39\x4b\xbb\x94\x14\xdc\x36\x4f\x52\x08\xaf\xe6\x67\xa2\xe8\x40\x93\x83\xa3\x1d\x9b\xe7\x8c\xee\x8f\x4d\x74\xa8\xb3\x23\xe2\xf0\xea\xc0\x28\x07\xf6\x3a\x6f\x98\x8b\x5e\x6e\xbe\xd7\xe8\x91\xb9\xf6\xf6\x3a\xd6\xd9\x40\x7e\xcf\xe7\xf9\xd5\x47\x1e\xa3\x9f\xae\x1b\x53\x8e\x8f\x04\x9d\xcc\x4f\x6d\xf3\xce\xa2\xa6\x2c\x59\x51\xc8\x22\x5b\x50\x29\xa0\xf1\xc4\x24\x2e\x55\xd7\x18\x6a\x94\x05\xea\x2e\xa5\xf0\x99\x3d\x25\x80\x07\x26\xf3\x55\xe5\x10\x4e\x9f\xe8\x30\x2e\x25\x53\x12\x01\x00\x8e\x9c\xc0\x01\xf5\x00\xa9\x44\x8c\x82\xd5\x06\x0b\x48\xc1\x7f\x04\x1f\x4f\xa2\x46\xf2\xbb\xf1\x24\x6c\xdf\x8f\x79\x74\xf3\xf3\xbe\x4c\xec\xc4\x7e\x9e\x42\x90\x58\x0d\xbc\x48\x47\x01\x3c\x3f\xe7\x82\x14\x75\x47\x8b\xbd\x04\xc3\xa5\x00\x89\x2d\x16\xae\x0f\xea\xeb\xb5\xbf\x07\x19\xcb\x6f\x57\xae\x10\x9a\x51\xaa\x35\x3e\x61\xcb\xd6\xcc\x32\xed\xb8\x4e\xe6\xb0\x27\x6f\x0b\xc5\x9c\x8c\x33\x07\x5f\x91\xba\x76\x2b\xf4\x9f\x28\xdc\x5b\xa6\x74\x81\x3a\xd4\xac\xe0\x8d\x99\xc1\x8b\xfa\x6e\xfe\xf7\xee\x13\x8e\x6b\x0a\x3f\x2a\x6a\xad\x71\x71\x22\x51\xdb\x65\x7c\x0e\x41\x12\x13\xc1\xef\xb1\xe9\x0f\x3b\xfc\xf8\x0e\x67\x5a\xdf\xd0\x7f\x1a\x6f\xc7\x2b\x5e\x14\x02\x49\xe0\x3d\x7b\x72\x46\xb2\xff\xd0\xa5\x0e\xb7\x84\xb6\xe7\xbd\x5f\xb3\x03\x14\x06\x1f\x59\xd0\xb7\xcf\x47\x04\x80\x90\x8e\xcc\x9d\xce\xdb\x62\xdb\x0d\xeb\x91\xd3\x45\xfb\x53\x8a\xa2\xd1\x2e\xd7\x1a\x87\x2d\xc0\x2e\x61\x64\x28\xf7\x2b\xcc\x68\x12\x95\x4d\xc5\x24\xff\x0d\xc7\x14\x97\x26\x5e\x57\xae\x1f\x1f\x9c\x5e\xc9\x27\xc2\xec\x1b\xe5\xa3\x2e\xc6\x8d\x5a\x25\x8e\x3a\xeb\xbe\xd8\xd7\xf6\x33\x98\xce\x47\x9f\xa8\xa1\xf3\xbb\x84\x19\xd3\x30\x7c\x09\xbb\xe0\x0b\x5a\xd1\xee\xdd\x5c\xc6\xf4\xc8\x77\x32\x5c\x7e\x2e\xd5\x26\x1d\xdd\x4c\x7b\x21\xbd\xa1\x9d\x9d\x47\x2d\xd6\x4e\x8c\x41\x52\x76\xae\xb9\x80\x9b\xe9\x97\x90\xd6\x77\x43\x8e\x4e\x60\x35\xaf\xb1\x00\x96\x5b\xbe\xc6\xff\x87\x83\x7c\x01\x25\x7f\xb2\x88\x84\xc3\x4e\x79\x0e\xa6\x07\xf2\xd2\x6c\xaf\xdb\x7f\x25\x7f\x83\xd8\x69\xf8\x39\x04\x67\x0f\xf2\x20\x12\x8f\x08\x8f\x5c\xfb\x61\xbf\x77\x1f\x98\x82\xe3\x98\x42\xd9\x6e\xff\x71\x74\x12\x95\xb6\x12\xe3\x20\xb1\xee\x47\x32\x24\x73\xcf\xc1\x31\xf0\xc3\x87\x29\xdd\xee\xb0\x90\xa1\xfa\x1d\x8f\xea\x2c\x18\x24\x27\x7d\x2d\xd6\x65\x22\xb0\xdb\xff\x96\x28\x8e\xe1\x47\xcb\xb4\x05\x06\x3f\xbd\x83\xa6\x2e\x98\xf5\x9f\x72\x28\x3e\xfa\x4f\x25\xdd\x8f\x8d\x32\xa6\x0d\x2c\x95\xde\x30\x5d\xb4\xfd\x19\x5b\xe2\xd6\x7d\xca\xe9\x52\x3f\x83\xf6\x1d\xdd\x62\x6b\x26\xc6\x27\x75\xdf\xd3\xf1\x28\x1a\x9a\x7c\x34\x89\x90\xe5\xe5\x29\xa1\x8b\x58\xfd\xbe\x29\x7c\xeb\x4a\x80\xf1\xd3\xb1\x2d\xb9\x99\x44\xcc\x5a\x3d\x1e\x1d\x80\x61\x34\x21\xbb\x5e\x0d\x4a\xb2\x7e\x79\x72\xe0\x56\x8f\xf1\xd8\x27\xd3\x7d\x22\xd0\x91\xe7\xc6\x8c\x3d\xae\x46\x97\x03\xde\x87\xb0\x1a\x3d\x1b\xf5\x86\xda\xbb\xf7\xfe\x1c\xe9\x59\x49\x0e\x58\x8f\xc8\xcb\x46\x27\xdb\xb3\xa2\x78\x4b\xfe\x33\x0e\xce\x78\xfa\x31\x3a\x26\xbd\xb2\xfd\x7d\xfd\xa8\x96\xfd\xcf\x32\x1e\x50\x31\x2f\x46\x93\xc8\x34\x99\xef\x4d\x8c\x5f\xf6\x05\x58\x47\xe6\xc0\x7b\x1c\x0a\x4e\x12\x0a\xda\xe2\x30\xa9\x08\x8f\x92\x90\x47\xa2\x46\xbb\xa5\x3f\xd5\xee\x92\x14\x3e\x9d\xf4\xad\xad\x6f\x0c\x25\x57\xbe\xf5\xbf\xc1\xcc\xb8\x4e\x02\xb4\x78\x77\xdd\x1c\xdf\xb5\x79\xf3\xfd\xbb\x41\xe7\xa6\xf7\x88\xb1\xe3\xde\xff\x0e\xf0\x5c\x9f\xe4\xec\x0f\x0f\x37\x9b\x4d\xb4\x52\x6a\x25\xfc\x4f\x0e\xfb\x46\x4a\xcc\x6a\x1e\x7d\x30\x01\x30\xb3\x95\x39\x14\xb8\x44\xbd\x18\xb0\x6f\xbb\x2b\x49\xec\x7f\x12\x97\xc4\xfe\x57\xbf\xff\x17\x00\x00\xff\xff\x31\x9f\x54\x5e\x06\x2c\x00\x00") + +func faucetHtmlBytes() ([]byte, error) { + return bindataRead( + _faucetHtml, + "faucet.html", + ) +} + +func faucetHtml() (*asset, error) { + bytes, err := faucetHtmlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "faucet.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdb, 0xa2, 0x98, 0x44, 0x4b, 0x50, 0xf8, 0xa1, 0xac, 0x4a, 0x76, 0x2e, 0xcc, 0x3d, 0xcb, 0x81, 0x9e, 0x2a, 0xaa, 0x87, 0xf5, 0x9d, 0x53, 0x4, 0x8a, 0xdd, 0x5a, 0xfe, 0xd3, 0xc3, 0xf, 0x11}} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "faucet.html": faucetHtml, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "faucet.html": {faucetHtml, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory. +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) +} + +// RestoreAssets restores an asset under the given directory recursively. +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/accountcmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/accountcmd.go new file mode 100644 index 00000000..8fd149ca --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/accountcmd.go @@ -0,0 +1,385 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "fmt" + "io/ioutil" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "gopkg.in/urfave/cli.v1" +) + +var ( + walletCommand = cli.Command{ + Name: "wallet", + Usage: "Manage Ethereum presale wallets", + ArgsUsage: "", + Category: "ACCOUNT COMMANDS", + Description: ` + geth wallet import /path/to/my/presale.wallet + +will prompt for your password and imports your ether presale account. +It can be used non-interactively with the --password option taking a +passwordfile as argument containing the wallet password in plaintext.`, + Subcommands: []cli.Command{ + { + + Name: "import", + Usage: "Import Ethereum presale wallet", + ArgsUsage: "", + Action: utils.MigrateFlags(importWallet), + Category: "ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + Description: ` + geth wallet [options] /path/to/my/presale.wallet + +will prompt for your password and imports your ether presale account. +It can be used non-interactively with the --password option taking a +passwordfile as argument containing the wallet password in plaintext.`, + }, + }, + } + + accountCommand = cli.Command{ + Name: "account", + Usage: "Manage accounts", + Category: "ACCOUNT COMMANDS", + Description: ` + +Manage accounts, list all existing accounts, import a private key into a new +account, create a new account or update an existing account. + +It supports interactive mode, when you are prompted for password as well as +non-interactive mode where passwords are supplied via a given password file. +Non-interactive mode is only meant for scripted use on test networks or known +safe environments. + +Make sure you remember the password you gave when creating a new account (with +either new or import). Without it you are not able to unlock your account. + +Note that exporting your key in unencrypted format is NOT supported. + +Keys are stored under /keystore. +It is safe to transfer the entire directory or the individual keys therein +between ethereum nodes by simply copying. + +Make sure you backup your keys regularly.`, + Subcommands: []cli.Command{ + { + Name: "list", + Usage: "Print summary of existing accounts", + Action: utils.MigrateFlags(accountList), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + }, + Description: ` +Print a short summary of all accounts`, + }, + { + Name: "new", + Usage: "Create a new account", + Action: utils.MigrateFlags(accountCreate), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + Description: ` + geth account new + +Creates a new account and prints the address. + +The account is saved in encrypted format, you are prompted for a passphrase. + +You must remember this passphrase to unlock your account in the future. + +For non-interactive use the passphrase can be specified with the --password flag: + +Note, this is meant to be used for testing only, it is a bad idea to save your +password to file or expose in any other way. +`, + }, + { + Name: "update", + Usage: "Update an existing account", + Action: utils.MigrateFlags(accountUpdate), + ArgsUsage: "
", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.LightKDFFlag, + }, + Description: ` + geth account update
+ +Update an existing account. + +The account is saved in the newest version in encrypted format, you are prompted +for a passphrase to unlock the account and another to save the updated file. + +This same command can therefore be used to migrate an account of a deprecated +format to the newest format or change the password for an account. + +For non-interactive use the passphrase can be specified with the --password flag: + + geth account update [options]
+ +Since only one password can be given, only format update can be performed, +changing your password is only possible interactively. +`, + }, + { + Name: "import", + Usage: "Import a private key into a new account", + Action: utils.MigrateFlags(accountImport), + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.KeyStoreDirFlag, + utils.PasswordFileFlag, + utils.LightKDFFlag, + }, + ArgsUsage: "", + Description: ` + geth account import + +Imports an unencrypted private key from and creates a new account. +Prints the address. + +The keyfile is assumed to contain an unencrypted private key in hexadecimal format. + +The account is saved in encrypted format, you are prompted for a passphrase. + +You must remember this passphrase to unlock your account in the future. + +For non-interactive use the passphrase can be specified with the -password flag: + + geth account import [options] + +Note: +As you can directly copy your encrypted accounts to another ethereum instance, +this import mechanism is not needed when you transfer an account between +nodes. +`, + }, + }, + } +) + +func accountList(ctx *cli.Context) error { + stack, _ := makeConfigNode(ctx) + var index int + for _, wallet := range stack.AccountManager().Wallets() { + for _, account := range wallet.Accounts() { + fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL) + index++ + } + } + return nil +} + +// tries unlocking the specified account a few times. +func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) { + account, err := utils.MakeAddress(ks, address) + if err != nil { + utils.Fatalf("Could not list accounts: %v", err) + } + for trials := 0; trials < 3; trials++ { + prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3) + password := getPassPhrase(prompt, false, i, passwords) + err = ks.Unlock(account, password) + if err == nil { + log.Info("Unlocked account", "address", account.Address.Hex()) + return account, password + } + if err, ok := err.(*keystore.AmbiguousAddrError); ok { + log.Info("Unlocked account", "address", account.Address.Hex()) + return ambiguousAddrRecovery(ks, err, password), password + } + if err != keystore.ErrDecrypt { + // No need to prompt again if the error is not decryption-related. + break + } + } + // All trials expended to unlock account, bail out + utils.Fatalf("Failed to unlock account %s (%v)", address, err) + + return accounts.Account{}, "" +} + +// getPassPhrase retrieves the password associated with an account, either fetched +// from a list of preloaded passphrases, or requested interactively from the user. +func getPassPhrase(prompt string, confirmation bool, i int, passwords []string) string { + // If a list of passwords was supplied, retrieve from them + if len(passwords) > 0 { + if i < len(passwords) { + return passwords[i] + } + return passwords[len(passwords)-1] + } + // Otherwise prompt the user for the password + if prompt != "" { + fmt.Println(prompt) + } + password, err := console.Stdin.PromptPassword("Passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase: %v", err) + } + if confirmation { + confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase confirmation: %v", err) + } + if password != confirm { + utils.Fatalf("Passphrases do not match") + } + } + return password +} + +func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account { + fmt.Printf("Multiple key files exist for address %x:\n", err.Addr) + for _, a := range err.Matches { + fmt.Println(" ", a.URL) + } + fmt.Println("Testing your passphrase against all of them...") + var match *accounts.Account + for _, a := range err.Matches { + if err := ks.Unlock(a, auth); err == nil { + match = &a + break + } + } + if match == nil { + utils.Fatalf("None of the listed files could be unlocked.") + } + fmt.Printf("Your passphrase unlocked %s\n", match.URL) + fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:") + for _, a := range err.Matches { + if a != *match { + fmt.Println(" ", a.URL) + } + } + return *match +} + +// accountCreate creates a new account into the keystore defined by the CLI flags. +func accountCreate(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + scryptN, scryptP, keydir, err := cfg.Node.AccountConfig() + + if err != nil { + utils.Fatalf("Failed to read configuration: %v", err) + } + + password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) + + account, err := keystore.StoreKey(keydir, password, scryptN, scryptP) + + if err != nil { + utils.Fatalf("Failed to create account: %v", err) + } + fmt.Printf("\nYour new key was generated\n\n") + fmt.Printf("Public address of the key: %s\n", account.Address.Hex()) + fmt.Printf("Path of the secret key file: %s\n\n", account.URL.Path) + fmt.Printf("- You can share your public address with anyone. Others need it to interact with you.\n") + fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your funds!\n") + fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to access account funds!\n") + fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") + return nil +} + +// accountUpdate transitions an account from a previous format to the current +// one, also providing the possibility to change the pass-phrase. +func accountUpdate(ctx *cli.Context) error { + if len(ctx.Args()) == 0 { + utils.Fatalf("No accounts specified to update") + } + stack, _ := makeConfigNode(ctx) + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + + for _, addr := range ctx.Args() { + account, oldPassword := unlockAccount(ks, addr, 0, nil) + newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil) + if err := ks.Update(account, oldPassword, newPassword); err != nil { + utils.Fatalf("Could not update the account: %v", err) + } + } + return nil +} + +func importWallet(ctx *cli.Context) error { + keyfile := ctx.Args().First() + if len(keyfile) == 0 { + utils.Fatalf("keyfile must be given as argument") + } + keyJSON, err := ioutil.ReadFile(keyfile) + if err != nil { + utils.Fatalf("Could not read wallet file: %v", err) + } + + stack, _ := makeConfigNode(ctx) + passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) + + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + acct, err := ks.ImportPreSaleKey(keyJSON, passphrase) + if err != nil { + utils.Fatalf("%v", err) + } + fmt.Printf("Address: {%x}\n", acct.Address) + return nil +} + +func accountImport(ctx *cli.Context) error { + keyfile := ctx.Args().First() + if len(keyfile) == 0 { + utils.Fatalf("keyfile must be given as argument") + } + key, err := crypto.LoadECDSA(keyfile) + if err != nil { + utils.Fatalf("Failed to load the private key: %v", err) + } + stack, _ := makeConfigNode(ctx) + passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) + + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + acct, err := ks.ImportECDSA(key, passphrase) + if err != nil { + utils.Fatalf("Could not create the account: %v", err) + } + fmt.Printf("Address: {%x}\n", acct.Address) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/chaincmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/chaincmd.go new file mode 100644 index 00000000..c91545c7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/chaincmd.go @@ -0,0 +1,544 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "runtime" + "strconv" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie" + "gopkg.in/urfave/cli.v1" +) + +var ( + initCommand = cli.Command{ + Action: utils.MigrateFlags(initGenesis), + Name: "init", + Usage: "Bootstrap and initialize a new genesis block", + ArgsUsage: "", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +The init command initializes a new genesis block and definition for the network. +This is a destructive action and changes the network in which you will be +participating. + +It expects the genesis file as argument.`, + } + importCommand = cli.Command{ + Action: utils.MigrateFlags(importChain), + Name: "import", + Usage: "Import a blockchain file", + ArgsUsage: " ( ... ) ", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + utils.GCModeFlag, + utils.CacheDatabaseFlag, + utils.CacheGCFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +The import command imports blocks from an RLP-encoded form. The form can be one file +with several RLP-encoded blocks, or several files can be used. + +If only one file is used, import error will result in failure. If several files are used, +processing will proceed even if an individual RLP-file import failure occurs.`, + } + exportCommand = cli.Command{ + Action: utils.MigrateFlags(exportChain), + Name: "export", + Usage: "Export blockchain into file", + ArgsUsage: " [ ]", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +Requires a first argument of the file to write to. +Optional second and third arguments control the first and +last block to write. In this mode, the file will be appended +if already existing. If the file ends with .gz, the output will +be gzipped.`, + } + importPreimagesCommand = cli.Command{ + Action: utils.MigrateFlags(importPreimages), + Name: "import-preimages", + Usage: "Import the preimage database from an RLP stream", + ArgsUsage: "", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` + The import-preimages command imports hash preimages from an RLP encoded stream.`, + } + exportPreimagesCommand = cli.Command{ + Action: utils.MigrateFlags(exportPreimages), + Name: "export-preimages", + Usage: "Export the preimage database into an RLP stream", + ArgsUsage: "", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +The export-preimages command export hash preimages to an RLP encoded stream`, + } + copydbCommand = cli.Command{ + Action: utils.MigrateFlags(copyDb), + Name: "copydb", + Usage: "Create a local chain from a target chaindata folder", + ArgsUsage: "", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + utils.FakePoWFlag, + utils.TestnetFlag, + utils.RinkebyFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +The first argument must be the directory containing the blockchain to download from`, + } + removedbCommand = cli.Command{ + Action: utils.MigrateFlags(removeDB), + Name: "removedb", + Usage: "Remove blockchain and state databases", + ArgsUsage: " ", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +Remove blockchain and state databases`, + } + dumpCommand = cli.Command{ + Action: utils.MigrateFlags(dump), + Name: "dump", + Usage: "Dump a specific block from storage", + ArgsUsage: "[ | ]...", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.CacheFlag, + utils.SyncModeFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + Description: ` +The arguments are interpreted as block numbers or hashes. +Use "ethereum dump 0" to dump the genesis block.`, + } + inspectCommand = cli.Command{ + Action: utils.MigrateFlags(inspect), + Name: "inspect", + Usage: "Inspect the storage size for each type of data in the database", + ArgsUsage: " ", + Flags: []cli.Flag{ + utils.DataDirFlag, + utils.AncientFlag, + utils.CacheFlag, + utils.TestnetFlag, + utils.RinkebyFlag, + utils.GoerliFlag, + utils.SyncModeFlag, + }, + Category: "BLOCKCHAIN COMMANDS", + } +) + +// initGenesis will initialise the given JSON format genesis file and writes it as +// the zero'd block (i.e. genesis) or will fail hard if it can't succeed. +func initGenesis(ctx *cli.Context) error { + // Make sure we have a valid genesis JSON + genesisPath := ctx.Args().First() + if len(genesisPath) == 0 { + utils.Fatalf("Must supply path to genesis JSON file") + } + file, err := os.Open(genesisPath) + if err != nil { + utils.Fatalf("Failed to read genesis file: %v", err) + } + defer file.Close() + + genesis := new(core.Genesis) + if err := json.NewDecoder(file).Decode(genesis); err != nil { + utils.Fatalf("invalid genesis file: %v", err) + } + // Open an initialise both full and light databases + stack := makeFullNode(ctx) + defer stack.Close() + + for _, name := range []string{"chaindata", "lightchaindata"} { + chaindb, err := stack.OpenDatabase(name, 0, 0, "") + if err != nil { + utils.Fatalf("Failed to open database: %v", err) + } + _, hash, err := core.SetupGenesisBlock(chaindb, genesis) + if err != nil { + utils.Fatalf("Failed to write genesis block: %v", err) + } + chaindb.Close() + log.Info("Successfully wrote genesis state", "database", name, "hash", hash) + } + return nil +} + +func importChain(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + stack := makeFullNode(ctx) + defer stack.Close() + + chain, db := utils.MakeChain(ctx, stack) + defer db.Close() + + // Start periodically gathering memory profiles + var peakMemAlloc, peakMemSys uint64 + go func() { + stats := new(runtime.MemStats) + for { + runtime.ReadMemStats(stats) + if atomic.LoadUint64(&peakMemAlloc) < stats.Alloc { + atomic.StoreUint64(&peakMemAlloc, stats.Alloc) + } + if atomic.LoadUint64(&peakMemSys) < stats.Sys { + atomic.StoreUint64(&peakMemSys, stats.Sys) + } + time.Sleep(5 * time.Second) + } + }() + // Import the chain + start := time.Now() + + if len(ctx.Args()) == 1 { + if err := utils.ImportChain(chain, ctx.Args().First()); err != nil { + log.Error("Import error", "err", err) + } + } else { + for _, arg := range ctx.Args() { + if err := utils.ImportChain(chain, arg); err != nil { + log.Error("Import error", "file", arg, "err", err) + } + } + } + chain.Stop() + fmt.Printf("Import done in %v.\n\n", time.Since(start)) + + // Output pre-compaction stats mostly to see the import trashing + stats, err := db.Stat("leveldb.stats") + if err != nil { + utils.Fatalf("Failed to read database stats: %v", err) + } + fmt.Println(stats) + + ioStats, err := db.Stat("leveldb.iostats") + if err != nil { + utils.Fatalf("Failed to read database iostats: %v", err) + } + fmt.Println(ioStats) + + // Print the memory statistics used by the importing + mem := new(runtime.MemStats) + runtime.ReadMemStats(mem) + + fmt.Printf("Object memory: %.3f MB current, %.3f MB peak\n", float64(mem.Alloc)/1024/1024, float64(atomic.LoadUint64(&peakMemAlloc))/1024/1024) + fmt.Printf("System memory: %.3f MB current, %.3f MB peak\n", float64(mem.Sys)/1024/1024, float64(atomic.LoadUint64(&peakMemSys))/1024/1024) + fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000) + fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs)) + + if ctx.GlobalIsSet(utils.NoCompactionFlag.Name) { + return nil + } + + // Compact the entire database to more accurately measure disk io and print the stats + start = time.Now() + fmt.Println("Compacting entire database...") + if err = db.Compact(nil, nil); err != nil { + utils.Fatalf("Compaction failed: %v", err) + } + fmt.Printf("Compaction done in %v.\n\n", time.Since(start)) + + stats, err = db.Stat("leveldb.stats") + if err != nil { + utils.Fatalf("Failed to read database stats: %v", err) + } + fmt.Println(stats) + + ioStats, err = db.Stat("leveldb.iostats") + if err != nil { + utils.Fatalf("Failed to read database iostats: %v", err) + } + fmt.Println(ioStats) + return nil +} + +func exportChain(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + stack := makeFullNode(ctx) + defer stack.Close() + + chain, _ := utils.MakeChain(ctx, stack) + start := time.Now() + + var err error + fp := ctx.Args().First() + if len(ctx.Args()) < 3 { + err = utils.ExportChain(chain, fp) + } else { + // This can be improved to allow for numbers larger than 9223372036854775807 + first, ferr := strconv.ParseInt(ctx.Args().Get(1), 10, 64) + last, lerr := strconv.ParseInt(ctx.Args().Get(2), 10, 64) + if ferr != nil || lerr != nil { + utils.Fatalf("Export error in parsing parameters: block number not an integer\n") + } + if first < 0 || last < 0 { + utils.Fatalf("Export error: block number must be greater than 0\n") + } + err = utils.ExportAppendChain(chain, fp, uint64(first), uint64(last)) + } + + if err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v\n", time.Since(start)) + return nil +} + +// importPreimages imports preimage data from the specified file. +func importPreimages(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + stack := makeFullNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack) + start := time.Now() + + if err := utils.ImportPreimages(db, ctx.Args().First()); err != nil { + utils.Fatalf("Import error: %v\n", err) + } + fmt.Printf("Import done in %v\n", time.Since(start)) + return nil +} + +// exportPreimages dumps the preimage data to specified json file in streaming way. +func exportPreimages(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + stack := makeFullNode(ctx) + defer stack.Close() + + db := utils.MakeChainDatabase(ctx, stack) + start := time.Now() + + if err := utils.ExportPreimages(db, ctx.Args().First()); err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v\n", time.Since(start)) + return nil +} + +func copyDb(ctx *cli.Context) error { + // Ensure we have a source chain directory to copy + if len(ctx.Args()) < 1 { + utils.Fatalf("Source chaindata directory path argument missing") + } + if len(ctx.Args()) < 2 { + utils.Fatalf("Source ancient chain directory path argument missing") + } + // Initialize a new chain for the running node to sync into + stack := makeFullNode(ctx) + defer stack.Close() + + chain, chainDb := utils.MakeChain(ctx, stack) + syncMode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode) + + var syncBloom *trie.SyncBloom + if syncMode == downloader.FastSync { + syncBloom = trie.NewSyncBloom(uint64(ctx.GlobalInt(utils.CacheFlag.Name)/2), chainDb) + } + dl := downloader.New(0, chainDb, syncBloom, new(event.TypeMux), chain, nil, nil) + + // Create a source peer to satisfy downloader requests from + db, err := rawdb.NewLevelDBDatabaseWithFreezer(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name)/2, 256, ctx.Args().Get(1), "") + if err != nil { + return err + } + hc, err := core.NewHeaderChain(db, chain.Config(), chain.Engine(), func() bool { return false }) + if err != nil { + return err + } + peer := downloader.NewFakePeer("local", db, hc, dl) + if err = dl.RegisterPeer("local", 63, peer); err != nil { + return err + } + // Synchronise with the simulated peer + start := time.Now() + + currentHeader := hc.CurrentHeader() + if err = dl.Synchronise("local", currentHeader.Hash(), hc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()), syncMode); err != nil { + return err + } + for dl.Synchronising() { + time.Sleep(10 * time.Millisecond) + } + fmt.Printf("Database copy done in %v\n", time.Since(start)) + + // Compact the entire database to remove any sync overhead + start = time.Now() + fmt.Println("Compacting entire database...") + if err = db.Compact(nil, nil); err != nil { + utils.Fatalf("Compaction failed: %v", err) + } + fmt.Printf("Compaction done in %v.\n\n", time.Since(start)) + return nil +} + +func removeDB(ctx *cli.Context) error { + stack, config := makeConfigNode(ctx) + + // Remove the full node state database + path := stack.ResolvePath("chaindata") + if common.FileExist(path) { + confirmAndRemoveDB(path, "full node state database") + } else { + log.Info("Full node state database missing", "path", path) + } + // Remove the full node ancient database + path = config.Eth.DatabaseFreezer + switch { + case path == "": + path = filepath.Join(stack.ResolvePath("chaindata"), "ancient") + case !filepath.IsAbs(path): + path = config.Node.ResolvePath(path) + } + if common.FileExist(path) { + confirmAndRemoveDB(path, "full node ancient database") + } else { + log.Info("Full node ancient database missing", "path", path) + } + // Remove the light node database + path = stack.ResolvePath("lightchaindata") + if common.FileExist(path) { + confirmAndRemoveDB(path, "light node database") + } else { + log.Info("Light node database missing", "path", path) + } + return nil +} + +// confirmAndRemoveDB prompts the user for a last confirmation and removes the +// folder if accepted. +func confirmAndRemoveDB(database string, kind string) { + confirm, err := console.Stdin.PromptConfirm(fmt.Sprintf("Remove %s (%s)?", kind, database)) + switch { + case err != nil: + utils.Fatalf("%v", err) + case !confirm: + log.Info("Database deletion skipped", "path", database) + default: + start := time.Now() + filepath.Walk(database, func(path string, info os.FileInfo, err error) error { + // If we're at the top level folder, recurse into + if path == database { + return nil + } + // Delete all the files, but not subfolders + if !info.IsDir() { + os.Remove(path) + return nil + } + return filepath.SkipDir + }) + log.Info("Database successfully deleted", "path", database, "elapsed", common.PrettyDuration(time.Since(start))) + } +} + +func dump(ctx *cli.Context) error { + stack := makeFullNode(ctx) + defer stack.Close() + + chain, chainDb := utils.MakeChain(ctx, stack) + for _, arg := range ctx.Args() { + var block *types.Block + if hashish(arg) { + block = chain.GetBlockByHash(common.HexToHash(arg)) + } else { + num, _ := strconv.Atoi(arg) + block = chain.GetBlockByNumber(uint64(num)) + } + if block == nil { + fmt.Println("{}") + utils.Fatalf("block not found") + } else { + state, err := state.New(block.Root(), state.NewDatabase(chainDb)) + if err != nil { + utils.Fatalf("could not create new state: %v", err) + } + fmt.Printf("%s\n", state.Dump()) + } + } + chainDb.Close() + return nil +} + +func inspect(ctx *cli.Context) error { + node, _ := makeConfigNode(ctx) + defer node.Close() + + _, chainDb := utils.MakeChain(ctx, node) + defer chainDb.Close() + + return rawdb.InspectDatabase(chainDb) +} + +// hashish returns true for strings that look like hashes. +func hashish(x string) bool { + _, err := strconv.Atoi(x) + return err != nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/config.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/config.go new file mode 100644 index 00000000..204eb37c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/config.go @@ -0,0 +1,229 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "bufio" + "errors" + "fmt" + "math/big" + "os" + "reflect" + "unicode" + + cli "gopkg.in/urfave/cli.v1" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/dashboard" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/graphql" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" + "github.com/naoina/toml" +) + +var ( + dumpConfigCommand = cli.Command{ + Action: utils.MigrateFlags(dumpConfig), + Name: "dumpconfig", + Usage: "Show configuration values", + ArgsUsage: "", + Flags: append(append(nodeFlags, rpcFlags...), whisperFlags...), + Category: "MISCELLANEOUS COMMANDS", + Description: `The dumpconfig command shows configuration values.`, + } + + configFileFlag = cli.StringFlag{ + Name: "config", + Usage: "TOML configuration file", + } +) + +// These settings ensure that TOML keys use the same names as Go struct fields. +var tomlSettings = toml.Config{ + NormFieldName: func(rt reflect.Type, key string) string { + return key + }, + FieldToKey: func(rt reflect.Type, field string) string { + return field + }, + MissingField: func(rt reflect.Type, field string) error { + link := "" + if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" { + link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name()) + } + return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link) + }, +} + +type ethstatsConfig struct { + URL string `toml:",omitempty"` +} + +type gethConfig struct { + Eth eth.Config + Shh whisper.Config + Node node.Config + Ethstats ethstatsConfig + Dashboard dashboard.Config +} + +func loadConfig(file string, cfg *gethConfig) error { + f, err := os.Open(file) + if err != nil { + return err + } + defer f.Close() + + err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg) + // Add file name to errors that have a line number. + if _, ok := err.(*toml.LineError); ok { + err = errors.New(file + ", " + err.Error()) + } + return err +} + +func defaultNodeConfig() node.Config { + cfg := node.DefaultConfig + cfg.Name = clientIdentifier + cfg.Version = params.VersionWithCommit(gitCommit, gitDate) + cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh") + cfg.WSModules = append(cfg.WSModules, "eth", "shh") + cfg.IPCPath = "geth.ipc" + return cfg +} + +func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { + // Load defaults. + cfg := gethConfig{ + Eth: eth.DefaultConfig, + Shh: whisper.DefaultConfig, + Node: defaultNodeConfig(), + Dashboard: dashboard.DefaultConfig, + } + + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + + // Apply flags. + utils.SetULC(ctx, &cfg.Eth) + utils.SetNodeConfig(ctx, &cfg.Node) + stack, err := node.New(&cfg.Node) + if err != nil { + utils.Fatalf("Failed to create the protocol stack: %v", err) + } + utils.SetEthConfig(ctx, stack, &cfg.Eth) + if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) { + cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name) + } + + utils.SetShhConfig(ctx, stack, &cfg.Shh) + utils.SetDashboardConfig(ctx, &cfg.Dashboard) + + return stack, cfg +} + +// enableWhisper returns true in case one of the whisper flags is set. +func enableWhisper(ctx *cli.Context) bool { + for _, flag := range whisperFlags { + if ctx.GlobalIsSet(flag.GetName()) { + return true + } + } + return false +} + +func makeFullNode(ctx *cli.Context) *node.Node { + stack, cfg := makeConfigNode(ctx) + if ctx.GlobalIsSet(utils.ConstantinopleOverrideFlag.Name) { + cfg.Eth.ConstantinopleOverride = new(big.Int).SetUint64(ctx.GlobalUint64(utils.ConstantinopleOverrideFlag.Name)) + } + + utils.RegisterEthService(stack, &cfg.Eth) + + if ctx.GlobalBool(utils.StateDiffFlag.Name) { + cfg.Eth.StateDiff = true + utils.RegisterStateDiffService(stack, ctx) + } + + if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { + utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit) + } + // Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode + shhEnabled := enableWhisper(ctx) + shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name) + if shhEnabled || shhAutoEnabled { + if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) { + cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name)) + } + if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) { + cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name) + } + if ctx.GlobalIsSet(utils.WhisperRestrictConnectionBetweenLightClientsFlag.Name) { + cfg.Shh.RestrictConnectionBetweenLightClients = true + } + utils.RegisterShhService(stack, &cfg.Shh) + } + + // Configure GraphQL if required + if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) { + if err := graphql.RegisterGraphQLService(stack, cfg.Node.GraphQLEndpoint(), cfg.Node.GraphQLCors, cfg.Node.GraphQLVirtualHosts, cfg.Node.HTTPTimeouts); err != nil { + utils.Fatalf("Failed to register the Ethereum service: %v", err) + } + } + + // Add the Ethereum Stats daemon if requested. + if cfg.Ethstats.URL != "" { + utils.RegisterEthStatsService(stack, cfg.Ethstats.URL) + } + + return stack +} + +// dumpConfig is the dumpconfig command. +func dumpConfig(ctx *cli.Context) error { + _, cfg := makeConfigNode(ctx) + comment := "" + + if cfg.Eth.Genesis != nil { + cfg.Eth.Genesis = nil + comment += "# Note: this config doesn't contain the genesis block.\n\n" + } + + out, err := tomlSettings.Marshal(&cfg) + if err != nil { + return err + } + + dump := os.Stdout + if ctx.NArg() > 0 { + dump, err = os.OpenFile(ctx.Args().Get(0), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + defer dump.Close() + } + dump.WriteString(comment) + dump.Write(out) + + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/main.go new file mode 100644 index 00000000..09086d0f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/main.go @@ -0,0 +1,446 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// geth is the official command-line client for Ethereum. +package main + +import ( + "fmt" + "math" + "os" + godebug "runtime/debug" + "sort" + "strconv" + "strings" + "time" + + "github.com/elastic/gosigar" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/node" + cli "gopkg.in/urfave/cli.v1" +) + +const ( + clientIdentifier = "geth" // Client identifier to advertise over the network +) + +var ( + // Git SHA1 commit hash of the release (set via linker flags) + gitCommit = "" + gitDate = "" + // The app that holds all commands and flags. + app = utils.NewApp(gitCommit, gitDate, "the go-ethereum command line interface") + // flags that configure the node + nodeFlags = []cli.Flag{ + utils.IdentityFlag, + utils.UnlockedAccountFlag, + utils.PasswordFileFlag, + utils.BootnodesFlag, + utils.BootnodesV4Flag, + utils.BootnodesV5Flag, + utils.DataDirFlag, + utils.AncientFlag, + utils.KeyStoreDirFlag, + utils.ExternalSignerFlag, + utils.NoUSBFlag, + utils.SmartCardDaemonPathFlag, + utils.DashboardEnabledFlag, + utils.DashboardAddrFlag, + utils.DashboardPortFlag, + utils.DashboardRefreshFlag, + utils.EthashCacheDirFlag, + utils.EthashCachesInMemoryFlag, + utils.EthashCachesOnDiskFlag, + utils.EthashDatasetDirFlag, + utils.EthashDatasetsInMemoryFlag, + utils.EthashDatasetsOnDiskFlag, + utils.TxPoolLocalsFlag, + utils.TxPoolNoLocalsFlag, + utils.TxPoolJournalFlag, + utils.TxPoolRejournalFlag, + utils.TxPoolPriceLimitFlag, + utils.TxPoolPriceBumpFlag, + utils.TxPoolAccountSlotsFlag, + utils.TxPoolGlobalSlotsFlag, + utils.TxPoolAccountQueueFlag, + utils.TxPoolGlobalQueueFlag, + utils.TxPoolLifetimeFlag, + utils.ULCModeConfigFlag, + utils.OnlyAnnounceModeFlag, + utils.ULCTrustedNodesFlag, + utils.ULCMinTrustedFractionFlag, + utils.SyncModeFlag, + utils.ExitWhenSyncedFlag, + utils.GCModeFlag, + utils.LightServFlag, + utils.LightBandwidthInFlag, + utils.LightBandwidthOutFlag, + utils.LightPeersFlag, + utils.LightKDFFlag, + utils.WhitelistFlag, + utils.CacheFlag, + utils.CacheDatabaseFlag, + utils.CacheTrieFlag, + utils.CacheGCFlag, + utils.CacheNoPrefetchFlag, + utils.ListenPortFlag, + utils.MaxPeersFlag, + utils.MaxPendingPeersFlag, + utils.MiningEnabledFlag, + utils.MinerThreadsFlag, + utils.MinerLegacyThreadsFlag, + utils.MinerNotifyFlag, + utils.MinerGasTargetFlag, + utils.MinerLegacyGasTargetFlag, + utils.MinerGasLimitFlag, + utils.MinerGasPriceFlag, + utils.MinerLegacyGasPriceFlag, + utils.MinerEtherbaseFlag, + utils.MinerLegacyEtherbaseFlag, + utils.MinerExtraDataFlag, + utils.MinerLegacyExtraDataFlag, + utils.MinerRecommitIntervalFlag, + utils.MinerNoVerfiyFlag, + utils.NATFlag, + utils.NoDiscoverFlag, + utils.DiscoveryV5Flag, + utils.NetrestrictFlag, + utils.NodeKeyFileFlag, + utils.NodeKeyHexFlag, + utils.DeveloperFlag, + utils.DeveloperPeriodFlag, + utils.TestnetFlag, + utils.RinkebyFlag, + utils.GoerliFlag, + utils.VMEnableDebugFlag, + utils.NetworkIdFlag, + utils.ConstantinopleOverrideFlag, + utils.EthStatsURLFlag, + utils.FakePoWFlag, + utils.NoCompactionFlag, + utils.GpoBlocksFlag, + utils.GpoPercentileFlag, + utils.EWASMInterpreterFlag, + utils.EVMInterpreterFlag, + utils.StateDiffFlag, + utils.StateDiffPathsAndProofs, + utils.StateDiffIntermediateNodes, + utils.StateDiffStreamBlock, + utils.StateDiffWatchedAddresses, + configFileFlag, + } + + rpcFlags = []cli.Flag{ + utils.RPCEnabledFlag, + utils.RPCListenAddrFlag, + utils.RPCPortFlag, + utils.RPCCORSDomainFlag, + utils.RPCVirtualHostsFlag, + utils.GraphQLEnabledFlag, + utils.GraphQLListenAddrFlag, + utils.GraphQLPortFlag, + utils.GraphQLCORSDomainFlag, + utils.GraphQLVirtualHostsFlag, + utils.RPCApiFlag, + utils.WSEnabledFlag, + utils.WSListenAddrFlag, + utils.WSPortFlag, + utils.WSApiFlag, + utils.WSAllowedOriginsFlag, + utils.IPCDisabledFlag, + utils.IPCPathFlag, + utils.InsecureUnlockAllowedFlag, + utils.RPCGlobalGasCap, + } + + whisperFlags = []cli.Flag{ + utils.WhisperEnabledFlag, + utils.WhisperMaxMessageSizeFlag, + utils.WhisperMinPOWFlag, + utils.WhisperRestrictConnectionBetweenLightClientsFlag, + } + + metricsFlags = []cli.Flag{ + utils.MetricsEnabledFlag, + utils.MetricsEnabledExpensiveFlag, + utils.MetricsEnableInfluxDBFlag, + utils.MetricsInfluxDBEndpointFlag, + utils.MetricsInfluxDBDatabaseFlag, + utils.MetricsInfluxDBUsernameFlag, + utils.MetricsInfluxDBPasswordFlag, + utils.MetricsInfluxDBTagsFlag, + } +) + +func init() { + // Initialize the CLI app and start Geth + app.Action = geth + app.HideVersion = true // we have a command to print the version + app.Copyright = "Copyright 2013-2019 The go-ethereum Authors" + app.Commands = []cli.Command{ + // See chaincmd.go: + initCommand, + importCommand, + exportCommand, + importPreimagesCommand, + exportPreimagesCommand, + copydbCommand, + removedbCommand, + dumpCommand, + inspectCommand, + // See accountcmd.go: + accountCommand, + walletCommand, + // See consolecmd.go: + consoleCommand, + attachCommand, + javascriptCommand, + // See misccmd.go: + makecacheCommand, + makedagCommand, + versionCommand, + licenseCommand, + // See config.go + dumpConfigCommand, + // See retesteth.go + retestethCommand, + } + sort.Sort(cli.CommandsByName(app.Commands)) + + app.Flags = append(app.Flags, nodeFlags...) + app.Flags = append(app.Flags, rpcFlags...) + app.Flags = append(app.Flags, consoleFlags...) + app.Flags = append(app.Flags, debug.Flags...) + app.Flags = append(app.Flags, whisperFlags...) + app.Flags = append(app.Flags, metricsFlags...) + + app.Before = func(ctx *cli.Context) error { + logdir := "" + if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { + logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs") + } + if err := debug.Setup(ctx, logdir); err != nil { + return err + } + // If we're a full node on mainnet without --cache specified, bump default cache allowance + if ctx.GlobalString(utils.SyncModeFlag.Name) != "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) && !ctx.GlobalIsSet(utils.NetworkIdFlag.Name) { + // Make sure we're not on any supported preconfigured testnet either + if !ctx.GlobalIsSet(utils.TestnetFlag.Name) && !ctx.GlobalIsSet(utils.RinkebyFlag.Name) && !ctx.GlobalIsSet(utils.GoerliFlag.Name) { + // Nope, we're really on mainnet. Bump that cache up! + log.Info("Bumping default cache on mainnet", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 4096) + ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(4096)) + } + } + // If we're running a light client on any network, drop the cache to some meaningfully low amount + if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) { + log.Info("Dropping default light client cache", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 128) + ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(128)) + } + // Cap the cache allowance and tune the garbage collector + var mem gosigar.Mem + if err := mem.Get(); err == nil { + allowance := int(mem.Total / 1024 / 1024 / 3) + if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance { + log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) + ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)) + } + } + // Ensure Go's GC ignores the database cache for trigger percentage + cache := ctx.GlobalInt(utils.CacheFlag.Name) + gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + + log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) + godebug.SetGCPercent(int(gogc)) + + // Start metrics export if enabled + utils.SetupMetrics(ctx) + + // Start system runtime metrics collection + go metrics.CollectProcessMetrics(3 * time.Second) + + return nil + } + + app.After = func(ctx *cli.Context) error { + debug.Exit() + console.Stdin.Close() // Resets terminal mode. + return nil + } +} + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +// geth is the main entry point into the system if no special subcommand is ran. +// It creates a default node based on the command line arguments and runs it in +// blocking mode, waiting for it to be shut down. +func geth(ctx *cli.Context) error { + if args := ctx.Args(); len(args) > 0 { + return fmt.Errorf("invalid command: %q", args[0]) + } + node := makeFullNode(ctx) + defer node.Close() + startNode(ctx, node) + node.Wait() + return nil +} + +// startNode boots up the system node and all registered protocols, after which +// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the +// miner. +func startNode(ctx *cli.Context, stack *node.Node) { + debug.Memsize.Add("node", stack) + + // Start up the node itself + utils.StartNode(stack) + + // Unlock any account specifically requested + unlockAccounts(ctx, stack) + + // Register wallet event handlers to open and auto-derive wallets + events := make(chan accounts.WalletEvent, 16) + stack.AccountManager().Subscribe(events) + + go func() { + // Create a chain state reader for self-derivation + rpcClient, err := stack.Attach() + if err != nil { + utils.Fatalf("Failed to attach to self: %v", err) + } + stateReader := ethclient.NewClient(rpcClient) + + // Open any wallets already attached + for _, wallet := range stack.AccountManager().Wallets() { + if err := wallet.Open(""); err != nil { + log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) + } + } + // Listen for wallet event till termination + for event := range events { + switch event.Kind { + case accounts.WalletArrived: + if err := event.Wallet.Open(""); err != nil { + log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) + } + case accounts.WalletOpened: + status, _ := event.Wallet.Status() + log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) + + var derivationPaths []accounts.DerivationPath + if event.Wallet.URL().Scheme == "ledger" { + derivationPaths = append(derivationPaths, accounts.LegacyLedgerBaseDerivationPath) + } + derivationPaths = append(derivationPaths, accounts.DefaultBaseDerivationPath) + + event.Wallet.SelfDerive(derivationPaths, stateReader) + + case accounts.WalletDropped: + log.Info("Old wallet dropped", "url", event.Wallet.URL()) + event.Wallet.Close() + } + } + }() + + // Spawn a standalone goroutine for status synchronization monitoring, + // close the node when synchronization is complete if user required. + if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) { + go func() { + sub := stack.EventMux().Subscribe(downloader.DoneEvent{}) + defer sub.Unsubscribe() + for { + event := <-sub.Chan() + if event == nil { + continue + } + done, ok := event.Data.(downloader.DoneEvent) + if !ok { + continue + } + if timestamp := time.Unix(int64(done.Latest.Time), 0); time.Since(timestamp) < 10*time.Minute { + log.Info("Synchronisation completed", "latestnum", done.Latest.Number, "latesthash", done.Latest.Hash(), + "age", common.PrettyAge(timestamp)) + stack.Stop() + } + + } + }() + } + + // Start auxiliary services if enabled + if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { + // Mining only makes sense if a full Ethereum node is running + if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { + utils.Fatalf("Light clients do not support mining") + } + var ethereum *eth.Ethereum + if err := stack.Service(ðereum); err != nil { + utils.Fatalf("Ethereum service not running: %v", err) + } + // Set the gas price to the limits from the CLI and start mining + gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name) + if ctx.IsSet(utils.MinerGasPriceFlag.Name) { + gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name) + } + ethereum.TxPool().SetGasPrice(gasprice) + + threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name) + if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) { + threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name) + } + if err := ethereum.StartMining(threads); err != nil { + utils.Fatalf("Failed to start mining: %v", err) + } + } +} + +// unlockAccounts unlocks any account specifically requested. +func unlockAccounts(ctx *cli.Context, stack *node.Node) { + var unlocks []string + inputs := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") + for _, input := range inputs { + if trimmed := strings.TrimSpace(input); trimmed != "" { + unlocks = append(unlocks, trimmed) + } + } + // Short circuit if there is no account to unlock. + if len(unlocks) == 0 { + return + } + // If insecure account unlocking is not allowed if node's APIs are exposed to external. + // Print warning log to user and skip unlocking. + if !stack.Config().InsecureUnlockAllowed && stack.Config().ExtRPCEnabled() { + utils.Fatalf("Account unlock with HTTP access is forbidden!") + } + ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + passwords := utils.MakePasswordList(ctx) + for i, account := range unlocks { + unlockAccount(ks, account, i, passwords) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/misccmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/misccmd.go new file mode 100644 index 00000000..39ca4787 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/misccmd.go @@ -0,0 +1,142 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "fmt" + "os" + "runtime" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/params" + "gopkg.in/urfave/cli.v1" +) + +var ( + makecacheCommand = cli.Command{ + Action: utils.MigrateFlags(makecache), + Name: "makecache", + Usage: "Generate ethash verification cache (for testing)", + ArgsUsage: " ", + Category: "MISCELLANEOUS COMMANDS", + Description: ` +The makecache command generates an ethash cache in . + +This command exists to support the system testing project. +Regular users do not need to execute it. +`, + } + makedagCommand = cli.Command{ + Action: utils.MigrateFlags(makedag), + Name: "makedag", + Usage: "Generate ethash mining DAG (for testing)", + ArgsUsage: " ", + Category: "MISCELLANEOUS COMMANDS", + Description: ` +The makedag command generates an ethash DAG in . + +This command exists to support the system testing project. +Regular users do not need to execute it. +`, + } + versionCommand = cli.Command{ + Action: utils.MigrateFlags(version), + Name: "version", + Usage: "Print version numbers", + ArgsUsage: " ", + Category: "MISCELLANEOUS COMMANDS", + Description: ` +The output of this command is supposed to be machine-readable. +`, + } + licenseCommand = cli.Command{ + Action: utils.MigrateFlags(license), + Name: "license", + Usage: "Display license information", + ArgsUsage: " ", + Category: "MISCELLANEOUS COMMANDS", + } +) + +// makecache generates an ethash verification cache into the provided folder. +func makecache(ctx *cli.Context) error { + args := ctx.Args() + if len(args) != 2 { + utils.Fatalf(`Usage: geth makecache `) + } + block, err := strconv.ParseUint(args[0], 0, 64) + if err != nil { + utils.Fatalf("Invalid block number: %v", err) + } + ethash.MakeCache(block, args[1]) + + return nil +} + +// makedag generates an ethash mining DAG into the provided folder. +func makedag(ctx *cli.Context) error { + args := ctx.Args() + if len(args) != 2 { + utils.Fatalf(`Usage: geth makedag `) + } + block, err := strconv.ParseUint(args[0], 0, 64) + if err != nil { + utils.Fatalf("Invalid block number: %v", err) + } + ethash.MakeDataset(block, args[1]) + + return nil +} + +func version(ctx *cli.Context) error { + fmt.Println(strings.Title(clientIdentifier)) + fmt.Println("Version:", params.VersionWithMeta) + if gitCommit != "" { + fmt.Println("Git Commit:", gitCommit) + } + if gitDate != "" { + fmt.Println("Git Commit Date:", gitDate) + } + fmt.Println("Architecture:", runtime.GOARCH) + fmt.Println("Protocol Versions:", eth.ProtocolVersions) + fmt.Println("Network Id:", eth.DefaultConfig.NetworkId) + fmt.Println("Go Version:", runtime.Version()) + fmt.Println("Operating System:", runtime.GOOS) + fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) + fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) + return nil +} + +func license(_ *cli.Context) error { + fmt.Println(`Geth is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Geth is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with geth. If not, see .`) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth.go new file mode 100644 index 00000000..6d5763f8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth.go @@ -0,0 +1,888 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "bytes" + "context" + "fmt" + "math/big" + "os" + "os/signal" + "strings" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" + + cli "gopkg.in/urfave/cli.v1" +) + +var ( + rpcPortFlag = cli.IntFlag{ + Name: "rpcport", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort, + } + retestethCommand = cli.Command{ + Action: utils.MigrateFlags(retesteth), + Name: "retesteth", + Usage: "Launches geth in retesteth mode", + ArgsUsage: "", + Flags: []cli.Flag{rpcPortFlag}, + Category: "MISCELLANEOUS COMMANDS", + Description: `Launches geth in retesteth mode (no database, no network, only retesteth RPC interface)`, + } +) + +type RetestethTestAPI interface { + SetChainParams(ctx context.Context, chainParams ChainParams) (bool, error) + MineBlocks(ctx context.Context, number uint64) (bool, error) + ModifyTimestamp(ctx context.Context, interval uint64) (bool, error) + ImportRawBlock(ctx context.Context, rawBlock hexutil.Bytes) (common.Hash, error) + RewindToBlock(ctx context.Context, number uint64) (bool, error) + GetLogHash(ctx context.Context, txHash common.Hash) (common.Hash, error) +} + +type RetestethEthAPI interface { + SendRawTransaction(ctx context.Context, rawTx hexutil.Bytes) (common.Hash, error) + BlockNumber(ctx context.Context) (uint64, error) + GetBlockByNumber(ctx context.Context, blockNr math.HexOrDecimal64, fullTx bool) (map[string]interface{}, error) + GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error) + GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error) + GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error) +} + +type RetestethDebugAPI interface { + AccountRangeAt(ctx context.Context, + blockHashOrNumber *math.HexOrDecimal256, txIndex uint64, + addressHash *math.HexOrDecimal256, maxResults uint64, + ) (AccountRangeResult, error) + StorageRangeAt(ctx context.Context, + blockHashOrNumber *math.HexOrDecimal256, txIndex uint64, + address common.Address, + begin *math.HexOrDecimal256, maxResults uint64, + ) (StorageRangeResult, error) +} + +type RetestWeb3API interface { + ClientVersion(ctx context.Context) (string, error) +} + +type RetestethAPI struct { + ethDb ethdb.Database + db state.Database + chainConfig *params.ChainConfig + author common.Address + extraData []byte + genesisHash common.Hash + engine *NoRewardEngine + blockchain *core.BlockChain + blockNumber uint64 + txMap map[common.Address]map[uint64]*types.Transaction // Sender -> Nonce -> Transaction + txSenders map[common.Address]struct{} // Set of transaction senders + blockInterval uint64 +} + +type ChainParams struct { + SealEngine string `json:"sealEngine"` + Params CParamsParams `json:"params"` + Genesis CParamsGenesis `json:"genesis"` + Accounts map[common.Address]CParamsAccount `json:"accounts"` +} + +type CParamsParams struct { + AccountStartNonce math.HexOrDecimal64 `json:"accountStartNonce"` + HomesteadForkBlock *math.HexOrDecimal64 `json:"homesteadForkBlock"` + EIP150ForkBlock *math.HexOrDecimal64 `json:"EIP150ForkBlock"` + EIP158ForkBlock *math.HexOrDecimal64 `json:"EIP158ForkBlock"` + DaoHardforkBlock *math.HexOrDecimal64 `json:"daoHardforkBlock"` + ByzantiumForkBlock *math.HexOrDecimal64 `json:"byzantiumForkBlock"` + ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"` + ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"` + ChainID *math.HexOrDecimal256 `json:"chainID"` + MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"` + TieBreakingGas bool `json:"tieBreakingGas"` + MinGasLimit math.HexOrDecimal64 `json:"minGasLimit"` + MaxGasLimit math.HexOrDecimal64 `json:"maxGasLimit"` + GasLimitBoundDivisor math.HexOrDecimal64 `json:"gasLimitBoundDivisor"` + MinimumDifficulty math.HexOrDecimal256 `json:"minimumDifficulty"` + DifficultyBoundDivisor math.HexOrDecimal256 `json:"difficultyBoundDivisor"` + DurationLimit math.HexOrDecimal256 `json:"durationLimit"` + BlockReward math.HexOrDecimal256 `json:"blockReward"` + NetworkID math.HexOrDecimal256 `json:"networkID"` +} + +type CParamsGenesis struct { + Nonce math.HexOrDecimal64 `json:"nonce"` + Difficulty *math.HexOrDecimal256 `json:"difficulty"` + MixHash *math.HexOrDecimal256 `json:"mixHash"` + Author common.Address `json:"author"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ParentHash common.Hash `json:"parentHash"` + ExtraData hexutil.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit"` +} + +type CParamsAccount struct { + Balance *math.HexOrDecimal256 `json:"balance"` + Precompiled *CPAccountPrecompiled `json:"precompiled"` + Code hexutil.Bytes `json:"code"` + Storage map[string]string `json:"storage"` + Nonce *math.HexOrDecimal64 `json:"nonce"` +} + +type CPAccountPrecompiled struct { + Name string `json:"name"` + StartingBlock math.HexOrDecimal64 `json:"startingBlock"` + Linear *CPAPrecompiledLinear `json:"linear"` +} + +type CPAPrecompiledLinear struct { + Base uint64 `json:"base"` + Word uint64 `json:"word"` +} + +type AccountRangeResult struct { + AddressMap map[common.Hash]common.Address `json:"addressMap"` + NextKey common.Hash `json:"nextKey"` +} + +type StorageRangeResult struct { + Complete bool `json:"complete"` + Storage map[common.Hash]SRItem `json:"storage"` +} + +type SRItem struct { + Key string `json:"key"` + Value string `json:"value"` +} + +type NoRewardEngine struct { + inner consensus.Engine + rewardsOn bool +} + +func (e *NoRewardEngine) Author(header *types.Header) (common.Address, error) { + return e.inner.Author(header) +} + +func (e *NoRewardEngine) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { + return e.inner.VerifyHeader(chain, header, seal) +} + +func (e *NoRewardEngine) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { + return e.inner.VerifyHeaders(chain, headers, seals) +} + +func (e *NoRewardEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + return e.inner.VerifyUncles(chain, block) +} + +func (e *NoRewardEngine) VerifySeal(chain consensus.ChainReader, header *types.Header) error { + return e.inner.VerifySeal(chain, header) +} + +func (e *NoRewardEngine) Prepare(chain consensus.ChainReader, header *types.Header) error { + return e.inner.Prepare(chain, header) +} + +func (e *NoRewardEngine) accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { + // Simply touch miner and uncle coinbase accounts + reward := big.NewInt(0) + for _, uncle := range uncles { + state.AddBalance(uncle.Coinbase, reward) + } + state.AddBalance(header.Coinbase, reward) +} + +func (e *NoRewardEngine) Finalize(chain consensus.ChainReader, header *types.Header, statedb *state.StateDB, txs []*types.Transaction, + uncles []*types.Header) { + if e.rewardsOn { + e.inner.Finalize(chain, header, statedb, txs, uncles) + } else { + e.accumulateRewards(chain.Config(), statedb, header, uncles) + header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + } +} + +func (e *NoRewardEngine) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, statedb *state.StateDB, txs []*types.Transaction, + uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + if e.rewardsOn { + return e.inner.FinalizeAndAssemble(chain, header, statedb, txs, uncles, receipts) + } else { + e.accumulateRewards(chain.Config(), statedb, header, uncles) + header.Root = statedb.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + + // Header seems complete, assemble into a block and return + return types.NewBlock(header, txs, uncles, receipts), nil + } +} + +func (e *NoRewardEngine) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + return e.inner.Seal(chain, block, results, stop) +} + +func (e *NoRewardEngine) SealHash(header *types.Header) common.Hash { + return e.inner.SealHash(header) +} + +func (e *NoRewardEngine) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { + return e.inner.CalcDifficulty(chain, time, parent) +} + +func (e *NoRewardEngine) APIs(chain consensus.ChainReader) []rpc.API { + return e.inner.APIs(chain) +} + +func (e *NoRewardEngine) Close() error { + return e.inner.Close() +} + +func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainParams) (bool, error) { + // Clean up + if api.blockchain != nil { + api.blockchain.Stop() + } + if api.engine != nil { + api.engine.Close() + } + if api.ethDb != nil { + api.ethDb.Close() + } + ethDb := rawdb.NewMemoryDatabase() + accounts := make(core.GenesisAlloc) + for address, account := range chainParams.Accounts { + balance := big.NewInt(0) + if account.Balance != nil { + balance.Set((*big.Int)(account.Balance)) + } + var nonce uint64 + if account.Nonce != nil { + nonce = uint64(*account.Nonce) + } + if account.Precompiled == nil || account.Balance != nil { + storage := make(map[common.Hash]common.Hash) + for k, v := range account.Storage { + storage[common.HexToHash(k)] = common.HexToHash(v) + } + accounts[address] = core.GenesisAccount{ + Balance: balance, + Code: account.Code, + Nonce: nonce, + Storage: storage, + } + } + } + chainId := big.NewInt(1) + if chainParams.Params.ChainID != nil { + chainId.Set((*big.Int)(chainParams.Params.ChainID)) + } + var ( + homesteadBlock *big.Int + daoForkBlock *big.Int + eip150Block *big.Int + eip155Block *big.Int + eip158Block *big.Int + byzantiumBlock *big.Int + constantinopleBlock *big.Int + petersburgBlock *big.Int + ) + if chainParams.Params.HomesteadForkBlock != nil { + homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock)) + } + if chainParams.Params.DaoHardforkBlock != nil { + daoForkBlock = big.NewInt(int64(*chainParams.Params.DaoHardforkBlock)) + } + if chainParams.Params.EIP150ForkBlock != nil { + eip150Block = big.NewInt(int64(*chainParams.Params.EIP150ForkBlock)) + } + if chainParams.Params.EIP158ForkBlock != nil { + eip158Block = big.NewInt(int64(*chainParams.Params.EIP158ForkBlock)) + eip155Block = eip158Block + } + if chainParams.Params.ByzantiumForkBlock != nil { + byzantiumBlock = big.NewInt(int64(*chainParams.Params.ByzantiumForkBlock)) + } + if chainParams.Params.ConstantinopleForkBlock != nil { + constantinopleBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleForkBlock)) + } + if chainParams.Params.ConstantinopleFixForkBlock != nil { + petersburgBlock = big.NewInt(int64(*chainParams.Params.ConstantinopleFixForkBlock)) + } + if constantinopleBlock != nil && petersburgBlock == nil { + petersburgBlock = big.NewInt(100000000000) + } + genesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: chainId, + HomesteadBlock: homesteadBlock, + DAOForkBlock: daoForkBlock, + DAOForkSupport: false, + EIP150Block: eip150Block, + EIP155Block: eip155Block, + EIP158Block: eip158Block, + ByzantiumBlock: byzantiumBlock, + ConstantinopleBlock: constantinopleBlock, + PetersburgBlock: petersburgBlock, + }, + Nonce: uint64(chainParams.Genesis.Nonce), + Timestamp: uint64(chainParams.Genesis.Timestamp), + ExtraData: chainParams.Genesis.ExtraData, + GasLimit: uint64(chainParams.Genesis.GasLimit), + Difficulty: big.NewInt(0).Set((*big.Int)(chainParams.Genesis.Difficulty)), + Mixhash: common.BigToHash((*big.Int)(chainParams.Genesis.MixHash)), + Coinbase: chainParams.Genesis.Author, + ParentHash: chainParams.Genesis.ParentHash, + Alloc: accounts, + } + chainConfig, genesisHash, err := core.SetupGenesisBlock(ethDb, genesis) + if err != nil { + return false, err + } + fmt.Printf("Chain config: %v\n", chainConfig) + + var inner consensus.Engine + switch chainParams.SealEngine { + case "NoProof", "NoReward": + inner = ethash.NewFaker() + case "Ethash": + inner = ethash.New(ethash.Config{ + CacheDir: "ethash", + CachesInMem: 2, + CachesOnDisk: 3, + DatasetsInMem: 1, + DatasetsOnDisk: 2, + }, nil, false) + default: + return false, fmt.Errorf("unrecognised seal engine: %s", chainParams.SealEngine) + } + engine := &NoRewardEngine{inner: inner, rewardsOn: chainParams.SealEngine != "NoReward"} + + blockchain, err := core.NewBlockChain(ethDb, nil, chainConfig, engine, vm.Config{}, nil) + if err != nil { + return false, err + } + + api.chainConfig = chainConfig + api.genesisHash = genesisHash + api.author = chainParams.Genesis.Author + api.extraData = chainParams.Genesis.ExtraData + api.ethDb = ethDb + api.engine = engine + api.blockchain = blockchain + api.db = state.NewDatabase(api.ethDb) + api.blockNumber = 0 + api.txMap = make(map[common.Address]map[uint64]*types.Transaction) + api.txSenders = make(map[common.Address]struct{}) + api.blockInterval = 0 + return true, nil +} + +func (api *RetestethAPI) SendRawTransaction(ctx context.Context, rawTx hexutil.Bytes) (common.Hash, error) { + tx := new(types.Transaction) + if err := rlp.DecodeBytes(rawTx, tx); err != nil { + // Return nil is not by mistake - some tests include sending transaction where gasLimit overflows uint64 + return common.Hash{}, nil + } + signer := types.MakeSigner(api.chainConfig, big.NewInt(int64(api.blockNumber))) + sender, err := types.Sender(signer, tx) + if err != nil { + return common.Hash{}, err + } + if nonceMap, ok := api.txMap[sender]; ok { + nonceMap[tx.Nonce()] = tx + } else { + nonceMap = make(map[uint64]*types.Transaction) + nonceMap[tx.Nonce()] = tx + api.txMap[sender] = nonceMap + } + api.txSenders[sender] = struct{}{} + return tx.Hash(), nil +} + +func (api *RetestethAPI) MineBlocks(ctx context.Context, number uint64) (bool, error) { + for i := 0; i < int(number); i++ { + if err := api.mineBlock(); err != nil { + return false, err + } + } + fmt.Printf("Mined %d blocks\n", number) + return true, nil +} + +func (api *RetestethAPI) mineBlock() error { + parentHash := rawdb.ReadCanonicalHash(api.ethDb, api.blockNumber) + parent := rawdb.ReadBlock(api.ethDb, parentHash, api.blockNumber) + var timestamp uint64 + if api.blockInterval == 0 { + timestamp = uint64(time.Now().Unix()) + } else { + timestamp = parent.Time() + api.blockInterval + } + gasLimit := core.CalcGasLimit(parent, 9223372036854775807, 9223372036854775807) + header := &types.Header{ + ParentHash: parent.Hash(), + Number: big.NewInt(int64(api.blockNumber + 1)), + GasLimit: gasLimit, + Extra: api.extraData, + Time: timestamp, + } + header.Coinbase = api.author + if api.engine != nil { + api.engine.Prepare(api.blockchain, header) + } + // If we are care about TheDAO hard-fork check whether to override the extra-data or not + if daoBlock := api.chainConfig.DAOForkBlock; daoBlock != nil { + // Check whether the block is among the fork extra-override range + limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) + if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 { + // Depending whether we support or oppose the fork, override differently + if api.chainConfig.DAOForkSupport { + header.Extra = common.CopyBytes(params.DAOForkBlockExtra) + } else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { + header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data + } + } + } + statedb, err := api.blockchain.StateAt(parent.Root()) + if err != nil { + return err + } + if api.chainConfig.DAOForkSupport && api.chainConfig.DAOForkBlock != nil && api.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { + misc.ApplyDAOHardFork(statedb) + } + gasPool := new(core.GasPool).AddGas(header.GasLimit) + txCount := 0 + var txs []*types.Transaction + var receipts []*types.Receipt + var coalescedLogs []*types.Log + var blockFull = gasPool.Gas() < params.TxGas + for address := range api.txSenders { + if blockFull { + break + } + m := api.txMap[address] + for nonce := statedb.GetNonce(address); ; nonce++ { + if tx, ok := m[nonce]; ok { + // Try to apply transactions to the state + statedb.Prepare(tx.Hash(), common.Hash{}, txCount) + snap := statedb.Snapshot() + + receipt, _, err := core.ApplyTransaction( + api.chainConfig, + api.blockchain, + &api.author, + gasPool, + statedb, + header, tx, &header.GasUsed, *api.blockchain.GetVMConfig(), + ) + if err != nil { + statedb.RevertToSnapshot(snap) + break + } + txs = append(txs, tx) + receipts = append(receipts, receipt) + coalescedLogs = append(coalescedLogs, receipt.Logs...) + delete(m, nonce) + if len(m) == 0 { + // Last tx for the sender + delete(api.txMap, address) + delete(api.txSenders, address) + } + txCount++ + if gasPool.Gas() < params.TxGas { + blockFull = true + break + } + } else { + break // Gap in the nonces + } + } + } + block, err := api.engine.FinalizeAndAssemble(api.blockchain, header, statedb, txs, []*types.Header{}, receipts) + return api.importBlock(block) +} + +func (api *RetestethAPI) importBlock(block *types.Block) error { + if _, err := api.blockchain.InsertChain([]*types.Block{block}); err != nil { + return err + } + api.blockNumber = block.NumberU64() + fmt.Printf("Imported block %d\n", block.NumberU64()) + return nil +} + +func (api *RetestethAPI) ModifyTimestamp(ctx context.Context, interval uint64) (bool, error) { + api.blockInterval = interval + return true, nil +} + +func (api *RetestethAPI) ImportRawBlock(ctx context.Context, rawBlock hexutil.Bytes) (common.Hash, error) { + block := new(types.Block) + if err := rlp.DecodeBytes(rawBlock, block); err != nil { + return common.Hash{}, err + } + fmt.Printf("Importing block %d with parent hash: %x, genesisHash: %x\n", block.NumberU64(), block.ParentHash(), api.genesisHash) + if err := api.importBlock(block); err != nil { + return common.Hash{}, err + } + return block.Hash(), nil +} + +func (api *RetestethAPI) RewindToBlock(ctx context.Context, newHead uint64) (bool, error) { + if err := api.blockchain.SetHead(newHead); err != nil { + return false, err + } + api.blockNumber = newHead + return true, nil +} + +var emptyListHash common.Hash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") + +func (api *RetestethAPI) GetLogHash(ctx context.Context, txHash common.Hash) (common.Hash, error) { + receipt, _, _, _ := rawdb.ReadReceipt(api.ethDb, txHash, api.chainConfig) + if receipt == nil { + return emptyListHash, nil + } else { + if logListRlp, err := rlp.EncodeToBytes(receipt.Logs); err != nil { + return common.Hash{}, err + } else { + return common.BytesToHash(crypto.Keccak256(logListRlp)), nil + } + } +} + +func (api *RetestethAPI) BlockNumber(ctx context.Context) (uint64, error) { + //fmt.Printf("BlockNumber, response: %d\n", api.blockNumber) + return api.blockNumber, nil +} + +func (api *RetestethAPI) GetBlockByNumber(ctx context.Context, blockNr math.HexOrDecimal64, fullTx bool) (map[string]interface{}, error) { + block := api.blockchain.GetBlockByNumber(uint64(blockNr)) + if block != nil { + response, err := RPCMarshalBlock(block, true, fullTx) + if err != nil { + return nil, err + } + response["author"] = response["miner"] + response["totalDifficulty"] = (*hexutil.Big)(api.blockchain.GetTd(block.Hash(), uint64(blockNr))) + return response, err + } + return nil, fmt.Errorf("block %d not found", blockNr) +} + +func (api *RetestethAPI) AccountRangeAt(ctx context.Context, + blockHashOrNumber *math.HexOrDecimal256, txIndex uint64, + addressHash *math.HexOrDecimal256, maxResults uint64, +) (AccountRangeResult, error) { + var ( + header *types.Header + block *types.Block + ) + if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 { + blockHash := common.BigToHash((*big.Int)(blockHashOrNumber)) + header = api.blockchain.GetHeaderByHash(blockHash) + block = api.blockchain.GetBlockByHash(blockHash) + //fmt.Printf("Account range: %x, txIndex %d, start: %x, maxResults: %d\n", blockHash, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults) + } else { + blockNumber := (*big.Int)(blockHashOrNumber).Uint64() + header = api.blockchain.GetHeaderByNumber(blockNumber) + block = api.blockchain.GetBlockByNumber(blockNumber) + //fmt.Printf("Account range: %d, txIndex %d, start: %x, maxResults: %d\n", blockNumber, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults) + } + parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash) + var root common.Hash + var statedb *state.StateDB + var err error + if parentHeader == nil || int(txIndex) >= len(block.Transactions()) { + root = header.Root + statedb, err = api.blockchain.StateAt(root) + if err != nil { + return AccountRangeResult{}, err + } + } else { + root = parentHeader.Root + statedb, err = api.blockchain.StateAt(root) + if err != nil { + return AccountRangeResult{}, err + } + // Recompute transactions up to the target index. + signer := types.MakeSigner(api.blockchain.Config(), block.Number()) + for idx, tx := range block.Transactions() { + // Assemble the transaction call message and return if the requested offset + msg, _ := tx.AsMessage(signer) + context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil) + // Not yet the searched for transaction, execute on top of the current state + vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{}) + if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { + return AccountRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) + } + // Ensure any modifications are committed to the state + // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect + root = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number())) + if idx == int(txIndex) { + // This is to make sure root can be opened by OpenTrie + root, err = statedb.Commit(api.chainConfig.IsEIP158(block.Number())) + if err != nil { + return AccountRangeResult{}, err + } + break + } + } + } + accountTrie, err := statedb.Database().OpenTrie(root) + if err != nil { + return AccountRangeResult{}, err + } + it := trie.NewIterator(accountTrie.NodeIterator(common.BigToHash((*big.Int)(addressHash)).Bytes())) + result := AccountRangeResult{AddressMap: make(map[common.Hash]common.Address)} + for i := 0; /*i < int(maxResults) && */ it.Next(); i++ { + if preimage := accountTrie.GetKey(it.Key); preimage != nil { + result.AddressMap[common.BytesToHash(it.Key)] = common.BytesToAddress(preimage) + //fmt.Printf("%x: %x\n", it.Key, preimage) + } else { + //fmt.Printf("could not find preimage for %x\n", it.Key) + } + } + //fmt.Printf("Number of entries returned: %d\n", len(result.AddressMap)) + // Add the 'next key' so clients can continue downloading. + if it.Next() { + next := common.BytesToHash(it.Key) + result.NextKey = next + } + return result, nil +} + +func (api *RetestethAPI) GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error) { + //fmt.Printf("GetBalance %x, block %d\n", address, blockNr) + header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) + statedb, err := api.blockchain.StateAt(header.Root) + if err != nil { + return nil, err + } + return (*math.HexOrDecimal256)(statedb.GetBalance(address)), nil +} + +func (api *RetestethAPI) GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error) { + header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) + statedb, err := api.blockchain.StateAt(header.Root) + if err != nil { + return nil, err + } + return statedb.GetCode(address), nil +} + +func (api *RetestethAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error) { + header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) + statedb, err := api.blockchain.StateAt(header.Root) + if err != nil { + return 0, err + } + return statedb.GetNonce(address), nil +} + +func (api *RetestethAPI) StorageRangeAt(ctx context.Context, + blockHashOrNumber *math.HexOrDecimal256, txIndex uint64, + address common.Address, + begin *math.HexOrDecimal256, maxResults uint64, +) (StorageRangeResult, error) { + var ( + header *types.Header + block *types.Block + ) + if (*big.Int)(blockHashOrNumber).Cmp(big.NewInt(math.MaxInt64)) > 0 { + blockHash := common.BigToHash((*big.Int)(blockHashOrNumber)) + header = api.blockchain.GetHeaderByHash(blockHash) + block = api.blockchain.GetBlockByHash(blockHash) + //fmt.Printf("Storage range: %x, txIndex %d, addr: %x, start: %x, maxResults: %d\n", + // blockHash, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults) + } else { + blockNumber := (*big.Int)(blockHashOrNumber).Uint64() + header = api.blockchain.GetHeaderByNumber(blockNumber) + block = api.blockchain.GetBlockByNumber(blockNumber) + //fmt.Printf("Storage range: %d, txIndex %d, addr: %x, start: %x, maxResults: %d\n", + // blockNumber, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults) + } + parentHeader := api.blockchain.GetHeaderByHash(header.ParentHash) + var root common.Hash + var statedb *state.StateDB + var err error + if parentHeader == nil || int(txIndex) >= len(block.Transactions()) { + root = header.Root + statedb, err = api.blockchain.StateAt(root) + if err != nil { + return StorageRangeResult{}, err + } + } else { + root = parentHeader.Root + statedb, err = api.blockchain.StateAt(root) + if err != nil { + return StorageRangeResult{}, err + } + // Recompute transactions up to the target index. + signer := types.MakeSigner(api.blockchain.Config(), block.Number()) + for idx, tx := range block.Transactions() { + // Assemble the transaction call message and return if the requested offset + msg, _ := tx.AsMessage(signer) + context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil) + // Not yet the searched for transaction, execute on top of the current state + vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{}) + if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { + return StorageRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) + } + // Ensure any modifications are committed to the state + // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect + root = statedb.IntermediateRoot(vmenv.ChainConfig().IsEIP158(block.Number())) + if idx == int(txIndex) { + // This is to make sure root can be opened by OpenTrie + root, err = statedb.Commit(vmenv.ChainConfig().IsEIP158(block.Number())) + if err != nil { + return StorageRangeResult{}, err + } + } + } + } + storageTrie := statedb.StorageTrie(address) + it := trie.NewIterator(storageTrie.NodeIterator(common.BigToHash((*big.Int)(begin)).Bytes())) + result := StorageRangeResult{Storage: make(map[common.Hash]SRItem)} + for i := 0; /*i < int(maxResults) && */ it.Next(); i++ { + if preimage := storageTrie.GetKey(it.Key); preimage != nil { + key := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(preimage)) + v, _, err := rlp.SplitString(it.Value) + if err != nil { + return StorageRangeResult{}, err + } + value := (*math.HexOrDecimal256)(big.NewInt(0).SetBytes(v)) + ks, _ := key.MarshalText() + vs, _ := value.MarshalText() + if len(ks)%2 != 0 { + ks = append(append(append([]byte{}, ks[:2]...), byte('0')), ks[2:]...) + } + if len(vs)%2 != 0 { + vs = append(append(append([]byte{}, vs[:2]...), byte('0')), vs[2:]...) + } + result.Storage[common.BytesToHash(it.Key)] = SRItem{ + Key: string(ks), + Value: string(vs), + } + //fmt.Printf("Key: %s, Value: %s\n", ks, vs) + } else { + //fmt.Printf("Did not find preimage for %x\n", it.Key) + } + } + if it.Next() { + result.Complete = false + } else { + result.Complete = true + } + return result, nil +} + +func (api *RetestethAPI) ClientVersion(ctx context.Context) (string, error) { + return "Geth-" + params.VersionWithCommit(gitCommit, gitDate), nil +} + +// splitAndTrim splits input separated by a comma +// and trims excessive white space from the substrings. +func splitAndTrim(input string) []string { + result := strings.Split(input, ",") + for i, r := range result { + result[i] = strings.TrimSpace(r) + } + return result +} + +func retesteth(ctx *cli.Context) error { + log.Info("Welcome to retesteth!") + // register signer API with server + var ( + extapiURL = "n/a" + ) + apiImpl := &RetestethAPI{} + var testApi RetestethTestAPI = apiImpl + var ethApi RetestethEthAPI = apiImpl + var debugApi RetestethDebugAPI = apiImpl + var web3Api RetestWeb3API = apiImpl + rpcAPI := []rpc.API{ + { + Namespace: "test", + Public: true, + Service: testApi, + Version: "1.0", + }, + { + Namespace: "eth", + Public: true, + Service: ethApi, + Version: "1.0", + }, + { + Namespace: "debug", + Public: true, + Service: debugApi, + Version: "1.0", + }, + { + Namespace: "web3", + Public: true, + Service: web3Api, + Version: "1.0", + }, + } + vhosts := splitAndTrim(ctx.GlobalString(utils.RPCVirtualHostsFlag.Name)) + cors := splitAndTrim(ctx.GlobalString(utils.RPCCORSDomainFlag.Name)) + + // start http server + httpEndpoint := fmt.Sprintf("%s:%d", ctx.GlobalString(utils.RPCListenAddrFlag.Name), ctx.Int(rpcPortFlag.Name)) + listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"test", "eth", "debug", "web3"}, cors, vhosts, rpc.DefaultHTTPTimeouts) + if err != nil { + utils.Fatalf("Could not start RPC api: %v", err) + } + extapiURL = fmt.Sprintf("http://%s", httpEndpoint) + log.Info("HTTP endpoint opened", "url", extapiURL) + + defer func() { + listener.Close() + log.Info("HTTP endpoint closed", "url", httpEndpoint) + }() + + abortChan := make(chan os.Signal) + signal.Notify(abortChan, os.Interrupt) + + sig := <-abortChan + log.Info("Exiting...", "signal", sig) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth_copypaste.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth_copypaste.go new file mode 100644 index 00000000..e2795af7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/retesteth_copypaste.go @@ -0,0 +1,148 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction +type RPCTransaction struct { + BlockHash common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex hexutil.Uint `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` +} + +// newRPCTransaction returns a transaction that will serialize to the RPC +// representation, with the given location metadata set (if available). +func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + v, r, s := tx.RawSignatureValues() + + result := &RPCTransaction{ + From: from, + Gas: hexutil.Uint64(tx.Gas()), + GasPrice: (*hexutil.Big)(tx.GasPrice()), + Hash: tx.Hash(), + Input: hexutil.Bytes(tx.Data()), + Nonce: hexutil.Uint64(tx.Nonce()), + To: tx.To(), + Value: (*hexutil.Big)(tx.Value()), + V: (*hexutil.Big)(v), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), + } + if blockHash != (common.Hash{}) { + result.BlockHash = blockHash + result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) + result.TransactionIndex = hexutil.Uint(index) + } + return result +} + +// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. +func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { + txs := b.Transactions() + if index >= uint64(len(txs)) { + return nil + } + return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) +} + +// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. +func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { + for idx, tx := range b.Transactions() { + if tx.Hash() == hash { + return newRPCTransactionFromBlockIndex(b, uint64(idx)) + } + } + return nil +} + +// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are +// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain +// transaction hashes. +func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { + head := b.Header() // copies the header once + fields := map[string]interface{}{ + "number": (*hexutil.Big)(head.Number), + "hash": b.Hash(), + "parentHash": head.ParentHash, + "nonce": head.Nonce, + "mixHash": head.MixDigest, + "sha3Uncles": head.UncleHash, + "logsBloom": head.Bloom, + "stateRoot": head.Root, + "miner": head.Coinbase, + "difficulty": (*hexutil.Big)(head.Difficulty), + "extraData": hexutil.Bytes(head.Extra), + "size": hexutil.Uint64(b.Size()), + "gasLimit": hexutil.Uint64(head.GasLimit), + "gasUsed": hexutil.Uint64(head.GasUsed), + "timestamp": hexutil.Uint64(head.Time), + "transactionsRoot": head.TxHash, + "receiptsRoot": head.ReceiptHash, + } + + if inclTx { + formatTx := func(tx *types.Transaction) (interface{}, error) { + return tx.Hash(), nil + } + if fullTx { + formatTx = func(tx *types.Transaction) (interface{}, error) { + return newRPCTransactionFromBlockHash(b, tx.Hash()), nil + } + } + txs := b.Transactions() + transactions := make([]interface{}, len(txs)) + var err error + for i, tx := range txs { + if transactions[i], err = formatTx(tx); err != nil { + return nil, err + } + } + fields["transactions"] = transactions + } + + uncles := b.Uncles() + uncleHashes := make([]common.Hash, len(uncles)) + for i, uncle := range uncles { + uncleHashes[i] = uncle.Hash() + } + fields["uncles"] = uncleHashes + + return fields, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/geth/usage.go b/vendor/github.com/ethereum/go-ethereum/cmd/geth/usage.go new file mode 100644 index 00000000..3ff7f884 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/geth/usage.go @@ -0,0 +1,365 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// Contains the geth command usage template and generator. + +package main + +import ( + "io" + "sort" + + "strings" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/internal/debug" + cli "gopkg.in/urfave/cli.v1" +) + +// AppHelpTemplate is the test template for the default, global app help topic. +var AppHelpTemplate = `NAME: + {{.App.Name}} - {{.App.Usage}} + + Copyright 2013-2019 The go-ethereum Authors + +USAGE: + {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} + {{if .App.Version}} +VERSION: + {{.App.Version}} + {{end}}{{if len .App.Authors}} +AUTHOR(S): + {{range .App.Authors}}{{ . }}{{end}} + {{end}}{{if .App.Commands}} +COMMANDS: + {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} + {{end}}{{end}}{{if .FlagGroups}} +{{range .FlagGroups}}{{.Name}} OPTIONS: + {{range .Flags}}{{.}} + {{end}} +{{end}}{{end}}{{if .App.Copyright }} +COPYRIGHT: + {{.App.Copyright}} + {{end}} +` + +// flagGroup is a collection of flags belonging to a single topic. +type flagGroup struct { + Name string + Flags []cli.Flag +} + +// AppHelpFlagGroups is the application flags, grouped by functionality. +var AppHelpFlagGroups = []flagGroup{ + { + Name: "ETHEREUM", + Flags: []cli.Flag{ + configFileFlag, + utils.DataDirFlag, + utils.AncientFlag, + utils.KeyStoreDirFlag, + utils.NoUSBFlag, + utils.SmartCardDaemonPathFlag, + utils.NetworkIdFlag, + utils.TestnetFlag, + utils.RinkebyFlag, + utils.GoerliFlag, + utils.SyncModeFlag, + utils.ExitWhenSyncedFlag, + utils.GCModeFlag, + utils.EthStatsURLFlag, + utils.IdentityFlag, + utils.LightServFlag, + utils.LightBandwidthInFlag, + utils.LightBandwidthOutFlag, + utils.LightPeersFlag, + utils.LightKDFFlag, + utils.WhitelistFlag, + }, + }, + { + Name: "DEVELOPER CHAIN", + Flags: []cli.Flag{ + utils.DeveloperFlag, + utils.DeveloperPeriodFlag, + }, + }, + { + Name: "ETHASH", + Flags: []cli.Flag{ + utils.EthashCacheDirFlag, + utils.EthashCachesInMemoryFlag, + utils.EthashCachesOnDiskFlag, + utils.EthashDatasetDirFlag, + utils.EthashDatasetsInMemoryFlag, + utils.EthashDatasetsOnDiskFlag, + }, + }, + //{ + // Name: "DASHBOARD", + // Flags: []cli.Flag{ + // utils.DashboardEnabledFlag, + // utils.DashboardAddrFlag, + // utils.DashboardPortFlag, + // utils.DashboardRefreshFlag, + // utils.DashboardAssetsFlag, + // }, + //}, + { + Name: "TRANSACTION POOL", + Flags: []cli.Flag{ + utils.TxPoolLocalsFlag, + utils.TxPoolNoLocalsFlag, + utils.TxPoolJournalFlag, + utils.TxPoolRejournalFlag, + utils.TxPoolPriceLimitFlag, + utils.TxPoolPriceBumpFlag, + utils.TxPoolAccountSlotsFlag, + utils.TxPoolGlobalSlotsFlag, + utils.TxPoolAccountQueueFlag, + utils.TxPoolGlobalQueueFlag, + utils.TxPoolLifetimeFlag, + }, + }, + { + Name: "PERFORMANCE TUNING", + Flags: []cli.Flag{ + utils.CacheFlag, + utils.CacheDatabaseFlag, + utils.CacheTrieFlag, + utils.CacheGCFlag, + utils.CacheNoPrefetchFlag, + }, + }, + { + Name: "ACCOUNT", + Flags: []cli.Flag{ + utils.UnlockedAccountFlag, + utils.PasswordFileFlag, + utils.ExternalSignerFlag, + utils.InsecureUnlockAllowedFlag, + }, + }, + { + Name: "API AND CONSOLE", + Flags: []cli.Flag{ + utils.RPCEnabledFlag, + utils.RPCListenAddrFlag, + utils.RPCPortFlag, + utils.RPCApiFlag, + utils.RPCGlobalGasCap, + utils.WSEnabledFlag, + utils.WSListenAddrFlag, + utils.WSPortFlag, + utils.WSApiFlag, + utils.WSAllowedOriginsFlag, + utils.IPCDisabledFlag, + utils.IPCPathFlag, + utils.RPCCORSDomainFlag, + utils.RPCVirtualHostsFlag, + utils.JSpathFlag, + utils.ExecFlag, + utils.PreloadJSFlag, + }, + }, + { + Name: "NETWORKING", + Flags: []cli.Flag{ + utils.BootnodesFlag, + utils.BootnodesV4Flag, + utils.BootnodesV5Flag, + utils.ListenPortFlag, + utils.MaxPeersFlag, + utils.MaxPendingPeersFlag, + utils.NATFlag, + utils.NoDiscoverFlag, + utils.DiscoveryV5Flag, + utils.NetrestrictFlag, + utils.NodeKeyFileFlag, + utils.NodeKeyHexFlag, + }, + }, + { + Name: "MINER", + Flags: []cli.Flag{ + utils.MiningEnabledFlag, + utils.MinerThreadsFlag, + utils.MinerNotifyFlag, + utils.MinerGasPriceFlag, + utils.MinerGasTargetFlag, + utils.MinerGasLimitFlag, + utils.MinerEtherbaseFlag, + utils.MinerExtraDataFlag, + utils.MinerRecommitIntervalFlag, + utils.MinerNoVerfiyFlag, + }, + }, + { + Name: "GAS PRICE ORACLE", + Flags: []cli.Flag{ + utils.GpoBlocksFlag, + utils.GpoPercentileFlag, + }, + }, + { + Name: "VIRTUAL MACHINE", + Flags: []cli.Flag{ + utils.VMEnableDebugFlag, + utils.EVMInterpreterFlag, + utils.EWASMInterpreterFlag, + }, + }, + { + Name: "LOGGING AND DEBUGGING", + Flags: append([]cli.Flag{ + utils.FakePoWFlag, + utils.NoCompactionFlag, + }, debug.Flags...), + }, + { + Name: "METRICS AND STATS", + Flags: metricsFlags, + }, + { + Name: "WHISPER (EXPERIMENTAL)", + Flags: whisperFlags, + }, + { + Name: "DEPRECATED", + Flags: []cli.Flag{ + utils.MinerLegacyThreadsFlag, + utils.MinerLegacyGasTargetFlag, + utils.MinerLegacyGasPriceFlag, + utils.MinerLegacyEtherbaseFlag, + utils.MinerLegacyExtraDataFlag, + }, + }, + { + Name: "STATE DIFF", + Flags: []cli.Flag{ + utils.StateDiffFlag, + utils.StateDiffPathsAndProofs, + utils.StateDiffIntermediateNodes, + utils.StateDiffStreamBlock, + utils.StateDiffWatchedAddresses, + }, + }, + { + Name: "MISC", + }, +} + +// byCategory sorts an array of flagGroup by Name in the order +// defined in AppHelpFlagGroups. +type byCategory []flagGroup + +func (a byCategory) Len() int { return len(a) } +func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byCategory) Less(i, j int) bool { + iCat, jCat := a[i].Name, a[j].Name + iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last + + for i, group := range AppHelpFlagGroups { + if iCat == group.Name { + iIdx = i + } + if jCat == group.Name { + jIdx = i + } + } + + return iIdx < jIdx +} + +func flagCategory(flag cli.Flag) string { + for _, category := range AppHelpFlagGroups { + for _, flg := range category.Flags { + if flg.GetName() == flag.GetName() { + return category.Name + } + } + } + return "MISC" +} + +func init() { + // Override the default app help template + cli.AppHelpTemplate = AppHelpTemplate + + // Define a one shot struct to pass to the usage template + type helpData struct { + App interface{} + FlagGroups []flagGroup + } + + // Override the default app help printer, but only for the global app help + originalHelpPrinter := cli.HelpPrinter + cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { + if tmpl == AppHelpTemplate { + // Iterate over all the flags and add any uncategorized ones + categorized := make(map[string]struct{}) + for _, group := range AppHelpFlagGroups { + for _, flag := range group.Flags { + categorized[flag.String()] = struct{}{} + } + } + var uncategorized []cli.Flag + for _, flag := range data.(*cli.App).Flags { + if _, ok := categorized[flag.String()]; !ok { + if strings.HasPrefix(flag.GetName(), "dashboard") { + continue + } + uncategorized = append(uncategorized, flag) + } + } + if len(uncategorized) > 0 { + // Append all ungategorized options to the misc group + miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) + AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) + + // Make sure they are removed afterwards + defer func() { + AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] + }() + } + // Render out custom usage screen + originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) + } else if tmpl == utils.CommandHelpTemplate { + // Iterate over all command specific flags and categorize them + categorized := make(map[string][]cli.Flag) + for _, flag := range data.(cli.Command).Flags { + if _, ok := categorized[flag.String()]; !ok { + categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) + } + } + + // sort to get a stable ordering + sorted := make([]flagGroup, 0, len(categorized)) + for cat, flgs := range categorized { + sorted = append(sorted, flagGroup{cat, flgs}) + } + sort.Sort(byCategory(sorted)) + + // add sorted array to data and render with default printer + originalHelpPrinter(w, tmpl, map[string]interface{}{ + "cmd": data, + "categorizedFlags": sorted, + }) + } else { + originalHelpPrinter(w, tmpl, data) + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go new file mode 100644 index 00000000..a3ee45ba --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go @@ -0,0 +1,314 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// Package utils contains internal helper functions for go-ethereum commands. +package utils + +import ( + "compress/gzip" + "fmt" + "io" + "os" + "os/signal" + "runtime" + "strings" + "syscall" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + importBatchSize = 2500 +) + +// Fatalf formats a message to standard error and exits the program. +// The message is also printed to standard output if standard error +// is redirected to a different file. +func Fatalf(format string, args ...interface{}) { + w := io.MultiWriter(os.Stdout, os.Stderr) + if runtime.GOOS == "windows" { + // The SameFile check below doesn't work on Windows. + // stdout is unlikely to get redirected though, so just print there. + w = os.Stdout + } else { + outf, _ := os.Stdout.Stat() + errf, _ := os.Stderr.Stat() + if outf != nil && errf != nil && os.SameFile(outf, errf) { + w = os.Stderr + } + } + fmt.Fprintf(w, "Fatal: "+format+"\n", args...) + os.Exit(1) +} + +func StartNode(stack *node.Node) { + if err := stack.Start(); err != nil { + Fatalf("Error starting protocol stack: %v", err) + } + go func() { + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(sigc) + <-sigc + log.Info("Got interrupt, shutting down...") + go stack.Stop() + for i := 10; i > 0; i-- { + <-sigc + if i > 1 { + log.Warn("Already shutting down, interrupt more to panic.", "times", i-1) + } + } + debug.Exit() // ensure trace and CPU profile data is flushed. + debug.LoudPanic("boom") + }() +} + +func ImportChain(chain *core.BlockChain, fn string) error { + // Watch for Ctrl-C while the import is running. + // If a signal is received, the import will stop at the next batch. + interrupt := make(chan os.Signal, 1) + stop := make(chan struct{}) + signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(interrupt) + defer close(interrupt) + go func() { + if _, ok := <-interrupt; ok { + log.Info("Interrupted during import, stopping at next batch") + } + close(stop) + }() + checkInterrupt := func() bool { + select { + case <-stop: + return true + default: + return false + } + } + + log.Info("Importing blockchain", "file", fn) + + // Open the file handle and potentially unwrap the gzip stream + fh, err := os.Open(fn) + if err != nil { + return err + } + defer fh.Close() + + var reader io.Reader = fh + if strings.HasSuffix(fn, ".gz") { + if reader, err = gzip.NewReader(reader); err != nil { + return err + } + } + stream := rlp.NewStream(reader, 0) + + // Run actual the import. + blocks := make(types.Blocks, importBatchSize) + n := 0 + for batch := 0; ; batch++ { + // Load a batch of RLP blocks. + if checkInterrupt() { + return fmt.Errorf("interrupted") + } + i := 0 + for ; i < importBatchSize; i++ { + var b types.Block + if err := stream.Decode(&b); err == io.EOF { + break + } else if err != nil { + return fmt.Errorf("at block %d: %v", n, err) + } + // don't import first block + if b.NumberU64() == 0 { + i-- + continue + } + blocks[i] = &b + n++ + } + if i == 0 { + break + } + // Import the batch. + if checkInterrupt() { + return fmt.Errorf("interrupted") + } + missing := missingBlocks(chain, blocks[:i]) + if len(missing) == 0 { + log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash()) + continue + } + if _, err := chain.InsertChain(missing); err != nil { + return fmt.Errorf("invalid block %d: %v", n, err) + } + } + return nil +} + +func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block { + head := chain.CurrentBlock() + for i, block := range blocks { + // If we're behind the chain head, only check block, state is available at head + if head.NumberU64() > block.NumberU64() { + if !chain.HasBlock(block.Hash(), block.NumberU64()) { + return blocks[i:] + } + continue + } + // If we're above the chain head, state availability is a must + if !chain.HasBlockAndState(block.Hash(), block.NumberU64()) { + return blocks[i:] + } + } + return nil +} + +// ExportChain exports a blockchain into the specified file, truncating any data +// already present in the file. +func ExportChain(blockchain *core.BlockChain, fn string) error { + log.Info("Exporting blockchain", "file", fn) + + // Open the file handle and potentially wrap with a gzip stream + fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) + if err != nil { + return err + } + defer fh.Close() + + var writer io.Writer = fh + if strings.HasSuffix(fn, ".gz") { + writer = gzip.NewWriter(writer) + defer writer.(*gzip.Writer).Close() + } + // Iterate over the blocks and export them + if err := blockchain.Export(writer); err != nil { + return err + } + log.Info("Exported blockchain", "file", fn) + + return nil +} + +// ExportAppendChain exports a blockchain into the specified file, appending to +// the file if data already exists in it. +func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, last uint64) error { + log.Info("Exporting blockchain", "file", fn) + + // Open the file handle and potentially wrap with a gzip stream + fh, err := os.OpenFile(fn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm) + if err != nil { + return err + } + defer fh.Close() + + var writer io.Writer = fh + if strings.HasSuffix(fn, ".gz") { + writer = gzip.NewWriter(writer) + defer writer.(*gzip.Writer).Close() + } + // Iterate over the blocks and export them + if err := blockchain.ExportN(writer, first, last); err != nil { + return err + } + log.Info("Exported blockchain to", "file", fn) + return nil +} + +// ImportPreimages imports a batch of exported hash preimages into the database. +func ImportPreimages(db ethdb.Database, fn string) error { + log.Info("Importing preimages", "file", fn) + + // Open the file handle and potentially unwrap the gzip stream + fh, err := os.Open(fn) + if err != nil { + return err + } + defer fh.Close() + + var reader io.Reader = fh + if strings.HasSuffix(fn, ".gz") { + if reader, err = gzip.NewReader(reader); err != nil { + return err + } + } + stream := rlp.NewStream(reader, 0) + + // Import the preimages in batches to prevent disk trashing + preimages := make(map[common.Hash][]byte) + + for { + // Read the next entry and ensure it's not junk + var blob []byte + + if err := stream.Decode(&blob); err != nil { + if err == io.EOF { + break + } + return err + } + // Accumulate the preimages and flush when enough ws gathered + preimages[crypto.Keccak256Hash(blob)] = common.CopyBytes(blob) + if len(preimages) > 1024 { + rawdb.WritePreimages(db, preimages) + preimages = make(map[common.Hash][]byte) + } + } + // Flush the last batch preimage data + if len(preimages) > 0 { + rawdb.WritePreimages(db, preimages) + } + return nil +} + +// ExportPreimages exports all known hash preimages into the specified file, +// truncating any data already present in the file. +func ExportPreimages(db ethdb.Database, fn string) error { + log.Info("Exporting preimages", "file", fn) + + // Open the file handle and potentially wrap with a gzip stream + fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) + if err != nil { + return err + } + defer fh.Close() + + var writer io.Writer = fh + if strings.HasSuffix(fn, ".gz") { + writer = gzip.NewWriter(writer) + defer writer.(*gzip.Writer).Close() + } + // Iterate over the preimages and export them + it := db.NewIteratorWithPrefix([]byte("secure-key-")) + defer it.Release() + + for it.Next() { + if err := rlp.Encode(writer, it.Value()); err != nil { + return err + } + } + log.Info("Exported preimages", "file", fn) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go b/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go new file mode 100644 index 00000000..9ace9be7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go @@ -0,0 +1,1758 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// Package utils contains internal helper functions for go-ethereum commands. +package utils + +import ( + "crypto/ecdsa" + "encoding/json" + "fmt" + "io/ioutil" + "math/big" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + cli "gopkg.in/urfave/cli.v1" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/dashboard" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/les" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" + + pcsclite "github.com/gballet/go-libpcsclite" +) + +var ( + CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} [arguments...] +{{if .cmd.Description}}{{.cmd.Description}} +{{end}}{{if .cmd.Subcommands}} +SUBCOMMANDS: + {{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} + {{end}}{{end}}{{if .categorizedFlags}} +{{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS: +{{range $categorized.Flags}}{{"\t"}}{{.}} +{{end}} +{{end}}{{end}}` +) + +func init() { + cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] + +VERSION: + {{.Version}} + +COMMANDS: + {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} + {{end}}{{if .Flags}} +GLOBAL OPTIONS: + {{range .Flags}}{{.}} + {{end}}{{end}} +` + + cli.CommandHelpTemplate = CommandHelpTemplate +} + +// NewApp creates an app with sane defaults. +func NewApp(gitCommit, gitDate, usage string) *cli.App { + app := cli.NewApp() + app.Name = filepath.Base(os.Args[0]) + app.Author = "" + //app.Authors = nil + app.Email = "" + app.Version = params.VersionWithCommit(gitCommit, gitDate) + app.Usage = usage + return app +} + +// These are all the command line flags we support. +// If you add to this list, please remember to include the +// flag in the appropriate command definition. +// +// The flags are defined here so their names and help texts +// are the same for all commands. + +var ( + // General settings + DataDirFlag = DirectoryFlag{ + Name: "datadir", + Usage: "Data directory for the databases and keystore", + Value: DirectoryString{node.DefaultDataDir()}, + } + AncientFlag = DirectoryFlag{ + Name: "datadir.ancient", + Usage: "Data directory for ancient chain segments (default = inside chaindata)", + } + KeyStoreDirFlag = DirectoryFlag{ + Name: "keystore", + Usage: "Directory for the keystore (default = inside the datadir)", + } + NoUSBFlag = cli.BoolFlag{ + Name: "nousb", + Usage: "Disables monitoring for and managing USB hardware wallets", + } + SmartCardDaemonPathFlag = cli.StringFlag{ + Name: "pcscdpath", + Usage: "Path to the smartcard daemon (pcscd) socket file", + Value: pcsclite.PCSCDSockName, + } + NetworkIdFlag = cli.Uint64Flag{ + Name: "networkid", + Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby)", + Value: eth.DefaultConfig.NetworkId, + } + TestnetFlag = cli.BoolFlag{ + Name: "testnet", + Usage: "Ropsten network: pre-configured proof-of-work test network", + } + RinkebyFlag = cli.BoolFlag{ + Name: "rinkeby", + Usage: "Rinkeby network: pre-configured proof-of-authority test network", + } + GoerliFlag = cli.BoolFlag{ + Name: "goerli", + Usage: "Görli network: pre-configured proof-of-authority test network", + } + ConstantinopleOverrideFlag = cli.Uint64Flag{ + Name: "override.constantinople", + Usage: "Manually specify constantinople fork-block, overriding the bundled setting", + } + DeveloperFlag = cli.BoolFlag{ + Name: "dev", + Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled", + } + DeveloperPeriodFlag = cli.IntFlag{ + Name: "dev.period", + Usage: "Block period to use in developer mode (0 = mine only if transaction pending)", + } + IdentityFlag = cli.StringFlag{ + Name: "identity", + Usage: "Custom node name", + } + DocRootFlag = DirectoryFlag{ + Name: "docroot", + Usage: "Document Root for HTTPClient file scheme", + Value: DirectoryString{homeDir()}, + } + ExitWhenSyncedFlag = cli.BoolFlag{ + Name: "exitwhensynced", + Usage: "Exits after block synchronisation completes", + } + ULCModeConfigFlag = cli.StringFlag{ + Name: "ulc.config", + Usage: "Config file to use for ultra light client mode", + } + OnlyAnnounceModeFlag = cli.BoolFlag{ + Name: "ulc.onlyannounce", + Usage: "ULC server sends announcements only", + } + ULCMinTrustedFractionFlag = cli.IntFlag{ + Name: "ulc.fraction", + Usage: "Minimum % of trusted ULC servers required to announce a new head", + } + ULCTrustedNodesFlag = cli.StringFlag{ + Name: "ulc.trusted", + Usage: "List of trusted ULC servers", + } + defaultSyncMode = eth.DefaultConfig.SyncMode + SyncModeFlag = TextMarshalerFlag{ + Name: "syncmode", + Usage: `Blockchain sync mode ("fast", "full", or "light")`, + Value: &defaultSyncMode, + } + GCModeFlag = cli.StringFlag{ + Name: "gcmode", + Usage: `Blockchain garbage collection mode ("full", "archive")`, + Value: "full", + } + LightServFlag = cli.IntFlag{ + Name: "lightserv", + Usage: "Maximum percentage of time allowed for serving LES requests (multi-threaded processing allows values over 100)", + Value: 0, + } + LightBandwidthInFlag = cli.IntFlag{ + Name: "lightbwin", + Usage: "Incoming bandwidth limit for light server (kilobytes/sec, 0 = unlimited)", + Value: 0, + } + LightBandwidthOutFlag = cli.IntFlag{ + Name: "lightbwout", + Usage: "Outgoing bandwidth limit for light server (kilobytes/sec, 0 = unlimited)", + Value: 0, + } + LightPeersFlag = cli.IntFlag{ + Name: "lightpeers", + Usage: "Maximum number of LES client peers", + Value: eth.DefaultConfig.LightPeers, + } + LightKDFFlag = cli.BoolFlag{ + Name: "lightkdf", + Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", + } + WhitelistFlag = cli.StringFlag{ + Name: "whitelist", + Usage: "Comma separated block number-to-hash mappings to enforce (=)", + } + // Dashboard settings + DashboardEnabledFlag = cli.BoolFlag{ + Name: "dashboard", + Usage: "Enable the dashboard", + } + DashboardAddrFlag = cli.StringFlag{ + Name: "dashboard.addr", + Usage: "Dashboard listening interface", + Value: dashboard.DefaultConfig.Host, + } + DashboardPortFlag = cli.IntFlag{ + Name: "dashboard.host", + Usage: "Dashboard listening port", + Value: dashboard.DefaultConfig.Port, + } + DashboardRefreshFlag = cli.DurationFlag{ + Name: "dashboard.refresh", + Usage: "Dashboard metrics collection refresh rate", + Value: dashboard.DefaultConfig.Refresh, + } + // Ethash settings + EthashCacheDirFlag = DirectoryFlag{ + Name: "ethash.cachedir", + Usage: "Directory to store the ethash verification caches (default = inside the datadir)", + } + EthashCachesInMemoryFlag = cli.IntFlag{ + Name: "ethash.cachesinmem", + Usage: "Number of recent ethash caches to keep in memory (16MB each)", + Value: eth.DefaultConfig.Ethash.CachesInMem, + } + EthashCachesOnDiskFlag = cli.IntFlag{ + Name: "ethash.cachesondisk", + Usage: "Number of recent ethash caches to keep on disk (16MB each)", + Value: eth.DefaultConfig.Ethash.CachesOnDisk, + } + EthashDatasetDirFlag = DirectoryFlag{ + Name: "ethash.dagdir", + Usage: "Directory to store the ethash mining DAGs (default = inside home folder)", + Value: DirectoryString{eth.DefaultConfig.Ethash.DatasetDir}, + } + EthashDatasetsInMemoryFlag = cli.IntFlag{ + Name: "ethash.dagsinmem", + Usage: "Number of recent ethash mining DAGs to keep in memory (1+GB each)", + Value: eth.DefaultConfig.Ethash.DatasetsInMem, + } + EthashDatasetsOnDiskFlag = cli.IntFlag{ + Name: "ethash.dagsondisk", + Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)", + Value: eth.DefaultConfig.Ethash.DatasetsOnDisk, + } + // Transaction pool settings + TxPoolLocalsFlag = cli.StringFlag{ + Name: "txpool.locals", + Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + } + TxPoolNoLocalsFlag = cli.BoolFlag{ + Name: "txpool.nolocals", + Usage: "Disables price exemptions for locally submitted transactions", + } + TxPoolJournalFlag = cli.StringFlag{ + Name: "txpool.journal", + Usage: "Disk journal for local transaction to survive node restarts", + Value: core.DefaultTxPoolConfig.Journal, + } + TxPoolRejournalFlag = cli.DurationFlag{ + Name: "txpool.rejournal", + Usage: "Time interval to regenerate the local transaction journal", + Value: core.DefaultTxPoolConfig.Rejournal, + } + TxPoolPriceLimitFlag = cli.Uint64Flag{ + Name: "txpool.pricelimit", + Usage: "Minimum gas price limit to enforce for acceptance into the pool", + Value: eth.DefaultConfig.TxPool.PriceLimit, + } + TxPoolPriceBumpFlag = cli.Uint64Flag{ + Name: "txpool.pricebump", + Usage: "Price bump percentage to replace an already existing transaction", + Value: eth.DefaultConfig.TxPool.PriceBump, + } + TxPoolAccountSlotsFlag = cli.Uint64Flag{ + Name: "txpool.accountslots", + Usage: "Minimum number of executable transaction slots guaranteed per account", + Value: eth.DefaultConfig.TxPool.AccountSlots, + } + TxPoolGlobalSlotsFlag = cli.Uint64Flag{ + Name: "txpool.globalslots", + Usage: "Maximum number of executable transaction slots for all accounts", + Value: eth.DefaultConfig.TxPool.GlobalSlots, + } + TxPoolAccountQueueFlag = cli.Uint64Flag{ + Name: "txpool.accountqueue", + Usage: "Maximum number of non-executable transaction slots permitted per account", + Value: eth.DefaultConfig.TxPool.AccountQueue, + } + TxPoolGlobalQueueFlag = cli.Uint64Flag{ + Name: "txpool.globalqueue", + Usage: "Maximum number of non-executable transaction slots for all accounts", + Value: eth.DefaultConfig.TxPool.GlobalQueue, + } + TxPoolLifetimeFlag = cli.DurationFlag{ + Name: "txpool.lifetime", + Usage: "Maximum amount of time non-executable transaction are queued", + Value: eth.DefaultConfig.TxPool.Lifetime, + } + // Performance tuning settings + CacheFlag = cli.IntFlag{ + Name: "cache", + Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node, 128 light mode)", + Value: 1024, + } + CacheDatabaseFlag = cli.IntFlag{ + Name: "cache.database", + Usage: "Percentage of cache memory allowance to use for database io", + Value: 50, + } + CacheTrieFlag = cli.IntFlag{ + Name: "cache.trie", + Usage: "Percentage of cache memory allowance to use for trie caching (default = 25% full mode, 50% archive mode)", + Value: 25, + } + CacheGCFlag = cli.IntFlag{ + Name: "cache.gc", + Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", + Value: 25, + } + CacheNoPrefetchFlag = cli.BoolFlag{ + Name: "cache.noprefetch", + Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", + } + // Miner settings + MiningEnabledFlag = cli.BoolFlag{ + Name: "mine", + Usage: "Enable mining", + } + MinerThreadsFlag = cli.IntFlag{ + Name: "miner.threads", + Usage: "Number of CPU threads to use for mining", + Value: 0, + } + MinerLegacyThreadsFlag = cli.IntFlag{ + Name: "minerthreads", + Usage: "Number of CPU threads to use for mining (deprecated, use --miner.threads)", + Value: 0, + } + MinerNotifyFlag = cli.StringFlag{ + Name: "miner.notify", + Usage: "Comma separated HTTP URL list to notify of new work packages", + } + MinerGasTargetFlag = cli.Uint64Flag{ + Name: "miner.gastarget", + Usage: "Target gas floor for mined blocks", + Value: eth.DefaultConfig.Miner.GasFloor, + } + MinerLegacyGasTargetFlag = cli.Uint64Flag{ + Name: "targetgaslimit", + Usage: "Target gas floor for mined blocks (deprecated, use --miner.gastarget)", + Value: eth.DefaultConfig.Miner.GasFloor, + } + MinerGasLimitFlag = cli.Uint64Flag{ + Name: "miner.gaslimit", + Usage: "Target gas ceiling for mined blocks", + Value: eth.DefaultConfig.Miner.GasCeil, + } + MinerGasPriceFlag = BigFlag{ + Name: "miner.gasprice", + Usage: "Minimum gas price for mining a transaction", + Value: eth.DefaultConfig.Miner.GasPrice, + } + MinerLegacyGasPriceFlag = BigFlag{ + Name: "gasprice", + Usage: "Minimum gas price for mining a transaction (deprecated, use --miner.gasprice)", + Value: eth.DefaultConfig.Miner.GasPrice, + } + MinerEtherbaseFlag = cli.StringFlag{ + Name: "miner.etherbase", + Usage: "Public address for block mining rewards (default = first account)", + Value: "0", + } + MinerLegacyEtherbaseFlag = cli.StringFlag{ + Name: "etherbase", + Usage: "Public address for block mining rewards (default = first account, deprecated, use --miner.etherbase)", + Value: "0", + } + MinerExtraDataFlag = cli.StringFlag{ + Name: "miner.extradata", + Usage: "Block extra data set by the miner (default = client version)", + } + MinerLegacyExtraDataFlag = cli.StringFlag{ + Name: "extradata", + Usage: "Block extra data set by the miner (default = client version, deprecated, use --miner.extradata)", + } + MinerRecommitIntervalFlag = cli.DurationFlag{ + Name: "miner.recommit", + Usage: "Time interval to recreate the block being mined", + Value: eth.DefaultConfig.Miner.Recommit, + } + MinerNoVerfiyFlag = cli.BoolFlag{ + Name: "miner.noverify", + Usage: "Disable remote sealing verification", + } + // Account settings + UnlockedAccountFlag = cli.StringFlag{ + Name: "unlock", + Usage: "Comma separated list of accounts to unlock", + Value: "", + } + PasswordFileFlag = cli.StringFlag{ + Name: "password", + Usage: "Password file to use for non-interactive password input", + Value: "", + } + ExternalSignerFlag = cli.StringFlag{ + Name: "signer", + Usage: "External signer (url or path to ipc file)", + Value: "", + } + VMEnableDebugFlag = cli.BoolFlag{ + Name: "vmdebug", + Usage: "Record information useful for VM and contract debugging", + } + InsecureUnlockAllowedFlag = cli.BoolFlag{ + Name: "allow-insecure-unlock", + Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", + } + RPCGlobalGasCap = cli.Uint64Flag{ + Name: "rpc.gascap", + Usage: "Sets a cap on gas that can be used in eth_call/estimateGas", + } + // Logging and debug settings + EthStatsURLFlag = cli.StringFlag{ + Name: "ethstats", + Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", + } + FakePoWFlag = cli.BoolFlag{ + Name: "fakepow", + Usage: "Disables proof-of-work verification", + } + NoCompactionFlag = cli.BoolFlag{ + Name: "nocompaction", + Usage: "Disables db compaction after import", + } + // RPC settings + RPCEnabledFlag = cli.BoolFlag{ + Name: "rpc", + Usage: "Enable the HTTP-RPC server", + } + RPCListenAddrFlag = cli.StringFlag{ + Name: "rpcaddr", + Usage: "HTTP-RPC server listening interface", + Value: node.DefaultHTTPHost, + } + RPCPortFlag = cli.IntFlag{ + Name: "rpcport", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort, + } + GraphQLEnabledFlag = cli.BoolFlag{ + Name: "graphql", + Usage: "Enable the GraphQL server", + } + GraphQLListenAddrFlag = cli.StringFlag{ + Name: "graphql.addr", + Usage: "GraphQL server listening interface", + Value: node.DefaultGraphQLHost, + } + GraphQLPortFlag = cli.IntFlag{ + Name: "graphql.port", + Usage: "GraphQL server listening port", + Value: node.DefaultGraphQLPort, + } + GraphQLCORSDomainFlag = cli.StringFlag{ + Name: "graphql.rpccorsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: "", + } + GraphQLVirtualHostsFlag = cli.StringFlag{ + Name: "graphql.rpcvhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","), + } + RPCCORSDomainFlag = cli.StringFlag{ + Name: "rpccorsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: "", + } + RPCVirtualHostsFlag = cli.StringFlag{ + Name: "rpcvhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","), + } + RPCApiFlag = cli.StringFlag{ + Name: "rpcapi", + Usage: "API's offered over the HTTP-RPC interface", + Value: "", + } + IPCDisabledFlag = cli.BoolFlag{ + Name: "ipcdisable", + Usage: "Disable the IPC-RPC server", + } + IPCPathFlag = DirectoryFlag{ + Name: "ipcpath", + Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", + } + WSEnabledFlag = cli.BoolFlag{ + Name: "ws", + Usage: "Enable the WS-RPC server", + } + WSListenAddrFlag = cli.StringFlag{ + Name: "wsaddr", + Usage: "WS-RPC server listening interface", + Value: node.DefaultWSHost, + } + WSPortFlag = cli.IntFlag{ + Name: "wsport", + Usage: "WS-RPC server listening port", + Value: node.DefaultWSPort, + } + WSApiFlag = cli.StringFlag{ + Name: "wsapi", + Usage: "API's offered over the WS-RPC interface", + Value: "", + } + WSAllowedOriginsFlag = cli.StringFlag{ + Name: "wsorigins", + Usage: "Origins from which to accept websockets requests", + Value: "", + } + ExecFlag = cli.StringFlag{ + Name: "exec", + Usage: "Execute JavaScript statement", + } + PreloadJSFlag = cli.StringFlag{ + Name: "preload", + Usage: "Comma separated list of JavaScript files to preload into the console", + } + + // Network Settings + MaxPeersFlag = cli.IntFlag{ + Name: "maxpeers", + Usage: "Maximum number of network peers (network disabled if set to 0)", + Value: node.DefaultConfig.P2P.MaxPeers, + } + MaxPendingPeersFlag = cli.IntFlag{ + Name: "maxpendpeers", + Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", + Value: node.DefaultConfig.P2P.MaxPendingPeers, + } + ListenPortFlag = cli.IntFlag{ + Name: "port", + Usage: "Network listening port", + Value: 30303, + } + BootnodesFlag = cli.StringFlag{ + Name: "bootnodes", + Usage: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)", + Value: "", + } + BootnodesV4Flag = cli.StringFlag{ + Name: "bootnodesv4", + Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)", + Value: "", + } + BootnodesV5Flag = cli.StringFlag{ + Name: "bootnodesv5", + Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)", + Value: "", + } + NodeKeyFileFlag = cli.StringFlag{ + Name: "nodekey", + Usage: "P2P node key file", + } + NodeKeyHexFlag = cli.StringFlag{ + Name: "nodekeyhex", + Usage: "P2P node key as hex (for testing)", + } + NATFlag = cli.StringFlag{ + Name: "nat", + Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)", + Value: "any", + } + NoDiscoverFlag = cli.BoolFlag{ + Name: "nodiscover", + Usage: "Disables the peer discovery mechanism (manual peer addition)", + } + DiscoveryV5Flag = cli.BoolFlag{ + Name: "v5disc", + Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", + } + NetrestrictFlag = cli.StringFlag{ + Name: "netrestrict", + Usage: "Restricts network communication to the given IP networks (CIDR masks)", + } + + // ATM the url is left to the user and deployment to + JSpathFlag = cli.StringFlag{ + Name: "jspath", + Usage: "JavaScript root path for `loadScript`", + Value: ".", + } + + // Gas price oracle settings + GpoBlocksFlag = cli.IntFlag{ + Name: "gpoblocks", + Usage: "Number of recent blocks to check for gas prices", + Value: eth.DefaultConfig.GPO.Blocks, + } + GpoPercentileFlag = cli.IntFlag{ + Name: "gpopercentile", + Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", + Value: eth.DefaultConfig.GPO.Percentile, + } + WhisperEnabledFlag = cli.BoolFlag{ + Name: "shh", + Usage: "Enable Whisper", + } + WhisperMaxMessageSizeFlag = cli.IntFlag{ + Name: "shh.maxmessagesize", + Usage: "Max message size accepted", + Value: int(whisper.DefaultMaxMessageSize), + } + WhisperMinPOWFlag = cli.Float64Flag{ + Name: "shh.pow", + Usage: "Minimum POW accepted", + Value: whisper.DefaultMinimumPoW, + } + WhisperRestrictConnectionBetweenLightClientsFlag = cli.BoolFlag{ + Name: "shh.restrict-light", + Usage: "Restrict connection between two whisper light clients", + } + + // Metrics flags + MetricsEnabledFlag = cli.BoolFlag{ + Name: "metrics", + Usage: "Enable metrics collection and reporting", + } + MetricsEnabledExpensiveFlag = cli.BoolFlag{ + Name: "metrics.expensive", + Usage: "Enable expensive metrics collection and reporting", + } + MetricsEnableInfluxDBFlag = cli.BoolFlag{ + Name: "metrics.influxdb", + Usage: "Enable metrics export/push to an external InfluxDB database", + } + MetricsInfluxDBEndpointFlag = cli.StringFlag{ + Name: "metrics.influxdb.endpoint", + Usage: "InfluxDB API endpoint to report metrics to", + Value: "http://localhost:8086", + } + MetricsInfluxDBDatabaseFlag = cli.StringFlag{ + Name: "metrics.influxdb.database", + Usage: "InfluxDB database name to push reported metrics to", + Value: "geth", + } + MetricsInfluxDBUsernameFlag = cli.StringFlag{ + Name: "metrics.influxdb.username", + Usage: "Username to authorize access to the database", + Value: "test", + } + MetricsInfluxDBPasswordFlag = cli.StringFlag{ + Name: "metrics.influxdb.password", + Usage: "Password to authorize access to the database", + Value: "test", + } + // Tags are part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB. + // For example `host` tag could be used so that we can group all nodes and average a measurement + // across all of them, but also so that we can select a specific node and inspect its measurements. + // https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key + MetricsInfluxDBTagsFlag = cli.StringFlag{ + Name: "metrics.influxdb.tags", + Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", + Value: "host=localhost", + } + + EWASMInterpreterFlag = cli.StringFlag{ + Name: "vm.ewasm", + Usage: "External ewasm configuration (default = built-in interpreter)", + Value: "", + } + EVMInterpreterFlag = cli.StringFlag{ + Name: "vm.evm", + Usage: "External EVM configuration (default = built-in interpreter)", + Value: "", + } + + StateDiffFlag = cli.BoolFlag{ + Name: "statediff", + Usage: "Enables the calculation of state diffs between each block, persists these state diffs the configured persistence mode.", + } + StateDiffPathsAndProofs = cli.BoolFlag{ + Name: "statediff.pathsandproofs", + Usage: "Set to true to generate paths and proof sets for diffed state and storage trie leaf nodes", + } + StateDiffIntermediateNodes = cli.BoolFlag{ + Name: "statediff.intermediatenodes", + Usage: "Set to include intermediate (branch and extension) nodes; default (false) processes leaf nodes only", + } + StateDiffStreamBlock = cli.BoolFlag{ + Name: "statediff.streamblock", + Usage: "Set to true to stream the block data alongside state diff data in the same subscription payload", + } + StateDiffWatchedAddresses = cli.StringSliceFlag{ + Name: "statediff.watchedaddresses", + Usage: "If provided, state diffing process is restricted to these addresses", + } +) + +// MakeDataDir retrieves the currently requested data directory, terminating +// if none (or the empty string) is specified. If the node is starting a testnet, +// the a subdirectory of the specified datadir will be used. +func MakeDataDir(ctx *cli.Context) string { + if path := ctx.GlobalString(DataDirFlag.Name); path != "" { + if ctx.GlobalBool(TestnetFlag.Name) { + return filepath.Join(path, "testnet") + } + if ctx.GlobalBool(RinkebyFlag.Name) { + return filepath.Join(path, "rinkeby") + } + if ctx.GlobalBool(GoerliFlag.Name) { + return filepath.Join(path, "goerli") + } + return path + } + Fatalf("Cannot determine default data directory, please set manually (--datadir)") + return "" +} + +// setNodeKey creates a node key from set command line flags, either loading it +// from a file or as a specified hex value. If neither flags were provided, this +// method returns nil and an emphemeral key is to be generated. +func setNodeKey(ctx *cli.Context, cfg *p2p.Config) { + var ( + hex = ctx.GlobalString(NodeKeyHexFlag.Name) + file = ctx.GlobalString(NodeKeyFileFlag.Name) + key *ecdsa.PrivateKey + err error + ) + switch { + case file != "" && hex != "": + Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name) + case file != "": + if key, err = crypto.LoadECDSA(file); err != nil { + Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err) + } + cfg.PrivateKey = key + case hex != "": + if key, err = crypto.HexToECDSA(hex); err != nil { + Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err) + } + cfg.PrivateKey = key + } +} + +// setNodeUserIdent creates the user identifier from CLI flags. +func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) { + if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 { + cfg.UserIdent = identity + } +} + +// setBootstrapNodes creates a list of bootstrap nodes from the command line +// flags, reverting to pre-configured ones if none have been specified. +func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { + urls := params.MainnetBootnodes + switch { + case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name): + if ctx.GlobalIsSet(BootnodesV4Flag.Name) { + urls = strings.Split(ctx.GlobalString(BootnodesV4Flag.Name), ",") + } else { + urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",") + } + case ctx.GlobalBool(TestnetFlag.Name): + urls = params.TestnetBootnodes + case ctx.GlobalBool(RinkebyFlag.Name): + urls = params.RinkebyBootnodes + case ctx.GlobalBool(GoerliFlag.Name): + urls = params.GoerliBootnodes + case cfg.BootstrapNodes != nil: + return // already set, don't apply defaults. + } + + cfg.BootstrapNodes = make([]*enode.Node, 0, len(urls)) + for _, url := range urls { + if url != "" { + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + log.Crit("Bootstrap URL invalid", "enode", url, "err", err) + continue + } + cfg.BootstrapNodes = append(cfg.BootstrapNodes, node) + } + } +} + +// setBootstrapNodesV5 creates a list of bootstrap nodes from the command line +// flags, reverting to pre-configured ones if none have been specified. +func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { + urls := params.DiscoveryV5Bootnodes + switch { + case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name): + if ctx.GlobalIsSet(BootnodesV5Flag.Name) { + urls = strings.Split(ctx.GlobalString(BootnodesV5Flag.Name), ",") + } else { + urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",") + } + case ctx.GlobalBool(RinkebyFlag.Name): + urls = params.RinkebyBootnodes + case ctx.GlobalBool(GoerliFlag.Name): + urls = params.GoerliBootnodes + case cfg.BootstrapNodesV5 != nil: + return // already set, don't apply defaults. + } + + cfg.BootstrapNodesV5 = make([]*discv5.Node, 0, len(urls)) + for _, url := range urls { + if url != "" { + node, err := discv5.ParseNode(url) + if err != nil { + log.Error("Bootstrap URL invalid", "enode", url, "err", err) + continue + } + cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node) + } + } +} + +// setListenAddress creates a TCP listening address string from set command +// line flags. +func setListenAddress(ctx *cli.Context, cfg *p2p.Config) { + if ctx.GlobalIsSet(ListenPortFlag.Name) { + cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name)) + } +} + +// setNAT creates a port mapper from command line flags. +func setNAT(ctx *cli.Context, cfg *p2p.Config) { + if ctx.GlobalIsSet(NATFlag.Name) { + natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name)) + if err != nil { + Fatalf("Option %s: %v", NATFlag.Name, err) + } + cfg.NAT = natif + } +} + +// splitAndTrim splits input separated by a comma +// and trims excessive white space from the substrings. +func splitAndTrim(input string) []string { + result := strings.Split(input, ",") + for i, r := range result { + result[i] = strings.TrimSpace(r) + } + return result +} + +// setHTTP creates the HTTP RPC listener interface string from the set +// command line flags, returning empty if the HTTP endpoint is disabled. +func setHTTP(ctx *cli.Context, cfg *node.Config) { + if ctx.GlobalBool(RPCEnabledFlag.Name) && cfg.HTTPHost == "" { + cfg.HTTPHost = "127.0.0.1" + if ctx.GlobalIsSet(RPCListenAddrFlag.Name) { + cfg.HTTPHost = ctx.GlobalString(RPCListenAddrFlag.Name) + } + } + + if ctx.GlobalIsSet(RPCPortFlag.Name) { + cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name) + } + if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) { + cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name)) + } + if ctx.GlobalIsSet(RPCApiFlag.Name) { + cfg.HTTPModules = splitAndTrim(ctx.GlobalString(RPCApiFlag.Name)) + } + if ctx.GlobalIsSet(RPCVirtualHostsFlag.Name) { + cfg.HTTPVirtualHosts = splitAndTrim(ctx.GlobalString(RPCVirtualHostsFlag.Name)) + } +} + +// setGraphQL creates the GraphQL listener interface string from the set +// command line flags, returning empty if the GraphQL endpoint is disabled. +func setGraphQL(ctx *cli.Context, cfg *node.Config) { + if ctx.GlobalBool(GraphQLEnabledFlag.Name) && cfg.GraphQLHost == "" { + cfg.GraphQLHost = "127.0.0.1" + if ctx.GlobalIsSet(GraphQLListenAddrFlag.Name) { + cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.Name) + } + } + cfg.GraphQLPort = ctx.GlobalInt(GraphQLPortFlag.Name) + if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) { + cfg.GraphQLCors = splitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name)) + } + if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) { + cfg.GraphQLVirtualHosts = splitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name)) + } +} + +// setWS creates the WebSocket RPC listener interface string from the set +// command line flags, returning empty if the HTTP endpoint is disabled. +func setWS(ctx *cli.Context, cfg *node.Config) { + if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" { + cfg.WSHost = "127.0.0.1" + if ctx.GlobalIsSet(WSListenAddrFlag.Name) { + cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name) + } + } + + if ctx.GlobalIsSet(WSPortFlag.Name) { + cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name) + } + if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) { + cfg.WSOrigins = splitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name)) + } + if ctx.GlobalIsSet(WSApiFlag.Name) { + cfg.WSModules = splitAndTrim(ctx.GlobalString(WSApiFlag.Name)) + } + if ctx.GlobalBool(StateDiffFlag.Name) { + cfg.WSModules = append(cfg.WSModules, "statediff") + } +} + +// setIPC creates an IPC path configuration from the set command line flags, +// returning an empty string if IPC was explicitly disabled, or the set path. +func setIPC(ctx *cli.Context, cfg *node.Config) { + checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag) + switch { + case ctx.GlobalBool(IPCDisabledFlag.Name): + cfg.IPCPath = "" + case ctx.GlobalIsSet(IPCPathFlag.Name): + cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name) + } +} + +// SetULC setup ULC config from file if given. +func SetULC(ctx *cli.Context, cfg *eth.Config) { + // ULC config isn't loaded from global config and ULC config and ULC trusted nodes are not defined. + if cfg.ULC == nil && !(ctx.GlobalIsSet(ULCModeConfigFlag.Name) || ctx.GlobalIsSet(ULCTrustedNodesFlag.Name)) { + return + } + cfg.ULC = ð.ULCConfig{} + + path := ctx.GlobalString(ULCModeConfigFlag.Name) + if path != "" { + cfgData, err := ioutil.ReadFile(path) + if err != nil { + Fatalf("Failed to unmarshal ULC configuration: %v", err) + } + + err = json.Unmarshal(cfgData, &cfg.ULC) + if err != nil { + Fatalf("Failed to unmarshal ULC configuration: %s", err.Error()) + } + } + + if trustedNodes := ctx.GlobalString(ULCTrustedNodesFlag.Name); trustedNodes != "" { + cfg.ULC.TrustedServers = strings.Split(trustedNodes, ",") + } + + if trustedFraction := ctx.GlobalInt(ULCMinTrustedFractionFlag.Name); trustedFraction > 0 { + cfg.ULC.MinTrustedFraction = trustedFraction + } + if cfg.ULC.MinTrustedFraction <= 0 && cfg.ULC.MinTrustedFraction > 100 { + log.Error("MinTrustedFraction is invalid", "MinTrustedFraction", cfg.ULC.MinTrustedFraction, "Changed to default", eth.DefaultULCMinTrustedFraction) + cfg.ULC.MinTrustedFraction = eth.DefaultULCMinTrustedFraction + } +} + +// makeDatabaseHandles raises out the number of allowed file handles per process +// for Geth and returns half of the allowance to assign to the database. +func makeDatabaseHandles() int { + limit, err := fdlimit.Maximum() + if err != nil { + Fatalf("Failed to retrieve file descriptor allowance: %v", err) + } + raised, err := fdlimit.Raise(uint64(limit)) + if err != nil { + Fatalf("Failed to raise file descriptor allowance: %v", err) + } + return int(raised / 2) // Leave half for networking and other stuff +} + +// MakeAddress converts an account specified directly as a hex encoded string or +// a key index in the key store to an internal account representation. +func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) { + // If the specified account is a valid address, return it + if common.IsHexAddress(account) { + return accounts.Account{Address: common.HexToAddress(account)}, nil + } + // Otherwise try to interpret the account as a keystore index + index, err := strconv.Atoi(account) + if err != nil || index < 0 { + return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account) + } + log.Warn("-------------------------------------------------------------------") + log.Warn("Referring to accounts by order in the keystore folder is dangerous!") + log.Warn("This functionality is deprecated and will be removed in the future!") + log.Warn("Please use explicit addresses! (can search via `geth account list`)") + log.Warn("-------------------------------------------------------------------") + + accs := ks.Accounts() + if len(accs) <= index { + return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs)) + } + return accs[index], nil +} + +// setEtherbase retrieves the etherbase either from the directly specified +// command line flags or from the keystore if CLI indexed. +func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) { + // Extract the current etherbase, new flag overriding legacy one + var etherbase string + if ctx.GlobalIsSet(MinerLegacyEtherbaseFlag.Name) { + etherbase = ctx.GlobalString(MinerLegacyEtherbaseFlag.Name) + } + if ctx.GlobalIsSet(MinerEtherbaseFlag.Name) { + etherbase = ctx.GlobalString(MinerEtherbaseFlag.Name) + } + // Convert the etherbase into an address and configure it + if etherbase != "" { + if ks != nil { + account, err := MakeAddress(ks, etherbase) + if err != nil { + Fatalf("Invalid miner etherbase: %v", err) + } + cfg.Miner.Etherbase = account.Address + } else { + Fatalf("No etherbase configured") + } + } +} + +// MakePasswordList reads password lines from the file specified by the global --password flag. +func MakePasswordList(ctx *cli.Context) []string { + path := ctx.GlobalString(PasswordFileFlag.Name) + if path == "" { + return nil + } + text, err := ioutil.ReadFile(path) + if err != nil { + Fatalf("Failed to read password file: %v", err) + } + lines := strings.Split(string(text), "\n") + // Sanitise DOS line endings. + for i := range lines { + lines[i] = strings.TrimRight(lines[i], "\r") + } + return lines +} + +func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { + setNodeKey(ctx, cfg) + setNAT(ctx, cfg) + setListenAddress(ctx, cfg) + setBootstrapNodes(ctx, cfg) + setBootstrapNodesV5(ctx, cfg) + + lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light" + lightServer := ctx.GlobalInt(LightServFlag.Name) != 0 + lightPeers := ctx.GlobalInt(LightPeersFlag.Name) + + if ctx.GlobalIsSet(MaxPeersFlag.Name) { + cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name) + if lightServer && !ctx.GlobalIsSet(LightPeersFlag.Name) { + cfg.MaxPeers += lightPeers + } + } else { + if lightServer { + cfg.MaxPeers += lightPeers + } + if lightClient && ctx.GlobalIsSet(LightPeersFlag.Name) && cfg.MaxPeers < lightPeers { + cfg.MaxPeers = lightPeers + } + } + if !(lightClient || lightServer) { + lightPeers = 0 + } + ethPeers := cfg.MaxPeers - lightPeers + if lightClient { + ethPeers = 0 + } + log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers) + + if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) { + cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name) + } + if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient { + cfg.NoDiscovery = true + } + + // if we're running a light client or server, force enable the v5 peer discovery + // unless it is explicitly disabled with --nodiscover note that explicitly specifying + // --v5disc overrides --nodiscover, in which case the later only disables v4 discovery + forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name) + if ctx.GlobalIsSet(DiscoveryV5Flag.Name) { + cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name) + } else if forceV5Discovery { + cfg.DiscoveryV5 = true + } + + if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" { + list, err := netutil.ParseNetlist(netrestrict) + if err != nil { + Fatalf("Option %q: %v", NetrestrictFlag.Name, err) + } + cfg.NetRestrict = list + } + + if ctx.GlobalBool(DeveloperFlag.Name) { + // --dev mode can't use p2p networking. + cfg.MaxPeers = 0 + cfg.ListenAddr = ":0" + cfg.NoDiscovery = true + cfg.DiscoveryV5 = false + } +} + +// SetNodeConfig applies node-related command line flags to the config. +func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { + SetP2PConfig(ctx, &cfg.P2P) + setIPC(ctx, cfg) + setHTTP(ctx, cfg) + setGraphQL(ctx, cfg) + setWS(ctx, cfg) + setNodeUserIdent(ctx, cfg) + setDataDir(ctx, cfg) + setSmartCard(ctx, cfg) + + if ctx.GlobalIsSet(ExternalSignerFlag.Name) { + cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name) + } + + if ctx.GlobalIsSet(KeyStoreDirFlag.Name) { + cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name) + } + if ctx.GlobalIsSet(LightKDFFlag.Name) { + cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name) + } + if ctx.GlobalIsSet(NoUSBFlag.Name) { + cfg.NoUSB = ctx.GlobalBool(NoUSBFlag.Name) + } + if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { + cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) + } +} + +func setSmartCard(ctx *cli.Context, cfg *node.Config) { + // Skip enabling smartcards if no path is set + path := ctx.GlobalString(SmartCardDaemonPathFlag.Name) + if path == "" { + return + } + // Sanity check that the smartcard path is valid + fi, err := os.Stat(path) + if err != nil { + log.Info("Smartcard socket not found, disabling", "err", err) + return + } + if fi.Mode()&os.ModeType != os.ModeSocket { + log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String()) + return + } + // Smartcard daemon path exists and is a socket, enable it + cfg.SmartCardDaemonPath = path +} + +func setDataDir(ctx *cli.Context, cfg *node.Config) { + switch { + case ctx.GlobalIsSet(DataDirFlag.Name): + cfg.DataDir = ctx.GlobalString(DataDirFlag.Name) + case ctx.GlobalBool(DeveloperFlag.Name): + cfg.DataDir = "" // unless explicitly requested, use memory databases + case ctx.GlobalBool(TestnetFlag.Name): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet") + case ctx.GlobalBool(RinkebyFlag.Name): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby") + case ctx.GlobalBool(GoerliFlag.Name): + cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli") + } +} + +func setGPO(ctx *cli.Context, cfg *gasprice.Config) { + if ctx.GlobalIsSet(GpoBlocksFlag.Name) { + cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name) + } + if ctx.GlobalIsSet(GpoPercentileFlag.Name) { + cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name) + } +} + +func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { + if ctx.GlobalIsSet(TxPoolLocalsFlag.Name) { + locals := strings.Split(ctx.GlobalString(TxPoolLocalsFlag.Name), ",") + for _, account := range locals { + if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) { + Fatalf("Invalid account in --txpool.locals: %s", trimmed) + } else { + cfg.Locals = append(cfg.Locals, common.HexToAddress(account)) + } + } + } + if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) { + cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name) + } + if ctx.GlobalIsSet(TxPoolJournalFlag.Name) { + cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name) + } + if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) { + cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name) + } + if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) { + cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name) + } + if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) { + cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name) + } + if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) { + cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name) + } + if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) { + cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name) + } + if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) { + cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name) + } + if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) { + cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name) + } + if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) { + cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name) + } +} + +func setEthash(ctx *cli.Context, cfg *eth.Config) { + if ctx.GlobalIsSet(EthashCacheDirFlag.Name) { + cfg.Ethash.CacheDir = ctx.GlobalString(EthashCacheDirFlag.Name) + } + if ctx.GlobalIsSet(EthashDatasetDirFlag.Name) { + cfg.Ethash.DatasetDir = ctx.GlobalString(EthashDatasetDirFlag.Name) + } + if ctx.GlobalIsSet(EthashCachesInMemoryFlag.Name) { + cfg.Ethash.CachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name) + } + if ctx.GlobalIsSet(EthashCachesOnDiskFlag.Name) { + cfg.Ethash.CachesOnDisk = ctx.GlobalInt(EthashCachesOnDiskFlag.Name) + } + if ctx.GlobalIsSet(EthashDatasetsInMemoryFlag.Name) { + cfg.Ethash.DatasetsInMem = ctx.GlobalInt(EthashDatasetsInMemoryFlag.Name) + } + if ctx.GlobalIsSet(EthashDatasetsOnDiskFlag.Name) { + cfg.Ethash.DatasetsOnDisk = ctx.GlobalInt(EthashDatasetsOnDiskFlag.Name) + } +} + +func setMiner(ctx *cli.Context, cfg *miner.Config) { + if ctx.GlobalIsSet(MinerNotifyFlag.Name) { + cfg.Notify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",") + } + if ctx.GlobalIsSet(MinerLegacyExtraDataFlag.Name) { + cfg.ExtraData = []byte(ctx.GlobalString(MinerLegacyExtraDataFlag.Name)) + } + if ctx.GlobalIsSet(MinerExtraDataFlag.Name) { + cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name)) + } + if ctx.GlobalIsSet(MinerLegacyGasTargetFlag.Name) { + cfg.GasFloor = ctx.GlobalUint64(MinerLegacyGasTargetFlag.Name) + } + if ctx.GlobalIsSet(MinerGasTargetFlag.Name) { + cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name) + } + if ctx.GlobalIsSet(MinerGasLimitFlag.Name) { + cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name) + } + if ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) { + cfg.GasPrice = GlobalBig(ctx, MinerLegacyGasPriceFlag.Name) + } + if ctx.GlobalIsSet(MinerGasPriceFlag.Name) { + cfg.GasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name) + } + if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) { + cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) + } + if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) { + cfg.Noverify = ctx.Bool(MinerNoVerfiyFlag.Name) + } +} + +func setWhitelist(ctx *cli.Context, cfg *eth.Config) { + whitelist := ctx.GlobalString(WhitelistFlag.Name) + if whitelist == "" { + return + } + cfg.Whitelist = make(map[uint64]common.Hash) + for _, entry := range strings.Split(whitelist, ",") { + parts := strings.Split(entry, "=") + if len(parts) != 2 { + Fatalf("Invalid whitelist entry: %s", entry) + } + number, err := strconv.ParseUint(parts[0], 0, 64) + if err != nil { + Fatalf("Invalid whitelist block number %s: %v", parts[0], err) + } + var hash common.Hash + if err = hash.UnmarshalText([]byte(parts[1])); err != nil { + Fatalf("Invalid whitelist hash %s: %v", parts[1], err) + } + cfg.Whitelist[number] = hash + } +} + +// checkExclusive verifies that only a single instance of the provided flags was +// set by the user. Each flag might optionally be followed by a string type to +// specialize it further. +func checkExclusive(ctx *cli.Context, args ...interface{}) { + set := make([]string, 0, 1) + for i := 0; i < len(args); i++ { + // Make sure the next argument is a flag and skip if not set + flag, ok := args[i].(cli.Flag) + if !ok { + panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i])) + } + // Check if next arg extends current and expand its name if so + name := flag.GetName() + + if i+1 < len(args) { + switch option := args[i+1].(type) { + case string: + // Extended flag check, make sure value set doesn't conflict with passed in option + if ctx.GlobalString(flag.GetName()) == option { + name += "=" + option + set = append(set, "--"+name) + } + // shift arguments and continue + i++ + continue + + case cli.Flag: + default: + panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1])) + } + } + // Mark the flag if it's set + if ctx.GlobalIsSet(flag.GetName()) { + set = append(set, "--"+name) + } + } + if len(set) > 1 { + Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", ")) + } +} + +// SetShhConfig applies shh-related command line flags to the config. +func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) { + if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) { + cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name)) + } + if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) { + cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name) + } + if ctx.GlobalIsSet(WhisperRestrictConnectionBetweenLightClientsFlag.Name) { + cfg.RestrictConnectionBetweenLightClients = true + } +} + +// SetEthConfig applies eth-related command line flags to the config. +func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { + // Avoid conflicting network flags + checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag, GoerliFlag) + checkExclusive(ctx, LightServFlag, SyncModeFlag, "light") + // Can't use both ephemeral unlocked and external signer + checkExclusive(ctx, DeveloperFlag, ExternalSignerFlag) + var ks *keystore.KeyStore + if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 { + ks = keystores[0].(*keystore.KeyStore) + } + setEtherbase(ctx, ks, cfg) + setGPO(ctx, &cfg.GPO) + setTxPool(ctx, &cfg.TxPool) + setEthash(ctx, cfg) + setMiner(ctx, &cfg.Miner) + setWhitelist(ctx, cfg) + + if ctx.GlobalIsSet(SyncModeFlag.Name) { + cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) + } + if ctx.GlobalIsSet(LightServFlag.Name) { + cfg.LightServ = ctx.GlobalInt(LightServFlag.Name) + } + cfg.LightBandwidthIn = ctx.GlobalInt(LightBandwidthInFlag.Name) + cfg.LightBandwidthOut = ctx.GlobalInt(LightBandwidthOutFlag.Name) + if ctx.GlobalIsSet(LightPeersFlag.Name) { + cfg.LightPeers = ctx.GlobalInt(LightPeersFlag.Name) + } + if ctx.GlobalIsSet(OnlyAnnounceModeFlag.Name) { + cfg.OnlyAnnounce = ctx.GlobalBool(OnlyAnnounceModeFlag.Name) + } + if ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name) + } + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { + cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 + } + cfg.DatabaseHandles = makeDatabaseHandles() + if ctx.GlobalIsSet(AncientFlag.Name) { + cfg.DatabaseFreezer = ctx.GlobalString(AncientFlag.Name) + } + + if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { + Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) + } + cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive" + cfg.NoPrefetch = ctx.GlobalBool(CacheNoPrefetchFlag.Name) + + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) { + cfg.TrieCleanCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100 + } + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { + cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 + } + if ctx.GlobalIsSet(DocRootFlag.Name) { + cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name) + } + if ctx.GlobalIsSet(VMEnableDebugFlag.Name) { + // TODO(fjl): force-enable this in --dev mode + cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) + } + + if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) { + cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name) + } + + if ctx.GlobalIsSet(EVMInterpreterFlag.Name) { + cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name) + } + if ctx.GlobalIsSet(RPCGlobalGasCap.Name) { + cfg.RPCGasCap = new(big.Int).SetUint64(ctx.GlobalUint64(RPCGlobalGasCap.Name)) + } + + // Override any default configs for hard coded networks. + switch { + case ctx.GlobalBool(TestnetFlag.Name): + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 3 + } + cfg.Genesis = core.DefaultTestnetGenesisBlock() + case ctx.GlobalBool(RinkebyFlag.Name): + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 4 + } + cfg.Genesis = core.DefaultRinkebyGenesisBlock() + case ctx.GlobalBool(GoerliFlag.Name): + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 5 + } + cfg.Genesis = core.DefaultGoerliGenesisBlock() + case ctx.GlobalBool(DeveloperFlag.Name): + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 1337 + } + // Create new developer account or reuse existing one + var ( + developer accounts.Account + err error + ) + if accs := ks.Accounts(); len(accs) > 0 { + developer = ks.Accounts()[0] + } else { + developer, err = ks.NewAccount("") + if err != nil { + Fatalf("Failed to create developer account: %v", err) + } + } + if err := ks.Unlock(developer, ""); err != nil { + Fatalf("Failed to unlock developer account: %v", err) + } + log.Info("Using developer account", "address", developer.Address) + + cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address) + if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) { + cfg.Miner.GasPrice = big.NewInt(1) + } + } +} + +// SetDashboardConfig applies dashboard related command line flags to the config. +func SetDashboardConfig(ctx *cli.Context, cfg *dashboard.Config) { + cfg.Host = ctx.GlobalString(DashboardAddrFlag.Name) + cfg.Port = ctx.GlobalInt(DashboardPortFlag.Name) + cfg.Refresh = ctx.GlobalDuration(DashboardRefreshFlag.Name) +} + +// RegisterEthService adds an Ethereum client to the stack. +func RegisterEthService(stack *node.Node, cfg *eth.Config) { + var err error + if cfg.SyncMode == downloader.LightSync { + err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return les.New(ctx, cfg) + }) + } else { + err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + fullNode, err := eth.New(ctx, cfg) + if fullNode != nil && cfg.LightServ > 0 { + ls, _ := les.NewLesServer(fullNode, cfg) + fullNode.AddLesServer(ls) + } + return fullNode, err + }) + } + if err != nil { + Fatalf("Failed to register the Ethereum service: %v", err) + } +} + +// RegisterDashboardService adds a dashboard to the stack. +func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) { + stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil + }) +} + +// RegisterShhService configures Whisper and adds it to the given node. +func RegisterShhService(stack *node.Node, cfg *whisper.Config) { + if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) { + return whisper.New(cfg), nil + }); err != nil { + Fatalf("Failed to register the Whisper service: %v", err) + } +} + +// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to +// the given node. +func RegisterEthStatsService(stack *node.Node, url string) { + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + // Retrieve both eth and les services + var ethServ *eth.Ethereum + ctx.Service(ðServ) + + var lesServ *les.LightEthereum + ctx.Service(&lesServ) + + return ethstats.New(url, ethServ, lesServ) + }); err != nil { + Fatalf("Failed to register the Ethereum Stats service: %v", err) + } +} + +// RegisterStateDiffService configures and registers a service to stream state diff data over RPC +func RegisterStateDiffService(stack *node.Node, ctx *cli.Context) { + config := statediff.Config{ + PathsAndProofs: ctx.GlobalBool(StateDiffPathsAndProofs.Name), + IntermediateNodes: ctx.GlobalBool(StateDiffIntermediateNodes.Name), + StreamBlock: ctx.GlobalBool(StateDiffStreamBlock.Name), + WatchedAddresses: ctx.GlobalStringSlice(StateDiffWatchedAddresses.Name), + } + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + var ethServ *eth.Ethereum + ctx.Service(ðServ) + chainDb := ethServ.ChainDb() + blockChain := ethServ.BlockChain() + return statediff.NewStateDiffService(chainDb, blockChain, config) + }); err != nil { + Fatalf("Failed to register State Diff Service", err) + } +} + +func SetupMetrics(ctx *cli.Context) { + if metrics.Enabled { + log.Info("Enabling metrics collection") + var ( + enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name) + endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name) + database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name) + username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name) + password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name) + ) + + if enableExport { + tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name)) + + log.Info("Enabling metrics export to InfluxDB") + + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap) + } + } +} + +func SplitTagsFlag(tagsFlag string) map[string]string { + tags := strings.Split(tagsFlag, ",") + tagsMap := map[string]string{} + + for _, t := range tags { + if t != "" { + kv := strings.Split(t, "=") + + if len(kv) == 2 { + tagsMap[kv[0]] = kv[1] + } + } + } + + return tagsMap +} + +// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. +func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database { + var ( + cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 + handles = makeDatabaseHandles() + ) + name := "chaindata" + if ctx.GlobalString(SyncModeFlag.Name) == "light" { + name = "lightchaindata" + } + chainDb, err := stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "") + if err != nil { + Fatalf("Could not open database: %v", err) + } + return chainDb +} + +func MakeGenesis(ctx *cli.Context) *core.Genesis { + var genesis *core.Genesis + switch { + case ctx.GlobalBool(TestnetFlag.Name): + genesis = core.DefaultTestnetGenesisBlock() + case ctx.GlobalBool(RinkebyFlag.Name): + genesis = core.DefaultRinkebyGenesisBlock() + case ctx.GlobalBool(GoerliFlag.Name): + genesis = core.DefaultGoerliGenesisBlock() + case ctx.GlobalBool(DeveloperFlag.Name): + Fatalf("Developer chains are ephemeral") + } + return genesis +} + +// MakeChain creates a chain manager from set command line flags. +func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) { + var err error + chainDb = MakeChainDatabase(ctx, stack) + config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx)) + if err != nil { + Fatalf("%v", err) + } + var engine consensus.Engine + if config.Clique != nil { + engine = clique.New(config.Clique, chainDb) + } else { + engine = ethash.NewFaker() + if !ctx.GlobalBool(FakePoWFlag.Name) { + engine = ethash.New(ethash.Config{ + CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir), + CachesInMem: eth.DefaultConfig.Ethash.CachesInMem, + CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk, + DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir), + DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem, + DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, + }, nil, false) + } + } + if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { + Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) + } + cache := &core.CacheConfig{ + TrieCleanLimit: eth.DefaultConfig.TrieCleanCache, + TrieCleanNoPrefetch: ctx.GlobalBool(CacheNoPrefetchFlag.Name), + TrieDirtyLimit: eth.DefaultConfig.TrieDirtyCache, + TrieDirtyDisabled: ctx.GlobalString(GCModeFlag.Name) == "archive", + TrieTimeLimit: eth.DefaultConfig.TrieTimeout, + } + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) { + cache.TrieCleanLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100 + } + if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { + cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 + } + vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)} + chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil) + if err != nil { + Fatalf("Can't create BlockChain: %v", err) + } + return chain, chainDb +} + +// MakeConsolePreloads retrieves the absolute paths for the console JavaScript +// scripts to preload before starting. +func MakeConsolePreloads(ctx *cli.Context) []string { + // Skip preloading if there's nothing to preload + if ctx.GlobalString(PreloadJSFlag.Name) == "" { + return nil + } + // Otherwise resolve absolute paths and return them + var preloads []string + + assets := ctx.GlobalString(JSpathFlag.Name) + for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") { + preloads = append(preloads, common.AbsolutePath(assets, strings.TrimSpace(file))) + } + return preloads +} + +// MigrateFlags sets the global flag from a local flag when it's set. +// This is a temporary function used for migrating old command/flags to the +// new format. +// +// e.g. geth account new --keystore /tmp/mykeystore --lightkdf +// +// is equivalent after calling this method with: +// +// geth --keystore /tmp/mykeystore --lightkdf account new +// +// This allows the use of the existing configuration functionality. +// When all flags are migrated this function can be removed and the existing +// configuration functionality must be changed that is uses local flags +func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error { + return func(ctx *cli.Context) error { + for _, name := range ctx.FlagNames() { + if ctx.IsSet(name) { + ctx.GlobalSet(name, ctx.String(name)) + } + } + return action(ctx) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go new file mode 100644 index 00000000..99cf84ec --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go @@ -0,0 +1,772 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +// This is a simple Whisper node. It could be used as a stand-alone bootstrap node. +// Also, could be used for different test and diagnostics purposes. + +package main + +import ( + "bufio" + "crypto/ecdsa" + crand "crypto/rand" + "crypto/sha512" + "encoding/binary" + "encoding/hex" + "flag" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/whisper/mailserver" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" + "golang.org/x/crypto/pbkdf2" +) + +const quitCommand = "~Q" +const entropySize = 32 + +// singletons +var ( + server *p2p.Server + shh *whisper.Whisper + done chan struct{} + mailServer mailserver.WMailServer + entropy [entropySize]byte + + input = bufio.NewReader(os.Stdin) +) + +// encryption +var ( + symKey []byte + pub *ecdsa.PublicKey + asymKey *ecdsa.PrivateKey + nodeid *ecdsa.PrivateKey + topic whisper.TopicType + + asymKeyID string + asymFilterID string + symFilterID string + symPass string + msPassword string +) + +// cmd arguments +var ( + bootstrapMode = flag.Bool("standalone", false, "boostrap node: don't initiate connection to peers, just wait for incoming connections") + forwarderMode = flag.Bool("forwarder", false, "forwarder mode: only forward messages, neither encrypt nor decrypt messages") + mailServerMode = flag.Bool("mailserver", false, "mail server mode: delivers expired messages on demand") + requestMail = flag.Bool("mailclient", false, "request expired messages from the bootstrap server") + asymmetricMode = flag.Bool("asym", false, "use asymmetric encryption") + generateKey = flag.Bool("generatekey", false, "generate and show the private key") + fileExMode = flag.Bool("fileexchange", false, "file exchange mode") + fileReader = flag.Bool("filereader", false, "load and decrypt messages saved as files, display as plain text") + testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics (password, etc.)") + echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics") + + argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level") + argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds") + argWorkTime = flag.Uint("work", 5, "work time in seconds") + argMaxSize = flag.Uint("maxsize", uint(whisper.DefaultMaxMessageSize), "max size of message") + argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)") + argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request") + + argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)") + argPub = flag.String("pub", "", "public key for asymmetric encryption") + argDBPath = flag.String("dbpath", "", "path to the server's DB directory") + argIDFile = flag.String("idfile", "", "file name with node id (private key)") + argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)") + argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)") + argSaveDir = flag.String("savedir", "", "directory where all incoming messages will be saved as files") +) + +func main() { + processArgs() + initialize() + run() + shutdown() +} + +func processArgs() { + flag.Parse() + + if len(*argIDFile) > 0 { + var err error + nodeid, err = crypto.LoadECDSA(*argIDFile) + if err != nil { + utils.Fatalf("Failed to load file [%s]: %s.", *argIDFile, err) + } + } + + const enodePrefix = "enode://" + if len(*argEnode) > 0 { + if (*argEnode)[:len(enodePrefix)] != enodePrefix { + *argEnode = enodePrefix + *argEnode + } + } + + if len(*argTopic) > 0 { + x, err := hex.DecodeString(*argTopic) + if err != nil { + utils.Fatalf("Failed to parse the topic: %s", err) + } + topic = whisper.BytesToTopic(x) + } + + if *asymmetricMode && len(*argPub) > 0 { + var err error + if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil { + utils.Fatalf("invalid public key") + } + } + + if len(*argSaveDir) > 0 { + if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) { + utils.Fatalf("Download directory '%s' does not exist", *argSaveDir) + } + } else if *fileExMode { + utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode") + } + + if *echoMode { + echo() + } +} + +func echo() { + fmt.Printf("ttl = %d \n", *argTTL) + fmt.Printf("workTime = %d \n", *argWorkTime) + fmt.Printf("pow = %f \n", *argPoW) + fmt.Printf("mspow = %f \n", *argServerPoW) + fmt.Printf("ip = %s \n", *argIP) + fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub))) + fmt.Printf("idfile = %s \n", *argIDFile) + fmt.Printf("dbpath = %s \n", *argDBPath) + fmt.Printf("boot = %s \n", *argEnode) +} + +func initialize() { + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*argVerbosity), log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) + + done = make(chan struct{}) + var peers []*enode.Node + var err error + + if *generateKey { + key, err := crypto.GenerateKey() + if err != nil { + utils.Fatalf("Failed to generate private key: %s", err) + } + k := hex.EncodeToString(crypto.FromECDSA(key)) + fmt.Printf("Random private key: %s \n", k) + os.Exit(0) + } + + if *testMode { + symPass = "wwww" // ascii code: 0x77777777 + msPassword = "wwww" + } + + if *bootstrapMode { + if len(*argIP) == 0 { + argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ") + } + } else if *fileReader { + *bootstrapMode = true + } else { + if len(*argEnode) == 0 { + argEnode = scanLineA("Please enter the peer's enode: ") + } + peer := enode.MustParse(*argEnode) + peers = append(peers, peer) + } + + if *mailServerMode { + if len(msPassword) == 0 { + msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ") + if err != nil { + utils.Fatalf("Failed to read Mail Server password: %s", err) + } + } + } + + cfg := &whisper.Config{ + MaxMessageSize: uint32(*argMaxSize), + MinimumAcceptedPOW: *argPoW, + } + + shh = whisper.New(cfg) + + if *argPoW != whisper.DefaultMinimumPoW { + err := shh.SetMinimumPoW(*argPoW) + if err != nil { + utils.Fatalf("Failed to set PoW: %s", err) + } + } + + if uint32(*argMaxSize) != whisper.DefaultMaxMessageSize { + err := shh.SetMaxMessageSize(uint32(*argMaxSize)) + if err != nil { + utils.Fatalf("Failed to set max message size: %s", err) + } + } + + asymKeyID, err = shh.NewKeyPair() + if err != nil { + utils.Fatalf("Failed to generate a new key pair: %s", err) + } + + asymKey, err = shh.GetPrivateKey(asymKeyID) + if err != nil { + utils.Fatalf("Failed to retrieve a new key pair: %s", err) + } + + if nodeid == nil { + tmpID, err := shh.NewKeyPair() + if err != nil { + utils.Fatalf("Failed to generate a new key pair: %s", err) + } + + nodeid, err = shh.GetPrivateKey(tmpID) + if err != nil { + utils.Fatalf("Failed to retrieve a new key pair: %s", err) + } + } + + maxPeers := 80 + if *bootstrapMode { + maxPeers = 800 + } + + _, err = crand.Read(entropy[:]) + if err != nil { + utils.Fatalf("crypto/rand failed: %s", err) + } + + if *mailServerMode { + shh.RegisterServer(&mailServer) + if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil { + utils.Fatalf("Failed to init MailServer: %s", err) + } + } + + server = &p2p.Server{ + Config: p2p.Config{ + PrivateKey: nodeid, + MaxPeers: maxPeers, + Name: common.MakeName("wnode", "6.0"), + Protocols: shh.Protocols(), + ListenAddr: *argIP, + NAT: nat.Any(), + BootstrapNodes: peers, + StaticNodes: peers, + TrustedNodes: peers, + }, + } +} + +func startServer() error { + err := server.Start() + if err != nil { + fmt.Printf("Failed to start Whisper peer: %s.", err) + return err + } + + fmt.Printf("my public key: %s \n", common.ToHex(crypto.FromECDSAPub(&asymKey.PublicKey))) + fmt.Println(server.NodeInfo().Enode) + + if *bootstrapMode { + configureNode() + fmt.Println("Bootstrap Whisper node started") + } else { + fmt.Println("Whisper node started") + // first see if we can establish connection, then ask for user input + waitForConnection(true) + configureNode() + } + + if *fileExMode { + fmt.Printf("Please type the file name to be send. To quit type: '%s'\n", quitCommand) + } else if *fileReader { + fmt.Printf("Please type the file name to be decrypted. To quit type: '%s'\n", quitCommand) + } else if !*forwarderMode { + fmt.Printf("Please type the message. To quit type: '%s'\n", quitCommand) + } + return nil +} + +func configureNode() { + var err error + var p2pAccept bool + + if *forwarderMode { + return + } + + if *asymmetricMode { + if len(*argPub) == 0 { + s := scanLine("Please enter the peer's public key: ") + b := common.FromHex(s) + if b == nil { + utils.Fatalf("Error: can not convert hexadecimal string") + } + if pub, err = crypto.UnmarshalPubkey(b); err != nil { + utils.Fatalf("Error: invalid peer public key") + } + } + } + + if *requestMail { + p2pAccept = true + if len(msPassword) == 0 { + msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ") + if err != nil { + utils.Fatalf("Failed to read Mail Server password: %s", err) + } + } + } + + if !*asymmetricMode && !*forwarderMode { + if len(symPass) == 0 { + symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ") + if err != nil { + utils.Fatalf("Failed to read passphrase: %v", err) + } + } + + symKeyID, err := shh.AddSymKeyFromPassword(symPass) + if err != nil { + utils.Fatalf("Failed to create symmetric key: %s", err) + } + symKey, err = shh.GetSymKey(symKeyID) + if err != nil { + utils.Fatalf("Failed to save symmetric key: %s", err) + } + if len(*argTopic) == 0 { + generateTopic([]byte(symPass)) + } + + fmt.Printf("Filter is configured for the topic: %x \n", topic) + } + + if *mailServerMode { + if len(*argDBPath) == 0 { + argDBPath = scanLineA("Please enter the path to DB file: ") + } + } + + symFilter := whisper.Filter{ + KeySym: symKey, + Topics: [][]byte{topic[:]}, + AllowP2P: p2pAccept, + } + symFilterID, err = shh.Subscribe(&symFilter) + if err != nil { + utils.Fatalf("Failed to install filter: %s", err) + } + + asymFilter := whisper.Filter{ + KeyAsym: asymKey, + Topics: [][]byte{topic[:]}, + AllowP2P: p2pAccept, + } + asymFilterID, err = shh.Subscribe(&asymFilter) + if err != nil { + utils.Fatalf("Failed to install filter: %s", err) + } +} + +func generateTopic(password []byte) { + x := pbkdf2.Key(password, password, 4096, 128, sha512.New) + for i := 0; i < len(x); i++ { + topic[i%whisper.TopicLength] ^= x[i] + } +} + +func waitForConnection(timeout bool) { + var cnt int + var connected bool + for !connected { + time.Sleep(time.Millisecond * 50) + connected = server.PeerCount() > 0 + if timeout { + cnt++ + if cnt > 1000 { + utils.Fatalf("Timeout expired, failed to connect") + } + } + } + + fmt.Println("Connected to peer.") +} + +func run() { + err := startServer() + if err != nil { + return + } + defer server.Stop() + shh.Start(nil) + defer shh.Stop() + + if !*forwarderMode { + go messageLoop() + } + + if *requestMail { + requestExpiredMessagesLoop() + } else if *fileExMode { + sendFilesLoop() + } else if *fileReader { + fileReaderLoop() + } else { + sendLoop() + } +} + +func shutdown() { + close(done) + mailServer.Close() +} + +func sendLoop() { + for { + s := scanLine("") + if s == quitCommand { + fmt.Println("Quit command received") + return + } + sendMsg([]byte(s)) + if *asymmetricMode { + // print your own message for convenience, + // because in asymmetric mode it is impossible to decrypt it + timestamp := time.Now().Unix() + from := crypto.PubkeyToAddress(asymKey.PublicKey) + fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s) + } + } +} + +func sendFilesLoop() { + for { + s := scanLine("") + if s == quitCommand { + fmt.Println("Quit command received") + return + } + b, err := ioutil.ReadFile(s) + if err != nil { + fmt.Printf(">>> Error: %s \n", err) + } else { + h := sendMsg(b) + if (h == common.Hash{}) { + fmt.Printf(">>> Error: message was not sent \n") + } else { + timestamp := time.Now().Unix() + from := crypto.PubkeyToAddress(asymKey.PublicKey) + fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h) + } + } + } +} + +func fileReaderLoop() { + watcher1 := shh.GetFilter(symFilterID) + watcher2 := shh.GetFilter(asymFilterID) + if watcher1 == nil && watcher2 == nil { + fmt.Println("Error: neither symmetric nor asymmetric filter is installed") + return + } + + for { + s := scanLine("") + if s == quitCommand { + fmt.Println("Quit command received") + return + } + raw, err := ioutil.ReadFile(s) + if err != nil { + fmt.Printf(">>> Error: %s \n", err) + } else { + env := whisper.Envelope{Data: raw} // the topic is zero + msg := env.Open(watcher1) // force-open envelope regardless of the topic + if msg == nil { + msg = env.Open(watcher2) + } + if msg == nil { + fmt.Printf(">>> Error: failed to decrypt the message \n") + } else { + printMessageInfo(msg) + } + } + } +} + +func scanLine(prompt string) string { + if len(prompt) > 0 { + fmt.Print(prompt) + } + txt, err := input.ReadString('\n') + if err != nil { + utils.Fatalf("input error: %s", err) + } + txt = strings.TrimRight(txt, "\n\r") + return txt +} + +func scanLineA(prompt string) *string { + s := scanLine(prompt) + return &s +} + +func scanUint(prompt string) uint32 { + s := scanLine(prompt) + i, err := strconv.Atoi(s) + if err != nil { + utils.Fatalf("Fail to parse the lower time limit: %s", err) + } + return uint32(i) +} + +func sendMsg(payload []byte) common.Hash { + params := whisper.MessageParams{ + Src: asymKey, + Dst: pub, + KeySym: symKey, + Payload: payload, + Topic: topic, + TTL: uint32(*argTTL), + PoW: *argPoW, + WorkTime: uint32(*argWorkTime), + } + + msg, err := whisper.NewSentMessage(¶ms) + if err != nil { + utils.Fatalf("failed to create new message: %s", err) + } + + envelope, err := msg.Wrap(¶ms) + if err != nil { + fmt.Printf("failed to seal message: %v \n", err) + return common.Hash{} + } + + err = shh.Send(envelope) + if err != nil { + fmt.Printf("failed to send message: %v \n", err) + return common.Hash{} + } + + return envelope.Hash() +} + +func messageLoop() { + sf := shh.GetFilter(symFilterID) + if sf == nil { + utils.Fatalf("symmetric filter is not installed") + } + + af := shh.GetFilter(asymFilterID) + if af == nil { + utils.Fatalf("asymmetric filter is not installed") + } + + ticker := time.NewTicker(time.Millisecond * 50) + + for { + select { + case <-ticker.C: + m1 := sf.Retrieve() + m2 := af.Retrieve() + messages := append(m1, m2...) + for _, msg := range messages { + reportedOnce := false + if !*fileExMode && len(msg.Payload) <= 2048 { + printMessageInfo(msg) + reportedOnce = true + } + + // All messages are saved upon specifying argSaveDir. + // fileExMode only specifies how messages are displayed on the console after they are saved. + // if fileExMode == true, only the hashes are displayed, since messages might be too big. + if len(*argSaveDir) > 0 { + writeMessageToFile(*argSaveDir, msg, !reportedOnce) + } + } + case <-done: + return + } + } +} + +func printMessageInfo(msg *whisper.ReceivedMessage) { + timestamp := fmt.Sprintf("%d", msg.Sent) // unix timestamp for diagnostics + text := string(msg.Payload) + + var address common.Address + if msg.Src != nil { + address = crypto.PubkeyToAddress(*msg.Src) + } + + if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) { + fmt.Printf("\n%s <%x>: %s\n", timestamp, address, text) // message from myself + } else { + fmt.Printf("\n%s [%x]: %s\n", timestamp, address, text) // message from a peer + } +} + +func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) { + if len(dir) == 0 { + return + } + + timestamp := fmt.Sprintf("%d", msg.Sent) + name := fmt.Sprintf("%x", msg.EnvelopeHash) + + var address common.Address + if msg.Src != nil { + address = crypto.PubkeyToAddress(*msg.Src) + } + + env := shh.GetEnvelope(msg.EnvelopeHash) + if env == nil { + fmt.Printf("\nUnexpected error: envelope not found: %x\n", msg.EnvelopeHash) + return + } + + // this is a sample code; uncomment if you don't want to save your own messages. + //if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) { + // fmt.Printf("\n%s <%x>: message from myself received, not saved: '%s'\n", timestamp, address, name) + // return + //} + + fullpath := filepath.Join(dir, name) + err := ioutil.WriteFile(fullpath, env.Data, 0644) + if err != nil { + fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err) + } else if show { + fmt.Printf("\n%s {%x}: message received and saved as '%s' (%d bytes)\n", timestamp, address, name, len(env.Data)) + } +} + +func requestExpiredMessagesLoop() { + var key, peerID, bloom []byte + var timeLow, timeUpp uint32 + var t string + var xt whisper.TopicType + + keyID, err := shh.AddSymKeyFromPassword(msPassword) + if err != nil { + utils.Fatalf("Failed to create symmetric key for mail request: %s", err) + } + key, err = shh.GetSymKey(keyID) + if err != nil { + utils.Fatalf("Failed to save symmetric key for mail request: %s", err) + } + peerID = extractIDFromEnode(*argEnode) + shh.AllowP2PMessagesFromPeer(peerID) + + for { + timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ") + timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ") + t = scanLine("Enter the topic (hex). Press enter to request all messages, regardless of the topic: ") + if len(t) == whisper.TopicLength*2 { + x, err := hex.DecodeString(t) + if err != nil { + fmt.Printf("Failed to parse the topic: %s \n", err) + continue + } + xt = whisper.BytesToTopic(x) + bloom = whisper.TopicToBloom(xt) + obfuscateBloom(bloom) + } else if len(t) == 0 { + bloom = whisper.MakeFullNodeBloom() + } else { + fmt.Println("Error: topic is invalid, request aborted") + continue + } + + if timeUpp == 0 { + timeUpp = 0xFFFFFFFF + } + + data := make([]byte, 8, 8+whisper.BloomFilterSize) + binary.BigEndian.PutUint32(data, timeLow) + binary.BigEndian.PutUint32(data[4:], timeUpp) + data = append(data, bloom...) + + var params whisper.MessageParams + params.PoW = *argServerPoW + params.Payload = data + params.KeySym = key + params.Src = asymKey + params.WorkTime = 5 + + msg, err := whisper.NewSentMessage(¶ms) + if err != nil { + utils.Fatalf("failed to create new message: %s", err) + } + env, err := msg.Wrap(¶ms) + if err != nil { + utils.Fatalf("Wrap failed: %s", err) + } + + err = shh.RequestHistoricMessages(peerID, env) + if err != nil { + utils.Fatalf("Failed to send P2P message: %s", err) + } + + time.Sleep(time.Second * 5) + } +} + +func extractIDFromEnode(s string) []byte { + n, err := enode.Parse(enode.ValidSchemes, s) + if err != nil { + utils.Fatalf("Failed to parse node: %s", err) + } + return n.ID().Bytes() +} + +// obfuscateBloom adds 16 random bits to the bloom +// filter, in order to obfuscate the containing topics. +// it does so deterministically within every session. +// despite additional bits, it will match on average +// 32000 times less messages than full node's bloom filter. +func obfuscateBloom(bloom []byte) { + const half = entropySize / 2 + for i := 0; i < half; i++ { + x := int(entropy[i]) + if entropy[half+i] < 128 { + x += 256 + } + + bloom[x/8] = 1 << uint(x%8) // set the bit number X + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/common/math/big.go b/vendor/github.com/ethereum/go-ethereum/common/math/big.go new file mode 100644 index 00000000..d31c59af --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/common/math/big.go @@ -0,0 +1,219 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package math provides integer math utilities. +package math + +import ( + "fmt" + "math/big" +) + +// Various big integer limit values. +var ( + tt255 = BigPow(2, 255) + tt256 = BigPow(2, 256) + tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1)) + tt63 = BigPow(2, 63) + MaxBig256 = new(big.Int).Set(tt256m1) + MaxBig63 = new(big.Int).Sub(tt63, big.NewInt(1)) +) + +const ( + // number of bits in a big.Word + wordBits = 32 << (uint64(^big.Word(0)) >> 63) + // number of bytes in a big.Word + wordBytes = wordBits / 8 +) + +// HexOrDecimal256 marshals big.Int as hex or decimal. +type HexOrDecimal256 big.Int + +// NewHexOrDecimal256 creates a new HexOrDecimal256 +func NewHexOrDecimal256(x int64) *HexOrDecimal256 { + b := big.NewInt(x) + h := HexOrDecimal256(*b) + return &h +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (i *HexOrDecimal256) UnmarshalText(input []byte) error { + bigint, ok := ParseBig256(string(input)) + if !ok { + return fmt.Errorf("invalid hex or decimal integer %q", input) + } + *i = HexOrDecimal256(*bigint) + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (i *HexOrDecimal256) MarshalText() ([]byte, error) { + if i == nil { + return []byte("0x0"), nil + } + return []byte(fmt.Sprintf("%#x", (*big.Int)(i))), nil +} + +// ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax. +// Leading zeros are accepted. The empty string parses as zero. +func ParseBig256(s string) (*big.Int, bool) { + if s == "" { + return new(big.Int), true + } + var bigint *big.Int + var ok bool + if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") { + bigint, ok = new(big.Int).SetString(s[2:], 16) + } else { + bigint, ok = new(big.Int).SetString(s, 10) + } + if ok && bigint.BitLen() > 256 { + bigint, ok = nil, false + } + return bigint, ok +} + +// MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid. +func MustParseBig256(s string) *big.Int { + v, ok := ParseBig256(s) + if !ok { + panic("invalid 256 bit integer: " + s) + } + return v +} + +// BigPow returns a ** b as a big integer. +func BigPow(a, b int64) *big.Int { + r := big.NewInt(a) + return r.Exp(r, big.NewInt(b), nil) +} + +// BigMax returns the larger of x or y. +func BigMax(x, y *big.Int) *big.Int { + if x.Cmp(y) < 0 { + return y + } + return x +} + +// BigMin returns the smaller of x or y. +func BigMin(x, y *big.Int) *big.Int { + if x.Cmp(y) > 0 { + return y + } + return x +} + +// FirstBitSet returns the index of the first 1 bit in v, counting from LSB. +func FirstBitSet(v *big.Int) int { + for i := 0; i < v.BitLen(); i++ { + if v.Bit(i) > 0 { + return i + } + } + return v.BitLen() +} + +// PaddedBigBytes encodes a big integer as a big-endian byte slice. The length +// of the slice is at least n bytes. +func PaddedBigBytes(bigint *big.Int, n int) []byte { + if bigint.BitLen()/8 >= n { + return bigint.Bytes() + } + ret := make([]byte, n) + ReadBits(bigint, ret) + return ret +} + +// bigEndianByteAt returns the byte at position n, +// in Big-Endian encoding +// So n==0 returns the least significant byte +func bigEndianByteAt(bigint *big.Int, n int) byte { + words := bigint.Bits() + // Check word-bucket the byte will reside in + i := n / wordBytes + if i >= len(words) { + return byte(0) + } + word := words[i] + // Offset of the byte + shift := 8 * uint(n%wordBytes) + + return byte(word >> shift) +} + +// Byte returns the byte at position n, +// with the supplied padlength in Little-Endian encoding. +// n==0 returns the MSB +// Example: bigint '5', padlength 32, n=31 => 5 +func Byte(bigint *big.Int, padlength, n int) byte { + if n >= padlength { + return byte(0) + } + return bigEndianByteAt(bigint, padlength-1-n) +} + +// ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure +// that buf has enough space. If buf is too short the result will be incomplete. +func ReadBits(bigint *big.Int, buf []byte) { + i := len(buf) + for _, d := range bigint.Bits() { + for j := 0; j < wordBytes && i > 0; j++ { + i-- + buf[i] = byte(d) + d >>= 8 + } + } +} + +// U256 encodes as a 256 bit two's complement number. This operation is destructive. +func U256(x *big.Int) *big.Int { + return x.And(x, tt256m1) +} + +// S256 interprets x as a two's complement number. +// x must not exceed 256 bits (the result is undefined if it does) and is not modified. +// +// S256(0) = 0 +// S256(1) = 1 +// S256(2**255) = -2**255 +// S256(2**256-1) = -1 +func S256(x *big.Int) *big.Int { + if x.Cmp(tt255) < 0 { + return x + } + return new(big.Int).Sub(x, tt256) +} + +// Exp implements exponentiation by squaring. +// Exp returns a newly-allocated big integer and does not change +// base or exponent. The result is truncated to 256 bits. +// +// Courtesy @karalabe and @chfast +func Exp(base, exponent *big.Int) *big.Int { + result := big.NewInt(1) + + for _, word := range exponent.Bits() { + for i := 0; i < wordBits; i++ { + if word&1 == 1 { + U256(result.Mul(result, base)) + } + U256(base.Mul(base, base)) + word >>= 1 + } + } + return result +} diff --git a/vendor/github.com/ethereum/go-ethereum/common/prque/prque.go b/vendor/github.com/ethereum/go-ethereum/common/prque/prque.go new file mode 100755 index 00000000..3cc5a1ad --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/common/prque/prque.go @@ -0,0 +1,78 @@ +// CookieJar - A contestant's algorithm toolbox +// Copyright (c) 2013 Peter Szilagyi. All rights reserved. +// +// CookieJar is dual licensed: use of this source code is governed by a BSD +// license that can be found in the LICENSE file. Alternatively, the CookieJar +// toolbox may be used in accordance with the terms and conditions contained +// in a signed written agreement between you and the author(s). + +// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque". + +// Package prque implements a priority queue data structure supporting arbitrary +// value types and int64 priorities. +// +// If you would like to use a min-priority queue, simply negate the priorities. +// +// Internally the queue is based on the standard heap package working on a +// sortable version of the block based stack. +package prque + +import ( + "container/heap" +) + +// Priority queue data structure. +type Prque struct { + cont *sstack +} + +// New creates a new priority queue. +func New(setIndex SetIndexCallback) *Prque { + return &Prque{newSstack(setIndex)} +} + +// Pushes a value with a given priority into the queue, expanding if necessary. +func (p *Prque) Push(data interface{}, priority int64) { + heap.Push(p.cont, &item{data, priority}) +} + +// Peek returns the value with the greates priority but does not pop it off. +func (p *Prque) Peek() (interface{}, int64) { + item := p.cont.blocks[0][0] + return item.value, item.priority +} + +// Pops the value with the greates priority off the stack and returns it. +// Currently no shrinking is done. +func (p *Prque) Pop() (interface{}, int64) { + item := heap.Pop(p.cont).(*item) + return item.value, item.priority +} + +// Pops only the item from the queue, dropping the associated priority value. +func (p *Prque) PopItem() interface{} { + return heap.Pop(p.cont).(*item).value +} + +// Remove removes the element with the given index. +func (p *Prque) Remove(i int) interface{} { + if i < 0 { + return nil + } + return heap.Remove(p.cont, i) +} + +// Checks whether the priority queue is empty. +func (p *Prque) Empty() bool { + return p.cont.Len() == 0 +} + +// Returns the number of element in the priority queue. +func (p *Prque) Size() int { + return p.cont.Len() +} + +// Clears the contents of the priority queue. +func (p *Prque) Reset() { + *p = *New(p.cont.setIndex) +} diff --git a/vendor/github.com/ethereum/go-ethereum/common/prque/sstack.go b/vendor/github.com/ethereum/go-ethereum/common/prque/sstack.go new file mode 100755 index 00000000..8518af54 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/common/prque/sstack.go @@ -0,0 +1,114 @@ +// CookieJar - A contestant's algorithm toolbox +// Copyright (c) 2013 Peter Szilagyi. All rights reserved. +// +// CookieJar is dual licensed: use of this source code is governed by a BSD +// license that can be found in the LICENSE file. Alternatively, the CookieJar +// toolbox may be used in accordance with the terms and conditions contained +// in a signed written agreement between you and the author(s). + +// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque". + +package prque + +// The size of a block of data +const blockSize = 4096 + +// A prioritized item in the sorted stack. +// +// Note: priorities can "wrap around" the int64 range, a comes before b if (a.priority - b.priority) > 0. +// The difference between the lowest and highest priorities in the queue at any point should be less than 2^63. +type item struct { + value interface{} + priority int64 +} + +// SetIndexCallback is called when the element is moved to a new index. +// Providing SetIndexCallback is optional, it is needed only if the application needs +// to delete elements other than the top one. +type SetIndexCallback func(data interface{}, index int) + +// Internal sortable stack data structure. Implements the Push and Pop ops for +// the stack (heap) functionality and the Len, Less and Swap methods for the +// sortability requirements of the heaps. +type sstack struct { + setIndex SetIndexCallback + size int + capacity int + offset int + + blocks [][]*item + active []*item +} + +// Creates a new, empty stack. +func newSstack(setIndex SetIndexCallback) *sstack { + result := new(sstack) + result.setIndex = setIndex + result.active = make([]*item, blockSize) + result.blocks = [][]*item{result.active} + result.capacity = blockSize + return result +} + +// Pushes a value onto the stack, expanding it if necessary. Required by +// heap.Interface. +func (s *sstack) Push(data interface{}) { + if s.size == s.capacity { + s.active = make([]*item, blockSize) + s.blocks = append(s.blocks, s.active) + s.capacity += blockSize + s.offset = 0 + } else if s.offset == blockSize { + s.active = s.blocks[s.size/blockSize] + s.offset = 0 + } + if s.setIndex != nil { + s.setIndex(data.(*item).value, s.size) + } + s.active[s.offset] = data.(*item) + s.offset++ + s.size++ +} + +// Pops a value off the stack and returns it. Currently no shrinking is done. +// Required by heap.Interface. +func (s *sstack) Pop() (res interface{}) { + s.size-- + s.offset-- + if s.offset < 0 { + s.offset = blockSize - 1 + s.active = s.blocks[s.size/blockSize] + } + res, s.active[s.offset] = s.active[s.offset], nil + if s.setIndex != nil { + s.setIndex(res.(*item).value, -1) + } + return +} + +// Returns the length of the stack. Required by sort.Interface. +func (s *sstack) Len() int { + return s.size +} + +// Compares the priority of two elements of the stack (higher is first). +// Required by sort.Interface. +func (s *sstack) Less(i, j int) bool { + return (s.blocks[i/blockSize][i%blockSize].priority - s.blocks[j/blockSize][j%blockSize].priority) > 0 +} + +// Swaps two elements in the stack. Required by sort.Interface. +func (s *sstack) Swap(i, j int) { + ib, io, jb, jo := i/blockSize, i%blockSize, j/blockSize, j%blockSize + a, b := s.blocks[jb][jo], s.blocks[ib][io] + if s.setIndex != nil { + s.setIndex(a.value, i) + s.setIndex(b.value, j) + } + s.blocks[ib][io], s.blocks[jb][jo] = a, b +} + +// Resets the stack, effectively clearing its contents. +func (s *sstack) Reset() { + *s = *newSstack(s.setIndex) +} diff --git a/vendor/github.com/ethereum/go-ethereum/common/size.go b/vendor/github.com/ethereum/go-ethereum/common/size.go new file mode 100644 index 00000000..097b6304 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/common/size.go @@ -0,0 +1,56 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +import ( + "fmt" +) + +// StorageSize is a wrapper around a float value that supports user friendly +// formatting. +type StorageSize float64 + +// String implements the stringer interface. +func (s StorageSize) String() string { + if s > 1099511627776 { + return fmt.Sprintf("%.2f TiB", s/1099511627776) + } else if s > 1073741824 { + return fmt.Sprintf("%.2f GiB", s/1073741824) + } else if s > 1048576 { + return fmt.Sprintf("%.2f MiB", s/1048576) + } else if s > 1024 { + return fmt.Sprintf("%.2f KiB", s/1024) + } else { + return fmt.Sprintf("%.2f B", s) + } +} + +// TerminalString implements log.TerminalStringer, formatting a string for console +// output during logging. +func (s StorageSize) TerminalString() string { + if s > 1099511627776 { + return fmt.Sprintf("%.2fTiB", s/1099511627776) + } else if s > 1073741824 { + return fmt.Sprintf("%.2fGiB", s/1073741824) + } else if s > 1048576 { + return fmt.Sprintf("%.2fMiB", s/1048576) + } else if s > 1024 { + return fmt.Sprintf("%.2fKiB", s/1024) + } else { + return fmt.Sprintf("%.2fB", s) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/consensus/clique/clique.go b/vendor/github.com/ethereum/go-ethereum/consensus/clique/clique.go new file mode 100644 index 00000000..084009a0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/consensus/clique/clique.go @@ -0,0 +1,738 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package clique implements the proof-of-authority consensus engine. +package clique + +import ( + "bytes" + "errors" + "io" + "math/big" + "math/rand" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + lru "github.com/hashicorp/golang-lru" + "golang.org/x/crypto/sha3" +) + +const ( + checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database + inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory + inmemorySignatures = 4096 // Number of recent block signatures to keep in memory + + wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers +) + +// Clique proof-of-authority protocol constants. +var ( + epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes + + extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal + + nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer + nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer. + + uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. + + diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures + diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures +) + +// Various error messages to mark blocks invalid. These should be private to +// prevent engine specific errors from being referenced in the remainder of the +// codebase, inherently breaking if the engine is swapped out. Please put common +// error types into the consensus package. +var ( + // errUnknownBlock is returned when the list of signers is requested for a block + // that is not part of the local blockchain. + errUnknownBlock = errors.New("unknown block") + + // errInvalidCheckpointBeneficiary is returned if a checkpoint/epoch transition + // block has a beneficiary set to non-zeroes. + errInvalidCheckpointBeneficiary = errors.New("beneficiary in checkpoint block non-zero") + + // errInvalidVote is returned if a nonce value is something else that the two + // allowed constants of 0x00..0 or 0xff..f. + errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f") + + // errInvalidCheckpointVote is returned if a checkpoint/epoch transition block + // has a vote nonce set to non-zeroes. + errInvalidCheckpointVote = errors.New("vote nonce in checkpoint block non-zero") + + // errMissingVanity is returned if a block's extra-data section is shorter than + // 32 bytes, which is required to store the signer vanity. + errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") + + // errMissingSignature is returned if a block's extra-data section doesn't seem + // to contain a 65 byte secp256k1 signature. + errMissingSignature = errors.New("extra-data 65 byte signature suffix missing") + + // errExtraSigners is returned if non-checkpoint block contain signer data in + // their extra-data fields. + errExtraSigners = errors.New("non-checkpoint block contains extra signer list") + + // errInvalidCheckpointSigners is returned if a checkpoint block contains an + // invalid list of signers (i.e. non divisible by 20 bytes). + errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block") + + // errMismatchingCheckpointSigners is returned if a checkpoint block contains a + // list of signers different than the one the local node calculated. + errMismatchingCheckpointSigners = errors.New("mismatching signer list on checkpoint block") + + // errInvalidMixDigest is returned if a block's mix digest is non-zero. + errInvalidMixDigest = errors.New("non-zero mix digest") + + // errInvalidUncleHash is returned if a block contains an non-empty uncle list. + errInvalidUncleHash = errors.New("non empty uncle hash") + + // errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2. + errInvalidDifficulty = errors.New("invalid difficulty") + + // errWrongDifficulty is returned if the difficulty of a block doesn't match the + // turn of the signer. + errWrongDifficulty = errors.New("wrong difficulty") + + // ErrInvalidTimestamp is returned if the timestamp of a block is lower than + // the previous block's timestamp + the minimum block period. + ErrInvalidTimestamp = errors.New("invalid timestamp") + + // errInvalidVotingChain is returned if an authorization list is attempted to + // be modified via out-of-range or non-contiguous headers. + errInvalidVotingChain = errors.New("invalid voting chain") + + // errUnauthorizedSigner is returned if a header is signed by a non-authorized entity. + errUnauthorizedSigner = errors.New("unauthorized signer") + + // errRecentlySigned is returned if a header is signed by an authorized entity + // that already signed a header recently, thus is temporarily not allowed to. + errRecentlySigned = errors.New("recently signed") +) + +// SignerFn is a signer callback function to request a header to be signed by a +// backing account. +type SignerFn func(accounts.Account, string, []byte) ([]byte, error) + +// ecrecover extracts the Ethereum account address from a signed header. +func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { + // If the signature's already cached, return that + hash := header.Hash() + if address, known := sigcache.Get(hash); known { + return address.(common.Address), nil + } + // Retrieve the signature from the header extra-data + if len(header.Extra) < extraSeal { + return common.Address{}, errMissingSignature + } + signature := header.Extra[len(header.Extra)-extraSeal:] + + // Recover the public key and the Ethereum address + pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) + if err != nil { + return common.Address{}, err + } + var signer common.Address + copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) + + sigcache.Add(hash, signer) + return signer, nil +} + +// Clique is the proof-of-authority consensus engine proposed to support the +// Ethereum testnet following the Ropsten attacks. +type Clique struct { + config *params.CliqueConfig // Consensus engine configuration parameters + db ethdb.Database // Database to store and retrieve snapshot checkpoints + + recents *lru.ARCCache // Snapshots for recent block to speed up reorgs + signatures *lru.ARCCache // Signatures of recent blocks to speed up mining + + proposals map[common.Address]bool // Current list of proposals we are pushing + + signer common.Address // Ethereum address of the signing key + signFn SignerFn // Signer function to authorize hashes with + lock sync.RWMutex // Protects the signer fields + + // The fields below are for testing only + fakeDiff bool // Skip difficulty verifications +} + +// New creates a Clique proof-of-authority consensus engine with the initial +// signers set to the ones provided by the user. +func New(config *params.CliqueConfig, db ethdb.Database) *Clique { + // Set any missing consensus parameters to their defaults + conf := *config + if conf.Epoch == 0 { + conf.Epoch = epochLength + } + // Allocate the snapshot caches and create the engine + recents, _ := lru.NewARC(inmemorySnapshots) + signatures, _ := lru.NewARC(inmemorySignatures) + + return &Clique{ + config: &conf, + db: db, + recents: recents, + signatures: signatures, + proposals: make(map[common.Address]bool), + } +} + +// Author implements consensus.Engine, returning the Ethereum address recovered +// from the signature in the header's extra-data section. +func (c *Clique) Author(header *types.Header) (common.Address, error) { + return ecrecover(header, c.signatures) +} + +// VerifyHeader checks whether a header conforms to the consensus rules. +func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { + return c.verifyHeader(chain, header, nil) +} + +// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The +// method returns a quit channel to abort the operations and a results channel to +// retrieve the async verifications (the order is that of the input slice). +func (c *Clique) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { + abort := make(chan struct{}) + results := make(chan error, len(headers)) + + go func() { + for i, header := range headers { + err := c.verifyHeader(chain, header, headers[:i]) + + select { + case <-abort: + return + case results <- err: + } + } + }() + return abort, results +} + +// verifyHeader checks whether a header conforms to the consensus rules.The +// caller may optionally pass in a batch of parents (ascending order) to avoid +// looking those up from the database. This is useful for concurrently verifying +// a batch of new headers. +func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { + if header.Number == nil { + return errUnknownBlock + } + number := header.Number.Uint64() + + // Don't waste time checking blocks from the future + if header.Time > uint64(time.Now().Unix()) { + return consensus.ErrFutureBlock + } + // Checkpoint blocks need to enforce zero beneficiary + checkpoint := (number % c.config.Epoch) == 0 + if checkpoint && header.Coinbase != (common.Address{}) { + return errInvalidCheckpointBeneficiary + } + // Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints + if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) { + return errInvalidVote + } + if checkpoint && !bytes.Equal(header.Nonce[:], nonceDropVote) { + return errInvalidCheckpointVote + } + // Check that the extra-data contains both the vanity and signature + if len(header.Extra) < extraVanity { + return errMissingVanity + } + if len(header.Extra) < extraVanity+extraSeal { + return errMissingSignature + } + // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise + signersBytes := len(header.Extra) - extraVanity - extraSeal + if !checkpoint && signersBytes != 0 { + return errExtraSigners + } + if checkpoint && signersBytes%common.AddressLength != 0 { + return errInvalidCheckpointSigners + } + // Ensure that the mix digest is zero as we don't have fork protection currently + if header.MixDigest != (common.Hash{}) { + return errInvalidMixDigest + } + // Ensure that the block doesn't contain any uncles which are meaningless in PoA + if header.UncleHash != uncleHash { + return errInvalidUncleHash + } + // Ensure that the block's difficulty is meaningful (may not be correct at this point) + if number > 0 { + if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { + return errInvalidDifficulty + } + } + // If all checks passed, validate any special fields for hard forks + if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { + return err + } + // All basic checks passed, verify cascading fields + return c.verifyCascadingFields(chain, header, parents) +} + +// verifyCascadingFields verifies all the header fields that are not standalone, +// rather depend on a batch of previous headers. The caller may optionally pass +// in a batch of parents (ascending order) to avoid looking those up from the +// database. This is useful for concurrently verifying a batch of new headers. +func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { + // The genesis block is the always valid dead-end + number := header.Number.Uint64() + if number == 0 { + return nil + } + // Ensure that the block's timestamp isn't too close to it's parent + var parent *types.Header + if len(parents) > 0 { + parent = parents[len(parents)-1] + } else { + parent = chain.GetHeader(header.ParentHash, number-1) + } + if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { + return consensus.ErrUnknownAncestor + } + if parent.Time+c.config.Period > header.Time { + return ErrInvalidTimestamp + } + // Retrieve the snapshot needed to verify this header and cache it + snap, err := c.snapshot(chain, number-1, header.ParentHash, parents) + if err != nil { + return err + } + // If the block is a checkpoint block, verify the signer list + if number%c.config.Epoch == 0 { + signers := make([]byte, len(snap.Signers)*common.AddressLength) + for i, signer := range snap.signers() { + copy(signers[i*common.AddressLength:], signer[:]) + } + extraSuffix := len(header.Extra) - extraSeal + if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) { + return errMismatchingCheckpointSigners + } + } + // All basic checks passed, verify the seal and return + return c.verifySeal(chain, header, parents) +} + +// snapshot retrieves the authorization snapshot at a given point in time. +func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { + // Search for a snapshot in memory or on disk for checkpoints + var ( + headers []*types.Header + snap *Snapshot + ) + for snap == nil { + // If an in-memory snapshot was found, use that + if s, ok := c.recents.Get(hash); ok { + snap = s.(*Snapshot) + break + } + // If an on-disk checkpoint snapshot can be found, use that + if number%checkpointInterval == 0 { + if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil { + log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash) + snap = s + break + } + } + // If we're at the genesis, snapshot the initial state. Alternatively if we're + // at a checkpoint block without a parent (light client CHT), or we have piled + // up more headers than allowed to be reorged (chain reinit from a freezer), + // consider the checkpoint trusted and snapshot it. + if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.ImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) { + checkpoint := chain.GetHeaderByNumber(number) + if checkpoint != nil { + hash := checkpoint.Hash() + + signers := make([]common.Address, (len(checkpoint.Extra)-extraVanity-extraSeal)/common.AddressLength) + for i := 0; i < len(signers); i++ { + copy(signers[i][:], checkpoint.Extra[extraVanity+i*common.AddressLength:]) + } + snap = newSnapshot(c.config, c.signatures, number, hash, signers) + if err := snap.store(c.db); err != nil { + return nil, err + } + log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash) + break + } + } + // No snapshot for this header, gather the header and move backward + var header *types.Header + if len(parents) > 0 { + // If we have explicit parents, pick from there (enforced) + header = parents[len(parents)-1] + if header.Hash() != hash || header.Number.Uint64() != number { + return nil, consensus.ErrUnknownAncestor + } + parents = parents[:len(parents)-1] + } else { + // No explicit parents (or no more left), reach out to the database + header = chain.GetHeader(hash, number) + if header == nil { + return nil, consensus.ErrUnknownAncestor + } + } + headers = append(headers, header) + number, hash = number-1, header.ParentHash + } + // Previous snapshot found, apply any pending headers on top of it + for i := 0; i < len(headers)/2; i++ { + headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] + } + snap, err := snap.apply(headers) + if err != nil { + return nil, err + } + c.recents.Add(snap.Hash, snap) + + // If we've generated a new checkpoint snapshot, save to disk + if snap.Number%checkpointInterval == 0 && len(headers) > 0 { + if err = snap.store(c.db); err != nil { + return nil, err + } + log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash) + } + return snap, err +} + +// VerifyUncles implements consensus.Engine, always returning an error for any +// uncles as this consensus mechanism doesn't permit uncles. +func (c *Clique) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + if len(block.Uncles()) > 0 { + return errors.New("uncles not allowed") + } + return nil +} + +// VerifySeal implements consensus.Engine, checking whether the signature contained +// in the header satisfies the consensus protocol requirements. +func (c *Clique) VerifySeal(chain consensus.ChainReader, header *types.Header) error { + return c.verifySeal(chain, header, nil) +} + +// verifySeal checks whether the signature contained in the header satisfies the +// consensus protocol requirements. The method accepts an optional list of parent +// headers that aren't yet part of the local blockchain to generate the snapshots +// from. +func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { + // Verifying the genesis block is not supported + number := header.Number.Uint64() + if number == 0 { + return errUnknownBlock + } + // Retrieve the snapshot needed to verify this header and cache it + snap, err := c.snapshot(chain, number-1, header.ParentHash, parents) + if err != nil { + return err + } + + // Resolve the authorization key and check against signers + signer, err := ecrecover(header, c.signatures) + if err != nil { + return err + } + if _, ok := snap.Signers[signer]; !ok { + return errUnauthorizedSigner + } + for seen, recent := range snap.Recents { + if recent == signer { + // Signer is among recents, only fail if the current block doesn't shift it out + if limit := uint64(len(snap.Signers)/2 + 1); seen > number-limit { + return errRecentlySigned + } + } + } + // Ensure that the difficulty corresponds to the turn-ness of the signer + if !c.fakeDiff { + inturn := snap.inturn(header.Number.Uint64(), signer) + if inturn && header.Difficulty.Cmp(diffInTurn) != 0 { + return errWrongDifficulty + } + if !inturn && header.Difficulty.Cmp(diffNoTurn) != 0 { + return errWrongDifficulty + } + } + return nil +} + +// Prepare implements consensus.Engine, preparing all the consensus fields of the +// header for running the transactions on top. +func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) error { + // If the block isn't a checkpoint, cast a random vote (good enough for now) + header.Coinbase = common.Address{} + header.Nonce = types.BlockNonce{} + + number := header.Number.Uint64() + // Assemble the voting snapshot to check which votes make sense + snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return err + } + if number%c.config.Epoch != 0 { + c.lock.RLock() + + // Gather all the proposals that make sense voting on + addresses := make([]common.Address, 0, len(c.proposals)) + for address, authorize := range c.proposals { + if snap.validVote(address, authorize) { + addresses = append(addresses, address) + } + } + // If there's pending proposals, cast a vote on them + if len(addresses) > 0 { + header.Coinbase = addresses[rand.Intn(len(addresses))] + if c.proposals[header.Coinbase] { + copy(header.Nonce[:], nonceAuthVote) + } else { + copy(header.Nonce[:], nonceDropVote) + } + } + c.lock.RUnlock() + } + // Set the correct difficulty + header.Difficulty = CalcDifficulty(snap, c.signer) + + // Ensure the extra data has all it's components + if len(header.Extra) < extraVanity { + header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) + } + header.Extra = header.Extra[:extraVanity] + + if number%c.config.Epoch == 0 { + for _, signer := range snap.signers() { + header.Extra = append(header.Extra, signer[:]...) + } + } + header.Extra = append(header.Extra, make([]byte, extraSeal)...) + + // Mix digest is reserved for now, set to empty + header.MixDigest = common.Hash{} + + // Ensure the timestamp has the correct delay + parent := chain.GetHeader(header.ParentHash, number-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + header.Time = parent.Time + c.config.Period + if header.Time < uint64(time.Now().Unix()) { + header.Time = uint64(time.Now().Unix()) + } + return nil +} + +// Finalize implements consensus.Engine, ensuring no uncles are set, nor block +// rewards given. +func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { + // No block rewards in PoA, so the state remains as is and uncles are dropped + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.UncleHash = types.CalcUncleHash(nil) +} + +// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, +// nor block rewards given, and returns the final block. +func (c *Clique) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + // No block rewards in PoA, so the state remains as is and uncles are dropped + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.UncleHash = types.CalcUncleHash(nil) + + // Assemble and return the final block for sealing + return types.NewBlock(header, txs, nil, receipts), nil +} + +// Authorize injects a private key into the consensus engine to mint new blocks +// with. +func (c *Clique) Authorize(signer common.Address, signFn SignerFn) { + c.lock.Lock() + defer c.lock.Unlock() + + c.signer = signer + c.signFn = signFn +} + +// Seal implements consensus.Engine, attempting to create a sealed block using +// the local signing credentials. +func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + header := block.Header() + + // Sealing the genesis block is not supported + number := header.Number.Uint64() + if number == 0 { + return errUnknownBlock + } + // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) + if c.config.Period == 0 && len(block.Transactions()) == 0 { + log.Info("Sealing paused, waiting for transactions") + return nil + } + // Don't hold the signer fields for the entire sealing procedure + c.lock.RLock() + signer, signFn := c.signer, c.signFn + c.lock.RUnlock() + + // Bail out if we're unauthorized to sign a block + snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return err + } + if _, authorized := snap.Signers[signer]; !authorized { + return errUnauthorizedSigner + } + // If we're amongst the recent signers, wait for the next block + for seen, recent := range snap.Recents { + if recent == signer { + // Signer is among recents, only wait if the current block doesn't shift it out + if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit { + log.Info("Signed recently, must wait for others") + return nil + } + } + } + // Sweet, the protocol permits us to sign the block, wait for our time + delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple + if header.Difficulty.Cmp(diffNoTurn) == 0 { + // It's not our turn explicitly to sign, delay it a bit + wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime + delay += time.Duration(rand.Int63n(int64(wiggle))) + + log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) + } + // Sign all the things! + sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeClique, CliqueRLP(header)) + if err != nil { + return err + } + copy(header.Extra[len(header.Extra)-extraSeal:], sighash) + // Wait until sealing is terminated or delay timeout. + log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) + go func() { + select { + case <-stop: + return + case <-time.After(delay): + } + + select { + case results <- block.WithSeal(header): + default: + log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header)) + } + }() + + return nil +} + +// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty +// that a new block should have based on the previous blocks in the chain and the +// current signer. +func (c *Clique) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { + snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil) + if err != nil { + return nil + } + return CalcDifficulty(snap, c.signer) +} + +// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty +// that a new block should have based on the previous blocks in the chain and the +// current signer. +func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { + if snap.inturn(snap.Number+1, signer) { + return new(big.Int).Set(diffInTurn) + } + return new(big.Int).Set(diffNoTurn) +} + +// SealHash returns the hash of a block prior to it being sealed. +func (c *Clique) SealHash(header *types.Header) common.Hash { + return SealHash(header) +} + +// Close implements consensus.Engine. It's a noop for clique as there are no background threads. +func (c *Clique) Close() error { + return nil +} + +// APIs implements consensus.Engine, returning the user facing RPC API to allow +// controlling the signer voting. +func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API { + return []rpc.API{{ + Namespace: "clique", + Version: "1.0", + Service: &API{chain: chain, clique: c}, + Public: false, + }} +} + +// SealHash returns the hash of a block prior to it being sealed. +func SealHash(header *types.Header) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + encodeSigHeader(hasher, header) + hasher.Sum(hash[:0]) + return hash +} + +// CliqueRLP returns the rlp bytes which needs to be signed for the proof-of-authority +// sealing. The RLP to sign consists of the entire header apart from the 65 byte signature +// contained at the end of the extra data. +// +// Note, the method requires the extra data to be at least 65 bytes, otherwise it +// panics. This is done to avoid accidentally using both forms (signature present +// or not), which could be abused to produce different hashes for the same header. +func CliqueRLP(header *types.Header) []byte { + b := new(bytes.Buffer) + encodeSigHeader(b, header) + return b.Bytes() +} + +func encodeSigHeader(w io.Writer, header *types.Header) { + err := rlp.Encode(w, []interface{}{ + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short + header.MixDigest, + header.Nonce, + }) + if err != nil { + panic("can't encode: " + err.Error()) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/consensus/clique/snapshot.go b/vendor/github.com/ethereum/go-ethereum/consensus/clique/snapshot.go new file mode 100644 index 00000000..4ee731a9 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/consensus/clique/snapshot.go @@ -0,0 +1,326 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package clique + +import ( + "bytes" + "encoding/json" + "sort" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + lru "github.com/hashicorp/golang-lru" +) + +// Vote represents a single vote that an authorized signer made to modify the +// list of authorizations. +type Vote struct { + Signer common.Address `json:"signer"` // Authorized signer that cast this vote + Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes) + Address common.Address `json:"address"` // Account being voted on to change its authorization + Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account +} + +// Tally is a simple vote tally to keep the current score of votes. Votes that +// go against the proposal aren't counted since it's equivalent to not voting. +type Tally struct { + Authorize bool `json:"authorize"` // Whether the vote is about authorizing or kicking someone + Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal +} + +// Snapshot is the state of the authorization voting at a given point in time. +type Snapshot struct { + config *params.CliqueConfig // Consensus engine parameters to fine tune behavior + sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover + + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + Signers map[common.Address]struct{} `json:"signers"` // Set of authorized signers at this moment + Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections + Votes []*Vote `json:"votes"` // List of votes cast in chronological order + Tally map[common.Address]Tally `json:"tally"` // Current vote tally to avoid recalculating +} + +// signersAscending implements the sort interface to allow sorting a list of addresses +type signersAscending []common.Address + +func (s signersAscending) Len() int { return len(s) } +func (s signersAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } +func (s signersAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// newSnapshot creates a new snapshot with the specified startup parameters. This +// method does not initialize the set of recent signers, so only ever use if for +// the genesis block. +func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot { + snap := &Snapshot{ + config: config, + sigcache: sigcache, + Number: number, + Hash: hash, + Signers: make(map[common.Address]struct{}), + Recents: make(map[uint64]common.Address), + Tally: make(map[common.Address]Tally), + } + for _, signer := range signers { + snap.Signers[signer] = struct{}{} + } + return snap +} + +// loadSnapshot loads an existing snapshot from the database. +func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) { + blob, err := db.Get(append([]byte("clique-"), hash[:]...)) + if err != nil { + return nil, err + } + snap := new(Snapshot) + if err := json.Unmarshal(blob, snap); err != nil { + return nil, err + } + snap.config = config + snap.sigcache = sigcache + + return snap, nil +} + +// store inserts the snapshot into the database. +func (s *Snapshot) store(db ethdb.Database) error { + blob, err := json.Marshal(s) + if err != nil { + return err + } + return db.Put(append([]byte("clique-"), s.Hash[:]...), blob) +} + +// copy creates a deep copy of the snapshot, though not the individual votes. +func (s *Snapshot) copy() *Snapshot { + cpy := &Snapshot{ + config: s.config, + sigcache: s.sigcache, + Number: s.Number, + Hash: s.Hash, + Signers: make(map[common.Address]struct{}), + Recents: make(map[uint64]common.Address), + Votes: make([]*Vote, len(s.Votes)), + Tally: make(map[common.Address]Tally), + } + for signer := range s.Signers { + cpy.Signers[signer] = struct{}{} + } + for block, signer := range s.Recents { + cpy.Recents[block] = signer + } + for address, tally := range s.Tally { + cpy.Tally[address] = tally + } + copy(cpy.Votes, s.Votes) + + return cpy +} + +// validVote returns whether it makes sense to cast the specified vote in the +// given snapshot context (e.g. don't try to add an already authorized signer). +func (s *Snapshot) validVote(address common.Address, authorize bool) bool { + _, signer := s.Signers[address] + return (signer && !authorize) || (!signer && authorize) +} + +// cast adds a new vote into the tally. +func (s *Snapshot) cast(address common.Address, authorize bool) bool { + // Ensure the vote is meaningful + if !s.validVote(address, authorize) { + return false + } + // Cast the vote into an existing or new tally + if old, ok := s.Tally[address]; ok { + old.Votes++ + s.Tally[address] = old + } else { + s.Tally[address] = Tally{Authorize: authorize, Votes: 1} + } + return true +} + +// uncast removes a previously cast vote from the tally. +func (s *Snapshot) uncast(address common.Address, authorize bool) bool { + // If there's no tally, it's a dangling vote, just drop + tally, ok := s.Tally[address] + if !ok { + return false + } + // Ensure we only revert counted votes + if tally.Authorize != authorize { + return false + } + // Otherwise revert the vote + if tally.Votes > 1 { + tally.Votes-- + s.Tally[address] = tally + } else { + delete(s.Tally, address) + } + return true +} + +// apply creates a new authorization snapshot by applying the given headers to +// the original one. +func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { + // Allow passing in no headers for cleaner code + if len(headers) == 0 { + return s, nil + } + // Sanity check that the headers can be applied + for i := 0; i < len(headers)-1; i++ { + if headers[i+1].Number.Uint64() != headers[i].Number.Uint64()+1 { + return nil, errInvalidVotingChain + } + } + if headers[0].Number.Uint64() != s.Number+1 { + return nil, errInvalidVotingChain + } + // Iterate through the headers and create a new snapshot + snap := s.copy() + + var ( + start = time.Now() + logged = time.Now() + ) + for i, header := range headers { + // Remove any votes on checkpoint blocks + number := header.Number.Uint64() + if number%s.config.Epoch == 0 { + snap.Votes = nil + snap.Tally = make(map[common.Address]Tally) + } + // Delete the oldest signer from the recent list to allow it signing again + if limit := uint64(len(snap.Signers)/2 + 1); number >= limit { + delete(snap.Recents, number-limit) + } + // Resolve the authorization key and check against signers + signer, err := ecrecover(header, s.sigcache) + if err != nil { + return nil, err + } + if _, ok := snap.Signers[signer]; !ok { + return nil, errUnauthorizedSigner + } + for _, recent := range snap.Recents { + if recent == signer { + return nil, errRecentlySigned + } + } + snap.Recents[number] = signer + + // Header authorized, discard any previous votes from the signer + for i, vote := range snap.Votes { + if vote.Signer == signer && vote.Address == header.Coinbase { + // Uncast the vote from the cached tally + snap.uncast(vote.Address, vote.Authorize) + + // Uncast the vote from the chronological list + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + break // only one vote allowed + } + } + // Tally up the new vote from the signer + var authorize bool + switch { + case bytes.Equal(header.Nonce[:], nonceAuthVote): + authorize = true + case bytes.Equal(header.Nonce[:], nonceDropVote): + authorize = false + default: + return nil, errInvalidVote + } + if snap.cast(header.Coinbase, authorize) { + snap.Votes = append(snap.Votes, &Vote{ + Signer: signer, + Block: number, + Address: header.Coinbase, + Authorize: authorize, + }) + } + // If the vote passed, update the list of signers + if tally := snap.Tally[header.Coinbase]; tally.Votes > len(snap.Signers)/2 { + if tally.Authorize { + snap.Signers[header.Coinbase] = struct{}{} + } else { + delete(snap.Signers, header.Coinbase) + + // Signer list shrunk, delete any leftover recent caches + if limit := uint64(len(snap.Signers)/2 + 1); number >= limit { + delete(snap.Recents, number-limit) + } + // Discard any previous votes the deauthorized signer cast + for i := 0; i < len(snap.Votes); i++ { + if snap.Votes[i].Signer == header.Coinbase { + // Uncast the vote from the cached tally + snap.uncast(snap.Votes[i].Address, snap.Votes[i].Authorize) + + // Uncast the vote from the chronological list + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + + i-- + } + } + } + // Discard any previous votes around the just changed account + for i := 0; i < len(snap.Votes); i++ { + if snap.Votes[i].Address == header.Coinbase { + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + i-- + } + } + delete(snap.Tally, header.Coinbase) + } + // If we're taking too much time (ecrecover), notify the user once a while + if time.Since(logged) > 8*time.Second { + log.Info("Reconstructing voting history", "processed", i, "total", len(headers), "elapsed", common.PrettyDuration(time.Since(start))) + logged = time.Now() + } + } + if time.Since(start) > 8*time.Second { + log.Info("Reconstructed voting history", "processed", len(headers), "elapsed", common.PrettyDuration(time.Since(start))) + } + snap.Number += uint64(len(headers)) + snap.Hash = headers[len(headers)-1].Hash() + + return snap, nil +} + +// signers retrieves the list of authorized signers in ascending order. +func (s *Snapshot) signers() []common.Address { + sigs := make([]common.Address, 0, len(s.Signers)) + for sig := range s.Signers { + sigs = append(sigs, sig) + } + sort.Sort(signersAscending(sigs)) + return sigs +} + +// inturn returns if a signer at a given block height is in-turn or not. +func (s *Snapshot) inturn(number uint64, signer common.Address) bool { + signers, offset := s.signers(), 0 + for offset < len(signers) && signers[offset] != signer { + offset++ + } + return (number % uint64(len(signers))) == uint64(offset) +} diff --git a/vendor/github.com/ethereum/go-ethereum/consensus/consensus.go b/vendor/github.com/ethereum/go-ethereum/consensus/consensus.go new file mode 100644 index 00000000..f753af55 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/consensus/consensus.go @@ -0,0 +1,125 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package consensus implements different Ethereum consensus engines. +package consensus + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +// ChainReader defines a small collection of methods needed to access the local +// blockchain during header and/or uncle verification. +type ChainReader interface { + // Config retrieves the blockchain's chain configuration. + Config() *params.ChainConfig + + // CurrentHeader retrieves the current header from the local chain. + CurrentHeader() *types.Header + + // GetHeader retrieves a block header from the database by hash and number. + GetHeader(hash common.Hash, number uint64) *types.Header + + // GetHeaderByNumber retrieves a block header from the database by number. + GetHeaderByNumber(number uint64) *types.Header + + // GetHeaderByHash retrieves a block header from the database by its hash. + GetHeaderByHash(hash common.Hash) *types.Header + + // GetBlock retrieves a block from the database by hash and number. + GetBlock(hash common.Hash, number uint64) *types.Block +} + +// Engine is an algorithm agnostic consensus engine. +type Engine interface { + // Author retrieves the Ethereum address of the account that minted the given + // block, which may be different from the header's coinbase if a consensus + // engine is based on signatures. + Author(header *types.Header) (common.Address, error) + + // VerifyHeader checks whether a header conforms to the consensus rules of a + // given engine. Verifying the seal may be done optionally here, or explicitly + // via the VerifySeal method. + VerifyHeader(chain ChainReader, header *types.Header, seal bool) error + + // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers + // concurrently. The method returns a quit channel to abort the operations and + // a results channel to retrieve the async verifications (the order is that of + // the input slice). + VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) + + // VerifyUncles verifies that the given block's uncles conform to the consensus + // rules of a given engine. + VerifyUncles(chain ChainReader, block *types.Block) error + + // VerifySeal checks whether the crypto seal on a header is valid according to + // the consensus rules of the given engine. + VerifySeal(chain ChainReader, header *types.Header) error + + // Prepare initializes the consensus fields of a block header according to the + // rules of a particular engine. The changes are executed inline. + Prepare(chain ChainReader, header *types.Header) error + + // Finalize runs any post-transaction state modifications (e.g. block rewards) + // but does not assemble the block. + // + // Note: The block header and state database might be updated to reflect any + // consensus rules that happen at finalization (e.g. block rewards). + Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, + uncles []*types.Header) + + // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block + // rewards) and assembles the final block. + // + // Note: The block header and state database might be updated to reflect any + // consensus rules that happen at finalization (e.g. block rewards). + FinalizeAndAssemble(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, + uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) + + // Seal generates a new sealing request for the given input block and pushes + // the result into the given channel. + // + // Note, the method returns immediately and will send the result async. More + // than one result may also be returned depending on the consensus algorithm. + Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error + + // SealHash returns the hash of a block prior to it being sealed. + SealHash(header *types.Header) common.Hash + + // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty + // that a new block should have. + CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int + + // APIs returns the RPC APIs this consensus engine provides. + APIs(chain ChainReader) []rpc.API + + // Close terminates any background threads maintained by the consensus engine. + Close() error +} + +// PoW is a consensus engine based on proof-of-work. +type PoW interface { + Engine + + // Hashrate returns the current mining hashrate of a PoW consensus engine. + Hashrate() float64 +} diff --git a/vendor/github.com/ethereum/go-ethereum/consensus/ethash/consensus.go b/vendor/github.com/ethereum/go-ethereum/consensus/ethash/consensus.go new file mode 100644 index 00000000..d271518f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/consensus/ethash/consensus.go @@ -0,0 +1,637 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethash + +import ( + "bytes" + "errors" + "fmt" + "math/big" + "runtime" + "time" + + mapset "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/crypto/sha3" +) + +// Ethash proof-of-work protocol constants. +var ( + FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block + ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium + ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople + maxUncles = 2 // Maximum number of uncles allowed in a single block + allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks + + // calcDifficultyConstantinople is the difficulty adjustment algorithm for Constantinople. + // It returns the difficulty that a new block should have when created at time given the + // parent block's time and difficulty. The calculation uses the Byzantium rules, but with + // bomb offset 5M. + // Specification EIP-1234: https://eips.ethereum.org/EIPS/eip-1234 + calcDifficultyConstantinople = makeDifficultyCalculator(big.NewInt(5000000)) + + // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns + // the difficulty that a new block should have when created at time given the + // parent block's time and difficulty. The calculation uses the Byzantium rules. + // Specification EIP-649: https://eips.ethereum.org/EIPS/eip-649 + calcDifficultyByzantium = makeDifficultyCalculator(big.NewInt(3000000)) +) + +// Various error messages to mark blocks invalid. These should be private to +// prevent engine specific errors from being referenced in the remainder of the +// codebase, inherently breaking if the engine is swapped out. Please put common +// error types into the consensus package. +var ( + errZeroBlockTime = errors.New("timestamp equals parent's") + errTooManyUncles = errors.New("too many uncles") + errDuplicateUncle = errors.New("duplicate uncle") + errUncleIsAncestor = errors.New("uncle is ancestor") + errDanglingUncle = errors.New("uncle's parent is not ancestor") + errInvalidDifficulty = errors.New("non-positive difficulty") + errInvalidMixDigest = errors.New("invalid mix digest") + errInvalidPoW = errors.New("invalid proof-of-work") +) + +// Author implements consensus.Engine, returning the header's coinbase as the +// proof-of-work verified author of the block. +func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { + return header.Coinbase, nil +} + +// VerifyHeader checks whether a header conforms to the consensus rules of the +// stock Ethereum ethash engine. +func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { + // If we're running a full engine faking, accept any input as valid + if ethash.config.PowMode == ModeFullFake { + return nil + } + // Short circuit if the header is known, or it's parent not + number := header.Number.Uint64() + if chain.GetHeader(header.Hash(), number) != nil { + return nil + } + parent := chain.GetHeader(header.ParentHash, number-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + // Sanity checks passed, do a proper verification + return ethash.verifyHeader(chain, header, parent, false, seal) +} + +// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers +// concurrently. The method returns a quit channel to abort the operations and +// a results channel to retrieve the async verifications. +func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { + // If we're running a full engine faking, accept any input as valid + if ethash.config.PowMode == ModeFullFake || len(headers) == 0 { + abort, results := make(chan struct{}), make(chan error, len(headers)) + for i := 0; i < len(headers); i++ { + results <- nil + } + return abort, results + } + + // Spawn as many workers as allowed threads + workers := runtime.GOMAXPROCS(0) + if len(headers) < workers { + workers = len(headers) + } + + // Create a task channel and spawn the verifiers + var ( + inputs = make(chan int) + done = make(chan int, workers) + errors = make([]error, len(headers)) + abort = make(chan struct{}) + ) + for i := 0; i < workers; i++ { + go func() { + for index := range inputs { + errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index) + done <- index + } + }() + } + + errorsOut := make(chan error, len(headers)) + go func() { + defer close(inputs) + var ( + in, out = 0, 0 + checked = make([]bool, len(headers)) + inputs = inputs + ) + for { + select { + case inputs <- in: + if in++; in == len(headers) { + // Reached end of headers. Stop sending to workers. + inputs = nil + } + case index := <-done: + for checked[index] = true; checked[out]; out++ { + errorsOut <- errors[out] + if out == len(headers)-1 { + return + } + } + case <-abort: + return + } + } + }() + return abort, errorsOut +} + +func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error { + var parent *types.Header + if index == 0 { + parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) + } else if headers[index-1].Hash() == headers[index].ParentHash { + parent = headers[index-1] + } + if parent == nil { + return consensus.ErrUnknownAncestor + } + if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { + return nil // known block + } + return ethash.verifyHeader(chain, headers[index], parent, false, seals[index]) +} + +// VerifyUncles verifies that the given block's uncles conform to the consensus +// rules of the stock Ethereum ethash engine. +func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + // If we're running a full engine faking, accept any input as valid + if ethash.config.PowMode == ModeFullFake { + return nil + } + // Verify that there are at most 2 uncles included in this block + if len(block.Uncles()) > maxUncles { + return errTooManyUncles + } + if len(block.Uncles()) == 0 { + return nil + } + // Gather the set of past uncles and ancestors + uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header) + + number, parent := block.NumberU64()-1, block.ParentHash() + for i := 0; i < 7; i++ { + ancestor := chain.GetBlock(parent, number) + if ancestor == nil { + break + } + ancestors[ancestor.Hash()] = ancestor.Header() + for _, uncle := range ancestor.Uncles() { + uncles.Add(uncle.Hash()) + } + parent, number = ancestor.ParentHash(), number-1 + } + ancestors[block.Hash()] = block.Header() + uncles.Add(block.Hash()) + + // Verify each of the uncles that it's recent, but not an ancestor + for _, uncle := range block.Uncles() { + // Make sure every uncle is rewarded only once + hash := uncle.Hash() + if uncles.Contains(hash) { + return errDuplicateUncle + } + uncles.Add(hash) + + // Make sure the uncle has a valid ancestry + if ancestors[hash] != nil { + return errUncleIsAncestor + } + if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() { + return errDanglingUncle + } + if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil { + return err + } + } + return nil +} + +// verifyHeader checks whether a header conforms to the consensus rules of the +// stock Ethereum ethash engine. +// See YP section 4.3.4. "Block Header Validity" +func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error { + // Ensure that the header's extra-data section is of a reasonable size + if uint64(len(header.Extra)) > params.MaximumExtraDataSize { + return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize) + } + // Verify the header's timestamp + if !uncle { + if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) { + return consensus.ErrFutureBlock + } + } + if header.Time <= parent.Time { + return errZeroBlockTime + } + // Verify the block's difficulty based in it's timestamp and parent's difficulty + expected := ethash.CalcDifficulty(chain, header.Time, parent) + + if expected.Cmp(header.Difficulty) != 0 { + return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) + } + // Verify that the gas limit is <= 2^63-1 + cap := uint64(0x7fffffffffffffff) + if header.GasLimit > cap { + return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) + } + // Verify that the gasUsed is <= gasLimit + if header.GasUsed > header.GasLimit { + return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) + } + + // Verify that the gas limit remains within allowed bounds + diff := int64(parent.GasLimit) - int64(header.GasLimit) + if diff < 0 { + diff *= -1 + } + limit := parent.GasLimit / params.GasLimitBoundDivisor + + if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { + return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) + } + // Verify that the block number is parent's +1 + if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { + return consensus.ErrInvalidNumber + } + // Verify the engine specific seal securing the block + if seal { + if err := ethash.VerifySeal(chain, header); err != nil { + return err + } + } + // If all checks passed, validate any special fields for hard forks + if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil { + return err + } + if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil { + return err + } + return nil +} + +// CalcDifficulty is the difficulty adjustment algorithm. It returns +// the difficulty that a new block should have when created at time +// given the parent block's time and difficulty. +func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { + return CalcDifficulty(chain.Config(), time, parent) +} + +// CalcDifficulty is the difficulty adjustment algorithm. It returns +// the difficulty that a new block should have when created at time +// given the parent block's time and difficulty. +func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { + next := new(big.Int).Add(parent.Number, big1) + switch { + case config.IsConstantinople(next): + return calcDifficultyConstantinople(time, parent) + case config.IsByzantium(next): + return calcDifficultyByzantium(time, parent) + case config.IsHomestead(next): + return calcDifficultyHomestead(time, parent) + default: + return calcDifficultyFrontier(time, parent) + } +} + +// Some weird constants to avoid constant memory allocs for them. +var ( + expDiffPeriod = big.NewInt(100000) + big1 = big.NewInt(1) + big2 = big.NewInt(2) + big9 = big.NewInt(9) + big10 = big.NewInt(10) + bigMinus99 = big.NewInt(-99) +) + +// makeDifficultyCalculator creates a difficultyCalculator with the given bomb-delay. +// the difficulty is calculated with Byzantium rules, which differs from Homestead in +// how uncles affect the calculation +func makeDifficultyCalculator(bombDelay *big.Int) func(time uint64, parent *types.Header) *big.Int { + // Note, the calculations below looks at the parent number, which is 1 below + // the block number. Thus we remove one from the delay given + bombDelayFromParent := new(big.Int).Sub(bombDelay, big1) + return func(time uint64, parent *types.Header) *big.Int { + // https://github.com/ethereum/EIPs/issues/100. + // algorithm: + // diff = (parent_diff + + // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) + // ) + 2^(periodCount - 2) + + bigTime := new(big.Int).SetUint64(time) + bigParentTime := new(big.Int).SetUint64(parent.Time) + + // holds intermediate values to make the algo easier to read & audit + x := new(big.Int) + y := new(big.Int) + + // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 + x.Sub(bigTime, bigParentTime) + x.Div(x, big9) + if parent.UncleHash == types.EmptyUncleHash { + x.Sub(big1, x) + } else { + x.Sub(big2, x) + } + // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) + if x.Cmp(bigMinus99) < 0 { + x.Set(bigMinus99) + } + // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) + y.Div(parent.Difficulty, params.DifficultyBoundDivisor) + x.Mul(y, x) + x.Add(parent.Difficulty, x) + + // minimum difficulty can ever be (before exponential factor) + if x.Cmp(params.MinimumDifficulty) < 0 { + x.Set(params.MinimumDifficulty) + } + // calculate a fake block number for the ice-age delay + // Specification: https://eips.ethereum.org/EIPS/eip-1234 + fakeBlockNumber := new(big.Int) + if parent.Number.Cmp(bombDelayFromParent) >= 0 { + fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, bombDelayFromParent) + } + // for the exponential factor + periodCount := fakeBlockNumber + periodCount.Div(periodCount, expDiffPeriod) + + // the exponential factor, commonly referred to as "the bomb" + // diff = diff + 2^(periodCount - 2) + if periodCount.Cmp(big1) > 0 { + y.Sub(periodCount, big2) + y.Exp(big2, y, nil) + x.Add(x, y) + } + return x + } +} + +// calcDifficultyHomestead is the difficulty adjustment algorithm. It returns +// the difficulty that a new block should have when created at time given the +// parent block's time and difficulty. The calculation uses the Homestead rules. +func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int { + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md + // algorithm: + // diff = (parent_diff + + // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) + // ) + 2^(periodCount - 2) + + bigTime := new(big.Int).SetUint64(time) + bigParentTime := new(big.Int).SetUint64(parent.Time) + + // holds intermediate values to make the algo easier to read & audit + x := new(big.Int) + y := new(big.Int) + + // 1 - (block_timestamp - parent_timestamp) // 10 + x.Sub(bigTime, bigParentTime) + x.Div(x, big10) + x.Sub(big1, x) + + // max(1 - (block_timestamp - parent_timestamp) // 10, -99) + if x.Cmp(bigMinus99) < 0 { + x.Set(bigMinus99) + } + // (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) + y.Div(parent.Difficulty, params.DifficultyBoundDivisor) + x.Mul(y, x) + x.Add(parent.Difficulty, x) + + // minimum difficulty can ever be (before exponential factor) + if x.Cmp(params.MinimumDifficulty) < 0 { + x.Set(params.MinimumDifficulty) + } + // for the exponential factor + periodCount := new(big.Int).Add(parent.Number, big1) + periodCount.Div(periodCount, expDiffPeriod) + + // the exponential factor, commonly referred to as "the bomb" + // diff = diff + 2^(periodCount - 2) + if periodCount.Cmp(big1) > 0 { + y.Sub(periodCount, big2) + y.Exp(big2, y, nil) + x.Add(x, y) + } + return x +} + +// calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the +// difficulty that a new block should have when created at time given the parent +// block's time and difficulty. The calculation uses the Frontier rules. +func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { + diff := new(big.Int) + adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor) + bigTime := new(big.Int) + bigParentTime := new(big.Int) + + bigTime.SetUint64(time) + bigParentTime.SetUint64(parent.Time) + + if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 { + diff.Add(parent.Difficulty, adjust) + } else { + diff.Sub(parent.Difficulty, adjust) + } + if diff.Cmp(params.MinimumDifficulty) < 0 { + diff.Set(params.MinimumDifficulty) + } + + periodCount := new(big.Int).Add(parent.Number, big1) + periodCount.Div(periodCount, expDiffPeriod) + if periodCount.Cmp(big1) > 0 { + // diff = diff + 2^(periodCount - 2) + expDiff := periodCount.Sub(periodCount, big2) + expDiff.Exp(big2, expDiff, nil) + diff.Add(diff, expDiff) + diff = math.BigMax(diff, params.MinimumDifficulty) + } + return diff +} + +// VerifySeal implements consensus.Engine, checking whether the given block satisfies +// the PoW difficulty requirements. +func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { + return ethash.verifySeal(chain, header, false) +} + +// verifySeal checks whether a block satisfies the PoW difficulty requirements, +// either using the usual ethash cache for it, or alternatively using a full DAG +// to make remote mining fast. +func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Header, fulldag bool) error { + // If we're running a fake PoW, accept any seal as valid + if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { + time.Sleep(ethash.fakeDelay) + if ethash.fakeFail == header.Number.Uint64() { + return errInvalidPoW + } + return nil + } + // If we're running a shared PoW, delegate verification to it + if ethash.shared != nil { + return ethash.shared.verifySeal(chain, header, fulldag) + } + // Ensure that we have a valid difficulty for the block + if header.Difficulty.Sign() <= 0 { + return errInvalidDifficulty + } + // Recompute the digest and PoW values + number := header.Number.Uint64() + + var ( + digest []byte + result []byte + ) + // If fast-but-heavy PoW verification was requested, use an ethash dataset + if fulldag { + dataset := ethash.dataset(number, true) + if dataset.generated() { + digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + + // Datasets are unmapped in a finalizer. Ensure that the dataset stays alive + // until after the call to hashimotoFull so it's not unmapped while being used. + runtime.KeepAlive(dataset) + } else { + // Dataset not yet generated, don't hang, use a cache instead + fulldag = false + } + } + // If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cache + if !fulldag { + cache := ethash.cache(number) + + size := datasetSize(number) + if ethash.config.PowMode == ModeTest { + size = 32 * 1024 + } + digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + + // Caches are unmapped in a finalizer. Ensure that the cache stays alive + // until after the call to hashimotoLight so it's not unmapped while being used. + runtime.KeepAlive(cache) + } + // Verify the calculated values against the ones provided in the header + if !bytes.Equal(header.MixDigest[:], digest) { + return errInvalidMixDigest + } + target := new(big.Int).Div(two256, header.Difficulty) + if new(big.Int).SetBytes(result).Cmp(target) > 0 { + return errInvalidPoW + } + return nil +} + +// Prepare implements consensus.Engine, initializing the difficulty field of a +// header to conform to the ethash protocol. The changes are done inline. +func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error { + parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + header.Difficulty = ethash.CalcDifficulty(chain, header.Time, parent) + return nil +} + +// Finalize implements consensus.Engine, accumulating the block and uncle rewards, +// setting the final state on the header +func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { + // Accumulate any block and uncle rewards and commit the final state root + accumulateRewards(chain.Config(), state, header, uncles) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) +} + +// FinalizeAndAssemble implements consensus.Engine, accumulating the block and +// uncle rewards, setting the final state and assembling the block. +func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + // Accumulate any block and uncle rewards and commit the final state root + accumulateRewards(chain.Config(), state, header, uncles) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + + // Header seems complete, assemble into a block and return + return types.NewBlock(header, txs, uncles, receipts), nil +} + +// SealHash returns the hash of a block prior to it being sealed. +func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + + rlp.Encode(hasher, []interface{}{ + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra, + }) + hasher.Sum(hash[:0]) + return hash +} + +// Some weird constants to avoid constant memory allocs for them. +var ( + big8 = big.NewInt(8) + big32 = big.NewInt(32) +) + +// AccumulateRewards credits the coinbase of the given block with the mining +// reward. The total reward consists of the static block reward and rewards for +// included uncles. The coinbase of each uncle block is also rewarded. +func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { + // Select the correct block reward based on chain progression + blockReward := FrontierBlockReward + if config.IsByzantium(header.Number) { + blockReward = ByzantiumBlockReward + } + if config.IsConstantinople(header.Number) { + blockReward = ConstantinopleBlockReward + } + // Accumulate the rewards for the miner and any included uncles + reward := new(big.Int).Set(blockReward) + r := new(big.Int) + for _, uncle := range uncles { + r.Add(uncle.Number, big8) + r.Sub(r, header.Number) + r.Mul(r, blockReward) + r.Div(r, big8) + state.AddBalance(uncle.Coinbase, r) + + r.Div(blockReward, big32) + reward.Add(reward, r) + } + state.AddBalance(header.Coinbase, reward) +} diff --git a/vendor/github.com/ethereum/go-ethereum/consensus/ethash/sealer.go b/vendor/github.com/ethereum/go-ethereum/consensus/ethash/sealer.go new file mode 100644 index 00000000..43db1fcb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/consensus/ethash/sealer.go @@ -0,0 +1,371 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethash + +import ( + "bytes" + crand "crypto/rand" + "encoding/json" + "errors" + "math" + "math/big" + "math/rand" + "net/http" + "runtime" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +const ( + // staleThreshold is the maximum depth of the acceptable stale but valid ethash solution. + staleThreshold = 7 +) + +var ( + errNoMiningWork = errors.New("no mining work available yet") + errInvalidSealResult = errors.New("invalid or stale proof-of-work solution") +) + +// Seal implements consensus.Engine, attempting to find a nonce that satisfies +// the block's difficulty requirements. +func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + // If we're running a fake PoW, simply return a 0 nonce immediately + if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { + header := block.Header() + header.Nonce, header.MixDigest = types.BlockNonce{}, common.Hash{} + select { + case results <- block.WithSeal(header): + default: + log.Warn("Sealing result is not read by miner", "mode", "fake", "sealhash", ethash.SealHash(block.Header())) + } + return nil + } + // If we're running a shared PoW, delegate sealing to it + if ethash.shared != nil { + return ethash.shared.Seal(chain, block, results, stop) + } + // Create a runner and the multiple search threads it directs + abort := make(chan struct{}) + + ethash.lock.Lock() + threads := ethash.threads + if ethash.rand == nil { + seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64)) + if err != nil { + ethash.lock.Unlock() + return err + } + ethash.rand = rand.New(rand.NewSource(seed.Int64())) + } + ethash.lock.Unlock() + if threads == 0 { + threads = runtime.NumCPU() + } + if threads < 0 { + threads = 0 // Allows disabling local mining without extra logic around local/remote + } + // Push new work to remote sealer + if ethash.workCh != nil { + ethash.workCh <- &sealTask{block: block, results: results} + } + var ( + pend sync.WaitGroup + locals = make(chan *types.Block) + ) + for i := 0; i < threads; i++ { + pend.Add(1) + go func(id int, nonce uint64) { + defer pend.Done() + ethash.mine(block, id, nonce, abort, locals) + }(i, uint64(ethash.rand.Int63())) + } + // Wait until sealing is terminated or a nonce is found + go func() { + var result *types.Block + select { + case <-stop: + // Outside abort, stop all miner threads + close(abort) + case result = <-locals: + // One of the threads found a block, abort all others + select { + case results <- result: + default: + log.Warn("Sealing result is not read by miner", "mode", "local", "sealhash", ethash.SealHash(block.Header())) + } + close(abort) + case <-ethash.update: + // Thread count was changed on user request, restart + close(abort) + if err := ethash.Seal(chain, block, results, stop); err != nil { + log.Error("Failed to restart sealing after update", "err", err) + } + } + // Wait for all miners to terminate and return the block + pend.Wait() + }() + return nil +} + +// mine is the actual proof-of-work miner that searches for a nonce starting from +// seed that results in correct final block difficulty. +func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) { + // Extract some data from the header + var ( + header = block.Header() + hash = ethash.SealHash(header).Bytes() + target = new(big.Int).Div(two256, header.Difficulty) + number = header.Number.Uint64() + dataset = ethash.dataset(number, false) + ) + // Start generating random nonces until we abort or find a good one + var ( + attempts = int64(0) + nonce = seed + ) + logger := log.New("miner", id) + logger.Trace("Started ethash search for new nonces", "seed", seed) +search: + for { + select { + case <-abort: + // Mining terminated, update stats and abort + logger.Trace("Ethash nonce search aborted", "attempts", nonce-seed) + ethash.hashrate.Mark(attempts) + break search + + default: + // We don't have to update hash rate on every nonce, so update after after 2^X nonces + attempts++ + if (attempts % (1 << 15)) == 0 { + ethash.hashrate.Mark(attempts) + attempts = 0 + } + // Compute the PoW value of this nonce + digest, result := hashimotoFull(dataset.dataset, hash, nonce) + if new(big.Int).SetBytes(result).Cmp(target) <= 0 { + // Correct nonce found, create a new header with it + header = types.CopyHeader(header) + header.Nonce = types.EncodeNonce(nonce) + header.MixDigest = common.BytesToHash(digest) + + // Seal and return a block (if still needed) + select { + case found <- block.WithSeal(header): + logger.Trace("Ethash nonce found and reported", "attempts", nonce-seed, "nonce", nonce) + case <-abort: + logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce) + } + break search + } + nonce++ + } + } + // Datasets are unmapped in a finalizer. Ensure that the dataset stays live + // during sealing so it's not unmapped while being read. + runtime.KeepAlive(dataset) +} + +// remote is a standalone goroutine to handle remote mining related stuff. +func (ethash *Ethash) remote(notify []string, noverify bool) { + var ( + works = make(map[common.Hash]*types.Block) + rates = make(map[common.Hash]hashrate) + + results chan<- *types.Block + currentBlock *types.Block + currentWork [4]string + + notifyTransport = &http.Transport{} + notifyClient = &http.Client{ + Transport: notifyTransport, + Timeout: time.Second, + } + notifyReqs = make([]*http.Request, len(notify)) + ) + // notifyWork notifies all the specified mining endpoints of the availability of + // new work to be processed. + notifyWork := func() { + work := currentWork + blob, _ := json.Marshal(work) + + for i, url := range notify { + // Terminate any previously pending request and create the new work + if notifyReqs[i] != nil { + notifyTransport.CancelRequest(notifyReqs[i]) + } + notifyReqs[i], _ = http.NewRequest("POST", url, bytes.NewReader(blob)) + notifyReqs[i].Header.Set("Content-Type", "application/json") + + // Push the new work concurrently to all the remote nodes + go func(req *http.Request, url string) { + res, err := notifyClient.Do(req) + if err != nil { + log.Warn("Failed to notify remote miner", "err", err) + } else { + log.Trace("Notified remote miner", "miner", url, "hash", log.Lazy{Fn: func() common.Hash { return common.HexToHash(work[0]) }}, "target", work[2]) + res.Body.Close() + } + }(notifyReqs[i], url) + } + } + // makeWork creates a work package for external miner. + // + // The work package consists of 3 strings: + // result[0], 32 bytes hex encoded current block header pow-hash + // result[1], 32 bytes hex encoded seed hash used for DAG + // result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty + // result[3], hex encoded block number + makeWork := func(block *types.Block) { + hash := ethash.SealHash(block.Header()) + + currentWork[0] = hash.Hex() + currentWork[1] = common.BytesToHash(SeedHash(block.NumberU64())).Hex() + currentWork[2] = common.BytesToHash(new(big.Int).Div(two256, block.Difficulty()).Bytes()).Hex() + currentWork[3] = hexutil.EncodeBig(block.Number()) + + // Trace the seal work fetched by remote sealer. + currentBlock = block + works[hash] = block + } + // submitWork verifies the submitted pow solution, returning + // whether the solution was accepted or not (not can be both a bad pow as well as + // any other error, like no pending work or stale mining result). + submitWork := func(nonce types.BlockNonce, mixDigest common.Hash, sealhash common.Hash) bool { + if currentBlock == nil { + log.Error("Pending work without block", "sealhash", sealhash) + return false + } + // Make sure the work submitted is present + block := works[sealhash] + if block == nil { + log.Warn("Work submitted but none pending", "sealhash", sealhash, "curnumber", currentBlock.NumberU64()) + return false + } + // Verify the correctness of submitted result. + header := block.Header() + header.Nonce = nonce + header.MixDigest = mixDigest + + start := time.Now() + if !noverify { + if err := ethash.verifySeal(nil, header, true); err != nil { + log.Warn("Invalid proof-of-work submitted", "sealhash", sealhash, "elapsed", common.PrettyDuration(time.Since(start)), "err", err) + return false + } + } + // Make sure the result channel is assigned. + if results == nil { + log.Warn("Ethash result channel is empty, submitted mining result is rejected") + return false + } + log.Trace("Verified correct proof-of-work", "sealhash", sealhash, "elapsed", common.PrettyDuration(time.Since(start))) + + // Solutions seems to be valid, return to the miner and notify acceptance. + solution := block.WithSeal(header) + + // The submitted solution is within the scope of acceptance. + if solution.NumberU64()+staleThreshold > currentBlock.NumberU64() { + select { + case results <- solution: + log.Debug("Work submitted is acceptable", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash()) + return true + default: + log.Warn("Sealing result is not read by miner", "mode", "remote", "sealhash", sealhash) + return false + } + } + // The submitted block is too old to accept, drop it. + log.Warn("Work submitted is too old", "number", solution.NumberU64(), "sealhash", sealhash, "hash", solution.Hash()) + return false + } + + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + for { + select { + case work := <-ethash.workCh: + // Update current work with new received block. + // Note same work can be past twice, happens when changing CPU threads. + results = work.results + + makeWork(work.block) + + // Notify and requested URLs of the new work availability + notifyWork() + + case work := <-ethash.fetchWorkCh: + // Return current mining work to remote miner. + if currentBlock == nil { + work.errc <- errNoMiningWork + } else { + work.res <- currentWork + } + + case result := <-ethash.submitWorkCh: + // Verify submitted PoW solution based on maintained mining blocks. + if submitWork(result.nonce, result.mixDigest, result.hash) { + result.errc <- nil + } else { + result.errc <- errInvalidSealResult + } + + case result := <-ethash.submitRateCh: + // Trace remote sealer's hash rate by submitted value. + rates[result.id] = hashrate{rate: result.rate, ping: time.Now()} + close(result.done) + + case req := <-ethash.fetchRateCh: + // Gather all hash rate submitted by remote sealer. + var total uint64 + for _, rate := range rates { + // this could overflow + total += rate.rate + } + req <- total + + case <-ticker.C: + // Clear stale submitted hash rate. + for id, rate := range rates { + if time.Since(rate.ping) > 10*time.Second { + delete(rates, id) + } + } + // Clear stale pending blocks + if currentBlock != nil { + for hash, block := range works { + if block.NumberU64()+staleThreshold <= currentBlock.NumberU64() { + delete(works, hash) + } + } + } + + case errc := <-ethash.exitCh: + // Exit remote loop if ethash is closed and return relevant error. + errc <- nil + log.Trace("Ethash remote sealer is exiting") + return + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/console/bridge.go b/vendor/github.com/ethereum/go-ethereum/console/bridge.go new file mode 100644 index 00000000..bb14abca --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/console/bridge.go @@ -0,0 +1,438 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package console + +import ( + "encoding/json" + "fmt" + "io" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/scwallet" + "github.com/ethereum/go-ethereum/accounts/usbwallet" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" + "github.com/robertkrimen/otto" +) + +// bridge is a collection of JavaScript utility methods to bride the .js runtime +// environment and the Go RPC connection backing the remote method calls. +type bridge struct { + client *rpc.Client // RPC client to execute Ethereum requests through + prompter UserPrompter // Input prompter to allow interactive user feedback + printer io.Writer // Output writer to serialize any display strings to +} + +// newBridge creates a new JavaScript wrapper around an RPC client. +func newBridge(client *rpc.Client, prompter UserPrompter, printer io.Writer) *bridge { + return &bridge{ + client: client, + prompter: prompter, + printer: printer, + } +} + +// NewAccount is a wrapper around the personal.newAccount RPC method that uses a +// non-echoing password prompt to acquire the passphrase and executes the original +// RPC method (saved in jeth.newAccount) with it to actually execute the RPC call. +func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) { + var ( + password string + confirm string + err error + ) + switch { + // No password was specified, prompt the user for it + case len(call.ArgumentList) == 0: + if password, err = b.prompter.PromptPassword("Passphrase: "); err != nil { + throwJSException(err.Error()) + } + if confirm, err = b.prompter.PromptPassword("Repeat passphrase: "); err != nil { + throwJSException(err.Error()) + } + if password != confirm { + throwJSException("passphrases don't match!") + } + + // A single string password was specified, use that + case len(call.ArgumentList) == 1 && call.Argument(0).IsString(): + password, _ = call.Argument(0).ToString() + + // Otherwise fail with some error + default: + throwJSException("expected 0 or 1 string argument") + } + // Password acquired, execute the call and return + ret, err := call.Otto.Call("jeth.newAccount", nil, password) + if err != nil { + throwJSException(err.Error()) + } + return ret +} + +// OpenWallet is a wrapper around personal.openWallet which can interpret and +// react to certain error messages, such as the Trezor PIN matrix request. +func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) { + // Make sure we have a wallet specified to open + if !call.Argument(0).IsString() { + throwJSException("first argument must be the wallet URL to open") + } + wallet := call.Argument(0) + + var passwd otto.Value + if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() { + passwd, _ = otto.ToValue("") + } else { + passwd = call.Argument(1) + } + // Open the wallet and return if successful in itself + val, err := call.Otto.Call("jeth.openWallet", nil, wallet, passwd) + if err == nil { + return val + } + + // Wallet open failed, report error unless it's a PIN or PUK entry + switch { + case strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()): + val, err = b.readPinAndReopenWallet(call) + if err == nil { + return val + } + val, err = b.readPassphraseAndReopenWallet(call) + if err != nil { + throwJSException(err.Error()) + } + + case strings.HasSuffix(err.Error(), scwallet.ErrPairingPasswordNeeded.Error()): + // PUK input requested, fetch from the user and call open again + if input, err := b.prompter.PromptPassword("Please enter the pairing password: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil { + if !strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()) { + throwJSException(err.Error()) + } else { + // PIN input requested, fetch from the user and call open again + if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil { + throwJSException(err.Error()) + } + } + } + + case strings.HasSuffix(err.Error(), scwallet.ErrPINUnblockNeeded.Error()): + // PIN unblock requested, fetch PUK and new PIN from the user + var pukpin string + if input, err := b.prompter.PromptPassword("Please enter current PUK: "); err != nil { + throwJSException(err.Error()) + } else { + pukpin = input + } + if input, err := b.prompter.PromptPassword("Please enter new PIN: "); err != nil { + throwJSException(err.Error()) + } else { + pukpin += input + } + passwd, _ = otto.ToValue(pukpin) + if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil { + throwJSException(err.Error()) + } + + case strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()): + // PIN input requested, fetch from the user and call open again + if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil { + throwJSException(err.Error()) + } + + default: + // Unknown error occurred, drop to the user + throwJSException(err.Error()) + } + return val +} + +func (b *bridge) readPassphraseAndReopenWallet(call otto.FunctionCall) (otto.Value, error) { + var passwd otto.Value + wallet := call.Argument(0) + if input, err := b.prompter.PromptPassword("Please enter your passphrase: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + return call.Otto.Call("jeth.openWallet", nil, wallet, passwd) +} + +func (b *bridge) readPinAndReopenWallet(call otto.FunctionCall) (otto.Value, error) { + var passwd otto.Value + wallet := call.Argument(0) + // Trezor PIN matrix input requested, display the matrix to the user and fetch the data + fmt.Fprintf(b.printer, "Look at the device for number positions\n\n") + fmt.Fprintf(b.printer, "7 | 8 | 9\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "4 | 5 | 6\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "1 | 2 | 3\n\n") + + if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + return call.Otto.Call("jeth.openWallet", nil, wallet, passwd) +} + +// UnlockAccount is a wrapper around the personal.unlockAccount RPC method that +// uses a non-echoing password prompt to acquire the passphrase and executes the +// original RPC method (saved in jeth.unlockAccount) with it to actually execute +// the RPC call. +func (b *bridge) UnlockAccount(call otto.FunctionCall) (response otto.Value) { + // Make sure we have an account specified to unlock + if !call.Argument(0).IsString() { + throwJSException("first argument must be the account to unlock") + } + account := call.Argument(0) + + // If password is not given or is the null value, prompt the user for it + var passwd otto.Value + + if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() { + fmt.Fprintf(b.printer, "Unlock account %s\n", account) + if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + } else { + if !call.Argument(1).IsString() { + throwJSException("password must be a string") + } + passwd = call.Argument(1) + } + // Third argument is the duration how long the account must be unlocked. + duration := otto.NullValue() + if call.Argument(2).IsDefined() && !call.Argument(2).IsNull() { + if !call.Argument(2).IsNumber() { + throwJSException("unlock duration must be a number") + } + duration = call.Argument(2) + } + // Send the request to the backend and return + val, err := call.Otto.Call("jeth.unlockAccount", nil, account, passwd, duration) + if err != nil { + throwJSException(err.Error()) + } + return val +} + +// Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password +// prompt to acquire the passphrase and executes the original RPC method (saved in +// jeth.sign) with it to actually execute the RPC call. +func (b *bridge) Sign(call otto.FunctionCall) (response otto.Value) { + var ( + message = call.Argument(0) + account = call.Argument(1) + passwd = call.Argument(2) + ) + + if !message.IsString() { + throwJSException("first argument must be the message to sign") + } + if !account.IsString() { + throwJSException("second argument must be the account to sign with") + } + + // if the password is not given or null ask the user and ensure password is a string + if passwd.IsUndefined() || passwd.IsNull() { + fmt.Fprintf(b.printer, "Give password for account %s\n", account) + if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + } + if !passwd.IsString() { + throwJSException("third argument must be the password to unlock the account") + } + + // Send the request to the backend and return + val, err := call.Otto.Call("jeth.sign", nil, message, account, passwd) + if err != nil { + throwJSException(err.Error()) + } + return val +} + +// Sleep will block the console for the specified number of seconds. +func (b *bridge) Sleep(call otto.FunctionCall) (response otto.Value) { + if call.Argument(0).IsNumber() { + sleep, _ := call.Argument(0).ToInteger() + time.Sleep(time.Duration(sleep) * time.Second) + return otto.TrueValue() + } + return throwJSException("usage: sleep()") +} + +// SleepBlocks will block the console for a specified number of new blocks optionally +// until the given timeout is reached. +func (b *bridge) SleepBlocks(call otto.FunctionCall) (response otto.Value) { + var ( + blocks = int64(0) + sleep = int64(9999999999999999) // indefinitely + ) + // Parse the input parameters for the sleep + nArgs := len(call.ArgumentList) + if nArgs == 0 { + throwJSException("usage: sleepBlocks([, max sleep in seconds])") + } + if nArgs >= 1 { + if call.Argument(0).IsNumber() { + blocks, _ = call.Argument(0).ToInteger() + } else { + throwJSException("expected number as first argument") + } + } + if nArgs >= 2 { + if call.Argument(1).IsNumber() { + sleep, _ = call.Argument(1).ToInteger() + } else { + throwJSException("expected number as second argument") + } + } + // go through the console, this will allow web3 to call the appropriate + // callbacks if a delayed response or notification is received. + blockNumber := func() int64 { + result, err := call.Otto.Run("eth.blockNumber") + if err != nil { + throwJSException(err.Error()) + } + block, err := result.ToInteger() + if err != nil { + throwJSException(err.Error()) + } + return block + } + // Poll the current block number until either it ot a timeout is reached + targetBlockNr := blockNumber() + blocks + deadline := time.Now().Add(time.Duration(sleep) * time.Second) + + for time.Now().Before(deadline) { + if blockNumber() >= targetBlockNr { + return otto.TrueValue() + } + time.Sleep(time.Second) + } + return otto.FalseValue() +} + +type jsonrpcCall struct { + ID int64 + Method string + Params []interface{} +} + +// Send implements the web3 provider "send" method. +func (b *bridge) Send(call otto.FunctionCall) (response otto.Value) { + // Remarshal the request into a Go value. + JSON, _ := call.Otto.Object("JSON") + reqVal, err := JSON.Call("stringify", call.Argument(0)) + if err != nil { + throwJSException(err.Error()) + } + var ( + rawReq = reqVal.String() + dec = json.NewDecoder(strings.NewReader(rawReq)) + reqs []jsonrpcCall + batch bool + ) + dec.UseNumber() // avoid float64s + if rawReq[0] == '[' { + batch = true + dec.Decode(&reqs) + } else { + batch = false + reqs = make([]jsonrpcCall, 1) + dec.Decode(&reqs[0]) + } + + // Execute the requests. + resps, _ := call.Otto.Object("new Array()") + for _, req := range reqs { + resp, _ := call.Otto.Object(`({"jsonrpc":"2.0"})`) + resp.Set("id", req.ID) + var result json.RawMessage + err = b.client.Call(&result, req.Method, req.Params...) + switch err := err.(type) { + case nil: + if result == nil { + // Special case null because it is decoded as an empty + // raw message for some reason. + resp.Set("result", otto.NullValue()) + } else { + resultVal, err := JSON.Call("parse", string(result)) + if err != nil { + setError(resp, -32603, err.Error()) + } else { + resp.Set("result", resultVal) + } + } + case rpc.Error: + setError(resp, err.ErrorCode(), err.Error()) + default: + setError(resp, -32603, err.Error()) + } + resps.Call("push", resp) + } + + // Return the responses either to the callback (if supplied) + // or directly as the return value. + if batch { + response = resps.Value() + } else { + response, _ = resps.Get("0") + } + if fn := call.Argument(1); fn.Class() == "Function" { + fn.Call(otto.NullValue(), otto.NullValue(), response) + return otto.UndefinedValue() + } + return response +} + +func setError(resp *otto.Object, code int, msg string) { + resp.Set("error", map[string]interface{}{"code": code, "message": msg}) +} + +// throwJSException panics on an otto.Value. The Otto VM will recover from the +// Go panic and throw msg as a JavaScript error. +func throwJSException(msg interface{}) otto.Value { + val, err := otto.ToValue(msg) + if err != nil { + log.Error("Failed to serialize JavaScript exception", "exception", msg, "err", err) + } + panic(val) +} diff --git a/vendor/github.com/ethereum/go-ethereum/console/console.go b/vendor/github.com/ethereum/go-ethereum/console/console.go new file mode 100644 index 00000000..5326ed2c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/console/console.go @@ -0,0 +1,450 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package console + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "os/signal" + "path/filepath" + "regexp" + "sort" + "strings" + "syscall" + + "github.com/ethereum/go-ethereum/internal/jsre" + "github.com/ethereum/go-ethereum/internal/web3ext" + "github.com/ethereum/go-ethereum/rpc" + "github.com/mattn/go-colorable" + "github.com/peterh/liner" + "github.com/robertkrimen/otto" +) + +var ( + passwordRegexp = regexp.MustCompile(`personal.[nus]`) + onlyWhitespace = regexp.MustCompile(`^\s*$`) + exit = regexp.MustCompile(`^\s*exit\s*;*\s*$`) +) + +// HistoryFile is the file within the data directory to store input scrollback. +const HistoryFile = "history" + +// DefaultPrompt is the default prompt line prefix to use for user input querying. +const DefaultPrompt = "> " + +// Config is the collection of configurations to fine tune the behavior of the +// JavaScript console. +type Config struct { + DataDir string // Data directory to store the console history at + DocRoot string // Filesystem path from where to load JavaScript files from + Client *rpc.Client // RPC client to execute Ethereum requests through + Prompt string // Input prompt prefix string (defaults to DefaultPrompt) + Prompter UserPrompter // Input prompter to allow interactive user feedback (defaults to TerminalPrompter) + Printer io.Writer // Output writer to serialize any display strings to (defaults to os.Stdout) + Preload []string // Absolute paths to JavaScript files to preload +} + +// Console is a JavaScript interpreted runtime environment. It is a fully fledged +// JavaScript console attached to a running node via an external or in-process RPC +// client. +type Console struct { + client *rpc.Client // RPC client to execute Ethereum requests through + jsre *jsre.JSRE // JavaScript runtime environment running the interpreter + prompt string // Input prompt prefix string + prompter UserPrompter // Input prompter to allow interactive user feedback + histPath string // Absolute path to the console scrollback history + history []string // Scroll history maintained by the console + printer io.Writer // Output writer to serialize any display strings to +} + +// New initializes a JavaScript interpreted runtime environment and sets defaults +// with the config struct. +func New(config Config) (*Console, error) { + // Handle unset config values gracefully + if config.Prompter == nil { + config.Prompter = Stdin + } + if config.Prompt == "" { + config.Prompt = DefaultPrompt + } + if config.Printer == nil { + config.Printer = colorable.NewColorableStdout() + } + // Initialize the console and return + console := &Console{ + client: config.Client, + jsre: jsre.New(config.DocRoot, config.Printer), + prompt: config.Prompt, + prompter: config.Prompter, + printer: config.Printer, + histPath: filepath.Join(config.DataDir, HistoryFile), + } + if err := os.MkdirAll(config.DataDir, 0700); err != nil { + return nil, err + } + if err := console.init(config.Preload); err != nil { + return nil, err + } + return console, nil +} + +// init retrieves the available APIs from the remote RPC provider and initializes +// the console's JavaScript namespaces based on the exposed modules. +func (c *Console) init(preload []string) error { + // Initialize the JavaScript <-> Go RPC bridge + bridge := newBridge(c.client, c.prompter, c.printer) + c.jsre.Set("jeth", struct{}{}) + + jethObj, _ := c.jsre.Get("jeth") + jethObj.Object().Set("send", bridge.Send) + jethObj.Object().Set("sendAsync", bridge.Send) + + consoleObj, _ := c.jsre.Get("console") + consoleObj.Object().Set("log", c.consoleOutput) + consoleObj.Object().Set("error", c.consoleOutput) + + // Load all the internal utility JavaScript libraries + if err := c.jsre.Compile("bignumber.js", jsre.BignumberJs); err != nil { + return fmt.Errorf("bignumber.js: %v", err) + } + if err := c.jsre.Compile("web3.js", jsre.Web3Js); err != nil { + return fmt.Errorf("web3.js: %v", err) + } + if _, err := c.jsre.Run("var Web3 = require('web3');"); err != nil { + return fmt.Errorf("web3 require: %v", err) + } + if _, err := c.jsre.Run("var web3 = new Web3(jeth);"); err != nil { + return fmt.Errorf("web3 provider: %v", err) + } + // Load the supported APIs into the JavaScript runtime environment + apis, err := c.client.SupportedModules() + if err != nil { + return fmt.Errorf("api modules: %v", err) + } + flatten := "var eth = web3.eth; var personal = web3.personal; " + for api := range apis { + if api == "web3" { + continue // manually mapped or ignore + } + if file, ok := web3ext.Modules[api]; ok { + // Load our extension for the module. + if err = c.jsre.Compile(fmt.Sprintf("%s.js", api), file); err != nil { + return fmt.Errorf("%s.js: %v", api, err) + } + flatten += fmt.Sprintf("var %s = web3.%s; ", api, api) + } else if obj, err := c.jsre.Run("web3." + api); err == nil && obj.IsObject() { + // Enable web3.js built-in extension if available. + flatten += fmt.Sprintf("var %s = web3.%s; ", api, api) + } + } + if _, err = c.jsre.Run(flatten); err != nil { + return fmt.Errorf("namespace flattening: %v", err) + } + // Initialize the global name register (disabled for now) + //c.jsre.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`) + + // If the console is in interactive mode, instrument password related methods to query the user + if c.prompter != nil { + // Retrieve the account management object to instrument + personal, err := c.jsre.Get("personal") + if err != nil { + return err + } + // Override the openWallet, unlockAccount, newAccount and sign methods since + // these require user interaction. Assign these method in the Console the + // original web3 callbacks. These will be called by the jeth.* methods after + // they got the password from the user and send the original web3 request to + // the backend. + if obj := personal.Object(); obj != nil { // make sure the personal api is enabled over the interface + if _, err = c.jsre.Run(`jeth.openWallet = personal.openWallet;`); err != nil { + return fmt.Errorf("personal.openWallet: %v", err) + } + if _, err = c.jsre.Run(`jeth.unlockAccount = personal.unlockAccount;`); err != nil { + return fmt.Errorf("personal.unlockAccount: %v", err) + } + if _, err = c.jsre.Run(`jeth.newAccount = personal.newAccount;`); err != nil { + return fmt.Errorf("personal.newAccount: %v", err) + } + if _, err = c.jsre.Run(`jeth.sign = personal.sign;`); err != nil { + return fmt.Errorf("personal.sign: %v", err) + } + obj.Set("openWallet", bridge.OpenWallet) + obj.Set("unlockAccount", bridge.UnlockAccount) + obj.Set("newAccount", bridge.NewAccount) + obj.Set("sign", bridge.Sign) + } + } + // The admin.sleep and admin.sleepBlocks are offered by the console and not by the RPC layer. + admin, err := c.jsre.Get("admin") + if err != nil { + return err + } + if obj := admin.Object(); obj != nil { // make sure the admin api is enabled over the interface + obj.Set("sleepBlocks", bridge.SleepBlocks) + obj.Set("sleep", bridge.Sleep) + obj.Set("clearHistory", c.clearHistory) + } + // Preload any JavaScript files before starting the console + for _, path := range preload { + if err := c.jsre.Exec(path); err != nil { + failure := err.Error() + if ottoErr, ok := err.(*otto.Error); ok { + failure = ottoErr.String() + } + return fmt.Errorf("%s: %v", path, failure) + } + } + // Configure the console's input prompter for scrollback and tab completion + if c.prompter != nil { + if content, err := ioutil.ReadFile(c.histPath); err != nil { + c.prompter.SetHistory(nil) + } else { + c.history = strings.Split(string(content), "\n") + c.prompter.SetHistory(c.history) + } + c.prompter.SetWordCompleter(c.AutoCompleteInput) + } + return nil +} + +func (c *Console) clearHistory() { + c.history = nil + c.prompter.ClearHistory() + if err := os.Remove(c.histPath); err != nil { + fmt.Fprintln(c.printer, "can't delete history file:", err) + } else { + fmt.Fprintln(c.printer, "history file deleted") + } +} + +// consoleOutput is an override for the console.log and console.error methods to +// stream the output into the configured output stream instead of stdout. +func (c *Console) consoleOutput(call otto.FunctionCall) otto.Value { + var output []string + for _, argument := range call.ArgumentList { + output = append(output, fmt.Sprintf("%v", argument)) + } + fmt.Fprintln(c.printer, strings.Join(output, " ")) + return otto.Value{} +} + +// AutoCompleteInput is a pre-assembled word completer to be used by the user +// input prompter to provide hints to the user about the methods available. +func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, string) { + // No completions can be provided for empty inputs + if len(line) == 0 || pos == 0 { + return "", nil, "" + } + // Chunck data to relevant part for autocompletion + // E.g. in case of nested lines eth.getBalance(eth.coinb + start := pos - 1 + for ; start > 0; start-- { + // Skip all methods and namespaces (i.e. including the dot) + if line[start] == '.' || (line[start] >= 'a' && line[start] <= 'z') || (line[start] >= 'A' && line[start] <= 'Z') { + continue + } + // Handle web3 in a special way (i.e. other numbers aren't auto completed) + if start >= 3 && line[start-3:start] == "web3" { + start -= 3 + continue + } + // We've hit an unexpected character, autocomplete form here + start++ + break + } + return line[:start], c.jsre.CompleteKeywords(line[start:pos]), line[pos:] +} + +// Welcome show summary of current Geth instance and some metadata about the +// console's available modules. +func (c *Console) Welcome() { + message := "Welcome to the Geth JavaScript console!\n\n" + + // Print some generic Geth metadata + if res, err := c.jsre.Run(` + var message = "instance: " + web3.version.node + "\n"; + try { + message += "coinbase: " + eth.coinbase + "\n"; + } catch (err) {} + message += "at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")\n"; + try { + message += " datadir: " + admin.datadir + "\n"; + } catch (err) {} + message + `); err == nil { + message += res.String() + } + // List all the supported modules for the user to call + if apis, err := c.client.SupportedModules(); err == nil { + modules := make([]string, 0, len(apis)) + for api, version := range apis { + modules = append(modules, fmt.Sprintf("%s:%s", api, version)) + } + sort.Strings(modules) + message += " modules: " + strings.Join(modules, " ") + "\n" + } + fmt.Fprintln(c.printer, message) +} + +// Evaluate executes code and pretty prints the result to the specified output +// stream. +func (c *Console) Evaluate(statement string) error { + defer func() { + if r := recover(); r != nil { + fmt.Fprintf(c.printer, "[native] error: %v\n", r) + } + }() + return c.jsre.Evaluate(statement, c.printer) +} + +// Interactive starts an interactive user session, where input is propted from +// the configured user prompter. +func (c *Console) Interactive() { + var ( + prompt = c.prompt // Current prompt line (used for multi-line inputs) + indents = 0 // Current number of input indents (used for multi-line inputs) + input = "" // Current user input + scheduler = make(chan string) // Channel to send the next prompt on and receive the input + ) + // Start a goroutine to listen for prompt requests and send back inputs + go func() { + for { + // Read the next user input + line, err := c.prompter.PromptInput(<-scheduler) + if err != nil { + // In case of an error, either clear the prompt or fail + if err == liner.ErrPromptAborted { // ctrl-C + prompt, indents, input = c.prompt, 0, "" + scheduler <- "" + continue + } + close(scheduler) + return + } + // User input retrieved, send for interpretation and loop + scheduler <- line + } + }() + // Monitor Ctrl-C too in case the input is empty and we need to bail + abort := make(chan os.Signal, 1) + signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM) + + // Start sending prompts to the user and reading back inputs + for { + // Send the next prompt, triggering an input read and process the result + scheduler <- prompt + select { + case <-abort: + // User forcefully quite the console + fmt.Fprintln(c.printer, "caught interrupt, exiting") + return + + case line, ok := <-scheduler: + // User input was returned by the prompter, handle special cases + if !ok || (indents <= 0 && exit.MatchString(line)) { + return + } + if onlyWhitespace.MatchString(line) { + continue + } + // Append the line to the input and check for multi-line interpretation + input += line + "\n" + + indents = countIndents(input) + if indents <= 0 { + prompt = c.prompt + } else { + prompt = strings.Repeat(".", indents*3) + " " + } + // If all the needed lines are present, save the command and run + if indents <= 0 { + if len(input) > 0 && input[0] != ' ' && !passwordRegexp.MatchString(input) { + if command := strings.TrimSpace(input); len(c.history) == 0 || command != c.history[len(c.history)-1] { + c.history = append(c.history, command) + if c.prompter != nil { + c.prompter.AppendHistory(command) + } + } + } + c.Evaluate(input) + input = "" + } + } + } +} + +// countIndents returns the number of identations for the given input. +// In case of invalid input such as var a = } the result can be negative. +func countIndents(input string) int { + var ( + indents = 0 + inString = false + strOpenChar = ' ' // keep track of the string open char to allow var str = "I'm ...."; + charEscaped = false // keep track if the previous char was the '\' char, allow var str = "abc\"def"; + ) + + for _, c := range input { + switch c { + case '\\': + // indicate next char as escaped when in string and previous char isn't escaping this backslash + if !charEscaped && inString { + charEscaped = true + } + case '\'', '"': + if inString && !charEscaped && strOpenChar == c { // end string + inString = false + } else if !inString && !charEscaped { // begin string + inString = true + strOpenChar = c + } + charEscaped = false + case '{', '(': + if !inString { // ignore brackets when in string, allow var str = "a{"; without indenting + indents++ + } + charEscaped = false + case '}', ')': + if !inString { + indents-- + } + charEscaped = false + default: + charEscaped = false + } + } + + return indents +} + +// Execute runs the JavaScript file specified as the argument. +func (c *Console) Execute(path string) error { + return c.jsre.Exec(path) +} + +// Stop cleans up the console and terminates the runtime environment. +func (c *Console) Stop(graceful bool) error { + if err := ioutil.WriteFile(c.histPath, []byte(strings.Join(c.history, "\n")), 0600); err != nil { + return err + } + if err := os.Chmod(c.histPath, 0600); err != nil { // Force 0600, even if it was different previously + return err + } + c.jsre.Stop(graceful) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/console/prompter.go b/vendor/github.com/ethereum/go-ethereum/console/prompter.go new file mode 100644 index 00000000..65675061 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/console/prompter.go @@ -0,0 +1,172 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package console + +import ( + "fmt" + "strings" + + "github.com/peterh/liner" +) + +// Stdin holds the stdin line reader (also using stdout for printing prompts). +// Only this reader may be used for input because it keeps an internal buffer. +var Stdin = newTerminalPrompter() + +// UserPrompter defines the methods needed by the console to prompt the user for +// various types of inputs. +type UserPrompter interface { + // PromptInput displays the given prompt to the user and requests some textual + // data to be entered, returning the input of the user. + PromptInput(prompt string) (string, error) + + // PromptPassword displays the given prompt to the user and requests some textual + // data to be entered, but one which must not be echoed out into the terminal. + // The method returns the input provided by the user. + PromptPassword(prompt string) (string, error) + + // PromptConfirm displays the given prompt to the user and requests a boolean + // choice to be made, returning that choice. + PromptConfirm(prompt string) (bool, error) + + // SetHistory sets the input scrollback history that the prompter will allow + // the user to scroll back to. + SetHistory(history []string) + + // AppendHistory appends an entry to the scrollback history. It should be called + // if and only if the prompt to append was a valid command. + AppendHistory(command string) + + // ClearHistory clears the entire history + ClearHistory() + + // SetWordCompleter sets the completion function that the prompter will call to + // fetch completion candidates when the user presses tab. + SetWordCompleter(completer WordCompleter) +} + +// WordCompleter takes the currently edited line with the cursor position and +// returns the completion candidates for the partial word to be completed. If +// the line is "Hello, wo!!!" and the cursor is before the first '!', ("Hello, +// wo!!!", 9) is passed to the completer which may returns ("Hello, ", {"world", +// "Word"}, "!!!") to have "Hello, world!!!". +type WordCompleter func(line string, pos int) (string, []string, string) + +// terminalPrompter is a UserPrompter backed by the liner package. It supports +// prompting the user for various input, among others for non-echoing password +// input. +type terminalPrompter struct { + *liner.State + warned bool + supported bool + normalMode liner.ModeApplier + rawMode liner.ModeApplier +} + +// newTerminalPrompter creates a liner based user input prompter working off the +// standard input and output streams. +func newTerminalPrompter() *terminalPrompter { + p := new(terminalPrompter) + // Get the original mode before calling NewLiner. + // This is usually regular "cooked" mode where characters echo. + normalMode, _ := liner.TerminalMode() + // Turn on liner. It switches to raw mode. + p.State = liner.NewLiner() + rawMode, err := liner.TerminalMode() + if err != nil || !liner.TerminalSupported() { + p.supported = false + } else { + p.supported = true + p.normalMode = normalMode + p.rawMode = rawMode + // Switch back to normal mode while we're not prompting. + normalMode.ApplyMode() + } + p.SetCtrlCAborts(true) + p.SetTabCompletionStyle(liner.TabPrints) + p.SetMultiLineMode(true) + return p +} + +// PromptInput displays the given prompt to the user and requests some textual +// data to be entered, returning the input of the user. +func (p *terminalPrompter) PromptInput(prompt string) (string, error) { + if p.supported { + p.rawMode.ApplyMode() + defer p.normalMode.ApplyMode() + } else { + // liner tries to be smart about printing the prompt + // and doesn't print anything if input is redirected. + // Un-smart it by printing the prompt always. + fmt.Print(prompt) + prompt = "" + defer fmt.Println() + } + return p.State.Prompt(prompt) +} + +// PromptPassword displays the given prompt to the user and requests some textual +// data to be entered, but one which must not be echoed out into the terminal. +// The method returns the input provided by the user. +func (p *terminalPrompter) PromptPassword(prompt string) (passwd string, err error) { + if p.supported { + p.rawMode.ApplyMode() + defer p.normalMode.ApplyMode() + return p.State.PasswordPrompt(prompt) + } + if !p.warned { + fmt.Println("!! Unsupported terminal, password will be echoed.") + p.warned = true + } + // Just as in Prompt, handle printing the prompt here instead of relying on liner. + fmt.Print(prompt) + passwd, err = p.State.Prompt("") + fmt.Println() + return passwd, err +} + +// PromptConfirm displays the given prompt to the user and requests a boolean +// choice to be made, returning that choice. +func (p *terminalPrompter) PromptConfirm(prompt string) (bool, error) { + input, err := p.Prompt(prompt + " [y/n] ") + if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" { + return true, nil + } + return false, err +} + +// SetHistory sets the input scrollback history that the prompter will allow +// the user to scroll back to. +func (p *terminalPrompter) SetHistory(history []string) { + p.State.ReadHistory(strings.NewReader(strings.Join(history, "\n"))) +} + +// AppendHistory appends an entry to the scrollback history. +func (p *terminalPrompter) AppendHistory(command string) { + p.State.AppendHistory(command) +} + +// ClearHistory clears the entire history +func (p *terminalPrompter) ClearHistory() { + p.State.ClearHistory() +} + +// SetWordCompleter sets the completion function that the prompter will call to +// fetch completion candidates when the user presses tab. +func (p *terminalPrompter) SetWordCompleter(completer WordCompleter) { + p.State.SetWordCompleter(liner.WordCompleter(completer)) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/blockchain.go b/vendor/github.com/ethereum/go-ethereum/core/blockchain.go new file mode 100644 index 00000000..15e771f4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/blockchain.go @@ -0,0 +1,2168 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package core implements the Ethereum consensus protocol. +package core + +import ( + "errors" + "fmt" + "io" + "math/big" + mrand "math/rand" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/hashicorp/golang-lru" +) + +var ( + headBlockGauge = metrics.NewRegisteredGauge("chain/head/block", nil) + headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil) + headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil) + + accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) + accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) + accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil) + accountCommitTimer = metrics.NewRegisteredTimer("chain/account/commits", nil) + + storageReadTimer = metrics.NewRegisteredTimer("chain/storage/reads", nil) + storageHashTimer = metrics.NewRegisteredTimer("chain/storage/hashes", nil) + storageUpdateTimer = metrics.NewRegisteredTimer("chain/storage/updates", nil) + storageCommitTimer = metrics.NewRegisteredTimer("chain/storage/commits", nil) + + blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) + blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) + blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) + blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) + + blockPrefetchExecuteTimer = metrics.NewRegisteredTimer("chain/prefetch/executes", nil) + blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil) + + errInsertionInterrupted = errors.New("insertion is interrupted") +) + +const ( + bodyCacheLimit = 256 + blockCacheLimit = 256 + receiptsCacheLimit = 32 + maxFutureBlocks = 256 + maxTimeFutureBlocks = 30 + badBlockLimit = 10 + TriesInMemory = 128 + + // BlockChainVersion ensures that an incompatible database forces a resync from scratch. + // + // Changelog: + // + // - Version 4 + // The following incompatible database changes were added: + // * the `BlockNumber`, `TxHash`, `TxIndex`, `BlockHash` and `Index` fields of log are deleted + // * the `Bloom` field of receipt is deleted + // * the `BlockIndex` and `TxIndex` fields of txlookup are deleted + // - Version 5 + // The following incompatible database changes were added: + // * the `TxHash`, `GasCost`, and `ContractAddress` fields are no longer stored for a receipt + // * the `TxHash`, `GasCost`, and `ContractAddress` fields are computed by looking up the + // receipts' corresponding block + // - Version 6 + // The following incompatible database changes were added: + // * Transaction lookup information stores the corresponding block number instead of block hash + // - Version 7 + // The following incompatible database changes were added: + // * Use freezer as the ancient database to maintain all ancient data + BlockChainVersion uint64 = 7 +) + +// CacheConfig contains the configuration values for the trie caching/pruning +// that's resident in a blockchain. +type CacheConfig struct { + TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory + TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks + TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk + TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node) + TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk + ProcessingStateDiffs bool // Whether statediffs processing should be taken into a account before a trie is pruned +} + +// BlockChain represents the canonical chain given a database with a genesis +// block. The Blockchain manages chain imports, reverts, chain reorganisations. +// +// Importing blocks in to the block chain happens according to the set of rules +// defined by the two stage Validator. Processing of blocks is done using the +// Processor which processes the included transaction. The validation of the state +// is done in the second part of the Validator. Failing results in aborting of +// the import. +// +// The BlockChain also helps in returning blocks from **any** chain included +// in the database as well as blocks that represents the canonical chain. It's +// important to note that GetBlock can return any block and does not need to be +// included in the canonical one where as GetBlockByNumber always represents the +// canonical chain. +type BlockChain struct { + chainConfig *params.ChainConfig // Chain & network configuration + cacheConfig *CacheConfig // Cache configuration for pruning + + db ethdb.Database // Low level persistent database to store final content in + triegc *prque.Prque // Priority queue mapping block numbers to tries to gc + gcproc time.Duration // Accumulates canonical block processing for trie dumping + + hc *HeaderChain + rmLogsFeed event.Feed + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + logsFeed event.Feed + blockProcFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block + + chainmu sync.RWMutex // blockchain insertion lock + + currentBlock atomic.Value // Current head of the block chain + currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) + + stateCache state.Database // State database to reuse between imports (contains state cache) + bodyCache *lru.Cache // Cache for the most recent block bodies + bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format + receiptsCache *lru.Cache // Cache for the most recent receipts per block + blockCache *lru.Cache // Cache for the most recent entire blocks + futureBlocks *lru.Cache // future blocks are blocks added for later processing + + quit chan struct{} // blockchain quit channel + running int32 // running must be called atomically + // procInterrupt must be atomically called + procInterrupt int32 // interrupt signaler for block processing + wg sync.WaitGroup // chain processing wait group for shutting down + + engine consensus.Engine + validator Validator // Block and state validator interface + prefetcher Prefetcher // Block state prefetcher interface + processor Processor // Block transaction processor interface + vmConfig vm.Config + + badBlocks *lru.Cache // Bad block cache + shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block. + terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion. + + stateDiffsProcessed map[common.Hash]int +} + +// NewBlockChain returns a fully initialised block chain using information +// available in the database. It initialises the default Ethereum Validator and +// Processor. +func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool) (*BlockChain, error) { + if cacheConfig == nil { + cacheConfig = &CacheConfig{ + TrieCleanLimit: 256, + TrieDirtyLimit: 256, + TrieTimeLimit: 5 * time.Minute, + } + } + bodyCache, _ := lru.New(bodyCacheLimit) + bodyRLPCache, _ := lru.New(bodyCacheLimit) + receiptsCache, _ := lru.New(receiptsCacheLimit) + blockCache, _ := lru.New(blockCacheLimit) + futureBlocks, _ := lru.New(maxFutureBlocks) + badBlocks, _ := lru.New(badBlockLimit) + stateDiffsProcessed := make(map[common.Hash]int) + bc := &BlockChain{ + chainConfig: chainConfig, + cacheConfig: cacheConfig, + db: db, + triegc: prque.New(nil), + stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit), + quit: make(chan struct{}), + shouldPreserve: shouldPreserve, + bodyCache: bodyCache, + bodyRLPCache: bodyRLPCache, + receiptsCache: receiptsCache, + blockCache: blockCache, + futureBlocks: futureBlocks, + engine: engine, + vmConfig: vmConfig, + badBlocks: badBlocks, + stateDiffsProcessed: stateDiffsProcessed, + } + bc.validator = NewBlockValidator(chainConfig, bc, engine) + bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine) + bc.processor = NewStateProcessor(chainConfig, bc, engine) + + var err error + bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt) + if err != nil { + return nil, err + } + bc.genesisBlock = bc.GetBlockByNumber(0) + if bc.genesisBlock == nil { + return nil, ErrNoGenesis + } + // Initialize the chain with ancient data if it isn't empty. + if bc.empty() { + rawdb.InitDatabaseFromFreezer(bc.db) + } + if err := bc.loadLastState(); err != nil { + return nil, err + } + // The first thing the node will do is reconstruct the verification data for + // the head block (ethash cache or clique voting snapshot). Might as well do + // it in advance. + bc.engine.VerifyHeader(bc, bc.CurrentHeader(), true) + + if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 { + var ( + needRewind bool + low uint64 + ) + // The head full block may be rolled back to a very low height due to + // blockchain repair. If the head full block is even lower than the ancient + // chain, truncate the ancient store. + fullBlock := bc.CurrentBlock() + if fullBlock != nil && fullBlock != bc.genesisBlock && fullBlock.NumberU64() < frozen-1 { + needRewind = true + low = fullBlock.NumberU64() + } + // In fast sync, it may happen that ancient data has been written to the + // ancient store, but the LastFastBlock has not been updated, truncate the + // extra data here. + fastBlock := bc.CurrentFastBlock() + if fastBlock != nil && fastBlock.NumberU64() < frozen-1 { + needRewind = true + if fastBlock.NumberU64() < low || low == 0 { + low = fastBlock.NumberU64() + } + } + if needRewind { + var hashes []common.Hash + previous := bc.CurrentHeader().Number.Uint64() + for i := low + 1; i <= bc.CurrentHeader().Number.Uint64(); i++ { + hashes = append(hashes, rawdb.ReadCanonicalHash(bc.db, i)) + } + bc.Rollback(hashes) + log.Warn("Truncate ancient chain", "from", previous, "to", low) + } + } + // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain + for hash := range BadHashes { + if header := bc.GetHeaderByHash(hash); header != nil { + // get the canonical block corresponding to the offending header's number + headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) + // make sure the headerByNumber (if present) is in our current canonical chain + if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { + log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) + bc.SetHead(header.Number.Uint64() - 1) + log.Error("Chain rewind was successful, resuming normal operation") + } + } + } + // Take ownership of this particular state + go bc.update() + return bc, nil +} + +func (bc *BlockChain) getProcInterrupt() bool { + return atomic.LoadInt32(&bc.procInterrupt) == 1 +} + +// GetVMConfig returns the block chain VM config. +func (bc *BlockChain) GetVMConfig() *vm.Config { + return &bc.vmConfig +} + +// empty returns an indicator whether the blockchain is empty. +// Note, it's a special case that we connect a non-empty ancient +// database with an empty node, so that we can plugin the ancient +// into node seamlessly. +func (bc *BlockChain) empty() bool { + genesis := bc.genesisBlock.Hash() + for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(bc.db), rawdb.ReadHeadHeaderHash(bc.db), rawdb.ReadHeadFastBlockHash(bc.db)} { + if hash != genesis { + return false + } + } + return true +} + +// loadLastState loads the last known chain state from the database. This method +// assumes that the chain manager mutex is held. +func (bc *BlockChain) loadLastState() error { + // Restore the last known head block + head := rawdb.ReadHeadBlockHash(bc.db) + if head == (common.Hash{}) { + // Corrupt or empty database, init from scratch + log.Warn("Empty database, resetting chain") + return bc.Reset() + } + // Make sure the entire head block is available + currentBlock := bc.GetBlockByHash(head) + if currentBlock == nil { + // Corrupt or empty database, init from scratch + log.Warn("Head block missing, resetting chain", "hash", head) + return bc.Reset() + } + // Make sure the state associated with the block is available + if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { + // Dangling block without a state associated, init from scratch + log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) + if err := bc.repair(¤tBlock); err != nil { + return err + } + rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash()) + } + // Everything seems to be fine, set as the head block + bc.currentBlock.Store(currentBlock) + headBlockGauge.Update(int64(currentBlock.NumberU64())) + + // Restore the last known head header + currentHeader := currentBlock.Header() + if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) { + if header := bc.GetHeaderByHash(head); header != nil { + currentHeader = header + } + } + bc.hc.SetCurrentHeader(currentHeader) + + // Restore the last known head fast block + bc.currentFastBlock.Store(currentBlock) + headFastBlockGauge.Update(int64(currentBlock.NumberU64())) + + if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) { + if block := bc.GetBlockByHash(head); block != nil { + bc.currentFastBlock.Store(block) + headFastBlockGauge.Update(int64(block.NumberU64())) + } + } + // Issue a status log for the user + currentFastBlock := bc.CurrentFastBlock() + + headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) + blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) + fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()) + + log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time), 0))) + log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentBlock.Time()), 0))) + log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentFastBlock.Time()), 0))) + + return nil +} + +// SetHead rewinds the local chain to a new head. In the case of headers, everything +// above the new head will be deleted and the new one set. In the case of blocks +// though, the head may be further rewound if block bodies are missing (non-archive +// nodes after a fast sync). +func (bc *BlockChain) SetHead(head uint64) error { + log.Warn("Rewinding blockchain", "target", head) + + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + updateFn := func(db ethdb.KeyValueWriter, header *types.Header) { + // Rewind the block chain, ensuring we don't end up with a stateless head block + if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() < currentBlock.NumberU64() { + newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) + if newHeadBlock == nil { + newHeadBlock = bc.genesisBlock + } else { + if _, err := state.New(newHeadBlock.Root(), bc.stateCache); err != nil { + // Rewound state missing, rolled back to before pivot, reset to genesis + newHeadBlock = bc.genesisBlock + } + } + rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash()) + bc.currentBlock.Store(newHeadBlock) + headBlockGauge.Update(int64(newHeadBlock.NumberU64())) + } + + // Rewind the fast block in a simpleton way to the target head + if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { + newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) + // If either blocks reached nil, reset to the genesis state + if newHeadFastBlock == nil { + newHeadFastBlock = bc.genesisBlock + } + rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash()) + bc.currentFastBlock.Store(newHeadFastBlock) + headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64())) + } + } + + // Rewind the header chain, deleting all block bodies until then + delFn := func(db ethdb.KeyValueWriter, hash common.Hash, num uint64) { + // Ignore the error here since light client won't hit this path + frozen, _ := bc.db.Ancients() + if num+1 <= frozen { + // Truncate all relative data(header, total difficulty, body, receipt + // and canonical hash) from ancient store. + if err := bc.db.TruncateAncients(num + 1); err != nil { + log.Crit("Failed to truncate ancient data", "number", num, "err", err) + } + + // Remove the hash <-> number mapping from the active store. + rawdb.DeleteHeaderNumber(db, hash) + } else { + // Remove relative body and receipts from the active store. + // The header, total difficulty and canonical hash will be + // removed in the hc.SetHead function. + rawdb.DeleteBody(db, hash, num) + rawdb.DeleteReceipts(db, hash, num) + } + // Todo(rjl493456442) txlookup, bloombits, etc + } + bc.hc.SetHead(head, updateFn, delFn) + + // Clear out any stale content from the caches + bc.bodyCache.Purge() + bc.bodyRLPCache.Purge() + bc.receiptsCache.Purge() + bc.blockCache.Purge() + bc.futureBlocks.Purge() + + return bc.loadLastState() +} + +// FastSyncCommitHead sets the current head block to the one defined by the hash +// irrelevant what the chain contents were prior. +func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { + // Make sure that both the block as well at its state trie exists + block := bc.GetBlockByHash(hash) + if block == nil { + return fmt.Errorf("non existent block [%x…]", hash[:4]) + } + if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil { + return err + } + // If all checks out, manually set the head block + bc.chainmu.Lock() + bc.currentBlock.Store(block) + headBlockGauge.Update(int64(block.NumberU64())) + bc.chainmu.Unlock() + + log.Info("Committed new head block", "number", block.Number(), "hash", hash) + return nil +} + +// GasLimit returns the gas limit of the current HEAD block. +func (bc *BlockChain) GasLimit() uint64 { + return bc.CurrentBlock().GasLimit() +} + +// CurrentBlock retrieves the current head block of the canonical chain. The +// block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentBlock() *types.Block { + return bc.currentBlock.Load().(*types.Block) +} + +// CurrentFastBlock retrieves the current fast-sync head block of the canonical +// chain. The block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentFastBlock() *types.Block { + return bc.currentFastBlock.Load().(*types.Block) +} + +// Validator returns the current validator. +func (bc *BlockChain) Validator() Validator { + return bc.validator +} + +// Processor returns the current processor. +func (bc *BlockChain) Processor() Processor { + return bc.processor +} + +// State returns a new mutable state based on the current HEAD block. +func (bc *BlockChain) State() (*state.StateDB, error) { + return bc.StateAt(bc.CurrentBlock().Root()) +} + +// StateAt returns a new mutable state based on a particular point in time. +func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { + return state.New(root, bc.stateCache) +} + +// StateCache returns the caching database underpinning the blockchain instance. +func (bc *BlockChain) StateCache() state.Database { + return bc.stateCache +} + +// Reset purges the entire blockchain, restoring it to its genesis state. +func (bc *BlockChain) Reset() error { + return bc.ResetWithGenesisBlock(bc.genesisBlock) +} + +// ResetWithGenesisBlock purges the entire blockchain, restoring it to the +// specified genesis state. +func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { + // Dump the entire block chain and purge the caches + if err := bc.SetHead(0); err != nil { + return err + } + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + // Prepare the genesis block and reinitialise the chain + if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { + log.Crit("Failed to write genesis block TD", "err", err) + } + rawdb.WriteBlock(bc.db, genesis) + + bc.genesisBlock = genesis + bc.insert(bc.genesisBlock) + bc.currentBlock.Store(bc.genesisBlock) + headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + + bc.hc.SetGenesis(bc.genesisBlock.Header()) + bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) + bc.currentFastBlock.Store(bc.genesisBlock) + headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + + return nil +} + +// repair tries to repair the current blockchain by rolling back the current block +// until one with associated state is found. This is needed to fix incomplete db +// writes caused either by crashes/power outages, or simply non-committed tries. +// +// This method only rolls back the current block. The current header and current +// fast block are left intact. +func (bc *BlockChain) repair(head **types.Block) error { + for { + // Abort if we've rewound to a head block that does have associated state + if _, err := state.New((*head).Root(), bc.stateCache); err == nil { + log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash()) + return nil + } + // Otherwise rewind one block and recheck state availability there + block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1) + if block == nil { + return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash()) + } + *head = block + } +} + +// Export writes the active chain to the given writer. +func (bc *BlockChain) Export(w io.Writer) error { + return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64()) +} + +// ExportN writes a subset of the active chain to the given writer. +func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { + bc.chainmu.RLock() + defer bc.chainmu.RUnlock() + + if first > last { + return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) + } + log.Info("Exporting batch of blocks", "count", last-first+1) + + start, reported := time.Now(), time.Now() + for nr := first; nr <= last; nr++ { + block := bc.GetBlockByNumber(nr) + if block == nil { + return fmt.Errorf("export failed on #%d: not found", nr) + } + if err := block.EncodeRLP(w); err != nil { + return err + } + if time.Since(reported) >= statsReportLimit { + log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) + reported = time.Now() + } + } + return nil +} + +// insert injects a new head block into the current block chain. This method +// assumes that the block is indeed a true head. It will also reset the head +// header and the head fast sync block to this very same block if they are older +// or if they are on a different side chain. +// +// Note, this function assumes that the `mu` mutex is held! +func (bc *BlockChain) insert(block *types.Block) { + // If the block is on a side chain or an unknown one, force other heads onto it too + updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() + + // Add the block to the canonical chain number scheme and mark as the head + rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(bc.db, block.Hash()) + + bc.currentBlock.Store(block) + headBlockGauge.Update(int64(block.NumberU64())) + + // If the block is better than our head or is on a different chain, force update heads + if updateHeads { + bc.hc.SetCurrentHeader(block.Header()) + rawdb.WriteHeadFastBlockHash(bc.db, block.Hash()) + + bc.currentFastBlock.Store(block) + headFastBlockGauge.Update(int64(block.NumberU64())) + } +} + +// Genesis retrieves the chain's genesis block. +func (bc *BlockChain) Genesis() *types.Block { + return bc.genesisBlock +} + +// GetBody retrieves a block body (transactions and uncles) from the database by +// hash, caching it if found. +func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { + // Short circuit if the body's already in the cache, retrieve otherwise + if cached, ok := bc.bodyCache.Get(hash); ok { + body := cached.(*types.Body) + return body + } + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + body := rawdb.ReadBody(bc.db, hash, *number) + if body == nil { + return nil + } + // Cache the found body for next time and return + bc.bodyCache.Add(hash, body) + return body +} + +// GetBodyRLP retrieves a block body in RLP encoding from the database by hash, +// caching it if found. +func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { + // Short circuit if the body's already in the cache, retrieve otherwise + if cached, ok := bc.bodyRLPCache.Get(hash); ok { + return cached.(rlp.RawValue) + } + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + body := rawdb.ReadBodyRLP(bc.db, hash, *number) + if len(body) == 0 { + return nil + } + // Cache the found body for next time and return + bc.bodyRLPCache.Add(hash, body) + return body +} + +// HasBlock checks if a block is fully present in the database or not. +func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { + if bc.blockCache.Contains(hash) { + return true + } + return rawdb.HasBody(bc.db, hash, number) +} + +// HasFastBlock checks if a fast block is fully present in the database or not. +func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool { + if !bc.HasBlock(hash, number) { + return false + } + if bc.receiptsCache.Contains(hash) { + return true + } + return rawdb.HasReceipts(bc.db, hash, number) +} + +// HasState checks if state trie is fully present in the database or not. +func (bc *BlockChain) HasState(hash common.Hash) bool { + _, err := bc.stateCache.OpenTrie(hash) + return err == nil +} + +// HasBlockAndState checks if a block and associated state trie is fully present +// in the database or not, caching it if present. +func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool { + // Check first that the block itself is known + block := bc.GetBlock(hash, number) + if block == nil { + return false + } + return bc.HasState(block.Root()) +} + +// GetBlock retrieves a block from the database by hash and number, +// caching it if found. +func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { + // Short circuit if the block's already in the cache, retrieve otherwise + if block, ok := bc.blockCache.Get(hash); ok { + return block.(*types.Block) + } + block := rawdb.ReadBlock(bc.db, hash, number) + if block == nil { + return nil + } + // Cache the found block for next time and return + bc.blockCache.Add(block.Hash(), block) + return block +} + +// GetBlockByHash retrieves a block from the database by hash, caching it if found. +func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return bc.GetBlock(hash, *number) +} + +// GetBlockByNumber retrieves a block from the database by number, caching it +// (associated with its hash) if found. +func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { + hash := rawdb.ReadCanonicalHash(bc.db, number) + if hash == (common.Hash{}) { + return nil + } + return bc.GetBlock(hash, number) +} + +// GetReceiptsByHash retrieves the receipts for all transactions in a given block. +func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { + if receipts, ok := bc.receiptsCache.Get(hash); ok { + return receipts.(types.Receipts) + } + number := rawdb.ReadHeaderNumber(bc.db, hash) + if number == nil { + return nil + } + receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) + if receipts == nil { + return nil + } + bc.receiptsCache.Add(hash, receipts) + return receipts +} + +// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. +// [deprecated by eth/62] +func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + for i := 0; i < n; i++ { + block := bc.GetBlock(hash, *number) + if block == nil { + break + } + blocks = append(blocks, block) + hash = block.ParentHash() + *number-- + } + return +} + +// GetUnclesInChain retrieves all the uncles from a given block backwards until +// a specific distance is reached. +func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { + uncles := []*types.Header{} + for i := 0; block != nil && i < length; i++ { + uncles = append(uncles, block.Uncles()...) + block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) + } + return uncles +} + +// TrieNode retrieves a blob of data associated with a trie node (or code hash) +// either from ephemeral in-memory cache, or from persistent storage. +func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { + return bc.stateCache.TrieDB().Node(hash) +} + +// Stop stops the blockchain service. If any imports are currently in progress +// it will abort them using the procInterrupt. +func (bc *BlockChain) Stop() { + if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { + return + } + // Unsubscribe all subscriptions registered from blockchain + bc.scope.Close() + close(bc.quit) + atomic.StoreInt32(&bc.procInterrupt, 1) + + bc.wg.Wait() + + // Ensure the state of a recent block is also stored to disk before exiting. + // We're writing three different states to catch different restart scenarios: + // - HEAD: So we don't need to reprocess any blocks in the general case + // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle + // - HEAD-127: So we have a hard limit on the number of blocks reexecuted + if !bc.cacheConfig.TrieDirtyDisabled { + triedb := bc.stateCache.TrieDB() + + for _, offset := range []uint64{0, 1, TriesInMemory - 1} { + if number := bc.CurrentBlock().NumberU64(); number > offset { + recent := bc.GetBlockByNumber(number - offset) + + log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) + if err := triedb.Commit(recent.Root(), true); err != nil { + log.Error("Failed to commit recent state trie", "err", err) + } + } + } + for !bc.triegc.Empty() { + triedb.Dereference(bc.triegc.PopItem().(common.Hash)) + } + if size, _ := triedb.Size(); size != 0 { + log.Error("Dangling trie nodes after full cleanup") + } + } + log.Info("Blockchain manager stopped") +} + +func (bc *BlockChain) procFutureBlocks() { + blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) + for _, hash := range bc.futureBlocks.Keys() { + if block, exist := bc.futureBlocks.Peek(hash); exist { + blocks = append(blocks, block.(*types.Block)) + } + } + if len(blocks) > 0 { + types.BlockBy(types.Number).Sort(blocks) + + // Insert one by one as chain insertion needs contiguous ancestry between blocks + for i := range blocks { + bc.InsertChain(blocks[i : i+1]) + } + } +} + +// WriteStatus status of write +type WriteStatus byte + +const ( + NonStatTy WriteStatus = iota + CanonStatTy + SideStatTy +) + +// Rollback is designed to remove a chain of links from the database that aren't +// certain enough to be valid. +func (bc *BlockChain) Rollback(chain []common.Hash) { + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + for i := len(chain) - 1; i >= 0; i-- { + hash := chain[i] + + currentHeader := bc.hc.CurrentHeader() + if currentHeader.Hash() == hash { + bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) + } + if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { + newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) + rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash()) + bc.currentFastBlock.Store(newFastBlock) + headFastBlockGauge.Update(int64(newFastBlock.NumberU64())) + } + if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { + newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) + rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash()) + bc.currentBlock.Store(newBlock) + headBlockGauge.Update(int64(newBlock.NumberU64())) + } + } + // Truncate ancient data which exceeds the current header. + // + // Notably, it can happen that system crashes without truncating the ancient data + // but the head indicator has been updated in the active store. Regarding this issue, + // system will self recovery by truncating the extra data during the setup phase. + if err := bc.truncateAncient(bc.hc.CurrentHeader().Number.Uint64()); err != nil { + log.Crit("Truncate ancient store failed", "err", err) + } +} + +// truncateAncient rewinds the blockchain to the specified header and deletes all +// data in the ancient store that exceeds the specified header. +func (bc *BlockChain) truncateAncient(head uint64) error { + frozen, err := bc.db.Ancients() + if err != nil { + return err + } + // Short circuit if there is no data to truncate in ancient store. + if frozen <= head+1 { + return nil + } + // Truncate all the data in the freezer beyond the specified head + if err := bc.db.TruncateAncients(head + 1); err != nil { + return err + } + // Clear out any stale content from the caches + bc.hc.headerCache.Purge() + bc.hc.tdCache.Purge() + bc.hc.numberCache.Purge() + + // Clear out any stale content from the caches + bc.bodyCache.Purge() + bc.bodyRLPCache.Purge() + bc.receiptsCache.Purge() + bc.blockCache.Purge() + bc.futureBlocks.Purge() + + log.Info("Rewind ancient data", "number", head) + return nil +} + +// InsertReceiptChain attempts to complete an already existing header chain with +// transaction and receipt data. +func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) { + bc.wg.Add(1) + defer bc.wg.Done() + + var ( + ancientBlocks, liveBlocks types.Blocks + ancientReceipts, liveReceipts []types.Receipts + ) + // Do a sanity check that the provided chain is actually ordered and linked + for i := 0; i < len(blockChain); i++ { + if i != 0 { + if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { + log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), + "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) + return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, blockChain[i-1].NumberU64(), + blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) + } + } + if blockChain[i].NumberU64() <= ancientLimit { + ancientBlocks, ancientReceipts = append(ancientBlocks, blockChain[i]), append(ancientReceipts, receiptChain[i]) + } else { + liveBlocks, liveReceipts = append(liveBlocks, blockChain[i]), append(liveReceipts, receiptChain[i]) + } + } + + var ( + stats = struct{ processed, ignored int32 }{} + start = time.Now() + size = 0 + ) + // updateHead updates the head fast sync block if the inserted blocks are better + // and returns a indicator whether the inserted blocks are canonical. + updateHead := func(head *types.Block) bool { + var isCanonical bool + bc.chainmu.Lock() + if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case + currentFastBlock := bc.CurrentFastBlock() + if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { + rawdb.WriteHeadFastBlockHash(bc.db, head.Hash()) + bc.currentFastBlock.Store(head) + headFastBlockGauge.Update(int64(head.NumberU64())) + isCanonical = true + } + } + bc.chainmu.Unlock() + return isCanonical + } + // writeAncient writes blockchain and corresponding receipt chain into ancient store. + // + // this function only accepts canonical chain data. All side chain will be reverted + // eventually. + writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { + var ( + previous = bc.CurrentFastBlock() + batch = bc.db.NewBatch() + ) + // If any error occurs before updating the head or we are inserting a side chain, + // all the data written this time wll be rolled back. + defer func() { + if previous != nil { + if err := bc.truncateAncient(previous.NumberU64()); err != nil { + log.Crit("Truncate ancient store failed", "err", err) + } + } + }() + var deleted types.Blocks + for i, block := range blockChain { + // Short circuit insertion if shutting down or processing failed + if atomic.LoadInt32(&bc.procInterrupt) == 1 { + return 0, errInsertionInterrupted + } + // Short circuit insertion if it is required(used in testing only) + if bc.terminateInsert != nil && bc.terminateInsert(block.Hash(), block.NumberU64()) { + return i, errors.New("insertion is terminated for testing purpose") + } + // Short circuit if the owner header is unknown + if !bc.HasHeader(block.Hash(), block.NumberU64()) { + return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) + } + var ( + start = time.Now() + logged = time.Now() + count int + ) + // Migrate all ancient blocks. This can happen if someone upgrades from Geth + // 1.8.x to 1.9.x mid-fast-sync. Perhaps we can get rid of this path in the + // long term. + for { + // We can ignore the error here since light client won't hit this code path. + frozen, _ := bc.db.Ancients() + if frozen >= block.NumberU64() { + break + } + h := rawdb.ReadCanonicalHash(bc.db, frozen) + b := rawdb.ReadBlock(bc.db, h, frozen) + size += rawdb.WriteAncientBlock(bc.db, b, rawdb.ReadReceipts(bc.db, h, frozen, bc.chainConfig), rawdb.ReadTd(bc.db, h, frozen)) + count += 1 + + // Always keep genesis block in active database. + if b.NumberU64() != 0 { + deleted = append(deleted, b) + } + if time.Since(logged) > 8*time.Second { + log.Info("Migrating ancient blocks", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) + logged = time.Now() + } + } + if count > 0 { + log.Info("Migrated ancient blocks", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) + } + // Flush data into ancient database. + size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64())) + rawdb.WriteTxLookupEntries(batch, block) + + stats.processed++ + } + // Flush all tx-lookup index data. + size += batch.ValueSize() + if err := batch.Write(); err != nil { + return 0, err + } + batch.Reset() + + // Sync the ancient store explicitly to ensure all data has been flushed to disk. + if err := bc.db.Sync(); err != nil { + return 0, err + } + if !updateHead(blockChain[len(blockChain)-1]) { + return 0, errors.New("side blocks can't be accepted as the ancient chain data") + } + previous = nil // disable rollback explicitly + + // Wipe out canonical block data. + for _, block := range append(deleted, blockChain...) { + // Always keep genesis block in active database. + if block.NumberU64() != 0 { + rawdb.DeleteBlockWithoutNumber(batch, block.Hash(), block.NumberU64()) + rawdb.DeleteCanonicalHash(batch, block.NumberU64()) + } + } + if err := batch.Write(); err != nil { + return 0, err + } + batch.Reset() + + // Wipe out side chain too. + for _, block := range append(deleted, blockChain...) { + // Always keep genesis block in active database. + if block.NumberU64() != 0 { + for _, hash := range rawdb.ReadAllHashes(bc.db, block.NumberU64()) { + rawdb.DeleteBlock(batch, hash, block.NumberU64()) + } + } + } + if err := batch.Write(); err != nil { + return 0, err + } + return 0, nil + } + // writeLive writes blockchain and corresponding receipt chain into active store. + writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { + batch := bc.db.NewBatch() + for i, block := range blockChain { + // Short circuit insertion if shutting down or processing failed + if atomic.LoadInt32(&bc.procInterrupt) == 1 { + return 0, errInsertionInterrupted + } + // Short circuit if the owner header is unknown + if !bc.HasHeader(block.Hash(), block.NumberU64()) { + return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) + } + if bc.HasBlock(block.Hash(), block.NumberU64()) { + stats.ignored++ + continue + } + // Write all the data out into the database + rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) + rawdb.WriteTxLookupEntries(batch, block) + + stats.processed++ + if batch.ValueSize() >= ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + return 0, err + } + size += batch.ValueSize() + batch.Reset() + } + } + if batch.ValueSize() > 0 { + size += batch.ValueSize() + if err := batch.Write(); err != nil { + return 0, err + } + } + updateHead(blockChain[len(blockChain)-1]) + return 0, nil + } + // Write downloaded chain data and corresponding receipt chain data. + if len(ancientBlocks) > 0 { + if n, err := writeAncient(ancientBlocks, ancientReceipts); err != nil { + if err == errInsertionInterrupted { + return 0, nil + } + return n, err + } + } + if len(liveBlocks) > 0 { + if n, err := writeLive(liveBlocks, liveReceipts); err != nil { + if err == errInsertionInterrupted { + return 0, nil + } + return n, err + } + } + + head := blockChain[len(blockChain)-1] + context := []interface{}{ + "count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)), + "number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.Time()), 0)), + "size", common.StorageSize(size), + } + if stats.ignored > 0 { + context = append(context, []interface{}{"ignored", stats.ignored}...) + } + log.Info("Imported new block receipts", context...) + + return 0, nil +} + +var lastWrite uint64 + +// writeBlockWithoutState writes only the block and its metadata to the database, +// but does not write any state. This is used to construct competing side forks +// up to the point where they exceed the canonical total difficulty. +func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) { + bc.wg.Add(1) + defer bc.wg.Done() + + if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil { + return err + } + rawdb.WriteBlock(bc.db, block) + + return nil +} + +// writeKnownBlock updates the head block flag with a known block +// and introduces chain reorg if necessary. +func (bc *BlockChain) writeKnownBlock(block *types.Block) error { + bc.wg.Add(1) + defer bc.wg.Done() + + current := bc.CurrentBlock() + if block.ParentHash() != current.Hash() { + if err := bc.reorg(current, block); err != nil { + return err + } + } + // Write the positional metadata for transaction/receipt lookups. + // Preimages here is empty, ignore it. + rawdb.WriteTxLookupEntries(bc.db, block) + + bc.insert(block) + return nil +} + +func (bc *BlockChain) AddToStateDiffProcessedCollection(hash common.Hash) { + count := bc.stateDiffsProcessed[hash] + bc.stateDiffsProcessed[hash] = count + 1 +} + +// WriteBlockWithState writes the block and all associated state to the database. +func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + return bc.writeBlockWithState(block, receipts, state) +} + +// writeBlockWithState writes the block and all associated state to the database, +// but is expects the chain mutex to be held. +func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { + bc.wg.Add(1) + defer bc.wg.Done() + + // Calculate the total difficulty of the block + ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) + if ptd == nil { + return NonStatTy, consensus.ErrUnknownAncestor + } + // Make sure no inconsistent state is leaked during insertion + currentBlock := bc.CurrentBlock() + localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) + externTd := new(big.Int).Add(block.Difficulty(), ptd) + + // Irrelevant of the canonical status, write the block itself to the database + if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { + return NonStatTy, err + } + rawdb.WriteBlock(bc.db, block) + + root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) + if err != nil { + return NonStatTy, err + } + triedb := bc.stateCache.TrieDB() + + // If we're running an archive node, always flush + if bc.cacheConfig.TrieDirtyDisabled { + if err := triedb.Commit(root, false); err != nil { + return NonStatTy, err + } + } else { + // Full but not archive node, do proper garbage collection + triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive + bc.triegc.Push(root, -int64(block.NumberU64())) + + if current := block.NumberU64(); current > TriesInMemory { + // If we exceeded our memory allowance, flush matured singleton nodes to disk + var ( + nodes, imgs = triedb.Size() + limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024 + ) + if nodes > limit || imgs > 4*1024*1024 { + triedb.Cap(limit - ethdb.IdealBatchSize) + } + // Find the next state trie we need to commit + chosen := current - TriesInMemory + + // If we exceeded out time allowance, flush an entire trie to disk + if bc.gcproc > bc.cacheConfig.TrieTimeLimit { + // If the header is missing (canonical chain behind), we're reorging a low + // diff sidechain. Suspend committing until this operation is completed. + header := bc.GetHeaderByNumber(chosen) + if header == nil { + log.Warn("Reorg in progress, trie commit postponed", "number", chosen) + } else { + // If we're exceeding limits but haven't reached a large enough memory gap, + // warn the user that the system is becoming unstable. + if chosen < lastWrite+TriesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { + log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/TriesInMemory) + } + // Flush an entire trie and restart the counters + triedb.Commit(header.Root, true) + lastWrite = chosen + bc.gcproc = 0 + } + } + // Garbage collect anything below our required write retention + for !bc.triegc.Empty() { + root, number := bc.triegc.Pop() + if uint64(-number) > chosen { + bc.triegc.Push(root, number) + break + } + if bc.cacheConfig.ProcessingStateDiffs { + if !bc.allowedRootToBeDereferenced(root.(common.Hash)) { + bc.triegc.Push(root, number) + break + } else { + log.Debug("Current root found in stateDiffsProcessed collection with a count of 2, okay to dereference", + "root", root.(common.Hash).Hex(), + "blockNumber", uint64(-number), + "size of stateDiffsProcessed", len(bc.stateDiffsProcessed)) + delete(bc.stateDiffsProcessed, root.(common.Hash)) + } + } + log.Debug("Dereferencing", "root", root.(common.Hash).Hex()) + triedb.Dereference(root.(common.Hash)) + } + } + } + + // Write other block data using a batch. + batch := bc.db.NewBatch() + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) + + // If the total difficulty is higher than our known, add it to the canonical chain + // Second clause in the if statement reduces the vulnerability to selfish mining. + // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf + reorg := externTd.Cmp(localTd) > 0 + currentBlock = bc.CurrentBlock() + if !reorg && externTd.Cmp(localTd) == 0 { + // Split same-difficulty blocks by number, then preferentially select + // the block generated by the local miner as the canonical block. + if block.NumberU64() < currentBlock.NumberU64() { + reorg = true + } else if block.NumberU64() == currentBlock.NumberU64() { + var currentPreserve, blockPreserve bool + if bc.shouldPreserve != nil { + currentPreserve, blockPreserve = bc.shouldPreserve(currentBlock), bc.shouldPreserve(block) + } + reorg = !currentPreserve && (blockPreserve || mrand.Float64() < 0.5) + } + } + if reorg { + // Reorganise the chain if the parent is not the head block + if block.ParentHash() != currentBlock.Hash() { + if err := bc.reorg(currentBlock, block); err != nil { + return NonStatTy, err + } + } + // Write the positional metadata for transaction/receipt lookups and preimages + rawdb.WriteTxLookupEntries(batch, block) + rawdb.WritePreimages(batch, state.Preimages()) + + status = CanonStatTy + } else { + status = SideStatTy + } + if err := batch.Write(); err != nil { + return NonStatTy, err + } + + // Set new head. + if status == CanonStatTy { + bc.insert(block) + } + bc.futureBlocks.Remove(block.Hash()) + return status, nil +} + +// since we need the state tries of the current block and its parent in-memory +// in order to process statediffs, we should avoid dereferencing roots until +// its statediff and its child have been processed +func (bc *BlockChain) allowedRootToBeDereferenced(root common.Hash) bool { + diffProcessedForSelfAndChildCount := 2 + count := bc.stateDiffsProcessed[root] + return count >= diffProcessedForSelfAndChildCount +} + +// addFutureBlock checks if the block is within the max allowed window to get +// accepted for future processing, and returns an error if the block is too far +// ahead and was not added. +func (bc *BlockChain) addFutureBlock(block *types.Block) error { + max := uint64(time.Now().Unix() + maxTimeFutureBlocks) + if block.Time() > max { + return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max) + } + bc.futureBlocks.Add(block.Hash(), block) + return nil +} + +// InsertChain attempts to insert the given batch of blocks in to the canonical +// chain or, otherwise, create a fork. If an error is returned it will return +// the index number of the failing block as well an error describing what went +// wrong. +// +// After insertion is done, all accumulated events will be fired. +func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { + // Sanity check that we have something meaningful to import + if len(chain) == 0 { + return 0, nil + } + + bc.blockProcFeed.Send(true) + defer bc.blockProcFeed.Send(false) + + // Remove already known canon-blocks + var ( + block, prev *types.Block + ) + // Do a sanity check that the provided chain is actually ordered and linked + for i := 1; i < len(chain); i++ { + block = chain[i] + prev = chain[i-1] + if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() { + // Chain broke ancestry, log a message (programming error) and skip insertion + log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(), + "parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash()) + + return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, prev.NumberU64(), + prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4]) + } + } + // Pre-checks passed, start the full block imports + bc.wg.Add(1) + bc.chainmu.Lock() + n, events, logs, err := bc.insertChain(chain, true) + bc.chainmu.Unlock() + bc.wg.Done() + + bc.PostChainEvents(events, logs) + return n, err +} + +// insertChain is the internal implementation of InsertChain, which assumes that +// 1) chains are contiguous, and 2) The chain mutex is held. +// +// This method is split out so that import batches that require re-injecting +// historical blocks can do so without releasing the lock, which could lead to +// racey behaviour. If a sidechain import is in progress, and the historic state +// is imported, but then new canon-head is added before the actual sidechain +// completes, then the historic state could be pruned again +func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) { + // If the chain is terminating, don't even bother starting up + if atomic.LoadInt32(&bc.procInterrupt) == 1 { + return 0, nil, nil, nil + } + // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) + senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) + + // A queued approach to delivering events. This is generally + // faster than direct delivery and requires much less mutex + // acquiring. + var ( + stats = insertStats{startTime: mclock.Now()} + events = make([]interface{}, 0, len(chain)) + lastCanon *types.Block + coalescedLogs []*types.Log + ) + // Start the parallel header verifier + headers := make([]*types.Header, len(chain)) + seals := make([]bool, len(chain)) + + for i, block := range chain { + headers[i] = block.Header() + seals[i] = verifySeals + } + abort, results := bc.engine.VerifyHeaders(bc, headers, seals) + defer close(abort) + + // Peek the error for the first block to decide the directing import logic + it := newInsertIterator(chain, results, bc.validator) + + block, err := it.next() + + // Left-trim all the known blocks + if err == ErrKnownBlock { + // First block (and state) is known + // 1. We did a roll-back, and should now do a re-import + // 2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot + // from the canonical chain, which has not been verified. + // Skip all known blocks that are behind us + var ( + current = bc.CurrentBlock() + localTd = bc.GetTd(current.Hash(), current.NumberU64()) + externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) // The first block can't be nil + ) + for block != nil && err == ErrKnownBlock { + externTd = new(big.Int).Add(externTd, block.Difficulty()) + if localTd.Cmp(externTd) < 0 { + break + } + log.Debug("Ignoring already known block", "number", block.Number(), "hash", block.Hash()) + stats.ignored++ + + block, err = it.next() + } + // The remaining blocks are still known blocks, the only scenario here is: + // During the fast sync, the pivot point is already submitted but rollback + // happens. Then node resets the head full block to a lower height via `rollback` + // and leaves a few known blocks in the database. + // + // When node runs a fast sync again, it can re-import a batch of known blocks via + // `insertChain` while a part of them have higher total difficulty than current + // head full block(new pivot point). + for block != nil && err == ErrKnownBlock { + log.Debug("Writing previously known block", "number", block.Number(), "hash", block.Hash()) + if err := bc.writeKnownBlock(block); err != nil { + return it.index, nil, nil, err + } + lastCanon = block + + block, err = it.next() + } + // Falls through to the block import + } + switch { + // First block is pruned, insert as sidechain and reorg only if TD grows enough + case err == consensus.ErrPrunedAncestor: + log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash()) + return bc.insertSideChain(block, it) + + // First block is future, shove it (and all children) to the future queue (unknown ancestor) + case err == consensus.ErrFutureBlock || (err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(it.first().ParentHash())): + for block != nil && (it.index == 0 || err == consensus.ErrUnknownAncestor) { + log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash()) + if err := bc.addFutureBlock(block); err != nil { + return it.index, events, coalescedLogs, err + } + block, err = it.next() + } + stats.queued += it.processed() + stats.ignored += it.remaining() + + // If there are any still remaining, mark as ignored + return it.index, events, coalescedLogs, err + + // Some other error occurred, abort + case err != nil: + stats.ignored += len(it.chain) + bc.reportBlock(block, nil, err) + return it.index, events, coalescedLogs, err + } + // No validation errors for the first block (or chain prefix skipped) + for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() { + // If the chain is terminating, stop processing blocks + if atomic.LoadInt32(&bc.procInterrupt) == 1 { + log.Debug("Premature abort during blocks processing") + break + } + // If the header is a banned one, straight out abort + if BadHashes[block.Hash()] { + bc.reportBlock(block, nil, ErrBlacklistedHash) + return it.index, events, coalescedLogs, ErrBlacklistedHash + } + // If the block is known (in the middle of the chain), it's a special case for + // Clique blocks where they can share state among each other, so importing an + // older block might complete the state of the subsequent one. In this case, + // just skip the block (we already validated it once fully (and crashed), since + // its header and body was already in the database). + if err == ErrKnownBlock { + logger := log.Debug + if bc.chainConfig.Clique == nil { + logger = log.Warn + } + logger("Inserted known block", "number", block.Number(), "hash", block.Hash(), + "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), + "root", block.Root()) + + if err := bc.writeKnownBlock(block); err != nil { + return it.index, nil, nil, err + } + stats.processed++ + + // We can assume that logs are empty here, since the only way for consecutive + // Clique blocks to have the same state is if there are no transactions. + events = append(events, ChainEvent{block, block.Hash(), nil}) + lastCanon = block + + continue + } + // Retrieve the parent block and it's state to execute on top + start := time.Now() + + parent := it.previous() + if parent == nil { + parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) + } + statedb, err := state.New(parent.Root, bc.stateCache) + if err != nil { + return it.index, events, coalescedLogs, err + } + // If we have a followup block, run that against the current state to pre-cache + // transactions and probabilistically some of the account/storage trie nodes. + var followupInterrupt uint32 + + if !bc.cacheConfig.TrieCleanNoPrefetch { + if followup, err := it.peek(); followup != nil && err == nil { + go func(start time.Time) { + throwaway, _ := state.New(parent.Root, bc.stateCache) + bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt) + + blockPrefetchExecuteTimer.Update(time.Since(start)) + if atomic.LoadUint32(&followupInterrupt) == 1 { + blockPrefetchInterruptMeter.Mark(1) + } + }(time.Now()) + } + } + // Process block using the parent state as reference point + substart := time.Now() + receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig) + if err != nil { + bc.reportBlock(block, receipts, err) + atomic.StoreUint32(&followupInterrupt, 1) + return it.index, events, coalescedLogs, err + } + // Update the metrics touched during block processing + accountReadTimer.Update(statedb.AccountReads) // Account reads are complete, we can mark them + storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete, we can mark them + accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete, we can mark them + storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete, we can mark them + + triehash := statedb.AccountHashes + statedb.StorageHashes // Save to not double count in validation + trieproc := statedb.AccountReads + statedb.AccountUpdates + trieproc += statedb.StorageReads + statedb.StorageUpdates + + blockExecutionTimer.Update(time.Since(substart) - trieproc - triehash) + + // Validate the state using the default validator + substart = time.Now() + if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil { + bc.reportBlock(block, receipts, err) + atomic.StoreUint32(&followupInterrupt, 1) + return it.index, events, coalescedLogs, err + } + proctime := time.Since(start) + + // Update the metrics touched during block validation + accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete, we can mark them + storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete, we can mark them + + blockValidationTimer.Update(time.Since(substart) - (statedb.AccountHashes + statedb.StorageHashes - triehash)) + + // Write the block to the chain and get the status. + substart = time.Now() + status, err := bc.writeBlockWithState(block, receipts, statedb) + if err != nil { + atomic.StoreUint32(&followupInterrupt, 1) + return it.index, events, coalescedLogs, err + } + atomic.StoreUint32(&followupInterrupt, 1) + + // Update the metrics touched during block commit + accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them + storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them + + blockWriteTimer.Update(time.Since(substart) - statedb.AccountCommits - statedb.StorageCommits) + blockInsertTimer.UpdateSince(start) + + switch status { + case CanonStatTy: + log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), + "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), + "elapsed", common.PrettyDuration(time.Since(start)), + "root", block.Root()) + + coalescedLogs = append(coalescedLogs, logs...) + events = append(events, ChainEvent{block, block.Hash(), logs}) + lastCanon = block + + // Only count canonical blocks for GC processing time + bc.gcproc += proctime + + case SideStatTy: + log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), + "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), + "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), + "root", block.Root()) + events = append(events, ChainSideEvent{block}) + + default: + // This in theory is impossible, but lets be nice to our future selves and leave + // a log, instead of trying to track down blocks imports that don't emit logs. + log.Warn("Inserted block with unknown status", "number", block.Number(), "hash", block.Hash(), + "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), + "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), + "root", block.Root()) + } + stats.processed++ + stats.usedGas += usedGas + + dirty, _ := bc.stateCache.TrieDB().Size() + stats.report(chain, it.index, dirty) + } + // Any blocks remaining here? The only ones we care about are the future ones + if block != nil && err == consensus.ErrFutureBlock { + if err := bc.addFutureBlock(block); err != nil { + return it.index, events, coalescedLogs, err + } + block, err = it.next() + + for ; block != nil && err == consensus.ErrUnknownAncestor; block, err = it.next() { + if err := bc.addFutureBlock(block); err != nil { + return it.index, events, coalescedLogs, err + } + stats.queued++ + } + } + stats.ignored += it.remaining() + + // Append a single chain head event if we've progressed the chain + if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { + events = append(events, ChainHeadEvent{lastCanon}) + } + return it.index, events, coalescedLogs, err +} + +// insertSideChain is called when an import batch hits upon a pruned ancestor +// error, which happens when a sidechain with a sufficiently old fork-block is +// found. +// +// The method writes all (header-and-body-valid) blocks to disk, then tries to +// switch over to the new chain if the TD exceeded the current chain. +func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (int, []interface{}, []*types.Log, error) { + var ( + externTd *big.Int + current = bc.CurrentBlock() + ) + // The first sidechain block error is already verified to be ErrPrunedAncestor. + // Since we don't import them here, we expect ErrUnknownAncestor for the remaining + // ones. Any other errors means that the block is invalid, and should not be written + // to disk. + err := consensus.ErrPrunedAncestor + for ; block != nil && (err == consensus.ErrPrunedAncestor); block, err = it.next() { + // Check the canonical state root for that number + if number := block.NumberU64(); current.NumberU64() >= number { + canonical := bc.GetBlockByNumber(number) + if canonical != nil && canonical.Hash() == block.Hash() { + // Not a sidechain block, this is a re-import of a canon block which has it's state pruned + continue + } + if canonical != nil && canonical.Root() == block.Root() { + // This is most likely a shadow-state attack. When a fork is imported into the + // database, and it eventually reaches a block height which is not pruned, we + // just found that the state already exist! This means that the sidechain block + // refers to a state which already exists in our canon chain. + // + // If left unchecked, we would now proceed importing the blocks, without actually + // having verified the state of the previous blocks. + log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root()) + + // If someone legitimately side-mines blocks, they would still be imported as usual. However, + // we cannot risk writing unverified blocks to disk when they obviously target the pruning + // mechanism. + return it.index, nil, nil, errors.New("sidechain ghost-state attack") + } + } + if externTd == nil { + externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) + } + externTd = new(big.Int).Add(externTd, block.Difficulty()) + + if !bc.HasBlock(block.Hash(), block.NumberU64()) { + start := time.Now() + if err := bc.writeBlockWithoutState(block, externTd); err != nil { + return it.index, nil, nil, err + } + log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(), + "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), + "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), + "root", block.Root()) + } + } + // At this point, we've written all sidechain blocks to database. Loop ended + // either on some other error or all were processed. If there was some other + // error, we can ignore the rest of those blocks. + // + // If the externTd was larger than our local TD, we now need to reimport the previous + // blocks to regenerate the required state + localTd := bc.GetTd(current.Hash(), current.NumberU64()) + if localTd.Cmp(externTd) > 0 { + log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd) + return it.index, nil, nil, err + } + // Gather all the sidechain hashes (full blocks may be memory heavy) + var ( + hashes []common.Hash + numbers []uint64 + ) + parent := it.previous() + for parent != nil && !bc.HasState(parent.Root) { + hashes = append(hashes, parent.Hash()) + numbers = append(numbers, parent.Number.Uint64()) + + parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1) + } + if parent == nil { + return it.index, nil, nil, errors.New("missing parent") + } + // Import all the pruned blocks to make the state available + var ( + blocks []*types.Block + memory common.StorageSize + ) + for i := len(hashes) - 1; i >= 0; i-- { + // Append the next block to our batch + block := bc.GetBlock(hashes[i], numbers[i]) + + blocks = append(blocks, block) + memory += block.Size() + + // If memory use grew too large, import and continue. Sadly we need to discard + // all raised events and logs from notifications since we're too heavy on the + // memory here. + if len(blocks) >= 2048 || memory > 64*1024*1024 { + log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64()) + if _, _, _, err := bc.insertChain(blocks, false); err != nil { + return 0, nil, nil, err + } + blocks, memory = blocks[:0], 0 + + // If the chain is terminating, stop processing blocks + if atomic.LoadInt32(&bc.procInterrupt) == 1 { + log.Debug("Premature abort during blocks processing") + return 0, nil, nil, nil + } + } + } + if len(blocks) > 0 { + log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64()) + return bc.insertChain(blocks, false) + } + return 0, nil, nil, nil +} + +// reorg takes two blocks, an old chain and a new chain and will reconstruct the +// blocks and inserts them to be part of the new canonical chain and accumulates +// potential missing transactions and post an event about them. +func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { + var ( + newChain types.Blocks + oldChain types.Blocks + commonBlock *types.Block + + deletedTxs types.Transactions + addedTxs types.Transactions + + deletedLogs []*types.Log + rebirthLogs []*types.Log + + // collectLogs collects the logs that were generated during the + // processing of the block that corresponds with the given hash. + // These logs are later announced as deleted or reborn + collectLogs = func(hash common.Hash, removed bool) { + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return + } + receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) + for _, receipt := range receipts { + for _, log := range receipt.Logs { + l := *log + if removed { + l.Removed = true + deletedLogs = append(deletedLogs, &l) + } else { + rebirthLogs = append(rebirthLogs, &l) + } + } + } + } + ) + // Reduce the longer chain to the same number as the shorter one + if oldBlock.NumberU64() > newBlock.NumberU64() { + // Old chain is longer, gather all transactions and logs as deleted ones + for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { + oldChain = append(oldChain, oldBlock) + deletedTxs = append(deletedTxs, oldBlock.Transactions()...) + collectLogs(oldBlock.Hash(), true) + } + } else { + // New chain is longer, stash all blocks away for subsequent insertion + for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { + newChain = append(newChain, newBlock) + } + } + if oldBlock == nil { + return fmt.Errorf("invalid old chain") + } + if newBlock == nil { + return fmt.Errorf("invalid new chain") + } + // Both sides of the reorg are at the same number, reduce both until the common + // ancestor is found + for { + // If the common ancestor was found, bail out + if oldBlock.Hash() == newBlock.Hash() { + commonBlock = oldBlock + break + } + // Remove an old block as well as stash away a new block + oldChain = append(oldChain, oldBlock) + deletedTxs = append(deletedTxs, oldBlock.Transactions()...) + collectLogs(oldBlock.Hash(), true) + + newChain = append(newChain, newBlock) + + // Step back with both chains + oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) + if oldBlock == nil { + return fmt.Errorf("invalid old chain") + } + newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) + if newBlock == nil { + return fmt.Errorf("invalid new chain") + } + } + // Ensure the user sees large reorgs + if len(oldChain) > 0 && len(newChain) > 0 { + logFn := log.Debug + if len(oldChain) > 63 { + logFn = log.Warn + } + logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(), + "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) + } else { + log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) + } + // Insert the new chain(except the head block(reverse order)), + // taking care of the proper incremental order. + for i := len(newChain) - 1; i >= 1; i-- { + // Insert the block in the canonical way, re-writing history + bc.insert(newChain[i]) + + // Collect reborn logs due to chain reorg + collectLogs(newChain[i].Hash(), false) + + // Write lookup entries for hash based transaction/receipt searches + rawdb.WriteTxLookupEntries(bc.db, newChain[i]) + addedTxs = append(addedTxs, newChain[i].Transactions()...) + } + // When transactions get deleted from the database, the receipts that were + // created in the fork must also be deleted + batch := bc.db.NewBatch() + for _, tx := range types.TxDifference(deletedTxs, addedTxs) { + rawdb.DeleteTxLookupEntry(batch, tx.Hash()) + } + // Delete any canonical number assignments above the new head + number := bc.CurrentBlock().NumberU64() + for i := number + 1; ; i++ { + hash := rawdb.ReadCanonicalHash(bc.db, i) + if hash == (common.Hash{}) { + break + } + rawdb.DeleteCanonicalHash(batch, i) + } + batch.Write() + // If any logs need to be fired, do it now. In theory we could avoid creating + // this goroutine if there are no events to fire, but realistcally that only + // ever happens if we're reorging empty blocks, which will only happen on idle + // networks where performance is not an issue either way. + // + // TODO(karalabe): Can we get rid of the goroutine somehow to guarantee correct + // event ordering? + go func() { + if len(deletedLogs) > 0 { + bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) + } + if len(rebirthLogs) > 0 { + bc.logsFeed.Send(rebirthLogs) + } + if len(oldChain) > 0 { + for _, block := range oldChain { + bc.chainSideFeed.Send(ChainSideEvent{Block: block}) + } + } + }() + return nil +} + +// PostChainEvents iterates over the events generated by a chain insertion and +// posts them into the event feed. +// TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock. +func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) { + // post event logs for further processing + if logs != nil { + bc.logsFeed.Send(logs) + } + for _, event := range events { + switch ev := event.(type) { + case ChainEvent: + bc.chainFeed.Send(ev) + + case ChainHeadEvent: + bc.chainHeadFeed.Send(ev) + + case ChainSideEvent: + bc.chainSideFeed.Send(ev) + } + } +} + +func (bc *BlockChain) update() { + futureTimer := time.NewTicker(5 * time.Second) + defer futureTimer.Stop() + for { + select { + case <-futureTimer.C: + bc.procFutureBlocks() + case <-bc.quit: + return + } + } +} + +// BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network +func (bc *BlockChain) BadBlocks() []*types.Block { + blocks := make([]*types.Block, 0, bc.badBlocks.Len()) + for _, hash := range bc.badBlocks.Keys() { + if blk, exist := bc.badBlocks.Peek(hash); exist { + block := blk.(*types.Block) + blocks = append(blocks, block) + } + } + return blocks +} + +// addBadBlock adds a bad block to the bad-block LRU cache +func (bc *BlockChain) addBadBlock(block *types.Block) { + bc.badBlocks.Add(block.Hash(), block) +} + +// reportBlock logs a bad block error. +func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { + bc.addBadBlock(block) + + var receiptString string + for i, receipt := range receipts { + receiptString += fmt.Sprintf("\t %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x\n", + i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(), + receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState) + } + log.Error(fmt.Sprintf(` +########## BAD BLOCK ######### +Chain config: %v + +Number: %v +Hash: 0x%x +%v + +Error: %v +############################## +`, bc.chainConfig, block.Number(), block.Hash(), receiptString, err)) +} + +// InsertHeaderChain attempts to insert the given header chain in to the local +// chain, possibly creating a reorg. If an error is returned, it will return the +// index number of the failing header as well an error describing what went wrong. +// +// The verify parameter can be used to fine tune whether nonce verification +// should be done or not. The reason behind the optional check is because some +// of the header retrieval mechanisms already need to verify nonces, as well as +// because nonces can be verified sparsely, not needing to check each. +func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + start := time.Now() + if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { + return i, err + } + + // Make sure only one thread manipulates the chain at once + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + bc.wg.Add(1) + defer bc.wg.Done() + + whFunc := func(header *types.Header) error { + _, err := bc.hc.WriteHeader(header) + return err + } + return bc.hc.InsertHeaderChain(chain, whFunc, start) +} + +// CurrentHeader retrieves the current head header of the canonical chain. The +// header is retrieved from the HeaderChain's internal cache. +func (bc *BlockChain) CurrentHeader() *types.Header { + return bc.hc.CurrentHeader() +} + +// GetTd retrieves a block's total difficulty in the canonical chain from the +// database by hash and number, caching it if found. +func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { + return bc.hc.GetTd(hash, number) +} + +// GetTdByHash retrieves a block's total difficulty in the canonical chain from the +// database by hash, caching it if found. +func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { + return bc.hc.GetTdByHash(hash) +} + +// GetHeader retrieves a block header from the database by hash and number, +// caching it if found. +func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { + return bc.hc.GetHeader(hash, number) +} + +// GetHeaderByHash retrieves a block header from the database by hash, caching it if +// found. +func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { + return bc.hc.GetHeaderByHash(hash) +} + +// HasHeader checks if a block header is present in the database or not, caching +// it if present. +func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { + return bc.hc.HasHeader(hash, number) +} + +// GetBlockHashesFromHash retrieves a number of block hashes starting at a given +// hash, fetching towards the genesis block. +func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { + return bc.hc.GetBlockHashesFromHash(hash, max) +} + +// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or +// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the +// number of blocks to be individually checked before we reach the canonical chain. +// +// Note: ancestor == 0 returns the same block, 1 returns its parent and so on. +func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { + bc.chainmu.RLock() + defer bc.chainmu.RUnlock() + + return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) +} + +// GetHeaderByNumber retrieves a block header from the database by number, +// caching it (associated with its hash) if found. +func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { + return bc.hc.GetHeaderByNumber(number) +} + +// Config retrieves the blockchain's chain configuration. +func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } + +// Engine retrieves the blockchain's consensus engine. +func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } + +// SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. +func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { + return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) +} + +// SubscribeChainEvent registers a subscription of ChainEvent. +func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription { + return bc.scope.Track(bc.chainFeed.Subscribe(ch)) +} + +// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. +func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { + return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch)) +} + +// SubscribeChainSideEvent registers a subscription of ChainSideEvent. +func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { + return bc.scope.Track(bc.chainSideFeed.Subscribe(ch)) +} + +// SubscribeLogsEvent registers a subscription of []*types.Log. +func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + return bc.scope.Track(bc.logsFeed.Subscribe(ch)) +} + +// SubscribeBlockProcessingEvent registers a subscription of bool where true means +// block processing has started while false means it has stopped. +func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { + return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/blockchain_insert.go b/vendor/github.com/ethereum/go-ethereum/core/blockchain_insert.go new file mode 100644 index 00000000..5685b0a4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/blockchain_insert.go @@ -0,0 +1,166 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// insertStats tracks and reports on block insertion. +type insertStats struct { + queued, processed, ignored int + usedGas uint64 + lastIndex int + startTime mclock.AbsTime +} + +// statsReportLimit is the time limit during import and export after which we +// always print out progress. This avoids the user wondering what's going on. +const statsReportLimit = 8 * time.Second + +// report prints statistics if some number of blocks have been processed +// or more than a few seconds have passed since the last message. +func (st *insertStats) report(chain []*types.Block, index int, dirty common.StorageSize) { + // Fetch the timings for the batch + var ( + now = mclock.Now() + elapsed = time.Duration(now) - time.Duration(st.startTime) + ) + // If we're at the last block of the batch or report period reached, log + if index == len(chain)-1 || elapsed >= statsReportLimit { + // Count the number of transactions in this segment + var txs int + for _, block := range chain[st.lastIndex : index+1] { + txs += len(block.Transactions()) + } + end := chain[index] + + // Assemble the log context and send it to the logger + context := []interface{}{ + "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, + "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), + "number", end.Number(), "hash", end.Hash(), + } + if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute { + context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) + } + context = append(context, []interface{}{"dirty", dirty}...) + + if st.queued > 0 { + context = append(context, []interface{}{"queued", st.queued}...) + } + if st.ignored > 0 { + context = append(context, []interface{}{"ignored", st.ignored}...) + } + log.Info("Imported new chain segment", context...) + + // Bump the stats reported to the next section + *st = insertStats{startTime: now, lastIndex: index + 1} + } +} + +// insertIterator is a helper to assist during chain import. +type insertIterator struct { + chain types.Blocks // Chain of blocks being iterated over + + results <-chan error // Verification result sink from the consensus engine + errors []error // Header verification errors for the blocks + + index int // Current offset of the iterator + validator Validator // Validator to run if verification succeeds +} + +// newInsertIterator creates a new iterator based on the given blocks, which are +// assumed to be a contiguous chain. +func newInsertIterator(chain types.Blocks, results <-chan error, validator Validator) *insertIterator { + return &insertIterator{ + chain: chain, + results: results, + errors: make([]error, 0, len(chain)), + index: -1, + validator: validator, + } +} + +// next returns the next block in the iterator, along with any potential validation +// error for that block. When the end is reached, it will return (nil, nil). +func (it *insertIterator) next() (*types.Block, error) { + // If we reached the end of the chain, abort + if it.index+1 >= len(it.chain) { + it.index = len(it.chain) + return nil, nil + } + // Advance the iterator and wait for verification result if not yet done + it.index++ + if len(it.errors) <= it.index { + it.errors = append(it.errors, <-it.results) + } + if it.errors[it.index] != nil { + return it.chain[it.index], it.errors[it.index] + } + // Block header valid, run body validation and return + return it.chain[it.index], it.validator.ValidateBody(it.chain[it.index]) +} + +// peek returns the next block in the iterator, along with any potential validation +// error for that block, but does **not** advance the iterator. +// +// Both header and body validation errors (nil too) is cached into the iterator +// to avoid duplicating work on the following next() call. +func (it *insertIterator) peek() (*types.Block, error) { + // If we reached the end of the chain, abort + if it.index+1 >= len(it.chain) { + return nil, nil + } + // Wait for verification result if not yet done + if len(it.errors) <= it.index+1 { + it.errors = append(it.errors, <-it.results) + } + if it.errors[it.index+1] != nil { + return it.chain[it.index+1], it.errors[it.index+1] + } + // Block header valid, ignore body validation since we don't have a parent anyway + return it.chain[it.index+1], nil +} + +// previous returns the previous header that was being processed, or nil. +func (it *insertIterator) previous() *types.Header { + if it.index < 1 { + return nil + } + return it.chain[it.index-1].Header() +} + +// first returns the first block in the it. +func (it *insertIterator) first() *types.Block { + return it.chain[0] +} + +// remaining returns the number of remaining blocks. +func (it *insertIterator) remaining() int { + return len(it.chain) - it.index +} + +// processed returns the number of processed blocks. +func (it *insertIterator) processed() int { + return it.index + 1 +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/chain_makers.go b/vendor/github.com/ethereum/go-ethereum/core/chain_makers.go new file mode 100644 index 00000000..17f40421 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/chain_makers.go @@ -0,0 +1,299 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +// BlockGen creates blocks for testing. +// See GenerateChain for a detailed explanation. +type BlockGen struct { + i int + parent *types.Block + chain []*types.Block + header *types.Header + statedb *state.StateDB + + gasPool *GasPool + txs []*types.Transaction + receipts []*types.Receipt + uncles []*types.Header + + config *params.ChainConfig + engine consensus.Engine +} + +// SetCoinbase sets the coinbase of the generated block. +// It can be called at most once. +func (b *BlockGen) SetCoinbase(addr common.Address) { + if b.gasPool != nil { + if len(b.txs) > 0 { + panic("coinbase must be set before adding transactions") + } + panic("coinbase can only be set once") + } + b.header.Coinbase = addr + b.gasPool = new(GasPool).AddGas(b.header.GasLimit) +} + +// SetExtra sets the extra data field of the generated block. +func (b *BlockGen) SetExtra(data []byte) { + b.header.Extra = data +} + +// SetNonce sets the nonce field of the generated block. +func (b *BlockGen) SetNonce(nonce types.BlockNonce) { + b.header.Nonce = nonce +} + +// SetDifficulty sets the difficulty field of the generated block. This method is +// useful for Clique tests where the difficulty does not depend on time. For the +// ethash tests, please use OffsetTime, which implicitly recalculates the diff. +func (b *BlockGen) SetDifficulty(diff *big.Int) { + b.header.Difficulty = diff +} + +// AddTx adds a transaction to the generated block. If no coinbase has +// been set, the block's coinbase is set to the zero address. +// +// AddTx panics if the transaction cannot be executed. In addition to +// the protocol-imposed limitations (gas limit, etc.), there are some +// further limitations on the content of transactions that can be +// added. Notably, contract code relying on the BLOCKHASH instruction +// will panic during execution. +func (b *BlockGen) AddTx(tx *types.Transaction) { + b.AddTxWithChain(nil, tx) +} + +// AddTxWithChain adds a transaction to the generated block. If no coinbase has +// been set, the block's coinbase is set to the zero address. +// +// AddTxWithChain panics if the transaction cannot be executed. In addition to +// the protocol-imposed limitations (gas limit, etc.), there are some +// further limitations on the content of transactions that can be +// added. If contract code relies on the BLOCKHASH instruction, +// the block in chain will be returned. +func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { + if b.gasPool == nil { + b.SetCoinbase(common.Address{}) + } + b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) + receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}) + if err != nil { + panic(err) + } + b.txs = append(b.txs, tx) + b.receipts = append(b.receipts, receipt) +} + +// AddUncheckedTx forcefully adds a transaction to the block without any +// validation. +// +// AddUncheckedTx will cause consensus failures when used during real +// chain processing. This is best used in conjunction with raw block insertion. +func (b *BlockGen) AddUncheckedTx(tx *types.Transaction) { + b.txs = append(b.txs, tx) +} + +// Number returns the block number of the block being generated. +func (b *BlockGen) Number() *big.Int { + return new(big.Int).Set(b.header.Number) +} + +// AddUncheckedReceipt forcefully adds a receipts to the block without a +// backing transaction. +// +// AddUncheckedReceipt will cause consensus failures when used during real +// chain processing. This is best used in conjunction with raw block insertion. +func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { + b.receipts = append(b.receipts, receipt) +} + +// TxNonce returns the next valid transaction nonce for the +// account at addr. It panics if the account does not exist. +func (b *BlockGen) TxNonce(addr common.Address) uint64 { + if !b.statedb.Exist(addr) { + panic("account does not exist") + } + return b.statedb.GetNonce(addr) +} + +// AddUncle adds an uncle header to the generated block. +func (b *BlockGen) AddUncle(h *types.Header) { + b.uncles = append(b.uncles, h) +} + +// PrevBlock returns a previously generated block by number. It panics if +// num is greater or equal to the number of the block being generated. +// For index -1, PrevBlock returns the parent block given to GenerateChain. +func (b *BlockGen) PrevBlock(index int) *types.Block { + if index >= b.i { + panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i)) + } + if index == -1 { + return b.parent + } + return b.chain[index] +} + +// OffsetTime modifies the time instance of a block, implicitly changing its +// associated difficulty. It's useful to test scenarios where forking is not +// tied to chain length directly. +func (b *BlockGen) OffsetTime(seconds int64) { + b.header.Time += uint64(seconds) + if b.header.Time <= b.parent.Header().Time { + panic("block time out of range") + } + chainreader := &fakeChainReader{config: b.config} + b.header.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, b.parent.Header()) +} + +// GenerateChain creates a chain of n blocks. The first block's +// parent will be the provided parent. db is used to store +// intermediate states and should contain the parent's state trie. +// +// The generator function is called with a new block generator for +// every block. Any transactions and uncles added to the generator +// become part of the block. If gen is nil, the blocks will be empty +// and their coinbase will be the zero address. +// +// Blocks created by GenerateChain do not contain valid proof of work +// values. Inserting them into BlockChain requires use of FakePow or +// a similar non-validating proof of work implementation. +func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { + if config == nil { + config = params.TestChainConfig + } + blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) + chainreader := &fakeChainReader{config: config} + genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) { + b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine} + b.header = makeHeader(chainreader, parent, statedb, b.engine) + + // Mutate the state and block according to any hard-fork specs + if daoBlock := config.DAOForkBlock; daoBlock != nil { + limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) + if b.header.Number.Cmp(daoBlock) >= 0 && b.header.Number.Cmp(limit) < 0 { + if config.DAOForkSupport { + b.header.Extra = common.CopyBytes(params.DAOForkBlockExtra) + } + } + } + if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { + misc.ApplyDAOHardFork(statedb) + } + // Execute any user modifications to the block + if gen != nil { + gen(i, b) + } + if b.engine != nil { + // Finalize and seal the block + block, _ := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts) + + // Write state changes to db + root, err := statedb.Commit(config.IsEIP158(b.header.Number)) + if err != nil { + panic(fmt.Sprintf("state write error: %v", err)) + } + if err := statedb.Database().TrieDB().Commit(root, false); err != nil { + panic(fmt.Sprintf("trie write error: %v", err)) + } + return block, b.receipts + } + return nil, nil + } + for i := 0; i < n; i++ { + statedb, err := state.New(parent.Root(), state.NewDatabase(db)) + if err != nil { + panic(err) + } + block, receipt := genblock(i, parent, statedb) + blocks[i] = block + receipts[i] = receipt + parent = block + } + return blocks, receipts +} + +func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { + var time uint64 + if parent.Time() == 0 { + time = 10 + } else { + time = parent.Time() + 10 // block time is fixed at 10 seconds + } + + return &types.Header{ + Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), + ParentHash: parent.Hash(), + Coinbase: parent.Coinbase(), + Difficulty: engine.CalcDifficulty(chain, time, &types.Header{ + Number: parent.Number(), + Time: time - 10, + Difficulty: parent.Difficulty(), + UncleHash: parent.UncleHash(), + }), + GasLimit: CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()), + Number: new(big.Int).Add(parent.Number(), common.Big1), + Time: time, + } +} + +// makeHeaderChain creates a deterministic chain of headers rooted at parent. +func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header { + blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed) + headers := make([]*types.Header, len(blocks)) + for i, block := range blocks { + headers[i] = block.Header() + } + return headers +} + +// makeBlockChain creates a deterministic chain of blocks rooted at parent. +func makeBlockChain(parent *types.Block, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Block { + blocks, _ := GenerateChain(params.TestChainConfig, parent, engine, db, n, func(i int, b *BlockGen) { + b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) + }) + return blocks +} + +type fakeChainReader struct { + config *params.ChainConfig + genesis *types.Block +} + +// Config returns the chain configuration. +func (cr *fakeChainReader) Config() *params.ChainConfig { + return cr.config +} + +func (cr *fakeChainReader) CurrentHeader() *types.Header { return nil } +func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil } +func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil } +func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { return nil } +func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } diff --git a/vendor/github.com/ethereum/go-ethereum/core/error.go b/vendor/github.com/ethereum/go-ethereum/core/error.go new file mode 100644 index 00000000..cd4be3d7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/error.go @@ -0,0 +1,38 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import "errors" + +var ( + // ErrKnownBlock is returned when a block to import is already known locally. + ErrKnownBlock = errors.New("block already known") + + // ErrGasLimitReached is returned by the gas pool if the amount of gas required + // by a transaction is higher than what's left in the block. + ErrGasLimitReached = errors.New("gas limit reached") + + // ErrBlacklistedHash is returned if a block to import is on the blacklist. + ErrBlacklistedHash = errors.New("blacklisted hash") + + // ErrNonceTooHigh is returned if the nonce of a transaction is higher than the + // next one expected based on the local chain. + ErrNonceTooHigh = errors.New("nonce too high") + + // ErrNoGenesis is returned when there is no Genesis Block. + ErrNoGenesis = errors.New("genesis not found in chain") +) diff --git a/vendor/github.com/ethereum/go-ethereum/core/evm.go b/vendor/github.com/ethereum/go-ethereum/core/evm.go new file mode 100644 index 00000000..b654bbd4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/evm.go @@ -0,0 +1,97 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" +) + +// ChainContext supports retrieving headers and consensus parameters from the +// current blockchain to be used during transaction processing. +type ChainContext interface { + // Engine retrieves the chain's consensus engine. + Engine() consensus.Engine + + // GetHeader returns the hash corresponding to their hash. + GetHeader(common.Hash, uint64) *types.Header +} + +// NewEVMContext creates a new context for use in the EVM. +func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context { + // If we don't have an explicit author (i.e. not mining), extract from the header + var beneficiary common.Address + if author == nil { + beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation + } else { + beneficiary = *author + } + return vm.Context{ + CanTransfer: CanTransfer, + Transfer: Transfer, + GetHash: GetHashFn(header, chain), + Origin: msg.From(), + Coinbase: beneficiary, + BlockNumber: new(big.Int).Set(header.Number), + Time: new(big.Int).SetUint64(header.Time), + Difficulty: new(big.Int).Set(header.Difficulty), + GasLimit: header.GasLimit, + GasPrice: new(big.Int).Set(msg.GasPrice()), + } +} + +// GetHashFn returns a GetHashFunc which retrieves header hashes by number +func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash { + var cache map[uint64]common.Hash + + return func(n uint64) common.Hash { + // If there's no hash cache yet, make one + if cache == nil { + cache = map[uint64]common.Hash{ + ref.Number.Uint64() - 1: ref.ParentHash, + } + } + // Try to fulfill the request from the cache + if hash, ok := cache[n]; ok { + return hash + } + // Not cached, iterate the blocks and cache the hashes + for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) { + cache[header.Number.Uint64()-1] = header.ParentHash + if n == header.Number.Uint64()-1 { + return header.ParentHash + } + } + return common.Hash{} + } +} + +// CanTransfer checks whether there are enough funds in the address' account to make a transfer. +// This does not take the necessary gas in to account to make the transfer valid. +func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { + return db.GetBalance(addr).Cmp(amount) >= 0 +} + +// Transfer subtracts amount from sender and adds amount to recipient using the given Db +func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) { + db.SubBalance(sender, amount) + db.AddBalance(recipient, amount) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/genesis.go b/vendor/github.com/ethereum/go-ethereum/core/genesis.go new file mode 100644 index 00000000..830fb033 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/genesis.go @@ -0,0 +1,408 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go +//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go + +var errGenesisNoConfig = errors.New("genesis has no chain configuration") + +// Genesis specifies the header fields, state of a genesis block. It also defines hard +// fork switch-over blocks through the chain configuration. +type Genesis struct { + Config *params.ChainConfig `json:"config"` + Nonce uint64 `json:"nonce"` + Timestamp uint64 `json:"timestamp"` + ExtraData []byte `json:"extraData"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` + Alloc GenesisAlloc `json:"alloc" gencodec:"required"` + + // These fields are used for consensus tests. Please don't use them + // in actual genesis blocks. + Number uint64 `json:"number"` + GasUsed uint64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` +} + +// GenesisAlloc specifies the initial state that is part of the genesis block. +type GenesisAlloc map[common.Address]GenesisAccount + +func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { + m := make(map[common.UnprefixedAddress]GenesisAccount) + if err := json.Unmarshal(data, &m); err != nil { + return err + } + *ga = make(GenesisAlloc) + for addr, a := range m { + (*ga)[common.Address(addr)] = a + } + return nil +} + +// GenesisAccount is an account in the state of the genesis block. +type GenesisAccount struct { + Code []byte `json:"code,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *big.Int `json:"balance" gencodec:"required"` + Nonce uint64 `json:"nonce,omitempty"` + PrivateKey []byte `json:"secretKey,omitempty"` // for tests +} + +// field type overrides for gencodec +type genesisSpecMarshaling struct { + Nonce math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 + ExtraData hexutil.Bytes + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Number math.HexOrDecimal64 + Difficulty *math.HexOrDecimal256 + Alloc map[common.UnprefixedAddress]GenesisAccount +} + +type genesisAccountMarshaling struct { + Code hexutil.Bytes + Balance *math.HexOrDecimal256 + Nonce math.HexOrDecimal64 + Storage map[storageJSON]storageJSON + PrivateKey hexutil.Bytes +} + +// storageJSON represents a 256 bit byte array, but allows less than 256 bits when +// unmarshaling from hex. +type storageJSON common.Hash + +func (h *storageJSON) UnmarshalText(text []byte) error { + text = bytes.TrimPrefix(text, []byte("0x")) + if len(text) > 64 { + return fmt.Errorf("too many hex characters in storage key/value %q", text) + } + offset := len(h) - len(text)/2 // pad on the left + if _, err := hex.Decode(h[offset:], text); err != nil { + fmt.Println(err) + return fmt.Errorf("invalid hex storage key/value %q", text) + } + return nil +} + +func (h storageJSON) MarshalText() ([]byte, error) { + return hexutil.Bytes(h[:]).MarshalText() +} + +// GenesisMismatchError is raised when trying to overwrite an existing +// genesis block with an incompatible one. +type GenesisMismatchError struct { + Stored, New common.Hash +} + +func (e *GenesisMismatchError) Error() string { + return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) +} + +// SetupGenesisBlock writes or updates the genesis block in db. +// The block that will be used is: +// +// genesis == nil genesis != nil +// +------------------------------------------ +// db has no genesis | main-net default | genesis +// db has genesis | from DB | genesis (if compatible) +// +// The stored chain configuration will be updated if it is compatible (i.e. does not +// specify a fork block below the local head block). In case of a conflict, the +// error is a *params.ConfigCompatError and the new, unwritten config is returned. +// +// The returned chain configuration is never nil. +func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { + return SetupGenesisBlockWithOverride(db, genesis, nil) +} +func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, constantinopleOverride *big.Int) (*params.ChainConfig, common.Hash, error) { + if genesis != nil && genesis.Config == nil { + return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig + } + // Just commit the new block if there is no stored genesis block. + stored := rawdb.ReadCanonicalHash(db, 0) + if (stored == common.Hash{}) { + if genesis == nil { + log.Info("Writing default main-net genesis block") + genesis = DefaultGenesisBlock() + } else { + log.Info("Writing custom genesis block") + } + block, err := genesis.Commit(db) + return genesis.Config, block.Hash(), err + } + + // We have the genesis block in database(perhaps in ancient database) + // but the corresponding state is missing. + header := rawdb.ReadHeader(db, stored, 0) + if _, err := state.New(header.Root, state.NewDatabaseWithCache(db, 0)); err != nil { + if genesis == nil { + genesis = DefaultGenesisBlock() + } + // Ensure the stored genesis matches with the given one. + hash := genesis.ToBlock(nil).Hash() + if hash != stored { + return genesis.Config, hash, &GenesisMismatchError{stored, hash} + } + block, err := genesis.Commit(db) + return genesis.Config, block.Hash(), err + } + + // Check whether the genesis block is already written. + if genesis != nil { + hash := genesis.ToBlock(nil).Hash() + if hash != stored { + return genesis.Config, hash, &GenesisMismatchError{stored, hash} + } + } + + // Get the existing chain configuration. + newcfg := genesis.configOrDefault(stored) + if constantinopleOverride != nil { + newcfg.ConstantinopleBlock = constantinopleOverride + newcfg.PetersburgBlock = constantinopleOverride + } + storedcfg := rawdb.ReadChainConfig(db, stored) + if storedcfg == nil { + log.Warn("Found genesis block without chain config") + rawdb.WriteChainConfig(db, stored, newcfg) + return newcfg, stored, nil + } + // Special case: don't change the existing config of a non-mainnet chain if no new + // config is supplied. These chains would get AllProtocolChanges (and a compat error) + // if we just continued here. + if genesis == nil && stored != params.MainnetGenesisHash { + return storedcfg, stored, nil + } + + // Check config compatibility and write the config. Compatibility errors + // are returned to the caller unless we're already at block zero. + height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) + if height == nil { + return newcfg, stored, fmt.Errorf("missing block number for head header hash") + } + compatErr := storedcfg.CheckCompatible(newcfg, *height) + if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { + return newcfg, stored, compatErr + } + rawdb.WriteChainConfig(db, stored, newcfg) + return newcfg, stored, nil +} + +func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { + switch { + case g != nil: + return g.Config + case ghash == params.MainnetGenesisHash: + return params.MainnetChainConfig + case ghash == params.TestnetGenesisHash: + return params.TestnetChainConfig + default: + return params.AllEthashProtocolChanges + } +} + +// ToBlock creates the genesis block and writes state of a genesis specification +// to the given database (or discards it if nil). +func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { + if db == nil { + db = rawdb.NewMemoryDatabase() + } + statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + for addr, account := range g.Alloc { + statedb.AddBalance(addr, account.Balance) + statedb.SetCode(addr, account.Code) + statedb.SetNonce(addr, account.Nonce) + for key, value := range account.Storage { + statedb.SetState(addr, key, value) + } + } + root := statedb.IntermediateRoot(false) + head := &types.Header{ + Number: new(big.Int).SetUint64(g.Number), + Nonce: types.EncodeNonce(g.Nonce), + Time: g.Timestamp, + ParentHash: g.ParentHash, + Extra: g.ExtraData, + GasLimit: g.GasLimit, + GasUsed: g.GasUsed, + Difficulty: g.Difficulty, + MixDigest: g.Mixhash, + Coinbase: g.Coinbase, + Root: root, + } + if g.GasLimit == 0 { + head.GasLimit = params.GenesisGasLimit + } + if g.Difficulty == nil { + head.Difficulty = params.GenesisDifficulty + } + statedb.Commit(false) + statedb.Database().TrieDB().Commit(root, true) + + return types.NewBlock(head, nil, nil, nil) +} + +// Commit writes the block and state of a genesis specification to the database. +// The block is committed as the canonical head block. +func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { + block := g.ToBlock(db) + if block.Number().Sign() != 0 { + return nil, fmt.Errorf("can't commit genesis block with number > 0") + } + rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty) + rawdb.WriteBlock(db, block) + rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) + rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(db, block.Hash()) + rawdb.WriteHeadFastBlockHash(db, block.Hash()) + rawdb.WriteHeadHeaderHash(db, block.Hash()) + + config := g.Config + if config == nil { + config = params.AllEthashProtocolChanges + } + rawdb.WriteChainConfig(db, block.Hash(), config) + return block, nil +} + +// MustCommit writes the genesis block and state to db, panicking on error. +// The block is committed as the canonical head block. +func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { + block, err := g.Commit(db) + if err != nil { + panic(err) + } + return block +} + +// GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. +func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { + g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}} + return g.MustCommit(db) +} + +// DefaultGenesisBlock returns the Ethereum main net genesis block. +func DefaultGenesisBlock() *Genesis { + return &Genesis{ + Config: params.MainnetChainConfig, + Nonce: 66, + ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), + GasLimit: 5000, + Difficulty: big.NewInt(17179869184), + Alloc: decodePrealloc(mainnetAllocData), + } +} + +// DefaultTestnetGenesisBlock returns the Ropsten network genesis block. +func DefaultTestnetGenesisBlock() *Genesis { + return &Genesis{ + Config: params.TestnetChainConfig, + Nonce: 66, + ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), + GasLimit: 16777216, + Difficulty: big.NewInt(1048576), + Alloc: decodePrealloc(testnetAllocData), + } +} + +// DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. +func DefaultRinkebyGenesisBlock() *Genesis { + return &Genesis{ + Config: params.RinkebyChainConfig, + Timestamp: 1492009146, + ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + GasLimit: 4700000, + Difficulty: big.NewInt(1), + Alloc: decodePrealloc(rinkebyAllocData), + } +} + +// DefaultGoerliGenesisBlock returns the Görli network genesis block. +func DefaultGoerliGenesisBlock() *Genesis { + return &Genesis{ + Config: params.GoerliChainConfig, + Timestamp: 1548854791, + ExtraData: hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + GasLimit: 10485760, + Difficulty: big.NewInt(1), + Alloc: decodePrealloc(goerliAllocData), + } +} + +// DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must +// be seeded with the +func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { + // Override the default period to the user requested one + config := *params.AllCliqueProtocolChanges + config.Clique.Period = period + + // Assemble and return the genesis with the precompiles and faucet pre-funded + return &Genesis{ + Config: &config, + ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), + GasLimit: 6283185, + Difficulty: big.NewInt(1), + Alloc: map[common.Address]GenesisAccount{ + common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover + common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 + common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD + common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity + common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp + common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd + common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul + common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing + faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, + }, + } +} + +func decodePrealloc(data string) GenesisAlloc { + var p []struct{ Addr, Balance *big.Int } + if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { + panic(err) + } + ga := make(GenesisAlloc, len(p)) + for _, account := range p { + ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} + } + return ga +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/headerchain.go b/vendor/github.com/ethereum/go-ethereum/core/headerchain.go new file mode 100644 index 00000000..034858f6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/headerchain.go @@ -0,0 +1,538 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + crand "crypto/rand" + "errors" + "fmt" + "math" + "math/big" + mrand "math/rand" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + lru "github.com/hashicorp/golang-lru" +) + +const ( + headerCacheLimit = 512 + tdCacheLimit = 1024 + numberCacheLimit = 2048 +) + +// HeaderChain implements the basic block header chain logic that is shared by +// core.BlockChain and light.LightChain. It is not usable in itself, only as +// a part of either structure. +// It is not thread safe either, the encapsulating chain structures should do +// the necessary mutex locking/unlocking. +type HeaderChain struct { + config *params.ChainConfig + + chainDb ethdb.Database + genesisHeader *types.Header + + currentHeader atomic.Value // Current head of the header chain (may be above the block chain!) + currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time) + + headerCache *lru.Cache // Cache for the most recent block headers + tdCache *lru.Cache // Cache for the most recent block total difficulties + numberCache *lru.Cache // Cache for the most recent block numbers + + procInterrupt func() bool + + rand *mrand.Rand + engine consensus.Engine +} + +// NewHeaderChain creates a new HeaderChain structure. +// getValidator should return the parent's validator +// procInterrupt points to the parent's interrupt semaphore +// wg points to the parent's shutdown wait group +func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) { + headerCache, _ := lru.New(headerCacheLimit) + tdCache, _ := lru.New(tdCacheLimit) + numberCache, _ := lru.New(numberCacheLimit) + + // Seed a fast but crypto originating random generator + seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64)) + if err != nil { + return nil, err + } + + hc := &HeaderChain{ + config: config, + chainDb: chainDb, + headerCache: headerCache, + tdCache: tdCache, + numberCache: numberCache, + procInterrupt: procInterrupt, + rand: mrand.New(mrand.NewSource(seed.Int64())), + engine: engine, + } + + hc.genesisHeader = hc.GetHeaderByNumber(0) + if hc.genesisHeader == nil { + return nil, ErrNoGenesis + } + + hc.currentHeader.Store(hc.genesisHeader) + if head := rawdb.ReadHeadBlockHash(chainDb); head != (common.Hash{}) { + if chead := hc.GetHeaderByHash(head); chead != nil { + hc.currentHeader.Store(chead) + } + } + hc.currentHeaderHash = hc.CurrentHeader().Hash() + headHeaderGauge.Update(hc.CurrentHeader().Number.Int64()) + + return hc, nil +} + +// GetBlockNumber retrieves the block number belonging to the given hash +// from the cache or database +func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { + if cached, ok := hc.numberCache.Get(hash); ok { + number := cached.(uint64) + return &number + } + number := rawdb.ReadHeaderNumber(hc.chainDb, hash) + if number != nil { + hc.numberCache.Add(hash, *number) + } + return number +} + +// WriteHeader writes a header into the local chain, given that its parent is +// already known. If the total difficulty of the newly inserted header becomes +// greater than the current known TD, the canonical chain is re-routed. +// +// Note: This method is not concurrent-safe with inserting blocks simultaneously +// into the chain, as side effects caused by reorganisations cannot be emulated +// without the real blocks. Hence, writing headers directly should only be done +// in two scenarios: pure-header mode of operation (light clients), or properly +// separated header/block phases (non-archive clients). +func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, err error) { + // Cache some values to prevent constant recalculation + var ( + hash = header.Hash() + number = header.Number.Uint64() + ) + // Calculate the total difficulty of the header + ptd := hc.GetTd(header.ParentHash, number-1) + if ptd == nil { + return NonStatTy, consensus.ErrUnknownAncestor + } + localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64()) + externTd := new(big.Int).Add(header.Difficulty, ptd) + + // Irrelevant of the canonical status, write the td and header to the database + if err := hc.WriteTd(hash, number, externTd); err != nil { + log.Crit("Failed to write header total difficulty", "err", err) + } + rawdb.WriteHeader(hc.chainDb, header) + + // If the total difficulty is higher than our known, add it to the canonical chain + // Second clause in the if statement reduces the vulnerability to selfish mining. + // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf + if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { + // Delete any canonical number assignments above the new head + batch := hc.chainDb.NewBatch() + for i := number + 1; ; i++ { + hash := rawdb.ReadCanonicalHash(hc.chainDb, i) + if hash == (common.Hash{}) { + break + } + rawdb.DeleteCanonicalHash(batch, i) + } + batch.Write() + + // Overwrite any stale canonical number assignments + var ( + headHash = header.ParentHash + headNumber = header.Number.Uint64() - 1 + headHeader = hc.GetHeader(headHash, headNumber) + ) + for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash { + rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber) + + headHash = headHeader.ParentHash + headNumber = headHeader.Number.Uint64() - 1 + headHeader = hc.GetHeader(headHash, headNumber) + } + // Extend the canonical chain with the new header + rawdb.WriteCanonicalHash(hc.chainDb, hash, number) + rawdb.WriteHeadHeaderHash(hc.chainDb, hash) + + hc.currentHeaderHash = hash + hc.currentHeader.Store(types.CopyHeader(header)) + headHeaderGauge.Update(header.Number.Int64()) + + status = CanonStatTy + } else { + status = SideStatTy + } + hc.headerCache.Add(hash, header) + hc.numberCache.Add(hash, number) + + return +} + +// WhCallback is a callback function for inserting individual headers. +// A callback is used for two reasons: first, in a LightChain, status should be +// processed and light chain events sent, while in a BlockChain this is not +// necessary since chain events are sent after inserting blocks. Second, the +// header writes should be protected by the parent chain mutex individually. +type WhCallback func(*types.Header) error + +func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + // Do a sanity check that the provided chain is actually ordered and linked + for i := 1; i < len(chain); i++ { + if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 || chain[i].ParentHash != chain[i-1].Hash() { + // Chain broke ancestry, log a message (programming error) and skip insertion + log.Error("Non contiguous header insert", "number", chain[i].Number, "hash", chain[i].Hash(), + "parent", chain[i].ParentHash, "prevnumber", chain[i-1].Number, "prevhash", chain[i-1].Hash()) + + return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].Number, + chain[i-1].Hash().Bytes()[:4], i, chain[i].Number, chain[i].Hash().Bytes()[:4], chain[i].ParentHash[:4]) + } + } + + // Generate the list of seal verification requests, and start the parallel verifier + seals := make([]bool, len(chain)) + if checkFreq != 0 { + // In case of checkFreq == 0 all seals are left false. + for i := 0; i < len(seals)/checkFreq; i++ { + index := i*checkFreq + hc.rand.Intn(checkFreq) + if index >= len(seals) { + index = len(seals) - 1 + } + seals[index] = true + } + // Last should always be verified to avoid junk. + seals[len(seals)-1] = true + } + + abort, results := hc.engine.VerifyHeaders(hc, chain, seals) + defer close(abort) + + // Iterate over the headers and ensure they all check out + for i, header := range chain { + // If the chain is terminating, stop processing blocks + if hc.procInterrupt() { + log.Debug("Premature abort during headers verification") + return 0, errors.New("aborted") + } + // If the header is a banned one, straight out abort + if BadHashes[header.Hash()] { + return i, ErrBlacklistedHash + } + // Otherwise wait for headers checks and ensure they pass + if err := <-results; err != nil { + return i, err + } + } + + return 0, nil +} + +// InsertHeaderChain attempts to insert the given header chain in to the local +// chain, possibly creating a reorg. If an error is returned, it will return the +// index number of the failing header as well an error describing what went wrong. +// +// The verify parameter can be used to fine tune whether nonce verification +// should be done or not. The reason behind the optional check is because some +// of the header retrieval mechanisms already need to verfy nonces, as well as +// because nonces can be verified sparsely, not needing to check each. +func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCallback, start time.Time) (int, error) { + // Collect some import statistics to report on + stats := struct{ processed, ignored int }{} + // All headers passed verification, import them into the database + for i, header := range chain { + // Short circuit insertion if shutting down + if hc.procInterrupt() { + log.Debug("Premature abort during headers import") + return i, errors.New("aborted") + } + // If the header's already known, skip it, otherwise store + hash := header.Hash() + if hc.HasHeader(hash, header.Number.Uint64()) { + externTd := hc.GetTd(hash, header.Number.Uint64()) + localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64()) + if externTd == nil || externTd.Cmp(localTd) <= 0 { + stats.ignored++ + continue + } + } + if err := writeHeader(header); err != nil { + return i, err + } + stats.processed++ + } + // Report some public statistics so the user has a clue what's going on + last := chain[len(chain)-1] + + context := []interface{}{ + "count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)), + "number", last.Number, "hash", last.Hash(), + } + if timestamp := time.Unix(int64(last.Time), 0); time.Since(timestamp) > time.Minute { + context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) + } + if stats.ignored > 0 { + context = append(context, []interface{}{"ignored", stats.ignored}...) + } + log.Info("Imported new block headers", context...) + + return 0, nil +} + +// GetBlockHashesFromHash retrieves a number of block hashes starting at a given +// hash, fetching towards the genesis block. +func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { + // Get the origin header from which to fetch + header := hc.GetHeaderByHash(hash) + if header == nil { + return nil + } + // Iterate the headers until enough is collected or the genesis reached + chain := make([]common.Hash, 0, max) + for i := uint64(0); i < max; i++ { + next := header.ParentHash + if header = hc.GetHeader(next, header.Number.Uint64()-1); header == nil { + break + } + chain = append(chain, next) + if header.Number.Sign() == 0 { + break + } + } + return chain +} + +// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or +// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the +// number of blocks to be individually checked before we reach the canonical chain. +// +// Note: ancestor == 0 returns the same block, 1 returns its parent and so on. +func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { + if ancestor > number { + return common.Hash{}, 0 + } + if ancestor == 1 { + // in this case it is cheaper to just read the header + if header := hc.GetHeader(hash, number); header != nil { + return header.ParentHash, number - 1 + } else { + return common.Hash{}, 0 + } + } + for ancestor != 0 { + if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash { + number -= ancestor + return rawdb.ReadCanonicalHash(hc.chainDb, number), number + } + if *maxNonCanonical == 0 { + return common.Hash{}, 0 + } + *maxNonCanonical-- + ancestor-- + header := hc.GetHeader(hash, number) + if header == nil { + return common.Hash{}, 0 + } + hash = header.ParentHash + number-- + } + return hash, number +} + +// GetTd retrieves a block's total difficulty in the canonical chain from the +// database by hash and number, caching it if found. +func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int { + // Short circuit if the td's already in the cache, retrieve otherwise + if cached, ok := hc.tdCache.Get(hash); ok { + return cached.(*big.Int) + } + td := rawdb.ReadTd(hc.chainDb, hash, number) + if td == nil { + return nil + } + // Cache the found body for next time and return + hc.tdCache.Add(hash, td) + return td +} + +// GetTdByHash retrieves a block's total difficulty in the canonical chain from the +// database by hash, caching it if found. +func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int { + number := hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return hc.GetTd(hash, *number) +} + +// WriteTd stores a block's total difficulty into the database, also caching it +// along the way. +func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) error { + rawdb.WriteTd(hc.chainDb, hash, number, td) + hc.tdCache.Add(hash, new(big.Int).Set(td)) + return nil +} + +// GetHeader retrieves a block header from the database by hash and number, +// caching it if found. +func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header { + // Short circuit if the header's already in the cache, retrieve otherwise + if header, ok := hc.headerCache.Get(hash); ok { + return header.(*types.Header) + } + header := rawdb.ReadHeader(hc.chainDb, hash, number) + if header == nil { + return nil + } + // Cache the found header for next time and return + hc.headerCache.Add(hash, header) + return header +} + +// GetHeaderByHash retrieves a block header from the database by hash, caching it if +// found. +func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { + number := hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return hc.GetHeader(hash, *number) +} + +// HasHeader checks if a block header is present in the database or not. +func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool { + if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) { + return true + } + return rawdb.HasHeader(hc.chainDb, hash, number) +} + +// GetHeaderByNumber retrieves a block header from the database by number, +// caching it (associated with its hash) if found. +func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { + hash := rawdb.ReadCanonicalHash(hc.chainDb, number) + if hash == (common.Hash{}) { + return nil + } + return hc.GetHeader(hash, number) +} + +// CurrentHeader retrieves the current head header of the canonical chain. The +// header is retrieved from the HeaderChain's internal cache. +func (hc *HeaderChain) CurrentHeader() *types.Header { + return hc.currentHeader.Load().(*types.Header) +} + +// SetCurrentHeader sets the current head header of the canonical chain. +func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { + rawdb.WriteHeadHeaderHash(hc.chainDb, head.Hash()) + + hc.currentHeader.Store(head) + hc.currentHeaderHash = head.Hash() + headHeaderGauge.Update(head.Number.Int64()) +} + +type ( + // UpdateHeadBlocksCallback is a callback function that is called by SetHead + // before head header is updated. + UpdateHeadBlocksCallback func(ethdb.KeyValueWriter, *types.Header) + + // DeleteBlockContentCallback is a callback function that is called by SetHead + // before each header is deleted. + DeleteBlockContentCallback func(ethdb.KeyValueWriter, common.Hash, uint64) +) + +// SetHead rewinds the local chain to a new head. Everything above the new head +// will be deleted and the new one set. +func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, delFn DeleteBlockContentCallback) { + var ( + parentHash common.Hash + batch = hc.chainDb.NewBatch() + ) + for hdr := hc.CurrentHeader(); hdr != nil && hdr.Number.Uint64() > head; hdr = hc.CurrentHeader() { + hash, num := hdr.Hash(), hdr.Number.Uint64() + + // Rewind block chain to new head. + parent := hc.GetHeader(hdr.ParentHash, num-1) + if parent == nil { + parent = hc.genesisHeader + } + parentHash = hdr.ParentHash + // Notably, since geth has the possibility for setting the head to a low + // height which is even lower than ancient head. + // In order to ensure that the head is always no higher than the data in + // the database(ancient store or active store), we need to update head + // first then remove the relative data from the database. + // + // Update head first(head fast block, head full block) before deleting the data. + if updateFn != nil { + updateFn(hc.chainDb, parent) + } + // Update head header then. + rawdb.WriteHeadHeaderHash(hc.chainDb, parentHash) + + // Remove the relative data from the database. + if delFn != nil { + delFn(batch, hash, num) + } + // Rewind header chain to new head. + rawdb.DeleteHeader(batch, hash, num) + rawdb.DeleteTd(batch, hash, num) + rawdb.DeleteCanonicalHash(batch, num) + + hc.currentHeader.Store(parent) + hc.currentHeaderHash = parentHash + headHeaderGauge.Update(parent.Number.Int64()) + } + batch.Write() + + // Clear out any stale content from the caches + hc.headerCache.Purge() + hc.tdCache.Purge() + hc.numberCache.Purge() +} + +// SetGenesis sets a new genesis block header for the chain +func (hc *HeaderChain) SetGenesis(head *types.Header) { + hc.genesisHeader = head +} + +// Config retrieves the header chain's chain configuration. +func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config } + +// Engine retrieves the header chain's consensus engine. +func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine } + +// GetBlock implements consensus.ChainReader, and returns nil for every input as +// a header chain does not have blocks available for retrieval. +func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block { + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_chain.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_chain.go new file mode 100644 index 00000000..fab7ca56 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_chain.go @@ -0,0 +1,560 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "bytes" + "encoding/binary" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// ReadCanonicalHash retrieves the hash assigned to a canonical block number. +func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { + data, _ := db.Ancient(freezerHashTable, number) + if len(data) == 0 { + data, _ = db.Get(headerHashKey(number)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerHashTable, number) + } + } + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteCanonicalHash stores the hash assigned to a canonical block number. +func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { + log.Crit("Failed to store number to hash mapping", "err", err) + } +} + +// DeleteCanonicalHash removes the number to hash canonical mapping. +func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { + if err := db.Delete(headerHashKey(number)); err != nil { + log.Crit("Failed to delete number to hash mapping", "err", err) + } +} + +// ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights, +// both canonical and reorged forks included. +func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash { + prefix := headerKeyPrefix(number) + + hashes := make([]common.Hash, 0, 1) + it := db.NewIteratorWithPrefix(prefix) + defer it.Release() + + for it.Next() { + if key := it.Key(); len(key) == len(prefix)+32 { + hashes = append(hashes, common.BytesToHash(key[len(key)-32:])) + } + } + return hashes +} + +// ReadHeaderNumber returns the header number assigned to a hash. +func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { + data, _ := db.Get(headerNumberKey(hash)) + if len(data) != 8 { + return nil + } + number := binary.BigEndian.Uint64(data) + return &number +} + +// WriteHeaderNumber stores the hash->number mapping. +func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + key := headerNumberKey(hash) + enc := encodeBlockNumber(number) + if err := db.Put(key, enc); err != nil { + log.Crit("Failed to store hash to number mapping", "err", err) + } +} + +// DeleteHeaderNumber removes hash->number mapping. +func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Delete(headerNumberKey(hash)); err != nil { + log.Crit("Failed to delete hash to number mapping", "err", err) + } +} + +// ReadHeadHeaderHash retrieves the hash of the current canonical head header. +func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { + data, _ := db.Get(headHeaderKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadHeaderHash stores the hash of the current canonical head header. +func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last header's hash", "err", err) + } +} + +// ReadHeadBlockHash retrieves the hash of the current canonical head block. +func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash { + data, _ := db.Get(headBlockKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadBlockHash stores the head block's hash. +func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(headBlockKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last block's hash", "err", err) + } +} + +// ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block. +func ReadHeadFastBlockHash(db ethdb.KeyValueReader) common.Hash { + data, _ := db.Get(headFastBlockKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadFastBlockHash stores the hash of the current fast-sync head block. +func WriteHeadFastBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last fast block's hash", "err", err) + } +} + +// ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow +// reporting correct numbers across restarts. +func ReadFastTrieProgress(db ethdb.KeyValueReader) uint64 { + data, _ := db.Get(fastTrieProgressKey) + if len(data) == 0 { + return 0 + } + return new(big.Int).SetBytes(data).Uint64() +} + +// WriteFastTrieProgress stores the fast sync trie process counter to support +// retrieving it across restarts. +func WriteFastTrieProgress(db ethdb.KeyValueWriter, count uint64) { + if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { + log.Crit("Failed to store fast sync trie progress", "err", err) + } +} + +// ReadHeaderRLP retrieves a block header in its raw RLP database encoding. +func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Ancient(freezerHeaderTable, number) + if len(data) == 0 { + data, _ = db.Get(headerKey(number, hash)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerHeaderTable, number) + } + } + return data +} + +// HasHeader verifies the existence of a block header corresponding to the hash. +func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { + if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { + return true + } + if has, err := db.Has(headerKey(number, hash)); !has || err != nil { + return false + } + return true +} + +// ReadHeader retrieves the block header corresponding to the hash. +func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { + data := ReadHeaderRLP(db, hash, number) + if len(data) == 0 { + return nil + } + header := new(types.Header) + if err := rlp.Decode(bytes.NewReader(data), header); err != nil { + log.Error("Invalid block header RLP", "hash", hash, "err", err) + return nil + } + return header +} + +// WriteHeader stores a block header into the database and also stores the hash- +// to-number mapping. +func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { + var ( + hash = header.Hash() + number = header.Number.Uint64() + ) + // Write the hash -> number mapping + WriteHeaderNumber(db, hash, number) + + // Write the encoded header + data, err := rlp.EncodeToBytes(header) + if err != nil { + log.Crit("Failed to RLP encode header", "err", err) + } + key := headerKey(number, hash) + if err := db.Put(key, data); err != nil { + log.Crit("Failed to store header", "err", err) + } +} + +// DeleteHeader removes all block header data associated with a hash. +func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + deleteHeaderWithoutNumber(db, hash, number) + if err := db.Delete(headerNumberKey(hash)); err != nil { + log.Crit("Failed to delete hash to number mapping", "err", err) + } +} + +// deleteHeaderWithoutNumber removes only the block header but does not remove +// the hash to number mapping. +func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(headerKey(number, hash)); err != nil { + log.Crit("Failed to delete header", "err", err) + } +} + +// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. +func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Ancient(freezerBodiesTable, number) + if len(data) == 0 { + data, _ = db.Get(blockBodyKey(number, hash)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerBodiesTable, number) + } + } + return data +} + +// WriteBodyRLP stores an RLP encoded block body into the database. +func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { + if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { + log.Crit("Failed to store block body", "err", err) + } +} + +// HasBody verifies the existence of a block body corresponding to the hash. +func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool { + if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { + return true + } + if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { + return false + } + return true +} + +// ReadBody retrieves the block body corresponding to the hash. +func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body { + data := ReadBodyRLP(db, hash, number) + if len(data) == 0 { + return nil + } + body := new(types.Body) + if err := rlp.Decode(bytes.NewReader(data), body); err != nil { + log.Error("Invalid block body RLP", "hash", hash, "err", err) + return nil + } + return body +} + +// WriteBody stores a block body into the database. +func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) { + data, err := rlp.EncodeToBytes(body) + if err != nil { + log.Crit("Failed to RLP encode body", "err", err) + } + WriteBodyRLP(db, hash, number, data) +} + +// DeleteBody removes all block body data associated with a hash. +func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(blockBodyKey(number, hash)); err != nil { + log.Crit("Failed to delete block body", "err", err) + } +} + +// ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding. +func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Ancient(freezerDifficultyTable, number) + if len(data) == 0 { + data, _ = db.Get(headerTDKey(number, hash)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerDifficultyTable, number) + } + } + return data +} + +// ReadTd retrieves a block's total difficulty corresponding to the hash. +func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int { + data := ReadTdRLP(db, hash, number) + if len(data) == 0 { + return nil + } + td := new(big.Int) + if err := rlp.Decode(bytes.NewReader(data), td); err != nil { + log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) + return nil + } + return td +} + +// WriteTd stores the total difficulty of a block into the database. +func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) { + data, err := rlp.EncodeToBytes(td) + if err != nil { + log.Crit("Failed to RLP encode block total difficulty", "err", err) + } + if err := db.Put(headerTDKey(number, hash), data); err != nil { + log.Crit("Failed to store block total difficulty", "err", err) + } +} + +// DeleteTd removes all block total difficulty data associated with a hash. +func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(headerTDKey(number, hash)); err != nil { + log.Crit("Failed to delete block total difficulty", "err", err) + } +} + +// HasReceipts verifies the existence of all the transaction receipts belonging +// to a block. +func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { + if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash { + return true + } + if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { + return false + } + return true +} + +// ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. +func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Ancient(freezerReceiptTable, number) + if len(data) == 0 { + data, _ = db.Get(blockReceiptsKey(number, hash)) + // In the background freezer is moving data from leveldb to flatten files. + // So during the first check for ancient db, the data is not yet in there, + // but when we reach into leveldb, the data was already moved. That would + // result in a not found error. + if len(data) == 0 { + data, _ = db.Ancient(freezerReceiptTable, number) + } + } + return data +} + +// ReadRawReceipts retrieves all the transaction receipts belonging to a block. +// The receipt metadata fields are not guaranteed to be populated, so they +// should not be used. Use ReadReceipts instead if the metadata is needed. +func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { + // Retrieve the flattened receipt slice + data := ReadReceiptsRLP(db, hash, number) + if len(data) == 0 { + return nil + } + // Convert the receipts from their storage form to their internal representation + storageReceipts := []*types.ReceiptForStorage{} + if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { + log.Error("Invalid receipt array RLP", "hash", hash, "err", err) + return nil + } + receipts := make(types.Receipts, len(storageReceipts)) + for i, storageReceipt := range storageReceipts { + receipts[i] = (*types.Receipt)(storageReceipt) + } + return receipts +} + +// ReadReceipts retrieves all the transaction receipts belonging to a block, including +// its correspoinding metadata fields. If it is unable to populate these metadata +// fields then nil is returned. +// +// The current implementation populates these metadata fields by reading the receipts' +// corresponding block body, so if the block body is not found it will return nil even +// if the receipt itself is stored. +func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts { + // We're deriving many fields from the block body, retrieve beside the receipt + receipts := ReadRawReceipts(db, hash, number) + if receipts == nil { + return nil + } + body := ReadBody(db, hash, number) + if body == nil { + log.Error("Missing body but have receipt", "hash", hash, "number", number) + return nil + } + if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil { + log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) + return nil + } + return receipts +} + +// WriteReceipts stores all the transaction receipts belonging to a block. +func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { + // Convert the receipts into their storage form and serialize them + storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) + for i, receipt := range receipts { + storageReceipts[i] = (*types.ReceiptForStorage)(receipt) + } + bytes, err := rlp.EncodeToBytes(storageReceipts) + if err != nil { + log.Crit("Failed to encode block receipts", "err", err) + } + // Store the flattened receipt slice + if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { + log.Crit("Failed to store block receipts", "err", err) + } +} + +// DeleteReceipts removes all receipt data associated with a block hash. +func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { + log.Crit("Failed to delete block receipts", "err", err) + } +} + +// ReadBlock retrieves an entire block corresponding to the hash, assembling it +// back from the stored header and body. If either the header or body could not +// be retrieved nil is returned. +// +// Note, due to concurrent download of header and block body the header and thus +// canonical hash can be stored in the database but the body data not (yet). +func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { + header := ReadHeader(db, hash, number) + if header == nil { + return nil + } + body := ReadBody(db, hash, number) + if body == nil { + return nil + } + return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) +} + +// WriteBlock serializes a block into the database, header and body separately. +func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { + WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) + WriteHeader(db, block.Header()) +} + +// WriteAncientBlock writes entire block data into ancient store and returns the total written size. +func WriteAncientBlock(db ethdb.AncientWriter, block *types.Block, receipts types.Receipts, td *big.Int) int { + // Encode all block components to RLP format. + headerBlob, err := rlp.EncodeToBytes(block.Header()) + if err != nil { + log.Crit("Failed to RLP encode block header", "err", err) + } + bodyBlob, err := rlp.EncodeToBytes(block.Body()) + if err != nil { + log.Crit("Failed to RLP encode body", "err", err) + } + storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) + for i, receipt := range receipts { + storageReceipts[i] = (*types.ReceiptForStorage)(receipt) + } + receiptBlob, err := rlp.EncodeToBytes(storageReceipts) + if err != nil { + log.Crit("Failed to RLP encode block receipts", "err", err) + } + tdBlob, err := rlp.EncodeToBytes(td) + if err != nil { + log.Crit("Failed to RLP encode block total difficulty", "err", err) + } + // Write all blob to flatten files. + err = db.AppendAncient(block.NumberU64(), block.Hash().Bytes(), headerBlob, bodyBlob, receiptBlob, tdBlob) + if err != nil { + log.Crit("Failed to write block data to ancient store", "err", err) + } + return len(headerBlob) + len(bodyBlob) + len(receiptBlob) + len(tdBlob) + common.HashLength +} + +// DeleteBlock removes all block data associated with a hash. +func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + DeleteReceipts(db, hash, number) + DeleteHeader(db, hash, number) + DeleteBody(db, hash, number) + DeleteTd(db, hash, number) +} + +// DeleteBlockWithoutNumber removes all block data associated with a hash, except +// the hash to number mapping. +func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + DeleteReceipts(db, hash, number) + deleteHeaderWithoutNumber(db, hash, number) + DeleteBody(db, hash, number) + DeleteTd(db, hash, number) +} + +// FindCommonAncestor returns the last common ancestor of two block headers +func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { + for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { + a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) + if a == nil { + return nil + } + } + for an := a.Number.Uint64(); an < b.Number.Uint64(); { + b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) + if b == nil { + return nil + } + } + for a.Hash() != b.Hash() { + a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) + if a == nil { + return nil + } + b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) + if b == nil { + return nil + } + } + return a +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_indexes.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_indexes.go new file mode 100644 index 00000000..38f8fe10 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_indexes.go @@ -0,0 +1,131 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// ReadTxLookupEntry retrieves the positional metadata associated with a transaction +// hash to allow retrieving the transaction or receipt by hash. +func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 { + data, _ := db.Get(txLookupKey(hash)) + if len(data) == 0 { + return nil + } + // Database v6 tx lookup just stores the block number + if len(data) < common.HashLength { + number := new(big.Int).SetBytes(data).Uint64() + return &number + } + // Database v4-v5 tx lookup format just stores the hash + if len(data) == common.HashLength { + return ReadHeaderNumber(db, common.BytesToHash(data)) + } + // Finally try database v3 tx lookup format + var entry LegacyTxLookupEntry + if err := rlp.DecodeBytes(data, &entry); err != nil { + log.Error("Invalid transaction lookup entry RLP", "hash", hash, "blob", data, "err", err) + return nil + } + return &entry.BlockIndex +} + +// WriteTxLookupEntries stores a positional metadata for every transaction from +// a block, enabling hash based transaction and receipt lookups. +func WriteTxLookupEntries(db ethdb.KeyValueWriter, block *types.Block) { + number := block.Number().Bytes() + for _, tx := range block.Transactions() { + if err := db.Put(txLookupKey(tx.Hash()), number); err != nil { + log.Crit("Failed to store transaction lookup entry", "err", err) + } + } +} + +// DeleteTxLookupEntry removes all transaction data associated with a hash. +func DeleteTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) { + db.Delete(txLookupKey(hash)) +} + +// ReadTransaction retrieves a specific transaction from the database, along with +// its added positional metadata. +func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { + blockNumber := ReadTxLookupEntry(db, hash) + if blockNumber == nil { + return nil, common.Hash{}, 0, 0 + } + blockHash := ReadCanonicalHash(db, *blockNumber) + if blockHash == (common.Hash{}) { + return nil, common.Hash{}, 0, 0 + } + body := ReadBody(db, blockHash, *blockNumber) + if body == nil { + log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash) + return nil, common.Hash{}, 0, 0 + } + for txIndex, tx := range body.Transactions { + if tx.Hash() == hash { + return tx, blockHash, *blockNumber, uint64(txIndex) + } + } + log.Error("Transaction not found", "number", blockNumber, "hash", blockHash, "txhash", hash) + return nil, common.Hash{}, 0, 0 +} + +// ReadReceipt retrieves a specific transaction receipt from the database, along with +// its added positional metadata. +func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig) (*types.Receipt, common.Hash, uint64, uint64) { + // Retrieve the context of the receipt based on the transaction hash + blockNumber := ReadTxLookupEntry(db, hash) + if blockNumber == nil { + return nil, common.Hash{}, 0, 0 + } + blockHash := ReadCanonicalHash(db, *blockNumber) + if blockHash == (common.Hash{}) { + return nil, common.Hash{}, 0, 0 + } + // Read all the receipts from the block and return the one with the matching hash + receipts := ReadReceipts(db, blockHash, *blockNumber, config) + for receiptIndex, receipt := range receipts { + if receipt.TxHash == hash { + return receipt, blockHash, *blockNumber, uint64(receiptIndex) + } + } + log.Error("Receipt not found", "number", blockNumber, "hash", blockHash, "txhash", hash) + return nil, common.Hash{}, 0, 0 +} + +// ReadBloomBits retrieves the compressed bloom bit vector belonging to the given +// section and bit index from the. +func ReadBloomBits(db ethdb.KeyValueReader, bit uint, section uint64, head common.Hash) ([]byte, error) { + return db.Get(bloomBitsKey(bit, section, head)) +} + +// WriteBloomBits stores the compressed bloom bits vector belonging to the given +// section and bit index. +func WriteBloomBits(db ethdb.KeyValueWriter, bit uint, section uint64, head common.Hash, bits []byte) { + if err := db.Put(bloomBitsKey(bit, section, head), bits); err != nil { + log.Crit("Failed to store bloom bits", "err", err) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_metadata.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_metadata.go new file mode 100644 index 00000000..f8d09fbd --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/accessors_metadata.go @@ -0,0 +1,98 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// ReadDatabaseVersion retrieves the version number of the database. +func ReadDatabaseVersion(db ethdb.KeyValueReader) *uint64 { + var version uint64 + + enc, _ := db.Get(databaseVerisionKey) + if len(enc) == 0 { + return nil + } + if err := rlp.DecodeBytes(enc, &version); err != nil { + return nil + } + + return &version +} + +// WriteDatabaseVersion stores the version number of the database +func WriteDatabaseVersion(db ethdb.KeyValueWriter, version uint64) { + enc, err := rlp.EncodeToBytes(version) + if err != nil { + log.Crit("Failed to encode database version", "err", err) + } + if err = db.Put(databaseVerisionKey, enc); err != nil { + log.Crit("Failed to store the database version", "err", err) + } +} + +// ReadChainConfig retrieves the consensus settings based on the given genesis hash. +func ReadChainConfig(db ethdb.KeyValueReader, hash common.Hash) *params.ChainConfig { + data, _ := db.Get(configKey(hash)) + if len(data) == 0 { + return nil + } + var config params.ChainConfig + if err := json.Unmarshal(data, &config); err != nil { + log.Error("Invalid chain config JSON", "hash", hash, "err", err) + return nil + } + return &config +} + +// WriteChainConfig writes the chain config settings to the database. +func WriteChainConfig(db ethdb.KeyValueWriter, hash common.Hash, cfg *params.ChainConfig) { + if cfg == nil { + return + } + data, err := json.Marshal(cfg) + if err != nil { + log.Crit("Failed to JSON encode chain config", "err", err) + } + if err := db.Put(configKey(hash), data); err != nil { + log.Crit("Failed to store chain config", "err", err) + } +} + +// ReadPreimage retrieves a single preimage of the provided hash. +func ReadPreimage(db ethdb.KeyValueReader, hash common.Hash) []byte { + data, _ := db.Get(preimageKey(hash)) + return data +} + +// WritePreimages writes the provided set of preimages to the database. +func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { + for hash, preimage := range preimages { + if err := db.Put(preimageKey(hash), preimage); err != nil { + log.Crit("Failed to store trie preimage", "err", err) + } + } + preimageCounter.Inc(int64(len(preimages))) + preimageHitCounter.Inc(int64(len(preimages))) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/database.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/database.go new file mode 100644 index 00000000..353b7dce --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/database.go @@ -0,0 +1,355 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "bytes" + "errors" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/leveldb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/log" + "github.com/olekukonko/tablewriter" +) + +// freezerdb is a database wrapper that enabled freezer data retrievals. +type freezerdb struct { + ethdb.KeyValueStore + ethdb.AncientStore +} + +// Close implements io.Closer, closing both the fast key-value store as well as +// the slow ancient tables. +func (frdb *freezerdb) Close() error { + var errs []error + if err := frdb.KeyValueStore.Close(); err != nil { + errs = append(errs, err) + } + if err := frdb.AncientStore.Close(); err != nil { + errs = append(errs, err) + } + if len(errs) != 0 { + return fmt.Errorf("%v", errs) + } + return nil +} + +// nofreezedb is a database wrapper that disables freezer data retrievals. +type nofreezedb struct { + ethdb.KeyValueStore +} + +// HasAncient returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) HasAncient(kind string, number uint64) (bool, error) { + return false, errNotSupported +} + +// Ancient returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) { + return nil, errNotSupported +} + +// Ancients returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) Ancients() (uint64, error) { + return 0, errNotSupported +} + +// AncientSize returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) AncientSize(kind string) (uint64, error) { + return 0, errNotSupported +} + +// AppendAncient returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error { + return errNotSupported +} + +// TruncateAncients returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) TruncateAncients(items uint64) error { + return errNotSupported +} + +// Sync returns an error as we don't have a backing chain freezer. +func (db *nofreezedb) Sync() error { + return errNotSupported +} + +// NewDatabase creates a high level database on top of a given key-value data +// store without a freezer moving immutable chain segments into cold storage. +func NewDatabase(db ethdb.KeyValueStore) ethdb.Database { + return &nofreezedb{ + KeyValueStore: db, + } +} + +// NewDatabaseWithFreezer creates a high level database on top of a given key- +// value data store with a freezer moving immutable chain segments into cold +// storage. +func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace string) (ethdb.Database, error) { + // Create the idle freezer instance + frdb, err := newFreezer(freezer, namespace) + if err != nil { + return nil, err + } + // Since the freezer can be stored separately from the user's key-value database, + // there's a fairly high probability that the user requests invalid combinations + // of the freezer and database. Ensure that we don't shoot ourselves in the foot + // by serving up conflicting data, leading to both datastores getting corrupted. + // + // - If both the freezer and key-value store is empty (no genesis), we just + // initialized a new empty freezer, so everything's fine. + // - If the key-value store is empty, but the freezer is not, we need to make + // sure the user's genesis matches the freezer. That will be checked in the + // blockchain, since we don't have the genesis block here (nor should we at + // this point care, the key-value/freezer combo is valid). + // - If neither the key-value store nor the freezer is empty, cross validate + // the genesis hashes to make sure they are compatible. If they are, also + // ensure that there's no gap between the freezer and sunsequently leveldb. + // - If the key-value store is not empty, but the freezer is we might just be + // upgrading to the freezer release, or we might have had a small chain and + // not frozen anything yet. Ensure that no blocks are missing yet from the + // key-value store, since that would mean we already had an old freezer. + + // If the genesis hash is empty, we have a new key-value store, so nothing to + // validate in this method. If, however, the genesis hash is not nil, compare + // it to the freezer content. + if kvgenesis, _ := db.Get(headerHashKey(0)); len(kvgenesis) > 0 { + if frozen, _ := frdb.Ancients(); frozen > 0 { + // If the freezer already contains something, ensure that the genesis blocks + // match, otherwise we might mix up freezers across chains and destroy both + // the freezer and the key-value store. + if frgenesis, _ := frdb.Ancient(freezerHashTable, 0); !bytes.Equal(kvgenesis, frgenesis) { + return nil, fmt.Errorf("genesis mismatch: %#x (leveldb) != %#x (ancients)", kvgenesis, frgenesis) + } + // Key-value store and freezer belong to the same network. Ensure that they + // are contiguous, otherwise we might end up with a non-functional freezer. + if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 { + // Subsequent header after the freezer limit is missing from the database. + // Reject startup is the database has a more recent head. + if *ReadHeaderNumber(db, ReadHeadHeaderHash(db)) > frozen-1 { + return nil, fmt.Errorf("gap (#%d) in the chain between ancients and leveldb", frozen) + } + // Database contains only older data than the freezer, this happens if the + // state was wiped and reinited from an existing freezer. + } else { + // Key-value store continues where the freezer left off, all is fine. We might + // have duplicate blocks (crash after freezer write but before kay-value store + // deletion, but that's fine). + } + } else { + // If the freezer is empty, ensure nothing was moved yet from the key-value + // store, otherwise we'll end up missing data. We check block #1 to decide + // if we froze anything previously or not, but do take care of databases with + // only the genesis block. + if ReadHeadHeaderHash(db) != common.BytesToHash(kvgenesis) { + // Key-value store contains more data than the genesis block, make sure we + // didn't freeze anything yet. + if kvblob, _ := db.Get(headerHashKey(1)); len(kvblob) == 0 { + return nil, errors.New("ancient chain segments already extracted, please set --datadir.ancient to the correct path") + } + // Block #1 is still in the database, we're allowed to init a new feezer + } else { + // The head header is still the genesis, we're allowed to init a new feezer + } + } + } + // Freezer is consistent with the key-value database, permit combining the two + go frdb.freeze(db) + + return &freezerdb{ + KeyValueStore: db, + AncientStore: frdb, + }, nil +} + +// NewMemoryDatabase creates an ephemeral in-memory key-value database without a +// freezer moving immutable chain segments into cold storage. +func NewMemoryDatabase() ethdb.Database { + return NewDatabase(memorydb.New()) +} + +// NewMemoryDatabaseWithCap creates an ephemeral in-memory key-value database +// with an initial starting capacity, but without a freezer moving immutable +// chain segments into cold storage. +func NewMemoryDatabaseWithCap(size int) ethdb.Database { + return NewDatabase(memorydb.NewWithCap(size)) +} + +// NewLevelDBDatabase creates a persistent key-value database without a freezer +// moving immutable chain segments into cold storage. +func NewLevelDBDatabase(file string, cache int, handles int, namespace string) (ethdb.Database, error) { + db, err := leveldb.New(file, cache, handles, namespace) + if err != nil { + return nil, err + } + return NewDatabase(db), nil +} + +// NewLevelDBDatabaseWithFreezer creates a persistent key-value database with a +// freezer moving immutable chain segments into cold storage. +func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, freezer string, namespace string) (ethdb.Database, error) { + kvdb, err := leveldb.New(file, cache, handles, namespace) + if err != nil { + return nil, err + } + frdb, err := NewDatabaseWithFreezer(kvdb, freezer, namespace) + if err != nil { + kvdb.Close() + return nil, err + } + return frdb, nil +} + +// InspectDatabase traverses the entire database and checks the size +// of all different categories of data. +func InspectDatabase(db ethdb.Database) error { + it := db.NewIterator() + defer it.Release() + + var ( + count int64 + start = time.Now() + logged = time.Now() + + // Key-value store statistics + total common.StorageSize + headerSize common.StorageSize + bodySize common.StorageSize + receiptSize common.StorageSize + tdSize common.StorageSize + numHashPairing common.StorageSize + hashNumPairing common.StorageSize + trieSize common.StorageSize + txlookupSize common.StorageSize + preimageSize common.StorageSize + bloomBitsSize common.StorageSize + cliqueSnapsSize common.StorageSize + + // Ancient store statistics + ancientHeaders common.StorageSize + ancientBodies common.StorageSize + ancientReceipts common.StorageSize + ancientHashes common.StorageSize + ancientTds common.StorageSize + + // Les statistic + chtTrieNodes common.StorageSize + bloomTrieNodes common.StorageSize + + // Meta- and unaccounted data + metadata common.StorageSize + unaccounted common.StorageSize + ) + // Inspect key-value database first. + for it.Next() { + var ( + key = it.Key() + size = common.StorageSize(len(key) + len(it.Value())) + ) + total += size + switch { + case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerTDSuffix): + tdSize += size + case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix): + numHashPairing += size + case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength): + headerSize += size + case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength): + hashNumPairing += size + case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength): + bodySize += size + case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength): + receiptSize += size + case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): + txlookupSize += size + case bytes.HasPrefix(key, preimagePrefix) && len(key) == (len(preimagePrefix)+common.HashLength): + preimageSize += size + case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): + bloomBitsSize += size + case bytes.HasPrefix(key, []byte("clique-")) && len(key) == 7+common.HashLength: + cliqueSnapsSize += size + case bytes.HasPrefix(key, []byte("cht-")) && len(key) == 4+common.HashLength: + chtTrieNodes += size + case bytes.HasPrefix(key, []byte("blt-")) && len(key) == 4+common.HashLength: + bloomTrieNodes += size + case len(key) == common.HashLength: + trieSize += size + default: + var accounted bool + for _, meta := range [][]byte{databaseVerisionKey, headHeaderKey, headBlockKey, headFastBlockKey, fastTrieProgressKey} { + if bytes.Equal(key, meta) { + metadata += size + accounted = true + break + } + } + if !accounted { + unaccounted += size + } + } + count += 1 + if count%1000 == 0 && time.Since(logged) > 8*time.Second { + log.Info("Inspecting database", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) + logged = time.Now() + } + } + // Inspect append-only file store then. + ancients := []*common.StorageSize{&ancientHeaders, &ancientBodies, &ancientReceipts, &ancientHashes, &ancientTds} + for i, category := range []string{freezerHeaderTable, freezerBodiesTable, freezerReceiptTable, freezerHashTable, freezerDifficultyTable} { + if size, err := db.AncientSize(category); err == nil { + *ancients[i] += common.StorageSize(size) + total += common.StorageSize(size) + } + } + // Display the database statistic. + stats := [][]string{ + {"Key-Value store", "Headers", headerSize.String()}, + {"Key-Value store", "Bodies", bodySize.String()}, + {"Key-Value store", "Receipts", receiptSize.String()}, + {"Key-Value store", "Difficulties", tdSize.String()}, + {"Key-Value store", "Block number->hash", numHashPairing.String()}, + {"Key-Value store", "Block hash->number", hashNumPairing.String()}, + {"Key-Value store", "Transaction index", txlookupSize.String()}, + {"Key-Value store", "Bloombit index", bloomBitsSize.String()}, + {"Key-Value store", "Trie nodes", trieSize.String()}, + {"Key-Value store", "Trie preimages", preimageSize.String()}, + {"Key-Value store", "Clique snapshots", cliqueSnapsSize.String()}, + {"Key-Value store", "Singleton metadata", metadata.String()}, + {"Ancient store", "Headers", ancientHeaders.String()}, + {"Ancient store", "Bodies", ancientBodies.String()}, + {"Ancient store", "Receipts", ancientReceipts.String()}, + {"Ancient store", "Difficulties", ancientTds.String()}, + {"Ancient store", "Block number->hash", ancientHashes.String()}, + {"Light client", "CHT trie nodes", chtTrieNodes.String()}, + {"Light client", "Bloom trie nodes", bloomTrieNodes.String()}, + } + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Database", "Category", "Size"}) + table.SetFooter([]string{"", "Total", total.String()}) + table.AppendBulk(stats) + table.Render() + + if unaccounted > 0 { + log.Error("Database contains unaccounted data", "size", unaccounted) + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer.go new file mode 100644 index 00000000..3f377447 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer.go @@ -0,0 +1,393 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "errors" + "fmt" + "math" + "os" + "path/filepath" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "github.com/prometheus/tsdb/fileutil" +) + +var ( + // errUnknownTable is returned if the user attempts to read from a table that is + // not tracked by the freezer. + errUnknownTable = errors.New("unknown table") + + // errOutOrderInsertion is returned if the user attempts to inject out-of-order + // binary blobs into the freezer. + errOutOrderInsertion = errors.New("the append operation is out-order") + + // errSymlinkDatadir is returned if the ancient directory specified by user + // is a symbolic link. + errSymlinkDatadir = errors.New("symbolic link datadir is not supported") +) + +const ( + // freezerRecheckInterval is the frequency to check the key-value database for + // chain progression that might permit new blocks to be frozen into immutable + // storage. + freezerRecheckInterval = time.Minute + + // freezerBatchLimit is the maximum number of blocks to freeze in one batch + // before doing an fsync and deleting it from the key-value store. + freezerBatchLimit = 30000 +) + +// freezer is an memory mapped append-only database to store immutable chain data +// into flat files: +// +// - The append only nature ensures that disk writes are minimized. +// - The memory mapping ensures we can max out system memory for caching without +// reserving it for go-ethereum. This would also reduce the memory requirements +// of Geth, and thus also GC overhead. +type freezer struct { + // WARNING: The `frozen` field is accessed atomically. On 32 bit platforms, only + // 64-bit aligned fields can be atomic. The struct is guaranteed to be so aligned, + // so take advantage of that (https://golang.org/pkg/sync/atomic/#pkg-note-BUG). + frozen uint64 // Number of blocks already frozen + + tables map[string]*freezerTable // Data tables for storing everything + instanceLock fileutil.Releaser // File-system lock to prevent double opens +} + +// newFreezer creates a chain freezer that moves ancient chain data into +// append-only flat file containers. +func newFreezer(datadir string, namespace string) (*freezer, error) { + // Create the initial freezer object + var ( + readMeter = metrics.NewRegisteredMeter(namespace+"ancient/read", nil) + writeMeter = metrics.NewRegisteredMeter(namespace+"ancient/write", nil) + sizeCounter = metrics.NewRegisteredCounter(namespace+"ancient/size", nil) + ) + // Ensure the datadir is not a symbolic link if it exists. + if info, err := os.Lstat(datadir); !os.IsNotExist(err) { + if info.Mode()&os.ModeSymlink != 0 { + log.Warn("Symbolic link ancient database is not supported", "path", datadir) + return nil, errSymlinkDatadir + } + } + // Leveldb uses LOCK as the filelock filename. To prevent the + // name collision, we use FLOCK as the lock name. + lock, _, err := fileutil.Flock(filepath.Join(datadir, "FLOCK")) + if err != nil { + return nil, err + } + // Open all the supported data tables + freezer := &freezer{ + tables: make(map[string]*freezerTable), + instanceLock: lock, + } + for name, disableSnappy := range freezerNoSnappy { + table, err := newTable(datadir, name, readMeter, writeMeter, sizeCounter, disableSnappy) + if err != nil { + for _, table := range freezer.tables { + table.Close() + } + lock.Release() + return nil, err + } + freezer.tables[name] = table + } + if err := freezer.repair(); err != nil { + for _, table := range freezer.tables { + table.Close() + } + lock.Release() + return nil, err + } + log.Info("Opened ancient database", "database", datadir) + return freezer, nil +} + +// Close terminates the chain freezer, unmapping all the data files. +func (f *freezer) Close() error { + var errs []error + for _, table := range f.tables { + if err := table.Close(); err != nil { + errs = append(errs, err) + } + } + if err := f.instanceLock.Release(); err != nil { + errs = append(errs, err) + } + if errs != nil { + return fmt.Errorf("%v", errs) + } + return nil +} + +// HasAncient returns an indicator whether the specified ancient data exists +// in the freezer. +func (f *freezer) HasAncient(kind string, number uint64) (bool, error) { + if table := f.tables[kind]; table != nil { + return table.has(number), nil + } + return false, nil +} + +// Ancient retrieves an ancient binary blob from the append-only immutable files. +func (f *freezer) Ancient(kind string, number uint64) ([]byte, error) { + if table := f.tables[kind]; table != nil { + return table.Retrieve(number) + } + return nil, errUnknownTable +} + +// Ancients returns the length of the frozen items. +func (f *freezer) Ancients() (uint64, error) { + return atomic.LoadUint64(&f.frozen), nil +} + +// AncientSize returns the ancient size of the specified category. +func (f *freezer) AncientSize(kind string) (uint64, error) { + if table := f.tables[kind]; table != nil { + return table.size() + } + return 0, errUnknownTable +} + +// AppendAncient injects all binary blobs belong to block at the end of the +// append-only immutable table files. +// +// Notably, this function is lock free but kind of thread-safe. All out-of-order +// injection will be rejected. But if two injections with same number happen at +// the same time, we can get into the trouble. +func (f *freezer) AppendAncient(number uint64, hash, header, body, receipts, td []byte) (err error) { + // Ensure the binary blobs we are appending is continuous with freezer. + if atomic.LoadUint64(&f.frozen) != number { + return errOutOrderInsertion + } + // Rollback all inserted data if any insertion below failed to ensure + // the tables won't out of sync. + defer func() { + if err != nil { + rerr := f.repair() + if rerr != nil { + log.Crit("Failed to repair freezer", "err", rerr) + } + log.Info("Append ancient failed", "number", number, "err", err) + } + }() + // Inject all the components into the relevant data tables + if err := f.tables[freezerHashTable].Append(f.frozen, hash[:]); err != nil { + log.Error("Failed to append ancient hash", "number", f.frozen, "hash", hash, "err", err) + return err + } + if err := f.tables[freezerHeaderTable].Append(f.frozen, header); err != nil { + log.Error("Failed to append ancient header", "number", f.frozen, "hash", hash, "err", err) + return err + } + if err := f.tables[freezerBodiesTable].Append(f.frozen, body); err != nil { + log.Error("Failed to append ancient body", "number", f.frozen, "hash", hash, "err", err) + return err + } + if err := f.tables[freezerReceiptTable].Append(f.frozen, receipts); err != nil { + log.Error("Failed to append ancient receipts", "number", f.frozen, "hash", hash, "err", err) + return err + } + if err := f.tables[freezerDifficultyTable].Append(f.frozen, td); err != nil { + log.Error("Failed to append ancient difficulty", "number", f.frozen, "hash", hash, "err", err) + return err + } + atomic.AddUint64(&f.frozen, 1) // Only modify atomically + return nil +} + +// Truncate discards any recent data above the provided threshold number. +func (f *freezer) TruncateAncients(items uint64) error { + if atomic.LoadUint64(&f.frozen) <= items { + return nil + } + for _, table := range f.tables { + if err := table.truncate(items); err != nil { + return err + } + } + atomic.StoreUint64(&f.frozen, items) + return nil +} + +// sync flushes all data tables to disk. +func (f *freezer) Sync() error { + var errs []error + for _, table := range f.tables { + if err := table.Sync(); err != nil { + errs = append(errs, err) + } + } + if errs != nil { + return fmt.Errorf("%v", errs) + } + return nil +} + +// freeze is a background thread that periodically checks the blockchain for any +// import progress and moves ancient data from the fast database into the freezer. +// +// This functionality is deliberately broken off from block importing to avoid +// incurring additional data shuffling delays on block propagation. +func (f *freezer) freeze(db ethdb.KeyValueStore) { + nfdb := &nofreezedb{KeyValueStore: db} + + for { + // Retrieve the freezing threshold. + hash := ReadHeadBlockHash(nfdb) + if hash == (common.Hash{}) { + log.Debug("Current full block hash unavailable") // new chain, empty database + time.Sleep(freezerRecheckInterval) + continue + } + number := ReadHeaderNumber(nfdb, hash) + switch { + case number == nil: + log.Error("Current full block number unavailable", "hash", hash) + time.Sleep(freezerRecheckInterval) + continue + + case *number < params.ImmutabilityThreshold: + log.Debug("Current full block not old enough", "number", *number, "hash", hash, "delay", params.ImmutabilityThreshold) + time.Sleep(freezerRecheckInterval) + continue + + case *number-params.ImmutabilityThreshold <= f.frozen: + log.Debug("Ancient blocks frozen already", "number", *number, "hash", hash, "frozen", f.frozen) + time.Sleep(freezerRecheckInterval) + continue + } + head := ReadHeader(nfdb, hash, *number) + if head == nil { + log.Error("Current full block unavailable", "number", *number, "hash", hash) + time.Sleep(freezerRecheckInterval) + continue + } + // Seems we have data ready to be frozen, process in usable batches + limit := *number - params.ImmutabilityThreshold + if limit-f.frozen > freezerBatchLimit { + limit = f.frozen + freezerBatchLimit + } + var ( + start = time.Now() + first = f.frozen + ancients = make([]common.Hash, 0, limit) + ) + for f.frozen < limit { + // Retrieves all the components of the canonical block + hash := ReadCanonicalHash(nfdb, f.frozen) + if hash == (common.Hash{}) { + log.Error("Canonical hash missing, can't freeze", "number", f.frozen) + break + } + header := ReadHeaderRLP(nfdb, hash, f.frozen) + if len(header) == 0 { + log.Error("Block header missing, can't freeze", "number", f.frozen, "hash", hash) + break + } + body := ReadBodyRLP(nfdb, hash, f.frozen) + if len(body) == 0 { + log.Error("Block body missing, can't freeze", "number", f.frozen, "hash", hash) + break + } + receipts := ReadReceiptsRLP(nfdb, hash, f.frozen) + if len(receipts) == 0 { + log.Error("Block receipts missing, can't freeze", "number", f.frozen, "hash", hash) + break + } + td := ReadTdRLP(nfdb, hash, f.frozen) + if len(td) == 0 { + log.Error("Total difficulty missing, can't freeze", "number", f.frozen, "hash", hash) + break + } + log.Trace("Deep froze ancient block", "number", f.frozen, "hash", hash) + // Inject all the components into the relevant data tables + if err := f.AppendAncient(f.frozen, hash[:], header, body, receipts, td); err != nil { + break + } + ancients = append(ancients, hash) + } + // Batch of blocks have been frozen, flush them before wiping from leveldb + if err := f.Sync(); err != nil { + log.Crit("Failed to flush frozen tables", "err", err) + } + // Wipe out all data from the active database + batch := db.NewBatch() + for i := 0; i < len(ancients); i++ { + // Always keep the genesis block in active database + if first+uint64(i) != 0 { + DeleteBlockWithoutNumber(batch, ancients[i], first+uint64(i)) + DeleteCanonicalHash(batch, first+uint64(i)) + } + } + if err := batch.Write(); err != nil { + log.Crit("Failed to delete frozen canonical blocks", "err", err) + } + batch.Reset() + // Wipe out side chain also. + for number := first; number < f.frozen; number++ { + // Always keep the genesis block in active database + if number != 0 { + for _, hash := range ReadAllHashes(db, number) { + DeleteBlock(batch, hash, number) + } + } + } + if err := batch.Write(); err != nil { + log.Crit("Failed to delete frozen side blocks", "err", err) + } + // Log something friendly for the user + context := []interface{}{ + "blocks", f.frozen - first, "elapsed", common.PrettyDuration(time.Since(start)), "number", f.frozen - 1, + } + if n := len(ancients); n > 0 { + context = append(context, []interface{}{"hash", ancients[n-1]}...) + } + log.Info("Deep froze chain segment", context...) + + // Avoid database thrashing with tiny writes + if f.frozen-first < freezerBatchLimit { + time.Sleep(freezerRecheckInterval) + } + } +} + +// repair truncates all data tables to the same length. +func (f *freezer) repair() error { + min := uint64(math.MaxUint64) + for _, table := range f.tables { + items := atomic.LoadUint64(&table.items) + if min > items { + min = items + } + } + for _, table := range f.tables { + if err := table.truncate(min); err != nil { + return err + } + } + atomic.StoreUint64(&f.frozen, min) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_reinit.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_reinit.go new file mode 100644 index 00000000..ea4dd33d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_reinit.go @@ -0,0 +1,127 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "errors" + "runtime" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" +) + +// InitDatabaseFromFreezer reinitializes an empty database from a previous batch +// of frozen ancient blocks. The method iterates over all the frozen blocks and +// injects into the database the block hash->number mappings and the transaction +// lookup entries. +func InitDatabaseFromFreezer(db ethdb.Database) error { + // If we can't access the freezer or it's empty, abort + frozen, err := db.Ancients() + if err != nil || frozen == 0 { + return err + } + // Blocks previously frozen, iterate over- and hash them concurrently + var ( + number = ^uint64(0) // -1 + results = make(chan *types.Block, 4*runtime.NumCPU()) + ) + abort := make(chan struct{}) + defer close(abort) + + for i := 0; i < runtime.NumCPU(); i++ { + go func() { + for { + // Fetch the next task number, terminating if everything's done + n := atomic.AddUint64(&number, 1) + if n >= frozen { + return + } + // Retrieve the block from the freezer (no need for the hash, we pull by + // number from the freezer). If successful, pre-cache the block hash and + // the individual transaction hashes for storing into the database. + block := ReadBlock(db, common.Hash{}, n) + if block != nil { + block.Hash() + for _, tx := range block.Transactions() { + tx.Hash() + } + } + // Feed the block to the aggregator, or abort on interrupt + select { + case results <- block: + case <-abort: + return + } + } + }() + } + // Reassemble the blocks into a contiguous stream and push them out to disk + var ( + queue = prque.New(nil) + next = int64(0) + + batch = db.NewBatch() + start = time.Now() + logged time.Time + ) + for i := uint64(0); i < frozen; i++ { + // Retrieve the next result and bail if it's nil + block := <-results + if block == nil { + return errors.New("broken ancient database") + } + // Push the block into the import queue and process contiguous ranges + queue.Push(block, -int64(block.NumberU64())) + for !queue.Empty() { + // If the next available item is gapped, return + if _, priority := queue.Peek(); -priority != next { + break + } + // Next block available, pop it off and index it + block = queue.PopItem().(*types.Block) + next++ + + // Inject hash<->number mapping and txlookup indexes + WriteHeaderNumber(batch, block.Hash(), block.NumberU64()) + WriteTxLookupEntries(batch, block) + + // If enough data was accumulated in memory or we're at the last block, dump to disk + if batch.ValueSize() > ethdb.IdealBatchSize || uint64(next) == frozen { + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + } + // If we've spent too much time already, notify the user of what we're doing + if time.Since(logged) > 8*time.Second { + log.Info("Initializing chain from ancient data", "number", block.Number(), "hash", block.Hash(), "total", frozen-1, "elapsed", common.PrettyDuration(time.Since(start))) + logged = time.Now() + } + } + } + hash := ReadCanonicalHash(db, frozen-1) + WriteHeadHeaderHash(db, hash) + WriteHeadFastBlockHash(db, hash) + + log.Info("Initialized chain from ancient data", "number", frozen-1, "hash", hash, "elapsed", common.PrettyDuration(time.Since(start))) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_table.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_table.go new file mode 100644 index 00000000..2fe354a0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/freezer_table.go @@ -0,0 +1,635 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "sync" + "sync/atomic" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/golang/snappy" +) + +var ( + // errClosed is returned if an operation attempts to read from or write to the + // freezer table after it has already been closed. + errClosed = errors.New("closed") + + // errOutOfBounds is returned if the item requested is not contained within the + // freezer table. + errOutOfBounds = errors.New("out of bounds") + + // errNotSupported is returned if the database doesn't support the required operation. + errNotSupported = errors.New("this operation is not supported") +) + +// indexEntry contains the number/id of the file that the data resides in, aswell as the +// offset within the file to the end of the data +// In serialized form, the filenum is stored as uint16. +type indexEntry struct { + filenum uint32 // stored as uint16 ( 2 bytes) + offset uint32 // stored as uint32 ( 4 bytes) +} + +const indexEntrySize = 6 + +// unmarshallBinary deserializes binary b into the rawIndex entry. +func (i *indexEntry) unmarshalBinary(b []byte) error { + i.filenum = uint32(binary.BigEndian.Uint16(b[:2])) + i.offset = binary.BigEndian.Uint32(b[2:6]) + return nil +} + +// marshallBinary serializes the rawIndex entry into binary. +func (i *indexEntry) marshallBinary() []byte { + b := make([]byte, indexEntrySize) + binary.BigEndian.PutUint16(b[:2], uint16(i.filenum)) + binary.BigEndian.PutUint32(b[2:6], i.offset) + return b +} + +// freezerTable represents a single chained data table within the freezer (e.g. blocks). +// It consists of a data file (snappy encoded arbitrary data blobs) and an indexEntry +// file (uncompressed 64 bit indices into the data file). +type freezerTable struct { + // WARNING: The `items` field is accessed atomically. On 32 bit platforms, only + // 64-bit aligned fields can be atomic. The struct is guaranteed to be so aligned, + // so take advantage of that (https://golang.org/pkg/sync/atomic/#pkg-note-BUG). + items uint64 // Number of items stored in the table (including items removed from tail) + + noCompression bool // if true, disables snappy compression. Note: does not work retroactively + maxFileSize uint32 // Max file size for data-files + name string + path string + + head *os.File // File descriptor for the data head of the table + files map[uint32]*os.File // open files + headId uint32 // number of the currently active head file + tailId uint32 // number of the earliest file + index *os.File // File descriptor for the indexEntry file of the table + + // In the case that old items are deleted (from the tail), we use itemOffset + // to count how many historic items have gone missing. + itemOffset uint32 // Offset (number of discarded items) + + headBytes uint32 // Number of bytes written to the head file + readMeter metrics.Meter // Meter for measuring the effective amount of data read + writeMeter metrics.Meter // Meter for measuring the effective amount of data written + sizeCounter metrics.Counter // Counter for tracking the combined size of all freezer tables + + logger log.Logger // Logger with database path and table name ambedded + lock sync.RWMutex // Mutex protecting the data file descriptors +} + +// newTable opens a freezer table with default settings - 2G files +func newTable(path string, name string, readMeter metrics.Meter, writeMeter metrics.Meter, sizeCounter metrics.Counter, disableSnappy bool) (*freezerTable, error) { + return newCustomTable(path, name, readMeter, writeMeter, sizeCounter, 2*1000*1000*1000, disableSnappy) +} + +// openFreezerFileForAppend opens a freezer table file and seeks to the end +func openFreezerFileForAppend(filename string) (*os.File, error) { + // Open the file without the O_APPEND flag + // because it has differing behaviour during Truncate operations + // on different OS's + file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return nil, err + } + // Seek to end for append + if _, err = file.Seek(0, io.SeekEnd); err != nil { + return nil, err + } + return file, nil +} + +// openFreezerFileForReadOnly opens a freezer table file for read only access +func openFreezerFileForReadOnly(filename string) (*os.File, error) { + return os.OpenFile(filename, os.O_RDONLY, 0644) +} + +// openFreezerFileTruncated opens a freezer table making sure it is truncated +func openFreezerFileTruncated(filename string) (*os.File, error) { + return os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) +} + +// truncateFreezerFile resizes a freezer table file and seeks to the end +func truncateFreezerFile(file *os.File, size int64) error { + if err := file.Truncate(size); err != nil { + return err + } + // Seek to end for append + if _, err := file.Seek(0, io.SeekEnd); err != nil { + return err + } + return nil +} + +// newCustomTable opens a freezer table, creating the data and index files if they are +// non existent. Both files are truncated to the shortest common length to ensure +// they don't go out of sync. +func newCustomTable(path string, name string, readMeter metrics.Meter, writeMeter metrics.Meter, sizeCounter metrics.Counter, maxFilesize uint32, noCompression bool) (*freezerTable, error) { + // Ensure the containing directory exists and open the indexEntry file + if err := os.MkdirAll(path, 0755); err != nil { + return nil, err + } + var idxName string + if noCompression { + // Raw idx + idxName = fmt.Sprintf("%s.ridx", name) + } else { + // Compressed idx + idxName = fmt.Sprintf("%s.cidx", name) + } + offsets, err := openFreezerFileForAppend(filepath.Join(path, idxName)) + if err != nil { + return nil, err + } + // Create the table and repair any past inconsistency + tab := &freezerTable{ + index: offsets, + files: make(map[uint32]*os.File), + readMeter: readMeter, + writeMeter: writeMeter, + sizeCounter: sizeCounter, + name: name, + path: path, + logger: log.New("database", path, "table", name), + noCompression: noCompression, + maxFileSize: maxFilesize, + } + if err := tab.repair(); err != nil { + tab.Close() + return nil, err + } + // Initialize the starting size counter + size, err := tab.sizeNolock() + if err != nil { + tab.Close() + return nil, err + } + tab.sizeCounter.Inc(int64(size)) + + return tab, nil +} + +// repair cross checks the head and the index file and truncates them to +// be in sync with each other after a potential crash / data loss. +func (t *freezerTable) repair() error { + // Create a temporary offset buffer to init files with and read indexEntry into + buffer := make([]byte, indexEntrySize) + + // If we've just created the files, initialize the index with the 0 indexEntry + stat, err := t.index.Stat() + if err != nil { + return err + } + if stat.Size() == 0 { + if _, err := t.index.Write(buffer); err != nil { + return err + } + } + // Ensure the index is a multiple of indexEntrySize bytes + if overflow := stat.Size() % indexEntrySize; overflow != 0 { + truncateFreezerFile(t.index, stat.Size()-overflow) // New file can't trigger this path + } + // Retrieve the file sizes and prepare for truncation + if stat, err = t.index.Stat(); err != nil { + return err + } + offsetsSize := stat.Size() + + // Open the head file + var ( + firstIndex indexEntry + lastIndex indexEntry + contentSize int64 + contentExp int64 + ) + // Read index zero, determine what file is the earliest + // and what item offset to use + t.index.ReadAt(buffer, 0) + firstIndex.unmarshalBinary(buffer) + + t.tailId = firstIndex.offset + t.itemOffset = firstIndex.filenum + + t.index.ReadAt(buffer, offsetsSize-indexEntrySize) + lastIndex.unmarshalBinary(buffer) + t.head, err = t.openFile(lastIndex.filenum, openFreezerFileForAppend) + if err != nil { + return err + } + if stat, err = t.head.Stat(); err != nil { + return err + } + contentSize = stat.Size() + + // Keep truncating both files until they come in sync + contentExp = int64(lastIndex.offset) + + for contentExp != contentSize { + // Truncate the head file to the last offset pointer + if contentExp < contentSize { + t.logger.Warn("Truncating dangling head", "indexed", common.StorageSize(contentExp), "stored", common.StorageSize(contentSize)) + if err := truncateFreezerFile(t.head, contentExp); err != nil { + return err + } + contentSize = contentExp + } + // Truncate the index to point within the head file + if contentExp > contentSize { + t.logger.Warn("Truncating dangling indexes", "indexed", common.StorageSize(contentExp), "stored", common.StorageSize(contentSize)) + if err := truncateFreezerFile(t.index, offsetsSize-indexEntrySize); err != nil { + return err + } + offsetsSize -= indexEntrySize + t.index.ReadAt(buffer, offsetsSize-indexEntrySize) + var newLastIndex indexEntry + newLastIndex.unmarshalBinary(buffer) + // We might have slipped back into an earlier head-file here + if newLastIndex.filenum != lastIndex.filenum { + // Release earlier opened file + t.releaseFile(lastIndex.filenum) + t.head, err = t.openFile(newLastIndex.filenum, openFreezerFileForAppend) + if stat, err = t.head.Stat(); err != nil { + // TODO, anything more we can do here? + // A data file has gone missing... + return err + } + contentSize = stat.Size() + } + lastIndex = newLastIndex + contentExp = int64(lastIndex.offset) + } + } + // Ensure all reparation changes have been written to disk + if err := t.index.Sync(); err != nil { + return err + } + if err := t.head.Sync(); err != nil { + return err + } + // Update the item and byte counters and return + t.items = uint64(t.itemOffset) + uint64(offsetsSize/indexEntrySize-1) // last indexEntry points to the end of the data file + t.headBytes = uint32(contentSize) + t.headId = lastIndex.filenum + + // Close opened files and preopen all files + if err := t.preopen(); err != nil { + return err + } + t.logger.Debug("Chain freezer table opened", "items", t.items, "size", common.StorageSize(t.headBytes)) + return nil +} + +// preopen opens all files that the freezer will need. This method should be called from an init-context, +// since it assumes that it doesn't have to bother with locking +// The rationale for doing preopen is to not have to do it from within Retrieve, thus not needing to ever +// obtain a write-lock within Retrieve. +func (t *freezerTable) preopen() (err error) { + // The repair might have already opened (some) files + t.releaseFilesAfter(0, false) + // Open all except head in RDONLY + for i := t.tailId; i < t.headId; i++ { + if _, err = t.openFile(i, openFreezerFileForReadOnly); err != nil { + return err + } + } + // Open head in read/write + t.head, err = t.openFile(t.headId, openFreezerFileForAppend) + return err +} + +// truncate discards any recent data above the provided threshold number. +func (t *freezerTable) truncate(items uint64) error { + t.lock.Lock() + defer t.lock.Unlock() + + // If our item count is correct, don't do anything + if atomic.LoadUint64(&t.items) <= items { + return nil + } + // We need to truncate, save the old size for metrics tracking + oldSize, err := t.sizeNolock() + if err != nil { + return err + } + // Something's out of sync, truncate the table's offset index + t.logger.Warn("Truncating freezer table", "items", t.items, "limit", items) + if err := truncateFreezerFile(t.index, int64(items+1)*indexEntrySize); err != nil { + return err + } + // Calculate the new expected size of the data file and truncate it + buffer := make([]byte, indexEntrySize) + if _, err := t.index.ReadAt(buffer, int64(items*indexEntrySize)); err != nil { + return err + } + var expected indexEntry + expected.unmarshalBinary(buffer) + + // We might need to truncate back to older files + if expected.filenum != t.headId { + // If already open for reading, force-reopen for writing + t.releaseFile(expected.filenum) + newHead, err := t.openFile(expected.filenum, openFreezerFileForAppend) + if err != nil { + return err + } + // Release any files _after the current head -- both the previous head + // and any files which may have been opened for reading + t.releaseFilesAfter(expected.filenum, true) + // Set back the historic head + t.head = newHead + atomic.StoreUint32(&t.headId, expected.filenum) + } + if err := truncateFreezerFile(t.head, int64(expected.offset)); err != nil { + return err + } + // All data files truncated, set internal counters and return + atomic.StoreUint64(&t.items, items) + atomic.StoreUint32(&t.headBytes, expected.offset) + + // Retrieve the new size and update the total size counter + newSize, err := t.sizeNolock() + if err != nil { + return err + } + t.sizeCounter.Dec(int64(oldSize - newSize)) + + return nil +} + +// Close closes all opened files. +func (t *freezerTable) Close() error { + t.lock.Lock() + defer t.lock.Unlock() + + var errs []error + if err := t.index.Close(); err != nil { + errs = append(errs, err) + } + t.index = nil + + for _, f := range t.files { + if err := f.Close(); err != nil { + errs = append(errs, err) + } + } + t.head = nil + + if errs != nil { + return fmt.Errorf("%v", errs) + } + return nil +} + +// openFile assumes that the write-lock is held by the caller +func (t *freezerTable) openFile(num uint32, opener func(string) (*os.File, error)) (f *os.File, err error) { + var exist bool + if f, exist = t.files[num]; !exist { + var name string + if t.noCompression { + name = fmt.Sprintf("%s.%04d.rdat", t.name, num) + } else { + name = fmt.Sprintf("%s.%04d.cdat", t.name, num) + } + f, err = opener(filepath.Join(t.path, name)) + if err != nil { + return nil, err + } + t.files[num] = f + } + return f, err +} + +// releaseFile closes a file, and removes it from the open file cache. +// Assumes that the caller holds the write lock +func (t *freezerTable) releaseFile(num uint32) { + if f, exist := t.files[num]; exist { + delete(t.files, num) + f.Close() + } +} + +// releaseFilesAfter closes all open files with a higher number, and optionally also deletes the files +func (t *freezerTable) releaseFilesAfter(num uint32, remove bool) { + for fnum, f := range t.files { + if fnum > num { + delete(t.files, fnum) + f.Close() + if remove { + os.Remove(f.Name()) + } + } + } +} + +// Append injects a binary blob at the end of the freezer table. The item number +// is a precautionary parameter to ensure data correctness, but the table will +// reject already existing data. +// +// Note, this method will *not* flush any data to disk so be sure to explicitly +// fsync before irreversibly deleting data from the database. +func (t *freezerTable) Append(item uint64, blob []byte) error { + // Read lock prevents competition with truncate + t.lock.RLock() + // Ensure the table is still accessible + if t.index == nil || t.head == nil { + t.lock.RUnlock() + return errClosed + } + // Ensure only the next item can be written, nothing else + if atomic.LoadUint64(&t.items) != item { + t.lock.RUnlock() + return fmt.Errorf("appending unexpected item: want %d, have %d", t.items, item) + } + // Encode the blob and write it into the data file + if !t.noCompression { + blob = snappy.Encode(nil, blob) + } + bLen := uint32(len(blob)) + if t.headBytes+bLen < bLen || + t.headBytes+bLen > t.maxFileSize { + // we need a new file, writing would overflow + t.lock.RUnlock() + t.lock.Lock() + nextID := atomic.LoadUint32(&t.headId) + 1 + // We open the next file in truncated mode -- if this file already + // exists, we need to start over from scratch on it + newHead, err := t.openFile(nextID, openFreezerFileTruncated) + if err != nil { + t.lock.Unlock() + return err + } + // Close old file, and reopen in RDONLY mode + t.releaseFile(t.headId) + t.openFile(t.headId, openFreezerFileForReadOnly) + + // Swap out the current head + t.head = newHead + atomic.StoreUint32(&t.headBytes, 0) + atomic.StoreUint32(&t.headId, nextID) + t.lock.Unlock() + t.lock.RLock() + } + + defer t.lock.RUnlock() + if _, err := t.head.Write(blob); err != nil { + return err + } + newOffset := atomic.AddUint32(&t.headBytes, bLen) + idx := indexEntry{ + filenum: atomic.LoadUint32(&t.headId), + offset: newOffset, + } + // Write indexEntry + t.index.Write(idx.marshallBinary()) + + t.writeMeter.Mark(int64(bLen + indexEntrySize)) + t.sizeCounter.Inc(int64(bLen + indexEntrySize)) + + atomic.AddUint64(&t.items, 1) + return nil +} + +// getBounds returns the indexes for the item +// returns start, end, filenumber and error +func (t *freezerTable) getBounds(item uint64) (uint32, uint32, uint32, error) { + var startIdx, endIdx indexEntry + buffer := make([]byte, indexEntrySize) + if _, err := t.index.ReadAt(buffer, int64(item*indexEntrySize)); err != nil { + return 0, 0, 0, err + } + startIdx.unmarshalBinary(buffer) + if _, err := t.index.ReadAt(buffer, int64((item+1)*indexEntrySize)); err != nil { + return 0, 0, 0, err + } + endIdx.unmarshalBinary(buffer) + if startIdx.filenum != endIdx.filenum { + // If a piece of data 'crosses' a data-file, + // it's actually in one piece on the second data-file. + // We return a zero-indexEntry for the second file as start + return 0, endIdx.offset, endIdx.filenum, nil + } + return startIdx.offset, endIdx.offset, endIdx.filenum, nil +} + +// Retrieve looks up the data offset of an item with the given number and retrieves +// the raw binary blob from the data file. +func (t *freezerTable) Retrieve(item uint64) ([]byte, error) { + // Ensure the table and the item is accessible + if t.index == nil || t.head == nil { + return nil, errClosed + } + if atomic.LoadUint64(&t.items) <= item { + return nil, errOutOfBounds + } + // Ensure the item was not deleted from the tail either + offset := atomic.LoadUint32(&t.itemOffset) + if uint64(offset) > item { + return nil, errOutOfBounds + } + t.lock.RLock() + startOffset, endOffset, filenum, err := t.getBounds(item - uint64(offset)) + if err != nil { + t.lock.RUnlock() + return nil, err + } + dataFile, exist := t.files[filenum] + if !exist { + t.lock.RUnlock() + return nil, fmt.Errorf("missing data file %d", filenum) + } + // Retrieve the data itself, decompress and return + blob := make([]byte, endOffset-startOffset) + if _, err := dataFile.ReadAt(blob, int64(startOffset)); err != nil { + t.lock.RUnlock() + return nil, err + } + t.lock.RUnlock() + t.readMeter.Mark(int64(len(blob) + 2*indexEntrySize)) + + if t.noCompression { + return blob, nil + } + return snappy.Decode(nil, blob) +} + +// has returns an indicator whether the specified number data +// exists in the freezer table. +func (t *freezerTable) has(number uint64) bool { + return atomic.LoadUint64(&t.items) > number +} + +// size returns the total data size in the freezer table. +func (t *freezerTable) size() (uint64, error) { + t.lock.RLock() + defer t.lock.RUnlock() + + return t.sizeNolock() +} + +// sizeNolock returns the total data size in the freezer table without obtaining +// the mutex first. +func (t *freezerTable) sizeNolock() (uint64, error) { + stat, err := t.index.Stat() + if err != nil { + return 0, err + } + total := uint64(t.maxFileSize)*uint64(t.headId-t.tailId) + uint64(t.headBytes) + uint64(stat.Size()) + return total, nil +} + +// Sync pushes any pending data from memory out to disk. This is an expensive +// operation, so use it with care. +func (t *freezerTable) Sync() error { + if err := t.index.Sync(); err != nil { + return err + } + return t.head.Sync() +} + +// printIndex is a debug print utility function for testing +func (t *freezerTable) printIndex() { + buf := make([]byte, indexEntrySize) + + fmt.Printf("|-----------------|\n") + fmt.Printf("| fileno | offset |\n") + fmt.Printf("|--------+--------|\n") + + for i := uint64(0); ; i++ { + if _, err := t.index.ReadAt(buf, int64(i*indexEntrySize)); err != nil { + break + } + var entry indexEntry + entry.unmarshalBinary(buf) + fmt.Printf("| %03d | %03d | \n", entry.filenum, entry.offset) + if i > 100 { + fmt.Printf(" ... \n") + break + } + } + fmt.Printf("|-----------------|\n") +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/schema.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/schema.go new file mode 100644 index 00000000..a44a2c99 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/schema.go @@ -0,0 +1,166 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package rawdb contains a collection of low level database accessors. +package rawdb + +import ( + "encoding/binary" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/metrics" +) + +// The fields below define the low level database schema prefixing. +var ( + // databaseVerisionKey tracks the current database version. + databaseVerisionKey = []byte("DatabaseVersion") + + // headHeaderKey tracks the latest known header's hash. + headHeaderKey = []byte("LastHeader") + + // headBlockKey tracks the latest known full block's hash. + headBlockKey = []byte("LastBlock") + + // headFastBlockKey tracks the latest known incomplete block's hash during fast sync. + headFastBlockKey = []byte("LastFast") + + // fastTrieProgressKey tracks the number of trie entries imported during fast sync. + fastTrieProgressKey = []byte("TrieSync") + + // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). + headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header + headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td + headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash + headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian) + + blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body + blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts + + txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata + bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits + + preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage + configPrefix = []byte("ethereum-config-") // config prefix for the db + + // Chain index prefixes (use `i` + single byte to avoid mixing data types). + BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress + + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) + preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) +) + +const ( + // freezerHeaderTable indicates the name of the freezer header table. + freezerHeaderTable = "headers" + + // freezerHashTable indicates the name of the freezer canonical hash table. + freezerHashTable = "hashes" + + // freezerBodiesTable indicates the name of the freezer block body table. + freezerBodiesTable = "bodies" + + // freezerReceiptTable indicates the name of the freezer receipts table. + freezerReceiptTable = "receipts" + + // freezerDifficultyTable indicates the name of the freezer total difficulty table. + freezerDifficultyTable = "diffs" +) + +// freezerNoSnappy configures whether compression is disabled for the ancient-tables. +// Hashes and difficulties don't compress well. +var freezerNoSnappy = map[string]bool{ + freezerHeaderTable: false, + freezerHashTable: true, + freezerBodiesTable: false, + freezerReceiptTable: false, + freezerDifficultyTable: true, +} + +// LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary +// fields. +type LegacyTxLookupEntry struct { + BlockHash common.Hash + BlockIndex uint64 + Index uint64 +} + +// encodeBlockNumber encodes a block number as big endian uint64 +func encodeBlockNumber(number uint64) []byte { + enc := make([]byte, 8) + binary.BigEndian.PutUint64(enc, number) + return enc +} + +// headerKeyPrefix = headerPrefix + num (uint64 big endian) +func headerKeyPrefix(number uint64) []byte { + return append(headerPrefix, encodeBlockNumber(number)...) +} + +// headerKey = headerPrefix + num (uint64 big endian) + hash +func headerKey(number uint64, hash common.Hash) []byte { + return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) +} + +// headerTDKey = headerPrefix + num (uint64 big endian) + hash + headerTDSuffix +func headerTDKey(number uint64, hash common.Hash) []byte { + return append(headerKey(number, hash), headerTDSuffix...) +} + +// headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix +func headerHashKey(number uint64) []byte { + return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...) +} + +// headerNumberKey = headerNumberPrefix + hash +func headerNumberKey(hash common.Hash) []byte { + return append(headerNumberPrefix, hash.Bytes()...) +} + +// blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash +func blockBodyKey(number uint64, hash common.Hash) []byte { + return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) +} + +// blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash +func blockReceiptsKey(number uint64, hash common.Hash) []byte { + return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) +} + +// txLookupKey = txLookupPrefix + hash +func txLookupKey(hash common.Hash) []byte { + return append(txLookupPrefix, hash.Bytes()...) +} + +// bloomBitsKey = bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash +func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte { + key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...) + + binary.BigEndian.PutUint16(key[1:], uint16(bit)) + binary.BigEndian.PutUint64(key[3:], section) + + return key +} + +// preimageKey = preimagePrefix + hash +func preimageKey(hash common.Hash) []byte { + return append(preimagePrefix, hash.Bytes()...) +} + +// configKey = configPrefix + hash +func configKey(hash common.Hash) []byte { + return append(configPrefix, hash.Bytes()...) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/rawdb/table.go b/vendor/github.com/ethereum/go-ethereum/core/rawdb/table.go new file mode 100644 index 00000000..6610b7f5 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/rawdb/table.go @@ -0,0 +1,204 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "github.com/ethereum/go-ethereum/ethdb" +) + +// table is a wrapper around a database that prefixes each key access with a pre- +// configured string. +type table struct { + db ethdb.Database + prefix string +} + +// NewTable returns a database object that prefixes all keys with a given string. +func NewTable(db ethdb.Database, prefix string) ethdb.Database { + return &table{ + db: db, + prefix: prefix, + } +} + +// Close is a noop to implement the Database interface. +func (t *table) Close() error { + return nil +} + +// Has retrieves if a prefixed version of a key is present in the database. +func (t *table) Has(key []byte) (bool, error) { + return t.db.Has(append([]byte(t.prefix), key...)) +} + +// Get retrieves the given prefixed key if it's present in the database. +func (t *table) Get(key []byte) ([]byte, error) { + return t.db.Get(append([]byte(t.prefix), key...)) +} + +// HasAncient is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) HasAncient(kind string, number uint64) (bool, error) { + return t.db.HasAncient(kind, number) +} + +// Ancient is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) Ancient(kind string, number uint64) ([]byte, error) { + return t.db.Ancient(kind, number) +} + +// Ancients is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) Ancients() (uint64, error) { + return t.db.Ancients() +} + +// AncientSize is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) AncientSize(kind string) (uint64, error) { + return t.db.AncientSize(kind) +} + +// AppendAncient is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error { + return t.db.AppendAncient(number, hash, header, body, receipts, td) +} + +// TruncateAncients is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) TruncateAncients(items uint64) error { + return t.db.TruncateAncients(items) +} + +// Sync is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) Sync() error { + return t.db.Sync() +} + +// Put inserts the given value into the database at a prefixed version of the +// provided key. +func (t *table) Put(key []byte, value []byte) error { + return t.db.Put(append([]byte(t.prefix), key...), value) +} + +// Delete removes the given prefixed key from the database. +func (t *table) Delete(key []byte) error { + return t.db.Delete(append([]byte(t.prefix), key...)) +} + +// NewIterator creates a binary-alphabetical iterator over the entire keyspace +// contained within the database. +func (t *table) NewIterator() ethdb.Iterator { + return t.NewIteratorWithPrefix(nil) +} + +// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of +// database content starting at a particular initial key (or after, if it does +// not exist). +func (t *table) NewIteratorWithStart(start []byte) ethdb.Iterator { + return t.db.NewIteratorWithStart(start) +} + +// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset +// of database content with a particular key prefix. +func (t *table) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator { + return t.db.NewIteratorWithPrefix(append([]byte(t.prefix), prefix...)) +} + +// Stat returns a particular internal stat of the database. +func (t *table) Stat(property string) (string, error) { + return t.db.Stat(property) +} + +// Compact flattens the underlying data store for the given key range. In essence, +// deleted and overwritten versions are discarded, and the data is rearranged to +// reduce the cost of operations needed to access them. +// +// A nil start is treated as a key before all keys in the data store; a nil limit +// is treated as a key after all keys in the data store. If both is nil then it +// will compact entire data store. +func (t *table) Compact(start []byte, limit []byte) error { + // If no start was specified, use the table prefix as the first value + if start == nil { + start = []byte(t.prefix) + } + // If no limit was specified, use the first element not matching the prefix + // as the limit + if limit == nil { + limit = []byte(t.prefix) + for i := len(limit) - 1; i >= 0; i-- { + // Bump the current character, stopping if it doesn't overflow + limit[i]++ + if limit[i] > 0 { + break + } + // Character overflown, proceed to the next or nil if the last + if i == 0 { + limit = nil + } + } + } + // Range correctly calculated based on table prefix, delegate down + return t.db.Compact(start, limit) +} + +// NewBatch creates a write-only database that buffers changes to its host db +// until a final write is called, each operation prefixing all keys with the +// pre-configured string. +func (t *table) NewBatch() ethdb.Batch { + return &tableBatch{t.db.NewBatch(), t.prefix} +} + +// tableBatch is a wrapper around a database batch that prefixes each key access +// with a pre-configured string. +type tableBatch struct { + batch ethdb.Batch + prefix string +} + +// Put inserts the given value into the batch for later committing. +func (b *tableBatch) Put(key, value []byte) error { + return b.batch.Put(append([]byte(b.prefix), key...), value) +} + +// Delete inserts the a key removal into the batch for later committing. +func (b *tableBatch) Delete(key []byte) error { + return b.batch.Delete(append([]byte(b.prefix), key...)) +} + +// ValueSize retrieves the amount of data queued up for writing. +func (b *tableBatch) ValueSize() int { + return b.batch.ValueSize() +} + +// Write flushes any accumulated data to disk. +func (b *tableBatch) Write() error { + return b.batch.Write() +} + +// Reset resets the batch for reuse. +func (b *tableBatch) Reset() { + b.batch.Reset() +} + +// Replay replays the batch contents. +func (b *tableBatch) Replay(w ethdb.KeyValueWriter) error { + return b.batch.Replay(w) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state/database.go b/vendor/github.com/ethereum/go-ethereum/core/state/database.go new file mode 100644 index 00000000..ecc2c134 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state/database.go @@ -0,0 +1,163 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" + lru "github.com/hashicorp/golang-lru" +) + +const ( + // Number of codehash->size associations to keep. + codeSizeCacheSize = 100000 +) + +// Database wraps access to tries and contract code. +type Database interface { + // OpenTrie opens the main account trie. + OpenTrie(root common.Hash) (Trie, error) + + // OpenStorageTrie opens the storage trie of an account. + OpenStorageTrie(addrHash, root common.Hash) (Trie, error) + + // CopyTrie returns an independent copy of the given trie. + CopyTrie(Trie) Trie + + // ContractCode retrieves a particular contract's code. + ContractCode(addrHash, codeHash common.Hash) ([]byte, error) + + // ContractCodeSize retrieves a particular contracts code's size. + ContractCodeSize(addrHash, codeHash common.Hash) (int, error) + + // TrieDB retrieves the low level trie database used for data storage. + TrieDB() *trie.Database +} + +// Trie is a Ethereum Merkle Patricia trie. +type Trie interface { + // GetKey returns the sha3 preimage of a hashed key that was previously used + // to store a value. + // + // TODO(fjl): remove this when SecureTrie is removed + GetKey([]byte) []byte + + // TryGet returns the value for key stored in the trie. The value bytes must + // not be modified by the caller. If a node was not found in the database, a + // trie.MissingNodeError is returned. + TryGet(key []byte) ([]byte, error) + + // TryUpdate associates key with value in the trie. If value has length zero, any + // existing value is deleted from the trie. The value bytes must not be modified + // by the caller while they are stored in the trie. If a node was not found in the + // database, a trie.MissingNodeError is returned. + TryUpdate(key, value []byte) error + + // TryDelete removes any existing value for key from the trie. If a node was not + // found in the database, a trie.MissingNodeError is returned. + TryDelete(key []byte) error + + // Hash returns the root hash of the trie. It does not write to the database and + // can be used even if the trie doesn't have one. + Hash() common.Hash + + // Commit writes all nodes to the trie's memory database, tracking the internal + // and external (for account tries) references. + Commit(onleaf trie.LeafCallback) (common.Hash, error) + + // NodeIterator returns an iterator that returns nodes of the trie. Iteration + // starts at the key after the given start key. + NodeIterator(startKey []byte) trie.NodeIterator + + // Prove constructs a Merkle proof for key. The result contains all encoded nodes + // on the path to the value at key. The value itself is also included in the last + // node and can be retrieved by verifying the proof. + // + // If the trie does not contain a value for key, the returned proof contains all + // nodes of the longest existing prefix of the key (at least the root), ending + // with the node that proves the absence of the key. + Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error +} + +// NewDatabase creates a backing store for state. The returned database is safe for +// concurrent use, but does not retain any recent trie nodes in memory. To keep some +// historical state in memory, use the NewDatabaseWithCache constructor. +func NewDatabase(db ethdb.Database) Database { + return NewDatabaseWithCache(db, 0) +} + +// NewDatabaseWithCache creates a backing store for state. The returned database +// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a +// large memory cache. +func NewDatabaseWithCache(db ethdb.Database, cache int) Database { + csc, _ := lru.New(codeSizeCacheSize) + return &cachingDB{ + db: trie.NewDatabaseWithCache(db, cache), + codeSizeCache: csc, + } +} + +type cachingDB struct { + db *trie.Database + codeSizeCache *lru.Cache +} + +// OpenTrie opens the main account trie at a specific root hash. +func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { + return trie.NewSecure(root, db.db) +} + +// OpenStorageTrie opens the storage trie of an account. +func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) { + return trie.NewSecure(root, db.db) +} + +// CopyTrie returns an independent copy of the given trie. +func (db *cachingDB) CopyTrie(t Trie) Trie { + switch t := t.(type) { + case *trie.SecureTrie: + return t.Copy() + default: + panic(fmt.Errorf("unknown trie type %T", t)) + } +} + +// ContractCode retrieves a particular contract's code. +func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) { + code, err := db.db.Node(codeHash) + if err == nil { + db.codeSizeCache.Add(codeHash, len(code)) + } + return code, err +} + +// ContractCodeSize retrieves a particular contracts code's size. +func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) { + if cached, ok := db.codeSizeCache.Get(codeHash); ok { + return cached.(int), nil + } + code, err := db.ContractCode(addrHash, codeHash) + return len(code), err +} + +// TrieDB retrieves any intermediate trie-node caching layer. +func (db *cachingDB) TrieDB() *trie.Database { + return db.db +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state/state_object.go b/vendor/github.com/ethereum/go-ethereum/core/state/state_object.go new file mode 100644 index 00000000..852c340b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state/state_object.go @@ -0,0 +1,403 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "bytes" + "fmt" + "io" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/rlp" +) + +var emptyCodeHash = crypto.Keccak256(nil) + +type Code []byte + +func (c Code) String() string { + return string(c) //strings.Join(Disassemble(c), " ") +} + +type Storage map[common.Hash]common.Hash + +func (s Storage) String() (str string) { + for key, value := range s { + str += fmt.Sprintf("%X : %X\n", key, value) + } + + return +} + +func (s Storage) Copy() Storage { + cpy := make(Storage) + for key, value := range s { + cpy[key] = value + } + + return cpy +} + +// stateObject represents an Ethereum account which is being modified. +// +// The usage pattern is as follows: +// First you need to obtain a state object. +// Account values can be accessed and modified through the object. +// Finally, call CommitTrie to write the modified storage trie into a database. +type stateObject struct { + address common.Address + addrHash common.Hash // hash of ethereum address of the account + data Account + db *StateDB + + // DB error. + // State objects are used by the consensus core and VM which are + // unable to deal with database-level errors. Any error that occurs + // during a database read is memoized here and will eventually be returned + // by StateDB.Commit. + dbErr error + + // Write caches. + trie Trie // storage trie, which becomes non-nil on first access + code Code // contract bytecode, which gets set when code is loaded + + originStorage Storage // Storage cache of original entries to dedup rewrites + dirtyStorage Storage // Storage entries that need to be flushed to disk + + // Cache flags. + // When an object is marked suicided it will be delete from the trie + // during the "update" phase of the state transition. + dirtyCode bool // true if the code was updated + suicided bool + deleted bool +} + +// empty returns whether the account is considered empty. +func (s *stateObject) empty() bool { + return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) +} + +// Account is the Ethereum consensus representation of accounts. +// These objects are stored in the main account trie. +type Account struct { + Nonce uint64 + Balance *big.Int + Root common.Hash // merkle root of the storage trie + CodeHash []byte +} + +// newObject creates a state object. +func newObject(db *StateDB, address common.Address, data Account) *stateObject { + if data.Balance == nil { + data.Balance = new(big.Int) + } + if data.CodeHash == nil { + data.CodeHash = emptyCodeHash + } + return &stateObject{ + db: db, + address: address, + addrHash: crypto.Keccak256Hash(address[:]), + data: data, + originStorage: make(Storage), + dirtyStorage: make(Storage), + } +} + +// EncodeRLP implements rlp.Encoder. +func (s *stateObject) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, s.data) +} + +// setError remembers the first non-nil error it is called with. +func (s *stateObject) setError(err error) { + if s.dbErr == nil { + s.dbErr = err + } +} + +func (s *stateObject) markSuicided() { + s.suicided = true +} + +func (s *stateObject) touch() { + s.db.journal.append(touchChange{ + account: &s.address, + }) + if s.address == ripemd { + // Explicitly put it in the dirty-cache, which is otherwise generated from + // flattened journals. + s.db.journal.dirty(s.address) + } +} + +func (s *stateObject) getTrie(db Database) Trie { + if s.trie == nil { + var err error + s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root) + if err != nil { + s.trie, _ = db.OpenStorageTrie(s.addrHash, common.Hash{}) + s.setError(fmt.Errorf("can't create storage trie: %v", err)) + } + } + return s.trie +} + +// GetState retrieves a value from the account storage trie. +func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { + // If we have a dirty value for this state entry, return it + value, dirty := s.dirtyStorage[key] + if dirty { + return value + } + // Otherwise return the entry's original value + return s.GetCommittedState(db, key) +} + +// GetCommittedState retrieves a value from the committed account storage trie. +func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { + // If we have the original value cached, return that + value, cached := s.originStorage[key] + if cached { + return value + } + // Track the amount of time wasted on reading the storge trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.db.StorageReads += time.Since(start) }(time.Now()) + } + // Otherwise load the value from the database + enc, err := s.getTrie(db).TryGet(key[:]) + if err != nil { + s.setError(err) + return common.Hash{} + } + if len(enc) > 0 { + _, content, _, err := rlp.Split(enc) + if err != nil { + s.setError(err) + } + value.SetBytes(content) + } + s.originStorage[key] = value + return value +} + +// SetState updates a value in account storage. +func (s *stateObject) SetState(db Database, key, value common.Hash) { + // If the new value is the same as old, don't set + prev := s.GetState(db, key) + if prev == value { + return + } + // New value is different, update and journal the change + s.db.journal.append(storageChange{ + account: &s.address, + key: key, + prevalue: prev, + }) + s.setState(key, value) +} + +func (s *stateObject) setState(key, value common.Hash) { + s.dirtyStorage[key] = value +} + +// updateTrie writes cached storage modifications into the object's storage trie. +func (s *stateObject) updateTrie(db Database) Trie { + // Track the amount of time wasted on updating the storge trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) + } + // Update all the dirty slots in the trie + tr := s.getTrie(db) + for key, value := range s.dirtyStorage { + delete(s.dirtyStorage, key) + + // Skip noop changes, persist actual changes + if value == s.originStorage[key] { + continue + } + s.originStorage[key] = value + + if (value == common.Hash{}) { + s.setError(tr.TryDelete(key[:])) + continue + } + // Encoding []byte cannot fail, ok to ignore the error. + v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + s.setError(tr.TryUpdate(key[:], v)) + } + return tr +} + +// UpdateRoot sets the trie root to the current root hash of +func (s *stateObject) updateRoot(db Database) { + s.updateTrie(db) + + // Track the amount of time wasted on hashing the storge trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now()) + } + s.data.Root = s.trie.Hash() +} + +// CommitTrie the storage trie of the object to db. +// This updates the trie root. +func (s *stateObject) CommitTrie(db Database) error { + s.updateTrie(db) + if s.dbErr != nil { + return s.dbErr + } + // Track the amount of time wasted on committing the storge trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) + } + root, err := s.trie.Commit(nil) + if err == nil { + s.data.Root = root + } + return err +} + +// AddBalance removes amount from c's balance. +// It is used to add funds to the destination account of a transfer. +func (s *stateObject) AddBalance(amount *big.Int) { + // EIP158: We must check emptiness for the objects such that the account + // clearing (0,0,0 objects) can take effect. + if amount.Sign() == 0 { + if s.empty() { + s.touch() + } + + return + } + s.SetBalance(new(big.Int).Add(s.Balance(), amount)) +} + +// SubBalance removes amount from c's balance. +// It is used to remove funds from the origin account of a transfer. +func (s *stateObject) SubBalance(amount *big.Int) { + if amount.Sign() == 0 { + return + } + s.SetBalance(new(big.Int).Sub(s.Balance(), amount)) +} + +func (s *stateObject) SetBalance(amount *big.Int) { + s.db.journal.append(balanceChange{ + account: &s.address, + prev: new(big.Int).Set(s.data.Balance), + }) + s.setBalance(amount) +} + +func (s *stateObject) setBalance(amount *big.Int) { + s.data.Balance = amount +} + +// Return the gas back to the origin. Used by the Virtual machine or Closures +func (s *stateObject) ReturnGas(gas *big.Int) {} + +func (s *stateObject) deepCopy(db *StateDB) *stateObject { + stateObject := newObject(db, s.address, s.data) + if s.trie != nil { + stateObject.trie = db.db.CopyTrie(s.trie) + } + stateObject.code = s.code + stateObject.dirtyStorage = s.dirtyStorage.Copy() + stateObject.originStorage = s.originStorage.Copy() + stateObject.suicided = s.suicided + stateObject.dirtyCode = s.dirtyCode + stateObject.deleted = s.deleted + return stateObject +} + +// +// Attribute accessors +// + +// Returns the address of the contract/account +func (s *stateObject) Address() common.Address { + return s.address +} + +// Code returns the contract code associated with this object, if any. +func (s *stateObject) Code(db Database) []byte { + if s.code != nil { + return s.code + } + if bytes.Equal(s.CodeHash(), emptyCodeHash) { + return nil + } + code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) + if err != nil { + s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) + } + s.code = code + return code +} + +func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { + prevcode := s.Code(s.db.db) + s.db.journal.append(codeChange{ + account: &s.address, + prevhash: s.CodeHash(), + prevcode: prevcode, + }) + s.setCode(codeHash, code) +} + +func (s *stateObject) setCode(codeHash common.Hash, code []byte) { + s.code = code + s.data.CodeHash = codeHash[:] + s.dirtyCode = true +} + +func (s *stateObject) SetNonce(nonce uint64) { + s.db.journal.append(nonceChange{ + account: &s.address, + prev: s.data.Nonce, + }) + s.setNonce(nonce) +} + +func (s *stateObject) setNonce(nonce uint64) { + s.data.Nonce = nonce +} + +func (s *stateObject) CodeHash() []byte { + return s.data.CodeHash +} + +func (s *stateObject) Balance() *big.Int { + return s.data.Balance +} + +func (s *stateObject) Nonce() uint64 { + return s.data.Nonce +} + +// Never called, but must be present to allow stateObject to be used +// as a vm.Account interface that also satisfies the vm.ContractRef +// interface. Interfaces are awesome. +func (s *stateObject) Value() *big.Int { + panic("Value on stateObject should never be called") +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state/statedb.go b/vendor/github.com/ethereum/go-ethereum/core/state/statedb.go new file mode 100644 index 00000000..3bb9862e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state/statedb.go @@ -0,0 +1,728 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package state provides a caching layer atop the Ethereum state trie. +package state + +import ( + "errors" + "fmt" + "math/big" + "sort" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +type revision struct { + id int + journalIndex int +} + +var ( + // emptyRoot is the known root hash of an empty trie. + emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + + // emptyCode is the known hash of the empty EVM bytecode. + emptyCode = crypto.Keccak256Hash(nil) +) + +type proofList [][]byte + +func (n *proofList) Put(key []byte, value []byte) error { + *n = append(*n, value) + return nil +} + +func (n *proofList) Delete(key []byte) error { + panic("not supported") +} + +// StateDBs within the ethereum protocol are used to store anything +// within the merkle trie. StateDBs take care of caching and storing +// nested states. It's the general query interface to retrieve: +// * Contracts +// * Accounts +type StateDB struct { + db Database + trie Trie + + // This map holds 'live' objects, which will get modified while processing a state transition. + stateObjects map[common.Address]*stateObject + stateObjectsDirty map[common.Address]struct{} + + // DB error. + // State objects are used by the consensus core and VM which are + // unable to deal with database-level errors. Any error that occurs + // during a database read is memoized here and will eventually be returned + // by StateDB.Commit. + dbErr error + + // The refund counter, also used by state transitioning. + refund uint64 + + thash, bhash common.Hash + txIndex int + logs map[common.Hash][]*types.Log + logSize uint + + preimages map[common.Hash][]byte + + // Journal of state modifications. This is the backbone of + // Snapshot and RevertToSnapshot. + journal *journal + validRevisions []revision + nextRevisionId int + + // Measurements gathered during execution for debugging purposes + AccountReads time.Duration + AccountHashes time.Duration + AccountUpdates time.Duration + AccountCommits time.Duration + StorageReads time.Duration + StorageHashes time.Duration + StorageUpdates time.Duration + StorageCommits time.Duration +} + +// Create a new state from a given trie. +func New(root common.Hash, db Database) (*StateDB, error) { + tr, err := db.OpenTrie(root) + if err != nil { + return nil, err + } + return &StateDB{ + db: db, + trie: tr, + stateObjects: make(map[common.Address]*stateObject), + stateObjectsDirty: make(map[common.Address]struct{}), + logs: make(map[common.Hash][]*types.Log), + preimages: make(map[common.Hash][]byte), + journal: newJournal(), + }, nil +} + +// setError remembers the first non-nil error it is called with. +func (self *StateDB) setError(err error) { + if self.dbErr == nil { + self.dbErr = err + } +} + +func (self *StateDB) Error() error { + return self.dbErr +} + +// Reset clears out all ephemeral state objects from the state db, but keeps +// the underlying state trie to avoid reloading data for the next operations. +func (self *StateDB) Reset(root common.Hash) error { + tr, err := self.db.OpenTrie(root) + if err != nil { + return err + } + self.trie = tr + self.stateObjects = make(map[common.Address]*stateObject) + self.stateObjectsDirty = make(map[common.Address]struct{}) + self.thash = common.Hash{} + self.bhash = common.Hash{} + self.txIndex = 0 + self.logs = make(map[common.Hash][]*types.Log) + self.logSize = 0 + self.preimages = make(map[common.Hash][]byte) + self.clearJournalAndRefund() + return nil +} + +func (self *StateDB) AddLog(log *types.Log) { + self.journal.append(addLogChange{txhash: self.thash}) + + log.TxHash = self.thash + log.BlockHash = self.bhash + log.TxIndex = uint(self.txIndex) + log.Index = self.logSize + self.logs[self.thash] = append(self.logs[self.thash], log) + self.logSize++ +} + +func (self *StateDB) GetLogs(hash common.Hash) []*types.Log { + return self.logs[hash] +} + +func (self *StateDB) Logs() []*types.Log { + var logs []*types.Log + for _, lgs := range self.logs { + logs = append(logs, lgs...) + } + return logs +} + +// AddPreimage records a SHA3 preimage seen by the VM. +func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) { + if _, ok := self.preimages[hash]; !ok { + self.journal.append(addPreimageChange{hash: hash}) + pi := make([]byte, len(preimage)) + copy(pi, preimage) + self.preimages[hash] = pi + } +} + +// Preimages returns a list of SHA3 preimages that have been submitted. +func (self *StateDB) Preimages() map[common.Hash][]byte { + return self.preimages +} + +// AddRefund adds gas to the refund counter +func (self *StateDB) AddRefund(gas uint64) { + self.journal.append(refundChange{prev: self.refund}) + self.refund += gas +} + +// SubRefund removes gas from the refund counter. +// This method will panic if the refund counter goes below zero +func (self *StateDB) SubRefund(gas uint64) { + self.journal.append(refundChange{prev: self.refund}) + if gas > self.refund { + panic("Refund counter below zero") + } + self.refund -= gas +} + +// Exist reports whether the given account address exists in the state. +// Notably this also returns true for suicided accounts. +func (self *StateDB) Exist(addr common.Address) bool { + return self.getStateObject(addr) != nil +} + +// Empty returns whether the state object is either non-existent +// or empty according to the EIP161 specification (balance = nonce = code = 0) +func (self *StateDB) Empty(addr common.Address) bool { + so := self.getStateObject(addr) + return so == nil || so.empty() +} + +// Retrieve the balance from the given address or 0 if object not found +func (self *StateDB) GetBalance(addr common.Address) *big.Int { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.Balance() + } + return common.Big0 +} + +func (self *StateDB) GetNonce(addr common.Address) uint64 { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.Nonce() + } + + return 0 +} + +// TxIndex returns the current transaction index set by Prepare. +func (self *StateDB) TxIndex() int { + return self.txIndex +} + +// BlockHash returns the current block hash set by Prepare. +func (self *StateDB) BlockHash() common.Hash { + return self.bhash +} + +func (self *StateDB) GetCode(addr common.Address) []byte { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.Code(self.db) + } + return nil +} + +func (self *StateDB) GetCodeSize(addr common.Address) int { + stateObject := self.getStateObject(addr) + if stateObject == nil { + return 0 + } + if stateObject.code != nil { + return len(stateObject.code) + } + size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) + if err != nil { + self.setError(err) + } + return size +} + +func (self *StateDB) GetCodeHash(addr common.Address) common.Hash { + stateObject := self.getStateObject(addr) + if stateObject == nil { + return common.Hash{} + } + return common.BytesToHash(stateObject.CodeHash()) +} + +// GetState retrieves a value from the given account's storage trie. +func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.GetState(self.db, hash) + } + return common.Hash{} +} + +// GetProof returns the MerkleProof for a given Account +func (self *StateDB) GetProof(a common.Address) ([][]byte, error) { + var proof proofList + err := self.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof) + return [][]byte(proof), err +} + +// GetProof returns the StorageProof for given key +func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) { + var proof proofList + trie := self.StorageTrie(a) + if trie == nil { + return proof, errors.New("storage trie for requested address does not exist") + } + err := trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof) + return [][]byte(proof), err +} + +// GetCommittedState retrieves a value from the given account's committed storage trie. +func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.GetCommittedState(self.db, hash) + } + return common.Hash{} +} + +// Database retrieves the low level database supporting the lower level trie ops. +func (self *StateDB) Database() Database { + return self.db +} + +// StorageTrie returns the storage trie of an account. +// The return value is a copy and is nil for non-existent accounts. +func (self *StateDB) StorageTrie(addr common.Address) Trie { + stateObject := self.getStateObject(addr) + if stateObject == nil { + return nil + } + cpy := stateObject.deepCopy(self) + return cpy.updateTrie(self.db) +} + +func (self *StateDB) HasSuicided(addr common.Address) bool { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.suicided + } + return false +} + +/* + * SETTERS + */ + +// AddBalance adds amount to the account associated with addr. +func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.AddBalance(amount) + } +} + +// SubBalance subtracts amount from the account associated with addr. +func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SubBalance(amount) + } +} + +func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetBalance(amount) + } +} + +func (self *StateDB) SetNonce(addr common.Address, nonce uint64) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetNonce(nonce) + } +} + +func (self *StateDB) SetCode(addr common.Address, code []byte) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetCode(crypto.Keccak256Hash(code), code) + } +} + +func (self *StateDB) SetState(addr common.Address, key, value common.Hash) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetState(self.db, key, value) + } +} + +// Suicide marks the given account as suicided. +// This clears the account balance. +// +// The account's state object is still available until the state is committed, +// getStateObject will return a non-nil account after Suicide. +func (self *StateDB) Suicide(addr common.Address) bool { + stateObject := self.getStateObject(addr) + if stateObject == nil { + return false + } + self.journal.append(suicideChange{ + account: &addr, + prev: stateObject.suicided, + prevbalance: new(big.Int).Set(stateObject.Balance()), + }) + stateObject.markSuicided() + stateObject.data.Balance = new(big.Int) + + return true +} + +// +// Setting, updating & deleting state object methods. +// + +// updateStateObject writes the given object to the trie. +func (s *StateDB) updateStateObject(stateObject *stateObject) { + // Track the amount of time wasted on updating the account from the trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) + } + // Encode the account and update the account trie + addr := stateObject.Address() + + data, err := rlp.EncodeToBytes(stateObject) + if err != nil { + panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err)) + } + s.setError(s.trie.TryUpdate(addr[:], data)) +} + +// deleteStateObject removes the given object from the state trie. +func (s *StateDB) deleteStateObject(stateObject *stateObject) { + // Track the amount of time wasted on deleting the account from the trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) + } + // Delete the account from the trie + stateObject.deleted = true + + addr := stateObject.Address() + s.setError(s.trie.TryDelete(addr[:])) +} + +// Retrieve a state object given by the address. Returns nil if not found. +func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) { + // Prefer live objects + if obj := s.stateObjects[addr]; obj != nil { + if obj.deleted { + return nil + } + return obj + } + // Track the amount of time wasted on loading the object from the database + if metrics.EnabledExpensive { + defer func(start time.Time) { s.AccountReads += time.Since(start) }(time.Now()) + } + // Load the object from the database + enc, err := s.trie.TryGet(addr[:]) + if len(enc) == 0 { + s.setError(err) + return nil + } + var data Account + if err := rlp.DecodeBytes(enc, &data); err != nil { + log.Error("Failed to decode state object", "addr", addr, "err", err) + return nil + } + // Insert into the live set + obj := newObject(s, addr, data) + s.setStateObject(obj) + return obj +} + +func (self *StateDB) setStateObject(object *stateObject) { + self.stateObjects[object.Address()] = object +} + +// Retrieve a state object or create a new state object if nil. +func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { + stateObject := self.getStateObject(addr) + if stateObject == nil || stateObject.deleted { + stateObject, _ = self.createObject(addr) + } + return stateObject +} + +// createObject creates a new state object. If there is an existing account with +// the given address, it is overwritten and returned as the second return value. +func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { + prev = self.getStateObject(addr) + newobj = newObject(self, addr, Account{}) + newobj.setNonce(0) // sets the object to dirty + if prev == nil { + self.journal.append(createObjectChange{account: &addr}) + } else { + self.journal.append(resetObjectChange{prev: prev}) + } + self.setStateObject(newobj) + return newobj, prev +} + +// CreateAccount explicitly creates a state object. If a state object with the address +// already exists the balance is carried over to the new account. +// +// CreateAccount is called during the EVM CREATE operation. The situation might arise that +// a contract does the following: +// +// 1. sends funds to sha(account ++ (nonce + 1)) +// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) +// +// Carrying over the balance ensures that Ether doesn't disappear. +func (self *StateDB) CreateAccount(addr common.Address) { + newObj, prev := self.createObject(addr) + if prev != nil { + newObj.setBalance(prev.data.Balance) + } +} + +func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error { + so := db.getStateObject(addr) + if so == nil { + return nil + } + it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil)) + + for it.Next() { + key := common.BytesToHash(db.trie.GetKey(it.Key)) + if value, dirty := so.dirtyStorage[key]; dirty { + if !cb(key, value) { + return nil + } + continue + } + + if len(it.Value) > 0 { + _, content, _, err := rlp.Split(it.Value) + if err != nil { + return err + } + if !cb(key, common.BytesToHash(content)) { + return nil + } + } + } + return nil +} + +// Copy creates a deep, independent copy of the state. +// Snapshots of the copied state cannot be applied to the copy. +func (self *StateDB) Copy() *StateDB { + // Copy all the basic fields, initialize the memory ones + state := &StateDB{ + db: self.db, + trie: self.db.CopyTrie(self.trie), + stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)), + stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)), + refund: self.refund, + logs: make(map[common.Hash][]*types.Log, len(self.logs)), + logSize: self.logSize, + preimages: make(map[common.Hash][]byte, len(self.preimages)), + journal: newJournal(), + } + // Copy the dirty states, logs, and preimages + for addr := range self.journal.dirties { + // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), + // and in the Finalise-method, there is a case where an object is in the journal but not + // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for + // nil + if object, exist := self.stateObjects[addr]; exist { + state.stateObjects[addr] = object.deepCopy(state) + state.stateObjectsDirty[addr] = struct{}{} + } + } + // Above, we don't copy the actual journal. This means that if the copy is copied, the + // loop above will be a no-op, since the copy's journal is empty. + // Thus, here we iterate over stateObjects, to enable copies of copies + for addr := range self.stateObjectsDirty { + if _, exist := state.stateObjects[addr]; !exist { + state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state) + state.stateObjectsDirty[addr] = struct{}{} + } + } + for hash, logs := range self.logs { + cpy := make([]*types.Log, len(logs)) + for i, l := range logs { + cpy[i] = new(types.Log) + *cpy[i] = *l + } + state.logs[hash] = cpy + } + for hash, preimage := range self.preimages { + state.preimages[hash] = preimage + } + return state +} + +// Snapshot returns an identifier for the current revision of the state. +func (self *StateDB) Snapshot() int { + id := self.nextRevisionId + self.nextRevisionId++ + self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()}) + return id +} + +// RevertToSnapshot reverts all state changes made since the given revision. +func (self *StateDB) RevertToSnapshot(revid int) { + // Find the snapshot in the stack of valid snapshots. + idx := sort.Search(len(self.validRevisions), func(i int) bool { + return self.validRevisions[i].id >= revid + }) + if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid { + panic(fmt.Errorf("revision id %v cannot be reverted", revid)) + } + snapshot := self.validRevisions[idx].journalIndex + + // Replay the journal to undo changes and remove invalidated snapshots + self.journal.revert(self, snapshot) + self.validRevisions = self.validRevisions[:idx] +} + +// GetRefund returns the current value of the refund counter. +func (self *StateDB) GetRefund() uint64 { + return self.refund +} + +// Finalise finalises the state by removing the self destructed objects +// and clears the journal as well as the refunds. +func (s *StateDB) Finalise(deleteEmptyObjects bool) { + for addr := range s.journal.dirties { + stateObject, exist := s.stateObjects[addr] + if !exist { + // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 + // That tx goes out of gas, and although the notion of 'touched' does not exist there, the + // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, + // it will persist in the journal even though the journal is reverted. In this special circumstance, + // it may exist in `s.journal.dirties` but not in `s.stateObjects`. + // Thus, we can safely ignore it here + continue + } + + if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { + s.deleteStateObject(stateObject) + } else { + stateObject.updateRoot(s.db) + s.updateStateObject(stateObject) + } + s.stateObjectsDirty[addr] = struct{}{} + } + // Invalidate journal because reverting across transactions is not allowed. + s.clearJournalAndRefund() +} + +// IntermediateRoot computes the current root hash of the state trie. +// It is called in between transactions to get the root hash that +// goes into transaction receipts. +func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { + s.Finalise(deleteEmptyObjects) + + // Track the amount of time wasted on hashing the account trie + if metrics.EnabledExpensive { + defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) + } + return s.trie.Hash() +} + +// Prepare sets the current transaction hash and index and block hash which is +// used when the EVM emits new state logs. +func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { + self.thash = thash + self.bhash = bhash + self.txIndex = ti +} + +func (s *StateDB) clearJournalAndRefund() { + s.journal = newJournal() + s.validRevisions = s.validRevisions[:0] + s.refund = 0 +} + +// Commit writes the state to the underlying in-memory trie database. +func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) { + defer s.clearJournalAndRefund() + + for addr := range s.journal.dirties { + s.stateObjectsDirty[addr] = struct{}{} + } + // Commit objects to the trie, measuring the elapsed time + for addr, stateObject := range s.stateObjects { + _, isDirty := s.stateObjectsDirty[addr] + switch { + case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()): + // If the object has been removed, don't bother syncing it + // and just mark it for deletion in the trie. + s.deleteStateObject(stateObject) + case isDirty: + // Write any contract code associated with the state object + if stateObject.code != nil && stateObject.dirtyCode { + s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code) + stateObject.dirtyCode = false + } + // Write any storage changes in the state object to its storage trie. + if err := stateObject.CommitTrie(s.db); err != nil { + return common.Hash{}, err + } + // Update the object in the main account trie. + s.updateStateObject(stateObject) + } + delete(s.stateObjectsDirty, addr) + } + // Write the account trie changes, measuing the amount of wasted time + if metrics.EnabledExpensive { + defer func(start time.Time) { s.AccountCommits += time.Since(start) }(time.Now()) + } + root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error { + var account Account + if err := rlp.DecodeBytes(leaf, &account); err != nil { + return nil + } + if account.Root != emptyRoot { + s.db.TrieDB().Reference(account.Root, parent) + } + code := common.BytesToHash(account.CodeHash) + if code != emptyCode { + s.db.TrieDB().Reference(code, parent) + } + return nil + }) + return root, err +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state/sync.go b/vendor/github.com/ethereum/go-ethereum/core/state/sync.go new file mode 100644 index 00000000..ef793052 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state/sync.go @@ -0,0 +1,42 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +// NewStateSync create a new state trie download scheduler. +func NewStateSync(root common.Hash, database ethdb.KeyValueReader, bloom *trie.SyncBloom) *trie.Sync { + var syncer *trie.Sync + callback := func(leaf []byte, parent common.Hash) error { + var obj Account + if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil { + return err + } + syncer.AddSubTrie(obj.Root, 64, parent, nil) + syncer.AddRawEntry(common.BytesToHash(obj.CodeHash), 64, parent) + return nil + } + syncer = trie.NewSync(root, database, callback, bloom) + return syncer +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state_prefetcher.go b/vendor/github.com/ethereum/go-ethereum/core/state_prefetcher.go new file mode 100644 index 00000000..cb85a05b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state_prefetcher.go @@ -0,0 +1,85 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "sync/atomic" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" +) + +// statePrefetcher is a basic Prefetcher, which blindly executes a block on top +// of an arbitrary state with the goal of prefetching potentially useful state +// data from disk before the main block processor start executing. +type statePrefetcher struct { + config *params.ChainConfig // Chain configuration options + bc *BlockChain // Canonical block chain + engine consensus.Engine // Consensus engine used for block rewards +} + +// newStatePrefetcher initialises a new statePrefetcher. +func newStatePrefetcher(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *statePrefetcher { + return &statePrefetcher{ + config: config, + bc: bc, + engine: engine, + } +} + +// Prefetch processes the state changes according to the Ethereum rules by running +// the transaction messages using the statedb, but any changes are discarded. The +// only goal is to pre-cache transaction signatures and state trie nodes. +func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *uint32) { + var ( + header = block.Header() + gaspool = new(GasPool).AddGas(block.GasLimit()) + ) + // Iterate over and process the individual transactions + for i, tx := range block.Transactions() { + // If block precaching was interrupted, abort + if interrupt != nil && atomic.LoadUint32(interrupt) == 1 { + return + } + // Block precaching permitted to continue, execute the transaction + statedb.Prepare(tx.Hash(), block.Hash(), i) + if err := precacheTransaction(p.config, p.bc, nil, gaspool, statedb, header, tx, cfg); err != nil { + return // Ugh, something went horribly wrong, bail out + } + } +} + +// precacheTransaction attempts to apply a transaction to the given state database +// and uses the input parameters for its environment. The goal is not to execute +// the transaction successfully, rather to warm up touched data slots. +func precacheTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gaspool *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, cfg vm.Config) error { + // Convert the transaction into an executable message and pre-cache its sender + msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) + if err != nil { + return err + } + // Create the EVM and execute the transaction + context := NewEVMContext(msg, header, bc, author) + vm := vm.NewEVM(context, statedb, config, cfg) + + _, _, _, err = ApplyMessage(vm, msg, gaspool) + return err +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/state_processor.go b/vendor/github.com/ethereum/go-ethereum/core/state_processor.go new file mode 100644 index 00000000..bed6a073 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/state_processor.go @@ -0,0 +1,129 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +// StateProcessor is a basic Processor, which takes care of transitioning +// state from one point to another. +// +// StateProcessor implements Processor. +type StateProcessor struct { + config *params.ChainConfig // Chain configuration options + bc *BlockChain // Canonical block chain + engine consensus.Engine // Consensus engine used for block rewards +} + +// NewStateProcessor initialises a new StateProcessor. +func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { + return &StateProcessor{ + config: config, + bc: bc, + engine: engine, + } +} + +// Process processes the state changes according to the Ethereum rules by running +// the transaction messages using the statedb and applying any rewards to both +// the processor (coinbase) and any included uncles. +// +// Process returns the receipts and logs accumulated during the process and +// returns the amount of gas that was used in the process. If any of the +// transactions failed to execute due to insufficient gas it will return an error. +func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { + var ( + receipts types.Receipts + usedGas = new(uint64) + header = block.Header() + allLogs []*types.Log + gp = new(GasPool).AddGas(block.GasLimit()) + ) + // Mutate the block and state according to any hard-fork specs + if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { + misc.ApplyDAOHardFork(statedb) + } + // Iterate over and process the individual transactions + for i, tx := range block.Transactions() { + statedb.Prepare(tx.Hash(), block.Hash(), i) + receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) + if err != nil { + return nil, nil, 0, err + } + receipts = append(receipts, receipt) + allLogs = append(allLogs, receipt.Logs...) + } + // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) + p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) + + return receipts, allLogs, *usedGas, nil +} + +// ApplyTransaction attempts to apply a transaction to the given state database +// and uses the input parameters for its environment. It returns the receipt +// for the transaction, gas used and an error if the transaction failed, +// indicating the block was invalid. +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { + msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) + if err != nil { + return nil, 0, err + } + // Create a new context to be used in the EVM environment + context := NewEVMContext(msg, header, bc, author) + // Create a new environment which holds all relevant information + // about the transaction and calling mechanisms. + vmenv := vm.NewEVM(context, statedb, config, cfg) + // Apply the transaction to the current state (included in the env) + _, gas, failed, err := ApplyMessage(vmenv, msg, gp) + if err != nil { + return nil, 0, err + } + // Update the state with pending changes + var root []byte + if config.IsByzantium(header.Number) { + statedb.Finalise(true) + } else { + root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + } + *usedGas += gas + + // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx + // based on the eip phase, we're passing whether the root touch-delete accounts. + receipt := types.NewReceipt(root, failed, *usedGas) + receipt.TxHash = tx.Hash() + receipt.GasUsed = gas + // if the transaction created a contract, store the creation address in the receipt. + if msg.To() == nil { + receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) + } + // Set the receipt logs and create a bloom for filtering + receipt.Logs = statedb.GetLogs(tx.Hash()) + receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + receipt.BlockHash = statedb.BlockHash() + receipt.BlockNumber = header.Number + receipt.TransactionIndex = uint(statedb.TxIndex()) + + return receipt, gas, err +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/tx_list.go b/vendor/github.com/ethereum/go-ethereum/core/tx_list.go new file mode 100644 index 00000000..75bfdaed --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/tx_list.go @@ -0,0 +1,520 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "container/heap" + "math" + "math/big" + "sort" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for +// retrieving sorted transactions from the possibly gapped future queue. +type nonceHeap []uint64 + +func (h nonceHeap) Len() int { return len(h) } +func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] } +func (h nonceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *nonceHeap) Push(x interface{}) { + *h = append(*h, x.(uint64)) +} + +func (h *nonceHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// txSortedMap is a nonce->transaction hash map with a heap based index to allow +// iterating over the contents in a nonce-incrementing way. +type txSortedMap struct { + items map[uint64]*types.Transaction // Hash map storing the transaction data + index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) + cache types.Transactions // Cache of the transactions already sorted +} + +// newTxSortedMap creates a new nonce-sorted transaction map. +func newTxSortedMap() *txSortedMap { + return &txSortedMap{ + items: make(map[uint64]*types.Transaction), + index: new(nonceHeap), + } +} + +// Get retrieves the current transactions associated with the given nonce. +func (m *txSortedMap) Get(nonce uint64) *types.Transaction { + return m.items[nonce] +} + +// Put inserts a new transaction into the map, also updating the map's nonce +// index. If a transaction already exists with the same nonce, it's overwritten. +func (m *txSortedMap) Put(tx *types.Transaction) { + nonce := tx.Nonce() + if m.items[nonce] == nil { + heap.Push(m.index, nonce) + } + m.items[nonce], m.cache = tx, nil +} + +// Forward removes all transactions from the map with a nonce lower than the +// provided threshold. Every removed transaction is returned for any post-removal +// maintenance. +func (m *txSortedMap) Forward(threshold uint64) types.Transactions { + var removed types.Transactions + + // Pop off heap items until the threshold is reached + for m.index.Len() > 0 && (*m.index)[0] < threshold { + nonce := heap.Pop(m.index).(uint64) + removed = append(removed, m.items[nonce]) + delete(m.items, nonce) + } + // If we had a cached order, shift the front + if m.cache != nil { + m.cache = m.cache[len(removed):] + } + return removed +} + +// Filter iterates over the list of transactions and removes all of them for which +// the specified function evaluates to true. +func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { + var removed types.Transactions + + // Collect all the transactions to filter out + for nonce, tx := range m.items { + if filter(tx) { + removed = append(removed, tx) + delete(m.items, nonce) + } + } + // If transactions were removed, the heap and cache are ruined + if len(removed) > 0 { + *m.index = make([]uint64, 0, len(m.items)) + for nonce := range m.items { + *m.index = append(*m.index, nonce) + } + heap.Init(m.index) + + m.cache = nil + } + return removed +} + +// Cap places a hard limit on the number of items, returning all transactions +// exceeding that limit. +func (m *txSortedMap) Cap(threshold int) types.Transactions { + // Short circuit if the number of items is under the limit + if len(m.items) <= threshold { + return nil + } + // Otherwise gather and drop the highest nonce'd transactions + var drops types.Transactions + + sort.Sort(*m.index) + for size := len(m.items); size > threshold; size-- { + drops = append(drops, m.items[(*m.index)[size-1]]) + delete(m.items, (*m.index)[size-1]) + } + *m.index = (*m.index)[:threshold] + heap.Init(m.index) + + // If we had a cache, shift the back + if m.cache != nil { + m.cache = m.cache[:len(m.cache)-len(drops)] + } + return drops +} + +// Remove deletes a transaction from the maintained map, returning whether the +// transaction was found. +func (m *txSortedMap) Remove(nonce uint64) bool { + // Short circuit if no transaction is present + _, ok := m.items[nonce] + if !ok { + return false + } + // Otherwise delete the transaction and fix the heap index + for i := 0; i < m.index.Len(); i++ { + if (*m.index)[i] == nonce { + heap.Remove(m.index, i) + break + } + } + delete(m.items, nonce) + m.cache = nil + + return true +} + +// Ready retrieves a sequentially increasing list of transactions starting at the +// provided nonce that is ready for processing. The returned transactions will be +// removed from the list. +// +// Note, all transactions with nonces lower than start will also be returned to +// prevent getting into and invalid state. This is not something that should ever +// happen but better to be self correcting than failing! +func (m *txSortedMap) Ready(start uint64) types.Transactions { + // Short circuit if no transactions are available + if m.index.Len() == 0 || (*m.index)[0] > start { + return nil + } + // Otherwise start accumulating incremental transactions + var ready types.Transactions + for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ { + ready = append(ready, m.items[next]) + delete(m.items, next) + heap.Pop(m.index) + } + m.cache = nil + + return ready +} + +// Len returns the length of the transaction map. +func (m *txSortedMap) Len() int { + return len(m.items) +} + +// Flatten creates a nonce-sorted slice of transactions based on the loosely +// sorted internal representation. The result of the sorting is cached in case +// it's requested again before any modifications are made to the contents. +func (m *txSortedMap) Flatten() types.Transactions { + // If the sorting was not cached yet, create and cache it + if m.cache == nil { + m.cache = make(types.Transactions, 0, len(m.items)) + for _, tx := range m.items { + m.cache = append(m.cache, tx) + } + sort.Sort(types.TxByNonce(m.cache)) + } + // Copy the cache to prevent accidental modifications + txs := make(types.Transactions, len(m.cache)) + copy(txs, m.cache) + return txs +} + +// txList is a "list" of transactions belonging to an account, sorted by account +// nonce. The same type can be used both for storing contiguous transactions for +// the executable/pending queue; and for storing gapped transactions for the non- +// executable/future queue, with minor behavioral changes. +type txList struct { + strict bool // Whether nonces are strictly continuous or not + txs *txSortedMap // Heap indexed sorted hash map of the transactions + + costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) + gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) +} + +// newTxList create a new transaction list for maintaining nonce-indexable fast, +// gapped, sortable transaction lists. +func newTxList(strict bool) *txList { + return &txList{ + strict: strict, + txs: newTxSortedMap(), + costcap: new(big.Int), + } +} + +// Overlaps returns whether the transaction specified has the same nonce as one +// already contained within the list. +func (l *txList) Overlaps(tx *types.Transaction) bool { + return l.txs.Get(tx.Nonce()) != nil +} + +// Add tries to insert a new transaction into the list, returning whether the +// transaction was accepted, and if yes, any previous transaction it replaced. +// +// If the new transaction is accepted into the list, the lists' cost and gas +// thresholds are also potentially updated. +func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { + // If there's an older better transaction, abort + old := l.txs.Get(tx.Nonce()) + if old != nil { + threshold := new(big.Int).Div(new(big.Int).Mul(old.GasPrice(), big.NewInt(100+int64(priceBump))), big.NewInt(100)) + // Have to ensure that the new gas price is higher than the old gas + // price as well as checking the percentage threshold to ensure that + // this is accurate for low (Wei-level) gas price replacements + if old.GasPrice().Cmp(tx.GasPrice()) >= 0 || threshold.Cmp(tx.GasPrice()) > 0 { + return false, nil + } + } + // Otherwise overwrite the old transaction with the current one + l.txs.Put(tx) + if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 { + l.costcap = cost + } + if gas := tx.Gas(); l.gascap < gas { + l.gascap = gas + } + return true, old +} + +// Forward removes all transactions from the list with a nonce lower than the +// provided threshold. Every removed transaction is returned for any post-removal +// maintenance. +func (l *txList) Forward(threshold uint64) types.Transactions { + return l.txs.Forward(threshold) +} + +// Filter removes all transactions from the list with a cost or gas limit higher +// than the provided thresholds. Every removed transaction is returned for any +// post-removal maintenance. Strict-mode invalidated transactions are also +// returned. +// +// This method uses the cached costcap and gascap to quickly decide if there's even +// a point in calculating all the costs or if the balance covers all. If the threshold +// is lower than the costgas cap, the caps will be reset to a new high after removing +// the newly invalidated transactions. +func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) { + // If all transactions are below the threshold, short circuit + if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { + return nil, nil + } + l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds + l.gascap = gasLimit + + // Filter out all the transactions above the account's funds + removed := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Cost().Cmp(costLimit) > 0 || tx.Gas() > gasLimit }) + + // If the list was strict, filter anything above the lowest nonce + var invalids types.Transactions + + if l.strict && len(removed) > 0 { + lowest := uint64(math.MaxUint64) + for _, tx := range removed { + if nonce := tx.Nonce(); lowest > nonce { + lowest = nonce + } + } + invalids = l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest }) + } + return removed, invalids +} + +// Cap places a hard limit on the number of items, returning all transactions +// exceeding that limit. +func (l *txList) Cap(threshold int) types.Transactions { + return l.txs.Cap(threshold) +} + +// Remove deletes a transaction from the maintained list, returning whether the +// transaction was found, and also returning any transaction invalidated due to +// the deletion (strict mode only). +func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { + // Remove the transaction from the set + nonce := tx.Nonce() + if removed := l.txs.Remove(nonce); !removed { + return false, nil + } + // In strict mode, filter out non-executable transactions + if l.strict { + return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce }) + } + return true, nil +} + +// Ready retrieves a sequentially increasing list of transactions starting at the +// provided nonce that is ready for processing. The returned transactions will be +// removed from the list. +// +// Note, all transactions with nonces lower than start will also be returned to +// prevent getting into and invalid state. This is not something that should ever +// happen but better to be self correcting than failing! +func (l *txList) Ready(start uint64) types.Transactions { + return l.txs.Ready(start) +} + +// Len returns the length of the transaction list. +func (l *txList) Len() int { + return l.txs.Len() +} + +// Empty returns whether the list of transactions is empty or not. +func (l *txList) Empty() bool { + return l.Len() == 0 +} + +// Flatten creates a nonce-sorted slice of transactions based on the loosely +// sorted internal representation. The result of the sorting is cached in case +// it's requested again before any modifications are made to the contents. +func (l *txList) Flatten() types.Transactions { + return l.txs.Flatten() +} + +// priceHeap is a heap.Interface implementation over transactions for retrieving +// price-sorted transactions to discard when the pool fills up. +type priceHeap []*types.Transaction + +func (h priceHeap) Len() int { return len(h) } +func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h priceHeap) Less(i, j int) bool { + // Sort primarily by price, returning the cheaper one + switch h[i].GasPrice().Cmp(h[j].GasPrice()) { + case -1: + return true + case 1: + return false + } + // If the prices match, stabilize via nonces (high nonce is worse) + return h[i].Nonce() > h[j].Nonce() +} + +func (h *priceHeap) Push(x interface{}) { + *h = append(*h, x.(*types.Transaction)) +} + +func (h *priceHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// txPricedList is a price-sorted heap to allow operating on transactions pool +// contents in a price-incrementing way. +type txPricedList struct { + all *txLookup // Pointer to the map of all transactions + items *priceHeap // Heap of prices of all the stored transactions + stales int // Number of stale price points to (re-heap trigger) +} + +// newTxPricedList creates a new price-sorted transaction heap. +func newTxPricedList(all *txLookup) *txPricedList { + return &txPricedList{ + all: all, + items: new(priceHeap), + } +} + +// Put inserts a new transaction into the heap. +func (l *txPricedList) Put(tx *types.Transaction) { + heap.Push(l.items, tx) +} + +// Removed notifies the prices transaction list that an old transaction dropped +// from the pool. The list will just keep a counter of stale objects and update +// the heap if a large enough ratio of transactions go stale. +func (l *txPricedList) Removed(count int) { + // Bump the stale counter, but exit if still too low (< 25%) + l.stales += count + if l.stales <= len(*l.items)/4 { + return + } + // Seems we've reached a critical number of stale transactions, reheap + reheap := make(priceHeap, 0, l.all.Count()) + + l.stales, l.items = 0, &reheap + l.all.Range(func(hash common.Hash, tx *types.Transaction) bool { + *l.items = append(*l.items, tx) + return true + }) + heap.Init(l.items) +} + +// Cap finds all the transactions below the given price threshold, drops them +// from the priced list and returns them for further removal from the entire pool. +func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transactions { + drop := make(types.Transactions, 0, 128) // Remote underpriced transactions to drop + save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep + + for len(*l.items) > 0 { + // Discard stale transactions if found during cleanup + tx := heap.Pop(l.items).(*types.Transaction) + if l.all.Get(tx.Hash()) == nil { + l.stales-- + continue + } + // Stop the discards if we've reached the threshold + if tx.GasPrice().Cmp(threshold) >= 0 { + save = append(save, tx) + break + } + // Non stale transaction found, discard unless local + if local.containsTx(tx) { + save = append(save, tx) + } else { + drop = append(drop, tx) + } + } + for _, tx := range save { + heap.Push(l.items, tx) + } + return drop +} + +// Underpriced checks whether a transaction is cheaper than (or as cheap as) the +// lowest priced transaction currently being tracked. +func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) bool { + // Local transactions cannot be underpriced + if local.containsTx(tx) { + return false + } + // Discard stale price points if found at the heap start + for len(*l.items) > 0 { + head := []*types.Transaction(*l.items)[0] + if l.all.Get(head.Hash()) == nil { + l.stales-- + heap.Pop(l.items) + continue + } + break + } + // Check if the transaction is underpriced or not + if len(*l.items) == 0 { + log.Error("Pricing query for empty pool") // This cannot happen, print to catch programming errors + return false + } + cheapest := []*types.Transaction(*l.items)[0] + return cheapest.GasPrice().Cmp(tx.GasPrice()) >= 0 +} + +// Discard finds a number of most underpriced transactions, removes them from the +// priced list and returns them for further removal from the entire pool. +func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions { + drop := make(types.Transactions, 0, count) // Remote underpriced transactions to drop + save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep + + for len(*l.items) > 0 && count > 0 { + // Discard stale transactions if found during cleanup + tx := heap.Pop(l.items).(*types.Transaction) + if l.all.Get(tx.Hash()) == nil { + l.stales-- + continue + } + // Non stale transaction found, discard unless local + if local.containsTx(tx) { + save = append(save, tx) + } else { + drop = append(drop, tx) + count-- + } + } + for _, tx := range save { + heap.Push(l.items, tx) + } + return drop +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/tx_pool.go b/vendor/github.com/ethereum/go-ethereum/core/tx_pool.go new file mode 100644 index 00000000..b1682533 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/tx_pool.go @@ -0,0 +1,1363 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "errors" + "fmt" + "math" + "math/big" + "sort" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +const ( + // chainHeadChanSize is the size of channel listening to ChainHeadEvent. + chainHeadChanSize = 10 +) + +var ( + // ErrInvalidSender is returned if the transaction contains an invalid signature. + ErrInvalidSender = errors.New("invalid sender") + + // ErrNonceTooLow is returned if the nonce of a transaction is lower than the + // one present in the local chain. + ErrNonceTooLow = errors.New("nonce too low") + + // ErrUnderpriced is returned if a transaction's gas price is below the minimum + // configured for the transaction pool. + ErrUnderpriced = errors.New("transaction underpriced") + + // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced + // with a different one without the required price bump. + ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") + + // ErrInsufficientFunds is returned if the total cost of executing a transaction + // is higher than the balance of the user's account. + ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") + + // ErrIntrinsicGas is returned if the transaction is specified to use less gas + // than required to start the invocation. + ErrIntrinsicGas = errors.New("intrinsic gas too low") + + // ErrGasLimit is returned if a transaction's requested gas limit exceeds the + // maximum allowance of the current block. + ErrGasLimit = errors.New("exceeds block gas limit") + + // ErrNegativeValue is a sanity error to ensure noone is able to specify a + // transaction with a negative value. + ErrNegativeValue = errors.New("negative value") + + // ErrOversizedData is returned if the input data of a transaction is greater + // than some meaningful limit a user might use. This is not a consensus error + // making the transaction invalid, rather a DOS protection. + ErrOversizedData = errors.New("oversized data") +) + +var ( + evictionInterval = time.Minute // Time interval to check for evictable transactions + statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats +) + +var ( + // Metrics for the pending pool + pendingDiscardMeter = metrics.NewRegisteredMeter("txpool/pending/discard", nil) + pendingReplaceMeter = metrics.NewRegisteredMeter("txpool/pending/replace", nil) + pendingRateLimitMeter = metrics.NewRegisteredMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting + pendingNofundsMeter = metrics.NewRegisteredMeter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds + + // Metrics for the queued pool + queuedDiscardMeter = metrics.NewRegisteredMeter("txpool/queued/discard", nil) + queuedReplaceMeter = metrics.NewRegisteredMeter("txpool/queued/replace", nil) + queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting + queuedNofundsMeter = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds + + // General tx metrics + validMeter = metrics.NewRegisteredMeter("txpool/valid", nil) + invalidTxMeter = metrics.NewRegisteredMeter("txpool/invalid", nil) + underpricedTxMeter = metrics.NewRegisteredMeter("txpool/underpriced", nil) + + pendingCounter = metrics.NewRegisteredCounter("txpool/pending", nil) + queuedCounter = metrics.NewRegisteredCounter("txpool/queued", nil) + localCounter = metrics.NewRegisteredCounter("txpool/local", nil) +) + +// TxStatus is the current status of a transaction as seen by the pool. +type TxStatus uint + +const ( + TxStatusUnknown TxStatus = iota + TxStatusQueued + TxStatusPending + TxStatusIncluded +) + +// blockChain provides the state of blockchain and current gas limit to do +// some pre checks in tx pool and event subscribers. +type blockChain interface { + CurrentBlock() *types.Block + GetBlock(hash common.Hash, number uint64) *types.Block + StateAt(root common.Hash) (*state.StateDB, error) + + SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription +} + +// TxPoolConfig are the configuration parameters of the transaction pool. +type TxPoolConfig struct { + Locals []common.Address // Addresses that should be treated by default as local + NoLocals bool // Whether local transaction handling should be disabled + Journal string // Journal of local transactions to survive node restarts + Rejournal time.Duration // Time interval to regenerate the local transaction journal + + PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool + PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) + + AccountSlots uint64 // Number of executable transaction slots guaranteed per account + GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts + AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account + GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts + + Lifetime time.Duration // Maximum amount of time non-executable transaction are queued +} + +// DefaultTxPoolConfig contains the default configurations for the transaction +// pool. +var DefaultTxPoolConfig = TxPoolConfig{ + Journal: "transactions.rlp", + Rejournal: time.Hour, + + PriceLimit: 1, + PriceBump: 10, + + AccountSlots: 16, + GlobalSlots: 4096, + AccountQueue: 64, + GlobalQueue: 1024, + + Lifetime: 3 * time.Hour, +} + +// sanitize checks the provided user configurations and changes anything that's +// unreasonable or unworkable. +func (config *TxPoolConfig) sanitize() TxPoolConfig { + conf := *config + if conf.Rejournal < time.Second { + log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) + conf.Rejournal = time.Second + } + if conf.PriceLimit < 1 { + log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) + conf.PriceLimit = DefaultTxPoolConfig.PriceLimit + } + if conf.PriceBump < 1 { + log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) + conf.PriceBump = DefaultTxPoolConfig.PriceBump + } + if conf.AccountSlots < 1 { + log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots) + conf.AccountSlots = DefaultTxPoolConfig.AccountSlots + } + if conf.GlobalSlots < 1 { + log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots) + conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots + } + if conf.AccountQueue < 1 { + log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue) + conf.AccountQueue = DefaultTxPoolConfig.AccountQueue + } + if conf.GlobalQueue < 1 { + log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue) + conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue + } + if conf.Lifetime < 1 { + log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime) + conf.Lifetime = DefaultTxPoolConfig.Lifetime + } + return conf +} + +// TxPool contains all currently known transactions. Transactions +// enter the pool when they are received from the network or submitted +// locally. They exit the pool when they are included in the blockchain. +// +// The pool separates processable transactions (which can be applied to the +// current state) and future transactions. Transactions move between those +// two states over time as they are received and processed. +type TxPool struct { + config TxPoolConfig + chainconfig *params.ChainConfig + chain blockChain + gasPrice *big.Int + txFeed event.Feed + scope event.SubscriptionScope + chainHeadCh chan ChainHeadEvent + chainHeadSub event.Subscription + signer types.Signer + mu sync.RWMutex + + currentState *state.StateDB // Current state in the blockchain head + pendingState *state.ManagedState // Pending state tracking virtual nonces + currentMaxGas uint64 // Current gas limit for transaction caps + + locals *accountSet // Set of local transaction to exempt from eviction rules + journal *txJournal // Journal of local transaction to back up to disk + + pending map[common.Address]*txList // All currently processable transactions + queue map[common.Address]*txList // Queued but non-processable transactions + beats map[common.Address]time.Time // Last heartbeat from each known account + all *txLookup // All transactions to allow lookups + priced *txPricedList // All transactions sorted by price + + wg sync.WaitGroup // for shutdown sync + + homestead bool +} + +// NewTxPool creates a new transaction pool to gather, sort and filter inbound +// transactions from the network. +func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { + // Sanitize the input to ensure no vulnerable gas prices are set + config = (&config).sanitize() + + // Create the transaction pool with its initial settings + pool := &TxPool{ + config: config, + chainconfig: chainconfig, + chain: chain, + signer: types.NewEIP155Signer(chainconfig.ChainID), + pending: make(map[common.Address]*txList), + queue: make(map[common.Address]*txList), + beats: make(map[common.Address]time.Time), + all: newTxLookup(), + chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), + gasPrice: new(big.Int).SetUint64(config.PriceLimit), + } + pool.locals = newAccountSet(pool.signer) + for _, addr := range config.Locals { + log.Info("Setting new local account", "address", addr) + pool.locals.add(addr) + } + pool.priced = newTxPricedList(pool.all) + pool.reset(nil, chain.CurrentBlock().Header()) + + // If local transactions and journaling is enabled, load from disk + if !config.NoLocals && config.Journal != "" { + pool.journal = newTxJournal(config.Journal) + + if err := pool.journal.load(pool.AddLocals); err != nil { + log.Warn("Failed to load transaction journal", "err", err) + } + if err := pool.journal.rotate(pool.local()); err != nil { + log.Warn("Failed to rotate transaction journal", "err", err) + } + } + // Subscribe events from blockchain + pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh) + + // Start the event loop and return + pool.wg.Add(1) + go pool.loop() + + return pool +} + +// loop is the transaction pool's main event loop, waiting for and reacting to +// outside blockchain events as well as for various reporting and transaction +// eviction events. +func (pool *TxPool) loop() { + defer pool.wg.Done() + + // Start the stats reporting and transaction eviction tickers + var prevPending, prevQueued, prevStales int + + report := time.NewTicker(statsReportInterval) + defer report.Stop() + + evict := time.NewTicker(evictionInterval) + defer evict.Stop() + + journal := time.NewTicker(pool.config.Rejournal) + defer journal.Stop() + + // Track the previous head headers for transaction reorgs + head := pool.chain.CurrentBlock() + + // Keep waiting for and reacting to the various events + for { + select { + // Handle ChainHeadEvent + case ev := <-pool.chainHeadCh: + if ev.Block != nil { + pool.mu.Lock() + if pool.chainconfig.IsHomestead(ev.Block.Number()) { + pool.homestead = true + } + pool.reset(head.Header(), ev.Block.Header()) + head = ev.Block + + pool.mu.Unlock() + } + // Be unsubscribed due to system stopped + case <-pool.chainHeadSub.Err(): + return + + // Handle stats reporting ticks + case <-report.C: + pool.mu.RLock() + pending, queued := pool.stats() + stales := pool.priced.stales + pool.mu.RUnlock() + + if pending != prevPending || queued != prevQueued || stales != prevStales { + log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales) + prevPending, prevQueued, prevStales = pending, queued, stales + } + + // Handle inactive account transaction eviction + case <-evict.C: + pool.mu.Lock() + for addr := range pool.queue { + // Skip local transactions from the eviction mechanism + if pool.locals.contains(addr) { + continue + } + // Any non-locals old enough should be removed + if time.Since(pool.beats[addr]) > pool.config.Lifetime { + for _, tx := range pool.queue[addr].Flatten() { + pool.removeTx(tx.Hash(), true) + } + } + } + pool.mu.Unlock() + + // Handle local transaction journal rotation + case <-journal.C: + if pool.journal != nil { + pool.mu.Lock() + if err := pool.journal.rotate(pool.local()); err != nil { + log.Warn("Failed to rotate local tx journal", "err", err) + } + pool.mu.Unlock() + } + } + } +} + +// lockedReset is a wrapper around reset to allow calling it in a thread safe +// manner. This method is only ever used in the tester! +func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) { + pool.mu.Lock() + defer pool.mu.Unlock() + + pool.reset(oldHead, newHead) +} + +// reset retrieves the current state of the blockchain and ensures the content +// of the transaction pool is valid with regard to the chain state. +func (pool *TxPool) reset(oldHead, newHead *types.Header) { + // If we're reorging an old state, reinject all dropped transactions + var reinject types.Transactions + + if oldHead != nil && oldHead.Hash() != newHead.ParentHash { + // If the reorg is too deep, avoid doing it (will happen during fast sync) + oldNum := oldHead.Number.Uint64() + newNum := newHead.Number.Uint64() + + if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 { + log.Debug("Skipping deep transaction reorg", "depth", depth) + } else { + // Reorg seems shallow enough to pull in all transactions into memory + var discarded, included types.Transactions + var ( + rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64()) + add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()) + ) + if rem == nil { + // This can happen if a setHead is performed, where we simply discard the old + // head from the chain. + // If that is the case, we don't have the lost transactions any more, and + // there's nothing to add + if newNum < oldNum { + // If the reorg ended up on a lower number, it's indicative of setHead being the cause + log.Debug("Skipping transaction reset caused by setHead", + "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum) + } else { + // If we reorged to a same or higher number, then it's not a case of setHead + log.Warn("Transaction pool reset with missing oldhead", + "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum) + } + return + } + for rem.NumberU64() > add.NumberU64() { + discarded = append(discarded, rem.Transactions()...) + if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { + log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) + return + } + } + for add.NumberU64() > rem.NumberU64() { + included = append(included, add.Transactions()...) + if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { + log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) + return + } + } + for rem.Hash() != add.Hash() { + discarded = append(discarded, rem.Transactions()...) + if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { + log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) + return + } + included = append(included, add.Transactions()...) + if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { + log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) + return + } + } + reinject = types.TxDifference(discarded, included) + } + } + // Initialize the internal state to the current head + if newHead == nil { + newHead = pool.chain.CurrentBlock().Header() // Special case during testing + } + statedb, err := pool.chain.StateAt(newHead.Root) + if err != nil { + log.Error("Failed to reset txpool state", "err", err) + return + } + pool.currentState = statedb + pool.pendingState = state.ManageState(statedb) + pool.currentMaxGas = newHead.GasLimit + + // Inject any transactions discarded due to reorgs + log.Debug("Reinjecting stale transactions", "count", len(reinject)) + senderCacher.recover(pool.signer, reinject) + pool.addTxsLocked(reinject, false) + + // validate the pool of pending transactions, this will remove + // any transactions that have been included in the block or + // have been invalidated because of another transaction (e.g. + // higher gas price) + pool.demoteUnexecutables() + + // Update all accounts to the latest known pending nonce + for addr, list := range pool.pending { + txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway + pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1) + } + // Check the queue and move transactions over to the pending if possible + // or remove those that have become invalid + pool.promoteExecutables(nil) +} + +// Stop terminates the transaction pool. +func (pool *TxPool) Stop() { + // Unsubscribe all subscriptions registered from txpool + pool.scope.Close() + + // Unsubscribe subscriptions registered from blockchain + pool.chainHeadSub.Unsubscribe() + pool.wg.Wait() + + if pool.journal != nil { + pool.journal.close() + } + log.Info("Transaction pool stopped") +} + +// SubscribeNewTxsEvent registers a subscription of NewTxsEvent and +// starts sending event to the given channel. +func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription { + return pool.scope.Track(pool.txFeed.Subscribe(ch)) +} + +// GasPrice returns the current gas price enforced by the transaction pool. +func (pool *TxPool) GasPrice() *big.Int { + pool.mu.RLock() + defer pool.mu.RUnlock() + + return new(big.Int).Set(pool.gasPrice) +} + +// SetGasPrice updates the minimum price required by the transaction pool for a +// new transaction, and drops all transactions below this threshold. +func (pool *TxPool) SetGasPrice(price *big.Int) { + pool.mu.Lock() + defer pool.mu.Unlock() + + pool.gasPrice = price + for _, tx := range pool.priced.Cap(price, pool.locals) { + pool.removeTx(tx.Hash(), false) + } + log.Info("Transaction pool price threshold updated", "price", price) +} + +// State returns the virtual managed state of the transaction pool. +func (pool *TxPool) State() *state.ManagedState { + pool.mu.RLock() + defer pool.mu.RUnlock() + + return pool.pendingState +} + +// Stats retrieves the current pool stats, namely the number of pending and the +// number of queued (non-executable) transactions. +func (pool *TxPool) Stats() (int, int) { + pool.mu.RLock() + defer pool.mu.RUnlock() + + return pool.stats() +} + +// stats retrieves the current pool stats, namely the number of pending and the +// number of queued (non-executable) transactions. +func (pool *TxPool) stats() (int, int) { + pending := 0 + for _, list := range pool.pending { + pending += list.Len() + } + queued := 0 + for _, list := range pool.queue { + queued += list.Len() + } + return pending, queued +} + +// Content retrieves the data content of the transaction pool, returning all the +// pending as well as queued transactions, grouped by account and sorted by nonce. +func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { + pool.mu.Lock() + defer pool.mu.Unlock() + + pending := make(map[common.Address]types.Transactions) + for addr, list := range pool.pending { + pending[addr] = list.Flatten() + } + queued := make(map[common.Address]types.Transactions) + for addr, list := range pool.queue { + queued[addr] = list.Flatten() + } + return pending, queued +} + +// Pending retrieves all currently processable transactions, grouped by origin +// account and sorted by nonce. The returned transaction set is a copy and can be +// freely modified by calling code. +func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) { + pool.mu.Lock() + defer pool.mu.Unlock() + + pending := make(map[common.Address]types.Transactions) + for addr, list := range pool.pending { + pending[addr] = list.Flatten() + } + return pending, nil +} + +// Locals retrieves the accounts currently considered local by the pool. +func (pool *TxPool) Locals() []common.Address { + pool.mu.Lock() + defer pool.mu.Unlock() + + return pool.locals.flatten() +} + +// local retrieves all currently known local transactions, grouped by origin +// account and sorted by nonce. The returned transaction set is a copy and can be +// freely modified by calling code. +func (pool *TxPool) local() map[common.Address]types.Transactions { + txs := make(map[common.Address]types.Transactions) + for addr := range pool.locals.accounts { + if pending := pool.pending[addr]; pending != nil { + txs[addr] = append(txs[addr], pending.Flatten()...) + } + if queued := pool.queue[addr]; queued != nil { + txs[addr] = append(txs[addr], queued.Flatten()...) + } + } + return txs +} + +// validateTx checks whether a transaction is valid according to the consensus +// rules and adheres to some heuristic limits of the local node (price and size). +func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { + // Heuristic limit, reject transactions over 32KB to prevent DOS attacks + if tx.Size() > 32*1024 { + return ErrOversizedData + } + // Transactions can't be negative. This may never happen using RLP decoded + // transactions but may occur if you create a transaction using the RPC. + if tx.Value().Sign() < 0 { + return ErrNegativeValue + } + // Ensure the transaction doesn't exceed the current block limit gas. + if pool.currentMaxGas < tx.Gas() { + return ErrGasLimit + } + // Make sure the transaction is signed properly + from, err := types.Sender(pool.signer, tx) + if err != nil { + return ErrInvalidSender + } + // Drop non-local transactions under our own minimal accepted gas price + local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network + if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { + return ErrUnderpriced + } + // Ensure the transaction adheres to nonce ordering + if pool.currentState.GetNonce(from) > tx.Nonce() { + return ErrNonceTooLow + } + // Transactor should have enough funds to cover the costs + // cost == V + GP * GL + if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { + return ErrInsufficientFunds + } + intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) + if err != nil { + return err + } + if tx.Gas() < intrGas { + return ErrIntrinsicGas + } + return nil +} + +// add validates a transaction and inserts it into the non-executable queue for +// later pending promotion and execution. If the transaction is a replacement for +// an already pending or queued one, it overwrites the previous and returns this +// so outer code doesn't uselessly call promote. +// +// If a newly added transaction is marked as local, its sending account will be +// whitelisted, preventing any associated transaction from being dropped out of +// the pool due to pricing constraints. +func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { + // If the transaction is already known, discard it + hash := tx.Hash() + if pool.all.Get(hash) != nil { + log.Trace("Discarding already known transaction", "hash", hash) + return false, fmt.Errorf("known transaction: %x", hash) + } + // If the transaction fails basic validation, discard it + if err := pool.validateTx(tx, local); err != nil { + log.Trace("Discarding invalid transaction", "hash", hash, "err", err) + invalidTxMeter.Mark(1) + return false, err + } + // If the transaction pool is full, discard underpriced transactions + if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue { + // If the new transaction is underpriced, don't accept it + if !local && pool.priced.Underpriced(tx, pool.locals) { + log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice()) + underpricedTxMeter.Mark(1) + return false, ErrUnderpriced + } + // New transaction is better than our worse ones, make room for it + drop := pool.priced.Discard(pool.all.Count()-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals) + for _, tx := range drop { + log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice()) + underpricedTxMeter.Mark(1) + pool.removeTx(tx.Hash(), false) + } + } + // If the transaction is replacing an already pending one, do directly + from, _ := types.Sender(pool.signer, tx) // already validated + if list := pool.pending[from]; list != nil && list.Overlaps(tx) { + // Nonce already pending, check if required price bump is met + inserted, old := list.Add(tx, pool.config.PriceBump) + if !inserted { + pendingDiscardMeter.Mark(1) + return false, ErrReplaceUnderpriced + } + // New transaction is better, replace old one + if old != nil { + pool.all.Remove(old.Hash()) + pool.priced.Removed(1) + pendingReplaceMeter.Mark(1) + } + pool.all.Add(tx) + pool.priced.Put(tx) + pool.journalTx(from, tx) + + log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) + + // We've directly injected a replacement transaction, notify subsystems + go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}}) + + return old != nil, nil + } + // New transaction isn't replacing a pending one, push into queue + replace, err := pool.enqueueTx(hash, tx) + if err != nil { + return false, err + } + // Mark local addresses and journal local transactions + if local { + if !pool.locals.contains(from) { + log.Info("Setting new local account", "address", from) + pool.locals.add(from) + } + } + if local || pool.locals.contains(from) { + localCounter.Inc(1) + } + pool.journalTx(from, tx) + + log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) + return replace, nil +} + +// enqueueTx inserts a new transaction into the non-executable transaction queue. +// +// Note, this method assumes the pool lock is held! +func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) { + // Try to insert the transaction into the future queue + from, _ := types.Sender(pool.signer, tx) // already validated + if pool.queue[from] == nil { + pool.queue[from] = newTxList(false) + } + inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) + if !inserted { + // An older transaction was better, discard this + queuedDiscardMeter.Mark(1) + return false, ErrReplaceUnderpriced + } + // Discard any previous transaction and mark this + if old != nil { + pool.all.Remove(old.Hash()) + pool.priced.Removed(1) + queuedReplaceMeter.Mark(1) + } else { + // Nothing was replaced, bump the queued counter + queuedCounter.Inc(1) + } + if pool.all.Get(hash) == nil { + pool.all.Add(tx) + pool.priced.Put(tx) + } + return old != nil, nil +} + +// journalTx adds the specified transaction to the local disk journal if it is +// deemed to have been sent from a local account. +func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { + // Only journal if it's enabled and the transaction is local + if pool.journal == nil || !pool.locals.contains(from) { + return + } + if err := pool.journal.insert(tx); err != nil { + log.Warn("Failed to journal local transaction", "err", err) + } +} + +// promoteTx adds a transaction to the pending (processable) list of transactions +// and returns whether it was inserted or an older was better. +// +// Note, this method assumes the pool lock is held! +func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { + // Try to insert the transaction into the pending queue + if pool.pending[addr] == nil { + pool.pending[addr] = newTxList(true) + } + list := pool.pending[addr] + + inserted, old := list.Add(tx, pool.config.PriceBump) + if !inserted { + // An older transaction was better, discard this + pool.all.Remove(hash) + pool.priced.Removed(1) + + pendingDiscardMeter.Mark(1) + return false + } + // Otherwise discard any previous transaction and mark this + if old != nil { + pool.all.Remove(old.Hash()) + pool.priced.Removed(1) + + pendingReplaceMeter.Mark(1) + } else { + // Nothing was replaced, bump the pending counter + pendingCounter.Inc(1) + } + // Failsafe to work around direct pending inserts (tests) + if pool.all.Get(hash) == nil { + pool.all.Add(tx) + pool.priced.Put(tx) + } + // Set the potentially new pending nonce and notify any subsystems of the new tx + pool.beats[addr] = time.Now() + pool.pendingState.SetNonce(addr, tx.Nonce()+1) + + return true +} + +// AddLocal enqueues a single transaction into the pool if it is valid, marking +// the sender as a local one in the mean time, ensuring it goes around the local +// pricing constraints. +func (pool *TxPool) AddLocal(tx *types.Transaction) error { + return pool.addTx(tx, !pool.config.NoLocals) +} + +// AddRemote enqueues a single transaction into the pool if it is valid. If the +// sender is not among the locally tracked ones, full pricing constraints will +// apply. +func (pool *TxPool) AddRemote(tx *types.Transaction) error { + return pool.addTx(tx, false) +} + +// AddLocals enqueues a batch of transactions into the pool if they are valid, +// marking the senders as a local ones in the mean time, ensuring they go around +// the local pricing constraints. +func (pool *TxPool) AddLocals(txs []*types.Transaction) []error { + return pool.addTxs(txs, !pool.config.NoLocals) +} + +// AddRemotes enqueues a batch of transactions into the pool if they are valid. +// If the senders are not among the locally tracked ones, full pricing constraints +// will apply. +func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error { + return pool.addTxs(txs, false) +} + +// addTx enqueues a single transaction into the pool if it is valid. +func (pool *TxPool) addTx(tx *types.Transaction, local bool) error { + // Cache sender in transaction before obtaining lock (pool.signer is immutable) + types.Sender(pool.signer, tx) + + pool.mu.Lock() + defer pool.mu.Unlock() + + // Try to inject the transaction and update any state + replace, err := pool.add(tx, local) + if err != nil { + return err + } + validMeter.Mark(1) + + // If we added a new transaction, run promotion checks and return + if !replace { + from, _ := types.Sender(pool.signer, tx) // already validated + pool.promoteExecutables([]common.Address{from}) + } + return nil +} + +// addTxs attempts to queue a batch of transactions if they are valid. +func (pool *TxPool) addTxs(txs []*types.Transaction, local bool) []error { + // Cache senders in transactions before obtaining lock (pool.signer is immutable) + for _, tx := range txs { + types.Sender(pool.signer, tx) + } + pool.mu.Lock() + defer pool.mu.Unlock() + + return pool.addTxsLocked(txs, local) +} + +// addTxsLocked attempts to queue a batch of transactions if they are valid, +// whilst assuming the transaction pool lock is already held. +func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error { + // Add the batch of transactions, tracking the accepted ones + dirty := make(map[common.Address]struct{}) + errs := make([]error, len(txs)) + + for i, tx := range txs { + var replace bool + if replace, errs[i] = pool.add(tx, local); errs[i] == nil && !replace { + from, _ := types.Sender(pool.signer, tx) // already validated + dirty[from] = struct{}{} + } + } + validMeter.Mark(int64(len(dirty))) + + // Only reprocess the internal state if something was actually added + if len(dirty) > 0 { + addrs := make([]common.Address, 0, len(dirty)) + for addr := range dirty { + addrs = append(addrs, addr) + } + pool.promoteExecutables(addrs) + } + return errs +} + +// Status returns the status (unknown/pending/queued) of a batch of transactions +// identified by their hashes. +func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { + pool.mu.RLock() + defer pool.mu.RUnlock() + + status := make([]TxStatus, len(hashes)) + for i, hash := range hashes { + if tx := pool.all.Get(hash); tx != nil { + from, _ := types.Sender(pool.signer, tx) // already validated + if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil { + status[i] = TxStatusPending + } else { + status[i] = TxStatusQueued + } + } + } + return status +} + +// Get returns a transaction if it is contained in the pool +// and nil otherwise. +func (pool *TxPool) Get(hash common.Hash) *types.Transaction { + return pool.all.Get(hash) +} + +// removeTx removes a single transaction from the queue, moving all subsequent +// transactions back to the future queue. +func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { + // Fetch the transaction we wish to delete + tx := pool.all.Get(hash) + if tx == nil { + return + } + addr, _ := types.Sender(pool.signer, tx) // already validated during insertion + + // Remove it from the list of known transactions + pool.all.Remove(hash) + if outofbound { + pool.priced.Removed(1) + } + if pool.locals.contains(addr) { + localCounter.Dec(1) + } + // Remove the transaction from the pending lists and reset the account nonce + if pending := pool.pending[addr]; pending != nil { + if removed, invalids := pending.Remove(tx); removed { + // If no more pending transactions are left, remove the list + if pending.Empty() { + delete(pool.pending, addr) + delete(pool.beats, addr) + } + // Postpone any invalidated transactions + for _, tx := range invalids { + pool.enqueueTx(tx.Hash(), tx) + } + // Update the account nonce if needed + if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce { + pool.pendingState.SetNonce(addr, nonce) + } + // Reduce the pending counter + pendingCounter.Dec(int64(1 + len(invalids))) + return + } + } + // Transaction is in the future queue + if future := pool.queue[addr]; future != nil { + if removed, _ := future.Remove(tx); removed { + // Reduce the queued counter + queuedCounter.Dec(1) + } + if future.Empty() { + delete(pool.queue, addr) + } + } +} + +// promoteExecutables moves transactions that have become processable from the +// future queue to the set of pending transactions. During this process, all +// invalidated transactions (low nonce, low balance) are deleted. +func (pool *TxPool) promoteExecutables(accounts []common.Address) { + // Track the promoted transactions to broadcast them at once + var promoted []*types.Transaction + + // Gather all the accounts potentially needing updates + if accounts == nil { + accounts = make([]common.Address, 0, len(pool.queue)) + for addr := range pool.queue { + accounts = append(accounts, addr) + } + } + // Iterate over all accounts and promote any executable transactions + for _, addr := range accounts { + list := pool.queue[addr] + if list == nil { + continue // Just in case someone calls with a non existing account + } + // Drop all transactions that are deemed too old (low nonce) + forwards := list.Forward(pool.currentState.GetNonce(addr)) + for _, tx := range forwards { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed old queued transaction", "hash", hash) + } + // Drop all transactions that are too costly (low balance or out of gas) + drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) + for _, tx := range drops { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed unpayable queued transaction", "hash", hash) + } + queuedNofundsMeter.Mark(int64(len(drops))) + + // Gather all executable transactions and promote them + readies := list.Ready(pool.pendingState.GetNonce(addr)) + for _, tx := range readies { + hash := tx.Hash() + if pool.promoteTx(addr, hash, tx) { + log.Trace("Promoting queued transaction", "hash", hash) + promoted = append(promoted, tx) + } + } + queuedCounter.Dec(int64(len(readies))) + + // Drop all transactions over the allowed limit + var caps types.Transactions + if !pool.locals.contains(addr) { + caps = list.Cap(int(pool.config.AccountQueue)) + for _, tx := range caps { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed cap-exceeding queued transaction", "hash", hash) + } + queuedRateLimitMeter.Mark(int64(len(caps))) + } + // Mark all the items dropped as removed + pool.priced.Removed(len(forwards) + len(drops) + len(caps)) + queuedCounter.Dec(int64(len(forwards) + len(drops) + len(caps))) + if pool.locals.contains(addr) { + localCounter.Dec(int64(len(forwards) + len(drops) + len(caps))) + } + // Delete the entire queue entry if it became empty. + if list.Empty() { + delete(pool.queue, addr) + } + } + // Notify subsystem for new promoted transactions. + if len(promoted) > 0 { + go pool.txFeed.Send(NewTxsEvent{promoted}) + } + // If the pending limit is overflown, start equalizing allowances + pending := uint64(0) + for _, list := range pool.pending { + pending += uint64(list.Len()) + } + if pending > pool.config.GlobalSlots { + pendingBeforeCap := pending + // Assemble a spam order to penalize large transactors first + spammers := prque.New(nil) + for addr, list := range pool.pending { + // Only evict transactions from high rollers + if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { + spammers.Push(addr, int64(list.Len())) + } + } + // Gradually drop transactions from offenders + offenders := []common.Address{} + for pending > pool.config.GlobalSlots && !spammers.Empty() { + // Retrieve the next offender if not local address + offender, _ := spammers.Pop() + offenders = append(offenders, offender.(common.Address)) + + // Equalize balances until all the same or below threshold + if len(offenders) > 1 { + // Calculate the equalization threshold for all current offenders + threshold := pool.pending[offender.(common.Address)].Len() + + // Iteratively reduce all offenders until below limit or threshold reached + for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { + for i := 0; i < len(offenders)-1; i++ { + list := pool.pending[offenders[i]] + + caps := list.Cap(list.Len() - 1) + for _, tx := range caps { + // Drop the transaction from the global pools too + hash := tx.Hash() + pool.all.Remove(hash) + + // Update the account nonce to the dropped transaction + if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce { + pool.pendingState.SetNonce(offenders[i], nonce) + } + log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) + } + pool.priced.Removed(len(caps)) + pendingCounter.Dec(int64(len(caps))) + if pool.locals.contains(offenders[i]) { + localCounter.Dec(int64(len(caps))) + } + pending-- + } + } + } + } + // If still above threshold, reduce to limit or min allowance + if pending > pool.config.GlobalSlots && len(offenders) > 0 { + for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots { + for _, addr := range offenders { + list := pool.pending[addr] + + caps := list.Cap(list.Len() - 1) + for _, tx := range caps { + // Drop the transaction from the global pools too + hash := tx.Hash() + pool.all.Remove(hash) + + // Update the account nonce to the dropped transaction + if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce { + pool.pendingState.SetNonce(addr, nonce) + } + log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) + } + pool.priced.Removed(len(caps)) + pendingCounter.Dec(int64(len(caps))) + if pool.locals.contains(addr) { + localCounter.Dec(int64(len(caps))) + } + pending-- + } + } + } + pendingRateLimitMeter.Mark(int64(pendingBeforeCap - pending)) + } + // If we've queued more transactions than the hard limit, drop oldest ones + queued := uint64(0) + for _, list := range pool.queue { + queued += uint64(list.Len()) + } + if queued > pool.config.GlobalQueue { + // Sort all accounts with queued transactions by heartbeat + addresses := make(addressesByHeartbeat, 0, len(pool.queue)) + for addr := range pool.queue { + if !pool.locals.contains(addr) { // don't drop locals + addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) + } + } + sort.Sort(addresses) + + // Drop transactions until the total is below the limit or only locals remain + for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { + addr := addresses[len(addresses)-1] + list := pool.queue[addr.address] + + addresses = addresses[:len(addresses)-1] + + // Drop all transactions if they are less than the overflow + if size := uint64(list.Len()); size <= drop { + for _, tx := range list.Flatten() { + pool.removeTx(tx.Hash(), true) + } + drop -= size + queuedRateLimitMeter.Mark(int64(size)) + continue + } + // Otherwise drop only last few transactions + txs := list.Flatten() + for i := len(txs) - 1; i >= 0 && drop > 0; i-- { + pool.removeTx(txs[i].Hash(), true) + drop-- + queuedRateLimitMeter.Mark(1) + } + } + } +} + +// demoteUnexecutables removes invalid and processed transactions from the pools +// executable/pending queue and any subsequent transactions that become unexecutable +// are moved back into the future queue. +func (pool *TxPool) demoteUnexecutables() { + // Iterate over all accounts and demote any non-executable transactions + for addr, list := range pool.pending { + nonce := pool.currentState.GetNonce(addr) + + // Drop all transactions that are deemed too old (low nonce) + olds := list.Forward(nonce) + for _, tx := range olds { + hash := tx.Hash() + pool.all.Remove(hash) + log.Trace("Removed old pending transaction", "hash", hash) + } + // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later + drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) + for _, tx := range drops { + hash := tx.Hash() + log.Trace("Removed unpayable pending transaction", "hash", hash) + pool.all.Remove(hash) + } + pool.priced.Removed(len(olds) + len(drops)) + pendingNofundsMeter.Mark(int64(len(drops))) + + for _, tx := range invalids { + hash := tx.Hash() + log.Trace("Demoting pending transaction", "hash", hash) + pool.enqueueTx(hash, tx) + } + pendingCounter.Dec(int64(len(olds) + len(drops) + len(invalids))) + if pool.locals.contains(addr) { + localCounter.Dec(int64(len(olds) + len(drops) + len(invalids))) + } + // If there's a gap in front, alert (should never happen) and postpone all transactions + if list.Len() > 0 && list.txs.Get(nonce) == nil { + gapped := list.Cap(0) + for _, tx := range gapped { + hash := tx.Hash() + log.Error("Demoting invalidated transaction", "hash", hash) + pool.enqueueTx(hash, tx) + } + pendingCounter.Inc(int64(len(gapped))) + } + // Delete the entire queue entry if it became empty. + if list.Empty() { + delete(pool.pending, addr) + delete(pool.beats, addr) + } + } +} + +// addressByHeartbeat is an account address tagged with its last activity timestamp. +type addressByHeartbeat struct { + address common.Address + heartbeat time.Time +} + +type addressesByHeartbeat []addressByHeartbeat + +func (a addressesByHeartbeat) Len() int { return len(a) } +func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } +func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// accountSet is simply a set of addresses to check for existence, and a signer +// capable of deriving addresses from transactions. +type accountSet struct { + accounts map[common.Address]struct{} + signer types.Signer + cache *[]common.Address +} + +// newAccountSet creates a new address set with an associated signer for sender +// derivations. +func newAccountSet(signer types.Signer) *accountSet { + return &accountSet{ + accounts: make(map[common.Address]struct{}), + signer: signer, + } +} + +// contains checks if a given address is contained within the set. +func (as *accountSet) contains(addr common.Address) bool { + _, exist := as.accounts[addr] + return exist +} + +// containsTx checks if the sender of a given tx is within the set. If the sender +// cannot be derived, this method returns false. +func (as *accountSet) containsTx(tx *types.Transaction) bool { + if addr, err := types.Sender(as.signer, tx); err == nil { + return as.contains(addr) + } + return false +} + +// add inserts a new address into the set to track. +func (as *accountSet) add(addr common.Address) { + as.accounts[addr] = struct{}{} + as.cache = nil +} + +// flatten returns the list of addresses within this set, also caching it for later +// reuse. The returned slice should not be changed! +func (as *accountSet) flatten() []common.Address { + if as.cache == nil { + accounts := make([]common.Address, 0, len(as.accounts)) + for account := range as.accounts { + accounts = append(accounts, account) + } + as.cache = &accounts + } + return *as.cache +} + +// txLookup is used internally by TxPool to track transactions while allowing lookup without +// mutex contention. +// +// Note, although this type is properly protected against concurrent access, it +// is **not** a type that should ever be mutated or even exposed outside of the +// transaction pool, since its internal state is tightly coupled with the pools +// internal mechanisms. The sole purpose of the type is to permit out-of-bound +// peeking into the pool in TxPool.Get without having to acquire the widely scoped +// TxPool.mu mutex. +type txLookup struct { + all map[common.Hash]*types.Transaction + lock sync.RWMutex +} + +// newTxLookup returns a new txLookup structure. +func newTxLookup() *txLookup { + return &txLookup{ + all: make(map[common.Hash]*types.Transaction), + } +} + +// Range calls f on each key and value present in the map. +func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) { + t.lock.RLock() + defer t.lock.RUnlock() + + for key, value := range t.all { + if !f(key, value) { + break + } + } +} + +// Get returns a transaction if it exists in the lookup, or nil if not found. +func (t *txLookup) Get(hash common.Hash) *types.Transaction { + t.lock.RLock() + defer t.lock.RUnlock() + + return t.all[hash] +} + +// Count returns the current number of items in the lookup. +func (t *txLookup) Count() int { + t.lock.RLock() + defer t.lock.RUnlock() + + return len(t.all) +} + +// Add adds a transaction to the lookup. +func (t *txLookup) Add(tx *types.Transaction) { + t.lock.Lock() + defer t.lock.Unlock() + + t.all[tx.Hash()] = tx +} + +// Remove removes a transaction from the lookup. +func (t *txLookup) Remove(hash common.Hash) { + t.lock.Lock() + defer t.lock.Unlock() + + delete(t.all, hash) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/types.go b/vendor/github.com/ethereum/go-ethereum/core/types.go new file mode 100644 index 00000000..4c5b74a4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types.go @@ -0,0 +1,51 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" +) + +// Validator is an interface which defines the standard for block validation. It +// is only responsible for validating block contents, as the header validation is +// done by the specific consensus engines. +type Validator interface { + // ValidateBody validates the given block's content. + ValidateBody(block *types.Block) error + + // ValidateState validates the given statedb and optionally the receipts and + // gas used. + ValidateState(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error +} + +// Prefetcher is an interface for pre-caching transaction signatures and state. +type Prefetcher interface { + // Prefetch processes the state changes according to the Ethereum rules by running + // the transaction messages using the statedb, but any changes are discarded. The + // only goal is to pre-cache transaction signatures and state trie nodes. + Prefetch(block *types.Block, statedb *state.StateDB, cfg vm.Config, interrupt *uint32) +} + +// Processor is an interface for processing blocks using a given initial state. +type Processor interface { + // Process processes the state changes according to the Ethereum rules by running + // the transaction messages using the statedb and applying any rewards to both + // the processor (coinbase) and any included uncles. + Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/types/block.go b/vendor/github.com/ethereum/go-ethereum/core/types/block.go new file mode 100644 index 00000000..f754c3c4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types/block.go @@ -0,0 +1,393 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package types contains data types related to Ethereum consensus. +package types + +import ( + "encoding/binary" + "io" + "math/big" + "reflect" + "sort" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/crypto/sha3" +) + +var ( + EmptyRootHash = DeriveSha(Transactions{}) + EmptyUncleHash = rlpHash([]*Header(nil)) +) + +// A BlockNonce is a 64-bit hash which proves (combined with the +// mix-hash) that a sufficient amount of computation has been carried +// out on a block. +type BlockNonce [8]byte + +// EncodeNonce converts the given integer to a block nonce. +func EncodeNonce(i uint64) BlockNonce { + var n BlockNonce + binary.BigEndian.PutUint64(n[:], i) + return n +} + +// Uint64 returns the integer value of a block nonce. +func (n BlockNonce) Uint64() uint64 { + return binary.BigEndian.Uint64(n[:]) +} + +// MarshalText encodes n as a hex string with 0x prefix. +func (n BlockNonce) MarshalText() ([]byte, error) { + return hexutil.Bytes(n[:]).MarshalText() +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (n *BlockNonce) UnmarshalText(input []byte) error { + return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) +} + +//go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go + +// Header represents a block header in the Ethereum blockchain. +type Header struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Number *big.Int `json:"number" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Time uint64 `json:"timestamp" gencodec:"required"` + Extra []byte `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` +} + +// field type overrides for gencodec +type headerMarshaling struct { + Difficulty *hexutil.Big + Number *hexutil.Big + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + Time hexutil.Uint64 + Extra hexutil.Bytes + Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON +} + +// Hash returns the block hash of the header, which is simply the keccak256 hash of its +// RLP encoding. +func (h *Header) Hash() common.Hash { + return rlpHash(h) +} + +var headerSize = common.StorageSize(reflect.TypeOf(Header{}).Size()) + +// Size returns the approximate memory used by all internal contents. It is used +// to approximate and limit the memory consumption of various caches. +func (h *Header) Size() common.StorageSize { + return headerSize + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen())/8) +} + +func rlpHash(x interface{}) (h common.Hash) { + hw := sha3.NewLegacyKeccak256() + rlp.Encode(hw, x) + hw.Sum(h[:0]) + return h +} + +// Body is a simple (mutable, non-safe) data container for storing and moving +// a block's data contents (transactions and uncles) together. +type Body struct { + Transactions []*Transaction + Uncles []*Header +} + +// Block represents an entire block in the Ethereum blockchain. +type Block struct { + header *Header + uncles []*Header + transactions Transactions + + // caches + hash atomic.Value + size atomic.Value + + // Td is used by package core to store the total difficulty + // of the chain up to and including the block. + td *big.Int + + // These fields are used by package eth to track + // inter-peer block relay. + ReceivedAt time.Time + ReceivedFrom interface{} +} + +// DeprecatedTd is an old relic for extracting the TD of a block. It is in the +// code solely to facilitate upgrading the database from the old format to the +// new, after which it should be deleted. Do not use! +func (b *Block) DeprecatedTd() *big.Int { + return b.td +} + +// [deprecated by eth/63] +// StorageBlock defines the RLP encoding of a Block stored in the +// state database. The StorageBlock encoding contains fields that +// would otherwise need to be recomputed. +type StorageBlock Block + +// "external" block encoding. used for eth protocol, etc. +type extblock struct { + Header *Header + Txs []*Transaction + Uncles []*Header +} + +// [deprecated by eth/63] +// "storage" block encoding. used for database. +type storageblock struct { + Header *Header + Txs []*Transaction + Uncles []*Header + TD *big.Int +} + +// NewBlock creates a new block. The input data is copied, +// changes to header and to the field values will not affect the +// block. +// +// The values of TxHash, UncleHash, ReceiptHash and Bloom in header +// are ignored and set to values derived from the given txs, uncles +// and receipts. +func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block { + b := &Block{header: CopyHeader(header), td: new(big.Int)} + + // TODO: panic if len(txs) != len(receipts) + if len(txs) == 0 { + b.header.TxHash = EmptyRootHash + } else { + b.header.TxHash = DeriveSha(Transactions(txs)) + b.transactions = make(Transactions, len(txs)) + copy(b.transactions, txs) + } + + if len(receipts) == 0 { + b.header.ReceiptHash = EmptyRootHash + } else { + b.header.ReceiptHash = DeriveSha(Receipts(receipts)) + b.header.Bloom = CreateBloom(receipts) + } + + if len(uncles) == 0 { + b.header.UncleHash = EmptyUncleHash + } else { + b.header.UncleHash = CalcUncleHash(uncles) + b.uncles = make([]*Header, len(uncles)) + for i := range uncles { + b.uncles[i] = CopyHeader(uncles[i]) + } + } + + return b +} + +// NewBlockWithHeader creates a block with the given header data. The +// header data is copied, changes to header and to the field values +// will not affect the block. +func NewBlockWithHeader(header *Header) *Block { + return &Block{header: CopyHeader(header)} +} + +// CopyHeader creates a deep copy of a block header to prevent side effects from +// modifying a header variable. +func CopyHeader(h *Header) *Header { + cpy := *h + if cpy.Difficulty = new(big.Int); h.Difficulty != nil { + cpy.Difficulty.Set(h.Difficulty) + } + if cpy.Number = new(big.Int); h.Number != nil { + cpy.Number.Set(h.Number) + } + if len(h.Extra) > 0 { + cpy.Extra = make([]byte, len(h.Extra)) + copy(cpy.Extra, h.Extra) + } + return &cpy +} + +// DecodeRLP decodes the Ethereum +func (b *Block) DecodeRLP(s *rlp.Stream) error { + var eb extblock + _, size, _ := s.Kind() + if err := s.Decode(&eb); err != nil { + return err + } + b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs + b.size.Store(common.StorageSize(rlp.ListSize(size))) + return nil +} + +// EncodeRLP serializes b into the Ethereum RLP block format. +func (b *Block) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, extblock{ + Header: b.header, + Txs: b.transactions, + Uncles: b.uncles, + }) +} + +// [deprecated by eth/63] +func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error { + var sb storageblock + if err := s.Decode(&sb); err != nil { + return err + } + b.header, b.uncles, b.transactions, b.td = sb.Header, sb.Uncles, sb.Txs, sb.TD + return nil +} + +// TODO: copies + +func (b *Block) Uncles() []*Header { return b.uncles } +func (b *Block) Transactions() Transactions { return b.transactions } + +func (b *Block) Transaction(hash common.Hash) *Transaction { + for _, transaction := range b.transactions { + if transaction.Hash() == hash { + return transaction + } + } + return nil +} + +func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } +func (b *Block) GasLimit() uint64 { return b.header.GasLimit } +func (b *Block) GasUsed() uint64 { return b.header.GasUsed } +func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } +func (b *Block) Time() uint64 { return b.header.Time } + +func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } +func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } +func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) } +func (b *Block) Bloom() Bloom { return b.header.Bloom } +func (b *Block) Coinbase() common.Address { return b.header.Coinbase } +func (b *Block) Root() common.Hash { return b.header.Root } +func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } +func (b *Block) TxHash() common.Hash { return b.header.TxHash } +func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } +func (b *Block) UncleHash() common.Hash { return b.header.UncleHash } +func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } + +func (b *Block) Header() *Header { return CopyHeader(b.header) } + +// Body returns the non-header content of the block. +func (b *Block) Body() *Body { return &Body{b.transactions, b.uncles} } + +// Size returns the true RLP encoded storage size of the block, either by encoding +// and returning it, or returning a previsouly cached value. +func (b *Block) Size() common.StorageSize { + if size := b.size.Load(); size != nil { + return size.(common.StorageSize) + } + c := writeCounter(0) + rlp.Encode(&c, b) + b.size.Store(common.StorageSize(c)) + return common.StorageSize(c) +} + +type writeCounter common.StorageSize + +func (c *writeCounter) Write(b []byte) (int, error) { + *c += writeCounter(len(b)) + return len(b), nil +} + +func CalcUncleHash(uncles []*Header) common.Hash { + if len(uncles) == 0 { + return EmptyUncleHash + } + return rlpHash(uncles) +} + +// WithSeal returns a new block with the data from b but the header replaced with +// the sealed one. +func (b *Block) WithSeal(header *Header) *Block { + cpy := *header + + return &Block{ + header: &cpy, + transactions: b.transactions, + uncles: b.uncles, + } +} + +// WithBody returns a new block with the given transaction and uncle contents. +func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block { + block := &Block{ + header: CopyHeader(b.header), + transactions: make([]*Transaction, len(transactions)), + uncles: make([]*Header, len(uncles)), + } + copy(block.transactions, transactions) + for i := range uncles { + block.uncles[i] = CopyHeader(uncles[i]) + } + return block +} + +// Hash returns the keccak256 hash of b's header. +// The hash is computed on the first call and cached thereafter. +func (b *Block) Hash() common.Hash { + if hash := b.hash.Load(); hash != nil { + return hash.(common.Hash) + } + v := b.header.Hash() + b.hash.Store(v) + return v +} + +type Blocks []*Block + +type BlockBy func(b1, b2 *Block) bool + +func (self BlockBy) Sort(blocks Blocks) { + bs := blockSorter{ + blocks: blocks, + by: self, + } + sort.Sort(bs) +} + +type blockSorter struct { + blocks Blocks + by func(b1, b2 *Block) bool +} + +func (self blockSorter) Len() int { return len(self.blocks) } +func (self blockSorter) Swap(i, j int) { + self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] +} +func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } + +func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 } diff --git a/vendor/github.com/ethereum/go-ethereum/core/types/gen_header_json.go b/vendor/github.com/ethereum/go-ethereum/core/types/gen_header_json.go new file mode 100644 index 00000000..4212b8d9 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types/gen_header_json.go @@ -0,0 +1,138 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package types + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var _ = (*headerMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (h Header) MarshalJSON() ([]byte, error) { + type Header struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce BlockNonce `json:"nonce"` + Hash common.Hash `json:"hash"` + } + var enc Header + enc.ParentHash = h.ParentHash + enc.UncleHash = h.UncleHash + enc.Coinbase = h.Coinbase + enc.Root = h.Root + enc.TxHash = h.TxHash + enc.ReceiptHash = h.ReceiptHash + enc.Bloom = h.Bloom + enc.Difficulty = (*hexutil.Big)(h.Difficulty) + enc.Number = (*hexutil.Big)(h.Number) + enc.GasLimit = hexutil.Uint64(h.GasLimit) + enc.GasUsed = hexutil.Uint64(h.GasUsed) + enc.Time = hexutil.Uint64(h.Time) + enc.Extra = h.Extra + enc.MixDigest = h.MixDigest + enc.Nonce = h.Nonce + enc.Hash = h.Hash() + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (h *Header) UnmarshalJSON(input []byte) error { + type Header struct { + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner" gencodec:"required"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *BlockNonce `json:"nonce"` + } + var dec Header + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ParentHash == nil { + return errors.New("missing required field 'parentHash' for Header") + } + h.ParentHash = *dec.ParentHash + if dec.UncleHash == nil { + return errors.New("missing required field 'sha3Uncles' for Header") + } + h.UncleHash = *dec.UncleHash + if dec.Coinbase == nil { + return errors.New("missing required field 'miner' for Header") + } + h.Coinbase = *dec.Coinbase + if dec.Root == nil { + return errors.New("missing required field 'stateRoot' for Header") + } + h.Root = *dec.Root + if dec.TxHash == nil { + return errors.New("missing required field 'transactionsRoot' for Header") + } + h.TxHash = *dec.TxHash + if dec.ReceiptHash == nil { + return errors.New("missing required field 'receiptsRoot' for Header") + } + h.ReceiptHash = *dec.ReceiptHash + if dec.Bloom == nil { + return errors.New("missing required field 'logsBloom' for Header") + } + h.Bloom = *dec.Bloom + if dec.Difficulty == nil { + return errors.New("missing required field 'difficulty' for Header") + } + h.Difficulty = (*big.Int)(dec.Difficulty) + if dec.Number == nil { + return errors.New("missing required field 'number' for Header") + } + h.Number = (*big.Int)(dec.Number) + if dec.GasLimit == nil { + return errors.New("missing required field 'gasLimit' for Header") + } + h.GasLimit = uint64(*dec.GasLimit) + if dec.GasUsed == nil { + return errors.New("missing required field 'gasUsed' for Header") + } + h.GasUsed = uint64(*dec.GasUsed) + if dec.Time == nil { + return errors.New("missing required field 'timestamp' for Header") + } + h.Time = uint64(*dec.Time) + if dec.Extra == nil { + return errors.New("missing required field 'extraData' for Header") + } + h.Extra = *dec.Extra + if dec.MixDigest != nil { + h.MixDigest = *dec.MixDigest + } + if dec.Nonce != nil { + h.Nonce = *dec.Nonce + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/types/log.go b/vendor/github.com/ethereum/go-ethereum/core/types/log.go new file mode 100644 index 00000000..006f62bb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types/log.go @@ -0,0 +1,143 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "io" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rlp" +) + +//go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go + +// Log represents a contract log event. These events are generated by the LOG opcode and +// stored/indexed by the node. +type Log struct { + // Consensus fields: + // address of the contract that generated the event + Address common.Address `json:"address" gencodec:"required"` + // list of topics provided by the contract. + Topics []common.Hash `json:"topics" gencodec:"required"` + // supplied by the contract, usually ABI-encoded + Data []byte `json:"data" gencodec:"required"` + + // Derived fields. These fields are filled in by the node + // but not secured by consensus. + // block in which the transaction was included + BlockNumber uint64 `json:"blockNumber"` + // hash of the transaction + TxHash common.Hash `json:"transactionHash" gencodec:"required"` + // index of the transaction in the block + TxIndex uint `json:"transactionIndex" gencodec:"required"` + // hash of the block in which the transaction was included + BlockHash common.Hash `json:"blockHash"` + // index of the log in the block + Index uint `json:"logIndex" gencodec:"required"` + + // The Removed field is true if this log was reverted due to a chain reorganisation. + // You must pay attention to this field if you receive logs through a filter query. + Removed bool `json:"removed"` +} + +type logMarshaling struct { + Data hexutil.Bytes + BlockNumber hexutil.Uint64 + TxIndex hexutil.Uint + Index hexutil.Uint +} + +type rlpLog struct { + Address common.Address + Topics []common.Hash + Data []byte +} + +// rlpStorageLog is the storage encoding of a log. +type rlpStorageLog rlpLog + +// legacyRlpStorageLog is the previous storage encoding of a log including some redundant fields. +type legacyRlpStorageLog struct { + Address common.Address + Topics []common.Hash + Data []byte + BlockNumber uint64 + TxHash common.Hash + TxIndex uint + BlockHash common.Hash + Index uint +} + +// EncodeRLP implements rlp.Encoder. +func (l *Log) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}) +} + +// DecodeRLP implements rlp.Decoder. +func (l *Log) DecodeRLP(s *rlp.Stream) error { + var dec rlpLog + err := s.Decode(&dec) + if err == nil { + l.Address, l.Topics, l.Data = dec.Address, dec.Topics, dec.Data + } + return err +} + +// LogForStorage is a wrapper around a Log that flattens and parses the entire content of +// a log including non-consensus fields. +type LogForStorage Log + +// EncodeRLP implements rlp.Encoder. +func (l *LogForStorage) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, rlpStorageLog{ + Address: l.Address, + Topics: l.Topics, + Data: l.Data, + }) +} + +// DecodeRLP implements rlp.Decoder. +// +// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later. +func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error { + blob, err := s.Raw() + if err != nil { + return err + } + var dec rlpStorageLog + err = rlp.DecodeBytes(blob, &dec) + if err == nil { + *l = LogForStorage{ + Address: dec.Address, + Topics: dec.Topics, + Data: dec.Data, + } + } else { + // Try to decode log with previous definition. + var dec legacyRlpStorageLog + err = rlp.DecodeBytes(blob, &dec) + if err == nil { + *l = LogForStorage{ + Address: dec.Address, + Topics: dec.Topics, + Data: dec.Data, + } + } + } + return err +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/types/receipt.go b/vendor/github.com/ethereum/go-ethereum/core/types/receipt.go new file mode 100644 index 00000000..a96c7525 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types/receipt.go @@ -0,0 +1,336 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "errors" + "fmt" + "io" + "math/big" + "unsafe" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go + +var ( + receiptStatusFailedRLP = []byte{} + receiptStatusSuccessfulRLP = []byte{0x01} +) + +const ( + // ReceiptStatusFailed is the status code of a transaction if execution failed. + ReceiptStatusFailed = uint64(0) + + // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. + ReceiptStatusSuccessful = uint64(1) +) + +// Receipt represents the results of a transaction. +type Receipt struct { + // Consensus fields: These fields are defined by the Yellow Paper + PostState []byte `json:"root"` + Status uint64 `json:"status"` + CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` + + // Implementation fields: These fields are added by geth when processing a transaction. + // They are stored in the chain database. + TxHash common.Hash `json:"transactionHash" gencodec:"required"` + ContractAddress common.Address `json:"contractAddress"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + + // Inclusion information: These fields provide information about the inclusion of the + // transaction corresponding to this receipt. + BlockHash common.Hash `json:"blockHash,omitempty"` + BlockNumber *big.Int `json:"blockNumber,omitempty"` + TransactionIndex uint `json:"transactionIndex"` +} + +type receiptMarshaling struct { + PostState hexutil.Bytes + Status hexutil.Uint64 + CumulativeGasUsed hexutil.Uint64 + GasUsed hexutil.Uint64 + BlockNumber *hexutil.Big + TransactionIndex hexutil.Uint +} + +// receiptRLP is the consensus encoding of a receipt. +type receiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Bloom Bloom + Logs []*Log +} + +// storedReceiptRLP is the storage encoding of a receipt. +type storedReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Logs []*LogForStorage +} + +// v4StoredReceiptRLP is the storage encoding of a receipt used in database version 4. +type v4StoredReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + TxHash common.Hash + ContractAddress common.Address + Logs []*LogForStorage + GasUsed uint64 +} + +// v3StoredReceiptRLP is the original storage encoding of a receipt including some unnecessary fields. +type v3StoredReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Bloom Bloom + TxHash common.Hash + ContractAddress common.Address + Logs []*LogForStorage + GasUsed uint64 +} + +// NewReceipt creates a barebone transaction receipt, copying the init fields. +func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { + r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: cumulativeGasUsed} + if failed { + r.Status = ReceiptStatusFailed + } else { + r.Status = ReceiptStatusSuccessful + } + return r +} + +// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt +// into an RLP stream. If no post state is present, byzantium fork is assumed. +func (r *Receipt) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}) +} + +// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt +// from an RLP stream. +func (r *Receipt) DecodeRLP(s *rlp.Stream) error { + var dec receiptRLP + if err := s.Decode(&dec); err != nil { + return err + } + if err := r.setStatus(dec.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed, r.Bloom, r.Logs = dec.CumulativeGasUsed, dec.Bloom, dec.Logs + return nil +} + +func (r *Receipt) setStatus(postStateOrStatus []byte) error { + switch { + case bytes.Equal(postStateOrStatus, receiptStatusSuccessfulRLP): + r.Status = ReceiptStatusSuccessful + case bytes.Equal(postStateOrStatus, receiptStatusFailedRLP): + r.Status = ReceiptStatusFailed + case len(postStateOrStatus) == len(common.Hash{}): + r.PostState = postStateOrStatus + default: + return fmt.Errorf("invalid receipt status %x", postStateOrStatus) + } + return nil +} + +func (r *Receipt) statusEncoding() []byte { + if len(r.PostState) == 0 { + if r.Status == ReceiptStatusFailed { + return receiptStatusFailedRLP + } + return receiptStatusSuccessfulRLP + } + return r.PostState +} + +// Size returns the approximate memory used by all internal contents. It is used +// to approximate and limit the memory consumption of various caches. +func (r *Receipt) Size() common.StorageSize { + size := common.StorageSize(unsafe.Sizeof(*r)) + common.StorageSize(len(r.PostState)) + + size += common.StorageSize(len(r.Logs)) * common.StorageSize(unsafe.Sizeof(Log{})) + for _, log := range r.Logs { + size += common.StorageSize(len(log.Topics)*common.HashLength + len(log.Data)) + } + return size +} + +// ReceiptForStorage is a wrapper around a Receipt that flattens and parses the +// entire content of a receipt, as opposed to only the consensus fields originally. +type ReceiptForStorage Receipt + +// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt +// into an RLP stream. +func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { + enc := &storedReceiptRLP{ + PostStateOrStatus: (*Receipt)(r).statusEncoding(), + CumulativeGasUsed: r.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(r.Logs)), + } + for i, log := range r.Logs { + enc.Logs[i] = (*LogForStorage)(log) + } + return rlp.Encode(w, enc) +} + +// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation +// fields of a receipt from an RLP stream. +func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { + // Retrieve the entire receipt blob as we need to try multiple decoders + blob, err := s.Raw() + if err != nil { + return err + } + // Try decoding from the newest format for future proofness, then the older one + // for old nodes that just upgraded. V4 was an intermediate unreleased format so + // we do need to decode it, but it's not common (try last). + if err := decodeStoredReceiptRLP(r, blob); err == nil { + return nil + } + if err := decodeV3StoredReceiptRLP(r, blob); err == nil { + return nil + } + return decodeV4StoredReceiptRLP(r, blob) +} + +func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored storedReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + + return nil +} + +func decodeV4StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored v4StoredReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.TxHash = stored.TxHash + r.ContractAddress = stored.ContractAddress + r.GasUsed = stored.GasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + + return nil +} + +func decodeV3StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored v3StoredReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Bloom = stored.Bloom + r.TxHash = stored.TxHash + r.ContractAddress = stored.ContractAddress + r.GasUsed = stored.GasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + return nil +} + +// Receipts is a wrapper around a Receipt array to implement DerivableList. +type Receipts []*Receipt + +// Len returns the number of receipts in this list. +func (r Receipts) Len() int { return len(r) } + +// GetRlp returns the RLP encoding of one receipt from the list. +func (r Receipts) GetRlp(i int) []byte { + bytes, err := rlp.EncodeToBytes(r[i]) + if err != nil { + panic(err) + } + return bytes +} + +// DeriveFields fills the receipts with their computed fields based on consensus +// data and contextual infos like containing block and transactions. +func (r Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, txs Transactions) error { + signer := MakeSigner(config, new(big.Int).SetUint64(number)) + + logIndex := uint(0) + if len(txs) != len(r) { + return errors.New("transaction and receipt count mismatch") + } + for i := 0; i < len(r); i++ { + // The transaction hash can be retrieved from the transaction itself + r[i].TxHash = txs[i].Hash() + + // block location fields + r[i].BlockHash = hash + r[i].BlockNumber = new(big.Int).SetUint64(number) + r[i].TransactionIndex = uint(i) + + // The contract address can be derived from the transaction itself + if txs[i].To() == nil { + // Deriving the signer is expensive, only do if it's actually needed + from, _ := Sender(signer, txs[i]) + r[i].ContractAddress = crypto.CreateAddress(from, txs[i].Nonce()) + } + // The used gas can be calculated based on previous r + if i == 0 { + r[i].GasUsed = r[i].CumulativeGasUsed + } else { + r[i].GasUsed = r[i].CumulativeGasUsed - r[i-1].CumulativeGasUsed + } + // The derived log fields can simply be set from the block and transaction + for j := 0; j < len(r[i].Logs); j++ { + r[i].Logs[j].BlockNumber = number + r[i].Logs[j].BlockHash = hash + r[i].Logs[j].TxHash = r[i].TxHash + r[i].Logs[j].TxIndex = uint(i) + r[i].Logs[j].Index = logIndex + logIndex++ + } + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/types/transaction.go b/vendor/github.com/ethereum/go-ethereum/core/types/transaction.go new file mode 100644 index 00000000..3eb8df0a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/types/transaction.go @@ -0,0 +1,419 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "container/heap" + "errors" + "io" + "math/big" + "sync/atomic" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" +) + +//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go + +var ( + ErrInvalidSig = errors.New("invalid transaction v, r, s values") +) + +type Transaction struct { + data txdata + // caches + hash atomic.Value + size atomic.Value + from atomic.Value +} + +type txdata struct { + AccountNonce uint64 `json:"nonce" gencodec:"required"` + Price *big.Int `json:"gasPrice" gencodec:"required"` + GasLimit uint64 `json:"gas" gencodec:"required"` + Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation + Amount *big.Int `json:"value" gencodec:"required"` + Payload []byte `json:"input" gencodec:"required"` + + // Signature values + V *big.Int `json:"v" gencodec:"required"` + R *big.Int `json:"r" gencodec:"required"` + S *big.Int `json:"s" gencodec:"required"` + + // This is only used when marshaling to JSON. + Hash *common.Hash `json:"hash" rlp:"-"` +} + +type txdataMarshaling struct { + AccountNonce hexutil.Uint64 + Price *hexutil.Big + GasLimit hexutil.Uint64 + Amount *hexutil.Big + Payload hexutil.Bytes + V *hexutil.Big + R *hexutil.Big + S *hexutil.Big +} + +func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { + return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data) +} + +func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { + return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data) +} + +func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { + if len(data) > 0 { + data = common.CopyBytes(data) + } + d := txdata{ + AccountNonce: nonce, + Recipient: to, + Payload: data, + Amount: new(big.Int), + GasLimit: gasLimit, + Price: new(big.Int), + V: new(big.Int), + R: new(big.Int), + S: new(big.Int), + } + if amount != nil { + d.Amount.Set(amount) + } + if gasPrice != nil { + d.Price.Set(gasPrice) + } + + return &Transaction{data: d} +} + +// ChainId returns which chain id this transaction was signed for (if at all) +func (tx *Transaction) ChainId() *big.Int { + return deriveChainId(tx.data.V) +} + +// Protected returns whether the transaction is protected from replay protection. +func (tx *Transaction) Protected() bool { + return isProtectedV(tx.data.V) +} + +func isProtectedV(V *big.Int) bool { + if V.BitLen() <= 8 { + v := V.Uint64() + return v != 27 && v != 28 + } + // anything not 27 or 28 is considered protected + return true +} + +// EncodeRLP implements rlp.Encoder +func (tx *Transaction) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, &tx.data) +} + +// DecodeRLP implements rlp.Decoder +func (tx *Transaction) DecodeRLP(s *rlp.Stream) error { + _, size, _ := s.Kind() + err := s.Decode(&tx.data) + if err == nil { + tx.size.Store(common.StorageSize(rlp.ListSize(size))) + } + + return err +} + +// MarshalJSON encodes the web3 RPC transaction format. +func (tx *Transaction) MarshalJSON() ([]byte, error) { + hash := tx.Hash() + data := tx.data + data.Hash = &hash + return data.MarshalJSON() +} + +// UnmarshalJSON decodes the web3 RPC transaction format. +func (tx *Transaction) UnmarshalJSON(input []byte) error { + var dec txdata + if err := dec.UnmarshalJSON(input); err != nil { + return err + } + + withSignature := dec.V.Sign() != 0 || dec.R.Sign() != 0 || dec.S.Sign() != 0 + if withSignature { + var V byte + if isProtectedV(dec.V) { + chainID := deriveChainId(dec.V).Uint64() + V = byte(dec.V.Uint64() - 35 - 2*chainID) + } else { + V = byte(dec.V.Uint64() - 27) + } + if !crypto.ValidateSignatureValues(V, dec.R, dec.S, false) { + return ErrInvalidSig + } + } + + *tx = Transaction{data: dec} + return nil +} + +func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } +func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit } +func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } +func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } +func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } +func (tx *Transaction) CheckNonce() bool { return true } + +// To returns the recipient address of the transaction. +// It returns nil if the transaction is a contract creation. +func (tx *Transaction) To() *common.Address { + if tx.data.Recipient == nil { + return nil + } + to := *tx.data.Recipient + return &to +} + +// Hash hashes the RLP encoding of tx. +// It uniquely identifies the transaction. +func (tx *Transaction) Hash() common.Hash { + if hash := tx.hash.Load(); hash != nil { + return hash.(common.Hash) + } + v := rlpHash(tx) + tx.hash.Store(v) + return v +} + +// Size returns the true RLP encoded storage size of the transaction, either by +// encoding and returning it, or returning a previsouly cached value. +func (tx *Transaction) Size() common.StorageSize { + if size := tx.size.Load(); size != nil { + return size.(common.StorageSize) + } + c := writeCounter(0) + rlp.Encode(&c, &tx.data) + tx.size.Store(common.StorageSize(c)) + return common.StorageSize(c) +} + +// AsMessage returns the transaction as a core.Message. +// +// AsMessage requires a signer to derive the sender. +// +// XXX Rename message to something less arbitrary? +func (tx *Transaction) AsMessage(s Signer) (Message, error) { + msg := Message{ + nonce: tx.data.AccountNonce, + gasLimit: tx.data.GasLimit, + gasPrice: new(big.Int).Set(tx.data.Price), + to: tx.data.Recipient, + amount: tx.data.Amount, + data: tx.data.Payload, + checkNonce: true, + } + + var err error + msg.from, err = Sender(s, tx) + return msg, err +} + +// WithSignature returns a new transaction with the given signature. +// This signature needs to be in the [R || S || V] format where V is 0 or 1. +func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) { + r, s, v, err := signer.SignatureValues(tx, sig) + if err != nil { + return nil, err + } + cpy := &Transaction{data: tx.data} + cpy.data.R, cpy.data.S, cpy.data.V = r, s, v + return cpy, nil +} + +// Cost returns amount + gasprice * gaslimit. +func (tx *Transaction) Cost() *big.Int { + total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit)) + total.Add(total, tx.data.Amount) + return total +} + +// RawSignatureValues returns the V, R, S signature values of the transaction. +// The return values should not be modified by the caller. +func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) { + return tx.data.V, tx.data.R, tx.data.S +} + +// Transactions is a Transaction slice type for basic sorting. +type Transactions []*Transaction + +// Len returns the length of s. +func (s Transactions) Len() int { return len(s) } + +// Swap swaps the i'th and the j'th element in s. +func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// GetRlp implements Rlpable and returns the i'th element of s in rlp. +func (s Transactions) GetRlp(i int) []byte { + enc, _ := rlp.EncodeToBytes(s[i]) + return enc +} + +// TxDifference returns a new set which is the difference between a and b. +func TxDifference(a, b Transactions) Transactions { + keep := make(Transactions, 0, len(a)) + + remove := make(map[common.Hash]struct{}) + for _, tx := range b { + remove[tx.Hash()] = struct{}{} + } + + for _, tx := range a { + if _, ok := remove[tx.Hash()]; !ok { + keep = append(keep, tx) + } + } + + return keep +} + +// TxByNonce implements the sort interface to allow sorting a list of transactions +// by their nonces. This is usually only useful for sorting transactions from a +// single account, otherwise a nonce comparison doesn't make much sense. +type TxByNonce Transactions + +func (s TxByNonce) Len() int { return len(s) } +func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce } +func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// TxByPrice implements both the sort and the heap interface, making it useful +// for all at once sorting as well as individually adding and removing elements. +type TxByPrice Transactions + +func (s TxByPrice) Len() int { return len(s) } +func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 } +func (s TxByPrice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s *TxByPrice) Push(x interface{}) { + *s = append(*s, x.(*Transaction)) +} + +func (s *TxByPrice) Pop() interface{} { + old := *s + n := len(old) + x := old[n-1] + *s = old[0 : n-1] + return x +} + +// TransactionsByPriceAndNonce represents a set of transactions that can return +// transactions in a profit-maximizing sorted order, while supporting removing +// entire batches of transactions for non-executable accounts. +type TransactionsByPriceAndNonce struct { + txs map[common.Address]Transactions // Per account nonce-sorted list of transactions + heads TxByPrice // Next transaction for each unique account (price heap) + signer Signer // Signer for the set of transactions +} + +// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve +// price sorted transactions in a nonce-honouring way. +// +// Note, the input map is reowned so the caller should not interact any more with +// if after providing it to the constructor. +func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce { + // Initialize a price based heap with the head transactions + heads := make(TxByPrice, 0, len(txs)) + for from, accTxs := range txs { + heads = append(heads, accTxs[0]) + // Ensure the sender address is from the signer + acc, _ := Sender(signer, accTxs[0]) + txs[acc] = accTxs[1:] + if from != acc { + delete(txs, from) + } + } + heap.Init(&heads) + + // Assemble and return the transaction set + return &TransactionsByPriceAndNonce{ + txs: txs, + heads: heads, + signer: signer, + } +} + +// Peek returns the next transaction by price. +func (t *TransactionsByPriceAndNonce) Peek() *Transaction { + if len(t.heads) == 0 { + return nil + } + return t.heads[0] +} + +// Shift replaces the current best head with the next one from the same account. +func (t *TransactionsByPriceAndNonce) Shift() { + acc, _ := Sender(t.signer, t.heads[0]) + if txs, ok := t.txs[acc]; ok && len(txs) > 0 { + t.heads[0], t.txs[acc] = txs[0], txs[1:] + heap.Fix(&t.heads, 0) + } else { + heap.Pop(&t.heads) + } +} + +// Pop removes the best transaction, *not* replacing it with the next one from +// the same account. This should be used when a transaction cannot be executed +// and hence all subsequent ones should be discarded from the same account. +func (t *TransactionsByPriceAndNonce) Pop() { + heap.Pop(&t.heads) +} + +// Message is a fully derived transaction and implements core.Message +// +// NOTE: In a future PR this will be removed. +type Message struct { + to *common.Address + from common.Address + nonce uint64 + amount *big.Int + gasLimit uint64 + gasPrice *big.Int + data []byte + checkNonce bool +} + +func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message { + return Message{ + from: from, + to: to, + nonce: nonce, + amount: amount, + gasLimit: gasLimit, + gasPrice: gasPrice, + data: data, + checkNonce: checkNonce, + } +} + +func (m Message) From() common.Address { return m.from } +func (m Message) To() *common.Address { return m.to } +func (m Message) GasPrice() *big.Int { return m.gasPrice } +func (m Message) Value() *big.Int { return m.amount } +func (m Message) Gas() uint64 { return m.gasLimit } +func (m Message) Nonce() uint64 { return m.nonce } +func (m Message) Data() []byte { return m.data } +func (m Message) CheckNonce() bool { return m.checkNonce } diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/gas_table.go b/vendor/github.com/ethereum/go-ethereum/core/vm/gas_table.go new file mode 100644 index 00000000..8270300b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/gas_table.go @@ -0,0 +1,513 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/params" +) + +// memoryGasCost calculates the quadratic gas for memory expansion. It does so +// only for the memory region that is expanded, not the total memory. +func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { + if newMemSize == 0 { + return 0, nil + } + // The maximum that will fit in a uint64 is max_word_count - 1. Anything above + // that will result in an overflow. Additionally, a newMemSize which results in + // a newMemSizeWords larger than 0xFFFFFFFF will cause the square operation to + // overflow. The constant 0x1FFFFFFFE0 is the highest number that can be used + // without overflowing the gas calculation. + if newMemSize > 0x1FFFFFFFE0 { + return 0, errGasUintOverflow + } + newMemSizeWords := toWordSize(newMemSize) + newMemSize = newMemSizeWords * 32 + + if newMemSize > uint64(mem.Len()) { + square := newMemSizeWords * newMemSizeWords + linCoef := newMemSizeWords * params.MemoryGas + quadCoef := square / params.QuadCoeffDiv + newTotalFee := linCoef + quadCoef + + fee := newTotalFee - mem.lastGasCost + mem.lastGasCost = newTotalFee + + return fee, nil + } + return 0, nil +} + +func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + + words, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errGasUintOverflow + } + + if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow { + return 0, errGasUintOverflow + } + + if gas, overflow = math.SafeAdd(gas, words); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + + words, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errGasUintOverflow + } + + if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow { + return 0, errGasUintOverflow + } + + if gas, overflow = math.SafeAdd(gas, words); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + y, x = stack.Back(1), stack.Back(0) + current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x)) + ) + // The legacy gas metering only takes into consideration the current state + // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283) + // OR Constantinople is not active + if evm.chainRules.IsPetersburg || !evm.chainRules.IsConstantinople { + // This checks for 3 scenario's and calculates gas accordingly: + // + // 1. From a zero-value address to a non-zero value (NEW VALUE) + // 2. From a non-zero value address to a zero-value address (DELETE) + // 3. From a non-zero to a non-zero (CHANGE) + switch { + case current == (common.Hash{}) && y.Sign() != 0: // 0 => non 0 + return params.SstoreSetGas, nil + case current != (common.Hash{}) && y.Sign() == 0: // non 0 => 0 + evm.StateDB.AddRefund(params.SstoreRefundGas) + return params.SstoreClearGas, nil + default: // non 0 => non 0 (or 0 => 0) + return params.SstoreResetGas, nil + } + } + // The new gas metering is based on net gas costs (EIP-1283): + // + // 1. If current value equals new value (this is a no-op), 200 gas is deducted. + // 2. If current value does not equal new value + // 2.1. If original value equals current value (this storage slot has not been changed by the current execution context) + // 2.1.1. If original value is 0, 20000 gas is deducted. + // 2.1.2. Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter. + // 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. + // 2.2.1. If original value is not 0 + // 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. + // 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. + // 2.2.2. If original value equals new value (this storage slot is reset) + // 2.2.2.1. If original value is 0, add 19800 gas to refund counter. + // 2.2.2.2. Otherwise, add 4800 gas to refund counter. + value := common.BigToHash(y) + if current == value { // noop (1) + return params.NetSstoreNoopGas, nil + } + original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x)) + if original == current { + if original == (common.Hash{}) { // create slot (2.1.1) + return params.NetSstoreInitGas, nil + } + if value == (common.Hash{}) { // delete slot (2.1.2b) + evm.StateDB.AddRefund(params.NetSstoreClearRefund) + } + return params.NetSstoreCleanGas, nil // write existing slot (2.1.2) + } + if original != (common.Hash{}) { + if current == (common.Hash{}) { // recreate slot (2.2.1.1) + evm.StateDB.SubRefund(params.NetSstoreClearRefund) + } else if value == (common.Hash{}) { // delete slot (2.2.1.2) + evm.StateDB.AddRefund(params.NetSstoreClearRefund) + } + } + if original == value { + if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1) + evm.StateDB.AddRefund(params.NetSstoreResetClearRefund) + } else { // reset to original existing slot (2.2.2.2) + evm.StateDB.AddRefund(params.NetSstoreResetRefund) + } + } + return params.NetSstoreDirtyGas, nil +} + +func makeGasLog(n uint64) gasFunc { + return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + requestedSize, overflow := bigUint64(stack.Back(1)) + if overflow { + return 0, errGasUintOverflow + } + + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow { + return 0, errGasUintOverflow + } + + var memorySizeGas uint64 + if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil + } +} + +func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow { + return 0, errGasUintOverflow + } + + wordGas, overflow := bigUint64(stack.Back(1)) + if overflow { + return 0, errGasUintOverflow + } + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, wordGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + + wordGas, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errGasUintOverflow + } + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, wordGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + + var overflow bool + if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow { + return 0, errGasUintOverflow + } + + wordGas, overflow := bigUint64(stack.Back(3)) + if overflow { + return 0, errGasUintOverflow + } + + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow { + return 0, errGasUintOverflow + } + + if gas, overflow = math.SafeAdd(gas, wordGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.ExtcodeHash, nil +} + +func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, params.Create2Gas); overflow { + return 0, errGasUintOverflow + } + wordGas, overflow := bigUint64(stack.Back(2)) + if overflow { + return 0, errGasUintOverflow + } + if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow { + return 0, errGasUintOverflow + } + if gas, overflow = math.SafeAdd(gas, wordGas); overflow { + return 0, errGasUintOverflow + } + + return gas, nil +} + +func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.Balance, nil +} + +func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.ExtcodeSize, nil +} + +func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.SLoad, nil +} + +func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8) + + var ( + gas = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas + overflow bool + ) + if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + gas = gt.Calls + transfersValue = stack.Back(2).Sign() != 0 + address = common.BigToAddress(stack.Back(1)) + eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber) + ) + if eip158 { + if transfersValue && evm.StateDB.Empty(address) { + gas += params.CallNewAccountGas + } + } else if !evm.StateDB.Exist(address) { + gas += params.CallNewAccountGas + } + if transfersValue { + gas += params.CallValueTransferGas + } + memoryGas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { + return 0, errGasUintOverflow + } + + evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas := gt.Calls + if stack.Back(2).Sign() != 0 { + gas += params.CallValueTransferGas + } + memoryGas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { + return 0, errGasUintOverflow + } + + evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return memoryGasCost(mem, memorySize) +} + +func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return memoryGasCost(mem, memorySize) +} + +func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var gas uint64 + // EIP150 homestead gas reprice fork: + if evm.ChainConfig().IsEIP150(evm.BlockNumber) { + gas = gt.Suicide + var ( + address = common.BigToAddress(stack.Back(0)) + eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber) + ) + + if eip158 { + // if empty and transfers value + if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { + gas += gt.CreateBySuicide + } + } else if !evm.StateDB.Exist(address) { + gas += gt.CreateBySuicide + } + } + + if !evm.StateDB.HasSuicided(contract.Address()) { + evm.StateDB.AddRefund(params.SuicideRefundGas) + } + return gas, nil +} + +func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow { + return 0, errGasUintOverflow + } + + evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + +func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow { + return 0, errGasUintOverflow + } + + evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0)) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/interface.go b/vendor/github.com/ethereum/go-ethereum/core/vm/interface.go new file mode 100644 index 00000000..dd401466 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/interface.go @@ -0,0 +1,80 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// StateDB is an EVM database for full state querying. +type StateDB interface { + CreateAccount(common.Address) + + SubBalance(common.Address, *big.Int) + AddBalance(common.Address, *big.Int) + GetBalance(common.Address) *big.Int + + GetNonce(common.Address) uint64 + SetNonce(common.Address, uint64) + + GetCodeHash(common.Address) common.Hash + GetCode(common.Address) []byte + SetCode(common.Address, []byte) + GetCodeSize(common.Address) int + + AddRefund(uint64) + SubRefund(uint64) + GetRefund() uint64 + + GetCommittedState(common.Address, common.Hash) common.Hash + GetState(common.Address, common.Hash) common.Hash + SetState(common.Address, common.Hash, common.Hash) + + Suicide(common.Address) bool + HasSuicided(common.Address) bool + + // Exist reports whether the given account exists in state. + // Notably this should also return true for suicided accounts. + Exist(common.Address) bool + // Empty returns whether the given account is empty. Empty + // is defined according to EIP161 (balance = nonce = code = 0). + Empty(common.Address) bool + + RevertToSnapshot(int) + Snapshot() int + + AddLog(*types.Log) + AddPreimage(common.Hash, []byte) + + ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error +} + +// CallContext provides a basic interface for the EVM calling conventions. The EVM +// depends on this context being implemented for doing subcalls and initialising new EVM contracts. +type CallContext interface { + // Call another contract + Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) + // Take another's contract code and execute within our own context + CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) + // Same as CallCode except sender and value is propagated from parent to child scope + DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) + // Create a new contract + Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/interpreter.go b/vendor/github.com/ethereum/go-ethereum/core/vm/interpreter.go new file mode 100644 index 00000000..989f85f5 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/interpreter.go @@ -0,0 +1,282 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "fmt" + "hash" + "sync/atomic" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/params" +) + +// Config are the configuration options for the Interpreter +type Config struct { + Debug bool // Enables debugging + Tracer Tracer // Opcode logger + NoRecursion bool // Disables call, callcode, delegate call and create + EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages + + JumpTable [256]operation // EVM instruction table, automatically populated if unset + + EWASMInterpreter string // External EWASM interpreter options + EVMInterpreter string // External EVM interpreter options +} + +// Interpreter is used to run Ethereum based contracts and will utilise the +// passed environment to query external sources for state information. +// The Interpreter will run the byte code VM based on the passed +// configuration. +type Interpreter interface { + // Run loops and evaluates the contract's code with the given input data and returns + // the return byte-slice and an error if one occurred. + Run(contract *Contract, input []byte, static bool) ([]byte, error) + // CanRun tells if the contract, passed as an argument, can be + // run by the current interpreter. This is meant so that the + // caller can do something like: + // + // ```golang + // for _, interpreter := range interpreters { + // if interpreter.CanRun(contract.code) { + // interpreter.Run(contract.code, input) + // } + // } + // ``` + CanRun([]byte) bool +} + +// keccakState wraps sha3.state. In addition to the usual hash methods, it also supports +// Read to get a variable amount of data from the hash state. Read is faster than Sum +// because it doesn't copy the internal state, but also modifies the internal state. +type keccakState interface { + hash.Hash + Read([]byte) (int, error) +} + +// EVMInterpreter represents an EVM interpreter +type EVMInterpreter struct { + evm *EVM + cfg Config + gasTable params.GasTable + + intPool *intPool + + hasher keccakState // Keccak256 hasher instance shared across opcodes + hasherBuf common.Hash // Keccak256 hasher result array shared aross opcodes + + readOnly bool // Whether to throw on stateful modifications + returnData []byte // Last CALL's return data for subsequent reuse +} + +// NewEVMInterpreter returns a new instance of the Interpreter. +func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { + // We use the STOP instruction whether to see + // the jump table was initialised. If it was not + // we'll set the default jump table. + if !cfg.JumpTable[STOP].valid { + switch { + case evm.ChainConfig().IsConstantinople(evm.BlockNumber): + cfg.JumpTable = constantinopleInstructionSet + case evm.ChainConfig().IsByzantium(evm.BlockNumber): + cfg.JumpTable = byzantiumInstructionSet + case evm.ChainConfig().IsHomestead(evm.BlockNumber): + cfg.JumpTable = homesteadInstructionSet + default: + cfg.JumpTable = frontierInstructionSet + } + } + + return &EVMInterpreter{ + evm: evm, + cfg: cfg, + gasTable: evm.ChainConfig().GasTable(evm.BlockNumber), + } +} + +// Run loops and evaluates the contract's code with the given input data and returns +// the return byte-slice and an error if one occurred. +// +// It's important to note that any errors returned by the interpreter should be +// considered a revert-and-consume-all-gas operation except for +// errExecutionReverted which means revert-and-keep-gas-left. +func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) { + if in.intPool == nil { + in.intPool = poolOfIntPools.get() + defer func() { + poolOfIntPools.put(in.intPool) + in.intPool = nil + }() + } + + // Increment the call depth which is restricted to 1024 + in.evm.depth++ + defer func() { in.evm.depth-- }() + + // Make sure the readOnly is only set if we aren't in readOnly yet. + // This makes also sure that the readOnly flag isn't removed for child calls. + if readOnly && !in.readOnly { + in.readOnly = true + defer func() { in.readOnly = false }() + } + + // Reset the previous call's return data. It's unimportant to preserve the old buffer + // as every returning call will return new data anyway. + in.returnData = nil + + // Don't bother with the execution if there's no code. + if len(contract.Code) == 0 { + return nil, nil + } + + var ( + op OpCode // current opcode + mem = NewMemory() // bound memory + stack = newstack() // local stack + // For optimisation reason we're using uint64 as the program counter. + // It's theoretically possible to go above 2^64. The YP defines the PC + // to be uint256. Practically much less so feasible. + pc = uint64(0) // program counter + cost uint64 + // copies used by tracer + pcCopy uint64 // needed for the deferred Tracer + gasCopy uint64 // for Tracer to log gas remaining before execution + logged bool // deferred Tracer should ignore already logged steps + res []byte // result of the opcode execution function + ) + contract.Input = input + + // Reclaim the stack as an int pool when the execution stops + defer func() { in.intPool.put(stack.data...) }() + + if in.cfg.Debug { + defer func() { + if err != nil { + if !logged { + in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + } else { + in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + } + } + }() + } + // The Interpreter main run loop (contextual). This loop runs until either an + // explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during + // the execution of one of the operations or until the done flag is set by the + // parent context. + for atomic.LoadInt32(&in.evm.abort) == 0 { + if in.cfg.Debug { + // Capture pre-execution values for tracing. + logged, pcCopy, gasCopy = false, pc, contract.Gas + } + + // Get the operation from the jump table and validate the stack to ensure there are + // enough stack items available to perform the operation. + op = contract.GetOp(pc) + operation := in.cfg.JumpTable[op] + if !operation.valid { + return nil, fmt.Errorf("invalid opcode 0x%x", int(op)) + } + // Validate stack + if sLen := stack.len(); sLen < operation.minStack { + return nil, fmt.Errorf("stack underflow (%d <=> %d)", sLen, operation.minStack) + } else if sLen > operation.maxStack { + return nil, fmt.Errorf("stack limit reached %d (%d)", sLen, operation.maxStack) + } + // If the operation is valid, enforce and write restrictions + if in.readOnly && in.evm.chainRules.IsByzantium { + // If the interpreter is operating in readonly mode, make sure no + // state-modifying operation is performed. The 3rd stack item + // for a call operation is the value. Transferring value from one + // account to the others means the state is modified and should also + // return with an error. + if operation.writes || (op == CALL && stack.Back(2).Sign() != 0) { + return nil, errWriteProtection + } + } + // Static portion of gas + if !contract.UseGas(operation.constantGas) { + return nil, ErrOutOfGas + } + + var memorySize uint64 + // calculate the new memory size and expand the memory to fit + // the operation + // Memory check needs to be done prior to evaluating the dynamic gas portion, + // to detect calculation overflows + if operation.memorySize != nil { + memSize, overflow := operation.memorySize(stack) + if overflow { + return nil, errGasUintOverflow + } + // memory is expanded in words of 32 bytes. Gas + // is also calculated in words. + if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow { + return nil, errGasUintOverflow + } + } + // Dynamic portion of gas + // consume the gas and return an error if not enough gas is available. + // cost is explicitly set so that the capture state defer method can get the proper cost + if operation.dynamicGas != nil { + cost, err = operation.dynamicGas(in.gasTable, in.evm, contract, stack, mem, memorySize) + if err != nil || !contract.UseGas(cost) { + return nil, ErrOutOfGas + } + } + if memorySize > 0 { + mem.Resize(memorySize) + } + + if in.cfg.Debug { + in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) + logged = true + } + + // execute the operation + res, err = operation.execute(&pc, in, contract, mem, stack) + // verifyPool is a build flag. Pool verification makes sure the integrity + // of the integer pool by comparing values to a default value. + if verifyPool { + verifyIntegerPool(in.intPool) + } + // if the operation clears the return data (e.g. it has returning data) + // set the last return to the result of the operation. + if operation.returns { + in.returnData = res + } + + switch { + case err != nil: + return nil, err + case operation.reverts: + return res, errExecutionReverted + case operation.halts: + return res, nil + case !operation.jumps: + pc++ + } + } + return nil, nil +} + +// CanRun tells if the contract, passed as an argument, can be +// run by the current interpreter. +func (in *EVMInterpreter) CanRun(code []byte) bool { + return true +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/logger.go b/vendor/github.com/ethereum/go-ethereum/core/vm/logger.go new file mode 100644 index 00000000..262ee5cc --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/logger.go @@ -0,0 +1,256 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "encoding/hex" + "fmt" + "io" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" +) + +// Storage represents a contract's storage. +type Storage map[common.Hash]common.Hash + +// Copy duplicates the current storage. +func (s Storage) Copy() Storage { + cpy := make(Storage) + for key, value := range s { + cpy[key] = value + } + + return cpy +} + +// LogConfig are the configuration options for structured logger the EVM +type LogConfig struct { + DisableMemory bool // disable memory capture + DisableStack bool // disable stack capture + DisableStorage bool // disable storage capture + Debug bool // print output during capture end + Limit int // maximum length of output, but zero means unlimited +} + +//go:generate gencodec -type StructLog -field-override structLogMarshaling -out gen_structlog.go + +// StructLog is emitted to the EVM each cycle and lists information about the current internal state +// prior to the execution of the statement. +type StructLog struct { + Pc uint64 `json:"pc"` + Op OpCode `json:"op"` + Gas uint64 `json:"gas"` + GasCost uint64 `json:"gasCost"` + Memory []byte `json:"memory"` + MemorySize int `json:"memSize"` + Stack []*big.Int `json:"stack"` + Storage map[common.Hash]common.Hash `json:"-"` + Depth int `json:"depth"` + RefundCounter uint64 `json:"refund"` + Err error `json:"-"` +} + +// overrides for gencodec +type structLogMarshaling struct { + Stack []*math.HexOrDecimal256 + Gas math.HexOrDecimal64 + GasCost math.HexOrDecimal64 + Memory hexutil.Bytes + OpName string `json:"opName"` // adds call to OpName() in MarshalJSON + ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON +} + +// OpName formats the operand name in a human-readable format. +func (s *StructLog) OpName() string { + return s.Op.String() +} + +// ErrorString formats the log's error as a string. +func (s *StructLog) ErrorString() string { + if s.Err != nil { + return s.Err.Error() + } + return "" +} + +// Tracer is used to collect execution traces from an EVM transaction +// execution. CaptureState is called for each step of the VM with the +// current VM state. +// Note that reference types are actual VM data structures; make copies +// if you need to retain them beyond the current call. +type Tracer interface { + CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error + CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error + CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error + CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error +} + +// StructLogger is an EVM state logger and implements Tracer. +// +// StructLogger can capture state based on the given Log configuration and also keeps +// a track record of modified storage which is used in reporting snapshots of the +// contract their storage. +type StructLogger struct { + cfg LogConfig + + logs []StructLog + changedValues map[common.Address]Storage + output []byte + err error +} + +// NewStructLogger returns a new logger +func NewStructLogger(cfg *LogConfig) *StructLogger { + logger := &StructLogger{ + changedValues: make(map[common.Address]Storage), + } + if cfg != nil { + logger.cfg = *cfg + } + return logger +} + +// CaptureStart implements the Tracer interface to initialize the tracing operation. +func (l *StructLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { + return nil +} + +// CaptureState logs a new structured log message and pushes it out to the environment +// +// CaptureState also tracks SSTORE ops to track dirty values. +func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { + // check if already accumulated the specified number of logs + if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { + return ErrTraceLimitReached + } + + // initialise new changed values storage container for this contract + // if not present. + if l.changedValues[contract.Address()] == nil { + l.changedValues[contract.Address()] = make(Storage) + } + + // capture SSTORE opcodes and determine the changed value and store + // it in the local storage container. + if op == SSTORE && stack.len() >= 2 { + var ( + value = common.BigToHash(stack.data[stack.len()-2]) + address = common.BigToHash(stack.data[stack.len()-1]) + ) + l.changedValues[contract.Address()][address] = value + } + // Copy a snapshot of the current memory state to a new buffer + var mem []byte + if !l.cfg.DisableMemory { + mem = make([]byte, len(memory.Data())) + copy(mem, memory.Data()) + } + // Copy a snapshot of the current stack state to a new buffer + var stck []*big.Int + if !l.cfg.DisableStack { + stck = make([]*big.Int, len(stack.Data())) + for i, item := range stack.Data() { + stck[i] = new(big.Int).Set(item) + } + } + // Copy a snapshot of the current storage to a new container + var storage Storage + if !l.cfg.DisableStorage { + storage = l.changedValues[contract.Address()].Copy() + } + // create a new snapshot of the EVM. + log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, env.StateDB.GetRefund(), err} + + l.logs = append(l.logs, log) + return nil +} + +// CaptureFault implements the Tracer interface to trace an execution fault +// while running an opcode. +func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { + return nil +} + +// CaptureEnd is called after the call finishes to finalize the tracing. +func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { + l.output = output + l.err = err + if l.cfg.Debug { + fmt.Printf("0x%x\n", output) + if err != nil { + fmt.Printf(" error: %v\n", err) + } + } + return nil +} + +// StructLogs returns the captured log entries. +func (l *StructLogger) StructLogs() []StructLog { return l.logs } + +// Error returns the VM error captured by the trace. +func (l *StructLogger) Error() error { return l.err } + +// Output returns the VM return value captured by the trace. +func (l *StructLogger) Output() []byte { return l.output } + +// WriteTrace writes a formatted trace to the given writer +func WriteTrace(writer io.Writer, logs []StructLog) { + for _, log := range logs { + fmt.Fprintf(writer, "%-16spc=%08d gas=%v cost=%v", log.Op, log.Pc, log.Gas, log.GasCost) + if log.Err != nil { + fmt.Fprintf(writer, " ERROR: %v", log.Err) + } + fmt.Fprintln(writer) + + if len(log.Stack) > 0 { + fmt.Fprintln(writer, "Stack:") + for i := len(log.Stack) - 1; i >= 0; i-- { + fmt.Fprintf(writer, "%08d %x\n", len(log.Stack)-i-1, math.PaddedBigBytes(log.Stack[i], 32)) + } + } + if len(log.Memory) > 0 { + fmt.Fprintln(writer, "Memory:") + fmt.Fprint(writer, hex.Dump(log.Memory)) + } + if len(log.Storage) > 0 { + fmt.Fprintln(writer, "Storage:") + for h, item := range log.Storage { + fmt.Fprintf(writer, "%x: %x\n", h, item) + } + } + fmt.Fprintln(writer) + } +} + +// WriteLogs writes vm logs in a readable format to the given writer +func WriteLogs(writer io.Writer, logs []*types.Log) { + for _, log := range logs { + fmt.Fprintf(writer, "LOG%d: %x bn=%d txi=%x\n", len(log.Topics), log.Address, log.BlockNumber, log.TxIndex) + + for i, topic := range log.Topics { + fmt.Fprintf(writer, "%08d %x\n", i, topic) + } + + fmt.Fprint(writer, hex.Dump(log.Data)) + fmt.Fprintln(writer) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json new file mode 100644 index 00000000..c03ae96a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json new file mode 100644 index 00000000..aba5f246 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json new file mode 100644 index 00000000..88d7c7d8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json new file mode 100644 index 00000000..b1f9c7fb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333332"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json new file mode 100644 index 00000000..937eadb0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json new file mode 100644 index 00000000..61818357 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000c35"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3cb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"58cd20afa2f05a708ede54b48d3ae685db76b3bb83cf2cf95d4e8fb00bcbe61d"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"a732df505d0fa58f7121ab4b72c5197a24894c447c30d306a2b1704ff43419e3"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json new file mode 100644 index 00000000..637bd3f6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json new file mode 100644 index 00000000..55252a4d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json new file mode 100644 index 00000000..192503f2 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json new file mode 100644 index 00000000..dc44c253 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json new file mode 100644 index 00000000..bfa561b5 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json new file mode 100644 index 00000000..c93abbd6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json new file mode 100644 index 00000000..18cb666a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json new file mode 100644 index 00000000..aa581a65 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json new file mode 100644 index 00000000..65e9c07b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000a0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json new file mode 100644 index 00000000..a3849135 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json new file mode 100644 index 00000000..bdadd400 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json new file mode 100644 index 00000000..4369b96f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json new file mode 100644 index 00000000..980e0341 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json new file mode 100644 index 00000000..b3881a5a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000007"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json new file mode 100644 index 00000000..4cc2dddd --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json @@ -0,0 +1 @@ +[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/bn256.go b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/bn256.go new file mode 100644 index 00000000..38822a76 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/bn256.go @@ -0,0 +1,490 @@ +// Package bn256 implements a particular bilinear group at the 128-bit security +// level. +// +// Bilinear groups are the basis of many of the new cryptographic protocols that +// have been proposed over the past decade. They consist of a triplet of groups +// (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ +// is a generator of the respective group). That function is called a pairing +// function. +// +// This package specifically implements the Optimal Ate pairing over a 256-bit +// Barreto-Naehrig curve as described in +// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible +// with the implementation described in that paper. +package bn256 + +import ( + "crypto/rand" + "errors" + "io" + "math/big" +) + +func randomK(r io.Reader) (k *big.Int, err error) { + for { + k, err = rand.Int(r, Order) + if k.Sign() > 0 || err != nil { + return + } + } +} + +// G1 is an abstract cyclic group. The zero value is suitable for use as the +// output of an operation, but cannot be used as an input. +type G1 struct { + p *curvePoint +} + +// RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r. +func RandomG1(r io.Reader) (*big.Int, *G1, error) { + k, err := randomK(r) + if err != nil { + return nil, nil, err + } + + return k, new(G1).ScalarBaseMult(k), nil +} + +func (g *G1) String() string { + return "bn256.G1" + g.p.String() +} + +// ScalarBaseMult sets e to g*k where g is the generator of the group and then +// returns e. +func (e *G1) ScalarBaseMult(k *big.Int) *G1 { + if e.p == nil { + e.p = &curvePoint{} + } + e.p.Mul(curveGen, k) + return e +} + +// ScalarMult sets e to a*k and then returns e. +func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 { + if e.p == nil { + e.p = &curvePoint{} + } + e.p.Mul(a.p, k) + return e +} + +// Add sets e to a+b and then returns e. +func (e *G1) Add(a, b *G1) *G1 { + if e.p == nil { + e.p = &curvePoint{} + } + e.p.Add(a.p, b.p) + return e +} + +// Neg sets e to -a and then returns e. +func (e *G1) Neg(a *G1) *G1 { + if e.p == nil { + e.p = &curvePoint{} + } + e.p.Neg(a.p) + return e +} + +// Set sets e to a and then returns e. +func (e *G1) Set(a *G1) *G1 { + if e.p == nil { + e.p = &curvePoint{} + } + e.p.Set(a.p) + return e +} + +// Marshal converts e to a byte slice. +func (e *G1) Marshal() []byte { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + + if e.p == nil { + e.p = &curvePoint{} + } + + e.p.MakeAffine() + ret := make([]byte, numBytes*2) + if e.p.IsInfinity() { + return ret + } + temp := &gfP{} + + montDecode(temp, &e.p.x) + temp.Marshal(ret) + montDecode(temp, &e.p.y) + temp.Marshal(ret[numBytes:]) + + return ret +} + +// Unmarshal sets e to the result of converting the output of Marshal back into +// a group element and then returns e. +func (e *G1) Unmarshal(m []byte) ([]byte, error) { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + if len(m) < 2*numBytes { + return nil, errors.New("bn256: not enough data") + } + // Unmarshal the points and check their caps + if e.p == nil { + e.p = &curvePoint{} + } else { + e.p.x, e.p.y = gfP{0}, gfP{0} + } + var err error + if err = e.p.x.Unmarshal(m); err != nil { + return nil, err + } + if err = e.p.y.Unmarshal(m[numBytes:]); err != nil { + return nil, err + } + // Encode into Montgomery form and ensure it's on the curve + montEncode(&e.p.x, &e.p.x) + montEncode(&e.p.y, &e.p.y) + + zero := gfP{0} + if e.p.x == zero && e.p.y == zero { + // This is the point at infinity. + e.p.y = *newGFp(1) + e.p.z = gfP{0} + e.p.t = gfP{0} + } else { + e.p.z = *newGFp(1) + e.p.t = *newGFp(1) + + if !e.p.IsOnCurve() { + return nil, errors.New("bn256: malformed point") + } + } + return m[2*numBytes:], nil +} + +// G2 is an abstract cyclic group. The zero value is suitable for use as the +// output of an operation, but cannot be used as an input. +type G2 struct { + p *twistPoint +} + +// RandomG2 returns x and g₂ˣ where x is a random, non-zero number read from r. +func RandomG2(r io.Reader) (*big.Int, *G2, error) { + k, err := randomK(r) + if err != nil { + return nil, nil, err + } + + return k, new(G2).ScalarBaseMult(k), nil +} + +func (e *G2) String() string { + return "bn256.G2" + e.p.String() +} + +// ScalarBaseMult sets e to g*k where g is the generator of the group and then +// returns out. +func (e *G2) ScalarBaseMult(k *big.Int) *G2 { + if e.p == nil { + e.p = &twistPoint{} + } + e.p.Mul(twistGen, k) + return e +} + +// ScalarMult sets e to a*k and then returns e. +func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 { + if e.p == nil { + e.p = &twistPoint{} + } + e.p.Mul(a.p, k) + return e +} + +// Add sets e to a+b and then returns e. +func (e *G2) Add(a, b *G2) *G2 { + if e.p == nil { + e.p = &twistPoint{} + } + e.p.Add(a.p, b.p) + return e +} + +// Neg sets e to -a and then returns e. +func (e *G2) Neg(a *G2) *G2 { + if e.p == nil { + e.p = &twistPoint{} + } + e.p.Neg(a.p) + return e +} + +// Set sets e to a and then returns e. +func (e *G2) Set(a *G2) *G2 { + if e.p == nil { + e.p = &twistPoint{} + } + e.p.Set(a.p) + return e +} + +// Marshal converts e into a byte slice. +func (e *G2) Marshal() []byte { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + + if e.p == nil { + e.p = &twistPoint{} + } + + e.p.MakeAffine() + ret := make([]byte, numBytes*4) + if e.p.IsInfinity() { + return ret + } + temp := &gfP{} + + montDecode(temp, &e.p.x.x) + temp.Marshal(ret) + montDecode(temp, &e.p.x.y) + temp.Marshal(ret[numBytes:]) + montDecode(temp, &e.p.y.x) + temp.Marshal(ret[2*numBytes:]) + montDecode(temp, &e.p.y.y) + temp.Marshal(ret[3*numBytes:]) + + return ret +} + +// Unmarshal sets e to the result of converting the output of Marshal back into +// a group element and then returns e. +func (e *G2) Unmarshal(m []byte) ([]byte, error) { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + if len(m) < 4*numBytes { + return nil, errors.New("bn256: not enough data") + } + // Unmarshal the points and check their caps + if e.p == nil { + e.p = &twistPoint{} + } + var err error + if err = e.p.x.x.Unmarshal(m); err != nil { + return nil, err + } + if err = e.p.x.y.Unmarshal(m[numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.x.Unmarshal(m[2*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.y.Unmarshal(m[3*numBytes:]); err != nil { + return nil, err + } + // Encode into Montgomery form and ensure it's on the curve + montEncode(&e.p.x.x, &e.p.x.x) + montEncode(&e.p.x.y, &e.p.x.y) + montEncode(&e.p.y.x, &e.p.y.x) + montEncode(&e.p.y.y, &e.p.y.y) + + if e.p.x.IsZero() && e.p.y.IsZero() { + // This is the point at infinity. + e.p.y.SetOne() + e.p.z.SetZero() + e.p.t.SetZero() + } else { + e.p.z.SetOne() + e.p.t.SetOne() + + if !e.p.IsOnCurve() { + return nil, errors.New("bn256: malformed point") + } + } + return m[4*numBytes:], nil +} + +// GT is an abstract cyclic group. The zero value is suitable for use as the +// output of an operation, but cannot be used as an input. +type GT struct { + p *gfP12 +} + +// Pair calculates an Optimal Ate pairing. +func Pair(g1 *G1, g2 *G2) *GT { + return >{optimalAte(g2.p, g1.p)} +} + +// PairingCheck calculates the Optimal Ate pairing for a set of points. +func PairingCheck(a []*G1, b []*G2) bool { + acc := new(gfP12) + acc.SetOne() + + for i := 0; i < len(a); i++ { + if a[i].p.IsInfinity() || b[i].p.IsInfinity() { + continue + } + acc.Mul(acc, miller(b[i].p, a[i].p)) + } + return finalExponentiation(acc).IsOne() +} + +// Miller applies Miller's algorithm, which is a bilinear function from the +// source groups to F_p^12. Miller(g1, g2).Finalize() is equivalent to Pair(g1, +// g2). +func Miller(g1 *G1, g2 *G2) *GT { + return >{miller(g2.p, g1.p)} +} + +func (g *GT) String() string { + return "bn256.GT" + g.p.String() +} + +// ScalarMult sets e to a*k and then returns e. +func (e *GT) ScalarMult(a *GT, k *big.Int) *GT { + if e.p == nil { + e.p = &gfP12{} + } + e.p.Exp(a.p, k) + return e +} + +// Add sets e to a+b and then returns e. +func (e *GT) Add(a, b *GT) *GT { + if e.p == nil { + e.p = &gfP12{} + } + e.p.Mul(a.p, b.p) + return e +} + +// Neg sets e to -a and then returns e. +func (e *GT) Neg(a *GT) *GT { + if e.p == nil { + e.p = &gfP12{} + } + e.p.Conjugate(a.p) + return e +} + +// Set sets e to a and then returns e. +func (e *GT) Set(a *GT) *GT { + if e.p == nil { + e.p = &gfP12{} + } + e.p.Set(a.p) + return e +} + +// Finalize is a linear function from F_p^12 to GT. +func (e *GT) Finalize() *GT { + ret := finalExponentiation(e.p) + e.p.Set(ret) + return e +} + +// Marshal converts e into a byte slice. +func (e *GT) Marshal() []byte { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + + if e.p == nil { + e.p = &gfP12{} + e.p.SetOne() + } + + ret := make([]byte, numBytes*12) + temp := &gfP{} + + montDecode(temp, &e.p.x.x.x) + temp.Marshal(ret) + montDecode(temp, &e.p.x.x.y) + temp.Marshal(ret[numBytes:]) + montDecode(temp, &e.p.x.y.x) + temp.Marshal(ret[2*numBytes:]) + montDecode(temp, &e.p.x.y.y) + temp.Marshal(ret[3*numBytes:]) + montDecode(temp, &e.p.x.z.x) + temp.Marshal(ret[4*numBytes:]) + montDecode(temp, &e.p.x.z.y) + temp.Marshal(ret[5*numBytes:]) + montDecode(temp, &e.p.y.x.x) + temp.Marshal(ret[6*numBytes:]) + montDecode(temp, &e.p.y.x.y) + temp.Marshal(ret[7*numBytes:]) + montDecode(temp, &e.p.y.y.x) + temp.Marshal(ret[8*numBytes:]) + montDecode(temp, &e.p.y.y.y) + temp.Marshal(ret[9*numBytes:]) + montDecode(temp, &e.p.y.z.x) + temp.Marshal(ret[10*numBytes:]) + montDecode(temp, &e.p.y.z.y) + temp.Marshal(ret[11*numBytes:]) + + return ret +} + +// Unmarshal sets e to the result of converting the output of Marshal back into +// a group element and then returns e. +func (e *GT) Unmarshal(m []byte) ([]byte, error) { + // Each value is a 256-bit number. + const numBytes = 256 / 8 + + if len(m) < 12*numBytes { + return nil, errors.New("bn256: not enough data") + } + + if e.p == nil { + e.p = &gfP12{} + } + + var err error + if err = e.p.x.x.x.Unmarshal(m); err != nil { + return nil, err + } + if err = e.p.x.x.y.Unmarshal(m[numBytes:]); err != nil { + return nil, err + } + if err = e.p.x.y.x.Unmarshal(m[2*numBytes:]); err != nil { + return nil, err + } + if err = e.p.x.y.y.Unmarshal(m[3*numBytes:]); err != nil { + return nil, err + } + if err = e.p.x.z.x.Unmarshal(m[4*numBytes:]); err != nil { + return nil, err + } + if err = e.p.x.z.y.Unmarshal(m[5*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.x.x.Unmarshal(m[6*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.x.y.Unmarshal(m[7*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.y.x.Unmarshal(m[8*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.y.y.Unmarshal(m[9*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.z.x.Unmarshal(m[10*numBytes:]); err != nil { + return nil, err + } + if err = e.p.y.z.y.Unmarshal(m[11*numBytes:]); err != nil { + return nil, err + } + montEncode(&e.p.x.x.x, &e.p.x.x.x) + montEncode(&e.p.x.x.y, &e.p.x.x.y) + montEncode(&e.p.x.y.x, &e.p.x.y.x) + montEncode(&e.p.x.y.y, &e.p.x.y.y) + montEncode(&e.p.x.z.x, &e.p.x.z.x) + montEncode(&e.p.x.z.y, &e.p.x.z.y) + montEncode(&e.p.y.x.x, &e.p.y.x.x) + montEncode(&e.p.y.x.y, &e.p.y.x.y) + montEncode(&e.p.y.y.x, &e.p.y.y.x) + montEncode(&e.p.y.y.y, &e.p.y.y.y) + montEncode(&e.p.y.z.x, &e.p.y.z.x) + montEncode(&e.p.y.z.y, &e.p.y.z.y) + + return m[12*numBytes:], nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/constants.go b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/constants.go new file mode 100644 index 00000000..f7d2c7c0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/constants.go @@ -0,0 +1,62 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bn256 + +import ( + "math/big" +) + +func bigFromBase10(s string) *big.Int { + n, _ := new(big.Int).SetString(s, 10) + return n +} + +// u is the BN parameter. +var u = bigFromBase10("4965661367192848881") + +// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. +// Needs to be highly 2-adic for efficient SNARK key and proof generation. +// Order - 1 = 2^28 * 3^2 * 13 * 29 * 983 * 11003 * 237073 * 405928799 * 1670836401704629 * 13818364434197438864469338081. +// Refer to https://eprint.iacr.org/2013/879.pdf and https://eprint.iacr.org/2013/507.pdf for more information on these parameters. +var Order = bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617") + +// P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. +var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583") + +// p2 is p, represented as little-endian 64-bit words. +var p2 = [4]uint64{0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} + +// np is the negative inverse of p, mod 2^256. +var np = [4]uint64{0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80, 0xf57a22b791888c6b} + +// rN1 is R^-1 where R = 2^256 mod p. +var rN1 = &gfP{0xed84884a014afa37, 0xeb2022850278edf8, 0xcf63e9cfb74492d9, 0x2e67157159e5c639} + +// r2 is R^2 where R = 2^256 mod p. +var r2 = &gfP{0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6, 0x06d89f71cab8351f} + +// r3 is R^3 where R = 2^256 mod p. +var r3 = &gfP{0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb, 0x20fd6e902d592544} + +// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+9. +var xiToPMinus1Over6 = &gfP2{gfP{0xa222ae234c492d72, 0xd00f02a4565de15b, 0xdc2ff3a253dfc926, 0x10a75716b3899551}, gfP{0xaf9ba69633144907, 0xca6b1d7387afb78a, 0x11bded5ef08a2087, 0x02f34d751a1f3a7c}} + +// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+9. +var xiToPMinus1Over3 = &gfP2{gfP{0x6e849f1ea0aa4757, 0xaa1c7b6d89f89141, 0xb6e713cdfae0ca3a, 0x26694fbb4e82ebc3}, gfP{0xb5773b104563ab30, 0x347f91c8a9aa6454, 0x7a007127242e0991, 0x1956bcd8118214ec}} + +// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+9. +var xiToPMinus1Over2 = &gfP2{gfP{0xa1d77ce45ffe77c7, 0x07affd117826d1db, 0x6d16bd27bb7edc6b, 0x2c87200285defecc}, gfP{0xe4bbdd0c2936b629, 0xbb30f162e133bacb, 0x31a9d1b6f9645366, 0x253570bea500f8dd}} + +// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+9. +var xiToPSquaredMinus1Over3 = &gfP{0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0} + +// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+9 (a cubic root of unity, mod p). +var xiTo2PSquaredMinus2Over3 = &gfP{0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943} + +// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+9 (a cubic root of -1, mod p). +var xiToPSquaredMinus1Over6 = &gfP{0xca8d800500fa1bf2, 0xf0c5d61468b39769, 0x0e201271ad0d4418, 0x04290f65bad856e6} + +// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+9. +var xiTo2PMinus2Over3 = &gfP2{gfP{0x5dddfd154bd8c949, 0x62cb29a5a4445b60, 0x37bc870a0c7dd2b9, 0x24830a9d3171f0fd}, gfP{0x7361d77f843abe92, 0xa5bb2bd3273411fb, 0x9c941f314b3e2399, 0x15df9cddbb9fd3ec}} diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/gfp6.go b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/gfp6.go new file mode 100644 index 00000000..a4273491 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/crypto/bn256/cloudflare/gfp6.go @@ -0,0 +1,213 @@ +package bn256 + +// For details of the algorithms used, see "Multiplication and Squaring on +// Pairing-Friendly Fields, Devegili et al. +// http://eprint.iacr.org/2006/471.pdf. + +// gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ +// and ξ=i+9. +type gfP6 struct { + x, y, z gfP2 // value is xτ² + yτ + z +} + +func (e *gfP6) String() string { + return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" +} + +func (e *gfP6) Set(a *gfP6) *gfP6 { + e.x.Set(&a.x) + e.y.Set(&a.y) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) SetZero() *gfP6 { + e.x.SetZero() + e.y.SetZero() + e.z.SetZero() + return e +} + +func (e *gfP6) SetOne() *gfP6 { + e.x.SetZero() + e.y.SetZero() + e.z.SetOne() + return e +} + +func (e *gfP6) IsZero() bool { + return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() +} + +func (e *gfP6) IsOne() bool { + return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() +} + +func (e *gfP6) Neg(a *gfP6) *gfP6 { + e.x.Neg(&a.x) + e.y.Neg(&a.y) + e.z.Neg(&a.z) + return e +} + +func (e *gfP6) Frobenius(a *gfP6) *gfP6 { + e.x.Conjugate(&a.x) + e.y.Conjugate(&a.y) + e.z.Conjugate(&a.z) + + e.x.Mul(&e.x, xiTo2PMinus2Over3) + e.y.Mul(&e.y, xiToPMinus1Over3) + return e +} + +// FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z +func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { + // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) + e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) + // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) + e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { + e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3) + e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) + e.z.Set(&a.z) + return e +} + +func (e *gfP6) Add(a, b *gfP6) *gfP6 { + e.x.Add(&a.x, &b.x) + e.y.Add(&a.y, &b.y) + e.z.Add(&a.z, &b.z) + return e +} + +func (e *gfP6) Sub(a, b *gfP6) *gfP6 { + e.x.Sub(&a.x, &b.x) + e.y.Sub(&a.y, &b.y) + e.z.Sub(&a.z, &b.z) + return e +} + +func (e *gfP6) Mul(a, b *gfP6) *gfP6 { + // "Multiplication and Squaring on Pairing-Friendly Fields" + // Section 4, Karatsuba method. + // http://eprint.iacr.org/2006/471.pdf + v0 := (&gfP2{}).Mul(&a.z, &b.z) + v1 := (&gfP2{}).Mul(&a.y, &b.y) + v2 := (&gfP2{}).Mul(&a.x, &b.x) + + t0 := (&gfP2{}).Add(&a.x, &a.y) + t1 := (&gfP2{}).Add(&b.x, &b.y) + tz := (&gfP2{}).Mul(t0, t1) + tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0) + + t0.Add(&a.y, &a.z) + t1.Add(&b.y, &b.z) + ty := (&gfP2{}).Mul(t0, t1) + t0.MulXi(v2) + ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) + + t0.Add(&a.x, &a.z) + t1.Add(&b.x, &b.z) + tx := (&gfP2{}).Mul(t0, t1) + tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) + + e.x.Set(tx) + e.y.Set(ty) + e.z.Set(tz) + return e +} + +func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { + e.x.Mul(&a.x, b) + e.y.Mul(&a.y, b) + e.z.Mul(&a.z, b) + return e +} + +func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { + e.x.MulScalar(&a.x, b) + e.y.MulScalar(&a.y, b) + e.z.MulScalar(&a.z, b) + return e +} + +// MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ +func (e *gfP6) MulTau(a *gfP6) *gfP6 { + tz := (&gfP2{}).MulXi(&a.x) + ty := (&gfP2{}).Set(&a.y) + + e.y.Set(&a.z) + e.x.Set(ty) + e.z.Set(tz) + return e +} + +func (e *gfP6) Square(a *gfP6) *gfP6 { + v0 := (&gfP2{}).Square(&a.z) + v1 := (&gfP2{}).Square(&a.y) + v2 := (&gfP2{}).Square(&a.x) + + c0 := (&gfP2{}).Add(&a.x, &a.y) + c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) + + c1 := (&gfP2{}).Add(&a.y, &a.z) + c1.Square(c1).Sub(c1, v0).Sub(c1, v1) + xiV2 := (&gfP2{}).MulXi(v2) + c1.Add(c1, xiV2) + + c2 := (&gfP2{}).Add(&a.x, &a.z) + c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) + + e.x.Set(c2) + e.y.Set(c1) + e.z.Set(c0) + return e +} + +func (e *gfP6) Invert(a *gfP6) *gfP6 { + // See "Implementing cryptographic pairings", M. Scott, section 3.2. + // ftp://136.206.11.249/pub/crypto/pairings.pdf + + // Here we can give a short explanation of how it works: let j be a cubic root of + // unity in GF(p²) so that 1+j+j²=0. + // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) + // = (xτ² + yτ + z)(Cτ²+Bτ+A) + // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). + // + // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) + // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) + // + // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) + t1 := (&gfP2{}).Mul(&a.x, &a.y) + t1.MulXi(t1) + + A := (&gfP2{}).Square(&a.z) + A.Sub(A, t1) + + B := (&gfP2{}).Square(&a.x) + B.MulXi(B) + t1.Mul(&a.y, &a.z) + B.Sub(B, t1) + + C := (&gfP2{}).Square(&a.y) + t1.Mul(&a.x, &a.z) + C.Sub(C, t1) + + F := (&gfP2{}).Mul(C, &a.y) + F.MulXi(F) + t1.Mul(A, &a.z) + F.Add(F, t1) + t1.Mul(B, &a.x).MulXi(t1) + F.Add(F, t1) + + F.Invert(F) + + e.x.Mul(C, F) + e.y.Mul(B, F) + e.z.Mul(A, F) + return e +} diff --git a/vendor/github.com/ethereum/go-ethereum/dashboard/assets.go b/vendor/github.com/ethereum/go-ethereum/dashboard/assets.go new file mode 100644 index 00000000..eb7a8271 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/dashboard/assets.go @@ -0,0 +1,38665 @@ +// Code generated by go-bindata. DO NOT EDIT. +// sources: +// assets/index.html +// assets/bundle.js +// assets/bundle.js.map + +package dashboard + +import ( + "crypto/sha256" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +type asset struct { + bytes []byte + info os.FileInfo + digest [sha256.Size]byte +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +//nolint:misspell +var _indexHtml = []byte(` + + + + + + + Go Ethereum Dashboard + + + + +
+ + + +`) + +func indexHtmlBytes() ([]byte, error) { + return _indexHtml, nil +} + +func indexHtml() (*asset, error) { + bytes, err := indexHtmlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "index.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6a, 0xe4, 0x19, 0xb4, 0xf4, 0x89, 0xd3, 0x51, 0xa8, 0xde, 0x87, 0x57, 0x96, 0x17, 0x3f, 0x43, 0xa6, 0xa0, 0x7a, 0x6f, 0xba, 0xeb, 0x27, 0xcf, 0x41, 0x28, 0x6e, 0x85, 0x91, 0xa6, 0x48, 0xcf}} + return a, nil +} + +//nolint:misspell +var _bundleJs = []byte((((`!function(e) { + var t = {}; + function n(r) { + if (t[r]) return t[r].exports; + var o = t[r] = { + i: r, + l: !1, + exports: {} + }; + return e[r].call(o.exports, o, o.exports, n), o.l = !0, o.exports; + } + n.m = e, n.c = t, n.d = function(e, t, r) { + n.o(e, t) || Object.defineProperty(e, t, { + enumerable: !0, + get: r + }); + }, n.r = function(e) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { + value: "Module" + }), Object.defineProperty(e, "__esModule", { + value: !0 + }); + }, n.t = function(e, t) { + if (1 & t && (e = n(e)), 8 & t) return e; + if (4 & t && "object" == typeof e && e && e.__esModule) return e; + var r = Object.create(null); + if (n.r(r), Object.defineProperty(r, "default", { + enumerable: !0, + value: e + }), 2 & t && "string" != typeof e) for (var o in e) n.d(r, o, function(t) { + return e[t]; + }.bind(null, o)); + return r; + }, n.n = function(e) { + var t = e && e.__esModule ? function() { + return e.default; + } : function() { + return e; + }; + return n.d(t, "a", t), t; + }, n.o = function(e, t) { + return Object.prototype.hasOwnProperty.call(e, t); + }, n.p = "", n(n.s = "./index.jsx"); +}({ + "./common.jsx": function(e, t, n) { + "use strict"; + (function(e) { + n.d(t, "b", function() { + return d; + }), n.d(t, "a", function() { + return f; + }), n.d(t, "c", function() { + return p; + }), n.d(t, "g", function() { + return h; + }), n.d(t, "f", function() { + return m; + }), n.d(t, "e", function() { + return y; + }), n.d(t, "d", function() { + return b; + }); + var r, o = n("./node_modules/@fortawesome/free-solid-svg-icons/index.es.js"), a = n("./node_modules/@fortawesome/free-regular-svg-icons/index.es.js"); + function i(e) { + for (var t = 1; t < arguments.length; t++) { + var n = null != arguments[t] ? arguments[t] : {}, r = Object.keys(n); + "function" == typeof Object.getOwnPropertySymbols && (r = r.concat(Object.getOwnPropertySymbols(n).filter(function(e) { + return Object.getOwnPropertyDescriptor(n, e).enumerable; + }))), r.forEach(function(t) { + s(e, t, n[t]); + }); + } + return e; + } + function s(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + (r = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).enterModule) && r(e); + var l, u, c = [ { + id: "home", + menu: { + title: "Home", + icon: o.d + } + }, { + id: "chain", + menu: { + title: "Chain", + icon: o.e + } + }, { + id: "txpool", + menu: { + title: "TxPool", + icon: a.b + } + }, { + id: "network", + menu: { + title: "Network", + icon: o.c + } + }, { + id: "system", + menu: { + title: "System", + icon: o.g + } + }, { + id: "logs", + menu: { + title: "Logs", + icon: o.f + } + } ], d = new Map(c.map(function(e) { + var t = e.id; + return [ t, i({ + id: t + }, e.menu) ]; + })), f = 200, p = .2, h = { + light: { + color: "rgba(255, 255, 255, 0.54)" + } + }, _ = [ "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" ], m = function(e) { + for (var t = 0; e > 1024 && t < 8; t++) e /= 1024; + return e.toFixed(2).toString().concat(" ", _[t], "B"); + }, y = [ "#00FF00", "#FFFF00", "#FF7F00", "#FF0000" ], b = [ 0, 2048, 102400, 2097152 ]; + (l = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).default) && (l.register(c, "menuSkeletons", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(d, "MENU", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(f, "DURATION", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(p, "chartStrokeWidth", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(h, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(_, "unit", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(m, "simplifyBytes", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(y, "hues", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx"), + l.register(b, "hueScale", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/common.jsx")), + (u = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).leaveModule) && u(e); + }).call(this, n("./node_modules/webpack/buildin/harmony-module.js")(e)); + }, + "./components/Body.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _SideBar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./components/SideBar.jsx"), _Main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./components/Main.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var styles = { + body: { + display: "flex", + width: "100%", + height: "92%" + } + }, Body = function(_Component) { + function Body() { + return _classCallCheck(this, Body), _possibleConstructorReturn(this, _getPrototypeOf(Body).apply(this, arguments)); + } + return _inherits(Body, _Component), _createClass(Body, [ { + key: "render", + value: function() { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.body + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_SideBar__WEBPACK_IMPORTED_MODULE_1__.a, { + opened: this.props.opened, + changeContent: this.props.changeContent + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Main__WEBPACK_IMPORTED_MODULE_2__.a, { + active: this.props.active, + content: this.props.content, + shouldUpdate: this.props.shouldUpdate, + send: this.props.send + })); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Body; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = Body, reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Body.jsx"), + reactHotLoader.register(Body, "Body", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Body.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Body.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/ChartRow.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/Grid/index.js"), _material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_1__), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var styles = { + container: { + flexWrap: "nowrap", + height: "100%", + maxWidth: "100%", + margin: 0 + }, + item: { + flex: 1, + padding: 0 + } + }, ChartRow = function(_Component) { + function ChartRow() { + return _classCallCheck(this, ChartRow), _possibleConstructorReturn(this, _getPrototypeOf(ChartRow).apply(this, arguments)); + } + return _inherits(ChartRow, _Component), _createClass(ChartRow, [ { + key: "render", + value: function() { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_1___default.a, { + container: !0, + direction: "row", + style: styles.container, + justify: "space-between" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.Children.map(this.props.children, function(e) { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_1___default.a, { + item: !0, + xs: !0, + style: styles.item + }, e); + })); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), ChartRow; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = ChartRow, reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/ChartRow.jsx"), + reactHotLoader.register(ChartRow, "ChartRow", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/ChartRow.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/ChartRow.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/CustomTooltip.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + __webpack_require__.d(__webpack_exports__, "d", function() { + return multiplier; + }), __webpack_require__.d(__webpack_exports__, "e", function() { + return percentPlotter; + }), __webpack_require__.d(__webpack_exports__, "b", function() { + return bytePlotter; + }), __webpack_require__.d(__webpack_exports__, "a", function() { + return bytePerSecPlotter; + }); + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/Typography/index.js"), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1__), _common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var multiplier = function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 1; + return function(t) { + return t * e; + }; + }, percentPlotter = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : multiplier(1); + return function(n) { + var r = t(n); + return "number" != typeof r ? null : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1___default.a, { + type: "caption", + color: "inherit" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + style: _common__WEBPACK_IMPORTED_MODULE_2__.g.light + }, e), " ", r.toFixed(2), " %"); + }; + }, bytePlotter = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : multiplier(1); + return function(n) { + var r = t(n); + return "number" != typeof r ? null : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1___default.a, { + type: "caption", + color: "inherit" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + style: _common__WEBPACK_IMPORTED_MODULE_2__.g.light + }, e), " ", Object(_common__WEBPACK_IMPORTED_MODULE_2__.f)(r)); + }; + }, bytePerSecPlotter = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : multiplier(1); + return function(n) { + var r = t(n); + return "number" != typeof r ? null : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_1___default.a, { + type: "caption", + color: "inherit" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + style: _common__WEBPACK_IMPORTED_MODULE_2__.g.light + }, e), Object(_common__WEBPACK_IMPORTED_MODULE_2__.f)(r), "/s"); + }; + }, CustomTooltip = function(_Component) { + function CustomTooltip() { + return _classCallCheck(this, CustomTooltip), _possibleConstructorReturn(this, _getPrototypeOf(CustomTooltip).apply(this, arguments)); + } + return _inherits(CustomTooltip, _Component), _createClass(CustomTooltip, [ { + key: "render", + value: function() { + var e = this.props, t = e.active, n = e.payload, r = e.tooltip; + return !t || "function" != typeof r || !Array.isArray(n) || n.length < 1 ? null : r(n[0].value); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), CustomTooltip; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = CustomTooltip, reactHotLoader, leaveModule; + __webpack_exports__.c = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(multiplier, "multiplier", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx"), + reactHotLoader.register(percentPlotter, "percentPlotter", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx"), + reactHotLoader.register(bytePlotter, "bytePlotter", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx"), + reactHotLoader.register(bytePerSecPlotter, "bytePerSecPlotter", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx"), + reactHotLoader.register(CustomTooltip, "CustomTooltip", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/CustomTooltip.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Dashboard.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), react_hot_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/react-hot-loader/index.js"), react_hot_loader__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(react_hot_loader__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/styles/withStyles.js"), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_2__), Header__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./components/Header.jsx"), Body__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./components/Body.jsx"), Logs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./components/Logs.jsx"), Network__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./components/Network.jsx"), _common__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + function _toConsumableArray(e) { + return _arrayWithoutHoles(e) || _iterableToArray(e) || _nonIterableSpread(); + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + function _iterableToArray(e) { + if (Symbol.iterator in Object(e) || "[object Arguments]" === Object.prototype.toString.call(e)) return Array.from(e); + } + function _arrayWithoutHoles(e) { + if (Array.isArray(e)) { + for (var t = 0, n = new Array(e.length); t < e.length; t++) n[t] = e[t]; + return n; + } + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var deepUpdate = function e(t, n, r) { + if (void 0 === n) return r; + if ("function" == typeof t) return t(n, r); + var o = {}; + return Object.keys(r).forEach(function(a) { + o[a] = e(t[a], n[a], r[a]); + }), o; + }, shouldUpdate = function e(t, n) { + var r = {}; + return Object.keys(n).forEach(function(o) { + r[o] = "function" == typeof t[o] || e(t[o], n[o]); + }), r; + }, replacer = function(e) { + return e; + }, appender = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : replacer; + return function(n, r) { + return [].concat(_toConsumableArray(r), _toConsumableArray(n.map(function(e) { + return t(e); + }))).slice(-e); + }; + }, defaultContent = function() { + return { + general: { + version: null, + commit: null + }, + home: {}, + chain: {}, + txpool: {}, + network: { + peers: { + bundles: {} + }, + diff: [] + }, + system: { + activeMemory: [], + virtualMemory: [], + networkIngress: [], + networkEgress: [], + processCPU: [], + systemCPU: [], + diskRead: [], + diskWrite: [] + }, + logs: { + chunks: [], + endTop: !1, + endBottom: !0, + topChanged: Logs__WEBPACK_IMPORTED_MODULE_5__.a, + bottomChanged: Logs__WEBPACK_IMPORTED_MODULE_5__.a + } + }; + }, updaters = { + general: { + version: replacer, + commit: replacer + }, + home: null, + chain: null, + txpool: null, + network: Object(Network__WEBPACK_IMPORTED_MODULE_6__.b)(200), + system: { + activeMemory: appender(200), + virtualMemory: appender(200), + networkIngress: appender(200), + networkEgress: appender(200), + processCPU: appender(200), + systemCPU: appender(200), + diskRead: appender(200), + diskWrite: appender(200) + }, + logs: Object(Logs__WEBPACK_IMPORTED_MODULE_5__.c)(5) + }, styles = { + dashboard: { + display: "flex", + flexFlow: "column", + width: "100%", + height: "100%", + zIndex: 1, + overflow: "hidden" + } + }, themeStyles = function(e) { + return { + dashboard: { + background: e.palette.background.default + } + }; + }, Dashboard = function(_Component) { + function Dashboard(e) { + var t; + return _classCallCheck(this, Dashboard), _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, _getPrototypeOf(Dashboard).call(this, e))), "reconnect", function() { + var e = window.location.host, n = new WebSocket("".concat("https:" === window.location.protocol ? "wss://" : "ws://").concat(e, "/api")); + n.onopen = function() { + t.setState({ + content: defaultContent(), + shouldUpdate: {}, + server: n + }); + }, n.onmessage = function(e) { + var n = JSON.parse(e.data); + n ? t.update(n) : console.error("Incoming message is ".concat(n)); + }, n.onclose = function() { + t.setState({ + server: null + }), setTimeout(t.reconnect, 3e3); + }; + }), _defineProperty(_assertThisInitialized(t), "send", function(e) { + null != t.state.server && t.state.server.send(e); + }), _defineProperty(_assertThisInitialized(t), "update", function(e) { + t.setState(function(t) { + return { + content: deepUpdate(updaters, e, t.content), + shouldUpdate: shouldUpdate(updaters, e) + }; + }); + }), _defineProperty(_assertThisInitialized(t), "changeContent", function(e) { + t.setState(function(t) { + return t.active !== e ? { + active: e + } : {}; + }); + }), _defineProperty(_assertThisInitialized(t), "switchSideBar", function() { + t.setState(function(e) { + return { + sideBar: !e.sideBar + }; + }); + }), t.state = { + active: _common__WEBPACK_IMPORTED_MODULE_7__.b.get("home").id, + sideBar: !0, + content: defaultContent(), + shouldUpdate: {}, + server: null + }, t; + } + return _inherits(Dashboard, _Component), _createClass(Dashboard, [ { + key: "componentDidMount", + value: function() { + this.reconnect(); + } + }, { + key: "render", + value: function() { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + className: this.props.classes.dashboard, + style: styles.dashboard + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Header__WEBPACK_IMPORTED_MODULE_3__.a, { + switchSideBar: this.switchSideBar + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Body__WEBPACK_IMPORTED_MODULE_4__.a, { + opened: this.state.sideBar, + changeContent: this.changeContent, + active: this.state.active, + content: this.state.content, + shouldUpdate: this.state.shouldUpdate, + send: this.send + })); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Dashboard; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = Object(react_hot_loader__WEBPACK_IMPORTED_MODULE_1__.hot)(module)(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_2___default()(themeStyles)(Dashboard)), reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(deepUpdate, "deepUpdate", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(shouldUpdate, "shouldUpdate", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(replacer, "replacer", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(appender, "appender", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(defaultContent, "defaultContent", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(updaters, "updaters", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(themeStyles, "themeStyles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(Dashboard, "Dashboard", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Dashboard.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Footer.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/styles/withStyles.js"), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/Typography/index.js"), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_2__), _material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/@material-ui/core/Grid/index.js"), _material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3__), recharts_es6_component_ResponsiveContainer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/recharts/es6/component/ResponsiveContainer.js"), recharts_es6_chart_AreaChart__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/recharts/es6/chart/AreaChart.js"), recharts_es6_cartesian_Area__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./node_modules/recharts/es6/cartesian/Area.js"), recharts_es6_cartesian_ReferenceLine__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./node_modules/recharts/es6/cartesian/ReferenceLine.js"), recharts_es6_component_Label__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./node_modules/recharts/es6/component/Label.js"), recharts_es6_component_Tooltip__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./node_modules/recharts/es6/component/Tooltip.js"), ChartRow__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./components/ChartRow.jsx"), CustomTooltip__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__("./components/CustomTooltip.jsx"), _common__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _extends() { + return (_extends = Object.assign || function(e) { + for (var t = 1; t < arguments.length; t++) { + var n = arguments[t]; + for (var r in n) Object.prototype.hasOwnProperty.call(n, r) && (e[r] = n[r]); + } + return e; + }).apply(this, arguments); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var FOOTER_SYNC_ID = "footerSyncId", CPU = "cpu", MEMORY = "memory", DISK = "disk", TRAFFIC = "traffic", TOP = "Top", BOTTOM = "Bottom", cpuLabelTop = "Process load", cpuLabelBottom = "System load", memoryLabelTop = "Active memory", memoryLabelBottom = "Virtual memory", diskLabelTop = "Disk read", diskLabelBottom = "Disk write", trafficLabelTop = "Download", trafficLabelBottom = "Upload", styles = { + footer: { + maxWidth: "100%", + flexWrap: "nowrap", + margin: 0 + }, + chartRowWrapper: { + height: "100%", + padding: 0 + }, + doubleChartWrapper: { + height: "100%", + width: "99%" + }, + link: { + color: "inherit", + textDecoration: "none" + } + }, themeStyles = function(e) { + return { + footer: { + backgroundColor: e.palette.grey[900], + color: e.palette.getContrastText(e.palette.grey[900]), + zIndex: e.zIndex.appBar, + height: 10 * e.spacing.unit + } + }; + }, Footer = function(_Component) { + function Footer() { + var e, t; + _classCallCheck(this, Footer); + for (var n = arguments.length, r = new Array(n), o = 0; o < n; o++) r[o] = arguments[o]; + return _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, (e = _getPrototypeOf(Footer)).call.apply(e, [ this ].concat(r)))), "halfHeightChart", function(e, t, n, r, o) { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_component_ResponsiveContainer__WEBPACK_IMPORTED_MODULE_4__.a, { + width: "100%", + height: "50%" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_chart_AreaChart__WEBPACK_IMPORTED_MODULE_5__.a, e, !t || react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_component_Tooltip__WEBPACK_IMPORTED_MODULE_9__.a, { + cursor: !1, + content: react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.c, { + tooltip: t + }) + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_cartesian_Area__WEBPACK_IMPORTED_MODULE_6__.a, _extends({ + isAnimationActive: !1, + strokeWidth: _common__WEBPACK_IMPORTED_MODULE_12__.c, + type: "monotone" + }, n)), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_cartesian_ReferenceLine__WEBPACK_IMPORTED_MODULE_7__.a, { + x: 0, + strokeWidth: 0 + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts_es6_component_Label__WEBPACK_IMPORTED_MODULE_8__.a, { + fill: n.fill, + value: r, + position: o + })))); + }), _defineProperty(_assertThisInitialized(t), "doubleChart", function(e, n, r, o) { + if (!Array.isArray(r.data) || !Array.isArray(o.data)) return null; + var a = r.default || 0, i = o.default || 0, s = "".concat(n).concat(TOP), l = "".concat(n).concat(BOTTOM); + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.doubleChartWrapper + }, t.halfHeightChart({ + syncId: e, + data: r.data.map(function(e) { + var t = e.value; + return _defineProperty({}, s, t || a); + }), + margin: { + top: 5, + right: 5, + bottom: 0, + left: 5 + } + }, r.tooltip, { + dataKey: s, + stroke: "#8884d8", + fill: "#8884d8" + }, r.label, "insideBottomLeft"), t.halfHeightChart({ + syncId: e, + data: o.data.map(function(e) { + var t = e.value; + return _defineProperty({}, l, -t || -i); + }), + margin: { + top: 0, + right: 5, + bottom: 5, + left: 5 + } + }, o.tooltip, { + dataKey: l, + stroke: "#82ca9d", + fill: "#82ca9d" + }, o.label, "insideTopLeft")); + }), t; + } + return _inherits(Footer, _Component), _createClass(Footer, [ { + key: "shouldComponentUpdate", + value: function(e, t, n) { + return void 0 !== e.shouldUpdate.general || void 0 !== e.shouldUpdate.system; + } + }, { + key: "render", + value: function() { + var e = this.props, t = e.general, n = e.system; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3___default.a, { + container: !0, + className: this.props.classes.footer, + direction: "row", + alignItems: "center", + style: styles.footer + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3___default.a, { + item: !0, + xs: !0, + style: styles.chartRowWrapper + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ChartRow__WEBPACK_IMPORTED_MODULE_10__.a, null, this.doubleChart(FOOTER_SYNC_ID, CPU, { + data: n.processCPU, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.e)(cpuLabelTop), + label: cpuLabelTop + }, { + data: n.systemCPU, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.e)(cpuLabelBottom, Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.d)(-1)), + label: cpuLabelBottom + }), this.doubleChart(FOOTER_SYNC_ID, MEMORY, { + data: n.activeMemory, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.b)(memoryLabelTop), + label: memoryLabelTop + }, { + data: n.virtualMemory, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.b)(memoryLabelBottom, Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.d)(-1)), + label: memoryLabelBottom + }), this.doubleChart(FOOTER_SYNC_ID, DISK, { + data: n.diskRead, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.a)(diskLabelTop), + label: diskLabelTop + }, { + data: n.diskWrite, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.a)(diskLabelBottom, Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.d)(-1)), + label: diskLabelBottom + }), this.doubleChart(FOOTER_SYNC_ID, TRAFFIC, { + data: n.networkIngress, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.a)(trafficLabelTop), + label: trafficLabelTop + }, { + data: n.networkEgress, + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.a)(trafficLabelBottom, Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_11__.d)(-1)), + label: trafficLabelBottom + }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid__WEBPACK_IMPORTED_MODULE_3___default.a, { + item: !0 + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_2___default.a, { + type: "caption", + color: "inherit" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + style: _common__WEBPACK_IMPORTED_MODULE_12__.g.light + }, "Geth"), " ", t.version), t.commit && react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_2___default.a, { + type: "caption", + color: "inherit" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + style: _common__WEBPACK_IMPORTED_MODULE_12__.g.light + }, "Commit "), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("a", { + href: "https://github.com/ethereum/go-ethereum/commit/".concat(t.commit), + target: "_blank", + rel: "noopener noreferrer", + style: styles.link + }, t.commit.substring(0, 8))))); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Footer; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default()(themeStyles)(Footer), reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(FOOTER_SYNC_ID, "FOOTER_SYNC_ID", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(CPU, "CPU", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(MEMORY, "MEMORY", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(DISK, "DISK", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(TRAFFIC, "TRAFFIC", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(TOP, "TOP", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(BOTTOM, "BOTTOM", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(cpuLabelTop, "cpuLabelTop", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(cpuLabelBottom, "cpuLabelBottom", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(memoryLabelTop, "memoryLabelTop", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(memoryLabelBottom, "memoryLabelBottom", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(diskLabelTop, "diskLabelTop", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(diskLabelBottom, "diskLabelBottom", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(trafficLabelTop, "trafficLabelTop", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(trafficLabelBottom, "trafficLabelBottom", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(themeStyles, "themeStyles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(Footer, "Footer", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Footer.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Header.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/styles/withStyles.js"), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_AppBar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/AppBar/index.js"), _material_ui_core_AppBar__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_AppBar__WEBPACK_IMPORTED_MODULE_2__), _material_ui_core_Toolbar__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/@material-ui/core/Toolbar/index.js"), _material_ui_core_Toolbar__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(_material_ui_core_Toolbar__WEBPACK_IMPORTED_MODULE_3__), _material_ui_core_IconButton__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/@material-ui/core/IconButton/index.js"), _material_ui_core_IconButton__WEBPACK_IMPORTED_MODULE_4___default = __webpack_require__.n(_material_ui_core_IconButton__WEBPACK_IMPORTED_MODULE_4__), _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/@fortawesome/react-fontawesome/index.es.js"), _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./node_modules/@fortawesome/free-solid-svg-icons/index.es.js"), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./node_modules/@material-ui/core/Typography/index.js"), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7___default = __webpack_require__.n(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7__), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var styles = { + header: { + height: "8%" + }, + toolbar: { + height: "100%" + } + }, themeStyles = function(e) { + return { + header: { + backgroundColor: e.palette.grey[900], + color: e.palette.getContrastText(e.palette.grey[900]), + zIndex: e.zIndex.appBar + }, + toolbar: { + paddingLeft: e.spacing.unit, + paddingRight: e.spacing.unit + }, + title: { + paddingLeft: e.spacing.unit, + fontSize: 3 * e.spacing.unit + } + }; + }, Header = function(_Component) { + function Header() { + return _classCallCheck(this, Header), _possibleConstructorReturn(this, _getPrototypeOf(Header).apply(this, arguments)); + } + return _inherits(Header, _Component), _createClass(Header, [ { + key: "render", + value: function() { + var e = this.props.classes; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_AppBar__WEBPACK_IMPORTED_MODULE_2___default.a, { + position: "static", + className: e.header, + style: styles.header + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Toolbar__WEBPACK_IMPORTED_MODULE_3___default.a, { + className: e.toolbar, + style: styles.toolbar + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_IconButton__WEBPACK_IMPORTED_MODULE_4___default.a, { + onClick: this.props.switchSideBar + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_5__.a, { + icon: _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_6__.a + })), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7___default.a, { + type: "title", + color: "inherit", + noWrap: !0, + className: e.title + }, "Go Ethereum Dashboard"))); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Header; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default()(themeStyles)(Header), reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Header.jsx"), + reactHotLoader.register(themeStyles, "themeStyles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Header.jsx"), + reactHotLoader.register(Header, "Header", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Header.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Header.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Logs.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + __webpack_require__.d(__webpack_exports__, "a", function() { + return SAME; + }), __webpack_require__.d(__webpack_exports__, "c", function() { + return inserter; + }); + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_List__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/List/index.js"), _material_ui_core_List__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_List__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/ListItem/index.js"), _material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_2__), escape_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/escape-html/index.js"), escape_html__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(escape_html__WEBPACK_IMPORTED_MODULE_3__), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + function _toConsumableArray(e) { + return _arrayWithoutHoles(e) || _iterableToArray(e) || _nonIterableSpread(); + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + function _iterableToArray(e) { + if (Symbol.iterator in Object(e) || "[object Arguments]" === Object.prototype.toString.call(e)) return Array.from(e); + } + function _arrayWithoutHoles(e) { + if (Array.isArray(e)) { + for (var t = 0, n = new Array(e.length); t < e.length; t++) n[t] = e[t]; + return n; + } + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var requestBand = .05, fieldPadding = new Map(), createChunk = function(e) { + var t = ""; + return e.forEach(function(e) { + var n = e.t, r = e.ctx, o = e.lvl, a = e.msg, i = "#ce3c23"; + switch (o) { + case "trace": + case "trce": + o = "TRACE", i = "#3465a4"; + break; + + case "debug": + case "dbug": + o = "DEBUG", i = "#3d989b"; + break; + + case "info": + o = "INFO ", i = "#4c8f0f"; + break; + + case "warn": + o = "WARN ", i = "#b79a22"; + break; + + case "error": + case "eror": + o = "ERROR", i = "#754b70"; + break; + + case "crit": + o = "CRIT ", i = "#ce3c23"; + break; + + default: + o = ""; + } + var s = new Date(n); + if ("" !== o && s instanceof Date && !isNaN(s) && "string" == typeof a && Array.isArray(r)) { + r.length > 0 && (a += " ".repeat(Math.max(40 - a.length, 0))); + var l = "0".concat(s.getMonth() + 1).slice(-2), u = "0".concat(s.getDate()).slice(-2), c = "0".concat(s.getHours()).slice(-2), d = "0".concat(s.getMinutes()).slice(-2), f = "0".concat(s.getSeconds()).slice(-2); + t += '').concat(o, "[").concat(l, "-").concat(u, "|").concat(c, ":").concat(d, ":").concat(f, "] ").concat(a); + for (var p = 0; p < r.length; p += 2) { + var h = escape_html__WEBPACK_IMPORTED_MODULE_3___default()(r[p]), _ = escape_html__WEBPACK_IMPORTED_MODULE_3___default()(r[p + 1]), m = fieldPadding.get(h); + ("number" != typeof m || m < _.length) && (m = _.length, fieldPadding.set(h, m)); + var y = ""; + p < r.length - 2 && (y = " ".repeat(m - _.length)), t += ' ').concat(h, "=").concat(_).concat(y); + } + t += "
"; + } else t += 'Invalid log record
'; + }), t; + }, ADDED = 1, SAME = 0, REMOVED = -1, inserter = function(e) { + return function(t, n) { + if (n.topChanged = SAME, n.bottomChanged = SAME, !Array.isArray(t.chunk) || t.chunk.length < 1) return n; + Array.isArray(n.chunks) || (n.chunks = []); + var r = createChunk(t.chunk); + if (!t.source) return n.endBottom ? n.chunks.length < 1 ? [ { + content: r, + name: "00000000000000.log" + } ] : (n.chunks[n.chunks.length - 1].content += r, n.bottomChanged = ADDED, n) : n; + var o = { + content: r, + name: t.source.name + }; + return n.chunks.length > 0 && t.source.name < n.chunks[0].name ? (t.source.last && (n.endTop = !0), + n.chunks.length >= e && (n.endBottom = !1, n.chunks.splice(e - 1, n.chunks.length - e + 1), + n.bottomChanged = REMOVED), n.chunks = [ o ].concat(_toConsumableArray(n.chunks)), + n.topChanged = ADDED, n) : (t.source.last && (n.endBottom = !0), n.chunks.length >= e && (n.endTop = !1, + n.chunks.splice(0, n.chunks.length - e + 1), n.topChanged = REMOVED), n.chunks = [].concat(_toConsumableArray(n.chunks), [ o ]), + n.bottomChanged = ADDED, n); + }; + }, styles = { + logListItem: { + padding: 0, + lineHeight: 1.231 + }, + logChunk: { + color: "white", + fontFamily: "monospace", + whiteSpace: "nowrap", + width: 0 + }, + waitMsg: { + textAlign: "center", + color: "white", + fontFamily: "monospace" + } + }, Logs = function(_Component) { + function Logs(e) { + var t; + return _classCallCheck(this, Logs), _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, _getPrototypeOf(Logs).call(this, e))), "onScroll", function() { + if (t.state.requestAllowed && void 0 !== t.content) { + var e = t.props.content.logs; + e.chunks.length < 1 || (t.atTop() && !e.endTop ? t.sendRequest(e.chunks[0].name, !0) : t.atBottom() && !e.endBottom && t.sendRequest(e.chunks[e.chunks.length - 1].name, !1)); + } + }), _defineProperty(_assertThisInitialized(t), "sendRequest", function(e, n) { + t.setState({ + requestAllowed: !1 + }), t.props.send(JSON.stringify({ + Logs: { + Name: e, + Past: n + } + })); + }), _defineProperty(_assertThisInitialized(t), "atTop", function() { + return t.props.container.scrollTop <= t.props.container.scrollHeight * requestBand; + }), _defineProperty(_assertThisInitialized(t), "atBottom", function() { + var e = t.props.container; + return e.scrollHeight - e.scrollTop <= e.clientHeight + e.scrollHeight * requestBand; + }), _defineProperty(_assertThisInitialized(t), "beforeUpdate", function() { + var e = 0, n = t.content.children[1]; + return n && n.children[0] && (e = n.children[0].clientHeight), { + scrollTop: t.props.container.scrollTop, + firstHeight: e + }; + }), _defineProperty(_assertThisInitialized(t), "didUpdate", function(e, n, r) { + if (void 0 !== t.props.shouldUpdate.logs && void 0 !== t.content && null !== r) { + var o = t.props.content.logs, a = t.props.container; + if (!(void 0 === a || o.chunks.length < 1)) if (t.content.clientHeight < a.clientHeight) o.endTop || t.sendRequest(o.chunks[0].name, !0); else { + var i = r.scrollTop; + o.topChanged === ADDED ? i += t.content.children[1].children[0].clientHeight : o.bottomChanged === ADDED && (o.topChanged === REMOVED ? i -= r.firstHeight : t.atBottom() && o.endBottom && (i = a.scrollHeight - a.clientHeight)), + a.scrollTop = i, t.setState({ + requestAllowed: !0 + }); + } + } + }), t.content = react__WEBPACK_IMPORTED_MODULE_0___default.a.createRef(), t.state = { + requestAllowed: !0 + }, t; + } + return _inherits(Logs, _Component), _createClass(Logs, [ { + key: "componentDidMount", + value: function() { + var e = this.props.container; + if (void 0 !== e) { + e.scrollTop = e.scrollHeight - e.clientHeight; + var t = this.props.content.logs; + void 0 === this.content || t.chunks.length < 1 || this.content.clientHeight < e.clientHeight && !t.endTop && this.sendRequest(t.chunks[0].name, !0); + } + } + }, { + key: "render", + value: function() { + var e = this; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + ref: function(t) { + e.content = t; + } + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.waitMsg + }, this.props.content.logs.endTop ? "No more logs." : "Waiting for server..."), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_List__WEBPACK_IMPORTED_MODULE_1___default.a, null, this.props.content.logs.chunks.map(function(e, t) { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_2___default.a, { + style: styles.logListItem, + key: t + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.logChunk, + dangerouslySetInnerHTML: { + __html: e.content + } + })); + })), this.props.content.logs.endBottom || react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.waitMsg + }, "Waiting for server...")); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Logs; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = Logs, reactHotLoader, leaveModule; + __webpack_exports__.b = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(requestBand, "requestBand", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(fieldPadding, "fieldPadding", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(createChunk, "createChunk", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(ADDED, "ADDED", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(SAME, "SAME", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(REMOVED, "REMOVED", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(inserter, "inserter", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(Logs, "Logs", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Logs.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Main.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/styles/withStyles.js"), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__), Network__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./components/Network.jsx"), Logs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./components/Logs.jsx"), Footer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./components/Footer.jsx"), _common__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var styles = { + wrapper: { + display: "flex", + flexDirection: "column", + width: "100%" + }, + content: { + flex: 1, + overflow: "auto" + } + }, themeStyles = function(e) { + return { + content: { + backgroundColor: e.palette.background.default, + padding: 3 * e.spacing.unit + } + }; + }, Main = function(_Component) { + function Main(e) { + var t; + return _classCallCheck(this, Main), _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, _getPrototypeOf(Main).call(this, e))), "onScroll", function() { + t.content && "function" == typeof t.content.onScroll && t.content.onScroll(); + }), t.container = react__WEBPACK_IMPORTED_MODULE_0___default.a.createRef(), t.content = react__WEBPACK_IMPORTED_MODULE_0___default.a.createRef(), + t; + } + return _inherits(Main, _Component), _createClass(Main, [ { + key: "componentDidUpdate", + value: function(e, t, n) { + this.content && "function" == typeof this.content.didUpdate && this.content.didUpdate(e, t, n); + } + }, { + key: "getSnapshotBeforeUpdate", + value: function(e, t) { + return this.content && "function" == typeof this.content.beforeUpdate ? this.content.beforeUpdate() : null; + } + }, { + key: "render", + value: function() { + var e = this, t = this.props, n = t.classes, r = t.active, o = t.content, a = t.shouldUpdate, i = null; + switch (r) { + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("home").id: + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("chain").id: + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("txpool").id: + i = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, "Work in progress."); + break; + + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("network").id: + i = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Network__WEBPACK_IMPORTED_MODULE_2__.a, { + content: this.props.content.network, + container: this.container + }); + break; + + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("system").id: + i = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, "Work in progress."); + break; + + case _common__WEBPACK_IMPORTED_MODULE_5__.b.get("logs").id: + i = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Logs__WEBPACK_IMPORTED_MODULE_3__.b, { + ref: function(t) { + e.content = t; + }, + container: this.container, + send: this.props.send, + content: this.props.content, + shouldUpdate: a + }); + } + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + style: styles.wrapper + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + className: n.content, + style: styles.content, + ref: function(t) { + e.container = t; + }, + onScroll: this.onScroll + }, i), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Footer__WEBPACK_IMPORTED_MODULE_4__.a, { + general: o.general, + system: o.system, + shouldUpdate: a + })); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Main; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default()(themeStyles)(Main), reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Main.jsx"), + reactHotLoader.register(themeStyles, "themeStyles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Main.jsx"), + reactHotLoader.register(Main, "Main", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Main.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Main.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/Network.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + __webpack_require__.d(__webpack_exports__, "b", function() { + return inserter; + }); + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_Table__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/Table/index.js"), _material_ui_core_Table__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_Table__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_TableHead__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/TableHead/index.js"), _material_ui_core_TableHead__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_TableHead__WEBPACK_IMPORTED_MODULE_2__), _material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/@material-ui/core/TableBody/index.js"), _material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(_material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3__), _material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/@material-ui/core/TableRow/index.js"), _material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4___default = __webpack_require__.n(_material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4__), _material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/@material-ui/core/TableCell/index.js"), _material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default = __webpack_require__.n(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5__), _material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./node_modules/@material-ui/core/Grid/Grid.js"), _material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6___default = __webpack_require__.n(_material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6__), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./node_modules/@material-ui/core/Typography/index.js"), _material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7___default = __webpack_require__.n(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7__), recharts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./node_modules/recharts/es6/index.js"), _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./node_modules/@fortawesome/react-fontawesome/index.es.js"), _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./node_modules/@fortawesome/free-solid-svg-icons/index.es.js"), _fortawesome_free_regular_svg_icons__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__("./node_modules/@fortawesome/free-regular-svg-icons/index.es.js"), color_convert__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__("./node_modules/color-convert/index.js"), color_convert__WEBPACK_IMPORTED_MODULE_12___default = __webpack_require__.n(color_convert__WEBPACK_IMPORTED_MODULE_12__), CustomTooltip__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__("./components/CustomTooltip.jsx"), _common__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _slicedToArray(e, t) { + return _arrayWithHoles(e) || _iterableToArrayLimit(e, t) || _nonIterableRest(); + } + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + function _iterableToArrayLimit(e, t) { + var n = [], r = !0, o = !1, a = void 0; + try { + for (var i, s = e[Symbol.iterator](); !(r = (i = s.next()).done) && (n.push(i.value), + !t || n.length !== t); r = !0) ; + } catch (e) { + o = !0, a = e; + } finally { + try { + r || null == s.return || s.return(); + } finally { + if (o) throw a; + } + } + return n; + } + function _arrayWithHoles(e) { + if (Array.isArray(e)) return e; + } + function _objectSpread(e) { + for (var t = 1; t < arguments.length; t++) { + var n = null != arguments[t] ? arguments[t] : {}, r = Object.keys(n); + "function" == typeof Object.getOwnPropertySymbols && (r = r.concat(Object.getOwnPropertySymbols(n).filter(function(e) { + return Object.getOwnPropertyDescriptor(n, e).enumerable; + }))), r.forEach(function(t) { + _defineProperty(e, t, n[t]); + }); + } + return e; + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + function _toConsumableArray(e) { + return _arrayWithoutHoles(e) || _iterableToArray(e) || _nonIterableSpread(); + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + function _iterableToArray(e) { + if (Symbol.iterator in Object(e) || "[object Arguments]" === Object.prototype.toString.call(e)) return Array.from(e); + } + function _arrayWithoutHoles(e) { + if (Array.isArray(e)) { + for (var t = 0, n = new Array(e.length); t < e.length; t++) n[t] = e[t]; + return n; + } + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var trafficChartHeight = 18, trafficChartWidth = 400, setMaxIngress = function(e, t) { + e.maxIngress = t, e.ingressGradient = [], e.ingressGradient.push({ + offset: _common__WEBPACK_IMPORTED_MODULE_14__.d[0], + color: _common__WEBPACK_IMPORTED_MODULE_14__.e[0] + }); + for (var n = 1; n < _common__WEBPACK_IMPORTED_MODULE_14__.e.length && t > _common__WEBPACK_IMPORTED_MODULE_14__.d[n]; n++) e.ingressGradient.push({ + offset: Math.floor(100 * _common__WEBPACK_IMPORTED_MODULE_14__.d[n] / t), + color: _common__WEBPACK_IMPORTED_MODULE_14__.e[n] + }); + if (--n < _common__WEBPACK_IMPORTED_MODULE_14__.e.length - 1) { + var r = color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.hex.lab(_common__WEBPACK_IMPORTED_MODULE_14__.e[n]), o = 100 * (t - _common__WEBPACK_IMPORTED_MODULE_14__.d[n]) / (_common__WEBPACK_IMPORTED_MODULE_14__.d[n + 1] - _common__WEBPACK_IMPORTED_MODULE_14__.d[n]); + color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.hex.lab(_common__WEBPACK_IMPORTED_MODULE_14__.e[n + 1]).forEach(function(e, t) { + r[t] = (r[t] * o + e * (100 - o)) / 100; + }), e.ingressGradient.push({ + offset: 100, + color: "#".concat(color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.lab.hex(r)) + }); + } + }, setMaxEgress = function(e, t) { + e.maxEgress = t, e.egressGradient = [], e.egressGradient.push({ + offset: 100 - _common__WEBPACK_IMPORTED_MODULE_14__.d[0], + color: _common__WEBPACK_IMPORTED_MODULE_14__.e[0] + }); + for (var n = 1; n < _common__WEBPACK_IMPORTED_MODULE_14__.e.length && t > _common__WEBPACK_IMPORTED_MODULE_14__.d[n]; n++) e.egressGradient.unshift({ + offset: 100 - Math.floor(100 * _common__WEBPACK_IMPORTED_MODULE_14__.d[n] / t), + color: _common__WEBPACK_IMPORTED_MODULE_14__.e[n] + }); + if (--n < _common__WEBPACK_IMPORTED_MODULE_14__.e.length - 1) { + var r = color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.hex.lab(_common__WEBPACK_IMPORTED_MODULE_14__.e[n]), o = 100 * (t - _common__WEBPACK_IMPORTED_MODULE_14__.d[n]) / (_common__WEBPACK_IMPORTED_MODULE_14__.d[n + 1] - _common__WEBPACK_IMPORTED_MODULE_14__.d[n]); + color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.hex.lab(_common__WEBPACK_IMPORTED_MODULE_14__.e[n + 1]).forEach(function(e, t) { + r[t] = (r[t] * o + e * (100 - o)) / 100; + }), e.egressGradient.unshift({ + offset: 0, + color: "#".concat(color_convert__WEBPACK_IMPORTED_MODULE_12___default.a.lab.hex(r)) + }); + } + }, setIngressChartAttributes = function(e) { + var t = 0; + e.ingress.forEach(function(e) { + var n = e.value; + n > t && (t = n); + }), setMaxIngress(e, t); + }, setEgressChartAttributes = function(e) { + var t = 0; + e.egress.forEach(function(e) { + var n = e.value; + n > t && (t = n); + }), setMaxEgress(e, t); + }, inserter = function(e) { + return function(t, n) { + return t.peers && t.peers.bundles && (n.peers = t.peers, Object.values(n.peers.bundles).forEach(function(e) { + e.knownPeers && Object.values(e.knownPeers).forEach(function(e) { + e.maxIngress || setIngressChartAttributes(e), e.maxEgress || setEgressChartAttributes(e); + }); + })), Array.isArray(t.diff) && t.diff.forEach(function(t) { + if (t.ip) { + switch (t.remove) { + case "bundle": + return void delete n.peers.bundles[t.ip]; + + case "known": + if (!t.id) return void console.error("Remove known peer event without ID", t.ip); + var r = n.peers.bundles[t.ip]; + return r && r.knownPeers && r.knownPeers[t.id] ? void delete r.knownPeers[t.id] : void console.error("No known peer to remove", t.ip, t.id); + + case "attempt": + var o = n.peers.bundles[t.ip]; + return !o || !Array.isArray(o.attempts) || o.attempts.length < 1 ? void console.error("No unknown peer to remove", t.ip) : void o.attempts.splice(0, 1); + } + n.peers.bundles[t.ip] || (n.peers.bundles[t.ip] = { + location: { + country: "", + city: "", + latitude: 0, + longitude: 0 + }, + knownPeers: {}, + attempts: [] + }); + var a = n.peers.bundles[t.ip]; + if (t.location) a.location = t.location; else { + if (!t.id) return a.attempts || (a.attempts = []), void a.attempts.push({ + connected: t.connected, + disconnected: t.disconnected + }); + a.knownPeers || (a.knownPeers = {}), a.knownPeers[t.id] || (a.knownPeers[t.id] = { + connected: [], + disconnected: [], + ingress: [], + egress: [], + active: !1 + }); + var i = a.knownPeers[t.id]; + switch (i.maxIngress || setIngressChartAttributes(i), i.maxEgress || setEgressChartAttributes(i), + t.connected && (i.connected || (console.warn("peer.connected should exist"), i.connected = []), + i.connected.push(t.connected)), t.disconnected && (i.disconnected || (console.warn("peer.disconnected should exist"), + i.disconnected = []), i.disconnected.push(t.disconnected)), t.activity) { + case "active": + i.active = !0; + break; + + case "inactive": + i.active = !1; + } + if (Array.isArray(t.ingress) && Array.isArray(t.egress)) { + var s, l; + if (t.ingress.length !== t.egress.length) return void console.error("Different traffic sample length", t); + var u = i.maxIngress; + t.ingress.forEach(function(e) { + var t = e.value; + t > u && (u = t); + }), u > i.maxIngress && setMaxIngress(i, u), (s = i.ingress).splice.apply(s, [ i.ingress.length, 0 ].concat(_toConsumableArray(t.ingress))); + var c = i.ingress.length - e; + if (c > 0) { + for (var d = 0; d < c && i.ingress[d].value < i.maxIngress; ) d++; + i.ingress.splice(0, c), d < c && setIngressChartAttributes(i); + } + var f = i.maxEgress; + t.egress.forEach(function(e) { + var t = e.value; + t > f && (f = t); + }), f > i.maxEgress && setMaxEgress(i, f), (l = i.egress).splice.apply(l, [ i.egress.length, 0 ].concat(_toConsumableArray(t.egress))); + var p = i.egress.length - e; + if (p > 0) { + for (var h = 0; h < p && i.egress[h].value < i.maxEgress; ) h++; + i.egress.splice(0, p), h < p && setEgressChartAttributes(i); + } + } + } + } else console.error("Peer event without IP", t); + }), n; + }; + }, styles = { + tableHead: { + height: "auto" + }, + tableRow: { + height: "auto" + }, + tableCell: { + paddingTop: 0, + paddingRight: 5, + paddingBottom: 0, + paddingLeft: 5, + border: "none" + } + }, Network = function(_Component) { + function Network() { + var e, t; + _classCallCheck(this, Network); + for (var n = arguments.length, r = new Array(n), o = 0; o < n; o++) r[o] = arguments[o]; + return _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, (e = _getPrototypeOf(Network)).call.apply(e, [ this ].concat(r)))), "formatTime", function(e) { + var t = new Date(e); + if (isNaN(t)) return ""; + var n = "0".concat(t.getMonth() + 1).slice(-2), r = "0".concat(t.getDate()).slice(-2), o = "0".concat(t.getHours()).slice(-2), a = "0".concat(t.getMinutes()).slice(-2), i = "0".concat(t.getSeconds()).slice(-2); + return "".concat(n, "/").concat(r, "/").concat(o, ":").concat(a, ":").concat(i); + }), _defineProperty(_assertThisInitialized(t), "copyToClipboard", function(e) { + return function(t) { + t.preventDefault(), navigator.clipboard.writeText(e).then(function() {}, function() { + console.error("Failed to copy node id", e); + }); + }; + }), _defineProperty(_assertThisInitialized(t), "peerTableRow", function(e, n, r, o) { + var a, i = o.ingress.map(function(e) { + return { + ingress: e.value || .001 + }; + }), s = o.egress.map(function(e) { + return { + egress: -e.value || -.001 + }; + }); + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4___default.a, { + key: "known_".concat(e, "_").concat(n), + style: styles.tableRow + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, o.active ? react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_9__.a, { + icon: _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_10__.b, + color: "green" + }) : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_9__.a, { + icon: _fortawesome_free_regular_svg_icons__WEBPACK_IMPORTED_MODULE_11__.a, + style: _common__WEBPACK_IMPORTED_MODULE_14__.g.light + })), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: _objectSpread({ + fontFamily: "monospace", + cursor: "copy" + }, styles.tableCell, _common__WEBPACK_IMPORTED_MODULE_14__.g.light), + onClick: t.copyToClipboard(n) + }, n.substring(0, 10)), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, r.location ? (a = r.location, "".concat(a.country ? a.country : "").concat(a.city ? "/".concat(a.city) : "")) : ""), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.b, { + width: trafficChartWidth, + height: trafficChartHeight, + data: i, + margin: { + top: 5, + right: 5, + bottom: 0, + left: 5 + }, + syncId: "peerIngress_".concat(e, "_").concat(n) + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("defs", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("linearGradient", { + id: "ingressGradient_".concat(e, "_").concat(n), + x1: "0", + y1: "1", + x2: "0", + y2: "0" + }, o.ingressGradient && o.ingressGradient.map(function(t, r) { + var o = t.offset, a = t.color; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("stop", { + key: "ingressStop_".concat(e, "_").concat(n, "_").concat(r), + offset: "".concat(o, "%"), + stopColor: a + }); + }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.c, { + cursor: !1, + content: react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(CustomTooltip__WEBPACK_IMPORTED_MODULE_13__.c, { + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_13__.b)("Download") + }) + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.d, { + hide: !0, + scale: "sqrt", + domain: [ .001, function(e) { + return Math.max(e, 0); + } ] + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.a, { + dataKey: "ingress", + isAnimationActive: !1, + type: "monotone", + fill: "url(#ingressGradient_".concat(e, "_").concat(n, ")"), + stroke: o.ingressGradient[o.ingressGradient.length - 1].color, + strokeWidth: _common__WEBPACK_IMPORTED_MODULE_14__.c + })), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.b, { + width: trafficChartWidth, + height: trafficChartHeight, + data: s, + margin: { + top: 0, + right: 5, + bottom: 5, + left: 5 + }, + syncId: "peerIngress_".concat(e, "_").concat(n) + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("defs", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("linearGradient", { + id: "egressGradient_".concat(e, "_").concat(n), + x1: "0", + y1: "1", + x2: "0", + y2: "0" + }, o.egressGradient && o.egressGradient.map(function(t, r) { + var o = t.offset, a = t.color; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("stop", { + key: "egressStop_".concat(e, "_").concat(n, "_").concat(r), + offset: "".concat(o, "%"), + stopColor: a + }); + }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.c, { + cursor: !1, + content: react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(CustomTooltip__WEBPACK_IMPORTED_MODULE_13__.c, { + tooltip: Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_13__.b)("Upload", Object(CustomTooltip__WEBPACK_IMPORTED_MODULE_13__.d)(-1)) + }) + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.d, { + hide: !0, + scale: "sqrt", + domain: [ function(e) { + return Math.min(e, 0); + }, -.001 ] + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(recharts__WEBPACK_IMPORTED_MODULE_8__.a, { + dataKey: "egress", + isAnimationActive: !1, + type: "monotone", + fill: "url(#egressGradient_".concat(e, "_").concat(n, ")"), + stroke: o.egressGradient[0].color, + strokeWidth: _common__WEBPACK_IMPORTED_MODULE_14__.c + })))); + }), t; + } + return _inherits(Network, _Component), _createClass(Network, [ { + key: "componentDidMount", + value: function() { + var e = this.props.container; + void 0 !== e && (e.scrollTop = 0); + } + }, { + key: "render", + value: function() { + var e = this; + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6___default.a, { + container: !0, + direction: "row", + justify: "space-between" + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6___default.a, { + item: !0 + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Table__WEBPACK_IMPORTED_MODULE_1___default.a, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableHead__WEBPACK_IMPORTED_MODULE_2___default.a, { + style: styles.tableHead + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4___default.a, { + style: styles.tableRow + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "Node ID"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "Location"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "Traffic"))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3___default.a, null, Object.entries(this.props.content.peers.bundles).map(function(t) { + var n = _slicedToArray(t, 2), r = n[0], o = n[1]; + return !o.knownPeers || Object.keys(o.knownPeers).length < 1 ? null : Object.entries(o.knownPeers).map(function(t) { + var n = _slicedToArray(t, 2), a = n[0], i = n[1]; + return !1 === i.active ? null : e.peerTableRow(r, a, o, i); + }); + })), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3___default.a, null, Object.entries(this.props.content.peers.bundles).map(function(t) { + var n = _slicedToArray(t, 2), r = n[0], o = n[1]; + return !o.knownPeers || Object.keys(o.knownPeers).length < 1 ? null : Object.entries(o.knownPeers).map(function(t) { + var n = _slicedToArray(t, 2), a = n[0], i = n[1]; + return !0 === i.active ? null : e.peerTableRow(r, a, o, i); + }); + })))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Grid_Grid__WEBPACK_IMPORTED_MODULE_6___default.a, { + item: !0 + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Typography__WEBPACK_IMPORTED_MODULE_7___default.a, { + variant: "subtitle1", + gutterBottom: !0 + }, "Connection attempts"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Table__WEBPACK_IMPORTED_MODULE_1___default.a, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableHead__WEBPACK_IMPORTED_MODULE_2___default.a, { + style: styles.tableHead + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4___default.a, { + style: styles.tableRow + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "IP"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "Location"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, "Nr"))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableBody__WEBPACK_IMPORTED_MODULE_3___default.a, null, Object.entries(this.props.content.peers.bundles).map(function(e) { + var t, n = _slicedToArray(e, 2), r = n[0], o = n[1]; + return !o.attempts || o.attempts.length < 1 ? null : react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableRow__WEBPACK_IMPORTED_MODULE_4___default.a, { + key: "attempt_".concat(r), + style: styles.tableRow + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, r), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, o.location ? (t = o.location, "".concat(t.country ? t.country : "").concat(t.city ? "/".concat(t.city) : "")) : ""), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_TableCell__WEBPACK_IMPORTED_MODULE_5___default.a, { + style: styles.tableCell + }, Object.values(o.attempts).length)); + }))))); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), Network; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = Network, reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(trafficChartHeight, "trafficChartHeight", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(trafficChartWidth, "trafficChartWidth", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(setMaxIngress, "setMaxIngress", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(setMaxEgress, "setMaxEgress", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(setIngressChartAttributes, "setIngressChartAttributes", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(setEgressChartAttributes, "setEgressChartAttributes", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(inserter, "inserter", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(Network, "Network", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/Network.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./components/SideBar.jsx": function(module, __webpack_exports__, __webpack_require__) { + "use strict"; + (function(module) { + var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/react/index.js"), react__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/@material-ui/core/styles/withStyles.js"), _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default = __webpack_require__.n(_material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1__), _material_ui_core_List__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/@material-ui/core/List/index.js"), _material_ui_core_List__WEBPACK_IMPORTED_MODULE_2___default = __webpack_require__.n(_material_ui_core_List__WEBPACK_IMPORTED_MODULE_2__), _material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/@material-ui/core/ListItem/index.js"), _material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_3___default = __webpack_require__.n(_material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_3__), _material_ui_core_ListItemIcon__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/@material-ui/core/ListItemIcon/index.js"), _material_ui_core_ListItemIcon__WEBPACK_IMPORTED_MODULE_4___default = __webpack_require__.n(_material_ui_core_ListItemIcon__WEBPACK_IMPORTED_MODULE_4__), _material_ui_core_ListItemText__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/@material-ui/core/ListItemText/index.js"), _material_ui_core_ListItemText__WEBPACK_IMPORTED_MODULE_5___default = __webpack_require__.n(_material_ui_core_ListItemText__WEBPACK_IMPORTED_MODULE_5__), _material_ui_core_Icon__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./node_modules/@material-ui/core/Icon/index.js"), _material_ui_core_Icon__WEBPACK_IMPORTED_MODULE_6___default = __webpack_require__.n(_material_ui_core_Icon__WEBPACK_IMPORTED_MODULE_6__), react_transition_group_Transition__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./node_modules/react-transition-group/Transition.js"), react_transition_group_Transition__WEBPACK_IMPORTED_MODULE_7___default = __webpack_require__.n(react_transition_group_Transition__WEBPACK_IMPORTED_MODULE_7__), _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./node_modules/@fortawesome/react-fontawesome/index.es.js"), _common__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./common.jsx"), enterModule; + function _typeof(e) { + return (_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function _objectSpread(e) { + for (var t = 1; t < arguments.length; t++) { + var n = null != arguments[t] ? arguments[t] : {}, r = Object.keys(n); + "function" == typeof Object.getOwnPropertySymbols && (r = r.concat(Object.getOwnPropertySymbols(n).filter(function(e) { + return Object.getOwnPropertyDescriptor(n, e).enumerable; + }))), r.forEach(function(t) { + _defineProperty(e, t, n[t]); + }); + } + return e; + } + function _classCallCheck(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + } + function _defineProperties(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function _createClass(e, t, n) { + return t && _defineProperties(e.prototype, t), n && _defineProperties(e, n), e; + } + function _possibleConstructorReturn(e, t) { + return !t || "object" !== _typeof(t) && "function" != typeof t ? _assertThisInitialized(e) : t; + } + function _getPrototypeOf(e) { + return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + })(e); + } + function _assertThisInitialized(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + function _inherits(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && _setPrototypeOf(e, t); + } + function _setPrototypeOf(e, t) { + return (_setPrototypeOf = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + })(e, t); + } + function _defineProperty(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + enterModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).enterModule, + enterModule && enterModule(module); + var styles = { + menu: { + default: { + transition: "margin-left ".concat(_common__WEBPACK_IMPORTED_MODULE_9__.a, "ms") + }, + transition: { + entered: { + marginLeft: -200 + } + } + } + }, themeStyles = function(e) { + return { + list: { + background: e.palette.grey[900] + }, + listItem: { + minWidth: 7 * e.spacing.unit + }, + icon: { + fontSize: 3 * e.spacing.unit, + overflow: "unset" + } + }; + }, SideBar = function(_Component) { + function SideBar() { + var e, t; + _classCallCheck(this, SideBar); + for (var n = arguments.length, r = new Array(n), o = 0; o < n; o++) r[o] = arguments[o]; + return _defineProperty(_assertThisInitialized(t = _possibleConstructorReturn(this, (e = _getPrototypeOf(SideBar)).call.apply(e, [ this ].concat(r)))), "clickOn", function(e) { + return function(n) { + n.preventDefault(), t.props.changeContent(e); + }; + }), _defineProperty(_assertThisInitialized(t), "menuItems", function(e) { + var n = t.props.classes, r = []; + return _common__WEBPACK_IMPORTED_MODULE_9__.b.forEach(function(o) { + r.push(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_ListItem__WEBPACK_IMPORTED_MODULE_3___default.a, { + button: !0, + key: o.id, + onClick: t.clickOn(o.id), + className: n.listItem + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_ListItemIcon__WEBPACK_IMPORTED_MODULE_4___default.a, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_Icon__WEBPACK_IMPORTED_MODULE_6___default.a, { + className: n.icon + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_8__.a, { + icon: o.icon + }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_ListItemText__WEBPACK_IMPORTED_MODULE_5___default.a, { + primary: o.title, + style: _objectSpread({}, styles.menu.default, styles.menu.transition[e], { + padding: 0 + }) + }))); + }), r; + }), _defineProperty(_assertThisInitialized(t), "menu", function(e) { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + className: t.props.classes.list + }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_material_ui_core_List__WEBPACK_IMPORTED_MODULE_2___default.a, null, t.menuItems(e))); + }), t; + } + return _inherits(SideBar, _Component), _createClass(SideBar, [ { + key: "shouldComponentUpdate", + value: function(e, t, n) { + return e.opened !== this.props.opened; + } + }, { + key: "render", + value: function() { + return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_transition_group_Transition__WEBPACK_IMPORTED_MODULE_7___default.a, { + mountOnEnter: !0, + in: this.props.opened, + timeout: { + enter: _common__WEBPACK_IMPORTED_MODULE_9__.a + } + }, this.menu); + } + }, { + key: "__reactstandin__regenerateByEval", + value: function __reactstandin__regenerateByEval(key, code) { + this[key] = eval(code); + } + } ]), SideBar; + }(react__WEBPACK_IMPORTED_MODULE_0__.Component), _default = _material_ui_core_styles_withStyles__WEBPACK_IMPORTED_MODULE_1___default()(themeStyles)(SideBar), reactHotLoader, leaveModule; + __webpack_exports__.a = _default, reactHotLoader = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).default, + reactHotLoader && (reactHotLoader.register(styles, "styles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/SideBar.jsx"), + reactHotLoader.register(themeStyles, "themeStyles", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/SideBar.jsx"), + reactHotLoader.register(SideBar, "SideBar", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/SideBar.jsx"), + reactHotLoader.register(_default, "default", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/components/SideBar.jsx")), + leaveModule = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : __webpack_require__("./node_modules/react-hot-loader/index.js")).leaveModule, + leaveModule && leaveModule(module); + }).call(this, __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)); + }, + "./index.jsx": function(e, t, n) { + "use strict"; + n.r(t), function(e) { + var t, r = n("./node_modules/react/index.js"), o = n.n(r), a = n("./node_modules/react-dom/index.js"), i = n("./node_modules/@material-ui/core/styles/MuiThemeProvider.js"), s = n.n(i), l = n("./node_modules/@material-ui/core/styles/createMuiTheme.js"), u = n.n(l), c = n("./components/Dashboard.jsx"); + (t = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).enterModule) && t(e); + var d, f, p = u()({ + palette: { + type: "dark" + } + }), h = document.getElementById("dashboard"); + h && Object(a.render)(o.a.createElement(s.a, { + theme: p + }, o.a.createElement(c.a, null)), h), (d = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).default) && (d.register(p, "theme", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/index.jsx"), + d.register(h, "dashboard", "/home/misi/Work/src/github.com/ethereum/go-ethereum/dashboard/assets/index.jsx")), + (f = ("undefined" != typeof reactHotLoaderGlobal ? reactHotLoaderGlobal : n("./node_modules/react-hot-loader/index.js")).leaveModule) && f(e); + }.call(this, n("./node_modules/webpack/buildin/harmony-module.js")(e)); + }, + "./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js": function(e, t) { + e.exports = function(e) { + if (Array.isArray(e)) { + for (var t = 0, n = new Array(e.length); t < e.length; t++) n[t] = e[t]; + return n; + } + }; + }, + "./node_modules/@babel/runtime/helpers/assertThisInitialized.js": function(e, t) { + e.exports = function(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + }; + }, + "./node_modules/@babel/runtime/helpers/classCallCheck.js": function(e, t) { + e.exports = function(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + }; + }, + "./node_modules/@babel/runtime/helpers/createClass.js": function(e, t) { + function n(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + e.exports = function(e, t, r) { + return t && n(e.prototype, t), r && n(e, r), e; + }; + }, + "./node_modules/@babel/runtime/helpers/defineProperty.js": function(e, t) { + e.exports = function(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + }; + }, + "./node_modules/@babel/runtime/helpers/extends.js": function(e, t) { + function n() { + return e.exports = n = Object.assign || function(e) { + for (var t = 1; t < arguments.length; t++) { + var n = arguments[t]; + for (var r in n) Object.prototype.hasOwnProperty.call(n, r) && (e[r] = n[r]); + } + return e; + }, n.apply(this, arguments); + } + e.exports = n; + }, + "./node_modules/@babel/runtime/helpers/getPrototypeOf.js": function(e, t) { + function n(t) { + return e.exports = n = Object.setPrototypeOf ? Object.getPrototypeOf : function(e) { + return e.__proto__ || Object.getPrototypeOf(e); + }, n(t); + } + e.exports = n; + }, + "./node_modules/@babel/runtime/helpers/inherits.js": function(e, t, n) { + var r = n("./node_modules/@babel/runtime/helpers/setPrototypeOf.js"); + e.exports = function(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), t && r(e, t); + }; + }, + "./node_modules/@babel/runtime/helpers/interopRequireDefault.js": function(e, t) { + e.exports = function(e) { + return e && e.__esModule ? e : { + default: e + }; + }; + }, + "./node_modules/@babel/runtime/helpers/interopRequireWildcard.js": function(e, t) { + e.exports = function(e) { + if (e && e.__esModule) return e; + var t = {}; + if (null != e) for (var n in e) if (Object.prototype.hasOwnProperty.call(e, n)) { + var r = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(e, n) : {}; + r.get || r.set ? Object.defineProperty(t, n, r) : t[n] = e[n]; + } + return t.default = e, t; + }; + }, + "./node_modules/@babel/runtime/helpers/iterableToArray.js": function(e, t) { + e.exports = function(e) { + if (Symbol.iterator in Object(e) || "[object Arguments]" === Object.prototype.toString.call(e)) return Array.from(e); + }; + }, + "./node_modules/@babel/runtime/helpers/nonIterableSpread.js": function(e, t) { + e.exports = function() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + }; + }, + "./node_modules/@babel/runtime/helpers/objectWithoutProperties.js": function(e, t, n) { + var r = n("./node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js"); + e.exports = function(e, t) { + if (null == e) return {}; + var n, o, a = r(e, t); + if (Object.getOwnPropertySymbols) { + var i = Object.getOwnPropertySymbols(e); + for (o = 0; o < i.length; o++) n = i[o], t.indexOf(n) >= 0 || Object.prototype.propertyIsEnumerable.call(e, n) && (a[n] = e[n]); + } + return a; + }; + }, + "./node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js": function(e, t) { + e.exports = function(e, t) { + if (null == e) return {}; + var n, r, o = {}, a = Object.keys(e); + for (r = 0; r < a.length; r++) n = a[r], t.indexOf(n) >= 0 || (o[n] = e[n]); + return o; + }; + }, + "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js": function(e, t, n) { + var r = n("./node_modules/@babel/runtime/helpers/typeof.js"), o = n("./node_modules/@babel/runtime/helpers/assertThisInitialized.js"); + e.exports = function(e, t) { + return !t || "object" !== r(t) && "function" != typeof t ? o(e) : t; + }; + }, + "./node_modules/@babel/runtime/helpers/setPrototypeOf.js": function(e, t) { + function n(t, r) { + return e.exports = n = Object.setPrototypeOf || function(e, t) { + return e.__proto__ = t, e; + }, n(t, r); + } + e.exports = n; + }, + "./node_modules/@babel/runtime/helpers/toConsumableArray.js": function(e, t, n) { + var r = n("./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js"), o = n("./node_modules/@babel/runtime/helpers/iterableToArray.js"), a = n("./node_modules/@babel/runtime/helpers/nonIterableSpread.js"); + e.exports = function(e) { + return r(e) || o(e) || a(); + }; + }, + "./node_modules/@babel/runtime/helpers/typeof.js": function(e, t) { + function n(e) { + return (n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function r(t) { + return "function" == typeof Symbol && "symbol" === n(Symbol.iterator) ? e.exports = r = function(e) { + return n(e); + } : e.exports = r = function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : n(e); + }, r(t); + } + e.exports = r; + }, + "./node_modules/@fortawesome/fontawesome-svg-core/index.es.js": function(e, t, n) { + "use strict"; + (function(e, r) { + function o(e) { + return (o = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function a(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r); + } + } + function i(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + function s(e) { + for (var t = 1; t < arguments.length; t++) { + var n = null != arguments[t] ? arguments[t] : {}, r = Object.keys(n); + "function" == typeof Object.getOwnPropertySymbols && (r = r.concat(Object.getOwnPropertySymbols(n).filter(function(e) { + return Object.getOwnPropertyDescriptor(n, e).enumerable; + }))), r.forEach(function(t) { + i(e, t, n[t]); + }); + } + return e; + } + function l(e, t) { + return function(e) { + if (Array.isArray(e)) return e; + }(e) || function(e, t) { + var n = [], r = !0, o = !1, a = void 0; + try { + for (var i, s = e[Symbol.iterator](); !(r = (i = s.next()).done) && (n.push(i.value), + !t || n.length !== t); r = !0) ; + } catch (e) { + o = !0, a = e; + } finally { + try { + r || null == s.return || s.return(); + } finally { + if (o) throw a; + } + } + return n; + }(e, t) || function() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + }(); + } + n.d(t, "a", function() { + return Ce; + }), n.d(t, "b", function() { + return Te; + }); + var u = function() {}, c = {}, d = {}, f = { + mark: u, + measure: u + }; + try { + "undefined" != typeof window && (c = window), "undefined" != typeof document && (d = document), + "undefined" != typeof MutationObserver && MutationObserver, "undefined" != typeof performance && (f = performance); + } catch (e) {} + var p = (c.navigator || {}).userAgent, h = void 0 === p ? "" : p, _ = c, m = d, y = f, b = (_.document, + !!m.documentElement && !!m.head && "function" == typeof m.addEventListener && "function" == typeof m.createElement), v = (~h.indexOf("MSIE") || h.indexOf("Trident/"), + "fa"), g = "svg-inline--fa", j = "data-fa-i2svg", x = (function() { + try { + } catch (e) { + return !1; + } + }(), [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]), O = x.concat([ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]), w = ([ "xs", "sm", "lg", "fw", "ul", "li", "border", "pull-left", "pull-right", "spin", "pulse", "rotate-90", "rotate-180", "rotate-270", "flip-horizontal", "flip-vertical", "flip-both", "stack", "stack-1x", "stack-2x", "inverse", "layers", "layers-text", "layers-counter" ].concat(x.map(function(e) { + return "".concat(e, "x"); + })).concat(O.map(function(e) { + return "w-".concat(e); + })), _.FontAwesomeConfig || {}); + if (m && "function" == typeof m.querySelector) { + [ [ "data-family-prefix", "familyPrefix" ], [ "data-replacement-class", "replacementClass" ], [ "data-auto-replace-svg", "autoReplaceSvg" ], [ "data-auto-add-css", "autoAddCss" ], [ "data-auto-a11y", "autoA11y" ], [ "data-search-pseudo-elements", "searchPseudoElements" ], [ "data-observe-mutations", "observeMutations" ], [ "data-mutate-approach", "mutateApproach" ], [ "data-keep-original-source", "keepOriginalSource" ], [ "data-measure-performance", "measurePerformance" ], [ "data-show-missing-icons", "showMissingIcons" ] ].forEach(function(e) { + var t = l(e, 2), n = t[0], r = t[1], o = function(e) { + return "" === e || "false" !== e && ("true" === e || e); + }(function(e) { + var t = m.querySelector("script[" + e + "]"); + if (t) return t.getAttribute(e); + }(n)); + null != o && (w[r] = o); + }); + } + var E = s({}, { + familyPrefix: v, + replacementClass: g, + autoReplaceSvg: !0, + autoAddCss: !0, + autoA11y: !0, + searchPseudoElements: !1, + observeMutations: !0, + mutateApproach: "async", + keepOriginalSource: !0, + measurePerformance: !1, + showMissingIcons: !0 + }, w); + E.autoReplaceSvg || (E.observeMutations = !1); + var M = s({}, E); + _.FontAwesomeConfig = M; + var P = _ || {}; + P.___FONT_AWESOME___ || (P.___FONT_AWESOME___ = {}), P.___FONT_AWESOME___.styles || (P.___FONT_AWESOME___.styles = {}), + P.___FONT_AWESOME___.hooks || (P.___FONT_AWESOME___.hooks = {}), P.___FONT_AWESOME___.shims || (P.___FONT_AWESOME___.shims = []); + var k = P.___FONT_AWESOME___, T = []; + b && ((m.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(m.readyState) || m.addEventListener("DOMContentLoaded", function e() { + m.removeEventListener("DOMContentLoaded", e), 1, T.map(function(e) { + return e(); + }); + })); + var C, S = "pending", D = "settled", A = "fulfilled", I = "rejected", R = function() {}, L = void 0 !== e && void 0 !== e.process && "function" == typeof e.process.emit, N = void 0 === r ? setTimeout : r, B = []; + function U() { + for (var e = 0; e < B.length; e++) B[e][0](B[e][1]); + B = [], C = !1; + } + function W(e, t) { + B.push([ e, t ]), C || (C = !0, N(U, 0)); + } + function z(e) { + var t = e.owner, n = t._state, r = t._data, o = e[n], a = e.then; + if ("function" == typeof o) { + n = A; + try { + r = o(r); + } catch (e) { + q(a, e); + } + } + K(a, r) || (n === A && F(a, r), n === I && q(a, r)); + } + function K(e, t) { + var n; + try { + if (e === t) throw new TypeError("A promises callback cannot return that same promise."); + if (t && ("function" == typeof t || "object" === o(t))) { + var r = t.then; + if ("function" == typeof r) return r.call(t, function(r) { + n || (n = !0, t === r ? H(e, r) : F(e, r)); + }, function(t) { + n || (n = !0, q(e, t)); + }), !0; + } + } catch (t) { + return n || q(e, t), !0; + } + return !1; + } + function F(e, t) { + e !== t && K(e, t) || H(e, t); + } + function H(e, t) { + e._state === S && (e._state = D, e._data = t, W(V, e)); + } + function q(e, t) { + e._state === S && (e._state = D, e._data = t, W(X, e)); + } + function G(e) { + e._then = e._then.forEach(z); + } + function V(e) { + e._state = A, G(e); + } + function X(t) { + t._state = I, G(t), !t._handled && L && e.process.emit("unhandledRejection", t._data, t); + } + function $(t) { + e.process.emit("rejectionHandled", t); + } + function Y(e) { + if ("function" != typeof e) throw new TypeError("Promise resolver " + e + " is not a function"); + if (this instanceof Y == !1) throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); + this._then = [], function(e, t) { + function n(e) { + q(t, e); + } + try { + e(function(e) { + F(t, e); + }, n); + } catch (e) { + n(e); + } + }(e, this); + } + Y.prototype = { + constructor: Y, + _state: S, + _then: null, + _data: void 0, + _handled: !1, + then: function(e, t) { + var n = { + owner: this, + then: new this.constructor(R), + fulfilled: e, + rejected: t + }; + return !t && !e || this._handled || (this._handled = !0, this._state === I && L && W($, this)), + this._state === A || this._state === I ? W(z, n) : this._then.push(n), n.then; + }, + catch: function(e) { + return this.then(null, e); + } + }, Y.all = function(e) { + if (!Array.isArray(e)) throw new TypeError("You must pass an array to Promise.all()."); + return new Y(function(t, n) { + var r = [], o = 0; + function a(e) { + return o++, function(n) { + r[e] = n, --o || t(r); + }; + } + for (var i, s = 0; s < e.length; s++) (i = e[s]) && "function" == typeof i.then ? i.then(a(s), n) : r[s] = i; + o || t(r); + }); + }, Y.race = function(e) { + if (!Array.isArray(e)) throw new TypeError("You must pass an array to Promise.race()."); + return new Y(function(t, n) { + for (var r, o = 0; o < e.length; o++) (r = e[o]) && "function" == typeof r.then ? r.then(t, n) : t(r); + }); + }, Y.resolve = function(e) { + return e && "object" === o(e) && e.constructor === Y ? e : new Y(function(t) { + t(e); + }); + }, Y.reject = function(e) { + return new Y(function(t, n) { + n(e); + }); + }; + "function" == typeof Promise && Promise; + var Q = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: !1, + flipY: !1 + }; + function J(e) { + if (e && b) { + var t = m.createElement("style"); + t.setAttribute("type", "text/css"), t.innerHTML = e; + for (var n = m.head.childNodes, r = null, o = n.length - 1; o > -1; o--) { + var a = n[o], i = (a.tagName || "").toUpperCase(); + [ "STYLE", "LINK" ].indexOf(i) > -1 && (r = a); + } + return m.head.insertBefore(t, r), e; + } + } + var Z = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + function ee() { + for (var e = 12, t = ""; e-- > 0; ) t += Z[62 * Math.random() | 0]; + return t; + } + function te(e) { + return "".concat(e).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">"); + } + function ne(e) { + return Object.keys(e || {}).reduce(function(t, n) { + return t + "".concat(n, ": ").concat(e[n], ";"); + }, ""); + } + function re(e) { + return e.size !== Q.size || e.x !== Q.x || e.y !== Q.y || e.rotate !== Q.rotate || e.flipX || e.flipY; + } + function oe(e) { + var t = e.transform, n = e.containerWidth, r = e.iconWidth, o = { + transform: "translate(".concat(n / 2, " 256)") + }, a = "translate(".concat(32 * t.x, ", ").concat(32 * t.y, ") "), i = "scale(".concat(t.size / 16 * (t.flipX ? -1 : 1), ", ").concat(t.size / 16 * (t.flipY ? -1 : 1), ") "), s = "rotate(".concat(t.rotate, " 0 0)"); + return { + outer: o, + inner: { + transform: "".concat(a, " ").concat(i, " ").concat(s) + }, + path: { + transform: "translate(".concat(r / 2 * -1, " -256)") + } + }; + } + var ae = { + x: 0, + y: 0, + width: "100%", + height: "100%" + }; + function ie(e) { + var t = e.icons, n = t.main, r = t.mask, o = e.prefix, a = e.iconName, i = e.transform, l = e.symbol, u = e.title, c = e.extra, d = e.watchable, f = void 0 !== d && d, p = r.found ? r : n, h = p.width, _ = p.height, m = "fa-w-".concat(Math.ceil(h / _ * 16)), y = [ M.replacementClass, a ? "".concat(M.familyPrefix, "-").concat(a) : "", m ].filter(function(e) { + return -1 === c.classes.indexOf(e); + }).concat(c.classes).join(" "), b = { + children: [], + attributes: s({}, c.attributes, { + "data-prefix": o, + "data-icon": a, + class: y, + role: c.attributes.role || "img", + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 ".concat(h, " ").concat(_) + }) + }; + f && (b.attributes[j] = ""), u && b.children.push({ + tag: "title", + attributes: { + id: b.attributes["aria-labelledby"] || "title-".concat(ee()) + }, + children: [ u ] + }); + var v = s({}, b, { + prefix: o, + iconName: a, + main: n, + mask: r, + transform: i, + symbol: l, + styles: c.styles + }), g = r.found && n.found ? function(e) { + var t = e.children, n = e.attributes, r = e.main, o = e.mask, a = e.transform, i = r.width, l = r.icon, u = o.width, c = o.icon, d = oe({ + transform: a, + containerWidth: u, + iconWidth: i + }), f = { + tag: "rect", + attributes: s({}, ae, { + fill: "white" + }) + }, p = { + tag: "g", + attributes: s({}, d.inner), + children: [ { + tag: "path", + attributes: s({}, l.attributes, d.path, { + fill: "black" + }) + } ] + }, h = { + tag: "g", + attributes: s({}, d.outer), + children: [ p ] + }, _ = "mask-".concat(ee()), m = "clip-".concat(ee()), y = { + tag: "defs", + children: [ { + tag: "clipPath", + attributes: { + id: m + }, + children: [ c ] + }, { + tag: "mask", + attributes: s({}, ae, { + id: _, + maskUnits: "userSpaceOnUse", + maskContentUnits: "userSpaceOnUse" + }), + children: [ f, h ] + } ] + }; + return t.push(y, { + tag: "rect", + attributes: s({ + fill: "currentColor", + "clip-path": "url(#".concat(m, ")"), + mask: "url(#".concat(_, ")") + }, ae) + }), { + children: t, + attributes: n + }; + }(v) : function(e) { + var t = e.children, n = e.attributes, r = e.main, o = e.transform, a = ne(e.styles); + if (a.length > 0 && (n.style = a), re(o)) { + var i = oe({ + transform: o, + containerWidth: r.width, + iconWidth: r.width + }); + t.push({ + tag: "g", + attributes: s({}, i.outer), + children: [ { + tag: "g", + attributes: s({}, i.inner), + children: [ { + tag: r.icon.tag, + children: r.icon.children, + attributes: s({}, r.icon.attributes, i.path) + } ] + } ] + }); + } else t.push(r.icon); + return { + children: t, + attributes: n + }; + }(v), x = g.children, O = g.attributes; + return v.children = x, v.attributes = O, l ? function(e) { + var t = e.prefix, n = e.iconName, r = e.children, o = e.attributes, a = e.symbol; + return [ { + tag: "svg", + attributes: { + style: "display: none;" + }, + children: [ { + tag: "symbol", + attributes: s({}, o, { + id: !0 === a ? "".concat(t, "-").concat(M.familyPrefix, "-").concat(n) : a + }), + children: r + } ] + } ]; + }(v) : function(e) { + var t = e.children, n = e.main, r = e.mask, o = e.attributes, a = e.styles, i = e.transform; + if (re(i) && n.found && !r.found) { + var l = { + x: n.width / n.height / 2, + y: .5 + }; + o.style = ne(s({}, a, { + "transform-origin": "".concat(l.x + i.x / 16, "em ").concat(l.y + i.y / 16, "em") + })); + } + return [ { + tag: "svg", + attributes: o, + children: t + } ]; + }(v); + } + var se = function() {}, le = (M.measurePerformance && y && y.mark && y.measure, + function(e, t, n, r) { + var o, a, i, s = Object.keys(e), l = s.length, u = void 0 !== r ? function(e, t) { + return function(n, r, o, a) { + return e.call(t, n, r, o, a); + }; + }(t, r) : t; + for (void 0 === n ? (o = 1, i = e[s[0]]) : (o = 0, i = n); o < l; o++) i = u(i, e[a = s[o]], a, e); + return i; + }); + var ue = k.styles, ce = k.shims, de = function() { + var e = function(e) { + return le(ue, function(t, n, r) { + return t[r] = le(n, e, {}), t; + }, {}); + }; + e(function(e, t, n) { + return t[3] && (e[t[3]] = n), e; + }), e(function(e, t, n) { + var r = t[2]; + return e[n] = n, r.forEach(function(t) { + e[t] = n; + }), e; + }); + var t = "far" in ue; + le(ce, function(e, n) { + var r = n[0], o = n[1], a = n[2]; + return "far" !== o || t || (o = "fas"), e[r] = { + prefix: o, + iconName: a + }, e; + }, {}); + }; + de(); + k.styles; + function fe(e, t, n) { + if (e && e[t] && e[t][n]) return { + prefix: t, + iconName: n, + icon: e[t][n] + }; + } + function pe(e) { + var t = e.tag, n = e.attributes, r = void 0 === n ? {} : n, o = e.children, a = void 0 === o ? [] : o; + return "string" == typeof e ? te(e) : "<".concat(t, " ").concat(function(e) { + return Object.keys(e || {}).reduce(function(t, n) { + return t + "".concat(n, '="').concat(te(e[n]), '" '); + }, "").trim(); + }(r), ">").concat(a.map(pe).join(""), ""); + } + var he = function(e) { + var t = { + size: 16, + x: 0, + y: 0, + flipX: !1, + flipY: !1, + rotate: 0 + }; + return e ? e.toLowerCase().split(" ").reduce(function(e, t) { + var n = t.toLowerCase().split("-"), r = n[0], o = n.slice(1).join("-"); + if (r && "h" === o) return e.flipX = !0, e; + if (r && "v" === o) return e.flipY = !0, e; + if (o = parseFloat(o), isNaN(o)) return e; + switch (r) { + case "grow": + e.size = e.size + o; + break; + + case "shrink": + e.size = e.size - o; + break; + + case "left": + e.x = e.x - o; + break; + + case "right": + e.x = e.x + o; + break; + + case "up": + e.y = e.y - o; + break; + + case "down": + e.y = e.y + o; + break; + + case "rotate": + e.rotate = e.rotate + o; + } + return e; + }, t) : t; + }; + function _e(e) { + this.name = "MissingIcon", this.message = e || "Icon unavailable", this.stack = new Error().stack; + } + _e.prototype = Object.create(Error.prototype), _e.prototype.constructor = _e; + var me = { + fill: "currentColor" + }, ye = { + attributeType: "XML", + repeatCount: "indefinite", + dur: "2s" + }, be = { + tag: "path", + attributes: s({}, me, { + d: "M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z" + }) + }, ve = s({}, ye, { + attributeName: "opacity" + }); + s({}, me, { + cx: "256", + cy: "364", + r: "28" + }), s({}, ye, { + attributeName: "r", + values: "28;14;28;28;14;28;" + }), s({}, ve, { + values: "1;0;1;1;0;1;" + }), s({}, me, { + opacity: "1", + d: "M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z" + }), s({}, ve, { + values: "1;0;0;0;0;1;" + }), s({}, me, { + opacity: "0", + d: "M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z" + }), s({}, ve, { + values: "0;0;1;1;0;0;" + }), k.styles; + k.styles; + var ge = 'svg:not(:root).svg-inline--fa {\n overflow: visible;\n}\n\n.svg-inline--fa {\n display: inline-block;\n font-size: inherit;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n}\n.svg-inline--fa.fa-lg {\n vertical-align: -0.225em;\n}\n.svg-inline--fa.fa-w-1 {\n width: 0.0625em;\n}\n.svg-inline--fa.fa-w-2 {\n width: 0.125em;\n}\n.svg-inline--fa.fa-w-3 {\n width: 0.1875em;\n}\n.svg-inline--fa.fa-w-4 {\n width: 0.25em;\n}\n.svg-inline--fa.fa-w-5 {\n width: 0.3125em;\n}\n.svg-inline--fa.fa-w-6 {\n width: 0.375em;\n}\n.svg-inline--fa.fa-w-7 {\n width: 0.4375em;\n}\n.svg-inline--fa.fa-w-8 {\n width: 0.5em;\n}\n.svg-inline--fa.fa-w-9 {\n width: 0.5625em;\n}\n.svg-inline--fa.fa-w-10 {\n width: 0.625em;\n}\n.svg-inline--fa.fa-w-11 {\n width: 0.6875em;\n}\n.svg-inline--fa.fa-w-12 {\n width: 0.75em;\n}\n.svg-inline--fa.fa-w-13 {\n width: 0.8125em;\n}\n.svg-inline--fa.fa-w-14 {\n width: 0.875em;\n}\n.svg-inline--fa.fa-w-15 {\n width: 0.9375em;\n}\n.svg-inline--fa.fa-w-16 {\n width: 1em;\n}\n.svg-inline--fa.fa-w-17 {\n width: 1.0625em;\n}\n.svg-inline--fa.fa-w-18 {\n width: 1.125em;\n}\n.svg-inline--fa.fa-w-19 {\n width: 1.1875em;\n}\n.svg-inline--fa.fa-w-20 {\n width: 1.25em;\n}\n.svg-inline--fa.fa-pull-left {\n margin-right: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-pull-right {\n margin-left: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-border {\n height: 1.5em;\n}\n.svg-inline--fa.fa-li {\n width: 2em;\n}\n.svg-inline--fa.fa-fw {\n width: 1.25em;\n}\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -0.125em;\n width: 1em;\n}\n.fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter, .fa-layers-text {\n display: inline-block;\n position: absolute;\n text-align: center;\n}\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter {\n background-color: #ff253a;\n border-radius: 1em;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n color: #fff;\n height: 1.5em;\n line-height: 1;\n max-width: 5em;\n min-width: 1.5em;\n overflow: hidden;\n padding: 0.25em;\n right: 0;\n text-overflow: ellipsis;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-bottom-right {\n bottom: 0;\n right: 0;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right;\n}\n\n.fa-layers-bottom-left {\n bottom: 0;\n left: 0;\n right: auto;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left;\n}\n\n.fa-layers-top-right {\n right: 0;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-top-left {\n left: 0;\n right: auto;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top left;\n transform-origin: top left;\n}\n\n.fa-lg {\n font-size: 1.3333333333em;\n line-height: 0.75em;\n vertical-align: -0.0667em;\n}\n\n.fa-xs {\n font-size: 0.75em;\n}\n\n.fa-sm {\n font-size: 0.875em;\n}\n\n.fa-1x {\n font-size: 1em;\n}\n\n.fa-2x {\n font-size: 2em;\n}\n\n.fa-3x {\n font-size: 3em;\n}\n\n.fa-4x {\n font-size: 4em;\n}\n\n.fa-5x {\n font-size: 5em;\n}\n\n.fa-6x {\n font-size: 6em;\n}\n\n.fa-7x {\n font-size: 7em;\n}\n\n.fa-8x {\n font-size: 8em;\n}\n\n.fa-9x {\n font-size: 9em;\n}\n\n.fa-10x {\n font-size: 10em;\n}\n\n.fa-fw {\n text-align: center;\n width: 1.25em;\n}\n\n.fa-ul {\n list-style-type: none;\n margin-left: 2.5em;\n padding-left: 0;\n}\n.fa-ul > li {\n position: relative;\n}\n\n.fa-li {\n left: -2em;\n position: absolute;\n text-align: center;\n width: 2em;\n line-height: inherit;\n}\n\n.fa-border {\n border: solid 0.08em #eee;\n border-radius: 0.1em;\n padding: 0.2em 0.25em 0.15em;\n}\n\n.fa-pull-left {\n float: left;\n}\n\n.fa-pull-right {\n float: right;\n}\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n margin-right: 0.3em;\n}\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n margin-left: 0.3em;\n}\n\n.fa-spin {\n -webkit-animation: fa-spin 2s infinite linear;\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n -webkit-animation: fa-spin 1s infinite steps(8);\n animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.fa-rotate-90 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1);\n}\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1);\n}\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n -webkit-filter: none;\n filter: none;\n}\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n position: relative;\n width: 2.5em;\n}\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1.25em;\n}\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2.5em;\n}\n\n.fa-inverse {\n color: #fff;\n}\n\n.sr-only {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n clip: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n position: static;\n width: auto;\n}'; + function je() { + var e = v, t = g, n = M.familyPrefix, r = M.replacementClass, o = ge; + if (n !== e || r !== t) { + var a = new RegExp("\\.".concat(e, "\\-"), "g"), i = new RegExp("\\.".concat(t), "g"); + o = o.replace(a, ".".concat(n, "-")).replace(i, ".".concat(r)); + } + return o; + } + function xe(e) { + return { + found: !0, + width: e[0], + height: e[1], + icon: { + tag: "path", + attributes: { + fill: "currentColor", + d: e.slice(4)[0] + } + } + }; + } + function Oe() { + M.autoAddCss && !ke && (J(je()), ke = !0); + } + function we(e, t) { + return Object.defineProperty(e, "abstract", { + get: t + }), Object.defineProperty(e, "html", { + get: function() { + return e.abstract.map(function(e) { + return pe(e); + }); + } + }), Object.defineProperty(e, "node", { + get: function() { + if (b) { + var t = m.createElement("div"); + return t.innerHTML = e.html, t.children; + } + } + }), e; + } + function Ee(e) { + var t = e.prefix, n = void 0 === t ? "fa" : t, r = e.iconName; + if (r) return fe(Pe.definitions, n, r) || fe(k.styles, n, r); + } + var Me, Pe = new (function() { + function e() { + !function(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function"); + }(this, e), this.definitions = {}; + } + var t, n, r; + return t = e, (n = [ { + key: "add", + value: function() { + for (var e = this, t = arguments.length, n = new Array(t), r = 0; r < t; r++) n[r] = arguments[r]; + var o = n.reduce(this._pullDefinitions, {}); + Object.keys(o).forEach(function(t) { + e.definitions[t] = s({}, e.definitions[t] || {}, o[t]), function e(t, n) { + var r = (arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}).skipHooks, o = void 0 !== r && r, a = Object.keys(n).reduce(function(e, t) { + var r = n[t]; + return r.icon ? e[r.iconName] = r.icon : e[t] = r, e; + }, {}); + "function" != typeof k.hooks.addPack || o ? k.styles[t] = s({}, k.styles[t] || {}, a) : k.hooks.addPack(t, a), + "fas" === t && e("fa", n); + }(t, o[t]), de(); + }); + } + }, { + key: "reset", + value: function() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function(e, t) { + var n = t.prefix && t.iconName && t.icon ? { + 0: t + } : t; + return Object.keys(n).map(function(t) { + var r = n[t], o = r.prefix, a = r.iconName, i = r.icon; + e[o] || (e[o] = {}), e[o][a] = i; + }), e; + } + } ]) && a(t.prototype, n), r && a(t, r), e; + }())(), ke = !1, Te = { + transform: function(e) { + return he(e); + } + }, Ce = (Me = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.transform, r = void 0 === n ? Q : n, o = t.symbol, a = void 0 !== o && o, i = t.mask, l = void 0 === i ? null : i, u = t.title, c = void 0 === u ? null : u, d = t.classes, f = void 0 === d ? [] : d, p = t.attributes, h = void 0 === p ? {} : p, _ = t.styles, m = void 0 === _ ? {} : _; + if (e) { + var y = e.prefix, b = e.iconName, v = e.icon; + return we(s({ + type: "icon" + }, e), function() { + return Oe(), M.autoA11y && (c ? h["aria-labelledby"] = "".concat(M.replacementClass, "-title-").concat(ee()) : (h["aria-hidden"] = "true", + h.focusable = "false")), ie({ + icons: { + main: xe(v), + mask: l ? xe(l.icon) : { + found: !1, + width: null, + height: null, + icon: {} + } + }, + prefix: y, + iconName: b, + transform: s({}, Q, r), + symbol: a, + title: c, + extra: { + attributes: h, + styles: m, + classes: f + } + }); + }); + } + }, function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = (e || {}).icon ? e : Ee(e || {}), r = t.mask; + return r && (r = (r || {}).icon ? r : Ee(r || {})), Me(n, s({}, t, { + mask: r + })); + }); + }).call(this, n("./node_modules/webpack/buildin/global.js"), n("./node_modules/timers-browserify/main.js").setImmediate); + }, + "./node_modules/@fortawesome/free-regular-svg-icons/index.es.js": function(e, t, n) { + "use strict"; + n.d(t, "a", function() { + return r; + }), n.d(t, "b", function() { + return o; + }); + var r = { + prefix: "far", + iconName: "circle", + icon: [ 512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z" ] + }, o = { + prefix: "far", + iconName: "credit-card", + icon: [ 576, 512, [], "f09d", "M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z" ] + }; + }, + "./node_modules/@fortawesome/free-solid-svg-icons/index.es.js": function(e, t, n) { + "use strict"; + n.d(t, "a", function() { + return r; + }), n.d(t, "b", function() { + return o; + }), n.d(t, "c", function() { + return a; + }), n.d(t, "d", function() { + return i; + }), n.d(t, "e", function() { + return s; + }), n.d(t, "f", function() { + return l; + }), n.d(t, "g", function() { + return u; + }); + var r = { + prefix: "fas", + iconName: "bars", + icon: [ 448, 512, [], "f0c9", "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" ] + }, o = { + prefix: "fas", + iconName: "circle", + icon: [ 512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z" ] + }, a = { + prefix: "fas", + iconName: "globe-europe", + icon: [ 496, 512, [], "f7a2", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm200 248c0 22.5-3.9 44.2-10.8 64.4h-20.3c-4.3 0-8.4-1.7-11.4-4.8l-32-32.6c-4.5-4.6-4.5-12.1.1-16.7l12.5-12.5v-8.7c0-3-1.2-5.9-3.3-8l-9.4-9.4c-2.1-2.1-5-3.3-8-3.3h-16c-6.2 0-11.3-5.1-11.3-11.3 0-3 1.2-5.9 3.3-8l9.4-9.4c2.1-2.1 5-3.3 8-3.3h32c6.2 0 11.3-5.1 11.3-11.3v-9.4c0-6.2-5.1-11.3-11.3-11.3h-36.7c-8.8 0-16 7.2-16 16v4.5c0 6.9-4.4 13-10.9 15.2l-31.6 10.5c-3.3 1.1-5.5 4.1-5.5 7.6v2.2c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8s-3.6-8-8-8H247c-3 0-5.8 1.7-7.2 4.4l-9.4 18.7c-2.7 5.4-8.2 8.8-14.3 8.8H194c-8.8 0-16-7.2-16-16V199c0-4.2 1.7-8.3 4.7-11.3l20.1-20.1c4.6-4.6 7.2-10.9 7.2-17.5 0-3.4 2.2-6.5 5.5-7.6l40-13.3c1.7-.6 3.2-1.5 4.4-2.7l26.8-26.8c2.1-2.1 3.3-5 3.3-8 0-6.2-5.1-11.3-11.3-11.3H258l-16 16v8c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8v-20c0-2.5 1.2-4.9 3.2-6.4l28.9-21.7c1.9-.1 3.8-.3 5.7-.3C358.3 56 448 145.7 448 256zM130.1 149.1c0-3 1.2-5.9 3.3-8l25.4-25.4c2.1-2.1 5-3.3 8-3.3 6.2 0 11.3 5.1 11.3 11.3v16c0 3-1.2 5.9-3.3 8l-9.4 9.4c-2.1 2.1-5 3.3-8 3.3h-16c-6.2 0-11.3-5.1-11.3-11.3zm128 306.4v-7.1c0-8.8-7.2-16-16-16h-20.2c-10.8 0-26.7-5.3-35.4-11.8l-22.2-16.7c-11.5-8.6-18.2-22.1-18.2-36.4v-23.9c0-16 8.4-30.8 22.1-39l42.9-25.7c7.1-4.2 15.2-6.5 23.4-6.5h31.2c10.9 0 21.4 3.9 29.6 10.9l43.2 37.1h18.3c8.5 0 16.6 3.4 22.6 9.4l17.3 17.3c3.4 3.4 8.1 5.3 12.9 5.3H423c-32.4 58.9-93.8 99.5-164.9 103.1z" ] + }, i = { + prefix: "fas", + iconName: "home", + icon: [ 576, 512, [], "f015", "M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z" ] + }, s = { + prefix: "fas", + iconName: "link", + icon: [ 512, 512, [], "f0c1", "M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z" ] + }, l = { + prefix: "fas", + iconName: "list", + icon: [ 512, 512, [], "f03a", "M80 368H16a16 16 0 0 0-16 16v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-64a16 16 0 0 0-16-16zm0-320H16A16 16 0 0 0 0 64v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16zm0 160H16a16 16 0 0 0-16 16v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-64a16 16 0 0 0-16-16zm416 176H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z" ] + }, u = { + prefix: "fas", + iconName: "tachometer-alt", + icon: [ 576, 512, [], "f3fd", "M288 32C128.94 32 0 160.94 0 320c0 52.8 14.25 102.26 39.06 144.8 5.61 9.62 16.3 15.2 27.44 15.2h443c11.14 0 21.83-5.58 27.44-15.2C561.75 422.26 576 372.8 576 320c0-159.06-128.94-288-288-288zm0 64c14.71 0 26.58 10.13 30.32 23.65-1.11 2.26-2.64 4.23-3.45 6.67l-9.22 27.67c-5.13 3.49-10.97 6.01-17.64 6.01-17.67 0-32-14.33-32-32S270.33 96 288 96zM96 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm48-160c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm246.77-72.41l-61.33 184C343.13 347.33 352 364.54 352 384c0 11.72-3.38 22.55-8.88 32H232.88c-5.5-9.45-8.88-20.28-8.88-32 0-33.94 26.5-61.43 59.9-63.59l61.34-184.01c4.17-12.56 17.73-19.45 30.36-15.17 12.57 4.19 19.35 17.79 15.17 30.36zm14.66 57.2l15.52-46.55c3.47-1.29 7.13-2.23 11.05-2.23 17.67 0 32 14.33 32 32s-14.33 32-32 32c-11.38-.01-20.89-6.28-26.57-15.22zM480 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z" ] + }; + }, + "./node_modules/@fortawesome/react-fontawesome/index.es.js": function(e, t, n) { + "use strict"; + (function(e) { + n.d(t, "a", function() { + return b; + }); + var r = n("./node_modules/@fortawesome/fontawesome-svg-core/index.es.js"), o = n("./node_modules/prop-types/index.js"), a = n.n(o), i = n("./node_modules/react/index.js"), s = n.n(i); + function l(e) { + return (l = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e; + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + })(e); + } + function u(e, t, n) { + return t in e ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[t] = n, e; + } + function c(e) { + for (var t = 1; t < arguments.length; t++) { + var n = null != arguments[t] ? arguments[t] : {}, r = Object.keys(n); + "function" == typeof Object.getOwnPropertySymbols && (r = r.concat(Object.getOwnPropertySymbols(n).filter(function(e) { + return Object.getOwnPropertyDescriptor(n, e).enumerable; + }))), r.forEach(function(t) { + u(e, t, n[t]); + }); + } + return e; + } + function d(e, t) { + if (null == e) return {}; + var n, r, o = function(e, t) { + if (null == e) return {}; + var n, r, o = {}, a = Object.keys(e); + for (r = 0; r < a.length; r++) n = a[r], t.indexOf(n) >= 0 || (o[n] = e[n]); + return o; + }(e, t); + if (Object.getOwnPropertySymbols) { + var a = Object.getOwnPropertySymbols(e); + for (r = 0; r < a.length; r++) n = a[r], t.indexOf(n) >= 0 || Object.prototype.propertyIsEnumerable.call(e, n) && (o[n] = e[n]); + } + return o; + } + function f(e) { + return function(e) { + if (Array.isArray(e)) { + for (var t = 0, n = new Array(e.length); t < e.length; t++) n[t] = e[t]; + return n; + } + }(e) || function(e) { + if (Symbol.iterator in Object(e) || "[object Arguments]" === Object.prototype.toString.call(e)) return Array.from(e); + }(e) || function() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + }(); + } + var p = "undefined" != typeof window ? window : void 0 !== e ? e : "undefined" != typeof self ? self : {}; + var h = function(e, t) { + return e(t = { + exports: {} + }, t.exports), t.exports; + }(function(e) { + !function(t) { + var n = function(e, t, r) { + if (!l(t) || c(t) || d(t) || f(t) || s(t)) return t; + var o, a = 0, i = 0; + if (u(t)) for (o = [], i = t.length; a < i; a++) o.push(n(e, t[a], r)); else for (var p in o = {}, + t) Object.prototype.hasOwnProperty.call(t, p) && (o[e(p, r)] = n(e, t[p], r)); + return o; + }, r = function(e) { + return p(e) ? e : (e = e.replace(/[\-_\s]+(.)?/g, function(e, t) { + return t ? t.toUpperCase() : ""; + })).substr(0, 1).toLowerCase() + e.substr(1); + }, o = function(e) { + var t = r(e); + return t.substr(0, 1).toUpperCase() + t.substr(1); + }, a = function(e, t) { + return function(e, t) { + var n = (t = t || {}).separator || "_", r = t.split || /(?=[A-Z])/; + return e.split(r).join(n); + }(e, t).toLowerCase(); + }, i = Object.prototype.toString, s = function(e) { + return "function" == typeof e; + }, l = function(e) { + return e === Object(e); + }, u = function(e) { + return "[object Array]" == i.call(e); + }, c = function(e) { + return "[object Date]" == i.call(e); + }, d = function(e) { + return "[object RegExp]" == i.call(e); + }, f = function(e) { + return "[object Boolean]" == i.call(e); + }, p = function(e) { + return (e -= 0) == e; + }, h = function(e, t) { + var n = t && "process" in t ? t.process : t; + return "function" != typeof n ? e : function(t, r) { + return n(t, e, r); + }; + }, _ = { + camelize: r, + decamelize: a, + pascalize: o, + depascalize: a, + camelizeKeys: function(e, t) { + return n(h(r, t), e); + }, + decamelizeKeys: function(e, t) { + return n(h(a, t), e, t); + }, + pascalizeKeys: function(e, t) { + return n(h(o, t), e); + }, + depascalizeKeys: function() { + return this.decamelizeKeys.apply(this, arguments); + } + }; + e.exports ? e.exports = _ : t.humps = _; + }(p); + }); + var _ = !1; + try { + _ = !0; + } catch (e) {} + function m(e, t) { + return Array.isArray(t) && t.length > 0 || !Array.isArray(t) && t ? u({}, e, t) : {}; + } + function y(e) { + return null === e ? null : "object" === l(e) && e.prefix && e.iconName ? e : Array.isArray(e) && 2 === e.length ? { + prefix: e[0], + iconName: e[1] + } : "string" == typeof e ? { + prefix: "fas", + iconName: e + } : void 0; + } + function b(e) { + var t = e.icon, n = e.mask, o = e.symbol, a = e.className, i = e.title, s = y(t), l = m("classes", [].concat(f(function(e) { + var t, n = (u(t = { + "fa-spin": e.spin, + "fa-pulse": e.pulse, + "fa-fw": e.fixedWidth, + "fa-inverse": e.inverse, + "fa-border": e.border, + "fa-li": e.listItem, + "fa-flip-horizontal": "horizontal" === e.flip || "both" === e.flip, + "fa-flip-vertical": "vertical" === e.flip || "both" === e.flip + }, "fa-".concat(e.size), null !== e.size), u(t, "fa-rotate-".concat(e.rotation), null !== e.rotation), + u(t, "fa-pull-".concat(e.pull), null !== e.pull), t); + return Object.keys(n).map(function(e) { + return n[e] ? e : null; + }).filter(function(e) { + return e; + }); + }(e)), f(a.split(" ")))), d = m("transform", "string" == typeof e.transform ? r.b.transform(e.transform) : e.transform), p = m("mask", y(n)), h = Object(r.a)(s, c({}, l, d, p, { + symbol: o, + title: i + })); + if (!h) return function() { + var e; + !_ && console && "function" == typeof console.error && (e = console).error.apply(e, arguments); + }("Could not find icon", s), null; + var g = h.abstract, j = {}; + return Object.keys(e).forEach(function(t) { + b.defaultProps.hasOwnProperty(t) || (j[t] = e[t]); + }), v(g[0], j); + } + b.displayName = "FontAwesomeIcon", b.propTypes = { + border: a.a.bool, + className: a.a.string, + mask: a.a.oneOfType([ a.a.object, a.a.array, a.a.string ]), + fixedWidth: a.a.bool, + inverse: a.a.bool, + flip: a.a.oneOf([ "horizontal", "vertical", "both" ]), + icon: a.a.oneOfType([ a.a.object, a.a.array, a.a.string ]), + listItem: a.a.bool, + pull: a.a.oneOf([ "right", "left" ]), + pulse: a.a.bool, + rotation: a.a.oneOf([ 90, 180, 270 ]), + size: a.a.oneOf([ "lg", "xs", "sm", "1x", "2x", "3x", "4x", "5x", "6x", "7x", "8x", "9x", "10x" ]), + spin: a.a.bool, + symbol: a.a.oneOfType([ a.a.bool, a.a.string ]), + title: a.a.string, + transform: a.a.oneOfType([ a.a.string, a.a.object ]) + }, b.defaultProps = { + border: !1, + className: "", + mask: null, + fixedWidth: !1, + inverse: !1, + flip: null, + icon: null, + listItem: !1, + pull: null, + pulse: !1, + rotation: null, + size: null, + spin: !1, + symbol: !1, + title: "", + transform: null + }; + var v = function e(t, n) { + var r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}; + if ("string" == typeof n) return n; + var o = (n.children || []).map(function(n) { + return e(t, n); + }), a = Object.keys(n.attributes || {}).reduce(function(e, t) { + var r = n.attributes[t]; + switch (t) { + case "class": + e.attrs.className = r, delete n.attributes.class; + break; + + case "style": + e.attrs.style = r.split(";").map(function(e) { + return e.trim(); + }).filter(function(e) { + return e; + }).reduce(function(e, t) { + var n, r = t.indexOf(":"), o = h.camelize(t.slice(0, r)), a = t.slice(r + 1).trim(); + return o.startsWith("webkit") ? e[(n = o, n.charAt(0).toUpperCase() + n.slice(1))] = a : e[o] = a, + e; + }, {}); + break; + + default: + 0 === t.indexOf("aria-") || 0 === t.indexOf("data-") ? e.attrs[t.toLowerCase()] = r : e.attrs[h.camelize(t)] = r; + } + return e; + }, { + attrs: {} + }), i = r.style, s = void 0 === i ? {} : i, l = d(r, [ "style" ]); + return a.attrs.style = c({}, a.attrs.style, s), t.apply(void 0, [ n.tag, c({}, a.attrs, l) ].concat(f(o))); + }.bind(null, s.a.createElement); + }).call(this, n("./node_modules/webpack/buildin/global.js")); + }, + "./node_modules/@material-ui/core/AppBar/AppBar.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), c = n("./node_modules/@material-ui/core/utils/helpers.js"), d = r(n("./node_modules/@material-ui/core/Paper/index.js")), f = function(e) { + var t = "light" === e.palette.type ? e.palette.grey[100] : e.palette.grey[900]; + return { + root: { + display: "flex", + flexDirection: "column", + width: "100%", + boxSizing: "border-box", + zIndex: e.zIndex.appBar, + flexShrink: 0 + }, + positionFixed: { + position: "fixed", + top: 0, + left: "auto", + right: 0 + }, + positionAbsolute: { + position: "absolute", + top: 0, + left: "auto", + right: 0 + }, + positionSticky: { + position: "sticky", + top: 0, + left: "auto", + right: 0 + }, + positionStatic: { + position: "static" + }, + positionRelative: { + position: "relative" + }, + colorDefault: { + backgroundColor: t, + color: e.palette.getContrastText(t) + }, + colorPrimary: { + backgroundColor: e.palette.primary.main, + color: e.palette.primary.contrastText + }, + colorSecondary: { + backgroundColor: e.palette.secondary.main, + color: e.palette.secondary.contrastText + } + }; + }; + function p(e) { + var t, n = e.children, r = e.classes, u = e.className, f = e.color, p = e.position, h = (0, + i.default)(e, [ "children", "classes", "className", "color", "position" ]), _ = (0, + l.default)(r.root, r["position".concat((0, c.capitalize)(p))], (t = {}, (0, a.default)(t, r["color".concat((0, + c.capitalize)(f))], "inherit" !== f), (0, a.default)(t, "mui-fixed", "fixed" === p), + t), u); + return s.default.createElement(d.default, (0, o.default)({ + square: !0, + component: "header", + elevation: 4, + className: _ + }, h), n); + } + t.styles = f, p.defaultProps = { + color: "primary", + position: "fixed" + }; + var h = (0, u.default)(f, { + name: "MuiAppBar" + })(p); + t.default = h; + }, + "./node_modules/@material-ui/core/AppBar/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/AppBar/AppBar.js")); + }, + "./node_modules/@material-ui/core/ButtonBase/ButtonBase.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), l = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), u = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), c = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), d = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), f = r(n("./node_modules/@babel/runtime/helpers/assertThisInitialized.js")), p = r(n("./node_modules/react/index.js")), h = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/react-dom/index.js"))), _ = r(n("./node_modules/classnames/index.js")), m = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/utils/ownerWindow.js"))), y = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), b = r(n("./node_modules/@material-ui/core/NoSsr/index.js")), v = n("./node_modules/@material-ui/core/ButtonBase/focusVisible.js"), g = r(n("./node_modules/@material-ui/core/ButtonBase/TouchRipple.js")), j = r(n("./node_modules/@material-ui/core/ButtonBase/createRippleHandler.js")), x = { + root: { + display: "inline-flex", + alignItems: "center", + justifyContent: "center", + position: "relative", + WebkitTapHighlightColor: "transparent", + backgroundColor: "transparent", + outline: "none", + border: 0, + margin: 0, + borderRadius: 0, + padding: 0, + cursor: "pointer", + userSelect: "none", + verticalAlign: "middle", + "-moz-appearance": "none", + "-webkit-appearance": "none", + textDecoration: "none", + color: "inherit", + "&::-moz-focus-inner": { + borderStyle: "none" + }, + "&$disabled": { + pointerEvents: "none", + cursor: "default" + } + }, + disabled: {}, + focusVisible: {} + }; + t.styles = x; + var O = function(e) { + function t() { + var e, n; + (0, s.default)(this, t); + for (var r = arguments.length, o = new Array(r), a = 0; a < r; a++) o[a] = arguments[a]; + return (n = (0, u.default)(this, (e = (0, c.default)(t)).call.apply(e, [ this ].concat(o)))).state = {}, + n.keyDown = !1, n.focusVisibleCheckTime = 50, n.focusVisibleMaxCheckTimes = 5, n.handleMouseDown = (0, + j.default)((0, f.default)((0, f.default)(n)), "MouseDown", "start", function() { + clearTimeout(n.focusVisibleTimeout), n.state.focusVisible && n.setState({ + focusVisible: !1 + }); + }), n.handleMouseUp = (0, j.default)((0, f.default)((0, f.default)(n)), "MouseUp", "stop"), + n.handleMouseLeave = (0, j.default)((0, f.default)((0, f.default)(n)), "MouseLeave", "stop", function(e) { + n.state.focusVisible && e.preventDefault(); + }), n.handleTouchStart = (0, j.default)((0, f.default)((0, f.default)(n)), "TouchStart", "start"), + n.handleTouchEnd = (0, j.default)((0, f.default)((0, f.default)(n)), "TouchEnd", "stop"), + n.handleTouchMove = (0, j.default)((0, f.default)((0, f.default)(n)), "TouchMove", "stop"), + n.handleContextMenu = (0, j.default)((0, f.default)((0, f.default)(n)), "ContextMenu", "stop"), + n.handleBlur = (0, j.default)((0, f.default)((0, f.default)(n)), "Blur", "stop", function() { + clearTimeout(n.focusVisibleTimeout), n.state.focusVisible && n.setState({ + focusVisible: !1 + }); + }), n.onRippleRef = function(e) { + n.ripple = e; + }, n.onFocusVisibleHandler = function(e) { + n.keyDown = !1, n.setState({ + focusVisible: !0 + }), n.props.onFocusVisible && n.props.onFocusVisible(e); + }, n.handleKeyDown = function(e) { + var t = n.props, r = t.component, o = t.focusRipple, a = t.onKeyDown, i = t.onClick; + o && !n.keyDown && n.state.focusVisible && n.ripple && " " === e.key && (n.keyDown = !0, + e.persist(), n.ripple.stop(e, function() { + n.ripple.start(e); + })), a && a(e), e.target !== e.currentTarget || !r || "button" === r || " " !== e.key && "Enter" !== e.key || "A" === n.button.tagName && n.button.href || (e.preventDefault(), + i && i(e)); + }, n.handleKeyUp = function(e) { + n.props.focusRipple && " " === e.key && n.ripple && n.state.focusVisible && (n.keyDown = !1, + e.persist(), n.ripple.stop(e, function() { + n.ripple.pulsate(e); + })), n.props.onKeyUp && n.props.onKeyUp(e); + }, n.handleFocus = function(e) { + n.props.disabled || (n.button || (n.button = e.currentTarget), e.persist(), (0, + v.detectFocusVisible)((0, f.default)((0, f.default)(n)), n.button, function() { + n.onFocusVisibleHandler(e); + }), n.props.onFocus && n.props.onFocus(e)); + }, n; + } + return (0, d.default)(t, e), (0, l.default)(t, [ { + key: "componentDidMount", + value: function() { + var e = this; + this.button = h.default.findDOMNode(this), (0, v.listenForFocusKeys)((0, m.default)(this.button)), + this.props.action && this.props.action({ + focusVisible: function() { + e.setState({ + focusVisible: !0 + }), e.button.focus(); + } + }); + } + }, { + key: "componentDidUpdate", + value: function(e, t) { + this.props.focusRipple && !this.props.disableRipple && !t.focusVisible && this.state.focusVisible && this.ripple.pulsate(); + } + }, { + key: "componentWillUnmount", + value: function() { + clearTimeout(this.focusVisibleTimeout); + } + }, { + key: "render", + value: function() { + var e, t = this.props, n = (t.action, t.buttonRef), r = t.centerRipple, s = t.children, l = t.classes, u = t.className, c = t.component, d = t.disabled, f = t.disableRipple, h = (t.disableTouchRipple, + t.focusRipple, t.focusVisibleClassName), m = (t.onBlur, t.onFocus, t.onFocusVisible, + t.onKeyDown, t.onKeyUp, t.onMouseDown, t.onMouseLeave, t.onMouseUp, t.onTouchEnd, + t.onTouchMove, t.onTouchStart, t.tabIndex), y = t.TouchRippleProps, v = t.type, j = (0, + i.default)(t, [ "action", "buttonRef", "centerRipple", "children", "classes", "className", "component", "disabled", "disableRipple", "disableTouchRipple", "focusRipple", "focusVisibleClassName", "onBlur", "onFocus", "onFocusVisible", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseLeave", "onMouseUp", "onTouchEnd", "onTouchMove", "onTouchStart", "tabIndex", "TouchRippleProps", "type" ]), x = (0, + _.default)(l.root, (e = {}, (0, a.default)(e, l.disabled, d), (0, a.default)(e, l.focusVisible, this.state.focusVisible), + (0, a.default)(e, h, this.state.focusVisible), e), u), O = c; + "button" === O && j.href && (O = "a"); + var w = {}; + return "button" === O ? (w.type = v || "button", w.disabled = d) : w.role = "button", + p.default.createElement(O, (0, o.default)({ + className: x, + onBlur: this.handleBlur, + onFocus: this.handleFocus, + onKeyDown: this.handleKeyDown, + onKeyUp: this.handleKeyUp, + onMouseDown: this.handleMouseDown, + onMouseLeave: this.handleMouseLeave, + onMouseUp: this.handleMouseUp, + onTouchEnd: this.handleTouchEnd, + onTouchMove: this.handleTouchMove, + onTouchStart: this.handleTouchStart, + onContextMenu: this.handleContextMenu, + ref: n, + tabIndex: d ? "-1" : m + }, w, j), s, f || d ? null : p.default.createElement(b.default, null, p.default.createElement(g.default, (0, + o.default)({ + innerRef: this.onRippleRef, + center: r + }, y)))); + } + } ], [ { + key: "getDerivedStateFromProps", + value: function(e, t) { + return void 0 === t.focusVisible ? { + focusVisible: !1, + lastDisabled: e.disabled + } : !t.prevState && e.disabled && t.focusVisible ? { + focusVisible: !1, + lastDisabled: e.disabled + } : { + lastDisabled: e.disabled + }; + } + } ]), t; + }(p.default.Component); + O.defaultProps = { + centerRipple: !1, + component: "button", + disableRipple: !1, + disableTouchRipple: !1, + focusRipple: !1, + tabIndex: "0", + type: "button" + }; + var w = (0, y.default)(x, { + name: "MuiButtonBase" + })(O); + t.default = w; + }, + "./node_modules/@material-ui/core/ButtonBase/Ripple.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), l = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), u = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), c = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), d = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), f = r(n("./node_modules/react/index.js")), p = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), h = r(n("./node_modules/@material-ui/core/node_modules/react-transition-group/Transition.js")), _ = function(e) { + function t() { + var e, n; + (0, s.default)(this, t); + for (var r = arguments.length, o = new Array(r), a = 0; a < r; a++) o[a] = arguments[a]; + return (n = (0, u.default)(this, (e = (0, c.default)(t)).call.apply(e, [ this ].concat(o)))).state = { + visible: !1, + leaving: !1 + }, n.handleEnter = function() { + n.setState({ + visible: !0 + }); + }, n.handleExit = function() { + n.setState({ + leaving: !0 + }); + }, n; + } + return (0, d.default)(t, e), (0, l.default)(t, [ { + key: "render", + value: function() { + var e, t, n = this.props, r = n.classes, s = n.className, l = n.pulsate, u = n.rippleX, c = n.rippleY, d = n.rippleSize, _ = (0, + i.default)(n, [ "classes", "className", "pulsate", "rippleX", "rippleY", "rippleSize" ]), m = this.state, y = m.visible, b = m.leaving, v = (0, + p.default)(r.ripple, (e = {}, (0, a.default)(e, r.rippleVisible, y), (0, a.default)(e, r.ripplePulsate, l), + e), s), g = { + width: d, + height: d, + top: -d / 2 + c, + left: -d / 2 + u + }, j = (0, p.default)(r.child, (t = {}, (0, a.default)(t, r.childLeaving, b), (0, + a.default)(t, r.childPulsate, l), t)); + return f.default.createElement(h.default, (0, o.default)({ + onEnter: this.handleEnter, + onExit: this.handleExit + }, _), f.default.createElement("span", { + className: v, + style: g + }, f.default.createElement("span", { + className: j + }))); + } + } ]), t; + }(f.default.Component); + _.defaultProps = { + pulsate: !1 + }; + var m = _; + t.default = m; + }, + "./node_modules/@material-ui/core/ButtonBase/TouchRipple.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = t.DELAY_RIPPLE = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/@babel/runtime/helpers/toConsumableArray.js")), s = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), l = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), u = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), c = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), d = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), f = r(n("./node_modules/@babel/runtime/helpers/assertThisInitialized.js")), p = r(n("./node_modules/react/index.js")), h = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/react-dom/index.js"))), _ = r(n("./node_modules/@material-ui/core/node_modules/react-transition-group/TransitionGroup.js")), m = r(n("./node_modules/classnames/index.js")), y = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), b = r(n("./node_modules/@material-ui/core/ButtonBase/Ripple.js")), v = 550, g = 80; + t.DELAY_RIPPLE = g; + var j = function(e) { + return { + root: { + display: "block", + position: "absolute", + overflow: "hidden", + borderRadius: "inherit", + width: "100%", + height: "100%", + left: 0, + top: 0, + pointerEvents: "none", + zIndex: 0 + }, + ripple: { + width: 50, + height: 50, + left: 0, + top: 0, + opacity: 0, + position: "absolute" + }, + rippleVisible: { + opacity: .3, + transform: "scale(1)", + animation: "mui-ripple-enter ".concat(v, "ms ").concat(e.transitions.easing.easeInOut), + animationName: "$mui-ripple-enter" + }, + ripplePulsate: { + animationDuration: "".concat(e.transitions.duration.shorter, "ms") + }, + child: { + opacity: 1, + display: "block", + width: "100%", + height: "100%", + borderRadius: "50%", + backgroundColor: "currentColor" + }, + childLeaving: { + opacity: 0, + animation: "mui-ripple-exit ".concat(v, "ms ").concat(e.transitions.easing.easeInOut), + animationName: "$mui-ripple-exit" + }, + childPulsate: { + position: "absolute", + left: 0, + top: 0, + animation: "mui-ripple-pulsate 2500ms ".concat(e.transitions.easing.easeInOut, " 200ms infinite"), + animationName: "$mui-ripple-pulsate" + }, + "@keyframes mui-ripple-enter": { + "0%": { + transform: "scale(0)", + opacity: .1 + }, + "100%": { + transform: "scale(1)", + opacity: .3 + } + }, + "@keyframes mui-ripple-exit": { + "0%": { + opacity: 1 + }, + "100%": { + opacity: 0 + } + }, + "@keyframes mui-ripple-pulsate": { + "0%": { + transform: "scale(1)" + }, + "50%": { + transform: "scale(0.92)" + }, + "100%": { + transform: "scale(1)" + } + } + }; + }; + t.styles = j; + var x = function(e) { + function t() { + var e, n; + (0, s.default)(this, t); + for (var r = arguments.length, o = new Array(r), a = 0; a < r; a++) o[a] = arguments[a]; + return (n = (0, u.default)(this, (e = (0, c.default)(t)).call.apply(e, [ this ].concat(o)))).state = { + nextKey: 0, + ripples: [] + }, n.pulsate = function() { + n.start({}, { + pulsate: !0 + }); + }, n.start = function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, r = arguments.length > 2 ? arguments[2] : void 0, o = t.pulsate, a = void 0 !== o && o, i = t.center, s = void 0 === i ? n.props.center || t.pulsate : i, l = t.fakeElement, u = void 0 !== l && l; + if ("mousedown" === e.type && n.ignoringMouseDown) n.ignoringMouseDown = !1; else { + "touchstart" === e.type && (n.ignoringMouseDown = !0); + var c, d, p, _ = u ? null : h.default.findDOMNode((0, f.default)((0, f.default)(n))), m = _ ? _.getBoundingClientRect() : { + width: 0, + height: 0, + left: 0, + top: 0 + }; + if (s || 0 === e.clientX && 0 === e.clientY || !e.clientX && !e.touches) c = Math.round(m.width / 2), + d = Math.round(m.height / 2); else { + var y = e.clientX ? e.clientX : e.touches[0].clientX, b = e.clientY ? e.clientY : e.touches[0].clientY; + c = Math.round(y - m.left), d = Math.round(b - m.top); + } + if (s) (p = Math.sqrt((2 * Math.pow(m.width, 2) + Math.pow(m.height, 2)) / 3)) % 2 == 0 && (p += 1); else { + var v = 2 * Math.max(Math.abs((_ ? _.clientWidth : 0) - c), c) + 2, j = 2 * Math.max(Math.abs((_ ? _.clientHeight : 0) - d), d) + 2; + p = Math.sqrt(Math.pow(v, 2) + Math.pow(j, 2)); + } + e.touches ? (n.startTimerCommit = function() { + n.startCommit({ + pulsate: a, + rippleX: c, + rippleY: d, + rippleSize: p, + cb: r + }); + }, n.startTimer = setTimeout(function() { + n.startTimerCommit && (n.startTimerCommit(), n.startTimerCommit = null); + }, g)) : n.startCommit({ + pulsate: a, + rippleX: c, + rippleY: d, + rippleSize: p, + cb: r + }); + } + }, n.startCommit = function(e) { + var t = e.pulsate, r = e.rippleX, o = e.rippleY, a = e.rippleSize, s = e.cb; + n.setState(function(e) { + return { + nextKey: e.nextKey + 1, + ripples: [].concat((0, i.default)(e.ripples), [ p.default.createElement(b.default, { + key: e.nextKey, + classes: n.props.classes, + timeout: { + exit: v, + enter: v + }, + pulsate: t, + rippleX: r, + rippleY: o, + rippleSize: a + }) ]) + }; + }, s); + }, n.stop = function(e, t) { + clearTimeout(n.startTimer); + var r = n.state.ripples; + if ("touchend" === e.type && n.startTimerCommit) return e.persist(), n.startTimerCommit(), + n.startTimerCommit = null, void (n.startTimer = setTimeout(function() { + n.stop(e, t); + })); + n.startTimerCommit = null, r && r.length && n.setState({ + ripples: r.slice(1) + }, t); + }, n; + } + return (0, d.default)(t, e), (0, l.default)(t, [ { + key: "componentWillUnmount", + value: function() { + clearTimeout(this.startTimer); + } + }, { + key: "render", + value: function() { + var e = this.props, t = (e.center, e.classes), n = e.className, r = (0, a.default)(e, [ "center", "classes", "className" ]); + return p.default.createElement(_.default, (0, o.default)({ + component: "span", + enter: !0, + exit: !0, + className: (0, m.default)(t.root, n) + }, r), this.state.ripples); + } + } ]), t; + }(p.default.PureComponent); + x.defaultProps = { + center: !1 + }; + var O = (0, y.default)(j, { + flip: !1, + name: "MuiTouchRipple" + })(x); + t.default = O; + }, + "./node_modules/@material-ui/core/ButtonBase/createRippleHandler.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e, t, n, r) { + return function(o) { + r && r.call(e, o); + var a = !1; + return o.defaultPrevented && (a = !0), e.props.disableTouchRipple && "Blur" !== t && (a = !0), + !a && e.ripple && e.ripple[n](o), "function" == typeof e.props["on".concat(t)] && e.props["on".concat(t)](o), + !0; + }; + }; + "undefined" == typeof window && (r = function() { + return function() {}; + }); + var o = r; + t.default = o; + }, + "./node_modules/@material-ui/core/ButtonBase/focusVisible.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.detectFocusVisible = function e(t, n, r) { + var i = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : 1; + t.focusVisibleTimeout = setTimeout(function() { + var s = (0, o.default)(n), l = function(e) { + var t = e.activeElement; + for (;t && t.shadowRoot && t.shadowRoot.activeElement; ) t = t.shadowRoot.activeElement; + return t; + }(s); + a.focusKeyPressed && (l === n || n.contains(l)) ? r() : i < t.focusVisibleMaxCheckTimes && e(t, n, r, i + 1); + }, t.focusVisibleCheckTime); + }, t.listenForFocusKeys = function(e) { + e.addEventListener("keyup", s); + }; + r(n("./node_modules/warning/warning.js")); + var o = r(n("./node_modules/@material-ui/core/utils/ownerDocument.js")), a = { + focusKeyPressed: !1, + keyUpEventTimeout: -1 + }; + var i = [ 9, 13, 27, 32, 37, 38, 39, 40 ]; + var s = function(e) { + (function(e) { + return i.indexOf(e.keyCode) > -1; + })(e) && (a.focusKeyPressed = !0, clearTimeout(a.keyUpEventTimeout), a.keyUpEventTimeout = setTimeout(function() { + a.focusKeyPressed = !1; + }, 500)); + }; + }, + "./node_modules/@material-ui/core/ButtonBase/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/ButtonBase/ButtonBase.js")); + }, + "./node_modules/@material-ui/core/Grid/Grid.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/@babel/runtime/helpers/extends.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = n("./node_modules/@material-ui/core/styles/createBreakpoints.js"), d = (r(n("./node_modules/@material-ui/core/utils/requirePropFactory.js")), + [ 0, 8, 16, 24, 32, 40 ]), f = [ "auto", !0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]; + var p = function(e) { + return (0, i.default)({ + container: { + boxSizing: "border-box", + display: "flex", + flexWrap: "wrap", + width: "100%" + }, + item: { + boxSizing: "border-box", + margin: "0" + }, + zeroMinWidth: { + minWidth: 0 + }, + "direction-xs-column": { + flexDirection: "column" + }, + "direction-xs-column-reverse": { + flexDirection: "column-reverse" + }, + "direction-xs-row-reverse": { + flexDirection: "row-reverse" + }, + "wrap-xs-nowrap": { + flexWrap: "nowrap" + }, + "wrap-xs-wrap-reverse": { + flexWrap: "wrap-reverse" + }, + "align-items-xs-center": { + alignItems: "center" + }, + "align-items-xs-flex-start": { + alignItems: "flex-start" + }, + "align-items-xs-flex-end": { + alignItems: "flex-end" + }, + "align-items-xs-baseline": { + alignItems: "baseline" + }, + "align-content-xs-center": { + alignContent: "center" + }, + "align-content-xs-flex-start": { + alignContent: "flex-start" + }, + "align-content-xs-flex-end": { + alignContent: "flex-end" + }, + "align-content-xs-space-between": { + alignContent: "space-between" + }, + "align-content-xs-space-around": { + alignContent: "space-around" + }, + "justify-xs-center": { + justifyContent: "center" + }, + "justify-xs-flex-end": { + justifyContent: "flex-end" + }, + "justify-xs-space-between": { + justifyContent: "space-between" + }, + "justify-xs-space-around": { + justifyContent: "space-around" + }, + "justify-xs-space-evenly": { + justifyContent: "space-evenly" + } + }, function(e, t) { + var n = {}; + return d.forEach(function(e, r) { + 0 !== r && (n["spacing-".concat(t, "-").concat(e)] = { + margin: -e / 2, + width: "calc(100% + ".concat(e, "px)"), + "& > $item": { + padding: e / 2 + } + }); + }), n; + }(0, "xs"), c.keys.reduce(function(t, n) { + return function(e, t, n) { + var r = {}; + f.forEach(function(e) { + var t = "grid-".concat(n, "-").concat(e); + if (!0 !== e) if ("auto" !== e) { + var o = "".concat(Math.round(e / 12 * 1e8) / 1e6, "%"); + r[t] = { + flexBasis: o, + flexGrow: 0, + maxWidth: o + }; + } else r[t] = { + flexBasis: "auto", + flexGrow: 0, + maxWidth: "none" + }; else r[t] = { + flexBasis: 0, + flexGrow: 1, + maxWidth: "100%" + }; + }), "xs" === n ? (0, i.default)(e, r) : e[t.breakpoints.up(n)] = r; + }(t, e, n), t; + }, {})); + }; + function h(e) { + var t, n = e.alignContent, r = e.alignItems, u = e.classes, c = e.className, d = e.component, f = e.container, p = e.direction, _ = e.item, m = e.justify, y = e.lg, b = e.md, v = e.sm, g = e.spacing, j = e.wrap, x = e.xl, O = e.xs, w = e.zeroMinWidth, E = (0, + a.default)(e, [ "alignContent", "alignItems", "classes", "className", "component", "container", "direction", "item", "justify", "lg", "md", "sm", "spacing", "wrap", "xl", "xs", "zeroMinWidth" ]), M = (0, + l.default)((t = {}, (0, o.default)(t, u.container, f), (0, o.default)(t, u.item, _), + (0, o.default)(t, u.zeroMinWidth, w), (0, o.default)(t, u["spacing-xs-".concat(String(g))], f && 0 !== g), + (0, o.default)(t, u["direction-xs-".concat(String(p))], p !== h.defaultProps.direction), + (0, o.default)(t, u["wrap-xs-".concat(String(j))], j !== h.defaultProps.wrap), (0, + o.default)(t, u["align-items-xs-".concat(String(r))], r !== h.defaultProps.alignItems), + (0, o.default)(t, u["align-content-xs-".concat(String(n))], n !== h.defaultProps.alignContent), + (0, o.default)(t, u["justify-xs-".concat(String(m))], m !== h.defaultProps.justify), + (0, o.default)(t, u["grid-xs-".concat(String(O))], !1 !== O), (0, o.default)(t, u["grid-sm-".concat(String(v))], !1 !== v), + (0, o.default)(t, u["grid-md-".concat(String(b))], !1 !== b), (0, o.default)(t, u["grid-lg-".concat(String(y))], !1 !== y), + (0, o.default)(t, u["grid-xl-".concat(String(x))], !1 !== x), t), c); + return s.default.createElement(d, (0, i.default)({ + className: M + }, E)); + } + t.styles = p, h.defaultProps = { + alignContent: "stretch", + alignItems: "stretch", + component: "div", + container: !1, + direction: "row", + item: !1, + justify: "flex-start", + lg: !1, + md: !1, + sm: !1, + spacing: 0, + wrap: "wrap", + xl: !1, + xs: !1, + zeroMinWidth: !1 + }; + var _ = (0, u.default)(p, { + name: "MuiGrid" + })(h); + t.default = _; + }, + "./node_modules/@material-ui/core/Grid/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Grid/Grid.js")); + }, + "./node_modules/@material-ui/core/Icon/Icon.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = n("./node_modules/@material-ui/core/utils/helpers.js"), d = function(e) { + return { + root: { + userSelect: "none", + fontSize: 24, + width: "1em", + height: "1em", + overflow: "hidden", + flexShrink: 0 + }, + colorPrimary: { + color: e.palette.primary.main + }, + colorSecondary: { + color: e.palette.secondary.main + }, + colorAction: { + color: e.palette.action.active + }, + colorError: { + color: e.palette.error.main + }, + colorDisabled: { + color: e.palette.action.disabled + }, + fontSizeInherit: { + fontSize: "inherit" + }, + fontSizeSmall: { + fontSize: 20 + }, + fontSizeLarge: { + fontSize: 36 + } + }; + }; + function f(e) { + var t, n = e.children, r = e.classes, u = e.className, d = e.color, f = e.component, p = e.fontSize, h = (0, + i.default)(e, [ "children", "classes", "className", "color", "component", "fontSize" ]); + return s.default.createElement(f, (0, o.default)({ + className: (0, l.default)("material-icons", r.root, (t = {}, (0, a.default)(t, r["color".concat((0, + c.capitalize)(d))], "inherit" !== d), (0, a.default)(t, r["fontSize".concat((0, + c.capitalize)(p))], "default" !== p), t), u), + "aria-hidden": "true" + }, h), n); + } + t.styles = d, f.defaultProps = { + color: "inherit", + component: "span", + fontSize: "default" + }, f.muiName = "Icon"; + var p = (0, u.default)(d, { + name: "MuiIcon" + })(f); + t.default = p; + }, + "./node_modules/@material-ui/core/Icon/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Icon/Icon.js")); + }, + "./node_modules/@material-ui/core/IconButton/IconButton.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = n("./node_modules/@material-ui/core/styles/colorManipulator.js"), d = r(n("./node_modules/@material-ui/core/ButtonBase/index.js")), f = n("./node_modules/@material-ui/core/utils/helpers.js"), p = function(e) { + return { + root: { + textAlign: "center", + flex: "0 0 auto", + fontSize: e.typography.pxToRem(24), + padding: 12, + borderRadius: "50%", + overflow: "visible", + color: e.palette.action.active, + transition: e.transitions.create("background-color", { + duration: e.transitions.duration.shortest + }), + "&:hover": { + backgroundColor: (0, c.fade)(e.palette.action.active, e.palette.action.hoverOpacity), + "@media (hover: none)": { + backgroundColor: "transparent" + }, + "&$disabled": { + backgroundColor: "transparent" + } + }, + "&$disabled": { + color: e.palette.action.disabled + } + }, + colorInherit: { + color: "inherit" + }, + colorPrimary: { + color: e.palette.primary.main, + "&:hover": { + backgroundColor: (0, c.fade)(e.palette.primary.main, e.palette.action.hoverOpacity), + "@media (hover: none)": { + backgroundColor: "transparent" + } + } + }, + colorSecondary: { + color: e.palette.secondary.main, + "&:hover": { + backgroundColor: (0, c.fade)(e.palette.secondary.main, e.palette.action.hoverOpacity), + "@media (hover: none)": { + backgroundColor: "transparent" + } + } + }, + disabled: {}, + label: { + width: "100%", + display: "flex", + alignItems: "inherit", + justifyContent: "inherit" + } + }; + }; + function h(e) { + var t, n = e.children, r = e.classes, u = e.className, c = e.color, p = e.disabled, h = (0, + i.default)(e, [ "children", "classes", "className", "color", "disabled" ]); + return s.default.createElement(d.default, (0, o.default)({ + className: (0, l.default)(r.root, (t = {}, (0, a.default)(t, r["color".concat((0, + f.capitalize)(c))], "default" !== c), (0, a.default)(t, r.disabled, p), t), u), + centerRipple: !0, + focusRipple: !0, + disabled: p + }, h), s.default.createElement("span", { + className: r.label + }, n)); + } + t.styles = p, h.defaultProps = { + color: "default", + disabled: !1 + }; + var _ = (0, u.default)(p, { + name: "MuiIconButton" + })(h); + t.default = _; + }, + "./node_modules/@material-ui/core/IconButton/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/IconButton/IconButton.js")); + }, + "./node_modules/@material-ui/core/List/List.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = r(n("./node_modules/@material-ui/core/List/ListContext.js")), d = { + root: { + listStyle: "none", + margin: 0, + padding: 0, + position: "relative" + }, + padding: { + paddingTop: 8, + paddingBottom: 8 + }, + dense: { + paddingTop: 4, + paddingBottom: 4 + }, + subheader: { + paddingTop: 0 + } + }; + function f(e) { + var t, n = e.children, r = e.classes, u = e.className, d = e.component, f = e.dense, p = e.disablePadding, h = e.subheader, _ = (0, + i.default)(e, [ "children", "classes", "className", "component", "dense", "disablePadding", "subheader" ]); + return s.default.createElement(d, (0, o.default)({ + className: (0, l.default)(r.root, (t = {}, (0, a.default)(t, r.dense, f && !p), + (0, a.default)(t, r.padding, !p), (0, a.default)(t, r.subheader, h), t), u) + }, _), s.default.createElement(c.default.Provider, { + value: { + dense: f + } + }, h, n)); + } + t.styles = d, f.defaultProps = { + component: "ul", + dense: !1, + disablePadding: !1 + }; + var p = (0, u.default)(d, { + name: "MuiList" + })(f); + t.default = p; + }, + "./node_modules/@material-ui/core/List/ListContext.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/react/index.js")).default.createContext({}); + t.default = o; + }, + "./node_modules/@material-ui/core/List/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/List/List.js")); + }, + "./node_modules/@material-ui/core/ListItem/ListItem.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = r(n("./node_modules/@material-ui/core/ButtonBase/index.js")), d = n("./node_modules/@material-ui/core/utils/reactHelpers.js"), f = r(n("./node_modules/@material-ui/core/ListItem/MergeListContext.js")), p = function(e) { + return { + root: { + display: "flex", + justifyContent: "flex-start", + alignItems: "center", + position: "relative", + textDecoration: "none", + width: "100%", + boxSizing: "border-box", + textAlign: "left", + paddingTop: 11, + paddingBottom: 11, + "&$selected, &$selected:hover, &$selected:focus": { + backgroundColor: e.palette.action.selected + } + }, + container: { + position: "relative" + }, + focusVisible: {}, + default: {}, + dense: { + paddingTop: 8, + paddingBottom: 8 + }, + alignItemsFlexStart: { + alignItems: "flex-start" + }, + disabled: { + opacity: .5 + }, + divider: { + borderBottom: "1px solid ".concat(e.palette.divider), + backgroundClip: "padding-box" + }, + gutters: { + paddingLeft: 16, + paddingRight: 16 + }, + button: { + transition: e.transitions.create("background-color", { + duration: e.transitions.duration.shortest + }), + "&:hover": { + textDecoration: "none", + backgroundColor: e.palette.action.hover, + "@media (hover: none)": { + backgroundColor: "transparent" + } + }, + "&:focus": { + backgroundColor: e.palette.action.hover + } + }, + secondaryAction: { + paddingRight: 32 + }, + selected: {} + }; + }; + function h(e) { + var t = e.alignItems, n = e.button, r = e.children, u = e.classes, p = e.className, h = e.component, _ = e.ContainerComponent, m = e.ContainerProps, y = (m = void 0 === m ? {} : m).className, b = (0, + i.default)(m, [ "className" ]), v = e.dense, g = e.disabled, j = e.disableGutters, x = e.divider, O = e.focusVisibleClassName, w = e.selected, E = (0, + i.default)(e, [ "alignItems", "button", "children", "classes", "className", "component", "ContainerComponent", "ContainerProps", "dense", "disabled", "disableGutters", "divider", "focusVisibleClassName", "selected" ]); + return s.default.createElement(f.default, { + dense: v, + alignItems: t + }, function(e) { + var i, f = e.dense, m = s.default.Children.toArray(r), v = m.some(function(e) { + return (0, d.isMuiElement)(e, [ "ListItemAvatar" ]); + }), M = m.length && (0, d.isMuiElement)(m[m.length - 1], [ "ListItemSecondaryAction" ]), P = (0, + l.default)(u.root, u.default, (i = {}, (0, a.default)(i, u.dense, f || v), (0, a.default)(i, u.gutters, !j), + (0, a.default)(i, u.divider, x), (0, a.default)(i, u.disabled, g), (0, a.default)(i, u.button, n), + (0, a.default)(i, u.alignItemsFlexStart, "flex-start" === t), (0, a.default)(i, u.secondaryAction, M), + (0, a.default)(i, u.selected, w), i), p), k = (0, o.default)({ + className: P, + disabled: g + }, E), T = h || "li"; + return n && (k.component = h || "div", k.focusVisibleClassName = (0, l.default)(u.focusVisible, O), + T = c.default), M ? (T = k.component || h ? T : "div", "li" === _ && ("li" === T ? T = "div" : "li" === k.component && (k.component = "div")), + s.default.createElement(_, (0, o.default)({ + className: (0, l.default)(u.container, y) + }, b), s.default.createElement(T, k, m), m.pop())) : s.default.createElement(T, k, m); + }); + } + t.styles = p, h.defaultProps = { + alignItems: "center", + button: !1, + ContainerComponent: "li", + dense: !1, + disabled: !1, + disableGutters: !1, + divider: !1, + selected: !1 + }; + var _ = (0, u.default)(p, { + name: "MuiListItem" + })(h); + t.default = _; + }, + "./node_modules/@material-ui/core/ListItem/MergeListContext.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/react/index.js")), a = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/@material-ui/core/List/ListContext.js"))); + var i = function(e) { + var t = e.alignItems, n = e.children, r = e.dense; + return o.default.createElement(a.default.Consumer, null, function(e) { + var i = { + dense: r || e.dense || !1, + alignItems: t + }; + return o.default.createElement(a.default.Provider, { + value: i + }, n(i)); + }); + }; + t.default = i; + }, + "./node_modules/@material-ui/core/ListItem/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/ListItem/ListItem.js")); + }, + "./node_modules/@material-ui/core/ListItemIcon/ListItemIcon.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/react/index.js")), s = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), l = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), u = function(e) { + return { + root: { + marginRight: 16, + color: e.palette.action.active, + flexShrink: 0, + display: "inline-flex" + } + }; + }; + t.styles = u; + var c = (0, l.default)(u, { + name: "MuiListItemIcon" + })(function(e) { + var t = e.children, n = e.classes, r = e.className, l = (0, a.default)(e, [ "children", "classes", "className" ]); + return i.default.createElement("div", (0, o.default)({ + className: (0, s.default)(n.root, r) + }, l), t); + }); + t.default = c; + }, + "./node_modules/@material-ui/core/ListItemIcon/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/ListItemIcon/ListItemIcon.js")); + }, + "./node_modules/@material-ui/core/ListItemText/ListItemText.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), c = r(n("./node_modules/@material-ui/core/Typography/index.js")), d = r(n("./node_modules/@material-ui/core/List/ListContext.js")), f = function(e) { + return { + root: { + flex: "1 1 auto", + minWidth: 0, + padding: "0 16px", + "&:first-child": { + paddingLeft: 0 + } + }, + inset: { + "&:first-child": { + paddingLeft: 56 + } + }, + dense: { + fontSize: e.typography.pxToRem(13) + }, + primary: { + "&$textDense": { + fontSize: "inherit" + } + }, + secondary: { + "&$textDense": { + fontSize: "inherit" + } + }, + textDense: {} + }; + }; + function p(e) { + var t = e.children, n = e.classes, r = e.className, u = e.disableTypography, f = e.inset, p = e.primary, h = e.primaryTypographyProps, _ = e.secondary, m = e.secondaryTypographyProps, y = e.theme, b = (0, + i.default)(e, [ "children", "classes", "className", "disableTypography", "inset", "primary", "primaryTypographyProps", "secondary", "secondaryTypographyProps", "theme" ]); + return s.default.createElement(d.default.Consumer, null, function(e) { + var i, d = e.dense, v = null != p ? p : t; + null == v || v.type === c.default || u || (v = s.default.createElement(c.default, (0, + o.default)({ + variant: y.typography.useNextVariants ? "body1" : "subheading", + className: (0, l.default)(n.primary, (0, a.default)({}, n.textDense, d)), + component: "span" + }, h), v)); + var g = _; + return null == g || g.type === c.default || u || (g = s.default.createElement(c.default, (0, + o.default)({ + className: (0, l.default)(n.secondary, (0, a.default)({}, n.textDense, d)), + color: "textSecondary" + }, m), g)), s.default.createElement("div", (0, o.default)({ + className: (0, l.default)(n.root, (i = {}, (0, a.default)(i, n.dense, d), (0, a.default)(i, n.inset, f), + i), r) + }, b), v, g); + }); + } + t.styles = f, p.defaultProps = { + disableTypography: !1, + inset: !1 + }; + var h = (0, u.default)(f, { + name: "MuiListItemText", + withTheme: !0 + })(p); + t.default = h; + }, + "./node_modules/@material-ui/core/ListItemText/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/ListItemText/ListItemText.js")); + }, + "./node_modules/@material-ui/core/NoSsr/NoSsr.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), a = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), i = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), s = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), l = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), u = r(n("./node_modules/react/index.js")), c = (r(n("./node_modules/prop-types/index.js")), + n("./node_modules/@material-ui/utils/index.es.js"), function(e) { + function t() { + var e, n; + (0, o.default)(this, t); + for (var r = arguments.length, a = new Array(r), l = 0; l < r; l++) a[l] = arguments[l]; + return (n = (0, i.default)(this, (e = (0, s.default)(t)).call.apply(e, [ this ].concat(a)))).mounted = !1, + n.state = { + mounted: !1 + }, n; + } + return (0, l.default)(t, e), (0, a.default)(t, [ { + key: "componentDidMount", + value: function() { + var e = this; + this.mounted = !0, this.props.defer ? requestAnimationFrame(function() { + requestAnimationFrame(function() { + e.mounted && e.setState({ + mounted: !0 + }); + }); + }) : this.setState({ + mounted: !0 + }); + } + }, { + key: "componentWillUnmount", + value: function() { + this.mounted = !1; + } + }, { + key: "render", + value: function() { + var e = this.props, t = e.children, n = e.fallback; + return this.state.mounted ? t : n; + } + } ]), t; + }(u.default.Component)); + c.defaultProps = { + defer: !1, + fallback: null + }; + var d = c; + t.default = d; + }, + "./node_modules/@material-ui/core/NoSsr/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/NoSsr/NoSsr.js")); + }, + "./node_modules/@material-ui/core/Paper/Paper.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/@babel/runtime/helpers/extends.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (r(n("./node_modules/warning/warning.js")), + n("./node_modules/@material-ui/utils/index.es.js"), r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = function(e) { + var t = {}; + return e.shadows.forEach(function(e, n) { + t["elevation".concat(n)] = { + boxShadow: e + }; + }), (0, i.default)({ + root: { + backgroundColor: e.palette.background.paper + }, + rounded: { + borderRadius: e.shape.borderRadius + } + }, t); + }; + function d(e) { + var t = e.classes, n = e.className, r = e.component, u = e.square, c = e.elevation, d = (0, + a.default)(e, [ "classes", "className", "component", "square", "elevation" ]), f = (0, + l.default)(t.root, t["elevation".concat(c)], (0, o.default)({}, t.rounded, !u), n); + return s.default.createElement(r, (0, i.default)({ + className: f + }, d)); + } + t.styles = c, d.defaultProps = { + component: "div", + elevation: 2, + square: !1 + }; + var f = (0, u.default)(c, { + name: "MuiPaper" + })(d); + t.default = f; + }, + "./node_modules/@material-ui/core/Paper/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Paper/Paper.js")); + }, + "./node_modules/@material-ui/core/Table/Table.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), s = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), l = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), u = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), c = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), d = r(n("./node_modules/react/index.js")), f = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), p = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), h = r(n("./node_modules/@material-ui/core/Table/TableContext.js")), _ = function(e) { + return { + root: { + display: "table", + fontFamily: e.typography.fontFamily, + width: "100%", + borderCollapse: "collapse", + borderSpacing: 0 + } + }; + }; + t.styles = _; + var m = function(e) { + function t() { + var e, n; + (0, i.default)(this, t); + for (var r = arguments.length, o = new Array(r), a = 0; a < r; a++) o[a] = arguments[a]; + return (n = (0, l.default)(this, (e = (0, u.default)(t)).call.apply(e, [ this ].concat(o)))).memoizedContextValue = {}, + n; + } + return (0, c.default)(t, e), (0, s.default)(t, [ { + key: "useMemo", + value: function(e) { + for (var t = Object.keys(e), n = 0; n < t.length; n += 1) { + var r = t[n]; + if (e[r] !== this.memoizedContextValue[r]) { + this.memoizedContextValue = e; + break; + } + } + return this.memoizedContextValue; + } + }, { + key: "render", + value: function() { + var e = this.props, t = e.classes, n = e.className, r = e.component, i = e.padding, s = (0, + a.default)(e, [ "classes", "className", "component", "padding" ]); + return d.default.createElement(h.default.Provider, { + value: this.useMemo({ + padding: i + }) + }, d.default.createElement(r, (0, o.default)({ + className: (0, f.default)(t.root, n) + }, s))); + } + } ]), t; + }(d.default.Component); + m.defaultProps = { + component: "table", + padding: "default" + }; + var y = (0, p.default)(_, { + name: "MuiTable" + })(m); + t.default = y; + }, + "./node_modules/@material-ui/core/Table/TableContext.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/react/index.js")).default.createContext(); + t.default = o; + }, + "./node_modules/@material-ui/core/Table/Tablelvl2Context.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/react/index.js")).default.createContext(); + t.default = o; + }, + "./node_modules/@material-ui/core/Table/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Table/Table.js")); + }, + "./node_modules/@material-ui/core/TableBody/TableBody.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/react/index.js")), s = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), l = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), u = r(n("./node_modules/@material-ui/core/Table/Tablelvl2Context.js")), c = { + root: { + display: "table-row-group" + } + }; + t.styles = c; + var d = { + variant: "body" + }; + function f(e) { + var t = e.classes, n = e.className, r = e.component, l = (0, a.default)(e, [ "classes", "className", "component" ]); + return i.default.createElement(u.default.Provider, { + value: d + }, i.default.createElement(r, (0, o.default)({ + className: (0, s.default)(t.root, n) + }, l))); + } + f.defaultProps = { + component: "tbody" + }; + var p = (0, l.default)(c, { + name: "MuiTableBody" + })(f); + t.default = p; + }, + "./node_modules/@material-ui/core/TableBody/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/TableBody/TableBody.js")); + }, + "./node_modules/@material-ui/core/TableCell/TableCell.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = n("./node_modules/@material-ui/core/utils/helpers.js"), d = (r(n("./node_modules/@material-ui/core/utils/deprecatedPropType.js")), + n("./node_modules/@material-ui/core/styles/colorManipulator.js")), f = r(n("./node_modules/@material-ui/core/Table/TableContext.js")), p = r(n("./node_modules/@material-ui/core/Table/Tablelvl2Context.js")), h = function(e) { + return { + root: { + display: "table-cell", + verticalAlign: "inherit", + borderBottom: "1px solid\n ".concat("light" === e.palette.type ? (0, d.lighten)((0, + d.fade)(e.palette.divider, 1), .88) : (0, d.darken)((0, d.fade)(e.palette.divider, 1), .68)), + textAlign: "left", + padding: "4px 56px 4px 24px", + "&:last-child": { + paddingRight: 24 + } + }, + head: { + color: e.palette.text.secondary, + fontSize: e.typography.pxToRem(12), + fontWeight: e.typography.fontWeightMedium + }, + body: { + color: e.palette.text.primary, + fontSize: e.typography.pxToRem(13), + fontWeight: e.typography.fontWeightRegular + }, + footer: { + borderBottom: 0, + color: e.palette.text.secondary, + fontSize: e.typography.pxToRem(12) + }, + numeric: { + textAlign: "right", + flexDirection: "row-reverse" + }, + paddingDense: { + paddingRight: 24 + }, + paddingCheckbox: { + padding: "0 12px", + "&:last-child": { + paddingRight: 12 + } + }, + paddingNone: { + padding: 0, + "&:last-child": { + padding: 0 + } + }, + alignLeft: { + textAlign: "left" + }, + alignCenter: { + textAlign: "center" + }, + alignRight: { + textAlign: "right", + flexDirection: "row-reverse" + }, + alignJustify: { + textAlign: "justify" + } + }; + }; + function _(e) { + var t = e.align, n = e.children, r = e.classes, u = e.className, d = e.component, h = e.sortDirection, _ = e.numeric, m = void 0 !== _ && _, y = e.padding, b = e.scope, v = e.variant, g = (0, + i.default)(e, [ "align", "children", "classes", "className", "component", "sortDirection", "numeric", "padding", "scope", "variant" ]); + return s.default.createElement(f.default.Consumer, null, function(e) { + return s.default.createElement(p.default.Consumer, null, function(i) { + var f, p; + p = d || (i && "head" === i.variant ? "th" : "td"); + var _ = b; + !_ && i && "head" === i.variant && (_ = "col"); + var j = y || (e && e.padding ? e.padding : "default"), x = (0, l.default)(r.root, (f = {}, + (0, a.default)(f, r.head, v ? "head" === v : i && "head" === i.variant), (0, a.default)(f, r.body, v ? "body" === v : i && "body" === i.variant), + (0, a.default)(f, r.footer, v ? "footer" === v : i && "footer" === i.variant), (0, + a.default)(f, r["align".concat((0, c.capitalize)(t))], "inherit" !== t), (0, a.default)(f, r.numeric, m), + (0, a.default)(f, r["padding".concat((0, c.capitalize)(j))], "default" !== j), f), u), O = null; + return h && (O = "asc" === h ? "ascending" : "descending"), s.default.createElement(p, (0, + o.default)({ + className: x, + "aria-sort": O, + scope: _ + }, g), n); + }); + }); + } + t.styles = h, _.defaultProps = { + align: "inherit" + }; + var m = (0, u.default)(h, { + name: "MuiTableCell" + })(_); + t.default = m; + }, + "./node_modules/@material-ui/core/TableCell/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/TableCell/TableCell.js")); + }, + "./node_modules/@material-ui/core/TableHead/TableHead.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/react/index.js")), s = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), l = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), u = r(n("./node_modules/@material-ui/core/Table/Tablelvl2Context.js")), c = { + root: { + display: "table-header-group" + } + }; + t.styles = c; + var d = { + variant: "head" + }; + function f(e) { + var t = e.classes, n = e.className, r = e.component, l = (0, a.default)(e, [ "classes", "className", "component" ]); + return i.default.createElement(u.default.Provider, { + value: d + }, i.default.createElement(r, (0, o.default)({ + className: (0, s.default)(t.root, n) + }, l))); + } + f.defaultProps = { + component: "thead" + }; + var p = (0, l.default)(c, { + name: "MuiTableHead" + })(f); + t.default = p; + }, + "./node_modules/@material-ui/core/TableHead/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/TableHead/TableHead.js")); + }, + "./node_modules/@material-ui/core/TableRow/TableRow.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = r(n("./node_modules/@material-ui/core/Table/Tablelvl2Context.js")), d = function(e) { + return { + root: { + color: "inherit", + display: "table-row", + height: 48, + verticalAlign: "middle", + outline: "none", + "&$selected": { + backgroundColor: "light" === e.palette.type ? "rgba(0, 0, 0, 0.04)" : "rgba(255, 255, 255, 0.08)" + }, + "&$hover:hover": { + backgroundColor: "light" === e.palette.type ? "rgba(0, 0, 0, 0.07)" : "rgba(255, 255, 255, 0.14)" + } + }, + selected: {}, + hover: {}, + head: { + height: 56 + }, + footer: { + height: 56 + } + }; + }; + function f(e) { + var t = e.classes, n = e.className, r = e.component, u = e.hover, d = e.selected, f = (0, + i.default)(e, [ "classes", "className", "component", "hover", "selected" ]); + return s.default.createElement(c.default.Consumer, null, function(e) { + var i, c = (0, l.default)(t.root, (i = {}, (0, a.default)(i, t.head, e && "head" === e.variant), + (0, a.default)(i, t.footer, e && "footer" === e.variant), (0, a.default)(i, t.hover, u), + (0, a.default)(i, t.selected, d), i), n); + return s.default.createElement(r, (0, o.default)({ + className: c + }, f)); + }); + } + t.styles = d, f.defaultProps = { + component: "tr", + hover: !1, + selected: !1 + }; + var p = (0, u.default)(d, { + name: "MuiTableRow" + })(f); + t.default = p; + }, + "./node_modules/@material-ui/core/TableRow/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/TableRow/TableRow.js")); + }, + "./node_modules/@material-ui/core/Toolbar/Toolbar.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = r(n("./node_modules/@material-ui/core/styles/withStyles.js")), c = function(e) { + return { + root: { + position: "relative", + display: "flex", + alignItems: "center" + }, + gutters: e.mixins.gutters(), + regular: e.mixins.toolbar, + dense: { + minHeight: 48 + } + }; + }; + function d(e) { + var t = e.children, n = e.classes, r = e.className, u = e.disableGutters, c = e.variant, d = (0, + i.default)(e, [ "children", "classes", "className", "disableGutters", "variant" ]), f = (0, + l.default)(n.root, n[c], (0, a.default)({}, n.gutters, !u), r); + return s.default.createElement("div", (0, o.default)({ + className: f + }, d), t); + } + t.styles = c, d.defaultProps = { + disableGutters: !1, + variant: "regular" + }; + var f = (0, u.default)(c, { + name: "MuiToolbar" + })(d); + t.default = f; + }, + "./node_modules/@material-ui/core/Toolbar/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Toolbar/Toolbar.js")); + }, + "./node_modules/@material-ui/core/Typography/Typography.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.styles = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), i = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), s = r(n("./node_modules/react/index.js")), l = (r(n("./node_modules/prop-types/index.js")), + r(n("./node_modules/classnames/index.js"))), u = (n("./node_modules/@material-ui/utils/index.es.js"), + r(n("./node_modules/@material-ui/core/styles/withStyles.js"))), c = n("./node_modules/@material-ui/core/utils/helpers.js"), d = function(e) { + return { + root: { + display: "block", + margin: 0 + }, + display4: e.typography.display4, + display3: e.typography.display3, + display2: e.typography.display2, + display1: e.typography.display1, + headline: e.typography.headline, + title: e.typography.title, + subheading: e.typography.subheading, + body2: e.typography.body2, + body1: e.typography.body1, + caption: e.typography.caption, + button: e.typography.button, + h1: e.typography.h1, + h2: e.typography.h2, + h3: e.typography.h3, + h4: e.typography.h4, + h5: e.typography.h5, + h6: e.typography.h6, + subtitle1: e.typography.subtitle1, + subtitle2: e.typography.subtitle2, + overline: e.typography.overline, + srOnly: { + position: "absolute", + height: 1, + width: 1, + overflow: "hidden" + }, + alignLeft: { + textAlign: "left" + }, + alignCenter: { + textAlign: "center" + }, + alignRight: { + textAlign: "right" + }, + alignJustify: { + textAlign: "justify" + }, + noWrap: { + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap" + }, + gutterBottom: { + marginBottom: "0.35em" + }, + paragraph: { + marginBottom: 16 + }, + colorInherit: { + color: "inherit" + }, + colorPrimary: { + color: e.palette.primary.main + }, + colorSecondary: { + color: e.palette.secondary.main + }, + colorTextPrimary: { + color: e.palette.text.primary + }, + colorTextSecondary: { + color: e.palette.text.secondary + }, + colorError: { + color: e.palette.error.main + }, + inline: { + display: "inline" + } + }; + }; + t.styles = d; + var f = { + display4: "h1", + display3: "h2", + display2: "h3", + display1: "h4", + headline: "h5", + title: "h6", + subheading: "subtitle1" + }; + var p = { + h1: "h1", + h2: "h2", + h3: "h3", + h4: "h4", + h5: "h5", + h6: "h6", + subtitle1: "h6", + subtitle2: "h6", + body1: "p", + body2: "p", + display4: "h1", + display3: "h1", + display2: "h1", + display1: "h1", + headline: "h1", + title: "h2", + subheading: "h3" + }; + function h(e) { + var t, n = e.align, r = e.classes, u = e.className, d = e.color, h = e.component, _ = e.gutterBottom, m = e.headlineMapping, y = e.inline, b = (e.internalDeprecatedVariant, + e.noWrap), v = e.paragraph, g = e.theme, j = e.variant, x = (0, i.default)(e, [ "align", "classes", "className", "color", "component", "gutterBottom", "headlineMapping", "inline", "internalDeprecatedVariant", "noWrap", "paragraph", "theme", "variant" ]), O = function(e, t) { + var n = e.typography, r = t; + return r || (r = n.useNextVariants ? "body2" : "body1"), n.useNextVariants && (r = f[r] || r), + r; + }(g, j), w = (0, l.default)(r.root, (t = {}, (0, a.default)(t, r[O], "inherit" !== O), + (0, a.default)(t, r["color".concat((0, c.capitalize)(d))], "default" !== d), (0, + a.default)(t, r.noWrap, b), (0, a.default)(t, r.gutterBottom, _), (0, a.default)(t, r.paragraph, v), + (0, a.default)(t, r["align".concat((0, c.capitalize)(n))], "inherit" !== n), (0, + a.default)(t, r.inline, y), t), u), E = h || (v ? "p" : m[O] || p[O]) || "span"; + return s.default.createElement(E, (0, o.default)({ + className: w + }, x)); + } + h.defaultProps = { + align: "inherit", + color: "default", + gutterBottom: !1, + headlineMapping: p, + inline: !1, + noWrap: !1, + paragraph: !1 + }; + var _ = (0, u.default)(d, { + name: "MuiTypography", + withTheme: !0 + })(h); + t.default = _; + }, + "./node_modules/@material-ui/core/Typography/index.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), Object.defineProperty(t, "default", { + enumerable: !0, + get: function() { + return o.default; + } + }); + var o = r(n("./node_modules/@material-ui/core/Typography/Typography.js")); + }, + "./node_modules/@material-ui/core/colors/common.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + black: "#000", + white: "#fff" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/colors/grey.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + 50: "#fafafa", + 100: "#f5f5f5", + 200: "#eeeeee", + 300: "#e0e0e0", + 400: "#bdbdbd", + 500: "#9e9e9e", + 600: "#757575", + 700: "#616161", + 800: "#424242", + 900: "#212121", + A100: "#d5d5d5", + A200: "#aaaaaa", + A400: "#303030", + A700: "#616161" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/colors/indigo.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + 50: "#e8eaf6", + 100: "#c5cae9", + 200: "#9fa8da", + 300: "#7986cb", + 400: "#5c6bc0", + 500: "#3f51b5", + 600: "#3949ab", + 700: "#303f9f", + 800: "#283593", + 900: "#1a237e", + A100: "#8c9eff", + A200: "#536dfe", + A400: "#3d5afe", + A700: "#304ffe" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/colors/pink.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + 50: "#fce4ec", + 100: "#f8bbd0", + 200: "#f48fb1", + 300: "#f06292", + 400: "#ec407a", + 500: "#e91e63", + 600: "#d81b60", + 700: "#c2185b", + 800: "#ad1457", + 900: "#880e4f", + A100: "#ff80ab", + A200: "#ff4081", + A400: "#f50057", + A700: "#c51162" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/colors/red.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + 50: "#ffebee", + 100: "#ffcdd2", + 200: "#ef9a9a", + 300: "#e57373", + 400: "#ef5350", + 500: "#f44336", + 600: "#e53935", + 700: "#d32f2f", + 800: "#c62828", + 900: "#b71c1c", + A100: "#ff8a80", + A200: "#ff5252", + A400: "#ff1744", + A700: "#d50000" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/node_modules/react-transition-group/Transition.js": function(e, t, n) { + "use strict"; + t.__esModule = !0, t.default = t.EXITING = t.ENTERED = t.ENTERING = t.EXITED = t.UNMOUNTED = void 0; + var r = function(e) { + if (e && e.__esModule) return e; + var t = {}; + if (null != e) for (var n in e) if (Object.prototype.hasOwnProperty.call(e, n)) { + var r = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(e, n) : {}; + r.get || r.set ? Object.defineProperty(t, n, r) : t[n] = e[n]; + } + return t.default = e, t; + }(n("./node_modules/prop-types/index.js")), o = s(n("./node_modules/react/index.js")), a = s(n("./node_modules/react-dom/index.js")), i = n("./node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js"); + n("./node_modules/@material-ui/core/node_modules/react-transition-group/utils/PropTypes.js"); + function s(e) { + return e && e.__esModule ? e : { + default: e + }; + } + var l = "unmounted"; + t.UNMOUNTED = l; + var u = "exited"; + t.EXITED = u; + var c = "entering"; + t.ENTERING = c; + var d = "entered"; + t.ENTERED = d; + t.EXITING = "exiting"; + var f = function(e) { + var t, n; + function r(t, n) { + var r; + r = e.call(this, t, n) || this; + var o, a = n.transitionGroup, i = a && !a.isMounting ? t.enter : t.appear; + return r.appearStatus = null, t.in ? i ? (o = u, r.appearStatus = c) : o = d : o = t.unmountOnExit || t.mountOnEnter ? l : u, + r.state = { + status: o + }, r.nextCallback = null, r; + } + n = e, (t = r).prototype = Object.create(n.prototype), t.prototype.constructor = t, + t.__proto__ = n; + var i = r.prototype; + return i.getChildContext = function() { + return { + transitionGroup: null + }; + }, r.getDerivedStateFromProps = function(e, t) { + return e.in && t.status === l ? { + status: u + } : null; + }, i.componentDidMount = function() { + this.updateStatus(!0, this.appearStatus); + }, i.componentDidUpdate = function(e) { + var t = null; + if (e !== this.props) { + var n = this.state.status; + this.props.in ? n !== c && n !== d && (t = c) : n !== c && n !== d || (t = "exiting"); + } + this.updateStatus(!1, t); + }, i.componentWillUnmount = function() { + this.cancelNextCallback(); + }, i.getTimeouts = function() { + var e, t, n, r = this.props.timeout; + return e = t = n = r, null != r && "number" != typeof r && (e = r.exit, t = r.enter, + n = void 0 !== r.appear ? r.appear : t), { + exit: e, + enter: t, + appear: n + }; + }, i.updateStatus = function(e, t) { + if (void 0 === e && (e = !1), null !== t) { + this.cancelNextCallback(); + var n = a.default.findDOMNode(this); + t === c ? this.performEnter(n, e) : this.performExit(n); + } else this.props.unmountOnExit && this.state.status === u && this.setState({ + status: l + }); + }, i.performEnter = function(e, t) { + var n = this, r = this.props.enter, o = this.context.transitionGroup ? this.context.transitionGroup.isMounting : t, a = this.getTimeouts(), i = o ? a.appear : a.enter; + t || r ? (this.props.onEnter(e, o), this.safeSetState({ + status: c + }, function() { + n.props.onEntering(e, o), n.onTransitionEnd(e, i, function() { + n.safeSetState({ + status: d + }, function() { + n.props.onEntered(e, o); + }); + }); + })) : this.safeSetState({ + status: d + }, function() { + n.props.onEntered(e); + }); + }, i.performExit = function(e) { + var t = this, n = this.props.exit, r = this.getTimeouts(); + n ? (this.props.onExit(e), this.safeSetState({ + status: "exiting" + }, function() { + t.props.onExiting(e), t.onTransitionEnd(e, r.exit, function() { + t.safeSetState({ + status: u + }, function() { + t.props.onExited(e); + }); + }); + })) : this.safeSetState({ + status: u + }, function() { + t.props.onExited(e); + }); + }, i.cancelNextCallback = function() { + null !== this.nextCallback && (this.nextCallback.cancel(), this.nextCallback = null); + }, i.safeSetState = function(e, t) { + t = this.setNextCallback(t), this.setState(e, t); + }, i.setNextCallback = function(e) { + var t = this, n = !0; + return this.nextCallback = function(r) { + n && (n = !1, t.nextCallback = null, e(r)); + }, this.nextCallback.cancel = function() { + n = !1; + }, this.nextCallback; + }, i.onTransitionEnd = function(e, t, n) { + this.setNextCallback(n); + var r = null == t && !this.props.addEndListener; + e && !r ? (this.props.addEndListener && this.props.addEndListener(e, this.nextCallback), + null != t && setTimeout(this.nextCallback, t)) : setTimeout(this.nextCallback, 0); + }, i.render = function() { + var e = this.state.status; + if (e === l) return null; + var t = this.props, n = t.children, r = function(e, t) { + if (null == e) return {}; + var n, r, o = {}, a = Object.keys(e); + for (r = 0; r < a.length; r++) n = a[r], t.indexOf(n) >= 0 || (o[n] = e[n]); + return o; + }(t, [ "children" ]); + if (delete r.in, delete r.mountOnEnter, delete r.unmountOnExit, delete r.appear, + delete r.enter, delete r.exit, delete r.timeout, delete r.addEndListener, delete r.onEnter, + delete r.onEntering, delete r.onEntered, delete r.onExit, delete r.onExiting, delete r.onExited, + "function" == typeof n) return n(e, r); + var a = o.default.Children.only(n); + return o.default.cloneElement(a, r); + }, r; + }(o.default.Component); + function p() {} + f.contextTypes = { + transitionGroup: r.object + }, f.childContextTypes = { + transitionGroup: function() {} + }, f.propTypes = {}, f.defaultProps = { + in: !1, + mountOnEnter: !1, + unmountOnExit: !1, + appear: !1, + enter: !0, + exit: !0, + onEnter: p, + onEntering: p, + onEntered: p, + onExit: p, + onExiting: p, + onExited: p + }, f.UNMOUNTED = 0, f.EXITED = 1, f.ENTERING = 2, f.ENTERED = 3, f.EXITING = 4; + var h = (0, i.polyfill)(f); + t.default = h; + }, + "./node_modules/@material-ui/core/node_modules/react-transition-group/TransitionGroup.js": function(e, t, n) { + "use strict"; + t.__esModule = !0, t.default = void 0; + var r = s(n("./node_modules/prop-types/index.js")), o = s(n("./node_modules/react/index.js")), a = n("./node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js"), i = n("./node_modules/@material-ui/core/node_modules/react-transition-group/utils/ChildMapping.js"); + function s(e) { + return e && e.__esModule ? e : { + default: e + }; + } + function l() { + return (l = Object.assign || function(e) { + for (var t = 1; t < arguments.length; t++) { + var n = arguments[t]; + for (var r in n) Object.prototype.hasOwnProperty.call(n, r) && (e[r] = n[r]); + } + return e; + }).apply(this, arguments); + } + function u(e) { + if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return e; + } + var c = Object.values || function(e) { + return Object.keys(e).map(function(t) { + return e[t]; + }); + }, d = function(e) { + var t, n; + function r(t, n) { + var r, o = (r = e.call(this, t, n) || this).handleExited.bind(u(u(r))); + return r.state = { + handleExited: o, + firstRender: !0 + }, r; + } + n = e, (t = r).prototype = Object.create(n.prototype), t.prototype.constructor = t, + t.__proto__ = n; + var a = r.prototype; + return a.getChildContext = function() { + return { + transitionGroup: { + isMounting: !this.appeared + } + }; + }, a.componentDidMount = function() { + this.appeared = !0, this.mounted = !0; + }, a.componentWillUnmount = function() { + this.mounted = !1; + }, r.getDerivedStateFromProps = function(e, t) { + var n = t.children, r = t.handleExited; + return { + children: t.firstRender ? (0, i.getInitialChildMapping)(e, r) : (0, i.getNextChildMapping)(e, n, r), + firstRender: !1 + }; + }, a.handleExited = function(e, t) { + var n = (0, i.getChildMapping)(this.props.children); + e.key in n || (e.props.onExited && e.props.onExited(t), this.mounted && this.setState(function(t) { + var n = l({}, t.children); + return delete n[e.key], { + children: n + }; + })); + }, a.render = function() { + var e = this.props, t = e.component, n = e.childFactory, r = function(e, t) { + if (null == e) return {}; + var n, r, o = {}, a = Object.keys(e); + for (r = 0; r < a.length; r++) n = a[r], t.indexOf(n) >= 0 || (o[n] = e[n]); + return o; + }(e, [ "component", "childFactory" ]), a = c(this.state.children).map(n); + return delete r.appear, delete r.enter, delete r.exit, null === t ? a : o.default.createElement(t, r, a); + }, r; + }(o.default.Component); + d.childContextTypes = { + transitionGroup: r.default.object.isRequired + }, d.propTypes = {}, d.defaultProps = { + component: "div", + childFactory: function(e) { + return e; + } + }; + var f = (0, a.polyfill)(d); + t.default = f, e.exports = t.default; + }, + "./node_modules/@material-ui/core/node_modules/react-transition-group/utils/ChildMapping.js": function(e, t, n) { + "use strict"; + t.__esModule = !0, t.getChildMapping = o, t.mergeChildMappings = a, t.getInitialChildMapping = function(e, t) { + return o(e.children, function(n) { + return (0, r.cloneElement)(n, { + onExited: t.bind(null, n), + in: !0, + appear: i(n, "appear", e), + enter: i(n, "enter", e), + exit: i(n, "exit", e) + }); + }); + }, t.getNextChildMapping = function(e, t, n) { + var s = o(e.children), l = a(t, s); + return Object.keys(l).forEach(function(o) { + var a = l[o]; + if ((0, r.isValidElement)(a)) { + var u = o in t, c = o in s, d = t[o], f = (0, r.isValidElement)(d) && !d.props.in; + !c || u && !f ? c || !u || f ? c && u && (0, r.isValidElement)(d) && (l[o] = (0, + r.cloneElement)(a, { + onExited: n.bind(null, a), + in: d.props.in, + exit: i(a, "exit", e), + enter: i(a, "enter", e) + })) : l[o] = (0, r.cloneElement)(a, { + in: !1 + }) : l[o] = (0, r.cloneElement)(a, { + onExited: n.bind(null, a), + in: !0, + exit: i(a, "exit", e), + enter: i(a, "enter", e) + }); + } + }), l; + }; + var r = n("./node_modules/react/index.js"); + function o(e, t) { + var n = Object.create(null); + return e && r.Children.map(e, function(e) { + return e; + }).forEach(function(e) { + n[e.key] = function(e) { + return t && (0, r.isValidElement)(e) ? t(e) : e; + }(e); + }), n; + } + function a(e, t) { + function n(n) { + return n in t ? t[n] : e[n]; + } + e = e || {}, t = t || {}; + var r, o = Object.create(null), a = []; + for (var i in e) i in t ? a.length && (o[i] = a, a = []) : a.push(i); + var s = {}; + for (var l in t) { + if (o[l]) for (r = 0; r < o[l].length; r++) { + var u = o[l][r]; + s[o[l][r]] = n(u); + } + s[l] = n(l); + } + for (r = 0; r < a.length; r++) s[a[r]] = n(a[r]); + return s; + } + function i(e, t, n) { + return null != n[t] ? n[t] : e.props[t]; + } + }, + "./node_modules/@material-ui/core/node_modules/react-transition-group/utils/PropTypes.js": function(e, t, n) { + "use strict"; + t.__esModule = !0, t.classNamesShape = t.timeoutsShape = void 0; + var r; + (r = n("./node_modules/prop-types/index.js")) && r.__esModule; + t.timeoutsShape = null; + t.classNamesShape = null; + }, + "./node_modules/@material-ui/core/styles/MuiThemeProvider.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireWildcard.js"), o = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.MuiThemeProviderOld = void 0; + var a = o(n("./node_modules/@babel/runtime/helpers/extends.js")), i = o(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), s = o(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), l = o(n("./node_modules/@babel/runtime/helpers/createClass.js")), u = o(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), c = o(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), d = o(n("./node_modules/@babel/runtime/helpers/inherits.js")), f = o(n("./node_modules/react/index.js")), p = o(n("./node_modules/prop-types/index.js")), h = (o(n("./node_modules/warning/warning.js")), + o(n("./node_modules/brcast/dist/brcast.es.js"))), _ = n("./node_modules/@material-ui/utils/index.es.js"), m = r(n("./node_modules/@material-ui/core/styles/themeListener.js")), y = function(e) { + function t(e, n) { + var r; + return (0, s.default)(this, t), (r = (0, u.default)(this, (0, c.default)(t).call(this))).broadcast = (0, + h.default)(), r.outerTheme = m.default.initial(n), r.broadcast.setState(r.mergeOuterLocalTheme(e.theme)), + r; + } + return (0, d.default)(t, e), (0, l.default)(t, [ { + key: "getChildContext", + value: function() { + var e, t = this.props, n = t.disableStylesGeneration, r = t.sheetsCache, o = t.sheetsManager, a = this.context.muiThemeProviderOptions || {}; + return void 0 !== n && (a.disableStylesGeneration = n), void 0 !== r && (a.sheetsCache = r), + void 0 !== o && (a.sheetsManager = o), e = {}, (0, i.default)(e, m.CHANNEL, this.broadcast), + (0, i.default)(e, "muiThemeProviderOptions", a), e; + } + }, { + key: "componentDidMount", + value: function() { + var e = this; + this.unsubscribeId = m.default.subscribe(this.context, function(t) { + e.outerTheme = t, e.broadcast.setState(e.mergeOuterLocalTheme(e.props.theme)); + }); + } + }, { + key: "componentDidUpdate", + value: function(e) { + this.props.theme !== e.theme && this.broadcast.setState(this.mergeOuterLocalTheme(this.props.theme)); + } + }, { + key: "componentWillUnmount", + value: function() { + null !== this.unsubscribeId && m.default.unsubscribe(this.context, this.unsubscribeId); + } + }, { + key: "mergeOuterLocalTheme", + value: function(e) { + return "function" == typeof e ? e(this.outerTheme) : this.outerTheme ? (0, a.default)({}, this.outerTheme, e) : e; + } + }, { + key: "render", + value: function() { + return this.props.children; + } + } ]), t; + }(f.default.Component); + t.MuiThemeProviderOld = y, y.childContextTypes = (0, a.default)({}, m.default.contextTypes, { + muiThemeProviderOptions: p.default.object + }), y.contextTypes = (0, a.default)({}, m.default.contextTypes, { + muiThemeProviderOptions: p.default.object + }), _.ponyfillGlobal.__MUI_STYLES__ || (_.ponyfillGlobal.__MUI_STYLES__ = {}), _.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider || (_.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider = y); + var b = _.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider; + t.default = b; + }, + "./node_modules/@material-ui/core/styles/colorManipulator.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.convertHexToRGB = a, t.rgbToHex = function(e) { + if (0 === e.indexOf("#")) return e; + var t = i(e).values; + return t = t.map(function(e) { + return 1 === (t = e.toString(16)).length ? "0".concat(t) : t; + var t; + }), "#".concat(t.join("")); + }, t.decomposeColor = i, t.recomposeColor = s, t.getContrastRatio = function(e, t) { + var n = l(e), r = l(t); + return (Math.max(n, r) + .05) / (Math.min(n, r) + .05); + }, t.getLuminance = l, t.emphasize = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : .15; + return l(e) > .5 ? u(e, t) : c(e, t); + }, t.fade = function(e, t) { + if (!e) return e; + e = i(e), t = o(t), ("rgb" === e.type || "hsl" === e.type) && (e.type += "a"); + return e.values[3] = t, s(e); + }, t.darken = u, t.lighten = c; + r(n("./node_modules/warning/warning.js")); + function o(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 1; + return e < t ? t : e > n ? n : e; + } + function a(e) { + e = e.substr(1); + var t = new RegExp(".{1,".concat(e.length / 3, "}"), "g"), n = e.match(t); + return n && 1 === n[0].length && (n = n.map(function(e) { + return e + e; + })), n ? "rgb(".concat(n.map(function(e) { + return parseInt(e, 16); + }).join(", "), ")") : ""; + } + function i(e) { + if ("#" === e.charAt(0)) return i(a(e)); + var t = e.indexOf("("), n = e.substring(0, t), r = e.substring(t + 1, e.length - 1).split(","); + return { + type: n, + values: r = r.map(function(e) { + return parseFloat(e); + }) + }; + } + function s(e) { + var t = e.type, n = e.values; + return -1 !== t.indexOf("rgb") && (n = n.map(function(e, t) { + return t < 3 ? parseInt(e, 10) : e; + })), -1 !== t.indexOf("hsl") && (n[1] = "".concat(n[1], "%"), n[2] = "".concat(n[2], "%")), + "".concat(e.type, "(").concat(n.join(", "), ")"); + } + function l(e) { + var t = i(e); + if (-1 !== t.type.indexOf("rgb")) { + var n = t.values.map(function(e) { + return (e /= 255) <= .03928 ? e / 12.92 : Math.pow((e + .055) / 1.055, 2.4); + }); + return Number((.2126 * n[0] + .7152 * n[1] + .0722 * n[2]).toFixed(3)); + } + return t.values[2] / 100; + } + function u(e, t) { + if (!e) return e; + if (e = i(e), t = o(t), -1 !== e.type.indexOf("hsl")) e.values[2] *= 1 - t; else if (-1 !== e.type.indexOf("rgb")) for (var n = 0; n < 3; n += 1) e.values[n] *= 1 - t; + return s(e); + } + function c(e, t) { + if (!e) return e; + if (e = i(e), t = o(t), -1 !== e.type.indexOf("hsl")) e.values[2] += (100 - e.values[2]) * t; else if (-1 !== e.type.indexOf("rgb")) for (var n = 0; n < 3; n += 1) e.values[n] += (255 - e.values[n]) * t; + return s(e); + } + }, + "./node_modules/@material-ui/core/styles/createBreakpoints.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = function(e) { + var t = e.values, n = void 0 === t ? { + xs: 0, + sm: 600, + md: 960, + lg: 1280, + xl: 1920 + } : t, r = e.unit, s = void 0 === r ? "px" : r, l = e.step, u = void 0 === l ? 5 : l, c = (0, + a.default)(e, [ "values", "unit", "step" ]); + function d(e) { + var t = "number" == typeof n[e] ? n[e] : e; + return "@media (min-width:".concat(t).concat(s, ")"); + } + function f(e, t) { + var r = i.indexOf(t) + 1; + return r === i.length ? d(e) : "@media (min-width:".concat(n[e]).concat(s, ") and ") + "(max-width:".concat(n[i[r]] - u / 100).concat(s, ")"); + } + return (0, o.default)({ + keys: i, + values: n, + up: d, + down: function(e) { + var t = i.indexOf(e) + 1, r = n[i[t]]; + if (t === i.length) return d("xs"); + return "@media (max-width:".concat(("number" == typeof r && t > 0 ? r : e) - u / 100).concat(s, ")"); + }, + between: f, + only: function(e) { + return f(e, e); + }, + width: function(e) { + return n[e]; + } + }, c); + }, t.keys = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = [ "xs", "sm", "md", "lg", "xl" ]; + t.keys = i; + }, + "./node_modules/@material-ui/core/styles/createGenerateClassName.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, t = e.dangerouslyUseGlobalCSS, n = void 0 !== t && t, r = e.productionPrefix, o = void 0 === r ? "jss" : r, i = e.seed, s = void 0 === i ? "" : i, l = 0; + return function(e, t) { + return l += 1, n && t && t.options.name ? "".concat(a(t.options.name), "-").concat(e.key) : "".concat(o).concat(s).concat(l); + }; + }; + r(n("./node_modules/warning/warning.js")); + var o = /([[\].#*$><+~=|^:(),"'` + "`") + (`\s])/g; + function a(e) { + return String(e).replace(o, "-"); + } + }, + "./node_modules/@material-ui/core/styles/createMixins.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = function(e, t, n) { + var r; + return (0, a.default)({ + gutters: function() { + var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; + return (0, a.default)({ + paddingLeft: 2 * t.unit, + paddingRight: 2 * t.unit + }, n, (0, o.default)({}, e.up("sm"), (0, a.default)({ + paddingLeft: 3 * t.unit, + paddingRight: 3 * t.unit + }, n[e.up("sm")]))); + }, + toolbar: (r = { + minHeight: 56 + }, (0, o.default)(r, "".concat(e.up("xs"), " and (orientation: landscape)"), { + minHeight: 48 + }), (0, o.default)(r, e.up("sm"), { + minHeight: 64 + }), r) + }, n); + }; + var o = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), a = r(n("./node_modules/@babel/runtime/helpers/extends.js")); + }, + "./node_modules/@material-ui/core/styles/createMuiTheme.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")); + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/deepmerge/dist/umd.js")), s = r(n("./node_modules/is-plain-object/index.js")), l = (r(n("./node_modules/warning/warning.js")), + r(n("./node_modules/@material-ui/core/styles/createBreakpoints.js"))), u = r(n("./node_modules/@material-ui/core/styles/createMixins.js")), c = r(n("./node_modules/@material-ui/core/styles/createPalette.js")), d = r(n("./node_modules/@material-ui/core/styles/createTypography.js")), f = r(n("./node_modules/@material-ui/core/styles/shadows.js")), p = r(n("./node_modules/@material-ui/core/styles/shape.js")), h = r(n("./node_modules/@material-ui/core/styles/spacing.js")), _ = r(n("./node_modules/@material-ui/core/styles/transitions.js")), m = r(n("./node_modules/@material-ui/core/styles/zIndex.js")); + var y = function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, t = e.breakpoints, n = void 0 === t ? {} : t, r = e.mixins, y = void 0 === r ? {} : r, b = e.palette, v = void 0 === b ? {} : b, g = e.shadows, j = e.spacing, x = void 0 === j ? {} : j, O = e.typography, w = void 0 === O ? {} : O, E = (0, + a.default)(e, [ "breakpoints", "mixins", "palette", "shadows", "spacing", "typography" ]), M = (0, + c.default)(v), P = (0, l.default)(n), k = (0, o.default)({}, h.default, x); + return (0, o.default)({ + breakpoints: P, + direction: "ltr", + mixins: (0, u.default)(P, k, y), + overrides: {}, + palette: M, + props: {}, + shadows: g || f.default, + typography: (0, d.default)(M, w) + }, (0, i.default)({ + shape: p.default, + spacing: k, + transitions: _.default, + zIndex: m.default + }, E, { + isMergeableObject: s.default + })); + }; + t.default = y; + }, + "./node_modules/@material-ui/core/styles/createPalette.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = function(e) { + var t = e.primary, n = void 0 === t ? { + light: s.default[300], + main: s.default[500], + dark: s.default[700] + } : t, r = e.secondary, m = void 0 === r ? { + light: l.default.A200, + main: l.default.A400, + dark: l.default.A700 + } : r, y = e.error, b = void 0 === y ? { + light: c.default[300], + main: c.default[500], + dark: c.default[700] + } : y, v = e.type, g = void 0 === v ? "light" : v, j = e.contrastThreshold, x = void 0 === j ? 3 : j, O = e.tonalOffset, w = void 0 === O ? .2 : O, E = (0, + a.default)(e, [ "primary", "secondary", "error", "type", "contrastThreshold", "tonalOffset" ]); + function M(e) { + var t = (0, f.getContrastRatio)(e, h.text.primary) >= x ? h.text.primary : p.text.primary; + return t; + } + function P(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 500, n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 300, r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : 700; + return !e.main && e[t] && (e.main = e[t]), _(e, "light", n, w), _(e, "dark", r, w), + e.contrastText || (e.contrastText = M(e.main)), e; + } + P(n), P(m, "A400", "A200", "A700"), P(b); + var k = { + dark: h, + light: p + }; + return (0, i.default)((0, o.default)({ + common: d.default, + type: g, + primary: n, + secondary: m, + error: b, + grey: u.default, + contrastThreshold: x, + getContrastText: M, + augmentColor: P, + tonalOffset: w + }, k[g]), E, { + clone: !1 + }); + }, t.dark = t.light = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = (r(n("./node_modules/warning/warning.js")), + r(n("./node_modules/deepmerge/dist/umd.js"))), s = r(n("./node_modules/@material-ui/core/colors/indigo.js")), l = r(n("./node_modules/@material-ui/core/colors/pink.js")), u = r(n("./node_modules/@material-ui/core/colors/grey.js")), c = r(n("./node_modules/@material-ui/core/colors/red.js")), d = r(n("./node_modules/@material-ui/core/colors/common.js")), f = n("./node_modules/@material-ui/core/styles/colorManipulator.js"), p = { + text: { + primary: "rgba(0, 0, 0, 0.87)", + secondary: "rgba(0, 0, 0, 0.54)", + disabled: "rgba(0, 0, 0, 0.38)", + hint: "rgba(0, 0, 0, 0.38)" + }, + divider: "rgba(0, 0, 0, 0.12)", + background: { + paper: d.default.white, + default: u.default[50] + }, + action: { + active: "rgba(0, 0, 0, 0.54)", + hover: "rgba(0, 0, 0, 0.08)", + hoverOpacity: .08, + selected: "rgba(0, 0, 0, 0.14)", + disabled: "rgba(0, 0, 0, 0.26)", + disabledBackground: "rgba(0, 0, 0, 0.12)" + } + }; + t.light = p; + var h = { + text: { + primary: d.default.white, + secondary: "rgba(255, 255, 255, 0.7)", + disabled: "rgba(255, 255, 255, 0.5)", + hint: "rgba(255, 255, 255, 0.5)", + icon: "rgba(255, 255, 255, 0.5)" + }, + divider: "rgba(255, 255, 255, 0.12)", + background: { + paper: u.default[800], + default: "#303030" + }, + action: { + active: d.default.white, + hover: "rgba(255, 255, 255, 0.1)", + hoverOpacity: .1, + selected: "rgba(255, 255, 255, 0.2)", + disabled: "rgba(255, 255, 255, 0.3)", + disabledBackground: "rgba(255, 255, 255, 0.12)" + } + }; + function _(e, t, n, r) { + e[t] || (e.hasOwnProperty(n) ? e[t] = e[n] : "light" === t ? e.light = (0, f.lighten)(e.main, r) : "dark" === t && (e.dark = (0, + f.darken)(e.main, 1.5 * r))); + } + t.dark = h; + }, + "./node_modules/@material-ui/core/styles/createTypography.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = function(e, t) { + var n = "function" == typeof t ? t(e) : t, r = n.fontFamily, d = void 0 === r ? c : r, f = n.fontSize, p = void 0 === f ? 14 : f, h = n.fontWeightLight, _ = void 0 === h ? 300 : h, m = n.fontWeightRegular, y = void 0 === m ? 400 : m, b = n.fontWeightMedium, v = void 0 === b ? 500 : b, g = n.htmlFontSize, j = void 0 === g ? 16 : g, x = n.useNextVariants, O = void 0 === x ? Boolean(s.ponyfillGlobal.__MUI_USE_NEXT_TYPOGRAPHY_VARIANTS__) : x, w = (n.suppressWarning, + n.allVariants), E = (0, a.default)(n, [ "fontFamily", "fontSize", "fontWeightLight", "fontWeightRegular", "fontWeightMedium", "htmlFontSize", "useNextVariants", "suppressWarning", "allVariants" ]); + var M = p / 14, P = function(e) { + return "".concat(e / j * M, "rem"); + }, k = function(t, n, r, a, i) { + return (0, o.default)({ + color: e.text.primary, + fontFamily: d, + fontWeight: t, + fontSize: P(n), + lineHeight: r + }, d === c ? { + letterSpacing: "".concat(l(a / n), "em") + } : {}, i, w); + }, T = { + h1: k(_, 96, 1, -1.5), + h2: k(_, 60, 1, -.5), + h3: k(y, 48, 1.04, 0), + h4: k(y, 34, 1.17, .25), + h5: k(y, 24, 1.33, 0), + h6: k(v, 20, 1.6, .15), + subtitle1: k(y, 16, 1.75, .15), + subtitle2: k(v, 14, 1.57, .1), + body1Next: k(y, 16, 1.5, .15), + body2Next: k(y, 14, 1.5, .15), + buttonNext: k(v, 14, 1.75, .4, u), + captionNext: k(y, 12, 1.66, .4), + overline: k(y, 12, 2.66, 1, u) + }, C = { + display4: (0, o.default)({ + fontSize: P(112), + fontWeight: _, + fontFamily: d, + letterSpacing: "-.04em", + lineHeight: "".concat(l(128 / 112), "em"), + marginLeft: "-.04em", + color: e.text.secondary + }, w), + display3: (0, o.default)({ + fontSize: P(56), + fontWeight: y, + fontFamily: d, + letterSpacing: "-.02em", + lineHeight: "".concat(l(73 / 56), "em"), + marginLeft: "-.02em", + color: e.text.secondary + }, w), + display2: (0, o.default)({ + fontSize: P(45), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(51 / 45), "em"), + marginLeft: "-.02em", + color: e.text.secondary + }, w), + display1: (0, o.default)({ + fontSize: P(34), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(41 / 34), "em"), + color: e.text.secondary + }, w), + headline: (0, o.default)({ + fontSize: P(24), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(32.5 / 24), "em"), + color: e.text.primary + }, w), + title: (0, o.default)({ + fontSize: P(21), + fontWeight: v, + fontFamily: d, + lineHeight: "".concat(l(24.5 / 21), "em"), + color: e.text.primary + }, w), + subheading: (0, o.default)({ + fontSize: P(16), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(1.5), "em"), + color: e.text.primary + }, w), + body2: (0, o.default)({ + fontSize: P(14), + fontWeight: v, + fontFamily: d, + lineHeight: "".concat(l(24 / 14), "em"), + color: e.text.primary + }, w), + body1: (0, o.default)({ + fontSize: P(14), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(20.5 / 14), "em"), + color: e.text.primary + }, w), + caption: (0, o.default)({ + fontSize: P(12), + fontWeight: y, + fontFamily: d, + lineHeight: "".concat(l(1.375), "em"), + color: e.text.secondary + }, w), + button: (0, o.default)({ + fontSize: P(14), + textTransform: "uppercase", + fontWeight: v, + fontFamily: d, + color: e.text.primary + }, w) + }; + return (0, i.default)((0, o.default)({ + pxToRem: P, + round: l, + fontFamily: d, + fontSize: p, + fontWeightLight: _, + fontWeightRegular: y, + fontWeightMedium: v + }, C, T, O ? { + body1: T.body1Next, + body2: T.body2Next, + button: T.buttonNext, + caption: T.captionNext + } : {}, { + useNextVariants: O + }), E, { + clone: !1 + }); + }; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), i = r(n("./node_modules/deepmerge/dist/umd.js")), s = (r(n("./node_modules/warning/warning.js")), + n("./node_modules/@material-ui/utils/index.es.js")); + function l(e) { + return Math.round(1e5 * e) / 1e5; + } + var u = { + textTransform: "uppercase" + }, c = '"Roboto", "Helvetica", "Arial", sans-serif'; + }, + "./node_modules/@material-ui/core/styles/getStylesCreator.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")), a = (r(n("./node_modules/@babel/runtime/helpers/typeof.js")), + r(n("./node_modules/warning/warning.js")), r(n("./node_modules/deepmerge/dist/umd.js"))); + function i(e, t) { + return t; + } + var s = function(e) { + var t = "function" == typeof e; + return { + create: function(n, r) { + var s = t ? e(n) : e; + if (!r || !n.overrides || !n.overrides[r]) return s; + var l = n.overrides[r], u = (0, o.default)({}, s); + return Object.keys(l).forEach(function(e) { + u[e] = (0, a.default)(u[e], l[e], { + arrayMerge: i + }); + }), u; + }, + options: {}, + themingEnabled: t + }; + }; + t.default = s; + }, + "./node_modules/@material-ui/core/styles/getThemeProps.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e) { + var t = e.theme, n = e.name, r = e.props; + if (!t.props || !n || !t.props[n]) return r; + var o, a = t.props[n]; + for (o in a) void 0 === r[o] && (r[o] = a[o]); + return r; + }; + t.default = r; + }, + "./node_modules/@material-ui/core/styles/jssPreset.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/jss-global/lib/index.js")), a = r(n("./node_modules/jss-nested/lib/index.js")), i = r(n("./node_modules/jss-camel-case/lib/index.js")), s = r(n("./node_modules/jss-default-unit/lib/index.js")), l = r(n("./node_modules/jss-vendor-prefixer/lib/index.js")), u = r(n("./node_modules/jss-props-sort/lib/index.js")); + var c = function() { + return { + plugins: [ (0, o.default)(), (0, a.default)(), (0, i.default)(), (0, s.default)(), "undefined" == typeof window ? null : (0, + l.default)(), (0, u.default)() ] + }; + }; + t.default = c; + }, + "./node_modules/@material-ui/core/styles/mergeClasses.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/extends.js")); + r(n("./node_modules/warning/warning.js")), n("./node_modules/@material-ui/utils/index.es.js"); + var a = function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, t = e.baseClasses, n = e.newClasses; + if (e.Component, !n) return t; + var r = (0, o.default)({}, t); + return Object.keys(n).forEach(function(e) { + n[e] && (r[e] = "".concat(t[e], " ").concat(n[e])); + }), r; + }; + t.default = a; + }, + "./node_modules/@material-ui/core/styles/multiKeyStore.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + set: function(e, t, n, r) { + var o = e.get(t); + o || (o = new Map(), e.set(t, o)), o.set(n, r); + }, + get: function(e, t, n) { + var r = e.get(t); + return r ? r.get(n) : void 0; + }, + delete: function(e, t, n) { + e.get(t).delete(n); + } + }; + t.default = r; + }, + "./node_modules/@material-ui/core/styles/reactJssContext.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + jss: "64a55d578f856d258dc345b094a2a2b3", + sheetsRegistry: "d4bd0baacbc52bbd48bbb9eb24344ecd", + sheetOptions: "6fc570d6bd61383819d0f9e7407c452d" + }; + t.default = r; + }, + "./node_modules/@material-ui/core/styles/shadows.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = .2, o = .14, a = .12; + function i() { + return [ "".concat(arguments.length <= 0 ? void 0 : arguments[0], "px ").concat(arguments.length <= 1 ? void 0 : arguments[1], "px ").concat(arguments.length <= 2 ? void 0 : arguments[2], "px ").concat(arguments.length <= 3 ? void 0 : arguments[3], "px rgba(0,0,0,").concat(r, ")"), "".concat(arguments.length <= 4 ? void 0 : arguments[4], "px ").concat(arguments.length <= 5 ? void 0 : arguments[5], "px ").concat(arguments.length <= 6 ? void 0 : arguments[6], "px ").concat(arguments.length <= 7 ? void 0 : arguments[7], "px rgba(0,0,0,").concat(o, ")"), "".concat(arguments.length <= 8 ? void 0 : arguments[8], "px ").concat(arguments.length <= 9 ? void 0 : arguments[9], "px ").concat(arguments.length <= 10 ? void 0 : arguments[10], "px ").concat(arguments.length <= 11 ? void 0 : arguments[11], "px rgba(0,0,0,").concat(a, ")") ].join(","); + } + var s = [ "none", i(0, 1, 3, 0, 0, 1, 1, 0, 0, 2, 1, -1), i(0, 1, 5, 0, 0, 2, 2, 0, 0, 3, 1, -2), i(0, 1, 8, 0, 0, 3, 4, 0, 0, 3, 3, -2), i(0, 2, 4, -1, 0, 4, 5, 0, 0, 1, 10, 0), i(0, 3, 5, -1, 0, 5, 8, 0, 0, 1, 14, 0), i(0, 3, 5, -1, 0, 6, 10, 0, 0, 1, 18, 0), i(0, 4, 5, -2, 0, 7, 10, 1, 0, 2, 16, 1), i(0, 5, 5, -3, 0, 8, 10, 1, 0, 3, 14, 2), i(0, 5, 6, -3, 0, 9, 12, 1, 0, 3, 16, 2), i(0, 6, 6, -3, 0, 10, 14, 1, 0, 4, 18, 3), i(0, 6, 7, -4, 0, 11, 15, 1, 0, 4, 20, 3), i(0, 7, 8, -4, 0, 12, 17, 2, 0, 5, 22, 4), i(0, 7, 8, -4, 0, 13, 19, 2, 0, 5, 24, 4), i(0, 7, 9, -4, 0, 14, 21, 2, 0, 5, 26, 4), i(0, 8, 9, -5, 0, 15, 22, 2, 0, 6, 28, 5), i(0, 8, 10, -5, 0, 16, 24, 2, 0, 6, 30, 5), i(0, 8, 11, -5, 0, 17, 26, 2, 0, 6, 32, 5), i(0, 9, 11, -5, 0, 18, 28, 2, 0, 7, 34, 6), i(0, 9, 12, -6, 0, 19, 29, 2, 0, 7, 36, 6), i(0, 10, 13, -6, 0, 20, 31, 3, 0, 8, 38, 7), i(0, 10, 13, -6, 0, 21, 33, 3, 0, 8, 40, 7), i(0, 10, 14, -6, 0, 22, 35, 3, 0, 8, 42, 7), i(0, 11, 14, -7, 0, 23, 36, 3, 0, 9, 44, 8), i(0, 11, 15, -7, 0, 24, 38, 3, 0, 9, 46, 8) ]; + t.default = s; + }, + "./node_modules/@material-ui/core/styles/shape.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + borderRadius: 4 + }; + t.default = r; + }, + "./node_modules/@material-ui/core/styles/spacing.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + unit: 8 + }; + t.default = r; + }, + "./node_modules/@material-ui/core/styles/themeListener.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.CHANNEL = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), a = "__THEMING__"; + t.CHANNEL = a; + var i = { + contextTypes: (0, o.default)({}, a, function() {}), + initial: function(e) { + return e[a] ? e[a].getState() : null; + }, + subscribe: function(e, t) { + return e[a] ? e[a].subscribe(t) : null; + }, + unsubscribe: function(e, t) { + e[a] && e[a].unsubscribe(t); + } + }; + t.default = i; + }, + "./node_modules/@material-ui/core/styles/transitions.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.isNumber = t.isString = t.formatMs = t.duration = t.easing = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), a = (r(n("./node_modules/warning/warning.js")), + { + easeInOut: "cubic-bezier(0.4, 0, 0.2, 1)", + easeOut: "cubic-bezier(0.0, 0, 0.2, 1)", + easeIn: "cubic-bezier(0.4, 0, 1, 1)", + sharp: "cubic-bezier(0.4, 0, 0.6, 1)" + }); + t.easing = a; + var i = { + shortest: 150, + shorter: 200, + short: 250, + standard: 300, + complex: 375, + enteringScreen: 225, + leavingScreen: 195 + }; + t.duration = i; + var s = function(e) { + return "".concat(Math.round(e), "ms"); + }; + t.formatMs = s; + t.isString = function(e) { + return "string" == typeof e; + }; + t.isNumber = function(e) { + return !isNaN(parseFloat(e)); + }; + var l = { + easing: a, + duration: i, + create: function() { + var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [ "all" ], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.duration, r = void 0 === n ? i.standard : n, l = t.easing, u = void 0 === l ? a.easeInOut : l, c = t.delay, d = void 0 === c ? 0 : c; + (0, o.default)(t, [ "duration", "easing", "delay" ]); + return (Array.isArray(e) ? e : [ e ]).map(function(e) { + return "".concat(e, " ").concat("string" == typeof r ? r : s(r), " ").concat(u, " ").concat("string" == typeof d ? d : s(d)); + }).join(","); + }, + getAutoHeightDuration: function(e) { + if (!e) return 0; + var t = e / 36; + return Math.round(10 * (4 + 15 * Math.pow(t, .25) + t / 5)); + } + }; + t.default = l; + }, + "./node_modules/@material-ui/core/styles/withStyles.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.sheetsManager = void 0; + var o = r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), a = r(n("./node_modules/@babel/runtime/helpers/extends.js")), i = r(n("./node_modules/@babel/runtime/helpers/classCallCheck.js")), s = r(n("./node_modules/@babel/runtime/helpers/createClass.js")), l = r(n("./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js")), u = r(n("./node_modules/@babel/runtime/helpers/getPrototypeOf.js")), c = r(n("./node_modules/@babel/runtime/helpers/inherits.js")), d = r(n("./node_modules/@babel/runtime/helpers/objectWithoutProperties.js")), f = r(n("./node_modules/react/index.js")), p = r(n("./node_modules/prop-types/index.js")), h = (r(n("./node_modules/warning/warning.js")), + r(n("./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js"))), _ = n("./node_modules/@material-ui/utils/index.es.js"), m = n("./node_modules/jss/lib/index.js"), y = r(n("./node_modules/@material-ui/core/styles/reactJssContext.js")), b = r(n("./node_modules/@material-ui/core/styles/jssPreset.js")), v = r(n("./node_modules/@material-ui/core/styles/mergeClasses.js")), g = r(n("./node_modules/@material-ui/core/styles/multiKeyStore.js")), j = r(n("./node_modules/@material-ui/core/styles/createMuiTheme.js")), x = r(n("./node_modules/@material-ui/core/styles/themeListener.js")), O = r(n("./node_modules/@material-ui/core/styles/createGenerateClassName.js")), w = r(n("./node_modules/@material-ui/core/styles/getStylesCreator.js")), E = r(n("./node_modules/@material-ui/core/styles/getThemeProps.js")), M = (0, + m.create)((0, b.default)()), P = (0, O.default)(), k = -1e11, T = new Map(); + t.sheetsManager = T; + var C = {}, S = (0, j.default)({ + typography: { + suppressWarning: !0 + } + }); + _.ponyfillGlobal.__MUI_STYLES__ || (_.ponyfillGlobal.__MUI_STYLES__ = {}), _.ponyfillGlobal.__MUI_STYLES__.withStyles || (_.ponyfillGlobal.__MUI_STYLES__.withStyles = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; + return function(n) { + var r, _ = t.withTheme, m = void 0 !== _ && _, b = t.flip, j = void 0 === b ? null : b, O = t.name, D = (0, + d.default)(t, [ "withTheme", "flip", "name" ]), A = (0, w.default)(e), I = A.themingEnabled || "string" == typeof O || m; + k += 1, A.options.index = k; + var R = function(e) { + function t(e, n) { + var r; + (0, i.default)(this, t), (r = (0, l.default)(this, (0, u.default)(t).call(this, e, n))).jss = n[y.default.jss] || M, + r.sheetsManager = T, r.unsubscribeId = null; + var o = n.muiThemeProviderOptions; + return o && (o.sheetsManager && (r.sheetsManager = o.sheetsManager), r.sheetsCache = o.sheetsCache, + r.disableStylesGeneration = o.disableStylesGeneration), r.stylesCreatorSaved = A, + r.sheetOptions = (0, a.default)({ + generateClassName: P + }, n[y.default.sheetOptions]), r.theme = I ? x.default.initial(n) || S : C, r.attach(r.theme), + r.cacheClasses = { + value: null, + lastProp: null, + lastJSS: {} + }, r; + } + return (0, c.default)(t, e), (0, s.default)(t, [ { + key: "componentDidMount", + value: function() { + var e = this; + I && (this.unsubscribeId = x.default.subscribe(this.context, function(t) { + var n = e.theme; + e.theme = t, e.attach(e.theme), e.setState({}, function() { + e.detach(n); + }); + })); + } + }, { + key: "componentDidUpdate", + value: function() { + this.stylesCreatorSaved; + } + }, { + key: "componentWillUnmount", + value: function() { + this.detach(this.theme), null !== this.unsubscribeId && x.default.unsubscribe(this.context, this.unsubscribeId); + } + }, { + key: "getClasses", + value: function() { + if (this.disableStylesGeneration) return this.props.classes || {}; + var e = !1, t = g.default.get(this.sheetsManager, this.stylesCreatorSaved, this.theme); + return t.sheet.classes !== this.cacheClasses.lastJSS && (this.cacheClasses.lastJSS = t.sheet.classes, + e = !0), this.props.classes !== this.cacheClasses.lastProp && (this.cacheClasses.lastProp = this.props.classes, + e = !0), e && (this.cacheClasses.value = (0, v.default)({ + baseClasses: this.cacheClasses.lastJSS, + newClasses: this.props.classes, + Component: n + })), this.cacheClasses.value; + } + }, { + key: "attach", + value: function(e) { + if (!this.disableStylesGeneration) { + var t = this.stylesCreatorSaved, n = g.default.get(this.sheetsManager, t, e); + if (n || (n = { + refs: 0, + sheet: null + }, g.default.set(this.sheetsManager, t, e, n)), 0 === n.refs) { + var r; + this.sheetsCache && (r = g.default.get(this.sheetsCache, t, e)), r || ((r = this.createSheet(e)).attach(), + this.sheetsCache && g.default.set(this.sheetsCache, t, e, r)), n.sheet = r; + var o = this.context[y.default.sheetsRegistry]; + o && o.add(r); + } + n.refs += 1; + } + } + }, { + key: "createSheet", + value: function(e) { + var t = this.stylesCreatorSaved.create(e, O), r = O; + return this.jss.createStyleSheet(t, (0, a.default)({ + meta: r, + classNamePrefix: r, + flip: "boolean" == typeof j ? j : "rtl" === e.direction, + link: !1 + }, this.sheetOptions, this.stylesCreatorSaved.options, { + name: O || n.displayName + }, D)); + } + }, { + key: "detach", + value: function(e) { + if (!this.disableStylesGeneration) { + var t = g.default.get(this.sheetsManager, this.stylesCreatorSaved, e); + if (t.refs -= 1, 0 === t.refs) { + g.default.delete(this.sheetsManager, this.stylesCreatorSaved, e), this.jss.removeStyleSheet(t.sheet); + var n = this.context[y.default.sheetsRegistry]; + n && n.remove(t.sheet); + } + } + } + }, { + key: "render", + value: function() { + var e = this.props, t = (e.classes, e.innerRef), r = (0, d.default)(e, [ "classes", "innerRef" ]), o = (0, + E.default)({ + theme: this.theme, + name: O, + props: r + }); + return m && !o.theme && (o.theme = this.theme), f.default.createElement(n, (0, a.default)({}, o, { + classes: this.getClasses(), + ref: t + })); + } + } ]), t; + }(f.default.Component); + return R.contextTypes = (0, a.default)((r = { + muiThemeProviderOptions: p.default.object + }, (0, o.default)(r, y.default.jss, p.default.object), (0, o.default)(r, y.default.sheetOptions, p.default.object), + (0, o.default)(r, y.default.sheetsRegistry, p.default.object), r), I ? x.default.contextTypes : {}), + (0, h.default)(R, n), R; + }; + }); + t.default = function(e, t) { + return _.ponyfillGlobal.__MUI_STYLES__.withStyles(e, (0, a.default)({ + defaultTheme: S + }, t)); + }; + }, + "./node_modules/@material-ui/core/styles/zIndex.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = { + mobileStepper: 1e3, + appBar: 1100, + drawer: 1200, + modal: 1300, + snackbar: 1400, + tooltip: 1500 + }; + t.default = r; + }, + "./node_modules/@material-ui/core/utils/deprecatedPropType.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e, t) { + return function() { + return null; + }; + }; + t.default = r; + }, + "./node_modules/@material-ui/core/utils/helpers.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.capitalize = function(e) { + 0; + return e.charAt(0).toUpperCase() + e.slice(1); + }, t.contains = a, t.findIndex = i, t.find = function(e, t) { + var n = i(e, t); + return n > -1 ? e[n] : void 0; + }, t.createChainedFunction = function() { + for (var e = arguments.length, t = new Array(e), n = 0; n < e; n++) t[n] = arguments[n]; + return t.reduce(function(e, t) { + return null == t ? e : function() { + for (var n = arguments.length, r = new Array(n), o = 0; o < n; o++) r[o] = arguments[o]; + e.apply(this, r), t.apply(this, r); + }; + }, function() {}); + }; + var o = r(n("./node_modules/@babel/runtime/helpers/typeof.js")); + r(n("./node_modules/warning/warning.js")); + function a(e, t) { + return Object.keys(t).every(function(n) { + return e.hasOwnProperty(n) && e[n] === t[n]; + }); + } + function i(e, t) { + for (var n = (0, o.default)(t), r = 0; r < e.length; r += 1) { + if ("function" === n && !0 == !!t(e[r], r, e)) return r; + if ("object" === n && a(e[r], t)) return r; + if (-1 !== [ "string", "number", "boolean" ].indexOf(n)) return e.indexOf(t); + } + return -1; + } + }, + "./node_modules/@material-ui/core/utils/ownerDocument.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e) { + return e && e.ownerDocument || document; + }; + t.default = r; + }, + "./node_modules/@material-ui/core/utils/ownerWindow.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var o = r(n("./node_modules/@material-ui/core/utils/ownerDocument.js")); + var a = function(e) { + var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : window, n = (0, + o.default)(e); + return n.defaultView || n.parentView || t; + }; + t.default = a; + }, + "./node_modules/@material-ui/core/utils/reactHelpers.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.cloneElementWithClassName = i, t.cloneChildrenWithClassName = function(e, t) { + return o.default.Children.map(e, function(e) { + return o.default.isValidElement(e) && i(e, t); + }); + }, t.isMuiElement = function(e, t) { + return o.default.isValidElement(e) && -1 !== t.indexOf(e.type.muiName); + }, t.setRef = function(e, t) { + "function" == typeof e ? e(t) : e && (e.current = t); + }; + var o = r(n("./node_modules/react/index.js")), a = r(n("./node_modules/classnames/index.js")); + function i(e, t) { + return o.default.cloneElement(e, { + className: (0, a.default)(e.props.className, t) + }); + } + }, + "./node_modules/@material-ui/core/utils/requirePropFactory.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e) { + return function() { + return null; + }; + }; + t.default = r; + }, + "./node_modules/@material-ui/utils/chainPropTypes.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = function(e, t) { + return function() { + return null; + }; + }; + t.default = r; + }, + "./node_modules/@material-ui/utils/componentPropType.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + r(n("./node_modules/@babel/runtime/helpers/typeof.js")), n("./node_modules/react-is/index.js"); + var o = function() { + return null; + }; + o.isRequired = function() { + return null; + }; + var a = o; + t.default = a; + }, + "./node_modules/@material-ui/utils/exactProp.js": function(e, t, n) { + "use strict"; + var r = n("./node_modules/@babel/runtime/helpers/interopRequireDefault.js"); + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = t.specialProperty = void 0; + r(n("./node_modules/@babel/runtime/helpers/defineProperty.js")), r(n("./node_modules/@babel/runtime/helpers/extends.js")); + var o = "exact-prop: ​"; + t.specialProperty = o; + var a = function(e) { + return e; + }; + t.default = a; + }, + "./node_modules/@material-ui/utils/getDisplayName.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.getFunctionName = o, t.default = void 0; + var r = /^\s*function(?:\s|\s*\/\*.*\*\/\s*)+([^(\s\/]*)\s*/; + function o(e) { + var t = "".concat(e).match(r); + return t && t[1] || ""; + } + var a = function(e) { + return "string" == typeof e ? e : e ? e.displayName || e.name || o(e) || "Component" : void 0; + }; + t.default = a; + }, + "./node_modules/@material-ui/utils/index.es.js": function(e, t, n) { + "use strict"; + n.r(t); + var r = n("./node_modules/@material-ui/utils/componentPropType.js"), o = n.n(r); + n.d(t, "componentPropType", function() { + return o.a; + }); + var a = n("./node_modules/@material-ui/utils/chainPropTypes.js"), i = n.n(a); + n.d(t, "chainPropTypes", function() { + return i.a; + }); + var s = n("./node_modules/@material-ui/utils/exactProp.js"), l = n.n(s); + n.d(t, "exactProp", function() { + return l.a; + }); + var u = n("./node_modules/@material-ui/utils/getDisplayName.js"), c = n.n(u); + n.d(t, "getDisplayName", function() { + return c.a; + }); + var d = n("./node_modules/@material-ui/utils/ponyfillGlobal.js"), f = n.n(d); + n.d(t, "ponyfillGlobal", function() { + return f.a; + }); + }, + "./node_modules/@material-ui/utils/ponyfillGlobal.js": function(e, t, n) { + "use strict"; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.default = void 0; + var r = "undefined" != typeof window && window.Math == Math ? window : "undefined" != typeof self && self.Math == Math ? self : Function("return this")(); + t.default = r; + }, + "./node_modules/balanced-match/index.js": function(e, t) { + function n(e, t, n) { + e instanceof RegExp && (e = r(e, n)), t instanceof RegExp && (t = r(t, n)); + var a = o(e, t, n); + return a && { + start: a[0], + end: a[1], + pre: n.slice(0, a[0]), + body: n.slice(a[0] + e.length, a[1]), + post: n.slice(a[1] + t.length) + }; + } + function r(e, t) { + var n = t.match(e); + return n ? n[0] : null; + } + function o(e, t, n) { + var r, o, a, i, s, l = n.indexOf(e), u = n.indexOf(t, l + 1), c = l; + if (l >= 0 && u > 0) { + for (r = [], a = n.length; c >= 0 && !s; ) c == l ? (r.push(c), l = n.indexOf(e, c + 1)) : 1 == r.length ? s = [ r.pop(), u ] : ((o = r.pop()) < a && (a = o, + i = u), u = n.indexOf(t, c + 1)), c = l < u && l >= 0 ? l : u; + r.length && (s = [ a, i ]); + } + return s; + } + e.exports = n, n.range = o; + }, + "./node_modules/brcast/dist/brcast.es.js": function(e, t, n) { + "use strict"; + n.r(t), t.default = function(e) { + var t = {}, n = 1, r = e; + return { + getState: function() { + return r; + }, + setState: function(e) { + r = e; + for (var n = Object.keys(t), o = 0, a = n.length; o < a; o++) t[n[o]] && t[n[o]](e); + }, + subscribe: function(e) { + if ("function" != typeof e) throw new Error("listener must be a function."); + var r = n; + return t[r] = e, n += 1, r; + }, + unsubscribe: function(e) { + t[e] = void 0; + } + }; + }; + }, + "./node_modules/classnames/index.js": function(e, t, n) { + var r; + !function() { + "use strict"; + var n = {}.hasOwnProperty; + function o() { + for (var e = [], t = 0; t < arguments.length; t++) { + var r = arguments[t]; + if (r) { + var a = typeof r; + if ("string" === a || "number" === a) e.push(r); else if (Array.isArray(r) && r.length) { + var i = o.apply(null, r); + i && e.push(i); + } else if ("object" === a) for (var s in r) n.call(r, s) && r[s] && e.push(s); + } + } + return e.join(" "); + } + e.exports ? (o.default = o, e.exports = o) : void 0 === (r = function() { + return o; + }.apply(t, [])) || (e.exports = r); + }(); + }, + "./node_modules/color-convert/conversions.js": function(e, t, n) { + const r = n("./node_modules/color-name/index.js"), o = {}; + for (const e of Object.keys(r)) o[r[e]] = e; + const a = { + rgb: { + channels: 3, + labels: "rgb" + }, + hsl: { + channels: 3, + labels: "hsl" + }, + hsv: { + channels: 3, + labels: "hsv" + }, + hwb: { + channels: 3, + labels: "hwb" + }, + cmyk: { + channels: 4, + labels: "cmyk" + }, + xyz: { + channels: 3, + labels: "xyz" + }, + lab: { + channels: 3, + labels: "lab" + }, + lch: { + channels: 3, + labels: "lch" + }, + hex: { + channels: 1, + labels: [ "hex" ] + }, + keyword: { + channels: 1, + labels: [ "keyword" ] + }, + ansi16: { + channels: 1, + labels: [ "ansi16" ] + }, + ansi256: { + channels: 1, + labels: [ "ansi256" ] + }, + hcg: { + channels: 3, + labels: [ "h", "c", "g" ] + }, + apple: { + channels: 3, + labels: [ "r16", "g16", "b16" ] + }, + gray: { + channels: 1, + labels: [ "gray" ] + } + }; + e.exports = a; + for (const e of Object.keys(a)) { + if (!("channels" in a[e])) throw new Error("missing channels property: " + e); + if (!("labels" in a[e])) throw new Error("missing channel labels property: " + e); + if (a[e].labels.length !== a[e].channels) throw new Error("channel and label counts mismatch: " + e); + const {channels: t, labels: n} = a[e]; + delete a[e].channels, delete a[e].labels, Object.defineProperty(a[e], "channels", { + value: t + }), Object.defineProperty(a[e], "labels", { + value: n + }); + } + function i(e, t) { + return (e[0] - t[0]) ** 2 + (e[1] - t[1]) ** 2 + (e[2] - t[2]) ** 2; + } + a.rgb.hsl = function(e) { + const t = e[0] / 255, n = e[1] / 255, r = e[2] / 255, o = Math.min(t, n, r), a = Math.max(t, n, r), i = a - o; + let s, l; + a === o ? s = 0 : t === a ? s = (n - r) / i : n === a ? s = 2 + (r - t) / i : r === a && (s = 4 + (t - n) / i), + (s = Math.min(60 * s, 360)) < 0 && (s += 360); + const u = (o + a) / 2; + return [ s, 100 * (l = a === o ? 0 : u <= .5 ? i / (a + o) : i / (2 - a - o)), 100 * u ]; + }, a.rgb.hsv = function(e) { + let t, n, r, o, a; + const i = e[0] / 255, s = e[1] / 255, l = e[2] / 255, u = Math.max(i, s, l), c = u - Math.min(i, s, l), d = function(e) { + return (u - e) / 6 / c + .5; + }; + return 0 === c ? (o = 0, a = 0) : (a = c / u, t = d(i), n = d(s), r = d(l), i === u ? o = r - n : s === u ? o = 1 / 3 + t - r : l === u && (o = 2 / 3 + n - t), + o < 0 ? o += 1 : o > 1 && (o -= 1)), [ 360 * o, 100 * a, 100 * u ]; + }, a.rgb.hwb = function(e) { + const t = e[0], n = e[1]; + let r = e[2]; + return [ a.rgb.hsl(e)[0], 100 * (1 / 255 * Math.min(t, Math.min(n, r))), 100 * (r = 1 - 1 / 255 * Math.max(t, Math.max(n, r))) ]; + }, a.rgb.cmyk = function(e) { + const t = e[0] / 255, n = e[1] / 255, r = e[2] / 255, o = Math.min(1 - t, 1 - n, 1 - r); + return [ 100 * ((1 - t - o) / (1 - o) || 0), 100 * ((1 - n - o) / (1 - o) || 0), 100 * ((1 - r - o) / (1 - o) || 0), 100 * o ]; + }, a.rgb.keyword = function(e) { + const t = o[e]; + if (t) return t; + let n, a = 1 / 0; + for (const t of Object.keys(r)) { + const o = i(e, r[t]); + o < a && (a = o, n = t); + } + return n; + }, a.keyword.rgb = function(e) { + return r[e]; + }, a.rgb.xyz = function(e) { + let t = e[0] / 255, n = e[1] / 255, r = e[2] / 255; + return [ 100 * (.4124 * (t = t > .04045 ? ((t + .055) / 1.055) ** 2.4 : t / 12.92) + .3576 * (n = n > .04045 ? ((n + .055) / 1.055) ** 2.4 : n / 12.92) + .1805 * (r = r > .04045 ? ((r + .055) / 1.055) ** 2.4 : r / 12.92)), 100 * (.2126 * t + .7152 * n + .0722 * r), 100 * (.0193 * t + .1192 * n + .9505 * r) ]; + }, a.rgb.lab = function(e) { + const t = a.rgb.xyz(e); + let n = t[0], r = t[1], o = t[2]; + return [ 116 * (r = (r /= 100) > .008856 ? r ** (1 / 3) : 7.787 * r + 16 / 116) - 16, 500 * ((n = (n /= 95.047) > .008856 ? n ** (1 / 3) : 7.787 * n + 16 / 116) - r), 200 * (r - (o = (o /= 108.883) > .008856 ? o ** (1 / 3) : 7.787 * o + 16 / 116)) ]; + }, a.hsl.rgb = function(e) { + const t = e[0] / 360, n = e[1] / 100, r = e[2] / 100; + let o, a, i; + if (0 === n) return [ i = 255 * r, i, i ]; + const s = 2 * r - (o = r < .5 ? r * (1 + n) : r + n - r * n), l = [ 0, 0, 0 ]; + for (let e = 0; e < 3; e++) (a = t + 1 / 3 * -(e - 1)) < 0 && a++, a > 1 && a--, + i = 6 * a < 1 ? s + 6 * (o - s) * a : 2 * a < 1 ? o : 3 * a < 2 ? s + (o - s) * (2 / 3 - a) * 6 : s, + l[e] = 255 * i; + return l; + }, a.hsl.hsv = function(e) { + const t = e[0]; + let n = e[1] / 100, r = e[2] / 100, o = n; + const a = Math.max(r, .01); + return n *= (r *= 2) <= 1 ? r : 2 - r, o *= a <= 1 ? a : 2 - a, [ t, 100 * (0 === r ? 2 * o / (a + o) : 2 * n / (r + n)), 100 * ((r + n) / 2) ]; + }, a.hsv.rgb = function(e) { + const t = e[0] / 60, n = e[1] / 100; + let r = e[2] / 100; + const o = Math.floor(t) % 6, a = t - Math.floor(t), i = 255 * r * (1 - n), s = 255 * r * (1 - n * a), l = 255 * r * (1 - n * (1 - a)); + switch (r *= 255, o) { + case 0: + return [ r, l, i ]; + + case 1: + return [ s, r, i ]; + + case 2: + return [ i, r, l ]; + + case 3: + return [ i, s, r ]; + + case 4: + return [ l, i, r ]; + + case 5: + return [ r, i, s ]; + } + }, a.hsv.hsl = function(e) { + const t = e[0], n = e[1] / 100, r = e[2] / 100, o = Math.max(r, .01); + let a, i; + i = (2 - n) * r; + const s = (2 - n) * o; + return a = n * o, [ t, 100 * (a = (a /= s <= 1 ? s : 2 - s) || 0), 100 * (i /= 2) ]; + }, a.hwb.rgb = function(e) { + const t = e[0] / 360; + let n = e[1] / 100, r = e[2] / 100; + const o = n + r; + let a; + o > 1 && (n /= o, r /= o); + const i = Math.floor(6 * t), s = 1 - r; + a = 6 * t - i, 0 != (1 & i) && (a = 1 - a); + const l = n + a * (s - n); + let u, c, d; + switch (i) { + default: + case 6: + case 0: + u = s, c = l, d = n; + break; + + case 1: + u = l, c = s, d = n; + break; + + case 2: + u = n, c = s, d = l; + break; + + case 3: + u = n, c = l, d = s; + break; + + case 4: + u = l, c = n, d = s; + break; + + case 5: + u = s, c = n, d = l; + } + return [ 255 * u, 255 * c, 255 * d ]; + }, a.cmyk.rgb = function(e) { + const t = e[0] / 100, n = e[1] / 100, r = e[2] / 100, o = e[3] / 100; + return [ 255 * (1 - Math.min(1, t * (1 - o) + o)), 255 * (1 - Math.min(1, n * (1 - o) + o)), 255 * (1 - Math.min(1, r * (1 - o) + o)) ]; + }, a.xyz.rgb = function(e) { + const t = e[0] / 100, n = e[1] / 100, r = e[2] / 100; + let o, a, i; + return o = (o = 3.2406 * t + -1.5372 * n + -.4986 * r) > .0031308 ? 1.055 * o ** (1 / 2.4) - .055 : 12.92 * o, + a = (a = -.9689 * t + 1.8758 * n + .0415 * r) > .0031308 ? 1.055 * a ** (1 / 2.4) - .055 : 12.92 * a, + i = (i = .0557 * t + -.204 * n + 1.057 * r) > .0031308 ? 1.055 * i ** (1 / 2.4) - .055 : 12.92 * i, + [ 255 * (o = Math.min(Math.max(0, o), 1)), 255 * (a = Math.min(Math.max(0, a), 1)), 255 * (i = Math.min(Math.max(0, i), 1)) ]; + }, a.xyz.lab = function(e) { + let t = e[0], n = e[1], r = e[2]; + return [ 116 * (n = (n /= 100) > .008856 ? n ** (1 / 3) : 7.787 * n + 16 / 116) - 16, 500 * ((t = (t /= 95.047) > .008856 ? t ** (1 / 3) : 7.787 * t + 16 / 116) - n), 200 * (n - (r = (r /= 108.883) > .008856 ? r ** (1 / 3) : 7.787 * r + 16 / 116)) ]; + }, a.lab.xyz = function(e) { + let t, n, r; + const o = (n = (e[0] + 16) / 116) ** 3, a = (t = e[1] / 500 + n) ** 3, i = (r = n - e[2] / 200) ** 3; + return n = o > .008856 ? o : (n - 16 / 116) / 7.787, t = a > .008856 ? a : (t - 16 / 116) / 7.787, + r = i > .008856 ? i : (r - 16 / 116) / 7.787, [ t *= 95.047, n *= 100, r *= 108.883 ]; + }, a.lab.lch = function(e) { + const t = e[0], n = e[1], r = e[2]; + let o; + return (o = 360 * Math.atan2(r, n) / 2 / Math.PI) < 0 && (o += 360), [ t, Math.sqrt(n * n + r * r), o ]; + }, a.lch.lab = function(e) { + const t = e[0], n = e[1], r = e[2] / 360 * 2 * Math.PI; + return [ t, n * Math.cos(r), n * Math.sin(r) ]; + }, a.rgb.ansi16 = function(e, t = null) { + const [n, r, o] = e; + let i = null === t ? a.rgb.hsv(e)[2] : t; + if (0 === (i = Math.round(i / 50))) return 30; + let s = 30 + (Math.round(o / 255) << 2 | Math.round(r / 255) << 1 | Math.round(n / 255)); + return 2 === i && (s += 60), s; + }, a.hsv.ansi16 = function(e) { + return a.rgb.ansi16(a.hsv.rgb(e), e[2]); + }, a.rgb.ansi256 = function(e) { + const t = e[0], n = e[1], r = e[2]; + return t === n && n === r ? t < 8 ? 16 : t > 248 ? 231 : Math.round((t - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(t / 255 * 5) + 6 * Math.round(n / 255 * 5) + Math.round(r / 255 * 5); + }, a.ansi16.rgb = function(e) { + let t = e % 10; + if (0 === t || 7 === t) return e > 50 && (t += 3.5), [ t = t / 10.5 * 255, t, t ]; + const n = .5 * (1 + ~~(e > 50)); + return [ (1 & t) * n * 255, (t >> 1 & 1) * n * 255, (t >> 2 & 1) * n * 255 ]; + }, a.ansi256.rgb = function(e) { + if (e >= 232) { + const t = 10 * (e - 232) + 8; + return [ t, t, t ]; + } + let t; + return e -= 16, [ Math.floor(e / 36) / 5 * 255, Math.floor((t = e % 36) / 6) / 5 * 255, t % 6 / 5 * 255 ]; + }, a.rgb.hex = function(e) { + const t = (((255 & Math.round(e[0])) << 16) + ((255 & Math.round(e[1])) << 8) + (255 & Math.round(e[2]))).toString(16).toUpperCase(); + return "000000".substring(t.length) + t; + }, a.hex.rgb = function(e) { + const t = e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!t) return [ 0, 0, 0 ]; + let n = t[0]; + 3 === t[0].length && (n = n.split("").map(e => e + e).join("")); + const r = parseInt(n, 16); + return [ r >> 16 & 255, r >> 8 & 255, 255 & r ]; + }, a.rgb.hcg = function(e) { + const t = e[0] / 255, n = e[1] / 255, r = e[2] / 255, o = Math.max(Math.max(t, n), r), a = Math.min(Math.min(t, n), r), i = o - a; + let s, l; + return l = i <= 0 ? 0 : o === t ? (n - r) / i % 6 : o === n ? 2 + (r - t) / i : 4 + (t - n) / i + 4, + l /= 6, [ 360 * (l %= 1), 100 * i, 100 * (s = i < 1 ? a / (1 - i) : 0) ]; + }, a.hsl.hcg = function(e) { + const t = e[1] / 100, n = e[2] / 100, r = n < .5 ? 2 * t * n : 2 * t * (1 - n); + let o = 0; + return r < 1 && (o = (n - .5 * r) / (1 - r)), [ e[0], 100 * r, 100 * o ]; + }, a.hsv.hcg = function(e) { + const t = e[1] / 100, n = e[2] / 100, r = t * n; + let o = 0; + return r < 1 && (o = (n - r) / (1 - r)), [ e[0], 100 * r, 100 * o ]; + }, a.hcg.rgb = function(e) { + const t = e[0] / 360, n = e[1] / 100, r = e[2] / 100; + if (0 === n) return [ 255 * r, 255 * r, 255 * r ]; + const o = [ 0, 0, 0 ], a = t % 1 * 6, i = a % 1, s = 1 - i; + let l = 0; + switch (Math.floor(a)) { + case 0: + o[0] = 1, o[1] = i, o[2] = 0; + break; + + case 1: + o[0] = s, o[1] = 1, o[2] = 0; + break; + + case 2: + o[0] = 0, o[1] = 1, o[2] = i; + break; + + case 3: + o[0] = 0, o[1] = s, o[2] = 1; + break; + + case 4: + o[0] = i, o[1] = 0, o[2] = 1; + break; + + default: + o[0] = 1, o[1] = 0, o[2] = s; + } + return l = (1 - n) * r, [ 255 * (n * o[0] + l), 255 * (n * o[1] + l), 255 * (n * o[2] + l) ]; + }, a.hcg.hsv = function(e) { + const t = e[1] / 100, n = t + e[2] / 100 * (1 - t); + let r = 0; + return n > 0 && (r = t / n), [ e[0], 100 * r, 100 * n ]; + }, a.hcg.hsl = function(e) { + const t = e[1] / 100, n = e[2] / 100 * (1 - t) + .5 * t; + let r = 0; + return n > 0 && n < .5 ? r = t / (2 * n) : n >= .5 && n < 1 && (r = t / (2 * (1 - n))), + [ e[0], 100 * r, 100 * n ]; + }, a.hcg.hwb = function(e) { + const t = e[1] / 100, n = t + e[2] / 100 * (1 - t); + return [ e[0], 100 * (n - t), 100 * (1 - n) ]; + }, a.hwb.hcg = function(e) { + const t = e[1] / 100, n = 1 - e[2] / 100, r = n - t; + let o = 0; + return r < 1 && (o = (n - r) / (1 - r)), [ e[0], 100 * r, 100 * o ]; + }, a.apple.rgb = function(e) { + return [ e[0] / 65535 * 255, e[1] / 65535 * 255, e[2] / 65535 * 255 ]; + }, a.rgb.apple = function(e) { + return [ e[0] / 255 * 65535, e[1] / 255 * 65535, e[2] / 255 * 65535 ]; + }, a.gray.rgb = function(e) { + return [ e[0] / 100 * 255, e[0] / 100 * 255, e[0] / 100 * 255 ]; + }, a.gray.hsl = function(e) { + return [ 0, 0, e[0] ]; + }, a.gray.hsv = a.gray.hsl, a.gray.hwb = function(e) { + return [ 0, 100, e[0] ]; + }, a.gray.cmyk = function(e) { + return [ 0, 0, 0, e[0] ]; + }, a.gray.lab = function(e) { + return [ e[0], 0, 0 ]; + }, a.gray.hex = function(e) { + const t = 255 & Math.round(e[0] / 100 * 255), n = ((t << 16) + (t << 8) + t).toString(16).toUpperCase(); + return "000000".substring(n.length) + n; + }, a.rgb.gray = function(e) { + return [ (e[0] + e[1] + e[2]) / 3 / 255 * 100 ]; + }; + }, + "./node_modules/color-convert/index.js": function(e, t, n) { + const r = n("./node_modules/color-convert/conversions.js"), o = n("./node_modules/color-convert/route.js"), a = {}; + Object.keys(r).forEach(e => { + a[e] = {}, Object.defineProperty(a[e], "channels", { + value: r[e].channels + }), Object.defineProperty(a[e], "labels", { + value: r[e].labels + }); + const t = o(e); + Object.keys(t).forEach(n => { + const r = t[n]; + a[e][n] = function(e) { + const t = function(...t) { + const n = t[0]; + if (null == n) return n; + n.length > 1 && (t = n); + const r = e(t); + if ("object" == typeof r) for (let e = r.length, t = 0; t < e; t++) r[t] = Math.round(r[t]); + return r; + }; + return "conversion" in e && (t.conversion = e.conversion), t; + }(r), a[e][n].raw = function(e) { + const t = function(...t) { + const n = t[0]; + return null == n ? n : (n.length > 1 && (t = n), e(t)); + }; + return "conversion" in e && (t.conversion = e.conversion), t; + }(r); + }); + }), e.exports = a; + }, + "./node_modules/color-convert/route.js": function(e, t, n) { + const r = n("./node_modules/color-convert/conversions.js"); + function o(e) { + const t = function() { + const e = {}, t = Object.keys(r); + for (let n = t.length, r = 0; r < n; r++) e[t[r]] = { + distance: -1, + parent: null + }; + return e; + }(), n = [ e ]; + for (t[e].distance = 0; n.length; ) { + const e = n.pop(), o = Object.keys(r[e]); + for (let r = o.length, a = 0; a < r; a++) { + const r = o[a], i = t[r]; + -1 === i.distance && (i.distance = t[e].distance + 1, i.parent = e, n.unshift(r)); + } + } + return t; + } + function a(e, t) { + return function(n) { + return t(e(n)); + }; + } + function i(e, t) { + const n = [ t[e].parent, e ]; + let o = r[t[e].parent][e], i = t[e].parent; + for (;t[i].parent; ) n.unshift(t[i].parent), o = a(r[t[i].parent][i], o), i = t[i].parent; + return o.conversion = n, o; + } + e.exports = function(e) { + const t = o(e), n = {}, r = Object.keys(t); + for (let e = r.length, o = 0; o < e; o++) { + const e = r[o]; + null !== t[e].parent && (n[e] = i(e, t)); + } + return n; + }; + }, + "./node_modules/color-name/index.js": function(e, t, n) { + "use strict"; + e.exports = { + aliceblue: [ 240, 248, 255 ], + antiquewhite: [ 250, 235, 215 ], + aqua: [ 0, 255, 255 ], + aquamarine: [ 127, 255, 212 ], + azure: [ 240, 255, 255 ], + beige: [ 245, 245, 220 ], + bisque: [ 255, 228, 196 ], + black: [ 0, 0, 0 ], + blanchedalmond: [ 255, 235, 205 ], + blue: [ 0, 0, 255 ], + blueviolet: [ 138, 43, 226 ], + brown: [ 165, 42, 42 ], + burlywood: [ 222, 184, 135 ], + cadetblue: [ 95, 158, 160 ], + chartreuse: [ 127, 255, 0 ], + chocolate: [ 210, 105, 30 ], + coral: [ 255, 127, 80 ], + cornflowerblue: [ 100, 149, 237 ], + cornsilk: [ 255, 248, 220 ], + crimson: [ 220, 20, 60 ], + cyan: [ 0, 255, 255 ], + darkblue: [ 0, 0, 139 ], + darkcyan: [ 0, 139, 139 ], + darkgoldenrod: [ 184, 134, 11 ], + darkgray: [ 169, 169, 169 ], + darkgreen: [ 0, 100, 0 ], + darkgrey: [ 169, 169, 169 ], + darkkhaki: [ 189, 183, 107 ], + darkmagenta: [ 139, 0, 139 ], + darkolivegreen: [ 85, 107, 47 ], + darkorange: [ 255, 140, 0 ], + darkorchid: [ 153, 50, 204 ], + darkred: [ 139, 0, 0 ], + darksalmon: [ 233, 150, 122 ], + darkseagreen: [ 143, 188, 143 ], + darkslateblue: [ 72, 61, 139 ], + darkslategray: [ 47, 79, 79 ], + darkslategrey: [ 47, 79, 79 ], + darkturquoise: [ 0, 206, 209 ], + darkviolet: [ 148, 0, 211 ], + deeppink: [ 255, 20, 147 ], + deepskyblue: [ 0, 191, 255 ], + dimgray: [ 105, 105, 105 ], + dimgrey: [ 105, 105, 105 ], + dodgerblue: [ 30, 144, 255 ], + firebrick: [ 178, 34, 34 ], + floralwhite: [ 255, 250, 240 ], + forestgreen: [ 34, 139, 34 ], + fuchsia: [ 255, 0, 255 ], + gainsboro: [ 220, 220, 220 ], + ghostwhite: [ 248, 248, 255 ], + gold: [ 255, 215, 0 ], + goldenrod: [ 218, 165, 32 ], + gray: [ 128, 128, 128 ], + green: [ 0, 128, 0 ], + greenyellow: [ 173, 255, 47 ], + grey: [ 128, 128, 128 ], + honeydew: [ 240, 255, 240 ], + hotpink: [ 255, 105, 180 ], + indianred: [ 205, 92, 92 ], + indigo: [ 75, 0, 130 ], + ivory: [ 255, 255, 240 ], + khaki: [ 240, 230, 140 ], + lavender: [ 230, 230, 250 ], + lavenderblush: [ 255, 240, 245 ], + lawngreen: [ 124, 252, 0 ], + lemonchiffon: [ 255, 250, 205 ], + lightblue: [ 173, 216, 230 ], + lightcoral: [ 240, 128, 128 ], + lightcyan: [ 224, 255, 255 ], + lightgoldenrodyellow: [ 250, 250, 210 ], + lightgray: [ 211, 211, 211 ], + lightgreen: [ 144, 238, 144 ], + lightgrey: [ 211, 211, 211 ], + lightpink: [ 255, 182, 193 ], + lightsalmon: [ 255, 160, 122 ], + lightseagreen: [ 32, 178, 170 ], + lightskyblue: [ 135, 206, 250 ], + lightslategray: [ 119, 136, 153 ], + lightslategrey: [ 119, 136, 153 ], + lightsteelblue: [ 176, 196, 222 ], + lightyellow: [ 255, 255, 224 ], + lime: [ 0, 255, 0 ], + limegreen: [ 50, 205, 50 ], + linen: [ 250, 240, 230 ], + magenta: [ 255, 0, 255 ], + maroon: [ 128, 0, 0 ], + mediumaquamarine: [ 102, 205, 170 ], + mediumblue: [ 0, 0, 205 ], + mediumorchid: [ 186, 85, 211 ], + mediumpurple: [ 147, 112, 219 ], + mediumseagreen: [ 60, 179, 113 ], + mediumslateblue: [ 123, 104, 238 ], + mediumspringgreen: [ 0, 250, 154 ], + mediumturquoise: [ 72, 209, 204 ], + mediumvioletred: [ 199, 21, 133 ], + midnightblue: [ 25, 25, 112 ], + mintcream: [ 245, 255, 250 ], + mistyrose: [ 255, 228, 225 ], + moccasin: [ 255, 228, 181 ], + navajowhite: [ 255, 222, 173 ], + navy: [ 0, 0, 128 ], + oldlace: [ 253, 245, 230 ], + olive: [ 128, 128, 0 ], + olivedrab: [ 107, 142, 35 ], + orange: [ 255, 165, 0 ], + orangered: [ 255, 69, 0 ], + orchid: [ 218, 112, 214 ], + palegoldenrod: [ 238, 232, 170 ], + palegreen: [ 152, 251, 152 ], + paleturquoise: [ 175, 238, 238 ], + palevioletred: [ 219, 112, 147 ], + papayawhip: [ 255, 239, 213 ], + peachpuff: [ 255, 218, 185 ], + peru: [ 205, 133, 63 ], + pink: [ 255, 192, 203 ], + plum: [ 221, 160, 221 ], + powderblue: [ 176, 224, 230 ], + purple: [ 128, 0, 128 ], + rebeccapurple: [ 102, 51, 153 ], + red: [ 255, 0, 0 ], + rosybrown: [ 188, 143, 143 ], + royalblue: [ 65, 105, 225 ], + saddlebrown: [ 139, 69, 19 ], + salmon: [ 250, 128, 114 ], + sandybrown: [ 244, 164, 96 ], + seagreen: [ 46, 139, 87 ], + seashell: [ 255, 245, 238 ], + sienna: [ 160, 82, 45 ], + silver: [ 192, 192, 192 ], + skyblue: [ 135, 206, 235 ], + slateblue: [ 106, 90, 205 ], + slategray: [ 112, 128, 144 ], + slategrey: [ 112, 128, 144 ], + snow: [ 255, 250, 250 ], + springgreen: [ 0, 255, 127 ], + steelblue: [ 70, 130, 180 ], + tan: [ 210, 180, 140 ], + teal: [ 0, 128, 128 ], + thistle: [ 216, 191, 216 ], + tomato: [ 255, 99, 71 ], + turquoise: [ 64, 224, 208 ], + violet: [ 238, 130, 238 ], + wheat: [ 245, 222, 179 ], + white: [ 255, 255, 255 ], + whitesmoke: [ 245, 245, 245 ], + yellow: [ 255, 255, 0 ], + yellowgreen: [ 154, 205, 50 ] + }; + }, + "./node_modules/core-js/es6/math.js": function(e, t, n) { + n("./node_modules/core-js/modules/es6.math.acosh.js"), n("./node_modules/core-js/modules/es6.math.asinh.js"), + n("./node_modules/core-js/modules/es6.math.atanh.js"), n("./node_modules/core-js/modules/es6.math.cbrt.js"), + n("./node_modules/core-js/modules/es6.math.clz32.js"), n("./node_modules/core-js/modules/es6.math.cosh.js"), + n("./node_modules/core-js/modules/es6.math.expm1.js"), n("./node_modules/core-js/modules/es6.math.fround.js"), + n("./node_modules/core-js/modules/es6.math.hypot.js"), n("./node_modules/core-js/modules/es6.math.imul.js"), + n("./node_modules/core-js/modules/es6.math.log10.js"), n("./node_modules/core-js/modules/es6.math.log1p.js"), + n("./node_modules/core-js/modules/es6.math.log2.js"), n("./node_modules/core-js/modules/es6.math.sign.js"), + n("./node_modules/core-js/modules/es6.math.sinh.js"), n("./node_modules/core-js/modules/es6.math.tanh.js"), + n("./node_modules/core-js/modules/es6.math.trunc.js"), e.exports = n("./node_modules/core-js/modules/_core.js").Math; + }, + "./node_modules/core-js/es6/number.js": function(e, t, n) { + n("./node_modules/core-js/modules/es6.number.constructor.js"), n("./node_modules/core-js/modules/es6.number.to-fixed.js"), + n("./node_modules/core-js/modules/es6.number.to-precision.js"), n("./node_modules/core-js/modules/es6.number.epsilon.js"), + n("./node_modules/core-js/modules/es6.number.is-finite.js"), n("./node_modules/core-js/modules/es6.number.is-integer.js"), + n("./node_modules/core-js/modules/es6.number.is-nan.js"), n("./node_modules/core-js/modules/es6.number.is-safe-integer.js"), + n("./node_modules/core-js/modules/es6.number.max-safe-integer.js"), n("./node_modules/core-js/modules/es6.number.min-safe-integer.js"), + n("./node_modules/core-js/modules/es6.number.parse-float.js"), n("./node_modules/core-js/modules/es6.number.parse-int.js"), + e.exports = n("./node_modules/core-js/modules/_core.js").Number; + }, + "./node_modules/core-js/modules/_a-function.js": function(e, t) { + e.exports = function(e) { + if ("function" != typeof e) throw TypeError(e + " is not a function!"); + return e; + }; + }, + "./node_modules/core-js/modules/_a-number-value.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_cof.js"); + e.exports = function(e, t) { + if ("number" != typeof e && "Number" != r(e)) throw TypeError(t); + return +e; + }; + }, + "./node_modules/core-js/modules/_an-object.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_is-object.js"); + e.exports = function(e) { + if (!r(e)) throw TypeError(e + " is not an object!"); + return e; + }; + }, + "./node_modules/core-js/modules/_array-includes.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_to-iobject.js"), o = n("./node_modules/core-js/modules/_to-length.js"), a = n("./node_modules/core-js/modules/_to-absolute-index.js"); + e.exports = function(e) { + return function(t, n, i) { + var s, l = r(t), u = o(l.length), c = a(i, u); + if (e && n != n) { + for (;u > c; ) if ((s = l[c++]) != s) return !0; + } else for (;u > c; c++) if ((e || c in l) && l[c] === n) return e || c || 0; + return !e && -1; + }; + }; + }, + "./node_modules/core-js/modules/_cof.js": function(e, t) { + var n = {}.toString; + e.exports = function(e) { + return n.call(e).slice(8, -1); + }; + }, + "./node_modules/core-js/modules/_core.js": function(e, t) { + var n = e.exports = { + version: "2.5.7" + }; + "number" == typeof __e && (__e = n); + }, + "./node_modules/core-js/modules/_ctx.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_a-function.js"); + e.exports = function(e, t, n) { + if (r(e), void 0 === t) return e; + switch (n) { + case 1: + return function(n) { + return e.call(t, n); + }; + + case 2: + return function(n, r) { + return e.call(t, n, r); + }; + + case 3: + return function(n, r, o) { + return e.call(t, n, r, o); + }; + } + return function() { + return e.apply(t, arguments); + }; + }; + }, + "./node_modules/core-js/modules/_defined.js": function(e, t) { + e.exports = function(e) { + if (null == e) throw TypeError("Can't call method on " + e); + return e; + }; + }, + "./node_modules/core-js/modules/_descriptors.js": function(e, t, n) { + e.exports = !n("./node_modules/core-js/modules/_fails.js")(function() { + return 7 != Object.defineProperty({}, "a", { + get: function() { + return 7; + } + }).a; + }); + }, + "./node_modules/core-js/modules/_dom-create.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_is-object.js"), o = n("./node_modules/core-js/modules/_global.js").document, a = r(o) && r(o.createElement); + e.exports = function(e) { + return a ? o.createElement(e) : {}; + }; + }, + "./node_modules/core-js/modules/_enum-bug-keys.js": function(e, t) { + e.exports = "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","); + }, + "./node_modules/core-js/modules/_export.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_global.js"), o = n("./node_modules/core-js/modules/_core.js"), a = n("./node_modules/core-js/modules/_hide.js"), i = n("./node_modules/core-js/modules/_redefine.js"), s = n("./node_modules/core-js/modules/_ctx.js"), l = function(e, t, n) { + var u, c, d, f, p = e & l.F, h = e & l.G, _ = e & l.S, m = e & l.P, y = e & l.B, b = h ? r : _ ? r[t] || (r[t] = {}) : (r[t] || {}).prototype, v = h ? o : o[t] || (o[t] = {}), g = v.prototype || (v.prototype = {}); + for (u in h && (n = t), n) d = ((c = !p && b && void 0 !== b[u]) ? b : n)[u], f = y && c ? s(d, r) : m && "function" == typeof d ? s(Function.call, d) : d, + b && i(b, u, d, e & l.U), v[u] != d && a(v, u, f), m && g[u] != d && (g[u] = d); + }; + r.core = o, l.F = 1, l.G = 2, l.S = 4, l.P = 8, l.B = 16, l.W = 32, l.U = 64, l.R = 128, + e.exports = l; + }, + "./node_modules/core-js/modules/_fails.js": function(e, t) { + e.exports = function(e) { + try { + return !!e(); + } catch (e) { + return !0; + } + }; + }, + "./node_modules/core-js/modules/_global.js": function(e, t) { + var n = e.exports = "undefined" != typeof window && window.Math == Math ? window : "undefined" != typeof self && self.Math == Math ? self : Function("return this")(); + "number" == typeof __g && (__g = n); + }, + "./node_modules/core-js/modules/_has.js": function(e, t) { + var n = {}.hasOwnProperty; + e.exports = function(e, t) { + return n.call(e, t); + }; + }, + "./node_modules/core-js/modules/_hide.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_object-dp.js"), o = n("./node_modules/core-js/modules/_property-desc.js"); + e.exports = n("./node_modules/core-js/modules/_descriptors.js") ? function(e, t, n) { + return r.f(e, t, o(1, n)); + } : function(e, t, n) { + return e[t] = n, e; + }; + }, + "./node_modules/core-js/modules/_html.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_global.js").document; + e.exports = r && r.documentElement; + }, + "./node_modules/core-js/modules/_ie8-dom-define.js": function(e, t, n) { + e.exports = !n("./node_modules/core-js/modules/_descriptors.js") && !n("./node_modules/core-js/modules/_fails.js")(function() { + return 7 != Object.defineProperty(n("./node_modules/core-js/modules/_dom-create.js")("div"), "a", { + get: function() { + return 7; + } + }).a; + }); + }, + "./node_modules/core-js/modules/_inherit-if-required.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_is-object.js"), o = n("./node_modules/core-js/modules/_set-proto.js").set; + e.exports = function(e, t, n) { + var a, i = t.constructor; + return i !== n && "function" == typeof i && (a = i.prototype) !== n.prototype && r(a) && o && o(e, a), + e; + }; + }, + "./node_modules/core-js/modules/_iobject.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_cof.js"); + e.exports = Object("z").propertyIsEnumerable(0) ? Object : function(e) { + return "String" == r(e) ? e.split("") : Object(e); + }; + }, + "./node_modules/core-js/modules/_is-integer.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_is-object.js"), o = Math.floor; + e.exports = function(e) { + return !r(e) && isFinite(e) && o(e) === e; + }; + }, + "./node_modules/core-js/modules/_is-object.js": function(e, t) { + e.exports = function(e) { + return "object" == typeof e ? null !== e : "function" == typeof e; + }; + }, + "./node_modules/core-js/modules/_library.js": function(e, t) { + e.exports = !1; + }, + "./node_modules/core-js/modules/_math-expm1.js": function(e, t) { + var n = Math.expm1; + e.exports = !n || n(10) > 22025.465794806718 || n(10) < 22025.465794806718 || -2e-17 != n(-2e-17) ? function(e) { + return 0 == (e = +e) ? e : e > -1e-6 && e < 1e-6 ? e + e * e / 2 : Math.exp(e) - 1; + } : n; + }, + "./node_modules/core-js/modules/_math-fround.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_math-sign.js"), o = Math.pow, a = o(2, -52), i = o(2, -23), s = o(2, 127) * (2 - i), l = o(2, -126); + e.exports = Math.fround || function(e) { + var t, n, o = Math.abs(e), u = r(e); + return o < l ? u * (o / l / i + 1 / a - 1 / a) * l * i : (n = (t = (1 + i / a) * o) - (t - o)) > s || n != n ? u * (1 / 0) : u * n; + }; + }, + "./node_modules/core-js/modules/_math-log1p.js": function(e, t) { + e.exports = Math.log1p || function(e) { + return (e = +e) > -1e-8 && e < 1e-8 ? e - e * e / 2 : Math.log(1 + e); + }; + }, + "./node_modules/core-js/modules/_math-sign.js": function(e, t) { + e.exports = Math.sign || function(e) { + return 0 == (e = +e) || e != e ? e : e < 0 ? -1 : 1; + }; + }, + "./node_modules/core-js/modules/_object-create.js": function(e, t, n) { + var r = n("./node_modules/core-js/modules/_an-object.js"), o = n("./node_modules/core-js/modules/_object-dps.js"), a = n("./node_modules/core-js/modules/_enum-bug-keys.js"), i = n("./node_modules/core-js/modules/_shared-key.js")("IE_PROTO"), s = function() {}, l = function() { + var e, t = n("./node_modules/core-js/modules/_dom-create.js")("iframe"), r = a.length; + for (t.style.display = "none", n("./node_modules/core-js/modules/_html.js").appendChild(t), + t.src = "javascript:", (e = t.contentWindow.document).open(), e.write("\n if (val === '') return true;\n if (val === 'false') return false;\n if (val === 'true') return true;\n return val;\n}\n\nif (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n attrs.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n attr = _ref2[0],\n key = _ref2[1];\n\n var val = coerce(getAttrConfig(attr));\n\n if (val !== undefined && val !== null) {\n initial[key] = val;\n }\n });\n}\n\nvar _default = {\n familyPrefix: DEFAULT_FAMILY_PREFIX,\n replacementClass: DEFAULT_REPLACEMENT_CLASS,\n autoReplaceSvg: true,\n autoAddCss: true,\n autoA11y: true,\n searchPseudoElements: false,\n observeMutations: true,\n mutateApproach: 'async',\n keepOriginalSource: true,\n measurePerformance: false,\n showMissingIcons: true\n};\n\nvar _config = _objectSpread({}, _default, initial);\n\nif (!_config.autoReplaceSvg) _config.observeMutations = false;\n\nvar config = _objectSpread({}, _config);\n\nWINDOW.FontAwesomeConfig = config;\n\nvar w = WINDOW || {};\nif (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\nif (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\nif (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\nif (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\nvar namespace = w[NAMESPACE_IDENTIFIER];\n\nvar functions = [];\n\nvar listener = function listener() {\n DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n loaded = 1;\n functions.map(function (fn) {\n return fn();\n });\n};\n\nvar loaded = false;\n\nif (IS_DOM) {\n loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n}\n\nfunction domready (fn) {\n if (!IS_DOM) return;\n loaded ? setTimeout(fn, 0) : functions.push(fn);\n}\n\nvar PENDING = 'pending';\nvar SETTLED = 'settled';\nvar FULFILLED = 'fulfilled';\nvar REJECTED = 'rejected';\n\nvar NOOP = function NOOP() {};\n\nvar isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\nvar asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\nvar asyncQueue = [];\nvar asyncTimer;\n\nfunction asyncFlush() {\n // run promise callbacks\n for (var i = 0; i < asyncQueue.length; i++) {\n asyncQueue[i][0](asyncQueue[i][1]);\n } // reset async asyncQueue\n\n\n asyncQueue = [];\n asyncTimer = false;\n}\n\nfunction asyncCall(callback, arg) {\n asyncQueue.push([callback, arg]);\n\n if (!asyncTimer) {\n asyncTimer = true;\n asyncSetTimer(asyncFlush, 0);\n }\n}\n\nfunction invokeResolver(resolver, promise) {\n function resolvePromise(value) {\n resolve(promise, value);\n }\n\n function rejectPromise(reason) {\n reject(promise, reason);\n }\n\n try {\n resolver(resolvePromise, rejectPromise);\n } catch (e) {\n rejectPromise(e);\n }\n}\n\nfunction invokeCallback(subscriber) {\n var owner = subscriber.owner;\n var settled = owner._state;\n var value = owner._data;\n var callback = subscriber[settled];\n var promise = subscriber.then;\n\n if (typeof callback === 'function') {\n settled = FULFILLED;\n\n try {\n value = callback(value);\n } catch (e) {\n reject(promise, e);\n }\n }\n\n if (!handleThenable(promise, value)) {\n if (settled === FULFILLED) {\n resolve(promise, value);\n }\n\n if (settled === REJECTED) {\n reject(promise, value);\n }\n }\n}\n\nfunction handleThenable(promise, value) {\n var resolved;\n\n try {\n if (promise === value) {\n throw new TypeError('A promises callback cannot return that same promise.');\n }\n\n if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n // then should be retrieved only once\n var then = value.then;\n\n if (typeof then === 'function') {\n then.call(value, function (val) {\n if (!resolved) {\n resolved = true;\n\n if (value === val) {\n fulfill(promise, val);\n } else {\n resolve(promise, val);\n }\n }\n }, function (reason) {\n if (!resolved) {\n resolved = true;\n reject(promise, reason);\n }\n });\n return true;\n }\n }\n } catch (e) {\n if (!resolved) {\n reject(promise, e);\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction resolve(promise, value) {\n if (promise === value || !handleThenable(promise, value)) {\n fulfill(promise, value);\n }\n}\n\nfunction fulfill(promise, value) {\n if (promise._state === PENDING) {\n promise._state = SETTLED;\n promise._data = value;\n asyncCall(publishFulfillment, promise);\n }\n}\n\nfunction reject(promise, reason) {\n if (promise._state === PENDING) {\n promise._state = SETTLED;\n promise._data = reason;\n asyncCall(publishRejection, promise);\n }\n}\n\nfunction publish(promise) {\n promise._then = promise._then.forEach(invokeCallback);\n}\n\nfunction publishFulfillment(promise) {\n promise._state = FULFILLED;\n publish(promise);\n}\n\nfunction publishRejection(promise) {\n promise._state = REJECTED;\n publish(promise);\n\n if (!promise._handled && isNode) {\n global.process.emit('unhandledRejection', promise._data, promise);\n }\n}\n\nfunction notifyRejectionHandled(promise) {\n global.process.emit('rejectionHandled', promise);\n}\n/**\n * @class\n */\n\n\nfunction P(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n }\n\n if (this instanceof P === false) {\n throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n }\n\n this._then = [];\n invokeResolver(resolver, this);\n}\n\nP.prototype = {\n constructor: P,\n _state: PENDING,\n _then: null,\n _data: undefined,\n _handled: false,\n then: function then(onFulfillment, onRejection) {\n var subscriber = {\n owner: this,\n then: new this.constructor(NOOP),\n fulfilled: onFulfillment,\n rejected: onRejection\n };\n\n if ((onRejection || onFulfillment) && !this._handled) {\n this._handled = true;\n\n if (this._state === REJECTED && isNode) {\n asyncCall(notifyRejectionHandled, this);\n }\n }\n\n if (this._state === FULFILLED || this._state === REJECTED) {\n // already resolved, call callback async\n asyncCall(invokeCallback, subscriber);\n } else {\n // subscribe\n this._then.push(subscriber);\n }\n\n return subscriber.then;\n },\n catch: function _catch(onRejection) {\n return this.then(null, onRejection);\n }\n};\n\nP.all = function (promises) {\n if (!Array.isArray(promises)) {\n throw new TypeError('You must pass an array to Promise.all().');\n }\n\n return new P(function (resolve, reject) {\n var results = [];\n var remaining = 0;\n\n function resolver(index) {\n remaining++;\n return function (value) {\n results[index] = value;\n\n if (! --remaining) {\n resolve(results);\n }\n };\n }\n\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n\n if (promise && typeof promise.then === 'function') {\n promise.then(resolver(i), reject);\n } else {\n results[i] = promise;\n }\n }\n\n if (!remaining) {\n resolve(results);\n }\n });\n};\n\nP.race = function (promises) {\n if (!Array.isArray(promises)) {\n throw new TypeError('You must pass an array to Promise.race().');\n }\n\n return new P(function (resolve, reject) {\n for (var i = 0, promise; i < promises.length; i++) {\n promise = promises[i];\n\n if (promise && typeof promise.then === 'function') {\n promise.then(resolve, reject);\n } else {\n resolve(promise);\n }\n }\n });\n};\n\nP.resolve = function (value) {\n if (value && _typeof(value) === 'object' && value.constructor === P) {\n return value;\n }\n\n return new P(function (resolve) {\n resolve(value);\n });\n};\n\nP.reject = function (reason) {\n return new P(function (resolve, reject) {\n reject(reason);\n });\n};\n\nvar picked = typeof Promise === 'function' ? Promise : P;\n\nvar d = UNITS_IN_GRID;\nvar meaninglessTransform = {\n size: 16,\n x: 0,\n y: 0,\n rotate: 0,\n flipX: false,\n flipY: false\n};\n\nfunction isReserved(name) {\n return ~RESERVED_CLASSES.indexOf(name);\n}\nfunction insertCss(css) {\n if (!css || !IS_DOM) {\n return;\n }\n\n var style = DOCUMENT.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = css;\n var headChildren = DOCUMENT.head.childNodes;\n var beforeChild = null;\n\n for (var i = headChildren.length - 1; i > -1; i--) {\n var child = headChildren[i];\n var tagName = (child.tagName || '').toUpperCase();\n\n if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n beforeChild = child;\n }\n }\n\n DOCUMENT.head.insertBefore(style, beforeChild);\n return css;\n}\nvar idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nfunction nextUniqueId() {\n var size = 12;\n var id = '';\n\n while (size-- > 0) {\n id += idPool[Math.random() * 62 | 0];\n }\n\n return id;\n}\nfunction toArray(obj) {\n var array = [];\n\n for (var i = (obj || []).length >>> 0; i--;) {\n array[i] = obj[i];\n }\n\n return array;\n}\nfunction classArray(node) {\n if (node.classList) {\n return toArray(node.classList);\n } else {\n return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n return i;\n });\n }\n}\nfunction getIconName(familyPrefix, cls) {\n var parts = cls.split('-');\n var prefix = parts[0];\n var iconName = parts.slice(1).join('-');\n\n if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n return iconName;\n } else {\n return null;\n }\n}\nfunction htmlEscape(str) {\n return \"\".concat(str).replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''').replace(//g, '>');\n}\nfunction joinAttributes(attributes) {\n return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n }, '').trim();\n}\nfunction joinStyles(styles) {\n return Object.keys(styles || {}).reduce(function (acc, styleName) {\n return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n }, '');\n}\nfunction transformIsMeaningful(transform) {\n return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n}\nfunction transformForSvg(_ref) {\n var transform = _ref.transform,\n containerWidth = _ref.containerWidth,\n iconWidth = _ref.iconWidth;\n var outer = {\n transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n };\n var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n var inner = {\n transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n };\n var path = {\n transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n };\n return {\n outer: outer,\n inner: inner,\n path: path\n };\n}\nfunction transformForCss(_ref2) {\n var transform = _ref2.transform,\n _ref2$width = _ref2.width,\n width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n _ref2$height = _ref2.height,\n height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n _ref2$startCentered = _ref2.startCentered,\n startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n var val = '';\n\n if (startCentered && IS_IE) {\n val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n } else if (startCentered) {\n val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n } else {\n val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n }\n\n val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n val += \"rotate(\".concat(transform.rotate, \"deg) \");\n return val;\n}\n\nvar ALL_SPACE = {\n x: 0,\n y: 0,\n width: '100%',\n height: '100%'\n};\nfunction makeIconMasking (_ref) {\n var children = _ref.children,\n attributes = _ref.attributes,\n main = _ref.main,\n mask = _ref.mask,\n transform = _ref.transform;\n var mainWidth = main.width,\n mainPath = main.icon;\n var maskWidth = mask.width,\n maskPath = mask.icon;\n var trans = transformForSvg({\n transform: transform,\n containerWidth: maskWidth,\n iconWidth: mainWidth\n });\n var maskRect = {\n tag: 'rect',\n attributes: _objectSpread({}, ALL_SPACE, {\n fill: 'white'\n })\n };\n var maskInnerGroup = {\n tag: 'g',\n attributes: _objectSpread({}, trans.inner),\n children: [{\n tag: 'path',\n attributes: _objectSpread({}, mainPath.attributes, trans.path, {\n fill: 'black'\n })\n }]\n };\n var maskOuterGroup = {\n tag: 'g',\n attributes: _objectSpread({}, trans.outer),\n children: [maskInnerGroup]\n };\n var maskId = \"mask-\".concat(nextUniqueId());\n var clipId = \"clip-\".concat(nextUniqueId());\n var maskTag = {\n tag: 'mask',\n attributes: _objectSpread({}, ALL_SPACE, {\n id: maskId,\n maskUnits: 'userSpaceOnUse',\n maskContentUnits: 'userSpaceOnUse'\n }),\n children: [maskRect, maskOuterGroup]\n };\n var defs = {\n tag: 'defs',\n children: [{\n tag: 'clipPath',\n attributes: {\n id: clipId\n },\n children: [maskPath]\n }, maskTag]\n };\n children.push(defs, {\n tag: 'rect',\n attributes: _objectSpread({\n fill: 'currentColor',\n 'clip-path': \"url(#\".concat(clipId, \")\"),\n mask: \"url(#\".concat(maskId, \")\")\n }, ALL_SPACE)\n });\n return {\n children: children,\n attributes: attributes\n };\n}\n\nfunction makeIconStandard (_ref) {\n var children = _ref.children,\n attributes = _ref.attributes,\n main = _ref.main,\n transform = _ref.transform,\n styles = _ref.styles;\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n if (transformIsMeaningful(transform)) {\n var trans = transformForSvg({\n transform: transform,\n containerWidth: main.width,\n iconWidth: main.width\n });\n children.push({\n tag: 'g',\n attributes: _objectSpread({}, trans.outer),\n children: [{\n tag: 'g',\n attributes: _objectSpread({}, trans.inner),\n children: [{\n tag: main.icon.tag,\n children: main.icon.children,\n attributes: _objectSpread({}, main.icon.attributes, trans.path)\n }]\n }]\n });\n } else {\n children.push(main.icon);\n }\n\n return {\n children: children,\n attributes: attributes\n };\n}\n\nfunction asIcon (_ref) {\n var children = _ref.children,\n main = _ref.main,\n mask = _ref.mask,\n attributes = _ref.attributes,\n styles = _ref.styles,\n transform = _ref.transform;\n\n if (transformIsMeaningful(transform) && main.found && !mask.found) {\n var width = main.width,\n height = main.height;\n var offset = {\n x: width / height / 2,\n y: 0.5\n };\n attributes['style'] = joinStyles(_objectSpread({}, styles, {\n 'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n }));\n }\n\n return [{\n tag: 'svg',\n attributes: attributes,\n children: children\n }];\n}\n\nfunction asSymbol (_ref) {\n var prefix = _ref.prefix,\n iconName = _ref.iconName,\n children = _ref.children,\n attributes = _ref.attributes,\n symbol = _ref.symbol;\n var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n return [{\n tag: 'svg',\n attributes: {\n style: 'display: none;'\n },\n children: [{\n tag: 'symbol',\n attributes: _objectSpread({}, attributes, {\n id: id\n }),\n children: children\n }]\n }];\n}\n\nfunction makeInlineSvgAbstract(params) {\n var _params$icons = params.icons,\n main = _params$icons.main,\n mask = _params$icons.mask,\n prefix = params.prefix,\n iconName = params.iconName,\n transform = params.transform,\n symbol = params.symbol,\n title = params.title,\n extra = params.extra,\n _params$watchable = params.watchable,\n watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n var _ref = mask.found ? mask : main,\n width = _ref.width,\n height = _ref.height;\n\n var widthClass = \"fa-w-\".concat(Math.ceil(width / height * 16));\n var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n return extra.classes.indexOf(c) === -1;\n }).concat(extra.classes).join(' ');\n var content = {\n children: [],\n attributes: _objectSpread({}, extra.attributes, {\n 'data-prefix': prefix,\n 'data-icon': iconName,\n 'class': attrClass,\n 'role': extra.attributes.role || 'img',\n 'xmlns': 'http://www.w3.org/2000/svg',\n 'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n })\n };\n\n if (watchable) {\n content.attributes[DATA_FA_I2SVG] = '';\n }\n\n if (title) content.children.push({\n tag: 'title',\n attributes: {\n id: content.attributes['aria-labelledby'] || \"title-\".concat(nextUniqueId())\n },\n children: [title]\n });\n\n var args = _objectSpread({}, content, {\n prefix: prefix,\n iconName: iconName,\n main: main,\n mask: mask,\n transform: transform,\n symbol: symbol,\n styles: extra.styles\n });\n\n var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n children = _ref2.children,\n attributes = _ref2.attributes;\n\n args.children = children;\n args.attributes = attributes;\n\n if (symbol) {\n return asSymbol(args);\n } else {\n return asIcon(args);\n }\n}\nfunction makeLayersTextAbstract(params) {\n var content = params.content,\n width = params.width,\n height = params.height,\n transform = params.transform,\n title = params.title,\n extra = params.extra,\n _params$watchable2 = params.watchable,\n watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n var attributes = _objectSpread({}, extra.attributes, title ? {\n 'title': title\n } : {}, {\n 'class': extra.classes.join(' ')\n });\n\n if (watchable) {\n attributes[DATA_FA_I2SVG] = '';\n }\n\n var styles = _objectSpread({}, extra.styles);\n\n if (transformIsMeaningful(transform)) {\n styles['transform'] = transformForCss({\n transform: transform,\n startCentered: true,\n width: width,\n height: height\n });\n styles['-webkit-transform'] = styles['transform'];\n }\n\n var styleString = joinStyles(styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\nfunction makeLayersCounterAbstract(params) {\n var content = params.content,\n title = params.title,\n extra = params.extra;\n\n var attributes = _objectSpread({}, extra.attributes, title ? {\n 'title': title\n } : {}, {\n 'class': extra.classes.join(' ')\n });\n\n var styleString = joinStyles(extra.styles);\n\n if (styleString.length > 0) {\n attributes['style'] = styleString;\n }\n\n var val = [];\n val.push({\n tag: 'span',\n attributes: attributes,\n children: [content]\n });\n\n if (title) {\n val.push({\n tag: 'span',\n attributes: {\n class: 'sr-only'\n },\n children: [title]\n });\n }\n\n return val;\n}\n\nvar noop$1 = function noop() {};\n\nvar p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n mark: noop$1,\n measure: noop$1\n};\nvar preamble = \"FA \\\"5.9.0\\\"\";\n\nvar begin = function begin(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n return function () {\n return end(name);\n };\n};\n\nvar end = function end(name) {\n p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n};\n\nvar perf = {\n begin: begin,\n end: end\n};\n\n/**\n * Internal helper to bind a function known to have 4 arguments\n * to a given context.\n */\n\nvar bindInternal4 = function bindInternal4(func, thisContext) {\n return function (a, b, c, d) {\n return func.call(thisContext, a, b, c, d);\n };\n};\n\n/**\n * # Reduce\n *\n * A fast object ` + ("`" + `.reduce()`)) + ("`" + (` implementation.\n *\n * @param {Object} subject The object to reduce over.\n * @param {Function} fn The reducer function.\n * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0].\n * @param {Object} thisContext The context for the reducer.\n * @return {mixed} The final result.\n */\n\n\nvar reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n var keys = Object.keys(subject),\n length = keys.length,\n iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n i,\n key,\n result;\n\n if (initialValue === undefined) {\n i = 1;\n result = subject[keys[0]];\n } else {\n i = 0;\n result = initialValue;\n }\n\n for (; i < length; i++) {\n key = keys[i];\n result = iterator(result, subject[key], key, subject);\n }\n\n return result;\n};\n\nfunction toHex(unicode) {\n var result = '';\n\n for (var i = 0; i < unicode.length; i++) {\n var hex = unicode.charCodeAt(i).toString(16);\n result += ('000' + hex).slice(-4);\n }\n\n return result;\n}\n\nfunction defineIcons(prefix, icons) {\n var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var _params$skipHooks = params.skipHooks,\n skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n var icon = icons[iconName];\n var expanded = !!icon.icon;\n\n if (expanded) {\n acc[icon.iconName] = icon.icon;\n } else {\n acc[iconName] = icon;\n }\n\n return acc;\n }, {});\n\n if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n namespace.hooks.addPack(prefix, normalized);\n } else {\n namespace.styles[prefix] = _objectSpread({}, namespace.styles[prefix] || {}, normalized);\n }\n /**\n * Font Awesome 4 used the prefix of ` + "`"))) + ((`fa` + ("`" + ` for all icons. With the introduction\n * of new styles we needed to differentiate between them. Prefix `)) + ("`" + (`fa` + "`")))) + (((` is now an alias\n * for ` + ("`" + `fas`)) + ("`" + (` so we'll easy the upgrade process for our users by automatically defining\n * this as well.\n */\n\n\n if (prefix === 'fas') {\n defineIcons('fa', icons);\n }\n}\n\nvar styles = namespace.styles,\n shims = namespace.shims;\nvar _byUnicode = {};\nvar _byLigature = {};\nvar _byOldName = {};\nvar build = function build() {\n var lookup = function lookup(reducer) {\n return reduce(styles, function (o, style, prefix) {\n o[prefix] = reduce(style, reducer, {});\n return o;\n }, {});\n };\n\n _byUnicode = lookup(function (acc, icon, iconName) {\n if (icon[3]) {\n acc[icon[3]] = iconName;\n }\n\n return acc;\n });\n _byLigature = lookup(function (acc, icon, iconName) {\n var ligatures = icon[2];\n acc[iconName] = iconName;\n ligatures.forEach(function (ligature) {\n acc[ligature] = iconName;\n });\n return acc;\n });\n var hasRegular = 'far' in styles;\n _byOldName = reduce(shims, function (acc, shim) {\n var oldName = shim[0];\n var prefix = shim[1];\n var iconName = shim[2];\n\n if (prefix === 'far' && !hasRegular) {\n prefix = 'fas';\n }\n\n acc[oldName] = {\n prefix: prefix,\n iconName: iconName\n };\n return acc;\n }, {});\n};\nbuild();\nfunction byUnicode(prefix, unicode) {\n return (_byUnicode[prefix] || {})[unicode];\n}\nfunction byLigature(prefix, ligature) {\n return (_byLigature[prefix] || {})[ligature];\n}\nfunction byOldName(name) {\n return _byOldName[name] || {\n prefix: null,\n iconName: null\n };\n}\n\nvar styles$1 = namespace.styles;\nvar emptyCanonicalIcon = function emptyCanonicalIcon() {\n return {\n prefix: null,\n iconName: null,\n rest: []\n };\n};\nfunction getCanonicalIcon(values) {\n return values.reduce(function (acc, cls) {\n var iconName = getIconName(config.familyPrefix, cls);\n\n if (styles$1[cls]) {\n acc.prefix = cls;\n } else if (config.autoFetchSvg && ['fas', 'far', 'fal', 'fab', 'fa'].indexOf(cls) > -1) {\n acc.prefix = cls;\n } else if (iconName) {\n var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n acc.iconName = shim.iconName || iconName;\n acc.prefix = shim.prefix || acc.prefix;\n } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n acc.rest.push(cls);\n }\n\n return acc;\n }, emptyCanonicalIcon());\n}\nfunction iconFromMapping(mapping, prefix, iconName) {\n if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n return {\n prefix: prefix,\n iconName: iconName,\n icon: mapping[prefix][iconName]\n };\n }\n}\n\nfunction toHtml(abstractNodes) {\n var tag = abstractNodes.tag,\n _abstractNodes$attrib = abstractNodes.attributes,\n attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n _abstractNodes$childr = abstractNodes.children,\n children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n if (typeof abstractNodes === 'string') {\n return htmlEscape(abstractNodes);\n } else {\n return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"\");\n }\n}\n\nvar noop$2 = function noop() {};\n\nfunction isWatched(node) {\n var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n return typeof i2svg === 'string';\n}\n\nfunction getMutator() {\n if (config.autoReplaceSvg === true) {\n return mutators.replace;\n }\n\n var mutator = mutators[config.autoReplaceSvg];\n return mutator || mutators.replace;\n}\n\nvar mutators = {\n replace: function replace(mutation) {\n var node = mutation[0];\n var abstract = mutation[1];\n var newOuterHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n\n if (node.parentNode && node.outerHTML) {\n node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"\") : '');\n } else if (node.parentNode) {\n var newNode = document.createElement('span');\n node.parentNode.replaceChild(newNode, node);\n newNode.outerHTML = newOuterHTML;\n }\n },\n nest: function nest(mutation) {\n var node = mutation[0];\n var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n // Short-circuit to the standard replacement\n\n if (~classArray(node).indexOf(config.replacementClass)) {\n return mutators.replace(mutation);\n }\n\n var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n delete abstract[0].attributes.style;\n var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n if (cls === config.replacementClass || cls.match(forSvg)) {\n acc.toSvg.push(cls);\n } else {\n acc.toNode.push(cls);\n }\n\n return acc;\n }, {\n toNode: [],\n toSvg: []\n });\n abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n var newInnerHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n node.setAttribute('class', splitClasses.toNode.join(' '));\n node.setAttribute(DATA_FA_I2SVG, '');\n node.innerHTML = newInnerHTML;\n }\n};\n\nfunction performOperationSync(op) {\n op();\n}\n\nfunction perform(mutations, callback) {\n var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n if (mutations.length === 0) {\n callbackFunction();\n } else {\n var frame = performOperationSync;\n\n if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n frame = WINDOW.requestAnimationFrame || performOperationSync;\n }\n\n frame(function () {\n var mutator = getMutator();\n var mark = perf.begin('mutate');\n mutations.map(mutator);\n mark();\n callbackFunction();\n });\n }\n}\nvar disabled = false;\nfunction disableObservation() {\n disabled = true;\n}\nfunction enableObservation() {\n disabled = false;\n}\nvar mo = null;\nfunction observe(options) {\n if (!MUTATION_OBSERVER) {\n return;\n }\n\n if (!config.observeMutations) {\n return;\n }\n\n var treeCallback = options.treeCallback,\n nodeCallback = options.nodeCallback,\n pseudoElementsCallback = options.pseudoElementsCallback,\n _options$observeMutat = options.observeMutationsRoot,\n observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n mo = new MUTATION_OBSERVER(function (objects) {\n if (disabled) return;\n toArray(objects).forEach(function (mutationRecord) {\n if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n if (config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target);\n }\n\n treeCallback(mutationRecord.target);\n }\n\n if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n pseudoElementsCallback(mutationRecord.target.parentNode);\n }\n\n if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n if (mutationRecord.attributeName === 'class') {\n var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n prefix = _getCanonicalIcon.prefix,\n iconName = _getCanonicalIcon.iconName;\n\n if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n } else {\n nodeCallback(mutationRecord.target);\n }\n }\n });\n });\n if (!IS_DOM) return;\n mo.observe(observeMutationsRoot, {\n childList: true,\n attributes: true,\n characterData: true,\n subtree: true\n });\n}\nfunction disconnect() {\n if (!mo) return;\n mo.disconnect();\n}\n\nfunction styleParser (node) {\n var style = node.getAttribute('style');\n var val = [];\n\n if (style) {\n val = style.split(';').reduce(function (acc, style) {\n var styles = style.split(':');\n var prop = styles[0];\n var value = styles.slice(1);\n\n if (prop && value.length > 0) {\n acc[prop] = value.join(':').trim();\n }\n\n return acc;\n }, {});\n }\n\n return val;\n}\n\nfunction classParser (node) {\n var existingPrefix = node.getAttribute('data-prefix');\n var existingIconName = node.getAttribute('data-icon');\n var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n var val = getCanonicalIcon(classArray(node));\n\n if (existingPrefix && existingIconName) {\n val.prefix = existingPrefix;\n val.iconName = existingIconName;\n }\n\n if (val.prefix && innerText.length > 1) {\n val.iconName = byLigature(val.prefix, node.innerText);\n } else if (val.prefix && innerText.length === 1) {\n val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n }\n\n return val;\n}\n\nvar parseTransformString = function parseTransformString(transformString) {\n var transform = {\n size: 16,\n x: 0,\n y: 0,\n flipX: false,\n flipY: false,\n rotate: 0\n };\n\n if (!transformString) {\n return transform;\n } else {\n return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n var parts = n.toLowerCase().split('-');\n var first = parts[0];\n var rest = parts.slice(1).join('-');\n\n if (first && rest === 'h') {\n acc.flipX = true;\n return acc;\n }\n\n if (first && rest === 'v') {\n acc.flipY = true;\n return acc;\n }\n\n rest = parseFloat(rest);\n\n if (isNaN(rest)) {\n return acc;\n }\n\n switch (first) {\n case 'grow':\n acc.size = acc.size + rest;\n break;\n\n case 'shrink':\n acc.size = acc.size - rest;\n break;\n\n case 'left':\n acc.x = acc.x - rest;\n break;\n\n case 'right':\n acc.x = acc.x + rest;\n break;\n\n case 'up':\n acc.y = acc.y - rest;\n break;\n\n case 'down':\n acc.y = acc.y + rest;\n break;\n\n case 'rotate':\n acc.rotate = acc.rotate + rest;\n break;\n }\n\n return acc;\n }, transform);\n }\n};\nfunction transformParser (node) {\n return parseTransformString(node.getAttribute('data-fa-transform'));\n}\n\nfunction symbolParser (node) {\n var symbol = node.getAttribute('data-fa-symbol');\n return symbol === null ? false : symbol === '' ? true : symbol;\n}\n\nfunction attributesParser (node) {\n var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n if (acc.name !== 'class' && acc.name !== 'style') {\n acc[attr.name] = attr.value;\n }\n\n return acc;\n }, {});\n var title = node.getAttribute('title');\n\n if (config.autoA11y) {\n if (title) {\n extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(nextUniqueId());\n } else {\n extraAttributes['aria-hidden'] = 'true';\n extraAttributes['focusable'] = 'false';\n }\n }\n\n return extraAttributes;\n}\n\nfunction maskParser (node) {\n var mask = node.getAttribute('data-fa-mask');\n\n if (!mask) {\n return emptyCanonicalIcon();\n } else {\n return getCanonicalIcon(mask.split(' ').map(function (i) {\n return i.trim();\n }));\n }\n}\n\nfunction blankMeta() {\n return {\n iconName: null,\n title: null,\n prefix: null,\n transform: meaninglessTransform,\n symbol: false,\n mask: null,\n extra: {\n classes: [],\n styles: {},\n attributes: {}\n }\n };\n}\nfunction parseMeta(node) {\n var _classParser = classParser(node),\n iconName = _classParser.iconName,\n prefix = _classParser.prefix,\n extraClasses = _classParser.rest;\n\n var extraStyles = styleParser(node);\n var transform = transformParser(node);\n var symbol = symbolParser(node);\n var extraAttributes = attributesParser(node);\n var mask = maskParser(node);\n return {\n iconName: iconName,\n title: node.getAttribute('title'),\n prefix: prefix,\n transform: transform,\n symbol: symbol,\n mask: mask,\n extra: {\n classes: extraClasses,\n styles: extraStyles,\n attributes: extraAttributes\n }\n };\n}\n\nfunction MissingIcon(error) {\n this.name = 'MissingIcon';\n this.message = error || 'Icon unavailable';\n this.stack = new Error().stack;\n}\nMissingIcon.prototype = Object.create(Error.prototype);\nMissingIcon.prototype.constructor = MissingIcon;\n\nvar FILL = {\n fill: 'currentColor'\n};\nvar ANIMATION_BASE = {\n attributeType: 'XML',\n repeatCount: 'indefinite',\n dur: '2s'\n};\nvar RING = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n })\n};\n\nvar OPACITY_ANIMATE = _objectSpread({}, ANIMATION_BASE, {\n attributeName: 'opacity'\n});\n\nvar DOT = {\n tag: 'circle',\n attributes: _objectSpread({}, FILL, {\n cx: '256',\n cy: '364',\n r: '28'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, ANIMATION_BASE, {\n attributeName: 'r',\n values: '28;14;28;28;14;28;'\n })\n }, {\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '1;0;1;1;0;1;'\n })\n }]\n};\nvar QUESTION = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n opacity: '1',\n d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '1;0;0;0;0;1;'\n })\n }]\n};\nvar EXCLAMATION = {\n tag: 'path',\n attributes: _objectSpread({}, FILL, {\n opacity: '0',\n d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n }),\n children: [{\n tag: 'animate',\n attributes: _objectSpread({}, OPACITY_ANIMATE, {\n values: '0;0;1;1;0;0;'\n })\n }]\n};\nvar missing = {\n tag: 'g',\n children: [RING, DOT, QUESTION, EXCLAMATION]\n};\n\nvar styles$2 = namespace.styles;\nfunction findIcon(iconName, prefix) {\n return new picked(function (resolve, reject) {\n var val = {\n found: false,\n width: 512,\n height: 512,\n icon: missing\n };\n\n if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n var icon = styles$2[prefix][iconName];\n var width = icon[0];\n var height = icon[1];\n var vectorData = icon.slice(4);\n val = {\n found: true,\n width: width,\n height: height,\n icon: {\n tag: 'path',\n attributes: {\n fill: 'currentColor',\n d: vectorData[0]\n }\n }\n };\n return resolve(val);\n }\n\n if (iconName && prefix && !config.showMissingIcons) {\n reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n } else {\n resolve(val);\n }\n });\n}\n\nvar styles$3 = namespace.styles;\n\nfunction generateSvgReplacementMutation(node, nodeMeta) {\n var iconName = nodeMeta.iconName,\n title = nodeMeta.title,\n prefix = nodeMeta.prefix,\n transform = nodeMeta.transform,\n symbol = nodeMeta.symbol,\n mask = nodeMeta.mask,\n extra = nodeMeta.extra;\n return new picked(function (resolve, reject) {\n picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n main = _ref2[0],\n mask = _ref2[1];\n\n resolve([node, makeInlineSvgAbstract({\n icons: {\n main: main,\n mask: mask\n },\n prefix: prefix,\n iconName: iconName,\n transform: transform,\n symbol: symbol,\n mask: mask,\n title: title,\n extra: extra,\n watchable: true\n })]);\n });\n });\n}\n\nfunction generateLayersText(node, nodeMeta) {\n var title = nodeMeta.title,\n transform = nodeMeta.transform,\n extra = nodeMeta.extra;\n var width = null;\n var height = null;\n\n if (IS_IE) {\n var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n var boundingClientRect = node.getBoundingClientRect();\n width = boundingClientRect.width / computedFontSize;\n height = boundingClientRect.height / computedFontSize;\n }\n\n if (config.autoA11y && !title) {\n extra.attributes['aria-hidden'] = 'true';\n }\n\n return picked.resolve([node, makeLayersTextAbstract({\n content: node.innerHTML,\n width: width,\n height: height,\n transform: transform,\n title: title,\n extra: extra,\n watchable: true\n })]);\n}\n\nfunction generateMutation(node) {\n var nodeMeta = parseMeta(node);\n\n if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n return generateLayersText(node, nodeMeta);\n } else {\n return generateSvgReplacementMutation(node, nodeMeta);\n }\n}\n\nfunction onTree(root) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n if (!IS_DOM) return;\n var htmlClassList = DOCUMENT.documentElement.classList;\n\n var hclAdd = function hclAdd(suffix) {\n return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var hclRemove = function hclRemove(suffix) {\n return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n };\n\n var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n })).join(', ');\n\n if (prefixesDomQuery.length === 0) {\n return;\n }\n\n var candidates = [];\n\n try {\n candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n } catch (e) {// noop\n }\n\n if (candidates.length > 0) {\n hclAdd('pending');\n hclRemove('complete');\n } else {\n return;\n }\n\n var mark = perf.begin('onTree');\n var mutations = candidates.reduce(function (acc, node) {\n try {\n var mutation = generateMutation(node);\n\n if (mutation) {\n acc.push(mutation);\n }\n } catch (e) {\n if (!PRODUCTION) {\n if (e instanceof MissingIcon) {\n console.error(e);\n }\n }\n }\n\n return acc;\n }, []);\n return new picked(function (resolve, reject) {\n picked.all(mutations).then(function (resolvedMutations) {\n perform(resolvedMutations, function () {\n hclAdd('active');\n hclAdd('complete');\n hclRemove('pending');\n if (typeof callback === 'function') callback();\n mark();\n resolve();\n });\n }).catch(function () {\n mark();\n reject();\n });\n });\n}\nfunction onNode(node) {\n var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n generateMutation(node).then(function (mutation) {\n if (mutation) {\n perform([mutation], callback);\n }\n });\n}\n\nfunction replaceForPosition(node, position) {\n var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n return new picked(function (resolve, reject) {\n if (node.getAttribute(pendingAttribute) !== null) {\n // This node is already being processed\n return resolve();\n }\n\n var children = toArray(node.children);\n var alreadyProcessedPseudoElement = children.filter(function (c) {\n return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n })[0];\n var styles = WINDOW.getComputedStyle(node, position);\n var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n var fontWeight = styles.getPropertyValue('font-weight');\n\n if (alreadyProcessedPseudoElement && !fontFamily) {\n // If we've already processed it but the current computed style does not result in a font-family,\n // that probably means that a class name that was previously present to make the icon has been\n // removed. So we now should delete the icon.\n node.removeChild(alreadyProcessedPseudoElement);\n return resolve();\n } else if (fontFamily) {\n var content = styles.getPropertyValue('content');\n var prefix = ~['Light', 'Regular', 'Solid', 'Brands'].indexOf(fontFamily[1]) ? STYLE_TO_PREFIX[fontFamily[1].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n var hexValue = toHex(content.length === 3 ? content.substr(1, 1) : content);\n var iconName = byUnicode(prefix, hexValue);\n var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n // already done so with the same prefix and iconName\n\n if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n node.setAttribute(pendingAttribute, iconIdentifier);\n\n if (alreadyProcessedPseudoElement) {\n // Delete the old one, since we're replacing it with a new one\n node.removeChild(alreadyProcessedPseudoElement);\n }\n\n var meta = blankMeta();\n var extra = meta.extra;\n extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n findIcon(iconName, prefix).then(function (main) {\n var abstract = makeInlineSvgAbstract(_objectSpread({}, meta, {\n icons: {\n main: main,\n mask: emptyCanonicalIcon()\n },\n prefix: prefix,\n iconName: iconIdentifier,\n extra: extra,\n watchable: true\n }));\n var element = DOCUMENT.createElement('svg');\n\n if (position === ':before') {\n node.insertBefore(element, node.firstChild);\n } else {\n node.appendChild(element);\n }\n\n element.outerHTML = abstract.map(function (a) {\n return toHtml(a);\n }).join('\\n');\n node.removeAttribute(pendingAttribute);\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n } else {\n resolve();\n }\n });\n}\n\nfunction replace(node) {\n return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n}\n\nfunction processable(node) {\n return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n}\n\nfunction searchPseudoElements (root) {\n if (!IS_DOM) return;\n return new picked(function (resolve, reject) {\n var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n var end = perf.begin('searchPseudoElements');\n disableObservation();\n picked.all(operations).then(function () {\n end();\n enableObservation();\n resolve();\n }).catch(function () {\n end();\n enableObservation();\n reject();\n });\n });\n}\n\nvar baseStyles = \"svg:not(:root).svg-inline--fa {\\n overflow: visible;\\n}\\n\\n.svg-inline--fa {\\n display: inline-block;\\n font-size: inherit;\\n height: 1em;\\n overflow: visible;\\n vertical-align: -0.125em;\\n}\\n.svg-inline--fa.fa-lg {\\n vertical-align: -0.225em;\\n}\\n.svg-inline--fa.fa-w-1 {\\n width: 0.0625em;\\n}\\n.svg-inline--fa.fa-w-2 {\\n width: 0.125em;\\n}\\n.svg-inline--fa.fa-w-3 {\\n width: 0.1875em;\\n}\\n.svg-inline--fa.fa-w-4 {\\n width: 0.25em;\\n}\\n.svg-inline--fa.fa-w-5 {\\n width: 0.3125em;\\n}\\n.svg-inline--fa.fa-w-6 {\\n width: 0.375em;\\n}\\n.svg-inline--fa.fa-w-7 {\\n width: 0.4375em;\\n}\\n.svg-inline--fa.fa-w-8 {\\n width: 0.5em;\\n}\\n.svg-inline--fa.fa-w-9 {\\n width: 0.5625em;\\n}\\n.svg-inline--fa.fa-w-10 {\\n width: 0.625em;\\n}\\n.svg-inline--fa.fa-w-11 {\\n width: 0.6875em;\\n}\\n.svg-inline--fa.fa-w-12 {\\n width: 0.75em;\\n}\\n.svg-inline--fa.fa-w-13 {\\n width: 0.8125em;\\n}\\n.svg-inline--fa.fa-w-14 {\\n width: 0.875em;\\n}\\n.svg-inline--fa.fa-w-15 {\\n width: 0.9375em;\\n}\\n.svg-inline--fa.fa-w-16 {\\n width: 1em;\\n}\\n.svg-inline--fa.fa-w-17 {\\n width: 1.0625em;\\n}\\n.svg-inline--fa.fa-w-18 {\\n width: 1.125em;\\n}\\n.svg-inline--fa.fa-w-19 {\\n width: 1.1875em;\\n}\\n.svg-inline--fa.fa-w-20 {\\n width: 1.25em;\\n}\\n.svg-inline--fa.fa-pull-left {\\n margin-right: 0.3em;\\n width: auto;\\n}\\n.svg-inline--fa.fa-pull-right {\\n margin-left: 0.3em;\\n width: auto;\\n}\\n.svg-inline--fa.fa-border {\\n height: 1.5em;\\n}\\n.svg-inline--fa.fa-li {\\n width: 2em;\\n}\\n.svg-inline--fa.fa-fw {\\n width: 1.25em;\\n}\\n\\n.fa-layers svg.svg-inline--fa {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n}\\n\\n.fa-layers {\\n display: inline-block;\\n height: 1em;\\n position: relative;\\n text-align: center;\\n vertical-align: -0.125em;\\n width: 1em;\\n}\\n.fa-layers svg.svg-inline--fa {\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-counter, .fa-layers-text {\\n display: inline-block;\\n position: absolute;\\n text-align: center;\\n}\\n\\n.fa-layers-text {\\n left: 50%;\\n top: 50%;\\n -webkit-transform: translate(-50%, -50%);\\n transform: translate(-50%, -50%);\\n -webkit-transform-origin: center center;\\n transform-origin: center center;\\n}\\n\\n.fa-layers-counter {\\n background-color: #ff253a;\\n border-radius: 1em;\\n -webkit-box-sizing: border-box;\\n box-sizing: border-box;\\n color: #fff;\\n height: 1.5em;\\n line-height: 1;\\n max-width: 5em;\\n min-width: 1.5em;\\n overflow: hidden;\\n padding: 0.25em;\\n right: 0;\\n text-overflow: ellipsis;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-bottom-right {\\n bottom: 0;\\n right: 0;\\n top: auto;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: bottom right;\\n transform-origin: bottom right;\\n}\\n\\n.fa-layers-bottom-left {\\n bottom: 0;\\n left: 0;\\n right: auto;\\n top: auto;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: bottom left;\\n transform-origin: bottom left;\\n}\\n\\n.fa-layers-top-right {\\n right: 0;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top right;\\n transform-origin: top right;\\n}\\n\\n.fa-layers-top-left {\\n left: 0;\\n right: auto;\\n top: 0;\\n -webkit-transform: scale(0.25);\\n transform: scale(0.25);\\n -webkit-transform-origin: top left;\\n transform-origin: top left;\\n}\\n\\n.fa-lg {\\n font-size: 1.3333333333em;\\n line-height: 0.75em;\\n vertical-align: -0.0667em;\\n}\\n\\n.fa-xs {\\n font-size: 0.75em;\\n}\\n\\n.fa-sm {\\n font-size: 0.875em;\\n}\\n\\n.fa-1x {\\n font-size: 1em;\\n}\\n\\n.fa-2x {\\n font-size: 2em;\\n}\\n\\n.fa-3x {\\n font-size: 3em;\\n}\\n\\n.fa-4x {\\n font-size: 4em;\\n}\\n\\n.fa-5x {\\n font-size: 5em;\\n}\\n\\n.fa-6x {\\n font-size: 6em;\\n}\\n\\n.fa-7x {\\n font-size: 7em;\\n}\\n\\n.fa-8x {\\n font-size: 8em;\\n}\\n\\n.fa-9x {\\n font-size: 9em;\\n}\\n\\n.fa-10x {\\n font-size: 10em;\\n}\\n\\n.fa-fw {\\n text-align: center;\\n width: 1.25em;\\n}\\n\\n.fa-ul {\\n list-style-type: none;\\n margin-left: 2.5em;\\n padding-left: 0;\\n}\\n.fa-ul > li {\\n position: relative;\\n}\\n\\n.fa-li {\\n left: -2em;\\n position: absolute;\\n text-align: center;\\n width: 2em;\\n line-height: inherit;\\n}\\n\\n.fa-border {\\n border: solid 0.08em #eee;\\n border-radius: 0.1em;\\n padding: 0.2em 0.25em 0.15em;\\n}\\n\\n.fa-pull-left {\\n float: left;\\n}\\n\\n.fa-pull-right {\\n float: right;\\n}\\n\\n.fa.fa-pull-left,\\n.fas.fa-pull-left,\\n.far.fa-pull-left,\\n.fal.fa-pull-left,\\n.fab.fa-pull-left {\\n margin-right: 0.3em;\\n}\\n.fa.fa-pull-right,\\n.fas.fa-pull-right,\\n.far.fa-pull-right,\\n.fal.fa-pull-right,\\n.fab.fa-pull-right {\\n margin-left: 0.3em;\\n}\\n\\n.fa-spin {\\n -webkit-animation: fa-spin 2s infinite linear;\\n animation: fa-spin 2s infinite linear;\\n}\\n\\n.fa-pulse {\\n -webkit-animation: fa-spin 1s infinite steps(8);\\n animation: fa-spin 1s infinite steps(8);\\n}\\n\\n@-webkit-keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n\\n@keyframes fa-spin {\\n 0% {\\n -webkit-transform: rotate(0deg);\\n transform: rotate(0deg);\\n }\\n 100% {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n.fa-rotate-90 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\\\";\\n -webkit-transform: rotate(90deg);\\n transform: rotate(90deg);\\n}\\n\\n.fa-rotate-180 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\\\";\\n -webkit-transform: rotate(180deg);\\n transform: rotate(180deg);\\n}\\n\\n.fa-rotate-270 {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\\\";\\n -webkit-transform: rotate(270deg);\\n transform: rotate(270deg);\\n}\\n\\n.fa-flip-horizontal {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\\\";\\n -webkit-transform: scale(-1, 1);\\n transform: scale(-1, 1);\\n}\\n\\n.fa-flip-vertical {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n -webkit-transform: scale(1, -1);\\n transform: scale(1, -1);\\n}\\n\\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\\n -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n -webkit-transform: scale(-1, -1);\\n transform: scale(-1, -1);\\n}\\n\\n:root .fa-rotate-90,\\n:root .fa-rotate-180,\\n:root .fa-rotate-270,\\n:root .fa-flip-horizontal,\\n:root .fa-flip-vertical,\\n:root .fa-flip-both {\\n -webkit-filter: none;\\n filter: none;\\n}\\n\\n.fa-stack {\\n display: inline-block;\\n height: 2em;\\n position: relative;\\n width: 2.5em;\\n}\\n\\n.fa-stack-1x,\\n.fa-stack-2x {\\n bottom: 0;\\n left: 0;\\n margin: auto;\\n position: absolute;\\n right: 0;\\n top: 0;\\n}\\n\\n.svg-inline--fa.fa-stack-1x {\\n height: 1em;\\n width: 1.25em;\\n}\\n.svg-inline--fa.fa-stack-2x {\\n height: 2em;\\n width: 2.5em;\\n}\\n\\n.fa-inverse {\\n color: #fff;\\n}\\n\\n.sr-only {\\n border: 0;\\n clip: rect(0, 0, 0, 0);\\n height: 1px;\\n margin: -1px;\\n overflow: hidden;\\n padding: 0;\\n position: absolute;\\n width: 1px;\\n}\\n\\n.sr-only-focusable:active, .sr-only-focusable:focus {\\n clip: auto;\\n height: auto;\\n margin: 0;\\n overflow: visible;\\n position: static;\\n width: auto;\\n}\";\n\nfunction css () {\n var dfp = DEFAULT_FAMILY_PREFIX;\n var drc = DEFAULT_REPLACEMENT_CLASS;\n var fp = config.familyPrefix;\n var rc = config.replacementClass;\n var s = baseStyles;\n\n if (fp !== dfp || rc !== drc) {\n var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n }\n\n return s;\n}\n\nvar Library =\n/*#__PURE__*/\nfunction () {\n function Library() {\n _classCallCheck(this, Library);\n\n this.definitions = {};\n }\n\n _createClass(Library, [{\n key: \"add\",\n value: function add() {\n var _this = this;\n\n for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n definitions[_key] = arguments[_key];\n }\n\n var additions = definitions.reduce(this._pullDefinitions, {});\n Object.keys(additions).forEach(function (key) {\n _this.definitions[key] = _objectSpread({}, _this.definitions[key] || {}, additions[key]);\n defineIcons(key, additions[key]);\n build();\n });\n }\n }, {\n key: \"reset\",\n value: function reset() {\n this.definitions = {};\n }\n }, {\n key: \"_pullDefinitions\",\n value: function _pullDefinitions(additions, definition) {\n var normalized = definition.prefix && definition.iconName && definition.icon ? {\n 0: definition\n } : definition;\n Object.keys(normalized).map(function (key) {\n var _normalized$key = normalized[key],\n prefix = _normalized$key.prefix,\n iconName = _normalized$key.iconName,\n icon = _normalized$key.icon;\n if (!additions[prefix]) additions[prefix] = {};\n additions[prefix][iconName] = icon;\n });\n return additions;\n }\n }]);\n\n return Library;\n}();\n\nfunction prepIcon(icon) {\n var width = icon[0];\n var height = icon[1];\n var vectorData = icon.slice(4);\n return {\n found: true,\n width: width,\n height: height,\n icon: {\n tag: 'path',\n attributes: {\n fill: 'currentColor',\n d: vectorData[0]\n }\n }\n };\n}\n\nfunction ensureCss() {\n if (config.autoAddCss && !_cssInserted) {\n insertCss(css());\n\n _cssInserted = true;\n }\n}\n\nfunction apiObject(val, abstractCreator) {\n Object.defineProperty(val, 'abstract', {\n get: abstractCreator\n });\n Object.defineProperty(val, 'html', {\n get: function get() {\n return val.abstract.map(function (a) {\n return toHtml(a);\n });\n }\n });\n Object.defineProperty(val, 'node', {\n get: function get() {\n if (!IS_DOM) return;\n var container = DOCUMENT.createElement('div');\n container.innerHTML = val.html;\n return container.children;\n }\n });\n return val;\n}\n\nfunction findIconDefinition(iconLookup) {\n var _iconLookup$prefix = iconLookup.prefix,\n prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n iconName = iconLookup.iconName;\n if (!iconName) return;\n return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n}\n\nfunction resolveIcons(next) {\n return function (maybeIconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n var mask = params.mask;\n\n if (mask) {\n mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n }\n\n return next(iconDefinition, _objectSpread({}, params, {\n mask: mask\n }));\n };\n}\n\nvar library = new Library();\nvar noAuto = function noAuto() {\n config.autoReplaceSvg = false;\n config.observeMutations = false;\n disconnect();\n};\nvar _cssInserted = false;\nvar dom = {\n i2svg: function i2svg() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n if (IS_DOM) {\n ensureCss();\n var _params$node = params.node,\n node = _params$node === void 0 ? DOCUMENT : _params$node,\n _params$callback = params.callback,\n callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n if (config.searchPseudoElements) {\n searchPseudoElements(node);\n }\n\n return onTree(node, callback);\n } else {\n return picked.reject('Operation requires a DOM of some kind.');\n }\n },\n css: css,\n insertCss: function insertCss$$1() {\n if (!_cssInserted) {\n insertCss(css());\n\n _cssInserted = true;\n }\n },\n watch: function watch() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n observeMutationsRoot = params.observeMutationsRoot;\n\n if (config.autoReplaceSvg === false) {\n config.autoReplaceSvg = true;\n }\n\n config.observeMutations = true;\n domready(function () {\n autoReplace({\n autoReplaceSvgRoot: autoReplaceSvgRoot\n });\n observe({\n treeCallback: onTree,\n nodeCallback: onNode,\n pseudoElementsCallback: searchPseudoElements,\n observeMutationsRoot: observeMutationsRoot\n });\n });\n }\n};\nvar parse = {\n transform: function transform(transformString) {\n return parseTransformString(transformString);\n }\n};\nvar icon = resolveIcons(function (iconDefinition) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform = params.transform,\n transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n _params$symbol = params.symbol,\n symbol = _params$symbol === void 0 ? false : _params$symbol,\n _params$mask = params.mask,\n mask = _params$mask === void 0 ? null : _params$mask,\n _params$title = params.title,\n title = _params$title === void 0 ? null : _params$title,\n _params$classes = params.classes,\n classes = _params$classes === void 0 ? [] : _params$classes,\n _params$attributes = params.attributes,\n attributes = _params$attributes === void 0 ? {} : _params$attributes,\n _params$styles = params.styles,\n styles = _params$styles === void 0 ? {} : _params$styles;\n if (!iconDefinition) return;\n var prefix = iconDefinition.prefix,\n iconName = iconDefinition.iconName,\n icon = iconDefinition.icon;\n return apiObject(_objectSpread({\n type: 'icon'\n }, iconDefinition), function () {\n ensureCss();\n\n if (config.autoA11y) {\n if (title) {\n attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(nextUniqueId());\n } else {\n attributes['aria-hidden'] = 'true';\n attributes['focusable'] = 'false';\n }\n }\n\n return makeInlineSvgAbstract({\n icons: {\n main: prepIcon(icon),\n mask: mask ? prepIcon(mask.icon) : {\n found: false,\n width: null,\n height: null,\n icon: {}\n }\n },\n prefix: prefix,\n iconName: iconName,\n transform: _objectSpread({}, meaninglessTransform, transform),\n symbol: symbol,\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: classes\n }\n });\n });\n});\nvar text = function text(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$transform2 = params.transform,\n transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n _params$title2 = params.title,\n title = _params$title2 === void 0 ? null : _params$title2,\n _params$classes2 = params.classes,\n classes = _params$classes2 === void 0 ? [] : _params$classes2,\n _params$attributes2 = params.attributes,\n attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n _params$styles2 = params.styles,\n styles = _params$styles2 === void 0 ? {} : _params$styles2;\n return apiObject({\n type: 'text',\n content: content\n }, function () {\n ensureCss();\n return makeLayersTextAbstract({\n content: content,\n transform: _objectSpread({}, meaninglessTransform, transform),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n }\n });\n });\n};\nvar counter = function counter(content) {\n var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _params$title3 = params.title,\n title = _params$title3 === void 0 ? null : _params$title3,\n _params$classes3 = params.classes,\n classes = _params$classes3 === void 0 ? [] : _params$classes3,\n _params$attributes3 = params.attributes,\n attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n _params$styles3 = params.styles,\n styles = _params$styles3 === void 0 ? {} : _params$styles3;\n return apiObject({\n type: 'counter',\n content: content\n }, function () {\n ensureCss();\n return makeLayersCounterAbstract({\n content: content.toString(),\n title: title,\n extra: {\n attributes: attributes,\n styles: styles,\n classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n }\n });\n });\n};\nvar layer = function layer(assembler) {\n return apiObject({\n type: 'layer'\n }, function () {\n ensureCss();\n var children = [];\n assembler(function (args) {\n Array.isArray(args) ? args.map(function (a) {\n children = children.concat(a.abstract);\n }) : children = children.concat(args.abstract);\n });\n return [{\n tag: 'span',\n attributes: {\n class: \"\".concat(config.familyPrefix, \"-layers\")\n },\n children: children\n }];\n });\n};\nvar api = {\n noAuto: noAuto,\n config: config,\n dom: dom,\n library: library,\n parse: parse,\n findIconDefinition: findIconDefinition,\n icon: icon,\n text: text,\n counter: counter,\n layer: layer,\n toHtml: toHtml\n};\n\nvar autoReplace = function autoReplace() {\n var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n node: autoReplaceSvgRoot\n });\n};\n\nexport { icon, noAuto, config, toHtml, layer, text, counter, library, dom, parse, findIconDefinition };\n", + "var prefix = \"far\";\nvar faAddressBook = {\n prefix: 'far',\n iconName: 'address-book',\n icon: [448, 512, [], \"f2b9\", \"M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-68 304H48V48h320v416zM208 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2z\"]\n};\nvar faAddressCard = {\n prefix: 'far',\n iconName: 'address-card',\n icon: [576, 512, [], \"f2bb\", \"M528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 400H48V80h480v352zM208 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2zM360 320h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm0-64h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm0-64h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8z\"]\n};\nvar faAngry = {\n prefix: 'far',\n iconName: 'angry',\n icon: [496, 512, [], \"f556\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm0-144c-33.6 0-65.2 14.8-86.8 40.6-8.5 10.2-7.1 25.3 3.1 33.8s25.3 7.2 33.8-3c24.8-29.7 75-29.7 99.8 0 8.1 9.7 23.2 11.9 33.8 3 10.2-8.5 11.5-23.6 3.1-33.8-21.6-25.8-53.2-40.6-86.8-40.6zm-48-72c10.3 0 19.9-6.7 23-17.1 3.8-12.7-3.4-26.1-16.1-29.9l-80-24c-12.8-3.9-26.1 3.4-29.9 16.1-3.8 12.7 3.4 26.1 16.1 29.9l28.2 8.5c-3.1 4.9-5.3 10.4-5.3 16.6 0 17.7 14.3 32 32 32s32-14.4 32-32.1zm199-54.9c-3.8-12.7-17.1-19.9-29.9-16.1l-80 24c-12.7 3.8-19.9 17.2-16.1 29.9 3.1 10.4 12.7 17.1 23 17.1 0 17.7 14.3 32 32 32s32-14.3 32-32c0-6.2-2.2-11.7-5.3-16.6l28.2-8.5c12.7-3.7 19.9-17.1 16.1-29.8z\"]\n};\nvar faArrowAltCircleDown = {\n prefix: 'far',\n iconName: 'arrow-alt-circle-down',\n icon: [512, 512, [], \"f358\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z\"]\n};\nvar faArrowAltCircleLeft = {\n prefix: 'far',\n iconName: 'arrow-alt-circle-left',\n icon: [512, 512, [], \"f359\", \"M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z\"]\n};\nvar faArrowAltCircleRight = {\n prefix: 'far',\n iconName: 'arrow-alt-circle-right',\n icon: [512, 512, [], \"f35a\", \"M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z\"]\n};\nvar faArrowAltCircleUp = {\n prefix: 'far',\n iconName: 'arrow-alt-circle-up',\n icon: [512, 512, [], \"f35b\", \"M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z\"]\n};\nvar faBell = {\n prefix: 'far',\n iconName: 'bell',\n icon: [448, 512, [], \"f0f3\", \"M439.39 362.29c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71zM67.53 368c21.22-27.97 44.42-74.33 44.53-159.42 0-.2-.06-.38-.06-.58 0-61.86 50.14-112 112-112s112 50.14 112 112c0 .2-.06.38-.06.58.11 85.1 23.31 131.46 44.53 159.42H67.53zM224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64z\"]\n};\nvar faBellSlash = {\n prefix: 'far',\n iconName: 'bell-slash',\n icon: [640, 512, [], \"f1f6\", \"M633.99 471.02L36 3.51C29.1-2.01 19.03-.9 13.51 6l-10 12.49C-2.02 25.39-.9 35.46 6 40.98l598 467.51c6.9 5.52 16.96 4.4 22.49-2.49l10-12.49c5.52-6.9 4.41-16.97-2.5-22.49zM163.53 368c16.71-22.03 34.48-55.8 41.4-110.58l-45.47-35.55c-3.27 90.73-36.47 120.68-54.84 140.42-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h279.66l-61.4-48H163.53zM320 96c61.86 0 112 50.14 112 112 0 .2-.06.38-.06.58.02 16.84 1.16 31.77 2.79 45.73l59.53 46.54c-8.31-22.13-14.34-51.49-14.34-92.85 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84c-26.02 5.41-49.45 16.94-69.13 32.72l38.17 29.84C275 103.18 296.65 96 320 96zm0 416c35.32 0 63.97-28.65 63.97-64H256.03c0 35.35 28.65 64 63.97 64z\"]\n};\nvar faBookmark = {\n prefix: 'far',\n iconName: 'bookmark',\n icon: [384, 512, [], \"f02e\", \"M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z\"]\n};\nvar faBuilding = {\n prefix: 'far',\n iconName: 'building',\n icon: [448, 512, [], \"f1ad\", \"M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z\"]\n};\nvar faCalendar = {\n prefix: 'far',\n iconName: 'calendar',\n icon: [448, 512, [], \"f133\", \"M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z\"]\n};\nvar faCalendarAlt = {\n prefix: 'far',\n iconName: 'calendar-alt',\n icon: [448, 512, [], \"f073\", \"M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCalendarCheck = {\n prefix: 'far',\n iconName: 'calendar-check',\n icon: [448, 512, [], \"f274\", \"M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z\"]\n};\nvar faCalendarMinus = {\n prefix: 'far',\n iconName: 'calendar-minus',\n icon: [448, 512, [], \"f272\", \"M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCalendarPlus = {\n prefix: 'far',\n iconName: 'calendar-plus',\n icon: [448, 512, [], \"f271\", \"M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCalendarTimes = {\n prefix: 'far',\n iconName: 'calendar-times',\n icon: [448, 512, [], \"f273\", \"M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCaretSquareDown = {\n prefix: 'far',\n iconName: 'caret-square-down',\n icon: [448, 512, [], \"f150\", \"M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCaretSquareLeft = {\n prefix: 'far',\n iconName: 'caret-square-left',\n icon: [448, 512, [], \"f191\", \"M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCaretSquareRight = {\n prefix: 'far',\n iconName: 'caret-square-right',\n icon: [448, 512, [], \"f152\", \"M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faCaretSquareUp = {\n prefix: 'far',\n iconName: 'caret-square-up',\n icon: [448, 512, [], \"f151\", \"M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faChartBar = {\n prefix: 'far',\n iconName: 'chart-bar',\n icon: [512, 512, [], \"f080\", \"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\"]\n};\nvar faCheckCircle = {\n prefix: 'far',\n iconName: 'check-circle',\n icon: [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"]\n};\nvar faCheckSquare = {\n prefix: 'far',\n iconName: 'check-square',\n icon: [448, 512, [], \"f14a\", \"M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z\"]\n};\nvar faCircle = {\n prefix: 'far',\n iconName: 'circle',\n icon: [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z\"]\n};\nvar faClipboard = {\n prefix: 'far',\n iconName: 'clipboard',\n icon: [384, 512, [], \"f328\", \"M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z\"]\n};\nvar faClock = {\n prefix: 'far',\n iconName: 'clock',\n icon: [512, 512, [], \"f017\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z\"]\n};\nvar faClone = {\n prefix: 'far',\n iconName: 'clone',\n icon: [512, 512, [], \"f24d\", \"M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z\"]\n};\nvar faClosedCaptioning = {\n prefix: 'far',\n iconName: 'closed-captioning',\n icon: [512, 512, [], \"f20a\", \"M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z\"]\n};\nvar faComment = {\n prefix: 'far',\n iconName: 'comment',\n icon: [512, 512, [], \"f075\", \"M256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 368c-26.7 0-53.1-4.1-78.4-12.1l-22.7-7.2-19.5 13.8c-14.3 10.1-33.9 21.4-57.5 29 7.3-12.1 14.4-25.7 19.9-40.2l10.6-28.1-20.6-21.8C69.7 314.1 48 282.2 48 240c0-88.2 93.3-160 208-160s208 71.8 208 160-93.3 160-208 160z\"]\n};\nvar faCommentAlt = {\n prefix: 'far',\n iconName: 'comment-alt',\n icon: [512, 512, [], \"f27a\", \"M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 7.1 5.8 12 12 12 2.4 0 4.9-.7 7.1-2.4L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zm16 352c0 8.8-7.2 16-16 16H288l-12.8 9.6L208 428v-60H64c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16h384c8.8 0 16 7.2 16 16v288z\"]\n};\nvar faCommentDots = {\n prefix: 'far',\n iconName: 'comment-dots',\n icon: [512, 512, [], \"f4ad\", \"M144 208c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm112 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm112 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zM256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 368c-26.7 0-53.1-4.1-78.4-12.1l-22.7-7.2-19.5 13.8c-14.3 10.1-33.9 21.4-57.5 29 7.3-12.1 14.4-25.7 19.9-40.2l10.6-28.1-20.6-21.8C69.7 314.1 48 282.2 48 240c0-88.2 93.3-160 208-160s208 71.8 208 160-93.3 160-208 160z\"]\n};\nvar faComments = {\n prefix: 'far',\n iconName: 'comments',\n icon: [576, 512, [], \"f086\", \"M532 386.2c27.5-27.1 44-61.1 44-98.2 0-80-76.5-146.1-176.2-157.9C368.3 72.5 294.3 32 208 32 93.1 32 0 103.6 0 192c0 37 16.5 71 44 98.2-15.3 30.7-37.3 54.5-37.7 54.9-6.3 6.7-8.1 16.5-4.4 25 3.6 8.5 12 14 21.2 14 53.5 0 96.7-20.2 125.2-38.8 9.2 2.1 18.7 3.7 28.4 4.9C208.1 407.6 281.8 448 368 448c20.8 0 40.8-2.4 59.8-6.8C456.3 459.7 499.4 480 553 480c9.2 0 17.5-5.5 21.2-14 3.6-8.5 1.9-18.3-4.4-25-.4-.3-22.5-24.1-37.8-54.8zm-392.8-92.3L122.1 305c-14.1 9.1-28.5 16.3-43.1 21.4 2.7-4.7 5.4-9.7 8-14.8l15.5-31.1L77.7 256C64.2 242.6 48 220.7 48 192c0-60.7 73.3-112 160-112s160 51.3 160 112-73.3 112-160 112c-16.5 0-33-1.9-49-5.6l-19.8-4.5zM498.3 352l-24.7 24.4 15.5 31.1c2.6 5.1 5.3 10.1 8 14.8-14.6-5.1-29-12.3-43.1-21.4l-17.1-11.1-19.9 4.6c-16 3.7-32.5 5.6-49 5.6-54 0-102.2-20.1-131.3-49.7C338 339.5 416 272.9 416 192c0-3.4-.4-6.7-.7-10C479.7 196.5 528 238.8 528 288c0 28.7-16.2 50.6-29.7 64z\"]\n};\nvar faCompass = {\n prefix: 'far',\n iconName: 'compass',\n icon: [496, 512, [], \"f14e\", \"M347.94 129.86L203.6 195.83a31.938 31.938 0 0 0-15.77 15.77l-65.97 144.34c-7.61 16.65 9.54 33.81 26.2 26.2l144.34-65.97a31.938 31.938 0 0 0 15.77-15.77l65.97-144.34c7.61-16.66-9.54-33.81-26.2-26.2zm-77.36 148.72c-12.47 12.47-32.69 12.47-45.16 0-12.47-12.47-12.47-32.69 0-45.16 12.47-12.47 32.69-12.47 45.16 0 12.47 12.47 12.47 32.69 0 45.16zM248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 448c-110.28 0-200-89.72-200-200S137.72 56 248 56s200 89.72 200 200-89.72 200-200 200z\"]\n};\nvar faCopy = {\n prefix: 'far',\n iconName: 'copy',\n icon: [448, 512, [], \"f0c5\", \"M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z\"]\n};\nvar faCopyright = {\n prefix: 'far',\n iconName: 'copyright',\n icon: [512, 512, [], \"f1f9\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z\"]\n};\nvar faCreditCard = {\n prefix: 'far',\n iconName: 'credit-card',\n icon: [576, 512, [], \"f09d\", \"M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z\"]\n};\nvar faDizzy = {\n prefix: 'far',\n iconName: 'dizzy',\n icon: [496, 512, [], \"f567\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-33.8-217.9c7.8-7.8 7.8-20.5 0-28.3L196.3 192l17.9-17.9c7.8-7.8 7.8-20.5 0-28.3-7.8-7.8-20.5-7.8-28.3 0L168 163.7l-17.8-17.8c-7.8-7.8-20.5-7.8-28.3 0-7.8 7.8-7.8 20.5 0 28.3l17.9 17.9-17.9 17.9c-7.8 7.8-7.8 20.5 0 28.3 7.8 7.8 20.5 7.8 28.3 0l17.8-17.8 17.8 17.8c7.9 7.7 20.5 7.7 28.4-.2zm160-92.2c-7.8-7.8-20.5-7.8-28.3 0L328 163.7l-17.8-17.8c-7.8-7.8-20.5-7.8-28.3 0-7.8 7.8-7.8 20.5 0 28.3l17.9 17.9-17.9 17.9c-7.8 7.8-7.8 20.5 0 28.3 7.8 7.8 20.5 7.8 28.3 0l17.8-17.8 17.8 17.8c7.8 7.8 20.5 7.8 28.3 0 7.8-7.8 7.8-20.5 0-28.3l-17.8-18 17.9-17.9c7.7-7.8 7.7-20.4 0-28.2zM248 272c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64z\"]\n};\nvar faDotCircle = {\n prefix: 'far',\n iconName: 'dot-circle',\n icon: [512, 512, [], \"f192\", \"M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z\"]\n};\nvar faEdit = {\n prefix: 'far',\n iconName: 'edit',\n icon: [576, 512, [], \"f044\", \"M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z\"]\n};\nvar faEnvelope = {\n prefix: 'far',\n iconName: 'envelope',\n icon: [512, 512, [], \"f0e0\", \"M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z\"]\n};\nvar faEnvelopeOpen = {\n prefix: 'far',\n iconName: 'envelope-open',\n icon: [512, 512, [], \"f2b6\", \"M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z\"]\n};\nvar faEye = {\n prefix: 'far',\n iconName: 'eye',\n icon: [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"]\n};\nvar faEyeSlash = {\n prefix: 'far',\n iconName: 'eye-slash',\n icon: [640, 512, [], \"f070\", \"M634 471L36 3.51A16 16 0 0 0 13.51 6l-10 12.49A16 16 0 0 0 6 41l598 467.49a16 16 0 0 0 22.49-2.49l10-12.49A16 16 0 0 0 634 471zM296.79 146.47l134.79 105.38C429.36 191.91 380.48 144 320 144a112.26 112.26 0 0 0-23.21 2.47zm46.42 219.07L208.42 260.16C210.65 320.09 259.53 368 320 368a113 113 0 0 0 23.21-2.46zM320 112c98.65 0 189.09 55 237.93 144a285.53 285.53 0 0 1-44 60.2l37.74 29.5a333.7 333.7 0 0 0 52.9-75.11 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64c-36.7 0-71.71 7-104.63 18.81l46.41 36.29c18.94-4.3 38.34-7.1 58.22-7.1zm0 288c-98.65 0-189.08-55-237.93-144a285.47 285.47 0 0 1 44.05-60.19l-37.74-29.5a333.6 333.6 0 0 0-52.89 75.1 32.35 32.35 0 0 0 0 29.19C89.72 376.41 197.08 448 320 448c36.7 0 71.71-7.05 104.63-18.81l-46.41-36.28C359.28 397.2 339.89 400 320 400z\"]\n};\nvar faFile = {\n prefix: 'far',\n iconName: 'file',\n icon: [384, 512, [], \"f15b\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z\"]\n};\nvar faFileAlt = {\n prefix: 'far',\n iconName: 'file-alt',\n icon: [384, 512, [], \"f15c\", \"M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z\"]\n};\nvar faFileArchive = {\n prefix: 'far',\n iconName: 'file-archive',\n icon: [384, 512, [], \"f1c6\", \"M128.3 160v32h32v-32zm64-96h-32v32h32zm-64 32v32h32V96zm64 32h-32v32h32zm177.6-30.1L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h79.7v16h32V48H208v104c0 13.3 10.7 24 24 24h104zM194.2 265.7c-1.1-5.6-6-9.7-11.8-9.7h-22.1v-32h-32v32l-19.7 97.1C102 385.6 126.8 416 160 416c33.1 0 57.9-30.2 51.5-62.6zm-33.9 124.4c-17.9 0-32.4-12.1-32.4-27s14.5-27 32.4-27 32.4 12.1 32.4 27-14.5 27-32.4 27zm32-198.1h-32v32h32z\"]\n};\nvar faFileAudio = {\n prefix: 'far',\n iconName: 'file-audio',\n icon: [384, 512, [], \"f1c7\", \"M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z\"]\n};\nvar faFileCode = {\n prefix: 'far',\n iconName: 'file-code',\n icon: [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"]\n};\nvar faFileExcel = {\n prefix: 'far',\n iconName: 'file-excel',\n icon: [384, 512, [], \"f1c3\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z\"]\n};\nvar faFileImage = {\n prefix: 'far',\n iconName: 'file-image',\n icon: [384, 512, [], \"f1c5\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z\"]\n};\nvar faFilePdf = {\n prefix: 'far',\n iconName: 'file-pdf',\n icon: [384, 512, [], \"f1c1\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z\"]\n};\nvar faFilePowerpoint = {\n prefix: 'far',\n iconName: 'file-powerpoint',\n icon: [384, 512, [], \"f1c4\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z\"]\n};\nvar faFileVideo = {\n prefix: 'far',\n iconName: 'file-video',\n icon: [384, 512, [], \"f1c8\", \"M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z\"]\n};\nvar faFileWord = {\n prefix: 'far',\n iconName: 'file-word',\n icon: [384, 512, [], \"f1c2\", \"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z\"]\n};\nvar faFlag = {\n prefix: 'far',\n iconName: 'flag',\n icon: [512, 512, [], \"f024\", \"M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z\"]\n};\nvar faFlushed = {\n prefix: 'far',\n iconName: 'flushed',\n icon: [496, 512, [], \"f579\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm96-312c-44.2 0-80 35.8-80 80s35.8 80 80 80 80-35.8 80-80-35.8-80-80-80zm0 128c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm0-72c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm-112 24c0-44.2-35.8-80-80-80s-80 35.8-80 80 35.8 80 80 80 80-35.8 80-80zm-80 48c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm0-72c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm160 144H184c-13.2 0-24 10.8-24 24s10.8 24 24 24h128c13.2 0 24-10.8 24-24s-10.8-24-24-24z\"]\n};\nvar faFolder = {\n prefix: 'far',\n iconName: 'folder',\n icon: [512, 512, [], \"f07b\", \"M464 128H272l-54.63-54.63c-6-6-14.14-9.37-22.63-9.37H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm0 272H48V112h140.12l54.63 54.63c6 6 14.14 9.37 22.63 9.37H464v224z\"]\n};\nvar faFolderOpen = {\n prefix: 'far',\n iconName: 'folder-open',\n icon: [576, 512, [], \"f07c\", \"M527.9 224H480v-48c0-26.5-21.5-48-48-48H272l-64-64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h400c16.5 0 31.9-8.5 40.7-22.6l79.9-128c20-31.9-3-73.4-40.7-73.4zM48 118c0-3.3 2.7-6 6-6h134.1l64 64H426c3.3 0 6 2.7 6 6v42H152c-16.8 0-32.4 8.8-41.1 23.2L48 351.4zm400 282H72l77.2-128H528z\"]\n};\nvar faFontAwesomeLogoFull = {\n prefix: 'far',\n iconName: 'font-awesome-logo-full',\n icon: [3992, 512, [\"Font Awesome\"], \"f4e6\", \"M454.6 0H57.4C25.9 0 0 25.9 0 57.4v397.3C0 486.1 25.9 512 57.4 512h397.3c31.4 0 57.4-25.9 57.4-57.4V57.4C512 25.9 486.1 0 454.6 0zm-58.9 324.9c0 4.8-4.1 6.9-8.9 8.9-19.2 8.1-39.7 15.7-61.5 15.7-40.5 0-68.7-44.8-163.2 2.5v51.8c0 30.3-45.7 30.2-45.7 0v-250c-9-7-15-17.9-15-30.3 0-21 17.1-38.2 38.2-38.2 21 0 38.2 17.1 38.2 38.2 0 12.2-5.8 23.2-14.9 30.2v21c37.1-12 65.5-34.4 146.1-3.4 26.6 11.4 68.7-15.7 76.5-15.7 5.5 0 10.3 4.1 10.3 8.9v160.4zm432.9-174.2h-137v70.1H825c39.8 0 40.4 62.2 0 62.2H691.6v105.6c0 45.5-70.7 46.4-70.7 0V128.3c0-22 18-39.8 39.8-39.8h167.8c39.6 0 40.5 62.2.1 62.2zm191.1 23.4c-169.3 0-169.1 252.4 0 252.4 169.9 0 169.9-252.4 0-252.4zm0 196.1c-81.6 0-82.1-139.8 0-139.8 82.5 0 82.4 139.8 0 139.8zm372.4 53.4c-17.5 0-31.4-13.9-31.4-31.4v-117c0-62.4-72.6-52.5-99.1-16.4v133.4c0 41.5-63.3 41.8-63.3 0V208c0-40 63.1-41.6 63.1 0v3.4c43.3-51.6 162.4-60.4 162.4 39.3v141.5c.3 30.4-31.5 31.4-31.7 31.4zm179.7 2.9c-44.3 0-68.3-22.9-68.3-65.8V235.2H1488c-35.6 0-36.7-55.3 0-55.3h15.5v-37.3c0-41.3 63.8-42.1 63.8 0v37.5h24.9c35.4 0 35.7 55.3 0 55.3h-24.9v108.5c0 29.6 26.1 26.3 27.4 26.3 31.4 0 52.6 56.3-22.9 56.3zM1992 123c-19.5-50.2-95.5-50-114.5 0-107.3 275.7-99.5 252.7-99.5 262.8 0 42.8 58.3 51.2 72.1 14.4l13.5-35.9H2006l13 35.9c14.2 37.7 72.1 27.2 72.1-14.4 0-10.1 5.3 6.8-99.1-262.8zm-108.9 179.1l51.7-142.9 51.8 142.9h-103.5zm591.3-85.6l-53.7 176.3c-12.4 41.2-72 41-84 0l-42.3-135.9-42.3 135.9c-12.4 40.9-72 41.2-84.5 0l-54.2-176.3c-12.5-39.4 49.8-56.1 60.2-16.9L2213 342l45.3-139.5c10.9-32.7 59.6-34.7 71.2 0l45.3 139.5 39.3-142.4c10.3-38.3 72.6-23.8 60.3 16.9zm275.4 75.1c0-42.4-33.9-117.5-119.5-117.5-73.2 0-124.4 56.3-124.4 126 0 77.2 55.3 126.4 128.5 126.4 31.7 0 93-11.5 93-39.8 0-18.3-21.1-31.5-39.3-22.4-49.4 26.2-109 8.4-115.9-43.8h148.3c16.3 0 29.3-13.4 29.3-28.9zM2571 277.7c9.5-73.4 113.9-68.6 118.6 0H2571zm316.7 148.8c-31.4 0-81.6-10.5-96.6-31.9-12.4-17 2.5-39.8 21.8-39.8 16.3 0 36.8 22.9 77.7 22.9 27.4 0 40.4-11 40.4-25.8 0-39.8-142.9-7.4-142.9-102 0-40.4 35.3-75.7 98.6-75.7 31.4 0 74.1 9.9 87.6 29.4 10.8 14.8-1.4 36.2-20.9 36.2-15.1 0-26.7-17.3-66.2-17.3-22.9 0-37.8 10.5-37.8 23.8 0 35.9 142.4 6 142.4 103.1-.1 43.7-37.4 77.1-104.1 77.1zm266.8-252.4c-169.3 0-169.1 252.4 0 252.4 170.1 0 169.6-252.4 0-252.4zm0 196.1c-81.8 0-82-139.8 0-139.8 82.5 0 82.4 139.8 0 139.8zm476.9 22V268.7c0-53.8-61.4-45.8-85.7-10.5v134c0 41.3-63.8 42.1-63.8 0V268.7c0-52.1-59.5-47.4-85.7-10.1v133.6c0 41.5-63.3 41.8-63.3 0V208c0-40 63.1-41.6 63.1 0v3.4c9.9-14.4 41.8-37.3 78.6-37.3 35.3 0 57.7 16.4 66.7 43.8 13.9-21.8 45.8-43.8 82.6-43.8 44.3 0 70.7 23.4 70.7 72.7v145.3c.5 17.3-13.5 31.4-31.9 31.4 3.5.1-31.3 1.1-31.3-31.3zM3992 291.6c0-42.4-32.4-117.5-117.9-117.5-73.2 0-127.5 56.3-127.5 126 0 77.2 58.3 126.4 131.6 126.4 31.7 0 91.5-11.5 91.5-39.8 0-18.3-21.1-31.5-39.3-22.4-49.4 26.2-110.5 8.4-117.5-43.8h149.8c16.3 0 29.1-13.4 29.3-28.9zm-180.5-13.9c9.7-74.4 115.9-68.3 120.1 0h-120.1z\"]\n};\nvar faFrown = {\n prefix: 'far',\n iconName: 'frown',\n icon: [496, 512, [], \"f119\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.4 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c8.1 9.7 23.1 11.9 33.8 3.1 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z\"]\n};\nvar faFrownOpen = {\n prefix: 'far',\n iconName: 'frown-open',\n icon: [496, 512, [], \"f57a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-48-248c0-17.7-14.3-32-32-32s-32 14.3-32 32 14.3 32 32 32 32-14.3 32-32zm128-32c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 112c-35.6 0-88.8 21.3-95.8 61.2-2 11.8 9 21.5 20.5 18.1 31.2-9.6 59.4-15.3 75.3-15.3s44.1 5.7 75.3 15.3c11.4 3.5 22.5-6.3 20.5-18.1-7-39.9-60.2-61.2-95.8-61.2z\"]\n};\nvar faFutbol = {\n prefix: 'far',\n iconName: 'futbol',\n icon: [496, 512, [], \"f1e3\", \"M483.8 179.4C449.8 74.6 352.6 8 248.1 8c-25.4 0-51.2 3.9-76.7 12.2C41.2 62.5-30.1 202.4 12.2 332.6 46.2 437.4 143.4 504 247.9 504c25.4 0 51.2-3.9 76.7-12.2 130.2-42.3 201.5-182.2 159.2-312.4zm-74.5 193.7l-52.2 6.4-43.7-60.9 24.4-75.2 71.1-22.1 38.9 36.4c-.2 30.7-7.4 61.1-21.7 89.2-4.7 9.3-10.7 17.8-16.8 26.2zm0-235.4l-10.4 53.1-70.7 22-64.2-46.5V92.5l47.4-26.2c39.2 13 73.4 38 97.9 71.4zM184.9 66.4L232 92.5v73.8l-64.2 46.5-70.6-22-10.1-52.5c24.3-33.4 57.9-58.6 97.8-71.9zM139 379.5L85.9 373c-14.4-20.1-37.3-59.6-37.8-115.3l39-36.4 71.1 22.2 24.3 74.3-43.5 61.7zm48.2 67l-22.4-48.1 43.6-61.7H287l44.3 61.7-22.4 48.1c-6.2 1.8-57.6 20.4-121.7 0z\"]\n};\nvar faGem = {\n prefix: 'far',\n iconName: 'gem',\n icon: [576, 512, [], \"f3a5\", \"M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z\"]\n};\nvar faGrimace = {\n prefix: 'far',\n iconName: 'grimace',\n icon: [496, 512, [], \"f57f\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm16 16H152c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h192c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48zm-168 96h-24c-8.8 0-16-7.2-16-16v-8h40v24zm0-40h-40v-8c0-8.8 7.2-16 16-16h24v24zm64 40h-48v-24h48v24zm0-40h-48v-24h48v24zm64 40h-48v-24h48v24zm0-40h-48v-24h48v24zm56 24c0 8.8-7.2 16-16 16h-24v-24h40v8zm0-24h-40v-24h24c8.8 0 16 7.2 16 16v8z\"]\n};\nvar faGrin = {\n prefix: 'far',\n iconName: 'grin',\n icon: [496, 512, [], \"f580\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.4-17.7 15.3 7.9 47.1 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z\"]\n};\nvar faGrinAlt = {\n prefix: 'far',\n iconName: 'grin-alt',\n icon: [496, 512, [], \"f581\", \"M200.3 248c12.4-18.7 15.1-37.3 15.7-56-.5-18.7-3.3-37.3-15.7-56-8-12-25.1-11.4-32.7 0-12.4 18.7-15.1 37.3-15.7 56 .5 18.7 3.3 37.3 15.7 56 8.1 12 25.2 11.4 32.7 0zm128 0c12.4-18.7 15.1-37.3 15.7-56-.5-18.7-3.3-37.3-15.7-56-8-12-25.1-11.4-32.7 0-12.4 18.7-15.1 37.3-15.7 56 .5 18.7 3.3 37.3 15.7 56 8.1 12 25.2 11.4 32.7 0zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.3-17.7 15.3 7.9 47.2 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3z\"]\n};\nvar faGrinBeam = {\n prefix: 'far',\n iconName: 'grin-beam',\n icon: [496, 512, [], \"f582\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.8-3.1-19.4 5.3-17.7 15.3 7.9 47.1 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zm-235.9-72.9c3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3zm160 0c3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3z\"]\n};\nvar faGrinBeamSweat = {\n prefix: 'far',\n iconName: 'grin-beam-sweat',\n icon: [496, 512, [], \"f583\", \"M440 160c29.5 0 53.3-26.3 53.3-58.7 0-25-31.7-75.5-46.2-97.3-3.6-5.3-10.7-5.3-14.2 0-14.5 21.8-46.2 72.3-46.2 97.3 0 32.4 23.8 58.7 53.3 58.7zM248 400c51.9 0 115.3-32.9 123.3-80 1.7-9.9-7.7-18.5-17.7-15.3-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.8-3.1-19.4 5.3-17.7 15.3 8 47.1 71.4 80 123.3 80zm130.3-168.3c3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3 3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.6 6.2 4.6 9.3 3.7zm105.3-52.9c-24.6 15.7-46 12.9-46.4 12.9 6.9 20.2 10.8 41.8 10.8 64.3 0 110.3-89.7 200-200 200S48 366.3 48 256 137.7 56 248 56c39.8 0 76.8 11.8 108 31.9 1.7-9.5 6.3-24.1 17.2-45.7C336.4 20.6 293.7 8 248 8 111 8 0 119 0 256s111 248 248 248 248-111 248-248c0-27-4.4-52.9-12.4-77.2zM168 189.4c12.3 0 23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3 3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.8 19.2-21.6 31.5-21.6z\"]\n};\nvar faGrinHearts = {\n prefix: 'far',\n iconName: 'grin-hearts',\n icon: [496, 512, [], \"f584\", \"M353.6 304.6c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.8-3.1-19.4 5.3-17.7 15.3 7.9 47.2 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zm-152.8-48.9c4.5 1.2 9.2-1.5 10.5-6l19.4-69.9c5.6-20.3-7.4-41.1-28.8-44.5-18.6-3-36.4 9.8-41.5 27.9l-2 7.1-7.1-1.9c-18.2-4.7-38.2 4.3-44.9 22-7.7 20.2 3.8 41.9 24.2 47.2l70.2 18.1zm188.8-65.3c-6.7-17.6-26.7-26.7-44.9-22l-7.1 1.9-2-7.1c-5-18.1-22.8-30.9-41.5-27.9-21.4 3.4-34.4 24.2-28.8 44.5l19.4 69.9c1.2 4.5 5.9 7.2 10.5 6l70.2-18.2c20.4-5.3 31.9-26.9 24.2-47.1zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200z\"]\n};\nvar faGrinSquint = {\n prefix: 'far',\n iconName: 'grin-squint',\n icon: [496, 512, [], \"f585\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.4-17.7 15.3 7.9 47.1 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zm-234.7-40.8c3.6 4.2 9.9 5.7 15.3 2.5l80-48c3.6-2.2 5.8-6.1 5.8-10.3s-2.2-8.1-5.8-10.3l-80-48c-5.1-3-11.4-1.9-15.3 2.5-3.8 4.5-3.8 11-.1 15.5l33.6 40.3-33.6 40.3c-3.8 4.5-3.7 11.1.1 15.5zm242.9 2.5c5.4 3.2 11.7 1.7 15.3-2.5 3.8-4.5 3.8-11 .1-15.5L343.6 208l33.6-40.3c3.8-4.5 3.7-11-.1-15.5-3.8-4.4-10.2-5.4-15.3-2.5l-80 48c-3.6 2.2-5.8 6.1-5.8 10.3s2.2 8.1 5.8 10.3l80 48z\"]\n};\nvar faGrinSquintTears = {\n prefix: 'far',\n iconName: 'grin-squint-tears',\n icon: [512, 512, [], \"f586\", \"M117.1 384.1c-25.8 3.7-84 13.7-100.9 30.6-21.9 21.9-21.5 57.9.9 80.3s58.3 22.8 80.3.9C114.3 479 124.3 420.8 128 395c.8-6.4-4.6-11.8-10.9-10.9zm-41.2-41.7C40.3 268 53 176.1 114.6 114.6 152.4 76.8 202.6 56 256 56c36.2 0 70.8 9.8 101.2 27.7 3.8-20.3 8-36.1 12-48.3C333.8 17.2 294.9 8 256 8 192.5 8 129.1 32.2 80.6 80.6c-74.1 74.1-91.3 183.4-52 274 12.2-4.1 27.7-8.3 47.3-12.2zm352.3-187.6c45 76.6 34.9 176.9-30.8 242.6-37.8 37.8-88 58.6-141.4 58.6-30.5 0-59.8-7-86.4-19.8-3.9 19.5-8 35-12.2 47.2 31.4 13.6 65 20.6 98.7 20.6 63.5 0 126.9-24.2 175.4-72.6 78.1-78.1 93.1-195.4 45.2-288.6-12.3 4-28.2 8.1-48.5 12zm-33.3-26.9c25.8-3.7 84-13.7 100.9-30.6 21.9-21.9 21.5-57.9-.9-80.3s-58.3-22.8-80.3-.9C397.7 33 387.7 91.2 384 117c-.8 6.4 4.6 11.8 10.9 10.9zm-187 108.3c-3-3-7.2-4.2-11.4-3.2L106 255.7c-5.7 1.4-9.5 6.7-9.1 12.6.5 5.8 5.1 10.5 10.9 11l52.3 4.8 4.8 52.3c.5 5.8 5.2 10.4 11 10.9h.9c5.5 0 10.3-3.7 11.7-9.1l22.6-90.5c1-4.2-.2-8.5-3.2-11.5zm39.7-25.1l90.5-22.6c5.7-1.4 9.5-6.7 9.1-12.6-.5-5.8-5.1-10.5-10.9-11l-52.3-4.8-4.8-52.3c-.5-5.8-5.2-10.4-11-10.9-5.6-.1-11.2 3.4-12.6 9.1L233 196.5c-1 4.1.2 8.4 3.2 11.4 5 5 11.3 3.2 11.4 3.2zm52 88.5c-29.1 29.1-59.7 52.9-83.9 65.4-9.2 4.8-10 17.5-1.7 23.4 38.9 27.7 107 6.2 143.7-30.6S416 253 388.3 214.1c-5.8-8.2-18.5-7.6-23.4 1.7-12.3 24.2-36.2 54.7-65.3 83.8z\"]\n};\nvar faGrinStars = {\n prefix: 'far',\n iconName: 'grin-stars',\n icon: [496, 512, [], \"f587\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm105.6-151.4c-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.8-3.1-19.4 5.3-17.7 15.3 7.9 47.2 71.3 80 123.3 80s115.3-32.9 123.3-80c1.6-9.8-7.7-18.4-17.7-15.3zm-227.9-57.5c-1 6.2 5.4 11 11 7.9l31.3-16.3 31.3 16.3c5.6 3.1 12-1.7 11-7.9l-6-34.9 25.4-24.6c4.5-4.5 1.9-12.2-4.3-13.2l-34.9-5-15.5-31.6c-2.9-5.8-11-5.8-13.9 0l-15.5 31.6-34.9 5c-6.2.9-8.9 8.6-4.3 13.2l25.4 24.6-6.1 34.9zm259.7-72.7l-34.9-5-15.5-31.6c-2.9-5.8-11-5.8-13.9 0l-15.5 31.6-34.9 5c-6.2.9-8.9 8.6-4.3 13.2l25.4 24.6-6 34.9c-1 6.2 5.4 11 11 7.9l31.3-16.3 31.3 16.3c5.6 3.1 12-1.7 11-7.9l-6-34.9 25.4-24.6c4.5-4.6 1.8-12.2-4.4-13.2z\"]\n};\nvar faGrinTears = {\n prefix: 'far',\n iconName: 'grin-tears',\n icon: [640, 512, [], \"f588\", \"M117.1 256.1c-25.8 3.7-84 13.7-100.9 30.6-21.9 21.9-21.5 57.9.9 80.3s58.3 22.8 80.3.9C114.3 351 124.3 292.8 128 267c.8-6.4-4.6-11.8-10.9-10.9zm506.7 30.6c-16.9-16.9-75.1-26.9-100.9-30.6-6.3-.9-11.7 4.5-10.8 10.8 3.7 25.8 13.7 84 30.6 100.9 21.9 21.9 57.9 21.5 80.3-.9 22.3-22.3 22.7-58.3.8-80.2zm-126.6 61.7C463.8 412.3 396.9 456 320 456c-76.9 0-143.8-43.7-177.2-107.6-12.5 37.4-25.2 43.9-28.3 46.5C159.1 460.7 234.5 504 320 504s160.9-43.3 205.5-109.1c-3.2-2.7-15.9-9.2-28.3-46.5zM122.7 224.5C137.9 129.2 220.5 56 320 56c99.5 0 182.1 73.2 197.3 168.5 2.1-.2 5.2-2.4 49.5 7C554.4 106 448.7 8 320 8S85.6 106 73.2 231.4c44.5-9.4 47.1-7.2 49.5-6.9zM320 400c51.9 0 115.3-32.9 123.3-80 1.7-9.9-7.7-18.5-17.7-15.3-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.8-3.1-19.4 5.3-17.7 15.3 8 47.1 71.4 80 123.3 80zm130.3-168.3c3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3 3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.6 6.2 4.6 9.3 3.7zM240 189.4c12.3 0 23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3 3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.8 19.2-21.6 31.5-21.6z\"]\n};\nvar faGrinTongue = {\n prefix: 'far',\n iconName: 'grin-tongue',\n icon: [496, 512, [], \"f589\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm64 400c0 35.6-29.1 64.5-64.9 64-35.1-.5-63.1-29.8-63.1-65v-42.8l17.7-8.8c15-7.5 31.5 1.7 34.9 16.5l2.8 12.1c2.1 9.2 15.2 9.2 17.3 0l2.8-12.1c3.4-14.8 19.8-24.1 34.9-16.5l17.7 8.8V408zm28.2 25.3c2.2-8.1 3.8-16.5 3.8-25.3v-43.5c14.2-12.4 24.4-27.5 27.3-44.5 1.7-9.9-7.7-18.5-17.7-15.3-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.3-17.7 15.3 2.9 17 13.1 32.1 27.3 44.5V408c0 8.8 1.6 17.2 3.8 25.3C91.8 399.9 48 333 48 256c0-110.3 89.7-200 200-200s200 89.7 200 200c0 77-43.8 143.9-107.8 177.3zM168 176c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm160 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"]\n};\nvar faGrinTongueSquint = {\n prefix: 'far',\n iconName: 'grin-tongue-squint',\n icon: [496, 512, [], \"f58a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm64 400c0 35.6-29.1 64.5-64.9 64-35.1-.5-63.1-29.8-63.1-65v-42.8l17.7-8.8c15-7.5 31.5 1.7 34.9 16.5l2.8 12.1c2.1 9.2 15.2 9.2 17.3 0l2.8-12.1c3.4-14.8 19.8-24.1 34.9-16.5l17.7 8.8V408zm28.2 25.3c2.2-8.1 3.8-16.5 3.8-25.3v-43.5c14.2-12.4 24.4-27.5 27.3-44.5 1.7-9.9-7.7-18.5-17.7-15.3-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.3-17.7 15.3 2.9 17 13.1 32.1 27.3 44.5V408c0 8.8 1.6 17.2 3.8 25.3C91.8 399.9 48 333 48 256c0-110.3 89.7-200 200-200s200 89.7 200 200c0 77-43.8 143.9-107.8 177.3zm36.9-281.1c-3.8-4.4-10.3-5.5-15.3-2.5l-80 48c-3.6 2.2-5.8 6.1-5.8 10.3s2.2 8.1 5.8 10.3l80 48c5.4 3.2 11.7 1.7 15.3-2.5 3.8-4.5 3.8-11 .1-15.5L343.6 208l33.6-40.3c3.8-4.5 3.7-11.1-.1-15.5zm-162.9 45.5l-80-48c-5-3-11.4-2-15.3 2.5-3.8 4.5-3.8 11-.1 15.5l33.6 40.3-33.6 40.3c-3.8 4.5-3.7 11 .1 15.5 3.6 4.2 9.9 5.7 15.3 2.5l80-48c3.6-2.2 5.8-6.1 5.8-10.3s-2.2-8.1-5.8-10.3z\"]\n};\nvar faGrinTongueWink = {\n prefix: 'far',\n iconName: 'grin-tongue-wink',\n icon: [496, 512, [], \"f58b\", \"M152 180c-25.7 0-55.9 16.9-59.8 42.1-.8 5 1.7 10 6.1 12.4 4.4 2.4 9.9 1.8 13.7-1.6l9.5-8.5c14.8-13.2 46.2-13.2 61 0l9.5 8.5c2.5 2.2 8 4.7 13.7 1.6 4.4-2.4 6.9-7.4 6.1-12.4-3.9-25.2-34.1-42.1-59.8-42.1zm176-52c-44.2 0-80 35.8-80 80s35.8 80 80 80 80-35.8 80-80-35.8-80-80-80zm0 128c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm0-72c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm64 400c0 35.6-29.1 64.5-64.9 64-35.1-.5-63.1-29.8-63.1-65v-42.8l17.7-8.8c15-7.5 31.5 1.7 34.9 16.5l2.8 12.1c2.1 9.2 15.2 9.2 17.3 0l2.8-12.1c3.4-14.8 19.8-24.1 34.9-16.5l17.7 8.8V408zm28.2 25.3c2.2-8.1 3.8-16.5 3.8-25.3v-43.5c14.2-12.4 24.4-27.5 27.3-44.5 1.7-9.9-7.7-18.5-17.7-15.3-25.9 8.3-64.4 13.1-105.6 13.1s-79.6-4.8-105.6-13.1c-9.9-3.1-19.4 5.3-17.7 15.3 2.9 17 13.1 32.1 27.3 44.5V408c0 8.8 1.6 17.2 3.8 25.3C91.8 399.9 48 333 48 256c0-110.3 89.7-200 200-200s200 89.7 200 200c0 77-43.8 143.9-107.8 177.3z\"]\n};\nvar faGrinWink = {\n prefix: 'far',\n iconName: 'grin-wink',\n icon: [496, 512, [], \"f58c\", \"M328 180c-25.69 0-55.88 16.92-59.86 42.12-1.75 11.22 11.5 18.24 19.83 10.84l9.55-8.48c14.81-13.19 46.16-13.19 60.97 0l9.55 8.48c8.48 7.43 21.56.25 19.83-10.84C383.88 196.92 353.69 180 328 180zm-160 60c17.67 0 32-14.33 32-32s-14.33-32-32-32-32 14.33-32 32 14.33 32 32 32zm185.55 64.64c-25.93 8.3-64.4 13.06-105.55 13.06s-79.62-4.75-105.55-13.06c-9.94-3.13-19.4 5.37-17.71 15.34C132.67 367.13 196.06 400 248 400s115.33-32.87 123.26-80.02c1.68-9.89-7.67-18.48-17.71-15.34zM248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 448c-110.28 0-200-89.72-200-200S137.72 56 248 56s200 89.72 200 200-89.72 200-200 200z\"]\n};\nvar faHandLizard = {\n prefix: 'far',\n iconName: 'hand-lizard',\n icon: [576, 512, [], \"f258\", \"M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z\"]\n};\nvar faHandPaper = {\n prefix: 'far',\n iconName: 'hand-paper',\n icon: [448, 512, [], \"f256\", \"M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z\"]\n};\nvar faHandPeace = {\n prefix: 'far',\n iconName: 'hand-peace',\n icon: [448, 512, [], \"f25b\", \"M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z\"]\n};\nvar faHandPointDown = {\n prefix: 'far',\n iconName: 'hand-point-down',\n icon: [448, 512, [], \"f0a7\", \"M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z\"]\n};\nvar faHandPointLeft = {\n prefix: 'far',\n iconName: 'hand-point-left',\n icon: [512, 512, [], \"f0a5\", \"M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z\"]\n};\nvar faHandPointRight = {\n prefix: 'far',\n iconName: 'hand-point-right',\n icon: [512, 512, [], \"f0a4\", \"M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z\"]\n};\nvar faHandPointUp = {\n prefix: 'far',\n iconName: 'hand-point-up',\n icon: [448, 512, [], \"f0a6\", \"M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z\"]\n};\nvar faHandPointer = {\n prefix: 'far',\n iconName: 'hand-pointer',\n icon: [448, 512, [], \"f25a\", \"M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z\"]\n};\nvar faHandRock = {\n prefix: 'far',\n iconName: 'hand-rock',\n icon: [512, 512, [], \"f255\", \"M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z\"]\n};\nvar faHandScissors = {\n prefix: 'far',\n iconName: 'hand-scissors',\n icon: [512, 512, [], \"f257\", \"M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z\"]\n};\nvar faHandSpock = {\n prefix: 'far',\n iconName: 'hand-spock',\n icon: [512, 512, [], \"f259\", \"M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z\"]\n};\nvar faHandshake = {\n prefix: 'far',\n iconName: 'handshake',\n icon: [640, 512, [], \"f2b5\", \"M519.2 127.9l-47.6-47.6A56.252 56.252 0 0 0 432 64H205.2c-14.8 0-29.1 5.9-39.6 16.3L118 127.9H0v255.7h64c17.6 0 31.8-14.2 31.9-31.7h9.1l84.6 76.4c30.9 25.1 73.8 25.7 105.6 3.8 12.5 10.8 26 15.9 41.1 15.9 18.2 0 35.3-7.4 48.8-24 22.1 8.7 48.2 2.6 64-16.8l26.2-32.3c5.6-6.9 9.1-14.8 10.9-23h57.9c.1 17.5 14.4 31.7 31.9 31.7h64V127.9H519.2zM48 351.6c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16c0 8.9-7.2 16-16 16zm390-6.9l-26.1 32.2c-2.8 3.4-7.8 4-11.3 1.2l-23.9-19.4-30 36.5c-6 7.3-15 4.8-18 2.4l-36.8-31.5-15.6 19.2c-13.9 17.1-39.2 19.7-55.3 6.6l-97.3-88H96V175.8h41.9l61.7-61.6c2-.8 3.7-1.5 5.7-2.3H262l-38.7 35.5c-29.4 26.9-31.1 72.3-4.4 101.3 14.8 16.2 61.2 41.2 101.5 4.4l8.2-7.5 108.2 87.8c3.4 2.8 3.9 7.9 1.2 11.3zm106-40.8h-69.2c-2.3-2.8-4.9-5.4-7.7-7.7l-102.7-83.4 12.5-11.4c6.5-6 7-16.1 1-22.6L367 167.1c-6-6.5-16.1-6.9-22.6-1l-55.2 50.6c-9.5 8.7-25.7 9.4-34.6 0-9.3-9.9-8.5-25.1 1.2-33.9l65.6-60.1c7.4-6.8 17-10.5 27-10.5l83.7-.2c2.1 0 4.1.8 5.5 2.3l61.7 61.6H544v128zm48 47.7c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16c0 8.9-7.2 16-16 16z\"]\n};\nvar faHdd = {\n prefix: 'far',\n iconName: 'hdd',\n icon: [576, 512, [], \"f0a0\", \"M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z\"]\n};\nvar faHeart = {\n prefix: 'far',\n iconName: 'heart',\n icon: [512, 512, [], \"f004\", \"M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z\"]\n};\nvar faHospital = {\n prefix: 'far',\n iconName: 'hospital',\n icon: [448, 512, [], \"f0f8\", \"M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z\"]\n};\nvar faHourglass = {\n prefix: 'far',\n iconName: 'hourglass',\n icon: [384, 512, [], \"f254\", \"M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z\"]\n};\nvar faIdBadge = {\n prefix: 'far',\n iconName: 'id-badge',\n icon: [384, 512, [], \"f2c1\", \"M336 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm0 464H48V48h288v416zM144 112h96c8.8 0 16-7.2 16-16s-7.2-16-16-16h-96c-8.8 0-16 7.2-16 16s7.2 16 16 16zm48 176c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2z\"]\n};\nvar faIdCard = {\n prefix: 'far',\n iconName: 'id-card',\n icon: [576, 512, [], \"f2c2\", \"M528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 400H303.2c.9-4.5.8 3.6.8-22.4 0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6 0 26-.2 17.9.8 22.4H48V144h480v288zm-168-80h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm0-64h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm0-64h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm-168 96c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64z\"]\n};\nvar faImage = {\n prefix: 'far',\n iconName: 'image',\n icon: [512, 512, [], \"f03e\", \"M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z\"]\n};\nvar faImages = {\n prefix: 'far',\n iconName: 'images',\n icon: [576, 512, [], \"f302\", \"M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z\"]\n};\nvar faKeyboard = {\n prefix: 'far',\n iconName: 'keyboard',\n icon: [576, 512, [], \"f11c\", \"M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z\"]\n};\nvar faKiss = {\n prefix: 'far',\n iconName: 'kiss',\n icon: [496, 512, [], \"f596\", \"M168 176c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm136 132c0-19.2-28.8-41.5-71.5-44-3.8-.4-7.4 2.4-8.2 6.2-.9 3.8 1.1 7.7 4.7 9.2l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-5.7 2.4-6 12.2 0 14.8l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-3.6 1.5-5.6 5.4-4.7 9.2.8 3.6 4.1 6.2 7.8 6.2h.5c42.8-2.5 71.5-24.8 71.5-44 0-13-13.4-27.3-35.2-36C290.6 335.3 304 321 304 308zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm80-280c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"]\n};\nvar faKissBeam = {\n prefix: 'far',\n iconName: 'kiss-beam',\n icon: [496, 512, [], \"f597\", \"M168 152c-23.8 0-52.7 29.3-56 71.4-.3 3.7 2 7.2 5.6 8.3 3.5 1 7.5-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 5.9-4.5 5.6-8.3-3.1-42.1-32-71.4-55.8-71.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm56-148c0-19.2-28.8-41.5-71.5-44-3.8-.4-7.4 2.4-8.2 6.2-.9 3.8 1.1 7.7 4.7 9.2l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-5.7 2.4-6 12.2 0 14.8l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-3.6 1.5-5.6 5.4-4.7 9.2.8 3.6 4.1 6.2 7.8 6.2h.5c42.8-2.5 71.5-24.8 71.5-44 0-13-13.4-27.3-35.2-36C290.6 335.3 304 321 304 308zm24-156c-23.8 0-52.7 29.3-56 71.4-.3 3.7 2 7.2 5.6 8.3 3.5 1 7.5-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 5.9-4.5 5.6-8.3-3.1-42.1-32-71.4-55.8-71.4z\"]\n};\nvar faKissWinkHeart = {\n prefix: 'far',\n iconName: 'kiss-wink-heart',\n icon: [504, 512, [], \"f598\", \"M304 308.5c0-19.2-28.8-41.5-71.5-44-3.8-.4-7.4 2.4-8.2 6.2-.9 3.8 1.1 7.7 4.7 9.2l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-5.7 2.4-6 12.2 0 14.8l16.9 7.2c13 5.5 20.8 13.5 20.8 21.5s-7.8 16-20.7 21.5l-17 7.2c-3.6 1.5-5.6 5.4-4.7 9.2.8 3.6 4.1 6.2 7.8 6.2h.5c42.8-2.5 71.5-24.8 71.5-44 0-13-13.4-27.3-35.2-36 21.7-9.1 35.1-23.4 35.1-36.4zm70.5-83.5l9.5 8.5c3.8 3.3 9.3 4 13.7 1.6 4.4-2.4 6.9-7.4 6.1-12.4-4-25.2-34.2-42.1-59.8-42.1s-55.9 16.9-59.8 42.1c-.8 5 1.7 10 6.1 12.4 5.8 3.1 11.2.7 13.7-1.6l9.5-8.5c14.8-13.2 46.2-13.2 61 0zM136 208.5c0 17.7 14.3 32 32 32s32-14.3 32-32-14.3-32-32-32-32 14.3-32 32zm365.1 194c-8-20.8-31.5-31.5-53.1-25.9l-8.4 2.2-2.3-8.4c-5.9-21.4-27-36.5-49-33-25.2 4-40.6 28.6-34 52.6l22.9 82.6c1.5 5.3 7 8.5 12.4 7.1l83-21.5c24.1-6.3 37.7-31.8 28.5-55.7zM334 436.3c-26.1 12.5-55.2 19.7-86 19.7-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200c0 22.1-3.7 43.3-10.4 63.2 9 6.4 17 14.2 22.6 23.9 6.4.1 12.6 1.4 18.6 2.9 10.9-27.9 17.1-58.2 17.1-90C496 119 385 8 248 8S0 119 0 256s111 248 248 248c35.4 0 68.9-7.5 99.4-20.9-2.5-7.3 4.3 17.2-13.4-46.8z\"]\n};\nvar faLaugh = {\n prefix: 'far',\n iconName: 'laugh',\n icon: [496, 512, [], \"f599\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm141.4 389.4c-37.8 37.8-88 58.6-141.4 58.6s-103.6-20.8-141.4-58.6S48 309.4 48 256s20.8-103.6 58.6-141.4S194.6 56 248 56s103.6 20.8 141.4 58.6S448 202.6 448 256s-20.8 103.6-58.6 141.4zM328 224c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm-160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm194.4 64H133.6c-8.2 0-14.5 7-13.5 15 7.5 59.2 58.9 105 121.1 105h13.6c62.2 0 113.6-45.8 121.1-105 1-8-5.3-15-13.5-15z\"]\n};\nvar faLaughBeam = {\n prefix: 'far',\n iconName: 'laugh-beam',\n icon: [496, 512, [], \"f59a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm141.4 389.4c-37.8 37.8-88 58.6-141.4 58.6s-103.6-20.8-141.4-58.6S48 309.4 48 256s20.8-103.6 58.6-141.4S194.6 56 248 56s103.6 20.8 141.4 58.6S448 202.6 448 256s-20.8 103.6-58.6 141.4zM328 152c-23.8 0-52.7 29.3-56 71.4-.7 8.6 10.8 11.9 14.9 4.5l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c4.1 7.4 15.6 4 14.9-4.5-3.1-42.1-32-71.4-55.8-71.4zm-201 75.9l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c4.1 7.4 15.6 4 14.9-4.5-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.6 8.5 10.9 11.9 15.1 4.5zM362.4 288H133.6c-8.2 0-14.5 7-13.5 15 7.5 59.2 58.9 105 121.1 105h13.6c62.2 0 113.6-45.8 121.1-105 1-8-5.3-15-13.5-15z\"]\n};\nvar faLaughSquint = {\n prefix: 'far',\n iconName: 'laugh-squint',\n icon: [496, 512, [], \"f59b\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm141.4 389.4c-37.8 37.8-88 58.6-141.4 58.6s-103.6-20.8-141.4-58.6S48 309.4 48 256s20.8-103.6 58.6-141.4S194.6 56 248 56s103.6 20.8 141.4 58.6S448 202.6 448 256s-20.8 103.6-58.6 141.4zM343.6 196l33.6-40.3c8.6-10.3-3.8-24.8-15.4-18l-80 48c-7.8 4.7-7.8 15.9 0 20.6l80 48c11.5 6.8 24-7.6 15.4-18L343.6 196zm-209.4 58.3l80-48c7.8-4.7 7.8-15.9 0-20.6l-80-48c-11.6-6.9-24 7.7-15.4 18l33.6 40.3-33.6 40.3c-8.7 10.4 3.8 24.8 15.4 18zM362.4 288H133.6c-8.2 0-14.5 7-13.5 15 7.5 59.2 58.9 105 121.1 105h13.6c62.2 0 113.6-45.8 121.1-105 1-8-5.3-15-13.5-15z\"]\n};\nvar faLaughWink = {\n prefix: 'far',\n iconName: 'laugh-wink',\n icon: [496, 512, [], \"f59c\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm141.4 389.4c-37.8 37.8-88 58.6-141.4 58.6s-103.6-20.8-141.4-58.6C68.8 359.6 48 309.4 48 256s20.8-103.6 58.6-141.4C144.4 76.8 194.6 56 248 56s103.6 20.8 141.4 58.6c37.8 37.8 58.6 88 58.6 141.4s-20.8 103.6-58.6 141.4zM328 164c-25.7 0-55.9 16.9-59.9 42.1-1.7 11.2 11.5 18.2 19.8 10.8l9.5-8.5c14.8-13.2 46.2-13.2 61 0l9.5 8.5c8.5 7.4 21.6.3 19.8-10.8-3.8-25.2-34-42.1-59.7-42.1zm-160 60c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm194.4 64H133.6c-8.2 0-14.5 7-13.5 15 7.5 59.2 58.9 105 121.1 105h13.6c62.2 0 113.6-45.8 121.1-105 1-8-5.3-15-13.5-15z\"]\n};\nvar faLemon = {\n prefix: 'far',\n iconName: 'lemon',\n icon: [512, 512, [], \"f094\", \"M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z\"]\n};\nvar faLifeRing = {\n prefix: 'far',\n iconName: 'life-ring',\n icon: [512, 512, [], \"f1cd\", \"M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z\"]\n};\nvar faLightbulb = {\n prefix: 'far',\n iconName: 'lightbulb',\n icon: [352, 512, [], \"f0eb\", \"M176 80c-52.94 0-96 43.06-96 96 0 8.84 7.16 16 16 16s16-7.16 16-16c0-35.3 28.72-64 64-64 8.84 0 16-7.16 16-16s-7.16-16-16-16zM96.06 459.17c0 3.15.93 6.22 2.68 8.84l24.51 36.84c2.97 4.46 7.97 7.14 13.32 7.14h78.85c5.36 0 10.36-2.68 13.32-7.14l24.51-36.84c1.74-2.62 2.67-5.7 2.68-8.84l.05-43.18H96.02l.04 43.18zM176 0C73.72 0 0 82.97 0 176c0 44.37 16.45 84.85 43.56 115.78 16.64 18.99 42.74 58.8 52.42 92.16v.06h48v-.12c-.01-4.77-.72-9.51-2.15-14.07-5.59-17.81-22.82-64.77-62.17-109.67-20.54-23.43-31.52-53.15-31.61-84.14-.2-73.64 59.67-128 127.95-128 70.58 0 128 57.42 128 128 0 30.97-11.24 60.85-31.65 84.14-39.11 44.61-56.42 91.47-62.1 109.46a47.507 47.507 0 0 0-2.22 14.3v.1h48v-.05c9.68-33.37 35.78-73.18 52.42-92.16C335.55 260.85 352 220.37 352 176 352 78.8 273.2 0 176 0z\"]\n};\nvar faListAlt = {\n prefix: 'far',\n iconName: 'list-alt',\n icon: [512, 512, [], \"f022\", \"M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z\"]\n};\nvar faMap = {\n prefix: 'far',\n iconName: 'map',\n icon: [576, 512, [], \"f279\", \"M560.02 32c-1.96 0-3.98.37-5.96 1.16L384.01 96H384L212 35.28A64.252 64.252 0 0 0 191.76 32c-6.69 0-13.37 1.05-19.81 3.14L20.12 87.95A32.006 32.006 0 0 0 0 117.66v346.32C0 473.17 7.53 480 15.99 480c1.96 0 3.97-.37 5.96-1.16L192 416l172 60.71a63.98 63.98 0 0 0 40.05.15l151.83-52.81A31.996 31.996 0 0 0 576 394.34V48.02c0-9.19-7.53-16.02-15.98-16.02zM224 90.42l128 45.19v285.97l-128-45.19V90.42zM48 418.05V129.07l128-44.53v286.2l-.64.23L48 418.05zm480-35.13l-128 44.53V141.26l.64-.24L528 93.95v288.97z\"]\n};\nvar faMeh = {\n prefix: 'far',\n iconName: 'meh',\n icon: [496, 512, [], \"f11a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z\"]\n};\nvar faMehBlank = {\n prefix: 'far',\n iconName: 'meh-blank',\n icon: [496, 512, [], \"f5a4\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-280c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm160 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"]\n};\nvar faMehRollingEyes = {\n prefix: 'far',\n iconName: 'meh-rolling-eyes',\n icon: [496, 512, [], \"f5a5\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm88-304c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm0 112c-22.1 0-40-17.9-40-40 0-13.6 7.3-25.1 17.7-32.3-1 2.6-1.7 5.3-1.7 8.3 0 13.3 10.7 24 24 24s24-10.7 24-24c0-2.9-.7-5.7-1.7-8.3 10.4 7.2 17.7 18.7 17.7 32.3 0 22.1-17.9 40-40 40zm-104-40c0-39.8-32.2-72-72-72s-72 32.2-72 72 32.2 72 72 72 72-32.2 72-72zm-112 0c0-13.6 7.3-25.1 17.7-32.3-1 2.6-1.7 5.3-1.7 8.3 0 13.3 10.7 24 24 24s24-10.7 24-24c0-2.9-.7-5.7-1.7-8.3 10.4 7.2 17.7 18.7 17.7 32.3 0 22.1-17.9 40-40 40s-40-17.9-40-40zm192 128H184c-13.2 0-24 10.8-24 24s10.8 24 24 24h128c13.2 0 24-10.8 24-24s-10.8-24-24-24z\"]\n};\nvar faMinusSquare = {\n prefix: 'far',\n iconName: 'minus-square',\n icon: [448, 512, [], \"f146\", \"M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faMoneyBillAlt = {\n prefix: 'far',\n iconName: 'money-bill-alt',\n icon: [640, 512, [], \"f3d1\", \"M320 144c-53.02 0-96 50.14-96 112 0 61.85 42.98 112 96 112 53 0 96-50.13 96-112 0-61.86-42.98-112-96-112zm40 168c0 4.42-3.58 8-8 8h-64c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h16v-55.44l-.47.31a7.992 7.992 0 0 1-11.09-2.22l-8.88-13.31a7.992 7.992 0 0 1 2.22-11.09l15.33-10.22a23.99 23.99 0 0 1 13.31-4.03H328c4.42 0 8 3.58 8 8v88h16c4.42 0 8 3.58 8 8v16zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zm-16 272c-35.35 0-64 28.65-64 64H112c0-35.35-28.65-64-64-64V176c35.35 0 64-28.65 64-64h416c0 35.35 28.65 64 64 64v160z\"]\n};\nvar faMoon = {\n prefix: 'far',\n iconName: 'moon',\n icon: [512, 512, [], \"f186\", \"M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z\"]\n};\nvar faNewspaper = {\n prefix: 'far',\n iconName: 'newspaper',\n icon: [576, 512, [], \"f1ea\", \"M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z\"]\n};\nvar faObjectGroup = {\n prefix: 'far',\n iconName: 'object-group',\n icon: [512, 512, [], \"f247\", \"M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z\"]\n};\nvar faObjectUngroup = {\n prefix: 'far',\n iconName: 'object-ungroup',\n icon: [576, 512, [], \"f248\", \"M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z\"]\n};\nvar faPaperPlane = {\n prefix: 'far',\n iconName: 'paper-plane',\n icon: [512, 512, [], \"f1d8\", \"M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z\"]\n};\nvar faPauseCircle = {\n prefix: 'far',\n iconName: 'pause-circle',\n icon: [512, 512, [], \"f28b\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z\"]\n};\nvar faPlayCircle = {\n prefix: 'far',\n iconName: 'play-circle',\n icon: [512, 512, [], \"f144\", \"M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z\"]\n};\nvar faPlusSquare = {\n prefix: 'far',\n iconName: 'plus-square',\n icon: [448, 512, [], \"f0fe\", \"M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"]\n};\nvar faQuestionCircle = {\n prefix: 'far',\n iconName: 'question-circle',\n icon: [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"]\n};\nvar faRegistered = {\n prefix: 'far',\n iconName: 'registered',\n icon: [512, 512, [], \"f25d\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z\"]\n};\nvar faSadCry = {\n prefix: 'far',\n iconName: 'sad-cry',\n icon: [496, 512, [], \"f5b3\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm144 386.4V280c0-13.2-10.8-24-24-24s-24 10.8-24 24v151.4C315.5 447 282.8 456 248 456s-67.5-9-96-24.6V280c0-13.2-10.8-24-24-24s-24 10.8-24 24v114.4c-34.6-36-56-84.7-56-138.4 0-110.3 89.7-200 200-200s200 89.7 200 200c0 53.7-21.4 102.5-56 138.4zM205.8 234.5c4.4-2.4 6.9-7.4 6.1-12.4-4-25.2-34.2-42.1-59.8-42.1s-55.9 16.9-59.8 42.1c-.8 5 1.7 10 6.1 12.4 4.4 2.4 9.9 1.8 13.7-1.6l9.5-8.5c14.8-13.2 46.2-13.2 61 0l9.5 8.5c2.5 2.3 7.9 4.8 13.7 1.6zM344 180c-25.7 0-55.9 16.9-59.8 42.1-.8 5 1.7 10 6.1 12.4 4.5 2.4 9.9 1.8 13.7-1.6l9.5-8.5c14.8-13.2 46.2-13.2 61 0l9.5 8.5c2.5 2.2 8 4.7 13.7 1.6 4.4-2.4 6.9-7.4 6.1-12.4-3.9-25.2-34.1-42.1-59.8-42.1zm-96 92c-30.9 0-56 28.7-56 64s25.1 64 56 64 56-28.7 56-64-25.1-64-56-64z\"]\n};\nvar faSadTear = {\n prefix: 'far',\n iconName: 'sad-tear',\n icon: [496, 512, [], \"f5b4\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm8-152c-13.2 0-24 10.8-24 24s10.8 24 24 24c23.8 0 46.3 10.5 61.6 28.8 8.1 9.8 23.2 11.9 33.8 3.1 10.2-8.5 11.6-23.6 3.1-33.8C330 320.8 294.1 304 256 304zm-88-64c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-165.6 98.8C151 290.1 126 325.4 126 342.9c0 22.7 18.8 41.1 42 41.1s42-18.4 42-41.1c0-17.5-25-52.8-36.4-68.1-2.8-3.7-8.4-3.7-11.2 0z\"]\n};\nvar faSave = {\n prefix: 'far',\n iconName: 'save',\n icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"]\n};\nvar faShareSquare = {\n prefix: 'far',\n iconName: 'share-square',\n icon: [576, 512, [], \"f14d\", \"M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z\"]\n};\nvar faSmile = {\n prefix: 'far',\n iconName: 'smile',\n icon: [496, 512, [], \"f118\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm4 72.6c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.1-8.4-25.3-7.1-33.8 3.1z\"]\n};\nvar faSmileBeam = {\n prefix: 'far',\n iconName: 'smile-beam',\n icon: [496, 512, [], \"f5b8\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm84-143.4c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.6-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.2-8.4-25.3-7.1-33.8 3.1zM136.5 211c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4s-52.7 29.3-56 71.4c-.3 3.7 2.1 7.2 5.7 8.3 3.4 1.1 7.4-.5 9.3-3.7l9.5-17zM328 152c-23.8 0-52.7 29.3-56 71.4-.3 3.7 2.1 7.2 5.7 8.3 3.5 1.1 7.4-.5 9.3-3.7l9.5-17c7.7-13.7 19.2-21.6 31.5-21.6s23.8 7.9 31.5 21.6l9.5 17c2.1 3.7 6.2 4.7 9.3 3.7 3.6-1.1 6-4.5 5.7-8.3-3.3-42.1-32.2-71.4-56-71.4z\"]\n};\nvar faSmileWink = {\n prefix: 'far',\n iconName: 'smile-wink',\n icon: [496, 512, [], \"f4da\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm117.8-146.4c-10.2-8.5-25.3-7.1-33.8 3.1-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-60c-25.7 0-55.9 16.9-59.9 42.1-1.7 11.2 11.5 18.2 19.8 10.8l9.5-8.5c14.8-13.2 46.2-13.2 61 0l9.5 8.5c8.5 7.4 21.6.3 19.8-10.8-3.8-25.2-34-42.1-59.7-42.1z\"]\n};\nvar faSnowflake = {\n prefix: 'far',\n iconName: 'snowflake',\n icon: [448, 512, [], \"f2dc\", \"M440.1 355.2l-39.2-23 34.1-9.3c8.4-2.3 13.4-11.1 11.1-19.6l-4.1-15.5c-2.2-8.5-10.9-13.6-19.3-11.3L343 298.2 271.2 256l71.9-42.2 79.7 21.7c8.4 2.3 17-2.8 19.3-11.3l4.1-15.5c2.2-8.5-2.7-17.3-11.1-19.6l-34.1-9.3 39.2-23c7.5-4.4 10.1-14.2 5.8-21.9l-7.9-13.9c-4.3-7.7-14-10.3-21.5-5.9l-39.2 23 9.1-34.7c2.2-8.5-2.7-17.3-11.1-19.6l-15.2-4.1c-8.4-2.3-17 2.8-19.3 11.3l-21.3 81-71.9 42.2v-84.5L306 70.4c6.1-6.2 6.1-16.4 0-22.6l-11.1-11.3c-6.1-6.2-16.1-6.2-22.2 0l-24.9 25.4V16c0-8.8-7-16-15.7-16h-15.7c-8.7 0-15.7 7.2-15.7 16v46.1l-24.9-25.4c-6.1-6.2-16.1-6.2-22.2 0L142.1 48c-6.1 6.2-6.1 16.4 0 22.6l58.3 59.3v84.5l-71.9-42.2-21.3-81c-2.2-8.5-10.9-13.6-19.3-11.3L72.7 84c-8.4 2.3-13.4 11.1-11.1 19.6l9.1 34.7-39.2-23c-7.5-4.4-17.1-1.8-21.5 5.9l-7.9 13.9c-4.3 7.7-1.8 17.4 5.8 21.9l39.2 23-34.1 9.1c-8.4 2.3-13.4 11.1-11.1 19.6L6 224.2c2.2 8.5 10.9 13.6 19.3 11.3l79.7-21.7 71.9 42.2-71.9 42.2-79.7-21.7c-8.4-2.3-17 2.8-19.3 11.3l-4.1 15.5c-2.2 8.5 2.7 17.3 11.1 19.6l34.1 9.3-39.2 23c-7.5 4.4-10.1 14.2-5.8 21.9L10 391c4.3 7.7 14 10.3 21.5 5.9l39.2-23-9.1 34.7c-2.2 8.5 2.7 17.3 11.1 19.6l15.2 4.1c8.4 2.3 17-2.8 19.3-11.3l21.3-81 71.9-42.2v84.5l-58.3 59.3c-6.1 6.2-6.1 16.4 0 22.6l11.1 11.3c6.1 6.2 16.1 6.2 22.2 0l24.9-25.4V496c0 8.8 7 16 15.7 16h15.7c8.7 0 15.7-7.2 15.7-16v-46.1l24.9 25.4c6.1 6.2 16.1 6.2 22.2 0l11.1-11.3c6.1-6.2 6.1-16.4 0-22.6l-58.3-59.3v-84.5l71.9 42.2 21.3 81c2.2 8.5 10.9 13.6 19.3 11.3L375 428c8.4-2.3 13.4-11.1 11.1-19.6l-9.1-34.7 39.2 23c7.5 4.4 17.1 1.8 21.5-5.9l7.9-13.9c4.6-7.5 2.1-17.3-5.5-21.7z\"]\n};\nvar faSquare = {\n prefix: 'far',\n iconName: 'square',\n icon: [448, 512, [], \"f0c8\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z\"]\n};\nvar faStar = {\n prefix: 'far',\n iconName: 'star',\n icon: [576, 512, [], \"f005\", \"M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z\"]\n};\nvar faStarHalf = {\n prefix: 'far',\n iconName: 'star-half',\n icon: [576, 512, [], \"f089\", \"M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z\"]\n};\nvar faStickyNote = {\n prefix: 'far',\n iconName: 'sticky-note',\n icon: [448, 512, [], \"f249\", \"M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z\"]\n};\nvar faStopCircle = {\n prefix: 'far',\n iconName: 'stop-circle',\n icon: [512, 512, [], \"f28d\", \"M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z\"]\n};\nvar faSun = {\n prefix: 'far',\n iconName: 'sun',\n icon: [512, 512, [], \"f185\", \"M494.2 221.9l-59.8-40.5 13.7-71c2.6-13.2-1.6-26.8-11.1-36.4-9.6-9.5-23.2-13.7-36.2-11.1l-70.9 13.7-40.4-59.9c-15.1-22.3-51.9-22.3-67 0l-40.4 59.9-70.8-13.7C98 60.4 84.5 64.5 75 74.1c-9.5 9.6-13.7 23.1-11.1 36.3l13.7 71-59.8 40.5C6.6 229.5 0 242 0 255.5s6.7 26 17.8 33.5l59.8 40.5-13.7 71c-2.6 13.2 1.6 26.8 11.1 36.3 9.5 9.5 22.9 13.7 36.3 11.1l70.8-13.7 40.4 59.9C230 505.3 242.6 512 256 512s26-6.7 33.5-17.8l40.4-59.9 70.9 13.7c13.4 2.7 26.8-1.6 36.3-11.1 9.5-9.5 13.6-23.1 11.1-36.3l-13.7-71 59.8-40.5c11.1-7.5 17.8-20.1 17.8-33.5-.1-13.6-6.7-26.1-17.9-33.7zm-112.9 85.6l17.6 91.2-91-17.6L256 458l-51.9-77-90.9 17.6 17.6-91.2-76.8-52 76.8-52-17.6-91.2 91 17.6L256 53l51.9 76.9 91-17.6-17.6 91.1 76.8 52-76.8 52.1zM256 152c-57.3 0-104 46.7-104 104s46.7 104 104 104 104-46.7 104-104-46.7-104-104-104zm0 160c-30.9 0-56-25.1-56-56s25.1-56 56-56 56 25.1 56 56-25.1 56-56 56z\"]\n};\nvar faSurprise = {\n prefix: 'far',\n iconName: 'surprise',\n icon: [496, 512, [], \"f5c2\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm0-176c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64zm-48-72c0-17.7-14.3-32-32-32s-32 14.3-32 32 14.3 32 32 32 32-14.3 32-32zm128-32c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"]\n};\nvar faThumbsDown = {\n prefix: 'far',\n iconName: 'thumbs-down',\n icon: [512, 512, [], \"f165\", \"M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z\"]\n};\nvar faThumbsUp = {\n prefix: 'far',\n iconName: 'thumbs-up',\n icon: [512, 512, [], \"f164\", \"M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z\"]\n};\nvar faTimesCircle = {\n prefix: 'far',\n iconName: 'times-circle',\n icon: [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z\"]\n};\nvar faTired = {\n prefix: 'far',\n iconName: 'tired',\n icon: [496, 512, [], \"f5c8\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm129.1-303.8c-3.8-4.4-10.3-5.4-15.3-2.5l-80 48c-3.6 2.2-5.8 6.1-5.8 10.3s2.2 8.1 5.8 10.3l80 48c5.4 3.2 11.8 1.6 15.3-2.5 3.8-4.5 3.9-11 .1-15.5L343.6 208l33.6-40.3c3.8-4.5 3.7-11.1-.1-15.5zM220 208c0-4.2-2.2-8.1-5.8-10.3l-80-48c-5-3-11.5-1.9-15.3 2.5-3.8 4.5-3.9 11-.1 15.5l33.6 40.3-33.6 40.3c-3.8 4.5-3.7 11 .1 15.5 3.5 4.1 9.9 5.7 15.3 2.5l80-48c3.6-2.2 5.8-6.1 5.8-10.3zm28 64c-45.4 0-100.9 38.3-107.8 93.3-1.5 11.8 6.9 21.6 15.5 17.9C178.4 373.5 212 368 248 368s69.6 5.5 92.3 15.2c8.5 3.7 17-6 15.5-17.9-6.9-55-62.4-93.3-107.8-93.3z\"]\n};\nvar faTrashAlt = {\n prefix: 'far',\n iconName: 'trash-alt',\n icon: [448, 512, [], \"f2ed\", \"M268 416h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12zM432 80h-82.41l-34-56.7A48 48 0 0 0 274.41 0H173.59a48 48 0 0 0-41.16 23.3L98.41 80H16A16 16 0 0 0 0 96v16a16 16 0 0 0 16 16h16v336a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128h16a16 16 0 0 0 16-16V96a16 16 0 0 0-16-16zM171.84 50.91A6 6 0 0 1 177 48h94a6 6 0 0 1 5.15 2.91L293.61 80H154.39zM368 464H80V128h288zm-212-48h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12z\"]\n};\nvar faUser = {\n prefix: 'far',\n iconName: 'user',\n icon: [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"]\n};\nvar faUserCircle = {\n prefix: 'far',\n iconName: 'user-circle',\n icon: [496, 512, [], \"f2bd\", \"M248 104c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96zm0 144c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm0-240C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-49.7 0-95.1-18.3-130.1-48.4 14.9-23 40.4-38.6 69.6-39.5 20.8 6.4 40.6 9.6 60.5 9.6s39.7-3.1 60.5-9.6c29.2 1 54.7 16.5 69.6 39.5-35 30.1-80.4 48.4-130.1 48.4zm162.7-84.1c-24.4-31.4-62.1-51.9-105.1-51.9-10.2 0-26 9.6-57.6 9.6-31.5 0-47.4-9.6-57.6-9.6-42.9 0-80.6 20.5-105.1 51.9C61.9 339.2 48 299.2 48 256c0-110.3 89.7-200 200-200s200 89.7 200 200c0 43.2-13.9 83.2-37.3 115.9z\"]\n};\nvar faWindowClose = {\n prefix: 'far',\n iconName: 'window-close',\n icon: [512, 512, [], \"f410\", \"M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z\"]\n};\nvar faWindowMaximize = {\n prefix: 'far',\n iconName: 'window-maximize',\n icon: [512, 512, [], \"f2d0\", \"M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z\"]\n};\nvar faWindowMinimize = {\n prefix: 'far',\n iconName: 'window-minimize',\n icon: [512, 512, [], \"f2d1\", \"M480 480H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h448c17.7 0 32 14.3 32 32s-14.3 32-32 32z\"]\n};\nvar faWindowRestore = {\n prefix: 'far',\n iconName: 'window-restore',\n icon: [512, 512, [], \"f2d2\", \"M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z\"]\n};\nvar _iconsCache = {\n faAddressBook: faAddressBook,\n faAddressCard: faAddressCard,\n faAngry: faAngry,\n faArrowAltCircleDown: faArrowAltCircleDown,\n faArrowAltCircleLeft: faArrowAltCircleLeft,\n faArrowAltCircleRight: faArrowAltCircleRight,\n faArrowAltCircleUp: faArrowAltCircleUp,\n faBell: faBell,\n faBellSlash: faBellSlash,\n faBookmark: faBookmark,\n faBuilding: faBuilding,\n faCalendar: faCalendar,\n faCalendarAlt: faCalendarAlt,\n faCalendarCheck: faCalendarCheck,\n faCalendarMinus: faCalendarMinus,\n faCalendarPlus: faCalendarPlus,\n faCalendarTimes: faCalendarTimes,\n faCaretSquareDown: faCaretSquareDown,\n faCaretSquareLeft: faCaretSquareLeft,\n faCaretSquareRight: faCaretSquareRight,\n faCaretSquareUp: faCaretSquareUp,\n faChartBar: faChartBar,\n faCheckCircle: faCheckCircle,\n faCheckSquare: faCheckSquare,\n faCircle: faCircle,\n faClipboard: faClipboard,\n faClock: faClock,\n faClone: faClone,\n faClosedCaptioning: faClosedCaptioning,\n faComment: faComment,\n faCommentAlt: faCommentAlt,\n faCommentDots: faCommentDots,\n faComments: faComments,\n faCompass: faCompass,\n faCopy: faCopy,\n faCopyright: faCopyright,\n faCreditCard: faCreditCard,\n faDizzy: faDizzy,\n faDotCircle: faDotCircle,\n faEdit: faEdit,\n faEnvelope: faEnvelope,\n faEnvelopeOpen: faEnvelopeOpen,\n faEye: faEye,\n faEyeSlash: faEyeSlash,\n faFile: faFile,\n faFileAlt: faFileAlt,\n faFileArchive: faFileArchive,\n faFileAudio: faFileAudio,\n faFileCode: faFileCode,\n faFileExcel: faFileExcel,\n faFileImage: faFileImage,\n faFilePdf: faFilePdf,\n faFilePowerpoint: faFilePowerpoint,\n faFileVideo: faFileVideo,\n faFileWord: faFileWord,\n faFlag: faFlag,\n faFlushed: faFlushed,\n faFolder: faFolder,\n faFolderOpen: faFolderOpen,\n faFontAwesomeLogoFull: faFontAwesomeLogoFull,\n faFrown: faFrown,\n faFrownOpen: faFrownOpen,\n faFutbol: faFutbol,\n faGem: faGem,\n faGrimace: faGrimace,\n faGrin: faGrin,\n faGrinAlt: faGrinAlt,\n faGrinBeam: faGrinBeam,\n faGrinBeamSweat: faGrinBeamSweat,\n faGrinHearts: faGrinHearts,\n faGrinSquint: faGrinSquint,\n faGrinSquintTears: faGrinSquintTears,\n faGrinStars: faGrinStars,\n faGrinTears: faGrinTears,\n faGrinTongue: faGrinTongue,\n faGrinTongueSquint: faGrinTongueSquint,\n faGrinTongueWink: faGrinTongueWink,\n faGrinWink: faGrinWink,\n faHandLizard: faHandLizard,\n faHandPaper: faHandPaper,\n faHandPeace: faHandPeace,\n faHandPointDown: faHandPointDown,\n faHandPointLeft: faHandPointLeft,\n faHandPointRight: faHandPointRight,\n faHandPointUp: faHandPointUp,\n faHandPointer: faHandPointer,\n faHandRock: faHandRock,\n faHandScissors: faHandScissors,\n faHandSpock: faHandSpock,\n faHandshake: faHandshake,\n faHdd: faHdd,\n faHeart: faHeart,\n faHospital: faHospital,\n faHourglass: faHourglass,\n faIdBadge: faIdBadge,\n faIdCard: faIdCard,\n faImage: faImage,\n faImages: faImages,\n faKeyboard: faKeyboard,\n faKiss: faKiss,\n faKissBeam: faKissBeam,\n faKissWinkHeart: faKissWinkHeart,\n faLaugh: faLaugh,\n faLaughBeam: faLaughBeam,\n faLaughSquint: faLaughSquint,\n faLaughWink: faLaughWink,\n faLemon: faLemon,\n faLifeRing: faLifeRing,\n faLightbulb: faLightbulb,\n faListAlt: faListAlt,\n faMap: faMap,\n faMeh: faMeh,\n faMehBlank: faMehBlank,\n faMehRollingEyes: faMehRollingEyes,\n faMinusSquare: faMinusSquare,\n faMoneyBillAlt: faMoneyBillAlt,\n faMoon: faMoon,\n faNewspaper: faNewspaper,\n faObjectGroup: faObjectGroup,\n faObjectUngroup: faObjectUngroup,\n faPaperPlane: faPaperPlane,\n faPauseCircle: faPauseCircle,\n faPlayCircle: faPlayCircle,\n faPlusSquare: faPlusSquare,\n faQuestionCircle: faQuestionCircle,\n faRegistered: faRegistered,\n faSadCry: faSadCry,\n faSadTear: faSadTear,\n faSave: faSave,\n faShareSquare: faShareSquare,\n faSmile: faSmile,\n faSmileBeam: faSmileBeam,\n faSmileWink: faSmileWink,\n faSnowflake: faSnowflake,\n faSquare: faSquare,\n faStar: faStar,\n faStarHalf: faStarHalf,\n faStickyNote: faStickyNote,\n faStopCircle: faStopCircle,\n faSun: faSun,\n faSurprise: faSurprise,\n faThumbsDown: faThumbsDown,\n faThumbsUp: faThumbsUp,\n faTimesCircle: faTimesCircle,\n faTired: faTired,\n faTrashAlt: faTrashAlt,\n faUser: faUser,\n faUserCircle: faUserCircle,\n faWindowClose: faWindowClose,\n faWindowMaximize: faWindowMaximize,\n faWindowMinimize: faWindowMinimize,\n faWindowRestore: faWindowRestore\n};\n\nexport { _iconsCache as far, prefix, faAddressBook, faAddressCard, faAngry, faArrowAltCircleDown, faArrowAltCircleLeft, faArrowAltCircleRight, faArrowAltCircleUp, faBell, faBellSlash, faBookmark, faBuilding, faCalendar, faCalendarAlt, faCalendarCheck, faCalendarMinus, faCalendarPlus, faCalendarTimes, faCaretSquareDown, faCaretSquareLeft, faCaretSquareRight, faCaretSquareUp, faChartBar, faCheckCircle, faCheckSquare, faCircle, faClipboard, faClock, faClone, faClosedCaptioning, faComment, faCommentAlt, faCommentDots, faComments, faCompass, faCopy, faCopyright, faCreditCard, faDizzy, faDotCircle, faEdit, faEnvelope, faEnvelopeOpen, faEye, faEyeSlash, faFile, faFileAlt, faFileArchive, faFileAudio, faFileCode, faFileExcel, faFileImage, faFilePdf, faFilePowerpoint, faFileVideo, faFileWord, faFlag, faFlushed, faFolder, faFolderOpen, faFontAwesomeLogoFull, faFrown, faFrownOpen, faFutbol, faGem, faGrimace, faGrin, faGrinAlt, faGrinBeam, faGrinBeamSweat, faGrinHearts, faGrinSquint, faGrinSquintTears, faGrinStars, faGrinTears, faGrinTongue, faGrinTongueSquint, faGrinTongueWink, faGrinWink, faHandLizard, faHandPaper, faHandPeace, faHandPointDown, faHandPointLeft, faHandPointRight, faHandPointUp, faHandPointer, faHandRock, faHandScissors, faHandSpock, faHandshake, faHdd, faHeart, faHospital, faHourglass, faIdBadge, faIdCard, faImage, faImages, faKeyboard, faKiss, faKissBeam, faKissWinkHeart, faLaugh, faLaughBeam, faLaughSquint, faLaughWink, faLemon, faLifeRing, faLightbulb, faListAlt, faMap, faMeh, faMehBlank, faMehRollingEyes, faMinusSquare, faMoneyBillAlt, faMoon, faNewspaper, faObjectGroup, faObjectUngroup, faPaperPlane, faPauseCircle, faPlayCircle, faPlusSquare, faQuestionCircle, faRegistered, faSadCry, faSadTear, faSave, faShareSquare, faSmile, faSmileBeam, faSmileWink, faSnowflake, faSquare, faStar, faStarHalf, faStickyNote, faStopCircle, faSun, faSurprise, faThumbsDown, faThumbsUp, faTimesCircle, faTired, faTrashAlt, faUser, faUserCircle, faWindowClose, faWindowMaximize, faWindowMinimize, faWindowRestore };\n", + "var prefix = \"fas\";\nvar faAd = {\n prefix: 'fas',\n iconName: 'ad',\n icon: [512, 512, [], \"f641\", \"M157.52 272h36.96L176 218.78 157.52 272zM352 256c-13.23 0-24 10.77-24 24s10.77 24 24 24 24-10.77 24-24-10.77-24-24-24zM464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM250.58 352h-16.94c-6.81 0-12.88-4.32-15.12-10.75L211.15 320h-70.29l-7.38 21.25A16 16 0 0 1 118.36 352h-16.94c-11.01 0-18.73-10.85-15.12-21.25L140 176.12A23.995 23.995 0 0 1 162.67 160h26.66A23.99 23.99 0 0 1 212 176.13l53.69 154.62c3.61 10.4-4.11 21.25-15.11 21.25zM424 336c0 8.84-7.16 16-16 16h-16c-4.85 0-9.04-2.27-11.98-5.68-8.62 3.66-18.09 5.68-28.02 5.68-39.7 0-72-32.3-72-72s32.3-72 72-72c8.46 0 16.46 1.73 24 4.42V176c0-8.84 7.16-16 16-16h16c8.84 0 16 7.16 16 16v160z\"]\n};\nvar faAddressBook = {\n prefix: 'fas',\n iconName: 'address-book',\n icon: [448, 512, [], \"f2b9\", \"M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-228-32c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H118.4C106 384 96 375.4 96 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z\"]\n};\nvar faAddressCard = {\n prefix: 'fas',\n iconName: 'address-card',\n icon: [576, 512, [], \"f2bb\", \"M528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-352 96c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H86.4C74 384 64 375.4 64 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2zM512 312c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-64c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-64c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16z\"]\n};\nvar faAdjust = {\n prefix: 'fas',\n iconName: 'adjust',\n icon: [512, 512, [], \"f042\", \"M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z\"]\n};\nvar faAirFreshener = {\n prefix: 'fas',\n iconName: 'air-freshener',\n icon: [384, 512, [], \"f5d0\", \"M378.94 321.41L284.7 224h49.22c15.3 0 23.66-16.6 13.86-27.53L234.45 69.96c3.43-6.61 5.55-14 5.55-21.96 0-26.51-21.49-48-48-48s-48 21.49-48 48c0 7.96 2.12 15.35 5.55 21.96L36.22 196.47C26.42 207.4 34.78 224 50.08 224H99.3L5.06 321.41C-6.69 333.56 3.34 352 21.7 352H160v32H48c-8.84 0-16 7.16-16 16v96c0 8.84 7.16 16 16 16h288c8.84 0 16-7.16 16-16v-96c0-8.84-7.16-16-16-16H224v-32h138.3c18.36 0 28.39-18.44 16.64-30.59zM192 31.98c8.85 0 16.02 7.17 16.02 16.02 0 8.84-7.17 16.02-16.02 16.02S175.98 56.84 175.98 48c0-8.85 7.17-16.02 16.02-16.02zM304 432v32H80v-32h224z\"]\n};\nvar faAlignCenter = {\n prefix: 'fas',\n iconName: 'align-center',\n icon: [448, 512, [], \"f037\", \"M432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM108.1 96h231.81A12.09 12.09 0 0 0 352 83.9V44.09A12.09 12.09 0 0 0 339.91 32H108.1A12.09 12.09 0 0 0 96 44.09V83.9A12.1 12.1 0 0 0 108.1 96zm231.81 256A12.09 12.09 0 0 0 352 339.9v-39.81A12.09 12.09 0 0 0 339.91 288H108.1A12.09 12.09 0 0 0 96 300.09v39.81a12.1 12.1 0 0 0 12.1 12.1z\"]\n};\nvar faAlignJustify = {\n prefix: 'fas',\n iconName: 'align-justify',\n icon: [448, 512, [], \"f039\", \"M432 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-128H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-128H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-128H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faAlignLeft = {\n prefix: 'fas',\n iconName: 'align-left',\n icon: [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faAlignRight = {\n prefix: 'fas',\n iconName: 'align-right',\n icon: [448, 512, [], \"f038\", \"M16 224h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm416 192H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm3.17-384H172.83A12.82 12.82 0 0 0 160 44.83v38.34A12.82 12.82 0 0 0 172.83 96h262.34A12.82 12.82 0 0 0 448 83.17V44.83A12.82 12.82 0 0 0 435.17 32zm0 256H172.83A12.82 12.82 0 0 0 160 300.83v38.34A12.82 12.82 0 0 0 172.83 352h262.34A12.82 12.82 0 0 0 448 339.17v-38.34A12.82 12.82 0 0 0 435.17 288z\"]\n};\nvar faAllergies = {\n prefix: 'fas',\n iconName: 'allergies',\n icon: [448, 512, [], \"f461\", \"M416 112c-17.6 0-32 14.4-32 32v72c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V64c0-17.6-14.4-32-32-32s-32 14.4-32 32v152c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V32c0-17.6-14.4-32-32-32s-32 14.4-32 32v184c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V64c0-17.6-14.4-32-32-32S96 46.4 96 64v241l-23.6-32.5c-13-17.9-38-21.8-55.9-8.8s-21.8 38-8.8 55.9l125.6 172.7c9 12.4 23.5 19.8 38.8 19.8h197.6c22.3 0 41.6-15.3 46.7-37l26.5-112.7c3.2-13.7 4.9-28.3 5.1-42.3V144c0-17.6-14.4-32-32-32zM176 416c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-96c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm64 128c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-96c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm64 32c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm32 64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm32-128c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z\"]\n};\nvar faAmbulance = {\n prefix: 'fas',\n iconName: 'ambulance',\n icon: [640, 512, [], \"f0f9\", \"M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h16c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm144-248c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48zm176 248c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z\"]\n};\nvar faAmericanSignLanguageInterpreting = {\n prefix: 'fas',\n iconName: 'american-sign-language-interpreting',\n icon: [640, 512, [], \"f2a3\", \"M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z\"]\n};\nvar faAnchor = {\n prefix: 'fas',\n iconName: 'anchor',\n icon: [576, 512, [], \"f13d\", \"M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z\"]\n};\nvar faAngleDoubleDown = {\n prefix: 'fas',\n iconName: 'angle-double-down',\n icon: [320, 512, [], \"f103\", \"M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z\"]\n};\nvar faAngleDoubleLeft = {\n prefix: 'fas',\n iconName: 'angle-double-left',\n icon: [448, 512, [], \"f100\", \"M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z\"]\n};\nvar faAngleDoubleRight = {\n prefix: 'fas',\n iconName: 'angle-double-right',\n icon: [448, 512, [], \"f101\", \"M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z\"]\n};\nvar faAngleDoubleUp = {\n prefix: 'fas',\n iconName: 'angle-double-up',\n icon: [320, 512, [], \"f102\", \"M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z\"]\n};\nvar faAngleDown = {\n prefix: 'fas',\n iconName: 'angle-down',\n icon: [320, 512, [], \"f107\", \"M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z\"]\n};\nvar faAngleLeft = {\n prefix: 'fas',\n iconName: 'angle-left',\n icon: [256, 512, [], \"f104\", \"M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z\"]\n};\nvar faAngleRight = {\n prefix: 'fas',\n iconName: 'angle-right',\n icon: [256, 512, [], \"f105\", \"M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z\"]\n};\nvar faAngleUp = {\n prefix: 'fas',\n iconName: 'angle-up',\n icon: [320, 512, [], \"f106\", \"M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z\"]\n};\nvar faAngry = {\n prefix: 'fas',\n iconName: 'angry',\n icon: [496, 512, [], \"f556\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM136 240c0-9.3 4.1-17.5 10.5-23.4l-31-9.3c-8.5-2.5-13.3-11.5-10.7-19.9 2.5-8.5 11.4-13.2 19.9-10.7l80 24c8.5 2.5 13.3 11.5 10.7 19.9-2.1 6.9-8.4 11.4-15.3 11.4-.5 0-1.1-.2-1.7-.2.7 2.7 1.7 5.3 1.7 8.2 0 17.7-14.3 32-32 32S136 257.7 136 240zm168 154.2c-27.8-33.4-84.2-33.4-112.1 0-13.5 16.3-38.2-4.2-24.6-20.5 20-24 49.4-37.8 80.6-37.8s60.6 13.8 80.6 37.8c13.8 16.5-11.1 36.6-24.5 20.5zm76.6-186.9l-31 9.3c6.3 5.8 10.5 14.1 10.5 23.4 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-2.9.9-5.6 1.7-8.2-.6.1-1.1.2-1.7.2-6.9 0-13.2-4.5-15.3-11.4-2.5-8.5 2.3-17.4 10.7-19.9l80-24c8.4-2.5 17.4 2.3 19.9 10.7 2.5 8.5-2.3 17.4-10.8 19.9z\"]\n};\nvar faAnkh = {\n prefix: 'fas',\n iconName: 'ankh',\n icon: [320, 512, [], \"f644\", \"M296 256h-44.62C272.46 222.01 288 181.65 288 144 288 55.63 230.69 0 160 0S32 55.63 32 144c0 37.65 15.54 78.01 36.62 112H24c-13.25 0-24 10.74-24 24v32c0 13.25 10.75 24 24 24h96v152c0 13.25 10.75 24 24 24h32c13.25 0 24-10.75 24-24V336h96c13.25 0 24-10.75 24-24v-32c0-13.26-10.75-24-24-24zM160 80c29.61 0 48 24.52 48 64 0 34.66-27.14 78.14-48 100.87-20.86-22.72-48-66.21-48-100.87 0-39.48 18.39-64 48-64z\"]\n};\nvar faAppleAlt = {\n prefix: 'fas',\n iconName: 'apple-alt',\n icon: [448, 512, [], \"f5d1\", \"M350.85 129c25.97 4.67 47.27 18.67 63.92 42 14.65 20.67 24.64 46.67 29.96 78 4.67 28.67 4.32 57.33-1 86-7.99 47.33-23.97 87-47.94 119-28.64 38.67-64.59 58-107.87 58-10.66 0-22.3-3.33-34.96-10-8.66-5.33-18.31-8-28.97-8s-20.3 2.67-28.97 8c-12.66 6.67-24.3 10-34.96 10-43.28 0-79.23-19.33-107.87-58-23.97-32-39.95-71.67-47.94-119-5.32-28.67-5.67-57.33-1-86 5.32-31.33 15.31-57.33 29.96-78 16.65-23.33 37.95-37.33 63.92-42 15.98-2.67 37.95-.33 65.92 7 23.97 6.67 44.28 14.67 60.93 24 16.65-9.33 36.96-17.33 60.93-24 27.98-7.33 49.96-9.67 65.94-7zm-54.94-41c-9.32 8.67-21.65 15-36.96 19-10.66 3.33-22.3 5-34.96 5l-14.98-1c-1.33-9.33-1.33-20 0-32 2.67-24 10.32-42.33 22.97-55 9.32-8.67 21.65-15 36.96-19 10.66-3.33 22.3-5 34.96-5l14.98 1 1 15c0 12.67-1.67 24.33-4.99 35-3.99 15.33-10.31 27.67-18.98 37z\"]\n};\nvar faArchive = {\n prefix: 'fas',\n iconName: 'archive',\n icon: [512, 512, [], \"f187\", \"M32 448c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32V160H32v288zm160-212c0-6.6 5.4-12 12-12h104c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-8zM480 32H32C14.3 32 0 46.3 0 64v48c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16V64c0-17.7-14.3-32-32-32z\"]\n};\nvar faArchway = {\n prefix: 'fas',\n iconName: 'archway',\n icon: [576, 512, [], \"f557\", \"M560 448h-16V96H32v352H16.02c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16H176c8.84 0 16-7.16 16-16V320c0-53.02 42.98-96 96-96s96 42.98 96 96l.02 160v16c0 8.84 7.16 16 16 16H560c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm0-448H16C7.16 0 0 7.16 0 16v32c0 8.84 7.16 16 16 16h544c8.84 0 16-7.16 16-16V16c0-8.84-7.16-16-16-16z\"]\n};\nvar faArrowAltCircleDown = {\n prefix: 'fas',\n iconName: 'arrow-alt-circle-down',\n icon: [512, 512, [], \"f358\", \"M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z\"]\n};\nvar faArrowAltCircleLeft = {\n prefix: 'fas',\n iconName: 'arrow-alt-circle-left',\n icon: [512, 512, [], \"f359\", \"M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z\"]\n};\nvar faArrowAltCircleRight = {\n prefix: 'fas',\n iconName: 'arrow-alt-circle-right',\n icon: [512, 512, [], \"f35a\", \"M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z\"]\n};\nvar faArrowAltCircleUp = {\n prefix: 'fas',\n iconName: 'arrow-alt-circle-up',\n icon: [512, 512, [], \"f35b\", \"M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z\"]\n};\nvar faArrowCircleDown = {\n prefix: 'fas',\n iconName: 'arrow-circle-down',\n icon: [512, 512, [], \"f0ab\", \"M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z\"]\n};\nvar faArrowCircleLeft = {\n prefix: 'fas',\n iconName: 'arrow-circle-left',\n icon: [512, 512, [], \"f0a8\", \"M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z\"]\n};\nvar faArrowCircleRight = {\n prefix: 'fas',\n iconName: 'arrow-circle-right',\n icon: [512, 512, [], \"f0a9\", \"M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z\"]\n};\nvar faArrowCircleUp = {\n prefix: 'fas',\n iconName: 'arrow-circle-up',\n icon: [512, 512, [], \"f0aa\", \"M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z\"]\n};\nvar faArrowDown = {\n prefix: 'fas',\n iconName: 'arrow-down',\n icon: [448, 512, [], \"f063\", \"M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z\"]\n};\nvar faArrowLeft = {\n prefix: 'fas',\n iconName: 'arrow-left',\n icon: [448, 512, [], \"f060\", \"M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z\"]\n};\nvar faArrowRight = {\n prefix: 'fas',\n iconName: 'arrow-right',\n icon: [448, 512, [], \"f061\", \"M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z\"]\n};\nvar faArrowUp = {\n prefix: 'fas',\n iconName: 'arrow-up',\n icon: [448, 512, [], \"f062\", \"M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z\"]\n};\nvar faArrowsAlt = {\n prefix: 'fas',\n iconName: 'arrows-alt',\n icon: [512, 512, [], \"f0b2\", \"M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z\"]\n};\nvar faArrowsAltH = {\n prefix: 'fas',\n iconName: 'arrows-alt-h',\n icon: [512, 512, [], \"f337\", \"M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z\"]\n};\nvar faArrowsAltV = {\n prefix: 'fas',\n iconName: 'arrows-alt-v',\n icon: [256, 512, [], \"f338\", \"M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z\"]\n};\nvar faAssistiveListeningSystems = {\n prefix: 'fas',\n iconName: 'assistive-listening-systems',\n icon: [512, 512, [], \"f2a2\", \"M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z\"]\n};\nvar faAsterisk = {\n prefix: 'fas',\n iconName: 'asterisk',\n icon: [512, 512, [], \"f069\", \"M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z\"]\n};\nvar faAt = {\n prefix: 'fas',\n iconName: 'at',\n icon: [512, 512, [], \"f1fa\", \"M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z\"]\n};\nvar faAtlas = {\n prefix: 'fas',\n iconName: 'atlas',\n icon: [448, 512, [], \"f558\", \"M318.38 208h-39.09c-1.49 27.03-6.54 51.35-14.21 70.41 27.71-13.24 48.02-39.19 53.3-70.41zm0-32c-5.29-31.22-25.59-57.17-53.3-70.41 7.68 19.06 12.72 43.38 14.21 70.41h39.09zM224 97.31c-7.69 7.45-20.77 34.42-23.43 78.69h46.87c-2.67-44.26-15.75-71.24-23.44-78.69zm-41.08 8.28c-27.71 13.24-48.02 39.19-53.3 70.41h39.09c1.49-27.03 6.53-51.35 14.21-70.41zm0 172.82c-7.68-19.06-12.72-43.38-14.21-70.41h-39.09c5.28 31.22 25.59 57.17 53.3 70.41zM247.43 208h-46.87c2.66 44.26 15.74 71.24 23.43 78.69 7.7-7.45 20.78-34.43 23.44-78.69zM448 358.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM224 64c70.69 0 128 57.31 128 128s-57.31 128-128 128S96 262.69 96 192 153.31 64 224 64zm160 384H96c-19.2 0-32-12.8-32-32s16-32 32-32h288v64z\"]\n};\nvar faAtom = {\n prefix: 'fas',\n iconName: 'atom',\n icon: [448, 512, [], \"f5d2\", \"M413.03 256c40.13-54.89 41.51-98.62 25.14-128-10.91-19.52-40.54-50.73-116.33-41.88C300.36 34.89 267.64 0 224 0s-76.36 34.89-97.84 86.12C50.43 77.34 20.73 108.48 9.83 128c-16.38 29.4-15 73.09 25.14 128-40.13 54.89-41.51 98.62-25.14 128 29.21 52.34 101.68 43.58 116.33 41.88C147.63 477.1 180.36 512 224 512s76.37-34.9 97.84-86.12c14.64 1.7 87.11 10.46 116.33-41.88 16.38-29.4 15-73.09-25.14-128zM63.38 352c-4.03-7.21-.19-24.8 14.95-48.29 6.96 6.53 14.2 12.89 21.87 19.18 1.71 13.71 4 27.08 6.76 40.08-24.56.89-39.89-4.37-43.58-10.97zm36.82-162.88c-7.66 6.29-14.9 12.65-21.87 19.18-15.13-23.5-18.97-41.09-14.95-48.3 3.41-6.14 16.39-11.47 37.92-11.47 1.71 0 3.87.3 5.69.37a472.191 472.191 0 0 0-6.79 40.22zM224 64c9.47 0 22.2 13.52 33.86 37.26-11.19 3.7-22.44 8-33.86 12.86-11.42-4.86-22.67-9.16-33.86-12.86C201.8 77.52 214.53 64 224 64zm0 384c-9.47 0-22.2-13.52-33.86-37.26 11.19-3.7 22.44-8 33.86-12.86 11.42 4.86 22.67 9.16 33.86 12.86C246.2 434.48 233.47 448 224 448zm62.5-157.33c-26.7 19.08-46.14 29.33-62.5 37.48-16.35-8.14-35.8-18.41-62.5-37.48-1.99-27.79-1.99-41.54 0-69.33 26.67-19.05 46.13-29.32 62.5-37.48 16.39 8.17 35.86 18.44 62.5 37.48 1.98 27.78 1.99 41.53 0 69.33zM384.62 352c-3.67 6.62-19 11.82-43.58 10.95 2.76-13 5.05-26.37 6.76-40.06 7.66-6.29 14.9-12.65 21.87-19.18 15.13 23.49 18.97 41.08 14.95 48.29zm-14.95-143.71c-6.96-6.53-14.2-12.89-21.87-19.18a473.535 473.535 0 0 0-6.79-40.22c1.82-.07 3.97-.37 5.69-.37 21.52 0 34.51 5.34 37.92 11.47 4.02 7.22.18 24.81-14.95 48.3zM224 224c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z\"]\n};\nvar faAudioDescription = {\n prefix: 'fas',\n iconName: 'audio-description',\n icon: [512, 512, [], \"f29e\", \"M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z\"]\n};\nvar faAward = {\n prefix: 'fas',\n iconName: 'award',\n icon: [384, 512, [], \"f559\", \"M97.12 362.63c-8.69-8.69-4.16-6.24-25.12-11.85-9.51-2.55-17.87-7.45-25.43-13.32L1.2 448.7c-4.39 10.77 3.81 22.47 15.43 22.03l52.69-2.01L105.56 507c8 8.44 22.04 5.81 26.43-4.96l52.05-127.62c-10.84 6.04-22.87 9.58-35.31 9.58-19.5 0-37.82-7.59-51.61-21.37zM382.8 448.7l-45.37-111.24c-7.56 5.88-15.92 10.77-25.43 13.32-21.07 5.64-16.45 3.18-25.12 11.85-13.79 13.78-32.12 21.37-51.62 21.37-12.44 0-24.47-3.55-35.31-9.58L252 502.04c4.39 10.77 18.44 13.4 26.43 4.96l36.25-38.28 52.69 2.01c11.62.44 19.82-11.27 15.43-22.03zM263 340c15.28-15.55 17.03-14.21 38.79-20.14 13.89-3.79 24.75-14.84 28.47-28.98 7.48-28.4 5.54-24.97 25.95-45.75 10.17-10.35 14.14-25.44 10.42-39.58-7.47-28.38-7.48-24.42 0-52.83 3.72-14.14-.25-29.23-10.42-39.58-20.41-20.78-18.47-17.36-25.95-45.75-3.72-14.14-14.58-25.19-28.47-28.98-27.88-7.61-24.52-5.62-44.95-26.41-10.17-10.35-25-14.4-38.89-10.61-27.87 7.6-23.98 7.61-51.9 0-13.89-3.79-28.72.25-38.89 10.61-20.41 20.78-17.05 18.8-44.94 26.41-13.89 3.79-24.75 14.84-28.47 28.98-7.47 28.39-5.54 24.97-25.95 45.75-10.17 10.35-14.15 25.44-10.42 39.58 7.47 28.36 7.48 24.4 0 52.82-3.72 14.14.25 29.23 10.42 39.59 20.41 20.78 18.47 17.35 25.95 45.75 3.72 14.14 14.58 25.19 28.47 28.98C104.6 325.96 106.27 325 121 340c13.23 13.47 33.84 15.88 49.74 5.82a39.676 39.676 0 0 1 42.53 0c15.89 10.06 36.5 7.65 49.73-5.82zM97.66 175.96c0-53.03 42.24-96.02 94.34-96.02s94.34 42.99 94.34 96.02-42.24 96.02-94.34 96.02-94.34-42.99-94.34-96.02z\"]\n};\nvar faBaby = {\n prefix: 'fas',\n iconName: 'baby',\n icon: [384, 512, [], \"f77c\", \"M192 160c44.2 0 80-35.8 80-80S236.2 0 192 0s-80 35.8-80 80 35.8 80 80 80zm-53.4 248.8l25.6-32-61.5-51.2L56.8 383c-11.4 14.2-11.7 34.4-.8 49l48 64c7.9 10.5 19.9 16 32 16 8.3 0 16.8-2.6 24-8 17.7-13.2 21.2-38.3 8-56l-29.4-39.2zm142.7-83.2l-61.5 51.2 25.6 32L216 448c-13.2 17.7-9.7 42.8 8 56 7.2 5.4 15.6 8 24 8 12.2 0 24.2-5.5 32-16l48-64c10.9-14.6 10.6-34.8-.8-49l-45.9-57.4zM376.7 145c-12.7-18.1-37.6-22.4-55.7-9.8l-40.6 28.5c-52.7 37-124.2 37-176.8 0L63 135.3C44.9 122.6 20 127 7.3 145-5.4 163.1-1 188 17 200.7l40.6 28.5c17 11.9 35.4 20.9 54.4 27.9V288h160v-30.8c19-7 37.4-16 54.4-27.9l40.6-28.5c18.1-12.8 22.4-37.7 9.7-55.8z\"]\n};\nvar faBabyCarriage = {\n prefix: 'fas',\n iconName: 'baby-carriage',\n icon: [512, 512, [], \"f77d\", \"M144.8 17c-11.3-17.8-37.2-22.8-54-9.4C35.3 51.9 0 118 0 192h256L144.8 17zM496 96h-48c-35.3 0-64 28.7-64 64v64H0c0 50.6 23 96.4 60.3 130.7C25.7 363.6 0 394.7 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-8.9-1.8-17.2-4.4-25.2 21.6 5.9 44.6 9.2 68.4 9.2s46.9-3.3 68.4-9.2c-2.7 8-4.4 16.3-4.4 25.2 0 44.2 35.8 80 80 80s80-35.8 80-80c0-37.3-25.7-68.4-60.3-77.3C425 320.4 448 274.6 448 224v-64h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM80 464c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zm320-32c0 17.6-14.4 32-32 32s-32-14.4-32-32 14.4-32 32-32 32 14.4 32 32z\"]\n};\nvar faBackspace = {\n prefix: 'fas',\n iconName: 'backspace',\n icon: [640, 512, [], \"f55a\", \"M576 64H205.26A63.97 63.97 0 0 0 160 82.75L9.37 233.37c-12.5 12.5-12.5 32.76 0 45.25L160 429.25c12 12 28.28 18.75 45.25 18.75H576c35.35 0 64-28.65 64-64V128c0-35.35-28.65-64-64-64zm-84.69 254.06c6.25 6.25 6.25 16.38 0 22.63l-22.62 22.62c-6.25 6.25-16.38 6.25-22.63 0L384 301.25l-62.06 62.06c-6.25 6.25-16.38 6.25-22.63 0l-22.62-22.62c-6.25-6.25-6.25-16.38 0-22.63L338.75 256l-62.06-62.06c-6.25-6.25-6.25-16.38 0-22.63l22.62-22.62c6.25-6.25 16.38-6.25 22.63 0L384 210.75l62.06-62.06c6.25-6.25 16.38-6.25 22.63 0l22.62 22.62c6.25 6.25 6.25 16.38 0 22.63L429.25 256l62.06 62.06z\"]\n};\nvar faBackward = {\n prefix: 'fas',\n iconName: 'backward',\n icon: [512, 512, [], \"f04a\", \"M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z\"]\n};\nvar faBacon = {\n prefix: 'fas',\n iconName: 'bacon',\n icon: [576, 512, [], \"f7e5\", \"M218.92 336.39c34.89-34.89 44.2-59.7 54.05-86 10.61-28.29 21.59-57.54 61.37-97.34s69.05-50.77 97.35-61.38c23.88-9 46.64-17.68 76.79-45.37L470.81 8.91a31 31 0 0 0-40.18-2.83c-13.64 10.1-25.15 14.39-41 20.3C247 79.52 209.26 191.29 200.65 214.1c-29.75 78.83-89.55 94.68-98.72 98.09-24.86 9.26-54.73 20.38-91.07 50.36C-3 374-3.63 395 9.07 407.61l35.76 35.51C80 410.52 107 400.15 133 390.39c26.27-9.84 51.06-19.12 85.92-54zm348-232l-35.75-35.51c-35.19 32.63-62.18 43-88.25 52.79-26.26 9.85-51.06 19.16-85.95 54s-44.19 59.69-54 86C292.33 290 281.34 319.22 241.55 359s-69 50.73-97.3 61.32c-23.86 9-46.61 17.66-76.72 45.33l37.68 37.43a31 31 0 0 0 40.18 2.82c13.6-10.06 25.09-14.34 40.94-20.24 142.2-53 180-164.1 188.94-187.69C405 219.18 464.8 203.3 474 199.86c24.87-9.27 54.74-20.4 91.11-50.41 13.89-11.4 14.52-32.45 1.82-45.05z\"]\n};\nvar faBalanceScale = {\n prefix: 'fas',\n iconName: 'balance-scale',\n icon: [640, 512, [], \"f24e\", \"M256 336h-.02c0-16.18 1.34-8.73-85.05-181.51-17.65-35.29-68.19-35.36-85.87 0C-2.06 328.75.02 320.33.02 336H0c0 44.18 57.31 80 128 80s128-35.82 128-80zM128 176l72 144H56l72-144zm511.98 160c0-16.18 1.34-8.73-85.05-181.51-17.65-35.29-68.19-35.36-85.87 0-87.12 174.26-85.04 165.84-85.04 181.51H384c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02zM440 320l72-144 72 144H440zm88 128H352V153.25c23.51-10.29 41.16-31.48 46.39-57.25H528c8.84 0 16-7.16 16-16V48c0-8.84-7.16-16-16-16H383.64C369.04 12.68 346.09 0 320 0s-49.04 12.68-63.64 32H112c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h129.61c5.23 25.76 22.87 46.96 46.39 57.25V448H112c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faBalanceScaleLeft = {\n prefix: 'fas',\n iconName: 'balance-scale-left',\n icon: [640, 512, [], \"f515\", \"M528 448H352V153.25c20.42-8.94 36.1-26.22 43.38-47.47l132-44.26c8.38-2.81 12.89-11.88 10.08-20.26l-10.17-30.34C524.48 2.54 515.41-1.97 507.03.84L389.11 40.37C375.3 16.36 349.69 0 320 0c-44.18 0-80 35.82-80 80 0 3.43.59 6.71 1.01 10.03l-128.39 43.05c-8.38 2.81-12.89 11.88-10.08 20.26l10.17 30.34c2.81 8.38 11.88 12.89 20.26 10.08l142.05-47.63c4.07 2.77 8.43 5.12 12.99 7.12V496c0 8.84 7.16 16 16 16h224c8.84 0 16-7.16 16-16v-32c-.01-8.84-7.17-16-16.01-16zm111.98-144c0-16.18 1.34-8.73-85.05-181.51-17.65-35.29-68.19-35.36-85.87 0-87.12 174.26-85.04 165.84-85.04 181.51H384c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02zM440 288l72-144 72 144H440zm-269.07-37.51c-17.65-35.29-68.19-35.36-85.87 0C-2.06 424.75.02 416.33.02 432H0c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02c0-16.18 1.34-8.73-85.05-181.51zM56 416l72-144 72 144H56z\"]\n};\nvar faBalanceScaleRight = {\n prefix: 'fas',\n iconName: 'balance-scale-right',\n icon: [640, 512, [], \"f516\", \"M96 464v32c0 8.84 7.16 16 16 16h224c8.84 0 16-7.16 16-16V153.25c4.56-2 8.92-4.35 12.99-7.12l142.05 47.63c8.38 2.81 17.45-1.71 20.26-10.08l10.17-30.34c2.81-8.38-1.71-17.45-10.08-20.26l-128.4-43.05c.42-3.32 1.01-6.6 1.01-10.03 0-44.18-35.82-80-80-80-29.69 0-55.3 16.36-69.11 40.37L132.96.83c-8.38-2.81-17.45 1.71-20.26 10.08l-10.17 30.34c-2.81 8.38 1.71 17.45 10.08 20.26l132 44.26c7.28 21.25 22.96 38.54 43.38 47.47V448H112c-8.84 0-16 7.16-16 16zM0 304c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02c0-15.67 2.08-7.25-85.05-181.51-17.68-35.36-68.22-35.29-85.87 0C-1.32 295.27.02 287.82.02 304H0zm56-16l72-144 72 144H56zm328.02 144H384c0 44.18 57.31 80 128 80s128-35.82 128-80h-.02c0-15.67 2.08-7.25-85.05-181.51-17.68-35.36-68.22-35.29-85.87 0-86.38 172.78-85.04 165.33-85.04 181.51zM440 416l72-144 72 144H440z\"]\n};\nvar faBan = {\n prefix: 'fas',\n iconName: 'ban',\n icon: [512, 512, [], \"f05e\", \"M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z\"]\n};\nvar faBandAid = {\n prefix: 'fas',\n iconName: 'band-aid',\n icon: [640, 512, [], \"f462\", \"M0 160v192c0 35.3 28.7 64 64 64h96V96H64c-35.3 0-64 28.7-64 64zm576-64h-96v320h96c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64zM192 416h256V96H192v320zm176-232c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm0 96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-96-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm0 96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24z\"]\n};\nvar faBarcode = {\n prefix: 'fas',\n iconName: 'barcode',\n icon: [512, 512, [], \"f02a\", \"M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z\"]\n};\nvar faBars = {\n prefix: 'fas',\n iconName: 'bars',\n icon: [448, 512, [], \"f0c9\", \"M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z\"]\n};\nvar faBaseballBall = {\n prefix: 'fas',\n iconName: 'baseball-ball',\n icon: [496, 512, [], \"f433\", \"M368.5 363.9l28.8-13.9c11.1 22.9 26 43.2 44.1 60.9 34-42.5 54.5-96.3 54.5-154.9 0-58.5-20.4-112.2-54.2-154.6-17.8 17.3-32.6 37.1-43.6 59.5l-28.7-14.1c12.8-26 30-49 50.8-69C375.6 34.7 315 8 248 8 181.1 8 120.5 34.6 75.9 77.7c20.7 19.9 37.9 42.9 50.7 68.8l-28.7 14.1c-11-22.3-25.7-42.1-43.5-59.4C20.4 143.7 0 197.4 0 256c0 58.6 20.4 112.3 54.4 154.7 18.2-17.7 33.2-38 44.3-61l28.8 13.9c-12.9 26.7-30.3 50.3-51.5 70.7 44.5 43.1 105.1 69.7 172 69.7 66.8 0 127.3-26.5 171.9-69.5-21.1-20.4-38.5-43.9-51.4-70.6zm-228.3-32l-30.5-9.8c14.9-46.4 12.7-93.8-.6-134l30.4-10c15 45.6 18 99.9.7 153.8zm216.3-153.4l30.4 10c-13.2 40.1-15.5 87.5-.6 134l-30.5 9.8c-17.3-54-14.3-108.3.7-153.8z\"]\n};\nvar faBasketballBall = {\n prefix: 'fas',\n iconName: 'basketball-ball',\n icon: [496, 512, [], \"f434\", \"M212.3 10.3c-43.8 6.3-86.2 24.1-122.2 53.8l77.4 77.4c27.8-35.8 43.3-81.2 44.8-131.2zM248 222L405.9 64.1c-42.4-35-93.6-53.5-145.5-56.1-1.2 63.9-21.5 122.3-58.7 167.7L248 222zM56.1 98.1c-29.7 36-47.5 78.4-53.8 122.2 50-1.5 95.5-17 131.2-44.8L56.1 98.1zm272.2 204.2c45.3-37.1 103.7-57.4 167.7-58.7-2.6-51.9-21.1-103.1-56.1-145.5L282 256l46.3 46.3zM248 290L90.1 447.9c42.4 34.9 93.6 53.5 145.5 56.1 1.3-64 21.6-122.4 58.7-167.7L248 290zm191.9 123.9c29.7-36 47.5-78.4 53.8-122.2-50.1 1.6-95.5 17.1-131.2 44.8l77.4 77.4zM167.7 209.7C122.3 246.9 63.9 267.3 0 268.4c2.6 51.9 21.1 103.1 56.1 145.5L214 256l-46.3-46.3zm116 292c43.8-6.3 86.2-24.1 122.2-53.8l-77.4-77.4c-27.7 35.7-43.2 81.2-44.8 131.2z\"]\n};\nvar faBath = {\n prefix: 'fas',\n iconName: 'bath',\n icon: [512, 512, [], \"f2cd\", \"M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z\"]\n};\nvar faBatteryEmpty = {\n prefix: 'fas',\n iconName: 'battery-empty',\n icon: [640, 512, [], \"f244\", \"M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z\"]\n};\nvar faBatteryFull = {\n prefix: 'fas',\n iconName: 'battery-full',\n icon: [640, 512, [], \"f240\", \"M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z\"]\n};\nvar faBatteryHalf = {\n prefix: 'fas',\n iconName: 'battery-half',\n icon: [640, 512, [], \"f242\", \"M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z\"]\n};\nvar faBatteryQuarter = {\n prefix: 'fas',\n iconName: 'battery-quarter',\n icon: [640, 512, [], \"f243\", \"M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z\"]\n};\nvar faBatteryThreeQuarters = {\n prefix: 'fas',\n iconName: 'battery-three-quarters',\n icon: [640, 512, [], \"f241\", \"M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z\"]\n};\nvar faBed = {\n prefix: 'fas',\n iconName: 'bed',\n icon: [640, 512, [], \"f236\", \"M176 256c44.11 0 80-35.89 80-80s-35.89-80-80-80-80 35.89-80 80 35.89 80 80 80zm352-128H304c-8.84 0-16 7.16-16 16v144H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v352c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48h512v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V240c0-61.86-50.14-112-112-112z\"]\n};\nvar faBeer = {\n prefix: 'fas',\n iconName: 'beer',\n icon: [448, 512, [], \"f0fc\", \"M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z\"]\n};\nvar faBell = {\n prefix: 'fas',\n iconName: 'bell',\n icon: [448, 512, [], \"f0f3\", \"M224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64zm215.39-149.71c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71z\"]\n};\nvar faBellSlash = {\n prefix: 'fas',\n iconName: 'bell-slash',\n icon: [640, 512, [], \"f1f6\", \"M633.82 458.1l-90.62-70.05c.19-1.38.8-2.66.8-4.06.05-7.55-2.61-15.27-8.61-21.71-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84c-40.33 8.38-74.66 31.07-97.59 62.57L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.35 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.42-6.97 4.17-17.02-2.81-22.45zM157.23 251.54c-8.61 67.96-36.41 93.33-52.62 110.75-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h241.92L157.23 251.54zM320 512c35.32 0 63.97-28.65 63.97-64H256.03c0 35.35 28.65 64 63.97 64z\"]\n};\nvar faBezierCurve = {\n prefix: 'fas',\n iconName: 'bezier-curve',\n icon: [640, 512, [], \"f55b\", \"M368 32h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V64c0-17.67-14.33-32-32-32zM208 88h-84.75C113.75 64.56 90.84 48 64 48 28.66 48 0 76.65 0 112s28.66 64 64 64c26.84 0 49.75-16.56 59.25-40h79.73c-55.37 32.52-95.86 87.32-109.54 152h49.4c11.3-41.61 36.77-77.21 71.04-101.56-3.7-8.08-5.88-16.99-5.88-26.44V88zm-48 232H64c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32zM576 48c-26.84 0-49.75 16.56-59.25 40H432v72c0 9.45-2.19 18.36-5.88 26.44 34.27 24.35 59.74 59.95 71.04 101.56h49.4c-13.68-64.68-54.17-119.48-109.54-152h79.73c9.5 23.44 32.41 40 59.25 40 35.34 0 64-28.65 64-64s-28.66-64-64-64zm0 272h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32z\"]\n};\nvar faBible = {\n prefix: 'fas',\n iconName: 'bible',\n icon: [448, 512, [], \"f647\", \"M448 358.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM144 144c0-8.84 7.16-16 16-16h48V80c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v48h48c8.84 0 16 7.16 16 16v32c0 8.84-7.16 16-16 16h-48v112c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16V192h-48c-8.84 0-16-7.16-16-16v-32zm236.8 304H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8v64z\"]\n};\nvar faBicycle = {\n prefix: 'fas',\n iconName: 'bicycle',\n icon: [640, 512, [], \"f206\", \"M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z\"]\n};\nvar faBiking = {\n prefix: 'fas',\n iconName: 'biking',\n icon: [640, 512, [], \"f84a\", \"M400 96a48 48 0 1 0-48-48 48 48 0 0 0 48 48zm-4 121a31.9 31.9 0 0 0 20 7h64a32 32 0 0 0 0-64h-52.78L356 103a31.94 31.94 0 0 0-40.81.68l-112 96a32 32 0 0 0 3.08 50.92L288 305.12V416a32 32 0 0 0 64 0V288a32 32 0 0 0-14.25-26.62l-41.36-27.57 58.25-49.92zm116 39a128 128 0 1 0 128 128 128 128 0 0 0-128-128zm0 192a64 64 0 1 1 64-64 64 64 0 0 1-64 64zM128 256a128 128 0 1 0 128 128 128 128 0 0 0-128-128zm0 192a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]\n};\nvar faBinoculars = {\n prefix: 'fas',\n iconName: 'binoculars',\n icon: [512, 512, [], \"f1e5\", \"M416 48c0-8.84-7.16-16-16-16h-64c-8.84 0-16 7.16-16 16v48h96V48zM63.91 159.99C61.4 253.84 3.46 274.22 0 404v44c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V288h32V128H95.84c-17.63 0-31.45 14.37-31.93 31.99zm384.18 0c-.48-17.62-14.3-31.99-31.93-31.99H320v160h32v160c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-44c-3.46-129.78-61.4-150.16-63.91-244.01zM176 32h-64c-8.84 0-16 7.16-16 16v48h96V48c0-8.84-7.16-16-16-16zm48 256h64V128h-64v160z\"]\n};\nvar faBiohazard = {\n prefix: 'fas',\n iconName: 'biohazard',\n icon: [576, 512, [], \"f780\", \"M287.9 112c18.6 0 36.2 3.8 52.8 9.6 13.3-10.3 23.6-24.3 29.5-40.7-25.2-10.9-53-17-82.2-17-29.1 0-56.9 6-82.1 16.9 5.9 16.4 16.2 30.4 29.5 40.7 16.5-5.7 34-9.5 52.5-9.5zM163.6 438.7c12-11.8 20.4-26.4 24.5-42.4-32.9-26.4-54.8-65.3-58.9-109.6-8.5-2.8-17.2-4.6-26.4-4.6-7.6 0-15.2 1-22.5 3.1 4.1 62.8 35.8 118 83.3 153.5zm224.2-42.6c4.1 16 12.5 30.7 24.5 42.5 47.4-35.5 79.1-90.7 83-153.5-7.2-2-14.7-3-22.2-3-9.2 0-18 1.9-26.6 4.7-4.1 44.2-26 82.9-58.7 109.3zm113.5-205c-17.6-10.4-36.3-16.6-55.3-19.9 6-17.7 10-36.4 10-56.2 0-41-14.5-80.8-41-112.2-2.5-3-6.6-3.7-10-1.8-3.3 1.9-4.8 6-3.6 9.7 4.5 13.8 6.6 26.3 6.6 38.5 0 67.8-53.8 122.9-120 122.9S168 117 168 49.2c0-12.1 2.2-24.7 6.6-38.5 1.2-3.7-.3-7.8-3.6-9.7-3.4-1.9-7.5-1.2-10 1.8C134.6 34.2 120 74 120 115c0 19.8 3.9 38.5 10 56.2-18.9 3.3-37.7 9.5-55.3 19.9-34.6 20.5-61 53.3-74.3 92.4-1.3 3.7.2 7.7 3.5 9.8 3.3 2 7.5 1.3 10-1.6 9.4-10.8 19-19.1 29.2-25.1 57.3-33.9 130.8-13.7 163.9 45 33.1 58.7 13.4 134-43.9 167.9-10.2 6.1-22 10.4-35.8 13.4-3.7.8-6.4 4.2-6.4 8.1.1 4 2.7 7.3 6.5 8 39.7 7.8 80.6.8 115.2-19.7 18-10.6 32.9-24.5 45.3-40.1 12.4 15.6 27.3 29.5 45.3 40.1 34.6 20.5 75.5 27.5 115.2 19.7 3.8-.7 6.4-4 6.5-8 0-3.9-2.6-7.3-6.4-8.1-13.9-2.9-25.6-7.3-35.8-13.4-57.3-33.9-77-109.2-43.9-167.9s106.6-78.9 163.9-45c10.2 6.1 19.8 14.3 29.2 25.1 2.5 2.9 6.7 3.6 10 1.6s4.8-6.1 3.5-9.8c-13.1-39.1-39.5-72-74.1-92.4zm-213.4 129c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z\"]\n};\nvar faBirthdayCake = {\n prefix: 'fas',\n iconName: 'birthday-cake',\n icon: [448, 512, [], \"f1fd\", \"M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z\"]\n};\nvar faBlender = {\n prefix: 'fas',\n iconName: 'blender',\n icon: [512, 512, [], \"f517\", \"M416 384H160c-35.35 0-64 28.65-64 64v32c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-32c0-35.35-28.65-64-64-64zm-128 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm40-416h166.54L512 0H48C21.49 0 0 21.49 0 48v160c0 26.51 21.49 48 48 48h103.27l8.73 96h256l17.46-64H328c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h114.18l17.46-64H328c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h140.36l17.46-64H328c-4.42 0-8-3.58-8-8V72c0-4.42 3.58-8 8-8zM64 192V64h69.82l11.64 128H64z\"]\n};\nvar faBlenderPhone = {\n prefix: 'fas',\n iconName: 'blender-phone',\n icon: [576, 512, [], \"f6b6\", \"M392 64h166.54L576 0H192v352h288l17.46-64H392c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h114.18l17.46-64H392c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h140.36l17.46-64H392c-4.42 0-8-3.58-8-8V72c0-4.42 3.58-8 8-8zM158.8 335.01l-25.78-63.26c-2.78-6.81-9.8-10.99-17.24-10.26l-45.03 4.42c-17.28-46.94-17.65-99.78 0-147.72l45.03 4.42c7.43.73 14.46-3.46 17.24-10.26l25.78-63.26c3.02-7.39.2-15.85-6.68-20.07l-39.28-24.1C98.51-3.87 80.09-.5 68.95 11.97c-92.57 103.6-92 259.55 2.1 362.49 9.87 10.8 29.12 12.48 41.65 4.8l39.41-24.18c6.89-4.22 9.7-12.67 6.69-20.07zM480 384H192c-35.35 0-64 28.65-64 64v32c0 17.67 14.33 32 32 32h352c17.67 0 32-14.33 32-32v-32c0-35.35-28.65-64-64-64zm-144 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faBlind = {\n prefix: 'fas',\n iconName: 'blind',\n icon: [384, 512, [], \"f29d\", \"M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z\"]\n};\nvar faBlog = {\n prefix: 'fas',\n iconName: 'blog',\n icon: [512, 512, [], \"f781\", \"M172.2 226.8c-14.6-2.9-28.2 8.9-28.2 23.8V301c0 10.2 7.1 18.4 16.7 22 18.2 6.8 31.3 24.4 31.3 45 0 26.5-21.5 48-48 48s-48-21.5-48-48V120c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v248c0 89.5 82.1 160.2 175 140.7 54.4-11.4 98.3-55.4 109.7-109.7 17.4-82.9-37-157.2-112.5-172.2zM209 0c-9.2-.5-17 6.8-17 16v31.6c0 8.5 6.6 15.5 15 15.9 129.4 7 233.4 112 240.9 241.5.5 8.4 7.5 15 15.9 15h32.1c9.2 0 16.5-7.8 16-17C503.4 139.8 372.2 8.6 209 0zm.3 96c-9.3-.7-17.3 6.7-17.3 16.1v32.1c0 8.4 6.5 15.3 14.8 15.9 76.8 6.3 138 68.2 144.9 145.2.8 8.3 7.6 14.7 15.9 14.7h32.2c9.3 0 16.8-8 16.1-17.3-8.4-110.1-96.5-198.2-206.6-206.7z\"]\n};\nvar faBold = {\n prefix: 'fas',\n iconName: 'bold',\n icon: [384, 512, [], \"f032\", \"M333.49 238a122 122 0 0 0 27-65.21C367.87 96.49 308 32 233.42 32H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h31.87v288H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h209.32c70.8 0 134.14-51.75 141-122.4 4.74-48.45-16.39-92.06-50.83-119.6zM145.66 112h87.76a48 48 0 0 1 0 96h-87.76zm87.76 288h-87.76V288h87.76a56 56 0 0 1 0 112z\"]\n};\nvar faBolt = {\n prefix: 'fas',\n iconName: 'bolt',\n icon: [320, 512, [], \"f0e7\", \"M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z\"]\n};\nvar faBomb = {\n prefix: 'fas',\n iconName: 'bomb',\n icon: [512, 512, [], \"f1e2\", \"M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z\"]\n};\nvar faBone = {\n prefix: 'fas',\n iconName: 'bone',\n icon: [640, 512, [], \"f5d7\", \"M598.88 244.56c25.2-12.6 41.12-38.36 41.12-66.53v-7.64C640 129.3 606.7 96 565.61 96c-32.02 0-60.44 20.49-70.57 50.86-7.68 23.03-11.6 45.14-38.11 45.14H183.06c-27.38 0-31.58-25.54-38.11-45.14C134.83 116.49 106.4 96 74.39 96 33.3 96 0 129.3 0 170.39v7.64c0 28.17 15.92 53.93 41.12 66.53 9.43 4.71 9.43 18.17 0 22.88C15.92 280.04 0 305.8 0 333.97v7.64C0 382.7 33.3 416 74.38 416c32.02 0 60.44-20.49 70.57-50.86 7.68-23.03 11.6-45.14 38.11-45.14h273.87c27.38 0 31.58 25.54 38.11 45.14C505.17 395.51 533.6 416 565.61 416c41.08 0 74.38-33.3 74.38-74.39v-7.64c0-28.18-15.92-53.93-41.12-66.53-9.42-4.71-9.42-18.17.01-22.88z\"]\n};\nvar faBong = {\n prefix: 'fas',\n iconName: 'bong',\n icon: [448, 512, [], \"f55c\", \"M302.5 512c23.18 0 44.43-12.58 56-32.66C374.69 451.26 384 418.75 384 384c0-36.12-10.08-69.81-27.44-98.62L400 241.94l9.38 9.38c6.25 6.25 16.38 6.25 22.63 0l11.3-11.32c6.25-6.25 6.25-16.38 0-22.63l-52.69-52.69c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63l9.38 9.38-39.41 39.41c-11.56-11.37-24.53-21.33-38.65-29.51V63.74l15.97-.02c8.82-.01 15.97-7.16 15.98-15.98l.04-31.72C320 7.17 312.82-.01 303.97 0L80.03.26c-8.82.01-15.97 7.16-15.98 15.98l-.04 31.73c-.01 8.85 7.17 16.02 16.02 16.01L96 63.96v153.93C38.67 251.1 0 312.97 0 384c0 34.75 9.31 67.27 25.5 95.34C37.08 499.42 58.33 512 81.5 512h221zM120.06 259.43L144 245.56V63.91l96-.11v181.76l23.94 13.87c24.81 14.37 44.12 35.73 56.56 60.57h-257c12.45-24.84 31.75-46.2 56.56-60.57z\"]\n};\nvar faBook = {\n prefix: 'fas',\n iconName: 'book',\n icon: [448, 512, [], \"f02d\", \"M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z\"]\n};\nvar faBookDead = {\n prefix: 'fas',\n iconName: 'book-dead',\n icon: [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"]\n};\nvar faBookMedical = {\n prefix: 'fas',\n iconName: 'book-medical',\n icon: [448, 512, [], \"f7e6\", \"M448 358.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16q0-9.6-9.6-19.2c-3.2-16-3.2-60.8 0-73.6q9.6-4.8 9.6-19.2zM144 168a8 8 0 0 1 8-8h56v-56a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8v56h56a8 8 0 0 1 8 8v48a8 8 0 0 1-8 8h-56v56a8 8 0 0 1-8 8h-48a8 8 0 0 1-8-8v-56h-56a8 8 0 0 1-8-8zm236.8 280H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8z\"]\n};\nvar faBookOpen = {\n prefix: 'fas',\n iconName: 'book-open',\n icon: [576, 512, [], \"f518\", \"M542.22 32.05c-54.8 3.11-163.72 14.43-230.96 55.59-4.64 2.84-7.27 7.89-7.27 13.17v363.87c0 11.55 12.63 18.85 23.28 13.49 69.18-34.82 169.23-44.32 218.7-46.92 16.89-.89 30.02-14.43 30.02-30.66V62.75c.01-17.71-15.35-31.74-33.77-30.7zM264.73 87.64C197.5 46.48 88.58 35.17 33.78 32.05 15.36 31.01 0 45.04 0 62.75V400.6c0 16.24 13.13 29.78 30.02 30.66 49.49 2.6 149.59 12.11 218.77 46.95 10.62 5.35 23.21-1.94 23.21-13.46V100.63c0-5.29-2.62-10.14-7.27-12.99z\"]\n};\nvar faBookReader = {\n prefix: 'fas',\n iconName: 'book-reader',\n icon: [512, 512, [], \"f5da\", \"M352 96c0-53.02-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM233.59 241.1c-59.33-36.32-155.43-46.3-203.79-49.05C13.55 191.13 0 203.51 0 219.14v222.8c0 14.33 11.59 26.28 26.49 27.05 43.66 2.29 131.99 10.68 193.04 41.43 9.37 4.72 20.48-1.71 20.48-11.87V252.56c-.01-4.67-2.32-8.95-6.42-11.46zm248.61-49.05c-48.35 2.74-144.46 12.73-203.78 49.05-4.1 2.51-6.41 6.96-6.41 11.63v245.79c0 10.19 11.14 16.63 20.54 11.9 61.04-30.72 149.32-39.11 192.97-41.4 14.9-.78 26.49-12.73 26.49-27.06V219.14c-.01-15.63-13.56-28.01-29.81-27.09z\"]\n};\nvar faBookmark = {\n prefix: 'fas',\n iconName: 'bookmark',\n icon: [384, 512, [], \"f02e\", \"M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z\"]\n};\nvar faBorderAll = {\n prefix: 'fas',\n iconName: 'border-all',\n icon: [448, 512, [], \"f84c\", \"M416 32H32A32 32 0 0 0 0 64v384a32 32 0 0 0 32 32h384a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-32 64v128H256V96zm-192 0v128H64V96zM64 416V288h128v128zm192 0V288h128v128z\"]\n};\nvar faBorderNone = {\n prefix: 'fas',\n iconName: 'border-none',\n icon: [448, 512, [], \"f850\", \"M240 224h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-288 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96 192h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-96h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-192h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM240 320h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-192h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-96 288h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96-384h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM48 224H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 192H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-96H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-192H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-96H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faBorderStyle = {\n prefix: 'fas',\n iconName: 'border-style',\n icon: [448, 512, [], \"f853\", \"M240 416h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm96-192h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 96h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 96h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-288h-32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-96H32A32 32 0 0 0 0 64v400a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V96h368a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faBowlingBall = {\n prefix: 'fas',\n iconName: 'bowling-ball',\n icon: [496, 512, [], \"f436\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM120 192c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm64-96c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm48 144c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faBox = {\n prefix: 'fas',\n iconName: 'box',\n icon: [512, 512, [], \"f466\", \"M509.5 184.6L458.9 32.8C452.4 13.2 434.1 0 413.4 0H272v192h238.7c-.4-2.5-.4-5-1.2-7.4zM240 0H98.6c-20.7 0-39 13.2-45.5 32.8L2.5 184.6c-.8 2.4-.8 4.9-1.2 7.4H240V0zM0 224v240c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V224H0z\"]\n};\nvar faBoxOpen = {\n prefix: 'fas',\n iconName: 'box-open',\n icon: [640, 512, [], \"f49e\", \"M425.7 256c-16.9 0-32.8-9-41.4-23.4L320 126l-64.2 106.6c-8.7 14.5-24.6 23.5-41.5 23.5-4.5 0-9-.6-13.3-1.9L64 215v178c0 14.7 10 27.5 24.2 31l216.2 54.1c10.2 2.5 20.9 2.5 31 0L551.8 424c14.2-3.6 24.2-16.4 24.2-31V215l-137 39.1c-4.3 1.3-8.8 1.9-13.3 1.9zm212.6-112.2L586.8 41c-3.1-6.2-9.8-9.8-16.7-8.9L320 64l91.7 152.1c3.8 6.3 11.4 9.3 18.5 7.3l197.9-56.5c9.9-2.9 14.7-13.9 10.2-23.1zM53.2 41L1.7 143.8c-4.6 9.2.3 20.2 10.1 23l197.9 56.5c7.1 2 14.7-1 18.5-7.3L320 64 69.8 32.1c-6.9-.8-13.5 2.7-16.6 8.9z\"]\n};\nvar faBoxes = {\n prefix: 'fas',\n iconName: 'boxes',\n icon: [576, 512, [], \"f468\", \"M560 288h-80v96l-32-21.3-32 21.3v-96h-80c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16h224c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16zm-384-64h224c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16h-80v96l-32-21.3L256 96V0h-80c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16zm64 64h-80v96l-32-21.3L96 384v-96H16c-8.8 0-16 7.2-16 16v192c0 8.8 7.2 16 16 16h224c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16z\"]\n};\nvar faBraille = {\n prefix: 'fas',\n iconName: 'braille',\n icon: [640, 512, [], \"f2a1\", \"M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z\"]\n};\nvar faBrain = {\n prefix: 'fas',\n iconName: 'brain',\n icon: [576, 512, [], \"f5dc\", \"M208 0c-29.9 0-54.7 20.5-61.8 48.2-.8 0-1.4-.2-2.2-.2-35.3 0-64 28.7-64 64 0 4.8.6 9.5 1.7 14C52.5 138 32 166.6 32 200c0 12.6 3.2 24.3 8.3 34.9C16.3 248.7 0 274.3 0 304c0 33.3 20.4 61.9 49.4 73.9-.9 4.6-1.4 9.3-1.4 14.1 0 39.8 32.2 72 72 72 4.1 0 8.1-.5 12-1.2 9.6 28.5 36.2 49.2 68 49.2 39.8 0 72-32.2 72-72V64c0-35.3-28.7-64-64-64zm368 304c0-29.7-16.3-55.3-40.3-69.1 5.2-10.6 8.3-22.3 8.3-34.9 0-33.4-20.5-62-49.7-74 1-4.5 1.7-9.2 1.7-14 0-35.3-28.7-64-64-64-.8 0-1.5.2-2.2.2C422.7 20.5 397.9 0 368 0c-35.3 0-64 28.6-64 64v376c0 39.8 32.2 72 72 72 31.8 0 58.4-20.7 68-49.2 3.9.7 7.9 1.2 12 1.2 39.8 0 72-32.2 72-72 0-4.8-.5-9.5-1.4-14.1 29-12 49.4-40.6 49.4-73.9z\"]\n};\nvar faBreadSlice = {\n prefix: 'fas',\n iconName: 'bread-slice',\n icon: [576, 512, [], \"f7ec\", \"M288 0C108 0 0 93.4 0 169.14 0 199.44 24.24 224 64 224v256c0 17.67 16.12 32 36 32h376c19.88 0 36-14.33 36-32V224c39.76 0 64-24.56 64-54.86C576 93.4 468 0 288 0z\"]\n};\nvar faBriefcase = {\n prefix: 'fas',\n iconName: 'briefcase',\n icon: [512, 512, [], \"f0b1\", \"M320 336c0 8.84-7.16 16-16 16h-96c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h416c25.6 0 48-22.4 48-48V288H320v48zm144-208h-80V80c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h512v-80c0-25.6-22.4-48-48-48zm-144 0H192V96h128v32z\"]\n};\nvar faBriefcaseMedical = {\n prefix: 'fas',\n iconName: 'briefcase-medical',\n icon: [512, 512, [], \"f469\", \"M464 128h-80V80c0-26.5-21.5-48-48-48H176c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48zM192 96h128v32H192V96zm160 248c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48z\"]\n};\nvar faBroadcastTower = {\n prefix: 'fas',\n iconName: 'broadcast-tower',\n icon: [640, 512, [], \"f519\", \"M150.94 192h33.73c11.01 0 18.61-10.83 14.86-21.18-4.93-13.58-7.55-27.98-7.55-42.82s2.62-29.24 7.55-42.82C203.29 74.83 195.68 64 184.67 64h-33.73c-7.01 0-13.46 4.49-15.41 11.23C130.64 92.21 128 109.88 128 128c0 18.12 2.64 35.79 7.54 52.76 1.94 6.74 8.39 11.24 15.4 11.24zM89.92 23.34C95.56 12.72 87.97 0 75.96 0H40.63c-6.27 0-12.14 3.59-14.74 9.31C9.4 45.54 0 85.65 0 128c0 24.75 3.12 68.33 26.69 118.86 2.62 5.63 8.42 9.14 14.61 9.14h34.84c12.02 0 19.61-12.74 13.95-23.37-49.78-93.32-16.71-178.15-.17-209.29zM614.06 9.29C611.46 3.58 605.6 0 599.33 0h-35.42c-11.98 0-19.66 12.66-14.02 23.25 18.27 34.29 48.42 119.42.28 209.23-5.72 10.68 1.8 23.52 13.91 23.52h35.23c6.27 0 12.13-3.58 14.73-9.29C630.57 210.48 640 170.36 640 128s-9.42-82.48-25.94-118.71zM489.06 64h-33.73c-11.01 0-18.61 10.83-14.86 21.18 4.93 13.58 7.55 27.98 7.55 42.82s-2.62 29.24-7.55 42.82c-3.76 10.35 3.85 21.18 14.86 21.18h33.73c7.02 0 13.46-4.49 15.41-11.24 4.9-16.97 7.53-34.64 7.53-52.76 0-18.12-2.64-35.79-7.54-52.76-1.94-6.75-8.39-11.24-15.4-11.24zm-116.3 100.12c7.05-10.29 11.2-22.71 11.2-36.12 0-35.35-28.63-64-63.96-64-35.32 0-63.96 28.65-63.96 64 0 13.41 4.15 25.83 11.2 36.12l-130.5 313.41c-3.4 8.15.46 17.52 8.61 20.92l29.51 12.31c8.15 3.4 17.52-.46 20.91-8.61L244.96 384h150.07l49.2 118.15c3.4 8.16 12.76 12.01 20.91 8.61l29.51-12.31c8.15-3.4 12-12.77 8.61-20.92l-130.5-313.41zM271.62 320L320 203.81 368.38 320h-96.76z\"]\n};\nvar faBroom = {\n prefix: 'fas',\n iconName: 'broom',\n icon: [640, 512, [], \"f51a\", \"M256.47 216.77l86.73 109.18s-16.6 102.36-76.57 150.12C206.66 523.85 0 510.19 0 510.19s3.8-23.14 11-55.43l94.62-112.17c3.97-4.7-.87-11.62-6.65-9.5l-60.4 22.09c14.44-41.66 32.72-80.04 54.6-97.47 59.97-47.76 163.3-40.94 163.3-40.94zM636.53 31.03l-19.86-25c-5.49-6.9-15.52-8.05-22.41-2.56l-232.48 177.8-34.14-42.97c-5.09-6.41-15.14-5.21-18.59 2.21l-25.33 54.55 86.73 109.18 58.8-12.45c8-1.69 11.42-11.2 6.34-17.6l-34.09-42.92 232.48-177.8c6.89-5.48 8.04-15.53 2.55-22.44z\"]\n};\nvar faBrush = {\n prefix: 'fas',\n iconName: 'brush',\n icon: [384, 512, [], \"f55d\", \"M352 0H32C14.33 0 0 14.33 0 32v224h384V32c0-17.67-14.33-32-32-32zM0 320c0 35.35 28.66 64 64 64h64v64c0 35.35 28.66 64 64 64s64-28.65 64-64v-64h64c35.34 0 64-28.65 64-64v-32H0v32zm192 104c13.25 0 24 10.74 24 24 0 13.25-10.75 24-24 24s-24-10.75-24-24c0-13.26 10.75-24 24-24z\"]\n};\nvar faBug = {\n prefix: 'fas',\n iconName: 'bug',\n icon: [512, 512, [], \"f188\", \"M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z\"]\n};\nvar faBuilding = {\n prefix: 'fas',\n iconName: 'building',\n icon: [448, 512, [], \"f1ad\", \"M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z\"]\n};\nvar faBullhorn = {\n prefix: 'fas',\n iconName: 'bullhorn',\n icon: [576, 512, [], \"f0a1\", \"M576 240c0-23.63-12.95-44.04-32-55.12V32.01C544 23.26 537.02 0 512 0c-7.12 0-14.19 2.38-19.98 7.02l-85.03 68.03C364.28 109.19 310.66 128 256 128H64c-35.35 0-64 28.65-64 64v96c0 35.35 28.65 64 64 64h33.7c-1.39 10.48-2.18 21.14-2.18 32 0 39.77 9.26 77.35 25.56 110.94 5.19 10.69 16.52 17.06 28.4 17.06h74.28c26.05 0 41.69-29.84 25.9-50.56-16.4-21.52-26.15-48.36-26.15-77.44 0-11.11 1.62-21.79 4.41-32H256c54.66 0 108.28 18.81 150.98 52.95l85.03 68.03a32.023 32.023 0 0 0 19.98 7.02c24.92 0 32-22.78 32-32V295.13C563.05 284.04 576 263.63 576 240zm-96 141.42l-33.05-26.44C392.95 311.78 325.12 288 256 288v-96c69.12 0 136.95-23.78 190.95-66.98L480 98.58v282.84z\"]\n};\nvar faBullseye = {\n prefix: 'fas',\n iconName: 'bullseye',\n icon: [496, 512, [], \"f140\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 432c-101.69 0-184-82.29-184-184 0-101.69 82.29-184 184-184 101.69 0 184 82.29 184 184 0 101.69-82.29 184-184 184zm0-312c-70.69 0-128 57.31-128 128s57.31 128 128 128 128-57.31 128-128-57.31-128-128-128zm0 192c-35.29 0-64-28.71-64-64s28.71-64 64-64 64 28.71 64 64-28.71 64-64 64z\"]\n};\nvar faBurn = {\n prefix: 'fas',\n iconName: 'burn',\n icon: [384, 512, [], \"f46a\", \"M192 0C79.7 101.3 0 220.9 0 300.5 0 425 79 512 192 512s192-87 192-211.5c0-79.9-80.2-199.6-192-300.5zm0 448c-56.5 0-96-39-96-94.8 0-13.5 4.6-61.5 96-161.2 91.4 99.7 96 147.7 96 161.2 0 55.8-39.5 94.8-96 94.8z\"]\n};\nvar faBus = {\n prefix: 'fas',\n iconName: 'bus',\n icon: [512, 512, [], \"f207\", \"M488 128h-8V80c0-44.8-99.2-80-224-80S32 35.2 32 80v48h-8c-13.25 0-24 10.74-24 24v80c0 13.25 10.75 24 24 24h8v160c0 17.67 14.33 32 32 32v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h192v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h6.4c16 0 25.6-12.8 25.6-25.6V256h8c13.25 0 24-10.75 24-24v-80c0-13.26-10.75-24-24-24zM112 400c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm16-112c-17.67 0-32-14.33-32-32V128c0-17.67 14.33-32 32-32h256c17.67 0 32 14.33 32 32v128c0 17.67-14.33 32-32 32H128zm272 112c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faBusAlt = {\n prefix: 'fas',\n iconName: 'bus-alt',\n icon: [512, 512, [], \"f55e\", \"M488 128h-8V80c0-44.8-99.2-80-224-80S32 35.2 32 80v48h-8c-13.25 0-24 10.74-24 24v80c0 13.25 10.75 24 24 24h8v160c0 17.67 14.33 32 32 32v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h192v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h6.4c16 0 25.6-12.8 25.6-25.6V256h8c13.25 0 24-10.75 24-24v-80c0-13.26-10.75-24-24-24zM160 72c0-4.42 3.58-8 8-8h176c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H168c-4.42 0-8-3.58-8-8V72zm-48 328c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm128-112H128c-17.67 0-32-14.33-32-32v-96c0-17.67 14.33-32 32-32h112v160zm32 0V128h112c17.67 0 32 14.33 32 32v96c0 17.67-14.33 32-32 32H272zm128 112c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faBusinessTime = {\n prefix: 'fas',\n iconName: 'business-time',\n icon: [640, 512, [], \"f64a\", \"M496 224c-79.59 0-144 64.41-144 144s64.41 144 144 144 144-64.41 144-144-64.41-144-144-144zm64 150.29c0 5.34-4.37 9.71-9.71 9.71h-60.57c-5.34 0-9.71-4.37-9.71-9.71v-76.57c0-5.34 4.37-9.71 9.71-9.71h12.57c5.34 0 9.71 4.37 9.71 9.71V352h38.29c5.34 0 9.71 4.37 9.71 9.71v12.58zM496 192c5.4 0 10.72.33 16 .81V144c0-25.6-22.4-48-48-48h-80V48c0-25.6-22.4-48-48-48H176c-25.6 0-48 22.4-48 48v48H48c-25.6 0-48 22.4-48 48v80h395.12c28.6-20.09 63.35-32 100.88-32zM320 96H192V64h128v32zm6.82 224H208c-8.84 0-16-7.16-16-16v-48H0v144c0 25.6 22.4 48 48 48h291.43C327.1 423.96 320 396.82 320 368c0-16.66 2.48-32.72 6.82-48z\"]\n};\nvar faCalculator = {\n prefix: 'fas',\n iconName: 'calculator',\n icon: [448, 512, [], \"f1ec\", \"M400 0H48C22.4 0 0 22.4 0 48v416c0 25.6 22.4 48 48 48h352c25.6 0 48-22.4 48-48V48c0-25.6-22.4-48-48-48zM128 435.2c0 6.4-6.4 12.8-12.8 12.8H76.8c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4zm0-128c0 6.4-6.4 12.8-12.8 12.8H76.8c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4zm128 128c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4zm0-128c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4zm128 128c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8V268.8c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v166.4zm0-256c0 6.4-6.4 12.8-12.8 12.8H76.8c-6.4 0-12.8-6.4-12.8-12.8V76.8C64 70.4 70.4 64 76.8 64h294.4c6.4 0 12.8 6.4 12.8 12.8v102.4z\"]\n};\nvar faCalendar = {\n prefix: 'fas',\n iconName: 'calendar',\n icon: [448, 512, [], \"f133\", \"M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z\"]\n};\nvar faCalendarAlt = {\n prefix: 'fas',\n iconName: 'calendar-alt',\n icon: [448, 512, [], \"f073\", \"M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z\"]\n};\nvar faCalendarCheck = {\n prefix: 'fas',\n iconName: 'calendar-check',\n icon: [448, 512, [], \"f274\", \"M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z\"]\n};\nvar faCalendarDay = {\n prefix: 'fas',\n iconName: 'calendar-day',\n icon: [448, 512, [], \"f783\", \"M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm64-192c0-8.8 7.2-16 16-16h96c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16v-96zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z\"]\n};\nvar faCalendarMinus = {\n prefix: 'fas',\n iconName: 'calendar-minus',\n icon: [448, 512, [], \"f272\", \"M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z\"]\n};\nvar faCalendarPlus = {\n prefix: 'fas',\n iconName: 'calendar-plus',\n icon: [448, 512, [], \"f271\", \"M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z\"]\n};\nvar faCalendarTimes = {\n prefix: 'fas',\n iconName: 'calendar-times',\n icon: [448, 512, [], \"f273\", \"M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z\"]\n};\nvar faCalendarWeek = {\n prefix: 'fas',\n iconName: 'calendar-week',\n icon: [448, 512, [], \"f784\", \"M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm64-192c0-8.8 7.2-16 16-16h288c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16v-64zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z\"]\n};\nvar faCamera = {\n prefix: 'fas',\n iconName: 'camera',\n icon: [512, 512, [], \"f030\", \"M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z\"]\n};\nvar faCameraRetro = {\n prefix: 'fas',\n iconName: 'camera-retro',\n icon: [512, 512, [], \"f083\", \"M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z\"]\n};\nvar faCampground = {\n prefix: 'fas',\n iconName: 'campground',\n icon: [640, 512, [], \"f6bb\", \"M624 448h-24.68L359.54 117.75l53.41-73.55c5.19-7.15 3.61-17.16-3.54-22.35l-25.9-18.79c-7.15-5.19-17.15-3.61-22.35 3.55L320 63.3 278.83 6.6c-5.19-7.15-15.2-8.74-22.35-3.55l-25.88 18.8c-7.15 5.19-8.74 15.2-3.54 22.35l53.41 73.55L40.68 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h608c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM320 288l116.36 160H203.64L320 288z\"]\n};\nvar faCandyCane = {\n prefix: 'fas',\n iconName: 'candy-cane',\n icon: [512, 512, [], \"f786\", \"M497.5 92C469.6 33.1 411.8 0 352.4 0c-27.9 0-56.2 7.3-81.8 22.6L243.1 39c-15.2 9.1-20.1 28.7-11 43.9l32.8 54.9c6 10 16.6 15.6 27.5 15.6 5.6 0 11.2-1.5 16.4-4.5l27.5-16.4c5.1-3.1 10.8-4.5 16.4-4.5 10.9 0 21.5 5.6 27.5 15.6 9.1 15.1 4.1 34.8-11 43.9L15.6 397.6c-15.2 9.1-20.1 28.7-11 43.9l32.8 54.9c6 10 16.6 15.6 27.5 15.6 5.6 0 11.2-1.5 16.4-4.5L428.6 301c71.7-42.9 104.6-133.5 68.9-209zm-177.7 13l-2.5 1.5L296.8 45c9.7-4.7 19.8-8.1 30.3-10.2l20.6 61.8c-9.8.8-19.4 3.3-27.9 8.4zM145.9 431.8l-60.5-38.5 30.8-18.3 60.5 38.5-30.8 18.3zm107.5-63.9l-60.5-38.5 30.8-18.3 60.5 38.5-30.8 18.3zM364.3 302l-60.5-38.5 30.8-18.3 60.5 38.5-30.8 18.3zm20.4-197.3l46-46c8.4 6.5 16 14.1 22.6 22.6L407.6 127c-5.7-9.3-13.7-16.9-22.9-22.3zm82.1 107.8l-59.5-19.8c3.2-5.3 5.8-10.9 7.4-17.1 1.1-4.5 1.7-9.1 1.8-13.6l60.4 20.1c-2.1 10.4-5.5 20.6-10.1 30.4z\"]\n};\nvar faCannabis = {\n prefix: 'fas',\n iconName: 'cannabis',\n icon: [512, 512, [], \"f55f\", \"M503.47 360.25c-1.56-.82-32.39-16.89-76.78-25.81 64.25-75.12 84.05-161.67 84.93-165.64 1.18-5.33-.44-10.9-4.3-14.77-3.03-3.04-7.12-4.7-11.32-4.7-1.14 0-2.29.12-3.44.38-3.88.85-86.54 19.59-160.58 79.76.01-1.46.01-2.93.01-4.4 0-118.79-59.98-213.72-62.53-217.7A15.973 15.973 0 0 0 256 0c-5.45 0-10.53 2.78-13.47 7.37-2.55 3.98-62.53 98.91-62.53 217.7 0 1.47.01 2.94.01 4.4-74.03-60.16-156.69-78.9-160.58-79.76-1.14-.25-2.29-.38-3.44-.38-4.2 0-8.29 1.66-11.32 4.7A15.986 15.986 0 0 0 .38 168.8c.88 3.97 20.68 90.52 84.93 165.64-44.39 8.92-75.21 24.99-76.78 25.81a16.003 16.003 0 0 0-.02 28.29c2.45 1.29 60.76 31.72 133.49 31.72 6.14 0 11.96-.1 17.5-.31-11.37 22.23-16.52 38.31-16.81 39.22-1.8 5.68-.29 11.89 3.91 16.11a16.019 16.019 0 0 0 16.1 3.99c1.83-.57 37.72-11.99 77.3-39.29V504c0 4.42 3.58 8 8 8h16c4.42 0 8-3.58 8-8v-64.01c39.58 27.3 75.47 38.71 77.3 39.29a16.019 16.019 0 0 0 16.1-3.99c4.2-4.22 5.71-10.43 3.91-16.11-.29-.91-5.45-16.99-16.81-39.22 5.54.21 11.37.31 17.5.31 72.72 0 131.04-30.43 133.49-31.72 5.24-2.78 8.52-8.22 8.51-14.15-.01-5.94-3.29-11.39-8.53-14.15z\"]\n};\nvar faCapsules = {\n prefix: 'fas',\n iconName: 'capsules',\n icon: [576, 512, [], \"f46b\", \"M555.3 300.1L424.2 112.8C401.9 81 366.4 64 330.4 64c-22.6 0-45.5 6.7-65.5 20.7-19.7 13.8-33.7 32.8-41.5 53.8C220.5 79.2 172 32 112 32 50.1 32 0 82.1 0 144v224c0 61.9 50.1 112 112 112s112-50.1 112-112V218.9c3.3 8.6 7.3 17.1 12.8 25L368 431.2c22.2 31.8 57.7 48.8 93.8 48.8 22.7 0 45.5-6.7 65.5-20.7 51.7-36.2 64.2-107.5 28-159.2zM160 256H64V144c0-26.5 21.5-48 48-48s48 21.5 48 48v112zm194.8 44.9l-65.6-93.7c-7.7-11-10.7-24.4-8.3-37.6 2.3-13.2 9.7-24.8 20.7-32.5 8.5-6 18.5-9.1 28.8-9.1 16.5 0 31.9 8 41.3 21.5l65.6 93.7-82.5 57.7z\"]\n};\nvar faCar = {\n prefix: 'fas',\n iconName: 'car',\n icon: [512, 512, [], \"f1b9\", \"M499.99 176h-59.87l-16.64-41.6C406.38 91.63 365.57 64 319.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4L71.87 176H12.01C4.2 176-1.53 183.34.37 190.91l6 24C7.7 220.25 12.5 224 18.01 224h20.07C24.65 235.73 16 252.78 16 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-19.22-8.65-36.27-22.07-48H494c5.51 0 10.31-3.75 11.64-9.09l6-24c1.89-7.57-3.84-14.91-11.65-14.91zm-352.06-17.83c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L384 208H128l19.93-49.83zM96 319.8c-19.2 0-32-12.76-32-31.9S76.8 256 96 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S396.8 256 416 256s32 12.76 32 31.9-12.8 31.9-32 31.9z\"]\n};\nvar faCarAlt = {\n prefix: 'fas',\n iconName: 'car-alt',\n icon: [480, 512, [], \"f5de\", \"M438.66 212.33l-11.24-28.1-19.93-49.83C390.38 91.63 349.57 64 303.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4l-19.93 49.83-11.24 28.1C17.22 221.5 0 244.66 0 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-27.34-17.22-50.5-41.34-59.67zm-306.73-54.16c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L368 208H112l19.93-49.83zM80 319.8c-19.2 0-32-12.76-32-31.9S60.8 256 80 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S380.8 256 400 256s32 12.76 32 31.9-12.8 31.9-32 31.9z\"]\n};\nvar faCarBattery = {\n prefix: 'fas',\n iconName: 'car-battery',\n icon: [512, 512, [], \"f5df\", \"M480 128h-32V80c0-8.84-7.16-16-16-16h-96c-8.84 0-16 7.16-16 16v48H192V80c0-8.84-7.16-16-16-16H80c-8.84 0-16 7.16-16 16v48H32c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32V160c0-17.67-14.33-32-32-32zM192 264c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h112c4.42 0 8 3.58 8 8v16zm256 0c0 4.42-3.58 8-8 8h-40v40c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-40h-40c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h40v-40c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v40h40c4.42 0 8 3.58 8 8v16z\"]\n};\nvar faCarCrash = {\n prefix: 'fas',\n iconName: 'car-crash',\n icon: [640, 512, [], \"f5e1\", \"M143.25 220.81l-12.42 46.37c-3.01 11.25-3.63 22.89-2.41 34.39l-35.2 28.98c-6.57 5.41-16.31-.43-14.62-8.77l15.44-76.68c1.06-5.26-2.66-10.28-8-10.79l-77.86-7.55c-8.47-.82-11.23-11.83-4.14-16.54l65.15-43.3c4.46-2.97 5.38-9.15 1.98-13.29L21.46 93.22c-5.41-6.57.43-16.3 8.78-14.62l76.68 15.44c5.26 1.06 10.28-2.66 10.8-8l7.55-77.86c.82-8.48 11.83-11.23 16.55-4.14l43.3 65.14c2.97 4.46 9.15 5.38 13.29 1.98l60.4-49.71c6.57-5.41 16.3.43 14.62 8.77L262.1 86.38c-2.71 3.05-5.43 6.09-7.91 9.4l-32.15 42.97-10.71 14.32c-32.73 8.76-59.18 34.53-68.08 67.74zm494.57 132.51l-12.42 46.36c-3.13 11.68-9.38 21.61-17.55 29.36a66.876 66.876 0 0 1-8.76 7l-13.99 52.23c-1.14 4.27-3.1 8.1-5.65 11.38-7.67 9.84-20.74 14.68-33.54 11.25L515 502.62c-17.07-4.57-27.2-22.12-22.63-39.19l8.28-30.91-247.28-66.26-8.28 30.91c-4.57 17.07-22.12 27.2-39.19 22.63l-30.91-8.28c-12.8-3.43-21.7-14.16-23.42-26.51-.57-4.12-.35-8.42.79-12.68l13.99-52.23a66.62 66.62 0 0 1-4.09-10.45c-3.2-10.79-3.65-22.52-.52-34.2l12.42-46.37c5.31-19.8 19.36-34.83 36.89-42.21a64.336 64.336 0 0 1 18.49-4.72l18.13-24.23 32.15-42.97c3.45-4.61 7.19-8.9 11.2-12.84 8-7.89 17.03-14.44 26.74-19.51 4.86-2.54 9.89-4.71 15.05-6.49 10.33-3.58 21.19-5.63 32.24-6.04 11.05-.41 22.31.82 33.43 3.8l122.68 32.87c11.12 2.98 21.48 7.54 30.85 13.43a111.11 111.11 0 0 1 34.69 34.5c8.82 13.88 14.64 29.84 16.68 46.99l6.36 53.29 3.59 30.05a64.49 64.49 0 0 1 22.74 29.93c4.39 11.88 5.29 25.19 1.75 38.39zM255.58 234.34c-18.55-4.97-34.21 4.04-39.17 22.53-4.96 18.49 4.11 34.12 22.65 39.09 18.55 4.97 45.54 15.51 50.49-2.98 4.96-18.49-15.43-53.67-33.97-58.64zm290.61 28.17l-6.36-53.29c-.58-4.87-1.89-9.53-3.82-13.86-5.8-12.99-17.2-23.01-31.42-26.82l-122.68-32.87a48.008 48.008 0 0 0-50.86 17.61l-32.15 42.97 172 46.08 75.29 20.18zm18.49 54.65c-18.55-4.97-53.8 15.31-58.75 33.79-4.95 18.49 23.69 22.86 42.24 27.83 18.55 4.97 34.21-4.04 39.17-22.53 4.95-18.48-4.11-34.12-22.66-39.09z\"]\n};\nvar faCarSide = {\n prefix: 'fas',\n iconName: 'car-side',\n icon: [640, 512, [], \"f5e4\", \"M544 192h-16L419.22 56.02A64.025 64.025 0 0 0 369.24 32H155.33c-26.17 0-49.7 15.93-59.42 40.23L48 194.26C20.44 201.4 0 226.21 0 256v112c0 8.84 7.16 16 16 16h48c0 53.02 42.98 96 96 96s96-42.98 96-96h128c0 53.02 42.98 96 96 96s96-42.98 96-96h48c8.84 0 16-7.16 16-16v-80c0-53.02-42.98-96-96-96zM160 432c-26.47 0-48-21.53-48-48s21.53-48 48-48 48 21.53 48 48-21.53 48-48 48zm72-240H116.93l38.4-96H232v96zm48 0V96h89.24l76.8 96H280zm200 240c-26.47 0-48-21.53-48-48s21.53-48 48-48 48 21.53 48 48-21.53 48-48 48z\"]\n};\nvar faCaretDown = {\n prefix: 'fas',\n iconName: 'caret-down',\n icon: [320, 512, [], \"f0d7\", \"M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z\"]\n};\nvar faCaretLeft = {\n prefix: 'fas',\n iconName: 'caret-left',\n icon: [192, 512, [], \"f0d9\", \"M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z\"]\n};\nvar faCaretRight = {\n prefix: 'fas',\n iconName: 'caret-right',\n icon: [192, 512, [], \"f0da\", \"M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z\"]\n};\nvar faCaretSquareDown = {\n prefix: 'fas',\n iconName: 'caret-square-down',\n icon: [448, 512, [], \"f150\", \"M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z\"]\n};\nvar faCaretSquareLeft = {\n prefix: 'fas',\n iconName: 'caret-square-left',\n icon: [448, 512, [], \"f191\", \"M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z\"]\n};\nvar faCaretSquareRight = {\n prefix: 'fas',\n iconName: 'caret-square-right',\n icon: [448, 512, [], \"f152\", \"M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z\"]\n};\nvar faCaretSquareUp = {\n prefix: 'fas',\n iconName: 'caret-square-up',\n icon: [448, 512, [], \"f151\", \"M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z\"]\n};\nvar faCaretUp = {\n prefix: 'fas',\n iconName: 'caret-up',\n icon: [320, 512, [], \"f0d8\", \"M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z\"]\n};\nvar faCarrot = {\n prefix: 'fas',\n iconName: 'carrot',\n icon: [512, 512, [], \"f787\", \"M298.2 156.6c-52.7-25.7-114.5-10.5-150.2 32.8l55.2 55.2c6.3 6.3 6.3 16.4 0 22.6-3.1 3.1-7.2 4.7-11.3 4.7s-8.2-1.6-11.3-4.7L130.4 217 2.3 479.7c-2.9 6-3.1 13.3 0 19.7 5.4 11.1 18.9 15.7 30 10.3l133.6-65.2-49.2-49.2c-6.3-6.2-6.3-16.4 0-22.6 6.3-6.2 16.4-6.2 22.6 0l57 57 102-49.8c24-11.7 44.5-31.3 57.1-57.1 30.1-61.7 4.5-136.1-57.2-166.2zm92.1-34.9C409.8 81 399.7 32.9 360 0c-50.3 41.7-52.5 107.5-7.9 151.9l8 8c44.4 44.6 110.3 42.4 151.9-7.9-32.9-39.7-81-49.8-121.7-30.3z\"]\n};\nvar faCartArrowDown = {\n prefix: 'fas',\n iconName: 'cart-arrow-down',\n icon: [576, 512, [], \"f218\", \"M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z\"]\n};\nvar faCartPlus = {\n prefix: 'fas',\n iconName: 'cart-plus',\n icon: [576, 512, [], \"f217\", \"M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z\"]\n};\nvar faCashRegister = {\n prefix: 'fas',\n iconName: 'cash-register',\n icon: [512, 512, [], \"f788\", \"M511.1 378.8l-26.7-160c-2.6-15.4-15.9-26.7-31.6-26.7H208v-64h96c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16H48c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h96v64H59.1c-15.6 0-29 11.3-31.6 26.7L.8 378.7c-.6 3.5-.9 7-.9 10.5V480c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32v-90.7c.1-3.5-.2-7-.8-10.5zM280 248c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16v-16zm-32 64h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16v-16c0-8.8 7.2-16 16-16zm-32-80c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16v-16c0-8.8 7.2-16 16-16h16zM80 80V48h192v32H80zm40 200h-16c-8.8 0-16-7.2-16-16v-16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16zm16 64v-16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16zm216 112c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v16zm24-112c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16v-16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16zm48-80c0 8.8-7.2 16-16 16h-16c-8.8 0-16-7.2-16-16v-16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16z\"]\n};\nvar faCat = {\n prefix: 'fas',\n iconName: 'cat',\n icon: [512, 512, [], \"f6be\", \"M290.59 192c-20.18 0-106.82 1.98-162.59 85.95V192c0-52.94-43.06-96-96-96-17.67 0-32 14.33-32 32s14.33 32 32 32c17.64 0 32 14.36 32 32v256c0 35.3 28.7 64 64 64h176c8.84 0 16-7.16 16-16v-16c0-17.67-14.33-32-32-32h-32l128-96v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V289.86c-10.29 2.67-20.89 4.54-32 4.54-61.81 0-113.52-44.05-125.41-102.4zM448 96h-64l-64-64v134.4c0 53.02 42.98 96 96 96s96-42.98 96-96V32l-64 64zm-72 80c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zm80 0c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16z\"]\n};\nvar faCertificate = {\n prefix: 'fas',\n iconName: 'certificate',\n icon: [512, 512, [], \"f0a3\", \"M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z\"]\n};\nvar faChair = {\n prefix: 'fas',\n iconName: 'chair',\n icon: [448, 512, [], \"f6c0\", \"M112 128c0-29.5 16.2-55 40-68.9V256h48V48h48v208h48V59.1c23.8 13.9 40 39.4 40 68.9v128h48V128C384 57.3 326.7 0 256 0h-64C121.3 0 64 57.3 64 128v128h48zm334.3 213.9l-10.7-32c-4.4-13.1-16.6-21.9-30.4-21.9H42.7c-13.8 0-26 8.8-30.4 21.9l-10.7 32C-5.2 362.6 10.2 384 32 384v112c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V384h256v112c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V384c21.8 0 37.2-21.4 30.3-42.1z\"]\n};\nvar faChalkboard = {\n prefix: 'fas',\n iconName: 'chalkboard',\n icon: [640, 512, [], \"f51b\", \"M96 64h448v352h64V40c0-22.06-17.94-40-40-40H72C49.94 0 32 17.94 32 40v376h64V64zm528 384H480v-64H288v64H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h608c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faChalkboardTeacher = {\n prefix: 'fas',\n iconName: 'chalkboard-teacher',\n icon: [640, 512, [], \"f51c\", \"M208 352c-2.39 0-4.78.35-7.06 1.09C187.98 357.3 174.35 360 160 360c-14.35 0-27.98-2.7-40.95-6.91-2.28-.74-4.66-1.09-7.05-1.09C49.94 352-.33 402.48 0 464.62.14 490.88 21.73 512 48 512h224c26.27 0 47.86-21.12 48-47.38.33-62.14-49.94-112.62-112-112.62zm-48-32c53.02 0 96-42.98 96-96s-42.98-96-96-96-96 42.98-96 96 42.98 96 96 96zM592 0H208c-26.47 0-48 22.25-48 49.59V96c23.42 0 45.1 6.78 64 17.8V64h352v288h-64v-64H384v64h-76.24c19.1 16.69 33.12 38.73 39.69 64H592c26.47 0 48-22.25 48-49.59V49.59C640 22.25 618.47 0 592 0z\"]\n};\nvar faChargingStation = {\n prefix: 'fas',\n iconName: 'charging-station',\n icon: [576, 512, [], \"f5e7\", \"M336 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h320c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm208-320V80c0-8.84-7.16-16-16-16s-16 7.16-16 16v48h-32V80c0-8.84-7.16-16-16-16s-16 7.16-16 16v48h-16c-8.84 0-16 7.16-16 16v32c0 35.76 23.62 65.69 56 75.93v118.49c0 13.95-9.5 26.92-23.26 29.19C431.22 402.5 416 388.99 416 372v-28c0-48.6-39.4-88-88-88h-8V64c0-35.35-28.65-64-64-64H96C60.65 0 32 28.65 32 64v352h288V304h8c22.09 0 40 17.91 40 40v24.61c0 39.67 28.92 75.16 68.41 79.01C481.71 452.05 520 416.41 520 372V251.93c32.38-10.24 56-40.17 56-75.93v-32c0-8.84-7.16-16-16-16h-16zm-283.91 47.76l-93.7 139c-2.2 3.33-6.21 5.24-10.39 5.24-7.67 0-13.47-6.28-11.67-12.92L167.35 224H108c-7.25 0-12.85-5.59-11.89-11.89l16-107C112.9 99.9 117.98 96 124 96h68c7.88 0 13.62 6.54 11.6 13.21L192 160h57.7c9.24 0 15.01 8.78 10.39 15.76z\"]\n};\nvar faChartArea = {\n prefix: 'fas',\n iconName: 'chart-area',\n icon: [512, 512, [], \"f1fe\", \"M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z\"]\n};\nvar faChartBar = {\n prefix: 'fas',\n iconName: 'chart-bar',\n icon: [512, 512, [], \"f080\", \"M332.8 320h38.4c6.4 0 12.8-6.4 12.8-12.8V172.8c0-6.4-6.4-12.8-12.8-12.8h-38.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h38.4c6.4 0 12.8-6.4 12.8-12.8V76.8c0-6.4-6.4-12.8-12.8-12.8h-38.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-288 0h38.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-38.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h38.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-38.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zM496 384H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faChartLine = {\n prefix: 'fas',\n iconName: 'chart-line',\n icon: [512, 512, [], \"f201\", \"M496 384H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM464 96H345.94c-21.38 0-32.09 25.85-16.97 40.97l32.4 32.4L288 242.75l-73.37-73.37c-12.5-12.5-32.76-12.5-45.25 0l-68.69 68.69c-6.25 6.25-6.25 16.38 0 22.63l22.62 22.62c6.25 6.25 16.38 6.25 22.63 0L192 237.25l73.37 73.37c12.5 12.5 32.76 12.5 45.25 0l96-96 32.4 32.4c15.12 15.12 40.97 4.41 40.97-16.97V112c.01-8.84-7.15-16-15.99-16z\"]\n};\nvar faChartPie = {\n prefix: 'fas',\n iconName: 'chart-pie',\n icon: [544, 512, [], \"f200\", \"M527.79 288H290.5l158.03 158.03c6.04 6.04 15.98 6.53 22.19.68 38.7-36.46 65.32-85.61 73.13-140.86 1.34-9.46-6.51-17.85-16.06-17.85zm-15.83-64.8C503.72 103.74 408.26 8.28 288.8.04 279.68-.59 272 7.1 272 16.24V240h223.77c9.14 0 16.82-7.68 16.19-16.8zM224 288V50.71c0-9.55-8.39-17.4-17.84-16.06C86.99 51.49-4.1 155.6.14 280.37 4.5 408.51 114.83 513.59 243.03 511.98c50.4-.63 96.97-16.87 135.26-44.03 7.9-5.6 8.42-17.23 1.57-24.08L224 288z\"]\n};\nvar faCheck = {\n prefix: 'fas',\n iconName: 'check',\n icon: [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"]\n};\nvar faCheckCircle = {\n prefix: 'fas',\n iconName: 'check-circle',\n icon: [512, 512, [], \"f058\", \"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z\"]\n};\nvar faCheckDouble = {\n prefix: 'fas',\n iconName: 'check-double',\n icon: [512, 512, [], \"f560\", \"M505 174.8l-39.6-39.6c-9.4-9.4-24.6-9.4-33.9 0L192 374.7 80.6 263.2c-9.4-9.4-24.6-9.4-33.9 0L7 302.9c-9.4 9.4-9.4 24.6 0 34L175 505c9.4 9.4 24.6 9.4 33.9 0l296-296.2c9.4-9.5 9.4-24.7.1-34zm-324.3 106c6.2 6.3 16.4 6.3 22.6 0l208-208.2c6.2-6.3 6.2-16.4 0-22.6L366.1 4.7c-6.2-6.3-16.4-6.3-22.6 0L192 156.2l-55.4-55.5c-6.2-6.3-16.4-6.3-22.6 0L68.7 146c-6.2 6.3-6.2 16.4 0 22.6l112 112.2z\"]\n};\nvar faCheckSquare = {\n prefix: 'fas',\n iconName: 'check-square',\n icon: [448, 512, [], \"f14a\", \"M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z\"]\n};\nvar faCheese = {\n prefix: 'fas',\n iconName: 'cheese',\n icon: [512, 512, [], \"f7ef\", \"M0 288v160a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V288zM299.83 32a32 32 0 0 0-21.13 7L0 256h512c0-119.89-94-217.8-212.17-224z\"]\n};\nvar faChess = {\n prefix: 'fas',\n iconName: 'chess',\n icon: [512, 512, [], \"f439\", \"M74 208H64a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h15.94A535.78 535.78 0 0 1 64 384h128a535.78 535.78 0 0 1-15.94-128H192a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16h-10l33.89-90.38a16 16 0 0 0-15-21.62H144V64h24a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8h-24V8a8 8 0 0 0-8-8h-16a8 8 0 0 0-8 8v24H88a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h24v32H55.09a16 16 0 0 0-15 21.62zm173.16 251.58L224 448v-16a16 16 0 0 0-16-16H48a16 16 0 0 0-16 16v16L8.85 459.58A16 16 0 0 0 0 473.89V496a16 16 0 0 0 16 16h224a16 16 0 0 0 16-16v-22.11a16 16 0 0 0-8.84-14.31zm92.77-157.78l-3.29 82.2h126.72l-3.29-82.21 24.6-20.79A32 32 0 0 0 496 256.54V198a6 6 0 0 0-6-6h-26.38a6 6 0 0 0-6 6v26h-24.71v-26a6 6 0 0 0-6-6H373.1a6 6 0 0 0-6 6v26h-24.71v-26a6 6 0 0 0-6-6H310a6 6 0 0 0-6 6v58.6a32 32 0 0 0 11.36 24.4zM384 304a16 16 0 0 1 32 0v32h-32zm119.16 155.58L480 448v-16a16 16 0 0 0-16-16H336a16 16 0 0 0-16 16v16l-23.15 11.58a16 16 0 0 0-8.85 14.31V496a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-22.11a16 16 0 0 0-8.84-14.31z\"]\n};\nvar faChessBishop = {\n prefix: 'fas',\n iconName: 'chess-bishop',\n icon: [320, 512, [], \"f43a\", \"M8 287.88c0 51.64 22.14 73.83 56 84.6V416h192v-43.52c33.86-10.77 56-33 56-84.6 0-30.61-10.73-67.1-26.69-102.56L185 285.65a8 8 0 0 1-11.31 0l-11.31-11.31a8 8 0 0 1 0-11.31L270.27 155.1c-20.8-37.91-46.47-72.1-70.87-92.59C213.4 59.09 224 47.05 224 32a32 32 0 0 0-32-32h-64a32 32 0 0 0-32 32c0 15 10.6 27.09 24.6 30.51C67.81 106.8 8 214.5 8 287.88zM304 448H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faChessBoard = {\n prefix: 'fas',\n iconName: 'chess-board',\n icon: [512, 512, [], \"f43c\", \"M255.9.2h-64v64h64zM0 64.17v64h64v-64zM128 .2H64v64h64zm64 255.9v64h64v-64zM0 192.12v64h64v-64zM383.85.2h-64v64h64zm128 0h-64v64h64zM128 256.1H64v64h64zM511.8 448v-64h-64v64zm0-128v-64h-64v64zM383.85 512h64v-64h-64zm128-319.88v-64h-64v64zM128 512h64v-64h-64zM0 512h64v-64H0zm255.9 0h64v-64h-64zM0 320.07v64h64v-64zm319.88-191.92v-64h-64v64zm-64 128h64v-64h-64zm-64 128v64h64v-64zm128-64h64v-64h-64zm0-127.95h64v-64h-64zm0 191.93v64h64v-64zM64 384.05v64h64v-64zm128-255.9v-64h-64v64zm191.92 255.9h64v-64h-64zm-128-191.93v-64h-64v64zm128-127.95v64h64v-64zm-128 255.9v64h64v-64zm-64-127.95H128v64h64zm191.92 64h64v-64h-64zM128 128.15H64v64h64zm0 191.92v64h64v-64z\"]\n};\nvar faChessKing = {\n prefix: 'fas',\n iconName: 'chess-king',\n icon: [448, 512, [], \"f43f\", \"M400 448H48a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h352a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm16-288H256v-48h40a8 8 0 0 0 8-8V56a8 8 0 0 0-8-8h-40V8a8 8 0 0 0-8-8h-48a8 8 0 0 0-8 8v40h-40a8 8 0 0 0-8 8v48a8 8 0 0 0 8 8h40v48H32a32 32 0 0 0-30.52 41.54L74.56 416h298.88l73.08-214.46A32 32 0 0 0 416 160z\"]\n};\nvar faChessKnight = {\n prefix: 'fas',\n iconName: 'chess-knight',\n icon: [384, 512, [], \"f441\", \"M19 272.47l40.63 18.06a32 32 0 0 0 24.88.47l12.78-5.12a32 32 0 0 0 18.76-20.5l9.22-30.65a24 24 0 0 1 12.55-15.65L159.94 208v50.33a48 48 0 0 1-26.53 42.94l-57.22 28.65A80 80 0 0 0 32 401.48V416h319.86V224c0-106-85.92-192-191.92-192H12A12 12 0 0 0 0 44a16.9 16.9 0 0 0 1.79 7.58L16 80l-9 9a24 24 0 0 0-7 17v137.21a32 32 0 0 0 19 29.26zM52 128a20 20 0 1 1-20 20 20 20 0 0 1 20-20zm316 320H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h352a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faChessPawn = {\n prefix: 'fas',\n iconName: 'chess-pawn',\n icon: [320, 512, [], \"f443\", \"M105.1 224H80a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h16v5.49c0 44-4.14 86.6-24 122.51h176c-19.89-35.91-24-78.51-24-122.51V288h16a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-25.1c29.39-18.38 49.1-50.78 49.1-88a104 104 0 0 0-208 0c0 37.22 19.71 69.62 49.1 88zM304 448H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faChessQueen = {\n prefix: 'fas',\n iconName: 'chess-queen',\n icon: [512, 512, [], \"f445\", \"M256 112a56 56 0 1 0-56-56 56 56 0 0 0 56 56zm176 336H80a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h352a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm72.87-263.84l-28.51-15.92c-7.44-5-16.91-2.46-22.29 4.68a47.59 47.59 0 0 1-47.23 18.23C383.7 186.86 368 164.93 368 141.4a13.4 13.4 0 0 0-13.4-13.4h-38.77c-6 0-11.61 4-12.86 9.91a48 48 0 0 1-93.94 0c-1.25-5.92-6.82-9.91-12.86-9.91H157.4a13.4 13.4 0 0 0-13.4 13.4c0 25.69-19 48.75-44.67 50.49a47.5 47.5 0 0 1-41.54-19.15c-5.28-7.09-14.73-9.45-22.09-4.54l-28.57 16a16 16 0 0 0-5.44 20.47L104.24 416h303.52l102.55-211.37a16 16 0 0 0-5.44-20.47z\"]\n};\nvar faChessRook = {\n prefix: 'fas',\n iconName: 'chess-rook',\n icon: [384, 512, [], \"f447\", \"M368 32h-56a16 16 0 0 0-16 16v48h-48V48a16 16 0 0 0-16-16h-80a16 16 0 0 0-16 16v48H88.1V48a16 16 0 0 0-16-16H16A16 16 0 0 0 0 48v176l64 32c0 48.33-1.54 95-13.21 160h282.42C321.54 351 320 303.72 320 256l64-32V48a16 16 0 0 0-16-16zM224 320h-64v-64a32 32 0 0 1 64 0zm144 128H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h352a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faChevronCircleDown = {\n prefix: 'fas',\n iconName: 'chevron-circle-down',\n icon: [512, 512, [], \"f13a\", \"M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z\"]\n};\nvar faChevronCircleLeft = {\n prefix: 'fas',\n iconName: 'chevron-circle-left',\n icon: [512, 512, [], \"f137\", \"M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z\"]\n};\nvar faChevronCircleRight = {\n prefix: 'fas',\n iconName: 'chevron-circle-right',\n icon: [512, 512, [], \"f138\", \"M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z\"]\n};\nvar faChevronCircleUp = {\n prefix: 'fas',\n iconName: 'chevron-circle-up',\n icon: [512, 512, [], \"f139\", \"M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z\"]\n};\nvar faChevronDown = {\n prefix: 'fas',\n iconName: 'chevron-down',\n icon: [448, 512, [], \"f078\", \"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\"]\n};\nvar faChevronLeft = {\n prefix: 'fas',\n iconName: 'chevron-left',\n icon: [320, 512, [], \"f053\", \"M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z\"]\n};\nvar faChevronRight = {\n prefix: 'fas',\n iconName: 'chevron-right',\n icon: [320, 512, [], \"f054\", \"M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z\"]\n};\nvar faChevronUp = {\n prefix: 'fas',\n iconName: 'chevron-up',\n icon: [448, 512, [], \"f077\", \"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\"]\n};\nvar faChild = {\n prefix: 'fas',\n iconName: 'child',\n icon: [384, 512, [], \"f1ae\", \"M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z\"]\n};\nvar faChurch = {\n prefix: 'fas',\n iconName: 'church',\n icon: [640, 512, [], \"f51d\", \"M464.46 246.68L352 179.2V128h48c8.84 0 16-7.16 16-16V80c0-8.84-7.16-16-16-16h-48V16c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v48h-48c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h48v51.2l-112.46 67.48A31.997 31.997 0 0 0 160 274.12V512h96v-96c0-35.35 28.65-64 64-64s64 28.65 64 64v96h96V274.12c0-11.24-5.9-21.66-15.54-27.44zM0 395.96V496c0 8.84 7.16 16 16 16h112V320L19.39 366.54A32.024 32.024 0 0 0 0 395.96zm620.61-29.42L512 320v192h112c8.84 0 16-7.16 16-16V395.96c0-12.8-7.63-24.37-19.39-29.42z\"]\n};\nvar faCircle = {\n prefix: 'fas',\n iconName: 'circle',\n icon: [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"]\n};\nvar faCircleNotch = {\n prefix: 'fas',\n iconName: 'circle-notch',\n icon: [512, 512, [], \"f1ce\", \"M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z\"]\n};\nvar faCity = {\n prefix: 'fas',\n iconName: 'city',\n icon: [640, 512, [], \"f64f\", \"M616 192H480V24c0-13.26-10.74-24-24-24H312c-13.26 0-24 10.74-24 24v72h-64V16c0-8.84-7.16-16-16-16h-16c-8.84 0-16 7.16-16 16v80h-64V16c0-8.84-7.16-16-16-16H80c-8.84 0-16 7.16-16 16v80H24c-13.26 0-24 10.74-24 24v360c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V216c0-13.26-10.75-24-24-24zM128 404c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm128 192c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm160 96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12V76c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm160 288c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40z\"]\n};\nvar faClinicMedical = {\n prefix: 'fas',\n iconName: 'clinic-medical',\n icon: [576, 512, [], \"f7f2\", \"M288 115L69.47 307.71c-1.62 1.46-3.69 2.14-5.47 3.35V496a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V311.1c-1.7-1.16-3.72-1.82-5.26-3.2zm96 261a8 8 0 0 1-8 8h-56v56a8 8 0 0 1-8 8h-48a8 8 0 0 1-8-8v-56h-56a8 8 0 0 1-8-8v-48a8 8 0 0 1 8-8h56v-56a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8v56h56a8 8 0 0 1 8 8zm186.69-139.72l-255.94-226a39.85 39.85 0 0 0-53.45 0l-256 226a16 16 0 0 0-1.21 22.6L25.5 282.7a16 16 0 0 0 22.6 1.21L277.42 81.63a16 16 0 0 1 21.17 0L527.91 283.9a16 16 0 0 0 22.6-1.21l21.4-23.82a16 16 0 0 0-1.22-22.59z\"]\n};\nvar faClipboard = {\n prefix: 'fas',\n iconName: 'clipboard',\n icon: [384, 512, [], \"f328\", \"M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z\"]\n};\nvar faClipboardCheck = {\n prefix: 'fas',\n iconName: 'clipboard-check',\n icon: [384, 512, [], \"f46c\", \"M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm121.2 231.8l-143 141.8c-4.7 4.7-12.3 4.6-17-.1l-82.6-83.3c-4.7-4.7-4.6-12.3.1-17L99.1 285c4.7-4.7 12.3-4.6 17 .1l46 46.4 106-105.2c4.7-4.7 12.3-4.6 17 .1l28.2 28.4c4.7 4.8 4.6 12.3-.1 17z\"]\n};\nvar faClipboardList = {\n prefix: 'fas',\n iconName: 'clipboard-list',\n icon: [384, 512, [], \"f46d\", \"M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM96 424c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm0-96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm0-96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zm96-192c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm128 368c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16z\"]\n};\nvar faClock = {\n prefix: 'fas',\n iconName: 'clock',\n icon: [512, 512, [], \"f017\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z\"]\n};\nvar faClone = {\n prefix: 'fas',\n iconName: 'clone',\n icon: [512, 512, [], \"f24d\", \"M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z\"]\n};\nvar faClosedCaptioning = {\n prefix: 'fas',\n iconName: 'closed-captioning',\n icon: [512, 512, [], \"f20a\", \"M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z\"]\n};\nvar faCloud = {\n prefix: 'fas',\n iconName: 'cloud',\n icon: [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"]\n};\nvar faCloudDownloadAlt = {\n prefix: 'fas',\n iconName: 'cloud-download-alt',\n icon: [640, 512, [], \"f381\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zm-132.9 88.7L299.3 420.7c-6.2 6.2-16.4 6.2-22.6 0L171.3 315.3c-10.1-10.1-2.9-27.3 11.3-27.3H248V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v112h65.4c14.2 0 21.4 17.2 11.3 27.3z\"]\n};\nvar faCloudMeatball = {\n prefix: 'fas',\n iconName: 'cloud-meatball',\n icon: [512, 512, [], \"f73b\", \"M48 352c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm416 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm-119 11.1c4.6-14.5 1.6-30.8-9.8-42.3-11.5-11.5-27.8-14.4-42.3-9.9-7-13.5-20.7-23-36.9-23s-29.9 9.5-36.9 23c-14.5-4.6-30.8-1.6-42.3 9.9-11.5 11.5-14.4 27.8-9.9 42.3-13.5 7-23 20.7-23 36.9s9.5 29.9 23 36.9c-4.6 14.5-1.6 30.8 9.9 42.3 8.2 8.2 18.9 12.3 29.7 12.3 4.3 0 8.5-1.1 12.6-2.5 7 13.5 20.7 23 36.9 23s29.9-9.5 36.9-23c4.1 1.3 8.3 2.5 12.6 2.5 10.8 0 21.5-4.1 29.7-12.3 11.5-11.5 14.4-27.8 9.8-42.3 13.5-7 23-20.7 23-36.9s-9.5-29.9-23-36.9zM512 224c0-53-43-96-96-96-.6 0-1.1.2-1.6.2 1.1-5.2 1.6-10.6 1.6-16.2 0-44.2-35.8-80-80-80-24.6 0-46.3 11.3-61 28.8C256.4 24.8 219.3 0 176 0 114.1 0 64 50.1 64 112c0 7.3.8 14.3 2.1 21.2C27.8 145.8 0 181.5 0 224c0 53 43 96 96 96h43.4c3.6-8 8.4-15.4 14.8-21.8 13.5-13.5 31.5-21.1 50.8-21.3 13.5-13.2 31.7-20.9 51-20.9s37.5 7.7 51 20.9c19.3.2 37.3 7.8 50.8 21.3 6.4 6.4 11.3 13.8 14.8 21.8H416c53 0 96-43 96-96z\"]\n};\nvar faCloudMoon = {\n prefix: 'fas',\n iconName: 'cloud-moon',\n icon: [576, 512, [], \"f6c3\", \"M342.8 352.7c5.7-9.6 9.2-20.7 9.2-32.7 0-35.3-28.7-64-64-64-17.2 0-32.8 6.9-44.3 17.9-16.3-29.6-47.5-49.9-83.7-49.9-53 0-96 43-96 96 0 2 .5 3.8.6 5.7C27.1 338.8 0 374.1 0 416c0 53 43 96 96 96h240c44.2 0 80-35.8 80-80 0-41.9-32.3-75.8-73.2-79.3zm222.5-54.3c-93.1 17.7-178.5-53.7-178.5-147.7 0-54.2 29-104 76.1-130.8 7.3-4.1 5.4-15.1-2.8-16.7C448.4 1.1 436.7 0 425 0 319.1 0 233.1 85.9 233.1 192c0 8.5.7 16.8 1.8 25 5.9 4.3 11.6 8.9 16.7 14.2 11.4-4.7 23.7-7.2 36.4-7.2 52.9 0 96 43.1 96 96 0 3.6-.2 7.2-.6 10.7 23.6 10.8 42.4 29.5 53.5 52.6 54.4-3.4 103.7-29.3 137.1-70.4 5.3-6.5-.5-16.1-8.7-14.5z\"]\n};\nvar faCloudMoonRain = {\n prefix: 'fas',\n iconName: 'cloud-moon-rain',\n icon: [576, 512, [], \"f73c\", \"M350.5 225.5c-6.9-37.2-39.3-65.5-78.5-65.5-12.3 0-23.9 3-34.3 8-17.4-24.1-45.6-40-77.7-40-53 0-96 43-96 96 0 .5.2 1.1.2 1.6C27.6 232.9 0 265.2 0 304c0 44.2 35.8 80 80 80h256c44.2 0 80-35.8 80-80 0-39.2-28.2-71.7-65.5-78.5zm217.4-1.7c-70.4 13.3-135-40.3-135-110.8 0-40.6 21.9-78 57.5-98.1 5.5-3.1 4.1-11.4-2.1-12.5C479.6.8 470.7 0 461.8 0c-77.9 0-141.1 61.2-144.4 137.9 26.7 11.9 48.2 33.8 58.9 61.7 37.1 14.3 64 47.4 70.2 86.8 5.1.5 10 1.5 15.2 1.5 44.7 0 85.6-20.2 112.6-53.3 4.2-4.8-.2-12-6.4-10.8zM364.5 418.1c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8z\"]\n};\nvar faCloudRain = {\n prefix: 'fas',\n iconName: 'cloud-rain',\n icon: [512, 512, [], \"f73d\", \"M416 128c-.6 0-1.1.2-1.6.2 1.1-5.2 1.6-10.6 1.6-16.2 0-44.2-35.8-80-80-80-24.6 0-46.3 11.3-61 28.8C256.4 24.8 219.3 0 176 0 114.1 0 64 50.1 64 112c0 7.3.8 14.3 2.1 21.2C27.8 145.8 0 181.5 0 224c0 53 43 96 96 96h320c53 0 96-43 96-96s-43-96-96-96zM88 374.2c-12.8 44.4-40 56.4-40 87.7 0 27.7 21.5 50.1 48 50.1s48-22.4 48-50.1c0-31.4-27.2-43.1-40-87.7-2.2-8.1-13.5-8.5-16 0zm160 0c-12.8 44.4-40 56.4-40 87.7 0 27.7 21.5 50.1 48 50.1s48-22.4 48-50.1c0-31.4-27.2-43.1-40-87.7-2.2-8.1-13.5-8.5-16 0zm160 0c-12.8 44.4-40 56.4-40 87.7 0 27.7 21.5 50.1 48 50.1s48-22.4 48-50.1c0-31.4-27.2-43.1-40-87.7-2.2-8.1-13.5-8.5-16 0z\"]\n};\nvar faCloudShowersHeavy = {\n prefix: 'fas',\n iconName: 'cloud-showers-heavy',\n icon: [512, 512, [], \"f740\", \"M183.9 370.1c-7.6-4.4-17.4-1.8-21.8 6l-64 112c-4.4 7.7-1.7 17.5 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l64-112c4.4-7.6 1.7-17.4-6-21.8zm96 0c-7.6-4.4-17.4-1.8-21.8 6l-64 112c-4.4 7.7-1.7 17.5 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l64-112c4.4-7.6 1.7-17.4-6-21.8zm-192 0c-7.6-4.4-17.4-1.8-21.8 6l-64 112c-4.4 7.7-1.7 17.5 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l64-112c4.4-7.6 1.7-17.4-6-21.8zm384 0c-7.6-4.4-17.4-1.8-21.8 6l-64 112c-4.4 7.7-1.7 17.5 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l64-112c4.4-7.6 1.7-17.4-6-21.8zm-96 0c-7.6-4.4-17.4-1.8-21.8 6l-64 112c-4.4 7.7-1.7 17.5 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l64-112c4.4-7.6 1.7-17.4-6-21.8zM416 128c-.6 0-1.1.2-1.6.2 1.1-5.2 1.6-10.6 1.6-16.2 0-44.2-35.8-80-80-80-24.6 0-46.3 11.3-61 28.8C256.4 24.8 219.3 0 176 0 114.2 0 64 50.1 64 112c0 7.3.8 14.3 2.1 21.2C27.8 145.8 0 181.5 0 224c0 53 43 96 96 96h320c53 0 96-43 96-96s-43-96-96-96z\"]\n};\nvar faCloudSun = {\n prefix: 'fas',\n iconName: 'cloud-sun',\n icon: [640, 512, [], \"f6c4\", \"M575.2 325.7c.2-1.9.8-3.7.8-5.6 0-35.3-28.7-64-64-64-12.6 0-24.2 3.8-34.1 10-17.6-38.8-56.5-66-101.9-66-61.8 0-112 50.1-112 112 0 3 .7 5.8.9 8.7-49.6 3.7-88.9 44.7-88.9 95.3 0 53 43 96 96 96h272c53 0 96-43 96-96 0-42.1-27.2-77.4-64.8-90.4zm-430.4-22.6c-43.7-43.7-43.7-114.7 0-158.3 43.7-43.7 114.7-43.7 158.4 0 9.7 9.7 16.9 20.9 22.3 32.7 9.8-3.7 20.1-6 30.7-7.5L386 81.1c4-11.9-7.3-23.1-19.2-19.2L279 91.2 237.5 8.4C232-2.8 216-2.8 210.4 8.4L169 91.2 81.1 61.9C69.3 58 58 69.3 61.9 81.1l29.3 87.8-82.8 41.5c-11.2 5.6-11.2 21.5 0 27.1l82.8 41.4-29.3 87.8c-4 11.9 7.3 23.1 19.2 19.2l76.1-25.3c6.1-12.4 14-23.7 23.6-33.5-13.1-5.4-25.4-13.4-36-24zm-4.8-79.2c0 40.8 29.3 74.8 67.9 82.3 8-4.7 16.3-8.8 25.2-11.7 5.4-44.3 31-82.5 67.4-105C287.3 160.4 258 140 224 140c-46.3 0-84 37.6-84 83.9z\"]\n};\nvar faCloudSunRain = {\n prefix: 'fas',\n iconName: 'cloud-sun-rain',\n icon: [576, 512, [], \"f743\", \"M510.5 225.5c-6.9-37.2-39.3-65.5-78.5-65.5-12.3 0-23.9 3-34.3 8-17.4-24.1-45.6-40-77.7-40-53 0-96 43-96 96 0 .5.2 1.1.2 1.6C187.6 233 160 265.2 160 304c0 44.2 35.8 80 80 80h256c44.2 0 80-35.8 80-80 0-39.2-28.2-71.7-65.5-78.5zm-386.4 34.4c-37.4-37.4-37.4-98.3 0-135.8 34.6-34.6 89.1-36.8 126.7-7.4 20-12.9 43.6-20.7 69.2-20.7.7 0 1.3.2 2 .2l8.9-26.7c3.4-10.2-6.3-19.8-16.5-16.4l-75.3 25.1-35.5-71c-4.8-9.6-18.5-9.6-23.3 0l-35.5 71-75.3-25.1c-10.2-3.4-19.8 6.3-16.4 16.5l25.1 75.3-71 35.5c-9.6 4.8-9.6 18.5 0 23.3l71 35.5-25.1 75.3c-3.4 10.2 6.3 19.8 16.5 16.5l59.2-19.7c-.2-2.4-.7-4.7-.7-7.2 0-12.5 2.3-24.5 6.2-35.9-3.6-2.7-7.1-5.2-10.2-8.3zm69.8-58c4.3-24.5 15.8-46.4 31.9-64-9.8-6.2-21.4-9.9-33.8-9.9-35.3 0-64 28.7-64 64 0 18.7 8.2 35.4 21.1 47.1 11.3-15.9 26.6-28.9 44.8-37.2zm330.6 216.2c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8zm-96 0c-7.6-4.3-17.4-1.8-21.8 6l-36.6 64c-4.4 7.7-1.7 17.4 6 21.8 2.5 1.4 5.2 2.1 7.9 2.1 5.5 0 10.9-2.9 13.9-8.1l36.6-64c4.3-7.7 1.7-17.4-6-21.8z\"]\n};\nvar faCloudUploadAlt = {\n prefix: 'fas',\n iconName: 'cloud-upload-alt',\n icon: [640, 512, [], \"f382\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zM393.4 288H328v112c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V288h-65.4c-14.3 0-21.4-17.2-11.3-27.3l105.4-105.4c6.2-6.2 16.4-6.2 22.6 0l105.4 105.4c10.1 10.1 2.9 27.3-11.3 27.3z\"]\n};\nvar faCocktail = {\n prefix: 'fas',\n iconName: 'cocktail',\n icon: [576, 512, [], \"f561\", \"M296 464h-56V338.78l168.74-168.73c15.52-15.52 4.53-42.05-17.42-42.05H24.68c-21.95 0-32.94 26.53-17.42 42.05L176 338.78V464h-56c-22.09 0-40 17.91-40 40 0 4.42 3.58 8 8 8h240c4.42 0 8-3.58 8-8 0-22.09-17.91-40-40-40zM432 0c-62.61 0-115.35 40.2-135.18 96h52.54c16.65-28.55 47.27-48 82.64-48 52.93 0 96 43.06 96 96s-43.07 96-96 96c-14.04 0-27.29-3.2-39.32-8.64l-35.26 35.26C379.23 279.92 404.59 288 432 288c79.53 0 144-64.47 144-144S511.53 0 432 0z\"]\n};\nvar faCode = {\n prefix: 'fas',\n iconName: 'code',\n icon: [640, 512, [], \"f121\", \"M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z\"]\n};\nvar faCodeBranch = {\n prefix: 'fas',\n iconName: 'code-branch',\n icon: [384, 512, [], \"f126\", \"M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z\"]\n};\nvar faCoffee = {\n prefix: 'fas',\n iconName: 'coffee',\n icon: [640, 512, [], \"f0f4\", \"M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z\"]\n};\nvar faCog = {\n prefix: 'fas',\n iconName: 'cog',\n icon: [512, 512, [], \"f013\", \"M487.4 315.7l-42.6-24.6c4.3-23.2 4.3-47 0-70.2l42.6-24.6c4.9-2.8 7.1-8.6 5.5-14-11.1-35.6-30-67.8-54.7-94.6-3.8-4.1-10-5.1-14.8-2.3L380.8 110c-17.9-15.4-38.5-27.3-60.8-35.1V25.8c0-5.6-3.9-10.5-9.4-11.7-36.7-8.2-74.3-7.8-109.2 0-5.5 1.2-9.4 6.1-9.4 11.7V75c-22.2 7.9-42.8 19.8-60.8 35.1L88.7 85.5c-4.9-2.8-11-1.9-14.8 2.3-24.7 26.7-43.6 58.9-54.7 94.6-1.7 5.4.6 11.2 5.5 14L67.3 221c-4.3 23.2-4.3 47 0 70.2l-42.6 24.6c-4.9 2.8-7.1 8.6-5.5 14 11.1 35.6 30 67.8 54.7 94.6 3.8 4.1 10 5.1 14.8 2.3l42.6-24.6c17.9 15.4 38.5 27.3 60.8 35.1v49.2c0 5.6 3.9 10.5 9.4 11.7 36.7 8.2 74.3 7.8 109.2 0 5.5-1.2 9.4-6.1 9.4-11.7v-49.2c22.2-7.9 42.8-19.8 60.8-35.1l42.6 24.6c4.9 2.8 11 1.9 14.8-2.3 24.7-26.7 43.6-58.9 54.7-94.6 1.5-5.5-.7-11.3-5.6-14.1zM256 336c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faCogs = {\n prefix: 'fas',\n iconName: 'cogs',\n icon: [640, 512, [], \"f085\", \"M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z\"]\n};\nvar faCoins = {\n prefix: 'fas',\n iconName: 'coins',\n icon: [512, 512, [], \"f51e\", \"M0 405.3V448c0 35.3 86 64 192 64s192-28.7 192-64v-42.7C342.7 434.4 267.2 448 192 448S41.3 434.4 0 405.3zM320 128c106 0 192-28.7 192-64S426 0 320 0 128 28.7 128 64s86 64 192 64zM0 300.4V352c0 35.3 86 64 192 64s192-28.7 192-64v-51.6c-41.3 34-116.9 51.6-192 51.6S41.3 334.4 0 300.4zm416 11c57.3-11.1 96-31.7 96-55.4v-42.7c-23.2 16.4-57.3 27.6-96 34.5v63.6zM192 160C86 160 0 195.8 0 240s86 80 192 80 192-35.8 192-80-86-80-192-80zm219.3 56.3c60-10.8 100.7-32 100.7-56.3v-42.7c-35.5 25.1-96.5 38.6-160.7 41.8 29.5 14.3 51.2 33.5 60 57.2z\"]\n};\nvar faColumns = {\n prefix: 'fas',\n iconName: 'columns',\n icon: [512, 512, [], \"f0db\", \"M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z\"]\n};\nvar faComment = {\n prefix: 'fas',\n iconName: 'comment',\n icon: [512, 512, [], \"f075\", \"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7S4.8 480 8 480c66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32z\"]\n};\nvar faCommentAlt = {\n prefix: 'fas',\n iconName: 'comment-alt',\n icon: [512, 512, [], \"f27a\", \"M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z\"]\n};\nvar faCommentDollar = {\n prefix: 'fas',\n iconName: 'comment-dollar',\n icon: [512, 512, [], \"f651\", \"M256 32C114.62 32 0 125.12 0 240c0 49.56 21.41 95.01 57.02 130.74C44.46 421.05 2.7 465.97 2.2 466.5A7.995 7.995 0 0 0 8 480c66.26 0 115.99-31.75 140.6-51.38C181.29 440.93 217.59 448 256 448c141.38 0 256-93.12 256-208S397.38 32 256 32zm24 302.44V352c0 8.84-7.16 16-16 16h-16c-8.84 0-16-7.16-16-16v-17.73c-11.42-1.35-22.28-5.19-31.78-11.46-6.22-4.11-6.82-13.11-1.55-18.38l17.52-17.52c3.74-3.74 9.31-4.24 14.11-2.03 3.18 1.46 6.66 2.22 10.26 2.22h32.78c4.66 0 8.44-3.78 8.44-8.42 0-3.75-2.52-7.08-6.12-8.11l-50.07-14.3c-22.25-6.35-40.01-24.71-42.91-47.67-4.05-32.07 19.03-59.43 49.32-63.05V128c0-8.84 7.16-16 16-16h16c8.84 0 16 7.16 16 16v17.73c11.42 1.35 22.28 5.19 31.78 11.46 6.22 4.11 6.82 13.11 1.55 18.38l-17.52 17.52c-3.74 3.74-9.31 4.24-14.11 2.03a24.516 24.516 0 0 0-10.26-2.22h-32.78c-4.66 0-8.44 3.78-8.44 8.42 0 3.75 2.52 7.08 6.12 8.11l50.07 14.3c22.25 6.36 40.01 24.71 42.91 47.67 4.05 32.06-19.03 59.42-49.32 63.04z\"]\n};\nvar faCommentDots = {\n prefix: 'fas',\n iconName: 'comment-dots',\n icon: [512, 512, [], \"f4ad\", \"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7S4.8 480 8 480c66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faCommentMedical = {\n prefix: 'fas',\n iconName: 'comment-medical',\n icon: [512, 512, [], \"f7f5\", \"M256 32C114.62 32 0 125.12 0 240c0 49.56 21.41 95 57 130.74C44.46 421.05 2.7 466 2.2 466.5A8 8 0 0 0 8 480c66.26 0 116-31.75 140.6-51.38A304.66 304.66 0 0 0 256 448c141.39 0 256-93.12 256-208S397.39 32 256 32zm96 232a8 8 0 0 1-8 8h-56v56a8 8 0 0 1-8 8h-48a8 8 0 0 1-8-8v-56h-56a8 8 0 0 1-8-8v-48a8 8 0 0 1 8-8h56v-56a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8v56h56a8 8 0 0 1 8 8z\"]\n};\nvar faCommentSlash = {\n prefix: 'fas',\n iconName: 'comment-slash',\n icon: [640, 512, [], \"f4b3\", \"M64 240c0 49.6 21.4 95 57 130.7-12.6 50.3-54.3 95.2-54.8 95.8-2.2 2.3-2.8 5.7-1.5 8.7 1.3 2.9 4.1 4.8 7.3 4.8 66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 27.4 0 53.7-3.6 78.4-10L72.9 186.4c-5.6 17.1-8.9 35-8.9 53.6zm569.8 218.1l-114.4-88.4C554.6 334.1 576 289.2 576 240c0-114.9-114.6-208-256-208-65.1 0-124.2 20.1-169.4 52.7L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3z\"]\n};\nvar faComments = {\n prefix: 'fas',\n iconName: 'comments',\n icon: [576, 512, [], \"f086\", \"M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160zm122 220c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z\"]\n};\nvar faCommentsDollar = {\n prefix: 'fas',\n iconName: 'comments-dollar',\n icon: [576, 512, [], \"f653\", \"M416 192c0-88.37-93.12-160-208-160S0 103.63 0 192c0 34.27 14.13 65.95 37.97 91.98C24.61 314.22 2.52 338.16 2.2 338.5A7.995 7.995 0 0 0 8 352c36.58 0 66.93-12.25 88.73-24.98C128.93 342.76 167.02 352 208 352c114.88 0 208-71.63 208-160zm-224 96v-16.29c-11.29-.58-22.27-4.52-31.37-11.35-3.9-2.93-4.1-8.77-.57-12.14l11.75-11.21c2.77-2.64 6.89-2.76 10.13-.73 3.87 2.42 8.26 3.72 12.82 3.72h28.11c6.5 0 11.8-5.92 11.8-13.19 0-5.95-3.61-11.19-8.77-12.73l-45-13.5c-18.59-5.58-31.58-23.42-31.58-43.39 0-24.52 19.05-44.44 42.67-45.07V96c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16.29c11.29.58 22.27 4.51 31.37 11.35 3.9 2.93 4.1 8.77.57 12.14l-11.75 11.21c-2.77 2.64-6.89 2.76-10.13.73-3.87-2.43-8.26-3.72-12.82-3.72h-28.11c-6.5 0-11.8 5.92-11.8 13.19 0 5.95 3.61 11.19 8.77 12.73l45 13.5c18.59 5.58 31.58 23.42 31.58 43.39 0 24.53-19.05 44.44-42.67 45.07V288c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8zm346.01 123.99C561.87 385.96 576 354.27 576 320c0-66.94-53.49-124.2-129.33-148.07.86 6.6 1.33 13.29 1.33 20.07 0 105.87-107.66 192-240 192-10.78 0-21.32-.77-31.73-1.88C207.8 439.63 281.77 480 368 480c40.98 0 79.07-9.24 111.27-24.98C501.07 467.75 531.42 480 568 480c3.2 0 6.09-1.91 7.34-4.84 1.27-2.94.66-6.34-1.55-8.67-.31-.33-22.42-24.24-35.78-54.5z\"]\n};\nvar faCompactDisc = {\n prefix: 'fas',\n iconName: 'compact-disc',\n icon: [496, 512, [], \"f51f\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM88 256H56c0-105.9 86.1-192 192-192v32c-88.2 0-160 71.8-160 160zm160 96c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96zm0-128c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"]\n};\nvar faCompass = {\n prefix: 'fas',\n iconName: 'compass',\n icon: [496, 512, [], \"f14e\", \"M225.38 233.37c-12.5 12.5-12.5 32.76 0 45.25 12.49 12.5 32.76 12.5 45.25 0 12.5-12.5 12.5-32.76 0-45.25-12.5-12.49-32.76-12.49-45.25 0zM248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm126.14 148.05L308.17 300.4a31.938 31.938 0 0 1-15.77 15.77l-144.34 65.97c-16.65 7.61-33.81-9.55-26.2-26.2l65.98-144.35a31.938 31.938 0 0 1 15.77-15.77l144.34-65.97c16.65-7.6 33.8 9.55 26.19 26.2z\"]\n};\nvar faCompress = {\n prefix: 'fas',\n iconName: 'compress',\n icon: [448, 512, [], \"f066\", \"M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z\"]\n};\nvar faCompressArrowsAlt = {\n prefix: 'fas',\n iconName: 'compress-arrows-alt',\n icon: [512, 512, [], \"f78c\", \"M200 288H88c-21.4 0-32.1 25.8-17 41l32.9 31-99.2 99.3c-6.2 6.2-6.2 16.4 0 22.6l25.4 25.4c6.2 6.2 16.4 6.2 22.6 0L152 408l31.1 33c15.1 15.1 40.9 4.4 40.9-17V312c0-13.3-10.7-24-24-24zm112-64h112c21.4 0 32.1-25.9 17-41l-33-31 99.3-99.3c6.2-6.2 6.2-16.4 0-22.6L481.9 4.7c-6.2-6.2-16.4-6.2-22.6 0L360 104l-31.1-33C313.8 55.9 288 66.6 288 88v112c0 13.3 10.7 24 24 24zm96 136l33-31.1c15.1-15.1 4.4-40.9-17-40.9H312c-13.3 0-24 10.7-24 24v112c0 21.4 25.9 32.1 41 17l31-32.9 99.3 99.3c6.2 6.2 16.4 6.2 22.6 0l25.4-25.4c6.2-6.2 6.2-16.4 0-22.6L408 360zM183 71.1L152 104 52.7 4.7c-6.2-6.2-16.4-6.2-22.6 0L4.7 30.1c-6.2 6.2-6.2 16.4 0 22.6L104 152l-33 31.1C55.9 198.2 66.6 224 88 224h112c13.3 0 24-10.7 24-24V88c0-21.3-25.9-32-41-16.9z\"]\n};\nvar faConciergeBell = {\n prefix: 'fas',\n iconName: 'concierge-bell',\n icon: [512, 512, [], \"f562\", \"M288 130.54V112h16c8.84 0 16-7.16 16-16V80c0-8.84-7.16-16-16-16h-96c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h16v18.54C115.49 146.11 32 239.18 32 352h448c0-112.82-83.49-205.89-192-221.46zM496 384H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h480c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faCookie = {\n prefix: 'fas',\n iconName: 'cookie',\n icon: [512, 512, [], \"f563\", \"M510.37 254.79l-12.08-76.26a132.493 132.493 0 0 0-37.16-72.95l-54.76-54.75c-19.73-19.72-45.18-32.7-72.71-37.05l-76.7-12.15c-27.51-4.36-55.69.11-80.52 12.76L107.32 49.6a132.25 132.25 0 0 0-57.79 57.8l-35.1 68.88a132.602 132.602 0 0 0-12.82 80.94l12.08 76.27a132.493 132.493 0 0 0 37.16 72.95l54.76 54.75a132.087 132.087 0 0 0 72.71 37.05l76.7 12.14c27.51 4.36 55.69-.11 80.52-12.75l69.12-35.21a132.302 132.302 0 0 0 57.79-57.8l35.1-68.87c12.71-24.96 17.2-53.3 12.82-80.96zM176 368c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm32-160c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm160 128c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faCookieBite = {\n prefix: 'fas',\n iconName: 'cookie-bite',\n icon: [512, 512, [], \"f564\", \"M510.52 255.82c-69.97-.85-126.47-57.69-126.47-127.86-70.17 0-127-56.49-127.86-126.45-27.26-4.14-55.13.3-79.72 12.82l-69.13 35.22a132.221 132.221 0 0 0-57.79 57.81l-35.1 68.88a132.645 132.645 0 0 0-12.82 80.95l12.08 76.27a132.521 132.521 0 0 0 37.16 72.96l54.77 54.76a132.036 132.036 0 0 0 72.71 37.06l76.71 12.15c27.51 4.36 55.7-.11 80.53-12.76l69.13-35.21a132.273 132.273 0 0 0 57.79-57.81l35.1-68.88c12.56-24.64 17.01-52.58 12.91-79.91zM176 368c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm32-160c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm160 128c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faCopy = {\n prefix: 'fas',\n iconName: 'copy',\n icon: [448, 512, [], \"f0c5\", \"M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z\"]\n};\nvar faCopyright = {\n prefix: 'fas',\n iconName: 'copyright',\n icon: [512, 512, [], \"f1f9\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z\"]\n};\nvar faCouch = {\n prefix: 'fas',\n iconName: 'couch',\n icon: [640, 512, [], \"f4b8\", \"M160 224v64h320v-64c0-35.3 28.7-64 64-64h32c0-53-43-96-96-96H160c-53 0-96 43-96 96h32c35.3 0 64 28.7 64 64zm416-32h-32c-17.7 0-32 14.3-32 32v96H128v-96c0-17.7-14.3-32-32-32H64c-35.3 0-64 28.7-64 64 0 23.6 13 44 32 55.1V432c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-16h384v16c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V311.1c19-11.1 32-31.5 32-55.1 0-35.3-28.7-64-64-64z\"]\n};\nvar faCreditCard = {\n prefix: 'fas',\n iconName: 'credit-card',\n icon: [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"]\n};\nvar faCrop = {\n prefix: 'fas',\n iconName: 'crop',\n icon: [512, 512, [], \"f125\", \"M488 352h-40V109.25l59.31-59.31c6.25-6.25 6.25-16.38 0-22.63L484.69 4.69c-6.25-6.25-16.38-6.25-22.63 0L402.75 64H192v96h114.75L160 306.75V24c0-13.26-10.75-24-24-24H88C74.75 0 64 10.74 64 24v40H24C10.75 64 0 74.74 0 88v48c0 13.25 10.75 24 24 24h40v264c0 13.25 10.75 24 24 24h232v-96H205.25L352 205.25V488c0 13.25 10.75 24 24 24h48c13.25 0 24-10.75 24-24v-40h40c13.25 0 24-10.75 24-24v-48c0-13.26-10.75-24-24-24z\"]\n};\nvar faCropAlt = {\n prefix: 'fas',\n iconName: 'crop-alt',\n icon: [512, 512, [], \"f565\", \"M488 352h-40V96c0-17.67-14.33-32-32-32H192v96h160v328c0 13.25 10.75 24 24 24h48c13.25 0 24-10.75 24-24v-40h40c13.25 0 24-10.75 24-24v-48c0-13.26-10.75-24-24-24zM160 24c0-13.26-10.75-24-24-24H88C74.75 0 64 10.74 64 24v40H24C10.75 64 0 74.74 0 88v48c0 13.25 10.75 24 24 24h40v256c0 17.67 14.33 32 32 32h224v-96H160V24z\"]\n};\nvar faCross = {\n prefix: 'fas',\n iconName: 'cross',\n icon: [384, 512, [], \"f654\", \"M352 128h-96V32c0-17.67-14.33-32-32-32h-64c-17.67 0-32 14.33-32 32v96H32c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h96v224c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32V256h96c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32z\"]\n};\nvar faCrosshairs = {\n prefix: 'fas',\n iconName: 'crosshairs',\n icon: [512, 512, [], \"f05b\", \"M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z\"]\n};\nvar faCrow = {\n prefix: 'fas',\n iconName: 'crow',\n icon: [640, 512, [], \"f520\", \"M544 32h-16.36C513.04 12.68 490.09 0 464 0c-44.18 0-80 35.82-80 80v20.98L12.09 393.57A30.216 30.216 0 0 0 0 417.74c0 22.46 23.64 37.07 43.73 27.03L165.27 384h96.49l44.41 120.1c2.27 6.23 9.15 9.44 15.38 7.17l22.55-8.21c6.23-2.27 9.44-9.15 7.17-15.38L312.94 384H352c1.91 0 3.76-.23 5.66-.29l44.51 120.38c2.27 6.23 9.15 9.44 15.38 7.17l22.55-8.21c6.23-2.27 9.44-9.15 7.17-15.38l-41.24-111.53C485.74 352.8 544 279.26 544 192v-80l96-16c0-35.35-42.98-64-96-64zm-80 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"]\n};\nvar faCrown = {\n prefix: 'fas',\n iconName: 'crown',\n icon: [640, 512, [], \"f521\", \"M528 448H112c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h416c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm64-320c-26.5 0-48 21.5-48 48 0 7.1 1.6 13.7 4.4 19.8L476 239.2c-15.4 9.2-35.3 4-44.2-11.6L350.3 85C361 76.2 368 63 368 48c0-26.5-21.5-48-48-48s-48 21.5-48 48c0 15 7 28.2 17.7 37l-81.5 142.6c-8.9 15.6-28.9 20.8-44.2 11.6l-72.3-43.4c2.7-6 4.4-12.7 4.4-19.8 0-26.5-21.5-48-48-48S0 149.5 0 176s21.5 48 48 48c2.6 0 5.2-.4 7.7-.8L128 416h384l72.3-192.8c2.5.4 5.1.8 7.7.8 26.5 0 48-21.5 48-48s-21.5-48-48-48z\"]\n};\nvar faCrutch = {\n prefix: 'fas',\n iconName: 'crutch',\n icon: [512, 512, [], \"f7f7\", \"M507.31 185.71l-181-181a16 16 0 0 0-22.62 0L281 27.31a16 16 0 0 0 0 22.63l181 181a16 16 0 0 0 22.63 0l22.62-22.63a16 16 0 0 0 .06-22.6zm-179.54 66.41l-67.89-67.89 55.1-55.1-45.25-45.25-109.67 109.67a96.08 96.08 0 0 0-25.67 46.29L106.65 360.1l-102 102a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0l102-102 120.25-27.75a95.88 95.88 0 0 0 46.29-25.65l109.68-109.68L382.87 197zm-54.57 54.57a32 32 0 0 1-15.45 8.54l-79.3 18.32 18.3-79.3a32.22 32.22 0 0 1 8.56-15.45l9.31-9.31 67.89 67.89z\"]\n};\nvar faCube = {\n prefix: 'fas',\n iconName: 'cube',\n icon: [512, 512, [], \"f1b2\", \"M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z\"]\n};\nvar faCubes = {\n prefix: 'fas',\n iconName: 'cubes',\n icon: [512, 512, [], \"f1b3\", \"M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z\"]\n};\nvar faCut = {\n prefix: 'fas',\n iconName: 'cut',\n icon: [448, 512, [], \"f0c4\", \"M278.06 256L444.48 89.57c4.69-4.69 4.69-12.29 0-16.97-32.8-32.8-85.99-32.8-118.79 0L210.18 188.12l-24.86-24.86c4.31-10.92 6.68-22.81 6.68-35.26 0-53.02-42.98-96-96-96S0 74.98 0 128s42.98 96 96 96c4.54 0 8.99-.32 13.36-.93L142.29 256l-32.93 32.93c-4.37-.61-8.83-.93-13.36-.93-53.02 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96c0-12.45-2.37-24.34-6.68-35.26l24.86-24.86L325.69 439.4c32.8 32.8 85.99 32.8 118.79 0 4.69-4.68 4.69-12.28 0-16.97L278.06 256zM96 160c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32zm0 256c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32z\"]\n};\nvar faDatabase = {\n prefix: 'fas',\n iconName: 'database',\n icon: [448, 512, [], \"f1c0\", \"M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z\"]\n};\nvar faDeaf = {\n prefix: 'fas',\n iconName: 'deaf',\n icon: [512, 512, [], \"f2a4\", \"M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z\"]\n};\nvar faDemocrat = {\n prefix: 'fas',\n iconName: 'democrat',\n icon: [640, 512, [], \"f747\", \"M637.3 256.9l-19.6-29.4c-28.2-42.3-75.3-67.5-126.1-67.5H256l-81.2-81.2c20.1-20.1 22.6-51.1 7.5-73.9-3.4-5.2-10.8-5.9-15.2-1.5l-41.8 41.8L82.4 2.4c-3.6-3.6-9.6-3-12.4 1.2-12.3 18.6-10.3 44 6.1 60.4 3.3 3.3 7.3 5.3 11.3 7.5-2.2 1.7-4.7 3.1-6.4 5.4L6.4 176.2c-7.3 9.7-8.4 22.7-3 33.5l14.3 28.6c5.4 10.8 16.5 17.7 28.6 17.7h31c8.5 0 16.6-3.4 22.6-9.4L138 212l54 108h352v-77.8c16.2 12.2 18.3 17.6 40.1 50.3 4.9 7.4 14.8 9.3 22.2 4.4l26.6-17.7c7.3-5 9.3-14.9 4.4-22.3zm-341.1-13.6l-16.5 16.1 3.9 22.7c.7 4.1-3.6 7.2-7.2 5.3L256 276.7l-20.4 10.7c-3.6 1.9-7.9-1.2-7.2-5.3l3.9-22.7-16.5-16.1c-3-2.9-1.3-7.9 2.8-8.5l22.8-3.3 10.2-20.7c1.8-3.7 7.1-3.7 9 0l10.2 20.7 22.8 3.3c4 .6 5.6 5.6 2.6 8.5zm112 0l-16.5 16.1 3.9 22.7c.7 4.1-3.6 7.2-7.2 5.3L368 276.7l-20.4 10.7c-3.6 1.9-7.9-1.2-7.2-5.3l3.9-22.7-16.5-16.1c-3-2.9-1.3-7.9 2.8-8.5l22.8-3.3 10.2-20.7c1.8-3.7 7.1-3.7 9 0l10.2 20.7 22.8 3.3c4 .6 5.6 5.6 2.6 8.5zm112 0l-16.5 16.1 3.9 22.7c.7 4.1-3.6 7.2-7.2 5.3L480 276.7l-20.4 10.7c-3.6 1.9-7.9-1.2-7.2-5.3l3.9-22.7-16.5-16.1c-3-2.9-1.3-7.9 2.8-8.5l22.8-3.3 10.2-20.7c1.8-3.7 7.1-3.7 9 0l10.2 20.7 22.8 3.3c4 .6 5.6 5.6 2.6 8.5zM192 496c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-80h160v80c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V352H192v144z\"]\n};\nvar faDesktop = {\n prefix: 'fas',\n iconName: 'desktop',\n icon: [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"]\n};\nvar faDharmachakra = {\n prefix: 'fas',\n iconName: 'dharmachakra',\n icon: [512, 512, [], \"f655\", \"M495 225.06l-17.22 1.08c-5.27-39.49-20.79-75.64-43.86-105.84l12.95-11.43c6.92-6.11 7.25-16.79.73-23.31L426.44 64.4c-6.53-6.53-17.21-6.19-23.31.73L391.7 78.07c-30.2-23.06-66.35-38.58-105.83-43.86L286.94 17c.58-9.21-6.74-17-15.97-17h-29.94c-9.23 0-16.54 7.79-15.97 17l1.08 17.22c-39.49 5.27-75.64 20.79-105.83 43.86l-11.43-12.95c-6.11-6.92-16.79-7.25-23.31-.73L64.4 85.56c-6.53 6.53-6.19 17.21.73 23.31l12.95 11.43c-23.06 30.2-38.58 66.35-43.86 105.84L17 225.06c-9.21-.58-17 6.74-17 15.97v29.94c0 9.23 7.79 16.54 17 15.97l17.22-1.08c5.27 39.49 20.79 75.64 43.86 105.83l-12.95 11.43c-6.92 6.11-7.25 16.79-.73 23.31l21.17 21.17c6.53 6.53 17.21 6.19 23.31-.73l11.43-12.95c30.2 23.06 66.35 38.58 105.84 43.86L225.06 495c-.58 9.21 6.74 17 15.97 17h29.94c9.23 0 16.54-7.79 15.97-17l-1.08-17.22c39.49-5.27 75.64-20.79 105.84-43.86l11.43 12.95c6.11 6.92 16.79 7.25 23.31.73l21.17-21.17c6.53-6.53 6.19-17.21-.73-23.31l-12.95-11.43c23.06-30.2 38.58-66.35 43.86-105.83l17.22 1.08c9.21.58 17-6.74 17-15.97v-29.94c-.01-9.23-7.8-16.54-17.01-15.97zM281.84 98.61c24.81 4.07 47.63 13.66 67.23 27.78l-42.62 48.29c-8.73-5.44-18.32-9.54-28.62-11.95l4.01-64.12zm-51.68 0l4.01 64.12c-10.29 2.41-19.89 6.52-28.62 11.95l-42.62-48.29c19.6-14.12 42.42-23.71 67.23-27.78zm-103.77 64.33l48.3 42.61c-5.44 8.73-9.54 18.33-11.96 28.62l-64.12-4.01c4.07-24.81 13.66-47.62 27.78-67.22zm-27.78 118.9l64.12-4.01c2.41 10.29 6.52 19.89 11.95 28.62l-48.29 42.62c-14.12-19.6-23.71-42.42-27.78-67.23zm131.55 131.55c-24.81-4.07-47.63-13.66-67.23-27.78l42.61-48.3c8.73 5.44 18.33 9.54 28.62 11.96l-4 64.12zM256 288c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm25.84 125.39l-4.01-64.12c10.29-2.41 19.89-6.52 28.62-11.96l42.61 48.3c-19.6 14.12-42.41 23.71-67.22 27.78zm103.77-64.33l-48.29-42.62c5.44-8.73 9.54-18.32 11.95-28.62l64.12 4.01c-4.07 24.82-13.66 47.64-27.78 67.23zm-36.34-114.89c-2.41-10.29-6.52-19.89-11.96-28.62l48.3-42.61c14.12 19.6 23.71 42.42 27.78 67.23l-64.12 4z\"]\n};\nvar faDiagnoses = {\n prefix: 'fas',\n iconName: 'diagnoses',\n icon: [640, 512, [], \"f470\", \"M496 256c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm-176-80c48.5 0 88-39.5 88-88S368.5 0 320 0s-88 39.5-88 88 39.5 88 88 88zM59.8 364c10.2 15.3 29.3 17.8 42.9 9.8 16.2-9.6 56.2-31.7 105.3-48.6V416h224v-90.7c49.1 16.8 89.1 39 105.3 48.6 13.6 8 32.7 5.3 42.9-9.8l17.8-26.7c8.8-13.2 7.6-34.6-10-45.1-11.9-7.1-29.7-17-51.1-27.4-28.1 46.1-99.4 17.8-87.7-35.1C409.3 217.2 365.1 208 320 208c-57 0-112.9 14.5-160 32.2-.2 40.2-47.6 63.3-79.2 36-11.2 6-21.3 11.6-28.7 16-17.6 10.5-18.8 31.8-10 45.1L59.8 364zM368 344c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-96-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm-160 8c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm512 192H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z\"]\n};\nvar faDice = {\n prefix: 'fas',\n iconName: 'dice',\n icon: [640, 512, [], \"f522\", \"M592 192H473.26c12.69 29.59 7.12 65.2-17 89.32L320 417.58V464c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48V240c0-26.51-21.49-48-48-48zM480 376c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm-46.37-186.7L258.7 14.37c-19.16-19.16-50.23-19.16-69.39 0L14.37 189.3c-19.16 19.16-19.16 50.23 0 69.39L189.3 433.63c19.16 19.16 50.23 19.16 69.39 0L433.63 258.7c19.16-19.17 19.16-50.24 0-69.4zM96 248c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm128 128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm0-128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm0-128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm128 128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"]\n};\nvar faDiceD20 = {\n prefix: 'fas',\n iconName: 'dice-d20',\n icon: [480, 512, [], \"f6cf\", \"M106.75 215.06L1.2 370.95c-3.08 5 .1 11.5 5.93 12.14l208.26 22.07-108.64-190.1zM7.41 315.43L82.7 193.08 6.06 147.1c-2.67-1.6-6.06.32-6.06 3.43v162.81c0 4.03 5.29 5.53 7.41 2.09zM18.25 423.6l194.4 87.66c5.3 2.45 11.35-1.43 11.35-7.26v-65.67l-203.55-22.3c-4.45-.5-6.23 5.59-2.2 7.57zm81.22-257.78L179.4 22.88c4.34-7.06-3.59-15.25-10.78-11.14L17.81 110.35c-2.47 1.62-2.39 5.26.13 6.78l81.53 48.69zM240 176h109.21L253.63 7.62C250.5 2.54 245.25 0 240 0s-10.5 2.54-13.63 7.62L130.79 176H240zm233.94-28.9l-76.64 45.99 75.29 122.35c2.11 3.44 7.41 1.94 7.41-2.1V150.53c0-3.11-3.39-5.03-6.06-3.43zm-93.41 18.72l81.53-48.7c2.53-1.52 2.6-5.16.13-6.78l-150.81-98.6c-7.19-4.11-15.12 4.08-10.78 11.14l79.93 142.94zm79.02 250.21L256 438.32v65.67c0 5.84 6.05 9.71 11.35 7.26l194.4-87.66c4.03-1.97 2.25-8.06-2.2-7.56zm-86.3-200.97l-108.63 190.1 208.26-22.07c5.83-.65 9.01-7.14 5.93-12.14L373.25 215.06zM240 208H139.57L240 383.75 340.43 208H240z\"]\n};\nvar faDiceD6 = {\n prefix: 'fas',\n iconName: 'dice-d6',\n icon: [448, 512, [], \"f6d1\", \"M422.19 109.95L256.21 9.07c-19.91-12.1-44.52-12.1-64.43 0L25.81 109.95c-5.32 3.23-5.29 11.27.06 14.46L224 242.55l198.14-118.14c5.35-3.19 5.38-11.22.05-14.46zm13.84 44.63L240 271.46v223.82c0 12.88 13.39 20.91 24.05 14.43l152.16-92.48c19.68-11.96 31.79-33.94 31.79-57.7v-197.7c0-6.41-6.64-10.43-11.97-7.25zM0 161.83v197.7c0 23.77 12.11 45.74 31.79 57.7l152.16 92.47c10.67 6.48 24.05-1.54 24.05-14.43V271.46L11.97 154.58C6.64 151.4 0 155.42 0 161.83z\"]\n};\nvar faDiceFive = {\n prefix: 'fas',\n iconName: 'dice-five',\n icon: [448, 512, [], \"f523\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM128 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm96 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm96 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDiceFour = {\n prefix: 'fas',\n iconName: 'dice-four',\n icon: [448, 512, [], \"f524\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM128 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm192 192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDiceOne = {\n prefix: 'fas',\n iconName: 'dice-one',\n icon: [448, 512, [], \"f525\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM224 288c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDiceSix = {\n prefix: 'fas',\n iconName: 'dice-six',\n icon: [448, 512, [], \"f526\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM128 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm192 192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDiceThree = {\n prefix: 'fas',\n iconName: 'dice-three',\n icon: [448, 512, [], \"f527\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM128 192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm96 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm96 96c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDiceTwo = {\n prefix: 'fas',\n iconName: 'dice-two',\n icon: [448, 512, [], \"f528\", \"M384 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h320c35.35 0 64-28.65 64-64V96c0-35.35-28.65-64-64-64zM128 192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm192 192c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faDigitalTachograph = {\n prefix: 'fas',\n iconName: 'digital-tachograph',\n icon: [640, 512, [], \"f566\", \"M608 96H32c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V128c0-17.67-14.33-32-32-32zM304 352c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-8c0-4.42 3.58-8 8-8h224c4.42 0 8 3.58 8 8v8zM72 288v-16c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H80c-4.42 0-8-3.58-8-8zm64 0v-16c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8zm64 0v-16c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8zm64 0v-16c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8zm40-64c0 8.84-7.16 16-16 16H80c-8.84 0-16-7.16-16-16v-48c0-8.84 7.16-16 16-16h208c8.84 0 16 7.16 16 16v48zm272 128c0 4.42-3.58 8-8 8H344c-4.42 0-8-3.58-8-8v-8c0-4.42 3.58-8 8-8h224c4.42 0 8 3.58 8 8v8z\"]\n};\nvar faDirections = {\n prefix: 'fas',\n iconName: 'directions',\n icon: [512, 512, [], \"f5eb\", \"M502.61 233.32L278.68 9.39c-12.52-12.52-32.83-12.52-45.36 0L9.39 233.32c-12.52 12.53-12.52 32.83 0 45.36l223.93 223.93c12.52 12.53 32.83 12.53 45.36 0l223.93-223.93c12.52-12.53 12.52-32.83 0-45.36zm-100.98 12.56l-84.21 77.73c-5.12 4.73-13.43 1.1-13.43-5.88V264h-96v64c0 4.42-3.58 8-8 8h-32c-4.42 0-8-3.58-8-8v-80c0-17.67 14.33-32 32-32h112v-53.73c0-6.97 8.3-10.61 13.43-5.88l84.21 77.73c3.43 3.17 3.43 8.59 0 11.76z\"]\n};\nvar faDivide = {\n prefix: 'fas',\n iconName: 'divide',\n icon: [448, 512, [], \"f529\", \"M224 352c-35.35 0-64 28.65-64 64s28.65 64 64 64 64-28.65 64-64-28.65-64-64-64zm0-192c35.35 0 64-28.65 64-64s-28.65-64-64-64-64 28.65-64 64 28.65 64 64 64zm192 48H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n};\nvar faDizzy = {\n prefix: 'fas',\n iconName: 'dizzy',\n icon: [496, 512, [], \"f567\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-96 206.6l-28.7 28.7c-14.8 14.8-37.8-7.5-22.6-22.6l28.7-28.7-28.7-28.7c-15-15 7.7-37.6 22.6-22.6l28.7 28.7 28.7-28.7c15-15 37.6 7.7 22.6 22.6L174.6 192l28.7 28.7c15.2 15.2-7.9 37.4-22.6 22.6L152 214.6zM248 416c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm147.3-195.3c15.2 15.2-7.9 37.4-22.6 22.6L344 214.6l-28.7 28.7c-14.8 14.8-37.8-7.5-22.6-22.6l28.7-28.7-28.7-28.7c-15-15 7.7-37.6 22.6-22.6l28.7 28.7 28.7-28.7c15-15 37.6 7.7 22.6 22.6L366.6 192l28.7 28.7z\"]\n};\nvar faDna = {\n prefix: 'fas',\n iconName: 'dna',\n icon: [448, 512, [], \"f471\", \"M.1 494.1c-1.1 9.5 6.3 17.8 15.9 17.8l32.3.1c8.1 0 14.9-5.9 16-13.9.7-4.9 1.8-11.1 3.4-18.1H380c1.6 6.9 2.9 13.2 3.5 18.1 1.1 8 7.9 14 16 13.9l32.3-.1c9.6 0 17.1-8.3 15.9-17.8-4.6-37.9-25.6-129-118.9-207.7-17.6 12.4-37.1 24.2-58.5 35.4 6.2 4.6 11.4 9.4 17 14.2H159.7c21.3-18.1 47-35.6 78.7-51.4C410.5 199.1 442.1 65.8 447.9 17.9 449 8.4 441.6.1 432 .1L399.6 0c-8.1 0-14.9 5.9-16 13.9-.7 4.9-1.8 11.1-3.4 18.1H67.8c-1.6-7-2.7-13.1-3.4-18.1-1.1-8-7.9-14-16-13.9L16.1.1C6.5.1-1 8.4.1 17.9 5.3 60.8 31.4 171.8 160 256 31.5 340.2 5.3 451.2.1 494.1zM224 219.6c-25.1-13.7-46.4-28.4-64.3-43.6h128.5c-17.8 15.2-39.1 30-64.2 43.6zM355.1 96c-5.8 10.4-12.8 21.1-21 32H114c-8.3-10.9-15.3-21.6-21-32h262.1zM92.9 416c5.8-10.4 12.8-21.1 21-32h219.4c8.3 10.9 15.4 21.6 21.2 32H92.9z\"]\n};\nvar faDog = {\n prefix: 'fas',\n iconName: 'dog',\n icon: [512, 512, [], \"f6d3\", \"M496 96h-64l-7.16-14.31A32 32 0 0 0 396.22 64H342.6l-27.28-27.28C305.23 26.64 288 33.78 288 48.03v149.84l128 45.71V208h32c35.35 0 64-28.65 64-64v-32c0-8.84-7.16-16-16-16zm-112 48c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zM96 224c-17.64 0-32-14.36-32-32 0-17.67-14.33-32-32-32S0 174.33 0 192c0 41.66 26.83 76.85 64 90.1V496c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V384h160v112c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V277.55L266.05 224H96z\"]\n};\nvar faDollarSign = {\n prefix: 'fas',\n iconName: 'dollar-sign',\n icon: [288, 512, [], \"f155\", \"M209.2 233.4l-108-31.6C88.7 198.2 80 186.5 80 173.5c0-16.3 13.2-29.5 29.5-29.5h66.3c12.2 0 24.2 3.7 34.2 10.5 6.1 4.1 14.3 3.1 19.5-2l34.8-34c7.1-6.9 6.1-18.4-1.8-24.5C238 74.8 207.4 64.1 176 64V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48h-2.5C45.8 64-5.4 118.7.5 183.6c4.2 46.1 39.4 83.6 83.8 96.6l102.5 30c12.5 3.7 21.2 15.3 21.2 28.3 0 16.3-13.2 29.5-29.5 29.5h-66.3C100 368 88 364.3 78 357.5c-6.1-4.1-14.3-3.1-19.5 2l-34.8 34c-7.1 6.9-6.1 18.4 1.8 24.5 24.5 19.2 55.1 29.9 86.5 30v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-48.2c46.6-.9 90.3-28.6 105.7-72.7 21.5-61.6-14.6-124.8-72.5-141.7z\"]\n};\nvar faDolly = {\n prefix: 'fas',\n iconName: 'dolly',\n icon: [576, 512, [], \"f472\", \"M294.2 277.7c18 5 34.7 13.4 49.5 24.7l161.5-53.8c8.4-2.8 12.9-11.9 10.1-20.2L454.9 47.2c-2.8-8.4-11.9-12.9-20.2-10.1l-61.1 20.4 33.1 99.4L346 177l-33.1-99.4-61.6 20.5c-8.4 2.8-12.9 11.9-10.1 20.2l53 159.4zm281 48.7L565 296c-2.8-8.4-11.9-12.9-20.2-10.1l-213.5 71.2c-17.2-22-43.6-36.4-73.5-37L158.4 21.9C154 8.8 141.8 0 128 0H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h88.9l92.2 276.7c-26.1 20.4-41.7 53.6-36 90.5 6.1 39.4 37.9 72.3 77.3 79.2 60.2 10.7 112.3-34.8 113.4-92.6l213.3-71.2c8.3-2.8 12.9-11.8 10.1-20.2zM256 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z\"]\n};\nvar faDollyFlatbed = {\n prefix: 'fas',\n iconName: 'dolly-flatbed',\n icon: [640, 512, [], \"f474\", \"M208 320h384c8.8 0 16-7.2 16-16V48c0-8.8-7.2-16-16-16H448v128l-48-32-48 32V32H208c-8.8 0-16 7.2-16 16v256c0 8.8 7.2 16 16 16zm416 64H128V16c0-8.8-7.2-16-16-16H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h48v368c0 8.8 7.2 16 16 16h82.9c-1.8 5-2.9 10.4-2.9 16 0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1.2-11-2.9-16H451c-1.8 5-2.9 10.4-2.9 16 0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1.2-11-2.9-16H624c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z\"]\n};\nvar faDonate = {\n prefix: 'fas',\n iconName: 'donate',\n icon: [512, 512, [], \"f4b9\", \"M256 416c114.9 0 208-93.1 208-208S370.9 0 256 0 48 93.1 48 208s93.1 208 208 208zM233.8 97.4V80.6c0-9.2 7.4-16.6 16.6-16.6h11.1c9.2 0 16.6 7.4 16.6 16.6v17c15.5.8 30.5 6.1 43 15.4 5.6 4.1 6.2 12.3 1.2 17.1L306 145.6c-3.8 3.7-9.5 3.8-14 1-5.4-3.4-11.4-5.1-17.8-5.1h-38.9c-9 0-16.3 8.2-16.3 18.3 0 8.2 5 15.5 12.1 17.6l62.3 18.7c25.7 7.7 43.7 32.4 43.7 60.1 0 34-26.4 61.5-59.1 62.4v16.8c0 9.2-7.4 16.6-16.6 16.6h-11.1c-9.2 0-16.6-7.4-16.6-16.6v-17c-15.5-.8-30.5-6.1-43-15.4-5.6-4.1-6.2-12.3-1.2-17.1l16.3-15.5c3.8-3.7 9.5-3.8 14-1 5.4 3.4 11.4 5.1 17.8 5.1h38.9c9 0 16.3-8.2 16.3-18.3 0-8.2-5-15.5-12.1-17.6l-62.3-18.7c-25.7-7.7-43.7-32.4-43.7-60.1.1-34 26.4-61.5 59.1-62.4zM480 352h-32.5c-19.6 26-44.6 47.7-73 64h63.8c5.3 0 9.6 3.6 9.6 8v16c0 4.4-4.3 8-9.6 8H73.6c-5.3 0-9.6-3.6-9.6-8v-16c0-4.4 4.3-8 9.6-8h63.8c-28.4-16.3-53.3-38-73-64H32c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32v-96c0-17.7-14.3-32-32-32z\"]\n};\nvar faDoorClosed = {\n prefix: 'fas',\n iconName: 'door-closed',\n icon: [640, 512, [], \"f52a\", \"M624 448H512V50.8C512 22.78 490.47 0 464 0H175.99c-26.47 0-48 22.78-48 50.8V448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h608c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM415.99 288c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32c.01 17.67-14.32 32-32 32z\"]\n};\nvar faDoorOpen = {\n prefix: 'fas',\n iconName: 'door-open',\n icon: [640, 512, [], \"f52b\", \"M624 448h-80V113.45C544 86.19 522.47 64 496 64H384v64h96v384h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM312.24 1.01l-192 49.74C105.99 54.44 96 67.7 96 82.92V448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h336V33.18c0-21.58-19.56-37.41-39.76-32.17zM264 288c-13.25 0-24-14.33-24-32s10.75-32 24-32 24 14.33 24 32-10.75 32-24 32z\"]\n};\nvar faDotCircle = {\n prefix: 'fas',\n iconName: 'dot-circle',\n icon: [512, 512, [], \"f192\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z\"]\n};\nvar faDove = {\n prefix: 'fas',\n iconName: 'dove',\n icon: [512, 512, [], \"f4ba\", \"M288 167.2v-28.1c-28.2-36.3-47.1-79.3-54.1-125.2-2.1-13.5-19-18.8-27.8-8.3-21.1 24.9-37.7 54.1-48.9 86.5 34.2 38.3 80 64.6 130.8 75.1zM400 64c-44.2 0-80 35.9-80 80.1v59.4C215.6 197.3 127 133 87 41.8c-5.5-12.5-23.2-13.2-29-.9C41.4 76 32 115.2 32 156.6c0 70.8 34.1 136.9 85.1 185.9 13.2 12.7 26.1 23.2 38.9 32.8l-143.9 36C1.4 414-3.4 426.4 2.6 435.7 20 462.6 63 508.2 155.8 512c8 .3 16-2.6 22.1-7.9l65.2-56.1H320c88.4 0 160-71.5 160-159.9V128l32-64H400zm0 96.1c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z\"]\n};\nvar faDownload = {\n prefix: 'fas',\n iconName: 'download',\n icon: [512, 512, [], \"f019\", \"M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z\"]\n};\nvar faDraftingCompass = {\n prefix: 'fas',\n iconName: 'drafting-compass',\n icon: [512, 512, [], \"f568\", \"M457.01 344.42c-25.05 20.33-52.63 37.18-82.54 49.05l54.38 94.19 53.95 23.04c9.81 4.19 20.89-2.21 22.17-12.8l7.02-58.25-54.98-95.23zm42.49-94.56c4.86-7.67 1.89-17.99-6.05-22.39l-28.07-15.57c-7.48-4.15-16.61-1.46-21.26 5.72C403.01 281.15 332.25 320 256 320c-23.93 0-47.23-4.25-69.41-11.53l67.36-116.68c.7.02 1.34.21 2.04.21s1.35-.19 2.04-.21l51.09 88.5c31.23-8.96 59.56-25.75 82.61-48.92l-51.79-89.71C347.39 128.03 352 112.63 352 96c0-53.02-42.98-96-96-96s-96 42.98-96 96c0 16.63 4.61 32.03 12.05 45.66l-68.3 118.31c-12.55-11.61-23.96-24.59-33.68-39-4.79-7.1-13.97-9.62-21.38-5.33l-27.75 16.07c-7.85 4.54-10.63 14.9-5.64 22.47 15.57 23.64 34.69 44.21 55.98 62.02L0 439.66l7.02 58.25c1.28 10.59 12.36 16.99 22.17 12.8l53.95-23.04 70.8-122.63C186.13 377.28 220.62 384 256 384c99.05 0 190.88-51.01 243.5-134.14zM256 64c17.67 0 32 14.33 32 32s-14.33 32-32 32-32-14.33-32-32 14.33-32 32-32z\"]\n};\nvar faDragon = {\n prefix: 'fas',\n iconName: 'dragon',\n icon: [640, 512, [], \"f6d5\", \"M18.32 255.78L192 223.96l-91.28 68.69c-10.08 10.08-2.94 27.31 11.31 27.31h222.7c-9.44-26.4-14.73-54.47-14.73-83.38v-42.27l-119.73-87.6c-23.82-15.88-55.29-14.01-77.06 4.59L5.81 227.64c-12.38 10.33-3.45 30.42 12.51 28.14zm556.87 34.1l-100.66-50.31A47.992 47.992 0 0 1 448 196.65v-36.69h64l28.09 22.63c6 6 14.14 9.37 22.63 9.37h30.97a32 32 0 0 0 28.62-17.69l14.31-28.62a32.005 32.005 0 0 0-3.02-33.51l-74.53-99.38C553.02 4.7 543.54 0 533.47 0H296.02c-7.13 0-10.7 8.57-5.66 13.61L352 63.96 292.42 88.8c-5.9 2.95-5.9 11.36 0 14.31L352 127.96v108.62c0 72.08 36.03 139.39 96 179.38-195.59 6.81-344.56 41.01-434.1 60.91C5.78 478.67 0 485.88 0 494.2 0 504 7.95 512 17.76 512h499.08c63.29.01 119.61-47.56 122.99-110.76 2.52-47.28-22.73-90.4-64.64-111.36zM489.18 66.25l45.65 11.41c-2.75 10.91-12.47 18.89-24.13 18.26-12.96-.71-25.85-12.53-21.52-29.67z\"]\n};\nvar faDrawPolygon = {\n prefix: 'fas',\n iconName: 'draw-polygon',\n icon: [448, 512, [], \"f5ee\", \"M384 352c-.35 0-.67.1-1.02.1l-39.2-65.32c5.07-9.17 8.22-19.56 8.22-30.78s-3.14-21.61-8.22-30.78l39.2-65.32c.35.01.67.1 1.02.1 35.35 0 64-28.65 64-64s-28.65-64-64-64c-23.63 0-44.04 12.95-55.12 32H119.12C108.04 44.95 87.63 32 64 32 28.65 32 0 60.65 0 96c0 23.63 12.95 44.04 32 55.12v209.75C12.95 371.96 0 392.37 0 416c0 35.35 28.65 64 64 64 23.63 0 44.04-12.95 55.12-32h209.75c11.09 19.05 31.49 32 55.12 32 35.35 0 64-28.65 64-64 .01-35.35-28.64-64-63.99-64zm-288 8.88V151.12A63.825 63.825 0 0 0 119.12 128h208.36l-38.46 64.1c-.35-.01-.67-.1-1.02-.1-35.35 0-64 28.65-64 64s28.65 64 64 64c.35 0 .67-.1 1.02-.1l38.46 64.1H119.12A63.748 63.748 0 0 0 96 360.88zM272 256c0-8.82 7.18-16 16-16s16 7.18 16 16-7.18 16-16 16-16-7.18-16-16zM400 96c0 8.82-7.18 16-16 16s-16-7.18-16-16 7.18-16 16-16 16 7.18 16 16zM64 80c8.82 0 16 7.18 16 16s-7.18 16-16 16-16-7.18-16-16 7.18-16 16-16zM48 416c0-8.82 7.18-16 16-16s16 7.18 16 16-7.18 16-16 16-16-7.18-16-16zm336 16c-8.82 0-16-7.18-16-16s7.18-16 16-16 16 7.18 16 16-7.18 16-16 16z\"]\n};\nvar faDrum = {\n prefix: 'fas',\n iconName: 'drum',\n icon: [576, 512, [], \"f569\", \"M458.08 120.88l102.39-61.43c15.16-9.09 20.06-28.75 10.97-43.91C562.34.39 542.7-4.53 527.53 4.57l-160.69 96.41A629.32 629.32 0 0 0 288 96C128.94 96 0 153.31 0 224v160.83c0 30.46 24.03 58.4 64 80.37v-96.37c0-17.6 14.4-32 32-32s32 14.4 32 32v122.41c37.4 11.13 81 18.44 128 20.75V400.84c0-17.6 14.4-32 32-32s32 14.4 32 32V512c47-2.31 90.6-9.62 128-20.75V368.84c0-17.6 14.4-32 32-32s32 14.4 32 32v96.37c39.97-21.97 64-49.91 64-80.37V224.01c-.01-42.38-46.54-79.84-117.92-103.13zM288 304c-132.55 0-240-35.82-240-80s107.45-80 240-80c2.34 0 4.62.1 6.94.12l-87.41 52.44c-15.16 9.09-20.06 28.75-10.97 43.91 9.56 15.93 29.51 19.61 43.91 10.97l162.71-97.62C477.55 167.41 528 193.74 528 224.01 528 268.19 420.54 304 288 304z\"]\n};\nvar faDrumSteelpan = {\n prefix: 'fas',\n iconName: 'drum-steelpan',\n icon: [576, 512, [], \"f56a\", \"M288 32C128.94 32 0 89.31 0 160v192c0 70.69 128.94 128 288 128s288-57.31 288-128V160c0-70.69-128.94-128-288-128zm-82.99 158.36c-4.45 16.61-14.54 30.57-28.31 40.48C100.23 217.46 48 190.78 48 160c0-30.16 50.11-56.39 124.04-70.03l25.6 44.34c9.86 17.09 12.48 36.99 7.37 56.05zM288 240c-21.08 0-41.41-1-60.89-2.7 8.06-26.13 32.15-45.3 60.89-45.3s52.83 19.17 60.89 45.3C329.41 239 309.08 240 288 240zm64-144c0 35.29-28.71 64-64 64s-64-28.71-64-64V82.96c20.4-1.88 41.8-2.96 64-2.96s43.6 1.08 64 2.96V96zm46.93 134.9c-13.81-9.91-23.94-23.9-28.4-40.54-5.11-19.06-2.49-38.96 7.38-56.04l25.65-44.42C477.72 103.5 528 129.79 528 160c0 30.83-52.4 57.54-129.07 70.9z\"]\n};\nvar faDrumstickBite = {\n prefix: 'fas',\n iconName: 'drumstick-bite',\n icon: [512, 512, [], \"f6d7\", \"M462.8 49.57a169.44 169.44 0 0 0-239.5 0C187.82 85 160.13 128 160.13 192v85.83l-40.62 40.59c-9.7 9.69-24 11.07-36.78 6a60.33 60.33 0 0 0-65 98.72C33 438.39 54.24 442.7 73.85 438.21c-4.5 19.6-.18 40.83 15.1 56.1a60.35 60.35 0 0 0 98.8-65c-5.09-12.73-3.72-27 6-36.75L234.36 352h85.89a187.87 187.87 0 0 0 61.89-10c-39.64-43.89-39.83-110.23 1.05-151.07 34.38-34.36 86.76-39.46 128.74-16.8 1.3-44.96-14.81-90.28-49.13-124.56z\"]\n};\nvar faDumbbell = {\n prefix: 'fas',\n iconName: 'dumbbell',\n icon: [640, 512, [], \"f44b\", \"M104 96H56c-13.3 0-24 10.7-24 24v104H8c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h24v104c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm528 128h-24V120c0-13.3-10.7-24-24-24h-48c-13.3 0-24 10.7-24 24v272c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V288h24c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM456 32h-48c-13.3 0-24 10.7-24 24v168H256V56c0-13.3-10.7-24-24-24h-48c-13.3 0-24 10.7-24 24v400c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V288h128v168c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24z\"]\n};\nvar faDumpster = {\n prefix: 'fas',\n iconName: 'dumpster',\n icon: [576, 512, [], \"f793\", \"M560 160c10.4 0 18-9.8 15.5-19.9l-24-96C549.7 37 543.3 32 536 32h-98.9l25.6 128H560zM272 32H171.5l-25.6 128H272V32zm132.5 0H304v128h126.1L404.5 32zM16 160h97.3l25.6-128H40c-7.3 0-13.7 5-15.5 12.1l-24 96C-2 150.2 5.6 160 16 160zm544 64h-20l4-32H32l4 32H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h28l20 160v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h320v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16l20-160h28c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z\"]\n};\nvar faDumpsterFire = {\n prefix: 'fas',\n iconName: 'dumpster-fire',\n icon: [640, 512, [], \"f794\", \"M418.7 104.1l.2-.2-14.4-72H304v128h60.8c16.2-19.3 34.2-38.2 53.9-55.8zM272 32H171.5l-25.6 128H272V32zm189.3 72.1c18.2 16.3 35.5 33.7 51.1 51.5 5.7-5.6 11.4-11.1 17.3-16.3l21.3-19 21.3 19c1.1.9 2.1 2.1 3.1 3.1-.1-.8.2-1.5 0-2.3l-24-96C549.7 37 543.3 32 536 32h-98.9l12.3 61.5 11.9 10.6zM16 160h97.3l25.6-128H40c-7.3 0-13.7 5-15.5 12.1l-24 96C-2 150.2 5.6 160 16 160zm324.6 32H32l4 32H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h28l20 160v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h208.8c-30.2-33.7-48.8-77.9-48.8-126.4 0-35.9 19.9-82.9 52.6-129.6zm210.5-28.8c-14.9 13.3-28.3 27.2-40.2 41.2-19.5-25.8-43.6-52-71-76.4-70.2 62.7-120 144.3-120 193.6 0 87.5 71.6 158.4 160 158.4s160-70.9 160-158.4c.1-36.6-37-112.2-88.8-158.4zm-18.6 229.4c-14.7 10.7-32.9 17-52.5 17-49 0-88.9-33.5-88.9-88 0-27.1 16.5-51 49.4-91.9 4.7 5.6 67.1 88.1 67.1 88.1l39.8-47c2.8 4.8 5.4 9.5 7.7 14 18.6 36.7 10.8 83.6-22.6 107.8z\"]\n};\nvar faDungeon = {\n prefix: 'fas',\n iconName: 'dungeon',\n icon: [512, 512, [], \"f6d9\", \"M128.73 195.32l-82.81-51.76c-8.04-5.02-18.99-2.17-22.93 6.45A254.19 254.19 0 0 0 .54 239.28C-.05 248.37 7.59 256 16.69 256h97.13c7.96 0 14.08-6.25 15.01-14.16 1.09-9.33 3.24-18.33 6.24-26.94 2.56-7.34.25-15.46-6.34-19.58zM319.03 8C298.86 2.82 277.77 0 256 0s-42.86 2.82-63.03 8c-9.17 2.35-13.91 12.6-10.39 21.39l37.47 104.03A16.003 16.003 0 0 0 235.1 144h41.8c6.75 0 12.77-4.23 15.05-10.58l37.47-104.03c3.52-8.79-1.22-19.03-10.39-21.39zM112 288H16c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h96c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16zm0 128H16c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h96c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16zm77.31-283.67l-36.32-90.8c-3.53-8.83-14.13-12.99-22.42-8.31a257.308 257.308 0 0 0-71.61 59.89c-6.06 7.32-3.85 18.48 4.22 23.52l82.93 51.83c6.51 4.07 14.66 2.62 20.11-2.79 5.18-5.15 10.79-9.85 16.79-14.05 6.28-4.41 9.15-12.17 6.3-19.29zM398.18 256h97.13c9.1 0 16.74-7.63 16.15-16.72a254.135 254.135 0 0 0-22.45-89.27c-3.94-8.62-14.89-11.47-22.93-6.45l-82.81 51.76c-6.59 4.12-8.9 12.24-6.34 19.58 3.01 8.61 5.15 17.62 6.24 26.94.93 7.91 7.05 14.16 15.01 14.16zm54.85-162.89a257.308 257.308 0 0 0-71.61-59.89c-8.28-4.68-18.88-.52-22.42 8.31l-36.32 90.8c-2.85 7.12.02 14.88 6.3 19.28 6 4.2 11.61 8.9 16.79 14.05 5.44 5.41 13.6 6.86 20.11 2.79l82.93-51.83c8.07-5.03 10.29-16.19 4.22-23.51zM496 288h-96c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h96c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16zm0 128h-96c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h96c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16zM240 177.62V472c0 4.42 3.58 8 8 8h16c4.42 0 8-3.58 8-8V177.62c-5.23-.89-10.52-1.62-16-1.62s-10.77.73-16 1.62zm-64 41.51V472c0 4.42 3.58 8 8 8h16c4.42 0 8-3.58 8-8V189.36c-12.78 7.45-23.84 17.47-32 29.77zm128-29.77V472c0 4.42 3.58 8 8 8h16c4.42 0 8-3.58 8-8V219.13c-8.16-12.3-19.22-22.32-32-29.77z\"]\n};\nvar faEdit = {\n prefix: 'fas',\n iconName: 'edit',\n icon: [576, 512, [], \"f044\", \"M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z\"]\n};\nvar faEgg = {\n prefix: 'fas',\n iconName: 'egg',\n icon: [384, 512, [], \"f7fb\", \"M192 0C86 0 0 214 0 320s86 192 192 192 192-86 192-192S298 0 192 0z\"]\n};\nvar faEject = {\n prefix: 'fas',\n iconName: 'eject',\n icon: [448, 512, [], \"f052\", \"M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z\"]\n};\nvar faEllipsisH = {\n prefix: 'fas',\n iconName: 'ellipsis-h',\n icon: [512, 512, [], \"f141\", \"M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z\"]\n};\nvar faEllipsisV = {\n prefix: 'fas',\n iconName: 'ellipsis-v',\n icon: [192, 512, [], \"f142\", \"M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z\"]\n};\nvar faEnvelope = {\n prefix: 'fas',\n iconName: 'envelope',\n icon: [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"]\n};\nvar faEnvelopeOpen = {\n prefix: 'fas',\n iconName: 'envelope-open',\n icon: [512, 512, [], \"f2b6\", \"M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z\"]\n};\nvar faEnvelopeOpenText = {\n prefix: 'fas',\n iconName: 'envelope-open-text',\n icon: [512, 512, [], \"f658\", \"M176 216h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16H176c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16zm-16 80c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16H176c-8.84 0-16 7.16-16 16v16zm96 121.13c-16.42 0-32.84-5.06-46.86-15.19L0 250.86V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V250.86L302.86 401.94c-14.02 10.12-30.44 15.19-46.86 15.19zm237.61-254.18c-8.85-6.94-17.24-13.47-29.61-22.81V96c0-26.51-21.49-48-48-48h-77.55c-3.04-2.2-5.87-4.26-9.04-6.56C312.6 29.17 279.2-.35 256 0c-23.2-.35-56.59 29.17-73.41 41.44-3.17 2.3-6 4.36-9.04 6.56H96c-26.51 0-48 21.49-48 48v44.14c-12.37 9.33-20.76 15.87-29.61 22.81A47.995 47.995 0 0 0 0 200.72v10.65l96 69.35V96h320v184.72l96-69.35v-10.65c0-14.74-6.78-28.67-18.39-37.77z\"]\n};\nvar faEnvelopeSquare = {\n prefix: 'fas',\n iconName: 'envelope-square',\n icon: [448, 512, [], \"f199\", \"M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z\"]\n};\nvar faEquals = {\n prefix: 'fas',\n iconName: 'equals',\n icon: [448, 512, [], \"f52c\", \"M416 304H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32zm0-192H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n};\nvar faEraser = {\n prefix: 'fas',\n iconName: 'eraser',\n icon: [512, 512, [], \"f12d\", \"M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z\"]\n};\nvar faEthernet = {\n prefix: 'fas',\n iconName: 'ethernet',\n icon: [512, 512, [], \"f796\", \"M496 192h-48v-48c0-8.8-7.2-16-16-16h-48V80c0-8.8-7.2-16-16-16H144c-8.8 0-16 7.2-16 16v48H80c-8.8 0-16 7.2-16 16v48H16c-8.8 0-16 7.2-16 16v224c0 8.8 7.2 16 16 16h80V320h32v128h64V320h32v128h64V320h32v128h64V320h32v128h80c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16z\"]\n};\nvar faEuroSign = {\n prefix: 'fas',\n iconName: 'euro-sign',\n icon: [320, 512, [], \"f153\", \"M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z\"]\n};\nvar faExchangeAlt = {\n prefix: 'fas',\n iconName: 'exchange-alt',\n icon: [512, 512, [], \"f362\", \"M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z\"]\n};\nvar faExclamation = {\n prefix: 'fas',\n iconName: 'exclamation',\n icon: [192, 512, [], \"f12a\", \"M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z\"]\n};\nvar faExclamationCircle = {\n prefix: 'fas',\n iconName: 'exclamation-circle',\n icon: [512, 512, [], \"f06a\", \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"]\n};\nvar faExclamationTriangle = {\n prefix: 'fas',\n iconName: 'exclamation-triangle',\n icon: [576, 512, [], \"f071\", \"M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"]\n};\nvar faExpand = {\n prefix: 'fas',\n iconName: 'expand',\n icon: [448, 512, [], \"f065\", \"M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z\"]\n};\nvar faExpandArrowsAlt = {\n prefix: 'fas',\n iconName: 'expand-arrows-alt',\n icon: [448, 512, [], \"f31e\", \"M448 344v112a23.94 23.94 0 0 1-24 24H312c-21.39 0-32.09-25.9-17-41l36.2-36.2L224 295.6 116.77 402.9 153 439c15.09 15.1 4.39 41-17 41H24a23.94 23.94 0 0 1-24-24V344c0-21.4 25.89-32.1 41-17l36.19 36.2L184.46 256 77.18 148.7 41 185c-15.1 15.1-41 4.4-41-17V56a23.94 23.94 0 0 1 24-24h112c21.39 0 32.09 25.9 17 41l-36.2 36.2L224 216.4l107.23-107.3L295 73c-15.09-15.1-4.39-41 17-41h112a23.94 23.94 0 0 1 24 24v112c0 21.4-25.89 32.1-41 17l-36.19-36.2L263.54 256l107.28 107.3L407 327.1c15.1-15.2 41-4.5 41 16.9z\"]\n};\nvar faExternalLinkAlt = {\n prefix: 'fas',\n iconName: 'external-link-alt',\n icon: [576, 512, [], \"f35d\", \"M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z\"]\n};\nvar faExternalLinkSquareAlt = {\n prefix: 'fas',\n iconName: 'external-link-square-alt',\n icon: [448, 512, [], \"f360\", \"M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z\"]\n};\nvar faEye = {\n prefix: 'fas',\n iconName: 'eye',\n icon: [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"]\n};\nvar faEyeDropper = {\n prefix: 'fas',\n iconName: 'eye-dropper',\n icon: [512, 512, [], \"f1fb\", \"M50.75 333.25c-12 12-18.75 28.28-18.75 45.26V424L0 480l32 32 56-32h45.49c16.97 0 33.25-6.74 45.25-18.74l126.64-126.62-128-128L50.75 333.25zM483.88 28.12c-37.47-37.5-98.28-37.5-135.75 0l-77.09 77.09-13.1-13.1c-9.44-9.44-24.65-9.31-33.94 0l-40.97 40.97c-9.37 9.37-9.37 24.57 0 33.94l161.94 161.94c9.44 9.44 24.65 9.31 33.94 0L419.88 288c9.37-9.37 9.37-24.57 0-33.94l-13.1-13.1 77.09-77.09c37.51-37.48 37.51-98.26.01-135.75z\"]\n};\nvar faEyeSlash = {\n prefix: 'fas',\n iconName: 'eye-slash',\n icon: [640, 512, [], \"f070\", \"M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z\"]\n};\nvar faFan = {\n prefix: 'fas',\n iconName: 'fan',\n icon: [512, 512, [], \"f863\", \"M352.57 128c-28.09 0-54.09 4.52-77.06 12.86l12.41-123.11C289 7.31 279.81-1.18 269.33.13 189.63 10.13 128 77.64 128 159.43c0 28.09 4.52 54.09 12.86 77.06L17.75 224.08C7.31 223-1.18 232.19.13 242.67c10 79.7 77.51 141.33 159.3 141.33 28.09 0 54.09-4.52 77.06-12.86l-12.41 123.11c-1.05 10.43 8.11 18.93 18.59 17.62 79.7-10 141.33-77.51 141.33-159.3 0-28.09-4.52-54.09-12.86-77.06l123.11 12.41c10.44 1.05 18.93-8.11 17.62-18.59-10-79.7-77.51-141.33-159.3-141.33zM256 288a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\"]\n};\nvar faFastBackward = {\n prefix: 'fas',\n iconName: 'fast-backward',\n icon: [512, 512, [], \"f049\", \"M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z\"]\n};\nvar faFastForward = {\n prefix: 'fas',\n iconName: 'fast-forward',\n icon: [512, 512, [], \"f050\", \"M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z\"]\n};\nvar faFax = {\n prefix: 'fas',\n iconName: 'fax',\n icon: [512, 512, [], \"f1ac\", \"M64 128H32c-17.67 0-32 14.33-32 32v320c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V160c0-17.67-14.33-32-32-32zm416 32V77.25c0-8.49-3.37-16.62-9.37-22.63L425.37 9.37c-6-6-14.14-9.37-22.63-9.37H160c-17.67 0-32 14.33-32 32v448c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32V192c0-17.67-14.33-32-32-32zM288 432c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v32zm0-128c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v32zm128 128c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v32zm0-128c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v32zm16-112H176V48h208v32c0 8.84 7.16 16 16 16h32v96z\"]\n};\nvar faFeather = {\n prefix: 'fas',\n iconName: 'feather',\n icon: [512, 512, [], \"f52d\", \"M467.14 44.84c-62.55-62.48-161.67-64.78-252.28 25.73-78.61 78.52-60.98 60.92-85.75 85.66-60.46 60.39-70.39 150.83-63.64 211.17l178.44-178.25c6.26-6.25 16.4-6.25 22.65 0s6.25 16.38 0 22.63L7.04 471.03c-9.38 9.37-9.38 24.57 0 33.94 9.38 9.37 24.6 9.37 33.98 0l66.1-66.03C159.42 454.65 279 457.11 353.95 384h-98.19l147.57-49.14c49.99-49.93 36.38-36.18 46.31-46.86h-97.78l131.54-43.8c45.44-74.46 34.31-148.84-16.26-199.36z\"]\n};\nvar faFeatherAlt = {\n prefix: 'fas',\n iconName: 'feather-alt',\n icon: [512, 512, [], \"f56b\", \"M512 0C460.22 3.56 96.44 38.2 71.01 287.61c-3.09 26.66-4.84 53.44-5.99 80.24l178.87-178.69c6.25-6.25 16.4-6.25 22.65 0s6.25 16.38 0 22.63L7.04 471.03c-9.38 9.37-9.38 24.57 0 33.94 9.38 9.37 24.59 9.37 33.98 0l57.13-57.07c42.09-.14 84.15-2.53 125.96-7.36 53.48-5.44 97.02-26.47 132.58-56.54H255.74l146.79-48.88c11.25-14.89 21.37-30.71 30.45-47.12h-81.14l106.54-53.21C500.29 132.86 510.19 26.26 512 0z\"]\n};\nvar faFemale = {\n prefix: 'fas',\n iconName: 'female',\n icon: [256, 512, [], \"f182\", \"M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z\"]\n};\nvar faFighterJet = {\n prefix: 'fas',\n iconName: 'fighter-jet',\n icon: [640, 512, [], \"f0fb\", \"M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z\"]\n};\nvar faFile = {\n prefix: 'fas',\n iconName: 'file',\n icon: [384, 512, [], \"f15b\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFileAlt = {\n prefix: 'fas',\n iconName: 'file-alt',\n icon: [384, 512, [], \"f15c\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFileArchive = {\n prefix: 'fas',\n iconName: 'file-archive',\n icon: [384, 512, [], \"f1c6\", \"M377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zM128.4 336c-17.9 0-32.4 12.1-32.4 27 0 15 14.6 27 32.5 27s32.4-12.1 32.4-27-14.6-27-32.5-27zM224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6z\"]\n};\nvar faFileAudio = {\n prefix: 'fas',\n iconName: 'file-audio',\n icon: [384, 512, [], \"f1c7\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFileCode = {\n prefix: 'fas',\n iconName: 'file-code',\n icon: [384, 512, [], \"f1c9\", \"M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z\"]\n};\nvar faFileContract = {\n prefix: 'fas',\n iconName: 'file-contract',\n icon: [384, 512, [], \"f56c\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM64 72c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8V72zm0 64c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16zm192.81 248H304c8.84 0 16 7.16 16 16s-7.16 16-16 16h-47.19c-16.45 0-31.27-9.14-38.64-23.86-2.95-5.92-8.09-6.52-10.17-6.52s-7.22.59-10.02 6.19l-7.67 15.34a15.986 15.986 0 0 1-14.31 8.84c-.38 0-.75-.02-1.14-.05-6.45-.45-12-4.75-14.03-10.89L144 354.59l-10.61 31.88c-5.89 17.66-22.38 29.53-41 29.53H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h12.39c4.83 0 9.11-3.08 10.64-7.66l18.19-54.64c3.3-9.81 12.44-16.41 22.78-16.41s19.48 6.59 22.77 16.41l13.88 41.64c19.77-16.19 54.05-9.7 66 14.16 2.02 4.06 5.96 6.5 10.16 6.5zM377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z\"]\n};\nvar faFileCsv = {\n prefix: 'fas',\n iconName: 'file-csv',\n icon: [384, 512, [], \"f6dd\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-96 144c0 4.42-3.58 8-8 8h-8c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h8c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8h-8c-26.51 0-48-21.49-48-48v-32c0-26.51 21.49-48 48-48h8c4.42 0 8 3.58 8 8v16zm44.27 104H160c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h12.27c5.95 0 10.41-3.5 10.41-6.62 0-1.3-.75-2.66-2.12-3.84l-21.89-18.77c-8.47-7.22-13.33-17.48-13.33-28.14 0-21.3 19.02-38.62 42.41-38.62H200c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8h-12.27c-5.95 0-10.41 3.5-10.41 6.62 0 1.3.75 2.66 2.12 3.84l21.89 18.77c8.47 7.22 13.33 17.48 13.33 28.14.01 21.29-19 38.62-42.39 38.62zM256 264v20.8c0 20.27 5.7 40.17 16 56.88 10.3-16.7 16-36.61 16-56.88V264c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v20.8c0 35.48-12.88 68.89-36.28 94.09-3.02 3.25-7.27 5.11-11.72 5.11s-8.7-1.86-11.72-5.11c-23.4-25.2-36.28-58.61-36.28-94.09V264c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8zm121-159L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z\"]\n};\nvar faFileDownload = {\n prefix: 'fas',\n iconName: 'file-download',\n icon: [384, 512, [], \"f56d\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm76.45 211.36l-96.42 95.7c-6.65 6.61-17.39 6.61-24.04 0l-96.42-95.7C73.42 337.29 80.54 320 94.82 320H160v-80c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v80h65.18c14.28 0 21.4 17.29 11.27 27.36zM377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z\"]\n};\nvar faFileExcel = {\n prefix: 'fas',\n iconName: 'file-excel',\n icon: [384, 512, [], \"f1c3\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFileExport = {\n prefix: 'fas',\n iconName: 'file-export',\n icon: [576, 512, [], \"f56e\", \"M384 121.9c0-6.3-2.5-12.4-7-16.9L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128zM571 308l-95.7-96.4c-10.1-10.1-27.4-3-27.4 11.3V288h-64v64h64v65.2c0 14.3 17.3 21.4 27.4 11.3L571 332c6.6-6.6 6.6-17.4 0-24zm-379 28v-32c0-8.8 7.2-16 16-16h176V160H248c-13.2 0-24-10.8-24-24V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V352H208c-8.8 0-16-7.2-16-16z\"]\n};\nvar faFileImage = {\n prefix: 'fas',\n iconName: 'file-image',\n icon: [384, 512, [], \"f1c5\", \"M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z\"]\n};\nvar faFileImport = {\n prefix: 'fas',\n iconName: 'file-import',\n icon: [512, 512, [], \"f56f\", \"M16 288c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h112v-64zm489-183L407.1 7c-4.5-4.5-10.6-7-17-7H384v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H152c-13.3 0-24 10.7-24 24v264h128v-65.2c0-14.3 17.3-21.4 27.4-11.3L379 308c6.6 6.7 6.6 17.4 0 24l-95.7 96.4c-10.1 10.1-27.4 3-27.4-11.3V352H128v136c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H376c-13.2 0-24-10.8-24-24z\"]\n};\nvar faFileInvoice = {\n prefix: 'fas',\n iconName: 'file-invoice',\n icon: [384, 512, [], \"f570\", \"M288 256H96v64h192v-64zm89-151L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM64 72c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8V72zm0 64c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16zm256 304c0 4.42-3.58 8-8 8h-80c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16zm0-200v96c0 8.84-7.16 16-16 16H80c-8.84 0-16-7.16-16-16v-96c0-8.84 7.16-16 16-16h224c8.84 0 16 7.16 16 16z\"]\n};\nvar faFileInvoiceDollar = {\n prefix: 'fas',\n iconName: 'file-invoice-dollar',\n icon: [384, 512, [], \"f571\", \"M377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM64 72c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8V72zm0 80v-16c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8zm144 263.88V440c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-24.29c-11.29-.58-22.27-4.52-31.37-11.35-3.9-2.93-4.1-8.77-.57-12.14l11.75-11.21c2.77-2.64 6.89-2.76 10.13-.73 3.87 2.42 8.26 3.72 12.82 3.72h28.11c6.5 0 11.8-5.92 11.8-13.19 0-5.95-3.61-11.19-8.77-12.73l-45-13.5c-18.59-5.58-31.58-23.42-31.58-43.39 0-24.52 19.05-44.44 42.67-45.07V232c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v24.29c11.29.58 22.27 4.51 31.37 11.35 3.9 2.93 4.1 8.77.57 12.14l-11.75 11.21c-2.77 2.64-6.89 2.76-10.13.73-3.87-2.43-8.26-3.72-12.82-3.72h-28.11c-6.5 0-11.8 5.92-11.8 13.19 0 5.95 3.61 11.19 8.77 12.73l45 13.5c18.59 5.58 31.58 23.42 31.58 43.39 0 24.53-19.05 44.44-42.67 45.07z\"]\n};\nvar faFileMedical = {\n prefix: 'fas',\n iconName: 'file-medical',\n icon: [384, 512, [], \"f477\", \"M377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 160v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8z\"]\n};\nvar faFileMedicalAlt = {\n prefix: 'fas',\n iconName: 'file-medical-alt',\n icon: [448, 512, [], \"f478\", \"M288 136V0H88C74.7 0 64 10.7 64 24v232H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h140.9c3 0 5.8 1.7 7.2 4.4l19.9 39.8 56.8-113.7c2.9-5.9 11.4-5.9 14.3 0l34.7 69.5H352c8.8 0 16 7.2 16 16s-7.2 16-16 16h-89.9L240 275.8l-56.8 113.7c-2.9 5.9-11.4 5.9-14.3 0L134.1 320H64v168c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H312c-13.2 0-24-10.8-24-24zm153-31L343.1 7c-4.5-4.5-10.6-7-17-7H320v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z\"]\n};\nvar faFilePdf = {\n prefix: 'fas',\n iconName: 'file-pdf',\n icon: [384, 512, [], \"f1c1\", \"M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z\"]\n};\nvar faFilePowerpoint = {\n prefix: 'fas',\n iconName: 'file-powerpoint',\n icon: [384, 512, [], \"f1c4\", \"M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z\"]\n};\nvar faFilePrescription = {\n prefix: 'fas',\n iconName: 'file-prescription',\n icon: [384, 512, [], \"f572\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm68.53 179.48l11.31 11.31c6.25 6.25 6.25 16.38 0 22.63l-29.9 29.9L304 409.38c6.25 6.25 6.25 16.38 0 22.63l-11.31 11.31c-6.25 6.25-16.38 6.25-22.63 0L240 413.25l-30.06 30.06c-6.25 6.25-16.38 6.25-22.63 0L176 432c-6.25-6.25-6.25-16.38 0-22.63l30.06-30.06L146.74 320H128v48c0 8.84-7.16 16-16 16H96c-8.84 0-16-7.16-16-16V208c0-8.84 7.16-16 16-16h80c35.35 0 64 28.65 64 64 0 24.22-13.62 45.05-33.46 55.92L240 345.38l29.9-29.9c6.25-6.25 16.38-6.25 22.63 0zM176 272h-48v-32h48c8.82 0 16 7.18 16 16s-7.18 16-16 16zm208-150.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFileSignature = {\n prefix: 'fas',\n iconName: 'file-signature',\n icon: [576, 512, [], \"f573\", \"M218.17 424.14c-2.95-5.92-8.09-6.52-10.17-6.52s-7.22.59-10.02 6.19l-7.67 15.34c-6.37 12.78-25.03 11.37-29.48-2.09L144 386.59l-10.61 31.88c-5.89 17.66-22.38 29.53-41 29.53H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h12.39c4.83 0 9.11-3.08 10.64-7.66l18.19-54.64c3.3-9.81 12.44-16.41 22.78-16.41s19.48 6.59 22.77 16.41l13.88 41.64c19.75-16.19 54.06-9.7 66 14.16 1.89 3.78 5.49 5.95 9.36 6.26v-82.12l128-127.09V160H248c-13.2 0-24-10.8-24-24V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24v-40l-128-.11c-16.12-.31-30.58-9.28-37.83-23.75zM384 121.9c0-6.3-2.5-12.4-7-16.9L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1zm-96 225.06V416h68.99l161.68-162.78-67.88-67.88L288 346.96zm280.54-179.63l-31.87-31.87c-9.94-9.94-26.07-9.94-36.01 0l-27.25 27.25 67.88 67.88 27.25-27.25c9.95-9.94 9.95-26.07 0-36.01z\"]\n};\nvar faFileUpload = {\n prefix: 'fas',\n iconName: 'file-upload',\n icon: [384, 512, [], \"f574\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm65.18 216.01H224v80c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-80H94.82c-14.28 0-21.41-17.29-11.27-27.36l96.42-95.7c6.65-6.61 17.39-6.61 24.04 0l96.42 95.7c10.15 10.07 3.03 27.36-11.25 27.36zM377 105L279.1 7c-4.5-4.5-10.6-7-17-7H256v128h128v-6.1c0-6.3-2.5-12.4-7-16.9z\"]\n};\nvar faFileVideo = {\n prefix: 'fas',\n iconName: 'file-video',\n icon: [384, 512, [], \"f1c8\", \"M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z\"]\n};\nvar faFileWord = {\n prefix: 'fas',\n iconName: 'file-word',\n icon: [384, 512, [], \"f1c2\", \"M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z\"]\n};\nvar faFill = {\n prefix: 'fas',\n iconName: 'fill',\n icon: [512, 512, [], \"f575\", \"M502.63 217.06L294.94 9.37C288.69 3.12 280.5 0 272.31 0s-16.38 3.12-22.62 9.37l-81.58 81.58L81.93 4.77c-6.24-6.25-16.38-6.25-22.62 0L36.69 27.38c-6.24 6.25-6.24 16.38 0 22.63l86.19 86.18-94.76 94.76c-37.49 37.49-37.49 98.26 0 135.75l117.19 117.19c18.75 18.74 43.31 28.12 67.87 28.12 24.57 0 49.13-9.37 67.88-28.12l221.57-221.57c12.49-12.5 12.49-32.76 0-45.26zm-116.22 70.97H65.93c1.36-3.84 3.57-7.98 7.43-11.83l13.15-13.15 81.61-81.61 58.61 58.6c12.49 12.49 32.75 12.49 45.24 0 12.49-12.49 12.49-32.75 0-45.24l-58.61-58.6 58.95-58.95 162.45 162.44-48.35 48.34z\"]\n};\nvar faFillDrip = {\n prefix: 'fas',\n iconName: 'fill-drip',\n icon: [576, 512, [], \"f576\", \"M512 320s-64 92.65-64 128c0 35.35 28.66 64 64 64s64-28.65 64-64-64-128-64-128zm-9.37-102.94L294.94 9.37C288.69 3.12 280.5 0 272.31 0s-16.38 3.12-22.62 9.37l-81.58 81.58L81.93 4.76c-6.25-6.25-16.38-6.25-22.62 0L36.69 27.38c-6.24 6.25-6.24 16.38 0 22.62l86.19 86.18-94.76 94.76c-37.49 37.48-37.49 98.26 0 135.75l117.19 117.19c18.74 18.74 43.31 28.12 67.87 28.12 24.57 0 49.13-9.37 67.87-28.12l221.57-221.57c12.5-12.5 12.5-32.75.01-45.25zm-116.22 70.97H65.93c1.36-3.84 3.57-7.98 7.43-11.83l13.15-13.15 81.61-81.61 58.6 58.6c12.49 12.49 32.75 12.49 45.24 0s12.49-32.75 0-45.24l-58.6-58.6 58.95-58.95 162.44 162.44-48.34 48.34z\"]\n};\nvar faFilm = {\n prefix: 'fas',\n iconName: 'film',\n icon: [512, 512, [], \"f008\", \"M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z\"]\n};\nvar faFilter = {\n prefix: 'fas',\n iconName: 'filter',\n icon: [512, 512, [], \"f0b0\", \"M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z\"]\n};\nvar faFingerprint = {\n prefix: 'fas',\n iconName: 'fingerprint',\n icon: [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"]\n};\nvar faFire = {\n prefix: 'fas',\n iconName: 'fire',\n icon: [384, 512, [], \"f06d\", \"M216 23.86c0-23.8-30.65-32.77-44.15-13.04C48 191.85 224 200 224 288c0 35.63-29.11 64.46-64.85 63.99-35.17-.45-63.15-29.77-63.15-64.94v-85.51c0-21.7-26.47-32.23-41.43-16.5C27.8 213.16 0 261.33 0 320c0 105.87 86.13 192 192 192s192-86.13 192-192c0-170.29-168-193-168-296.14z\"]\n};\nvar faFireAlt = {\n prefix: 'fas',\n iconName: 'fire-alt',\n icon: [448, 512, [], \"f7e4\", \"M323.56 51.2c-20.8 19.3-39.58 39.59-56.22 59.97C240.08 73.62 206.28 35.53 168 0 69.74 91.17 0 209.96 0 281.6 0 408.85 100.29 512 224 512s224-103.15 224-230.4c0-53.27-51.98-163.14-124.44-230.4zm-19.47 340.65C282.43 407.01 255.72 416 226.86 416 154.71 416 96 368.26 96 290.75c0-38.61 24.31-72.63 72.79-130.75 6.93 7.98 98.83 125.34 98.83 125.34l58.63-66.88c4.14 6.85 7.91 13.55 11.27 19.97 27.35 52.19 15.81 118.97-33.43 153.42z\"]\n};\nvar faFireExtinguisher = {\n prefix: 'fas',\n iconName: 'fire-extinguisher',\n icon: [448, 512, [], \"f134\", \"M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z\"]\n};\nvar faFirstAid = {\n prefix: 'fas',\n iconName: 'first-aid',\n icon: [576, 512, [], \"f479\", \"M0 80v352c0 26.5 21.5 48 48 48h48V32H48C21.5 32 0 53.5 0 80zm128 400h320V32H128v448zm64-248c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48zM528 32h-48v448h48c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"]\n};\nvar faFish = {\n prefix: 'fas',\n iconName: 'fish',\n icon: [576, 512, [], \"f578\", \"M327.1 96c-89.97 0-168.54 54.77-212.27 101.63L27.5 131.58c-12.13-9.18-30.24.6-27.14 14.66L24.54 256 .35 365.77c-3.1 14.06 15.01 23.83 27.14 14.66l87.33-66.05C158.55 361.23 237.13 416 327.1 416 464.56 416 576 288 576 256S464.56 96 327.1 96zm87.43 184c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24 13.26 0 24 10.74 24 24 0 13.25-10.75 24-24 24z\"]\n};\nvar faFistRaised = {\n prefix: 'fas',\n iconName: 'fist-raised',\n icon: [384, 512, [], \"f6de\", \"M255.98 160V16c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v146.93c5.02-1.78 10.34-2.93 15.97-2.93h48.03zm128 95.99c-.01-35.34-28.66-63.99-63.99-63.99H207.85c-8.78 0-15.9 7.07-15.9 15.85v.56c0 26.27 21.3 47.59 47.57 47.59h35.26c9.68 0 13.2 3.58 13.2 8v16.2c0 4.29-3.59 7.78-7.88 8-44.52 2.28-64.16 24.71-96.05 72.55l-6.31 9.47a7.994 7.994 0 0 1-11.09 2.22l-13.31-8.88a7.994 7.994 0 0 1-2.22-11.09l6.31-9.47c15.73-23.6 30.2-43.26 47.31-58.08-17.27-5.51-31.4-18.12-38.87-34.45-6.59 3.41-13.96 5.52-21.87 5.52h-32c-12.34 0-23.49-4.81-32-12.48C71.48 251.19 60.33 256 48 256H16c-5.64 0-10.97-1.15-16-2.95v77.93c0 33.95 13.48 66.5 37.49 90.51L63.99 448v64h255.98v-63.96l35.91-35.92A96.035 96.035 0 0 0 384 344.21l-.02-88.22zm-32.01-90.09V48c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v112h32c11.28 0 21.94 2.31 32 5.9zM16 224h32c8.84 0 16-7.16 16-16V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v128c0 8.84 7.16 16 16 16zm95.99 0h32c8.84 0 16-7.16 16-16V48c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v160c0 8.84 7.16 16 16 16z\"]\n};\nvar faFlag = {\n prefix: 'fas',\n iconName: 'flag',\n icon: [512, 512, [], \"f024\", \"M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z\"]\n};\nvar faFlagCheckered = {\n prefix: 'fas',\n iconName: 'flag-checkered',\n icon: [512, 512, [], \"f11e\", \"M243.2 189.9V258c26.1 5.9 49.3 15.6 73.6 22.3v-68.2c-26-5.8-49.4-15.5-73.6-22.2zm223.3-123c-34.3 15.9-76.5 31.9-117 31.9C296 98.8 251.7 64 184.3 64c-25 0-47.3 4.4-68 12 2.8-7.3 4.1-15.2 3.6-23.6C118.1 24 94.8 1.2 66.3 0 34.3-1.3 8 24.3 8 56c0 19 9.5 35.8 24 45.9V488c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-94.4c28.3-12.1 63.6-22.1 114.4-22.1 53.6 0 97.8 34.8 165.2 34.8 48.2 0 86.7-16.3 122.5-40.9 8.7-6 13.8-15.8 13.8-26.4V95.9c.1-23.3-24.2-38.8-45.4-29zM169.6 325.5c-25.8 2.7-50 8.2-73.6 16.6v-70.5c26.2-9.3 47.5-15 73.6-17.4zM464 191c-23.6 9.8-46.3 19.5-73.6 23.9V286c24.8-3.4 51.4-11.8 73.6-26v70.5c-25.1 16.1-48.5 24.7-73.6 27.1V286c-27 3.7-47.9 1.5-73.6-5.6v67.4c-23.9-7.4-47.3-16.7-73.6-21.3V258c-19.7-4.4-40.8-6.8-73.6-3.8v-70c-22.4 3.1-44.6 10.2-73.6 20.9v-70.5c33.2-12.2 50.1-19.8 73.6-22v71.6c27-3.7 48.4-1.3 73.6 5.7v-67.4c23.7 7.4 47.2 16.7 73.6 21.3v68.4c23.7 5.3 47.6 6.9 73.6 2.7V143c27-4.8 52.3-13.6 73.6-22.5z\"]\n};\nvar faFlagUsa = {\n prefix: 'fas',\n iconName: 'flag-usa',\n icon: [512, 512, [], \"f74d\", \"M32 0C14.3 0 0 14.3 0 32v464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V32C64 14.3 49.7 0 32 0zm267.9 303.6c-57.2-15.1-111.7-28.8-203.9 11.1V384c185.7-92.2 221.7 53.3 397.5-23.1 11.4-5 18.5-16.5 18.5-28.8v-36c-43.6 17.3-80.2 24.1-112.1 24.1-37.4-.1-68.9-8.4-100-16.6zm0-96c-57.2-15.1-111.7-28.8-203.9 11.1v61.5c94.8-37.6 154.6-22.7 212.1-7.6 57.2 15.1 111.7 28.8 203.9-11.1V200c-43.6 17.3-80.2 24.1-112.1 24.1-37.4 0-68.9-8.3-100-16.5zm9.5-125.9c51.8 15.6 97.4 29 202.6-20.1V30.8c0-25.1-26.8-38.1-49.4-26.6C291.3 91.5 305.4-62.2 96 32.4v151.9c94.8-37.5 154.6-22.7 212.1-7.6 57.2 15 111.7 28.7 203.9-11.1V96.7c-53.6 23.5-93.3 31.4-126.1 31.4s-59-7.8-85.7-15.9c-4-1.2-8.1-2.4-12.1-3.5V75.5c7.2 2 14.3 4.1 21.3 6.2zM160 128.1c-8.8 0-16-7.1-16-16 0-8.8 7.2-16 16-16s16 7.1 16 16-7.2 16-16 16zm0-55.8c-8.8 0-16-7.1-16-16 0-8.8 7.2-16 16-16s16 7.1 16 16c0 8.8-7.2 16-16 16zm64 47.9c-8.8 0-16-7.1-16-16 0-8.8 7.2-16 16-16s16 7.1 16 16c0 8.8-7.2 16-16 16zm0-55.9c-8.8 0-16-7.1-16-16 0-8.8 7.2-16 16-16s16 7.1 16 16c0 8.8-7.2 16-16 16z\"]\n};\nvar faFlask = {\n prefix: 'fas',\n iconName: 'flask',\n icon: [448, 512, [], \"f0c3\", \"M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z\"]\n};\nvar faFlushed = {\n prefix: 'fas',\n iconName: 'flushed',\n icon: [496, 512, [], \"f579\", \"M344 200c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm-192 0c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM80 224c0-39.8 32.2-72 72-72s72 32.2 72 72-32.2 72-72 72-72-32.2-72-72zm232 176H184c-21.2 0-21.2-32 0-32h128c21.2 0 21.2 32 0 32zm32-104c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z\"]\n};\nvar faFolder = {\n prefix: 'fas',\n iconName: 'folder',\n icon: [512, 512, [], \"f07b\", \"M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z\"]\n};\nvar faFolderMinus = {\n prefix: 'fas',\n iconName: 'folder-minus',\n icon: [512, 512, [], \"f65d\", \"M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-96 168c0 8.84-7.16 16-16 16H160c-8.84 0-16-7.16-16-16v-16c0-8.84 7.16-16 16-16h192c8.84 0 16 7.16 16 16v16z\"]\n};\nvar faFolderOpen = {\n prefix: 'fas',\n iconName: 'folder-open',\n icon: [576, 512, [], \"f07c\", \"M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z\"]\n};\nvar faFolderPlus = {\n prefix: 'fas',\n iconName: 'folder-plus',\n icon: [512, 512, [], \"f65e\", \"M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-96 168c0 8.84-7.16 16-16 16h-72v72c0 8.84-7.16 16-16 16h-16c-8.84 0-16-7.16-16-16v-72h-72c-8.84 0-16-7.16-16-16v-16c0-8.84 7.16-16 16-16h72v-72c0-8.84 7.16-16 16-16h16c8.84 0 16 7.16 16 16v72h72c8.84 0 16 7.16 16 16v16z\"]\n};\nvar faFont = {\n prefix: 'fas',\n iconName: 'font',\n icon: [448, 512, [], \"f031\", \"M432 416h-23.41L277.88 53.69A32 32 0 0 0 247.58 32h-47.16a32 32 0 0 0-30.3 21.69L39.41 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-19.58l23.3-64h152.56l23.3 64H304a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM176.85 272L224 142.51 271.15 272z\"]\n};\nvar faFontAwesomeLogoFull = {\n prefix: 'fas',\n iconName: 'font-awesome-logo-full',\n icon: [3992, 512, [\"Font Awesome\"], \"f4e6\", \"M454.6 0H57.4C25.9 0 0 25.9 0 57.4v397.3C0 486.1 25.9 512 57.4 512h397.3c31.4 0 57.4-25.9 57.4-57.4V57.4C512 25.9 486.1 0 454.6 0zm-58.9 324.9c0 4.8-4.1 6.9-8.9 8.9-19.2 8.1-39.7 15.7-61.5 15.7-40.5 0-68.7-44.8-163.2 2.5v51.8c0 30.3-45.7 30.2-45.7 0v-250c-9-7-15-17.9-15-30.3 0-21 17.1-38.2 38.2-38.2 21 0 38.2 17.1 38.2 38.2 0 12.2-5.8 23.2-14.9 30.2v21c37.1-12 65.5-34.4 146.1-3.4 26.6 11.4 68.7-15.7 76.5-15.7 5.5 0 10.3 4.1 10.3 8.9v160.4zm432.9-174.2h-137v70.1H825c39.8 0 40.4 62.2 0 62.2H691.6v105.6c0 45.5-70.7 46.4-70.7 0V128.3c0-22 18-39.8 39.8-39.8h167.8c39.6 0 40.5 62.2.1 62.2zm191.1 23.4c-169.3 0-169.1 252.4 0 252.4 169.9 0 169.9-252.4 0-252.4zm0 196.1c-81.6 0-82.1-139.8 0-139.8 82.5 0 82.4 139.8 0 139.8zm372.4 53.4c-17.5 0-31.4-13.9-31.4-31.4v-117c0-62.4-72.6-52.5-99.1-16.4v133.4c0 41.5-63.3 41.8-63.3 0V208c0-40 63.1-41.6 63.1 0v3.4c43.3-51.6 162.4-60.4 162.4 39.3v141.5c.3 30.4-31.5 31.4-31.7 31.4zm179.7 2.9c-44.3 0-68.3-22.9-68.3-65.8V235.2H1488c-35.6 0-36.7-55.3 0-55.3h15.5v-37.3c0-41.3 63.8-42.1 63.8 0v37.5h24.9c35.4 0 35.7 55.3 0 55.3h-24.9v108.5c0 29.6 26.1 26.3 27.4 26.3 31.4 0 52.6 56.3-22.9 56.3zM1992 123c-19.5-50.2-95.5-50-114.5 0-107.3 275.7-99.5 252.7-99.5 262.8 0 42.8 58.3 51.2 72.1 14.4l13.5-35.9H2006l13 35.9c14.2 37.7 72.1 27.2 72.1-14.4 0-10.1 5.3 6.8-99.1-262.8zm-108.9 179.1l51.7-142.9 51.8 142.9h-103.5zm591.3-85.6l-53.7 176.3c-12.4 41.2-72 41-84 0l-42.3-135.9-42.3 135.9c-12.4 40.9-72 41.2-84.5 0l-54.2-176.3c-12.5-39.4 49.8-56.1 60.2-16.9L2213 342l45.3-139.5c10.9-32.7 59.6-34.7 71.2 0l45.3 139.5 39.3-142.4c10.3-38.3 72.6-23.8 60.3 16.9zm275.4 75.1c0-42.4-33.9-117.5-119.5-117.5-73.2 0-124.4 56.3-124.4 126 0 77.2 55.3 126.4 128.5 126.4 31.7 0 93-11.5 93-39.8 0-18.3-21.1-31.5-39.3-22.4-49.4 26.2-109 8.4-115.9-43.8h148.3c16.3 0 29.3-13.4 29.3-28.9zM2571 277.7c9.5-73.4 113.9-68.6 118.6 0H2571zm316.7 148.8c-31.4 0-81.6-10.5-96.6-31.9-12.4-17 2.5-39.8 21.8-39.8 16.3 0 36.8 22.9 77.7 22.9 27.4 0 40.4-11 40.4-25.8 0-39.8-142.9-7.4-142.9-102 0-40.4 35.3-75.7 98.6-75.7 31.4 0 74.1 9.9 87.6 29.4 10.8 14.8-1.4 36.2-20.9 36.2-15.1 0-26.7-17.3-66.2-17.3-22.9 0-37.8 10.5-37.8 23.8 0 35.9 142.4 6 142.4 103.1-.1 43.7-37.4 77.1-104.1 77.1zm266.8-252.4c-169.3 0-169.1 252.4 0 252.4 170.1 0 169.6-252.4 0-252.4zm0 196.1c-81.8 0-82-139.8 0-139.8 82.5 0 82.4 139.8 0 139.8zm476.9 22V268.7c0-53.8-61.4-45.8-85.7-10.5v134c0 41.3-63.8 42.1-63.8 0V268.7c0-52.1-59.5-47.4-85.7-10.1v133.6c0 41.5-63.3 41.8-63.3 0V208c0-40 63.1-41.6 63.1 0v3.4c9.9-14.4 41.8-37.3 78.6-37.3 35.3 0 57.7 16.4 66.7 43.8 13.9-21.8 45.8-43.8 82.6-43.8 44.3 0 70.7 23.4 70.7 72.7v145.3c.5 17.3-13.5 31.4-31.9 31.4 3.5.1-31.3 1.1-31.3-31.3zM3992 291.6c0-42.4-32.4-117.5-117.9-117.5-73.2 0-127.5 56.3-127.5 126 0 77.2 58.3 126.4 131.6 126.4 31.7 0 91.5-11.5 91.5-39.8 0-18.3-21.1-31.5-39.3-22.4-49.4 26.2-110.5 8.4-117.5-43.8h149.8c16.3 0 29.1-13.4 29.3-28.9zm-180.5-13.9c9.7-74.4 115.9-68.3 120.1 0h-120.1z\"]\n};\nvar faFootballBall = {\n prefix: 'fas',\n iconName: 'football-ball',\n icon: [496, 512, [], \"f44e\", \"M481.5 60.3c-4.8-18.2-19.1-32.5-37.3-37.4C420.3 16.5 383 8.9 339.4 8L496 164.8c-.8-43.5-8.2-80.6-14.5-104.5zm-467 391.4c4.8 18.2 19.1 32.5 37.3 37.4 23.9 6.4 61.2 14 104.8 14.9L0 347.2c.8 43.5 8.2 80.6 14.5 104.5zM4.2 283.4L220.4 500c132.5-19.4 248.8-118.7 271.5-271.4L275.6 12C143.1 31.4 26.8 130.7 4.2 283.4zm317.3-123.6c3.1-3.1 8.2-3.1 11.3 0l11.3 11.3c3.1 3.1 3.1 8.2 0 11.3l-28.3 28.3 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-28.3-28.3-22.6 22.7 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L248 278.6l-22.6 22.6 28.3 28.3c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-28.3-28.3-28.3 28.3c-3.1 3.1-8.2 3.1-11.3 0l-11.3-11.3c-3.1-3.1-3.1-8.2 0-11.3l28.3-28.3-28.3-28.2c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 22.6-22.6-28.3-28.3c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 22.6-22.6-28.3-28.3c-3.1-3.1-3.1-8.2 0-11.3l11.3-11.3c3.1-3.1 8.2-3.1 11.3 0l28.3 28.3 28.3-28.5z\"]\n};\nvar faForward = {\n prefix: 'fas',\n iconName: 'forward',\n icon: [512, 512, [], \"f04e\", \"M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z\"]\n};\nvar faFrog = {\n prefix: 'fas',\n iconName: 'frog',\n icon: [576, 512, [], \"f52e\", \"M446.53 97.43C439.67 60.23 407.19 32 368 32c-39.23 0-71.72 28.29-78.54 65.54C126.75 112.96-.5 250.12 0 416.98.11 451.9 29.08 480 64 480h304c8.84 0 16-7.16 16-16 0-17.67-14.33-32-32-32h-79.49l35.8-48.33c24.14-36.23 10.35-88.28-33.71-106.6-23.89-9.93-51.55-4.65-72.24 10.88l-32.76 24.59c-7.06 5.31-17.09 3.91-22.41-3.19-5.3-7.08-3.88-17.11 3.19-22.41l34.78-26.09c36.84-27.66 88.28-27.62 125.13 0 10.87 8.15 45.87 39.06 40.8 93.21L469.62 480H560c8.84 0 16-7.16 16-16 0-17.67-14.33-32-32-32h-53.63l-98.52-104.68 154.44-86.65A58.16 58.16 0 0 0 576 189.94c0-21.4-11.72-40.95-30.48-51.23-40.56-22.22-98.99-41.28-98.99-41.28zM368 136c-13.26 0-24-10.75-24-24 0-13.26 10.74-24 24-24 13.25 0 24 10.74 24 24 0 13.25-10.75 24-24 24z\"]\n};\nvar faFrown = {\n prefix: 'fas',\n iconName: 'frown',\n icon: [496, 512, [], \"f119\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm170.2 218.2C315.8 367.4 282.9 352 248 352s-67.8 15.4-90.2 42.2c-13.5 16.3-38.1-4.2-24.6-20.5C161.7 339.6 203.6 320 248 320s86.3 19.6 114.7 53.8c13.6 16.2-11 36.7-24.5 20.4z\"]\n};\nvar faFrownOpen = {\n prefix: 'fas',\n iconName: 'frown-open',\n icon: [496, 512, [], \"f57a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM136 208c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm187.3 183.3c-31.2-9.6-59.4-15.3-75.3-15.3s-44.1 5.7-75.3 15.3c-11.5 3.5-22.5-6.3-20.5-18.1 7-40 60.1-61.2 95.8-61.2s88.8 21.3 95.8 61.2c2 11.9-9.1 21.6-20.5 18.1zM328 240c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faFunnelDollar = {\n prefix: 'fas',\n iconName: 'funnel-dollar',\n icon: [640, 512, [], \"f662\", \"M433.46 165.94l101.2-111.87C554.61 34.12 540.48 0 512.26 0H31.74C3.52 0-10.61 34.12 9.34 54.07L192 256v155.92c0 12.59 5.93 24.44 16 32l79.99 60c20.86 15.64 48.47 6.97 59.22-13.57C310.8 455.38 288 406.35 288 352c0-89.79 62.05-165.17 145.46-186.06zM480 192c-88.37 0-160 71.63-160 160s71.63 160 160 160 160-71.63 160-160-71.63-160-160-160zm16 239.88V448c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-16.29c-11.29-.58-22.27-4.52-31.37-11.35-3.9-2.93-4.1-8.77-.57-12.14l11.75-11.21c2.77-2.64 6.89-2.76 10.13-.73 3.87 2.42 8.26 3.72 12.82 3.72h28.11c6.5 0 11.8-5.92 11.8-13.19 0-5.95-3.61-11.19-8.77-12.73l-45-13.5c-18.59-5.58-31.58-23.42-31.58-43.39 0-24.52 19.05-44.44 42.67-45.07V256c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16.29c11.29.58 22.27 4.51 31.37 11.35 3.9 2.93 4.1 8.77.57 12.14l-11.75 11.21c-2.77 2.64-6.89 2.76-10.13.73-3.87-2.43-8.26-3.72-12.82-3.72h-28.11c-6.5 0-11.8 5.92-11.8 13.19 0 5.95 3.61 11.19 8.77 12.73l45 13.5c18.59 5.58 31.58 23.42 31.58 43.39 0 24.53-19.04 44.44-42.67 45.07z\"]\n};\nvar faFutbol = {\n prefix: 'fas',\n iconName: 'futbol',\n icon: [512, 512, [], \"f1e3\", \"M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z\"]\n};\nvar faGamepad = {\n prefix: 'fas',\n iconName: 'gamepad',\n icon: [640, 512, [], \"f11b\", \"M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z\"]\n};\nvar faGasPump = {\n prefix: 'fas',\n iconName: 'gas-pump',\n icon: [512, 512, [], \"f52f\", \"M336 448H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h320c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm157.2-340.7l-81-81c-6.2-6.2-16.4-6.2-22.6 0l-11.3 11.3c-6.2 6.2-6.2 16.4 0 22.6L416 97.9V160c0 28.1 20.9 51.3 48 55.2V376c0 13.2-10.8 24-24 24s-24-10.8-24-24v-32c0-48.6-39.4-88-88-88h-8V64c0-35.3-28.7-64-64-64H96C60.7 0 32 28.7 32 64v352h288V304h8c22.1 0 40 17.9 40 40v27.8c0 37.7 27 72 64.5 75.9 43 4.3 79.5-29.5 79.5-71.7V152.6c0-17-6.8-33.3-18.8-45.3zM256 192H96V64h160v128z\"]\n};\nvar faGavel = {\n prefix: 'fas',\n iconName: 'gavel',\n icon: [512, 512, [], \"f0e3\", \"M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z\"]\n};\nvar faGem = {\n prefix: 'fas',\n iconName: 'gem',\n icon: [576, 512, [], \"f3a5\", \"M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z\"]\n};\nvar faGenderless = {\n prefix: 'fas',\n iconName: 'genderless',\n icon: [288, 512, [], \"f22d\", \"M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z\"]\n};\nvar faGhost = {\n prefix: 'fas',\n iconName: 'ghost',\n icon: [384, 512, [], \"f6e2\", \"M186.1.09C81.01 3.24 0 94.92 0 200.05v263.92c0 14.26 17.23 21.39 27.31 11.31l24.92-18.53c6.66-4.95 16-3.99 21.51 2.21l42.95 48.35c6.25 6.25 16.38 6.25 22.63 0l40.72-45.85c6.37-7.17 17.56-7.17 23.92 0l40.72 45.85c6.25 6.25 16.38 6.25 22.63 0l42.95-48.35c5.51-6.2 14.85-7.17 21.51-2.21l24.92 18.53c10.08 10.08 27.31 2.94 27.31-11.31V192C384 84 294.83-3.17 186.1.09zM128 224c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm128 0c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faGift = {\n prefix: 'fas',\n iconName: 'gift',\n icon: [512, 512, [], \"f06b\", \"M32 448c0 17.7 14.3 32 32 32h160V320H32v128zm256 32h160c17.7 0 32-14.3 32-32V320H288v160zm192-320h-42.1c6.2-12.1 10.1-25.5 10.1-40 0-48.5-39.5-88-88-88-41.6 0-68.5 21.3-103 68.3-34.5-47-61.4-68.3-103-68.3-48.5 0-88 39.5-88 88 0 14.5 3.8 27.9 10.1 40H32c-17.7 0-32 14.3-32 32v80c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-80c0-17.7-14.3-32-32-32zm-326.1 0c-22.1 0-40-17.9-40-40s17.9-40 40-40c19.9 0 34.6 3.3 86.1 80h-86.1zm206.1 0h-86.1c51.4-76.5 65.7-80 86.1-80 22.1 0 40 17.9 40 40s-17.9 40-40 40z\"]\n};\nvar faGifts = {\n prefix: 'fas',\n iconName: 'gifts',\n icon: [640, 512, [], \"f79c\", \"M240.6 194.1c1.9-30.8 17.3-61.2 44-79.8C279.4 103.5 268.7 96 256 96h-29.4l30.7-22c7.2-5.1 8.9-15.1 3.7-22.3l-9.3-13c-5.1-7.2-15.1-8.9-22.3-3.7l-32 22.9 11.5-30.6c3.1-8.3-1.1-17.5-9.4-20.6l-15-5.6c-8.3-3.1-17.5 1.1-20.6 9.4l-19.9 53-19.9-53.1C121 2.1 111.8-2.1 103.5 1l-15 5.6C80.2 9.7 76 19 79.2 27.2l11.5 30.6L58.6 35c-7.2-5.1-17.2-3.5-22.3 3.7l-9.3 13c-5.1 7.2-3.5 17.2 3.7 22.3l30.7 22H32c-17.7 0-32 14.3-32 32v352c0 17.7 14.3 32 32 32h168.9c-5.5-9.5-8.9-20.3-8.9-32V256c0-29.9 20.8-55 48.6-61.9zM224 480c0 17.7 14.3 32 32 32h160V384H224v96zm224 32h160c17.7 0 32-14.3 32-32v-96H448v128zm160-288h-20.4c2.6-7.6 4.4-15.5 4.4-23.8 0-35.5-27-72.2-72.1-72.2-48.1 0-75.9 47.7-87.9 75.3-12.1-27.6-39.9-75.3-87.9-75.3-45.1 0-72.1 36.7-72.1 72.2 0 8.3 1.7 16.2 4.4 23.8H256c-17.7 0-32 14.3-32 32v96h192V224h15.3l.7-.2.7.2H448v128h192v-96c0-17.7-14.3-32-32-32zm-272 0c-2.7-1.4-5.1-3-7.2-4.8-7.3-6.4-8.8-13.8-8.8-19 0-9.7 6.4-24.2 24.1-24.2 18.7 0 35.6 27.4 44.5 48H336zm199.2-4.8c-2.1 1.8-4.5 3.4-7.2 4.8h-52.6c8.8-20.3 25.8-48 44.5-48 17.7 0 24.1 14.5 24.1 24.2 0 5.2-1.5 12.6-8.8 19z\"]\n};\nvar faGlassCheers = {\n prefix: 'fas',\n iconName: 'glass-cheers',\n icon: [640, 512, [], \"f79f\", \"M639.4 433.6c-8.4-20.4-31.8-30.1-52.2-21.6l-22.1 9.2-38.7-101.9c47.9-35 64.8-100.3 34.5-152.8L474.3 16c-8-13.9-25.1-19.7-40-13.6L320 49.8 205.7 2.4c-14.9-6.2-32-.3-40 13.6L79.1 166.5C48.9 219 65.7 284.3 113.6 319.2L74.9 421.1l-22.1-9.2c-20.4-8.5-43.7 1.2-52.2 21.6-1.7 4.1.2 8.8 4.3 10.5l162.3 67.4c4.1 1.7 8.7-.2 10.4-4.3 8.4-20.4-1.2-43.8-21.6-52.3l-22.1-9.2L173.3 342c4.4.5 8.8 1.3 13.1 1.3 51.7 0 99.4-33.1 113.4-85.3l20.2-75.4 20.2 75.4c14 52.2 61.7 85.3 113.4 85.3 4.3 0 8.7-.8 13.1-1.3L506 445.6l-22.1 9.2c-20.4 8.5-30.1 31.9-21.6 52.3 1.7 4.1 6.4 6 10.4 4.3L635.1 444c4-1.7 6-6.3 4.3-10.4zM275.9 162.1l-112.1-46.5 36.5-63.4 94.5 39.2-18.9 70.7zm88.2 0l-18.9-70.7 94.5-39.2 36.5 63.4-112.1 46.5z\"]\n};\nvar faGlassMartini = {\n prefix: 'fas',\n iconName: 'glass-martini',\n icon: [512, 512, [], \"f000\", \"M502.05 57.6C523.3 36.34 508.25 0 478.2 0H33.8C3.75 0-11.3 36.34 9.95 57.6L224 271.64V464h-56c-22.09 0-40 17.91-40 40 0 4.42 3.58 8 8 8h240c4.42 0 8-3.58 8-8 0-22.09-17.91-40-40-40h-56V271.64L502.05 57.6z\"]\n};\nvar faGlassMartiniAlt = {\n prefix: 'fas',\n iconName: 'glass-martini-alt',\n icon: [512, 512, [], \"f57b\", \"M502.05 57.6C523.3 36.34 508.25 0 478.2 0H33.8C3.75 0-11.3 36.34 9.95 57.6L224 271.64V464h-56c-22.09 0-40 17.91-40 40 0 4.42 3.58 8 8 8h240c4.42 0 8-3.58 8-8 0-22.09-17.91-40-40-40h-56V271.64L502.05 57.6zM443.77 48l-48 48H116.24l-48-48h375.53z\"]\n};\nvar faGlassWhiskey = {\n prefix: 'fas',\n iconName: 'glass-whiskey',\n icon: [512, 512, [], \"f7a0\", \"M480 32H32C12.5 32-2.4 49.2.3 68.5l56 356.5c4.5 31.5 31.5 54.9 63.4 54.9h273c31.8 0 58.9-23.4 63.4-54.9l55.6-356.5C514.4 49.2 499.5 32 480 32zm-37.4 64l-30 192h-313L69.4 96h373.2z\"]\n};\nvar faGlasses = {\n prefix: 'fas',\n iconName: 'glasses',\n icon: [576, 512, [], \"f530\", \"M574.1 280.37L528.75 98.66c-5.91-23.7-21.59-44.05-43-55.81-21.44-11.73-46.97-14.11-70.19-6.33l-15.25 5.08c-8.39 2.79-12.92 11.86-10.12 20.24l5.06 15.18c2.79 8.38 11.85 12.91 20.23 10.12l13.18-4.39c10.87-3.62 23-3.57 33.16 1.73 10.29 5.37 17.57 14.56 20.37 25.82l38.46 153.82c-22.19-6.81-49.79-12.46-81.2-12.46-34.77 0-73.98 7.02-114.85 26.74h-73.18c-40.87-19.74-80.08-26.75-114.86-26.75-31.42 0-59.02 5.65-81.21 12.46l38.46-153.83c2.79-11.25 10.09-20.45 20.38-25.81 10.16-5.3 22.28-5.35 33.15-1.73l13.17 4.39c8.38 2.79 17.44-1.74 20.23-10.12l5.06-15.18c2.8-8.38-1.73-17.45-10.12-20.24l-15.25-5.08c-23.22-7.78-48.75-5.41-70.19 6.33-21.41 11.77-37.09 32.11-43 55.8L1.9 280.37A64.218 64.218 0 0 0 0 295.86v70.25C0 429.01 51.58 480 115.2 480h37.12c60.28 0 110.37-45.94 114.88-105.37l2.93-38.63h35.75l2.93 38.63C313.31 434.06 363.4 480 423.68 480h37.12c63.62 0 115.2-50.99 115.2-113.88v-70.25c0-5.23-.64-10.43-1.9-15.5zm-370.72 89.42c-1.97 25.91-24.4 46.21-51.06 46.21H115.2C86.97 416 64 393.62 64 366.11v-37.54c18.12-6.49 43.42-12.92 72.58-12.92 23.86 0 47.26 4.33 69.93 12.92l-3.13 41.22zM512 366.12c0 27.51-22.97 49.88-51.2 49.88h-37.12c-26.67 0-49.1-20.3-51.06-46.21l-3.13-41.22c22.67-8.59 46.08-12.92 69.95-12.92 29.12 0 54.43 6.44 72.55 12.93v37.54z\"]\n};\nvar faGlobe = {\n prefix: 'fas',\n iconName: 'globe',\n icon: [496, 512, [], \"f0ac\", \"M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z\"]\n};\nvar faGlobeAfrica = {\n prefix: 'fas',\n iconName: 'globe-africa',\n icon: [496, 512, [], \"f57c\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm160 215.5v6.93c0 5.87-3.32 11.24-8.57 13.86l-15.39 7.7a15.485 15.485 0 0 1-15.53-.97l-18.21-12.14a15.52 15.52 0 0 0-13.5-1.81l-2.65.88c-9.7 3.23-13.66 14.79-7.99 23.3l13.24 19.86c2.87 4.31 7.71 6.9 12.89 6.9h8.21c8.56 0 15.5 6.94 15.5 15.5v11.34c0 3.35-1.09 6.62-3.1 9.3l-18.74 24.98c-1.42 1.9-2.39 4.1-2.83 6.43l-4.3 22.83c-.62 3.29-2.29 6.29-4.76 8.56a159.608 159.608 0 0 0-25 29.16l-13.03 19.55a27.756 27.756 0 0 1-23.09 12.36c-10.51 0-20.12-5.94-24.82-15.34a78.902 78.902 0 0 1-8.33-35.29V367.5c0-8.56-6.94-15.5-15.5-15.5h-25.88c-14.49 0-28.38-5.76-38.63-16a54.659 54.659 0 0 1-16-38.63v-14.06c0-17.19 8.1-33.38 21.85-43.7l27.58-20.69a54.663 54.663 0 0 1 32.78-10.93h.89c8.48 0 16.85 1.97 24.43 5.77l14.72 7.36c3.68 1.84 7.93 2.14 11.83.84l47.31-15.77c6.33-2.11 10.6-8.03 10.6-14.7 0-8.56-6.94-15.5-15.5-15.5h-10.09c-4.11 0-8.05-1.63-10.96-4.54l-6.92-6.92a15.493 15.493 0 0 0-10.96-4.54H199.5c-8.56 0-15.5-6.94-15.5-15.5v-4.4c0-7.11 4.84-13.31 11.74-15.04l14.45-3.61c3.74-.94 7-3.23 9.14-6.44l8.08-12.11c2.87-4.31 7.71-6.9 12.89-6.9h24.21c8.56 0 15.5-6.94 15.5-15.5v-21.7C359.23 71.63 422.86 131.02 441.93 208H423.5c-8.56 0-15.5 6.94-15.5 15.5z\"]\n};\nvar faGlobeAmericas = {\n prefix: 'fas',\n iconName: 'globe-americas',\n icon: [496, 512, [], \"f57d\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm82.29 357.6c-3.9 3.88-7.99 7.95-11.31 11.28-2.99 3-5.1 6.7-6.17 10.71-1.51 5.66-2.73 11.38-4.77 16.87l-17.39 46.85c-13.76 3-28 4.69-42.65 4.69v-27.38c1.69-12.62-7.64-36.26-22.63-51.25-6-6-9.37-14.14-9.37-22.63v-32.01c0-11.64-6.27-22.34-16.46-27.97-14.37-7.95-34.81-19.06-48.81-26.11-11.48-5.78-22.1-13.14-31.65-21.75l-.8-.72a114.792 114.792 0 0 1-18.06-20.74c-9.38-13.77-24.66-36.42-34.59-51.14 20.47-45.5 57.36-82.04 103.2-101.89l24.01 12.01C203.48 89.74 216 82.01 216 70.11v-11.3c7.99-1.29 16.12-2.11 24.39-2.42l28.3 28.3c6.25 6.25 6.25 16.38 0 22.63L264 112l-10.34 10.34c-3.12 3.12-3.12 8.19 0 11.31l4.69 4.69c3.12 3.12 3.12 8.19 0 11.31l-8 8a8.008 8.008 0 0 1-5.66 2.34h-8.99c-2.08 0-4.08.81-5.58 2.27l-9.92 9.65a8.008 8.008 0 0 0-1.58 9.31l15.59 31.19c2.66 5.32-1.21 11.58-7.15 11.58h-5.64c-1.93 0-3.79-.7-5.24-1.96l-9.28-8.06a16.017 16.017 0 0 0-15.55-3.1l-31.17 10.39a11.95 11.95 0 0 0-8.17 11.34c0 4.53 2.56 8.66 6.61 10.69l11.08 5.54c9.41 4.71 19.79 7.16 30.31 7.16s22.59 27.29 32 32h66.75c8.49 0 16.62 3.37 22.63 9.37l13.69 13.69a30.503 30.503 0 0 1 8.93 21.57 46.536 46.536 0 0 1-13.72 32.98zM417 274.25c-5.79-1.45-10.84-5-14.15-9.97l-17.98-26.97a23.97 23.97 0 0 1 0-26.62l19.59-29.38c2.32-3.47 5.5-6.29 9.24-8.15l12.98-6.49C440.2 193.59 448 223.87 448 256c0 8.67-.74 17.16-1.82 25.54L417 274.25z\"]\n};\nvar faGlobeAsia = {\n prefix: 'fas',\n iconName: 'globe-asia',\n icon: [496, 512, [], \"f57e\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm-11.34 240.23c-2.89 4.82-8.1 7.77-13.72 7.77h-.31c-4.24 0-8.31 1.69-11.31 4.69l-5.66 5.66c-3.12 3.12-3.12 8.19 0 11.31l5.66 5.66c3 3 4.69 7.07 4.69 11.31V304c0 8.84-7.16 16-16 16h-6.11c-6.06 0-11.6-3.42-14.31-8.85l-22.62-45.23c-2.44-4.88-8.95-5.94-12.81-2.08l-19.47 19.46c-3 3-7.07 4.69-11.31 4.69H50.81C49.12 277.55 48 266.92 48 256c0-110.28 89.72-200 200-200 21.51 0 42.2 3.51 61.63 9.82l-50.16 38.53c-5.11 3.41-4.63 11.06.86 13.81l10.83 5.41c5.42 2.71 8.84 8.25 8.84 14.31V216c0 4.42-3.58 8-8 8h-3.06c-3.03 0-5.8-1.71-7.15-4.42-1.56-3.12-5.96-3.29-7.76-.3l-17.37 28.95zM408 358.43c0 4.24-1.69 8.31-4.69 11.31l-9.57 9.57c-3 3-7.07 4.69-11.31 4.69h-15.16c-4.24 0-8.31-1.69-11.31-4.69l-13.01-13.01a26.767 26.767 0 0 0-25.42-7.04l-21.27 5.32c-1.27.32-2.57.48-3.88.48h-10.34c-4.24 0-8.31-1.69-11.31-4.69l-11.91-11.91a8.008 8.008 0 0 1-2.34-5.66v-10.2c0-3.27 1.99-6.21 5.03-7.43l39.34-15.74c1.98-.79 3.86-1.82 5.59-3.05l23.71-16.89a7.978 7.978 0 0 1 4.64-1.48h12.09c3.23 0 6.15 1.94 7.39 4.93l5.35 12.85a4 4 0 0 0 3.69 2.46h3.8c1.78 0 3.35-1.18 3.84-2.88l4.2-14.47c.5-1.71 2.06-2.88 3.84-2.88h6.06c2.21 0 4 1.79 4 4v12.93c0 2.12.84 4.16 2.34 5.66l11.91 11.91c3 3 4.69 7.07 4.69 11.31v24.6z\"]\n};\nvar faGlobeEurope = {\n prefix: 'fas',\n iconName: 'globe-europe',\n icon: [496, 512, [], \"f7a2\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm200 248c0 22.5-3.9 44.2-10.8 64.4h-20.3c-4.3 0-8.4-1.7-11.4-4.8l-32-32.6c-4.5-4.6-4.5-12.1.1-16.7l12.5-12.5v-8.7c0-3-1.2-5.9-3.3-8l-9.4-9.4c-2.1-2.1-5-3.3-8-3.3h-16c-6.2 0-11.3-5.1-11.3-11.3 0-3 1.2-5.9 3.3-8l9.4-9.4c2.1-2.1 5-3.3 8-3.3h32c6.2 0 11.3-5.1 11.3-11.3v-9.4c0-6.2-5.1-11.3-11.3-11.3h-36.7c-8.8 0-16 7.2-16 16v4.5c0 6.9-4.4 13-10.9 15.2l-31.6 10.5c-3.3 1.1-5.5 4.1-5.5 7.6v2.2c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8s-3.6-8-8-8H247c-3 0-5.8 1.7-7.2 4.4l-9.4 18.7c-2.7 5.4-8.2 8.8-14.3 8.8H194c-8.8 0-16-7.2-16-16V199c0-4.2 1.7-8.3 4.7-11.3l20.1-20.1c4.6-4.6 7.2-10.9 7.2-17.5 0-3.4 2.2-6.5 5.5-7.6l40-13.3c1.7-.6 3.2-1.5 4.4-2.7l26.8-26.8c2.1-2.1 3.3-5 3.3-8 0-6.2-5.1-11.3-11.3-11.3H258l-16 16v8c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8v-20c0-2.5 1.2-4.9 3.2-6.4l28.9-21.7c1.9-.1 3.8-.3 5.7-.3C358.3 56 448 145.7 448 256zM130.1 149.1c0-3 1.2-5.9 3.3-8l25.4-25.4c2.1-2.1 5-3.3 8-3.3 6.2 0 11.3 5.1 11.3 11.3v16c0 3-1.2 5.9-3.3 8l-9.4 9.4c-2.1 2.1-5 3.3-8 3.3h-16c-6.2 0-11.3-5.1-11.3-11.3zm128 306.4v-7.1c0-8.8-7.2-16-16-16h-20.2c-10.8 0-26.7-5.3-35.4-11.8l-22.2-16.7c-11.5-8.6-18.2-22.1-18.2-36.4v-23.9c0-16 8.4-30.8 22.1-39l42.9-25.7c7.1-4.2 15.2-6.5 23.4-6.5h31.2c10.9 0 21.4 3.9 29.6 10.9l43.2 37.1h18.3c8.5 0 16.6 3.4 22.6 9.4l17.3 17.3c3.4 3.4 8.1 5.3 12.9 5.3H423c-32.4 58.9-93.8 99.5-164.9 103.1z\"]\n};\nvar faGolfBall = {\n prefix: 'fas',\n iconName: 'golf-ball',\n icon: [416, 512, [], \"f450\", \"M96 416h224c0 17.7-14.3 32-32 32h-16c-17.7 0-32 14.3-32 32v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-20c0-17.7-14.3-32-32-32h-16c-17.7 0-32-14.3-32-32zm320-208c0 74.2-39 139.2-97.5 176h-221C39 347.2 0 282.2 0 208 0 93.1 93.1 0 208 0s208 93.1 208 208zm-180.1 43.9c18.3 0 33.1-14.8 33.1-33.1 0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1zm49.1 46.9c0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1 18.3 0 33.1-14.9 33.1-33.1zm64-64c0-14.4-9.3-26.3-22.1-30.9 9.6 26.8-15.6 51.3-41.9 41.9 4.6 12.8 16.5 22.1 30.9 22.1 18.3 0 33.1-14.9 33.1-33.1z\"]\n};\nvar faGopuram = {\n prefix: 'fas',\n iconName: 'gopuram',\n icon: [512, 512, [], \"f664\", \"M496 352h-16V240c0-8.8-7.2-16-16-16h-16v-80c0-8.8-7.2-16-16-16h-16V16c0-8.8-7.2-16-16-16s-16 7.2-16 16v16h-64V16c0-8.8-7.2-16-16-16s-16 7.2-16 16v16h-64V16c0-8.8-7.2-16-16-16s-16 7.2-16 16v16h-64V16c0-8.8-7.2-16-16-16S96 7.2 96 16v112H80c-8.8 0-16 7.2-16 16v80H48c-8.8 0-16 7.2-16 16v112H16c-8.8 0-16 7.2-16 16v128c0 8.8 7.2 16 16 16h80V352h32V224h32v-96h32v96h-32v128h-32v160h80v-80c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16v80h80V352h-32V224h-32v-96h32v96h32v128h32v160h80c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16zM232 176c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v48h-48zm56 176h-64v-64c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16z\"]\n};\nvar faGraduationCap = {\n prefix: 'fas',\n iconName: 'graduation-cap',\n icon: [640, 512, [], \"f19d\", \"M622.34 153.2L343.4 67.5c-15.2-4.67-31.6-4.67-46.79 0L17.66 153.2c-23.54 7.23-23.54 38.36 0 45.59l48.63 14.94c-10.67 13.19-17.23 29.28-17.88 46.9C38.78 266.15 32 276.11 32 288c0 10.78 5.68 19.85 13.86 25.65L20.33 428.53C18.11 438.52 25.71 448 35.94 448h56.11c10.24 0 17.84-9.48 15.62-19.47L82.14 313.65C90.32 307.85 96 298.78 96 288c0-11.57-6.47-21.25-15.66-26.87.76-15.02 8.44-28.3 20.69-36.72L296.6 284.5c9.06 2.78 26.44 6.25 46.79 0l278.95-85.7c23.55-7.24 23.55-38.36 0-45.6zM352.79 315.09c-28.53 8.76-52.84 3.92-65.59 0l-145.02-44.55L128 384c0 35.35 85.96 64 192 64s192-28.65 192-64l-14.18-113.47-145.03 44.56z\"]\n};\nvar faGreaterThan = {\n prefix: 'fas',\n iconName: 'greater-than',\n icon: [384, 512, [], \"f531\", \"M365.52 209.85L59.22 67.01c-16.06-7.49-35.15-.54-42.64 15.52L3.01 111.61c-7.49 16.06-.54 35.15 15.52 42.64L236.96 256.1 18.49 357.99C2.47 365.46-4.46 384.5 3.01 400.52l13.52 29C24 445.54 43.04 452.47 59.06 445l306.47-142.91a32.003 32.003 0 0 0 18.48-29v-34.23c-.01-12.45-7.21-23.76-18.49-29.01z\"]\n};\nvar faGreaterThanEqual = {\n prefix: 'fas',\n iconName: 'greater-than-equal',\n icon: [448, 512, [], \"f532\", \"M55.22 107.69l175.56 68.09-175.44 68.05c-18.39 6.03-27.88 24.39-21.2 41l12.09 30.08c6.68 16.61 26.99 25.19 45.38 19.15L393.02 214.2c13.77-4.52 22.98-16.61 22.98-30.17v-15.96c0-13.56-9.21-25.65-22.98-30.17L91.3 17.92c-18.29-6-38.51 2.53-45.15 19.06L34.12 66.9c-6.64 16.53 2.81 34.79 21.1 40.79zM424 400H24c-13.25 0-24 10.74-24 24v48c0 13.25 10.75 24 24 24h400c13.25 0 24-10.75 24-24v-48c0-13.26-10.75-24-24-24z\"]\n};\nvar faGrimace = {\n prefix: 'fas',\n iconName: 'grimace',\n icon: [496, 512, [], \"f57f\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM144 400h-8c-17.7 0-32-14.3-32-32v-8h40v40zm0-56h-40v-8c0-17.7 14.3-32 32-32h8v40zm-8-136c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm72 192h-48v-40h48v40zm0-56h-48v-40h48v40zm64 56h-48v-40h48v40zm0-56h-48v-40h48v40zm64 56h-48v-40h48v40zm0-56h-48v-40h48v40zm-8-104c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm64 128c0 17.7-14.3 32-32 32h-8v-40h40v8zm0-24h-40v-40h8c17.7 0 32 14.3 32 32v8z\"]\n};\nvar faGrin = {\n prefix: 'fas',\n iconName: 'grin',\n icon: [496, 512, [], \"f580\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm80 256c-60.6 0-134.5-38.3-143.8-93.3-2-11.8 9.3-21.6 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.3-3.7 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinAlt = {\n prefix: 'fas',\n iconName: 'grin-alt',\n icon: [496, 512, [], \"f581\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm63.7 128.7c7.6-11.4 24.7-11.7 32.7 0 12.4 18.4 15.1 36.9 15.7 55.3-.5 18.4-3.3 36.9-15.7 55.3-7.6 11.4-24.7 11.7-32.7 0-12.4-18.4-15.1-36.9-15.7-55.3.5-18.4 3.3-36.9 15.7-55.3zm-160 0c7.6-11.4 24.7-11.7 32.7 0 12.4 18.4 15.1 36.9 15.7 55.3-.5 18.4-3.3 36.9-15.7 55.3-7.6 11.4-24.7 11.7-32.7 0-12.4-18.4-15.1-36.9-15.7-55.3.5-18.4 3.3-36.9 15.7-55.3zM248 432c-60.6 0-134.5-38.3-143.8-93.3-2-11.8 9.3-21.6 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.4-3.7 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinBeam = {\n prefix: 'fas',\n iconName: 'grin-beam',\n icon: [496, 512, [], \"f582\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 144c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 11.9-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.1 7.3-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm-160 0c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 11.9-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm80 280c-60.6 0-134.5-38.3-143.8-93.3-2-11.9 9.4-21.6 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.4-3.7 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinBeamSweat = {\n prefix: 'fas',\n iconName: 'grin-beam-sweat',\n icon: [504, 512, [], \"f583\", \"M456 128c26.5 0 48-21 48-47 0-20-28.5-60.4-41.6-77.8-3.2-4.3-9.6-4.3-12.8 0C436.5 20.6 408 61 408 81c0 26 21.5 47 48 47zm0 32c-44.1 0-80-35.4-80-79 0-4.4.3-14.2 8.1-32.2C345 23.1 298.3 8 248 8 111 8 0 119 0 256s111 248 248 248 248-111 248-248c0-35.1-7.4-68.4-20.5-98.6-6.3 1.5-12.7 2.6-19.5 2.6zm-128-8c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 12-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.1 7.4-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm-160 0c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 12-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm80 280c-60.6 0-134.5-38.3-143.8-93.3-2-11.8 9.3-21.6 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.5-3.7 22.6 6.2 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinHearts = {\n prefix: 'fas',\n iconName: 'grin-hearts',\n icon: [496, 512, [], \"f584\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM90.4 183.6c6.7-17.6 26.7-26.7 44.9-21.9l7.1 1.9 2-7.1c5-18.1 22.8-30.9 41.5-27.9 21.4 3.4 34.4 24.2 28.8 44.5L195.3 243c-1.2 4.5-5.9 7.2-10.5 6l-70.2-18.2c-20.4-5.4-31.9-27-24.2-47.2zM248 432c-60.6 0-134.5-38.3-143.8-93.3-2-11.8 9.2-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.4-3.6 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3zm133.4-201.3l-70.2 18.2c-4.5 1.2-9.2-1.5-10.5-6L281.3 173c-5.6-20.3 7.4-41.1 28.8-44.5 18.6-3 36.4 9.8 41.5 27.9l2 7.1 7.1-1.9c18.2-4.7 38.2 4.3 44.9 21.9 7.7 20.3-3.8 41.9-24.2 47.2z\"]\n};\nvar faGrinSquint = {\n prefix: 'fas',\n iconName: 'grin-squint',\n icon: [496, 512, [], \"f585\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm33.8 189.7l80-48c11.6-6.9 24 7.7 15.4 18L343.6 208l33.6 40.3c8.7 10.4-3.9 24.8-15.4 18l-80-48c-7.7-4.7-7.7-15.9 0-20.6zm-163-30c-8.6-10.3 3.8-24.9 15.4-18l80 48c7.8 4.7 7.8 15.9 0 20.6l-80 48c-11.5 6.8-24-7.6-15.4-18l33.6-40.3-33.6-40.3zM248 432c-60.6 0-134.5-38.3-143.8-93.3-2-11.9 9.4-21.6 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.5-3.7 22.6 6.2 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinSquintTears = {\n prefix: 'fas',\n iconName: 'grin-squint-tears',\n icon: [512, 512, [], \"f586\", \"M409.6 111.9c22.6-3.2 73.5-12 88.3-26.8 19.2-19.2 18.9-50.6-.7-70.2S446-5 426.9 14.2c-14.8 14.8-23.5 65.7-26.8 88.3-.8 5.5 3.9 10.2 9.5 9.4zM102.4 400.1c-22.6 3.2-73.5 12-88.3 26.8-19.1 19.1-18.8 50.6.8 70.2s51 19.9 70.2.7c14.8-14.8 23.5-65.7 26.8-88.3.8-5.5-3.9-10.2-9.5-9.4zm311.7-256.5c-33 3.9-48.6-25.1-45.7-45.7 3.4-24 7.4-42.1 11.5-56.5C285.1-13.4 161.8-.5 80.6 80.6-.5 161.7-13.4 285 41.4 379.9c14.4-4.1 32.4-8 56.5-11.5 33.2-3.9 48.6 25.2 45.7 45.7-3.4 24-7.4 42.1-11.5 56.5 94.8 54.8 218.1 41.9 299.3-39.2s94-204.4 39.2-299.3c-14.4 4.1-32.5 8-56.5 11.5zM255.7 106c3.3-13.2 22.4-11.5 23.6 1.8l4.8 52.3 52.3 4.8c13.4 1.2 14.9 20.3 1.8 23.6l-90.5 22.6c-8.9 2.2-16.7-5.9-14.5-14.5l22.5-90.6zm-90.9 230.3L160 284l-52.3-4.8c-13.4-1.2-14.9-20.3-1.8-23.6l90.5-22.6c8.8-2.2 16.7 5.8 14.5 14.5L188.3 338c-3.1 13.2-22.2 11.7-23.5-1.7zm215.7 44.2c-29.3 29.3-75.7 50.4-116.7 50.4-18.9 0-36.6-4.5-51-14.7-9.8-6.9-8.7-21.8 2-27.2 28.3-14.6 63.9-42.4 97.8-76.3s61.7-69.6 76.3-97.8c5.4-10.5 20.2-11.9 27.3-2 32.3 45.3 7.1 124.7-35.7 167.6z\"]\n};\nvar faGrinStars = {\n prefix: 'fas',\n iconName: 'grin-stars',\n icon: [496, 512, [], \"f587\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM94.6 168.9l34.9-5 15.5-31.6c2.9-5.8 11-5.8 13.9 0l15.5 31.6 34.9 5c6.2 1 8.9 8.6 4.3 13.2l-25.4 24.6 6 34.9c1 6.2-5.3 11-11 7.9L152 233.3l-31.3 16.3c-5.7 3.1-12-1.7-11-7.9l6-34.9-25.4-24.6c-4.6-4.7-1.9-12.3 4.3-13.3zM248 432c-60.6 0-134.5-38.3-143.8-93.3-2-11.8 9.3-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.5-3.7 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3zm157.7-249.9l-25.4 24.6 6 34.9c1 6.2-5.3 11-11 7.9L344 233.3l-31.3 16.3c-5.7 3.1-12-1.7-11-7.9l6-34.9-25.4-24.6c-4.5-4.6-1.9-12.2 4.3-13.2l34.9-5 15.5-31.6c2.9-5.8 11-5.8 13.9 0l15.5 31.6 34.9 5c6.3.9 9 8.5 4.4 13.1z\"]\n};\nvar faGrinTears = {\n prefix: 'fas',\n iconName: 'grin-tears',\n icon: [640, 512, [], \"f588\", \"M102.4 256.1c-22.6 3.2-73.5 12-88.3 26.8-19.1 19.1-18.8 50.6.8 70.2s51 19.9 70.2.7c14.8-14.8 23.5-65.7 26.8-88.3.8-5.5-3.9-10.2-9.5-9.4zm523.4 26.8c-14.8-14.8-65.7-23.5-88.3-26.8-5.5-.8-10.3 3.9-9.5 9.5 3.2 22.6 12 73.5 26.8 88.3 19.2 19.2 50.6 18.9 70.2-.7s20-51.2.8-70.3zm-129.4-12.8c-3.8-26.6 19.1-49.5 45.7-45.7 8.9 1.3 16.8 2.7 24.3 4.1C552.7 104.5 447.7 8 320 8S87.3 104.5 73.6 228.5c7.5-1.4 15.4-2.8 24.3-4.1 33.2-3.9 48.6 25.3 45.7 45.7-11.8 82.3-29.9 100.4-35.8 106.4-.9.9-2 1.6-3 2.5 42.7 74.6 123 125 215.2 125s172.5-50.4 215.2-125.1c-1-.9-2.1-1.5-3-2.5-5.9-5.9-24-24-35.8-106.3zM400 152c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 12-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm-160 0c23.8 0 52.7 29.3 56 71.4.7 8.6-10.8 12-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.6 4-14.9-4.5 3.1-42.1 32-71.4 55.8-71.4zm80 280c-60.6 0-134.5-38.3-143.8-93.3-2-11.7 9.2-21.6 20.7-17.9C227.1 330.5 272 336 320 336s92.9-5.5 123.1-15.2c11.4-3.7 22.6 6.1 20.7 17.9-9.3 55-83.2 93.3-143.8 93.3z\"]\n};\nvar faGrinTongue = {\n prefix: 'fas',\n iconName: 'grin-tongue',\n icon: [496, 512, [], \"f589\", \"M248 8C111 8 0 119 0 256c0 106.3 67 196.7 161 232-5.6-12.2-9-25.7-9-40v-45.5c-24.7-16.2-43.5-38.1-47.8-63.8-2-11.8 9.3-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.4-3.6 22.6 6.1 20.7 17.9-4.3 25.7-23.1 47.6-47.8 63.8V448c0 14.3-3.4 27.8-9 40 94-35.3 161-125.7 161-232C496 119 385 8 248 8zm-80 232c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm160 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm-34.9 134.6c-14.4-6.5-31.1 2.2-34.6 17.6l-1.8 7.8c-2.1 9.2-15.2 9.2-17.3 0l-1.8-7.8c-3.5-15.4-20.2-24.1-34.6-17.6-.9.4.3-.2-18.9 9.4v63c0 35.2 28 64.5 63.1 64.9 35.7.5 64.9-28.4 64.9-64v-64c-19.5-9.6-18.2-8.9-19-9.3z\"]\n};\nvar faGrinTongueSquint = {\n prefix: 'fas',\n iconName: 'grin-tongue-squint',\n icon: [496, 512, [], \"f58a\", \"M293.1 374.6c-14.4-6.5-31.1 2.2-34.6 17.6l-1.8 7.8c-2.1 9.2-15.2 9.2-17.3 0l-1.8-7.8c-3.5-15.4-20.2-24.1-34.6-17.6-.9.4.3-.2-18.9 9.4v63c0 35.2 28 64.5 63.1 64.9 35.7.5 64.9-28.4 64.9-64v-64c-19.5-9.6-18.2-8.9-19-9.3zM248 8C111 8 0 119 0 256c0 106.3 67 196.7 161 232-5.6-12.2-9-25.7-9-40v-45.5c-24.7-16.2-43.5-38.1-47.8-63.8-2-11.8 9.2-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.4-3.7 22.6 6.1 20.7 17.9-4.3 25.7-23.1 47.6-47.8 63.8V448c0 14.3-3.4 27.8-9 40 94-35.3 161-125.7 161-232C496 119 385 8 248 8zm-33.8 210.3l-80 48c-11.5 6.8-24-7.6-15.4-18l33.6-40.3-33.6-40.3c-8.6-10.3 3.8-24.9 15.4-18l80 48c7.7 4.7 7.7 15.9 0 20.6zm163 30c8.7 10.4-3.9 24.8-15.4 18l-80-48c-7.8-4.7-7.8-15.9 0-20.6l80-48c11.7-6.9 23.9 7.7 15.4 18L343.6 208l33.6 40.3z\"]\n};\nvar faGrinTongueWink = {\n prefix: 'fas',\n iconName: 'grin-tongue-wink',\n icon: [496, 512, [], \"f58b\", \"M344 184c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM248 8C111 8 0 119 0 256c0 106.3 67 196.7 161 232-5.6-12.2-9-25.7-9-40v-45.5c-24.7-16.2-43.5-38.1-47.8-63.8-2-11.8 9.3-21.5 20.7-17.9C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.5-3.7 22.6 6.1 20.7 17.9-4.3 25.7-23.1 47.6-47.8 63.8V448c0 14.3-3.4 27.8-9 40 94-35.3 161-125.7 161-232C496 119 385 8 248 8zm-56 225l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L112 233c-8.5 7.4-21.6.3-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S208 197 212 222.2c1.6 11.1-11.6 18.2-20 10.8zm152 39c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm-50.9 102.6c-14.4-6.5-31.1 2.2-34.6 17.6l-1.8 7.8c-2.1 9.2-15.2 9.2-17.3 0l-1.8-7.8c-3.5-15.4-20.2-24.1-34.6-17.6-.9.4.3-.2-18.9 9.4v63c0 35.2 28 64.5 63.1 64.9 35.7.5 64.9-28.4 64.9-64v-64c-19.5-9.6-18.2-8.9-19-9.3z\"]\n};\nvar faGrinWink = {\n prefix: 'fas',\n iconName: 'grin-wink',\n icon: [496, 512, [], \"f58c\", \"M0 256c0 137 111 248 248 248s248-111 248-248S385 8 248 8 0 119 0 256zm200-48c0 17.7-14.3 32-32 32s-32-14.3-32-32 14.3-32 32-32 32 14.3 32 32zm168 25l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L288 233c-8.3 7.4-21.6.4-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S384 197 388 222.2c1.6 11-11.5 18.2-20 10.8zm-243.1 87.8C155.1 330.5 200 336 248 336s92.9-5.5 123.1-15.2c11.3-3.7 22.6 6 20.7 17.9-9.2 55-83.2 93.3-143.8 93.3s-134.5-38.3-143.8-93.3c-2-11.9 9.3-21.6 20.7-17.9z\"]\n};\nvar faGripHorizontal = {\n prefix: 'fas',\n iconName: 'grip-horizontal',\n icon: [448, 512, [], \"f58d\", \"M96 288H32c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm160 0h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm160 0h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zM96 96H32c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm160 0h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm160 0h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32z\"]\n};\nvar faGripLines = {\n prefix: 'fas',\n iconName: 'grip-lines',\n icon: [512, 512, [], \"f7a4\", \"M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z\"]\n};\nvar faGripLinesVertical = {\n prefix: 'fas',\n iconName: 'grip-lines-vertical',\n icon: [256, 512, [], \"f7a5\", \"M96 496V16c0-8.8-7.2-16-16-16H48c-8.8 0-16 7.2-16 16v480c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16zm128 0V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v480c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16z\"]\n};\nvar faGripVertical = {\n prefix: 'fas',\n iconName: 'grip-vertical',\n icon: [320, 512, [], \"f58e\", \"M96 32H32C14.33 32 0 46.33 0 64v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32V64c0-17.67-14.33-32-32-32zm0 160H32c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm0 160H32c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zM288 32h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32V64c0-17.67-14.33-32-32-32zm0 160h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32zm0 160h-64c-17.67 0-32 14.33-32 32v64c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-64c0-17.67-14.33-32-32-32z\"]\n};\nvar faGuitar = {\n prefix: 'fas',\n iconName: 'guitar',\n icon: [512, 512, [], \"f7a6\", \"M502.6 54.6L457.4 9.4c-12.5-12.5-32.8-12.5-45.3 0l-67.9 67.9c-12.5 12.5-12.5 32.8 0 45.3L290 176.7c-45.4-29-100.4-28.9-133.5 4.2-9.7 9.7-16.4 21.2-20.5 33.9-6.1 18.8-23.5 33.1-42.7 34.9-24 2.3-46.3 11.6-63.4 28.8C-16.3 324.6-8 407.6 48.2 463.8c56.2 56.2 139.2 64.4 185.3 18.3 17.2-17.1 26.5-39.4 28.8-63.5 1.8-19.1 16.1-36.6 34.9-42.7 12.7-4.1 24.2-10.8 33.9-20.5 33.1-33.1 33.1-88.1 4.2-133.5l54.2-54.2c12.5 12.5 32.8 12.5 45.3 0l67.9-67.9c12.4-12.4 12.4-32.7-.1-45.2zM208 352c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z\"]\n};\nvar faHSquare = {\n prefix: 'fas',\n iconName: 'h-square',\n icon: [448, 512, [], \"f0fd\", \"M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z\"]\n};\nvar faHamburger = {\n prefix: 'fas',\n iconName: 'hamburger',\n icon: [512, 512, [], \"f805\", \"M464 256H48a48 48 0 0 0 0 96h416a48 48 0 0 0 0-96zm16 128H32a16 16 0 0 0-16 16v16a64 64 0 0 0 64 64h352a64 64 0 0 0 64-64v-16a16 16 0 0 0-16-16zM58.64 224h394.72c34.57 0 54.62-43.9 34.82-75.88C448 83.2 359.55 32.1 256 32c-103.54.1-192 51.2-232.18 116.11C4 180.09 24.07 224 58.64 224zM384 112a16 16 0 1 1-16 16 16 16 0 0 1 16-16zM256 80a16 16 0 1 1-16 16 16 16 0 0 1 16-16zm-128 32a16 16 0 1 1-16 16 16 16 0 0 1 16-16z\"]\n};\nvar faHammer = {\n prefix: 'fas',\n iconName: 'hammer',\n icon: [576, 512, [], \"f6e3\", \"M571.31 193.94l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31-28.9-28.9c5.63-21.31.36-44.9-16.35-61.61l-45.25-45.25c-62.48-62.48-163.79-62.48-226.28 0l90.51 45.25v18.75c0 16.97 6.74 33.25 18.75 45.25l49.14 49.14c16.71 16.71 40.3 21.98 61.61 16.35l28.9 28.9-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l90.51-90.51c6.23-6.24 6.23-16.37-.02-22.62zm-286.72-15.2c-3.7-3.7-6.84-7.79-9.85-11.95L19.64 404.96c-25.57 23.88-26.26 64.19-1.53 88.93s65.05 24.05 88.93-1.53l238.13-255.07c-3.96-2.91-7.9-5.87-11.44-9.41l-49.14-49.14z\"]\n};\nvar faHamsa = {\n prefix: 'fas',\n iconName: 'hamsa',\n icon: [512, 512, [], \"f665\", \"M509.34 307.25C504.28 295.56 492.75 288 480 288h-64V80c0-22-18-40-40-40s-40 18-40 40v134c0 5.52-4.48 10-10 10h-20c-5.52 0-10-4.48-10-10V40c0-22-18-40-40-40s-40 18-40 40v174c0 5.52-4.48 10-10 10h-20c-5.52 0-10-4.48-10-10V80c0-22-18-40-40-40S96 58 96 80v208H32c-12.75 0-24.28 7.56-29.34 19.25a31.966 31.966 0 0 0 5.94 34.58l102.69 110.03C146.97 490.08 199.69 512 256 512s109.03-21.92 144.72-60.14L503.4 341.83a31.966 31.966 0 0 0 5.94-34.58zM256 416c-53.02 0-96-64-96-64s42.98-64 96-64 96 64 96 64-42.98 64-96 64zm0-96c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z\"]\n};\nvar faHandHolding = {\n prefix: 'fas',\n iconName: 'hand-holding',\n icon: [576, 512, [], \"f4bd\", \"M565.3 328.1c-11.8-10.7-30.2-10-42.6 0L430.3 402c-11.3 9.1-25.4 14-40 14H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h78.3c15.9 0 30.7-10.9 33.3-26.6 3.3-20-12.1-37.4-31.6-37.4H192c-27 0-53.1 9.3-74.1 26.3L71.4 384H16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h356.8c14.5 0 28.6-4.9 40-14L564 377c15.2-12.1 16.4-35.3 1.3-48.9z\"]\n};\nvar faHandHoldingHeart = {\n prefix: 'fas',\n iconName: 'hand-holding-heart',\n icon: [576, 512, [], \"f4be\", \"M275.3 250.5c7 7.4 18.4 7.4 25.5 0l108.9-114.2c31.6-33.2 29.8-88.2-5.6-118.8-30.8-26.7-76.7-21.9-104.9 7.7L288 36.9l-11.1-11.6C248.7-4.4 202.8-9.2 172 17.5c-35.3 30.6-37.2 85.6-5.6 118.8l108.9 114.2zm290 77.6c-11.8-10.7-30.2-10-42.6 0L430.3 402c-11.3 9.1-25.4 14-40 14H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h78.3c15.9 0 30.7-10.9 33.3-26.6 3.3-20-12.1-37.4-31.6-37.4H192c-27 0-53.1 9.3-74.1 26.3L71.4 384H16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h356.8c14.5 0 28.6-4.9 40-14L564 377c15.2-12.1 16.4-35.3 1.3-48.9z\"]\n};\nvar faHandHoldingUsd = {\n prefix: 'fas',\n iconName: 'hand-holding-usd',\n icon: [544, 512, [], \"f4c0\", \"M257.6 144.3l50 14.3c3.6 1 6.1 4.4 6.1 8.1 0 4.6-3.8 8.4-8.4 8.4h-32.8c-3.6 0-7.1-.8-10.3-2.2-4.8-2.2-10.4-1.7-14.1 2l-17.5 17.5c-5.3 5.3-4.7 14.3 1.5 18.4 9.5 6.3 20.3 10.1 31.8 11.5V240c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16v-17.6c30.3-3.6 53.3-31 49.3-63-2.9-23-20.7-41.3-42.9-47.7l-50-14.3c-3.6-1-6.1-4.4-6.1-8.1 0-4.6 3.8-8.4 8.4-8.4h32.8c3.6 0 7.1.8 10.3 2.2 4.8 2.2 10.4 1.7 14.1-2l17.5-17.5c5.3-5.3 4.7-14.3-1.5-18.4-9.5-6.3-20.3-10.1-31.8-11.5V16c0-8.8-7.2-16-16-16h-16c-8.8 0-16 7.2-16 16v17.6c-30.3 3.6-53.3 31-49.3 63 2.9 23 20.7 41.3 42.9 47.7zm276.3 183.8c-11.2-10.7-28.5-10-40.3 0L406.4 402c-10.7 9.1-24 14-37.8 14H256.9c-8.3 0-15.1-7.2-15.1-16s6.8-16 15.1-16h73.9c15.1 0 29-10.9 31.4-26.6 3.1-20-11.5-37.4-29.8-37.4H181.3c-25.5 0-50.2 9.3-69.9 26.3L67.5 384H15.1C6.8 384 0 391.2 0 400v96c0 8.8 6.8 16 15.1 16H352c13.7 0 27-4.9 37.8-14l142.8-121c14.4-12.1 15.5-35.3 1.3-48.9z\"]\n};\nvar faHandLizard = {\n prefix: 'fas',\n iconName: 'hand-lizard',\n icon: [576, 512, [], \"f258\", \"M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z\"]\n};\nvar faHandMiddleFinger = {\n prefix: 'fas',\n iconName: 'hand-middle-finger',\n icon: [512, 512, [], \"f806\", \"M479.93 317.12a37.33 37.33 0 0 0-28.28-36.19L416 272v-49.59c0-11.44-9.69-21.29-23.15-23.54l-38.4-6.4C336.63 189.5 320 200.86 320 216v32a8 8 0 0 1-16 0V50c0-26.28-20.25-49.2-46.52-50A48 48 0 0 0 208 48v200a8 8 0 0 1-16 0v-32c0-15.15-16.63-26.51-34.45-23.54l-30.68 5.12c-18 3-30.87 16.12-30.87 31.38V376a8 8 0 0 1-16 0v-76l-27.36 15A37.34 37.34 0 0 0 32 348.4v73.47a37.31 37.31 0 0 0 10.93 26.39l30.93 30.93A112 112 0 0 0 153.05 512h215A112 112 0 0 0 480 400z\"]\n};\nvar faHandPaper = {\n prefix: 'fas',\n iconName: 'hand-paper',\n icon: [448, 512, [], \"f256\", \"M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z\"]\n};\nvar faHandPeace = {\n prefix: 'fas',\n iconName: 'hand-peace',\n icon: [448, 512, [], \"f25b\", \"M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z\"]\n};\nvar faHandPointDown = {\n prefix: 'fas',\n iconName: 'hand-point-down',\n icon: [384, 512, [], \"f0a7\", \"M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z\"]\n};\nvar faHandPointLeft = {\n prefix: 'fas',\n iconName: 'hand-point-left',\n icon: [512, 512, [], \"f0a5\", \"M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z\"]\n};\nvar faHandPointRight = {\n prefix: 'fas',\n iconName: 'hand-point-right',\n icon: [512, 512, [], \"f0a4\", \"M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z\"]\n};\nvar faHandPointUp = {\n prefix: 'fas',\n iconName: 'hand-point-up',\n icon: [384, 512, [], \"f0a6\", \"M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z\"]\n};\nvar faHandPointer = {\n prefix: 'fas',\n iconName: 'hand-pointer',\n icon: [448, 512, [], \"f25a\", \"M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z\"]\n};\nvar faHandRock = {\n prefix: 'fas',\n iconName: 'hand-rock',\n icon: [512, 512, [], \"f255\", \"M464.8 80c-26.9-.4-48.8 21.2-48.8 48h-8V96.8c0-26.3-20.9-48.3-47.2-48.8-26.9-.4-48.8 21.2-48.8 48v32h-8V80.8c0-26.3-20.9-48.3-47.2-48.8-26.9-.4-48.8 21.2-48.8 48v48h-8V96.8c0-26.3-20.9-48.3-47.2-48.8-26.9-.4-48.8 21.2-48.8 48v136l-8-7.1v-48.1c0-26.3-20.9-48.3-47.2-48.8C21.9 127.6 0 149.2 0 176v66.4c0 27.4 11.7 53.5 32.2 71.8l111.7 99.3c10.2 9.1 16.1 22.2 16.1 35.9v6.7c0 13.3 10.7 24 24 24h240c13.3 0 24-10.7 24-24v-2.9c0-12.8 2.6-25.5 7.5-37.3l49-116.3c5-11.8 7.5-24.5 7.5-37.3V128.8c0-26.3-20.9-48.4-47.2-48.8z\"]\n};\nvar faHandScissors = {\n prefix: 'fas',\n iconName: 'hand-scissors',\n icon: [512, 512, [], \"f257\", \"M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z\"]\n};\nvar faHandSpock = {\n prefix: 'fas',\n iconName: 'hand-spock',\n icon: [512, 512, [], \"f259\", \"M481.3 97.1c-21.5-5.1-43.1 8.2-48.2 29.6L402.3 256h-11.1l43.6-174.3c5.4-21.4-7.7-43.1-29.1-48.5s-43.1 7.7-48.5 29.1L308.8 256h-15.1L242 31.1c-5-21.6-26.4-35-48-30.1-21.5 4.9-35 26.4-30 47.9l47.6 207h-9.8L167 103.1c-4.9-21.5-26.3-35-47.9-30.1-21.5 4.9-35 26.3-30.1 47.9l39 171.6v79.4l-60.6-57c-16.1-15.1-41.4-14.4-56.5 1.7s-14.4 41.4 1.7 56.5L146.3 499c8.9 8.4 20.7 13 32.9 13h216.7c21.3 0 40-14 46-34.4l26.2-88.3c2.6-8.9 4-18 4-27.3v-42c0-7.5.9-15 2.6-22.2L511 145.3c5-21.5-8.3-43.1-29.7-48.2z\"]\n};\nvar faHands = {\n prefix: 'fas',\n iconName: 'hands',\n icon: [640, 512, [], \"f4c2\", \"M204.8 230.4c-10.6-14.1-30.7-17-44.8-6.4-14.1 10.6-17 30.7-6.4 44.8l38.1 50.8c4.8 6.4 4.1 15.3-1.5 20.9l-12.8 12.8c-6.7 6.7-17.6 6.2-23.6-1.1L64 244.4V96c0-17.7-14.3-32-32-32S0 78.3 0 96v218.4c0 10.9 3.7 21.5 10.5 30l104.1 134.3c5 6.5 8.4 13.9 10.4 21.7 1.8 6.9 8.1 11.6 15.3 11.6H272c8.8 0 16-7.2 16-16V384c0-27.7-9-54.6-25.6-76.8l-57.6-76.8zM608 64c-17.7 0-32 14.3-32 32v148.4l-89.8 107.8c-6 7.2-17 7.7-23.6 1.1l-12.8-12.8c-5.6-5.6-6.3-14.5-1.5-20.9l38.1-50.8c10.6-14.1 7.7-34.2-6.4-44.8-14.1-10.6-34.2-7.7-44.8 6.4l-57.6 76.8C361 329.4 352 356.3 352 384v112c0 8.8 7.2 16 16 16h131.7c7.1 0 13.5-4.7 15.3-11.6 2-7.8 5.4-15.2 10.4-21.7l104.1-134.3c6.8-8.5 10.5-19.1 10.5-30V96c0-17.7-14.3-32-32-32z\"]\n};\nvar faHandsHelping = {\n prefix: 'fas',\n iconName: 'hands-helping',\n icon: [640, 512, [], \"f4c4\", \"M488 192H336v56c0 39.7-32.3 72-72 72s-72-32.3-72-72V126.4l-64.9 39C107.8 176.9 96 197.8 96 220.2v47.3l-80 46.2C.7 322.5-4.6 342.1 4.3 357.4l80 138.6c8.8 15.3 28.4 20.5 43.7 11.7L231.4 448H368c35.3 0 64-28.7 64-64h16c17.7 0 32-14.3 32-32v-64h8c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zm147.7-37.4L555.7 16C546.9.7 527.3-4.5 512 4.3L408.6 64H306.4c-12 0-23.7 3.4-33.9 9.7L239 94.6c-9.4 5.8-15 16.1-15 27.1V248c0 22.1 17.9 40 40 40s40-17.9 40-40v-88h184c30.9 0 56 25.1 56 56v28.5l80-46.2c15.3-8.9 20.5-28.4 11.7-43.7z\"]\n};\nvar faHandshake = {\n prefix: 'fas',\n iconName: 'handshake',\n icon: [640, 512, [], \"f2b5\", \"M434.7 64h-85.9c-8 0-15.7 3-21.6 8.4l-98.3 90c-.1.1-.2.3-.3.4-16.6 15.6-16.3 40.5-2.1 56 12.7 13.9 39.4 17.6 56.1 2.7.1-.1.3-.1.4-.2l79.9-73.2c6.5-5.9 16.7-5.5 22.6 1 6 6.5 5.5 16.6-1 22.6l-26.1 23.9L504 313.8c2.9 2.4 5.5 5 7.9 7.7V128l-54.6-54.6c-5.9-6-14.1-9.4-22.6-9.4zM544 128.2v223.9c0 17.7 14.3 32 32 32h64V128.2h-96zm48 223.9c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zM0 384h64c17.7 0 32-14.3 32-32V128.2H0V384zm48-63.9c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16c0-8.9 7.2-16 16-16zm435.9 18.6L334.6 217.5l-30 27.5c-29.7 27.1-75.2 24.5-101.7-4.4-26.9-29.4-24.8-74.9 4.4-101.7L289.1 64h-83.8c-8.5 0-16.6 3.4-22.6 9.4L128 128v223.9h18.3l90.5 81.9c27.4 22.3 67.7 18.1 90-9.3l.2-.2 17.9 15.5c15.9 13 39.4 10.5 52.3-5.4l31.4-38.6 5.4 4.4c13.7 11.1 33.9 9.1 45-4.7l9.5-11.7c11.2-13.8 9.1-33.9-4.6-45.1z\"]\n};\nvar faHanukiah = {\n prefix: 'fas',\n iconName: 'hanukiah',\n icon: [640, 512, [], \"f6e6\", \"M232 160c-4.42 0-8 3.58-8 8v120h32V168c0-4.42-3.58-8-8-8h-16zm-64 0c-4.42 0-8 3.58-8 8v120h32V168c0-4.42-3.58-8-8-8h-16zm224 0c-4.42 0-8 3.58-8 8v120h32V168c0-4.42-3.58-8-8-8h-16zm64 0c-4.42 0-8 3.58-8 8v120h32V168c0-4.42-3.58-8-8-8h-16zm88 8c0-4.42-3.58-8-8-8h-16c-4.42 0-8 3.58-8 8v120h32V168zm-440-8c-4.42 0-8 3.58-8 8v120h32V168c0-4.42-3.58-8-8-8h-16zm520 0h-32c-8.84 0-16 7.16-16 16v112c0 17.67-14.33 32-32 32H352V128c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v192H96c-17.67 0-32-14.33-32-32V176c0-8.84-7.16-16-16-16H16c-8.84 0-16 7.16-16 16v112c0 53.02 42.98 96 96 96h192v64H112c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16H352v-64h192c53.02 0 96-42.98 96-96V176c0-8.84-7.16-16-16-16zm-16-32c13.25 0 24-11.94 24-26.67S608 48 608 48s-24 38.61-24 53.33S594.75 128 608 128zm-576 0c13.25 0 24-11.94 24-26.67S32 48 32 48 8 86.61 8 101.33 18.75 128 32 128zm288-48c13.25 0 24-11.94 24-26.67S320 0 320 0s-24 38.61-24 53.33S306.75 80 320 80zm-208 48c13.25 0 24-11.94 24-26.67S112 48 112 48s-24 38.61-24 53.33S98.75 128 112 128zm64 0c13.25 0 24-11.94 24-26.67S176 48 176 48s-24 38.61-24 53.33S162.75 128 176 128zm64 0c13.25 0 24-11.94 24-26.67S240 48 240 48s-24 38.61-24 53.33S226.75 128 240 128zm160 0c13.25 0 24-11.94 24-26.67S400 48 400 48s-24 38.61-24 53.33S386.75 128 400 128zm64 0c13.25 0 24-11.94 24-26.67S464 48 464 48s-24 38.61-24 53.33S450.75 128 464 128zm64 0c13.25 0 24-11.94 24-26.67S528 48 528 48s-24 38.61-24 53.33S514.75 128 528 128z\"]\n};\nvar faHardHat = {\n prefix: 'fas',\n iconName: 'hard-hat',\n icon: [512, 512, [], \"f807\", \"M480 288c0-80.25-49.28-148.92-119.19-177.62L320 192V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v112l-40.81-81.62C81.28 139.08 32 207.75 32 288v64h448zm16 96H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h480a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faHashtag = {\n prefix: 'fas',\n iconName: 'hashtag',\n icon: [448, 512, [], \"f292\", \"M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z\"]\n};\nvar faHatWizard = {\n prefix: 'fas',\n iconName: 'hat-wizard',\n icon: [512, 512, [], \"f6e8\", \"M496 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h480c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-304-64l-64-32 64-32 32-64 32 64 64 32-64 32-16 32h208l-86.41-201.63a63.955 63.955 0 0 1-1.89-45.45L416 0 228.42 107.19a127.989 127.989 0 0 0-53.46 59.15L64 416h144l-16-32zm64-224l16-32 16 32 32 16-32 16-16 32-16-32-32-16 32-16z\"]\n};\nvar faHaykal = {\n prefix: 'fas',\n iconName: 'haykal',\n icon: [512, 512, [], \"f666\", \"M496.25 202.52l-110-15.44 41.82-104.34c6.67-16.64-11.6-32.18-26.59-22.63L307.44 120 273.35 12.82C270.64 4.27 263.32 0 256 0c-7.32 0-14.64 4.27-17.35 12.82l-34.09 107.19-94.04-59.89c-14.99-9.55-33.25 5.99-26.59 22.63l41.82 104.34-110 15.43c-17.54 2.46-21.68 26.27-6.03 34.67l98.16 52.66-74.48 83.54c-10.92 12.25-1.72 30.93 13.29 30.93 1.31 0 2.67-.14 4.07-.45l108.57-23.65-4.11 112.55c-.43 11.65 8.87 19.22 18.41 19.22 5.15 0 10.39-2.21 14.2-7.18l68.18-88.9 68.18 88.9c3.81 4.97 9.04 7.18 14.2 7.18 9.54 0 18.84-7.57 18.41-19.22l-4.11-112.55 108.57 23.65c17.36 3.76 29.21-17.2 17.35-30.49l-74.48-83.54 98.16-52.66c15.64-8.39 11.5-32.2-6.04-34.66zM338.51 311.68l-51.89-11.3 1.97 53.79L256 311.68l-32.59 42.49 1.96-53.79-51.89 11.3 35.6-39.93-46.92-25.17 52.57-7.38-19.99-49.87 44.95 28.62L256 166.72l16.29 51.23 44.95-28.62-19.99 49.87 52.57 7.38-46.92 25.17 35.61 39.93z\"]\n};\nvar faHdd = {\n prefix: 'fas',\n iconName: 'hdd',\n icon: [576, 512, [], \"f0a0\", \"M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z\"]\n};\nvar faHeading = {\n prefix: 'fas',\n iconName: 'heading',\n icon: [512, 512, [], \"f1dc\", \"M448 96v320h32a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H320a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32V288H160v128h32a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32V96H32a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h160a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16h-32v128h192V96h-32a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h160a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16z\"]\n};\nvar faHeadphones = {\n prefix: 'fas',\n iconName: 'headphones',\n icon: [512, 512, [], \"f025\", \"M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z\"]\n};\nvar faHeadphonesAlt = {\n prefix: 'fas',\n iconName: 'headphones-alt',\n icon: [512, 512, [], \"f58f\", \"M160 288h-16c-35.35 0-64 28.7-64 64.12v63.76c0 35.41 28.65 64.12 64 64.12h16c17.67 0 32-14.36 32-32.06V320.06c0-17.71-14.33-32.06-32-32.06zm208 0h-16c-17.67 0-32 14.35-32 32.06v127.88c0 17.7 14.33 32.06 32 32.06h16c35.35 0 64-28.71 64-64.12v-63.76c0-35.41-28.65-64.12-64-64.12zM256 32C112.91 32 4.57 151.13 0 288v112c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16V288c0-114.67 93.33-207.8 208-207.82 114.67.02 208 93.15 208 207.82v112c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16V288C507.43 151.13 399.09 32 256 32z\"]\n};\nvar faHeadset = {\n prefix: 'fas',\n iconName: 'headset',\n icon: [512, 512, [], \"f590\", \"M192 208c0-17.67-14.33-32-32-32h-16c-35.35 0-64 28.65-64 64v48c0 35.35 28.65 64 64 64h16c17.67 0 32-14.33 32-32V208zm176 144c35.35 0 64-28.65 64-64v-48c0-35.35-28.65-64-64-64h-16c-17.67 0-32 14.33-32 32v112c0 17.67 14.33 32 32 32h16zM256 0C113.18 0 4.58 118.83 0 256v16c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-16c0-114.69 93.31-208 208-208s208 93.31 208 208h-.12c.08 2.43.12 165.72.12 165.72 0 23.35-18.93 42.28-42.28 42.28H320c0-26.51-21.49-48-48-48h-32c-26.51 0-48 21.49-48 48s21.49 48 48 48h181.72c49.86 0 90.28-40.42 90.28-90.28V256C507.42 118.83 398.82 0 256 0z\"]\n};\nvar faHeart = {\n prefix: 'fas',\n iconName: 'heart',\n icon: [512, 512, [], \"f004\", \"M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z\"]\n};\nvar faHeartBroken = {\n prefix: 'fas',\n iconName: 'heart-broken',\n icon: [512, 512, [], \"f7a9\", \"M473.7 73.8l-2.4-2.5c-46-47-118-51.7-169.6-14.8L336 159.9l-96 64 48 128-144-144 96-64-28.6-86.5C159.7 19.6 87 24 40.7 71.4l-2.4 2.4C-10.4 123.6-12.5 202.9 31 256l212.1 218.6c7.1 7.3 18.6 7.3 25.7 0L481 255.9c43.5-53 41.4-132.3-7.3-182.1z\"]\n};\nvar faHeartbeat = {\n prefix: 'fas',\n iconName: 'heartbeat',\n icon: [512, 512, [], \"f21e\", \"M320.2 243.8l-49.7 99.4c-6 12.1-23.4 11.7-28.9-.6l-56.9-126.3-30 71.7H60.6l182.5 186.5c7.1 7.3 18.6 7.3 25.7 0L451.4 288H342.3l-22.1-44.2zM473.7 73.9l-2.4-2.5c-51.5-52.6-135.8-52.6-187.4 0L256 100l-27.9-28.5c-51.5-52.7-135.9-52.7-187.4 0l-2.4 2.4C-10.4 123.7-12.5 203 31 256h102.4l35.9-86.2c5.4-12.9 23.6-13.2 29.4-.4l58.2 129.3 49-97.9c5.9-11.8 22.7-11.8 28.6 0l27.6 55.2H481c43.5-53 41.4-132.3-7.3-182.1z\"]\n};\nvar faHelicopter = {\n prefix: 'fas',\n iconName: 'helicopter',\n icon: [640, 512, [], \"f533\", \"M304 384h272c17.67 0 32-14.33 32-32 0-123.71-100.29-224-224-224V64h176c8.84 0 16-7.16 16-16V16c0-8.84-7.16-16-16-16H144c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h176v64H112L68.8 70.4C65.78 66.37 61.03 64 56 64H16.01C5.6 64-2.04 73.78.49 83.88L32 192l160 64 86.4 115.2A31.992 31.992 0 0 0 304 384zm112-188.49C478.55 208.3 528.03 257.44 540.79 320H416V195.51zm219.37 263.3l-22.15-22.2c-6.25-6.26-16.24-6.1-22.64.01-7.09 6.77-13.84 11.25-24.64 11.25H240c-8.84 0-16 7.18-16 16.03v32.06c0 8.85 7.16 16.03 16 16.03h325.94c14.88 0 35.3-.47 68.45-29.52 7.02-6.14 7.57-17.05.98-23.66z\"]\n};\nvar faHighlighter = {\n prefix: 'fas',\n iconName: 'highlighter',\n icon: [544, 512, [], \"f591\", \"M0 479.98L99.92 512l35.45-35.45-67.04-67.04L0 479.98zm124.61-240.01a36.592 36.592 0 0 0-10.79 38.1l13.05 42.83-50.93 50.94 96.23 96.23 50.86-50.86 42.74 13.08c13.73 4.2 28.65-.01 38.15-10.78l35.55-41.64-173.34-173.34-41.52 35.44zm403.31-160.7l-63.2-63.2c-20.49-20.49-53.38-21.52-75.12-2.35L190.55 183.68l169.77 169.78L530.27 154.4c19.18-21.74 18.15-54.63-2.35-75.13z\"]\n};\nvar faHiking = {\n prefix: 'fas',\n iconName: 'hiking',\n icon: [384, 512, [], \"f6ec\", \"M80.95 472.23c-4.28 17.16 6.14 34.53 23.28 38.81 2.61.66 5.22.95 7.8.95 14.33 0 27.37-9.7 31.02-24.23l25.24-100.97-52.78-52.78-34.56 138.22zm14.89-196.12L137 117c2.19-8.42-3.14-16.95-11.92-19.06-43.88-10.52-88.35 15.07-99.32 57.17L.49 253.24c-2.19 8.42 3.14 16.95 11.92 19.06l63.56 15.25c8.79 2.1 17.68-3.02 19.87-11.44zM368 160h-16c-8.84 0-16 7.16-16 16v16h-34.75l-46.78-46.78C243.38 134.11 228.61 128 212.91 128c-27.02 0-50.47 18.3-57.03 44.52l-26.92 107.72a32.012 32.012 0 0 0 8.42 30.39L224 397.25V480c0 17.67 14.33 32 32 32s32-14.33 32-32v-82.75c0-17.09-6.66-33.16-18.75-45.25l-46.82-46.82c.15-.5.49-.89.62-1.41l19.89-79.57 22.43 22.43c6 6 14.14 9.38 22.62 9.38h48v240c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16V176c.01-8.84-7.15-16-15.99-16zM240 96c26.51 0 48-21.49 48-48S266.51 0 240 0s-48 21.49-48 48 21.49 48 48 48z\"]\n};\nvar faHippo = {\n prefix: 'fas',\n iconName: 'hippo',\n icon: [640, 512, [], \"f6ed\", \"M581.12 96.2c-27.67-.15-52.5 17.58-76.6 26.62C489.98 88.27 455.83 64 416 64c-11.28 0-21.95 2.3-32 5.88V56c0-13.26-10.75-24-24-24h-16c-13.25 0-24 10.74-24 24v48.98C286.01 79.58 241.24 64 192 64 85.96 64 0 135.64 0 224v240c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16v-70.79C128.35 407.57 166.72 416 208 416s79.65-8.43 112-22.79V464c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V288h128v32c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-32c17.67 0 32-14.33 32-32v-92.02c0-34.09-24.79-67.59-58.88-67.78zM448 176c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16z\"]\n};\nvar faHistory = {\n prefix: 'fas',\n iconName: 'history',\n icon: [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"]\n};\nvar faHockeyPuck = {\n prefix: 'fas',\n iconName: 'hockey-puck',\n icon: [512, 512, [], \"f453\", \"M0 160c0-53 114.6-96 256-96s256 43 256 96-114.6 96-256 96S0 213 0 160zm0 82.2V352c0 53 114.6 96 256 96s256-43 256-96V242.2c-113.4 82.3-398.5 82.4-512 0z\"]\n};\nvar faHollyBerry = {\n prefix: 'fas',\n iconName: 'holly-berry',\n icon: [448, 512, [], \"f7aa\", \"M144 192c26.5 0 48-21.5 48-48s-21.5-48-48-48-48 21.5-48 48 21.5 48 48 48zm112-48c0 26.5 21.5 48 48 48s48-21.5 48-48-21.5-48-48-48-48 21.5-48 48zm-32-48c26.5 0 48-21.5 48-48S250.5 0 224 0s-48 21.5-48 48 21.5 48 48 48zm-16.2 139.1c.1-12.4-13.1-20.1-23.8-13.7-34.3 20.3-71.4 32.7-108.7 36.2-9.7.9-15.6 11.3-11.6 20.2 6.2 13.9 11.1 28.6 14.7 43.8 3.6 15.2-5.3 30.6-20.2 35.1-14.9 4.5-30.1 7.6-45.3 9.1-9.7 1-15.7 11.3-11.7 20.2 15 32.8 22.9 69.5 23 107.7.1 14.4 15.2 23.1 27.6 16 33.2-19 68.9-30.5 104.8-33.9 9.7-.9 15.6-11.3 11.6-20.2-6.2-13.9-11.1-28.6-14.7-43.8-3.6-15.2 5.3-30.6 20.2-35.1 14.9-4.5 30.1-7.6 45.3-9.1 9.7-1 15.7-11.3 11.7-20.2-15.5-34.2-23.3-72.5-22.9-112.3zM435 365.6c-15.2-1.6-30.3-4.7-45.3-9.1-14.9-4.5-23.8-19.9-20.2-35.1 3.6-15.2 8.5-29.8 14.7-43.8 4-8.9-1.9-19.3-11.6-20.2-37.3-3.5-74.4-15.9-108.7-36.2-10.7-6.3-23.9 1.4-23.8 13.7 0 1.6-.2 3.2-.2 4.9.2 33.3 7 65.7 19.9 94 5.7 12.4 5.2 26.6-.6 38.9 4.9 1.2 9.9 2.2 14.8 3.7 14.9 4.5 23.8 19.9 20.2 35.1-3.6 15.2-8.5 29.8-14.7 43.8-4 8.9 1.9 19.3 11.6 20.2 35.9 3.4 71.6 14.9 104.8 33.9 12.5 7.1 27.6-1.6 27.6-16 .2-38.2 8-75 23-107.7 4.3-8.7-1.8-19.1-11.5-20.1z\"]\n};\nvar faHome = {\n prefix: 'fas',\n iconName: 'home',\n icon: [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"]\n};\nvar faHorse = {\n prefix: 'fas',\n iconName: 'horse',\n icon: [576, 512, [], \"f6f0\", \"M575.92 76.6c-.01-8.13-3.02-15.87-8.58-21.8-3.78-4.03-8.58-9.12-13.69-14.5 11.06-6.84 19.5-17.49 22.18-30.66C576.85 4.68 572.96 0 567.9 0H447.92c-70.69 0-128 57.31-128 128H160c-28.84 0-54.4 12.98-72 33.11V160c-48.53 0-88 39.47-88 88v56c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-56c0-13.22 6.87-24.39 16.78-31.68-.21 2.58-.78 5.05-.78 7.68 0 27.64 11.84 52.36 30.54 69.88l-25.72 68.6a63.945 63.945 0 0 0-2.16 37.99l24.85 99.41A15.982 15.982 0 0 0 107.02 512h65.96c10.41 0 18.05-9.78 15.52-19.88l-26.31-105.26 23.84-63.59L320 345.6V496c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V318.22c19.74-20.19 32-47.75 32-78.22 0-.22-.07-.42-.08-.64V136.89l16 7.11 18.9 37.7c7.45 14.87 25.05 21.55 40.49 15.37l32.55-13.02a31.997 31.997 0 0 0 20.12-29.74l-.06-77.71zm-64 19.4c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16z\"]\n};\nvar faHorseHead = {\n prefix: 'fas',\n iconName: 'horse-head',\n icon: [512, 512, [], \"f7ab\", \"M509.8 332.5l-69.9-164.3c-14.9-41.2-50.4-71-93-79.2 18-10.6 46.3-35.9 34.2-82.3-1.3-5-7.1-7.9-12-6.1L166.9 76.3C35.9 123.4 0 238.9 0 398.8V480c0 17.7 14.3 32 32 32h236.2c23.8 0 39.3-25 28.6-46.3L256 384v-.7c-45.6-3.5-84.6-30.7-104.3-69.6-1.6-3.1-.9-6.9 1.6-9.3l12.1-12.1c3.9-3.9 10.6-2.7 12.9 2.4 14.8 33.7 48.2 57.4 87.4 57.4 17.2 0 33-5.1 46.8-13.2l46 63.9c6 8.4 15.7 13.3 26 13.3h50.3c8.5 0 16.6-3.4 22.6-9.4l45.3-39.8c8.9-9.1 11.7-22.6 7.1-34.4zM328 224c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z\"]\n};\nvar faHospital = {\n prefix: 'fas',\n iconName: 'hospital',\n icon: [448, 512, [], \"f0f8\", \"M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z\"]\n};\nvar faHospitalAlt = {\n prefix: 'fas',\n iconName: 'hospital-alt',\n icon: [576, 512, [], \"f47d\", \"M544 96H416V32c0-17.7-14.3-32-32-32H192c-17.7 0-32 14.3-32 32v64H32c-17.7 0-32 14.3-32 32v368c0 8.8 7.2 16 16 16h544c8.8 0 16-7.2 16-16V128c0-17.7-14.3-32-32-32zM160 436c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm160 128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm16-170c0 3.3-2.7 6-6 6h-26v26c0 3.3-2.7 6-6 6h-20c-3.3 0-6-2.7-6-6v-26h-26c-3.3 0-6-2.7-6-6v-20c0-3.3 2.7-6 6-6h26V86c0-3.3 2.7-6 6-6h20c3.3 0 6 2.7 6 6v26h26c3.3 0 6 2.7 6 6v20zm144 298c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-128c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z\"]\n};\nvar faHospitalSymbol = {\n prefix: 'fas',\n iconName: 'hospital-symbol',\n icon: [512, 512, [], \"f47e\", \"M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm112 376c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-88h-96v88c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V136c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v88h96v-88c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v240z\"]\n};\nvar faHotTub = {\n prefix: 'fas',\n iconName: 'hot-tub',\n icon: [512, 512, [], \"f593\", \"M414.21 177.65c1.02 8.21 7.75 14.35 15.75 14.35h16.12c9.51 0 17.08-8.57 16-18.35-4.34-39.11-22.4-74.53-50.13-97.16-17.37-14.17-28.82-36.75-31.98-62.15C378.96 6.14 372.22 0 364.23 0h-16.12c-9.51 0-17.09 8.57-16 18.35 4.34 39.11 22.4 74.53 50.13 97.16 17.36 14.17 28.82 36.75 31.97 62.14zm-108 0c1.02 8.21 7.75 14.35 15.75 14.35h16.12c9.51 0 17.08-8.57 16-18.35-4.34-39.11-22.4-74.53-50.13-97.16-17.37-14.17-28.82-36.75-31.98-62.15C270.96 6.14 264.22 0 256.23 0h-16.12c-9.51 0-17.09 8.57-16 18.35 4.34 39.11 22.4 74.53 50.13 97.16 17.36 14.17 28.82 36.75 31.97 62.14zM480 256H256l-110.93-83.2a63.99 63.99 0 0 0-38.4-12.8H64c-35.35 0-64 28.65-64 64v224c0 35.35 28.65 64 64 64h384c35.35 0 64-28.65 64-64V288c0-17.67-14.33-32-32-32zM128 440c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8V328c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v112zm96 0c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8V328c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v112zm96 0c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8V328c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v112zm96 0c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8V328c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v112zM64 128c35.35 0 64-28.65 64-64S99.35 0 64 0 0 28.65 0 64s28.65 64 64 64z\"]\n};\nvar faHotdog = {\n prefix: 'fas',\n iconName: 'hotdog',\n icon: [512, 512, [], \"f80f\", \"M488.56 23.44a80 80 0 0 0-113.12 0l-352 352a80 80 0 1 0 113.12 113.12l352-352a80 80 0 0 0 0-113.12zm-49.93 95.19c-19.6 19.59-37.52 22.67-51.93 25.14C373.76 146 364.4 147.6 352 160s-14 21.76-16.23 34.71c-2.48 14.4-5.55 32.33-25.15 51.92s-37.52 22.67-51.92 25.15C245.75 274 236.4 275.6 224 288s-14 21.75-16.23 34.7c-2.47 14.4-5.54 32.33-25.14 51.92s-37.53 22.68-51.93 25.15C117.76 402 108.4 403.6 96 416a16 16 0 0 1-22.63-22.63c19.6-19.59 37.52-22.67 51.92-25.14 13-2.22 22.3-3.82 34.71-16.23s14-21.75 16.22-34.7c2.48-14.4 5.55-32.33 25.15-51.92s37.52-22.67 51.92-25.14c13-2.22 22.3-3.83 34.7-16.23s14-21.76 16.24-34.71c2.47-14.4 5.54-32.33 25.14-51.92s37.52-22.68 51.92-25.15C394.24 110 403.59 108.41 416 96a16 16 0 0 1 22.63 22.63zM31.44 322.18L322.18 31.44l-11.54-11.55c-25-25-63.85-26.66-86.79-3.72L16.17 223.85c-22.94 22.94-21.27 61.79 3.72 86.78zm449.12-132.36L189.82 480.56l11.54 11.55c25 25 63.85 26.66 86.79 3.72l207.68-207.68c22.94-22.94 21.27-61.79-3.72-86.79z\"]\n};\nvar faHotel = {\n prefix: 'fas',\n iconName: 'hotel',\n icon: [576, 512, [], \"f594\", \"M560 64c8.84 0 16-7.16 16-16V16c0-8.84-7.16-16-16-16H16C7.16 0 0 7.16 0 16v32c0 8.84 7.16 16 16 16h15.98v384H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h240v-80c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v80h240c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16h-16V64h16zm-304 44.8c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4zm0 96c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4zm-128-96c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4zM179.2 256h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4c0 6.4-6.4 12.8-12.8 12.8zM192 384c0-53.02 42.98-96 96-96s96 42.98 96 96H192zm256-140.8c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4zm0-96c0 6.4-6.4 12.8-12.8 12.8h-38.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h38.4c6.4 0 12.8 6.4 12.8 12.8v38.4z\"]\n};\nvar faHourglass = {\n prefix: 'fas',\n iconName: 'hourglass',\n icon: [384, 512, [], \"f254\", \"M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z\"]\n};\nvar faHourglassEnd = {\n prefix: 'fas',\n iconName: 'hourglass-end',\n icon: [384, 512, [], \"f253\", \"M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z\"]\n};\nvar faHourglassHalf = {\n prefix: 'fas',\n iconName: 'hourglass-half',\n icon: [384, 512, [], \"f252\", \"M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z\"]\n};\nvar faHourglassStart = {\n prefix: 'fas',\n iconName: 'hourglass-start',\n icon: [384, 512, [], \"f251\", \"M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z\"]\n};\nvar faHouseDamage = {\n prefix: 'fas',\n iconName: 'house-damage',\n icon: [576, 512, [], \"f6f1\", \"M288 114.96L69.47 307.71c-1.62 1.46-3.69 2.14-5.47 3.35V496c0 8.84 7.16 16 16 16h149.23L192 439.19l104.11-64-60.16-119.22L384 392.75l-104.11 64L319.81 512H496c8.84 0 16-7.16 16-16V311.1c-1.7-1.16-3.72-1.82-5.26-3.2L288 114.96zm282.69 121.32L512 184.45V48c0-8.84-7.16-16-16-16h-64c-8.84 0-16 7.16-16 16v51.69L314.75 10.31C307.12 3.45 297.56.01 288 0s-19.1 3.41-26.7 10.27L5.31 236.28c-6.57 5.91-7.12 16.02-1.21 22.6l21.4 23.82c5.9 6.57 16.02 7.12 22.6 1.21L277.42 81.63c6.05-5.33 15.12-5.33 21.17 0L527.91 283.9c6.57 5.9 16.69 5.36 22.6-1.21l21.4-23.82c5.9-6.57 5.36-16.69-1.22-22.59z\"]\n};\nvar faHryvnia = {\n prefix: 'fas',\n iconName: 'hryvnia',\n icon: [384, 512, [], \"f6f2\", \"M368 240c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16h-41.86c13.41-28.63 13.74-63.33-4.13-94.05C303.34 49.84 267.1 32 229.96 32h-78.82c-24.32 0-47.86 8.53-66.54 24.09L72.83 65.9c-10.18 8.49-11.56 23.62-3.07 33.8l20.49 24.59c8.49 10.19 23.62 11.56 33.81 3.07l11.73-9.78c4.32-3.6 9.77-5.57 15.39-5.57h83.62c11.69 0 21.2 9.52 21.2 21.2 0 5.91-2.48 11.58-6.81 15.58L219.7 176H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h134.37l-34.67 32H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h41.86c-13.41 28.63-13.74 63.33 4.13 94.05C80.66 462.15 116.9 480 154.04 480h78.82c24.32 0 47.86-8.53 66.54-24.09l11.77-9.81c10.18-8.49 11.56-23.62 3.07-33.8l-20.49-24.59c-8.49-10.19-23.62-11.56-33.81-3.07l-11.75 9.8a23.992 23.992 0 0 1-15.36 5.56H149.2c-11.69 0-21.2-9.52-21.2-21.2 0-5.91 2.48-11.58 6.81-15.58L164.3 336H368c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16H233.63l34.67-32H368z\"]\n};\nvar faICursor = {\n prefix: 'fas',\n iconName: 'i-cursor',\n icon: [256, 512, [], \"f246\", \"M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z\"]\n};\nvar faIceCream = {\n prefix: 'fas',\n iconName: 'ice-cream',\n icon: [448, 512, [], \"f810\", \"M368 160h-.94a144 144 0 1 0-286.12 0H80a48 48 0 0 0 0 96h288a48 48 0 0 0 0-96zM195.38 493.69a31.52 31.52 0 0 0 57.24 0L352 288H96z\"]\n};\nvar faIcicles = {\n prefix: 'fas',\n iconName: 'icicles',\n icon: [512, 512, [], \"f7ad\", \"M511.4 37.9C515.1 18.2 500 0 480 0H32C10.6 0-4.8 20.7 1.4 41.2l87.1 273.4c2.5 7.2 12.7 7.2 15.1 0L140 190.5l44.2 187.3c1.9 8.3 13.7 8.3 15.6 0l46.5-196.9 34.1 133.4c2.3 7.6 13 7.6 15.3 0l45.8-172.5 66.7 363.8c1.7 8.6 14 8.6 15.7 0l87.5-467.7z\"]\n};\nvar faIcons = {\n prefix: 'fas',\n iconName: 'icons',\n icon: [512, 512, [], \"f86d\", \"M116.65 219.35a15.68 15.68 0 0 0 22.65 0l96.75-99.83c28.15-29 26.5-77.1-4.91-103.88C203.75-7.7 163-3.5 137.86 22.44L128 32.58l-9.85-10.14C93.05-3.5 52.25-7.7 24.86 15.64c-31.41 26.78-33 74.85-5 103.88zm143.92 100.49h-48l-7.08-14.24a27.39 27.39 0 0 0-25.66-17.78h-71.71a27.39 27.39 0 0 0-25.66 17.78l-7 14.24h-48A27.45 27.45 0 0 0 0 347.3v137.25A27.44 27.44 0 0 0 27.43 512h233.14A27.45 27.45 0 0 0 288 484.55V347.3a27.45 27.45 0 0 0-27.43-27.46zM144 468a52 52 0 1 1 52-52 52 52 0 0 1-52 52zm355.4-115.9h-60.58l22.36-50.75c2.1-6.65-3.93-13.21-12.18-13.21h-75.59c-6.3 0-11.66 3.9-12.5 9.1l-16.8 106.93c-1 6.3 4.88 11.89 12.5 11.89h62.31l-24.2 83c-1.89 6.65 4.2 12.9 12.23 12.9a13.26 13.26 0 0 0 10.92-5.25l92.4-138.91c4.88-6.91-1.16-15.7-10.87-15.7zM478.08.33L329.51 23.17C314.87 25.42 304 38.92 304 54.83V161.6a83.25 83.25 0 0 0-16-1.7c-35.35 0-64 21.48-64 48s28.65 48 64 48c35.2 0 63.73-21.32 64-47.66V99.66l112-17.22v47.18a83.25 83.25 0 0 0-16-1.7c-35.35 0-64 21.48-64 48s28.65 48 64 48c35.2 0 63.73-21.32 64-47.66V32c0-19.48-16-34.42-33.92-31.67z\"]\n};\nvar faIdBadge = {\n prefix: 'fas',\n iconName: 'id-badge',\n icon: [384, 512, [], \"f2c1\", \"M336 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM144 32h96c8.8 0 16 7.2 16 16s-7.2 16-16 16h-96c-8.8 0-16-7.2-16-16s7.2-16 16-16zm48 128c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H102.4C90 416 80 407.4 80 396.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z\"]\n};\nvar faIdCard = {\n prefix: 'fas',\n iconName: 'id-card',\n icon: [576, 512, [], \"f2c2\", \"M528 32H48C21.5 32 0 53.5 0 80v16h576V80c0-26.5-21.5-48-48-48zM0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V128H0v304zm352-232c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zm0 64c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zm0 64c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H360c-4.4 0-8-3.6-8-8v-16zM176 192c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM67.1 396.2C75.5 370.5 99.6 352 128 352h8.2c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h8.2c28.4 0 52.5 18.5 60.9 44.2 3.2 9.9-5.2 19.8-15.6 19.8H82.7c-10.4 0-18.8-10-15.6-19.8z\"]\n};\nvar faIdCardAlt = {\n prefix: 'fas',\n iconName: 'id-card-alt',\n icon: [576, 512, [], \"f47f\", \"M528 64H384v96H192V64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM288 224c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm93.3 224H194.7c-10.4 0-18.8-10-15.6-19.8 8.3-25.6 32.4-44.2 60.9-44.2h8.2c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h8.2c28.4 0 52.5 18.5 60.9 44.2 3.2 9.8-5.2 19.8-15.6 19.8zM352 32c0-17.7-14.3-32-32-32h-64c-17.7 0-32 14.3-32 32v96h128V32z\"]\n};\nvar faIgloo = {\n prefix: 'fas',\n iconName: 'igloo',\n icon: [576, 512, [], \"f7ae\", \"M320 33.9c-10.5-1.2-21.2-1.9-32-1.9-99.8 0-187.8 50.8-239.4 128H320V33.9zM96 192H30.3C11.1 230.6 0 274 0 320h96V192zM352 39.4V160h175.4C487.2 99.9 424.8 55.9 352 39.4zM480 320h96c0-46-11.1-89.4-30.3-128H480v128zm-64 64v96h128c17.7 0 32-14.3 32-32v-96H411.5c2.6 10.3 4.5 20.9 4.5 32zm32-192H128v128h49.8c22.2-38.1 63-64 110.2-64s88 25.9 110.2 64H448V192zM0 448c0 17.7 14.3 32 32 32h128v-96c0-11.1 1.9-21.7 4.5-32H0v96zm288-160c-53 0-96 43-96 96v96h192v-96c0-53-43-96-96-96z\"]\n};\nvar faImage = {\n prefix: 'fas',\n iconName: 'image',\n icon: [512, 512, [], \"f03e\", \"M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z\"]\n};\nvar faImages = {\n prefix: 'fas',\n iconName: 'images',\n icon: [576, 512, [], \"f302\", \"M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z\"]\n};\nvar faInbox = {\n prefix: 'fas',\n iconName: 'inbox',\n icon: [576, 512, [], \"f01c\", \"M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z\"]\n};\nvar faIndent = {\n prefix: 'fas',\n iconName: 'indent',\n icon: [448, 512, [], \"f03c\", \"M27.31 363.3l96-96a16 16 0 0 0 0-22.62l-96-96C17.27 138.66 0 145.78 0 160v192c0 14.31 17.33 21.3 27.31 11.3zM432 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm3.17-128H204.83A12.82 12.82 0 0 0 192 300.83v38.34A12.82 12.82 0 0 0 204.83 352h230.34A12.82 12.82 0 0 0 448 339.17v-38.34A12.82 12.82 0 0 0 435.17 288zm0-128H204.83A12.82 12.82 0 0 0 192 172.83v38.34A12.82 12.82 0 0 0 204.83 224h230.34A12.82 12.82 0 0 0 448 211.17v-38.34A12.82 12.82 0 0 0 435.17 160zM432 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faIndustry = {\n prefix: 'fas',\n iconName: 'industry',\n icon: [512, 512, [], \"f275\", \"M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z\"]\n};\nvar faInfinity = {\n prefix: 'fas',\n iconName: 'infinity',\n icon: [640, 512, [], \"f534\", \"M471.1 96C405 96 353.3 137.3 320 174.6 286.7 137.3 235 96 168.9 96 75.8 96 0 167.8 0 256s75.8 160 168.9 160c66.1 0 117.8-41.3 151.1-78.6 33.3 37.3 85 78.6 151.1 78.6 93.1 0 168.9-71.8 168.9-160S564.2 96 471.1 96zM168.9 320c-40.2 0-72.9-28.7-72.9-64s32.7-64 72.9-64c38.2 0 73.4 36.1 94 64-20.4 27.6-55.9 64-94 64zm302.2 0c-38.2 0-73.4-36.1-94-64 20.4-27.6 55.9-64 94-64 40.2 0 72.9 28.7 72.9 64s-32.7 64-72.9 64z\"]\n};\nvar faInfo = {\n prefix: 'fas',\n iconName: 'info',\n icon: [192, 512, [], \"f129\", \"M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z\"]\n};\nvar faInfoCircle = {\n prefix: 'fas',\n iconName: 'info-circle',\n icon: [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"]\n};\nvar faItalic = {\n prefix: 'fas',\n iconName: 'italic',\n icon: [320, 512, [], \"f033\", \"M320 48v32a16 16 0 0 1-16 16h-62.76l-80 320H208a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h62.76l80-320H112a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16z\"]\n};\nvar faJedi = {\n prefix: 'fas',\n iconName: 'jedi',\n icon: [544, 512, [], \"f669\", \"M479.99 352l58.88-58.87c3.29-16.8 5.13-34.12 5.13-51.86 0-5.81-.68-11.51-1.05-17.27H496l41.25-41.24c-14.5-64.79-52.43-123.05-107.91-162.27-2.77-1.96-5.97-2.99-9.25-2.99-5.37 0-10.41 2.71-13.49 7.24-3.05 4.49-3.64 9.99-1.61 15.09 6.55 16.46 9.86 33.73 9.86 51.31 0 45.12-21.03 86.57-57.69 113.73-4.02 2.98-6.46 7.5-6.7 12.4-.24 4.92 1.76 9.66 5.49 13.03 32.93 29.75 47.35 73.51 38.57 117.07-9.74 48.35-48.84 87.1-97.31 96.5l-2.5-65.34L321.88 397c2.98 2.06 7.39 1.69 10.02-.8a8.002 8.002 0 0 0 1.34-9.92l-20.11-33.73 42.07-8.72c3.7-.75 6.38-4.05 6.38-7.83 0-3.77-2.69-7.06-6.38-7.83l-42.07-8.73 20.13-33.77c1.92-3.23 1.34-7.31-1.38-9.91-2.7-2.55-6.97-2.89-10-.8l-30.39 20.67L279.96 7.7a7.964 7.964 0 0 0-8-7.7c-4.33 0-7.84 3.38-8 7.67l-11.52 287.97-30.39-20.66c-3.14-2.12-7.27-1.83-10 .78-2.72 2.59-3.3 6.67-1.36 9.94l20.11 33.73-42.07 8.73c-3.7.75-6.38 4.05-6.38 7.83s2.67 7.08 6.38 7.83l42.07 8.72-20.13 33.77c-1.92 3.23-1.34 7.33 1.39 9.94 2.59 2.45 7.03 2.75 10 .75l27.16-18.48-2.5 65.26c-56.94-11.64-99.89-61.89-99.89-121.92 0-35.08 14.62-67.6 41.17-91.58 3.72-3.36 5.72-8.11 5.48-13.01-.24-4.9-2.68-9.41-6.69-12.38-36.67-27.16-57.71-68.62-57.71-113.74 0-17.56 3.31-34.81 9.84-51.26 2.02-5.09 1.43-10.59-1.62-15.09-3.08-4.54-8.13-7.25-13.51-7.25-3.3 0-6.5 1.04-9.27 3-55.87 39.52-93.6 97.37-107.97 162.07L47.93 224H.72c-.63 9.92-.97 19.91-.5 29.99.62 13.43 2.54 26.53 5.11 39.41l58.6 58.6H24.02c41.25 90.23 131.13 154.94 235.1 159.71 4.3.2 8.59.29 12.85.29 110.34 0 205.35-65.83 247.98-160h-39.96z\"]\n};\nvar faJoint = {\n prefix: 'fas',\n iconName: 'joint',\n icon: [640, 512, [], \"f595\", \"M444.34 181.1c22.38 15.68 35.66 41.16 35.66 68.59V280c0 4.42 3.58 8 8 8h48c4.42 0 8-3.58 8-8v-30.31c0-43.24-21.01-83.41-56.34-108.06C463.85 125.02 448 99.34 448 70.31V8c0-4.42-3.58-8-8-8h-48c-4.42 0-8 3.58-8 8v66.4c0 43.69 24.56 81.63 60.34 106.7zM194.97 358.98C126.03 370.07 59.69 394.69 0 432c83.65 52.28 180.3 80 278.94 80h88.57L254.79 380.49c-14.74-17.2-37.45-25.11-59.82-21.51zM553.28 87.09c-5.67-3.8-9.28-9.96-9.28-16.78V8c0-4.42-3.58-8-8-8h-48c-4.42 0-8 3.58-8 8v62.31c0 22.02 10.17 43.41 28.64 55.39C550.79 153.04 576 199.54 576 249.69V280c0 4.42 3.58 8 8 8h48c4.42 0 8-3.58 8-8v-30.31c0-65.44-32.41-126.19-86.72-162.6zM360.89 352.05c-34.4.06-86.81.15-88.21.17l117.8 137.43A63.987 63.987 0 0 0 439.07 512h88.45L409.57 374.4a63.955 63.955 0 0 0-48.68-22.35zM616 352H432l117.99 137.65A63.987 63.987 0 0 0 598.58 512H616c13.25 0 24-10.75 24-24V376c0-13.26-10.75-24-24-24z\"]\n};\nvar faJournalWhills = {\n prefix: 'fas',\n iconName: 'journal-whills',\n icon: [448, 512, [], \"f66a\", \"M448 358.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM133.08 144.39l21.26 21.26c1.56 1.56 3.61 2.34 5.66 2.34s4.09-.78 5.66-2.34c3.12-3.12 3.12-8.19 0-11.31l-26.42-26.42c10-20.9 26.24-37.97 46.37-49.26C179.62 88.4 176 99.74 176 112c0 19.96 9.33 37.57 23.66 49.31C190.01 171.37 184 184.96 184 200c0 26.94 19.04 49.4 44.38 54.76l1.36-32.71-10.37 7.04c-.69.45-1.47.69-2.25.69-1 0-1.98-.38-2.75-1.09a4.006 4.006 0 0 1-.69-4.95l8.54-14.31-17.91-3.72c-1.86-.39-3.19-2.03-3.19-3.92s1.33-3.53 3.19-3.92l17.91-3.72-8.54-14.31c-.95-1.61-.67-3.67.69-4.95 1.36-1.3 3.44-1.44 5-.41l12.01 8.16L236 71.83c.09-2.14 1.86-3.83 4-3.83s3.91 1.69 4 3.83l4.68 112.29 14.2-9.65a4.067 4.067 0 0 1 5 .41 4.006 4.006 0 0 1 .69 4.95l-8.54 14.31 17.91 3.72c1.86.39 3.19 2.03 3.19 3.92s-1.33 3.53-3.19 3.92l-17.91 3.72 8.54 14.31c.95 1.61.67 3.67-.69 4.95-.77.72-1.77 1.09-2.75 1.09-.78 0-1.56-.23-2.25-.69l-12.68-8.62 1.43 34.28C276.96 249.4 296 226.94 296 200c0-15.04-6.01-28.63-15.66-38.69C294.67 149.57 304 131.96 304 112c0-12.26-3.62-23.6-9.6-33.33 20.13 11.28 36.37 28.36 46.37 49.26l-26.42 26.42c-3.12 3.12-3.12 8.19 0 11.31 1.56 1.56 3.61 2.34 5.66 2.34s4.09-.78 5.66-2.34l21.26-21.26c2.97 10.08 5.07 20.55 5.07 31.6 0 .52-.14.99-.15 1.51l-37.11 32.47a7.975 7.975 0 0 0-.75 11.28 7.97 7.97 0 0 0 6.02 2.73c1.88 0 3.75-.66 5.27-1.98l23.59-20.64C337.32 250.96 293.09 288 240 288s-97.32-37.04-108.86-86.62l23.59 20.64A7.957 7.957 0 0 0 160 224c2.22 0 4.44-.92 6.02-2.73 2.92-3.33 2.58-8.38-.75-11.28l-37.11-32.47c-.01-.52-.15-.99-.15-1.51-.01-11.06 2.09-21.53 5.07-31.62zM380.8 448H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8v64z\"]\n};\nvar faKaaba = {\n prefix: 'fas',\n iconName: 'kaaba',\n icon: [576, 512, [], \"f66b\", \"M554.12 83.51L318.36 4.93a95.962 95.962 0 0 0-60.71 0L21.88 83.51A32.006 32.006 0 0 0 0 113.87v49.01l265.02-79.51c15.03-4.5 30.92-4.5 45.98 0l265 79.51v-49.01c0-13.77-8.81-26-21.88-30.36zm-279.9 30.52L0 196.3v228.38c0 15 10.42 27.98 25.06 31.24l242.12 53.8a95.937 95.937 0 0 0 41.65 0l242.12-53.8c14.64-3.25 25.06-16.24 25.06-31.24V196.29l-274.2-82.26c-9.04-2.72-18.59-2.72-27.59 0zM128 230.11c0 3.61-2.41 6.77-5.89 7.72l-80 21.82C37.02 261.03 32 257.2 32 251.93v-16.58c0-3.61 2.41-6.77 5.89-7.72l80-21.82c5.09-1.39 10.11 2.44 10.11 7.72v16.58zm144-39.28c0 3.61-2.41 6.77-5.89 7.72l-96 26.18c-5.09 1.39-10.11-2.44-10.11-7.72v-16.58c0-3.61 2.41-6.77 5.89-7.72l96-26.18c5.09-1.39 10.11 2.44 10.11 7.72v16.58zm176 22.7c0-5.28 5.02-9.11 10.11-7.72l80 21.82c3.48.95 5.89 4.11 5.89 7.72v16.58c0 5.28-5.02 9.11-10.11 7.72l-80-21.82a7.997 7.997 0 0 1-5.89-7.72v-16.58zm-144-39.27c0-5.28 5.02-9.11 10.11-7.72l96 26.18c3.48.95 5.89 4.11 5.89 7.72v16.58c0 5.28-5.02 9.11-10.11 7.72l-96-26.18a7.997 7.997 0 0 1-5.89-7.72v-16.58z\"]\n};\nvar faKey = {\n prefix: 'fas',\n iconName: 'key',\n icon: [512, 512, [], \"f084\", \"M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z\"]\n};\nvar faKeyboard = {\n prefix: 'fas',\n iconName: 'keyboard',\n icon: [576, 512, [], \"f11c\", \"M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z\"]\n};\nvar faKhanda = {\n prefix: 'fas',\n iconName: 'khanda',\n icon: [512, 512, [], \"f66d\", \"M415.81 66c-6.37-3.5-14.37-2.33-19.36 3.02a15.974 15.974 0 0 0-1.91 19.52c16.49 26.16 25.2 56.39 25.2 87.41-.19 53.25-26.77 102.69-71.27 132.41l-76.63 53.35v-20.1l44.05-36.09c3.92-4.2 5-10.09 2.81-15.28L310.85 273c33.84-19.26 56.94-55.25 56.94-96.99 0-40.79-22.02-76.13-54.59-95.71l5.22-11.44c2.34-5.53.93-11.83-3.57-16.04L255.86 0l-58.99 52.81c-4.5 4.21-5.9 10.51-3.57 16.04l5.22 11.44c-32.57 19.58-54.59 54.93-54.59 95.72 0 41.75 23.09 77.73 56.94 96.99l-7.85 17.24c-2.19 5.18-1.1 11.07 2.81 15.28l44.05 36.09v19.9l-76.59-53.33C119.02 278.62 92.44 229.19 92.26 176c0-31.08 8.71-61.31 25.2-87.47 3.87-6.16 2.4-13.77-2.59-19.08-5-5.34-13.68-6.2-20.02-2.7C16.32 109.6-22.3 205.3 13.36 295.99c7.07 17.99 17.89 34.38 30.46 49.06l55.97 65.36c4.87 5.69 13.04 7.24 19.65 3.72l79.35-42.23L228 392.23l-47.08 32.78c-1.67-.37-3.23-1.01-5.01-1.01-13.25 0-23.99 10.74-23.99 24 0 13.25 10.74 24 23.99 24 12.1 0 21.69-9.11 23.33-20.76l40.63-28.28v29.95c-9.39 5.57-15.99 15.38-15.99 27.1 0 17.67 14.32 32 31.98 32s31.98-14.33 31.98-32c0-11.71-6.61-21.52-15.99-27.1v-30.15l40.91 28.48C314.41 462.89 324 472 336.09 472c13.25 0 23.99-10.75 23.99-24 0-13.26-10.74-24-23.99-24-1.78 0-3.34.64-5.01 1.01L284 392.23l29.21-20.34 79.35 42.23c6.61 3.52 14.78 1.97 19.65-3.71l52.51-61.31c18.87-22.02 34-47.5 41.25-75.59 21.62-83.66-16.45-167.27-90.16-207.51zm-95.99 110c0 22.3-11.49 41.92-28.83 53.38l-5.65-12.41c-8.75-24.52-8.75-51.04 0-75.56l7.83-17.18c16.07 11.65 26.65 30.45 26.65 51.77zm-127.93 0c0-21.32 10.58-40.12 26.66-51.76l7.83 17.18c8.75 24.52 8.75 51.03 0 75.56l-5.65 12.41c-17.34-11.46-28.84-31.09-28.84-53.39z\"]\n};\nvar faKiss = {\n prefix: 'fas',\n iconName: 'kiss',\n icon: [496, 512, [], \"f596\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-80 232c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm136 156c0 19.2-28.7 41.5-71.5 44-8.5.8-12.1-11.8-3.6-15.4l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-6-2.5-6.1-12.2 0-14.8l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-8.6-3.6-4.8-16.5 3.6-15.4 42.8 2.5 71.5 24.8 71.5 44 0 13-13.4 27.3-35.2 36C290.6 368.7 304 383 304 396zm24-156c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faKissBeam = {\n prefix: 'fas',\n iconName: 'kiss-beam',\n icon: [496, 512, [], \"f597\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-39 219.9l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.6 4-14.9-4.5 3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.5 8.5-10.9 12-15.1 4.5zM304 396c0 19.2-28.7 41.5-71.5 44-8.5.8-12.1-11.8-3.6-15.4l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-6-2.5-6.1-12.2 0-14.8l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-8.6-3.6-4.8-16.5 3.6-15.4 42.8 2.5 71.5 24.8 71.5 44 0 13-13.4 27.3-35.2 36C290.6 368.7 304 383 304 396zm65-168.1l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.1 7.3-15.6 4-14.9-4.5 3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.5 8.5-10.9 12-15.1 4.5z\"]\n};\nvar faKissWinkHeart = {\n prefix: 'fas',\n iconName: 'kiss-wink-heart',\n icon: [504, 512, [], \"f598\", \"M501.1 402.5c-8-20.8-31.5-31.5-53.1-25.9l-8.4 2.2-2.3-8.4c-5.9-21.4-27-36.5-49-33-25.2 4-40.6 28.6-34 52.6l22.9 82.6c1.5 5.3 7 8.5 12.4 7.1l83-21.5c24.1-6.3 37.7-31.8 28.5-55.7zm-177.6-4c-5.6-20.3-2.3-42 9-59.7 29.7-46.3 98.7-45.5 127.8 4.3 6.4.1 12.6 1.4 18.6 2.9 10.9-27.9 17.1-58.2 17.1-90C496 119 385 8 248 8S0 119 0 256s111 248 248 248c35.4 0 68.9-7.5 99.4-20.9-.3-.7-23.9-84.6-23.9-84.6zM168 240c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm120 156c0 19.2-28.7 41.5-71.5 44-8.5.8-12.1-11.8-3.6-15.4l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-6-2.5-5.7-12.3 0-14.8l17-7.2c13-5.5 20.8-13.5 20.8-21.5s-7.8-16-20.8-21.5l-17-7.2c-8.8-3.7-4.6-16.6 3.6-15.4 42.8 2.5 71.5 24.8 71.5 44 0 13-13.4 27.3-35.2 36C274.6 368.7 288 383 288 396zm16-179c-8.3 7.4-21.6.4-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S400 181 404 206.2c1.7 11.1-11.3 18.3-19.8 10.8l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L304 217z\"]\n};\nvar faKiwiBird = {\n prefix: 'fas',\n iconName: 'kiwi-bird',\n icon: [576, 512, [], \"f535\", \"M575.81 217.98C572.64 157.41 518.28 112 457.63 112h-9.37c-52.82 0-104.25-16.25-147.74-46.24-41.99-28.96-96.04-41.62-153.21-28.7C129.3 41.12-.08 78.24 0 224c.04 70.95 38.68 132.8 95.99 166.01V464c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-54.26c15.36 3.96 31.4 6.26 48 6.26 5.44 0 10.68-.73 16-1.18V464c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-59.43c14.24-5.06 27.88-11.39 40.34-19.51C342.07 355.25 393.86 336 448.46 336c25.48 0 16.01-.31 23.05-.78l74.41 136.44c2.86 5.23 8.3 8.34 14.05 8.34 1.31 0 2.64-.16 3.95-.5 7.09-1.8 12.05-8.19 12.05-15.5 0 0 .14-240.24-.16-246.02zM463.97 248c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm80 153.25l-39.86-73.08c15.12-5.83 28.73-14.6 39.86-25.98v99.06z\"]\n};\nvar faLandmark = {\n prefix: 'fas',\n iconName: 'landmark',\n icon: [512, 512, [], \"f66f\", \"M501.62 92.11L267.24 2.04a31.958 31.958 0 0 0-22.47 0L10.38 92.11A16.001 16.001 0 0 0 0 107.09V144c0 8.84 7.16 16 16 16h480c8.84 0 16-7.16 16-16v-36.91c0-6.67-4.14-12.64-10.38-14.98zM64 192v160H48c-8.84 0-16 7.16-16 16v48h448v-48c0-8.84-7.16-16-16-16h-16V192h-64v160h-96V192h-64v160h-96V192H64zm432 256H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h480c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faLanguage = {\n prefix: 'fas',\n iconName: 'language',\n icon: [640, 512, [], \"f1ab\", \"M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z\"]\n};\nvar faLaptop = {\n prefix: 'fas',\n iconName: 'laptop',\n icon: [640, 512, [], \"f109\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33.02-17.47-32.77-32H16c-8.8 0-16 7.2-16 16v16c0 35.2 28.8 64 64 64h512c35.2 0 64-28.8 64-64v-16c0-8.8-7.2-16-16-16zM576 48c0-26.4-21.6-48-48-48H112C85.6 0 64 21.6 64 48v336h512V48zm-64 272H128V64h384v256z\"]\n};\nvar faLaptopCode = {\n prefix: 'fas',\n iconName: 'laptop-code',\n icon: [640, 512, [], \"f5fc\", \"M255.03 261.65c6.25 6.25 16.38 6.25 22.63 0l11.31-11.31c6.25-6.25 6.25-16.38 0-22.63L253.25 192l35.71-35.72c6.25-6.25 6.25-16.38 0-22.63l-11.31-11.31c-6.25-6.25-16.38-6.25-22.63 0l-58.34 58.34c-6.25 6.25-6.25 16.38 0 22.63l58.35 58.34zm96.01-11.3l11.31 11.31c6.25 6.25 16.38 6.25 22.63 0l58.34-58.34c6.25-6.25 6.25-16.38 0-22.63l-58.34-58.34c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63L386.75 192l-35.71 35.72c-6.25 6.25-6.25 16.38 0 22.63zM624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33.02-17.47-32.77-32H16c-8.8 0-16 7.2-16 16v16c0 35.2 28.8 64 64 64h512c35.2 0 64-28.8 64-64v-16c0-8.8-7.2-16-16-16zM576 48c0-26.4-21.6-48-48-48H112C85.6 0 64 21.6 64 48v336h512V48zm-64 272H128V64h384v256z\"]\n};\nvar faLaptopMedical = {\n prefix: 'fas',\n iconName: 'laptop-medical',\n icon: [640, 512, [], \"f812\", \"M232 224h56v56a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-56h56a8 8 0 0 0 8-8v-48a8 8 0 0 0-8-8h-56v-56a8 8 0 0 0-8-8h-48a8 8 0 0 0-8 8v56h-56a8 8 0 0 0-8 8v48a8 8 0 0 0 8 8zM576 48a48.14 48.14 0 0 0-48-48H112a48.14 48.14 0 0 0-48 48v336h512zm-64 272H128V64h384zm112 96H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]\n};\nvar faLaugh = {\n prefix: 'fas',\n iconName: 'laugh',\n icon: [496, 512, [], \"f599\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 152c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm88 272h-16c-73.4 0-134-55-142.9-126-1.2-9.5 6.3-18 15.9-18h270c9.6 0 17.1 8.4 15.9 18-8.9 71-69.5 126-142.9 126z\"]\n};\nvar faLaughBeam = {\n prefix: 'fas',\n iconName: 'laugh-beam',\n icon: [496, 512, [], \"f59a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm24 199.4c3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.7 8.6-10.8 11.9-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.2 7.4-15.8 4.1-15.1-4.5zm-160 0c3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.7 8.6-10.8 11.9-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.3 7.4-15.8 4-15.1-4.5zM398.9 306C390 377 329.4 432 256 432h-16c-73.4 0-134-55-142.9-126-1.2-9.5 6.3-18 15.9-18h270c9.6 0 17.1 8.4 15.9 18z\"]\n};\nvar faLaughSquint = {\n prefix: 'fas',\n iconName: 'laugh-squint',\n icon: [496, 512, [], \"f59b\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm33.8 161.7l80-48c11.6-6.9 24 7.7 15.4 18L343.6 180l33.6 40.3c8.7 10.4-3.9 24.8-15.4 18l-80-48c-7.7-4.7-7.7-15.9 0-20.6zm-163-30c-8.6-10.3 3.8-24.9 15.4-18l80 48c7.8 4.7 7.8 15.9 0 20.6l-80 48c-11.5 6.8-24-7.6-15.4-18l33.6-40.3-33.6-40.3zM398.9 306C390 377 329.4 432 256 432h-16c-73.4 0-134-55-142.9-126-1.2-9.5 6.3-18 15.9-18h270c9.6 0 17.1 8.4 15.9 18z\"]\n};\nvar faLaughWink = {\n prefix: 'fas',\n iconName: 'laugh-wink',\n icon: [496, 512, [], \"f59c\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm20.1 198.1c4-25.2 34.2-42.1 59.9-42.1s55.9 16.9 59.9 42.1c1.7 11.1-11.4 18.3-19.8 10.8l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L288 217c-8.4 7.4-21.6.3-19.9-10.9zM168 160c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm230.9 146C390 377 329.4 432 256 432h-16c-73.4 0-134-55-142.9-126-1.2-9.5 6.3-18 15.9-18h270c9.6 0 17.1 8.4 15.9 18z\"]\n};\nvar faLayerGroup = {\n prefix: 'fas',\n iconName: 'layer-group',\n icon: [512, 512, [], \"f5fd\", \"M12.41 148.02l232.94 105.67c6.8 3.09 14.49 3.09 21.29 0l232.94-105.67c16.55-7.51 16.55-32.52 0-40.03L266.65 2.31a25.607 25.607 0 0 0-21.29 0L12.41 107.98c-16.55 7.51-16.55 32.53 0 40.04zm487.18 88.28l-58.09-26.33-161.64 73.27c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.51 209.97l-58.1 26.33c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 276.3c16.55-7.5 16.55-32.5 0-40zm0 127.8l-57.87-26.23-161.86 73.37c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.29 337.87 12.41 364.1c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 404.1c16.55-7.5 16.55-32.5 0-40z\"]\n};\nvar faLeaf = {\n prefix: 'fas',\n iconName: 'leaf',\n icon: [576, 512, [], \"f06c\", \"M546.2 9.7c-5.6-12.5-21.6-13-28.3-1.2C486.9 62.4 431.4 96 368 96h-80C182 96 96 182 96 288c0 7 .8 13.7 1.5 20.5C161.3 262.8 253.4 224 384 224c8.8 0 16 7.2 16 16s-7.2 16-16 16C132.6 256 26 410.1 2.4 468c-6.6 16.3 1.2 34.9 17.5 41.6 16.4 6.8 35-1.1 41.8-17.3 1.5-3.6 20.9-47.9 71.9-90.6 32.4 43.9 94 85.8 174.9 77.2C465.5 467.5 576 326.7 576 154.3c0-50.2-10.8-102.2-29.8-144.6z\"]\n};\nvar faLemon = {\n prefix: 'fas',\n iconName: 'lemon',\n icon: [512, 512, [], \"f094\", \"M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z\"]\n};\nvar faLessThan = {\n prefix: 'fas',\n iconName: 'less-than',\n icon: [384, 512, [], \"f536\", \"M365.46 357.74L147.04 255.89l218.47-101.88c16.02-7.47 22.95-26.51 15.48-42.53l-13.52-29C360 66.46 340.96 59.53 324.94 67L18.48 209.91a32.014 32.014 0 0 0-18.48 29v34.24c0 12.44 7.21 23.75 18.48 29l306.31 142.83c16.06 7.49 35.15.54 42.64-15.52l13.56-29.08c7.49-16.06.54-35.15-15.53-42.64z\"]\n};\nvar faLessThanEqual = {\n prefix: 'fas',\n iconName: 'less-than-equal',\n icon: [448, 512, [], \"f537\", \"M54.98 214.2l301.41 119.87c18.39 6.03 38.71-2.54 45.38-19.15l12.09-30.08c6.68-16.61-2.82-34.97-21.21-41l-175.44-68.05 175.56-68.09c18.29-6 27.74-24.27 21.1-40.79l-12.03-29.92c-6.64-16.53-26.86-25.06-45.15-19.06L54.98 137.89C41.21 142.41 32 154.5 32 168.07v15.96c0 13.56 9.21 25.65 22.98 30.17zM424 400H24c-13.25 0-24 10.74-24 24v48c0 13.25 10.75 24 24 24h400c13.25 0 24-10.75 24-24v-48c0-13.26-10.75-24-24-24z\"]\n};\nvar faLevelDownAlt = {\n prefix: 'fas',\n iconName: 'level-down-alt',\n icon: [320, 512, [], \"f3be\", \"M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z\"]\n};\nvar faLevelUpAlt = {\n prefix: 'fas',\n iconName: 'level-up-alt',\n icon: [320, 512, [], \"f3bf\", \"M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z\"]\n};\nvar faLifeRing = {\n prefix: 'fas',\n iconName: 'life-ring',\n icon: [512, 512, [], \"f1cd\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z\"]\n};\nvar faLightbulb = {\n prefix: 'fas',\n iconName: 'lightbulb',\n icon: [352, 512, [], \"f0eb\", \"M96.06 454.35c.01 6.29 1.87 12.45 5.36 17.69l17.09 25.69a31.99 31.99 0 0 0 26.64 14.28h61.71a31.99 31.99 0 0 0 26.64-14.28l17.09-25.69a31.989 31.989 0 0 0 5.36-17.69l.04-38.35H96.01l.05 38.35zM0 176c0 44.37 16.45 84.85 43.56 115.78 16.52 18.85 42.36 58.23 52.21 91.45.04.26.07.52.11.78h160.24c.04-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45C335.55 260.85 352 220.37 352 176 352 78.61 272.91-.3 175.45 0 73.44.31 0 82.97 0 176zm176-80c-44.11 0-80 35.89-80 80 0 8.84-7.16 16-16 16s-16-7.16-16-16c0-61.76 50.24-112 112-112 8.84 0 16 7.16 16 16s-7.16 16-16 16z\"]\n};\nvar faLink = {\n prefix: 'fas',\n iconName: 'link',\n icon: [512, 512, [], \"f0c1\", \"M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z\"]\n};\nvar faLiraSign = {\n prefix: 'fas',\n iconName: 'lira-sign',\n icon: [384, 512, [], \"f195\", \"M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z\"]\n};\nvar faList = {\n prefix: 'fas',\n iconName: 'list',\n icon: [512, 512, [], \"f03a\", \"M80 368H16a16 16 0 0 0-16 16v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-64a16 16 0 0 0-16-16zm0-320H16A16 16 0 0 0 0 64v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16zm0 160H16a16 16 0 0 0-16 16v64a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-64a16 16 0 0 0-16-16zm416 176H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faListAlt = {\n prefix: 'fas',\n iconName: 'list-alt',\n icon: [512, 512, [], \"f022\", \"M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z\"]\n};\nvar faListOl = {\n prefix: 'fas',\n iconName: 'list-ol',\n icon: [512, 512, [], \"f0cb\", \"M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z\"]\n};\nvar faListUl = {\n prefix: 'fas',\n iconName: 'list-ul',\n icon: [512, 512, [], \"f0ca\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm448 16H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faLocationArrow = {\n prefix: 'fas',\n iconName: 'location-arrow',\n icon: [512, 512, [], \"f124\", \"M444.52 3.52L28.74 195.42c-47.97 22.39-31.98 92.75 19.19 92.75h175.91v175.91c0 51.17 70.36 67.17 92.75 19.19l191.9-415.78c15.99-38.39-25.59-79.97-63.97-63.97z\"]\n};\nvar faLock = {\n prefix: 'fas',\n iconName: 'lock',\n icon: [448, 512, [], \"f023\", \"M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z\"]\n};\nvar faLockOpen = {\n prefix: 'fas',\n iconName: 'lock-open',\n icon: [576, 512, [], \"f3c1\", \"M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z\"]\n};\nvar faLongArrowAltDown = {\n prefix: 'fas',\n iconName: 'long-arrow-alt-down',\n icon: [256, 512, [], \"f309\", \"M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z\"]\n};\nvar faLongArrowAltLeft = {\n prefix: 'fas',\n iconName: 'long-arrow-alt-left',\n icon: [448, 512, [], \"f30a\", \"M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z\"]\n};\nvar faLongArrowAltRight = {\n prefix: 'fas',\n iconName: 'long-arrow-alt-right',\n icon: [448, 512, [], \"f30b\", \"M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z\"]\n};\nvar faLongArrowAltUp = {\n prefix: 'fas',\n iconName: 'long-arrow-alt-up',\n icon: [256, 512, [], \"f30c\", \"M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z\"]\n};\nvar faLowVision = {\n prefix: 'fas',\n iconName: 'low-vision',\n icon: [576, 512, [], \"f2a8\", \"M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z\"]\n};\nvar faLuggageCart = {\n prefix: 'fas',\n iconName: 'luggage-cart',\n icon: [640, 512, [], \"f59d\", \"M224 320h32V96h-32c-17.67 0-32 14.33-32 32v160c0 17.67 14.33 32 32 32zm352-32V128c0-17.67-14.33-32-32-32h-32v224h32c17.67 0 32-14.33 32-32zm48 96H128V16c0-8.84-7.16-16-16-16H16C7.16 0 0 7.16 0 16v32c0 8.84 7.16 16 16 16h48v368c0 8.84 7.16 16 16 16h82.94c-1.79 5.03-2.94 10.36-2.94 16 0 26.51 21.49 48 48 48s48-21.49 48-48c0-5.64-1.15-10.97-2.94-16h197.88c-1.79 5.03-2.94 10.36-2.94 16 0 26.51 21.49 48 48 48s48-21.49 48-48c0-5.64-1.15-10.97-2.94-16H624c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM480 96V48c0-26.51-21.49-48-48-48h-96c-26.51 0-48 21.49-48 48v272h192V96zm-48 0h-96V48h96v48z\"]\n};\nvar faMagic = {\n prefix: 'fas',\n iconName: 'magic',\n icon: [512, 512, [], \"f0d0\", \"M224 96l16-32 32-16-32-16-16-32-16 32-32 16 32 16 16 32zM80 160l26.66-53.33L160 80l-53.34-26.67L80 0 53.34 53.33 0 80l53.34 26.67L80 160zm352 128l-26.66 53.33L352 368l53.34 26.67L432 448l26.66-53.33L512 368l-53.34-26.67L432 288zm70.62-193.77L417.77 9.38C411.53 3.12 403.34 0 395.15 0c-8.19 0-16.38 3.12-22.63 9.38L9.38 372.52c-12.5 12.5-12.5 32.76 0 45.25l84.85 84.85c6.25 6.25 14.44 9.37 22.62 9.37 8.19 0 16.38-3.12 22.63-9.37l363.14-363.15c12.5-12.48 12.5-32.75 0-45.24zM359.45 203.46l-50.91-50.91 86.6-86.6 50.91 50.91-86.6 86.6z\"]\n};\nvar faMagnet = {\n prefix: 'fas',\n iconName: 'magnet',\n icon: [512, 512, [], \"f076\", \"M164.07 148.1H12a12 12 0 0 1-12-12v-80a36 36 0 0 1 36-36h104a36 36 0 0 1 36 36v80a11.89 11.89 0 0 1-11.93 12zm347.93-12V56a36 36 0 0 0-36-36H372a36 36 0 0 0-36 36v80a12 12 0 0 0 12 12h152a11.89 11.89 0 0 0 12-11.9zm-164 44a12 12 0 0 0-12 12v52c0 128.1-160 127.9-160 0v-52a12 12 0 0 0-12-12H12.1a12 12 0 0 0-12 12.1c.1 21.4.6 40.3 0 53.3 0 150.6 136.17 246.6 256.75 246.6s255-96 255-246.7c-.6-12.8-.2-33 0-53.2a12 12 0 0 0-12-12.1z\"]\n};\nvar faMailBulk = {\n prefix: 'fas',\n iconName: 'mail-bulk',\n icon: [576, 512, [], \"f674\", \"M160 448c-25.6 0-51.2-22.4-64-32-64-44.8-83.2-60.8-96-70.4V480c0 17.67 14.33 32 32 32h256c17.67 0 32-14.33 32-32V345.6c-12.8 9.6-32 25.6-96 70.4-12.8 9.6-38.4 32-64 32zm128-192H32c-17.67 0-32 14.33-32 32v16c25.6 19.2 22.4 19.2 115.2 86.4 9.6 6.4 28.8 25.6 44.8 25.6s35.2-19.2 44.8-22.4c92.8-67.2 89.6-67.2 115.2-86.4V288c0-17.67-14.33-32-32-32zm256-96H224c-17.67 0-32 14.33-32 32v32h96c33.21 0 60.59 25.42 63.71 57.82l.29-.22V416h192c17.67 0 32-14.33 32-32V192c0-17.67-14.33-32-32-32zm-32 128h-64v-64h64v64zm-352-96c0-35.29 28.71-64 64-64h224V32c0-17.67-14.33-32-32-32H96C78.33 0 64 14.33 64 32v192h96v-32z\"]\n};\nvar faMale = {\n prefix: 'fas',\n iconName: 'male',\n icon: [192, 512, [], \"f183\", \"M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z\"]\n};\nvar faMap = {\n prefix: 'fas',\n iconName: 'map',\n icon: [576, 512, [], \"f279\", \"M0 117.66v346.32c0 11.32 11.43 19.06 21.94 14.86L160 416V32L20.12 87.95A32.006 32.006 0 0 0 0 117.66zM192 416l192 64V96L192 32v384zM554.06 33.16L416 96v384l139.88-55.95A31.996 31.996 0 0 0 576 394.34V48.02c0-11.32-11.43-19.06-21.94-14.86z\"]\n};\nvar faMapMarked = {\n prefix: 'fas',\n iconName: 'map-marked',\n icon: [576, 512, [], \"f59f\", \"M288 0c-69.59 0-126 56.41-126 126 0 56.26 82.35 158.8 113.9 196.02 6.39 7.54 17.82 7.54 24.2 0C331.65 284.8 414 182.26 414 126 414 56.41 357.59 0 288 0zM20.12 215.95A32.006 32.006 0 0 0 0 245.66v250.32c0 11.32 11.43 19.06 21.94 14.86L160 448V214.92c-8.84-15.98-16.07-31.54-21.25-46.42L20.12 215.95zM288 359.67c-14.07 0-27.38-6.18-36.51-16.96-19.66-23.2-40.57-49.62-59.49-76.72v182l192 64V266c-18.92 27.09-39.82 53.52-59.49 76.72-9.13 10.77-22.44 16.95-36.51 16.95zm266.06-198.51L416 224v288l139.88-55.95A31.996 31.996 0 0 0 576 426.34V176.02c0-11.32-11.43-19.06-21.94-14.86z\"]\n};\nvar faMapMarkedAlt = {\n prefix: 'fas',\n iconName: 'map-marked-alt',\n icon: [576, 512, [], \"f5a0\", \"M288 0c-69.59 0-126 56.41-126 126 0 56.26 82.35 158.8 113.9 196.02 6.39 7.54 17.82 7.54 24.2 0C331.65 284.8 414 182.26 414 126 414 56.41 357.59 0 288 0zm0 168c-23.2 0-42-18.8-42-42s18.8-42 42-42 42 18.8 42 42-18.8 42-42 42zM20.12 215.95A32.006 32.006 0 0 0 0 245.66v250.32c0 11.32 11.43 19.06 21.94 14.86L160 448V214.92c-8.84-15.98-16.07-31.54-21.25-46.42L20.12 215.95zM288 359.67c-14.07 0-27.38-6.18-36.51-16.96-19.66-23.2-40.57-49.62-59.49-76.72v182l192 64V266c-18.92 27.09-39.82 53.52-59.49 76.72-9.13 10.77-22.44 16.95-36.51 16.95zm266.06-198.51L416 224v288l139.88-55.95A31.996 31.996 0 0 0 576 426.34V176.02c0-11.32-11.43-19.06-21.94-14.86z\"]\n};\nvar faMapMarker = {\n prefix: 'fas',\n iconName: 'map-marker',\n icon: [384, 512, [], \"f041\", \"M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z\"]\n};\nvar faMapMarkerAlt = {\n prefix: 'fas',\n iconName: 'map-marker-alt',\n icon: [384, 512, [], \"f3c5\", \"M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z\"]\n};\nvar faMapPin = {\n prefix: 'fas',\n iconName: 'map-pin',\n icon: [288, 512, [], \"f276\", \"M112 316.94v156.69l22.02 33.02c4.75 7.12 15.22 7.12 19.97 0L176 473.63V316.94c-10.39 1.92-21.06 3.06-32 3.06s-21.61-1.14-32-3.06zM144 0C64.47 0 0 64.47 0 144s64.47 144 144 144 144-64.47 144-144S223.53 0 144 0zm0 76c-37.5 0-68 30.5-68 68 0 6.62-5.38 12-12 12s-12-5.38-12-12c0-50.73 41.28-92 92-92 6.62 0 12 5.38 12 12s-5.38 12-12 12z\"]\n};\nvar faMapSigns = {\n prefix: 'fas',\n iconName: 'map-signs',\n icon: [512, 512, [], \"f277\", \"M507.31 84.69L464 41.37c-6-6-14.14-9.37-22.63-9.37H288V16c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v16H56c-13.25 0-24 10.75-24 24v80c0 13.25 10.75 24 24 24h385.37c8.49 0 16.62-3.37 22.63-9.37l43.31-43.31c6.25-6.26 6.25-16.38 0-22.63zM224 496c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V384h-64v112zm232-272H288v-32h-64v32H70.63c-8.49 0-16.62 3.37-22.63 9.37L4.69 276.69c-6.25 6.25-6.25 16.38 0 22.63L48 342.63c6 6 14.14 9.37 22.63 9.37H456c13.25 0 24-10.75 24-24v-80c0-13.25-10.75-24-24-24z\"]\n};\nvar faMarker = {\n prefix: 'fas',\n iconName: 'marker',\n icon: [512, 512, [], \"f5a1\", \"M93.95 290.03A327.038 327.038 0 0 0 .17 485.11l-.03.23c-1.7 15.28 11.21 28.2 26.49 26.51a327.02 327.02 0 0 0 195.34-93.8l75.4-75.4-128.02-128.02-75.4 75.4zM485.49 26.51c-35.35-35.35-92.67-35.35-128.02 0l-21.76 21.76-36.56-36.55c-15.62-15.62-40.95-15.62-56.56 0L138.47 115.84c-6.25 6.25-6.25 16.38 0 22.63l22.62 22.62c6.25 6.25 16.38 6.25 22.63 0l87.15-87.15 19.59 19.59L191.98 192 320 320.02l165.49-165.49c35.35-35.35 35.35-92.66 0-128.02z\"]\n};\nvar faMars = {\n prefix: 'fas',\n iconName: 'mars',\n icon: [384, 512, [], \"f222\", \"M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faMarsDouble = {\n prefix: 'fas',\n iconName: 'mars-double',\n icon: [512, 512, [], \"f227\", \"M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z\"]\n};\nvar faMarsStroke = {\n prefix: 'fas',\n iconName: 'mars-stroke',\n icon: [384, 512, [], \"f229\", \"M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faMarsStrokeH = {\n prefix: 'fas',\n iconName: 'mars-stroke-h',\n icon: [480, 512, [], \"f22b\", \"M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z\"]\n};\nvar faMarsStrokeV = {\n prefix: 'fas',\n iconName: 'mars-stroke-v',\n icon: [288, 512, [], \"f22a\", \"M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z\"]\n};\nvar faMask = {\n prefix: 'fas',\n iconName: 'mask',\n icon: [640, 512, [], \"f6fa\", \"M320.67 64c-442.6 0-357.57 384-158.46 384 39.9 0 77.47-20.69 101.42-55.86l25.73-37.79c15.66-22.99 46.97-22.99 62.63 0l25.73 37.79C401.66 427.31 439.23 448 479.13 448c189.86 0 290.63-384-158.46-384zM184 308.36c-41.06 0-67.76-25.66-80.08-41.05-5.23-6.53-5.23-16.09 0-22.63 12.32-15.4 39.01-41.05 80.08-41.05s67.76 25.66 80.08 41.05c5.23 6.53 5.23 16.09 0 22.63-12.32 15.4-39.02 41.05-80.08 41.05zm272 0c-41.06 0-67.76-25.66-80.08-41.05-5.23-6.53-5.23-16.09 0-22.63 12.32-15.4 39.01-41.05 80.08-41.05s67.76 25.66 80.08 41.05c5.23 6.53 5.23 16.09 0 22.63-12.32 15.4-39.02 41.05-80.08 41.05z\"]\n};\nvar faMedal = {\n prefix: 'fas',\n iconName: 'medal',\n icon: [512, 512, [], \"f5a2\", \"M223.75 130.75L154.62 15.54A31.997 31.997 0 0 0 127.18 0H16.03C3.08 0-4.5 14.57 2.92 25.18l111.27 158.96c29.72-27.77 67.52-46.83 109.56-53.39zM495.97 0H384.82c-11.24 0-21.66 5.9-27.44 15.54l-69.13 115.21c42.04 6.56 79.84 25.62 109.56 53.38L509.08 25.18C516.5 14.57 508.92 0 495.97 0zM256 160c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm92.52 157.26l-37.93 36.96 8.97 52.22c1.6 9.36-8.26 16.51-16.65 12.09L256 393.88l-46.9 24.65c-8.4 4.45-18.25-2.74-16.65-12.09l8.97-52.22-37.93-36.96c-6.82-6.64-3.05-18.23 6.35-19.59l52.43-7.64 23.43-47.52c2.11-4.28 6.19-6.39 10.28-6.39 4.11 0 8.22 2.14 10.33 6.39l23.43 47.52 52.43 7.64c9.4 1.36 13.17 12.95 6.35 19.59z\"]\n};\nvar faMedkit = {\n prefix: 'fas',\n iconName: 'medkit',\n icon: [512, 512, [], \"f0fa\", \"M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z\"]\n};\nvar faMeh = {\n prefix: 'fas',\n iconName: 'meh',\n icon: [496, 512, [], \"f11a\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm176 192H152c-21.2 0-21.2-32 0-32h192c21.2 0 21.2 32 0 32zm-16-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faMehBlank = {\n prefix: 'fas',\n iconName: 'meh-blank',\n icon: [496, 512, [], \"f5a4\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm-80 232c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm160 0c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faMehRollingEyes = {\n prefix: 'fas',\n iconName: 'meh-rolling-eyes',\n icon: [496, 512, [], \"f5a5\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM88 224c0-24.3 13.7-45.2 33.6-56-.7 2.6-1.6 5.2-1.6 8 0 17.7 14.3 32 32 32s32-14.3 32-32c0-2.8-.9-5.4-1.6-8 19.9 10.8 33.6 31.7 33.6 56 0 35.3-28.7 64-64 64s-64-28.7-64-64zm224 176H184c-21.2 0-21.2-32 0-32h128c21.2 0 21.2 32 0 32zm32-112c-35.3 0-64-28.7-64-64 0-24.3 13.7-45.2 33.6-56-.7 2.6-1.6 5.2-1.6 8 0 17.7 14.3 32 32 32s32-14.3 32-32c0-2.8-.9-5.4-1.6-8 19.9 10.8 33.6 31.7 33.6 56 0 35.3-28.7 64-64 64z\"]\n};\nvar faMemory = {\n prefix: 'fas',\n iconName: 'memory',\n icon: [640, 512, [], \"f538\", \"M640 130.94V96c0-17.67-14.33-32-32-32H32C14.33 64 0 78.33 0 96v34.94c18.6 6.61 32 24.19 32 45.06s-13.4 38.45-32 45.06V320h640v-98.94c-18.6-6.61-32-24.19-32-45.06s13.4-38.45 32-45.06zM224 256h-64V128h64v128zm128 0h-64V128h64v128zm128 0h-64V128h64v128zM0 448h64v-26.67c0-8.84 7.16-16 16-16s16 7.16 16 16V448h128v-26.67c0-8.84 7.16-16 16-16s16 7.16 16 16V448h128v-26.67c0-8.84 7.16-16 16-16s16 7.16 16 16V448h128v-26.67c0-8.84 7.16-16 16-16s16 7.16 16 16V448h64v-96H0v96z\"]\n};\nvar faMenorah = {\n prefix: 'fas',\n iconName: 'menorah',\n icon: [640, 512, [], \"f676\", \"M144 128h-32c-8.84 0-16 7.16-16 16v144h64V144c0-8.84-7.16-16-16-16zm96 0h-32c-8.84 0-16 7.16-16 16v144h64V144c0-8.84-7.16-16-16-16zm192 0h-32c-8.84 0-16 7.16-16 16v144h64V144c0-8.84-7.16-16-16-16zm96 0h-32c-8.84 0-16 7.16-16 16v144h64V144c0-8.84-7.16-16-16-16zm80-32c17.67 0 32-14.33 32-32S608 0 608 0s-32 46.33-32 64 14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S512 0 512 0s-32 46.33-32 64 14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S416 0 416 0s-32 46.33-32 64 14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S320 0 320 0s-32 46.33-32 64 14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S224 0 224 0s-32 46.33-32 64 14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S128 0 128 0 96 46.33 96 64s14.33 32 32 32zm-96 0c17.67 0 32-14.33 32-32S32 0 32 0 0 46.33 0 64s14.33 32 32 32zm544 192c0 17.67-14.33 32-32 32H352V144c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v176H96c-17.67 0-32-14.33-32-32V144c0-8.84-7.16-16-16-16H16c-8.84 0-16 7.16-16 16v144c0 53.02 42.98 96 96 96h192v64H112c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16H352v-64h192c53.02 0 96-42.98 96-96V144c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144z\"]\n};\nvar faMercury = {\n prefix: 'fas',\n iconName: 'mercury',\n icon: [288, 512, [], \"f223\", \"M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z\"]\n};\nvar faMeteor = {\n prefix: 'fas',\n iconName: 'meteor',\n icon: [512, 512, [], \"f753\", \"M491.2.7C452.5 12.3 379.4 35 303.5 62c-2.1-7-4-13.5-5.6-18.6-3-9.7-13.9-14.2-22.9-9.5C232.6 56 122.2 116.5 60.6 176.4c-1.1 1-2.5 2-3.5 3C19 217.4 0 267.3 0 317.2 0 367 19 416.9 57 455c38 38 87.9 57.1 137.8 57 49.9 0 99.8-19 137.9-57.1 1-1 2-2.4 3-3.5 59.8-61.6 120.4-172.1 142.5-214.4 4.7-9 .2-19.9-9.5-22.9-5.2-1.6-11.6-3.5-18.6-5.6 27-76 49.7-149 61.3-187.7C515 8.4 503.6-3 491.2.7zM192 448c-70.7 0-128-57.3-128-128s57.3-128 128-128 128 57.3 128 128-57.3 128-128 128zm-32-192c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm48 96c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16z\"]\n};\nvar faMicrochip = {\n prefix: 'fas',\n iconName: 'microchip',\n icon: [512, 512, [], \"f2db\", \"M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z\"]\n};\nvar faMicrophone = {\n prefix: 'fas',\n iconName: 'microphone',\n icon: [352, 512, [], \"f130\", \"M176 352c53.02 0 96-42.98 96-96V96c0-53.02-42.98-96-96-96S80 42.98 80 96v160c0 53.02 42.98 96 96 96zm160-160h-16c-8.84 0-16 7.16-16 16v48c0 74.8-64.49 134.82-140.79 127.38C96.71 376.89 48 317.11 48 250.3V208c0-8.84-7.16-16-16-16H16c-8.84 0-16 7.16-16 16v40.16c0 89.64 63.97 169.55 152 181.69V464H96c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16h-56v-33.77C285.71 418.47 352 344.9 352 256v-48c0-8.84-7.16-16-16-16z\"]\n};\nvar faMicrophoneAlt = {\n prefix: 'fas',\n iconName: 'microphone-alt',\n icon: [352, 512, [], \"f3c9\", \"M336 192h-16c-8.84 0-16 7.16-16 16v48c0 74.8-64.49 134.82-140.79 127.38C96.71 376.89 48 317.11 48 250.3V208c0-8.84-7.16-16-16-16H16c-8.84 0-16 7.16-16 16v40.16c0 89.64 63.97 169.55 152 181.69V464H96c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16h-56v-33.77C285.71 418.47 352 344.9 352 256v-48c0-8.84-7.16-16-16-16zM176 352c53.02 0 96-42.98 96-96h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H272c0-53.02-42.98-96-96-96S80 42.98 80 96v160c0 53.02 42.98 96 96 96z\"]\n};\nvar faMicrophoneAltSlash = {\n prefix: 'fas',\n iconName: 'microphone-alt-slash',\n icon: [640, 512, [], \"f539\", \"M633.82 458.1L476.26 336.33C488.74 312.21 496 284.98 496 256v-48c0-8.84-7.16-16-16-16h-16c-8.84 0-16 7.16-16 16v48c0 17.92-3.96 34.8-10.72 50.2l-26.55-20.52c3.1-9.4 5.28-19.22 5.28-29.67h-43.67l-41.4-32H416v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H416v-32h-85.33c-5.89 0-10.67-3.58-10.67-8v-16c0-4.42 4.78-8 10.67-8H416c0-53.02-42.98-96-96-96s-96 42.98-96 96v45.36L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.36 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.41-6.97 4.16-17.02-2.82-22.45zM400 464h-56v-33.78c11.71-1.62 23.1-4.28 33.96-8.08l-50.4-38.96c-6.71.4-13.41.87-20.35.2-55.85-5.45-98.74-48.63-111.18-101.85L144 241.31v6.85c0 89.64 63.97 169.55 152 181.69V464h-56c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16z\"]\n};\nvar faMicrophoneSlash = {\n prefix: 'fas',\n iconName: 'microphone-slash',\n icon: [640, 512, [], \"f131\", \"M633.82 458.1l-157.8-121.96C488.61 312.13 496 285.01 496 256v-48c0-8.84-7.16-16-16-16h-16c-8.84 0-16 7.16-16 16v48c0 17.92-3.96 34.8-10.72 50.2l-26.55-20.52c3.1-9.4 5.28-19.22 5.28-29.67V96c0-53.02-42.98-96-96-96s-96 42.98-96 96v45.36L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.36 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.41-6.97 4.16-17.02-2.82-22.45zM400 464h-56v-33.77c11.66-1.6 22.85-4.54 33.67-8.31l-50.11-38.73c-6.71.4-13.41.87-20.35.2-55.85-5.45-98.74-48.63-111.18-101.85L144 241.31v6.85c0 89.64 63.97 169.55 152 181.69V464h-56c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h160c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16z\"]\n};\nvar faMicroscope = {\n prefix: 'fas',\n iconName: 'microscope',\n icon: [512, 512, [], \"f610\", \"M160 320h12v16c0 8.84 7.16 16 16 16h40c8.84 0 16-7.16 16-16v-16h12c17.67 0 32-14.33 32-32V64c0-17.67-14.33-32-32-32V16c0-8.84-7.16-16-16-16h-64c-8.84 0-16 7.16-16 16v16c-17.67 0-32 14.33-32 32v224c0 17.67 14.33 32 32 32zm304 128h-1.29C493.24 413.99 512 369.2 512 320c0-105.88-86.12-192-192-192v64c70.58 0 128 57.42 128 128s-57.42 128-128 128H48c-26.51 0-48 21.49-48 48 0 8.84 7.16 16 16 16h480c8.84 0 16-7.16 16-16 0-26.51-21.49-48-48-48zm-360-32h208c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8H104c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8z\"]\n};\nvar faMinus = {\n prefix: 'fas',\n iconName: 'minus',\n icon: [448, 512, [], \"f068\", \"M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n};\nvar faMinusCircle = {\n prefix: 'fas',\n iconName: 'minus-circle',\n icon: [512, 512, [], \"f056\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z\"]\n};\nvar faMinusSquare = {\n prefix: 'fas',\n iconName: 'minus-square',\n icon: [448, 512, [], \"f146\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z\"]\n};\nvar faMitten = {\n prefix: 'fas',\n iconName: 'mitten',\n icon: [448, 512, [], \"f7b5\", \"M368 416H48c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h320c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16zm57-209.1c-27.2-22.6-67.5-19-90.1 8.2l-20.9 25-29.6-128.4c-18-77.5-95.4-125.9-172.8-108C34.2 21.6-14.2 98.9 3.7 176.4L51.6 384h309l72.5-87c22.7-27.2 19-67.5-8.1-90.1z\"]\n};\nvar faMobile = {\n prefix: 'fas',\n iconName: 'mobile',\n icon: [320, 512, [], \"f10b\", \"M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faMobileAlt = {\n prefix: 'fas',\n iconName: 'mobile-alt',\n icon: [320, 512, [], \"f3cd\", \"M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z\"]\n};\nvar faMoneyBill = {\n prefix: 'fas',\n iconName: 'money-bill',\n icon: [640, 512, [], \"f0d6\", \"M608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 176c-44.19 0-80-42.99-80-96 0-53.02 35.82-96 80-96s80 42.98 80 96c0 53.03-35.83 96-80 96zm272 48h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z\"]\n};\nvar faMoneyBillAlt = {\n prefix: 'fas',\n iconName: 'money-bill-alt',\n icon: [640, 512, [], \"f3d1\", \"M352 288h-16v-88c0-4.42-3.58-8-8-8h-13.58c-4.74 0-9.37 1.4-13.31 4.03l-15.33 10.22a7.994 7.994 0 0 0-2.22 11.09l8.88 13.31a7.994 7.994 0 0 0 11.09 2.22l.47-.31V288h-16c-4.42 0-8 3.58-8 8v16c0 4.42 3.58 8 8 8h64c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zM608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM48 400v-64c35.35 0 64 28.65 64 64H48zm0-224v-64h64c0 35.35-28.65 64-64 64zm272 192c-53.02 0-96-50.15-96-112 0-61.86 42.98-112 96-112s96 50.14 96 112c0 61.87-43 112-96 112zm272 32h-64c0-35.35 28.65-64 64-64v64zm0-224c-35.35 0-64-28.65-64-64h64v64z\"]\n};\nvar faMoneyBillWave = {\n prefix: 'fas',\n iconName: 'money-bill-wave',\n icon: [640, 512, [], \"f53a\", \"M621.16 54.46C582.37 38.19 543.55 32 504.75 32c-123.17-.01-246.33 62.34-369.5 62.34-30.89 0-61.76-3.92-92.65-13.72-3.47-1.1-6.95-1.62-10.35-1.62C15.04 79 0 92.32 0 110.81v317.26c0 12.63 7.23 24.6 18.84 29.46C57.63 473.81 96.45 480 135.25 480c123.17 0 246.34-62.35 369.51-62.35 30.89 0 61.76 3.92 92.65 13.72 3.47 1.1 6.95 1.62 10.35 1.62 17.21 0 32.25-13.32 32.25-31.81V83.93c-.01-12.64-7.24-24.6-18.85-29.47zM48 132.22c20.12 5.04 41.12 7.57 62.72 8.93C104.84 170.54 79 192.69 48 192.69v-60.47zm0 285v-47.78c34.37 0 62.18 27.27 63.71 61.4-22.53-1.81-43.59-6.31-63.71-13.62zM320 352c-44.19 0-80-42.99-80-96 0-53.02 35.82-96 80-96s80 42.98 80 96c0 53.03-35.83 96-80 96zm272 27.78c-17.52-4.39-35.71-6.85-54.32-8.44 5.87-26.08 27.5-45.88 54.32-49.28v57.72zm0-236.11c-30.89-3.91-54.86-29.7-55.81-61.55 19.54 2.17 38.09 6.23 55.81 12.66v48.89z\"]\n};\nvar faMoneyBillWaveAlt = {\n prefix: 'fas',\n iconName: 'money-bill-wave-alt',\n icon: [640, 512, [], \"f53b\", \"M621.16 54.46C582.37 38.19 543.55 32 504.75 32c-123.17-.01-246.33 62.34-369.5 62.34-30.89 0-61.76-3.92-92.65-13.72-3.47-1.1-6.95-1.62-10.35-1.62C15.04 79 0 92.32 0 110.81v317.26c0 12.63 7.23 24.6 18.84 29.46C57.63 473.81 96.45 480 135.25 480c123.17 0 246.34-62.35 369.51-62.35 30.89 0 61.76 3.92 92.65 13.72 3.47 1.1 6.95 1.62 10.35 1.62 17.21 0 32.25-13.32 32.25-31.81V83.93c-.01-12.64-7.24-24.6-18.85-29.47zM320 352c-44.19 0-80-42.99-80-96 0-53.02 35.82-96 80-96s80 42.98 80 96c0 53.03-35.83 96-80 96z\"]\n};\nvar faMoneyCheck = {\n prefix: 'fas',\n iconName: 'money-check',\n icon: [640, 512, [], \"f53c\", \"M0 448c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V128H0v320zm448-208c0-8.84 7.16-16 16-16h96c8.84 0 16 7.16 16 16v32c0 8.84-7.16 16-16 16h-96c-8.84 0-16-7.16-16-16v-32zm0 120c0-4.42 3.58-8 8-8h112c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H456c-4.42 0-8-3.58-8-8v-16zM64 264c0-4.42 3.58-8 8-8h304c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16zm0 96c0-4.42 3.58-8 8-8h176c4.42 0 8 3.58 8 8v16c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16zM624 32H16C7.16 32 0 39.16 0 48v48h640V48c0-8.84-7.16-16-16-16z\"]\n};\nvar faMoneyCheckAlt = {\n prefix: 'fas',\n iconName: 'money-check-alt',\n icon: [640, 512, [], \"f53d\", \"M608 32H32C14.33 32 0 46.33 0 64v384c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V64c0-17.67-14.33-32-32-32zM176 327.88V344c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-16.29c-11.29-.58-22.27-4.52-31.37-11.35-3.9-2.93-4.1-8.77-.57-12.14l11.75-11.21c2.77-2.64 6.89-2.76 10.13-.73 3.87 2.42 8.26 3.72 12.82 3.72h28.11c6.5 0 11.8-5.92 11.8-13.19 0-5.95-3.61-11.19-8.77-12.73l-45-13.5c-18.59-5.58-31.58-23.42-31.58-43.39 0-24.52 19.05-44.44 42.67-45.07V152c0-4.42 3.58-8 8-8h16c4.42 0 8 3.58 8 8v16.29c11.29.58 22.27 4.51 31.37 11.35 3.9 2.93 4.1 8.77.57 12.14l-11.75 11.21c-2.77 2.64-6.89 2.76-10.13.73-3.87-2.43-8.26-3.72-12.82-3.72h-28.11c-6.5 0-11.8 5.92-11.8 13.19 0 5.95 3.61 11.19 8.77 12.73l45 13.5c18.59 5.58 31.58 23.42 31.58 43.39 0 24.53-19.05 44.44-42.67 45.07zM416 312c0 4.42-3.58 8-8 8H296c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h112c4.42 0 8 3.58 8 8v16zm160 0c0 4.42-3.58 8-8 8h-80c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h80c4.42 0 8 3.58 8 8v16zm0-96c0 4.42-3.58 8-8 8H296c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h272c4.42 0 8 3.58 8 8v16z\"]\n};\nvar faMonument = {\n prefix: 'fas',\n iconName: 'monument',\n icon: [384, 512, [], \"f5a6\", \"M368 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h352c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-78.86-347.26a31.97 31.97 0 0 0-9.21-19.44L203.31 4.69c-6.25-6.25-16.38-6.25-22.63 0l-76.6 76.61a31.97 31.97 0 0 0-9.21 19.44L64 416h256l-30.86-315.26zM240 307.2c0 6.4-6.4 12.8-12.8 12.8h-70.4c-6.4 0-12.8-6.4-12.8-12.8v-38.4c0-6.4 6.4-12.8 12.8-12.8h70.4c6.4 0 12.8 6.4 12.8 12.8v38.4z\"]\n};\nvar faMoon = {\n prefix: 'fas',\n iconName: 'moon',\n icon: [512, 512, [], \"f186\", \"M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z\"]\n};\nvar faMortarPestle = {\n prefix: 'fas',\n iconName: 'mortar-pestle',\n icon: [512, 512, [], \"f5a7\", \"M501.54 60.91c17.22-17.22 12.51-46.25-9.27-57.14a35.696 35.696 0 0 0-37.37 3.37L251.09 160h151.37l99.08-99.09zM496 192H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h16c0 80.98 50.2 150.11 121.13 178.32-12.76 16.87-21.72 36.8-24.95 58.69-1.46 9.92 6.04 18.98 16.07 18.98h223.5c10.03 0 17.53-9.06 16.07-18.98-3.22-21.89-12.18-41.82-24.95-58.69C429.8 406.11 480 336.98 480 256h16c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faMosque = {\n prefix: 'fas',\n iconName: 'mosque',\n icon: [640, 512, [], \"f678\", \"M0 480c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32V160H0v320zm579.16-192c17.86-17.39 28.84-37.34 28.84-58.91 0-52.86-41.79-93.79-87.92-122.9-41.94-26.47-80.63-57.77-111.96-96.22L400 0l-8.12 9.97c-31.33 38.45-70.01 69.76-111.96 96.22C233.79 135.3 192 176.23 192 229.09c0 21.57 10.98 41.52 28.84 58.91h358.32zM608 320H192c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h32v-64c0-17.67 14.33-32 32-32s32 14.33 32 32v64h64v-72c0-48 48-72 48-72s48 24 48 72v72h64v-64c0-17.67 14.33-32 32-32s32 14.33 32 32v64h32c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32zM64 0S0 32 0 96v32h128V96c0-64-64-96-64-96z\"]\n};\nvar faMotorcycle = {\n prefix: 'fas',\n iconName: 'motorcycle',\n icon: [640, 512, [], \"f21c\", \"M512.9 192c-14.9-.1-29.1 2.3-42.4 6.9L437.6 144H520c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24h-45.3c-6.8 0-13.3 2.9-17.8 7.9l-37.5 41.7-22.8-38C392.2 68.4 384.4 64 376 64h-80c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h66.4l19.2 32H227.9c-17.7-23.1-44.9-40-99.9-40H72.5C59 104 47.7 115 48 128.5c.2 13 10.9 23.5 24 23.5h56c24.5 0 38.7 10.9 47.8 24.8l-11.3 20.5c-13-3.9-26.9-5.7-41.3-5.2C55.9 194.5 1.6 249.6 0 317c-1.6 72.1 56.3 131 128 131 59.6 0 109.7-40.8 124-96h84.2c13.7 0 24.6-11.4 24-25.1-2.1-47.1 17.5-93.7 56.2-125l12.5 20.8c-27.6 23.7-45.1 58.9-44.8 98.2.5 69.6 57.2 126.5 126.8 127.1 71.6.7 129.8-57.5 129.2-129.1-.7-69.6-57.6-126.4-127.2-126.9zM128 400c-44.1 0-80-35.9-80-80s35.9-80 80-80c4.2 0 8.4.3 12.5 1L99 316.4c-8.8 16 2.8 35.6 21 35.6h81.3c-12.4 28.2-40.6 48-73.3 48zm463.9-75.6c-2.2 40.6-35 73.4-75.5 75.5-46.1 2.5-84.4-34.3-84.4-79.9 0-21.4 8.4-40.8 22.1-55.1l49.4 82.4c4.5 7.6 14.4 10 22 5.5l13.7-8.2c7.6-4.5 10-14.4 5.5-22l-48.6-80.9c5.2-1.1 10.5-1.6 15.9-1.6 45.6-.1 82.3 38.2 79.9 84.3z\"]\n};\nvar faMountain = {\n prefix: 'fas',\n iconName: 'mountain',\n icon: [640, 512, [], \"f6fc\", \"M634.92 462.7l-288-448C341.03 5.54 330.89 0 320 0s-21.03 5.54-26.92 14.7l-288 448a32.001 32.001 0 0 0-1.17 32.64A32.004 32.004 0 0 0 32 512h576c11.71 0 22.48-6.39 28.09-16.67a31.983 31.983 0 0 0-1.17-32.63zM320 91.18L405.39 224H320l-64 64-38.06-38.06L320 91.18z\"]\n};\nvar faMousePointer = {\n prefix: 'fas',\n iconName: 'mouse-pointer',\n icon: [320, 512, [], \"f245\", \"M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z\"]\n};\nvar faMugHot = {\n prefix: 'fas',\n iconName: 'mug-hot',\n icon: [512, 512, [], \"f7b6\", \"M127.1 146.5c1.3 7.7 8 13.5 16 13.5h16.5c9.8 0 17.6-8.5 16.3-18-3.8-28.2-16.4-54.2-36.6-74.7-14.4-14.7-23.6-33.3-26.4-53.5C111.8 5.9 105 0 96.8 0H80.4C70.6 0 63 8.5 64.1 18c3.9 31.9 18 61.3 40.6 84.4 12 12.2 19.7 27.5 22.4 44.1zm112 0c1.3 7.7 8 13.5 16 13.5h16.5c9.8 0 17.6-8.5 16.3-18-3.8-28.2-16.4-54.2-36.6-74.7-14.4-14.7-23.6-33.3-26.4-53.5C223.8 5.9 217 0 208.8 0h-16.4c-9.8 0-17.5 8.5-16.3 18 3.9 31.9 18 61.3 40.6 84.4 12 12.2 19.7 27.5 22.4 44.1zM400 192H32c-17.7 0-32 14.3-32 32v192c0 53 43 96 96 96h192c53 0 96-43 96-96h16c61.8 0 112-50.2 112-112s-50.2-112-112-112zm0 160h-16v-96h16c26.5 0 48 21.5 48 48s-21.5 48-48 48z\"]\n};\nvar faMusic = {\n prefix: 'fas',\n iconName: 'music',\n icon: [512, 512, [], \"f001\", \"M511.99 32.01c0-21.71-21.1-37.01-41.6-30.51L150.4 96c-13.3 4.2-22.4 16.5-22.4 30.5v261.42c-10.05-2.38-20.72-3.92-32-3.92-53.02 0-96 28.65-96 64s42.98 64 96 64 96-28.65 96-64V214.31l256-75.02v184.63c-10.05-2.38-20.72-3.92-32-3.92-53.02 0-96 28.65-96 64s42.98 64 96 64 96-28.65 96-64l-.01-351.99z\"]\n};\nvar faNetworkWired = {\n prefix: 'fas',\n iconName: 'network-wired',\n icon: [640, 512, [], \"f6ff\", \"M640 264v-16c0-8.84-7.16-16-16-16H344v-40h72c17.67 0 32-14.33 32-32V32c0-17.67-14.33-32-32-32H224c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h72v40H16c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h104v40H64c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h160c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32h-56v-40h304v40h-56c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h160c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32h-56v-40h104c8.84 0 16-7.16 16-16zM256 128V64h128v64H256zm-64 320H96v-64h96v64zm352 0h-96v-64h96v64z\"]\n};\nvar faNeuter = {\n prefix: 'fas',\n iconName: 'neuter',\n icon: [288, 512, [], \"f22c\", \"M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faNewspaper = {\n prefix: 'fas',\n iconName: 'newspaper',\n icon: [576, 512, [], \"f1ea\", \"M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z\"]\n};\nvar faNotEqual = {\n prefix: 'fas',\n iconName: 'not-equal',\n icon: [448, 512, [], \"f53e\", \"M416 208c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32h-23.88l51.87-66.81c5.37-7.02 4.04-17.06-2.97-22.43L415.61 3.3c-7.02-5.38-17.06-4.04-22.44 2.97L311.09 112H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h204.56l-74.53 96H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h55.49l-51.87 66.81c-5.37 7.01-4.04 17.05 2.97 22.43L64 508.7c7.02 5.38 17.06 4.04 22.43-2.97L168.52 400H416c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32H243.05l74.53-96H416z\"]\n};\nvar faNotesMedical = {\n prefix: 'fas',\n iconName: 'notes-medical',\n icon: [384, 512, [], \"f481\", \"M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm96 304c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48zm0-192c0 4.4-3.6 8-8 8H104c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h176c4.4 0 8 3.6 8 8v16z\"]\n};\nvar faObjectGroup = {\n prefix: 'fas',\n iconName: 'object-group',\n icon: [512, 512, [], \"f247\", \"M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z\"]\n};\nvar faObjectUngroup = {\n prefix: 'fas',\n iconName: 'object-ungroup',\n icon: [576, 512, [], \"f248\", \"M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z\"]\n};\nvar faOilCan = {\n prefix: 'fas',\n iconName: 'oil-can',\n icon: [640, 512, [], \"f613\", \"M629.8 160.31L416 224l-50.49-25.24a64.07 64.07 0 0 0-28.62-6.76H280v-48h56c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16H176c-8.84 0-16 7.16-16 16v16c0 8.84 7.16 16 16 16h56v48h-56L37.72 166.86a31.9 31.9 0 0 0-5.79-.53C14.67 166.33 0 180.36 0 198.34v94.95c0 15.46 11.06 28.72 26.28 31.48L96 337.46V384c0 17.67 14.33 32 32 32h274.63c8.55 0 16.75-3.42 22.76-9.51l212.26-214.75c1.5-1.5 2.34-3.54 2.34-5.66V168c.01-5.31-5.08-9.15-10.19-7.69zM96 288.67l-48-8.73v-62.43l48 8.73v62.43zm453.33 84.66c0 23.56 19.1 42.67 42.67 42.67s42.67-19.1 42.67-42.67S592 288 592 288s-42.67 61.77-42.67 85.33z\"]\n};\nvar faOm = {\n prefix: 'fas',\n iconName: 'om',\n icon: [512, 512, [], \"f679\", \"M360.6 60.94a10.43 10.43 0 0 0 14.76 0l21.57-21.56a10.43 10.43 0 0 0 0-14.76L375.35 3.06c-4.08-4.07-10.68-4.07-14.76 0l-21.57 21.56a10.43 10.43 0 0 0 0 14.76l21.58 21.56zM412.11 192c-26.69 0-51.77 10.39-70.64 29.25l-24.25 24.25c-6.78 6.77-15.78 10.5-25.38 10.5H245c10.54-22.1 14.17-48.11 7.73-75.23-10.1-42.55-46.36-76.11-89.52-83.19-36.15-5.93-70.9 5.04-96.01 28.78-7.36 6.96-6.97 18.85 1.12 24.93l26.15 19.63c5.72 4.3 13.66 4.32 19.2-.21 8.45-6.9 19.02-10.71 30.27-10.71 26.47 0 48.01 21.53 48.01 48s-21.54 48-48.01 48h-31.9c-11.96 0-19.74 12.58-14.39 23.28l16.09 32.17c2.53 5.06 7.6 8.1 13.17 8.55h33.03c35.3 0 64.01 28.7 64.01 64s-28.71 64-64.01 64c-96.02 0-122.35-54.02-145.15-92.03-4.53-7.55-14.77-3.58-14.79 5.22C-.09 416 41.13 512 159.94 512c70.59 0 128.02-57.42 128.02-128 0-23.42-6.78-45.1-17.81-64h21.69c26.69 0 51.77-10.39 70.64-29.25l24.25-24.25c6.78-6.77 15.78-10.5 25.38-10.5 19.78 0 35.88 16.09 35.88 35.88V392c0 13.23-18.77 24-32.01 24-39.4 0-66.67-24.24-81.82-42.89-4.77-5.87-14.2-2.54-14.2 5.02V416s0 64 96.02 64c48.54 0 96.02-39.47 96.02-88V291.88c0-55.08-44.8-99.88-99.89-99.88zm42.18-124.73c-85.55 65.12-169.05 2.75-172.58.05-6.02-4.62-14.44-4.38-20.14.55-5.74 4.92-7.27 13.17-3.66 19.8 1.61 2.95 40.37 72.34 118.8 72.34 79.92 0 98.78-31.36 101.75-37.66 1.02-2.12 1.53-4.47 1.53-6.83V80c0-13.22-15.14-20.69-25.7-12.73z\"]\n};\nvar faOtter = {\n prefix: 'fas',\n iconName: 'otter',\n icon: [640, 512, [], \"f700\", \"M608 32h-32l-13.25-13.25A63.97 63.97 0 0 0 517.49 0H497c-11.14 0-22.08 2.91-31.75 8.43L312 96h-56C149.96 96 64 181.96 64 288v1.61c0 32.75-16 62.14-39.56 84.89-18.19 17.58-28.1 43.68-23.19 71.8 6.76 38.8 42.9 65.7 82.28 65.7H192c17.67 0 32-14.33 32-32s-14.33-32-32-32H80c-8.83 0-16-7.17-16-16s7.17-16 16-16h224c8.84 0 16-7.16 16-16v-16c0-17.67-14.33-32-32-32h-64l149.49-80.5L448 416h80c8.84 0 16-7.16 16-16v-16c0-17.67-14.33-32-32-32h-28.22l-55.11-110.21L521.14 192H544c53.02 0 96-42.98 96-96V64c0-17.67-14.33-32-32-32zm-96 16c8.84 0 16 7.16 16 16s-7.16 16-16 16-16-7.16-16-16 7.16-16 16-16zm32 96h-34.96L407.2 198.84l-13.77-27.55L512 112h77.05c-6.62 18.58-24.22 32-45.05 32z\"]\n};\nvar faOutdent = {\n prefix: 'fas',\n iconName: 'outdent',\n icon: [448, 512, [], \"f03b\", \"M100.69 363.29c10 10 27.31 2.93 27.31-11.31V160c0-14.32-17.33-21.31-27.31-11.31l-96 96a16 16 0 0 0 0 22.62zM432 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm3.17-128H204.83A12.82 12.82 0 0 0 192 300.83v38.34A12.82 12.82 0 0 0 204.83 352h230.34A12.82 12.82 0 0 0 448 339.17v-38.34A12.82 12.82 0 0 0 435.17 288zm0-128H204.83A12.82 12.82 0 0 0 192 172.83v38.34A12.82 12.82 0 0 0 204.83 224h230.34A12.82 12.82 0 0 0 448 211.17v-38.34A12.82 12.82 0 0 0 435.17 160zM432 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faPager = {\n prefix: 'fas',\n iconName: 'pager',\n icon: [512, 512, [], \"f815\", \"M448 64H64a64 64 0 0 0-64 64v256a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V128a64 64 0 0 0-64-64zM160 368H80a16 16 0 0 1-16-16v-16a16 16 0 0 1 16-16h80zm128-16a16 16 0 0 1-16 16h-80v-48h80a16 16 0 0 1 16 16zm160-128a32 32 0 0 1-32 32H96a32 32 0 0 1-32-32v-64a32 32 0 0 1 32-32h320a32 32 0 0 1 32 32z\"]\n};\nvar faPaintBrush = {\n prefix: 'fas',\n iconName: 'paint-brush',\n icon: [512, 512, [], \"f1fc\", \"M167.02 309.34c-40.12 2.58-76.53 17.86-97.19 72.3-2.35 6.21-8 9.98-14.59 9.98-11.11 0-45.46-27.67-55.25-34.35C0 439.62 37.93 512 128 512c75.86 0 128-43.77 128-120.19 0-3.11-.65-6.08-.97-9.13l-88.01-73.34zM457.89 0c-15.16 0-29.37 6.71-40.21 16.45C213.27 199.05 192 203.34 192 257.09c0 13.7 3.25 26.76 8.73 38.7l63.82 53.18c7.21 1.8 14.64 3.03 22.39 3.03 62.11 0 98.11-45.47 211.16-256.46 7.38-14.35 13.9-29.85 13.9-45.99C512 20.64 486 0 457.89 0z\"]\n};\nvar faPaintRoller = {\n prefix: 'fas',\n iconName: 'paint-roller',\n icon: [512, 512, [], \"f5aa\", \"M416 128V32c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v96c0 17.67 14.33 32 32 32h352c17.67 0 32-14.33 32-32zm32-64v128c0 17.67-14.33 32-32 32H256c-35.35 0-64 28.65-64 64v32c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32v-32h160c53.02 0 96-42.98 96-96v-64c0-35.35-28.65-64-64-64z\"]\n};\nvar faPalette = {\n prefix: 'fas',\n iconName: 'palette',\n icon: [512, 512, [], \"f53f\", \"M204.3 5C104.9 24.4 24.8 104.3 5.2 203.4c-37 187 131.7 326.4 258.8 306.7 41.2-6.4 61.4-54.6 42.5-91.7-23.1-45.4 9.9-98.4 60.9-98.4h79.7c35.8 0 64.8-29.6 64.9-65.3C511.5 97.1 368.1-26.9 204.3 5zM96 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm32-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128-64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faPallet = {\n prefix: 'fas',\n iconName: 'pallet',\n icon: [640, 512, [], \"f482\", \"M144 256h352c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16H384v128l-64-32-64 32V0H144c-8.8 0-16 7.2-16 16v224c0 8.8 7.2 16 16 16zm480 128c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v64H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16h-48v-64h48zm-336 64H128v-64h160v64zm224 0H352v-64h160v64z\"]\n};\nvar faPaperPlane = {\n prefix: 'fas',\n iconName: 'paper-plane',\n icon: [512, 512, [], \"f1d8\", \"M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z\"]\n};\nvar faPaperclip = {\n prefix: 'fas',\n iconName: 'paperclip',\n icon: [448, 512, [], \"f0c6\", \"M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z\"]\n};\nvar faParachuteBox = {\n prefix: 'fas',\n iconName: 'parachute-box',\n icon: [512, 512, [], \"f4cd\", \"M511.9 175c-9.1-75.6-78.4-132.4-158.3-158.7C390 55.7 416 116.9 416 192h28.1L327.5 321.5c-2.5-.6-4.8-1.5-7.5-1.5h-48V192h112C384 76.8 315.1 0 256 0S128 76.8 128 192h112v128h-48c-2.7 0-5 .9-7.5 1.5L67.9 192H96c0-75.1 26-136.3 62.4-175.7C78.5 42.7 9.2 99.5.1 175c-1.1 9.1 6.8 17 16 17h8.7l136.7 151.9c-.7 2.6-1.6 5.2-1.6 8.1v128c0 17.7 14.3 32 32 32h128c17.7 0 32-14.3 32-32V352c0-2.9-.9-5.4-1.6-8.1L487.1 192h8.7c9.3 0 17.2-7.8 16.1-17z\"]\n};\nvar faParagraph = {\n prefix: 'fas',\n iconName: 'paragraph',\n icon: [448, 512, [], \"f1dd\", \"M448 48v32a16 16 0 0 1-16 16h-48v368a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16V96h-32v368a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16V352h-32a160 160 0 0 1 0-320h240a16 16 0 0 1 16 16z\"]\n};\nvar faParking = {\n prefix: 'fas',\n iconName: 'parking',\n icon: [448, 512, [], \"f540\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM240 320h-48v48c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h96c52.9 0 96 43.1 96 96s-43.1 96-96 96zm0-128h-48v64h48c17.6 0 32-14.4 32-32s-14.4-32-32-32z\"]\n};\nvar faPassport = {\n prefix: 'fas',\n iconName: 'passport',\n icon: [448, 512, [], \"f5ab\", \"M129.62 176h39.09c1.49-27.03 6.54-51.35 14.21-70.41-27.71 13.24-48.02 39.19-53.3 70.41zm0 32c5.29 31.22 25.59 57.17 53.3 70.41-7.68-19.06-12.72-43.38-14.21-70.41h-39.09zM224 286.69c7.69-7.45 20.77-34.42 23.43-78.69h-46.87c2.67 44.26 15.75 71.24 23.44 78.69zM200.57 176h46.87c-2.66-44.26-15.74-71.24-23.43-78.69-7.7 7.45-20.78 34.43-23.44 78.69zm64.51 102.41c27.71-13.24 48.02-39.19 53.3-70.41h-39.09c-1.49 27.03-6.53 51.35-14.21 70.41zM416 0H64C28.65 0 0 28.65 0 64v384c0 35.35 28.65 64 64 64h352c17.67 0 32-14.33 32-32V32c0-17.67-14.33-32-32-32zm-80 416H112c-8.8 0-16-7.2-16-16s7.2-16 16-16h224c8.8 0 16 7.2 16 16s-7.2 16-16 16zm-112-96c-70.69 0-128-57.31-128-128S153.31 64 224 64s128 57.31 128 128-57.31 128-128 128zm41.08-214.41c7.68 19.06 12.72 43.38 14.21 70.41h39.09c-5.28-31.22-25.59-57.17-53.3-70.41z\"]\n};\nvar faPastafarianism = {\n prefix: 'fas',\n iconName: 'pastafarianism',\n icon: [640, 512, [], \"f67b\", \"M624.54 347.67c-32.7-12.52-57.36 4.25-75.37 16.45-17.06 11.53-23.25 14.42-31.41 11.36-8.12-3.09-10.83-9.38-15.89-29.38-3.33-13.15-7.44-29.32-17.95-42.65 2.24-2.91 4.43-5.79 6.38-8.57C500.47 304.45 513.71 312 532 312c33.95 0 50.87-25.78 62.06-42.83 10.59-16.14 15-21.17 21.94-21.17 13.25 0 24-10.75 24-24s-10.75-24-24-24c-33.95 0-50.87 25.78-62.06 42.83-10.6 16.14-15 21.17-21.94 21.17-17.31 0-37.48-61.43-97.26-101.91l17.25-34.5C485.43 125.5 512 97.98 512 64c0-35.35-28.65-64-64-64s-64 28.65-64 64c0 13.02 3.94 25.1 10.62 35.21l-18.15 36.3c-16.98-4.6-35.6-7.51-56.46-7.51s-39.49 2.91-56.46 7.51l-18.15-36.3C252.06 89.1 256 77.02 256 64c0-35.35-28.65-64-64-64s-64 28.65-64 64c0 33.98 26.56 61.5 60.02 63.6l17.25 34.5C145.68 202.44 125.15 264 108 264c-6.94 0-11.34-5.03-21.94-21.17C74.88 225.78 57.96 200 24 200c-13.25 0-24 10.75-24 24s10.75 24 24 24c6.94 0 11.34 5.03 21.94 21.17C57.13 286.22 74.05 312 108 312c18.29 0 31.53-7.55 41.7-17.11 1.95 2.79 4.14 5.66 6.38 8.57-10.51 13.33-14.62 29.5-17.95 42.65-5.06 20-7.77 26.28-15.89 29.38-8.11 3.06-14.33.17-31.41-11.36-18.03-12.2-42.72-28.92-75.37-16.45-12.39 4.72-18.59 18.58-13.87 30.97 4.72 12.41 18.61 18.61 30.97 13.88 8.16-3.09 14.34-.19 31.39 11.36 13.55 9.16 30.83 20.86 52.42 20.84 7.17 0 14.83-1.28 22.97-4.39 32.66-12.44 39.98-41.33 45.33-62.44 2.21-8.72 3.99-14.49 5.95-18.87 16.62 13.61 36.95 25.88 61.64 34.17-9.96 37-32.18 90.8-60.26 90.8-13.25 0-24 10.75-24 24s10.75 24 24 24c66.74 0 97.05-88.63 107.42-129.14 6.69.6 13.42 1.14 20.58 1.14s13.89-.54 20.58-1.14C350.95 423.37 381.26 512 448 512c13.25 0 24-10.75 24-24s-10.75-24-24-24c-27.94 0-50.21-53.81-60.22-90.81 24.69-8.29 45-20.56 61.62-34.16 1.96 4.38 3.74 10.15 5.95 18.87 5.34 21.11 12.67 50 45.33 62.44 8.14 3.11 15.8 4.39 22.97 4.39 21.59 0 38.87-11.69 52.42-20.84 17.05-11.55 23.28-14.45 31.39-11.36 12.39 4.75 26.27-1.47 30.97-13.88 4.71-12.4-1.49-26.26-13.89-30.98zM448 48c8.82 0 16 7.18 16 16s-7.18 16-16 16-16-7.18-16-16 7.18-16 16-16zm-256 0c8.82 0 16 7.18 16 16s-7.18 16-16 16-16-7.18-16-16 7.18-16 16-16z\"]\n};\nvar faPaste = {\n prefix: 'fas',\n iconName: 'paste',\n icon: [448, 512, [], \"f0ea\", \"M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z\"]\n};\nvar faPause = {\n prefix: 'fas',\n iconName: 'pause',\n icon: [448, 512, [], \"f04c\", \"M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z\"]\n};\nvar faPauseCircle = {\n prefix: 'fas',\n iconName: 'pause-circle',\n icon: [512, 512, [], \"f28b\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z\"]\n};\nvar faPaw = {\n prefix: 'fas',\n iconName: 'paw',\n icon: [512, 512, [], \"f1b0\", \"M256 224c-79.41 0-192 122.76-192 200.25 0 34.9 26.81 55.75 71.74 55.75 48.84 0 81.09-25.08 120.26-25.08 39.51 0 71.85 25.08 120.26 25.08 44.93 0 71.74-20.85 71.74-55.75C448 346.76 335.41 224 256 224zm-147.28-12.61c-10.4-34.65-42.44-57.09-71.56-50.13-29.12 6.96-44.29 40.69-33.89 75.34 10.4 34.65 42.44 57.09 71.56 50.13 29.12-6.96 44.29-40.69 33.89-75.34zm84.72-20.78c30.94-8.14 46.42-49.94 34.58-93.36s-46.52-72.01-77.46-63.87-46.42 49.94-34.58 93.36c11.84 43.42 46.53 72.02 77.46 63.87zm281.39-29.34c-29.12-6.96-61.15 15.48-71.56 50.13-10.4 34.65 4.77 68.38 33.89 75.34 29.12 6.96 61.15-15.48 71.56-50.13 10.4-34.65-4.77-68.38-33.89-75.34zm-156.27 29.34c30.94 8.14 65.62-20.45 77.46-63.87 11.84-43.42-3.64-85.21-34.58-93.36s-65.62 20.45-77.46 63.87c-11.84 43.42 3.64 85.22 34.58 93.36z\"]\n};\nvar faPeace = {\n prefix: 'fas',\n iconName: 'peace',\n icon: [496, 512, [], \"f67c\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm184 248c0 31.93-8.2 61.97-22.57 88.17L280 240.63V74.97c86.23 15.21 152 90.5 152 181.03zM216 437.03c-33.86-5.97-64.49-21.2-89.29-43.02L216 322.57v114.46zm64-114.46L369.29 394c-24.8 21.82-55.43 37.05-89.29 43.02V322.57zm-64-247.6v165.66L86.57 344.17C72.2 317.97 64 287.93 64 256c0-90.53 65.77-165.82 152-181.03z\"]\n};\nvar faPen = {\n prefix: 'fas',\n iconName: 'pen',\n icon: [512, 512, [], \"f304\", \"M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z\"]\n};\nvar faPenAlt = {\n prefix: 'fas',\n iconName: 'pen-alt',\n icon: [512, 512, [], \"f305\", \"M497.94 74.17l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.75 18.75-49.15 0-67.91zm-246.8-20.53c-15.62-15.62-40.94-15.62-56.56 0L75.8 172.43c-6.25 6.25-6.25 16.38 0 22.62l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l101.82-101.82 22.63 22.62L93.95 290.03A327.038 327.038 0 0 0 .17 485.11l-.03.23c-1.7 15.28 11.21 28.2 26.49 26.51a327.02 327.02 0 0 0 195.34-93.8l196.79-196.79-82.77-82.77-84.85-84.85z\"]\n};\nvar faPenFancy = {\n prefix: 'fas',\n iconName: 'pen-fancy',\n icon: [512, 512, [], \"f5ac\", \"M79.18 282.94a32.005 32.005 0 0 0-20.24 20.24L0 480l4.69 4.69 92.89-92.89c-.66-2.56-1.57-5.03-1.57-7.8 0-17.67 14.33-32 32-32s32 14.33 32 32-14.33 32-32 32c-2.77 0-5.24-.91-7.8-1.57l-92.89 92.89L32 512l176.82-58.94a31.983 31.983 0 0 0 20.24-20.24l33.07-84.07-98.88-98.88-84.07 33.07zM369.25 28.32L186.14 227.81l97.85 97.85 199.49-183.11C568.4 67.48 443.73-55.94 369.25 28.32z\"]\n};\nvar faPenNib = {\n prefix: 'fas',\n iconName: 'pen-nib',\n icon: [512, 512, [], \"f5ad\", \"M136.6 138.79a64.003 64.003 0 0 0-43.31 41.35L0 460l14.69 14.69L164.8 324.58c-2.99-6.26-4.8-13.18-4.8-20.58 0-26.51 21.49-48 48-48s48 21.49 48 48-21.49 48-48 48c-7.4 0-14.32-1.81-20.58-4.8L37.31 497.31 52 512l279.86-93.29a64.003 64.003 0 0 0 41.35-43.31L416 224 288 96l-151.4 42.79zm361.34-64.62l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.75 18.75-49.15 0-67.91z\"]\n};\nvar faPenSquare = {\n prefix: 'fas',\n iconName: 'pen-square',\n icon: [448, 512, [], \"f14b\", \"M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z\"]\n};\nvar faPencilAlt = {\n prefix: 'fas',\n iconName: 'pencil-alt',\n icon: [512, 512, [], \"f303\", \"M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z\"]\n};\nvar faPencilRuler = {\n prefix: 'fas',\n iconName: 'pencil-ruler',\n icon: [512, 512, [], \"f5ae\", \"M109.46 244.04l134.58-134.56-44.12-44.12-61.68 61.68a7.919 7.919 0 0 1-11.21 0l-11.21-11.21c-3.1-3.1-3.1-8.12 0-11.21l61.68-61.68-33.64-33.65C131.47-3.1 111.39-3.1 99 9.29L9.29 99c-12.38 12.39-12.39 32.47 0 44.86l100.17 100.18zm388.47-116.8c18.76-18.76 18.75-49.17 0-67.93l-45.25-45.25c-18.76-18.76-49.18-18.76-67.95 0l-46.02 46.01 113.2 113.2 46.02-46.03zM316.08 82.71l-297 296.96L.32 487.11c-2.53 14.49 10.09 27.11 24.59 24.56l107.45-18.84L429.28 195.9 316.08 82.71zm186.63 285.43l-33.64-33.64-61.68 61.68c-3.1 3.1-8.12 3.1-11.21 0l-11.21-11.21c-3.09-3.1-3.09-8.12 0-11.21l61.68-61.68-44.14-44.14L267.93 402.5l100.21 100.2c12.39 12.39 32.47 12.39 44.86 0l89.71-89.7c12.39-12.39 12.39-32.47 0-44.86z\"]\n};\nvar faPeopleCarry = {\n prefix: 'fas',\n iconName: 'people-carry',\n icon: [640, 512, [], \"f4ce\", \"M128 96c26.5 0 48-21.5 48-48S154.5 0 128 0 80 21.5 80 48s21.5 48 48 48zm384 0c26.5 0 48-21.5 48-48S538.5 0 512 0s-48 21.5-48 48 21.5 48 48 48zm125.7 372.1l-44-110-41.1 46.4-2 18.2 27.7 69.2c5 12.5 17 20.1 29.7 20.1 4 0 8-.7 11.9-2.3 16.4-6.6 24.4-25.2 17.8-41.6zm-34.2-209.8L585 178.1c-4.6-20-18.6-36.8-37.5-44.9-18.5-8-39-6.7-56.1 3.3-22.7 13.4-39.7 34.5-48.1 59.4L432 229.8 416 240v-96c0-8.8-7.2-16-16-16H240c-8.8 0-16 7.2-16 16v96l-16.1-10.2-11.3-33.9c-8.3-25-25.4-46-48.1-59.4-17.2-10-37.6-11.3-56.1-3.3-18.9 8.1-32.9 24.9-37.5 44.9l-18.4 80.2c-4.6 20 .7 41.2 14.4 56.7l67.2 75.9 10.1 92.6C130 499.8 143.8 512 160 512c1.2 0 2.3-.1 3.5-.2 17.6-1.9 30.2-17.7 28.3-35.3l-10.1-92.8c-1.5-13-6.9-25.1-15.6-35l-43.3-49 17.6-70.3 6.8 20.4c4.1 12.5 11.9 23.4 24.5 32.6l51.1 32.5c4.6 2.9 12.1 4.6 17.2 5h160c5.1-.4 12.6-2.1 17.2-5l51.1-32.5c12.6-9.2 20.4-20 24.5-32.6l6.8-20.4 17.6 70.3-43.3 49c-8.7 9.9-14.1 22-15.6 35l-10.1 92.8c-1.9 17.6 10.8 33.4 28.3 35.3 1.2.1 2.3.2 3.5.2 16.1 0 30-12.1 31.8-28.5l10.1-92.6 67.2-75.9c13.6-15.5 19-36.7 14.4-56.7zM46.3 358.1l-44 110c-6.6 16.4 1.4 35 17.8 41.6 16.8 6.6 35.1-1.7 41.6-17.8l27.7-69.2-2-18.2-41.1-46.4z\"]\n};\nvar faPepperHot = {\n prefix: 'fas',\n iconName: 'pepper-hot',\n icon: [512, 512, [], \"f816\", \"M330.67 263.12V173.4l-52.75-24.22C219.44 218.76 197.58 400 56 400a56 56 0 0 0 0 112c212.64 0 370.65-122.87 419.18-210.34l-37.05-38.54zm131.09-128.37C493.92 74.91 477.18 26.48 458.62 3a8 8 0 0 0-11.93-.59l-22.9 23a8.06 8.06 0 0 0-.89 10.23c6.86 10.36 17.05 35.1-1.4 72.32A142.85 142.85 0 0 0 364.34 96c-28 0-54 8.54-76.34 22.59l74.67 34.29v78.24h89.09L506.44 288c3.26-12.62 5.56-25.63 5.56-39.31a154 154 0 0 0-50.24-113.94z\"]\n};\nvar faPercent = {\n prefix: 'fas',\n iconName: 'percent',\n icon: [448, 512, [], \"f295\", \"M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z\"]\n};\nvar faPercentage = {\n prefix: 'fas',\n iconName: 'percentage',\n icon: [384, 512, [], \"f541\", \"M109.25 173.25c24.99-24.99 24.99-65.52 0-90.51-24.99-24.99-65.52-24.99-90.51 0-24.99 24.99-24.99 65.52 0 90.51 25 25 65.52 25 90.51 0zm256 165.49c-24.99-24.99-65.52-24.99-90.51 0-24.99 24.99-24.99 65.52 0 90.51 24.99 24.99 65.52 24.99 90.51 0 25-24.99 25-65.51 0-90.51zm-1.94-231.43l-22.62-22.62c-12.5-12.5-32.76-12.5-45.25 0L20.69 359.44c-12.5 12.5-12.5 32.76 0 45.25l22.62 22.62c12.5 12.5 32.76 12.5 45.25 0l274.75-274.75c12.5-12.49 12.5-32.75 0-45.25z\"]\n};\nvar faPersonBooth = {\n prefix: 'fas',\n iconName: 'person-booth',\n icon: [576, 512, [], \"f756\", \"M192 496c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320h-64v176zm32-272h-50.9l-45.2-45.3C115.8 166.6 99.7 160 82.7 160H64c-17.1 0-33.2 6.7-45.3 18.8C6.7 190.9 0 207 0 224.1L.2 320 0 480c0 17.7 14.3 32 31.9 32 17.6 0 32-14.3 32-32l.1-100.7c.9.5 1.6 1.3 2.5 1.7l29.1 43v56c0 17.7 14.3 32 32 32s32-14.3 32-32v-56.5c0-9.9-2.3-19.8-6.7-28.6l-41.2-61.3V253l20.9 20.9c9.1 9.1 21.1 14.1 33.9 14.1H224c17.7 0 32-14.3 32-32s-14.3-32-32-32zM64 128c26.5 0 48-21.5 48-48S90.5 32 64 32 16 53.5 16 80s21.5 48 48 48zm224-96l31.5 223.1-30.9 154.6c-4.3 21.6 13 38.3 31.4 38.3 15.2 0 28-9.1 32.3-30.4.9 16.9 14.6 30.4 31.7 30.4 17.7 0 32-14.3 32-32 0 17.7 14.3 32 32 32s32-14.3 32-32V0H288v32zm-96 0v160h64V0h-32c-17.7 0-32 14.3-32 32zM544 0h-32v496c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V32c0-17.7-14.3-32-32-32z\"]\n};\nvar faPhone = {\n prefix: 'fas',\n iconName: 'phone',\n icon: [512, 512, [], \"f095\", \"M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z\"]\n};\nvar faPhoneAlt = {\n prefix: 'fas',\n iconName: 'phone-alt',\n icon: [512, 512, [], \"f879\", \"M497.39 361.8l-112-48a24 24 0 0 0-28 6.9l-49.6 60.6A370.66 370.66 0 0 1 130.6 204.11l60.6-49.6a23.94 23.94 0 0 0 6.9-28l-48-112A24.16 24.16 0 0 0 122.6.61l-104 24A24 24 0 0 0 0 48c0 256.5 207.9 464 464 464a24 24 0 0 0 23.4-18.6l24-104a24.29 24.29 0 0 0-14.01-27.6z\"]\n};\nvar faPhoneSlash = {\n prefix: 'fas',\n iconName: 'phone-slash',\n icon: [640, 512, [], \"f3dd\", \"M268.2 381.4l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48c-10.7 4.6-16.5 16.1-13.9 27.5l24 104c2.5 10.8 12.1 18.6 23.4 18.6 100.7 0 193.7-32.4 269.7-86.9l-80-61.8c-10.9 6.5-22.1 12.7-33.6 18.1zm365.6 76.7L475.1 335.5C537.9 256.4 576 156.9 576 48c0-11.2-7.7-20.9-18.6-23.4l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-12.2 26.1-27.9 50.3-46 72.8L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3z\"]\n};\nvar faPhoneSquare = {\n prefix: 'fas',\n iconName: 'phone-square',\n icon: [448, 512, [], \"f098\", \"M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z\"]\n};\nvar faPhoneSquareAlt = {\n prefix: 'fas',\n iconName: 'phone-square-alt',\n icon: [448, 512, [], \"f87b\", \"M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zm-16.39 307.37l-15 65A15 15 0 0 1 354 416C194 416 64 286.29 64 126a15.7 15.7 0 0 1 11.63-14.61l65-15A18.23 18.23 0 0 1 144 96a16.27 16.27 0 0 1 13.79 9.09l30 70A17.9 17.9 0 0 1 189 181a17 17 0 0 1-5.5 11.61l-37.89 31a231.91 231.91 0 0 0 110.78 110.78l31-37.89A17 17 0 0 1 299 291a17.85 17.85 0 0 1 5.91 1.21l70 30A16.25 16.25 0 0 1 384 336a17.41 17.41 0 0 1-.39 3.37z\"]\n};\nvar faPhoneVolume = {\n prefix: 'fas',\n iconName: 'phone-volume',\n icon: [384, 512, [], \"f2a0\", \"M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z\"]\n};\nvar faPhotoVideo = {\n prefix: 'fas',\n iconName: 'photo-video',\n icon: [640, 512, [], \"f87c\", \"M608 0H160a32 32 0 0 0-32 32v96h160V64h192v320h128a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zM232 103a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm352 208a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9v-30a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm0-104a9 9 0 0 1-9 9h-30a9 9 0 0 1-9-9V73a9 9 0 0 1 9-9h30a9 9 0 0 1 9 9zm-168 57H32a32 32 0 0 0-32 32v288a32 32 0 0 0 32 32h384a32 32 0 0 0 32-32V192a32 32 0 0 0-32-32zM96 224a32 32 0 1 1-32 32 32 32 0 0 1 32-32zm288 224H64v-32l64-64 32 32 128-128 96 96z\"]\n};\nvar faPiggyBank = {\n prefix: 'fas',\n iconName: 'piggy-bank',\n icon: [576, 512, [], \"f4d3\", \"M560 224h-29.5c-8.8-20-21.6-37.7-37.4-52.5L512 96h-32c-29.4 0-55.4 13.5-73 34.3-7.6-1.1-15.1-2.3-23-2.3H256c-77.4 0-141.9 55-156.8 128H56c-14.8 0-26.5-13.5-23.5-28.8C34.7 215.8 45.4 208 57 208h1c3.3 0 6-2.7 6-6v-20c0-3.3-2.7-6-6-6-28.5 0-53.9 20.4-57.5 48.6C-3.9 258.8 22.7 288 56 288h40c0 52.2 25.4 98.1 64 127.3V496c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-48h128v48c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16v-80.7c11.8-8.9 22.3-19.4 31.3-31.3H560c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16zm-128 64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zM256 96h128c5.4 0 10.7.4 15.9.8 0-.3.1-.5.1-.8 0-53-43-96-96-96s-96 43-96 96c0 2.1.5 4.1.6 6.2 15.2-3.9 31-6.2 47.4-6.2z\"]\n};\nvar faPills = {\n prefix: 'fas',\n iconName: 'pills',\n icon: [576, 512, [], \"f484\", \"M112 32C50.1 32 0 82.1 0 144v224c0 61.9 50.1 112 112 112s112-50.1 112-112V144c0-61.9-50.1-112-112-112zm48 224H64V144c0-26.5 21.5-48 48-48s48 21.5 48 48v112zm139.7-29.7c-3.5-3.5-9.4-3.1-12.3.8-45.3 62.5-40.4 150.1 15.9 206.4 56.3 56.3 143.9 61.2 206.4 15.9 4-2.9 4.3-8.8.8-12.3L299.7 226.3zm229.8-19c-56.3-56.3-143.9-61.2-206.4-15.9-4 2.9-4.3 8.8-.8 12.3l210.8 210.8c3.5 3.5 9.4 3.1 12.3-.8 45.3-62.6 40.5-150.1-15.9-206.4z\"]\n};\nvar faPizzaSlice = {\n prefix: 'fas',\n iconName: 'pizza-slice',\n icon: [512, 512, [], \"f818\", \"M158.87.15c-16.16-1.52-31.2 8.42-35.33 24.12l-14.81 56.27c187.62 5.49 314.54 130.61 322.48 317l56.94-15.78c15.72-4.36 25.49-19.68 23.62-35.9C490.89 165.08 340.78 17.32 158.87.15zm-58.47 112L.55 491.64a16.21 16.21 0 0 0 20 19.75l379-105.1c-4.27-174.89-123.08-292.14-299.15-294.1zM128 416a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm48-152a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm104 104a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\"]\n};\nvar faPlaceOfWorship = {\n prefix: 'fas',\n iconName: 'place-of-worship',\n icon: [640, 512, [], \"f67f\", \"M620.61 366.55L512 320v192h112c8.84 0 16-7.16 16-16V395.96a32 32 0 0 0-19.39-29.41zM0 395.96V496c0 8.84 7.16 16 16 16h112V320L19.39 366.55A32 32 0 0 0 0 395.96zm464.46-149.28L416 217.6V102.63c0-8.49-3.37-16.62-9.38-22.63L331.31 4.69c-6.25-6.25-16.38-6.25-22.62 0L233.38 80c-6 6-9.38 14.14-9.38 22.63V217.6l-48.46 29.08A31.997 31.997 0 0 0 160 274.12V512h96v-96c0-35.35 28.66-64 64-64s64 28.65 64 64v96h96V274.12c0-11.24-5.9-21.66-15.54-27.44z\"]\n};\nvar faPlane = {\n prefix: 'fas',\n iconName: 'plane',\n icon: [576, 512, [], \"f072\", \"M480 192H365.71L260.61 8.06A16.014 16.014 0 0 0 246.71 0h-65.5c-10.63 0-18.3 10.17-15.38 20.39L214.86 192H112l-43.2-57.6c-3.02-4.03-7.77-6.4-12.8-6.4H16.01C5.6 128-2.04 137.78.49 147.88L32 256 .49 364.12C-2.04 374.22 5.6 384 16.01 384H56c5.04 0 9.78-2.37 12.8-6.4L112 320h102.86l-49.03 171.6c-2.92 10.22 4.75 20.4 15.38 20.4h65.5c5.74 0 11.04-3.08 13.89-8.06L365.71 320H480c35.35 0 96-28.65 96-64s-60.65-64-96-64z\"]\n};\nvar faPlaneArrival = {\n prefix: 'fas',\n iconName: 'plane-arrival',\n icon: [640, 512, [], \"f5af\", \"M624 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h608c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM44.81 205.66l88.74 80a62.607 62.607 0 0 0 25.47 13.93l287.6 78.35c26.48 7.21 54.56 8.72 81 1.36 29.67-8.27 43.44-21.21 47.25-35.71 3.83-14.5-1.73-32.71-23.37-54.96-19.28-19.82-44.35-32.79-70.83-40l-97.51-26.56L282.8 30.22c-1.51-5.81-5.95-10.35-11.66-11.91L206.05.58c-10.56-2.88-20.9 5.32-20.71 16.44l47.92 164.21-102.2-27.84-27.59-67.88c-1.93-4.89-6.01-8.57-11.02-9.93L52.72 64.75c-10.34-2.82-20.53 5-20.72 15.88l.23 101.78c.19 8.91 6.03 17.34 12.58 23.25z\"]\n};\nvar faPlaneDeparture = {\n prefix: 'fas',\n iconName: 'plane-departure',\n icon: [640, 512, [], \"f5b0\", \"M624 448H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h608c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM80.55 341.27c6.28 6.84 15.1 10.72 24.33 10.71l130.54-.18a65.62 65.62 0 0 0 29.64-7.12l290.96-147.65c26.74-13.57 50.71-32.94 67.02-58.31 18.31-28.48 20.3-49.09 13.07-63.65-7.21-14.57-24.74-25.27-58.25-27.45-29.85-1.94-59.54 5.92-86.28 19.48l-98.51 49.99-218.7-82.06a17.799 17.799 0 0 0-18-1.11L90.62 67.29c-10.67 5.41-13.25 19.65-5.17 28.53l156.22 98.1-103.21 52.38-72.35-36.47a17.804 17.804 0 0 0-16.07.02L9.91 230.22c-10.44 5.3-13.19 19.12-5.57 28.08l76.21 82.97z\"]\n};\nvar faPlay = {\n prefix: 'fas',\n iconName: 'play',\n icon: [448, 512, [], \"f04b\", \"M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z\"]\n};\nvar faPlayCircle = {\n prefix: 'fas',\n iconName: 'play-circle',\n icon: [512, 512, [], \"f144\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z\"]\n};\nvar faPlug = {\n prefix: 'fas',\n iconName: 'plug',\n icon: [384, 512, [], \"f1e6\", \"M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z\"]\n};\nvar faPlus = {\n prefix: 'fas',\n iconName: 'plus',\n icon: [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n};\nvar faPlusCircle = {\n prefix: 'fas',\n iconName: 'plus-circle',\n icon: [512, 512, [], \"f055\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"]\n};\nvar faPlusSquare = {\n prefix: 'fas',\n iconName: 'plus-square',\n icon: [448, 512, [], \"f0fe\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"]\n};\nvar faPodcast = {\n prefix: 'fas',\n iconName: 'podcast',\n icon: [448, 512, [], \"f2ce\", \"M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z\"]\n};\nvar faPoll = {\n prefix: 'fas',\n iconName: 'poll',\n icon: [448, 512, [], \"f681\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM160 368c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16V240c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v128zm96 0c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16V144c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v224zm96 0c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-64c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v64z\"]\n};\nvar faPollH = {\n prefix: 'fas',\n iconName: 'poll-h',\n icon: [448, 512, [], \"f682\", \"M448 432V80c0-26.5-21.5-48-48-48H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48zM112 192c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h128c8.84 0 16 7.16 16 16v32c0 8.84-7.16 16-16 16H112zm0 96c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h224c8.84 0 16 7.16 16 16v32c0 8.84-7.16 16-16 16H112zm0 96c-8.84 0-16-7.16-16-16v-32c0-8.84 7.16-16 16-16h64c8.84 0 16 7.16 16 16v32c0 8.84-7.16 16-16 16h-64z\"]\n};\nvar faPoo = {\n prefix: 'fas',\n iconName: 'poo',\n icon: [512, 512, [], \"f2fe\", \"M451.4 369.1C468.7 356 480 335.4 480 312c0-39.8-32.2-72-72-72h-14.1c13.4-11.7 22.1-28.8 22.1-48 0-35.3-28.7-64-64-64h-5.9c3.6-10.1 5.9-20.7 5.9-32 0-53-43-96-96-96-5.2 0-10.2.7-15.1 1.5C250.3 14.6 256 30.6 256 48c0 44.2-35.8 80-80 80h-16c-35.3 0-64 28.7-64 64 0 19.2 8.7 36.3 22.1 48H104c-39.8 0-72 32.2-72 72 0 23.4 11.3 44 28.6 57.1C26.3 374.6 0 404.1 0 440c0 39.8 32.2 72 72 72h368c39.8 0 72-32.2 72-72 0-35.9-26.3-65.4-60.6-70.9zM192 256c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm159.5 139C341 422.9 293 448 256 448s-85-25.1-95.5-53c-2-5.3 2-11 7.8-11h175.4c5.8 0 9.8 5.7 7.8 11zM320 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faPooStorm = {\n prefix: 'fas',\n iconName: 'poo-storm',\n icon: [448, 512, [], \"f75a\", \"M308 336h-57.7l17.3-64.9c2-7.6-3.7-15.1-11.6-15.1h-68c-6 0-11.1 4.5-11.9 10.4l-16 120c-1 7.2 4.6 13.6 11.9 13.6h59.3l-23 97.2c-1.8 7.6 4 14.8 11.7 14.8 4.2 0 8.2-2.2 10.4-6l88-152c4.6-8-1.2-18-10.4-18zm66.4-111.3c5.9-9.6 9.6-20.6 9.6-32.7 0-35.3-28.7-64-64-64h-5.9c3.6-10.1 5.9-20.7 5.9-32 0-53-43-96-96-96-5.2 0-10.2.7-15.1 1.5C218.3 14.6 224 30.6 224 48c0 44.2-35.8 80-80 80h-16c-35.3 0-64 28.7-64 64 0 12.1 3.7 23.1 9.6 32.7C32.6 228 0 262.2 0 304c0 44 36 80 80 80h48.3c.1-.6 0-1.2 0-1.8l16-120c3-21.8 21.7-38.2 43.7-38.2h68c13.8 0 26.5 6.3 34.9 17.2s11.2 24.8 7.6 38.1l-6.6 24.7h16c15.7 0 30.3 8.4 38.1 22 7.8 13.6 7.8 30.5 0 44l-8.1 14h30c44 0 80-36 80-80 .1-41.8-32.5-76-73.5-79.3z\"]\n};\nvar faPoop = {\n prefix: 'fas',\n iconName: 'poop',\n icon: [512, 512, [], \"f619\", \"M451.36 369.14C468.66 355.99 480 335.41 480 312c0-39.77-32.24-72-72-72h-14.07c13.42-11.73 22.07-28.78 22.07-48 0-35.35-28.65-64-64-64h-5.88c3.57-10.05 5.88-20.72 5.88-32 0-53.02-42.98-96-96-96-5.17 0-10.15.74-15.11 1.52C250.31 14.64 256 30.62 256 48c0 44.18-35.82 80-80 80h-16c-35.35 0-64 28.65-64 64 0 19.22 8.65 36.27 22.07 48H104c-39.76 0-72 32.23-72 72 0 23.41 11.34 43.99 28.64 57.14C26.31 374.62 0 404.12 0 440c0 39.76 32.24 72 72 72h368c39.76 0 72-32.24 72-72 0-35.88-26.31-65.38-60.64-70.86z\"]\n};\nvar faPortrait = {\n prefix: 'fas',\n iconName: 'portrait',\n icon: [384, 512, [], \"f3e0\", \"M336 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM192 128c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm112 236.8c0 10.6-10 19.2-22.4 19.2H102.4C90 384 80 375.4 80 364.8v-19.2c0-31.8 30.1-57.6 67.2-57.6h5c12.3 5.1 25.7 8 39.8 8s27.6-2.9 39.8-8h5c37.1 0 67.2 25.8 67.2 57.6v19.2z\"]\n};\nvar faPoundSign = {\n prefix: 'fas',\n iconName: 'pound-sign',\n icon: [320, 512, [], \"f154\", \"M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z\"]\n};\nvar faPowerOff = {\n prefix: 'fas',\n iconName: 'power-off',\n icon: [512, 512, [], \"f011\", \"M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z\"]\n};\nvar faPray = {\n prefix: 'fas',\n iconName: 'pray',\n icon: [384, 512, [], \"f683\", \"M256 128c35.35 0 64-28.65 64-64S291.35 0 256 0s-64 28.65-64 64 28.65 64 64 64zm-30.63 169.75c14.06 16.72 39 19.09 55.97 5.22l88-72.02c17.09-13.98 19.59-39.19 5.62-56.28-13.97-17.11-39.19-19.59-56.31-5.62l-57.44 47-38.91-46.31c-15.44-18.39-39.22-27.92-64-25.33-24.19 2.48-45.25 16.27-56.37 36.92l-49.37 92.03c-23.4 43.64-8.69 96.37 34.19 123.75L131.56 432H40c-22.09 0-40 17.91-40 40s17.91 40 40 40h208c34.08 0 53.77-42.79 28.28-68.28L166.42 333.86l34.8-64.87 24.15 28.76z\"]\n};\nvar faPrayingHands = {\n prefix: 'fas',\n iconName: 'praying-hands',\n icon: [640, 512, [], \"f684\", \"M272 191.91c-17.6 0-32 14.4-32 32v80c0 8.84-7.16 16-16 16s-16-7.16-16-16v-76.55c0-17.39 4.72-34.47 13.69-49.39l77.75-129.59c9.09-15.16 4.19-34.81-10.97-43.91-14.45-8.67-32.72-4.3-42.3 9.21-.2.23-.62.21-.79.48l-117.26 175.9C117.56 205.9 112 224.31 112 243.29v80.23l-90.12 30.04A31.974 31.974 0 0 0 0 383.91v96c0 10.82 8.52 32 32 32 2.69 0 5.41-.34 8.06-1.03l179.19-46.62C269.16 449.99 304 403.8 304 351.91v-128c0-17.6-14.4-32-32-32zm346.12 161.73L528 323.6v-80.23c0-18.98-5.56-37.39-16.12-53.23L394.62 14.25c-.18-.27-.59-.24-.79-.48-9.58-13.51-27.85-17.88-42.3-9.21-15.16 9.09-20.06 28.75-10.97 43.91l77.75 129.59c8.97 14.92 13.69 32 13.69 49.39V304c0 8.84-7.16 16-16 16s-16-7.16-16-16v-80c0-17.6-14.4-32-32-32s-32 14.4-32 32v128c0 51.89 34.84 98.08 84.75 112.34l179.19 46.62c2.66.69 5.38 1.03 8.06 1.03 23.48 0 32-21.18 32-32v-96c0-13.77-8.81-25.99-21.88-30.35z\"]\n};\nvar faPrescription = {\n prefix: 'fas',\n iconName: 'prescription',\n icon: [384, 512, [], \"f5b1\", \"M301.26 352l78.06-78.06c6.25-6.25 6.25-16.38 0-22.63l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0L256 306.74l-83.96-83.96C219.31 216.8 256 176.89 256 128c0-53.02-42.98-96-96-96H16C7.16 32 0 39.16 0 48v256c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-80h18.75l128 128-78.06 78.06c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0L256 397.25l78.06 78.06c6.25 6.25 16.38 6.25 22.63 0l22.63-22.63c6.25-6.25 6.25-16.38 0-22.63L301.26 352zM64 96h96c17.64 0 32 14.36 32 32s-14.36 32-32 32H64V96z\"]\n};\nvar faPrescriptionBottle = {\n prefix: 'fas',\n iconName: 'prescription-bottle',\n icon: [384, 512, [], \"f485\", \"M32 192h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64h120c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H32v64c0 17.6 14.4 32 32 32h256c17.6 0 32-14.4 32-32V128H32v64zM360 0H24C10.8 0 0 10.8 0 24v48c0 13.2 10.8 24 24 24h336c13.2 0 24-10.8 24-24V24c0-13.2-10.8-24-24-24z\"]\n};\nvar faPrescriptionBottleAlt = {\n prefix: 'fas',\n iconName: 'prescription-bottle-alt',\n icon: [384, 512, [], \"f486\", \"M360 0H24C10.8 0 0 10.8 0 24v48c0 13.2 10.8 24 24 24h336c13.2 0 24-10.8 24-24V24c0-13.2-10.8-24-24-24zM32 480c0 17.6 14.4 32 32 32h256c17.6 0 32-14.4 32-32V128H32v352zm64-184c0-4.4 3.6-8 8-8h56v-56c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v56h56c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8h-56v56c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8v-56h-56c-4.4 0-8-3.6-8-8v-48z\"]\n};\nvar faPrint = {\n prefix: 'fas',\n iconName: 'print',\n icon: [512, 512, [], \"f02f\", \"M448 192V77.25c0-8.49-3.37-16.62-9.37-22.63L393.37 9.37c-6-6-14.14-9.37-22.63-9.37H96C78.33 0 64 14.33 64 32v160c-35.35 0-64 28.65-64 64v112c0 8.84 7.16 16 16 16h48v96c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-96h48c8.84 0 16-7.16 16-16V256c0-35.35-28.65-64-64-64zm-64 256H128v-96h256v96zm0-224H128V64h192v48c0 8.84 7.16 16 16 16h48v96zm48 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"]\n};\nvar faProcedures = {\n prefix: 'fas',\n iconName: 'procedures',\n icon: [640, 512, [], \"f487\", \"M528 224H272c-8.8 0-16 7.2-16 16v144H64V144c0-8.8-7.2-16-16-16H16c-8.8 0-16 7.2-16 16v352c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-48h512v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V336c0-61.9-50.1-112-112-112zM136 96h126.1l27.6 55.2c5.9 11.8 22.7 11.8 28.6 0L368 51.8 390.1 96H512c8.8 0 16-7.2 16-16s-7.2-16-16-16H409.9L382.3 8.8C376.4-3 359.6-3 353.7 8.8L304 108.2l-19.9-39.8c-1.4-2.7-4.1-4.4-7.2-4.4H136c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8zm24 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64z\"]\n};\nvar faProjectDiagram = {\n prefix: 'fas',\n iconName: 'project-diagram',\n icon: [640, 512, [], \"f542\", \"M384 320H256c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h128c17.67 0 32-14.33 32-32V352c0-17.67-14.33-32-32-32zM192 32c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v128c0 17.67 14.33 32 32 32h95.72l73.16 128.04C211.98 300.98 232.4 288 256 288h.28L192 175.51V128h224V64H192V32zM608 0H480c-17.67 0-32 14.33-32 32v128c0 17.67 14.33 32 32 32h128c17.67 0 32-14.33 32-32V32c0-17.67-14.33-32-32-32z\"]\n};\nvar faPuzzlePiece = {\n prefix: 'fas',\n iconName: 'puzzle-piece',\n icon: [576, 512, [], \"f12e\", \"M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z\"]\n};\nvar faQrcode = {\n prefix: 'fas',\n iconName: 'qrcode',\n icon: [448, 512, [], \"f029\", \"M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z\"]\n};\nvar faQuestion = {\n prefix: 'fas',\n iconName: 'question',\n icon: [384, 512, [], \"f128\", \"M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z\"]\n};\nvar faQuestionCircle = {\n prefix: 'fas',\n iconName: 'question-circle',\n icon: [512, 512, [], \"f059\", \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z\"]\n};\nvar faQuidditch = {\n prefix: 'fas',\n iconName: 'quidditch',\n icon: [640, 512, [], \"f458\", \"M256.5 216.8L343.2 326s-16.6 102.4-76.6 150.1C206.7 523.8 0 510.2 0 510.2s3.8-23.1 11-55.4l94.6-112.2c4-4.7-.9-11.6-6.6-9.5l-60.4 22.1c14.4-41.7 32.7-80 54.6-97.5 59.9-47.8 163.3-40.9 163.3-40.9zm238 135c-44 0-79.8 35.8-79.8 79.9 0 44.1 35.7 79.9 79.8 79.9 44.1 0 79.8-35.8 79.8-79.9 0-44.2-35.8-79.9-79.8-79.9zM636.5 31L616.7 6c-5.5-6.9-15.5-8-22.4-2.6L361.8 181.3l-34.1-43c-5.1-6.4-15.1-5.2-18.6 2.2l-25.3 54.6 86.7 109.2 58.8-12.4c8-1.7 11.4-11.2 6.3-17.6l-34.1-42.9L634 53.5c6.9-5.5 8-15.6 2.5-22.5z\"]\n};\nvar faQuoteLeft = {\n prefix: 'fas',\n iconName: 'quote-left',\n icon: [512, 512, [], \"f10d\", \"M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z\"]\n};\nvar faQuoteRight = {\n prefix: 'fas',\n iconName: 'quote-right',\n icon: [512, 512, [], \"f10e\", \"M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z\"]\n};\nvar faQuran = {\n prefix: 'fas',\n iconName: 'quran',\n icon: [448, 512, [], \"f687\", \"M448 358.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM301.08 145.82c.6-1.21 1.76-1.82 2.92-1.82s2.32.61 2.92 1.82l11.18 22.65 25 3.63c2.67.39 3.74 3.67 1.81 5.56l-18.09 17.63 4.27 24.89c.36 2.11-1.31 3.82-3.21 3.82-.5 0-1.02-.12-1.52-.38L304 211.87l-22.36 11.75c-.5.26-1.02.38-1.52.38-1.9 0-3.57-1.71-3.21-3.82l4.27-24.89-18.09-17.63c-1.94-1.89-.87-5.17 1.81-5.56l24.99-3.63 11.19-22.65zm-57.89-69.01c13.67 0 27.26 2.49 40.38 7.41a6.775 6.775 0 1 1-2.38 13.12c-.67 0-3.09-.21-4.13-.21-52.31 0-94.86 42.55-94.86 94.86 0 52.3 42.55 94.86 94.86 94.86 1.03 0 3.48-.21 4.13-.21 3.93 0 6.8 3.14 6.8 6.78 0 2.98-1.94 5.51-4.62 6.42-13.07 4.87-26.59 7.34-40.19 7.34C179.67 307.19 128 255.51 128 192c0-63.52 51.67-115.19 115.19-115.19zM380.8 448H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8v64z\"]\n};\nvar faRadiation = {\n prefix: 'fas',\n iconName: 'radiation',\n icon: [496, 512, [], \"f7b9\", \"M328.2 255.8h151.6c9.1 0 16.8-7.7 16.2-16.8-5.1-75.8-44.4-142.2-102.5-184.2-7.4-5.3-17.9-2.9-22.7 4.8L290.4 188c22.6 14.3 37.8 39.2 37.8 67.8zm-37.8 67.7c-12.3 7.7-26.8 12.4-42.4 12.4-15.6 0-30-4.7-42.4-12.4L125.2 452c-4.8 7.7-2.4 18.1 5.6 22.4C165.7 493.2 205.6 504 248 504s82.3-10.8 117.2-29.6c8-4.3 10.4-14.8 5.6-22.4l-80.4-128.5zM248 303.8c26.5 0 48-21.5 48-48s-21.5-48-48-48-48 21.5-48 48 21.5 48 48 48zm-231.8-48h151.6c0-28.6 15.2-53.5 37.8-67.7L125.2 59.7c-4.8-7.7-15.3-10.2-22.7-4.8C44.4 96.9 5.1 163.3 0 239.1c-.6 9 7.1 16.7 16.2 16.7z\"]\n};\nvar faRadiationAlt = {\n prefix: 'fas',\n iconName: 'radiation-alt',\n icon: [496, 512, [], \"f7ba\", \"M312 256h79.1c9.2 0 16.9-7.7 16-16.8-4.6-43.6-27-81.8-59.5-107.8-7.6-6.1-18.8-4.5-24 3.8L281.9 202c18 11.2 30.1 31.2 30.1 54zm-97.8 54.1L172.4 377c-4.9 7.8-2.4 18.4 5.8 22.5 21.1 10.4 44.7 16.5 69.8 16.5s48.7-6.1 69.9-16.5c8.2-4.1 10.6-14.7 5.8-22.5l-41.8-66.9c-9.8 6.2-21.4 9.9-33.8 9.9s-24.1-3.7-33.9-9.9zM104.9 256H184c0-22.8 12.1-42.8 30.2-54.1l-41.7-66.8c-5.2-8.3-16.4-9.9-24-3.8-32.6 26-54.9 64.2-59.5 107.8-1.1 9.2 6.7 16.9 15.9 16.9zM248 504c137 0 248-111 248-248S385 8 248 8 0 119 0 256s111 248 248 248zm0-432c101.5 0 184 82.5 184 184s-82.5 184-184 184S64 357.5 64 256 146.5 72 248 72zm0 216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z\"]\n};\nvar faRainbow = {\n prefix: 'fas',\n iconName: 'rainbow',\n icon: [576, 512, [], \"f75b\", \"M268.3 32.7C115.4 42.9 0 176.9 0 330.2V464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320C64 186.8 180.9 80.3 317.5 97.9 430.4 112.4 512 214 512 327.8V464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320c0-165.3-140-298.6-307.7-287.3zm-5.6 96.9C166 142 96 229.1 96 326.7V464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320c0-74.8 64.5-134.8 140.8-127.4 66.5 6.5 115.2 66.2 115.2 133.1V464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320c0-114.2-100.2-205.4-217.3-190.4zm6.2 96.3c-45.6 8.9-76.9 51.5-76.9 97.9V464c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320c0-17.6 14.3-32 32-32s32 14.4 32 32v144c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320c0-59.2-53.8-106-115.1-94.1z\"]\n};\nvar faRandom = {\n prefix: 'fas',\n iconName: 'random',\n icon: [512, 512, [], \"f074\", \"M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z\"]\n};\nvar faReceipt = {\n prefix: 'fas',\n iconName: 'receipt',\n icon: [384, 512, [], \"f543\", \"M358.4 3.2L320 48 265.6 3.2a15.9 15.9 0 0 0-19.2 0L192 48 137.6 3.2a15.9 15.9 0 0 0-19.2 0L64 48 25.6 3.2C15-4.7 0 2.8 0 16v480c0 13.2 15 20.7 25.6 12.8L64 464l54.4 44.8a15.9 15.9 0 0 0 19.2 0L192 464l54.4 44.8a15.9 15.9 0 0 0 19.2 0L320 464l38.4 44.8c10.5 7.9 25.6.4 25.6-12.8V16c0-13.2-15-20.7-25.6-12.8zM320 360c0 4.4-3.6 8-8 8H72c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h240c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H72c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h240c4.4 0 8 3.6 8 8v16zm0-96c0 4.4-3.6 8-8 8H72c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h240c4.4 0 8 3.6 8 8v16z\"]\n};\nvar faRecycle = {\n prefix: 'fas',\n iconName: 'recycle',\n icon: [512, 512, [], \"f1b8\", \"M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z\"]\n};\nvar faRedo = {\n prefix: 'fas',\n iconName: 'redo',\n icon: [512, 512, [], \"f01e\", \"M500.33 0h-47.41a12 12 0 0 0-12 12.57l4 82.76A247.42 247.42 0 0 0 256 8C119.34 8 7.9 119.53 8 256.19 8.1 393.07 119.1 504 256 504a247.1 247.1 0 0 0 166.18-63.91 12 12 0 0 0 .48-17.43l-34-34a12 12 0 0 0-16.38-.55A176 176 0 1 1 402.1 157.8l-101.53-4.87a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12h200.33a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12z\"]\n};\nvar faRedoAlt = {\n prefix: 'fas',\n iconName: 'redo-alt',\n icon: [512, 512, [], \"f2f9\", \"M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z\"]\n};\nvar faRegistered = {\n prefix: 'fas',\n iconName: 'registered',\n icon: [512, 512, [], \"f25d\", \"M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z\"]\n};\nvar faRemoveFormat = {\n prefix: 'fas',\n iconName: 'remove-format',\n icon: [640, 512, [], \"f87d\", \"M336 416h-11.17l9.26-27.77L267 336.4 240.49 416H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm297.82 42.1L377 259.59 426.17 112H544v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H176a16 16 0 0 0-16 16v43.9L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zM309.91 207.76L224 141.36V112h117.83z\"]\n};\nvar faReply = {\n prefix: 'fas',\n iconName: 'reply',\n icon: [512, 512, [], \"f3e5\", \"M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z\"]\n};\nvar faReplyAll = {\n prefix: 'fas',\n iconName: 'reply-all',\n icon: [576, 512, [], \"f122\", \"M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z\"]\n};\nvar faRepublican = {\n prefix: 'fas',\n iconName: 'republican',\n icon: [640, 512, [], \"f75e\", \"M544 192c0-88.4-71.6-160-160-160H160C71.6 32 0 103.6 0 192v64h544v-64zm-367.7-21.6l-19.8 19.3 4.7 27.3c.8 4.9-4.3 8.6-8.7 6.3L128 210.4l-24.5 12.9c-4.3 2.3-9.5-1.4-8.7-6.3l4.7-27.3-19.8-19.3c-3.6-3.5-1.6-9.5 3.3-10.2l27.4-4 12.2-24.8c2.2-4.5 8.6-4.4 10.7 0l12.2 24.8 27.4 4c5 .7 6.9 6.7 3.4 10.2zm144 0l-19.8 19.3 4.7 27.3c.8 4.9-4.3 8.6-8.7 6.3L272 210.4l-24.5 12.9c-4.3 2.3-9.5-1.4-8.7-6.3l4.7-27.3-19.8-19.3c-3.6-3.5-1.6-9.5 3.3-10.2l27.4-4 12.2-24.8c2.2-4.5 8.6-4.4 10.7 0l12.2 24.8 27.4 4c5 .7 6.9 6.7 3.4 10.2zm144 0l-19.8 19.3 4.7 27.3c.8 4.9-4.3 8.6-8.7 6.3L416 210.4l-24.5 12.9c-4.3 2.3-9.5-1.4-8.7-6.3l4.7-27.3-19.8-19.3c-3.6-3.5-1.6-9.5 3.3-10.2l27.4-4 12.2-24.8c2.2-4.5 8.6-4.4 10.7 0l12.2 24.8 27.4 4c5 .7 6.9 6.7 3.4 10.2zM624 320h-32c-8.8 0-16 7.2-16 16v64c0 8.8-7.2 16-16 16s-16-7.2-16-16V288H0v176c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16v-80h192v80c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16V352h32v43.3c0 41.8 30 80.1 71.6 84.3 47.8 4.9 88.4-32.7 88.4-79.6v-64c0-8.8-7.2-16-16-16z\"]\n};\nvar faRestroom = {\n prefix: 'fas',\n iconName: 'restroom',\n icon: [640, 512, [], \"f7bd\", \"M128 128c35.3 0 64-28.7 64-64S163.3 0 128 0 64 28.7 64 64s28.7 64 64 64zm384 0c35.3 0 64-28.7 64-64S547.3 0 512 0s-64 28.7-64 64 28.7 64 64 64zm127.3 226.5l-45.6-185.8c-3.3-13.5-15.5-23-29.8-24.2-15 9.7-32.8 15.5-52 15.5-19.2 0-37-5.8-52-15.5-14.3 1.2-26.5 10.7-29.8 24.2l-45.6 185.8C381 369.6 393 384 409.2 384H464v104c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V384h54.8c16.2 0 28.2-14.4 24.5-29.5zM336 0h-32c-8.8 0-16 7.2-16 16v480c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16zM180.1 144.4c-15 9.8-32.9 15.6-52.1 15.6-19.2 0-37.1-5.8-52.1-15.6C51.3 146.5 32 166.9 32 192v136c0 13.3 10.7 24 24 24h8v136c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V352h8c13.3 0 24-10.7 24-24V192c0-25.1-19.3-45.5-43.9-47.6z\"]\n};\nvar faRetweet = {\n prefix: 'fas',\n iconName: 'retweet',\n icon: [640, 512, [], \"f079\", \"M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z\"]\n};\nvar faRibbon = {\n prefix: 'fas',\n iconName: 'ribbon',\n icon: [448, 512, [], \"f4d6\", \"M6.1 444.3c-9.6 10.8-7.5 27.6 4.5 35.7l68.8 27.9c9.9 6.7 23.3 5 31.3-3.8l91.8-101.9-79.2-87.9-117.2 130zm435.8 0s-292-324.6-295.4-330.1c15.4-8.4 40.2-17.9 77.5-17.9s62.1 9.5 77.5 17.9c-3.3 5.6-56 64.6-56 64.6l79.1 87.7 34.2-38c28.7-31.9 33.3-78.6 11.4-115.5l-43.7-73.5c-4.3-7.2-9.9-13.3-16.8-18-40.7-27.6-127.4-29.7-171.4 0-6.9 4.7-12.5 10.8-16.8 18l-43.6 73.2c-1.5 2.5-37.1 62.2 11.5 116L337.5 504c8 8.9 21.4 10.5 31.3 3.8l68.8-27.9c11.9-8 14-24.8 4.3-35.6z\"]\n};\nvar faRing = {\n prefix: 'fas',\n iconName: 'ring',\n icon: [512, 512, [], \"f70b\", \"M256 64C110.06 64 0 125.91 0 208v98.13C0 384.48 114.62 448 256 448s256-63.52 256-141.87V208c0-82.09-110.06-144-256-144zm0 64c106.04 0 192 35.82 192 80 0 9.26-3.97 18.12-10.91 26.39C392.15 208.21 328.23 192 256 192s-136.15 16.21-181.09 42.39C67.97 226.12 64 217.26 64 208c0-44.18 85.96-80 192-80zM120.43 264.64C155.04 249.93 201.64 240 256 240s100.96 9.93 135.57 24.64C356.84 279.07 308.93 288 256 288s-100.84-8.93-135.57-23.36z\"]\n};\nvar faRoad = {\n prefix: 'fas',\n iconName: 'road',\n icon: [576, 512, [], \"f018\", \"M573.19 402.67l-139.79-320C428.43 71.29 417.6 64 405.68 64h-97.59l2.45 23.16c.5 4.72-3.21 8.84-7.96 8.84h-29.16c-4.75 0-8.46-4.12-7.96-8.84L267.91 64h-97.59c-11.93 0-22.76 7.29-27.73 18.67L2.8 402.67C-6.45 423.86 8.31 448 30.54 448h196.84l10.31-97.68c.86-8.14 7.72-14.32 15.91-14.32h68.8c8.19 0 15.05 6.18 15.91 14.32L348.62 448h196.84c22.23 0 36.99-24.14 27.73-45.33zM260.4 135.16a8 8 0 0 1 7.96-7.16h39.29c4.09 0 7.53 3.09 7.96 7.16l4.6 43.58c.75 7.09-4.81 13.26-11.93 13.26h-40.54c-7.13 0-12.68-6.17-11.93-13.26l4.59-43.58zM315.64 304h-55.29c-9.5 0-16.91-8.23-15.91-17.68l5.07-48c.86-8.14 7.72-14.32 15.91-14.32h45.15c8.19 0 15.05 6.18 15.91 14.32l5.07 48c1 9.45-6.41 17.68-15.91 17.68z\"]\n};\nvar faRobot = {\n prefix: 'fas',\n iconName: 'robot',\n icon: [640, 512, [], \"f544\", \"M0 256v128c0 17.7 14.3 32 32 32h32V224H32c-17.7 0-32 14.3-32 32zM464 96H352V32c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H176c-44.2 0-80 35.8-80 80v272c0 35.3 28.7 64 64 64h320c35.3 0 64-28.7 64-64V176c0-44.2-35.8-80-80-80zM256 416h-64v-32h64v32zm-32-120c-22.1 0-40-17.9-40-40s17.9-40 40-40 40 17.9 40 40-17.9 40-40 40zm128 120h-64v-32h64v32zm96 0h-64v-32h64v32zm-32-120c-22.1 0-40-17.9-40-40s17.9-40 40-40 40 17.9 40 40-17.9 40-40 40zm192-72h-32v192h32c17.7 0 32-14.3 32-32V256c0-17.7-14.3-32-32-32z\"]\n};\nvar faRocket = {\n prefix: 'fas',\n iconName: 'rocket',\n icon: [512, 512, [], \"f135\", \"M505.05 19.1a15.89 15.89 0 0 0-12.2-12.2C460.65 0 435.46 0 410.36 0c-103.2 0-165.1 55.2-211.29 128H94.87A48 48 0 0 0 52 154.49l-49.42 98.8A24 24 0 0 0 24.07 288h103.77l-22.47 22.47a32 32 0 0 0 0 45.25l50.9 50.91a32 32 0 0 0 45.26 0L224 384.16V488a24 24 0 0 0 34.7 21.49l98.7-49.39a47.91 47.91 0 0 0 26.5-42.9V312.79c72.59-46.3 128-108.4 128-211.09.1-25.2.1-50.4-6.85-82.6zM384 168a40 40 0 1 1 40-40 40 40 0 0 1-40 40z\"]\n};\nvar faRoute = {\n prefix: 'fas',\n iconName: 'route',\n icon: [512, 512, [], \"f4d7\", \"M416 320h-96c-17.6 0-32-14.4-32-32s14.4-32 32-32h96s96-107 96-160-43-96-96-96-96 43-96 96c0 25.5 22.2 63.4 45.3 96H320c-52.9 0-96 43.1-96 96s43.1 96 96 96h96c17.6 0 32 14.4 32 32s-14.4 32-32 32H185.5c-16 24.8-33.8 47.7-47.3 64H416c52.9 0 96-43.1 96-96s-43.1-96-96-96zm0-256c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zM96 256c-53 0-96 43-96 96s96 160 96 160 96-107 96-160-43-96-96-96zm0 128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faRss = {\n prefix: 'fas',\n iconName: 'rss',\n icon: [448, 512, [], \"f09e\", \"M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z\"]\n};\nvar faRssSquare = {\n prefix: 'fas',\n iconName: 'rss-square',\n icon: [448, 512, [], \"f143\", \"M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z\"]\n};\nvar faRubleSign = {\n prefix: 'fas',\n iconName: 'ruble-sign',\n icon: [384, 512, [], \"f158\", \"M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z\"]\n};\nvar faRuler = {\n prefix: 'fas',\n iconName: 'ruler',\n icon: [640, 512, [], \"f545\", \"M635.7 167.2L556.1 31.7c-8.8-15-28.3-20.1-43.5-11.5l-69 39.1L503.3 161c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L416 75l-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L333.2 122 278 153.3 337.8 255c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-59.7-101.7-55.2 31.3 27.9 47.4c2.2 3.8.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9l-27.9-47.5-55.2 31.3 59.7 101.7c2.2 3.7.9 8.5-2.9 10.7l-13.8 7.8c-3.8 2.2-8.7.9-10.9-2.9L84.9 262.9l-69 39.1C.7 310.7-4.6 329.8 4.2 344.8l79.6 135.6c8.8 15 28.3 20.1 43.5 11.5L624.1 210c15.2-8.6 20.4-27.8 11.6-42.8z\"]\n};\nvar faRulerCombined = {\n prefix: 'fas',\n iconName: 'ruler-combined',\n icon: [512, 512, [], \"f546\", \"M160 288h-56c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h56v-64h-56c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h56V96h-56c-4.42 0-8-3.58-8-8V72c0-4.42 3.58-8 8-8h56V32c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v448c0 2.77.91 5.24 1.57 7.8L160 329.38V288zm320 64h-32v56c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-56h-64v56c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-56h-64v56c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-56h-41.37L24.2 510.43c2.56.66 5.04 1.57 7.8 1.57h448c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32z\"]\n};\nvar faRulerHorizontal = {\n prefix: 'fas',\n iconName: 'ruler-horizontal',\n icon: [576, 512, [], \"f547\", \"M544 128h-48v88c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-88h-64v88c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-88h-64v88c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-88h-64v88c0 4.42-3.58 8-8 8h-16c-4.42 0-8-3.58-8-8v-88h-64v88c0 4.42-3.58 8-8 8H88c-4.42 0-8-3.58-8-8v-88H32c-17.67 0-32 14.33-32 32v192c0 17.67 14.33 32 32 32h512c17.67 0 32-14.33 32-32V160c0-17.67-14.33-32-32-32z\"]\n};\nvar faRulerVertical = {\n prefix: 'fas',\n iconName: 'ruler-vertical',\n icon: [256, 512, [], \"f548\", \"M168 416c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h88v-64h-88c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h88v-64h-88c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h88v-64h-88c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h88V32c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v448c0 17.67 14.33 32 32 32h192c17.67 0 32-14.33 32-32v-64h-88z\"]\n};\nvar faRunning = {\n prefix: 'fas',\n iconName: 'running',\n icon: [416, 512, [], \"f70c\", \"M272 96c26.51 0 48-21.49 48-48S298.51 0 272 0s-48 21.49-48 48 21.49 48 48 48zM113.69 317.47l-14.8 34.52H32c-17.67 0-32 14.33-32 32s14.33 32 32 32h77.45c19.25 0 36.58-11.44 44.11-29.09l8.79-20.52-10.67-6.3c-17.32-10.23-30.06-25.37-37.99-42.61zM384 223.99h-44.03l-26.06-53.25c-12.5-25.55-35.45-44.23-61.78-50.94l-71.08-21.14c-28.3-6.8-57.77-.55-80.84 17.14l-39.67 30.41c-14.03 10.75-16.69 30.83-5.92 44.86s30.84 16.66 44.86 5.92l39.69-30.41c7.67-5.89 17.44-8 25.27-6.14l14.7 4.37-37.46 87.39c-12.62 29.48-1.31 64.01 26.3 80.31l84.98 50.17-27.47 87.73c-5.28 16.86 4.11 34.81 20.97 40.09 3.19 1 6.41 1.48 9.58 1.48 13.61 0 26.23-8.77 30.52-22.45l31.64-101.06c5.91-20.77-2.89-43.08-21.64-54.39l-61.24-36.14 31.31-78.28 20.27 41.43c8 16.34 24.92 26.89 43.11 26.89H384c17.67 0 32-14.33 32-32s-14.33-31.99-32-31.99z\"]\n};\nvar faRupeeSign = {\n prefix: 'fas',\n iconName: 'rupee-sign',\n icon: [320, 512, [], \"f156\", \"M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z\"]\n};\nvar faSadCry = {\n prefix: 'fas',\n iconName: 'sad-cry',\n icon: [496, 512, [], \"f5b3\", \"M248 8C111 8 0 119 0 256c0 90.1 48.2 168.7 120 212.1V288c0-8.8 7.2-16 16-16s16 7.2 16 16v196.7c29.5 12.4 62 19.3 96 19.3s66.5-6.9 96-19.3V288c0-8.8 7.2-16 16-16s16 7.2 16 16v180.1C447.8 424.7 496 346 496 256 496 119 385 8 248 8zm-65.5 216.5c-14.8-13.2-46.2-13.2-61 0L112 233c-3.8 3.3-9.3 4-13.7 1.6-4.4-2.4-6.9-7.4-6.1-12.4 4-25.2 34.2-42.1 59.9-42.1S208 197 212 222.2c.8 5-1.7 10-6.1 12.4-5.8 3.1-11.2.7-13.7-1.6l-9.7-8.5zM248 416c-26.5 0-48-28.7-48-64s21.5-64 48-64 48 28.7 48 64-21.5 64-48 64zm149.8-181.5c-5.8 3.1-11.2.7-13.7-1.6l-9.5-8.5c-14.8-13.2-46.2-13.2-61 0L304 233c-3.8 3.3-9.3 4-13.7 1.6-4.4-2.4-6.9-7.4-6.1-12.4 4-25.2 34.2-42.1 59.9-42.1S400 197 404 222.2c.6 4.9-1.8 9.9-6.2 12.3z\"]\n};\nvar faSadTear = {\n prefix: 'fas',\n iconName: 'sad-tear',\n icon: [496, 512, [], \"f5b4\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zM152 416c-26.5 0-48-21-48-47 0-20 28.5-60.4 41.6-77.8 3.2-4.3 9.6-4.3 12.8 0C171.5 308.6 200 349 200 369c0 26-21.5 47-48 47zm16-176c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm170.2 154.2C315.8 367.4 282.9 352 248 352c-21.2 0-21.2-32 0-32 44.4 0 86.3 19.6 114.7 53.8 13.8 16.4-11.2 36.5-24.5 20.4z\"]\n};\nvar faSatellite = {\n prefix: 'fas',\n iconName: 'satellite',\n icon: [512, 512, [], \"f7bf\", \"M502.7 265l-80.3-80.4 47.8-47.9c13.1-13.1 13.1-34.4 0-47.5l-47.5-47.5c-13.1-13.1-34.4-13.1-47.5 0l-47.8 47.9-80.3-80.3C240.8 3.1 232.7 0 224.5 0S208.2 3.1 202 9.3L105.3 106c-12.4 12.4-12.4 32.6 0 45.1l80.3 80.4-9.8 9.8C122.1 217 59.6 218.6 7.3 246.7c-8.5 4.6-9.6 16.4-2.8 23.2L112 377.4l-17.8 17.8c-2.6-.7-5-1.6-7.8-1.6-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32c0-2.8-.9-5.2-1.6-7.8l17.8-17.8 107.5 107.5c6.8 6.8 18.7 5.7 23.2-2.8 28.1-52.3 29.7-114.8 5.4-168.5l9.9-9.9 80.3 80.4c6.2 6.2 14.4 9.3 22.5 9.3s16.3-3.1 22.5-9.3l96.7-96.7c12.5-12.4 12.5-32.6.1-45zm-352-136.5l73.8-73.8 68.9 68.9-73.8 73.8-68.9-68.9zm232.8 232.8l-68.9-68.9 73.8-73.8 68.9 68.9-73.8 73.8z\"]\n};\nvar faSatelliteDish = {\n prefix: 'fas',\n iconName: 'satellite-dish',\n icon: [512, 512, [], \"f7c0\", \"M188.8 345.9l27.4-27.4c2.6.7 5 1.6 7.8 1.6 17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32c0 2.8.9 5.2 1.6 7.8l-27.4 27.4L49.4 206.5c-7.3-7.3-20.1-6.1-25 3-41.8 77.8-29.9 176.7 35.7 242.3 65.6 65.6 164.6 77.5 242.3 35.7 9.2-4.9 10.4-17.7 3-25L188.8 345.9zM209 0c-9.2-.5-17 6.8-17 16v31.6c0 8.5 6.6 15.5 15 15.9 129.4 7 233.4 112 240.9 241.5.5 8.4 7.5 15 15.9 15h32.1c9.2 0 16.5-7.8 16-17C503.4 139.8 372.2 8.6 209 0zm.3 96c-9.3-.7-17.3 6.7-17.3 16.1v32.1c0 8.4 6.5 15.3 14.8 15.9 76.8 6.3 138 68.2 144.9 145.2.8 8.3 7.6 14.7 15.9 14.7h32.2c9.3 0 16.8-8 16.1-17.3-8.4-110.1-96.5-198.2-206.6-206.7z\"]\n};\nvar faSave = {\n prefix: 'fas',\n iconName: 'save',\n icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"]\n};\nvar faSchool = {\n prefix: 'fas',\n iconName: 'school',\n icon: [640, 512, [], \"f549\", \"M0 224v272c0 8.84 7.16 16 16 16h80V192H32c-17.67 0-32 14.33-32 32zm360-48h-24v-40c0-4.42-3.58-8-8-8h-16c-4.42 0-8 3.58-8 8v64c0 4.42 3.58 8 8 8h48c4.42 0 8-3.58 8-8v-16c0-4.42-3.58-8-8-8zm137.75-63.96l-160-106.67a32.02 32.02 0 0 0-35.5 0l-160 106.67A32.002 32.002 0 0 0 128 138.66V512h128V368c0-8.84 7.16-16 16-16h96c8.84 0 16 7.16 16 16v144h128V138.67c0-10.7-5.35-20.7-14.25-26.63zM320 256c-44.18 0-80-35.82-80-80s35.82-80 80-80 80 35.82 80 80-35.82 80-80 80zm288-64h-64v320h80c8.84 0 16-7.16 16-16V224c0-17.67-14.33-32-32-32z\"]\n};\nvar faScrewdriver = {\n prefix: 'fas',\n iconName: 'screwdriver',\n icon: [512, 512, [], \"f54a\", \"M448 0L320 96v62.06l-83.03 83.03c6.79 4.25 13.27 9.06 19.07 14.87 5.8 5.8 10.62 12.28 14.87 19.07L353.94 192H416l96-128-64-64zM128 278.59L10.92 395.67c-14.55 14.55-14.55 38.15 0 52.71l52.7 52.7c14.56 14.56 38.15 14.56 52.71 0L233.41 384c29.11-29.11 29.11-76.3 0-105.41s-76.3-29.11-105.41 0z\"]\n};\nvar faScroll = {\n prefix: 'fas',\n iconName: 'scroll',\n icon: [640, 512, [], \"f70e\", \"M48 0C21.53 0 0 21.53 0 48v64c0 8.84 7.16 16 16 16h80V48C96 21.53 74.47 0 48 0zm208 412.57V352h288V96c0-52.94-43.06-96-96-96H111.59C121.74 13.41 128 29.92 128 48v368c0 38.87 34.65 69.65 74.75 63.12C234.22 474 256 444.46 256 412.57zM288 384v32c0 52.93-43.06 96-96 96h336c61.86 0 112-50.14 112-112 0-8.84-7.16-16-16-16H288z\"]\n};\nvar faSdCard = {\n prefix: 'fas',\n iconName: 'sd-card',\n icon: [384, 512, [], \"f7c2\", \"M320 0H128L0 128v320c0 35.3 28.7 64 64 64h256c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zM160 160h-48V64h48v96zm80 0h-48V64h48v96zm80 0h-48V64h48v96z\"]\n};\nvar faSearch = {\n prefix: 'fas',\n iconName: 'search',\n icon: [512, 512, [], \"f002\", \"M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z\"]\n};\nvar faSearchDollar = {\n prefix: 'fas',\n iconName: 'search-dollar',\n icon: [512, 512, [], \"f688\", \"M505.04 442.66l-99.71-99.69c-4.5-4.5-10.6-7-17-7h-16.3c27.6-35.3 44-79.69 44-127.99C416.03 93.09 322.92 0 208.02 0S0 93.09 0 207.98s93.11 207.98 208.02 207.98c48.3 0 92.71-16.4 128.01-44v16.3c0 6.4 2.5 12.5 7 17l99.71 99.69c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.59.1-33.99zm-297.02-90.7c-79.54 0-144-64.34-144-143.98 0-79.53 64.35-143.98 144-143.98 79.54 0 144 64.34 144 143.98 0 79.53-64.35 143.98-144 143.98zm27.11-152.54l-45.01-13.5c-5.16-1.55-8.77-6.78-8.77-12.73 0-7.27 5.3-13.19 11.8-13.19h28.11c4.56 0 8.96 1.29 12.82 3.72 3.24 2.03 7.36 1.91 10.13-.73l11.75-11.21c3.53-3.37 3.33-9.21-.57-12.14-9.1-6.83-20.08-10.77-31.37-11.35V112c0-4.42-3.58-8-8-8h-16c-4.42 0-8 3.58-8 8v16.12c-23.63.63-42.68 20.55-42.68 45.07 0 19.97 12.99 37.81 31.58 43.39l45.01 13.5c5.16 1.55 8.77 6.78 8.77 12.73 0 7.27-5.3 13.19-11.8 13.19h-28.1c-4.56 0-8.96-1.29-12.82-3.72-3.24-2.03-7.36-1.91-10.13.73l-11.75 11.21c-3.53 3.37-3.33 9.21.57 12.14 9.1 6.83 20.08 10.77 31.37 11.35V304c0 4.42 3.58 8 8 8h16c4.42 0 8-3.58 8-8v-16.12c23.63-.63 42.68-20.54 42.68-45.07 0-19.97-12.99-37.81-31.59-43.39z\"]\n};\nvar faSearchLocation = {\n prefix: 'fas',\n iconName: 'search-location',\n icon: [512, 512, [], \"f689\", \"M505.04 442.66l-99.71-99.69c-4.5-4.5-10.6-7-17-7h-16.3c27.6-35.3 44-79.69 44-127.99C416.03 93.09 322.92 0 208.02 0S0 93.09 0 207.98s93.11 207.98 208.02 207.98c48.3 0 92.71-16.4 128.01-44v16.3c0 6.4 2.5 12.5 7 17l99.71 99.69c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.59.1-33.99zm-297.02-90.7c-79.54 0-144-64.34-144-143.98 0-79.53 64.35-143.98 144-143.98 79.54 0 144 64.34 144 143.98 0 79.53-64.35 143.98-144 143.98zm.02-239.96c-40.78 0-73.84 33.05-73.84 73.83 0 32.96 48.26 93.05 66.75 114.86a9.24 9.24 0 0 0 14.18 0c18.49-21.81 66.75-81.89 66.75-114.86 0-40.78-33.06-73.83-73.84-73.83zm0 96c-13.26 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"]\n};\nvar faSearchMinus = {\n prefix: 'fas',\n iconName: 'search-minus',\n icon: [512, 512, [], \"f010\", \"M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z\"]\n};\nvar faSearchPlus = {\n prefix: 'fas',\n iconName: 'search-plus',\n icon: [512, 512, [], \"f00e\", \"M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z\"]\n};\nvar faSeedling = {\n prefix: 'fas',\n iconName: 'seedling',\n icon: [512, 512, [], \"f4d8\", \"M64 96H0c0 123.7 100.3 224 224 224v144c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320C288 196.3 187.7 96 64 96zm384-64c-84.2 0-157.4 46.5-195.7 115.2 27.7 30.2 48.2 66.9 59 107.6C424 243.1 512 147.9 512 32h-64z\"]\n};\nvar faServer = {\n prefix: 'fas',\n iconName: 'server',\n icon: [512, 512, [], \"f233\", \"M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z\"]\n};\nvar faShapes = {\n prefix: 'fas',\n iconName: 'shapes',\n icon: [512, 512, [], \"f61f\", \"M512 320v160c0 17.67-14.33 32-32 32H320c-17.67 0-32-14.33-32-32V320c0-17.67 14.33-32 32-32h160c17.67 0 32 14.33 32 32zm-384-64C57.31 256 0 313.31 0 384s57.31 128 128 128 128-57.31 128-128-57.31-128-128-128zm351.03-32c25.34 0 41.18-26.67 28.51-48L412.51 16c-12.67-21.33-44.35-21.33-57.02 0l-95.03 160c-12.67 21.33 3.17 48 28.51 48h190.06z\"]\n};\nvar faShare = {\n prefix: 'fas',\n iconName: 'share',\n icon: [512, 512, [], \"f064\", \"M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z\"]\n};\nvar faShareAlt = {\n prefix: 'fas',\n iconName: 'share-alt',\n icon: [448, 512, [], \"f1e0\", \"M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z\"]\n};\nvar faShareAltSquare = {\n prefix: 'fas',\n iconName: 'share-alt-square',\n icon: [448, 512, [], \"f1e1\", \"M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z\"]\n};\nvar faShareSquare = {\n prefix: 'fas',\n iconName: 'share-square',\n icon: [576, 512, [], \"f14d\", \"M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z\"]\n};\nvar faShekelSign = {\n prefix: 'fas',\n iconName: 'shekel-sign',\n icon: [448, 512, [], \"f20b\", \"M248 168v168c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V168c0-75.11-60.89-136-136-136H24C10.75 32 0 42.74 0 56v408c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V112h112c30.93 0 56 25.07 56 56zM432 32h-48c-8.84 0-16 7.16-16 16v296c0 30.93-25.07 56-56 56H200V176c0-8.84-7.16-16-16-16h-48c-8.84 0-16 7.16-16 16v280c0 13.25 10.75 24 24 24h168c75.11 0 136-60.89 136-136V48c0-8.84-7.16-16-16-16z\"]\n};\nvar faShieldAlt = {\n prefix: 'fas',\n iconName: 'shield-alt',\n icon: [512, 512, [], \"f3ed\", \"M466.5 83.7l-192-80a48.15 48.15 0 0 0-36.9 0l-192 80C27.7 91.1 16 108.6 16 128c0 198.5 114.5 335.7 221.5 380.3 11.8 4.9 25.1 4.9 36.9 0C360.1 472.6 496 349.3 496 128c0-19.4-11.7-36.9-29.5-44.3zM256.1 446.3l-.1-381 175.9 73.3c-3.3 151.4-82.1 261.1-175.8 307.7z\"]\n};\nvar faShip = {\n prefix: 'fas',\n iconName: 'ship',\n icon: [640, 512, [], \"f21a\", \"M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z\"]\n};\nvar faShippingFast = {\n prefix: 'fas',\n iconName: 'shipping-fast',\n icon: [640, 512, [], \"f48b\", \"M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H112C85.5 0 64 21.5 64 48v48H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h272c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H40c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h208c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H8c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h208c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H64v128c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm320 0c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z\"]\n};\nvar faShoePrints = {\n prefix: 'fas',\n iconName: 'shoe-prints',\n icon: [640, 512, [], \"f54b\", \"M192 160h32V32h-32c-35.35 0-64 28.65-64 64s28.65 64 64 64zM0 416c0 35.35 28.65 64 64 64h32V352H64c-35.35 0-64 28.65-64 64zm337.46-128c-34.91 0-76.16 13.12-104.73 32-24.79 16.38-44.52 32-104.73 32v128l57.53 15.97c26.21 7.28 53.01 13.12 80.31 15.05 32.69 2.31 65.6.67 97.58-6.2C472.9 481.3 512 429.22 512 384c0-64-84.18-96-174.54-96zM491.42 7.19C459.44.32 426.53-1.33 393.84.99c-27.3 1.93-54.1 7.77-80.31 15.04L256 32v128c60.2 0 79.94 15.62 104.73 32 28.57 18.88 69.82 32 104.73 32C555.82 224 640 192 640 128c0-45.22-39.1-97.3-148.58-120.81z\"]\n};\nvar faShoppingBag = {\n prefix: 'fas',\n iconName: 'shopping-bag',\n icon: [448, 512, [], \"f290\", \"M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z\"]\n};\nvar faShoppingBasket = {\n prefix: 'fas',\n iconName: 'shopping-basket',\n icon: [576, 512, [], \"f291\", \"M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z\"]\n};\nvar faShoppingCart = {\n prefix: 'fas',\n iconName: 'shopping-cart',\n icon: [576, 512, [], \"f07a\", \"M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z\"]\n};\nvar faShower = {\n prefix: 'fas',\n iconName: 'shower',\n icon: [512, 512, [], \"f2cc\", \"M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z\"]\n};\nvar faShuttleVan = {\n prefix: 'fas',\n iconName: 'shuttle-van',\n icon: [640, 512, [], \"f5b6\", \"M628.88 210.65L494.39 49.27A48.01 48.01 0 0 0 457.52 32H32C14.33 32 0 46.33 0 64v288c0 17.67 14.33 32 32 32h32c0 53.02 42.98 96 96 96s96-42.98 96-96h128c0 53.02 42.98 96 96 96s96-42.98 96-96h32c17.67 0 32-14.33 32-32V241.38c0-11.23-3.94-22.1-11.12-30.73zM64 192V96h96v96H64zm96 240c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm160-240h-96V96h96v96zm160 240c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm-96-240V96h66.02l80 96H384z\"]\n};\nvar faSign = {\n prefix: 'fas',\n iconName: 'sign',\n icon: [512, 512, [], \"f4d9\", \"M496 64H128V16c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16v48H16C7.2 64 0 71.2 0 80v32c0 8.8 7.2 16 16 16h48v368c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V128h368c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16zM160 384h320V160H160v224z\"]\n};\nvar faSignInAlt = {\n prefix: 'fas',\n iconName: 'sign-in-alt',\n icon: [512, 512, [], \"f2f6\", \"M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z\"]\n};\nvar faSignLanguage = {\n prefix: 'fas',\n iconName: 'sign-language',\n icon: [448, 512, [], \"f2a7\", \"M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z\"]\n};\nvar faSignOutAlt = {\n prefix: 'fas',\n iconName: 'sign-out-alt',\n icon: [512, 512, [], \"f2f5\", \"M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z\"]\n};\nvar faSignal = {\n prefix: 'fas',\n iconName: 'signal',\n icon: [640, 512, [], \"f012\", \"M216 288h-48c-8.84 0-16 7.16-16 16v192c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V304c0-8.84-7.16-16-16-16zM88 384H40c-8.84 0-16 7.16-16 16v96c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16v-96c0-8.84-7.16-16-16-16zm256-192h-48c-8.84 0-16 7.16-16 16v288c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V208c0-8.84-7.16-16-16-16zm128-96h-48c-8.84 0-16 7.16-16 16v384c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V112c0-8.84-7.16-16-16-16zM600 0h-48c-8.84 0-16 7.16-16 16v480c0 8.84 7.16 16 16 16h48c8.84 0 16-7.16 16-16V16c0-8.84-7.16-16-16-16z\"]\n};\nvar faSignature = {\n prefix: 'fas',\n iconName: 'signature',\n icon: [640, 512, [], \"f5b7\", \"M623.2 192c-51.8 3.5-125.7 54.7-163.1 71.5-29.1 13.1-54.2 24.4-76.1 24.4-22.6 0-26-16.2-21.3-51.9 1.1-8 11.7-79.2-42.7-76.1-25.1 1.5-64.3 24.8-169.5 126L192 182.2c30.4-75.9-53.2-151.5-129.7-102.8L7.4 116.3C0 121-2.2 130.9 2.5 138.4l17.2 27c4.7 7.5 14.6 9.7 22.1 4.9l58-38.9c18.4-11.7 40.7 7.2 32.7 27.1L34.3 404.1C27.5 421 37 448 64 448c8.3 0 16.5-3.2 22.6-9.4 42.2-42.2 154.7-150.7 211.2-195.8-2.2 28.5-2.1 58.9 20.6 83.8 15.3 16.8 37.3 25.3 65.5 25.3 35.6 0 68-14.6 102.3-30 33-14.8 99-62.6 138.4-65.8 8.5-.7 15.2-7.3 15.2-15.8v-32.1c.2-9.1-7.5-16.8-16.6-16.2z\"]\n};\nvar faSimCard = {\n prefix: 'fas',\n iconName: 'sim-card',\n icon: [384, 512, [], \"f7c4\", \"M0 64v384c0 35.3 28.7 64 64 64h256c35.3 0 64-28.7 64-64V128L256 0H64C28.7 0 0 28.7 0 64zm224 192h-64v-64h64v64zm96 0h-64v-64h32c17.7 0 32 14.3 32 32v32zm-64 128h64v32c0 17.7-14.3 32-32 32h-32v-64zm-96 0h64v64h-64v-64zm-96 0h64v64H96c-17.7 0-32-14.3-32-32v-32zm0-96h256v64H64v-64zm0-64c0-17.7 14.3-32 32-32h32v64H64v-32z\"]\n};\nvar faSitemap = {\n prefix: 'fas',\n iconName: 'sitemap',\n icon: [640, 512, [], \"f0e8\", \"M128 352H32c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32zm-24-80h192v48h48v-48h192v48h48v-57.59c0-21.17-17.23-38.41-38.41-38.41H344v-64h40c17.67 0 32-14.33 32-32V32c0-17.67-14.33-32-32-32H256c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h40v64H94.41C73.23 224 56 241.23 56 262.41V320h48v-48zm264 80h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32zm240 0h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32z\"]\n};\nvar faSkating = {\n prefix: 'fas',\n iconName: 'skating',\n icon: [448, 512, [], \"f7c5\", \"M400 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm0 448c-8.8 0-16 7.2-16 16s-7.2 16-16 16h-96c-8.8 0-16 7.2-16 16s7.2 16 16 16h96c26.5 0 48-21.5 48-48 0-8.8-7.2-16-16-16zm-282.2 8.6c-6.2 6.2-16.4 6.3-22.6 0l-67.9-67.9c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l67.9 67.9c9.4 9.4 21.7 14 34 14s24.6-4.7 33.9-14c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.3-22.7 0zm56.1-179.8l-93.7 93.7c-12.5 12.5-12.5 32.8 0 45.2 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l91.9-91.9-30.2-30.2c-5-5-9.4-10.7-13.2-16.8zM128 160h105.5l-20.1 17.2c-13.5 11.5-21.6 28.4-22.3 46.1-.7 17.8 6.1 35.2 18.7 47.7l78.2 78.2V432c0 17.7 14.3 32 32 32s32-14.3 32-32v-89.4c0-12.6-5.1-25-14.1-33.9l-61-61c.5-.4 1.2-.6 1.7-1.1l82.3-82.3c11.5-11.5 14.9-28.6 8.7-43.6-6.2-15-20.7-24.7-37-24.7H128c-17.7 0-32 14.3-32 32s14.3 32 32 32z\"]\n};\nvar faSkiing = {\n prefix: 'fas',\n iconName: 'skiing',\n icon: [512, 512, [], \"f7c9\", \"M432 96c26.5 0 48-21.5 48-48S458.5 0 432 0s-48 21.5-48 48 21.5 48 48 48zm73 356.1c-9.4-9.4-24.6-9.4-33.9 0-12.1 12.1-30.5 15.4-45.1 8.7l-135.8-70.2 49.2-73.8c12.7-19 10.2-44.5-6-60.6L293 215.7l-107-53.1c-2.9 19.9 3.4 40 17.7 54.4l75.1 75.2-45.9 68.8L35 258.7c-11.7-6-26.2-1.5-32.3 10.3-6.1 11.8-1.5 26.3 10.3 32.3l391.9 202.5c11.9 5.5 24.5 8.1 37.1 8.1 23.2 0 46-9 63-26 9.3-9.3 9.3-24.5 0-33.8zM120 91.6l-11.5 22.5c14.4 7.3 31.2 4.9 42.8-4.8l47.2 23.4c-.1.1-.1.2-.2.3l114.5 56.8 32.4-13 6.4 19.1c4 12.1 12.6 22 24 27.7l58.1 29c15.9 7.9 35 1.5 42.9-14.3 7.9-15.8 1.5-35-14.3-42.9l-52.1-26.1-17.1-51.2c-8.1-24.2-40.9-56.6-84.5-39.2l-81.2 32.5-62.5-31c.3-14.5-7.2-28.6-20.9-35.6l-11.1 21.7h-.2l-34.4-7c-1.8-.4-3.7.2-5 1.7-1.9 2.2-1.7 5.5.5 7.4l26.2 23z\"]\n};\nvar faSkiingNordic = {\n prefix: 'fas',\n iconName: 'skiing-nordic',\n icon: [576, 512, [], \"f7ca\", \"M336 96c26.5 0 48-21.5 48-48S362.5 0 336 0s-48 21.5-48 48 21.5 48 48 48zm216 320c-13.2 0-24 10.7-24 24 0 13.2-10.8 24-24 24h-69.5L460 285.6c11.7-4.7 20.1-16.2 20.1-29.6 0-17.7-14.3-32-32-32h-44L378 170.8c-12.5-25.5-35.5-44.2-61.8-50.9L245 98.7c-28.3-6.8-57.8-.5-80.8 17.1l-39.7 30.4c-14 10.7-16.7 30.8-5.9 44.9.7.9 1.7 1.3 2.4 2.1L66.9 464H24c-13.2 0-24 10.7-24 24s10.8 24 24 24h480c39.7 0 72-32.3 72-72 0-13.2-10.8-24-24-24zm-260.5 48h-96.9l43.1-91-22-13c-12.1-7.2-21.9-16.9-29.5-27.8L123.7 464H99.5l52.3-261.4c4.1-1 8.1-2.9 11.7-5.6l39.7-30.4c7.7-5.9 17.4-8 25.3-6.1l14.7 4.4-37.5 87.4c-12.6 29.5-1.3 64 26.3 80.3l85 50.2-25.5 81.2zm110.6 0h-43.6l23.6-75.5c5.9-20.8-2.9-43.1-21.6-54.4L299.3 298l31.3-78.3 20.3 41.4c8 16.3 24.9 26.9 43.1 26.9h33.3l-25.2 176z\"]\n};\nvar faSkull = {\n prefix: 'fas',\n iconName: 'skull',\n icon: [512, 512, [], \"f54c\", \"M256 0C114.6 0 0 100.3 0 224c0 70.1 36.9 132.6 94.5 173.7 9.6 6.9 15.2 18.1 13.5 29.9l-9.4 66.2c-1.4 9.6 6 18.2 15.7 18.2H192v-56c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v56h64v-56c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v56h77.7c9.7 0 17.1-8.6 15.7-18.2l-9.4-66.2c-1.7-11.7 3.8-23 13.5-29.9C475.1 356.6 512 294.1 512 224 512 100.3 397.4 0 256 0zm-96 320c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm192 0c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z\"]\n};\nvar faSkullCrossbones = {\n prefix: 'fas',\n iconName: 'skull-crossbones',\n icon: [448, 512, [], \"f714\", \"M439.15 453.06L297.17 384l141.99-69.06c7.9-3.95 11.11-13.56 7.15-21.46L432 264.85c-3.95-7.9-13.56-11.11-21.47-7.16L224 348.41 37.47 257.69c-7.9-3.95-17.51-.75-21.47 7.16L1.69 293.48c-3.95 7.9-.75 17.51 7.15 21.46L150.83 384 8.85 453.06c-7.9 3.95-11.11 13.56-7.15 21.47l14.31 28.63c3.95 7.9 13.56 11.11 21.47 7.15L224 419.59l186.53 90.72c7.9 3.95 17.51.75 21.47-7.15l14.31-28.63c3.95-7.91.74-17.52-7.16-21.47zM150 237.28l-5.48 25.87c-2.67 12.62 5.42 24.85 16.45 24.85h126.08c11.03 0 19.12-12.23 16.45-24.85l-5.5-25.87c41.78-22.41 70-62.75 70-109.28C368 57.31 303.53 0 224 0S80 57.31 80 128c0 46.53 28.22 86.87 70 109.28zM280 112c17.65 0 32 14.35 32 32s-14.35 32-32 32-32-14.35-32-32 14.35-32 32-32zm-112 0c17.65 0 32 14.35 32 32s-14.35 32-32 32-32-14.35-32-32 14.35-32 32-32z\"]\n};\nvar faSlash = {\n prefix: 'fas',\n iconName: 'slash',\n icon: [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"]\n};\nvar faSleigh = {\n prefix: 'fas',\n iconName: 'sleigh',\n icon: [640, 512, [], \"f7cc\", \"M612.7 350.7l-9.3-7.4c-6.9-5.5-17-4.4-22.5 2.5l-10 12.5c-5.5 6.9-4.4 17 2.5 22.5l9.3 7.4c5.9 4.7 9.2 11.7 9.2 19.2 0 13.6-11 24.6-24.6 24.6H48c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h516c39 0 73.7-29.3 75.9-68.3 1.4-23.8-8.7-46.3-27.2-61zM32 224c0 59.6 40.9 109.2 96 123.5V400h64v-48h192v48h64v-48c53 0 96-43 96-96v-96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-96v64c0 35.3-28.7 64-64 64h-20.7c-65.8 0-125.9-37.2-155.3-96-29.4-58.8-89.6-96-155.3-96H32C14.3 32 0 46.3 0 64s14.3 32 32 32v128z\"]\n};\nvar faSlidersH = {\n prefix: 'fas',\n iconName: 'sliders-h',\n icon: [512, 512, [], \"f1de\", \"M496 384H160v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h80v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h336c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160h-80v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h336v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h80c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160H288V48c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16C7.2 64 0 71.2 0 80v32c0 8.8 7.2 16 16 16h208v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h208c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16z\"]\n};\nvar faSmile = {\n prefix: 'fas',\n iconName: 'smile',\n icon: [496, 512, [], \"f118\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm194.8 170.2C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.6-16.3 11-36.7 24.6-20.5 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c13.4-16.2 38.1 4.2 24.6 20.5z\"]\n};\nvar faSmileBeam = {\n prefix: 'fas',\n iconName: 'smile-beam',\n icon: [496, 512, [], \"f5b8\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM112 223.4c3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.7 8.6-10.8 11.9-14.9 4.5l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.3 7.4-15.8 4-15.1-4.5zm250.8 122.8C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.5-16.3 11-36.7 24.6-20.5 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c13.6-16.2 38.1 4.3 24.6 20.5zm6.2-118.3l-9.5-17c-7.7-13.7-19.2-21.6-31.5-21.6s-23.8 7.9-31.5 21.6l-9.5 17c-4.1 7.3-15.6 4-14.9-4.5 3.3-42.1 32.2-71.4 56-71.4s52.7 29.3 56 71.4c.6 8.6-11 11.9-15.1 4.5z\"]\n};\nvar faSmileWink = {\n prefix: 'fas',\n iconName: 'smile-wink',\n icon: [496, 512, [], \"f4da\", \"M0 256c0 137 111 248 248 248s248-111 248-248S385 8 248 8 0 119 0 256zm200-48c0 17.7-14.3 32-32 32s-32-14.3-32-32 14.3-32 32-32 32 14.3 32 32zm158.5 16.5c-14.8-13.2-46.2-13.2-61 0L288 233c-8.3 7.4-21.6.4-19.8-10.8 4-25.2 34.2-42.1 59.9-42.1S384 197 388 222.2c1.7 11.1-11.4 18.3-19.8 10.8l-9.7-8.5zM157.8 325.8C180.2 352.7 213 368 248 368s67.8-15.4 90.2-42.2c13.6-16.2 38.1 4.2 24.6 20.5C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.5-16.3 11.2-36.7 24.6-20.4z\"]\n};\nvar faSmog = {\n prefix: 'fas',\n iconName: 'smog',\n icon: [640, 512, [], \"f75f\", \"M624 368H80c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h544c8.8 0 16-7.2 16-16v-16c0-8.8-7.2-16-16-16zm-480 96H16c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h128c8.8 0 16-7.2 16-16v-16c0-8.8-7.2-16-16-16zm416 0H224c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h336c8.8 0 16-7.2 16-16v-16c0-8.8-7.2-16-16-16zM144 288h156.1c22.5 19.7 51.6 32 83.9 32s61.3-12.3 83.9-32H528c61.9 0 112-50.1 112-112S589.9 64 528 64c-18 0-34.7 4.6-49.7 12.1C454 31 406.8 0 352 0c-41 0-77.8 17.3-104 44.8C221.8 17.3 185 0 144 0 64.5 0 0 64.5 0 144s64.5 144 144 144z\"]\n};\nvar faSmoking = {\n prefix: 'fas',\n iconName: 'smoking',\n icon: [640, 512, [], \"f48d\", \"M632 352h-48c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8zM553.3 87.1c-5.7-3.8-9.3-10-9.3-16.8V8c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v62.3c0 22 10.2 43.4 28.6 55.4 42.2 27.3 67.4 73.8 67.4 124V280c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-30.3c0-65.5-32.4-126.2-86.7-162.6zM432 352H48c-26.5 0-48 21.5-48 48v64c0 26.5 21.5 48 48 48h384c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16zm-32 112H224v-64h176v64zm87.7-322.4C463.8 125 448 99.3 448 70.3V8c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v66.4c0 43.7 24.6 81.6 60.3 106.7 22.4 15.7 35.7 41.2 35.7 68.6V280c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-30.3c0-43.3-21-83.4-56.3-108.1zM536 352h-48c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8z\"]\n};\nvar faSmokingBan = {\n prefix: 'fas',\n iconName: 'smoking-ban',\n icon: [512, 512, [], \"f54d\", \"M96 304c0 8.8 7.2 16 16 16h117.5l-96-96H112c-8.8 0-16 7.2-16 16v64zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm0 448c-105.9 0-192-86.1-192-192 0-41.4 13.3-79.7 35.7-111.1l267.4 267.4C335.7 434.7 297.4 448 256 448zm45.2-192H384v32h-50.8l-32-32zm111.1 111.1L365.2 320H400c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16H269.2L144.9 99.7C176.3 77.3 214.6 64 256 64c105.9 0 192 86.1 192 192 0 41.4-13.3 79.7-35.7 111.1zM320.6 128c-15.6 0-28.6-11.2-31.4-25.9-.7-3.6-4-6.1-7.7-6.1h-16.2c-5 0-8.7 4.5-8 9.4 4.6 30.9 31.2 54.6 63.3 54.6 15.6 0 28.6 11.2 31.4 25.9.7 3.6 4 6.1 7.7 6.1h16.2c5 0 8.7-4.5 8-9.4-4.6-30.9-31.2-54.6-63.3-54.6z\"]\n};\nvar faSms = {\n prefix: 'fas',\n iconName: 'sms',\n icon: [512, 512, [], \"f7cd\", \"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5c-2.2 2.3-2.8 5.7-1.5 8.7 1.3 3 4.1 4.8 7.3 4.8 66.3 0 116-31.8 140.6-51.4 32.7 12.3 69 19.4 107.4 19.4 141.4 0 256-93.1 256-208S397.4 32 256 32zM128.2 304H116c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h12.3c6 0 10.4-3.5 10.4-6.6 0-1.3-.8-2.7-2.1-3.8l-21.9-18.8c-8.5-7.2-13.3-17.5-13.3-28.1 0-21.3 19-38.6 42.4-38.6H156c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8h-12.3c-6 0-10.4 3.5-10.4 6.6 0 1.3.8 2.7 2.1 3.8l21.9 18.8c8.5 7.2 13.3 17.5 13.3 28.1.1 21.3-19 38.6-42.4 38.6zm191.8-8c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8v-68.2l-24.8 55.8c-2.9 5.9-11.4 5.9-14.3 0L224 227.8V296c0 4.4-3.6 8-8 8h-16c-4.4 0-8-3.6-8-8V192c0-8.8 7.2-16 16-16h16c6.1 0 11.6 3.4 14.3 8.8l17.7 35.4 17.7-35.4c2.7-5.4 8.3-8.8 14.3-8.8h16c8.8 0 16 7.2 16 16v104zm48.3 8H356c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h12.3c6 0 10.4-3.5 10.4-6.6 0-1.3-.8-2.7-2.1-3.8l-21.9-18.8c-8.5-7.2-13.3-17.5-13.3-28.1 0-21.3 19-38.6 42.4-38.6H396c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8h-12.3c-6 0-10.4 3.5-10.4 6.6 0 1.3.8 2.7 2.1 3.8l21.9 18.8c8.5 7.2 13.3 17.5 13.3 28.1.1 21.3-18.9 38.6-42.3 38.6z\"]\n};\nvar faSnowboarding = {\n prefix: 'fas',\n iconName: 'snowboarding',\n icon: [512, 512, [], \"f7ce\", \"M432 96c26.5 0 48-21.5 48-48S458.5 0 432 0s-48 21.5-48 48 21.5 48 48 48zm28.8 153.6c5.8 4.3 12.5 6.4 19.2 6.4 9.7 0 19.3-4.4 25.6-12.8 10.6-14.1 7.8-34.2-6.4-44.8l-111.4-83.5c-13.8-10.3-29.1-18.4-45.4-23.8l-63.7-21.2-26.1-52.1C244.7 2 225.5-4.4 209.7 3.5c-15.8 7.9-22.2 27.1-14.3 42.9l29.1 58.1c5.7 11.4 15.6 19.9 27.7 24l16.4 5.5-41.2 20.6c-21.8 10.9-35.4 32.8-35.4 57.2v53.1l-74.1 24.7c-16.8 5.6-25.8 23.7-20.2 40.5 1.7 5.2 4.9 9.4 8.7 12.9l-38.7-14.1c-9.7-3.5-17.4-10.6-21.8-20-5.6-12-19.9-17.2-31.9-11.6s-17.2 19.9-11.6 31.9c9.8 21 27.1 36.9 48.9 44.8l364.8 132.7c9.7 3.5 19.7 5.3 29.7 5.3 12.5 0 24.9-2.7 36.5-8.2 12-5.6 17.2-19.9 11.6-31.9S474 454.7 462 460.3c-9.3 4.4-19.8 4.8-29.5 1.3l-90.8-33.1c8.7-4.1 15.6-11.8 17.8-21.9l21.9-102c3.9-18.2-3.2-37.2-18.1-48.4l-52-39 66-30.5 83.5 62.9zm-144.4 51.7l-19.7 92c-1.5 7.1-.1 13.9 2.8 20l-169.4-61.6c2.7-.2 5.4-.4 8-1.3l85-28.4c19.6-6.5 32.8-24.8 32.8-45.5V256l60.5 45.3z\"]\n};\nvar faSnowflake = {\n prefix: 'fas',\n iconName: 'snowflake',\n icon: [448, 512, [], \"f2dc\", \"M440.3 345.2l-33.8-19.5 26-7c8.2-2.2 13.1-10.7 10.9-18.9l-4-14.9c-2.2-8.2-10.7-13.1-18.9-10.9l-70.8 19-63.9-37 63.8-36.9 70.8 19c8.2 2.2 16.7-2.7 18.9-10.9l4-14.9c2.2-8.2-2.7-16.7-10.9-18.9l-26-7 33.8-19.5c7.4-4.3 9.9-13.7 5.7-21.1L430.4 119c-4.3-7.4-13.7-9.9-21.1-5.7l-33.8 19.5 7-26c2.2-8.2-2.7-16.7-10.9-18.9l-14.9-4c-8.2-2.2-16.7 2.7-18.9 10.9l-19 70.8-62.8 36.2v-77.5l53.7-53.7c6.2-6.2 6.2-16.4 0-22.6l-11.3-11.3c-6.2-6.2-16.4-6.2-22.6 0L256 56.4V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v40.4l-19.7-19.7c-6.2-6.2-16.4-6.2-22.6 0L138.3 48c-6.3 6.2-6.3 16.4 0 22.6l53.7 53.7v77.5l-62.8-36.2-19-70.8c-2.2-8.2-10.7-13.1-18.9-10.9l-14.9 4c-8.2 2.2-13.1 10.7-10.9 18.9l7 26-33.8-19.5c-7.4-4.3-16.8-1.7-21.1 5.7L2.1 145.7c-4.3 7.4-1.7 16.8 5.7 21.1l33.8 19.5-26 7c-8.3 2.2-13.2 10.7-11 19l4 14.9c2.2 8.2 10.7 13.1 18.9 10.9l70.8-19 63.8 36.9-63.8 36.9-70.8-19c-8.2-2.2-16.7 2.7-18.9 10.9l-4 14.9c-2.2 8.2 2.7 16.7 10.9 18.9l26 7-33.8 19.6c-7.4 4.3-9.9 13.7-5.7 21.1l15.5 26.8c4.3 7.4 13.7 9.9 21.1 5.7l33.8-19.5-7 26c-2.2 8.2 2.7 16.7 10.9 18.9l14.9 4c8.2 2.2 16.7-2.7 18.9-10.9l19-70.8 62.8-36.2v77.5l-53.7 53.7c-6.3 6.2-6.3 16.4 0 22.6l11.3 11.3c6.2 6.2 16.4 6.2 22.6 0l19.7-19.7V496c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-40.4l19.7 19.7c6.2 6.2 16.4 6.2 22.6 0l11.3-11.3c6.2-6.2 6.2-16.4 0-22.6L256 387.7v-77.5l62.8 36.2 19 70.8c2.2 8.2 10.7 13.1 18.9 10.9l14.9-4c8.2-2.2 13.1-10.7 10.9-18.9l-7-26 33.8 19.5c7.4 4.3 16.8 1.7 21.1-5.7l15.5-26.8c4.3-7.3 1.8-16.8-5.6-21z\"]\n};\nvar faSnowman = {\n prefix: 'fas',\n iconName: 'snowman',\n icon: [512, 512, [], \"f7d0\", \"M510.9 152.3l-5.9-14.5c-3.3-8-12.6-11.9-20.8-8.7L456 140.6v-29c0-8.6-7.2-15.6-16-15.6h-16c-8.8 0-16 7-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.4 23c-5.9-10-13.3-18.9-22-26.6 13.6-16.6 22-37.4 22-60.5 0-53-43-96-96-96s-96 43-96 96c0 23.1 8.5 43.9 22 60.5-8.7 7.7-16 16.6-22 26.6l-56.4-23c.1-.5.3-1 .3-1.5v-46.9C104 103 96.8 96 88 96H72c-8.8 0-16 7-16 15.6v29l-28.1-11.5c-8.2-3.2-17.5.7-20.8 8.7l-5.9 14.5c-3.3 8 .7 17.1 8.9 20.3l135.2 55.2c-.4 4-1.2 8-1.2 12.2 0 10.1 1.7 19.6 4.2 28.9C120.9 296.4 104 334.2 104 376c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2c13.3 0 26.3-4.1 37.2-11.7 46.5-32.3 74.4-89.4 62.9-152.6-5.5-30.2-20.5-57.6-41.6-79 2.5-9.2 4.2-18.7 4.2-28.7 0-4.2-.8-8.1-1.2-12.2L502 172.6c8.1-3.1 12.1-12.2 8.9-20.3zM224 96c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm32 272c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-64c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm0-88s-16-23.2-16-32 7.2-16 16-16 16 7.2 16 16-16 32-16 32zm32-56c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z\"]\n};\nvar faSnowplow = {\n prefix: 'fas',\n iconName: 'snowplow',\n icon: [640, 512, [], \"f7d2\", \"M120 376c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm80 0c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm80 0c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm80 0c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm238.6 49.4c-14.5-14.5-22.6-34.1-22.6-54.6V269.2c0-20.5 8.1-40.1 22.6-54.6l36.7-36.7c6.2-6.2 6.2-16.4 0-22.6l-22.6-22.6c-6.2-6.2-16.4-6.2-22.6 0l-36.7 36.7c-26.5 26.5-41.4 62.4-41.4 99.9V288h-64v-50.9c0-8.7-1.8-17.2-5.2-25.2L364.5 29.1C356.9 11.4 339.6 0 320.3 0H176c-26.5 0-48 21.5-48 48v112h-16c-26.5 0-48 21.5-48 48v91.2C26.3 317.2 0 355.4 0 400c0 61.9 50.1 112 112 112h256c61.9 0 112-50.1 112-112 0-17.3-4.2-33.4-11.2-48H512v18.7c0 37.5 14.9 73.4 41.4 99.9l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0l22.6-22.6c6.2-6.2 6.2-16.4 0-22.6l-36.7-36.7zM192 64h117.8l68.6 160H256l-64-64V64zm176 384H112c-26.5 0-48-21.5-48-48s21.5-48 48-48h256c26.5 0 48 21.5 48 48s-21.5 48-48 48z\"]\n};\nvar faSocks = {\n prefix: 'fas',\n iconName: 'socks',\n icon: [512, 512, [], \"f696\", \"M214.66 311.01L288 256V96H128v176l-86.65 64.61c-39.4 29.56-53.86 84.42-29.21 127.06C30.39 495.25 63.27 512 96.08 512c20.03 0 40.25-6.25 57.52-19.2l21.86-16.39c-29.85-55.38-13.54-125.84 39.2-165.4zM288 32c0-11.05 3.07-21.3 8.02-30.38C293.4.92 290.85 0 288 0H160c-17.67 0-32 14.33-32 32v32h160V32zM480 0H352c-17.67 0-32 14.33-32 32v32h192V32c0-17.67-14.33-32-32-32zM320 272l-86.13 64.61c-39.4 29.56-53.86 84.42-29.21 127.06 18.25 31.58 50.61 48.33 83.42 48.33 20.03 0 40.25-6.25 57.52-19.2l115.2-86.4A127.997 127.997 0 0 0 512 304V96H320v176z\"]\n};\nvar faSolarPanel = {\n prefix: 'fas',\n iconName: 'solar-panel',\n icon: [640, 512, [], \"f5ba\", \"M431.98 448.01l-47.97.05V416h-128v32.21l-47.98.05c-8.82.01-15.97 7.16-15.98 15.99l-.05 31.73c-.01 8.85 7.17 16.03 16.02 16.02l223.96-.26c8.82-.01 15.97-7.16 15.98-15.98l.04-31.73c.01-8.85-7.17-16.03-16.02-16.02zM585.2 26.74C582.58 11.31 568.99 0 553.06 0H86.93C71 0 57.41 11.31 54.79 26.74-3.32 369.16.04 348.08.03 352c-.03 17.32 14.29 32 32.6 32h574.74c18.23 0 32.51-14.56 32.59-31.79.02-4.08 3.35 16.95-54.76-325.47zM259.83 64h120.33l9.77 96H250.06l9.77-96zm-75.17 256H71.09L90.1 208h105.97l-11.41 112zm16.29-160H98.24l16.29-96h96.19l-9.77 96zm32.82 160l11.4-112h149.65l11.4 112H233.77zm195.5-256h96.19l16.29 96H439.04l-9.77-96zm26.06 256l-11.4-112H549.9l19.01 112H455.33z\"]\n};\nvar faSort = {\n prefix: 'fas',\n iconName: 'sort',\n icon: [320, 512, [], \"f0dc\", \"M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z\"]\n};\nvar faSortAlphaDown = {\n prefix: 'fas',\n iconName: 'sort-alpha-down',\n icon: [448, 512, [], \"f15d\", \"M176 352h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.36 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352zm240-64H288a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h56l-61.26 70.45A32 32 0 0 0 272 446.37V464a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-56l61.26-70.45A32 32 0 0 0 432 321.63V304a16 16 0 0 0-16-16zm31.06-85.38l-59.27-160A16 16 0 0 0 372.72 32h-41.44a16 16 0 0 0-15.07 10.62l-59.27 160A16 16 0 0 0 272 224h24.83a16 16 0 0 0 15.23-11.08l4.42-12.92h71l4.41 12.92A16 16 0 0 0 407.16 224H432a16 16 0 0 0 15.06-21.38zM335.61 144L352 96l16.39 48z\"]\n};\nvar faSortAlphaDownAlt = {\n prefix: 'fas',\n iconName: 'sort-alpha-down-alt',\n icon: [448, 512, [], \"f881\", \"M176 352h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.36 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352zm112-128h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-56l61.26-70.45A32 32 0 0 0 432 65.63V48a16 16 0 0 0-16-16H288a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h56l-61.26 70.45A32 32 0 0 0 272 190.37V208a16 16 0 0 0 16 16zm159.06 234.62l-59.27-160A16 16 0 0 0 372.72 288h-41.44a16 16 0 0 0-15.07 10.62l-59.27 160A16 16 0 0 0 272 480h24.83a16 16 0 0 0 15.23-11.08l4.42-12.92h71l4.41 12.92A16 16 0 0 0 407.16 480H432a16 16 0 0 0 15.06-21.38zM335.61 400L352 352l16.39 48z\"]\n};\nvar faSortAlphaUp = {\n prefix: 'fas',\n iconName: 'sort-alpha-up',\n icon: [448, 512, [], \"f15e\", \"M16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.78 160 16 160zm400 128H288a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h56l-61.26 70.45A32 32 0 0 0 272 446.37V464a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-56l61.26-70.45A32 32 0 0 0 432 321.63V304a16 16 0 0 0-16-16zm31.06-85.38l-59.27-160A16 16 0 0 0 372.72 32h-41.44a16 16 0 0 0-15.07 10.62l-59.27 160A16 16 0 0 0 272 224h24.83a16 16 0 0 0 15.23-11.08l4.42-12.92h71l4.41 12.92A16 16 0 0 0 407.16 224H432a16 16 0 0 0 15.06-21.38zM335.61 144L352 96l16.39 48z\"]\n};\nvar faSortAlphaUpAlt = {\n prefix: 'fas',\n iconName: 'sort-alpha-up-alt',\n icon: [448, 512, [], \"f882\", \"M16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.78 160 16 160zm272 64h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-56l61.26-70.45A32 32 0 0 0 432 65.63V48a16 16 0 0 0-16-16H288a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h56l-61.26 70.45A32 32 0 0 0 272 190.37V208a16 16 0 0 0 16 16zm159.06 234.62l-59.27-160A16 16 0 0 0 372.72 288h-41.44a16 16 0 0 0-15.07 10.62l-59.27 160A16 16 0 0 0 272 480h24.83a16 16 0 0 0 15.23-11.08l4.42-12.92h71l4.41 12.92A16 16 0 0 0 407.16 480H432a16 16 0 0 0 15.06-21.38zM335.61 400L352 352l16.39 48z\"]\n};\nvar faSortAmountDown = {\n prefix: 'fas',\n iconName: 'sort-amount-down',\n icon: [512, 512, [], \"f160\", \"M304 416h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-128-64h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.37 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352zm256-192H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-64 128H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM496 32H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faSortAmountDownAlt = {\n prefix: 'fas',\n iconName: 'sort-amount-down-alt',\n icon: [512, 512, [], \"f884\", \"M240 96h64a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm0 128h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm256 192H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-256-64h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm-64 0h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.37 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352z\"]\n};\nvar faSortAmountUp = {\n prefix: 'fas',\n iconName: 'sort-amount-up',\n icon: [512, 512, [], \"f161\", \"M304 416h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.77 160 16 160zm416 0H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-64 128H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM496 32H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faSortAmountUpAlt = {\n prefix: 'fas',\n iconName: 'sort-amount-up-alt',\n icon: [512, 512, [], \"f885\", \"M240 96h64a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm0 128h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm256 192H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-256-64h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zM16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.39-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.78 160 16 160z\"]\n};\nvar faSortDown = {\n prefix: 'fas',\n iconName: 'sort-down',\n icon: [320, 512, [], \"f0dd\", \"M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z\"]\n};\nvar faSortNumericDown = {\n prefix: 'fas',\n iconName: 'sort-numeric-down',\n icon: [448, 512, [], \"f162\", \"M304 96h16v64h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-16V48a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 304 96zm26.15 162.91a79 79 0 0 0-55 54.17c-14.25 51.05 21.21 97.77 68.85 102.53a84.07 84.07 0 0 1-20.85 12.91c-7.57 3.4-10.8 12.47-8.18 20.34l9.9 20c2.87 8.63 12.53 13.49 20.9 9.91 58-24.76 86.25-61.61 86.25-132V336c-.02-51.21-48.4-91.34-101.85-77.09zM352 356a20 20 0 1 1 20-20 20 20 0 0 1-20 20zm-176-4h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.36 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352z\"]\n};\nvar faSortNumericDownAlt = {\n prefix: 'fas',\n iconName: 'sort-numeric-down-alt',\n icon: [448, 512, [], \"f886\", \"M176 352h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.36 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352zm224 64h-16V304a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 304 352h16v64h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM330.17 34.91a79 79 0 0 0-55 54.17c-14.27 51.05 21.19 97.77 68.83 102.53a84.07 84.07 0 0 1-20.85 12.91c-7.57 3.4-10.8 12.47-8.18 20.34l9.9 20c2.87 8.63 12.53 13.49 20.9 9.91 58-24.77 86.25-61.61 86.25-132V112c-.02-51.21-48.4-91.34-101.85-77.09zM352 132a20 20 0 1 1 20-20 20 20 0 0 1-20 20z\"]\n};\nvar faSortNumericUp = {\n prefix: 'fas',\n iconName: 'sort-numeric-up',\n icon: [448, 512, [], \"f163\", \"M330.17 258.91a79 79 0 0 0-55 54.17c-14.27 51.05 21.19 97.77 68.83 102.53a84.07 84.07 0 0 1-20.85 12.91c-7.57 3.4-10.8 12.47-8.18 20.34l9.9 20c2.87 8.63 12.53 13.49 20.9 9.91 58-24.76 86.25-61.61 86.25-132V336c-.02-51.21-48.4-91.34-101.85-77.09zM352 356a20 20 0 1 1 20-20 20 20 0 0 1-20 20zM304 96h16v64h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-16V48a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 304 96zM107.31 36.69a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.78 160 16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31z\"]\n};\nvar faSortNumericUpAlt = {\n prefix: 'fas',\n iconName: 'sort-numeric-up-alt',\n icon: [448, 512, [], \"f887\", \"M107.31 36.69a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.78 160 16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31zM400 416h-16V304a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 304 352h16v64h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM330.17 34.91a79 79 0 0 0-55 54.17c-14.27 51.05 21.19 97.77 68.83 102.53a84.07 84.07 0 0 1-20.85 12.91c-7.57 3.4-10.8 12.47-8.18 20.34l9.9 20c2.87 8.63 12.53 13.49 20.9 9.91 58-24.77 86.25-61.61 86.25-132V112c-.02-51.21-48.4-91.34-101.85-77.09zM352 132a20 20 0 1 1 20-20 20 20 0 0 1-20 20z\"]\n};\nvar faSortUp = {\n prefix: 'fas',\n iconName: 'sort-up',\n icon: [320, 512, [], \"f0de\", \"M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z\"]\n};\nvar faSpa = {\n prefix: 'fas',\n iconName: 'spa',\n icon: [576, 512, [], \"f5bb\", \"M568.25 192c-29.04.13-135.01 6.16-213.84 83-33.12 29.63-53.36 63.3-66.41 94.86-13.05-31.56-33.29-65.23-66.41-94.86-78.83-76.84-184.8-82.87-213.84-83-4.41-.02-7.79 3.4-7.75 7.82.23 27.92 7.14 126.14 88.77 199.3C172.79 480.94 256 480 288 480s115.19.95 199.23-80.88c81.64-73.17 88.54-171.38 88.77-199.3.04-4.42-3.34-7.84-7.75-7.82zM287.98 302.6c12.82-18.85 27.6-35.78 44.09-50.52 19.09-18.61 39.58-33.3 60.26-45.18-16.44-70.5-51.72-133.05-96.73-172.22-4.11-3.58-11.02-3.58-15.14 0-44.99 39.14-80.27 101.63-96.74 172.07 20.37 11.7 40.5 26.14 59.22 44.39a282.768 282.768 0 0 1 45.04 51.46z\"]\n};\nvar faSpaceShuttle = {\n prefix: 'fas',\n iconName: 'space-shuttle',\n icon: [640, 512, [], \"f197\", \"M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z\"]\n};\nvar faSpellCheck = {\n prefix: 'fas',\n iconName: 'spell-check',\n icon: [576, 512, [], \"f891\", \"M272 256h91.36c43.2 0 82-32.2 84.51-75.34a79.82 79.82 0 0 0-25.26-63.07 79.81 79.81 0 0 0 9.06-44.91C427.9 30.57 389.3 0 347 0h-75a16 16 0 0 0-16 16v224a16 16 0 0 0 16 16zm40-200h40a24 24 0 0 1 0 48h-40zm0 96h56a24 24 0 0 1 0 48h-56zM155.12 22.25A32 32 0 0 0 124.64 0H99.36a32 32 0 0 0-30.48 22.25L.59 235.73A16 16 0 0 0 16 256h24.93a16 16 0 0 0 15.42-11.73L68.29 208h87.42l11.94 36.27A16 16 0 0 0 183.07 256H208a16 16 0 0 0 15.42-20.27zM89.37 144L112 75.3l22.63 68.7zm482 132.48l-45.21-45.3a15.88 15.88 0 0 0-22.59 0l-151.5 151.5-55.41-55.5a15.88 15.88 0 0 0-22.59 0l-45.3 45.3a16 16 0 0 0 0 22.59l112 112.21a15.89 15.89 0 0 0 22.6 0l208-208.21a16 16 0 0 0-.02-22.59z\"]\n};\nvar faSpider = {\n prefix: 'fas',\n iconName: 'spider',\n icon: [576, 512, [], \"f717\", \"M151.17 167.35L177.1 176h4.67l5.22-26.12c.72-3.58 1.8-7.58 3.21-11.79l-20.29-40.58 23.8-71.39c2.79-8.38-1.73-17.44-10.12-20.24L168.42.82c-8.38-2.8-17.45 1.73-20.24 10.12l-25.89 77.68a32.04 32.04 0 0 0 1.73 24.43l27.15 54.3zm422.14 182.03l-52.75-79.12a32.002 32.002 0 0 0-26.62-14.25H416l68.99-24.36a32.03 32.03 0 0 0 16.51-12.61l53.6-80.41c4.9-7.35 2.91-17.29-4.44-22.19l-13.31-8.88c-7.35-4.9-17.29-2.91-22.19 4.44l-50.56 75.83L404.1 208H368l-10.37-51.85C355.44 145.18 340.26 96 288 96c-52.26 0-67.44 49.18-69.63 60.15L208 208h-36.1l-60.49-20.17L60.84 112c-4.9-7.35-14.83-9.34-22.19-4.44l-13.31 8.88c-7.35 4.9-9.34 14.83-4.44 22.19l53.6 80.41a32.03 32.03 0 0 0 16.51 12.61L160 256H82.06a32.02 32.02 0 0 0-26.63 14.25L2.69 349.38c-4.9 7.35-2.92 17.29 4.44 22.19l13.31 8.88c7.35 4.9 17.29 2.91 22.19-4.44l48-72h47.06l-60.83 97.33A31.988 31.988 0 0 0 72 418.3V496c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-73.11l74.08-118.53c-1.01 14.05-2.08 28.11-2.08 42.21C192 399.64 232.76 448 288 448s96-48.36 96-101.43c0-14.1-1.08-28.16-2.08-42.21L456 422.89V496c0 8.84 7.16 16 16 16h16c8.84 0 16-7.16 16-16v-77.71c0-6-1.69-11.88-4.86-16.96L438.31 304h47.06l48 72c4.9 7.35 14.84 9.34 22.19 4.44l13.31-8.88c7.36-4.9 9.34-14.83 4.44-22.18zM406.09 97.51l-20.29 40.58c1.41 4.21 2.49 8.21 3.21 11.79l5.22 26.12h4.67l25.93-8.65 27.15-54.3a31.995 31.995 0 0 0 1.73-24.43l-25.89-77.68C425.03 2.56 415.96-1.98 407.58.82l-15.17 5.06c-8.38 2.8-12.91 11.86-10.12 20.24l23.8 71.39z\"]\n};\nvar faSpinner = {\n prefix: 'fas',\n iconName: 'spinner',\n icon: [512, 512, [], \"f110\", \"M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z\"]\n};\nvar faSplotch = {\n prefix: 'fas',\n iconName: 'splotch',\n icon: [512, 512, [], \"f5bc\", \"M472.29 195.89l-67.06-22.95c-19.28-6.6-33.54-20.92-38.14-38.3L351.1 74.19c-11.58-43.77-76.57-57.13-109.98-22.62l-46.14 47.67c-13.26 13.71-33.54 20.93-54.2 19.31l-71.88-5.62c-52.05-4.07-86.93 44.88-59.03 82.83l38.54 52.42c11.08 15.07 12.82 33.86 4.64 50.24L24.62 355.4c-20.59 41.25 22.84 84.87 73.49 73.81l69.96-15.28c20.11-4.39 41.45 0 57.07 11.73l54.32 40.83c39.32 29.56 101.04 7.57 104.45-37.22l4.7-61.86c1.35-17.79 12.8-33.86 30.63-42.99l62-31.74c44.88-22.96 39.59-80.17-8.95-96.79z\"]\n};\nvar faSprayCan = {\n prefix: 'fas',\n iconName: 'spray-can',\n icon: [512, 512, [], \"f5bd\", \"M224 32c0-17.67-14.33-32-32-32h-64c-17.67 0-32 14.33-32 32v96h128V32zm256 96c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32zm-256 32H96c-53.02 0-96 42.98-96 96v224c0 17.67 14.33 32 32 32h256c17.67 0 32-14.33 32-32V256c0-53.02-42.98-96-96-96zm-64 256c-44.18 0-80-35.82-80-80s35.82-80 80-80 80 35.82 80 80-35.82 80-80 80zM480 96c17.67 0 32-14.33 32-32s-14.33-32-32-32-32 14.33-32 32 14.33 32 32 32zm-96 32c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32zm-96-96c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32zm96 0c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32zm96 192c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z\"]\n};\nvar faSquare = {\n prefix: 'fas',\n iconName: 'square',\n icon: [448, 512, [], \"f0c8\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"]\n};\nvar faSquareFull = {\n prefix: 'fas',\n iconName: 'square-full',\n icon: [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"]\n};\nvar faSquareRootAlt = {\n prefix: 'fas',\n iconName: 'square-root-alt',\n icon: [576, 512, [], \"f698\", \"M571.31 251.31l-22.62-22.62c-6.25-6.25-16.38-6.25-22.63 0L480 274.75l-46.06-46.06c-6.25-6.25-16.38-6.25-22.63 0l-22.62 22.62c-6.25 6.25-6.25 16.38 0 22.63L434.75 320l-46.06 46.06c-6.25 6.25-6.25 16.38 0 22.63l22.62 22.62c6.25 6.25 16.38 6.25 22.63 0L480 365.25l46.06 46.06c6.25 6.25 16.38 6.25 22.63 0l22.62-22.62c6.25-6.25 6.25-16.38 0-22.63L525.25 320l46.06-46.06c6.25-6.25 6.25-16.38 0-22.63zM552 0H307.65c-14.54 0-27.26 9.8-30.95 23.87l-84.79 322.8-58.41-106.1A32.008 32.008 0 0 0 105.47 224H24c-13.25 0-24 10.74-24 24v48c0 13.25 10.75 24 24 24h43.62l88.88 163.73C168.99 503.5 186.3 512 204.94 512c17.27 0 44.44-9 54.28-41.48L357.03 96H552c13.25 0 24-10.75 24-24V24c0-13.26-10.75-24-24-24z\"]\n};\nvar faStamp = {\n prefix: 'fas',\n iconName: 'stamp',\n icon: [512, 512, [], \"f5bf\", \"M32 512h448v-64H32v64zm384-256h-66.56c-16.26 0-29.44-13.18-29.44-29.44v-9.46c0-27.37 8.88-53.41 21.46-77.72 9.11-17.61 12.9-38.39 9.05-60.42-6.77-38.78-38.47-70.7-77.26-77.45C212.62-9.04 160 37.33 160 96c0 14.16 3.12 27.54 8.69 39.58C182.02 164.43 192 194.7 192 226.49v.07c0 16.26-13.18 29.44-29.44 29.44H96c-53.02 0-96 42.98-96 96v32c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-32c0-53.02-42.98-96-96-96z\"]\n};\nvar faStar = {\n prefix: 'fas',\n iconName: 'star',\n icon: [576, 512, [], \"f005\", \"M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z\"]\n};\nvar faStarAndCrescent = {\n prefix: 'fas',\n iconName: 'star-and-crescent',\n icon: [512, 512, [], \"f699\", \"M340.47 466.36c-1.45 0-6.89.46-9.18.46-116.25 0-210.82-94.57-210.82-210.82S215.04 45.18 331.29 45.18c2.32 0 7.7.46 9.18.46 7.13 0 13.33-5.03 14.75-12.07 1.46-7.25-2.55-14.49-9.47-17.09C316.58 5.54 286.39 0 256 0 114.84 0 0 114.84 0 256s114.84 256 256 256c30.23 0 60.28-5.49 89.32-16.32 5.96-2.02 10.28-7.64 10.28-14.26 0-8.09-6.39-15.06-15.13-15.06zm162.99-252.5l-76.38-11.1-34.16-69.21c-1.83-3.7-5.38-5.55-8.93-5.55s-7.1 1.85-8.93 5.55l-34.16 69.21-76.38 11.1c-8.17 1.18-11.43 11.22-5.52 16.99l55.27 53.87-13.05 76.07c-1.11 6.44 4.01 11.66 9.81 11.66 1.53 0 3.11-.36 4.64-1.17L384 335.37l68.31 35.91c1.53.8 3.11 1.17 4.64 1.17 5.8 0 10.92-5.23 9.81-11.66l-13.05-76.07 55.27-53.87c5.91-5.77 2.65-15.81-5.52-16.99z\"]\n};\nvar faStarHalf = {\n prefix: 'fas',\n iconName: 'star-half',\n icon: [576, 512, [], \"f089\", \"M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z\"]\n};\nvar faStarHalfAlt = {\n prefix: 'fas',\n iconName: 'star-half-alt',\n icon: [536, 512, [], \"f5c0\", \"M508.55 171.51L362.18 150.2 296.77 17.81C290.89 5.98 279.42 0 267.95 0c-11.4 0-22.79 5.9-28.69 17.81l-65.43 132.38-146.38 21.29c-26.25 3.8-36.77 36.09-17.74 54.59l105.89 103-25.06 145.48C86.98 495.33 103.57 512 122.15 512c4.93 0 10-1.17 14.87-3.75l130.95-68.68 130.94 68.7c4.86 2.55 9.92 3.71 14.83 3.71 18.6 0 35.22-16.61 31.66-37.4l-25.03-145.49 105.91-102.98c19.04-18.5 8.52-50.8-17.73-54.6zm-121.74 123.2l-18.12 17.62 4.28 24.88 19.52 113.45-102.13-53.59-22.38-11.74.03-317.19 51.03 103.29 11.18 22.63 25.01 3.64 114.23 16.63-82.65 80.38z\"]\n};\nvar faStarOfDavid = {\n prefix: 'fas',\n iconName: 'star-of-david',\n icon: [464, 512, [], \"f69a\", \"M405.68 256l53.21-89.39C473.3 142.4 455.48 112 426.88 112H319.96l-55.95-93.98C256.86 6.01 244.43 0 232 0s-24.86 6.01-32.01 18.02L144.04 112H37.11c-28.6 0-46.42 30.4-32.01 54.61L58.32 256 5.1 345.39C-9.31 369.6 8.51 400 37.11 400h106.93l55.95 93.98C207.14 505.99 219.57 512 232 512s24.86-6.01 32.01-18.02L319.96 400h106.93c28.6 0 46.42-30.4 32.01-54.61L405.68 256zm-12.78-88l-19.8 33.26L353.3 168h39.6zm-52.39 88l-52.39 88H175.88l-52.39-88 52.38-88h112.25l52.39 88zM232 73.72L254.79 112h-45.57L232 73.72zM71.1 168h39.6l-19.8 33.26L71.1 168zm0 176l19.8-33.26L110.7 344H71.1zM232 438.28L209.21 400h45.57L232 438.28zM353.29 344l19.8-33.26L392.9 344h-39.61z\"]\n};\nvar faStarOfLife = {\n prefix: 'fas',\n iconName: 'star-of-life',\n icon: [480, 512, [], \"f621\", \"M471.99 334.43L336.06 256l135.93-78.43c7.66-4.42 10.28-14.2 5.86-21.86l-32.02-55.43c-4.42-7.65-14.21-10.28-21.87-5.86l-135.93 78.43V16c0-8.84-7.17-16-16.01-16h-64.04c-8.84 0-16.01 7.16-16.01 16v156.86L56.04 94.43c-7.66-4.42-17.45-1.79-21.87 5.86L2.15 155.71c-4.42 7.65-1.8 17.44 5.86 21.86L143.94 256 8.01 334.43c-7.66 4.42-10.28 14.21-5.86 21.86l32.02 55.43c4.42 7.65 14.21 10.27 21.87 5.86l135.93-78.43V496c0 8.84 7.17 16 16.01 16h64.04c8.84 0 16.01-7.16 16.01-16V339.14l135.93 78.43c7.66 4.42 17.45 1.8 21.87-5.86l32.02-55.43c4.42-7.65 1.8-17.43-5.86-21.85z\"]\n};\nvar faStepBackward = {\n prefix: 'fas',\n iconName: 'step-backward',\n icon: [448, 512, [], \"f048\", \"M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z\"]\n};\nvar faStepForward = {\n prefix: 'fas',\n iconName: 'step-forward',\n icon: [448, 512, [], \"f051\", \"M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z\"]\n};\nvar faStethoscope = {\n prefix: 'fas',\n iconName: 'stethoscope',\n icon: [512, 512, [], \"f0f1\", \"M447.1 112c-34.2.5-62.3 28.4-63 62.6-.5 24.3 12.5 45.6 32 56.8V344c0 57.3-50.2 104-112 104-60 0-109.2-44.1-111.9-99.2C265 333.8 320 269.2 320 192V36.6c0-11.4-8.1-21.3-19.3-23.5L237.8.5c-13-2.6-25.6 5.8-28.2 18.8L206.4 35c-2.6 13 5.8 25.6 18.8 28.2l30.7 6.1v121.4c0 52.9-42.2 96.7-95.1 97.2-53.4.5-96.9-42.7-96.9-96V69.4l30.7-6.1c13-2.6 21.4-15.2 18.8-28.2l-3.1-15.7C107.7 6.4 95.1-2 82.1.6L19.3 13C8.1 15.3 0 25.1 0 36.6V192c0 77.3 55.1 142 128.1 156.8C130.7 439.2 208.6 512 304 512c97 0 176-75.4 176-168V231.4c19.1-11.1 32-31.7 32-55.4 0-35.7-29.2-64.5-64.9-64zm.9 80c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16z\"]\n};\nvar faStickyNote = {\n prefix: 'fas',\n iconName: 'sticky-note',\n icon: [448, 512, [], \"f249\", \"M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z\"]\n};\nvar faStop = {\n prefix: 'fas',\n iconName: 'stop',\n icon: [448, 512, [], \"f04d\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"]\n};\nvar faStopCircle = {\n prefix: 'fas',\n iconName: 'stop-circle',\n icon: [512, 512, [], \"f28d\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z\"]\n};\nvar faStopwatch = {\n prefix: 'fas',\n iconName: 'stopwatch',\n icon: [448, 512, [], \"f2f2\", \"M432 304c0 114.9-93.1 208-208 208S16 418.9 16 304c0-104 76.3-190.2 176-205.5V64h-28c-6.6 0-12-5.4-12-12V12c0-6.6 5.4-12 12-12h120c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-28v34.5c37.5 5.8 71.7 21.6 99.7 44.6l27.5-27.5c4.7-4.7 12.3-4.7 17 0l28.3 28.3c4.7 4.7 4.7 12.3 0 17l-29.4 29.4-.6.6C419.7 223.3 432 262.2 432 304zm-176 36V188.5c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12V340c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z\"]\n};\nvar faStore = {\n prefix: 'fas',\n iconName: 'store',\n icon: [616, 512, [], \"f54e\", \"M602 118.6L537.1 15C531.3 5.7 521 0 510 0H106C95 0 84.7 5.7 78.9 15L14 118.6c-33.5 53.5-3.8 127.9 58.8 136.4 4.5.6 9.1.9 13.7.9 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18 20.1 44.3 33.1 73.8 33.1 29.6 0 55.8-13 73.8-33.1 18.1 20.1 44.3 33.1 73.8 33.1 4.7 0 9.2-.3 13.7-.9 62.8-8.4 92.6-82.8 59-136.4zM529.5 288c-10 0-19.9-1.5-29.5-3.8V384H116v-99.8c-9.6 2.2-19.5 3.8-29.5 3.8-6 0-12.1-.4-18-1.2-5.6-.8-11.1-2.1-16.4-3.6V480c0 17.7 14.3 32 32 32h448c17.7 0 32-14.3 32-32V283.2c-5.4 1.6-10.8 2.9-16.4 3.6-6.1.8-12.1 1.2-18.2 1.2z\"]\n};\nvar faStoreAlt = {\n prefix: 'fas',\n iconName: 'store-alt',\n icon: [640, 512, [], \"f54f\", \"M320 384H128V224H64v256c0 17.7 14.3 32 32 32h256c17.7 0 32-14.3 32-32V224h-64v160zm314.6-241.8l-85.3-128c-6-8.9-16-14.2-26.7-14.2H117.4c-10.7 0-20.7 5.3-26.6 14.2l-85.3 128c-14.2 21.3 1 49.8 26.6 49.8H608c25.5 0 40.7-28.5 26.6-49.8zM512 496c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V224h-64v272z\"]\n};\nvar faStream = {\n prefix: 'fas',\n iconName: 'stream',\n icon: [512, 512, [], \"f550\", \"M16 128h416c8.84 0 16-7.16 16-16V48c0-8.84-7.16-16-16-16H16C7.16 32 0 39.16 0 48v64c0 8.84 7.16 16 16 16zm480 80H80c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16zm-64 176H16c-8.84 0-16 7.16-16 16v64c0 8.84 7.16 16 16 16h416c8.84 0 16-7.16 16-16v-64c0-8.84-7.16-16-16-16z\"]\n};\nvar faStreetView = {\n prefix: 'fas',\n iconName: 'street-view',\n icon: [512, 512, [], \"f21d\", \"M367.9 329.76c-4.62 5.3-9.78 10.1-15.9 13.65v22.94c66.52 9.34 112 28.05 112 49.65 0 30.93-93.12 56-208 56S48 446.93 48 416c0-21.6 45.48-40.3 112-49.65v-22.94c-6.12-3.55-11.28-8.35-15.9-13.65C58.87 345.34 0 378.05 0 416c0 53.02 114.62 96 256 96s256-42.98 256-96c0-37.95-58.87-70.66-144.1-86.24zM256 128c35.35 0 64-28.65 64-64S291.35 0 256 0s-64 28.65-64 64 28.65 64 64 64zm-64 192v96c0 17.67 14.33 32 32 32h64c17.67 0 32-14.33 32-32v-96c17.67 0 32-14.33 32-32v-96c0-26.51-21.49-48-48-48h-11.8c-11.07 5.03-23.26 8-36.2 8s-25.13-2.97-36.2-8H208c-26.51 0-48 21.49-48 48v96c0 17.67 14.33 32 32 32z\"]\n};\nvar faStrikethrough = {\n prefix: 'fas',\n iconName: 'strikethrough',\n icon: [512, 512, [], \"f0cc\", \"M496 224H293.9l-87.17-26.83A43.55 43.55 0 0 1 219.55 112h66.79A49.89 49.89 0 0 1 331 139.58a16 16 0 0 0 21.46 7.15l42.94-21.47a16 16 0 0 0 7.16-21.46l-.53-1A128 128 0 0 0 287.51 32h-68a123.68 123.68 0 0 0-123 135.64c2 20.89 10.1 39.83 21.78 56.36H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h480a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-180.24 96A43 43 0 0 1 336 356.45 43.59 43.59 0 0 1 292.45 400h-66.79A49.89 49.89 0 0 1 181 372.42a16 16 0 0 0-21.46-7.15l-42.94 21.47a16 16 0 0 0-7.16 21.46l.53 1A128 128 0 0 0 224.49 480h68a123.68 123.68 0 0 0 123-135.64 114.25 114.25 0 0 0-5.34-24.36z\"]\n};\nvar faStroopwafel = {\n prefix: 'fas',\n iconName: 'stroopwafel',\n icon: [512, 512, [], \"f551\", \"M188.12 210.74L142.86 256l45.25 45.25L233.37 256l-45.25-45.26zm113.13-22.62L256 142.86l-45.25 45.25L256 233.37l45.25-45.25zm-90.5 135.76L256 369.14l45.26-45.26L256 278.63l-45.25 45.25zM256 0C114.62 0 0 114.62 0 256s114.62 256 256 256 256-114.62 256-256S397.38 0 256 0zm186.68 295.6l-11.31 11.31c-3.12 3.12-8.19 3.12-11.31 0l-28.29-28.29-45.25 45.25 33.94 33.94 16.97-16.97c3.12-3.12 8.19-3.12 11.31 0l11.31 11.31c3.12 3.12 3.12 8.19 0 11.31l-16.97 16.97 16.97 16.97c3.12 3.12 3.12 8.19 0 11.31l-11.31 11.31c-3.12 3.12-8.19 3.12-11.31 0l-16.97-16.97-16.97 16.97c-3.12 3.12-8.19 3.12-11.31 0l-11.31-11.31c-3.12-3.12-3.12-8.19 0-11.31l16.97-16.97-33.94-33.94-45.26 45.26 28.29 28.29c3.12 3.12 3.12 8.19 0 11.31l-11.31 11.31c-3.12 3.12-8.19 3.12-11.31 0L256 414.39l-28.29 28.29c-3.12 3.12-8.19 3.12-11.31 0l-11.31-11.31c-3.12-3.12-3.12-8.19 0-11.31l28.29-28.29-45.25-45.26-33.94 33.94 16.97 16.97c3.12 3.12 3.12 8.19 0 11.31l-11.31 11.31c-3.12 3.12-8.19 3.12-11.31 0l-16.97-16.97-16.97 16.97c-3.12 3.12-8.19 3.12-11.31 0l-11.31-11.31c-3.12-3.12-3.12-8.19 0-11.31l16.97-16.97-16.97-16.97c-3.12-3.12-3.12-8.19 0-11.31l11.31-11.31c3.12-3.12 8.19-3.12 11.31 0l16.97 16.97 33.94-33.94-45.25-45.25-28.29 28.29c-3.12 3.12-8.19 3.12-11.31 0L69.32 295.6c-3.12-3.12-3.12-8.19 0-11.31L97.61 256l-28.29-28.29c-3.12-3.12-3.12-8.19 0-11.31l11.31-11.31c3.12-3.12 8.19-3.12 11.31 0l28.29 28.29 45.25-45.26-33.94-33.94-16.97 16.97c-3.12 3.12-8.19 3.12-11.31 0l-11.31-11.31c-3.12-3.12-3.12-8.19 0-11.31l16.97-16.97-16.97-16.97c-3.12-3.12-3.12-8.19 0-11.31l11.31-11.31c3.12-3.12 8.19-3.12 11.31 0l16.97 16.97 16.97-16.97c3.12-3.12 8.19-3.12 11.31 0l11.31 11.31c3.12 3.12 3.12 8.19 0 11.31l-16.97 16.97 33.94 33.94 45.26-45.25-28.29-28.29c-3.12-3.12-3.12-8.19 0-11.31l11.31-11.31c3.12-3.12 8.19-3.12 11.31 0L256 97.61l28.29-28.29c3.12-3.12 8.19-3.12 11.31 0l11.31 11.31c3.12 3.12 3.12 8.19 0 11.31l-28.29 28.29 45.26 45.25 33.94-33.94-16.97-16.97c-3.12-3.12-3.12-8.19 0-11.31l11.31-11.31c3.12-3.12 8.19-3.12 11.31 0l16.97 16.97 16.97-16.97c3.12-3.12 8.19-3.12 11.31 0l11.31 11.31c3.12 3.12 3.12 8.19 0 11.31l-16.97 16.97 16.97 16.97c3.12 3.12 3.12 8.19 0 11.31l-11.31 11.31c-3.12 3.12-8.19 3.12-11.31 0l-16.97-16.97-33.94 33.94 45.25 45.26 28.29-28.29c3.12-3.12 8.19-3.12 11.31 0l11.31 11.31c3.12 3.12 3.12 8.19 0 11.31L414.39 256l28.29 28.28a8.015 8.015 0 0 1 0 11.32zM278.63 256l45.26 45.25L369.14 256l-45.25-45.26L278.63 256z\"]\n};\nvar faSubscript = {\n prefix: 'fas',\n iconName: 'subscript',\n icon: [512, 512, [], \"f12c\", \"M496 448h-16V304a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 400 352h16v96h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM336 64h-67a16 16 0 0 0-13.14 6.87l-79.9 115-79.9-115A16 16 0 0 0 83 64H16A16 16 0 0 0 0 80v48a16 16 0 0 0 16 16h33.48l77.81 112-77.81 112H16a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h67a16 16 0 0 0 13.14-6.87l79.9-115 79.9 115A16 16 0 0 0 269 448h67a16 16 0 0 0 16-16v-48a16 16 0 0 0-16-16h-33.48l-77.81-112 77.81-112H336a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16z\"]\n};\nvar faSubway = {\n prefix: 'fas',\n iconName: 'subway',\n icon: [448, 512, [], \"f239\", \"M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z\"]\n};\nvar faSuitcase = {\n prefix: 'fas',\n iconName: 'suitcase',\n icon: [512, 512, [], \"f0f2\", \"M128 480h256V80c0-26.5-21.5-48-48-48H176c-26.5 0-48 21.5-48 48v400zm64-384h128v32H192V96zm320 80v256c0 26.5-21.5 48-48 48h-48V128h48c26.5 0 48 21.5 48 48zM96 480H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h48v352z\"]\n};\nvar faSuitcaseRolling = {\n prefix: 'fas',\n iconName: 'suitcase-rolling',\n icon: [384, 512, [], \"f5c1\", \"M336 160H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h16v16c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-16h128v16c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-16h16c26.51 0 48-21.49 48-48V208c0-26.51-21.49-48-48-48zm-16 216c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h240c4.42 0 8 3.58 8 8v16zm0-96c0 4.42-3.58 8-8 8H72c-4.42 0-8-3.58-8-8v-16c0-4.42 3.58-8 8-8h240c4.42 0 8 3.58 8 8v16zM144 48h96v80h48V48c0-26.51-21.49-48-48-48h-96c-26.51 0-48 21.49-48 48v80h48V48z\"]\n};\nvar faSun = {\n prefix: 'fas',\n iconName: 'sun',\n icon: [512, 512, [], \"f185\", \"M256 160c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm246.4 80.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.4-94.8c-6.4-12.8-24.6-12.8-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4c-12.8 6.4-12.8 24.6 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.4-33.5 47.3 94.7c6.4 12.8 24.6 12.8 31 0l47.3-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3c13-6.5 13-24.7.2-31.1zm-155.9 106c-49.9 49.9-131.1 49.9-181 0-49.9-49.9-49.9-131.1 0-181 49.9-49.9 131.1-49.9 181 0 49.9 49.9 49.9 131.1 0 181z\"]\n};\nvar faSuperscript = {\n prefix: 'fas',\n iconName: 'superscript',\n icon: [512, 512, [], \"f12b\", \"M496 160h-16V16a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 400 64h16v96h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM336 64h-67a16 16 0 0 0-13.14 6.87l-79.9 115-79.9-115A16 16 0 0 0 83 64H16A16 16 0 0 0 0 80v48a16 16 0 0 0 16 16h33.48l77.81 112-77.81 112H16a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h67a16 16 0 0 0 13.14-6.87l79.9-115 79.9 115A16 16 0 0 0 269 448h67a16 16 0 0 0 16-16v-48a16 16 0 0 0-16-16h-33.48l-77.81-112 77.81-112H336a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16z\"]\n};\nvar faSurprise = {\n prefix: 'fas',\n iconName: 'surprise',\n icon: [496, 512, [], \"f5c2\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zM136 208c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm112 208c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm80-176c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faSwatchbook = {\n prefix: 'fas',\n iconName: 'swatchbook',\n icon: [511, 512, [], \"f5c3\", \"M479.06 320H372.29L186.15 506.51c-2.06 2.07-4.49 3.58-6.67 5.49h299.58c17.64 0 31.94-14.33 31.94-32V352c0-17.67-14.3-32-31.94-32zm-44.5-152.9l-90.33-90.51c-12.47-12.5-32.69-12.5-45.17 0l-75.5 75.65V416c0 2.96-.67 5.73-.87 8.64l211.87-212.28c12.47-12.5 12.47-32.77 0-45.26zM191.62 32c0-17.67-14.3-32-31.94-32H31.94C14.3 0 0 14.33 0 32v384c0 53.02 42.9 96 95.81 96s95.81-42.98 95.81-96V32zM95.81 440c-13.23 0-23.95-10.75-23.95-24 0-13.26 10.73-24 23.95-24s23.95 10.74 23.95 24c.01 13.25-10.72 24-23.95 24zm31.94-184H63.88v-64h63.88v64zm0-128H63.88V64h63.88v64z\"]\n};\nvar faSwimmer = {\n prefix: 'fas',\n iconName: 'swimmer',\n icon: [640, 512, [], \"f5c4\", \"M189.61 310.58c3.54 3.26 15.27 9.42 34.39 9.42s30.86-6.16 34.39-9.42c16.02-14.77 34.5-22.58 53.46-22.58h16.3c18.96 0 37.45 7.81 53.46 22.58 3.54 3.26 15.27 9.42 34.39 9.42s30.86-6.16 34.39-9.42c14.86-13.71 31.88-21.12 49.39-22.16l-112.84-80.6 18-12.86c3.64-2.58 8.28-3.52 12.62-2.61l100.35 21.53c25.91 5.53 51.44-10.97 57-36.88 5.55-25.92-10.95-51.44-36.88-57L437.68 98.47c-30.73-6.58-63.02.12-88.56 18.38l-80.02 57.17c-10.38 7.39-19.36 16.44-26.72 26.94L173.75 299c5.47 3.23 10.82 6.93 15.86 11.58zM624 352h-16c-26.04 0-45.8-8.42-56.09-17.9-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C461.8 343.58 442.04 352 416 352s-45.8-8.42-56.09-17.9c-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C269.8 343.58 250.04 352 224 352s-45.8-8.42-56.09-17.9c-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C77.8 343.58 58.04 352 32 352H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h16c38.62 0 72.72-12.19 96-31.84 23.28 19.66 57.38 31.84 96 31.84s72.72-12.19 96-31.84c23.28 19.66 57.38 31.84 96 31.84s72.72-12.19 96-31.84c23.28 19.66 57.38 31.84 96 31.84h16c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-512-96c44.18 0 80-35.82 80-80s-35.82-80-80-80-80 35.82-80 80 35.82 80 80 80z\"]\n};\nvar faSwimmingPool = {\n prefix: 'fas',\n iconName: 'swimming-pool',\n icon: [640, 512, [], \"f5c5\", \"M624 416h-16c-26.04 0-45.8-8.42-56.09-17.9-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C461.8 407.58 442.04 416 416 416s-45.8-8.42-56.09-17.9c-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C269.8 407.58 250.04 416 224 416s-45.8-8.42-56.09-17.9c-8.9-8.21-19.66-14.1-31.77-14.1h-16.3c-12.11 0-22.87 5.89-31.77 14.1C77.8 407.58 58.04 416 32 416H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h16c38.62 0 72.72-12.19 96-31.84 23.28 19.66 57.38 31.84 96 31.84s72.72-12.19 96-31.84c23.28 19.66 57.38 31.84 96 31.84s72.72-12.19 96-31.84c23.28 19.66 57.38 31.84 96 31.84h16c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-400-32v-96h192v96c19.12 0 30.86-6.16 34.39-9.42 9.17-8.46 19.2-14.34 29.61-18.07V128c0-17.64 14.36-32 32-32s32 14.36 32 32v16c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-16c0-52.94-43.06-96-96-96s-96 43.06-96 96v96H224v-96c0-17.64 14.36-32 32-32s32 14.36 32 32v16c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-16c0-52.94-43.06-96-96-96s-96 43.06-96 96v228.5c10.41 3.73 20.44 9.62 29.61 18.07 3.53 3.27 15.27 9.43 34.39 9.43z\"]\n};\nvar faSynagogue = {\n prefix: 'fas',\n iconName: 'synagogue',\n icon: [640, 512, [], \"f69b\", \"M70 196.51L6.67 268.29A26.643 26.643 0 0 0 0 285.93V512h128V239.58l-38-43.07c-5.31-6.01-14.69-6.01-20 0zm563.33 71.78L570 196.51c-5.31-6.02-14.69-6.02-20 0l-38 43.07V512h128V285.93c0-6.5-2.37-12.77-6.67-17.64zM339.99 7.01c-11.69-9.35-28.29-9.35-39.98 0l-128 102.4A32.005 32.005 0 0 0 160 134.4V512h96v-92.57c0-31.88 21.78-61.43 53.25-66.55C349.34 346.35 384 377.13 384 416v96h96V134.4c0-9.72-4.42-18.92-12.01-24.99l-128-102.4zm52.07 215.55c1.98 3.15-.29 7.24-4 7.24h-38.94L324 269.79c-1.85 2.95-6.15 2.95-8 0l-25.12-39.98h-38.94c-3.72 0-5.98-4.09-4-7.24l19.2-30.56-19.2-30.56c-1.98-3.15.29-7.24 4-7.24h38.94l25.12-40c1.85-2.95 6.15-2.95 8 0l25.12 39.98h38.95c3.71 0 5.98 4.09 4 7.24L372.87 192l19.19 30.56z\"]\n};\nvar faSync = {\n prefix: 'fas',\n iconName: 'sync',\n icon: [512, 512, [], \"f021\", \"M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z\"]\n};\nvar faSyncAlt = {\n prefix: 'fas',\n iconName: 'sync-alt',\n icon: [512, 512, [], \"f2f1\", \"M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z\"]\n};\nvar faSyringe = {\n prefix: 'fas',\n iconName: 'syringe',\n icon: [512, 512, [], \"f48e\", \"M201.5 174.8l55.7 55.8c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-55.7-55.8-45.3 45.3 55.8 55.8c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L111 265.2l-26.4 26.4c-17.3 17.3-25.6 41.1-23 65.4l7.1 63.6L2.3 487c-3.1 3.1-3.1 8.2 0 11.3l11.3 11.3c3.1 3.1 8.2 3.1 11.3 0l66.3-66.3 63.6 7.1c23.9 2.6 47.9-5.4 65.4-23l181.9-181.9-135.7-135.7-64.9 65zm308.2-93.3L430.5 2.3c-3.1-3.1-8.2-3.1-11.3 0l-11.3 11.3c-3.1 3.1-3.1 8.2 0 11.3l28.3 28.3-45.3 45.3-56.6-56.6-17-17c-3.1-3.1-8.2-3.1-11.3 0l-33.9 33.9c-3.1 3.1-3.1 8.2 0 11.3l17 17L424.8 223l17 17c3.1 3.1 8.2 3.1 11.3 0l33.9-34c3.1-3.1 3.1-8.2 0-11.3l-73.5-73.5 45.3-45.3 28.3 28.3c3.1 3.1 8.2 3.1 11.3 0l11.3-11.3c3.1-3.2 3.1-8.2 0-11.4z\"]\n};\nvar faTable = {\n prefix: 'fas',\n iconName: 'table',\n icon: [512, 512, [], \"f0ce\", \"M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z\"]\n};\nvar faTableTennis = {\n prefix: 'fas',\n iconName: 'table-tennis',\n icon: [512, 512, [], \"f45d\", \"M496.2 296.5C527.7 218.7 512 126.2 449 63.1 365.1-21 229-21 145.1 63.1l-56 56.1 211.5 211.5c46.1-62.1 131.5-77.4 195.6-34.2zm-217.9 79.7L57.9 155.9c-27.3 45.3-21.7 105 17.3 144.1l34.5 34.6L6.7 424c-8.6 7.5-9.1 20.7-1 28.8l53.4 53.5c8 8.1 21.2 7.6 28.7-1L177.1 402l35.7 35.7c19.7 19.7 44.6 30.5 70.3 33.3-7.1-17-11-35.6-11-55.1-.1-13.8 2.5-27 6.2-39.7zM416 320c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z\"]\n};\nvar faTablet = {\n prefix: 'fas',\n iconName: 'tablet',\n icon: [448, 512, [], \"f10a\", \"M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"]\n};\nvar faTabletAlt = {\n prefix: 'fas',\n iconName: 'tablet-alt',\n icon: [448, 512, [], \"f3fa\", \"M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z\"]\n};\nvar faTablets = {\n prefix: 'fas',\n iconName: 'tablets',\n icon: [640, 512, [], \"f490\", \"M160 192C78.9 192 12.5 250.5.1 326.7c-.8 4.8 3.3 9.3 8.3 9.3h303.3c5 0 9.1-4.5 8.3-9.3C307.5 250.5 241.1 192 160 192zm151.6 176H8.4c-5 0-9.1 4.5-8.3 9.3C12.5 453.5 78.9 512 160 512s147.5-58.5 159.9-134.7c.8-4.8-3.3-9.3-8.3-9.3zM593.4 46.6c-56.5-56.5-144.2-61.4-206.9-16-4 2.9-4.3 8.9-.8 12.3L597 254.3c3.5 3.5 9.5 3.2 12.3-.8 45.5-62.7 40.6-150.4-15.9-206.9zM363 65.7c-3.5-3.5-9.5-3.2-12.3.8-45.4 62.7-40.5 150.4 15.9 206.9 56.5 56.5 144.2 61.4 206.9 15.9 4-2.9 4.3-8.9.8-12.3L363 65.7z\"]\n};\nvar faTachometerAlt = {\n prefix: 'fas',\n iconName: 'tachometer-alt',\n icon: [576, 512, [], \"f3fd\", \"M288 32C128.94 32 0 160.94 0 320c0 52.8 14.25 102.26 39.06 144.8 5.61 9.62 16.3 15.2 27.44 15.2h443c11.14 0 21.83-5.58 27.44-15.2C561.75 422.26 576 372.8 576 320c0-159.06-128.94-288-288-288zm0 64c14.71 0 26.58 10.13 30.32 23.65-1.11 2.26-2.64 4.23-3.45 6.67l-9.22 27.67c-5.13 3.49-10.97 6.01-17.64 6.01-17.67 0-32-14.33-32-32S270.33 96 288 96zM96 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm48-160c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm246.77-72.41l-61.33 184C343.13 347.33 352 364.54 352 384c0 11.72-3.38 22.55-8.88 32H232.88c-5.5-9.45-8.88-20.28-8.88-32 0-33.94 26.5-61.43 59.9-63.59l61.34-184.01c4.17-12.56 17.73-19.45 30.36-15.17 12.57 4.19 19.35 17.79 15.17 30.36zm14.66 57.2l15.52-46.55c3.47-1.29 7.13-2.23 11.05-2.23 17.67 0 32 14.33 32 32s-14.33 32-32 32c-11.38-.01-20.89-6.28-26.57-15.22zM480 384c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faTag = {\n prefix: 'fas',\n iconName: 'tag',\n icon: [512, 512, [], \"f02b\", \"M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z\"]\n};\nvar faTags = {\n prefix: 'fas',\n iconName: 'tags',\n icon: [640, 512, [], \"f02c\", \"M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z\"]\n};\nvar faTape = {\n prefix: 'fas',\n iconName: 'tape',\n icon: [640, 512, [], \"f4db\", \"M224 192c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64zm400 224H380.6c41.5-40.7 67.4-97.3 67.4-160 0-123.7-100.3-224-224-224S0 132.3 0 256s100.3 224 224 224h400c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400-64c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96z\"]\n};\nvar faTasks = {\n prefix: 'fas',\n iconName: 'tasks',\n icon: [512, 512, [], \"f0ae\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96zm432 16H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faTaxi = {\n prefix: 'fas',\n iconName: 'taxi',\n icon: [512, 512, [], \"f1ba\", \"M462 241.64l-22-84.84c-9.6-35.2-41.6-60.8-76.8-60.8H352V64c0-17.67-14.33-32-32-32H192c-17.67 0-32 14.33-32 32v32h-11.2c-35.2 0-67.2 25.6-76.8 60.8l-22 84.84C21.41 248.04 0 273.47 0 304v48c0 23.63 12.95 44.04 32 55.12V448c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-40.88c19.05-11.09 32-31.5 32-55.12v-48c0-30.53-21.41-55.96-50-62.36zM96 352c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm20.55-112l17.2-66.36c2.23-8.16 9.59-13.64 15.06-13.64h214.4c5.47 0 12.83 5.48 14.85 12.86L395.45 240h-278.9zM416 352c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faTeeth = {\n prefix: 'fas',\n iconName: 'teeth',\n icon: [640, 512, [], \"f62e\", \"M544 0H96C42.98 0 0 42.98 0 96v320c0 53.02 42.98 96 96 96h448c53.02 0 96-42.98 96-96V96c0-53.02-42.98-96-96-96zM160 368c0 26.51-21.49 48-48 48s-48-21.49-48-48v-64c0-8.84 7.16-16 16-16h64c8.84 0 16 7.16 16 16v64zm0-128c0 8.84-7.16 16-16 16H80c-8.84 0-16-7.16-16-16v-64c0-26.51 21.49-48 48-48s48 21.49 48 48v64zm144 120c0 30.93-25.07 56-56 56s-56-25.07-56-56v-56c0-8.84 7.16-16 16-16h80c8.84 0 16 7.16 16 16v56zm0-120c0 8.84-7.16 16-16 16h-80c-8.84 0-16-7.16-16-16v-88c0-30.93 25.07-56 56-56s56 25.07 56 56v88zm144 120c0 30.93-25.07 56-56 56s-56-25.07-56-56v-56c0-8.84 7.16-16 16-16h80c8.84 0 16 7.16 16 16v56zm0-120c0 8.84-7.16 16-16 16h-80c-8.84 0-16-7.16-16-16v-88c0-30.93 25.07-56 56-56s56 25.07 56 56v88zm128 128c0 26.51-21.49 48-48 48s-48-21.49-48-48v-64c0-8.84 7.16-16 16-16h64c8.84 0 16 7.16 16 16v64zm0-128c0 8.84-7.16 16-16 16h-64c-8.84 0-16-7.16-16-16v-64c0-26.51 21.49-48 48-48s48 21.49 48 48v64z\"]\n};\nvar faTeethOpen = {\n prefix: 'fas',\n iconName: 'teeth-open',\n icon: [640, 512, [], \"f62f\", \"M544 0H96C42.98 0 0 42.98 0 96v64c0 35.35 28.66 64 64 64h512c35.34 0 64-28.65 64-64V96c0-53.02-42.98-96-96-96zM160 176c0 8.84-7.16 16-16 16H80c-8.84 0-16-7.16-16-16v-32c0-26.51 21.49-48 48-48s48 21.49 48 48v32zm144 0c0 8.84-7.16 16-16 16h-80c-8.84 0-16-7.16-16-16v-56c0-30.93 25.07-56 56-56s56 25.07 56 56v56zm144 0c0 8.84-7.16 16-16 16h-80c-8.84 0-16-7.16-16-16v-56c0-30.93 25.07-56 56-56s56 25.07 56 56v56zm128 0c0 8.84-7.16 16-16 16h-64c-8.84 0-16-7.16-16-16v-32c0-26.51 21.49-48 48-48s48 21.49 48 48v32zm0 144H64c-35.34 0-64 28.65-64 64v32c0 53.02 42.98 96 96 96h448c53.02 0 96-42.98 96-96v-32c0-35.35-28.66-64-64-64zm-416 80c0 26.51-21.49 48-48 48s-48-21.49-48-48v-32c0-8.84 7.16-16 16-16h64c8.84 0 16 7.16 16 16v32zm144-8c0 30.93-25.07 56-56 56s-56-25.07-56-56v-24c0-8.84 7.16-16 16-16h80c8.84 0 16 7.16 16 16v24zm144 0c0 30.93-25.07 56-56 56s-56-25.07-56-56v-24c0-8.84 7.16-16 16-16h80c8.84 0 16 7.16 16 16v24zm128 8c0 26.51-21.49 48-48 48s-48-21.49-48-48v-32c0-8.84 7.16-16 16-16h64c8.84 0 16 7.16 16 16v32z\"]\n};\nvar faTemperatureHigh = {\n prefix: 'fas',\n iconName: 'temperature-high',\n icon: [512, 512, [], \"f769\", \"M416 0c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm0 128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm-160-16C256 50.1 205.9 0 144 0S32 50.1 32 112v166.5C12.3 303.2 0 334 0 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-34-12.3-64.9-32-89.5V112zM144 448c-44.1 0-80-35.9-80-80 0-25.5 12.2-48.9 32-63.8V112c0-26.5 21.5-48 48-48s48 21.5 48 48v192.2c19.8 14.8 32 38.3 32 63.8 0 44.1-35.9 80-80 80zm16-125.1V112c0-8.8-7.2-16-16-16s-16 7.2-16 16v210.9c-18.6 6.6-32 24.2-32 45.1 0 26.5 21.5 48 48 48s48-21.5 48-48c0-20.9-13.4-38.5-32-45.1z\"]\n};\nvar faTemperatureLow = {\n prefix: 'fas',\n iconName: 'temperature-low',\n icon: [512, 512, [], \"f76b\", \"M416 0c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm0 128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm-160-16C256 50.1 205.9 0 144 0S32 50.1 32 112v166.5C12.3 303.2 0 334 0 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-34-12.3-64.9-32-89.5V112zM144 448c-44.1 0-80-35.9-80-80 0-25.5 12.2-48.9 32-63.8V112c0-26.5 21.5-48 48-48s48 21.5 48 48v192.2c19.8 14.8 32 38.3 32 63.8 0 44.1-35.9 80-80 80zm16-125.1V304c0-8.8-7.2-16-16-16s-16 7.2-16 16v18.9c-18.6 6.6-32 24.2-32 45.1 0 26.5 21.5 48 48 48s48-21.5 48-48c0-20.9-13.4-38.5-32-45.1z\"]\n};\nvar faTenge = {\n prefix: 'fas',\n iconName: 'tenge',\n icon: [384, 512, [], \"f7d7\", \"M372 160H12c-6.6 0-12 5.4-12 12v56c0 6.6 5.4 12 12 12h140v228c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V240h140c6.6 0 12-5.4 12-12v-56c0-6.6-5.4-12-12-12zm0-128H12C5.4 32 0 37.4 0 44v56c0 6.6 5.4 12 12 12h360c6.6 0 12-5.4 12-12V44c0-6.6-5.4-12-12-12z\"]\n};\nvar faTerminal = {\n prefix: 'fas',\n iconName: 'terminal',\n icon: [640, 512, [], \"f120\", \"M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z\"]\n};\nvar faTextHeight = {\n prefix: 'fas',\n iconName: 'text-height',\n icon: [576, 512, [], \"f034\", \"M304 32H16A16 16 0 0 0 0 48v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-32h56v304H80a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-40V112h56v32a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm256 336h-48V144h48c14.31 0 21.33-17.31 11.31-27.31l-80-80a16 16 0 0 0-22.62 0l-80 80C379.36 126 384.36 144 400 144h48v224h-48c-14.31 0-21.32 17.31-11.31 27.31l80 80a16 16 0 0 0 22.62 0l80-80C580.64 386 575.64 368 560 368z\"]\n};\nvar faTextWidth = {\n prefix: 'fas',\n iconName: 'text-width',\n icon: [448, 512, [], \"f035\", \"M432 32H16A16 16 0 0 0 0 48v80a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-16h120v112h-24a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-24V112h120v16a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-68.69 260.69C354 283.36 336 288.36 336 304v48H112v-48c0-14.31-17.31-21.32-27.31-11.31l-80 80a16 16 0 0 0 0 22.62l80 80C94 484.64 112 479.64 112 464v-48h224v48c0 14.31 17.31 21.33 27.31 11.31l80-80a16 16 0 0 0 0-22.62z\"]\n};\nvar faTh = {\n prefix: 'fas',\n iconName: 'th',\n icon: [512, 512, [], \"f00a\", \"M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z\"]\n};\nvar faThLarge = {\n prefix: 'fas',\n iconName: 'th-large',\n icon: [512, 512, [], \"f009\", \"M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z\"]\n};\nvar faThList = {\n prefix: 'fas',\n iconName: 'th-list',\n icon: [512, 512, [], \"f00b\", \"M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z\"]\n};\nvar faTheaterMasks = {\n prefix: 'fas',\n iconName: 'theater-masks',\n icon: [640, 512, [], \"f630\", \"M206.86 245.15c-35.88 10.45-59.95 41.2-57.53 74.1 11.4-12.72 28.81-23.7 49.9-30.92l7.63-43.18zM95.81 295L64.08 115.49c-.29-1.62.28-2.62.24-2.65 57.76-32.06 123.12-49.01 189.01-49.01 1.61 0 3.23.17 4.85.19 13.95-13.47 31.73-22.83 51.59-26 18.89-3.02 38.05-4.55 57.18-5.32-9.99-13.95-24.48-24.23-41.77-27C301.27 1.89 277.24 0 253.32 0 176.66 0 101.02 19.42 33.2 57.06 9.03 70.48-3.92 98.48 1.05 126.58l31.73 179.51c14.23 80.52 136.33 142.08 204.45 142.08 3.59 0 6.75-.46 10.01-.8-13.52-17.08-28.94-40.48-39.5-67.58-47.61-12.98-106.06-51.62-111.93-84.79zm97.55-137.46c-.73-4.12-2.23-7.87-4.07-11.4-8.25 8.91-20.67 15.75-35.32 18.32-14.65 2.58-28.67.4-39.48-5.17-.52 3.94-.64 7.98.09 12.1 3.84 21.7 24.58 36.19 46.34 32.37 21.75-3.82 36.28-24.52 32.44-46.22zM606.8 120.9c-88.98-49.38-191.43-67.41-291.98-51.35-27.31 4.36-49.08 26.26-54.04 54.36l-31.73 179.51c-15.39 87.05 95.28 196.27 158.31 207.35 63.03 11.09 204.47-53.79 219.86-140.84l31.73-179.51c4.97-28.11-7.98-56.11-32.15-69.52zm-273.24 96.8c3.84-21.7 24.58-36.19 46.34-32.36 21.76 3.83 36.28 24.52 32.45 46.22-.73 4.12-2.23 7.87-4.07 11.4-8.25-8.91-20.67-15.75-35.32-18.32-14.65-2.58-28.67-.4-39.48 5.17-.53-3.95-.65-7.99.08-12.11zm70.47 198.76c-55.68-9.79-93.52-59.27-89.04-112.9 20.6 25.54 56.21 46.17 99.49 53.78 43.28 7.61 83.82.37 111.93-16.6-14.18 51.94-66.71 85.51-122.38 75.72zm130.3-151.34c-8.25-8.91-20.68-15.75-35.33-18.32-14.65-2.58-28.67-.4-39.48 5.17-.52-3.94-.64-7.98.09-12.1 3.84-21.7 24.58-36.19 46.34-32.37 21.75 3.83 36.28 24.52 32.45 46.22-.73 4.13-2.23 7.88-4.07 11.4z\"]\n};\nvar faThermometer = {\n prefix: 'fas',\n iconName: 'thermometer',\n icon: [512, 512, [], \"f491\", \"M476.8 20.4c-37.5-30.7-95.5-26.3-131.9 10.2l-45.7 46 50.5 50.5c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-50.4-50.5-45.1 45.4 50.3 50.4c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0L209 167.4l-45.1 45.4L214 263c3.1 3.1 3.1 8.2 0 11.3l-11.3 11.3c-3.1 3.1-8.2 3.1-11.3 0l-50.1-50.2L96 281.1V382L7 471c-9.4 9.4-9.4 24.6 0 33.9 9.4 9.4 24.6 9.4 33.9 0l89-89h99.9L484 162.6c34.9-34.9 42.2-101.5-7.2-142.2z\"]\n};\nvar faThermometerEmpty = {\n prefix: 'fas',\n iconName: 'thermometer-empty',\n icon: [256, 512, [], \"f2cb\", \"M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z\"]\n};\nvar faThermometerFull = {\n prefix: 'fas',\n iconName: 'thermometer-full',\n icon: [256, 512, [], \"f2c7\", \"M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z\"]\n};\nvar faThermometerHalf = {\n prefix: 'fas',\n iconName: 'thermometer-half',\n icon: [256, 512, [], \"f2c9\", \"M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z\"]\n};\nvar faThermometerQuarter = {\n prefix: 'fas',\n iconName: 'thermometer-quarter',\n icon: [256, 512, [], \"f2ca\", \"M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z\"]\n};\nvar faThermometerThreeQuarters = {\n prefix: 'fas',\n iconName: 'thermometer-three-quarters',\n icon: [256, 512, [], \"f2c8\", \"M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z\"]\n};\nvar faThumbsDown = {\n prefix: 'fas',\n iconName: 'thumbs-down',\n icon: [512, 512, [], \"f165\", \"M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z\"]\n};\nvar faThumbsUp = {\n prefix: 'fas',\n iconName: 'thumbs-up',\n icon: [512, 512, [], \"f164\", \"M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z\"]\n};\nvar faThumbtack = {\n prefix: 'fas',\n iconName: 'thumbtack',\n icon: [384, 512, [], \"f08d\", \"M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z\"]\n};\nvar faTicketAlt = {\n prefix: 'fas',\n iconName: 'ticket-alt',\n icon: [576, 512, [], \"f3ff\", \"M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z\"]\n};\nvar faTimes = {\n prefix: 'fas',\n iconName: 'times',\n icon: [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"]\n};\nvar faTimesCircle = {\n prefix: 'fas',\n iconName: 'times-circle',\n icon: [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"]\n};\nvar faTint = {\n prefix: 'fas',\n iconName: 'tint',\n icon: [352, 512, [], \"f043\", \"M205.22 22.09c-7.94-28.78-49.44-30.12-58.44 0C100.01 179.85 0 222.72 0 333.91 0 432.35 78.72 512 176 512s176-79.65 176-178.09c0-111.75-99.79-153.34-146.78-311.82zM176 448c-61.75 0-112-50.25-112-112 0-8.84 7.16-16 16-16s16 7.16 16 16c0 44.11 35.89 80 80 80 8.84 0 16 7.16 16 16s-7.16 16-16 16z\"]\n};\nvar faTintSlash = {\n prefix: 'fas',\n iconName: 'tint-slash',\n icon: [640, 512, [], \"f5c7\", \"M633.82 458.1L494.97 350.78c.52-5.57 1.03-11.16 1.03-16.87 0-111.76-99.79-153.34-146.78-311.82-7.94-28.78-49.44-30.12-58.44 0-15.52 52.34-36.87 91.96-58.49 125.68L45.47 3.37C38.49-2.05 28.43-.8 23.01 6.18L3.37 31.45C-2.05 38.42-.8 48.47 6.18 53.9l588.36 454.73c6.98 5.43 17.03 4.17 22.46-2.81l19.64-25.27c5.41-6.97 4.16-17.02-2.82-22.45zM144 333.91C144 432.35 222.72 512 320 512c44.71 0 85.37-16.96 116.4-44.7L162.72 255.78c-11.41 23.5-18.72 48.35-18.72 78.13z\"]\n};\nvar faTired = {\n prefix: 'fas',\n iconName: 'tired',\n icon: [496, 512, [], \"f5c8\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm33.8 189.7l80-48c11.6-6.9 24 7.7 15.4 18L343.6 208l33.6 40.3c8.7 10.4-3.9 24.8-15.4 18l-80-48c-7.7-4.7-7.7-15.9 0-20.6zm-163-30c-8.6-10.3 3.8-24.9 15.4-18l80 48c7.8 4.7 7.8 15.9 0 20.6l-80 48c-11.5 6.8-24-7.6-15.4-18l33.6-40.3-33.6-40.3zM248 288c51.9 0 115.3 43.8 123.2 106.7 1.7 13.6-8 24.6-17.7 20.4-25.9-11.1-64.4-17.4-105.5-17.4s-79.6 6.3-105.5 17.4c-9.8 4.2-19.4-7-17.7-20.4C132.7 331.8 196.1 288 248 288z\"]\n};\nvar faToggleOff = {\n prefix: 'fas',\n iconName: 'toggle-off',\n icon: [576, 512, [], \"f204\", \"M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z\"]\n};\nvar faToggleOn = {\n prefix: 'fas',\n iconName: 'toggle-on',\n icon: [576, 512, [], \"f205\", \"M384 64H192C86 64 0 150 0 256s86 192 192 192h192c106 0 192-86 192-192S490 64 384 64zm0 320c-70.8 0-128-57.3-128-128 0-70.8 57.3-128 128-128 70.8 0 128 57.3 128 128 0 70.8-57.3 128-128 128z\"]\n};\nvar faToilet = {\n prefix: 'fas',\n iconName: 'toilet',\n icon: [384, 512, [], \"f7d8\", \"M368 48c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16H16C7.2 0 0 7.2 0 16v16c0 8.8 7.2 16 16 16h16v156.7C11.8 214.8 0 226.9 0 240c0 67.2 34.6 126.2 86.8 160.5l-21.4 70.2C59.1 491.2 74.5 512 96 512h192c21.5 0 36.9-20.8 30.6-41.3l-21.4-70.2C349.4 366.2 384 307.2 384 240c0-13.1-11.8-25.2-32-35.3V48h16zM80 72c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H88c-4.4 0-8-3.6-8-8V72zm112 200c-77.1 0-139.6-14.3-139.6-32s62.5-32 139.6-32 139.6 14.3 139.6 32-62.5 32-139.6 32z\"]\n};\nvar faToiletPaper = {\n prefix: 'fas',\n iconName: 'toilet-paper',\n icon: [576, 512, [], \"f71e\", \"M128 0C74.98 0 32 85.96 32 192v172.07c0 41.12-9.8 62.77-31.17 126.87C-2.62 501.3 5.09 512 16.01 512h280.92c13.77 0 26-8.81 30.36-21.88 12.83-38.48 24.71-72.4 24.71-126.05V192c0-83.6 23.67-153.52 60.44-192H128zM96 224c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zm64 0c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zm64 0c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zm64 0c-8.84 0-16-7.16-16-16s7.16-16 16-16 16 7.16 16 16-7.16 16-16 16zM480 0c-53.02 0-96 85.96-96 192s42.98 192 96 192 96-85.96 96-192S533.02 0 480 0zm0 256c-17.67 0-32-28.65-32-64s14.33-64 32-64 32 28.65 32 64-14.33 64-32 64z\"]\n};\nvar faToolbox = {\n prefix: 'fas',\n iconName: 'toolbox',\n icon: [512, 512, [], \"f552\", \"M502.63 214.63l-45.25-45.25c-6-6-14.14-9.37-22.63-9.37H384V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v80H77.25c-8.49 0-16.62 3.37-22.63 9.37L9.37 214.63c-6 6-9.37 14.14-9.37 22.63V320h128v-16c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v16h128v-16c0-8.84 7.16-16 16-16h32c8.84 0 16 7.16 16 16v16h128v-82.75c0-8.48-3.37-16.62-9.37-22.62zM320 160H192V96h128v64zm64 208c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-16H192v16c0 8.84-7.16 16-16 16h-32c-8.84 0-16-7.16-16-16v-16H0v96c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-96H384v16z\"]\n};\nvar faTools = {\n prefix: 'fas',\n iconName: 'tools',\n icon: [512, 512, [], \"f7d9\", \"M501.1 395.7L384 278.6c-23.1-23.1-57.6-27.6-85.4-13.9L192 158.1V96L64 0 0 64l96 128h62.1l106.6 106.6c-13.6 27.8-9.2 62.3 13.9 85.4l117.1 117.1c14.6 14.6 38.2 14.6 52.7 0l52.7-52.7c14.5-14.6 14.5-38.2 0-52.7zM331.7 225c28.3 0 54.9 11 74.9 31l19.4 19.4c15.8-6.9 30.8-16.5 43.8-29.5 37.1-37.1 49.7-89.3 37.9-136.7-2.2-9-13.5-12.1-20.1-5.5l-74.4 74.4-67.9-11.3L334 98.9l74.4-74.4c6.6-6.6 3.4-17.9-5.7-20.2-47.4-11.7-99.6.9-136.6 37.9-28.5 28.5-41.9 66.1-41.2 103.6l82.1 82.1c8.1-1.9 16.5-2.9 24.7-2.9zm-103.9 82l-56.7-56.7L18.7 402.8c-25 25-25 65.5 0 90.5s65.5 25 90.5 0l123.6-123.6c-7.6-19.9-9.9-41.6-5-62.7zM64 472c-13.2 0-24-10.8-24-24 0-13.3 10.7-24 24-24s24 10.7 24 24c0 13.2-10.7 24-24 24z\"]\n};\nvar faTooth = {\n prefix: 'fas',\n iconName: 'tooth',\n icon: [448, 512, [], \"f5c9\", \"M443.98 96.25c-11.01-45.22-47.11-82.06-92.01-93.72-32.19-8.36-63 5.1-89.14 24.33-3.25 2.39-6.96 3.73-10.5 5.48l28.32 18.21c7.42 4.77 9.58 14.67 4.8 22.11-4.46 6.95-14.27 9.86-22.11 4.8L162.83 12.84c-20.7-10.85-43.38-16.4-66.81-10.31-44.9 11.67-81 48.5-92.01 93.72-10.13 41.62-.42 80.81 21.5 110.43 23.36 31.57 32.68 68.66 36.29 107.35 4.4 47.16 10.33 94.16 20.94 140.32l7.8 33.95c3.19 13.87 15.49 23.7 29.67 23.7 13.97 0 26.15-9.55 29.54-23.16l34.47-138.42c4.56-18.32 20.96-31.16 39.76-31.16s35.2 12.85 39.76 31.16l34.47 138.42c3.39 13.61 15.57 23.16 29.54 23.16 14.18 0 26.48-9.83 29.67-23.7l7.8-33.95c10.61-46.15 16.53-93.16 20.94-140.32 3.61-38.7 12.93-75.78 36.29-107.35 21.95-29.61 31.66-68.8 21.53-110.43z\"]\n};\nvar faTorah = {\n prefix: 'fas',\n iconName: 'torah',\n icon: [640, 512, [], \"f6a0\", \"M320.05 366.48l17.72-29.64h-35.46zm99.21-166H382.4l18.46 30.82zM48 0C21.49 0 0 14.33 0 32v448c0 17.67 21.49 32 48 32s48-14.33 48-32V32C96 14.33 74.51 0 48 0zm172.74 311.5h36.85l-18.46-30.82zm161.71 0h36.86l-18.45-30.8zM128 464h384V48H128zm66.77-278.13a21.22 21.22 0 0 1 18.48-10.71h59.45l29.13-48.71a21.13 21.13 0 0 1 18.22-10.37A20.76 20.76 0 0 1 338 126.29l29.25 48.86h59.52a21.12 21.12 0 0 1 18.1 32L415.63 256 445 305a20.69 20.69 0 0 1 .24 21.12 21.25 21.25 0 0 1-18.48 10.72h-59.47l-29.13 48.7a21.13 21.13 0 0 1-18.16 10.4 20.79 20.79 0 0 1-18-10.22l-29.25-48.88h-59.5a21.11 21.11 0 0 1-18.1-32L224.36 256 195 207a20.7 20.7 0 0 1-.23-21.13zM592 0c-26.51 0-48 14.33-48 32v448c0 17.67 21.49 32 48 32s48-14.33 48-32V32c0-17.67-21.49-32-48-32zM320 145.53l-17.78 29.62h35.46zm-62.45 55h-36.81l18.44 30.8zm29.58 111h65.79L386.09 256l-33.23-55.52h-65.79L253.9 256z\"]\n};\nvar faToriiGate = {\n prefix: 'fas',\n iconName: 'torii-gate',\n icon: [512, 512, [], \"f6a1\", \"M376.45 32h-240.9A303.17 303.17 0 0 1 0 0v96c0 17.67 14.33 32 32 32h32v64H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h48v240c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V256h256v240c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V256h48c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16h-48v-64h32c17.67 0 32-14.33 32-32V0a303.17 303.17 0 0 1-135.55 32zM128 128h96v64h-96v-64zm256 64h-96v-64h96v64z\"]\n};\nvar faTractor = {\n prefix: 'fas',\n iconName: 'tractor',\n icon: [640, 512, [], \"f722\", \"M528 336c-48.6 0-88 39.4-88 88s39.4 88 88 88 88-39.4 88-88-39.4-88-88-88zm0 112c-13.23 0-24-10.77-24-24s10.77-24 24-24 24 10.77 24 24-10.77 24-24 24zm80-288h-64v-40.2c0-14.12 4.7-27.76 13.15-38.84 4.42-5.8 3.55-14.06-1.32-19.49L534.2 37.3c-6.66-7.45-18.32-6.92-24.7.78C490.58 60.9 480 89.81 480 119.8V160H377.67L321.58 29.14A47.914 47.914 0 0 0 277.45 0H144c-26.47 0-48 21.53-48 48v146.52c-8.63-6.73-20.96-6.46-28.89 1.47L36 227.1c-8.59 8.59-8.59 22.52 0 31.11l5.06 5.06c-4.99 9.26-8.96 18.82-11.91 28.72H22c-12.15 0-22 9.85-22 22v44c0 12.15 9.85 22 22 22h7.14c2.96 9.91 6.92 19.46 11.91 28.73l-5.06 5.06c-8.59 8.59-8.59 22.52 0 31.11L67.1 476c8.59 8.59 22.52 8.59 31.11 0l5.06-5.06c9.26 4.99 18.82 8.96 28.72 11.91V490c0 12.15 9.85 22 22 22h44c12.15 0 22-9.85 22-22v-7.14c9.9-2.95 19.46-6.92 28.72-11.91l5.06 5.06c8.59 8.59 22.52 8.59 31.11 0l31.11-31.11c8.59-8.59 8.59-22.52 0-31.11l-5.06-5.06c4.99-9.26 8.96-18.82 11.91-28.72H330c12.15 0 22-9.85 22-22v-6h80.54c21.91-28.99 56.32-48 95.46-48 18.64 0 36.07 4.61 51.8 12.2l50.82-50.82c6-6 9.37-14.14 9.37-22.63V192c.01-17.67-14.32-32-31.99-32zM176 416c-44.18 0-80-35.82-80-80s35.82-80 80-80 80 35.82 80 80-35.82 80-80 80zm22-256h-38V64h106.89l41.15 96H198z\"]\n};\nvar faTrademark = {\n prefix: 'fas',\n iconName: 'trademark',\n icon: [640, 512, [], \"f25c\", \"M260.6 96H12c-6.6 0-12 5.4-12 12v43.1c0 6.6 5.4 12 12 12h85.1V404c0 6.6 5.4 12 12 12h54.3c6.6 0 12-5.4 12-12V163.1h85.1c6.6 0 12-5.4 12-12V108c.1-6.6-5.3-12-11.9-12zM640 403l-24-296c-.5-6.2-5.7-11-12-11h-65.4c-5.1 0-9.7 3.3-11.3 8.1l-43.8 127.1c-7.2 20.6-16.1 52.8-16.1 52.8h-.9s-8.9-32.2-16.1-52.8l-43.8-127.1c-1.7-4.8-6.2-8.1-11.3-8.1h-65.4c-6.2 0-11.4 4.8-12 11l-24.4 296c-.6 7 4.9 13 12 13H360c6.3 0 11.5-4.9 12-11.2l9.1-132.9c1.8-24.2 0-53.7 0-53.7h.9s10.7 33.6 17.9 53.7l30.7 84.7c1.7 4.7 6.2 7.9 11.3 7.9h50.3c5.1 0 9.6-3.2 11.3-7.9l30.7-84.7c7.2-20.1 17.9-53.7 17.9-53.7h.9s-1.8 29.5 0 53.7l9.1 132.9c.4 6.3 5.7 11.2 12 11.2H628c7 0 12.5-6 12-13z\"]\n};\nvar faTrafficLight = {\n prefix: 'fas',\n iconName: 'traffic-light',\n icon: [384, 512, [], \"f637\", \"M384 192h-64v-37.88c37.2-13.22 64-48.38 64-90.12h-64V32c0-17.67-14.33-32-32-32H96C78.33 0 64 14.33 64 32v32H0c0 41.74 26.8 76.9 64 90.12V192H0c0 41.74 26.8 76.9 64 90.12V320H0c0 42.84 28.25 78.69 66.99 91.05C79.42 468.72 130.6 512 192 512s112.58-43.28 125.01-100.95C355.75 398.69 384 362.84 384 320h-64v-37.88c37.2-13.22 64-48.38 64-90.12zM192 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm0-128c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm0-128c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48z\"]\n};\nvar faTrain = {\n prefix: 'fas',\n iconName: 'train',\n icon: [448, 512, [], \"f238\", \"M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z\"]\n};\nvar faTram = {\n prefix: 'fas',\n iconName: 'tram',\n icon: [512, 512, [], \"f7da\", \"M288 64c17.7 0 32-14.3 32-32S305.7 0 288 0s-32 14.3-32 32 14.3 32 32 32zm223.5-12.1c-2.3-8.6-11-13.6-19.6-11.3l-480 128c-8.5 2.3-13.6 11-11.3 19.6C2.5 195.3 8.9 200 16 200c1.4 0 2.8-.2 4.1-.5L240 140.8V224H64c-17.7 0-32 14.3-32 32v224c0 17.7 14.3 32 32 32h384c17.7 0 32-14.3 32-32V256c0-17.7-14.3-32-32-32H272v-91.7l228.1-60.8c8.6-2.3 13.6-11.1 11.4-19.6zM176 384H80v-96h96v96zm160-96h96v96h-96v-96zm-32 0v96h-96v-96h96zM192 96c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z\"]\n};\nvar faTransgender = {\n prefix: 'fas',\n iconName: 'transgender',\n icon: [384, 512, [], \"f224\", \"M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faTransgenderAlt = {\n prefix: 'fas',\n iconName: 'transgender-alt',\n icon: [480, 512, [], \"f225\", \"M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faTrash = {\n prefix: 'fas',\n iconName: 'trash',\n icon: [448, 512, [], \"f1f8\", \"M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z\"]\n};\nvar faTrashAlt = {\n prefix: 'fas',\n iconName: 'trash-alt',\n icon: [448, 512, [], \"f2ed\", \"M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faTrashRestore = {\n prefix: 'fas',\n iconName: 'trash-restore',\n icon: [448, 512, [], \"f829\", \"M53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32zm70.11-175.8l89.38-94.26a15.41 15.41 0 0 1 22.62 0l89.38 94.26c10.08 10.62 2.94 28.8-11.32 28.8H256v112a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16V320h-57.37c-14.26 0-21.4-18.18-11.32-28.8zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faTrashRestoreAlt = {\n prefix: 'fas',\n iconName: 'trash-restore-alt',\n icon: [448, 512, [], \"f82a\", \"M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm91.31-172.8l89.38-94.26a15.41 15.41 0 0 1 22.62 0l89.38 94.26c10.08 10.62 2.94 28.8-11.32 28.8H256v112a16 16 0 0 1-16 16h-32a16 16 0 0 1-16-16V320h-57.37c-14.26 0-21.4-18.18-11.32-28.8zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]\n};\nvar faTree = {\n prefix: 'fas',\n iconName: 'tree',\n icon: [384, 512, [], \"f1bb\", \"M378.31 378.49L298.42 288h30.63c9.01 0 16.98-5 20.78-13.06 3.8-8.04 2.55-17.26-3.28-24.05L268.42 160h28.89c9.1 0 17.3-5.35 20.86-13.61 3.52-8.13 1.86-17.59-4.24-24.08L203.66 4.83c-6.03-6.45-17.28-6.45-23.32 0L70.06 122.31c-6.1 6.49-7.75 15.95-4.24 24.08C69.38 154.65 77.59 160 86.69 160h28.89l-78.14 90.91c-5.81 6.78-7.06 15.99-3.27 24.04C37.97 283 45.93 288 54.95 288h30.63L5.69 378.49c-6 6.79-7.36 16.09-3.56 24.26 3.75 8.05 12 13.25 21.01 13.25H160v24.45l-30.29 48.4c-5.32 10.64 2.42 23.16 14.31 23.16h95.96c11.89 0 19.63-12.52 14.31-23.16L224 440.45V416h136.86c9.01 0 17.26-5.2 21.01-13.25 3.8-8.17 2.44-17.47-3.56-24.26z\"]\n};\nvar faTrophy = {\n prefix: 'fas',\n iconName: 'trophy',\n icon: [576, 512, [], \"f091\", \"M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z\"]\n};\nvar faTruck = {\n prefix: 'fas',\n iconName: 'truck',\n icon: [640, 512, [], \"f0d1\", \"M624 352h-16V243.9c0-12.7-5.1-24.9-14.1-33.9L494 110.1c-9-9-21.2-14.1-33.9-14.1H416V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h16c0 53 43 96 96 96s96-43 96-96h128c0 53 43 96 96 96s96-43 96-96h48c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM160 464c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm320 0c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-208H416V144h44.1l99.9 99.9V256z\"]\n};\nvar faTruckLoading = {\n prefix: 'fas',\n iconName: 'truck-loading',\n icon: [640, 512, [], \"f4de\", \"M50.2 375.6c2.3 8.5 11.1 13.6 19.6 11.3l216.4-58c8.5-2.3 13.6-11.1 11.3-19.6l-49.7-185.5c-2.3-8.5-11.1-13.6-19.6-11.3L151 133.3l24.8 92.7-61.8 16.5-24.8-92.7-77.3 20.7C3.4 172.8-1.7 181.6.6 190.1l49.6 185.5zM384 0c-17.7 0-32 14.3-32 32v323.6L5.9 450c-4.3 1.2-6.8 5.6-5.6 9.8l12.6 46.3c1.2 4.3 5.6 6.8 9.8 5.6l393.7-107.4C418.8 464.1 467.6 512 528 512c61.9 0 112-50.1 112-112V0H384zm144 448c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z\"]\n};\nvar faTruckMonster = {\n prefix: 'fas',\n iconName: 'truck-monster',\n icon: [640, 512, [], \"f63b\", \"M624 224h-16v-64c0-17.67-14.33-32-32-32h-73.6L419.22 24.02A64.025 64.025 0 0 0 369.24 0H256c-17.67 0-32 14.33-32 32v96H48c-8.84 0-16 7.16-16 16v80H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h16.72c29.21-38.65 75.1-64 127.28-64s98.07 25.35 127.28 64h65.45c29.21-38.65 75.1-64 127.28-64s98.07 25.35 127.28 64H624c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zm-336-96V64h81.24l51.2 64H288zm304 224h-5.2c-2.2-7.33-5.07-14.28-8.65-20.89l3.67-3.67c6.25-6.25 6.25-16.38 0-22.63l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-3.67 3.67A110.85 110.85 0 0 0 512 277.2V272c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v5.2c-7.33 2.2-14.28 5.07-20.89 8.65l-3.67-3.67c-6.25-6.25-16.38-6.25-22.63 0l-22.63 22.63c-6.25 6.25-6.25 16.38 0 22.63l3.67 3.67A110.85 110.85 0 0 0 373.2 352H368c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h5.2c2.2 7.33 5.07 14.28 8.65 20.89l-3.67 3.67c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l3.67-3.67c6.61 3.57 13.57 6.45 20.9 8.65v5.2c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-5.2c7.33-2.2 14.28-5.07 20.9-8.65l3.67 3.67c6.25 6.25 16.38 6.25 22.63 0l22.63-22.63c6.25-6.25 6.25-16.38 0-22.63l-3.67-3.67a110.85 110.85 0 0 0 8.65-20.89h5.2c8.84 0 16-7.16 16-16v-32c-.02-8.84-7.18-16-16.02-16zm-112 80c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm-208-80h-5.2c-2.2-7.33-5.07-14.28-8.65-20.89l3.67-3.67c6.25-6.25 6.25-16.38 0-22.63l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-3.67 3.67A110.85 110.85 0 0 0 192 277.2V272c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v5.2c-7.33 2.2-14.28 5.07-20.89 8.65l-3.67-3.67c-6.25-6.25-16.38-6.25-22.63 0L58.18 304.8c-6.25 6.25-6.25 16.38 0 22.63l3.67 3.67a110.85 110.85 0 0 0-8.65 20.89H48c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h5.2c2.2 7.33 5.07 14.28 8.65 20.89l-3.67 3.67c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l3.67-3.67c6.61 3.57 13.57 6.45 20.9 8.65v5.2c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-5.2c7.33-2.2 14.28-5.07 20.9-8.65l3.67 3.67c6.25 6.25 16.38 6.25 22.63 0l22.63-22.63c6.25-6.25 6.25-16.38 0-22.63l-3.67-3.67a110.85 110.85 0 0 0 8.65-20.89h5.2c8.84 0 16-7.16 16-16v-32C288 359.16 280.84 352 272 352zm-112 80c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48z\"]\n};\nvar faTruckMoving = {\n prefix: 'fas',\n iconName: 'truck-moving',\n icon: [640, 512, [], \"f4df\", \"M621.3 237.3l-58.5-58.5c-12-12-28.3-18.7-45.3-18.7H480V64c0-17.7-14.3-32-32-32H32C14.3 32 0 46.3 0 64v336c0 44.2 35.8 80 80 80 26.3 0 49.4-12.9 64-32.4 14.6 19.6 37.7 32.4 64 32.4 44.2 0 80-35.8 80-80 0-5.5-.6-10.8-1.6-16h163.2c-1.1 5.2-1.6 10.5-1.6 16 0 44.2 35.8 80 80 80s80-35.8 80-80c0-5.5-.6-10.8-1.6-16H624c8.8 0 16-7.2 16-16v-85.5c0-17-6.7-33.2-18.7-45.2zM80 432c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zm128 0c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zm272-224h37.5c4.3 0 8.3 1.7 11.3 4.7l43.3 43.3H480v-48zm48 224c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32z\"]\n};\nvar faTruckPickup = {\n prefix: 'fas',\n iconName: 'truck-pickup',\n icon: [640, 512, [], \"f63c\", \"M624 288h-16v-64c0-17.67-14.33-32-32-32h-48L419.22 56.02A64.025 64.025 0 0 0 369.24 32H256c-17.67 0-32 14.33-32 32v128H64c-17.67 0-32 14.33-32 32v64H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h49.61c-.76 5.27-1.61 10.52-1.61 16 0 61.86 50.14 112 112 112s112-50.14 112-112c0-5.48-.85-10.73-1.61-16h67.23c-.76 5.27-1.61 10.52-1.61 16 0 61.86 50.14 112 112 112s112-50.14 112-112c0-5.48-.85-10.73-1.61-16H624c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM288 96h81.24l76.8 96H288V96zM176 416c-26.47 0-48-21.53-48-48s21.53-48 48-48 48 21.53 48 48-21.53 48-48 48zm288 0c-26.47 0-48-21.53-48-48s21.53-48 48-48 48 21.53 48 48-21.53 48-48 48z\"]\n};\nvar faTshirt = {\n prefix: 'fas',\n iconName: 'tshirt',\n icon: [640, 512, [], \"f553\", \"M631.2 96.5L436.5 0C416.4 27.8 371.9 47.2 320 47.2S223.6 27.8 203.5 0L8.8 96.5c-7.9 4-11.1 13.6-7.2 21.5l57.2 114.5c4 7.9 13.6 11.1 21.5 7.2l56.6-27.7c10.6-5.2 23 2.5 23 14.4V480c0 17.7 14.3 32 32 32h256c17.7 0 32-14.3 32-32V226.3c0-11.8 12.4-19.6 23-14.4l56.6 27.7c7.9 4 17.5.8 21.5-7.2L638.3 118c4-7.9.8-17.6-7.1-21.5z\"]\n};\nvar faTty = {\n prefix: 'fas',\n iconName: 'tty',\n icon: [512, 512, [], \"f1e4\", \"M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z\"]\n};\nvar faTv = {\n prefix: 'fas',\n iconName: 'tv',\n icon: [640, 512, [], \"f26c\", \"M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z\"]\n};\nvar faUmbrella = {\n prefix: 'fas',\n iconName: 'umbrella',\n icon: [576, 512, [], \"f0e9\", \"M575.7 280.8C547.1 144.5 437.3 62.6 320 49.9V32c0-17.7-14.3-32-32-32s-32 14.3-32 32v17.9C138.3 62.6 29.5 144.5.3 280.8c-2.2 10.1 8.5 21.3 18.7 11.4 52-55 107.7-52.4 158.6 37 5.3 9.5 14.9 8.6 19.7 0 20.2-35.4 44.9-73.2 90.7-73.2 58.5 0 88.2 68.8 90.7 73.2 4.8 8.6 14.4 9.5 19.7 0 51-89.5 107.1-91.4 158.6-37 10.3 10 20.9-1.3 18.7-11.4zM256 301.7V432c0 8.8-7.2 16-16 16-7.8 0-13.2-5.3-15.1-10.7-5.9-16.7-24.1-25.4-40.8-19.5-16.7 5.9-25.4 24.2-19.5 40.8 11.2 31.9 41.6 53.3 75.4 53.3 44.1 0 80-35.9 80-80V301.6c-9.1-7.9-19.8-13.6-32-13.6-12.3.1-22.4 4.8-32 13.7z\"]\n};\nvar faUmbrellaBeach = {\n prefix: 'fas',\n iconName: 'umbrella-beach',\n icon: [640, 512, [], \"f5ca\", \"M115.38 136.9l102.11 37.18c35.19-81.54 86.21-144.29 139-173.7-95.88-4.89-188.78 36.96-248.53 111.8-6.69 8.4-2.66 21.05 7.42 24.72zm132.25 48.16l238.48 86.83c35.76-121.38 18.7-231.66-42.63-253.98-7.4-2.7-15.13-4-23.09-4-58.02.01-128.27 69.17-172.76 171.15zM521.48 60.5c6.22 16.3 10.83 34.6 13.2 55.19 5.74 49.89-1.42 108.23-18.95 166.98l102.62 37.36c10.09 3.67 21.31-3.43 21.57-14.17 2.32-95.69-41.91-187.44-118.44-245.36zM560 447.98H321.06L386 269.5l-60.14-21.9-72.9 200.37H16c-8.84 0-16 7.16-16 16.01v32.01C0 504.83 7.16 512 16 512h544c8.84 0 16-7.17 16-16.01v-32.01c0-8.84-7.16-16-16-16z\"]\n};\nvar faUnderline = {\n prefix: 'fas',\n iconName: 'underline',\n icon: [448, 512, [], \"f0cd\", \"M32 64h32v160c0 88.22 71.78 160 160 160s160-71.78 160-160V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H272a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32v160a80 80 0 0 1-160 0V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm400 384H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faUndo = {\n prefix: 'fas',\n iconName: 'undo',\n icon: [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"]\n};\nvar faUndoAlt = {\n prefix: 'fas',\n iconName: 'undo-alt',\n icon: [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"]\n};\nvar faUniversalAccess = {\n prefix: 'fas',\n iconName: 'universal-access',\n icon: [512, 512, [], \"f29a\", \"M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z\"]\n};\nvar faUniversity = {\n prefix: 'fas',\n iconName: 'university',\n icon: [512, 512, [], \"f19c\", \"M496 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H60c-6.627 0-12-5.373-12-12v-12H24a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 496 128zm-24 304H40c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM96 192v192H60c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-36V192h-64v192h-64V192h-64v192h-64V192H96z\"]\n};\nvar faUnlink = {\n prefix: 'fas',\n iconName: 'unlink',\n icon: [512, 512, [], \"f127\", \"M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z\"]\n};\nvar faUnlock = {\n prefix: 'fas',\n iconName: 'unlock',\n icon: [448, 512, [], \"f09c\", \"M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z\"]\n};\nvar faUnlockAlt = {\n prefix: 'fas',\n iconName: 'unlock-alt',\n icon: [448, 512, [], \"f13e\", \"M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z\"]\n};\nvar faUpload = {\n prefix: 'fas',\n iconName: 'upload',\n icon: [512, 512, [], \"f093\", \"M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z\"]\n};\nvar faUser = {\n prefix: 'fas',\n iconName: 'user',\n icon: [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n};\nvar faUserAlt = {\n prefix: 'fas',\n iconName: 'user-alt',\n icon: [512, 512, [], \"f406\", \"M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z\"]\n};\nvar faUserAltSlash = {\n prefix: 'fas',\n iconName: 'user-alt-slash',\n icon: [640, 512, [], \"f4fa\", \"M633.8 458.1L389.6 269.3C433.8 244.7 464 198.1 464 144 464 64.5 399.5 0 320 0c-67.1 0-123 46.1-139 108.2L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3zM198.4 320C124.2 320 64 380.2 64 454.4v9.6c0 26.5 21.5 48 48 48h382.2L245.8 320h-47.4z\"]\n};\nvar faUserAstronaut = {\n prefix: 'fas',\n iconName: 'user-astronaut',\n icon: [448, 512, [], \"f4fb\", \"M64 224h13.5c24.7 56.5 80.9 96 146.5 96s121.8-39.5 146.5-96H384c8.8 0 16-7.2 16-16v-96c0-8.8-7.2-16-16-16h-13.5C345.8 39.5 289.6 0 224 0S102.2 39.5 77.5 96H64c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16zm40-88c0-22.1 21.5-40 48-40h144c26.5 0 48 17.9 48 40v24c0 53-43 96-96 96h-48c-53 0-96-43-96-96v-24zm72 72l12-36 36-12-36-12-12-36-12 36-36 12 36 12 12 36zm151.6 113.4C297.7 340.7 262.2 352 224 352s-73.7-11.3-103.6-30.6C52.9 328.5 0 385 0 454.4v9.6c0 26.5 21.5 48 48 48h80v-64c0-17.7 14.3-32 32-32h128c17.7 0 32 14.3 32 32v64h80c26.5 0 48-21.5 48-48v-9.6c0-69.4-52.9-125.9-120.4-133zM272 448c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-96 0c-8.8 0-16 7.2-16 16v48h32v-48c0-8.8-7.2-16-16-16z\"]\n};\nvar faUserCheck = {\n prefix: 'fas',\n iconName: 'user-check',\n icon: [640, 512, [], \"f4fc\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4zm323-128.4l-27.8-28.1c-4.6-4.7-12.1-4.7-16.8-.1l-104.8 104-45.5-45.8c-4.6-4.7-12.1-4.7-16.8-.1l-28.1 27.9c-4.7 4.6-4.7 12.1-.1 16.8l81.7 82.3c4.6 4.7 12.1 4.7 16.8.1l141.3-140.2c4.6-4.7 4.7-12.2.1-16.8z\"]\n};\nvar faUserCircle = {\n prefix: 'fas',\n iconName: 'user-circle',\n icon: [496, 512, [], \"f2bd\", \"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 96c48.6 0 88 39.4 88 88s-39.4 88-88 88-88-39.4-88-88 39.4-88 88-88zm0 344c-58.7 0-111.3-26.6-146.5-68.2 18.8-35.4 55.6-59.8 98.5-59.8 2.4 0 4.8.4 7.1 1.1 13 4.2 26.6 6.9 40.9 6.9 14.3 0 28-2.7 40.9-6.9 2.3-.7 4.7-1.1 7.1-1.1 42.9 0 79.7 24.4 98.5 59.8C359.3 421.4 306.7 448 248 448z\"]\n};\nvar faUserClock = {\n prefix: 'fas',\n iconName: 'user-clock',\n icon: [640, 512, [], \"f4fd\", \"M496 224c-79.6 0-144 64.4-144 144s64.4 144 144 144 144-64.4 144-144-64.4-144-144-144zm64 150.3c0 5.3-4.4 9.7-9.7 9.7h-60.6c-5.3 0-9.7-4.4-9.7-9.7v-76.6c0-5.3 4.4-9.7 9.7-9.7h12.6c5.3 0 9.7 4.4 9.7 9.7V352h38.3c5.3 0 9.7 4.4 9.7 9.7v12.6zM320 368c0-27.8 6.7-54.1 18.2-77.5-8-1.5-16.2-2.5-24.6-2.5h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h347.1c-45.3-31.9-75.1-84.5-75.1-144zm-96-112c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128z\"]\n};\nvar faUserCog = {\n prefix: 'fas',\n iconName: 'user-cog',\n icon: [640, 512, [], \"f4fe\", \"M610.5 373.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 400.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm201.2 226.5c-2.3-1.2-4.6-2.6-6.8-3.9l-7.9 4.6c-6 3.4-12.8 5.3-19.6 5.3-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-5.5-17.7 1.9-36.4 17.9-45.7l7.9-4.6c-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-16-9.2-23.4-28-17.9-45.7.9-2.9 2.2-5.8 3.2-8.7-3.8-.3-7.5-1.2-11.4-1.2h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c10.1 0 19.5-3.2 27.2-8.5-1.2-3.8-2-7.7-2-11.8v-9.2z\"]\n};\nvar faUserEdit = {\n prefix: 'fas',\n iconName: 'user-edit',\n icon: [640, 512, [], \"f4ff\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h274.9c-2.4-6.8-3.4-14-2.6-21.3l6.8-60.9 1.2-11.1 7.9-7.9 77.3-77.3c-24.5-27.7-60-45.5-99.9-45.5zm45.3 145.3l-6.8 61c-1.1 10.2 7.5 18.8 17.6 17.6l60.9-6.8 137.9-137.9-71.7-71.7-137.9 137.8zM633 268.9L595.1 231c-9.3-9.3-24.5-9.3-33.8 0l-37.8 37.8-4.1 4.1 71.8 71.7 41.8-41.8c9.3-9.4 9.3-24.5 0-33.9z\"]\n};\nvar faUserFriends = {\n prefix: 'fas',\n iconName: 'user-friends',\n icon: [640, 512, [], \"f500\", \"M192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C51.6 288 0 339.6 0 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zM480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm48 32h-3.8c-13.9 4.8-28.6 8-44.2 8s-30.3-3.2-44.2-8H432c-20.4 0-39.2 5.9-55.7 15.4 24.4 26.3 39.7 61.2 39.7 99.8v38.4c0 2.2-.5 4.3-.6 6.4H592c26.5 0 48-21.5 48-48 0-61.9-50.1-112-112-112z\"]\n};\nvar faUserGraduate = {\n prefix: 'fas',\n iconName: 'user-graduate',\n icon: [448, 512, [], \"f501\", \"M319.4 320.6L224 416l-95.4-95.4C57.1 323.7 0 382.2 0 454.4v9.6c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-9.6c0-72.2-57.1-130.7-128.6-133.8zM13.6 79.8l6.4 1.5v58.4c-7 4.2-12 11.5-12 20.3 0 8.4 4.6 15.4 11.1 19.7L3.5 242c-1.7 6.9 2.1 14 7.6 14h41.8c5.5 0 9.3-7.1 7.6-14l-15.6-62.3C51.4 175.4 56 168.4 56 160c0-8.8-5-16.1-12-20.3V87.1l66 15.9c-8.6 17.2-14 36.4-14 57 0 70.7 57.3 128 128 128s128-57.3 128-128c0-20.6-5.3-39.8-14-57l96.3-23.2c18.2-4.4 18.2-27.1 0-31.5l-190.4-46c-13-3.1-26.7-3.1-39.7 0L13.6 48.2c-18.1 4.4-18.1 27.2 0 31.6z\"]\n};\nvar faUserInjured = {\n prefix: 'fas',\n iconName: 'user-injured',\n icon: [448, 512, [], \"f728\", \"M277.37 11.98C261.08 4.47 243.11 0 224 0c-53.69 0-99.5 33.13-118.51 80h81.19l90.69-68.02zM342.51 80c-7.9-19.47-20.67-36.2-36.49-49.52L239.99 80h102.52zM224 256c70.69 0 128-57.31 128-128 0-5.48-.95-10.7-1.61-16H97.61c-.67 5.3-1.61 10.52-1.61 16 0 70.69 57.31 128 128 128zM80 299.7V512h128.26l-98.45-221.52A132.835 132.835 0 0 0 80 299.7zM0 464c0 26.51 21.49 48 48 48V320.24C18.88 344.89 0 381.26 0 422.4V464zm256-48h-55.38l42.67 96H256c26.47 0 48-21.53 48-48s-21.53-48-48-48zm57.6-128h-16.71c-22.24 10.18-46.88 16-72.89 16s-50.65-5.82-72.89-16h-7.37l42.67 96H256c44.11 0 80 35.89 80 80 0 18.08-6.26 34.59-16.41 48H400c26.51 0 48-21.49 48-48v-41.6c0-74.23-60.17-134.4-134.4-134.4z\"]\n};\nvar faUserLock = {\n prefix: 'fas',\n iconName: 'user-lock',\n icon: [640, 512, [], \"f502\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 64a63.08 63.08 0 0 1 8.1-30.5c-4.8-.5-9.5-1.5-14.5-1.5h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h280.9a63.54 63.54 0 0 1-8.9-32zm288-32h-32v-80a80 80 0 0 0-160 0v80h-32a32 32 0 0 0-32 32v160a32 32 0 0 0 32 32h224a32 32 0 0 0 32-32V320a32 32 0 0 0-32-32zM496 432a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm32-144h-64v-80a32 32 0 0 1 64 0z\"]\n};\nvar faUserMd = {\n prefix: 'fas',\n iconName: 'user-md',\n icon: [448, 512, [], \"f0f0\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zM104 424c0 13.3 10.7 24 24 24s24-10.7 24-24-10.7-24-24-24-24 10.7-24 24zm216-135.4v49c36.5 7.4 64 39.8 64 78.4v41.7c0 7.6-5.4 14.2-12.9 15.7l-32.2 6.4c-4.3.9-8.5-1.9-9.4-6.3l-3.1-15.7c-.9-4.3 1.9-8.6 6.3-9.4l19.3-3.9V416c0-62.8-96-65.1-96 1.9v26.7l19.3 3.9c4.3.9 7.1 5.1 6.3 9.4l-3.1 15.7c-.9 4.3-5.1 7.1-9.4 6.3l-31.2-4.2c-7.9-1.1-13.8-7.8-13.8-15.9V416c0-38.6 27.5-70.9 64-78.4v-45.2c-2.2.7-4.4 1.1-6.6 1.9-18 6.3-37.3 9.8-57.4 9.8s-39.4-3.5-57.4-9.8c-7.4-2.6-14.9-4.2-22.6-5.2v81.6c23.1 6.9 40 28.1 40 53.4 0 30.9-25.1 56-56 56s-56-25.1-56-56c0-25.3 16.9-46.5 40-53.4v-80.4C48.5 301 0 355.8 0 422.4v44.8C0 491.9 20.1 512 44.8 512h358.4c24.7 0 44.8-20.1 44.8-44.8v-44.8c0-72-56.8-130.3-128-133.8z\"]\n};\nvar faUserMinus = {\n prefix: 'fas',\n iconName: 'user-minus',\n icon: [640, 512, [], \"f503\", \"M624 208H432c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h192c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n};\nvar faUserNinja = {\n prefix: 'fas',\n iconName: 'user-ninja',\n icon: [448, 512, [], \"f504\", \"M325.4 289.2L224 390.6 122.6 289.2C54 295.3 0 352.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-70.2-54-127.1-122.6-133.2zM32 192c27.3 0 51.8-11.5 69.2-29.7 15.1 53.9 64 93.7 122.8 93.7 70.7 0 128-57.3 128-128S294.7 0 224 0c-50.4 0-93.6 29.4-114.5 71.8C92.1 47.8 64 32 32 32c0 33.4 17.1 62.8 43.1 80-26 17.2-43.1 46.6-43.1 80zm144-96h96c17.7 0 32 14.3 32 32H144c0-17.7 14.3-32 32-32z\"]\n};\nvar faUserNurse = {\n prefix: 'fas',\n iconName: 'user-nurse',\n icon: [448, 512, [], \"f82f\", \"M57.78 288h82.36c22.51 19.68 51.62 32 83.86 32s61.35-12.32 83.86-32h82.36a16 16 0 0 0 14.28-23.18c-15.23-29.85-31.28-62.23-42.15-95.54C354.78 146.09 352 121.59 352 97.2V48L224 0 96 48v49.2c0 24.39-2.75 48.89-10.33 72.08C74.78 202.59 58.73 235 43.5 264.82A16 16 0 0 0 57.78 288zM184 71.67a5 5 0 0 1 5-5h21.67V45a5 5 0 0 1 5-5h16.66a5 5 0 0 1 5 5v21.67H259a5 5 0 0 1 5 5v16.66a5 5 0 0 1-5 5h-21.67V115a5 5 0 0 1-5 5h-16.66a5 5 0 0 1-5-5V93.33H189a5 5 0 0 1-5-5zM144 160h160v32a80 80 0 0 1-160 0zm175.41 160L224 415.39 128.59 320C57.1 323.1 0 381.6 0 453.79A58.21 58.21 0 0 0 58.21 512h331.58A58.21 58.21 0 0 0 448 453.79C448 381.6 390.9 323.1 319.41 320z\"]\n};\nvar faUserPlus = {\n prefix: 'fas',\n iconName: 'user-plus',\n icon: [640, 512, [], \"f234\", \"M624 208h-64v-64c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v64h-64c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h64v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-64h64c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n};\nvar faUserSecret = {\n prefix: 'fas',\n iconName: 'user-secret',\n icon: [448, 512, [], \"f21b\", \"M383.9 308.3l23.9-62.6c4-10.5-3.7-21.7-15-21.7h-58.5c11-18.9 17.8-40.6 17.8-64v-.3c39.2-7.8 64-19.1 64-31.7 0-13.3-27.3-25.1-70.1-33-9.2-32.8-27-65.8-40.6-82.8-9.5-11.9-25.9-15.6-39.5-8.8l-27.6 13.8c-9 4.5-19.6 4.5-28.6 0L182.1 3.4c-13.6-6.8-30-3.1-39.5 8.8-13.5 17-31.4 50-40.6 82.8-42.7 7.9-70 19.7-70 33 0 12.6 24.8 23.9 64 31.7v.3c0 23.4 6.8 45.1 17.8 64H56.3c-11.5 0-19.2 11.7-14.7 22.3l25.8 60.2C27.3 329.8 0 372.7 0 422.4v44.8C0 491.9 20.1 512 44.8 512h358.4c24.7 0 44.8-20.1 44.8-44.8v-44.8c0-48.4-25.8-90.4-64.1-114.1zM176 480l-41.6-192 49.6 32 24 40-32 120zm96 0l-32-120 24-40 49.6-32L272 480zm41.7-298.5c-3.9 11.9-7 24.6-16.5 33.4-10.1 9.3-48 22.4-64-25-2.8-8.4-15.4-8.4-18.3 0-17 50.2-56 32.4-64 25-9.5-8.8-12.7-21.5-16.5-33.4-.8-2.5-6.3-5.7-6.3-5.8v-10.8c28.3 3.6 61 5.8 96 5.8s67.7-2.1 96-5.8v10.8c-.1.1-5.6 3.2-6.4 5.8z\"]\n};\nvar faUserShield = {\n prefix: 'fas',\n iconName: 'user-shield',\n icon: [640, 512, [], \"f505\", \"M622.3 271.1l-115.2-45c-4.1-1.6-12.6-3.7-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9 9.6 3.7 18 1.6 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8zM224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c6.8 0 13.3-1.5 19.2-4-54-42.9-99.2-116.7-99.2-212z\"]\n};\nvar faUserSlash = {\n prefix: 'fas',\n iconName: 'user-slash',\n icon: [640, 512, [], \"f506\", \"M633.8 458.1L362.3 248.3C412.1 230.7 448 183.8 448 128 448 57.3 390.7 0 320 0c-67.1 0-121.5 51.8-126.9 117.4L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4l588.4 454.7c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.4-6.8 4.1-16.9-2.9-22.3zM96 422.4V464c0 26.5 21.5 48 48 48h350.2L207.4 290.3C144.2 301.3 96 356 96 422.4z\"]\n};\nvar faUserTag = {\n prefix: 'fas',\n iconName: 'user-tag',\n icon: [640, 512, [], \"f507\", \"M630.6 364.9l-90.3-90.2c-12-12-28.3-18.7-45.3-18.7h-79.3c-17.7 0-32 14.3-32 32v79.2c0 17 6.7 33.2 18.7 45.2l90.3 90.2c12.5 12.5 32.8 12.5 45.3 0l92.5-92.5c12.6-12.5 12.6-32.7.1-45.2zm-182.8-21c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24c0 13.2-10.7 24-24 24zm-223.8-88c70.7 0 128-57.3 128-128C352 57.3 294.7 0 224 0S96 57.3 96 128c0 70.6 57.3 127.9 128 127.9zm127.8 111.2V294c-12.2-3.6-24.9-6.2-38.2-6.2h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 287.9 0 348.1 0 422.3v41.6c0 26.5 21.5 48 48 48h352c15.5 0 29.1-7.5 37.9-18.9l-58-58c-18.1-18.1-28.1-42.2-28.1-67.9z\"]\n};\nvar faUserTie = {\n prefix: 'fas',\n iconName: 'user-tie',\n icon: [448, 512, [], \"f508\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm95.8 32.6L272 480l-32-136 32-56h-96l32 56-32 136-47.8-191.4C56.9 292 0 350.3 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-72.1-56.9-130.4-128.2-133.8z\"]\n};\nvar faUserTimes = {\n prefix: 'fas',\n iconName: 'user-times',\n icon: [640, 512, [], \"f235\", \"M589.6 240l45.6-45.6c6.3-6.3 6.3-16.5 0-22.8l-22.8-22.8c-6.3-6.3-16.5-6.3-22.8 0L544 194.4l-45.6-45.6c-6.3-6.3-16.5-6.3-22.8 0l-22.8 22.8c-6.3 6.3-6.3 16.5 0 22.8l45.6 45.6-45.6 45.6c-6.3 6.3-6.3 16.5 0 22.8l22.8 22.8c6.3 6.3 16.5 6.3 22.8 0l45.6-45.6 45.6 45.6c6.3 6.3 16.5 6.3 22.8 0l22.8-22.8c6.3-6.3 6.3-16.5 0-22.8L589.6 240zM224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n};\nvar faUsers = {\n prefix: 'fas',\n iconName: 'users',\n icon: [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n};\nvar faUsersCog = {\n prefix: 'fas',\n iconName: 'users-cog',\n icon: [640, 512, [], \"f509\", \"M610.5 341.3c2.6-14.1 2.6-28.5 0-42.6l25.8-14.9c3-1.7 4.3-5.2 3.3-8.5-6.7-21.6-18.2-41.2-33.2-57.4-2.3-2.5-6-3.1-9-1.4l-25.8 14.9c-10.9-9.3-23.4-16.5-36.9-21.3v-29.8c0-3.4-2.4-6.4-5.7-7.1-22.3-5-45-4.8-66.2 0-3.3.7-5.7 3.7-5.7 7.1v29.8c-13.5 4.8-26 12-36.9 21.3l-25.8-14.9c-2.9-1.7-6.7-1.1-9 1.4-15 16.2-26.5 35.8-33.2 57.4-1 3.3.4 6.8 3.3 8.5l25.8 14.9c-2.6 14.1-2.6 28.5 0 42.6l-25.8 14.9c-3 1.7-4.3 5.2-3.3 8.5 6.7 21.6 18.2 41.1 33.2 57.4 2.3 2.5 6 3.1 9 1.4l25.8-14.9c10.9 9.3 23.4 16.5 36.9 21.3v29.8c0 3.4 2.4 6.4 5.7 7.1 22.3 5 45 4.8 66.2 0 3.3-.7 5.7-3.7 5.7-7.1v-29.8c13.5-4.8 26-12 36.9-21.3l25.8 14.9c2.9 1.7 6.7 1.1 9-1.4 15-16.2 26.5-35.8 33.2-57.4 1-3.3-.4-6.8-3.3-8.5l-25.8-14.9zM496 368.5c-26.8 0-48.5-21.8-48.5-48.5s21.8-48.5 48.5-48.5 48.5 21.8 48.5 48.5-21.7 48.5-48.5 48.5zM96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm224 32c1.9 0 3.7-.5 5.6-.6 8.3-21.7 20.5-42.1 36.3-59.2 7.4-8 17.9-12.6 28.9-12.6 6.9 0 13.7 1.8 19.6 5.3l7.9 4.6c.8-.5 1.6-.9 2.4-1.4 7-14.6 11.2-30.8 11.2-48 0-61.9-50.1-112-112-112S208 82.1 208 144c0 61.9 50.1 112 112 112zm105.2 194.5c-2.3-1.2-4.6-2.6-6.8-3.9-8.2 4.8-15.3 9.8-27.5 9.8-10.9 0-21.4-4.6-28.9-12.6-18.3-19.8-32.3-43.9-40.2-69.6-10.7-34.5 24.9-49.7 25.8-50.3-.1-2.6-.1-5.2 0-7.8l-7.9-4.6c-3.8-2.2-7-5-9.8-8.1-3.3.2-6.5.6-9.8.6-24.6 0-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h255.4c-3.7-6-6.2-12.8-6.2-20.3v-9.2zM173.1 274.6C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n};\nvar faUtensilSpoon = {\n prefix: 'fas',\n iconName: 'utensil-spoon',\n icon: [512, 512, [], \"f2e5\", \"M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z\"]\n};\nvar faUtensils = {\n prefix: 'fas',\n iconName: 'utensils',\n icon: [416, 512, [], \"f2e7\", \"M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z\"]\n};\nvar faVectorSquare = {\n prefix: 'fas',\n iconName: 'vector-square',\n icon: [512, 512, [], \"f5cb\", \"M512 128V32c0-17.67-14.33-32-32-32h-96c-17.67 0-32 14.33-32 32H160c0-17.67-14.33-32-32-32H32C14.33 0 0 14.33 0 32v96c0 17.67 14.33 32 32 32v192c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32h192c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96c0-17.67-14.33-32-32-32V160c17.67 0 32-14.33 32-32zm-96-64h32v32h-32V64zM64 64h32v32H64V64zm32 384H64v-32h32v32zm352 0h-32v-32h32v32zm-32-96h-32c-17.67 0-32 14.33-32 32v32H160v-32c0-17.67-14.33-32-32-32H96V160h32c17.67 0 32-14.33 32-32V96h192v32c0 17.67 14.33 32 32 32h32v192z\"]\n};\nvar faVenus = {\n prefix: 'fas',\n iconName: 'venus',\n icon: [288, 512, [], \"f221\", \"M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z\"]\n};\nvar faVenusDouble = {\n prefix: 'fas',\n iconName: 'venus-double',\n icon: [512, 512, [], \"f226\", \"M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z\"]\n};\nvar faVenusMars = {\n prefix: 'fas',\n iconName: 'venus-mars',\n icon: [576, 512, [], \"f228\", \"M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z\"]\n};\nvar faVial = {\n prefix: 'fas',\n iconName: 'vial',\n icon: [480, 512, [], \"f492\", \"M477.7 186.1L309.5 18.3c-3.1-3.1-8.2-3.1-11.3 0l-34 33.9c-3.1 3.1-3.1 8.2 0 11.3l11.2 11.1L33 316.5c-38.8 38.7-45.1 102-9.4 143.5 20.6 24 49.5 36 78.4 35.9 26.4 0 52.8-10 72.9-30.1l246.3-245.7 11.2 11.1c3.1 3.1 8.2 3.1 11.3 0l34-33.9c3.1-3 3.1-8.1 0-11.2zM318 256H161l148-147.7 78.5 78.3L318 256z\"]\n};\nvar faVials = {\n prefix: 'fas',\n iconName: 'vials',\n icon: [640, 512, [], \"f493\", \"M72 64h24v240c0 44.1 35.9 80 80 80s80-35.9 80-80V64h24c4.4 0 8-3.6 8-8V8c0-4.4-3.6-8-8-8H72c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm72 0h64v96h-64V64zm480 384H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM360 64h24v240c0 44.1 35.9 80 80 80s80-35.9 80-80V64h24c4.4 0 8-3.6 8-8V8c0-4.4-3.6-8-8-8H360c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm72 0h64v96h-64V64z\"]\n};\nvar faVideo = {\n prefix: 'fas',\n iconName: 'video',\n icon: [576, 512, [], \"f03d\", \"M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z\"]\n};\nvar faVideoSlash = {\n prefix: 'fas',\n iconName: 'video-slash',\n icon: [640, 512, [], \"f4e2\", \"M633.8 458.1l-55-42.5c15.4-1.4 29.2-13.7 29.2-31.1v-257c0-25.5-29.1-40.4-50.4-25.8L448 177.3v137.2l-32-24.7v-178c0-26.4-21.4-47.8-47.8-47.8H123.9L45.5 3.4C38.5-2 28.5-.8 23 6.2L3.4 31.4c-5.4 7-4.2 17 2.8 22.4L42.7 82 416 370.6l178.5 138c7 5.4 17 4.2 22.5-2.8l19.6-25.3c5.5-6.9 4.2-17-2.8-22.4zM32 400.2c0 26.4 21.4 47.8 47.8 47.8h288.4c11.2 0 21.4-4 29.6-10.5L32 154.7v245.5z\"]\n};\nvar faVihara = {\n prefix: 'fas',\n iconName: 'vihara',\n icon: [640, 512, [], \"f6a7\", \"M632.88 400.71L544 352v-64l55.16-17.69c11.79-5.9 11.79-22.72 0-28.62L480 192v-64l27.31-16.3c7.72-7.72 5.61-20.74-4.16-25.62L320 0 136.85 86.07c-9.77 4.88-11.88 17.9-4.16 25.62L160 128v64L40.84 241.69c-11.79 5.9-11.79 22.72 0 28.62L96 288v64L7.12 400.71c-5.42 3.62-7.7 9.63-7 15.29.62 5.01 3.57 9.75 8.72 12.33L64 448v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48h160v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48h160v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48l55.15-19.67c5.16-2.58 8.1-7.32 8.72-12.33.71-5.67-1.57-11.68-6.99-15.29zM224 128h192v64H224v-64zm-64 224v-64h320v64H160z\"]\n};\nvar faVoicemail = {\n prefix: 'fas',\n iconName: 'voicemail',\n icon: [640, 512, [], \"f897\", \"M496 128a144 144 0 0 0-119.74 224H263.74A144 144 0 1 0 144 416h352a144 144 0 0 0 0-288zM64 272a80 80 0 1 1 80 80 80 80 0 0 1-80-80zm432 80a80 80 0 1 1 80-80 80 80 0 0 1-80 80z\"]\n};\nvar faVolleyballBall = {\n prefix: 'fas',\n iconName: 'volleyball-ball',\n icon: [512, 512, [], \"f45f\", \"M231.39 243.48a285.56 285.56 0 0 0-22.7-105.7c-90.8 42.4-157.5 122.4-180.3 216.8a249 249 0 0 0 56.9 81.1 333.87 333.87 0 0 1 146.1-192.2zm-36.9-134.4a284.23 284.23 0 0 0-57.4-70.7c-91 49.8-144.8 152.9-125 262.2 33.4-83.1 98.4-152 182.4-191.5zm187.6 165.1c8.6-99.8-27.3-197.5-97.5-264.4-14.7-1.7-51.6-5.5-98.9 8.5A333.87 333.87 0 0 1 279.19 241a285 285 0 0 0 102.9 33.18zm-124.7 9.5a286.33 286.33 0 0 0-80.2 72.6c82 57.3 184.5 75.1 277.5 47.8a247.15 247.15 0 0 0 42.2-89.9 336.1 336.1 0 0 1-80.9 10.4c-54.6-.1-108.9-14.1-158.6-40.9zm-98.3 99.7c-15.2 26-25.7 54.4-32.1 84.2a247.07 247.07 0 0 0 289-22.1c-112.9 16.1-203.3-24.8-256.9-62.1zm180.3-360.6c55.3 70.4 82.5 161.2 74.6 253.6a286.59 286.59 0 0 0 89.7-14.2c0-2 .3-4 .3-6 0-107.8-68.7-199.1-164.6-233.4z\"]\n};\nvar faVolumeDown = {\n prefix: 'fas',\n iconName: 'volume-down',\n icon: [384, 512, [], \"f027\", \"M215.03 72.04L126.06 161H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V89.02c0-21.47-25.96-31.98-40.97-16.98zm123.2 108.08c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 229.28 336 242.62 336 257c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.87z\"]\n};\nvar faVolumeMute = {\n prefix: 'fas',\n iconName: 'volume-mute',\n icon: [512, 512, [], \"f6a9\", \"M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zM461.64 256l45.64-45.64c6.3-6.3 6.3-16.52 0-22.82l-22.82-22.82c-6.3-6.3-16.52-6.3-22.82 0L416 210.36l-45.64-45.64c-6.3-6.3-16.52-6.3-22.82 0l-22.82 22.82c-6.3 6.3-6.3 16.52 0 22.82L370.36 256l-45.63 45.63c-6.3 6.3-6.3 16.52 0 22.82l22.82 22.82c6.3 6.3 16.52 6.3 22.82 0L416 301.64l45.64 45.64c6.3 6.3 16.52 6.3 22.82 0l22.82-22.82c6.3-6.3 6.3-16.52 0-22.82L461.64 256z\"]\n};\nvar faVolumeOff = {\n prefix: 'fas',\n iconName: 'volume-off',\n icon: [256, 512, [], \"f026\", \"M215 71l-89 89H24a24 24 0 0 0-24 24v144a24 24 0 0 0 24 24h102.06L215 441c15 15 41 4.47 41-17V88c0-21.47-26-32-41-17z\"]\n};\nvar faVolumeUp = {\n prefix: 'fas',\n iconName: 'volume-up',\n icon: [576, 512, [], \"f028\", \"M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zm233.32-51.08c-11.17-7.33-26.18-4.24-33.51 6.95-7.34 11.17-4.22 26.18 6.95 33.51 66.27 43.49 105.82 116.6 105.82 195.58 0 78.98-39.55 152.09-105.82 195.58-11.17 7.32-14.29 22.34-6.95 33.5 7.04 10.71 21.93 14.56 33.51 6.95C528.27 439.58 576 351.33 576 256S528.27 72.43 448.35 19.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.54 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z\"]\n};\nvar faVoteYea = {\n prefix: 'fas',\n iconName: 'vote-yea',\n icon: [640, 512, [], \"f772\", \"M608 320h-64v64h22.4c5.3 0 9.6 3.6 9.6 8v16c0 4.4-4.3 8-9.6 8H73.6c-5.3 0-9.6-3.6-9.6-8v-16c0-4.4 4.3-8 9.6-8H96v-64H32c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32h576c17.7 0 32-14.3 32-32v-96c0-17.7-14.3-32-32-32zm-96 64V64.3c0-17.9-14.5-32.3-32.3-32.3H160.4C142.5 32 128 46.5 128 64.3V384h384zM211.2 202l25.5-25.3c4.2-4.2 11-4.2 15.2.1l41.3 41.6 95.2-94.4c4.2-4.2 11-4.2 15.2.1l25.3 25.5c4.2 4.2 4.2 11-.1 15.2L300.5 292c-4.2 4.2-11 4.2-15.2-.1l-74.1-74.7c-4.3-4.2-4.2-11 0-15.2z\"]\n};\nvar faVrCardboard = {\n prefix: 'fas',\n iconName: 'vr-cardboard',\n icon: [640, 512, [], \"f729\", \"M608 64H32C14.33 64 0 78.33 0 96v320c0 17.67 14.33 32 32 32h160.22c25.19 0 48.03-14.77 58.36-37.74l27.74-61.64C286.21 331.08 302.35 320 320 320s33.79 11.08 41.68 28.62l27.74 61.64C399.75 433.23 422.6 448 447.78 448H608c17.67 0 32-14.33 32-32V96c0-17.67-14.33-32-32-32zM160 304c-35.35 0-64-28.65-64-64s28.65-64 64-64 64 28.65 64 64-28.65 64-64 64zm320 0c-35.35 0-64-28.65-64-64s28.65-64 64-64 64 28.65 64 64-28.65 64-64 64z\"]\n};\nvar faWalking = {\n prefix: 'fas',\n iconName: 'walking',\n icon: [320, 512, [], \"f554\", \"M208 96c26.5 0 48-21.5 48-48S234.5 0 208 0s-48 21.5-48 48 21.5 48 48 48zm94.5 149.1l-23.3-11.8-9.7-29.4c-14.7-44.6-55.7-75.8-102.2-75.9-36-.1-55.9 10.1-93.3 25.2-21.6 8.7-39.3 25.2-49.7 46.2L17.6 213c-7.8 15.8-1.5 35 14.2 42.9 15.6 7.9 34.6 1.5 42.5-14.3L81 228c3.5-7 9.3-12.5 16.5-15.4l26.8-10.8-15.2 60.7c-5.2 20.8.4 42.9 14.9 58.8l59.9 65.4c7.2 7.9 12.3 17.4 14.9 27.7l18.3 73.3c4.3 17.1 21.7 27.6 38.8 23.3 17.1-4.3 27.6-21.7 23.3-38.8l-22.2-89c-2.6-10.3-7.7-19.9-14.9-27.7l-45.5-49.7 17.2-68.7 5.5 16.5c5.3 16.1 16.7 29.4 31.7 37l23.3 11.8c15.6 7.9 34.6 1.5 42.5-14.3 7.7-15.7 1.4-35.1-14.3-43zM73.6 385.8c-3.2 8.1-8 15.4-14.2 21.5l-50 50.1c-12.5 12.5-12.5 32.8 0 45.3s32.7 12.5 45.2 0l59.4-59.4c6.1-6.1 10.9-13.4 14.2-21.5l13.5-33.8c-55.3-60.3-38.7-41.8-47.4-53.7l-20.7 51.5z\"]\n};\nvar faWallet = {\n prefix: 'fas',\n iconName: 'wallet',\n icon: [512, 512, [], \"f555\", \"M461.2 128H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h384c8.84 0 16-7.16 16-16 0-26.51-21.49-48-48-48H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h397.2c28.02 0 50.8-21.53 50.8-48V176c0-26.47-22.78-48-50.8-48zM416 336c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z\"]\n};\nvar faWarehouse = {\n prefix: 'fas',\n iconName: 'warehouse',\n icon: [640, 512, [], \"f494\", \"M504 352H136.4c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0 96H136.1c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0-192H136.6c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm106.5-139L338.4 3.7a48.15 48.15 0 0 0-36.9 0L29.5 117C11.7 124.5 0 141.9 0 161.3V504c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V256c0-17.6 14.6-32 32.6-32h382.8c18 0 32.6 14.4 32.6 32v248c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V161.3c0-19.4-11.7-36.8-29.5-44.3z\"]\n};\nvar faWater = {\n prefix: 'fas',\n iconName: 'water',\n icon: [576, 512, [], \"f773\", \"M562.1 383.9c-21.5-2.4-42.1-10.5-57.9-22.9-14.1-11.1-34.2-11.3-48.2 0-37.9 30.4-107.2 30.4-145.7-1.5-13.5-11.2-33-9.1-46.7 1.8-38 30.1-106.9 30-145.2-1.7-13.5-11.2-33.3-8.9-47.1 2-15.5 12.2-36 20.1-57.7 22.4-7.9.8-13.6 7.8-13.6 15.7v32.2c0 9.1 7.6 16.8 16.7 16 28.8-2.5 56.1-11.4 79.4-25.9 56.5 34.6 137 34.1 192 0 56.5 34.6 137 34.1 192 0 23.3 14.2 50.9 23.3 79.1 25.8 9.1.8 16.7-6.9 16.7-16v-31.6c.1-8-5.7-15.4-13.8-16.3zm0-144c-21.5-2.4-42.1-10.5-57.9-22.9-14.1-11.1-34.2-11.3-48.2 0-37.9 30.4-107.2 30.4-145.7-1.5-13.5-11.2-33-9.1-46.7 1.8-38 30.1-106.9 30-145.2-1.7-13.5-11.2-33.3-8.9-47.1 2-15.5 12.2-36 20.1-57.7 22.4-7.9.8-13.6 7.8-13.6 15.7v32.2c0 9.1 7.6 16.8 16.7 16 28.8-2.5 56.1-11.4 79.4-25.9 56.5 34.6 137 34.1 192 0 56.5 34.6 137 34.1 192 0 23.3 14.2 50.9 23.3 79.1 25.8 9.1.8 16.7-6.9 16.7-16v-31.6c.1-8-5.7-15.4-13.8-16.3zm0-144C540.6 93.4 520 85.4 504.2 73 490.1 61.9 470 61.7 456 73c-37.9 30.4-107.2 30.4-145.7-1.5-13.5-11.2-33-9.1-46.7 1.8-38 30.1-106.9 30-145.2-1.7-13.5-11.2-33.3-8.9-47.1 2-15.5 12.2-36 20.1-57.7 22.4-7.9.8-13.6 7.8-13.6 15.7v32.2c0 9.1 7.6 16.8 16.7 16 28.8-2.5 56.1-11.4 79.4-25.9 56.5 34.6 137 34.1 192 0 56.5 34.6 137 34.1 192 0 23.3 14.2 50.9 23.3 79.1 25.8 9.1.8 16.7-6.9 16.7-16v-31.6c.1-8-5.7-15.4-13.8-16.3z\"]\n};\nvar faWaveSquare = {\n prefix: 'fas',\n iconName: 'wave-square',\n icon: [640, 512, [], \"f83e\", \"M476 480H324a36 36 0 0 1-36-36V96h-96v156a36 36 0 0 1-36 36H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h112V68a36 36 0 0 1 36-36h152a36 36 0 0 1 36 36v348h96V260a36 36 0 0 1 36-36h140a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H512v156a36 36 0 0 1-36 36z\"]\n};\nvar faWeight = {\n prefix: 'fas',\n iconName: 'weight',\n icon: [512, 512, [], \"f496\", \"M448 64h-25.98C438.44 92.28 448 125.01 448 160c0 105.87-86.13 192-192 192S64 265.87 64 160c0-34.99 9.56-67.72 25.98-96H64C28.71 64 0 92.71 0 128v320c0 35.29 28.71 64 64 64h384c35.29 0 64-28.71 64-64V128c0-35.29-28.71-64-64-64zM256 320c88.37 0 160-71.63 160-160S344.37 0 256 0 96 71.63 96 160s71.63 160 160 160zm-.3-151.94l33.58-78.36c3.5-8.17 12.94-11.92 21.03-8.41 8.12 3.48 11.88 12.89 8.41 21l-33.67 78.55C291.73 188 296 197.45 296 208c0 22.09-17.91 40-40 40s-40-17.91-40-40c0-21.98 17.76-39.77 39.7-39.94z\"]\n};\nvar faWeightHanging = {\n prefix: 'fas',\n iconName: 'weight-hanging',\n icon: [512, 512, [], \"f5cd\", \"M510.28 445.86l-73.03-292.13c-3.8-15.19-16.44-25.72-30.87-25.72h-60.25c3.57-10.05 5.88-20.72 5.88-32 0-53.02-42.98-96-96-96s-96 42.98-96 96c0 11.28 2.3 21.95 5.88 32h-60.25c-14.43 0-27.08 10.54-30.87 25.72L1.72 445.86C-6.61 479.17 16.38 512 48.03 512h415.95c31.64 0 54.63-32.83 46.3-66.14zM256 128c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32z\"]\n};\nvar faWheelchair = {\n prefix: 'fas',\n iconName: 'wheelchair',\n icon: [512, 512, [], \"f193\", \"M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z\"]\n};\nvar faWifi = {\n prefix: 'fas',\n iconName: 'wifi',\n icon: [640, 512, [], \"f1eb\", \"M634.91 154.88C457.74-8.99 182.19-8.93 5.09 154.88c-6.66 6.16-6.79 16.59-.35 22.98l34.24 33.97c6.14 6.1 16.02 6.23 22.4.38 145.92-133.68 371.3-133.71 517.25 0 6.38 5.85 16.26 5.71 22.4-.38l34.24-33.97c6.43-6.39 6.3-16.82-.36-22.98zM320 352c-35.35 0-64 28.65-64 64s28.65 64 64 64 64-28.65 64-64-28.65-64-64-64zm202.67-83.59c-115.26-101.93-290.21-101.82-405.34 0-6.9 6.1-7.12 16.69-.57 23.15l34.44 33.99c6 5.92 15.66 6.32 22.05.8 83.95-72.57 209.74-72.41 293.49 0 6.39 5.52 16.05 5.13 22.05-.8l34.44-33.99c6.56-6.46 6.33-17.06-.56-23.15z\"]\n};\nvar faWind = {\n prefix: 'fas',\n iconName: 'wind',\n icon: [512, 512, [], \"f72e\", \"M156.7 256H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h142.2c15.9 0 30.8 10.9 33.4 26.6 3.3 20-12.1 37.4-31.6 37.4-14.1 0-26.1-9.2-30.4-21.9-2.1-6.3-8.6-10.1-15.2-10.1H81.6c-9.8 0-17.7 8.8-15.9 18.4 8.6 44.1 47.6 77.6 94.2 77.6 57.1 0 102.7-50.1 95.2-108.6C249 291 205.4 256 156.7 256zM16 224h336c59.7 0 106.8-54.8 93.8-116.7-7.6-36.2-36.9-65.5-73.1-73.1-55.4-11.6-105.1 24.9-114.9 75.5-1.9 9.6 6.1 18.3 15.8 18.3h32.8c6.7 0 13.1-3.8 15.2-10.1C325.9 105.2 337.9 96 352 96c19.4 0 34.9 17.4 31.6 37.4-2.6 15.7-17.4 26.6-33.4 26.6H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16zm384 32H243.7c19.3 16.6 33.2 38.8 39.8 64H400c26.5 0 48 21.5 48 48s-21.5 48-48 48c-17.9 0-33.3-9.9-41.6-24.4-2.9-5-8.7-7.6-14.5-7.6h-33.8c-10.9 0-19 10.8-15.3 21.1 17.8 50.6 70.5 84.8 129.4 72.3 41.2-8.7 75.1-41.6 84.7-82.7C526 321.5 470.5 256 400 256z\"]\n};\nvar faWindowClose = {\n prefix: 'fas',\n iconName: 'window-close',\n icon: [512, 512, [], \"f410\", \"M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z\"]\n};\nvar faWindowMaximize = {\n prefix: 'fas',\n iconName: 'window-maximize',\n icon: [512, 512, [], \"f2d0\", \"M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z\"]\n};\nvar faWindowMinimize = {\n prefix: 'fas',\n iconName: 'window-minimize',\n icon: [512, 512, [], \"f2d1\", \"M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z\"]\n};\nvar faWindowRestore = {\n prefix: 'fas',\n iconName: 'window-restore',\n icon: [512, 512, [], \"f2d2\", \"M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z\"]\n};\nvar faWineBottle = {\n prefix: 'fas',\n iconName: 'wine-bottle',\n icon: [512, 512, [], \"f72f\", \"M507.31 72.57L439.43 4.69c-6.25-6.25-16.38-6.25-22.63 0l-22.63 22.63c-6.25 6.25-6.25 16.38 0 22.63l-76.67 76.67c-46.58-19.7-102.4-10.73-140.37 27.23L18.75 312.23c-24.99 24.99-24.99 65.52 0 90.51l90.51 90.51c24.99 24.99 65.52 24.99 90.51 0l158.39-158.39c37.96-37.96 46.93-93.79 27.23-140.37l76.67-76.67c6.25 6.25 16.38 6.25 22.63 0l22.63-22.63c6.24-6.24 6.24-16.37-.01-22.62zM179.22 423.29l-90.51-90.51 122.04-122.04 90.51 90.51-122.04 122.04z\"]\n};\nvar faWineGlass = {\n prefix: 'fas',\n iconName: 'wine-glass',\n icon: [288, 512, [], \"f4e3\", \"M216 464h-40V346.81c68.47-15.89 118.05-79.91 111.4-154.16l-15.95-178.1C270.71 6.31 263.9 0 255.74 0H32.26c-8.15 0-14.97 6.31-15.7 14.55L.6 192.66C-6.05 266.91 43.53 330.93 112 346.82V464H72c-22.09 0-40 17.91-40 40 0 4.42 3.58 8 8 8h208c4.42 0 8-3.58 8-8 0-22.09-17.91-40-40-40z\"]\n};\nvar faWineGlassAlt = {\n prefix: 'fas',\n iconName: 'wine-glass-alt',\n icon: [288, 512, [], \"f5ce\", \"M216 464h-40V346.81c68.47-15.89 118.05-79.91 111.4-154.16l-15.95-178.1C270.71 6.31 263.9 0 255.74 0H32.26c-8.15 0-14.97 6.31-15.7 14.55L.6 192.66C-6.05 266.91 43.53 330.93 112 346.82V464H72c-22.09 0-40 17.91-40 40 0 4.42 3.58 8 8 8h208c4.42 0 8-3.58 8-8 0-22.09-17.91-40-40-40zM61.75 48h164.5l7.17 80H54.58l7.17-80z\"]\n};\nvar faWonSign = {\n prefix: 'fas',\n iconName: 'won-sign',\n icon: [576, 512, [], \"f159\", \"M564 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-48l18.6-80.6c1.7-7.5-4-14.7-11.7-14.7h-46.1c-5.7 0-10.6 4-11.7 9.5L450.7 128H340.8l-19.7-86c-1.3-5.5-6.1-9.3-11.7-9.3h-44c-5.6 0-10.4 3.8-11.7 9.3l-20 86H125l-17.5-85.7c-1.1-5.6-6.1-9.6-11.8-9.6H53.6c-7.7 0-13.4 7.1-11.7 14.6L60 128H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h62.3l7.2 32H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h83.9l40.9 182.6c1.2 5.5 6.1 9.4 11.7 9.4h56.8c5.6 0 10.4-3.9 11.7-9.3L259.3 288h55.1l42.4 182.7c1.3 5.4 6.1 9.3 11.7 9.3h56.8c5.6 0 10.4-3.9 11.7-9.3L479.1 288H564c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-70.1l7.4-32zM183.8 342c-6.2 25.8-6.8 47.2-7.3 47.2h-1.1s-1.7-22-6.8-47.2l-11-54h38.8zm27.5-118h-66.8l-6.5-32h80.8zm62.9 0l2-8.6c1.9-8 3.5-16 4.8-23.4h11.8c1.3 7.4 2.9 15.4 4.8 23.4l2 8.6zm130.9 118c-5.1 25.2-6.8 47.2-6.8 47.2h-1.1c-.6 0-1.1-21.4-7.3-47.2l-12.4-54h39.1zm25.2-118h-67.4l-7.3-32h81.6z\"]\n};\nvar faWrench = {\n prefix: 'fas',\n iconName: 'wrench',\n icon: [512, 512, [], \"f0ad\", \"M507.73 109.1c-2.24-9.03-13.54-12.09-20.12-5.51l-74.36 74.36-67.88-11.31-11.31-67.88 74.36-74.36c6.62-6.62 3.43-17.9-5.66-20.16-47.38-11.74-99.55.91-136.58 37.93-39.64 39.64-50.55 97.1-34.05 147.2L18.74 402.76c-24.99 24.99-24.99 65.51 0 90.5 24.99 24.99 65.51 24.99 90.5 0l213.21-213.21c50.12 16.71 107.47 5.68 147.37-34.22 37.07-37.07 49.7-89.32 37.91-136.73zM64 472c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"]\n};\nvar faXRay = {\n prefix: 'fas',\n iconName: 'x-ray',\n icon: [640, 512, [], \"f497\", \"M240 384c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm160 32c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zM624 0H16C7.2 0 0 7.2 0 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16V16c0-8.8-7.2-16-16-16zm0 448h-48V96H64v352H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zM480 248c0 4.4-3.6 8-8 8H336v32h104c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H336v32h64c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48v-16h-64v16c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48h64v-32H200c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h104v-32H168c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h136v-32H200c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h104v-24c0-4.4 3.6-8 8-8h16c4.4 0 8 3.6 8 8v24h104c4.4 0 8 3.6 8 8v16c0 4.4-3.6 8-8 8H336v32h136c4.4 0 8 3.6 8 8v16z\"]\n};\nvar faYenSign = {\n prefix: 'fas',\n iconName: 'yen-sign',\n icon: [384, 512, [], \"f157\", \"M351.2 32h-65.3c-4.6 0-8.8 2.6-10.8 6.7l-55.4 113.2c-14.5 34.7-27.1 71.9-27.1 71.9h-1.3s-12.6-37.2-27.1-71.9L108.8 38.7c-2-4.1-6.2-6.7-10.8-6.7H32.8c-9.1 0-14.8 9.7-10.6 17.6L102.3 200H44c-6.6 0-12 5.4-12 12v32c0 6.6 5.4 12 12 12h88.2l19.8 37.2V320H44c-6.6 0-12 5.4-12 12v32c0 6.6 5.4 12 12 12h108v92c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12v-92h108c6.6 0 12-5.4 12-12v-32c0-6.6-5.4-12-12-12H232v-26.8l19.8-37.2H340c6.6 0 12-5.4 12-12v-32c0-6.6-5.4-12-12-12h-58.3l80.1-150.4c4.3-7.9-1.5-17.6-10.6-17.6z\"]\n};\nvar faYinYang = {\n prefix: 'fas',\n iconName: 'yin-yang',\n icon: [496, 512, [], \"f6ad\", \"M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 376c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm0-128c-53.02 0-96 42.98-96 96s42.98 96 96 96c-106.04 0-192-85.96-192-192S141.96 64 248 64c53.02 0 96 42.98 96 96s-42.98 96-96 96zm0-128c-17.67 0-32 14.33-32 32s14.33 32 32 32 32-14.33 32-32-14.33-32-32-32z\"]\n};\nvar _iconsCache = {\n faAd: faAd,\n faAddressBook: faAddressBook,\n faAddressCard: faAddressCard,\n faAdjust: faAdjust,\n faAirFreshener: faAirFreshener,\n faAlignCenter: faAlignCenter,\n faAlignJustify: faAlignJustify,\n faAlignLeft: faAlignLeft,\n faAlignRight: faAlignRight,\n faAllergies: faAllergies,\n faAmbulance: faAmbulance,\n faAmericanSignLanguageInterpreting: faAmericanSignLanguageInterpreting,\n faAnchor: faAnchor,\n faAngleDoubleDown: faAngleDoubleDown,\n faAngleDoubleLeft: faAngleDoubleLeft,\n faAngleDoubleRight: faAngleDoubleRight,\n faAngleDoubleUp: faAngleDoubleUp,\n faAngleDown: faAngleDown,\n faAngleLeft: faAngleLeft,\n faAngleRight: faAngleRight,\n faAngleUp: faAngleUp,\n faAngry: faAngry,\n faAnkh: faAnkh,\n faAppleAlt: faAppleAlt,\n faArchive: faArchive,\n faArchway: faArchway,\n faArrowAltCircleDown: faArrowAltCircleDown,\n faArrowAltCircleLeft: faArrowAltCircleLeft,\n faArrowAltCircleRight: faArrowAltCircleRight,\n faArrowAltCircleUp: faArrowAltCircleUp,\n faArrowCircleDown: faArrowCircleDown,\n faArrowCircleLeft: faArrowCircleLeft,\n faArrowCircleRight: faArrowCircleRight,\n faArrowCircleUp: faArrowCircleUp,\n faArrowDown: faArrowDown,\n faArrowLeft: faArrowLeft,\n faArrowRight: faArrowRight,\n faArrowUp: faArrowUp,\n faArrowsAlt: faArrowsAlt,\n faArrowsAltH: faArrowsAltH,\n faArrowsAltV: faArrowsAltV,\n faAssistiveListeningSystems: faAssistiveListeningSystems,\n faAsterisk: faAsterisk,\n faAt: faAt,\n faAtlas: faAtlas,\n faAtom: faAtom,\n faAudioDescription: faAudioDescription,\n faAward: faAward,\n faBaby: faBaby,\n faBabyCarriage: faBabyCarriage,\n faBackspace: faBackspace,\n faBackward: faBackward,\n faBacon: faBacon,\n faBalanceScale: faBalanceScale,\n faBalanceScaleLeft: faBalanceScaleLeft,\n faBalanceScaleRight: faBalanceScaleRight,\n faBan: faBan,\n faBandAid: faBandAid,\n faBarcode: faBarcode,\n faBars: faBars,\n faBaseballBall: faBaseballBall,\n faBasketballBall: faBasketballBall,\n faBath: faBath,\n faBatteryEmpty: faBatteryEmpty,\n faBatteryFull: faBatteryFull,\n faBatteryHalf: faBatteryHalf,\n faBatteryQuarter: faBatteryQuarter,\n faBatteryThreeQuarters: faBatteryThreeQuarters,\n faBed: faBed,\n faBeer: faBeer,\n faBell: faBell,\n faBellSlash: faBellSlash,\n faBezierCurve: faBezierCurve,\n faBible: faBible,\n faBicycle: faBicycle,\n faBiking: faBiking,\n faBinoculars: faBinoculars,\n faBiohazard: faBiohazard,\n faBirthdayCake: faBirthdayCake,\n faBlender: faBlender,\n faBlenderPhone: faBlenderPhone,\n faBlind: faBlind,\n faBlog: faBlog,\n faBold: faBold,\n faBolt: faBolt,\n faBomb: faBomb,\n faBone: faBone,\n faBong: faBong,\n faBook: faBook,\n faBookDead: faBookDead,\n faBookMedical: faBookMedical,\n faBookOpen: faBookOpen,\n faBookReader: faBookReader,\n faBookmark: faBookmark,\n faBorderAll: faBorderAll,\n faBorderNone: faBorderNone,\n faBorderStyle: faBorderStyle,\n faBowlingBall: faBowlingBall,\n faBox: faBox,\n faBoxOpen: faBoxOpen,\n faBoxes: faBoxes,\n faBraille: faBraille,\n faBrain: faBrain,\n faBreadSlice: faBreadSlice,\n faBriefcase: faBriefcase,\n faBriefcaseMedical: faBriefcaseMedical,\n faBroadcastTower: faBroadcastTower,\n faBroom: faBroom,\n faBrush: faBrush,\n faBug: faBug,\n faBuilding: faBuilding,\n faBullhorn: faBullhorn,\n faBullseye: faBullseye,\n faBurn: faBurn,\n faBus: faBus,\n faBusAlt: faBusAlt,\n faBusinessTime: faBusinessTime,\n faCalculator: faCalculator,\n faCalendar: faCalendar,\n faCalendarAlt: faCalendarAlt,\n faCalendarCheck: faCalendarCheck,\n faCalendarDay: faCalendarDay,\n faCalendarMinus: faCalendarMinus,\n faCalendarPlus: faCalendarPlus,\n faCalendarTimes: faCalendarTimes,\n faCalendarWeek: faCalendarWeek,\n faCamera: faCamera,\n faCameraRetro: faCameraRetro,\n faCampground: faCampground,\n faCandyCane: faCandyCane,\n faCannabis: faCannabis,\n faCapsules: faCapsules,\n faCar: faCar,\n faCarAlt: faCarAlt,\n faCarBattery: faCarBattery,\n faCarCrash: faCarCrash,\n faCarSide: faCarSide,\n faCaretDown: faCaretDown,\n faCaretLeft: faCaretLeft,\n faCaretRight: faCaretRight,\n faCaretSquareDown: faCaretSquareDown,\n faCaretSquareLeft: faCaretSquareLeft,\n faCaretSquareRight: faCaretSquareRight,\n faCaretSquareUp: faCaretSquareUp,\n faCaretUp: faCaretUp,\n faCarrot: faCarrot,\n faCartArrowDown: faCartArrowDown,\n faCartPlus: faCartPlus,\n faCashRegister: faCashRegister,\n faCat: faCat,\n faCertificate: faCertificate,\n faChair: faChair,\n faChalkboard: faChalkboard,\n faChalkboardTeacher: faChalkboardTeacher,\n faChargingStation: faChargingStation,\n faChartArea: faChartArea,\n faChartBar: faChartBar,\n faChartLine: faChartLine,\n faChartPie: faChartPie,\n faCheck: faCheck,\n faCheckCircle: faCheckCircle,\n faCheckDouble: faCheckDouble,\n faCheckSquare: faCheckSquare,\n faCheese: faCheese,\n faChess: faChess,\n faChessBishop: faChessBishop,\n faChessBoard: faChessBoard,\n faChessKing: faChessKing,\n faChessKnight: faChessKnight,\n faChessPawn: faChessPawn,\n faChessQueen: faChessQueen,\n faChessRook: faChessRook,\n faChevronCircleDown: faChevronCircleDown,\n faChevronCircleLeft: faChevronCircleLeft,\n faChevronCircleRight: faChevronCircleRight,\n faChevronCircleUp: faChevronCircleUp,\n faChevronDown: faChevronDown,\n faChevronLeft: faChevronLeft,\n faChevronRight: faChevronRight,\n faChevronUp: faChevronUp,\n faChild: faChild,\n faChurch: faChurch,\n faCircle: faCircle,\n faCircleNotch: faCircleNotch,\n faCity: faCity,\n faClinicMedical: faClinicMedical,\n faClipboard: faClipboard,\n faClipboardCheck: faClipboardCheck,\n faClipboardList: faClipboardList,\n faClock: faClock,\n faClone: faClone,\n faClosedCaptioning: faClosedCaptioning,\n faCloud: faCloud,\n faCloudDownloadAlt: faCloudDownloadAlt,\n faCloudMeatball: faCloudMeatball,\n faCloudMoon: faCloudMoon,\n faCloudMoonRain: faCloudMoonRain,\n faCloudRain: faCloudRain,\n faCloudShowersHeavy: faCloudShowersHeavy,\n faCloudSun: faCloudSun,\n faCloudSunRain: faCloudSunRain,\n faCloudUploadAlt: faCloudUploadAlt,\n faCocktail: faCocktail,\n faCode: faCode,\n faCodeBranch: faCodeBranch,\n faCoffee: faCoffee,\n faCog: faCog,\n faCogs: faCogs,\n faCoins: faCoins,\n faColumns: faColumns,\n faComment: faComment,\n faCommentAlt: faCommentAlt,\n faCommentDollar: faCommentDollar,\n faCommentDots: faCommentDots,\n faCommentMedical: faCommentMedical,\n faCommentSlash: faCommentSlash,\n faComments: faComments,\n faCommentsDollar: faCommentsDollar,\n faCompactDisc: faCompactDisc,\n faCompass: faCompass,\n faCompress: faCompress,\n faCompressArrowsAlt: faCompressArrowsAlt,\n faConciergeBell: faConciergeBell,\n faCookie: faCookie,\n faCookieBite: faCookieBite,\n faCopy: faCopy,\n faCopyright: faCopyright,\n faCouch: faCouch,\n faCreditCard: faCreditCard,\n faCrop: faCrop,\n faCropAlt: faCropAlt,\n faCross: faCross,\n faCrosshairs: faCrosshairs,\n faCrow: faCrow,\n faCrown: faCrown,\n faCrutch: faCrutch,\n faCube: faCube,\n faCubes: faCubes,\n faCut: faCut,\n faDatabase: faDatabase,\n faDeaf: faDeaf,\n faDemocrat: faDemocrat,\n faDesktop: faDesktop,\n faDharmachakra: faDharmachakra,\n faDiagnoses: faDiagnoses,\n faDice: faDice,\n faDiceD20: faDiceD20,\n faDiceD6: faDiceD6,\n faDiceFive: faDiceFive,\n faDiceFour: faDiceFour,\n faDiceOne: faDiceOne,\n faDiceSix: faDiceSix,\n faDiceThree: faDiceThree,\n faDiceTwo: faDiceTwo,\n faDigitalTachograph: faDigitalTachograph,\n faDirections: faDirections,\n faDivide: faDivide,\n faDizzy: faDizzy,\n faDna: faDna,\n faDog: faDog,\n faDollarSign: faDollarSign,\n faDolly: faDolly,\n faDollyFlatbed: faDollyFlatbed,\n faDonate: faDonate,\n faDoorClosed: faDoorClosed,\n faDoorOpen: faDoorOpen,\n faDotCircle: faDotCircle,\n faDove: faDove,\n faDownload: faDownload,\n faDraftingCompass: faDraftingCompass,\n faDragon: faDragon,\n faDrawPolygon: faDrawPolygon,\n faDrum: faDrum,\n faDrumSteelpan: faDrumSteelpan,\n faDrumstickBite: faDrumstickBite,\n faDumbbell: faDumbbell,\n faDumpster: faDumpster,\n faDumpsterFire: faDumpsterFire,\n faDungeon: faDungeon,\n faEdit: faEdit,\n faEgg: faEgg,\n faEject: faEject,\n faEllipsisH: faEllipsisH,\n faEllipsisV: faEllipsisV,\n faEnvelope: faEnvelope,\n faEnvelopeOpen: faEnvelopeOpen,\n faEnvelopeOpenText: faEnvelopeOpenText,\n faEnvelopeSquare: faEnvelopeSquare,\n faEquals: faEquals,\n faEraser: faEraser,\n faEthernet: faEthernet,\n faEuroSign: faEuroSign,\n faExchangeAlt: faExchangeAlt,\n faExclamation: faExclamation,\n faExclamationCircle: faExclamationCircle,\n faExclamationTriangle: faExclamationTriangle,\n faExpand: faExpand,\n faExpandArrowsAlt: faExpandArrowsAlt,\n faExternalLinkAlt: faExternalLinkAlt,\n faExternalLinkSquareAlt: faExternalLinkSquareAlt,\n faEye: faEye,\n faEyeDropper: faEyeDropper,\n faEyeSlash: faEyeSlash,\n faFan: faFan,\n faFastBackward: faFastBackward,\n faFastForward: faFastForward,\n faFax: faFax,\n faFeather: faFeather,\n faFeatherAlt: faFeatherAlt,\n faFemale: faFemale,\n faFighterJet: faFighterJet,\n faFile: faFile,\n faFileAlt: faFileAlt,\n faFileArchive: faFileArchive,\n faFileAudio: faFileAudio,\n faFileCode: faFileCode,\n faFileContract: faFileContract,\n faFileCsv: faFileCsv,\n faFileDownload: faFileDownload,\n faFileExcel: faFileExcel,\n faFileExport: faFileExport,\n faFileImage: faFileImage,\n faFileImport: faFileImport,\n faFileInvoice: faFileInvoice,\n faFileInvoiceDollar: faFileInvoiceDollar,\n faFileMedical: faFileMedical,\n faFileMedicalAlt: faFileMedicalAlt,\n faFilePdf: faFilePdf,\n faFilePowerpoint: faFilePowerpoint,\n faFilePrescription: faFilePrescription,\n faFileSignature: faFileSignature,\n faFileUpload: faFileUpload,\n faFileVideo: faFileVideo,\n faFileWord: faFileWord,\n faFill: faFill,\n faFillDrip: faFillDrip,\n faFilm: faFilm,\n faFilter: faFilter,\n faFingerprint: faFingerprint,\n faFire: faFire,\n faFireAlt: faFireAlt,\n faFireExtinguisher: faFireExtinguisher,\n faFirstAid: faFirstAid,\n faFish: faFish,\n faFistRaised: faFistRaised,\n faFlag: faFlag,\n faFlagCheckered: faFlagCheckered,\n faFlagUsa: faFlagUsa,\n faFlask: faFlask,\n faFlushed: faFlushed,\n faFolder: faFolder,\n faFolderMinus: faFolderMinus,\n faFolderOpen: faFolderOpen,\n faFolderPlus: faFolderPlus,\n faFont: faFont,\n faFontAwesomeLogoFull: faFontAwesomeLogoFull,\n faFootballBall: faFootballBall,\n faForward: faForward,\n faFrog: faFrog,\n faFrown: faFrown,\n faFrownOpen: faFrownOpen,\n faFunnelDollar: faFunnelDollar,\n faFutbol: faFutbol,\n faGamepad: faGamepad,\n faGasPump: faGasPump,\n faGavel: faGavel,\n faGem: faGem,\n faGenderless: faGenderless,\n faGhost: faGhost,\n faGift: faGift,\n faGifts: faGifts,\n faGlassCheers: faGlassCheers,\n faGlassMartini: faGlassMartini,\n faGlassMartiniAlt: faGlassMartiniAlt,\n faGlassWhiskey: faGlassWhiskey,\n faGlasses: faGlasses,\n faGlobe: faGlobe,\n faGlobeAfrica: faGlobeAfrica,\n faGlobeAmericas: faGlobeAmericas,\n faGlobeAsia: faGlobeAsia,\n faGlobeEurope: faGlobeEurope,\n faGolfBall: faGolfBall,\n faGopuram: faGopuram,\n faGraduationCap: faGraduationCap,\n faGreaterThan: faGreaterThan,\n faGreaterThanEqual: faGreaterThanEqual,\n faGrimace: faGrimace,\n faGrin: faGrin,\n faGrinAlt: faGrinAlt,\n faGrinBeam: faGrinBeam,\n faGrinBeamSweat: faGrinBeamSweat,\n faGrinHearts: faGrinHearts,\n faGrinSquint: faGrinSquint,\n faGrinSquintTears: faGrinSquintTears,\n faGrinStars: faGrinStars,\n faGrinTears: faGrinTears,\n faGrinTongue: faGrinTongue,\n faGrinTongueSquint: faGrinTongueSquint,\n faGrinTongueWink: faGrinTongueWink,\n faGrinWink: faGrinWink,\n faGripHorizontal: faGripHorizontal,\n faGripLines: faGripLines,\n faGripLinesVertical: faGripLinesVertical,\n faGripVertical: faGripVertical,\n faGuitar: faGuitar,\n faHSquare: faHSquare,\n faHamburger: faHamburger,\n faHammer: faHammer,\n faHamsa: faHamsa,\n faHandHolding: faHandHolding,\n faHandHoldingHeart: faHandHoldingHeart,\n faHandHoldingUsd: faHandHoldingUsd,\n faHandLizard: faHandLizard,\n faHandMiddleFinger: faHandMiddleFinger,\n faHandPaper: faHandPaper,\n faHandPeace: faHandPeace,\n faHandPointDown: faHandPointDown,\n faHandPointLeft: faHandPointLeft,\n faHandPointRight: faHandPointRight,\n faHandPointUp: faHandPointUp,\n faHandPointer: faHandPointer,\n faHandRock: faHandRock,\n faHandScissors: faHandScissors,\n faHandSpock: faHandSpock,\n faHands: faHands,\n faHandsHelping: faHandsHelping,\n faHandshake: faHandshake,\n faHanukiah: faHanukiah,\n faHardHat: faHardHat,\n faHashtag: faHashtag,\n faHatWizard: faHatWizard,\n faHaykal: faHaykal,\n faHdd: faHdd,\n faHeading: faHeading,\n faHeadphones: faHeadphones,\n faHeadphonesAlt: faHeadphonesAlt,\n faHeadset: faHeadset,\n faHeart: faHeart,\n faHeartBroken: faHeartBroken,\n faHeartbeat: faHeartbeat,\n faHelicopter: faHelicopter,\n faHighlighter: faHighlighter,\n faHiking: faHiking,\n faHippo: faHippo,\n faHistory: faHistory,\n faHockeyPuck: faHockeyPuck,\n faHollyBerry: faHollyBerry,\n faHome: faHome,\n faHorse: faHorse,\n faHorseHead: faHorseHead,\n faHospital: faHospital,\n faHospitalAlt: faHospitalAlt,\n faHospitalSymbol: faHospitalSymbol,\n faHotTub: faHotTub,\n faHotdog: faHotdog,\n faHotel: faHotel,\n faHourglass: faHourglass,\n faHourglassEnd: faHourglassEnd,\n faHourglassHalf: faHourglassHalf,\n faHourglassStart: faHourglassStart,\n faHouseDamage: faHouseDamage,\n faHryvnia: faHryvnia,\n faICursor: faICursor,\n faIceCream: faIceCream,\n faIcicles: faIcicles,\n faIcons: faIcons,\n faIdBadge: faIdBadge,\n faIdCard: faIdCard,\n faIdCardAlt: faIdCardAlt,\n faIgloo: faIgloo,\n faImage: faImage,\n faImages: faImages,\n faInbox: faInbox,\n faIndent: faIndent,\n faIndustry: faIndustry,\n faInfinity: faInfinity,\n faInfo: faInfo,\n faInfoCircle: faInfoCircle,\n faItalic: faItalic,\n faJedi: faJedi,\n faJoint: faJoint,\n faJournalWhills: faJournalWhills,\n faKaaba: faKaaba,\n faKey: faKey,\n faKeyboard: faKeyboard,\n faKhanda: faKhanda,\n faKiss: faKiss,\n faKissBeam: faKissBeam,\n faKissWinkHeart: faKissWinkHeart,\n faKiwiBird: faKiwiBird,\n faLandmark: faLandmark,\n faLanguage: faLanguage,\n faLaptop: faLaptop,\n faLaptopCode: faLaptopCode,\n faLaptopMedical: faLaptopMedical,\n faLaugh: faLaugh,\n faLaughBeam: faLaughBeam,\n faLaughSquint: faLaughSquint,\n faLaughWink: faLaughWink,\n faLayerGroup: faLayerGroup,\n faLeaf: faLeaf,\n faLemon: faLemon,\n faLessThan: faLessThan,\n faLessThanEqual: faLessThanEqual,\n faLevelDownAlt: faLevelDownAlt,\n faLevelUpAlt: faLevelUpAlt,\n faLifeRing: faLifeRing,\n faLightbulb: faLightbulb,\n faLink: faLink,\n faLiraSign: faLiraSign,\n faList: faList,\n faListAlt: faListAlt,\n faListOl: faListOl,\n faListUl: faListUl,\n faLocationArrow: faLocationArrow,\n faLock: faLock,\n faLockOpen: faLockOpen,\n faLongArrowAltDown: faLongArrowAltDown,\n faLongArrowAltLeft: faLongArrowAltLeft,\n faLongArrowAltRight: faLongArrowAltRight,\n faLongArrowAltUp: faLongArrowAltUp,\n faLowVision: faLowVision,\n faLuggageCart: faLuggageCart,\n faMagic: faMagic,\n faMagnet: faMagnet,\n faMailBulk: faMailBulk,\n faMale: faMale,\n faMap: faMap,\n faMapMarked: faMapMarked,\n faMapMarkedAlt: faMapMarkedAlt,\n faMapMarker: faMapMarker,\n faMapMarkerAlt: faMapMarkerAlt,\n faMapPin: faMapPin,\n faMapSigns: faMapSigns,\n faMarker: faMarker,\n faMars: faMars,\n faMarsDouble: faMarsDouble,\n faMarsStroke: faMarsStroke,\n faMarsStrokeH: faMarsStrokeH,\n faMarsStrokeV: faMarsStrokeV,\n faMask: faMask,\n faMedal: faMedal,\n faMedkit: faMedkit,\n faMeh: faMeh,\n faMehBlank: faMehBlank,\n faMehRollingEyes: faMehRollingEyes,\n faMemory: faMemory,\n faMenorah: faMenorah,\n faMercury: faMercury,\n faMeteor: faMeteor,\n faMicrochip: faMicrochip,\n faMicrophone: faMicrophone,\n faMicrophoneAlt: faMicrophoneAlt,\n faMicrophoneAltSlash: faMicrophoneAltSlash,\n faMicrophoneSlash: faMicrophoneSlash,\n faMicroscope: faMicroscope,\n faMinus: faMinus,\n faMinusCircle: faMinusCircle,\n faMinusSquare: faMinusSquare,\n faMitten: faMitten,\n faMobile: faMobile,\n faMobileAlt: faMobileAlt,\n faMoneyBill: faMoneyBill,\n faMoneyBillAlt: faMoneyBillAlt,\n faMoneyBillWave: faMoneyBillWave,\n faMoneyBillWaveAlt: faMoneyBillWaveAlt,\n faMoneyCheck: faMoneyCheck,\n faMoneyCheckAlt: faMoneyCheckAlt,\n faMonument: faMonument,\n faMoon: faMoon,\n faMortarPestle: faMortarPestle,\n faMosque: faMosque,\n faMotorcycle: faMotorcycle,\n faMountain: faMountain,\n faMousePointer: faMousePointer,\n faMugHot: faMugHot,\n faMusic: faMusic,\n faNetworkWired: faNetworkWired,\n faNeuter: faNeuter,\n faNewspaper: faNewspaper,\n faNotEqual: faNotEqual,\n faNotesMedical: faNotesMedical,\n faObjectGroup: faObjectGroup,\n faObjectUngroup: faObjectUngroup,\n faOilCan: faOilCan,\n faOm: faOm,\n faOtter: faOtter,\n faOutdent: faOutdent,\n faPager: faPager,\n faPaintBrush: faPaintBrush,\n faPaintRoller: faPaintRoller,\n faPalette: faPalette,\n faPallet: faPallet,\n faPaperPlane: faPaperPlane,\n faPaperclip: faPaperclip,\n faParachuteBox: faParachuteBox,\n faParagraph: faParagraph,\n faParking: faParking,\n faPassport: faPassport,\n faPastafarianism: faPastafarianism,\n faPaste: faPaste,\n faPause: faPause,\n faPauseCircle: faPauseCircle,\n faPaw: faPaw,\n faPeace: faPeace,\n faPen: faPen,\n faPenAlt: faPenAlt,\n faPenFancy: faPenFancy,\n faPenNib: faPenNib,\n faPenSquare: faPenSquare,\n faPencilAlt: faPencilAlt,\n faPencilRuler: faPencilRuler,\n faPeopleCarry: faPeopleCarry,\n faPepperHot: faPepperHot,\n faPercent: faPercent,\n faPercentage: faPercentage,\n faPersonBooth: faPersonBooth,\n faPhone: faPhone,\n faPhoneAlt: faPhoneAlt,\n faPhoneSlash: faPhoneSlash,\n faPhoneSquare: faPhoneSquare,\n faPhoneSquareAlt: faPhoneSquareAlt,\n faPhoneVolume: faPhoneVolume,\n faPhotoVideo: faPhotoVideo,\n faPiggyBank: faPiggyBank,\n faPills: faPills,\n faPizzaSlice: faPizzaSlice,\n faPlaceOfWorship: faPlaceOfWorship,\n faPlane: faPlane,\n faPlaneArrival: faPlaneArrival,\n faPlaneDeparture: faPlaneDeparture,\n faPlay: faPlay,\n faPlayCircle: faPlayCircle,\n faPlug: faPlug,\n faPlus: faPlus,\n faPlusCircle: faPlusCircle,\n faPlusSquare: faPlusSquare,\n faPodcast: faPodcast,\n faPoll: faPoll,\n faPollH: faPollH,\n faPoo: faPoo,\n faPooStorm: faPooStorm,\n faPoop: faPoop,\n faPortrait: faPortrait,\n faPoundSign: faPoundSign,\n faPowerOff: faPowerOff,\n faPray: faPray,\n faPrayingHands: faPrayingHands,\n faPrescription: faPrescription,\n faPrescriptionBottle: faPrescriptionBottle,\n faPrescriptionBottleAlt: faPrescriptionBottleAlt,\n faPrint: faPrint,\n faProcedures: faProcedures,\n faProjectDiagram: faProjectDiagram,\n faPuzzlePiece: faPuzzlePiece,\n faQrcode: faQrcode,\n faQuestion: faQuestion,\n faQuestionCircle: faQuestionCircle,\n faQuidditch: faQuidditch,\n faQuoteLeft: faQuoteLeft,\n faQuoteRight: faQuoteRight,\n faQuran: faQuran,\n faRadiation: faRadiation,\n faRadiationAlt: faRadiationAlt,\n faRainbow: faRainbow,\n faRandom: faRandom,\n faReceipt: faReceipt,\n faRecycle: faRecycle,\n faRedo: faRedo,\n faRedoAlt: faRedoAlt,\n faRegistered: faRegistered,\n faRemoveFormat: faRemoveFormat,\n faReply: faReply,\n faReplyAll: faReplyAll,\n faRepublican: faRepublican,\n faRestroom: faRestroom,\n faRetweet: faRetweet,\n faRibbon: faRibbon,\n faRing: faRing,\n faRoad: faRoad,\n faRobot: faRobot,\n faRocket: faRocket,\n faRoute: faRoute,\n faRss: faRss,\n faRssSquare: faRssSquare,\n faRubleSign: faRubleSign,\n faRuler: faRuler,\n faRulerCombined: faRulerCombined,\n faRulerHorizontal: faRulerHorizontal,\n faRulerVertical: faRulerVertical,\n faRunning: faRunning,\n faRupeeSign: faRupeeSign,\n faSadCry: faSadCry,\n faSadTear: faSadTear,\n faSatellite: faSatellite,\n faSatelliteDish: faSatelliteDish,\n faSave: faSave,\n faSchool: faSchool,\n faScrewdriver: faScrewdriver,\n faScroll: faScroll,\n faSdCard: faSdCard,\n faSearch: faSearch,\n faSearchDollar: faSearchDollar,\n faSearchLocation: faSearchLocation,\n faSearchMinus: faSearchMinus,\n faSearchPlus: faSearchPlus,\n faSeedling: faSeedling,\n faServer: faServer,\n faShapes: faShapes,\n faShare: faShare,\n faShareAlt: faShareAlt,\n faShareAltSquare: faShareAltSquare,\n faShareSquare: faShareSquare,\n faShekelSign: faShekelSign,\n faShieldAlt: faShieldAlt,\n faShip: faShip,\n faShippingFast: faShippingFast,\n faShoePrints: faShoePrints,\n faShoppingBag: faShoppingBag,\n faShoppingBasket: faShoppingBasket,\n faShoppingCart: faShoppingCart,\n faShower: faShower,\n faShuttleVan: faShuttleVan,\n faSign: faSign,\n faSignInAlt: faSignInAlt,\n faSignLanguage: faSignLanguage,\n faSignOutAlt: faSignOutAlt,\n faSignal: faSignal,\n faSignature: faSignature,\n faSimCard: faSimCard,\n faSitemap: faSitemap,\n faSkating: faSkating,\n faSkiing: faSkiing,\n faSkiingNordic: faSkiingNordic,\n faSkull: faSkull,\n faSkullCrossbones: faSkullCrossbones,\n faSlash: faSlash,\n faSleigh: faSleigh,\n faSlidersH: faSlidersH,\n faSmile: faSmile,\n faSmileBeam: faSmileBeam,\n faSmileWink: faSmileWink,\n faSmog: faSmog,\n faSmoking: faSmoking,\n faSmokingBan: faSmokingBan,\n faSms: faSms,\n faSnowboarding: faSnowboarding,\n faSnowflake: faSnowflake,\n faSnowman: faSnowman,\n faSnowplow: faSnowplow,\n faSocks: faSocks,\n faSolarPanel: faSolarPanel,\n faSort: faSort,\n faSortAlphaDown: faSortAlphaDown,\n faSortAlphaDownAlt: faSortAlphaDownAlt,\n faSortAlphaUp: faSortAlphaUp,\n faSortAlphaUpAlt: faSortAlphaUpAlt,\n faSortAmountDown: faSortAmountDown,\n faSortAmountDownAlt: faSortAmountDownAlt,\n faSortAmountUp: faSortAmountUp,\n faSortAmountUpAlt: faSortAmountUpAlt,\n faSortDown: faSortDown,\n faSortNumericDown: faSortNumericDown,\n faSortNumericDownAlt: faSortNumericDownAlt,\n faSortNumericUp: faSortNumericUp,\n faSortNumericUpAlt: faSortNumericUpAlt,\n faSortUp: faSortUp,\n faSpa: faSpa,\n faSpaceShuttle: faSpaceShuttle,\n faSpellCheck: faSpellCheck,\n faSpider: faSpider,\n faSpinner: faSpinner,\n faSplotch: faSplotch,\n faSprayCan: faSprayCan,\n faSquare: faSquare,\n faSquareFull: faSquareFull,\n faSquareRootAlt: faSquareRootAlt,\n faStamp: faStamp,\n faStar: faStar,\n faStarAndCrescent: faStarAndCrescent,\n faStarHalf: faStarHalf,\n faStarHalfAlt: faStarHalfAlt,\n faStarOfDavid: faStarOfDavid,\n faStarOfLife: faStarOfLife,\n faStepBackward: faStepBackward,\n faStepForward: faStepForward,\n faStethoscope: faStethoscope,\n faStickyNote: faStickyNote,\n faStop: faStop,\n faStopCircle: faStopCircle,\n faStopwatch: faStopwatch,\n faStore: faStore,\n faStoreAlt: faStoreAlt,\n faStream: faStream,\n faStreetView: faStreetView,\n faStrikethrough: faStrikethrough,\n faStroopwafel: faStroopwafel,\n faSubscript: faSubscript,\n faSubway: faSubway,\n faSuitcase: faSuitcase,\n faSuitcaseRolling: faSuitcaseRolling,\n faSun: faSun,\n faSuperscript: faSuperscript,\n faSurprise: faSurprise,\n faSwatchbook: faSwatchbook,\n faSwimmer: faSwimmer,\n faSwimmingPool: faSwimmingPool,\n faSynagogue: faSynagogue,\n faSync: faSync,\n faSyncAlt: faSyncAlt,\n faSyringe: faSyringe,\n faTable: faTable,\n faTableTennis: faTableTennis,\n faTablet: faTablet,\n faTabletAlt: faTabletAlt,\n faTablets: faTablets,\n faTachometerAlt: faTachometerAlt,\n faTag: faTag,\n faTags: faTags,\n faTape: faTape,\n faTasks: faTasks,\n faTaxi: faTaxi,\n faTeeth: faTeeth,\n faTeethOpen: faTeethOpen,\n faTemperatureHigh: faTemperatureHigh,\n faTemperatureLow: faTemperatureLow,\n faTenge: faTenge,\n faTerminal: faTerminal,\n faTextHeight: faTextHeight,\n faTextWidth: faTextWidth,\n faTh: faTh,\n faThLarge: faThLarge,\n faThList: faThList,\n faTheaterMasks: faTheaterMasks,\n faThermometer: faThermometer,\n faThermometerEmpty: faThermometerEmpty,\n faThermometerFull: faThermometerFull,\n faThermometerHalf: faThermometerHalf,\n faThermometerQuarter: faThermometerQuarter,\n faThermometerThreeQuarters: faThermometerThreeQuarters,\n faThumbsDown: faThumbsDown,\n faThumbsUp: faThumbsUp,\n faThumbtack: faThumbtack,\n faTicketAlt: faTicketAlt,\n faTimes: faTimes,\n faTimesCircle: faTimesCircle,\n faTint: faTint,\n faTintSlash: faTintSlash,\n faTired: faTired,\n faToggleOff: faToggleOff,\n faToggleOn: faToggleOn,\n faToilet: faToilet,\n faToiletPaper: faToiletPaper,\n faToolbox: faToolbox,\n faTools: faTools,\n faTooth: faTooth,\n faTorah: faTorah,\n faToriiGate: faToriiGate,\n faTractor: faTractor,\n faTrademark: faTrademark,\n faTrafficLight: faTrafficLight,\n faTrain: faTrain,\n faTram: faTram,\n faTransgender: faTransgender,\n faTransgenderAlt: faTransgenderAlt,\n faTrash: faTrash,\n faTrashAlt: faTrashAlt,\n faTrashRestore: faTrashRestore,\n faTrashRestoreAlt: faTrashRestoreAlt,\n faTree: faTree,\n faTrophy: faTrophy,\n faTruck: faTruck,\n faTruckLoading: faTruckLoading,\n faTruckMonster: faTruckMonster,\n faTruckMoving: faTruckMoving,\n faTruckPickup: faTruckPickup,\n faTshirt: faTshirt,\n faTty: faTty,\n faTv: faTv,\n faUmbrella: faUmbrella,\n faUmbrellaBeach: faUmbrellaBeach,\n faUnderline: faUnderline,\n faUndo: faUndo,\n faUndoAlt: faUndoAlt,\n faUniversalAccess: faUniversalAccess,\n faUniversity: faUniversity,\n faUnlink: faUnlink,\n faUnlock: faUnlock,\n faUnlockAlt: faUnlockAlt,\n faUpload: faUpload,\n faUser: faUser,\n faUserAlt: faUserAlt,\n faUserAltSlash: faUserAltSlash,\n faUserAstronaut: faUserAstronaut,\n faUserCheck: faUserCheck,\n faUserCircle: faUserCircle,\n faUserClock: faUserClock,\n faUserCog: faUserCog,\n faUserEdit: faUserEdit,\n faUserFriends: faUserFriends,\n faUserGraduate: faUserGraduate,\n faUserInjured: faUserInjured,\n faUserLock: faUserLock,\n faUserMd: faUserMd,\n faUserMinus: faUserMinus,\n faUserNinja: faUserNinja,\n faUserNurse: faUserNurse,\n faUserPlus: faUserPlus,\n faUserSecret: faUserSecret,\n faUserShield: faUserShield,\n faUserSlash: faUserSlash,\n faUserTag: faUserTag,\n faUserTie: faUserTie,\n faUserTimes: faUserTimes,\n faUsers: faUsers,\n faUsersCog: faUsersCog,\n faUtensilSpoon: faUtensilSpoon,\n faUtensils: faUtensils,\n faVectorSquare: faVectorSquare,\n faVenus: faVenus,\n faVenusDouble: faVenusDouble,\n faVenusMars: faVenusMars,\n faVial: faVial,\n faVials: faVials,\n faVideo: faVideo,\n faVideoSlash: faVideoSlash,\n faVihara: faVihara,\n faVoicemail: faVoicemail,\n faVolleyballBall: faVolleyballBall,\n faVolumeDown: faVolumeDown,\n faVolumeMute: faVolumeMute,\n faVolumeOff: faVolumeOff,\n faVolumeUp: faVolumeUp,\n faVoteYea: faVoteYea,\n faVrCardboard: faVrCardboard,\n faWalking: faWalking,\n faWallet: faWallet,\n faWarehouse: faWarehouse,\n faWater: faWater,\n faWaveSquare: faWaveSquare,\n faWeight: faWeight,\n faWeightHanging: faWeightHanging,\n faWheelchair: faWheelchair,\n faWifi: faWifi,\n faWind: faWind,\n faWindowClose: faWindowClose,\n faWindowMaximize: faWindowMaximize,\n faWindowMinimize: faWindowMinimize,\n faWindowRestore: faWindowRestore,\n faWineBottle: faWineBottle,\n faWineGlass: faWineGlass,\n faWineGlassAlt: faWineGlassAlt,\n faWonSign: faWonSign,\n faWrench: faWrench,\n faXRay: faXRay,\n faYenSign: faYenSign,\n faYinYang: faYinYang\n};\n\nexport { _iconsCache as fas, prefix, faAd, faAddressBook, faAddressCard, faAdjust, faAirFreshener, faAlignCenter, faAlignJustify, faAlignLeft, faAlignRight, faAllergies, faAmbulance, faAmericanSignLanguageInterpreting, faAnchor, faAngleDoubleDown, faAngleDoubleLeft, faAngleDoubleRight, faAngleDoubleUp, faAngleDown, faAngleLeft, faAngleRight, faAngleUp, faAngry, faAnkh, faAppleAlt, faArchive, faArchway, faArrowAltCircleDown, faArrowAltCircleLeft, faArrowAltCircleRight, faArrowAltCircleUp, faArrowCircleDown, faArrowCircleLeft, faArrowCircleRight, faArrowCircleUp, faArrowDown, faArrowLeft, faArrowRight, faArrowUp, faArrowsAlt, faArrowsAltH, faArrowsAltV, faAssistiveListeningSystems, faAsterisk, faAt, faAtlas, faAtom, faAudioDescription, faAward, faBaby, faBabyCarriage, faBackspace, faBackward, faBacon, faBalanceScale, faBalanceScaleLeft, faBalanceScaleRight, faBan, faBandAid, faBarcode, faBars, faBaseballBall, faBasketballBall, faBath, faBatteryEmpty, faBatteryFull, faBatteryHalf, faBatteryQuarter, faBatteryThreeQuarters, faBed, faBeer, faBell, faBellSlash, faBezierCurve, faBible, faBicycle, faBiking, faBinoculars, faBiohazard, faBirthdayCake, faBlender, faBlenderPhone, faBlind, faBlog, faBold, faBolt, faBomb, faBone, faBong, faBook, faBookDead, faBookMedical, faBookOpen, faBookReader, faBookmark, faBorderAll, faBorderNone, faBorderStyle, faBowlingBall, faBox, faBoxOpen, faBoxes, faBraille, faBrain, faBreadSlice, faBriefcase, faBriefcaseMedical, faBroadcastTower, faBroom, faBrush, faBug, faBuilding, faBullhorn, faBullseye, faBurn, faBus, faBusAlt, faBusinessTime, faCalculator, faCalendar, faCalendarAlt, faCalendarCheck, faCalendarDay, faCalendarMinus, faCalendarPlus, faCalendarTimes, faCalendarWeek, faCamera, faCameraRetro, faCampground, faCandyCane, faCannabis, faCapsules, faCar, faCarAlt, faCarBattery, faCarCrash, faCarSide, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareLeft, faCaretSquareRight, faCaretSquareUp, faCaretUp, faCarrot, faCartArrowDown, faCartPlus, faCashRegister, faCat, faCertificate, faChair, faChalkboard, faChalkboardTeacher, faChargingStation, faChartArea, faChartBar, faChartLine, faChartPie, faCheck, faCheckCircle, faCheckDouble, faCheckSquare, faCheese, faChess, faChessBishop, faChessBoard, faChessKing, faChessKnight, faChessPawn, faChessQueen, faChessRook, faChevronCircleDown, faChevronCircleLeft, faChevronCircleRight, faChevronCircleUp, faChevronDown, faChevronLeft, faChevronRight, faChevronUp, faChild, faChurch, faCircle, faCircleNotch, faCity, faClinicMedical, faClipboard, faClipboardCheck, faClipboardList, faClock, faClone, faClosedCaptioning, faCloud, faCloudDownloadAlt, faCloudMeatball, faCloudMoon, faCloudMoonRain, faCloudRain, faCloudShowersHeavy, faCloudSun, faCloudSunRain, faCloudUploadAlt, faCocktail, faCode, faCodeBranch, faCoffee, faCog, faCogs, faCoins, faColumns, faComment, faCommentAlt, faCommentDollar, faCommentDots, faCommentMedical, faCommentSlash, faComments, faCommentsDollar, faCompactDisc, faCompass, faCompress, faCompressArrowsAlt, faConciergeBell, faCookie, faCookieBite, faCopy, faCopyright, faCouch, faCreditCard, faCrop, faCropAlt, faCross, faCrosshairs, faCrow, faCrown, faCrutch, faCube, faCubes, faCut, faDatabase, faDeaf, faDemocrat, faDesktop, faDharmachakra, faDiagnoses, faDice, faDiceD20, faDiceD6, faDiceFive, faDiceFour, faDiceOne, faDiceSix, faDiceThree, faDiceTwo, faDigitalTachograph, faDirections, faDivide, faDizzy, faDna, faDog, faDollarSign, faDolly, faDollyFlatbed, faDonate, faDoorClosed, faDoorOpen, faDotCircle, faDove, faDownload, faDraftingCompass, faDragon, faDrawPolygon, faDrum, faDrumSteelpan, faDrumstickBite, faDumbbell, faDumpster, faDumpsterFire, faDungeon, faEdit, faEgg, faEject, faEllipsisH, faEllipsisV, faEnvelope, faEnvelopeOpen, faEnvelopeOpenText, faEnvelopeSquare, faEquals, faEraser, faEthernet, faEuroSign, faExchangeAlt, faExclamation, faExclamationCircle, faExclamationTriangle, faExpand, faExpandArrowsAlt, faExternalLinkAlt, faExternalLinkSquareAlt, faEye, faEyeDropper, faEyeSlash, faFan, faFastBackward, faFastForward, faFax, faFeather, faFeatherAlt, faFemale, faFighterJet, faFile, faFileAlt, faFileArchive, faFileAudio, faFileCode, faFileContract, faFileCsv, faFileDownload, faFileExcel, faFileExport, faFileImage, faFileImport, faFileInvoice, faFileInvoiceDollar, faFileMedical, faFileMedicalAlt, faFilePdf, faFilePowerpoint, faFilePrescription, faFileSignature, faFileUpload, faFileVideo, faFileWord, faFill, faFillDrip, faFilm, faFilter, faFingerprint, faFire, faFireAlt, faFireExtinguisher, faFirstAid, faFish, faFistRaised, faFlag, faFlagCheckered, faFlagUsa, faFlask, faFlushed, faFolder, faFolderMinus, faFolderOpen, faFolderPlus, faFont, faFontAwesomeLogoFull, faFootballBall, faForward, faFrog, faFrown, faFrownOpen, faFunnelDollar, faFutbol, faGamepad, faGasPump, faGavel, faGem, faGenderless, faGhost, faGift, faGifts, faGlassCheers, faGlassMartini, faGlassMartiniAlt, faGlassWhiskey, faGlasses, faGlobe, faGlobeAfrica, faGlobeAmericas, faGlobeAsia, faGlobeEurope, faGolfBall, faGopuram, faGraduationCap, faGreaterThan, faGreaterThanEqual, faGrimace, faGrin, faGrinAlt, faGrinBeam, faGrinBeamSweat, faGrinHearts, faGrinSquint, faGrinSquintTears, faGrinStars, faGrinTears, faGrinTongue, faGrinTongueSquint, faGrinTongueWink, faGrinWink, faGripHorizontal, faGripLines, faGripLinesVertical, faGripVertical, faGuitar, faHSquare, faHamburger, faHammer, faHamsa, faHandHolding, faHandHoldingHeart, faHandHoldingUsd, faHandLizard, faHandMiddleFinger, faHandPaper, faHandPeace, faHandPointDown, faHandPointLeft, faHandPointRight, faHandPointUp, faHandPointer, faHandRock, faHandScissors, faHandSpock, faHands, faHandsHelping, faHandshake, faHanukiah, faHardHat, faHashtag, faHatWizard, faHaykal, faHdd, faHeading, faHeadphones, faHeadphonesAlt, faHeadset, faHeart, faHeartBroken, faHeartbeat, faHelicopter, faHighlighter, faHiking, faHippo, faHistory, faHockeyPuck, faHollyBerry, faHome, faHorse, faHorseHead, faHospital, faHospitalAlt, faHospitalSymbol, faHotTub, faHotdog, faHotel, faHourglass, faHourglassEnd, faHourglassHalf, faHourglassStart, faHouseDamage, faHryvnia, faICursor, faIceCream, faIcicles, faIcons, faIdBadge, faIdCard, faIdCardAlt, faIgloo, faImage, faImages, faInbox, faIndent, faIndustry, faInfinity, faInfo, faInfoCircle, faItalic, faJedi, faJoint, faJournalWhills, faKaaba, faKey, faKeyboard, faKhanda, faKiss, faKissBeam, faKissWinkHeart, faKiwiBird, faLandmark, faLanguage, faLaptop, faLaptopCode, faLaptopMedical, faLaugh, faLaughBeam, faLaughSquint, faLaughWink, faLayerGroup, faLeaf, faLemon, faLessThan, faLessThanEqual, faLevelDownAlt, faLevelUpAlt, faLifeRing, faLightbulb, faLink, faLiraSign, faList, faListAlt, faListOl, faListUl, faLocationArrow, faLock, faLockOpen, faLongArrowAltDown, faLongArrowAltLeft, faLongArrowAltRight, faLongArrowAltUp, faLowVision, faLuggageCart, faMagic, faMagnet, faMailBulk, faMale, faMap, faMapMarked, faMapMarkedAlt, faMapMarker, faMapMarkerAlt, faMapPin, faMapSigns, faMarker, faMars, faMarsDouble, faMarsStroke, faMarsStrokeH, faMarsStrokeV, faMask, faMedal, faMedkit, faMeh, faMehBlank, faMehRollingEyes, faMemory, faMenorah, faMercury, faMeteor, faMicrochip, faMicrophone, faMicrophoneAlt, faMicrophoneAltSlash, faMicrophoneSlash, faMicroscope, faMinus, faMinusCircle, faMinusSquare, faMitten, faMobile, faMobileAlt, faMoneyBill, faMoneyBillAlt, faMoneyBillWave, faMoneyBillWaveAlt, faMoneyCheck, faMoneyCheckAlt, faMonument, faMoon, faMortarPestle, faMosque, faMotorcycle, faMountain, faMousePointer, faMugHot, faMusic, faNetworkWired, faNeuter, faNewspaper, faNotEqual, faNotesMedical, faObjectGroup, faObjectUngroup, faOilCan, faOm, faOtter, faOutdent, faPager, faPaintBrush, faPaintRoller, faPalette, faPallet, faPaperPlane, faPaperclip, faParachuteBox, faParagraph, faParking, faPassport, faPastafarianism, faPaste, faPause, faPauseCircle, faPaw, faPeace, faPen, faPenAlt, faPenFancy, faPenNib, faPenSquare, faPencilAlt, faPencilRuler, faPeopleCarry, faPepperHot, faPercent, faPercentage, faPersonBooth, faPhone, faPhoneAlt, faPhoneSlash, faPhoneSquare, faPhoneSquareAlt, faPhoneVolume, faPhotoVideo, faPiggyBank, faPills, faPizzaSlice, faPlaceOfWorship, faPlane, faPlaneArrival, faPlaneDeparture, faPlay, faPlayCircle, faPlug, faPlus, faPlusCircle, faPlusSquare, faPodcast, faPoll, faPollH, faPoo, faPooStorm, faPoop, faPortrait, faPoundSign, faPowerOff, faPray, faPrayingHands, faPrescription, faPrescriptionBottle, faPrescriptionBottleAlt, faPrint, faProcedures, faProjectDiagram, faPuzzlePiece, faQrcode, faQuestion, faQuestionCircle, faQuidditch, faQuoteLeft, faQuoteRight, faQuran, faRadiation, faRadiationAlt, faRainbow, faRandom, faReceipt, faRecycle, faRedo, faRedoAlt, faRegistered, faRemoveFormat, faReply, faReplyAll, faRepublican, faRestroom, faRetweet, faRibbon, faRing, faRoad, faRobot, faRocket, faRoute, faRss, faRssSquare, faRubleSign, faRuler, faRulerCombined, faRulerHorizontal, faRulerVertical, faRunning, faRupeeSign, faSadCry, faSadTear, faSatellite, faSatelliteDish, faSave, faSchool, faScrewdriver, faScroll, faSdCard, faSearch, faSearchDollar, faSearchLocation, faSearchMinus, faSearchPlus, faSeedling, faServer, faShapes, faShare, faShareAlt, faShareAltSquare, faShareSquare, faShekelSign, faShieldAlt, faShip, faShippingFast, faShoePrints, faShoppingBag, faShoppingBasket, faShoppingCart, faShower, faShuttleVan, faSign, faSignInAlt, faSignLanguage, faSignOutAlt, faSignal, faSignature, faSimCard, faSitemap, faSkating, faSkiing, faSkiingNordic, faSkull, faSkullCrossbones, faSlash, faSleigh, faSlidersH, faSmile, faSmileBeam, faSmileWink, faSmog, faSmoking, faSmokingBan, faSms, faSnowboarding, faSnowflake, faSnowman, faSnowplow, faSocks, faSolarPanel, faSort, faSortAlphaDown, faSortAlphaDownAlt, faSortAlphaUp, faSortAlphaUpAlt, faSortAmountDown, faSortAmountDownAlt, faSortAmountUp, faSortAmountUpAlt, faSortDown, faSortNumericDown, faSortNumericDownAlt, faSortNumericUp, faSortNumericUpAlt, faSortUp, faSpa, faSpaceShuttle, faSpellCheck, faSpider, faSpinner, faSplotch, faSprayCan, faSquare, faSquareFull, faSquareRootAlt, faStamp, faStar, faStarAndCrescent, faStarHalf, faStarHalfAlt, faStarOfDavid, faStarOfLife, faStepBackward, faStepForward, faStethoscope, faStickyNote, faStop, faStopCircle, faStopwatch, faStore, faStoreAlt, faStream, faStreetView, faStrikethrough, faStroopwafel, faSubscript, faSubway, faSuitcase, faSuitcaseRolling, faSun, faSuperscript, faSurprise, faSwatchbook, faSwimmer, faSwimmingPool, faSynagogue, faSync, faSyncAlt, faSyringe, faTable, faTableTennis, faTablet, faTabletAlt, faTablets, faTachometerAlt, faTag, faTags, faTape, faTasks, faTaxi, faTeeth, faTeethOpen, faTemperatureHigh, faTemperatureLow, faTenge, faTerminal, faTextHeight, faTextWidth, faTh, faThLarge, faThList, faTheaterMasks, faThermometer, faThermometerEmpty, faThermometerFull, faThermometerHalf, faThermometerQuarter, faThermometerThreeQuarters, faThumbsDown, faThumbsUp, faThumbtack, faTicketAlt, faTimes, faTimesCircle, faTint, faTintSlash, faTired, faToggleOff, faToggleOn, faToilet, faToiletPaper, faToolbox, faTools, faTooth, faTorah, faToriiGate, faTractor, faTrademark, faTrafficLight, faTrain, faTram, faTransgender, faTransgenderAlt, faTrash, faTrashAlt, faTrashRestore, faTrashRestoreAlt, faTree, faTrophy, faTruck, faTruckLoading, faTruckMonster, faTruckMoving, faTruckPickup, faTshirt, faTty, faTv, faUmbrella, faUmbrellaBeach, faUnderline, faUndo, faUndoAlt, faUniversalAccess, faUniversity, faUnlink, faUnlock, faUnlockAlt, faUpload, faUser, faUserAlt, faUserAltSlash, faUserAstronaut, faUserCheck, faUserCircle, faUserClock, faUserCog, faUserEdit, faUserFriends, faUserGraduate, faUserInjured, faUserLock, faUserMd, faUserMinus, faUserNinja, faUserNurse, faUserPlus, faUserSecret, faUserShield, faUserSlash, faUserTag, faUserTie, faUserTimes, faUsers, faUsersCog, faUtensilSpoon, faUtensils, faVectorSquare, faVenus, faVenusDouble, faVenusMars, faVial, faVials, faVideo, faVideoSlash, faVihara, faVoicemail, faVolleyballBall, faVolumeDown, faVolumeMute, faVolumeOff, faVolumeUp, faVoteYea, faVrCardboard, faWalking, faWallet, faWarehouse, faWater, faWaveSquare, faWeight, faWeightHanging, faWheelchair, faWifi, faWind, faWindowClose, faWindowMaximize, faWindowMinimize, faWindowRestore, faWineBottle, faWineGlass, faWineGlassAlt, faWonSign, faWrench, faXRay, faYenSign, faYinYang };\n", + "import { parse, icon } from '@fortawesome/fontawesome-svg-core';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nfunction _typeof(obj) {\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n var ownKeys = Object.keys(source);\n\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n }));\n }\n\n ownKeys.forEach(function (key) {\n _defineProperty(target, key, source[key]);\n });\n }\n\n return target;\n}\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n\n var target = _objectWithoutPropertiesLoose(source, excluded);\n\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n }\n}\n\nfunction _iterableToArray(iter) {\n if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n}\n\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n}\n\nvar commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nvar humps = createCommonjsModule(function (module) {\n(function(global) {\n\n var _processKeys = function(convert, obj, options) {\n if(!_isObject(obj) || _isDate(obj) || _isRegExp(obj) || _isBoolean(obj) || _isFunction(obj)) {\n return obj;\n }\n\n var output,\n i = 0,\n l = 0;\n\n if(_isArray(obj)) {\n output = [];\n for(l=obj.length; i 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (typeof element === 'string') {\n return element;\n }\n\n var children = (element.children || []).map(function (child) {\n return convert(createElement, child);\n });\n var mixins = Object.keys(element.attributes || {}).reduce(function (acc, key) {\n var val = element.attributes[key];\n\n switch (key) {\n case 'class':\n acc.attrs['className'] = val;\n delete element.attributes['class'];\n break;\n\n case 'style':\n acc.attrs['style'] = styleToObject(val);\n break;\n\n default:\n if (key.indexOf('aria-') === 0 || key.indexOf('data-') === 0) {\n acc.attrs[key.toLowerCase()] = val;\n } else {\n acc.attrs[humps.camelize(key)] = val;\n }\n\n }\n\n return acc;\n }, {\n attrs: {}\n });\n\n var _extraProps$style = extraProps.style,\n existingStyle = _extraProps$style === void 0 ? {} : _extraProps$style,\n remaining = _objectWithoutProperties(extraProps, [\"style\"]);\n\n mixins.attrs['style'] = _objectSpread({}, mixins.attrs['style'], existingStyle);\n return createElement.apply(void 0, [element.tag, _objectSpread({}, mixins.attrs, remaining)].concat(_toConsumableArray(children)));\n}\n\nvar PRODUCTION = false;\n\ntry {\n PRODUCTION = process.env.NODE_ENV === 'production';\n} catch (e) {}\n\nfunction log () {\n if (!PRODUCTION && console && typeof console.error === 'function') {\n var _console;\n\n (_console = console).error.apply(_console, arguments);\n }\n}\n\nfunction objectWithKey(key, value) {\n return Array.isArray(value) && value.length > 0 || !Array.isArray(value) && value ? _defineProperty({}, key, value) : {};\n}\n\nfunction classList(props) {\n var _classes;\n\n var classes = (_classes = {\n 'fa-spin': props.spin,\n 'fa-pulse': props.pulse,\n 'fa-fw': props.fixedWidth,\n 'fa-inverse': props.inverse,\n 'fa-border': props.border,\n 'fa-li': props.listItem,\n 'fa-flip-horizontal': props.flip === 'horizontal' || props.flip === 'both',\n 'fa-flip-vertical': props.flip === 'vertical' || props.flip === 'both'\n }, _defineProperty(_classes, \"fa-\".concat(props.size), props.size !== null), _defineProperty(_classes, \"fa-rotate-\".concat(props.rotation), props.rotation !== null), _defineProperty(_classes, \"fa-pull-\".concat(props.pull), props.pull !== null), _classes);\n return Object.keys(classes).map(function (key) {\n return classes[key] ? key : null;\n }).filter(function (key) {\n return key;\n });\n}\n\nfunction normalizeIconArgs(icon$$1) {\n if (icon$$1 === null) {\n return null;\n }\n\n if (_typeof(icon$$1) === 'object' && icon$$1.prefix && icon$$1.iconName) {\n return icon$$1;\n }\n\n if (Array.isArray(icon$$1) && icon$$1.length === 2) {\n return {\n prefix: icon$$1[0],\n iconName: icon$$1[1]\n };\n }\n\n if (typeof icon$$1 === 'string') {\n return {\n prefix: 'fas',\n iconName: icon$$1\n };\n }\n}\n\nfunction FontAwesomeIcon(props) {\n var iconArgs = props.icon,\n maskArgs = props.mask,\n symbol = props.symbol,\n className = props.className,\n title = props.title;\n var iconLookup = normalizeIconArgs(iconArgs);\n var classes = objectWithKey('classes', [].concat(_toConsumableArray(classList(props)), _toConsumableArray(className.split(' '))));\n var transform = objectWithKey('transform', typeof props.transform === 'string' ? parse.transform(props.transform) : props.transform);\n var mask = objectWithKey('mask', normalizeIconArgs(maskArgs));\n var renderedIcon = icon(iconLookup, _objectSpread({}, classes, transform, mask, {\n symbol: symbol,\n title: title\n }));\n\n if (!renderedIcon) {\n log('Could not find icon', iconLookup);\n return null;\n }\n\n var abstract = renderedIcon.abstract;\n var extraProps = {};\n Object.keys(props).forEach(function (key) {\n if (!FontAwesomeIcon.defaultProps.hasOwnProperty(key)) {\n extraProps[key] = props[key];\n }\n });\n return convertCurry(abstract[0], extraProps);\n}\nFontAwesomeIcon.displayName = 'FontAwesomeIcon';\nFontAwesomeIcon.propTypes = {\n border: PropTypes.bool,\n className: PropTypes.string,\n mask: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),\n fixedWidth: PropTypes.bool,\n inverse: PropTypes.bool,\n flip: PropTypes.oneOf(['horizontal', 'vertical', 'both']),\n icon: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),\n listItem: PropTypes.bool,\n pull: PropTypes.oneOf(['right', 'left']),\n pulse: PropTypes.bool,\n rotation: PropTypes.oneOf([90, 180, 270]),\n size: PropTypes.oneOf(['lg', 'xs', 'sm', '1x', '2x', '3x', '4x', '5x', '6x', '7x', '8x', '9x', '10x']),\n spin: PropTypes.bool,\n symbol: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),\n title: PropTypes.string,\n transform: PropTypes.oneOfType([PropTypes.string, PropTypes.object])\n};\nFontAwesomeIcon.defaultProps = {\n border: false,\n className: '',\n mask: null,\n fixedWidth: false,\n inverse: false,\n flip: null,\n icon: null,\n listItem: false,\n pull: null,\n pulse: false,\n rotation: null,\n size: null,\n spin: false,\n symbol: false,\n title: '',\n transform: null\n};\nvar convertCurry = convert.bind(null, React.createElement);\n\nexport { FontAwesomeIcon };\n", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _helpers = require(\"../utils/helpers\");\n\nvar _Paper = _interopRequireDefault(require(\"../Paper\"));\n\n// @inheritedComponent Paper\nvar styles = function styles(theme) {\n var backgroundColorDefault = theme.palette.type === 'light' ? theme.palette.grey[100] : theme.palette.grey[900];\n return {\n /* Styles applied to the root element. */\n root: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n boxSizing: 'border-box',\n // Prevent padding issue with the Modal and fixed positioned AppBar.\n zIndex: theme.zIndex.appBar,\n flexShrink: 0\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`position=\"fixed\"` + ("`" + `. */\n positionFixed: {\n position: 'fixed',\n top: 0,\n left: 'auto',\n right: 0\n },\n\n /* Styles applied to the root element if `)) + (("`" + `position=\"absolute\"`) + ("`" + `. */\n positionAbsolute: {\n position: 'absolute',\n top: 0,\n left: 'auto',\n right: 0\n },\n\n /* Styles applied to the root element if `))))) + (((("`" + (`position=\"sticky\"` + "`")) + (`. */\n positionSticky: {\n position: 'sticky',\n top: 0,\n left: 'auto',\n right: 0\n },\n\n /* Styles applied to the root element if ` + ("`" + `position=\"static\"`))) + (("`" + (`. */\n positionStatic: {\n position: 'static'\n },\n\n /* Styles applied to the root element if ` + "`")) + (`position=\"relative\"` + ("`" + `. */\n positionRelative: {\n position: 'relative'\n },\n\n /* Styles applied to the root element if `)))) + ((("`" + (`color=\"default\"` + "`")) + (`. */\n colorDefault: {\n backgroundColor: backgroundColorDefault,\n color: theme.palette.getContrastText(backgroundColorDefault)\n },\n\n /* Styles applied to the root element if ` + ("`" + `color=\"primary\"`))) + (("`" + (`. */\n colorPrimary: {\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText\n },\n\n /* Styles applied to the root element if ` + "`")) + ((`color=\"secondary\"` + "`") + (`. */\n colorSecondary: {\n backgroundColor: theme.palette.secondary.main,\n color: theme.palette.secondary.contrastText\n }\n };\n};\n\nexports.styles = styles;\n\nfunction AppBar(props) {\n var _classNames;\n\n var children = props.children,\n classes = props.classes,\n classNameProp = props.className,\n color = props.color,\n position = props.position,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"color\", \"position\"]);\n var className = (0, _classnames.default)(classes.root, classes[\"position\".concat((0, _helpers.capitalize)(position))], (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes[\"color\".concat((0, _helpers.capitalize)(color))], color !== 'inherit'), (0, _defineProperty2.default)(_classNames, 'mui-fixed', position === 'fixed'), _classNames), classNameProp);\n return _react.default.createElement(_Paper.default, (0, _extends2.default)({\n square: true,\n component: \"header\",\n elevation: 4,\n className: className\n }, other), children);\n}\n\nprocess.env.NODE_ENV !== \"production\" ? AppBar.propTypes = {\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node.isRequired,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The color of the component. It supports those theme colors that make sense for this component.\r\n */\n color: _propTypes.default.oneOf(['inherit', 'primary', 'secondary', 'default']),\n\n /**\r\n * The positioning type. The behavior of the different options is described\r\n * [in the MDN web docs](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning).\r\n * Note: ` + "`")))))))) + (((((((`sticky` + ("`" + ` is not universally supported and will fall back to `)) + ("`" + (`static` + "`"))) + ((` when unavailable.\r\n */\n position: _propTypes.default.oneOf(['fixed', 'absolute', 'sticky', 'static', 'relative'])\n} : void 0;\nAppBar.defaultProps = {\n color: 'primary',\n position: 'fixed'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiAppBar'\n})(AppBar);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _AppBar.default;\n }\n});\n\nvar _AppBar = _interopRequireDefault(require(\"./AppBar\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf3 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _assertThisInitialized2 = _interopRequireDefault(require(\"@babel/runtime/helpers/assertThisInitialized\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _reactDom = _interopRequireDefault(require(\"react-dom\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _ownerWindow = _interopRequireDefault(require(\"../utils/ownerWindow\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _NoSsr = _interopRequireDefault(require(\"../NoSsr\"));\n\nvar _focusVisible = require(\"./focusVisible\");\n\nvar _TouchRipple = _interopRequireDefault(require(\"./TouchRipple\"));\n\nvar _createRippleHandler = _interopRequireDefault(require(\"./createRippleHandler\"));\n\nvar styles = {\n /* Styles applied to the root element. */\n root: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n // Remove grey highlight\n WebkitTapHighlightColor: 'transparent',\n backgroundColor: 'transparent',\n // Reset default value\n // We disable the focus ring for mouse, touch and keyboard users.\n outline: 'none',\n border: 0,\n margin: 0,\n // Remove the margin in Safari\n borderRadius: 0,\n padding: 0,\n // Remove the padding in Firefox\n cursor: 'pointer',\n userSelect: 'none',\n verticalAlign: 'middle',\n '-moz-appearance': 'none',\n // Reset\n '-webkit-appearance': 'none',\n // Reset\n textDecoration: 'none',\n // So we take precedent over the style of a native element.\n color: 'inherit',\n '&::-moz-focus-inner': {\n borderStyle: 'none' // Remove Firefox dotted outline.\n\n },\n '&$disabled': {\n pointerEvents: 'none',\n // Disable link interactions\n cursor: 'default'\n }\n },\n\n /* Styles applied to the root element if ` + ("`" + `disabled={true}`)) + ("`" + (`. */\n disabled: {},\n\n /* Styles applied to the root element if keyboard focused. */\n focusVisible: {}\n};\n/* istanbul ignore if */\n\nexports.styles = styles;\n\nif (process.env.NODE_ENV !== 'production' && !_react.default.createContext) {\n throw new Error('Material-UI: react@16.3.0 or greater is required.');\n}\n/**\r\n * ` + "`")))) + (((`ButtonBase` + ("`" + ` contains as few styles as possible.\r\n * It aims to be a simple building block for creating a button.\r\n * It contains a load of style reset and some focus/ripple logic.\r\n */\n\n\nvar ButtonBase =\n/*#__PURE__*/\nfunction (_React$Component) {\n (0, _inherits2.default)(ButtonBase, _React$Component);\n\n function ButtonBase() {\n var _getPrototypeOf2;\n\n var _this;\n\n (0, _classCallCheck2.default)(this, ButtonBase);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(ButtonBase)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {};\n _this.keyDown = false;\n _this.focusVisibleCheckTime = 50;\n _this.focusVisibleMaxCheckTimes = 5;\n _this.handleMouseDown = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'MouseDown', 'start', function () {\n clearTimeout(_this.focusVisibleTimeout);\n\n if (_this.state.focusVisible) {\n _this.setState({\n focusVisible: false\n });\n }\n });\n _this.handleMouseUp = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'MouseUp', 'stop');\n _this.handleMouseLeave = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'MouseLeave', 'stop', function (event) {\n if (_this.state.focusVisible) {\n event.preventDefault();\n }\n });\n _this.handleTouchStart = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'TouchStart', 'start');\n _this.handleTouchEnd = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'TouchEnd', 'stop');\n _this.handleTouchMove = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'TouchMove', 'stop');\n _this.handleContextMenu = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'ContextMenu', 'stop');\n _this.handleBlur = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), 'Blur', 'stop', function () {\n clearTimeout(_this.focusVisibleTimeout);\n\n if (_this.state.focusVisible) {\n _this.setState({\n focusVisible: false\n });\n }\n });\n\n _this.onRippleRef = function (node) {\n _this.ripple = node;\n };\n\n _this.onFocusVisibleHandler = function (event) {\n _this.keyDown = false;\n\n _this.setState({\n focusVisible: true\n });\n\n if (_this.props.onFocusVisible) {\n _this.props.onFocusVisible(event);\n }\n };\n\n _this.handleKeyDown = function (event) {\n var _this$props = _this.props,\n component = _this$props.component,\n focusRipple = _this$props.focusRipple,\n onKeyDown = _this$props.onKeyDown,\n onClick = _this$props.onClick; // Check if key is already down to avoid repeats being counted as multiple activations\n\n if (focusRipple && !_this.keyDown && _this.state.focusVisible && _this.ripple && event.key === ' ') {\n _this.keyDown = true;\n event.persist();\n\n _this.ripple.stop(event, function () {\n _this.ripple.start(event);\n });\n }\n\n if (onKeyDown) {\n onKeyDown(event);\n } // Keyboard accessibility for non interactive elements\n\n\n if (event.target === event.currentTarget && component && component !== 'button' && (event.key === ' ' || event.key === 'Enter') && !(_this.button.tagName === 'A' && _this.button.href)) {\n event.preventDefault();\n\n if (onClick) {\n onClick(event);\n }\n }\n };\n\n _this.handleKeyUp = function (event) {\n if (_this.props.focusRipple && event.key === ' ' && _this.ripple && _this.state.focusVisible) {\n _this.keyDown = false;\n event.persist();\n\n _this.ripple.stop(event, function () {\n _this.ripple.pulsate(event);\n });\n }\n\n if (_this.props.onKeyUp) {\n _this.props.onKeyUp(event);\n }\n };\n\n _this.handleFocus = function (event) {\n if (_this.props.disabled) {\n return;\n } // Fix for https://github.com/facebook/react/issues/7769\n\n\n if (!_this.button) {\n _this.button = event.currentTarget;\n }\n\n event.persist();\n (0, _focusVisible.detectFocusVisible)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), _this.button, function () {\n _this.onFocusVisibleHandler(event);\n });\n\n if (_this.props.onFocus) {\n _this.props.onFocus(event);\n }\n };\n\n return _this;\n }\n\n (0, _createClass2.default)(ButtonBase, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n this.button = _reactDom.default.findDOMNode(this);\n (0, _focusVisible.listenForFocusKeys)((0, _ownerWindow.default)(this.button));\n\n if (this.props.action) {\n this.props.action({\n focusVisible: function focusVisible() {\n _this2.setState({\n focusVisible: true\n });\n\n _this2.button.focus();\n }\n });\n }\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate(prevProps, prevState) {\n if (this.props.focusRipple && !this.props.disableRipple && !prevState.focusVisible && this.state.focusVisible) {\n this.ripple.pulsate();\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n clearTimeout(this.focusVisibleTimeout);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _classNames;\n\n var _this$props2 = this.props,\n action = _this$props2.action,\n buttonRef = _this$props2.buttonRef,\n centerRipple = _this$props2.centerRipple,\n children = _this$props2.children,\n classes = _this$props2.classes,\n classNameProp = _this$props2.className,\n component = _this$props2.component,\n disabled = _this$props2.disabled,\n disableRipple = _this$props2.disableRipple,\n disableTouchRipple = _this$props2.disableTouchRipple,\n focusRipple = _this$props2.focusRipple,\n focusVisibleClassName = _this$props2.focusVisibleClassName,\n onBlur = _this$props2.onBlur,\n onFocus = _this$props2.onFocus,\n onFocusVisible = _this$props2.onFocusVisible,\n onKeyDown = _this$props2.onKeyDown,\n onKeyUp = _this$props2.onKeyUp,\n onMouseDown = _this$props2.onMouseDown,\n onMouseLeave = _this$props2.onMouseLeave,\n onMouseUp = _this$props2.onMouseUp,\n onTouchEnd = _this$props2.onTouchEnd,\n onTouchMove = _this$props2.onTouchMove,\n onTouchStart = _this$props2.onTouchStart,\n tabIndex = _this$props2.tabIndex,\n TouchRippleProps = _this$props2.TouchRippleProps,\n type = _this$props2.type,\n other = (0, _objectWithoutProperties2.default)(_this$props2, [\"action\", \"buttonRef\", \"centerRipple\", \"children\", \"classes\", \"className\", \"component\", \"disabled\", \"disableRipple\", \"disableTouchRipple\", \"focusRipple\", \"focusVisibleClassName\", \"onBlur\", \"onFocus\", \"onFocusVisible\", \"onKeyDown\", \"onKeyUp\", \"onMouseDown\", \"onMouseLeave\", \"onMouseUp\", \"onTouchEnd\", \"onTouchMove\", \"onTouchStart\", \"tabIndex\", \"TouchRippleProps\", \"type\"]);\n var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), (0, _defineProperty2.default)(_classNames, classes.focusVisible, this.state.focusVisible), (0, _defineProperty2.default)(_classNames, focusVisibleClassName, this.state.focusVisible), _classNames), classNameProp);\n var ComponentProp = component;\n\n if (ComponentProp === 'button' && other.href) {\n ComponentProp = 'a';\n }\n\n var buttonProps = {};\n\n if (ComponentProp === 'button') {\n buttonProps.type = type || 'button';\n buttonProps.disabled = disabled;\n } else {\n buttonProps.role = 'button';\n }\n\n return _react.default.createElement(ComponentProp, (0, _extends2.default)({\n className: className,\n onBlur: this.handleBlur,\n onFocus: this.handleFocus,\n onKeyDown: this.handleKeyDown,\n onKeyUp: this.handleKeyUp,\n onMouseDown: this.handleMouseDown,\n onMouseLeave: this.handleMouseLeave,\n onMouseUp: this.handleMouseUp,\n onTouchEnd: this.handleTouchEnd,\n onTouchMove: this.handleTouchMove,\n onTouchStart: this.handleTouchStart,\n onContextMenu: this.handleContextMenu,\n ref: buttonRef,\n tabIndex: disabled ? '-1' : tabIndex\n }, buttonProps, other), children, !disableRipple && !disabled ? _react.default.createElement(_NoSsr.default, null, _react.default.createElement(_TouchRipple.default, (0, _extends2.default)({\n innerRef: this.onRippleRef,\n center: centerRipple\n }, TouchRippleProps))) : null);\n }\n }], [{\n key: \"getDerivedStateFromProps\",\n value: function getDerivedStateFromProps(nextProps, prevState) {\n if (typeof prevState.focusVisible === 'undefined') {\n return {\n focusVisible: false,\n lastDisabled: nextProps.disabled\n };\n } // The blur won't fire when the disabled state is set on a focused input.\n // We need to book keep the focused state manually.\n\n\n if (!prevState.prevState && nextProps.disabled && prevState.focusVisible) {\n return {\n focusVisible: false,\n lastDisabled: nextProps.disabled\n };\n }\n\n return {\n lastDisabled: nextProps.disabled\n };\n }\n }]);\n return ButtonBase;\n}(_react.default.Component);\n\nprocess.env.NODE_ENV !== \"production\" ? ButtonBase.propTypes = {\n /**\r\n * Callback fired when the component mounts.\r\n * This is useful when you want to trigger an action programmatically.\r\n * It currently only supports `)) + ("`" + (`focusVisible()` + "`"))) + ((` action.\r\n *\r\n * @param {object} actions This object contains all possible actions\r\n * that can be triggered programmatically.\r\n */\n action: _propTypes.default.func,\n\n /**\r\n * Use that property to pass a ref callback to the native button component.\r\n */\n buttonRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, the ripples will be centered.\r\n * They won't start at the cursor interaction position.\r\n */\n centerRipple: _propTypes.default.bool,\n\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If ` + "`"))))) + ((((`true` + ("`" + `, the base button will be disabled.\r\n */\n disabled: _propTypes.default.bool,\n\n /**\r\n * If `)) + ("`" + (`true` + "`"))) + ((`, the ripple effect will be disabled.\r\n */\n disableRipple: _propTypes.default.bool,\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, the touch ripple effect will be disabled.\r\n */\n disableTouchRipple: _propTypes.default.bool,\n\n /**\r\n * If ` + "`")))) + (((`true` + ("`" + `, the base button will have a keyboard focus ripple.\r\n * `)) + ("`" + (`disableRipple` + "`"))) + ((` must also be ` + ("`" + `false`)) + (("`" + `.\r\n */\n focusRipple: _propTypes.default.bool,\n\n /**\r\n * This property can help a person know which element has the keyboard focus.\r\n * The class name will be applied when the element gain the focus through a keyboard interaction.\r\n * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).\r\n * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/master/explainer.md).\r\n * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `) + ("`" + `focus-visible`)))))) + ((((("`" + (` class to other components\r\n * if needed.\r\n */\n focusVisibleClassName: _propTypes.default.string,\n\n /**\r\n * @ignore\r\n */\n onBlur: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onClick: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onFocus: _propTypes.default.func,\n\n /**\r\n * Callback fired when the component is focused with a keyboard.\r\n * We trigger a ` + "`")) + (`onFocus` + ("`" + ` callback too.\r\n */\n onFocusVisible: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onKeyDown: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onKeyUp: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onMouseDown: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onMouseLeave: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onMouseUp: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onTouchEnd: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onTouchMove: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n onTouchStart: _propTypes.default.func,\n\n /**\r\n * @ignore\r\n */\n role: _propTypes.default.string,\n\n /**\r\n * @ignore\r\n */\n tabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),\n\n /**\r\n * Properties applied to the `))) + (("`" + (`TouchRipple` + "`")) + (` element.\r\n */\n TouchRippleProps: _propTypes.default.object,\n\n /**\r\n * Used to control the button's purpose.\r\n * This property passes the value to the ` + ("`" + `type`)))) + ((("`" + (` attribute of the native button component.\r\n * Valid property values include ` + "`")) + (`button` + ("`" + `, `))) + (("`" + (`submit` + "`")) + ((`, and ` + "`") + (`reset` + "`"))))) + ((((`.\r\n */\n type: _propTypes.default.string\n} : void 0;\nButtonBase.defaultProps = {\n centerRipple: false,\n component: 'button',\n disableRipple: false,\n disableTouchRipple: false,\n focusRipple: false,\n tabIndex: '0',\n type: 'button'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiButtonBase'\n})(ButtonBase);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf3 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _Transition = _interopRequireDefault(require(\"react-transition-group/Transition\"));\n\n/**\r\n * @ignore - internal component.\r\n */\nvar Ripple =\n/*#__PURE__*/\nfunction (_React$Component) {\n (0, _inherits2.default)(Ripple, _React$Component);\n\n function Ripple() {\n var _getPrototypeOf2;\n\n var _this;\n\n (0, _classCallCheck2.default)(this, Ripple);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(Ripple)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n visible: false,\n leaving: false\n };\n\n _this.handleEnter = function () {\n _this.setState({\n visible: true\n });\n };\n\n _this.handleExit = function () {\n _this.setState({\n leaving: true\n });\n };\n\n return _this;\n }\n\n (0, _createClass2.default)(Ripple, [{\n key: \"render\",\n value: function render() {\n var _classNames, _classNames2;\n\n var _this$props = this.props,\n classes = _this$props.classes,\n classNameProp = _this$props.className,\n pulsate = _this$props.pulsate,\n rippleX = _this$props.rippleX,\n rippleY = _this$props.rippleY,\n rippleSize = _this$props.rippleSize,\n other = (0, _objectWithoutProperties2.default)(_this$props, [\"classes\", \"className\", \"pulsate\", \"rippleX\", \"rippleY\", \"rippleSize\"]);\n var _this$state = this.state,\n visible = _this$state.visible,\n leaving = _this$state.leaving;\n var rippleClassName = (0, _classnames.default)(classes.ripple, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.rippleVisible, visible), (0, _defineProperty2.default)(_classNames, classes.ripplePulsate, pulsate), _classNames), classNameProp);\n var rippleStyles = {\n width: rippleSize,\n height: rippleSize,\n top: -(rippleSize / 2) + rippleY,\n left: -(rippleSize / 2) + rippleX\n };\n var childClassName = (0, _classnames.default)(classes.child, (_classNames2 = {}, (0, _defineProperty2.default)(_classNames2, classes.childLeaving, leaving), (0, _defineProperty2.default)(_classNames2, classes.childPulsate, pulsate), _classNames2));\n return _react.default.createElement(_Transition.default, (0, _extends2.default)({\n onEnter: this.handleEnter,\n onExit: this.handleExit\n }, other), _react.default.createElement(\"span\", {\n className: rippleClassName,\n style: rippleStyles\n }, _react.default.createElement(\"span\", {\n className: childClassName\n })));\n }\n }]);\n return Ripple;\n}(_react.default.Component);\n\nprocess.env.NODE_ENV !== \"production\" ? Ripple.propTypes = {\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, the ripple pulsates, typically indicating the keyboard focus state of an element.\r\n */\n pulsate: _propTypes.default.bool,\n\n /**\r\n * Diameter of the ripple.\r\n */\n rippleSize: _propTypes.default.number,\n\n /**\r\n * Horizontal position of the ripple center.\r\n */\n rippleX: _propTypes.default.number,\n\n /**\r\n * Vertical position of the ripple center.\r\n */\n rippleY: _propTypes.default.number\n} : void 0;\nRipple.defaultProps = {\n pulsate: false\n};\nvar _default = Ripple;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = exports.DELAY_RIPPLE = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _toConsumableArray2 = _interopRequireDefault(require(\"@babel/runtime/helpers/toConsumableArray\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf3 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _assertThisInitialized2 = _interopRequireDefault(require(\"@babel/runtime/helpers/assertThisInitialized\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _reactDom = _interopRequireDefault(require(\"react-dom\"));\n\nvar _TransitionGroup = _interopRequireDefault(require(\"react-transition-group/TransitionGroup\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _Ripple = _interopRequireDefault(require(\"./Ripple\"));\n\nvar DURATION = 550;\nvar DELAY_RIPPLE = 80;\nexports.DELAY_RIPPLE = DELAY_RIPPLE;\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n display: 'block',\n position: 'absolute',\n overflow: 'hidden',\n borderRadius: 'inherit',\n width: '100%',\n height: '100%',\n left: 0,\n top: 0,\n pointerEvents: 'none',\n zIndex: 0\n },\n\n /* Styles applied to the internal ` + "`"))) + ((`Ripple` + ("`" + ` components `)) + ("`" + (`ripple` + "`")))) + (((` class. */\n ripple: {\n width: 50,\n height: 50,\n left: 0,\n top: 0,\n opacity: 0,\n position: 'absolute'\n },\n\n /* Styles applied to the internal ` + ("`" + `Ripple`)) + ("`" + (` components ` + "`"))) + ((`rippleVisible` + ("`" + ` class. */\n rippleVisible: {\n opacity: 0.3,\n transform: 'scale(1)',\n animation: \"mui-ripple-enter \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n // Backward compatible logic between JSS v9 and v10.\n // To remove with the release of Material-UI v4\n animationName: '$mui-ripple-enter'\n },\n\n /* Styles applied to the internal `)) + (("`" + `Ripple`) + ("`" + ` components `))))))) + (((((("`" + (`ripplePulsate` + "`")) + (` class. */\n ripplePulsate: {\n animationDuration: \"\".concat(theme.transitions.duration.shorter, \"ms\")\n },\n\n /* Styles applied to the internal ` + ("`" + `Ripple`))) + (("`" + (` components ` + "`")) + (`child` + ("`" + ` class. */\n child: {\n opacity: 1,\n display: 'block',\n width: '100%',\n height: '100%',\n borderRadius: '50%',\n backgroundColor: 'currentColor'\n },\n\n /* Styles applied to the internal `)))) + ((("`" + (`Ripple` + "`")) + (` components ` + ("`" + `childLeaving`))) + (("`" + (` class. */\n childLeaving: {\n opacity: 0,\n animation: \"mui-ripple-exit \".concat(DURATION, \"ms \").concat(theme.transitions.easing.easeInOut),\n // Backward compatible logic between JSS v9 and v10.\n // To remove with the release of Material-UI v4\n animationName: '$mui-ripple-exit'\n },\n\n /* Styles applied to the internal ` + "`")) + (`Ripple` + ("`" + ` components `))))) + (((("`" + (`childPulsate` + "`")) + (` class. */\n childPulsate: {\n position: 'absolute',\n left: 0,\n top: 0,\n animation: \"mui-ripple-pulsate 2500ms \".concat(theme.transitions.easing.easeInOut, \" 200ms infinite\"),\n // Backward compatible logic between JSS v9 and v10.\n // To remove with the release of Material-UI v4\n animationName: '$mui-ripple-pulsate'\n },\n '@keyframes mui-ripple-enter': {\n '0%': {\n transform: 'scale(0)',\n opacity: 0.1\n },\n '100%': {\n transform: 'scale(1)',\n opacity: 0.3\n }\n },\n '@keyframes mui-ripple-exit': {\n '0%': {\n opacity: 1\n },\n '100%': {\n opacity: 0\n }\n },\n '@keyframes mui-ripple-pulsate': {\n '0%': {\n transform: 'scale(1)'\n },\n '50%': {\n transform: 'scale(0.92)'\n },\n '100%': {\n transform: 'scale(1)'\n }\n }\n };\n};\n\nexports.styles = styles;\n\nvar TouchRipple =\n/*#__PURE__*/\nfunction (_React$PureComponent) {\n (0, _inherits2.default)(TouchRipple, _React$PureComponent);\n\n function TouchRipple() {\n var _getPrototypeOf2;\n\n var _this;\n\n (0, _classCallCheck2.default)(this, TouchRipple);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(TouchRipple)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n nextKey: 0,\n ripples: []\n };\n\n _this.pulsate = function () {\n _this.start({}, {\n pulsate: true\n });\n };\n\n _this.start = function () {\n var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var cb = arguments.length > 2 ? arguments[2] : undefined;\n var _options$pulsate = options.pulsate,\n pulsate = _options$pulsate === void 0 ? false : _options$pulsate,\n _options$center = options.center,\n center = _options$center === void 0 ? _this.props.center || options.pulsate : _options$center,\n _options$fakeElement = options.fakeElement,\n fakeElement = _options$fakeElement === void 0 ? false : _options$fakeElement;\n\n if (event.type === 'mousedown' && _this.ignoringMouseDown) {\n _this.ignoringMouseDown = false;\n return;\n }\n\n if (event.type === 'touchstart') {\n _this.ignoringMouseDown = true;\n }\n\n var element = fakeElement ? null : _reactDom.default.findDOMNode((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));\n var rect = element ? element.getBoundingClientRect() : {\n width: 0,\n height: 0,\n left: 0,\n top: 0\n }; // Get the size of the ripple\n\n var rippleX;\n var rippleY;\n var rippleSize;\n\n if (center || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {\n rippleX = Math.round(rect.width / 2);\n rippleY = Math.round(rect.height / 2);\n } else {\n var clientX = event.clientX ? event.clientX : event.touches[0].clientX;\n var clientY = event.clientY ? event.clientY : event.touches[0].clientY;\n rippleX = Math.round(clientX - rect.left);\n rippleY = Math.round(clientY - rect.top);\n }\n\n if (center) {\n rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3); // For some reason the animation is broken on Mobile Chrome if the size if even.\n\n if (rippleSize % 2 === 0) {\n rippleSize += 1;\n }\n } else {\n var sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;\n var sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;\n rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));\n } // Touche devices\n\n\n if (event.touches) {\n // Prepare the ripple effect.\n _this.startTimerCommit = function () {\n _this.startCommit({\n pulsate: pulsate,\n rippleX: rippleX,\n rippleY: rippleY,\n rippleSize: rippleSize,\n cb: cb\n });\n }; // Delay the execution of the ripple effect.\n\n\n _this.startTimer = setTimeout(function () {\n if (_this.startTimerCommit) {\n _this.startTimerCommit();\n\n _this.startTimerCommit = null;\n }\n }, DELAY_RIPPLE); // We have to make a tradeoff with this value.\n } else {\n _this.startCommit({\n pulsate: pulsate,\n rippleX: rippleX,\n rippleY: rippleY,\n rippleSize: rippleSize,\n cb: cb\n });\n }\n };\n\n _this.startCommit = function (params) {\n var pulsate = params.pulsate,\n rippleX = params.rippleX,\n rippleY = params.rippleY,\n rippleSize = params.rippleSize,\n cb = params.cb;\n\n _this.setState(function (state) {\n return {\n nextKey: state.nextKey + 1,\n ripples: [].concat((0, _toConsumableArray2.default)(state.ripples), [_react.default.createElement(_Ripple.default, {\n key: state.nextKey,\n classes: _this.props.classes,\n timeout: {\n exit: DURATION,\n enter: DURATION\n },\n pulsate: pulsate,\n rippleX: rippleX,\n rippleY: rippleY,\n rippleSize: rippleSize\n })])\n };\n }, cb);\n };\n\n _this.stop = function (event, cb) {\n clearTimeout(_this.startTimer);\n var ripples = _this.state.ripples; // The touch interaction occurs too quickly.\n // We still want to show ripple effect.\n\n if (event.type === 'touchend' && _this.startTimerCommit) {\n event.persist();\n\n _this.startTimerCommit();\n\n _this.startTimerCommit = null;\n _this.startTimer = setTimeout(function () {\n _this.stop(event, cb);\n });\n return;\n }\n\n _this.startTimerCommit = null;\n\n if (ripples && ripples.length) {\n _this.setState({\n ripples: ripples.slice(1)\n }, cb);\n }\n };\n\n return _this;\n }\n\n (0, _createClass2.default)(TouchRipple, [{\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n clearTimeout(this.startTimer);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n center = _this$props.center,\n classes = _this$props.classes,\n className = _this$props.className,\n other = (0, _objectWithoutProperties2.default)(_this$props, [\"center\", \"classes\", \"className\"]);\n return _react.default.createElement(_TransitionGroup.default, (0, _extends2.default)({\n component: \"span\",\n enter: true,\n exit: true,\n className: (0, _classnames.default)(classes.root, className)\n }, other), this.state.ripples);\n }\n }]);\n return TouchRipple;\n}(_react.default.PureComponent);\n\nprocess.env.NODE_ENV !== \"production\" ? TouchRipple.propTypes = {\n /**\r\n * If ` + ("`" + `true`))) + (("`" + (`, the ripple starts at the center of the component\r\n * rather than at the point of interaction.\r\n */\n center: _propTypes.default.bool,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string\n} : void 0;\nTouchRipple.defaultProps = {\n center: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n flip: false,\n name: 'MuiTouchRipple'\n})(TouchRipple);\n\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n/* eslint-disable import/no-mutable-exports */\nvar createRippleHandler = function createRippleHandler(instance, eventName, action, cb) {\n return function (event) {\n if (cb) {\n cb.call(instance, event);\n }\n\n var ignore = false; // Ignore events that have been ` + "`")) + (`event.preventDefault()` + ("`" + ` marked.\n\n if (event.defaultPrevented) {\n ignore = true;\n }\n\n if (instance.props.disableTouchRipple && eventName !== 'Blur') {\n ignore = true;\n }\n\n if (!ignore && instance.ripple) {\n instance.ripple[action](event);\n }\n\n if (typeof instance.props[\"on\".concat(eventName)] === 'function') {\n instance.props[\"on\".concat(eventName)](event);\n }\n\n return true;\n };\n};\n/* istanbul ignore if */\n\n\nif (typeof window === 'undefined') {\n createRippleHandler = function createRippleHandler() {\n return function () {};\n };\n}\n\nvar _default = createRippleHandler;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.detectFocusVisible = detectFocusVisible;\nexports.listenForFocusKeys = listenForFocusKeys;\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _ownerDocument = _interopRequireDefault(require(\"../utils/ownerDocument\"));\n\nvar internal = {\n focusKeyPressed: false,\n keyUpEventTimeout: -1\n};\n\nfunction findActiveElement(doc) {\n var activeElement = doc.activeElement;\n\n while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) {\n activeElement = activeElement.shadowRoot.activeElement;\n }\n\n return activeElement;\n}\n\nfunction detectFocusVisible(instance, element, callback) {\n var attempt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(instance.focusVisibleCheckTime, 'Material-UI: missing instance.focusVisibleCheckTime.') : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(instance.focusVisibleMaxCheckTimes, 'Material-UI: missing instance.focusVisibleMaxCheckTimes.') : void 0;\n instance.focusVisibleTimeout = setTimeout(function () {\n var doc = (0, _ownerDocument.default)(element);\n var activeElement = findActiveElement(doc);\n\n if (internal.focusKeyPressed && (activeElement === element || element.contains(activeElement))) {\n callback();\n } else if (attempt < instance.focusVisibleMaxCheckTimes) {\n detectFocusVisible(instance, element, callback, attempt + 1);\n }\n }, instance.focusVisibleCheckTime);\n}\n\nvar FOCUS_KEYS = [9, // 'Tab',\n13, // 'Enter',\n27, // 'Escape',\n32, // ' ',\n37, // 'ArrowLeft',\n38, // 'ArrowUp',\n39, // 'ArrowRight',\n40];\n\nfunction isFocusKey(event) {\n // Use event.keyCode to support IE 11\n return FOCUS_KEYS.indexOf(event.keyCode) > -1;\n}\n\nvar handleKeyUpEvent = function handleKeyUpEvent(event) {\n if (isFocusKey(event)) {\n internal.focusKeyPressed = true; // Let's consider that the user is using a keyboard during a window frame of 500ms.\n\n clearTimeout(internal.keyUpEventTimeout);\n internal.keyUpEventTimeout = setTimeout(function () {\n internal.focusKeyPressed = false;\n }, 500);\n }\n};\n\nfunction listenForFocusKeys(win) {\n // The event listener will only be added once per window.\n // Duplicate event listeners will be ignored by addEventListener.\n // Also, this logic is client side only, we don't need a teardown.\n win.addEventListener('keyup', handleKeyUpEvent);\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _ButtonBase.default;\n }\n});\n\nvar _ButtonBase = _interopRequireDefault(require(\"./ButtonBase\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _createBreakpoints = require(\"../styles/createBreakpoints\");\n\nvar _requirePropFactory = _interopRequireDefault(require(\"../utils/requirePropFactory\"));\n\n// A grid component using the following libs as inspiration.\n//\n// For the implementation:\n// - http://v4-alpha.getbootstrap.com/layout/flexbox-grid/\n// - https://github.com/kristoferjoseph/flexboxgrid/blob/master/src/css/flexboxgrid.css\n// - https://github.com/roylee0704/react-flexbox-grid\n// - https://material.angularjs.org/latest/layout/introduction\n//\n// Follow this flexbox Guide to better understand the underlying model:\n// - https://css-tricks.com/snippets/css/a-guide-to-flexbox/\nvar GUTTERS = [0, 8, 16, 24, 32, 40];\nvar GRID_SIZES = ['auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];\n\nfunction generateGrid(globalStyles, theme, breakpoint) {\n var styles = {};\n GRID_SIZES.forEach(function (size) {\n var key = \"grid-\".concat(breakpoint, \"-\").concat(size);\n\n if (size === true) {\n // For the auto layouting\n styles[key] = {\n flexBasis: 0,\n flexGrow: 1,\n maxWidth: '100%'\n };\n return;\n }\n\n if (size === 'auto') {\n styles[key] = {\n flexBasis: 'auto',\n flexGrow: 0,\n maxWidth: 'none'\n };\n return;\n } // Keep 7 significant numbers.\n\n\n var width = \"\".concat(Math.round(size / 12 * 10e7) / 10e5, \"%\"); // Close to the bootstrap implementation:\n // https://github.com/twbs/bootstrap/blob/8fccaa2439e97ec72a4b7dc42ccc1f649790adb0/scss/mixins/_grid.scss#L41\n\n styles[key] = {\n flexBasis: width,\n flexGrow: 0,\n maxWidth: width\n };\n }); // No need for a media query for the first size.\n\n if (breakpoint === 'xs') {\n (0, _extends2.default)(globalStyles, styles);\n } else {\n globalStyles[theme.breakpoints.up(breakpoint)] = styles;\n }\n}\n\nfunction generateGutter(theme, breakpoint) {\n var styles = {};\n GUTTERS.forEach(function (spacing, index) {\n if (index === 0) {\n // Skip the default style.\n return;\n }\n\n styles[\"spacing-\".concat(breakpoint, \"-\").concat(spacing)] = {\n margin: -spacing / 2,\n width: \"calc(100% + \".concat(spacing, \"px)\"),\n '& > $item': {\n padding: spacing / 2\n }\n };\n });\n return styles;\n} // Default CSS values\n// flex: '0 1 auto',\n// flexDirection: 'row',\n// alignItems: 'flex-start',\n// flexWrap: 'nowrap',\n// justifyContent: 'flex-start',\n\n\nvar styles = function styles(theme) {\n return (0, _extends2.default)({\n /* Styles applied to the root element if `)))) + ((("`" + (`container={true}` + "`")) + (`. */\n container: {\n boxSizing: 'border-box',\n display: 'flex',\n flexWrap: 'wrap',\n width: '100%'\n },\n\n /* Styles applied to the root element if ` + ("`" + `item={true}`))) + (("`" + (`. */\n item: {\n boxSizing: 'border-box',\n margin: '0' // For instance, it's useful when used with a ` + "`")) + ((`figure` + "`") + (` element.\n\n },\n\n /* Styles applied to the root element if ` + "`")))))) + (((((`zeroMinWidth={true}` + ("`" + `. */\n zeroMinWidth: {\n minWidth: 0\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`direction=\"column\"` + "`"))) + ((`. */\n 'direction-xs-column': {\n flexDirection: 'column'\n },\n\n /* Styles applied to the root element if ` + ("`" + `direction=\"column-reverse\"`)) + ("`" + (`. */\n 'direction-xs-column-reverse': {\n flexDirection: 'column-reverse'\n },\n\n /* Styles applied to the root element if ` + "`")))) + (((`direction=\"rwo-reverse\"` + ("`" + `. */\n 'direction-xs-row-reverse': {\n flexDirection: 'row-reverse'\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`wrap=\"nowrap\"` + "`"))) + ((`. */\n 'wrap-xs-nowrap': {\n flexWrap: 'nowrap'\n },\n\n /* Styles applied to the root element if ` + ("`" + `wrap=\"reverse\"`)) + (("`" + `. */\n 'wrap-xs-wrap-reverse': {\n flexWrap: 'wrap-reverse'\n },\n\n /* Styles applied to the root element if `) + ("`" + `alignItems=\"center\"`))))) + (((("`" + (`. */\n 'align-items-xs-center': {\n alignItems: 'center'\n },\n\n /* Styles applied to the root element if ` + "`")) + (`alignItems=\"flex-start\"` + ("`" + `. */\n 'align-items-xs-flex-start': {\n alignItems: 'flex-start'\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`alignItems=\"flex-end\"` + "`")) + (`. */\n 'align-items-xs-flex-end': {\n alignItems: 'flex-end'\n },\n\n /* Styles applied to the root element if ` + ("`" + `alignItems=\"baseline\"`)))) + ((("`" + (`. */\n 'align-items-xs-baseline': {\n alignItems: 'baseline'\n },\n\n /* Styles applied to the root element if ` + "`")) + (`alignContent=\"center\"` + ("`" + `. */\n 'align-content-xs-center': {\n alignContent: 'center'\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`alignContent=\"flex-start\"` + "`")) + ((`. */\n 'align-content-xs-flex-start': {\n alignContent: 'flex-start'\n },\n\n /* Styles applied to the root element if ` + "`") + (`alignContent=\"flex-end\"` + "`"))))))))) + ((((((((`. */\n 'align-content-xs-flex-end': {\n alignContent: 'flex-end'\n },\n\n /* Styles applied to the root element if ` + ("`" + `alignContent=\"space-between\"`)) + ("`" + (`. */\n 'align-content-xs-space-between': {\n alignContent: 'space-between'\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`alignContent=\"space-around\"` + ("`" + `. */\n 'align-content-xs-space-around': {\n alignContent: 'space-around'\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`justify=\"center\"` + "`")))) + (((`. */\n 'justify-xs-center': {\n justifyContent: 'center'\n },\n\n /* Styles applied to the root element if ` + ("`" + `justify=\"flex-end\"`)) + ("`" + (`. */\n 'justify-xs-flex-end': {\n justifyContent: 'flex-end'\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`justify=\"space-between\"` + ("`" + `. */\n 'justify-xs-space-between': {\n justifyContent: 'space-between'\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`justify=\"space-around\"` + "`"))))) + ((((`. */\n 'justify-xs-space-around': {\n justifyContent: 'space-around'\n },\n\n /* Styles applied to the root element if ` + ("`" + `justify=\"space-evenly\"`)) + ("`" + (`. */\n 'justify-xs-space-evenly': {\n justifyContent: 'space-evenly'\n }\n }, generateGutter(theme, 'xs'), _createBreakpoints.keys.reduce(function (accumulator, key) {\n // Use side effect over immutability for better performance.\n generateGrid(accumulator, theme, key);\n return accumulator;\n }, {}));\n};\n\nexports.styles = styles;\n\nfunction Grid(props) {\n var _classNames;\n\n var alignContent = props.alignContent,\n alignItems = props.alignItems,\n classes = props.classes,\n classNameProp = props.className,\n Component = props.component,\n container = props.container,\n direction = props.direction,\n item = props.item,\n justify = props.justify,\n lg = props.lg,\n md = props.md,\n sm = props.sm,\n spacing = props.spacing,\n wrap = props.wrap,\n xl = props.xl,\n xs = props.xs,\n zeroMinWidth = props.zeroMinWidth,\n other = (0, _objectWithoutProperties2.default)(props, [\"alignContent\", \"alignItems\", \"classes\", \"className\", \"component\", \"container\", \"direction\", \"item\", \"justify\", \"lg\", \"md\", \"sm\", \"spacing\", \"wrap\", \"xl\", \"xs\", \"zeroMinWidth\"]);\n var className = (0, _classnames.default)((_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.container, container), (0, _defineProperty2.default)(_classNames, classes.item, item), (0, _defineProperty2.default)(_classNames, classes.zeroMinWidth, zeroMinWidth), (0, _defineProperty2.default)(_classNames, classes[\"spacing-xs-\".concat(String(spacing))], container && spacing !== 0), (0, _defineProperty2.default)(_classNames, classes[\"direction-xs-\".concat(String(direction))], direction !== Grid.defaultProps.direction), (0, _defineProperty2.default)(_classNames, classes[\"wrap-xs-\".concat(String(wrap))], wrap !== Grid.defaultProps.wrap), (0, _defineProperty2.default)(_classNames, classes[\"align-items-xs-\".concat(String(alignItems))], alignItems !== Grid.defaultProps.alignItems), (0, _defineProperty2.default)(_classNames, classes[\"align-content-xs-\".concat(String(alignContent))], alignContent !== Grid.defaultProps.alignContent), (0, _defineProperty2.default)(_classNames, classes[\"justify-xs-\".concat(String(justify))], justify !== Grid.defaultProps.justify), (0, _defineProperty2.default)(_classNames, classes[\"grid-xs-\".concat(String(xs))], xs !== false), (0, _defineProperty2.default)(_classNames, classes[\"grid-sm-\".concat(String(sm))], sm !== false), (0, _defineProperty2.default)(_classNames, classes[\"grid-md-\".concat(String(md))], md !== false), (0, _defineProperty2.default)(_classNames, classes[\"grid-lg-\".concat(String(lg))], lg !== false), (0, _defineProperty2.default)(_classNames, classes[\"grid-xl-\".concat(String(xl))], xl !== false), _classNames), classNameProp);\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: className\n }, other));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? Grid.propTypes = {\n /**\r\n * Defines the ` + "`"))) + ((`align-content` + ("`" + ` style property.\r\n * It's applied for all screen sizes.\r\n */\n alignContent: _propTypes.default.oneOf(['stretch', 'center', 'flex-start', 'flex-end', 'space-between', 'space-around']),\n\n /**\r\n * Defines the `)) + ("`" + (`align-items` + "`")))) + (((` style property.\r\n * It's applied for all screen sizes.\r\n */\n alignItems: _propTypes.default.oneOf(['flex-start', 'center', 'flex-end', 'stretch', 'baseline']),\n\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, the component will have the flex *container* behavior.\r\n * You should be wrapping *items* with a *container*.\r\n */\n container: _propTypes.default.bool,\n\n /**\r\n * Defines the ` + "`"))) + ((`flex-direction` + ("`" + ` style property.\r\n * It is applied for all screen sizes.\r\n */\n direction: _propTypes.default.oneOf(['row', 'row-reverse', 'column', 'column-reverse']),\n\n /**\r\n * If `)) + (("`" + `true`) + ("`" + `, the component will have the flex *item* behavior.\r\n * You should be wrapping *items* with a *container*.\r\n */\n item: _propTypes.default.bool,\n\n /**\r\n * Defines the `)))))) + ((((("`" + (`justify-content` + "`")) + (` style property.\r\n * It is applied for all screen sizes.\r\n */\n justify: _propTypes.default.oneOf(['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly']),\n\n /**\r\n * Defines the number of grids the component is going to use.\r\n * It's applied for the ` + ("`" + `lg`))) + (("`" + (` breakpoint and wider screens if not overridden.\r\n */\n lg: _propTypes.default.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),\n\n /**\r\n * Defines the number of grids the component is going to use.\r\n * It's applied for the ` + "`")) + (`md` + ("`" + ` breakpoint and wider screens if not overridden.\r\n */\n md: _propTypes.default.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),\n\n /**\r\n * Defines the number of grids the component is going to use.\r\n * It's applied for the `)))) + ((("`" + (`sm` + "`")) + (` breakpoint and wider screens if not overridden.\r\n */\n sm: _propTypes.default.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),\n\n /**\r\n * Defines the space between the type ` + ("`" + `item`))) + (("`" + (` component.\r\n * It can only be used on a type ` + "`")) + ((`container` + "`") + (` component.\r\n */\n spacing: _propTypes.default.oneOf(GUTTERS),\n\n /**\r\n * Defines the ` + "`"))))) + ((((`flex-wrap` + ("`" + ` style property.\r\n * It's applied for all screen sizes.\r\n */\n wrap: _propTypes.default.oneOf(['nowrap', 'wrap', 'wrap-reverse']),\n\n /**\r\n * Defines the number of grids the component is going to use.\r\n * It's applied for the `)) + ("`" + (`xl` + "`"))) + ((` breakpoint and wider screens.\r\n */\n xl: _propTypes.default.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),\n\n /**\r\n * Defines the number of grids the component is going to use.\r\n * It's applied for all the screen sizes with the lowest priority.\r\n */\n xs: _propTypes.default.oneOf([false, 'auto', true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, it sets ` + "`")))) + (((`min-width: 0` + ("`" + ` on the item.\r\n * Refer to the limitations section of the documentation to better understand the use case.\r\n */\n zeroMinWidth: _propTypes.default.bool\n} : void 0;\nGrid.defaultProps = {\n alignContent: 'stretch',\n alignItems: 'stretch',\n component: 'div',\n container: false,\n direction: 'row',\n item: false,\n justify: 'flex-start',\n lg: false,\n md: false,\n sm: false,\n spacing: 0,\n wrap: 'wrap',\n xl: false,\n xs: false,\n zeroMinWidth: false\n};\nvar StyledGrid = (0, _withStyles.default)(styles, {\n name: 'MuiGrid'\n})(Grid);\n\nif (process.env.NODE_ENV !== 'production') {\n var requireProp = (0, _requirePropFactory.default)('Grid');\n StyledGrid.propTypes = (0, _extends2.default)({}, StyledGrid.propTypes, {\n alignContent: requireProp('container'),\n alignItems: requireProp('container'),\n direction: requireProp('container'),\n justify: requireProp('container'),\n lg: requireProp('item'),\n md: requireProp('item'),\n sm: requireProp('item'),\n spacing: requireProp('container'),\n wrap: requireProp('container'),\n xs: requireProp('item'),\n zeroMinWidth: requireProp('zeroMinWidth')\n });\n}\n\nvar _default = StyledGrid;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Grid.default;\n }\n});\n\nvar _Grid = _interopRequireDefault(require(\"./Grid\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _helpers = require(\"../utils/helpers\");\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n userSelect: 'none',\n fontSize: 24,\n width: '1em',\n height: '1em',\n // Chrome fix for https://bugs.chromium.org/p/chromium/issues/detail?id=820541\n // To remove at some point.\n overflow: 'hidden',\n flexShrink: 0\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`color=\"primary\"` + "`"))) + ((`. */\n colorPrimary: {\n color: theme.palette.primary.main\n },\n\n /* Styles applied to the root element if ` + ("`" + `color=\"secondary\"`)) + (("`" + `. */\n colorSecondary: {\n color: theme.palette.secondary.main\n },\n\n /* Styles applied to the root element if `) + ("`" + `color=\"action\"`))))))) + (((((("`" + (`. */\n colorAction: {\n color: theme.palette.action.active\n },\n\n /* Styles applied to the root element if ` + "`")) + (`color=\"error\"` + ("`" + `. */\n colorError: {\n color: theme.palette.error.main\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`color=\"disabled\"` + "`")) + (`. */\n colorDisabled: {\n color: theme.palette.action.disabled\n },\n fontSizeInherit: {\n fontSize: 'inherit'\n },\n\n /* Styles applied to the root element if ` + ("`" + `fontSize=\"small\"`)))) + ((("`" + (`. */\n fontSizeSmall: {\n fontSize: 20\n },\n\n /* Styles applied to the root element if ` + "`")) + (`fontSize=\"large\"` + ("`" + `. */\n fontSizeLarge: {\n fontSize: 36\n }\n };\n};\n\nexports.styles = styles;\n\nfunction Icon(props) {\n var _classNames;\n\n var children = props.children,\n classes = props.classes,\n className = props.className,\n color = props.color,\n Component = props.component,\n fontSize = props.fontSize,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"color\", \"component\", \"fontSize\"]);\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: (0, _classnames.default)('material-icons', classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes[\"color\".concat((0, _helpers.capitalize)(color))], color !== 'inherit'), (0, _defineProperty2.default)(_classNames, classes[\"fontSize\".concat((0, _helpers.capitalize)(fontSize))], fontSize !== 'default'), _classNames), className),\n \"aria-hidden\": \"true\"\n }, other), children);\n}\n\nprocess.env.NODE_ENV !== \"production\" ? Icon.propTypes = {\n /**\r\n * The name of the icon font ligature.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The color of the component. It supports those theme colors that make sense for this component.\r\n */\n color: _propTypes.default.oneOf(['inherit', 'primary', 'secondary', 'action', 'error', 'disabled']),\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * The fontSize applied to the icon. Defaults to 24px, but can be configure to inherit font size.\r\n */\n fontSize: _propTypes.default.oneOf(['inherit', 'default', 'small', 'large'])\n} : void 0;\nIcon.defaultProps = {\n color: 'inherit',\n component: 'span',\n fontSize: 'default'\n};\nIcon.muiName = 'Icon';\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiIcon'\n})(Icon);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Icon.default;\n }\n});\n\nvar _Icon = _interopRequireDefault(require(\"./Icon\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _colorManipulator = require(\"../styles/colorManipulator\");\n\nvar _ButtonBase = _interopRequireDefault(require(\"../ButtonBase\"));\n\nvar _helpers = require(\"../utils/helpers\");\n\n// @inheritedComponent ButtonBase\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n textAlign: 'center',\n flex: '0 0 auto',\n fontSize: theme.typography.pxToRem(24),\n padding: 12,\n borderRadius: '50%',\n overflow: 'visible',\n // Explicitly set the default value to solve a bug on IE 11.\n color: theme.palette.action.active,\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.shortest\n }),\n '&:hover': {\n backgroundColor: (0, _colorManipulator.fade)(theme.palette.action.active, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n },\n '&$disabled': {\n backgroundColor: 'transparent'\n }\n },\n '&$disabled': {\n color: theme.palette.action.disabled\n }\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`color=\"inherit\"` + "`")) + (`. */\n colorInherit: {\n color: 'inherit'\n },\n\n /* Styles applied to the root element if ` + ("`" + `color=\"primary\"`))))) + (((("`" + (`. */\n colorPrimary: {\n color: theme.palette.primary.main,\n '&:hover': {\n backgroundColor: (0, _colorManipulator.fade)(theme.palette.primary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n }\n },\n\n /* Styles applied to the root element if ` + "`")) + (`color=\"secondary\"` + ("`" + `. */\n colorSecondary: {\n color: theme.palette.secondary.main,\n '&:hover': {\n backgroundColor: (0, _colorManipulator.fade)(theme.palette.secondary.main, theme.palette.action.hoverOpacity),\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n }\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`disabled={true}` + "`")) + (`. */\n disabled: {},\n\n /* Styles applied to the children container element. */\n label: {\n width: '100%',\n display: 'flex',\n alignItems: 'inherit',\n justifyContent: 'inherit'\n }\n };\n};\n/**\r\n * Refer to the [Icons](/style/icons/) section of the documentation\r\n * regarding the available icon options.\r\n */\n\n\nexports.styles = styles;\n\nfunction IconButton(props) {\n var _classNames;\n\n var children = props.children,\n classes = props.classes,\n className = props.className,\n color = props.color,\n disabled = props.disabled,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"color\", \"disabled\"]);\n return _react.default.createElement(_ButtonBase.default, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes[\"color\".concat((0, _helpers.capitalize)(color))], color !== 'default'), (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), _classNames), className),\n centerRipple: true,\n focusRipple: true,\n disabled: disabled\n }, other), _react.default.createElement(\"span\", {\n className: classes.label\n }, children));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? IconButton.propTypes = {\n /**\r\n * The icon element.\r\n */\n children: (0, _utils.chainPropTypes)(_propTypes.default.node, function (props) {\n var found = _react.default.Children.toArray(props.children).some(function (child) {\n return _react.default.isValidElement(child) && child.props.onClick;\n });\n\n if (found) {\n return new Error(['Material-UI: you are providing an onClick event listener ' + 'to a child of a button element.', 'Firefox will never trigger the event.', 'You should move the onClick listener to the parent button element.', 'https://github.com/mui-org/material-ui/issues/13957', // Change error message slightly on every check to prevent caching when testing\n // which would not trigger console errors on subsequent fails\n process.env.NODE_ENV === 'test' ? Date.now() : ''].join('\\n'));\n }\n\n return null;\n }),\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The color of the component. It supports those theme colors that make sense for this component.\r\n */\n color: _propTypes.default.oneOf(['default', 'inherit', 'primary', 'secondary']),\n\n /**\r\n * If ` + ("`" + `true`)))) + ((("`" + (`, the button will be disabled.\r\n */\n disabled: _propTypes.default.bool,\n\n /**\r\n * If ` + "`")) + (`true` + ("`" + `, the ripple will be disabled.\r\n */\n disableRipple: _propTypes.default.bool\n} : void 0;\nIconButton.defaultProps = {\n color: 'default',\n disabled: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiIconButton'\n})(IconButton);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _IconButton.default;\n }\n});\n\nvar _IconButton = _interopRequireDefault(require(\"./IconButton\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _ListContext = _interopRequireDefault(require(\"./ListContext\"));\n\nvar styles = {\n /* Styles applied to the root element. */\n root: {\n listStyle: 'none',\n margin: 0,\n padding: 0,\n position: 'relative'\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`disablePadding={false}` + "`")) + ((`. */\n padding: {\n paddingTop: 8,\n paddingBottom: 8\n },\n\n /* Styles applied to the root element if ` + "`") + (`dense={true}` + "`")))))) + (((((` & ` + ("`" + `disablePadding={false}`)) + ("`" + (`. */\n dense: {\n paddingTop: 4,\n paddingBottom: 4\n },\n\n /* Styles applied to the root element if a ` + "`"))) + ((`subheader` + ("`" + ` is provided. */\n subheader: {\n paddingTop: 0\n }\n};\nexports.styles = styles;\n\nfunction List(props) {\n var _classNames;\n\n var children = props.children,\n classes = props.classes,\n className = props.className,\n Component = props.component,\n dense = props.dense,\n disablePadding = props.disablePadding,\n subheader = props.subheader,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"component\", \"dense\", \"disablePadding\", \"subheader\"]);\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.dense, dense && !disablePadding), (0, _defineProperty2.default)(_classNames, classes.padding, !disablePadding), (0, _defineProperty2.default)(_classNames, classes.subheader, subheader), _classNames), className)\n }, other), _react.default.createElement(_ListContext.default.Provider, {\n value: {\n dense: dense\n }\n }, subheader, children));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? List.propTypes = {\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If `)) + ("`" + (`true` + "`")))) + (((`, compact vertical padding designed for keyboard and mouse input will be used for\r\n * the list and list items. The property is available to descendant components as the\r\n * ` + ("`" + `dense`)) + ("`" + (` context.\r\n */\n dense: _propTypes.default.bool,\n\n /**\r\n * If ` + "`"))) + ((`true` + ("`" + `, vertical padding will be removed from the list.\r\n */\n disablePadding: _propTypes.default.bool,\n\n /**\r\n * The content of the subheader, normally `)) + (("`" + `ListSubheader`) + ("`" + `.\r\n */\n subheader: _propTypes.default.node\n} : void 0;\nList.defaultProps = {\n component: 'ul',\n dense: false,\n disablePadding: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiList'\n})(List);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\n/**\r\n * @ignore - internal component.\r\n */\nvar ListContext = _react.default.createContext({});\n\nvar _default = ListContext;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _List.default;\n }\n});\n\nvar _List = _interopRequireDefault(require(\"./List\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _ButtonBase = _interopRequireDefault(require(\"../ButtonBase\"));\n\nvar _reactHelpers = require(\"../utils/reactHelpers\");\n\nvar _MergeListContext = _interopRequireDefault(require(\"./MergeListContext\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the (normally root) `))))) + (((("`" + (`component` + "`")) + (` element. May be wrapped by a ` + ("`" + `container`))) + (("`" + (`. */\n root: {\n display: 'flex',\n justifyContent: 'flex-start',\n alignItems: 'center',\n position: 'relative',\n textDecoration: 'none',\n width: '100%',\n boxSizing: 'border-box',\n textAlign: 'left',\n paddingTop: 11,\n // To use 10px in v4\n paddingBottom: 11,\n // To use 10px in v4\n '&$selected, &$selected:hover, &$selected:focus': {\n backgroundColor: theme.palette.action.selected\n }\n },\n\n /* Styles applied to the ` + "`")) + (`container` + ("`" + ` element if `)))) + ((("`" + (`children` + "`")) + (` includes ` + ("`" + `ListItemSecondaryAction`))) + (("`" + (`. */\n container: {\n position: 'relative'\n },\n // To remove in v4\n\n /* Styles applied to the ` + "`")) + ((`component` + "`") + (`'s ` + "`")))))))) + (((((((`focusVisibleClassName` + ("`" + ` property if `)) + ("`" + (`button={true}` + "`"))) + ((`. */\n focusVisible: {},\n\n /* Legacy styles applied to the root element. Use ` + ("`" + `root`)) + ("`" + (` instead. */\n default: {},\n\n /* Styles applied to the ` + "`")))) + (((`component` + ("`" + ` element if `)) + ("`" + (`dense={true}` + "`"))) + ((` or ` + ("`" + `children`)) + ("`" + (` includes ` + "`"))))) + ((((`Avatar` + ("`" + `. */\n dense: {\n paddingTop: 8,\n paddingBottom: 8\n },\n\n /* Styles applied to the `)) + ("`" + (`component` + "`"))) + ((` element if ` + ("`" + `alignItems=\"flex-start\"`)) + ("`" + (`. */\n alignItemsFlexStart: {\n alignItems: 'flex-start'\n },\n\n /* Styles applied to the inner ` + "`")))) + (((`component` + ("`" + ` element if `)) + ("`" + (`disabled={true}` + "`"))) + ((`. */\n disabled: {\n opacity: 0.5\n },\n\n /* Styles applied to the inner ` + ("`" + `component`)) + (("`" + ` element if `) + ("`" + `divider={true}`)))))) + ((((("`" + (`. */\n divider: {\n borderBottom: \"1px solid \".concat(theme.palette.divider),\n backgroundClip: 'padding-box'\n },\n\n /* Styles applied to the inner ` + "`")) + (`component` + ("`" + ` element if `))) + (("`" + (`disableGutters={false}` + "`")) + (`. */\n gutters: {\n paddingLeft: 16,\n paddingRight: 16\n },\n\n /* Styles applied to the inner ` + ("`" + `component`)))) + ((("`" + (` element if ` + "`")) + (`button={true}` + ("`" + `. */\n button: {\n transition: theme.transitions.create('background-color', {\n duration: theme.transitions.duration.shortest\n }),\n '&:hover': {\n textDecoration: 'none',\n backgroundColor: theme.palette.action.hover,\n // Reset on touch devices, it doesn't add specificity\n '@media (hover: none)': {\n backgroundColor: 'transparent'\n }\n },\n '&:focus': {\n backgroundColor: theme.palette.action.hover\n }\n },\n\n /* Styles applied to the `))) + (("`" + (`component` + "`")) + ((` element if ` + "`") + (`children` + "`"))))) + ((((` includes ` + ("`" + `ListItemSecondaryAction`)) + ("`" + (`. */\n secondaryAction: {\n // Add some space to avoid collision as ` + "`"))) + ((`ListItemSecondaryAction` + ("`" + `\n // is absolutely positioned.\n paddingRight: 32\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`selected={true}` + "`")))) + (((`. */\n selected: {}\n };\n};\n/**\r\n * Uses an additional container component if ` + ("`" + `ListItemSecondaryAction`)) + ("`" + (` is the last child.\r\n */\n\n\nexports.styles = styles;\n\nfunction ListItem(props) {\n var alignItems = props.alignItems,\n button = props.button,\n childrenProp = props.children,\n classes = props.classes,\n classNameProp = props.className,\n componentProp = props.component,\n ContainerComponent = props.ContainerComponent,\n _props$ContainerProps = props.ContainerProps;\n _props$ContainerProps = _props$ContainerProps === void 0 ? {} : _props$ContainerProps;\n var ContainerClassName = _props$ContainerProps.className,\n ContainerProps = (0, _objectWithoutProperties2.default)(_props$ContainerProps, [\"className\"]),\n denseProp = props.dense,\n disabled = props.disabled,\n disableGutters = props.disableGutters,\n divider = props.divider,\n focusVisibleClassName = props.focusVisibleClassName,\n selected = props.selected,\n other = (0, _objectWithoutProperties2.default)(props, [\"alignItems\", \"button\", \"children\", \"classes\", \"className\", \"component\", \"ContainerComponent\", \"ContainerProps\", \"dense\", \"disabled\", \"disableGutters\", \"divider\", \"focusVisibleClassName\", \"selected\"]);\n return _react.default.createElement(_MergeListContext.default, {\n dense: denseProp,\n alignItems: alignItems\n }, function (_ref) {\n var _classNames;\n\n var dense = _ref.dense;\n\n var children = _react.default.Children.toArray(childrenProp);\n\n var hasAvatar = children.some(function (value) {\n return (0, _reactHelpers.isMuiElement)(value, ['ListItemAvatar']);\n });\n var hasSecondaryAction = children.length && (0, _reactHelpers.isMuiElement)(children[children.length - 1], ['ListItemSecondaryAction']);\n var className = (0, _classnames.default)(classes.root, classes.default, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.dense, dense || hasAvatar), (0, _defineProperty2.default)(_classNames, classes.gutters, !disableGutters), (0, _defineProperty2.default)(_classNames, classes.divider, divider), (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), (0, _defineProperty2.default)(_classNames, classes.button, button), (0, _defineProperty2.default)(_classNames, classes.alignItemsFlexStart, alignItems === 'flex-start'), (0, _defineProperty2.default)(_classNames, classes.secondaryAction, hasSecondaryAction), (0, _defineProperty2.default)(_classNames, classes.selected, selected), _classNames), classNameProp);\n var componentProps = (0, _extends2.default)({\n className: className,\n disabled: disabled\n }, other);\n var Component = componentProp || 'li';\n\n if (button) {\n componentProps.component = componentProp || 'div';\n componentProps.focusVisibleClassName = (0, _classnames.default)(classes.focusVisible, focusVisibleClassName);\n Component = _ButtonBase.default;\n }\n\n if (hasSecondaryAction) {\n // Use div by default.\n Component = !componentProps.component && !componentProp ? 'div' : Component; // Avoid nesting of li > li.\n\n if (ContainerComponent === 'li') {\n if (Component === 'li') {\n Component = 'div';\n } else if (componentProps.component === 'li') {\n componentProps.component = 'div';\n }\n }\n\n return _react.default.createElement(ContainerComponent, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.container, ContainerClassName)\n }, ContainerProps), _react.default.createElement(Component, componentProps, children), children.pop());\n }\n\n return _react.default.createElement(Component, componentProps, children);\n });\n}\n\nprocess.env.NODE_ENV !== \"production\" ? ListItem.propTypes = {\n /**\r\n * Defines the ` + "`"))) + ((`align-items` + ("`" + ` style property.\r\n */\n alignItems: _propTypes.default.oneOf(['flex-start', 'center']),\n\n /**\r\n * If `)) + (("`" + `true`) + ("`" + `, the list item will be a button (using `))))))) + (((((("`" + (`ButtonBase` + "`")) + (`).\r\n */\n button: _propTypes.default.bool,\n\n /**\r\n * The content of the component. If a ` + ("`" + `ListItemSecondaryAction`))) + (("`" + (` is used it must\r\n * be the last child.\r\n */\n children: (0, _utils.chainPropTypes)(_propTypes.default.node, function (props) {\n var children = _react.default.Children.toArray(props.children); // React.Children.toArray(props.children).findLastIndex(isListItemSecondaryAction)\n\n\n var secondaryActionIndex = -1;\n\n for (var i = children.length - 1; i >= 0; i -= 1) {\n var child = children[i];\n\n if ((0, _reactHelpers.isMuiElement)(child, ['ListItemSecondaryAction'])) {\n secondaryActionIndex = i;\n break;\n }\n } // is ListItemSecondaryAction the last child of ListItem\n\n\n if (secondaryActionIndex !== -1 && secondaryActionIndex !== children.length - 1) {\n return new Error('Material-UI: you used an element after ListItemSecondaryAction. ' + 'For ListItem to detect that it has a secondary action ' + \"you must pass it has the last children to ListItem.\".concat(process.env.NODE_ENV === 'test' ? Date.now() : ''));\n }\n\n return null;\n }),\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n * By default, it's a ` + "`")) + (`li` + ("`" + ` when `)))) + ((("`" + (`button` + "`")) + (` is ` + ("`" + `false`))) + (("`" + (` and a ` + "`")) + ((`div` + "`") + (` when ` + "`"))))) + ((((`button` + ("`" + ` is `)) + ("`" + (`true` + "`"))) + ((`.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * The container component used when a ` + ("`" + `ListItemSecondaryAction`)) + ("`" + (` is the last child.\r\n */\n ContainerComponent: _utils.componentPropType,\n\n /**\r\n * Properties applied to the container component if used.\r\n */\n ContainerProps: _propTypes.default.object,\n\n /**\r\n * If ` + "`")))) + (((`true` + ("`" + `, compact vertical padding designed for keyboard and mouse input will be used.\r\n */\n dense: _propTypes.default.bool,\n\n /**\r\n * If `)) + ("`" + (`true` + "`"))) + ((`, the list item will be disabled.\r\n */\n disabled: _propTypes.default.bool,\n\n /**\r\n * If ` + ("`" + `true`)) + (("`" + `, the left and right padding is removed.\r\n */\n disableGutters: _propTypes.default.bool,\n\n /**\r\n * If `) + ("`" + `true`)))))) + ((((("`" + (`, a 1px light border is added to the bottom of the list item.\r\n */\n divider: _propTypes.default.bool,\n\n /**\r\n * @ignore\r\n */\n focusVisibleClassName: _propTypes.default.string,\n\n /**\r\n * Use to apply selected styling.\r\n */\n selected: _propTypes.default.bool\n} : void 0;\nListItem.defaultProps = {\n alignItems: 'center',\n button: false,\n ContainerComponent: 'li',\n dense: false,\n disabled: false,\n disableGutters: false,\n divider: false,\n selected: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiListItem'\n})(ListItem);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _ListContext = _interopRequireDefault(require(\"../List/ListContext\"));\n\n/**\r\n * @ignore - internal component.\r\n *\r\n * Consumes a context and passes that context merged with its props.\r\n */\nfunction MergeListContext(props) {\n var alignItems = props.alignItems,\n children = props.children,\n dense = props.dense;\n return _react.default.createElement(_ListContext.default.Consumer, null, function (context) {\n var childContext = {\n dense: dense || context.dense || false,\n alignItems: alignItems\n };\n return _react.default.createElement(_ListContext.default.Provider, {\n value: childContext\n }, children(childContext));\n });\n}\n\nprocess.env.NODE_ENV !== \"production\" ? MergeListContext.propTypes = {\n alignItems: _propTypes.default.oneOf(['flex-start', 'center']).isRequired,\n children: _propTypes.default.func.isRequired,\n dense: _propTypes.default.bool.isRequired\n} : void 0;\nvar _default = MergeListContext;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _ListItem.default;\n }\n});\n\nvar _ListItem = _interopRequireDefault(require(\"./ListItem\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n marginRight: 16,\n color: theme.palette.action.active,\n flexShrink: 0,\n display: 'inline-flex'\n }\n };\n};\n/**\r\n * A simple wrapper to apply ` + "`")) + (`List` + ("`" + ` styles to an `))) + (("`" + (`Icon` + "`")) + (` or ` + ("`" + `SvgIcon`)))) + ((("`" + (`.\r\n */\n\n\nexports.styles = styles;\n\nfunction ListItemIcon(props) {\n var children = props.children,\n classes = props.classes,\n classNameProp = props.className,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\"]);\n return _react.default.createElement(\"div\", (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, classNameProp)\n }, other), children);\n}\n\nprocess.env.NODE_ENV !== \"production\" ? ListItemIcon.propTypes = {\n /**\r\n * The content of the component, normally ` + "`")) + (`Icon` + ("`" + `, `))) + (("`" + (`SvgIcon` + "`")) + ((`,\r\n * or a ` + "`") + (`@material-ui/icons` + "`"))))) + ((((` SVG icon element.\r\n */\n children: _propTypes.default.element.isRequired,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string\n} : void 0;\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiListItemIcon'\n})(ListItemIcon);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _ListItemIcon.default;\n }\n});\n\nvar _ListItemIcon = _interopRequireDefault(require(\"./ListItemIcon\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _Typography = _interopRequireDefault(require(\"../Typography\"));\n\nvar _ListContext = _interopRequireDefault(require(\"../List/ListContext\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n flex: '1 1 auto',\n minWidth: 0,\n padding: '0 16px',\n '&:first-child': {\n paddingLeft: 0\n }\n },\n\n /* Styles applied to the root element if ` + ("`" + `inset={true}`)) + ("`" + (`. */\n inset: {\n '&:first-child': {\n paddingLeft: 56\n }\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`context.dense` + ("`" + ` is `)) + ("`" + (`true` + "`")))) + (((`. */\n dense: {\n fontSize: theme.typography.pxToRem(13)\n },\n\n /* Styles applied to the primary ` + ("`" + `Typography`)) + ("`" + (` component. */\n primary: {\n '&$textDense': {\n fontSize: 'inherit'\n }\n },\n\n /* Styles applied to the secondary ` + "`"))) + ((`Typography` + ("`" + ` component. */\n secondary: {\n '&$textDense': {\n fontSize: 'inherit'\n }\n },\n\n /* Styles applied to the `)) + (("`" + `Typography`) + ("`" + ` components if `)))))))))) + ((((((((("`" + (`context.dense` + "`")) + (` is ` + ("`" + `true`))) + (("`" + (`. */\n textDense: {}\n };\n};\n\nexports.styles = styles;\n\nfunction ListItemText(props) {\n var children = props.children,\n classes = props.classes,\n classNameProp = props.className,\n disableTypography = props.disableTypography,\n inset = props.inset,\n primaryProp = props.primary,\n primaryTypographyProps = props.primaryTypographyProps,\n secondaryProp = props.secondary,\n secondaryTypographyProps = props.secondaryTypographyProps,\n theme = props.theme,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"disableTypography\", \"inset\", \"primary\", \"primaryTypographyProps\", \"secondary\", \"secondaryTypographyProps\", \"theme\"]);\n return _react.default.createElement(_ListContext.default.Consumer, null, function (_ref) {\n var _classNames3;\n\n var dense = _ref.dense;\n var primary = primaryProp != null ? primaryProp : children;\n\n if (primary != null && primary.type !== _Typography.default && !disableTypography) {\n primary = _react.default.createElement(_Typography.default, (0, _extends2.default)({\n variant: theme.typography.useNextVariants ? 'body1' : 'subheading',\n className: (0, _classnames.default)(classes.primary, (0, _defineProperty2.default)({}, classes.textDense, dense)),\n component: \"span\"\n }, primaryTypographyProps), primary);\n }\n\n var secondary = secondaryProp;\n\n if (secondary != null && secondary.type !== _Typography.default && !disableTypography) {\n secondary = _react.default.createElement(_Typography.default, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.secondary, (0, _defineProperty2.default)({}, classes.textDense, dense)),\n color: \"textSecondary\"\n }, secondaryTypographyProps), secondary);\n }\n\n return _react.default.createElement(\"div\", (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, (_classNames3 = {}, (0, _defineProperty2.default)(_classNames3, classes.dense, dense), (0, _defineProperty2.default)(_classNames3, classes.inset, inset), _classNames3), classNameProp)\n }, other), primary, secondary);\n });\n}\n\nprocess.env.NODE_ENV !== \"production\" ? ListItemText.propTypes = {\n /**\r\n * Alias for the ` + "`")) + (`primary` + ("`" + ` property.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * If `)))) + ((("`" + (`true` + "`")) + (`, the children won't be wrapped by a Typography component.\r\n * This can be useful to render an alternative Typography variant by wrapping\r\n * the ` + ("`" + `children`))) + (("`" + (` (or ` + "`")) + (`primary` + ("`" + `) text, and optional `))))) + (((("`" + (`secondary` + "`")) + (` text\r\n * with the Typography component.\r\n */\n disableTypography: _propTypes.default.bool,\n\n /**\r\n * If ` + ("`" + `true`))) + (("`" + (`, the children will be indented.\r\n * This should be used if there is no left avatar or left icon.\r\n */\n inset: _propTypes.default.bool,\n\n /**\r\n * The main content element.\r\n */\n primary: _propTypes.default.node,\n\n /**\r\n * These props will be forwarded to the primary typography component\r\n * (as long as disableTypography is not ` + "`")) + (`true` + ("`" + `).\r\n */\n primaryTypographyProps: _propTypes.default.object,\n\n /**\r\n * The secondary content element.\r\n */\n secondary: _propTypes.default.node,\n\n /**\r\n * These props will be forwarded to the secondary typography component\r\n * (as long as disableTypography is not `)))) + ((("`" + (`true` + "`")) + (`).\r\n */\n secondaryTypographyProps: _propTypes.default.object,\n\n /**\r\n * @ignore\r\n */\n theme: _propTypes.default.object.isRequired\n} : void 0;\nListItemText.defaultProps = {\n disableTypography: false,\n inset: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiListItemText',\n withTheme: true\n})(ListItemText);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _ListItemText.default;\n }\n});\n\nvar _ListItemText = _interopRequireDefault(require(\"./ListItemText\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf3 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\n/**\r\n * NoSsr purposely removes components from the subject of Server Side Rendering (SSR).\r\n *\r\n * This component can be useful in a variety of situations:\r\n * - Escape hatch for broken dependencies not supporting SSR.\r\n * - Improve the time-to-first paint on the client by only rendering above the fold.\r\n * - Reduce the rendering time on the server.\r\n * - Under too heavy server load, you can turn on service degradation.\r\n */\nvar NoSsr =\n/*#__PURE__*/\nfunction (_React$Component) {\n (0, _inherits2.default)(NoSsr, _React$Component);\n\n function NoSsr() {\n var _getPrototypeOf2;\n\n var _this;\n\n (0, _classCallCheck2.default)(this, NoSsr);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(NoSsr)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.mounted = false;\n _this.state = {\n mounted: false\n };\n return _this;\n }\n\n (0, _createClass2.default)(NoSsr, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n this.mounted = true;\n\n if (this.props.defer) {\n // Wondering why we use two RAFs? Check this video out:\n // https://www.youtube.com/watch?v=cCOL7MC4Pl0\n //\n // The componentDidMount() method is called after the DOM nodes are inserted.\n // The UI might not have rendering the changes. We request a frame.\n requestAnimationFrame(function () {\n // The browser should be about to render the DOM nodes\n // that React committed at this point.\n // We don't want to interrupt. Let's wait the next frame.\n requestAnimationFrame(function () {\n // The UI is up-to-date at this point.\n // We can continue rendering the children.\n if (_this2.mounted) {\n _this2.setState({\n mounted: true\n });\n }\n });\n });\n } else {\n this.setState({\n mounted: true\n });\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.mounted = false;\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n children = _this$props.children,\n fallback = _this$props.fallback;\n return this.state.mounted ? children : fallback;\n }\n }]);\n return NoSsr;\n}(_react.default.Component);\n\nprocess.env.NODE_ENV !== \"production\" ? NoSsr.propTypes = {\n children: _propTypes.default.node.isRequired,\n\n /**\r\n * If ` + ("`" + `true`))) + (("`" + (`, the component will not only prevent server-side rendering.\r\n * It will also defer the rendering of the children into a different screen frame.\r\n */\n defer: _propTypes.default.bool,\n\n /**\r\n * The fallback content to display.\r\n */\n fallback: _propTypes.default.node\n} : void 0;\n\nif (process.env.NODE_ENV !== 'production') {\n process.env.NODE_ENV !== \"production\" ? NoSsr.propTypes = (0, _utils.exactProp)(NoSsr.propTypes) : void 0;\n}\n\nNoSsr.defaultProps = {\n defer: false,\n fallback: null\n};\nvar _default = NoSsr;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _NoSsr.default;\n }\n});\n\nvar _NoSsr = _interopRequireDefault(require(\"./NoSsr\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar styles = function styles(theme) {\n var elevations = {};\n theme.shadows.forEach(function (shadow, index) {\n elevations[\"elevation\".concat(index)] = {\n boxShadow: shadow\n };\n });\n return (0, _extends2.default)({\n /* Styles applied to the root element. */\n root: {\n backgroundColor: theme.palette.background.paper\n },\n\n /* Styles applied to the root element if ` + "`")) + ((`square={false}` + "`") + (`. */\n rounded: {\n borderRadius: theme.shape.borderRadius\n }\n }, elevations);\n};\n\nexports.styles = styles;\n\nfunction Paper(props) {\n var classes = props.classes,\n classNameProp = props.className,\n Component = props.component,\n square = props.square,\n elevation = props.elevation,\n other = (0, _objectWithoutProperties2.default)(props, [\"classes\", \"className\", \"component\", \"square\", \"elevation\"]);\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(elevation >= 0 && elevation < 25, \"Material-UI: this elevation ` + "`")))))) + (((((`\".concat(elevation, \"` + ("`" + ` is not implemented.\")) : void 0;\n var className = (0, _classnames.default)(classes.root, classes[\"elevation\".concat(elevation)], (0, _defineProperty2.default)({}, classes.rounded, !square), classNameProp);\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: className\n }, other));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? Paper.propTypes = {\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * Shadow depth, corresponds to `)) + ("`" + (`dp` + "`"))) + ((` in the spec.\r\n * It's accepting values between 0 and 24 inclusive.\r\n */\n elevation: _propTypes.default.number,\n\n /**\r\n * If ` + ("`" + `true`)) + ("`" + (`, rounded corners are disabled.\r\n */\n square: _propTypes.default.bool\n} : void 0;\nPaper.defaultProps = {\n component: 'div',\n elevation: 2,\n square: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiPaper'\n})(Paper);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Paper.default;\n }\n});\n\nvar _Paper = _interopRequireDefault(require(\"./Paper\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf3 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _TableContext = _interopRequireDefault(require(\"./TableContext\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n display: 'table',\n fontFamily: theme.typography.fontFamily,\n width: '100%',\n borderCollapse: 'collapse',\n borderSpacing: 0\n }\n };\n};\n\nexports.styles = styles;\n\nvar Table =\n/*#__PURE__*/\nfunction (_React$Component) {\n (0, _inherits2.default)(Table, _React$Component);\n\n function Table() {\n var _getPrototypeOf2;\n\n var _this;\n\n (0, _classCallCheck2.default)(this, Table);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(Table)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.memoizedContextValue = {};\n return _this;\n }\n\n (0, _createClass2.default)(Table, [{\n key: \"useMemo\",\n // To replace with the corresponding Hook once Material-UI v4 is out:\n // https://reactjs.org/docs/hooks-reference.html#usememo\n value: function useMemo(contextValue) {\n var objectKeys = Object.keys(contextValue);\n\n for (var i = 0; i < objectKeys.length; i += 1) {\n var objectKey = objectKeys[i];\n\n if (contextValue[objectKey] !== this.memoizedContextValue[objectKey]) {\n this.memoizedContextValue = contextValue;\n break;\n }\n }\n\n return this.memoizedContextValue;\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n classes = _this$props.classes,\n className = _this$props.className,\n Component = _this$props.component,\n padding = _this$props.padding,\n other = (0, _objectWithoutProperties2.default)(_this$props, [\"classes\", \"className\", \"component\", \"padding\"]);\n return _react.default.createElement(_TableContext.default.Provider, {\n value: this.useMemo({\n padding: padding\n })\n }, _react.default.createElement(Component, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, className)\n }, other)));\n }\n }]);\n return Table;\n}(_react.default.Component);\n\nprocess.env.NODE_ENV !== \"production\" ? Table.propTypes = {\n /**\r\n * The content of the table, normally ` + "`")))) + (((`TableHead` + ("`" + ` and `)) + ("`" + (`TableBody` + "`"))) + ((`.\r\n */\n children: _propTypes.default.node.isRequired,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * Allows TableCells to inherit padding of the Table.\r\n */\n padding: _propTypes.default.oneOf(['default', 'checkbox', 'dense', 'none'])\n} : void 0;\nTable.defaultProps = {\n component: 'table',\n padding: 'default'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTable'\n})(Table);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\n/**\r\n * @ignore - internal component.\r\n */\nvar TableContext = _react.default.createContext();\n\nvar _default = TableContext;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\n/**\r\n * @ignore - internal component.\r\n */\nvar Tablelvl2Context = _react.default.createContext();\n\nvar _default = Tablelvl2Context;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Table.default;\n }\n});\n\nvar _Table = _interopRequireDefault(require(\"./Table\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _Tablelvl2Context = _interopRequireDefault(require(\"../Table/Tablelvl2Context\"));\n\nvar styles = {\n /* Styles applied to the root element. */\n root: {\n display: 'table-row-group'\n }\n};\nexports.styles = styles;\nvar contextValue = {\n variant: 'body'\n};\n\nfunction TableBody(props) {\n var classes = props.classes,\n className = props.className,\n Component = props.component,\n other = (0, _objectWithoutProperties2.default)(props, [\"classes\", \"className\", \"component\"]);\n return _react.default.createElement(_Tablelvl2Context.default.Provider, {\n value: contextValue\n }, _react.default.createElement(Component, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, className)\n }, other)));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? TableBody.propTypes = {\n /**\r\n * The content of the component, normally ` + ("`" + `TableRow`)) + (("`" + `.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType\n} : void 0;\nTableBody.defaultProps = {\n component: 'tbody'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTableBody'\n})(TableBody);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _TableBody.default;\n }\n});\n\nvar _TableBody = _interopRequireDefault(require(\"./TableBody\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _helpers = require(\"../utils/helpers\");\n\nvar _deprecatedPropType = _interopRequireDefault(require(\"../utils/deprecatedPropType\"));\n\nvar _colorManipulator = require(\"../styles/colorManipulator\");\n\nvar _TableContext = _interopRequireDefault(require(\"../Table/TableContext\"));\n\nvar _Tablelvl2Context = _interopRequireDefault(require(\"../Table/Tablelvl2Context\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n display: 'table-cell',\n verticalAlign: 'inherit',\n // Workaround for a rendering bug with spanned columns in Chrome 62.0.\n // Removes the alpha (sets it to 1), and lightens or darkens the theme color.\n borderBottom: \"1px solid\\n \".concat(theme.palette.type === 'light' ? (0, _colorManipulator.lighten)((0, _colorManipulator.fade)(theme.palette.divider, 1), 0.88) : (0, _colorManipulator.darken)((0, _colorManipulator.fade)(theme.palette.divider, 1), 0.68)),\n textAlign: 'left',\n padding: '4px 56px 4px 24px',\n '&:last-child': {\n paddingRight: 24\n }\n },\n\n /* Styles applied to the root element if `) + ("`" + `variant=\"head\"`))))) + (((("`" + (` or ` + "`")) + (`context.table.head` + ("`" + `. */\n head: {\n color: theme.palette.text.secondary,\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightMedium\n },\n\n /* Styles applied to the root element if `))) + (("`" + (`variant=\"body\"` + "`")) + (` or ` + ("`" + `context.table.body`)))) + ((("`" + (`. */\n body: {\n color: theme.palette.text.primary,\n fontSize: theme.typography.pxToRem(13),\n fontWeight: theme.typography.fontWeightRegular\n },\n\n /* Styles applied to the root element if ` + "`")) + (`variant=\"footer\"` + ("`" + ` or `))) + (("`" + (`context.table.footer` + "`")) + ((`. */\n footer: {\n borderBottom: 0,\n color: theme.palette.text.secondary,\n fontSize: theme.typography.pxToRem(12)\n },\n\n /* Styles applied to the root element if ` + "`") + (`numeric={true}` + "`"))))))) + ((((((`. */\n numeric: {\n textAlign: 'right',\n flexDirection: 'row-reverse' // can be dynamically inherited at runtime by contents\n\n },\n\n /* Styles applied to the root element if ` + ("`" + `padding=\"dense\"`)) + ("`" + (`. */\n paddingDense: {\n paddingRight: 24\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`padding=\"checkbox\"` + ("`" + `. */\n paddingCheckbox: {\n padding: '0 12px',\n '&:last-child': {\n paddingRight: 12\n }\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`padding=\"none\"` + "`")))) + (((`. */\n paddingNone: {\n padding: 0,\n '&:last-child': {\n padding: 0\n }\n },\n\n /* Styles applied to the root element if ` + ("`" + `align=\"left\"`)) + ("`" + (`. */\n alignLeft: {\n textAlign: 'left'\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`align=\"center\"` + ("`" + `. */\n alignCenter: {\n textAlign: 'center'\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`align=\"right\"` + "`"))))) + ((((`. */\n alignRight: {\n textAlign: 'right',\n flexDirection: 'row-reverse'\n },\n\n /* Styles applied to the root element if ` + ("`" + `align=\"justify\"`)) + ("`" + (`. */\n alignJustify: {\n textAlign: 'justify'\n }\n };\n};\n\nexports.styles = styles;\n\nfunction TableCell(props) {\n var align = props.align,\n children = props.children,\n classes = props.classes,\n classNameProp = props.className,\n component = props.component,\n sortDirection = props.sortDirection,\n _props$numeric = props.numeric,\n numeric = _props$numeric === void 0 ? false : _props$numeric,\n paddingProp = props.padding,\n scopeProp = props.scope,\n variant = props.variant,\n other = (0, _objectWithoutProperties2.default)(props, [\"align\", \"children\", \"classes\", \"className\", \"component\", \"sortDirection\", \"numeric\", \"padding\", \"scope\", \"variant\"]);\n return _react.default.createElement(_TableContext.default.Consumer, null, function (table) {\n return _react.default.createElement(_Tablelvl2Context.default.Consumer, null, function (tablelvl2) {\n var _classNames;\n\n var Component;\n\n if (component) {\n Component = component;\n } else {\n Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td';\n }\n\n var scope = scopeProp;\n\n if (!scope && tablelvl2 && tablelvl2.variant === 'head') {\n scope = 'col';\n }\n\n var padding = paddingProp || (table && table.padding ? table.padding : 'default');\n var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.head, variant ? variant === 'head' : tablelvl2 && tablelvl2.variant === 'head'), (0, _defineProperty2.default)(_classNames, classes.body, variant ? variant === 'body' : tablelvl2 && tablelvl2.variant === 'body'), (0, _defineProperty2.default)(_classNames, classes.footer, variant ? variant === 'footer' : tablelvl2 && tablelvl2.variant === 'footer'), (0, _defineProperty2.default)(_classNames, classes[\"align\".concat((0, _helpers.capitalize)(align))], align !== 'inherit'), (0, _defineProperty2.default)(_classNames, classes.numeric, numeric), (0, _defineProperty2.default)(_classNames, classes[\"padding\".concat((0, _helpers.capitalize)(padding))], padding !== 'default'), _classNames), classNameProp);\n var ariaSort = null;\n\n if (sortDirection) {\n ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending';\n }\n\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: className,\n \"aria-sort\": ariaSort,\n scope: scope\n }, other), children);\n });\n });\n}\n\nprocess.env.NODE_ENV !== \"production\" ? TableCell.propTypes = {\n /**\r\n * Set the text-align on the table cell content.\r\n *\r\n * Monetary or generally number fields **should be right aligned** as that allows\r\n * you to add them up quickly in your head without having to worry about decimals.\r\n */\n align: _propTypes.default.oneOf(['inherit', 'left', 'center', 'right', 'justify']),\n\n /**\r\n * The table cell contents.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If ` + "`"))) + ((`true` + ("`" + `, content will align to the right.\r\n */\n numeric: (0, _deprecatedPropType.default)(_propTypes.default.bool, 'Instead, use the `)) + ("`" + (`align` + "`")))) + (((` property.'),\n\n /**\r\n * Sets the padding applied to the cell.\r\n * By default, the Table parent component set the value.\r\n */\n padding: _propTypes.default.oneOf(['default', 'checkbox', 'dense', 'none']),\n\n /**\r\n * Set scope attribute.\r\n */\n scope: _propTypes.default.string,\n\n /**\r\n * Set aria-sort direction.\r\n */\n sortDirection: _propTypes.default.oneOf(['asc', 'desc', false]),\n\n /**\r\n * Specify the cell type.\r\n * By default, the TableHead, TableBody or TableFooter parent component set the value.\r\n */\n variant: _propTypes.default.oneOf(['head', 'body', 'footer'])\n} : void 0;\nTableCell.defaultProps = {\n align: 'inherit'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTableCell'\n})(TableCell);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _TableCell.default;\n }\n});\n\nvar _TableCell = _interopRequireDefault(require(\"./TableCell\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _Tablelvl2Context = _interopRequireDefault(require(\"../Table/Tablelvl2Context\"));\n\nvar styles = {\n /* Styles applied to the root element. */\n root: {\n display: 'table-header-group'\n }\n};\nexports.styles = styles;\nvar contextValue = {\n variant: 'head'\n};\n\nfunction TableHead(props) {\n var classes = props.classes,\n className = props.className,\n Component = props.component,\n other = (0, _objectWithoutProperties2.default)(props, [\"classes\", \"className\", \"component\"]);\n return _react.default.createElement(_Tablelvl2Context.default.Provider, {\n value: contextValue\n }, _react.default.createElement(Component, (0, _extends2.default)({\n className: (0, _classnames.default)(classes.root, className)\n }, other)));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? TableHead.propTypes = {\n /**\r\n * The content of the component, normally ` + ("`" + `TableRow`)) + ("`" + (`.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType\n} : void 0;\nTableHead.defaultProps = {\n component: 'thead'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTableHead'\n})(TableHead);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _TableHead.default;\n }\n});\n\nvar _TableHead = _interopRequireDefault(require(\"./TableHead\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _Tablelvl2Context = _interopRequireDefault(require(\"../Table/Tablelvl2Context\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n color: 'inherit',\n display: 'table-row',\n height: 48,\n verticalAlign: 'middle',\n // We disable the focus ring for mouse, touch and keyboard users.\n outline: 'none',\n '&$selected': {\n backgroundColor: theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.04)' // grey[100]\n : 'rgba(255, 255, 255, 0.08)'\n },\n '&$hover:hover': {\n backgroundColor: theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.07)' // grey[200]\n : 'rgba(255, 255, 255, 0.14)'\n }\n },\n\n /* Styles applied to the root element if ` + "`"))) + ((`selected={true}` + ("`" + `. */\n selected: {},\n\n /* Styles applied to the root element if `)) + (("`" + `hover={true}`) + ("`" + `. */\n hover: {},\n\n /* Styles applied to the root element if table variant = 'head'. */\n head: {\n height: 56\n },\n\n /* Styles applied to the root element if table variant = 'footer'. */\n footer: {\n height: 56\n }\n };\n};\n/**\r\n * Will automatically set dynamic row height\r\n * based on the material table element parent (head, body, etc).\r\n */\n\n\nexports.styles = styles;\n\nfunction TableRow(props) {\n var classes = props.classes,\n classNameProp = props.className,\n Component = props.component,\n hover = props.hover,\n selected = props.selected,\n other = (0, _objectWithoutProperties2.default)(props, [\"classes\", \"className\", \"component\", \"hover\", \"selected\"]);\n return _react.default.createElement(_Tablelvl2Context.default.Consumer, null, function (tablelvl2) {\n var _classNames;\n\n var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.head, tablelvl2 && tablelvl2.variant === 'head'), (0, _defineProperty2.default)(_classNames, classes.footer, tablelvl2 && tablelvl2.variant === 'footer'), (0, _defineProperty2.default)(_classNames, classes.hover, hover), (0, _defineProperty2.default)(_classNames, classes.selected, selected), _classNames), classNameProp);\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: className\n }, other));\n });\n}\n\nprocess.env.NODE_ENV !== \"production\" ? TableRow.propTypes = {\n /**\r\n * Should be valid children such as `)))))) + ((((("`" + (`TableCell` + "`")) + (`.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If ` + ("`" + `true`))) + (("`" + (`, the table row will shade on hover.\r\n */\n hover: _propTypes.default.bool,\n\n /**\r\n * If ` + "`")) + (`true` + ("`" + `, the table row will have the selected shading.\r\n */\n selected: _propTypes.default.bool\n} : void 0;\nTableRow.defaultProps = {\n component: 'tr',\n hover: false,\n selected: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTableRow'\n})(TableRow);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _TableRow.default;\n }\n});\n\nvar _TableRow = _interopRequireDefault(require(\"./TableRow\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center'\n },\n\n /* Styles applied to the root element if `)))) + ((("`" + (`disableGutters={false}` + "`")) + (`. */\n gutters: theme.mixins.gutters(),\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"regular\"`))) + (("`" + (`. */\n regular: theme.mixins.toolbar,\n\n /* Styles applied to the root element if ` + "`")) + ((`variant=\"dense\"` + "`") + (`. */\n dense: {\n minHeight: 48\n }\n };\n};\n\nexports.styles = styles;\n\nfunction Toolbar(props) {\n var children = props.children,\n classes = props.classes,\n classNameProp = props.className,\n disableGutters = props.disableGutters,\n variant = props.variant,\n other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"disableGutters\", \"variant\"]);\n var className = (0, _classnames.default)(classes.root, classes[variant], (0, _defineProperty2.default)({}, classes.gutters, !disableGutters), classNameProp);\n return _react.default.createElement(\"div\", (0, _extends2.default)({\n className: className\n }, other), children);\n}\n\nprocess.env.NODE_ENV !== \"production\" ? Toolbar.propTypes = {\n /**\r\n * Toolbar children, usually a mixture of ` + "`"))))) + ((((`IconButton` + ("`" + `, `)) + ("`" + (`Button` + "`"))) + ((` and ` + ("`" + `Typography`)) + ("`" + (`.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * If ` + "`")))) + (((`true` + ("`" + `, disables gutter padding.\r\n */\n disableGutters: _propTypes.default.bool,\n\n /**\r\n * The variant to use.\r\n */\n variant: _propTypes.default.oneOf(['regular', 'dense'])\n} : void 0;\nToolbar.defaultProps = {\n disableGutters: false,\n variant: 'regular'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiToolbar'\n})(Toolbar);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Toolbar.default;\n }\n});\n\nvar _Toolbar = _interopRequireDefault(require(\"./Toolbar\"));", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _withStyles = _interopRequireDefault(require(\"../styles/withStyles\"));\n\nvar _helpers = require(\"../utils/helpers\");\n\nvar styles = function styles(theme) {\n return {\n /* Styles applied to the root element. */\n root: {\n display: 'block',\n margin: 0\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`variant=\"display4\"` + "`"))) + ((`. */\n display4: theme.typography.display4,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"display3\"`)) + (("`" + `. */\n display3: theme.typography.display3,\n\n /* Styles applied to the root element if `) + ("`" + `variant=\"display2\"`)))))))) + ((((((("`" + (`. */\n display2: theme.typography.display2,\n\n /* Styles applied to the root element if ` + "`")) + (`variant=\"display1\"` + ("`" + `. */\n display1: theme.typography.display1,\n\n /* Styles applied to the root element if `))) + (("`" + (`variant=\"headline\"` + "`")) + (`. */\n headline: theme.typography.headline,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"title\"`)))) + ((("`" + (`. */\n title: theme.typography.title,\n\n /* Styles applied to the root element if ` + "`")) + (`variant=\"subheading\"` + ("`" + `. */\n subheading: theme.typography.subheading,\n\n /* Styles applied to the root element if `))) + (("`" + (`variant=\"body2\"` + "`")) + (`. */\n body2: theme.typography.body2,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"body1\"`))))) + (((("`" + (`. */\n body1: theme.typography.body1,\n\n /* Styles applied to the root element if ` + "`")) + (`variant=\"caption\"` + ("`" + `. */\n caption: theme.typography.caption,\n\n /* Styles applied to the root element if `))) + (("`" + (`variant=\"button\"` + "`")) + (`. */\n button: theme.typography.button,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"h1\"`)))) + ((("`" + (`. */\n h1: theme.typography.h1,\n\n /* Styles applied to the root element if ` + "`")) + (`variant=\"h2\"` + ("`" + `. */\n h2: theme.typography.h2,\n\n /* Styles applied to the root element if `))) + (("`" + (`variant=\"h3\"` + "`")) + ((`. */\n h3: theme.typography.h3,\n\n /* Styles applied to the root element if ` + "`") + (`variant=\"h4\"` + "`")))))) + (((((`. */\n h4: theme.typography.h4,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"h5\"`)) + ("`" + (`. */\n h5: theme.typography.h5,\n\n /* Styles applied to the root element if ` + "`"))) + ((`variant=\"h6\"` + ("`" + `. */\n h6: theme.typography.h6,\n\n /* Styles applied to the root element if `)) + ("`" + (`variant=\"subtitle1\"` + "`")))) + (((`. */\n subtitle1: theme.typography.subtitle1,\n\n /* Styles applied to the root element if ` + ("`" + `variant=\"subtitle2\"`)) + ("`" + (`. */\n subtitle2: theme.typography.subtitle2,\n\n /* Styles applied to the root element if ` + "`"))) + ((`variant=\"overline\"` + ("`" + `. */\n overline: theme.typography.overline,\n\n /* Styles applied to the root element if `)) + (("`" + `variant=\"srOnly\"`) + ("`" + `. Only accessible to screen readers. */\n srOnly: {\n position: 'absolute',\n height: 1,\n width: 1,\n overflow: 'hidden'\n },\n\n /* Styles applied to the root element if `))))) + (((("`" + (`align=\"left\"` + "`")) + (`. */\n alignLeft: {\n textAlign: 'left'\n },\n\n /* Styles applied to the root element if ` + ("`" + `align=\"center\"`))) + (("`" + (`. */\n alignCenter: {\n textAlign: 'center'\n },\n\n /* Styles applied to the root element if ` + "`")) + (`align=\"right\"` + ("`" + `. */\n alignRight: {\n textAlign: 'right'\n },\n\n /* Styles applied to the root element if `)))) + ((("`" + (`align=\"justify\"` + "`")) + (`. */\n alignJustify: {\n textAlign: 'justify'\n },\n\n /* Styles applied to the root element if ` + ("`" + `align=\"nowrap\"`))) + (("`" + (`. */\n noWrap: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap'\n },\n\n /* Styles applied to the root element if ` + "`")) + ((`gutterBottom={true}` + "`") + (`. */\n gutterBottom: {\n marginBottom: '0.35em'\n },\n\n /* Styles applied to the root element if ` + "`"))))))) + ((((((`paragraph={true}` + ("`" + `. */\n paragraph: {\n marginBottom: 16\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`color=\"inherit\"` + "`"))) + ((`. */\n colorInherit: {\n color: 'inherit'\n },\n\n /* Styles applied to the root element if ` + ("`" + `color=\"primary\"`)) + ("`" + (`. */\n colorPrimary: {\n color: theme.palette.primary.main\n },\n\n /* Styles applied to the root element if ` + "`")))) + (((`color=\"secondary\"` + ("`" + `. */\n colorSecondary: {\n color: theme.palette.secondary.main\n },\n\n /* Styles applied to the root element if `)) + ("`" + (`color=\"textPrimary\"` + "`"))) + ((`. */\n colorTextPrimary: {\n color: theme.palette.text.primary\n },\n\n /* Styles applied to the root element if ` + ("`" + `color=\"textSecondary\"`)) + (("`" + `. */\n colorTextSecondary: {\n color: theme.palette.text.secondary\n },\n\n /* Styles applied to the root element if `) + ("`" + `color=\"error\"`))))) + (((("`" + (`. */\n colorError: {\n color: theme.palette.error.main\n },\n\n /* Styles applied to the root element if ` + "`")) + (`inline={true}` + ("`" + `. */\n inline: {\n display: 'inline'\n }\n };\n};\n\nexports.styles = styles;\nvar nextVariants = {\n display4: 'h1',\n display3: 'h2',\n display2: 'h3',\n display1: 'h4',\n headline: 'h5',\n title: 'h6',\n subheading: 'subtitle1'\n};\n\nfunction getVariant(theme, variantProp) {\n var typography = theme.typography;\n var variant = variantProp;\n\n if (!variant) {\n variant = typography.useNextVariants ? 'body2' : 'body1';\n } // complete v2 switch\n\n\n if (typography.useNextVariants) {\n variant = nextVariants[variant] || variant;\n }\n\n return variant;\n}\n\nvar defaultHeadlineMapping = {\n h1: 'h1',\n h2: 'h2',\n h3: 'h3',\n h4: 'h4',\n h5: 'h5',\n h6: 'h6',\n subtitle1: 'h6',\n subtitle2: 'h6',\n body1: 'p',\n body2: 'p',\n // deprecated\n display4: 'h1',\n display3: 'h1',\n display2: 'h1',\n display1: 'h1',\n headline: 'h1',\n title: 'h2',\n subheading: 'h3'\n};\n\nfunction Typography(props) {\n var _classNames;\n\n var align = props.align,\n classes = props.classes,\n classNameProp = props.className,\n color = props.color,\n componentProp = props.component,\n gutterBottom = props.gutterBottom,\n headlineMapping = props.headlineMapping,\n inline = props.inline,\n internalDeprecatedVariant = props.internalDeprecatedVariant,\n noWrap = props.noWrap,\n paragraph = props.paragraph,\n theme = props.theme,\n variantProp = props.variant,\n other = (0, _objectWithoutProperties2.default)(props, [\"align\", \"classes\", \"className\", \"color\", \"component\", \"gutterBottom\", \"headlineMapping\", \"inline\", \"internalDeprecatedVariant\", \"noWrap\", \"paragraph\", \"theme\", \"variant\"]);\n var variant = getVariant(theme, variantProp);\n var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes[variant], variant !== 'inherit'), (0, _defineProperty2.default)(_classNames, classes[\"color\".concat((0, _helpers.capitalize)(color))], color !== 'default'), (0, _defineProperty2.default)(_classNames, classes.noWrap, noWrap), (0, _defineProperty2.default)(_classNames, classes.gutterBottom, gutterBottom), (0, _defineProperty2.default)(_classNames, classes.paragraph, paragraph), (0, _defineProperty2.default)(_classNames, classes[\"align\".concat((0, _helpers.capitalize)(align))], align !== 'inherit'), (0, _defineProperty2.default)(_classNames, classes.inline, inline), _classNames), classNameProp);\n var Component = componentProp || (paragraph ? 'p' : headlineMapping[variant] || defaultHeadlineMapping[variant]) || 'span';\n return _react.default.createElement(Component, (0, _extends2.default)({\n className: className\n }, other));\n}\n\nprocess.env.NODE_ENV !== \"production\" ? Typography.propTypes = {\n /**\r\n * Set the text-align on the component.\r\n */\n align: _propTypes.default.oneOf(['inherit', 'left', 'center', 'right', 'justify']),\n\n /**\r\n * The content of the component.\r\n */\n children: _propTypes.default.node,\n\n /**\r\n * Override or extend the styles applied to the component.\r\n * See [CSS API](#css-api) below for more details.\r\n */\n classes: _propTypes.default.object.isRequired,\n\n /**\r\n * @ignore\r\n */\n className: _propTypes.default.string,\n\n /**\r\n * The color of the component. It supports those theme colors that make sense for this component.\r\n */\n color: _propTypes.default.oneOf(['default', 'error', 'inherit', 'primary', 'secondary', 'textPrimary', 'textSecondary']),\n\n /**\r\n * The component used for the root node.\r\n * Either a string to use a DOM element or a component.\r\n * By default, it maps the variant to a good default headline component.\r\n */\n component: _utils.componentPropType,\n\n /**\r\n * If `))) + (("`" + (`true` + "`")) + (`, the text will have a bottom margin.\r\n */\n gutterBottom: _propTypes.default.bool,\n\n /**\r\n * We are empirically mapping the variant property to a range of different DOM element types.\r\n * For instance, subtitle1 to ` + ("`" + `
`)))) + ((("`" + (`.\r\n * If you wish to change that mapping, you can provide your own.\r\n * Alternatively, you can use the ` + "`")) + (`component` + ("`" + ` property.\r\n * The default mapping is the following:\r\n */\n headlineMapping: _propTypes.default.object,\n\n /**\r\n * Controls whether the Typography is inline or not.\r\n */\n inline: _propTypes.default.bool,\n\n /**\r\n * A deprecated variant is used from an internal component. Users don't need\r\n * a deprecation warning here if they switched to the v2 theme. They already\r\n * get the mapping that will be applied in the next major release.\r\n *\r\n * @internal\r\n */\n internalDeprecatedVariant: _propTypes.default.bool,\n\n /**\r\n * If `))) + (("`" + (`true` + "`")) + ((`, the text will not wrap, but instead will truncate with an ellipsis.\r\n */\n noWrap: _propTypes.default.bool,\n\n /**\r\n * If ` + "`") + (`true` + "`")))))) + (((((`, the text will have a bottom margin.\r\n */\n paragraph: _propTypes.default.bool,\n\n /**\r\n * @ignore\r\n */\n theme: _propTypes.default.object.isRequired,\n\n /**\r\n * Applies the theme typography styles.\r\n * Use ` + ("`" + `body1`)) + ("`" + (` as the default value with the legacy implementation and ` + "`"))) + ((`body2` + ("`" + ` with the new one.\r\n */\n variant: (0, _utils.chainPropTypes)(_propTypes.default.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'subtitle1', 'subtitle2', 'body1', 'body2', 'caption', 'button', 'overline', 'srOnly', 'inherit', // deprecated\n 'display4', 'display3', 'display2', 'display1', 'headline', 'title', 'subheading']), function (props) {\n var deprecatedVariants = ['display4', 'display3', 'display2', 'display1', 'headline', 'title', 'subheading'];\n\n if (props.theme.typography.useNextVariants && !props.internalDeprecatedVariant && deprecatedVariants.indexOf(props.variant) !== -1) {\n return new Error('Material-UI: you are using a deprecated typography variant: ' + \"`)) + ("`" + (`\".concat(props.variant, \"` + "`")))) + (((` that will be removed in the next major release.\\n\") + 'Please read the migration guide under https://material-ui.com/style/typography#migration-to-typography-v2.');\n }\n\n return null;\n })\n} : void 0;\nTypography.defaultProps = {\n align: 'inherit',\n color: 'default',\n gutterBottom: false,\n headlineMapping: defaultHeadlineMapping,\n inline: false,\n noWrap: false,\n paragraph: false\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n name: 'MuiTypography',\n withTheme: true\n})(Typography);\n\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _Typography.default;\n }\n});\n\nvar _Typography = _interopRequireDefault(require(\"./Typography\"));", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar common = {\n black: '#000',\n white: '#fff'\n};\nvar _default = common;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar grey = {\n 50: '#fafafa',\n 100: '#f5f5f5',\n 200: '#eeeeee',\n 300: '#e0e0e0',\n 400: '#bdbdbd',\n 500: '#9e9e9e',\n 600: '#757575',\n 700: '#616161',\n 800: '#424242',\n 900: '#212121',\n A100: '#d5d5d5',\n A200: '#aaaaaa',\n A400: '#303030',\n A700: '#616161'\n};\nvar _default = grey;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar indigo = {\n 50: '#e8eaf6',\n 100: '#c5cae9',\n 200: '#9fa8da',\n 300: '#7986cb',\n 400: '#5c6bc0',\n 500: '#3f51b5',\n 600: '#3949ab',\n 700: '#303f9f',\n 800: '#283593',\n 900: '#1a237e',\n A100: '#8c9eff',\n A200: '#536dfe',\n A400: '#3d5afe',\n A700: '#304ffe'\n};\nvar _default = indigo;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar pink = {\n 50: '#fce4ec',\n 100: '#f8bbd0',\n 200: '#f48fb1',\n 300: '#f06292',\n 400: '#ec407a',\n 500: '#e91e63',\n 600: '#d81b60',\n 700: '#c2185b',\n 800: '#ad1457',\n 900: '#880e4f',\n A100: '#ff80ab',\n A200: '#ff4081',\n A400: '#f50057',\n A700: '#c51162'\n};\nvar _default = pink;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar red = {\n 50: '#ffebee',\n 100: '#ffcdd2',\n 200: '#ef9a9a',\n 300: '#e57373',\n 400: '#ef5350',\n 500: '#f44336',\n 600: '#e53935',\n 700: '#d32f2f',\n 800: '#c62828',\n 900: '#b71c1c',\n A100: '#ff8a80',\n A200: '#ff5252',\n A400: '#ff1744',\n A700: '#d50000'\n};\nvar _default = red;\nexports.default = _default;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = exports.EXITING = exports.ENTERED = exports.ENTERING = exports.EXITED = exports.UNMOUNTED = void 0;\n\nvar PropTypes = _interopRequireWildcard(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactDom = _interopRequireDefault(require(\"react-dom\"));\n\nvar _reactLifecyclesCompat = require(\"react-lifecycles-compat\");\n\nvar _PropTypes = require(\"./utils/PropTypes\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nvar UNMOUNTED = 'unmounted';\nexports.UNMOUNTED = UNMOUNTED;\nvar EXITED = 'exited';\nexports.EXITED = EXITED;\nvar ENTERING = 'entering';\nexports.ENTERING = ENTERING;\nvar ENTERED = 'entered';\nexports.ENTERED = ENTERED;\nvar EXITING = 'exiting';\n/**\n * The Transition component lets you describe a transition from one component\n * state to another _over time_ with a simple declarative API. Most commonly\n * it's used to animate the mounting and unmounting of a component, but can also\n * be used to describe in-place transition states as well.\n *\n * ---\n *\n * **Note**: ` + ("`" + `Transition`)) + ("`" + (` is a platform-agnostic base component. If you're using\n * transitions in CSS, you'll probably want to use\n * [` + "`"))) + ((`CSSTransition` + ("`" + `](https://reactcommunity.org/react-transition-group/css-transition)\n * instead. It inherits all the features of `)) + (("`" + `Transition`) + ("`" + `, but contains\n * additional features necessary to play nice with CSS transitions (hence the\n * name of the component).\n *\n * ---\n *\n * By default the `))))) + (((("`" + (`Transition` + "`")) + (` component does not alter the behavior of the\n * component it renders, it only tracks \"enter\" and \"exit\" states for the\n * components. It's up to you to give meaning and effect to those states. For\n * example we can add styles to a component when it enters or exits:\n *\n * ` + ("`" + "`"))) + (("`" + (`jsx\n * import { Transition } from 'react-transition-group';\n *\n * const duration = 300;\n *\n * const defaultStyle = {\n * transition: ` + "`")) + (`opacity ${duration}ms ease-in-out` + ("`" + `,\n * opacity: 0,\n * }\n *\n * const transitionStyles = {\n * entering: { opacity: 0 },\n * entered: { opacity: 1 },\n * };\n *\n * const Fade = ({ in: inProp }) => (\n * \n * {state => (\n *
\n * I'm a fade Transition!\n *
\n * )}\n *
\n * );\n * `)))) + ((("`" + ("`" + "`")) + (`\n *\n * There are 4 main states a Transition can be in:\n * - ` + ("`" + `'entering'`))) + (("`" + (`\n * - ` + "`")) + ((`'entered'` + "`") + (`\n * - ` + "`"))))))))) + ((((((((`'exiting'` + ("`" + `\n * - `)) + ("`" + (`'exited'` + "`"))) + ((`\n *\n * Transition state is toggled via the ` + ("`" + `in`)) + ("`" + (` prop. When ` + "`")))) + (((`true` + ("`" + ` the component\n * begins the \"Enter\" stage. During this stage, the component will shift from\n * its current transition state, to `)) + ("`" + (`'entering'` + "`"))) + ((` for the duration of the\n * transition and then to the ` + ("`" + `'entered'`)) + ("`" + (` stage once it's complete. Let's take\n * the following example (we'll use the\n * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) hook):\n *\n * ` + "`"))))) + (((("`" + ("`" + `jsx\n * function App() {\n * const [inProp, setInProp] = useState(false);\n * return (\n *
\n * \n * {state => (\n * // ...\n * )}\n * \n * \n *
\n * );\n * }\n * `)) + ("`" + ("`" + "`"))) + ((`\n *\n * When the button is clicked the component will shift to the ` + ("`" + `'entering'`)) + ("`" + (` state\n * and stay there for 500ms (the value of ` + "`")))) + (((`timeout` + ("`" + `) before it finally switches\n * to `)) + ("`" + (`'entered'` + "`"))) + ((`.\n *\n * When ` + ("`" + `in`)) + (("`" + ` is `) + ("`" + `false`)))))) + ((((("`" + (` the same thing happens except the state moves from\n * ` + "`")) + (`'exiting'` + ("`" + ` to `))) + (("`" + (`'exited'` + "`")) + (`.\n */\n\nexports.EXITING = EXITING;\n\nvar Transition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(Transition, _React$Component);\n\n function Transition(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n var parentGroup = context.transitionGroup; // In the context of a TransitionGroup all enters are really appears\n\n var appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n var initialStatus;\n _this.appearStatus = null;\n\n if (props.in) {\n if (appear) {\n initialStatus = EXITED;\n _this.appearStatus = ENTERING;\n } else {\n initialStatus = ENTERED;\n }\n } else {\n if (props.unmountOnExit || props.mountOnEnter) {\n initialStatus = UNMOUNTED;\n } else {\n initialStatus = EXITED;\n }\n }\n\n _this.state = {\n status: initialStatus\n };\n _this.nextCallback = null;\n return _this;\n }\n\n var _proto = Transition.prototype;\n\n _proto.getChildContext = function getChildContext() {\n return {\n transitionGroup: null // allows for nested Transitions\n\n };\n };\n\n Transition.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var nextIn = _ref.in;\n\n if (nextIn && prevState.status === UNMOUNTED) {\n return {\n status: EXITED\n };\n }\n\n return null;\n }; // getSnapshotBeforeUpdate(prevProps) {\n // let nextStatus = null\n // if (prevProps !== this.props) {\n // const { status } = this.state\n // if (this.props.in) {\n // if (status !== ENTERING && status !== ENTERED) {\n // nextStatus = ENTERING\n // }\n // } else {\n // if (status === ENTERING || status === ENTERED) {\n // nextStatus = EXITING\n // }\n // }\n // }\n // return { nextStatus }\n // }\n\n\n _proto.componentDidMount = function componentDidMount() {\n this.updateStatus(true, this.appearStatus);\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var nextStatus = null;\n\n if (prevProps !== this.props) {\n var status = this.state.status;\n\n if (this.props.in) {\n if (status !== ENTERING && status !== ENTERED) {\n nextStatus = ENTERING;\n }\n } else {\n if (status === ENTERING || status === ENTERED) {\n nextStatus = EXITING;\n }\n }\n }\n\n this.updateStatus(false, nextStatus);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.cancelNextCallback();\n };\n\n _proto.getTimeouts = function getTimeouts() {\n var timeout = this.props.timeout;\n var exit, enter, appear;\n exit = enter = appear = timeout;\n\n if (timeout != null && typeof timeout !== 'number') {\n exit = timeout.exit;\n enter = timeout.enter; // TODO: remove fallback for next major\n\n appear = timeout.appear !== undefined ? timeout.appear : enter;\n }\n\n return {\n exit: exit,\n enter: enter,\n appear: appear\n };\n };\n\n _proto.updateStatus = function updateStatus(mounting, nextStatus) {\n if (mounting === void 0) {\n mounting = false;\n }\n\n if (nextStatus !== null) {\n // nextStatus will always be ENTERING or EXITING.\n this.cancelNextCallback();\n\n var node = _reactDom.default.findDOMNode(this);\n\n if (nextStatus === ENTERING) {\n this.performEnter(node, mounting);\n } else {\n this.performExit(node);\n }\n } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n this.setState({\n status: UNMOUNTED\n });\n }\n };\n\n _proto.performEnter = function performEnter(node, mounting) {\n var _this2 = this;\n\n var enter = this.props.enter;\n var appearing = this.context.transitionGroup ? this.context.transitionGroup.isMounting : mounting;\n var timeouts = this.getTimeouts();\n var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED\n // if we are mounting and running this it means appear _must_ be set\n\n if (!mounting && !enter) {\n this.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node);\n });\n return;\n }\n\n this.props.onEnter(node, appearing);\n this.safeSetState({\n status: ENTERING\n }, function () {\n _this2.props.onEntering(node, appearing);\n\n _this2.onTransitionEnd(node, enterTimeout, function () {\n _this2.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node, appearing);\n });\n });\n });\n };\n\n _proto.performExit = function performExit(node) {\n var _this3 = this;\n\n var exit = this.props.exit;\n var timeouts = this.getTimeouts(); // no exit animation skip right to EXITED\n\n if (!exit) {\n this.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n return;\n }\n\n this.props.onExit(node);\n this.safeSetState({\n status: EXITING\n }, function () {\n _this3.props.onExiting(node);\n\n _this3.onTransitionEnd(node, timeouts.exit, function () {\n _this3.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n });\n });\n };\n\n _proto.cancelNextCallback = function cancelNextCallback() {\n if (this.nextCallback !== null) {\n this.nextCallback.cancel();\n this.nextCallback = null;\n }\n };\n\n _proto.safeSetState = function safeSetState(nextState, callback) {\n // This shouldn't be necessary, but there are weird race conditions with\n // setState callbacks and unmounting in testing, so always make sure that\n // we can cancel any pending setState callbacks after we unmount.\n callback = this.setNextCallback(callback);\n this.setState(nextState, callback);\n };\n\n _proto.setNextCallback = function setNextCallback(callback) {\n var _this4 = this;\n\n var active = true;\n\n this.nextCallback = function (event) {\n if (active) {\n active = false;\n _this4.nextCallback = null;\n callback(event);\n }\n };\n\n this.nextCallback.cancel = function () {\n active = false;\n };\n\n return this.nextCallback;\n };\n\n _proto.onTransitionEnd = function onTransitionEnd(node, timeout, handler) {\n this.setNextCallback(handler);\n var doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener;\n\n if (!node || doesNotHaveTimeoutOrListener) {\n setTimeout(this.nextCallback, 0);\n return;\n }\n\n if (this.props.addEndListener) {\n this.props.addEndListener(node, this.nextCallback);\n }\n\n if (timeout != null) {\n setTimeout(this.nextCallback, timeout);\n }\n };\n\n _proto.render = function render() {\n var status = this.state.status;\n\n if (status === UNMOUNTED) {\n return null;\n }\n\n var _this$props = this.props,\n children = _this$props.children,\n childProps = _objectWithoutPropertiesLoose(_this$props, [\"children\"]); // filter props for Transtition\n\n\n delete childProps.in;\n delete childProps.mountOnEnter;\n delete childProps.unmountOnExit;\n delete childProps.appear;\n delete childProps.enter;\n delete childProps.exit;\n delete childProps.timeout;\n delete childProps.addEndListener;\n delete childProps.onEnter;\n delete childProps.onEntering;\n delete childProps.onEntered;\n delete childProps.onExit;\n delete childProps.onExiting;\n delete childProps.onExited;\n\n if (typeof children === 'function') {\n return children(status, childProps);\n }\n\n var child = _react.default.Children.only(children);\n\n return _react.default.cloneElement(child, childProps);\n };\n\n return Transition;\n}(_react.default.Component);\n\nTransition.contextTypes = {\n transitionGroup: PropTypes.object\n};\nTransition.childContextTypes = {\n transitionGroup: function transitionGroup() {}\n};\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * A ` + ("`" + `function`)))) + ((("`" + (` child can be used instead of a React element. This function is\n * called with the current transition status (` + "`")) + (`'entering'` + ("`" + `, `))) + (("`" + (`'entered'` + "`")) + ((`,\n * ` + "`") + (`'exiting'` + "`"))))) + ((((`, ` + ("`" + `'exited'`)) + ("`" + (`, ` + "`"))) + ((`'unmounted'` + ("`" + `), which can be used to apply context\n * specific props to a component.\n *\n * `)) + ("`" + ("`" + "`")))) + (((`jsx\n * \n * {state => (\n * \n * )}\n * \n * ` + "`"))) + (("`" + ("`" + `\n */\n children: PropTypes.oneOfType([PropTypes.func.isRequired, PropTypes.element.isRequired]).isRequired,\n\n /**\n * Show the component; triggers the enter or exit states\n */\n in: PropTypes.bool,\n\n /**\n * By default the child component is mounted immediately along with\n * the parent `)) + (("`" + `Transition`) + ("`" + ` component. If you want to \"lazy mount\" the component on the\n * first `))))))) + (((((("`" + (`in={true}` + "`")) + (` you can set ` + ("`" + `mountOnEnter`))) + (("`" + (`. After the first enter transition the component will stay\n * mounted, even on \"exited\", unless you also specify ` + "`")) + (`unmountOnExit` + ("`" + `.\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * By default the child component stays mounted after it reaches the `)))) + ((("`" + (`'exited'` + "`")) + (` state.\n * Set ` + ("`" + `unmountOnExit`))) + (("`" + (` if you'd prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * Normally a component is not transitioned if it is shown when the ` + "`")) + (`` + ("`" + ` component mounts.\n * If you want to transition on the first mount set `))))) + (((("`" + (`appear` + "`")) + (` to ` + ("`" + `true`))) + (("`" + (`, and the\n * component will transition in as soon as the ` + "`")) + (`` + ("`" + ` mounts.\n *\n * > Note: there are no specific \"appear\" states. `)))) + ((("`" + (`appear` + "`")) + (` only adds an additional ` + ("`" + `enter`))) + (("`" + (` transition.\n */\n appear: PropTypes.bool,\n\n /**\n * Enable or disable enter transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * Enable or disable exit transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * The duration of the transition, in milliseconds.\n * Required unless ` + "`")) + ((`addEndListener` + "`") + (` is provided.\n *\n * You may specify a single timeout for all transitions:\n *\n * ` + "`")))))) + ((((("`" + ("`" + `jsx\n * timeout={500}\n * `)) + ("`" + ("`" + "`"))) + ((`\n *\n * or individually:\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * timeout={{\n * appear: 500,\n * enter: 300,\n * exit: 500,\n * }}\n * ` + "`")))) + ((("`" + ("`" + `\n *\n * - `)) + ("`" + (`appear` + "`"))) + ((` defaults to the value of ` + ("`" + `enter`)) + (("`" + `\n * - `) + ("`" + `enter`))))) + (((("`" + (` defaults to ` + "`")) + (`0` + ("`" + `\n * - `))) + (("`" + (`exit` + "`")) + (` defaults to ` + ("`" + `0`)))) + ((("`" + (`\n *\n * @type {number | { enter?: number, exit?: number, appear?: number }}\n */\n timeout: function timeout(props) {\n var pt = _PropTypes.timeoutsShape;\n if (!props.addEndListener) pt = pt.isRequired;\n\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return pt.apply(void 0, [props].concat(args));\n },\n\n /**\n * Add a custom transition end trigger. Called with the transitioning\n * DOM node and a ` + "`")) + (`done` + ("`" + ` callback. Allows for more fine grained transition end\n * logic. **Note:** Timeouts are still used as a fallback if provided.\n *\n * `))) + (("`" + ("`" + "`")) + ((`jsx\n * addEndListener={(node, done) => {\n * // use the css transitionend event to mark the finish of a transition\n * node.addEventListener('transitionend', done, false);\n * }}\n * ` + "`") + ("`" + "`")))))))) + (((((((`\n */\n addEndListener: PropTypes.func,\n\n /**\n * Callback fired before the \"entering\" status is applied. An extra parameter\n * ` + ("`" + `isAppearing`)) + ("`" + (` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired after the \"entering\" status is applied. An extra parameter\n * ` + "`"))) + ((`isAppearing` + ("`" + ` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the \"entered\" status is applied. An extra parameter\n * `)) + ("`" + (`isAppearing` + "`")))) + (((` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired before the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired after the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the \"exited\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExited: PropTypes.func // Name the function so it is clearer in the documentation\n\n} : {};\n\nfunction noop() {}\n\nTransition.defaultProps = {\n in: false,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n enter: true,\n exit: true,\n onEnter: noop,\n onEntering: noop,\n onEntered: noop,\n onExit: noop,\n onExiting: noop,\n onExited: noop\n};\nTransition.UNMOUNTED = 0;\nTransition.EXITED = 1;\nTransition.ENTERING = 2;\nTransition.ENTERED = 3;\nTransition.EXITING = 4;\n\nvar _default = (0, _reactLifecyclesCompat.polyfill)(Transition);\n\nexports.default = _default;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactLifecyclesCompat = require(\"react-lifecycles-compat\");\n\nvar _ChildMapping = require(\"./utils/ChildMapping\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nvar values = Object.values || function (obj) {\n return Object.keys(obj).map(function (k) {\n return obj[k];\n });\n};\n\nvar defaultProps = {\n component: 'div',\n childFactory: function childFactory(child) {\n return child;\n }\n /**\n * The ` + ("`" + ``)) + ("`" + (` component manages a set of transition components\n * (` + "`"))) + ((`` + ("`" + ` and `)) + ("`" + (`` + "`"))))) + ((((`) in a list. Like with the transition\n * components, ` + ("`" + ``)) + ("`" + (` is a state machine for managing the mounting\n * and unmounting of components over time.\n *\n * Consider the example below. As items are removed or added to the TodoList the\n * ` + "`"))) + ((`in` + ("`" + ` prop is toggled automatically by the `)) + ("`" + (`` + "`")))) + (((`.\n *\n * Note that ` + ("`" + ``)) + ("`" + (` does not define any animation behavior!\n * Exactly _how_ a list item animates is up to the individual transition\n * component. This means you can mix and match animations across different list\n * items.\n */\n\n};\n\nvar TransitionGroup =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(TransitionGroup, _React$Component);\n\n function TransitionGroup(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n\n var handleExited = _this.handleExited.bind(_assertThisInitialized(_assertThisInitialized(_this))); // Initial children should all be entering, dependent on appear\n\n\n _this.state = {\n handleExited: handleExited,\n firstRender: true\n };\n return _this;\n }\n\n var _proto = TransitionGroup.prototype;\n\n _proto.getChildContext = function getChildContext() {\n return {\n transitionGroup: {\n isMounting: !this.appeared\n }\n };\n };\n\n _proto.componentDidMount = function componentDidMount() {\n this.appeared = true;\n this.mounted = true;\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.mounted = false;\n };\n\n TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {\n var prevChildMapping = _ref.children,\n handleExited = _ref.handleExited,\n firstRender = _ref.firstRender;\n return {\n children: firstRender ? (0, _ChildMapping.getInitialChildMapping)(nextProps, handleExited) : (0, _ChildMapping.getNextChildMapping)(nextProps, prevChildMapping, handleExited),\n firstRender: false\n };\n };\n\n _proto.handleExited = function handleExited(child, node) {\n var currentChildMapping = (0, _ChildMapping.getChildMapping)(this.props.children);\n if (child.key in currentChildMapping) return;\n\n if (child.props.onExited) {\n child.props.onExited(node);\n }\n\n if (this.mounted) {\n this.setState(function (state) {\n var children = _extends({}, state.children);\n\n delete children[child.key];\n return {\n children: children\n };\n });\n }\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n Component = _this$props.component,\n childFactory = _this$props.childFactory,\n props = _objectWithoutPropertiesLoose(_this$props, [\"component\", \"childFactory\"]);\n\n var children = values(this.state.children).map(childFactory);\n delete props.appear;\n delete props.enter;\n delete props.exit;\n\n if (Component === null) {\n return children;\n }\n\n return _react.default.createElement(Component, props, children);\n };\n\n return TransitionGroup;\n}(_react.default.Component);\n\nTransitionGroup.childContextTypes = {\n transitionGroup: _propTypes.default.object.isRequired\n};\nTransitionGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * ` + "`"))) + ((`` + ("`" + ` renders a `)) + (("`" + `
`) + ("`" + ` by default. You can change this\n * behavior by providing a `)))))) + ((((("`" + (`component` + "`")) + (` prop.\n * If you use React v16+ and would like to avoid a wrapping ` + ("`" + `
`))) + (("`" + (` element\n * you can pass in ` + "`")) + (`component={null}` + ("`" + `. This is useful if the wrapping div\n * borks your css styles.\n */\n component: _propTypes.default.any,\n\n /**\n * A set of `)))) + ((("`" + (`` + "`")) + (` components, that are toggled ` + ("`" + `in`))) + (("`" + (` and out as they\n * leave. the ` + "`")) + ((`` + "`") + (` will inject specific transition props, so\n * remember to spread them through if you are wrapping the ` + "`"))))) + ((((`` + ("`" + ` as\n * with our `)) + ("`" + (`` + "`"))) + ((` example.\n *\n * While this component is meant for multiple ` + ("`" + `Transition`)) + ("`" + (` or ` + "`")))) + (((`CSSTransition` + ("`" + `\n * children, sometimes you may want to have a single transition child with\n * content that you want to be transitioned out and in when you change it\n * (e.g. routes, images etc.) In that case you can change the `)) + ("`" + (`key` + "`"))) + ((` prop of\n * the transition child as you change its content, this will cause\n * ` + ("`" + `TransitionGroup`)) + (("`" + ` to transition the child out and back in.\n */\n children: _propTypes.default.node,\n\n /**\n * A convenience prop that enables or disables appear animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n appear: _propTypes.default.bool,\n\n /**\n * A convenience prop that enables or disables enter animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n enter: _propTypes.default.bool,\n\n /**\n * A convenience prop that enables or disables exit animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n exit: _propTypes.default.bool,\n\n /**\n * You may need to apply reactive updates to a child as it is exiting.\n * This is generally done by using `) + ("`" + `cloneElement`))))))) + (((((("`" + (` however in the case of an exiting\n * child the element has already been removed and not accessible to the consumer.\n *\n * If you do need to update a child as it leaves you can provide a ` + "`")) + (`childFactory` + ("`" + `\n * to wrap every child, even the ones that are leaving.\n *\n * @type Function(child: ReactElement) -> ReactElement\n */\n childFactory: _propTypes.default.func\n} : {};\nTransitionGroup.defaultProps = defaultProps;\n\nvar _default = (0, _reactLifecyclesCompat.polyfill)(TransitionGroup);\n\nexports.default = _default;\nmodule.exports = exports[\"default\"];", + "\"use strict\";\n\nexports.__esModule = true;\nexports.getChildMapping = getChildMapping;\nexports.mergeChildMappings = mergeChildMappings;\nexports.getInitialChildMapping = getInitialChildMapping;\nexports.getNextChildMapping = getNextChildMapping;\n\nvar _react = require(\"react\");\n\n/**\n * Given `))) + (("`" + (`this.props.children` + "`")) + (`, return an object mapping key to child.\n *\n * @param {*} children ` + ("`" + `this.props.children`)))) + ((("`" + (`\n * @return {object} Mapping of key to child\n */\nfunction getChildMapping(children, mapFn) {\n var mapper = function mapper(child) {\n return mapFn && (0, _react.isValidElement)(child) ? mapFn(child) : child;\n };\n\n var result = Object.create(null);\n if (children) _react.Children.map(children, function (c) {\n return c;\n }).forEach(function (child) {\n // run the map function here instead so that the key is the computed one\n result[child.key] = mapper(child);\n });\n return result;\n}\n/**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want to show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev children as returned from\n * ` + "`")) + (`ReactTransitionChildMapping.getChildMapping()` + ("`" + `.\n * @param {object} next next children as returned from\n * `))) + (("`" + (`ReactTransitionChildMapping.getChildMapping()` + "`")) + ((`.\n * @return {object} a key set that contains all keys in ` + "`") + (`prev` + "`"))))) + ((((` and all keys\n * in ` + ("`" + `next`)) + ("`" + (` in a reasonable order.\n */\n\n\nfunction mergeChildMappings(prev, next) {\n prev = prev || {};\n next = next || {};\n\n function getValueForKey(key) {\n return key in next ? next[key] : prev[key];\n } // For each key of ` + "`"))) + ((`next` + ("`" + `, the list of keys to insert before that key in\n // the combined list\n\n\n var nextKeysPending = Object.create(null);\n var pendingKeys = [];\n\n for (var prevKey in prev) {\n if (prevKey in next) {\n if (pendingKeys.length) {\n nextKeysPending[prevKey] = pendingKeys;\n pendingKeys = [];\n }\n } else {\n pendingKeys.push(prevKey);\n }\n }\n\n var i;\n var childMapping = {};\n\n for (var nextKey in next) {\n if (nextKeysPending[nextKey]) {\n for (i = 0; i < nextKeysPending[nextKey].length; i++) {\n var pendingNextKey = nextKeysPending[nextKey][i];\n childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);\n }\n }\n\n childMapping[nextKey] = getValueForKey(nextKey);\n } // Finally, add the keys which didn't appear before any key in `)) + ("`" + (`next` + "`")))) + (((`\n\n\n for (i = 0; i < pendingKeys.length; i++) {\n childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);\n }\n\n return childMapping;\n}\n\nfunction getProp(child, prop, props) {\n return props[prop] != null ? props[prop] : child.props[prop];\n}\n\nfunction getInitialChildMapping(props, onExited) {\n return getChildMapping(props.children, function (child) {\n return (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: true,\n appear: getProp(child, 'appear', props),\n enter: getProp(child, 'enter', props),\n exit: getProp(child, 'exit', props)\n });\n });\n}\n\nfunction getNextChildMapping(nextProps, prevChildMapping, onExited) {\n var nextChildMapping = getChildMapping(nextProps.children);\n var children = mergeChildMappings(prevChildMapping, nextChildMapping);\n Object.keys(children).forEach(function (key) {\n var child = children[key];\n if (!(0, _react.isValidElement)(child)) return;\n var hasPrev = key in prevChildMapping;\n var hasNext = key in nextChildMapping;\n var prevChild = prevChildMapping[key];\n var isLeaving = (0, _react.isValidElement)(prevChild) && !prevChild.props.in; // item is new (entering)\n\n if (hasNext && (!hasPrev || isLeaving)) {\n // console.log('entering', key)\n children[key] = (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: true,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n } else if (!hasNext && hasPrev && !isLeaving) {\n // item is old (exiting)\n // console.log('leaving', key)\n children[key] = (0, _react.cloneElement)(child, {\n in: false\n });\n } else if (hasNext && hasPrev && (0, _react.isValidElement)(prevChild)) {\n // item hasn't changed transition states\n // copy over the last transition props;\n // console.log('unchanged', key)\n children[key] = (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: prevChild.props.in,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n }\n });\n return children;\n}", + "\"use strict\";\n\nexports.__esModule = true;\nexports.classNamesShape = exports.timeoutsShape = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar timeoutsShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({\n enter: _propTypes.default.number,\n exit: _propTypes.default.number,\n appear: _propTypes.default.number\n}).isRequired]) : null;\nexports.timeoutsShape = timeoutsShape;\nvar classNamesShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({\n enter: _propTypes.default.string,\n exit: _propTypes.default.string,\n active: _propTypes.default.string\n}), _propTypes.default.shape({\n enter: _propTypes.default.string,\n enterDone: _propTypes.default.string,\n enterActive: _propTypes.default.string,\n exit: _propTypes.default.string,\n exitDone: _propTypes.default.string,\n exitActive: _propTypes.default.string\n})]) : null;\nexports.classNamesShape = classNamesShape;", + "\"use strict\";\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.MuiThemeProviderOld = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf2 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _brcast = _interopRequireDefault(require(\"brcast\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _themeListener = _interopRequireWildcard(require(\"./themeListener\"));\n\n/* eslint-disable no-underscore-dangle */\n\n/**\r\n * This component takes a ` + ("`" + `theme`)) + ("`" + (` property.\r\n * It makes the ` + "`"))) + ((`theme` + ("`" + ` available down the React tree thanks to React context.\r\n * This component should preferably be used at **the root of your component tree**.\r\n */\nvar MuiThemeProviderOld =\n/*#__PURE__*/\nfunction (_React$Component) {\n (0, _inherits2.default)(MuiThemeProviderOld, _React$Component);\n\n // We are not using the React state in order to avoid unnecessary rerender.\n function MuiThemeProviderOld(props, context) {\n var _this;\n\n (0, _classCallCheck2.default)(this, MuiThemeProviderOld);\n _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MuiThemeProviderOld).call(this)); // Get the outer theme from the context, can be null\n\n _this.broadcast = (0, _brcast.default)();\n _this.outerTheme = _themeListener.default.initial(context); // Propagate the theme so it can be accessed by the children\n\n _this.broadcast.setState(_this.mergeOuterLocalTheme(props.theme));\n\n return _this;\n }\n\n (0, _createClass2.default)(MuiThemeProviderOld, [{\n key: \"getChildContext\",\n value: function getChildContext() {\n var _ref;\n\n var _this$props = this.props,\n disableStylesGeneration = _this$props.disableStylesGeneration,\n sheetsCache = _this$props.sheetsCache,\n sheetsManager = _this$props.sheetsManager;\n var muiThemeProviderOptions = this.context.muiThemeProviderOptions || {};\n\n if (disableStylesGeneration !== undefined) {\n muiThemeProviderOptions.disableStylesGeneration = disableStylesGeneration;\n }\n\n if (sheetsCache !== undefined) {\n muiThemeProviderOptions.sheetsCache = sheetsCache;\n }\n\n if (sheetsManager !== undefined) {\n muiThemeProviderOptions.sheetsManager = sheetsManager;\n }\n\n return _ref = {}, (0, _defineProperty2.default)(_ref, _themeListener.CHANNEL, this.broadcast), (0, _defineProperty2.default)(_ref, \"muiThemeProviderOptions\", muiThemeProviderOptions), _ref;\n }\n }, {\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n // Subscribe on the outer theme, if present\n this.unsubscribeId = _themeListener.default.subscribe(this.context, function (outerTheme) {\n _this2.outerTheme = outerTheme; // Forward the parent theme update to the children\n\n _this2.broadcast.setState(_this2.mergeOuterLocalTheme(_this2.props.theme));\n });\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate(prevProps) {\n // Propagate a local theme update\n if (this.props.theme !== prevProps.theme) {\n this.broadcast.setState(this.mergeOuterLocalTheme(this.props.theme));\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n if (this.unsubscribeId !== null) {\n _themeListener.default.unsubscribe(this.context, this.unsubscribeId);\n }\n } // Simple merge between the outer theme and the local theme\n\n }, {\n key: \"mergeOuterLocalTheme\",\n value: function mergeOuterLocalTheme(localTheme) {\n // To support composition of theme.\n if (typeof localTheme === 'function') {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(this.outerTheme, ['Material-UI: you are providing a theme function property ' + 'to the MuiThemeProvider component:', ' outerTheme} />', 'However, no outer theme is present.', 'Make sure a theme is already injected higher in the React tree ' + 'or provide a theme object.'].join('\\n')) : void 0;\n return localTheme(this.outerTheme);\n }\n\n if (!this.outerTheme) {\n return localTheme;\n }\n\n return (0, _extends2.default)({}, this.outerTheme, localTheme);\n }\n }, {\n key: \"render\",\n value: function render() {\n // TODO move the sheetsManager property to a different component.\n // warning(\n // typeof window !== 'undefined' || this.props.sheetsManager,\n // [\n // 'Material-UI: you need to provide a sheetsManager to the MuiThemeProvider ' +\n // 'when rendering on the server.',\n // 'If you do not, you might experience a memory leak',\n // ].join('\\n'),\n // );\n return this.props.children;\n }\n }]);\n return MuiThemeProviderOld;\n}(_react.default.Component);\n\nexports.MuiThemeProviderOld = MuiThemeProviderOld;\nprocess.env.NODE_ENV !== \"production\" ? MuiThemeProviderOld.propTypes = {\n /**\r\n * You can wrap a node.\r\n */\n children: _propTypes.default.node.isRequired,\n\n /**\r\n * You can disable the generation of the styles with this option.\r\n * It can be useful when traversing the React tree outside of the HTML\r\n * rendering step on the server.\r\n * Let's say you are using react-apollo to extract all\r\n * the queries made by the interface server-side.\r\n * You can significantly speed up the traversal with this property.\r\n */\n disableStylesGeneration: _propTypes.default.bool,\n\n /**\r\n * @ignore\r\n *\r\n * In beta.\r\n */\n sheetsCache: _propTypes.default.object,\n\n /**\r\n * The sheetsManager is used to deduplicate style sheet injection in the page.\r\n * It's deduplicating using the (theme, styles) couple.\r\n * On the server, you should provide a new instance for each request.\r\n */\n sheetsManager: _propTypes.default.object,\n\n /**\r\n * A theme object.\r\n */\n theme: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.func]).isRequired\n} : void 0;\n\nif (process.env.NODE_ENV !== 'production') {\n process.env.NODE_ENV !== \"production\" ? MuiThemeProviderOld.propTypes = (0, _utils.exactProp)(MuiThemeProviderOld.propTypes) : void 0;\n}\n\nMuiThemeProviderOld.childContextTypes = (0, _extends2.default)({}, _themeListener.default.contextTypes, {\n muiThemeProviderOptions: _propTypes.default.object\n});\nMuiThemeProviderOld.contextTypes = (0, _extends2.default)({}, _themeListener.default.contextTypes, {\n muiThemeProviderOptions: _propTypes.default.object\n});\n/* istanbul ignore if */\n\nif (!_utils.ponyfillGlobal.__MUI_STYLES__) {\n _utils.ponyfillGlobal.__MUI_STYLES__ = {};\n}\n\nif (!_utils.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider) {\n _utils.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider = MuiThemeProviderOld;\n}\n\nvar _default = _utils.ponyfillGlobal.__MUI_STYLES__.MuiThemeProvider;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.convertHexToRGB = convertHexToRGB;\nexports.rgbToHex = rgbToHex;\nexports.decomposeColor = decomposeColor;\nexports.recomposeColor = recomposeColor;\nexports.getContrastRatio = getContrastRatio;\nexports.getLuminance = getLuminance;\nexports.emphasize = emphasize;\nexports.fade = fade;\nexports.darken = darken;\nexports.lighten = lighten;\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\n/* eslint-disable no-use-before-define */\n\n/**\r\n * Returns a number whose value is limited to the given range.\r\n *\r\n * @param {number} value The value to be clamped\r\n * @param {number} min The lower boundary of the output range\r\n * @param {number} max The upper boundary of the output range\r\n * @returns {number} A number in the range [min, max]\r\n */\nfunction clamp(value) {\n var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(value >= min && value <= max, \"Material-UI: the value provided \".concat(value, \" is out of range [\").concat(min, \", \").concat(max, \"].\")) : void 0;\n\n if (value < min) {\n return min;\n }\n\n if (value > max) {\n return max;\n }\n\n return value;\n}\n/**\r\n * Converts a color from CSS hex format to CSS rgb format.\r\n *\r\n * @param {string} color - Hex color, i.e. #nnn or #nnnnnn\r\n * @returns {string} A CSS rgb color string\r\n */\n\n\nfunction convertHexToRGB(color) {\n color = color.substr(1);\n var re = new RegExp(\".{1,\".concat(color.length / 3, \"}\"), 'g');\n var colors = color.match(re);\n\n if (colors && colors[0].length === 1) {\n colors = colors.map(function (n) {\n return n + n;\n });\n }\n\n return colors ? \"rgb(\".concat(colors.map(function (n) {\n return parseInt(n, 16);\n }).join(', '), \")\") : '';\n}\n/**\r\n * Converts a color from CSS rgb format to CSS hex format.\r\n *\r\n * @param {string} color - RGB color, i.e. rgb(n, n, n)\r\n * @returns {string} A CSS rgb color string, i.e. #nnnnnn\r\n */\n\n\nfunction rgbToHex(color) {\n // Pass hex straight through\n if (color.indexOf('#') === 0) {\n return color;\n }\n\n function intToHex(c) {\n var hex = c.toString(16);\n return hex.length === 1 ? \"0\".concat(hex) : hex;\n }\n\n var _decomposeColor = decomposeColor(color),\n values = _decomposeColor.values;\n\n values = values.map(function (n) {\n return intToHex(n);\n });\n return \"#\".concat(values.join(''));\n}\n/**\r\n * Returns an object with the type and values of a color.\r\n *\r\n * Note: Does not support rgb % values.\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @returns {object} - A MUI color object: {type: string, values: number[]}\r\n */\n\n\nfunction decomposeColor(color) {\n if (color.charAt(0) === '#') {\n return decomposeColor(convertHexToRGB(color));\n }\n\n var marker = color.indexOf('(');\n var type = color.substring(0, marker);\n var values = color.substring(marker + 1, color.length - 1).split(',');\n values = values.map(function (value) {\n return parseFloat(value);\n });\n\n if (process.env.NODE_ENV !== 'production') {\n if (['rgb', 'rgba', 'hsl', 'hsla'].indexOf(type) === -1) {\n throw new Error([\"Material-UI: unsupported `)) + (("`" + `\".concat(color, \"`) + ("`" + ` color.\"), 'We support the following formats: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla().'].join('\\n'));\n }\n }\n\n return {\n type: type,\n values: values\n };\n}\n/**\r\n * Converts a color object with type and values to a string.\r\n *\r\n * @param {object} color - Decomposed color\r\n * @param {string} color.type - One of: 'rgb', 'rgba', 'hsl', 'hsla'\r\n * @param {array} color.values - [n,n,n] or [n,n,n,n]\r\n * @returns {string} A CSS color string\r\n */\n\n\nfunction recomposeColor(color) {\n var type = color.type;\n var values = color.values;\n\n if (type.indexOf('rgb') !== -1) {\n // Only convert the first 3 values to int (i.e. not alpha)\n values = values.map(function (n, i) {\n return i < 3 ? parseInt(n, 10) : n;\n });\n }\n\n if (type.indexOf('hsl') !== -1) {\n values[1] = \"\".concat(values[1], \"%\");\n values[2] = \"\".concat(values[2], \"%\");\n }\n\n return \"\".concat(color.type, \"(\").concat(values.join(', '), \")\");\n}\n/**\r\n * Calculates the contrast ratio between two colors.\r\n *\r\n * Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests\r\n *\r\n * @param {string} foreground - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @param {string} background - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @returns {number} A contrast ratio value in the range 0 - 21.\r\n */\n\n\nfunction getContrastRatio(foreground, background) {\n var lumA = getLuminance(foreground);\n var lumB = getLuminance(background);\n return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);\n}\n/**\r\n * The relative brightness of any point in a color space,\r\n * normalized to 0 for darkest black and 1 for lightest white.\r\n *\r\n * Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @returns {number} The relative brightness of the color in the range 0 - 1\r\n */\n\n\nfunction getLuminance(color) {\n var decomposedColor = decomposeColor(color);\n\n if (decomposedColor.type.indexOf('rgb') !== -1) {\n var rgb = decomposedColor.values.map(function (val) {\n val /= 255; // normalized\n\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n }); // Truncate at 3 digits\n\n return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));\n } // else if (decomposedColor.type.indexOf('hsl') !== -1)\n\n\n return decomposedColor.values[2] / 100;\n}\n/**\r\n * Darken or lighten a colour, depending on its luminance.\r\n * Light colors are darkened, dark colors are lightened.\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @param {number} coefficient=0.15 - multiplier in the range 0 - 1\r\n * @returns {string} A CSS color string. Hex input values are returned as rgb\r\n */\n\n\nfunction emphasize(color) {\n var coefficient = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;\n return getLuminance(color) > 0.5 ? darken(color, coefficient) : lighten(color, coefficient);\n}\n/**\r\n * Set the absolute transparency of a color.\r\n * Any existing alpha values are overwritten.\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @param {number} value - value to set the alpha channel to in the range 0 -1\r\n * @returns {string} A CSS color string. Hex input values are returned as rgb\r\n */\n\n\nfunction fade(color, value) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(color, \"Material-UI: missing color argument in fade(\".concat(color, \", \").concat(value, \").\")) : void 0;\n if (!color) return color;\n color = decomposeColor(color);\n value = clamp(value);\n\n if (color.type === 'rgb' || color.type === 'hsl') {\n color.type += 'a';\n }\n\n color.values[3] = value;\n return recomposeColor(color);\n}\n/**\r\n * Darkens a color.\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @param {number} coefficient - multiplier in the range 0 - 1\r\n * @returns {string} A CSS color string. Hex input values are returned as rgb\r\n */\n\n\nfunction darken(color, coefficient) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(color, \"Material-UI: missing color argument in darken(\".concat(color, \", \").concat(coefficient, \").\")) : void 0;\n if (!color) return color;\n color = decomposeColor(color);\n coefficient = clamp(coefficient);\n\n if (color.type.indexOf('hsl') !== -1) {\n color.values[2] *= 1 - coefficient;\n } else if (color.type.indexOf('rgb') !== -1) {\n for (var i = 0; i < 3; i += 1) {\n color.values[i] *= 1 - coefficient;\n }\n }\n\n return recomposeColor(color);\n}\n/**\r\n * Lightens a color.\r\n *\r\n * @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()\r\n * @param {number} coefficient - multiplier in the range 0 - 1\r\n * @returns {string} A CSS color string. Hex input values are returned as rgb\r\n */\n\n\nfunction lighten(color, coefficient) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(color, \"Material-UI: missing color argument in lighten(\".concat(color, \", \").concat(coefficient, \").\")) : void 0;\n if (!color) return color;\n color = decomposeColor(color);\n coefficient = clamp(coefficient);\n\n if (color.type.indexOf('hsl') !== -1) {\n color.values[2] += (100 - color.values[2]) * coefficient;\n } else if (color.type.indexOf('rgb') !== -1) {\n for (var i = 0; i < 3; i += 1) {\n color.values[i] += (255 - color.values[i]) * coefficient;\n }\n }\n\n return recomposeColor(color);\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = createBreakpoints;\nexports.keys = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\n// Sorted ASC by size. That's important.\n// It can't be configured as it's used statically for propTypes.\nvar keys = ['xs', 'sm', 'md', 'lg', 'xl']; // Keep in mind that @media is inclusive by the CSS specification.\n\nexports.keys = keys;\n\nfunction createBreakpoints(breakpoints) {\n var _breakpoints$values = breakpoints.values,\n values = _breakpoints$values === void 0 ? {\n xs: 0,\n sm: 600,\n md: 960,\n lg: 1280,\n xl: 1920\n } : _breakpoints$values,\n _breakpoints$unit = breakpoints.unit,\n unit = _breakpoints$unit === void 0 ? 'px' : _breakpoints$unit,\n _breakpoints$step = breakpoints.step,\n step = _breakpoints$step === void 0 ? 5 : _breakpoints$step,\n other = (0, _objectWithoutProperties2.default)(breakpoints, [\"values\", \"unit\", \"step\"]);\n\n function up(key) {\n var value = typeof values[key] === 'number' ? values[key] : key;\n return \"@media (min-width:\".concat(value).concat(unit, \")\");\n }\n\n function down(key) {\n var endIndex = keys.indexOf(key) + 1;\n var upperbound = values[keys[endIndex]];\n\n if (endIndex === keys.length) {\n // xl down applies to all sizes\n return up('xs');\n }\n\n var value = typeof upperbound === 'number' && endIndex > 0 ? upperbound : key;\n return \"@media (max-width:\".concat(value - step / 100).concat(unit, \")\");\n }\n\n function between(start, end) {\n var endIndex = keys.indexOf(end) + 1;\n\n if (endIndex === keys.length) {\n return up(start);\n }\n\n return \"@media (min-width:\".concat(values[start]).concat(unit, \") and \") + \"(max-width:\".concat(values[keys[endIndex]] - step / 100).concat(unit, \")\");\n }\n\n function only(key) {\n return between(key, key);\n }\n\n function width(key) {\n return values[key];\n }\n\n return (0, _extends2.default)({\n keys: keys,\n values: values,\n up: up,\n down: down,\n between: between,\n only: only,\n width: width\n }, other);\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = createGenerateClassName;\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar escapeRegex = /([[\\].#*$><+~=|^:(),\"'`)))))) + ((((("`" + (`\\s])/g;\n\nfunction safePrefix(classNamePrefix) {\n var prefix = String(classNamePrefix);\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(prefix.length < 256, \"Material-UI: the class name prefix is too long: \".concat(prefix, \".\")) : void 0; // Sanitize the string as will be used to prefix the generated class name.\n\n return prefix.replace(escapeRegex, '-');\n} // Returns a function which generates unique class names based on counters.\n// When new generator function is created, rule counter is reset.\n// We need to reset the rule counter for SSR for each request.\n//\n// It's inspired by\n// https://github.com/cssinjs/jss/blob/4e6a05dd3f7b6572fdd3ab216861d9e446c20331/src/utils/createGenerateClassName.js\n\n\nfunction createGenerateClassName() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _options$dangerouslyU = options.dangerouslyUseGlobalCSS,\n dangerouslyUseGlobalCSS = _options$dangerouslyU === void 0 ? false : _options$dangerouslyU,\n _options$productionPr = options.productionPrefix,\n productionPrefix = _options$productionPr === void 0 ? 'jss' : _options$productionPr,\n _options$seed = options.seed,\n seed = _options$seed === void 0 ? '' : _options$seed;\n var ruleCounter = 0;\n return function (rule, styleSheet) {\n ruleCounter += 1;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(ruleCounter < 1e10, ['Material-UI: you might have a memory leak.', 'The ruleCounter is not supposed to grow that much.'].join('')) : void 0;\n\n if (dangerouslyUseGlobalCSS && styleSheet && styleSheet.options.name) {\n return \"\".concat(safePrefix(styleSheet.options.name), \"-\").concat(rule.key);\n }\n\n if (process.env.NODE_ENV === 'production') {\n return \"\".concat(productionPrefix).concat(seed).concat(ruleCounter);\n } // Help with debuggability.\n\n\n if (styleSheet && styleSheet.options.classNamePrefix) {\n return \"\".concat(safePrefix(styleSheet.options.classNamePrefix), \"-\").concat(rule.key, \"-\").concat(seed).concat(ruleCounter);\n }\n\n return \"\".concat(rule.key, \"-\").concat(seed).concat(ruleCounter);\n };\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = createMixins;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _extends3 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nfunction createMixins(breakpoints, spacing, mixins) {\n var _toolbar;\n\n return (0, _extends3.default)({\n gutters: function gutters() {\n var styles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return (0, _extends3.default)({\n paddingLeft: spacing.unit * 2,\n paddingRight: spacing.unit * 2\n }, styles, (0, _defineProperty2.default)({}, breakpoints.up('sm'), (0, _extends3.default)({\n paddingLeft: spacing.unit * 3,\n paddingRight: spacing.unit * 3\n }, styles[breakpoints.up('sm')])));\n },\n toolbar: (_toolbar = {\n minHeight: 56\n }, (0, _defineProperty2.default)(_toolbar, \"\".concat(breakpoints.up('xs'), \" and (orientation: landscape)\"), {\n minHeight: 48\n }), (0, _defineProperty2.default)(_toolbar, breakpoints.up('sm'), {\n minHeight: 64\n }), _toolbar)\n }, mixins);\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _deepmerge = _interopRequireDefault(require(\"deepmerge\"));\n\nvar _isPlainObject = _interopRequireDefault(require(\"is-plain-object\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _createBreakpoints = _interopRequireDefault(require(\"./createBreakpoints\"));\n\nvar _createMixins = _interopRequireDefault(require(\"./createMixins\"));\n\nvar _createPalette = _interopRequireDefault(require(\"./createPalette\"));\n\nvar _createTypography = _interopRequireDefault(require(\"./createTypography\"));\n\nvar _shadows = _interopRequireDefault(require(\"./shadows\"));\n\nvar _shape = _interopRequireDefault(require(\"./shape\"));\n\nvar _spacing = _interopRequireDefault(require(\"./spacing\"));\n\nvar _transitions = _interopRequireDefault(require(\"./transitions\"));\n\nvar _zIndex = _interopRequireDefault(require(\"./zIndex\"));\n\n// < 1kb payload overhead when lodash/merge is > 3kb.\nfunction createMuiTheme() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _options$breakpoints = options.breakpoints,\n breakpointsInput = _options$breakpoints === void 0 ? {} : _options$breakpoints,\n _options$mixins = options.mixins,\n mixinsInput = _options$mixins === void 0 ? {} : _options$mixins,\n _options$palette = options.palette,\n paletteInput = _options$palette === void 0 ? {} : _options$palette,\n shadowsInput = options.shadows,\n _options$spacing = options.spacing,\n spacingInput = _options$spacing === void 0 ? {} : _options$spacing,\n _options$typography = options.typography,\n typographyInput = _options$typography === void 0 ? {} : _options$typography,\n other = (0, _objectWithoutProperties2.default)(options, [\"breakpoints\", \"mixins\", \"palette\", \"shadows\", \"spacing\", \"typography\"]);\n var palette = (0, _createPalette.default)(paletteInput);\n var breakpoints = (0, _createBreakpoints.default)(breakpointsInput);\n var spacing = (0, _extends2.default)({}, _spacing.default, spacingInput);\n var muiTheme = (0, _extends2.default)({\n breakpoints: breakpoints,\n direction: 'ltr',\n mixins: (0, _createMixins.default)(breakpoints, spacing, mixinsInput),\n overrides: {},\n // Inject custom styles\n palette: palette,\n props: {},\n // Inject custom properties\n shadows: shadowsInput || _shadows.default,\n typography: (0, _createTypography.default)(palette, typographyInput)\n }, (0, _deepmerge.default)({\n shape: _shape.default,\n spacing: spacing,\n transitions: _transitions.default,\n zIndex: _zIndex.default\n }, other, {\n isMergeableObject: _isPlainObject.default\n }));\n\n if (process.env.NODE_ENV !== 'production') {\n var statesWarning = ['disabled', 'focused', 'selected', 'checked'];\n\n var traverse = function traverse(node, parentKey) {\n var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var key; // eslint-disable-next-line guard-for-in, no-restricted-syntax\n\n for (key in node) {\n var child = node[key];\n\n if (depth === 1) {\n if (key.indexOf('Mui') === 0 && child) {\n traverse(child, key, depth + 1);\n }\n } else if (statesWarning.indexOf(key) !== -1 && Object.keys(child).length > 0) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(false, [\"Material-UI: the ` + "`")) + (`\".concat(parentKey, \"` + ("`" + ` component increases \") + \"the CSS specificity of the `))) + (("`" + (`\".concat(key, \"` + "`")) + (` internal state.\"), 'You can not override it like this: ', JSON.stringify(node, null, 2), '', 'Instead, you need to use the $ruleName syntax:', JSON.stringify((0, _defineProperty2.default)({}, \"&$\".concat(key), child), null, 2), '', 'https://material-ui.com/customization/overrides#internal-states'].join('\\n')) : void 0;\n }\n }\n };\n\n traverse(other.overrides);\n }\n\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(muiTheme.shadows.length === 25, 'Material-UI: the shadows array provided to createMuiTheme should support 25 elevations.') : void 0;\n return muiTheme;\n}\n\nvar _default = createMuiTheme;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = createPalette;\nexports.dark = exports.light = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _deepmerge = _interopRequireDefault(require(\"deepmerge\"));\n\nvar _indigo = _interopRequireDefault(require(\"../colors/indigo\"));\n\nvar _pink = _interopRequireDefault(require(\"../colors/pink\"));\n\nvar _grey = _interopRequireDefault(require(\"../colors/grey\"));\n\nvar _red = _interopRequireDefault(require(\"../colors/red\"));\n\nvar _common = _interopRequireDefault(require(\"../colors/common\"));\n\nvar _colorManipulator = require(\"./colorManipulator\");\n\n// < 1kb payload overhead when lodash/merge is > 3kb.\nvar light = {\n // The colors used to style the text.\n text: {\n // The most important text.\n primary: 'rgba(0, 0, 0, 0.87)',\n // Secondary text.\n secondary: 'rgba(0, 0, 0, 0.54)',\n // Disabled text have even lower visual prominence.\n disabled: 'rgba(0, 0, 0, 0.38)',\n // Text hints.\n hint: 'rgba(0, 0, 0, 0.38)'\n },\n // The color used to divide different elements.\n divider: 'rgba(0, 0, 0, 0.12)',\n // The background colors used to style the surfaces.\n // Consistency between these values is important.\n background: {\n paper: _common.default.white,\n default: _grey.default[50]\n },\n // The colors used to style the action elements.\n action: {\n // The color of an active action like an icon button.\n active: 'rgba(0, 0, 0, 0.54)',\n // The color of an hovered action.\n hover: 'rgba(0, 0, 0, 0.08)',\n hoverOpacity: 0.08,\n // The color of a selected action.\n selected: 'rgba(0, 0, 0, 0.14)',\n // The color of a disabled action.\n disabled: 'rgba(0, 0, 0, 0.26)',\n // The background color of a disabled action.\n disabledBackground: 'rgba(0, 0, 0, 0.12)'\n }\n};\nexports.light = light;\nvar dark = {\n text: {\n primary: _common.default.white,\n secondary: 'rgba(255, 255, 255, 0.7)',\n disabled: 'rgba(255, 255, 255, 0.5)',\n hint: 'rgba(255, 255, 255, 0.5)',\n icon: 'rgba(255, 255, 255, 0.5)'\n },\n divider: 'rgba(255, 255, 255, 0.12)',\n background: {\n paper: _grey.default[800],\n default: '#303030'\n },\n action: {\n active: _common.default.white,\n hover: 'rgba(255, 255, 255, 0.1)',\n hoverOpacity: 0.1,\n selected: 'rgba(255, 255, 255, 0.2)',\n disabled: 'rgba(255, 255, 255, 0.3)',\n disabledBackground: 'rgba(255, 255, 255, 0.12)'\n }\n};\nexports.dark = dark;\n\nfunction addLightOrDark(intent, direction, shade, tonalOffset) {\n if (!intent[direction]) {\n if (intent.hasOwnProperty(shade)) {\n intent[direction] = intent[shade];\n } else if (direction === 'light') {\n intent.light = (0, _colorManipulator.lighten)(intent.main, tonalOffset);\n } else if (direction === 'dark') {\n intent.dark = (0, _colorManipulator.darken)(intent.main, tonalOffset * 1.5);\n }\n }\n}\n\nfunction createPalette(palette) {\n var _palette$primary = palette.primary,\n primary = _palette$primary === void 0 ? {\n light: _indigo.default[300],\n main: _indigo.default[500],\n dark: _indigo.default[700]\n } : _palette$primary,\n _palette$secondary = palette.secondary,\n secondary = _palette$secondary === void 0 ? {\n light: _pink.default.A200,\n main: _pink.default.A400,\n dark: _pink.default.A700\n } : _palette$secondary,\n _palette$error = palette.error,\n error = _palette$error === void 0 ? {\n light: _red.default[300],\n main: _red.default[500],\n dark: _red.default[700]\n } : _palette$error,\n _palette$type = palette.type,\n type = _palette$type === void 0 ? 'light' : _palette$type,\n _palette$contrastThre = palette.contrastThreshold,\n contrastThreshold = _palette$contrastThre === void 0 ? 3 : _palette$contrastThre,\n _palette$tonalOffset = palette.tonalOffset,\n tonalOffset = _palette$tonalOffset === void 0 ? 0.2 : _palette$tonalOffset,\n other = (0, _objectWithoutProperties2.default)(palette, [\"primary\", \"secondary\", \"error\", \"type\", \"contrastThreshold\", \"tonalOffset\"]);\n\n function getContrastText(background) {\n // Use the same logic as\n // Bootstrap: https://github.com/twbs/bootstrap/blob/1d6e3710dd447de1a200f29e8fa521f8a0908f70/scss/_functions.scss#L59\n // and material-components-web https://github.com/material-components/material-components-web/blob/ac46b8863c4dab9fc22c4c662dc6bd1b65dd652f/packages/mdc-theme/_functions.scss#L54\n var contrastText = (0, _colorManipulator.getContrastRatio)(background, dark.text.primary) >= contrastThreshold ? dark.text.primary : light.text.primary;\n\n if (process.env.NODE_ENV !== 'production') {\n var contrast = (0, _colorManipulator.getContrastRatio)(background, contrastText);\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(contrast >= 3, [\"Material-UI: the contrast ratio of \".concat(contrast, \":1 for \").concat(contrastText, \" on \").concat(background), 'falls below the WACG recommended absolute minimum contrast ratio of 3:1.', 'https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast-contrast'].join('\\n')) : void 0;\n }\n\n return contrastText;\n }\n\n function augmentColor(color) {\n var mainShade = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 500;\n var lightShade = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 300;\n var darkShade = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 700;\n\n if (!color.main && color[mainShade]) {\n color.main = color[mainShade];\n }\n\n if (process.env.NODE_ENV !== 'production' && !color.main) {\n throw new Error(['Material-UI: the color provided to augmentColor(color) is invalid.', \"The color object needs to have a ` + ("`" + `main`)))) + ((("`" + (` property or a ` + "`")) + (`\".concat(mainShade, \"` + ("`" + ` property.\")].join('\\n'));\n }\n\n addLightOrDark(color, 'light', lightShade, tonalOffset);\n addLightOrDark(color, 'dark', darkShade, tonalOffset);\n\n if (!color.contrastText) {\n color.contrastText = getContrastText(color.main);\n }\n\n return color;\n }\n\n augmentColor(primary);\n augmentColor(secondary, 'A400', 'A200', 'A700');\n augmentColor(error);\n var types = {\n dark: dark,\n light: light\n };\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(types[type], \"Material-UI: the palette type `))) + (("`" + (`\".concat(type, \"` + "`")) + ((` is not supported.\")) : void 0;\n var paletteOutput = (0, _deepmerge.default)((0, _extends2.default)({\n // A collection of common colors.\n common: _common.default,\n // The palette type, can be light or dark.\n type: type,\n // The colors used to represent primary interface elements for a user.\n primary: primary,\n // The colors used to represent secondary interface elements for a user.\n secondary: secondary,\n // The colors used to represent interface elements that the user should be made aware of.\n error: error,\n // The grey colors.\n grey: _grey.default,\n // Used by ` + "`") + (`getContrastText()` + "`"))))) + ((((` to maximize the contrast between the background and\n // the text.\n contrastThreshold: contrastThreshold,\n // Take a background color and return the color of the text to maximize the contrast.\n getContrastText: getContrastText,\n // Generate a rich color object.\n augmentColor: augmentColor,\n // Used by the functions below to shift a color's luminance by approximately\n // two indexes within its tonal palette.\n // E.g., shift from Red 500 to Red 300 or Red 700.\n tonalOffset: tonalOffset\n }, types[type]), other, {\n clone: false // No need to clone deep\n\n });\n return paletteOutput;\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = createTypography;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _deepmerge = _interopRequireDefault(require(\"deepmerge\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\n// < 1kb payload overhead when lodash/merge is > 3kb.\nfunction round(value) {\n return Math.round(value * 1e5) / 1e5;\n}\n\nvar caseAllCaps = {\n textTransform: 'uppercase'\n};\nvar defaultFontFamily = '\"Roboto\", \"Helvetica\", \"Arial\", sans-serif';\n/**\r\n * @see @link{https://material.io/design/typography/the-type-system.html}\r\n * @see @link{https://material.io/design/typography/understanding-typography.html}\r\n */\n\nfunction createTypography(palette, typography) {\n var _ref = typeof typography === 'function' ? typography(palette) : typography,\n _ref$fontFamily = _ref.fontFamily,\n fontFamily = _ref$fontFamily === void 0 ? defaultFontFamily : _ref$fontFamily,\n _ref$fontSize = _ref.fontSize,\n fontSize = _ref$fontSize === void 0 ? 14 : _ref$fontSize,\n _ref$fontWeightLight = _ref.fontWeightLight,\n fontWeightLight = _ref$fontWeightLight === void 0 ? 300 : _ref$fontWeightLight,\n _ref$fontWeightRegula = _ref.fontWeightRegular,\n fontWeightRegular = _ref$fontWeightRegula === void 0 ? 400 : _ref$fontWeightRegula,\n _ref$fontWeightMedium = _ref.fontWeightMedium,\n fontWeightMedium = _ref$fontWeightMedium === void 0 ? 500 : _ref$fontWeightMedium,\n _ref$htmlFontSize = _ref.htmlFontSize,\n htmlFontSize = _ref$htmlFontSize === void 0 ? 16 : _ref$htmlFontSize,\n _ref$useNextVariants = _ref.useNextVariants,\n useNextVariants = _ref$useNextVariants === void 0 ? Boolean(_utils.ponyfillGlobal.__MUI_USE_NEXT_TYPOGRAPHY_VARIANTS__) : _ref$useNextVariants,\n _ref$suppressWarning = _ref.suppressWarning,\n suppressWarning = _ref$suppressWarning === void 0 ? false : _ref$suppressWarning,\n allVariants = _ref.allVariants,\n other = (0, _objectWithoutProperties2.default)(_ref, [\"fontFamily\", \"fontSize\", \"fontWeightLight\", \"fontWeightRegular\", \"fontWeightMedium\", \"htmlFontSize\", \"useNextVariants\", \"suppressWarning\", \"allVariants\"]);\n\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(useNextVariants || suppressWarning, 'Material-UI: you are using the deprecated typography variants ' + 'that will be removed in the next major release.' + '\\nPlease read the migration guide under https://material-ui.com/style/typography#migration-to-typography-v2') : void 0;\n var coef = fontSize / 14;\n\n var pxToRem = function pxToRem(size) {\n return \"\".concat(size / htmlFontSize * coef, \"rem\");\n };\n\n var buildVariant = function buildVariant(fontWeight, size, lineHeight, letterSpacing, casing) {\n return (0, _extends2.default)({\n color: palette.text.primary,\n fontFamily: fontFamily,\n fontWeight: fontWeight,\n fontSize: pxToRem(size),\n // Unitless following http://meyerweb.com/eric/thoughts/2006/02/08/unitless-line-heights/\n lineHeight: lineHeight\n }, fontFamily === defaultFontFamily ? {\n letterSpacing: \"\".concat(round(letterSpacing / size), \"em\")\n } : {}, casing, allVariants);\n };\n\n var nextVariants = {\n h1: buildVariant(fontWeightLight, 96, 1, -1.5),\n h2: buildVariant(fontWeightLight, 60, 1, -0.5),\n h3: buildVariant(fontWeightRegular, 48, 1.04, 0),\n h4: buildVariant(fontWeightRegular, 34, 1.17, 0.25),\n h5: buildVariant(fontWeightRegular, 24, 1.33, 0),\n h6: buildVariant(fontWeightMedium, 20, 1.6, 0.15),\n subtitle1: buildVariant(fontWeightRegular, 16, 1.75, 0.15),\n subtitle2: buildVariant(fontWeightMedium, 14, 1.57, 0.1),\n body1Next: buildVariant(fontWeightRegular, 16, 1.5, 0.15),\n body2Next: buildVariant(fontWeightRegular, 14, 1.5, 0.15),\n buttonNext: buildVariant(fontWeightMedium, 14, 1.75, 0.4, caseAllCaps),\n captionNext: buildVariant(fontWeightRegular, 12, 1.66, 0.4),\n overline: buildVariant(fontWeightRegular, 12, 2.66, 1, caseAllCaps)\n }; // To remove in v4\n\n var oldVariants = {\n display4: (0, _extends2.default)({\n fontSize: pxToRem(112),\n fontWeight: fontWeightLight,\n fontFamily: fontFamily,\n letterSpacing: '-.04em',\n lineHeight: \"\".concat(round(128 / 112), \"em\"),\n marginLeft: '-.04em',\n color: palette.text.secondary\n }, allVariants),\n display3: (0, _extends2.default)({\n fontSize: pxToRem(56),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n letterSpacing: '-.02em',\n lineHeight: \"\".concat(round(73 / 56), \"em\"),\n marginLeft: '-.02em',\n color: palette.text.secondary\n }, allVariants),\n display2: (0, _extends2.default)({\n fontSize: pxToRem(45),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(51 / 45), \"em\"),\n marginLeft: '-.02em',\n color: palette.text.secondary\n }, allVariants),\n display1: (0, _extends2.default)({\n fontSize: pxToRem(34),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(41 / 34), \"em\"),\n color: palette.text.secondary\n }, allVariants),\n headline: (0, _extends2.default)({\n fontSize: pxToRem(24),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(32.5 / 24), \"em\"),\n color: palette.text.primary\n }, allVariants),\n title: (0, _extends2.default)({\n fontSize: pxToRem(21),\n fontWeight: fontWeightMedium,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(24.5 / 21), \"em\"),\n color: palette.text.primary\n }, allVariants),\n subheading: (0, _extends2.default)({\n fontSize: pxToRem(16),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(24 / 16), \"em\"),\n color: palette.text.primary\n }, allVariants),\n body2: (0, _extends2.default)({\n fontSize: pxToRem(14),\n fontWeight: fontWeightMedium,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(24 / 14), \"em\"),\n color: palette.text.primary\n }, allVariants),\n body1: (0, _extends2.default)({\n fontSize: pxToRem(14),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(20.5 / 14), \"em\"),\n color: palette.text.primary\n }, allVariants),\n caption: (0, _extends2.default)({\n fontSize: pxToRem(12),\n fontWeight: fontWeightRegular,\n fontFamily: fontFamily,\n lineHeight: \"\".concat(round(16.5 / 12), \"em\"),\n color: palette.text.secondary\n }, allVariants),\n button: (0, _extends2.default)({\n fontSize: pxToRem(14),\n textTransform: 'uppercase',\n fontWeight: fontWeightMedium,\n fontFamily: fontFamily,\n color: palette.text.primary\n }, allVariants)\n };\n return (0, _deepmerge.default)((0, _extends2.default)({\n pxToRem: pxToRem,\n round: round,\n fontFamily: fontFamily,\n fontSize: fontSize,\n fontWeightLight: fontWeightLight,\n fontWeightRegular: fontWeightRegular,\n fontWeightMedium: fontWeightMedium\n }, oldVariants, nextVariants, useNextVariants ? {\n body1: nextVariants.body1Next,\n body2: nextVariants.body2Next,\n button: nextVariants.buttonNext,\n caption: nextVariants.captionNext\n } : {}, {\n useNextVariants: useNextVariants\n }), other, {\n clone: false // No need to clone deep\n\n });\n}", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _typeof2 = _interopRequireDefault(require(\"@babel/runtime/helpers/typeof\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _deepmerge = _interopRequireDefault(require(\"deepmerge\"));\n\n// < 1kb payload overhead when lodash/merge is > 3kb.\n// Support for the jss-expand plugin.\nfunction arrayMerge(destination, source) {\n return source;\n}\n\nfunction getStylesCreator(stylesOrCreator) {\n var themingEnabled = typeof stylesOrCreator === 'function';\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)((0, _typeof2.default)(stylesOrCreator) === 'object' || themingEnabled, ['Material-UI: the first argument provided to withStyles() is invalid.', 'You need to provide a function generating the styles or a styles object.'].join('\\n')) : void 0;\n\n function create(theme, name) {\n var styles = themingEnabled ? stylesOrCreator(theme) : stylesOrCreator;\n\n if (!name || !theme.overrides || !theme.overrides[name]) {\n return styles;\n }\n\n var overrides = theme.overrides[name];\n var stylesWithOverrides = (0, _extends2.default)({}, styles);\n Object.keys(overrides).forEach(function (key) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(stylesWithOverrides[key], ['Material-UI: you are trying to override a style that does not exist.', \"Fix the ` + ("`" + `\".concat(key, \"`)) + ("`" + (` key of ` + "`"))) + ((`theme.overrides.\").concat(name, \"` + ("`" + `.\")].join('\\n')) : void 0;\n stylesWithOverrides[key] = (0, _deepmerge.default)(stylesWithOverrides[key], overrides[key], {\n arrayMerge: arrayMerge\n });\n });\n return stylesWithOverrides;\n }\n\n return {\n create: create,\n options: {},\n themingEnabled: themingEnabled\n };\n}\n\nvar _default = getStylesCreator;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n/* eslint-disable no-restricted-syntax */\nfunction getThemeProps(params) {\n var theme = params.theme,\n name = params.name,\n props = params.props;\n\n if (!theme.props || !name || !theme.props[name]) {\n return props;\n } // Resolve default props, code borrow from React source.\n // https://github.com/facebook/react/blob/15a8f031838a553e41c0b66eb1bcf1da8448104d/packages/react/src/ReactElement.js#L221\n\n\n var defaultProps = theme.props[name];\n var propName;\n\n for (propName in defaultProps) {\n if (props[propName] === undefined) {\n props[propName] = defaultProps[propName];\n }\n }\n\n return props;\n}\n\nvar _default = getThemeProps;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _jssGlobal = _interopRequireDefault(require(\"jss-global\"));\n\nvar _jssNested = _interopRequireDefault(require(\"jss-nested\"));\n\nvar _jssCamelCase = _interopRequireDefault(require(\"jss-camel-case\"));\n\nvar _jssDefaultUnit = _interopRequireDefault(require(\"jss-default-unit\"));\n\nvar _jssVendorPrefixer = _interopRequireDefault(require(\"jss-vendor-prefixer\"));\n\nvar _jssPropsSort = _interopRequireDefault(require(\"jss-props-sort\"));\n\n// Subset of jss-preset-default with only the plugins the Material-UI components are using.\nfunction jssPreset() {\n return {\n plugins: [(0, _jssGlobal.default)(), (0, _jssNested.default)(), (0, _jssCamelCase.default)(), (0, _jssDefaultUnit.default)(), // Disable the vendor prefixer server-side, it does nothing.\n // This way, we can get a performance boost.\n // In the documentation, we are using `)) + ("`" + (`autoprefixer` + "`")))) + (((` to solve this problem.\n typeof window === 'undefined' ? null : (0, _jssVendorPrefixer.default)(), (0, _jssPropsSort.default)()]\n };\n}\n\nvar _default = jssPreset;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _extends2 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nfunction mergeClasses() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var baseClasses = options.baseClasses,\n newClasses = options.newClasses,\n Component = options.Component;\n\n if (!newClasses) {\n return baseClasses;\n }\n\n var nextClasses = (0, _extends2.default)({}, baseClasses);\n\n if (process.env.NODE_ENV !== 'production' && typeof newClasses === 'string') {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(false, [\"Material-UI: the value ` + ("`" + `\".concat(newClasses, \"`)) + ("`" + (` \") + \"provided to the classes property of \".concat((0, _utils.getDisplayName)(Component), \" is incorrect.\"), 'You might want to use the className property instead.'].join('\\n')) : void 0;\n return baseClasses;\n }\n\n Object.keys(newClasses).forEach(function (key) {\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(baseClasses[key] || !newClasses[key], [\"Material-UI: the key ` + "`"))) + ((`\".concat(key, \"` + ("`" + ` \") + \"provided to the classes property is not implemented in \".concat((0, _utils.getDisplayName)(Component), \".\"), \"You can only override one of the following: \".concat(Object.keys(baseClasses).join(','), \".\")].join('\\n')) : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(!newClasses[key] || typeof newClasses[key] === 'string', [\"Material-UI: the key `)) + (("`" + `\".concat(key, \"`) + ("`" + ` \") + \"provided to the classes property is not valid for \".concat((0, _utils.getDisplayName)(Component), \".\"), \"You need to provide a non empty string instead of: \".concat(newClasses[key], \".\")].join('\\n')) : void 0;\n\n if (newClasses[key]) {\n nextClasses[key] = \"\".concat(baseClasses[key], \" \").concat(newClasses[key]);\n }\n });\n return nextClasses;\n}\n\nvar _default = mergeClasses;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n// Used https://github.com/thinkloop/multi-key-cache as inspiration\nvar multiKeyStore = {\n set: function set(cache, key1, key2, value) {\n var subCache = cache.get(key1);\n\n if (!subCache) {\n subCache = new Map();\n cache.set(key1, subCache);\n }\n\n subCache.set(key2, value);\n },\n get: function get(cache, key1, key2) {\n var subCache = cache.get(key1);\n return subCache ? subCache.get(key2) : undefined;\n },\n delete: function _delete(cache, key1, key2) {\n var subCache = cache.get(key1);\n subCache.delete(key2);\n }\n};\nvar _default = multiKeyStore;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n// Share the same values than in\n// https://github.com/cssinjs/jss/blob/master/packages/react-jss/src/ns.js\nvar ns = {\n jss: '64a55d578f856d258dc345b094a2a2b3',\n sheetsRegistry: 'd4bd0baacbc52bbd48bbb9eb24344ecd',\n sheetOptions: '6fc570d6bd61383819d0f9e7407c452d'\n};\nvar _default = ns;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar shadowKeyUmbraOpacity = 0.2;\nvar shadowKeyPenumbraOpacity = 0.14;\nvar shadowAmbientShadowOpacity = 0.12;\n\nfunction createShadow() {\n return [\"\".concat(arguments.length <= 0 ? undefined : arguments[0], \"px \").concat(arguments.length <= 1 ? undefined : arguments[1], \"px \").concat(arguments.length <= 2 ? undefined : arguments[2], \"px \").concat(arguments.length <= 3 ? undefined : arguments[3], \"px rgba(0,0,0,\").concat(shadowKeyUmbraOpacity, \")\"), \"\".concat(arguments.length <= 4 ? undefined : arguments[4], \"px \").concat(arguments.length <= 5 ? undefined : arguments[5], \"px \").concat(arguments.length <= 6 ? undefined : arguments[6], \"px \").concat(arguments.length <= 7 ? undefined : arguments[7], \"px rgba(0,0,0,\").concat(shadowKeyPenumbraOpacity, \")\"), \"\".concat(arguments.length <= 8 ? undefined : arguments[8], \"px \").concat(arguments.length <= 9 ? undefined : arguments[9], \"px \").concat(arguments.length <= 10 ? undefined : arguments[10], \"px \").concat(arguments.length <= 11 ? undefined : arguments[11], \"px rgba(0,0,0,\").concat(shadowAmbientShadowOpacity, \")\")].join(',');\n}\n\nvar shadows = ['none', createShadow(0, 1, 3, 0, 0, 1, 1, 0, 0, 2, 1, -1), createShadow(0, 1, 5, 0, 0, 2, 2, 0, 0, 3, 1, -2), createShadow(0, 1, 8, 0, 0, 3, 4, 0, 0, 3, 3, -2), createShadow(0, 2, 4, -1, 0, 4, 5, 0, 0, 1, 10, 0), createShadow(0, 3, 5, -1, 0, 5, 8, 0, 0, 1, 14, 0), createShadow(0, 3, 5, -1, 0, 6, 10, 0, 0, 1, 18, 0), createShadow(0, 4, 5, -2, 0, 7, 10, 1, 0, 2, 16, 1), createShadow(0, 5, 5, -3, 0, 8, 10, 1, 0, 3, 14, 2), createShadow(0, 5, 6, -3, 0, 9, 12, 1, 0, 3, 16, 2), createShadow(0, 6, 6, -3, 0, 10, 14, 1, 0, 4, 18, 3), createShadow(0, 6, 7, -4, 0, 11, 15, 1, 0, 4, 20, 3), createShadow(0, 7, 8, -4, 0, 12, 17, 2, 0, 5, 22, 4), createShadow(0, 7, 8, -4, 0, 13, 19, 2, 0, 5, 24, 4), createShadow(0, 7, 9, -4, 0, 14, 21, 2, 0, 5, 26, 4), createShadow(0, 8, 9, -5, 0, 15, 22, 2, 0, 6, 28, 5), createShadow(0, 8, 10, -5, 0, 16, 24, 2, 0, 6, 30, 5), createShadow(0, 8, 11, -5, 0, 17, 26, 2, 0, 6, 32, 5), createShadow(0, 9, 11, -5, 0, 18, 28, 2, 0, 7, 34, 6), createShadow(0, 9, 12, -6, 0, 19, 29, 2, 0, 7, 36, 6), createShadow(0, 10, 13, -6, 0, 20, 31, 3, 0, 8, 38, 7), createShadow(0, 10, 13, -6, 0, 21, 33, 3, 0, 8, 40, 7), createShadow(0, 10, 14, -6, 0, 22, 35, 3, 0, 8, 42, 7), createShadow(0, 11, 14, -7, 0, 23, 36, 3, 0, 9, 44, 8), createShadow(0, 11, 15, -7, 0, 24, 38, 3, 0, 9, 46, 8)];\nvar _default = shadows;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar shape = {\n borderRadius: 4\n};\nvar _default = shape;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar spacing = {\n // All components align to an 8dp square baseline grid for mobile, tablet, and desktop.\n // https://material.io/design/layout/understanding-layout.html#pixel-density\n unit: 8\n};\nvar _default = spacing;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.CHANNEL = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\n// Same value used by react-jss\nvar CHANNEL = '__THEMING__';\nexports.CHANNEL = CHANNEL;\nvar themeListener = {\n contextTypes: (0, _defineProperty2.default)({}, CHANNEL, function () {}),\n initial: function initial(context) {\n if (!context[CHANNEL]) {\n return null;\n }\n\n return context[CHANNEL].getState();\n },\n subscribe: function subscribe(context, cb) {\n if (!context[CHANNEL]) {\n return null;\n }\n\n return context[CHANNEL].subscribe(cb);\n },\n unsubscribe: function unsubscribe(context, subscriptionId) {\n if (context[CHANNEL]) {\n context[CHANNEL].unsubscribe(subscriptionId);\n }\n }\n};\nvar _default = themeListener;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.isNumber = exports.isString = exports.formatMs = exports.duration = exports.easing = void 0;\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\n/* eslint-disable no-restricted-globals */\n// Follow https://material.google.com/motion/duration-easing.html#duration-easing-natural-easing-curves\n// to learn the context in which each easing should be used.\nvar easing = {\n // This is the most common easing curve.\n easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)',\n // Objects enter the screen at full velocity from off-screen and\n // slowly decelerate to a resting point.\n easeOut: 'cubic-bezier(0.0, 0, 0.2, 1)',\n // Objects leave the screen at full velocity. They do not decelerate when off-screen.\n easeIn: 'cubic-bezier(0.4, 0, 1, 1)',\n // The sharp curve is used by objects that may return to the screen at any time.\n sharp: 'cubic-bezier(0.4, 0, 0.6, 1)'\n}; // Follow https://material.io/guidelines/motion/duration-easing.html#duration-easing-common-durations\n// to learn when use what timing\n\nexports.easing = easing;\nvar duration = {\n shortest: 150,\n shorter: 200,\n short: 250,\n // most basic recommended timing\n standard: 300,\n // this is to be used in complex animations\n complex: 375,\n // recommended when something is entering screen\n enteringScreen: 225,\n // recommended when something is leaving screen\n leavingScreen: 195\n};\nexports.duration = duration;\n\nvar formatMs = function formatMs(milliseconds) {\n return \"\".concat(Math.round(milliseconds), \"ms\");\n};\n\nexports.formatMs = formatMs;\n\nvar isString = function isString(value) {\n return typeof value === 'string';\n};\n\nexports.isString = isString;\n\nvar isNumber = function isNumber(value) {\n return !isNaN(parseFloat(value));\n};\n/**\r\n * @param {string|Array} props\r\n * @param {object} param\r\n * @param {string} param.prop\r\n * @param {number} param.duration\r\n * @param {string} param.easing\r\n * @param {number} param.delay\r\n */\n\n\nexports.isNumber = isNumber;\nvar _default = {\n easing: easing,\n duration: duration,\n create: function create() {\n var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['all'];\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var _options$duration = options.duration,\n durationOption = _options$duration === void 0 ? duration.standard : _options$duration,\n _options$easing = options.easing,\n easingOption = _options$easing === void 0 ? easing.easeInOut : _options$easing,\n _options$delay = options.delay,\n delay = _options$delay === void 0 ? 0 : _options$delay,\n other = (0, _objectWithoutProperties2.default)(options, [\"duration\", \"easing\", \"delay\"]);\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(isString(props) || Array.isArray(props), 'Material-UI: argument \"props\" must be a string or Array.') : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(isNumber(durationOption) || isString(durationOption), \"Material-UI: argument \\\"duration\\\" must be a number or a string but found \".concat(durationOption, \".\")) : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(isString(easingOption), 'Material-UI: argument \"easing\" must be a string.') : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(isNumber(delay) || isString(delay), 'Material-UI: argument \"delay\" must be a number or a string.') : void 0;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(Object.keys(other).length === 0, \"Material-UI: unrecognized argument(s) [\".concat(Object.keys(other).join(','), \"]\")) : void 0;\n return (Array.isArray(props) ? props : [props]).map(function (animatedProp) {\n return \"\".concat(animatedProp, \" \").concat(typeof durationOption === 'string' ? durationOption : formatMs(durationOption), \" \").concat(easingOption, \" \").concat(typeof delay === 'string' ? delay : formatMs(delay));\n }).join(',');\n },\n getAutoHeightDuration: function getAutoHeightDuration(height) {\n if (!height) {\n return 0;\n }\n\n var constant = height / 36; // https://www.wolframalpha.com/input/?i=(4+%2B+15+*+(x+%2F+36+)+**+0.25+%2B+(x+%2F+36)+%2F+5)+*+10\n\n return Math.round((4 + 15 * Math.pow(constant, 0.25) + constant / 5) * 10);\n }\n};\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.sheetsManager = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _extends3 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\nvar _classCallCheck2 = _interopRequireDefault(require(\"@babel/runtime/helpers/classCallCheck\"));\n\nvar _createClass2 = _interopRequireDefault(require(\"@babel/runtime/helpers/createClass\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(require(\"@babel/runtime/helpers/possibleConstructorReturn\"));\n\nvar _getPrototypeOf2 = _interopRequireDefault(require(\"@babel/runtime/helpers/getPrototypeOf\"));\n\nvar _inherits2 = _interopRequireDefault(require(\"@babel/runtime/helpers/inherits\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(require(\"@babel/runtime/helpers/objectWithoutProperties\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\nvar _hoistNonReactStatics = _interopRequireDefault(require(\"hoist-non-react-statics\"));\n\nvar _utils = require(\"@material-ui/utils\");\n\nvar _jss = require(\"jss\");\n\nvar _reactJssContext = _interopRequireDefault(require(\"./reactJssContext\"));\n\nvar _jssPreset = _interopRequireDefault(require(\"./jssPreset\"));\n\nvar _mergeClasses = _interopRequireDefault(require(\"./mergeClasses\"));\n\nvar _multiKeyStore = _interopRequireDefault(require(\"./multiKeyStore\"));\n\nvar _createMuiTheme = _interopRequireDefault(require(\"./createMuiTheme\"));\n\nvar _themeListener = _interopRequireDefault(require(\"./themeListener\"));\n\nvar _createGenerateClassName = _interopRequireDefault(require(\"./createGenerateClassName\"));\n\nvar _getStylesCreator = _interopRequireDefault(require(\"./getStylesCreator\"));\n\nvar _getThemeProps = _interopRequireDefault(require(\"./getThemeProps\"));\n\n/* eslint-disable no-underscore-dangle */\n// Default JSS instance.\nvar jss = (0, _jss.create)((0, _jssPreset.default)()); // Use a singleton or the provided one by the context.\n//\n// The counter-based approach doesn't tolerate any mistake.\n// It's much safer to use the same counter everywhere.\n\nvar generateClassName = (0, _createGenerateClassName.default)(); // Global index counter to preserve source order.\n// We create the style sheet during at the creation of the component,\n// children are handled after the parents, so the order of style elements would be parent->child.\n// It is a problem though when a parent passes a className\n// which needs to override any child's styles.\n// StyleSheet of the child has a higher specificity, because of the source order.\n// So our solution is to render sheets them in the reverse order child->sheet, so\n// that parent has a higher specificity.\n\nvar indexCounter = -10e10; // Exported for test purposes\n\nvar sheetsManager = new Map(); // We use the same empty object to ref count the styles that don't need a theme object.\n\nexports.sheetsManager = sheetsManager;\nvar noopTheme = {}; // In order to have self-supporting components, we rely on default theme when not provided.\n\nvar defaultTheme = (0, _createMuiTheme.default)({\n typography: {\n suppressWarning: true\n }\n}); // Link a style sheet with a component.\n// It does not modify the component passed to it;\n// instead, it returns a new component, with a `))))))))))) + (((((((((("`" + (`classes` + "`")) + (` property.\n\nvar withStylesOld = function withStylesOld(stylesOrCreator) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n return function (Component) {\n var _extends2;\n\n var _options$withTheme = options.withTheme,\n withTheme = _options$withTheme === void 0 ? false : _options$withTheme,\n _options$flip = options.flip,\n flip = _options$flip === void 0 ? null : _options$flip,\n name = options.name,\n styleSheetOptions = (0, _objectWithoutProperties2.default)(options, [\"withTheme\", \"flip\", \"name\"]);\n var stylesCreator = (0, _getStylesCreator.default)(stylesOrCreator);\n var listenToTheme = stylesCreator.themingEnabled || typeof name === 'string' || withTheme;\n indexCounter += 1;\n stylesCreator.options.index = indexCounter;\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(indexCounter < 0, ['Material-UI: you might have a memory leak.', 'The indexCounter is not supposed to grow that much.'].join('\\n')) : void 0;\n\n var WithStyles =\n /*#__PURE__*/\n function (_React$Component) {\n (0, _inherits2.default)(WithStyles, _React$Component);\n\n function WithStyles(props, context) {\n var _this;\n\n (0, _classCallCheck2.default)(this, WithStyles);\n _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(WithStyles).call(this, props, context));\n _this.jss = context[_reactJssContext.default.jss] || jss;\n _this.sheetsManager = sheetsManager;\n _this.unsubscribeId = null;\n var muiThemeProviderOptions = context.muiThemeProviderOptions;\n\n if (muiThemeProviderOptions) {\n if (muiThemeProviderOptions.sheetsManager) {\n _this.sheetsManager = muiThemeProviderOptions.sheetsManager;\n }\n\n _this.sheetsCache = muiThemeProviderOptions.sheetsCache;\n _this.disableStylesGeneration = muiThemeProviderOptions.disableStylesGeneration;\n } // Attach the stylesCreator to the instance of the component as in the context\n // of react-hot-loader the hooks can be executed in a different closure context:\n // https://github.com/gaearon/react-hot-loader/blob/master/src/patch.dev.js#L107\n\n\n _this.stylesCreatorSaved = stylesCreator;\n _this.sheetOptions = (0, _extends3.default)({\n generateClassName: generateClassName\n }, context[_reactJssContext.default.sheetOptions]); // We use || as the function call is lazy evaluated.\n\n _this.theme = listenToTheme ? _themeListener.default.initial(context) || defaultTheme : noopTheme;\n\n _this.attach(_this.theme);\n\n _this.cacheClasses = {\n // Cache for the finalized classes value.\n value: null,\n // Cache for the last used classes prop pointer.\n lastProp: null,\n // Cache for the last used rendered classes pointer.\n lastJSS: {}\n };\n return _this;\n }\n\n (0, _createClass2.default)(WithStyles, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n if (!listenToTheme) {\n return;\n }\n\n this.unsubscribeId = _themeListener.default.subscribe(this.context, function (theme) {\n var oldTheme = _this2.theme;\n _this2.theme = theme;\n\n _this2.attach(_this2.theme); // Rerender the component so the underlying component gets the theme update.\n // By theme update we mean receiving and applying the new class names.\n\n\n _this2.setState({}, function () {\n _this2.detach(oldTheme);\n });\n });\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n // react-hot-loader specific logic\n if (this.stylesCreatorSaved === stylesCreator || process.env.NODE_ENV === 'production') {\n return;\n }\n\n this.detach(this.theme);\n this.stylesCreatorSaved = stylesCreator;\n this.attach(this.theme);\n this.forceUpdate();\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.detach(this.theme);\n\n if (this.unsubscribeId !== null) {\n _themeListener.default.unsubscribe(this.context, this.unsubscribeId);\n }\n }\n }, {\n key: \"getClasses\",\n value: function getClasses() {\n if (this.disableStylesGeneration) {\n return this.props.classes || {};\n } // Tracks if either the rendered classes or classes prop has changed,\n // requiring the generation of a new finalized classes object.\n\n\n var generate = false;\n\n var sheetManager = _multiKeyStore.default.get(this.sheetsManager, this.stylesCreatorSaved, this.theme);\n\n if (sheetManager.sheet.classes !== this.cacheClasses.lastJSS) {\n this.cacheClasses.lastJSS = sheetManager.sheet.classes;\n generate = true;\n }\n\n if (this.props.classes !== this.cacheClasses.lastProp) {\n this.cacheClasses.lastProp = this.props.classes;\n generate = true;\n }\n\n if (generate) {\n this.cacheClasses.value = (0, _mergeClasses.default)({\n baseClasses: this.cacheClasses.lastJSS,\n newClasses: this.props.classes,\n Component: Component\n });\n }\n\n return this.cacheClasses.value;\n }\n }, {\n key: \"attach\",\n value: function attach(theme) {\n if (this.disableStylesGeneration) {\n return;\n }\n\n var stylesCreatorSaved = this.stylesCreatorSaved;\n\n var sheetManager = _multiKeyStore.default.get(this.sheetsManager, stylesCreatorSaved, theme);\n\n if (!sheetManager) {\n sheetManager = {\n refs: 0,\n sheet: null\n };\n\n _multiKeyStore.default.set(this.sheetsManager, stylesCreatorSaved, theme, sheetManager);\n }\n\n if (sheetManager.refs === 0) {\n var sheet;\n\n if (this.sheetsCache) {\n sheet = _multiKeyStore.default.get(this.sheetsCache, stylesCreatorSaved, theme);\n }\n\n if (!sheet) {\n sheet = this.createSheet(theme);\n sheet.attach();\n\n if (this.sheetsCache) {\n _multiKeyStore.default.set(this.sheetsCache, stylesCreatorSaved, theme, sheet);\n }\n }\n\n sheetManager.sheet = sheet;\n var sheetsRegistry = this.context[_reactJssContext.default.sheetsRegistry];\n\n if (sheetsRegistry) {\n sheetsRegistry.add(sheet);\n }\n }\n\n sheetManager.refs += 1;\n }\n }, {\n key: \"createSheet\",\n value: function createSheet(theme) {\n var styles = this.stylesCreatorSaved.create(theme, name);\n var meta = name;\n\n if (process.env.NODE_ENV !== 'production' && !meta) {\n // Provide a better DX outside production.\n meta = (0, _utils.getDisplayName)(Component);\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(typeof meta === 'string', ['Material-UI: the component displayName is invalid. It needs to be a string.', \"Please fix the following component: \".concat(Component, \".\")].join('\\n')) : void 0;\n }\n\n var sheet = this.jss.createStyleSheet(styles, (0, _extends3.default)({\n meta: meta,\n classNamePrefix: meta,\n flip: typeof flip === 'boolean' ? flip : theme.direction === 'rtl',\n link: false\n }, this.sheetOptions, this.stylesCreatorSaved.options, {\n name: name || Component.displayName\n }, styleSheetOptions));\n return sheet;\n }\n }, {\n key: \"detach\",\n value: function detach(theme) {\n if (this.disableStylesGeneration) {\n return;\n }\n\n var sheetManager = _multiKeyStore.default.get(this.sheetsManager, this.stylesCreatorSaved, theme);\n\n sheetManager.refs -= 1;\n\n if (sheetManager.refs === 0) {\n _multiKeyStore.default.delete(this.sheetsManager, this.stylesCreatorSaved, theme);\n\n this.jss.removeStyleSheet(sheetManager.sheet);\n var sheetsRegistry = this.context[_reactJssContext.default.sheetsRegistry];\n\n if (sheetsRegistry) {\n sheetsRegistry.remove(sheetManager.sheet);\n }\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n classes = _this$props.classes,\n innerRef = _this$props.innerRef,\n other = (0, _objectWithoutProperties2.default)(_this$props, [\"classes\", \"innerRef\"]);\n var more = (0, _getThemeProps.default)({\n theme: this.theme,\n name: name,\n props: other\n }); // Provide the theme to the wrapped component.\n // So we don't have to use the ` + ("`" + `withTheme()`))) + (("`" + (` Higher-order Component.\n\n if (withTheme && !more.theme) {\n more.theme = this.theme;\n }\n\n return _react.default.createElement(Component, (0, _extends3.default)({}, more, {\n classes: this.getClasses(),\n ref: innerRef\n }));\n }\n }]);\n return WithStyles;\n }(_react.default.Component);\n\n process.env.NODE_ENV !== \"production\" ? WithStyles.propTypes = {\n /**\r\n * Override or extend the styles applied to the component.\r\n */\n classes: _propTypes.default.object,\n\n /**\r\n * Use that property to pass a ref callback to the decorated component.\r\n */\n innerRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object])\n } : void 0;\n WithStyles.contextTypes = (0, _extends3.default)((_extends2 = {\n muiThemeProviderOptions: _propTypes.default.object\n }, (0, _defineProperty2.default)(_extends2, _reactJssContext.default.jss, _propTypes.default.object), (0, _defineProperty2.default)(_extends2, _reactJssContext.default.sheetOptions, _propTypes.default.object), (0, _defineProperty2.default)(_extends2, _reactJssContext.default.sheetsRegistry, _propTypes.default.object), _extends2), listenToTheme ? _themeListener.default.contextTypes : {});\n\n if (process.env.NODE_ENV !== 'production') {\n WithStyles.displayName = \"WithStyles(\".concat((0, _utils.getDisplayName)(Component), \")\");\n }\n\n (0, _hoistNonReactStatics.default)(WithStyles, Component);\n\n if (process.env.NODE_ENV !== 'production') {\n // Exposed for test purposes.\n WithStyles.Naked = Component;\n WithStyles.options = options;\n }\n\n return WithStyles;\n };\n};\n/* istanbul ignore if */\n\n\nif (!_utils.ponyfillGlobal.__MUI_STYLES__) {\n _utils.ponyfillGlobal.__MUI_STYLES__ = {};\n}\n\nif (!_utils.ponyfillGlobal.__MUI_STYLES__.withStyles) {\n _utils.ponyfillGlobal.__MUI_STYLES__.withStyles = withStylesOld;\n}\n\nvar _default = function _default(styles, options) {\n return _utils.ponyfillGlobal.__MUI_STYLES__.withStyles(styles, (0, _extends3.default)({\n defaultTheme: defaultTheme\n }, options));\n};\n\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n// We need to centralize the zIndex definitions as they work\n// like global values in the browser.\nvar zIndex = {\n mobileStepper: 1000,\n appBar: 1100,\n drawer: 1200,\n modal: 1300,\n snackbar: 1400,\n tooltip: 1500\n};\nvar _default = zIndex;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction deprecatedPropType(validator, reason) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV === 'production') {\n return function () {\n return null;\n };\n }\n\n return function (props, propName, componentName, location, propFullName) {\n var componentNameSafe = componentName || '<>';\n var propFullNameSafe = propFullName || propName;\n\n if (typeof props[propName] !== 'undefined') {\n return new Error(\"The \".concat(location, \" ` + "`")) + (`\").concat(propFullNameSafe, \"` + ("`" + ` of \") + \"`)))) + ((("`" + (`\".concat(componentNameSafe, \"` + "`")) + (` is deprecated. \").concat(reason));\n }\n\n return null;\n };\n}\n\nvar _default = deprecatedPropType;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.capitalize = capitalize;\nexports.contains = contains;\nexports.findIndex = findIndex;\nexports.find = find;\nexports.createChainedFunction = createChainedFunction;\n\nvar _typeof2 = _interopRequireDefault(require(\"@babel/runtime/helpers/typeof\"));\n\nvar _warning = _interopRequireDefault(require(\"warning\"));\n\n// It should to be noted that this function isn't equivalent to ` + ("`" + `text-transform: capitalize`))) + (("`" + (`.\n//\n// A strict capitalization should uppercase the first letter of each word a the sentence.\n// We only handle the first word.\nfunction capitalize(string) {\n if (process.env.NODE_ENV !== 'production' && typeof string !== 'string') {\n throw new Error('Material-UI: capitalize(string) expects a string argument.');\n }\n\n return string.charAt(0).toUpperCase() + string.slice(1);\n}\n\nfunction contains(obj, pred) {\n return Object.keys(pred).every(function (key) {\n return obj.hasOwnProperty(key) && obj[key] === pred[key];\n });\n}\n\nfunction findIndex(arr, pred) {\n var predType = (0, _typeof2.default)(pred);\n\n for (var i = 0; i < arr.length; i += 1) {\n if (predType === 'function' && !!pred(arr[i], i, arr) === true) {\n return i;\n }\n\n if (predType === 'object' && contains(arr[i], pred)) {\n return i;\n }\n\n if (['string', 'number', 'boolean'].indexOf(predType) !== -1) {\n return arr.indexOf(pred);\n }\n }\n\n return -1;\n}\n\nfunction find(arr, pred) {\n var index = findIndex(arr, pred);\n return index > -1 ? arr[index] : undefined;\n}\n/**\r\n * Safe chained function\r\n *\r\n * Will only create a new function if needed,\r\n * otherwise will pass back existing functions or null.\r\n *\r\n * @param {function} functions to chain\r\n * @returns {function|null}\r\n */\n\n\nfunction createChainedFunction() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n return funcs.reduce(function (acc, func) {\n if (func == null) {\n return acc;\n }\n\n process.env.NODE_ENV !== \"production\" ? (0, _warning.default)(typeof func === 'function', 'Material-UI: invalid Argument Type, must only provide functions, undefined, or null.') : void 0;\n return function chainedFunction() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n acc.apply(this, args);\n func.apply(this, args);\n };\n }, function () {});\n}", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction ownerDocument(node) {\n return node && node.ownerDocument || document;\n}\n\nvar _default = ownerDocument;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _ownerDocument = _interopRequireDefault(require(\"./ownerDocument\"));\n\nfunction ownerWindow(node) {\n var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;\n var doc = (0, _ownerDocument.default)(node);\n return doc.defaultView || doc.parentView || fallback;\n}\n\nvar _default = ownerWindow;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.cloneElementWithClassName = cloneElementWithClassName;\nexports.cloneChildrenWithClassName = cloneChildrenWithClassName;\nexports.isMuiElement = isMuiElement;\nexports.setRef = setRef;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _classnames = _interopRequireDefault(require(\"classnames\"));\n\nfunction cloneElementWithClassName(child, className) {\n return _react.default.cloneElement(child, {\n className: (0, _classnames.default)(child.props.className, className)\n });\n}\n\nfunction cloneChildrenWithClassName(children, className) {\n return _react.default.Children.map(children, function (child) {\n return _react.default.isValidElement(child) && cloneElementWithClassName(child, className);\n });\n}\n\nfunction isMuiElement(element, muiNames) {\n return _react.default.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1;\n}\n\nfunction setRef(ref, value) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref) {\n ref.current = value;\n }\n}", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction requirePropFactory(componentNameInError) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV === 'production') {\n return function () {\n return null;\n };\n }\n\n var requireProp = function requireProp(requiredProp) {\n return function (props, propName, componentName, location, propFullName) {\n var propFullNameSafe = propFullName || propName;\n\n if (typeof props[propName] !== 'undefined' && !props[requiredProp]) {\n return new Error(\"The property ` + "`")) + (`\".concat(propFullNameSafe, \"` + ("`" + ` of \") + \"`))))) + (((("`" + (`\".concat(componentNameInError, \"` + "`")) + (` must be used on ` + ("`" + `\").concat(requiredProp, \"`))) + (("`" + (`.\"));\n }\n\n return null;\n };\n };\n\n return requireProp;\n}\n\nvar _default = requirePropFactory;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction chainPropTypes(propType1, propType2) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV === 'production') {\n return function () {\n return null;\n };\n }\n\n return function validate() {\n return propType1.apply(void 0, arguments) || propType2.apply(void 0, arguments);\n };\n}\n\nvar _default = chainPropTypes;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _typeof2 = _interopRequireDefault(require(\"@babel/runtime/helpers/typeof\"));\n\nvar _reactIs = require(\"react-is\");\n\n/**\n * A factory that returns a propTypes validator that only accepts values that\n * are also accepted by React.createElement\n * e.g. \"div\", functional, class components, forwardRef etc.\n *\n * @param {boolean} isRequired If ` + "`")) + (`true` + ("`" + ` returns a validator\n * that will throw if nullish values are passed\n */\nfunction createComponentProp(isRequired) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV === 'production') {\n return function () {\n return null;\n };\n }\n\n return function componentPropType(props, key, componentName, location, propFullName) {\n var prop = props[key];\n var propName = propFullName || key;\n var message;\n\n if (prop == null) {\n if (isRequired) {\n message = \"The \".concat(location, \" `)))) + ((("`" + (`\").concat(propName, \"` + "`")) + (` is marked as required in ` + ("`" + `\").concat(componentName, \"`))) + (("`" + (`, \") + \"but its value is ` + "`")) + ((`\".concat((0, _typeof2.default)(prop), \"` + "`") + (`.\");\n }\n } else if (!(0, _reactIs.isValidElementType)(prop)) {\n var preciseType = (0, _typeof2.default)(prop);\n message = \"Invalid \".concat(location, \" ` + "`")))))) + (((((`\").concat(propName, \"` + ("`" + ` of type `)) + ("`" + (`\").concat(preciseType, \"` + "`"))) + ((` \") + \"supplied to ` + ("`" + `\".concat(componentName, \"`)) + ("`" + (`, expected a component.\");\n }\n\n if (message != null) {\n // change error message slightly on every check to prevent caching when testing\n // which would not trigger console errors on subsequent fails\n return new Error(\"\".concat(message).concat(process.env.NODE_ENV === 'test' ? Date.now() : ''));\n }\n\n return null;\n };\n}\n\nvar componentPropType = createComponentProp(false);\ncomponentPropType.isRequired = createComponentProp(true);\nvar _default = componentPropType;\nexports.default = _default;", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = exports.specialProperty = void 0;\n\nvar _defineProperty2 = _interopRequireDefault(require(\"@babel/runtime/helpers/defineProperty\"));\n\nvar _extends3 = _interopRequireDefault(require(\"@babel/runtime/helpers/extends\"));\n\n// This module is based on https://github.com/airbnb/prop-types-exact repository.\n// However, in order to reduce the number of dependencies and to remove some extra safe checks\n// the module was forked.\n// Only exported for test purposes.\nvar specialProperty = \"exact-prop: \\u200B\";\nexports.specialProperty = specialProperty;\n\nfunction exactProp(propTypes) {\n /* istanbul ignore if */\n if (process.env.NODE_ENV === 'production') {\n return propTypes;\n }\n\n return (0, _extends3.default)({}, propTypes, (0, _defineProperty2.default)({}, specialProperty, function (props) {\n var unsupportedProps = Object.keys(props).filter(function (prop) {\n return !propTypes.hasOwnProperty(prop);\n });\n\n if (unsupportedProps.length > 0) {\n return new Error(\"The following properties are not supported: \".concat(unsupportedProps.map(function (prop) {\n return \"` + "`")))) + (((`\".concat(prop, \"` + ("`" + `\");\n }).join(', '), \". Please remove them.\"));\n }\n\n return null;\n }));\n}\n\nvar _default = exactProp;\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getFunctionName = getFunctionName;\nexports.default = void 0;\n// Fork of recompose/getDisplayName with added IE 11 support\n// Simplified polyfill for IE 11 support\n// https://github.com/JamesMGreene/Function.name/blob/58b314d4a983110c3682f1228f845d39ccca1817/Function.name.js#L3\nvar fnNameMatchRegex = /^\\s*function(?:\\s|\\s*\\/\\*.*\\*\\/\\s*)+([^(\\s/]*)\\s*/;\n\nfunction getFunctionName(fn) {\n var match = \"\".concat(fn).match(fnNameMatchRegex);\n var name = match && match[1];\n return name || '';\n}\n\nfunction getDisplayName(Component) {\n if (typeof Component === 'string') {\n return Component;\n }\n\n if (!Component) {\n return undefined;\n }\n\n return Component.displayName || Component.name || getFunctionName(Component) || 'Component';\n}\n\nvar _default = getDisplayName;\nexports.default = _default;", + "/** @license Material-UI v3.0.0-alpha.3\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nexport { default as componentPropType } from './componentPropType';\nexport { default as chainPropTypes } from './chainPropTypes';\nexport { default as exactProp } from './exactProp';\nexport { default as getDisplayName } from './getDisplayName';\nexport { default as ponyfillGlobal } from './ponyfillGlobal';\n", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\n/* eslint-disable */\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar _default = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\n\nexports.default = _default;", + "module.exports = balanced;\nfunction balanced(a, b, str) {\n if (a instanceof RegExp) a = maybeMatch(a, str);\n if (b instanceof RegExp) b = maybeMatch(b, str);\n\n var r = range(a, b, str);\n\n return r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + a.length, r[1]),\n post: str.slice(r[1] + b.length)\n };\n}\n\nfunction maybeMatch(reg, str) {\n var m = str.match(reg);\n return m ? m[0] : null;\n}\n\nbalanced.range = range;\nfunction range(a, b, str) {\n var begs, beg, left, right, result;\n var ai = str.indexOf(a);\n var bi = str.indexOf(b, ai + 1);\n var i = ai;\n\n if (ai >= 0 && bi > 0) {\n begs = [];\n left = str.length;\n\n while (i >= 0 && !result) {\n if (i == ai) {\n begs.push(i);\n ai = str.indexOf(a, i + 1);\n } else if (begs.length == 1) {\n result = [ begs.pop(), bi ];\n } else {\n beg = begs.pop();\n if (beg < left) {\n left = beg;\n right = bi;\n }\n\n bi = str.indexOf(b, i + 1);\n }\n\n i = ai < bi && ai >= 0 ? ai : bi;\n }\n\n if (begs.length) {\n result = [ left, right ];\n }\n }\n\n return result;\n}\n", + "function createBroadcast (initialState) {\n var listeners = {};\n var id = 1;\n var _state = initialState;\n\n function getState () {\n return _state\n }\n\n function setState (state) {\n _state = state;\n var keys = Object.keys(listeners);\n var i = 0;\n var len = keys.length;\n for (; i < len; i++) {\n // if a listener gets unsubscribed during setState we just skip it\n if (listeners[keys[i]]) { listeners[keys[i]](state); }\n }\n }\n\n // subscribe to changes and return the subscriptionId\n function subscribe (listener) {\n if (typeof listener !== 'function') {\n throw new Error('listener must be a function.')\n }\n var currentId = id;\n listeners[currentId] = listener;\n id += 1;\n return currentId\n }\n\n // remove subscription by removing the listener function\n function unsubscribe (id) {\n listeners[id] = undefined;\n }\n\n return { getState: getState, setState: setState, subscribe: subscribe, unsubscribe: unsubscribe }\n}\n\nexport default createBroadcast;\n", + "/*!\n Copyright (c) 2017 Jed Watson.\n Licensed under the MIT License (MIT), see\n http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg) && arg.length) {\n\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\tif (inner) {\n\t\t\t\t\tclasses.push(inner);\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n", + "/* MIT license */\n/* eslint-disable no-mixed-operators */\nconst cssKeywords = require('color-name');\n\n// NOTE: conversions should only return primitive values (i.e. arrays, or\n// values that give correct `)) + ("`" + (`typeof` + "`"))) + ((` results).\n// do not use box values types (i.e. Number(), String(), etc.)\n\nconst reverseKeywords = {};\nfor (const key of Object.keys(cssKeywords)) {\n\treverseKeywords[cssKeywords[key]] = key;\n}\n\nconst convert = {\n\trgb: {channels: 3, labels: 'rgb'},\n\thsl: {channels: 3, labels: 'hsl'},\n\thsv: {channels: 3, labels: 'hsv'},\n\thwb: {channels: 3, labels: 'hwb'},\n\tcmyk: {channels: 4, labels: 'cmyk'},\n\txyz: {channels: 3, labels: 'xyz'},\n\tlab: {channels: 3, labels: 'lab'},\n\tlch: {channels: 3, labels: 'lch'},\n\thex: {channels: 1, labels: ['hex']},\n\tkeyword: {channels: 1, labels: ['keyword']},\n\tansi16: {channels: 1, labels: ['ansi16']},\n\tansi256: {channels: 1, labels: ['ansi256']},\n\thcg: {channels: 3, labels: ['h', 'c', 'g']},\n\tapple: {channels: 3, labels: ['r16', 'g16', 'b16']},\n\tgray: {channels: 1, labels: ['gray']}\n};\n\nmodule.exports = convert;\n\n// Hide .channels and .labels properties\nfor (const model of Object.keys(convert)) {\n\tif (!('channels' in convert[model])) {\n\t\tthrow new Error('missing channels property: ' + model);\n\t}\n\n\tif (!('labels' in convert[model])) {\n\t\tthrow new Error('missing channel labels property: ' + model);\n\t}\n\n\tif (convert[model].labels.length !== convert[model].channels) {\n\t\tthrow new Error('channel and label counts mismatch: ' + model);\n\t}\n\n\tconst {channels, labels} = convert[model];\n\tdelete convert[model].channels;\n\tdelete convert[model].labels;\n\tObject.defineProperty(convert[model], 'channels', {value: channels});\n\tObject.defineProperty(convert[model], 'labels', {value: labels});\n}\n\nconvert.rgb.hsl = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst min = Math.min(r, g, b);\n\tconst max = Math.max(r, g, b);\n\tconst delta = max - min;\n\tlet h;\n\tlet s;\n\n\tif (max === min) {\n\t\th = 0;\n\t} else if (r === max) {\n\t\th = (g - b) / delta;\n\t} else if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t} else if (b === max) {\n\t\th = 4 + (r - g) / delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tconst l = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t} else if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t} else {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\n};\n\nconvert.rgb.hsv = function (rgb) {\n\tlet rdif;\n\tlet gdif;\n\tlet bdif;\n\tlet h;\n\tlet s;\n\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst v = Math.max(r, g, b);\n\tconst diff = v - Math.min(r, g, b);\n\tconst diffc = function (c) {\n\t\treturn (v - c) / 6 / diff + 1 / 2;\n\t};\n\n\tif (diff === 0) {\n\t\th = 0;\n\t\ts = 0;\n\t} else {\n\t\ts = diff / v;\n\t\trdif = diffc(r);\n\t\tgdif = diffc(g);\n\t\tbdif = diffc(b);\n\n\t\tif (r === v) {\n\t\t\th = bdif - gdif;\n\t\t} else if (g === v) {\n\t\t\th = (1 / 3) + rdif - bdif;\n\t\t} else if (b === v) {\n\t\t\th = (2 / 3) + gdif - rdif;\n\t\t}\n\n\t\tif (h < 0) {\n\t\t\th += 1;\n\t\t} else if (h > 1) {\n\t\t\th -= 1;\n\t\t}\n\t}\n\n\treturn [\n\t\th * 360,\n\t\ts * 100,\n\t\tv * 100\n\t];\n};\n\nconvert.rgb.hwb = function (rgb) {\n\tconst r = rgb[0];\n\tconst g = rgb[1];\n\tlet b = rgb[2];\n\tconst h = convert.rgb.hsl(rgb)[0];\n\tconst w = 1 / 255 * Math.min(r, Math.min(g, b));\n\n\tb = 1 - 1 / 255 * Math.max(r, Math.max(g, b));\n\n\treturn [h, w * 100, b * 100];\n};\n\nconvert.rgb.cmyk = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\n\tconst k = Math.min(1 - r, 1 - g, 1 - b);\n\tconst c = (1 - r - k) / (1 - k) || 0;\n\tconst m = (1 - g - k) / (1 - k) || 0;\n\tconst y = (1 - b - k) / (1 - k) || 0;\n\n\treturn [c * 100, m * 100, y * 100, k * 100];\n};\n\nfunction comparativeDistance(x, y) {\n\t/*\n\t\tSee https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance\n\t*/\n\treturn (\n\t\t((x[0] - y[0]) ** 2) +\n\t\t((x[1] - y[1]) ** 2) +\n\t\t((x[2] - y[2]) ** 2)\n\t);\n}\n\nconvert.rgb.keyword = function (rgb) {\n\tconst reversed = reverseKeywords[rgb];\n\tif (reversed) {\n\t\treturn reversed;\n\t}\n\n\tlet currentClosestDistance = Infinity;\n\tlet currentClosestKeyword;\n\n\tfor (const keyword of Object.keys(cssKeywords)) {\n\t\tconst value = cssKeywords[keyword];\n\n\t\t// Compute comparative distance\n\t\tconst distance = comparativeDistance(rgb, value);\n\n\t\t// Check if its less, if so set as closest\n\t\tif (distance < currentClosestDistance) {\n\t\t\tcurrentClosestDistance = distance;\n\t\t\tcurrentClosestKeyword = keyword;\n\t\t}\n\t}\n\n\treturn currentClosestKeyword;\n};\n\nconvert.keyword.rgb = function (keyword) {\n\treturn cssKeywords[keyword];\n};\n\nconvert.rgb.xyz = function (rgb) {\n\tlet r = rgb[0] / 255;\n\tlet g = rgb[1] / 255;\n\tlet b = rgb[2] / 255;\n\n\t// Assume sRGB\n\tr = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);\n\n\tconst x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n\tconst y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n\tconst z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n\treturn [x * 100, y * 100, z * 100];\n};\n\nconvert.rgb.lab = function (rgb) {\n\tconst xyz = convert.rgb.xyz(rgb);\n\tlet x = xyz[0];\n\tlet y = xyz[1];\n\tlet z = xyz[2];\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);\n\n\tconst l = (116 * y) - 16;\n\tconst a = 500 * (x - y);\n\tconst b = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.hsl.rgb = function (hsl) {\n\tconst h = hsl[0] / 360;\n\tconst s = hsl[1] / 100;\n\tconst l = hsl[2] / 100;\n\tlet t2;\n\tlet t3;\n\tlet val;\n\n\tif (s === 0) {\n\t\tval = l * 255;\n\t\treturn [val, val, val];\n\t}\n\n\tif (l < 0.5) {\n\t\tt2 = l * (1 + s);\n\t} else {\n\t\tt2 = l + s - l * s;\n\t}\n\n\tconst t1 = 2 * l - t2;\n\n\tconst rgb = [0, 0, 0];\n\tfor (let i = 0; i < 3; i++) {\n\t\tt3 = h + 1 / 3 * -(i - 1);\n\t\tif (t3 < 0) {\n\t\t\tt3++;\n\t\t}\n\n\t\tif (t3 > 1) {\n\t\t\tt3--;\n\t\t}\n\n\t\tif (6 * t3 < 1) {\n\t\t\tval = t1 + (t2 - t1) * 6 * t3;\n\t\t} else if (2 * t3 < 1) {\n\t\t\tval = t2;\n\t\t} else if (3 * t3 < 2) {\n\t\t\tval = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n\t\t} else {\n\t\t\tval = t1;\n\t\t}\n\n\t\trgb[i] = val * 255;\n\t}\n\n\treturn rgb;\n};\n\nconvert.hsl.hsv = function (hsl) {\n\tconst h = hsl[0];\n\tlet s = hsl[1] / 100;\n\tlet l = hsl[2] / 100;\n\tlet smin = s;\n\tconst lmin = Math.max(l, 0.01);\n\n\tl *= 2;\n\ts *= (l <= 1) ? l : 2 - l;\n\tsmin *= lmin <= 1 ? lmin : 2 - lmin;\n\tconst v = (l + s) / 2;\n\tconst sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);\n\n\treturn [h, sv * 100, v * 100];\n};\n\nconvert.hsv.rgb = function (hsv) {\n\tconst h = hsv[0] / 60;\n\tconst s = hsv[1] / 100;\n\tlet v = hsv[2] / 100;\n\tconst hi = Math.floor(h) % 6;\n\n\tconst f = h - Math.floor(h);\n\tconst p = 255 * v * (1 - s);\n\tconst q = 255 * v * (1 - (s * f));\n\tconst t = 255 * v * (1 - (s * (1 - f)));\n\tv *= 255;\n\n\tswitch (hi) {\n\t\tcase 0:\n\t\t\treturn [v, t, p];\n\t\tcase 1:\n\t\t\treturn [q, v, p];\n\t\tcase 2:\n\t\t\treturn [p, v, t];\n\t\tcase 3:\n\t\t\treturn [p, q, v];\n\t\tcase 4:\n\t\t\treturn [t, p, v];\n\t\tcase 5:\n\t\t\treturn [v, p, q];\n\t}\n};\n\nconvert.hsv.hsl = function (hsv) {\n\tconst h = hsv[0];\n\tconst s = hsv[1] / 100;\n\tconst v = hsv[2] / 100;\n\tconst vmin = Math.max(v, 0.01);\n\tlet sl;\n\tlet l;\n\n\tl = (2 - s) * v;\n\tconst lmin = (2 - s) * vmin;\n\tsl = s * vmin;\n\tsl /= (lmin <= 1) ? lmin : 2 - lmin;\n\tsl = sl || 0;\n\tl /= 2;\n\n\treturn [h, sl * 100, l * 100];\n};\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nconvert.hwb.rgb = function (hwb) {\n\tconst h = hwb[0] / 360;\n\tlet wh = hwb[1] / 100;\n\tlet bl = hwb[2] / 100;\n\tconst ratio = wh + bl;\n\tlet f;\n\n\t// Wh + bl cant be > 1\n\tif (ratio > 1) {\n\t\twh /= ratio;\n\t\tbl /= ratio;\n\t}\n\n\tconst i = Math.floor(6 * h);\n\tconst v = 1 - bl;\n\tf = 6 * h - i;\n\n\tif ((i & 0x01) !== 0) {\n\t\tf = 1 - f;\n\t}\n\n\tconst n = wh + f * (v - wh); // Linear interpolation\n\n\tlet r;\n\tlet g;\n\tlet b;\n\t/* eslint-disable max-statements-per-line,no-multi-spaces */\n\tswitch (i) {\n\t\tdefault:\n\t\tcase 6:\n\t\tcase 0: r = v; g = n; b = wh; break;\n\t\tcase 1: r = n; g = v; b = wh; break;\n\t\tcase 2: r = wh; g = v; b = n; break;\n\t\tcase 3: r = wh; g = n; b = v; break;\n\t\tcase 4: r = n; g = wh; b = v; break;\n\t\tcase 5: r = v; g = wh; b = n; break;\n\t}\n\t/* eslint-enable max-statements-per-line,no-multi-spaces */\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.cmyk.rgb = function (cmyk) {\n\tconst c = cmyk[0] / 100;\n\tconst m = cmyk[1] / 100;\n\tconst y = cmyk[2] / 100;\n\tconst k = cmyk[3] / 100;\n\n\tconst r = 1 - Math.min(1, c * (1 - k) + k);\n\tconst g = 1 - Math.min(1, m * (1 - k) + k);\n\tconst b = 1 - Math.min(1, y * (1 - k) + k);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.rgb = function (xyz) {\n\tconst x = xyz[0] / 100;\n\tconst y = xyz[1] / 100;\n\tconst z = xyz[2] / 100;\n\tlet r;\n\tlet g;\n\tlet b;\n\n\tr = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n\tg = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n\tb = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n\t// Assume sRGB\n\tr = r > 0.0031308\n\t\t? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)\n\t\t: r * 12.92;\n\n\tg = g > 0.0031308\n\t\t? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)\n\t\t: g * 12.92;\n\n\tb = b > 0.0031308\n\t\t? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)\n\t\t: b * 12.92;\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.lab = function (xyz) {\n\tlet x = xyz[0];\n\tlet y = xyz[1];\n\tlet z = xyz[2];\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);\n\n\tconst l = (116 * y) - 16;\n\tconst a = 500 * (x - y);\n\tconst b = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.lab.xyz = function (lab) {\n\tconst l = lab[0];\n\tconst a = lab[1];\n\tconst b = lab[2];\n\tlet x;\n\tlet y;\n\tlet z;\n\n\ty = (l + 16) / 116;\n\tx = a / 500 + y;\n\tz = y - b / 200;\n\n\tconst y2 = y ** 3;\n\tconst x2 = x ** 3;\n\tconst z2 = z ** 3;\n\ty = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;\n\tx = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;\n\tz = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;\n\n\tx *= 95.047;\n\ty *= 100;\n\tz *= 108.883;\n\n\treturn [x, y, z];\n};\n\nconvert.lab.lch = function (lab) {\n\tconst l = lab[0];\n\tconst a = lab[1];\n\tconst b = lab[2];\n\tlet h;\n\n\tconst hr = Math.atan2(b, a);\n\th = hr * 360 / 2 / Math.PI;\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tconst c = Math.sqrt(a * a + b * b);\n\n\treturn [l, c, h];\n};\n\nconvert.lch.lab = function (lch) {\n\tconst l = lch[0];\n\tconst c = lch[1];\n\tconst h = lch[2];\n\n\tconst hr = h / 360 * 2 * Math.PI;\n\tconst a = c * Math.cos(hr);\n\tconst b = c * Math.sin(hr);\n\n\treturn [l, a, b];\n};\n\nconvert.rgb.ansi16 = function (args, saturation = null) {\n\tconst [r, g, b] = args;\n\tlet value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization\n\n\tvalue = Math.round(value / 50);\n\n\tif (value === 0) {\n\t\treturn 30;\n\t}\n\n\tlet ansi = 30\n\t\t+ ((Math.round(b / 255) << 2)\n\t\t| (Math.round(g / 255) << 1)\n\t\t| Math.round(r / 255));\n\n\tif (value === 2) {\n\t\tansi += 60;\n\t}\n\n\treturn ansi;\n};\n\nconvert.hsv.ansi16 = function (args) {\n\t// Optimization here; we already know the value and don't need to get\n\t// it converted for us.\n\treturn convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);\n};\n\nconvert.rgb.ansi256 = function (args) {\n\tconst r = args[0];\n\tconst g = args[1];\n\tconst b = args[2];\n\n\t// We use the extended greyscale palette here, with the exception of\n\t// black and white. normal palette only has 4 greyscale shades.\n\tif (r === g && g === b) {\n\t\tif (r < 8) {\n\t\t\treturn 16;\n\t\t}\n\n\t\tif (r > 248) {\n\t\t\treturn 231;\n\t\t}\n\n\t\treturn Math.round(((r - 8) / 247) * 24) + 232;\n\t}\n\n\tconst ansi = 16\n\t\t+ (36 * Math.round(r / 255 * 5))\n\t\t+ (6 * Math.round(g / 255 * 5))\n\t\t+ Math.round(b / 255 * 5);\n\n\treturn ansi;\n};\n\nconvert.ansi16.rgb = function (args) {\n\tlet color = args % 10;\n\n\t// Handle greyscale\n\tif (color === 0 || color === 7) {\n\t\tif (args > 50) {\n\t\t\tcolor += 3.5;\n\t\t}\n\n\t\tcolor = color / 10.5 * 255;\n\n\t\treturn [color, color, color];\n\t}\n\n\tconst mult = (~~(args > 50) + 1) * 0.5;\n\tconst r = ((color & 1) * mult) * 255;\n\tconst g = (((color >> 1) & 1) * mult) * 255;\n\tconst b = (((color >> 2) & 1) * mult) * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.ansi256.rgb = function (args) {\n\t// Handle greyscale\n\tif (args >= 232) {\n\t\tconst c = (args - 232) * 10 + 8;\n\t\treturn [c, c, c];\n\t}\n\n\targs -= 16;\n\n\tlet rem;\n\tconst r = Math.floor(args / 36) / 5 * 255;\n\tconst g = Math.floor((rem = args % 36) / 6) / 5 * 255;\n\tconst b = (rem % 6) / 5 * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hex = function (args) {\n\tconst integer = ((Math.round(args[0]) & 0xFF) << 16)\n\t\t+ ((Math.round(args[1]) & 0xFF) << 8)\n\t\t+ (Math.round(args[2]) & 0xFF);\n\n\tconst string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.hex.rgb = function (args) {\n\tconst match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\n\tlet colorString = match[0];\n\n\tif (match[0].length === 3) {\n\t\tcolorString = colorString.split('').map(char => {\n\t\t\treturn char + char;\n\t\t}).join('');\n\t}\n\n\tconst integer = parseInt(colorString, 16);\n\tconst r = (integer >> 16) & 0xFF;\n\tconst g = (integer >> 8) & 0xFF;\n\tconst b = integer & 0xFF;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hcg = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst max = Math.max(Math.max(r, g), b);\n\tconst min = Math.min(Math.min(r, g), b);\n\tconst chroma = (max - min);\n\tlet grayscale;\n\tlet hue;\n\n\tif (chroma < 1) {\n\t\tgrayscale = min / (1 - chroma);\n\t} else {\n\t\tgrayscale = 0;\n\t}\n\n\tif (chroma <= 0) {\n\t\thue = 0;\n\t} else\n\tif (max === r) {\n\t\thue = ((g - b) / chroma) % 6;\n\t} else\n\tif (max === g) {\n\t\thue = 2 + (b - r) / chroma;\n\t} else {\n\t\thue = 4 + (r - g) / chroma + 4;\n\t}\n\n\thue /= 6;\n\thue %= 1;\n\n\treturn [hue * 360, chroma * 100, grayscale * 100];\n};\n\nconvert.hsl.hcg = function (hsl) {\n\tconst s = hsl[1] / 100;\n\tconst l = hsl[2] / 100;\n\n\tconst c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));\n\n\tlet f = 0;\n\tif (c < 1.0) {\n\t\tf = (l - 0.5 * c) / (1.0 - c);\n\t}\n\n\treturn [hsl[0], c * 100, f * 100];\n};\n\nconvert.hsv.hcg = function (hsv) {\n\tconst s = hsv[1] / 100;\n\tconst v = hsv[2] / 100;\n\n\tconst c = s * v;\n\tlet f = 0;\n\n\tif (c < 1.0) {\n\t\tf = (v - c) / (1 - c);\n\t}\n\n\treturn [hsv[0], c * 100, f * 100];\n};\n\nconvert.hcg.rgb = function (hcg) {\n\tconst h = hcg[0] / 360;\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tif (c === 0.0) {\n\t\treturn [g * 255, g * 255, g * 255];\n\t}\n\n\tconst pure = [0, 0, 0];\n\tconst hi = (h % 1) * 6;\n\tconst v = hi % 1;\n\tconst w = 1 - v;\n\tlet mg = 0;\n\n\t/* eslint-disable max-statements-per-line */\n\tswitch (Math.floor(hi)) {\n\t\tcase 0:\n\t\t\tpure[0] = 1; pure[1] = v; pure[2] = 0; break;\n\t\tcase 1:\n\t\t\tpure[0] = w; pure[1] = 1; pure[2] = 0; break;\n\t\tcase 2:\n\t\t\tpure[0] = 0; pure[1] = 1; pure[2] = v; break;\n\t\tcase 3:\n\t\t\tpure[0] = 0; pure[1] = w; pure[2] = 1; break;\n\t\tcase 4:\n\t\t\tpure[0] = v; pure[1] = 0; pure[2] = 1; break;\n\t\tdefault:\n\t\t\tpure[0] = 1; pure[1] = 0; pure[2] = w;\n\t}\n\t/* eslint-enable max-statements-per-line */\n\n\tmg = (1.0 - c) * g;\n\n\treturn [\n\t\t(c * pure[0] + mg) * 255,\n\t\t(c * pure[1] + mg) * 255,\n\t\t(c * pure[2] + mg) * 255\n\t];\n};\n\nconvert.hcg.hsv = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tconst v = c + g * (1.0 - c);\n\tlet f = 0;\n\n\tif (v > 0.0) {\n\t\tf = c / v;\n\t}\n\n\treturn [hcg[0], f * 100, v * 100];\n};\n\nconvert.hcg.hsl = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tconst l = g * (1.0 - c) + 0.5 * c;\n\tlet s = 0;\n\n\tif (l > 0.0 && l < 0.5) {\n\t\ts = c / (2 * l);\n\t} else\n\tif (l >= 0.5 && l < 1.0) {\n\t\ts = c / (2 * (1 - l));\n\t}\n\n\treturn [hcg[0], s * 100, l * 100];\n};\n\nconvert.hcg.hwb = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\tconst v = c + g * (1.0 - c);\n\treturn [hcg[0], (v - c) * 100, (1 - v) * 100];\n};\n\nconvert.hwb.hcg = function (hwb) {\n\tconst w = hwb[1] / 100;\n\tconst b = hwb[2] / 100;\n\tconst v = 1 - b;\n\tconst c = v - w;\n\tlet g = 0;\n\n\tif (c < 1) {\n\t\tg = (v - c) / (1 - c);\n\t}\n\n\treturn [hwb[0], c * 100, g * 100];\n};\n\nconvert.apple.rgb = function (apple) {\n\treturn [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];\n};\n\nconvert.rgb.apple = function (rgb) {\n\treturn [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];\n};\n\nconvert.gray.rgb = function (args) {\n\treturn [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];\n};\n\nconvert.gray.hsl = function (args) {\n\treturn [0, 0, args[0]];\n};\n\nconvert.gray.hsv = convert.gray.hsl;\n\nconvert.gray.hwb = function (gray) {\n\treturn [0, 100, gray[0]];\n};\n\nconvert.gray.cmyk = function (gray) {\n\treturn [0, 0, 0, gray[0]];\n};\n\nconvert.gray.lab = function (gray) {\n\treturn [gray[0], 0, 0];\n};\n\nconvert.gray.hex = function (gray) {\n\tconst val = Math.round(gray[0] / 100 * 255) & 0xFF;\n\tconst integer = (val << 16) + (val << 8) + val;\n\n\tconst string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.rgb.gray = function (rgb) {\n\tconst val = (rgb[0] + rgb[1] + rgb[2]) / 3;\n\treturn [val / 255 * 100];\n};\n", + "const conversions = require('./conversions');\nconst route = require('./route');\n\nconst convert = {};\n\nconst models = Object.keys(conversions);\n\nfunction wrapRaw(fn) {\n\tconst wrappedFn = function (...args) {\n\t\tconst arg0 = args[0];\n\t\tif (arg0 === undefined || arg0 === null) {\n\t\t\treturn arg0;\n\t\t}\n\n\t\tif (arg0.length > 1) {\n\t\t\targs = arg0;\n\t\t}\n\n\t\treturn fn(args);\n\t};\n\n\t// Preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nfunction wrapRounded(fn) {\n\tconst wrappedFn = function (...args) {\n\t\tconst arg0 = args[0];\n\n\t\tif (arg0 === undefined || arg0 === null) {\n\t\t\treturn arg0;\n\t\t}\n\n\t\tif (arg0.length > 1) {\n\t\t\targs = arg0;\n\t\t}\n\n\t\tconst result = fn(args);\n\n\t\t// We're assuming the result is an array here.\n\t\t// see notice in conversions.js; don't use box types\n\t\t// in conversion functions.\n\t\tif (typeof result === 'object') {\n\t\t\tfor (let len = result.length, i = 0; i < len; i++) {\n\t\t\t\tresult[i] = Math.round(result[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t// Preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nmodels.forEach(fromModel => {\n\tconvert[fromModel] = {};\n\n\tObject.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});\n\tObject.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});\n\n\tconst routes = route(fromModel);\n\tconst routeModels = Object.keys(routes);\n\n\trouteModels.forEach(toModel => {\n\t\tconst fn = routes[toModel];\n\n\t\tconvert[fromModel][toModel] = wrapRounded(fn);\n\t\tconvert[fromModel][toModel].raw = wrapRaw(fn);\n\t});\n});\n\nmodule.exports = convert;\n", + "const conversions = require('./conversions');\n\n/*\n\tThis function routes a model to all other models.\n\n\tall functions that are routed have a property ` + ("`" + `.conversion`)) + (("`" + ` attached\n\tto the returned synthetic function. This property is an array\n\tof strings, each with the steps in between the 'from' and 'to'\n\tcolor models (inclusive).\n\n\tconversions that are not possible simply are not included.\n*/\n\nfunction buildGraph() {\n\tconst graph = {};\n\t// https://jsperf.com/object-keys-vs-for-in-with-closure/3\n\tconst models = Object.keys(conversions);\n\n\tfor (let len = models.length, i = 0; i < len; i++) {\n\t\tgraph[models[i]] = {\n\t\t\t// http://jsperf.com/1-vs-infinity\n\t\t\t// micro-opt, but this is simple.\n\t\t\tdistance: -1,\n\t\t\tparent: null\n\t\t};\n\t}\n\n\treturn graph;\n}\n\n// https://en.wikipedia.org/wiki/Breadth-first_search\nfunction deriveBFS(fromModel) {\n\tconst graph = buildGraph();\n\tconst queue = [fromModel]; // Unshift -> queue -> pop\n\n\tgraph[fromModel].distance = 0;\n\n\twhile (queue.length) {\n\t\tconst current = queue.pop();\n\t\tconst adjacents = Object.keys(conversions[current]);\n\n\t\tfor (let len = adjacents.length, i = 0; i < len; i++) {\n\t\t\tconst adjacent = adjacents[i];\n\t\t\tconst node = graph[adjacent];\n\n\t\t\tif (node.distance === -1) {\n\t\t\t\tnode.distance = graph[current].distance + 1;\n\t\t\t\tnode.parent = current;\n\t\t\t\tqueue.unshift(adjacent);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn graph;\n}\n\nfunction link(from, to) {\n\treturn function (args) {\n\t\treturn to(from(args));\n\t};\n}\n\nfunction wrapConversion(toModel, graph) {\n\tconst path = [graph[toModel].parent, toModel];\n\tlet fn = conversions[graph[toModel].parent][toModel];\n\n\tlet cur = graph[toModel].parent;\n\twhile (graph[cur].parent) {\n\t\tpath.unshift(graph[cur].parent);\n\t\tfn = link(conversions[graph[cur].parent][cur], fn);\n\t\tcur = graph[cur].parent;\n\t}\n\n\tfn.conversion = path;\n\treturn fn;\n}\n\nmodule.exports = function (fromModel) {\n\tconst graph = deriveBFS(fromModel);\n\tconst conversion = {};\n\n\tconst models = Object.keys(graph);\n\tfor (let len = models.length, i = 0; i < len; i++) {\n\t\tconst toModel = models[i];\n\t\tconst node = graph[toModel];\n\n\t\tif (node.parent === null) {\n\t\t\t// No possible conversion, or this node is the source model.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconversion[toModel] = wrapConversion(toModel, graph);\n\t}\n\n\treturn conversion;\n};\n\n", + "'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n", + "require('../modules/es6.math.acosh');\nrequire('../modules/es6.math.asinh');\nrequire('../modules/es6.math.atanh');\nrequire('../modules/es6.math.cbrt');\nrequire('../modules/es6.math.clz32');\nrequire('../modules/es6.math.cosh');\nrequire('../modules/es6.math.expm1');\nrequire('../modules/es6.math.fround');\nrequire('../modules/es6.math.hypot');\nrequire('../modules/es6.math.imul');\nrequire('../modules/es6.math.log10');\nrequire('../modules/es6.math.log1p');\nrequire('../modules/es6.math.log2');\nrequire('../modules/es6.math.sign');\nrequire('../modules/es6.math.sinh');\nrequire('../modules/es6.math.tanh');\nrequire('../modules/es6.math.trunc');\nmodule.exports = require('../modules/_core').Math;\n", + "require('../modules/es6.number.constructor');\nrequire('../modules/es6.number.to-fixed');\nrequire('../modules/es6.number.to-precision');\nrequire('../modules/es6.number.epsilon');\nrequire('../modules/es6.number.is-finite');\nrequire('../modules/es6.number.is-integer');\nrequire('../modules/es6.number.is-nan');\nrequire('../modules/es6.number.is-safe-integer');\nrequire('../modules/es6.number.max-safe-integer');\nrequire('../modules/es6.number.min-safe-integer');\nrequire('../modules/es6.number.parse-float');\nrequire('../modules/es6.number.parse-int');\nmodule.exports = require('../modules/_core').Number;\n", + "module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n", + "var cof = require('./_cof');\nmodule.exports = function (it, msg) {\n if (typeof it != 'number' && cof(it) != 'Number') throw TypeError(msg);\n return +it;\n};\n", + "var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n", + "// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject');\nvar toLength = require('./_to-length');\nvar toAbsoluteIndex = require('./_to-absolute-index');\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n", + "var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n", + "var core = module.exports = { version: '2.5.7' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n", + "// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n", + "// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n", + "// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n", + "var isObject = require('./_is-object');\nvar document = require('./_global').document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n return is ? document.createElement(it) : {};\n};\n", + "// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n", + "var global = require('./_global');\nvar core = require('./_core');\nvar hide = require('./_hide');\nvar redefine = require('./_redefine');\nvar ctx = require('./_ctx');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n var key, own, out, exp;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n // export native or passed\n out = (own ? target : source)[key];\n // bind timers to global for call from export context\n exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // extend global\n if (target) redefine(target, key, out, type & $export.U);\n // export\n if (exports[key] != out) hide(exports, key, exp);\n if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `) + ("`" + `library`))))) + (((("`" + (`\nmodule.exports = $export;\n", + "module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n", + "// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n", + "var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n", + "var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n", + "var document = require('./_global').document;\nmodule.exports = document && document.documentElement;\n", + "module.exports = !require('./_descriptors') && !require('./_fails')(function () {\n return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n", + "var isObject = require('./_is-object');\nvar setPrototypeOf = require('./_set-proto').set;\nmodule.exports = function (that, target, C) {\n var S = target.constructor;\n var P;\n if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {\n setPrototypeOf(that, P);\n } return that;\n};\n", + "// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n", + "// 20.1.2.3 Number.isInteger(number)\nvar isObject = require('./_is-object');\nvar floor = Math.floor;\nmodule.exports = function isInteger(it) {\n return !isObject(it) && isFinite(it) && floor(it) === it;\n};\n", + "module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n", + "module.exports = false;\n", + "// 20.2.2.14 Math.expm1(x)\nvar $expm1 = Math.expm1;\nmodule.exports = (!$expm1\n // Old FF bug\n || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168\n // Tor Browser bug\n || $expm1(-2e-17) != -2e-17\n) ? function expm1(x) {\n return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;\n} : $expm1;\n", + "// 20.2.2.16 Math.fround(x)\nvar sign = require('./_math-sign');\nvar pow = Math.pow;\nvar EPSILON = pow(2, -52);\nvar EPSILON32 = pow(2, -23);\nvar MAX32 = pow(2, 127) * (2 - EPSILON32);\nvar MIN32 = pow(2, -126);\n\nvar roundTiesToEven = function (n) {\n return n + 1 / EPSILON - 1 / EPSILON;\n};\n\nmodule.exports = Math.fround || function fround(x) {\n var $abs = Math.abs(x);\n var $sign = sign(x);\n var a, result;\n if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;\n a = (1 + EPSILON32 / EPSILON) * $abs;\n result = a - (a - $abs);\n // eslint-disable-next-line no-self-compare\n if (result > MAX32 || result != result) return $sign * Infinity;\n return $sign * result;\n};\n", + "// 20.2.2.20 Math.log1p(x)\nmodule.exports = Math.log1p || function log1p(x) {\n return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);\n};\n", + "// 20.2.2.28 Math.sign(x)\nmodule.exports = Math.sign || function sign(x) {\n // eslint-disable-next-line no-self-compare\n return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;\n};\n", + "// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake ` + "`")) + (`null` + ("`" + ` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n", + "var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n", + "var dP = require('./_object-dp');\nvar anObject = require('./_an-object');\nvar getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = getKeys(Properties);\n var length = keys.length;\n var i = 0;\n var P;\n while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n", + "var pIE = require('./_object-pie');\nvar createDesc = require('./_property-desc');\nvar toIObject = require('./_to-iobject');\nvar toPrimitive = require('./_to-primitive');\nvar has = require('./_has');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {\n O = toIObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return gOPD(O, P);\n } catch (e) { /* empty */ }\n if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n", + "// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal');\nvar hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return $keys(O, hiddenKeys);\n};\n", + "var has = require('./_has');\nvar toIObject = require('./_to-iobject');\nvar arrayIndexOf = require('./_array-includes')(false);\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function (object, names) {\n var O = toIObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n", + "// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n", + "exports.f = {}.propertyIsEnumerable;\n", + "var $parseFloat = require('./_global').parseFloat;\nvar $trim = require('./_string-trim').trim;\n\nmodule.exports = 1 / $parseFloat(require('./_string-ws') + '-0') !== -Infinity ? function parseFloat(str) {\n var string = $trim(String(str), 3);\n var result = $parseFloat(string);\n return result === 0 && string.charAt(0) == '-' ? -0 : result;\n} : $parseFloat;\n", + "var $parseInt = require('./_global').parseInt;\nvar $trim = require('./_string-trim').trim;\nvar ws = require('./_string-ws');\nvar hex = /^[-+]?0[xX]/;\n\nmodule.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {\n var string = $trim(String(str), 3);\n return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));\n} : $parseInt;\n", + "module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n", + "var global = require('./_global');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar SRC = require('./_uid')('src');\nvar TO_STRING = 'toString';\nvar $toString = Function[TO_STRING];\nvar TPL = ('' + $toString).split(TO_STRING);\n\nrequire('./_core').inspectSource = function (it) {\n return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n var isFunction = typeof val == 'function';\n if (isFunction) has(val, 'name') || hide(val, 'name', key);\n if (O[key] === val) return;\n if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n if (O === global) {\n O[key] = val;\n } else if (!safe) {\n delete O[key];\n hide(O, key, val);\n } else if (O[key]) {\n O[key] = val;\n } else {\n hide(O, key, val);\n }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n", + "// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = require('./_is-object');\nvar anObject = require('./_an-object');\nvar check = function (O, proto) {\n anObject(O);\n if (!isObject(proto) && proto !== null) throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n function (test, buggy, set) {\n try {\n set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);\n set(test, []);\n buggy = !(test instanceof Array);\n } catch (e) { buggy = true; }\n return function setPrototypeOf(O, proto) {\n check(O, proto);\n if (buggy) O.__proto__ = proto;\n else set(O, proto);\n return O;\n };\n }({}, false) : undefined),\n check: check\n};\n", + "var shared = require('./_shared')('keys');\nvar uid = require('./_uid');\nmodule.exports = function (key) {\n return shared[key] || (shared[key] = uid(key));\n};\n", + "var core = require('./_core');\nvar global = require('./_global');\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: core.version,\n mode: require('./_library') ? 'pure' : 'global',\n copyright: '© 2018 Denis Pushkarev (zloirock.ru)'\n});\n", + "'use strict';\nvar toInteger = require('./_to-integer');\nvar defined = require('./_defined');\n\nmodule.exports = function repeat(count) {\n var str = String(defined(this));\n var res = '';\n var n = toInteger(count);\n if (n < 0 || n == Infinity) throw RangeError(\"Count can't be negative\");\n for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;\n return res;\n};\n", + "var $export = require('./_export');\nvar defined = require('./_defined');\nvar fails = require('./_fails');\nvar spaces = require('./_string-ws');\nvar space = '[' + spaces + ']';\nvar non = '\\u200b\\u0085';\nvar ltrim = RegExp('^' + space + space + '*');\nvar rtrim = RegExp(space + space + '*$');\n\nvar exporter = function (KEY, exec, ALIAS) {\n var exp = {};\n var FORCE = fails(function () {\n return !!spaces[KEY]() || non[KEY]() != non;\n });\n var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];\n if (ALIAS) exp[ALIAS] = fn;\n $export($export.P + $export.F * FORCE, 'String', exp);\n};\n\n// 1 -> String#trimLeft\n// 2 -> String#trimRight\n// 3 -> String#trim\nvar trim = exporter.trim = function (string, TYPE) {\n string = String(defined(string));\n if (TYPE & 1) string = string.replace(ltrim, '');\n if (TYPE & 2) string = string.replace(rtrim, '');\n return string;\n};\n\nmodule.exports = exporter;\n", + "module.exports = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n", + "var toInteger = require('./_to-integer');\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n", + "// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n", + "// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n", + "// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n", + "// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n if (!isObject(it)) return it;\n var fn, val;\n if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n", + "var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n", + "// 20.2.2.3 Math.acosh(x)\nvar $export = require('./_export');\nvar log1p = require('./_math-log1p');\nvar sqrt = Math.sqrt;\nvar $acosh = Math.acosh;\n\n$export($export.S + $export.F * !($acosh\n // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509\n && Math.floor($acosh(Number.MAX_VALUE)) == 710\n // Tor Browser bug: Math.acosh(Infinity) -> NaN\n && $acosh(Infinity) == Infinity\n), 'Math', {\n acosh: function acosh(x) {\n return (x = +x) < 1 ? NaN : x > 94906265.62425156\n ? Math.log(x) + Math.LN2\n : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));\n }\n});\n", + "// 20.2.2.5 Math.asinh(x)\nvar $export = require('./_export');\nvar $asinh = Math.asinh;\n\nfunction asinh(x) {\n return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));\n}\n\n// Tor Browser bug: Math.asinh(0) -> -0\n$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh });\n", + "// 20.2.2.7 Math.atanh(x)\nvar $export = require('./_export');\nvar $atanh = Math.atanh;\n\n// Tor Browser bug: Math.atanh(-0) -> 0\n$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {\n atanh: function atanh(x) {\n return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;\n }\n});\n", + "// 20.2.2.9 Math.cbrt(x)\nvar $export = require('./_export');\nvar sign = require('./_math-sign');\n\n$export($export.S, 'Math', {\n cbrt: function cbrt(x) {\n return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);\n }\n});\n", + "// 20.2.2.11 Math.clz32(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n clz32: function clz32(x) {\n return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;\n }\n});\n", + "// 20.2.2.12 Math.cosh(x)\nvar $export = require('./_export');\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n cosh: function cosh(x) {\n return (exp(x = +x) + exp(-x)) / 2;\n }\n});\n", + "// 20.2.2.14 Math.expm1(x)\nvar $export = require('./_export');\nvar $expm1 = require('./_math-expm1');\n\n$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 });\n", + "// 20.2.2.16 Math.fround(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', { fround: require('./_math-fround') });\n", + "// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])\nvar $export = require('./_export');\nvar abs = Math.abs;\n\n$export($export.S, 'Math', {\n hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars\n var sum = 0;\n var i = 0;\n var aLen = arguments.length;\n var larg = 0;\n var arg, div;\n while (i < aLen) {\n arg = abs(arguments[i++]);\n if (larg < arg) {\n div = larg / arg;\n sum = sum * div * div + 1;\n larg = arg;\n } else if (arg > 0) {\n div = arg / larg;\n sum += div * div;\n } else sum += arg;\n }\n return larg === Infinity ? Infinity : larg * Math.sqrt(sum);\n }\n});\n", + "// 20.2.2.18 Math.imul(x, y)\nvar $export = require('./_export');\nvar $imul = Math.imul;\n\n// some WebKit versions fails with big numbers, some has wrong arity\n$export($export.S + $export.F * require('./_fails')(function () {\n return $imul(0xffffffff, 5) != -5 || $imul.length != 2;\n}), 'Math', {\n imul: function imul(x, y) {\n var UINT16 = 0xffff;\n var xn = +x;\n var yn = +y;\n var xl = UINT16 & xn;\n var yl = UINT16 & yn;\n return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);\n }\n});\n", + "// 20.2.2.21 Math.log10(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n log10: function log10(x) {\n return Math.log(x) * Math.LOG10E;\n }\n});\n", + "// 20.2.2.20 Math.log1p(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', { log1p: require('./_math-log1p') });\n", + "// 20.2.2.22 Math.log2(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n log2: function log2(x) {\n return Math.log(x) / Math.LN2;\n }\n});\n", + "// 20.2.2.28 Math.sign(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', { sign: require('./_math-sign') });\n", + "// 20.2.2.30 Math.sinh(x)\nvar $export = require('./_export');\nvar expm1 = require('./_math-expm1');\nvar exp = Math.exp;\n\n// V8 near Chromium 38 has a problem with very small numbers\n$export($export.S + $export.F * require('./_fails')(function () {\n return !Math.sinh(-2e-17) != -2e-17;\n}), 'Math', {\n sinh: function sinh(x) {\n return Math.abs(x = +x) < 1\n ? (expm1(x) - expm1(-x)) / 2\n : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);\n }\n});\n", + "// 20.2.2.33 Math.tanh(x)\nvar $export = require('./_export');\nvar expm1 = require('./_math-expm1');\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n tanh: function tanh(x) {\n var a = expm1(x = +x);\n var b = expm1(-x);\n return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));\n }\n});\n", + "// 20.2.2.34 Math.trunc(x)\nvar $export = require('./_export');\n\n$export($export.S, 'Math', {\n trunc: function trunc(it) {\n return (it > 0 ? Math.floor : Math.ceil)(it);\n }\n});\n", + "'use strict';\nvar global = require('./_global');\nvar has = require('./_has');\nvar cof = require('./_cof');\nvar inheritIfRequired = require('./_inherit-if-required');\nvar toPrimitive = require('./_to-primitive');\nvar fails = require('./_fails');\nvar gOPN = require('./_object-gopn').f;\nvar gOPD = require('./_object-gopd').f;\nvar dP = require('./_object-dp').f;\nvar $trim = require('./_string-trim').trim;\nvar NUMBER = 'Number';\nvar $Number = global[NUMBER];\nvar Base = $Number;\nvar proto = $Number.prototype;\n// Opera ~12 has broken Object#toString\nvar BROKEN_COF = cof(require('./_object-create')(proto)) == NUMBER;\nvar TRIM = 'trim' in String.prototype;\n\n// 7.1.3 ToNumber(argument)\nvar toNumber = function (argument) {\n var it = toPrimitive(argument, false);\n if (typeof it == 'string' && it.length > 2) {\n it = TRIM ? it.trim() : $trim(it, 3);\n var first = it.charCodeAt(0);\n var third, radix, maxCode;\n if (first === 43 || first === 45) {\n third = it.charCodeAt(2);\n if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n } else if (first === 48) {\n switch (it.charCodeAt(1)) {\n case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i\n case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i\n default: return +it;\n }\n for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {\n code = digits.charCodeAt(i);\n // parseInt parses a string to a first unavailable symbol\n // but ToNumber should return NaN if a string contains unavailable symbols\n if (code < 48 || code > maxCode) return NaN;\n } return parseInt(digits, radix);\n }\n } return +it;\n};\n\nif (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {\n $Number = function Number(value) {\n var it = arguments.length < 1 ? 0 : value;\n var that = this;\n return that instanceof $Number\n // check on 1..constructor(foo) case\n && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)\n ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);\n };\n for (var keys = require('./_descriptors') ? gOPN(Base) : (\n // ES3:\n 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n // ES6 (in case, if modules with ES6 Number statics required before):\n 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n ).split(','), j = 0, key; keys.length > j; j++) {\n if (has(Base, key = keys[j]) && !has($Number, key)) {\n dP($Number, key, gOPD(Base, key));\n }\n }\n $Number.prototype = proto;\n proto.constructor = $Number;\n require('./_redefine')(global, NUMBER, $Number);\n}\n", + "// 20.1.2.1 Number.EPSILON\nvar $export = require('./_export');\n\n$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });\n", + "// 20.1.2.2 Number.isFinite(number)\nvar $export = require('./_export');\nvar _isFinite = require('./_global').isFinite;\n\n$export($export.S, 'Number', {\n isFinite: function isFinite(it) {\n return typeof it == 'number' && _isFinite(it);\n }\n});\n", + "// 20.1.2.3 Number.isInteger(number)\nvar $export = require('./_export');\n\n$export($export.S, 'Number', { isInteger: require('./_is-integer') });\n", + "// 20.1.2.4 Number.isNaN(number)\nvar $export = require('./_export');\n\n$export($export.S, 'Number', {\n isNaN: function isNaN(number) {\n // eslint-disable-next-line no-self-compare\n return number != number;\n }\n});\n", + "// 20.1.2.5 Number.isSafeInteger(number)\nvar $export = require('./_export');\nvar isInteger = require('./_is-integer');\nvar abs = Math.abs;\n\n$export($export.S, 'Number', {\n isSafeInteger: function isSafeInteger(number) {\n return isInteger(number) && abs(number) <= 0x1fffffffffffff;\n }\n});\n", + "// 20.1.2.6 Number.MAX_SAFE_INTEGER\nvar $export = require('./_export');\n\n$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });\n", + "// 20.1.2.10 Number.MIN_SAFE_INTEGER\nvar $export = require('./_export');\n\n$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });\n", + "var $export = require('./_export');\nvar $parseFloat = require('./_parse-float');\n// 20.1.2.12 Number.parseFloat(string)\n$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat });\n", + "var $export = require('./_export');\nvar $parseInt = require('./_parse-int');\n// 20.1.2.13 Number.parseInt(string, radix)\n$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt });\n", + "'use strict';\nvar $export = require('./_export');\nvar toInteger = require('./_to-integer');\nvar aNumberValue = require('./_a-number-value');\nvar repeat = require('./_string-repeat');\nvar $toFixed = 1.0.toFixed;\nvar floor = Math.floor;\nvar data = [0, 0, 0, 0, 0, 0];\nvar ERROR = 'Number.toFixed: incorrect invocation!';\nvar ZERO = '0';\n\nvar multiply = function (n, c) {\n var i = -1;\n var c2 = c;\n while (++i < 6) {\n c2 += n * data[i];\n data[i] = c2 % 1e7;\n c2 = floor(c2 / 1e7);\n }\n};\nvar divide = function (n) {\n var i = 6;\n var c = 0;\n while (--i >= 0) {\n c += data[i];\n data[i] = floor(c / n);\n c = (c % n) * 1e7;\n }\n};\nvar numToString = function () {\n var i = 6;\n var s = '';\n while (--i >= 0) {\n if (s !== '' || i === 0 || data[i] !== 0) {\n var t = String(data[i]);\n s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;\n }\n } return s;\n};\nvar pow = function (x, n, acc) {\n return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);\n};\nvar log = function (x) {\n var n = 0;\n var x2 = x;\n while (x2 >= 4096) {\n n += 12;\n x2 /= 4096;\n }\n while (x2 >= 2) {\n n += 1;\n x2 /= 2;\n } return n;\n};\n\n$export($export.P + $export.F * (!!$toFixed && (\n 0.00008.toFixed(3) !== '0.000' ||\n 0.9.toFixed(0) !== '1' ||\n 1.255.toFixed(2) !== '1.25' ||\n 1000000000000000128.0.toFixed(0) !== '1000000000000000128'\n) || !require('./_fails')(function () {\n // V8 ~ Android 4.3-\n $toFixed.call({});\n})), 'Number', {\n toFixed: function toFixed(fractionDigits) {\n var x = aNumberValue(this, ERROR);\n var f = toInteger(fractionDigits);\n var s = '';\n var m = ZERO;\n var e, z, j, k;\n if (f < 0 || f > 20) throw RangeError(ERROR);\n // eslint-disable-next-line no-self-compare\n if (x != x) return 'NaN';\n if (x <= -1e21 || x >= 1e21) return String(x);\n if (x < 0) {\n s = '-';\n x = -x;\n }\n if (x > 1e-21) {\n e = log(x * pow(2, 69, 1)) - 69;\n z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);\n z *= 0x10000000000000;\n e = 52 - e;\n if (e > 0) {\n multiply(0, z);\n j = f;\n while (j >= 7) {\n multiply(1e7, 0);\n j -= 7;\n }\n multiply(pow(10, j, 1), 0);\n j = e - 1;\n while (j >= 23) {\n divide(1 << 23);\n j -= 23;\n }\n divide(1 << j);\n multiply(1, 1);\n divide(2);\n m = numToString();\n } else {\n multiply(0, z);\n multiply(1 << -e, 0);\n m = numToString() + repeat.call(ZERO, f);\n }\n }\n if (f > 0) {\n k = m.length;\n m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));\n } else {\n m = s + m;\n } return m;\n }\n});\n", + "'use strict';\nvar $export = require('./_export');\nvar $fails = require('./_fails');\nvar aNumberValue = require('./_a-number-value');\nvar $toPrecision = 1.0.toPrecision;\n\n$export($export.P + $export.F * ($fails(function () {\n // IE7-\n return $toPrecision.call(1, undefined) !== '1';\n}) || !$fails(function () {\n // V8 ~ Android 4.3-\n $toPrecision.call({});\n})), 'Number', {\n toPrecision: function toPrecision(precision) {\n var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');\n return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision);\n }\n});\n", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = camelize;\nvar regExp = /[-\\s]+(.)?/g;\n\n/**\n * Convert dash separated strings to camel cased.\n *\n * @param {String} str\n * @return {String}\n */\nfunction camelize(str) {\n return str.replace(regExp, toUpper);\n}\n\nfunction toUpper(match, c) {\n return c ? c.toUpperCase() : '';\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.supportedValue = exports.supportedProperty = exports.prefix = undefined;\n\nvar _prefix = require('./prefix');\n\nvar _prefix2 = _interopRequireDefault(_prefix);\n\nvar _supportedProperty = require('./supported-property');\n\nvar _supportedProperty2 = _interopRequireDefault(_supportedProperty);\n\nvar _supportedValue = require('./supported-value');\n\nvar _supportedValue2 = _interopRequireDefault(_supportedValue);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nexports['default'] = {\n prefix: _prefix2['default'],\n supportedProperty: _supportedProperty2['default'],\n supportedValue: _supportedValue2['default']\n}; /**\n * CSS Vendor prefix detection and property feature testing.\n *\n * @copyright Oleg Slobodskoi 2015\n * @website https://github.com/jsstyles/css-vendor\n * @license MIT\n */\n\nexports.prefix = _prefix2['default'];\nexports.supportedProperty = _supportedProperty2['default'];\nexports.supportedValue = _supportedValue2['default'];", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _isInBrowser = require('is-in-browser');\n\nvar _isInBrowser2 = _interopRequireDefault(_isInBrowser);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar js = ''; /**\n * Export javascript style and css style vendor prefixes.\n * Based on \"transform\" support test.\n */\n\nvar css = '';\n\n// We should not do anything if required serverside.\nif (_isInBrowser2['default']) {\n // Order matters. We need to check Webkit the last one because\n // other vendors use to add Webkit prefixes to some properties\n var jsCssMap = {\n Moz: '-moz-',\n // IE did it wrong again ...\n ms: '-ms-',\n O: '-o-',\n Webkit: '-webkit-'\n };\n var style = document.createElement('p').style;\n var testProp = 'Transform';\n\n for (var key in jsCssMap) {\n if (key + testProp in style) {\n js = key;\n css = jsCssMap[key];\n break;\n }\n }\n}\n\n/**\n * Vendor prefix string for the current browser.\n *\n * @type {{js: String, css: String}}\n * @api public\n */\nexports['default'] = { js: js, css: css };", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = supportedProperty;\n\nvar _isInBrowser = require('is-in-browser');\n\nvar _isInBrowser2 = _interopRequireDefault(_isInBrowser);\n\nvar _prefix = require('./prefix');\n\nvar _prefix2 = _interopRequireDefault(_prefix);\n\nvar _camelize = require('./camelize');\n\nvar _camelize2 = _interopRequireDefault(_camelize);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar el = void 0;\nvar cache = {};\n\nif (_isInBrowser2['default']) {\n el = document.createElement('p');\n\n /**\n * We test every property on vendor prefix requirement.\n * Once tested, result is cached. It gives us up to 70% perf boost.\n * http://jsperf.com/element-style-object-access-vs-plain-object\n *\n * Prefill cache with known css properties to reduce amount of\n * properties we need to feature test at runtime.\n * http://davidwalsh.name/vendor-prefix\n */\n var computed = window.getComputedStyle(document.documentElement, '');\n for (var key in computed) {\n if (!isNaN(key)) cache[computed[key]] = computed[key];\n }\n}\n\n/**\n * Test if a property is supported, returns supported property with vendor\n * prefix if required. Returns `))) + (("`" + (`false` + "`")) + (` if not supported.\n *\n * @param {String} prop dash separated\n * @return {String|Boolean}\n * @api public\n */\nfunction supportedProperty(prop) {\n // For server-side rendering.\n if (!el) return prop;\n\n // We have not tested this prop yet, lets do the test.\n if (cache[prop] != null) return cache[prop];\n\n // Camelization is required because we can't test using\n // css syntax for e.g. in FF.\n // Test if property is supported as it is.\n if ((0, _camelize2['default'])(prop) in el.style) {\n cache[prop] = prop;\n }\n // Test if property is supported with vendor prefix.\n else if (_prefix2['default'].js + (0, _camelize2['default'])('-' + prop) in el.style) {\n cache[prop] = _prefix2['default'].css + prop;\n } else {\n cache[prop] = false;\n }\n\n return cache[prop];\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = supportedValue;\n\nvar _isInBrowser = require('is-in-browser');\n\nvar _isInBrowser2 = _interopRequireDefault(_isInBrowser);\n\nvar _prefix = require('./prefix');\n\nvar _prefix2 = _interopRequireDefault(_prefix);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar cache = {};\nvar el = void 0;\n\nif (_isInBrowser2['default']) el = document.createElement('p');\n\n/**\n * Returns prefixed value if needed. Returns ` + ("`" + `false`)))) + ((("`" + (` if value is not supported.\n *\n * @param {String} property\n * @param {String} value\n * @return {String|Boolean}\n * @api public\n */\nfunction supportedValue(property, value) {\n // For server-side rendering.\n if (!el) return value;\n\n // It is a string or a number as a string like '1'.\n // We want only prefixable values here.\n if (typeof value !== 'string' || !isNaN(parseInt(value, 10))) return value;\n\n var cacheKey = property + value;\n\n if (cache[cacheKey] != null) return cache[cacheKey];\n\n // IE can even throw an error in some cases, for e.g. style.content = 'bar'\n try {\n // Test value as it is.\n el.style[property] = value;\n } catch (err) {\n cache[cacheKey] = false;\n return false;\n }\n\n // Value is supported as it is.\n if (el.style[property] !== '') {\n cache[cacheKey] = value;\n } else {\n // Test value with vendor prefix.\n value = _prefix2['default'].css + value;\n\n // Hardcode test to convert \"flex\" to \"-ms-flexbox\" for IE10.\n if (value === '-ms-flex') value = '-ms-flexbox';\n\n el.style[property] = value;\n\n // Value is supported with vendor prefix.\n if (el.style[property] !== '') cache[cacheKey] = value;\n }\n\n if (!cache[cacheKey]) cache[cacheKey] = false;\n\n // Reset style value.\n el.style[property] = '';\n\n return cache[cacheKey];\n}", + "export default function(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n", + "import ascending from \"./ascending\";\n\nexport default function(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n}\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n", + "import ascending from \"./ascending\";\nimport bisector from \"./bisector\";\n\nvar ascendingBisect = bisector(ascending);\nexport var bisectRight = ascendingBisect.right;\nexport var bisectLeft = ascendingBisect.left;\nexport default bisectRight;\n", + "import {pair} from \"./pairs\";\n\nexport default function(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n}\n", + "export default function(x) {\n return x === null ? NaN : +x;\n}\n", + "var array = Array.prototype;\n\nexport var slice = array.slice;\nexport var map = array.map;\n", + "export default function(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n}\n", + "var e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\nexport default function(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nexport function tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n", + "export default function(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n}\n", + "import number from \"./number\";\n\nexport default function(values, p, valueof) {\n if (valueof == null) valueof = number;\n if (!(n = values.length)) return;\n if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n}\n", + "export var prefix = \"$\";\n\nfunction Map() {}\n\nMap.prototype = map.prototype = {\n constructor: Map,\n has: function(key) {\n return (prefix + key) in this;\n },\n get: function(key) {\n return this[prefix + key];\n },\n set: function(key, value) {\n this[prefix + key] = value;\n return this;\n },\n remove: function(key) {\n var property = prefix + key;\n return property in this && delete this[property];\n },\n clear: function() {\n for (var property in this) if (property[0] === prefix) delete this[property];\n },\n keys: function() {\n var keys = [];\n for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));\n return keys;\n },\n values: function() {\n var values = [];\n for (var property in this) if (property[0] === prefix) values.push(this[property]);\n return values;\n },\n entries: function() {\n var entries = [];\n for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});\n return entries;\n },\n size: function() {\n var size = 0;\n for (var property in this) if (property[0] === prefix) ++size;\n return size;\n },\n empty: function() {\n for (var property in this) if (property[0] === prefix) return false;\n return true;\n },\n each: function(f) {\n for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);\n }\n};\n\nfunction map(object, f) {\n var map = new Map;\n\n // Copy constructor.\n if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });\n\n // Index array by numeric index or specified key function.\n else if (Array.isArray(object)) {\n var i = -1,\n n = object.length,\n o;\n\n if (f == null) while (++i < n) map.set(i, object[i]);\n else while (++i < n) map.set(f(o = object[i], i, object), o);\n }\n\n // Convert object to map.\n else if (object) for (var key in object) map.set(key, object[key]);\n\n return map;\n}\n\nexport default map;\n", + "import {default as map, prefix} from \"./map\";\n\nfunction Set() {}\n\nvar proto = map.prototype;\n\nSet.prototype = set.prototype = {\n constructor: Set,\n has: proto.has,\n add: function(value) {\n value += \"\";\n this[prefix + value] = value;\n return this;\n },\n remove: proto.remove,\n clear: proto.clear,\n values: proto.keys,\n size: proto.size,\n empty: proto.empty,\n each: proto.each\n};\n\nfunction set(object, f) {\n var set = new Set;\n\n // Copy constructor.\n if (object instanceof Set) object.each(function(value) { set.add(value); });\n\n // Otherwise, assume it’s an array.\n else if (object) {\n var i = -1, n = object.length;\n if (f == null) while (++i < n) set.add(object[i]);\n else while (++i < n) set.add(f(object[i], i, object));\n }\n\n return set;\n}\n\nexport default set;\n", + "var array = Array.prototype;\n\nexport var map = array.map;\nexport var slice = array.slice;\n", + "import {map} from \"d3-collection\";\nimport {slice} from \"./array\";\n\nexport var implicit = {name: \"implicit\"};\n\nexport default function ordinal(range) {\n var index = map(),\n domain = [],\n unknown = implicit;\n\n range = range == null ? [] : slice.call(range);\n\n function scale(d) {\n var key = d + \"\", i = index.get(key);\n if (!i) {\n if (unknown !== implicit) return unknown;\n index.set(key, i = domain.push(d));\n }\n return range[(i - 1) % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = map();\n var i = -1, n = _.length, d, key;\n while (++i < n) if (!index.has(key = (d = _[i]) + \"\")) index.set(key, domain.push(d));\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal()\n .domain(domain)\n .range(range)\n .unknown(unknown);\n };\n\n return scale;\n}\n", + "import {range as sequence} from \"d3-array\";\nimport ordinal from \"./ordinal\";\n\nexport default function band() {\n var scale = ordinal().unknown(undefined),\n domain = scale.domain,\n ordinalRange = scale.range,\n range = [0, 1],\n step,\n bandwidth,\n round = false,\n paddingInner = 0,\n paddingOuter = 0,\n align = 0.5;\n\n delete scale.unknown;\n\n function rescale() {\n var n = domain().length,\n reverse = range[1] < range[0],\n start = range[reverse - 0],\n stop = range[1 - reverse];\n step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n if (round) step = Math.floor(step);\n start += (stop - start - step * (n - paddingInner)) * align;\n bandwidth = step * (1 - paddingInner);\n if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n var values = sequence(n).map(function(i) { return start + step * i; });\n return ordinalRange(reverse ? values.reverse() : values);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = [+_[0], +_[1]], rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = [+_[0], +_[1]], round = true, rescale();\n };\n\n scale.bandwidth = function() {\n return bandwidth;\n };\n\n scale.step = function() {\n return step;\n };\n\n scale.round = function(_) {\n return arguments.length ? (round = !!_, rescale()) : round;\n };\n\n scale.padding = function(_) {\n return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingInner = function(_) {\n return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n };\n\n scale.paddingOuter = function(_) {\n return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;\n };\n\n scale.align = function(_) {\n return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n };\n\n scale.copy = function() {\n return band()\n .domain(domain())\n .range(range)\n .round(round)\n .paddingInner(paddingInner)\n .paddingOuter(paddingOuter)\n .align(align);\n };\n\n return rescale();\n}\n\nfunction pointish(scale) {\n var copy = scale.copy;\n\n scale.padding = scale.paddingOuter;\n delete scale.paddingInner;\n delete scale.paddingOuter;\n\n scale.copy = function() {\n return pointish(copy());\n };\n\n return scale;\n}\n\nexport function point() {\n return pointish(band().paddingInner(1));\n}\n", + "export default function(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n", + "import define, {extend} from \"./define\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n reN = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n reP = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n reHex3 = /^#([0-9a-f]{3})$/,\n reHex6 = /^#([0-9a-f]{6})$/,\n reRgbInteger = new RegExp(\"^rgb\\\\(\" + [reI, reI, reI] + \"\\\\)$\"),\n reRgbPercent = new RegExp(\"^rgb\\\\(\" + [reP, reP, reP] + \"\\\\)$\"),\n reRgbaInteger = new RegExp(\"^rgba\\\\(\" + [reI, reI, reI, reN] + \"\\\\)$\"),\n reRgbaPercent = new RegExp(\"^rgba\\\\(\" + [reP, reP, reP, reN] + \"\\\\)$\"),\n reHslPercent = new RegExp(\"^hsl\\\\(\" + [reN, reP, reP] + \"\\\\)$\"),\n reHslaPercent = new RegExp(\"^hsla\\\\(\" + [reN, reP, reP, reN] + \"\\\\)$\");\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n displayable: function() {\n return this.rgb().displayable();\n },\n hex: function() {\n return this.rgb().hex();\n },\n toString: function() {\n return this.rgb() + \"\";\n }\n});\n\nexport default function color(format) {\n var m;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00\n : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format])\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb: function() {\n return this;\n },\n displayable: function() {\n return (0 <= this.r && this.r <= 255)\n && (0 <= this.g && this.g <= 255)\n && (0 <= this.b && this.b <= 255)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n hex: function() {\n return \"#\" + hex(this.r) + hex(this.g) + hex(this.b);\n },\n toString: function() {\n var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n return (a === 1 ? \"rgb(\" : \"rgba(\")\n + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + \", \"\n + Math.max(0, Math.min(255, Math.round(this.b) || 0))\n + (a === 1 ? \")\" : \", \" + a + \")\");\n }\n}));\n\nfunction hex(value) {\n value = Math.max(0, Math.min(255, Math.round(value) || 0));\n return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n displayable: function() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n }\n}));\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n", + "export var deg2rad = Math.PI / 180;\nexport var rad2deg = 180 / Math.PI;\n", + "import define, {extend} from \"./define\";\nimport {Color, rgbConvert, Rgb} from \"./color\";\nimport {deg2rad, rad2deg} from \"./math\";\n\n// https://beta.observablehq.com/@mbostock/lab-and-rgb\nvar K = 18,\n Xn = 0.96422,\n Yn = 1,\n Zn = 0.82521,\n t0 = 4 / 29,\n t1 = 6 / 29,\n t2 = 3 * t1 * t1,\n t3 = t1 * t1 * t1;\n\nfunction labConvert(o) {\n if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);\n if (o instanceof Hcl) {\n if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);\n var h = o.h * deg2rad;\n return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);\n }\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var r = rgb2lrgb(o.r),\n g = rgb2lrgb(o.g),\n b = rgb2lrgb(o.b),\n y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z;\n if (r === g && g === b) x = z = y; else {\n x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);\n z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);\n }\n return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);\n}\n\nexport function gray(l, opacity) {\n return new Lab(l, 0, 0, opacity == null ? 1 : opacity);\n}\n\nexport default function lab(l, a, b, opacity) {\n return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);\n}\n\nexport function Lab(l, a, b, opacity) {\n this.l = +l;\n this.a = +a;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Lab, lab, extend(Color, {\n brighter: function(k) {\n return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n darker: function(k) {\n return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);\n },\n rgb: function() {\n var y = (this.l + 16) / 116,\n x = isNaN(this.a) ? y : y + this.a / 500,\n z = isNaN(this.b) ? y : y - this.b / 200;\n x = Xn * lab2xyz(x);\n y = Yn * lab2xyz(y);\n z = Zn * lab2xyz(z);\n return new Rgb(\n lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),\n lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),\n lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),\n this.opacity\n );\n }\n}));\n\nfunction xyz2lab(t) {\n return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t) {\n return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction lrgb2rgb(x) {\n return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2lrgb(x) {\n return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\nfunction hclConvert(o) {\n if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);\n if (!(o instanceof Lab)) o = labConvert(o);\n if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0, o.l, o.opacity);\n var h = Math.atan2(o.b, o.a) * rad2deg;\n return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);\n}\n\nexport function lch(l, c, h, opacity) {\n return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nexport function hcl(h, c, l, opacity) {\n return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nexport function Hcl(h, c, l, opacity) {\n this.h = +h;\n this.c = +c;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hcl, hcl, extend(Color, {\n brighter: function(k) {\n return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);\n },\n darker: function(k) {\n return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);\n },\n rgb: function() {\n return labConvert(this).rgb();\n }\n}));\n", + "import define, {extend} from \"./define\";\nimport {Color, rgbConvert, Rgb, darker, brighter} from \"./color\";\nimport {deg2rad, rad2deg} from \"./math\";\n\nvar A = -0.14861,\n B = +1.78277,\n C = -0.29227,\n D = -0.90649,\n E = +1.97294,\n ED = E * D,\n EB = E * B,\n BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Rgb)) o = rgbConvert(o);\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n bl = b - l,\n k = (E * (g - l) - C * bl) / D,\n s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;\n return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nexport default function cubehelix(h, s, l, opacity) {\n return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nexport function Cubehelix(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n brighter: function(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function() {\n var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,\n l = +this.l,\n a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n cosh = Math.cos(h),\n sinh = Math.sin(h);\n return new Rgb(\n 255 * (l + a * (A * cosh + B * sinh)),\n 255 * (l + a * (C * cosh + D * sinh)),\n 255 * (l + a * (E * cosh)),\n this.opacity\n );\n }\n}));\n", + "export function basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1, t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n + (4 - 6 * t2 + 3 * t3) * v1\n + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n + t3 * v3) / 6;\n}\n\nexport default function(values) {\n var n = values.length - 1;\n return function(t) {\n var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n", + "export default function(x) {\n return function() {\n return x;\n };\n}\n", + "import constant from \"./constant\";\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nexport function hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\n\nexport function gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);\n };\n}\n\nexport default function nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant(isNaN(a) ? b : a);\n}\n", + "import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis\";\nimport basisClosed from \"./basisClosed\";\nimport nogamma, {gamma} from \"./color\";\n\nexport default (function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb.gamma = rgbGamma;\n\n return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color;\n for (i = 0; i < n; ++i) {\n color = colorRgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function(t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + \"\";\n };\n };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n", + "import {basis} from \"./basis\";\n\nexport default function(values) {\n var n = values.length;\n return function(t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n", + "export default function(a, b) {\n return a = +a, b -= a, function(t) {\n return a + b * t;\n };\n}\n", + "import number from \"./number\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nexport default function(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: number(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n", + "import decompose, {identity} from \"./decompose\";\n\nvar cssNode,\n cssRoot,\n cssView,\n svgNode;\n\nexport function parseCss(value) {\n if (value === \"none\") return identity;\n if (!cssNode) cssNode = document.createElement(\"DIV\"), cssRoot = document.documentElement, cssView = document.defaultView;\n cssNode.style.transform = value;\n value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue(\"transform\");\n cssRoot.removeChild(cssNode);\n value = value.slice(7, -1).split(\",\");\n return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);\n}\n\nexport function parseSvg(value) {\n if (value == null) return identity;\n if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n svgNode.setAttribute(\"transform\", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return identity;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n", + "import {color} from \"d3-color\";\nimport rgb from \"./rgb\";\nimport array from \"./array\";\nimport date from \"./date\";\nimport number from \"./number\";\nimport object from \"./object\";\nimport string from \"./string\";\nimport constant from \"./constant\";\n\nexport default function(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant(b)\n : (t === \"number\" ? number\n : t === \"string\" ? ((c = color(b)) ? (b = c, rgb) : string)\n : b instanceof color ? rgb\n : b instanceof Date ? date\n : Array.isArray(b) ? array\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : number)(a, b);\n}\n", + "export default function(a, b) {\n var d = new Date;\n return a = +a, b -= a, function(t) {\n return d.setTime(a + b * t), d;\n };\n}\n", + "import value from \"./value\";\n\nexport default function(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n", + "import value from \"./value\";\n\nexport default function(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n", + "export default function(a, b) {\n return a = +a, b -= a, function(t) {\n return Math.round(a + b * t);\n };\n}\n", + "var degrees = 180 / Math.PI;\n\nexport var identity = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n\nexport default function(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n", + "import number from \"../number\";\nimport {parseCss, parseSvg} from \"./parse\";\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n function pop(s) {\n return s.length ? s.pop() + \" \" : \"\";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb || yb) {\n s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"rotate(\" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"skewX(\" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n }\n }\n\n return function(a, b) {\n var s = [], // string constants and placeholders\n q = []; // number interpolators\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n return function(t) {\n var i = -1, n = q.length, o;\n while (++i < n) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n };\n };\n}\n\nexport var interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nexport var interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n", + "var rho = Math.SQRT2,\n rho2 = 2,\n rho4 = 4,\n epsilon2 = 1e-12;\n\nfunction cosh(x) {\n return ((x = Math.exp(x)) + 1 / x) / 2;\n}\n\nfunction sinh(x) {\n return ((x = Math.exp(x)) - 1 / x) / 2;\n}\n\nfunction tanh(x) {\n return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n}\n\n// p0 = [ux0, uy0, w0]\n// p1 = [ux1, uy1, w1]\nexport default function(p0, p1) {\n var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],\n ux1 = p1[0], uy1 = p1[1], w1 = p1[2],\n dx = ux1 - ux0,\n dy = uy1 - uy0,\n d2 = dx * dx + dy * dy,\n i,\n S;\n\n // Special case for u0 ≅ u1.\n if (d2 < epsilon2) {\n S = Math.log(w1 / w0) / rho;\n i = function(t) {\n return [\n ux0 + t * dx,\n uy0 + t * dy,\n w0 * Math.exp(rho * t * S)\n ];\n }\n }\n\n // General case.\n else {\n var d1 = Math.sqrt(d2),\n b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),\n b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),\n r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),\n r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n S = (r1 - r0) / rho;\n i = function(t) {\n var s = t * S,\n coshr0 = cosh(r0),\n u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));\n return [\n ux0 + u * dx,\n uy0 + u * dy,\n w0 * coshr0 / cosh(rho * s + r0)\n ];\n }\n }\n\n i.duration = S * 1000;\n\n return i;\n}\n", + "import {hsl as colorHsl} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction hsl(hue) {\n return function(start, end) {\n var h = hue((start = colorHsl(start)).h, (end = colorHsl(end)).h),\n s = color(start.s, end.s),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nexport default hsl(hue);\nexport var hslLong = hsl(color);\n", + "import {hcl as colorHcl} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction hcl(hue) {\n return function(start, end) {\n var h = hue((start = colorHcl(start)).h, (end = colorHcl(end)).h),\n c = color(start.c, end.c),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.c = c(t);\n start.l = l(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n}\n\nexport default hcl(hue);\nexport var hclLong = hcl(color);\n", + "import {cubehelix as colorCubehelix} from \"d3-color\";\nimport color, {hue} from \"./color\";\n\nfunction cubehelix(hue) {\n return (function cubehelixGamma(y) {\n y = +y;\n\n function cubehelix(start, end) {\n var h = hue((start = colorCubehelix(start)).h, (end = colorCubehelix(end)).h),\n s = color(start.s, end.s),\n l = color(start.l, end.l),\n opacity = color(start.opacity, end.opacity);\n return function(t) {\n start.h = h(t);\n start.s = s(t);\n start.l = l(Math.pow(t, y));\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n cubehelix.gamma = cubehelixGamma;\n\n return cubehelix;\n })(1);\n}\n\nexport default cubehelix(hue);\nexport var cubehelixLong = cubehelix(color);\n", + "export default function(interpolator, n) {\n var samples = new Array(n);\n for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));\n return samples;\n}\n", + "export default function(x) {\n return function() {\n return x;\n };\n}\n", + "export default function(x) {\n return +x;\n}\n", + "import {bisect} from \"d3-array\";\nimport {interpolate as interpolateValue, interpolateRound} from \"d3-interpolate\";\nimport {map, slice} from \"./array\";\nimport constant from \"./constant\";\nimport number from \"./number\";\n\nvar unit = [0, 1];\n\nexport function deinterpolateLinear(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant(b);\n}\n\nfunction deinterpolateClamp(deinterpolate) {\n return function(a, b) {\n var d = deinterpolate(a = +a, b = +b);\n return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };\n };\n}\n\nfunction reinterpolateClamp(reinterpolate) {\n return function(a, b) {\n var r = reinterpolate(a = +a, b = +b);\n return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };\n };\n}\n\nfunction bimap(domain, range, deinterpolate, reinterpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);\n else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, deinterpolate, reinterpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = deinterpolate(domain[i], domain[i + 1]);\n r[i] = reinterpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisect(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp());\n}\n\n// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].\nexport default function continuous(deinterpolate, reinterpolate) {\n var domain = unit,\n range = unit,\n interpolate = interpolateValue,\n clamp = false,\n piecewise,\n output,\n input;\n\n function rescale() {\n piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate)))(+x);\n }\n\n scale.invert = function(y) {\n return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = map.call(_, number), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = slice.call(_), interpolate = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, rescale()) : clamp;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate = _, rescale()) : interpolate;\n };\n\n return rescale();\n}\n", + "// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimal(1.23) returns [\"123\", 0].\nexport default function(x, p) {\n if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\")) < 0) return null; // NaN, ±Infinity\n var i, coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n", + "import formatDecimal from \"./formatDecimal\";\n\nexport default function(x) {\n return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;\n}\n", + "// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n return new FormatSpecifier(specifier);\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n var match;\n this.fill = match[1] || \" \";\n this.align = match[2] || \">\";\n this.sign = match[3] || \"-\";\n this.symbol = match[4] || \"\";\n this.zero = !!match[5];\n this.width = match[6] && +match[6];\n this.comma = !!match[7];\n this.precision = match[8] && +match[8].slice(1);\n this.trim = !!match[9];\n this.type = match[10] || \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width == null ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision == null ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + (this.trim ? \"~\" : \"\")\n + this.type;\n};\n", + "// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n default: if (i0 > 0) { if (!+s[i]) break out; i0 = 0; } break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n", + "import formatDecimal from \"./formatDecimal\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n", + "import formatLocale from \"./locale\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n decimal: \".\",\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n", + "import formatDecimal from \"./formatDecimal\";\n\nexport default function(x, p) {\n var d = formatDecimal(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n", + "import formatPrefixAuto from \"./formatPrefixAuto\";\nimport formatRounded from \"./formatRounded\";\n\nexport default {\n \"%\": function(x, p) { return (x * 100).toFixed(p); },\n \"b\": function(x) { return Math.round(x).toString(2); },\n \"c\": function(x) { return x + \"\"; },\n \"d\": function(x) { return Math.round(x).toString(10); },\n \"e\": function(x, p) { return x.toExponential(p); },\n \"f\": function(x, p) { return x.toFixed(p); },\n \"g\": function(x, p) { return x.toPrecision(p); },\n \"o\": function(x) { return Math.round(x).toString(8); },\n \"p\": function(x, p) { return formatRounded(x * 100, p); },\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": function(x) { return Math.round(x).toString(16).toUpperCase(); },\n \"x\": function(x) { return Math.round(x).toString(16); }\n};\n", + "export default function(x) {\n return x;\n}\n", + "import exponent from \"./exponent\";\nimport formatGroup from \"./formatGroup\";\nimport formatNumerals from \"./formatNumerals\";\nimport formatSpecifier from \"./formatSpecifier\";\nimport formatTrim from \"./formatTrim\";\nimport formatTypes from \"./formatTypes\";\nimport {prefixExponent} from \"./formatPrefixAuto\";\nimport identity from \"./identity\";\n\nvar prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,\n currency = locale.currency,\n decimal = locale.decimal,\n numerals = locale.numerals ? formatNumerals(locale.numerals) : identity,\n percent = locale.percent || \"%\";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type;\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // The \"\" type, and any invalid type, is an alias for \".12~g\".\n else if (!formatTypes[type]) precision == null && (precision = 12), trim = true, type = \"g\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = symbol === \"$\" ? currency[0] : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n suffix = symbol === \"$\" ? currency[1] : /[%p]/.test(type) ? percent : \"\";\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision == null ? 6\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Perform the initial formatting.\n var valueNegative = value < 0;\n value = formatType(Math.abs(value), precision);\n\n // Trim insignificant zeros.\n if (trim) value = formatTrim(value);\n\n // If a negative value rounds to zero during formatting, treat as positive.\n if (valueNegative && +value === 0) valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : \"-\") : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function(value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n", + "export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n", + "export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n", + "import exponent from \"./exponent\";\n\nexport default function(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n", + "import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function(domain, count, specifier) {\n var start = domain[0],\n stop = domain[domain.length - 1],\n step = tickStep(start, stop, count == null ? 10 : count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return format(specifier);\n}\n", + "import exponent from \"./exponent\";\n\nexport default function(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n", + "import exponent from \"./exponent\";\n\nexport default function(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n", + "import {ticks, tickIncrement} from \"d3-array\";\nimport {interpolateNumber as reinterpolate} from \"d3-interpolate\";\nimport {default as continuous, copy, deinterpolateLinear as deinterpolate} from \"./continuous\";\nimport tickFormat from \"./tickFormat\";\n\nexport function linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n return tickFormat(domain(), count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain(),\n i0 = 0,\n i1 = d.length - 1,\n start = d[i0],\n stop = d[i1],\n step;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n\n step = tickIncrement(start, stop, count);\n\n if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n step = tickIncrement(start, stop, count);\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n step = tickIncrement(start, stop, count);\n }\n\n if (step > 0) {\n d[i0] = Math.floor(start / step) * step;\n d[i1] = Math.ceil(stop / step) * step;\n domain(d);\n } else if (step < 0) {\n d[i0] = Math.ceil(start * step) / step;\n d[i1] = Math.floor(stop * step) / step;\n domain(d);\n }\n\n return scale;\n };\n\n return scale;\n}\n\nexport default function linear() {\n var scale = continuous(deinterpolate, reinterpolate);\n\n scale.copy = function() {\n return copy(scale, linear());\n };\n\n return linearish(scale);\n}\n", + "import {map} from \"./array\";\nimport {linearish} from \"./linear\";\nimport number from \"./number\";\n\nexport default function identity() {\n var domain = [0, 1];\n\n function scale(x) {\n return +x;\n }\n\n scale.invert = scale;\n\n scale.domain = scale.range = function(_) {\n return arguments.length ? (domain = map.call(_, number), scale) : domain.slice();\n };\n\n scale.copy = function() {\n return identity().domain(domain);\n };\n\n return linearish(scale);\n}\n", + "export default function(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n", + "import {ticks} from \"d3-array\";\nimport {format} from \"d3-format\";\nimport constant from \"./constant\";\nimport nice from \"./nice\";\nimport {default as continuous, copy} from \"./continuous\";\n\nfunction deinterpolate(a, b) {\n return (b = Math.log(b / a))\n ? function(x) { return Math.log(x / a) / b; }\n : constant(b);\n}\n\nfunction reinterpolate(a, b) {\n return a < 0\n ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }\n : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : function(x) { return Math.pow(base, x); };\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), function(x) { return Math.log(x) / base; });\n}\n\nfunction reflect(f) {\n return function(x) {\n return -f(-x);\n };\n}\n\nexport default function log() {\n var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),\n domain = scale.domain,\n base = 10,\n logs = logp(10),\n pows = powp(10);\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = function(count) {\n var d = domain(),\n u = d[0],\n v = d[d.length - 1],\n r;\n\n if (r = v < u) i = u, u = v, v = i;\n\n var i = logs(u),\n j = logs(v),\n p,\n k,\n t,\n n = count == null ? 10 : +count,\n z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.round(i) - 1, j = Math.round(j) + 1;\n if (u > 0) for (; i < j; ++i) {\n for (k = 1, p = pows(i); k < base; ++k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i < j; ++i) {\n for (k = base - 1, p = pows(i); k >= 1; --k) {\n t = p * k;\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = function(count, specifier) {\n if (specifier == null) specifier = base === 10 ? \".0e\" : \",\";\n if (typeof specifier !== \"function\") specifier = format(specifier);\n if (count === Infinity) return specifier;\n if (count == null) count = 10;\n var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return function(d) {\n var i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = function() {\n return domain(nice(domain(), {\n floor: function(x) { return pows(Math.floor(logs(x))); },\n ceil: function(x) { return pows(Math.ceil(logs(x))); }\n }));\n };\n\n scale.copy = function() {\n return copy(scale, log().base(base));\n };\n\n return scale;\n}\n", + "import constant from \"./constant\";\nimport {linearish} from \"./linear\";\nimport {default as continuous, copy} from \"./continuous\";\n\nfunction raise(x, exponent) {\n return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n}\n\nexport default function pow() {\n var exponent = 1,\n scale = continuous(deinterpolate, reinterpolate),\n domain = scale.domain;\n\n function deinterpolate(a, b) {\n return (b = raise(b, exponent) - (a = raise(a, exponent)))\n ? function(x) { return (raise(x, exponent) - a) / b; }\n : constant(b);\n }\n\n function reinterpolate(a, b) {\n b = raise(b, exponent) - (a = raise(a, exponent));\n return function(t) { return raise(a + b * t, 1 / exponent); };\n }\n\n scale.exponent = function(_) {\n return arguments.length ? (exponent = +_, domain(domain())) : exponent;\n };\n\n scale.copy = function() {\n return copy(scale, pow().exponent(exponent));\n };\n\n return linearish(scale);\n}\n\nexport function sqrt() {\n return pow().exponent(0.5);\n}\n", + "import {ascending, bisect, quantile as threshold} from \"d3-array\";\nimport {slice} from \"./array\";\n\nexport default function quantile() {\n var domain = [],\n range = [],\n thresholds = [];\n\n function rescale() {\n var i = 0, n = Math.max(1, range.length);\n thresholds = new Array(n - 1);\n while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n return scale;\n }\n\n function scale(x) {\n if (!isNaN(x = +x)) return range[bisect(thresholds, x)];\n }\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN] : [\n i > 0 ? thresholds[i - 1] : domain[0],\n i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n ];\n };\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [];\n for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);\n domain.sort(ascending);\n return rescale();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), rescale()) : range.slice();\n };\n\n scale.quantiles = function() {\n return thresholds.slice();\n };\n\n scale.copy = function() {\n return quantile()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n", + "import {bisect} from \"d3-array\";\nimport {slice} from \"./array\";\nimport {linearish} from \"./linear\";\n\nexport default function quantize() {\n var x0 = 0,\n x1 = 1,\n n = 1,\n domain = [0.5],\n range = [0, 1];\n\n function scale(x) {\n if (x <= x) return range[bisect(domain, x, 0, n)];\n }\n\n function rescale() {\n var i = -1;\n domain = new Array(n);\n while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n return scale;\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];\n };\n\n scale.range = function(_) {\n return arguments.length ? (n = (range = slice.call(_)).length - 1, rescale()) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return i < 0 ? [NaN, NaN]\n : i < 1 ? [x0, domain[0]]\n : i >= n ? [domain[n - 1], x1]\n : [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return quantize()\n .domain([x0, x1])\n .range(range);\n };\n\n return linearish(scale);\n}\n", + "import {bisect} from \"d3-array\";\nimport {slice} from \"./array\";\n\nexport default function threshold() {\n var domain = [0.5],\n range = [0, 1],\n n = 1;\n\n function scale(x) {\n if (x <= x) return range[bisect(domain, x, 0, n)];\n }\n\n scale.domain = function(_) {\n return arguments.length ? (domain = slice.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = slice.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();\n };\n\n scale.invertExtent = function(y) {\n var i = range.indexOf(y);\n return [domain[i - 1], domain[i]];\n };\n\n scale.copy = function() {\n return threshold()\n .domain(domain)\n .range(range);\n };\n\n return scale;\n}\n", + "var t0 = new Date,\n t1 = new Date;\n\nexport default function newInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = new Date(+date)), date;\n }\n\n interval.floor = interval;\n\n interval.ceil = function(date) {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = function(date) {\n var d0 = interval(date),\n d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = function(date, step) {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = function(start, stop, step) {\n var range = [], previous;\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = function(test) {\n return newInterval(function(date) {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, function(date, step) {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = function(start, end) {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = function(step) {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? function(d) { return field(d) % step === 0; }\n : function(d) { return interval.count(0, d) % step === 0; });\n };\n }\n\n return interval;\n}\n", + "import interval from \"./interval\";\n\nvar millisecond = interval(function() {\n // noop\n}, function(date, step) {\n date.setTime(+date + step);\n}, function(start, end) {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = function(k) {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return interval(function(date) {\n date.setTime(Math.floor(date / k) * k);\n }, function(date, step) {\n date.setTime(+date + step * k);\n }, function(start, end) {\n return (end - start) / k;\n });\n};\n\nexport default millisecond;\nexport var milliseconds = millisecond.range;\n", + "export var durationSecond = 1e3;\nexport var durationMinute = 6e4;\nexport var durationHour = 36e5;\nexport var durationDay = 864e5;\nexport var durationWeek = 6048e5;\n", + "import interval from \"./interval\";\nimport {durationSecond} from \"./duration\";\n\nvar second = interval(function(date) {\n date.setTime(date - date.getMilliseconds());\n}, function(date, step) {\n date.setTime(+date + step * durationSecond);\n}, function(start, end) {\n return (end - start) / durationSecond;\n}, function(date) {\n return date.getUTCSeconds();\n});\n\nexport default second;\nexport var seconds = second.range;\n", + "import interval from \"./interval\";\nimport {durationMinute, durationSecond} from \"./duration\";\n\nvar minute = interval(function(date) {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute);\n}, function(start, end) {\n return (end - start) / durationMinute;\n}, function(date) {\n return date.getMinutes();\n});\n\nexport default minute;\nexport var minutes = minute.range;\n", + "import interval from \"./interval\";\nimport {durationHour, durationMinute, durationSecond} from \"./duration\";\n\nvar hour = interval(function(date) {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);\n}, function(date, step) {\n date.setTime(+date + step * durationHour);\n}, function(start, end) {\n return (end - start) / durationHour;\n}, function(date) {\n return date.getHours();\n});\n\nexport default hour;\nexport var hours = hour.range;\n", + "import interval from \"./interval\";\nimport {durationDay, durationMinute} from \"./duration\";\n\nvar day = interval(function(date) {\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setDate(date.getDate() + step);\n}, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;\n}, function(date) {\n return date.getDate() - 1;\n});\n\nexport default day;\nexport var days = day.range;\n", + "import interval from \"./interval\";\nimport {durationMinute, durationWeek} from \"./duration\";\n\nfunction weekday(i) {\n return interval(function(date) {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setDate(date.getDate() + step * 7);\n }, function(start, end) {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport var sunday = weekday(0);\nexport var monday = weekday(1);\nexport var tuesday = weekday(2);\nexport var wednesday = weekday(3);\nexport var thursday = weekday(4);\nexport var friday = weekday(5);\nexport var saturday = weekday(6);\n\nexport var sundays = sunday.range;\nexport var mondays = monday.range;\nexport var tuesdays = tuesday.range;\nexport var wednesdays = wednesday.range;\nexport var thursdays = thursday.range;\nexport var fridays = friday.range;\nexport var saturdays = saturday.range;\n", + "import interval from \"./interval\";\n\nvar month = interval(function(date) {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setMonth(date.getMonth() + step);\n}, function(start, end) {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, function(date) {\n return date.getMonth();\n});\n\nexport default month;\nexport var months = month.range;\n", + "import interval from \"./interval\";\n\nvar year = interval(function(date) {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setFullYear(date.getFullYear() + step);\n}, function(start, end) {\n return end.getFullYear() - start.getFullYear();\n}, function(date) {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\nyear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport default year;\nexport var years = year.range;\n", + "import interval from \"./interval\";\nimport {durationMinute} from \"./duration\";\n\nvar utcMinute = interval(function(date) {\n date.setUTCSeconds(0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationMinute);\n}, function(start, end) {\n return (end - start) / durationMinute;\n}, function(date) {\n return date.getUTCMinutes();\n});\n\nexport default utcMinute;\nexport var utcMinutes = utcMinute.range;\n", + "import interval from \"./interval\";\nimport {durationHour} from \"./duration\";\n\nvar utcHour = interval(function(date) {\n date.setUTCMinutes(0, 0, 0);\n}, function(date, step) {\n date.setTime(+date + step * durationHour);\n}, function(start, end) {\n return (end - start) / durationHour;\n}, function(date) {\n return date.getUTCHours();\n});\n\nexport default utcHour;\nexport var utcHours = utcHour.range;\n", + "import interval from \"./interval\";\nimport {durationDay} from \"./duration\";\n\nvar utcDay = interval(function(date) {\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step);\n}, function(start, end) {\n return (end - start) / durationDay;\n}, function(date) {\n return date.getUTCDate() - 1;\n});\n\nexport default utcDay;\nexport var utcDays = utcDay.range;\n", + "import interval from \"./interval\";\nimport {durationWeek} from \"./duration\";\n\nfunction utcWeekday(i) {\n return interval(function(date) {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, function(start, end) {\n return (end - start) / durationWeek;\n });\n}\n\nexport var utcSunday = utcWeekday(0);\nexport var utcMonday = utcWeekday(1);\nexport var utcTuesday = utcWeekday(2);\nexport var utcWednesday = utcWeekday(3);\nexport var utcThursday = utcWeekday(4);\nexport var utcFriday = utcWeekday(5);\nexport var utcSaturday = utcWeekday(6);\n\nexport var utcSundays = utcSunday.range;\nexport var utcMondays = utcMonday.range;\nexport var utcTuesdays = utcTuesday.range;\nexport var utcWednesdays = utcWednesday.range;\nexport var utcThursdays = utcThursday.range;\nexport var utcFridays = utcFriday.range;\nexport var utcSaturdays = utcSaturday.range;\n", + "import interval from \"./interval\";\n\nvar utcMonth = interval(function(date) {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, function(start, end) {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, function(date) {\n return date.getUTCMonth();\n});\n\nexport default utcMonth;\nexport var utcMonths = utcMonth.range;\n", + "import interval from \"./interval\";\n\nvar utcYear = interval(function(date) {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, function(start, end) {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, function(date) {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = function(k) {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, function(date, step) {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport default utcYear;\nexport var utcYears = utcYear.range;\n", + "import {\n timeDay,\n timeSunday,\n timeMonday,\n timeThursday,\n timeYear,\n utcDay,\n utcSunday,\n utcMonday,\n utcThursday,\n utcYear\n} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newYear(y) {\n return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, newDate) {\n return function(string) {\n var d = newYear(1900),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newYear(d.y)), day = week.getUTCDay();\n week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = newDate(newYear(d.y)), day = week.getDay();\n week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);\n week = timeDay.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day = \"Z\" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return newDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", localDate);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier, utcDate);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n var map = {}, i = -1, n = names.length;\n while (++i < n) map[names[i].toLowerCase()] = i;\n return map;\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day = d.getDay();\n return day === 0 ? 7 : day;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d), d), p, 2);\n}\n\nfunction formatWeekNumberISO(d, p) {\n var day = d.getDay();\n d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d), d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n var day = d.getUTCDay();\n d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n", + "import formatLocale from \"./locale\";\n\nvar locale;\nexport var timeFormat;\nexport var timeParse;\nexport var utcFormat;\nexport var utcParse;\n\ndefaultLocale({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n timeFormat = locale.format;\n timeParse = locale.parse;\n utcFormat = locale.utcFormat;\n utcParse = locale.utcParse;\n return locale;\n}\n", + "import {utcFormat} from \"./defaultLocale\";\n\nexport var isoSpecifier = \"%Y-%m-%dT%H:%M:%S.%LZ\";\n\nfunction formatIsoNative(date) {\n return date.toISOString();\n}\n\nvar formatIso = Date.prototype.toISOString\n ? formatIsoNative\n : utcFormat(isoSpecifier);\n\nexport default formatIso;\n", + "import {isoSpecifier} from \"./isoFormat\";\nimport {utcParse} from \"./defaultLocale\";\n\nfunction parseIsoNative(string) {\n var date = new Date(string);\n return isNaN(date) ? null : date;\n}\n\nvar parseIso = +new Date(\"2000-01-01T00:00:00.000Z\")\n ? parseIsoNative\n : utcParse(isoSpecifier);\n\nexport default parseIso;\n", + "import {bisector, tickStep} from \"d3-array\";\nimport {interpolateNumber as reinterpolate} from \"d3-interpolate\";\nimport {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeMillisecond} from \"d3-time\";\nimport {timeFormat} from \"d3-time-format\";\nimport {map} from \"./array\";\nimport {default as continuous, copy, deinterpolateLinear as deinterpolate} from \"./continuous\";\nimport nice from \"./nice\";\n\nvar durationSecond = 1000,\n durationMinute = durationSecond * 60,\n durationHour = durationMinute * 60,\n durationDay = durationHour * 24,\n durationWeek = durationDay * 7,\n durationMonth = durationDay * 30,\n durationYear = durationDay * 365;\n\nfunction date(t) {\n return new Date(t);\n}\n\nfunction number(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nexport function calendar(year, month, week, day, hour, minute, second, millisecond, format) {\n var scale = continuous(deinterpolate, reinterpolate),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n var tickIntervals = [\n [second, 1, durationSecond],\n [second, 5, 5 * durationSecond],\n [second, 15, 15 * durationSecond],\n [second, 30, 30 * durationSecond],\n [minute, 1, durationMinute],\n [minute, 5, 5 * durationMinute],\n [minute, 15, 15 * durationMinute],\n [minute, 30, 30 * durationMinute],\n [ hour, 1, durationHour ],\n [ hour, 3, 3 * durationHour ],\n [ hour, 6, 6 * durationHour ],\n [ hour, 12, 12 * durationHour ],\n [ day, 1, durationDay ],\n [ day, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month, 1, durationMonth ],\n [ month, 3, 3 * durationMonth ],\n [ year, 1, durationYear ]\n ];\n\n function tickFormat(date) {\n return (second(date) < date ? formatMillisecond\n : minute(date) < date ? formatSecond\n : hour(date) < date ? formatMinute\n : day(date) < date ? formatHour\n : month(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n function tickInterval(interval, start, stop, step) {\n if (interval == null) interval = 10;\n\n // If a desired tick count is specified, pick a reasonable tick interval\n // based on the extent of the domain and a rough estimate of tick size.\n // Otherwise, assume interval is already a time interval and use it.\n if (typeof interval === \"number\") {\n var target = Math.abs(stop - start) / interval,\n i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);\n if (i === tickIntervals.length) {\n step = tickStep(start / durationYear, stop / durationYear, interval);\n interval = year;\n } else if (i) {\n i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n step = i[1];\n interval = i[0];\n } else {\n step = Math.max(tickStep(start, stop, interval), 1);\n interval = millisecond;\n }\n }\n\n return step == null ? interval : interval.every(step);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(map.call(_, number)) : domain().map(date);\n };\n\n scale.ticks = function(interval, step) {\n var d = domain(),\n t0 = d[0],\n t1 = d[d.length - 1],\n r = t1 < t0,\n t;\n if (r) t = t0, t0 = t1, t1 = t;\n t = tickInterval(interval, t0, t1, step);\n t = t ? t.range(t0, t1 + 1) : []; // inclusive stop\n return r ? t.reverse() : t;\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval, step) {\n var d = domain();\n return (interval = tickInterval(interval, d[0], d[d.length - 1], step))\n ? domain(nice(d, interval))\n : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(year, month, week, day, hour, minute, second, millisecond, format));\n };\n\n return scale;\n}\n\nexport default function() {\n return calendar(timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeMillisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);\n}\n", + "import {calendar} from \"./time\";\nimport {utcFormat} from \"d3-time-format\";\nimport {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcMillisecond} from \"d3-time\";\n\nexport default function() {\n return calendar(utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcMillisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);\n}\n", + "import {linearish} from \"./linear\";\n\nexport default function sequential(interpolator) {\n var x0 = 0,\n x1 = 1,\n k10 = 1,\n clamp = false;\n\n function scale(x) {\n var t = (x - x0) * k10;\n return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], k10 = x0 === x1 ? 0 : 1 / (x1 - x0), scale) : [x0, x1];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n scale.copy = function() {\n return sequential(interpolator).domain([x0, x1]).clamp(clamp);\n };\n\n return linearish(scale);\n}\n", + "import {linearish} from \"./linear\";\n\nexport default function diverging(interpolator) {\n var x0 = 0,\n x1 = 0.5,\n x2 = 1,\n k10 = 1,\n k21 = 1,\n clamp = false;\n\n function scale(x) {\n var t = 0.5 + ((x = +x) - x1) * (x < x1 ? k10 : k21);\n return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n }\n\n scale.domain = function(_) {\n return arguments.length ? (x0 = +_[0], x1 = +_[1], x2 = +_[2], k10 = x0 === x1 ? 0 : 0.5 / (x1 - x0), k21 = x1 === x2 ? 0 : 0.5 / (x2 - x1), scale) : [x0, x1, x2];\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function(_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n scale.copy = function() {\n return diverging(interpolator).domain([x0, x1, x2]).clamp(clamp);\n };\n\n return linearish(scale);\n}\n", + "export {\n default as scaleBand,\n point as scalePoint\n} from \"./band\";\n\nexport {\n default as scaleIdentity\n} from \"./identity\";\n\nexport {\n default as scaleLinear\n} from \"./linear\";\n\nexport {\n default as scaleLog\n} from \"./log\";\n\nexport {\n default as scaleOrdinal,\n implicit as scaleImplicit\n} from \"./ordinal\";\n\nexport {\n default as scalePow,\n sqrt as scaleSqrt\n} from \"./pow\";\n\nexport {\n default as scaleQuantile\n} from \"./quantile\";\n\nexport {\n default as scaleQuantize\n} from \"./quantize\";\n\nexport {\n default as scaleThreshold\n} from \"./threshold\";\n\nexport {\n default as scaleTime\n} from \"./time\";\n\nexport {\n default as scaleUtc\n} from \"./utcTime\";\n\nexport {\n default as scaleSequential\n} from \"./sequential\";\n\nexport {\n default as scaleDiverging\n} from \"./diverging\";\n", + "var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n", + "export default function(x) {\n return function constant() {\n return x;\n };\n}\n", + "export var abs = Math.abs;\nexport var atan2 = Math.atan2;\nexport var cos = Math.cos;\nexport var max = Math.max;\nexport var min = Math.min;\nexport var sin = Math.sin;\nexport var sqrt = Math.sqrt;\n\nexport var epsilon = 1e-12;\nexport var pi = Math.PI;\nexport var halfPi = pi / 2;\nexport var tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n", + "function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n", + "export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n", + "import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport curveLinear from \"./curve/linear\";\nimport {x as pointX, y as pointY} from \"./point\";\n\nexport default function() {\n var x = pointX,\n y = pointY,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function line(data) {\n var i,\n n = data.length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x(d, i, data), +y(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), line) : x;\n };\n\n line.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), line) : y;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n", + "import {path} from \"d3-path\";\nimport constant from \"./constant\";\nimport curveLinear from \"./curve/linear\";\nimport line from \"./line\";\nimport {x as pointX, y as pointY} from \"./point\";\n\nexport default function() {\n var x0 = pointX,\n x1 = null,\n y0 = constant(0),\n y1 = pointY,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null;\n\n function area(data) {\n var i,\n j,\n k,\n n = data.length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n", + "import curveLinear from \"./linear\";\n\nexport var curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n this._curve = curve;\n}\n\nRadial.prototype = {\n areaStart: function() {\n this._curve.areaStart();\n },\n areaEnd: function() {\n this._curve.areaEnd();\n },\n lineStart: function() {\n this._curve.lineStart();\n },\n lineEnd: function() {\n this._curve.lineEnd();\n },\n point: function(a, r) {\n this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n }\n};\n\nexport default function curveRadial(curve) {\n\n function radial(context) {\n return new Radial(curve(context));\n }\n\n radial._curve = curve;\n\n return radial;\n}\n", + "import curveRadial, {curveRadialLinear} from \"./curve/radial\";\nimport line from \"./line\";\n\nexport function lineRadial(l) {\n var c = l.curve;\n\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n\n l.curve = function(_) {\n return arguments.length ? c(curveRadial(_)) : c()._curve;\n };\n\n return l;\n}\n\nexport default function() {\n return lineRadial(line().curve(curveRadialLinear));\n}\n", + "export var slice = Array.prototype.slice;\n", + "import {pi, tau} from \"../math\";\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / pi);\n context.moveTo(r, 0);\n context.arc(0, 0, r, 0, tau);\n }\n};\n", + "export default {\n draw: function(context, size) {\n var r = Math.sqrt(size / 5) / 2;\n context.moveTo(-3 * r, -r);\n context.lineTo(-r, -r);\n context.lineTo(-r, -3 * r);\n context.lineTo(r, -3 * r);\n context.lineTo(r, -r);\n context.lineTo(3 * r, -r);\n context.lineTo(3 * r, r);\n context.lineTo(r, r);\n context.lineTo(r, 3 * r);\n context.lineTo(-r, 3 * r);\n context.lineTo(-r, r);\n context.lineTo(-3 * r, r);\n context.closePath();\n }\n};\n", + "var tan30 = Math.sqrt(1 / 3),\n tan30_2 = tan30 * 2;\n\nexport default {\n draw: function(context, size) {\n var y = Math.sqrt(size / tan30_2),\n x = y * tan30;\n context.moveTo(0, -y);\n context.lineTo(x, 0);\n context.lineTo(0, y);\n context.lineTo(-x, 0);\n context.closePath();\n }\n};\n", + "import {pi, tau} from \"../math\";\n\nvar ka = 0.89081309152928522810,\n kr = Math.sin(pi / 10) / Math.sin(7 * pi / 10),\n kx = Math.sin(tau / 10) * kr,\n ky = -Math.cos(tau / 10) * kr;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size * ka),\n x = kx * r,\n y = ky * r;\n context.moveTo(0, -r);\n context.lineTo(x, y);\n for (var i = 1; i < 5; ++i) {\n var a = tau * i / 5,\n c = Math.cos(a),\n s = Math.sin(a);\n context.lineTo(s * r, -c * r);\n context.lineTo(c * x - s * y, s * x + c * y);\n }\n context.closePath();\n }\n};\n", + "export default {\n draw: function(context, size) {\n var w = Math.sqrt(size),\n x = -w / 2;\n context.rect(x, x, w, w);\n }\n};\n", + "var sqrt3 = Math.sqrt(3);\n\nexport default {\n draw: function(context, size) {\n var y = -Math.sqrt(size / (sqrt3 * 3));\n context.moveTo(0, y * 2);\n context.lineTo(-sqrt3 * y, -y);\n context.lineTo(sqrt3 * y, -y);\n context.closePath();\n }\n};\n", + "var c = -0.5,\n s = Math.sqrt(3) / 2,\n k = 1 / Math.sqrt(12),\n a = (k / 2 + 1) * 3;\n\nexport default {\n draw: function(context, size) {\n var r = Math.sqrt(size / a),\n x0 = r / 2,\n y0 = r * k,\n x1 = x0,\n y1 = r * k + r,\n x2 = -x1,\n y2 = y1;\n context.moveTo(x0, y0);\n context.lineTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n context.closePath();\n }\n};\n", + "import {path} from \"d3-path\";\nimport circle from \"./symbol/circle\";\nimport cross from \"./symbol/cross\";\nimport diamond from \"./symbol/diamond\";\nimport star from \"./symbol/star\";\nimport square from \"./symbol/square\";\nimport triangle from \"./symbol/triangle\";\nimport wye from \"./symbol/wye\";\nimport constant from \"./constant\";\n\nexport var symbols = [\n circle,\n cross,\n diamond,\n square,\n star,\n triangle,\n wye\n];\n\nexport default function() {\n var type = constant(circle),\n size = constant(64),\n context = null;\n\n function symbol() {\n var buffer;\n if (!context) context = buffer = path();\n type.apply(this, arguments).draw(context, +size.apply(this, arguments));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n symbol.type = function(_) {\n return arguments.length ? (type = typeof _ === \"function\" ? _ : constant(_), symbol) : type;\n };\n\n symbol.size = function(_) {\n return arguments.length ? (size = typeof _ === \"function\" ? _ : constant(+_), symbol) : size;\n };\n\n symbol.context = function(_) {\n return arguments.length ? (context = _ == null ? null : _, symbol) : context;\n };\n\n return symbol;\n}\n", + "export default function() {}\n", + "export function point(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nexport function Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point(this, this._x1, this._y1); // proceed\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new Basis(context);\n}\n", + "import noop from \"../noop\";\nimport {point} from \"./basis\";\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisClosed(context);\n}\n", + "import {point} from \"./basis\";\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisOpen(context);\n}\n", + "import {Basis} from \"./basis\";\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nexport default (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n", + "export function point(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nexport function Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n", + "import noop from \"../noop\";\nimport {point} from \"./cardinal\";\n\nexport function CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n", + "import {point} from \"./cardinal\";\n\nexport function CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n", + "import {epsilon} from \"../math\";\nimport {Cardinal} from \"./cardinal\";\n\nexport function point(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n", + "import {CardinalClosed} from \"./cardinalClosed\";\nimport noop from \"../noop\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n", + "import {CardinalOpen} from \"./cardinalOpen\";\nimport {point} from \"./catmullRom\";\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // proceed\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n", + "import noop from \"../noop\";\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nexport default function(context) {\n return new LinearClosed(context);\n}\n", + "function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n", + "function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n", + "function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // proceed\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n", + "export default function(series, order) {\n if (!((n = series.length) > 1)) return;\n for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {\n s0 = s1, s1 = series[order[i]];\n for (j = 0; j < m; ++j) {\n s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];\n }\n }\n}\n", + "export default function(series) {\n var n = series.length, o = new Array(n);\n while (--n >= 0) o[n] = n;\n return o;\n}\n", + "import {slice} from \"./array\";\nimport constant from \"./constant\";\nimport offsetNone from \"./offset/none\";\nimport orderNone from \"./order/none\";\n\nfunction stackValue(d, key) {\n return d[key];\n}\n\nexport default function() {\n var keys = constant([]),\n order = orderNone,\n offset = offsetNone,\n value = stackValue;\n\n function stack(data) {\n var kz = keys.apply(this, arguments),\n i,\n m = data.length,\n n = kz.length,\n sz = new Array(n),\n oz;\n\n for (i = 0; i < n; ++i) {\n for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {\n si[j] = sij = [0, +value(data[j], ki, j, data)];\n sij.data = data[j];\n }\n si.key = ki;\n }\n\n for (i = 0, oz = order(sz); i < n; ++i) {\n sz[oz[i]].index = i;\n }\n\n offset(sz, oz);\n return sz;\n }\n\n stack.keys = function(_) {\n return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant(slice.call(_)), stack) : keys;\n };\n\n stack.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(+_), stack) : value;\n };\n\n stack.order = function(_) {\n return arguments.length ? (order = _ == null ? orderNone : typeof _ === \"function\" ? _ : constant(slice.call(_)), stack) : order;\n };\n\n stack.offset = function(_) {\n return arguments.length ? (offset = _ == null ? offsetNone : _, stack) : offset;\n };\n\n return stack;\n}\n", + "import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n }\n none(series, order);\n}\n", + "import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0)) return;\n for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n s0[j][1] += s0[j][0] = -y / 2;\n }\n none(series, order);\n}\n", + "import none from \"./none\";\n\nexport default function(series, order) {\n if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;\n for (var y = 0, j = 1, s0, m, n; j < m; ++j) {\n for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {\n var si = series[order[i]],\n sij0 = si[j][1] || 0,\n sij1 = si[j - 1][1] || 0,\n s3 = (sij0 - sij1) / 2;\n for (var k = 0; k < i; ++k) {\n var sk = series[order[k]],\n skj0 = sk[j][1] || 0,\n skj1 = sk[j - 1][1] || 0;\n s3 += skj0 - skj1;\n }\n s1 += sij0, s2 += s3 * sij0;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n if (s1) y -= s2 / s1;\n }\n s0[j - 1][1] += s0[j - 1][0] = y;\n none(series, order);\n}\n", + "export {default as arc} from \"./arc\";\nexport {default as area} from \"./area\";\nexport {default as line} from \"./line\";\nexport {default as pie} from \"./pie\";\nexport {default as areaRadial, default as radialArea} from \"./areaRadial\"; // Note: radialArea is deprecated!\nexport {default as lineRadial, default as radialLine} from \"./lineRadial\"; // Note: radialLine is deprecated!\nexport {default as pointRadial} from \"./pointRadial\";\nexport {linkHorizontal, linkVertical, linkRadial} from \"./link/index\";\n\nexport {default as symbol, symbols} from \"./symbol\";\nexport {default as symbolCircle} from \"./symbol/circle\";\nexport {default as symbolCross} from \"./symbol/cross\";\nexport {default as symbolDiamond} from \"./symbol/diamond\";\nexport {default as symbolSquare} from \"./symbol/square\";\nexport {default as symbolStar} from \"./symbol/star\";\nexport {default as symbolTriangle} from \"./symbol/triangle\";\nexport {default as symbolWye} from \"./symbol/wye\";\n\nexport {default as curveBasisClosed} from \"./curve/basisClosed\";\nexport {default as curveBasisOpen} from \"./curve/basisOpen\";\nexport {default as curveBasis} from \"./curve/basis\";\nexport {default as curveBundle} from \"./curve/bundle\";\nexport {default as curveCardinalClosed} from \"./curve/cardinalClosed\";\nexport {default as curveCardinalOpen} from \"./curve/cardinalOpen\";\nexport {default as curveCardinal} from \"./curve/cardinal\";\nexport {default as curveCatmullRomClosed} from \"./curve/catmullRomClosed\";\nexport {default as curveCatmullRomOpen} from \"./curve/catmullRomOpen\";\nexport {default as curveCatmullRom} from \"./curve/catmullRom\";\nexport {default as curveLinearClosed} from \"./curve/linearClosed\";\nexport {default as curveLinear} from \"./curve/linear\";\nexport {monotoneX as curveMonotoneX, monotoneY as curveMonotoneY} from \"./curve/monotone\";\nexport {default as curveNatural} from \"./curve/natural\";\nexport {default as curveStep, stepAfter as curveStepAfter, stepBefore as curveStepBefore} from \"./curve/step\";\n\nexport {default as stack} from \"./stack\";\nexport {default as stackOffsetExpand} from \"./offset/expand\";\nexport {default as stackOffsetDiverging} from \"./offset/diverging\";\nexport {default as stackOffsetNone} from \"./offset/none\";\nexport {default as stackOffsetSilhouette} from \"./offset/silhouette\";\nexport {default as stackOffsetWiggle} from \"./offset/wiggle\";\nexport {default as stackOrderAscending} from \"./order/ascending\";\nexport {default as stackOrderDescending} from \"./order/descending\";\nexport {default as stackOrderInsideOut} from \"./order/insideOut\";\nexport {default as stackOrderNone} from \"./order/none\";\nexport {default as stackOrderReverse} from \"./order/reverse\";\n", + "/*! decimal.js-light v2.5.0 https://github.com/MikeMcl/decimal.js-light/LICENCE */\r\n;(function (globalScope) {\r\n 'use strict';\r\n\r\n\r\n /*\r\n * decimal.js-light v2.5.0\r\n * An arbitrary-precision Decimal type for JavaScript.\r\n * https://github.com/MikeMcl/decimal.js-light\r\n * Copyright (c) 2018 Michael Mclaughlin \r\n * MIT Expat Licence\r\n */\r\n\r\n\r\n // ----------------------------------- EDITABLE DEFAULTS ------------------------------------ //\r\n\r\n\r\n // The limit on the value of ` + "`")) + (`precision` + ("`" + `, and on the value of the first argument to\r\n // `))) + (("`" + (`toDecimalPlaces` + "`")) + ((`, ` + "`") + (`toExponential` + "`"))))))) + ((((((`, ` + ("`" + `toFixed`)) + ("`" + (`, ` + "`"))) + ((`toPrecision` + ("`" + ` and `)) + ("`" + (`toSignificantDigits` + "`")))) + (((`.\r\n var MAX_DIGITS = 1e9, // 0 to 1e9\r\n\r\n\r\n // The initial configuration properties of the Decimal constructor.\r\n Decimal = {\r\n\r\n // These values must be integers within the stated ranges (inclusive).\r\n // Most of these values can be changed during run-time using ` + ("`" + `Decimal.config`)) + ("`" + (`.\r\n\r\n // The maximum number of significant digits of the result of a calculation or base conversion.\r\n // E.g. ` + "`"))) + ((`Decimal.config({ precision: 20 });` + ("`" + `\r\n precision: 20, // 1 to MAX_DIGITS\r\n\r\n // The rounding mode used by default by `)) + ("`" + (`toInteger` + "`"))))) + ((((`, ` + ("`" + `toDecimalPlaces`)) + ("`" + (`, ` + "`"))) + ((`toExponential` + ("`" + `,\r\n // `)) + ("`" + (`toFixed` + "`")))) + (((`, ` + ("`" + `toPrecision`)) + ("`" + (` and ` + "`"))) + ((`toSignificantDigits` + ("`" + `.\r\n //\r\n // ROUND_UP 0 Away from zero.\r\n // ROUND_DOWN 1 Towards zero.\r\n // ROUND_CEIL 2 Towards +Infinity.\r\n // ROUND_FLOOR 3 Towards -Infinity.\r\n // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up.\r\n // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.\r\n // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.\r\n // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.\r\n // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.\r\n //\r\n // E.g.\r\n // `)) + (("`" + `Decimal.rounding = 4;`) + ("`" + `\r\n // `)))))) + ((((("`" + (`Decimal.rounding = Decimal.ROUND_HALF_UP;` + "`")) + (`\r\n rounding: 4, // 0 to 8\r\n\r\n // The exponent value at and beneath which ` + ("`" + `toString`))) + (("`" + (` returns exponential notation.\r\n // JavaScript numbers: -7\r\n toExpNeg: -7, // 0 to -MAX_E\r\n\r\n // The exponent value at and above which ` + "`")) + (`toString` + ("`" + ` returns exponential notation.\r\n // JavaScript numbers: 21\r\n toExpPos: 21, // 0 to MAX_E\r\n\r\n // The natural logarithm of 10.\r\n // 115 digits\r\n LN10: '2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286'\r\n },\r\n\r\n\r\n // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- //\r\n\r\n\r\n external = true,\r\n\r\n decimalError = '[DecimalError] ',\r\n invalidArgument = decimalError + 'Invalid argument: ',\r\n exponentOutOfRange = decimalError + 'Exponent out of range: ',\r\n\r\n mathfloor = Math.floor,\r\n mathpow = Math.pow,\r\n\r\n isDecimal = /^(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?$/i,\r\n\r\n ONE,\r\n BASE = 1e7,\r\n LOG_BASE = 7,\r\n MAX_SAFE_INTEGER = 9007199254740991,\r\n MAX_E = mathfloor(MAX_SAFE_INTEGER / LOG_BASE), // 1286742750677284\r\n\r\n // Decimal.prototype object\r\n P = {};\r\n\r\n\r\n // Decimal prototype methods\r\n\r\n\r\n /*\r\n * absoluteValue abs\r\n * comparedTo cmp\r\n * decimalPlaces dp\r\n * dividedBy div\r\n * dividedToIntegerBy idiv\r\n * equals eq\r\n * exponent\r\n * greaterThan gt\r\n * greaterThanOrEqualTo gte\r\n * isInteger isint\r\n * isNegative isneg\r\n * isPositive ispos\r\n * isZero\r\n * lessThan lt\r\n * lessThanOrEqualTo lte\r\n * logarithm log\r\n * minus sub\r\n * modulo mod\r\n * naturalExponential exp\r\n * naturalLogarithm ln\r\n * negated neg\r\n * plus add\r\n * precision sd\r\n * squareRoot sqrt\r\n * times mul\r\n * toDecimalPlaces todp\r\n * toExponential\r\n * toFixed\r\n * toInteger toint\r\n * toNumber\r\n * toPower pow\r\n * toPrecision\r\n * toSignificantDigits tosd\r\n * toString\r\n * valueOf val\r\n */\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the absolute value of this Decimal.\r\n *\r\n */\r\n P.absoluteValue = P.abs = function () {\r\n var x = new this.constructor(this);\r\n if (x.s) x.s = 1;\r\n return x;\r\n };\r\n\r\n\r\n /*\r\n * Return\r\n * 1 if the value of this Decimal is greater than the value of `)))) + ((("`" + (`y` + "`")) + (`,\r\n * -1 if the value of this Decimal is less than the value of ` + ("`" + `y`))) + (("`" + (`,\r\n * 0 if they have the same value\r\n *\r\n */\r\n P.comparedTo = P.cmp = function (y) {\r\n var i, j, xdL, ydL,\r\n x = this;\r\n\r\n y = new x.constructor(y);\r\n\r\n // Signs differ?\r\n if (x.s !== y.s) return x.s || -y.s;\r\n\r\n // Compare exponents.\r\n if (x.e !== y.e) return x.e > y.e ^ x.s < 0 ? 1 : -1;\r\n\r\n xdL = x.d.length;\r\n ydL = y.d.length;\r\n\r\n // Compare digit by digit.\r\n for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) {\r\n if (x.d[i] !== y.d[i]) return x.d[i] > y.d[i] ^ x.s < 0 ? 1 : -1;\r\n }\r\n\r\n // Compare lengths.\r\n return xdL === ydL ? 0 : xdL > ydL ^ x.s < 0 ? 1 : -1;\r\n };\r\n\r\n\r\n /*\r\n * Return the number of decimal places of the value of this Decimal.\r\n *\r\n */\r\n P.decimalPlaces = P.dp = function () {\r\n var x = this,\r\n w = x.d.length - 1,\r\n dp = (w - x.e) * LOG_BASE;\r\n\r\n // Subtract the number of trailing zeros of the last word.\r\n w = x.d[w];\r\n if (w) for (; w % 10 == 0; w /= 10) dp--;\r\n\r\n return dp < 0 ? 0 : dp;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal divided by ` + "`")) + ((`y` + "`") + (`, truncated to\r\n * ` + "`"))))) + ((((`precision` + ("`" + ` significant digits.\r\n *\r\n */\r\n P.dividedBy = P.div = function (y) {\r\n return divide(this, new this.constructor(y));\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the integer part of dividing the value of this Decimal\r\n * by the value of `)) + ("`" + (`y` + "`"))) + ((`, truncated to ` + ("`" + `precision`)) + ("`" + (` significant digits.\r\n *\r\n */\r\n P.dividedToIntegerBy = P.idiv = function (y) {\r\n var x = this,\r\n Ctor = x.constructor;\r\n return round(divide(x, new Ctor(y), 0, 1), Ctor.precision);\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is equal to the value of ` + "`")))) + (((`y` + ("`" + `, otherwise return false.\r\n *\r\n */\r\n P.equals = P.eq = function (y) {\r\n return !this.cmp(y);\r\n };\r\n\r\n\r\n /*\r\n * Return the (base 10) exponent value of this Decimal (this.e is the base 10000000 exponent).\r\n *\r\n */\r\n P.exponent = function () {\r\n return getBase10Exponent(this);\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is greater than the value of `)) + ("`" + (`y` + "`"))) + ((`, otherwise return\r\n * false.\r\n *\r\n */\r\n P.greaterThan = P.gt = function (y) {\r\n return this.cmp(y) > 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is greater than or equal to the value of ` + ("`" + `y`)) + (("`" + `,\r\n * otherwise return false.\r\n *\r\n */\r\n P.greaterThanOrEqualTo = P.gte = function (y) {\r\n return this.cmp(y) >= 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is an integer, otherwise return false.\r\n *\r\n */\r\n P.isInteger = P.isint = function () {\r\n return this.e > this.d.length - 2;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is negative, otherwise return false.\r\n *\r\n */\r\n P.isNegative = P.isneg = function () {\r\n return this.s < 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is positive, otherwise return false.\r\n *\r\n */\r\n P.isPositive = P.ispos = function () {\r\n return this.s > 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is 0, otherwise return false.\r\n *\r\n */\r\n P.isZero = function () {\r\n return this.s === 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is less than `) + ("`" + `y`)))))))) + ((((((("`" + (`, otherwise return false.\r\n *\r\n */\r\n P.lessThan = P.lt = function (y) {\r\n return this.cmp(y) < 0;\r\n };\r\n\r\n\r\n /*\r\n * Return true if the value of this Decimal is less than or equal to ` + "`")) + (`y` + ("`" + `, otherwise return false.\r\n *\r\n */\r\n P.lessThanOrEqualTo = P.lte = function (y) {\r\n return this.cmp(y) < 1;\r\n };\r\n\r\n\r\n /*\r\n * Return the logarithm of the value of this Decimal to the specified base, truncated to\r\n * `))) + (("`" + (`precision` + "`")) + (` significant digits.\r\n *\r\n * If no base is specified, return log[10](x).\r\n *\r\n * log[base](x) = ln(x) / ln(base)\r\n *\r\n * The maximum error of the result is 1 ulp (unit in the last place).\r\n *\r\n * [base] {number|string|Decimal} The base of the logarithm.\r\n *\r\n */\r\n P.logarithm = P.log = function (base) {\r\n var r,\r\n x = this,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision,\r\n wpr = pr + 5;\r\n\r\n // Default base is 10.\r\n if (base === void 0) {\r\n base = new Ctor(10);\r\n } else {\r\n base = new Ctor(base);\r\n\r\n // log[-b](x) = NaN\r\n // log[0](x) = NaN\r\n // log[1](x) = NaN\r\n if (base.s < 1 || base.eq(ONE)) throw Error(decimalError + 'NaN');\r\n }\r\n\r\n // log[b](-x) = NaN\r\n // log[b](0) = -Infinity\r\n if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));\r\n\r\n // log[b](1) = 0\r\n if (x.eq(ONE)) return new Ctor(0);\r\n\r\n external = false;\r\n r = divide(ln(x, wpr), ln(base, wpr), wpr);\r\n external = true;\r\n\r\n return round(r, pr);\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal minus ` + ("`" + `y`)))) + ((("`" + (`, truncated to\r\n * ` + "`")) + (`precision` + ("`" + ` significant digits.\r\n *\r\n */\r\n P.minus = P.sub = function (y) {\r\n var x = this;\r\n y = new x.constructor(y);\r\n return x.s == y.s ? subtract(x, y) : add(x, (y.s = -y.s, y));\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal modulo `))) + (("`" + (`y` + "`")) + (`, truncated to\r\n * ` + ("`" + `precision`))))) + (((("`" + (` significant digits.\r\n *\r\n */\r\n P.modulo = P.mod = function (y) {\r\n var q,\r\n x = this,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision;\r\n\r\n y = new Ctor(y);\r\n\r\n // x % 0 = NaN\r\n if (!y.s) throw Error(decimalError + 'NaN');\r\n\r\n // Return x if x is 0.\r\n if (!x.s) return round(new Ctor(x), pr);\r\n\r\n // Prevent rounding of intermediate calculations.\r\n external = false;\r\n q = divide(x, y, 0, 1).times(y);\r\n external = true;\r\n\r\n return x.minus(q);\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the natural exponential of the value of this Decimal,\r\n * i.e. the base e raised to the power the value of this Decimal, truncated to ` + "`")) + (`precision` + ("`" + `\r\n * significant digits.\r\n *\r\n */\r\n P.naturalExponential = P.exp = function () {\r\n return exp(this);\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the natural logarithm of the value of this Decimal,\r\n * truncated to `))) + (("`" + (`precision` + "`")) + (` significant digits.\r\n *\r\n */\r\n P.naturalLogarithm = P.ln = function () {\r\n return ln(this);\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by\r\n * -1.\r\n *\r\n */\r\n P.negated = P.neg = function () {\r\n var x = new this.constructor(this);\r\n x.s = -x.s || 0;\r\n return x;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal plus ` + ("`" + `y`)))) + ((("`" + (`, truncated to\r\n * ` + "`")) + (`precision` + ("`" + ` significant digits.\r\n *\r\n */\r\n P.plus = P.add = function (y) {\r\n var x = this;\r\n y = new x.constructor(y);\r\n return x.s == y.s ? add(x, y) : subtract(x, (y.s = -y.s, y));\r\n };\r\n\r\n\r\n /*\r\n * Return the number of significant digits of the value of this Decimal.\r\n *\r\n * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.\r\n *\r\n */\r\n P.precision = P.sd = function (z) {\r\n var e, sd, w,\r\n x = this;\r\n\r\n if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z);\r\n\r\n e = getBase10Exponent(x) + 1;\r\n w = x.d.length - 1;\r\n sd = w * LOG_BASE + 1;\r\n w = x.d[w];\r\n\r\n // If non-zero...\r\n if (w) {\r\n\r\n // Subtract the number of trailing zeros of the last word.\r\n for (; w % 10 == 0; w /= 10) sd--;\r\n\r\n // Add the number of digits of the first word.\r\n for (w = x.d[0]; w >= 10; w /= 10) sd++;\r\n }\r\n\r\n return z && e > sd ? e : sd;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the square root of this Decimal, truncated to `))) + (("`" + (`precision` + "`")) + ((`\r\n * significant digits.\r\n *\r\n */\r\n P.squareRoot = P.sqrt = function () {\r\n var e, n, pr, r, s, t, wpr,\r\n x = this,\r\n Ctor = x.constructor;\r\n\r\n // Negative or zero?\r\n if (x.s < 1) {\r\n if (!x.s) return new Ctor(0);\r\n\r\n // sqrt(-x) = NaN\r\n throw Error(decimalError + 'NaN');\r\n }\r\n\r\n e = getBase10Exponent(x);\r\n external = false;\r\n\r\n // Initial estimate.\r\n s = Math.sqrt(+x);\r\n\r\n // Math.sqrt underflow/overflow?\r\n // Pass x to Math.sqrt as integer, then adjust the exponent of the result.\r\n if (s == 0 || s == 1 / 0) {\r\n n = digitsToString(x.d);\r\n if ((n.length + e) % 2 == 0) n += '0';\r\n s = Math.sqrt(n);\r\n e = mathfloor((e + 1) / 2) - (e < 0 || e % 2);\r\n\r\n if (s == 1 / 0) {\r\n n = '1e' + e;\r\n } else {\r\n n = s.toExponential();\r\n n = n.slice(0, n.indexOf('e') + 1) + e;\r\n }\r\n\r\n r = new Ctor(n);\r\n } else {\r\n r = new Ctor(s.toString());\r\n }\r\n\r\n pr = Ctor.precision;\r\n s = wpr = pr + 3;\r\n\r\n // Newton-Raphson iteration.\r\n for (;;) {\r\n t = r;\r\n r = t.plus(divide(x, t, wpr + 2)).times(0.5);\r\n\r\n if (digitsToString(t.d).slice(0, wpr) === (n = digitsToString(r.d)).slice(0, wpr)) {\r\n n = n.slice(wpr - 3, wpr + 1);\r\n\r\n // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or\r\n // 4999, i.e. approaching a rounding boundary, continue the iteration.\r\n if (s == wpr && n == '4999') {\r\n\r\n // On the first iteration only, check to see if rounding up gives the exact result as the\r\n // nines may infinitely repeat.\r\n round(t, pr + 1, 0);\r\n\r\n if (t.times(t).eq(x)) {\r\n r = t;\r\n break;\r\n }\r\n } else if (n != '9999') {\r\n break;\r\n }\r\n\r\n wpr += 4;\r\n }\r\n }\r\n\r\n external = true;\r\n\r\n return round(r, pr);\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal times ` + "`") + (`y` + "`")))))) + (((((`, truncated to\r\n * ` + ("`" + `precision`)) + ("`" + (` significant digits.\r\n *\r\n */\r\n P.times = P.mul = function (y) {\r\n var carry, e, i, k, r, rL, t, xdL, ydL,\r\n x = this,\r\n Ctor = x.constructor,\r\n xd = x.d,\r\n yd = (y = new Ctor(y)).d;\r\n\r\n // Return 0 if either is 0.\r\n if (!x.s || !y.s) return new Ctor(0);\r\n\r\n y.s *= x.s;\r\n e = x.e + y.e;\r\n xdL = xd.length;\r\n ydL = yd.length;\r\n\r\n // Ensure xd points to the longer array.\r\n if (xdL < ydL) {\r\n r = xd;\r\n xd = yd;\r\n yd = r;\r\n rL = xdL;\r\n xdL = ydL;\r\n ydL = rL;\r\n }\r\n\r\n // Initialise the result array with zeros.\r\n r = [];\r\n rL = xdL + ydL;\r\n for (i = rL; i--;) r.push(0);\r\n\r\n // Multiply!\r\n for (i = ydL; --i >= 0;) {\r\n carry = 0;\r\n for (k = xdL + i; k > i;) {\r\n t = r[k] + yd[i] * xd[k - i - 1] + carry;\r\n r[k--] = t % BASE | 0;\r\n carry = t / BASE | 0;\r\n }\r\n\r\n r[k] = (r[k] + carry) % BASE | 0;\r\n }\r\n\r\n // Remove trailing zeros.\r\n for (; !r[--rL];) r.pop();\r\n\r\n if (carry) ++e;\r\n else r.shift();\r\n\r\n y.d = r;\r\n y.e = e;\r\n\r\n return external ? round(y, Ctor.precision) : y;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of ` + "`"))) + ((`dp` + ("`" + `\r\n * decimal places using rounding mode `)) + ("`" + (`rm` + "`")))) + (((` or ` + ("`" + `rounding`)) + ("`" + (` if ` + "`"))) + ((`rm` + ("`" + ` is omitted.\r\n *\r\n * If `)) + (("`" + `dp`) + ("`" + ` is omitted, return a new Decimal whose value is the value of this Decimal.\r\n *\r\n * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.\r\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\r\n *\r\n */\r\n P.toDecimalPlaces = P.todp = function (dp, rm) {\r\n var x = this,\r\n Ctor = x.constructor;\r\n\r\n x = new Ctor(x);\r\n if (dp === void 0) return x;\r\n\r\n checkInt32(dp, 0, MAX_DIGITS);\r\n\r\n if (rm === void 0) rm = Ctor.rounding;\r\n else checkInt32(rm, 0, 8);\r\n\r\n return round(x, dp + getBase10Exponent(x) + 1, rm);\r\n };\r\n\r\n\r\n /*\r\n * Return a string representing the value of this Decimal in exponential notation rounded to\r\n * `))))) + (((("`" + (`dp` + "`")) + (` fixed decimal places using rounding mode ` + ("`" + `rounding`))) + (("`" + (`.\r\n *\r\n * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.\r\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\r\n *\r\n */\r\n P.toExponential = function (dp, rm) {\r\n var str,\r\n x = this,\r\n Ctor = x.constructor;\r\n\r\n if (dp === void 0) {\r\n str = toString(x, true);\r\n } else {\r\n checkInt32(dp, 0, MAX_DIGITS);\r\n\r\n if (rm === void 0) rm = Ctor.rounding;\r\n else checkInt32(rm, 0, 8);\r\n\r\n x = round(new Ctor(x), dp + 1, rm);\r\n str = toString(x, true, dp + 1);\r\n }\r\n\r\n return str;\r\n };\r\n\r\n\r\n /*\r\n * Return a string representing the value of this Decimal in normal (fixed-point) notation to\r\n * ` + "`")) + (`dp` + ("`" + ` fixed decimal places and rounded using rounding mode `)))) + ((("`" + (`rm` + "`")) + (` or ` + ("`" + `rounding`))) + (("`" + (` if ` + "`")) + ((`rm` + "`") + (` is\r\n * omitted.\r\n *\r\n * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'.\r\n *\r\n * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive.\r\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\r\n *\r\n * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'.\r\n * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'.\r\n * (-0).toFixed(3) is '0.000'.\r\n * (-0.5).toFixed(0) is '-0'.\r\n *\r\n */\r\n P.toFixed = function (dp, rm) {\r\n var str, y,\r\n x = this,\r\n Ctor = x.constructor;\r\n\r\n if (dp === void 0) return toString(x);\r\n\r\n checkInt32(dp, 0, MAX_DIGITS);\r\n\r\n if (rm === void 0) rm = Ctor.rounding;\r\n else checkInt32(rm, 0, 8);\r\n\r\n y = round(new Ctor(x), dp + getBase10Exponent(x) + 1, rm);\r\n str = toString(y.abs(), false, dp + getBase10Exponent(y) + 1);\r\n\r\n // To determine whether to add the minus sign look at the value before it was rounded,\r\n // i.e. look at ` + "`"))))))) + ((((((`x` + ("`" + ` rather than `)) + ("`" + (`y` + "`"))) + ((`.\r\n return x.isneg() && !x.isZero() ? '-' + str : str;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using\r\n * rounding mode ` + ("`" + `rounding`)) + ("`" + (`.\r\n *\r\n */\r\n P.toInteger = P.toint = function () {\r\n var x = this,\r\n Ctor = x.constructor;\r\n return round(new Ctor(x), getBase10Exponent(x) + 1, Ctor.rounding);\r\n };\r\n\r\n\r\n /*\r\n * Return the value of this Decimal converted to a number primitive.\r\n *\r\n */\r\n P.toNumber = function () {\r\n return +this;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal raised to the power ` + "`")))) + (((`y` + ("`" + `,\r\n * truncated to `)) + ("`" + (`precision` + "`"))) + ((` significant digits.\r\n *\r\n * For non-integer or very large exponents pow(x, y) is calculated using\r\n *\r\n * x^y = exp(y*ln(x))\r\n *\r\n * The maximum error is 1 ulp (unit in last place).\r\n *\r\n * y {number|string|Decimal} The power to which to raise this Decimal.\r\n *\r\n */\r\n P.toPower = P.pow = function (y) {\r\n var e, k, pr, r, sign, yIsInt,\r\n x = this,\r\n Ctor = x.constructor,\r\n guard = 12,\r\n yn = +(y = new Ctor(y));\r\n\r\n // pow(x, 0) = 1\r\n if (!y.s) return new Ctor(ONE);\r\n\r\n x = new Ctor(x);\r\n\r\n // pow(0, y > 0) = 0\r\n // pow(0, y < 0) = Infinity\r\n if (!x.s) {\r\n if (y.s < 1) throw Error(decimalError + 'Infinity');\r\n return x;\r\n }\r\n\r\n // pow(1, y) = 1\r\n if (x.eq(ONE)) return x;\r\n\r\n pr = Ctor.precision;\r\n\r\n // pow(x, 1) = x\r\n if (y.eq(ONE)) return round(x, pr);\r\n\r\n e = y.e;\r\n k = y.d.length - 1;\r\n yIsInt = e >= k;\r\n sign = x.s;\r\n\r\n if (!yIsInt) {\r\n\r\n // pow(x < 0, y non-integer) = NaN\r\n if (sign < 0) throw Error(decimalError + 'NaN');\r\n\r\n // If y is a small integer use the 'exponentiation by squaring' algorithm.\r\n } else if ((k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) {\r\n r = new Ctor(ONE);\r\n\r\n // Max k of 9007199254740991 takes 53 loop iterations.\r\n // Maximum digits array length; leaves [28, 34] guard digits.\r\n e = Math.ceil(pr / LOG_BASE + 4);\r\n\r\n external = false;\r\n\r\n for (;;) {\r\n if (k % 2) {\r\n r = r.times(x);\r\n truncate(r.d, e);\r\n }\r\n\r\n k = mathfloor(k / 2);\r\n if (k === 0) break;\r\n\r\n x = x.times(x);\r\n truncate(x.d, e);\r\n }\r\n\r\n external = true;\r\n\r\n return y.s < 0 ? new Ctor(ONE).div(r) : round(r, pr);\r\n }\r\n\r\n // Result is negative if x is negative and the last digit of integer y is odd.\r\n sign = sign < 0 && y.d[Math.max(e, k)] & 1 ? -1 : 1;\r\n\r\n x.s = 1;\r\n external = false;\r\n r = y.times(ln(x, pr + guard));\r\n external = true;\r\n r = exp(r);\r\n r.s = sign;\r\n\r\n return r;\r\n };\r\n\r\n\r\n /*\r\n * Return a string representing the value of this Decimal rounded to ` + ("`" + `sd`)) + ("`" + (` significant digits\r\n * using rounding mode ` + "`"))))) + ((((`rounding` + ("`" + `.\r\n *\r\n * Return exponential notation if `)) + ("`" + (`sd` + "`"))) + ((` is less than the number of digits necessary to represent\r\n * the integer part of the value in normal notation.\r\n *\r\n * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.\r\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\r\n *\r\n */\r\n P.toPrecision = function (sd, rm) {\r\n var e, str,\r\n x = this,\r\n Ctor = x.constructor;\r\n\r\n if (sd === void 0) {\r\n e = getBase10Exponent(x);\r\n str = toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);\r\n } else {\r\n checkInt32(sd, 1, MAX_DIGITS);\r\n\r\n if (rm === void 0) rm = Ctor.rounding;\r\n else checkInt32(rm, 0, 8);\r\n\r\n x = round(new Ctor(x), sd, rm);\r\n e = getBase10Exponent(x);\r\n str = toString(x, sd <= e || e <= Ctor.toExpNeg, sd);\r\n }\r\n\r\n return str;\r\n };\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of ` + ("`" + `sd`)) + ("`" + (`\r\n * significant digits using rounding mode ` + "`")))) + (((`rm` + ("`" + `, or to `)) + ("`" + (`precision` + "`"))) + ((` and ` + ("`" + `rounding`)) + (("`" + ` respectively if\r\n * omitted.\r\n *\r\n * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive.\r\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\r\n *\r\n */\r\n P.toSignificantDigits = P.tosd = function (sd, rm) {\r\n var x = this,\r\n Ctor = x.constructor;\r\n\r\n if (sd === void 0) {\r\n sd = Ctor.precision;\r\n rm = Ctor.rounding;\r\n } else {\r\n checkInt32(sd, 1, MAX_DIGITS);\r\n\r\n if (rm === void 0) rm = Ctor.rounding;\r\n else checkInt32(rm, 0, 8);\r\n }\r\n\r\n return round(new Ctor(x), sd, rm);\r\n };\r\n\r\n\r\n /*\r\n * Return a string representing the value of this Decimal.\r\n *\r\n * Return exponential notation if this Decimal has a positive exponent equal to or greater than\r\n * `) + ("`" + `toExpPos`)))))) + ((((("`" + (`, or a negative exponent equal to or less than ` + "`")) + (`toExpNeg` + ("`" + `.\r\n *\r\n */\r\n P.toString = P.valueOf = P.val = P.toJSON = function () {\r\n var x = this,\r\n e = getBase10Exponent(x),\r\n Ctor = x.constructor;\r\n\r\n return toString(x, e <= Ctor.toExpNeg || e >= Ctor.toExpPos);\r\n };\r\n\r\n\r\n // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.\r\n\r\n\r\n /*\r\n * add P.minus, P.plus\r\n * checkInt32 P.todp, P.toExponential, P.toFixed, P.toPrecision, P.tosd\r\n * digitsToString P.log, P.sqrt, P.pow, toString, exp, ln\r\n * divide P.div, P.idiv, P.log, P.mod, P.sqrt, exp, ln\r\n * exp P.exp, P.pow\r\n * getBase10Exponent P.exponent, P.sd, P.toint, P.sqrt, P.todp, P.toFixed, P.toPrecision,\r\n * P.toString, divide, round, toString, exp, ln\r\n * getLn10 P.log, ln\r\n * getZeroString digitsToString, toString\r\n * ln P.log, P.ln, P.pow, exp\r\n * parseDecimal Decimal\r\n * round P.abs, P.idiv, P.log, P.minus, P.mod, P.neg, P.plus, P.toint, P.sqrt,\r\n * P.times, P.todp, P.toExponential, P.toFixed, P.pow, P.toPrecision, P.tosd,\r\n * divide, getLn10, exp, ln\r\n * subtract P.minus, P.plus\r\n * toString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf\r\n * truncate P.pow\r\n *\r\n * Throws: P.log, P.mod, P.sd, P.sqrt, P.pow, checkInt32, divide, round,\r\n * getLn10, exp, ln, parseDecimal, Decimal, config\r\n */\r\n\r\n\r\n function add(x, y) {\r\n var carry, d, e, i, k, len, xd, yd,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision;\r\n\r\n // If either is zero...\r\n if (!x.s || !y.s) {\r\n\r\n // Return x if y is zero.\r\n // Return y if y is non-zero.\r\n if (!y.s) y = new Ctor(x);\r\n return external ? round(y, pr) : y;\r\n }\r\n\r\n xd = x.d;\r\n yd = y.d;\r\n\r\n // x and y are finite, non-zero numbers with the same sign.\r\n\r\n k = x.e;\r\n e = y.e;\r\n xd = xd.slice();\r\n i = k - e;\r\n\r\n // If base 1e7 exponents differ...\r\n if (i) {\r\n if (i < 0) {\r\n d = xd;\r\n i = -i;\r\n len = yd.length;\r\n } else {\r\n d = yd;\r\n e = k;\r\n len = xd.length;\r\n }\r\n\r\n // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1.\r\n k = Math.ceil(pr / LOG_BASE);\r\n len = k > len ? k + 1 : len + 1;\r\n\r\n if (i > len) {\r\n i = len;\r\n d.length = 1;\r\n }\r\n\r\n // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts.\r\n d.reverse();\r\n for (; i--;) d.push(0);\r\n d.reverse();\r\n }\r\n\r\n len = xd.length;\r\n i = yd.length;\r\n\r\n // If yd is longer than xd, swap xd and yd so xd points to the longer array.\r\n if (len - i < 0) {\r\n i = len;\r\n d = yd;\r\n yd = xd;\r\n xd = d;\r\n }\r\n\r\n // Only start adding at yd.length - 1 as the further digits of xd can be left as they are.\r\n for (carry = 0; i;) {\r\n carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0;\r\n xd[i] %= BASE;\r\n }\r\n\r\n if (carry) {\r\n xd.unshift(carry);\r\n ++e;\r\n }\r\n\r\n // Remove trailing zeros.\r\n // No need to check for zero, as +x + +y != 0 && -x + -y != 0\r\n for (len = xd.length; xd[--len] == 0;) xd.pop();\r\n\r\n y.d = xd;\r\n y.e = e;\r\n\r\n return external ? round(y, pr) : y;\r\n }\r\n\r\n\r\n function checkInt32(i, min, max) {\r\n if (i !== ~~i || i < min || i > max) {\r\n throw Error(invalidArgument + i);\r\n }\r\n }\r\n\r\n\r\n function digitsToString(d) {\r\n var i, k, ws,\r\n indexOfLastWord = d.length - 1,\r\n str = '',\r\n w = d[0];\r\n\r\n if (indexOfLastWord > 0) {\r\n str += w;\r\n for (i = 1; i < indexOfLastWord; i++) {\r\n ws = d[i] + '';\r\n k = LOG_BASE - ws.length;\r\n if (k) str += getZeroString(k);\r\n str += ws;\r\n }\r\n\r\n w = d[i];\r\n ws = w + '';\r\n k = LOG_BASE - ws.length;\r\n if (k) str += getZeroString(k);\r\n } else if (w === 0) {\r\n return '0';\r\n }\r\n\r\n // Remove trailing zeros of last w.\r\n for (; w % 10 === 0;) w /= 10;\r\n\r\n return str + w;\r\n }\r\n\r\n\r\n var divide = (function () {\r\n\r\n // Assumes non-zero x and k, and hence non-zero result.\r\n function multiplyInteger(x, k) {\r\n var temp,\r\n carry = 0,\r\n i = x.length;\r\n\r\n for (x = x.slice(); i--;) {\r\n temp = x[i] * k + carry;\r\n x[i] = temp % BASE | 0;\r\n carry = temp / BASE | 0;\r\n }\r\n\r\n if (carry) x.unshift(carry);\r\n\r\n return x;\r\n }\r\n\r\n function compare(a, b, aL, bL) {\r\n var i, r;\r\n\r\n if (aL != bL) {\r\n r = aL > bL ? 1 : -1;\r\n } else {\r\n for (i = r = 0; i < aL; i++) {\r\n if (a[i] != b[i]) {\r\n r = a[i] > b[i] ? 1 : -1;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return r;\r\n }\r\n\r\n function subtract(a, b, aL) {\r\n var i = 0;\r\n\r\n // Subtract b from a.\r\n for (; aL--;) {\r\n a[aL] -= i;\r\n i = a[aL] < b[aL] ? 1 : 0;\r\n a[aL] = i * BASE + a[aL] - b[aL];\r\n }\r\n\r\n // Remove leading zeros.\r\n for (; !a[0] && a.length > 1;) a.shift();\r\n }\r\n\r\n return function (x, y, pr, dp) {\r\n var cmp, e, i, k, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, yL, yz,\r\n Ctor = x.constructor,\r\n sign = x.s == y.s ? 1 : -1,\r\n xd = x.d,\r\n yd = y.d;\r\n\r\n // Either 0?\r\n if (!x.s) return new Ctor(x);\r\n if (!y.s) throw Error(decimalError + 'Division by zero');\r\n\r\n e = x.e - y.e;\r\n yL = yd.length;\r\n xL = xd.length;\r\n q = new Ctor(sign);\r\n qd = q.d = [];\r\n\r\n // Result exponent may be one less than e.\r\n for (i = 0; yd[i] == (xd[i] || 0); ) ++i;\r\n if (yd[i] > (xd[i] || 0)) --e;\r\n\r\n if (pr == null) {\r\n sd = pr = Ctor.precision;\r\n } else if (dp) {\r\n sd = pr + (getBase10Exponent(x) - getBase10Exponent(y)) + 1;\r\n } else {\r\n sd = pr;\r\n }\r\n\r\n if (sd < 0) return new Ctor(0);\r\n\r\n // Convert precision in number of base 10 digits to base 1e7 digits.\r\n sd = sd / LOG_BASE + 2 | 0;\r\n i = 0;\r\n\r\n // divisor < 1e7\r\n if (yL == 1) {\r\n k = 0;\r\n yd = yd[0];\r\n sd++;\r\n\r\n // k is the carry.\r\n for (; (i < xL || k) && sd--; i++) {\r\n t = k * BASE + (xd[i] || 0);\r\n qd[i] = t / yd | 0;\r\n k = t % yd | 0;\r\n }\r\n\r\n // divisor >= 1e7\r\n } else {\r\n\r\n // Normalise xd and yd so highest order digit of yd is >= BASE/2\r\n k = BASE / (yd[0] + 1) | 0;\r\n\r\n if (k > 1) {\r\n yd = multiplyInteger(yd, k);\r\n xd = multiplyInteger(xd, k);\r\n yL = yd.length;\r\n xL = xd.length;\r\n }\r\n\r\n xi = yL;\r\n rem = xd.slice(0, yL);\r\n remL = rem.length;\r\n\r\n // Add zeros to make remainder as long as divisor.\r\n for (; remL < yL;) rem[remL++] = 0;\r\n\r\n yz = yd.slice();\r\n yz.unshift(0);\r\n yd0 = yd[0];\r\n\r\n if (yd[1] >= BASE / 2) ++yd0;\r\n\r\n do {\r\n k = 0;\r\n\r\n // Compare divisor and remainder.\r\n cmp = compare(yd, rem, yL, remL);\r\n\r\n // If divisor < remainder.\r\n if (cmp < 0) {\r\n\r\n // Calculate trial digit, k.\r\n rem0 = rem[0];\r\n if (yL != remL) rem0 = rem0 * BASE + (rem[1] || 0);\r\n\r\n // k will be how many times the divisor goes into the current remainder.\r\n k = rem0 / yd0 | 0;\r\n\r\n // Algorithm:\r\n // 1. product = divisor * trial digit (k)\r\n // 2. if product > remainder: product -= divisor, k--\r\n // 3. remainder -= product\r\n // 4. if product was < remainder at 2:\r\n // 5. compare new remainder and divisor\r\n // 6. If remainder > divisor: remainder -= divisor, k++\r\n\r\n if (k > 1) {\r\n if (k >= BASE) k = BASE - 1;\r\n\r\n // product = divisor * trial digit.\r\n prod = multiplyInteger(yd, k);\r\n prodL = prod.length;\r\n remL = rem.length;\r\n\r\n // Compare product and remainder.\r\n cmp = compare(prod, rem, prodL, remL);\r\n\r\n // product > remainder.\r\n if (cmp == 1) {\r\n k--;\r\n\r\n // Subtract divisor from product.\r\n subtract(prod, yL < prodL ? yz : yd, prodL);\r\n }\r\n } else {\r\n\r\n // cmp is -1.\r\n // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1\r\n // to avoid it. If k is 1 there is a need to compare yd and rem again below.\r\n if (k == 0) cmp = k = 1;\r\n prod = yd.slice();\r\n }\r\n\r\n prodL = prod.length;\r\n if (prodL < remL) prod.unshift(0);\r\n\r\n // Subtract product from remainder.\r\n subtract(rem, prod, remL);\r\n\r\n // If product was < previous remainder.\r\n if (cmp == -1) {\r\n remL = rem.length;\r\n\r\n // Compare divisor and new remainder.\r\n cmp = compare(yd, rem, yL, remL);\r\n\r\n // If divisor < new remainder, subtract divisor from remainder.\r\n if (cmp < 1) {\r\n k++;\r\n\r\n // Subtract divisor from remainder.\r\n subtract(rem, yL < remL ? yz : yd, remL);\r\n }\r\n }\r\n\r\n remL = rem.length;\r\n } else if (cmp === 0) {\r\n k++;\r\n rem = [0];\r\n } // if cmp === 1, k will be 0\r\n\r\n // Add the next digit, k, to the result array.\r\n qd[i++] = k;\r\n\r\n // Update the remainder.\r\n if (cmp && rem[0]) {\r\n rem[remL++] = xd[xi] || 0;\r\n } else {\r\n rem = [xd[xi]];\r\n remL = 1;\r\n }\r\n\r\n } while ((xi++ < xL || rem[0] !== void 0) && sd--);\r\n }\r\n\r\n // Leading zero?\r\n if (!qd[0]) qd.shift();\r\n\r\n q.e = e;\r\n\r\n return round(q, dp ? pr + getBase10Exponent(q) + 1 : pr);\r\n };\r\n })();\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the natural exponential of `))) + (("`" + (`x` + "`")) + (` truncated to ` + ("`" + `sd`)))) + ((("`" + (`\r\n * significant digits.\r\n *\r\n * Taylor/Maclaurin series.\r\n *\r\n * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ...\r\n *\r\n * Argument reduction:\r\n * Repeat x = x / 32, k += 5, until |x| < 0.1\r\n * exp(x) = exp(x / 2^k)^(2^k)\r\n *\r\n * Previously, the argument was initially reduced by\r\n * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10)\r\n * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was\r\n * found to be slower than just dividing repeatedly by 32 as above.\r\n *\r\n * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324)\r\n *\r\n * exp(x) is non-terminating for any finite, non-zero x.\r\n *\r\n */\r\n function exp(x, sd) {\r\n var denominator, guard, pow, sum, t, wpr,\r\n i = 0,\r\n k = 0,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision;\r\n\r\n if (getBase10Exponent(x) > 16) throw Error(exponentOutOfRange + getBase10Exponent(x));\r\n\r\n // exp(0) = 1\r\n if (!x.s) return new Ctor(ONE);\r\n\r\n if (sd == null) {\r\n external = false;\r\n wpr = pr;\r\n } else {\r\n wpr = sd;\r\n }\r\n\r\n t = new Ctor(0.03125);\r\n\r\n while (x.abs().gte(0.1)) {\r\n x = x.times(t); // x = x / 2^5\r\n k += 5;\r\n }\r\n\r\n // Estimate the precision increase necessary to ensure the first 4 rounding digits are correct.\r\n guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0;\r\n wpr += guard;\r\n denominator = pow = sum = new Ctor(ONE);\r\n Ctor.precision = wpr;\r\n\r\n for (;;) {\r\n pow = round(pow.times(x), wpr);\r\n denominator = denominator.times(++i);\r\n t = sum.plus(divide(pow, denominator, wpr));\r\n\r\n if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {\r\n while (k--) sum = round(sum.times(sum), wpr);\r\n Ctor.precision = pr;\r\n return sd == null ? (external = true, round(sum, pr)) : sum;\r\n }\r\n\r\n sum = t;\r\n }\r\n }\r\n\r\n\r\n // Calculate the base 10 exponent from the base 1e7 exponent.\r\n function getBase10Exponent(x) {\r\n var e = x.e * LOG_BASE,\r\n w = x.d[0];\r\n\r\n // Add the number of digits of the first word of the digits array.\r\n for (; w >= 10; w /= 10) e++;\r\n return e;\r\n }\r\n\r\n\r\n function getLn10(Ctor, sd, pr) {\r\n\r\n if (sd > Ctor.LN10.sd()) {\r\n\r\n\r\n // Reset global state in case the exception is caught.\r\n external = true;\r\n if (pr) Ctor.precision = pr;\r\n throw Error(decimalError + 'LN10 precision limit exceeded');\r\n }\r\n\r\n return round(new Ctor(Ctor.LN10), sd);\r\n }\r\n\r\n\r\n function getZeroString(k) {\r\n var zs = '';\r\n for (; k--;) zs += '0';\r\n return zs;\r\n }\r\n\r\n\r\n /*\r\n * Return a new Decimal whose value is the natural logarithm of ` + "`")) + (`x` + ("`" + ` truncated to `))) + (("`" + (`sd` + "`")) + ((` significant\r\n * digits.\r\n *\r\n * ln(n) is non-terminating (n != 1)\r\n *\r\n */\r\n function ln(y, sd) {\r\n var c, c0, denominator, e, numerator, sum, t, wpr, x2,\r\n n = 1,\r\n guard = 10,\r\n x = y,\r\n xd = x.d,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision;\r\n\r\n // ln(-x) = NaN\r\n // ln(0) = -Infinity\r\n if (x.s < 1) throw Error(decimalError + (x.s ? 'NaN' : '-Infinity'));\r\n\r\n // ln(1) = 0\r\n if (x.eq(ONE)) return new Ctor(0);\r\n\r\n if (sd == null) {\r\n external = false;\r\n wpr = pr;\r\n } else {\r\n wpr = sd;\r\n }\r\n\r\n if (x.eq(10)) {\r\n if (sd == null) external = true;\r\n return getLn10(Ctor, wpr);\r\n }\r\n\r\n wpr += guard;\r\n Ctor.precision = wpr;\r\n c = digitsToString(xd);\r\n c0 = c.charAt(0);\r\n e = getBase10Exponent(x);\r\n\r\n if (Math.abs(e) < 1.5e15) {\r\n\r\n // Argument reduction.\r\n // The series converges faster the closer the argument is to 1, so using\r\n // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b\r\n // multiply the argument by itself until the leading digits of the significand are 7, 8, 9,\r\n // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can\r\n // later be divided by this number, then separate out the power of 10 using\r\n // ln(a*10^b) = ln(a) + b*ln(10).\r\n\r\n // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14).\r\n //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) {\r\n // max n is 6 (gives 0.7 - 1.3)\r\n while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) {\r\n x = x.times(y);\r\n c = digitsToString(x.d);\r\n c0 = c.charAt(0);\r\n n++;\r\n }\r\n\r\n e = getBase10Exponent(x);\r\n\r\n if (c0 > 1) {\r\n x = new Ctor('0.' + c);\r\n e++;\r\n } else {\r\n x = new Ctor(c0 + '.' + c.slice(1));\r\n }\r\n } else {\r\n\r\n // The argument reduction method above may result in overflow if the argument y is a massive\r\n // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this\r\n // function using ln(x*10^e) = ln(x) + e*ln(10).\r\n t = getLn10(Ctor, wpr + 2, pr).times(e + '');\r\n x = ln(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t);\r\n\r\n Ctor.precision = pr;\r\n return sd == null ? (external = true, round(x, pr)) : x;\r\n }\r\n\r\n // x is reduced to a value near 1.\r\n\r\n // Taylor series.\r\n // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...)\r\n // where x = (y - 1)/(y + 1) (|x| < 1)\r\n sum = numerator = x = divide(x.minus(ONE), x.plus(ONE), wpr);\r\n x2 = round(x.times(x), wpr);\r\n denominator = 3;\r\n\r\n for (;;) {\r\n numerator = round(numerator.times(x2), wpr);\r\n t = sum.plus(divide(numerator, new Ctor(denominator), wpr));\r\n\r\n if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) {\r\n sum = sum.times(2);\r\n\r\n // Reverse the argument reduction.\r\n if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + ''));\r\n sum = divide(sum, new Ctor(n), wpr);\r\n\r\n Ctor.precision = pr;\r\n return sd == null ? (external = true, round(sum, pr)) : sum;\r\n }\r\n\r\n sum = t;\r\n denominator += 2;\r\n }\r\n }\r\n\r\n\r\n /*\r\n * Parse the value of a new Decimal ` + "`") + (`x` + "`"))))) + ((((` from string ` + ("`" + `str`)) + ("`" + (`.\r\n */\r\n function parseDecimal(x, str) {\r\n var e, i, len;\r\n\r\n // Decimal point?\r\n if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');\r\n\r\n // Exponential form?\r\n if ((i = str.search(/e/i)) > 0) {\r\n\r\n // Determine exponent.\r\n if (e < 0) e = i;\r\n e += +str.slice(i + 1);\r\n str = str.substring(0, i);\r\n } else if (e < 0) {\r\n\r\n // Integer.\r\n e = str.length;\r\n }\r\n\r\n // Determine leading zeros.\r\n for (i = 0; str.charCodeAt(i) === 48;) ++i;\r\n\r\n // Determine trailing zeros.\r\n for (len = str.length; str.charCodeAt(len - 1) === 48;) --len;\r\n str = str.slice(i, len);\r\n\r\n if (str) {\r\n len -= i;\r\n e = e - i - 1;\r\n x.e = mathfloor(e / LOG_BASE);\r\n x.d = [];\r\n\r\n // Transform base\r\n\r\n // e is the base 10 exponent.\r\n // i is where to slice str to get the first word of the digits array.\r\n i = (e + 1) % LOG_BASE;\r\n if (e < 0) i += LOG_BASE;\r\n\r\n if (i < len) {\r\n if (i) x.d.push(+str.slice(0, i));\r\n for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE));\r\n str = str.slice(i);\r\n i = LOG_BASE - str.length;\r\n } else {\r\n i -= len;\r\n }\r\n\r\n for (; i--;) str += '0';\r\n x.d.push(+str);\r\n\r\n if (external && (x.e > MAX_E || x.e < -MAX_E)) throw Error(exponentOutOfRange + e);\r\n } else {\r\n\r\n // Zero.\r\n x.s = 0;\r\n x.e = 0;\r\n x.d = [0];\r\n }\r\n\r\n return x;\r\n }\r\n\r\n\r\n /*\r\n * Round ` + "`"))) + ((`x` + ("`" + ` to `)) + ("`" + (`sd` + "`")))) + (((` significant digits, using rounding mode ` + ("`" + `rm`)) + ("`" + (` if present (truncate otherwise).\r\n */\r\n function round(x, sd, rm) {\r\n var i, j, k, n, rd, doRound, w, xdi,\r\n xd = x.d;\r\n\r\n // rd: the rounding digit, i.e. the digit after the digit that may be rounded up.\r\n // w: the word of xd which contains the rounding digit, a base 1e7 number.\r\n // xdi: the index of w within xd.\r\n // n: the number of digits of w.\r\n // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if\r\n // they had leading zeros)\r\n // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero).\r\n\r\n // Get the length of the first word of the digits array xd.\r\n for (n = 1, k = xd[0]; k >= 10; k /= 10) n++;\r\n i = sd - n;\r\n\r\n // Is the rounding digit in the first word of xd?\r\n if (i < 0) {\r\n i += LOG_BASE;\r\n j = sd;\r\n w = xd[xdi = 0];\r\n } else {\r\n xdi = Math.ceil((i + 1) / LOG_BASE);\r\n k = xd.length;\r\n if (xdi >= k) return x;\r\n w = k = xd[xdi];\r\n\r\n // Get the number of digits of w.\r\n for (n = 1; k >= 10; k /= 10) n++;\r\n\r\n // Get the index of rd within w.\r\n i %= LOG_BASE;\r\n\r\n // Get the index of rd within w, adjusted for leading zeros.\r\n // The number of leading zeros of w is given by LOG_BASE - n.\r\n j = i - LOG_BASE + n;\r\n }\r\n\r\n if (rm !== void 0) {\r\n k = mathpow(10, n - j - 1);\r\n\r\n // Get the rounding digit at index j of w.\r\n rd = w / k % 10 | 0;\r\n\r\n // Are there any non-zero digits after the rounding digit?\r\n doRound = sd < 0 || xd[xdi + 1] !== void 0 || w % k;\r\n\r\n // The expression ` + "`"))) + ((`w % mathpow(10, n - j - 1)` + ("`" + ` returns all the digits of w to the right of the\r\n // digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression will give\r\n // 714.\r\n\r\n doRound = rm < 4\r\n ? (rd || doRound) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))\r\n : rd > 5 || rd == 5 && (rm == 4 || doRound || rm == 6 &&\r\n\r\n // Check whether the digit to the left of the rounding digit is odd.\r\n ((i > 0 ? j > 0 ? w / mathpow(10, n - j) : 0 : xd[xdi - 1]) % 10) & 1 ||\r\n rm == (x.s < 0 ? 8 : 7));\r\n }\r\n\r\n if (sd < 1 || !xd[0]) {\r\n if (doRound) {\r\n k = getBase10Exponent(x);\r\n xd.length = 1;\r\n\r\n // Convert sd to decimal places.\r\n sd = sd - k - 1;\r\n\r\n // 1, 0.1, 0.01, 0.001, 0.0001 etc.\r\n xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE);\r\n x.e = mathfloor(-sd / LOG_BASE) || 0;\r\n } else {\r\n xd.length = 1;\r\n\r\n // Zero.\r\n xd[0] = x.e = x.s = 0;\r\n }\r\n\r\n return x;\r\n }\r\n\r\n // Remove excess digits.\r\n if (i == 0) {\r\n xd.length = xdi;\r\n k = 1;\r\n xdi--;\r\n } else {\r\n xd.length = xdi + 1;\r\n k = mathpow(10, LOG_BASE - i);\r\n\r\n // E.g. 56700 becomes 56000 if 7 is the rounding digit.\r\n // j > 0 means i > number of leading zeros of w.\r\n xd[xdi] = j > 0 ? (w / mathpow(10, n - j) % mathpow(10, j) | 0) * k : 0;\r\n }\r\n\r\n if (doRound) {\r\n for (;;) {\r\n\r\n // Is the digit to be rounded up in the first word of xd?\r\n if (xdi == 0) {\r\n if ((xd[0] += k) == BASE) {\r\n xd[0] = 1;\r\n ++x.e;\r\n }\r\n\r\n break;\r\n } else {\r\n xd[xdi] += k;\r\n if (xd[xdi] != BASE) break;\r\n xd[xdi--] = 0;\r\n k = 1;\r\n }\r\n }\r\n }\r\n\r\n // Remove trailing zeros.\r\n for (i = xd.length; xd[--i] === 0;) xd.pop();\r\n\r\n if (external && (x.e > MAX_E || x.e < -MAX_E)) {\r\n throw Error(exponentOutOfRange + getBase10Exponent(x));\r\n }\r\n\r\n return x;\r\n }\r\n\r\n\r\n function subtract(x, y) {\r\n var d, e, i, j, k, len, xd, xe, xLTy, yd,\r\n Ctor = x.constructor,\r\n pr = Ctor.precision;\r\n\r\n // Return y negated if x is zero.\r\n // Return x if y is zero and x is non-zero.\r\n if (!x.s || !y.s) {\r\n if (y.s) y.s = -y.s;\r\n else y = new Ctor(x);\r\n return external ? round(y, pr) : y;\r\n }\r\n\r\n xd = x.d;\r\n yd = y.d;\r\n\r\n // x and y are non-zero numbers with the same sign.\r\n\r\n e = y.e;\r\n xe = x.e;\r\n xd = xd.slice();\r\n k = xe - e;\r\n\r\n // If exponents differ...\r\n if (k) {\r\n xLTy = k < 0;\r\n\r\n if (xLTy) {\r\n d = xd;\r\n k = -k;\r\n len = yd.length;\r\n } else {\r\n d = yd;\r\n e = xe;\r\n len = xd.length;\r\n }\r\n\r\n // Numbers with massively different exponents would result in a very high number of zeros\r\n // needing to be prepended, but this can be avoided while still ensuring correct rounding by\r\n // limiting the number of zeros to `)) + (("`" + `Math.ceil(pr / LOG_BASE) + 2`) + ("`" + `.\r\n i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2;\r\n\r\n if (k > i) {\r\n k = i;\r\n d.length = 1;\r\n }\r\n\r\n // Prepend zeros to equalise exponents.\r\n d.reverse();\r\n for (i = k; i--;) d.push(0);\r\n d.reverse();\r\n\r\n // Base 1e7 exponents equal.\r\n } else {\r\n\r\n // Check digits to determine which is the bigger number.\r\n\r\n i = xd.length;\r\n len = yd.length;\r\n xLTy = i < len;\r\n if (xLTy) len = i;\r\n\r\n for (i = 0; i < len; i++) {\r\n if (xd[i] != yd[i]) {\r\n xLTy = xd[i] < yd[i];\r\n break;\r\n }\r\n }\r\n\r\n k = 0;\r\n }\r\n\r\n if (xLTy) {\r\n d = xd;\r\n xd = yd;\r\n yd = d;\r\n y.s = -y.s;\r\n }\r\n\r\n len = xd.length;\r\n\r\n // Append zeros to xd if shorter.\r\n // Don't add zeros to yd if shorter as subtraction only needs to start at yd length.\r\n for (i = yd.length - len; i > 0; --i) xd[len++] = 0;\r\n\r\n // Subtract yd from xd.\r\n for (i = yd.length; i > k;) {\r\n if (xd[--i] < yd[i]) {\r\n for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1;\r\n --xd[j];\r\n xd[i] += BASE;\r\n }\r\n\r\n xd[i] -= yd[i];\r\n }\r\n\r\n // Remove trailing zeros.\r\n for (; xd[--len] === 0;) xd.pop();\r\n\r\n // Remove leading zeros and adjust exponent accordingly.\r\n for (; xd[0] === 0; xd.shift()) --e;\r\n\r\n // Zero?\r\n if (!xd[0]) return new Ctor(0);\r\n\r\n y.d = xd;\r\n y.e = e;\r\n\r\n //return external && xd.length >= pr / LOG_BASE ? round(y, pr) : y;\r\n return external ? round(y, pr) : y;\r\n }\r\n\r\n\r\n function toString(x, isExp, sd) {\r\n var k,\r\n e = getBase10Exponent(x),\r\n str = digitsToString(x.d),\r\n len = str.length;\r\n\r\n if (isExp) {\r\n if (sd && (k = sd - len) > 0) {\r\n str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k);\r\n } else if (len > 1) {\r\n str = str.charAt(0) + '.' + str.slice(1);\r\n }\r\n\r\n str = str + (e < 0 ? 'e' : 'e+') + e;\r\n } else if (e < 0) {\r\n str = '0.' + getZeroString(-e - 1) + str;\r\n if (sd && (k = sd - len) > 0) str += getZeroString(k);\r\n } else if (e >= len) {\r\n str += getZeroString(e + 1 - len);\r\n if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k);\r\n } else {\r\n if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k);\r\n if (sd && (k = sd - len) > 0) {\r\n if (e + 1 === len) str += '.';\r\n str += getZeroString(k);\r\n }\r\n }\r\n\r\n return x.s < 0 ? '-' + str : str;\r\n }\r\n\r\n\r\n // Does not strip trailing zeros.\r\n function truncate(arr, len) {\r\n if (arr.length > len) {\r\n arr.length = len;\r\n return true;\r\n }\r\n }\r\n\r\n\r\n // Decimal methods\r\n\r\n\r\n /*\r\n * clone\r\n * config/set\r\n */\r\n\r\n\r\n /*\r\n * Create and return a Decimal constructor with the same configuration properties as this Decimal\r\n * constructor.\r\n *\r\n */\r\n function clone(obj) {\r\n var i, p, ps;\r\n\r\n /*\r\n * The Decimal constructor and exported function.\r\n * Return a new Decimal instance.\r\n *\r\n * value {number|string|Decimal} A numeric value.\r\n *\r\n */\r\n function Decimal(value) {\r\n var x = this;\r\n\r\n // Decimal called without new.\r\n if (!(x instanceof Decimal)) return new Decimal(value);\r\n\r\n // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor\r\n // which points to Object.\r\n x.constructor = Decimal;\r\n\r\n // Duplicate.\r\n if (value instanceof Decimal) {\r\n x.s = value.s;\r\n x.e = value.e;\r\n x.d = (value = value.d) ? value.slice() : value;\r\n return;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n\r\n // Reject Infinity/NaN.\r\n if (value * 0 !== 0) {\r\n throw Error(invalidArgument + value);\r\n }\r\n\r\n if (value > 0) {\r\n x.s = 1;\r\n } else if (value < 0) {\r\n value = -value;\r\n x.s = -1;\r\n } else {\r\n x.s = 0;\r\n x.e = 0;\r\n x.d = [0];\r\n return;\r\n }\r\n\r\n // Fast path for small integers.\r\n if (value === ~~value && value < 1e7) {\r\n x.e = 0;\r\n x.d = [value];\r\n return;\r\n }\r\n\r\n return parseDecimal(x, value.toString());\r\n } else if (typeof value !== 'string') {\r\n throw Error(invalidArgument + value);\r\n }\r\n\r\n // Minus sign?\r\n if (value.charCodeAt(0) === 45) {\r\n value = value.slice(1);\r\n x.s = -1;\r\n } else {\r\n x.s = 1;\r\n }\r\n\r\n if (isDecimal.test(value)) parseDecimal(x, value);\r\n else throw Error(invalidArgument + value);\r\n }\r\n\r\n Decimal.prototype = P;\r\n\r\n Decimal.ROUND_UP = 0;\r\n Decimal.ROUND_DOWN = 1;\r\n Decimal.ROUND_CEIL = 2;\r\n Decimal.ROUND_FLOOR = 3;\r\n Decimal.ROUND_HALF_UP = 4;\r\n Decimal.ROUND_HALF_DOWN = 5;\r\n Decimal.ROUND_HALF_EVEN = 6;\r\n Decimal.ROUND_HALF_CEIL = 7;\r\n Decimal.ROUND_HALF_FLOOR = 8;\r\n\r\n Decimal.clone = clone;\r\n Decimal.config = Decimal.set = config;\r\n\r\n if (obj === void 0) obj = {};\r\n if (obj) {\r\n ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'LN10'];\r\n for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p];\r\n }\r\n\r\n Decimal.config(obj);\r\n\r\n return Decimal;\r\n }\r\n\r\n\r\n /*\r\n * Configure global settings for a Decimal constructor.\r\n *\r\n * `))))))))) + (((((((("`" + (`obj` + "`")) + (` is an object with one or more of the following properties,\r\n *\r\n * precision {number}\r\n * rounding {number}\r\n * toExpNeg {number}\r\n * toExpPos {number}\r\n *\r\n * E.g. Decimal.config({ precision: 20, rounding: 4 })\r\n *\r\n */\r\n function config(obj) {\r\n if (!obj || typeof obj !== 'object') {\r\n throw Error(decimalError + 'Object expected');\r\n }\r\n var i, p, v,\r\n ps = [\r\n 'precision', 1, MAX_DIGITS,\r\n 'rounding', 0, 8,\r\n 'toExpNeg', -1 / 0, 0,\r\n 'toExpPos', 0, 1 / 0\r\n ];\r\n\r\n for (i = 0; i < ps.length; i += 3) {\r\n if ((v = obj[p = ps[i]]) !== void 0) {\r\n if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v;\r\n else throw Error(invalidArgument + p + ': ' + v);\r\n }\r\n }\r\n\r\n if ((v = obj[p = 'LN10']) !== void 0) {\r\n if (v == Math.LN10) this[p] = new this(v);\r\n else throw Error(invalidArgument + p + ': ' + v);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n\r\n // Create and configure initial Decimal constructor.\r\n Decimal = clone(Decimal);\r\n\r\n Decimal['default'] = Decimal.Decimal = Decimal;\r\n\r\n // Internal constant.\r\n ONE = new Decimal(1);\r\n\r\n\r\n // Export.\r\n\r\n\r\n // AMD.\r\n if (typeof define == 'function' && define.amd) {\r\n define(function () {\r\n return Decimal;\r\n });\r\n\r\n // Node and other environments that support module.exports.\r\n } else if (typeof module != 'undefined' && module.exports) {\r\n module.exports = Decimal;\r\n\r\n // Browser.\r\n } else {\r\n if (!globalScope) {\r\n globalScope = typeof self != 'undefined' && self && self.self == self\r\n ? self : Function('return this')();\r\n }\r\n\r\n globalScope.Decimal = Decimal;\r\n }\r\n})(this);\r\n", + "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.deepmerge = factory());\n}(this, (function () { 'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tObject.keys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tObject.keys(source).forEach(function(key) {\n\t\tif (!options.isMergeableObject(source[key]) || !target[key]) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nreturn deepmerge_1;\n\n})));\n", + "\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nexports.__esModule = true;\nexports.default = addClass;\n\nvar _hasClass = _interopRequireDefault(require(\"./hasClass\"));\n\nfunction addClass(element, className) {\n if (element.classList) element.classList.add(className);else if (!(0, _hasClass.default)(element, className)) if (typeof element.className === 'string') element.className = element.className + ' ' + className;else element.setAttribute('class', (element.className && element.className.baseVal || '') + ' ' + className);\n}\n\nmodule.exports = exports[\"default\"];", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = hasClass;\n\nfunction hasClass(element, className) {\n if (element.classList) return !!className && element.classList.contains(className);else return (\" \" + (element.className.baseVal || element.className) + \" \").indexOf(\" \" + className + \" \") !== -1;\n}\n\nmodule.exports = exports[\"default\"];", + "'use strict';\n\nfunction replaceClassName(origClass, classToRemove) {\n return origClass.replace(new RegExp('(^|\\\\s)' + classToRemove + '(?:\\\\s|$)', 'g'), '$1').replace(/\\s+/g, ' ').replace(/^\\s*|\\s*$/g, '');\n}\n\nmodule.exports = function removeClass(element, className) {\n if (element.classList) element.classList.remove(className);else if (typeof element.className === 'string') element.className = replaceClassName(element.className, className);else element.setAttribute('class', replaceClassName(element.className && element.className.baseVal || '', className));\n};", + "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", + "// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction $getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return $getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the ` + ("`" + `throw`))) + (("`" + (` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign ` + "`")) + (`events` + ("`" + ` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = $getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n var args = [];\n for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n ReflectApply(this.listener, this.target, args);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n", + "'use strict';\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar ReactIs = require('react-is');\nvar REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true\n};\n\nvar KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true\n};\n\nvar FORWARD_REF_STATICS = {\n '$$typeof': true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true\n};\n\nvar MEMO_STATICS = {\n '$$typeof': true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true\n};\n\nvar TYPE_STATICS = {};\nTYPE_STATICS[ReactIs.ForwardRef] = FORWARD_REF_STATICS;\n\nfunction getStatics(component) {\n if (ReactIs.isMemo(component)) {\n return MEMO_STATICS;\n }\n return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\n\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n if (typeof sourceComponent !== 'string') {\n // don't hoist over string (html) components\n\n if (objectPrototype) {\n var inheritedComponent = getPrototypeOf(sourceComponent);\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n }\n }\n\n var keys = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n var targetStatics = getStatics(targetComponent);\n var sourceStatics = getStatics(sourceComponent);\n\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {}\n }\n }\n\n return targetComponent;\n }\n\n return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n", + "/* eslint-disable no-var, prefer-template */\nvar uppercasePattern = /[A-Z]/g\nvar msPattern = /^ms-/\nvar cache = {}\n\nfunction toHyphenLower(match) {\n return '-' + match.toLowerCase()\n}\n\nfunction hyphenateStyleName(name) {\n if (cache.hasOwnProperty(name)) {\n return cache[name]\n }\n\n var hName = name.replace(uppercasePattern, toHyphenLower)\n return (cache[name] = msPattern.test(hName) ? '-' + hName : hName)\n}\n\nexport default hyphenateStyleName\n", + "var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nexport var isBrowser = (typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) === \"object\" && (typeof document === \"undefined\" ? \"undefined\" : _typeof(document)) === 'object' && document.nodeType === 9;\n\nexport default isBrowser;\n", + "/*!\n * is-plain-object \n *\n * Copyright (c) 2014-2017, Jon Schlinkert.\n * Released under the MIT License.\n */\n\n'use strict';\n\nvar isObject = require('isobject');\n\nfunction isObjectObject(o) {\n return isObject(o) === true\n && Object.prototype.toString.call(o) === '[object Object]';\n}\n\nmodule.exports = function isPlainObject(o) {\n var ctor,prot;\n\n if (isObjectObject(o) === false) return false;\n\n // If has modified constructor\n ctor = o.constructor;\n if (typeof ctor !== 'function') return false;\n\n // If has modified prototype\n prot = ctor.prototype;\n if (isObjectObject(prot) === false) return false;\n\n // If constructor does not have an Object-specific method\n if (prot.hasOwnProperty('isPrototypeOf') === false) {\n return false;\n }\n\n // Most likely a plain Object\n return true;\n};\n", + "/*!\n * isobject \n *\n * Copyright (c) 2014-2017, Jon Schlinkert.\n * Released under the MIT License.\n */\n\n'use strict';\n\nmodule.exports = function isObject(val) {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n};\n", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = camelCase;\n\nvar _hyphenateStyleName = require('hyphenate-style-name');\n\nvar _hyphenateStyleName2 = _interopRequireDefault(_hyphenateStyleName);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Convert camel cased property names to dash separated.\n *\n * @param {Object} style\n * @return {Object}\n */\nfunction convertCase(style) {\n var converted = {};\n\n for (var prop in style) {\n converted[(0, _hyphenateStyleName2['default'])(prop)] = style[prop];\n }\n\n if (style.fallbacks) {\n if (Array.isArray(style.fallbacks)) converted.fallbacks = style.fallbacks.map(convertCase);else converted.fallbacks = convertCase(style.fallbacks);\n }\n\n return converted;\n}\n\n/**\n * Allow camel cased property names by converting them back to dasherized.\n *\n * @param {Rule} rule\n */\nfunction camelCase() {\n function onProcessStyle(style) {\n if (Array.isArray(style)) {\n // Handle rules like @font-face, which can have multiple styles in an array\n for (var index = 0; index < style.length; index++) {\n style[index] = convertCase(style[index]);\n }\n return style;\n }\n\n return convertCase(style);\n }\n\n function onChangeValue(value, prop, rule) {\n var hyphenatedProp = (0, _hyphenateStyleName2['default'])(prop);\n\n // There was no camel case in place\n if (prop === hyphenatedProp) return value;\n\n rule.prop(hyphenatedProp, value);\n\n // Core will ignore that property value we set the proper one above.\n return null;\n }\n\n return { onProcessStyle: onProcessStyle, onChangeValue: onChangeValue };\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n/**\n * Generated jss-default-unit CSS property units\n *\n * @type object\n */\nexports['default'] = {\n 'animation-delay': 'ms',\n 'animation-duration': 'ms',\n 'background-position': 'px',\n 'background-position-x': 'px',\n 'background-position-y': 'px',\n 'background-size': 'px',\n border: 'px',\n 'border-bottom': 'px',\n 'border-bottom-left-radius': 'px',\n 'border-bottom-right-radius': 'px',\n 'border-bottom-width': 'px',\n 'border-left': 'px',\n 'border-left-width': 'px',\n 'border-radius': 'px',\n 'border-right': 'px',\n 'border-right-width': 'px',\n 'border-spacing': 'px',\n 'border-top': 'px',\n 'border-top-left-radius': 'px',\n 'border-top-right-radius': 'px',\n 'border-top-width': 'px',\n 'border-width': 'px',\n 'border-after-width': 'px',\n 'border-before-width': 'px',\n 'border-end-width': 'px',\n 'border-horizontal-spacing': 'px',\n 'border-start-width': 'px',\n 'border-vertical-spacing': 'px',\n bottom: 'px',\n 'box-shadow': 'px',\n 'column-gap': 'px',\n 'column-rule': 'px',\n 'column-rule-width': 'px',\n 'column-width': 'px',\n 'flex-basis': 'px',\n 'font-size': 'px',\n 'font-size-delta': 'px',\n height: 'px',\n left: 'px',\n 'letter-spacing': 'px',\n 'logical-height': 'px',\n 'logical-width': 'px',\n margin: 'px',\n 'margin-after': 'px',\n 'margin-before': 'px',\n 'margin-bottom': 'px',\n 'margin-left': 'px',\n 'margin-right': 'px',\n 'margin-top': 'px',\n 'max-height': 'px',\n 'max-width': 'px',\n 'margin-end': 'px',\n 'margin-start': 'px',\n 'mask-position-x': 'px',\n 'mask-position-y': 'px',\n 'mask-size': 'px',\n 'max-logical-height': 'px',\n 'max-logical-width': 'px',\n 'min-height': 'px',\n 'min-width': 'px',\n 'min-logical-height': 'px',\n 'min-logical-width': 'px',\n motion: 'px',\n 'motion-offset': 'px',\n outline: 'px',\n 'outline-offset': 'px',\n 'outline-width': 'px',\n padding: 'px',\n 'padding-bottom': 'px',\n 'padding-left': 'px',\n 'padding-right': 'px',\n 'padding-top': 'px',\n 'padding-after': 'px',\n 'padding-before': 'px',\n 'padding-end': 'px',\n 'padding-start': 'px',\n 'perspective-origin-x': '%',\n 'perspective-origin-y': '%',\n perspective: 'px',\n right: 'px',\n 'shape-margin': 'px',\n size: 'px',\n 'text-indent': 'px',\n 'text-stroke': 'px',\n 'text-stroke-width': 'px',\n top: 'px',\n 'transform-origin': '%',\n 'transform-origin-x': '%',\n 'transform-origin-y': '%',\n 'transform-origin-z': '%',\n 'transition-delay': 'ms',\n 'transition-duration': 'ms',\n 'vertical-align': 'px',\n width: 'px',\n 'word-spacing': 'px',\n // Not existing properties.\n // Used to avoid issues with jss-expand intergration.\n 'box-shadow-x': 'px',\n 'box-shadow-y': 'px',\n 'box-shadow-blur': 'px',\n 'box-shadow-spread': 'px',\n 'font-line-height': 'px',\n 'text-shadow-x': 'px',\n 'text-shadow-y': 'px',\n 'text-shadow-blur': 'px'\n};", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nexports['default'] = defaultUnit;\n\nvar _defaultUnits = require('./defaultUnits');\n\nvar _defaultUnits2 = _interopRequireDefault(_defaultUnits);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Clones the object and adds a camel cased property version.\n */\nfunction addCamelCasedVersion(obj) {\n var regExp = /(-[a-z])/g;\n var replace = function replace(str) {\n return str[1].toUpperCase();\n };\n var newObj = {};\n for (var key in obj) {\n newObj[key] = obj[key];\n newObj[key.replace(regExp, replace)] = obj[key];\n }\n return newObj;\n}\n\nvar units = addCamelCasedVersion(_defaultUnits2['default']);\n\n/**\n * Recursive deep style passing function\n *\n * @param {String} current property\n * @param {(Object|Array|Number|String)} property value\n * @param {Object} options\n * @return {(Object|Array|Number|String)} resulting value\n */\nfunction iterate(prop, value, options) {\n if (!value) return value;\n\n var convertedValue = value;\n\n var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);\n if (type === 'object' && Array.isArray(value)) type = 'array';\n\n switch (type) {\n case 'object':\n if (prop === 'fallbacks') {\n for (var innerProp in value) {\n value[innerProp] = iterate(innerProp, value[innerProp], options);\n }\n break;\n }\n for (var _innerProp in value) {\n value[_innerProp] = iterate(prop + '-' + _innerProp, value[_innerProp], options);\n }\n break;\n case 'array':\n for (var i = 0; i < value.length; i++) {\n value[i] = iterate(prop, value[i], options);\n }\n break;\n case 'number':\n if (value !== 0) {\n convertedValue = value + (options[prop] || units[prop] || '');\n }\n break;\n default:\n break;\n }\n\n return convertedValue;\n}\n\n/**\n * Add unit to numeric values.\n */\nfunction defaultUnit() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n var camelCasedOptions = addCamelCasedVersion(options);\n\n function onProcessStyle(style, rule) {\n if (rule.type !== 'style') return style;\n\n for (var prop in style) {\n style[prop] = iterate(prop, style[prop], camelCasedOptions);\n }\n\n return style;\n }\n\n function onChangeValue(value, prop) {\n return iterate(prop, value, camelCasedOptions);\n }\n\n return { onProcessStyle: onProcessStyle, onChangeValue: onChangeValue };\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nexports['default'] = jssGlobal;\n\nvar _jss = require('jss');\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar propKey = '@global';\nvar prefixKey = '@global ';\n\nvar GlobalContainerRule = function () {\n function GlobalContainerRule(key, styles, options) {\n _classCallCheck(this, GlobalContainerRule);\n\n this.type = 'global';\n\n this.key = key;\n this.options = options;\n this.rules = new _jss.RuleList(_extends({}, options, {\n parent: this\n }));\n\n for (var selector in styles) {\n this.rules.add(selector, styles[selector], { selector: selector });\n }\n\n this.rules.process();\n }\n\n /**\n * Get a rule.\n */\n\n\n _createClass(GlobalContainerRule, [{\n key: 'getRule',\n value: function getRule(name) {\n return this.rules.get(name);\n }\n\n /**\n * Create and register rule, run plugins.\n */\n\n }, {\n key: 'addRule',\n value: function addRule(name, style, options) {\n var rule = this.rules.add(name, style, options);\n this.options.jss.plugins.onProcessRule(rule);\n return rule;\n }\n\n /**\n * Get index of a rule.\n */\n\n }, {\n key: 'indexOf',\n value: function indexOf(rule) {\n return this.rules.indexOf(rule);\n }\n\n /**\n * Generates a CSS string.\n */\n\n }, {\n key: 'toString',\n value: function toString() {\n return this.rules.toString();\n }\n }]);\n\n return GlobalContainerRule;\n}();\n\nvar GlobalPrefixedRule = function () {\n function GlobalPrefixedRule(name, style, options) {\n _classCallCheck(this, GlobalPrefixedRule);\n\n this.name = name;\n this.options = options;\n var selector = name.substr(prefixKey.length);\n this.rule = options.jss.createRule(selector, style, _extends({}, options, {\n parent: this,\n selector: selector\n }));\n }\n\n _createClass(GlobalPrefixedRule, [{\n key: 'toString',\n value: function toString(options) {\n return this.rule.toString(options);\n }\n }]);\n\n return GlobalPrefixedRule;\n}();\n\nvar separatorRegExp = /\\s*,\\s*/g;\n\nfunction addScope(selector, scope) {\n var parts = selector.split(separatorRegExp);\n var scoped = '';\n for (var i = 0; i < parts.length; i++) {\n scoped += scope + ' ' + parts[i].trim();\n if (parts[i + 1]) scoped += ', ';\n }\n return scoped;\n}\n\nfunction handleNestedGlobalContainerRule(rule) {\n var options = rule.options,\n style = rule.style;\n\n var rules = style[propKey];\n\n if (!rules) return;\n\n for (var name in rules) {\n options.sheet.addRule(name, rules[name], _extends({}, options, {\n selector: addScope(name, rule.selector)\n }));\n }\n\n delete style[propKey];\n}\n\nfunction handlePrefixedGlobalRule(rule) {\n var options = rule.options,\n style = rule.style;\n\n for (var prop in style) {\n if (prop.substr(0, propKey.length) !== propKey) continue;\n\n var selector = addScope(prop.substr(propKey.length), rule.selector);\n options.sheet.addRule(selector, style[prop], _extends({}, options, {\n selector: selector\n }));\n delete style[prop];\n }\n}\n\n/**\n * Convert nested rules to separate, remove them from original styles.\n *\n * @param {Rule} rule\n * @api public\n */\nfunction jssGlobal() {\n function onCreateRule(name, styles, options) {\n if (name === propKey) {\n return new GlobalContainerRule(name, styles, options);\n }\n\n if (name[0] === '@' && name.substr(0, prefixKey.length) === prefixKey) {\n return new GlobalPrefixedRule(name, styles, options);\n }\n\n var parent = options.parent;\n\n\n if (parent) {\n if (parent.type === 'global' || parent.options.parent.type === 'global') {\n options.global = true;\n }\n }\n\n if (options.global) options.selector = name;\n\n return null;\n }\n\n function onProcessRule(rule) {\n if (rule.type !== 'style') return;\n\n handleNestedGlobalContainerRule(rule);\n handlePrefixedGlobalRule(rule);\n }\n\n return { onCreateRule: onCreateRule, onProcessRule: onProcessRule };\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = jssNested;\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar separatorRegExp = /\\s*,\\s*/g;\nvar parentRegExp = /&/g;\nvar refRegExp = /\\$([\\w-]+)/g;\n\n/**\n * Convert nested rules to separate, remove them from original styles.\n *\n * @param {Rule} rule\n * @api public\n */\nfunction jssNested() {\n // Get a function to be used for $ref replacement.\n function getReplaceRef(container) {\n return function (match, key) {\n var rule = container.getRule(key);\n if (rule) return rule.selector;\n (0, _warning2.default)(false, '[JSS] Could not find the referenced rule %s in %s.', key, container.options.meta || container);\n return key;\n };\n }\n\n var hasAnd = function hasAnd(str) {\n return str.indexOf('&') !== -1;\n };\n\n function replaceParentRefs(nestedProp, parentProp) {\n var parentSelectors = parentProp.split(separatorRegExp);\n var nestedSelectors = nestedProp.split(separatorRegExp);\n\n var result = '';\n\n for (var i = 0; i < parentSelectors.length; i++) {\n var parent = parentSelectors[i];\n\n for (var j = 0; j < nestedSelectors.length; j++) {\n var nested = nestedSelectors[j];\n if (result) result += ', ';\n // Replace all & by the parent or prefix & with the parent.\n result += hasAnd(nested) ? nested.replace(parentRegExp, parent) : parent + ' ' + nested;\n }\n }\n\n return result;\n }\n\n function getOptions(rule, container, options) {\n // Options has been already created, now we only increase index.\n if (options) return _extends({}, options, { index: options.index + 1 });\n\n var nestingLevel = rule.options.nestingLevel;\n\n nestingLevel = nestingLevel === undefined ? 1 : nestingLevel + 1;\n\n return _extends({}, rule.options, {\n nestingLevel: nestingLevel,\n index: container.indexOf(rule) + 1\n });\n }\n\n function onProcessStyle(style, rule) {\n if (rule.type !== 'style') return style;\n var container = rule.options.parent;\n var options = void 0;\n var replaceRef = void 0;\n for (var prop in style) {\n var isNested = hasAnd(prop);\n var isNestedConditional = prop[0] === '@';\n\n if (!isNested && !isNestedConditional) continue;\n\n options = getOptions(rule, container, options);\n\n if (isNested) {\n var selector = replaceParentRefs(prop, rule.selector\n // Lazily create the ref replacer function just once for\n // all nested rules within the sheet.\n );if (!replaceRef) replaceRef = getReplaceRef(container\n // Replace all $refs.\n );selector = selector.replace(refRegExp, replaceRef);\n\n container.addRule(selector, style[prop], _extends({}, options, { selector: selector }));\n } else if (isNestedConditional) {\n container\n // Place conditional right after the parent rule to ensure right ordering.\n .addRule(prop, null, options).addRule(rule.key, style[prop], { selector: rule.selector });\n }\n\n delete style[prop];\n }\n\n return style;\n }\n\n return { onProcessStyle: onProcessStyle };\n}", + "/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n warning = function(condition, format, args) {\n var len = arguments.length;\n args = new Array(len > 2 ? len - 2 : 0);\n for (var key = 2; key < len; key++) {\n args[key - 2] = arguments[key];\n }\n if (format === undefined) {\n throw new Error(\n '`)))) + ((("`" + (`warning(condition, format, ...args)` + "`")) + (` requires a warning ' +\n 'message argument'\n );\n }\n\n if (format.length < 10 || (/^[s\\W]*$/).test(format)) {\n throw new Error(\n 'The warning format should be able to uniquely identify this ' +\n 'warning. Please, use a more descriptive format than: ' + format\n );\n }\n\n if (!condition) {\n var argIndex = 0;\n var message = 'Warning: ' +\n format.replace(/%s/g, function() {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch(x) {}\n }\n };\n}\n\nmodule.exports = warning;\n", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = jssPropsSort;\n/**\n * Sort props by length.\n */\nfunction jssPropsSort() {\n function sort(prop0, prop1) {\n return prop0.length - prop1.length;\n }\n\n function onProcessStyle(style, rule) {\n if (rule.type !== 'style') return style;\n\n var newStyle = {};\n var props = Object.keys(style).sort(sort);\n for (var prop in props) {\n newStyle[props[prop]] = style[props[prop]];\n }\n return newStyle;\n }\n\n return { onProcessStyle: onProcessStyle };\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = jssVendorPrefixer;\n\nvar _cssVendor = require('css-vendor');\n\nvar vendor = _interopRequireWildcard(_cssVendor);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\n/**\n * Add vendor prefix to a property name when needed.\n *\n * @param {Rule} rule\n * @api public\n */\nfunction jssVendorPrefixer() {\n function onProcessRule(rule) {\n if (rule.type === 'keyframes') {\n rule.key = '@' + vendor.prefix.css + rule.key.substr(1);\n }\n }\n\n function onProcessStyle(style, rule) {\n if (rule.type !== 'style') return style;\n\n for (var prop in style) {\n var value = style[prop];\n\n var changeProp = false;\n var supportedProp = vendor.supportedProperty(prop);\n if (supportedProp && supportedProp !== prop) changeProp = true;\n\n var changeValue = false;\n var supportedValue = vendor.supportedValue(supportedProp, value);\n if (supportedValue && supportedValue !== value) changeValue = true;\n\n if (changeProp || changeValue) {\n if (changeProp) delete style[prop];\n style[supportedProp || prop] = supportedValue || value;\n }\n }\n\n return style;\n }\n\n function onChangeValue(value, prop) {\n return vendor.supportedValue(prop, value);\n }\n\n return { onProcessRule: onProcessRule, onProcessStyle: onProcessStyle, onChangeValue: onChangeValue };\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _isInBrowser = require('is-in-browser');\n\nvar _isInBrowser2 = _interopRequireDefault(_isInBrowser);\n\nvar _StyleSheet = require('./StyleSheet');\n\nvar _StyleSheet2 = _interopRequireDefault(_StyleSheet);\n\nvar _PluginsRegistry = require('./PluginsRegistry');\n\nvar _PluginsRegistry2 = _interopRequireDefault(_PluginsRegistry);\n\nvar _rules = require('./plugins/rules');\n\nvar _rules2 = _interopRequireDefault(_rules);\n\nvar _observables = require('./plugins/observables');\n\nvar _observables2 = _interopRequireDefault(_observables);\n\nvar _functions = require('./plugins/functions');\n\nvar _functions2 = _interopRequireDefault(_functions);\n\nvar _sheets = require('./sheets');\n\nvar _sheets2 = _interopRequireDefault(_sheets);\n\nvar _StyleRule = require('./rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _createGenerateClassName = require('./utils/createGenerateClassName');\n\nvar _createGenerateClassName2 = _interopRequireDefault(_createGenerateClassName);\n\nvar _createRule2 = require('./utils/createRule');\n\nvar _createRule3 = _interopRequireDefault(_createRule2);\n\nvar _DomRenderer = require('./renderers/DomRenderer');\n\nvar _DomRenderer2 = _interopRequireDefault(_DomRenderer);\n\nvar _VirtualRenderer = require('./renderers/VirtualRenderer');\n\nvar _VirtualRenderer2 = _interopRequireDefault(_VirtualRenderer);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar defaultPlugins = _rules2['default'].concat([_observables2['default'], _functions2['default']]);\n\nvar instanceCounter = 0;\n\nvar Jss = function () {\n function Jss(options) {\n _classCallCheck(this, Jss);\n\n this.id = instanceCounter++;\n this.version = \"9.8.7\";\n this.plugins = new _PluginsRegistry2['default']();\n this.options = {\n createGenerateClassName: _createGenerateClassName2['default'],\n Renderer: _isInBrowser2['default'] ? _DomRenderer2['default'] : _VirtualRenderer2['default'],\n plugins: []\n };\n this.generateClassName = (0, _createGenerateClassName2['default'])();\n\n // eslint-disable-next-line prefer-spread\n this.use.apply(this, defaultPlugins);\n this.setup(options);\n }\n\n _createClass(Jss, [{\n key: 'setup',\n value: function setup() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n if (options.createGenerateClassName) {\n this.options.createGenerateClassName = options.createGenerateClassName;\n // $FlowFixMe\n this.generateClassName = options.createGenerateClassName();\n }\n\n if (options.insertionPoint != null) this.options.insertionPoint = options.insertionPoint;\n if (options.virtual || options.Renderer) {\n this.options.Renderer = options.Renderer || (options.virtual ? _VirtualRenderer2['default'] : _DomRenderer2['default']);\n }\n\n // eslint-disable-next-line prefer-spread\n if (options.plugins) this.use.apply(this, options.plugins);\n\n return this;\n }\n\n /**\n * Create a Style Sheet.\n */\n\n }, {\n key: 'createStyleSheet',\n value: function createStyleSheet(styles) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n var index = options.index;\n if (typeof index !== 'number') {\n index = _sheets2['default'].index === 0 ? 0 : _sheets2['default'].index + 1;\n }\n var sheet = new _StyleSheet2['default'](styles, _extends({}, options, {\n jss: this,\n generateClassName: options.generateClassName || this.generateClassName,\n insertionPoint: this.options.insertionPoint,\n Renderer: this.options.Renderer,\n index: index\n }));\n this.plugins.onProcessSheet(sheet);\n\n return sheet;\n }\n\n /**\n * Detach the Style Sheet and remove it from the registry.\n */\n\n }, {\n key: 'removeStyleSheet',\n value: function removeStyleSheet(sheet) {\n sheet.detach();\n _sheets2['default'].remove(sheet);\n return this;\n }\n\n /**\n * Create a rule without a Style Sheet.\n */\n\n }, {\n key: 'createRule',\n value: function createRule(name) {\n var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n // Enable rule without name for inline styles.\n if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') {\n options = style;\n style = name;\n name = undefined;\n }\n\n // Cast from RuleFactoryOptions to RuleOptions\n // https://stackoverflow.com/questions/41328728/force-casting-in-flow\n var ruleOptions = options;\n\n ruleOptions.jss = this;\n ruleOptions.Renderer = this.options.Renderer;\n if (!ruleOptions.generateClassName) ruleOptions.generateClassName = this.generateClassName;\n if (!ruleOptions.classes) ruleOptions.classes = {};\n var rule = (0, _createRule3['default'])(name, style, ruleOptions);\n\n if (!ruleOptions.selector && rule instanceof _StyleRule2['default']) {\n rule.selector = '.' + ruleOptions.generateClassName(rule);\n }\n\n this.plugins.onProcessRule(rule);\n\n return rule;\n }\n\n /**\n * Register plugin. Passed function will be invoked with a rule instance.\n */\n\n }, {\n key: 'use',\n value: function use() {\n var _this = this;\n\n for (var _len = arguments.length, plugins = Array(_len), _key = 0; _key < _len; _key++) {\n plugins[_key] = arguments[_key];\n }\n\n plugins.forEach(function (plugin) {\n // Avoids applying same plugin twice, at least based on ref.\n if (_this.options.plugins.indexOf(plugin) === -1) {\n _this.options.plugins.push(plugin);\n _this.plugins.use(plugin);\n }\n });\n\n return this;\n }\n }]);\n\n return Jss;\n}();\n\nexports['default'] = Jss;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar PluginsRegistry = function () {\n function PluginsRegistry() {\n _classCallCheck(this, PluginsRegistry);\n\n this.hooks = {\n onCreateRule: [],\n onProcessRule: [],\n onProcessStyle: [],\n onProcessSheet: [],\n onChangeValue: [],\n onUpdate: []\n\n /**\n * Call ` + ("`" + `onCreateRule`))) + (("`" + (` hooks and return an object if returned by a hook.\n */\n };\n }\n\n _createClass(PluginsRegistry, [{\n key: 'onCreateRule',\n value: function onCreateRule(name, decl, options) {\n for (var i = 0; i < this.hooks.onCreateRule.length; i++) {\n var rule = this.hooks.onCreateRule[i](name, decl, options);\n if (rule) return rule;\n }\n return null;\n }\n\n /**\n * Call ` + "`")) + (`onProcessRule` + ("`" + ` hooks.\n */\n\n }, {\n key: 'onProcessRule',\n value: function onProcessRule(rule) {\n if (rule.isProcessed) return;\n var sheet = rule.options.sheet;\n\n for (var i = 0; i < this.hooks.onProcessRule.length; i++) {\n this.hooks.onProcessRule[i](rule, sheet);\n }\n\n // $FlowFixMe\n if (rule.style) this.onProcessStyle(rule.style, rule, sheet);\n\n rule.isProcessed = true;\n }\n\n /**\n * Call `))))) + (((("`" + (`onProcessStyle` + "`")) + (` hooks.\n */\n\n }, {\n key: 'onProcessStyle',\n value: function onProcessStyle(style, rule, sheet) {\n var nextStyle = style;\n\n for (var i = 0; i < this.hooks.onProcessStyle.length; i++) {\n nextStyle = this.hooks.onProcessStyle[i](nextStyle, rule, sheet);\n // $FlowFixMe\n rule.style = nextStyle;\n }\n }\n\n /**\n * Call ` + ("`" + `onProcessSheet`))) + (("`" + (` hooks.\n */\n\n }, {\n key: 'onProcessSheet',\n value: function onProcessSheet(sheet) {\n for (var i = 0; i < this.hooks.onProcessSheet.length; i++) {\n this.hooks.onProcessSheet[i](sheet);\n }\n }\n\n /**\n * Call ` + "`")) + (`onUpdate` + ("`" + ` hooks.\n */\n\n }, {\n key: 'onUpdate',\n value: function onUpdate(data, rule, sheet) {\n for (var i = 0; i < this.hooks.onUpdate.length; i++) {\n this.hooks.onUpdate[i](data, rule, sheet);\n }\n }\n\n /**\n * Call `)))) + ((("`" + (`onChangeValue` + "`")) + (` hooks.\n */\n\n }, {\n key: 'onChangeValue',\n value: function onChangeValue(value, prop, rule) {\n var processedValue = value;\n for (var i = 0; i < this.hooks.onChangeValue.length; i++) {\n processedValue = this.hooks.onChangeValue[i](processedValue, prop, rule);\n }\n return processedValue;\n }\n\n /**\n * Register a plugin.\n * If function is passed, it is a shortcut for ` + ("`" + `{onProcessRule}`))) + (("`" + (`.\n */\n\n }, {\n key: 'use',\n value: function use(plugin) {\n for (var name in plugin) {\n if (this.hooks[name]) this.hooks[name].push(plugin[name]);else (0, _warning2['default'])(false, '[JSS] Unknown hook \"%s\".', name);\n }\n }\n }]);\n\n return PluginsRegistry;\n}();\n\nexports['default'] = PluginsRegistry;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _createRule = require('./utils/createRule');\n\nvar _createRule2 = _interopRequireDefault(_createRule);\n\nvar _linkRule = require('./utils/linkRule');\n\nvar _linkRule2 = _interopRequireDefault(_linkRule);\n\nvar _StyleRule = require('./rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _escape = require('./utils/escape');\n\nvar _escape2 = _interopRequireDefault(_escape);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Contains rules objects and allows adding/removing etc.\n * Is used for e.g. by ` + "`")) + ((`StyleSheet` + "`") + (` or ` + "`")))))) + (((((`ConditionalRule` + ("`" + `.\n */\nvar RuleList = function () {\n\n // Original styles object.\n function RuleList(options) {\n var _this = this;\n\n _classCallCheck(this, RuleList);\n\n this.map = {};\n this.raw = {};\n this.index = [];\n\n this.update = function (name, data) {\n var _options = _this.options,\n plugins = _options.jss.plugins,\n sheet = _options.sheet;\n\n if (typeof name === 'string') {\n plugins.onUpdate(data, _this.get(name), sheet);\n } else {\n for (var index = 0; index < _this.index.length; index++) {\n plugins.onUpdate(name, _this.index[index], sheet);\n }\n }\n };\n\n this.options = options;\n this.classes = options.classes;\n }\n\n /**\n * Create and register rule.\n *\n * Will not render after Style Sheet was rendered the first time.\n */\n\n\n // Used to ensure correct rules order.\n\n // Rules registry for access by .get() method.\n // It contains the same rule registered by name and by selector.\n\n\n _createClass(RuleList, [{\n key: 'add',\n value: function add(name, decl, options) {\n var _options2 = this.options,\n parent = _options2.parent,\n sheet = _options2.sheet,\n jss = _options2.jss,\n Renderer = _options2.Renderer,\n generateClassName = _options2.generateClassName;\n\n\n options = _extends({\n classes: this.classes,\n parent: parent,\n sheet: sheet,\n jss: jss,\n Renderer: Renderer,\n generateClassName: generateClassName\n }, options);\n\n if (!options.selector && this.classes[name]) {\n options.selector = '.' + (0, _escape2['default'])(this.classes[name]);\n }\n\n this.raw[name] = decl;\n\n var rule = (0, _createRule2['default'])(name, decl, options);\n\n var className = void 0;\n\n if (!options.selector && rule instanceof _StyleRule2['default']) {\n className = generateClassName(rule, sheet);\n rule.selector = '.' + (0, _escape2['default'])(className);\n }\n\n this.register(rule, className);\n\n var index = options.index === undefined ? this.index.length : options.index;\n this.index.splice(index, 0, rule);\n\n return rule;\n }\n\n /**\n * Get a rule.\n */\n\n }, {\n key: 'get',\n value: function get(name) {\n return this.map[name];\n }\n\n /**\n * Delete a rule.\n */\n\n }, {\n key: 'remove',\n value: function remove(rule) {\n this.unregister(rule);\n this.index.splice(this.indexOf(rule), 1);\n }\n\n /**\n * Get index of a rule.\n */\n\n }, {\n key: 'indexOf',\n value: function indexOf(rule) {\n return this.index.indexOf(rule);\n }\n\n /**\n * Run `)) + ("`" + (`onProcessRule()` + "`"))) + ((` plugins on every rule.\n */\n\n }, {\n key: 'process',\n value: function process() {\n var plugins = this.options.jss.plugins;\n // We need to clone array because if we modify the index somewhere else during a loop\n // we end up with very hard-to-track-down side effects.\n\n this.index.slice(0).forEach(plugins.onProcessRule, plugins);\n }\n\n /**\n * Register a rule in ` + ("`" + `.map`)) + ("`" + (` and ` + "`")))) + (((`.classes` + ("`" + ` maps.\n */\n\n }, {\n key: 'register',\n value: function register(rule, className) {\n this.map[rule.key] = rule;\n if (rule instanceof _StyleRule2['default']) {\n this.map[rule.selector] = rule;\n if (className) this.classes[rule.key] = className;\n }\n }\n\n /**\n * Unregister a rule.\n */\n\n }, {\n key: 'unregister',\n value: function unregister(rule) {\n delete this.map[rule.key];\n if (rule instanceof _StyleRule2['default']) {\n delete this.map[rule.selector];\n delete this.classes[rule.key];\n }\n }\n\n /**\n * Update the function values with a new data.\n */\n\n }, {\n key: 'link',\n\n\n /**\n * Link renderable rules with CSSRuleList.\n */\n value: function link(cssRules) {\n var map = this.options.sheet.renderer.getUnescapedKeysMap(this.index);\n\n for (var i = 0; i < cssRules.length; i++) {\n var cssRule = cssRules[i];\n var _key = this.options.sheet.renderer.getKey(cssRule);\n if (map[_key]) _key = map[_key];\n var rule = this.map[_key];\n if (rule) (0, _linkRule2['default'])(rule, cssRule);\n }\n }\n\n /**\n * Convert rules to a CSS string.\n */\n\n }, {\n key: 'toString',\n value: function toString(options) {\n var str = '';\n var sheet = this.options.sheet;\n\n var link = sheet ? sheet.options.link : false;\n\n for (var index = 0; index < this.index.length; index++) {\n var rule = this.index[index];\n var css = rule.toString(options);\n\n // No need to render an empty rule.\n if (!css && !link) continue;\n\n if (str) str += '\\n';\n str += css;\n }\n\n return str;\n }\n }]);\n\n return RuleList;\n}();\n\nexports['default'] = RuleList;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * SheetsManager is like a WeakMap which is designed to count StyleSheet\n * instances and attach/detach automatically.\n */\nvar SheetsManager = function () {\n function SheetsManager() {\n _classCallCheck(this, SheetsManager);\n\n this.sheets = [];\n this.refs = [];\n this.keys = [];\n }\n\n _createClass(SheetsManager, [{\n key: 'get',\n value: function get(key) {\n var index = this.keys.indexOf(key);\n return this.sheets[index];\n }\n }, {\n key: 'add',\n value: function add(key, sheet) {\n var sheets = this.sheets,\n refs = this.refs,\n keys = this.keys;\n\n var index = sheets.indexOf(sheet);\n\n if (index !== -1) return index;\n\n sheets.push(sheet);\n refs.push(0);\n keys.push(key);\n\n return sheets.length - 1;\n }\n }, {\n key: 'manage',\n value: function manage(key) {\n var index = this.keys.indexOf(key);\n var sheet = this.sheets[index];\n if (this.refs[index] === 0) sheet.attach();\n this.refs[index]++;\n if (!this.keys[index]) this.keys.splice(index, 0, key);\n return sheet;\n }\n }, {\n key: 'unmanage',\n value: function unmanage(key) {\n var index = this.keys.indexOf(key);\n if (index === -1) {\n // eslint-ignore-next-line no-console\n (0, _warning2['default'])(false, \"SheetsManager: can't find sheet to unmanage\");\n return;\n }\n if (this.refs[index] > 0) {\n this.refs[index]--;\n if (this.refs[index] === 0) this.sheets[index].detach();\n }\n }\n }, {\n key: 'size',\n get: function get() {\n return this.keys.length;\n }\n }]);\n\n return SheetsManager;\n}();\n\nexports['default'] = SheetsManager;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Sheets registry to access them all at one place.\n */\nvar SheetsRegistry = function () {\n function SheetsRegistry() {\n _classCallCheck(this, SheetsRegistry);\n\n this.registry = [];\n }\n\n _createClass(SheetsRegistry, [{\n key: 'add',\n\n\n /**\n * Register a Style Sheet.\n */\n value: function add(sheet) {\n var registry = this.registry;\n var index = sheet.options.index;\n\n\n if (registry.indexOf(sheet) !== -1) return;\n\n if (registry.length === 0 || index >= this.index) {\n registry.push(sheet);\n return;\n }\n\n // Find a position.\n for (var i = 0; i < registry.length; i++) {\n if (registry[i].options.index > index) {\n registry.splice(i, 0, sheet);\n return;\n }\n }\n }\n\n /**\n * Reset the registry.\n */\n\n }, {\n key: 'reset',\n value: function reset() {\n this.registry = [];\n }\n\n /**\n * Remove a Style Sheet.\n */\n\n }, {\n key: 'remove',\n value: function remove(sheet) {\n var index = this.registry.indexOf(sheet);\n this.registry.splice(index, 1);\n }\n\n /**\n * Convert all attached sheets to a CSS string.\n */\n\n }, {\n key: 'toString',\n value: function toString(options) {\n return this.registry.filter(function (sheet) {\n return sheet.attached;\n }).map(function (sheet) {\n return sheet.toString(options);\n }).join('\\n');\n }\n }, {\n key: 'index',\n\n\n /**\n * Current highest index number.\n */\n get: function get() {\n return this.registry.length === 0 ? 0 : this.registry[this.registry.length - 1].options.index;\n }\n }]);\n\n return SheetsRegistry;\n}();\n\nexports['default'] = SheetsRegistry;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _linkRule = require('./utils/linkRule');\n\nvar _linkRule2 = _interopRequireDefault(_linkRule);\n\nvar _RuleList = require('./RuleList');\n\nvar _RuleList2 = _interopRequireDefault(_RuleList);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/* eslint-disable-next-line no-use-before-define */\nvar StyleSheet = function () {\n function StyleSheet(styles, options) {\n var _this = this;\n\n _classCallCheck(this, StyleSheet);\n\n this.update = function (name, data) {\n if (typeof name === 'string') {\n _this.rules.update(name, data);\n } else {\n _this.rules.update(name);\n }\n return _this;\n };\n\n this.attached = false;\n this.deployed = false;\n this.linked = false;\n this.classes = {};\n this.options = _extends({}, options, {\n sheet: this,\n parent: this,\n classes: this.classes\n });\n this.renderer = new options.Renderer(this);\n this.rules = new _RuleList2['default'](this.options);\n\n for (var _name in styles) {\n this.rules.add(_name, styles[_name]);\n }\n\n this.rules.process();\n }\n\n /**\n * Attach renderable to the render tree.\n */\n\n\n _createClass(StyleSheet, [{\n key: 'attach',\n value: function attach() {\n if (this.attached) return this;\n if (!this.deployed) this.deploy();\n this.renderer.attach();\n if (!this.linked && this.options.link) this.link();\n this.attached = true;\n return this;\n }\n\n /**\n * Remove renderable from render tree.\n */\n\n }, {\n key: 'detach',\n value: function detach() {\n if (!this.attached) return this;\n this.renderer.detach();\n this.attached = false;\n return this;\n }\n\n /**\n * Add a rule to the current stylesheet.\n * Will insert a rule also after the stylesheet has been rendered first time.\n */\n\n }, {\n key: 'addRule',\n value: function addRule(name, decl, options) {\n var queue = this.queue;\n\n // Plugins can create rules.\n // In order to preserve the right order, we need to queue all `)) + ("`" + (`.addRule` + "`"))) + ((` calls,\n // which happen after the first ` + ("`" + `rules.add()`)) + (("`" + ` call.\n\n if (this.attached && !queue) this.queue = [];\n\n var rule = this.rules.add(name, decl, options);\n this.options.jss.plugins.onProcessRule(rule);\n\n if (this.attached) {\n if (!this.deployed) return rule;\n // Don't insert rule directly if there is no stringified version yet.\n // It will be inserted all together when .attach is called.\n if (queue) queue.push(rule);else {\n this.insertRule(rule);\n if (this.queue) {\n this.queue.forEach(this.insertRule, this);\n this.queue = undefined;\n }\n }\n return rule;\n }\n\n // We can't add rules to a detached style node.\n // We will redeploy the sheet once user will attach it.\n this.deployed = false;\n\n return rule;\n }\n\n /**\n * Insert rule into the StyleSheet\n */\n\n }, {\n key: 'insertRule',\n value: function insertRule(rule) {\n var renderable = this.renderer.insertRule(rule);\n if (renderable && this.options.link) (0, _linkRule2['default'])(rule, renderable);\n }\n\n /**\n * Create and add rules.\n * Will render also after Style Sheet was rendered the first time.\n */\n\n }, {\n key: 'addRules',\n value: function addRules(styles, options) {\n var added = [];\n for (var _name2 in styles) {\n added.push(this.addRule(_name2, styles[_name2], options));\n }\n return added;\n }\n\n /**\n * Get a rule by name.\n */\n\n }, {\n key: 'getRule',\n value: function getRule(name) {\n return this.rules.get(name);\n }\n\n /**\n * Delete a rule by name.\n * Returns `) + ("`" + `true`))))) + (((("`" + (`: if rule has been deleted from the DOM.\n */\n\n }, {\n key: 'deleteRule',\n value: function deleteRule(name) {\n var rule = this.rules.get(name);\n\n if (!rule) return false;\n\n this.rules.remove(rule);\n\n if (this.attached && rule.renderable) {\n return this.renderer.deleteRule(rule.renderable);\n }\n\n return true;\n }\n\n /**\n * Get index of a rule.\n */\n\n }, {\n key: 'indexOf',\n value: function indexOf(rule) {\n return this.rules.indexOf(rule);\n }\n\n /**\n * Deploy pure CSS string to a renderable.\n */\n\n }, {\n key: 'deploy',\n value: function deploy() {\n this.renderer.deploy();\n this.deployed = true;\n return this;\n }\n\n /**\n * Link renderable CSS rules from sheet with their corresponding models.\n */\n\n }, {\n key: 'link',\n value: function link() {\n var cssRules = this.renderer.getRules();\n\n // Is undefined when VirtualRenderer is used.\n if (cssRules) this.rules.link(cssRules);\n this.linked = true;\n return this;\n }\n\n /**\n * Update the function values with a new data.\n */\n\n }, {\n key: 'toString',\n\n\n /**\n * Convert rules to a CSS string.\n */\n value: function toString(options) {\n return this.rules.toString(options);\n }\n }]);\n\n return StyleSheet;\n}();\n\nexports['default'] = StyleSheet;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.create = exports.createGenerateClassName = exports.sheets = exports.RuleList = exports.SheetsManager = exports.SheetsRegistry = exports.toCssValue = exports.getDynamicStyles = undefined;\n\nvar _getDynamicStyles = require('./utils/getDynamicStyles');\n\nObject.defineProperty(exports, 'getDynamicStyles', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_getDynamicStyles)['default'];\n }\n});\n\nvar _toCssValue = require('./utils/toCssValue');\n\nObject.defineProperty(exports, 'toCssValue', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_toCssValue)['default'];\n }\n});\n\nvar _SheetsRegistry = require('./SheetsRegistry');\n\nObject.defineProperty(exports, 'SheetsRegistry', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_SheetsRegistry)['default'];\n }\n});\n\nvar _SheetsManager = require('./SheetsManager');\n\nObject.defineProperty(exports, 'SheetsManager', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_SheetsManager)['default'];\n }\n});\n\nvar _RuleList = require('./RuleList');\n\nObject.defineProperty(exports, 'RuleList', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_RuleList)['default'];\n }\n});\n\nvar _sheets = require('./sheets');\n\nObject.defineProperty(exports, 'sheets', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_sheets)['default'];\n }\n});\n\nvar _createGenerateClassName = require('./utils/createGenerateClassName');\n\nObject.defineProperty(exports, 'createGenerateClassName', {\n enumerable: true,\n get: function get() {\n return _interopRequireDefault(_createGenerateClassName)['default'];\n }\n});\n\nvar _Jss = require('./Jss');\n\nvar _Jss2 = _interopRequireDefault(_Jss);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Creates a new instance of Jss.\n */\nvar create = exports.create = function create(options) {\n return new _Jss2['default'](options);\n};\n\n/**\n * A global Jss instance.\n */\nexports['default'] = create();", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _RuleList = require('../RuleList');\n\nvar _RuleList2 = _interopRequireDefault(_RuleList);\n\nvar _StyleRule = require('../rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _createRule = require('../utils/createRule');\n\nvar _createRule2 = _interopRequireDefault(_createRule);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n// A symbol replacement.\nvar now = Date.now();\n\nvar fnValuesNs = 'fnValues' + now;\nvar fnStyleNs = 'fnStyle' + ++now;\n\nexports['default'] = {\n onCreateRule: function onCreateRule(name, decl, options) {\n if (typeof decl !== 'function') return null;\n var rule = (0, _createRule2['default'])(name, {}, options);\n rule[fnStyleNs] = decl;\n return rule;\n },\n onProcessStyle: function onProcessStyle(style, rule) {\n var fn = {};\n for (var prop in style) {\n var value = style[prop];\n if (typeof value !== 'function') continue;\n delete style[prop];\n fn[prop] = value;\n }\n rule = rule;\n rule[fnValuesNs] = fn;\n return style;\n },\n onUpdate: function onUpdate(data, rule) {\n // It is a rules container like for e.g. ConditionalRule.\n if (rule.rules instanceof _RuleList2['default']) {\n rule.rules.update(data);\n return;\n }\n if (!(rule instanceof _StyleRule2['default'])) return;\n\n rule = rule;\n\n // If we have a fn values map, it is a rule with function values.\n if (rule[fnValuesNs]) {\n for (var prop in rule[fnValuesNs]) {\n rule.prop(prop, rule[fnValuesNs][prop](data));\n }\n }\n\n rule = rule;\n\n var fnStyle = rule[fnStyleNs];\n\n // If we have a style function, the entire rule is dynamic and style object\n // will be returned from that function.\n if (fnStyle) {\n var style = fnStyle(data);\n for (var _prop in style) {\n rule.prop(_prop, style[_prop]);\n }\n }\n }\n};", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _StyleRule = require('../rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _createRule = require('../utils/createRule');\n\nvar _createRule2 = _interopRequireDefault(_createRule);\n\nvar _isObservable = require('../utils/isObservable');\n\nvar _isObservable2 = _interopRequireDefault(_isObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nexports['default'] = {\n onCreateRule: function onCreateRule(name, decl, options) {\n if (!(0, _isObservable2['default'])(decl)) return null;\n\n // Cast ` + "`")) + (`decl` + ("`" + ` to `))) + (("`" + (`Observable` + "`")) + (`, since it passed the type guard.\n var style$ = decl;\n\n var rule = (0, _createRule2['default'])(name, {}, options);\n\n // TODO\n // Call ` + ("`" + `stream.subscribe()`)))) + ((("`" + (` returns a subscription, which should be explicitly\n // unsubscribed from when we know this sheet is no longer needed.\n style$.subscribe(function (style) {\n for (var prop in style) {\n rule.prop(prop, style[prop]);\n }\n });\n\n return rule;\n },\n onProcessRule: function onProcessRule(rule) {\n if (!(rule instanceof _StyleRule2['default'])) return;\n var styleRule = rule;\n var style = styleRule.style;\n\n var _loop = function _loop(prop) {\n var value = style[prop];\n if (!(0, _isObservable2['default'])(value)) return 'continue';\n delete style[prop];\n value.subscribe({\n next: function next(nextValue) {\n styleRule.prop(prop, nextValue);\n }\n });\n };\n\n for (var prop in style) {\n var _ret = _loop(prop);\n\n if (_ret === 'continue') continue;\n }\n }\n};", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _SimpleRule = require('../rules/SimpleRule');\n\nvar _SimpleRule2 = _interopRequireDefault(_SimpleRule);\n\nvar _KeyframesRule = require('../rules/KeyframesRule');\n\nvar _KeyframesRule2 = _interopRequireDefault(_KeyframesRule);\n\nvar _ConditionalRule = require('../rules/ConditionalRule');\n\nvar _ConditionalRule2 = _interopRequireDefault(_ConditionalRule);\n\nvar _FontFaceRule = require('../rules/FontFaceRule');\n\nvar _FontFaceRule2 = _interopRequireDefault(_FontFaceRule);\n\nvar _ViewportRule = require('../rules/ViewportRule');\n\nvar _ViewportRule2 = _interopRequireDefault(_ViewportRule);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar classes = {\n '@charset': _SimpleRule2['default'],\n '@import': _SimpleRule2['default'],\n '@namespace': _SimpleRule2['default'],\n '@keyframes': _KeyframesRule2['default'],\n '@media': _ConditionalRule2['default'],\n '@supports': _ConditionalRule2['default'],\n '@font-face': _FontFaceRule2['default'],\n '@viewport': _ViewportRule2['default'],\n '@-ms-viewport': _ViewportRule2['default']\n\n /**\n * Generate plugins which will register all rules.\n */\n};\nvar plugins = Object.keys(classes).map(function (key) {\n // https://jsperf.com/indexof-vs-substr-vs-regex-at-the-beginning-3\n var re = new RegExp('^' + key);\n var RuleClass = classes[key];\n var onCreateRule = function onCreateRule(name, decl, options) {\n return re.test(name) ? new RuleClass(name, decl, options) : null;\n };\n return { onCreateRule: onCreateRule };\n});\n\nexports['default'] = plugins;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nvar _sheets = require('../sheets');\n\nvar _sheets2 = _interopRequireDefault(_sheets);\n\nvar _StyleRule = require('../rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _toCssValue = require('../utils/toCssValue');\n\nvar _toCssValue2 = _interopRequireDefault(_toCssValue);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Cache the value from the first time a function is called.\n */\nvar memoize = function memoize(fn) {\n var value = void 0;\n return function () {\n if (!value) value = fn();\n return value;\n };\n};\n\n/**\n * Get a style property value.\n */\nfunction getPropertyValue(cssRule, prop) {\n try {\n return cssRule.style.getPropertyValue(prop);\n } catch (err) {\n // IE may throw if property is unknown.\n return '';\n }\n}\n\n/**\n * Set a style property.\n */\nfunction setProperty(cssRule, prop, value) {\n try {\n var cssValue = value;\n\n if (Array.isArray(value)) {\n cssValue = (0, _toCssValue2['default'])(value, true);\n\n if (value[value.length - 1] === '!important') {\n cssRule.style.setProperty(prop, cssValue, 'important');\n return true;\n }\n }\n\n cssRule.style.setProperty(prop, cssValue);\n } catch (err) {\n // IE may throw if property is unknown.\n return false;\n }\n return true;\n}\n\n/**\n * Remove a style property.\n */\nfunction removeProperty(cssRule, prop) {\n try {\n cssRule.style.removeProperty(prop);\n } catch (err) {\n (0, _warning2['default'])(false, '[JSS] DOMException \"%s\" was thrown. Tried to remove property \"%s\".', err.message, prop);\n }\n}\n\nvar CSSRuleTypes = {\n STYLE_RULE: 1,\n KEYFRAMES_RULE: 7\n\n /**\n * Get the CSS Rule key.\n */\n\n};var getKey = function () {\n var extractKey = function extractKey(cssText) {\n var from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n return cssText.substr(from, cssText.indexOf('{') - 1);\n };\n\n return function (cssRule) {\n if (cssRule.type === CSSRuleTypes.STYLE_RULE) return cssRule.selectorText;\n if (cssRule.type === CSSRuleTypes.KEYFRAMES_RULE) {\n var name = cssRule.name;\n\n if (name) return '@keyframes ' + name;\n\n // There is no rule.name in the following browsers:\n // - IE 9\n // - Safari 7.1.8\n // - Mobile Safari 9.0.0\n var cssText = cssRule.cssText;\n\n return '@' + extractKey(cssText, cssText.indexOf('keyframes'));\n }\n\n // Conditionals.\n return extractKey(cssRule.cssText);\n };\n}();\n\n/**\n * Set the selector.\n */\nfunction setSelector(cssRule, selectorText) {\n cssRule.selectorText = selectorText;\n\n // Return false if setter was not successful.\n // Currently works in chrome only.\n return cssRule.selectorText === selectorText;\n}\n\n/**\n * Gets the ` + "`")) + (`head` + ("`" + ` element upon the first call and caches it.\n */\nvar getHead = memoize(function () {\n return document.head || document.getElementsByTagName('head')[0];\n});\n\n/**\n * Gets a map of rule keys, where the property is an unescaped key and value\n * is a potentially escaped one.\n * It is used to identify CSS rules and the corresponding JSS rules. As an identifier\n * for CSSStyleRule we normally use `))) + (("`" + (`selectorText` + "`")) + ((`. Though if original selector text\n * contains escaped code points e.g. ` + "`") + (`:not(#\\\\20)` + "`"))))))) + ((((((`, CSSOM will compile it to ` + ("`" + `:not(# )`)) + ("`" + (`\n * and so CSS rule's ` + "`"))) + ((`selectorText` + ("`" + ` won't match JSS rule selector.\n *\n * https://www.w3.org/International/questions/qa-escapes#cssescapes\n */\nvar getUnescapedKeysMap = function () {\n var style = void 0;\n var isAttached = false;\n\n return function (rules) {\n var map = {};\n // https://github.com/facebook/flow/issues/2696\n if (!style) style = document.createElement('style');\n for (var i = 0; i < rules.length; i++) {\n var rule = rules[i];\n if (!(rule instanceof _StyleRule2['default'])) continue;\n var selector = rule.selector;\n // Only unescape selector over CSSOM if it contains a back slash.\n\n if (selector && selector.indexOf('\\\\') !== -1) {\n // Lazilly attach when needed.\n if (!isAttached) {\n getHead().appendChild(style);\n isAttached = true;\n }\n style.textContent = selector + ' {}';\n var _style = style,\n sheet = _style.sheet;\n\n if (sheet) {\n var cssRules = sheet.cssRules;\n\n if (cssRules) map[cssRules[0].selectorText] = rule.key;\n }\n }\n }\n if (isAttached) {\n getHead().removeChild(style);\n isAttached = false;\n }\n return map;\n };\n}();\n\n/**\n * Find attached sheet with an index higher than the passed one.\n */\nfunction findHigherSheet(registry, options) {\n for (var i = 0; i < registry.length; i++) {\n var sheet = registry[i];\n if (sheet.attached && sheet.options.index > options.index && sheet.options.insertionPoint === options.insertionPoint) {\n return sheet;\n }\n }\n return null;\n}\n\n/**\n * Find attached sheet with the highest index.\n */\nfunction findHighestSheet(registry, options) {\n for (var i = registry.length - 1; i >= 0; i--) {\n var sheet = registry[i];\n if (sheet.attached && sheet.options.insertionPoint === options.insertionPoint) {\n return sheet;\n }\n }\n return null;\n}\n\n/**\n * Find a comment with \"jss\" inside.\n */\nfunction findCommentNode(text) {\n var head = getHead();\n for (var i = 0; i < head.childNodes.length; i++) {\n var node = head.childNodes[i];\n if (node.nodeType === 8 && node.nodeValue.trim() === text) {\n return node;\n }\n }\n return null;\n}\n\n/**\n * Find a node before which we can insert the sheet.\n */\nfunction findPrevNode(options) {\n var registry = _sheets2['default'].registry;\n\n\n if (registry.length > 0) {\n // Try to insert before the next higher sheet.\n var sheet = findHigherSheet(registry, options);\n if (sheet) return sheet.renderer.element;\n\n // Otherwise insert after the last attached.\n sheet = findHighestSheet(registry, options);\n if (sheet) return sheet.renderer.element.nextElementSibling;\n }\n\n // Try to find a comment placeholder if registry is empty.\n var insertionPoint = options.insertionPoint;\n\n if (insertionPoint && typeof insertionPoint === 'string') {\n var comment = findCommentNode(insertionPoint);\n if (comment) return comment.nextSibling;\n // If user specifies an insertion point and it can't be found in the document -\n // bad specificity issues may appear.\n (0, _warning2['default'])(insertionPoint === 'jss', '[JSS] Insertion point \"%s\" not found.', insertionPoint);\n }\n\n return null;\n}\n\n/**\n * Insert style element into the DOM.\n */\nfunction insertStyle(style, options) {\n var insertionPoint = options.insertionPoint;\n\n var prevNode = findPrevNode(options);\n\n if (prevNode) {\n var parentNode = prevNode.parentNode;\n\n if (parentNode) parentNode.insertBefore(style, prevNode);\n return;\n }\n\n // Works with iframes and any node types.\n if (insertionPoint && typeof insertionPoint.nodeType === 'number') {\n // https://stackoverflow.com/questions/41328728/force-casting-in-flow\n var insertionPointElement = insertionPoint;\n var _parentNode = insertionPointElement.parentNode;\n\n if (_parentNode) _parentNode.insertBefore(style, insertionPointElement.nextSibling);else (0, _warning2['default'])(false, '[JSS] Insertion point is not in the DOM.');\n return;\n }\n\n getHead().insertBefore(style, prevNode);\n}\n\n/**\n * Read jss nonce setting from the page if the user has set it.\n */\nvar getNonce = memoize(function () {\n var node = document.querySelector('meta[property=\"csp-nonce\"]');\n return node ? node.getAttribute('content') : null;\n});\n\nvar DomRenderer = function () {\n function DomRenderer(sheet) {\n _classCallCheck(this, DomRenderer);\n\n this.getPropertyValue = getPropertyValue;\n this.setProperty = setProperty;\n this.removeProperty = removeProperty;\n this.setSelector = setSelector;\n this.getKey = getKey;\n this.getUnescapedKeysMap = getUnescapedKeysMap;\n this.hasInsertedRules = false;\n\n // There is no sheet when the renderer is used from a standalone StyleRule.\n if (sheet) _sheets2['default'].add(sheet);\n\n this.sheet = sheet;\n\n var _ref = this.sheet ? this.sheet.options : {},\n media = _ref.media,\n meta = _ref.meta,\n element = _ref.element;\n\n this.element = element || document.createElement('style');\n this.element.setAttribute('data-jss', '');\n if (media) this.element.setAttribute('media', media);\n if (meta) this.element.setAttribute('data-meta', meta);\n var nonce = getNonce();\n if (nonce) this.element.setAttribute('nonce', nonce);\n }\n\n /**\n * Insert style element into render tree.\n */\n\n\n // HTMLStyleElement needs fixing https://github.com/facebook/flow/issues/2696\n\n\n _createClass(DomRenderer, [{\n key: 'attach',\n value: function attach() {\n // In the case the element node is external and it is already in the DOM.\n if (this.element.parentNode || !this.sheet) return;\n\n // When rules are inserted using `)) + ("`" + (`insertRule` + "`")))) + (((` API, after ` + ("`" + `sheet.detach().attach()`)) + ("`" + (`\n // browsers remove those rules.\n // TODO figure out if its a bug and if it is known.\n // Workaround is to redeploy the sheet before attaching as a string.\n if (this.hasInsertedRules) {\n this.deploy();\n this.hasInsertedRules = false;\n }\n\n insertStyle(this.element, this.sheet.options);\n }\n\n /**\n * Remove style element from render tree.\n */\n\n }, {\n key: 'detach',\n value: function detach() {\n this.element.parentNode.removeChild(this.element);\n }\n\n /**\n * Inject CSS string into element.\n */\n\n }, {\n key: 'deploy',\n value: function deploy() {\n if (!this.sheet) return;\n this.element.textContent = '\\n' + this.sheet.toString() + '\\n';\n }\n\n /**\n * Insert a rule into element.\n */\n\n }, {\n key: 'insertRule',\n value: function insertRule(rule, index) {\n var sheet = this.element.sheet;\n var cssRules = sheet.cssRules;\n\n var str = rule.toString();\n if (!index) index = cssRules.length;\n\n if (!str) return false;\n\n try {\n sheet.insertRule(str, index);\n } catch (err) {\n (0, _warning2['default'])(false, '[JSS] Can not insert an unsupported rule \\n\\r%s', rule);\n return false;\n }\n this.hasInsertedRules = true;\n\n return cssRules[index];\n }\n\n /**\n * Delete a rule.\n */\n\n }, {\n key: 'deleteRule',\n value: function deleteRule(cssRule) {\n var sheet = this.element.sheet;\n\n var index = this.indexOf(cssRule);\n if (index === -1) return false;\n sheet.deleteRule(index);\n return true;\n }\n\n /**\n * Get index of a CSS Rule.\n */\n\n }, {\n key: 'indexOf',\n value: function indexOf(cssRule) {\n var cssRules = this.element.sheet.cssRules;\n\n for (var _index = 0; _index < cssRules.length; _index++) {\n if (cssRule === cssRules[_index]) return _index;\n }\n return -1;\n }\n\n /**\n * Generate a new CSS rule and replace the existing one.\n */\n\n }, {\n key: 'replaceRule',\n value: function replaceRule(cssRule, rule) {\n var index = this.indexOf(cssRule);\n var newCssRule = this.insertRule(rule, index);\n this.element.sheet.deleteRule(index);\n return newCssRule;\n }\n\n /**\n * Get all rules elements.\n */\n\n }, {\n key: 'getRules',\n value: function getRules() {\n return this.element.sheet.cssRules;\n }\n }]);\n\n return DomRenderer;\n}();\n\nexports['default'] = DomRenderer;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/* eslint-disable class-methods-use-this */\n\n/**\n * Rendering backend to do nothing in nodejs.\n */\nvar VirtualRenderer = function () {\n function VirtualRenderer() {\n _classCallCheck(this, VirtualRenderer);\n }\n\n _createClass(VirtualRenderer, [{\n key: 'setProperty',\n value: function setProperty() {\n return true;\n }\n }, {\n key: 'getPropertyValue',\n value: function getPropertyValue() {\n return '';\n }\n }, {\n key: 'removeProperty',\n value: function removeProperty() {}\n }, {\n key: 'setSelector',\n value: function setSelector() {\n return true;\n }\n }, {\n key: 'getKey',\n value: function getKey() {\n return '';\n }\n }, {\n key: 'attach',\n value: function attach() {}\n }, {\n key: 'detach',\n value: function detach() {}\n }, {\n key: 'deploy',\n value: function deploy() {}\n }, {\n key: 'insertRule',\n value: function insertRule() {\n return false;\n }\n }, {\n key: 'deleteRule',\n value: function deleteRule() {\n return true;\n }\n }, {\n key: 'replaceRule',\n value: function replaceRule() {\n return false;\n }\n }, {\n key: 'getRules',\n value: function getRules() {}\n }, {\n key: 'indexOf',\n value: function indexOf() {\n return -1;\n }\n }]);\n\n return VirtualRenderer;\n}();\n\nexports['default'] = VirtualRenderer;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _RuleList = require('../RuleList');\n\nvar _RuleList2 = _interopRequireDefault(_RuleList);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Conditional rule for @media, @supports\n */\nvar ConditionalRule = function () {\n function ConditionalRule(key, styles, options) {\n _classCallCheck(this, ConditionalRule);\n\n this.type = 'conditional';\n this.isProcessed = false;\n\n this.key = key;\n this.options = options;\n this.rules = new _RuleList2['default'](_extends({}, options, { parent: this }));\n\n for (var name in styles) {\n this.rules.add(name, styles[name]);\n }\n\n this.rules.process();\n }\n\n /**\n * Get a rule.\n */\n\n\n _createClass(ConditionalRule, [{\n key: 'getRule',\n value: function getRule(name) {\n return this.rules.get(name);\n }\n\n /**\n * Get index of a rule.\n */\n\n }, {\n key: 'indexOf',\n value: function indexOf(rule) {\n return this.rules.indexOf(rule);\n }\n\n /**\n * Create and register rule, run plugins.\n */\n\n }, {\n key: 'addRule',\n value: function addRule(name, style, options) {\n var rule = this.rules.add(name, style, options);\n this.options.jss.plugins.onProcessRule(rule);\n return rule;\n }\n\n /**\n * Generates a CSS string.\n */\n\n }, {\n key: 'toString',\n value: function toString() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { indent: 1 };\n\n var inner = this.rules.toString(options);\n return inner ? this.key + ' {\\n' + inner + '\\n}' : '';\n }\n }]);\n\n return ConditionalRule;\n}();\n\nexports['default'] = ConditionalRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _toCss = require('../utils/toCss');\n\nvar _toCss2 = _interopRequireDefault(_toCss);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar FontFaceRule = function () {\n function FontFaceRule(key, style, options) {\n _classCallCheck(this, FontFaceRule);\n\n this.type = 'font-face';\n this.isProcessed = false;\n\n this.key = key;\n this.style = style;\n this.options = options;\n }\n\n /**\n * Generates a CSS string.\n */\n\n\n _createClass(FontFaceRule, [{\n key: 'toString',\n value: function toString(options) {\n if (Array.isArray(this.style)) {\n var str = '';\n for (var index = 0; index < this.style.length; index++) {\n str += (0, _toCss2['default'])(this.key, this.style[index]);\n if (this.style[index + 1]) str += '\\n';\n }\n return str;\n }\n\n return (0, _toCss2['default'])(this.key, this.style, options);\n }\n }]);\n\n return FontFaceRule;\n}();\n\nexports['default'] = FontFaceRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _RuleList = require('../RuleList');\n\nvar _RuleList2 = _interopRequireDefault(_RuleList);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Rule for @keyframes\n */\nvar KeyframesRule = function () {\n function KeyframesRule(key, frames, options) {\n _classCallCheck(this, KeyframesRule);\n\n this.type = 'keyframes';\n this.isProcessed = false;\n\n this.key = key;\n this.options = options;\n this.rules = new _RuleList2['default'](_extends({}, options, { parent: this }));\n\n for (var name in frames) {\n this.rules.add(name, frames[name], _extends({}, this.options, {\n parent: this,\n selector: name\n }));\n }\n\n this.rules.process();\n }\n\n /**\n * Generates a CSS string.\n */\n\n\n _createClass(KeyframesRule, [{\n key: 'toString',\n value: function toString() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { indent: 1 };\n\n var inner = this.rules.toString(options);\n if (inner) inner += '\\n';\n return this.key + ' {\\n' + inner + '}';\n }\n }]);\n\n return KeyframesRule;\n}();\n\nexports['default'] = KeyframesRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SimpleRule = function () {\n function SimpleRule(key, value, options) {\n _classCallCheck(this, SimpleRule);\n\n this.type = 'simple';\n this.isProcessed = false;\n\n this.key = key;\n this.value = value;\n this.options = options;\n }\n\n /**\n * Generates a CSS string.\n */\n // eslint-disable-next-line no-unused-vars\n\n\n _createClass(SimpleRule, [{\n key: 'toString',\n value: function toString(options) {\n if (Array.isArray(this.value)) {\n var str = '';\n for (var index = 0; index < this.value.length; index++) {\n str += this.key + ' ' + this.value[index] + ';';\n if (this.value[index + 1]) str += '\\n';\n }\n return str;\n }\n\n return this.key + ' ' + this.value + ';';\n }\n }]);\n\n return SimpleRule;\n}();\n\nexports['default'] = SimpleRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nvar _toCss = require('../utils/toCss');\n\nvar _toCss2 = _interopRequireDefault(_toCss);\n\nvar _toCssValue = require('../utils/toCssValue');\n\nvar _toCssValue2 = _interopRequireDefault(_toCssValue);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar StyleRule = function () {\n function StyleRule(key, style, options) {\n _classCallCheck(this, StyleRule);\n\n this.type = 'style';\n this.isProcessed = false;\n var sheet = options.sheet,\n Renderer = options.Renderer,\n selector = options.selector;\n\n this.key = key;\n this.options = options;\n this.style = style;\n if (selector) this.selectorText = selector;\n this.renderer = sheet ? sheet.renderer : new Renderer();\n }\n\n /**\n * Set selector string.\n * Attention: use this with caution. Most browsers didn't implement\n * selectorText setter, so this may result in rerendering of entire Style Sheet.\n */\n\n\n _createClass(StyleRule, [{\n key: 'prop',\n\n\n /**\n * Get or set a style property.\n */\n value: function prop(name, value) {\n // It's a getter.\n if (value === undefined) return this.style[name];\n\n // Don't do anything if the value has not changed.\n if (this.style[name] === value) return this;\n\n value = this.options.jss.plugins.onChangeValue(value, name, this);\n\n var isEmpty = value == null || value === false;\n var isDefined = name in this.style;\n\n // Value is empty and wasn't defined before.\n if (isEmpty && !isDefined) return this;\n\n // We are going to remove this value.\n var remove = isEmpty && isDefined;\n\n if (remove) delete this.style[name];else this.style[name] = value;\n\n // Renderable is defined if StyleSheet option ` + "`"))) + ((`link` + ("`" + ` is true.\n if (this.renderable) {\n if (remove) this.renderer.removeProperty(this.renderable, name);else this.renderer.setProperty(this.renderable, name, value);\n return this;\n }\n\n var sheet = this.options.sheet;\n\n if (sheet && sheet.attached) {\n (0, _warning2['default'])(false, 'Rule is not linked. Missing sheet option \"link: true\".');\n }\n return this;\n }\n\n /**\n * Apply rule to an element inline.\n */\n\n }, {\n key: 'applyTo',\n value: function applyTo(renderable) {\n var json = this.toJSON();\n for (var prop in json) {\n this.renderer.setProperty(renderable, prop, json[prop]);\n }return this;\n }\n\n /**\n * Returns JSON representation of the rule.\n * Fallbacks are not supported.\n * Useful for inline styles.\n */\n\n }, {\n key: 'toJSON',\n value: function toJSON() {\n var json = {};\n for (var prop in this.style) {\n var value = this.style[prop];\n if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object') json[prop] = value;else if (Array.isArray(value)) json[prop] = (0, _toCssValue2['default'])(value);\n }\n return json;\n }\n\n /**\n * Generates a CSS string.\n */\n\n }, {\n key: 'toString',\n value: function toString(options) {\n var sheet = this.options.sheet;\n\n var link = sheet ? sheet.options.link : false;\n var opts = link ? _extends({}, options, { allowEmpty: true }) : options;\n return (0, _toCss2['default'])(this.selector, this.style, opts);\n }\n }, {\n key: 'selector',\n set: function set(selector) {\n if (selector === this.selectorText) return;\n\n this.selectorText = selector;\n\n if (!this.renderable) return;\n\n var hasChanged = this.renderer.setSelector(this.renderable, selector);\n\n // If selector setter is not implemented, rerender the rule.\n if (!hasChanged && this.renderable) {\n var renderable = this.renderer.replaceRule(this.renderable, this);\n if (renderable) this.renderable = renderable;\n }\n }\n\n /**\n * Get selector string.\n */\n ,\n get: function get() {\n return this.selectorText;\n }\n }]);\n\n return StyleRule;\n}();\n\nexports['default'] = StyleRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _toCss = require('../utils/toCss');\n\nvar _toCss2 = _interopRequireDefault(_toCss);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar ViewportRule = function () {\n function ViewportRule(key, style, options) {\n _classCallCheck(this, ViewportRule);\n\n this.type = 'viewport';\n this.isProcessed = false;\n\n this.key = key;\n this.style = style;\n this.options = options;\n }\n\n /**\n * Generates a CSS string.\n */\n\n\n _createClass(ViewportRule, [{\n key: 'toString',\n value: function toString(options) {\n return (0, _toCss2['default'])(this.key, this.style, options);\n }\n }]);\n\n return ViewportRule;\n}();\n\nexports['default'] = ViewportRule;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _SheetsRegistry = require('./SheetsRegistry');\n\nvar _SheetsRegistry2 = _interopRequireDefault(_SheetsRegistry);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * This is a global sheets registry. Only DomRenderer will add sheets to it.\n * On the server one should use an own SheetsRegistry instance and add the\n * sheets to it, because you need to make sure to create a new registry for\n * each request in order to not leak sheets across requests.\n */\nexports['default'] = new _SheetsRegistry2['default']();", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nexports['default'] = cloneStyle;\n\nvar _isObservable = require('./isObservable');\n\nvar _isObservable2 = _interopRequireDefault(_isObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar isArray = Array.isArray;\nfunction cloneStyle(style) {\n // Support empty values in case user ends up with them by accident.\n if (style == null) return style;\n\n // Support string value for SimpleRule.\n var typeOfStyle = typeof style === 'undefined' ? 'undefined' : _typeof(style);\n\n if (typeOfStyle === 'string' || typeOfStyle === 'number' || typeOfStyle === 'function') {\n return style;\n }\n\n // Support array for FontFaceRule.\n if (isArray(style)) return style.map(cloneStyle);\n\n // Support Observable styles. Observables are immutable, so we don't need to\n // copy them.\n if ((0, _isObservable2['default'])(style)) return style;\n\n var newStyle = {};\n for (var name in style) {\n var value = style[name];\n if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n newStyle[name] = cloneStyle(value);\n continue;\n }\n newStyle[name] = value;\n }\n\n return newStyle;\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nvar _StyleSheet = require('../StyleSheet');\n\nvar _StyleSheet2 = _interopRequireDefault(_StyleSheet);\n\nvar _moduleId = require('./moduleId');\n\nvar _moduleId2 = _interopRequireDefault(_moduleId);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar maxRules = 1e10;\n\n\nvar env = process.env.NODE_ENV;\n\n/**\n * Returns a function which generates unique class names based on counters.\n * When new generator function is created, rule counter is reseted.\n * We need to reset the rule counter for SSR for each request.\n */\n\nexports['default'] = function () {\n var ruleCounter = 0;\n var defaultPrefix = env === 'production' ? 'c' : '';\n\n return function (rule, sheet) {\n ruleCounter += 1;\n\n if (ruleCounter > maxRules) {\n (0, _warning2['default'])(false, '[JSS] You might have a memory leak. Rule counter is at %s.', ruleCounter);\n }\n\n var prefix = defaultPrefix;\n var jssId = '';\n\n if (sheet) {\n prefix = sheet.options.classNamePrefix || defaultPrefix;\n if (sheet.options.jss.id != null) jssId += sheet.options.jss.id;\n }\n\n if (env === 'production') {\n return '' + prefix + _moduleId2['default'] + jssId + ruleCounter;\n }\n\n return prefix + rule.key + '-' + _moduleId2['default'] + (jssId && '-' + jssId) + '-' + ruleCounter;\n };\n};", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = createRule;\n\nvar _warning = require('warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nvar _StyleRule = require('../rules/StyleRule');\n\nvar _StyleRule2 = _interopRequireDefault(_StyleRule);\n\nvar _cloneStyle = require('../utils/cloneStyle');\n\nvar _cloneStyle2 = _interopRequireDefault(_cloneStyle);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Create a rule instance.\n */\nfunction createRule() {\n var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unnamed';\n var decl = arguments[1];\n var options = arguments[2];\n var jss = options.jss;\n\n var declCopy = (0, _cloneStyle2['default'])(decl);\n\n var rule = jss.plugins.onCreateRule(name, declCopy, options);\n if (rule) return rule;\n\n // It is an at-rule and it has no instance.\n if (name[0] === '@') {\n (0, _warning2['default'])(false, '[JSS] Unknown at-rule %s', name);\n }\n\n return new _StyleRule2['default'](name, declCopy, options);\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar CSS = global.CSS;\n\nvar env = process.env.NODE_ENV;\n\nvar escapeRegex = /([[\\].#*$><+~=|^:(),\"'`)) + ("`" + (`])/g;\n\nexports['default'] = function (str) {\n // We don't need to escape it in production, because we are not using user's\n // input for selectors, we are generating a valid selector.\n if (env === 'production') return str;\n\n if (!CSS || !CSS.escape) {\n return str.replace(escapeRegex, '\\\\$1');\n }\n\n return CSS.escape(str);\n};", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nexports['default'] = getDynamicStyles;\n/**\n * Extracts a styles object with only props that contain function values.\n */\nfunction getDynamicStyles(styles) {\n var to = null;\n\n for (var key in styles) {\n var value = styles[key];\n var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);\n\n if (type === 'function') {\n if (!to) to = {};\n to[key] = value;\n } else if (type === 'object' && value !== null && !Array.isArray(value)) {\n var extracted = getDynamicStyles(value);\n if (extracted) {\n if (!to) to = {};\n to[key] = extracted;\n }\n }\n }\n\n return to;\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _symbolObservable = require('symbol-observable');\n\nvar _symbolObservable2 = _interopRequireDefault(_symbolObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nexports['default'] = function (value) {\n return value && value[_symbolObservable2['default']] && value === value[_symbolObservable2['default']]();\n};", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = linkRule;\n/**\n * Link rule with CSSStyleRule and nested rules with corresponding nested cssRules if both exists.\n */\nfunction linkRule(rule, cssRule) {\n rule.renderable = cssRule;\n if (rule.rules && cssRule.cssRules) rule.rules.link(cssRule.cssRules);\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar ns = '2f1acc6c3a606b082e5eef5e54414ffb';\nif (global[ns] == null) global[ns] = 0;\n\n// Bundle may contain multiple JSS versions at the same time. In order to identify\n// the current version with just one short number and use it for classes generation\n// we use a counter. Also it is more accurate, because user can manually reevaluate\n// the module.\nexports['default'] = global[ns]++;", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = toCss;\n\nvar _toCssValue = require('./toCssValue');\n\nvar _toCssValue2 = _interopRequireDefault(_toCssValue);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Indent a string.\n * http://jsperf.com/array-join-vs-for\n */\nfunction indentStr(str, indent) {\n var result = '';\n for (var index = 0; index < indent; index++) {\n result += ' ';\n }return result + str;\n}\n\n/**\n * Converts a Rule to CSS string.\n */\n\nfunction toCss(selector, style) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n var result = '';\n\n if (!style) return result;\n\n var _options$indent = options.indent,\n indent = _options$indent === undefined ? 0 : _options$indent;\n var fallbacks = style.fallbacks;\n\n\n indent++;\n\n // Apply fallbacks first.\n if (fallbacks) {\n // Array syntax {fallbacks: [{prop: value}]}\n if (Array.isArray(fallbacks)) {\n for (var index = 0; index < fallbacks.length; index++) {\n var fallback = fallbacks[index];\n for (var prop in fallback) {\n var value = fallback[prop];\n if (value != null) {\n result += '\\n' + indentStr(prop + ': ' + (0, _toCssValue2['default'])(value) + ';', indent);\n }\n }\n }\n } else {\n // Object syntax {fallbacks: {prop: value}}\n for (var _prop in fallbacks) {\n var _value = fallbacks[_prop];\n if (_value != null) {\n result += '\\n' + indentStr(_prop + ': ' + (0, _toCssValue2['default'])(_value) + ';', indent);\n }\n }\n }\n }\n\n for (var _prop2 in style) {\n var _value2 = style[_prop2];\n if (_value2 != null && _prop2 !== 'fallbacks') {\n result += '\\n' + indentStr(_prop2 + ': ' + (0, _toCssValue2['default'])(_value2) + ';', indent);\n }\n }\n\n // Allow empty style in this case, because properties will be added dynamically.\n if (!result && !options.allowEmpty) return result;\n\n indent--;\n result = indentStr(selector + ' {' + result + '\\n', indent) + indentStr('}', indent);\n\n return result;\n}", + "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports['default'] = toCssValue;\nvar join = function join(value, by) {\n var result = '';\n for (var i = 0; i < value.length; i++) {\n // Remove !important from the value, it will be readded later.\n if (value[i] === '!important') break;\n if (result) result += by;\n result += value[i];\n }\n return result;\n};\n\n/**\n * Converts array values to string.\n *\n * ` + "`"))))) + ((((`margin: [['5px', '10px']]` + ("`" + ` > `)) + ("`" + (`margin: 5px 10px;` + "`"))) + ((`\n * ` + ("`" + `border: ['1px', '2px']`)) + ("`" + (` > ` + "`")))) + (((`border: 1px, 2px;` + ("`" + `\n * `)) + ("`" + (`margin: [['5px', '10px'], '!important']` + "`"))) + ((` > ` + ("`" + `margin: 5px 10px !important;`)) + (("`" + `\n * `) + ("`" + `color: ['red', !important]`)))))) + ((((("`" + (` > ` + "`")) + (`color: red !important;` + ("`" + `\n */\nfunction toCssValue(value) {\n var ignoreImportant = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (!Array.isArray(value)) return value;\n\n var cssValue = '';\n\n // Support space separated values via `))) + (("`" + (`[['5px', '10px']]` + "`")) + (`.\n if (Array.isArray(value[0])) {\n for (var i = 0; i < value.length; i++) {\n if (value[i] === '!important') break;\n if (cssValue) cssValue += ', ';\n cssValue += join(value[i], ' ');\n }\n } else cssValue = join(value, ', ');\n\n // Add !important, because it was ignored.\n if (!ignoreImportant && value[value.length - 1] === '!important') {\n cssValue += ' !important';\n }\n\n return cssValue;\n}", + "/**\n * Copyright 2014-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n warning = function(condition, format, args) {\n var len = arguments.length;\n args = new Array(len > 2 ? len - 2 : 0);\n for (var key = 2; key < len; key++) {\n args[key - 2] = arguments[key];\n }\n if (format === undefined) {\n throw new Error(\n '` + ("`" + `warning(condition, format, ...args)`)))) + ((("`" + (` requires a warning ' +\n 'message argument'\n );\n }\n\n if (format.length < 10 || (/^[s\\W]*$/).test(format)) {\n throw new Error(\n 'The warning format should be able to uniquely identify this ' +\n 'warning. Please, use a more descriptive format than: ' + format\n );\n }\n\n if (!condition) {\n var argIndex = 0;\n var message = 'Warning: ' +\n format.replace(/%s/g, function() {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch(x) {}\n }\n };\n}\n\nmodule.exports = warning;\n", + "/**\n * lodash (Custom Build) \n * Build: ` + "`")) + (`lodash modularize exports=\"npm\" -o ./` + ("`" + `\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `))) + (("`" + (`TypeError` + "`")) + ((` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various ` + "`") + (`Number` + "`"))))) + ((((` constants. */\nvar NAN = 0 / 0;\n\n/** ` + ("`" + `Object#toString`)) + ("`" + (` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on ` + "`"))) + ((`root` + ("`" + `. */\nvar freeParseInt = parseInt;\n\n/** Detect free variable `)) + ("`" + (`global` + "`")))) + (((` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable ` + ("`" + `self`)) + ("`" + (`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [` + "`"))) + ((`toStringTag` + ("`" + `](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `)) + (("`" + `lodash`) + ("`" + ` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\n/**\n * Creates a debounced function that delays invoking `)))))))) + ((((((("`" + (`func` + "`")) + (` until after ` + ("`" + `wait`))) + (("`" + (`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a ` + "`")) + (`cancel` + ("`" + ` method to cancel\n * delayed `)))) + ((("`" + (`func` + "`")) + (` invocations and a ` + ("`" + `flush`))) + (("`" + (` method to immediately invoke them.\n * Provide ` + "`")) + (`options` + ("`" + ` to indicate whether `))))) + (((("`" + (`func` + "`")) + (` should be invoked on the\n * leading and/or trailing edge of the ` + ("`" + `wait`))) + (("`" + (` timeout. The ` + "`")) + (`func` + ("`" + ` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `)))) + ((("`" + (`func` + "`")) + (`\n * invocation.\n *\n * **Note:** If ` + ("`" + `leading`))) + (("`" + (` and ` + "`")) + ((`trailing` + "`") + (` options are ` + "`")))))) + (((((`true` + ("`" + `, `)) + ("`" + (`func` + "`"))) + ((` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the ` + ("`" + `wait`)) + ("`" + (` timeout.\n *\n * If ` + "`")))) + (((`wait` + ("`" + ` is `)) + ("`" + (`0` + "`"))) + ((` and ` + ("`" + `leading`)) + (("`" + ` is `) + ("`" + `false`))))) + (((("`" + (`, ` + "`")) + (`func` + ("`" + ` invocation is deferred\n * until to the next tick, similar to `))) + (("`" + (`setTimeout` + "`")) + (` with a timeout of ` + ("`" + `0`)))) + ((("`" + (`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between ` + "`")) + (`_.debounce` + ("`" + ` and `))) + (("`" + (`_.throttle` + "`")) + ((`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time ` + "`") + (`func` + "`"))))))) + ((((((` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke ` + ("`" + `sendMail`)) + ("`" + (` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure ` + "`"))) + ((`batchLog` + ("`" + ` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `)) + ("`" + (`maxWait` + "`")))) + (((` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the ` + ("`" + `maxWait`)) + ("`" + (` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have ` + "`"))) + ((`lastArgs` + ("`" + ` which means `)) + (("`" + `func`) + ("`" + ` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Checks if `))))) + (((("`" + (`value` + "`")) + (` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of ` + ("`" + `Object`))) + (("`" + (`. (e.g. arrays, functions, objects, regexes, ` + "`")) + (`new Number(0)` + ("`" + `, and `)))) + ((("`" + (`new String('')` + "`")) + (`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + ((`value` + "`") + (` is an object, else ` + "`")))))) + (((((`false` + ("`" + `.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `)) + ("`" + (`value` + "`"))) + ((` is object-like. A value is object-like if it's not ` + ("`" + `null`)) + ("`" + (`\n * and has a ` + "`")))) + (((`typeof` + ("`" + ` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))) + ((` if ` + ("`" + `value`)) + (("`" + ` is object-like, else `) + ("`" + `false`))))) + (((("`" + (`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is classified as a `))) + (("`" + (`Symbol` + "`")) + (` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)))) + ((("`" + (` if ` + "`")) + (`value` + ("`" + ` is a symbol, else `))) + (("`" + (`false` + "`")) + ((`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts ` + "`") + (`value` + "`")))))))))) + (((((((((` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = debounce;\n", + "/**\n * lodash (Custom Build) \n * Build: ` + ("`" + `lodash modularize exports=\"npm\" -o ./`)) + ("`" + (`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the ` + "`"))) + ((`TypeError` + ("`" + ` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `)) + ("`" + (`Number` + "`")))) + (((` constants. */\nvar NAN = 0 / 0;\n\n/** ` + ("`" + `Object#toString`)) + ("`" + (` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on ` + "`"))) + ((`root` + ("`" + `. */\nvar freeParseInt = parseInt;\n\n/** Detect free variable `)) + ("`" + (`global` + "`"))))) + ((((` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable ` + ("`" + `self`)) + ("`" + (`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [` + "`"))) + ((`toStringTag` + ("`" + `](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `)) + ("`" + (`lodash` + "`")))) + (((` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\n/**\n * Creates a debounced function that delays invoking ` + ("`" + `func`)) + ("`" + (` until after ` + "`"))) + ((`wait` + ("`" + `\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `)) + (("`" + `cancel`) + ("`" + ` method to cancel\n * delayed `)))))) + ((((("`" + (`func` + "`")) + (` invocations and a ` + ("`" + `flush`))) + (("`" + (` method to immediately invoke them.\n * Provide ` + "`")) + (`options` + ("`" + ` to indicate whether `)))) + ((("`" + (`func` + "`")) + (` should be invoked on the\n * leading and/or trailing edge of the ` + ("`" + `wait`))) + (("`" + (` timeout. The ` + "`")) + ((`func` + "`") + (` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last ` + "`"))))) + ((((`func` + ("`" + `\n * invocation.\n *\n * **Note:** If `)) + ("`" + (`leading` + "`"))) + ((` and ` + ("`" + `trailing`)) + ("`" + (` options are ` + "`")))) + (((`true` + ("`" + `, `)) + ("`" + (`func` + "`"))) + ((` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the ` + ("`" + `wait`)) + (("`" + ` timeout.\n *\n * If `) + ("`" + `wait`))))))) + (((((("`" + (` is ` + "`")) + (`0` + ("`" + ` and `))) + (("`" + (`leading` + "`")) + (` is ` + ("`" + `false`)))) + ((("`" + (`, ` + "`")) + (`func` + ("`" + ` invocation is deferred\n * until to the next tick, similar to `))) + (("`" + (`setTimeout` + "`")) + (` with a timeout of ` + ("`" + `0`))))) + (((("`" + (`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between ` + "`")) + (`_.debounce` + ("`" + ` and `))) + (("`" + (`_.throttle` + "`")) + (`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time ` + ("`" + `func`)))) + ((("`" + (` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke ` + "`")) + (`sendMail` + ("`" + ` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `))) + (("`" + (`batchLog` + "`")) + ((` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any ` + "`") + (`maxWait` + "`")))))) + (((((` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the ` + ("`" + `maxWait`)) + ("`" + (` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have ` + "`"))) + ((`lastArgs` + ("`" + ` which means `)) + ("`" + (`func` + "`")))) + (((` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Creates a throttled function that only invokes ` + ("`" + `func`)) + ("`" + (` at most once per\n * every ` + "`"))) + ((`wait` + ("`" + ` milliseconds. The throttled function comes with a `)) + (("`" + `cancel`) + ("`" + `\n * method to cancel delayed `))))) + (((("`" + (`func` + "`")) + (` invocations and a ` + ("`" + `flush`))) + (("`" + (` method to\n * immediately invoke them. Provide ` + "`")) + (`options` + ("`" + ` to indicate whether `)))) + ((("`" + (`func` + "`")) + (`\n * should be invoked on the leading and/or trailing edge of the ` + ("`" + `wait`))) + (("`" + (`\n * timeout. The ` + "`")) + ((`func` + "`") + (` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last ` + "`")))))))) + (((((((`func` + ("`" + ` invocation.\n *\n * **Note:** If `)) + ("`" + (`leading` + "`"))) + ((` and ` + ("`" + `trailing`)) + ("`" + (` options are ` + "`")))) + (((`true` + ("`" + `, `)) + ("`" + (`func` + "`"))) + ((` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the ` + ("`" + `wait`)) + ("`" + (` timeout.\n *\n * If ` + "`"))))) + ((((`wait` + ("`" + ` is `)) + ("`" + (`0` + "`"))) + ((` and ` + ("`" + `leading`)) + ("`" + (` is ` + "`")))) + (((`false` + ("`" + `, `)) + ("`" + (`func` + "`"))) + ((` invocation is deferred\n * until to the next tick, similar to ` + ("`" + `setTimeout`)) + (("`" + ` with a timeout of `) + ("`" + `0`)))))) + ((((("`" + (`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between ` + "`")) + (`_.throttle` + ("`" + ` and `))) + (("`" + (`_.debounce` + "`")) + (`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke ` + ("`" + `renewToken`)))) + ((("`" + (` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n}\n\n/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `))) + (("`" + (`Object` + "`")) + ((`. (e.g. arrays, functions, objects, regexes, ` + "`") + (`new Number(0)` + "`"))))) + ((((`, and ` + ("`" + `new String('')`)) + ("`" + (`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`"))) + ((`true` + ("`" + ` if `)) + ("`" + (`value` + "`")))) + (((` is an object, else ` + ("`" + `false`)) + ("`" + (`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if ` + "`"))) + ((`value` + ("`" + ` is object-like. A value is object-like if it's not `)) + (("`" + `null`) + ("`" + `\n * and has a `))))))) + (((((("`" + (`typeof` + "`")) + (` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`value` + ("`" + ` is object-like, else `)))) + ((("`" + (`false` + "`")) + (`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if ` + ("`" + `value`))) + (("`" + (` is classified as a ` + "`")) + ((`Symbol` + "`") + (` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`"))))) + ((((`true` + ("`" + ` if `)) + ("`" + (`value` + "`"))) + ((` is a symbol, else ` + ("`" + `false`)) + ("`" + (`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts ` + "`")))) + (((`value` + ("`" + ` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = throttle;\n", + "var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n", + "var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `)) + ("`" + (`Hash` + "`"))) + ((`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n", + "var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to ` + ("`" + `ListCache`)) + (("`" + `.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n", + "var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n", + "var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `) + ("`" + `MapCache`)))))) + ((((("`" + (`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n", + "var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n", + "var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n", + "var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to ` + "`")) + (`SetCache` + ("`" + `.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n", + "var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `))) + (("`" + (`Stack` + "`")) + (`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n", + "var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n", + "var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n", + "var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n", + "/**\n * A faster alternative to ` + ("`" + `Function#apply`)))) + ((("`" + (`, this function invokes ` + "`")) + (`func` + ("`" + `\n * with the `))) + (("`" + (`this` + "`")) + ((` binding of ` + "`") + (`thisArg` + "`"))))) + ((((` and the arguments of ` + ("`" + `args`)) + ("`" + (`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The ` + "`"))) + ((`this` + ("`" + ` binding of `)) + ("`" + (`func` + "`")))) + (((`.\n * @param {Array} args The arguments to invoke ` + ("`" + `func`)) + ("`" + (` with.\n * @returns {*} Returns the result of ` + "`"))) + ((`func` + ("`" + `.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n", + "/**\n * A specialized version of `)) + (("`" + `_.every`) + ("`" + ` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `))))))))) + (((((((("`" + (`true` + "`")) + (` if all elements pass the predicate check,\n * else ` + ("`" + `false`))) + (("`" + (`.\n */\nfunction arrayEvery(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (!predicate(array[index], index, array)) {\n return false;\n }\n }\n return true;\n}\n\nmodule.exports = arrayEvery;\n", + "/**\n * A specialized version of ` + "`")) + (`_.filter` + ("`" + ` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n", + "var baseIndexOf = require('./_baseIndexOf');\n\n/**\n * A specialized version of `)))) + ((("`" + (`_.includes` + "`")) + (` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`target` + ("`" + ` is found, else `))))) + (((("`" + (`false` + "`")) + (`.\n */\nfunction arrayIncludes(array, value) {\n var length = array == null ? 0 : array.length;\n return !!length && baseIndexOf(array, value, 0) > -1;\n}\n\nmodule.exports = arrayIncludes;\n", + "/**\n * This function is like ` + ("`" + `arrayIncludes`))) + (("`" + (` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if `)))) + ((("`" + (`target` + "`")) + (` is found, else ` + ("`" + `false`))) + (("`" + (`.\n */\nfunction arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arrayIncludesWith;\n", + "var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like ` + "`")) + ((`value` + "`") + (`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable ` + "`")))))) + (((((`arguments.length` + ("`" + ` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n", + "/**\n * A specialized version of `)) + ("`" + (`_.map` + "`"))) + ((` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n", + "/**\n * Appends the elements of ` + ("`" + `values`)) + ("`" + (` to ` + "`")))) + (((`array` + ("`" + `.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `)) + ("`" + (`array` + "`"))) + ((`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n", + "/**\n * A specialized version of ` + ("`" + `_.some`)) + (("`" + ` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `) + ("`" + `true`))))) + (((("`" + (` if any element passes the predicate check,\n * else ` + "`")) + (`false` + ("`" + `.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n", + "var eq = require('./eq');\n\n/**\n * Gets the index at which the `))) + (("`" + (`key` + "`")) + (` is found in ` + ("`" + `array`)))) + ((("`" + (` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else ` + "`")) + (`-1` + ("`" + `.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n", + "var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `))) + (("`" + (`assignValue` + "`")) + ((` and ` + "`") + (`assignMergeValue` + "`"))))))) + ((((((` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n", + "var baseForOwn = require('./_baseForOwn'),\n createBaseEach = require('./_createBaseEach');\n\n/**\n * The base implementation of ` + ("`" + `_.forEach`)) + ("`" + (` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns ` + "`"))) + ((`collection` + ("`" + `.\n */\nvar baseEach = createBaseEach(baseForOwn);\n\nmodule.exports = baseEach;\n", + "var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of `)) + ("`" + (`_.every` + "`")))) + (((` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if all elements pass the predicate check,\n * else ` + "`"))) + ((`false` + ("`" + `\n */\nfunction baseEvery(collection, predicate) {\n var result = true;\n baseEach(collection, function(value, index, collection) {\n result = !!predicate(value, index, collection);\n return result;\n });\n return result;\n}\n\nmodule.exports = baseEvery;\n", + "var isSymbol = require('./isSymbol');\n\n/**\n * The base implementation of methods like `)) + ("`" + (`_.max` + "`"))))) + ((((` and ` + ("`" + `_.min`)) + ("`" + (` which accepts a\n * ` + "`"))) + ((`comparator` + ("`" + ` to determine the extremum value.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The iteratee invoked per iteration.\n * @param {Function} comparator The comparator used to compare values.\n * @returns {*} Returns the extremum value.\n */\nfunction baseExtremum(array, iteratee, comparator) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n var value = array[index],\n current = iteratee(value);\n\n if (current != null && (computed === undefined\n ? (current === current && !isSymbol(current))\n : comparator(current, computed)\n )) {\n var computed = current,\n result = value;\n }\n }\n return result;\n}\n\nmodule.exports = baseExtremum;\n", + "var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of `)) + ("`" + (`_.filter` + "`")))) + (((` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction baseFilter(collection, predicate) {\n var result = [];\n baseEach(collection, function(value, index, collection) {\n if (predicate(value, index, collection)) {\n result.push(value);\n }\n });\n return result;\n}\n\nmodule.exports = baseFilter;\n", + "/**\n * The base implementation of ` + ("`" + `_.findIndex`)) + ("`" + (` and ` + "`"))) + ((`_.findLastIndex` + ("`" + ` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `)) + (("`" + `-1`) + ("`" + `.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n", + "var arrayPush = require('./_arrayPush'),\n isFlattenable = require('./_isFlattenable');\n\n/**\n * The base implementation of `)))))) + ((((("`" + (`_.flatten` + "`")) + (` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass ` + ("`" + `predicate`))) + (("`" + (` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nmodule.exports = baseFlatten;\n", + "var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of ` + "`")) + (`baseForOwn` + ("`" + ` which iterates over `)))) + ((("`" + (`object` + "`")) + (`\n * properties returned by ` + ("`" + `keysFunc`))) + (("`" + (` and invokes ` + "`")) + ((`iteratee` + "`") + (` for each property.\n * Iteratee functions may exit iteration early by explicitly returning ` + "`"))))) + ((((`false` + ("`" + `.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `)) + ("`" + (`object` + "`"))) + ((`.\n * @returns {Object} Returns ` + ("`" + `object`)) + ("`" + (`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n", + "var baseFor = require('./_baseFor'),\n keys = require('./keys');\n\n/**\n * The base implementation of ` + "`")))) + (((`_.forOwn` + ("`" + ` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `)) + ("`" + (`object` + "`"))) + ((`.\n */\nfunction baseForOwn(object, iteratee) {\n return object && baseFor(object, iteratee, keys);\n}\n\nmodule.exports = baseForOwn;\n", + "var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of ` + ("`" + `_.get`)) + (("`" + ` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n", + "var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `) + ("`" + `getAllKeys`)))))))) + ((((((("`" + (` and ` + "`")) + (`getAllKeysIn` + ("`" + ` which uses\n * `))) + (("`" + (`keysFunc` + "`")) + (` and ` + ("`" + `symbolsFunc`)))) + ((("`" + (` to get the enumerable property names and\n * symbols of ` + "`")) + (`object` + ("`" + `.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `))) + (("`" + (`object` + "`")) + (`.\n * @param {Function} symbolsFunc The function to get the symbols of ` + ("`" + `object`))))) + (((("`" + (`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n", + "var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** ` + "`")) + (`Object#toString` + ("`" + ` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `))) + (("`" + (`getTag` + "`")) + (` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the ` + ("`" + `toStringTag`)))) + ((("`" + (`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n", + "/**\n * The base implementation of ` + "`")) + (`_.gt` + ("`" + ` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `))) + (("`" + (`true` + "`")) + ((` if ` + "`") + (`value` + "`")))))) + (((((` is greater than ` + ("`" + `other`)) + ("`" + (`,\n * else ` + "`"))) + ((`false` + ("`" + `.\n */\nfunction baseGt(value, other) {\n return value > other;\n}\n\nmodule.exports = baseGt;\n", + "/**\n * The base implementation of `)) + ("`" + (`_.hasIn` + "`")))) + (((` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if ` + "`"))) + ((`key` + ("`" + ` exists, else `)) + (("`" + `false`) + ("`" + `.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n", + "var baseFindIndex = require('./_baseFindIndex'),\n baseIsNaN = require('./_baseIsNaN'),\n strictIndexOf = require('./_strictIndexOf');\n\n/**\n * The base implementation of `))))) + (((("`" + (`_.indexOf` + "`")) + (` without ` + ("`" + `fromIndex`))) + (("`" + (` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else ` + "`")) + (`-1` + ("`" + `.\n */\nfunction baseIndexOf(array, value, fromIndex) {\n return value === value\n ? strictIndexOf(array, value, fromIndex)\n : baseFindIndex(array, baseIsNaN, fromIndex);\n}\n\nmodule.exports = baseIndexOf;\n", + "var SetCache = require('./_SetCache'),\n arrayIncludes = require('./_arrayIncludes'),\n arrayIncludesWith = require('./_arrayIncludesWith'),\n arrayMap = require('./_arrayMap'),\n baseUnary = require('./_baseUnary'),\n cacheHas = require('./_cacheHas');\n\n/* Built-in method references for those with the same name as other `)))) + ((("`" + (`lodash` + "`")) + (` methods. */\nvar nativeMin = Math.min;\n\n/**\n * The base implementation of methods like ` + ("`" + `_.intersection`))) + (("`" + (`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\nfunction baseIntersection(arrays, iteratee, comparator) {\n var includes = comparator ? arrayIncludesWith : arrayIncludes,\n length = arrays[0].length,\n othLength = arrays.length,\n othIndex = othLength,\n caches = Array(othLength),\n maxLength = Infinity,\n result = [];\n\n while (othIndex--) {\n var array = arrays[othIndex];\n if (othIndex && iteratee) {\n array = arrayMap(array, baseUnary(iteratee));\n }\n maxLength = nativeMin(array.length, maxLength);\n caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n ? new SetCache(othIndex && array)\n : undefined;\n }\n array = arrays[0];\n\n var index = -1,\n seen = caches[0];\n\n outer:\n while (++index < length && result.length < maxLength) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (!(seen\n ? cacheHas(seen, computed)\n : includes(result, computed, comparator)\n )) {\n othIndex = othLength;\n while (--othIndex) {\n var cache = caches[othIndex];\n if (!(cache\n ? cacheHas(cache, computed)\n : includes(arrays[othIndex], computed, comparator))\n ) {\n continue outer;\n }\n }\n if (seen) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nmodule.exports = baseIntersection;\n", + "var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** ` + "`")) + ((`Object#toString` + "`") + (` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of ` + "`"))))))) + ((((((`_.isArguments` + ("`" + `.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))) + ((` if ` + ("`" + `value`)) + ("`" + (` is an ` + "`")))) + (((`arguments` + ("`" + ` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n", + "var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `)) + ("`" + (`_.isEqual` + "`"))) + ((` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed ` + ("`" + `value`)) + (("`" + ` and `) + ("`" + `other`))))) + (((("`" + (` objects.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if the values are equivalent, else `))) + (("`" + (`false` + "`")) + (`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n", + "var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** ` + ("`" + `Object#toString`)))) + ((("`" + (` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of ` + "`")) + (`baseIsEqual` + ("`" + ` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `))) + (("`" + (`baseIsEqual` + "`")) + ((` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed ` + "`") + (`object` + "`")))))) + (((((` and ` + ("`" + `other`)) + ("`" + (` objects.\n * @returns {boolean} Returns ` + "`"))) + ((`true` + ("`" + ` if the objects are equivalent, else `)) + ("`" + (`false` + "`")))) + (((`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n", + "var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of ` + ("`" + `_.isMatch`)) + ("`" + (` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns ` + "`"))) + ((`true` + ("`" + ` if `)) + (("`" + `object`) + ("`" + ` is a match, else `))))) + (((("`" + (`false` + "`")) + (`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n", + "/**\n * The base implementation of ` + ("`" + `_.isNaN`))) + (("`" + (` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if `)))) + ((("`" + (`value` + "`")) + (` is ` + ("`" + `NaN`))) + (("`" + (`, else ` + "`")) + ((`false` + "`") + (`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nmodule.exports = baseIsNaN;\n", + "var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match ` + "`")))))))))))) + (((((((((((`RegExp` + ("`" + `\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `)) + ("`" + (`_.isNative` + "`"))) + ((` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if ` + "`")))) + (((`value` + ("`" + ` is a native function,\n * else `)) + ("`" + (`false` + "`"))) + ((`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n", + "var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** ` + ("`" + `Object#toString`)) + ("`" + (` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify ` + "`"))))) + ((((`toStringTag` + ("`" + ` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `)) + ("`" + (`_.isTypedArray` + "`"))) + ((` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if ` + "`")))) + (((`value` + ("`" + ` is a typed array, else `)) + ("`" + (`false` + "`"))) + ((`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n", + "var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of ` + ("`" + `_.iteratee`)) + (("`" + `.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `) + ("`" + `typeof`)))))) + ((((("`" + (` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n", + "var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of ` + "`")) + (`_.keys` + ("`" + ` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n", + "/**\n * The base implementation of `))) + (("`" + (`_.lt` + "`")) + (` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns ` + ("`" + `true`)))) + ((("`" + (` if ` + "`")) + (`value` + ("`" + ` is less than `))) + (("`" + (`other` + "`")) + ((`,\n * else ` + "`") + (`false` + "`"))))) + ((((`.\n */\nfunction baseLt(value, other) {\n return value < other;\n}\n\nmodule.exports = baseLt;\n", + "var baseEach = require('./_baseEach'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * The base implementation of ` + ("`" + `_.map`)) + ("`" + (` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction baseMap(collection, iteratee) {\n var index = -1,\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value, key, collection) {\n result[++index] = iteratee(value, key, collection);\n });\n return result;\n}\n\nmodule.exports = baseMap;\n", + "var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of ` + "`"))) + ((`_.matches` + ("`" + ` which doesn't clone `)) + ("`" + (`source` + "`")))) + (((`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n", + "var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of ` + ("`" + `_.matchesProperty`)) + ("`" + (` which doesn't clone ` + "`"))) + ((`srcValue` + ("`" + `.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n", + "var arrayMap = require('./_arrayMap'),\n baseIteratee = require('./_baseIteratee'),\n baseMap = require('./_baseMap'),\n baseSortBy = require('./_baseSortBy'),\n baseUnary = require('./_baseUnary'),\n compareMultiple = require('./_compareMultiple'),\n identity = require('./identity');\n\n/**\n * The base implementation of `)) + (("`" + `_.orderBy`) + ("`" + ` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `))))))) + (((((("`" + (`iteratees` + "`")) + (`.\n * @returns {Array} Returns the new sorted array.\n */\nfunction baseOrderBy(collection, iteratees, orders) {\n var index = -1;\n iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(baseIteratee));\n\n var result = baseMap(collection, function(value, key, collection) {\n var criteria = arrayMap(iteratees, function(iteratee) {\n return iteratee(value);\n });\n return { 'criteria': criteria, 'index': ++index, 'value': value };\n });\n\n return baseSortBy(result, function(object, other) {\n return compareMultiple(object, other, orders);\n });\n}\n\nmodule.exports = baseOrderBy;\n", + "/**\n * The base implementation of ` + ("`" + `_.property`))) + (("`" + (` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n", + "var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of ` + "`")) + (`baseProperty` + ("`" + ` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n", + "/* Built-in method references for those with the same name as other `)))) + ((("`" + (`lodash` + "`")) + (` methods. */\nvar nativeCeil = Math.ceil,\n nativeMax = Math.max;\n\n/**\n * The base implementation of ` + ("`" + `_.range`))) + (("`" + (` and ` + "`")) + (`_.rangeRight` + ("`" + ` which doesn't\n * coerce arguments.\n *\n * @private\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @param {number} step The value to increment or decrement by.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the range of numbers.\n */\nfunction baseRange(start, end, step, fromRight) {\n var index = -1,\n length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n result = Array(length);\n\n while (length--) {\n result[fromRight ? length : ++index] = start;\n start += step;\n }\n return result;\n}\n\nmodule.exports = baseRange;\n", + "var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `))))) + (((("`" + (`_.rest` + "`")) + (` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n", + "var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of ` + ("`" + `setToString`))) + (("`" + (` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The ` + "`")) + (`toString` + ("`" + ` result.\n * @returns {Function} Returns `)))) + ((("`" + (`func` + "`")) + (`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n", + "var baseEach = require('./_baseEach');\n\n/**\n * The base implementation of ` + ("`" + `_.some`))) + (("`" + (` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if any element passes the predicate check,\n * else ` + "`")))))) + (((((`false` + ("`" + `.\n */\nfunction baseSome(collection, predicate) {\n var result;\n\n baseEach(collection, function(value, index, collection) {\n result = predicate(value, index, collection);\n return !result;\n });\n return !!result;\n}\n\nmodule.exports = baseSome;\n", + "/**\n * The base implementation of `)) + ("`" + (`_.sortBy` + "`"))) + ((` which uses ` + ("`" + `comparer`)) + ("`" + (` to define the\n * sort order of ` + "`")))) + (((`array` + ("`" + ` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `)) + ("`" + (`array` + "`"))) + ((`.\n */\nfunction baseSortBy(array, comparer) {\n var length = array.length;\n\n array.sort(comparer);\n while (length--) {\n array[length] = array[length].value;\n }\n return array;\n}\n\nmodule.exports = baseSortBy;\n", + "/**\n * The base implementation of ` + ("`" + `_.times`)) + (("`" + ` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `) + ("`" + `iteratee`))))) + (((("`" + (`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n", + "var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various ` + "`")) + (`Number` + ("`" + ` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `))) + (("`" + (`_.toString` + "`")) + (` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n", + "/**\n * The base implementation of ` + ("`" + `_.unary`)))) + ((("`" + (` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n", + "var SetCache = require('./_SetCache'),\n arrayIncludes = require('./_arrayIncludes'),\n arrayIncludesWith = require('./_arrayIncludesWith'),\n cacheHas = require('./_cacheHas'),\n createSet = require('./_createSet'),\n setToArray = require('./_setToArray');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of ` + "`")) + (`_.uniqBy` + ("`" + ` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nmodule.exports = baseUniq;\n", + "/**\n * Checks if a `))) + (("`" + (`cache` + "`")) + ((` value for ` + "`") + (`key` + "`")))))))) + (((((((` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if an entry for ` + "`"))) + ((`key` + ("`" + ` exists, else `)) + ("`" + (`false` + "`")))) + (((`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n", + "var isArrayLikeObject = require('./isArrayLikeObject');\n\n/**\n * Casts ` + ("`" + `value`)) + ("`" + (` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\nfunction castArrayLikeObject(value) {\n return isArrayLikeObject(value) ? value : [];\n}\n\nmodule.exports = castArrayLikeObject;\n", + "var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts ` + "`"))) + ((`value` + ("`" + ` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n", + "var isSymbol = require('./isSymbol');\n\n/**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `)) + ("`" + (`value` + "`"))))) + ((((`.\n */\nfunction compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n}\n\nmodule.exports = compareAscending;\n", + "var compareAscending = require('./_compareAscending');\n\n/**\n * Used by ` + ("`" + `_.orderBy`)) + ("`" + (` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If ` + "`"))) + ((`orders` + ("`" + ` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `)) + ("`" + (`object` + "`")))) + (((`.\n */\nfunction compareMultiple(object, other, orders) {\n var index = -1,\n objCriteria = object.criteria,\n othCriteria = other.criteria,\n length = objCriteria.length,\n ordersLength = orders.length;\n\n while (++index < length) {\n var result = compareAscending(objCriteria[index], othCriteria[index]);\n if (result) {\n if (index >= ordersLength) {\n return result;\n }\n var order = orders[index];\n return result * (order == 'desc' ? -1 : 1);\n }\n }\n // Fixes an ` + ("`" + `Array#sort`)) + ("`" + (` bug in the JS engine embedded in Adobe applications\n // that causes it, under certain circumstances, to provide the same value for\n // ` + "`"))) + ((`object` + ("`" + ` and `)) + (("`" + `other`) + ("`" + `. See https://github.com/jashkenas/underscore/pull/1247\n // for more details.\n //\n // This also ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n}\n\nmodule.exports = compareMultiple;\n", + "var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n", + "var isArrayLike = require('./isArrayLike');\n\n/**\n * Creates a `)))))) + ((((("`" + (`baseEach` + "`")) + (` or ` + ("`" + `baseEachRight`))) + (("`" + (` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseEach(eachFunc, fromRight) {\n return function(collection, iteratee) {\n if (collection == null) {\n return collection;\n }\n if (!isArrayLike(collection)) {\n return eachFunc(collection, iteratee);\n }\n var length = collection.length,\n index = fromRight ? length : -1,\n iterable = Object(collection);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (iteratee(iterable[index], index, iterable) === false) {\n break;\n }\n }\n return collection;\n };\n}\n\nmodule.exports = createBaseEach;\n", + "/**\n * Creates a base function for methods like ` + "`")) + (`_.forIn` + ("`" + ` and `)))) + ((("`" + (`_.forOwn` + "`")) + (`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nmodule.exports = createBaseFor;\n", + "var baseIteratee = require('./_baseIteratee'),\n isArrayLike = require('./isArrayLike'),\n keys = require('./keys');\n\n/**\n * Creates a ` + ("`" + `_.find`))) + (("`" + (` or ` + "`")) + ((`_.findLast` + "`") + (` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = baseIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n}\n\nmodule.exports = createFind;\n", + "var baseRange = require('./_baseRange'),\n isIterateeCall = require('./_isIterateeCall'),\n toFinite = require('./toFinite');\n\n/**\n * Creates a ` + "`"))))) + ((((`_.range` + ("`" + ` or `)) + ("`" + (`_.rangeRight` + "`"))) + ((` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new range function.\n */\nfunction createRange(fromRight) {\n return function(start, end, step) {\n if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n end = step = undefined;\n }\n // Ensure the sign of ` + ("`" + `-0`)) + ("`" + (` is preserved.\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n return baseRange(start, end, step, fromRight);\n };\n}\n\nmodule.exports = createRange;\n", + "var Set = require('./_Set'),\n noop = require('./noop'),\n setToArray = require('./_setToArray');\n\n/** Used as references for various ` + "`")))) + (((`Number` + ("`" + ` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Creates a set object of `)) + ("`" + (`values` + "`"))) + ((`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\nvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n};\n\nmodule.exports = createSet;\n", + "var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n", + "var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of ` + ("`" + `baseIsEqualDeep`)) + (("`" + ` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `) + ("`" + `baseIsEqual`))))))) + (((((("`" + (` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed ` + "`")) + (`array` + ("`" + ` and `))) + (("`" + (`other` + "`")) + (` objects.\n * @returns {boolean} Returns ` + ("`" + `true`)))) + ((("`" + (` if the arrays are equivalent, else ` + "`")) + (`false` + ("`" + `.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n", + "var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `))) + (("`" + (`Object#toString` + "`")) + (` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of ` + ("`" + `baseIsEqualDeep`))))) + (((("`" + (` for comparing objects of\n * the same ` + "`")) + (`toStringTag` + ("`" + `.\n *\n * **Note:** This function only supports comparing values with tags of\n * `))) + (("`" + (`Boolean` + "`")) + (`, ` + ("`" + `Date`)))) + ((("`" + (`, ` + "`")) + (`Error` + ("`" + `, `))) + (("`" + (`Number` + "`")) + ((`, ` + "`") + (`RegExp` + "`")))))) + (((((`, or ` + ("`" + `String`)) + ("`" + (`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The ` + "`"))) + ((`toStringTag` + ("`" + ` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `)) + ("`" + (`baseIsEqual` + "`")))) + (((` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed ` + ("`" + `object`)) + ("`" + (` and ` + "`"))) + ((`other` + ("`" + ` objects.\n * @returns {boolean} Returns `)) + (("`" + `true`) + ("`" + ` if the objects are equivalent, else `))))) + (((("`" + (`false` + "`")) + (`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to ` + ("`" + `1`))) + (("`" + (` or ` + "`")) + (`0` + ("`" + ` and dates to milliseconds.\n // Invalid dates are coerced to `)))) + ((("`" + (`NaN` + "`")) + (`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n", + "var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of ` + ("`" + `baseIsEqualDeep`))) + (("`" + (` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See ` + "`")) + ((`baseIsEqual` + "`") + (` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed ` + "`"))))))))) + ((((((((`object` + ("`" + ` and `)) + ("`" + (`other` + "`"))) + ((` objects.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if the objects are equivalent, else ` + "`")))) + (((`false` + ("`" + `.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `)) + ("`" + (`Object` + "`"))) + ((` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n", + "/** Detect free variable ` + ("`" + `global`)) + ("`" + (` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n", + "var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of ` + "`"))))) + ((((`object` + ("`" + `.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n", + "var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `)) + ("`" + (`map` + "`"))) + ((`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n", + "var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of ` + ("`" + `object`)) + ("`" + (`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of ` + "`")))) + (((`object` + ("`" + `.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n", + "var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `)) + ("`" + (`key` + "`"))) + ((` of ` + ("`" + `object`)) + (("`" + `.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `) + ("`" + `undefined`)))))) + ((((("`" + (`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n", + "var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n", + "var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [` + "`")) + (`toStringTag` + ("`" + `](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `))) + (("`" + (`baseGetTag` + "`")) + (` which ignores ` + ("`" + `Symbol.toStringTag`)))) + ((("`" + (` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw ` + "`")) + (`toStringTag` + ("`" + `.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n", + "var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `))) + (("`" + (`lodash` + "`")) + ((` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of ` + "`") + (`object` + "`"))))) + ((((`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n", + "var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** ` + ("`" + `Object#toString`)) + ("`" + (` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the ` + "`"))) + ((`toStringTag` + ("`" + ` of `)) + ("`" + (`value` + "`")))) + (((`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the ` + ("`" + `toStringTag`)) + ("`" + (`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n", + "/**\n * Gets the value at ` + "`"))) + ((`key` + ("`" + ` of `)) + (("`" + `object`) + ("`" + `.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n", + "var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `))))))) + (((((("`" + (`path` + "`")) + (` exists on ` + ("`" + `object`))) + (("`" + (`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if `)))) + ((("`" + (`path` + "`")) + (` exists, else ` + ("`" + `false`))) + (("`" + (`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n", + "var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n", + "/**\n * Removes ` + "`")) + (`key` + ("`" + ` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `))))) + (((("`" + (`true` + "`")) + (` if the entry was removed, else ` + ("`" + `false`))) + (("`" + (`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n", + "var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for ` + "`")) + (`undefined` + ("`" + ` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `)))) + ((("`" + (`key` + "`")) + (`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n", + "var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for ` + ("`" + `key`))) + (("`" + (` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if an entry for ` + "`")))))) + (((((`key` + ("`" + ` exists, else `)) + ("`" + (`false` + "`"))) + ((`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n", + "var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for ` + ("`" + `undefined`)) + ("`" + (` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash ` + "`")))) + (((`key` + ("`" + ` to `)) + ("`" + (`value` + "`"))) + ((`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n", + "var Symbol = require('./_Symbol'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray');\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if ` + ("`" + `value`)) + (("`" + ` is a flattenable `) + ("`" + `arguments`))))) + (((("`" + (` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if `))) + (("`" + (`value` + "`")) + (` is flattenable, else ` + ("`" + `false`)))) + ((("`" + (`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nmodule.exports = isFlattenable;\n", + "/** Used as references for various ` + "`")) + (`Number` + ("`" + ` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `))) + (("`" + (`value` + "`")) + ((` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns ` + "`") + (`true` + "`")))))))) + (((((((` if ` + ("`" + `value`)) + ("`" + (` is a valid index, else ` + "`"))) + ((`false` + ("`" + `.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n", + "var eq = require('./eq'),\n isArrayLike = require('./isArrayLike'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`")))) + (((` if the arguments are from an iteratee call,\n * else ` + ("`" + `false`)) + ("`" + (`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nmodule.exports = isIterateeCall;\n", + "var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if ` + "`"))) + ((`value` + ("`" + ` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))))) + ((((` if ` + ("`" + `value`)) + ("`" + (` is a property name, else ` + "`"))) + ((`false` + ("`" + `.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n", + "/**\n * Checks if `)) + ("`" + (`value` + "`")))) + (((` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if ` + "`"))) + ((`value` + ("`" + ` is suitable, else `)) + (("`" + `false`) + ("`" + `.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n", + "var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `)))))) + ((((("`" + (`func` + "`")) + (` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`func` + ("`" + ` is masked, else `)))) + ((("`" + (`false` + "`")) + (`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n", + "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if ` + ("`" + `value`))) + (("`" + (` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if ` + "`"))))) + ((((`value` + ("`" + ` is a prototype, else `)) + ("`" + (`false` + "`"))) + ((`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n", + "var isObject = require('./isObject');\n\n/**\n * Checks if ` + ("`" + `value`)) + ("`" + (` is suitable for strict equality comparisons, i.e. ` + "`")))) + (((`===` + ("`" + `.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))) + ((` if ` + ("`" + `value`)) + (("`" + ` if suitable for strict\n * equality comparisons, else `) + ("`" + `false`))))))) + (((((("`" + (`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n", + "/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n", + "var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes ` + "`")) + (`key` + ("`" + ` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `))) + (("`" + (`true` + "`")) + (` if the entry was removed, else ` + ("`" + `false`)))) + ((("`" + (`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n", + "var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for ` + "`")) + (`key` + ("`" + `.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n", + "var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `))) + (("`" + (`key` + "`")) + ((` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns ` + "`") + (`true` + "`"))))) + ((((` if an entry for ` + ("`" + `key`)) + ("`" + (` exists, else ` + "`"))) + ((`false` + ("`" + `.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n", + "var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `)) + ("`" + (`key` + "`")))) + (((` to ` + ("`" + `value`)) + ("`" + (`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n", + "var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n", + "var getMapData = require('./_getMapData');\n\n/**\n * Removes ` + "`"))) + ((`key` + ("`" + ` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `)) + (("`" + `true`) + ("`" + ` if the entry was removed, else `)))))) + ((((("`" + (`false` + "`")) + (`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n", + "var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for ` + ("`" + `key`))) + (("`" + (`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n", + "var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for ` + "`")) + (`key` + ("`" + ` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `)))) + ((("`" + (`true` + "`")) + (` if an entry for ` + ("`" + `key`))) + (("`" + (` exists, else ` + "`")) + ((`false` + "`") + (`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n", + "var getMapData = require('./_getMapData');\n\n/**\n * Sets the map ` + "`"))))) + ((((`key` + ("`" + ` to `)) + ("`" + (`value` + "`"))) + ((`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n", + "/**\n * Converts ` + ("`" + `map`)) + ("`" + (` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n", + "/**\n * A specialized version of ` + "`")))) + (((`matchesProperty` + ("`" + ` for source values suitable\n * for strict equality comparisons, i.e. `)) + ("`" + (`===` + "`"))) + ((`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n", + "var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of ` + ("`" + `_.memoize`)) + (("`" + ` which clears the memoized function's\n * cache when it exceeds `) + ("`" + `MAX_MEMOIZE_SIZE`)))))))))) + ((((((((("`" + (`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n", + "var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n", + "var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other ` + "`")) + (`lodash` + ("`" + ` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n", + "var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `))) + (("`" + (`exports` + "`")) + (`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable ` + ("`" + `module`)))) + ((("`" + (`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension ` + "`")) + (`module.exports` + ("`" + `. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `))) + (("`" + (`process` + "`")) + (` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use ` + ("`" + `util.types`))))) + (((("`" + (` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy ` + "`")) + (`process.binding('util')` + ("`" + ` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n", + "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`))) + (("`" + (`toStringTag` + "`")) + (`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts ` + ("`" + `value`)))) + ((("`" + (` to a string using ` + "`")) + (`Object.prototype.toString` + ("`" + `.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n", + "/**\n * Creates a unary function that invokes `))) + (("`" + (`func` + "`")) + ((` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n", + "var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other ` + "`") + (`lodash` + "`")))))) + (((((` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of ` + ("`" + `baseRest`)) + ("`" + (` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n", + "var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable ` + "`"))) + ((`self` + ("`" + `. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n", + "/** Used to stand-in for `)) + ("`" + (`undefined` + "`")))) + (((` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds ` + ("`" + `value`)) + ("`" + (` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n", + "/**\n * Checks if ` + "`"))) + ((`value` + ("`" + ` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `)) + (("`" + `true`) + ("`" + ` if `))))) + (((("`" + (`value` + "`")) + (` is found, else ` + ("`" + `false`))) + (("`" + (`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n", + "/**\n * Converts ` + "`")) + (`set` + ("`" + ` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n", + "var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `)))) + ((("`" + (`toString` + "`")) + (` method of ` + ("`" + `func`))) + (("`" + (` to return ` + "`")) + ((`string` + "`") + (`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The ` + "`"))))))) + ((((((`toString` + ("`" + ` result.\n * @returns {Function} Returns `)) + ("`" + (`func` + "`"))) + ((`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n", + "/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other ` + ("`" + `lodash`)) + ("`" + (` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke ` + "`")))) + (((`identity` + ("`" + ` instead\n * of `)) + ("`" + (`func` + "`"))) + ((` when it's called ` + ("`" + `HOT_COUNT`)) + ("`" + (` or more times in ` + "`"))))) + ((((`HOT_SPAN` + ("`" + `\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n", + "var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n", + "/**\n * Removes `)) + ("`" + (`key` + "`"))) + ((` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if the entry was removed, else ` + "`")))) + (((`false` + ("`" + `.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n", + "/**\n * Gets the stack value for `)) + ("`" + (`key` + "`"))) + ((`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n", + "/**\n * Checks if a stack value for ` + ("`" + `key`)) + (("`" + ` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `) + ("`" + `true`)))))) + ((((("`" + (` if an entry for ` + "`")) + (`key` + ("`" + ` exists, else `))) + (("`" + (`false` + "`")) + (`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n", + "var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack ` + ("`" + `key`)))) + ((("`" + (` to ` + "`")) + (`value` + ("`" + `.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n", + "/**\n * A specialized version of `))) + (("`" + (`_.indexOf` + "`")) + ((` which performs strict equality\n * comparisons of values, i.e. ` + "`") + (`===` + "`"))))) + ((((`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else ` + ("`" + `-1`)) + ("`" + (`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = strictIndexOf;\n", + "var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts ` + "`"))) + ((`string` + ("`" + ` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n", + "var isSymbol = require('./isSymbol');\n\n/** Used as references for various `)) + ("`" + (`Number` + "`")))) + (((` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts ` + ("`" + `value`)) + ("`" + (` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n", + "/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts ` + "`"))) + ((`func` + ("`" + ` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n", + "/**\n * Creates a function that returns `)) + (("`" + `value`) + ("`" + `.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n", + "var isObject = require('./isObject'),\n now = require('./now'),\n toNumber = require('./toNumber');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `)))))))) + ((((((("`" + (`lodash` + "`")) + (` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking ` + ("`" + `func`))) + (("`" + (` until after ` + "`")) + (`wait` + ("`" + `\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `)))) + ((("`" + (`cancel` + "`")) + (` method to cancel\n * delayed ` + ("`" + `func`))) + (("`" + (` invocations and a ` + "`")) + (`flush` + ("`" + ` method to immediately invoke them.\n * Provide `))))) + (((("`" + (`options` + "`")) + (` to indicate whether ` + ("`" + `func`))) + (("`" + (` should be invoked on the\n * leading and/or trailing edge of the ` + "`")) + (`wait` + ("`" + ` timeout. The `)))) + ((("`" + (`func` + "`")) + (` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last ` + ("`" + `func`))) + (("`" + (`\n * invocation.\n *\n * **Note:** If ` + "`")) + ((`leading` + "`") + (` and ` + "`")))))) + (((((`trailing` + ("`" + ` options are `)) + ("`" + (`true` + "`"))) + ((`, ` + ("`" + `func`)) + ("`" + (` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the ` + "`")))) + (((`wait` + ("`" + ` timeout.\n *\n * If `)) + ("`" + (`wait` + "`"))) + ((` is ` + ("`" + `0`)) + (("`" + ` and `) + ("`" + `leading`))))) + (((("`" + (` is ` + "`")) + (`false` + ("`" + `, `))) + (("`" + (`func` + "`")) + (` invocation is deferred\n * until to the next tick, similar to ` + ("`" + `setTimeout`)))) + ((("`" + (` with a timeout of ` + "`")) + (`0` + ("`" + `.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `))) + (("`" + (`_.debounce` + "`")) + ((` and ` + "`") + (`_.throttle` + "`"))))))) + ((((((`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time ` + ("`" + `func`)) + ("`" + (` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke ` + "`"))) + ((`sendMail` + ("`" + ` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `)) + ("`" + (`batchLog` + "`")))) + (((` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any ` + ("`" + `maxWait`)) + ("`" + (` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the ` + "`"))) + ((`maxWait` + ("`" + ` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `)) + (("`" + `lastArgs`) + ("`" + ` which means `))))) + (((("`" + (`func` + "`")) + (` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nmodule.exports = debounce;\n", + "/**\n * Performs a\n * [` + ("`" + `SameValueZero`))) + (("`" + (`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if the values are equivalent, else `)))) + ((("`" + (`false` + "`")) + (`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n", + "var arrayEvery = require('./_arrayEvery'),\n baseEvery = require('./_baseEvery'),\n baseIteratee = require('./_baseIteratee'),\n isArray = require('./isArray'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Checks if ` + ("`" + `predicate`))) + (("`" + (` returns truthy for **all** elements of ` + "`")) + ((`collection` + "`") + (`.\n * Iteration is stopped once ` + "`")))))) + (((((`predicate` + ("`" + ` returns falsey. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * **Note:** This method returns `)) + ("`" + (`true` + "`"))) + ((` for\n * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n * elements of empty collections.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like ` + ("`" + `_.map`)) + ("`" + (`.\n * @returns {boolean} Returns ` + "`")))) + (((`true` + ("`" + ` if all elements pass the predicate check,\n * else `)) + ("`" + (`false` + "`"))) + ((`.\n * @example\n *\n * _.every([true, 1, null, 'yes'], Boolean);\n * // => false\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * // The ` + ("`" + `_.matches`)) + (("`" + ` iteratee shorthand.\n * _.every(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `) + ("`" + `_.matchesProperty`))))) + (((("`" + (` iteratee shorthand.\n * _.every(users, ['active', false]);\n * // => true\n *\n * // The ` + "`")) + (`_.property` + ("`" + ` iteratee shorthand.\n * _.every(users, 'active');\n * // => false\n */\nfunction every(collection, predicate, guard) {\n var func = isArray(collection) ? arrayEvery : baseEvery;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = every;\n", + "var arrayFilter = require('./_arrayFilter'),\n baseFilter = require('./_baseFilter'),\n baseIteratee = require('./_baseIteratee'),\n isArray = require('./isArray');\n\n/**\n * Iterates over elements of `))) + (("`" + (`collection` + "`")) + (`, returning an array of all elements\n * ` + ("`" + `predicate`)))) + ((("`" + (` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike ` + "`")) + (`_.remove` + ("`" + `, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `))) + (("`" + (`_.matches` + "`")) + ((` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The ` + "`") + (`_.matchesProperty` + "`"))))))))) + ((((((((` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The ` + ("`" + `_.property`)) + ("`" + (` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n */\nfunction filter(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = filter;\n", + "var createFind = require('./_createFind'),\n findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of ` + "`"))) + ((`collection` + ("`" + `, returning the first element\n * `)) + ("`" + (`predicate` + "`")))) + (((` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else ` + ("`" + `undefined`)) + ("`" + (`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The ` + "`"))) + ((`_.matches` + ("`" + ` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `)) + ("`" + (`_.matchesProperty` + "`"))))) + ((((` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The ` + ("`" + `_.property`)) + ("`" + (` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n", + "var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other ` + "`"))) + ((`lodash` + ("`" + ` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `)) + ("`" + (`_.find` + "`")))) + (((` except that it returns the index of the first\n * element ` + ("`" + `predicate`)) + ("`" + (` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else ` + "`"))) + ((`-1` + ("`" + `.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `)) + (("`" + `_.matches`) + ("`" + ` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `)))))) + ((((("`" + (`_.matchesProperty` + "`")) + (` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The ` + ("`" + `_.property`))) + (("`" + (` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n", + "var baseFlatten = require('./_baseFlatten'),\n map = require('./map');\n\n/**\n * Creates a flattened array of values by running each element in ` + "`")) + (`collection` + ("`" + `\n * thru `)))) + ((("`" + (`iteratee` + "`")) + (` and flattening the mapped results. The iteratee is invoked\n * with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [n, n];\n * }\n *\n * _.flatMap([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\nfunction flatMap(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), 1);\n}\n\nmodule.exports = flatMap;\n", + "var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at ` + ("`" + `path`))) + (("`" + (` of ` + "`")) + ((`object` + "`") + (`. If the resolved value is\n * ` + "`"))))) + ((((`undefined` + ("`" + `, the `)) + ("`" + (`defaultValue` + "`"))) + ((` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for ` + ("`" + `undefined`)) + ("`" + (` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n", + "var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if ` + "`")))) + (((`path` + ("`" + ` is a direct or inherited property of `)) + ("`" + (`object` + "`"))) + ((`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + (("`" + ` if `) + ("`" + `path`))))))) + (((((("`" + (` exists, else ` + "`")) + (`false` + ("`" + `.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n", + "/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `))) + (("`" + (`value` + "`")) + (`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n", + "var arrayMap = require('./_arrayMap'),\n baseIntersection = require('./_baseIntersection'),\n baseRest = require('./_baseRest'),\n castArrayLikeObject = require('./_castArrayLikeObject');\n\n/**\n * Creates an array of unique values that are included in all given arrays\n * using [` + ("`" + `SameValueZero`)))) + ((("`" + (`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [2, 3]);\n * // => [2]\n */\nvar intersection = baseRest(function(arrays) {\n var mapped = arrayMap(arrays, castArrayLikeObject);\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped)\n : [];\n});\n\nmodule.exports = intersection;\n", + "var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is likely an `))) + (("`" + (`arguments` + "`")) + (` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))))) + (((("`" + (` if ` + "`")) + (`value` + ("`" + ` is an `))) + (("`" + (`arguments` + "`")) + (` object,\n * else ` + ("`" + `false`)))) + ((("`" + (`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n", + "/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is classified as an `))) + (("`" + (`Array` + "`")) + ((` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`") + (`true` + "`")))))) + (((((` if ` + ("`" + `value`)) + ("`" + (` is an array, else ` + "`"))) + ((`false` + ("`" + `.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n", + "var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `)) + ("`" + (`value` + "`")))) + (((` is array-like. A value is considered array-like if it's\n * not a function and has a ` + ("`" + `value.length`)) + ("`" + (` that's an integer greater than or\n * equal to ` + "`"))) + ((`0` + ("`" + ` and less than or equal to `)) + (("`" + `Number.MAX_SAFE_INTEGER`) + ("`" + `.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `))))) + (((("`" + (`true` + "`")) + (` if ` + ("`" + `value`))) + (("`" + (` is array-like, else ` + "`")) + (`false` + ("`" + `.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n", + "var isArrayLike = require('./isArrayLike'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `)))) + ((("`" + (`_.isArrayLike` + "`")) + (` except that it also checks if ` + ("`" + `value`))) + (("`" + (`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if ` + "`")))))))) + (((((((`value` + ("`" + ` is an array-like object,\n * else `)) + ("`" + (`false` + "`"))) + ((`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n", + "var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable ` + ("`" + `exports`)) + ("`" + (`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable ` + "`")))) + (((`module` + ("`" + `. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `)) + ("`" + (`module.exports` + "`"))) + ((`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other ` + ("`" + `lodash`)) + ("`" + (` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if ` + "`"))))) + ((((`value` + ("`" + ` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))) + ((` if ` + ("`" + `value`)) + ("`" + (` is a buffer, else ` + "`")))) + (((`false` + ("`" + `.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n", + "var baseIsEqual = require('./_baseIsEqual');\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `)) + ("`" + (`Object` + "`"))) + ((` objects, regexes,\n * sets, strings, symbols, and typed arrays. ` + ("`" + `Object`)) + (("`" + ` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `) + ("`" + `===`)))))) + ((((("`" + (`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns ` + "`")) + (`true` + ("`" + ` if the values are equivalent, else `))) + (("`" + (`false` + "`")) + (`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\nmodule.exports = isEqual;\n", + "var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** ` + ("`" + `Object#toString`)))) + ((("`" + (` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is classified as a `))) + (("`" + (`Function` + "`")) + ((` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`") + (`true` + "`"))))) + ((((` if ` + ("`" + `value`)) + ("`" + (` is a function, else ` + "`"))) + ((`false` + ("`" + `.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `)) + ("`" + (`Object#toString` + "`")))) + (((` avoids issues with the ` + ("`" + `typeof`)) + ("`" + (` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n", + "/** Used as references for various ` + "`"))) + ((`Number` + ("`" + ` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `)) + (("`" + `value`) + ("`" + ` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`))))))) + (((((("`" + (`ToLength` + "`")) + (`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`value` + ("`" + ` is a valid length, else `)))) + ((("`" + (`false` + "`")) + (`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n", + "var isNumber = require('./isNumber');\n\n/**\n * Checks if ` + ("`" + `value`))) + (("`" + (` is ` + "`")) + ((`NaN` + "`") + (`.\n *\n * **Note:** This method is based on\n * [` + "`"))))) + ((((`Number.isNaN` + ("`" + `](https://mdn.io/Number/isNaN) and is not the same as\n * global [`)) + ("`" + (`isNaN` + "`"))) + ((`](https://mdn.io/isNaN) which returns ` + ("`" + `true`)) + ("`" + (` for\n * ` + "`")))) + (((`undefined` + ("`" + ` and other non-number values.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `)) + ("`" + (`true` + "`"))) + ((` if ` + ("`" + `value`)) + (("`" + ` is `) + ("`" + `NaN`)))))) + ((((("`" + (`, else ` + "`")) + (`false` + ("`" + `.\n * @example\n *\n * _.isNaN(NaN);\n * // => true\n *\n * _.isNaN(new Number(NaN));\n * // => true\n *\n * isNaN(undefined);\n * // => true\n *\n * _.isNaN(undefined);\n * // => false\n */\nfunction isNaN(value) {\n // An `))) + (("`" + (`NaN` + "`")) + (` primitive is the only value that is not equal to itself.\n // Perform the ` + ("`" + `toStringTag`)))) + ((("`" + (` check first to avoid errors with some\n // ActiveX objects in IE.\n return isNumber(value) && value != +value;\n}\n\nmodule.exports = isNaN;\n", + "/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is `))) + (("`" + (`null` + "`")) + ((` or ` + "`") + (`undefined` + "`"))))) + ((((`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + ("`" + (` if ` + "`"))) + ((`value` + ("`" + ` is nullish, else `)) + ("`" + (`false` + "`")))) + (((`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\nfunction isNil(value) {\n return value == null;\n}\n\nmodule.exports = isNil;\n", + "var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** ` + ("`" + `Object#toString`)) + ("`" + (` result references. */\nvar numberTag = '[object Number]';\n\n/**\n * Checks if ` + "`"))) + ((`value` + ("`" + ` is classified as a `)) + (("`" + `Number`) + ("`" + ` primitive or object.\n *\n * **Note:** To exclude `))))))))))) + (((((((((("`" + (`Infinity` + "`")) + (`, ` + ("`" + `-Infinity`))) + (("`" + (`, and ` + "`")) + (`NaN` + ("`" + `, which are\n * classified as numbers, use the `)))) + ((("`" + (`_.isFinite` + "`")) + (` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`value` + ("`" + ` is a number, else `))))) + (((("`" + (`false` + "`")) + (`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\nfunction isNumber(value) {\n return typeof value == 'number' ||\n (isObjectLike(value) && baseGetTag(value) == numberTag);\n}\n\nmodule.exports = isNumber;\n", + "/**\n * Checks if ` + ("`" + `value`))) + (("`" + (` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of ` + "`")) + (`Object` + ("`" + `. (e.g. arrays, functions, objects, regexes, `)))) + ((("`" + (`new Number(0)` + "`")) + (`, and ` + ("`" + `new String('')`))) + (("`" + (`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if ` + "`")))))) + (((((`value` + ("`" + ` is an object, else `)) + ("`" + (`false` + "`"))) + ((`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n", + "/**\n * Checks if ` + ("`" + `value`)) + ("`" + (` is object-like. A value is object-like if it's not ` + "`")))) + (((`null` + ("`" + `\n * and has a `)) + ("`" + (`typeof` + "`"))) + ((` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`)) + (("`" + ` if `) + ("`" + `value`))))) + (((("`" + (` is object-like, else ` + "`")) + (`false` + ("`" + `.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n", + "var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `))) + (("`" + (`Object#toString` + "`")) + (` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the ` + ("`" + `Object`)))) + ((("`" + (` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if ` + "`")) + (`value` + ("`" + ` is a plain object, that is, an object created by the\n * `))) + (("`" + (`Object` + "`")) + ((` constructor or one with a ` + "`") + (`[[Prototype]]` + "`"))))))) + ((((((` of ` + ("`" + `null`)) + ("`" + (`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`"))) + ((`true` + ("`" + ` if `)) + ("`" + (`value` + "`")))) + (((` is a plain object, else ` + ("`" + `false`)) + ("`" + (`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n", + "var baseGetTag = require('./_baseGetTag'),\n isArray = require('./isArray'),\n isObjectLike = require('./isObjectLike');\n\n/** ` + "`"))) + ((`Object#toString` + ("`" + ` result references. */\nvar stringTag = '[object String]';\n\n/**\n * Checks if `)) + ("`" + (`value` + "`"))))) + ((((` is classified as a ` + ("`" + `String`)) + ("`" + (` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`"))) + ((`true` + ("`" + ` if `)) + ("`" + (`value` + "`")))) + (((` is a string, else ` + ("`" + `false`)) + ("`" + (`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n}\n\nmodule.exports = isString;\n", + "var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** ` + "`"))) + ((`Object#toString` + ("`" + ` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `)) + (("`" + `value`) + ("`" + ` is classified as a `)))))) + ((((("`" + (`Symbol` + "`")) + (` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + ("`" + `true`))) + (("`" + (` if ` + "`")) + (`value` + ("`" + ` is a symbol, else `)))) + ((("`" + (`false` + "`")) + (`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n", + "var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if ` + ("`" + `value`))) + (("`" + (` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns ` + "`")) + ((`true` + "`") + (` if ` + "`"))))) + ((((`value` + ("`" + ` is a typed array, else `)) + ("`" + (`false` + "`"))) + ((`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n", + "var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of ` + ("`" + `object`)) + ("`" + (`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n", + "/**\n * Gets the last element of ` + "`")))) + (((`array` + ("`" + `.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `)) + ("`" + (`array` + "`"))) + ((`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n}\n\nmodule.exports = last;\n", + "var arrayMap = require('./_arrayMap'),\n baseIteratee = require('./_baseIteratee'),\n baseMap = require('./_baseMap'),\n isArray = require('./isArray');\n\n/**\n * Creates an array of values by running each element in ` + ("`" + `collection`)) + (("`" + ` thru\n * `) + ("`" + `iteratee`)))))))) + ((((((("`" + (`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * ` + "`")) + (`_.every` + ("`" + `, `))) + (("`" + (`_.filter` + "`")) + (`, ` + ("`" + `_.map`)))) + ((("`" + (`, ` + "`")) + (`_.mapValues` + ("`" + `, `))) + (("`" + (`_.reject` + "`")) + (`, and ` + ("`" + `_.some`))))) + (((("`" + (`.\n *\n * The guarded methods are:\n * ` + "`")) + (`ary` + ("`" + `, `))) + (("`" + (`chunk` + "`")) + (`, ` + ("`" + `curry`)))) + ((("`" + (`, ` + "`")) + (`curryRight` + ("`" + `, `))) + (("`" + (`drop` + "`")) + ((`, ` + "`") + (`dropRight` + "`")))))) + (((((`, ` + ("`" + `every`)) + ("`" + (`,\n * ` + "`"))) + ((`fill` + ("`" + `, `)) + ("`" + (`invert` + "`")))) + (((`, ` + ("`" + `parseInt`)) + ("`" + (`, ` + "`"))) + ((`random` + ("`" + `, `)) + (("`" + `range`) + ("`" + `, `))))) + (((("`" + (`rangeRight` + "`")) + (`, ` + ("`" + `repeat`))) + (("`" + (`,\n * ` + "`")) + (`sampleSize` + ("`" + `, `)))) + ((("`" + (`slice` + "`")) + (`, ` + ("`" + `some`))) + (("`" + (`, ` + "`")) + ((`sortBy` + "`") + (`, ` + "`"))))))) + ((((((`split` + ("`" + `, `)) + ("`" + (`take` + "`"))) + ((`, ` + ("`" + `takeRight`)) + ("`" + (`,\n * ` + "`")))) + (((`template` + ("`" + `, `)) + ("`" + (`trim` + "`"))) + ((`, ` + ("`" + `trimEnd`)) + (("`" + `, `) + ("`" + `trimStart`))))) + (((("`" + (`, and ` + "`")) + (`words` + ("`" + `\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n * { 'user': 'barney' },\n * { 'user': 'fred' }\n * ];\n *\n * // The `))) + (("`" + (`_.property` + "`")) + (` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\nfunction map(collection, iteratee) {\n var func = isArray(collection) ? arrayMap : baseMap;\n return func(collection, baseIteratee(iteratee, 3));\n}\n\nmodule.exports = map;\n", + "var baseAssignValue = require('./_baseAssignValue'),\n baseForOwn = require('./_baseForOwn'),\n baseIteratee = require('./_baseIteratee');\n\n/**\n * Creates an object with the same keys as ` + ("`" + `object`)))) + ((("`" + (` and values generated\n * by running each own enumerable string keyed property of ` + "`")) + (`object` + ("`" + ` thru\n * `))) + (("`" + (`iteratee` + "`")) + ((`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n * 'fred': { 'user': 'fred', 'age': 40 },\n * 'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The ` + "`") + (`_.property` + "`")))))) + (((((` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\nfunction mapValues(object, iteratee) {\n var result = {};\n iteratee = baseIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, key, iteratee(value, key, object));\n });\n return result;\n}\n\nmodule.exports = mapValues;\n", + "var baseExtremum = require('./_baseExtremum'),\n baseGt = require('./_baseGt'),\n identity = require('./identity');\n\n/**\n * Computes the maximum value of ` + ("`" + `array`)) + ("`" + (`. If ` + "`"))) + ((`array` + ("`" + ` is empty or falsey,\n * `)) + ("`" + (`undefined` + "`")))) + (((` is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {*} Returns the maximum value.\n * @example\n *\n * _.max([4, 2, 8, 6]);\n * // => 8\n *\n * _.max([]);\n * // => undefined\n */\nfunction max(array) {\n return (array && array.length)\n ? baseExtremum(array, identity, baseGt)\n : undefined;\n}\n\nmodule.exports = max;\n", + "var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of ` + ("`" + `func`)) + ("`" + (`. If ` + "`"))) + ((`resolver` + ("`" + ` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `)) + (("`" + `func`) + ("`" + `\n * is invoked with the `))))) + (((("`" + (`this` + "`")) + (` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the ` + ("`" + `cache`))) + (("`" + (` property on the memoized\n * function. Its creation may be customized by replacing the ` + "`")) + (`_.memoize.Cache` + ("`" + `\n * constructor with one whose instances implement the\n * [`)))) + ((("`" + (`Map` + "`")) + (`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of ` + ("`" + `clear`))) + (("`" + (`, ` + "`")) + ((`delete` + "`") + (`, ` + "`"))))))))) + ((((((((`get` + ("`" + `, `)) + ("`" + (`has` + "`"))) + ((`, and ` + ("`" + `set`)) + ("`" + (`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace ` + "`")))) + (((`_.memoize.Cache` + ("`" + `.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `)) + ("`" + (`MapCache` + "`"))) + ((`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n", + "var baseExtremum = require('./_baseExtremum'),\n baseLt = require('./_baseLt'),\n identity = require('./identity');\n\n/**\n * Computes the minimum value of ` + ("`" + `array`)) + ("`" + (`. If ` + "`"))))) + ((((`array` + ("`" + ` is empty or falsey,\n * `)) + ("`" + (`undefined` + "`"))) + ((` is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {*} Returns the minimum value.\n * @example\n *\n * _.min([4, 2, 8, 6]);\n * // => 2\n *\n * _.min([]);\n * // => undefined\n */\nfunction min(array) {\n return (array && array.length)\n ? baseExtremum(array, identity, baseLt)\n : undefined;\n}\n\nmodule.exports = min;\n", + "/**\n * This method returns ` + ("`" + `undefined`)) + ("`" + (`.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Util\n * @example\n *\n * _.times(2, _.noop);\n * // => [undefined, undefined]\n */\nfunction noop() {\n // No operation performed.\n}\n\nmodule.exports = noop;\n", + "var root = require('./_root');\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\nmodule.exports = now;\n", + "var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at ` + "`")))) + (((`path` + ("`" + ` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n", + "var createRange = require('./_createRange');\n\n/**\n * Creates an array of numbers (positive and/or negative) progressing from\n * `)) + ("`" + (`start` + "`"))) + ((` up to, but not including, ` + ("`" + `end`)) + (("`" + `. A step of `) + ("`" + `-1`)))))) + ((((("`" + (` is used if a negative\n * ` + "`")) + (`start` + ("`" + ` is specified without an `))) + (("`" + (`end` + "`")) + (` or ` + ("`" + `step`)))) + ((("`" + (`. If ` + "`")) + (`end` + ("`" + ` is not specified,\n * it's set to `))) + (("`" + (`start` + "`")) + ((` with ` + "`") + (`start` + "`"))))) + ((((` then set to ` + ("`" + `0`)) + ("`" + (`.\n *\n * **Note:** JavaScript follows the IEEE-754 standard for resolving\n * floating-point values which can produce unexpected results.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @param {number} [step=1] The value to increment or decrement by.\n * @returns {Array} Returns the range of numbers.\n * @see _.inRange, _.rangeRight\n * @example\n *\n * _.range(4);\n * // => [0, 1, 2, 3]\n *\n * _.range(-4);\n * // => [0, -1, -2, -3]\n *\n * _.range(1, 5);\n * // => [1, 2, 3, 4]\n *\n * _.range(0, 20, 5);\n * // => [0, 5, 10, 15]\n *\n * _.range(0, -4, -1);\n * // => [0, -1, -2, -3]\n *\n * _.range(1, 4, 0);\n * // => [1, 1, 1]\n *\n * _.range(0);\n * // => []\n */\nvar range = createRange();\n\nmodule.exports = range;\n", + "var arraySome = require('./_arraySome'),\n baseIteratee = require('./_baseIteratee'),\n baseSome = require('./_baseSome'),\n isArray = require('./isArray'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Checks if ` + "`"))) + ((`predicate` + ("`" + ` returns truthy for **any** element of `)) + ("`" + (`collection` + "`")))) + (((`.\n * Iteration is stopped once ` + ("`" + `predicate`)) + ("`" + (` returns truthy. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like ` + "`"))) + ((`_.map` + ("`" + `.\n * @returns {boolean} Returns `)) + (("`" + `true`) + ("`" + ` if any element passes the predicate check,\n * else `))))))) + (((((("`" + (`false` + "`")) + (`.\n * @example\n *\n * _.some([null, 0, 'yes', false], Boolean);\n * // => true\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false }\n * ];\n *\n * // The ` + ("`" + `_.matches`))) + (("`" + (` iteratee shorthand.\n * _.some(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The ` + "`")) + (`_.matchesProperty` + ("`" + ` iteratee shorthand.\n * _.some(users, ['active', false]);\n * // => true\n *\n * // The `)))) + ((("`" + (`_.property` + "`")) + (` iteratee shorthand.\n * _.some(users, 'active');\n * // => true\n */\nfunction some(collection, predicate, guard) {\n var func = isArray(collection) ? arraySome : baseSome;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, baseIteratee(predicate, 3));\n}\n\nmodule.exports = some;\n", + "var baseFlatten = require('./_baseFlatten'),\n baseOrderBy = require('./_baseOrderBy'),\n baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]\n */\nvar sortBy = baseRest(function(collection, iteratees) {\n if (collection == null) {\n return [];\n }\n var length = iteratees.length;\n if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n iteratees = [];\n } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n iteratees = [iteratees[0]];\n }\n return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n});\n\nmodule.exports = sortBy;\n", + "/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n", + "/**\n * This method returns ` + ("`" + `false`))) + (("`" + (`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns ` + "`")) + (`false` + ("`" + `.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n", + "var debounce = require('./debounce'),\n isObject = require('./isObject');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a throttled function that only invokes `))))) + (((("`" + (`func` + "`")) + (` at most once per\n * every ` + ("`" + `wait`))) + (("`" + (` milliseconds. The throttled function comes with a ` + "`")) + (`cancel` + ("`" + `\n * method to cancel delayed `)))) + ((("`" + (`func` + "`")) + (` invocations and a ` + ("`" + `flush`))) + (("`" + (` method to\n * immediately invoke them. Provide ` + "`")) + ((`options` + "`") + (` to indicate whether ` + "`")))))) + (((((`func` + ("`" + `\n * should be invoked on the leading and/or trailing edge of the `)) + ("`" + (`wait` + "`"))) + ((`\n * timeout. The ` + ("`" + `func`)) + ("`" + (` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last ` + "`")))) + (((`func` + ("`" + ` invocation.\n *\n * **Note:** If `)) + ("`" + (`leading` + "`"))) + ((` and ` + ("`" + `trailing`)) + (("`" + ` options are `) + ("`" + `true`))))) + (((("`" + (`, ` + "`")) + (`func` + ("`" + ` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `))) + (("`" + (`wait` + "`")) + (` timeout.\n *\n * If ` + ("`" + `wait`)))) + ((("`" + (` is ` + "`")) + (`0` + ("`" + ` and `))) + (("`" + (`leading` + "`")) + ((` is ` + "`") + (`false` + "`")))))))) + (((((((`, ` + ("`" + `func`)) + ("`" + (` invocation is deferred\n * until to the next tick, similar to ` + "`"))) + ((`setTimeout` + ("`" + ` with a timeout of `)) + ("`" + (`0` + "`")))) + (((`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between ` + ("`" + `_.throttle`)) + ("`" + (` and ` + "`"))) + ((`_.debounce` + ("`" + `.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `)) + ("`" + (`renewToken` + "`"))))) + ((((` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n}\n\nmodule.exports = throttle;\n", + "var toNumber = require('./toNumber');\n\n/** Used as references for various ` + ("`" + `Number`)) + ("`" + (` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts ` + "`"))) + ((`value` + ("`" + ` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n", + "var toFinite = require('./toFinite');\n\n/**\n * Converts `)) + ("`" + (`value` + "`")))) + (((` to an integer.\n *\n * **Note:** This method is loosely based on\n * [` + ("`" + `ToInteger`)) + ("`" + (`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n", + "var isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various ` + "`"))) + ((`Number` + ("`" + ` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `)) + (("`" + `root`) + ("`" + `. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `)))))) + ((((("`" + (`value` + "`")) + (` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n", + "var baseToString = require('./_baseToString');\n\n/**\n * Converts ` + ("`" + `value`))) + (("`" + (` to a string. An empty string is returned for ` + "`")) + (`null` + ("`" + `\n * and `)))) + ((("`" + (`undefined` + "`")) + (` values. The sign of ` + ("`" + `-0`))) + (("`" + (` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n", + "var baseIteratee = require('./_baseIteratee'),\n baseUniq = require('./_baseUniq');\n\n/**\n * This method is like ` + "`")) + ((`_.uniq` + "`") + (` except that it accepts ` + "`"))))) + ((((`iteratee` + ("`" + ` which is\n * invoked for each element in `)) + ("`" + (`array` + "`"))) + ((` to generate the criterion by which\n * uniqueness is computed. The order of result values is determined by the\n * order they occur in the array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The ` + ("`" + `_.property`)) + ("`" + (` iteratee shorthand.\n * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\nfunction uniqBy(array, iteratee) {\n return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];\n}\n\nmodule.exports = uniqBy;\n", + "var Mexp=require('./postfix_evaluator.js');\r\nMexp.prototype.formulaEval = function () {\r\n\t\"use strict\";\r\n\tvar stack=[],pop1,pop2,pop3;\r\n\tvar disp=[];\r\n\tvar temp='';\r\n\tvar arr=this.value;\r\n\tfor(var i=0;i\"+pop2.value+\"\"+arr[i].show+\"\"+pop1.value+\"\",type:10});\r\n\t\t\telse disp.push({value:(pop2.type!=1?\"(\":\"\")+pop2.value+(pop2.type!=1?\")\":\"\")+\"\"+pop1.value+\"\",type:1});\r\n\t\t}\r\n\t\telse if(arr[i].type===2||arr[i].type===9){\r\n\t\t\tpop1=disp.pop();\r\n\t\t\tpop2=disp.pop();\r\n\t\t\tdisp.push({value:(pop2.type!=1?\"(\":\"\")+pop2.value+(pop2.type!=1?\")\":\"\")+arr[i].show+(pop1.type!=1?\"(\":\"\")+pop1.value+(pop1.type!=1?\")\":\"\"),type:arr[i].type});\r\n\t\t}\r\n\t\telse if(arr[i].type===12){\r\n\t\t\tpop1=disp.pop();\r\n\t\t\tpop2=disp.pop();\r\n\t\t\tpop3=disp.pop();\r\n\t\t\tdisp.push({value:arr[i].show+\"(\"+pop3.value+\",\"+pop2.value+\",\"+pop1.value+\")\",type:12});\r\n\t\t}\r\n\t}\r\n\treturn disp[0].value;\r\n};\r\nmodule.exports=Mexp;", + "var Mexp=require('./math_function.js');\r\n\tfunction inc(arr,val){\r\n\t\tfor(var i=0;i(newAr.length-2)?newAr.length-1:inpStr.length-i);x>0;x--){\r\n\t\t\t\tfor(y=0;yprep)stack.push(elem);\r\n\t\t\t\telse {\r\n\t\t\t\t\twhile(prep>=pre&&!flag||flag&&pre1) {\r\n\t\tthrow(new Mexp.exception(\"Uncaught Syntax error\"));\r\n\t}\r\n\treturn stack[0].value>1000000000000000?\"Infinity\":parseFloat(stack[0].value.toFixed(15));\r\n};\r\nMexp.eval=function(str,tokens,obj){\r\n\tif (typeof tokens===\"undefined\") {\r\n\t\treturn this.lex(str).toPostfix().postfixEval();\r\n\t}\r\n\telse if (typeof obj===\"undefined\") {\r\n\t\tif (typeof tokens.length!==\"undefined\") \r\n\t\t\treturn this.lex(str,tokens).toPostfix().postfixEval();\r\n\t\telse\r\n\t\t\treturn this.lex(str).toPostfix().postfixEval(tokens);\r\n\t}\r\n\telse\r\n\t\treturn this.lex(str,tokens).toPostfix().postfixEval(obj);\r\n};\r\nmodule.exports=Mexp;", + "/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n", + "// Generated by CoffeeScript 1.12.2\n(function() {\n var getNanoSeconds, hrtime, loadTime, moduleLoadTime, nodeLoadTime, upTime;\n\n if ((typeof performance !== \"undefined\" && performance !== null) && performance.now) {\n module.exports = function() {\n return performance.now();\n };\n } else if ((typeof process !== \"undefined\" && process !== null) && process.hrtime) {\n module.exports = function() {\n return (getNanoSeconds() - nodeLoadTime) / 1e6;\n };\n hrtime = process.hrtime;\n getNanoSeconds = function() {\n var hr;\n hr = hrtime();\n return hr[0] * 1e9 + hr[1];\n };\n moduleLoadTime = getNanoSeconds();\n upTime = process.uptime() * 1e9;\n nodeLoadTime = moduleLoadTime - upTime;\n } else if (Date.now) {\n module.exports = function() {\n return Date.now() - loadTime;\n };\n loadTime = Date.now();\n } else {\n module.exports = function() {\n return new Date().getTime() - loadTime;\n };\n loadTime = new Date().getTime();\n }\n\n}).call(this);\n\n//# sourceMappingURL=performance-now.js.map\n", + "// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the ` + "`")))) + (((`prop-types` + ("`" + ` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `)) + ("`" + (`./factoryWithTypeCheckers.js` + "`"))) + ((`.\n var ReactPropTypes = {\n array: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactIs = require('react-is');\n\n // By explicitly using ` + ("`" + `prop-types`)) + (("`" + ` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n // By explicitly using `) + ("`" + `prop-types`))))))) + (((((("`" + (` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n", + "var now = require('performance-now')\n , root = typeof window === 'undefined' ? global : window\n , vendors = ['moz', 'webkit']\n , suffix = 'AnimationFrame'\n , raf = root['request' + suffix]\n , caf = root['cancel' + suffix] || root['cancelRequest' + suffix]\n\nfor(var i = 0; !raf && i < vendors.length; i++) {\n raf = root[vendors[i] + 'Request' + suffix]\n caf = root[vendors[i] + 'Cancel' + suffix]\n || root[vendors[i] + 'CancelRequest' + suffix]\n}\n\n// Some versions of FF have rAF but not cAF\nif(!raf || !caf) {\n var last = 0\n , id = 0\n , queue = []\n , frameDuration = 1000 / 60\n\n raf = function(callback) {\n if(queue.length === 0) {\n var _now = now()\n , next = Math.max(0, frameDuration - (_now - last))\n last = next + _now\n setTimeout(function() {\n var cp = queue.slice(0)\n // Clear queue here to prevent\n // callbacks from appending listeners\n // to the current frame's queue\n queue.length = 0\n for(var i = 0; i < cp.length; i++) {\n if(!cp[i].cancelled) {\n try{\n cp[i].callback(last)\n } catch(e) {\n setTimeout(function() { throw e }, 0)\n }\n }\n }\n }, Math.round(next))\n }\n queue.push({\n handle: ++id,\n callback: callback,\n cancelled: false\n })\n return id\n }\n\n caf = function(handle) {\n for(var i = 0; i < queue.length; i++) {\n if(queue[i].handle === handle) {\n queue[i].cancelled = true\n }\n }\n }\n}\n\nmodule.exports = function(fn) {\n // Wrap in a new function to prevent\n // ` + "`")) + (`cancel` + ("`" + ` potentially being assigned\n // to the native rAF function\n return raf.call(root, fn)\n}\nmodule.exports.cancel = function() {\n caf.apply(root, arguments)\n}\nmodule.exports.polyfill = function(object) {\n if (!object) {\n object = root;\n }\n object.requestAnimationFrame = raf\n object.cancelAnimationFrame = caf\n}\n", + "/** @license React v16.8.4\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n'use strict';var aa=require(\"react\"),n=require(\"object-assign\"),r=require(\"scheduler\");function ba(a,b,c,d,e,f,g,h){if(!a){a=void 0;if(void 0===b)a=Error(\"Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.\");else{var l=[c,d,e,f,g,h],k=0;a=Error(b.replace(/%s/g,function(){return l[k++]}));a.name=\"Invariant Violation\"}a.framesToPop=1;throw a;}}\nfunction x(a){for(var b=arguments.length-1,c=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,d=0;dthis.eventPool.length&&this.eventPool.push(a)}\nfunction hb(a){a.eventPool=[];a.getPooled=ib;a.release=jb}var kb=y.extend({data:null}),lb=y.extend({data:null}),mb=[9,13,27,32],nb=Ra&&\"CompositionEvent\"in window,ob=null;Ra&&\"documentMode\"in document&&(ob=document.documentMode);\nvar pb=Ra&&\"TextEvent\"in window&&!ob,qb=Ra&&(!nb||ob&&8=ob),rb=String.fromCharCode(32),sb={beforeInput:{phasedRegistrationNames:{bubbled:\"onBeforeInput\",captured:\"onBeforeInputCapture\"},dependencies:[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]},compositionEnd:{phasedRegistrationNames:{bubbled:\"onCompositionEnd\",captured:\"onCompositionEndCapture\"},dependencies:\"blur compositionend keydown keypress keyup mousedown\".split(\" \")},compositionStart:{phasedRegistrationNames:{bubbled:\"onCompositionStart\",\ncaptured:\"onCompositionStartCapture\"},dependencies:\"blur compositionstart keydown keypress keyup mousedown\".split(\" \")},compositionUpdate:{phasedRegistrationNames:{bubbled:\"onCompositionUpdate\",captured:\"onCompositionUpdateCapture\"},dependencies:\"blur compositionupdate keydown keypress keyup mousedown\".split(\" \")}},tb=!1;\nfunction ub(a,b){switch(a){case \"keyup\":return-1!==mb.indexOf(b.keyCode);case \"keydown\":return 229!==b.keyCode;case \"keypress\":case \"mousedown\":case \"blur\":return!0;default:return!1}}function vb(a){a=a.detail;return\"object\"===typeof a&&\"data\"in a?a.data:null}var wb=!1;function xb(a,b){switch(a){case \"compositionend\":return vb(b);case \"keypress\":if(32!==b.which)return null;tb=!0;return rb;case \"textInput\":return a=b.data,a===rb&&tb?null:a;default:return null}}\nfunction yb(a,b){if(wb)return\"compositionend\"===a||!nb&&ub(a,b)?(a=eb(),db=cb=bb=null,wb=!1,a):null;switch(a){case \"paste\":return null;case \"keypress\":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1b}return!1}function C(a,b,c,d,e){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b}var D={};\n\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){D[a]=new C(a,0,!1,a,null)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var b=a[0];D[b]=new C(b,1,!1,a[1],null)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){D[a]=new C(a,2,!1,a.toLowerCase(),null)});\n[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){D[a]=new C(a,2,!1,a,null)});\"allowFullScreen async autoFocus autoPlay controls default defer disabled formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(a){D[a]=new C(a,3,!1,a.toLowerCase(),null)});[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){D[a]=new C(a,3,!0,a,null)});\n[\"capture\",\"download\"].forEach(function(a){D[a]=new C(a,4,!1,a,null)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){D[a]=new C(a,6,!1,a,null)});[\"rowSpan\",\"start\"].forEach(function(a){D[a]=new C(a,5,!1,a.toLowerCase(),null)});var rc=/[\\-:]([a-z])/g;function sc(a){return a[1].toUpperCase()}\n\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(a){var b=a.replace(rc,\nsc);D[b]=new C(b,1,!1,a,null)});\"xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var b=a.replace(rc,sc);D[b]=new C(b,1,!1,a,\"http://www.w3.org/1999/xlink\")});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var b=a.replace(rc,sc);D[b]=new C(b,1,!1,a,\"http://www.w3.org/XML/1998/namespace\")});[\"tabIndex\",\"crossOrigin\"].forEach(function(a){D[a]=new C(a,1,!1,a.toLowerCase(),null)});\nfunction tc(a,b,c,d){var e=D.hasOwnProperty(b)?D[b]:null;var f=null!==e?0===e.type:d?!1:!(2zd.length&&zd.push(a)}}}var Fd={},Gd=0,Hd=\"_reactListenersID\"+(\"\"+Math.random()).slice(2);\nfunction Id(a){Object.prototype.hasOwnProperty.call(a,Hd)||(a[Hd]=Gd++,Fd[a[Hd]]={});return Fd[a[Hd]]}function Jd(a){a=a||(\"undefined\"!==typeof document?document:void 0);if(\"undefined\"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}function Kd(a){for(;a&&a.firstChild;)a=a.firstChild;return a}\nfunction Ld(a,b){var c=Kd(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Kd(c)}}function Md(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Md(a,b.parentNode):\"contains\"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}\nfunction Nd(){for(var a=window,b=Jd();b instanceof a.HTMLIFrameElement;){try{a=b.contentDocument.defaultView}catch(c){break}b=Jd(a.document)}return b}function Od(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&(\"input\"===b&&(\"text\"===a.type||\"search\"===a.type||\"tel\"===a.type||\"url\"===a.type||\"password\"===a.type)||\"textarea\"===b||\"true\"===a.contentEditable)}\nfunction Pd(){var a=Nd();if(Od(a)){if(\"selectionStart\"in a)var b={start:a.selectionStart,end:a.selectionEnd};else a:{b=(b=a.ownerDocument)&&b.defaultView||window;var c=b.getSelection&&b.getSelection();if(c&&0!==c.rangeCount){b=c.anchorNode;var d=c.anchorOffset,e=c.focusNode;c=c.focusOffset;try{b.nodeType,e.nodeType}catch(A){b=null;break a}var f=0,g=-1,h=-1,l=0,k=0,m=a,p=null;b:for(;;){for(var t;;){m!==b||0!==d&&3!==m.nodeType||(g=f+d);m!==e||0!==c&&3!==m.nodeType||(h=f+c);3===m.nodeType&&(f+=m.nodeValue.length);\nif(null===(t=m.firstChild))break;p=m;m=t}for(;;){if(m===a)break b;p===b&&++l===d&&(g=f);p===e&&++k===c&&(h=f);if(null!==(t=m.nextSibling))break;m=p;p=m.parentNode}m=t}b=-1===g||-1===h?null:{start:g,end:h}}else b=null}b=b||{start:0,end:0}}else b=null;return{focusedElem:a,selectionRange:b}}\nfunction Qd(a){var b=Nd(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Md(c.ownerDocument.documentElement,c)){if(null!==d&&Od(c))if(b=d.start,a=d.end,void 0===a&&(a=b),\"selectionStart\"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ld(c,f);var g=Ld(c,\nd);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});\"function\"===typeof c.focus&&c.focus();for(c=0;c=document.documentMode,Sd={select:{phasedRegistrationNames:{bubbled:\"onSelect\",captured:\"onSelectCapture\"},dependencies:\"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange\".split(\" \")}},Td=null,Ud=null,Vd=null,Wd=!1;\nfunction Xd(a,b){var c=b.window===b?b.document:9===b.nodeType?b:b.ownerDocument;if(Wd||null==Td||Td!==Jd(c))return null;c=Td;\"selectionStart\"in c&&Od(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset});return Vd&&dd(Vd,c)?null:(Vd=c,a=y.getPooled(Sd.select,Ud,a,b),a.type=\"select\",a.target=Td,Qa(a),a)}\nvar Yd={eventTypes:Sd,extractEvents:function(a,b,c,d){var e=d.window===d?d.document:9===d.nodeType?d:d.ownerDocument,f;if(!(f=!e)){a:{e=Id(e);f=sa.onSelect;for(var g=0;g=b.length?void 0:x(\"93\"),b=b[0]),c=b),null==c&&(c=\"\"));a._wrapperState={initialValue:uc(c)}}\nfunction de(a,b){var c=uc(b.value),d=uc(b.defaultValue);null!=c&&(c=\"\"+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=\"\"+d)}function ee(a){var b=a.textContent;b===a._wrapperState.initialValue&&(a.value=b)}var fe={html:\"http://www.w3.org/1999/xhtml\",mathml:\"http://www.w3.org/1998/Math/MathML\",svg:\"http://www.w3.org/2000/svg\"};\nfunction ge(a){switch(a){case \"svg\":return\"http://www.w3.org/2000/svg\";case \"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function he(a,b){return null==a||\"http://www.w3.org/1999/xhtml\"===a?ge(b):\"http://www.w3.org/2000/svg\"===a&&\"foreignObject\"===b?\"http://www.w3.org/1999/xhtml\":a}\nvar ie=void 0,je=function(a){return\"undefined\"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if(a.namespaceURI!==fe.svg||\"innerHTML\"in a)a.innerHTML=b;else{ie=ie||document.createElement(\"div\");ie.innerHTML=\"\"+b+\"\";for(b=ie.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction ke(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}\nvar le={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,\nfloodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=[\"Webkit\",\"ms\",\"Moz\",\"O\"];Object.keys(le).forEach(function(a){me.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);le[b]=le[a]})});function ne(a,b,c){return null==b||\"boolean\"===typeof b||\"\"===b?\"\":c||\"number\"!==typeof b||0===b||le.hasOwnProperty(a)&&le[a]?(\"\"+b).trim():b+\"px\"}\nfunction oe(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf(\"--\"),e=ne(c,b[c],d);\"float\"===c&&(c=\"cssFloat\");d?a.setProperty(c,e):a[c]=e}}var pe=n({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});\nfunction qe(a,b){b&&(pe[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML?x(\"137\",a,\"\"):void 0),null!=b.dangerouslySetInnerHTML&&(null!=b.children?x(\"60\"):void 0,\"object\"===typeof b.dangerouslySetInnerHTML&&\"__html\"in b.dangerouslySetInnerHTML?void 0:x(\"61\")),null!=b.style&&\"object\"!==typeof b.style?x(\"62\",\"\"):void 0)}\nfunction re(a,b){if(-1===a.indexOf(\"-\"))return\"string\"===typeof b.is;switch(a){case \"annotation-xml\":case \"color-profile\":case \"font-face\":case \"font-face-src\":case \"font-face-uri\":case \"font-face-format\":case \"font-face-name\":case \"missing-glyph\":return!1;default:return!0}}\nfunction se(a,b){a=9===a.nodeType||11===a.nodeType?a:a.ownerDocument;var c=Id(a);b=sa[b];for(var d=0;dGe||(a.current=Fe[Ge],Fe[Ge]=null,Ge--)}function G(a,b){Ge++;Fe[Ge]=a.current;a.current=b}var He={},H={current:He},I={current:!1},Ie=He;\nfunction Je(a,b){var c=a.type.contextTypes;if(!c)return He;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function J(a){a=a.childContextTypes;return null!==a&&void 0!==a}function Ke(a){F(I,a);F(H,a)}function Le(a){F(I,a);F(H,a)}\nfunction Me(a,b,c){H.current!==He?x(\"168\"):void 0;G(H,b,a);G(I,c,a)}function Ne(a,b,c){var d=a.stateNode;a=b.childContextTypes;if(\"function\"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)e in a?void 0:x(\"108\",ic(b)||\"Unknown\",e);return n({},c,d)}function Oe(a){var b=a.stateNode;b=b&&b.__reactInternalMemoizedMergedChildContext||He;Ie=H.current;G(H,b,a);G(I,I.current,a);return!0}\nfunction Pe(a,b,c){var d=a.stateNode;d?void 0:x(\"169\");c?(b=Ne(a,b,Ie),d.__reactInternalMemoizedMergedChildContext=b,F(I,a),F(H,a),G(H,b,a)):F(I,a);G(I,c,a)}var Qe=null,Re=null;function Se(a){return function(b){try{return a(b)}catch(c){}}}\nfunction Te(a){if(\"undefined\"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var b=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(b.isDisabled||!b.supportsFiber)return!0;try{var c=b.inject(a);Qe=Se(function(a){return b.onCommitFiberRoot(c,a)});Re=Se(function(a){return b.onCommitFiberUnmount(c,a)})}catch(d){}return!0}\nfunction Ue(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.contextDependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.effectTag=0;this.lastEffect=this.firstEffect=this.nextEffect=null;this.childExpirationTime=this.expirationTime=0;this.alternate=null}function K(a,b,c,d){return new Ue(a,b,c,d)}\nfunction Ve(a){a=a.prototype;return!(!a||!a.isReactComponent)}function We(a){if(\"function\"===typeof a)return Ve(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===cc)return 11;if(a===ec)return 14}return 2}\nfunction Xe(a,b){var c=a.alternate;null===c?(c=K(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.effectTag=0,c.nextEffect=null,c.firstEffect=null,c.lastEffect=null);c.childExpirationTime=a.childExpirationTime;c.expirationTime=a.expirationTime;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;c.contextDependencies=a.contextDependencies;c.sibling=a.sibling;\nc.index=a.index;c.ref=a.ref;return c}\nfunction Ye(a,b,c,d,e,f){var g=2;d=a;if(\"function\"===typeof a)Ve(a)&&(g=1);else if(\"string\"===typeof a)g=5;else a:switch(a){case Xb:return Ze(c.children,e,f,b);case bc:return $e(c,e|3,f,b);case Yb:return $e(c,e|2,f,b);case Zb:return a=K(12,c,b,e|4),a.elementType=Zb,a.type=Zb,a.expirationTime=f,a;case dc:return a=K(13,c,b,e),a.elementType=dc,a.type=dc,a.expirationTime=f,a;default:if(\"object\"===typeof a&&null!==a)switch(a.$$typeof){case $b:g=10;break a;case ac:g=9;break a;case cc:g=11;break a;case ec:g=\n14;break a;case fc:g=16;d=null;break a}x(\"130\",null==a?a:typeof a,\"\")}b=K(g,c,b,e);b.elementType=a;b.type=d;b.expirationTime=f;return b}function Ze(a,b,c,d){a=K(7,a,d,b);a.expirationTime=c;return a}function $e(a,b,c,d){a=K(8,a,d,b);b=0===(b&1)?Yb:bc;a.elementType=b;a.type=b;a.expirationTime=c;return a}function af(a,b,c){a=K(6,a,null,b);a.expirationTime=c;return a}\nfunction bf(a,b,c){b=K(4,null!==a.children?a.children:[],a.key,b);b.expirationTime=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function cf(a,b){a.didError=!1;var c=a.earliestPendingTime;0===c?a.earliestPendingTime=a.latestPendingTime=b:cb&&(a.latestPendingTime=b);df(b,a)}\nfunction ef(a,b){a.didError=!1;if(0===b)a.earliestPendingTime=0,a.latestPendingTime=0,a.earliestSuspendedTime=0,a.latestSuspendedTime=0,a.latestPingedTime=0;else{bb?a.earliestPendingTime=a.latestPendingTime=0:a.earliestPendingTime>b&&(a.earliestPendingTime=a.latestPendingTime));c=a.earliestSuspendedTime;0===c?cf(a,b):bc&&cf(a,b)}df(0,a)}function ff(a,b){a.didError=!1;a.latestPingedTime>=b&&(a.latestPingedTime=0);var c=a.earliestPendingTime,d=a.latestPendingTime;c===b?a.earliestPendingTime=d===b?a.latestPendingTime=0:d:d===b&&(a.latestPendingTime=c);c=a.earliestSuspendedTime;d=a.latestSuspendedTime;0===c?a.earliestSuspendedTime=a.latestSuspendedTime=b:cb&&(a.latestSuspendedTime=b);df(b,a)}\nfunction gf(a,b){var c=a.earliestPendingTime;a=a.earliestSuspendedTime;c>b&&(b=c);a>b&&(b=a);return b}function df(a,b){var c=b.earliestSuspendedTime,d=b.latestSuspendedTime,e=b.earliestPendingTime,f=b.latestPingedTime;e=0!==e?e:f;0===e&&(0===a||da&&(a=c);b.nextExpirationTimeToWorkOn=e;b.expirationTime=a}function L(a,b){if(a&&a.defaultProps){b=n({},b);a=a.defaultProps;for(var c in a)void 0===b[c]&&(b[c]=a[c])}return b}\nfunction hf(a){var b=a._result;switch(a._status){case 1:return b;case 2:throw b;case 0:throw b;default:a._status=0;b=a._ctor;b=b();b.then(function(b){0===a._status&&(b=b.default,a._status=1,a._result=b)},function(b){0===a._status&&(a._status=2,a._result=b)});switch(a._status){case 1:return a._result;case 2:throw a._result;}a._result=b;throw b;}}var jf=(new aa.Component).refs;\nfunction kf(a,b,c,d){b=a.memoizedState;c=c(d,b);c=null===c||void 0===c?b:n({},b,c);a.memoizedState=c;d=a.updateQueue;null!==d&&0===a.expirationTime&&(d.baseState=c)}\nvar tf={isMounted:function(a){return(a=a._reactInternalFiber)?2===ed(a):!1},enqueueSetState:function(a,b,c){a=a._reactInternalFiber;var d=lf();d=mf(d,a);var e=nf(d);e.payload=b;void 0!==c&&null!==c&&(e.callback=c);of();pf(a,e);qf(a,d)},enqueueReplaceState:function(a,b,c){a=a._reactInternalFiber;var d=lf();d=mf(d,a);var e=nf(d);e.tag=rf;e.payload=b;void 0!==c&&null!==c&&(e.callback=c);of();pf(a,e);qf(a,d)},enqueueForceUpdate:function(a,b){a=a._reactInternalFiber;var c=lf();c=mf(c,a);var d=nf(c);d.tag=\nsf;void 0!==b&&null!==b&&(d.callback=b);of();pf(a,d);qf(a,c)}};function uf(a,b,c,d,e,f,g){a=a.stateNode;return\"function\"===typeof a.shouldComponentUpdate?a.shouldComponentUpdate(d,f,g):b.prototype&&b.prototype.isPureReactComponent?!dd(c,d)||!dd(e,f):!0}\nfunction vf(a,b,c){var d=!1,e=He;var f=b.contextType;\"object\"===typeof f&&null!==f?f=M(f):(e=J(b)?Ie:H.current,d=b.contextTypes,f=(d=null!==d&&void 0!==d)?Je(a,e):He);b=new b(c,f);a.memoizedState=null!==b.state&&void 0!==b.state?b.state:null;b.updater=tf;a.stateNode=b;b._reactInternalFiber=a;d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=e,a.__reactInternalMemoizedMaskedChildContext=f);return b}\nfunction wf(a,b,c,d){a=b.state;\"function\"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);\"function\"===typeof b.UNSAFE_componentWillReceiveProps&&b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&tf.enqueueReplaceState(b,b.state,null)}\nfunction xf(a,b,c,d){var e=a.stateNode;e.props=c;e.state=a.memoizedState;e.refs=jf;var f=b.contextType;\"object\"===typeof f&&null!==f?e.context=M(f):(f=J(b)?Ie:H.current,e.context=Je(a,f));f=a.updateQueue;null!==f&&(yf(a,f,c,e,d),e.state=a.memoizedState);f=b.getDerivedStateFromProps;\"function\"===typeof f&&(kf(a,b,f,c),e.state=a.memoizedState);\"function\"===typeof b.getDerivedStateFromProps||\"function\"===typeof e.getSnapshotBeforeUpdate||\"function\"!==typeof e.UNSAFE_componentWillMount&&\"function\"!==\ntypeof e.componentWillMount||(b=e.state,\"function\"===typeof e.componentWillMount&&e.componentWillMount(),\"function\"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),b!==e.state&&tf.enqueueReplaceState(e,e.state,null),f=a.updateQueue,null!==f&&(yf(a,f,c,e,d),e.state=a.memoizedState));\"function\"===typeof e.componentDidMount&&(a.effectTag|=4)}var zf=Array.isArray;\nfunction Af(a,b,c){a=c.ref;if(null!==a&&\"function\"!==typeof a&&\"object\"!==typeof a){if(c._owner){c=c._owner;var d=void 0;c&&(1!==c.tag?x(\"309\"):void 0,d=c.stateNode);d?void 0:x(\"147\",a);var e=\"\"+a;if(null!==b&&null!==b.ref&&\"function\"===typeof b.ref&&b.ref._stringRef===e)return b.ref;b=function(a){var b=d.refs;b===jf&&(b=d.refs={});null===a?delete b[e]:b[e]=a};b._stringRef=e;return b}\"string\"!==typeof a?x(\"284\"):void 0;c._owner?void 0:x(\"290\",a)}return a}\nfunction Bf(a,b){\"textarea\"!==a.type&&x(\"31\",\"[object Object]\"===Object.prototype.toString.call(b)?\"object with keys {\"+Object.keys(b).join(\", \")+\"}\":b,\"\")}\nfunction Cf(a){function b(b,c){if(a){var d=b.lastEffect;null!==d?(d.nextEffect=c,b.lastEffect=c):b.firstEffect=b.lastEffect=c;c.nextEffect=null;c.effectTag=8}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,b),b=b.sibling;return a}function e(a,b,c){a=Xe(a,b,c);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return c;d=b.alternate;if(null!==d)return d=d.index,du?(B=q,q=null):B=q.sibling;var w=t(e,q,h[u],k);if(null===w){null===q&&(q=B);break}a&&\nq&&null===w.alternate&&b(e,q);g=f(w,g,u);null===m?l=w:m.sibling=w;m=w;q=B}if(u===h.length)return c(e,q),l;if(null===q){for(;uu?(B=q,q=null):B=q.sibling;var v=t(e,q,w.value,k);if(null===v){q||(q=B);break}a&&q&&null===v.alternate&&b(e,q);g=f(v,g,u);null===m?l=v:m.sibling=v;m=v;q=B}if(w.done)return c(e,q),l;if(null===q){for(;!w.done;u++,w=h.next())w=p(e,w.value,k),null!==w&&(g=f(w,g,u),null===m?l=w:m.sibling=w,m=w);return l}for(q=d(e,q);!w.done;u++,w=h.next())w=A(q,e,u,w.value,k),null!==w&&(a&&null!==w.alternate&&q.delete(null===w.key?u:\nw.key),g=f(w,g,u),null===m?l=w:m.sibling=w,m=w);a&&q.forEach(function(a){return b(e,a)});return l}return function(a,d,f,h){var k=\"object\"===typeof f&&null!==f&&f.type===Xb&&null===f.key;k&&(f=f.props.children);var l=\"object\"===typeof f&&null!==f;if(l)switch(f.$$typeof){case Vb:a:{l=f.key;for(k=d;null!==k;){if(k.key===l)if(7===k.tag?f.type===Xb:k.elementType===f.type){c(a,k.sibling);d=e(k,f.type===Xb?f.props.children:f.props,h);d.ref=Af(a,k,f);d.return=a;a=d;break a}else{c(a,k);break}else b(a,k);k=\nk.sibling}f.type===Xb?(d=Ze(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=Ye(f.type,f.key,f.props,null,a.mode,h),h.ref=Af(a,d,f),h.return=a,a=h)}return g(a);case Wb:a:{for(k=f.key;null!==d;){if(d.key===k)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[],h);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=bf(f,a.mode,h);d.return=a;a=d}return g(a)}if(\"string\"===typeof f||\"number\"===typeof f)return f=\n\"\"+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f,h),d.return=a,a=d):(c(a,d),d=af(f,a.mode,h),d.return=a,a=d),g(a);if(zf(f))return v(a,d,f,h);if(hc(f))return R(a,d,f,h);l&&Bf(a,f);if(\"undefined\"===typeof f&&!k)switch(a.tag){case 1:case 0:h=a.type,x(\"152\",h.displayName||h.name||\"Component\")}return c(a,d)}}var Df=Cf(!0),Ef=Cf(!1),Ff={},N={current:Ff},Gf={current:Ff},Hf={current:Ff};function If(a){a===Ff?x(\"174\"):void 0;return a}\nfunction Jf(a,b){G(Hf,b,a);G(Gf,a,a);G(N,Ff,a);var c=b.nodeType;switch(c){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:he(null,\"\");break;default:c=8===c?b.parentNode:b,b=c.namespaceURI||null,c=c.tagName,b=he(b,c)}F(N,a);G(N,b,a)}function Kf(a){F(N,a);F(Gf,a);F(Hf,a)}function Lf(a){If(Hf.current);var b=If(N.current);var c=he(b,a.type);b!==c&&(G(Gf,a,a),G(N,c,a))}function Mf(a){Gf.current===a&&(F(N,a),F(Gf,a))}\nvar Nf=0,Of=2,Pf=4,Qf=8,Rf=16,Sf=32,Tf=64,Uf=128,Vf=Tb.ReactCurrentDispatcher,Wf=0,Xf=null,O=null,P=null,Yf=null,Q=null,Zf=null,$f=0,ag=null,bg=0,cg=!1,dg=null,eg=0;function fg(){x(\"307\")}function gg(a,b){if(null===b)return!1;for(var c=0;c$f&&($f=m)):f=l.eagerReducer===a?l.eagerState:a(f,l.action);g=l;l=l.next}while(null!==l&&l!==d);k||(h=g,e=f);bd(f,b.memoizedState)||(qg=!0);b.memoizedState=f;b.baseUpdate=h;b.baseState=e;c.eagerReducer=a;c.eagerState=f}return[b.memoizedState,c.dispatch]}\nfunction rg(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};null===ag?(ag={lastEffect:null},ag.lastEffect=a.next=a):(b=ag.lastEffect,null===b?ag.lastEffect=a.next=a:(c=b.next,b.next=a,a.next=c,ag.lastEffect=a));return a}function sg(a,b,c,d){var e=mg();bg|=a;e.memoizedState=rg(b,c,void 0,void 0===d?null:d)}\nfunction tg(a,b,c,d){var e=ng();d=void 0===d?null:d;var f=void 0;if(null!==O){var g=O.memoizedState;f=g.destroy;if(null!==d&&gg(d,g.deps)){rg(Nf,c,f,d);return}}bg|=a;e.memoizedState=rg(b,c,f,d)}function ug(a,b){if(\"function\"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function vg(){}\nfunction wg(a,b,c){25>eg?void 0:x(\"301\");var d=a.alternate;if(a===Xf||null!==d&&d===Xf)if(cg=!0,a={expirationTime:Wf,action:c,eagerReducer:null,eagerState:null,next:null},null===dg&&(dg=new Map),c=dg.get(b),void 0===c)dg.set(b,a);else{for(b=c;null!==b.next;)b=b.next;b.next=a}else{of();var e=lf();e=mf(e,a);var f={expirationTime:e,action:c,eagerReducer:null,eagerState:null,next:null},g=b.last;if(null===g)f.next=f;else{var h=g.next;null!==h&&(f.next=h);g.next=f}b.last=f;if(0===a.expirationTime&&(null===\nd||0===d.expirationTime)&&(d=b.eagerReducer,null!==d))try{var l=b.eagerState,k=d(l,c);f.eagerReducer=d;f.eagerState=k;if(bd(k,l))return}catch(m){}finally{}qf(a,e)}}\nvar kg={readContext:M,useCallback:fg,useContext:fg,useEffect:fg,useImperativeHandle:fg,useLayoutEffect:fg,useMemo:fg,useReducer:fg,useRef:fg,useState:fg,useDebugValue:fg},ig={readContext:M,useCallback:function(a,b){mg().memoizedState=[a,void 0===b?null:b];return a},useContext:M,useEffect:function(a,b){return sg(516,Uf|Tf,a,b)},useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return sg(4,Pf|Sf,ug.bind(null,b,a),c)},useLayoutEffect:function(a,b){return sg(4,Pf|Sf,a,b)},\nuseMemo:function(a,b){var c=mg();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=mg();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a=d.queue={last:null,dispatch:null,eagerReducer:a,eagerState:b};a=a.dispatch=wg.bind(null,Xf,a);return[d.memoizedState,a]},useRef:function(a){var b=mg();a={current:a};return b.memoizedState=a},useState:function(a){var b=mg();\"function\"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a=b.queue={last:null,dispatch:null,eagerReducer:og,\neagerState:a};a=a.dispatch=wg.bind(null,Xf,a);return[b.memoizedState,a]},useDebugValue:vg},jg={readContext:M,useCallback:function(a,b){var c=ng();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&gg(b,d[1]))return d[0];c.memoizedState=[a,b];return a},useContext:M,useEffect:function(a,b){return tg(516,Uf|Tf,a,b)},useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return tg(4,Pf|Sf,ug.bind(null,b,a),c)},useLayoutEffect:function(a,b){return tg(4,Pf|Sf,a,b)},\nuseMemo:function(a,b){var c=ng();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&gg(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a},useReducer:pg,useRef:function(){return ng().memoizedState},useState:function(a){return pg(og,a)},useDebugValue:vg},xg=null,yg=null,zg=!1;\nfunction Ag(a,b){var c=K(5,null,null,0);c.elementType=\"DELETED\";c.type=\"DELETED\";c.stateNode=b;c.return=a;c.effectTag=8;null!==a.lastEffect?(a.lastEffect.nextEffect=c,a.lastEffect=c):a.firstEffect=a.lastEffect=c}function Bg(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,!0):!1;case 6:return b=\"\"===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,!0):!1;case 13:return!1;default:return!1}}\nfunction Cg(a){if(zg){var b=yg;if(b){var c=b;if(!Bg(a,b)){b=De(c);if(!b||!Bg(a,b)){a.effectTag|=2;zg=!1;xg=a;return}Ag(xg,c)}xg=a;yg=Ee(b)}else a.effectTag|=2,zg=!1,xg=a}}function Dg(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&18!==a.tag;)a=a.return;xg=a}function Eg(a){if(a!==xg)return!1;if(!zg)return Dg(a),zg=!0,!1;var b=a.type;if(5!==a.tag||\"head\"!==b&&\"body\"!==b&&!xe(b,a.memoizedProps))for(b=yg;b;)Ag(a,b),b=De(b);Dg(a);yg=xg?De(a.stateNode):null;return!0}function Fg(){yg=xg=null;zg=!1}\nvar Gg=Tb.ReactCurrentOwner,qg=!1;function S(a,b,c,d){b.child=null===a?Ef(b,null,c,d):Df(b,a.child,c,d)}function Hg(a,b,c,d,e){c=c.render;var f=b.ref;Ig(b,e);d=hg(a,b,c,d,f,e);if(null!==a&&!qg)return b.updateQueue=a.updateQueue,b.effectTag&=-517,a.expirationTime<=e&&(a.expirationTime=0),Jg(a,b,e);b.effectTag|=1;S(a,b,d,e);return b.child}\nfunction Kg(a,b,c,d,e,f){if(null===a){var g=c.type;if(\"function\"===typeof g&&!Ve(g)&&void 0===g.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=g,Lg(a,b,g,d,e,f);a=Ye(c.type,null,d,null,b.mode,f);a.ref=b.ref;a.return=b;return b.child=a}g=a.child;if(e=c)return Sg(a,b,c);b=Jg(a,b,c);return null!==b?b.sibling:null}}return Jg(a,b,c)}}else qg=!1;b.expirationTime=0;switch(b.tag){case 2:d=\nb.elementType;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;var e=Je(b,H.current);Ig(b,c);e=hg(null,b,d,a,e,c);b.effectTag|=1;if(\"object\"===typeof e&&null!==e&&\"function\"===typeof e.render&&void 0===e.$$typeof){b.tag=1;lg();if(J(d)){var f=!0;Oe(b)}else f=!1;b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null;var g=d.getDerivedStateFromProps;\"function\"===typeof g&&kf(b,d,g,a);e.updater=tf;b.stateNode=e;e._reactInternalFiber=b;xf(b,d,a,c);b=Qg(null,b,d,!0,f,\nc)}else b.tag=0,S(null,b,e,c),b=b.child;return b;case 16:e=b.elementType;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);f=b.pendingProps;a=hf(e);b.type=a;e=b.tag=We(a);f=L(a,f);g=void 0;switch(e){case 0:g=Mg(null,b,a,f,c);break;case 1:g=Og(null,b,a,f,c);break;case 11:g=Hg(null,b,a,f,c);break;case 14:g=Kg(null,b,a,L(a.type,f),d,c);break;default:x(\"306\",a,\"\")}return g;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:L(d,e),Mg(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,\ne=b.elementType===d?e:L(d,e),Og(a,b,d,e,c);case 3:Rg(b);d=b.updateQueue;null===d?x(\"282\"):void 0;e=b.memoizedState;e=null!==e?e.element:null;yf(b,d,b.pendingProps,null,c);d=b.memoizedState.element;if(d===e)Fg(),b=Jg(a,b,c);else{e=b.stateNode;if(e=(null===a||null===a.child)&&e.hydrate)yg=Ee(b.stateNode.containerInfo),xg=b,e=zg=!0;e?(b.effectTag|=2,b.child=Ef(b,null,d,c)):(S(a,b,d,c),Fg());b=b.child}return b;case 5:return Lf(b),null===a&&Cg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,\ng=e.children,xe(d,e)?g=null:null!==f&&xe(d,f)&&(b.effectTag|=16),Ng(a,b),1!==c&&b.mode&1&&e.hidden?(b.expirationTime=b.childExpirationTime=1,b=null):(S(a,b,g,c),b=b.child),b;case 6:return null===a&&Cg(b),null;case 13:return Sg(a,b,c);case 4:return Jf(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Df(b,null,d,c):S(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:L(d,e),Hg(a,b,d,e,c);case 7:return S(a,b,b.pendingProps,c),b.child;case 8:return S(a,b,b.pendingProps.children,\nc),b.child;case 12:return S(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;g=b.memoizedProps;f=e.value;Ug(b,f);if(null!==g){var h=g.value;f=bd(h,f)?0:(\"function\"===typeof d._calculateChangedBits?d._calculateChangedBits(h,f):1073741823)|0;if(0===f){if(g.children===e.children&&!I.current){b=Jg(a,b,c);break a}}else for(h=b.child,null!==h&&(h.return=b);null!==h;){var l=h.contextDependencies;if(null!==l){g=h.child;for(var k=l.first;null!==k;){if(k.context===d&&0!==\n(k.observedBits&f)){1===h.tag&&(k=nf(c),k.tag=sf,pf(h,k));h.expirationTime=b&&(qg=!0);a.contextDependencies=null}\nfunction M(a,b){if(Yg!==a&&!1!==b&&0!==b){if(\"number\"!==typeof b||1073741823===b)Yg=a,b=1073741823;b={context:a,observedBits:b,next:null};null===Xg?(null===Wg?x(\"308\"):void 0,Xg=b,Wg.contextDependencies={first:b,expirationTime:0}):Xg=Xg.next=b}return a._currentValue}var $g=0,rf=1,sf=2,ah=3,Pg=!1;function bh(a){return{baseState:a,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}\nfunction ch(a){return{baseState:a.baseState,firstUpdate:a.firstUpdate,lastUpdate:a.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function nf(a){return{expirationTime:a,tag:$g,payload:null,callback:null,next:null,nextEffect:null}}function dh(a,b){null===a.lastUpdate?a.firstUpdate=a.lastUpdate=b:(a.lastUpdate.next=b,a.lastUpdate=b)}\nfunction pf(a,b){var c=a.alternate;if(null===c){var d=a.updateQueue;var e=null;null===d&&(d=a.updateQueue=bh(a.memoizedState))}else d=a.updateQueue,e=c.updateQueue,null===d?null===e?(d=a.updateQueue=bh(a.memoizedState),e=c.updateQueue=bh(c.memoizedState)):d=a.updateQueue=ch(e):null===e&&(e=c.updateQueue=ch(d));null===e||d===e?dh(d,b):null===d.lastUpdate||null===e.lastUpdate?(dh(d,b),dh(e,b)):(dh(d,b),e.lastUpdate=b)}\nfunction eh(a,b){var c=a.updateQueue;c=null===c?a.updateQueue=bh(a.memoizedState):fh(a,c);null===c.lastCapturedUpdate?c.firstCapturedUpdate=c.lastCapturedUpdate=b:(c.lastCapturedUpdate.next=b,c.lastCapturedUpdate=b)}function fh(a,b){var c=a.alternate;null!==c&&b===c.updateQueue&&(b=a.updateQueue=ch(b));return b}\nfunction gh(a,b,c,d,e,f){switch(c.tag){case rf:return a=c.payload,\"function\"===typeof a?a.call(f,d,e):a;case ah:a.effectTag=a.effectTag&-2049|64;case $g:a=c.payload;e=\"function\"===typeof a?a.call(f,d,e):a;if(null===e||void 0===e)break;return n({},d,e);case sf:Pg=!0}return d}\nfunction yf(a,b,c,d,e){Pg=!1;b=fh(a,b);for(var f=b.baseState,g=null,h=0,l=b.firstUpdate,k=f;null!==l;){var m=l.expirationTime;md?e:d);Ih.current=null;d=void 0;1c?b:c;0===b&&(Fh=null);$h(a,b)}\nfunction ai(a){for(;;){var b=a.alternate,c=a.return,d=a.sibling;if(0===(a.effectTag&1024)){T=a;a:{var e=b;b=a;var f=U;var g=b.pendingProps;switch(b.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:J(b.type)&&Ke(b);break;case 3:Kf(b);Le(b);g=b.stateNode;g.pendingContext&&(g.context=g.pendingContext,g.pendingContext=null);if(null===e||null===e.child)Eg(b),b.effectTag&=-3;mh(b);break;case 5:Mf(b);var h=If(Hf.current);f=b.type;if(null!==e&&null!=b.stateNode)nh(e,b,f,g,h),e.ref!==b.ref&&(b.effectTag|=\n128);else if(g){var l=If(N.current);if(Eg(b)){g=b;e=g.stateNode;var k=g.type,m=g.memoizedProps,p=h;e[Fa]=g;e[Ga]=m;f=void 0;h=k;switch(h){case \"iframe\":case \"object\":E(\"load\",e);break;case \"video\":case \"audio\":for(k=0;k\\x3c/script>\",k=e.removeChild(e.firstChild)):\"string\"===typeof p.is?k=k.createElement(e,{is:p.is}):(k=k.createElement(e),\"select\"===e&&p.multiple&&(k.multiple=!0)):k=k.createElementNS(l,e);e=k;e[Fa]=m;e[Ga]=g;lh(e,b,!1,!1);p=e;k=f;m=g;var t=h,A=re(k,m);switch(k){case \"iframe\":case \"object\":E(\"load\",\np);h=m;break;case \"video\":case \"audio\":for(h=0;hg&&(g=e),h>g&&(g=h),f=f.sibling;b.childExpirationTime=g}if(null!==T)return T;null!==c&&0===(c.effectTag&1024)&&(null===c.firstEffect&&\n(c.firstEffect=a.firstEffect),null!==a.lastEffect&&(null!==c.lastEffect&&(c.lastEffect.nextEffect=a.firstEffect),c.lastEffect=a.lastEffect),1=v)t=0;else if(-1===t||v component higher in the tree to provide a loading indicator or placeholder to display.\"+jc(k))}Nh=!0;m=jh(m,k);h=l;do{switch(h.tag){case 3:h.effectTag|=2048;h.expirationTime=g;g=Ch(h,m,g);eh(h,g);break a;case 1:if(t=m,A=h.type,k=h.stateNode,0===(h.effectTag&64)&&(\"function\"===typeof A.getDerivedStateFromError||null!==k&&\"function\"===typeof k.componentDidCatch&&(null===Fh||!Fh.has(k)))){h.effectTag|=2048;\nh.expirationTime=g;g=Eh(h,t,g);eh(h,g);break a}}h=h.return}while(null!==h)}T=ai(f);continue}}}break}while(1);Kh=!1;Hh.current=c;Yg=Xg=Wg=null;lg();if(e)Lh=null,a.finishedWork=null;else if(null!==T)a.finishedWork=null;else{c=a.current.alternate;null===c?x(\"281\"):void 0;Lh=null;if(Nh){e=a.latestPendingTime;f=a.latestSuspendedTime;g=a.latestPingedTime;if(0!==e&&eb?0:b)):(a.pendingCommitExpirationTime=d,a.finishedWork=c)}}\nfunction sh(a,b){for(var c=a.return;null!==c;){switch(c.tag){case 1:var d=c.stateNode;if(\"function\"===typeof c.type.getDerivedStateFromError||\"function\"===typeof d.componentDidCatch&&(null===Fh||!Fh.has(d))){a=jh(b,a);a=Eh(c,a,1073741823);pf(c,a);qf(c,1073741823);return}break;case 3:a=jh(b,a);a=Ch(c,a,1073741823);pf(c,a);qf(c,1073741823);return}c=c.return}3===a.tag&&(c=jh(b,a),c=Ch(a,c,1073741823),pf(a,c),qf(a,1073741823))}\nfunction mf(a,b){var c=r.unstable_getCurrentPriorityLevel(),d=void 0;if(0===(b.mode&1))d=1073741823;else if(Kh&&!Oh)d=U;else{switch(c){case r.unstable_ImmediatePriority:d=1073741823;break;case r.unstable_UserBlockingPriority:d=1073741822-10*(((1073741822-a+15)/10|0)+1);break;case r.unstable_NormalPriority:d=1073741822-25*(((1073741822-a+500)/25|0)+1);break;case r.unstable_LowPriority:case r.unstable_IdlePriority:d=1;break;default:x(\"313\")}null!==Lh&&d===U&&--d}c===r.unstable_UserBlockingPriority&&\n(0===gi||d=d){a.didError=!1;b=a.latestPingedTime;if(0===b||b>c)a.latestPingedTime=c;df(c,a);c=a.expirationTime;0!==c&&Xh(a,c)}}function Ah(a,b){var c=a.stateNode;null!==c&&c.delete(b);b=lf();b=mf(b,a);a=hi(a,b);null!==a&&(cf(a,b),b=a.expirationTime,0!==b&&Xh(a,b))}\nfunction hi(a,b){a.expirationTimeU&&Sh(),cf(a,b),Kh&&!Oh&&Lh===a||Xh(a,a.expirationTime),ii>ji&&(ii=0,x(\"185\")))}function ki(a,b,c,d,e){return r.unstable_runWithPriority(r.unstable_ImmediatePriority,function(){return a(b,c,d,e)})}var li=null,Y=null,mi=0,ni=void 0,W=!1,oi=null,Z=0,gi=0,pi=!1,qi=null,X=!1,ri=!1,si=null,ti=r.unstable_now(),ui=1073741822-(ti/10|0),vi=ui,ji=50,ii=0,wi=null;function xi(){ui=1073741822-((r.unstable_now()-ti)/10|0)}\nfunction yi(a,b){if(0!==mi){if(ba.expirationTime&&(a.expirationTime=b);W||(X?ri&&(oi=a,Z=1073741823,Di(a,1073741823,!1)):1073741823===b?Yh(1073741823,!1):yi(a,b))}\nfunction Ci(){var a=0,b=null;if(null!==Y)for(var c=Y,d=li;null!==d;){var e=d.expirationTime;if(0===e){null===c||null===Y?x(\"244\"):void 0;if(d===d.nextScheduledRoot){li=Y=d.nextScheduledRoot=null;break}else if(d===li)li=e=d.nextScheduledRoot,Y.nextScheduledRoot=e,d.nextScheduledRoot=null;else if(d===Y){Y=c;Y.nextScheduledRoot=li;d.nextScheduledRoot=null;break}else c.nextScheduledRoot=d.nextScheduledRoot,d.nextScheduledRoot=null;d=c.nextScheduledRoot}else{e>a&&(a=e,b=d);if(d===Y)break;if(1073741823===\na)break;c=d;d=d.nextScheduledRoot}}oi=b;Z=a}var Ei=!1;function di(){return Ei?!0:r.unstable_shouldYield()?Ei=!0:!1}function zi(){try{if(!di()&&null!==li){xi();var a=li;do{var b=a.expirationTime;0!==b&&ui<=b&&(a.nextExpirationTimeToWorkOn=ui);a=a.nextScheduledRoot}while(a!==li)}Yh(0,!0)}finally{Ei=!1}}\nfunction Yh(a,b){Ci();if(b)for(xi(),vi=ui;null!==oi&&0!==Z&&a<=Z&&!(Ei&&ui>Z);)Di(oi,Z,ui>Z),Ci(),xi(),vi=ui;else for(;null!==oi&&0!==Z&&a<=Z;)Di(oi,Z,!1),Ci();b&&(mi=0,ni=null);0!==Z&&yi(oi,Z);ii=0;wi=null;if(null!==si)for(a=si,si=null,b=0;b=c&&(null===si?si=[d]:si.push(d),d._defer)){a.finishedWork=b;a.expirationTime=0;return}a.finishedWork=null;a===wi?ii++:(wi=a,ii=0);r.unstable_runWithPriority(r.unstable_ImmediatePriority,function(){Zh(a,b)})}function Dh(a){null===oi?x(\"246\"):void 0;oi.expirationTime=0;pi||(pi=!0,qi=a)}function Gi(a,b){var c=X;X=!0;try{return a(b)}finally{(X=c)||W||Yh(1073741823,!1)}}\nfunction Hi(a,b){if(X&&!ri){ri=!0;try{return a(b)}finally{ri=!1}}return a(b)}function Ii(a,b,c){X||W||0===gi||(Yh(gi,!1),gi=0);var d=X;X=!0;try{return r.unstable_runWithPriority(r.unstable_UserBlockingPriority,function(){return a(b,c)})}finally{(X=d)||W||Yh(1073741823,!1)}}\nfunction Ji(a,b,c,d,e){var f=b.current;a:if(c){c=c._reactInternalFiber;b:{2===ed(c)&&1===c.tag?void 0:x(\"170\");var g=c;do{switch(g.tag){case 3:g=g.stateNode.context;break b;case 1:if(J(g.type)){g=g.stateNode.__reactInternalMemoizedMergedChildContext;break b}}g=g.return}while(null!==g);x(\"171\");g=void 0}if(1===c.tag){var h=c.type;if(J(h)){c=Ne(c,h,g);break a}}c=g}else c=He;null===b.context?b.context=c:b.pendingContext=c;b=e;e=nf(d);e.payload={element:a};b=void 0===b?null:b;null!==b&&(e.callback=b);\nof();pf(f,e);qf(f,d);return d}function Ki(a,b,c,d){var e=b.current,f=lf();e=mf(f,e);return Ji(a,b,c,e,d)}function Li(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function Mi(a,b,c){var d=3=Jh&&(b=Jh-1);this._expirationTime=Jh=b;this._root=a;this._callbacks=this._next=null;this._hasChildren=this._didComplete=!1;this._children=null;this._defer=!0}Ni.prototype.render=function(a){this._defer?void 0:x(\"250\");this._hasChildren=!0;this._children=a;var b=this._root._internalRoot,c=this._expirationTime,d=new Oi;Ji(a,b,null,c,d._onCommit);return d};\nNi.prototype.then=function(a){if(this._didComplete)a();else{var b=this._callbacks;null===b&&(b=this._callbacks=[]);b.push(a)}};\nNi.prototype.commit=function(){var a=this._root._internalRoot,b=a.firstBatch;this._defer&&null!==b?void 0:x(\"251\");if(this._hasChildren){var c=this._expirationTime;if(b!==this){this._hasChildren&&(c=this._expirationTime=b._expirationTime,this.render(this._children));for(var d=null,e=b;e!==this;)d=e,e=e._next;null===d?x(\"251\"):void 0;d._next=e._next;this._next=b;a.firstBatch=this}this._defer=!1;Bi(a,c);b=this._next;this._next=null;b=a.firstBatch=b;null!==b&&b._hasChildren&&b.render(b._children)}else this._next=\nnull,this._defer=!1};Ni.prototype._onComplete=function(){if(!this._didComplete){this._didComplete=!0;var a=this._callbacks;if(null!==a)for(var b=0;b=b;)c=d,d=d._next;a._next=d;null!==c&&(c._next=a)}return a};function Qi(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||\" react-mount-point-unstable \"!==a.nodeValue))}Gb=Gi;Hb=Ii;Ib=function(){W||0===gi||(Yh(gi,!1),gi=0)};\nfunction Ri(a,b){b||(b=a?9===a.nodeType?a.documentElement:a.firstChild:null,b=!(!b||1!==b.nodeType||!b.hasAttribute(\"data-reactroot\")));if(!b)for(var c;c=a.lastChild;)a.removeChild(c);return new Pi(a,!1,b)}\nfunction Si(a,b,c,d,e){var f=c._reactRootContainer;if(f){if(\"function\"===typeof e){var g=e;e=function(){var a=Li(f._internalRoot);g.call(a)}}null!=a?f.legacy_renderSubtreeIntoContainer(a,b,e):f.render(b,e)}else{f=c._reactRootContainer=Ri(c,d);if(\"function\"===typeof e){var h=e;e=function(){var a=Li(f._internalRoot);h.call(a)}}Hi(function(){null!=a?f.legacy_renderSubtreeIntoContainer(a,b,e):f.render(b,e)})}return Li(f._internalRoot)}\nfunction Ti(a,b){var c=2 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var currTime = -1;\n\n var shouldUpdate = function shouldUpdate(now) {\n if (currTime < 0) {\n currTime = now;\n }\n\n if (now - currTime > timeout) {\n callback(now);\n currTime = -1;\n } else {\n raf(shouldUpdate);\n }\n };\n\n raf(shouldUpdate);\n}", + "function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nimport setRafTimeout from './setRafTimeout';\nexport default function createAnimateManager() {\n var currStyle = {};\n\n var handleChange = function handleChange() {\n return null;\n };\n\n var shouldStop = false;\n\n var setStyle = function setStyle(_style) {\n if (shouldStop) {\n return;\n }\n\n if (Array.isArray(_style)) {\n if (!_style.length) {\n return;\n }\n\n var styles = _style;\n\n var _styles = _toArray(styles),\n curr = _styles[0],\n restStyles = _styles.slice(1);\n\n if (typeof curr === 'number') {\n setRafTimeout(setStyle.bind(null, restStyles), curr);\n return;\n }\n\n setStyle(curr);\n setRafTimeout(setStyle.bind(null, restStyles));\n return;\n }\n\n if (_typeof(_style) === 'object') {\n currStyle = _style;\n handleChange(currStyle);\n }\n\n if (typeof _style === 'function') {\n _style();\n }\n };\n\n return {\n stop: function stop() {\n shouldStop = true;\n },\n start: function start(style) {\n shouldStop = false;\n setStyle(style);\n },\n subscribe: function subscribe(_handleChange) {\n handleChange = _handleChange;\n return function () {\n handleChange = function handleChange() {\n return null;\n };\n };\n }\n };\n}", + "import _isPlainObject from \"lodash/isPlainObject\";\nimport _isEqual from \"lodash/isEqual\";\nimport _isArray from \"lodash/isArray\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction shallowEqual(objA, objB) {\n if (objA === objB) {\n return true;\n }\n\n if (_typeof(objA) !== 'object' || objA === null || _typeof(objB) !== 'object' || objB === null) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n var bHasOwnProperty = hasOwnProperty.bind(objB);\n\n for (var i = 0; i < keysA.length; i++) {\n var keyA = keysA[i];\n\n if (objA[keyA] === objB[keyA]) {\n continue;\n } // special diff with Array or Object\n\n\n if (_isArray(objA[keyA])) {\n if (!_isArray(objB[keyA]) || objA[keyA].length !== objB[keyA].length) {\n return false;\n } else if (!_isEqual(objA[keyA], objB[keyA])) {\n return false;\n }\n } else if (_isPlainObject(objA[keyA])) {\n if (!_isPlainObject(objB[keyA]) || !_isEqual(objA[keyA], objB[keyA])) {\n return false;\n }\n } else if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction shallowCompare(instance, nextProps, nextState) {\n return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);\n}\n\nfunction shouldComponentUpdate(nextProps, nextState) {\n return shallowCompare(this, nextProps, nextState);\n}\n/* eslint-disable no-param-reassign */\n\n\nfunction pureRenderDecorator(component) {\n component.prototype.shouldComponentUpdate = shouldComponentUpdate;\n}\n\nexport { shallowEqual };\nexport default pureRenderDecorator;", + "import _intersection from \"lodash/intersection\";\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n/* eslint no-console: 0 */\nvar PREFIX_LIST = ['Webkit', 'Moz', 'O', 'ms'];\nvar IN_LINE_PREFIX_LIST = ['-webkit-', '-moz-', '-o-', '-ms-'];\nvar IN_COMPATIBLE_PROPERTY = ['transform', 'transformOrigin', 'transition'];\nexport var getIntersectionKeys = function getIntersectionKeys(preObj, nextObj) {\n return _intersection(Object.keys(preObj), Object.keys(nextObj));\n};\nexport var identity = function identity(param) {\n return param;\n};\n/*\n * @description: convert camel case to dash case\n * string => string\n */\n\nexport var getDashCase = function getDashCase(name) {\n return name.replace(/([A-Z])/g, function (v) {\n return \"-\".concat(v.toLowerCase());\n });\n};\n/*\n * @description: add compatible style prefix\n * (string, string) => object\n */\n\nexport var generatePrefixStyle = function generatePrefixStyle(name, value) {\n if (IN_COMPATIBLE_PROPERTY.indexOf(name) === -1) {\n return _defineProperty({}, name, value);\n }\n\n var isTransition = name === 'transition';\n var camelName = name.replace(/(\\w)/, function (v) {\n return v.toUpperCase();\n });\n var styleVal = value;\n return PREFIX_LIST.reduce(function (result, property, i) {\n if (isTransition) {\n styleVal = value.replace(/(transform|transform-origin)/gim, \"\".concat(IN_LINE_PREFIX_LIST[i], \"$1\"));\n }\n\n return _objectSpread({}, result, _defineProperty({}, property + camelName, styleVal));\n }, {});\n};\nexport var log = function log() {\n var _console;\n\n (_console = console).log.apply(_console, arguments);\n};\n/*\n * @description: log the value of a varible\n * string => any => any\n */\n\nexport var debug = function debug(name) {\n return function (item) {\n log(name, item);\n return item;\n };\n};\n/*\n * @description: log name, args, return value of a function\n * function => function\n */\n\nexport var debugf = function debugf(tag, f) {\n return function () {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var res = f.apply(void 0, args);\n var name = tag || f.name || 'anonymous function';\n var argNames = \"(\".concat(args.map(JSON.stringify).join(', '), \")\");\n log(\"\".concat(name, \": \").concat(argNames, \" => \").concat(JSON.stringify(res)));\n return res;\n };\n};\n/*\n * @description: map object on every element in this object.\n * (function, object) => object\n */\n\nexport var mapObject = function mapObject(fn, obj) {\n return Object.keys(obj).reduce(function (res, key) {\n return _objectSpread({}, res, _defineProperty({}, key, fn(key, obj[key])));\n }, {});\n};\n/*\n * @description: add compatible prefix to style\n * object => object\n */\n\nexport var translateStyle = function translateStyle(style) {\n return Object.keys(style).reduce(function (res, key) {\n return _objectSpread({}, res, generatePrefixStyle(key, res[key]));\n }, style);\n};\nexport var compose = function compose() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n if (!args.length) {\n return identity;\n }\n\n var fns = args.reverse(); // first function can receive multiply arguments\n\n var firstFn = fns[0];\n var tailsFn = fns.slice(1);\n return function () {\n return tailsFn.reduce(function (res, fn) {\n return fn(res);\n }, firstFn.apply(void 0, arguments));\n };\n};\nexport var getTransitionVal = function getTransitionVal(props, duration, easing) {\n return props.map(function (prop) {\n return \"\".concat(getDashCase(prop), \" \").concat(duration, \"ms \").concat(easing);\n }).join(',');\n};\nvar isDev = process.env.NODE_ENV !== 'production';\nexport var warn = function warn(condition, format, a, b, c, d, e, f) {\n if (isDev && typeof console !== 'undefined' && console.warn) {\n if (format === undefined) {\n console.warn('LogUtils requires an error message argument');\n }\n\n if (!condition) {\n if (format === undefined) {\n console.warn('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n } else {\n var args = [a, b, c, d, e, f];\n var argIndex = 0;\n console.warn(format.replace(/%s/g, function () {\n return args[argIndex++];\n }));\n }\n }\n }\n};", + "function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nimport { warn } from './util';\nvar ACCURACY = 1e-4;\n\nvar cubicBezierFactor = function cubicBezierFactor(c1, c2) {\n return [0, 3 * c1, 3 * c2 - 6 * c1, 3 * c1 - 3 * c2 + 1];\n};\n\nvar multyTime = function multyTime(params, t) {\n return params.map(function (param, i) {\n return param * Math.pow(t, i);\n }).reduce(function (pre, curr) {\n return pre + curr;\n });\n};\n\nvar cubicBezier = function cubicBezier(c1, c2) {\n return function (t) {\n var params = cubicBezierFactor(c1, c2);\n return multyTime(params, t);\n };\n};\n\nvar derivativeCubicBezier = function derivativeCubicBezier(c1, c2) {\n return function (t) {\n var params = cubicBezierFactor(c1, c2);\n\n var newParams = _toConsumableArray(params.map(function (param, i) {\n return param * i;\n }).slice(1)).concat([0]);\n\n return multyTime(newParams, t);\n };\n}; // calculate cubic-bezier using Newton's method\n\n\nexport var configBezier = function configBezier() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var x1 = args[0],\n y1 = args[1],\n x2 = args[2],\n y2 = args[3];\n\n if (args.length === 1) {\n switch (args[0]) {\n case 'linear':\n x1 = 0.0;\n y1 = 0.0;\n x2 = 1.0;\n y2 = 1.0;\n break;\n\n case 'ease':\n x1 = 0.25;\n y1 = 0.1;\n x2 = 0.25;\n y2 = 1.0;\n break;\n\n case 'ease-in':\n x1 = 0.42;\n y1 = 0.0;\n x2 = 1.0;\n y2 = 1.0;\n break;\n\n case 'ease-out':\n x1 = 0.42;\n y1 = 0.0;\n x2 = 0.58;\n y2 = 1.0;\n break;\n\n case 'ease-in-out':\n x1 = 0.0;\n y1 = 0.0;\n x2 = 0.58;\n y2 = 1.0;\n break;\n\n default:\n warn(false, '[configBezier]: arguments should be one of ' + 'oneOf \\'linear\\', \\'ease\\', \\'ease-in\\', \\'ease-out\\', ' + '\\'ease-in-out\\', instead received %s', args);\n }\n }\n\n warn([x1, x2, y1, y2].every(function (num) {\n return typeof num === 'number' && num >= 0 && num <= 1;\n }), '[configBezier]: arguments should be x1, y1, x2, y2 of [0, 1] instead received %s', args);\n var curveX = cubicBezier(x1, x2);\n var curveY = cubicBezier(y1, y2);\n var derCurveX = derivativeCubicBezier(x1, x2);\n\n var rangeValue = function rangeValue(value) {\n if (value > 1) {\n return 1;\n } else if (value < 0) {\n return 0;\n }\n\n return value;\n };\n\n var bezier = function bezier(_t) {\n var t = _t > 1 ? 1 : _t;\n var x = t;\n\n for (var i = 0; i < 8; ++i) {\n var evalT = curveX(x) - t;\n var derVal = derCurveX(x);\n\n if (Math.abs(evalT - t) < ACCURACY || derVal < ACCURACY) {\n return curveY(x);\n }\n\n x = rangeValue(x - evalT / derVal);\n }\n\n return curveY(x);\n };\n\n bezier.isStepper = false;\n return bezier;\n};\nexport var configSpring = function configSpring() {\n var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var _config$stiff = config.stiff,\n stiff = _config$stiff === void 0 ? 100 : _config$stiff,\n _config$damping = config.damping,\n damping = _config$damping === void 0 ? 8 : _config$damping,\n _config$dt = config.dt,\n dt = _config$dt === void 0 ? 17 : _config$dt;\n\n var stepper = function stepper(currX, destX, currV) {\n var FSpring = -(currX - destX) * stiff;\n var FDamping = currV * damping;\n var newV = currV + (FSpring - FDamping) * dt / 1000;\n var newX = currV * dt / 1000 + currX;\n\n if (Math.abs(newX - destX) < ACCURACY && Math.abs(newV) < ACCURACY) {\n return [destX, 0];\n }\n\n return [newX, newV];\n };\n\n stepper.isStepper = true;\n stepper.dt = dt;\n return stepper;\n};\nexport var configEasing = function configEasing() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n var easing = args[0];\n\n if (typeof easing === 'string') {\n switch (easing) {\n case 'ease':\n case 'ease-in-out':\n case 'ease-out':\n case 'ease-in':\n case 'linear':\n return configBezier(easing);\n\n case 'spring':\n return configSpring();\n\n default:\n warn(false, '[configEasing]: first argument should be one of \\'ease\\', \\'ease-in\\', ' + '\\'ease-out\\', \\'ease-in-out\\', \\'linear\\' and \\'spring\\', instead received %s', args);\n }\n }\n\n if (typeof easing === 'function') {\n return easing;\n }\n\n warn(false, '[configEasing]: first argument type should be function or ' + 'string, instead received %s', args);\n return null;\n};", + "import _filter from \"lodash/filter\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nimport raf, { cancel as caf } from 'raf';\nimport { getIntersectionKeys, mapObject } from './util';\n\nvar alpha = function alpha(begin, end, k) {\n return begin + (end - begin) * k;\n};\n\nvar needContinue = function needContinue(_ref) {\n var from = _ref.from,\n to = _ref.to;\n return from !== to;\n};\n/*\n * @description: cal new from value and velocity in each stepper\n * @return: { [styleProperty]: { from, to, velocity } }\n */\n\n\nvar calStepperVals = function calStepperVals(easing, preVals, steps) {\n var nextStepVals = mapObject(function (key, val) {\n if (needContinue(val)) {\n var _easing = easing(val.from, val.to, val.velocity),\n _easing2 = _slicedToArray(_easing, 2),\n newX = _easing2[0],\n newV = _easing2[1];\n\n return _objectSpread({}, val, {\n from: newX,\n velocity: newV\n });\n }\n\n return val;\n }, preVals);\n\n if (steps < 1) {\n return mapObject(function (key, val) {\n if (needContinue(val)) {\n return _objectSpread({}, val, {\n velocity: alpha(val.velocity, nextStepVals[key].velocity, steps),\n from: alpha(val.from, nextStepVals[key].from, steps)\n });\n }\n\n return val;\n }, preVals);\n }\n\n return calStepperVals(easing, nextStepVals, steps - 1);\n}; // configure update function\n\n\nexport default (function (from, to, easing, duration, render) {\n var interKeys = getIntersectionKeys(from, to);\n var timingStyle = interKeys.reduce(function (res, key) {\n return _objectSpread({}, res, _defineProperty({}, key, [from[key], to[key]]));\n }, {});\n var stepperStyle = interKeys.reduce(function (res, key) {\n return _objectSpread({}, res, _defineProperty({}, key, {\n from: from[key],\n velocity: 0,\n to: to[key]\n }));\n }, {});\n var cafId = -1;\n var preTime;\n var beginTime;\n\n var update = function update() {\n return null;\n };\n\n var getCurrStyle = function getCurrStyle() {\n return mapObject(function (key, val) {\n return val.from;\n }, stepperStyle);\n };\n\n var shouldStopAnimation = function shouldStopAnimation() {\n return !_filter(stepperStyle, needContinue).length;\n }; // stepper timing function like spring\n\n\n var stepperUpdate = function stepperUpdate(now) {\n if (!preTime) {\n preTime = now;\n }\n\n var deltaTime = now - preTime;\n var steps = deltaTime / easing.dt;\n stepperStyle = calStepperVals(easing, stepperStyle, steps); // get union set and add compatible prefix\n\n render(_objectSpread({}, from, to, getCurrStyle(stepperStyle)));\n preTime = now;\n\n if (!shouldStopAnimation()) {\n cafId = raf(update);\n }\n }; // t => val timing function like cubic-bezier\n\n\n var timingUpdate = function timingUpdate(now) {\n if (!beginTime) {\n beginTime = now;\n }\n\n var t = (now - beginTime) / duration;\n var currStyle = mapObject(function (key, val) {\n return alpha.apply(void 0, _toConsumableArray(val).concat([easing(t)]));\n }, timingStyle); // get union set and add compatible prefix\n\n render(_objectSpread({}, from, to, currStyle));\n\n if (t < 1) {\n cafId = raf(update);\n } else {\n var finalStyle = mapObject(function (key, val) {\n return alpha.apply(void 0, _toConsumableArray(val).concat([easing(1)]));\n }, timingStyle);\n render(_objectSpread({}, from, to, finalStyle));\n }\n };\n\n update = easing.isStepper ? stepperUpdate : timingUpdate; // return start animation method\n\n return function () {\n raf(update); // return stop animation method\n\n return function () {\n caf(cafId);\n };\n };\n});", + "import _isEqual from \"lodash/isEqual\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nimport React, { Component, cloneElement, Children } from 'react';\nimport PropTypes from 'prop-types';\nimport createAnimateManager from './AnimateManager';\nimport pureRender from './PureRender';\nimport { configEasing } from './easing';\nimport configUpdate from './configUpdate';\nimport { getTransitionVal, identity, translateStyle } from './util';\n\nvar Animate = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Animate, _Component);\n\n function Animate(props, context) {\n var _this;\n\n _classCallCheck(this, Animate);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(Animate).call(this, props, context));\n var _this$props = _this.props,\n isActive = _this$props.isActive,\n attributeName = _this$props.attributeName,\n from = _this$props.from,\n to = _this$props.to,\n steps = _this$props.steps,\n children = _this$props.children;\n _this.handleStyleChange = _this.handleStyleChange.bind(_assertThisInitialized(_assertThisInitialized(_this)));\n _this.changeStyle = _this.changeStyle.bind(_assertThisInitialized(_assertThisInitialized(_this)));\n\n if (!isActive) {\n _this.state = {\n style: {}\n }; // if children is a function and animation is not active, set style to 'to'\n\n if (typeof children === 'function') {\n _this.state = {\n style: to\n };\n }\n\n return _possibleConstructorReturn(_this);\n }\n\n if (steps && steps.length) {\n _this.state = {\n style: steps[0].style\n };\n } else if (from) {\n if (typeof children === 'function') {\n _this.state = {\n style: from\n };\n return _possibleConstructorReturn(_this);\n }\n\n _this.state = {\n style: attributeName ? _defineProperty({}, attributeName, from) : from\n };\n } else {\n _this.state = {\n style: {}\n };\n }\n\n return _this;\n }\n\n _createClass(Animate, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this$props2 = this.props,\n isActive = _this$props2.isActive,\n canBegin = _this$props2.canBegin;\n this.mounted = true;\n\n if (!isActive || !canBegin) {\n return;\n }\n\n this.runAnimation(this.props);\n }\n }, {\n key: \"componentWillReceiveProps\",\n value: function componentWillReceiveProps(nextProps) {\n var isActive = nextProps.isActive,\n canBegin = nextProps.canBegin,\n attributeName = nextProps.attributeName,\n shouldReAnimate = nextProps.shouldReAnimate;\n\n if (!canBegin) {\n return;\n }\n\n if (!isActive) {\n this.setState({\n style: attributeName ? _defineProperty({}, attributeName, nextProps.to) : nextProps.to\n });\n return;\n }\n\n if (_isEqual(this.props.to, nextProps.to) && this.props.canBegin && this.props.isActive) {\n return;\n }\n\n var isTriggered = !this.props.canBegin || !this.props.isActive;\n\n if (this.manager) {\n this.manager.stop();\n }\n\n if (this.stopJSAnimation) {\n this.stopJSAnimation();\n }\n\n var from = isTriggered || shouldReAnimate ? nextProps.from : this.props.to;\n this.setState({\n style: attributeName ? _defineProperty({}, attributeName, from) : from\n });\n this.runAnimation(_objectSpread({}, nextProps, {\n from: from,\n begin: 0\n }));\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.mounted = false;\n\n if (this.unSubscribe) {\n this.unSubscribe();\n }\n\n if (this.manager) {\n this.manager.stop();\n this.manager = null;\n }\n\n if (this.stopJSAnimation) {\n this.stopJSAnimation();\n }\n }\n }, {\n key: \"runJSAnimation\",\n value: function runJSAnimation(props) {\n var _this2 = this;\n\n var from = props.from,\n to = props.to,\n duration = props.duration,\n easing = props.easing,\n begin = props.begin,\n onAnimationEnd = props.onAnimationEnd,\n onAnimationStart = props.onAnimationStart;\n var startAnimation = configUpdate(from, to, configEasing(easing), duration, this.changeStyle);\n\n var finalStartAnimation = function finalStartAnimation() {\n _this2.stopJSAnimation = startAnimation();\n };\n\n this.manager.start([onAnimationStart, begin, finalStartAnimation, duration, onAnimationEnd]);\n }\n }, {\n key: \"runStepAnimation\",\n value: function runStepAnimation(props) {\n var _this3 = this;\n\n var steps = props.steps,\n begin = props.begin,\n onAnimationStart = props.onAnimationStart;\n var _steps$ = steps[0],\n initialStyle = _steps$.style,\n _steps$$duration = _steps$.duration,\n initialTime = _steps$$duration === void 0 ? 0 : _steps$$duration;\n\n var addStyle = function addStyle(sequence, nextItem, index) {\n if (index === 0) {\n return sequence;\n }\n\n var duration = nextItem.duration,\n _nextItem$easing = nextItem.easing,\n easing = _nextItem$easing === void 0 ? 'ease' : _nextItem$easing,\n style = nextItem.style,\n nextProperties = nextItem.properties,\n onAnimationEnd = nextItem.onAnimationEnd;\n var preItem = index > 0 ? steps[index - 1] : nextItem;\n var properties = nextProperties || Object.keys(style);\n\n if (typeof easing === 'function' || easing === 'spring') {\n return _toConsumableArray(sequence).concat([_this3.runJSAnimation.bind(_this3, {\n from: preItem.style,\n to: style,\n duration: duration,\n easing: easing\n }), duration]);\n }\n\n var transition = getTransitionVal(properties, duration, easing);\n\n var newStyle = _objectSpread({}, preItem.style, style, {\n transition: transition\n });\n\n return _toConsumableArray(sequence).concat([newStyle, duration, onAnimationEnd]).filter(identity);\n };\n\n return this.manager.start([onAnimationStart].concat(_toConsumableArray(steps.reduce(addStyle, [initialStyle, Math.max(initialTime, begin)])), [props.onAnimationEnd]));\n }\n }, {\n key: \"runAnimation\",\n value: function runAnimation(props) {\n if (!this.manager) {\n this.manager = createAnimateManager();\n }\n\n var begin = props.begin,\n duration = props.duration,\n attributeName = props.attributeName,\n propsTo = props.to,\n easing = props.easing,\n onAnimationStart = props.onAnimationStart,\n onAnimationEnd = props.onAnimationEnd,\n steps = props.steps,\n children = props.children;\n var manager = this.manager;\n this.unSubscribe = manager.subscribe(this.handleStyleChange);\n\n if (typeof easing === 'function' || typeof children === 'function' || easing === 'spring') {\n this.runJSAnimation(props);\n return;\n }\n\n if (steps.length > 1) {\n this.runStepAnimation(props);\n return;\n }\n\n var to = attributeName ? _defineProperty({}, attributeName, propsTo) : propsTo;\n var transition = getTransitionVal(Object.keys(to), duration, easing);\n manager.start([onAnimationStart, begin, _objectSpread({}, to, {\n transition: transition\n }), duration, onAnimationEnd]);\n }\n }, {\n key: \"handleStyleChange\",\n value: function handleStyleChange(style) {\n this.changeStyle(style);\n }\n }, {\n key: \"changeStyle\",\n value: function changeStyle(style) {\n if (this.mounted) {\n this.setState({\n style: style\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props3 = this.props,\n children = _this$props3.children,\n begin = _this$props3.begin,\n duration = _this$props3.duration,\n attributeName = _this$props3.attributeName,\n easing = _this$props3.easing,\n isActive = _this$props3.isActive,\n steps = _this$props3.steps,\n from = _this$props3.from,\n to = _this$props3.to,\n canBegin = _this$props3.canBegin,\n onAnimationEnd = _this$props3.onAnimationEnd,\n shouldReAnimate = _this$props3.shouldReAnimate,\n onAnimationReStart = _this$props3.onAnimationReStart,\n others = _objectWithoutProperties(_this$props3, [\"children\", \"begin\", \"duration\", \"attributeName\", \"easing\", \"isActive\", \"steps\", \"from\", \"to\", \"canBegin\", \"onAnimationEnd\", \"shouldReAnimate\", \"onAnimationReStart\"]);\n\n var count = Children.count(children);\n var stateStyle = translateStyle(this.state.style);\n\n if (typeof children === 'function') {\n return children(stateStyle);\n }\n\n if (!isActive || count === 0) {\n return children;\n }\n\n var cloneContainer = function cloneContainer(container) {\n var _container$props = container.props,\n _container$props$styl = _container$props.style,\n style = _container$props$styl === void 0 ? {} : _container$props$styl,\n className = _container$props.className;\n var res = cloneElement(container, _objectSpread({}, others, {\n style: _objectSpread({}, style, stateStyle),\n className: className\n }));\n return res;\n };\n\n if (count === 1) {\n return cloneContainer(Children.only(children));\n }\n\n return React.createElement(\"div\", null, Children.map(children, function (child) {\n return cloneContainer(child);\n }));\n }\n }]);\n\n return Animate;\n}(Component), _class2.displayName = 'Animate', _class2.propTypes = {\n from: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),\n to: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),\n attributeName: PropTypes.string,\n // animation duration\n duration: PropTypes.number,\n begin: PropTypes.number,\n easing: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n steps: PropTypes.arrayOf(PropTypes.shape({\n duration: PropTypes.number.isRequired,\n style: PropTypes.object.isRequired,\n easing: PropTypes.oneOfType([PropTypes.oneOf(['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear']), PropTypes.func]),\n // transition css properties(dash case), optional\n properties: PropTypes.arrayOf('string'),\n onAnimationEnd: PropTypes.func\n })),\n children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),\n isActive: PropTypes.bool,\n canBegin: PropTypes.bool,\n onAnimationEnd: PropTypes.func,\n // decide if it should reanimate with initial from style when props change\n shouldReAnimate: PropTypes.bool,\n onAnimationStart: PropTypes.func,\n onAnimationReStart: PropTypes.func\n}, _class2.defaultProps = {\n begin: 0,\n duration: 1000,\n from: '',\n to: '',\n attributeName: '',\n easing: 'ease',\n isActive: true,\n canBegin: true,\n steps: [],\n onAnimationEnd: function onAnimationEnd() {},\n onAnimationStart: function onAnimationStart() {}\n}, _temp)) || _class;\n\nexport default Animate;", + "import _isNumber from \"lodash/isNumber\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport React, { Component, Children } from 'react';\nimport { Transition } from 'react-transition-group';\nimport PropTypes from 'prop-types';\nimport Animate from './Animate';\n\nvar parseDurationOfSingleTransition = function parseDurationOfSingleTransition() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var steps = options.steps,\n duration = options.duration;\n\n if (steps && steps.length) {\n return steps.reduce(function (result, entry) {\n return result + (_isNumber(entry.duration) && entry.duration > 0 ? entry.duration : 0);\n }, 0);\n }\n\n if (_isNumber(duration)) {\n return duration;\n }\n\n return 0;\n};\n\nvar AnimateGroupChild =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(AnimateGroupChild, _Component);\n\n function AnimateGroupChild() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, AnimateGroupChild);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(AnimateGroupChild)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n isActive: false\n };\n\n _this.handleEnter = function (node, isAppearing) {\n var _this$props = _this.props,\n appearOptions = _this$props.appearOptions,\n enterOptions = _this$props.enterOptions;\n\n _this.handleStyleActive(isAppearing ? appearOptions : enterOptions);\n };\n\n _this.handleExit = function () {\n _this.handleStyleActive(_this.props.leaveOptions);\n };\n\n return _this;\n }\n\n _createClass(AnimateGroupChild, [{\n key: \"handleStyleActive\",\n value: function handleStyleActive(style) {\n if (style) {\n var onAnimationEnd = style.onAnimationEnd ? function () {\n style.onAnimationEnd();\n } : null;\n this.setState(_objectSpread({}, style, {\n onAnimationEnd: onAnimationEnd,\n isActive: true\n }));\n }\n }\n }, {\n key: \"parseTimeout\",\n value: function parseTimeout() {\n var _this$props2 = this.props,\n appearOptions = _this$props2.appearOptions,\n enterOptions = _this$props2.enterOptions,\n leaveOptions = _this$props2.leaveOptions;\n return parseDurationOfSingleTransition(appearOptions) + parseDurationOfSingleTransition(enterOptions) + parseDurationOfSingleTransition(leaveOptions);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props3 = this.props,\n children = _this$props3.children,\n appearOptions = _this$props3.appearOptions,\n enterOptions = _this$props3.enterOptions,\n leaveOptions = _this$props3.leaveOptions,\n props = _objectWithoutProperties(_this$props3, [\"children\", \"appearOptions\", \"enterOptions\", \"leaveOptions\"]);\n\n return React.createElement(Transition, _extends({}, props, {\n onEnter: this.handleEnter,\n onExit: this.handleExit,\n timeout: this.parseTimeout()\n }), function () {\n return React.createElement(Animate, _this2.state, Children.only(children));\n });\n }\n }]);\n\n return AnimateGroupChild;\n}(Component);\n\nAnimateGroupChild.propTypes = {\n appearOptions: PropTypes.object,\n enterOptions: PropTypes.object,\n leaveOptions: PropTypes.object,\n children: PropTypes.element\n};\nexport default AnimateGroupChild;", + "import React, { Children } from 'react';\nimport { TransitionGroup } from 'react-transition-group';\nimport PropTypes from 'prop-types';\nimport AnimateGroupChild from './AnimateGroupChild';\n\nfunction AnimateGroup(props) {\n var component = props.component,\n children = props.children,\n appear = props.appear,\n enter = props.enter,\n leave = props.leave;\n return React.createElement(TransitionGroup, {\n component: component\n }, Children.map(children, function (child, index) {\n return React.createElement(AnimateGroupChild, {\n appearOptions: appear,\n enterOptions: enter,\n leaveOptions: leave,\n key: \"child-\".concat(index)\n }, child);\n }));\n}\n\nAnimateGroup.propTypes = {\n appear: PropTypes.object,\n enter: PropTypes.object,\n leave: PropTypes.object,\n children: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),\n component: PropTypes.any\n};\nAnimateGroup.defaultProps = {\n component: 'span'\n};\nexport default AnimateGroup;", + "import Animate from './Animate';\nimport { configBezier, configSpring } from './easing';\nimport { translateStyle } from './util';\nimport AnimateGroup from './AnimateGroup';\nexport { configSpring, configBezier, AnimateGroup, translateStyle };\nexport default Animate;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = void 0;\n\nvar PropTypes = _interopRequireWildcard(require(\"prop-types\"));\n\nvar _addClass = _interopRequireDefault(require(\"dom-helpers/class/addClass\"));\n\nvar _removeClass = _interopRequireDefault(require(\"dom-helpers/class/removeClass\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _Transition = _interopRequireDefault(require(\"./Transition\"));\n\nvar _PropTypes = require(\"./utils/PropTypes\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nvar addClass = function addClass(node, classes) {\n return node && classes && classes.split(' ').forEach(function (c) {\n return (0, _addClass.default)(node, c);\n });\n};\n\nvar removeClass = function removeClass(node, classes) {\n return node && classes && classes.split(' ').forEach(function (c) {\n return (0, _removeClass.default)(node, c);\n });\n};\n/**\n * A transition component inspired by the excellent\n * [ng-animate](http://www.nganimate.org/) library, you should use it if you're\n * using CSS transitions or animations. It's built upon the\n * [`))) + (("`" + (`Transition` + "`")) + (`](https://reactcommunity.org/react-transition-group/transition)\n * component, so it inherits all of its props.\n *\n * ` + ("`" + `CSSTransition`)))) + ((("`" + (` applies a pair of class names during the ` + "`")) + (`appear` + ("`" + `, `))) + (("`" + (`enter` + "`")) + ((`,\n * and ` + "`") + (`exit` + "`"))))) + ((((` states of the transition. The first class is applied and then a\n * second ` + ("`" + `*-active`)) + ("`" + (` class in order to activate the CSSS transition. After the\n * transition, matching ` + "`"))) + ((`*-done` + ("`" + ` class names are applied to persist the\n * transition state.\n *\n * `)) + ("`" + ("`" + "`")))) + (((`jsx\n * function App() {\n * const [inProp, setInProp] = useState(false);\n * return (\n *
\n * \n *
\n * {\"I'll receive my-node-* classes\"}\n *
\n *
\n * \n *
\n * );\n * }\n * ` + ("`" + "`")) + ("`" + (`\n *\n * When the ` + "`"))) + ((`in` + ("`" + ` prop is set to `)) + (("`" + `true`) + ("`" + `, the child component will first receive\n * the class `)))))) + ((((("`" + (`example-enter` + "`")) + (`, then the ` + ("`" + `example-enter-active`))) + (("`" + (` will be added in\n * the next tick. ` + "`")) + (`CSSTransition` + ("`" + ` [forces a\n * reflow](https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215)\n * between before adding the `)))) + ((("`" + (`example-enter-active` + "`")) + (`. This is an important trick\n * because it allows us to transition between ` + ("`" + `example-enter`))) + (("`" + (` and\n * ` + "`")) + ((`example-enter-active` + "`") + (` even though they were added immediately one after\n * another. Most notably, this is what makes it possible for us to animate\n * _appearance_.\n *\n * ` + "`"))))) + (((("`" + ("`" + `css\n * .my-node-enter {\n * opacity: 0;\n * }\n * .my-node-enter-active {\n * opacity: 1;\n * transition: opacity 200ms;\n * }\n * .my-node-exit {\n * opacity: 1;\n * }\n * .my-node-exit-active {\n * opacity: 0;\n * transition: opacity: 200ms;\n * }\n * `)) + ("`" + ("`" + "`"))) + ((`\n *\n * ` + ("`" + `*-active`)) + ("`" + (` classes represent which styles you want to animate **to**.\n */\n\n\nvar CSSTransition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(CSSTransition, _React$Component);\n\n function CSSTransition() {\n var _this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;\n\n _this.onEnter = function (node, appearing) {\n var _this$getClassNames = _this.getClassNames(appearing ? 'appear' : 'enter'),\n className = _this$getClassNames.className;\n\n _this.removeClasses(node, 'exit');\n\n addClass(node, className);\n\n if (_this.props.onEnter) {\n _this.props.onEnter(node, appearing);\n }\n };\n\n _this.onEntering = function (node, appearing) {\n var _this$getClassNames2 = _this.getClassNames(appearing ? 'appear' : 'enter'),\n activeClassName = _this$getClassNames2.activeClassName;\n\n _this.reflowAndAddClass(node, activeClassName);\n\n if (_this.props.onEntering) {\n _this.props.onEntering(node, appearing);\n }\n };\n\n _this.onEntered = function (node, appearing) {\n var appearClassName = _this.getClassNames('appear').doneClassName;\n\n var enterClassName = _this.getClassNames('enter').doneClassName;\n\n var doneClassName = appearing ? appearClassName + \" \" + enterClassName : enterClassName;\n\n _this.removeClasses(node, appearing ? 'appear' : 'enter');\n\n addClass(node, doneClassName);\n\n if (_this.props.onEntered) {\n _this.props.onEntered(node, appearing);\n }\n };\n\n _this.onExit = function (node) {\n var _this$getClassNames3 = _this.getClassNames('exit'),\n className = _this$getClassNames3.className;\n\n _this.removeClasses(node, 'appear');\n\n _this.removeClasses(node, 'enter');\n\n addClass(node, className);\n\n if (_this.props.onExit) {\n _this.props.onExit(node);\n }\n };\n\n _this.onExiting = function (node) {\n var _this$getClassNames4 = _this.getClassNames('exit'),\n activeClassName = _this$getClassNames4.activeClassName;\n\n _this.reflowAndAddClass(node, activeClassName);\n\n if (_this.props.onExiting) {\n _this.props.onExiting(node);\n }\n };\n\n _this.onExited = function (node) {\n var _this$getClassNames5 = _this.getClassNames('exit'),\n doneClassName = _this$getClassNames5.doneClassName;\n\n _this.removeClasses(node, 'exit');\n\n addClass(node, doneClassName);\n\n if (_this.props.onExited) {\n _this.props.onExited(node);\n }\n };\n\n _this.getClassNames = function (type) {\n var classNames = _this.props.classNames;\n var isStringClassNames = typeof classNames === 'string';\n var prefix = isStringClassNames && classNames ? classNames + '-' : '';\n var className = isStringClassNames ? prefix + type : classNames[type];\n var activeClassName = isStringClassNames ? className + '-active' : classNames[type + 'Active'];\n var doneClassName = isStringClassNames ? className + '-done' : classNames[type + 'Done'];\n return {\n className: className,\n activeClassName: activeClassName,\n doneClassName: doneClassName\n };\n };\n\n return _this;\n }\n\n var _proto = CSSTransition.prototype;\n\n _proto.removeClasses = function removeClasses(node, type) {\n var _this$getClassNames6 = this.getClassNames(type),\n className = _this$getClassNames6.className,\n activeClassName = _this$getClassNames6.activeClassName,\n doneClassName = _this$getClassNames6.doneClassName;\n\n className && removeClass(node, className);\n activeClassName && removeClass(node, activeClassName);\n doneClassName && removeClass(node, doneClassName);\n };\n\n _proto.reflowAndAddClass = function reflowAndAddClass(node, className) {\n // This is for to force a repaint,\n // which is necessary in order to transition styles when adding a class name.\n if (className) {\n /* eslint-disable no-unused-expressions */\n node && node.scrollTop;\n /* eslint-enable no-unused-expressions */\n\n addClass(node, className);\n }\n };\n\n _proto.render = function render() {\n var props = _extends({}, this.props);\n\n delete props.classNames;\n return _react.default.createElement(_Transition.default, _extends({}, props, {\n onEnter: this.onEnter,\n onEntered: this.onEntered,\n onEntering: this.onEntering,\n onExit: this.onExit,\n onExiting: this.onExiting,\n onExited: this.onExited\n }));\n };\n\n return CSSTransition;\n}(_react.default.Component);\n\nCSSTransition.defaultProps = {\n classNames: ''\n};\nCSSTransition.propTypes = process.env.NODE_ENV !== \"production\" ? _extends({}, _Transition.default.propTypes, {\n /**\n * The animation classNames applied to the component as it enters, exits or\n * has finished the transition. A single name can be provided and it will be\n * suffixed for each stage: e.g.\n *\n * ` + "`")))) + (((`classNames=\"fade\"` + ("`" + ` applies `)) + ("`" + (`fade-enter` + "`"))) + ((`, ` + ("`" + `fade-enter-active`)) + (("`" + `,\n * `) + ("`" + `fade-enter-done`)))))))))) + ((((((((("`" + (`, ` + "`")) + (`fade-exit` + ("`" + `, `))) + (("`" + (`fade-exit-active` + "`")) + (`, ` + ("`" + `fade-exit-done`)))) + ((("`" + (`,\n * ` + "`")) + (`fade-appear` + ("`" + `, `))) + (("`" + (`fade-appear-active` + "`")) + (`, and ` + ("`" + `fade-appear-done`))))) + (((("`" + (`.\n *\n * **Note**: ` + "`")) + (`fade-appear-done` + ("`" + ` and `))) + (("`" + (`fade-enter-done` + "`")) + (` will _both_ be applied.\n * This allows you to define different behavior for when appearing is done and\n * when regular entering is done, using selectors like\n * ` + ("`" + `.fade-enter-done:not(.fade-appear-done)`)))) + ((("`" + (`. For example, you could apply an\n * epic entrance animation when element first appears in the DOM using\n * [Animate.css](https://daneden.github.io/animate.css/). Otherwise you can\n * simply use ` + "`")) + (`fade-enter-done` + ("`" + ` for defining both cases.\n *\n * Each individual classNames can also be specified independently like:\n *\n * `))) + (("`" + ("`" + "`")) + ((`js\n * classNames={{\n * appear: 'my-appear',\n * appearActive: 'my-active-appear',\n * appearDone: 'my-done-appear',\n * enter: 'my-enter',\n * enterActive: 'my-active-enter',\n * enterDone: 'my-done-enter',\n * exit: 'my-exit',\n * exitActive: 'my-active-exit',\n * exitDone: 'my-done-exit',\n * }}\n * ` + "`") + ("`" + "`")))))) + (((((`\n *\n * If you want to set these classes using CSS Modules:\n *\n * ` + ("`" + "`")) + ("`" + (`js\n * import styles from './styles.css';\n * ` + "`"))) + (("`" + ("`" + `\n *\n * you might want to use camelCase in your CSS file, that way could simply\n * spread them instead of listing them one by one:\n *\n * `)) + ("`" + ("`" + "`")))) + (((`js\n * classNames={{ ...styles }}\n * ` + ("`" + "`")) + ("`" + (`\n *\n * @type {string | {\n * appear?: string,\n * appearActive?: string,\n * appearDone?: string,\n * enter?: string,\n * enterActive?: string,\n * enterDone?: string,\n * exit?: string,\n * exitActive?: string,\n * exitDone?: string,\n * }}\n */\n classNames: _PropTypes.classNamesShape,\n\n /**\n * A ` + "`"))) + ((`` + ("`" + ` callback fired immediately after the 'enter' or 'appear' class is\n * applied.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEnter: PropTypes.func,\n\n /**\n * A `)) + (("`" + ``) + ("`" + ` callback fired immediately after the 'enter-active' or\n * 'appear-active' class is applied.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * A `))))) + (((("`" + (`` + "`")) + (` callback fired immediately after the 'enter' or\n * 'appear' classes are **removed** and the ` + ("`" + `done`))) + (("`" + (` class is added to the DOM node.\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntered: PropTypes.func,\n\n /**\n * A ` + "`")) + (`` + ("`" + ` callback fired immediately after the 'exit' class is\n * applied.\n *\n * @type Function(node: HtmlElement)\n */\n onExit: PropTypes.func,\n\n /**\n * A `)))) + ((("`" + (`` + "`")) + (` callback fired immediately after the 'exit-active' is applied.\n *\n * @type Function(node: HtmlElement)\n */\n onExiting: PropTypes.func,\n\n /**\n * A ` + ("`" + ``))) + (("`" + (` callback fired immediately after the 'exit' classes\n * are **removed** and the ` + "`")) + ((`exit-done` + "`") + (` class is added to the DOM node.\n *\n * @type Function(node: HtmlElement)\n */\n onExited: PropTypes.func\n}) : {};\nvar _default = CSSTransition;\nexports.default = _default;\nmodule.exports = exports[\"default\"];", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactDom = require(\"react-dom\");\n\nvar _TransitionGroup = _interopRequireDefault(require(\"./TransitionGroup\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\n/**\n * The ` + "`"))))))) + ((((((`` + ("`" + ` component is a specialized `)) + ("`" + (`Transition` + "`"))) + ((` component\n * that animates between two children.\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * \n *
I appear first
\n *
I replace the above
\n *
\n * ` + "`")))) + ((("`" + ("`" + `\n */\nvar ReplaceTransition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(ReplaceTransition, _React$Component);\n\n function ReplaceTransition() {\n var _this;\n\n for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {\n _args[_key] = arguments[_key];\n }\n\n _this = _React$Component.call.apply(_React$Component, [this].concat(_args)) || this;\n\n _this.handleEnter = function () {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return _this.handleLifecycle('onEnter', 0, args);\n };\n\n _this.handleEntering = function () {\n for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n args[_key3] = arguments[_key3];\n }\n\n return _this.handleLifecycle('onEntering', 0, args);\n };\n\n _this.handleEntered = function () {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n\n return _this.handleLifecycle('onEntered', 0, args);\n };\n\n _this.handleExit = function () {\n for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n args[_key5] = arguments[_key5];\n }\n\n return _this.handleLifecycle('onExit', 1, args);\n };\n\n _this.handleExiting = function () {\n for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n args[_key6] = arguments[_key6];\n }\n\n return _this.handleLifecycle('onExiting', 1, args);\n };\n\n _this.handleExited = function () {\n for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {\n args[_key7] = arguments[_key7];\n }\n\n return _this.handleLifecycle('onExited', 1, args);\n };\n\n return _this;\n }\n\n var _proto = ReplaceTransition.prototype;\n\n _proto.handleLifecycle = function handleLifecycle(handler, idx, originalArgs) {\n var _child$props;\n\n var children = this.props.children;\n\n var child = _react.default.Children.toArray(children)[idx];\n\n if (child.props[handler]) (_child$props = child.props)[handler].apply(_child$props, originalArgs);\n if (this.props[handler]) this.props[handler]((0, _reactDom.findDOMNode)(this));\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n children = _this$props.children,\n inProp = _this$props.in,\n props = _objectWithoutPropertiesLoose(_this$props, [\"children\", \"in\"]);\n\n var _React$Children$toArr = _react.default.Children.toArray(children),\n first = _React$Children$toArr[0],\n second = _React$Children$toArr[1];\n\n delete props.onEnter;\n delete props.onEntering;\n delete props.onEntered;\n delete props.onExit;\n delete props.onExiting;\n delete props.onExited;\n return _react.default.createElement(_TransitionGroup.default, props, inProp ? _react.default.cloneElement(first, {\n key: 'first',\n onEnter: this.handleEnter,\n onEntering: this.handleEntering,\n onEntered: this.handleEntered\n }) : _react.default.cloneElement(second, {\n key: 'second',\n onEnter: this.handleExit,\n onEntering: this.handleExiting,\n onEntered: this.handleExited\n }));\n };\n\n return ReplaceTransition;\n}(_react.default.Component);\n\nReplaceTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n in: _propTypes.default.bool.isRequired,\n children: function children(props, propName) {\n if (_react.default.Children.count(props[propName]) !== 2) return new Error(\"\\\"\" + propName + \"\\\" must be exactly two transition components.\");\n return null;\n }\n} : {};\nvar _default = ReplaceTransition;\nexports.default = _default;\nmodule.exports = exports[\"default\"];", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = exports.EXITING = exports.ENTERED = exports.ENTERING = exports.EXITED = exports.UNMOUNTED = void 0;\n\nvar PropTypes = _interopRequireWildcard(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactDom = _interopRequireDefault(require(\"react-dom\"));\n\nvar _reactLifecyclesCompat = require(\"react-lifecycles-compat\");\n\nvar _PropTypes = require(\"./utils/PropTypes\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nvar UNMOUNTED = 'unmounted';\nexports.UNMOUNTED = UNMOUNTED;\nvar EXITED = 'exited';\nexports.EXITED = EXITED;\nvar ENTERING = 'entering';\nexports.ENTERING = ENTERING;\nvar ENTERED = 'entered';\nexports.ENTERED = ENTERED;\nvar EXITING = 'exiting';\n/**\n * The Transition component lets you describe a transition from one component\n * state to another _over time_ with a simple declarative API. Most commonly\n * it's used to animate the mounting and unmounting of a component, but can also\n * be used to describe in-place transition states as well.\n *\n * ---\n *\n * **Note**: `)) + ("`" + (`Transition` + "`"))) + ((` is a platform-agnostic base component. If you're using\n * transitions in CSS, you'll probably want to use\n * [` + ("`" + `CSSTransition`)) + ("`" + (`](https://reactcommunity.org/react-transition-group/css-transition)\n * instead. It inherits all the features of ` + "`"))))) + ((((`Transition` + ("`" + `, but contains\n * additional features necessary to play nice with CSS transitions (hence the\n * name of the component).\n *\n * ---\n *\n * By default the `)) + ("`" + (`Transition` + "`"))) + ((` component does not alter the behavior of the\n * component it renders, it only tracks \"enter\" and \"exit\" states for the\n * components. It's up to you to give meaning and effect to those states. For\n * example we can add styles to a component when it enters or exits:\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * import { Transition } from 'react-transition-group';\n *\n * const duration = 300;\n *\n * const defaultStyle = {\n * transition: ` + "`")))) + (((`opacity ${duration}ms ease-in-out` + ("`" + `,\n * opacity: 0,\n * }\n *\n * const transitionStyles = {\n * entering: { opacity: 0 },\n * entered: { opacity: 1 },\n * };\n *\n * const Fade = ({ in: inProp }) => (\n * \n * {state => (\n *
\n * I'm a fade Transition!\n *
\n * )}\n *
\n * );\n * `)) + ("`" + ("`" + "`"))) + ((`\n *\n * There are 4 main states a Transition can be in:\n * - ` + ("`" + `'entering'`)) + (("`" + `\n * - `) + ("`" + `'entered'`)))))) + ((((("`" + (`\n * - ` + "`")) + (`'exiting'` + ("`" + `\n * - `))) + (("`" + (`'exited'` + "`")) + (`\n *\n * Transition state is toggled via the ` + ("`" + `in`)))) + ((("`" + (` prop. When ` + "`")) + (`true` + ("`" + ` the component\n * begins the \"Enter\" stage. During this stage, the component will shift from\n * its current transition state, to `))) + (("`" + (`'entering'` + "`")) + ((` for the duration of the\n * transition and then to the ` + "`") + (`'entered'` + "`"))))) + ((((` stage once it's complete. Let's take\n * the following example (we'll use the\n * [useState](https://reactjs.org/docs/hooks-reference.html#usestate) hook):\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * function App() {\n * const [inProp, setInProp] = useState(false);\n * return (\n *
\n * \n * {state => (\n * // ...\n * )}\n * \n * \n *
\n * );\n * }\n * ` + "`"))) + (("`" + ("`" + `\n *\n * When the button is clicked the component will shift to the `)) + ("`" + (`'entering'` + "`")))) + (((` state\n * and stay there for 500ms (the value of ` + ("`" + `timeout`)) + ("`" + (`) before it finally switches\n * to ` + "`"))) + ((`'entered'` + ("`" + `.\n *\n * When `)) + (("`" + `in`) + ("`" + ` is `)))))))) + ((((((("`" + (`false` + "`")) + (` the same thing happens except the state moves from\n * ` + ("`" + `'exiting'`))) + (("`" + (` to ` + "`")) + (`'exited'` + ("`" + `.\n */\n\nexports.EXITING = EXITING;\n\nvar Transition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(Transition, _React$Component);\n\n function Transition(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n var parentGroup = context.transitionGroup; // In the context of a TransitionGroup all enters are really appears\n\n var appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n var initialStatus;\n _this.appearStatus = null;\n\n if (props.in) {\n if (appear) {\n initialStatus = EXITED;\n _this.appearStatus = ENTERING;\n } else {\n initialStatus = ENTERED;\n }\n } else {\n if (props.unmountOnExit || props.mountOnEnter) {\n initialStatus = UNMOUNTED;\n } else {\n initialStatus = EXITED;\n }\n }\n\n _this.state = {\n status: initialStatus\n };\n _this.nextCallback = null;\n return _this;\n }\n\n var _proto = Transition.prototype;\n\n _proto.getChildContext = function getChildContext() {\n return {\n transitionGroup: null // allows for nested Transitions\n\n };\n };\n\n Transition.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var nextIn = _ref.in;\n\n if (nextIn && prevState.status === UNMOUNTED) {\n return {\n status: EXITED\n };\n }\n\n return null;\n }; // getSnapshotBeforeUpdate(prevProps) {\n // let nextStatus = null\n // if (prevProps !== this.props) {\n // const { status } = this.state\n // if (this.props.in) {\n // if (status !== ENTERING && status !== ENTERED) {\n // nextStatus = ENTERING\n // }\n // } else {\n // if (status === ENTERING || status === ENTERED) {\n // nextStatus = EXITING\n // }\n // }\n // }\n // return { nextStatus }\n // }\n\n\n _proto.componentDidMount = function componentDidMount() {\n this.updateStatus(true, this.appearStatus);\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var nextStatus = null;\n\n if (prevProps !== this.props) {\n var status = this.state.status;\n\n if (this.props.in) {\n if (status !== ENTERING && status !== ENTERED) {\n nextStatus = ENTERING;\n }\n } else {\n if (status === ENTERING || status === ENTERED) {\n nextStatus = EXITING;\n }\n }\n }\n\n this.updateStatus(false, nextStatus);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.cancelNextCallback();\n };\n\n _proto.getTimeouts = function getTimeouts() {\n var timeout = this.props.timeout;\n var exit, enter, appear;\n exit = enter = appear = timeout;\n\n if (timeout != null && typeof timeout !== 'number') {\n exit = timeout.exit;\n enter = timeout.enter; // TODO: remove fallback for next major\n\n appear = timeout.appear !== undefined ? timeout.appear : enter;\n }\n\n return {\n exit: exit,\n enter: enter,\n appear: appear\n };\n };\n\n _proto.updateStatus = function updateStatus(mounting, nextStatus) {\n if (mounting === void 0) {\n mounting = false;\n }\n\n if (nextStatus !== null) {\n // nextStatus will always be ENTERING or EXITING.\n this.cancelNextCallback();\n\n var node = _reactDom.default.findDOMNode(this);\n\n if (nextStatus === ENTERING) {\n this.performEnter(node, mounting);\n } else {\n this.performExit(node);\n }\n } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n this.setState({\n status: UNMOUNTED\n });\n }\n };\n\n _proto.performEnter = function performEnter(node, mounting) {\n var _this2 = this;\n\n var enter = this.props.enter;\n var appearing = this.context.transitionGroup ? this.context.transitionGroup.isMounting : mounting;\n var timeouts = this.getTimeouts();\n var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED\n // if we are mounting and running this it means appear _must_ be set\n\n if (!mounting && !enter) {\n this.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node);\n });\n return;\n }\n\n this.props.onEnter(node, appearing);\n this.safeSetState({\n status: ENTERING\n }, function () {\n _this2.props.onEntering(node, appearing);\n\n _this2.onTransitionEnd(node, enterTimeout, function () {\n _this2.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node, appearing);\n });\n });\n });\n };\n\n _proto.performExit = function performExit(node) {\n var _this3 = this;\n\n var exit = this.props.exit;\n var timeouts = this.getTimeouts(); // no exit animation skip right to EXITED\n\n if (!exit) {\n this.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n return;\n }\n\n this.props.onExit(node);\n this.safeSetState({\n status: EXITING\n }, function () {\n _this3.props.onExiting(node);\n\n _this3.onTransitionEnd(node, timeouts.exit, function () {\n _this3.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n });\n });\n };\n\n _proto.cancelNextCallback = function cancelNextCallback() {\n if (this.nextCallback !== null) {\n this.nextCallback.cancel();\n this.nextCallback = null;\n }\n };\n\n _proto.safeSetState = function safeSetState(nextState, callback) {\n // This shouldn't be necessary, but there are weird race conditions with\n // setState callbacks and unmounting in testing, so always make sure that\n // we can cancel any pending setState callbacks after we unmount.\n callback = this.setNextCallback(callback);\n this.setState(nextState, callback);\n };\n\n _proto.setNextCallback = function setNextCallback(callback) {\n var _this4 = this;\n\n var active = true;\n\n this.nextCallback = function (event) {\n if (active) {\n active = false;\n _this4.nextCallback = null;\n callback(event);\n }\n };\n\n this.nextCallback.cancel = function () {\n active = false;\n };\n\n return this.nextCallback;\n };\n\n _proto.onTransitionEnd = function onTransitionEnd(node, timeout, handler) {\n this.setNextCallback(handler);\n var doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener;\n\n if (!node || doesNotHaveTimeoutOrListener) {\n setTimeout(this.nextCallback, 0);\n return;\n }\n\n if (this.props.addEndListener) {\n this.props.addEndListener(node, this.nextCallback);\n }\n\n if (timeout != null) {\n setTimeout(this.nextCallback, timeout);\n }\n };\n\n _proto.render = function render() {\n var status = this.state.status;\n\n if (status === UNMOUNTED) {\n return null;\n }\n\n var _this$props = this.props,\n children = _this$props.children,\n childProps = _objectWithoutPropertiesLoose(_this$props, [\"children\"]); // filter props for Transtition\n\n\n delete childProps.in;\n delete childProps.mountOnEnter;\n delete childProps.unmountOnExit;\n delete childProps.appear;\n delete childProps.enter;\n delete childProps.exit;\n delete childProps.timeout;\n delete childProps.addEndListener;\n delete childProps.onEnter;\n delete childProps.onEntering;\n delete childProps.onEntered;\n delete childProps.onExit;\n delete childProps.onExiting;\n delete childProps.onExited;\n\n if (typeof children === 'function') {\n return children(status, childProps);\n }\n\n var child = _react.default.Children.only(children);\n\n return _react.default.cloneElement(child, childProps);\n };\n\n return Transition;\n}(_react.default.Component);\n\nTransition.contextTypes = {\n transitionGroup: PropTypes.object\n};\nTransition.childContextTypes = {\n transitionGroup: function transitionGroup() {}\n};\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * A `)))) + ((("`" + (`function` + "`")) + (` child can be used instead of a React element. This function is\n * called with the current transition status (` + ("`" + `'entering'`))) + (("`" + (`, ` + "`")) + (`'entered'` + ("`" + `,\n * `))))) + (((("`" + (`'exiting'` + "`")) + (`, ` + ("`" + `'exited'`))) + (("`" + (`, ` + "`")) + (`'unmounted'` + ("`" + `), which can be used to apply context\n * specific props to a component.\n *\n * `)))) + ((("`" + ("`" + "`")) + (`jsx\n * \n * {state => (\n * \n * )}\n * \n * ` + "`")) + (("`" + "`") + (`\n */\n children: PropTypes.oneOfType([PropTypes.func.isRequired, PropTypes.element.isRequired]).isRequired,\n\n /**\n * Show the component; triggers the enter or exit states\n */\n in: PropTypes.bool,\n\n /**\n * By default the child component is mounted immediately along with\n * the parent ` + "`")))))) + (((((`Transition` + ("`" + ` component. If you want to \"lazy mount\" the component on the\n * first `)) + ("`" + (`in={true}` + "`"))) + ((` you can set ` + ("`" + `mountOnEnter`)) + ("`" + (`. After the first enter transition the component will stay\n * mounted, even on \"exited\", unless you also specify ` + "`")))) + (((`unmountOnExit` + ("`" + `.\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * By default the child component stays mounted after it reaches the `)) + ("`" + (`'exited'` + "`"))) + ((` state.\n * Set ` + ("`" + `unmountOnExit`)) + (("`" + ` if you'd prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * Normally a component is not transitioned if it is shown when the `) + ("`" + ``))))) + (((("`" + (` component mounts.\n * If you want to transition on the first mount set ` + "`")) + (`appear` + ("`" + ` to `))) + (("`" + (`true` + "`")) + (`, and the\n * component will transition in as soon as the ` + ("`" + ``)))) + ((("`" + (` mounts.\n *\n * > Note: there are no specific \"appear\" states. ` + "`")) + (`appear` + ("`" + ` only adds an additional `))) + (("`" + (`enter` + "`")) + ((` transition.\n */\n appear: PropTypes.bool,\n\n /**\n * Enable or disable enter transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * Enable or disable exit transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * The duration of the transition, in milliseconds.\n * Required unless ` + "`") + (`addEndListener` + "`"))))))) + ((((((` is provided.\n *\n * You may specify a single timeout for all transitions:\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * timeout={500}\n * ` + "`"))) + (("`" + ("`" + `\n *\n * or individually:\n *\n * `)) + ("`" + ("`" + "`")))) + (((`jsx\n * timeout={{\n * appear: 500,\n * enter: 300,\n * exit: 500,\n * }}\n * ` + ("`" + "`")) + ("`" + (`\n *\n * - ` + "`"))) + ((`appear` + ("`" + ` defaults to the value of `)) + (("`" + `enter`) + ("`" + `\n * - `))))) + (((("`" + (`enter` + "`")) + (` defaults to ` + ("`" + `0`))) + (("`" + (`\n * - ` + "`")) + (`exit` + ("`" + ` defaults to `)))) + ((("`" + (`0` + "`")) + (`\n *\n * @type {number | { enter?: number, exit?: number, appear?: number }}\n */\n timeout: function timeout(props) {\n var pt = _PropTypes.timeoutsShape;\n if (!props.addEndListener) pt = pt.isRequired;\n\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return pt.apply(void 0, [props].concat(args));\n },\n\n /**\n * Add a custom transition end trigger. Called with the transitioning\n * DOM node and a ` + ("`" + `done`))) + (("`" + (` callback. Allows for more fine grained transition end\n * logic. **Note:** Timeouts are still used as a fallback if provided.\n *\n * ` + "`")) + (("`" + "`") + (`jsx\n * addEndListener={(node, done) => {\n * // use the css transitionend event to mark the finish of a transition\n * node.addEventListener('transitionend', done, false);\n * }}\n * ` + "`")))))) + ((((("`" + ("`" + `\n */\n addEndListener: PropTypes.func,\n\n /**\n * Callback fired before the \"entering\" status is applied. An extra parameter\n * `)) + ("`" + (`isAppearing` + "`"))) + ((` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired after the \"entering\" status is applied. An extra parameter\n * ` + ("`" + `isAppearing`)) + ("`" + (` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the \"entered\" status is applied. An extra parameter\n * ` + "`")))) + (((`isAppearing` + ("`" + ` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired before the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired after the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the \"exited\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExited: PropTypes.func // Name the function so it is clearer in the documentation\n\n} : {};\n\nfunction noop() {}\n\nTransition.defaultProps = {\n in: false,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n enter: true,\n exit: true,\n onEnter: noop,\n onEntering: noop,\n onEntered: noop,\n onExit: noop,\n onExiting: noop,\n onExited: noop\n};\nTransition.UNMOUNTED = 0;\nTransition.EXITED = 1;\nTransition.ENTERING = 2;\nTransition.ENTERED = 3;\nTransition.EXITING = 4;\n\nvar _default = (0, _reactLifecyclesCompat.polyfill)(Transition);\n\nexports.default = _default;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactLifecyclesCompat = require(\"react-lifecycles-compat\");\n\nvar _ChildMapping = require(\"./utils/ChildMapping\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nvar values = Object.values || function (obj) {\n return Object.keys(obj).map(function (k) {\n return obj[k];\n });\n};\n\nvar defaultProps = {\n component: 'div',\n childFactory: function childFactory(child) {\n return child;\n }\n /**\n * The `)) + ("`" + (`` + "`"))) + ((` component manages a set of transition components\n * (` + ("`" + ``)) + (("`" + ` and `) + ("`" + ``))))) + (((("`" + (`) in a list. Like with the transition\n * components, ` + "`")) + (`` + ("`" + ` is a state machine for managing the mounting\n * and unmounting of components over time.\n *\n * Consider the example below. As items are removed or added to the TodoList the\n * `))) + (("`" + (`in` + "`")) + (` prop is toggled automatically by the ` + ("`" + ``)))) + ((("`" + (`.\n *\n * Note that ` + "`")) + (`` + ("`" + ` does not define any animation behavior!\n * Exactly _how_ a list item animates is up to the individual transition\n * component. This means you can mix and match animations across different list\n * items.\n */\n\n};\n\nvar TransitionGroup =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(TransitionGroup, _React$Component);\n\n function TransitionGroup(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n\n var handleExited = _this.handleExited.bind(_assertThisInitialized(_assertThisInitialized(_this))); // Initial children should all be entering, dependent on appear\n\n\n _this.state = {\n handleExited: handleExited,\n firstRender: true\n };\n return _this;\n }\n\n var _proto = TransitionGroup.prototype;\n\n _proto.getChildContext = function getChildContext() {\n return {\n transitionGroup: {\n isMounting: !this.appeared\n }\n };\n };\n\n _proto.componentDidMount = function componentDidMount() {\n this.appeared = true;\n this.mounted = true;\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.mounted = false;\n };\n\n TransitionGroup.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {\n var prevChildMapping = _ref.children,\n handleExited = _ref.handleExited,\n firstRender = _ref.firstRender;\n return {\n children: firstRender ? (0, _ChildMapping.getInitialChildMapping)(nextProps, handleExited) : (0, _ChildMapping.getNextChildMapping)(nextProps, prevChildMapping, handleExited),\n firstRender: false\n };\n };\n\n _proto.handleExited = function handleExited(child, node) {\n var currentChildMapping = (0, _ChildMapping.getChildMapping)(this.props.children);\n if (child.key in currentChildMapping) return;\n\n if (child.props.onExited) {\n child.props.onExited(node);\n }\n\n if (this.mounted) {\n this.setState(function (state) {\n var children = _extends({}, state.children);\n\n delete children[child.key];\n return {\n children: children\n };\n });\n }\n };\n\n _proto.render = function render() {\n var _this$props = this.props,\n Component = _this$props.component,\n childFactory = _this$props.childFactory,\n props = _objectWithoutPropertiesLoose(_this$props, [\"component\", \"childFactory\"]);\n\n var children = values(this.state.children).map(childFactory);\n delete props.appear;\n delete props.enter;\n delete props.exit;\n\n if (Component === null) {\n return children;\n }\n\n return _react.default.createElement(Component, props, children);\n };\n\n return TransitionGroup;\n}(_react.default.Component);\n\nTransitionGroup.childContextTypes = {\n transitionGroup: _propTypes.default.object.isRequired\n};\nTransitionGroup.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * `))) + (("`" + (`` + "`")) + ((` renders a ` + "`") + (`
` + "`"))))))))) + ((((((((` by default. You can change this\n * behavior by providing a ` + ("`" + `component`)) + ("`" + (` prop.\n * If you use React v16+ and would like to avoid a wrapping ` + "`"))) + ((`
` + ("`" + ` element\n * you can pass in `)) + ("`" + (`component={null}` + "`")))) + (((`. This is useful if the wrapping div\n * borks your css styles.\n */\n component: _propTypes.default.any,\n\n /**\n * A set of ` + ("`" + ``)) + ("`" + (` components, that are toggled ` + "`"))) + ((`in` + ("`" + ` and out as they\n * leave. the `)) + ("`" + (`` + "`"))))) + ((((` will inject specific transition props, so\n * remember to spread them through if you are wrapping the ` + ("`" + ``)) + ("`" + (` as\n * with our ` + "`"))) + ((`` + ("`" + ` example.\n *\n * While this component is meant for multiple `)) + ("`" + (`Transition` + "`")))) + (((` or ` + ("`" + `CSSTransition`)) + ("`" + (`\n * children, sometimes you may want to have a single transition child with\n * content that you want to be transitioned out and in when you change it\n * (e.g. routes, images etc.) In that case you can change the ` + "`"))) + ((`key` + ("`" + ` prop of\n * the transition child as you change its content, this will cause\n * `)) + (("`" + `TransitionGroup`) + ("`" + ` to transition the child out and back in.\n */\n children: _propTypes.default.node,\n\n /**\n * A convenience prop that enables or disables appear animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n appear: _propTypes.default.bool,\n\n /**\n * A convenience prop that enables or disables enter animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n enter: _propTypes.default.bool,\n\n /**\n * A convenience prop that enables or disables exit animations\n * for all children. Note that specifying this will override any defaults set\n * on individual children Transitions.\n */\n exit: _propTypes.default.bool,\n\n /**\n * You may need to apply reactive updates to a child as it is exiting.\n * This is generally done by using `)))))) + ((((("`" + (`cloneElement` + "`")) + (` however in the case of an exiting\n * child the element has already been removed and not accessible to the consumer.\n *\n * If you do need to update a child as it leaves you can provide a ` + ("`" + `childFactory`))) + (("`" + (`\n * to wrap every child, even the ones that are leaving.\n *\n * @type Function(child: ReactElement) -> ReactElement\n */\n childFactory: _propTypes.default.func\n} : {};\nTransitionGroup.defaultProps = defaultProps;\n\nvar _default = (0, _reactLifecyclesCompat.polyfill)(TransitionGroup);\n\nexports.default = _default;\nmodule.exports = exports[\"default\"];", + "\"use strict\";\n\nvar _CSSTransition = _interopRequireDefault(require(\"./CSSTransition\"));\n\nvar _ReplaceTransition = _interopRequireDefault(require(\"./ReplaceTransition\"));\n\nvar _TransitionGroup = _interopRequireDefault(require(\"./TransitionGroup\"));\n\nvar _Transition = _interopRequireDefault(require(\"./Transition\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nmodule.exports = {\n Transition: _Transition.default,\n TransitionGroup: _TransitionGroup.default,\n ReplaceTransition: _ReplaceTransition.default,\n CSSTransition: _CSSTransition.default\n};", + "\"use strict\";\n\nexports.__esModule = true;\nexports.getChildMapping = getChildMapping;\nexports.mergeChildMappings = mergeChildMappings;\nexports.getInitialChildMapping = getInitialChildMapping;\nexports.getNextChildMapping = getNextChildMapping;\n\nvar _react = require(\"react\");\n\n/**\n * Given ` + "`")) + (`this.props.children` + ("`" + `, return an object mapping key to child.\n *\n * @param {*} children `)))) + ((("`" + (`this.props.children` + "`")) + (`\n * @return {object} Mapping of key to child\n */\nfunction getChildMapping(children, mapFn) {\n var mapper = function mapper(child) {\n return mapFn && (0, _react.isValidElement)(child) ? mapFn(child) : child;\n };\n\n var result = Object.create(null);\n if (children) _react.Children.map(children, function (c) {\n return c;\n }).forEach(function (child) {\n // run the map function here instead so that the key is the computed one\n result[child.key] = mapper(child);\n });\n return result;\n}\n/**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want to show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev children as returned from\n * ` + ("`" + `ReactTransitionChildMapping.getChildMapping()`))) + (("`" + (`.\n * @param {object} next next children as returned from\n * ` + "`")) + ((`ReactTransitionChildMapping.getChildMapping()` + "`") + (`.\n * @return {object} a key set that contains all keys in ` + "`"))))) + ((((`prev` + ("`" + ` and all keys\n * in `)) + ("`" + (`next` + "`"))) + ((` in a reasonable order.\n */\n\n\nfunction mergeChildMappings(prev, next) {\n prev = prev || {};\n next = next || {};\n\n function getValueForKey(key) {\n return key in next ? next[key] : prev[key];\n } // For each key of ` + ("`" + `next`)) + ("`" + (`, the list of keys to insert before that key in\n // the combined list\n\n\n var nextKeysPending = Object.create(null);\n var pendingKeys = [];\n\n for (var prevKey in prev) {\n if (prevKey in next) {\n if (pendingKeys.length) {\n nextKeysPending[prevKey] = pendingKeys;\n pendingKeys = [];\n }\n } else {\n pendingKeys.push(prevKey);\n }\n }\n\n var i;\n var childMapping = {};\n\n for (var nextKey in next) {\n if (nextKeysPending[nextKey]) {\n for (i = 0; i < nextKeysPending[nextKey].length; i++) {\n var pendingNextKey = nextKeysPending[nextKey][i];\n childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);\n }\n }\n\n childMapping[nextKey] = getValueForKey(nextKey);\n } // Finally, add the keys which didn't appear before any key in ` + "`")))) + (((`next` + ("`" + `\n\n\n for (i = 0; i < pendingKeys.length; i++) {\n childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);\n }\n\n return childMapping;\n}\n\nfunction getProp(child, prop, props) {\n return props[prop] != null ? props[prop] : child.props[prop];\n}\n\nfunction getInitialChildMapping(props, onExited) {\n return getChildMapping(props.children, function (child) {\n return (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: true,\n appear: getProp(child, 'appear', props),\n enter: getProp(child, 'enter', props),\n exit: getProp(child, 'exit', props)\n });\n });\n}\n\nfunction getNextChildMapping(nextProps, prevChildMapping, onExited) {\n var nextChildMapping = getChildMapping(nextProps.children);\n var children = mergeChildMappings(prevChildMapping, nextChildMapping);\n Object.keys(children).forEach(function (key) {\n var child = children[key];\n if (!(0, _react.isValidElement)(child)) return;\n var hasPrev = key in prevChildMapping;\n var hasNext = key in nextChildMapping;\n var prevChild = prevChildMapping[key];\n var isLeaving = (0, _react.isValidElement)(prevChild) && !prevChild.props.in; // item is new (entering)\n\n if (hasNext && (!hasPrev || isLeaving)) {\n // console.log('entering', key)\n children[key] = (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: true,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n } else if (!hasNext && hasPrev && !isLeaving) {\n // item is old (exiting)\n // console.log('leaving', key)\n children[key] = (0, _react.cloneElement)(child, {\n in: false\n });\n } else if (hasNext && hasPrev && (0, _react.isValidElement)(prevChild)) {\n // item hasn't changed transition states\n // copy over the last transition props;\n // console.log('unchanged', key)\n children[key] = (0, _react.cloneElement)(child, {\n onExited: onExited.bind(null, child),\n in: prevChild.props.in,\n exit: getProp(child, 'exit', nextProps),\n enter: getProp(child, 'enter', nextProps)\n });\n }\n });\n return children;\n}", + "\"use strict\";\n\nexports.__esModule = true;\nexports.classNamesShape = exports.timeoutsShape = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar timeoutsShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({\n enter: _propTypes.default.number,\n exit: _propTypes.default.number,\n appear: _propTypes.default.number\n}).isRequired]) : null;\nexports.timeoutsShape = timeoutsShape;\nvar classNamesShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({\n enter: _propTypes.default.string,\n exit: _propTypes.default.string,\n active: _propTypes.default.string\n}), _propTypes.default.shape({\n enter: _propTypes.default.string,\n enterDone: _propTypes.default.string,\n enterActive: _propTypes.default.string,\n exit: _propTypes.default.string,\n exitDone: _propTypes.default.string,\n exitActive: _propTypes.default.string\n})]) : null;\nexports.classNamesShape = classNamesShape;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.default = exports.EXITING = exports.ENTERED = exports.ENTERING = exports.EXITED = exports.UNMOUNTED = void 0;\n\nvar PropTypes = _interopRequireWildcard(require(\"prop-types\"));\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _reactDom = _interopRequireDefault(require(\"react-dom\"));\n\nvar _reactLifecyclesCompat = require(\"react-lifecycles-compat\");\n\nvar _PropTypes = require(\"./utils/PropTypes\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\nvar UNMOUNTED = 'unmounted';\nexports.UNMOUNTED = UNMOUNTED;\nvar EXITED = 'exited';\nexports.EXITED = EXITED;\nvar ENTERING = 'entering';\nexports.ENTERING = ENTERING;\nvar ENTERED = 'entered';\nexports.ENTERED = ENTERED;\nvar EXITING = 'exiting';\n/**\n * The Transition component lets you describe a transition from one component\n * state to another _over time_ with a simple declarative API. Most commonly\n * it's used to animate the mounting and unmounting of a component, but can also\n * be used to describe in-place transition states as well.\n *\n * By default the `)) + ("`" + (`Transition` + "`"))) + ((` component does not alter the behavior of the\n * component it renders, it only tracks \"enter\" and \"exit\" states for the components.\n * It's up to you to give meaning and effect to those states. For example we can\n * add styles to a component when it enters or exits:\n *\n * ` + ("`" + "`")) + (("`" + `jsx\n * import Transition from 'react-transition-group/Transition';\n *\n * const duration = 300;\n *\n * const defaultStyle = {\n * transition: `) + ("`" + `opacity ${duration}ms ease-in-out`))))))) + (((((("`" + (`,\n * opacity: 0,\n * }\n *\n * const transitionStyles = {\n * entering: { opacity: 0 },\n * entered: { opacity: 1 },\n * };\n *\n * const Fade = ({ in: inProp }) => (\n * \n * {(state) => (\n *
\n * I'm a fade Transition!\n *
\n * )}\n *
\n * );\n * ` + "`")) + ("`" + ("`" + `\n *\n * As noted the `))) + (("`" + (`Transition` + "`")) + (` component doesn't _do_ anything by itself to its child component.\n * What it does do is track transition states over time so you can update the\n * component (such as by adding styles or classes) when it changes states.\n *\n * There are 4 main states a Transition can be in:\n * - ` + ("`" + `'entering'`)))) + ((("`" + (`\n * - ` + "`")) + (`'entered'` + ("`" + `\n * - `))) + (("`" + (`'exiting'` + "`")) + (`\n * - ` + ("`" + `'exited'`))))) + (((("`" + (`\n *\n * Transition state is toggled via the ` + "`")) + (`in` + ("`" + ` prop. When `))) + (("`" + (`true` + "`")) + (` the component begins the\n * \"Enter\" stage. During this stage, the component will shift from its current transition state,\n * to ` + ("`" + `'entering'`)))) + ((("`" + (` for the duration of the transition and then to the ` + "`")) + (`'entered'` + ("`" + ` stage once\n * it's complete. Let's take the following example:\n *\n * `))) + (("`" + ("`" + "`")) + ((`jsx\n * state = { in: false };\n *\n * toggleEnterState = () => {\n * this.setState({ in: true });\n * }\n *\n * render() {\n * return (\n *
\n * \n * \n *
\n * );\n * }\n * ` + "`") + ("`" + "`")))))) + (((((`\n *\n * When the button is clicked the component will shift to the ` + ("`" + `'entering'`)) + ("`" + (` state and\n * stay there for 500ms (the value of ` + "`"))) + ((`timeout` + ("`" + `) before it finally switches to `)) + ("`" + (`'entered'` + "`")))) + (((`.\n *\n * When ` + ("`" + `in`)) + ("`" + (` is ` + "`"))) + ((`false` + ("`" + ` the same thing happens except the state moves from `)) + (("`" + `'exiting'`) + ("`" + ` to `))))) + (((("`" + (`'exited'` + "`")) + (`.\n *\n * ## Timing\n *\n * Timing is often the trickiest part of animation, mistakes can result in slight delays\n * that are hard to pin down. A common example is when you want to add an exit transition,\n * you should set the desired final styles when the state is ` + ("`" + `'exiting'`))) + (("`" + (`. That's when the\n * transition to those styles will start and, if you matched the ` + "`")) + (`timeout` + ("`" + ` prop with the\n * CSS Transition duration, it will end exactly when the state changes to `)))) + ((("`" + (`'exited'` + "`")) + (`.\n *\n * > **Note**: For simpler transitions the ` + ("`" + `Transition`))) + (("`" + (` component might be enough, but\n * > take into account that it's platform-agnostic, while the ` + "`")) + ((`CSSTransition` + "`") + (` component\n * > [forces reflows](https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215)\n * > in order to make more complex transitions more predictable. For example, even though\n * > classes ` + "`")))))))) + (((((((`example-enter` + ("`" + ` and `)) + ("`" + (`example-enter-active` + "`"))) + ((` are applied immediately one after\n * > another, you can still transition from one to the other because of the forced reflow\n * > (read [this issue](https://github.com/reactjs/react-transition-group/issues/159#issuecomment-322761171)\n * > for more info). Take this into account when choosing between ` + ("`" + `Transition`)) + ("`" + (` and\n * > ` + "`")))) + (((`CSSTransition` + ("`" + `.\n */\n\nexports.EXITING = EXITING;\n\nvar Transition =\n/*#__PURE__*/\nfunction (_React$Component) {\n _inheritsLoose(Transition, _React$Component);\n\n function Transition(props, context) {\n var _this;\n\n _this = _React$Component.call(this, props, context) || this;\n var parentGroup = context.transitionGroup; // In the context of a TransitionGroup all enters are really appears\n\n var appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear;\n var initialStatus;\n _this.appearStatus = null;\n\n if (props.in) {\n if (appear) {\n initialStatus = EXITED;\n _this.appearStatus = ENTERING;\n } else {\n initialStatus = ENTERED;\n }\n } else {\n if (props.unmountOnExit || props.mountOnEnter) {\n initialStatus = UNMOUNTED;\n } else {\n initialStatus = EXITED;\n }\n }\n\n _this.state = {\n status: initialStatus\n };\n _this.nextCallback = null;\n return _this;\n }\n\n var _proto = Transition.prototype;\n\n _proto.getChildContext = function getChildContext() {\n return {\n transitionGroup: null // allows for nested Transitions\n\n };\n };\n\n Transition.getDerivedStateFromProps = function getDerivedStateFromProps(_ref, prevState) {\n var nextIn = _ref.in;\n\n if (nextIn && prevState.status === UNMOUNTED) {\n return {\n status: EXITED\n };\n }\n\n return null;\n }; // getSnapshotBeforeUpdate(prevProps) {\n // let nextStatus = null\n // if (prevProps !== this.props) {\n // const { status } = this.state\n // if (this.props.in) {\n // if (status !== ENTERING && status !== ENTERED) {\n // nextStatus = ENTERING\n // }\n // } else {\n // if (status === ENTERING || status === ENTERED) {\n // nextStatus = EXITING\n // }\n // }\n // }\n // return { nextStatus }\n // }\n\n\n _proto.componentDidMount = function componentDidMount() {\n this.updateStatus(true, this.appearStatus);\n };\n\n _proto.componentDidUpdate = function componentDidUpdate(prevProps) {\n var nextStatus = null;\n\n if (prevProps !== this.props) {\n var status = this.state.status;\n\n if (this.props.in) {\n if (status !== ENTERING && status !== ENTERED) {\n nextStatus = ENTERING;\n }\n } else {\n if (status === ENTERING || status === ENTERED) {\n nextStatus = EXITING;\n }\n }\n }\n\n this.updateStatus(false, nextStatus);\n };\n\n _proto.componentWillUnmount = function componentWillUnmount() {\n this.cancelNextCallback();\n };\n\n _proto.getTimeouts = function getTimeouts() {\n var timeout = this.props.timeout;\n var exit, enter, appear;\n exit = enter = appear = timeout;\n\n if (timeout != null && typeof timeout !== 'number') {\n exit = timeout.exit;\n enter = timeout.enter; // TODO: remove fallback for next major\n\n appear = timeout.appear !== undefined ? timeout.appear : enter;\n }\n\n return {\n exit: exit,\n enter: enter,\n appear: appear\n };\n };\n\n _proto.updateStatus = function updateStatus(mounting, nextStatus) {\n if (mounting === void 0) {\n mounting = false;\n }\n\n if (nextStatus !== null) {\n // nextStatus will always be ENTERING or EXITING.\n this.cancelNextCallback();\n\n var node = _reactDom.default.findDOMNode(this);\n\n if (nextStatus === ENTERING) {\n this.performEnter(node, mounting);\n } else {\n this.performExit(node);\n }\n } else if (this.props.unmountOnExit && this.state.status === EXITED) {\n this.setState({\n status: UNMOUNTED\n });\n }\n };\n\n _proto.performEnter = function performEnter(node, mounting) {\n var _this2 = this;\n\n var enter = this.props.enter;\n var appearing = this.context.transitionGroup ? this.context.transitionGroup.isMounting : mounting;\n var timeouts = this.getTimeouts();\n var enterTimeout = appearing ? timeouts.appear : timeouts.enter; // no enter animation skip right to ENTERED\n // if we are mounting and running this it means appear _must_ be set\n\n if (!mounting && !enter) {\n this.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node);\n });\n return;\n }\n\n this.props.onEnter(node, appearing);\n this.safeSetState({\n status: ENTERING\n }, function () {\n _this2.props.onEntering(node, appearing);\n\n _this2.onTransitionEnd(node, enterTimeout, function () {\n _this2.safeSetState({\n status: ENTERED\n }, function () {\n _this2.props.onEntered(node, appearing);\n });\n });\n });\n };\n\n _proto.performExit = function performExit(node) {\n var _this3 = this;\n\n var exit = this.props.exit;\n var timeouts = this.getTimeouts(); // no exit animation skip right to EXITED\n\n if (!exit) {\n this.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n return;\n }\n\n this.props.onExit(node);\n this.safeSetState({\n status: EXITING\n }, function () {\n _this3.props.onExiting(node);\n\n _this3.onTransitionEnd(node, timeouts.exit, function () {\n _this3.safeSetState({\n status: EXITED\n }, function () {\n _this3.props.onExited(node);\n });\n });\n });\n };\n\n _proto.cancelNextCallback = function cancelNextCallback() {\n if (this.nextCallback !== null) {\n this.nextCallback.cancel();\n this.nextCallback = null;\n }\n };\n\n _proto.safeSetState = function safeSetState(nextState, callback) {\n // This shouldn't be necessary, but there are weird race conditions with\n // setState callbacks and unmounting in testing, so always make sure that\n // we can cancel any pending setState callbacks after we unmount.\n callback = this.setNextCallback(callback);\n this.setState(nextState, callback);\n };\n\n _proto.setNextCallback = function setNextCallback(callback) {\n var _this4 = this;\n\n var active = true;\n\n this.nextCallback = function (event) {\n if (active) {\n active = false;\n _this4.nextCallback = null;\n callback(event);\n }\n };\n\n this.nextCallback.cancel = function () {\n active = false;\n };\n\n return this.nextCallback;\n };\n\n _proto.onTransitionEnd = function onTransitionEnd(node, timeout, handler) {\n this.setNextCallback(handler);\n var doesNotHaveTimeoutOrListener = timeout == null && !this.props.addEndListener;\n\n if (!node || doesNotHaveTimeoutOrListener) {\n setTimeout(this.nextCallback, 0);\n return;\n }\n\n if (this.props.addEndListener) {\n this.props.addEndListener(node, this.nextCallback);\n }\n\n if (timeout != null) {\n setTimeout(this.nextCallback, timeout);\n }\n };\n\n _proto.render = function render() {\n var status = this.state.status;\n\n if (status === UNMOUNTED) {\n return null;\n }\n\n var _this$props = this.props,\n children = _this$props.children,\n childProps = _objectWithoutPropertiesLoose(_this$props, [\"children\"]); // filter props for Transtition\n\n\n delete childProps.in;\n delete childProps.mountOnEnter;\n delete childProps.unmountOnExit;\n delete childProps.appear;\n delete childProps.enter;\n delete childProps.exit;\n delete childProps.timeout;\n delete childProps.addEndListener;\n delete childProps.onEnter;\n delete childProps.onEntering;\n delete childProps.onEntered;\n delete childProps.onExit;\n delete childProps.onExiting;\n delete childProps.onExited;\n\n if (typeof children === 'function') {\n return children(status, childProps);\n }\n\n var child = _react.default.Children.only(children);\n\n return _react.default.cloneElement(child, childProps);\n };\n\n return Transition;\n}(_react.default.Component);\n\nTransition.contextTypes = {\n transitionGroup: PropTypes.object\n};\nTransition.childContextTypes = {\n transitionGroup: function transitionGroup() {}\n};\nTransition.propTypes = process.env.NODE_ENV !== \"production\" ? {\n /**\n * A `)) + ("`" + (`function` + "`"))) + ((` child can be used instead of a React element.\n * This function is called with the current transition status\n * ('entering', 'entered', 'exiting', 'exited', 'unmounted'), which can be used\n * to apply context specific props to a component.\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * \n * {(status) => (\n * \n * )}\n * \n * `)) + ("`" + ("`" + "`"))) + ((`\n */\n children: PropTypes.oneOfType([PropTypes.func.isRequired, PropTypes.element.isRequired]).isRequired,\n\n /**\n * Show the component; triggers the enter or exit states\n */\n in: PropTypes.bool,\n\n /**\n * By default the child component is mounted immediately along with\n * the parent ` + ("`" + `Transition`)) + ("`" + (` component. If you want to \"lazy mount\" the component on the\n * first ` + "`")))) + (((`in={true}` + ("`" + ` you can set `)) + ("`" + (`mountOnEnter` + "`"))) + ((`. After the first enter transition the component will stay\n * mounted, even on \"exited\", unless you also specify ` + ("`" + `unmountOnExit`)) + (("`" + `.\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * By default the child component stays mounted after it reaches the `) + ("`" + `'exited'`)))))) + ((((("`" + (` state.\n * Set ` + "`")) + (`unmountOnExit` + ("`" + ` if you'd prefer to unmount the component after it finishes exiting.\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * Normally a component is not transitioned if it is shown when the `))) + (("`" + (`` + "`")) + (` component mounts.\n * If you want to transition on the first mount set ` + ("`" + `appear`)))) + ((("`" + (` to ` + "`")) + (`true` + ("`" + `, and the\n * component will transition in as soon as the `))) + (("`" + (`` + "`")) + ((` mounts.\n *\n * > Note: there are no specific \"appear\" states. ` + "`") + (`appear` + "`"))))) + ((((` only adds an additional ` + ("`" + `enter`)) + ("`" + (` transition.\n */\n appear: PropTypes.bool,\n\n /**\n * Enable or disable enter transitions.\n */\n enter: PropTypes.bool,\n\n /**\n * Enable or disable exit transitions.\n */\n exit: PropTypes.bool,\n\n /**\n * The duration of the transition, in milliseconds.\n * Required unless ` + "`"))) + ((`addEndListener` + ("`" + ` is provided\n *\n * You may specify a single timeout for all transitions like: `)) + ("`" + (`timeout={500}` + "`")))) + (((`,\n * or individually like:\n *\n * ` + ("`" + "`")) + ("`" + (`jsx\n * timeout={{\n * enter: 300,\n * exit: 500,\n * appear: 500,\n * }}\n * ` + "`"))) + (("`" + ("`" + `\n *\n * If the value of `)) + (("`" + `appear`) + ("`" + ` is not set, then the value from enter is taken.\n *\n * If the `))))))) + (((((("`" + (`enter` + "`")) + (` or ` + ("`" + `exit`))) + (("`" + (` value is ` + "`")) + (`null` + ("`" + ` or `)))) + ((("`" + (`undefined` + "`")) + (`, then the timer is set to ` + ("`" + `0`))) + (("`" + (`\n *\n * @type {number | { enter?: number, exit?: number, appear?: number }}\n */\n timeout: function timeout(props) {\n var pt = process.env.NODE_ENV !== \"production\" ? _PropTypes.timeoutsShape : {};;\n if (!props.addEndListener) pt = pt.isRequired;\n\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return pt.apply(void 0, [props].concat(args));\n },\n\n /**\n * Add a custom transition end trigger. Called with the transitioning\n * DOM node and a ` + "`")) + ((`done` + "`") + (` callback. Allows for more fine grained transition end\n * logic. **Note:** Timeouts are still used as a fallback if provided.\n *\n * ` + "`"))))) + (((("`" + ("`" + `jsx\n * addEndListener={(node, done) => {\n * // use the css transitionend event to mark the finish of a transition\n * node.addEventListener('transitionend', done, false);\n * }}\n * `)) + ("`" + ("`" + "`"))) + ((`\n */\n addEndListener: PropTypes.func,\n\n /**\n * Callback fired before the \"entering\" status is applied. An extra parameter\n * ` + ("`" + `isAppearing`)) + ("`" + (` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired after the \"entering\" status is applied. An extra parameter\n * ` + "`")))) + (((`isAppearing` + ("`" + ` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool)\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the \"entered\" status is applied. An extra parameter\n * `)) + ("`" + (`isAppearing` + "`"))) + ((` is supplied to indicate if the enter stage is occurring on the initial mount\n *\n * @type Function(node: HtmlElement, isAppearing: bool) -> void\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired before the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired after the \"exiting\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the \"exited\" status is applied.\n *\n * @type Function(node: HtmlElement) -> void\n */\n onExited: PropTypes.func // Name the function so it is clearer in the documentation\n\n} : {};\n\nfunction noop() {}\n\nTransition.defaultProps = {\n in: false,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n enter: true,\n exit: true,\n onEnter: noop,\n onEntering: noop,\n onEntered: noop,\n onExit: noop,\n onExiting: noop,\n onExited: noop\n};\nTransition.UNMOUNTED = 0;\nTransition.EXITED = 1;\nTransition.ENTERING = 2;\nTransition.ENTERED = 3;\nTransition.EXITING = 4;\n\nvar _default = (0, _reactLifecyclesCompat.polyfill)(Transition);\n\nexports.default = _default;", + "\"use strict\";\n\nexports.__esModule = true;\nexports.classNamesShape = exports.timeoutsShape = void 0;\n\nvar _propTypes = _interopRequireDefault(require(\"prop-types\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar timeoutsShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({\n enter: _propTypes.default.number,\n exit: _propTypes.default.number,\n appear: _propTypes.default.number\n}).isRequired]) : null;\nexports.timeoutsShape = timeoutsShape;\nvar classNamesShape = process.env.NODE_ENV !== 'production' ? _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({\n enter: _propTypes.default.string,\n exit: _propTypes.default.string,\n active: _propTypes.default.string\n}), _propTypes.default.shape({\n enter: _propTypes.default.string,\n enterDone: _propTypes.default.string,\n enterActive: _propTypes.default.string,\n exit: _propTypes.default.string,\n exitDone: _propTypes.default.string,\n exitActive: _propTypes.default.string\n})]) : null;\nexports.classNamesShape = classNamesShape;", + "/** @license React v16.8.4\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var k=require(\"object-assign\"),n=\"function\"===typeof Symbol&&Symbol.for,p=n?Symbol.for(\"react.element\"):60103,q=n?Symbol.for(\"react.portal\"):60106,r=n?Symbol.for(\"react.fragment\"):60107,t=n?Symbol.for(\"react.strict_mode\"):60108,u=n?Symbol.for(\"react.profiler\"):60114,v=n?Symbol.for(\"react.provider\"):60109,w=n?Symbol.for(\"react.context\"):60110,x=n?Symbol.for(\"react.concurrent_mode\"):60111,y=n?Symbol.for(\"react.forward_ref\"):60112,z=n?Symbol.for(\"react.suspense\"):60113,aa=n?Symbol.for(\"react.memo\"):\n60115,ba=n?Symbol.for(\"react.lazy\"):60116,A=\"function\"===typeof Symbol&&Symbol.iterator;function ca(a,b,d,c,e,g,h,f){if(!a){a=void 0;if(void 0===b)a=Error(\"Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.\");else{var l=[d,c,e,g,h,f],m=0;a=Error(b.replace(/%s/g,function(){return l[m++]}));a.name=\"Invariant Violation\"}a.framesToPop=1;throw a;}}\nfunction B(a){for(var b=arguments.length-1,d=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=0;cP.length&&P.push(a)}\nfunction S(a,b,d,c){var e=typeof a;if(\"undefined\"===e||\"boolean\"===e)a=null;var g=!1;if(null===a)g=!0;else switch(e){case \"string\":case \"number\":g=!0;break;case \"object\":switch(a.$$typeof){case p:case q:g=!0}}if(g)return d(c,a,\"\"===b?\".\"+T(a,0):b),1;g=0;b=\"\"===b?\".\":b+\":\";if(Array.isArray(a))for(var h=0;h max) {\n validMin = max;\n validMax = min;\n }\n\n return [validMin, validMax];\n}\n/**\n * Calculate the step which is easy to understand between ticks, like 10, 20, 25\n *\n * @param {Decimal} roughStep The rough step calculated by deviding the\n * difference by the tickCount\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @param {Integer} correctionFactor A correction factor\n * @return {Decimal} The step which is easy to understand between two ticks\n */\n\n\nfunction getFormatStep(roughStep, allowDecimals, correctionFactor) {\n if (roughStep.lte(0)) {\n return new _decimal.default(0);\n }\n\n var digitCount = _arithmetic.default.getDigitCount(roughStep.toNumber()); // The ratio between the rough step and the smallest number which has a bigger\n // order of magnitudes than the rough step\n\n\n var digitCountValue = new _decimal.default(10).pow(digitCount);\n var stepRatio = roughStep.div(digitCountValue); // When an integer and a float multiplied, the accuracy of result may be wrong\n\n var stepRatioScale = digitCount !== 1 ? 0.05 : 0.1;\n var amendStepRatio = new _decimal.default(Math.ceil(stepRatio.div(stepRatioScale).toNumber())).add(correctionFactor).mul(stepRatioScale);\n var formatStep = amendStepRatio.mul(digitCountValue);\n return allowDecimals ? formatStep : new _decimal.default(Math.ceil(formatStep));\n}\n/**\n * calculate the ticks when the minimum value equals to the maximum value\n *\n * @param {Number} value The minimum valuue which is also the maximum value\n * @param {Integer} tickCount The count of ticks\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @return {Array} ticks\n */\n\n\nfunction getTickOfSingleValue(value, tickCount, allowDecimals) {\n var step = 1; // calculate the middle value of ticks\n\n var middle = new _decimal.default(value);\n\n if (!middle.isint() && allowDecimals) {\n var absVal = Math.abs(value);\n\n if (absVal < 1) {\n // The step should be a float number when the difference is smaller than 1\n step = new _decimal.default(10).pow(_arithmetic.default.getDigitCount(value) - 1);\n middle = new _decimal.default(Math.floor(middle.div(step).toNumber())).mul(step);\n } else if (absVal > 1) {\n // Return the maximum integer which is smaller than 'value' when 'value' is greater than 1\n middle = new _decimal.default(Math.floor(value));\n }\n } else if (value === 0) {\n middle = new _decimal.default(Math.floor((tickCount - 1) / 2));\n } else if (!allowDecimals) {\n middle = new _decimal.default(Math.floor(value));\n }\n\n var middleIndex = Math.floor((tickCount - 1) / 2);\n var fn = (0, _utils.compose)((0, _utils.map)(function (n) {\n return middle.add(new _decimal.default(n - middleIndex).mul(step)).toNumber();\n }), _utils.range);\n return fn(0, tickCount);\n}\n/**\n * Calculate the step\n *\n * @param {Number} min The minimum value of an interval\n * @param {Number} max The maximum value of an interval\n * @param {Integer} tickCount The count of ticks\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @param {Number} correctionFactor A correction factor\n * @return {Object} The step, minimum value of ticks, maximum value of ticks\n */\n\n\nfunction calculateStep(min, max, tickCount, allowDecimals) {\n var correctionFactor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;\n\n // dirty hack (for recharts' test)\n if (!Number.isFinite((max - min) / (tickCount - 1))) {\n return {\n step: new _decimal.default(0),\n tickMin: new _decimal.default(0),\n tickMax: new _decimal.default(0)\n };\n } // The step which is easy to understand between two ticks\n\n\n var step = getFormatStep(new _decimal.default(max).sub(min).div(tickCount - 1), allowDecimals, correctionFactor); // A medial value of ticks\n\n var middle; // When 0 is inside the interval, 0 should be a tick\n\n if (min <= 0 && max >= 0) {\n middle = new _decimal.default(0);\n } else {\n // calculate the middle value\n middle = new _decimal.default(min).add(max).div(2); // minus modulo value\n\n middle = middle.sub(new _decimal.default(middle).mod(step));\n }\n\n var belowCount = Math.ceil(middle.sub(min).div(step).toNumber());\n var upCount = Math.ceil(new _decimal.default(max).sub(middle).div(step).toNumber());\n var scaleCount = belowCount + upCount + 1;\n\n if (scaleCount > tickCount) {\n // When more ticks need to cover the interval, step should be bigger.\n return calculateStep(min, max, tickCount, allowDecimals, correctionFactor + 1);\n }\n\n if (scaleCount < tickCount) {\n // When less ticks can cover the interval, we should add some additional ticks\n upCount = max > 0 ? upCount + (tickCount - scaleCount) : upCount;\n belowCount = max > 0 ? belowCount : belowCount + (tickCount - scaleCount);\n }\n\n return {\n step: step,\n tickMin: middle.sub(new _decimal.default(belowCount).mul(step)),\n tickMax: middle.add(new _decimal.default(upCount).mul(step))\n };\n}\n/**\n * Calculate the ticks of an interval, the count of ticks will be guraranteed\n *\n * @param {Number} min, max min: The minimum value, max: The maximum value\n * @param {Integer} tickCount The count of ticks\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @return {Array} ticks\n */\n\n\nfunction getNiceTickValuesFn(_ref3) {\n var _ref4 = _slicedToArray(_ref3, 2),\n min = _ref4[0],\n max = _ref4[1];\n\n var tickCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6;\n var allowDecimals = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n // More than two ticks should be return\n var count = Math.max(tickCount, 2);\n\n var _getValidInterval = getValidInterval([min, max]),\n _getValidInterval2 = _slicedToArray(_getValidInterval, 2),\n cormin = _getValidInterval2[0],\n cormax = _getValidInterval2[1];\n\n if (cormin === -Infinity || cormax === Infinity) {\n var _values = cormax === Infinity ? [cormin].concat(_toConsumableArray((0, _utils.range)(0, tickCount - 1).map(function () {\n return Infinity;\n }))) : _toConsumableArray((0, _utils.range)(0, tickCount - 1).map(function () {\n return -Infinity;\n })).concat([cormax]);\n\n return min > max ? (0, _utils.reverse)(_values) : _values;\n }\n\n if (cormin === cormax) {\n return getTickOfSingleValue(cormin, tickCount, allowDecimals);\n } // Get the step between two ticks\n\n\n var _calculateStep = calculateStep(cormin, cormax, count, allowDecimals),\n step = _calculateStep.step,\n tickMin = _calculateStep.tickMin,\n tickMax = _calculateStep.tickMax;\n\n var values = _arithmetic.default.rangeStep(tickMin, tickMax.add(new _decimal.default(0.1).mul(step)), step);\n\n return min > max ? (0, _utils.reverse)(values) : values;\n}\n/**\n * Calculate the ticks of an interval, the count of ticks won't be guraranteed\n *\n * @param {Number} min, max min: The minimum value, max: The maximum value\n * @param {Integer} tickCount The count of ticks\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @return {Array} ticks\n */\n\n\nfunction getTickValuesFn(_ref5) {\n var _ref6 = _slicedToArray(_ref5, 2),\n min = _ref6[0],\n max = _ref6[1];\n\n var tickCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6;\n var allowDecimals = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n // More than two ticks should be return\n var count = Math.max(tickCount, 2);\n\n var _getValidInterval3 = getValidInterval([min, max]),\n _getValidInterval4 = _slicedToArray(_getValidInterval3, 2),\n cormin = _getValidInterval4[0],\n cormax = _getValidInterval4[1];\n\n if (cormin === -Infinity || cormax === Infinity) {\n return [min, max];\n }\n\n if (cormin === cormax) {\n return getTickOfSingleValue(cormin, tickCount, allowDecimals);\n }\n\n var step = getFormatStep(new _decimal.default(cormax).sub(cormin).div(count - 1), allowDecimals, 0);\n var fn = (0, _utils.compose)((0, _utils.map)(function (n) {\n return new _decimal.default(cormin).add(new _decimal.default(n).mul(step)).toNumber();\n }), _utils.range);\n var values = fn(0, count).filter(function (entry) {\n return entry >= cormin && entry <= cormax;\n });\n return min > max ? (0, _utils.reverse)(values) : values;\n}\n/**\n * Calculate the ticks of an interval, the count of ticks won't be guraranteed,\n * but the domain will be guaranteed\n *\n * @param {Number} min, max min: The minimum value, max: The maximum value\n * @param {Integer} tickCount The count of ticks\n * @param {Boolean} allowDecimals Allow the ticks to be decimals or not\n * @return {Array} ticks\n */\n\n\nfunction getTickValuesFixedDomainFn(_ref7, tickCount) {\n var _ref8 = _slicedToArray(_ref7, 2),\n min = _ref8[0],\n max = _ref8[1];\n\n var allowDecimals = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n // More than two ticks should be return\n var _getValidInterval5 = getValidInterval([min, max]),\n _getValidInterval6 = _slicedToArray(_getValidInterval5, 2),\n cormin = _getValidInterval6[0],\n cormax = _getValidInterval6[1];\n\n if (cormin === -Infinity || cormax === Infinity) {\n return [min, max];\n }\n\n if (cormin === cormax) {\n return [cormin];\n }\n\n var count = Math.max(tickCount, 2);\n var step = getFormatStep(new _decimal.default(cormax).sub(cormin).div(count - 1), allowDecimals, 0);\n\n var values = _toConsumableArray(_arithmetic.default.rangeStep(new _decimal.default(cormin), new _decimal.default(cormax).sub(new _decimal.default(0.99).mul(step)), step)).concat([cormax]);\n\n return min > max ? (0, _utils.reverse)(values) : values;\n}\n\nvar getNiceTickValues = (0, _utils.memoize)(getNiceTickValuesFn);\nexports.getNiceTickValues = getNiceTickValues;\nvar getTickValues = (0, _utils.memoize)(getTickValuesFn);\nexports.getTickValues = getTickValues;\nvar getTickValuesFixedDomain = (0, _utils.memoize)(getTickValuesFixedDomainFn);\nexports.getTickValuesFixedDomain = getTickValuesFixedDomain;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"getTickValues\", {\n enumerable: true,\n get: function get() {\n return _getNiceTickValues.getTickValues;\n }\n});\nObject.defineProperty(exports, \"getNiceTickValues\", {\n enumerable: true,\n get: function get() {\n return _getNiceTickValues.getNiceTickValues;\n }\n});\nObject.defineProperty(exports, \"getTickValuesFixedDomain\", {\n enumerable: true,\n get: function get() {\n return _getNiceTickValues.getTickValuesFixedDomain;\n }\n});\n\nvar _getNiceTickValues = require(\"./getNiceTickValues\");", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _decimal = _interopRequireDefault(require(\"decimal.js-light\"));\n\nvar _utils = require(\"./utils\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * @fileOverview 一些公用的运算方法\n * @author xile611\n * @date 2015-09-17\n */\n\n/**\n * 获取数值的位数\n * 其中绝对值属于区间[0.1, 1), 得到的值为0\n * 绝对值属于区间[0.01, 0.1),得到的位数为 -1\n * 绝对值属于区间[0.001, 0.01),得到的位数为 -2\n *\n * @param {Number} value 数值\n * @return {Integer} 位数\n */\nfunction getDigitCount(value) {\n var result;\n\n if (value === 0) {\n result = 1;\n } else {\n result = Math.floor(new _decimal.default(value).abs().log(10).toNumber()) + 1;\n }\n\n return result;\n}\n/**\n * 按照固定的步长获取[start, end)这个区间的数据\n * 并且需要处理js计算精度的问题\n *\n * @param {Decimal} start 起点\n * @param {Decimal} end 终点,不包含该值\n * @param {Decimal} step 步长\n * @return {Array} 若干数值\n */\n\n\nfunction rangeStep(start, end, step) {\n var num = new _decimal.default(start);\n var result = [];\n\n while (num.lt(end)) {\n result.push(num.toNumber());\n num = num.add(step);\n }\n\n return result;\n}\n/**\n * 对数值进行线性插值\n *\n * @param {Number} a 定义域的极点\n * @param {Number} b 定义域的极点\n * @param {Number} t [0, 1]内的某个值\n * @return {Number} 定义域内的某个值\n */\n\n\nvar interpolateNumber = (0, _utils.curry)(function (a, b, t) {\n var newA = +a;\n var newB = +b;\n return newA + t * (newB - newA);\n});\n/**\n * 线性插值的逆运算\n *\n * @param {Number} a 定义域的极点\n * @param {Number} b 定义域的极点\n * @param {Number} x 可以认为是插值后的一个输出值\n * @return {Number} 当x在 a ~ b这个范围内时,返回值属于[0, 1]\n */\n\nvar uninterpolateNumber = (0, _utils.curry)(function (a, b, x) {\n var diff = b - +a;\n diff = diff || Infinity;\n return (x - a) / diff;\n});\n/**\n * 线性插值的逆运算,并且有截断的操作\n *\n * @param {Number} a 定义域的极点\n * @param {Number} b 定义域的极点\n * @param {Number} x 可以认为是插值后的一个输出值\n * @return {Number} 当x在 a ~ b这个区间内时,返回值属于[0, 1],\n * 当x不在 a ~ b这个区间时,会截断到 a ~ b 这个区间\n */\n\nvar uninterpolateTruncation = (0, _utils.curry)(function (a, b, x) {\n var diff = b - +a;\n diff = diff || Infinity;\n return Math.max(0, Math.min(1, (x - a) / diff));\n});\nvar _default = {\n rangeStep: rangeStep,\n getDigitCount: getDigitCount,\n interpolateNumber: interpolateNumber,\n uninterpolateNumber: uninterpolateNumber,\n uninterpolateTruncation: uninterpolateTruncation\n};\nexports.default = _default;", + "\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.memoize = exports.reverse = exports.compose = exports.map = exports.range = exports.curry = exports.PLACE_HOLDER = void 0;\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nvar identity = function identity(i) {\n return i;\n};\n\nvar PLACE_HOLDER = {\n '@@functional/placeholder': true\n};\nexports.PLACE_HOLDER = PLACE_HOLDER;\n\nvar isPlaceHolder = function isPlaceHolder(val) {\n return val === PLACE_HOLDER;\n};\n\nvar curry0 = function curry0(fn) {\n return function _curried() {\n if (arguments.length === 0 || arguments.length === 1 && isPlaceHolder(arguments.length <= 0 ? undefined : arguments[0])) {\n return _curried;\n }\n\n return fn.apply(void 0, arguments);\n };\n};\n\nvar curryN = function curryN(n, fn) {\n if (n === 1) {\n return fn;\n }\n\n return curry0(function () {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var argsLength = args.filter(function (arg) {\n return arg !== PLACE_HOLDER;\n }).length;\n\n if (argsLength >= n) {\n return fn.apply(void 0, args);\n }\n\n return curryN(n - argsLength, curry0(function () {\n for (var _len2 = arguments.length, restArgs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n restArgs[_key2] = arguments[_key2];\n }\n\n var newArgs = args.map(function (arg) {\n return isPlaceHolder(arg) ? restArgs.shift() : arg;\n });\n return fn.apply(void 0, _toConsumableArray(newArgs).concat(restArgs));\n }));\n });\n};\n\nvar curry = function curry(fn) {\n return curryN(fn.length, fn);\n};\n\nexports.curry = curry;\n\nvar range = function range(begin, end) {\n var arr = [];\n\n for (var i = begin; i < end; ++i) {\n arr[i - begin] = i;\n }\n\n return arr;\n};\n\nexports.range = range;\nvar map = curry(function (fn, arr) {\n if (Array.isArray(arr)) {\n return arr.map(fn);\n }\n\n return Object.keys(arr).map(function (key) {\n return arr[key];\n }).map(fn);\n});\nexports.map = map;\n\nvar compose = function compose() {\n for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n args[_key3] = arguments[_key3];\n }\n\n if (!args.length) {\n return identity;\n }\n\n var fns = args.reverse(); // first function can receive multiply arguments\n\n var firstFn = fns[0];\n var tailsFn = fns.slice(1);\n return function () {\n return tailsFn.reduce(function (res, fn) {\n return fn(res);\n }, firstFn.apply(void 0, arguments));\n };\n};\n\nexports.compose = compose;\n\nvar reverse = function reverse(arr) {\n if (Array.isArray(arr)) {\n return arr.reverse();\n } // can be string\n\n\n return arr.split('').reverse.join('');\n};\n\nexports.reverse = reverse;\n\nvar memoize = function memoize(fn) {\n var lastArgs = null;\n var lastResult = null;\n return function () {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n\n if (lastArgs && args.every(function (val, i) {\n return val === lastArgs[i];\n })) {\n return lastResult;\n }\n\n lastArgs = args;\n lastResult = fn.apply(void 0, args);\n return lastResult;\n };\n};\n\nexports.memoize = memoize;", + "import _isEqual from \"lodash/isEqual\";\nimport _isNaN from \"lodash/isNaN\";\nimport _isFunction from \"lodash/isFunction\";\nimport _get from \"lodash/get\";\nimport _isNil from \"lodash/isNil\";\nimport _isArray from \"lodash/isArray\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Area\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Animate from 'react-smooth';\nimport Curve from '../shape/Curve';\nimport Dot from '../shape/Dot';\nimport Layer from '../container/Layer';\nimport LabelList from '../component/LabelList';\nimport pureRender from '../util/PureRender';\nimport { PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, LEGEND_TYPES, getPresentationAttributes, isSsr, filterEventAttributes } from '../util/ReactUtils';\nimport { isNumber, uniqueId, interpolateNumber } from '../util/DataUtils';\nimport { getCateCoordinateOfLine, getValueByDataKey } from '../util/ChartUtils';\n\nvar Area = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Area, _Component);\n\n function Area() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, Area);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Area)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n isAnimationFinished: true\n };\n _this.id = uniqueId('recharts-area-');\n\n _this.cachePrevData = function (points, baseLine) {\n _this.setState({\n prevPoints: points,\n prevBaseLine: baseLine\n });\n };\n\n _this.handleAnimationEnd = function () {\n var onAnimationEnd = _this.props.onAnimationEnd;\n\n _this.setState({\n isAnimationFinished: true\n });\n\n if (_isFunction(onAnimationEnd)) {\n onAnimationEnd();\n }\n };\n\n _this.handleAnimationStart = function () {\n var onAnimationStart = _this.props.onAnimationStart;\n\n _this.setState({\n isAnimationFinished: false\n });\n\n if (_isFunction(onAnimationStart)) {\n onAnimationStart();\n }\n };\n\n return _this;\n }\n\n _createClass(Area, [{\n key: \"componentWillReceiveProps\",\n value: function componentWillReceiveProps(nextProps) {\n var _this$props = this.props,\n animationId = _this$props.animationId,\n points = _this$props.points,\n baseLine = _this$props.baseLine;\n\n if (nextProps.animationId !== animationId) {\n this.cachePrevData(points, baseLine);\n }\n }\n }, {\n key: \"renderDots\",\n value: function renderDots(needClip, clipPathId) {\n var _this2 = this;\n\n var isAnimationActive = this.props.isAnimationActive;\n var isAnimationFinished = this.state.isAnimationFinished;\n\n if (isAnimationActive && !isAnimationFinished) {\n return null;\n }\n\n var _this$props2 = this.props,\n dot = _this$props2.dot,\n points = _this$props2.points,\n dataKey = _this$props2.dataKey;\n var areaProps = getPresentationAttributes(this.props);\n var customDotProps = getPresentationAttributes(dot);\n var dotEvents = filterEventAttributes(dot);\n var dots = points.map(function (entry, i) {\n var dotProps = _objectSpread({\n key: \"dot-\".concat(i),\n r: 3\n }, areaProps, customDotProps, dotEvents, {\n dataKey: dataKey,\n cx: entry.x,\n cy: entry.y,\n index: i,\n value: entry.value,\n payload: entry.payload\n });\n\n return _this2.constructor.renderDotItem(dot, dotProps);\n });\n var dotsProps = {\n clipPath: needClip ? \"url(#clipPath-\".concat(clipPathId, \")\") : null\n };\n return React.createElement(Layer, _extends({\n className: \"recharts-area-dots\"\n }, dotsProps), dots);\n }\n }, {\n key: \"renderHorizontalRect\",\n value: function renderHorizontalRect(alpha) {\n var _this$props3 = this.props,\n baseLine = _this$props3.baseLine,\n points = _this$props3.points,\n strokeWidth = _this$props3.strokeWidth;\n var startX = points[0].x;\n var endX = points[points.length - 1].x;\n var width = alpha * Math.abs(startX - endX);\n var maxY = Math.max.apply(null, points.map(function (entry) {\n return entry.y || 0;\n }));\n\n if (isNumber(baseLine)) {\n maxY = Math.max(baseLine, maxY);\n } else if (baseLine && _isArray(baseLine) && baseLine.length) {\n maxY = Math.max(Math.max.apply(null, baseLine.map(function (entry) {\n return entry.y || 0;\n })), maxY);\n }\n\n if (isNumber(maxY)) {\n return React.createElement(\"rect\", {\n x: startX < endX ? startX : startX - width,\n y: 0,\n width: width,\n height: parseInt(maxY + (strokeWidth || 1), 10)\n });\n }\n\n return null;\n }\n }, {\n key: \"renderVerticalRect\",\n value: function renderVerticalRect(alpha) {\n var _this$props4 = this.props,\n baseLine = _this$props4.baseLine,\n points = _this$props4.points,\n strokeWidth = _this$props4.strokeWidth;\n var startY = points[0].y;\n var endY = points[points.length - 1].y;\n var height = alpha * Math.abs(startY - endY);\n var maxX = Math.max.apply(null, points.map(function (entry) {\n return entry.x || 0;\n }));\n\n if (isNumber(baseLine)) {\n maxX = Math.max(baseLine, maxX);\n } else if (baseLine && _isArray(baseLine) && baseLine.length) {\n maxX = Math.max(Math.max.apply(null, baseLine.map(function (entry) {\n return entry.x || 0;\n })), maxX);\n }\n\n if (isNumber(maxX)) {\n return React.createElement(\"rect\", {\n x: 0,\n y: startY < endY ? startY : startY - height,\n width: maxX + (strokeWidth || 1),\n height: parseInt(height, 10)\n });\n }\n\n return null;\n }\n }, {\n key: \"renderClipRect\",\n value: function renderClipRect(alpha) {\n var layout = this.props.layout;\n\n if (layout === 'vertical') {\n return this.renderVerticalRect(alpha);\n }\n\n return this.renderHorizontalRect(alpha);\n }\n }, {\n key: \"renderAreaStatically\",\n value: function renderAreaStatically(points, baseLine, needClip, clipPathId) {\n var _this$props5 = this.props,\n layout = _this$props5.layout,\n type = _this$props5.type,\n stroke = _this$props5.stroke,\n connectNulls = _this$props5.connectNulls,\n isRange = _this$props5.isRange;\n return React.createElement(Layer, {\n clipPath: needClip ? \"url(#clipPath-\".concat(clipPathId, \")\") : null\n }, React.createElement(Curve, _extends({}, this.props, {\n points: points,\n baseLine: baseLine,\n stroke: \"none\",\n className: \"recharts-area-area\"\n })), stroke !== 'none' && React.createElement(Curve, _extends({}, getPresentationAttributes(this.props), {\n className: \"recharts-area-curve\",\n layout: layout,\n type: type,\n connectNulls: connectNulls,\n fill: \"none\",\n points: points\n })), stroke !== 'none' && isRange && React.createElement(Curve, _extends({}, getPresentationAttributes(this.props), {\n className: \"recharts-area-curve\",\n layout: layout,\n type: type,\n connectNulls: connectNulls,\n fill: \"none\",\n points: baseLine\n })));\n }\n }, {\n key: \"renderAreaWithAnimation\",\n value: function renderAreaWithAnimation(needClip, clipPathId) {\n var _this3 = this;\n\n var _this$props6 = this.props,\n points = _this$props6.points,\n baseLine = _this$props6.baseLine,\n isAnimationActive = _this$props6.isAnimationActive,\n animationBegin = _this$props6.animationBegin,\n animationDuration = _this$props6.animationDuration,\n animationEasing = _this$props6.animationEasing,\n animationId = _this$props6.animationId;\n var _this$state = this.state,\n prevPoints = _this$state.prevPoints,\n prevBaseLine = _this$state.prevBaseLine; // const clipPathId = _.isNil(id) ? this.id : id;\n\n return React.createElement(Animate, {\n begin: animationBegin,\n duration: animationDuration,\n isActive: isAnimationActive,\n easing: animationEasing,\n from: {\n t: 0\n },\n to: {\n t: 1\n },\n key: \"area-\".concat(animationId),\n onAnimationEnd: this.handleAnimationEnd,\n onAnimationStart: this.handleAnimationStart\n }, function (_ref) {\n var t = _ref.t;\n\n if (prevPoints) {\n var prevPointsDiffFactor = prevPoints.length / points.length; // update animtaion\n\n var stepPoints = points.map(function (entry, index) {\n var prevPointIndex = Math.floor(index * prevPointsDiffFactor);\n\n if (prevPoints[prevPointIndex]) {\n var prev = prevPoints[prevPointIndex];\n var interpolatorX = interpolateNumber(prev.x, entry.x);\n var interpolatorY = interpolateNumber(prev.y, entry.y);\n return _objectSpread({}, entry, {\n x: interpolatorX(t),\n y: interpolatorY(t)\n });\n }\n\n return entry;\n });\n var stepBaseLine;\n\n if (isNumber(baseLine)) {\n var interpolator = interpolateNumber(prevBaseLine, baseLine);\n stepBaseLine = interpolator(t);\n } else if (_isNil(baseLine) || _isNaN(baseLine)) {\n var _interpolator = interpolateNumber(prevBaseLine, 0);\n\n stepBaseLine = _interpolator(t);\n } else {\n stepBaseLine = baseLine.map(function (entry, index) {\n var prevPointIndex = Math.floor(index * prevPointsDiffFactor);\n\n if (prevBaseLine[prevPointIndex]) {\n var prev = prevBaseLine[prevPointIndex];\n var interpolatorX = interpolateNumber(prev.x, entry.x);\n var interpolatorY = interpolateNumber(prev.y, entry.y);\n return _objectSpread({}, entry, {\n x: interpolatorX(t),\n y: interpolatorY(t)\n });\n }\n\n return entry;\n });\n }\n\n return _this3.renderAreaStatically(stepPoints, stepBaseLine, needClip, clipPathId);\n }\n\n return React.createElement(Layer, null, React.createElement(\"defs\", null, React.createElement(\"clipPath\", {\n id: \"animationClipPath-\".concat(clipPathId)\n }, _this3.renderClipRect(t))), React.createElement(Layer, {\n clipPath: \"url(#animationClipPath-\".concat(clipPathId, \")\")\n }, _this3.renderAreaStatically(points, baseLine, needClip, clipPathId)));\n });\n }\n }, {\n key: \"renderArea\",\n value: function renderArea(needClip, clipPathId) {\n var _this$props7 = this.props,\n points = _this$props7.points,\n baseLine = _this$props7.baseLine,\n isAnimationActive = _this$props7.isAnimationActive;\n var _this$state2 = this.state,\n prevPoints = _this$state2.prevPoints,\n prevBaseLine = _this$state2.prevBaseLine,\n totalLength = _this$state2.totalLength;\n\n if (isAnimationActive && points && points.length && (!prevPoints && totalLength > 0 || !_isEqual(prevPoints, points) || !_isEqual(prevBaseLine, baseLine))) {\n return this.renderAreaWithAnimation(needClip, clipPathId);\n }\n\n return this.renderAreaStatically(points, baseLine, needClip, clipPathId);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props8 = this.props,\n hide = _this$props8.hide,\n dot = _this$props8.dot,\n points = _this$props8.points,\n className = _this$props8.className,\n top = _this$props8.top,\n left = _this$props8.left,\n xAxis = _this$props8.xAxis,\n yAxis = _this$props8.yAxis,\n width = _this$props8.width,\n height = _this$props8.height,\n isAnimationActive = _this$props8.isAnimationActive,\n id = _this$props8.id;\n\n if (hide || !points || !points.length) {\n return null;\n }\n\n var isAnimationFinished = this.state.isAnimationFinished;\n var hasSinglePoint = points.length === 1;\n var layerClass = classNames('recharts-area', className);\n var needClip = xAxis && xAxis.allowDataOverflow || yAxis && yAxis.allowDataOverflow;\n var clipPathId = _isNil(id) ? this.id : id;\n return React.createElement(Layer, {\n className: layerClass\n }, needClip ? React.createElement(\"defs\", null, React.createElement(\"clipPath\", {\n id: \"clipPath-\".concat(clipPathId)\n }, React.createElement(\"rect\", {\n x: left,\n y: top,\n width: width,\n height: parseInt(height, 10)\n }))) : null, !hasSinglePoint ? this.renderArea(needClip, clipPathId) : null, (dot || hasSinglePoint) && this.renderDots(needClip, clipPathId), (!isAnimationActive || isAnimationFinished) && LabelList.renderCallByParent(this.props, points));\n }\n }]);\n\n return Area;\n}(Component), _class2.displayName = 'Area', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, {\n className: PropTypes.string,\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]).isRequired,\n type: PropTypes.oneOfType([PropTypes.oneOf(['basis', 'basisClosed', 'basisOpen', 'linear', 'linearClosed', 'natural', 'monotoneX', 'monotoneY', 'monotone', 'step', 'stepBefore', 'stepAfter']), PropTypes.func]),\n unit: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n yAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n xAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n yAxis: PropTypes.object,\n xAxis: PropTypes.object,\n stackId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n legendType: PropTypes.oneOf(LEGEND_TYPES),\n connectNulls: PropTypes.bool,\n activeDot: PropTypes.oneOfType([PropTypes.object, PropTypes.element, PropTypes.func, PropTypes.bool]),\n // dot configuration\n dot: PropTypes.oneOfType([PropTypes.func, PropTypes.element, PropTypes.object, PropTypes.bool]),\n label: PropTypes.oneOfType([PropTypes.func, PropTypes.element, PropTypes.object, PropTypes.bool]),\n hide: PropTypes.bool,\n // have curve configuration\n layout: PropTypes.oneOf(['horizontal', 'vertical']),\n baseLine: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),\n isRange: PropTypes.bool,\n points: PropTypes.arrayOf(PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.array])\n })),\n onAnimationStart: PropTypes.func,\n onAnimationEnd: PropTypes.func,\n animationId: PropTypes.number,\n isAnimationActive: PropTypes.bool,\n animationBegin: PropTypes.number,\n animationDuration: PropTypes.number,\n animationEasing: PropTypes.oneOf(['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear']),\n id: PropTypes.string\n}), _class2.defaultProps = {\n stroke: '#3182bd',\n fill: '#3182bd',\n fillOpacity: 0.6,\n xAxisId: 0,\n yAxisId: 0,\n legendType: 'line',\n connectNulls: false,\n // points of area\n points: [],\n dot: false,\n activeDot: true,\n hide: false,\n isAnimationActive: !isSsr(),\n animationBegin: 0,\n animationDuration: 1500,\n animationEasing: 'ease'\n}, _class2.getBaseValue = function (props, xAxis, yAxis) {\n var layout = props.layout,\n baseValue = props.baseValue;\n\n if (isNumber(baseValue)) {\n return baseValue;\n }\n\n var numericAxis = layout === 'horizontal' ? yAxis : xAxis;\n var domain = numericAxis.scale.domain();\n\n if (numericAxis.type === 'number') {\n var max = Math.max(domain[0], domain[1]);\n var min = Math.min(domain[0], domain[1]);\n\n if (baseValue === 'dataMin') {\n return min;\n }\n\n if (baseValue === 'dataMax') {\n return max;\n }\n\n return max < 0 ? max : Math.max(Math.min(domain[0], domain[1]), 0);\n }\n\n if (baseValue === 'dataMin') {\n return domain[0];\n }\n\n if (baseValue === 'dataMax') {\n return domain[1];\n }\n\n return domain[0];\n}, _class2.getComposedData = function (_ref2) {\n var props = _ref2.props,\n xAxis = _ref2.xAxis,\n yAxis = _ref2.yAxis,\n xAxisTicks = _ref2.xAxisTicks,\n yAxisTicks = _ref2.yAxisTicks,\n bandSize = _ref2.bandSize,\n dataKey = _ref2.dataKey,\n stackedData = _ref2.stackedData,\n dataStartIndex = _ref2.dataStartIndex,\n displayedData = _ref2.displayedData,\n offset = _ref2.offset;\n var layout = props.layout;\n var hasStack = stackedData && stackedData.length;\n var baseValue = Area.getBaseValue(props, xAxis, yAxis);\n var isRange = false;\n var points = displayedData.map(function (entry, index) {\n var value;\n\n if (hasStack) {\n value = stackedData[dataStartIndex + index];\n } else {\n value = getValueByDataKey(entry, dataKey);\n\n if (!_isArray(value)) {\n value = [baseValue, value];\n } else {\n isRange = true;\n }\n }\n\n if (layout === 'horizontal') {\n return {\n x: getCateCoordinateOfLine({\n axis: xAxis,\n ticks: xAxisTicks,\n bandSize: bandSize,\n entry: entry,\n index: index\n }),\n y: _isNil(value[1]) ? null : yAxis.scale(value[1]),\n value: value,\n payload: entry\n };\n }\n\n return {\n x: _isNil(value[1]) ? null : xAxis.scale(value[1]),\n y: getCateCoordinateOfLine({\n axis: yAxis,\n ticks: yAxisTicks,\n bandSize: bandSize,\n entry: entry,\n index: index\n }),\n value: value,\n payload: entry\n };\n });\n var baseLine;\n\n if (hasStack || isRange) {\n baseLine = points.map(function (entry) {\n if (layout === 'horizontal') {\n return {\n x: entry.x,\n y: !_isNil(_get(entry, 'value[0]')) ? yAxis.scale(_get(entry, 'value[0]')) : null\n };\n }\n\n return {\n x: !_isNil(_get(entry, 'value[0]')) ? xAxis.scale(_get(entry, 'value[0]')) : null,\n y: entry.y\n };\n });\n } else if (layout === 'horizontal') {\n baseLine = yAxis.scale(baseValue);\n } else {\n baseLine = xAxis.scale(baseValue);\n }\n\n return _objectSpread({\n points: points,\n baseLine: baseLine,\n layout: layout,\n isRange: isRange\n }, offset);\n}, _class2.renderDotItem = function (option, props) {\n var dotItem;\n\n if (React.isValidElement(option)) {\n dotItem = React.cloneElement(option, props);\n } else if (_isFunction(option)) {\n dotItem = option(props);\n } else {\n dotItem = React.createElement(Dot, _extends({}, props, {\n className: \"recharts-area-dot\"\n }));\n }\n\n return dotItem;\n}, _temp)) || _class;\n\nexport default Area;", + "function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar PREFIX_LIST = ['Webkit', 'Moz', 'O', 'ms'];\nexport var generatePrefixStyle = function generatePrefixStyle(name, value) {\n if (!name) {\n return null;\n }\n\n var camelName = name.replace(/(\\w)/, function (v) {\n return v.toUpperCase();\n });\n var result = PREFIX_LIST.reduce(function (res, entry) {\n return _objectSpread({}, res, _defineProperty({}, entry + camelName, value));\n }, {});\n result[name] = value;\n return result;\n};", + "import _range from \"lodash/range\";\nimport _isFunction from \"lodash/isFunction\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n/**\n * @fileOverview Brush\n */\nimport React, { Component, Children } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { scalePoint } from 'd3-scale';\nimport { getValueByDataKey } from '../util/ChartUtils';\nimport pureRender from '../util/PureRender';\nimport Layer from '../container/Layer';\nimport Text from '../component/Text';\nimport { isNumber } from '../util/DataUtils';\nimport { generatePrefixStyle } from '../util/CssPrefixUtils';\n\nvar Brush = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Brush, _Component);\n\n function Brush(props) {\n var _this;\n\n _classCallCheck(this, Brush);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(Brush).call(this, props));\n\n _this.handleDrag = function (e) {\n if (_this.leaveTimer) {\n clearTimeout(_this.leaveTimer);\n _this.leaveTimer = null;\n }\n\n if (_this.state.isTravellerMoving) {\n _this.handleTravellerMove(e);\n } else if (_this.state.isSlideMoving) {\n _this.handleSlideDrag(e);\n }\n };\n\n _this.handleTouchMove = function (e) {\n if (e.changedTouches != null && e.changedTouches.length > 0) {\n _this.handleDrag(e.changedTouches[0]);\n }\n };\n\n _this.handleDragEnd = function () {\n _this.setState({\n isTravellerMoving: false,\n isSlideMoving: false\n });\n };\n\n _this.handleLeaveWrapper = function () {\n if (_this.state.isTravellerMoving || _this.state.isSlideMoving) {\n _this.leaveTimer = setTimeout(_this.handleDragEnd, _this.props.leaveTimeOut);\n }\n };\n\n _this.handleEnterSlideOrTraveller = function () {\n _this.setState({\n isTextActive: true\n });\n };\n\n _this.handleLeaveSlideOrTraveller = function () {\n _this.setState({\n isTextActive: false\n });\n };\n\n _this.handleSlideDragStart = function (e) {\n var event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;\n\n _this.setState({\n isTravellerMoving: false,\n isSlideMoving: true,\n slideMoveStartX: event.pageX\n });\n };\n\n _this.travellerDragStartHandlers = {\n startX: _this.handleTravellerDragStart.bind(_assertThisInitialized(_assertThisInitialized(_this)), 'startX'),\n endX: _this.handleTravellerDragStart.bind(_assertThisInitialized(_assertThisInitialized(_this)), 'endX')\n };\n _this.state = props.data && props.data.length ? _this.updateScale(props) : {};\n return _this;\n }\n\n _createClass(Brush, [{\n key: \"componentWillReceiveProps\",\n value: function componentWillReceiveProps(nextProps) {\n var _this2 = this;\n\n var _this$props = this.props,\n data = _this$props.data,\n width = _this$props.width,\n x = _this$props.x,\n travellerWidth = _this$props.travellerWidth,\n updateId = _this$props.updateId;\n\n if ((nextProps.data !== data || nextProps.updateId !== updateId) && nextProps.data && nextProps.data.length) {\n this.setState(this.updateScale(nextProps));\n } else if (nextProps.width !== width || nextProps.x !== x || nextProps.travellerWidth !== travellerWidth) {\n this.scale.range([nextProps.x, nextProps.x + nextProps.width - nextProps.travellerWidth]);\n this.scaleValues = this.scale.domain().map(function (entry) {\n return _this2.scale(entry);\n });\n this.setState({\n startX: this.scale(nextProps.startIndex),\n endX: this.scale(nextProps.endIndex)\n });\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.scale = null;\n this.scaleValues = null;\n\n if (this.leaveTimer) {\n clearTimeout(this.leaveTimer);\n this.leaveTimer = null;\n }\n }\n }, {\n key: \"getIndex\",\n value: function getIndex(_ref) {\n var startX = _ref.startX,\n endX = _ref.endX;\n var _this$props2 = this.props,\n gap = _this$props2.gap,\n data = _this$props2.data;\n var lastIndex = data.length - 1;\n var min = Math.min(startX, endX);\n var max = Math.max(startX, endX);\n var minIndex = this.constructor.getIndexInRange(this.scaleValues, min);\n var maxIndex = this.constructor.getIndexInRange(this.scaleValues, max);\n return {\n startIndex: minIndex - minIndex % gap,\n endIndex: maxIndex === lastIndex ? lastIndex : maxIndex - maxIndex % gap\n };\n }\n }, {\n key: \"getTextOfTick\",\n value: function getTextOfTick(index) {\n var _this$props3 = this.props,\n data = _this$props3.data,\n tickFormatter = _this$props3.tickFormatter,\n dataKey = _this$props3.dataKey;\n var text = getValueByDataKey(data[index], dataKey, index);\n return _isFunction(tickFormatter) ? tickFormatter(text) : text;\n }\n }, {\n key: \"handleSlideDrag\",\n value: function handleSlideDrag(e) {\n var _this$state = this.state,\n slideMoveStartX = _this$state.slideMoveStartX,\n startX = _this$state.startX,\n endX = _this$state.endX;\n var _this$props4 = this.props,\n x = _this$props4.x,\n width = _this$props4.width,\n travellerWidth = _this$props4.travellerWidth,\n startIndex = _this$props4.startIndex,\n endIndex = _this$props4.endIndex,\n onChange = _this$props4.onChange;\n var delta = e.pageX - slideMoveStartX;\n\n if (delta > 0) {\n delta = Math.min(delta, x + width - travellerWidth - endX, x + width - travellerWidth - startX);\n } else if (delta < 0) {\n delta = Math.max(delta, x - startX, x - endX);\n }\n\n var newIndex = this.getIndex({\n startX: startX + delta,\n endX: endX + delta\n });\n\n if ((newIndex.startIndex !== startIndex || newIndex.endIndex !== endIndex) && onChange) {\n onChange(newIndex);\n }\n\n this.setState({\n startX: startX + delta,\n endX: endX + delta,\n slideMoveStartX: e.pageX\n });\n }\n }, {\n key: \"handleTravellerDragStart\",\n value: function handleTravellerDragStart(id, e) {\n var event = e.changedTouches && e.changedTouches.length ? e.changedTouches[0] : e;\n this.setState({\n isSlideMoving: false,\n isTravellerMoving: true,\n movingTravellerId: id,\n brushMoveStartX: event.pageX\n });\n }\n }, {\n key: \"handleTravellerMove\",\n value: function handleTravellerMove(e) {\n var _this$setState;\n\n var _this$state2 = this.state,\n brushMoveStartX = _this$state2.brushMoveStartX,\n movingTravellerId = _this$state2.movingTravellerId,\n endX = _this$state2.endX,\n startX = _this$state2.startX;\n var prevValue = this.state[movingTravellerId];\n var _this$props5 = this.props,\n x = _this$props5.x,\n width = _this$props5.width,\n travellerWidth = _this$props5.travellerWidth,\n onChange = _this$props5.onChange,\n gap = _this$props5.gap,\n data = _this$props5.data;\n var params = {\n startX: this.state.startX,\n endX: this.state.endX\n };\n var delta = e.pageX - brushMoveStartX;\n\n if (delta > 0) {\n delta = Math.min(delta, x + width - travellerWidth - prevValue);\n } else if (delta < 0) {\n delta = Math.max(delta, x - prevValue);\n }\n\n params[movingTravellerId] = prevValue + delta;\n var newIndex = this.getIndex(params);\n var startIndex = newIndex.startIndex,\n endIndex = newIndex.endIndex;\n\n var isFullGap = function isFullGap() {\n var lastIndex = data.length - 1;\n\n if (movingTravellerId === 'startX' && (endX > startX ? startIndex % gap === 0 : endIndex % gap === 0) || endX < startX && endIndex === lastIndex || movingTravellerId === 'endX' && (endX > startX ? endIndex % gap === 0 : startIndex % gap === 0) || endX > startX && endIndex === lastIndex) {\n return true;\n }\n\n return false;\n };\n\n this.setState((_this$setState = {}, _defineProperty(_this$setState, movingTravellerId, prevValue + delta), _defineProperty(_this$setState, \"brushMoveStartX\", e.pageX), _this$setState), function () {\n if (onChange) {\n if (isFullGap()) {\n onChange(newIndex);\n }\n }\n });\n }\n }, {\n key: \"updateScale\",\n value: function updateScale(props) {\n var _this3 = this;\n\n var data = props.data,\n startIndex = props.startIndex,\n endIndex = props.endIndex,\n x = props.x,\n width = props.width,\n travellerWidth = props.travellerWidth;\n var len = data.length;\n this.scale = scalePoint().domain(_range(0, len)).range([x, x + width - travellerWidth]);\n this.scaleValues = this.scale.domain().map(function (entry) {\n return _this3.scale(entry);\n });\n return {\n isTextActive: false,\n isSlideMoving: false,\n isTravellerMoving: false,\n startX: this.scale(startIndex),\n endX: this.scale(endIndex)\n };\n }\n }, {\n key: \"renderBackground\",\n value: function renderBackground() {\n var _this$props6 = this.props,\n x = _this$props6.x,\n y = _this$props6.y,\n width = _this$props6.width,\n height = _this$props6.height,\n fill = _this$props6.fill,\n stroke = _this$props6.stroke;\n return React.createElement(\"rect\", {\n stroke: stroke,\n fill: fill,\n x: x,\n y: y,\n width: width,\n height: height\n });\n }\n }, {\n key: \"renderPanorama\",\n value: function renderPanorama() {\n var _this$props7 = this.props,\n x = _this$props7.x,\n y = _this$props7.y,\n width = _this$props7.width,\n height = _this$props7.height,\n data = _this$props7.data,\n children = _this$props7.children,\n padding = _this$props7.padding;\n var chartElement = Children.only(children);\n\n if (!chartElement) {\n return null;\n }\n\n return React.cloneElement(chartElement, {\n x: x,\n y: y,\n width: width,\n height: height,\n margin: padding,\n compact: true,\n data: data\n });\n }\n }, {\n key: \"renderTraveller\",\n value: function renderTraveller(travellerX, id) {\n var _this$props8 = this.props,\n y = _this$props8.y,\n travellerWidth = _this$props8.travellerWidth,\n height = _this$props8.height,\n stroke = _this$props8.stroke;\n var lineY = Math.floor(y + height / 2) - 1;\n var x = Math.max(travellerX, this.props.x);\n return React.createElement(Layer, {\n className: \"recharts-brush-traveller\",\n onMouseEnter: this.handleEnterSlideOrTraveller,\n onMouseLeave: this.handleLeaveSlideOrTraveller,\n onMouseDown: this.travellerDragStartHandlers[id],\n onTouchStart: this.travellerDragStartHandlers[id],\n style: {\n cursor: 'col-resize'\n }\n }, React.createElement(\"rect\", {\n x: x,\n y: y,\n width: travellerWidth,\n height: height,\n fill: stroke,\n stroke: \"none\"\n }), React.createElement(\"line\", {\n x1: x + 1,\n y1: lineY,\n x2: x + travellerWidth - 1,\n y2: lineY,\n fill: \"none\",\n stroke: \"#fff\"\n }), React.createElement(\"line\", {\n x1: x + 1,\n y1: lineY + 2,\n x2: x + travellerWidth - 1,\n y2: lineY + 2,\n fill: \"none\",\n stroke: \"#fff\"\n }));\n }\n }, {\n key: \"renderSlide\",\n value: function renderSlide(startX, endX) {\n var _this$props9 = this.props,\n y = _this$props9.y,\n height = _this$props9.height,\n stroke = _this$props9.stroke;\n return React.createElement(\"rect\", {\n className: \"recharts-brush-slide\",\n onMouseEnter: this.handleEnterSlideOrTraveller,\n onMouseLeave: this.handleLeaveSlideOrTraveller,\n onMouseDown: this.handleSlideDragStart,\n onTouchStart: this.handleSlideDragStart,\n style: {\n cursor: 'move'\n },\n stroke: \"none\",\n fill: stroke,\n fillOpacity: 0.2,\n x: Math.min(startX, endX),\n y: y,\n width: Math.abs(endX - startX),\n height: height\n });\n }\n }, {\n key: \"renderText\",\n value: function renderText() {\n var _this$props10 = this.props,\n startIndex = _this$props10.startIndex,\n endIndex = _this$props10.endIndex,\n y = _this$props10.y,\n height = _this$props10.height,\n travellerWidth = _this$props10.travellerWidth,\n stroke = _this$props10.stroke;\n var _this$state3 = this.state,\n startX = _this$state3.startX,\n endX = _this$state3.endX;\n var offset = 5;\n var attrs = {\n pointerEvents: 'none',\n fill: stroke\n };\n return React.createElement(Layer, {\n className: \"recharts-brush-texts\"\n }, React.createElement(Text, _extends({\n textAnchor: \"end\",\n verticalAnchor: \"middle\",\n x: Math.min(startX, endX) - offset,\n y: y + height / 2\n }, attrs), this.getTextOfTick(startIndex)), React.createElement(Text, _extends({\n textAnchor: \"start\",\n verticalAnchor: \"middle\",\n x: Math.max(startX, endX) + travellerWidth + offset,\n y: y + height / 2\n }, attrs), this.getTextOfTick(endIndex)));\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props11 = this.props,\n data = _this$props11.data,\n className = _this$props11.className,\n children = _this$props11.children,\n x = _this$props11.x,\n y = _this$props11.y,\n width = _this$props11.width,\n height = _this$props11.height;\n var _this$state4 = this.state,\n startX = _this$state4.startX,\n endX = _this$state4.endX,\n isTextActive = _this$state4.isTextActive,\n isSlideMoving = _this$state4.isSlideMoving,\n isTravellerMoving = _this$state4.isTravellerMoving;\n\n if (!data || !data.length || !isNumber(x) || !isNumber(y) || !isNumber(width) || !isNumber(height) || width <= 0 || height <= 0) {\n return null;\n }\n\n var layerClass = classNames('recharts-brush', className);\n var isPanoramic = React.Children.count(children) === 1;\n var style = generatePrefixStyle('userSelect', 'none');\n return React.createElement(Layer, {\n className: layerClass,\n onMouseMove: this.handleDrag,\n onMouseLeave: this.handleLeaveWrapper,\n onMouseUp: this.handleDragEnd,\n onTouchEnd: this.handleDragEnd,\n onTouchMove: this.handleTouchMove,\n style: style\n }, this.renderBackground(), isPanoramic && this.renderPanorama(), this.renderSlide(startX, endX), this.renderTraveller(startX, 'startX'), this.renderTraveller(endX, 'endX'), (isTextActive || isSlideMoving || isTravellerMoving) && this.renderText());\n }\n }], [{\n key: \"getIndexInRange\",\n value: function getIndexInRange(range, x) {\n var len = range.length;\n var start = 0;\n var end = len - 1;\n\n while (end - start > 1) {\n var middle = Math.floor((start + end) / 2);\n\n if (range[middle] > x) {\n end = middle;\n } else {\n start = middle;\n }\n }\n\n return x >= range[end] ? end : start;\n }\n }]);\n\n return Brush;\n}(Component), _class2.displayName = 'Brush', _class2.propTypes = {\n className: PropTypes.string,\n fill: PropTypes.string,\n stroke: PropTypes.string,\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number.isRequired,\n travellerWidth: PropTypes.number,\n gap: PropTypes.number,\n padding: PropTypes.shape({\n top: PropTypes.number,\n right: PropTypes.number,\n bottom: PropTypes.number,\n left: PropTypes.number\n }),\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]),\n data: PropTypes.array,\n startIndex: PropTypes.number,\n endIndex: PropTypes.number,\n tickFormatter: PropTypes.func,\n children: PropTypes.node,\n onChange: PropTypes.func,\n updateId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n leaveTimeOut: PropTypes.number\n}, _class2.defaultProps = {\n height: 40,\n travellerWidth: 5,\n gap: 1,\n fill: '#fff',\n stroke: '#666',\n padding: {\n top: 1,\n right: 1,\n bottom: 1,\n left: 1\n },\n leaveTimeOut: 1000\n}, _temp)) || _class;\n\nexport default Brush;", + "import _isFunction from \"lodash/isFunction\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Cartesian Axis\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { shallowEqual } from '../util/PureRender';\nimport { getStringSize } from '../util/DOMUtils';\nimport Layer from '../container/Layer';\nimport Text from '../component/Text';\nimport Label from '../component/Label';\nimport { isSsr, PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, getPresentationAttributes, filterEventsOfChild } from '../util/ReactUtils';\nimport { isNumber, mathSign } from '../util/DataUtils';\n\nvar CartesianAxis =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(CartesianAxis, _Component);\n\n function CartesianAxis() {\n _classCallCheck(this, CartesianAxis);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(CartesianAxis).apply(this, arguments));\n }\n\n _createClass(CartesianAxis, [{\n key: \"shouldComponentUpdate\",\n value: function shouldComponentUpdate(_ref, state) {\n var viewBox = _ref.viewBox,\n restProps = _objectWithoutProperties(_ref, [\"viewBox\"]);\n\n // props.viewBox is sometimes generated every time -\n // check that specially as object equality is likely to fail\n var _this$props = this.props,\n viewBoxOld = _this$props.viewBox,\n restPropsOld = _objectWithoutProperties(_this$props, [\"viewBox\"]);\n\n return !shallowEqual(viewBox, viewBoxOld) || !shallowEqual(restProps, restPropsOld) || !shallowEqual(state, this.state);\n }\n /**\n * Calculate the coordinates of endpoints in ticks\n * @param {Object} data The data of a simple tick\n * @return {Object} (x1, y1): The coordinate of endpoint close to tick text\n * (x2, y2): The coordinate of endpoint close to axis\n */\n\n }, {\n key: \"getTickLineCoord\",\n value: function getTickLineCoord(data) {\n var _this$props2 = this.props,\n x = _this$props2.x,\n y = _this$props2.y,\n width = _this$props2.width,\n height = _this$props2.height,\n orientation = _this$props2.orientation,\n tickSize = _this$props2.tickSize,\n mirror = _this$props2.mirror,\n tickMargin = _this$props2.tickMargin;\n var x1, x2, y1, y2, tx, ty;\n var sign = mirror ? -1 : 1;\n var finalTickSize = data.tickSize || tickSize;\n var tickCoord = isNumber(data.tickCoord) ? data.tickCoord : data.coordinate;\n\n switch (orientation) {\n case 'top':\n x1 = x2 = data.coordinate;\n y2 = y + !mirror * height;\n y1 = y2 - sign * finalTickSize;\n ty = y1 - sign * tickMargin;\n tx = tickCoord;\n break;\n\n case 'left':\n y1 = y2 = data.coordinate;\n x2 = x + !mirror * width;\n x1 = x2 - sign * finalTickSize;\n tx = x1 - sign * tickMargin;\n ty = tickCoord;\n break;\n\n case 'right':\n y1 = y2 = data.coordinate;\n x2 = x + mirror * width;\n x1 = x2 + sign * finalTickSize;\n tx = x1 + sign * tickMargin;\n ty = tickCoord;\n break;\n\n default:\n x1 = x2 = data.coordinate;\n y2 = y + mirror * height;\n y1 = y2 + sign * finalTickSize;\n ty = y1 + sign * tickMargin;\n tx = tickCoord;\n break;\n }\n\n return {\n line: {\n x1: x1,\n y1: y1,\n x2: x2,\n y2: y2\n },\n tick: {\n x: tx,\n y: ty\n }\n };\n }\n }, {\n key: \"getTickTextAnchor\",\n value: function getTickTextAnchor() {\n var _this$props3 = this.props,\n orientation = _this$props3.orientation,\n mirror = _this$props3.mirror;\n var textAnchor;\n\n switch (orientation) {\n case 'left':\n textAnchor = mirror ? 'start' : 'end';\n break;\n\n case 'right':\n textAnchor = mirror ? 'end' : 'start';\n break;\n\n default:\n textAnchor = 'middle';\n break;\n }\n\n return textAnchor;\n }\n }, {\n key: \"getTickVerticalAnchor\",\n value: function getTickVerticalAnchor() {\n var _this$props4 = this.props,\n orientation = _this$props4.orientation,\n mirror = _this$props4.mirror;\n var verticalAnchor = 'end';\n\n switch (orientation) {\n case 'left':\n case 'right':\n verticalAnchor = 'middle';\n break;\n\n case 'top':\n verticalAnchor = mirror ? 'start' : 'end';\n break;\n\n default:\n verticalAnchor = mirror ? 'end' : 'start';\n break;\n }\n\n return verticalAnchor;\n }\n }, {\n key: \"renderAxisLine\",\n value: function renderAxisLine() {\n var _this$props5 = this.props,\n x = _this$props5.x,\n y = _this$props5.y,\n width = _this$props5.width,\n height = _this$props5.height,\n orientation = _this$props5.orientation,\n axisLine = _this$props5.axisLine,\n mirror = _this$props5.mirror;\n\n var props = _objectSpread({}, getPresentationAttributes(this.props), {\n fill: 'none'\n }, getPresentationAttributes(axisLine));\n\n if (orientation === 'top' || orientation === 'bottom') {\n var needHeight = orientation === 'top' && !mirror || orientation === 'bottom' && mirror;\n props = _objectSpread({}, props, {\n x1: x,\n y1: y + needHeight * height,\n x2: x + width,\n y2: y + needHeight * height\n });\n } else {\n var needWidth = orientation === 'left' && !mirror || orientation === 'right' && mirror;\n props = _objectSpread({}, props, {\n x1: x + needWidth * width,\n y1: y,\n x2: x + needWidth * width,\n y2: y + height\n });\n }\n\n return React.createElement(\"line\", _extends({\n className: \"recharts-cartesian-axis-line\"\n }, props));\n }\n }, {\n key: \"renderTicks\",\n\n /**\n * render the ticks\n * @param {Array} ticks The ticks to actually render (overrides what was passed in props)\n * @return {ReactComponent} renderedTicks\n */\n value: function renderTicks(ticks) {\n var _this = this;\n\n var _this$props6 = this.props,\n tickLine = _this$props6.tickLine,\n stroke = _this$props6.stroke,\n tick = _this$props6.tick,\n tickFormatter = _this$props6.tickFormatter,\n unit = _this$props6.unit;\n var finalTicks = CartesianAxis.getTicks(_objectSpread({}, this.props, {\n ticks: ticks\n }));\n var textAnchor = this.getTickTextAnchor();\n var verticalAnchor = this.getTickVerticalAnchor();\n var axisProps = getPresentationAttributes(this.props);\n var customTickProps = getPresentationAttributes(tick);\n\n var tickLineProps = _objectSpread({}, axisProps, {\n fill: 'none'\n }, getPresentationAttributes(tickLine));\n\n var items = finalTicks.map(function (entry, i) {\n var _this$getTickLineCoor = _this.getTickLineCoord(entry),\n lineCoord = _this$getTickLineCoor.line,\n tickCoord = _this$getTickLineCoor.tick;\n\n var tickProps = _objectSpread({\n textAnchor: textAnchor,\n verticalAnchor: verticalAnchor\n }, axisProps, {\n stroke: 'none',\n fill: stroke\n }, customTickProps, tickCoord, {\n index: i,\n payload: entry,\n visibleTicksCount: finalTicks.length\n });\n\n return React.createElement(Layer, _extends({\n className: \"recharts-cartesian-axis-tick\",\n key: \"tick-\".concat(i)\n }, filterEventsOfChild(_this.props, entry, i)), tickLine && React.createElement(\"line\", _extends({\n className: \"recharts-cartesian-axis-tick-line\"\n }, tickLineProps, lineCoord)), tick && _this.constructor.renderTickItem(tick, tickProps, \"\".concat(_isFunction(tickFormatter) ? tickFormatter(entry.value) : entry.value).concat(unit || '')));\n });\n return React.createElement(\"g\", {\n className: \"recharts-cartesian-axis-ticks\"\n }, items);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props7 = this.props,\n axisLine = _this$props7.axisLine,\n width = _this$props7.width,\n height = _this$props7.height,\n ticksGenerator = _this$props7.ticksGenerator,\n className = _this$props7.className,\n hide = _this$props7.hide;\n\n if (hide) {\n return null;\n }\n\n var _this$props8 = this.props,\n ticks = _this$props8.ticks,\n noTicksProps = _objectWithoutProperties(_this$props8, [\"ticks\"]);\n\n var finalTicks = ticks;\n\n if (_isFunction(ticksGenerator)) {\n finalTicks = ticks && ticks.length > 0 ? ticksGenerator(this.props) : ticksGenerator(noTicksProps);\n }\n\n if (width <= 0 || height <= 0 || !finalTicks || !finalTicks.length) {\n return null;\n }\n\n return React.createElement(Layer, {\n className: classNames('recharts-cartesian-axis', className)\n }, axisLine && this.renderAxisLine(), this.renderTicks(finalTicks), Label.renderCallByParent(this.props));\n }\n }], [{\n key: \"getTicks\",\n value: function getTicks(props) {\n var tick = props.tick,\n ticks = props.ticks,\n viewBox = props.viewBox,\n minTickGap = props.minTickGap,\n orientation = props.orientation,\n interval = props.interval,\n tickFormatter = props.tickFormatter,\n unit = props.unit;\n\n if (!ticks || !ticks.length || !tick) {\n return [];\n }\n\n if (isNumber(interval) || isSsr()) {\n return CartesianAxis.getNumberIntervalTicks(ticks, isNumber(interval) ? interval : 0);\n }\n\n if (interval === 'preserveStartEnd') {\n return CartesianAxis.getTicksStart({\n ticks: ticks,\n tickFormatter: tickFormatter,\n viewBox: viewBox,\n orientation: orientation,\n minTickGap: minTickGap,\n unit: unit\n }, true);\n }\n\n if (interval === 'preserveStart') {\n return CartesianAxis.getTicksStart({\n ticks: ticks,\n tickFormatter: tickFormatter,\n viewBox: viewBox,\n orientation: orientation,\n minTickGap: minTickGap,\n unit: unit\n });\n }\n\n return CartesianAxis.getTicksEnd({\n ticks: ticks,\n tickFormatter: tickFormatter,\n viewBox: viewBox,\n orientation: orientation,\n minTickGap: minTickGap,\n unit: unit\n });\n }\n }, {\n key: \"getNumberIntervalTicks\",\n value: function getNumberIntervalTicks(ticks, interval) {\n return ticks.filter(function (entry, i) {\n return i % (interval + 1) === 0;\n });\n }\n }, {\n key: \"getTicksStart\",\n value: function getTicksStart(_ref2, preserveEnd) {\n var ticks = _ref2.ticks,\n tickFormatter = _ref2.tickFormatter,\n viewBox = _ref2.viewBox,\n orientation = _ref2.orientation,\n minTickGap = _ref2.minTickGap,\n unit = _ref2.unit;\n var x = viewBox.x,\n y = viewBox.y,\n width = viewBox.width,\n height = viewBox.height;\n var sizeKey = orientation === 'top' || orientation === 'bottom' ? 'width' : 'height';\n var result = (ticks || []).slice(); // we need add the width of 'unit' only when sizeKey === 'width'\n\n var unitSize = unit && sizeKey === 'width' ? getStringSize(unit)[sizeKey] : 0;\n var len = result.length;\n var sign = len >= 2 ? mathSign(result[1].coordinate - result[0].coordinate) : 1;\n var start, end;\n\n if (sign === 1) {\n start = sizeKey === 'width' ? x : y;\n end = sizeKey === 'width' ? x + width : y + height;\n } else {\n start = sizeKey === 'width' ? x + width : y + height;\n end = sizeKey === 'width' ? x : y;\n }\n\n if (preserveEnd) {\n // Try to guarantee the tail to be displayed\n var tail = ticks[len - 1];\n var tailContent = _isFunction(tickFormatter) ? tickFormatter(tail.value) : tail.value;\n var tailSize = getStringSize(tailContent)[sizeKey] + unitSize;\n var tailGap = sign * (tail.coordinate + sign * tailSize / 2 - end);\n result[len - 1] = tail = _objectSpread({}, tail, {\n tickCoord: tailGap > 0 ? tail.coordinate - tailGap * sign : tail.coordinate\n });\n var isTailShow = sign * (tail.tickCoord - sign * tailSize / 2 - start) >= 0 && sign * (tail.tickCoord + sign * tailSize / 2 - end) <= 0;\n\n if (isTailShow) {\n end = tail.tickCoord - sign * (tailSize / 2 + minTickGap);\n result[len - 1] = _objectSpread({}, tail, {\n isShow: true\n });\n }\n }\n\n var count = preserveEnd ? len - 1 : len;\n\n for (var i = 0; i < count; i++) {\n var entry = result[i];\n var content = _isFunction(tickFormatter) ? tickFormatter(entry.value) : entry.value;\n var size = getStringSize(content)[sizeKey] + unitSize;\n\n if (i === 0) {\n var gap = sign * (entry.coordinate - sign * size / 2 - start);\n result[i] = entry = _objectSpread({}, entry, {\n tickCoord: gap < 0 ? entry.coordinate - gap * sign : entry.coordinate\n });\n } else {\n result[i] = entry = _objectSpread({}, entry, {\n tickCoord: entry.coordinate\n });\n }\n\n var isShow = sign * (entry.tickCoord - sign * size / 2 - start) >= 0 && sign * (entry.tickCoord + sign * size / 2 - end) <= 0;\n\n if (isShow) {\n start = entry.tickCoord + sign * (size / 2 + minTickGap);\n result[i] = _objectSpread({}, entry, {\n isShow: true\n });\n }\n }\n\n return result.filter(function (entry) {\n return entry.isShow;\n });\n }\n }, {\n key: \"getTicksEnd\",\n value: function getTicksEnd(_ref3) {\n var ticks = _ref3.ticks,\n tickFormatter = _ref3.tickFormatter,\n viewBox = _ref3.viewBox,\n orientation = _ref3.orientation,\n minTickGap = _ref3.minTickGap,\n unit = _ref3.unit;\n var x = viewBox.x,\n y = viewBox.y,\n width = viewBox.width,\n height = viewBox.height;\n var sizeKey = orientation === 'top' || orientation === 'bottom' ? 'width' : 'height'; // we need add the width of 'unit' only when sizeKey === 'width'\n\n var unitSize = unit && sizeKey === 'width' ? getStringSize(unit)[sizeKey] : 0;\n var result = (ticks || []).slice();\n var len = result.length;\n var sign = len >= 2 ? mathSign(result[1].coordinate - result[0].coordinate) : 1;\n var start, end;\n\n if (sign === 1) {\n start = sizeKey === 'width' ? x : y;\n end = sizeKey === 'width' ? x + width : y + height;\n } else {\n start = sizeKey === 'width' ? x + width : y + height;\n end = sizeKey === 'width' ? x : y;\n }\n\n for (var i = len - 1; i >= 0; i--) {\n var entry = result[i];\n var content = _isFunction(tickFormatter) ? tickFormatter(entry.value) : entry.value;\n var size = getStringSize(content)[sizeKey] + unitSize;\n\n if (i === len - 1) {\n var gap = sign * (entry.coordinate + sign * size / 2 - end);\n result[i] = entry = _objectSpread({}, entry, {\n tickCoord: gap > 0 ? entry.coordinate - gap * sign : entry.coordinate\n });\n } else {\n result[i] = entry = _objectSpread({}, entry, {\n tickCoord: entry.coordinate\n });\n }\n\n var isShow = sign * (entry.tickCoord - sign * size / 2 - start) >= 0 && sign * (entry.tickCoord + sign * size / 2 - end) <= 0;\n\n if (isShow) {\n end = entry.tickCoord - sign * (size / 2 + minTickGap);\n result[i] = _objectSpread({}, entry, {\n isShow: true\n });\n }\n }\n\n return result.filter(function (entry) {\n return entry.isShow;\n });\n }\n }, {\n key: \"renderTickItem\",\n value: function renderTickItem(option, props, value) {\n var tickItem;\n\n if (React.isValidElement(option)) {\n tickItem = React.cloneElement(option, props);\n } else if (_isFunction(option)) {\n tickItem = option(props);\n } else {\n tickItem = React.createElement(Text, _extends({}, props, {\n className: \"recharts-cartesian-axis-tick-value\"\n }), value);\n }\n\n return tickItem;\n }\n }]);\n\n return CartesianAxis;\n}(Component);\n\nCartesianAxis.displayName = 'CartesianAxis';\nCartesianAxis.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, {\n className: PropTypes.string,\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number,\n orientation: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),\n // The viewBox of svg\n viewBox: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n }),\n tick: PropTypes.oneOfType([PropTypes.bool, PropTypes.func, PropTypes.object, PropTypes.element]),\n axisLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n tickLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n mirror: PropTypes.bool,\n tickMargin: PropTypes.number.isRequired,\n minTickGap: PropTypes.number,\n ticks: PropTypes.array,\n tickSize: PropTypes.number,\n stroke: PropTypes.string,\n tickFormatter: PropTypes.func,\n ticksGenerator: PropTypes.func,\n interval: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(['preserveStart', 'preserveEnd', 'preserveStartEnd'])])\n});\nCartesianAxis.defaultProps = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n viewBox: {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n },\n // The orientation of axis\n orientation: 'bottom',\n // The ticks\n ticks: [],\n stroke: '#666',\n tickLine: true,\n axisLine: true,\n tick: true,\n mirror: false,\n minTickGap: 5,\n // The width or height of tick\n tickSize: 6,\n tickMargin: 2,\n interval: 'preserveEnd'\n};\nexport default CartesianAxis;", + "function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Render a group of error bar\n*/\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Layer from '../container/Layer';\nimport { getPresentationAttributes } from '../util/ReactUtils';\n\nvar ErrorBar =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(ErrorBar, _Component);\n\n function ErrorBar() {\n _classCallCheck(this, ErrorBar);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(ErrorBar).apply(this, arguments));\n }\n\n _createClass(ErrorBar, [{\n key: \"renderErrorBars\",\n value: function renderErrorBars() {\n var _this$props = this.props,\n offset = _this$props.offset,\n layout = _this$props.layout,\n width = _this$props.width,\n dataKey = _this$props.dataKey,\n data = _this$props.data,\n dataPointFormatter = _this$props.dataPointFormatter,\n xAxis = _this$props.xAxis,\n yAxis = _this$props.yAxis,\n others = _objectWithoutProperties(_this$props, [\"offset\", \"layout\", \"width\", \"dataKey\", \"data\", \"dataPointFormatter\", \"xAxis\", \"yAxis\"]);\n\n var props = getPresentationAttributes(others);\n return data.map(function (entry, i) {\n var _dataPointFormatter = dataPointFormatter(entry, dataKey),\n x = _dataPointFormatter.x,\n y = _dataPointFormatter.y,\n value = _dataPointFormatter.value,\n errorVal = _dataPointFormatter.errorVal;\n\n if (!errorVal) {\n return null;\n }\n\n var xMid, yMid, xMin, yMin, xMax, yMax, scale, coordsTop, coordsMid, coordsBot, lowBound, highBound;\n\n if (Array.isArray(errorVal)) {\n var _errorVal = _slicedToArray(errorVal, 2);\n\n lowBound = _errorVal[0];\n highBound = _errorVal[1];\n } else {\n lowBound = highBound = errorVal;\n }\n\n if (layout === 'vertical') {\n scale = xAxis.scale;\n xMid = value;\n yMid = y + offset;\n xMin = scale(xMid - lowBound);\n yMin = yMid + width;\n xMax = scale(xMid + highBound);\n yMax = yMid - width;\n coordsTop = {\n x1: xMax,\n y1: yMin,\n x2: xMax,\n y2: yMax\n };\n coordsMid = {\n x1: xMin,\n y1: yMid,\n x2: xMax,\n y2: yMid\n };\n coordsBot = {\n x1: xMin,\n y1: yMin,\n x2: xMin,\n y2: yMax\n };\n } else if (layout === 'horizontal') {\n scale = yAxis.scale;\n xMid = x + offset;\n yMid = value;\n xMin = xMid - width;\n xMax = xMid + width;\n yMin = scale(yMid - lowBound);\n yMax = scale(yMid + highBound);\n coordsTop = {\n x1: xMin,\n y1: yMax,\n x2: xMax,\n y2: yMax\n };\n coordsMid = {\n x1: xMid,\n y1: yMin,\n x2: xMid,\n y2: yMax\n };\n coordsBot = {\n x1: xMin,\n y1: yMin,\n x2: xMax,\n y2: yMin\n };\n }\n\n return React.createElement(Layer, _extends({\n className: \"recharts-errorBar\",\n key: \"bar-\".concat(i)\n }, props), React.createElement(\"line\", coordsTop), React.createElement(\"line\", coordsMid), React.createElement(\"line\", coordsBot));\n });\n }\n }, {\n key: \"render\",\n value: function render() {\n return React.createElement(Layer, {\n className: \"recharts-errorBars\"\n }, this.renderErrorBars());\n }\n }]);\n\n return ErrorBar;\n}(Component);\n\nErrorBar.propTypes = {\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]).isRequired,\n data: PropTypes.array,\n xAxis: PropTypes.object,\n yAxis: PropTypes.object,\n layout: PropTypes.string,\n dataPointFormatter: PropTypes.func,\n stroke: PropTypes.string,\n strokeWidth: PropTypes.number,\n width: PropTypes.number,\n offset: PropTypes.number\n};\nErrorBar.defaultProps = {\n stroke: 'black',\n strokeWidth: 1.5,\n width: 5,\n offset: 0,\n layout: 'horizontal'\n};\nexport default ErrorBar;", + "import _isFunction from \"lodash/isFunction\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Reference Line\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport Layer from '../container/Layer';\nimport Label from '../component/Label';\nimport { LabeledScaleHelper, rectWithPoints } from '../util/CartesianUtils';\nimport { ifOverflowMatches } from '../util/ChartUtils';\nimport { isNumOrStr } from '../util/DataUtils';\nimport { warn } from '../util/LogUtils';\nimport { PRESENTATION_ATTRIBUTES } from '../util/ReactUtils';\nimport Rectangle from '../shape/Rectangle';\n\nvar ReferenceArea = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(ReferenceArea, _Component);\n\n function ReferenceArea() {\n _classCallCheck(this, ReferenceArea);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(ReferenceArea).apply(this, arguments));\n }\n\n _createClass(ReferenceArea, [{\n key: \"getRect\",\n value: function getRect(hasX1, hasX2, hasY1, hasY2) {\n var _this$props = this.props,\n xValue1 = _this$props.x1,\n xValue2 = _this$props.x2,\n yValue1 = _this$props.y1,\n yValue2 = _this$props.y2,\n xAxis = _this$props.xAxis,\n yAxis = _this$props.yAxis;\n var scale = LabeledScaleHelper.create({\n x: xAxis.scale,\n y: yAxis.scale\n });\n var p1 = {\n x: hasX1 ? scale.x.apply(xValue1) : scale.x.rangeMin,\n y: hasY1 ? scale.y.apply(yValue1) : scale.y.rangeMin\n };\n var p2 = {\n x: hasX2 ? scale.x.apply(xValue2) : scale.x.rangeMax,\n y: hasY2 ? scale.y.apply(yValue2) : scale.y.rangeMax\n };\n\n if (ifOverflowMatches(this.props, 'discard') && (!scale.isInRange(p1) || !scale.isInRange(p2))) {\n return null;\n }\n\n return rectWithPoints(p1, p2);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n x1 = _this$props2.x1,\n x2 = _this$props2.x2,\n y1 = _this$props2.y1,\n y2 = _this$props2.y2,\n className = _this$props2.className,\n alwaysShow = _this$props2.alwaysShow,\n clipPathId = _this$props2.clipPathId;\n warn(alwaysShow === undefined, 'The alwaysShow prop is deprecated. Please use ifOverflow=\"extendDomain\" instead.');\n var hasX1 = isNumOrStr(x1);\n var hasX2 = isNumOrStr(x2);\n var hasY1 = isNumOrStr(y1);\n var hasY2 = isNumOrStr(y2);\n\n if (!hasX1 && !hasX2 && !hasY1 && !hasY2) {\n return null;\n }\n\n var rect = this.getRect(hasX1, hasX2, hasY1, hasY2);\n\n if (!rect) {\n return null;\n }\n\n var shape = this.props.shape;\n var clipPath = ifOverflowMatches(this.props, 'hidden') ? \"url(#\".concat(clipPathId, \")\") : undefined;\n return React.createElement(Layer, {\n className: classNames('recharts-reference-area', className)\n }, this.constructor.renderRect(shape, _objectSpread({\n clipPath: clipPath\n }, this.props, rect)), Label.renderCallByParent(this.props, rect));\n }\n }], [{\n key: \"renderRect\",\n value: function renderRect(option, props) {\n var rect;\n\n if (React.isValidElement(option)) {\n rect = React.cloneElement(option, props);\n } else if (_isFunction(option)) {\n rect = option(props);\n } else {\n rect = React.createElement(Rectangle, _extends({}, props, {\n className: \"recharts-reference-area-rect\"\n }));\n }\n\n return rect;\n }\n }]);\n\n return ReferenceArea;\n}(Component), _class2.displayName = 'ReferenceArea', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n viewBox: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n }),\n xAxis: PropTypes.object,\n yAxis: PropTypes.object,\n isFront: PropTypes.bool,\n alwaysShow: PropTypes.bool,\n ifOverflow: PropTypes.oneOf(['hidden', 'visible', 'discard', 'extendDomain']),\n x1: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n x2: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n y1: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n y2: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n className: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n yAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n xAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n shape: PropTypes.oneOfType([PropTypes.func, PropTypes.element])\n}), _class2.defaultProps = {\n isFront: false,\n ifOverflow: 'discard',\n xAxisId: 0,\n yAxisId: 0,\n r: 10,\n fill: '#ccc',\n fillOpacity: 0.5,\n stroke: 'none',\n strokeWidth: 1\n}, _temp)) || _class;\n\nexport default ReferenceArea;", + "import _isFunction from \"lodash/isFunction\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Reference Dot\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport Layer from '../container/Layer';\nimport Dot from '../shape/Dot';\nimport { PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\nimport Label from '../component/Label';\nimport { isNumOrStr } from '../util/DataUtils';\nimport { ifOverflowMatches } from '../util/ChartUtils';\nimport { LabeledScaleHelper } from '../util/CartesianUtils';\nimport { warn } from '../util/LogUtils';\n\nvar ReferenceDot = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(ReferenceDot, _Component);\n\n function ReferenceDot() {\n _classCallCheck(this, ReferenceDot);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(ReferenceDot).apply(this, arguments));\n }\n\n _createClass(ReferenceDot, [{\n key: \"getCoordinate\",\n value: function getCoordinate() {\n var _this$props = this.props,\n x = _this$props.x,\n y = _this$props.y,\n xAxis = _this$props.xAxis,\n yAxis = _this$props.yAxis;\n var scales = LabeledScaleHelper.create({\n x: xAxis.scale,\n y: yAxis.scale\n });\n var result = scales.apply({\n x: x,\n y: y\n }, {\n bandAware: true\n });\n\n if (ifOverflowMatches(this.props, 'discard') && !scales.isInRange(result)) {\n return null;\n }\n\n return result;\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n x = _this$props2.x,\n y = _this$props2.y,\n r = _this$props2.r,\n alwaysShow = _this$props2.alwaysShow,\n clipPathId = _this$props2.clipPathId;\n var isX = isNumOrStr(x);\n var isY = isNumOrStr(y);\n warn(alwaysShow === undefined, 'The alwaysShow prop is deprecated. Please use ifOverflow=\"extendDomain\" instead.');\n\n if (!isX || !isY) {\n return null;\n }\n\n var coordinate = this.getCoordinate();\n\n if (!coordinate) {\n return null;\n }\n\n var cx = coordinate.x,\n cy = coordinate.y;\n var _this$props3 = this.props,\n shape = _this$props3.shape,\n className = _this$props3.className;\n var clipPath = ifOverflowMatches(this.props, 'hidden') ? \"url(#\".concat(clipPathId, \")\") : undefined;\n\n var dotProps = _objectSpread({\n clipPath: clipPath\n }, getPresentationAttributes(this.props), filterEventAttributes(this.props), {\n cx: cx,\n cy: cy\n });\n\n return React.createElement(Layer, {\n className: classNames('recharts-reference-dot', className)\n }, this.constructor.renderDot(shape, dotProps), Label.renderCallByParent(this.props, {\n x: cx - r,\n y: cy - r,\n width: 2 * r,\n height: 2 * r\n }));\n }\n }], [{\n key: \"renderDot\",\n value: function renderDot(option, props) {\n var dot;\n\n if (React.isValidElement(option)) {\n dot = React.cloneElement(option, props);\n } else if (_isFunction(option)) {\n dot = option(props);\n } else {\n dot = React.createElement(Dot, _extends({}, props, {\n cx: props.cx,\n cy: props.cy,\n className: \"recharts-reference-dot-dot\"\n }));\n }\n\n return dot;\n }\n }]);\n\n return ReferenceDot;\n}(Component), _class2.displayName = 'ReferenceDot', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, {\n r: PropTypes.number,\n xAxis: PropTypes.shape({\n scale: PropTypes.func\n }),\n yAxis: PropTypes.shape({\n scale: PropTypes.func\n }),\n isFront: PropTypes.bool,\n alwaysShow: PropTypes.bool,\n ifOverflow: PropTypes.oneOf(['hidden', 'visible', 'discard', 'extendDomain']),\n x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n y: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n className: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n yAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n xAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n shape: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),\n clipPathId: PropTypes.string\n}), _class2.defaultProps = {\n isFront: false,\n ifOverflow: 'discard',\n xAxisId: 0,\n yAxisId: 0,\n r: 10,\n fill: '#fff',\n stroke: '#ccc',\n fillOpacity: 1,\n strokeWidth: 1\n}, _temp)) || _class;\n\nexport default ReferenceDot;", + "import _some from \"lodash/some\";\nimport _isFunction from \"lodash/isFunction\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\n/**\n * @fileOverview Reference Line\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport Layer from '../container/Layer';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\nimport Label from '../component/Label';\nimport { ifOverflowMatches } from '../util/ChartUtils';\nimport { isNumOrStr } from '../util/DataUtils';\nimport { LabeledScaleHelper, rectWithCoords } from '../util/CartesianUtils';\nimport { warn } from '../util/LogUtils';\n\nvar renderLine = function renderLine(option, props) {\n var line;\n\n if (React.isValidElement(option)) {\n line = React.cloneElement(option, props);\n } else if (_isFunction(option)) {\n line = option(props);\n } else {\n line = React.createElement(\"line\", _extends({}, props, {\n className: \"recharts-reference-line-line\"\n }));\n }\n\n return line;\n};\n\nvar ReferenceLine = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(ReferenceLine, _Component);\n\n function ReferenceLine() {\n _classCallCheck(this, ReferenceLine);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(ReferenceLine).apply(this, arguments));\n }\n\n _createClass(ReferenceLine, [{\n key: \"getEndPoints\",\n value: function getEndPoints(scales, isFixedX, isFixedY, isSegment) {\n var _this$props$viewBox = this.props.viewBox,\n x = _this$props$viewBox.x,\n y = _this$props$viewBox.y,\n width = _this$props$viewBox.width,\n height = _this$props$viewBox.height;\n\n if (isFixedY) {\n var _this$props = this.props,\n yCoord = _this$props.y,\n orientation = _this$props.yAxis.orientation;\n var coord = scales.y.apply(yCoord, {\n bandAware: true\n });\n\n if (ifOverflowMatches(this.props, 'discard') && !scales.y.isInRange(coord)) {\n return null;\n }\n\n var points = [{\n x: x + width,\n y: coord\n }, {\n x: x,\n y: coord\n }];\n return orientation === 'left' ? points.reverse() : points;\n }\n\n if (isFixedX) {\n var _this$props2 = this.props,\n xCoord = _this$props2.x,\n _orientation = _this$props2.xAxis.orientation;\n\n var _coord = scales.x.apply(xCoord, {\n bandAware: true\n });\n\n if (ifOverflowMatches(this.props, 'discard') && !scales.x.isInRange(_coord)) {\n return null;\n }\n\n var _points = [{\n x: _coord,\n y: y + height\n }, {\n x: _coord,\n y: y\n }];\n return _orientation === 'top' ? _points.reverse() : _points;\n }\n\n if (isSegment) {\n var segment = this.props.segment;\n\n var _points2 = segment.map(function (p) {\n return scales.apply(p, {\n bandAware: true\n });\n });\n\n if (ifOverflowMatches(this.props, 'discard') && _some(_points2, function (p) {\n return !scales.isInRange(p);\n })) {\n return null;\n }\n\n return _points2;\n }\n\n return null;\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props3 = this.props,\n fixedX = _this$props3.x,\n fixedY = _this$props3.y,\n segment = _this$props3.segment,\n xAxis = _this$props3.xAxis,\n yAxis = _this$props3.yAxis,\n shape = _this$props3.shape,\n className = _this$props3.className,\n alwaysShow = _this$props3.alwaysShow,\n clipPathId = _this$props3.clipPathId;\n warn(alwaysShow === undefined, 'The alwaysShow prop is deprecated. Please use ifOverflow=\"extendDomain\" instead.');\n var scales = LabeledScaleHelper.create({\n x: xAxis.scale,\n y: yAxis.scale\n });\n var isX = isNumOrStr(fixedX);\n var isY = isNumOrStr(fixedY);\n var isSegment = segment && segment.length === 2;\n var endPoints = this.getEndPoints(scales, isX, isY, isSegment);\n\n if (!endPoints) {\n return null;\n }\n\n var _endPoints = _slicedToArray(endPoints, 2),\n _endPoints$ = _endPoints[0],\n x1 = _endPoints$.x,\n y1 = _endPoints$.y,\n _endPoints$2 = _endPoints[1],\n x2 = _endPoints$2.x,\n y2 = _endPoints$2.y;\n\n var clipPath = ifOverflowMatches(this.props, 'hidden') ? \"url(#\".concat(clipPathId, \")\") : undefined;\n\n var props = _objectSpread({\n clipPath: clipPath\n }, getPresentationAttributes(this.props), filterEventAttributes(this.props), {\n x1: x1,\n y1: y1,\n x2: x2,\n y2: y2\n });\n\n return React.createElement(Layer, {\n className: classNames('recharts-reference-line', className)\n }, renderLine(shape, props), Label.renderCallByParent(this.props, rectWithCoords({\n x1: x1,\n y1: y1,\n x2: x2,\n y2: y2\n })));\n }\n }]);\n\n return ReferenceLine;\n}(Component), _class2.displayName = 'ReferenceLine', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n viewBox: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n }),\n xAxis: PropTypes.object,\n yAxis: PropTypes.object,\n isFront: PropTypes.bool,\n alwaysShow: PropTypes.bool,\n ifOverflow: PropTypes.oneOf(['hidden', 'visible', 'discard', 'extendDomain']),\n x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n y: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n segment: PropTypes.arrayOf(PropTypes.shape({\n x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n y: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n })),\n className: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n yAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n xAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n shape: PropTypes.func\n}), _class2.defaultProps = {\n isFront: false,\n ifOverflow: 'discard',\n xAxisId: 0,\n yAxisId: 0,\n fill: 'none',\n stroke: '#ccc',\n fillOpacity: 1,\n strokeWidth: 1\n}, _temp)) || _class;\n\nexport default ReferenceLine;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview X Axis\n */\nimport { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport pureRender from '../util/PureRender';\nimport { SCALE_TYPES } from '../util/ReactUtils';\n\nvar XAxis = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(XAxis, _Component);\n\n function XAxis() {\n _classCallCheck(this, XAxis);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(XAxis).apply(this, arguments));\n }\n\n _createClass(XAxis, [{\n key: \"render\",\n value: function render() {\n return null;\n }\n }]);\n\n return XAxis;\n}(Component), _class2.displayName = 'XAxis', _class2.propTypes = {\n allowDecimals: PropTypes.bool,\n allowDuplicatedCategory: PropTypes.bool,\n hide: PropTypes.bool,\n // The name of data displayed in the axis\n name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n // The unit of data displayed in the axis\n unit: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n // The unique id of x-axis\n xAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n domain: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func, PropTypes.oneOf(['auto', 'dataMin', 'dataMax'])])),\n // The key of data displayed in the axis\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]),\n // The width of axis which is usually calculated internally\n width: PropTypes.number,\n // The height of axis, which need to be setted by user\n height: PropTypes.number,\n mirror: PropTypes.bool,\n // The orientation of axis\n orientation: PropTypes.oneOf(['top', 'bottom']),\n type: PropTypes.oneOf(['number', 'category']),\n // Ticks can be any type when the axis is the type of category\n // Ticks must be numbers when the axis is the type of number\n ticks: PropTypes.array,\n // The count of ticks\n tickCount: PropTypes.number,\n // The formatter function of tick\n tickFormatter: PropTypes.func,\n padding: PropTypes.shape({\n left: PropTypes.number,\n right: PropTypes.number\n }),\n allowDataOverflow: PropTypes.bool,\n scale: PropTypes.oneOfType([PropTypes.oneOf(SCALE_TYPES), PropTypes.func]),\n tick: PropTypes.oneOfType([PropTypes.bool, PropTypes.func, PropTypes.object, PropTypes.element]),\n axisLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n tickLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n minTickGap: PropTypes.number,\n tickSize: PropTypes.number,\n interval: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(['preserveStart', 'preserveEnd', 'preserveStartEnd'])]),\n reversed: PropTypes.bool\n}, _class2.defaultProps = {\n allowDecimals: true,\n hide: false,\n orientation: 'bottom',\n width: 0,\n height: 30,\n mirror: false,\n xAxisId: 0,\n tickCount: 5,\n type: 'category',\n domain: [0, 'auto'],\n padding: {\n left: 0,\n right: 0\n },\n allowDataOverflow: false,\n scale: 'auto',\n reversed: false,\n allowDuplicatedCategory: true\n}, _temp)) || _class;\n\nexport default XAxis;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Y Axis\n */\nimport { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport pureRender from '../util/PureRender';\n\nvar YAxis = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(YAxis, _Component);\n\n function YAxis() {\n _classCallCheck(this, YAxis);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(YAxis).apply(this, arguments));\n }\n\n _createClass(YAxis, [{\n key: \"render\",\n value: function render() {\n return null;\n }\n }]);\n\n return YAxis;\n}(Component), _class2.displayName = 'YAxis', _class2.propTypes = {\n allowDecimals: PropTypes.bool,\n allowDuplicatedCategory: PropTypes.bool,\n hide: PropTypes.bool,\n // The name of data displayed in the axis\n name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n // The unit of data displayed in the axis\n unit: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n // The unique id of y-axis\n yAxisId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n domain: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func, PropTypes.oneOf(['auto', 'dataMin', 'dataMax'])])),\n // The key of data displayed in the axis\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]),\n // Ticks can be any type when the axis is the type of category\n // Ticks must be numbers when the axis is the type of number\n ticks: PropTypes.array,\n // The count of ticks\n tickCount: PropTypes.number,\n // The formatter function of tick\n tickFormatter: PropTypes.func,\n // The width of axis, which need to be setted by user\n width: PropTypes.number,\n // The height of axis which is usually calculated in Chart\n height: PropTypes.number,\n mirror: PropTypes.bool,\n // The orientation of axis\n orientation: PropTypes.oneOf(['left', 'right']),\n type: PropTypes.oneOf(['number', 'category']),\n padding: PropTypes.shape({\n top: PropTypes.number,\n bottom: PropTypes.number\n }),\n allowDataOverflow: PropTypes.bool,\n scale: PropTypes.oneOfType([PropTypes.oneOf(['auto', 'linear', 'pow', 'sqrt', 'log', 'identity', 'time', 'band', 'point', 'ordinal', 'quantile', 'quantize', 'utc', 'sequential', 'threshold']), PropTypes.func]),\n tick: PropTypes.oneOfType([PropTypes.bool, PropTypes.func, PropTypes.object, PropTypes.element]),\n axisLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n tickLine: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),\n minTickGap: PropTypes.number,\n tickSize: PropTypes.number,\n interval: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(['preserveStart', 'preserveEnd', 'preserveStartEnd'])]),\n reversed: PropTypes.bool\n}, _class2.defaultProps = {\n allowDuplicatedCategory: true,\n allowDecimals: true,\n hide: false,\n orientation: 'left',\n width: 60,\n height: 0,\n mirror: false,\n yAxisId: 0,\n tickCount: 5,\n type: 'number',\n domain: [0, 'auto'],\n padding: {\n top: 0,\n bottom: 0\n },\n allowDataOverflow: false,\n scale: 'auto',\n reversed: false\n}, _temp)) || _class;\n\nexport default YAxis;", + "import EventEmitter from 'events';\nvar eventCenter = new EventEmitter();\n\nif (eventCenter.setMaxListeners) {\n eventCenter.setMaxListeners(10);\n}\n\nexport { eventCenter };\nexport var SYNC_EVENT = 'recharts.syncMouseEvents';", + "import _every from \"lodash/every\";\nimport _find from \"lodash/find\";\nimport _sortBy from \"lodash/sortBy\";\nimport _isFunction from \"lodash/isFunction\";\nimport _range from \"lodash/range\";\nimport _throttle from \"lodash/throttle\";\nimport _isNil from \"lodash/isNil\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nimport React, { Component, cloneElement, isValidElement, createElement } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Surface from '../container/Surface';\nimport Layer from '../container/Layer';\nimport Tooltip from '../component/Tooltip';\nimport Legend from '../component/Legend';\nimport Curve from '../shape/Curve';\nimport Cross from '../shape/Cross';\nimport Sector from '../shape/Sector';\nimport Dot from '../shape/Dot';\nimport Rectangle from '../shape/Rectangle';\nimport { findAllByType, findChildByType, getDisplayName, parseChildIndex, getPresentationAttributes, validateWidthHeight, isChildrenEqual, renderByOrder, getReactEventByType, filterEventAttributes } from '../util/ReactUtils';\nimport CartesianAxis from '../cartesian/CartesianAxis';\nimport Brush from '../cartesian/Brush';\nimport { getOffset, calculateChartCoordinate } from '../util/DOMUtils';\nimport { getAnyElementOfObject, hasDuplicate, uniqueId, isNumber, findEntryInArray } from '../util/DataUtils';\nimport { calculateActiveTickIndex, getMainColorOfGraphicItem, getBarSizeList, getBarPosition, appendOffsetOfLegend, getLegendProps, combineEventHandlers, getTicksOfAxis, getCoordinatesOfGrid, getStackedDataOfItem, parseErrorBarsOfAxis, getBandSizeOfAxis, getStackGroupsByAxisId, getValueByDataKey, isCategorialAxis, getDomainOfItemsWithSameAxis, getDomainOfStackGroups, getDomainOfDataByKey, detectReferenceElementsDomain, parseSpecifiedDomain, parseDomainOfCategoryAxis } from '../util/ChartUtils';\nimport { inRangeOfSector, polarToCartesian } from '../util/PolarUtils';\nimport { shallowEqual } from '../util/PureRender';\nimport { eventCenter, SYNC_EVENT } from '../util/Events';\nvar ORIENT_MAP = {\n xAxis: ['bottom', 'top'],\n yAxis: ['left', 'right']\n};\nvar originCoordinate = {\n x: 0,\n y: 0\n};\n\nvar generateCategoricalChart = function generateCategoricalChart(_ref) {\n var chartName = _ref.chartName,\n GraphicalChild = _ref.GraphicalChild,\n _ref$eventType = _ref.eventType,\n eventType = _ref$eventType === void 0 ? 'axis' : _ref$eventType,\n axisComponents = _ref.axisComponents,\n legendContent = _ref.legendContent,\n formatAxisMap = _ref.formatAxisMap,\n defaultProps = _ref.defaultProps,\n propTypes = _ref.propTypes;\n\n var CategoricalChartWrapper =\n /*#__PURE__*/\n function (_Component) {\n _inherits(CategoricalChartWrapper, _Component);\n\n /**\n * Returns default, reset state for the categorical chart.\n * @param {Object} props Props object to use when creating the default state\n * @return {Object} Whole new state\n */\n function CategoricalChartWrapper(_props) {\n var _this;\n\n _classCallCheck(this, CategoricalChartWrapper);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(CategoricalChartWrapper).call(this, _props));\n\n _this.handleLegendBBoxUpdate = function (box) {\n if (box && _this.legendInstance) {\n var _this$state = _this.state,\n dataStartIndex = _this$state.dataStartIndex,\n dataEndIndex = _this$state.dataEndIndex,\n updateId = _this$state.updateId;\n\n _this.setState(_this.updateStateOfAxisMapsOffsetAndStackGroups({\n props: _this.props,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex,\n updateId: updateId\n }));\n }\n };\n\n _this.handleReceiveSyncEvent = function (cId, chartId, data) {\n var _this$props = _this.props,\n syncId = _this$props.syncId,\n layout = _this$props.layout;\n var updateId = _this.state.updateId;\n\n if (syncId === cId && chartId !== _this.uniqueChartId) {\n var dataStartIndex = data.dataStartIndex,\n dataEndIndex = data.dataEndIndex;\n\n if (!_isNil(data.dataStartIndex) || !_isNil(data.dataEndIndex)) {\n _this.setState(_objectSpread({\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n }, _this.updateStateOfAxisMapsOffsetAndStackGroups({\n props: _this.props,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex,\n updateId: updateId\n })));\n } else if (!_isNil(data.activeTooltipIndex)) {\n var chartX = data.chartX,\n chartY = data.chartY,\n activeTooltipIndex = data.activeTooltipIndex;\n var _this$state2 = _this.state,\n offset = _this$state2.offset,\n tooltipTicks = _this$state2.tooltipTicks;\n\n if (!offset) {\n return;\n }\n\n var viewBox = _objectSpread({}, offset, {\n x: offset.left,\n y: offset.top\n }); // When a categotical chart is combined with another chart, the value of chartX\n // and chartY may beyond the boundaries.\n\n\n var validateChartX = Math.min(chartX, viewBox.x + viewBox.width);\n var validateChartY = Math.min(chartY, viewBox.y + viewBox.height);\n var activeLabel = tooltipTicks[activeTooltipIndex] && tooltipTicks[activeTooltipIndex].value;\n\n var activePayload = _this.getTooltipContent(activeTooltipIndex);\n\n var activeCoordinate = tooltipTicks[activeTooltipIndex] ? {\n x: layout === 'horizontal' ? tooltipTicks[activeTooltipIndex].coordinate : validateChartX,\n y: layout === 'horizontal' ? validateChartY : tooltipTicks[activeTooltipIndex].coordinate\n } : originCoordinate;\n\n _this.setState(_objectSpread({}, data, {\n activeLabel: activeLabel,\n activeCoordinate: activeCoordinate,\n activePayload: activePayload\n }));\n } else {\n _this.setState(data);\n }\n }\n };\n\n _this.handleBrushChange = function (_ref2) {\n var startIndex = _ref2.startIndex,\n endIndex = _ref2.endIndex;\n\n // Only trigger changes if the extents of the brush have actually changed\n if (startIndex !== _this.state.dataStartIndex || endIndex !== _this.state.dataEndIndex) {\n var updateId = _this.state.updateId;\n\n _this.setState(function () {\n return _objectSpread({\n dataStartIndex: startIndex,\n dataEndIndex: endIndex\n }, _this.updateStateOfAxisMapsOffsetAndStackGroups({\n props: _this.props,\n dataStartIndex: startIndex,\n dataEndIndex: endIndex,\n updateId: updateId\n }));\n });\n\n _this.triggerSyncEvent({\n dataStartIndex: startIndex,\n dataEndIndex: endIndex\n });\n }\n };\n\n _this.handleMouseEnter = function (e) {\n var onMouseEnter = _this.props.onMouseEnter;\n\n var mouse = _this.getMouseInfo(e);\n\n if (mouse) {\n var nextState = _objectSpread({}, mouse, {\n isTooltipActive: true\n });\n\n _this.setState(nextState);\n\n _this.triggerSyncEvent(nextState);\n\n if (_isFunction(onMouseEnter)) {\n onMouseEnter(nextState, e);\n }\n }\n };\n\n _this.triggeredAfterMouseMove = function (e) {\n var onMouseMove = _this.props.onMouseMove;\n\n var mouse = _this.getMouseInfo(e);\n\n var nextState = mouse ? _objectSpread({}, mouse, {\n isTooltipActive: true\n }) : {\n isTooltipActive: false\n };\n\n _this.setState(nextState);\n\n _this.triggerSyncEvent(nextState);\n\n if (_isFunction(onMouseMove)) {\n onMouseMove(nextState, e);\n }\n };\n\n _this.handleItemMouseEnter = function (el) {\n _this.setState(function () {\n return {\n isTooltipActive: true,\n activeItem: el,\n activePayload: el.tooltipPayload,\n activeCoordinate: el.tooltipPosition || {\n x: el.cx,\n y: el.cy\n }\n };\n });\n };\n\n _this.handleItemMouseLeave = function () {\n _this.setState(function () {\n return {\n isTooltipActive: false\n };\n });\n };\n\n _this.handleMouseMove = function (e) {\n if (e && _isFunction(e.persist)) {\n e.persist();\n }\n\n _this.triggeredAfterMouseMove(e);\n };\n\n _this.handleMouseLeave = function (e) {\n var onMouseLeave = _this.props.onMouseLeave;\n var nextState = {\n isTooltipActive: false\n };\n\n _this.setState(nextState);\n\n _this.triggerSyncEvent(nextState);\n\n if (_isFunction(onMouseLeave)) {\n onMouseLeave(nextState, e);\n }\n };\n\n _this.handleOuterEvent = function (e) {\n var eventName = getReactEventByType(e);\n\n if (eventName && _isFunction(_this.props[eventName])) {\n var mouse = _this.getMouseInfo(e);\n\n var handler = _this.props[eventName];\n handler(mouse, e);\n }\n };\n\n _this.handleClick = function (e) {\n var onClick = _this.props.onClick;\n\n if (_isFunction(onClick)) {\n var mouse = _this.getMouseInfo(e);\n\n onClick(mouse, e);\n }\n };\n\n _this.handleMouseDown = function (e) {\n var onMouseDown = _this.props.onMouseDown;\n\n if (_isFunction(onMouseDown)) {\n var mouse = _this.getMouseInfo(e);\n\n onMouseDown(mouse, e);\n }\n };\n\n _this.handleMouseUp = function (e) {\n var onMouseUp = _this.props.onMouseUp;\n\n if (_isFunction(onMouseUp)) {\n var mouse = _this.getMouseInfo(e);\n\n onMouseUp(mouse, e);\n }\n };\n\n _this.handleTouchMove = function (e) {\n if (e.changedTouches != null && e.changedTouches.length > 0) {\n _this.handleMouseMove(e.changedTouches[0]);\n }\n };\n\n _this.handleTouchStart = function (e) {\n if (e.changedTouches != null && e.changedTouches.length > 0) {\n _this.handleMouseDown(e.changedTouches[0]);\n }\n };\n\n _this.handleTouchEnd = function (e) {\n if (e.changedTouches != null && e.changedTouches.length > 0) {\n _this.handleMouseUp(e.changedTouches[0]);\n }\n };\n\n _this.verticalCoordinatesGenerator = function (_ref3) {\n var xAxis = _ref3.xAxis,\n width = _ref3.width,\n height = _ref3.height,\n offset = _ref3.offset;\n return getCoordinatesOfGrid(CartesianAxis.getTicks(_objectSpread({}, CartesianAxis.defaultProps, xAxis, {\n ticks: getTicksOfAxis(xAxis, true),\n viewBox: {\n x: 0,\n y: 0,\n width: width,\n height: height\n }\n })), offset.left, offset.left + offset.width);\n };\n\n _this.horizontalCoordinatesGenerator = function (_ref4) {\n var yAxis = _ref4.yAxis,\n width = _ref4.width,\n height = _ref4.height,\n offset = _ref4.offset;\n return getCoordinatesOfGrid(CartesianAxis.getTicks(_objectSpread({}, CartesianAxis.defaultProps, yAxis, {\n ticks: getTicksOfAxis(yAxis, true),\n viewBox: {\n x: 0,\n y: 0,\n width: width,\n height: height\n }\n })), offset.top, offset.top + offset.height);\n };\n\n _this.axesTicksGenerator = function (axis) {\n return getTicksOfAxis(axis, true);\n };\n\n _this.tooltipTicksGenerator = function (axisMap) {\n var axis = getAnyElementOfObject(axisMap);\n var tooltipTicks = getTicksOfAxis(axis, false, true);\n return {\n tooltipTicks: tooltipTicks,\n orderedTooltipTicks: _sortBy(tooltipTicks, function (o) {\n return o.coordinate;\n }),\n tooltipAxis: axis,\n tooltipAxisBandSize: getBandSizeOfAxis(axis)\n };\n };\n\n _this.renderCursor = function (element) {\n var _this$state3 = _this.state,\n isTooltipActive = _this$state3.isTooltipActive,\n activeCoordinate = _this$state3.activeCoordinate,\n activePayload = _this$state3.activePayload,\n offset = _this$state3.offset;\n\n if (!element || !element.props.cursor || !isTooltipActive || !activeCoordinate) {\n return null;\n }\n\n var layout = _this.props.layout;\n var restProps;\n var cursorComp = Curve;\n\n if (chartName === 'ScatterChart') {\n restProps = activeCoordinate;\n cursorComp = Cross;\n } else if (chartName === 'BarChart') {\n restProps = _this.getCursorRectangle();\n cursorComp = Rectangle;\n } else if (layout === 'radial') {\n var _this$getCursorPoints = _this.getCursorPoints(),\n cx = _this$getCursorPoints.cx,\n cy = _this$getCursorPoints.cy,\n radius = _this$getCursorPoints.radius,\n startAngle = _this$getCursorPoints.startAngle,\n endAngle = _this$getCursorPoints.endAngle;\n\n restProps = {\n cx: cx,\n cy: cy,\n startAngle: startAngle,\n endAngle: endAngle,\n innerRadius: radius,\n outerRadius: radius\n };\n cursorComp = Sector;\n } else {\n restProps = {\n points: _this.getCursorPoints()\n };\n cursorComp = Curve;\n }\n\n var key = element.key || '_recharts-cursor';\n\n var cursorProps = _objectSpread({\n stroke: '#ccc',\n pointerEvents: 'none'\n }, offset, restProps, getPresentationAttributes(element.props.cursor), {\n payload: activePayload,\n key: key,\n className: 'recharts-tooltip-cursor'\n });\n\n return isValidElement(element.props.cursor) ? cloneElement(element.props.cursor, cursorProps) : createElement(cursorComp, cursorProps);\n };\n\n _this.renderPolarAxis = function (element, displayName, index) {\n var axisType = element.type.axisType;\n\n var axisMap = _this.state[\"\".concat(axisType, \"Map\")];\n\n var axisOption = axisMap[element.props[\"\".concat(axisType, \"Id\")]];\n return cloneElement(element, _objectSpread({}, axisOption, {\n className: axisType,\n key: element.key || \"\".concat(displayName, \"-\").concat(index),\n ticks: getTicksOfAxis(axisOption, true)\n }));\n };\n\n _this.renderXAxis = function (element, displayName, index) {\n var xAxisMap = _this.state.xAxisMap;\n var axisObj = xAxisMap[element.props.xAxisId];\n return _this.renderAxis(axisObj, element, displayName, index);\n };\n\n _this.renderYAxis = function (element, displayName, index) {\n var yAxisMap = _this.state.yAxisMap;\n var axisObj = yAxisMap[element.props.yAxisId];\n return _this.renderAxis(axisObj, element, displayName, index);\n };\n\n _this.renderGrid = function (element) {\n var _this$state4 = _this.state,\n xAxisMap = _this$state4.xAxisMap,\n yAxisMap = _this$state4.yAxisMap,\n offset = _this$state4.offset;\n var _this$props2 = _this.props,\n width = _this$props2.width,\n height = _this$props2.height;\n var xAxis = getAnyElementOfObject(xAxisMap);\n\n var yAxisWithFiniteDomain = _find(yAxisMap, function (axis) {\n return _every(axis.domain, Number.isFinite);\n });\n\n var yAxis = yAxisWithFiniteDomain || getAnyElementOfObject(yAxisMap);\n var props = element.props || {};\n return cloneElement(element, {\n key: element.key || 'grid',\n x: isNumber(props.x) ? props.x : offset.left,\n y: isNumber(props.y) ? props.y : offset.top,\n width: isNumber(props.width) ? props.width : offset.width,\n height: isNumber(props.height) ? props.height : offset.height,\n xAxis: xAxis,\n yAxis: yAxis,\n offset: offset,\n chartWidth: width,\n chartHeight: height,\n verticalCoordinatesGenerator: props.verticalCoordinatesGenerator || _this.verticalCoordinatesGenerator,\n horizontalCoordinatesGenerator: props.horizontalCoordinatesGenerator || _this.horizontalCoordinatesGenerator\n });\n };\n\n _this.renderPolarGrid = function (element) {\n var _this$state5 = _this.state,\n radiusAxisMap = _this$state5.radiusAxisMap,\n angleAxisMap = _this$state5.angleAxisMap;\n var radiusAxis = getAnyElementOfObject(radiusAxisMap);\n var angleAxis = getAnyElementOfObject(angleAxisMap);\n var cx = angleAxis.cx,\n cy = angleAxis.cy,\n innerRadius = angleAxis.innerRadius,\n outerRadius = angleAxis.outerRadius;\n return cloneElement(element, {\n polarAngles: getTicksOfAxis(angleAxis, true).map(function (entry) {\n return entry.coordinate;\n }),\n polarRadius: getTicksOfAxis(radiusAxis, true).map(function (entry) {\n return entry.coordinate;\n }),\n cx: cx,\n cy: cy,\n innerRadius: innerRadius,\n outerRadius: outerRadius,\n key: element.key || 'polar-grid'\n });\n };\n\n _this.renderBrush = function (element) {\n var _this$props3 = _this.props,\n margin = _this$props3.margin,\n data = _this$props3.data;\n var _this$state6 = _this.state,\n offset = _this$state6.offset,\n dataStartIndex = _this$state6.dataStartIndex,\n dataEndIndex = _this$state6.dataEndIndex,\n updateId = _this$state6.updateId; // TODO: update brush when children update\n\n return cloneElement(element, {\n key: element.key || '_recharts-brush',\n onChange: combineEventHandlers(_this.handleBrushChange, null, element.props.onChange),\n data: data,\n x: isNumber(element.props.x) ? element.props.x : offset.left,\n y: isNumber(element.props.y) ? element.props.y : offset.top + offset.height + offset.brushBottom - (margin.bottom || 0),\n width: isNumber(element.props.width) ? element.props.width : offset.width,\n startIndex: dataStartIndex,\n endIndex: dataEndIndex,\n updateId: \"brush-\".concat(updateId)\n });\n };\n\n _this.renderReferenceElement = function (element, displayName, index) {\n if (!element) {\n return null;\n }\n\n var _assertThisInitialize = _assertThisInitialized(_assertThisInitialized(_this)),\n clipPathId = _assertThisInitialize.clipPathId;\n\n var _this$state7 = _this.state,\n xAxisMap = _this$state7.xAxisMap,\n yAxisMap = _this$state7.yAxisMap,\n offset = _this$state7.offset;\n var _element$props = element.props,\n xAxisId = _element$props.xAxisId,\n yAxisId = _element$props.yAxisId;\n return cloneElement(element, {\n key: element.key || \"\".concat(displayName, \"-\").concat(index),\n xAxis: xAxisMap[xAxisId],\n yAxis: yAxisMap[yAxisId],\n viewBox: {\n x: offset.left,\n y: offset.top,\n width: offset.width,\n height: offset.height\n },\n clipPathId: clipPathId\n });\n };\n\n _this.renderGraphicChild = function (element, displayName, index) {\n var item = _this.filterFormatItem(element, displayName, index);\n\n if (!item) {\n return null;\n }\n\n var graphicalItem = cloneElement(element, item.props);\n var _this$state8 = _this.state,\n isTooltipActive = _this$state8.isTooltipActive,\n tooltipAxis = _this$state8.tooltipAxis,\n activeTooltipIndex = _this$state8.activeTooltipIndex,\n activeLabel = _this$state8.activeLabel;\n var children = _this.props.children;\n var tooltipItem = findChildByType(children, Tooltip);\n var _item$props = item.props,\n points = _item$props.points,\n isRange = _item$props.isRange,\n baseLine = _item$props.baseLine;\n var _item$item$props = item.item.props,\n activeDot = _item$item$props.activeDot,\n hide = _item$item$props.hide;\n var hasActive = !hide && isTooltipActive && tooltipItem && activeDot && activeTooltipIndex >= 0;\n\n if (hasActive) {\n var activePoint, basePoint;\n\n if (tooltipAxis.dataKey && !tooltipAxis.allowDuplicatedCategory) {\n activePoint = findEntryInArray(points, \"payload.\".concat(tooltipAxis.dataKey), activeLabel);\n basePoint = isRange && baseLine && findEntryInArray(baseLine, \"payload.\".concat(tooltipAxis.dataKey), activeLabel);\n } else {\n activePoint = points[activeTooltipIndex];\n basePoint = isRange && baseLine && baseLine[activeTooltipIndex];\n }\n\n if (!_isNil(activePoint)) {\n return [graphicalItem].concat(_toConsumableArray(_this.renderActivePoints({\n item: item,\n activePoint: activePoint,\n basePoint: basePoint,\n childIndex: activeTooltipIndex,\n isRange: isRange\n })));\n }\n }\n\n if (isRange) {\n return [graphicalItem, null, null];\n }\n\n return [graphicalItem, null];\n };\n\n var defaultState = _this.constructor.createDefaultState(_props);\n\n var _updateId = 0;\n _this.state = _objectSpread({}, defaultState, {\n updateId: 0\n }, _this.updateStateOfAxisMapsOffsetAndStackGroups(_objectSpread({\n props: _props\n }, defaultState, {\n updateId: _updateId\n })));\n _this.uniqueChartId = _isNil(_props.id) ? uniqueId('recharts') : _props.id;\n _this.clipPathId = \"\".concat(_this.uniqueChartId, \"-clip\");\n\n if (_props.throttleDelay) {\n _this.triggeredAfterMouseMove = _throttle(_this.triggeredAfterMouseMove, _props.throttleDelay);\n }\n\n return _this;\n }\n /* eslint-disable react/no-did-mount-set-state */\n\n\n _createClass(CategoricalChartWrapper, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n if (!_isNil(this.props.syncId)) {\n this.addListener();\n }\n }\n }, {\n key: \"componentWillReceiveProps\",\n value: function componentWillReceiveProps(nextProps) {\n var _this2 = this;\n\n var _this$props4 = this.props,\n data = _this$props4.data,\n children = _this$props4.children,\n width = _this$props4.width,\n height = _this$props4.height,\n layout = _this$props4.layout,\n stackOffset = _this$props4.stackOffset,\n margin = _this$props4.margin;\n var updateId = this.state.updateId;\n\n if (nextProps.data !== data || nextProps.width !== width || nextProps.height !== height || nextProps.layout !== layout || nextProps.stackOffset !== stackOffset || !shallowEqual(nextProps.margin, margin)) {\n var defaultState = this.constructor.createDefaultState(nextProps);\n this.setState(_objectSpread({}, defaultState, {\n updateId: updateId + 1\n }, this.updateStateOfAxisMapsOffsetAndStackGroups(_objectSpread({\n props: nextProps\n }, defaultState, {\n updateId: updateId + 1\n }))));\n } else if (!isChildrenEqual(nextProps.children, children)) {\n // update configuration in chilren\n var hasGlobalData = !_isNil(nextProps.data);\n var newUpdateId = hasGlobalData ? updateId : updateId + 1;\n this.setState(function (prevState) {\n return _objectSpread({\n updateId: newUpdateId\n }, _this2.updateStateOfAxisMapsOffsetAndStackGroups(_objectSpread({\n props: nextProps\n }, prevState, {\n updateId: newUpdateId\n })));\n });\n } // add syncId\n\n\n if (_isNil(this.props.syncId) && !_isNil(nextProps.syncId)) {\n this.addListener();\n } // remove syncId\n\n\n if (!_isNil(this.props.syncId) && _isNil(nextProps.syncId)) {\n this.removeListener();\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n if (!_isNil(this.props.syncId)) {\n this.removeListener();\n }\n\n if (typeof this.triggeredAfterMouseMove.cancel === 'function') {\n this.triggeredAfterMouseMove.cancel();\n }\n }\n /**\n * Get the configuration of all x-axis or y-axis\n * @param {Object} props Latest props\n * @param {String} axisType The type of axis\n * @param {Array} graphicalItems The instances of item\n * @param {Object} stackGroups The items grouped by axisId and stackId\n * @param {Number} dataStartIndex The start index of the data series when a brush is applied\n * @param {Number} dataEndIndex The end index of the data series when a brush is applied\n * @return {Object} Configuration\n */\n\n }, {\n key: \"getAxisMap\",\n value: function getAxisMap(props, _ref5) {\n var _ref5$axisType = _ref5.axisType,\n axisType = _ref5$axisType === void 0 ? 'xAxis' : _ref5$axisType,\n AxisComp = _ref5.AxisComp,\n graphicalItems = _ref5.graphicalItems,\n stackGroups = _ref5.stackGroups,\n dataStartIndex = _ref5.dataStartIndex,\n dataEndIndex = _ref5.dataEndIndex;\n var children = props.children;\n var axisIdKey = \"\".concat(axisType, \"Id\"); // Get all the instance of Axis\n\n var axes = findAllByType(children, AxisComp);\n var axisMap = {};\n\n if (axes && axes.length) {\n axisMap = this.getAxisMapByAxes(props, {\n axes: axes,\n graphicalItems: graphicalItems,\n axisType: axisType,\n axisIdKey: axisIdKey,\n stackGroups: stackGroups,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n });\n } else if (graphicalItems && graphicalItems.length) {\n axisMap = this.getAxisMapByItems(props, {\n Axis: AxisComp,\n graphicalItems: graphicalItems,\n axisType: axisType,\n axisIdKey: axisIdKey,\n stackGroups: stackGroups,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n });\n }\n\n return axisMap;\n }\n /**\n * Get the configuration of axis by the options of axis instance\n * @param {Object} props Latest props\n * @param {Array} axes The instance of axes\n * @param {Array} graphicalItems The instances of item\n * @param {String} axisType The type of axis, xAxis - x-axis, yAxis - y-axis\n * @param {String} axisIdKey The unique id of an axis\n * @param {Object} stackGroups The items grouped by axisId and stackId\n * @param {Number} dataStartIndex The start index of the data series when a brush is applied\n * @param {Number} dataEndIndex The end index of the data series when a brush is applied\n * @return {Object} Configuration\n */\n\n }, {\n key: \"getAxisMapByAxes\",\n value: function getAxisMapByAxes(props, _ref6) {\n var _this3 = this;\n\n var axes = _ref6.axes,\n graphicalItems = _ref6.graphicalItems,\n axisType = _ref6.axisType,\n axisIdKey = _ref6.axisIdKey,\n stackGroups = _ref6.stackGroups,\n dataStartIndex = _ref6.dataStartIndex,\n dataEndIndex = _ref6.dataEndIndex;\n var layout = props.layout,\n children = props.children,\n stackOffset = props.stackOffset;\n var isCategorial = isCategorialAxis(layout, axisType); // Eliminate duplicated axes\n\n var axisMap = axes.reduce(function (result, child) {\n var _child$props = child.props,\n type = _child$props.type,\n dataKey = _child$props.dataKey,\n allowDataOverflow = _child$props.allowDataOverflow,\n allowDuplicatedCategory = _child$props.allowDuplicatedCategory,\n scale = _child$props.scale,\n ticks = _child$props.ticks;\n var axisId = child.props[axisIdKey];\n\n var displayedData = _this3.constructor.getDisplayedData(props, {\n graphicalItems: graphicalItems.filter(function (item) {\n return item.props[axisIdKey] === axisId;\n }),\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n });\n\n var len = displayedData.length;\n\n if (!result[axisId]) {\n var domain, duplicateDomain, categoricalDomain;\n\n if (dataKey) {\n domain = getDomainOfDataByKey(displayedData, dataKey, type);\n\n if (type === 'category' && isCategorial) {\n var duplicate = hasDuplicate(domain);\n\n if (allowDuplicatedCategory && duplicate) {\n duplicateDomain = domain; // When category axis has duplicated text, serial numbers are used to generate scale\n\n domain = _range(0, len);\n } else if (!allowDuplicatedCategory) {\n // remove duplicated category\n domain = parseDomainOfCategoryAxis(child.props.domain, domain, child).reduce(function (finalDomain, entry) {\n return finalDomain.indexOf(entry) >= 0 ? finalDomain : _toConsumableArray(finalDomain).concat([entry]);\n }, []);\n }\n } else if (type === 'category') {\n if (!allowDuplicatedCategory) {\n domain = parseDomainOfCategoryAxis(child.props.domain, domain, child).reduce(function (finalDomain, entry) {\n return finalDomain.indexOf(entry) >= 0 || entry === '' || _isNil(entry) ? finalDomain : _toConsumableArray(finalDomain).concat([entry]);\n }, []);\n } else {\n // eliminate undefined or null or empty string\n domain = domain.filter(function (entry) {\n return entry !== '' && !_isNil(entry);\n });\n }\n } else if (type === 'number') {\n var errorBarsDomain = parseErrorBarsOfAxis(displayedData, graphicalItems.filter(function (item) {\n return item.props[axisIdKey] === axisId && !item.props.hide;\n }), dataKey, axisType);\n\n if (errorBarsDomain) {\n domain = errorBarsDomain;\n }\n }\n\n if (isCategorial && (type === 'number' || scale !== 'auto')) {\n categoricalDomain = getDomainOfDataByKey(displayedData, dataKey, 'category');\n }\n } else if (isCategorial) {\n domain = _range(0, len);\n } else if (stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack && type === 'number') {\n // when stackOffset is 'expand', the domain may be calculated as [0, 1.000000000002]\n domain = stackOffset === 'expand' ? [0, 1] : getDomainOfStackGroups(stackGroups[axisId].stackGroups, dataStartIndex, dataEndIndex);\n } else {\n domain = getDomainOfItemsWithSameAxis(displayedData, graphicalItems.filter(function (item) {\n return item.props[axisIdKey] === axisId && !item.props.hide;\n }), type, true);\n }\n\n if (type === 'number') {\n // To detect wether there is any reference lines whose props alwaysShow is true\n domain = detectReferenceElementsDomain(children, domain, axisId, axisType, ticks);\n\n if (child.props.domain) {\n domain = parseSpecifiedDomain(child.props.domain, domain, allowDataOverflow);\n }\n }\n\n return _objectSpread({}, result, _defineProperty({}, axisId, _objectSpread({}, child.props, {\n axisType: axisType,\n domain: domain,\n categoricalDomain: categoricalDomain,\n duplicateDomain: duplicateDomain,\n originalDomain: child.props.domain,\n isCategorial: isCategorial,\n layout: layout\n })));\n }\n\n return result;\n }, {});\n return axisMap;\n }\n /**\n * Get the configuration of axis by the options of item,\n * this kind of axis does not display in chart\n * @param {Object} props Latest props\n * @param {Array} graphicalItems The instances of item\n * @param {ReactElement} Axis Axis Component\n * @param {String} axisType The type of axis, xAxis - x-axis, yAxis - y-axis\n * @param {String} axisIdKey The unique id of an axis\n * @param {Object} stackGroups The items grouped by axisId and stackId\n * @param {Number} dataStartIndex The start index of the data series when a brush is applied\n * @param {Number} dataEndIndex The end index of the data series when a brush is applied\n * @return {Object} Configuration\n */\n\n }, {\n key: \"getAxisMapByItems\",\n value: function getAxisMapByItems(props, _ref7) {\n var graphicalItems = _ref7.graphicalItems,\n Axis = _ref7.Axis,\n axisType = _ref7.axisType,\n axisIdKey = _ref7.axisIdKey,\n stackGroups = _ref7.stackGroups,\n dataStartIndex = _ref7.dataStartIndex,\n dataEndIndex = _ref7.dataEndIndex;\n var layout = props.layout,\n children = props.children;\n var displayedData = this.constructor.getDisplayedData(props, {\n graphicalItems: graphicalItems,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n });\n var len = displayedData.length;\n var isCategorial = isCategorialAxis(layout, axisType);\n var index = -1; // The default type of x-axis is category axis,\n // The default contents of x-axis is the serial numbers of data\n // The default type of y-axis is number axis\n // The default contents of y-axis is the domain of data\n\n var axisMap = graphicalItems.reduce(function (result, child) {\n var axisId = child.props[axisIdKey];\n\n if (!result[axisId]) {\n index++;\n var domain;\n\n if (isCategorial) {\n domain = _range(0, len);\n } else if (stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack) {\n domain = getDomainOfStackGroups(stackGroups[axisId].stackGroups, dataStartIndex, dataEndIndex);\n domain = detectReferenceElementsDomain(children, domain, axisId, axisType);\n } else {\n domain = parseSpecifiedDomain(Axis.defaultProps.domain, getDomainOfItemsWithSameAxis(displayedData, graphicalItems.filter(function (item) {\n return item.props[axisIdKey] === axisId && !item.props.hide;\n }), 'number'), Axis.defaultProps.allowDataOverflow);\n domain = detectReferenceElementsDomain(children, domain, axisId, axisType);\n }\n\n return _objectSpread({}, result, _defineProperty({}, axisId, _objectSpread({\n axisType: axisType\n }, Axis.defaultProps, {\n hide: true,\n orientation: ORIENT_MAP[axisType] && ORIENT_MAP[axisType][index % 2],\n domain: domain,\n originalDomain: Axis.defaultProps.domain,\n isCategorial: isCategorial,\n layout: layout // specify scale when no Axis\n // scale: isCategorial ? 'band' : 'linear',\n\n })));\n }\n\n return result;\n }, {});\n return axisMap;\n }\n }, {\n key: \"getActiveCoordinate\",\n value: function getActiveCoordinate(tooltipTicks, activeIndex, rangeObj) {\n var layout = this.props.layout;\n var entry = tooltipTicks.find(function (tick) {\n return tick && tick.index === activeIndex;\n });\n\n if (entry) {\n if (layout === 'horizontal') {\n return {\n x: entry.coordinate,\n y: rangeObj.y\n };\n }\n\n if (layout === 'vertical') {\n return {\n x: rangeObj.x,\n y: entry.coordinate\n };\n }\n\n if (layout === 'centric') {\n var _angle = entry.coordinate;\n var _radius = rangeObj.radius;\n return _objectSpread({}, rangeObj, polarToCartesian(rangeObj.cx, rangeObj.cy, _radius, _angle), {\n angle: _angle,\n radius: _radius\n });\n }\n\n var radius = entry.coordinate;\n var angle = rangeObj.angle;\n return _objectSpread({}, rangeObj, polarToCartesian(rangeObj.cx, rangeObj.cy, radius, angle), {\n angle: angle,\n radius: radius\n });\n }\n\n return originCoordinate;\n }\n /**\n * Get the information of mouse in chart, return null when the mouse is not in the chart\n * @param {Object} event The event object\n * @return {Object} Mouse data\n */\n\n }, {\n key: \"getMouseInfo\",\n value: function getMouseInfo(event) {\n if (!this.container) {\n return null;\n }\n\n var containerOffset = getOffset(this.container);\n var e = calculateChartCoordinate(event, containerOffset);\n var rangeObj = this.inRange(e.chartX, e.chartY);\n\n if (!rangeObj) {\n return null;\n }\n\n var _this$state9 = this.state,\n xAxisMap = _this$state9.xAxisMap,\n yAxisMap = _this$state9.yAxisMap;\n\n if (eventType !== 'axis' && xAxisMap && yAxisMap) {\n var xScale = getAnyElementOfObject(xAxisMap).scale;\n var yScale = getAnyElementOfObject(yAxisMap).scale;\n var xValue = xScale && xScale.invert ? xScale.invert(e.chartX) : null;\n var yValue = yScale && yScale.invert ? yScale.invert(e.chartY) : null;\n return _objectSpread({}, e, {\n xValue: xValue,\n yValue: yValue\n });\n }\n\n var _this$state10 = this.state,\n ticks = _this$state10.orderedTooltipTicks,\n axis = _this$state10.tooltipAxis,\n tooltipTicks = _this$state10.tooltipTicks;\n var pos = this.calculateTooltipPos(rangeObj);\n var activeIndex = calculateActiveTickIndex(pos, ticks, tooltipTicks, axis);\n\n if (activeIndex >= 0 && tooltipTicks) {\n var activeLabel = tooltipTicks[activeIndex] && tooltipTicks[activeIndex].value;\n var activePayload = this.getTooltipContent(activeIndex, activeLabel);\n var activeCoordinate = this.getActiveCoordinate(ticks, activeIndex, rangeObj);\n return _objectSpread({}, e, {\n activeTooltipIndex: activeIndex,\n activeLabel: activeLabel,\n activePayload: activePayload,\n activeCoordinate: activeCoordinate\n });\n }\n\n return null;\n }\n /**\n * Get the content to be displayed in the tooltip\n * @param {Number} activeIndex Active index of data\n * @param {String} activeLabel Active label of data\n * @return {Array} The content of tooltip\n */\n\n }, {\n key: \"getTooltipContent\",\n value: function getTooltipContent(activeIndex, activeLabel) {\n var _this$state11 = this.state,\n graphicalItems = _this$state11.graphicalItems,\n tooltipAxis = _this$state11.tooltipAxis;\n var displayedData = this.constructor.getDisplayedData(this.props, this.state);\n\n if (activeIndex < 0 || !graphicalItems || !graphicalItems.length || activeIndex >= displayedData.length) {\n return null;\n } // get data by activeIndex when the axis don't allow duplicated category\n\n\n return graphicalItems.reduce(function (result, child) {\n var hide = child.props.hide;\n\n if (hide) {\n return result;\n }\n\n var _child$props2 = child.props,\n dataKey = _child$props2.dataKey,\n name = _child$props2.name,\n unit = _child$props2.unit,\n formatter = _child$props2.formatter,\n data = _child$props2.data;\n var payload;\n\n if (tooltipAxis.dataKey && !tooltipAxis.allowDuplicatedCategory) {\n // graphic child has data props\n payload = findEntryInArray(data || displayedData, tooltipAxis.dataKey, activeLabel);\n } else {\n payload = displayedData[activeIndex];\n }\n\n if (!payload) {\n return result;\n }\n\n return _toConsumableArray(result).concat([_objectSpread({}, getPresentationAttributes(child), {\n dataKey: dataKey,\n unit: unit,\n formatter: formatter,\n name: name || dataKey,\n color: getMainColorOfGraphicItem(child),\n value: getValueByDataKey(payload, dataKey),\n payload: payload\n })]);\n }, []);\n }\n }, {\n key: \"getFormatItems\",\n value: function getFormatItems(props, currentState) {\n var _this4 = this;\n\n var graphicalItems = currentState.graphicalItems,\n stackGroups = currentState.stackGroups,\n offset = currentState.offset,\n updateId = currentState.updateId,\n dataStartIndex = currentState.dataStartIndex,\n dataEndIndex = currentState.dataEndIndex;\n var barSize = props.barSize,\n layout = props.layout,\n barGap = props.barGap,\n barCategoryGap = props.barCategoryGap,\n globalMaxBarSize = props.maxBarSize;\n\n var _this$constructor$get = this.constructor.getAxisNameByLayout(layout),\n numericAxisName = _this$constructor$get.numericAxisName,\n cateAxisName = _this$constructor$get.cateAxisName;\n\n var hasBar = this.constructor.hasBar(graphicalItems);\n var sizeList = hasBar && getBarSizeList({\n barSize: barSize,\n stackGroups: stackGroups\n });\n var formatedItems = [];\n graphicalItems.forEach(function (item, index) {\n var displayedData = _this4.constructor.getDisplayedData(props, {\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n }, item);\n\n var _item$props2 = item.props,\n dataKey = _item$props2.dataKey,\n childMaxBarSize = _item$props2.maxBarSize;\n var numericAxisId = item.props[\"\".concat(numericAxisName, \"Id\")];\n var cateAxisId = item.props[\"\".concat(cateAxisName, \"Id\")];\n var axisObj = axisComponents.reduce(function (result, entry) {\n var _objectSpread4;\n\n var axisMap = currentState[\"\".concat(entry.axisType, \"Map\")];\n var id = item.props[\"\".concat(entry.axisType, \"Id\")];\n var axis = axisMap && axisMap[id];\n return _objectSpread({}, result, (_objectSpread4 = {}, _defineProperty(_objectSpread4, entry.axisType, axis), _defineProperty(_objectSpread4, \"\".concat(entry.axisType, \"Ticks\"), getTicksOfAxis(axis)), _objectSpread4));\n }, {});\n var cateAxis = axisObj[cateAxisName];\n var cateTicks = axisObj[\"\".concat(cateAxisName, \"Ticks\")];\n var stackedData = stackGroups && stackGroups[numericAxisId] && stackGroups[numericAxisId].hasStack && getStackedDataOfItem(item, stackGroups[numericAxisId].stackGroups);\n var bandSize = getBandSizeOfAxis(cateAxis, cateTicks);\n var maxBarSize = _isNil(childMaxBarSize) ? globalMaxBarSize : childMaxBarSize;\n var barPosition = hasBar && getBarPosition({\n barGap: barGap,\n barCategoryGap: barCategoryGap,\n bandSize: bandSize,\n sizeList: sizeList[cateAxisId],\n maxBarSize: maxBarSize\n });\n var componsedFn = item && item.type && item.type.getComposedData;\n\n if (componsedFn) {\n var _objectSpread5;\n\n formatedItems.push({\n props: _objectSpread({}, componsedFn(_objectSpread({}, axisObj, {\n displayedData: displayedData,\n props: props,\n dataKey: dataKey,\n item: item,\n bandSize: bandSize,\n barPosition: barPosition,\n offset: offset,\n stackedData: stackedData,\n layout: layout,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex,\n onItemMouseLeave: combineEventHandlers(_this4.handleItemMouseLeave, null, item.props.onMouseLeave),\n onItemMouseEnter: combineEventHandlers(_this4.handleItemMouseEnter, null, item.props.onMouseEnter)\n })), (_objectSpread5 = {\n key: item.key || \"item-\".concat(index)\n }, _defineProperty(_objectSpread5, numericAxisName, axisObj[numericAxisName]), _defineProperty(_objectSpread5, cateAxisName, axisObj[cateAxisName]), _defineProperty(_objectSpread5, \"animationId\", updateId), _objectSpread5)),\n childIndex: parseChildIndex(item, props.children),\n item: item\n });\n }\n });\n return formatedItems;\n }\n }, {\n key: \"getCursorRectangle\",\n value: function getCursorRectangle() {\n var layout = this.props.layout;\n var _this$state12 = this.state,\n activeCoordinate = _this$state12.activeCoordinate,\n offset = _this$state12.offset,\n tooltipAxisBandSize = _this$state12.tooltipAxisBandSize;\n var halfSize = tooltipAxisBandSize / 2;\n return {\n stroke: 'none',\n fill: '#ccc',\n x: layout === 'horizontal' ? activeCoordinate.x - halfSize : offset.left + 0.5,\n y: layout === 'horizontal' ? offset.top + 0.5 : activeCoordinate.y - halfSize,\n width: layout === 'horizontal' ? tooltipAxisBandSize : offset.width - 1,\n height: layout === 'horizontal' ? offset.height - 1 : tooltipAxisBandSize\n };\n }\n }, {\n key: \"getCursorPoints\",\n value: function getCursorPoints() {\n var layout = this.props.layout;\n var _this$state13 = this.state,\n activeCoordinate = _this$state13.activeCoordinate,\n offset = _this$state13.offset;\n var x1, y1, x2, y2;\n\n if (layout === 'horizontal') {\n x1 = activeCoordinate.x;\n x2 = x1;\n y1 = offset.top;\n y2 = offset.top + offset.height;\n } else if (layout === 'vertical') {\n y1 = activeCoordinate.y;\n y2 = y1;\n x1 = offset.left;\n x2 = offset.left + offset.width;\n } else if (!_isNil(activeCoordinate.cx) || !_isNil(activeCoordinate.cy)) {\n if (layout === 'centric') {\n var cx = activeCoordinate.cx,\n cy = activeCoordinate.cy,\n innerRadius = activeCoordinate.innerRadius,\n outerRadius = activeCoordinate.outerRadius,\n angle = activeCoordinate.angle;\n var innerPoint = polarToCartesian(cx, cy, innerRadius, angle);\n var outerPoint = polarToCartesian(cx, cy, outerRadius, angle);\n x1 = innerPoint.x;\n y1 = innerPoint.y;\n x2 = outerPoint.x;\n y2 = outerPoint.y;\n } else {\n var _cx = activeCoordinate.cx,\n _cy = activeCoordinate.cy,\n radius = activeCoordinate.radius,\n startAngle = activeCoordinate.startAngle,\n endAngle = activeCoordinate.endAngle;\n var startPoint = polarToCartesian(_cx, _cy, radius, startAngle);\n var endPoint = polarToCartesian(_cx, _cy, radius, endAngle);\n return {\n points: [startPoint, endPoint],\n cx: _cx,\n cy: _cy,\n radius: radius,\n startAngle: startAngle,\n endAngle: endAngle\n };\n }\n }\n\n return [{\n x: x1,\n y: y1\n }, {\n x: x2,\n y: y2\n }];\n }\n }, {\n key: \"calculateTooltipPos\",\n value: function calculateTooltipPos(rangeObj) {\n var layout = this.props.layout;\n\n if (layout === 'horizontal') {\n return rangeObj.x;\n }\n\n if (layout === 'vertical') {\n return rangeObj.y;\n }\n\n if (layout === 'centric') {\n return rangeObj.angle;\n }\n\n return rangeObj.radius;\n }\n }, {\n key: \"inRange\",\n value: function inRange(x, y) {\n var layout = this.props.layout;\n\n if (layout === 'horizontal' || layout === 'vertical') {\n var offset = this.state.offset;\n var isInRange = x >= offset.left && x <= offset.left + offset.width && y >= offset.top && y <= offset.top + offset.height;\n return isInRange ? {\n x: x,\n y: y\n } : null;\n }\n\n var _this$state14 = this.state,\n angleAxisMap = _this$state14.angleAxisMap,\n radiusAxisMap = _this$state14.radiusAxisMap;\n\n if (angleAxisMap && radiusAxisMap) {\n var angleAxis = getAnyElementOfObject(angleAxisMap);\n return inRangeOfSector({\n x: x,\n y: y\n }, angleAxis);\n }\n\n return null;\n }\n }, {\n key: \"parseEventsOfWrapper\",\n value: function parseEventsOfWrapper() {\n var children = this.props.children;\n var tooltipItem = findChildByType(children, Tooltip);\n var tooltipEvents = tooltipItem && eventType === 'axis' ? {\n onMouseEnter: this.handleMouseEnter,\n onMouseMove: this.handleMouseMove,\n onMouseLeave: this.handleMouseLeave,\n onTouchMove: this.handleTouchMove,\n onTouchStart: this.handleTouchStart,\n onTouchEnd: this.handleTouchEnd\n } : {};\n var outerEvents = filterEventAttributes(this.props, this.handleOuterEvent);\n return _objectSpread({}, outerEvents, tooltipEvents);\n }\n /**\n * The AxisMaps are expensive to render on large data sets\n * so provide the ability to store them in state and only update them when necessary\n * they are dependent upon the start and end index of\n * the brush so it's important that this method is called _after_\n * the state is updated with any new start/end indices\n *\n * @param {Object} props The props object to be used for updating the axismaps\n * @param {Number} dataStartIndex The start index of the data series when a brush is applied\n * @param {Number} dataEndIndex The end index of the data series when a brush is applied\n * @param {Number} updateId The update id\n * @return {Object} state New state to set\n */\n\n }, {\n key: \"updateStateOfAxisMapsOffsetAndStackGroups\",\n value: function updateStateOfAxisMapsOffsetAndStackGroups(_ref8) {\n var _this5 = this;\n\n var props = _ref8.props,\n dataStartIndex = _ref8.dataStartIndex,\n dataEndIndex = _ref8.dataEndIndex,\n updateId = _ref8.updateId;\n\n if (!validateWidthHeight({\n props: props\n })) {\n return null;\n }\n\n var children = props.children,\n layout = props.layout,\n stackOffset = props.stackOffset,\n data = props.data,\n reverseStackOrder = props.reverseStackOrder;\n\n var _this$constructor$get2 = this.constructor.getAxisNameByLayout(layout),\n numericAxisName = _this$constructor$get2.numericAxisName,\n cateAxisName = _this$constructor$get2.cateAxisName;\n\n var graphicalItems = findAllByType(children, GraphicalChild);\n var stackGroups = getStackGroupsByAxisId(data, graphicalItems, \"\".concat(numericAxisName, \"Id\"), \"\".concat(cateAxisName, \"Id\"), stackOffset, reverseStackOrder);\n var axisObj = axisComponents.reduce(function (result, entry) {\n var name = \"\".concat(entry.axisType, \"Map\");\n return _objectSpread({}, result, _defineProperty({}, name, _this5.getAxisMap(props, _objectSpread({}, entry, {\n graphicalItems: graphicalItems,\n stackGroups: entry.axisType === numericAxisName && stackGroups,\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex\n }))));\n }, {});\n var offset = this.calculateOffset(_objectSpread({}, axisObj, {\n props: props,\n graphicalItems: graphicalItems\n }));\n Object.keys(axisObj).forEach(function (key) {\n axisObj[key] = formatAxisMap(props, axisObj[key], offset, key.replace('Map', ''), chartName);\n });\n var cateAxisMap = axisObj[\"\".concat(cateAxisName, \"Map\")];\n var ticksObj = this.tooltipTicksGenerator(cateAxisMap);\n var formatedGraphicalItems = this.getFormatItems(props, _objectSpread({}, axisObj, {\n dataStartIndex: dataStartIndex,\n dataEndIndex: dataEndIndex,\n updateId: updateId,\n graphicalItems: graphicalItems,\n stackGroups: stackGroups,\n offset: offset\n }));\n return _objectSpread({\n formatedGraphicalItems: formatedGraphicalItems,\n graphicalItems: graphicalItems,\n offset: offset,\n stackGroups: stackGroups\n }, ticksObj, axisObj);\n }\n /* eslint-disable no-underscore-dangle */\n\n }, {\n key: \"addListener\",\n value: function addListener() {\n eventCenter.on(SYNC_EVENT, this.handleReceiveSyncEvent);\n\n if (eventCenter.setMaxListeners && eventCenter._maxListeners) {\n eventCenter.setMaxListeners(eventCenter._maxListeners + 1);\n }\n }\n }, {\n key: \"removeListener\",\n value: function removeListener() {\n eventCenter.removeListener(SYNC_EVENT, this.handleReceiveSyncEvent);\n\n if (eventCenter.setMaxListeners && eventCenter._maxListeners) {\n eventCenter.setMaxListeners(eventCenter._maxListeners - 1);\n }\n }\n /**\n * Calculate the offset of main part in the svg element\n * @param {Object} props Latest props\n * @param {Array} graphicalItems The instances of item\n * @param {Object} xAxisMap The configuration of x-axis\n * @param {Object} yAxisMap The configuration of y-axis\n * @return {Object} The offset of main part in the svg element\n */\n\n }, {\n key: \"calculateOffset\",\n value: function calculateOffset(_ref9) {\n var props = _ref9.props,\n graphicalItems = _ref9.graphicalItems,\n _ref9$xAxisMap = _ref9.xAxisMap,\n xAxisMap = _ref9$xAxisMap === void 0 ? {} : _ref9$xAxisMap,\n _ref9$yAxisMap = _ref9.yAxisMap,\n yAxisMap = _ref9$yAxisMap === void 0 ? {} : _ref9$yAxisMap;\n var width = props.width,\n height = props.height,\n children = props.children;\n var margin = props.margin || {};\n var brushItem = findChildByType(children, Brush);\n var legendItem = findChildByType(children, Legend);\n var offsetH = Object.keys(yAxisMap).reduce(function (result, id) {\n var entry = yAxisMap[id];\n var orientation = entry.orientation;\n\n if (!entry.mirror && !entry.hide) {\n return _objectSpread({}, result, _defineProperty({}, orientation, result[orientation] + entry.width));\n }\n\n return result;\n }, {\n left: margin.left || 0,\n right: margin.right || 0\n });\n var offsetV = Object.keys(xAxisMap).reduce(function (result, id) {\n var entry = xAxisMap[id];\n var orientation = entry.orientation;\n\n if (!entry.mirror && !entry.hide) {\n return _objectSpread({}, result, _defineProperty({}, orientation, result[orientation] + entry.height));\n }\n\n return result;\n }, {\n top: margin.top || 0,\n bottom: margin.bottom || 0\n });\n\n var offset = _objectSpread({}, offsetV, offsetH);\n\n var brushBottom = offset.bottom;\n\n if (brushItem) {\n offset.bottom += brushItem.props.height || Brush.defaultProps.height;\n }\n\n if (legendItem && this.legendInstance) {\n var legendBox = this.legendInstance.getBBox();\n offset = appendOffsetOfLegend(offset, graphicalItems, props, legendBox);\n }\n\n return _objectSpread({\n brushBottom: brushBottom\n }, offset, {\n width: width - offset.left - offset.right,\n height: height - offset.top - offset.bottom\n });\n }\n }, {\n key: \"triggerSyncEvent\",\n value: function triggerSyncEvent(data) {\n var syncId = this.props.syncId;\n\n if (!_isNil(syncId)) {\n eventCenter.emit(SYNC_EVENT, syncId, this.uniqueChartId, data);\n }\n }\n }, {\n key: \"filterFormatItem\",\n value: function filterFormatItem(item, displayName, childIndex) {\n var formatedGraphicalItems = this.state.formatedGraphicalItems;\n\n for (var i = 0, len = formatedGraphicalItems.length; i < len; i++) {\n var entry = formatedGraphicalItems[i];\n\n if (entry.item === item || entry.props.key === item.key || displayName === getDisplayName(entry.item.type) && childIndex === entry.childIndex) {\n return entry;\n }\n }\n\n return null;\n }\n }, {\n key: \"renderAxis\",\n\n /**\n * Draw axis\n * @param {Object} axisOptions The options of axis\n * @param {Object} element The axis element\n * @param {String} displayName The display name of axis\n * @param {Number} index The index of element\n * @return {ReactElement} The instance of x-axes\n */\n value: function renderAxis(axisOptions, element, displayName, index) {\n var _this$props5 = this.props,\n width = _this$props5.width,\n height = _this$props5.height;\n return React.createElement(CartesianAxis, _extends({}, axisOptions, {\n className: \"recharts-\".concat(axisOptions.axisType, \" \").concat(axisOptions.axisType),\n key: element.key || \"\".concat(displayName, \"-\").concat(index),\n viewBox: {\n x: 0,\n y: 0,\n width: width,\n height: height\n },\n ticksGenerator: this.axesTicksGenerator\n }));\n }\n /**\n * Draw grid\n * @param {ReactElement} element the grid item\n * @return {ReactElement} The instance of grid\n */\n\n }, {\n key: \"renderLegend\",\n\n /**\n * Draw legend\n * @return {ReactElement} The instance of Legend\n */\n value: function renderLegend() {\n var _this6 = this;\n\n var formatedGraphicalItems = this.state.formatedGraphicalItems;\n var _this$props6 = this.props,\n children = _this$props6.children,\n width = _this$props6.width,\n height = _this$props6.height;\n var margin = this.props.margin || {};\n var legendWidth = width - (margin.left || 0) - (margin.right || 0);\n var legendHeight = height - (margin.top || 0) - (margin.bottom || 0);\n var props = getLegendProps({\n children: children,\n formatedGraphicalItems: formatedGraphicalItems,\n legendWidth: legendWidth,\n legendHeight: legendHeight,\n legendContent: legendContent\n });\n\n if (!props) {\n return null;\n }\n\n var item = props.item,\n otherProps = _objectWithoutProperties(props, [\"item\"]);\n\n return cloneElement(item, _objectSpread({}, otherProps, {\n chartWidth: width,\n chartHeight: height,\n margin: margin,\n ref: function ref(legend) {\n _this6.legendInstance = legend;\n },\n onBBoxUpdate: this.handleLegendBBoxUpdate\n }));\n }\n /**\n * Draw Tooltip\n * @return {ReactElement} The instance of Tooltip\n */\n\n }, {\n key: \"renderTooltip\",\n value: function renderTooltip() {\n var children = this.props.children;\n var tooltipItem = findChildByType(children, Tooltip);\n\n if (!tooltipItem) {\n return null;\n }\n\n var _this$state15 = this.state,\n isTooltipActive = _this$state15.isTooltipActive,\n activeCoordinate = _this$state15.activeCoordinate,\n activePayload = _this$state15.activePayload,\n activeLabel = _this$state15.activeLabel,\n offset = _this$state15.offset;\n return cloneElement(tooltipItem, {\n viewBox: _objectSpread({}, offset, {\n x: offset.left,\n y: offset.top\n }),\n active: isTooltipActive,\n label: activeLabel,\n payload: isTooltipActive ? activePayload : [],\n coordinate: activeCoordinate\n });\n }\n }, {\n key: \"renderActivePoints\",\n value: function renderActivePoints(_ref10) {\n var item = _ref10.item,\n activePoint = _ref10.activePoint,\n basePoint = _ref10.basePoint,\n childIndex = _ref10.childIndex,\n isRange = _ref10.isRange;\n var result = [];\n var key = item.props.key;\n var _item$item$props2 = item.item.props,\n activeDot = _item$item$props2.activeDot,\n dataKey = _item$item$props2.dataKey;\n\n var dotProps = _objectSpread({\n index: childIndex,\n dataKey: dataKey,\n cx: activePoint.x,\n cy: activePoint.y,\n r: 4,\n fill: getMainColorOfGraphicItem(item.item),\n strokeWidth: 2,\n stroke: '#fff',\n payload: activePoint.payload,\n value: activePoint.value,\n key: \"\".concat(key, \"-activePoint-\").concat(childIndex)\n }, getPresentationAttributes(activeDot), filterEventAttributes(activeDot));\n\n result.push(this.constructor.renderActiveDot(activeDot, dotProps, childIndex));\n\n if (basePoint) {\n result.push(this.constructor.renderActiveDot(activeDot, _objectSpread({}, dotProps, {\n cx: basePoint.x,\n cy: basePoint.y,\n key: \"\".concat(key, \"-basePoint-\").concat(childIndex)\n }), childIndex));\n } else if (isRange) {\n result.push(null);\n }\n\n return result;\n }\n }, {\n key: \"renderClipPath\",\n value: function renderClipPath() {\n var clipPathId = this.clipPathId;\n var _this$state$offset = this.state.offset,\n left = _this$state$offset.left,\n top = _this$state$offset.top,\n height = _this$state$offset.height,\n width = _this$state$offset.width;\n return React.createElement(\"defs\", null, React.createElement(\"clipPath\", {\n id: clipPathId\n }, React.createElement(\"rect\", {\n x: left,\n y: top,\n height: height,\n width: width\n })));\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this7 = this;\n\n if (!validateWidthHeight(this)) {\n return null;\n }\n\n var _this$props7 = this.props,\n children = _this$props7.children,\n className = _this$props7.className,\n width = _this$props7.width,\n height = _this$props7.height,\n style = _this$props7.style,\n compact = _this$props7.compact,\n others = _objectWithoutProperties(_this$props7, [\"children\", \"className\", \"width\", \"height\", \"style\", \"compact\"]);\n\n var attrs = getPresentationAttributes(others);\n var map = {\n CartesianGrid: {\n handler: this.renderGrid,\n once: true\n },\n ReferenceArea: {\n handler: this.renderReferenceElement\n },\n ReferenceLine: {\n handler: this.renderReferenceElement\n },\n ReferenceDot: {\n handler: this.renderReferenceElement\n },\n XAxis: {\n handler: this.renderXAxis\n },\n YAxis: {\n handler: this.renderYAxis\n },\n Brush: {\n handler: this.renderBrush,\n once: true\n },\n Bar: {\n handler: this.renderGraphicChild\n },\n Line: {\n handler: this.renderGraphicChild\n },\n Area: {\n handler: this.renderGraphicChild\n },\n Radar: {\n handler: this.renderGraphicChild\n },\n RadialBar: {\n handler: this.renderGraphicChild\n },\n Scatter: {\n handler: this.renderGraphicChild\n },\n Pie: {\n handler: this.renderGraphicChild\n },\n Funnel: {\n handler: this.renderGraphicChild\n },\n Tooltip: {\n handler: this.renderCursor,\n once: true\n },\n PolarGrid: {\n handler: this.renderPolarGrid,\n once: true\n },\n PolarAngleAxis: {\n handler: this.renderPolarAxis\n },\n PolarRadiusAxis: {\n handler: this.renderPolarAxis\n }\n }; // The \"compact\" mode is mainly used as the panorama within Brush\n\n if (compact) {\n return React.createElement(Surface, _extends({}, attrs, {\n width: width,\n height: height\n }), this.renderClipPath(), renderByOrder(children, map));\n }\n\n var events = this.parseEventsOfWrapper();\n return React.createElement(\"div\", _extends({\n className: classNames('recharts-wrapper', className),\n style: _objectSpread({\n position: 'relative',\n cursor: 'default',\n width: width,\n height: height\n }, style)\n }, events, {\n ref: function ref(node) {\n _this7.container = node;\n }\n }), React.createElement(Surface, _extends({}, attrs, {\n width: width,\n height: height\n }), this.renderClipPath(), renderByOrder(children, map)), this.renderLegend(), this.renderTooltip());\n }\n }], [{\n key: \"getAxisNameByLayout\",\n value: function getAxisNameByLayout(layout) {\n if (layout === 'horizontal') {\n return {\n numericAxisName: 'yAxis',\n cateAxisName: 'xAxis'\n };\n }\n\n if (layout === 'vertical') {\n return {\n numericAxisName: 'xAxis',\n cateAxisName: 'yAxis'\n };\n }\n\n if (layout === 'centric') {\n return {\n numericAxisName: 'radiusAxis',\n cateAxisName: 'angleAxis'\n };\n }\n\n return {\n numericAxisName: 'angleAxis',\n cateAxisName: 'radiusAxis'\n };\n }\n }, {\n key: \"renderActiveDot\",\n value: function renderActiveDot(option, props) {\n var dot;\n\n if (isValidElement(option)) {\n dot = cloneElement(option, props);\n } else if (_isFunction(option)) {\n dot = option(props);\n } else {\n dot = React.createElement(Dot, props);\n }\n\n return React.createElement(Layer, {\n className: \"recharts-active-dot\",\n key: props.key\n }, dot);\n }\n }]);\n\n return CategoricalChartWrapper;\n }(Component);\n\n CategoricalChartWrapper.displayName = chartName;\n CategoricalChartWrapper.propTypes = _objectSpread({\n syncId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n compact: PropTypes.bool,\n width: PropTypes.number,\n height: PropTypes.number,\n data: PropTypes.arrayOf(PropTypes.object),\n layout: PropTypes.oneOf(['horizontal', 'vertical']),\n stackOffset: PropTypes.oneOf(['sign', 'expand', 'none', 'wiggle', 'silhouette']),\n throttleDelay: PropTypes.number,\n margin: PropTypes.shape({\n top: PropTypes.number,\n right: PropTypes.number,\n bottom: PropTypes.number,\n left: PropTypes.number\n }),\n barCategoryGap: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n barGap: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n barSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n maxBarSize: PropTypes.number,\n style: PropTypes.object,\n className: PropTypes.string,\n children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),\n defaultShowTooltip: PropTypes.bool,\n onClick: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onMouseEnter: PropTypes.func,\n onMouseMove: PropTypes.func,\n onMouseDown: PropTypes.func,\n onMouseUp: PropTypes.func,\n reverseStackOrder: PropTypes.bool,\n id: PropTypes.string\n }, propTypes);\n CategoricalChartWrapper.defaultProps = _objectSpread({\n layout: 'horizontal',\n stackOffset: 'none',\n barCategoryGap: '10%',\n barGap: 4,\n margin: {\n top: 5,\n right: 5,\n bottom: 5,\n left: 5\n },\n reverseStackOrder: false\n }, defaultProps);\n\n CategoricalChartWrapper.createDefaultState = function (props) {\n var children = props.children,\n defaultShowTooltip = props.defaultShowTooltip;\n var brushItem = findChildByType(children, Brush);\n var startIndex = brushItem && brushItem.props && brushItem.props.startIndex || 0;\n var endIndex = brushItem && brushItem.props && brushItem.props.endIndex || props.data && props.data.length - 1 || 0;\n return {\n chartX: 0,\n chartY: 0,\n dataStartIndex: startIndex,\n dataEndIndex: endIndex,\n activeTooltipIndex: -1,\n isTooltipActive: !_isNil(defaultShowTooltip) ? defaultShowTooltip : false\n };\n };\n\n CategoricalChartWrapper.hasBar = function (graphicalItems) {\n if (!graphicalItems || !graphicalItems.length) {\n return false;\n }\n\n return graphicalItems.some(function (item) {\n var name = getDisplayName(item && item.type);\n return name && name.indexOf('Bar') >= 0;\n });\n };\n\n CategoricalChartWrapper.getDisplayedData = function (props, _ref11, item) {\n var graphicalItems = _ref11.graphicalItems,\n dataStartIndex = _ref11.dataStartIndex,\n dataEndIndex = _ref11.dataEndIndex;\n var itemsData = (graphicalItems || []).reduce(function (result, child) {\n var itemData = child.props.data;\n\n if (itemData && itemData.length) {\n return _toConsumableArray(result).concat(_toConsumableArray(itemData));\n }\n\n return result;\n }, []);\n\n if (itemsData && itemsData.length > 0) {\n return itemsData;\n }\n\n if (item && item.props && item.props.data && item.props.data.length > 0) {\n return item.props.data;\n }\n\n var data = props.data;\n\n if (data && data.length && isNumber(dataStartIndex) && isNumber(dataEndIndex)) {\n return data.slice(dataStartIndex, dataEndIndex + 1);\n }\n\n return [];\n };\n\n return CategoricalChartWrapper;\n};\n\nexport default generateCategoricalChart;", + "/**\n * @fileOverview Area Chart\n */\nimport generateCategoricalChart from './generateCategoricalChart';\nimport Area from '../cartesian/Area';\nimport XAxis from '../cartesian/XAxis';\nimport YAxis from '../cartesian/YAxis';\nimport { formatAxisMap } from '../util/CartesianUtils';\nexport default generateCategoricalChart({\n chartName: 'AreaChart',\n GraphicalChild: Area,\n axisComponents: [{\n axisType: 'xAxis',\n AxisComp: XAxis\n }, {\n axisType: 'yAxis',\n AxisComp: YAxis\n }],\n formatAxisMap: formatAxisMap\n});", + "import _isObject from \"lodash/isObject\";\nimport _isFunction from \"lodash/isFunction\";\nimport _isNil from \"lodash/isNil\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nimport React, { cloneElement, isValidElement } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Text from './Text';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, findAllByType } from '../util/ReactUtils';\nimport { isNumOrStr, isNumber, isPercent, getPercentValue, uniqueId, mathSign } from '../util/DataUtils';\nimport { polarToCartesian } from '../util/PolarUtils';\nvar cartesianViewBoxShape = PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n});\nvar polarViewBoxShape = PropTypes.shape({\n cx: PropTypes.number,\n cy: PropTypes.number,\n innerRadius: PropTypes.number,\n outerRadius: PropTypes.number,\n startAngle: PropTypes.number,\n endAngle: PropTypes.number\n});\n\nvar propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n viewBox: PropTypes.oneOfType([cartesianViewBoxShape, polarViewBoxShape]),\n formatter: PropTypes.func,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n offset: PropTypes.number,\n position: PropTypes.oneOf(['top', 'left', 'right', 'bottom', 'inside', 'outside', 'insideLeft', 'insideRight', 'insideTop', 'insideBottom', 'insideTopLeft', 'insideBottomLeft', 'insideTopRight', 'insideBottomRight', 'insideStart', 'insideEnd', 'end', 'center', 'centerTop', 'centerBottom']),\n children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),\n className: PropTypes.string,\n content: PropTypes.oneOfType([PropTypes.element, PropTypes.func])\n});\n\nvar defaultProps = {\n offset: 5\n};\n\nvar getLabel = function getLabel(props) {\n var value = props.value,\n formatter = props.formatter;\n var label = _isNil(props.children) ? value : props.children;\n\n if (_isFunction(formatter)) {\n return formatter(label);\n }\n\n return label;\n};\n\nvar getDeltaAngle = function getDeltaAngle(startAngle, endAngle) {\n var sign = mathSign(endAngle - startAngle);\n var deltaAngle = Math.min(Math.abs(endAngle - startAngle), 360);\n return sign * deltaAngle;\n};\n\nvar renderRadialLabel = function renderRadialLabel(labelProps, label, attrs) {\n var position = labelProps.position,\n viewBox = labelProps.viewBox,\n offset = labelProps.offset,\n className = labelProps.className;\n var cx = viewBox.cx,\n cy = viewBox.cy,\n innerRadius = viewBox.innerRadius,\n outerRadius = viewBox.outerRadius,\n startAngle = viewBox.startAngle,\n endAngle = viewBox.endAngle,\n clockWise = viewBox.clockWise;\n var radius = (innerRadius + outerRadius) / 2;\n var deltaAngle = getDeltaAngle(startAngle, endAngle);\n var sign = deltaAngle >= 0 ? 1 : -1;\n var labelAngle, direction;\n\n if (position === 'insideStart') {\n labelAngle = startAngle + sign * offset;\n direction = clockWise;\n } else if (position === 'insideEnd') {\n labelAngle = endAngle - sign * offset;\n direction = !clockWise;\n } else if (position === 'end') {\n labelAngle = endAngle + sign * offset;\n direction = clockWise;\n }\n\n direction = deltaAngle <= 0 ? direction : !direction;\n var startPoint = polarToCartesian(cx, cy, radius, labelAngle);\n var endPoint = polarToCartesian(cx, cy, radius, labelAngle + (direction ? 1 : -1) * 359);\n var path = \"M\".concat(startPoint.x, \",\").concat(startPoint.y, \"\\n A\").concat(radius, \",\").concat(radius, \",0,1,\").concat(direction ? 0 : 1, \",\\n \").concat(endPoint.x, \",\").concat(endPoint.y);\n var id = _isNil(labelProps.id) ? uniqueId('recharts-radial-line-') : labelProps.id;\n return React.createElement(\"text\", _extends({}, attrs, {\n dominantBaseline: \"central\",\n className: classNames('recharts-radial-bar-label', className)\n }), React.createElement(\"defs\", null, React.createElement(\"path\", {\n id: id,\n d: path\n })), React.createElement(\"textPath\", {\n xlinkHref: \"#\".concat(id)\n }, label));\n};\n\nvar getAttrsOfPolarLabel = function getAttrsOfPolarLabel(props) {\n var viewBox = props.viewBox,\n offset = props.offset,\n position = props.position;\n var cx = viewBox.cx,\n cy = viewBox.cy,\n innerRadius = viewBox.innerRadius,\n outerRadius = viewBox.outerRadius,\n startAngle = viewBox.startAngle,\n endAngle = viewBox.endAngle;\n var midAngle = (startAngle + endAngle) / 2;\n\n if (position === 'outside') {\n var _polarToCartesian = polarToCartesian(cx, cy, outerRadius + offset, midAngle),\n _x = _polarToCartesian.x,\n _y = _polarToCartesian.y;\n\n return {\n x: _x,\n y: _y,\n textAnchor: _x >= cx ? 'start' : 'end',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'center') {\n return {\n x: cx,\n y: cy,\n textAnchor: 'middle',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'centerTop') {\n return {\n x: cx,\n y: cy,\n textAnchor: 'middle',\n verticalAnchor: 'start'\n };\n }\n\n if (position === 'centerBottom') {\n return {\n x: cx,\n y: cy,\n textAnchor: 'middle',\n verticalAnchor: 'end'\n };\n }\n\n var r = (innerRadius + outerRadius) / 2;\n\n var _polarToCartesian2 = polarToCartesian(cx, cy, r, midAngle),\n x = _polarToCartesian2.x,\n y = _polarToCartesian2.y;\n\n return {\n x: x,\n y: y,\n textAnchor: 'middle',\n verticalAnchor: 'middle'\n };\n};\n\nvar getAttrsOfCartesianLabel = function getAttrsOfCartesianLabel(props) {\n var viewBox = props.viewBox,\n offset = props.offset,\n position = props.position;\n var x = viewBox.x,\n y = viewBox.y,\n width = viewBox.width,\n height = viewBox.height;\n var sign = height >= 0 ? 1 : -1;\n\n if (position === 'top') {\n return {\n x: x + width / 2,\n y: y - sign * offset,\n textAnchor: 'middle',\n verticalAnchor: sign > 0 ? 'end' : 'start'\n };\n }\n\n if (position === 'bottom') {\n return {\n x: x + width / 2,\n y: y + height + sign * offset,\n textAnchor: 'middle',\n verticalAnchor: 'start'\n };\n }\n\n if (position === 'left') {\n return {\n x: x - offset,\n y: y + height / 2,\n textAnchor: 'end',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'right') {\n return {\n x: x + width + offset,\n y: y + height / 2,\n textAnchor: 'start',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'insideLeft') {\n return {\n x: x + offset,\n y: y + height / 2,\n textAnchor: 'start',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'insideRight') {\n return {\n x: x + width - offset,\n y: y + height / 2,\n textAnchor: 'end',\n verticalAnchor: 'middle'\n };\n }\n\n if (position === 'insideTop') {\n return {\n x: x + width / 2,\n y: y + sign * offset,\n textAnchor: 'middle',\n verticalAnchor: 'start'\n };\n }\n\n if (position === 'insideBottom') {\n return {\n x: x + width / 2,\n y: y + height - sign * offset,\n textAnchor: 'middle',\n verticalAnchor: 'end'\n };\n }\n\n if (position === 'insideTopLeft') {\n return {\n x: x + offset,\n y: y + sign * offset,\n textAnchor: 'start',\n verticalAnchor: 'start'\n };\n }\n\n if (position === 'insideTopRight') {\n return {\n x: x + width - offset,\n y: y + sign * offset,\n textAnchor: 'end',\n verticalAnchor: 'start'\n };\n }\n\n if (position === 'insideBottomLeft') {\n return {\n x: x + offset,\n y: y + height - sign * offset,\n textAnchor: 'start',\n verticalAnchor: 'end'\n };\n }\n\n if (position === 'insideBottomRight') {\n return {\n x: x + width - offset,\n y: y + height - sign * offset,\n textAnchor: 'end',\n verticalAnchor: 'end'\n };\n }\n\n if (_isObject(position) && (isNumber(position.x) || isPercent(position.x)) && (isNumber(position.y) || isPercent(position.y))) {\n return {\n x: x + getPercentValue(position.x, width),\n y: y + getPercentValue(position.y, height),\n textAnchor: 'end',\n verticalAnchor: 'end'\n };\n }\n\n return {\n x: x + width / 2,\n y: y + height / 2,\n textAnchor: 'middle',\n verticalAnchor: 'middle'\n };\n};\n\nvar isPolar = function isPolar(viewBox) {\n return isNumber(viewBox.cx);\n};\n\nfunction Label(props) {\n var viewBox = props.viewBox,\n position = props.position,\n value = props.value,\n children = props.children,\n content = props.content,\n _props$className = props.className,\n className = _props$className === void 0 ? '' : _props$className;\n\n if (!viewBox || _isNil(value) && _isNil(children) && !isValidElement(content) && !_isFunction(content)) {\n return null;\n }\n\n if (isValidElement(content)) {\n return cloneElement(content, props);\n }\n\n var label;\n\n if (_isFunction(content)) {\n label = content(props);\n\n if (isValidElement(label)) {\n return label;\n }\n } else {\n label = getLabel(props);\n }\n\n var isPolarLabel = isPolar(viewBox);\n var attrs = getPresentationAttributes(props);\n\n if (isPolarLabel && (position === 'insideStart' || position === 'insideEnd' || position === 'end')) {\n return renderRadialLabel(props, label, attrs);\n }\n\n var positionAttrs = isPolarLabel ? getAttrsOfPolarLabel(props) : getAttrsOfCartesianLabel(props);\n return React.createElement(Text, _extends({\n className: classNames('recharts-label', className)\n }, attrs, positionAttrs), label);\n}\n\nLabel.displayName = 'Label';\nLabel.defaultProps = defaultProps;\nLabel.propTypes = propTypes;\n\nvar parseViewBox = function parseViewBox(props) {\n var cx = props.cx,\n cy = props.cy,\n angle = props.angle,\n startAngle = props.startAngle,\n endAngle = props.endAngle,\n r = props.r,\n radius = props.radius,\n innerRadius = props.innerRadius,\n outerRadius = props.outerRadius,\n x = props.x,\n y = props.y,\n top = props.top,\n left = props.left,\n width = props.width,\n height = props.height,\n clockWise = props.clockWise;\n\n if (isNumber(width) && isNumber(height)) {\n if (isNumber(x) && isNumber(y)) {\n return {\n x: x,\n y: y,\n width: width,\n height: height\n };\n }\n\n if (isNumber(top) && isNumber(left)) {\n return {\n x: top,\n y: left,\n width: width,\n height: height\n };\n }\n }\n\n if (isNumber(x) && isNumber(y)) {\n return {\n x: x,\n y: y,\n width: 0,\n height: 0\n };\n }\n\n if (isNumber(cx) && isNumber(cy)) {\n return {\n cx: cx,\n cy: cy,\n startAngle: startAngle || angle || 0,\n endAngle: endAngle || angle || 0,\n innerRadius: innerRadius || 0,\n outerRadius: outerRadius || radius || r || 0,\n clockWise: clockWise\n };\n }\n\n if (props.viewBox) {\n return props.viewBox;\n }\n\n return {};\n};\n\nvar parseLabel = function parseLabel(label, viewBox) {\n if (!label) {\n return null;\n }\n\n if (label === true) {\n return React.createElement(Label, {\n key: \"label-implicit\",\n viewBox: viewBox\n });\n }\n\n if (isNumOrStr(label)) {\n return React.createElement(Label, {\n key: \"label-implicit\",\n viewBox: viewBox,\n value: label\n });\n }\n\n if (isValidElement(label) || _isFunction(label)) {\n return React.createElement(Label, {\n key: \"label-implicit\",\n content: label,\n viewBox: viewBox\n });\n }\n\n if (_isObject(label)) {\n return React.createElement(Label, _extends({\n viewBox: viewBox\n }, label, {\n key: \"label-implicit\"\n }));\n }\n\n return null;\n};\n\nvar renderCallByParent = function renderCallByParent(parentProps, viewBox) {\n var ckeckPropsLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n if (!parentProps || !parentProps.children && ckeckPropsLabel && !parentProps.label) {\n return null;\n }\n\n var children = parentProps.children;\n var parentViewBox = parseViewBox(parentProps);\n var explicitChilren = findAllByType(children, Label).map(function (child, index) {\n return cloneElement(child, {\n viewBox: viewBox || parentViewBox,\n key: \"label-\".concat(index)\n });\n });\n\n if (!ckeckPropsLabel) {\n return explicitChilren;\n }\n\n var implicitLabel = parseLabel(parentProps.label, viewBox || parentViewBox);\n return [implicitLabel].concat(_toConsumableArray(explicitChilren));\n};\n\nLabel.parseViewBox = parseViewBox;\nLabel.renderCallByParent = renderCallByParent;\nexport default Label;", + "import _isObject from \"lodash/isObject\";\nimport _isFunction from \"lodash/isFunction\";\nimport _isNil from \"lodash/isNil\";\nimport _last from \"lodash/last\";\nimport _isArray from \"lodash/isArray\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React, { cloneElement } from 'react';\nimport PropTypes from 'prop-types';\nimport Label from './Label';\nimport Layer from '../container/Layer';\nimport { getPresentationAttributes, findAllByType } from '../util/ReactUtils';\nimport { getValueByDataKey } from '../util/ChartUtils';\nvar propTypes = {\n id: PropTypes.string,\n data: PropTypes.arrayOf(PropTypes.object),\n valueAccessor: PropTypes.func,\n clockWise: PropTypes.bool,\n dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func])\n};\nvar defaultProps = {\n valueAccessor: function valueAccessor(entry) {\n return _isArray(entry.value) ? _last(entry.value) : entry.value;\n }\n};\n\nfunction LabelList(props) {\n var data = props.data,\n valueAccessor = props.valueAccessor,\n dataKey = props.dataKey,\n clockWise = props.clockWise,\n id = props.id,\n others = _objectWithoutProperties(props, [\"data\", \"valueAccessor\", \"dataKey\", \"clockWise\", \"id\"]);\n\n if (!data || !data.length) {\n return null;\n }\n\n return React.createElement(Layer, {\n className: \"recharts-label-list\"\n }, data.map(function (entry, index) {\n var value = _isNil(dataKey) ? valueAccessor(entry, index) : getValueByDataKey(entry && entry.payload, dataKey);\n var idProps = _isNil(id) ? {} : {\n id: \"\".concat(id, \"-\").concat(index)\n };\n return React.createElement(Label, _extends({}, getPresentationAttributes(entry), others, idProps, {\n index: index,\n value: value,\n viewBox: Label.parseViewBox(_isNil(clockWise) ? entry : _objectSpread({}, entry, {\n clockWise: clockWise\n })),\n key: \"label-\".concat(index)\n }));\n }));\n}\n\nLabelList.propTypes = propTypes;\nLabelList.displayName = 'LabelList';\n\nvar parseLabelList = function parseLabelList(label, data) {\n if (!label) {\n return null;\n }\n\n if (label === true) {\n return React.createElement(LabelList, {\n key: \"labelList-implicit\",\n data: data\n });\n }\n\n if (React.isValidElement(label) || _isFunction(label)) {\n return React.createElement(LabelList, {\n key: \"labelList-implicit\",\n data: data,\n content: label\n });\n }\n\n if (_isObject(label)) {\n return React.createElement(LabelList, _extends({\n data: data\n }, label, {\n key: \"labelList-implicit\"\n }));\n }\n\n return null;\n};\n\nvar renderCallByParent = function renderCallByParent(parentProps, data) {\n var ckeckPropsLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n if (!parentProps || !parentProps.children && ckeckPropsLabel && !parentProps.label) {\n return null;\n }\n\n var children = parentProps.children;\n var explicitChilren = findAllByType(children, LabelList).map(function (child, index) {\n return cloneElement(child, {\n data: data,\n key: \"labelList-\".concat(index)\n });\n });\n\n if (!ckeckPropsLabel) {\n return explicitChilren;\n }\n\n var implicitLabelList = parseLabelList(parentProps.label, data);\n return [implicitLabelList].concat(_toConsumableArray(explicitChilren));\n};\n\nLabelList.renderCallByParent = renderCallByParent;\nLabelList.defaultProps = defaultProps;\nexport default LabelList;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Default Legend Content\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport Surface from '../container/Surface';\nimport Symbols from '../shape/Symbols';\nimport { filterEventsOfChild, LEGEND_TYPES } from '../util/ReactUtils';\nvar SIZE = 32;\nvar ICON_TYPES = LEGEND_TYPES.filter(function (type) {\n return type !== 'none';\n});\n\nvar DefaultLegendContent = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(DefaultLegendContent, _Component);\n\n function DefaultLegendContent() {\n _classCallCheck(this, DefaultLegendContent);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(DefaultLegendContent).apply(this, arguments));\n }\n\n _createClass(DefaultLegendContent, [{\n key: \"renderIcon\",\n\n /**\n * Render the path of icon\n * @param {Object} data Data of each legend item\n * @return {String} Path element\n */\n value: function renderIcon(data) {\n var inactiveColor = this.props.inactiveColor;\n var halfSize = SIZE / 2;\n var sixthSize = SIZE / 6;\n var thirdSize = SIZE / 3;\n var color = data.inactive ? inactiveColor : data.color;\n\n if (data.type === 'plainline') {\n return React.createElement(\"line\", {\n strokeWidth: 4,\n fill: \"none\",\n stroke: color,\n strokeDasharray: data.payload.strokeDasharray,\n x1: 0,\n y1: halfSize,\n x2: SIZE,\n y2: halfSize,\n className: \"recharts-legend-icon\"\n });\n }\n\n if (data.type === 'line') {\n return React.createElement(\"path\", {\n strokeWidth: 4,\n fill: \"none\",\n stroke: color,\n d: \"M0,\".concat(halfSize, \"h\").concat(thirdSize, \"\\n A\").concat(sixthSize, \",\").concat(sixthSize, \",0,1,1,\").concat(2 * thirdSize, \",\").concat(halfSize, \"\\n H\").concat(SIZE, \"M\").concat(2 * thirdSize, \",\").concat(halfSize, \"\\n A\").concat(sixthSize, \",\").concat(sixthSize, \",0,1,1,\").concat(thirdSize, \",\").concat(halfSize),\n className: \"recharts-legend-icon\"\n });\n }\n\n if (data.type === 'rect') {\n return React.createElement(\"path\", {\n stroke: \"none\",\n fill: color,\n d: \"M0,\".concat(SIZE / 8, \"h\").concat(SIZE, \"v\").concat(SIZE * 3 / 4, \"h\").concat(-SIZE, \"z\"),\n className: \"recharts-legend-icon\"\n });\n }\n\n return React.createElement(Symbols, {\n fill: color,\n cx: halfSize,\n cy: halfSize,\n size: SIZE,\n sizeType: \"diameter\",\n type: data.type\n });\n }\n /**\n * Draw items of legend\n * @return {ReactElement} Items\n */\n\n }, {\n key: \"renderItems\",\n value: function renderItems() {\n var _this = this;\n\n var _this$props = this.props,\n payload = _this$props.payload,\n iconSize = _this$props.iconSize,\n layout = _this$props.layout,\n formatter = _this$props.formatter;\n var viewBox = {\n x: 0,\n y: 0,\n width: SIZE,\n height: SIZE\n };\n var itemStyle = {\n display: layout === 'horizontal' ? 'inline-block' : 'block',\n marginRight: 10\n };\n var svgStyle = {\n display: 'inline-block',\n verticalAlign: 'middle',\n marginRight: 4\n };\n return payload.map(function (entry, i) {\n var _classNames;\n\n var finalFormatter = entry.formatter || formatter;\n var className = classNames((_classNames = {\n 'recharts-legend-item': true\n }, _defineProperty(_classNames, \"legend-item-\".concat(i), true), _defineProperty(_classNames, \"inactive\", entry.inactive), _classNames));\n\n if (entry.type === 'none') {\n return null;\n }\n\n return React.createElement(\"li\", _extends({\n className: className,\n style: itemStyle,\n key: \"legend-item-\".concat(i)\n }, filterEventsOfChild(_this.props, entry, i)), React.createElement(Surface, {\n width: iconSize,\n height: iconSize,\n viewBox: viewBox,\n style: svgStyle\n }, _this.renderIcon(entry)), React.createElement(\"span\", {\n className: \"recharts-legend-item-text\"\n }, finalFormatter ? finalFormatter(entry.value, entry, i) : entry.value));\n });\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n payload = _this$props2.payload,\n layout = _this$props2.layout,\n align = _this$props2.align;\n\n if (!payload || !payload.length) {\n return null;\n }\n\n var finalStyle = {\n padding: 0,\n margin: 0,\n textAlign: layout === 'horizontal' ? align : 'left'\n };\n return React.createElement(\"ul\", {\n className: \"recharts-default-legend\",\n style: finalStyle\n }, this.renderItems());\n }\n }]);\n\n return DefaultLegendContent;\n}(Component), _class2.displayName = 'Legend', _class2.propTypes = {\n content: PropTypes.element,\n iconSize: PropTypes.number,\n iconType: PropTypes.oneOf(ICON_TYPES),\n layout: PropTypes.oneOf(['horizontal', 'vertical']),\n align: PropTypes.oneOf(['center', 'left', 'right']),\n verticalAlign: PropTypes.oneOf(['top', 'bottom', 'middle']),\n payload: PropTypes.arrayOf(PropTypes.shape({\n value: PropTypes.any,\n id: PropTypes.any,\n type: PropTypes.oneOf(LEGEND_TYPES)\n })),\n inactiveColor: PropTypes.string,\n formatter: PropTypes.func,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onClick: PropTypes.func\n}, _class2.defaultProps = {\n iconSize: 14,\n layout: 'horizontal',\n align: 'center',\n verticalAlign: 'middle',\n inactiveColor: '#ccc'\n}, _temp)) || _class;\n\nexport default DefaultLegendContent;", + "import _isFunction from \"lodash/isFunction\";\nimport _uniqBy from \"lodash/uniqBy\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Legend\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport pureRender from '../util/PureRender';\nimport DefaultLegendContent from './DefaultLegendContent';\nimport { isNumber } from '../util/DataUtils';\nimport { LEGEND_TYPES } from '../util/ReactUtils';\n\nvar defaultUniqBy = function defaultUniqBy(entry) {\n return entry.value;\n};\n\nvar getUniqPaylod = function getUniqPaylod(option, payload) {\n if (option === true) {\n return _uniqBy(payload, defaultUniqBy);\n }\n\n if (_isFunction(option)) {\n return _uniqBy(payload, option);\n }\n\n return payload;\n};\n\nvar renderContent = function renderContent(content, props) {\n if (React.isValidElement(content)) {\n return React.cloneElement(content, props);\n }\n\n if (_isFunction(content)) {\n return content(props);\n }\n\n return React.createElement(DefaultLegendContent, props);\n};\n\nvar EPS = 1;\nvar ICON_TYPES = LEGEND_TYPES.filter(function (type) {\n return type !== 'none';\n});\n\nvar Legend = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Legend, _Component);\n\n function Legend() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, Legend);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Legend)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n boxWidth: -1,\n boxHeight: -1\n };\n return _this;\n }\n\n _createClass(Legend, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.updateBBox();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n this.updateBBox();\n }\n }, {\n key: \"getBBox\",\n value: function getBBox() {\n var _this$state = this.state,\n boxWidth = _this$state.boxWidth,\n boxHeight = _this$state.boxHeight;\n\n if (boxWidth >= 0 && boxHeight >= 0) {\n return {\n width: boxWidth,\n height: boxHeight\n };\n }\n\n return null;\n }\n }, {\n key: \"getDefaultPosition\",\n value: function getDefaultPosition(style) {\n var _this$props = this.props,\n layout = _this$props.layout,\n align = _this$props.align,\n verticalAlign = _this$props.verticalAlign,\n margin = _this$props.margin,\n chartWidth = _this$props.chartWidth,\n chartHeight = _this$props.chartHeight;\n var hPos, vPos;\n\n if (!style || (style.left === undefined || style.left === null) && (style.right === undefined || style.right === null)) {\n if (align === 'center' && layout === 'vertical') {\n var box = this.getBBox() || {\n width: 0\n };\n hPos = {\n left: ((chartWidth || 0) - box.width) / 2\n };\n } else {\n hPos = align === 'right' ? {\n right: margin && margin.right || 0\n } : {\n left: margin && margin.left || 0\n };\n }\n }\n\n if (!style || (style.top === undefined || style.top === null) && (style.bottom === undefined || style.bottom === null)) {\n if (verticalAlign === 'middle') {\n var _box = this.getBBox() || {\n height: 0\n };\n\n vPos = {\n top: ((chartHeight || 0) - _box.height) / 2\n };\n } else {\n vPos = verticalAlign === 'bottom' ? {\n bottom: margin && margin.bottom || 0\n } : {\n top: margin && margin.top || 0\n };\n }\n }\n\n return _objectSpread({}, hPos, vPos);\n }\n }, {\n key: \"updateBBox\",\n value: function updateBBox() {\n var _this$state2 = this.state,\n boxWidth = _this$state2.boxWidth,\n boxHeight = _this$state2.boxHeight;\n var onBBoxUpdate = this.props.onBBoxUpdate;\n\n if (this.wrapperNode && this.wrapperNode.getBoundingClientRect) {\n var box = this.wrapperNode.getBoundingClientRect();\n\n if (Math.abs(box.width - boxWidth) > EPS || Math.abs(box.height - boxHeight) > EPS) {\n this.setState({\n boxWidth: box.width,\n boxHeight: box.height\n }, function () {\n if (onBBoxUpdate) {\n onBBoxUpdate(box);\n }\n });\n }\n } else if (boxWidth !== -1 || boxHeight !== -1) {\n this.setState({\n boxWidth: -1,\n boxHeight: -1\n }, function () {\n if (onBBoxUpdate) {\n onBBoxUpdate(null);\n }\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props2 = this.props,\n content = _this$props2.content,\n width = _this$props2.width,\n height = _this$props2.height,\n wrapperStyle = _this$props2.wrapperStyle,\n paylodUniqBy = _this$props2.paylodUniqBy,\n payload = _this$props2.payload;\n\n var outerStyle = _objectSpread({\n position: 'absolute',\n width: width || 'auto',\n height: height || 'auto'\n }, this.getDefaultPosition(wrapperStyle), wrapperStyle);\n\n return React.createElement(\"div\", {\n className: \"recharts-legend-wrapper\",\n style: outerStyle,\n ref: function ref(node) {\n _this2.wrapperNode = node;\n }\n }, renderContent(content, _objectSpread({}, this.props, {\n payload: getUniqPaylod(paylodUniqBy, payload)\n })));\n }\n }], [{\n key: \"getWithHeight\",\n value: function getWithHeight(item, chartWidth) {\n var layout = item.props.layout;\n\n if (layout === 'vertical' && isNumber(item.props.height)) {\n return {\n height: item.props.height\n };\n }\n\n if (layout === 'horizontal') {\n return {\n width: item.props.width || chartWidth\n };\n }\n\n return null;\n }\n }]);\n\n return Legend;\n}(Component), _class2.displayName = 'Legend', _class2.propTypes = {\n content: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),\n wrapperStyle: PropTypes.object,\n chartWidth: PropTypes.number,\n chartHeight: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number,\n iconSize: PropTypes.number,\n iconType: PropTypes.oneOf(ICON_TYPES),\n layout: PropTypes.oneOf(['horizontal', 'vertical']),\n align: PropTypes.oneOf(['center', 'left', 'right']),\n verticalAlign: PropTypes.oneOf(['top', 'bottom', 'middle']),\n margin: PropTypes.shape({\n top: PropTypes.number,\n left: PropTypes.number,\n bottom: PropTypes.number,\n right: PropTypes.number\n }),\n payload: PropTypes.arrayOf(PropTypes.shape({\n value: PropTypes.any,\n id: PropTypes.any,\n type: PropTypes.oneOf(LEGEND_TYPES)\n })),\n paylodUniqBy: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),\n formatter: PropTypes.func,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onClick: PropTypes.func,\n onBBoxUpdate: PropTypes.func\n}, _class2.defaultProps = {\n iconSize: 14,\n layout: 'horizontal',\n align: 'center',\n verticalAlign: 'bottom'\n}, _temp)) || _class;\n\nexport default Legend;", + "import _debounce from \"lodash/debounce\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Wrapper component to make charts adapt to the size of parent * DOM\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport ReactResizeDetector from 'react-resize-detector';\nimport { isPercent } from '../util/DataUtils';\nimport { warn } from '../util/LogUtils';\n\nvar ResponsiveContainer =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(ResponsiveContainer, _Component);\n\n function ResponsiveContainer(props) {\n var _this;\n\n _classCallCheck(this, ResponsiveContainer);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(ResponsiveContainer).call(this, props));\n\n _this.updateDimensionsImmediate = function () {\n if (!_this.mounted) {\n return;\n }\n\n var newSize = _this.getContainerSize();\n\n if (newSize) {\n var _this$state = _this.state,\n oldWidth = _this$state.containerWidth,\n oldHeight = _this$state.containerHeight;\n var containerWidth = newSize.containerWidth,\n containerHeight = newSize.containerHeight;\n\n if (containerWidth !== oldWidth || containerHeight !== oldHeight) {\n _this.setState({\n containerWidth: containerWidth,\n containerHeight: containerHeight\n });\n }\n }\n };\n\n _this.state = {\n containerWidth: -1,\n containerHeight: -1\n };\n _this.handleResize = props.debounce > 0 ? _debounce(_this.updateDimensionsImmediate, props.debounce) : _this.updateDimensionsImmediate;\n return _this;\n }\n /* eslint-disable react/no-did-mount-set-state */\n\n\n _createClass(ResponsiveContainer, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.mounted = true;\n var size = this.getContainerSize();\n\n if (size) {\n this.setState(size);\n }\n }\n }, {\n key: \"componentWillUnmount\",\n value: function componentWillUnmount() {\n this.mounted = false;\n }\n }, {\n key: \"getContainerSize\",\n value: function getContainerSize() {\n if (!this.container) {\n return null;\n }\n\n return {\n containerWidth: this.container.clientWidth,\n containerHeight: this.container.clientHeight\n };\n }\n }, {\n key: \"renderChart\",\n value: function renderChart() {\n var _this$state2 = this.state,\n containerWidth = _this$state2.containerWidth,\n containerHeight = _this$state2.containerHeight;\n\n if (containerWidth < 0 || containerHeight < 0) {\n return null;\n }\n\n var _this$props = this.props,\n aspect = _this$props.aspect,\n width = _this$props.width,\n height = _this$props.height,\n minWidth = _this$props.minWidth,\n minHeight = _this$props.minHeight,\n maxHeight = _this$props.maxHeight,\n children = _this$props.children;\n warn(isPercent(width) || isPercent(height), \"The width(%s) and height(%s) are both fixed numbers,\\n maybe you don't need to use a ResponsiveContainer.\", width, height);\n warn(!aspect || aspect > 0, 'The aspect(%s) must be greater than zero.', aspect);\n var calculatedWidth = isPercent(width) ? containerWidth : width;\n var calculatedHeight = isPercent(height) ? containerHeight : height;\n\n if (aspect && aspect > 0) {\n // Preserve the desired aspect ratio\n calculatedHeight = calculatedWidth / aspect; // if maxHeight is set, overwrite if calculatedHeight is greater than maxHeight\n\n if (maxHeight && calculatedHeight > maxHeight) {\n calculatedHeight = maxHeight;\n }\n }\n\n warn(calculatedWidth > 0 || calculatedHeight > 0, \"The width(%s) and height(%s) of chart should be greater than 0,\\n please check the style of container, or the props width(%s) and height(%s),\\n or add a minWidth(%s) or minHeight(%s) or use aspect(%s) to control the\\n height and width.\", calculatedWidth, calculatedHeight, width, height, minWidth, minHeight, aspect);\n return React.cloneElement(children, {\n width: calculatedWidth,\n height: calculatedHeight\n });\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props2 = this.props,\n minWidth = _this$props2.minWidth,\n minHeight = _this$props2.minHeight,\n width = _this$props2.width,\n height = _this$props2.height,\n maxHeight = _this$props2.maxHeight,\n id = _this$props2.id,\n className = _this$props2.className;\n var style = {\n width: width,\n height: height,\n minWidth: minWidth,\n minHeight: minHeight,\n maxHeight: maxHeight\n };\n return React.createElement(\"div\", {\n id: id,\n className: classNames('recharts-responsive-container', className),\n style: style,\n ref: function ref(node) {\n _this2.container = node;\n }\n }, this.renderChart(), React.createElement(ReactResizeDetector, {\n handleWidth: true,\n handleHeight: true,\n onResize: this.handleResize\n }));\n }\n }]);\n\n return ResponsiveContainer;\n}(Component);\n\nResponsiveContainer.displayName = 'ResponsiveContainer';\nResponsiveContainer.propTypes = {\n aspect: PropTypes.number,\n width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n minHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n children: PropTypes.node.isRequired,\n debounce: PropTypes.number,\n id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n className: PropTypes.oneOfType([PropTypes.string, PropTypes.number])\n};\nResponsiveContainer.defaultProps = {\n width: '100%',\n height: '100%',\n debounce: 0\n};\nexport default ResponsiveContainer;", + "import _isNil from \"lodash/isNil\";\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport reduceCSSCalc from 'reduce-css-calc';\nimport classNames from 'classnames';\nimport { isNumber, isNumOrStr } from '../util/DataUtils';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, isSsr } from '../util/ReactUtils';\nimport { getStringSize } from '../util/DOMUtils';\nvar BREAKING_SPACES = /[ \\f\\n\\r\\t\\v\\u2028\\u2029]+/;\n\nvar calculateWordWidths = function calculateWordWidths(props) {\n try {\n var words = !_isNil(props.children) ? props.children.toString().split(BREAKING_SPACES) : [];\n var wordsWithComputedWidth = words.map(function (word) {\n return {\n word: word,\n width: getStringSize(word, props.style).width\n };\n });\n var spaceWidth = getStringSize(\"\\xA0\", props.style).width;\n return {\n wordsWithComputedWidth: wordsWithComputedWidth,\n spaceWidth: spaceWidth\n };\n } catch (e) {\n return null;\n }\n};\n\nvar Text =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Text, _Component);\n\n function Text() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, Text);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Text)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n wordsByLines: []\n };\n return _this;\n }\n\n _createClass(Text, [{\n key: \"componentWillMount\",\n value: function componentWillMount() {\n this.updateWordsByLines(this.props, true);\n }\n }, {\n key: \"componentWillReceiveProps\",\n value: function componentWillReceiveProps(nextProps) {\n var needCalculate = this.props.children !== nextProps.children || this.props.style !== nextProps.style;\n this.updateWordsByLines(nextProps, needCalculate);\n }\n }, {\n key: \"updateWordsByLines\",\n value: function updateWordsByLines(props, needCalculate) {\n // Only perform calculations if using features that require them (multiline, scaleToFit)\n if ((props.width || props.scaleToFit) && !isSsr()) {\n if (needCalculate) {\n var wordWidths = calculateWordWidths(props);\n\n if (wordWidths) {\n var wordsWithComputedWidth = wordWidths.wordsWithComputedWidth,\n spaceWidth = wordWidths.spaceWidth;\n this.wordsWithComputedWidth = wordsWithComputedWidth;\n this.spaceWidth = spaceWidth;\n } else {\n this.updateWordsWithoutCalculate(props);\n return;\n }\n }\n\n var wordsByLines = this.calculateWordsByLines(this.wordsWithComputedWidth, this.spaceWidth, props.width);\n this.setState({\n wordsByLines: wordsByLines\n });\n } else {\n this.updateWordsWithoutCalculate(props);\n }\n }\n }, {\n key: \"updateWordsWithoutCalculate\",\n value: function updateWordsWithoutCalculate(props) {\n var words = !_isNil(props.children) ? props.children.toString().split(BREAKING_SPACES) : [];\n this.setState({\n wordsByLines: [{\n words: words\n }]\n });\n }\n }, {\n key: \"calculateWordsByLines\",\n value: function calculateWordsByLines(wordsWithComputedWidth, spaceWidth, lineWidth) {\n var scaleToFit = this.props.scaleToFit;\n return wordsWithComputedWidth.reduce(function (result, _ref) {\n var word = _ref.word,\n width = _ref.width;\n var currentLine = result[result.length - 1];\n\n if (currentLine && (lineWidth == null || scaleToFit || currentLine.width + width + spaceWidth < lineWidth)) {\n // Word can be added to an existing line\n currentLine.words.push(word);\n currentLine.width += width + spaceWidth;\n } else {\n // Add first word to line or word is too long to scaleToFit on existing line\n var newLine = {\n words: [word],\n width: width\n };\n result.push(newLine);\n }\n\n return result;\n }, []);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n dx = _this$props.dx,\n dy = _this$props.dy,\n textAnchor = _this$props.textAnchor,\n verticalAnchor = _this$props.verticalAnchor,\n scaleToFit = _this$props.scaleToFit,\n angle = _this$props.angle,\n lineHeight = _this$props.lineHeight,\n capHeight = _this$props.capHeight,\n className = _this$props.className,\n textProps = _objectWithoutProperties(_this$props, [\"dx\", \"dy\", \"textAnchor\", \"verticalAnchor\", \"scaleToFit\", \"angle\", \"lineHeight\", \"capHeight\", \"className\"]);\n\n var wordsByLines = this.state.wordsByLines;\n\n if (!isNumOrStr(textProps.x) || !isNumOrStr(textProps.y)) {\n return null;\n }\n\n var x = textProps.x + (isNumber(dx) ? dx : 0);\n var y = textProps.y + (isNumber(dy) ? dy : 0);\n var startDy;\n\n switch (verticalAnchor) {\n case 'start':\n startDy = reduceCSSCalc(\"calc(\".concat(capHeight, \")\"));\n break;\n\n case 'middle':\n startDy = reduceCSSCalc(\"calc(\".concat((wordsByLines.length - 1) / 2, \" * -\").concat(lineHeight, \" + (\").concat(capHeight, \" / 2))\"));\n break;\n\n default:\n startDy = reduceCSSCalc(\"calc(\".concat(wordsByLines.length - 1, \" * -\").concat(lineHeight, \")\"));\n break;\n }\n\n var transforms = [];\n\n if (scaleToFit) {\n var lineWidth = wordsByLines[0].width;\n transforms.push(\"scale(\".concat(this.props.width / lineWidth, \")\"));\n }\n\n if (angle) {\n transforms.push(\"rotate(\".concat(angle, \", \").concat(x, \", \").concat(y, \")\"));\n }\n\n if (transforms.length) {\n textProps.transform = transforms.join(' ');\n }\n\n return React.createElement(\"text\", _extends({}, getPresentationAttributes(textProps), {\n x: x,\n y: y,\n className: classNames('recharts-text', className),\n textAnchor: textAnchor\n }), wordsByLines.map(function (line, index) {\n return React.createElement(\"tspan\", {\n x: x,\n dy: index === 0 ? startDy : lineHeight,\n key: index\n }, line.words.join(' '));\n }));\n }\n }]);\n\n return Text;\n}(Component);\n\nText.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n scaleToFit: PropTypes.bool,\n angle: PropTypes.number,\n textAnchor: PropTypes.oneOf(['start', 'middle', 'end', 'inherit']),\n verticalAnchor: PropTypes.oneOf(['start', 'middle', 'end']),\n style: PropTypes.object\n});\nText.defaultProps = {\n x: 0,\n y: 0,\n lineHeight: '1em',\n capHeight: '0.71em',\n // Magic number from d3\n scaleToFit: false,\n textAnchor: 'start',\n verticalAnchor: 'end' // Maintain compat with existing charts / default SVG behavior\n\n};\nexport default Text;", + "import _isArray from \"lodash/isArray\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { isNumOrStr } from '../util/DataUtils';\n\nvar defaultFormatter = function defaultFormatter(value) {\n return _isArray(value) && isNumOrStr(value[0]) && isNumOrStr(value[1]) ? value.join(' ~ ') : value;\n};\n\nvar DefaultTooltipContent = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(DefaultTooltipContent, _Component);\n\n function DefaultTooltipContent() {\n _classCallCheck(this, DefaultTooltipContent);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(DefaultTooltipContent).apply(this, arguments));\n }\n\n _createClass(DefaultTooltipContent, [{\n key: \"renderContent\",\n value: function renderContent() {\n var _this$props = this.props,\n payload = _this$props.payload,\n separator = _this$props.separator,\n formatter = _this$props.formatter,\n itemStyle = _this$props.itemStyle,\n itemSorter = _this$props.itemSorter;\n\n if (payload && payload.length) {\n var listStyle = {\n padding: 0,\n margin: 0\n };\n var items = payload.sort(itemSorter).map(function (entry, i) {\n var finalItemStyle = _objectSpread({\n display: 'block',\n paddingTop: 4,\n paddingBottom: 4,\n color: entry.color || '#000'\n }, itemStyle);\n\n var finalFormatter = entry.formatter || formatter || defaultFormatter;\n var name = entry.name,\n value = entry.value;\n\n if (finalFormatter) {\n var formatted = finalFormatter(value, name, entry, i);\n\n if (Array.isArray(formatted)) {\n var _formatted = _slicedToArray(formatted, 2);\n\n value = _formatted[0];\n name = _formatted[1];\n } else {\n value = formatted;\n }\n }\n\n return React.createElement(\"li\", {\n className: \"recharts-tooltip-item\",\n key: \"tooltip-item-\".concat(i),\n style: finalItemStyle\n }, isNumOrStr(name) ? React.createElement(\"span\", {\n className: \"recharts-tooltip-item-name\"\n }, name) : null, isNumOrStr(name) ? React.createElement(\"span\", {\n className: \"recharts-tooltip-item-separator\"\n }, separator) : null, React.createElement(\"span\", {\n className: \"recharts-tooltip-item-value\"\n }, value), React.createElement(\"span\", {\n className: \"recharts-tooltip-item-unit\"\n }, entry.unit || ''));\n });\n return React.createElement(\"ul\", {\n className: \"recharts-tooltip-item-list\",\n style: listStyle\n }, items);\n }\n\n return null;\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n wrapperClassName = _this$props2.wrapperClassName,\n contentStyle = _this$props2.contentStyle,\n labelClassName = _this$props2.labelClassName,\n labelStyle = _this$props2.labelStyle,\n label = _this$props2.label,\n labelFormatter = _this$props2.labelFormatter;\n\n var finalStyle = _objectSpread({\n margin: 0,\n padding: 10,\n backgroundColor: '#fff',\n border: '1px solid #ccc',\n whiteSpace: 'nowrap'\n }, contentStyle);\n\n var finalLabelStyle = _objectSpread({\n margin: 0\n }, labelStyle);\n\n var hasLabel = isNumOrStr(label);\n var finalLabel = hasLabel ? label : '';\n var wrapperCN = classNames('recharts-default-tooltip', wrapperClassName);\n var labelCN = classNames('recharts-tooltip-label', labelClassName);\n\n if (hasLabel && labelFormatter) {\n finalLabel = labelFormatter(label);\n }\n\n return React.createElement(\"div\", {\n className: wrapperCN,\n style: finalStyle\n }, React.createElement(\"p\", {\n className: labelCN,\n style: finalLabelStyle\n }, finalLabel), this.renderContent());\n }\n }]);\n\n return DefaultTooltipContent;\n}(Component), _class2.displayName = 'DefaultTooltipContent', _class2.propTypes = {\n separator: PropTypes.string,\n wrapperClassName: PropTypes.string,\n labelClassName: PropTypes.string,\n formatter: PropTypes.func,\n contentStyle: PropTypes.object,\n itemStyle: PropTypes.object,\n labelStyle: PropTypes.object,\n labelFormatter: PropTypes.func,\n label: PropTypes.any,\n payload: PropTypes.arrayOf(PropTypes.shape({\n name: PropTypes.any,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.array]),\n unit: PropTypes.any\n })),\n itemSorter: PropTypes.func\n}, _class2.defaultProps = {\n separator: ' : ',\n contentStyle: {},\n itemStyle: {},\n labelStyle: {}\n}, _temp)) || _class;\n\nexport default DefaultTooltipContent;", + "import _isNil from \"lodash/isNil\";\nimport _isFunction from \"lodash/isFunction\";\nimport _uniqBy from \"lodash/uniqBy\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Tooltip\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { translateStyle } from 'react-smooth';\nimport classNames from 'classnames';\nimport DefaultTooltipContent from './DefaultTooltipContent';\nimport { isSsr } from '../util/ReactUtils';\nimport { isNumber } from '../util/DataUtils';\nimport pureRender from '../util/PureRender';\nvar CLS_PREFIX = 'recharts-tooltip-wrapper';\nvar EPS = 1;\n\nvar defaultUniqBy = function defaultUniqBy(entry) {\n return entry.dataKey;\n};\n\nvar getUniqPaylod = function getUniqPaylod(option, payload) {\n if (option === true) {\n return _uniqBy(payload, defaultUniqBy);\n }\n\n if (_isFunction(option)) {\n return _uniqBy(payload, option);\n }\n\n return payload;\n};\n\nvar propTypes = {\n content: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),\n viewBox: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n }),\n active: PropTypes.bool,\n separator: PropTypes.string,\n formatter: PropTypes.func,\n offset: PropTypes.number,\n itemStyle: PropTypes.object,\n labelStyle: PropTypes.object,\n wrapperStyle: PropTypes.object,\n contentStyle: PropTypes.object,\n cursor: PropTypes.oneOfType([PropTypes.bool, PropTypes.element, PropTypes.object]),\n coordinate: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number\n }),\n position: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number\n }),\n label: PropTypes.any,\n payload: PropTypes.arrayOf(PropTypes.shape({\n name: PropTypes.any,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.array]),\n unit: PropTypes.any\n })),\n paylodUniqBy: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),\n isAnimationActive: PropTypes.bool,\n animationDuration: PropTypes.number,\n animationEasing: PropTypes.oneOf(['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear']),\n itemSorter: PropTypes.func,\n filterNull: PropTypes.bool,\n useTranslate3d: PropTypes.bool\n};\nvar defaultProps = {\n active: false,\n offset: 10,\n viewBox: {\n x1: 0,\n x2: 0,\n y1: 0,\n y2: 0\n },\n coordinate: {\n x: 0,\n y: 0\n },\n cursorStyle: {},\n separator: ' : ',\n wrapperStyle: {},\n contentStyle: {},\n itemStyle: {},\n labelStyle: {},\n cursor: true,\n isAnimationActive: !isSsr(),\n animationEasing: 'ease',\n animationDuration: 400,\n itemSorter: function itemSorter() {\n return -1;\n },\n filterNull: true,\n useTranslate3d: false\n};\n\nvar renderContent = function renderContent(content, props) {\n if (React.isValidElement(content)) {\n return React.cloneElement(content, props);\n }\n\n if (_isFunction(content)) {\n return content(props);\n }\n\n return React.createElement(DefaultTooltipContent, props);\n};\n\nvar Tooltip = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Tooltip, _Component);\n\n function Tooltip() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, Tooltip);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Tooltip)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n boxWidth: -1,\n boxHeight: -1\n };\n return _this;\n }\n\n _createClass(Tooltip, [{\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.updateBBox();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n this.updateBBox();\n }\n }, {\n key: \"updateBBox\",\n value: function updateBBox() {\n var _this$state = this.state,\n boxWidth = _this$state.boxWidth,\n boxHeight = _this$state.boxHeight;\n\n if (this.wrapperNode && this.wrapperNode.getBoundingClientRect) {\n var box = this.wrapperNode.getBoundingClientRect();\n\n if (Math.abs(box.width - boxWidth) > EPS || Math.abs(box.height - boxHeight) > EPS) {\n this.setState({\n boxWidth: box.width,\n boxHeight: box.height\n });\n }\n } else if (boxWidth !== -1 || boxHeight !== -1) {\n this.setState({\n boxWidth: -1,\n boxHeight: -1\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _classNames,\n _this2 = this;\n\n var _this$props = this.props,\n payload = _this$props.payload,\n isAnimationActive = _this$props.isAnimationActive,\n animationDuration = _this$props.animationDuration,\n animationEasing = _this$props.animationEasing,\n filterNull = _this$props.filterNull,\n paylodUniqBy = _this$props.paylodUniqBy;\n var finalPayload = getUniqPaylod(paylodUniqBy, filterNull && payload && payload.length ? payload.filter(function (entry) {\n return !_isNil(entry.value);\n }) : payload);\n var hasPayload = finalPayload && finalPayload.length;\n var _this$props2 = this.props,\n content = _this$props2.content,\n viewBox = _this$props2.viewBox,\n coordinate = _this$props2.coordinate,\n position = _this$props2.position,\n active = _this$props2.active,\n offset = _this$props2.offset,\n wrapperStyle = _this$props2.wrapperStyle;\n\n var outerStyle = _objectSpread({\n pointerEvents: 'none',\n visibility: active && hasPayload ? 'visible' : 'hidden',\n position: 'absolute',\n top: 0\n }, wrapperStyle);\n\n var translateX, translateY;\n\n if (position && isNumber(position.x) && isNumber(position.y)) {\n translateX = position.x;\n translateY = position.y;\n } else {\n var _this$state2 = this.state,\n boxWidth = _this$state2.boxWidth,\n boxHeight = _this$state2.boxHeight;\n\n if (boxWidth > 0 && boxHeight > 0 && coordinate) {\n translateX = position && isNumber(position.x) ? position.x : Math.max(coordinate.x + boxWidth + offset > viewBox.x + viewBox.width ? coordinate.x - boxWidth - offset : coordinate.x + offset, viewBox.x);\n translateY = position && isNumber(position.y) ? position.y : Math.max(coordinate.y + boxHeight + offset > viewBox.y + viewBox.height ? coordinate.y - boxHeight - offset : coordinate.y + offset, viewBox.y);\n } else {\n outerStyle.visibility = 'hidden';\n }\n }\n\n outerStyle = _objectSpread({}, outerStyle, translateStyle({\n transform: this.props.useTranslate3d ? \"translate3d(\".concat(translateX, \"px, \").concat(translateY, \"px, 0)\") : \"translate(\".concat(translateX, \"px, \").concat(translateY, \"px)\")\n }));\n\n if (isAnimationActive && active) {\n outerStyle = _objectSpread({}, outerStyle, translateStyle({\n transition: \"transform \".concat(animationDuration, \"ms \").concat(animationEasing)\n }));\n }\n\n var cls = classNames(CLS_PREFIX, (_classNames = {}, _defineProperty(_classNames, \"\".concat(CLS_PREFIX, \"-right\"), isNumber(translateX) && coordinate && isNumber(coordinate.x) && translateX >= coordinate.x), _defineProperty(_classNames, \"\".concat(CLS_PREFIX, \"-left\"), isNumber(translateX) && coordinate && isNumber(coordinate.x) && translateX < coordinate.x), _defineProperty(_classNames, \"\".concat(CLS_PREFIX, \"-bottom\"), isNumber(translateY) && coordinate && isNumber(coordinate.y) && translateY >= coordinate.y), _defineProperty(_classNames, \"\".concat(CLS_PREFIX, \"-top\"), isNumber(translateY) && coordinate && isNumber(coordinate.y) && translateY < coordinate.y), _classNames));\n return React.createElement(\"div\", {\n className: cls,\n style: outerStyle,\n ref: function ref(node) {\n _this2.wrapperNode = node;\n }\n }, renderContent(content, _objectSpread({}, this.props, {\n payload: finalPayload\n })));\n }\n }]);\n\n return Tooltip;\n}(Component), _class2.displayName = 'Tooltip', _class2.propTypes = propTypes, _class2.defaultProps = defaultProps, _temp)) || _class;\n\nexport default Tooltip;", + "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/**\n * @fileOverview Layer\n */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nvar propTypes = {\n className: PropTypes.string,\n children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])\n};\n\nfunction Layer(props) {\n var children = props.children,\n className = props.className,\n others = _objectWithoutProperties(props, [\"children\", \"className\"]);\n\n var layerClass = classNames('recharts-layer', className);\n return React.createElement(\"g\", _extends({\n className: layerClass\n }, others), children);\n}\n\nLayer.propTypes = propTypes;\nexport default Layer;", + "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/**\n * @fileOverview Surface\n */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { getPresentationAttributes } from '../util/ReactUtils';\nvar propTypes = {\n width: PropTypes.number.isRequired,\n height: PropTypes.number.isRequired,\n viewBox: PropTypes.shape({\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number\n }),\n className: PropTypes.string,\n style: PropTypes.object,\n children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])\n};\n\nfunction Surface(props) {\n var children = props.children,\n width = props.width,\n height = props.height,\n viewBox = props.viewBox,\n className = props.className,\n style = props.style,\n others = _objectWithoutProperties(props, [\"children\", \"width\", \"height\", \"viewBox\", \"className\", \"style\"]);\n\n var svgView = viewBox || {\n width: width,\n height: height,\n x: 0,\n y: 0\n };\n var layerClass = classNames('recharts-surface', className);\n var attrs = getPresentationAttributes(others);\n return React.createElement(\"svg\", _extends({}, attrs, {\n className: layerClass,\n width: width,\n height: height,\n style: style,\n viewBox: \"\".concat(svgView.x, \" \").concat(svgView.y, \" \").concat(svgView.width, \" \").concat(svgView.height),\n version: \"1.1\"\n }), children);\n}\n\nSurface.propTypes = propTypes;\nexport default Surface;", + "import 'core-js/es6/math';\nimport 'core-js/es6/number';\n/* eslint no-proto: 0 */\n\nvar testObject = {};\n\nif (!(Object.setPrototypeOf || testObject.__proto__)) {\n var nativeGetPrototypeOf = Object.getPrototypeOf;\n\n Object.getPrototypeOf = function (object) {\n if (object.__proto__) {\n return object.__proto__;\n }\n\n return nativeGetPrototypeOf.call(Object, object);\n };\n}", + "import './polyfill';\nimport _Surface from './container/Surface';\nexport { _Surface as Surface };\nimport _Layer from './container/Layer';\nexport { _Layer as Layer };\nimport _Legend from './component/Legend';\nexport { _Legend as Legend };\nimport _Tooltip from './component/Tooltip';\nexport { _Tooltip as Tooltip };\nimport _ResponsiveContainer from './component/ResponsiveContainer';\nexport { _ResponsiveContainer as ResponsiveContainer };\nimport _Cell from './component/Cell';\nexport { _Cell as Cell };\nimport _Text from './component/Text';\nexport { _Text as Text };\nimport _Label from './component/Label';\nexport { _Label as Label };\nimport _LabelList from './component/LabelList';\nexport { _LabelList as LabelList };\nimport _Sector from './shape/Sector';\nexport { _Sector as Sector };\nimport _Curve from './shape/Curve';\nexport { _Curve as Curve };\nimport _Rectangle from './shape/Rectangle';\nexport { _Rectangle as Rectangle };\nimport _Polygon from './shape/Polygon';\nexport { _Polygon as Polygon };\nimport _Dot from './shape/Dot';\nexport { _Dot as Dot };\nimport _Cross from './shape/Cross';\nexport { _Cross as Cross };\nimport _Symbols from './shape/Symbols';\nexport { _Symbols as Symbols };\nimport _PolarGrid from './polar/PolarGrid';\nexport { _PolarGrid as PolarGrid };\nimport _PolarRadiusAxis from './polar/PolarRadiusAxis';\nexport { _PolarRadiusAxis as PolarRadiusAxis };\nimport _PolarAngleAxis from './polar/PolarAngleAxis';\nexport { _PolarAngleAxis as PolarAngleAxis };\nimport _Pie from './polar/Pie';\nexport { _Pie as Pie };\nimport _Radar from './polar/Radar';\nexport { _Radar as Radar };\nimport _RadialBar from './polar/RadialBar';\nexport { _RadialBar as RadialBar };\nimport _Brush from './cartesian/Brush';\nexport { _Brush as Brush };\nimport _ReferenceLine from './cartesian/ReferenceLine';\nexport { _ReferenceLine as ReferenceLine };\nimport _ReferenceDot from './cartesian/ReferenceDot';\nexport { _ReferenceDot as ReferenceDot };\nimport _ReferenceArea from './cartesian/ReferenceArea';\nexport { _ReferenceArea as ReferenceArea };\nimport _CartesianAxis from './cartesian/CartesianAxis';\nexport { _CartesianAxis as CartesianAxis };\nimport _CartesianGrid from './cartesian/CartesianGrid';\nexport { _CartesianGrid as CartesianGrid };\nimport _Line from './cartesian/Line';\nexport { _Line as Line };\nimport _Area from './cartesian/Area';\nexport { _Area as Area };\nimport _Bar from './cartesian/Bar';\nexport { _Bar as Bar };\nimport _Scatter from './cartesian/Scatter';\nexport { _Scatter as Scatter };\nimport _XAxis from './cartesian/XAxis';\nexport { _XAxis as XAxis };\nimport _YAxis from './cartesian/YAxis';\nexport { _YAxis as YAxis };\nimport _ZAxis from './cartesian/ZAxis';\nexport { _ZAxis as ZAxis };\nimport _ErrorBar from './cartesian/ErrorBar';\nexport { _ErrorBar as ErrorBar };\nimport _LineChart from './chart/LineChart';\nexport { _LineChart as LineChart };\nimport _BarChart from './chart/BarChart';\nexport { _BarChart as BarChart };\nimport _PieChart from './chart/PieChart';\nexport { _PieChart as PieChart };\nimport _Treemap from './chart/Treemap';\nexport { _Treemap as Treemap };\nimport _Sankey from './chart/Sankey';\nexport { _Sankey as Sankey };\nimport _RadarChart from './chart/RadarChart';\nexport { _RadarChart as RadarChart };\nimport _ScatterChart from './chart/ScatterChart';\nexport { _ScatterChart as ScatterChart };\nimport _AreaChart from './chart/AreaChart';\nexport { _AreaChart as AreaChart };\nimport _RadialBarChart from './chart/RadialBarChart';\nexport { _RadialBarChart as RadialBarChart };\nimport _ComposedChart from './chart/ComposedChart';\nexport { _ComposedChart as ComposedChart };\nimport _Funnel from './numberAxis/Funnel';\nexport { _Funnel as Funnel };\nimport _FunnelChart from './chart/FunnelChart';\nexport { _FunnelChart as FunnelChart };\nimport _Trapezoid from './shape/Trapezoid';\nexport { _Trapezoid as Trapezoid };", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Cross\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { isNumber } from '../util/DataUtils';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes } from '../util/ReactUtils';\n\nvar Cross = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Cross, _Component);\n\n function Cross() {\n _classCallCheck(this, Cross);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Cross).apply(this, arguments));\n }\n\n _createClass(Cross, [{\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n x = _this$props.x,\n y = _this$props.y,\n width = _this$props.width,\n height = _this$props.height,\n top = _this$props.top,\n left = _this$props.left,\n className = _this$props.className;\n\n if (!isNumber(x) || !isNumber(y) || !isNumber(width) || !isNumber(height) || !isNumber(top) || !isNumber(left)) {\n return null;\n }\n\n return React.createElement(\"path\", _extends({}, getPresentationAttributes(this.props), {\n className: classNames('recharts-cross', className),\n d: this.constructor.getPath(x, y, width, height, top, left)\n }));\n }\n }], [{\n key: \"getPath\",\n value: function getPath(x, y, width, height, top, left) {\n return \"M\".concat(x, \",\").concat(top, \"v\").concat(height, \"M\").concat(left, \",\").concat(y, \"h\").concat(width);\n }\n }]);\n\n return Cross;\n}(Component), _class2.displayName = 'Cross', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number,\n top: PropTypes.number,\n left: PropTypes.number,\n className: PropTypes.string\n}), _class2.defaultProps = {\n x: 0,\n y: 0,\n top: 0,\n left: 0,\n width: 0,\n height: 0\n}, _temp)) || _class;\n\nexport default Cross;", + "import _isArray from \"lodash/isArray\";\nimport _isFunction from \"lodash/isFunction\";\n\nvar _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Curve\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { line as shapeLine, area as shapeArea, curveBasisClosed, curveBasisOpen, curveBasis, curveLinearClosed, curveLinear, curveMonotoneX, curveMonotoneY, curveNatural, curveStep, curveStepAfter, curveStepBefore } from 'd3-shape';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\nimport { isNumber } from '../util/DataUtils';\nvar CURVE_FACTORIES = {\n curveBasisClosed: curveBasisClosed,\n curveBasisOpen: curveBasisOpen,\n curveBasis: curveBasis,\n curveLinearClosed: curveLinearClosed,\n curveLinear: curveLinear,\n curveMonotoneX: curveMonotoneX,\n curveMonotoneY: curveMonotoneY,\n curveNatural: curveNatural,\n curveStep: curveStep,\n curveStepAfter: curveStepAfter,\n curveStepBefore: curveStepBefore\n};\n\nvar defined = function defined(p) {\n return p.x === +p.x && p.y === +p.y;\n};\n\nvar getX = function getX(p) {\n return p.x;\n};\n\nvar getY = function getY(p) {\n return p.y;\n};\n\nvar getCurveFactory = function getCurveFactory(type, layout) {\n if (_isFunction(type)) {\n return type;\n }\n\n var name = \"curve\".concat(type.slice(0, 1).toUpperCase()).concat(type.slice(1));\n\n if (name === 'curveMonotone' && layout) {\n return CURVE_FACTORIES[\"\".concat(name).concat(layout === 'vertical' ? 'Y' : 'X')];\n }\n\n return CURVE_FACTORIES[name] || curveLinear;\n};\n\nvar Curve = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Curve, _Component);\n\n function Curve() {\n _classCallCheck(this, Curve);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Curve).apply(this, arguments));\n }\n\n _createClass(Curve, [{\n key: \"getPath\",\n\n /**\n * Calculate the path of curve\n * @return {String} path\n */\n value: function getPath() {\n var _this$props = this.props,\n type = _this$props.type,\n points = _this$props.points,\n baseLine = _this$props.baseLine,\n layout = _this$props.layout,\n connectNulls = _this$props.connectNulls;\n var curveFactory = getCurveFactory(type, layout);\n var formatPoints = connectNulls ? points.filter(function (entry) {\n return defined(entry);\n }) : points;\n var lineFunction;\n\n if (_isArray(baseLine)) {\n var formatBaseLine = connectNulls ? baseLine.filter(function (base) {\n return defined(base);\n }) : baseLine;\n var areaPoints = formatPoints.map(function (entry, index) {\n return _objectSpread({}, entry, {\n base: formatBaseLine[index]\n });\n });\n\n if (layout === 'vertical') {\n lineFunction = shapeArea().y(getY).x1(getX).x0(function (d) {\n return d.base.x;\n });\n } else {\n lineFunction = shapeArea().x(getX).y1(getY).y0(function (d) {\n return d.base.y;\n });\n }\n\n lineFunction.defined(defined).curve(curveFactory);\n return lineFunction(areaPoints);\n }\n\n if (layout === 'vertical' && isNumber(baseLine)) {\n lineFunction = shapeArea().y(getY).x1(getX).x0(baseLine);\n } else if (isNumber(baseLine)) {\n lineFunction = shapeArea().x(getX).y1(getY).y0(baseLine);\n } else {\n lineFunction = shapeLine().x(getX).y(getY);\n }\n\n lineFunction.defined(defined).curve(curveFactory);\n return lineFunction(formatPoints);\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n className = _this$props2.className,\n points = _this$props2.points,\n path = _this$props2.path,\n pathRef = _this$props2.pathRef;\n\n if ((!points || !points.length) && !path) {\n return null;\n }\n\n var realPath = points && points.length ? this.getPath() : path;\n return React.createElement(\"path\", _extends({}, getPresentationAttributes(this.props), filterEventAttributes(this.props, null, true), {\n className: classNames('recharts-curve', className),\n d: realPath,\n ref: pathRef\n }));\n }\n }]);\n\n return Curve;\n}(Component), _class2.displayName = 'Curve', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n className: PropTypes.string,\n type: PropTypes.oneOfType([PropTypes.oneOf(['basis', 'basisClosed', 'basisOpen', 'linear', 'linearClosed', 'natural', 'monotoneX', 'monotoneY', 'monotone', 'step', 'stepBefore', 'stepAfter']), PropTypes.func]),\n layout: PropTypes.oneOf(['horizontal', 'vertical']),\n baseLine: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),\n points: PropTypes.arrayOf(PropTypes.object),\n connectNulls: PropTypes.bool,\n path: PropTypes.string,\n pathRef: PropTypes.func\n}), _class2.defaultProps = {\n type: 'linear',\n points: [],\n connectNulls: false\n}, _temp)) || _class;\n\nexport default Curve;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Dot\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\n\nvar Dot = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Dot, _Component);\n\n function Dot() {\n _classCallCheck(this, Dot);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Dot).apply(this, arguments));\n }\n\n _createClass(Dot, [{\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n cx = _this$props.cx,\n cy = _this$props.cy,\n r = _this$props.r,\n className = _this$props.className;\n var layerClass = classNames('recharts-dot', className);\n\n if (cx === +cx && cy === +cy && r === +r) {\n return React.createElement(\"circle\", _extends({}, getPresentationAttributes(this.props), filterEventAttributes(this.props, null, true), {\n className: layerClass,\n cx: cx,\n cy: cy,\n r: r\n }));\n }\n\n return null;\n }\n }]);\n\n return Dot;\n}(Component), _class2.displayName = 'Dot', _class2.propTypes = {\n className: PropTypes.string,\n cx: PropTypes.number,\n cy: PropTypes.number,\n r: PropTypes.number\n}, _temp)) || _class;\n\nexport default Dot;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Rectangle\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Animate from 'react-smooth';\nimport pureRender from '../util/PureRender';\nimport { PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\n\nvar getRectangePath = function getRectangePath(x, y, width, height, radius) {\n var maxRadius = Math.min(Math.abs(width) / 2, Math.abs(height) / 2);\n var ySign = height >= 0 ? 1 : -1;\n var xSign = width >= 0 ? 1 : -1;\n var clockWise = height >= 0 && width >= 0 || height < 0 && width < 0 ? 1 : 0;\n var path;\n\n if (maxRadius > 0 && radius instanceof Array) {\n var newRadius = [];\n\n for (var i = 0, len = 4; i < len; i++) {\n newRadius[i] = radius[i] > maxRadius ? maxRadius : radius[i];\n }\n\n path = \"M\".concat(x, \",\").concat(y + ySign * newRadius[0]);\n\n if (newRadius[0] > 0) {\n path += \"A \".concat(newRadius[0], \",\").concat(newRadius[0], \",0,0,\").concat(clockWise, \",\").concat(x + xSign * newRadius[0], \",\").concat(y);\n }\n\n path += \"L \".concat(x + width - xSign * newRadius[1], \",\").concat(y);\n\n if (newRadius[1] > 0) {\n path += \"A \".concat(newRadius[1], \",\").concat(newRadius[1], \",0,0,\").concat(clockWise, \",\\n \").concat(x + width, \",\").concat(y + ySign * newRadius[1]);\n }\n\n path += \"L \".concat(x + width, \",\").concat(y + height - ySign * newRadius[2]);\n\n if (newRadius[2] > 0) {\n path += \"A \".concat(newRadius[2], \",\").concat(newRadius[2], \",0,0,\").concat(clockWise, \",\\n \").concat(x + width - xSign * newRadius[2], \",\").concat(y + height);\n }\n\n path += \"L \".concat(x + xSign * newRadius[3], \",\").concat(y + height);\n\n if (newRadius[3] > 0) {\n path += \"A \".concat(newRadius[3], \",\").concat(newRadius[3], \",0,0,\").concat(clockWise, \",\\n \").concat(x, \",\").concat(y + height - ySign * newRadius[3]);\n }\n\n path += 'Z';\n } else if (maxRadius > 0 && radius === +radius && radius > 0) {\n var _newRadius = Math.min(maxRadius, radius);\n\n path = \"M \".concat(x, \",\").concat(y + ySign * _newRadius, \"\\n A \").concat(_newRadius, \",\").concat(_newRadius, \",0,0,\").concat(clockWise, \",\").concat(x + xSign * _newRadius, \",\").concat(y, \"\\n L \").concat(x + width - xSign * _newRadius, \",\").concat(y, \"\\n A \").concat(_newRadius, \",\").concat(_newRadius, \",0,0,\").concat(clockWise, \",\").concat(x + width, \",\").concat(y + ySign * _newRadius, \"\\n L \").concat(x + width, \",\").concat(y + height - ySign * _newRadius, \"\\n A \").concat(_newRadius, \",\").concat(_newRadius, \",0,0,\").concat(clockWise, \",\").concat(x + width - xSign * _newRadius, \",\").concat(y + height, \"\\n L \").concat(x + xSign * _newRadius, \",\").concat(y + height, \"\\n A \").concat(_newRadius, \",\").concat(_newRadius, \",0,0,\").concat(clockWise, \",\").concat(x, \",\").concat(y + height - ySign * _newRadius, \" Z\");\n } else {\n path = \"M \".concat(x, \",\").concat(y, \" h \").concat(width, \" v \").concat(height, \" h \").concat(-width, \" Z\");\n }\n\n return path;\n};\n\nvar Rectangle = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Rectangle, _Component);\n\n function Rectangle() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, Rectangle);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Rectangle)).call.apply(_getPrototypeOf2, [this].concat(args)));\n _this.state = {\n totalLength: -1\n };\n return _this;\n }\n\n _createClass(Rectangle, [{\n key: \"componentDidMount\",\n\n /* eslint-disable react/no-did-mount-set-state */\n value: function componentDidMount() {\n if (this.node && this.node.getTotalLength) {\n try {\n var totalLength = this.node.getTotalLength();\n\n if (totalLength) {\n this.setState({\n totalLength: totalLength\n });\n }\n } catch (err) {// calculate total length error\n }\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this2 = this;\n\n var _this$props = this.props,\n x = _this$props.x,\n y = _this$props.y,\n width = _this$props.width,\n height = _this$props.height,\n radius = _this$props.radius,\n className = _this$props.className;\n var totalLength = this.state.totalLength;\n var _this$props2 = this.props,\n animationEasing = _this$props2.animationEasing,\n animationDuration = _this$props2.animationDuration,\n animationBegin = _this$props2.animationBegin,\n isAnimationActive = _this$props2.isAnimationActive,\n isUpdateAnimationActive = _this$props2.isUpdateAnimationActive;\n\n if (x !== +x || y !== +y || width !== +width || height !== +height || width === 0 || height === 0) {\n return null;\n }\n\n var layerClass = classNames('recharts-rectangle', className);\n\n if (!isUpdateAnimationActive) {\n return React.createElement(\"path\", _extends({}, getPresentationAttributes(this.props), filterEventAttributes(this.props), {\n className: layerClass,\n d: getRectangePath(x, y, width, height, radius)\n }));\n }\n\n return React.createElement(Animate, {\n canBegin: totalLength > 0,\n from: {\n width: width,\n height: height,\n x: x,\n y: y\n },\n to: {\n width: width,\n height: height,\n x: x,\n y: y\n },\n duration: animationDuration,\n animationEasing: animationEasing,\n isActive: isUpdateAnimationActive\n }, function (_ref) {\n var currWidth = _ref.width,\n currHeight = _ref.height,\n currX = _ref.x,\n currY = _ref.y;\n return React.createElement(Animate, {\n canBegin: totalLength > 0,\n from: \"0px \".concat(totalLength === -1 ? 1 : totalLength, \"px\"),\n to: \"\".concat(totalLength, \"px 0px\"),\n attributeName: \"strokeDasharray\",\n begin: animationBegin,\n duration: animationDuration,\n isActive: isAnimationActive,\n easing: animationEasing\n }, React.createElement(\"path\", _extends({}, getPresentationAttributes(_this2.props), filterEventAttributes(_this2.props), {\n className: layerClass,\n d: getRectangePath(currX, currY, currWidth, currHeight, radius),\n ref: function ref(node) {\n _this2.node = node;\n }\n })));\n });\n }\n }]);\n\n return Rectangle;\n}(Component), _class2.displayName = 'Rectangle', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, EVENT_ATTRIBUTES, {\n className: PropTypes.string,\n x: PropTypes.number,\n y: PropTypes.number,\n width: PropTypes.number,\n height: PropTypes.number,\n radius: PropTypes.oneOfType([PropTypes.number, PropTypes.array]),\n isAnimationActive: PropTypes.bool,\n isUpdateAnimationActive: PropTypes.bool,\n animationBegin: PropTypes.number,\n animationDuration: PropTypes.number,\n animationEasing: PropTypes.oneOf(['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear'])\n}), _class2.defaultProps = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n // The radius of border\n // The radius of four corners when radius is a number\n // The radius of left-top, right-top, right-bottom, left-bottom when radius is an array\n radius: 0,\n isAnimationActive: false,\n isUpdateAnimationActive: false,\n animationBegin: 0,\n animationDuration: 1500,\n animationEasing: 'ease'\n}, _temp)) || _class;\n\nexport default Rectangle;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Sector\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\nimport { polarToCartesian, RADIAN } from '../util/PolarUtils';\nimport { getPercentValue, mathSign } from '../util/DataUtils';\n\nvar getDeltaAngle = function getDeltaAngle(startAngle, endAngle) {\n var sign = mathSign(endAngle - startAngle);\n var deltaAngle = Math.min(Math.abs(endAngle - startAngle), 359.999);\n return sign * deltaAngle;\n};\n\nvar getTangentCircle = function getTangentCircle(_ref) {\n var cx = _ref.cx,\n cy = _ref.cy,\n radius = _ref.radius,\n angle = _ref.angle,\n sign = _ref.sign,\n isExternal = _ref.isExternal,\n cornerRadius = _ref.cornerRadius;\n var centerRadius = cornerRadius * (isExternal ? 1 : -1) + radius;\n var theta = Math.asin(cornerRadius / centerRadius) / RADIAN;\n var centerAngle = angle + sign * theta;\n var center = polarToCartesian(cx, cy, centerRadius, centerAngle); // The coordinate of point which is tangent to the circle\n\n var circleTangency = polarToCartesian(cx, cy, radius, centerAngle); // The coordinate of point which is tangent to the radius line\n\n var lineTangency = polarToCartesian(cx, cy, centerRadius * Math.cos(theta * RADIAN), angle);\n return {\n center: center,\n circleTangency: circleTangency,\n lineTangency: lineTangency,\n theta: theta\n };\n};\n\nvar getSectorPath = function getSectorPath(_ref2) {\n var cx = _ref2.cx,\n cy = _ref2.cy,\n innerRadius = _ref2.innerRadius,\n outerRadius = _ref2.outerRadius,\n startAngle = _ref2.startAngle,\n endAngle = _ref2.endAngle;\n var angle = getDeltaAngle(startAngle, endAngle); // When the angle of sector equals to 360, star point and end point coincide\n\n var tempEndAngle = startAngle + angle;\n var outerStartPoint = polarToCartesian(cx, cy, outerRadius, startAngle);\n var outerEndPoint = polarToCartesian(cx, cy, outerRadius, tempEndAngle);\n var path = \"M \".concat(outerStartPoint.x, \",\").concat(outerStartPoint.y, \"\\n A \").concat(outerRadius, \",\").concat(outerRadius, \",0,\\n \").concat(+(Math.abs(angle) > 180), \",\").concat(+(startAngle > tempEndAngle), \",\\n \").concat(outerEndPoint.x, \",\").concat(outerEndPoint.y, \"\\n \");\n\n if (innerRadius > 0) {\n var innerStartPoint = polarToCartesian(cx, cy, innerRadius, startAngle);\n var innerEndPoint = polarToCartesian(cx, cy, innerRadius, tempEndAngle);\n path += \"L \".concat(innerEndPoint.x, \",\").concat(innerEndPoint.y, \"\\n A \").concat(innerRadius, \",\").concat(innerRadius, \",0,\\n \").concat(+(Math.abs(angle) > 180), \",\").concat(+(startAngle <= tempEndAngle), \",\\n \").concat(innerStartPoint.x, \",\").concat(innerStartPoint.y, \" Z\");\n } else {\n path += \"L \".concat(cx, \",\").concat(cy, \" Z\");\n }\n\n return path;\n};\n\nvar getSectorWithCorner = function getSectorWithCorner(_ref3) {\n var cx = _ref3.cx,\n cy = _ref3.cy,\n innerRadius = _ref3.innerRadius,\n outerRadius = _ref3.outerRadius,\n cornerRadius = _ref3.cornerRadius,\n startAngle = _ref3.startAngle,\n endAngle = _ref3.endAngle;\n var sign = mathSign(endAngle - startAngle);\n\n var _getTangentCircle = getTangentCircle({\n cx: cx,\n cy: cy,\n radius: outerRadius,\n angle: startAngle,\n sign: sign,\n cornerRadius: cornerRadius\n }),\n soct = _getTangentCircle.circleTangency,\n solt = _getTangentCircle.lineTangency,\n sot = _getTangentCircle.theta;\n\n var _getTangentCircle2 = getTangentCircle({\n cx: cx,\n cy: cy,\n radius: outerRadius,\n angle: endAngle,\n sign: -sign,\n cornerRadius: cornerRadius\n }),\n eoct = _getTangentCircle2.circleTangency,\n eolt = _getTangentCircle2.lineTangency,\n eot = _getTangentCircle2.theta;\n\n var outerArcAngle = Math.abs(startAngle - endAngle) - sot - eot;\n\n if (outerArcAngle < 0) {\n return getSectorPath({\n cx: cx,\n cy: cy,\n innerRadius: innerRadius,\n outerRadius: outerRadius,\n startAngle: startAngle,\n endAngle: endAngle\n });\n }\n\n var path = \"M \".concat(solt.x, \",\").concat(solt.y, \"\\n A\").concat(cornerRadius, \",\").concat(cornerRadius, \",0,0,\").concat(+(sign < 0), \",\").concat(soct.x, \",\").concat(soct.y, \"\\n A\").concat(outerRadius, \",\").concat(outerRadius, \",0,\").concat(+(outerArcAngle > 180), \",\").concat(+(sign < 0), \",\").concat(eoct.x, \",\").concat(eoct.y, \"\\n A\").concat(cornerRadius, \",\").concat(cornerRadius, \",0,0,\").concat(+(sign < 0), \",\").concat(eolt.x, \",\").concat(eolt.y, \"\\n \");\n\n if (innerRadius > 0) {\n var _getTangentCircle3 = getTangentCircle({\n cx: cx,\n cy: cy,\n radius: innerRadius,\n angle: startAngle,\n sign: sign,\n isExternal: true,\n cornerRadius: cornerRadius\n }),\n sict = _getTangentCircle3.circleTangency,\n silt = _getTangentCircle3.lineTangency,\n sit = _getTangentCircle3.theta;\n\n var _getTangentCircle4 = getTangentCircle({\n cx: cx,\n cy: cy,\n radius: innerRadius,\n angle: endAngle,\n sign: -sign,\n isExternal: true,\n cornerRadius: cornerRadius\n }),\n eict = _getTangentCircle4.circleTangency,\n eilt = _getTangentCircle4.lineTangency,\n eit = _getTangentCircle4.theta;\n\n var innerArcAngle = Math.abs(startAngle - endAngle) - sit - eit;\n\n if (innerArcAngle < 0) {\n return \"\".concat(path, \"L\").concat(cx, \",\").concat(cy, \"Z\");\n }\n\n path += \"L\".concat(eilt.x, \",\").concat(eilt.y, \"\\n A\").concat(cornerRadius, \",\").concat(cornerRadius, \",0,0,\").concat(+(sign < 0), \",\").concat(eict.x, \",\").concat(eict.y, \"\\n A\").concat(innerRadius, \",\").concat(innerRadius, \",0,\").concat(+(innerArcAngle > 180), \",\").concat(+(sign > 0), \",\").concat(sict.x, \",\").concat(sict.y, \"\\n A\").concat(cornerRadius, \",\").concat(cornerRadius, \",0,0,\").concat(+(sign < 0), \",\").concat(silt.x, \",\").concat(silt.y, \"Z\");\n } else {\n path += \"L\".concat(cx, \",\").concat(cy, \"Z\");\n }\n\n return path;\n};\n\nvar Sector = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Sector, _Component);\n\n function Sector() {\n _classCallCheck(this, Sector);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Sector).apply(this, arguments));\n }\n\n _createClass(Sector, [{\n key: \"render\",\n value: function render() {\n var _this$props = this.props,\n cx = _this$props.cx,\n cy = _this$props.cy,\n innerRadius = _this$props.innerRadius,\n outerRadius = _this$props.outerRadius,\n cornerRadius = _this$props.cornerRadius,\n startAngle = _this$props.startAngle,\n endAngle = _this$props.endAngle,\n className = _this$props.className;\n\n if (outerRadius < innerRadius || startAngle === endAngle) {\n return null;\n }\n\n var layerClass = classNames('recharts-sector', className);\n var deltaRadius = outerRadius - innerRadius;\n var cr = getPercentValue(cornerRadius, deltaRadius, 0, true);\n var path;\n\n if (cr > 0 && Math.abs(startAngle - endAngle) < 360) {\n path = getSectorWithCorner({\n cx: cx,\n cy: cy,\n innerRadius: innerRadius,\n outerRadius: outerRadius,\n cornerRadius: Math.min(cr, deltaRadius / 2),\n startAngle: startAngle,\n endAngle: endAngle\n });\n } else {\n path = getSectorPath({\n cx: cx,\n cy: cy,\n innerRadius: innerRadius,\n outerRadius: outerRadius,\n startAngle: startAngle,\n endAngle: endAngle\n });\n }\n\n return React.createElement(\"path\", _extends({}, getPresentationAttributes(this.props), filterEventAttributes(this.props), {\n className: layerClass,\n d: path\n }));\n }\n }]);\n\n return Sector;\n}(Component), _class2.displayName = 'Sector', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n className: PropTypes.string,\n cx: PropTypes.number,\n cy: PropTypes.number,\n innerRadius: PropTypes.number,\n outerRadius: PropTypes.number,\n startAngle: PropTypes.number,\n endAngle: PropTypes.number,\n cornerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n}), _class2.defaultProps = {\n cx: 0,\n cy: 0,\n innerRadius: 0,\n outerRadius: 0,\n startAngle: 0,\n endAngle: 0,\n cornerRadius: 0\n}, _temp)) || _class;\n\nexport default Sector;", + "var _class, _class2, _temp;\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n/**\n * @fileOverview Curve\n */\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { symbol as shapeSymbol, symbolCircle, symbolCross, symbolDiamond, symbolSquare, symbolStar, symbolTriangle, symbolWye } from 'd3-shape';\nimport classNames from 'classnames';\nimport pureRender from '../util/PureRender';\nimport { PRESENTATION_ATTRIBUTES, getPresentationAttributes, filterEventAttributes } from '../util/ReactUtils';\nvar SYMBOL_FACTORIES = {\n symbolCircle: symbolCircle,\n symbolCross: symbolCross,\n symbolDiamond: symbolDiamond,\n symbolSquare: symbolSquare,\n symbolStar: symbolStar,\n symbolTriangle: symbolTriangle,\n symbolWye: symbolWye\n};\nvar RADIAN = Math.PI / 180;\n\nvar getSymbolFactory = function getSymbolFactory(type) {\n var name = \"symbol\".concat(type.slice(0, 1).toUpperCase()).concat(type.slice(1));\n return SYMBOL_FACTORIES[name] || symbolCircle;\n};\n\nvar calculateAreaSize = function calculateAreaSize(size, sizeType, type) {\n if (sizeType === 'area') {\n return size;\n }\n\n switch (type) {\n case 'cross':\n return 5 * size * size / 9;\n\n case 'diamond':\n return 0.5 * size * size / Math.sqrt(3);\n\n case 'square':\n return size * size;\n\n case 'star':\n {\n var angle = 18 * RADIAN;\n return 1.25 * size * size * (Math.tan(angle) - Math.tan(angle * 2) * Math.pow(Math.tan(angle), 2));\n }\n\n case 'triangle':\n return Math.sqrt(3) * size * size / 4;\n\n case 'wye':\n return (21 - 10 * Math.sqrt(3)) * size * size / 8;\n\n default:\n return Math.PI * size * size / 4;\n }\n};\n\nvar Symbols = pureRender(_class = (_temp = _class2 =\n/*#__PURE__*/\nfunction (_Component) {\n _inherits(Symbols, _Component);\n\n function Symbols() {\n _classCallCheck(this, Symbols);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Symbols).apply(this, arguments));\n }\n\n _createClass(Symbols, [{\n key: \"getPath\",\n\n /**\n * Calculate the path of curve\n * @return {String} path\n */\n value: function getPath() {\n var _this$props = this.props,\n size = _this$props.size,\n sizeType = _this$props.sizeType,\n type = _this$props.type;\n var symbolFactory = getSymbolFactory(type);\n var symbol = shapeSymbol().type(symbolFactory).size(calculateAreaSize(size, sizeType, type));\n return symbol();\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n className = _this$props2.className,\n cx = _this$props2.cx,\n cy = _this$props2.cy,\n size = _this$props2.size;\n\n if (cx === +cx && cy === +cy && size === +size) {\n return React.createElement(\"path\", _extends({}, getPresentationAttributes(this.props), filterEventAttributes(this.props), {\n className: classNames('recharts-symbols', className),\n transform: \"translate(\".concat(cx, \", \").concat(cy, \")\"),\n d: this.getPath()\n }));\n }\n\n return null;\n }\n }]);\n\n return Symbols;\n}(Component), _class2.displayName = 'Symbols', _class2.propTypes = _objectSpread({}, PRESENTATION_ATTRIBUTES, {\n className: PropTypes.string,\n type: PropTypes.oneOf(['circle', 'cross', 'diamond', 'square', 'star', 'triangle', 'wye']),\n cx: PropTypes.number,\n cy: PropTypes.number,\n size: PropTypes.number,\n sizeType: PropTypes.oneOf(['area', 'diameter'])\n}), _class2.defaultProps = {\n type: 'circle',\n size: 64,\n sizeType: 'area'\n}, _temp)) || _class;\n\nexport default Symbols;", + "import _every from \"lodash/every\";\nimport _mapValues from \"lodash/mapValues\";\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nimport { getTicksOfScale, parseScale, checkDomainOfScale, getBandSizeOfAxis } from './ChartUtils';\n/**\n * Calculate the scale function, position, width, height of axes\n * @param {Object} props Latest props\n * @param {Object} axisMap The configuration of axes\n * @param {Object} offset The offset of main part in the svg element\n * @param {String} axisType The type of axes, x-axis or y-axis\n * @param {String} chartName The name of chart\n * @return {Object} Configuration\n */\n\nexport var formatAxisMap = function formatAxisMap(props, axisMap, offset, axisType, chartName) {\n var width = props.width,\n height = props.height,\n layout = props.layout;\n var ids = Object.keys(axisMap);\n var steps = {\n left: offset.left,\n leftMirror: offset.left,\n right: width - offset.right,\n rightMirror: width - offset.right,\n top: offset.top,\n topMirror: offset.top,\n bottom: height - offset.bottom,\n bottomMirror: height - offset.bottom\n };\n return ids.reduce(function (result, id) {\n var axis = axisMap[id];\n var orientation = axis.orientation,\n domain = axis.domain,\n _axis$padding = axis.padding,\n padding = _axis$padding === void 0 ? {} : _axis$padding,\n mirror = axis.mirror,\n reversed = axis.reversed;\n var offsetKey = \"\".concat(orientation).concat(mirror ? 'Mirror' : '');\n var range, x, y, needSpace;\n\n if (axisType === 'xAxis') {\n range = [offset.left + (padding.left || 0), offset.left + offset.width - (padding.right || 0)];\n } else if (axisType === 'yAxis') {\n range = layout === 'horizontal' ? [offset.top + offset.height - (padding.bottom || 0), offset.top + (padding.top || 0)] : [offset.top + (padding.top || 0), offset.top + offset.height - (padding.bottom || 0)];\n } else {\n range = axis.range;\n }\n\n if (reversed) {\n range = [range[1], range[0]];\n }\n\n var _parseScale = parseScale(axis, chartName),\n scale = _parseScale.scale,\n realScaleType = _parseScale.realScaleType;\n\n scale.domain(domain).range(range);\n checkDomainOfScale(scale);\n var ticks = getTicksOfScale(scale, _objectSpread({}, axis, {\n realScaleType: realScaleType\n }));\n\n if (axisType === 'xAxis') {\n needSpace = orientation === 'top' && !mirror || orientation === 'bottom' && mirror;\n x = offset.left;\n y = steps[offsetKey] - needSpace * axis.height;\n } else if (axisType === 'yAxis') {\n needSpace = orientation === 'left' && !mirror || orientation === 'right' && mirror;\n x = steps[offsetKey] - needSpace * axis.width;\n y = offset.top;\n }\n\n var finalAxis = _objectSpread({}, axis, ticks, {\n realScaleType: realScaleType,\n x: x,\n y: y,\n scale: scale,\n width: axisType === 'xAxis' ? offset.width : axis.width,\n height: axisType === 'yAxis' ? offset.height : axis.height\n });\n\n finalAxis.bandSize = getBandSizeOfAxis(finalAxis, ticks);\n\n if (!axis.hide && axisType === 'xAxis') {\n steps[offsetKey] += (needSpace ? -1 : 1) * finalAxis.height;\n } else if (!axis.hide) {\n steps[offsetKey] += (needSpace ? -1 : 1) * finalAxis.width;\n }\n\n return _objectSpread({}, result, _defineProperty({}, id, finalAxis));\n }, {});\n};\nexport var rectWithPoints = function rectWithPoints(_ref, _ref2) {\n var x1 = _ref.x,\n y1 = _ref.y;\n var x2 = _ref2.x,\n y2 = _ref2.y;\n return {\n x: Math.min(x1, x2),\n y: Math.min(y1, y2),\n width: Math.abs(x2 - x1),\n height: Math.abs(y2 - y1)\n };\n};\n/**\n * Compute the x, y, width, and height of a box from two reference points.\n * @param {Object} coords x1, x2, y1, and y2\n * @return {Object} object\n */\n\nexport var rectWithCoords = function rectWithCoords(_ref3) {\n var x1 = _ref3.x1,\n y1 = _ref3.y1,\n x2 = _ref3.x2,\n y2 = _ref3.y2;\n return rectWithPoints({\n x: x1,\n y: y1\n }, {\n x: x2,\n y: y2\n });\n};\nexport var ScaleHelper =\n/*#__PURE__*/\nfunction () {\n _createClass(ScaleHelper, null, [{\n key: \"create\",\n value: function create(obj) {\n return new ScaleHelper(obj);\n }\n }]);\n\n function ScaleHelper(scale) {\n _classCallCheck(this, ScaleHelper);\n\n this.scale = scale;\n }\n\n _createClass(ScaleHelper, [{\n key: \"apply\",\n value: function apply(value) {\n var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n bandAware = _ref4.bandAware;\n\n if (value === undefined) {\n return undefined;\n }\n\n if (bandAware) {\n var offset = this.bandwidth ? this.bandwidth() / 2 : 0;\n return this.scale(value) + offset;\n }\n\n return this.scale(value);\n }\n }, {\n key: \"isInRange\",\n value: function isInRange(value) {\n var range = this.range();\n var first = range[0];\n var last = range[range.length - 1];\n return first <= last ? value >= first && value <= last : value >= last && value <= first;\n }\n }, {\n key: \"domain\",\n get: function get() {\n return this.scale.domain;\n }\n }, {\n key: \"range\",\n get: function get() {\n return this.scale.range;\n }\n }, {\n key: \"rangeMin\",\n get: function get() {\n return this.range()[0];\n }\n }, {\n key: \"rangeMax\",\n get: function get() {\n return this.range()[1];\n }\n }, {\n key: \"bandwidth\",\n get: function get() {\n return this.scale.bandwidth;\n }\n }]);\n\n return ScaleHelper;\n}();\nScaleHelper.EPS = 1e-4;\nexport var LabeledScaleHelper =\n/*#__PURE__*/\nfunction () {\n _createClass(LabeledScaleHelper, null, [{\n key: \"create\",\n value: function create(obj) {\n return new this(obj);\n }\n }]);\n\n function LabeledScaleHelper(scales) {\n _classCallCheck(this, LabeledScaleHelper);\n\n this.scales = _mapValues(scales, ScaleHelper.create);\n Object.assign(this, this.scales);\n }\n\n _createClass(LabeledScaleHelper, [{\n key: \"apply\",\n value: function apply(coords) {\n var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n bandAware = _ref5.bandAware;\n\n var scales = this.scales;\n return _mapValues(coords, function (value, label) {\n return scales[label].apply(value, {\n bandAware: bandAware\n });\n });\n }\n }, {\n key: \"isInRange\",\n value: function isInRange(coords) {\n var scales = this.scales;\n return _every(coords, function (value, label) {\n return scales[label].isInRange(value);\n });\n }\n }]);\n\n return LabeledScaleHelper;\n}();", + "import _isEqual from \"lodash/isEqual\";\nimport _sortBy from \"lodash/sortBy\";\nimport _isNaN from \"lodash/isNaN\";\nimport _isString from \"lodash/isString\";\nimport _max from \"lodash/max\";\nimport _min from \"lodash/min\";\nimport _isArray from \"lodash/isArray\";\nimport _flatMap from \"lodash/flatMap\";\nimport _isFunction from \"lodash/isFunction\";\nimport _get from \"lodash/get\";\nimport _isNil from \"lodash/isNil\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nimport { getNiceTickValues, getTickValuesFixedDomain } from 'recharts-scale';\nimport * as d3Scales from 'd3-scale';\nimport { stack as shapeStack, stackOrderNone, stackOffsetExpand, stackOffsetNone, stackOffsetSilhouette, stackOffsetWiggle } from 'd3-shape';\nimport { isNumOrStr, uniqueId, isNumber, getPercentValue, mathSign, findEntryInArray } from './DataUtils';\nimport ReferenceDot from '../cartesian/ReferenceDot';\nimport ReferenceLine from '../cartesian/ReferenceLine';\nimport ReferenceArea from '../cartesian/ReferenceArea';\nimport ErrorBar from '../cartesian/ErrorBar';\nimport Legend from '../component/Legend';\nimport { findAllByType, findChildByType, getDisplayName } from './ReactUtils';\nexport var getValueByDataKey = function getValueByDataKey(obj, dataKey, defaultValue) {\n if (_isNil(obj) || _isNil(dataKey)) {\n return defaultValue;\n }\n\n if (isNumOrStr(dataKey)) {\n return _get(obj, dataKey, defaultValue);\n }\n\n if (_isFunction(dataKey)) {\n return dataKey(obj);\n }\n\n return defaultValue;\n};\n/**\n * Get domain of data by key\n * @param {Array} data The data displayed in the chart\n * @param {String} key The unique key of a group of data\n * @param {String} type The type of axis\n * @param {Boolean} filterNil Whether or not filter nil values\n * @return {Array} Domain of data\n */\n\nexport var getDomainOfDataByKey = function getDomainOfDataByKey(data, key, type, filterNil) {\n var flattenData = _flatMap(data, function (entry) {\n return getValueByDataKey(entry, key);\n });\n\n if (type === 'number') {\n var domain = flattenData.filter(function (entry) {\n return isNumber(entry) || parseFloat(entry, 10);\n });\n return [Math.min.apply(null, domain), Math.max.apply(null, domain)];\n }\n\n var validateData = filterNil ? flattenData.filter(function (entry) {\n return !_isNil(entry);\n }) : flattenData;\n return validateData.map(function (entry) {\n return isNumOrStr(entry) ? entry : '';\n });\n};\nexport var calculateActiveTickIndex = function calculateActiveTickIndex(coordinate, ticks, unsortedTicks, axis) {\n var index = -1;\n var len = ticks.length;\n\n if (len > 1) {\n if (axis && axis.axisType === 'angleAxis' && Math.abs(Math.abs(axis.range[1] - axis.range[0]) - 360) <= 1e-6) {\n var range = axis.range; // ticks are distributed in a circle\n\n for (var i = 0; i < len; i++) {\n var before = i > 0 ? unsortedTicks[i - 1].coordinate : unsortedTicks[len - 1].coordinate;\n var cur = unsortedTicks[i].coordinate;\n var after = i >= len - 1 ? unsortedTicks[0].coordinate : unsortedTicks[i + 1].coordinate;\n var sameDirectionCoord = void 0;\n\n if (mathSign(cur - before) !== mathSign(after - cur)) {\n var diffInterval = [];\n\n if (mathSign(after - cur) === mathSign(range[1] - range[0])) {\n sameDirectionCoord = after;\n var curInRange = cur + range[1] - range[0];\n diffInterval[0] = Math.min(curInRange, (curInRange + before) / 2);\n diffInterval[1] = Math.max(curInRange, (curInRange + before) / 2);\n } else {\n sameDirectionCoord = before;\n var afterInRange = after + range[1] - range[0];\n diffInterval[0] = Math.min(cur, (afterInRange + cur) / 2);\n diffInterval[1] = Math.max(cur, (afterInRange + cur) / 2);\n }\n\n var sameInterval = [Math.min(cur, (sameDirectionCoord + cur) / 2), Math.max(cur, (sameDirectionCoord + cur) / 2)];\n\n if (coordinate > sameInterval[0] && coordinate <= sameInterval[1] || coordinate >= diffInterval[0] && coordinate <= diffInterval[1]) {\n index = unsortedTicks[i].index;\n break;\n }\n } else {\n var min = Math.min(before, after);\n var max = Math.max(before, after);\n\n if (coordinate > (min + cur) / 2 && coordinate <= (max + cur) / 2) {\n index = unsortedTicks[i].index;\n break;\n }\n }\n }\n } else {\n // ticks are distributed in a single direction\n for (var _i = 0; _i < len; _i++) {\n if (_i === 0 && coordinate <= (ticks[_i].coordinate + ticks[_i + 1].coordinate) / 2 || _i > 0 && _i < len - 1 && coordinate > (ticks[_i].coordinate + ticks[_i - 1].coordinate) / 2 && coordinate <= (ticks[_i].coordinate + ticks[_i + 1].coordinate) / 2 || _i === len - 1 && coordinate > (ticks[_i].coordinate + ticks[_i - 1].coordinate) / 2) {\n index = ticks[_i].index;\n break;\n }\n }\n }\n } else {\n index = 0;\n }\n\n return index;\n};\n/**\n * Get the main color of each graphic item\n * @param {ReactElement} item A graphic item\n * @return {String} Color\n */\n\nexport var getMainColorOfGraphicItem = function getMainColorOfGraphicItem(item) {\n var displayName = item.type.displayName;\n var result;\n\n switch (displayName) {\n case 'Line':\n case 'Area':\n case 'Radar':\n result = item.props.stroke;\n break;\n\n default:\n result = item.props.fill;\n break;\n }\n\n return result;\n};\nexport var getLegendProps = function getLegendProps(_ref) {\n var children = _ref.children,\n formatedGraphicalItems = _ref.formatedGraphicalItems,\n legendWidth = _ref.legendWidth,\n legendContent = _ref.legendContent;\n var legendItem = findChildByType(children, Legend);\n\n if (!legendItem) {\n return null;\n }\n\n var legendData;\n\n if (legendItem.props && legendItem.props.payload) {\n legendData = legendItem.props && legendItem.props.payload;\n } else if (legendContent === 'children') {\n legendData = (formatedGraphicalItems || []).reduce(function (result, _ref2) {\n var item = _ref2.item,\n props = _ref2.props;\n var data = props.sectors || props.data || [];\n return result.concat(data.map(function (entry) {\n return {\n type: legendItem.props.iconType || item.props.legendType,\n value: entry.name,\n color: entry.fill,\n payload: entry\n };\n }));\n }, []);\n } else {\n legendData = (formatedGraphicalItems || []).map(function (_ref3) {\n var item = _ref3.item;\n var _item$props = item.props,\n dataKey = _item$props.dataKey,\n name = _item$props.name,\n legendType = _item$props.legendType,\n hide = _item$props.hide;\n return {\n inactive: hide,\n dataKey: dataKey,\n type: legendItem.props.iconType || legendType || 'square',\n color: getMainColorOfGraphicItem(item),\n value: name || dataKey,\n payload: item.props\n };\n });\n }\n\n return _objectSpread({}, legendItem.props, Legend.getWithHeight(legendItem, legendWidth), {\n payload: legendData,\n item: legendItem\n });\n};\n/**\n * Calculate the size of all groups for stacked bar graph\n * @param {Object} stackGroups The items grouped by axisId and stackId\n * @return {Object} The size of all groups\n */\n\nexport var getBarSizeList = function getBarSizeList(_ref4) {\n var globalSize = _ref4.barSize,\n _ref4$stackGroups = _ref4.stackGroups,\n stackGroups = _ref4$stackGroups === void 0 ? {} : _ref4$stackGroups;\n\n if (!stackGroups) {\n return {};\n }\n\n var result = {};\n var numericAxisIds = Object.keys(stackGroups);\n\n for (var i = 0, len = numericAxisIds.length; i < len; i++) {\n var sgs = stackGroups[numericAxisIds[i]].stackGroups;\n var stackIds = Object.keys(sgs);\n\n for (var j = 0, sLen = stackIds.length; j < sLen; j++) {\n var _sgs$stackIds$j = sgs[stackIds[j]],\n items = _sgs$stackIds$j.items,\n cateAxisId = _sgs$stackIds$j.cateAxisId;\n var barItems = items.filter(function (item) {\n return getDisplayName(item.type).indexOf('Bar') >= 0;\n });\n\n if (barItems && barItems.length) {\n var selfSize = barItems[0].props.barSize;\n var cateId = barItems[0].props[cateAxisId];\n\n if (!result[cateId]) {\n result[cateId] = [];\n }\n\n result[cateId].push({\n item: barItems[0],\n stackList: barItems.slice(1),\n barSize: _isNil(selfSize) ? globalSize : selfSize\n });\n }\n }\n }\n\n return result;\n};\n/**\n * Calculate the size of each bar and the gap between two bars\n * @param {Number} bandSize The size of each category\n * @param {sizeList} sizeList The size of all groups\n * @param {maxBarSize} maxBarSize The maximum size of bar\n * @return {Number} The size of each bar and the gap between two bars\n */\n\nexport var getBarPosition = function getBarPosition(_ref5) {\n var barGap = _ref5.barGap,\n barCategoryGap = _ref5.barCategoryGap,\n bandSize = _ref5.bandSize,\n _ref5$sizeList = _ref5.sizeList,\n sizeList = _ref5$sizeList === void 0 ? [] : _ref5$sizeList,\n maxBarSize = _ref5.maxBarSize;\n var len = sizeList.length;\n if (len < 1) return null;\n var realBarGap = getPercentValue(barGap, bandSize, 0, true);\n var result; // whether or not is barSize setted by user\n\n if (sizeList[0].barSize === +sizeList[0].barSize) {\n var useFull = false;\n var fullBarSize = bandSize / len;\n var sum = sizeList.reduce(function (res, entry) {\n return res + entry.barSize || 0;\n }, 0);\n sum += (len - 1) * realBarGap;\n\n if (sum >= bandSize) {\n sum -= (len - 1) * realBarGap;\n realBarGap = 0;\n }\n\n if (sum >= bandSize && fullBarSize > 0) {\n useFull = true;\n fullBarSize *= 0.9;\n sum = len * fullBarSize;\n }\n\n var offset = (bandSize - sum) / 2 >> 0;\n var prev = {\n offset: offset - realBarGap,\n size: 0\n };\n result = sizeList.reduce(function (res, entry) {\n var newRes = _toConsumableArray(res).concat([{\n item: entry.item,\n position: {\n offset: prev.offset + prev.size + realBarGap,\n size: useFull ? fullBarSize : entry.barSize\n }\n }]);\n\n prev = newRes[newRes.length - 1].position;\n\n if (entry.stackList && entry.stackList.length) {\n entry.stackList.forEach(function (item) {\n newRes.push({\n item: item,\n position: prev\n });\n });\n }\n\n return newRes;\n }, []);\n } else {\n var _offset = getPercentValue(barCategoryGap, bandSize, 0, true);\n\n if (bandSize - 2 * _offset - (len - 1) * realBarGap <= 0) {\n realBarGap = 0;\n }\n\n var originalSize = (bandSize - 2 * _offset - (len - 1) * realBarGap) / len;\n\n if (originalSize > 1) {\n originalSize >>= 0;\n }\n\n var size = maxBarSize === +maxBarSize ? Math.min(originalSize, maxBarSize) : originalSize;\n result = sizeList.reduce(function (res, entry, i) {\n var newRes = _toConsumableArray(res).concat([{\n item: entry.item,\n position: {\n offset: _offset + (originalSize + realBarGap) * i + (originalSize - size) / 2,\n size: size\n }\n }]);\n\n if (entry.stackList && entry.stackList.length) {\n entry.stackList.forEach(function (item) {\n newRes.push({\n item: item,\n position: newRes[newRes.length - 1].position\n });\n });\n }\n\n return newRes;\n }, []);\n }\n\n return result;\n};\nexport var appendOffsetOfLegend = function appendOffsetOfLegend(offset, items, props, legendBox) {\n var children = props.children,\n width = props.width,\n height = props.height,\n margin = props.margin;\n var legendWidth = width - (margin.left || 0) - (margin.right || 0);\n var legendHeight = height - (margin.top || 0) - (margin.bottom || 0);\n var legendProps = getLegendProps({\n children: children,\n items: items,\n legendWidth: legendWidth,\n legendHeight: legendHeight\n });\n var newOffset = offset;\n\n if (legendProps) {\n var box = legendBox || {};\n var align = legendProps.align,\n verticalAlign = legendProps.verticalAlign,\n layout = legendProps.layout;\n\n if ((layout === 'vertical' || layout === 'horizontal' && verticalAlign === 'center') && isNumber(offset[align])) {\n newOffset = _objectSpread({}, offset, _defineProperty({}, align, newOffset[align] + (box.width || 0)));\n }\n\n if ((layout === 'horizontal' || layout === 'vertical' && align === 'center') && isNumber(offset[verticalAlign])) {\n newOffset = _objectSpread({}, offset, _defineProperty({}, verticalAlign, newOffset[verticalAlign] + (box.height || 0)));\n }\n }\n\n return newOffset;\n};\nexport var getDomainOfErrorBars = function getDomainOfErrorBars(data, item, dataKey, axisType) {\n var children = item.props.children;\n var errorBars = findAllByType(children, ErrorBar).filter(function (errorBarChild) {\n var direction = errorBarChild.props.direction;\n return _isNil(direction) || _isNil(axisType) ? true : axisType.indexOf(direction) >= 0;\n });\n\n if (errorBars && errorBars.length) {\n var keys = errorBars.map(function (errorBarChild) {\n return errorBarChild.props.dataKey;\n });\n return data.reduce(function (result, entry) {\n var entryValue = getValueByDataKey(entry, dataKey, 0);\n var mainValue = _isArray(entryValue) ? [_min(entryValue), _max(entryValue)] : [entryValue, entryValue];\n var errorDomain = keys.reduce(function (prevErrorArr, k) {\n var errorValue = getValueByDataKey(entry, k, 0);\n var lowerValue = mainValue[0] - Math.abs(_isArray(errorValue) ? errorValue[0] : errorValue);\n var upperValue = mainValue[1] + Math.abs(_isArray(errorValue) ? errorValue[1] : errorValue);\n return [Math.min(lowerValue, prevErrorArr[0]), Math.max(upperValue, prevErrorArr[1])];\n }, [Infinity, -Infinity]);\n return [Math.min(errorDomain[0], result[0]), Math.max(errorDomain[1], result[1])];\n }, [Infinity, -Infinity]);\n }\n\n return null;\n};\nexport var parseErrorBarsOfAxis = function parseErrorBarsOfAxis(data, items, dataKey, axisType) {\n var domains = items.map(function (item) {\n return getDomainOfErrorBars(data, item, dataKey, axisType);\n }).filter(function (entry) {\n return !_isNil(entry);\n });\n\n if (domains && domains.length) {\n return domains.reduce(function (result, entry) {\n return [Math.min(result[0], entry[0]), Math.max(result[1], entry[1])];\n }, [Infinity, -Infinity]);\n }\n\n return null;\n};\n/**\n * Get domain of data by the configuration of item element\n * @param {Array} data The data displayed in the chart\n * @param {Array} items The instances of item\n * @param {String} type The type of axis, number - Number Axis, category - Category Axis\n * @param {Boolean} filterNil Whether or not filter nil values\n * @return {Array} Domain\n */\n\nexport var getDomainOfItemsWithSameAxis = function getDomainOfItemsWithSameAxis(data, items, type, filterNil) {\n var domains = items.map(function (item) {\n var dataKey = item.props.dataKey;\n\n if (type === 'number' && dataKey) {\n return getDomainOfErrorBars(data, item, dataKey) || getDomainOfDataByKey(data, dataKey, type, filterNil);\n }\n\n return getDomainOfDataByKey(data, dataKey, type, filterNil);\n });\n\n if (type === 'number') {\n // Calculate the domain of number axis\n return domains.reduce(function (result, entry) {\n return [Math.min(result[0], entry[0]), Math.max(result[1], entry[1])];\n }, [Infinity, -Infinity]);\n }\n\n var tag = {}; // Get the union set of category axis\n\n return domains.reduce(function (result, entry) {\n for (var i = 0, len = entry.length; i < len; i++) {\n if (!tag[entry[i]]) {\n tag[entry[i]] = true;\n result.push(entry[i]);\n }\n }\n\n return result;\n }, []);\n};\nexport var isCategorialAxis = function isCategorialAxis(layout, axisType) {\n return layout === 'horizontal' && axisType === 'xAxis' || layout === 'vertical' && axisType === 'yAxis' || layout === 'centric' && axisType === 'angleAxis' || layout === 'radial' && axisType === 'radiusAxis';\n};\n/**\n * Calculate the Coordinates of grid\n * @param {Array} ticks The ticks in axis\n * @param {Number} min The minimun value of axis\n * @param {Number} max The maximun value of axis\n * @return {Array} Coordinates\n */\n\nexport var getCoordinatesOfGrid = function getCoordinatesOfGrid(ticks, min, max) {\n var hasMin, hasMax;\n var values = ticks.map(function (entry) {\n if (entry.coordinate === min) {\n hasMin = true;\n }\n\n if (entry.coordinate === max) {\n hasMax = true;\n }\n\n return entry.coordinate;\n });\n\n if (!hasMin) {\n values.push(min);\n }\n\n if (!hasMax) {\n values.push(max);\n }\n\n return values;\n};\n/**\n * Get the ticks of an axis\n * @param {Object} axis The configuration of an axis\n * @param {Boolean} isGrid Whether or not are the ticks in grid\n * @param {Boolean} isAll Return the ticks of all the points or not\n * @return {Array} Ticks\n */\n\nexport var getTicksOfAxis = function getTicksOfAxis(axis, isGrid, isAll) {\n if (!axis) return null;\n var scale = axis.scale;\n var duplicateDomain = axis.duplicateDomain,\n type = axis.type,\n range = axis.range;\n var offset = (isGrid || isAll) && type === 'category' && scale.bandwidth ? scale.bandwidth() / 2 : 0;\n offset = axis.axisType === 'angleAxis' ? mathSign(range[0] - range[1]) * 2 * offset : offset; // The ticks setted by user should only affect the ticks adjacent to axis line\n\n if (isGrid && (axis.ticks || axis.niceTicks)) {\n return (axis.ticks || axis.niceTicks).map(function (entry) {\n var scaleContent = duplicateDomain ? duplicateDomain.indexOf(entry) : entry;\n return {\n coordinate: scale(scaleContent) + offset,\n value: entry,\n offset: offset\n };\n });\n }\n\n if (axis.isCategorial && axis.categoricalDomain) {\n return axis.categoricalDomain.map(function (entry, index) {\n return {\n coordinate: scale(entry),\n value: entry,\n index: index,\n offset: offset\n };\n });\n }\n\n if (scale.ticks && !isAll) {\n return scale.ticks(axis.tickCount).map(function (entry) {\n return {\n coordinate: scale(entry) + offset,\n value: entry,\n offset: offset\n };\n });\n } // When axis has duplicated text, serial numbers are used to generate scale\n\n\n return scale.domain().map(function (entry, index) {\n return {\n coordinate: scale(entry) + offset,\n value: duplicateDomain ? duplicateDomain[entry] : entry,\n index: index,\n offset: offset\n };\n });\n};\n/**\n * combine the handlers\n * @param {Function} defaultHandler Internal private handler\n * @param {Function} parentHandler Handler function specified in parent component\n * @param {Function} childHandler Handler function specified in child component\n * @return {Function} The combined handler\n */\n\nexport var combineEventHandlers = function combineEventHandlers(defaultHandler, parentHandler, childHandler) {\n var customizedHandler;\n\n if (_isFunction(childHandler)) {\n customizedHandler = childHandler;\n } else if (_isFunction(parentHandler)) {\n customizedHandler = parentHandler;\n }\n\n if (_isFunction(defaultHandler) || customizedHandler) {\n return function (arg1, arg2, arg3, arg4) {\n if (_isFunction(defaultHandler)) {\n defaultHandler(arg1, arg2, arg3, arg4);\n }\n\n if (_isFunction(customizedHandler)) {\n customizedHandler(arg1, arg2, arg3, arg4);\n }\n };\n }\n\n return null;\n};\n/**\n * Parse the scale function of axis\n * @param {Object} axis The option of axis\n * @param {String} chartType The displayName of chart\n * @return {Function} The scale funcion\n */\n\nexport var parseScale = function parseScale(axis, chartType) {\n var scale = axis.scale,\n type = axis.type,\n layout = axis.layout,\n axisType = axis.axisType;\n\n if (scale === 'auto') {\n if (layout === 'radial' && axisType === 'radiusAxis') {\n return {\n scale: d3Scales.scaleBand(),\n realScaleType: 'band'\n };\n }\n\n if (layout === 'radial' && axisType === 'angleAxis') {\n return {\n scale: d3Scales.scaleLinear(),\n realScaleType: 'linear'\n };\n }\n\n if (type === 'category' && chartType && (chartType.indexOf('LineChart') >= 0 || chartType.indexOf('AreaChart') >= 0)) {\n return {\n scale: d3Scales.scalePoint(),\n realScaleType: 'point'\n };\n }\n\n if (type === 'category') {\n return {\n scale: d3Scales.scaleBand(),\n realScaleType: 'band'\n };\n }\n\n return {\n scale: d3Scales.scaleLinear(),\n realScaleType: 'linear'\n };\n }\n\n if (_isString(scale)) {\n var name = \"scale\".concat(scale.slice(0, 1).toUpperCase()).concat(scale.slice(1));\n return {\n scale: (d3Scales[name] || d3Scales.scalePoint)(),\n realScaleType: d3Scales[name] ? name : 'point'\n };\n }\n\n return _isFunction(scale) ? {\n scale: scale\n } : {\n scale: d3Scales.scalePoint(),\n realScaleType: 'point'\n };\n};\nvar EPS = 1e-4;\nexport var checkDomainOfScale = function checkDomainOfScale(scale) {\n var domain = scale.domain();\n\n if (!domain || domain.length <= 2) {\n return;\n }\n\n var len = domain.length;\n var range = scale.range();\n var min = Math.min(range[0], range[1]) - EPS;\n var max = Math.max(range[0], range[1]) + EPS;\n var first = scale(domain[0]);\n var last = scale(domain[len - 1]);\n\n if (first < min || first > max || last < min || last > max) {\n scale.domain([domain[0], domain[len - 1]]);\n }\n};\nexport var findPositionOfBar = function findPositionOfBar(barPosition, child) {\n if (!barPosition) {\n return null;\n }\n\n for (var i = 0, len = barPosition.length; i < len; i++) {\n if (barPosition[i].item === child) {\n return barPosition[i].position;\n }\n }\n\n return null;\n};\nexport var truncateByDomain = function truncateByDomain(value, domain) {\n if (!domain || domain.length !== 2 || !isNumber(domain[0]) || !isNumber(domain[1])) {\n return value;\n }\n\n var min = Math.min(domain[0], domain[1]);\n var max = Math.max(domain[0], domain[1]);\n var result = [value[0], value[1]];\n\n if (!isNumber(value[0]) || value[0] < min) {\n result[0] = min;\n }\n\n if (!isNumber(value[1]) || value[1] > max) {\n result[1] = max;\n }\n\n if (result[0] > max) {\n result[0] = max;\n }\n\n if (result[1] < min) {\n result[1] = min;\n }\n\n return result;\n};\n/* eslint no-param-reassign: 0 */\n\nexport var offsetSign = function offsetSign(series) {\n var n = series.length;\n\n if (n <= 0) {\n return;\n }\n\n for (var j = 0, m = series[0].length; j < m; ++j) {\n var positive = 0;\n var negative = 0;\n\n for (var i = 0; i < n; ++i) {\n var value = _isNaN(series[i][j][1]) ? series[i][j][0] : series[i][j][1];\n /* eslint-disable prefer-destructuring */\n\n if (value >= 0) {\n series[i][j][0] = positive;\n series[i][j][1] = positive + value;\n positive = series[i][j][1];\n } else {\n series[i][j][0] = negative;\n series[i][j][1] = negative + value;\n negative = series[i][j][1];\n }\n /* eslint-enable prefer-destructuring */\n\n }\n }\n};\nvar STACK_OFFSET_MAP = {\n sign: offsetSign,\n expand: stackOffsetExpand,\n none: stackOffsetNone,\n silhouette: stackOffsetSilhouette,\n wiggle: stackOffsetWiggle\n};\nexport var getStackedData = function getStackedData(data, stackItems, offsetType) {\n var dataKeys = stackItems.map(function (item) {\n return item.props.dataKey;\n });\n var stack = shapeStack().keys(dataKeys).value(function (d, key) {\n return +getValueByDataKey(d, key, 0);\n }).order(stackOrderNone).offset(STACK_OFFSET_MAP[offsetType]);\n return stack(data);\n};\nexport var getStackGroupsByAxisId = function getStackGroupsByAxisId(data, _items, numericAxisId, cateAxisId, offsetType, reverseStackOrder) {\n if (!data) {\n return null;\n } // reversing items to affect render order (for layering)\n\n\n var items = reverseStackOrder ? _items.reverse() : _items;\n var stackGroups = items.reduce(function (result, item) {\n var _item$props2 = item.props,\n stackId = _item$props2.stackId,\n hide = _item$props2.hide;\n\n if (hide) {\n return result;\n }\n\n var axisId = item.props[numericAxisId];\n var parentGroup = result[axisId] || {\n hasStack: false,\n stackGroups: {}\n };\n\n if (isNumOrStr(stackId)) {\n var childGroup = parentGroup.stackGroups[stackId] || {\n numericAxisId: numericAxisId,\n cateAxisId: cateAxisId,\n items: []\n };\n childGroup.items.push(item);\n parentGroup.hasStack = true;\n parentGroup.stackGroups[stackId] = childGroup;\n } else {\n parentGroup.stackGroups[uniqueId('_stackId_')] = {\n numericAxisId: numericAxisId,\n cateAxisId: cateAxisId,\n items: [item]\n };\n }\n\n return _objectSpread({}, result, _defineProperty({}, axisId, parentGroup));\n }, {});\n return Object.keys(stackGroups).reduce(function (result, axisId) {\n var group = stackGroups[axisId];\n\n if (group.hasStack) {\n group.stackGroups = Object.keys(group.stackGroups).reduce(function (res, stackId) {\n var g = group.stackGroups[stackId];\n return _objectSpread({}, res, _defineProperty({}, stackId, {\n numericAxisId: numericAxisId,\n cateAxisId: cateAxisId,\n items: g.items,\n stackedData: getStackedData(data, g.items, offsetType)\n }));\n }, {});\n }\n\n return _objectSpread({}, result, _defineProperty({}, axisId, group));\n }, {});\n};\n/**\n * get domain of ticks\n * @param {Array} ticks Ticks of axis\n * @param {String} type The type of axis\n * @return {Array} domain\n */\n\nexport var calculateDomainOfTicks = function calculateDomainOfTicks(ticks, type) {\n if (type === 'number') {\n return [Math.min.apply(null, ticks), Math.max.apply(null, ticks)];\n }\n\n return ticks;\n};\n/**\n * Configure the scale function of axis\n * @param {Object} scale The scale function\n * @param {Object} opts The configuration of axis\n * @return {Object} null\n */\n\nexport var getTicksOfScale = function getTicksOfScale(scale, opts) {\n var realScaleType = opts.realScaleType,\n type = opts.type,\n tickCount = opts.tickCount,\n originalDomain = opts.originalDomain,\n allowDecimals = opts.allowDecimals;\n var scaleType = realScaleType || opts.scale;\n\n if (scaleType !== 'auto' && scaleType !== 'linear') {\n return null;\n }\n\n if (tickCount && type === 'number' && originalDomain && (originalDomain[0] === 'auto' || originalDomain[1] === 'auto')) {\n // Calculate the ticks by the number of grid when the axis is a number axis\n var domain = scale.domain();\n var tickValues = getNiceTickValues(domain, tickCount, allowDecimals);\n scale.domain(calculateDomainOfTicks(tickValues, type));\n return {\n niceTicks: tickValues\n };\n }\n\n if (tickCount && type === 'number') {\n var _domain = scale.domain();\n\n var _tickValues = getTickValuesFixedDomain(_domain, tickCount, allowDecimals);\n\n return {\n niceTicks: _tickValues\n };\n }\n\n return null;\n};\nexport var getCateCoordinateOfLine = function getCateCoordinateOfLine(_ref6) {\n var axis = _ref6.axis,\n ticks = _ref6.ticks,\n bandSize = _ref6.bandSize,\n entry = _ref6.entry,\n index = _ref6.index,\n dataKey = _ref6.dataKey;\n\n if (axis.type === 'category') {\n // find coordinate of category axis by the value of category\n if (!axis.allowDuplicatedCategory && axis.dataKey && !_isNil(entry[axis.dataKey])) {\n var matchedTick = findEntryInArray(ticks, 'value', entry[axis.dataKey]);\n\n if (matchedTick) {\n return matchedTick.coordinate + bandSize / 2;\n }\n }\n\n return ticks[index] ? ticks[index].coordinate + bandSize / 2 : null;\n }\n\n var value = getValueByDataKey(entry, !_isNil(dataKey) ? dataKey : axis.dataKey);\n return !_isNil(value) ? axis.scale(value) : null;\n};\nexport var getCateCoordinateOfBar = function getCateCoordinateOfBar(_ref7) {\n var axis = _ref7.axis,\n ticks = _ref7.ticks,\n offset = _ref7.offset,\n bandSize = _ref7.bandSize,\n entry = _ref7.entry,\n index = _ref7.index;\n\n if (axis.type === 'category') {\n return ticks[index] ? ticks[index].coordinate + offset : null;\n }\n\n var value = getValueByDataKey(entry, axis.dataKey, axis.domain[index]);\n return !_isNil(value) ? axis.scale(value) - bandSize / 2 + offset : null;\n};\nexport var getBaseValueOfBar = function getBaseValueOfBar(_ref8) {\n var numericAxis = _ref8.numericAxis;\n var domain = numericAxis.scale.domain();\n\n if (numericAxis.type === 'number') {\n var min = Math.min(domain[0], domain[1]);\n var max = Math.max(domain[0], domain[1]);\n\n if (min <= 0 && max >= 0) {\n return 0;\n }\n\n if (max < 0) {\n return max;\n }\n\n return min;\n }\n\n return domain[0];\n};\nexport var ifOverflowMatches = function ifOverflowMatches(props, value) {\n var alwaysShow = props.alwaysShow;\n var ifOverflow = props.ifOverflow;\n\n if (alwaysShow) {\n ifOverflow = 'extendDomain';\n }\n\n return ifOverflow === value;\n};\nexport var detectReferenceElementsDomain = function detectReferenceElementsDomain(children, domain, axisId, axisType, specifiedTicks) {\n var lines = findAllByType(children, ReferenceLine);\n var dots = findAllByType(children, ReferenceDot);\n var elements = lines.concat(dots);\n var areas = findAllByType(children, ReferenceArea);\n var idKey = \"\".concat(axisType, \"Id\");\n var valueKey = axisType[0];\n var finalDomain = domain;\n\n if (elements.length) {\n finalDomain = elements.reduce(function (result, el) {\n if (el.props[idKey] === axisId && ifOverflowMatches(el.props, 'extendDomain') && isNumber(el.props[valueKey])) {\n var value = el.props[valueKey];\n return [Math.min(result[0], value), Math.max(result[1], value)];\n }\n\n return result;\n }, finalDomain);\n }\n\n if (areas.length) {\n var key1 = \"\".concat(valueKey, \"1\");\n var key2 = \"\".concat(valueKey, \"2\");\n finalDomain = areas.reduce(function (result, el) {\n if (el.props[idKey] === axisId && ifOverflowMatches(el.props, 'extendDomain') && isNumber(el.props[key1]) && isNumber(el.props[key2])) {\n var value1 = el.props[key1];\n var value2 = el.props[key2];\n return [Math.min(result[0], value1, value2), Math.max(result[1], value1, value2)];\n }\n\n return result;\n }, finalDomain);\n }\n\n if (specifiedTicks && specifiedTicks.length) {\n finalDomain = specifiedTicks.reduce(function (result, tick) {\n if (isNumber(tick)) {\n return [Math.min(result[0], tick), Math.max(result[1], tick)];\n }\n\n return result;\n }, finalDomain);\n }\n\n return finalDomain;\n};\nexport var getStackedDataOfItem = function getStackedDataOfItem(item, stackGroups) {\n var stackId = item.props.stackId;\n\n if (isNumOrStr(stackId)) {\n var group = stackGroups[stackId];\n\n if (group && group.items.length) {\n var itemIndex = -1;\n\n for (var i = 0, len = group.items.length; i < len; i++) {\n if (group.items[i] === item) {\n itemIndex = i;\n break;\n }\n }\n\n return itemIndex >= 0 ? group.stackedData[itemIndex] : null;\n }\n }\n\n return null;\n};\n\nvar getDomainOfSingle = function getDomainOfSingle(data) {\n return data.reduce(function (result, entry) {\n return [Math.min.apply(null, entry.concat([result[0]]).filter(isNumber)), Math.max.apply(null, entry.concat([result[1]]).filter(isNumber))];\n }, [Infinity, -Infinity]);\n};\n\nexport var getDomainOfStackGroups = function getDomainOfStackGroups(stackGroups, startIndex, endIndex) {\n return Object.keys(stackGroups).reduce(function (result, stackId) {\n var group = stackGroups[stackId];\n var stackedData = group.stackedData;\n var domain = stackedData.reduce(function (res, entry) {\n var s = getDomainOfSingle(entry.slice(startIndex, endIndex + 1));\n return [Math.min(res[0], s[0]), Math.max(res[1], s[1])];\n }, [Infinity, -Infinity]);\n return [Math.min(domain[0], result[0]), Math.max(domain[1], result[1])];\n }, [Infinity, -Infinity]).map(function (result) {\n return result === Infinity || result === -Infinity ? 0 : result;\n });\n};\nexport var MIN_VALUE_REG = /^dataMin[\\s]*-[\\s]*([0-9]+([.]{1}[0-9]+){0,1})$/;\nexport var MAX_VALUE_REG = /^dataMax[\\s]*\\+[\\s]*([0-9]+([.]{1}[0-9]+){0,1})$/;\nexport var parseSpecifiedDomain = function parseSpecifiedDomain(specifiedDomain, dataDomain, allowDataOverflow) {\n if (!_isArray(specifiedDomain)) {\n return dataDomain;\n }\n\n var domain = [];\n /* eslint-disable prefer-destructuring */\n\n if (isNumber(specifiedDomain[0])) {\n domain[0] = allowDataOverflow ? specifiedDomain[0] : Math.min(specifiedDomain[0], dataDomain[0]);\n } else if (MIN_VALUE_REG.test(specifiedDomain[0])) {\n var value = +MIN_VALUE_REG.exec(specifiedDomain[0])[1];\n domain[0] = dataDomain[0] - value;\n } else if (_isFunction(specifiedDomain[0])) {\n domain[0] = specifiedDomain[0](dataDomain[0]);\n } else {\n domain[0] = dataDomain[0];\n }\n\n if (isNumber(specifiedDomain[1])) {\n domain[1] = allowDataOverflow ? specifiedDomain[1] : Math.max(specifiedDomain[1], dataDomain[1]);\n } else if (MAX_VALUE_REG.test(specifiedDomain[1])) {\n var _value = +MAX_VALUE_REG.exec(specifiedDomain[1])[1];\n\n domain[1] = dataDomain[1] + _value;\n } else if (_isFunction(specifiedDomain[1])) {\n domain[1] = specifiedDomain[1](dataDomain[1]);\n } else {\n domain[1] = dataDomain[1];\n }\n /* eslint-enable prefer-destructuring */\n\n\n return domain;\n};\n/**\n * Calculate the size between two category\n * @param {Object} axis The options of axis\n * @param {Array} ticks The ticks of axis\n * @return {Number} Size\n */\n\nexport var getBandSizeOfAxis = function getBandSizeOfAxis(axis, ticks) {\n if (axis && axis.scale && axis.scale.bandwidth) {\n return axis.scale.bandwidth();\n }\n\n if (axis && ticks && ticks.length >= 2) {\n var orderedTicks = _sortBy(ticks, function (o) {\n return o.coordinate;\n });\n\n var bandSize = Infinity;\n\n for (var i = 1, len = orderedTicks.length; i < len; i++) {\n var cur = orderedTicks[i];\n var prev = orderedTicks[i - 1];\n bandSize = Math.min((cur.coordinate || 0) - (prev.coordinate || 0), bandSize);\n }\n\n return bandSize === Infinity ? 0 : bandSize;\n }\n\n return 0;\n};\n/**\n * parse the domain of a category axis when a domain is specified\n * @param {Array} specifiedDomain The domain specified by users\n * @param {Array} calculatedDomain The domain calculated by dateKey\n * @param {ReactElement} axisChild The axis element\n * @returns {Array} domains\n */\n\nexport var parseDomainOfCategoryAxis = function parseDomainOfCategoryAxis(specifiedDomain, calculatedDomain, axisChild) {\n if (!specifiedDomain || !specifiedDomain.length) {\n return calculatedDomain;\n }\n\n if (_isEqual(specifiedDomain, _get(axisChild, 'type.defaultProps.domain'))) {\n return calculatedDomain;\n }\n\n return specifiedDomain;\n};", + "function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nimport { isSsr } from './ReactUtils';\nvar stringCache = {\n widthCache: {},\n cacheCount: 0\n};\nvar MAX_CACHE_NUM = 2000;\nvar SPAN_STYLE = {\n position: 'absolute',\n top: '-20000px',\n left: 0,\n padding: 0,\n margin: 0,\n border: 'none',\n whiteSpace: 'pre'\n};\nvar STYLE_LIST = ['minWidth', 'maxWidth', 'width', 'minHeight', 'maxHeight', 'height', 'top', 'left', 'fontSize', 'lineHeight', 'padding', 'margin', 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom'];\nvar MEASUREMENT_SPAN_ID = 'recharts_measurement_span';\n\nfunction autoCompleteStyle(name, value) {\n if (STYLE_LIST.indexOf(name) >= 0 && value === +value) {\n return \"\".concat(value, \"px\");\n }\n\n return value;\n}\n\nfunction camelToMiddleLine(text) {\n var strs = text.split('');\n var formatStrs = strs.reduce(function (result, entry) {\n if (entry === entry.toUpperCase()) {\n return _toConsumableArray(result).concat(['-', entry.toLowerCase()]);\n }\n\n return _toConsumableArray(result).concat([entry]);\n }, []);\n return formatStrs.join('');\n}\n\nexport var getStyleString = function getStyleString(style) {\n return Object.keys(style).reduce(function (result, s) {\n return \"\".concat(result).concat(camelToMiddleLine(s), \":\").concat(autoCompleteStyle(s, style[s]), \";\");\n }, '');\n};\nexport var getStringSize = function getStringSize(text) {\n var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (text === undefined || text === null || isSsr()) {\n return {\n width: 0,\n height: 0\n };\n }\n\n var str = \"\".concat(text);\n var styleString = getStyleString(style);\n var cacheKey = \"\".concat(str, \"-\").concat(styleString);\n\n if (stringCache.widthCache[cacheKey]) {\n return stringCache.widthCache[cacheKey];\n }\n\n try {\n var measurementSpan = document.getElementById(MEASUREMENT_SPAN_ID);\n\n if (!measurementSpan) {\n measurementSpan = document.createElement('span');\n measurementSpan.setAttribute('id', MEASUREMENT_SPAN_ID);\n document.body.appendChild(measurementSpan);\n } // Need to use CSS Object Model (CSSOM) to be able to comply with Content Security Policy (CSP)\n // https://en.wikipedia.org/wiki/Content_Security_Policy\n\n\n var measurementSpanStyle = _objectSpread({}, SPAN_STYLE, style);\n\n Object.keys(measurementSpanStyle).map(function (styleKey) {\n measurementSpan.style[styleKey] = measurementSpanStyle[styleKey];\n return styleKey;\n });\n measurementSpan.textContent = str;\n var rect = measurementSpan.getBoundingClientRect();\n var result = {\n width: rect.width,\n height: rect.height\n };\n stringCache.widthCache[cacheKey] = result;\n\n if (++stringCache.cacheCount > MAX_CACHE_NUM) {\n stringCache.cacheCount = 0;\n stringCache.widthCache = {};\n }\n\n return result;\n } catch (e) {\n return {\n width: 0,\n height: 0\n };\n }\n};\nexport var getOffset = function getOffset(el) {\n var html = el.ownerDocument.documentElement;\n var box = {\n top: 0,\n left: 0\n }; // If we don't have gBCR, just use 0,0 rather than error\n // BlackBerry 5, iOS 3 (original iPhone)\n\n if (typeof el.getBoundingClientRect !== 'undefined') {\n box = el.getBoundingClientRect();\n }\n\n return {\n top: box.top + window.pageYOffset - html.clientTop,\n left: box.left + window.pageXOffset - html.clientLeft\n };\n};\n/**\n * Calculate coordinate of cursor in chart\n * @param {Object} event Event object\n * @param {Object} offset The offset of main part in the svg element\n * @return {Object} {chartX, chartY}\n */\n\nexport var calculateChartCoordinate = function calculateChartCoordinate(event, offset) {\n return {\n chartX: Math.round(event.pageX - offset.left),\n chartY: Math.round(event.pageY - offset.top)\n };\n};", + "import _get from \"lodash/get\";\nimport _isArray from \"lodash/isArray\";\nimport _isNaN from \"lodash/isNaN\";\nimport _isNumber from \"lodash/isNumber\";\nimport _isString from \"lodash/isString\";\nexport var mathSign = function mathSign(value) {\n if (value === 0) {\n return 0;\n }\n\n if (value > 0) {\n return 1;\n }\n\n return -1;\n};\nexport var isPercent = function isPercent(value) {\n return _isString(value) && value.indexOf('%') === value.length - 1;\n};\nexport var isNumber = function isNumber(value) {\n return _isNumber(value) && !_isNaN(value);\n};\nexport var isNumOrStr = function isNumOrStr(value) {\n return isNumber(value) || _isString(value);\n};\nvar idCounter = 0;\nexport var uniqueId = function uniqueId(prefix) {\n var id = ++idCounter;\n return \"\".concat(prefix || '').concat(id);\n};\n/**\n * Get percent value of a total value\n * @param {Number|String} percent A percent\n * @param {Number} totalValue Total value\n * @param {NUmber} defaultValue The value returned when percent is undefined or invalid\n * @param {Boolean} validate If set to be true, the result will be validated\n * @return {Number} value\n */\n\nexport var getPercentValue = function getPercentValue(percent, totalValue) {\n var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;\n var validate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n\n if (!isNumber(percent) && !_isString(percent)) {\n return defaultValue;\n }\n\n var value;\n\n if (isPercent(percent)) {\n var index = percent.indexOf('%');\n value = totalValue * parseFloat(percent.slice(0, index)) / 100;\n } else {\n value = +percent;\n }\n\n if (_isNaN(value)) {\n value = defaultValue;\n }\n\n if (validate && value > totalValue) {\n value = totalValue;\n }\n\n return value;\n};\nexport var getAnyElementOfObject = function getAnyElementOfObject(obj) {\n if (!obj) {\n return null;\n }\n\n var keys = Object.keys(obj);\n\n if (keys && keys.length) {\n return obj[keys[0]];\n }\n\n return null;\n};\nexport var hasDuplicate = function hasDuplicate(ary) {\n if (!_isArray(ary)) {\n return false;\n }\n\n var len = ary.length;\n var cache = {};\n\n for (var i = 0; i < len; i++) {\n if (!cache[ary[i]]) {\n cache[ary[i]] = true;\n } else {\n return true;\n }\n }\n\n return false;\n};\nexport var interpolateNumber = function interpolateNumber(numberA, numberB) {\n if (isNumber(numberA) && isNumber(numberB)) {\n return function (t) {\n return numberA + t * (numberB - numberA);\n };\n }\n\n return function () {\n return numberB;\n };\n};\nexport var findEntryInArray = function findEntryInArray(ary, specifiedKey, specifiedValue) {\n if (!ary || !ary.length) {\n return null;\n }\n\n return ary.find(function (entry) {\n return entry && _get(entry, specifiedKey) === specifiedValue;\n });\n};\n/**\n * The least square linear regression\n * @param {Array} data The array of points\n * @returns {Object} The domain of x, and the parameter of linear function\n */\n\nexport var getLinearRegression = function getLinearRegression(data) {\n if (!data || !data.length) {\n return null;\n }\n\n var len = data.length;\n var xsum = 0;\n var ysum = 0;\n var xysum = 0;\n var xxsum = 0;\n var xmin = Infinity;\n var xmax = -Infinity;\n\n for (var i = 0; i < len; i++) {\n xsum += data[i].cx;\n ysum += data[i].cy;\n xysum += data[i].cx * data[i].cy;\n xxsum += data[i].cx * data[i].cx;\n xmin = Math.min(xmin, data[i].cx);\n xmax = Math.max(xmax, data[i].cx);\n }\n\n var a = len * xxsum !== xsum * xsum ? (len * xysum - xsum * ysum) / (len * xxsum - xsum * xsum) : 0;\n return {\n xmin: xmin,\n xmax: xmax,\n a: a,\n b: (ysum - a * xsum) / len\n };\n};", + "/* eslint no-console: 0 */\nvar isDev = process.env.NODE_ENV !== 'production';\nexport var warn = function warn(condition, format, a, b, c, d, e, f) {\n if (isDev && typeof console !== 'undefined' && console.warn) {\n if (format === undefined) {\n console.warn('LogUtils requires an error message argument');\n }\n\n if (!condition) {\n if (format === undefined) {\n console.warn('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n } else {\n var args = [a, b, c, d, e, f];\n var argIndex = 0;\n console.warn(format.replace(/%s/g, function () {\n return args[argIndex++];\n }));\n }\n }\n }\n};", + "import _isNil from \"lodash/isNil\";\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nimport { getPercentValue } from './DataUtils';\nimport { parseScale, checkDomainOfScale, getTicksOfScale } from './ChartUtils';\nexport var RADIAN = Math.PI / 180;\nexport var degreeToRadian = function degreeToRadian(angle) {\n return angle * Math.PI / 180;\n};\nexport var radianToDegree = function radianToDegree(angleInRadian) {\n return angleInRadian * 180 / Math.PI;\n};\nexport var polarToCartesian = function polarToCartesian(cx, cy, radius, angle) {\n return {\n x: cx + Math.cos(-RADIAN * angle) * radius,\n y: cy + Math.sin(-RADIAN * angle) * radius\n };\n};\nexport var getMaxRadius = function getMaxRadius(width, height) {\n var offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n return Math.min(Math.abs(width - (offset.left || 0) - (offset.right || 0)), Math.abs(height - (offset.top || 0) - (offset.bottom || 0))) / 2;\n};\n/**\n * Calculate the scale function, position, width, height of axes\n * @param {Object} props Latest props\n * @param {Object} axisMap The configuration of axes\n * @param {Object} offset The offset of main part in the svg element\n * @param {Object} axisType The type of axes, radius-axis or angle-axis\n * @param {String} chartName The name of chart\n * @return {Object} Configuration\n */\n\nexport var formatAxisMap = function formatAxisMap(props, axisMap, offset, axisType, chartName) {\n var width = props.width,\n height = props.height;\n var startAngle = props.startAngle,\n endAngle = props.endAngle;\n var cx = getPercentValue(props.cx, width, width / 2);\n var cy = getPercentValue(props.cy, height, height / 2);\n var maxRadius = getMaxRadius(width, height, offset);\n var innerRadius = getPercentValue(props.innerRadius, maxRadius, 0);\n var outerRadius = getPercentValue(props.outerRadius, maxRadius, maxRadius * 0.8);\n var ids = Object.keys(axisMap);\n return ids.reduce(function (result, id) {\n var axis = axisMap[id];\n var domain = axis.domain,\n reversed = axis.reversed;\n var range;\n\n if (_isNil(axis.range)) {\n if (axisType === 'angleAxis') {\n range = [startAngle, endAngle];\n } else if (axisType === 'radiusAxis') {\n range = [innerRadius, outerRadius];\n }\n\n if (reversed) {\n range = [range[1], range[0]];\n }\n } else {\n range = axis.range;\n var _range = range;\n\n var _range2 = _slicedToArray(_range, 2);\n\n startAngle = _range2[0];\n endAngle = _range2[1];\n }\n\n var _parseScale = parseScale(axis, chartName),\n realScaleType = _parseScale.realScaleType,\n scale = _parseScale.scale;\n\n scale.domain(domain).range(range);\n checkDomainOfScale(scale);\n var ticks = getTicksOfScale(scale, _objectSpread({}, axis, {\n realScaleType: realScaleType\n }));\n\n var finalAxis = _objectSpread({}, axis, ticks, {\n range: range,\n radius: outerRadius,\n realScaleType: realScaleType,\n scale: scale,\n cx: cx,\n cy: cy,\n innerRadius: innerRadius,\n outerRadius: outerRadius,\n startAngle: startAngle,\n endAngle: endAngle\n });\n\n return _objectSpread({}, result, _defineProperty({}, id, finalAxis));\n }, {});\n};\nexport var distanceBetweenPoints = function distanceBetweenPoints(point, anotherPoint) {\n var x1 = point.x,\n y1 = point.y;\n var x2 = anotherPoint.x,\n y2 = anotherPoint.y;\n return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));\n};\nexport var getAngleOfPoint = function getAngleOfPoint(_ref, _ref2) {\n var x = _ref.x,\n y = _ref.y;\n var cx = _ref2.cx,\n cy = _ref2.cy;\n var radius = distanceBetweenPoints({\n x: x,\n y: y\n }, {\n x: cx,\n y: cy\n });\n\n if (radius <= 0) {\n return {\n radius: radius\n };\n }\n\n var cos = (x - cx) / radius;\n var angleInRadian = Math.acos(cos);\n\n if (y > cy) {\n angleInRadian = 2 * Math.PI - angleInRadian;\n }\n\n return {\n radius: radius,\n angle: radianToDegree(angleInRadian),\n angleInRadian: angleInRadian\n };\n};\nexport var formatAngleOfSector = function formatAngleOfSector(_ref3) {\n var startAngle = _ref3.startAngle,\n endAngle = _ref3.endAngle;\n var startCnt = Math.floor(startAngle / 360);\n var endCnt = Math.floor(endAngle / 360);\n var min = Math.min(startCnt, endCnt);\n return {\n startAngle: startAngle - min * 360,\n endAngle: endAngle - min * 360\n };\n};\n\nvar reverseFormatAngleOfSetor = function reverseFormatAngleOfSetor(angle, _ref4) {\n var startAngle = _ref4.startAngle,\n endAngle = _ref4.endAngle;\n var startCnt = Math.floor(startAngle / 360);\n var endCnt = Math.floor(endAngle / 360);\n var min = Math.min(startCnt, endCnt);\n return angle + min * 360;\n};\n\nexport var inRangeOfSector = function inRangeOfSector(_ref5, sector) {\n var x = _ref5.x,\n y = _ref5.y;\n\n var _getAngleOfPoint = getAngleOfPoint({\n x: x,\n y: y\n }, sector),\n radius = _getAngleOfPoint.radius,\n angle = _getAngleOfPoint.angle;\n\n var innerRadius = sector.innerRadius,\n outerRadius = sector.outerRadius;\n\n if (radius < innerRadius || radius > outerRadius) {\n return false;\n }\n\n if (radius === 0) {\n return true;\n }\n\n var _formatAngleOfSector = formatAngleOfSector(sector),\n startAngle = _formatAngleOfSector.startAngle,\n endAngle = _formatAngleOfSector.endAngle;\n\n var formatAngle = angle;\n var inRange;\n\n if (startAngle <= endAngle) {\n while (formatAngle > endAngle) {\n formatAngle -= 360;\n }\n\n while (formatAngle < startAngle) {\n formatAngle += 360;\n }\n\n inRange = formatAngle >= startAngle && formatAngle <= endAngle;\n } else {\n while (formatAngle > startAngle) {\n formatAngle -= 360;\n }\n\n while (formatAngle < endAngle) {\n formatAngle += 360;\n }\n\n inRange = formatAngle >= endAngle && formatAngle <= startAngle;\n }\n\n if (inRange) {\n return _objectSpread({}, sector, {\n radius: radius,\n angle: reverseFormatAngleOfSetor(formatAngle, sector)\n });\n }\n\n return null;\n};", + "export function shallowEqual(a, b) {\n /* eslint-disable no-restricted-syntax */\n for (var key in a) {\n if ({}.hasOwnProperty.call(a, key) && (!{}.hasOwnProperty.call(b, key) || a[key] !== b[key])) {\n return false;\n }\n }\n\n for (var _key in b) {\n if ({}.hasOwnProperty.call(b, _key) && !{}.hasOwnProperty.call(a, _key)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction shouldComponentUpdate(props, state) {\n return !shallowEqual(props, this.props) || !shallowEqual(state, this.state);\n}\n\nexport default function pureRenderDecorator(component) {\n // eslint-disable-next-line no-param-reassign\n component.prototype.shouldComponentUpdate = shouldComponentUpdate;\n}", + "import _isNil from \"lodash/isNil\";\nimport _isString from \"lodash/isString\";\nimport _isObject from \"lodash/isObject\";\nimport _isFunction from \"lodash/isFunction\";\nimport _isArray from \"lodash/isArray\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport React, { Children } from 'react';\nimport PropTypes from 'prop-types';\nimport { isNumber } from './DataUtils';\nimport { shallowEqual } from './PureRender';\nexport var PRESENTATION_ATTRIBUTES = {\n 'aria-current': PropTypes.string,\n // state\n 'aria-details': PropTypes.any,\n 'aria-disabled': PropTypes.any,\n // state\n 'aria-hidden': PropTypes.any,\n // state\n 'aria-invalid': PropTypes.any,\n // state\n 'aria-keyshortcuts': PropTypes.any,\n 'aria-label': PropTypes.any,\n 'aria-roledescription': PropTypes.any,\n // Widget Attributes\n 'aria-autocomplete': PropTypes.any,\n 'aria-checked': PropTypes.any,\n 'aria-expanded': PropTypes.any,\n 'aria-haspopup': PropTypes.any,\n 'aria-level': PropTypes.any,\n 'aria-modal': PropTypes.any,\n 'aria-multiline': PropTypes.any,\n 'aria-multiselectable': PropTypes.any,\n 'aria-orientation': PropTypes.any,\n 'aria-placeholder': PropTypes.any,\n 'aria-pressed': PropTypes.any,\n 'aria-readonly': PropTypes.any,\n 'aria-required': PropTypes.any,\n 'aria-selected': PropTypes.any,\n 'aria-sort': PropTypes.any,\n 'aria-valuemax': PropTypes.any,\n 'aria-valuemin': PropTypes.any,\n 'aria-valuenow': PropTypes.any,\n 'aria-valuetext': PropTypes.any,\n // Live Region Attributes\n 'aria-atomic': PropTypes.any,\n 'aria-busy': PropTypes.any,\n 'aria-live': PropTypes.any,\n 'aria-relevant': PropTypes.any,\n // Drag-and-Drop Attributes\n 'aria-dropeffect': PropTypes.any,\n 'aria-grabbed': PropTypes.any,\n // Relationship Attributes\n 'aria-activedescendant': PropTypes.any,\n 'aria-colcount': PropTypes.any,\n 'aria-colindex': PropTypes.any,\n 'aria-colspan': PropTypes.any,\n 'aria-controls': PropTypes.any,\n 'aria-describedby': PropTypes.any,\n 'aria-errormessage': PropTypes.any,\n 'aria-flowto': PropTypes.any,\n 'aria-labelledby': PropTypes.any,\n 'aria-owns': PropTypes.any,\n 'aria-posinset': PropTypes.any,\n 'aria-rowcount': PropTypes.any,\n 'aria-rowindex': PropTypes.any,\n 'aria-rowspan': PropTypes.any,\n 'aria-setsize': PropTypes.any,\n alignmentBaseline: PropTypes.string,\n angle: PropTypes.number,\n baselineShift: PropTypes.string,\n clip: PropTypes.string,\n clipPath: PropTypes.string,\n clipRule: PropTypes.string,\n color: PropTypes.string,\n colorInterpolation: PropTypes.string,\n colorInterpolationFilters: PropTypes.string,\n colorProfile: PropTypes.string,\n colorRendering: PropTypes.string,\n cursor: PropTypes.string,\n direction: PropTypes.oneOf(['ltr', 'rtl', 'inherit']),\n display: PropTypes.string,\n dominantBaseline: PropTypes.string,\n enableBackground: PropTypes.string,\n fill: PropTypes.string,\n fillOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n fillRule: PropTypes.oneOf(['nonzero', 'evenodd', 'inherit']),\n filter: PropTypes.string,\n floodColor: PropTypes.string,\n floodOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n font: PropTypes.string,\n fontFamily: PropTypes.string,\n fontSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n fontSizeAdjust: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n fontStretch: PropTypes.oneOf(['normal', 'wider', 'narrower', 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded', 'inherit']),\n fontStyle: PropTypes.oneOf(['normal', 'italic', 'oblique', 'inherit']),\n fontVariant: PropTypes.oneOf(['normal', 'small-caps', 'inherit']),\n fontWeight: PropTypes.oneOf(['normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900, 'inherit']),\n glyphOrientationHorizontal: PropTypes.string,\n glyphOrientationVertical: PropTypes.string,\n imageRendering: PropTypes.oneOf(['auto', 'optimizeSpeed', 'optimizeQuality', 'inherit']),\n kerning: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n letterSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n lightingColor: PropTypes.string,\n lineHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n markerEnd: PropTypes.string,\n markerMid: PropTypes.string,\n markerStart: PropTypes.string,\n mask: PropTypes.string,\n opacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n overflow: PropTypes.oneOf(['visible', 'hidden', 'scroll', 'auto', 'inherit']),\n pointerEvents: PropTypes.oneOf(['visiblePainted', 'visibleFill', 'visibleStroke', 'visible', 'painted', 'fill', 'stroke', 'all', 'none', 'inherit']),\n shapeRendering: PropTypes.oneOf(['auto', 'optimizeSpeed', 'crispEdges', 'geometricPrecision', 'inherit']),\n stopColor: PropTypes.string,\n stopOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n stroke: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n strokeDasharray: PropTypes.string,\n strokeDashoffset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square', 'inherit']),\n strokeLinejoin: PropTypes.oneOf(['miter', 'round', 'bevel', 'inherit']),\n strokeMiterlimit: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n strokeOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n textAnchor: PropTypes.oneOf(['start', 'middle', 'end', 'inherit']),\n textDecoration: PropTypes.oneOf(['none', 'underline', 'overline', 'line-through', 'blink', 'inherit']),\n textRendering: PropTypes.oneOf(['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision', 'inherit']),\n unicodeBidi: PropTypes.oneOf(['normal', 'embed', 'bidi-override', 'inherit']),\n visibility: PropTypes.oneOf(['visible', 'hidden', 'collapse', 'inherit']),\n wordSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n writingMode: PropTypes.oneOf(['lr-tb', 'rl-tb', 'tb-rl', 'lr', 'rl', 'tb', 'inherit']),\n transform: PropTypes.string,\n role: PropTypes.string,\n focusable: PropTypes.string,\n tabIndex: PropTypes.string,\n style: PropTypes.object,\n width: PropTypes.number,\n height: PropTypes.number,\n dx: PropTypes.number,\n dy: PropTypes.number,\n x: PropTypes.number,\n y: PropTypes.number,\n r: PropTypes.number,\n // The radius of Rectangle\n radius: PropTypes.oneOfType([PropTypes.number, PropTypes.array])\n};\nexport var EVENT_ATTRIBUTES = {\n onClick: PropTypes.func,\n onMouseDown: PropTypes.func,\n onMouseUp: PropTypes.func,\n onMouseOver: PropTypes.func,\n onMouseMove: PropTypes.func,\n onMouseOut: PropTypes.func,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onTouchEnd: PropTypes.func,\n onTouchMove: PropTypes.func,\n onTouchStart: PropTypes.func,\n onTouchCancel: PropTypes.func\n};\nvar REACT_BROWSER_EVENT_MAP = {\n click: 'onClick',\n mousedown: 'onMouseDown',\n mouseup: 'onMouseUp',\n mouseover: 'onMouseOver',\n mousemove: 'onMouseMove',\n mouseout: 'onMouseOut',\n mouseenter: 'onMouseEnter',\n mouseleave: 'onMouseLeave',\n touchcancel: 'onTouchCancel',\n touchend: 'onTouchEnd',\n touchmove: 'onTouchMove',\n touchstart: 'onTouchStart'\n};\nexport var SCALE_TYPES = ['auto', 'linear', 'pow', 'sqrt', 'log', 'identity', 'time', 'band', 'point', 'ordinal', 'quantile', 'quantize', 'utc', 'sequential', 'threshold'];\nexport var LEGEND_TYPES = ['plainline', 'line', 'square', 'rect', 'circle', 'cross', 'diamond', 'star', 'triangle', 'wye', 'none'];\n/**\n * Get the display name of a component\n * @param {Object} Comp Specified Component\n * @return {String} Display name of Component\n */\n\nexport var getDisplayName = function getDisplayName(Comp) {\n if (typeof Comp === 'string') {\n return Comp;\n }\n\n if (!Comp) {\n return '';\n }\n\n return Comp.displayName || Comp.name || 'Component';\n};\n/*\n * Find and return all matched children by type. ` + ("`" + `type`)) + (("`" + ` can be a React element class or\n * string\n */\n\nexport var findAllByType = function findAllByType(children, type) {\n var result = [];\n var types = [];\n\n if (_isArray(type)) {\n types = type.map(function (t) {\n return getDisplayName(t);\n });\n } else {\n types = [getDisplayName(type)];\n }\n\n React.Children.forEach(children, function (child) {\n var childType = child && child.type && (child.type.displayName || child.type.name);\n\n if (types.indexOf(childType) !== -1) {\n result.push(child);\n }\n });\n return result;\n};\n/*\n * Return the first matched child by type, return null otherwise.\n * `) + ("`" + `type`)))))) + ((((("`" + (` can be a React element class or string.\n */\n\nexport var findChildByType = function findChildByType(children, type) {\n var result = findAllByType(children, type);\n return result && result[0];\n};\n/*\n * Create a new array of children excluding the ones matched the type\n */\n\nexport var withoutType = function withoutType(children, type) {\n var newChildren = [];\n var types;\n\n if (_isArray(type)) {\n types = type.map(function (t) {\n return getDisplayName(t);\n });\n } else {\n types = [getDisplayName(type)];\n }\n\n React.Children.forEach(children, function (child) {\n if (child && child.type && child.type.displayName && types.indexOf(child.type.displayName) !== -1) {\n return;\n }\n\n newChildren.push(child);\n });\n return newChildren;\n};\n/**\n * get all the presentation attribute of svg element\n * @param {Object} el A react element or the props of a react element\n * @return {Object} attributes or null\n */\n\nexport var getPresentationAttributes = function getPresentationAttributes(el) {\n if (!el || _isFunction(el)) {\n return null;\n }\n\n var props = React.isValidElement(el) ? el.props : el;\n\n if (!_isObject(props)) {\n return null;\n }\n\n var out = null; // eslint-disable-next-line no-restricted-syntax\n\n for (var i in props) {\n if ({}.hasOwnProperty.call(props, i) && PRESENTATION_ATTRIBUTES[i]) {\n if (!out) out = {};\n out[i] = props[i];\n }\n }\n\n return out;\n};\n\nvar getEventHandlerOfElement = function getEventHandlerOfElement(originalHandler, props) {\n return function (e) {\n originalHandler(props, e);\n return null;\n };\n};\n/**\n * get all the event attribute of svg element\n * @param {Object} el A react element or the props of a react element\n * @param {Function} newHandler New handler of event\n * @param {Boolean} wrapCallback Wrap callback and return more parameters or not\n * @return {Object} attributes or null\n */\n\n\nexport var filterEventAttributes = function filterEventAttributes(el, newHandler) {\n var wrapCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n if (!el || _isFunction(el)) {\n return null;\n }\n\n var props = React.isValidElement(el) ? el.props : el;\n\n if (!_isObject(props)) {\n return null;\n }\n\n var out = null; // eslint-disable-next-line no-restricted-syntax\n\n for (var i in props) {\n if ({}.hasOwnProperty.call(props, i) && EVENT_ATTRIBUTES[i]) {\n if (!out) out = {};\n out[i] = newHandler || (wrapCallback ? getEventHandlerOfElement(props[i], props) : props[i]);\n }\n }\n\n return out;\n};\n\nvar getEventHandlerOfChild = function getEventHandlerOfChild(originalHandler, data, index) {\n return function (e) {\n originalHandler(data, index, e);\n return null;\n };\n};\n\nexport var filterEventsOfChild = function filterEventsOfChild(props, data, index) {\n if (!_isObject(props)) {\n return null;\n }\n\n var out = null; // eslint-disable-next-line no-restricted-syntax\n\n for (var i in props) {\n if ({}.hasOwnProperty.call(props, i) && EVENT_ATTRIBUTES[i] && _isFunction(props[i])) {\n if (!out) out = {};\n out[i] = getEventHandlerOfChild(props[i], data, index);\n }\n }\n\n return out;\n};\n/**\n * validate the width and height props of a chart element\n * @param {Object} el A chart element\n * @return {Boolean} true If the props width and height are number, and greater than 0\n */\n\nexport var validateWidthHeight = function validateWidthHeight(el) {\n if (!el || !el.props) {\n return false;\n }\n\n var _el$props = el.props,\n width = _el$props.width,\n height = _el$props.height;\n\n if (!isNumber(width) || width <= 0 || !isNumber(height) || height <= 0) {\n return false;\n }\n\n return true;\n};\nexport var isSsr = function isSsr() {\n return !(typeof window !== 'undefined' && window.document && window.document.createElement && window.setTimeout);\n};\nvar SVG_TAGS = ['a', 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'circle', 'clipPath', 'color-profile', 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColormatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'filter', 'font', 'font-face', 'font-face-format', 'font-face-name', 'font-face-url', 'foreignObject', 'g', 'glyph', 'glyphRef', 'hkern', 'image', 'line', 'lineGradient', 'marker', 'mask', 'metadata', 'missing-glyph', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'script', 'set', 'stop', 'style', 'svg', 'switch', 'symbol', 'text', 'textPath', 'title', 'tref', 'tspan', 'use', 'view', 'vkern'];\n\nvar isSvgElement = function isSvgElement(child) {\n return child && child.type && _isString(child.type) && SVG_TAGS.indexOf(child.type) >= 0;\n};\n/**\n * Filter all the svg elements of children\n * @param {Array} children The children of a react element\n * @return {Array} All the svg elements\n */\n\n\nexport var filterSvgElements = function filterSvgElements(children) {\n var svgElements = [];\n React.Children.forEach(children, function (entry) {\n if (entry && entry.type && _isString(entry.type) && SVG_TAGS.indexOf(entry.type) >= 0) {\n svgElements.push(entry);\n }\n });\n return svgElements;\n};\nexport var isSingleChildEqual = function isSingleChildEqual(nextChild, prevChild) {\n if (_isNil(nextChild) && _isNil(prevChild)) {\n return true;\n }\n\n if (!_isNil(nextChild) && !_isNil(prevChild)) {\n var _ref = nextChild.props || {},\n nextChildren = _ref.children,\n nextProps = _objectWithoutProperties(_ref, [\"children\"]);\n\n var _ref2 = prevChild.props || {},\n prevChildren = _ref2.children,\n prevProps = _objectWithoutProperties(_ref2, [\"children\"]);\n\n if (nextChildren && prevChildren) {\n // eslint-disable-next-line no-use-before-define\n return shallowEqual(nextProps, prevProps) && isChildrenEqual(nextChildren, prevChildren);\n }\n\n if (!nextChildren && !prevChildren) {\n return shallowEqual(nextProps, prevProps);\n }\n\n return false;\n }\n\n return false;\n};\n/**\n * Wether props of children changed\n * @param {Object} nextChildren The latest children\n * @param {Object} prevChildren The prev children\n * @return {Boolean} equal or not\n */\n\nexport var isChildrenEqual = function isChildrenEqual(nextChildren, prevChildren) {\n if (nextChildren === prevChildren) {\n return true;\n }\n\n if (Children.count(nextChildren) !== Children.count(prevChildren)) {\n return false;\n }\n\n var count = Children.count(nextChildren);\n\n if (count === 0) {\n return true;\n }\n\n if (count === 1) {\n return isSingleChildEqual(_isArray(nextChildren) ? nextChildren[0] : nextChildren, _isArray(prevChildren) ? prevChildren[0] : prevChildren);\n }\n\n for (var i = 0; i < count; i++) {\n var nextChild = nextChildren[i];\n var prevChild = prevChildren[i];\n\n if (_isArray(nextChild) || _isArray(prevChild)) {\n if (!isChildrenEqual(nextChild, prevChild)) {\n return false;\n }\n } else if (!isSingleChildEqual(nextChild, prevChild)) {\n return false;\n }\n }\n\n return true;\n};\nexport var renderByOrder = function renderByOrder(children, renderMap) {\n var elements = [];\n var record = {};\n Children.forEach(children, function (child, index) {\n if (child && isSvgElement(child)) {\n elements.push(child);\n } else if (child && renderMap[getDisplayName(child.type)]) {\n var displayName = getDisplayName(child.type);\n var _renderMap$displayNam = renderMap[displayName],\n handler = _renderMap$displayNam.handler,\n once = _renderMap$displayNam.once;\n\n if (once && !record[displayName] || !once) {\n var results = handler(child, displayName, index);\n\n if (_isArray(results)) {\n elements = [elements].concat(_toConsumableArray(results));\n } else {\n elements.push(results);\n }\n\n record[displayName] = true;\n }\n }\n });\n return elements;\n};\nexport var getReactEventByType = function getReactEventByType(e) {\n var type = e && e.type;\n\n if (type && REACT_BROWSER_EVENT_MAP[type]) {\n return REACT_BROWSER_EVENT_MAP[type];\n }\n\n return null;\n};\nexport var parseChildIndex = function parseChildIndex(child, children) {\n var result = -1;\n Children.forEach(children, function (entry, index) {\n if (entry === child) {\n result = index;\n }\n });\n return result;\n};", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the ` + "`")) + (`prop-types` + ("`" + ` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `))) + (("`" + (`./factoryWithTypeCheckers.js` + "`")) + (`.\n var ReactPropTypes = {\n array: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim\n };\n\n ReactPropTypes.checkPropTypes = emptyFunction;\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&\n Symbol.for &&\n Symbol.for('react.element')) ||\n 0xeac7;\n\n var isValidElement = function(object) {\n return typeof object === 'object' &&\n object !== null &&\n object.$$typeof === REACT_ELEMENT_TYPE;\n };\n\n // By explicitly using ` + ("`" + `prop-types`)))) + ((("`" + (` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(isValidElement, throwOnDirectAccess);\n} else {\n // By explicitly using ` + "`")) + (`prop-types` + ("`" + ` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n", + "/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n", + "/**\n * Module dependencies\n */\nvar balanced = require(\"balanced-match\")\nvar reduceFunctionCall = require(\"reduce-function-call\")\nvar mexp = require(\"math-expression-evaluator\")\n\n/**\n * Constantes\n */\nvar MAX_STACK = 100 // should be enough for a single calc()...\nvar NESTED_CALC_RE = /(\\+|\\-|\\*|\\\\|[^a-z]|)(\\s*)(\\()/g\n\n/**\n * Global variables\n */\nvar stack\n\n/**\n * Expose reduceCSSCalc plugin\n *\n * @type {Function}\n */\nmodule.exports = reduceCSSCalc\n\n/**\n * Reduce CSS calc() in a string, whenever it's possible\n *\n * @param {String} value css input\n */\nfunction reduceCSSCalc(value, decimalPrecision) {\n stack = 0\n decimalPrecision = Math.pow(10, decimalPrecision === undefined ? 5 : decimalPrecision)\n\n // Allow calc() on multiple lines\n value = value.replace(/\\n+/g, \" \")\n\n /**\n * Evaluates an expression\n *\n * @param {String} expression\n * @returns {String}\n */\n function evaluateExpression (expression, functionIdentifier, call) {\n if (stack++ > MAX_STACK) {\n stack = 0\n throw new Error(\"Call stack overflow for \" + call)\n }\n\n if (expression === \"\") {\n throw new Error(functionIdentifier + \"(): '\" + call + \"' must contain a non-whitespace string\")\n }\n\n expression = evaluateNestedExpression(expression, call)\n\n var units = getUnitsInExpression(expression)\n\n // If the expression contains multiple units or CSS variables,\n // then let the expression be (i.e. browser calc())\n if (units.length > 1 || expression.indexOf(\"var(\") > -1) {\n return functionIdentifier + \"(\" + expression + \")\"\n }\n\n var unit = units[0] || \"\"\n\n if (unit === \"%\") {\n // Convert percentages to numbers, to handle expressions like: 50% * 50% (will become: 25%):\n // console.log(expression)\n expression = expression.replace(/\\b[0-9\\.]+%/g, function(percent) {\n return parseFloat(percent.slice(0, -1)) * 0.01\n })\n }\n\n // Remove units in expression:\n var toEvaluate = expression.replace(new RegExp(unit, \"gi\"), \"\")\n var result\n\n try {\n result = mexp.eval(toEvaluate)\n }\n catch (e) {\n return functionIdentifier + \"(\" + expression + \")\"\n }\n\n // Transform back to a percentage result:\n if (unit === \"%\") {\n result *= 100\n }\n\n // adjust rounding shit\n // (0.1 * 0.2 === 0.020000000000000004)\n if (functionIdentifier.length || unit === \"%\") {\n result = Math.round(result * decimalPrecision) / decimalPrecision\n }\n\n // Add unit\n result += unit\n\n return result\n }\n\n /**\n * Evaluates nested expressions\n *\n * @param {String} expression\n * @returns {String}\n */\n function evaluateNestedExpression(expression, call) {\n // Remove the calc part from nested expressions to ensure\n // better browser compatibility\n expression = expression.replace(/((?:\\-[a-z]+\\-)?calc)/g, \"\")\n var evaluatedPart = \"\"\n var nonEvaluatedPart = expression\n var matches\n while ((matches = NESTED_CALC_RE.exec(nonEvaluatedPart))) {\n if (matches[0].index > 0) {\n evaluatedPart += nonEvaluatedPart.substring(0, matches[0].index)\n }\n\n var balancedExpr = balanced(\"(\", \")\", nonEvaluatedPart.substring([0].index))\n if (balancedExpr.body === \"\") {\n throw new Error(\"'\" + expression + \"' must contain a non-whitespace string\")\n }\n\n var evaluated = evaluateExpression(balancedExpr.body, \"\", call)\n\n evaluatedPart += balancedExpr.pre + evaluated\n nonEvaluatedPart = balancedExpr.post\n }\n\n return evaluatedPart + nonEvaluatedPart\n }\n\n return reduceFunctionCall(value, /((?:\\-[a-z]+\\-)?calc)\\(/, evaluateExpression)\n}\n\n/**\n * Checks what units are used in an expression\n *\n * @param {String} expression\n * @returns {Array}\n */\n\nfunction getUnitsInExpression(expression) {\n var uniqueUnits = []\n var uniqueLowerCaseUnits = []\n var unitRegEx = /[\\.0-9]([%a-z]+)/gi\n var matches = unitRegEx.exec(expression)\n\n while (matches) {\n if (!matches || !matches[1]) {\n continue\n }\n\n if (uniqueLowerCaseUnits.indexOf(matches[1].toLowerCase()) === -1) {\n uniqueUnits.push(matches[1])\n uniqueLowerCaseUnits.push(matches[1].toLowerCase())\n }\n\n matches = unitRegEx.exec(expression)\n }\n\n return uniqueUnits\n}\n", + "/*\n * Module dependencies\n */\nvar balanced = require(\"balanced-match\")\n\n/**\n * Expose `))) + (("`" + (`reduceFunctionCall` + "`")) + ((`\n *\n * @type {Function}\n */\nmodule.exports = reduceFunctionCall\n\n/**\n * Walkthrough all expressions, evaluate them and insert them into the declaration\n *\n * @param {Array} expressions\n * @param {Object} declaration\n */\n\nfunction reduceFunctionCall(string, functionRE, callback) {\n var call = string\n return getFunctionCalls(string, functionRE).reduce(function(string, obj) {\n return string.replace(obj.functionIdentifier + \"(\" + obj.matches.body + \")\", evalFunctionCall(obj.matches.body, obj.functionIdentifier, callback, call, functionRE))\n }, string)\n}\n\n/**\n * Parses expressions in a value\n *\n * @param {String} value\n * @returns {Array}\n * @api private\n */\n\nfunction getFunctionCalls(call, functionRE) {\n var expressions = []\n\n var fnRE = typeof functionRE === \"string\" ? new RegExp(\"\\\\b(\" + functionRE + \")\\\\(\") : functionRE\n do {\n var searchMatch = fnRE.exec(call)\n if (!searchMatch) {\n return expressions\n }\n if (searchMatch[1] === undefined) {\n throw new Error(\"Missing the first couple of parenthesis to get the function identifier in \" + functionRE)\n }\n var fn = searchMatch[1]\n var startIndex = searchMatch.index\n var matches = balanced(\"(\", \")\", call.substring(startIndex))\n\n if (!matches || matches.start !== searchMatch[0].length - 1) {\n throw new SyntaxError(fn + \"(): missing closing ')' in the value '\" + call + \"'\")\n }\n\n expressions.push({matches: matches, functionIdentifier: fn})\n call = matches.post\n }\n while (fnRE.test(call))\n\n return expressions\n}\n\n/**\n * Evaluates an expression\n *\n * @param {String} expression\n * @returns {String}\n * @api private\n */\n\nfunction evalFunctionCall (string, functionIdentifier, callback, call, functionRE) {\n // allow recursivity\n return callback(reduceFunctionCall(string, functionRE, callback), functionIdentifier, call)\n}\n", + "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", + "/** @license React v0.13.6\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';Object.defineProperty(exports,\"__esModule\",{value:!0});var d=null,e=!1,g=3,k=-1,l=-1,m=!1,n=!1;function p(){if(!m){var a=d.expirationTime;n?q():n=!0;r(t,a)}}\nfunction u(){var a=d,b=d.next;if(d===b)d=null;else{var c=d.previous;d=c.next=b;b.previous=c}a.next=a.previous=null;c=a.callback;b=a.expirationTime;a=a.priorityLevel;var f=g,Q=l;g=a;l=b;try{var h=c()}finally{g=f,l=Q}if(\"function\"===typeof h)if(h={callback:h,priorityLevel:a,expirationTime:b,next:null,previous:null},null===d)d=h.next=h.previous=h;else{c=null;a=d;do{if(a.expirationTime>=b){c=a;break}a=a.next}while(a!==d);null===c?c=d:c===d&&(d=h,p());b=c.previous;b.next=c.previous=h;h.next=c;h.previous=\nb}}function v(){if(-1===k&&null!==d&&1===d.priorityLevel){m=!0;try{do u();while(null!==d&&1===d.priorityLevel)}finally{m=!1,null!==d?p():n=!1}}}function t(a){m=!0;var b=e;e=a;try{if(a)for(;null!==d;){var c=exports.unstable_now();if(d.expirationTime<=c){do u();while(null!==d&&d.expirationTime<=c)}else break}else if(null!==d){do u();while(null!==d&&!w())}}finally{m=!1,e=b,null!==d?p():n=!1,v()}}\nvar x=Date,y=\"function\"===typeof setTimeout?setTimeout:void 0,z=\"function\"===typeof clearTimeout?clearTimeout:void 0,A=\"function\"===typeof requestAnimationFrame?requestAnimationFrame:void 0,B=\"function\"===typeof cancelAnimationFrame?cancelAnimationFrame:void 0,C,D;function E(a){C=A(function(b){z(D);a(b)});D=y(function(){B(C);a(exports.unstable_now())},100)}\nif(\"object\"===typeof performance&&\"function\"===typeof performance.now){var F=performance;exports.unstable_now=function(){return F.now()}}else exports.unstable_now=function(){return x.now()};var r,q,w,G=null;\"undefined\"!==typeof window?G=window:\"undefined\"!==typeof global&&(G=global);\nif(G&&G._schedMock){var H=G._schedMock;r=H[0];q=H[1];w=H[2];exports.unstable_now=H[3]}else if(\"undefined\"===typeof window||\"function\"!==typeof MessageChannel){var I=null,J=function(a){if(null!==I)try{I(a)}finally{I=null}};r=function(a){null!==I?setTimeout(r,0,a):(I=a,setTimeout(J,0,!1))};q=function(){I=null};w=function(){return!1}}else{\"undefined\"!==typeof console&&(\"function\"!==typeof A&&console.error(\"This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills\"),\n\"function\"!==typeof B&&console.error(\"This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills\"));var K=null,L=!1,M=-1,N=!1,O=!1,P=0,R=33,S=33;w=function(){return P<=exports.unstable_now()};var T=new MessageChannel,U=T.port2;T.port1.onmessage=function(){L=!1;var a=K,b=M;K=null;M=-1;var c=exports.unstable_now(),f=!1;if(0>=P-c)if(-1!==b&&b<=c)f=!0;else{N||(N=!0,E(V));K=a;M=b;return}if(null!==a){O=!0;try{a(f)}finally{O=!1}}};\nvar V=function(a){if(null!==K){E(V);var b=a-P+S;bb&&(b=8),S=bb?U.postMessage(void 0):N||(N=!0,E(V))};q=function(){K=null;L=!1;M=-1}}exports.unstable_ImmediatePriority=1;exports.unstable_UserBlockingPriority=2;exports.unstable_NormalPriority=3;exports.unstable_IdlePriority=5;exports.unstable_LowPriority=4;\nexports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=g,f=k;g=a;k=exports.unstable_now();try{return b()}finally{g=c,k=f,v()}};exports.unstable_next=function(a){switch(g){case 1:case 2:case 3:var b=3;break;default:b=g}var c=g,f=k;g=b;k=exports.unstable_now();try{return a()}finally{g=c,k=f,v()}};\nexports.unstable_scheduleCallback=function(a,b){var c=-1!==k?k:exports.unstable_now();if(\"object\"===typeof b&&null!==b&&\"number\"===typeof b.timeout)b=c+b.timeout;else switch(g){case 1:b=c+-1;break;case 2:b=c+250;break;case 5:b=c+1073741823;break;case 4:b=c+1E4;break;default:b=c+5E3}a={callback:a,priorityLevel:g,expirationTime:b,next:null,previous:null};if(null===d)d=a.next=a.previous=a,p();else{c=null;var f=d;do{if(f.expirationTime>b){c=f;break}f=f.next}while(f!==d);null===c?c=d:c===d&&(d=a,p());\nb=c.previous;b.next=c.previous=a;a.next=c;a.previous=b}return a};exports.unstable_cancelCallback=function(a){var b=a.next;if(null!==b){if(b===a)d=null;else{a===d&&(d=b);var c=a.previous;c.next=b;b.previous=c}a.next=a.previous=null}};exports.unstable_wrapCallback=function(a){var b=g;return function(){var c=g,f=k;g=b;k=exports.unstable_now();try{return a.apply(this,arguments)}finally{g=c,k=f,v()}}};exports.unstable_getCurrentPriorityLevel=function(){return g};\nexports.unstable_shouldYield=function(){return!e&&(null!==d&&d.expirationTime element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var script = doc.createElement(\"script\");\n script.onreadystatechange = function () {\n runIfPresent(handle);\n script.onreadystatechange = null;\n html.removeChild(script);\n script = null;\n };\n html.appendChild(script);\n };\n }\n\n function installSetTimeoutImplementation() {\n registerImmediate = function(handle) {\n setTimeout(runIfPresent, 0, handle);\n };\n }\n\n // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.\n var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);\n attachTo = attachTo && attachTo.setTimeout ? attachTo : global;\n\n // Don't get fooled by e.g. browserify environments.\n if ({}.toString.call(global.process) === \"[object process]\") {\n // For Node.js before 0.9\n installNextTickImplementation();\n\n } else if (canUsePostMessage()) {\n // For non-IE10 modern browsers\n installPostMessageImplementation();\n\n } else if (global.MessageChannel) {\n // For web workers, where supported\n installMessageChannelImplementation();\n\n } else if (doc && \"onreadystatechange\" in doc.createElement(\"script\")) {\n // For IE 6–8\n installReadyStateChangeImplementation();\n\n } else {\n // For older browsers\n installSetTimeoutImplementation();\n }\n\n attachTo.setImmediate = setImmediate;\n attachTo.clearImmediate = clearImmediate;\n}(typeof self === \"undefined\" ? typeof global === \"undefined\" ? this : global : self));\n", + "/* global window */\nimport ponyfill from './ponyfill.js';\n\nvar root;\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = ponyfill(root);\nexport default result;\n", + "export default function symbolObservablePonyfill(root) {\n\tvar result;\n\tvar Symbol = root.Symbol;\n\n\tif (typeof Symbol === 'function') {\n\t\tif (Symbol.observable) {\n\t\t\tresult = Symbol.observable;\n\t\t} else {\n\t\t\tresult = Symbol('observable');\n\t\t\tSymbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n", + "var scope = (typeof global !== \"undefined\" && global) ||\n (typeof self !== \"undefined\" && self) ||\n window;\nvar apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n if (timeout) {\n timeout.close();\n }\n};\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(scope, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object ` + ("`" + `setimmediate`)) + ("`" + (` was\n// able to install onto. Search each possibility in the same order as the\n// ` + "`"))) + ((`setimmediate` + ("`" + ` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n", + "/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar __DEV__ = process.env.NODE_ENV !== 'production';\n\nvar warning = function() {};\n\nif (__DEV__) {\n var printWarning = function printWarning(format, args) {\n var len = arguments.length;\n args = new Array(len > 1 ? len - 1 : 0);\n for (var key = 1; key < len; key++) {\n args[key - 1] = arguments[key];\n }\n var argIndex = 0;\n var message = 'Warning: ' +\n format.replace(/%s/g, function() {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n }\n\n warning = function(condition, format, args) {\n var len = arguments.length;\n args = new Array(len > 2 ? len - 2 : 0);\n for (var key = 2; key < len; key++) {\n args[key - 2] = arguments[key];\n }\n if (format === undefined) {\n throw new Error(\n '`)) + (("`" + `warning(condition, format, ...args)`) + ("`" + ` requires a warning ' +\n 'message argument'\n );\n }\n if (!condition) {\n printWarning.apply(null, [format].concat(args));\n }\n };\n}\n\nmodule.exports = warning;\n", + "var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n", + "module.exports = function(originalModule) {\n\tif (!originalModule.webpackPolyfill) {\n\t\tvar module = Object.create(originalModule);\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"exports\", {\n\t\t\tenumerable: true\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n", + "module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n" + ], + "sourceRoot": "" +}`)))))))))))))) + +func bundleJsMapBytes() ([]byte, error) { + return _bundleJsMap, nil +} + +func bundleJsMap() (*asset, error) { + bytes, err := bundleJsMapBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "bundle.js.map", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd0, 0xf7, 0xf2, 0xa1, 0x8e, 0xb5, 0x7a, 0xcc, 0xd9, 0x76, 0x54, 0x30, 0x90, 0x93, 0xc7, 0x1, 0x62, 0xa7, 0xda, 0x4c, 0x74, 0x3f, 0x7f, 0x6e, 0x42, 0x8c, 0x2d, 0x47, 0x58, 0x3d, 0xbc, 0x3e}} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "index.html": indexHtml, + + "bundle.js": bundleJs, + + "bundle.js.map": bundleJsMap, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "bundle.js": {bundleJs, map[string]*bintree{}}, + "bundle.js.map": {bundleJsMap, map[string]*bintree{}}, + "index.html": {indexHtml, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory. +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) +} + +// RestoreAssets restores an asset under the given directory recursively. +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) +} diff --git a/vendor/github.com/ethereum/go-ethereum/dashboard/assets/yarn.lock b/vendor/github.com/ethereum/go-ethereum/dashboard/assets/yarn.lock new file mode 100644 index 00000000..0fdf5593 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/dashboard/assets/yarn.lock @@ -0,0 +1,7408 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" + integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.3.4" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.3.4" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.3.4", "@babel/generator@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041" + integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ== + dependencies: + "@babel/types" "^7.4.4" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-builder-react-jsx@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" + integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== + dependencies: + "@babel/types" "^7.3.0" + esutils "^2.0.0" + +"@babel/helper-call-delegate@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" + integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/helper-create-class-features-plugin@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz#fc3d690af6554cc9efc607364a82d48f58736dba" + integrity sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-split-export-declaration" "^7.4.4" + +"@babel/helper-define-map@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a" + integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.4.4" + lodash "^4.17.11" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" + integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8" + integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/template" "^7.4.4" + "@babel/types" "^7.4.4" + lodash "^4.17.11" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" + integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== + dependencies: + lodash "^4.17.11" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" + integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helper-wrap-function@^7.1.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.2.0" + +"@babel/helpers@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5" + integrity sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A== + dependencies: + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.3.4", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872" + integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + +"@babel/plugin-proposal-class-properties@7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.4.tgz#410f5173b3dc45939f9ab30ca26684d72901405e" + integrity sha512-lUf8D3HLs4yYlAo8zjuneLvfxN7qfKv1Yzbj5vjqaqMJxgJA3Ipwp4VUJ+OrOdz53Wbww6ahwB8UhB2HQyLotA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.3.4" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-proposal-function-bind@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.2.0.tgz#94dc2cdc505cafc4e225c0014335a01648056bf7" + integrity sha512-qOFJ/eX1Is78sywwTxDcsntLOdb5ZlHVVqUz5xznq8ldAfOVIyZzp1JE2rzHnaksZIhrqMrwIpQL/qcEprnVbw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-function-bind" "^7.2.0" + +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + +"@babel/plugin-proposal-object-rest-spread@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005" + integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" + integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-flow@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" + integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-function-bind@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.2.0.tgz#68fe85b0c0da67125f87bf239c68051b06c66309" + integrity sha512-/WzU1lLU2l0wDfB42Wkg6tahrmtBbiD8C4H6EGSX0M4GAjzN6JiOpq/Uh8G6GSoR6lPMvhjM0MNiV6znj6y/zg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-jsx@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" + integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894" + integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d" + integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.11" + +"@babel/plugin-transform-classes@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6" + integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.4.4" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.4" + "@babel/helper-split-export-declaration" "^7.4.4" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f" + integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" + integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-flow-strip-types@7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.3.4.tgz#00156236defb7dedddc2d3c9477dcc01a4494327" + integrity sha512-PmQC9R7DwpBFA+7ATKMyzViz3zCaMNouzZMPZN2K5PnbBbtL3AXFYTkDk+Hey5crQq2A90UG5Uthz0mel+XZrA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" + +"@babel/plugin-transform-for-of@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" + integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" + integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e" + integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw== + dependencies: + "@babel/helper-module-transforms" "^7.4.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.3.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405" + integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.4" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" + integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== + dependencies: + regexp-tree "^0.1.6" + +"@babel/plugin-transform-new-target@^7.0.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" + integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" + integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== + dependencies: + "@babel/helper-call-delegate" "^7.4.4" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-react-display-name@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" + integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-react-jsx-self@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba" + integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@babel/plugin-transform-react-jsx-source@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f" + integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@babel/plugin-transform-react-jsx@^7.0.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" + integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== + dependencies: + "@babel/helper-builder-react-jsx" "^7.3.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@babel/plugin-transform-regenerator@^7.3.4": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" + integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== + dependencies: + regenerator-transform "^0.14.0" + +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" + integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" + integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/polyfill@^7.0.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893" + integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.2" + +"@babel/preset-env@7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" + integrity sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.3.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.3.4" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.3.4" + "@babel/plugin-transform-classes" "^7.3.4" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.2.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.3.4" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" + "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.2.0" + "@babel/plugin-transform-regenerator" "^7.3.4" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + browserslist "^4.3.4" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.3.0" + +"@babel/preset-react@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" + integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + +"@babel/preset-stage-0@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-stage-0/-/preset-stage-0-7.0.0.tgz#999aaec79ee8f0a763042c68c06539c97c6e0646" + integrity sha512-FBMd0IiARPtH5aaOFUVki6evHiJQiY0pFy7fizyRF7dtwc+el3nwpzvhb9qBNzceG1OIJModG1xpE0DDFjPXwA== + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12" + integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" + integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.3.4", "@babel/traverse@^7.4.4": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.5.tgz#4e92d1728fd2f1897dafdd321efbff92156c3216" + integrity sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.4" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.4.5" + "@babel/types" "^7.4.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.4", "@babel/types@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" + integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + +"@fortawesome/fontawesome-common-types@^0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.1.7.tgz#4336c4b06d0b5608ff1215464b66fcf9f4795284" + integrity sha512-ego8jRVSHfq/iq4KRZJKQeUAdi3ZjGNrqw4oPN3fNdvTBnLCSntwVCnc37bsAJP9UB8MhrTfPnZYxkv2vpS4pg== + +"@fortawesome/fontawesome-common-types@^0.2.19": + version "0.2.19" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.19.tgz#754a0f85e1290858152e1c05700ab502b11197f1" + integrity sha512-nd2Ul/CUs8U9sjofQYAALzOGpgkVJQgEhIJnOHaoyVR/LeC3x2mVg4eB910a4kS6WgLPebAY0M2fApEI497raQ== + +"@fortawesome/fontawesome-free-regular@^5.0.13": + version "5.0.13" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free-regular/-/fontawesome-free-regular-5.0.13.tgz#eb78c30184e3f456a423a1dcfa0f682f7b50de4a" + integrity sha512-36lz9Idww1L4QaaTcv7GZiOeIP9emJFDUsedvRovI10kmwyd6rN0PKkIjnq0FB4foLhX4Rou8vnbCCmjtqiLug== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.1.7" + +"@fortawesome/fontawesome-svg-core@^1.2.15": + version "1.2.19" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.19.tgz#0eca1ce9285c3d99e6e340633ee8f615f9d1a2e0" + integrity sha512-D4ICXg9oU08eF9o7Or392gPpjmwwgJu8ecCFusthbID95CLVXOgIyd4mOKD9Nud5Ckz+Ty59pqkNtThDKR0erA== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.19" + +"@fortawesome/free-regular-svg-icons@^5.7.2": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.9.0.tgz#b16b325bdcdf51abebc547313cb75c3ef722ca04" + integrity sha512-6ZO0jLhk/Yrso0u5pXeYYSfZiHCNoCF7SgtqStdlEX8WtWD4IOfAB1N+MlSnMo12P5KR4cmucX/K0NCOPrhJwg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.19" + +"@fortawesome/free-solid-svg-icons@^5.7.2": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.9.0.tgz#1c73e7bac17417d23f934d83f7fff5b100a7fda9" + integrity sha512-U8YXPfWcSozsCW0psCtlRGKjjRs5+Am5JJwLOUmVHFZbIEWzaz4YbP84EoPwUsVmSAKrisu3QeNcVOtmGml0Xw== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.19" + +"@fortawesome/react-fontawesome@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.4.tgz#18d61d9b583ca289a61aa7dccc05bd164d6bc9ad" + integrity sha512-GwmxQ+TK7PEdfSwvxtGnMCqrfEm0/HbRHArbUudsYiy9KzVCwndxa2KMcfyTQ8El0vROrq8gOOff09RF1oQe8g== + dependencies: + humps "^2.0.1" + prop-types "^15.5.10" + +"@material-ui/core@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-3.9.2.tgz#41ed1a470e981d199829eb5d9317a671c66a6f7d" + integrity sha512-aukR3mSH3g115St2OnqoeMRtmxzxxx+Mch7pFKRV3Tz3URExBlZwOolimjxKZpG4LGec8HlhREawafLsDzjVWQ== + dependencies: + "@babel/runtime" "^7.2.0" + "@material-ui/system" "^3.0.0-alpha.0" + "@material-ui/utils" "^3.0.0-alpha.2" + "@types/jss" "^9.5.6" + "@types/react-transition-group" "^2.0.8" + brcast "^3.0.1" + classnames "^2.2.5" + csstype "^2.5.2" + debounce "^1.1.0" + deepmerge "^3.0.0" + dom-helpers "^3.2.1" + hoist-non-react-statics "^3.2.1" + is-plain-object "^2.0.4" + jss "^9.8.7" + jss-camel-case "^6.0.0" + jss-default-unit "^8.0.2" + jss-global "^3.0.0" + jss-nested "^6.0.1" + jss-props-sort "^6.0.0" + jss-vendor-prefixer "^7.0.0" + normalize-scroll-left "^0.1.2" + popper.js "^1.14.1" + prop-types "^15.6.0" + react-event-listener "^0.6.2" + react-transition-group "^2.2.1" + recompose "0.28.0 - 0.30.0" + warning "^4.0.1" + +"@material-ui/icons@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-3.0.2.tgz#d67a6dd1ec8312d3a88ec97944a63daeef24fe10" + integrity sha512-QY/3gJnObZQ3O/e6WjH+0ah2M3MOgLOzCy8HTUoUx9B6dDrS18vP7Ycw3qrDEKlB6q1KNxy6CZHm5FCauWGy2g== + dependencies: + "@babel/runtime" "^7.2.0" + recompose "0.28.0 - 0.30.0" + +"@material-ui/system@^3.0.0-alpha.0": + version "3.0.0-alpha.2" + resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-3.0.0-alpha.2.tgz#096e80c8bb0f70aea435b9e38ea7749ee77b4e46" + integrity sha512-odmxQ0peKpP7RQBQ8koly06YhsPzcoVib1vByVPBH4QhwqBXuYoqlCjt02846fYspAqkrWzjxnWUD311EBbxOA== + dependencies: + "@babel/runtime" "^7.2.0" + deepmerge "^3.0.0" + prop-types "^15.6.0" + warning "^4.0.1" + +"@material-ui/utils@^3.0.0-alpha.2": + version "3.0.0-alpha.3" + resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-3.0.0-alpha.3.tgz#836c62ea46f5ffc6f0b5ea05ab814704a86908b1" + integrity sha512-rwMdMZptX0DivkqBuC+Jdq7BYTXwqKai5G5ejPpuEDKpWzi1Oxp+LygGw329FrKpuKeiqpcymlqJTjmy+quWng== + dependencies: + "@babel/runtime" "^7.2.0" + prop-types "^15.6.0" + react-is "^16.6.3" + +"@most/multicast@^1.2.5": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@most/multicast/-/multicast-1.3.0.tgz#e01574840df634478ac3fabd164c6e830fb3b966" + integrity sha512-DWH8AShgp5bXn+auGzf5tzPxvpmEvQJd0CNsApOci1LDF4eAEcnw4HQOr2Jaa+L92NbDYFKBSXxll+i7r1ikvw== + dependencies: + "@most/prelude" "^1.4.0" + +"@most/prelude@^1.4.0": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@most/prelude/-/prelude-1.7.2.tgz#be4ed406518d4c8c220e45c39fa7251365425b73" + integrity sha512-GM5ec7+xpkuXiCMyzhyENgH/xZ8t0nAMDBY0QOsVVD6TrZYjJKUnW1eaI18HHX8W+COWMwWR9c0zoPiBp9+tUg== + +"@octokit/rest@^15.12.1": + version "15.18.1" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.18.1.tgz#ec7fb0f8775ef64dc095fae6635411d3fbff9b62" + integrity sha512-g2tecjp2TEtYV8bKAFvfQtu+W29HM7ektmWmw8zrMy9/XCKDEYRErR2YvvhN9+IxkLC4O3lDqYP4b6WgsL6Utw== + dependencies: + before-after-hook "^1.1.0" + btoa-lite "^1.0.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lodash "^4.17.4" + node-fetch "^2.1.1" + universal-user-agent "^2.0.0" + url-template "^2.0.8" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@types/jss@^9.5.6": + version "9.5.8" + resolved "https://registry.yarnpkg.com/@types/jss/-/jss-9.5.8.tgz#258391f42211c042fc965508d505cbdc579baa5b" + integrity sha512-bBbHvjhm42UKki+wZpR89j73ykSXg99/bhuKuYYePtpma3ZAnmeGnl0WxXiZhPGsIfzKwCUkpPC0jlrVMBfRxA== + dependencies: + csstype "^2.0.0" + indefinite-observable "^1.0.1" + +"@types/prop-types@*": + version "15.7.1" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6" + integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg== + +"@types/react-transition-group@^2.0.8": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.9.2.tgz#c48cf2a11977c8b4ff539a1c91d259eaa627028d" + integrity sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "16.8.19" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.19.tgz#629154ef05e2e1985cdde94477deefd823ad9be3" + integrity sha512-QzEzjrd1zFzY9cDlbIiFvdr+YUmefuuRYrPxmkwG0UQv5XF35gFIi7a95m1bNVcFU0VimxSZ5QVGSiBmlggQXQ== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn@^6.0.5, acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@4, agent-base@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" + integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== + +ajv@^6.1.0, ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +axobject-query@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" + integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== + dependencies: + ast-types-flow "0.0.7" + +babel-eslint@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" + integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-loader@8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.5.tgz#225322d7509c2157655840bba52e46b6c2f2fe33" + integrity sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw== + dependencies: + find-cache-dir "^2.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + util.promisify "^1.0.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +before-after-hook@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d" + integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg== + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big-integer@^1.6.17: + version "1.6.44" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" + integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +bluebird@^3.5.3: + version "3.5.5" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" + integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + +bluebird@~3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brcast@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/brcast/-/brcast-3.0.1.tgz#6256a8349b20de9eed44257a9b24d71493cd48dd" + integrity sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg== + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.3.4: + version "4.6.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.2.tgz#574c665950915c2ac73a4594b8537a9eba26203f" + integrity sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q== + dependencies: + caniuse-lite "^1.0.30000974" + electron-to-chromium "^1.3.150" + node-releases "^1.1.23" + +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof-polyfill@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf" + integrity sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8= + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^11.3.2: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== + dependencies: + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0, camelcase@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30000974: + version "1.0.30000974" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz#b7afe14ee004e97ce6dc73e3f878290a12928ad8" + integrity sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww== + +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= + dependencies: + traverse ">=0.3.0 <0.4" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +change-emitter@^0.1.2: + version "0.1.6" + resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" + integrity sha1-6LL+PX8at9aaMhma/5HqaTFAlRU= + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + +chokidar@^2.0.0, chokidar@^2.0.2: + version "2.1.6" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" + integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chrome-trace-event@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.5, classnames@^2.2.6, classnames@~2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.0.tgz#9851ac61cc0d3898a8a3088650d5bf447bf69d97" + integrity sha512-hzTicsCJIHdxih9+2aLR1tNGZX5qSJGRHDPVwSY26tVrEf55XNajLOBWz2UuWSIergszA09/bqnOiHyqx9fxQg== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +commander@^2.11.0, commander@^2.15.1, commander@^2.19.0, commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compressible@~2.0.16: + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== + dependencies: + mime-db ">= 1.40.0 < 2" + +compression@^1.5.2: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect-history-api-fallback@^1.3.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.1.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + +core-js@^2.6.5: + version "2.6.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" + integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== + +core-js@~2.5.1: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-loader@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" + integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== + dependencies: + camelcase "^5.2.0" + icss-utils "^4.1.0" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.14" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^2.0.6" + postcss-modules-scope "^2.1.0" + postcss-modules-values "^2.0.0" + postcss-value-parser "^3.3.0" + schema-utils "^1.0.0" + +css-vendor@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-0.3.8.tgz#6421cfd3034ce664fe7673972fd0119fc28941fa" + integrity sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo= + dependencies: + is-in-browser "^1.0.2" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@^2.0.0, csstype@^2.2.0, csstype@^2.5.2: + version "2.6.5" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.5.tgz#1cd1dff742ebf4d7c991470ae71e12bb6751e034" + integrity sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA== + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +d3-array@^1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + +d3-collection@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== + +d3-color@1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.3.tgz#6c67bb2af6df3cc8d79efcc4d3a3e83e28c8048f" + integrity sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw== + +d3-format@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.2.tgz#6a96b5e31bcb98122a30863f7d92365c00603562" + integrity sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ== + +d3-interpolate@1, d3-interpolate@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68" + integrity sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w== + dependencies: + d3-color "1" + +d3-path@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.7.tgz#8de7cd693a75ac0b5480d3abaccd94793e58aae8" + integrity sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA== + +d3-scale@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.1.2.tgz#4e932b7b60182aee9073ede8764c98423e5f9a94" + integrity sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q== + dependencies: + d3-array "^1.2.0" + d3-collection "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-shape@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.3.tgz#3dad9b593e7297adac19b1f34a6821940968d7d6" + integrity sha512-mdrQ+V3jdEAa5k9clSEhCNFtq+pdky25PBGjocUgAI0AUbu/Esq4x6bdFcjkNura87Wqp1pd3dfZh6uJ+XojlA== + dependencies: + d3-path "1" + +d3-time-format@2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.3.tgz#ae06f8e0126a9d60d6364eac5b1533ae1bac826b" + integrity sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA== + dependencies: + d3-time "1" + +d3-time@1: + version "1.0.11" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.11.tgz#1d831a3e25cd189eb256c17770a666368762bbce" + integrity sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw== + +damerau-levenshtein@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414" + integrity sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA== + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +debounce@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" + integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.5, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== + dependencies: + xregexp "4.0.0" + +decimal.js-light@^2.4.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.0.tgz#ca7faf504c799326df94b0ab920424fdfc125348" + integrity sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" + integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-helpers@^3.2.1, dom-helpers@^3.3.1, dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +editorconfig@^0.15.2: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.150: + version "1.3.157" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.157.tgz#6211d69e8c4ee18df8c84e74e8644bcafc09486c" + integrity sha512-vxGi3lOGqlupuogZxJOMfu+Q1vaOlG6XbsblWw8XnUZSr/ptbt3D6jhHT5LJPZuFUpKhbEo1u4QipivSory1Kg== + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1, emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.2.tgz#04e068798d75beda14375a264bb3d742d7bc33aa" + integrity sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.3.2.tgz#18cbc8b6f36e9461c5c0f81df2b830de16058a59" + integrity sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~6.1.0" + +enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-config-airbnb-base@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c" + integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw== + dependencies: + eslint-restricted-globals "^0.1.1" + object.assign "^4.1.0" + object.entries "^1.0.4" + +eslint-config-airbnb@^17.0.0: + version "17.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz#3964ed4bc198240315ff52030bf8636f42bc4732" + integrity sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw== + dependencies: + eslint-config-airbnb-base "^13.1.0" + object.assign "^4.1.0" + object.entries "^1.0.4" + +eslint-import-resolver-node@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-loader@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.2.tgz#453542a1230d6ffac90e4e7cb9cadba9d851be68" + integrity sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg== + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-module-utils@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" + integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== + dependencies: + debug "^2.6.8" + pkg-dir "^2.0.0" + +eslint-plugin-es@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" + integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== + dependencies: + eslint-utils "^1.3.0" + regexpp "^2.0.1" + +eslint-plugin-flowtype@3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.4.2.tgz#55475e10b05fd714d60bceebbbed596cb8706b16" + integrity sha512-sv6O6fiN3dIwhU4qRxfcyIpbKGVvsxwIQ6vgBLudpQKjH1rEyEFEOjGzGEUBTQP9J8LdTZm37OjiqZ0ZeFOa6g== + dependencies: + lodash "^4.17.11" + +eslint-plugin-import@2.16.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f" + integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A== + dependencies: + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.3.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" + read-pkg-up "^2.0.0" + resolve "^1.9.0" + +eslint-plugin-jsx-a11y@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c" + integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w== + dependencies: + aria-query "^3.0.0" + array-includes "^3.0.3" + ast-types-flow "^0.0.7" + axobject-query "^2.0.2" + damerau-levenshtein "^1.0.4" + emoji-regex "^7.0.2" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + +eslint-plugin-node@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" + integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== + dependencies: + eslint-plugin-es "^1.3.1" + eslint-utils "^1.3.1" + ignore "^5.0.2" + minimatch "^3.0.4" + resolve "^1.8.1" + semver "^5.5.0" + +eslint-plugin-promise@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== + +eslint-plugin-react@7.12.4: + version "7.12.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" + integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ== + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + object.fromentries "^2.0.0" + prop-types "^15.6.2" + resolve "^1.9.0" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= + +eslint-scope@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.0, eslint-scope@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.0, eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@5.15.1: + version "5.15.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.1.tgz#8266b089fd5391e0009a047050795b1d73664524" + integrity sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.2" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.2: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +fbjs@^0.8.1: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" + integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + +flow-bin-loader@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flow-bin-loader/-/flow-bin-loader-1.0.3.tgz#1b95260437bea24786a5abc022ef3efa02df77c5" + integrity sha512-JgbydYGf7/Di8Jq4Az3+58g8lreabVdzI3IZQFICpQSH+yK8Uhgc1+Os5rnFBUfAQuhx3imUjpfOjaTLlz8M5A== + +flow-bin@0.94.0: + version "0.94.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.94.0.tgz#b5d58fe7559705b73a18229f97edfc3ab6ffffcb" + integrity sha512-DYF7r9CJ/AksfmmB4+q+TyLMoeQPRnqtF1Pk7KY3zgfkB/nVuA3nXyzqgsIPIvnMSiFEXQcFK4z+iPxSLckZhQ== + +flow-typed@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.2.tgz#967e83c762a1cbfcd52eebaece1ade77944f1714" + integrity sha512-RrHRmp/Bof1vDG1AqBcwuyxMMoezkl7TxvimA5c6GKZOOb1fkkRZ81S+1qAuvb4rUka5fLlFomKCnpMnCsgP+g== + dependencies: + "@babel/polyfill" "^7.0.0" + "@octokit/rest" "^15.12.1" + colors "^1.3.2" + fs-extra "^7.0.0" + glob "^7.1.3" + got "^8.3.2" + md5 "^2.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.2" + semver "^5.5.1" + table "^5.0.2" + through "^2.3.8" + unzipper "^0.9.3" + which "^1.3.1" + yargs "^12.0.2" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" + integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + dependencies: + debug "^3.2.6" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fp-ts@^1.0.0, fp-ts@^1.0.1: + version "1.18.2" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.18.2.tgz#b9a7025174e1a59bc43b485b3a0ca6f78e371d01" + integrity sha512-kznerusCuG5dUt0bH6eiQHVp2fstPiSlyzGb//rYgMMxCuromWEoVS0riH++86vyJm9Nv1B+pbe6udDx1tqjfA== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" + integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + dependencies: + nan "^2.12.1" + node-pre-gyp "^0.12.0" + +fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^7.0.3, glob@^7.1.2, glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +handle-thing@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" + integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== + +handlebars@^4.0.11: + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^2.3.1: + version "2.5.5" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" + integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== + +hoist-non-react-statics@^3.2.1, hoist-non-react-statics@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" + integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== + dependencies: + react-is "^16.7.0" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2, http-errors@~1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.4.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" + integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy-middleware@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-proxy-agent@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa" + integrity sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao= + +hyphenate-style-name@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" + integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== + +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.0.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558" + integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ== + +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indefinite-observable@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/indefinite-observable/-/indefinite-observable-1.0.2.tgz#0a328793ab2385d4b9dca23eaab4afe6936a73f8" + integrity sha512-Mps0898zEduHyPhb7UCgNmfzlqNZknVmaFz5qzr0mm04YQ5FGLhAyK/dJ+NaRxGyR6juQXIxh5Ev0xx+qq0nYA== + dependencies: + symbol-observable "1.2.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^6.2.2: + version "6.3.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7" + integrity sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +inspectpack@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/inspectpack/-/inspectpack-4.2.1.tgz#8e1893feb5293458c9d587cb2a8ec70be2e79dd4" + integrity sha512-3kraYZ9tfxNYXzBsRTNvluj1oJKlJ6wkD+TZ6Vk9CNI1SZcQ5H/9yskuq1Yzha1Cn/wEX/Qw+g+tSLIP5iGXhg== + dependencies: + chalk "^2.4.0" + io-ts "^1.0.5" + io-ts-reporters "^0.0.20" + pify "^3.0.0" + semver-compare "^1.0.0" + yargs "^11.0.0" + +internal-ip@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +interpret@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +io-ts-reporters@^0.0.20: + version "0.0.20" + resolved "https://registry.yarnpkg.com/io-ts-reporters/-/io-ts-reporters-0.0.20.tgz#2b8cbb6a2bc4562dae6917a3a413fa2c9851a644" + integrity sha512-ZGyPkto96U8exipqA915ZqxIJsaFLavgZIQOEgg4Pa8qgq1Hl9ZKBtN708ZXPzlAGR/jxofrD4QNT8SHowIDVA== + dependencies: + fp-ts "^1.0.1" + io-ts "^1.0.2" + +io-ts@^1.0.2, io-ts@^1.0.5: + version "1.8.6" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.8.6.tgz#43930e025b88bbb317cb193bd9af784322a6fed6" + integrity sha512-0V0gbEfW5FnlEL++hO+j1cbxSvhH3f/i5Puz5AjmN6Q071vJONWTuOHttMSe60gi4DBHBTd2eHbSnHv37ptTnQ== + dependencies: + fp-ts "^1.0.0" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.0, ipaddr.js@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" + integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5, is-buffer@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-in-browser@^1.0.2, is-in-browser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" + integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-retry-allowed@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-beautify@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.9.0.tgz#2562fcdee340f9f962ae2ec4a8a40e7aaa6d964f" + integrity sha512-P0skmY4IDjfLiVrx+GLDeme8w5G0R1IGXgccVU5HP2VM3lRblH7qN2LTea5vZAxrDjpZBD0Jv+ahpjwVcbz/rw== + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.2" + glob "^7.1.3" + mkdirp "~0.5.0" + nopt "~4.0.1" + +js-levenshtein@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.12.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jss-camel-case@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-6.1.0.tgz#ccb1ff8d6c701c02a1fed6fb6fb6b7896e11ce44" + integrity sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ== + dependencies: + hyphenate-style-name "^1.0.2" + +jss-default-unit@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-8.0.2.tgz#cc1e889bae4c0b9419327b314ab1c8e2826890e6" + integrity sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg== + +jss-global@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-3.0.0.tgz#e19e5c91ab2b96353c227e30aa2cbd938cdaafa2" + integrity sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q== + +jss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-6.0.1.tgz#ef992b79d6e8f63d939c4397b9d99b5cbbe824ca" + integrity sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA== + dependencies: + warning "^3.0.0" + +jss-props-sort@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-6.0.0.tgz#9105101a3b5071fab61e2d85ea74cc22e9b16323" + integrity sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g== + +jss-vendor-prefixer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz#0166729650015ef19d9f02437c73667231605c71" + integrity sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA== + dependencies: + css-vendor "^0.3.8" + +jss@^9.8.7: + version "9.8.7" + resolved "https://registry.yarnpkg.com/jss/-/jss-9.8.7.tgz#ed9763fc0f2f0260fc8260dac657af61e622ce05" + integrity sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ== + dependencies: + is-in-browser "^1.1.3" + symbol-observable "^1.1.0" + warning "^3.0.0" + +jsx-ast-utils@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz#0ee4e2c971fb9601c67b5641b71be80faecf0b36" + integrity sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA== + dependencies: + array-includes "^3.0.3" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +killable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +listenercount@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-fs-cache@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" + integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "0.5.1" + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + +lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.4, lodash@~4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +loglevel@^1.4.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.3.tgz#77f2eb64be55a404c9fd04ad16d57c1d6d6b1280" + integrity sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1, lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +macos-release@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" + integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-expression-evaluator@^1.2.14: + version "1.2.17" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" + integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw= + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +md5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.40.0, "mime-db@>= 1.40.0 < 2": + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.0.3, mime@^2.4.2: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +most@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/most/-/most-1.7.3.tgz#406c31a66d73aa16957816fdf96965e27df84f1a" + integrity sha512-mk68SM/ptK8WSo3l03raXcWy02Hl7jbzxVozMuvyYxohn4yteh2THhl3+XABF5cunWE8eXHAsLbv+RCJI5y+jg== + dependencies: + "@most/multicast" "^1.2.5" + "@most/prelude" "^1.4.0" + symbol-observable "^1.0.2" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +neo-blessed@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/neo-blessed/-/neo-blessed-0.2.0.tgz#30f9495fdd104494402b62c6273a9c9b82de4f2b" + integrity sha512-C2kC4K+G2QnNQFXUIxTQvqmrdSIzGTX1ZRKeDW6ChmvPRw8rTkTEJzbEQHiHy06d36PCl/yMOCjquCRV8SpSQw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^2.1.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + +node-forge@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" + integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== + +node-libs-browser@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" + integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "0.0.4" + +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.1.23: + version "1.1.23" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.23.tgz#de7409f72de044a2fa59c097f436ba89c39997f0" + integrity sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w== + dependencies: + semver "^5.3.0" + +nopt@^4.0.1, nopt@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-scroll-left@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-scroll-left/-/normalize-scroll-left-0.1.2.tgz#6b79691ba79eb5fb107fa5edfbdc06b55caee2aa" + integrity sha512-F9YMRls0zCF6BFIE2YnXDRpHPpfd91nOIaNdDgrx5YMoPLo8Wqj+6jNXHQsYBavJeXP4ww8HCt0xQAKc5qk2Fg== + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.entries@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519" + integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +object.fromentries@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" + integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA== + dependencies: + define-properties "^1.1.2" + es-abstract "^1.11.0" + function-bind "^1.1.1" + has "^1.0.1" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opn@^5.1.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-name@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" + integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== + dependencies: + macos-release "^2.2.0" + windows-release "^3.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= + dependencies: + process "^0.11.1" + util "^0.10.3" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +popper.js@^1.14.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" + integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== + +portfinder@^1.0.9: + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" + integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-value-parser "^3.3.1" + +postcss-modules-scope@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz#ad3f5bf7856114f6fcab901b0502e2a2bc39d4eb" + integrity sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" + integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^7.0.6" + +postcss-selector-parser@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.17" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" + integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +private@^0.1.6: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.1, process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +prop-types@~15.6.0: + version "15.6.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +proxy-addr@~2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" + integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.0" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +raf@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@16.8.4: + version "16.8.4" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.4.tgz#1061a8e01a2b3b0c8160037441c3bf00a0e3bc48" + integrity sha512-Ob2wK7XG2tUDt7ps7LtLzGYYB6DXMCLj0G5fO6WeEICtT4/HdpOi7W/xLzZnR6RCG1tYza60nMdqtxzA8FaPJQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.4" + +react-event-listener@^0.6.2: + version "0.6.6" + resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a" + integrity sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw== + dependencies: + "@babel/runtime" "^7.2.0" + prop-types "^15.6.0" + warning "^4.0.1" + +react-hot-loader@4.8.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.8.0.tgz#0b7c7dd9407415e23eb8246fdd28b0b839f54cb6" + integrity sha512-HY9F0vITYSVmXhAR6tPkMk240nxmoH8+0rca9iO2B82KVguiCiBJkieS0Wb4CeSIzLWecYx3iOcq8dcbnp0bxA== + dependencies: + fast-levenshtein "^2.0.6" + global "^4.3.0" + hoist-non-react-statics "^3.3.0" + loader-utils "^1.1.0" + lodash "^4.17.11" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.0.2" + source-map "^0.7.3" + +react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + +react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-resize-detector@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-2.3.0.tgz#57bad1ae26a28a62a2ddb678ba6ffdf8fa2b599c" + integrity sha512-oCAddEWWeFWYH5FAcHdBYcZjAw9fMzRUK9sWSx6WvSSOPVRxcHd5zTIGy/mOus+AhN/u6T4TMiWxvq79PywnJQ== + dependencies: + lodash.debounce "^4.0.8" + lodash.throttle "^4.1.1" + prop-types "^15.6.0" + resize-observer-polyfill "^1.5.0" + +react-smooth@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-1.0.2.tgz#f7a2d932ece8db898646078c3c97f3e9533e0486" + integrity sha512-pIGzL1g9VGAsRsdZQokIK0vrCkcdKtnOnS1gyB2rrowdLy69lNSWoIjCTWAfgbiYvria8tm5hEZqj+jwXMkV4A== + dependencies: + lodash "~4.17.4" + prop-types "^15.6.0" + raf "^3.4.0" + react-transition-group "^2.5.0" + +react-transition-group@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.6.1.tgz#abf4a95e2f13fb9ba83a970a896fedbc5c4856a2" + integrity sha512-9DHwCy0aOYEe35frlEN68N9ut/THDQBLnVoQuKTvzF4/s3tk7lqkefCqxK2Nv96fOh6JXk6tQtliygk6tl3bQA== + dependencies: + dom-helpers "^3.3.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react-transition-group@^2.2.1, react-transition-group@^2.5.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react@16.8.4: + version "16.8.4" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.4.tgz#fdf7bd9ae53f03a9c4cd1a371432c206be1c4768" + integrity sha512-0GQ6gFXfUH7aZcjGVymlPOASTuSjlQL4ZtVC5YKH+3JL6bBLCVO21DknzmaPlI90LN253ojj02nsapy+j7wIjg== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.4" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recharts-scale@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.2.tgz#b66315d985cd9b80d5f7d977a5aab9a305abc354" + integrity sha512-p/cKt7j17D1CImLgX2f5+6IXLbRHGUQkogIp06VUoci/XkhOQiGSzUrsD1uRmiI7jha4u8XNFOjkHkzzBPivMg== + dependencies: + decimal.js-light "^2.4.1" + +recharts@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-1.5.0.tgz#ecb4f015cec5b1284294954b7906c7c2ec6e25be" + integrity sha512-bsKJRvh4NepPJlXoI4L9oRKhrv59W7fjs6qTqk6le9MFAywe8EYiW/t07RDQHBVIj6icb+UdSFsHxEo8c5AcTg== + dependencies: + classnames "~2.2.5" + core-js "~2.5.1" + d3-interpolate "~1.3.0" + d3-scale "~2.1.0" + d3-shape "~1.2.0" + lodash "~4.17.5" + prop-types "~15.6.0" + react-resize-detector "~2.3.0" + react-smooth "~1.0.0" + recharts-scale "^0.4.2" + reduce-css-calc "~1.3.0" + +"recompose@0.28.0 - 0.30.0": + version "0.30.0" + resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.30.0.tgz#82773641b3927e8c7d24a0d87d65aeeba18aabd0" + integrity sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w== + dependencies: + "@babel/runtime" "^7.0.0" + change-emitter "^0.1.2" + fbjs "^0.8.1" + hoist-non-react-statics "^2.3.1" + react-lifecycles-compat "^3.0.2" + symbol-observable "^1.0.4" + +reduce-css-calc@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" + integrity sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk= + dependencies: + balanced-match "^0.4.2" + +regenerate-unicode-properties@^8.0.2: + version "8.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" + integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + +regenerator-transform@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" + integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== + dependencies: + private "^0.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp-tree@^0.1.6: + version "0.1.10" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc" + integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ== + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" + integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.0.2" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resize-observer-polyfill@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + dependencies: + path-parse "^1.0.6" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.4.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" + integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@>=5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scheduler@^0.13.4: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.9.1: + version "1.10.4" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" + integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== + dependencies: + node-forge "0.7.5" + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" + integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== + +serve-index@^1.7.2: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5, setimmediate@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallowequal@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.2.0, socket.io-client@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.2.0.tgz#84e73ee3c43d5020ccc1a258faeeb9aec2723af7" + integrity sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.3.1" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.2.0.tgz#f0f633161ef6712c972b307598ecd08c9b1b4d5b" + integrity sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w== + dependencies: + debug "~4.1.0" + engine.io "~3.3.1" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.2.0" + socket.io-parser "~3.3.0" + +sockjs-client@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" + integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.10: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52" + integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.2.0, symbol-observable@^1.0.2, symbol-observable@^1.0.4, symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +table@^5.0.2, table@^5.2.3: + version "5.4.0" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.0.tgz#d772a3216e68829920a41a32c18eda286c95d780" + integrity sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw== + dependencies: + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar@^4: + version "4.4.10" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" + integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.5" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4" + integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg== + dependencies: + cacache "^11.3.2" + find-cache-dir "^2.0.0" + is-wsl "^1.1.0" + loader-utils "^1.2.3" + schema-utils "^1.0.0" + serialize-javascript "^1.7.0" + source-map "^0.6.1" + terser "^4.0.0" + webpack-sources "^1.3.0" + worker-farm "^1.7.0" + +terser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.0.0.tgz#ef356f6f359a963e2cc675517f21c1c382877374" + integrity sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA== + dependencies: + commander "^2.19.0" + source-map "~0.6.1" + source-map-support "~0.5.10" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6, through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" + integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@^0.7.18: + version "0.7.20" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" + integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== + +uglify-js@^3.1.4: + version "3.6.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" + integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + dependencies: + commander "~2.20.0" + source-map "~0.6.1" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" + integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universal-user-agent@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4" + integrity sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q== + dependencies: + os-name "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzipper@^0.9.3: + version "0.9.15" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.9.15.tgz#97d99203dad17698ee39882483c14e4845c7549c" + integrity sha512-2aaUvO4RAeHDvOCuEtth7jrHFaCKTSXPqUkXwADaLBzGbgZGzUDccoEdJ5lW+3RmfpOZYNx0Rw6F6PUzM6caIA== + dependencies: + big-integer "^1.6.17" + binary "~0.3.0" + bluebird "~3.4.1" + buffer-indexof-polyfill "~1.0.0" + duplexer2 "~0.1.4" + fstream "^1.0.12" + listenercount "~1.0.1" + readable-stream "~2.3.6" + setimmediate "~1.0.4" + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +v8-compile-cache@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + +warning@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.2.3.tgz#13653549adfd8ccd920ad7be1ef868bacc22e346" + integrity sha512-Ik3SjV6uJtWIAN5jp5ZuBMWEAaP5E4V78XJ2nI+paFPh8v4HPSwo/myN0r29Xc/6ZKnd2IdrAlpSgNOu2CDQ6Q== + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + findup-sync "^2.0.0" + global-modules "^1.0.0" + import-local "^2.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.4" + +webpack-dashboard@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/webpack-dashboard/-/webpack-dashboard-3.0.0.tgz#14b2374841efd9b28d0368f07a38bc1af43970e1" + integrity sha512-OtqccZJLR9CPbn86p6iwXWrseh944AkNj0AzrNvC7j4x+yHjmX1dlDpyo1f35GwY6F9eBWpMffUoGeWrFjLNUA== + dependencies: + commander "^2.15.1" + cross-spawn "^6.0.5" + filesize "^3.6.1" + handlebars "^4.0.11" + inspectpack "^4.0.0" + most "^1.7.3" + neo-blessed "^0.2.0" + socket.io "^2.1.1" + socket.io-client "^2.1.1" + +webpack-dev-middleware@^3.5.1: + version "3.7.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz#ef751d25f4e9a5c8a35da600c5fda3582b5c6cff" + integrity sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.2" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.2.1.tgz#1b45ce3ecfc55b6ebe5e36dab2777c02bc508c4e" + integrity sha512-sjuE4mnmx6JOh9kvSbPYw3u/6uxCLHNWfhWaIPwcXWsvWOPN+nc5baq4i9jui3oOBRXGonK9+OI0jVkaz6/rCw== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.0.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + debug "^4.1.1" + del "^3.0.0" + express "^4.16.2" + html-entities "^1.2.0" + http-proxy-middleware "^0.19.1" + import-local "^2.0.0" + internal-ip "^4.2.0" + ip "^1.1.5" + killable "^1.0.0" + loglevel "^1.4.1" + opn "^5.1.0" + portfinder "^1.0.9" + schema-utils "^1.0.0" + selfsigned "^1.9.1" + semver "^5.6.0" + serve-index "^1.7.2" + sockjs "0.3.19" + sockjs-client "1.3.0" + spdy "^4.0.0" + strip-ansi "^3.0.0" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.5.1" + webpack-log "^2.0.0" + yargs "12.0.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4" + integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw== + dependencies: + lodash "^4.17.5" + +webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@4.29.6: + version "4.29.6" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.29.6.tgz#66bf0ec8beee4d469f8b598d3988ff9d8d90e955" + integrity sha512-MwBwpiE1BQpMDkbnUUaW6K8RFZjljJHArC6tWQJoFm0oQtfoSebtg4Y7/QHnJ/SddtjYLHaKGX64CFjG5rehJw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^1.0.0" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +websocket-driver@>=0.5.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.1.tgz#d58fa3269f51e480f5af051db7f5c5c1a1092d20" + integrity sha512-EC4YX5LEHtiB1XjaCh6++35jGaFmhT7687pySyCfPX9bB8Quw7+Fpx8gSCpkD78tPjalxuoOm8TtTz8K4dAQEg== + dependencies: + http-parser-js ">=0.4.0" + safe-buffer ">=5.1.1" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +whatwg-fetch@>=0.10.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +windows-release@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" + integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== + dependencies: + execa "^1.0.0" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs@12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + +yargs@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@^12.0.2, yargs@^12.0.4: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= diff --git a/vendor/github.com/ethereum/go-ethereum/eth/api_backend.go b/vendor/github.com/ethereum/go-ethereum/eth/api_backend.go new file mode 100644 index 00000000..db0e8cf4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/api_backend.go @@ -0,0 +1,244 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package eth + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +// EthAPIBackend implements ethapi.Backend for full nodes +type EthAPIBackend struct { + extRPCEnabled bool + eth *Ethereum + gpo *gasprice.Oracle +} + +// ChainConfig returns the active chain configuration. +func (b *EthAPIBackend) ChainConfig() *params.ChainConfig { + return b.eth.blockchain.Config() +} + +func (b *EthAPIBackend) CurrentBlock() *types.Block { + return b.eth.blockchain.CurrentBlock() +} + +func (b *EthAPIBackend) SetHead(number uint64) { + b.eth.protocolManager.downloader.Cancel() + b.eth.blockchain.SetHead(number) +} + +func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { + // Pending block is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block := b.eth.miner.PendingBlock() + return block.Header(), nil + } + // Otherwise resolve and return the block + if blockNr == rpc.LatestBlockNumber { + return b.eth.blockchain.CurrentBlock().Header(), nil + } + return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)), nil +} + +func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return b.eth.blockchain.GetHeaderByHash(hash), nil +} + +func (b *EthAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { + // Pending block is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block := b.eth.miner.PendingBlock() + return block, nil + } + // Otherwise resolve and return the block + if blockNr == rpc.LatestBlockNumber { + return b.eth.blockchain.CurrentBlock(), nil + } + return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil +} + +func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { + // Pending state is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block, state := b.eth.miner.Pending() + return state, block.Header(), nil + } + // Otherwise resolve the block number and return its state + header, err := b.HeaderByNumber(ctx, blockNr) + if err != nil { + return nil, nil, err + } + if header == nil { + return nil, nil, errors.New("header not found") + } + stateDb, err := b.eth.BlockChain().StateAt(header.Root) + return stateDb, header, err +} + +func (b *EthAPIBackend) GetBlock(ctx context.Context, hash common.Hash) (*types.Block, error) { + return b.eth.blockchain.GetBlockByHash(hash), nil +} + +func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { + return b.eth.blockchain.GetReceiptsByHash(hash), nil +} + +func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { + receipts := b.eth.blockchain.GetReceiptsByHash(hash) + if receipts == nil { + return nil, nil + } + logs := make([][]*types.Log, len(receipts)) + for i, receipt := range receipts { + logs[i] = receipt.Logs + } + return logs, nil +} + +func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int { + return b.eth.blockchain.GetTdByHash(blockHash) +} + +func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) { + state.SetBalance(msg.From(), math.MaxBig256) + vmError := func() error { return nil } + + context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) + return vm.NewEVM(context, state, b.eth.blockchain.Config(), *b.eth.blockchain.GetVMConfig()), vmError, nil +} + +func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { + return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch) +} + +func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + return b.eth.BlockChain().SubscribeChainEvent(ch) +} + +func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { + return b.eth.BlockChain().SubscribeChainHeadEvent(ch) +} + +func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { + return b.eth.BlockChain().SubscribeChainSideEvent(ch) +} + +func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + return b.eth.BlockChain().SubscribeLogsEvent(ch) +} + +func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + return b.eth.txPool.AddLocal(signedTx) +} + +func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) { + pending, err := b.eth.txPool.Pending() + if err != nil { + return nil, err + } + var txs types.Transactions + for _, batch := range pending { + txs = append(txs, batch...) + } + return txs, nil +} + +func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction { + return b.eth.txPool.Get(hash) +} + +func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) { + tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash) + return tx, blockHash, blockNumber, index, nil +} + +func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { + return b.eth.txPool.State().GetNonce(addr), nil +} + +func (b *EthAPIBackend) Stats() (pending int, queued int) { + return b.eth.txPool.Stats() +} + +func (b *EthAPIBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { + return b.eth.TxPool().Content() +} + +func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { + return b.eth.TxPool().SubscribeNewTxsEvent(ch) +} + +func (b *EthAPIBackend) Downloader() *downloader.Downloader { + return b.eth.Downloader() +} + +func (b *EthAPIBackend) ProtocolVersion() int { + return b.eth.EthVersion() +} + +func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { + return b.gpo.SuggestPrice(ctx) +} + +func (b *EthAPIBackend) ChainDb() ethdb.Database { + return b.eth.ChainDb() +} + +func (b *EthAPIBackend) EventMux() *event.TypeMux { + return b.eth.EventMux() +} + +func (b *EthAPIBackend) AccountManager() *accounts.Manager { + return b.eth.AccountManager() +} + +func (b *EthAPIBackend) ExtRPCEnabled() bool { + return b.extRPCEnabled +} + +func (b *EthAPIBackend) RPCGasCap() *big.Int { + return b.eth.config.RPCGasCap +} + +func (b *EthAPIBackend) BloomStatus() (uint64, uint64) { + sections, _, _ := b.eth.bloomIndexer.Sections() + return params.BloomBitsBlocks, sections +} + +func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { + for i := 0; i < bloomFilterThreads; i++ { + go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/backend.go b/vendor/github.com/ethereum/go-ethereum/eth/backend.go new file mode 100644 index 00000000..f3c7b58d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/backend.go @@ -0,0 +1,538 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package eth implements the Ethereum protocol. +package eth + +import ( + "errors" + "fmt" + "math/big" + "runtime" + "sync" + "sync/atomic" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" +) + +type LesServer interface { + Start(srvr *p2p.Server) + Stop() + APIs() []rpc.API + Protocols() []p2p.Protocol + SetBloomBitsIndexer(bbIndexer *core.ChainIndexer) +} + +// Ethereum implements the Ethereum full node service. +type Ethereum struct { + config *Config + + // Channel for shutting down the service + shutdownChan chan bool // Channel for shutting down the Ethereum + + // Handlers + txPool *core.TxPool + blockchain *core.BlockChain + protocolManager *ProtocolManager + lesServer LesServer + + // DB interfaces + chainDb ethdb.Database // Block chain database + + eventMux *event.TypeMux + engine consensus.Engine + accountManager *accounts.Manager + + bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests + bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports + + APIBackend *EthAPIBackend + + miner *miner.Miner + gasPrice *big.Int + etherbase common.Address + + networkID uint64 + netRPCService *ethapi.PublicNetAPI + + lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) +} + +func (s *Ethereum) AddLesServer(ls LesServer) { + s.lesServer = ls + ls.SetBloomBitsIndexer(s.bloomIndexer) +} + +// New creates a new Ethereum object (including the +// initialisation of the common Ethereum object) +func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { + // Ensure configuration values are compatible and sane + if config.SyncMode == downloader.LightSync { + return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum") + } + if !config.SyncMode.IsValid() { + return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) + } + if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 { + log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", DefaultConfig.Miner.GasPrice) + config.Miner.GasPrice = new(big.Int).Set(DefaultConfig.Miner.GasPrice) + } + if config.NoPruning && config.TrieDirtyCache > 0 { + config.TrieCleanCache += config.TrieDirtyCache + config.TrieDirtyCache = 0 + } + log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024) + + // Assemble the Ethereum object + chainDb, err := ctx.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/") + if err != nil { + return nil, err + } + chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.ConstantinopleOverride) + if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { + return nil, genesisErr + } + log.Info("Initialised chain configuration", "config", chainConfig) + + eth := &Ethereum{ + config: config, + chainDb: chainDb, + eventMux: ctx.EventMux, + accountManager: ctx.AccountManager, + engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb), + shutdownChan: make(chan bool), + networkID: config.NetworkId, + gasPrice: config.Miner.GasPrice, + etherbase: config.Miner.Etherbase, + bloomRequests: make(chan chan *bloombits.Retrieval), + bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), + } + + bcVersion := rawdb.ReadDatabaseVersion(chainDb) + var dbVer = "" + if bcVersion != nil { + dbVer = fmt.Sprintf("%d", *bcVersion) + } + log.Info("Initialising Ethereum protocol", "versions", ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) + + if !config.SkipBcVersionCheck { + if bcVersion != nil && *bcVersion > core.BlockChainVersion { + return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, params.VersionWithMeta, core.BlockChainVersion) + } else if bcVersion == nil || *bcVersion < core.BlockChainVersion { + log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion) + rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion) + } + } + var ( + vmConfig = vm.Config{ + EnablePreimageRecording: config.EnablePreimageRecording, + EWASMInterpreter: config.EWASMInterpreter, + EVMInterpreter: config.EVMInterpreter, + } + cacheConfig = &core.CacheConfig{ + TrieCleanLimit: config.TrieCleanCache, + TrieCleanNoPrefetch: config.NoPrefetch, + TrieDirtyLimit: config.TrieDirtyCache, + TrieDirtyDisabled: config.NoPruning, + TrieTimeLimit: config.TrieTimeout, + ProcessingStateDiffs: config.StateDiff, + } + ) + eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve) + if err != nil { + return nil, err + } + // Rewind the chain in case of an incompatible config upgrade. + if compat, ok := genesisErr.(*params.ConfigCompatError); ok { + log.Warn("Rewinding chain to upgrade configuration", "err", compat) + eth.blockchain.SetHead(compat.RewindTo) + rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) + } + eth.bloomIndexer.Start(eth.blockchain) + + if config.TxPool.Journal != "" { + config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) + } + eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) + + // Permit the downloader to use the trie cache allowance during fast sync + cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + if eth.protocolManager, err = NewProtocolManager(chainConfig, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist); err != nil { + return nil, err + } + eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) + eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) + + eth.APIBackend = &EthAPIBackend{ctx.ExtRPCEnabled(), eth, nil} + gpoParams := config.GPO + if gpoParams.Default == nil { + gpoParams.Default = config.Miner.GasPrice + } + eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) + + return eth, nil +} + +func makeExtraData(extra []byte) []byte { + if len(extra) == 0 { + // create default extradata + extra, _ = rlp.EncodeToBytes([]interface{}{ + uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch), + "geth", + runtime.Version(), + runtime.GOOS, + }) + } + if uint64(len(extra)) > params.MaximumExtraDataSize { + log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.MaximumExtraDataSize) + extra = nil + } + return extra +} + +// CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service +func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { + // If proof-of-authority is requested, set it up + if chainConfig.Clique != nil { + return clique.New(chainConfig.Clique, db) + } + // Otherwise assume proof-of-work + switch config.PowMode { + case ethash.ModeFake: + log.Warn("Ethash used in fake mode") + return ethash.NewFaker() + case ethash.ModeTest: + log.Warn("Ethash used in test mode") + return ethash.NewTester(nil, noverify) + case ethash.ModeShared: + log.Warn("Ethash used in shared mode") + return ethash.NewShared() + default: + engine := ethash.New(ethash.Config{ + CacheDir: ctx.ResolvePath(config.CacheDir), + CachesInMem: config.CachesInMem, + CachesOnDisk: config.CachesOnDisk, + DatasetDir: config.DatasetDir, + DatasetsInMem: config.DatasetsInMem, + DatasetsOnDisk: config.DatasetsOnDisk, + }, notify, noverify) + engine.SetThreads(-1) // Disable CPU mining + return engine + } +} + +// APIs return the collection of RPC services the ethereum package offers. +// NOTE, some of these services probably need to be moved to somewhere else. +func (s *Ethereum) APIs() []rpc.API { + apis := ethapi.GetAPIs(s.APIBackend) + + // Append any APIs exposed explicitly by the les server + if s.lesServer != nil { + apis = append(apis, s.lesServer.APIs()...) + } + // Append any APIs exposed explicitly by the consensus engine + apis = append(apis, s.engine.APIs(s.BlockChain())...) + + // Append all the local APIs and return + return append(apis, []rpc.API{ + { + Namespace: "eth", + Version: "1.0", + Service: NewPublicEthereumAPI(s), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicMinerAPI(s), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), + Public: true, + }, { + Namespace: "miner", + Version: "1.0", + Service: NewPrivateMinerAPI(s), + Public: false, + }, { + Namespace: "eth", + Version: "1.0", + Service: filters.NewPublicFilterAPI(s.APIBackend, false), + Public: true, + }, { + Namespace: "admin", + Version: "1.0", + Service: NewPrivateAdminAPI(s), + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPublicDebugAPI(s), + Public: true, + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPrivateDebugAPI(s), + }, { + Namespace: "net", + Version: "1.0", + Service: s.netRPCService, + Public: true, + }, + }...) +} + +func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { + s.blockchain.ResetWithGenesisBlock(gb) +} + +func (s *Ethereum) Etherbase() (eb common.Address, err error) { + s.lock.RLock() + etherbase := s.etherbase + s.lock.RUnlock() + + if etherbase != (common.Address{}) { + return etherbase, nil + } + if wallets := s.AccountManager().Wallets(); len(wallets) > 0 { + if accounts := wallets[0].Accounts(); len(accounts) > 0 { + etherbase := accounts[0].Address + + s.lock.Lock() + s.etherbase = etherbase + s.lock.Unlock() + + log.Info("Etherbase automatically configured", "address", etherbase) + return etherbase, nil + } + } + return common.Address{}, fmt.Errorf("etherbase must be explicitly specified") +} + +// isLocalBlock checks whether the specified block is mined +// by local miner accounts. +// +// We regard two types of accounts as local miner account: etherbase +// and accounts specified via `txpool.locals` flag. +func (s *Ethereum) isLocalBlock(block *types.Block) bool { + author, err := s.engine.Author(block.Header()) + if err != nil { + log.Warn("Failed to retrieve block author", "number", block.NumberU64(), "hash", block.Hash(), "err", err) + return false + } + // Check whether the given address is etherbase. + s.lock.RLock() + etherbase := s.etherbase + s.lock.RUnlock() + if author == etherbase { + return true + } + // Check whether the given address is specified by `txpool.local` + // CLI flag. + for _, account := range s.config.TxPool.Locals { + if account == author { + return true + } + } + return false +} + +// shouldPreserve checks whether we should preserve the given block +// during the chain reorg depending on whether the author of block +// is a local account. +func (s *Ethereum) shouldPreserve(block *types.Block) bool { + // The reason we need to disable the self-reorg preserving for clique + // is it can be probable to introduce a deadlock. + // + // e.g. If there are 7 available signers + // + // r1 A + // r2 B + // r3 C + // r4 D + // r5 A [X] F G + // r6 [X] + // + // In the round5, the inturn signer E is offline, so the worst case + // is A, F and G sign the block of round5 and reject the block of opponents + // and in the round6, the last available signer B is offline, the whole + // network is stuck. + if _, ok := s.engine.(*clique.Clique); ok { + return false + } + return s.isLocalBlock(block) +} + +// SetEtherbase sets the mining reward address. +func (s *Ethereum) SetEtherbase(etherbase common.Address) { + s.lock.Lock() + s.etherbase = etherbase + s.lock.Unlock() + + s.miner.SetEtherbase(etherbase) +} + +// StartMining starts the miner with the given number of CPU threads. If mining +// is already running, this method adjust the number of threads allowed to use +// and updates the minimum price required by the transaction pool. +func (s *Ethereum) StartMining(threads int) error { + // Update the thread count within the consensus engine + type threaded interface { + SetThreads(threads int) + } + if th, ok := s.engine.(threaded); ok { + log.Info("Updated mining threads", "threads", threads) + if threads == 0 { + threads = -1 // Disable the miner from within + } + th.SetThreads(threads) + } + // If the miner was not running, initialize it + if !s.IsMining() { + // Propagate the initial price point to the transaction pool + s.lock.RLock() + price := s.gasPrice + s.lock.RUnlock() + s.txPool.SetGasPrice(price) + + // Configure the local mining address + eb, err := s.Etherbase() + if err != nil { + log.Error("Cannot start mining without etherbase", "err", err) + return fmt.Errorf("etherbase missing: %v", err) + } + if clique, ok := s.engine.(*clique.Clique); ok { + wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) + if wallet == nil || err != nil { + log.Error("Etherbase account unavailable locally", "err", err) + return fmt.Errorf("signer missing: %v", err) + } + clique.Authorize(eb, wallet.SignData) + } + // If mining is started, we can disable the transaction rejection mechanism + // introduced to speed sync times. + atomic.StoreUint32(&s.protocolManager.acceptTxs, 1) + + go s.miner.Start(eb) + } + return nil +} + +// StopMining terminates the miner, both at the consensus engine level as well as +// at the block creation level. +func (s *Ethereum) StopMining() { + // Update the thread count within the consensus engine + type threaded interface { + SetThreads(threads int) + } + if th, ok := s.engine.(threaded); ok { + th.SetThreads(-1) + } + // Stop the block creating itself + s.miner.Stop() +} + +func (s *Ethereum) IsMining() bool { return s.miner.Mining() } +func (s *Ethereum) Miner() *miner.Miner { return s.miner } + +func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } +func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } +func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } +func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } +func (s *Ethereum) Engine() consensus.Engine { return s.engine } +func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } +func (s *Ethereum) IsListening() bool { return true } // Always listening +func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) } +func (s *Ethereum) NetVersion() uint64 { return s.networkID } +func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } +func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.protocolManager.acceptTxs) == 1 } +func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning } + +// Protocols implements node.Service, returning all the currently configured +// network protocols to start. +func (s *Ethereum) Protocols() []p2p.Protocol { + if s.lesServer == nil { + return s.protocolManager.SubProtocols + } + return append(s.protocolManager.SubProtocols, s.lesServer.Protocols()...) +} + +// Start implements node.Service, starting all internal goroutines needed by the +// Ethereum protocol implementation. +func (s *Ethereum) Start(srvr *p2p.Server) error { + // Start the bloom bits servicing goroutines + s.startBloomHandlers(params.BloomBitsBlocks) + + // Start the RPC service + s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion()) + + // Figure out a max peers count based on the server limits + maxPeers := srvr.MaxPeers + if s.config.LightServ > 0 { + if s.config.LightPeers >= srvr.MaxPeers { + return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, srvr.MaxPeers) + } + maxPeers -= s.config.LightPeers + } + // Start the networking layer and the light server if requested + s.protocolManager.Start(maxPeers) + if s.lesServer != nil { + s.lesServer.Start(srvr) + } + return nil +} + +// Stop implements node.Service, terminating all internal goroutines used by the +// Ethereum protocol. +func (s *Ethereum) Stop() error { + s.bloomIndexer.Close() + s.blockchain.Stop() + s.engine.Close() + s.protocolManager.Stop() + if s.lesServer != nil { + s.lesServer.Stop() + } + s.txPool.Stop() + s.miner.Stop() + s.eventMux.Stop() + + s.chainDb.Close() + close(s.shutdownChan) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/config.go b/vendor/github.com/ethereum/go-ethereum/eth/config.go new file mode 100644 index 00000000..cd1d6c28 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/config.go @@ -0,0 +1,156 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package eth + +import ( + "math/big" + "os" + "os/user" + "path/filepath" + "runtime" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/params" +) + +// DefaultConfig contains default settings for use on the Ethereum main net. +var DefaultConfig = Config{ + SyncMode: downloader.FastSync, + Ethash: ethash.Config{ + CacheDir: "ethash", + CachesInMem: 2, + CachesOnDisk: 3, + DatasetsInMem: 1, + DatasetsOnDisk: 2, + }, + NetworkId: 1, + LightPeers: 100, + DatabaseCache: 512, + TrieCleanCache: 256, + TrieDirtyCache: 256, + TrieTimeout: 60 * time.Minute, + Miner: miner.Config{ + GasFloor: 8000000, + GasCeil: 8000000, + GasPrice: big.NewInt(params.GWei), + Recommit: 3 * time.Second, + }, + TxPool: core.DefaultTxPoolConfig, + GPO: gasprice.Config{ + Blocks: 20, + Percentile: 60, + }, + + StateDiff: false, +} + +func init() { + home := os.Getenv("HOME") + if home == "" { + if user, err := user.Current(); err == nil { + home = user.HomeDir + } + } + if runtime.GOOS == "darwin" { + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "Library", "Ethash") + } else if runtime.GOOS == "windows" { + localappdata := os.Getenv("LOCALAPPDATA") + if localappdata != "" { + DefaultConfig.Ethash.DatasetDir = filepath.Join(localappdata, "Ethash") + } else { + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Local", "Ethash") + } + } else { + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, ".ethash") + } +} + +//go:generate gencodec -type Config -formats toml -out gen_config.go + +type Config struct { + // The genesis block, which is inserted if the database is empty. + // If nil, the Ethereum main net block is used. + Genesis *core.Genesis `toml:",omitempty"` + + // Protocol options + NetworkId uint64 // Network ID to use for selecting peers to connect to + SyncMode downloader.SyncMode + + NoPruning bool // Whether to disable pruning and flush everything to disk + NoPrefetch bool // Whether to disable prefetching and only load state on demand + + // Whitelist of required block number -> hash values to accept + Whitelist map[uint64]common.Hash `toml:"-"` + + // Light client options + LightServ int `toml:",omitempty"` // Maximum percentage of time allowed for serving LES requests + LightBandwidthIn int `toml:",omitempty"` // Incoming bandwidth limit for light servers + LightBandwidthOut int `toml:",omitempty"` // Outgoing bandwidth limit for light servers + LightPeers int `toml:",omitempty"` // Maximum number of LES client peers + OnlyAnnounce bool // Maximum number of LES client peers + + // Ultra Light client options + ULC *ULCConfig `toml:",omitempty"` + + // Database options + SkipBcVersionCheck bool `toml:"-"` + DatabaseHandles int `toml:"-"` + DatabaseCache int + DatabaseFreezer string + + TrieCleanCache int + TrieDirtyCache int + TrieTimeout time.Duration + + // Mining options + Miner miner.Config + + // Ethash options + Ethash ethash.Config + + // Transaction pool options + TxPool core.TxPoolConfig + + // Gas Price Oracle options + GPO gasprice.Config + + // Enables tracking of SHA3 preimages in the VM + EnablePreimageRecording bool + + // Miscellaneous options + DocRoot string `toml:"-"` + + // Type of the EWASM interpreter ("" for default) + EWASMInterpreter string + + // Type of the EVM interpreter ("" for default) + EVMInterpreter string + + // Constantinople block override (TODO: remove after the fork) + ConstantinopleOverride *big.Int + + // RPCGasCap is the global gas cap for eth-call variants. + RPCGasCap *big.Int `toml:",omitempty"` + + StateDiff bool +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/downloader/downloader.go b/vendor/github.com/ethereum/go-ethereum/eth/downloader/downloader.go new file mode 100644 index 00000000..874e6e07 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/downloader/downloader.go @@ -0,0 +1,1858 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package downloader contains the manual full chain synchronisation. +package downloader + +import ( + "errors" + "fmt" + "math/big" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie" +) + +var ( + MaxHashFetch = 512 // Amount of hashes to be fetched per retrieval request + MaxBlockFetch = 128 // Amount of blocks to be fetched per retrieval request + MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request + MaxSkeletonSize = 128 // Number of header fetches to need for a skeleton assembly + MaxBodyFetch = 128 // Amount of block bodies to be fetched per retrieval request + MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request + MaxStateFetch = 384 // Amount of node state values to allow fetching per request + + rttMinEstimate = 2 * time.Second // Minimum round-trip time to target for download requests + rttMaxEstimate = 20 * time.Second // Maximum round-trip time to target for download requests + rttMinConfidence = 0.1 // Worse confidence factor in our estimated RTT value + ttlScaling = 3 // Constant scaling factor for RTT -> TTL conversion + ttlLimit = time.Minute // Maximum TTL allowance to prevent reaching crazy timeouts + + qosTuningPeers = 5 // Number of peers to tune based on (best peers) + qosConfidenceCap = 10 // Number of peers above which not to modify RTT confidence + qosTuningImpact = 0.25 // Impact that a new tuning target has on the previous value + + maxQueuedHeaders = 32 * 1024 // [eth/62] Maximum number of headers to queue for import (DOS protection) + maxHeadersProcess = 2048 // Number of header download results to import at once into the chain + maxResultsProcess = 2048 // Number of content download results to import at once into the chain + maxForkAncestry uint64 = params.ImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it) + + reorgProtThreshold = 48 // Threshold number of recent blocks to disable mini reorg protection + reorgProtHeaderDelay = 2 // Number of headers to delay delivering to cover mini reorgs + + fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during fast sync + fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected + fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it + fsHeaderContCheck = 3 * time.Second // Time interval to check for header continuations during state download + fsMinFullBlocks = 64 // Number of blocks to retrieve fully even in fast sync +) + +var ( + errBusy = errors.New("busy") + errUnknownPeer = errors.New("peer is unknown or unhealthy") + errBadPeer = errors.New("action from bad peer ignored") + errStallingPeer = errors.New("peer is stalling") + errUnsyncedPeer = errors.New("unsynced peer") + errNoPeers = errors.New("no peers to keep download active") + errTimeout = errors.New("timeout") + errEmptyHeaderSet = errors.New("empty header set by peer") + errPeersUnavailable = errors.New("no peers available or all tried for download") + errInvalidAncestor = errors.New("retrieved ancestor is invalid") + errInvalidChain = errors.New("retrieved hash chain is invalid") + errInvalidBody = errors.New("retrieved block body is invalid") + errInvalidReceipt = errors.New("retrieved receipt is invalid") + errCancelStateFetch = errors.New("state data download canceled (requested)") + errCancelContentProcessing = errors.New("content processing canceled (requested)") + errCanceled = errors.New("syncing canceled (requested)") + errNoSyncActive = errors.New("no sync active") + errTooOld = errors.New("peer doesn't speak recent enough protocol version (need version >= 62)") +) + +type Downloader struct { + // WARNING: The `rttEstimate` and `rttConfidence` fields are accessed atomically. + // On 32 bit platforms, only 64-bit aligned fields can be atomic. The struct is + // guaranteed to be so aligned, so take advantage of that. For more information, + // see https://golang.org/pkg/sync/atomic/#pkg-note-BUG. + rttEstimate uint64 // Round trip time to target for download requests + rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops) + + mode SyncMode // Synchronisation mode defining the strategy used (per sync cycle) + mux *event.TypeMux // Event multiplexer to announce sync operation events + + checkpoint uint64 // Checkpoint block number to enforce head against (e.g. fast sync) + genesis uint64 // Genesis block number to limit sync to (e.g. light client CHT) + queue *queue // Scheduler for selecting the hashes to download + peers *peerSet // Set of active peers from which download can proceed + + stateDB ethdb.Database // Database to state sync into (and deduplicate via) + stateBloom *trie.SyncBloom // Bloom filter for fast trie node existence checks + + // Statistics + syncStatsChainOrigin uint64 // Origin block number where syncing started at + syncStatsChainHeight uint64 // Highest block number known when syncing started + syncStatsState stateSyncStats + syncStatsLock sync.RWMutex // Lock protecting the sync stats fields + + lightchain LightChain + blockchain BlockChain + + // Callbacks + dropPeer peerDropFn // Drops a peer for misbehaving + + // Status + synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing + synchronising int32 + notified int32 + committed int32 + ancientLimit uint64 // The maximum block number which can be regarded as ancient data. + + // Channels + headerCh chan dataPack // [eth/62] Channel receiving inbound block headers + bodyCh chan dataPack // [eth/62] Channel receiving inbound block bodies + receiptCh chan dataPack // [eth/63] Channel receiving inbound receipts + bodyWakeCh chan bool // [eth/62] Channel to signal the block body fetcher of new tasks + receiptWakeCh chan bool // [eth/63] Channel to signal the receipt fetcher of new tasks + headerProcCh chan []*types.Header // [eth/62] Channel to feed the header processor new tasks + + // for stateFetcher + stateSyncStart chan *stateSync + trackStateReq chan *stateReq + stateCh chan dataPack // [eth/63] Channel receiving inbound node state data + + // Cancellation and termination + cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop) + cancelCh chan struct{} // Channel to cancel mid-flight syncs + cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers + cancelWg sync.WaitGroup // Make sure all fetcher goroutines have exited. + + quitCh chan struct{} // Quit channel to signal termination + quitLock sync.RWMutex // Lock to prevent double closes + + // Testing hooks + syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run + bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch + receiptFetchHook func([]*types.Header) // Method to call upon starting a receipt fetch + chainInsertHook func([]*fetchResult) // Method to call upon inserting a chain of blocks (possibly in multiple invocations) +} + +// LightChain encapsulates functions required to synchronise a light chain. +type LightChain interface { + // HasHeader verifies a header's presence in the local chain. + HasHeader(common.Hash, uint64) bool + + // GetHeaderByHash retrieves a header from the local chain. + GetHeaderByHash(common.Hash) *types.Header + + // CurrentHeader retrieves the head header from the local chain. + CurrentHeader() *types.Header + + // GetTd returns the total difficulty of a local block. + GetTd(common.Hash, uint64) *big.Int + + // InsertHeaderChain inserts a batch of headers into the local chain. + InsertHeaderChain([]*types.Header, int) (int, error) + + // Rollback removes a few recently added elements from the local chain. + Rollback([]common.Hash) +} + +// BlockChain encapsulates functions required to sync a (full or fast) blockchain. +type BlockChain interface { + LightChain + + // HasBlock verifies a block's presence in the local chain. + HasBlock(common.Hash, uint64) bool + + // HasFastBlock verifies a fast block's presence in the local chain. + HasFastBlock(common.Hash, uint64) bool + + // GetBlockByHash retrieves a block from the local chain. + GetBlockByHash(common.Hash) *types.Block + + // CurrentBlock retrieves the head block from the local chain. + CurrentBlock() *types.Block + + // CurrentFastBlock retrieves the head fast block from the local chain. + CurrentFastBlock() *types.Block + + // FastSyncCommitHead directly commits the head block to a certain entity. + FastSyncCommitHead(common.Hash) error + + // InsertChain inserts a batch of blocks into the local chain. + InsertChain(types.Blocks) (int, error) + + // InsertReceiptChain inserts a batch of receipts into the local chain. + InsertReceiptChain(types.Blocks, []types.Receipts, uint64) (int, error) +} + +// New creates a new downloader to fetch hashes and blocks from remote peers. +func New(checkpoint uint64, stateDb ethdb.Database, stateBloom *trie.SyncBloom, mux *event.TypeMux, chain BlockChain, lightchain LightChain, dropPeer peerDropFn) *Downloader { + if lightchain == nil { + lightchain = chain + } + dl := &Downloader{ + stateDB: stateDb, + stateBloom: stateBloom, + mux: mux, + checkpoint: checkpoint, + queue: newQueue(), + peers: newPeerSet(), + rttEstimate: uint64(rttMaxEstimate), + rttConfidence: uint64(1000000), + blockchain: chain, + lightchain: lightchain, + dropPeer: dropPeer, + headerCh: make(chan dataPack, 1), + bodyCh: make(chan dataPack, 1), + receiptCh: make(chan dataPack, 1), + bodyWakeCh: make(chan bool, 1), + receiptWakeCh: make(chan bool, 1), + headerProcCh: make(chan []*types.Header, 1), + quitCh: make(chan struct{}), + stateCh: make(chan dataPack), + stateSyncStart: make(chan *stateSync), + syncStatsState: stateSyncStats{ + processed: rawdb.ReadFastTrieProgress(stateDb), + }, + trackStateReq: make(chan *stateReq), + } + go dl.qosTuner() + go dl.stateFetcher() + return dl +} + +// Progress retrieves the synchronisation boundaries, specifically the origin +// block where synchronisation started at (may have failed/suspended); the block +// or header sync is currently at; and the latest known block which the sync targets. +// +// In addition, during the state download phase of fast synchronisation the number +// of processed and the total number of known states are also returned. Otherwise +// these are zero. +func (d *Downloader) Progress() ethereum.SyncProgress { + // Lock the current stats and return the progress + d.syncStatsLock.RLock() + defer d.syncStatsLock.RUnlock() + + current := uint64(0) + switch { + case d.blockchain != nil && d.mode == FullSync: + current = d.blockchain.CurrentBlock().NumberU64() + case d.blockchain != nil && d.mode == FastSync: + current = d.blockchain.CurrentFastBlock().NumberU64() + case d.lightchain != nil: + current = d.lightchain.CurrentHeader().Number.Uint64() + default: + log.Error("Unknown downloader chain/mode combo", "light", d.lightchain != nil, "full", d.blockchain != nil, "mode", d.mode) + } + return ethereum.SyncProgress{ + StartingBlock: d.syncStatsChainOrigin, + CurrentBlock: current, + HighestBlock: d.syncStatsChainHeight, + PulledStates: d.syncStatsState.processed, + KnownStates: d.syncStatsState.processed + d.syncStatsState.pending, + } +} + +// Synchronising returns whether the downloader is currently retrieving blocks. +func (d *Downloader) Synchronising() bool { + return atomic.LoadInt32(&d.synchronising) > 0 +} + +// RegisterPeer injects a new download peer into the set of block source to be +// used for fetching hashes and blocks from. +func (d *Downloader) RegisterPeer(id string, version int, peer Peer) error { + logger := log.New("peer", id) + logger.Trace("Registering sync peer") + if err := d.peers.Register(newPeerConnection(id, version, peer, logger)); err != nil { + logger.Error("Failed to register sync peer", "err", err) + return err + } + d.qosReduceConfidence() + + return nil +} + +// RegisterLightPeer injects a light client peer, wrapping it so it appears as a regular peer. +func (d *Downloader) RegisterLightPeer(id string, version int, peer LightPeer) error { + return d.RegisterPeer(id, version, &lightPeerWrapper{peer}) +} + +// UnregisterPeer remove a peer from the known list, preventing any action from +// the specified peer. An effort is also made to return any pending fetches into +// the queue. +func (d *Downloader) UnregisterPeer(id string) error { + // Unregister the peer from the active peer set and revoke any fetch tasks + logger := log.New("peer", id) + logger.Trace("Unregistering sync peer") + if err := d.peers.Unregister(id); err != nil { + logger.Error("Failed to unregister sync peer", "err", err) + return err + } + d.queue.Revoke(id) + + return nil +} + +// Synchronise tries to sync up our local block chain with a remote peer, both +// adding various sanity checks as well as wrapping it with various log entries. +func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) error { + err := d.synchronise(id, head, td, mode) + switch err { + case nil: + case errBusy, errCanceled: + + case errTimeout, errBadPeer, errStallingPeer, errUnsyncedPeer, + errEmptyHeaderSet, errPeersUnavailable, errTooOld, + errInvalidAncestor, errInvalidChain: + log.Warn("Synchronisation failed, dropping peer", "peer", id, "err", err) + if d.dropPeer == nil { + // The dropPeer method is nil when `--copydb` is used for a local copy. + // Timeouts can occur if e.g. compaction hits at the wrong time, and can be ignored + log.Warn("Downloader wants to drop peer, but peerdrop-function is not set", "peer", id) + } else { + d.dropPeer(id) + } + default: + log.Warn("Synchronisation failed, retrying", "err", err) + } + return err +} + +// synchronise will select the peer and use it for synchronising. If an empty string is given +// it will use the best peer possible and synchronize if its TD is higher than our own. If any of the +// checks fail an error will be returned. This method is synchronous +func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode SyncMode) error { + // Mock out the synchronisation if testing + if d.synchroniseMock != nil { + return d.synchroniseMock(id, hash) + } + // Make sure only one goroutine is ever allowed past this point at once + if !atomic.CompareAndSwapInt32(&d.synchronising, 0, 1) { + return errBusy + } + defer atomic.StoreInt32(&d.synchronising, 0) + + // Post a user notification of the sync (only once per session) + if atomic.CompareAndSwapInt32(&d.notified, 0, 1) { + log.Info("Block synchronisation started") + } + // If we are already full syncing, but have a fast-sync bloom filter laying + // around, make sure it does't use memory any more. This is a special case + // when the user attempts to fast sync a new empty network. + if mode == FullSync && d.stateBloom != nil { + d.stateBloom.Close() + } + // Reset the queue, peer set and wake channels to clean any internal leftover state + d.queue.Reset() + d.peers.Reset() + + for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { + select { + case <-ch: + default: + } + } + for _, ch := range []chan dataPack{d.headerCh, d.bodyCh, d.receiptCh} { + for empty := false; !empty; { + select { + case <-ch: + default: + empty = true + } + } + } + for empty := false; !empty; { + select { + case <-d.headerProcCh: + default: + empty = true + } + } + // Create cancel channel for aborting mid-flight and mark the master peer + d.cancelLock.Lock() + d.cancelCh = make(chan struct{}) + d.cancelPeer = id + d.cancelLock.Unlock() + + defer d.Cancel() // No matter what, we can't leave the cancel channel open + + // Set the requested sync mode, unless it's forbidden + d.mode = mode + + // Retrieve the origin peer and initiate the downloading process + p := d.peers.Peer(id) + if p == nil { + return errUnknownPeer + } + return d.syncWithPeer(p, hash, td) +} + +// syncWithPeer starts a block synchronization based on the hash chain from the +// specified peer and head hash. +func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.Int) (err error) { + d.mux.Post(StartEvent{}) + defer func() { + // reset on error + if err != nil { + d.mux.Post(FailedEvent{err}) + } else { + latest := d.lightchain.CurrentHeader() + d.mux.Post(DoneEvent{latest}) + } + }() + if p.version < 62 { + return errTooOld + } + + log.Debug("Synchronising with the network", "peer", p.id, "eth", p.version, "head", hash, "td", td, "mode", d.mode) + defer func(start time.Time) { + log.Debug("Synchronisation terminated", "elapsed", common.PrettyDuration(time.Since(start))) + }(time.Now()) + + // Look up the sync boundaries: the common ancestor and the target block + latest, err := d.fetchHeight(p) + if err != nil { + return err + } + height := latest.Number.Uint64() + + origin, err := d.findAncestor(p, latest) + if err != nil { + return err + } + d.syncStatsLock.Lock() + if d.syncStatsChainHeight <= origin || d.syncStatsChainOrigin > origin { + d.syncStatsChainOrigin = origin + } + d.syncStatsChainHeight = height + d.syncStatsLock.Unlock() + + // Ensure our origin point is below any fast sync pivot point + pivot := uint64(0) + if d.mode == FastSync { + if height <= uint64(fsMinFullBlocks) { + origin = 0 + } else { + pivot = height - uint64(fsMinFullBlocks) + if pivot <= origin { + origin = pivot - 1 + } + } + } + d.committed = 1 + if d.mode == FastSync && pivot != 0 { + d.committed = 0 + } + if d.mode == FastSync { + // Set the ancient data limitation. + // If we are running fast sync, all block data older than ancientLimit will be + // written to the ancient store. More recent data will be written to the active + // database and will wait for the freezer to migrate. + // + // If there is a checkpoint available, then calculate the ancientLimit through + // that. Otherwise calculate the ancient limit through the advertised height + // of the remote peer. + // + // The reason for picking checkpoint first is that a malicious peer can give us + // a fake (very high) height, forcing the ancient limit to also be very high. + // The peer would start to feed us valid blocks until head, resulting in all of + // the blocks might be written into the ancient store. A following mini-reorg + // could cause issues. + if d.checkpoint != 0 && d.checkpoint > maxForkAncestry+1 { + d.ancientLimit = d.checkpoint + } else if height > maxForkAncestry+1 { + d.ancientLimit = height - maxForkAncestry - 1 + } + frozen, _ := d.stateDB.Ancients() // Ignore the error here since light client can also hit here. + // If a part of blockchain data has already been written into active store, + // disable the ancient style insertion explicitly. + if origin >= frozen && frozen != 0 { + d.ancientLimit = 0 + log.Info("Disabling direct-ancient mode", "origin", origin, "ancient", frozen-1) + } else if d.ancientLimit > 0 { + log.Debug("Enabling direct-ancient mode", "ancient", d.ancientLimit) + } + // Rewind the ancient store and blockchain if reorg happens. + if origin+1 < frozen { + var hashes []common.Hash + for i := origin + 1; i < d.lightchain.CurrentHeader().Number.Uint64(); i++ { + hashes = append(hashes, rawdb.ReadCanonicalHash(d.stateDB, i)) + } + d.lightchain.Rollback(hashes) + } + } + // Initiate the sync using a concurrent header and content retrieval algorithm + d.queue.Prepare(origin+1, d.mode) + if d.syncInitHook != nil { + d.syncInitHook(origin, height) + } + fetchers := []func() error{ + func() error { return d.fetchHeaders(p, origin+1, pivot) }, // Headers are always retrieved + func() error { return d.fetchBodies(origin + 1) }, // Bodies are retrieved during normal and fast sync + func() error { return d.fetchReceipts(origin + 1) }, // Receipts are retrieved during fast sync + func() error { return d.processHeaders(origin+1, pivot, td) }, + } + if d.mode == FastSync { + fetchers = append(fetchers, func() error { return d.processFastSyncContent(latest) }) + } else if d.mode == FullSync { + fetchers = append(fetchers, d.processFullSyncContent) + } + return d.spawnSync(fetchers) +} + +// spawnSync runs d.process and all given fetcher functions to completion in +// separate goroutines, returning the first error that appears. +func (d *Downloader) spawnSync(fetchers []func() error) error { + errc := make(chan error, len(fetchers)) + d.cancelWg.Add(len(fetchers)) + for _, fn := range fetchers { + fn := fn + go func() { defer d.cancelWg.Done(); errc <- fn() }() + } + // Wait for the first error, then terminate the others. + var err error + for i := 0; i < len(fetchers); i++ { + if i == len(fetchers)-1 { + // Close the queue when all fetchers have exited. + // This will cause the block processor to end when + // it has processed the queue. + d.queue.Close() + } + if err = <-errc; err != nil && err != errCanceled { + break + } + } + d.queue.Close() + d.Cancel() + return err +} + +// cancel aborts all of the operations and resets the queue. However, cancel does +// not wait for the running download goroutines to finish. This method should be +// used when cancelling the downloads from inside the downloader. +func (d *Downloader) cancel() { + // Close the current cancel channel + d.cancelLock.Lock() + if d.cancelCh != nil { + select { + case <-d.cancelCh: + // Channel was already closed + default: + close(d.cancelCh) + } + } + d.cancelLock.Unlock() +} + +// Cancel aborts all of the operations and waits for all download goroutines to +// finish before returning. +func (d *Downloader) Cancel() { + d.cancel() + d.cancelWg.Wait() + + d.ancientLimit = 0 + log.Debug("Reset ancient limit to zero") +} + +// Terminate interrupts the downloader, canceling all pending operations. +// The downloader cannot be reused after calling Terminate. +func (d *Downloader) Terminate() { + // Close the termination channel (make sure double close is allowed) + d.quitLock.Lock() + select { + case <-d.quitCh: + default: + close(d.quitCh) + } + d.quitLock.Unlock() + + // Cancel any pending download requests + d.Cancel() +} + +// fetchHeight retrieves the head header of the remote peer to aid in estimating +// the total time a pending synchronisation would take. +func (d *Downloader) fetchHeight(p *peerConnection) (*types.Header, error) { + p.log.Debug("Retrieving remote chain height") + + // Request the advertised remote head block and wait for the response + head, _ := p.peer.Head() + go p.peer.RequestHeadersByHash(head, 1, 0, false) + + ttl := d.requestTTL() + timeout := time.After(ttl) + for { + select { + case <-d.cancelCh: + return nil, errCanceled + + case packet := <-d.headerCh: + // Discard anything not from the origin peer + if packet.PeerId() != p.id { + log.Debug("Received headers from incorrect peer", "peer", packet.PeerId()) + break + } + // Make sure the peer actually gave something valid + headers := packet.(*headerPack).headers + if len(headers) != 1 { + p.log.Debug("Multiple headers for single request", "headers", len(headers)) + return nil, errBadPeer + } + head := headers[0] + if (d.mode == FastSync || d.mode == LightSync) && head.Number.Uint64() < d.checkpoint { + p.log.Warn("Remote head below checkpoint", "number", head.Number, "hash", head.Hash()) + return nil, errUnsyncedPeer + } + p.log.Debug("Remote head header identified", "number", head.Number, "hash", head.Hash()) + return head, nil + + case <-timeout: + p.log.Debug("Waiting for head header timed out", "elapsed", ttl) + return nil, errTimeout + + case <-d.bodyCh: + case <-d.receiptCh: + // Out of bounds delivery, ignore + } + } +} + +// calculateRequestSpan calculates what headers to request from a peer when trying to determine the +// common ancestor. +// It returns parameters to be used for peer.RequestHeadersByNumber: +// from - starting block number +// count - number of headers to request +// skip - number of headers to skip +// and also returns 'max', the last block which is expected to be returned by the remote peers, +// given the (from,count,skip) +func calculateRequestSpan(remoteHeight, localHeight uint64) (int64, int, int, uint64) { + var ( + from int + count int + MaxCount = MaxHeaderFetch / 16 + ) + // requestHead is the highest block that we will ask for. If requestHead is not offset, + // the highest block that we will get is 16 blocks back from head, which means we + // will fetch 14 or 15 blocks unnecessarily in the case the height difference + // between us and the peer is 1-2 blocks, which is most common + requestHead := int(remoteHeight) - 1 + if requestHead < 0 { + requestHead = 0 + } + // requestBottom is the lowest block we want included in the query + // Ideally, we want to include just below own head + requestBottom := int(localHeight - 1) + if requestBottom < 0 { + requestBottom = 0 + } + totalSpan := requestHead - requestBottom + span := 1 + totalSpan/MaxCount + if span < 2 { + span = 2 + } + if span > 16 { + span = 16 + } + + count = 1 + totalSpan/span + if count > MaxCount { + count = MaxCount + } + if count < 2 { + count = 2 + } + from = requestHead - (count-1)*span + if from < 0 { + from = 0 + } + max := from + (count-1)*span + return int64(from), count, span - 1, uint64(max) +} + +// findAncestor tries to locate the common ancestor link of the local chain and +// a remote peers blockchain. In the general case when our node was in sync and +// on the correct chain, checking the top N links should already get us a match. +// In the rare scenario when we ended up on a long reorganisation (i.e. none of +// the head links match), we do a binary search to find the common ancestor. +func (d *Downloader) findAncestor(p *peerConnection, remoteHeader *types.Header) (uint64, error) { + // Figure out the valid ancestor range to prevent rewrite attacks + var ( + floor = int64(-1) + localHeight uint64 + remoteHeight = remoteHeader.Number.Uint64() + ) + switch d.mode { + case FullSync: + localHeight = d.blockchain.CurrentBlock().NumberU64() + case FastSync: + localHeight = d.blockchain.CurrentFastBlock().NumberU64() + default: + localHeight = d.lightchain.CurrentHeader().Number.Uint64() + } + p.log.Debug("Looking for common ancestor", "local", localHeight, "remote", remoteHeight) + + // Recap floor value for binary search + if localHeight >= maxForkAncestry { + // We're above the max reorg threshold, find the earliest fork point + floor = int64(localHeight - maxForkAncestry) + } + // If we're doing a light sync, ensure the floor doesn't go below the CHT, as + // all headers before that point will be missing. + if d.mode == LightSync { + // If we dont know the current CHT position, find it + if d.genesis == 0 { + header := d.lightchain.CurrentHeader() + for header != nil { + d.genesis = header.Number.Uint64() + if floor >= int64(d.genesis)-1 { + break + } + header = d.lightchain.GetHeaderByHash(header.ParentHash) + } + } + // We already know the "genesis" block number, cap floor to that + if floor < int64(d.genesis)-1 { + floor = int64(d.genesis) - 1 + } + } + + from, count, skip, max := calculateRequestSpan(remoteHeight, localHeight) + + p.log.Trace("Span searching for common ancestor", "count", count, "from", from, "skip", skip) + go p.peer.RequestHeadersByNumber(uint64(from), count, skip, false) + + // Wait for the remote response to the head fetch + number, hash := uint64(0), common.Hash{} + + ttl := d.requestTTL() + timeout := time.After(ttl) + + for finished := false; !finished; { + select { + case <-d.cancelCh: + return 0, errCanceled + + case packet := <-d.headerCh: + // Discard anything not from the origin peer + if packet.PeerId() != p.id { + log.Debug("Received headers from incorrect peer", "peer", packet.PeerId()) + break + } + // Make sure the peer actually gave something valid + headers := packet.(*headerPack).headers + if len(headers) == 0 { + p.log.Warn("Empty head header set") + return 0, errEmptyHeaderSet + } + // Make sure the peer's reply conforms to the request + for i, header := range headers { + expectNumber := from + int64(i)*int64(skip+1) + if number := header.Number.Int64(); number != expectNumber { + p.log.Warn("Head headers broke chain ordering", "index", i, "requested", expectNumber, "received", number) + return 0, errInvalidChain + } + } + // Check if a common ancestor was found + finished = true + for i := len(headers) - 1; i >= 0; i-- { + // Skip any headers that underflow/overflow our requested set + if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > max { + continue + } + // Otherwise check if we already know the header or not + h := headers[i].Hash() + n := headers[i].Number.Uint64() + + var known bool + switch d.mode { + case FullSync: + known = d.blockchain.HasBlock(h, n) + case FastSync: + known = d.blockchain.HasFastBlock(h, n) + default: + known = d.lightchain.HasHeader(h, n) + } + if known { + number, hash = n, h + break + } + } + + case <-timeout: + p.log.Debug("Waiting for head header timed out", "elapsed", ttl) + return 0, errTimeout + + case <-d.bodyCh: + case <-d.receiptCh: + // Out of bounds delivery, ignore + } + } + // If the head fetch already found an ancestor, return + if hash != (common.Hash{}) { + if int64(number) <= floor { + p.log.Warn("Ancestor below allowance", "number", number, "hash", hash, "allowance", floor) + return 0, errInvalidAncestor + } + p.log.Debug("Found common ancestor", "number", number, "hash", hash) + return number, nil + } + // Ancestor not found, we need to binary search over our chain + start, end := uint64(0), remoteHeight + if floor > 0 { + start = uint64(floor) + } + p.log.Trace("Binary searching for common ancestor", "start", start, "end", end) + + for start+1 < end { + // Split our chain interval in two, and request the hash to cross check + check := (start + end) / 2 + + ttl := d.requestTTL() + timeout := time.After(ttl) + + go p.peer.RequestHeadersByNumber(check, 1, 0, false) + + // Wait until a reply arrives to this request + for arrived := false; !arrived; { + select { + case <-d.cancelCh: + return 0, errCanceled + + case packer := <-d.headerCh: + // Discard anything not from the origin peer + if packer.PeerId() != p.id { + log.Debug("Received headers from incorrect peer", "peer", packer.PeerId()) + break + } + // Make sure the peer actually gave something valid + headers := packer.(*headerPack).headers + if len(headers) != 1 { + p.log.Debug("Multiple headers for single request", "headers", len(headers)) + return 0, errBadPeer + } + arrived = true + + // Modify the search interval based on the response + h := headers[0].Hash() + n := headers[0].Number.Uint64() + + var known bool + switch d.mode { + case FullSync: + known = d.blockchain.HasBlock(h, n) + case FastSync: + known = d.blockchain.HasFastBlock(h, n) + default: + known = d.lightchain.HasHeader(h, n) + } + if !known { + end = check + break + } + header := d.lightchain.GetHeaderByHash(h) // Independent of sync mode, header surely exists + if header.Number.Uint64() != check { + p.log.Debug("Received non requested header", "number", header.Number, "hash", header.Hash(), "request", check) + return 0, errBadPeer + } + start = check + hash = h + + case <-timeout: + p.log.Debug("Waiting for search header timed out", "elapsed", ttl) + return 0, errTimeout + + case <-d.bodyCh: + case <-d.receiptCh: + // Out of bounds delivery, ignore + } + } + } + // Ensure valid ancestry and return + if int64(start) <= floor { + p.log.Warn("Ancestor below allowance", "number", start, "hash", hash, "allowance", floor) + return 0, errInvalidAncestor + } + p.log.Debug("Found common ancestor", "number", start, "hash", hash) + return start, nil +} + +// fetchHeaders keeps retrieving headers concurrently from the number +// requested, until no more are returned, potentially throttling on the way. To +// facilitate concurrency but still protect against malicious nodes sending bad +// headers, we construct a header chain skeleton using the "origin" peer we are +// syncing with, and fill in the missing headers using anyone else. Headers from +// other peers are only accepted if they map cleanly to the skeleton. If no one +// can fill in the skeleton - not even the origin peer - it's assumed invalid and +// the origin is dropped. +func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, pivot uint64) error { + p.log.Debug("Directing header downloads", "origin", from) + defer p.log.Debug("Header download terminated") + + // Create a timeout timer, and the associated header fetcher + skeleton := true // Skeleton assembly phase or finishing up + request := time.Now() // time of the last skeleton fetch request + timeout := time.NewTimer(0) // timer to dump a non-responsive active peer + <-timeout.C // timeout channel should be initially empty + defer timeout.Stop() + + var ttl time.Duration + getHeaders := func(from uint64) { + request = time.Now() + + ttl = d.requestTTL() + timeout.Reset(ttl) + + if skeleton { + p.log.Trace("Fetching skeleton headers", "count", MaxHeaderFetch, "from", from) + go p.peer.RequestHeadersByNumber(from+uint64(MaxHeaderFetch)-1, MaxSkeletonSize, MaxHeaderFetch-1, false) + } else { + p.log.Trace("Fetching full headers", "count", MaxHeaderFetch, "from", from) + go p.peer.RequestHeadersByNumber(from, MaxHeaderFetch, 0, false) + } + } + // Start pulling the header chain skeleton until all is done + ancestor := from + getHeaders(from) + + for { + select { + case <-d.cancelCh: + return errCanceled + + case packet := <-d.headerCh: + // Make sure the active peer is giving us the skeleton headers + if packet.PeerId() != p.id { + log.Debug("Received skeleton from incorrect peer", "peer", packet.PeerId()) + break + } + headerReqTimer.UpdateSince(request) + timeout.Stop() + + // If the skeleton's finished, pull any remaining head headers directly from the origin + if packet.Items() == 0 && skeleton { + skeleton = false + getHeaders(from) + continue + } + // If no more headers are inbound, notify the content fetchers and return + if packet.Items() == 0 { + // Don't abort header fetches while the pivot is downloading + if atomic.LoadInt32(&d.committed) == 0 && pivot <= from { + p.log.Debug("No headers, waiting for pivot commit") + select { + case <-time.After(fsHeaderContCheck): + getHeaders(from) + continue + case <-d.cancelCh: + return errCanceled + } + } + // Pivot done (or not in fast sync) and no more headers, terminate the process + p.log.Debug("No more headers available") + select { + case d.headerProcCh <- nil: + return nil + case <-d.cancelCh: + return errCanceled + } + } + headers := packet.(*headerPack).headers + + // If we received a skeleton batch, resolve internals concurrently + if skeleton { + filled, proced, err := d.fillHeaderSkeleton(from, headers) + if err != nil { + p.log.Debug("Skeleton chain invalid", "err", err) + return errInvalidChain + } + headers = filled[proced:] + from += uint64(proced) + } else { + // If we're closing in on the chain head, but haven't yet reached it, delay + // the last few headers so mini reorgs on the head don't cause invalid hash + // chain errors. + if n := len(headers); n > 0 { + // Retrieve the current head we're at + head := uint64(0) + if d.mode == LightSync { + head = d.lightchain.CurrentHeader().Number.Uint64() + } else { + head = d.blockchain.CurrentFastBlock().NumberU64() + if full := d.blockchain.CurrentBlock().NumberU64(); head < full { + head = full + } + } + // If the head is below the common ancestor, we're actually deduplicating + // already existing chain segments, so use the ancestor as the fake head. + // Otherwise we might end up delaying header deliveries pointlessly. + if head < ancestor { + head = ancestor + } + // If the head is way older than this batch, delay the last few headers + if head+uint64(reorgProtThreshold) < headers[n-1].Number.Uint64() { + delay := reorgProtHeaderDelay + if delay > n { + delay = n + } + headers = headers[:n-delay] + } + } + } + // Insert all the new headers and fetch the next batch + if len(headers) > 0 { + p.log.Trace("Scheduling new headers", "count", len(headers), "from", from) + select { + case d.headerProcCh <- headers: + case <-d.cancelCh: + return errCanceled + } + from += uint64(len(headers)) + getHeaders(from) + } else { + // No headers delivered, or all of them being delayed, sleep a bit and retry + p.log.Trace("All headers delayed, waiting") + select { + case <-time.After(fsHeaderContCheck): + getHeaders(from) + continue + case <-d.cancelCh: + return errCanceled + } + } + + case <-timeout.C: + if d.dropPeer == nil { + // The dropPeer method is nil when `--copydb` is used for a local copy. + // Timeouts can occur if e.g. compaction hits at the wrong time, and can be ignored + p.log.Warn("Downloader wants to drop peer, but peerdrop-function is not set", "peer", p.id) + break + } + // Header retrieval timed out, consider the peer bad and drop + p.log.Debug("Header request timed out", "elapsed", ttl) + headerTimeoutMeter.Mark(1) + d.dropPeer(p.id) + + // Finish the sync gracefully instead of dumping the gathered data though + for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { + select { + case ch <- false: + case <-d.cancelCh: + } + } + select { + case d.headerProcCh <- nil: + case <-d.cancelCh: + } + return errBadPeer + } + } +} + +// fillHeaderSkeleton concurrently retrieves headers from all our available peers +// and maps them to the provided skeleton header chain. +// +// Any partial results from the beginning of the skeleton is (if possible) forwarded +// immediately to the header processor to keep the rest of the pipeline full even +// in the case of header stalls. +// +// The method returns the entire filled skeleton and also the number of headers +// already forwarded for processing. +func (d *Downloader) fillHeaderSkeleton(from uint64, skeleton []*types.Header) ([]*types.Header, int, error) { + log.Debug("Filling up skeleton", "from", from) + d.queue.ScheduleSkeleton(from, skeleton) + + var ( + deliver = func(packet dataPack) (int, error) { + pack := packet.(*headerPack) + return d.queue.DeliverHeaders(pack.peerID, pack.headers, d.headerProcCh) + } + expire = func() map[string]int { return d.queue.ExpireHeaders(d.requestTTL()) } + throttle = func() bool { return false } + reserve = func(p *peerConnection, count int) (*fetchRequest, bool, error) { + return d.queue.ReserveHeaders(p, count), false, nil + } + fetch = func(p *peerConnection, req *fetchRequest) error { return p.FetchHeaders(req.From, MaxHeaderFetch) } + capacity = func(p *peerConnection) int { return p.HeaderCapacity(d.requestRTT()) } + setIdle = func(p *peerConnection, accepted int) { p.SetHeadersIdle(accepted) } + ) + err := d.fetchParts(d.headerCh, deliver, d.queue.headerContCh, expire, + d.queue.PendingHeaders, d.queue.InFlightHeaders, throttle, reserve, + nil, fetch, d.queue.CancelHeaders, capacity, d.peers.HeaderIdlePeers, setIdle, "headers") + + log.Debug("Skeleton fill terminated", "err", err) + + filled, proced := d.queue.RetrieveHeaders() + return filled, proced, err +} + +// fetchBodies iteratively downloads the scheduled block bodies, taking any +// available peers, reserving a chunk of blocks for each, waiting for delivery +// and also periodically checking for timeouts. +func (d *Downloader) fetchBodies(from uint64) error { + log.Debug("Downloading block bodies", "origin", from) + + var ( + deliver = func(packet dataPack) (int, error) { + pack := packet.(*bodyPack) + return d.queue.DeliverBodies(pack.peerID, pack.transactions, pack.uncles) + } + expire = func() map[string]int { return d.queue.ExpireBodies(d.requestTTL()) } + fetch = func(p *peerConnection, req *fetchRequest) error { return p.FetchBodies(req) } + capacity = func(p *peerConnection) int { return p.BlockCapacity(d.requestRTT()) } + setIdle = func(p *peerConnection, accepted int) { p.SetBodiesIdle(accepted) } + ) + err := d.fetchParts(d.bodyCh, deliver, d.bodyWakeCh, expire, + d.queue.PendingBlocks, d.queue.InFlightBlocks, d.queue.ShouldThrottleBlocks, d.queue.ReserveBodies, + d.bodyFetchHook, fetch, d.queue.CancelBodies, capacity, d.peers.BodyIdlePeers, setIdle, "bodies") + + log.Debug("Block body download terminated", "err", err) + return err +} + +// fetchReceipts iteratively downloads the scheduled block receipts, taking any +// available peers, reserving a chunk of receipts for each, waiting for delivery +// and also periodically checking for timeouts. +func (d *Downloader) fetchReceipts(from uint64) error { + log.Debug("Downloading transaction receipts", "origin", from) + + var ( + deliver = func(packet dataPack) (int, error) { + pack := packet.(*receiptPack) + return d.queue.DeliverReceipts(pack.peerID, pack.receipts) + } + expire = func() map[string]int { return d.queue.ExpireReceipts(d.requestTTL()) } + fetch = func(p *peerConnection, req *fetchRequest) error { return p.FetchReceipts(req) } + capacity = func(p *peerConnection) int { return p.ReceiptCapacity(d.requestRTT()) } + setIdle = func(p *peerConnection, accepted int) { p.SetReceiptsIdle(accepted) } + ) + err := d.fetchParts(d.receiptCh, deliver, d.receiptWakeCh, expire, + d.queue.PendingReceipts, d.queue.InFlightReceipts, d.queue.ShouldThrottleReceipts, d.queue.ReserveReceipts, + d.receiptFetchHook, fetch, d.queue.CancelReceipts, capacity, d.peers.ReceiptIdlePeers, setIdle, "receipts") + + log.Debug("Transaction receipt download terminated", "err", err) + return err +} + +// fetchParts iteratively downloads scheduled block parts, taking any available +// peers, reserving a chunk of fetch requests for each, waiting for delivery and +// also periodically checking for timeouts. +// +// As the scheduling/timeout logic mostly is the same for all downloaded data +// types, this method is used by each for data gathering and is instrumented with +// various callbacks to handle the slight differences between processing them. +// +// The instrumentation parameters: +// - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) +// - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) +// - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) +// - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) +// - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) +// - pending: task callback for the number of requests still needing download (detect completion/non-completability) +// - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) +// - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) +// - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) +// - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) +// - fetch: network callback to actually send a particular download request to a physical remote peer +// - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) +// - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) +// - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks +// - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) +// - kind: textual label of the type being downloaded to display in log mesages +func (d *Downloader) fetchParts(deliveryCh chan dataPack, deliver func(dataPack) (int, error), wakeCh chan bool, + expire func() map[string]int, pending func() int, inFlight func() bool, throttle func() bool, reserve func(*peerConnection, int) (*fetchRequest, bool, error), + fetchHook func([]*types.Header), fetch func(*peerConnection, *fetchRequest) error, cancel func(*fetchRequest), capacity func(*peerConnection) int, + idle func() ([]*peerConnection, int), setIdle func(*peerConnection, int), kind string) error { + + // Create a ticker to detect expired retrieval tasks + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + + update := make(chan struct{}, 1) + + // Prepare the queue and fetch block parts until the block header fetcher's done + finished := false + for { + select { + case <-d.cancelCh: + return errCanceled + + case packet := <-deliveryCh: + // If the peer was previously banned and failed to deliver its pack + // in a reasonable time frame, ignore its message. + if peer := d.peers.Peer(packet.PeerId()); peer != nil { + // Deliver the received chunk of data and check chain validity + accepted, err := deliver(packet) + if err == errInvalidChain { + return err + } + // Unless a peer delivered something completely else than requested (usually + // caused by a timed out request which came through in the end), set it to + // idle. If the delivery's stale, the peer should have already been idled. + if err != errStaleDelivery { + setIdle(peer, accepted) + } + // Issue a log to the user to see what's going on + switch { + case err == nil && packet.Items() == 0: + peer.log.Trace("Requested data not delivered", "type", kind) + case err == nil: + peer.log.Trace("Delivered new batch of data", "type", kind, "count", packet.Stats()) + default: + peer.log.Trace("Failed to deliver retrieved data", "type", kind, "err", err) + } + } + // Blocks assembled, try to update the progress + select { + case update <- struct{}{}: + default: + } + + case cont := <-wakeCh: + // The header fetcher sent a continuation flag, check if it's done + if !cont { + finished = true + } + // Headers arrive, try to update the progress + select { + case update <- struct{}{}: + default: + } + + case <-ticker.C: + // Sanity check update the progress + select { + case update <- struct{}{}: + default: + } + + case <-update: + // Short circuit if we lost all our peers + if d.peers.Len() == 0 { + return errNoPeers + } + // Check for fetch request timeouts and demote the responsible peers + for pid, fails := range expire() { + if peer := d.peers.Peer(pid); peer != nil { + // If a lot of retrieval elements expired, we might have overestimated the remote peer or perhaps + // ourselves. Only reset to minimal throughput but don't drop just yet. If even the minimal times + // out that sync wise we need to get rid of the peer. + // + // The reason the minimum threshold is 2 is because the downloader tries to estimate the bandwidth + // and latency of a peer separately, which requires pushing the measures capacity a bit and seeing + // how response times reacts, to it always requests one more than the minimum (i.e. min 2). + if fails > 2 { + peer.log.Trace("Data delivery timed out", "type", kind) + setIdle(peer, 0) + } else { + peer.log.Debug("Stalling delivery, dropping", "type", kind) + + if d.dropPeer == nil { + // The dropPeer method is nil when `--copydb` is used for a local copy. + // Timeouts can occur if e.g. compaction hits at the wrong time, and can be ignored + peer.log.Warn("Downloader wants to drop peer, but peerdrop-function is not set", "peer", pid) + } else { + d.dropPeer(pid) + + // If this peer was the master peer, abort sync immediately + d.cancelLock.RLock() + master := pid == d.cancelPeer + d.cancelLock.RUnlock() + + if master { + d.cancel() + return errTimeout + } + } + } + } + } + // If there's nothing more to fetch, wait or terminate + if pending() == 0 { + if !inFlight() && finished { + log.Debug("Data fetching completed", "type", kind) + return nil + } + break + } + // Send a download request to all idle peers, until throttled + progressed, throttled, running := false, false, inFlight() + idles, total := idle() + + for _, peer := range idles { + // Short circuit if throttling activated + if throttle() { + throttled = true + break + } + // Short circuit if there is no more available task. + if pending() == 0 { + break + } + // Reserve a chunk of fetches for a peer. A nil can mean either that + // no more headers are available, or that the peer is known not to + // have them. + request, progress, err := reserve(peer, capacity(peer)) + if err != nil { + return err + } + if progress { + progressed = true + } + if request == nil { + continue + } + if request.From > 0 { + peer.log.Trace("Requesting new batch of data", "type", kind, "from", request.From) + } else { + peer.log.Trace("Requesting new batch of data", "type", kind, "count", len(request.Headers), "from", request.Headers[0].Number) + } + // Fetch the chunk and make sure any errors return the hashes to the queue + if fetchHook != nil { + fetchHook(request.Headers) + } + if err := fetch(peer, request); err != nil { + // Although we could try and make an attempt to fix this, this error really + // means that we've double allocated a fetch task to a peer. If that is the + // case, the internal state of the downloader and the queue is very wrong so + // better hard crash and note the error instead of silently accumulating into + // a much bigger issue. + panic(fmt.Sprintf("%v: %s fetch assignment failed", peer, kind)) + } + running = true + } + // Make sure that we have peers available for fetching. If all peers have been tried + // and all failed throw an error + if !progressed && !throttled && !running && len(idles) == total && pending() > 0 { + return errPeersUnavailable + } + } + } +} + +// processHeaders takes batches of retrieved headers from an input channel and +// keeps processing and scheduling them into the header chain and downloader's +// queue until the stream ends or a failure occurs. +func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) error { + // Keep a count of uncertain headers to roll back + var rollback []*types.Header + defer func() { + if len(rollback) > 0 { + // Flatten the headers and roll them back + hashes := make([]common.Hash, len(rollback)) + for i, header := range rollback { + hashes[i] = header.Hash() + } + lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, common.Big0, common.Big0 + if d.mode != LightSync { + lastFastBlock = d.blockchain.CurrentFastBlock().Number() + lastBlock = d.blockchain.CurrentBlock().Number() + } + d.lightchain.Rollback(hashes) + curFastBlock, curBlock := common.Big0, common.Big0 + if d.mode != LightSync { + curFastBlock = d.blockchain.CurrentFastBlock().Number() + curBlock = d.blockchain.CurrentBlock().Number() + } + log.Warn("Rolled back headers", "count", len(hashes), + "header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number), + "fast", fmt.Sprintf("%d->%d", lastFastBlock, curFastBlock), + "block", fmt.Sprintf("%d->%d", lastBlock, curBlock)) + } + }() + + // Wait for batches of headers to process + gotHeaders := false + + for { + select { + case <-d.cancelCh: + return errCanceled + + case headers := <-d.headerProcCh: + // Terminate header processing if we synced up + if len(headers) == 0 { + // Notify everyone that headers are fully processed + for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { + select { + case ch <- false: + case <-d.cancelCh: + } + } + // If no headers were retrieved at all, the peer violated its TD promise that it had a + // better chain compared to ours. The only exception is if its promised blocks were + // already imported by other means (e.g. fetcher): + // + // R , L : Both at block 10 + // R: Mine block 11, and propagate it to L + // L: Queue block 11 for import + // L: Notice that R's head and TD increased compared to ours, start sync + // L: Import of block 11 finishes + // L: Sync begins, and finds common ancestor at 11 + // L: Request new headers up from 11 (R's TD was higher, it must have something) + // R: Nothing to give + if d.mode != LightSync { + head := d.blockchain.CurrentBlock() + if !gotHeaders && td.Cmp(d.blockchain.GetTd(head.Hash(), head.NumberU64())) > 0 { + return errStallingPeer + } + } + // If fast or light syncing, ensure promised headers are indeed delivered. This is + // needed to detect scenarios where an attacker feeds a bad pivot and then bails out + // of delivering the post-pivot blocks that would flag the invalid content. + // + // This check cannot be executed "as is" for full imports, since blocks may still be + // queued for processing when the header download completes. However, as long as the + // peer gave us something useful, we're already happy/progressed (above check). + if d.mode == FastSync || d.mode == LightSync { + head := d.lightchain.CurrentHeader() + if td.Cmp(d.lightchain.GetTd(head.Hash(), head.Number.Uint64())) > 0 { + return errStallingPeer + } + } + // Disable any rollback and return + rollback = nil + return nil + } + // Otherwise split the chunk of headers into batches and process them + gotHeaders = true + for len(headers) > 0 { + // Terminate if something failed in between processing chunks + select { + case <-d.cancelCh: + return errCanceled + default: + } + // Select the next chunk of headers to import + limit := maxHeadersProcess + if limit > len(headers) { + limit = len(headers) + } + chunk := headers[:limit] + // In case of header only syncing, validate the chunk immediately + if d.mode == FastSync || d.mode == LightSync { + // Collect the yet unknown headers to mark them as uncertain + unknown := make([]*types.Header, 0, len(chunk)) + for _, header := range chunk { + if !d.lightchain.HasHeader(header.Hash(), header.Number.Uint64()) { + unknown = append(unknown, header) + } + } + // If we're importing pure headers, verify based on their recentness + frequency := fsHeaderCheckFrequency + if chunk[len(chunk)-1].Number.Uint64()+uint64(fsHeaderForceVerify) > pivot { + frequency = 1 + } + if n, err := d.lightchain.InsertHeaderChain(chunk, frequency); err != nil { + // If some headers were inserted, add them too to the rollback list + if n > 0 { + rollback = append(rollback, chunk[:n]...) + } + log.Debug("Invalid header encountered", "number", chunk[n].Number, "hash", chunk[n].Hash(), "err", err) + return errInvalidChain + } + // All verifications passed, store newly found uncertain headers + rollback = append(rollback, unknown...) + if len(rollback) > fsHeaderSafetyNet { + rollback = append(rollback[:0], rollback[len(rollback)-fsHeaderSafetyNet:]...) + } + } + // Unless we're doing light chains, schedule the headers for associated content retrieval + if d.mode == FullSync || d.mode == FastSync { + // If we've reached the allowed number of pending headers, stall a bit + for d.queue.PendingBlocks() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders { + select { + case <-d.cancelCh: + return errCanceled + case <-time.After(time.Second): + } + } + // Otherwise insert the headers for content retrieval + inserts := d.queue.Schedule(chunk, origin) + if len(inserts) != len(chunk) { + log.Debug("Stale headers") + return errBadPeer + } + } + headers = headers[limit:] + origin += uint64(limit) + } + // Update the highest block number we know if a higher one is found. + d.syncStatsLock.Lock() + if d.syncStatsChainHeight < origin { + d.syncStatsChainHeight = origin - 1 + } + d.syncStatsLock.Unlock() + + // Signal the content downloaders of the availablility of new tasks + for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { + select { + case ch <- true: + default: + } + } + } + } +} + +// processFullSyncContent takes fetch results from the queue and imports them into the chain. +func (d *Downloader) processFullSyncContent() error { + for { + results := d.queue.Results(true) + if len(results) == 0 { + return nil + } + if d.chainInsertHook != nil { + d.chainInsertHook(results) + } + if err := d.importBlockResults(results); err != nil { + return err + } + } +} + +func (d *Downloader) importBlockResults(results []*fetchResult) error { + // Check for any early termination requests + if len(results) == 0 { + return nil + } + select { + case <-d.quitCh: + return errCancelContentProcessing + default: + } + // Retrieve the a batch of results to import + first, last := results[0].Header, results[len(results)-1].Header + log.Debug("Inserting downloaded chain", "items", len(results), + "firstnum", first.Number, "firsthash", first.Hash(), + "lastnum", last.Number, "lasthash", last.Hash(), + ) + blocks := make([]*types.Block, len(results)) + for i, result := range results { + blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles) + } + if index, err := d.blockchain.InsertChain(blocks); err != nil { + if index < len(results) { + log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) + } else { + // The InsertChain method in blockchain.go will sometimes return an out-of-bounds index, + // when it needs to preprocess blocks to import a sidechain. + // The importer will put together a new list of blocks to import, which is a superset + // of the blocks delivered from the downloader, and the indexing will be off. + log.Debug("Downloaded item processing failed on sidechain import", "index", index, "err", err) + } + return errInvalidChain + } + return nil +} + +// processFastSyncContent takes fetch results from the queue and writes them to the +// database. It also controls the synchronisation of state nodes of the pivot block. +func (d *Downloader) processFastSyncContent(latest *types.Header) error { + // Start syncing state of the reported head block. This should get us most of + // the state of the pivot block. + stateSync := d.syncState(latest.Root) + defer stateSync.Cancel() + go func() { + if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled { + d.queue.Close() // wake up Results + } + }() + // Figure out the ideal pivot block. Note, that this goalpost may move if the + // sync takes long enough for the chain head to move significantly. + pivot := uint64(0) + if height := latest.Number.Uint64(); height > uint64(fsMinFullBlocks) { + pivot = height - uint64(fsMinFullBlocks) + } + // To cater for moving pivot points, track the pivot block and subsequently + // accumulated download results separately. + var ( + oldPivot *fetchResult // Locked in pivot block, might change eventually + oldTail []*fetchResult // Downloaded content after the pivot + ) + for { + // Wait for the next batch of downloaded data to be available, and if the pivot + // block became stale, move the goalpost + results := d.queue.Results(oldPivot == nil) // Block if we're not monitoring pivot staleness + if len(results) == 0 { + // If pivot sync is done, stop + if oldPivot == nil { + return stateSync.Cancel() + } + // If sync failed, stop + select { + case <-d.cancelCh: + stateSync.Cancel() + return errCanceled + default: + } + } + if d.chainInsertHook != nil { + d.chainInsertHook(results) + } + if oldPivot != nil { + results = append(append([]*fetchResult{oldPivot}, oldTail...), results...) + } + // Split around the pivot block and process the two sides via fast/full sync + if atomic.LoadInt32(&d.committed) == 0 { + latest = results[len(results)-1].Header + if height := latest.Number.Uint64(); height > pivot+2*uint64(fsMinFullBlocks) { + log.Warn("Pivot became stale, moving", "old", pivot, "new", height-uint64(fsMinFullBlocks)) + pivot = height - uint64(fsMinFullBlocks) + } + } + P, beforeP, afterP := splitAroundPivot(pivot, results) + if err := d.commitFastSyncData(beforeP, stateSync); err != nil { + return err + } + if P != nil { + // If new pivot block found, cancel old state retrieval and restart + if oldPivot != P { + stateSync.Cancel() + + stateSync = d.syncState(P.Header.Root) + defer stateSync.Cancel() + go func() { + if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled { + d.queue.Close() // wake up Results + } + }() + oldPivot = P + } + // Wait for completion, occasionally checking for pivot staleness + select { + case <-stateSync.done: + if stateSync.err != nil { + return stateSync.err + } + if err := d.commitPivotBlock(P); err != nil { + return err + } + oldPivot = nil + + case <-time.After(time.Second): + oldTail = afterP + continue + } + } + // Fast sync done, pivot commit done, full import + if err := d.importBlockResults(afterP); err != nil { + return err + } + } +} + +func splitAroundPivot(pivot uint64, results []*fetchResult) (p *fetchResult, before, after []*fetchResult) { + for _, result := range results { + num := result.Header.Number.Uint64() + switch { + case num < pivot: + before = append(before, result) + case num == pivot: + p = result + default: + after = append(after, result) + } + } + return p, before, after +} + +func (d *Downloader) commitFastSyncData(results []*fetchResult, stateSync *stateSync) error { + // Check for any early termination requests + if len(results) == 0 { + return nil + } + select { + case <-d.quitCh: + return errCancelContentProcessing + case <-stateSync.done: + if err := stateSync.Wait(); err != nil { + return err + } + default: + } + // Retrieve the a batch of results to import + first, last := results[0].Header, results[len(results)-1].Header + log.Debug("Inserting fast-sync blocks", "items", len(results), + "firstnum", first.Number, "firsthash", first.Hash(), + "lastnumn", last.Number, "lasthash", last.Hash(), + ) + blocks := make([]*types.Block, len(results)) + receipts := make([]types.Receipts, len(results)) + for i, result := range results { + blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles) + receipts[i] = result.Receipts + } + if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil { + log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) + return errInvalidChain + } + return nil +} + +func (d *Downloader) commitPivotBlock(result *fetchResult) error { + block := types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles) + log.Debug("Committing fast sync pivot as new head", "number", block.Number(), "hash", block.Hash()) + + // Commit the pivot block as the new head, will require full sync from here on + if _, err := d.blockchain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{result.Receipts}, d.ancientLimit); err != nil { + return err + } + if err := d.blockchain.FastSyncCommitHead(block.Hash()); err != nil { + return err + } + atomic.StoreInt32(&d.committed, 1) + + // If we had a bloom filter for the state sync, deallocate it now. Note, we only + // deallocate internally, but keep the empty wrapper. This ensures that if we do + // a rollback after committing the pivot and restarting fast sync, we don't end + // up using a nil bloom. Empty bloom is fine, it just returns that it does not + // have the info we need, so reach down to the database instead. + if d.stateBloom != nil { + d.stateBloom.Close() + } + return nil +} + +// DeliverHeaders injects a new batch of block headers received from a remote +// node into the download schedule. +func (d *Downloader) DeliverHeaders(id string, headers []*types.Header) (err error) { + return d.deliver(id, d.headerCh, &headerPack{id, headers}, headerInMeter, headerDropMeter) +} + +// DeliverBodies injects a new batch of block bodies received from a remote node. +func (d *Downloader) DeliverBodies(id string, transactions [][]*types.Transaction, uncles [][]*types.Header) (err error) { + return d.deliver(id, d.bodyCh, &bodyPack{id, transactions, uncles}, bodyInMeter, bodyDropMeter) +} + +// DeliverReceipts injects a new batch of receipts received from a remote node. +func (d *Downloader) DeliverReceipts(id string, receipts [][]*types.Receipt) (err error) { + return d.deliver(id, d.receiptCh, &receiptPack{id, receipts}, receiptInMeter, receiptDropMeter) +} + +// DeliverNodeData injects a new batch of node state data received from a remote node. +func (d *Downloader) DeliverNodeData(id string, data [][]byte) (err error) { + return d.deliver(id, d.stateCh, &statePack{id, data}, stateInMeter, stateDropMeter) +} + +// deliver injects a new batch of data received from a remote node. +func (d *Downloader) deliver(id string, destCh chan dataPack, packet dataPack, inMeter, dropMeter metrics.Meter) (err error) { + // Update the delivery metrics for both good and failed deliveries + inMeter.Mark(int64(packet.Items())) + defer func() { + if err != nil { + dropMeter.Mark(int64(packet.Items())) + } + }() + // Deliver or abort if the sync is canceled while queuing + d.cancelLock.RLock() + cancel := d.cancelCh + d.cancelLock.RUnlock() + if cancel == nil { + return errNoSyncActive + } + select { + case destCh <- packet: + return nil + case <-cancel: + return errNoSyncActive + } +} + +// qosTuner is the quality of service tuning loop that occasionally gathers the +// peer latency statistics and updates the estimated request round trip time. +func (d *Downloader) qosTuner() { + for { + // Retrieve the current median RTT and integrate into the previoust target RTT + rtt := time.Duration((1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT())) + atomic.StoreUint64(&d.rttEstimate, uint64(rtt)) + + // A new RTT cycle passed, increase our confidence in the estimated RTT + conf := atomic.LoadUint64(&d.rttConfidence) + conf = conf + (1000000-conf)/2 + atomic.StoreUint64(&d.rttConfidence, conf) + + // Log the new QoS values and sleep until the next RTT + log.Debug("Recalculated downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL()) + select { + case <-d.quitCh: + return + case <-time.After(rtt): + } + } +} + +// qosReduceConfidence is meant to be called when a new peer joins the downloader's +// peer set, needing to reduce the confidence we have in out QoS estimates. +func (d *Downloader) qosReduceConfidence() { + // If we have a single peer, confidence is always 1 + peers := uint64(d.peers.Len()) + if peers == 0 { + // Ensure peer connectivity races don't catch us off guard + return + } + if peers == 1 { + atomic.StoreUint64(&d.rttConfidence, 1000000) + return + } + // If we have a ton of peers, don't drop confidence) + if peers >= uint64(qosConfidenceCap) { + return + } + // Otherwise drop the confidence factor + conf := atomic.LoadUint64(&d.rttConfidence) * (peers - 1) / peers + if float64(conf)/1000000 < rttMinConfidence { + conf = uint64(rttMinConfidence * 1000000) + } + atomic.StoreUint64(&d.rttConfidence, conf) + + rtt := time.Duration(atomic.LoadUint64(&d.rttEstimate)) + log.Debug("Relaxed downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL()) +} + +// requestRTT returns the current target round trip time for a download request +// to complete in. +// +// Note, the returned RTT is .9 of the actually estimated RTT. The reason is that +// the downloader tries to adapt queries to the RTT, so multiple RTT values can +// be adapted to, but smaller ones are preferred (stabler download stream). +func (d *Downloader) requestRTT() time.Duration { + return time.Duration(atomic.LoadUint64(&d.rttEstimate)) * 9 / 10 +} + +// requestTTL returns the current timeout allowance for a single download request +// to finish under. +func (d *Downloader) requestTTL() time.Duration { + var ( + rtt = time.Duration(atomic.LoadUint64(&d.rttEstimate)) + conf = float64(atomic.LoadUint64(&d.rttConfidence)) / 1000000.0 + ) + ttl := time.Duration(ttlScaling) * time.Duration(float64(rtt)/conf) + if ttl > ttlLimit { + ttl = ttlLimit + } + return ttl +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/downloader/fakepeer.go b/vendor/github.com/ethereum/go-ethereum/eth/downloader/fakepeer.go new file mode 100644 index 00000000..3ec90bc9 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/downloader/fakepeer.go @@ -0,0 +1,161 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package downloader + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +// FakePeer is a mock downloader peer that operates on a local database instance +// instead of being an actual live node. It's useful for testing and to implement +// sync commands from an existing local database. +type FakePeer struct { + id string + db ethdb.Database + hc *core.HeaderChain + dl *Downloader +} + +// NewFakePeer creates a new mock downloader peer with the given data sources. +func NewFakePeer(id string, db ethdb.Database, hc *core.HeaderChain, dl *Downloader) *FakePeer { + return &FakePeer{id: id, db: db, hc: hc, dl: dl} +} + +// Head implements downloader.Peer, returning the current head hash and number +// of the best known header. +func (p *FakePeer) Head() (common.Hash, *big.Int) { + header := p.hc.CurrentHeader() + return header.Hash(), header.Number +} + +// RequestHeadersByHash implements downloader.Peer, returning a batch of headers +// defined by the origin hash and the associated query parameters. +func (p *FakePeer) RequestHeadersByHash(hash common.Hash, amount int, skip int, reverse bool) error { + var ( + headers []*types.Header + unknown bool + ) + for !unknown && len(headers) < amount { + origin := p.hc.GetHeaderByHash(hash) + if origin == nil { + break + } + number := origin.Number.Uint64() + headers = append(headers, origin) + if reverse { + for i := 0; i <= skip; i++ { + if header := p.hc.GetHeader(hash, number); header != nil { + hash = header.ParentHash + number-- + } else { + unknown = true + break + } + } + } else { + var ( + current = origin.Number.Uint64() + next = current + uint64(skip) + 1 + ) + if header := p.hc.GetHeaderByNumber(next); header != nil { + if p.hc.GetBlockHashesFromHash(header.Hash(), uint64(skip+1))[skip] == hash { + hash = header.Hash() + } else { + unknown = true + } + } else { + unknown = true + } + } + } + p.dl.DeliverHeaders(p.id, headers) + return nil +} + +// RequestHeadersByNumber implements downloader.Peer, returning a batch of headers +// defined by the origin number and the associated query parameters. +func (p *FakePeer) RequestHeadersByNumber(number uint64, amount int, skip int, reverse bool) error { + var ( + headers []*types.Header + unknown bool + ) + for !unknown && len(headers) < amount { + origin := p.hc.GetHeaderByNumber(number) + if origin == nil { + break + } + if reverse { + if number >= uint64(skip+1) { + number -= uint64(skip + 1) + } else { + unknown = true + } + } else { + number += uint64(skip + 1) + } + headers = append(headers, origin) + } + p.dl.DeliverHeaders(p.id, headers) + return nil +} + +// RequestBodies implements downloader.Peer, returning a batch of block bodies +// corresponding to the specified block hashes. +func (p *FakePeer) RequestBodies(hashes []common.Hash) error { + var ( + txs [][]*types.Transaction + uncles [][]*types.Header + ) + for _, hash := range hashes { + block := rawdb.ReadBlock(p.db, hash, *p.hc.GetBlockNumber(hash)) + + txs = append(txs, block.Transactions()) + uncles = append(uncles, block.Uncles()) + } + p.dl.DeliverBodies(p.id, txs, uncles) + return nil +} + +// RequestReceipts implements downloader.Peer, returning a batch of transaction +// receipts corresponding to the specified block hashes. +func (p *FakePeer) RequestReceipts(hashes []common.Hash) error { + var receipts [][]*types.Receipt + for _, hash := range hashes { + receipts = append(receipts, rawdb.ReadRawReceipts(p.db, hash, *p.hc.GetBlockNumber(hash))) + } + p.dl.DeliverReceipts(p.id, receipts) + return nil +} + +// RequestNodeData implements downloader.Peer, returning a batch of state trie +// nodes corresponding to the specified trie hashes. +func (p *FakePeer) RequestNodeData(hashes []common.Hash) error { + var data [][]byte + for _, hash := range hashes { + if entry, err := p.db.Get(hash.Bytes()); err == nil { + data = append(data, entry) + } + } + p.dl.DeliverNodeData(p.id, data) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/downloader/statesync.go b/vendor/github.com/ethereum/go-ethereum/eth/downloader/statesync.go new file mode 100644 index 00000000..b422557d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/downloader/statesync.go @@ -0,0 +1,496 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package downloader + +import ( + "fmt" + "hash" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie" + "golang.org/x/crypto/sha3" +) + +// stateReq represents a batch of state fetch requests grouped together into +// a single data retrieval network packet. +type stateReq struct { + items []common.Hash // Hashes of the state items to download + tasks map[common.Hash]*stateTask // Download tasks to track previous attempts + timeout time.Duration // Maximum round trip time for this to complete + timer *time.Timer // Timer to fire when the RTT timeout expires + peer *peerConnection // Peer that we're requesting from + response [][]byte // Response data of the peer (nil for timeouts) + dropped bool // Flag whether the peer dropped off early +} + +// timedOut returns if this request timed out. +func (req *stateReq) timedOut() bool { + return req.response == nil +} + +// stateSyncStats is a collection of progress stats to report during a state trie +// sync to RPC requests as well as to display in user logs. +type stateSyncStats struct { + processed uint64 // Number of state entries processed + duplicate uint64 // Number of state entries downloaded twice + unexpected uint64 // Number of non-requested state entries received + pending uint64 // Number of still pending state entries +} + +// syncState starts downloading state with the given root hash. +func (d *Downloader) syncState(root common.Hash) *stateSync { + // Create the state sync + s := newStateSync(d, root) + select { + case d.stateSyncStart <- s: + case <-d.quitCh: + s.err = errCancelStateFetch + close(s.done) + } + return s +} + +// stateFetcher manages the active state sync and accepts requests +// on its behalf. +func (d *Downloader) stateFetcher() { + for { + select { + case s := <-d.stateSyncStart: + for next := s; next != nil; { + next = d.runStateSync(next) + } + case <-d.stateCh: + // Ignore state responses while no sync is running. + case <-d.quitCh: + return + } + } +} + +// runStateSync runs a state synchronisation until it completes or another root +// hash is requested to be switched over to. +func (d *Downloader) runStateSync(s *stateSync) *stateSync { + var ( + active = make(map[string]*stateReq) // Currently in-flight requests + finished []*stateReq // Completed or failed requests + timeout = make(chan *stateReq) // Timed out active requests + ) + defer func() { + // Cancel active request timers on exit. Also set peers to idle so they're + // available for the next sync. + for _, req := range active { + req.timer.Stop() + req.peer.SetNodeDataIdle(len(req.items)) + } + }() + // Run the state sync. + go s.run() + defer s.Cancel() + + // Listen for peer departure events to cancel assigned tasks + peerDrop := make(chan *peerConnection, 1024) + peerSub := s.d.peers.SubscribePeerDrops(peerDrop) + defer peerSub.Unsubscribe() + + for { + // Enable sending of the first buffered element if there is one. + var ( + deliverReq *stateReq + deliverReqCh chan *stateReq + ) + if len(finished) > 0 { + deliverReq = finished[0] + deliverReqCh = s.deliver + } + + select { + // The stateSync lifecycle: + case next := <-d.stateSyncStart: + return next + + case <-s.done: + return nil + + // Send the next finished request to the current sync: + case deliverReqCh <- deliverReq: + // Shift out the first request, but also set the emptied slot to nil for GC + copy(finished, finished[1:]) + finished[len(finished)-1] = nil + finished = finished[:len(finished)-1] + + // Handle incoming state packs: + case pack := <-d.stateCh: + // Discard any data not requested (or previously timed out) + req := active[pack.PeerId()] + if req == nil { + log.Debug("Unrequested node data", "peer", pack.PeerId(), "len", pack.Items()) + continue + } + // Finalize the request and queue up for processing + req.timer.Stop() + req.response = pack.(*statePack).states + + finished = append(finished, req) + delete(active, pack.PeerId()) + + // Handle dropped peer connections: + case p := <-peerDrop: + // Skip if no request is currently pending + req := active[p.id] + if req == nil { + continue + } + // Finalize the request and queue up for processing + req.timer.Stop() + req.dropped = true + + finished = append(finished, req) + delete(active, p.id) + + // Handle timed-out requests: + case req := <-timeout: + // If the peer is already requesting something else, ignore the stale timeout. + // This can happen when the timeout and the delivery happens simultaneously, + // causing both pathways to trigger. + if active[req.peer.id] != req { + continue + } + // Move the timed out data back into the download queue + finished = append(finished, req) + delete(active, req.peer.id) + + // Track outgoing state requests: + case req := <-d.trackStateReq: + // If an active request already exists for this peer, we have a problem. In + // theory the trie node schedule must never assign two requests to the same + // peer. In practice however, a peer might receive a request, disconnect and + // immediately reconnect before the previous times out. In this case the first + // request is never honored, alas we must not silently overwrite it, as that + // causes valid requests to go missing and sync to get stuck. + if old := active[req.peer.id]; old != nil { + log.Warn("Busy peer assigned new state fetch", "peer", old.peer.id) + + // Make sure the previous one doesn't get siletly lost + old.timer.Stop() + old.dropped = true + + finished = append(finished, old) + } + // Start a timer to notify the sync loop if the peer stalled. + req.timer = time.AfterFunc(req.timeout, func() { + select { + case timeout <- req: + case <-s.done: + // Prevent leaking of timer goroutines in the unlikely case where a + // timer is fired just before exiting runStateSync. + } + }) + active[req.peer.id] = req + } + } +} + +// stateSync schedules requests for downloading a particular state trie defined +// by a given state root. +type stateSync struct { + d *Downloader // Downloader instance to access and manage current peerset + + sched *trie.Sync // State trie sync scheduler defining the tasks + keccak hash.Hash // Keccak256 hasher to verify deliveries with + tasks map[common.Hash]*stateTask // Set of tasks currently queued for retrieval + + numUncommitted int + bytesUncommitted int + + deliver chan *stateReq // Delivery channel multiplexing peer responses + cancel chan struct{} // Channel to signal a termination request + cancelOnce sync.Once // Ensures cancel only ever gets called once + done chan struct{} // Channel to signal termination completion + err error // Any error hit during sync (set before completion) +} + +// stateTask represents a single trie node download task, containing a set of +// peers already attempted retrieval from to detect stalled syncs and abort. +type stateTask struct { + attempts map[string]struct{} +} + +// newStateSync creates a new state trie download scheduler. This method does not +// yet start the sync. The user needs to call run to initiate. +func newStateSync(d *Downloader, root common.Hash) *stateSync { + return &stateSync{ + d: d, + sched: state.NewStateSync(root, d.stateDB, d.stateBloom), + keccak: sha3.NewLegacyKeccak256(), + tasks: make(map[common.Hash]*stateTask), + deliver: make(chan *stateReq), + cancel: make(chan struct{}), + done: make(chan struct{}), + } +} + +// run starts the task assignment and response processing loop, blocking until +// it finishes, and finally notifying any goroutines waiting for the loop to +// finish. +func (s *stateSync) run() { + s.err = s.loop() + close(s.done) +} + +// Wait blocks until the sync is done or canceled. +func (s *stateSync) Wait() error { + <-s.done + return s.err +} + +// Cancel cancels the sync and waits until it has shut down. +func (s *stateSync) Cancel() error { + s.cancelOnce.Do(func() { close(s.cancel) }) + return s.Wait() +} + +// loop is the main event loop of a state trie sync. It it responsible for the +// assignment of new tasks to peers (including sending it to them) as well as +// for the processing of inbound data. Note, that the loop does not directly +// receive data from peers, rather those are buffered up in the downloader and +// pushed here async. The reason is to decouple processing from data receipt +// and timeouts. +func (s *stateSync) loop() (err error) { + // Listen for new peer events to assign tasks to them + newPeer := make(chan *peerConnection, 1024) + peerSub := s.d.peers.SubscribeNewPeers(newPeer) + defer peerSub.Unsubscribe() + defer func() { + cerr := s.commit(true) + if err == nil { + err = cerr + } + }() + + // Keep assigning new tasks until the sync completes or aborts + for s.sched.Pending() > 0 { + if err = s.commit(false); err != nil { + return err + } + s.assignTasks() + // Tasks assigned, wait for something to happen + select { + case <-newPeer: + // New peer arrived, try to assign it download tasks + + case <-s.cancel: + return errCancelStateFetch + + case <-s.d.cancelCh: + return errCanceled + + case req := <-s.deliver: + // Response, disconnect or timeout triggered, drop the peer if stalling + log.Trace("Received node data response", "peer", req.peer.id, "count", len(req.response), "dropped", req.dropped, "timeout", !req.dropped && req.timedOut()) + if len(req.items) <= 2 && !req.dropped && req.timedOut() { + // 2 items are the minimum requested, if even that times out, we've no use of + // this peer at the moment. + log.Warn("Stalling state sync, dropping peer", "peer", req.peer.id) + if s.d.dropPeer == nil { + // The dropPeer method is nil when `--copydb` is used for a local copy. + // Timeouts can occur if e.g. compaction hits at the wrong time, and can be ignored + req.peer.log.Warn("Downloader wants to drop peer, but peerdrop-function is not set", "peer", req.peer.id) + } else { + s.d.dropPeer(req.peer.id) + + // If this peer was the master peer, abort sync immediately + s.d.cancelLock.RLock() + master := req.peer.id == s.d.cancelPeer + s.d.cancelLock.RUnlock() + + if master { + s.d.cancel() + return errTimeout + } + } + } + // Process all the received blobs and check for stale delivery + delivered, err := s.process(req) + if err != nil { + log.Warn("Node data write error", "err", err) + return err + } + req.peer.SetNodeDataIdle(delivered) + } + } + return nil +} + +func (s *stateSync) commit(force bool) error { + if !force && s.bytesUncommitted < ethdb.IdealBatchSize { + return nil + } + start := time.Now() + b := s.d.stateDB.NewBatch() + if written, err := s.sched.Commit(b); written == 0 || err != nil { + return err + } + if err := b.Write(); err != nil { + return fmt.Errorf("DB write error: %v", err) + } + s.updateStats(s.numUncommitted, 0, 0, time.Since(start)) + s.numUncommitted = 0 + s.bytesUncommitted = 0 + return nil +} + +// assignTasks attempts to assign new tasks to all idle peers, either from the +// batch currently being retried, or fetching new data from the trie sync itself. +func (s *stateSync) assignTasks() { + // Iterate over all idle peers and try to assign them state fetches + peers, _ := s.d.peers.NodeDataIdlePeers() + for _, p := range peers { + // Assign a batch of fetches proportional to the estimated latency/bandwidth + cap := p.NodeDataCapacity(s.d.requestRTT()) + req := &stateReq{peer: p, timeout: s.d.requestTTL()} + s.fillTasks(cap, req) + + // If the peer was assigned tasks to fetch, send the network request + if len(req.items) > 0 { + req.peer.log.Trace("Requesting new batch of data", "type", "state", "count", len(req.items)) + select { + case s.d.trackStateReq <- req: + req.peer.FetchNodeData(req.items) + case <-s.cancel: + case <-s.d.cancelCh: + } + } + } +} + +// fillTasks fills the given request object with a maximum of n state download +// tasks to send to the remote peer. +func (s *stateSync) fillTasks(n int, req *stateReq) { + // Refill available tasks from the scheduler. + if len(s.tasks) < n { + new := s.sched.Missing(n - len(s.tasks)) + for _, hash := range new { + s.tasks[hash] = &stateTask{make(map[string]struct{})} + } + } + // Find tasks that haven't been tried with the request's peer. + req.items = make([]common.Hash, 0, n) + req.tasks = make(map[common.Hash]*stateTask, n) + for hash, t := range s.tasks { + // Stop when we've gathered enough requests + if len(req.items) == n { + break + } + // Skip any requests we've already tried from this peer + if _, ok := t.attempts[req.peer.id]; ok { + continue + } + // Assign the request to this peer + t.attempts[req.peer.id] = struct{}{} + req.items = append(req.items, hash) + req.tasks[hash] = t + delete(s.tasks, hash) + } +} + +// process iterates over a batch of delivered state data, injecting each item +// into a running state sync, re-queuing any items that were requested but not +// delivered. Returns whether the peer actually managed to deliver anything of +// value, and any error that occurred. +func (s *stateSync) process(req *stateReq) (int, error) { + // Collect processing stats and update progress if valid data was received + duplicate, unexpected, successful := 0, 0, 0 + + defer func(start time.Time) { + if duplicate > 0 || unexpected > 0 { + s.updateStats(0, duplicate, unexpected, time.Since(start)) + } + }(time.Now()) + + // Iterate over all the delivered data and inject one-by-one into the trie + for _, blob := range req.response { + _, hash, err := s.processNodeData(blob) + switch err { + case nil: + s.numUncommitted++ + s.bytesUncommitted += len(blob) + successful++ + case trie.ErrNotRequested: + unexpected++ + case trie.ErrAlreadyProcessed: + duplicate++ + default: + return successful, fmt.Errorf("invalid state node %s: %v", hash.TerminalString(), err) + } + delete(req.tasks, hash) + } + // Put unfulfilled tasks back into the retry queue + npeers := s.d.peers.Len() + for hash, task := range req.tasks { + // If the node did deliver something, missing items may be due to a protocol + // limit or a previous timeout + delayed delivery. Both cases should permit + // the node to retry the missing items (to avoid single-peer stalls). + if len(req.response) > 0 || req.timedOut() { + delete(task.attempts, req.peer.id) + } + // If we've requested the node too many times already, it may be a malicious + // sync where nobody has the right data. Abort. + if len(task.attempts) >= npeers { + return successful, fmt.Errorf("state node %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.attempts), npeers) + } + // Missing item, place into the retry queue. + s.tasks[hash] = task + } + return successful, nil +} + +// processNodeData tries to inject a trie node data blob delivered from a remote +// peer into the state trie, returning whether anything useful was written or any +// error occurred. +func (s *stateSync) processNodeData(blob []byte) (bool, common.Hash, error) { + res := trie.SyncResult{Data: blob} + s.keccak.Reset() + s.keccak.Write(blob) + s.keccak.Sum(res.Hash[:0]) + committed, _, err := s.sched.Process([]trie.SyncResult{res}) + return committed, res.Hash, err +} + +// updateStats bumps the various state sync progress counters and displays a log +// message for the user to see. +func (s *stateSync) updateStats(written, duplicate, unexpected int, duration time.Duration) { + s.d.syncStatsLock.Lock() + defer s.d.syncStatsLock.Unlock() + + s.d.syncStatsState.pending = uint64(s.sched.Pending()) + s.d.syncStatsState.processed += uint64(written) + s.d.syncStatsState.duplicate += uint64(duplicate) + s.d.syncStatsState.unexpected += uint64(unexpected) + + if written > 0 || duplicate > 0 || unexpected > 0 { + log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "retry", len(s.tasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected) + } + if written > 0 { + rawdb.WriteFastTrieProgress(s.d.stateDB, s.d.syncStatsState.processed) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/gen_config.go b/vendor/github.com/ethereum/go-ethereum/eth/gen_config.go new file mode 100644 index 00000000..178faf7c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/gen_config.go @@ -0,0 +1,202 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package eth + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/miner" +) + +// MarshalTOML marshals as TOML. +func (c Config) MarshalTOML() (interface{}, error) { + type Config struct { + Genesis *core.Genesis `toml:",omitempty"` + NetworkId uint64 + SyncMode downloader.SyncMode + NoPruning bool + NoPrefetch bool + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ int `toml:",omitempty"` + LightBandwidthIn int `toml:",omitempty"` + LightBandwidthOut int `toml:",omitempty"` + LightPeers int `toml:",omitempty"` + OnlyAnnounce bool + ULC *ULCConfig `toml:",omitempty"` + SkipBcVersionCheck bool `toml:"-"` + DatabaseHandles int `toml:"-"` + DatabaseCache int + TrieCleanCache int + TrieDirtyCache int + TrieTimeout time.Duration + Miner miner.Config + Ethash ethash.Config + TxPool core.TxPoolConfig + GPO gasprice.Config + EnablePreimageRecording bool + DocRoot string `toml:"-"` + EWASMInterpreter string + EVMInterpreter string + ConstantinopleOverride *big.Int + RPCGasCap *big.Int `toml:",omitempty"` + } + var enc Config + enc.Genesis = c.Genesis + enc.NetworkId = c.NetworkId + enc.SyncMode = c.SyncMode + enc.NoPruning = c.NoPruning + enc.NoPrefetch = c.NoPrefetch + enc.Whitelist = c.Whitelist + enc.LightServ = c.LightServ + enc.LightBandwidthIn = c.LightBandwidthIn + enc.LightBandwidthOut = c.LightBandwidthOut + enc.LightPeers = c.LightPeers + enc.OnlyAnnounce = c.OnlyAnnounce + enc.ULC = c.ULC + enc.SkipBcVersionCheck = c.SkipBcVersionCheck + enc.DatabaseHandles = c.DatabaseHandles + enc.DatabaseCache = c.DatabaseCache + enc.TrieCleanCache = c.TrieCleanCache + enc.TrieDirtyCache = c.TrieDirtyCache + enc.TrieTimeout = c.TrieTimeout + enc.Miner = c.Miner + enc.Ethash = c.Ethash + enc.TxPool = c.TxPool + enc.GPO = c.GPO + enc.EnablePreimageRecording = c.EnablePreimageRecording + enc.DocRoot = c.DocRoot + enc.EWASMInterpreter = c.EWASMInterpreter + enc.EVMInterpreter = c.EVMInterpreter + enc.ConstantinopleOverride = c.ConstantinopleOverride + enc.RPCGasCap = c.RPCGasCap + return &enc, nil +} + +// UnmarshalTOML unmarshals from TOML. +func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { + type Config struct { + Genesis *core.Genesis `toml:",omitempty"` + NetworkId *uint64 + SyncMode *downloader.SyncMode + NoPruning *bool + NoPrefetch *bool + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ *int `toml:",omitempty"` + LightBandwidthIn *int `toml:",omitempty"` + LightBandwidthOut *int `toml:",omitempty"` + LightPeers *int `toml:",omitempty"` + OnlyAnnounce *bool + ULC *ULCConfig `toml:",omitempty"` + SkipBcVersionCheck *bool `toml:"-"` + DatabaseHandles *int `toml:"-"` + DatabaseCache *int + TrieCleanCache *int + TrieDirtyCache *int + TrieTimeout *time.Duration + Miner *miner.Config + Ethash *ethash.Config + TxPool *core.TxPoolConfig + GPO *gasprice.Config + EnablePreimageRecording *bool + DocRoot *string `toml:"-"` + EWASMInterpreter *string + EVMInterpreter *string + ConstantinopleOverride *big.Int + RPCGasCap *big.Int `toml:",omitempty"` + } + var dec Config + if err := unmarshal(&dec); err != nil { + return err + } + if dec.Genesis != nil { + c.Genesis = dec.Genesis + } + if dec.NetworkId != nil { + c.NetworkId = *dec.NetworkId + } + if dec.SyncMode != nil { + c.SyncMode = *dec.SyncMode + } + if dec.NoPruning != nil { + c.NoPruning = *dec.NoPruning + } + if dec.NoPrefetch != nil { + c.NoPrefetch = *dec.NoPrefetch + } + if dec.Whitelist != nil { + c.Whitelist = dec.Whitelist + } + if dec.LightServ != nil { + c.LightServ = *dec.LightServ + } + if dec.LightBandwidthIn != nil { + c.LightBandwidthIn = *dec.LightBandwidthIn + } + if dec.LightBandwidthOut != nil { + c.LightBandwidthOut = *dec.LightBandwidthOut + } + if dec.LightPeers != nil { + c.LightPeers = *dec.LightPeers + } + if dec.OnlyAnnounce != nil { + c.OnlyAnnounce = *dec.OnlyAnnounce + } + if dec.ULC != nil { + c.ULC = dec.ULC + } + if dec.SkipBcVersionCheck != nil { + c.SkipBcVersionCheck = *dec.SkipBcVersionCheck + } + if dec.DatabaseHandles != nil { + c.DatabaseHandles = *dec.DatabaseHandles + } + if dec.DatabaseCache != nil { + c.DatabaseCache = *dec.DatabaseCache + } + if dec.TrieCleanCache != nil { + c.TrieCleanCache = *dec.TrieCleanCache + } + if dec.TrieDirtyCache != nil { + c.TrieDirtyCache = *dec.TrieDirtyCache + } + if dec.TrieTimeout != nil { + c.TrieTimeout = *dec.TrieTimeout + } + if dec.Miner != nil { + c.Miner = *dec.Miner + } + if dec.Ethash != nil { + c.Ethash = *dec.Ethash + } + if dec.TxPool != nil { + c.TxPool = *dec.TxPool + } + if dec.GPO != nil { + c.GPO = *dec.GPO + } + if dec.EnablePreimageRecording != nil { + c.EnablePreimageRecording = *dec.EnablePreimageRecording + } + if dec.DocRoot != nil { + c.DocRoot = *dec.DocRoot + } + if dec.EWASMInterpreter != nil { + c.EWASMInterpreter = *dec.EWASMInterpreter + } + if dec.EVMInterpreter != nil { + c.EVMInterpreter = *dec.EVMInterpreter + } + if dec.ConstantinopleOverride != nil { + c.ConstantinopleOverride = dec.ConstantinopleOverride + } + if dec.RPCGasCap != nil { + c.RPCGasCap = dec.RPCGasCap + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/handler.go b/vendor/github.com/ethereum/go-ethereum/eth/handler.go new file mode 100644 index 00000000..58add2ea --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/handler.go @@ -0,0 +1,835 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package eth + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "math/big" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/fetcher" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +const ( + softResponseLimit = 2 * 1024 * 1024 // Target maximum size of returned blocks, headers or node data. + estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header + + // txChanSize is the size of channel listening to NewTxsEvent. + // The number is referenced from the size of tx pool. + txChanSize = 4096 + + // minimim number of peers to broadcast new blocks to + minBroadcastPeers = 4 +) + +var ( + syncChallengeTimeout = 15 * time.Second // Time allowance for a node to reply to the sync progress challenge +) + +// errIncompatibleConfig is returned if the requested protocols and configs are +// not compatible (low protocol version restrictions and high requirements). +var errIncompatibleConfig = errors.New("incompatible configuration") + +func errResp(code errCode, format string, v ...interface{}) error { + return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) +} + +type ProtocolManager struct { + networkID uint64 + + fastSync uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks) + acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing) + + checkpointNumber uint64 // Block number for the sync progress validator to cross reference + checkpointHash common.Hash // Block hash for the sync progress validator to cross reference + + txpool txPool + blockchain *core.BlockChain + chainconfig *params.ChainConfig + maxPeers int + + downloader *downloader.Downloader + fetcher *fetcher.Fetcher + peers *peerSet + + SubProtocols []p2p.Protocol + + eventMux *event.TypeMux + txsCh chan core.NewTxsEvent + txsSub event.Subscription + minedBlockSub *event.TypeMuxSubscription + + whitelist map[uint64]common.Hash + + // channels for fetcher, syncer, txsyncLoop + newPeerCh chan *peer + txsyncCh chan *txsync + quitSync chan struct{} + noMorePeers chan struct{} + + // wait group is used for graceful shutdowns during downloading + // and processing + wg sync.WaitGroup +} + +// NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable +// with the Ethereum network. +func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database, cacheLimit int, whitelist map[uint64]common.Hash) (*ProtocolManager, error) { + // Create the protocol manager with the base fields + manager := &ProtocolManager{ + networkID: networkID, + eventMux: mux, + txpool: txpool, + blockchain: blockchain, + chainconfig: config, + peers: newPeerSet(), + whitelist: whitelist, + newPeerCh: make(chan *peer), + noMorePeers: make(chan struct{}), + txsyncCh: make(chan *txsync), + quitSync: make(chan struct{}), + } + // If fast sync was requested and our database is empty, grant it + if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() == 0 { + manager.fastSync = uint32(1) + } + // If we have trusted checkpoints, enforce them on the chain + if checkpoint, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok { + manager.checkpointNumber = (checkpoint.SectionIndex+1)*params.CHTFrequency - 1 + manager.checkpointHash = checkpoint.SectionHead + } + // Initiate a sub-protocol for every implemented version we can handle + manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions)) + for i, version := range ProtocolVersions { + // Skip protocol version if incompatible with the mode of operation + // TODO(karalabe): hard-drop eth/62 from the code base + if atomic.LoadUint32(&manager.fastSync) == 1 && version < eth63 { + continue + } + // Compatible; initialise the sub-protocol + version := version // Closure for the run + manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{ + Name: ProtocolName, + Version: version, + Length: ProtocolLengths[i], + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + peer := manager.newPeer(int(version), p, rw) + select { + case manager.newPeerCh <- peer: + manager.wg.Add(1) + defer manager.wg.Done() + return manager.handle(peer) + case <-manager.quitSync: + return p2p.DiscQuitting + } + }, + NodeInfo: func() interface{} { + return manager.NodeInfo() + }, + PeerInfo: func(id enode.ID) interface{} { + if p := manager.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil { + return p.Info() + } + return nil + }, + }) + } + if len(manager.SubProtocols) == 0 { + return nil, errIncompatibleConfig + } + // Construct the downloader (long sync) and its backing state bloom if fast + // sync is requested. The downloader is responsible for deallocating the state + // bloom when it's done. + var stateBloom *trie.SyncBloom + if atomic.LoadUint32(&manager.fastSync) == 1 { + stateBloom = trie.NewSyncBloom(uint64(cacheLimit), chaindb) + } + manager.downloader = downloader.New(manager.checkpointNumber, chaindb, stateBloom, manager.eventMux, blockchain, nil, manager.removePeer) + + // Construct the fetcher (short sync) + validator := func(header *types.Header) error { + return engine.VerifyHeader(blockchain, header, true) + } + heighter := func() uint64 { + return blockchain.CurrentBlock().NumberU64() + } + inserter := func(blocks types.Blocks) (int, error) { + // If sync hasn't reached the checkpoint yet, deny importing weird blocks. + // + // Ideally we would also compare the head block's timestamp and similarly reject + // the propagated block if the head is too old. Unfortunately there is a corner + // case when starting new networks, where the genesis might be ancient (0 unix) + // which would prevent full nodes from accepting it. + if manager.blockchain.CurrentBlock().NumberU64() < manager.checkpointNumber { + log.Warn("Unsynced yet, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash()) + return 0, nil + } + // If fast sync is running, deny importing weird blocks. This is a problematic + // clause when starting up a new network, because fast-syncing miners might not + // accept each others' blocks until a restart. Unfortunately we haven't figured + // out a way yet where nodes can decide unilaterally whether the network is new + // or not. This should be fixed if we figure out a solution. + if atomic.LoadUint32(&manager.fastSync) == 1 { + log.Warn("Fast syncing, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash()) + return 0, nil + } + n, err := manager.blockchain.InsertChain(blocks) + if err == nil { + atomic.StoreUint32(&manager.acceptTxs, 1) // Mark initial sync done on any fetcher import + } + return n, err + } + manager.fetcher = fetcher.New(blockchain.GetBlockByHash, validator, manager.BroadcastBlock, heighter, inserter, manager.removePeer) + + return manager, nil +} + +func (pm *ProtocolManager) removePeer(id string) { + // Short circuit if the peer was already removed + peer := pm.peers.Peer(id) + if peer == nil { + return + } + log.Debug("Removing Ethereum peer", "peer", id) + + // Unregister the peer from the downloader and Ethereum peer set + pm.downloader.UnregisterPeer(id) + if err := pm.peers.Unregister(id); err != nil { + log.Error("Peer removal failed", "peer", id, "err", err) + } + // Hard disconnect at the networking layer + if peer != nil { + peer.Peer.Disconnect(p2p.DiscUselessPeer) + } +} + +func (pm *ProtocolManager) Start(maxPeers int) { + pm.maxPeers = maxPeers + + // broadcast transactions + pm.txsCh = make(chan core.NewTxsEvent, txChanSize) + pm.txsSub = pm.txpool.SubscribeNewTxsEvent(pm.txsCh) + go pm.txBroadcastLoop() + + // broadcast mined blocks + pm.minedBlockSub = pm.eventMux.Subscribe(core.NewMinedBlockEvent{}) + go pm.minedBroadcastLoop() + + // start sync handlers + go pm.syncer() + go pm.txsyncLoop() +} + +func (pm *ProtocolManager) Stop() { + log.Info("Stopping Ethereum protocol") + + pm.txsSub.Unsubscribe() // quits txBroadcastLoop + pm.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop + + // Quit the sync loop. + // After this send has completed, no new peers will be accepted. + pm.noMorePeers <- struct{}{} + + // Quit fetcher, txsyncLoop. + close(pm.quitSync) + + // Disconnect existing sessions. + // This also closes the gate for any new registrations on the peer set. + // sessions which are already established but not added to pm.peers yet + // will exit when they try to register. + pm.peers.Close() + + // Wait for all peer handler goroutines and the loops to come down. + pm.wg.Wait() + + log.Info("Ethereum protocol stopped") +} + +func (pm *ProtocolManager) newPeer(pv int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { + return newPeer(pv, p, newMeteredMsgWriter(rw)) +} + +// handle is the callback invoked to manage the life cycle of an eth peer. When +// this function terminates, the peer is disconnected. +func (pm *ProtocolManager) handle(p *peer) error { + // Ignore maxPeers if this is a trusted peer + if pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted { + return p2p.DiscTooManyPeers + } + p.Log().Debug("Ethereum peer connected", "name", p.Name()) + + // Execute the Ethereum handshake + var ( + genesis = pm.blockchain.Genesis() + head = pm.blockchain.CurrentHeader() + hash = head.Hash() + number = head.Number.Uint64() + td = pm.blockchain.GetTd(hash, number) + ) + if err := p.Handshake(pm.networkID, td, hash, genesis.Hash()); err != nil { + p.Log().Debug("Ethereum handshake failed", "err", err) + return err + } + if rw, ok := p.rw.(*meteredMsgReadWriter); ok { + rw.Init(p.version) + } + // Register the peer locally + if err := pm.peers.Register(p); err != nil { + p.Log().Error("Ethereum peer registration failed", "err", err) + return err + } + defer pm.removePeer(p.id) + + // Register the peer in the downloader. If the downloader considers it banned, we disconnect + if err := pm.downloader.RegisterPeer(p.id, p.version, p); err != nil { + return err + } + // Propagate existing transactions. new transactions appearing + // after this will be sent via broadcasts. + pm.syncTransactions(p) + + // If we have a trusted CHT, reject all peers below that (avoid fast sync eclipse) + if pm.checkpointHash != (common.Hash{}) { + // Request the peer's checkpoint header for chain height/weight validation + if err := p.RequestHeadersByNumber(pm.checkpointNumber, 1, 0, false); err != nil { + return err + } + // Start a timer to disconnect if the peer doesn't reply in time + p.syncDrop = time.AfterFunc(syncChallengeTimeout, func() { + p.Log().Warn("Checkpoint challenge timed out, dropping", "addr", p.RemoteAddr(), "type", p.Name()) + pm.removePeer(p.id) + }) + // Make sure it's cleaned up if the peer dies off + defer func() { + if p.syncDrop != nil { + p.syncDrop.Stop() + p.syncDrop = nil + } + }() + } + // If we have any explicit whitelist block hashes, request them + for number := range pm.whitelist { + if err := p.RequestHeadersByNumber(number, 1, 0, false); err != nil { + return err + } + } + // Handle incoming messages until the connection is torn down + for { + if err := pm.handleMsg(p); err != nil { + p.Log().Debug("Ethereum message handling failed", "err", err) + return err + } + } +} + +// handleMsg is invoked whenever an inbound message is received from a remote +// peer. The remote connection is torn down upon returning any error. +func (pm *ProtocolManager) handleMsg(p *peer) error { + // Read the next message from the remote peer, and ensure it's fully consumed + msg, err := p.rw.ReadMsg() + if err != nil { + return err + } + if msg.Size > ProtocolMaxMsgSize { + return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) + } + defer msg.Discard() + + // Handle the message depending on its contents + switch { + case msg.Code == StatusMsg: + // Status messages should never arrive after the handshake + return errResp(ErrExtraStatusMsg, "uncontrolled status message") + + // Block header query, collect the requested headers and reply + case msg.Code == GetBlockHeadersMsg: + // Decode the complex header query + var query getBlockHeadersData + if err := msg.Decode(&query); err != nil { + return errResp(ErrDecode, "%v: %v", msg, err) + } + hashMode := query.Origin.Hash != (common.Hash{}) + first := true + maxNonCanonical := uint64(100) + + // Gather headers until the fetch or network limits is reached + var ( + bytes common.StorageSize + headers []*types.Header + unknown bool + ) + for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit && len(headers) < downloader.MaxHeaderFetch { + // Retrieve the next header satisfying the query + var origin *types.Header + if hashMode { + if first { + first = false + origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash) + if origin != nil { + query.Origin.Number = origin.Number.Uint64() + } + } else { + origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number) + } + } else { + origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number) + } + if origin == nil { + break + } + headers = append(headers, origin) + bytes += estHeaderRlpSize + + // Advance to the next header of the query + switch { + case hashMode && query.Reverse: + // Hash based traversal towards the genesis block + ancestor := query.Skip + 1 + if ancestor == 0 { + unknown = true + } else { + query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical) + unknown = (query.Origin.Hash == common.Hash{}) + } + case hashMode && !query.Reverse: + // Hash based traversal towards the leaf block + var ( + current = origin.Number.Uint64() + next = current + query.Skip + 1 + ) + if next <= current { + infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ") + p.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos) + unknown = true + } else { + if header := pm.blockchain.GetHeaderByNumber(next); header != nil { + nextHash := header.Hash() + expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical) + if expOldHash == query.Origin.Hash { + query.Origin.Hash, query.Origin.Number = nextHash, next + } else { + unknown = true + } + } else { + unknown = true + } + } + case query.Reverse: + // Number based traversal towards the genesis block + if query.Origin.Number >= query.Skip+1 { + query.Origin.Number -= query.Skip + 1 + } else { + unknown = true + } + + case !query.Reverse: + // Number based traversal towards the leaf block + query.Origin.Number += query.Skip + 1 + } + } + return p.SendBlockHeaders(headers) + + case msg.Code == BlockHeadersMsg: + // A batch of headers arrived to one of our previous requests + var headers []*types.Header + if err := msg.Decode(&headers); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // If no headers were received, but we're expencting a checkpoint header, consider it that + if len(headers) == 0 && p.syncDrop != nil { + // Stop the timer either way, decide later to drop or not + p.syncDrop.Stop() + p.syncDrop = nil + + // If we're doing a fast sync, we must enforce the checkpoint block to avoid + // eclipse attacks. Unsynced nodes are welcome to connect after we're done + // joining the network + if atomic.LoadUint32(&pm.fastSync) == 1 { + p.Log().Warn("Dropping unsynced node during fast sync", "addr", p.RemoteAddr(), "type", p.Name()) + return errors.New("unsynced node cannot serve fast sync") + } + } + // Filter out any explicitly requested headers, deliver the rest to the downloader + filter := len(headers) == 1 + if filter { + // If it's a potential sync progress check, validate the content and advertised chain weight + if p.syncDrop != nil && headers[0].Number.Uint64() == pm.checkpointNumber { + // Disable the sync drop timer + p.syncDrop.Stop() + p.syncDrop = nil + + // Validate the header and either drop the peer or continue + if headers[0].Hash() != pm.checkpointHash { + return errors.New("checkpoint hash mismatch") + } + return nil + } + // Otherwise if it's a whitelisted block, validate against the set + if want, ok := pm.whitelist[headers[0].Number.Uint64()]; ok { + if hash := headers[0].Hash(); want != hash { + p.Log().Info("Whitelist mismatch, dropping peer", "number", headers[0].Number.Uint64(), "hash", hash, "want", want) + return errors.New("whitelist block mismatch") + } + p.Log().Debug("Whitelist block verified", "number", headers[0].Number.Uint64(), "hash", want) + } + // Irrelevant of the fork checks, send the header to the fetcher just in case + headers = pm.fetcher.FilterHeaders(p.id, headers, time.Now()) + } + if len(headers) > 0 || !filter { + err := pm.downloader.DeliverHeaders(p.id, headers) + if err != nil { + log.Debug("Failed to deliver headers", "err", err) + } + } + + case msg.Code == GetBlockBodiesMsg: + // Decode the retrieval message + msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) + if _, err := msgStream.List(); err != nil { + return err + } + // Gather blocks until the fetch or network limits is reached + var ( + hash common.Hash + bytes int + bodies []rlp.RawValue + ) + for bytes < softResponseLimit && len(bodies) < downloader.MaxBlockFetch { + // Retrieve the hash of the next block + if err := msgStream.Decode(&hash); err == rlp.EOL { + break + } else if err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Retrieve the requested block body, stopping if enough was found + if data := pm.blockchain.GetBodyRLP(hash); len(data) != 0 { + bodies = append(bodies, data) + bytes += len(data) + } + } + return p.SendBlockBodiesRLP(bodies) + + case msg.Code == BlockBodiesMsg: + // A batch of block bodies arrived to one of our previous requests + var request blockBodiesData + if err := msg.Decode(&request); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Deliver them all to the downloader for queuing + transactions := make([][]*types.Transaction, len(request)) + uncles := make([][]*types.Header, len(request)) + + for i, body := range request { + transactions[i] = body.Transactions + uncles[i] = body.Uncles + } + // Filter out any explicitly requested bodies, deliver the rest to the downloader + filter := len(transactions) > 0 || len(uncles) > 0 + if filter { + transactions, uncles = pm.fetcher.FilterBodies(p.id, transactions, uncles, time.Now()) + } + if len(transactions) > 0 || len(uncles) > 0 || !filter { + err := pm.downloader.DeliverBodies(p.id, transactions, uncles) + if err != nil { + log.Debug("Failed to deliver bodies", "err", err) + } + } + + case p.version >= eth63 && msg.Code == GetNodeDataMsg: + // Decode the retrieval message + msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) + if _, err := msgStream.List(); err != nil { + return err + } + // Gather state data until the fetch or network limits is reached + var ( + hash common.Hash + bytes int + data [][]byte + ) + for bytes < softResponseLimit && len(data) < downloader.MaxStateFetch { + // Retrieve the hash of the next state entry + if err := msgStream.Decode(&hash); err == rlp.EOL { + break + } else if err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Retrieve the requested state entry, stopping if enough was found + if entry, err := pm.blockchain.TrieNode(hash); err == nil { + data = append(data, entry) + bytes += len(entry) + } + } + return p.SendNodeData(data) + + case p.version >= eth63 && msg.Code == NodeDataMsg: + // A batch of node state data arrived to one of our previous requests + var data [][]byte + if err := msg.Decode(&data); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Deliver all to the downloader + if err := pm.downloader.DeliverNodeData(p.id, data); err != nil { + log.Debug("Failed to deliver node state data", "err", err) + } + + case p.version >= eth63 && msg.Code == GetReceiptsMsg: + // Decode the retrieval message + msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size)) + if _, err := msgStream.List(); err != nil { + return err + } + // Gather state data until the fetch or network limits is reached + var ( + hash common.Hash + bytes int + receipts []rlp.RawValue + ) + for bytes < softResponseLimit && len(receipts) < downloader.MaxReceiptFetch { + // Retrieve the hash of the next block + if err := msgStream.Decode(&hash); err == rlp.EOL { + break + } else if err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Retrieve the requested block's receipts, skipping if unknown to us + results := pm.blockchain.GetReceiptsByHash(hash) + if results == nil { + if header := pm.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash { + continue + } + } + // If known, encode and queue for response packet + if encoded, err := rlp.EncodeToBytes(results); err != nil { + log.Error("Failed to encode receipt", "err", err) + } else { + receipts = append(receipts, encoded) + bytes += len(encoded) + } + } + return p.SendReceiptsRLP(receipts) + + case p.version >= eth63 && msg.Code == ReceiptsMsg: + // A batch of receipts arrived to one of our previous requests + var receipts [][]*types.Receipt + if err := msg.Decode(&receipts); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Deliver all to the downloader + if err := pm.downloader.DeliverReceipts(p.id, receipts); err != nil { + log.Debug("Failed to deliver receipts", "err", err) + } + + case msg.Code == NewBlockHashesMsg: + var announces newBlockHashesData + if err := msg.Decode(&announces); err != nil { + return errResp(ErrDecode, "%v: %v", msg, err) + } + // Mark the hashes as present at the remote node + for _, block := range announces { + p.MarkBlock(block.Hash) + } + // Schedule all the unknown hashes for retrieval + unknown := make(newBlockHashesData, 0, len(announces)) + for _, block := range announces { + if !pm.blockchain.HasBlock(block.Hash, block.Number) { + unknown = append(unknown, block) + } + } + for _, block := range unknown { + pm.fetcher.Notify(p.id, block.Hash, block.Number, time.Now(), p.RequestOneHeader, p.RequestBodies) + } + + case msg.Code == NewBlockMsg: + // Retrieve and decode the propagated block + var request newBlockData + if err := msg.Decode(&request); err != nil { + return errResp(ErrDecode, "%v: %v", msg, err) + } + request.Block.ReceivedAt = msg.ReceivedAt + request.Block.ReceivedFrom = p + + // Mark the peer as owning the block and schedule it for import + p.MarkBlock(request.Block.Hash()) + pm.fetcher.Enqueue(p.id, request.Block) + + // Assuming the block is importable by the peer, but possibly not yet done so, + // calculate the head hash and TD that the peer truly must have. + var ( + trueHead = request.Block.ParentHash() + trueTD = new(big.Int).Sub(request.TD, request.Block.Difficulty()) + ) + // Update the peer's total difficulty if better than the previous + if _, td := p.Head(); trueTD.Cmp(td) > 0 { + p.SetHead(trueHead, trueTD) + + // Schedule a sync if above ours. Note, this will not fire a sync for a gap of + // a single block (as the true TD is below the propagated block), however this + // scenario should easily be covered by the fetcher. + currentBlock := pm.blockchain.CurrentBlock() + if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())) > 0 { + go pm.synchronise(p) + } + } + + case msg.Code == TxMsg: + // Transactions arrived, make sure we have a valid and fresh chain to handle them + if atomic.LoadUint32(&pm.acceptTxs) == 0 { + break + } + // Transactions can be processed, parse all of them and deliver to the pool + var txs []*types.Transaction + if err := msg.Decode(&txs); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + for i, tx := range txs { + // Validate and mark the remote transaction + if tx == nil { + return errResp(ErrDecode, "transaction %d is nil", i) + } + p.MarkTransaction(tx.Hash()) + } + pm.txpool.AddRemotes(txs) + + default: + return errResp(ErrInvalidMsgCode, "%v", msg.Code) + } + return nil +} + +// BroadcastBlock will either propagate a block to a subset of it's peers, or +// will only announce it's availability (depending what's requested). +func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) { + hash := block.Hash() + peers := pm.peers.PeersWithoutBlock(hash) + + // If propagation is requested, send to a subset of the peer + if propagate { + // Calculate the TD of the block (it's not imported yet, so block.Td is not valid) + var td *big.Int + if parent := pm.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1); parent != nil { + td = new(big.Int).Add(block.Difficulty(), pm.blockchain.GetTd(block.ParentHash(), block.NumberU64()-1)) + } else { + log.Error("Propagating dangling block", "number", block.Number(), "hash", hash) + return + } + // Send the block to a subset of our peers + transferLen := int(math.Sqrt(float64(len(peers)))) + if transferLen < minBroadcastPeers { + transferLen = minBroadcastPeers + } + if transferLen > len(peers) { + transferLen = len(peers) + } + transfer := peers[:transferLen] + for _, peer := range transfer { + peer.AsyncSendNewBlock(block, td) + } + log.Trace("Propagated block", "hash", hash, "recipients", len(transfer), "duration", common.PrettyDuration(time.Since(block.ReceivedAt))) + return + } + // Otherwise if the block is indeed in out own chain, announce it + if pm.blockchain.HasBlock(hash, block.NumberU64()) { + for _, peer := range peers { + peer.AsyncSendNewBlockHash(block) + } + log.Trace("Announced block", "hash", hash, "recipients", len(peers), "duration", common.PrettyDuration(time.Since(block.ReceivedAt))) + } +} + +// BroadcastTxs will propagate a batch of transactions to all peers which are not known to +// already have the given transaction. +func (pm *ProtocolManager) BroadcastTxs(txs types.Transactions) { + var txset = make(map[*peer]types.Transactions) + + // Broadcast transactions to a batch of peers not knowing about it + for _, tx := range txs { + peers := pm.peers.PeersWithoutTx(tx.Hash()) + for _, peer := range peers { + txset[peer] = append(txset[peer], tx) + } + log.Trace("Broadcast transaction", "hash", tx.Hash(), "recipients", len(peers)) + } + // FIXME include this again: peers = peers[:int(math.Sqrt(float64(len(peers))))] + for peer, txs := range txset { + peer.AsyncSendTransactions(txs) + } +} + +// Mined broadcast loop +func (pm *ProtocolManager) minedBroadcastLoop() { + // automatically stops if unsubscribe + for obj := range pm.minedBlockSub.Chan() { + if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok { + pm.BroadcastBlock(ev.Block, true) // First propagate block to peers + pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest + } + } +} + +func (pm *ProtocolManager) txBroadcastLoop() { + for { + select { + case event := <-pm.txsCh: + pm.BroadcastTxs(event.Txs) + + // Err() channel will be closed when unsubscribing. + case <-pm.txsSub.Err(): + return + } + } +} + +// NodeInfo represents a short summary of the Ethereum sub-protocol metadata +// known about the host peer. +type NodeInfo struct { + Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4) + Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain + Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block + Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules + Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block +} + +// NodeInfo retrieves some protocol metadata about the running host node. +func (pm *ProtocolManager) NodeInfo() *NodeInfo { + currentBlock := pm.blockchain.CurrentBlock() + return &NodeInfo{ + Network: pm.networkID, + Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()), + Genesis: pm.blockchain.Genesis().Hash(), + Config: pm.blockchain.Config(), + Head: currentBlock.Hash(), + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/peer.go b/vendor/github.com/ethereum/go-ethereum/eth/peer.go new file mode 100644 index 00000000..208badc5 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/peer.go @@ -0,0 +1,546 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package eth + +import ( + "errors" + "fmt" + "math/big" + "sync" + "time" + + mapset "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + errClosed = errors.New("peer set is closed") + errAlreadyRegistered = errors.New("peer is already registered") + errNotRegistered = errors.New("peer is not registered") +) + +const ( + maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS) + + // maxQueuedTxs is the maximum number of transaction lists to queue up before + // dropping broadcasts. This is a sensitive number as a transaction list might + // contain a single transaction, or thousands. + maxQueuedTxs = 128 + + // maxQueuedProps is the maximum number of block propagations to queue up before + // dropping broadcasts. There's not much point in queueing stale blocks, so a few + // that might cover uncles should be enough. + maxQueuedProps = 4 + + // maxQueuedAnns is the maximum number of block announcements to queue up before + // dropping broadcasts. Similarly to block propagations, there's no point to queue + // above some healthy uncle limit, so use that. + maxQueuedAnns = 4 + + handshakeTimeout = 5 * time.Second +) + +// PeerInfo represents a short summary of the Ethereum sub-protocol metadata known +// about a connected peer. +type PeerInfo struct { + Version int `json:"version"` // Ethereum protocol version negotiated + Difficulty *big.Int `json:"difficulty"` // Total difficulty of the peer's blockchain + Head string `json:"head"` // SHA3 hash of the peer's best owned block +} + +// propEvent is a block propagation, waiting for its turn in the broadcast queue. +type propEvent struct { + block *types.Block + td *big.Int +} + +type peer struct { + id string + + *p2p.Peer + rw p2p.MsgReadWriter + + version int // Protocol version negotiated + syncDrop *time.Timer // Timed connection dropper if sync progress isn't validated in time + + head common.Hash + td *big.Int + lock sync.RWMutex + + knownTxs mapset.Set // Set of transaction hashes known to be known by this peer + knownBlocks mapset.Set // Set of block hashes known to be known by this peer + queuedTxs chan []*types.Transaction // Queue of transactions to broadcast to the peer + queuedProps chan *propEvent // Queue of blocks to broadcast to the peer + queuedAnns chan *types.Block // Queue of blocks to announce to the peer + term chan struct{} // Termination channel to stop the broadcaster +} + +func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { + return &peer{ + Peer: p, + rw: rw, + version: version, + id: fmt.Sprintf("%x", p.ID().Bytes()[:8]), + knownTxs: mapset.NewSet(), + knownBlocks: mapset.NewSet(), + queuedTxs: make(chan []*types.Transaction, maxQueuedTxs), + queuedProps: make(chan *propEvent, maxQueuedProps), + queuedAnns: make(chan *types.Block, maxQueuedAnns), + term: make(chan struct{}), + } +} + +// broadcast is a write loop that multiplexes block propagations, announcements +// and transaction broadcasts into the remote peer. The goal is to have an async +// writer that does not lock up node internals. +func (p *peer) broadcast() { + for { + select { + case txs := <-p.queuedTxs: + if err := p.SendTransactions(txs); err != nil { + return + } + p.Log().Trace("Broadcast transactions", "count", len(txs)) + + case prop := <-p.queuedProps: + if err := p.SendNewBlock(prop.block, prop.td); err != nil { + return + } + p.Log().Trace("Propagated block", "number", prop.block.Number(), "hash", prop.block.Hash(), "td", prop.td) + + case block := <-p.queuedAnns: + if err := p.SendNewBlockHashes([]common.Hash{block.Hash()}, []uint64{block.NumberU64()}); err != nil { + return + } + p.Log().Trace("Announced block", "number", block.Number(), "hash", block.Hash()) + + case <-p.term: + return + } + } +} + +// close signals the broadcast goroutine to terminate. +func (p *peer) close() { + close(p.term) +} + +// Info gathers and returns a collection of metadata known about a peer. +func (p *peer) Info() *PeerInfo { + hash, td := p.Head() + + return &PeerInfo{ + Version: p.version, + Difficulty: td, + Head: hash.Hex(), + } +} + +// Head retrieves a copy of the current head hash and total difficulty of the +// peer. +func (p *peer) Head() (hash common.Hash, td *big.Int) { + p.lock.RLock() + defer p.lock.RUnlock() + + copy(hash[:], p.head[:]) + return hash, new(big.Int).Set(p.td) +} + +// SetHead updates the head hash and total difficulty of the peer. +func (p *peer) SetHead(hash common.Hash, td *big.Int) { + p.lock.Lock() + defer p.lock.Unlock() + + copy(p.head[:], hash[:]) + p.td.Set(td) +} + +// MarkBlock marks a block as known for the peer, ensuring that the block will +// never be propagated to this particular peer. +func (p *peer) MarkBlock(hash common.Hash) { + // If we reached the memory allowance, drop a previously known block hash + for p.knownBlocks.Cardinality() >= maxKnownBlocks { + p.knownBlocks.Pop() + } + p.knownBlocks.Add(hash) +} + +// MarkTransaction marks a transaction as known for the peer, ensuring that it +// will never be propagated to this particular peer. +func (p *peer) MarkTransaction(hash common.Hash) { + // If we reached the memory allowance, drop a previously known transaction hash + for p.knownTxs.Cardinality() >= maxKnownTxs { + p.knownTxs.Pop() + } + p.knownTxs.Add(hash) +} + +// SendTransactions sends transactions to the peer and includes the hashes +// in its transaction hash set for future reference. +func (p *peer) SendTransactions(txs types.Transactions) error { + // Mark all the transactions as known, but ensure we don't overflow our limits + for _, tx := range txs { + p.knownTxs.Add(tx.Hash()) + } + for p.knownTxs.Cardinality() >= maxKnownTxs { + p.knownTxs.Pop() + } + return p2p.Send(p.rw, TxMsg, txs) +} + +// AsyncSendTransactions queues list of transactions propagation to a remote +// peer. If the peer's broadcast queue is full, the event is silently dropped. +func (p *peer) AsyncSendTransactions(txs []*types.Transaction) { + select { + case p.queuedTxs <- txs: + // Mark all the transactions as known, but ensure we don't overflow our limits + for _, tx := range txs { + p.knownTxs.Add(tx.Hash()) + } + for p.knownTxs.Cardinality() >= maxKnownTxs { + p.knownTxs.Pop() + } + default: + p.Log().Debug("Dropping transaction propagation", "count", len(txs)) + } +} + +// SendNewBlockHashes announces the availability of a number of blocks through +// a hash notification. +func (p *peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error { + // Mark all the block hashes as known, but ensure we don't overflow our limits + for _, hash := range hashes { + p.knownBlocks.Add(hash) + } + for p.knownBlocks.Cardinality() >= maxKnownBlocks { + p.knownBlocks.Pop() + } + request := make(newBlockHashesData, len(hashes)) + for i := 0; i < len(hashes); i++ { + request[i].Hash = hashes[i] + request[i].Number = numbers[i] + } + return p2p.Send(p.rw, NewBlockHashesMsg, request) +} + +// AsyncSendNewBlockHash queues the availability of a block for propagation to a +// remote peer. If the peer's broadcast queue is full, the event is silently +// dropped. +func (p *peer) AsyncSendNewBlockHash(block *types.Block) { + select { + case p.queuedAnns <- block: + // Mark all the block hash as known, but ensure we don't overflow our limits + p.knownBlocks.Add(block.Hash()) + for p.knownBlocks.Cardinality() >= maxKnownBlocks { + p.knownBlocks.Pop() + } + default: + p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash()) + } +} + +// SendNewBlock propagates an entire block to a remote peer. +func (p *peer) SendNewBlock(block *types.Block, td *big.Int) error { + // Mark all the block hash as known, but ensure we don't overflow our limits + p.knownBlocks.Add(block.Hash()) + for p.knownBlocks.Cardinality() >= maxKnownBlocks { + p.knownBlocks.Pop() + } + return p2p.Send(p.rw, NewBlockMsg, []interface{}{block, td}) +} + +// AsyncSendNewBlock queues an entire block for propagation to a remote peer. If +// the peer's broadcast queue is full, the event is silently dropped. +func (p *peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { + select { + case p.queuedProps <- &propEvent{block: block, td: td}: + // Mark all the block hash as known, but ensure we don't overflow our limits + p.knownBlocks.Add(block.Hash()) + for p.knownBlocks.Cardinality() >= maxKnownBlocks { + p.knownBlocks.Pop() + } + default: + p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash()) + } +} + +// SendBlockHeaders sends a batch of block headers to the remote peer. +func (p *peer) SendBlockHeaders(headers []*types.Header) error { + return p2p.Send(p.rw, BlockHeadersMsg, headers) +} + +// SendBlockBodies sends a batch of block contents to the remote peer. +func (p *peer) SendBlockBodies(bodies []*blockBody) error { + return p2p.Send(p.rw, BlockBodiesMsg, blockBodiesData(bodies)) +} + +// SendBlockBodiesRLP sends a batch of block contents to the remote peer from +// an already RLP encoded format. +func (p *peer) SendBlockBodiesRLP(bodies []rlp.RawValue) error { + return p2p.Send(p.rw, BlockBodiesMsg, bodies) +} + +// SendNodeDataRLP sends a batch of arbitrary internal data, corresponding to the +// hashes requested. +func (p *peer) SendNodeData(data [][]byte) error { + return p2p.Send(p.rw, NodeDataMsg, data) +} + +// SendReceiptsRLP sends a batch of transaction receipts, corresponding to the +// ones requested from an already RLP encoded format. +func (p *peer) SendReceiptsRLP(receipts []rlp.RawValue) error { + return p2p.Send(p.rw, ReceiptsMsg, receipts) +} + +// RequestOneHeader is a wrapper around the header query functions to fetch a +// single header. It is used solely by the fetcher. +func (p *peer) RequestOneHeader(hash common.Hash) error { + p.Log().Debug("Fetching single header", "hash", hash) + return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: uint64(1), Skip: uint64(0), Reverse: false}) +} + +// RequestHeadersByHash fetches a batch of blocks' headers corresponding to the +// specified header query, based on the hash of an origin block. +func (p *peer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { + p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) + return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) +} + +// RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the +// specified header query, based on the number of an origin block. +func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { + p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) + return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) +} + +// RequestBodies fetches a batch of blocks' bodies corresponding to the hashes +// specified. +func (p *peer) RequestBodies(hashes []common.Hash) error { + p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) + return p2p.Send(p.rw, GetBlockBodiesMsg, hashes) +} + +// RequestNodeData fetches a batch of arbitrary data from a node's known state +// data, corresponding to the specified hashes. +func (p *peer) RequestNodeData(hashes []common.Hash) error { + p.Log().Debug("Fetching batch of state data", "count", len(hashes)) + return p2p.Send(p.rw, GetNodeDataMsg, hashes) +} + +// RequestReceipts fetches a batch of transaction receipts from a remote node. +func (p *peer) RequestReceipts(hashes []common.Hash) error { + p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) + return p2p.Send(p.rw, GetReceiptsMsg, hashes) +} + +// Handshake executes the eth protocol handshake, negotiating version number, +// network IDs, difficulties, head and genesis blocks. +func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash) error { + // Send out own handshake in a new thread + errc := make(chan error, 2) + var status statusData // safe to read after two values have been received from errc + + go func() { + errc <- p2p.Send(p.rw, StatusMsg, &statusData{ + ProtocolVersion: uint32(p.version), + NetworkId: network, + TD: td, + CurrentBlock: head, + GenesisBlock: genesis, + }) + }() + go func() { + errc <- p.readStatus(network, &status, genesis) + }() + timeout := time.NewTimer(handshakeTimeout) + defer timeout.Stop() + for i := 0; i < 2; i++ { + select { + case err := <-errc: + if err != nil { + return err + } + case <-timeout.C: + return p2p.DiscReadTimeout + } + } + p.td, p.head = status.TD, status.CurrentBlock + return nil +} + +func (p *peer) readStatus(network uint64, status *statusData, genesis common.Hash) (err error) { + msg, err := p.rw.ReadMsg() + if err != nil { + return err + } + if msg.Code != StatusMsg { + return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) + } + if msg.Size > ProtocolMaxMsgSize { + return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) + } + // Decode the handshake and make sure everything matches + if err := msg.Decode(&status); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + if status.GenesisBlock != genesis { + return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", status.GenesisBlock[:8], genesis[:8]) + } + if status.NetworkId != network { + return errResp(ErrNetworkIdMismatch, "%d (!= %d)", status.NetworkId, network) + } + if int(status.ProtocolVersion) != p.version { + return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version) + } + return nil +} + +// String implements fmt.Stringer. +func (p *peer) String() string { + return fmt.Sprintf("Peer %s [%s]", p.id, + fmt.Sprintf("eth/%2d", p.version), + ) +} + +// peerSet represents the collection of active peers currently participating in +// the Ethereum sub-protocol. +type peerSet struct { + peers map[string]*peer + lock sync.RWMutex + closed bool +} + +// newPeerSet creates a new peer set to track the active participants. +func newPeerSet() *peerSet { + return &peerSet{ + peers: make(map[string]*peer), + } +} + +// Register injects a new peer into the working set, or returns an error if the +// peer is already known. If a new peer it registered, its broadcast loop is also +// started. +func (ps *peerSet) Register(p *peer) error { + ps.lock.Lock() + defer ps.lock.Unlock() + + if ps.closed { + return errClosed + } + if _, ok := ps.peers[p.id]; ok { + return errAlreadyRegistered + } + ps.peers[p.id] = p + go p.broadcast() + + return nil +} + +// Unregister removes a remote peer from the active set, disabling any further +// actions to/from that particular entity. +func (ps *peerSet) Unregister(id string) error { + ps.lock.Lock() + defer ps.lock.Unlock() + + p, ok := ps.peers[id] + if !ok { + return errNotRegistered + } + delete(ps.peers, id) + p.close() + + return nil +} + +// Peer retrieves the registered peer with the given id. +func (ps *peerSet) Peer(id string) *peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + return ps.peers[id] +} + +// Len returns if the current number of peers in the set. +func (ps *peerSet) Len() int { + ps.lock.RLock() + defer ps.lock.RUnlock() + + return len(ps.peers) +} + +// PeersWithoutBlock retrieves a list of peers that do not have a given block in +// their set of known hashes. +func (ps *peerSet) PeersWithoutBlock(hash common.Hash) []*peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + list := make([]*peer, 0, len(ps.peers)) + for _, p := range ps.peers { + if !p.knownBlocks.Contains(hash) { + list = append(list, p) + } + } + return list +} + +// PeersWithoutTx retrieves a list of peers that do not have a given transaction +// in their set of known hashes. +func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + list := make([]*peer, 0, len(ps.peers)) + for _, p := range ps.peers { + if !p.knownTxs.Contains(hash) { + list = append(list, p) + } + } + return list +} + +// BestPeer retrieves the known peer with the currently highest total difficulty. +func (ps *peerSet) BestPeer() *peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + var ( + bestPeer *peer + bestTd *big.Int + ) + for _, p := range ps.peers { + if _, td := p.Head(); bestPeer == nil || td.Cmp(bestTd) > 0 { + bestPeer, bestTd = p, td + } + } + return bestPeer +} + +// Close disconnects all peers. +// No new peers can be registered after Close has returned. +func (ps *peerSet) Close() { + ps.lock.Lock() + defer ps.lock.Unlock() + + for _, p := range ps.peers { + p.Disconnect(p2p.DiscQuitting) + } + ps.closed = true +} diff --git a/vendor/github.com/ethereum/go-ethereum/eth/sync.go b/vendor/github.com/ethereum/go-ethereum/eth/sync.go new file mode 100644 index 00000000..e303ef8d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/eth/sync.go @@ -0,0 +1,224 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package eth + +import ( + "math/rand" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +const ( + forceSyncCycle = 10 * time.Second // Time interval to force syncs, even if few peers are available + minDesiredPeerCount = 5 // Amount of peers desired to start syncing + + // This is the target size for the packs of transactions sent by txsyncLoop. + // A pack can get larger than this if a single transactions exceeds this size. + txsyncPackSize = 100 * 1024 +) + +type txsync struct { + p *peer + txs []*types.Transaction +} + +// syncTransactions starts sending all currently pending transactions to the given peer. +func (pm *ProtocolManager) syncTransactions(p *peer) { + var txs types.Transactions + pending, _ := pm.txpool.Pending() + for _, batch := range pending { + txs = append(txs, batch...) + } + if len(txs) == 0 { + return + } + select { + case pm.txsyncCh <- &txsync{p, txs}: + case <-pm.quitSync: + } +} + +// txsyncLoop takes care of the initial transaction sync for each new +// connection. When a new peer appears, we relay all currently pending +// transactions. In order to minimise egress bandwidth usage, we send +// the transactions in small packs to one peer at a time. +func (pm *ProtocolManager) txsyncLoop() { + var ( + pending = make(map[enode.ID]*txsync) + sending = false // whether a send is active + pack = new(txsync) // the pack that is being sent + done = make(chan error, 1) // result of the send + ) + + // send starts a sending a pack of transactions from the sync. + send := func(s *txsync) { + // Fill pack with transactions up to the target size. + size := common.StorageSize(0) + pack.p = s.p + pack.txs = pack.txs[:0] + for i := 0; i < len(s.txs) && size < txsyncPackSize; i++ { + pack.txs = append(pack.txs, s.txs[i]) + size += s.txs[i].Size() + } + // Remove the transactions that will be sent. + s.txs = s.txs[:copy(s.txs, s.txs[len(pack.txs):])] + if len(s.txs) == 0 { + delete(pending, s.p.ID()) + } + // Send the pack in the background. + s.p.Log().Trace("Sending batch of transactions", "count", len(pack.txs), "bytes", size) + sending = true + go func() { done <- pack.p.SendTransactions(pack.txs) }() + } + + // pick chooses the next pending sync. + pick := func() *txsync { + if len(pending) == 0 { + return nil + } + n := rand.Intn(len(pending)) + 1 + for _, s := range pending { + if n--; n == 0 { + return s + } + } + return nil + } + + for { + select { + case s := <-pm.txsyncCh: + pending[s.p.ID()] = s + if !sending { + send(s) + } + case err := <-done: + sending = false + // Stop tracking peers that cause send failures. + if err != nil { + pack.p.Log().Debug("Transaction send failed", "err", err) + delete(pending, pack.p.ID()) + } + // Schedule the next send. + if s := pick(); s != nil { + send(s) + } + case <-pm.quitSync: + return + } + } +} + +// syncer is responsible for periodically synchronising with the network, both +// downloading hashes and blocks as well as handling the announcement handler. +func (pm *ProtocolManager) syncer() { + // Start and ensure cleanup of sync mechanisms + pm.fetcher.Start() + defer pm.fetcher.Stop() + defer pm.downloader.Terminate() + + // Wait for different events to fire synchronisation operations + forceSync := time.NewTicker(forceSyncCycle) + defer forceSync.Stop() + + for { + select { + case <-pm.newPeerCh: + // Make sure we have peers to select from, then sync + if pm.peers.Len() < minDesiredPeerCount { + break + } + go pm.synchronise(pm.peers.BestPeer()) + + case <-forceSync.C: + // Force a sync even if not enough peers are present + go pm.synchronise(pm.peers.BestPeer()) + + case <-pm.noMorePeers: + return + } + } +} + +// synchronise tries to sync up our local block chain with a remote peer. +func (pm *ProtocolManager) synchronise(peer *peer) { + // Short circuit if no peers are available + if peer == nil { + return + } + // Make sure the peer's TD is higher than our own + currentBlock := pm.blockchain.CurrentBlock() + td := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) + + pHead, pTd := peer.Head() + if pTd.Cmp(td) <= 0 { + return + } + // Otherwise try to sync with the downloader + mode := downloader.FullSync + if atomic.LoadUint32(&pm.fastSync) == 1 { + // Fast sync was explicitly requested, and explicitly granted + mode = downloader.FastSync + } else if currentBlock.NumberU64() == 0 && pm.blockchain.CurrentFastBlock().NumberU64() > 0 { + // The database seems empty as the current block is the genesis. Yet the fast + // block is ahead, so fast sync was enabled for this node at a certain point. + // The only scenario where this can happen is if the user manually (or via a + // bad block) rolled back a fast sync node below the sync point. In this case + // however it's safe to reenable fast sync. + atomic.StoreUint32(&pm.fastSync, 1) + mode = downloader.FastSync + } + if mode == downloader.FastSync { + // Make sure the peer's total difficulty we are synchronizing is higher. + if pm.blockchain.GetTdByHash(pm.blockchain.CurrentFastBlock().Hash()).Cmp(pTd) >= 0 { + return + } + } + // Run the sync cycle, and disable fast sync if we've went past the pivot block + if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil { + return + } + if atomic.LoadUint32(&pm.fastSync) == 1 { + log.Info("Fast sync complete, auto disabling") + atomic.StoreUint32(&pm.fastSync, 0) + } + // If we've successfully finished a sync cycle and passed any required checkpoint, + // enable accepting transactions from the network. + head := pm.blockchain.CurrentBlock() + if head.NumberU64() >= pm.checkpointNumber { + // Checkpoint passed, sanity check the timestamp to have a fallback mechanism + // for non-checkpointed (number = 0) private networks. + if head.Time() >= uint64(time.Now().AddDate(0, -1, 0).Unix()) { + atomic.StoreUint32(&pm.acceptTxs, 1) + } + } + if head.NumberU64() > 0 { + // We've completed a sync cycle, notify all peers of new state. This path is + // essential in star-topology networks where a gateway node needs to notify + // all its out-of-date peers of the availability of a new block. This failure + // scenario will most often crop up in private and hackathon networks with + // degenerate connectivity, but it should be healthy for the mainnet too to + // more reliably update peers or the local TD state. + go pm.BroadcastBlock(head, false) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethclient/ethclient.go b/vendor/github.com/ethereum/go-ethereum/ethclient/ethclient.go new file mode 100644 index 00000000..0a6f73ab --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethclient/ethclient.go @@ -0,0 +1,538 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package ethclient provides a client for the Ethereum RPC API. +package ethclient + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" +) + +// Client defines typed wrappers for the Ethereum RPC API. +type Client struct { + c *rpc.Client +} + +// Dial connects a client to the given URL. +func Dial(rawurl string) (*Client, error) { + return DialContext(context.Background(), rawurl) +} + +func DialContext(ctx context.Context, rawurl string) (*Client, error) { + c, err := rpc.DialContext(ctx, rawurl) + if err != nil { + return nil, err + } + return NewClient(c), nil +} + +// NewClient creates a client that uses the given RPC client. +func NewClient(c *rpc.Client) *Client { + return &Client{c} +} + +func (ec *Client) Close() { + ec.c.Close() +} + +// Blockchain Access + +// ChainId retrieves the current chain ID for transaction replay protection. +func (ec *Client) ChainID(ctx context.Context) (*big.Int, error) { + var result hexutil.Big + err := ec.c.CallContext(ctx, &result, "eth_chainId") + if err != nil { + return nil, err + } + return (*big.Int)(&result), err +} + +// BlockByHash returns the given full block. +// +// Note that loading full blocks requires two requests. Use HeaderByHash +// if you don't need all transactions or uncle headers. +func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + return ec.getBlock(ctx, "eth_getBlockByHash", hash, true) +} + +// BlockByNumber returns a block from the current canonical chain. If number is nil, the +// latest known block is returned. +// +// Note that loading full blocks requires two requests. Use HeaderByNumber +// if you don't need all transactions or uncle headers. +func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true) +} + +type rpcBlock struct { + Hash common.Hash `json:"hash"` + Transactions []rpcTransaction `json:"transactions"` + UncleHashes []common.Hash `json:"uncles"` +} + +func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) { + var raw json.RawMessage + err := ec.c.CallContext(ctx, &raw, method, args...) + if err != nil { + return nil, err + } else if len(raw) == 0 { + return nil, ethereum.NotFound + } + // Decode header and transactions. + var head *types.Header + var body rpcBlock + if err := json.Unmarshal(raw, &head); err != nil { + return nil, err + } + if err := json.Unmarshal(raw, &body); err != nil { + return nil, err + } + // Quick-verify transaction and uncle lists. This mostly helps with debugging the server. + if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 { + return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles") + } + if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 { + return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles") + } + if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 { + return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions") + } + if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 { + return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions") + } + // Load uncles because they are not included in the block response. + var uncles []*types.Header + if len(body.UncleHashes) > 0 { + uncles = make([]*types.Header, len(body.UncleHashes)) + reqs := make([]rpc.BatchElem, len(body.UncleHashes)) + for i := range reqs { + reqs[i] = rpc.BatchElem{ + Method: "eth_getUncleByBlockHashAndIndex", + Args: []interface{}{body.Hash, hexutil.EncodeUint64(uint64(i))}, + Result: &uncles[i], + } + } + if err := ec.c.BatchCallContext(ctx, reqs); err != nil { + return nil, err + } + for i := range reqs { + if reqs[i].Error != nil { + return nil, reqs[i].Error + } + if uncles[i] == nil { + return nil, fmt.Errorf("got null header for uncle %d of block %x", i, body.Hash[:]) + } + } + } + // Fill the sender cache of transactions in the block. + txs := make([]*types.Transaction, len(body.Transactions)) + for i, tx := range body.Transactions { + if tx.From != nil { + setSenderFromServer(tx.tx, *tx.From, body.Hash) + } + txs[i] = tx.tx + } + return types.NewBlockWithHeader(head).WithBody(txs, uncles), nil +} + +// HeaderByHash returns the block header with the given hash. +func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + var head *types.Header + err := ec.c.CallContext(ctx, &head, "eth_getBlockByHash", hash, false) + if err == nil && head == nil { + err = ethereum.NotFound + } + return head, err +} + +// HeaderByNumber returns a block header from the current canonical chain. If number is +// nil, the latest known header is returned. +func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { + var head *types.Header + err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", toBlockNumArg(number), false) + if err == nil && head == nil { + err = ethereum.NotFound + } + return head, err +} + +type rpcTransaction struct { + tx *types.Transaction + txExtraInfo +} + +type txExtraInfo struct { + BlockNumber *string `json:"blockNumber,omitempty"` + BlockHash *common.Hash `json:"blockHash,omitempty"` + From *common.Address `json:"from,omitempty"` +} + +func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error { + if err := json.Unmarshal(msg, &tx.tx); err != nil { + return err + } + return json.Unmarshal(msg, &tx.txExtraInfo) +} + +// TransactionByHash returns the transaction with the given hash. +func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) { + var json *rpcTransaction + err = ec.c.CallContext(ctx, &json, "eth_getTransactionByHash", hash) + if err != nil { + return nil, false, err + } else if json == nil { + return nil, false, ethereum.NotFound + } else if _, r, _ := json.tx.RawSignatureValues(); r == nil { + return nil, false, fmt.Errorf("server returned transaction without signature") + } + if json.From != nil && json.BlockHash != nil { + setSenderFromServer(json.tx, *json.From, *json.BlockHash) + } + return json.tx, json.BlockNumber == nil, nil +} + +// TransactionSender returns the sender address of the given transaction. The transaction +// must be known to the remote node and included in the blockchain at the given block and +// index. The sender is the one derived by the protocol at the time of inclusion. +// +// There is a fast-path for transactions retrieved by TransactionByHash and +// TransactionInBlock. Getting their sender address can be done without an RPC interaction. +func (ec *Client) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) { + // Try to load the address from the cache. + sender, err := types.Sender(&senderFromServer{blockhash: block}, tx) + if err == nil { + return sender, nil + } + var meta struct { + Hash common.Hash + From common.Address + } + if err = ec.c.CallContext(ctx, &meta, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index)); err != nil { + return common.Address{}, err + } + if meta.Hash == (common.Hash{}) || meta.Hash != tx.Hash() { + return common.Address{}, errors.New("wrong inclusion block/index") + } + return meta.From, nil +} + +// TransactionCount returns the total number of transactions in the given block. +func (ec *Client) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { + var num hexutil.Uint + err := ec.c.CallContext(ctx, &num, "eth_getBlockTransactionCountByHash", blockHash) + return uint(num), err +} + +// TransactionInBlock returns a single transaction at index in the given block. +func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { + var json *rpcTransaction + err := ec.c.CallContext(ctx, &json, "eth_getTransactionByBlockHashAndIndex", blockHash, hexutil.Uint64(index)) + if err != nil { + return nil, err + } + if json == nil { + return nil, ethereum.NotFound + } else if _, r, _ := json.tx.RawSignatureValues(); r == nil { + return nil, fmt.Errorf("server returned transaction without signature") + } + if json.From != nil && json.BlockHash != nil { + setSenderFromServer(json.tx, *json.From, *json.BlockHash) + } + return json.tx, err +} + +// TransactionReceipt returns the receipt of a transaction by transaction hash. +// Note that the receipt is not available for pending transactions. +func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + var r *types.Receipt + err := ec.c.CallContext(ctx, &r, "eth_getTransactionReceipt", txHash) + if err == nil { + if r == nil { + return nil, ethereum.NotFound + } + } + return r, err +} + +func toBlockNumArg(number *big.Int) string { + if number == nil { + return "latest" + } + return hexutil.EncodeBig(number) +} + +type rpcProgress struct { + StartingBlock hexutil.Uint64 + CurrentBlock hexutil.Uint64 + HighestBlock hexutil.Uint64 + PulledStates hexutil.Uint64 + KnownStates hexutil.Uint64 +} + +// SyncProgress retrieves the current progress of the sync algorithm. If there's +// no sync currently running, it returns nil. +func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, error) { + var raw json.RawMessage + if err := ec.c.CallContext(ctx, &raw, "eth_syncing"); err != nil { + return nil, err + } + // Handle the possible response types + var syncing bool + if err := json.Unmarshal(raw, &syncing); err == nil { + return nil, nil // Not syncing (always false) + } + var progress *rpcProgress + if err := json.Unmarshal(raw, &progress); err != nil { + return nil, err + } + return ðereum.SyncProgress{ + StartingBlock: uint64(progress.StartingBlock), + CurrentBlock: uint64(progress.CurrentBlock), + HighestBlock: uint64(progress.HighestBlock), + PulledStates: uint64(progress.PulledStates), + KnownStates: uint64(progress.KnownStates), + }, nil +} + +// SubscribeNewHead subscribes to notifications about the current blockchain head +// on the given channel. +func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newHeads") +} + +// State Access + +// NetworkID returns the network ID (also known as the chain ID) for this chain. +func (ec *Client) NetworkID(ctx context.Context) (*big.Int, error) { + version := new(big.Int) + var ver string + if err := ec.c.CallContext(ctx, &ver, "net_version"); err != nil { + return nil, err + } + if _, ok := version.SetString(ver, 10); !ok { + return nil, fmt.Errorf("invalid net_version result %q", ver) + } + return version, nil +} + +// BalanceAt returns the wei balance of the given account. +// The block number can be nil, in which case the balance is taken from the latest known block. +func (ec *Client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { + var result hexutil.Big + err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, toBlockNumArg(blockNumber)) + return (*big.Int)(&result), err +} + +// StorageAt returns the value of key in the contract storage of the given account. +// The block number can be nil, in which case the value is taken from the latest known block. +func (ec *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, toBlockNumArg(blockNumber)) + return result, err +} + +// CodeAt returns the contract code of the given account. +// The block number can be nil, in which case the code is taken from the latest known block. +func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getCode", account, toBlockNumArg(blockNumber)) + return result, err +} + +// NonceAt returns the account nonce of the given account. +// The block number can be nil, in which case the nonce is taken from the latest known block. +func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { + var result hexutil.Uint64 + err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, toBlockNumArg(blockNumber)) + return uint64(result), err +} + +// Filters + +// FilterLogs executes a filter query. +func (ec *Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { + var result []types.Log + arg, err := toFilterArg(q) + if err != nil { + return nil, err + } + err = ec.c.CallContext(ctx, &result, "eth_getLogs", arg) + return result, err +} + +// SubscribeFilterLogs subscribes to the results of a streaming filter query. +func (ec *Client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { + arg, err := toFilterArg(q) + if err != nil { + return nil, err + } + return ec.c.EthSubscribe(ctx, ch, "logs", arg) +} + +func toFilterArg(q ethereum.FilterQuery) (interface{}, error) { + arg := map[string]interface{}{ + "address": q.Addresses, + "topics": q.Topics, + } + if q.BlockHash != nil { + arg["blockHash"] = *q.BlockHash + if q.FromBlock != nil || q.ToBlock != nil { + return nil, fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock") + } + } else { + if q.FromBlock == nil { + arg["fromBlock"] = "0x0" + } else { + arg["fromBlock"] = toBlockNumArg(q.FromBlock) + } + arg["toBlock"] = toBlockNumArg(q.ToBlock) + } + return arg, nil +} + +// Pending State + +// PendingBalanceAt returns the wei balance of the given account in the pending state. +func (ec *Client) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) { + var result hexutil.Big + err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, "pending") + return (*big.Int)(&result), err +} + +// PendingStorageAt returns the value of key in the contract storage of the given account in the pending state. +func (ec *Client) PendingStorageAt(ctx context.Context, account common.Address, key common.Hash) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, "pending") + return result, err +} + +// PendingCodeAt returns the contract code of the given account in the pending state. +func (ec *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getCode", account, "pending") + return result, err +} + +// PendingNonceAt returns the account nonce of the given account in the pending state. +// This is the nonce that should be used for the next transaction. +func (ec *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { + var result hexutil.Uint64 + err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, "pending") + return uint64(result), err +} + +// PendingTransactionCount returns the total number of transactions in the pending state. +func (ec *Client) PendingTransactionCount(ctx context.Context) (uint, error) { + var num hexutil.Uint + err := ec.c.CallContext(ctx, &num, "eth_getBlockTransactionCountByNumber", "pending") + return uint(num), err +} + +// TODO: SubscribePendingTransactions (needs server side) + +// Contract Calling + +// CallContract executes a message call transaction, which is directly executed in the VM +// of the node, but never mined into the blockchain. +// +// blockNumber selects the block height at which the call runs. It can be nil, in which +// case the code is taken from the latest known block. Note that state from very old +// blocks might not be available. +func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + var hex hexutil.Bytes + err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), toBlockNumArg(blockNumber)) + if err != nil { + return nil, err + } + return hex, nil +} + +// PendingCallContract executes a message call transaction using the EVM. +// The state seen by the contract call is the pending state. +func (ec *Client) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { + var hex hexutil.Bytes + err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), "pending") + if err != nil { + return nil, err + } + return hex, nil +} + +// SuggestGasPrice retrieves the currently suggested gas price to allow a timely +// execution of a transaction. +func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + var hex hexutil.Big + if err := ec.c.CallContext(ctx, &hex, "eth_gasPrice"); err != nil { + return nil, err + } + return (*big.Int)(&hex), nil +} + +// EstimateGas tries to estimate the gas needed to execute a specific transaction based on +// the current pending state of the backend blockchain. There is no guarantee that this is +// the true gas limit requirement as other transactions may be added or removed by miners, +// but it should provide a basis for setting a reasonable default. +func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { + var hex hexutil.Uint64 + err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg)) + if err != nil { + return 0, err + } + return uint64(hex), nil +} + +// SendTransaction injects a signed transaction into the pending pool for execution. +// +// If the transaction was a contract creation use the TransactionReceipt method to get the +// contract address after the transaction has been mined. +func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error { + data, err := rlp.EncodeToBytes(tx) + if err != nil { + return err + } + return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) +} + +func toCallArg(msg ethereum.CallMsg) interface{} { + arg := map[string]interface{}{ + "from": msg.From, + "to": msg.To, + } + if len(msg.Data) > 0 { + arg["data"] = hexutil.Bytes(msg.Data) + } + if msg.Value != nil { + arg["value"] = (*hexutil.Big)(msg.Value) + } + if msg.Gas != 0 { + arg["gas"] = hexutil.Uint64(msg.Gas) + } + if msg.GasPrice != nil { + arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice) + } + return arg +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethdb/batch.go b/vendor/github.com/ethereum/go-ethereum/ethdb/batch.go new file mode 100644 index 00000000..e261415b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethdb/batch.go @@ -0,0 +1,46 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethdb + +// IdealBatchSize defines the size of the data batches should ideally add in one +// write. +const IdealBatchSize = 100 * 1024 + +// Batch is a write-only database that commits changes to its host database +// when Write is called. A batch cannot be used concurrently. +type Batch interface { + KeyValueWriter + + // ValueSize retrieves the amount of data queued up for writing. + ValueSize() int + + // Write flushes any accumulated data to disk. + Write() error + + // Reset resets the batch for reuse. + Reset() + + // Replay replays the batch contents. + Replay(w KeyValueWriter) error +} + +// Batcher wraps the NewBatch method of a backing data store. +type Batcher interface { + // NewBatch creates a write-only database that buffers changes to its host db + // until a final write is called. + NewBatch() Batch +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethdb/database.go b/vendor/github.com/ethereum/go-ethereum/ethdb/database.go new file mode 100644 index 00000000..1ba169bc --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethdb/database.go @@ -0,0 +1,131 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package ethdb defines the interfaces for an Ethereum data store. +package ethdb + +import "io" + +// KeyValueReader wraps the Has and Get method of a backing data store. +type KeyValueReader interface { + // Has retrieves if a key is present in the key-value data store. + Has(key []byte) (bool, error) + + // Get retrieves the given key if it's present in the key-value data store. + Get(key []byte) ([]byte, error) +} + +// KeyValueWriter wraps the Put method of a backing data store. +type KeyValueWriter interface { + // Put inserts the given value into the key-value data store. + Put(key []byte, value []byte) error + + // Delete removes the key from the key-value data store. + Delete(key []byte) error +} + +// Stater wraps the Stat method of a backing data store. +type Stater interface { + // Stat returns a particular internal stat of the database. + Stat(property string) (string, error) +} + +// Compacter wraps the Compact method of a backing data store. +type Compacter interface { + // Compact flattens the underlying data store for the given key range. In essence, + // deleted and overwritten versions are discarded, and the data is rearranged to + // reduce the cost of operations needed to access them. + // + // A nil start is treated as a key before all keys in the data store; a nil limit + // is treated as a key after all keys in the data store. If both is nil then it + // will compact entire data store. + Compact(start []byte, limit []byte) error +} + +// KeyValueStore contains all the methods required to allow handling different +// key-value data stores backing the high level database. +type KeyValueStore interface { + KeyValueReader + KeyValueWriter + Batcher + Iteratee + Stater + Compacter + io.Closer +} + +// AncientReader contains the methods required to read from immutable ancient data. +type AncientReader interface { + // HasAncient returns an indicator whether the specified data exists in the + // ancient store. + HasAncient(kind string, number uint64) (bool, error) + + // Ancient retrieves an ancient binary blob from the append-only immutable files. + Ancient(kind string, number uint64) ([]byte, error) + + // Ancients returns the ancient item numbers in the ancient store. + Ancients() (uint64, error) + + // AncientSize returns the ancient size of the specified category. + AncientSize(kind string) (uint64, error) +} + +// AncientWriter contains the methods required to write to immutable ancient data. +type AncientWriter interface { + // AppendAncient injects all binary blobs belong to block at the end of the + // append-only immutable table files. + AppendAncient(number uint64, hash, header, body, receipt, td []byte) error + + // TruncateAncients discards all but the first n ancient data from the ancient store. + TruncateAncients(n uint64) error + + // Sync flushes all in-memory ancient store data to disk. + Sync() error +} + +// Reader contains the methods required to read data from both key-value as well as +// immutable ancient data. +type Reader interface { + KeyValueReader + AncientReader +} + +// Writer contains the methods required to write data to both key-value as well as +// immutable ancient data. +type Writer interface { + KeyValueWriter + AncientWriter +} + +// AncientStore contains all the methods required to allow handling different +// ancient data stores backing immutable chain data store. +type AncientStore interface { + AncientReader + AncientWriter + io.Closer +} + +// Database contains all the methods required by the high level database to not +// only access the key-value data store but also the chain freezer. +type Database interface { + Reader + Writer + Batcher + Iteratee + Stater + Compacter + io.Closer +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethdb/iterator.go b/vendor/github.com/ethereum/go-ethereum/ethdb/iterator.go new file mode 100644 index 00000000..419e9bdf --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethdb/iterator.go @@ -0,0 +1,66 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethdb + +// Iterator iterates over a database's key/value pairs in ascending key order. +// +// When it encounters an error any seek will return false and will yield no key/ +// value pairs. The error can be queried by calling the Error method. Calling +// Release is still necessary. +// +// An iterator must be released after use, but it is not necessary to read an +// iterator until exhaustion. An iterator is not safe for concurrent use, but it +// is safe to use multiple iterators concurrently. +type Iterator interface { + // Next moves the iterator to the next key/value pair. It returns whether the + // iterator is exhausted. + Next() bool + + // Error returns any accumulated error. Exhausting all the key/value pairs + // is not considered to be an error. + Error() error + + // Key returns the key of the current key/value pair, or nil if done. The caller + // should not modify the contents of the returned slice, and its contents may + // change on the next call to Next. + Key() []byte + + // Value returns the value of the current key/value pair, or nil if done. The + // caller should not modify the contents of the returned slice, and its contents + // may change on the next call to Next. + Value() []byte + + // Release releases associated resources. Release should always succeed and can + // be called multiple times without causing error. + Release() +} + +// Iteratee wraps the NewIterator methods of a backing data store. +type Iteratee interface { + // NewIterator creates a binary-alphabetical iterator over the entire keyspace + // contained within the key-value database. + NewIterator() Iterator + + // NewIteratorWithStart creates a binary-alphabetical iterator over a subset of + // database content starting at a particular initial key (or after, if it does + // not exist). + NewIteratorWithStart(start []byte) Iterator + + // NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset + // of database content with a particular key prefix. + NewIteratorWithPrefix(prefix []byte) Iterator +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethdb/leveldb/leveldb.go b/vendor/github.com/ethereum/go-ethereum/ethdb/leveldb/leveldb.go new file mode 100644 index 00000000..3781a6da --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethdb/leveldb/leveldb.go @@ -0,0 +1,458 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build !js + +// Package leveldb implements the key-value database layer based on LevelDB. +package leveldb + +import ( + "fmt" + "strconv" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" +) + +const ( + // degradationWarnInterval specifies how often warning should be printed if the + // leveldb database cannot keep up with requested writes. + degradationWarnInterval = time.Minute + + // minCache is the minimum amount of memory in megabytes to allocate to leveldb + // read and write caching, split half and half. + minCache = 16 + + // minHandles is the minimum number of files handles to allocate to the open + // database files. + minHandles = 16 + + // metricsGatheringInterval specifies the interval to retrieve leveldb database + // compaction, io and pause stats to report to the user. + metricsGatheringInterval = 3 * time.Second +) + +// Database is a persistent key-value store. Apart from basic data storage +// functionality it also supports batch writes and iterating over the keyspace in +// binary-alphabetical order. +type Database struct { + fn string // filename for reporting + db *leveldb.DB // LevelDB instance + + compTimeMeter metrics.Meter // Meter for measuring the total time spent in database compaction + compReadMeter metrics.Meter // Meter for measuring the data read during compaction + compWriteMeter metrics.Meter // Meter for measuring the data written during compaction + writeDelayNMeter metrics.Meter // Meter for measuring the write delay number due to database compaction + writeDelayMeter metrics.Meter // Meter for measuring the write delay duration due to database compaction + diskSizeGauge metrics.Gauge // Gauge for tracking the size of all the levels in the database + diskReadMeter metrics.Meter // Meter for measuring the effective amount of data read + diskWriteMeter metrics.Meter // Meter for measuring the effective amount of data written + + quitLock sync.Mutex // Mutex protecting the quit channel access + quitChan chan chan error // Quit channel to stop the metrics collection before closing the database + + log log.Logger // Contextual logger tracking the database path +} + +// New returns a wrapped LevelDB object. The namespace is the prefix that the +// metrics reporting should use for surfacing internal stats. +func New(file string, cache int, handles int, namespace string) (*Database, error) { + // Ensure we have some minimal caching and file guarantees + if cache < minCache { + cache = minCache + } + if handles < minHandles { + handles = minHandles + } + logger := log.New("database", file) + logger.Info("Allocated cache and file handles", "cache", common.StorageSize(cache*1024*1024), "handles", handles) + + // Open the db and recover any potential corruptions + db, err := leveldb.OpenFile(file, &opt.Options{ + OpenFilesCacheCapacity: handles, + BlockCacheCapacity: cache / 2 * opt.MiB, + WriteBuffer: cache / 4 * opt.MiB, // Two of these are used internally + Filter: filter.NewBloomFilter(10), + }) + if _, corrupted := err.(*errors.ErrCorrupted); corrupted { + db, err = leveldb.RecoverFile(file, nil) + } + if err != nil { + return nil, err + } + // Assemble the wrapper with all the registered metrics + ldb := &Database{ + fn: file, + db: db, + log: logger, + quitChan: make(chan chan error), + } + ldb.compTimeMeter = metrics.NewRegisteredMeter(namespace+"compact/time", nil) + ldb.compReadMeter = metrics.NewRegisteredMeter(namespace+"compact/input", nil) + ldb.compWriteMeter = metrics.NewRegisteredMeter(namespace+"compact/output", nil) + ldb.diskSizeGauge = metrics.NewRegisteredGauge(namespace+"disk/size", nil) + ldb.diskReadMeter = metrics.NewRegisteredMeter(namespace+"disk/read", nil) + ldb.diskWriteMeter = metrics.NewRegisteredMeter(namespace+"disk/write", nil) + ldb.writeDelayMeter = metrics.NewRegisteredMeter(namespace+"compact/writedelay/duration", nil) + ldb.writeDelayNMeter = metrics.NewRegisteredMeter(namespace+"compact/writedelay/counter", nil) + + // Start up the metrics gathering and return + go ldb.meter(metricsGatheringInterval) + return ldb, nil +} + +// Close stops the metrics collection, flushes any pending data to disk and closes +// all io accesses to the underlying key-value store. +func (db *Database) Close() error { + db.quitLock.Lock() + defer db.quitLock.Unlock() + + if db.quitChan != nil { + errc := make(chan error) + db.quitChan <- errc + if err := <-errc; err != nil { + db.log.Error("Metrics collection failed", "err", err) + } + db.quitChan = nil + } + return db.db.Close() +} + +// Has retrieves if a key is present in the key-value store. +func (db *Database) Has(key []byte) (bool, error) { + return db.db.Has(key, nil) +} + +// Get retrieves the given key if it's present in the key-value store. +func (db *Database) Get(key []byte) ([]byte, error) { + dat, err := db.db.Get(key, nil) + if err != nil { + return nil, err + } + return dat, nil +} + +// Put inserts the given value into the key-value store. +func (db *Database) Put(key []byte, value []byte) error { + return db.db.Put(key, value, nil) +} + +// Delete removes the key from the key-value store. +func (db *Database) Delete(key []byte) error { + return db.db.Delete(key, nil) +} + +// NewBatch creates a write-only key-value store that buffers changes to its host +// database until a final write is called. +func (db *Database) NewBatch() ethdb.Batch { + return &batch{ + db: db.db, + b: new(leveldb.Batch), + } +} + +// NewIterator creates a binary-alphabetical iterator over the entire keyspace +// contained within the leveldb database. +func (db *Database) NewIterator() ethdb.Iterator { + return db.db.NewIterator(new(util.Range), nil) +} + +// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of +// database content starting at a particular initial key (or after, if it does +// not exist). +func (db *Database) NewIteratorWithStart(start []byte) ethdb.Iterator { + return db.db.NewIterator(&util.Range{Start: start}, nil) +} + +// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset +// of database content with a particular key prefix. +func (db *Database) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator { + return db.db.NewIterator(util.BytesPrefix(prefix), nil) +} + +// Stat returns a particular internal stat of the database. +func (db *Database) Stat(property string) (string, error) { + return db.db.GetProperty(property) +} + +// Compact flattens the underlying data store for the given key range. In essence, +// deleted and overwritten versions are discarded, and the data is rearranged to +// reduce the cost of operations needed to access them. +// +// A nil start is treated as a key before all keys in the data store; a nil limit +// is treated as a key after all keys in the data store. If both is nil then it +// will compact entire data store. +func (db *Database) Compact(start []byte, limit []byte) error { + return db.db.CompactRange(util.Range{Start: start, Limit: limit}) +} + +// Path returns the path to the database directory. +func (db *Database) Path() string { + return db.fn +} + +// meter periodically retrieves internal leveldb counters and reports them to +// the metrics subsystem. +// +// This is how a LevelDB stats table looks like (currently): +// Compactions +// Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB) +// -------+------------+---------------+---------------+---------------+--------------- +// 0 | 0 | 0.00000 | 1.27969 | 0.00000 | 12.31098 +// 1 | 85 | 109.27913 | 28.09293 | 213.92493 | 214.26294 +// 2 | 523 | 1000.37159 | 7.26059 | 66.86342 | 66.77884 +// 3 | 570 | 1113.18458 | 0.00000 | 0.00000 | 0.00000 +// +// This is how the write delay look like (currently): +// DelayN:5 Delay:406.604657ms Paused: false +// +// This is how the iostats look like (currently): +// Read(MB):3895.04860 Write(MB):3654.64712 +func (db *Database) meter(refresh time.Duration) { + // Create the counters to store current and previous compaction values + compactions := make([][]float64, 2) + for i := 0; i < 2; i++ { + compactions[i] = make([]float64, 4) + } + // Create storage for iostats. + var iostats [2]float64 + + // Create storage and warning log tracer for write delay. + var ( + delaystats [2]int64 + lastWritePaused time.Time + ) + + var ( + errc chan error + merr error + ) + + // Iterate ad infinitum and collect the stats + for i := 1; errc == nil && merr == nil; i++ { + // Retrieve the database stats + stats, err := db.db.GetProperty("leveldb.stats") + if err != nil { + db.log.Error("Failed to read database stats", "err", err) + merr = err + continue + } + // Find the compaction table, skip the header + lines := strings.Split(stats, "\n") + for len(lines) > 0 && strings.TrimSpace(lines[0]) != "Compactions" { + lines = lines[1:] + } + if len(lines) <= 3 { + db.log.Error("Compaction leveldbTable not found") + merr = errors.New("compaction leveldbTable not found") + continue + } + lines = lines[3:] + + // Iterate over all the leveldbTable rows, and accumulate the entries + for j := 0; j < len(compactions[i%2]); j++ { + compactions[i%2][j] = 0 + } + for _, line := range lines { + parts := strings.Split(line, "|") + if len(parts) != 6 { + break + } + for idx, counter := range parts[2:] { + value, err := strconv.ParseFloat(strings.TrimSpace(counter), 64) + if err != nil { + db.log.Error("Compaction entry parsing failed", "err", err) + merr = err + continue + } + compactions[i%2][idx] += value + } + } + // Update all the requested meters + if db.diskSizeGauge != nil { + db.diskSizeGauge.Update(int64(compactions[i%2][0] * 1024 * 1024)) + } + if db.compTimeMeter != nil { + db.compTimeMeter.Mark(int64((compactions[i%2][1] - compactions[(i-1)%2][1]) * 1000 * 1000 * 1000)) + } + if db.compReadMeter != nil { + db.compReadMeter.Mark(int64((compactions[i%2][2] - compactions[(i-1)%2][2]) * 1024 * 1024)) + } + if db.compWriteMeter != nil { + db.compWriteMeter.Mark(int64((compactions[i%2][3] - compactions[(i-1)%2][3]) * 1024 * 1024)) + } + // Retrieve the write delay statistic + writedelay, err := db.db.GetProperty("leveldb.writedelay") + if err != nil { + db.log.Error("Failed to read database write delay statistic", "err", err) + merr = err + continue + } + var ( + delayN int64 + delayDuration string + duration time.Duration + paused bool + ) + if n, err := fmt.Sscanf(writedelay, "DelayN:%d Delay:%s Paused:%t", &delayN, &delayDuration, &paused); n != 3 || err != nil { + db.log.Error("Write delay statistic not found") + merr = err + continue + } + duration, err = time.ParseDuration(delayDuration) + if err != nil { + db.log.Error("Failed to parse delay duration", "err", err) + merr = err + continue + } + if db.writeDelayNMeter != nil { + db.writeDelayNMeter.Mark(delayN - delaystats[0]) + } + if db.writeDelayMeter != nil { + db.writeDelayMeter.Mark(duration.Nanoseconds() - delaystats[1]) + } + // If a warning that db is performing compaction has been displayed, any subsequent + // warnings will be withheld for one minute not to overwhelm the user. + if paused && delayN-delaystats[0] == 0 && duration.Nanoseconds()-delaystats[1] == 0 && + time.Now().After(lastWritePaused.Add(degradationWarnInterval)) { + db.log.Warn("Database compacting, degraded performance") + lastWritePaused = time.Now() + } + delaystats[0], delaystats[1] = delayN, duration.Nanoseconds() + + // Retrieve the database iostats. + ioStats, err := db.db.GetProperty("leveldb.iostats") + if err != nil { + db.log.Error("Failed to read database iostats", "err", err) + merr = err + continue + } + var nRead, nWrite float64 + parts := strings.Split(ioStats, " ") + if len(parts) < 2 { + db.log.Error("Bad syntax of ioStats", "ioStats", ioStats) + merr = fmt.Errorf("bad syntax of ioStats %s", ioStats) + continue + } + if n, err := fmt.Sscanf(parts[0], "Read(MB):%f", &nRead); n != 1 || err != nil { + db.log.Error("Bad syntax of read entry", "entry", parts[0]) + merr = err + continue + } + if n, err := fmt.Sscanf(parts[1], "Write(MB):%f", &nWrite); n != 1 || err != nil { + db.log.Error("Bad syntax of write entry", "entry", parts[1]) + merr = err + continue + } + if db.diskReadMeter != nil { + db.diskReadMeter.Mark(int64((nRead - iostats[0]) * 1024 * 1024)) + } + if db.diskWriteMeter != nil { + db.diskWriteMeter.Mark(int64((nWrite - iostats[1]) * 1024 * 1024)) + } + iostats[0], iostats[1] = nRead, nWrite + + // Sleep a bit, then repeat the stats collection + select { + case errc = <-db.quitChan: + // Quit requesting, stop hammering the database + case <-time.After(refresh): + // Timeout, gather a new set of stats + } + } + + if errc == nil { + errc = <-db.quitChan + } + errc <- merr +} + +// batch is a write-only leveldb batch that commits changes to its host database +// when Write is called. A batch cannot be used concurrently. +type batch struct { + db *leveldb.DB + b *leveldb.Batch + size int +} + +// Put inserts the given value into the batch for later committing. +func (b *batch) Put(key, value []byte) error { + b.b.Put(key, value) + b.size += len(value) + return nil +} + +// Delete inserts the a key removal into the batch for later committing. +func (b *batch) Delete(key []byte) error { + b.b.Delete(key) + b.size++ + return nil +} + +// ValueSize retrieves the amount of data queued up for writing. +func (b *batch) ValueSize() int { + return b.size +} + +// Write flushes any accumulated data to disk. +func (b *batch) Write() error { + return b.db.Write(b.b, nil) +} + +// Reset resets the batch for reuse. +func (b *batch) Reset() { + b.b.Reset() + b.size = 0 +} + +// Replay replays the batch contents. +func (b *batch) Replay(w ethdb.KeyValueWriter) error { + return b.b.Replay(&replayer{writer: w}) +} + +// replayer is a small wrapper to implement the correct replay methods. +type replayer struct { + writer ethdb.KeyValueWriter + failure error +} + +// Put inserts the given value into the key-value data store. +func (r *replayer) Put(key, value []byte) { + // If the replay already failed, stop executing ops + if r.failure != nil { + return + } + r.failure = r.writer.Put(key, value) +} + +// Delete removes the key from the key-value data store. +func (r *replayer) Delete(key []byte) { + // If the replay already failed, stop executing ops + if r.failure != nil { + return + } + r.failure = r.writer.Delete(key) +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethdb/memorydb/memorydb.go b/vendor/github.com/ethereum/go-ethereum/ethdb/memorydb/memorydb.go new file mode 100644 index 00000000..caa9b02a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethdb/memorydb/memorydb.go @@ -0,0 +1,343 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package memorydb implements the key-value database layer based on memory maps. +package memorydb + +import ( + "errors" + "sort" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" +) + +var ( + // errMemorydbClosed is returned if a memory database was already closed at the + // invocation of a data access operation. + errMemorydbClosed = errors.New("database closed") + + // errMemorydbNotFound is returned if a key is requested that is not found in + // the provided memory database. + errMemorydbNotFound = errors.New("not found") +) + +// Database is an ephemeral key-value store. Apart from basic data storage +// functionality it also supports batch writes and iterating over the keyspace in +// binary-alphabetical order. +type Database struct { + db map[string][]byte + lock sync.RWMutex +} + +// New returns a wrapped map with all the required database interface methods +// implemented. +func New() *Database { + return &Database{ + db: make(map[string][]byte), + } +} + +// NewWithCap returns a wrapped map pre-allocated to the provided capcity with +// all the required database interface methods implemented. +func NewWithCap(size int) *Database { + return &Database{ + db: make(map[string][]byte, size), + } +} + +// Close deallocates the internal map and ensures any consecutive data access op +// failes with an error. +func (db *Database) Close() error { + db.lock.Lock() + defer db.lock.Unlock() + + db.db = nil + return nil +} + +// Has retrieves if a key is present in the key-value store. +func (db *Database) Has(key []byte) (bool, error) { + db.lock.RLock() + defer db.lock.RUnlock() + + if db.db == nil { + return false, errMemorydbClosed + } + _, ok := db.db[string(key)] + return ok, nil +} + +// Get retrieves the given key if it's present in the key-value store. +func (db *Database) Get(key []byte) ([]byte, error) { + db.lock.RLock() + defer db.lock.RUnlock() + + if db.db == nil { + return nil, errMemorydbClosed + } + if entry, ok := db.db[string(key)]; ok { + return common.CopyBytes(entry), nil + } + return nil, errMemorydbNotFound +} + +// Put inserts the given value into the key-value store. +func (db *Database) Put(key []byte, value []byte) error { + db.lock.Lock() + defer db.lock.Unlock() + + if db.db == nil { + return errMemorydbClosed + } + db.db[string(key)] = common.CopyBytes(value) + return nil +} + +// Delete removes the key from the key-value store. +func (db *Database) Delete(key []byte) error { + db.lock.Lock() + defer db.lock.Unlock() + + if db.db == nil { + return errMemorydbClosed + } + delete(db.db, string(key)) + return nil +} + +// NewBatch creates a write-only key-value store that buffers changes to its host +// database until a final write is called. +func (db *Database) NewBatch() ethdb.Batch { + return &batch{ + db: db, + } +} + +// NewIterator creates a binary-alphabetical iterator over the entire keyspace +// contained within the memory database. +func (db *Database) NewIterator() ethdb.Iterator { + return db.NewIteratorWithStart(nil) +} + +// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of +// database content starting at a particular initial key (or after, if it does +// not exist). +func (db *Database) NewIteratorWithStart(start []byte) ethdb.Iterator { + db.lock.RLock() + defer db.lock.RUnlock() + + var ( + st = string(start) + keys = make([]string, 0, len(db.db)) + values = make([][]byte, 0, len(db.db)) + ) + // Collect the keys from the memory database corresponding to the given start + for key := range db.db { + if key >= st { + keys = append(keys, key) + } + } + // Sort the items and retrieve the associated values + sort.Strings(keys) + for _, key := range keys { + values = append(values, db.db[key]) + } + return &iterator{ + keys: keys, + values: values, + } +} + +// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset +// of database content with a particular key prefix. +func (db *Database) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator { + db.lock.RLock() + defer db.lock.RUnlock() + + var ( + pr = string(prefix) + keys = make([]string, 0, len(db.db)) + values = make([][]byte, 0, len(db.db)) + ) + // Collect the keys from the memory database corresponding to the given prefix + for key := range db.db { + if strings.HasPrefix(key, pr) { + keys = append(keys, key) + } + } + // Sort the items and retrieve the associated values + sort.Strings(keys) + for _, key := range keys { + values = append(values, db.db[key]) + } + return &iterator{ + keys: keys, + values: values, + } +} + +// Stat returns a particular internal stat of the database. +func (db *Database) Stat(property string) (string, error) { + return "", errors.New("unknown property") +} + +// Compact is not supported on a memory database. +func (db *Database) Compact(start []byte, limit []byte) error { + return errors.New("unsupported operation") +} + +// Len returns the number of entries currently present in the memory database. +// +// Note, this method is only used for testing (i.e. not public in general) and +// does not have explicit checks for closed-ness to allow simpler testing code. +func (db *Database) Len() int { + db.lock.RLock() + defer db.lock.RUnlock() + + return len(db.db) +} + +// keyvalue is a key-value tuple tagged with a deletion field to allow creating +// memory-database write batches. +type keyvalue struct { + key []byte + value []byte + delete bool +} + +// batch is a write-only memory batch that commits changes to its host +// database when Write is called. A batch cannot be used concurrently. +type batch struct { + db *Database + writes []keyvalue + size int +} + +// Put inserts the given value into the batch for later committing. +func (b *batch) Put(key, value []byte) error { + b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false}) + b.size += len(value) + return nil +} + +// Delete inserts the a key removal into the batch for later committing. +func (b *batch) Delete(key []byte) error { + b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true}) + b.size += 1 + return nil +} + +// ValueSize retrieves the amount of data queued up for writing. +func (b *batch) ValueSize() int { + return b.size +} + +// Write flushes any accumulated data to the memory database. +func (b *batch) Write() error { + b.db.lock.Lock() + defer b.db.lock.Unlock() + + for _, keyvalue := range b.writes { + if keyvalue.delete { + delete(b.db.db, string(keyvalue.key)) + continue + } + b.db.db[string(keyvalue.key)] = keyvalue.value + } + return nil +} + +// Reset resets the batch for reuse. +func (b *batch) Reset() { + b.writes = b.writes[:0] + b.size = 0 +} + +// Replay replays the batch contents. +func (b *batch) Replay(w ethdb.KeyValueWriter) error { + for _, keyvalue := range b.writes { + if keyvalue.delete { + if err := w.Delete(keyvalue.key); err != nil { + return err + } + continue + } + if err := w.Put(keyvalue.key, keyvalue.value); err != nil { + return err + } + } + return nil +} + +// iterator can walk over the (potentially partial) keyspace of a memory key +// value store. Internally it is a deep copy of the entire iterated state, +// sorted by keys. +type iterator struct { + inited bool + keys []string + values [][]byte +} + +// Next moves the iterator to the next key/value pair. It returns whether the +// iterator is exhausted. +func (it *iterator) Next() bool { + // If the iterator was not yet initialized, do it now + if !it.inited { + it.inited = true + return len(it.keys) > 0 + } + // Iterator already initialize, advance it + if len(it.keys) > 0 { + it.keys = it.keys[1:] + it.values = it.values[1:] + } + return len(it.keys) > 0 +} + +// Error returns any accumulated error. Exhausting all the key/value pairs +// is not considered to be an error. A memory iterator cannot encounter errors. +func (it *iterator) Error() error { + return nil +} + +// Key returns the key of the current key/value pair, or nil if done. The caller +// should not modify the contents of the returned slice, and its contents may +// change on the next call to Next. +func (it *iterator) Key() []byte { + if len(it.keys) > 0 { + return []byte(it.keys[0]) + } + return nil +} + +// Value returns the value of the current key/value pair, or nil if done. The +// caller should not modify the contents of the returned slice, and its contents +// may change on the next call to Next. +func (it *iterator) Value() []byte { + if len(it.values) > 0 { + return it.values[0] + } + return nil +} + +// Release releases associated resources. Release should always succeed and can +// be called multiple times without causing error. +func (it *iterator) Release() { + it.keys, it.values = nil, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/ethstats/ethstats.go b/vendor/github.com/ethereum/go-ethereum/ethstats/ethstats.go new file mode 100644 index 00000000..caf23209 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/ethstats/ethstats.go @@ -0,0 +1,717 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package ethstats implements the network stats reporting service. +package ethstats + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "net" + "regexp" + "runtime" + "strconv" + "strings" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/les" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/websocket" +) + +const ( + // historyUpdateRange is the number of blocks a node should report upon login or + // history request. + historyUpdateRange = 50 + + // txChanSize is the size of channel listening to NewTxsEvent. + // The number is referenced from the size of tx pool. + txChanSize = 4096 + // chainHeadChanSize is the size of channel listening to ChainHeadEvent. + chainHeadChanSize = 10 +) + +type txPool interface { + // SubscribeNewTxsEvent should return an event subscription of + // NewTxsEvent and send events to the given channel. + SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription +} + +type blockChain interface { + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription +} + +// Service implements an Ethereum netstats reporting daemon that pushes local +// chain statistics up to a monitoring server. +type Service struct { + server *p2p.Server // Peer-to-peer server to retrieve networking infos + eth *eth.Ethereum // Full Ethereum service if monitoring a full node + les *les.LightEthereum // Light Ethereum service if monitoring a light node + engine consensus.Engine // Consensus engine to retrieve variadic block fields + + node string // Name of the node to display on the monitoring page + pass string // Password to authorize access to the monitoring page + host string // Remote address of the monitoring service + + pongCh chan struct{} // Pong notifications are fed into this channel + histCh chan []uint64 // History request block numbers are fed into this channel +} + +// New returns a monitoring service ready for stats reporting. +func New(url string, ethServ *eth.Ethereum, lesServ *les.LightEthereum) (*Service, error) { + // Parse the netstats connection url + re := regexp.MustCompile("([^:@]*)(:([^@]*))?@(.+)") + parts := re.FindStringSubmatch(url) + if len(parts) != 5 { + return nil, fmt.Errorf("invalid netstats url: \"%s\", should be nodename:secret@host:port", url) + } + // Assemble and return the stats service + var engine consensus.Engine + if ethServ != nil { + engine = ethServ.Engine() + } else { + engine = lesServ.Engine() + } + return &Service{ + eth: ethServ, + les: lesServ, + engine: engine, + node: parts[1], + pass: parts[3], + host: parts[4], + pongCh: make(chan struct{}), + histCh: make(chan []uint64, 1), + }, nil +} + +// Protocols implements node.Service, returning the P2P network protocols used +// by the stats service (nil as it doesn't use the devp2p overlay network). +func (s *Service) Protocols() []p2p.Protocol { return nil } + +// APIs implements node.Service, returning the RPC API endpoints provided by the +// stats service (nil as it doesn't provide any user callable APIs). +func (s *Service) APIs() []rpc.API { return nil } + +// Start implements node.Service, starting up the monitoring and reporting daemon. +func (s *Service) Start(server *p2p.Server) error { + s.server = server + go s.loop() + + log.Info("Stats daemon started") + return nil +} + +// Stop implements node.Service, terminating the monitoring and reporting daemon. +func (s *Service) Stop() error { + log.Info("Stats daemon stopped") + return nil +} + +// loop keeps trying to connect to the netstats server, reporting chain events +// until termination. +func (s *Service) loop() { + // Subscribe to chain events to execute updates on + var blockchain blockChain + var txpool txPool + if s.eth != nil { + blockchain = s.eth.BlockChain() + txpool = s.eth.TxPool() + } else { + blockchain = s.les.BlockChain() + txpool = s.les.TxPool() + } + + chainHeadCh := make(chan core.ChainHeadEvent, chainHeadChanSize) + headSub := blockchain.SubscribeChainHeadEvent(chainHeadCh) + defer headSub.Unsubscribe() + + txEventCh := make(chan core.NewTxsEvent, txChanSize) + txSub := txpool.SubscribeNewTxsEvent(txEventCh) + defer txSub.Unsubscribe() + + // Start a goroutine that exhausts the subsciptions to avoid events piling up + var ( + quitCh = make(chan struct{}) + headCh = make(chan *types.Block, 1) + txCh = make(chan struct{}, 1) + ) + go func() { + var lastTx mclock.AbsTime + + HandleLoop: + for { + select { + // Notify of chain head events, but drop if too frequent + case head := <-chainHeadCh: + select { + case headCh <- head.Block: + default: + } + + // Notify of new transaction events, but drop if too frequent + case <-txEventCh: + if time.Duration(mclock.Now()-lastTx) < time.Second { + continue + } + lastTx = mclock.Now() + + select { + case txCh <- struct{}{}: + default: + } + + // node stopped + case <-txSub.Err(): + break HandleLoop + case <-headSub.Err(): + break HandleLoop + } + } + close(quitCh) + }() + // Loop reporting until termination + for { + // Resolve the URL, defaulting to TLS, but falling back to none too + path := fmt.Sprintf("%s/api", s.host) + urls := []string{path} + + if !strings.Contains(path, "://") { // url.Parse and url.IsAbs is unsuitable (https://github.com/golang/go/issues/19779) + urls = []string{"wss://" + path, "ws://" + path} + } + // Establish a websocket connection to the server on any supported URL + var ( + conf *websocket.Config + conn *websocket.Conn + err error + ) + for _, url := range urls { + if conf, err = websocket.NewConfig(url, "http://localhost/"); err != nil { + continue + } + conf.Dialer = &net.Dialer{Timeout: 5 * time.Second} + if conn, err = websocket.DialConfig(conf); err == nil { + break + } + } + if err != nil { + log.Warn("Stats server unreachable", "err", err) + time.Sleep(10 * time.Second) + continue + } + // Authenticate the client with the server + if err = s.login(conn); err != nil { + log.Warn("Stats login failed", "err", err) + conn.Close() + time.Sleep(10 * time.Second) + continue + } + go s.readLoop(conn) + + // Send the initial stats so our node looks decent from the get go + if err = s.report(conn); err != nil { + log.Warn("Initial stats report failed", "err", err) + conn.Close() + continue + } + // Keep sending status updates until the connection breaks + fullReport := time.NewTicker(15 * time.Second) + + for err == nil { + select { + case <-quitCh: + conn.Close() + return + + case <-fullReport.C: + if err = s.report(conn); err != nil { + log.Warn("Full stats report failed", "err", err) + } + case list := <-s.histCh: + if err = s.reportHistory(conn, list); err != nil { + log.Warn("Requested history report failed", "err", err) + } + case head := <-headCh: + if err = s.reportBlock(conn, head); err != nil { + log.Warn("Block stats report failed", "err", err) + } + if err = s.reportPending(conn); err != nil { + log.Warn("Post-block transaction stats report failed", "err", err) + } + case <-txCh: + if err = s.reportPending(conn); err != nil { + log.Warn("Transaction stats report failed", "err", err) + } + } + } + // Make sure the connection is closed + conn.Close() + } +} + +// readLoop loops as long as the connection is alive and retrieves data packets +// from the network socket. If any of them match an active request, it forwards +// it, if they themselves are requests it initiates a reply, and lastly it drops +// unknown packets. +func (s *Service) readLoop(conn *websocket.Conn) { + // If the read loop exists, close the connection + defer conn.Close() + + for { + // Retrieve the next generic network packet and bail out on error + var msg map[string][]interface{} + if err := websocket.JSON.Receive(conn, &msg); err != nil { + log.Warn("Failed to decode stats server message", "err", err) + return + } + log.Trace("Received message from stats server", "msg", msg) + if len(msg["emit"]) == 0 { + log.Warn("Stats server sent non-broadcast", "msg", msg) + return + } + command, ok := msg["emit"][0].(string) + if !ok { + log.Warn("Invalid stats server message type", "type", msg["emit"][0]) + return + } + // If the message is a ping reply, deliver (someone must be listening!) + if len(msg["emit"]) == 2 && command == "node-pong" { + select { + case s.pongCh <- struct{}{}: + // Pong delivered, continue listening + continue + default: + // Ping routine dead, abort + log.Warn("Stats server pinger seems to have died") + return + } + } + // If the message is a history request, forward to the event processor + if len(msg["emit"]) == 2 && command == "history" { + // Make sure the request is valid and doesn't crash us + request, ok := msg["emit"][1].(map[string]interface{}) + if !ok { + log.Warn("Invalid stats history request", "msg", msg["emit"][1]) + s.histCh <- nil + continue // Ethstats sometime sends invalid history requests, ignore those + } + list, ok := request["list"].([]interface{}) + if !ok { + log.Warn("Invalid stats history block list", "list", request["list"]) + return + } + // Convert the block number list to an integer list + numbers := make([]uint64, len(list)) + for i, num := range list { + n, ok := num.(float64) + if !ok { + log.Warn("Invalid stats history block number", "number", num) + return + } + numbers[i] = uint64(n) + } + select { + case s.histCh <- numbers: + continue + default: + } + } + // Report anything else and continue + log.Info("Unknown stats message", "msg", msg) + } +} + +// nodeInfo is the collection of metainformation about a node that is displayed +// on the monitoring page. +type nodeInfo struct { + Name string `json:"name"` + Node string `json:"node"` + Port int `json:"port"` + Network string `json:"net"` + Protocol string `json:"protocol"` + API string `json:"api"` + Os string `json:"os"` + OsVer string `json:"os_v"` + Client string `json:"client"` + History bool `json:"canUpdateHistory"` +} + +// authMsg is the authentication infos needed to login to a monitoring server. +type authMsg struct { + ID string `json:"id"` + Info nodeInfo `json:"info"` + Secret string `json:"secret"` +} + +// login tries to authorize the client at the remote server. +func (s *Service) login(conn *websocket.Conn) error { + // Construct and send the login authentication + infos := s.server.NodeInfo() + + var network, protocol string + if info := infos.Protocols["eth"]; info != nil { + network = fmt.Sprintf("%d", info.(*eth.NodeInfo).Network) + protocol = fmt.Sprintf("eth/%d", eth.ProtocolVersions[0]) + } else { + network = fmt.Sprintf("%d", infos.Protocols["les"].(*les.NodeInfo).Network) + protocol = fmt.Sprintf("les/%d", les.ClientProtocolVersions[0]) + } + auth := &authMsg{ + ID: s.node, + Info: nodeInfo{ + Name: s.node, + Node: infos.Name, + Port: infos.Ports.Listener, + Network: network, + Protocol: protocol, + API: "No", + Os: runtime.GOOS, + OsVer: runtime.GOARCH, + Client: "0.1.1", + History: true, + }, + Secret: s.pass, + } + login := map[string][]interface{}{ + "emit": {"hello", auth}, + } + if err := websocket.JSON.Send(conn, login); err != nil { + return err + } + // Retrieve the remote ack or connection termination + var ack map[string][]string + if err := websocket.JSON.Receive(conn, &ack); err != nil || len(ack["emit"]) != 1 || ack["emit"][0] != "ready" { + return errors.New("unauthorized") + } + return nil +} + +// report collects all possible data to report and send it to the stats server. +// This should only be used on reconnects or rarely to avoid overloading the +// server. Use the individual methods for reporting subscribed events. +func (s *Service) report(conn *websocket.Conn) error { + if err := s.reportLatency(conn); err != nil { + return err + } + if err := s.reportBlock(conn, nil); err != nil { + return err + } + if err := s.reportPending(conn); err != nil { + return err + } + if err := s.reportStats(conn); err != nil { + return err + } + return nil +} + +// reportLatency sends a ping request to the server, measures the RTT time and +// finally sends a latency update. +func (s *Service) reportLatency(conn *websocket.Conn) error { + // Send the current time to the ethstats server + start := time.Now() + + ping := map[string][]interface{}{ + "emit": {"node-ping", map[string]string{ + "id": s.node, + "clientTime": start.String(), + }}, + } + if err := websocket.JSON.Send(conn, ping); err != nil { + return err + } + // Wait for the pong request to arrive back + select { + case <-s.pongCh: + // Pong delivered, report the latency + case <-time.After(5 * time.Second): + // Ping timeout, abort + return errors.New("ping timed out") + } + latency := strconv.Itoa(int((time.Since(start) / time.Duration(2)).Nanoseconds() / 1000000)) + + // Send back the measured latency + log.Trace("Sending measured latency to ethstats", "latency", latency) + + stats := map[string][]interface{}{ + "emit": {"latency", map[string]string{ + "id": s.node, + "latency": latency, + }}, + } + return websocket.JSON.Send(conn, stats) +} + +// blockStats is the information to report about individual blocks. +type blockStats struct { + Number *big.Int `json:"number"` + Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash"` + Timestamp *big.Int `json:"timestamp"` + Miner common.Address `json:"miner"` + GasUsed uint64 `json:"gasUsed"` + GasLimit uint64 `json:"gasLimit"` + Diff string `json:"difficulty"` + TotalDiff string `json:"totalDifficulty"` + Txs []txStats `json:"transactions"` + TxHash common.Hash `json:"transactionsRoot"` + Root common.Hash `json:"stateRoot"` + Uncles uncleStats `json:"uncles"` +} + +// txStats is the information to report about individual transactions. +type txStats struct { + Hash common.Hash `json:"hash"` +} + +// uncleStats is a custom wrapper around an uncle array to force serializing +// empty arrays instead of returning null for them. +type uncleStats []*types.Header + +func (s uncleStats) MarshalJSON() ([]byte, error) { + if uncles := ([]*types.Header)(s); len(uncles) > 0 { + return json.Marshal(uncles) + } + return []byte("[]"), nil +} + +// reportBlock retrieves the current chain head and reports it to the stats server. +func (s *Service) reportBlock(conn *websocket.Conn, block *types.Block) error { + // Gather the block details from the header or block chain + details := s.assembleBlockStats(block) + + // Assemble the block report and send it to the server + log.Trace("Sending new block to ethstats", "number", details.Number, "hash", details.Hash) + + stats := map[string]interface{}{ + "id": s.node, + "block": details, + } + report := map[string][]interface{}{ + "emit": {"block", stats}, + } + return websocket.JSON.Send(conn, report) +} + +// assembleBlockStats retrieves any required metadata to report a single block +// and assembles the block stats. If block is nil, the current head is processed. +func (s *Service) assembleBlockStats(block *types.Block) *blockStats { + // Gather the block infos from the local blockchain + var ( + header *types.Header + td *big.Int + txs []txStats + uncles []*types.Header + ) + if s.eth != nil { + // Full nodes have all needed information available + if block == nil { + block = s.eth.BlockChain().CurrentBlock() + } + header = block.Header() + td = s.eth.BlockChain().GetTd(header.Hash(), header.Number.Uint64()) + + txs = make([]txStats, len(block.Transactions())) + for i, tx := range block.Transactions() { + txs[i].Hash = tx.Hash() + } + uncles = block.Uncles() + } else { + // Light nodes would need on-demand lookups for transactions/uncles, skip + if block != nil { + header = block.Header() + } else { + header = s.les.BlockChain().CurrentHeader() + } + td = s.les.BlockChain().GetTd(header.Hash(), header.Number.Uint64()) + txs = []txStats{} + } + // Assemble and return the block stats + author, _ := s.engine.Author(header) + + return &blockStats{ + Number: header.Number, + Hash: header.Hash(), + ParentHash: header.ParentHash, + Timestamp: new(big.Int).SetUint64(header.Time), + Miner: author, + GasUsed: header.GasUsed, + GasLimit: header.GasLimit, + Diff: header.Difficulty.String(), + TotalDiff: td.String(), + Txs: txs, + TxHash: header.TxHash, + Root: header.Root, + Uncles: uncles, + } +} + +// reportHistory retrieves the most recent batch of blocks and reports it to the +// stats server. +func (s *Service) reportHistory(conn *websocket.Conn, list []uint64) error { + // Figure out the indexes that need reporting + indexes := make([]uint64, 0, historyUpdateRange) + if len(list) > 0 { + // Specific indexes requested, send them back in particular + indexes = append(indexes, list...) + } else { + // No indexes requested, send back the top ones + var head int64 + if s.eth != nil { + head = s.eth.BlockChain().CurrentHeader().Number.Int64() + } else { + head = s.les.BlockChain().CurrentHeader().Number.Int64() + } + start := head - historyUpdateRange + 1 + if start < 0 { + start = 0 + } + for i := uint64(start); i <= uint64(head); i++ { + indexes = append(indexes, i) + } + } + // Gather the batch of blocks to report + history := make([]*blockStats, len(indexes)) + for i, number := range indexes { + // Retrieve the next block if it's known to us + var block *types.Block + if s.eth != nil { + block = s.eth.BlockChain().GetBlockByNumber(number) + } else { + if header := s.les.BlockChain().GetHeaderByNumber(number); header != nil { + block = types.NewBlockWithHeader(header) + } + } + // If we do have the block, add to the history and continue + if block != nil { + history[len(history)-1-i] = s.assembleBlockStats(block) + continue + } + // Ran out of blocks, cut the report short and send + history = history[len(history)-i:] + break + } + // Assemble the history report and send it to the server + if len(history) > 0 { + log.Trace("Sending historical blocks to ethstats", "first", history[0].Number, "last", history[len(history)-1].Number) + } else { + log.Trace("No history to send to stats server") + } + stats := map[string]interface{}{ + "id": s.node, + "history": history, + } + report := map[string][]interface{}{ + "emit": {"history", stats}, + } + return websocket.JSON.Send(conn, report) +} + +// pendStats is the information to report about pending transactions. +type pendStats struct { + Pending int `json:"pending"` +} + +// reportPending retrieves the current number of pending transactions and reports +// it to the stats server. +func (s *Service) reportPending(conn *websocket.Conn) error { + // Retrieve the pending count from the local blockchain + var pending int + if s.eth != nil { + pending, _ = s.eth.TxPool().Stats() + } else { + pending = s.les.TxPool().Stats() + } + // Assemble the transaction stats and send it to the server + log.Trace("Sending pending transactions to ethstats", "count", pending) + + stats := map[string]interface{}{ + "id": s.node, + "stats": &pendStats{ + Pending: pending, + }, + } + report := map[string][]interface{}{ + "emit": {"pending", stats}, + } + return websocket.JSON.Send(conn, report) +} + +// nodeStats is the information to report about the local node. +type nodeStats struct { + Active bool `json:"active"` + Syncing bool `json:"syncing"` + Mining bool `json:"mining"` + Hashrate int `json:"hashrate"` + Peers int `json:"peers"` + GasPrice int `json:"gasPrice"` + Uptime int `json:"uptime"` +} + +// reportPending retrieves various stats about the node at the networking and +// mining layer and reports it to the stats server. +func (s *Service) reportStats(conn *websocket.Conn) error { + // Gather the syncing and mining infos from the local miner instance + var ( + mining bool + hashrate int + syncing bool + gasprice int + ) + if s.eth != nil { + mining = s.eth.Miner().Mining() + hashrate = int(s.eth.Miner().HashRate()) + + sync := s.eth.Downloader().Progress() + syncing = s.eth.BlockChain().CurrentHeader().Number.Uint64() >= sync.HighestBlock + + price, _ := s.eth.APIBackend.SuggestPrice(context.Background()) + gasprice = int(price.Uint64()) + } else { + sync := s.les.Downloader().Progress() + syncing = s.les.BlockChain().CurrentHeader().Number.Uint64() >= sync.HighestBlock + } + // Assemble the node stats and send it to the server + log.Trace("Sending node details to ethstats") + + stats := map[string]interface{}{ + "id": s.node, + "stats": &nodeStats{ + Active: true, + Mining: mining, + Hashrate: hashrate, + Peers: s.server.PeerCount(), + GasPrice: gasprice, + Syncing: syncing, + Uptime: 100, + }, + } + report := map[string][]interface{}{ + "emit": {"stats", stats}, + } + return websocket.JSON.Send(conn, report) +} diff --git a/vendor/github.com/ethereum/go-ethereum/graphql/graphql.go b/vendor/github.com/ethereum/go-ethereum/graphql/graphql.go new file mode 100644 index 00000000..d22a3afb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/graphql/graphql.go @@ -0,0 +1,1233 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package graphql provides a GraphQL interface to Ethereum node data. +package graphql + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + graphqlgo "github.com/graph-gophers/graphql-go" + "github.com/graph-gophers/graphql-go/relay" +) + +var OnlyOnMainChainError = errors.New("This operation is only available for blocks on the canonical chain.") +var BlockInvariantError = errors.New("Block objects must be instantiated with at least one of num or hash.") + +// Account represents an Ethereum account at a particular block. +type Account struct { + backend *eth.EthAPIBackend + address common.Address + blockNumber rpc.BlockNumber +} + +// getState fetches the StateDB object for an account. +func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { + state, _, err := a.backend.StateAndHeaderByNumber(ctx, a.blockNumber) + return state, err +} + +func (a *Account) Address(ctx context.Context) (common.Address, error) { + return a.address, nil +} + +func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) { + state, err := a.getState(ctx) + if err != nil { + return hexutil.Big{}, err + } + + return hexutil.Big(*state.GetBalance(a.address)), nil +} + +func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { + state, err := a.getState(ctx) + if err != nil { + return 0, err + } + + return hexutil.Uint64(state.GetNonce(a.address)), nil +} + +func (a *Account) Code(ctx context.Context) (hexutil.Bytes, error) { + state, err := a.getState(ctx) + if err != nil { + return hexutil.Bytes{}, err + } + + return hexutil.Bytes(state.GetCode(a.address)), nil +} + +func (a *Account) Storage(ctx context.Context, args struct{ Slot common.Hash }) (common.Hash, error) { + state, err := a.getState(ctx) + if err != nil { + return common.Hash{}, err + } + + return state.GetState(a.address, args.Slot), nil +} + +// Log represents an individual log message. All arguments are mandatory. +type Log struct { + backend *eth.EthAPIBackend + transaction *Transaction + log *types.Log +} + +func (l *Log) Transaction(ctx context.Context) *Transaction { + return l.transaction +} + +func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account { + return &Account{ + backend: l.backend, + address: l.log.Address, + blockNumber: args.Number(), + } +} + +func (l *Log) Index(ctx context.Context) int32 { + return int32(l.log.Index) +} + +func (l *Log) Topics(ctx context.Context) []common.Hash { + return l.log.Topics +} + +func (l *Log) Data(ctx context.Context) hexutil.Bytes { + return hexutil.Bytes(l.log.Data) +} + +// Transaction represents an Ethereum transaction. +// backend and hash are mandatory; all others will be fetched when required. +type Transaction struct { + backend *eth.EthAPIBackend + hash common.Hash + tx *types.Transaction + block *Block + index uint64 +} + +// resolve returns the internal transaction object, fetching it if needed. +func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) { + if t.tx == nil { + tx, blockHash, _, index := rawdb.ReadTransaction(t.backend.ChainDb(), t.hash) + if tx != nil { + t.tx = tx + t.block = &Block{ + backend: t.backend, + hash: blockHash, + canonical: unknown, + } + t.index = index + } else { + t.tx = t.backend.GetPoolTransaction(t.hash) + } + } + return t.tx, nil +} + +func (tx *Transaction) Hash(ctx context.Context) common.Hash { + return tx.hash +} + +func (t *Transaction) InputData(ctx context.Context) (hexutil.Bytes, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return hexutil.Bytes{}, err + } + return hexutil.Bytes(tx.Data()), nil +} + +func (t *Transaction) Gas(ctx context.Context) (hexutil.Uint64, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return 0, err + } + return hexutil.Uint64(tx.Gas()), nil +} + +func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return hexutil.Big{}, err + } + return hexutil.Big(*tx.GasPrice()), nil +} + +func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return hexutil.Big{}, err + } + return hexutil.Big(*tx.Value()), nil +} + +func (t *Transaction) Nonce(ctx context.Context) (hexutil.Uint64, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return 0, err + } + return hexutil.Uint64(tx.Nonce()), nil +} + +func (t *Transaction) To(ctx context.Context, args BlockNumberArgs) (*Account, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return nil, err + } + + to := tx.To() + if to == nil { + return nil, nil + } + + return &Account{ + backend: t.backend, + address: *to, + blockNumber: args.Number(), + }, nil +} + +func (t *Transaction) From(ctx context.Context, args BlockNumberArgs) (*Account, error) { + tx, err := t.resolve(ctx) + if err != nil || tx == nil { + return nil, err + } + + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + + return &Account{ + backend: t.backend, + address: from, + blockNumber: args.Number(), + }, nil +} + +func (t *Transaction) Block(ctx context.Context) (*Block, error) { + if _, err := t.resolve(ctx); err != nil { + return nil, err + } + return t.block, nil +} + +func (t *Transaction) Index(ctx context.Context) (*int32, error) { + if _, err := t.resolve(ctx); err != nil { + return nil, err + } + if t.block == nil { + return nil, nil + } + index := int32(t.index) + return &index, nil +} + +// getReceipt returns the receipt associated with this transaction, if any. +func (t *Transaction) getReceipt(ctx context.Context) (*types.Receipt, error) { + if _, err := t.resolve(ctx); err != nil { + return nil, err + } + + if t.block == nil { + return nil, nil + } + + receipts, err := t.block.resolveReceipts(ctx) + if err != nil { + return nil, err + } + + return receipts[t.index], nil +} + +func (t *Transaction) Status(ctx context.Context) (*hexutil.Uint64, error) { + receipt, err := t.getReceipt(ctx) + if err != nil || receipt == nil { + return nil, err + } + + ret := hexutil.Uint64(receipt.Status) + return &ret, nil +} + +func (t *Transaction) GasUsed(ctx context.Context) (*hexutil.Uint64, error) { + receipt, err := t.getReceipt(ctx) + if err != nil || receipt == nil { + return nil, err + } + + ret := hexutil.Uint64(receipt.GasUsed) + return &ret, nil +} + +func (t *Transaction) CumulativeGasUsed(ctx context.Context) (*hexutil.Uint64, error) { + receipt, err := t.getReceipt(ctx) + if err != nil || receipt == nil { + return nil, err + } + + ret := hexutil.Uint64(receipt.CumulativeGasUsed) + return &ret, nil +} + +func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs) (*Account, error) { + receipt, err := t.getReceipt(ctx) + if err != nil || receipt == nil || receipt.ContractAddress == (common.Address{}) { + return nil, err + } + + return &Account{ + backend: t.backend, + address: receipt.ContractAddress, + blockNumber: args.Number(), + }, nil +} + +func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) { + receipt, err := t.getReceipt(ctx) + if err != nil || receipt == nil { + return nil, err + } + + ret := make([]*Log, 0, len(receipt.Logs)) + for _, log := range receipt.Logs { + ret = append(ret, &Log{ + backend: t.backend, + transaction: t, + log: log, + }) + } + return &ret, nil +} + +type BlockType int + +const ( + unknown BlockType = iota + isCanonical + notCanonical +) + +// Block represents an Ethereum block. +// backend, and either num or hash are mandatory. All other fields are lazily fetched +// when required. +type Block struct { + backend *eth.EthAPIBackend + num *rpc.BlockNumber + hash common.Hash + header *types.Header + block *types.Block + receipts []*types.Receipt + canonical BlockType // Indicates if this block is on the main chain or not. +} + +func (b *Block) onMainChain(ctx context.Context) error { + if b.canonical == unknown { + header, err := b.resolveHeader(ctx) + if err != nil { + return err + } + canonHeader, err := b.backend.HeaderByNumber(ctx, rpc.BlockNumber(header.Number.Uint64())) + if err != nil { + return err + } + if header.Hash() == canonHeader.Hash() { + b.canonical = isCanonical + } else { + b.canonical = notCanonical + } + } + if b.canonical != isCanonical { + return OnlyOnMainChainError + } + return nil +} + +// resolve returns the internal Block object representing this block, fetching +// it if necessary. +func (b *Block) resolve(ctx context.Context) (*types.Block, error) { + if b.block != nil { + return b.block, nil + } + + var err error + if b.hash != (common.Hash{}) { + b.block, err = b.backend.GetBlock(ctx, b.hash) + } else { + b.block, err = b.backend.BlockByNumber(ctx, *b.num) + } + if b.block != nil { + b.header = b.block.Header() + } + return b.block, err +} + +// resolveHeader returns the internal Header object for this block, fetching it +// if necessary. Call this function instead of `resolve` unless you need the +// additional data (transactions and uncles). +func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) { + if b.num == nil && b.hash == (common.Hash{}) { + return nil, BlockInvariantError + } + + if b.header == nil { + if _, err := b.resolve(ctx); err != nil { + return nil, err + } + } + return b.header, nil +} + +// resolveReceipts returns the list of receipts for this block, fetching them +// if necessary. +func (b *Block) resolveReceipts(ctx context.Context) ([]*types.Receipt, error) { + if b.receipts == nil { + hash := b.hash + if hash == (common.Hash{}) { + header, err := b.resolveHeader(ctx) + if err != nil { + return nil, err + } + hash = header.Hash() + } + + receipts, err := b.backend.GetReceipts(ctx, hash) + if err != nil { + return nil, err + } + b.receipts = []*types.Receipt(receipts) + } + return b.receipts, nil +} + +func (b *Block) Number(ctx context.Context) (hexutil.Uint64, error) { + if b.num == nil || *b.num == rpc.LatestBlockNumber { + header, err := b.resolveHeader(ctx) + if err != nil { + return 0, err + } + num := rpc.BlockNumber(header.Number.Uint64()) + b.num = &num + } + return hexutil.Uint64(*b.num), nil +} + +func (b *Block) Hash(ctx context.Context) (common.Hash, error) { + if b.hash == (common.Hash{}) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + b.hash = header.Hash() + } + return b.hash, nil +} + +func (b *Block) GasLimit(ctx context.Context) (hexutil.Uint64, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return 0, err + } + return hexutil.Uint64(header.GasLimit), nil +} + +func (b *Block) GasUsed(ctx context.Context) (hexutil.Uint64, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return 0, err + } + return hexutil.Uint64(header.GasUsed), nil +} + +func (b *Block) Parent(ctx context.Context) (*Block, error) { + // If the block hasn't been fetched, and we'll need it, fetch it. + if b.num == nil && b.hash != (common.Hash{}) && b.header == nil { + if _, err := b.resolve(ctx); err != nil { + return nil, err + } + } + + if b.header != nil && b.block.NumberU64() > 0 { + num := rpc.BlockNumber(b.header.Number.Uint64() - 1) + return &Block{ + backend: b.backend, + num: &num, + hash: b.header.ParentHash, + canonical: unknown, + }, nil + } + if b.num != nil && *b.num != 0 { + num := *b.num - 1 + return &Block{ + backend: b.backend, + num: &num, + canonical: isCanonical, + }, nil + } + return nil, nil +} + +func (b *Block) Difficulty(ctx context.Context) (hexutil.Big, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Big{}, err + } + return hexutil.Big(*header.Difficulty), nil +} + +func (b *Block) Timestamp(ctx context.Context) (hexutil.Uint64, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return 0, err + } + return hexutil.Uint64(header.Time), nil +} + +func (b *Block) Nonce(ctx context.Context) (hexutil.Bytes, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Bytes{}, err + } + return hexutil.Bytes(header.Nonce[:]), nil +} + +func (b *Block) MixHash(ctx context.Context) (common.Hash, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + return header.MixDigest, nil +} + +func (b *Block) TransactionsRoot(ctx context.Context) (common.Hash, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + return header.TxHash, nil +} + +func (b *Block) StateRoot(ctx context.Context) (common.Hash, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + return header.Root, nil +} + +func (b *Block) ReceiptsRoot(ctx context.Context) (common.Hash, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + return header.ReceiptHash, nil +} + +func (b *Block) OmmerHash(ctx context.Context) (common.Hash, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return common.Hash{}, err + } + return header.UncleHash, nil +} + +func (b *Block) OmmerCount(ctx context.Context) (*int32, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + count := int32(len(block.Uncles())) + return &count, err +} + +func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + + ret := make([]*Block, 0, len(block.Uncles())) + for _, uncle := range block.Uncles() { + blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) + ret = append(ret, &Block{ + backend: b.backend, + num: &blockNumber, + hash: uncle.Hash(), + header: uncle, + canonical: notCanonical, + }) + } + return &ret, nil +} + +func (b *Block) ExtraData(ctx context.Context) (hexutil.Bytes, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Bytes{}, err + } + return hexutil.Bytes(header.Extra), nil +} + +func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) { + header, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Bytes{}, err + } + return hexutil.Bytes(header.Bloom.Bytes()), nil +} + +func (b *Block) TotalDifficulty(ctx context.Context) (hexutil.Big, error) { + h := b.hash + if h == (common.Hash{}) { + header, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Big{}, err + } + h = header.Hash() + } + + return hexutil.Big(*b.backend.GetTd(h)), nil +} + +// BlockNumberArgs encapsulates arguments to accessors that specify a block number. +type BlockNumberArgs struct { + Block *hexutil.Uint64 +} + +// Number returns the provided block number, or rpc.LatestBlockNumber if none +// was provided. +func (a BlockNumberArgs) Number() rpc.BlockNumber { + if a.Block != nil { + return rpc.BlockNumber(*a.Block) + } + return rpc.LatestBlockNumber +} + +func (b *Block) Miner(ctx context.Context, args BlockNumberArgs) (*Account, error) { + block, err := b.resolve(ctx) + if err != nil { + return nil, err + } + + return &Account{ + backend: b.backend, + address: block.Coinbase(), + blockNumber: args.Number(), + }, nil +} + +func (b *Block) TransactionCount(ctx context.Context) (*int32, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + count := int32(len(block.Transactions())) + return &count, err +} + +func (b *Block) Transactions(ctx context.Context) (*[]*Transaction, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + + ret := make([]*Transaction, 0, len(block.Transactions())) + for i, tx := range block.Transactions() { + ret = append(ret, &Transaction{ + backend: b.backend, + hash: tx.Hash(), + tx: tx, + block: b, + index: uint64(i), + }) + } + return &ret, nil +} + +func (b *Block) TransactionAt(ctx context.Context, args struct{ Index int32 }) (*Transaction, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + + txes := block.Transactions() + if args.Index < 0 || int(args.Index) >= len(txes) { + return nil, nil + } + + tx := txes[args.Index] + return &Transaction{ + backend: b.backend, + hash: tx.Hash(), + tx: tx, + block: b, + index: uint64(args.Index), + }, nil +} + +func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block, error) { + block, err := b.resolve(ctx) + if err != nil || block == nil { + return nil, err + } + + uncles := block.Uncles() + if args.Index < 0 || int(args.Index) >= len(uncles) { + return nil, nil + } + + uncle := uncles[args.Index] + blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) + return &Block{ + backend: b.backend, + num: &blockNumber, + hash: uncle.Hash(), + header: uncle, + canonical: notCanonical, + }, nil +} + +// BlockFilterCriteria encapsulates criteria passed to a `logs` accessor inside +// a block. +type BlockFilterCriteria struct { + Addresses *[]common.Address // restricts matches to events created by specific contracts + + // The Topic list restricts matches to particular event topics. Each event has a list + // of topics. Topics matches a prefix of that list. An empty element slice matches any + // topic. Non-empty elements represent an alternative that matches any of the + // contained topics. + // + // Examples: + // {} or nil matches any topic list + // {{A}} matches topic A in first position + // {{}, {B}} matches any topic in first position, B in second position + // {{A}, {B}} matches topic A in first position, B in second position + // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position + Topics *[][]common.Hash +} + +// runFilter accepts a filter and executes it, returning all its results as +// `Log` objects. +func runFilter(ctx context.Context, be *eth.EthAPIBackend, filter *filters.Filter) ([]*Log, error) { + logs, err := filter.Logs(ctx) + if err != nil || logs == nil { + return nil, err + } + + ret := make([]*Log, 0, len(logs)) + for _, log := range logs { + ret = append(ret, &Log{ + backend: be, + transaction: &Transaction{backend: be, hash: log.TxHash}, + log: log, + }) + } + return ret, nil +} + +func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteria }) ([]*Log, error) { + var addresses []common.Address + if args.Filter.Addresses != nil { + addresses = *args.Filter.Addresses + } + + var topics [][]common.Hash + if args.Filter.Topics != nil { + topics = *args.Filter.Topics + } + + hash := b.hash + if hash == (common.Hash{}) { + block, err := b.resolve(ctx) + if err != nil { + return nil, err + } + hash = block.Hash() + } + + // Construct the range filter + filter := filters.NewBlockFilter(b.backend, hash, addresses, topics) + + // Run the filter and return all the logs + return runFilter(ctx, b.backend, filter) +} + +func (b *Block) Account(ctx context.Context, args struct { + Address common.Address +}) (*Account, error) { + err := b.onMainChain(ctx) + if err != nil { + return nil, err + } + + if b.num == nil { + _, err := b.resolveHeader(ctx) + if err != nil { + return nil, err + } + } + + return &Account{ + backend: b.backend, + address: args.Address, + blockNumber: *b.num, + }, nil +} + +// CallData encapsulates arguments to `call` or `estimateGas`. +// All arguments are optional. +type CallData struct { + From *common.Address // The Ethereum address the call is from. + To *common.Address // The Ethereum address the call is to. + Gas *hexutil.Uint64 // The amount of gas provided for the call. + GasPrice *hexutil.Big // The price of each unit of gas, in wei. + Value *hexutil.Big // The value sent along with the call. + Data *hexutil.Bytes // Any data sent with the call. +} + +// CallResult encapsulates the result of an invocation of the `call` accessor. +type CallResult struct { + data hexutil.Bytes // The return data from the call + gasUsed hexutil.Uint64 // The amount of gas used + status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success. +} + +func (c *CallResult) Data() hexutil.Bytes { + return c.data +} + +func (c *CallResult) GasUsed() hexutil.Uint64 { + return c.gasUsed +} + +func (c *CallResult) Status() hexutil.Uint64 { + return c.status +} + +func (b *Block) Call(ctx context.Context, args struct { + Data ethapi.CallArgs +}) (*CallResult, error) { + err := b.onMainChain(ctx) + if err != nil { + return nil, err + } + + if b.num == nil { + _, err := b.resolveHeader(ctx) + if err != nil { + return nil, err + } + } + + result, gas, failed, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.num, vm.Config{}, 5*time.Second, b.backend.RPCGasCap()) + status := hexutil.Uint64(1) + if failed { + status = 0 + } + return &CallResult{ + data: hexutil.Bytes(result), + gasUsed: hexutil.Uint64(gas), + status: status, + }, err +} + +func (b *Block) EstimateGas(ctx context.Context, args struct { + Data ethapi.CallArgs +}) (hexutil.Uint64, error) { + err := b.onMainChain(ctx) + if err != nil { + return hexutil.Uint64(0), err + } + + if b.num == nil { + _, err := b.resolveHeader(ctx) + if err != nil { + return hexutil.Uint64(0), err + } + } + + gas, err := ethapi.DoEstimateGas(ctx, b.backend, args.Data, *b.num, b.backend.RPCGasCap()) + return gas, err +} + +type Pending struct { + backend *eth.EthAPIBackend +} + +func (p *Pending) TransactionCount(ctx context.Context) (int32, error) { + txs, err := p.backend.GetPoolTransactions() + return int32(len(txs)), err +} + +func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) { + txs, err := p.backend.GetPoolTransactions() + if err != nil { + return nil, err + } + + ret := make([]*Transaction, 0, len(txs)) + for i, tx := range txs { + ret = append(ret, &Transaction{ + backend: p.backend, + hash: tx.Hash(), + tx: tx, + index: uint64(i), + }) + } + return &ret, nil +} + +func (p *Pending) Account(ctx context.Context, args struct { + Address common.Address +}) *Account { + return &Account{ + backend: p.backend, + address: args.Address, + blockNumber: rpc.PendingBlockNumber, + } +} + +func (p *Pending) Call(ctx context.Context, args struct { + Data ethapi.CallArgs +}) (*CallResult, error) { + result, gas, failed, err := ethapi.DoCall(ctx, p.backend, args.Data, rpc.PendingBlockNumber, vm.Config{}, 5*time.Second, p.backend.RPCGasCap()) + status := hexutil.Uint64(1) + if failed { + status = 0 + } + return &CallResult{ + data: hexutil.Bytes(result), + gasUsed: hexutil.Uint64(gas), + status: status, + }, err +} + +func (p *Pending) EstimateGas(ctx context.Context, args struct { + Data ethapi.CallArgs +}) (hexutil.Uint64, error) { + return ethapi.DoEstimateGas(ctx, p.backend, args.Data, rpc.PendingBlockNumber, p.backend.RPCGasCap()) +} + +// Resolver is the top-level object in the GraphQL hierarchy. +type Resolver struct { + backend *eth.EthAPIBackend +} + +func (r *Resolver) Block(ctx context.Context, args struct { + Number *hexutil.Uint64 + Hash *common.Hash +}) (*Block, error) { + var block *Block + if args.Number != nil { + num := rpc.BlockNumber(uint64(*args.Number)) + block = &Block{ + backend: r.backend, + num: &num, + canonical: isCanonical, + } + } else if args.Hash != nil { + block = &Block{ + backend: r.backend, + hash: *args.Hash, + canonical: unknown, + } + } else { + num := rpc.LatestBlockNumber + block = &Block{ + backend: r.backend, + num: &num, + canonical: isCanonical, + } + } + + // Resolve the block; if it doesn't exist, return nil. + b, err := block.resolve(ctx) + if err != nil { + return nil, err + } else if b == nil { + return nil, nil + } + return block, nil +} + +func (r *Resolver) Blocks(ctx context.Context, args struct { + From hexutil.Uint64 + To *hexutil.Uint64 +}) ([]*Block, error) { + from := rpc.BlockNumber(args.From) + + var to rpc.BlockNumber + if args.To != nil { + to = rpc.BlockNumber(*args.To) + } else { + to = rpc.BlockNumber(r.backend.CurrentBlock().Number().Int64()) + } + + if to < from { + return []*Block{}, nil + } + + ret := make([]*Block, 0, to-from+1) + for i := from; i <= to; i++ { + num := i + ret = append(ret, &Block{ + backend: r.backend, + num: &num, + canonical: isCanonical, + }) + } + return ret, nil +} + +func (r *Resolver) Pending(ctx context.Context) *Pending { + return &Pending{r.backend} +} + +func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) { + tx := &Transaction{ + backend: r.backend, + hash: args.Hash, + } + + // Resolve the transaction; if it doesn't exist, return nil. + t, err := tx.resolve(ctx) + if err != nil { + return nil, err + } else if t == nil { + return nil, nil + } + return tx, nil +} + +func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hexutil.Bytes }) (common.Hash, error) { + tx := new(types.Transaction) + if err := rlp.DecodeBytes(args.Data, tx); err != nil { + return common.Hash{}, err + } + hash, err := ethapi.SubmitTransaction(ctx, r.backend, tx) + return hash, err +} + +// FilterCriteria encapsulates the arguments to `logs` on the root resolver object. +type FilterCriteria struct { + FromBlock *hexutil.Uint64 // beginning of the queried range, nil means genesis block + ToBlock *hexutil.Uint64 // end of the range, nil means latest block + Addresses *[]common.Address // restricts matches to events created by specific contracts + + // The Topic list restricts matches to particular event topics. Each event has a list + // of topics. Topics matches a prefix of that list. An empty element slice matches any + // topic. Non-empty elements represent an alternative that matches any of the + // contained topics. + // + // Examples: + // {} or nil matches any topic list + // {{A}} matches topic A in first position + // {{}, {B}} matches any topic in first position, B in second position + // {{A}, {B}} matches topic A in first position, B in second position + // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position + Topics *[][]common.Hash +} + +func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria }) ([]*Log, error) { + // Convert the RPC block numbers into internal representations + begin := rpc.LatestBlockNumber.Int64() + if args.Filter.FromBlock != nil { + begin = int64(*args.Filter.FromBlock) + } + end := rpc.LatestBlockNumber.Int64() + if args.Filter.ToBlock != nil { + end = int64(*args.Filter.ToBlock) + } + + var addresses []common.Address + if args.Filter.Addresses != nil { + addresses = *args.Filter.Addresses + } + + var topics [][]common.Hash + if args.Filter.Topics != nil { + topics = *args.Filter.Topics + } + + // Construct the range filter + filter := filters.NewRangeFilter(filters.Backend(r.backend), begin, end, addresses, topics) + + return runFilter(ctx, r.backend, filter) +} + +func (r *Resolver) GasPrice(ctx context.Context) (hexutil.Big, error) { + price, err := r.backend.SuggestPrice(ctx) + return hexutil.Big(*price), err +} + +func (r *Resolver) ProtocolVersion(ctx context.Context) (int32, error) { + return int32(r.backend.ProtocolVersion()), nil +} + +// SyncState represents the synchronisation status returned from the `syncing` accessor. +type SyncState struct { + progress ethereum.SyncProgress +} + +func (s *SyncState) StartingBlock() hexutil.Uint64 { + return hexutil.Uint64(s.progress.StartingBlock) +} + +func (s *SyncState) CurrentBlock() hexutil.Uint64 { + return hexutil.Uint64(s.progress.CurrentBlock) +} + +func (s *SyncState) HighestBlock() hexutil.Uint64 { + return hexutil.Uint64(s.progress.HighestBlock) +} + +func (s *SyncState) PulledStates() *hexutil.Uint64 { + ret := hexutil.Uint64(s.progress.PulledStates) + return &ret +} + +func (s *SyncState) KnownStates() *hexutil.Uint64 { + ret := hexutil.Uint64(s.progress.KnownStates) + return &ret +} + +// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not +// yet received the latest block headers from its pears. In case it is synchronizing: +// - startingBlock: block number this node started to synchronise from +// - currentBlock: block number this node is currently importing +// - highestBlock: block number of the highest block header this node has received from peers +// - pulledStates: number of state entries processed until now +// - knownStates: number of known state entries that still need to be pulled +func (r *Resolver) Syncing() (*SyncState, error) { + progress := r.backend.Downloader().Progress() + + // Return not syncing if the synchronisation already completed + if progress.CurrentBlock >= progress.HighestBlock { + return nil, nil + } + // Otherwise gather the block sync stats + return &SyncState{progress}, nil +} + +// NewHandler returns a new `http.Handler` that will answer GraphQL queries. +// It additionally exports an interactive query browser on the / endpoint. +func NewHandler(be *eth.EthAPIBackend) (http.Handler, error) { + q := Resolver{be} + + s, err := graphqlgo.ParseSchema(schema, &q) + if err != nil { + return nil, err + } + h := &relay.Handler{Schema: s} + + mux := http.NewServeMux() + mux.Handle("/", GraphiQL{}) + mux.Handle("/graphql", h) + mux.Handle("/graphql/", h) + return mux, nil +} + +// Service encapsulates a GraphQL service. +type Service struct { + endpoint string // The host:port endpoint for this service. + cors []string // Allowed CORS domains + vhosts []string // Recognised vhosts + timeouts rpc.HTTPTimeouts // Timeout settings for HTTP requests. + backend *eth.EthAPIBackend // The backend that queries will operate onn. + handler http.Handler // The `http.Handler` used to answer queries. + listener net.Listener // The listening socket. +} + +// Protocols returns the list of protocols exported by this service. +func (s *Service) Protocols() []p2p.Protocol { return nil } + +// APIs returns the list of APIs exported by this service. +func (s *Service) APIs() []rpc.API { return nil } + +// Start is called after all services have been constructed and the networking +// layer was also initialized to spawn any goroutines required by the service. +func (s *Service) Start(server *p2p.Server) error { + var err error + s.handler, err = NewHandler(s.backend) + if err != nil { + return err + } + + if s.listener, err = net.Listen("tcp", s.endpoint); err != nil { + return err + } + + go rpc.NewHTTPServer(s.cors, s.vhosts, s.timeouts, s.handler).Serve(s.listener) + log.Info("GraphQL endpoint opened", "url", fmt.Sprintf("http://%s", s.endpoint)) + return nil +} + +// Stop terminates all goroutines belonging to the service, blocking until they +// are all terminated. +func (s *Service) Stop() error { + if s.listener != nil { + s.listener.Close() + s.listener = nil + log.Info("GraphQL endpoint closed", "url", fmt.Sprintf("http://%s", s.endpoint)) + } + return nil +} + +// NewService constructs a new service instance. +func NewService(backend *eth.EthAPIBackend, endpoint string, cors, vhosts []string, timeouts rpc.HTTPTimeouts) (*Service, error) { + return &Service{ + endpoint: endpoint, + cors: cors, + vhosts: vhosts, + timeouts: timeouts, + backend: backend, + }, nil +} + +// RegisterGraphQLService is a utility function to construct a new service and register it against a node. +func RegisterGraphQLService(stack *node.Node, endpoint string, cors, vhosts []string, timeouts rpc.HTTPTimeouts) error { + return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + var ethereum *eth.Ethereum + if err := ctx.Service(ðereum); err != nil { + return nil, err + } + return NewService(ethereum.APIBackend, endpoint, cors, vhosts, timeouts) + }) +} diff --git a/vendor/github.com/ethereum/go-ethereum/graphql/schema.go b/vendor/github.com/ethereum/go-ethereum/graphql/schema.go new file mode 100644 index 00000000..bd913d9a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/graphql/schema.go @@ -0,0 +1,320 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package graphql + +const schema string = ` + # Bytes32 is a 32 byte binary string, represented as 0x-prefixed hexadecimal. + scalar Bytes32 + # Address is a 20 byte Ethereum address, represented as 0x-prefixed hexadecimal. + scalar Address + # Bytes is an arbitrary length binary string, represented as 0x-prefixed hexadecimal. + # An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles. + scalar Bytes + # BigInt is a large integer. Input is accepted as either a JSON number or as a string. + # Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all + # 0x-prefixed hexadecimal. + scalar BigInt + # Long is a 64 bit unsigned integer. + scalar Long + + schema { + query: Query + mutation: Mutation + } + + # Account is an Ethereum account at a particular block. + type Account { + # Address is the address owning the account. + address: Address! + # Balance is the balance of the account, in wei. + balance: BigInt! + # TransactionCount is the number of transactions sent from this account, + # or in the case of a contract, the number of contracts created. Otherwise + # known as the nonce. + transactionCount: Long! + # Code contains the smart contract code for this account, if the account + # is a (non-self-destructed) contract. + code: Bytes! + # Storage provides access to the storage of a contract account, indexed + # by its 32 byte slot identifier. + storage(slot: Bytes32!): Bytes32! + } + + # Log is an Ethereum event log. + type Log { + # Index is the index of this log in the block. + index: Int! + # Account is the account which generated this log - this will always + # be a contract account. + account(block: Long): Account! + # Topics is a list of 0-4 indexed topics for the log. + topics: [Bytes32!]! + # Data is unindexed data for this log. + data: Bytes! + # Transaction is the transaction that generated this log entry. + transaction: Transaction! + } + + # Transaction is an Ethereum transaction. + type Transaction { + # Hash is the hash of this transaction. + hash: Bytes32! + # Nonce is the nonce of the account this transaction was generated with. + nonce: Long! + # Index is the index of this transaction in the parent block. This will + # be null if the transaction has not yet been mined. + index: Int + # From is the account that sent this transaction - this will always be + # an externally owned account. + from(block: Long): Account! + # To is the account the transaction was sent to. This is null for + # contract-creating transactions. + to(block: Long): Account + # Value is the value, in wei, sent along with this transaction. + value: BigInt! + # GasPrice is the price offered to miners for gas, in wei per unit. + gasPrice: BigInt! + # Gas is the maximum amount of gas this transaction can consume. + gas: Long! + # InputData is the data supplied to the target of the transaction. + inputData: Bytes! + # Block is the block this transaction was mined in. This will be null if + # the transaction has not yet been mined. + block: Block + + # Status is the return status of the transaction. This will be 1 if the + # transaction succeeded, or 0 if it failed (due to a revert, or due to + # running out of gas). If the transaction has not yet been mined, this + # field will be null. + status: Long + # GasUsed is the amount of gas that was used processing this transaction. + # If the transaction has not yet been mined, this field will be null. + gasUsed: Long + # CumulativeGasUsed is the total gas used in the block up to and including + # this transaction. If the transaction has not yet been mined, this field + # will be null. + cumulativeGasUsed: Long + # CreatedContract is the account that was created by a contract creation + # transaction. If the transaction was not a contract creation transaction, + # or it has not yet been mined, this field will be null. + createdContract(block: Long): Account + # Logs is a list of log entries emitted by this transaction. If the + # transaction has not yet been mined, this field will be null. + logs: [Log!] + } + + # BlockFilterCriteria encapsulates log filter criteria for a filter applied + # to a single block. + input BlockFilterCriteria { + # Addresses is list of addresses that are of interest. If this list is + # empty, results will not be filtered by address. + addresses: [Address!] + # Topics list restricts matches to particular event topics. Each event has a list + # of topics. Topics matches a prefix of that list. An empty element array matches any + # topic. Non-empty elements represent an alternative that matches any of the + # contained topics. + # + # Examples: + # - [] or nil matches any topic list + # - [[A]] matches topic A in first position + # - [[], [B]] matches any topic in first position, B in second position + # - [[A], [B]] matches topic A in first position, B in second position + # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position + topics: [[Bytes32!]!] + } + + # Block is an Ethereum block. + type Block { + # Number is the number of this block, starting at 0 for the genesis block. + number: Long! + # Hash is the block hash of this block. + hash: Bytes32! + # Parent is the parent block of this block. + parent: Block + # Nonce is the block nonce, an 8 byte sequence determined by the miner. + nonce: Bytes! + # TransactionsRoot is the keccak256 hash of the root of the trie of transactions in this block. + transactionsRoot: Bytes32! + # TransactionCount is the number of transactions in this block. if + # transactions are not available for this block, this field will be null. + transactionCount: Int + # StateRoot is the keccak256 hash of the state trie after this block was processed. + stateRoot: Bytes32! + # ReceiptsRoot is the keccak256 hash of the trie of transaction receipts in this block. + receiptsRoot: Bytes32! + # Miner is the account that mined this block. + miner(block: Long): Account! + # ExtraData is an arbitrary data field supplied by the miner. + extraData: Bytes! + # GasLimit is the maximum amount of gas that was available to transactions in this block. + gasLimit: Long! + # GasUsed is the amount of gas that was used executing transactions in this block. + gasUsed: Long! + # Timestamp is the unix timestamp at which this block was mined. + timestamp: Long! + # LogsBloom is a bloom filter that can be used to check if a block may + # contain log entries matching a filter. + logsBloom: Bytes! + # MixHash is the hash that was used as an input to the PoW process. + mixHash: Bytes32! + # Difficulty is a measure of the difficulty of mining this block. + difficulty: BigInt! + # TotalDifficulty is the sum of all difficulty values up to and including + # this block. + totalDifficulty: BigInt! + # OmmerCount is the number of ommers (AKA uncles) associated with this + # block. If ommers are unavailable, this field will be null. + ommerCount: Int + # Ommers is a list of ommer (AKA uncle) blocks associated with this block. + # If ommers are unavailable, this field will be null. Depending on your + # node, the transactions, transactionAt, transactionCount, ommers, + # ommerCount and ommerAt fields may not be available on any ommer blocks. + ommers: [Block] + # OmmerAt returns the ommer (AKA uncle) at the specified index. If ommers + # are unavailable, or the index is out of bounds, this field will be null. + ommerAt(index: Int!): Block + # OmmerHash is the keccak256 hash of all the ommers (AKA uncles) + # associated with this block. + ommerHash: Bytes32! + # Transactions is a list of transactions associated with this block. If + # transactions are unavailable for this block, this field will be null. + transactions: [Transaction!] + # TransactionAt returns the transaction at the specified index. If + # transactions are unavailable for this block, or if the index is out of + # bounds, this field will be null. + transactionAt(index: Int!): Transaction + # Logs returns a filtered set of logs from this block. + logs(filter: BlockFilterCriteria!): [Log!]! + # Account fetches an Ethereum account at the current block's state. + account(address: Address!): Account! + # Call executes a local call operation at the current block's state. + call(data: CallData!): CallResult + # EstimateGas estimates the amount of gas that will be required for + # successful execution of a transaction at the current block's state. + estimateGas(data: CallData!): Long! + } + + # CallData represents the data associated with a local contract call. + # All fields are optional. + input CallData { + # From is the address making the call. + from: Address + # To is the address the call is sent to. + to: Address + # Gas is the amount of gas sent with the call. + gas: Long + # GasPrice is the price, in wei, offered for each unit of gas. + gasPrice: BigInt + # Value is the value, in wei, sent along with the call. + value: BigInt + # Data is the data sent to the callee. + data: Bytes + } + + # CallResult is the result of a local call operation. + type CallResult { + # Data is the return data of the called contract. + data: Bytes! + # GasUsed is the amount of gas used by the call, after any refunds. + gasUsed: Long! + # Status is the result of the call - 1 for success or 0 for failure. + status: Long! + } + + # FilterCriteria encapsulates log filter criteria for searching log entries. + input FilterCriteria { + # FromBlock is the block at which to start searching, inclusive. Defaults + # to the latest block if not supplied. + fromBlock: Long + # ToBlock is the block at which to stop searching, inclusive. Defaults + # to the latest block if not supplied. + toBlock: Long + # Addresses is a list of addresses that are of interest. If this list is + # empty, results will not be filtered by address. + addresses: [Address!] + # Topics list restricts matches to particular event topics. Each event has a list + # of topics. Topics matches a prefix of that list. An empty element array matches any + # topic. Non-empty elements represent an alternative that matches any of the + # contained topics. + # + # Examples: + # - [] or nil matches any topic list + # - [[A]] matches topic A in first position + # - [[], [B]] matches any topic in first position, B in second position + # - [[A], [B]] matches topic A in first position, B in second position + # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position + topics: [[Bytes32!]!] + } + + # SyncState contains the current synchronisation state of the client. + type SyncState{ + # StartingBlock is the block number at which synchronisation started. + startingBlock: Long! + # CurrentBlock is the point at which synchronisation has presently reached. + currentBlock: Long! + # HighestBlock is the latest known block number. + highestBlock: Long! + # PulledStates is the number of state entries fetched so far, or null + # if this is not known or not relevant. + pulledStates: Long + # KnownStates is the number of states the node knows of so far, or null + # if this is not known or not relevant. + knownStates: Long + } + + # Pending represents the current pending state. + type Pending { + # TransactionCount is the number of transactions in the pending state. + transactionCount: Int! + # Transactions is a list of transactions in the current pending state. + transactions: [Transaction!] + # Account fetches an Ethereum account for the pending state. + account(address: Address!): Account! + # Call executes a local call operation for the pending state. + call(data: CallData!): CallResult + # EstimateGas estimates the amount of gas that will be required for + # successful execution of a transaction for the pending state. + estimateGas(data: CallData!): Long! + } + + type Query { + # Block fetches an Ethereum block by number or by hash. If neither is + # supplied, the most recent known block is returned. + block(number: Long, hash: Bytes32): Block + # Blocks returns all the blocks between two numbers, inclusive. If + # to is not supplied, it defaults to the most recent known block. + blocks(from: Long!, to: Long): [Block!]! + # Pending returns the current pending state. + pending: Pending! + # Transaction returns a transaction specified by its hash. + transaction(hash: Bytes32!): Transaction + # Logs returns log entries matching the provided filter. + logs(filter: FilterCriteria!): [Log!]! + # GasPrice returns the node's estimate of a gas price sufficient to + # ensure a transaction is mined in a timely fashion. + gasPrice: BigInt! + # ProtocolVersion returns the current wire protocol version number. + protocolVersion: Int! + # Syncing returns information on the current synchronisation state. + syncing: SyncState + } + + type Mutation { + # SendRawTransaction sends an RLP-encoded transaction to the network. + sendRawTransaction(data: Bytes!): Bytes32! + } +` diff --git a/vendor/github.com/ethereum/go-ethereum/internal/build/env.go b/vendor/github.com/ethereum/go-ethereum/internal/build/env.go new file mode 100644 index 00000000..95f00035 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/build/env.go @@ -0,0 +1,161 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "flag" + "fmt" + "os" + "strconv" + "strings" + "time" +) + +var ( + // These flags override values in build env. + GitCommitFlag = flag.String("git-commit", "", `Overrides git commit hash embedded into executables`) + GitBranchFlag = flag.String("git-branch", "", `Overrides git branch being built`) + GitTagFlag = flag.String("git-tag", "", `Overrides git tag being built`) + BuildnumFlag = flag.String("buildnum", "", `Overrides CI build number`) + PullRequestFlag = flag.Bool("pull-request", false, `Overrides pull request status of the build`) + CronJobFlag = flag.Bool("cron-job", false, `Overrides cron job status of the build`) +) + +// Environment contains metadata provided by the build environment. +type Environment struct { + Name string // name of the environment + Repo string // name of GitHub repo + Commit, Date, Branch, Tag string // Git info + Buildnum string + IsPullRequest bool + IsCronJob bool +} + +func (env Environment) String() string { + return fmt.Sprintf("%s env (commit:%s date:%s branch:%s tag:%s buildnum:%s pr:%t)", + env.Name, env.Commit, env.Date, env.Branch, env.Tag, env.Buildnum, env.IsPullRequest) +} + +// Env returns metadata about the current CI environment, falling back to LocalEnv +// if not running on CI. +func Env() Environment { + switch { + case os.Getenv("CI") == "true" && os.Getenv("TRAVIS") == "true": + commit := os.Getenv("TRAVIS_PULL_REQUEST_SHA") + if commit == "" { + commit = os.Getenv("TRAVIS_COMMIT") + } + return Environment{ + Name: "travis", + Repo: os.Getenv("TRAVIS_REPO_SLUG"), + Commit: commit, + Date: getDate(commit), + Branch: os.Getenv("TRAVIS_BRANCH"), + Tag: os.Getenv("TRAVIS_TAG"), + Buildnum: os.Getenv("TRAVIS_BUILD_NUMBER"), + IsPullRequest: os.Getenv("TRAVIS_PULL_REQUEST") != "false", + IsCronJob: os.Getenv("TRAVIS_EVENT_TYPE") == "cron", + } + case os.Getenv("CI") == "True" && os.Getenv("APPVEYOR") == "True": + commit := os.Getenv("APPVEYOR_PULL_REQUEST_HEAD_COMMIT") + if commit == "" { + commit = os.Getenv("APPVEYOR_REPO_COMMIT") + } + return Environment{ + Name: "appveyor", + Repo: os.Getenv("APPVEYOR_REPO_NAME"), + Commit: commit, + Date: getDate(commit), + Branch: os.Getenv("APPVEYOR_REPO_BRANCH"), + Tag: os.Getenv("APPVEYOR_REPO_TAG_NAME"), + Buildnum: os.Getenv("APPVEYOR_BUILD_NUMBER"), + IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "", + IsCronJob: os.Getenv("APPVEYOR_SCHEDULED_BUILD") == "True", + } + default: + return LocalEnv() + } +} + +// LocalEnv returns build environment metadata gathered from git. +func LocalEnv() Environment { + env := applyEnvFlags(Environment{Name: "local", Repo: "ethereum/go-ethereum"}) + + head := readGitFile("HEAD") + if fields := strings.Fields(head); len(fields) == 2 { + head = fields[1] + } else { + return env + } + if env.Commit == "" { + env.Commit = readGitFile(head) + } + env.Date = getDate(env.Commit) + if env.Branch == "" { + if head != "HEAD" { + env.Branch = strings.TrimPrefix(head, "refs/heads/") + } + } + if info, err := os.Stat(".git/objects"); err == nil && info.IsDir() && env.Tag == "" { + env.Tag = firstLine(RunGit("tag", "-l", "--points-at", "HEAD")) + } + return env +} + +func firstLine(s string) string { + return strings.Split(s, "\n")[0] +} + +func getDate(commit string) string { + if commit == "" { + return "" + } + out := RunGit("show", "-s", "--format=%ct", commit) + if out == "" { + return "" + } + date, err := strconv.ParseInt(strings.TrimSpace(out), 10, 64) + if err != nil { + panic(fmt.Sprintf("failed to parse git commit date: %v", err)) + } + return time.Unix(date, 0).Format("20060102") +} + +func applyEnvFlags(env Environment) Environment { + if !flag.Parsed() { + panic("you need to call flag.Parse before Env or LocalEnv") + } + if *GitCommitFlag != "" { + env.Commit = *GitCommitFlag + } + if *GitBranchFlag != "" { + env.Branch = *GitBranchFlag + } + if *GitTagFlag != "" { + env.Tag = *GitTagFlag + } + if *BuildnumFlag != "" { + env.Buildnum = *BuildnumFlag + } + if *PullRequestFlag { + env.IsPullRequest = true + } + if *CronJobFlag { + env.IsCronJob = true + } + return env +} diff --git a/vendor/github.com/ethereum/go-ethereum/internal/build/util.go b/vendor/github.com/ethereum/go-ethereum/internal/build/util.go new file mode 100644 index 00000000..971d948c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/build/util.go @@ -0,0 +1,211 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package build + +import ( + "bytes" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "runtime" + "strings" + "text/template" +) + +var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") + +// MustRun executes the given command and exits the host process for +// any error. +func MustRun(cmd *exec.Cmd) { + fmt.Println(">>>", strings.Join(cmd.Args, " ")) + if !*DryRunFlag { + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + log.Fatal(err) + } + } +} + +func MustRunCommand(cmd string, args ...string) { + MustRun(exec.Command(cmd, args...)) +} + +// GOPATH returns the value that the GOPATH environment +// variable should be set to. +func GOPATH() string { + if os.Getenv("GOPATH") == "" { + log.Fatal("GOPATH is not set") + } + return os.Getenv("GOPATH") +} + +var warnedAboutGit bool + +// RunGit runs a git subcommand and returns its output. +// The command must complete successfully. +func RunGit(args ...string) string { + cmd := exec.Command("git", args...) + var stdout, stderr bytes.Buffer + cmd.Stdout, cmd.Stderr = &stdout, &stderr + if err := cmd.Run(); err != nil { + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + if !warnedAboutGit { + log.Println("Warning: can't find 'git' in PATH") + warnedAboutGit = true + } + return "" + } + log.Fatal(strings.Join(cmd.Args, " "), ": ", err, "\n", stderr.String()) + } + return strings.TrimSpace(stdout.String()) +} + +// readGitFile returns content of file in .git directory. +func readGitFile(file string) string { + content, err := ioutil.ReadFile(path.Join(".git", file)) + if err != nil { + return "" + } + return strings.TrimSpace(string(content)) +} + +// Render renders the given template file into outputFile. +func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) { + tpl := template.Must(template.ParseFiles(templateFile)) + render(tpl, outputFile, outputPerm, x) +} + +// RenderString renders the given template string into outputFile. +func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) { + tpl := template.Must(template.New("").Parse(templateContent)) + render(tpl, outputFile, outputPerm, x) +} + +func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x interface{}) { + if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil { + log.Fatal(err) + } + out, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY|os.O_EXCL, outputPerm) + if err != nil { + log.Fatal(err) + } + if err := tpl.Execute(out, x); err != nil { + log.Fatal(err) + } + if err := out.Close(); err != nil { + log.Fatal(err) + } +} + +// CopyFile copies a file. +func CopyFile(dst, src string, mode os.FileMode) { + if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { + log.Fatal(err) + } + destFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode) + if err != nil { + log.Fatal(err) + } + defer destFile.Close() + + srcFile, err := os.Open(src) + if err != nil { + log.Fatal(err) + } + defer srcFile.Close() + + if _, err := io.Copy(destFile, srcFile); err != nil { + log.Fatal(err) + } +} + +// GoTool returns the command that runs a go tool. This uses go from GOROOT instead of PATH +// so that go commands executed by build use the same version of Go as the 'host' that runs +// build code. e.g. +// +// /usr/lib/go-1.12.1/bin/go run build/ci.go ... +// +// runs using go 1.12.1 and invokes go 1.12.1 tools from the same GOROOT. This is also important +// because runtime.Version checks on the host should match the tools that are run. +func GoTool(tool string, args ...string) *exec.Cmd { + args = append([]string{tool}, args...) + return exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) +} + +// ExpandPackagesNoVendor expands a cmd/go import path pattern, skipping +// vendored packages. +func ExpandPackagesNoVendor(patterns []string) []string { + expand := false + for _, pkg := range patterns { + if strings.Contains(pkg, "...") { + expand = true + } + } + if expand { + cmd := GoTool("list", patterns...) + out, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("package listing failed: %v\n%s", err, string(out)) + } + var packages []string + for _, line := range strings.Split(string(out), "\n") { + if !strings.Contains(line, "/vendor/") { + packages = append(packages, strings.TrimSpace(line)) + } + } + return packages + } + return patterns +} + +// UploadSFTP uploads files to a remote host using the sftp command line tool. +// The destination host may be specified either as [user@]host[: or as a URI in +// the form sftp://[user@]host[:port]. +func UploadSFTP(identityFile, host, dir string, files []string) error { + sftp := exec.Command("sftp") + sftp.Stdout = nil + sftp.Stderr = os.Stderr + if identityFile != "" { + sftp.Args = append(sftp.Args, "-i", identityFile) + } + sftp.Args = append(sftp.Args, host) + fmt.Println(">>>", strings.Join(sftp.Args, " ")) + if *DryRunFlag { + return nil + } + + stdin, err := sftp.StdinPipe() + if err != nil { + return fmt.Errorf("can't create stdin pipe for sftp: %v", err) + } + if err := sftp.Start(); err != nil { + return err + } + in := io.MultiWriter(stdin, os.Stdout) + for _, f := range files { + fmt.Fprintln(in, "put", f, path.Join(dir, filepath.Base(f))) + } + stdin.Close() + return sftp.Wait() +} diff --git a/vendor/github.com/ethereum/go-ethereum/internal/ethapi/api.go b/vendor/github.com/ethereum/go-ethereum/internal/ethapi/api.go new file mode 100644 index 00000000..4132ff14 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/ethapi/api.go @@ -0,0 +1,1688 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package ethapi + +import ( + "bytes" + "context" + "errors" + "fmt" + "math/big" + "strings" + "time" + + "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/scwallet" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/syndtr/goleveldb/leveldb" + "github.com/tyler-smith/go-bip39" +) + +const ( + defaultGasPrice = params.GWei +) + +// PublicEthereumAPI provides an API to access Ethereum related information. +// It offers only methods that operate on public data that is freely available to anyone. +type PublicEthereumAPI struct { + b Backend +} + +// NewPublicEthereumAPI creates a new Ethereum protocol API. +func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { + return &PublicEthereumAPI{b} +} + +// GasPrice returns a suggestion for a gas price. +func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { + price, err := s.b.SuggestPrice(ctx) + return (*hexutil.Big)(price), err +} + +// ProtocolVersion returns the current Ethereum protocol version this node supports +func (s *PublicEthereumAPI) ProtocolVersion() hexutil.Uint { + return hexutil.Uint(s.b.ProtocolVersion()) +} + +// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not +// yet received the latest block headers from its pears. In case it is synchronizing: +// - startingBlock: block number this node started to synchronise from +// - currentBlock: block number this node is currently importing +// - highestBlock: block number of the highest block header this node has received from peers +// - pulledStates: number of state entries processed until now +// - knownStates: number of known state entries that still need to be pulled +func (s *PublicEthereumAPI) Syncing() (interface{}, error) { + progress := s.b.Downloader().Progress() + + // Return not syncing if the synchronisation already completed + if progress.CurrentBlock >= progress.HighestBlock { + return false, nil + } + // Otherwise gather the block sync stats + return map[string]interface{}{ + "startingBlock": hexutil.Uint64(progress.StartingBlock), + "currentBlock": hexutil.Uint64(progress.CurrentBlock), + "highestBlock": hexutil.Uint64(progress.HighestBlock), + "pulledStates": hexutil.Uint64(progress.PulledStates), + "knownStates": hexutil.Uint64(progress.KnownStates), + }, nil +} + +// PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. +type PublicTxPoolAPI struct { + b Backend +} + +// NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. +func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { + return &PublicTxPoolAPI{b} +} + +// Content returns the transactions contained within the transaction pool. +func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { + content := map[string]map[string]map[string]*RPCTransaction{ + "pending": make(map[string]map[string]*RPCTransaction), + "queued": make(map[string]map[string]*RPCTransaction), + } + pending, queue := s.b.TxPoolContent() + + // Flatten the pending transactions + for account, txs := range pending { + dump := make(map[string]*RPCTransaction) + for _, tx := range txs { + dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) + } + content["pending"][account.Hex()] = dump + } + // Flatten the queued transactions + for account, txs := range queue { + dump := make(map[string]*RPCTransaction) + for _, tx := range txs { + dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) + } + content["queued"][account.Hex()] = dump + } + return content +} + +// Status returns the number of pending and queued transaction in the pool. +func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { + pending, queue := s.b.Stats() + return map[string]hexutil.Uint{ + "pending": hexutil.Uint(pending), + "queued": hexutil.Uint(queue), + } +} + +// Inspect retrieves the content of the transaction pool and flattens it into an +// easily inspectable list. +func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { + content := map[string]map[string]map[string]string{ + "pending": make(map[string]map[string]string), + "queued": make(map[string]map[string]string), + } + pending, queue := s.b.TxPoolContent() + + // Define a formatter to flatten a transaction into a string + var format = func(tx *types.Transaction) string { + if to := tx.To(); to != nil { + return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) + } + return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) + } + // Flatten the pending transactions + for account, txs := range pending { + dump := make(map[string]string) + for _, tx := range txs { + dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) + } + content["pending"][account.Hex()] = dump + } + // Flatten the queued transactions + for account, txs := range queue { + dump := make(map[string]string) + for _, tx := range txs { + dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) + } + content["queued"][account.Hex()] = dump + } + return content +} + +// PublicAccountAPI provides an API to access accounts managed by this node. +// It offers only methods that can retrieve accounts. +type PublicAccountAPI struct { + am *accounts.Manager +} + +// NewPublicAccountAPI creates a new PublicAccountAPI. +func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { + return &PublicAccountAPI{am: am} +} + +// Accounts returns the collection of accounts this node manages +func (s *PublicAccountAPI) Accounts() []common.Address { + addresses := make([]common.Address, 0) // return [] instead of nil if empty + for _, wallet := range s.am.Wallets() { + for _, account := range wallet.Accounts() { + addresses = append(addresses, account.Address) + } + } + return addresses +} + +// PrivateAccountAPI provides an API to access accounts managed by this node. +// It offers methods to create, (un)lock en list accounts. Some methods accept +// passwords and are therefore considered private by default. +type PrivateAccountAPI struct { + am *accounts.Manager + nonceLock *AddrLocker + b Backend +} + +// NewPrivateAccountAPI create a new PrivateAccountAPI. +func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { + return &PrivateAccountAPI{ + am: b.AccountManager(), + nonceLock: nonceLock, + b: b, + } +} + +// listAccounts will return a list of addresses for accounts this node manages. +func (s *PrivateAccountAPI) ListAccounts() []common.Address { + addresses := make([]common.Address, 0) // return [] instead of nil if empty + for _, wallet := range s.am.Wallets() { + for _, account := range wallet.Accounts() { + addresses = append(addresses, account.Address) + } + } + return addresses +} + +// rawWallet is a JSON representation of an accounts.Wallet interface, with its +// data contents extracted into plain fields. +type rawWallet struct { + URL string `json:"url"` + Status string `json:"status"` + Failure string `json:"failure,omitempty"` + Accounts []accounts.Account `json:"accounts,omitempty"` +} + +// ListWallets will return a list of wallets this node manages. +func (s *PrivateAccountAPI) ListWallets() []rawWallet { + wallets := make([]rawWallet, 0) // return [] instead of nil if empty + for _, wallet := range s.am.Wallets() { + status, failure := wallet.Status() + + raw := rawWallet{ + URL: wallet.URL().String(), + Status: status, + Accounts: wallet.Accounts(), + } + if failure != nil { + raw.Failure = failure.Error() + } + wallets = append(wallets, raw) + } + return wallets +} + +// OpenWallet initiates a hardware wallet opening procedure, establishing a USB +// connection and attempting to authenticate via the provided passphrase. Note, +// the method may return an extra challenge requiring a second open (e.g. the +// Trezor PIN matrix challenge). +func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { + wallet, err := s.am.Wallet(url) + if err != nil { + return err + } + pass := "" + if passphrase != nil { + pass = *passphrase + } + return wallet.Open(pass) +} + +// DeriveAccount requests a HD wallet to derive a new account, optionally pinning +// it for later reuse. +func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { + wallet, err := s.am.Wallet(url) + if err != nil { + return accounts.Account{}, err + } + derivPath, err := accounts.ParseDerivationPath(path) + if err != nil { + return accounts.Account{}, err + } + if pin == nil { + pin = new(bool) + } + return wallet.Derive(derivPath, *pin) +} + +// NewAccount will create a new account and returns the address for the new account. +func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { + acc, err := fetchKeystore(s.am).NewAccount(password) + if err == nil { + log.Info("Your new key was generated", "address", acc.Address) + log.Warn("Please backup your key file!", "path", acc.URL.Path) + log.Warn("Please remember your password!") + return acc.Address, nil + } + return common.Address{}, err +} + +// fetchKeystore retrives the encrypted keystore from the account manager. +func fetchKeystore(am *accounts.Manager) *keystore.KeyStore { + return am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) +} + +// ImportRawKey stores the given hex encoded ECDSA key into the key directory, +// encrypting it with the passphrase. +func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { + key, err := crypto.HexToECDSA(privkey) + if err != nil { + return common.Address{}, err + } + acc, err := fetchKeystore(s.am).ImportECDSA(key, password) + return acc.Address, err +} + +// UnlockAccount will unlock the account associated with the given address with +// the given password for duration seconds. If duration is nil it will use a +// default of 300 seconds. It returns an indication if the account was unlocked. +func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { + // When the API is exposed by external RPC(http, ws etc), unless the user + // explicitly specifies to allow the insecure account unlocking, otherwise + // it is disabled. + if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { + return false, errors.New("account unlock with HTTP access is forbidden") + } + + const max = uint64(time.Duration(math.MaxInt64) / time.Second) + var d time.Duration + if duration == nil { + d = 300 * time.Second + } else if *duration > max { + return false, errors.New("unlock duration too large") + } else { + d = time.Duration(*duration) * time.Second + } + err := fetchKeystore(s.am).TimedUnlock(accounts.Account{Address: addr}, password, d) + if err != nil { + log.Warn("Failed account unlock attempt", "address", addr, "err", err) + } + return err == nil, err +} + +// LockAccount will lock the account associated with the given address when it's unlocked. +func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { + return fetchKeystore(s.am).Lock(addr) == nil +} + +// signTransaction sets defaults and signs the given transaction +// NOTE: the caller needs to ensure that the nonceLock is held, if applicable, +// and release it after the transaction has been submitted to the tx pool +func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: args.From} + wallet, err := s.am.Find(account) + if err != nil { + return nil, err + } + // Set some sanity defaults and terminate on failure + if err := args.setDefaults(ctx, s.b); err != nil { + return nil, err + } + // Assemble the transaction and sign with the wallet + tx := args.toTransaction() + + return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) +} + +// SendTransaction will create a transaction from the given arguments and +// tries to sign it with the key associated with args.To. If the given passwd isn't +// able to decrypt the key it fails. +func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { + if args.Nonce == nil { + // Hold the addresse's mutex around signing to prevent concurrent assignment of + // the same nonce to multiple accounts. + s.nonceLock.LockAddr(args.From) + defer s.nonceLock.UnlockAddr(args.From) + } + signed, err := s.signTransaction(ctx, &args, passwd) + if err != nil { + log.Warn("Failed transaction send attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) + return common.Hash{}, err + } + return SubmitTransaction(ctx, s.b, signed) +} + +// SignTransaction will create a transaction from the given arguments and +// tries to sign it with the key associated with args.To. If the given passwd isn't +// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast +// to other nodes +func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { + // No need to obtain the noncelock mutex, since we won't be sending this + // tx into the transaction pool, but right back to the user + if args.Gas == nil { + return nil, fmt.Errorf("gas not specified") + } + if args.GasPrice == nil { + return nil, fmt.Errorf("gasPrice not specified") + } + if args.Nonce == nil { + return nil, fmt.Errorf("nonce not specified") + } + signed, err := s.signTransaction(ctx, &args, passwd) + if err != nil { + log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) + return nil, err + } + data, err := rlp.EncodeToBytes(signed) + if err != nil { + return nil, err + } + return &SignTransactionResult{data, signed}, nil +} + +// Sign calculates an Ethereum ECDSA signature for: +// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)) +// +// Note, the produced signature conforms to the secp256k1 curve R, S and V values, +// where the V value will be 27 or 28 for legacy reasons. +// +// The key used to calculate the signature is decrypted with the given password. +// +// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign +func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: addr} + + wallet, err := s.b.AccountManager().Find(account) + if err != nil { + return nil, err + } + // Assemble sign the data with the wallet + signature, err := wallet.SignTextWithPassphrase(account, passwd, data) + if err != nil { + log.Warn("Failed data sign attempt", "address", addr, "err", err) + return nil, err + } + signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper + return signature, nil +} + +// EcRecover returns the address for the account that was used to create the signature. +// Note, this function is compatible with eth_sign and personal_sign. As such it recovers +// the address of: +// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message}) +// addr = ecrecover(hash, signature) +// +// Note, the signature must conform to the secp256k1 curve R, S and V values, where +// the V value must be 27 or 28 for legacy reasons. +// +// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover +func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { + if len(sig) != 65 { + return common.Address{}, fmt.Errorf("signature must be 65 bytes long") + } + if sig[64] != 27 && sig[64] != 28 { + return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") + } + sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1 + + rpk, err := crypto.SigToPub(accounts.TextHash(data), sig) + if err != nil { + return common.Address{}, err + } + return crypto.PubkeyToAddress(*rpk), nil +} + +// SignAndSendTransaction was renamed to SendTransaction. This method is deprecated +// and will be removed in the future. It primary goal is to give clients time to update. +func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { + return s.SendTransaction(ctx, args, passwd) +} + +// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. +func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { + wallet, err := s.am.Wallet(url) + if err != nil { + return "", err + } + + entropy, err := bip39.NewEntropy(256) + if err != nil { + return "", err + } + + mnemonic, err := bip39.NewMnemonic(entropy) + if err != nil { + return "", err + } + + seed := bip39.NewSeed(mnemonic, "") + + switch wallet := wallet.(type) { + case *scwallet.Wallet: + return mnemonic, wallet.Initialize(seed) + default: + return "", fmt.Errorf("Specified wallet does not support initialization") + } +} + +// Unpair deletes a pairing between wallet and geth. +func (s *PrivateAccountAPI) Unpair(ctx context.Context, url string, pin string) error { + wallet, err := s.am.Wallet(url) + if err != nil { + return err + } + + switch wallet := wallet.(type) { + case *scwallet.Wallet: + return wallet.Unpair([]byte(pin)) + default: + return fmt.Errorf("Specified wallet does not support pairing") + } +} + +// PublicBlockChainAPI provides an API to access the Ethereum blockchain. +// It offers only methods that operate on public data that is freely available to anyone. +type PublicBlockChainAPI struct { + b Backend +} + +// NewPublicBlockChainAPI creates a new Ethereum blockchain API. +func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { + return &PublicBlockChainAPI{b} +} + +// ChainId returns the chainID value for transaction replay protection. +func (s *PublicBlockChainAPI) ChainId() *hexutil.Big { + return (*hexutil.Big)(s.b.ChainConfig().ChainID) +} + +// BlockNumber returns the block number of the chain head. +func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { + header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available + return hexutil.Uint64(header.Number.Uint64()) +} + +// GetBalance returns the amount of wei for the given address in the state of the +// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta +// block numbers are also allowed. +func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) { + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + return (*hexutil.Big)(state.GetBalance(address)), state.Error() +} + +// Result structs for GetProof +type AccountResult struct { + Address common.Address `json:"address"` + AccountProof []string `json:"accountProof"` + Balance *hexutil.Big `json:"balance"` + CodeHash common.Hash `json:"codeHash"` + Nonce hexutil.Uint64 `json:"nonce"` + StorageHash common.Hash `json:"storageHash"` + StorageProof []StorageResult `json:"storageProof"` +} +type StorageResult struct { + Key string `json:"key"` + Value *hexutil.Big `json:"value"` + Proof []string `json:"proof"` +} + +// GetProof returns the Merkle-proof for a given account and optionally some storage keys. +func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*AccountResult, error) { + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + + storageTrie := state.StorageTrie(address) + storageHash := types.EmptyRootHash + codeHash := state.GetCodeHash(address) + storageProof := make([]StorageResult, len(storageKeys)) + + // if we have a storageTrie, (which means the account exists), we can update the storagehash + if storageTrie != nil { + storageHash = storageTrie.Hash() + } else { + // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. + codeHash = crypto.Keccak256Hash(nil) + } + + // create the proof for the storageKeys + for i, key := range storageKeys { + if storageTrie != nil { + proof, storageError := state.GetStorageProof(address, common.HexToHash(key)) + if storageError != nil { + return nil, storageError + } + storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), common.ToHexArray(proof)} + } else { + storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} + } + } + + // create the accountProof + accountProof, proofErr := state.GetProof(address) + if proofErr != nil { + return nil, proofErr + } + + return &AccountResult{ + Address: address, + AccountProof: common.ToHexArray(accountProof), + Balance: (*hexutil.Big)(state.GetBalance(address)), + CodeHash: codeHash, + Nonce: hexutil.Uint64(state.GetNonce(address)), + StorageHash: storageHash, + StorageProof: storageProof, + }, state.Error() +} + +// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all +// transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.BlockByNumber(ctx, blockNr) + if block != nil { + response, err := s.rpcOutputBlock(block, true, fullTx) + if err == nil && blockNr == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + return response, err + } + return nil, err +} + +// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full +// detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.GetBlock(ctx, blockHash) + if block != nil { + return s.rpcOutputBlock(block, true, fullTx) + } + return nil, err +} + +// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true +// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { + block, err := s.b.BlockByNumber(ctx, blockNr) + if block != nil { + uncles := block.Uncles() + if index >= hexutil.Uint(len(uncles)) { + log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) + return nil, nil + } + block = types.NewBlockWithHeader(uncles[index]) + return s.rpcOutputBlock(block, false, false) + } + return nil, err +} + +// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true +// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { + block, err := s.b.GetBlock(ctx, blockHash) + if block != nil { + uncles := block.Uncles() + if index >= hexutil.Uint(len(uncles)) { + log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) + return nil, nil + } + block = types.NewBlockWithHeader(uncles[index]) + return s.rpcOutputBlock(block, false, false) + } + return nil, err +} + +// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number +func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + n := hexutil.Uint(len(block.Uncles())) + return &n + } + return nil +} + +// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash +func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + n := hexutil.Uint(len(block.Uncles())) + return &n + } + return nil +} + +// GetCode returns the code stored at the given address in the state for the given block number. +func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + code := state.GetCode(address) + return code, state.Error() +} + +// GetStorageAt returns the storage from the state at the given address, key and +// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block +// numbers are also allowed. +func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + res := state.GetState(address, common.HexToHash(key)) + return res[:], state.Error() +} + +// CallArgs represents the arguments for a call. +type CallArgs struct { + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + Value *hexutil.Big `json:"value"` + Data *hexutil.Bytes `json:"data"` +} + +func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration, globalGasCap *big.Int) ([]byte, uint64, bool, error) { + defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) + + state, header, err := b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, 0, false, err + } + // Set sender address or use a default if none specified + var addr common.Address + if args.From == nil { + if wallets := b.AccountManager().Wallets(); len(wallets) > 0 { + if accounts := wallets[0].Accounts(); len(accounts) > 0 { + addr = accounts[0].Address + } + } + } else { + addr = *args.From + } + // Set default gas & gas price if none were set + gas := uint64(math.MaxUint64 / 2) + if args.Gas != nil { + gas = uint64(*args.Gas) + } + if globalGasCap != nil && globalGasCap.Uint64() < gas { + log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) + gas = globalGasCap.Uint64() + } + gasPrice := new(big.Int).SetUint64(defaultGasPrice) + if args.GasPrice != nil { + gasPrice = args.GasPrice.ToInt() + } + + value := new(big.Int) + if args.Value != nil { + value = args.Value.ToInt() + } + + var data []byte + if args.Data != nil { + data = []byte(*args.Data) + } + + // Create new call message + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, false) + + // Setup context so it may be cancelled the call has completed + // or, in case of unmetered gas, setup a context with a timeout. + var cancel context.CancelFunc + if timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, timeout) + } else { + ctx, cancel = context.WithCancel(ctx) + } + // Make sure the context is cancelled when the call has completed + // this makes sure resources are cleaned up. + defer cancel() + + // Get a new instance of the EVM. + evm, vmError, err := b.GetEVM(ctx, msg, state, header) + if err != nil { + return nil, 0, false, err + } + // Wait for the context to be done and cancel the evm. Even if the + // EVM has finished, cancelling may be done (repeatedly) + go func() { + <-ctx.Done() + evm.Cancel() + }() + + // Setup the gas pool (also for unmetered requests) + // and apply the message. + gp := new(core.GasPool).AddGas(math.MaxUint64) + res, gas, failed, err := core.ApplyMessage(evm, msg, gp) + if err := vmError(); err != nil { + return nil, 0, false, err + } + return res, gas, failed, err +} + +// Call executes the given transaction on the state for the given block number. +// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values. +func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { + result, _, _, err := DoCall(ctx, s.b, args, blockNr, vm.Config{}, 5*time.Second, s.b.RPCGasCap()) + return (hexutil.Bytes)(result), err +} + +func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber, gasCap *big.Int) (hexutil.Uint64, error) { + // Binary search the gas requirement, as it may be higher than the amount used + var ( + lo uint64 = params.TxGas - 1 + hi uint64 + cap uint64 + ) + if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { + hi = uint64(*args.Gas) + } else { + // Retrieve the block to act as the gas ceiling + block, err := b.BlockByNumber(ctx, blockNr) + if err != nil { + return 0, err + } + hi = block.GasLimit() + } + if gasCap != nil && hi > gasCap.Uint64() { + log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) + hi = gasCap.Uint64() + } + cap = hi + + // Create a helper to check if a gas allowance results in an executable transaction + executable := func(gas uint64) bool { + args.Gas = (*hexutil.Uint64)(&gas) + + _, _, failed, err := DoCall(ctx, b, args, rpc.PendingBlockNumber, vm.Config{}, 0, gasCap) + if err != nil || failed { + return false + } + return true + } + // Execute the binary search and hone in on an executable gas limit + for lo+1 < hi { + mid := (hi + lo) / 2 + if !executable(mid) { + lo = mid + } else { + hi = mid + } + } + // Reject the transaction as invalid if it still fails at the highest allowance + if hi == cap { + if !executable(hi) { + return 0, fmt.Errorf("gas required exceeds allowance (%d) or always failing transaction", cap) + } + } + return hexutil.Uint64(hi), nil +} + +// EstimateGas returns an estimate of the amount of gas needed to execute the +// given transaction against the current pending block. +func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) { + return DoEstimateGas(ctx, s.b, args, rpc.PendingBlockNumber, s.b.RPCGasCap()) +} + +// ExecutionResult groups all structured logs emitted by the EVM +// while replaying a transaction in debug mode as well as transaction +// execution status, the amount of gas used and the return value +type ExecutionResult struct { + Gas uint64 `json:"gas"` + Failed bool `json:"failed"` + ReturnValue string `json:"returnValue"` + StructLogs []StructLogRes `json:"structLogs"` +} + +// StructLogRes stores a structured log emitted by the EVM while replaying a +// transaction in debug mode +type StructLogRes struct { + Pc uint64 `json:"pc"` + Op string `json:"op"` + Gas uint64 `json:"gas"` + GasCost uint64 `json:"gasCost"` + Depth int `json:"depth"` + Error error `json:"error,omitempty"` + Stack *[]string `json:"stack,omitempty"` + Memory *[]string `json:"memory,omitempty"` + Storage *map[string]string `json:"storage,omitempty"` +} + +// FormatLogs formats EVM returned structured logs for json output +func FormatLogs(logs []vm.StructLog) []StructLogRes { + formatted := make([]StructLogRes, len(logs)) + for index, trace := range logs { + formatted[index] = StructLogRes{ + Pc: trace.Pc, + Op: trace.Op.String(), + Gas: trace.Gas, + GasCost: trace.GasCost, + Depth: trace.Depth, + Error: trace.Err, + } + if trace.Stack != nil { + stack := make([]string, len(trace.Stack)) + for i, stackValue := range trace.Stack { + stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32)) + } + formatted[index].Stack = &stack + } + if trace.Memory != nil { + memory := make([]string, 0, (len(trace.Memory)+31)/32) + for i := 0; i+32 <= len(trace.Memory); i += 32 { + memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) + } + formatted[index].Memory = &memory + } + if trace.Storage != nil { + storage := make(map[string]string) + for i, storageValue := range trace.Storage { + storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) + } + formatted[index].Storage = &storage + } + } + return formatted +} + +// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are +// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain +// transaction hashes. +func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { + head := b.Header() // copies the header once + fields := map[string]interface{}{ + "number": (*hexutil.Big)(head.Number), + "hash": b.Hash(), + "parentHash": head.ParentHash, + "nonce": head.Nonce, + "mixHash": head.MixDigest, + "sha3Uncles": head.UncleHash, + "logsBloom": head.Bloom, + "stateRoot": head.Root, + "miner": head.Coinbase, + "difficulty": (*hexutil.Big)(head.Difficulty), + "extraData": hexutil.Bytes(head.Extra), + "size": hexutil.Uint64(b.Size()), + "gasLimit": hexutil.Uint64(head.GasLimit), + "gasUsed": hexutil.Uint64(head.GasUsed), + "timestamp": hexutil.Uint64(head.Time), + "transactionsRoot": head.TxHash, + "receiptsRoot": head.ReceiptHash, + } + + if inclTx { + formatTx := func(tx *types.Transaction) (interface{}, error) { + return tx.Hash(), nil + } + if fullTx { + formatTx = func(tx *types.Transaction) (interface{}, error) { + return newRPCTransactionFromBlockHash(b, tx.Hash()), nil + } + } + txs := b.Transactions() + transactions := make([]interface{}, len(txs)) + var err error + for i, tx := range txs { + if transactions[i], err = formatTx(tx); err != nil { + return nil, err + } + } + fields["transactions"] = transactions + } + + uncles := b.Uncles() + uncleHashes := make([]common.Hash, len(uncles)) + for i, uncle := range uncles { + uncleHashes[i] = uncle.Hash() + } + fields["uncles"] = uncleHashes + + return fields, nil +} + +// rpcOutputBlock uses the generalized output filler, then adds the total difficulty field, which requires +// a `PublicBlockchainAPI`. +func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { + fields, err := RPCMarshalBlock(b, inclTx, fullTx) + if err != nil { + return nil, err + } + fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash())) + return fields, err +} + +// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction +type RPCTransaction struct { + BlockHash common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex hexutil.Uint `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` +} + +// newRPCTransaction returns a transaction that will serialize to the RPC +// representation, with the given location metadata set (if available). +func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + v, r, s := tx.RawSignatureValues() + + result := &RPCTransaction{ + From: from, + Gas: hexutil.Uint64(tx.Gas()), + GasPrice: (*hexutil.Big)(tx.GasPrice()), + Hash: tx.Hash(), + Input: hexutil.Bytes(tx.Data()), + Nonce: hexutil.Uint64(tx.Nonce()), + To: tx.To(), + Value: (*hexutil.Big)(tx.Value()), + V: (*hexutil.Big)(v), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), + } + if blockHash != (common.Hash{}) { + result.BlockHash = blockHash + result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) + result.TransactionIndex = hexutil.Uint(index) + } + return result +} + +// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation +func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { + return newRPCTransaction(tx, common.Hash{}, 0, 0) +} + +// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. +func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { + txs := b.Transactions() + if index >= uint64(len(txs)) { + return nil + } + return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) +} + +// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. +func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { + txs := b.Transactions() + if index >= uint64(len(txs)) { + return nil + } + blob, _ := rlp.EncodeToBytes(txs[index]) + return blob +} + +// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. +func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { + for idx, tx := range b.Transactions() { + if tx.Hash() == hash { + return newRPCTransactionFromBlockIndex(b, uint64(idx)) + } + } + return nil +} + +// PublicTransactionPoolAPI exposes methods for the RPC interface +type PublicTransactionPoolAPI struct { + b Backend + nonceLock *AddrLocker +} + +// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. +func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { + return &PublicTransactionPoolAPI{b, nonceLock} +} + +// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. +func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + n := hexutil.Uint(len(block.Transactions())) + return &n + } + return nil +} + +// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. +func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + n := hexutil.Uint(len(block.Transactions())) + return &n + } + return nil +} + +// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. +func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index)) + } + return nil +} + +// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. +func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return newRPCTransactionFromBlockIndex(block, uint64(index)) + } + return nil +} + +// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. +func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + return newRPCRawTransactionFromBlockIndex(block, uint64(index)) + } + return nil +} + +// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. +func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return newRPCRawTransactionFromBlockIndex(block, uint64(index)) + } + return nil +} + +// GetTransactionCount returns the number of transactions the given address has sent for the given block number +func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { + // Ask transaction pool for the nonce which includes pending transactions + if blockNr == rpc.PendingBlockNumber { + nonce, err := s.b.GetPoolNonce(ctx, address) + if err != nil { + return nil, err + } + return (*hexutil.Uint64)(&nonce), nil + } + // Resolve block number and use its state to ask for the nonce + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + nonce := state.GetNonce(address) + return (*hexutil.Uint64)(&nonce), state.Error() +} + +// GetTransactionByHash returns the transaction for the given hash +func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { + // Try to return an already finalized transaction + tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) + if err != nil { + return nil, err + } + if tx != nil { + return newRPCTransaction(tx, blockHash, blockNumber, index), nil + } + // No finalized transaction, try to retrieve it from the pool + if tx := s.b.GetPoolTransaction(hash); tx != nil { + return newRPCPendingTransaction(tx), nil + } + + // Transaction unknown, return as such + return nil, nil +} + +// GetRawTransactionByHash returns the bytes of the transaction for the given hash. +func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { + // Retrieve a finalized transaction, or a pooled otherwise + tx, _, _, _, err := s.b.GetTransaction(ctx, hash) + if err != nil { + return nil, err + } + if tx == nil { + if tx = s.b.GetPoolTransaction(hash); tx == nil { + // Transaction not found anywhere, abort + return nil, nil + } + } + // Serialize to RLP and return + return rlp.EncodeToBytes(tx) +} + +// GetTransactionReceipt returns the transaction receipt for the given transaction hash. +func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { + tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) + if tx == nil { + return nil, nil + } + receipts, err := s.b.GetReceipts(ctx, blockHash) + if err != nil { + return nil, err + } + if len(receipts) <= int(index) { + return nil, nil + } + receipt := receipts[index] + + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + + fields := map[string]interface{}{ + "blockHash": blockHash, + "blockNumber": hexutil.Uint64(blockNumber), + "transactionHash": hash, + "transactionIndex": hexutil.Uint64(index), + "from": from, + "to": tx.To(), + "gasUsed": hexutil.Uint64(receipt.GasUsed), + "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), + "contractAddress": nil, + "logs": receipt.Logs, + "logsBloom": receipt.Bloom, + } + + // Assign receipt status or post state. + if len(receipt.PostState) > 0 { + fields["root"] = hexutil.Bytes(receipt.PostState) + } else { + fields["status"] = hexutil.Uint(receipt.Status) + } + if receipt.Logs == nil { + fields["logs"] = [][]*types.Log{} + } + // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation + if receipt.ContractAddress != (common.Address{}) { + fields["contractAddress"] = receipt.ContractAddress + } + return fields, nil +} + +// sign is a helper function that signs a transaction with the private key of the given address. +func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: addr} + + wallet, err := s.b.AccountManager().Find(account) + if err != nil { + return nil, err + } + // Request the wallet to sign the transaction + return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) +} + +// SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. +type SendTxArgs struct { + From common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` + // We accept "data" and "input" for backwards-compatibility reasons. "input" is the + // newer name and should be preferred by clients. + Data *hexutil.Bytes `json:"data"` + Input *hexutil.Bytes `json:"input"` +} + +// setDefaults is a helper function that fills in default values for unspecified tx fields. +func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { + if args.GasPrice == nil { + price, err := b.SuggestPrice(ctx) + if err != nil { + return err + } + args.GasPrice = (*hexutil.Big)(price) + } + if args.Value == nil { + args.Value = new(hexutil.Big) + } + if args.Nonce == nil { + nonce, err := b.GetPoolNonce(ctx, args.From) + if err != nil { + return err + } + args.Nonce = (*hexutil.Uint64)(&nonce) + } + if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { + return errors.New(`Both "data" and "input" are set and not equal. Please use "input" to pass transaction call data.`) + } + if args.To == nil { + // Contract creation + var input []byte + if args.Data != nil { + input = *args.Data + } else if args.Input != nil { + input = *args.Input + } + if len(input) == 0 { + return errors.New(`contract creation without any data provided`) + } + } + // Estimate the gas usage if necessary. + if args.Gas == nil { + // For backwards-compatibility reason, we try both input and data + // but input is preferred. + input := args.Input + if input == nil { + input = args.Data + } + callArgs := CallArgs{ + From: &args.From, // From shouldn't be nil + To: args.To, + GasPrice: args.GasPrice, + Value: args.Value, + Data: input, + } + estimated, err := DoEstimateGas(ctx, b, callArgs, rpc.PendingBlockNumber, b.RPCGasCap()) + if err != nil { + return err + } + args.Gas = &estimated + log.Trace("Estimate gas usage automatically", "gas", args.Gas) + } + return nil +} + +func (args *SendTxArgs) toTransaction() *types.Transaction { + var input []byte + if args.Input != nil { + input = *args.Input + } else if args.Data != nil { + input = *args.Data + } + if args.To == nil { + return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) + } + return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) +} + +// SubmitTransaction is a helper function that submits tx to txPool and logs a message. +func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { + if err := b.SendTx(ctx, tx); err != nil { + return common.Hash{}, err + } + if tx.To() == nil { + signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) + from, err := types.Sender(signer, tx) + if err != nil { + return common.Hash{}, err + } + addr := crypto.CreateAddress(from, tx.Nonce()) + log.Info("Submitted contract creation", "fullhash", tx.Hash().Hex(), "contract", addr.Hex()) + } else { + log.Info("Submitted transaction", "fullhash", tx.Hash().Hex(), "recipient", tx.To()) + } + return tx.Hash(), nil +} + +// SendTransaction creates a transaction for the given argument, sign it and submit it to the +// transaction pool. +func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: args.From} + + wallet, err := s.b.AccountManager().Find(account) + if err != nil { + return common.Hash{}, err + } + + if args.Nonce == nil { + // Hold the addresse's mutex around signing to prevent concurrent assignment of + // the same nonce to multiple accounts. + s.nonceLock.LockAddr(args.From) + defer s.nonceLock.UnlockAddr(args.From) + } + + // Set some sanity defaults and terminate on failure + if err := args.setDefaults(ctx, s.b); err != nil { + return common.Hash{}, err + } + // Assemble the transaction and sign with the wallet + tx := args.toTransaction() + + signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) + if err != nil { + return common.Hash{}, err + } + return SubmitTransaction(ctx, s.b, signed) +} + +// SendRawTransaction will add the signed transaction to the transaction pool. +// The sender is responsible for signing the transaction and using the correct nonce. +func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { + tx := new(types.Transaction) + if err := rlp.DecodeBytes(encodedTx, tx); err != nil { + return common.Hash{}, err + } + return SubmitTransaction(ctx, s.b, tx) +} + +// Sign calculates an ECDSA signature for: +// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message). +// +// Note, the produced signature conforms to the secp256k1 curve R, S and V values, +// where the V value will be 27 or 28 for legacy reasons. +// +// The account associated with addr must be unlocked. +// +// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign +func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { + // Look up the wallet containing the requested signer + account := accounts.Account{Address: addr} + + wallet, err := s.b.AccountManager().Find(account) + if err != nil { + return nil, err + } + // Sign the requested hash with the wallet + signature, err := wallet.SignText(account, data) + if err == nil { + signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper + } + return signature, err +} + +// SignTransactionResult represents a RLP encoded signed transaction. +type SignTransactionResult struct { + Raw hexutil.Bytes `json:"raw"` + Tx *types.Transaction `json:"tx"` +} + +// SignTransaction will sign the given transaction with the from account. +// The node needs to have the private key of the account corresponding with +// the given from address and it needs to be unlocked. +func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { + if args.Gas == nil { + return nil, fmt.Errorf("gas not specified") + } + if args.GasPrice == nil { + return nil, fmt.Errorf("gasPrice not specified") + } + if args.Nonce == nil { + return nil, fmt.Errorf("nonce not specified") + } + if err := args.setDefaults(ctx, s.b); err != nil { + return nil, err + } + tx, err := s.sign(args.From, args.toTransaction()) + if err != nil { + return nil, err + } + data, err := rlp.EncodeToBytes(tx) + if err != nil { + return nil, err + } + return &SignTransactionResult{data, tx}, nil +} + +// PendingTransactions returns the transactions that are in the transaction pool +// and have a from address that is one of the accounts this node manages. +func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { + pending, err := s.b.GetPoolTransactions() + if err != nil { + return nil, err + } + accounts := make(map[common.Address]struct{}) + for _, wallet := range s.b.AccountManager().Wallets() { + for _, account := range wallet.Accounts() { + accounts[account.Address] = struct{}{} + } + } + transactions := make([]*RPCTransaction, 0, len(pending)) + for _, tx := range pending { + var signer types.Signer = types.HomesteadSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + if _, exists := accounts[from]; exists { + transactions = append(transactions, newRPCPendingTransaction(tx)) + } + } + return transactions, nil +} + +// Resend accepts an existing transaction and a new gas price and limit. It will remove +// the given transaction from the pool and reinsert it with the new gas price and limit. +func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { + if sendArgs.Nonce == nil { + return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") + } + if err := sendArgs.setDefaults(ctx, s.b); err != nil { + return common.Hash{}, err + } + matchTx := sendArgs.toTransaction() + pending, err := s.b.GetPoolTransactions() + if err != nil { + return common.Hash{}, err + } + + for _, p := range pending { + var signer types.Signer = types.HomesteadSigner{} + if p.Protected() { + signer = types.NewEIP155Signer(p.ChainId()) + } + wantSigHash := signer.Hash(matchTx) + + if pFrom, err := types.Sender(signer, p); err == nil && pFrom == sendArgs.From && signer.Hash(p) == wantSigHash { + // Match. Re-sign and send the transaction. + if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { + sendArgs.GasPrice = gasPrice + } + if gasLimit != nil && *gasLimit != 0 { + sendArgs.Gas = gasLimit + } + signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) + if err != nil { + return common.Hash{}, err + } + if err = s.b.SendTx(ctx, signedTx); err != nil { + return common.Hash{}, err + } + return signedTx.Hash(), nil + } + } + + return common.Hash{}, fmt.Errorf("Transaction %#x not found", matchTx.Hash()) +} + +// PublicDebugAPI is the collection of Ethereum APIs exposed over the public +// debugging endpoint. +type PublicDebugAPI struct { + b Backend +} + +// NewPublicDebugAPI creates a new API definition for the public debug methods +// of the Ethereum service. +func NewPublicDebugAPI(b Backend) *PublicDebugAPI { + return &PublicDebugAPI{b: b} +} + +// GetBlockRlp retrieves the RLP encoded for of a single block. +func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + encoded, err := rlp.EncodeToBytes(block) + if err != nil { + return "", err + } + return fmt.Sprintf("%x", encoded), nil +} + +// TestSignCliqueBlock fetches the given block number, and attempts to sign it as a clique header with the +// given address, returning the address of the recovered signature +// +// This is a temporary method to debug the externalsigner integration, +// TODO: Remove this method when the integration is mature +func (api *PublicDebugAPI) TestSignCliqueBlock(ctx context.Context, address common.Address, number uint64) (common.Address, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return common.Address{}, fmt.Errorf("block #%d not found", number) + } + header := block.Header() + header.Extra = make([]byte, 32+65) + encoded := clique.CliqueRLP(header) + + // Look up the wallet containing the requested signer + account := accounts.Account{Address: address} + wallet, err := api.b.AccountManager().Find(account) + if err != nil { + return common.Address{}, err + } + + signature, err := wallet.SignData(account, accounts.MimetypeClique, encoded) + if err != nil { + return common.Address{}, err + } + sealHash := clique.SealHash(header).Bytes() + log.Info("test signing of clique block", + "Sealhash", fmt.Sprintf("%x", sealHash), + "signature", fmt.Sprintf("%x", signature)) + pubkey, err := crypto.Ecrecover(sealHash, signature) + if err != nil { + return common.Address{}, err + } + var signer common.Address + copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) + + return signer, nil +} + +// PrintBlock retrieves a block and returns its pretty printed form. +func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + return spew.Sdump(block), nil +} + +// SeedHash retrieves the seed hash of a block. +func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + return fmt.Sprintf("0x%x", ethash.SeedHash(number)), nil +} + +// PrivateDebugAPI is the collection of Ethereum APIs exposed over the private +// debugging endpoint. +type PrivateDebugAPI struct { + b Backend +} + +// NewPrivateDebugAPI creates a new API definition for the private debug methods +// of the Ethereum service. +func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { + return &PrivateDebugAPI{b: b} +} + +// ChaindbProperty returns leveldb properties of the chain database. +func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { + ldb, ok := api.b.ChainDb().(interface { + LDB() *leveldb.DB + }) + if !ok { + return "", fmt.Errorf("chaindbProperty does not work for memory databases") + } + if property == "" { + property = "leveldb.stats" + } else if !strings.HasPrefix(property, "leveldb.") { + property = "leveldb." + property + } + return ldb.LDB().GetProperty(property) +} + +func (api *PrivateDebugAPI) ChaindbCompact() error { + for b := byte(0); b < 255; b++ { + log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) + if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { + log.Error("Database compaction failed", "err", err) + return err + } + } + return nil +} + +// SetHead rewinds the head of the blockchain to a previous block. +func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { + api.b.SetHead(uint64(number)) +} + +// PublicNetAPI offers network related RPC methods +type PublicNetAPI struct { + net *p2p.Server + networkVersion uint64 +} + +// NewPublicNetAPI creates a new net API instance. +func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { + return &PublicNetAPI{net, networkVersion} +} + +// Listening returns an indication if the node is listening for network connections. +func (s *PublicNetAPI) Listening() bool { + return true // always listening +} + +// PeerCount returns the number of connected peers +func (s *PublicNetAPI) PeerCount() hexutil.Uint { + return hexutil.Uint(s.net.PeerCount()) +} + +// Version returns the current ethereum protocol version. +func (s *PublicNetAPI) Version() string { + return fmt.Sprintf("%d", s.networkVersion) +} diff --git a/vendor/github.com/ethereum/go-ethereum/internal/ethapi/backend.go b/vendor/github.com/ethereum/go-ethereum/internal/ethapi/backend.go new file mode 100644 index 00000000..9229ccfb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/ethapi/backend.go @@ -0,0 +1,121 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package ethapi implements the general Ethereum API functions. +package ethapi + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +// Backend interface provides the common API services (that are provided by +// both full and light clients) with access to necessary functions. +type Backend interface { + // General Ethereum API + Downloader() *downloader.Downloader + ProtocolVersion() int + SuggestPrice(ctx context.Context) (*big.Int, error) + ChainDb() ethdb.Database + EventMux() *event.TypeMux + AccountManager() *accounts.Manager + ExtRPCEnabled() bool + RPCGasCap() *big.Int // global gas cap for eth_call over rpc: DoS protection + + // BlockChain API + SetHead(number uint64) + HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) + BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) + StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) + GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) + GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) + GetTd(blockHash common.Hash) *big.Int + GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) + SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription + SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription + + // TxPool API + SendTx(ctx context.Context, signedTx *types.Transaction) error + GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) + GetPoolTransactions() (types.Transactions, error) + GetPoolTransaction(txHash common.Hash) *types.Transaction + GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) + Stats() (pending int, queued int) + TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) + SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription + + ChainConfig() *params.ChainConfig + CurrentBlock() *types.Block +} + +func GetAPIs(apiBackend Backend) []rpc.API { + nonceLock := new(AddrLocker) + return []rpc.API{ + { + Namespace: "eth", + Version: "1.0", + Service: NewPublicEthereumAPI(apiBackend), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicBlockChainAPI(apiBackend), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicTransactionPoolAPI(apiBackend, nonceLock), + Public: true, + }, { + Namespace: "txpool", + Version: "1.0", + Service: NewPublicTxPoolAPI(apiBackend), + Public: true, + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPublicDebugAPI(apiBackend), + Public: true, + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPrivateDebugAPI(apiBackend), + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicAccountAPI(apiBackend.AccountManager()), + Public: true, + }, { + Namespace: "personal", + Version: "1.0", + Service: NewPrivateAccountAPI(apiBackend, nonceLock), + Public: false, + }, + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/internal/testlog/testlog.go b/vendor/github.com/ethereum/go-ethereum/internal/testlog/testlog.go new file mode 100644 index 00000000..ffe0546f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/testlog/testlog.go @@ -0,0 +1,46 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package testlog provides a log handler for unit tests. +package testlog + +import ( + "testing" + + "github.com/ethereum/go-ethereum/log" +) + +// Logger returns a logger which logs to the unit test log of t. +func Logger(t *testing.T, level log.Lvl) log.Logger { + l := log.New() + l.SetHandler(Handler(t, level)) + return l +} + +// Handler returns a log handler which logs to the unit test log of t. +func Handler(t *testing.T, level log.Lvl) log.Handler { + return log.LvlFilterHandler(level, &handler{t, log.TerminalFormat(false)}) +} + +type handler struct { + t *testing.T + fmt log.Format +} + +func (h *handler) Log(r *log.Record) error { + h.t.Logf("%s", h.fmt.Format(r)) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/internal/web3ext/web3ext.go b/vendor/github.com/ethereum/go-ethereum/internal/web3ext/web3ext.go new file mode 100644 index 00000000..31c0c57e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/internal/web3ext/web3ext.go @@ -0,0 +1,762 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// package web3ext contains geth specific web3.js extensions. +package web3ext + +var Modules = map[string]string{ + "accounting": AccountingJs, + "admin": AdminJs, + "chequebook": ChequebookJs, + "clique": CliqueJs, + "ethash": EthashJs, + "debug": DebugJs, + "eth": EthJs, + "miner": MinerJs, + "net": NetJs, + "personal": PersonalJs, + "rpc": RpcJs, + "shh": ShhJs, + "swarmfs": SwarmfsJs, + "txpool": TxpoolJs, +} + +const ChequebookJs = ` +web3._extend({ + property: 'chequebook', + methods: [ + new web3._extend.Method({ + name: 'deposit', + call: 'chequebook_deposit', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Property({ + name: 'balance', + getter: 'chequebook_balance', + outputFormatter: web3._extend.utils.toDecimal + }), + new web3._extend.Method({ + name: 'cash', + call: 'chequebook_cash', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'issue', + call: 'chequebook_issue', + params: 2, + inputFormatter: [null, null] + }), + ] +}); +` + +const CliqueJs = ` +web3._extend({ + property: 'clique', + methods: [ + new web3._extend.Method({ + name: 'getSnapshot', + call: 'clique_getSnapshot', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'getSnapshotAtHash', + call: 'clique_getSnapshotAtHash', + params: 1 + }), + new web3._extend.Method({ + name: 'getSigners', + call: 'clique_getSigners', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'getSignersAtHash', + call: 'clique_getSignersAtHash', + params: 1 + }), + new web3._extend.Method({ + name: 'propose', + call: 'clique_propose', + params: 2 + }), + new web3._extend.Method({ + name: 'discard', + call: 'clique_discard', + params: 1 + }), + ], + properties: [ + new web3._extend.Property({ + name: 'proposals', + getter: 'clique_proposals' + }), + ] +}); +` + +const EthashJs = ` +web3._extend({ + property: 'ethash', + methods: [ + new web3._extend.Method({ + name: 'getWork', + call: 'ethash_getWork', + params: 0 + }), + new web3._extend.Method({ + name: 'getHashrate', + call: 'ethash_getHashrate', + params: 0 + }), + new web3._extend.Method({ + name: 'submitWork', + call: 'ethash_submitWork', + params: 3, + }), + new web3._extend.Method({ + name: 'submitHashRate', + call: 'ethash_submitHashRate', + params: 2, + }), + ] +}); +` + +const AdminJs = ` +web3._extend({ + property: 'admin', + methods: [ + new web3._extend.Method({ + name: 'addPeer', + call: 'admin_addPeer', + params: 1 + }), + new web3._extend.Method({ + name: 'removePeer', + call: 'admin_removePeer', + params: 1 + }), + new web3._extend.Method({ + name: 'addTrustedPeer', + call: 'admin_addTrustedPeer', + params: 1 + }), + new web3._extend.Method({ + name: 'removeTrustedPeer', + call: 'admin_removeTrustedPeer', + params: 1 + }), + new web3._extend.Method({ + name: 'exportChain', + call: 'admin_exportChain', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'importChain', + call: 'admin_importChain', + params: 1 + }), + new web3._extend.Method({ + name: 'sleepBlocks', + call: 'admin_sleepBlocks', + params: 2 + }), + new web3._extend.Method({ + name: 'startRPC', + call: 'admin_startRPC', + params: 4, + inputFormatter: [null, null, null, null] + }), + new web3._extend.Method({ + name: 'stopRPC', + call: 'admin_stopRPC' + }), + new web3._extend.Method({ + name: 'startWS', + call: 'admin_startWS', + params: 4, + inputFormatter: [null, null, null, null] + }), + new web3._extend.Method({ + name: 'stopWS', + call: 'admin_stopWS' + }), + ], + properties: [ + new web3._extend.Property({ + name: 'nodeInfo', + getter: 'admin_nodeInfo' + }), + new web3._extend.Property({ + name: 'peers', + getter: 'admin_peers' + }), + new web3._extend.Property({ + name: 'datadir', + getter: 'admin_datadir' + }), + ] +}); +` + +const DebugJs = ` +web3._extend({ + property: 'debug', + methods: [ + new web3._extend.Method({ + name: 'printBlock', + call: 'debug_printBlock', + params: 1 + }), + new web3._extend.Method({ + name: 'getBlockRlp', + call: 'debug_getBlockRlp', + params: 1 + }), + new web3._extend.Method({ + name: 'testSignCliqueBlock', + call: 'debug_testSignCliqueBlock', + params: 2, + inputFormatters: [web3._extend.formatters.inputAddressFormatter, null], + }), + new web3._extend.Method({ + name: 'setHead', + call: 'debug_setHead', + params: 1 + }), + new web3._extend.Method({ + name: 'seedHash', + call: 'debug_seedHash', + params: 1 + }), + new web3._extend.Method({ + name: 'dumpBlock', + call: 'debug_dumpBlock', + params: 1 + }), + new web3._extend.Method({ + name: 'chaindbProperty', + call: 'debug_chaindbProperty', + params: 1, + outputFormatter: console.log + }), + new web3._extend.Method({ + name: 'chaindbCompact', + call: 'debug_chaindbCompact', + }), + new web3._extend.Method({ + name: 'verbosity', + call: 'debug_verbosity', + params: 1 + }), + new web3._extend.Method({ + name: 'vmodule', + call: 'debug_vmodule', + params: 1 + }), + new web3._extend.Method({ + name: 'backtraceAt', + call: 'debug_backtraceAt', + params: 1, + }), + new web3._extend.Method({ + name: 'stacks', + call: 'debug_stacks', + params: 0, + outputFormatter: console.log + }), + new web3._extend.Method({ + name: 'freeOSMemory', + call: 'debug_freeOSMemory', + params: 0, + }), + new web3._extend.Method({ + name: 'setGCPercent', + call: 'debug_setGCPercent', + params: 1, + }), + new web3._extend.Method({ + name: 'memStats', + call: 'debug_memStats', + params: 0, + }), + new web3._extend.Method({ + name: 'gcStats', + call: 'debug_gcStats', + params: 0, + }), + new web3._extend.Method({ + name: 'cpuProfile', + call: 'debug_cpuProfile', + params: 2 + }), + new web3._extend.Method({ + name: 'startCPUProfile', + call: 'debug_startCPUProfile', + params: 1 + }), + new web3._extend.Method({ + name: 'stopCPUProfile', + call: 'debug_stopCPUProfile', + params: 0 + }), + new web3._extend.Method({ + name: 'goTrace', + call: 'debug_goTrace', + params: 2 + }), + new web3._extend.Method({ + name: 'startGoTrace', + call: 'debug_startGoTrace', + params: 1 + }), + new web3._extend.Method({ + name: 'stopGoTrace', + call: 'debug_stopGoTrace', + params: 0 + }), + new web3._extend.Method({ + name: 'blockProfile', + call: 'debug_blockProfile', + params: 2 + }), + new web3._extend.Method({ + name: 'setBlockProfileRate', + call: 'debug_setBlockProfileRate', + params: 1 + }), + new web3._extend.Method({ + name: 'writeBlockProfile', + call: 'debug_writeBlockProfile', + params: 1 + }), + new web3._extend.Method({ + name: 'mutexProfile', + call: 'debug_mutexProfile', + params: 2 + }), + new web3._extend.Method({ + name: 'setMutexProfileFraction', + call: 'debug_setMutexProfileFraction', + params: 1 + }), + new web3._extend.Method({ + name: 'writeMutexProfile', + call: 'debug_writeMutexProfile', + params: 1 + }), + new web3._extend.Method({ + name: 'writeMemProfile', + call: 'debug_writeMemProfile', + params: 1 + }), + new web3._extend.Method({ + name: 'traceBlock', + call: 'debug_traceBlock', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'traceBlockFromFile', + call: 'debug_traceBlockFromFile', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'traceBadBlock', + call: 'debug_traceBadBlock', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'standardTraceBadBlockToFile', + call: 'debug_standardTraceBadBlockToFile', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'standardTraceBlockToFile', + call: 'debug_standardTraceBlockToFile', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'traceBlockByNumber', + call: 'debug_traceBlockByNumber', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'traceBlockByHash', + call: 'debug_traceBlockByHash', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'traceTransaction', + call: 'debug_traceTransaction', + params: 2, + inputFormatter: [null, null] + }), + new web3._extend.Method({ + name: 'preimage', + call: 'debug_preimage', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'getBadBlocks', + call: 'debug_getBadBlocks', + params: 0, + }), + new web3._extend.Method({ + name: 'storageRangeAt', + call: 'debug_storageRangeAt', + params: 5, + }), + new web3._extend.Method({ + name: 'getModifiedAccountsByNumber', + call: 'debug_getModifiedAccountsByNumber', + params: 2, + inputFormatter: [null, null], + }), + new web3._extend.Method({ + name: 'getModifiedAccountsByHash', + call: 'debug_getModifiedAccountsByHash', + params: 2, + inputFormatter:[null, null], + }), + ], + properties: [] +}); +` + +const EthJs = ` +web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'chainId', + call: 'eth_chainId', + params: 0 + }), + new web3._extend.Method({ + name: 'sign', + call: 'eth_sign', + params: 2, + inputFormatter: [web3._extend.formatters.inputAddressFormatter, null] + }), + new web3._extend.Method({ + name: 'resend', + call: 'eth_resend', + params: 3, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal] + }), + new web3._extend.Method({ + name: 'signTransaction', + call: 'eth_signTransaction', + params: 1, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'submitTransaction', + call: 'eth_submitTransaction', + params: 1, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter] + }), + new web3._extend.Method({ + name: 'getRawTransaction', + call: 'eth_getRawTransactionByHash', + params: 1 + }), + new web3._extend.Method({ + name: 'getRawTransactionFromBlock', + call: function(args) { + return (web3._extend.utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getRawTransactionByBlockHashAndIndex' : 'eth_getRawTransactionByBlockNumberAndIndex'; + }, + params: 2, + inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter, web3._extend.utils.toHex] + }), + new web3._extend.Method({ + name: 'getProof', + call: 'eth_getProof', + params: 3, + inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, web3._extend.formatters.inputBlockNumberFormatter] + }), + ], + properties: [ + new web3._extend.Property({ + name: 'pendingTransactions', + getter: 'eth_pendingTransactions', + outputFormatter: function(txs) { + var formatted = []; + for (var i = 0; i < txs.length; i++) { + formatted.push(web3._extend.formatters.outputTransactionFormatter(txs[i])); + formatted[i].blockHash = null; + } + return formatted; + } + }), + ] +}); +` + +const MinerJs = ` +web3._extend({ + property: 'miner', + methods: [ + new web3._extend.Method({ + name: 'start', + call: 'miner_start', + params: 1, + inputFormatter: [null] + }), + new web3._extend.Method({ + name: 'stop', + call: 'miner_stop' + }), + new web3._extend.Method({ + name: 'setEtherbase', + call: 'miner_setEtherbase', + params: 1, + inputFormatter: [web3._extend.formatters.inputAddressFormatter] + }), + new web3._extend.Method({ + name: 'setExtra', + call: 'miner_setExtra', + params: 1 + }), + new web3._extend.Method({ + name: 'setGasPrice', + call: 'miner_setGasPrice', + params: 1, + inputFormatter: [web3._extend.utils.fromDecimal] + }), + new web3._extend.Method({ + name: 'setRecommitInterval', + call: 'miner_setRecommitInterval', + params: 1, + }), + new web3._extend.Method({ + name: 'getHashrate', + call: 'miner_getHashrate' + }), + ], + properties: [] +}); +` + +const NetJs = ` +web3._extend({ + property: 'net', + methods: [], + properties: [ + new web3._extend.Property({ + name: 'version', + getter: 'net_version' + }), + ] +}); +` + +const PersonalJs = ` +web3._extend({ + property: 'personal', + methods: [ + new web3._extend.Method({ + name: 'importRawKey', + call: 'personal_importRawKey', + params: 2 + }), + new web3._extend.Method({ + name: 'sign', + call: 'personal_sign', + params: 3, + inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null] + }), + new web3._extend.Method({ + name: 'ecRecover', + call: 'personal_ecRecover', + params: 2 + }), + new web3._extend.Method({ + name: 'openWallet', + call: 'personal_openWallet', + params: 2 + }), + new web3._extend.Method({ + name: 'deriveAccount', + call: 'personal_deriveAccount', + params: 3 + }), + new web3._extend.Method({ + name: 'signTransaction', + call: 'personal_signTransaction', + params: 2, + inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null] + }), + new web3._extend.Method({ + name: 'unpair', + call: 'personal_unpair', + params: 2 + }), + new web3._extend.Method({ + name: 'initializeWallet', + call: 'personal_initializeWallet', + params: 1 + }) + ], + properties: [ + new web3._extend.Property({ + name: 'listWallets', + getter: 'personal_listWallets' + }), + ] +}) +` + +const RpcJs = ` +web3._extend({ + property: 'rpc', + methods: [], + properties: [ + new web3._extend.Property({ + name: 'modules', + getter: 'rpc_modules' + }), + ] +}); +` + +const ShhJs = ` +web3._extend({ + property: 'shh', + methods: [ + ], + properties: + [ + new web3._extend.Property({ + name: 'version', + getter: 'shh_version', + outputFormatter: web3._extend.utils.toDecimal + }), + new web3._extend.Property({ + name: 'info', + getter: 'shh_info' + }), + ] +}); +` + +const SwarmfsJs = ` +web3._extend({ + property: 'swarmfs', + methods: + [ + new web3._extend.Method({ + name: 'mount', + call: 'swarmfs_mount', + params: 2 + }), + new web3._extend.Method({ + name: 'unmount', + call: 'swarmfs_unmount', + params: 1 + }), + new web3._extend.Method({ + name: 'listmounts', + call: 'swarmfs_listmounts', + params: 0 + }), + ] +}); +` + +const TxpoolJs = ` +web3._extend({ + property: 'txpool', + methods: [], + properties: + [ + new web3._extend.Property({ + name: 'content', + getter: 'txpool_content' + }), + new web3._extend.Property({ + name: 'inspect', + getter: 'txpool_inspect' + }), + new web3._extend.Property({ + name: 'status', + getter: 'txpool_status', + outputFormatter: function(status) { + status.pending = web3._extend.utils.toDecimal(status.pending); + status.queued = web3._extend.utils.toDecimal(status.queued); + return status; + } + }), + ] +}); +` + +const AccountingJs = ` +web3._extend({ + property: 'accounting', + methods: [ + new web3._extend.Property({ + name: 'balance', + getter: 'account_balance' + }), + new web3._extend.Property({ + name: 'balanceCredit', + getter: 'account_balanceCredit' + }), + new web3._extend.Property({ + name: 'balanceDebit', + getter: 'account_balanceDebit' + }), + new web3._extend.Property({ + name: 'bytesCredit', + getter: 'account_bytesCredit' + }), + new web3._extend.Property({ + name: 'bytesDebit', + getter: 'account_bytesDebit' + }), + new web3._extend.Property({ + name: 'msgCredit', + getter: 'account_msgCredit' + }), + new web3._extend.Property({ + name: 'msgDebit', + getter: 'account_msgDebit' + }), + new web3._extend.Property({ + name: 'peerDrops', + getter: 'account_peerDrops' + }), + new web3._extend.Property({ + name: 'selfDrops', + getter: 'account_selfDrops' + }), + ] +}); +` diff --git a/vendor/github.com/ethereum/go-ethereum/les/api.go b/vendor/github.com/ethereum/go-ethereum/les/api.go new file mode 100644 index 00000000..3a8d49ca --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/api.go @@ -0,0 +1,472 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/les/csvlogger" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rpc" +) + +var ( + ErrMinCap = errors.New("capacity too small") + ErrTotalCap = errors.New("total capacity exceeded") + ErrUnknownBenchmarkType = errors.New("unknown benchmark type") + + dropCapacityDelay = time.Second // delay applied to decreasing capacity changes +) + +// PrivateLightServerAPI provides an API to access the LES light server. +// It offers only methods that operate on public data that is freely available to anyone. +type PrivateLightServerAPI struct { + server *LesServer +} + +// NewPrivateLightServerAPI creates a new LES light server API. +func NewPrivateLightServerAPI(server *LesServer) *PrivateLightServerAPI { + return &PrivateLightServerAPI{ + server: server, + } +} + +// TotalCapacity queries total available capacity for all clients +func (api *PrivateLightServerAPI) TotalCapacity() hexutil.Uint64 { + return hexutil.Uint64(api.server.priorityClientPool.totalCapacity()) +} + +// SubscribeTotalCapacity subscribes to changed total capacity events. +// If onlyUnderrun is true then notification is sent only if the total capacity +// drops under the total capacity of connected priority clients. +// +// Note: actually applying decreasing total capacity values is delayed while the +// notification is sent instantly. This allows lowering the capacity of a priority client +// or choosing which one to drop before the system drops some of them automatically. +func (api *PrivateLightServerAPI) SubscribeTotalCapacity(ctx context.Context, onlyUnderrun bool) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + rpcSub := notifier.CreateSubscription() + api.server.priorityClientPool.subscribeTotalCapacity(&tcSubscription{notifier, rpcSub, onlyUnderrun}) + return rpcSub, nil +} + +type ( + // tcSubscription represents a total capacity subscription + tcSubscription struct { + notifier *rpc.Notifier + rpcSub *rpc.Subscription + onlyUnderrun bool + } + tcSubs map[*tcSubscription]struct{} +) + +// send sends a changed total capacity event to the subscribers +func (s tcSubs) send(tc uint64, underrun bool) { + for sub := range s { + select { + case <-sub.rpcSub.Err(): + delete(s, sub) + case <-sub.notifier.Closed(): + delete(s, sub) + default: + if underrun || !sub.onlyUnderrun { + sub.notifier.Notify(sub.rpcSub.ID, tc) + } + } + } +} + +// MinimumCapacity queries minimum assignable capacity for a single client +func (api *PrivateLightServerAPI) MinimumCapacity() hexutil.Uint64 { + return hexutil.Uint64(api.server.minCapacity) +} + +// FreeClientCapacity queries the capacity provided for free clients +func (api *PrivateLightServerAPI) FreeClientCapacity() hexutil.Uint64 { + return hexutil.Uint64(api.server.freeClientCap) +} + +// SetClientCapacity sets the priority capacity assigned to a given client. +// If the assigned capacity is bigger than zero then connection is always +// guaranteed. The sum of capacity assigned to priority clients can not exceed +// the total available capacity. +// +// Note: assigned capacity can be changed while the client is connected with +// immediate effect. +func (api *PrivateLightServerAPI) SetClientCapacity(id enode.ID, cap uint64) error { + if cap != 0 && cap < api.server.minCapacity { + return ErrMinCap + } + return api.server.priorityClientPool.setClientCapacity(id, cap) +} + +// GetClientCapacity returns the capacity assigned to a given client +func (api *PrivateLightServerAPI) GetClientCapacity(id enode.ID) hexutil.Uint64 { + api.server.priorityClientPool.lock.Lock() + defer api.server.priorityClientPool.lock.Unlock() + + return hexutil.Uint64(api.server.priorityClientPool.clients[id].cap) +} + +// clientPool is implemented by both the free and priority client pools +type clientPool interface { + peerSetNotify + setLimits(count int, totalCap uint64) +} + +// priorityClientPool stores information about prioritized clients +type priorityClientPool struct { + lock sync.Mutex + child clientPool + ps *peerSet + clients map[enode.ID]priorityClientInfo + totalCap, totalCapAnnounced uint64 + totalConnectedCap, freeClientCap uint64 + maxPeers, priorityCount int + logger *csvlogger.Logger + logTotalPriConn *csvlogger.Channel + + subs tcSubs + updateSchedule []scheduledUpdate + scheduleCounter uint64 +} + +// scheduledUpdate represents a delayed total capacity update +type scheduledUpdate struct { + time mclock.AbsTime + totalCap, id uint64 +} + +// priorityClientInfo entries exist for all prioritized clients and currently connected non-priority clients +type priorityClientInfo struct { + cap uint64 // zero for non-priority clients + connected bool + peer *peer +} + +// newPriorityClientPool creates a new priority client pool +func newPriorityClientPool(freeClientCap uint64, ps *peerSet, child clientPool, metricsLogger, eventLogger *csvlogger.Logger) *priorityClientPool { + return &priorityClientPool{ + clients: make(map[enode.ID]priorityClientInfo), + freeClientCap: freeClientCap, + ps: ps, + child: child, + logger: eventLogger, + logTotalPriConn: metricsLogger.NewChannel("totalPriConn", 0), + } +} + +// registerPeer is called when a new client is connected. If the client has no +// priority assigned then it is passed to the child pool which may either keep it +// or disconnect it. +// +// Note: priorityClientPool also stores a record about free clients while they are +// connected in order to be able to assign priority to them later. +func (v *priorityClientPool) registerPeer(p *peer) { + v.lock.Lock() + defer v.lock.Unlock() + + id := p.ID() + c := v.clients[id] + v.logger.Event(fmt.Sprintf("priorityClientPool: registerPeer cap=%d connected=%v, %x", c.cap, c.connected, id.Bytes())) + if c.connected { + return + } + if c.cap == 0 && v.child != nil { + v.child.registerPeer(p) + } + if c.cap != 0 && v.totalConnectedCap+c.cap > v.totalCap { + v.logger.Event(fmt.Sprintf("priorityClientPool: rejected, %x", id.Bytes())) + go v.ps.Unregister(p.id) + return + } + + c.connected = true + c.peer = p + v.clients[id] = c + if c.cap != 0 { + v.priorityCount++ + v.totalConnectedCap += c.cap + v.logger.Event(fmt.Sprintf("priorityClientPool: accepted with %d capacity, %x", c.cap, id.Bytes())) + v.logTotalPriConn.Update(float64(v.totalConnectedCap)) + if v.child != nil { + v.child.setLimits(v.maxPeers-v.priorityCount, v.totalCap-v.totalConnectedCap) + } + p.updateCapacity(c.cap) + } +} + +// unregisterPeer is called when a client is disconnected. If the client has no +// priority assigned then it is also removed from the child pool. +func (v *priorityClientPool) unregisterPeer(p *peer) { + v.lock.Lock() + defer v.lock.Unlock() + + id := p.ID() + c := v.clients[id] + v.logger.Event(fmt.Sprintf("priorityClientPool: unregisterPeer cap=%d connected=%v, %x", c.cap, c.connected, id.Bytes())) + if !c.connected { + return + } + if c.cap != 0 { + c.connected = false + v.clients[id] = c + v.priorityCount-- + v.totalConnectedCap -= c.cap + v.logTotalPriConn.Update(float64(v.totalConnectedCap)) + if v.child != nil { + v.child.setLimits(v.maxPeers-v.priorityCount, v.totalCap-v.totalConnectedCap) + } + } else { + if v.child != nil { + v.child.unregisterPeer(p) + } + delete(v.clients, id) + } +} + +// setLimits updates the allowed peer count and total capacity of the priority +// client pool. Since the free client pool is a child of the priority pool the +// remaining peer count and capacity is assigned to the free pool by calling its +// own setLimits function. +// +// Note: a decreasing change of the total capacity is applied with a delay. +func (v *priorityClientPool) setLimits(count int, totalCap uint64) { + v.lock.Lock() + defer v.lock.Unlock() + + v.totalCapAnnounced = totalCap + if totalCap > v.totalCap { + v.setLimitsNow(count, totalCap) + v.subs.send(totalCap, false) + return + } + v.setLimitsNow(count, v.totalCap) + if totalCap < v.totalCap { + v.subs.send(totalCap, totalCap < v.totalConnectedCap) + for i, s := range v.updateSchedule { + if totalCap >= s.totalCap { + s.totalCap = totalCap + v.updateSchedule = v.updateSchedule[:i+1] + return + } + } + v.updateSchedule = append(v.updateSchedule, scheduledUpdate{time: mclock.Now() + mclock.AbsTime(dropCapacityDelay), totalCap: totalCap}) + if len(v.updateSchedule) == 1 { + v.scheduleCounter++ + id := v.scheduleCounter + v.updateSchedule[0].id = id + time.AfterFunc(dropCapacityDelay, func() { v.checkUpdate(id) }) + } + } else { + v.updateSchedule = nil + } +} + +// checkUpdate performs the next scheduled update if possible and schedules +// the one after that +func (v *priorityClientPool) checkUpdate(id uint64) { + v.lock.Lock() + defer v.lock.Unlock() + + if len(v.updateSchedule) == 0 || v.updateSchedule[0].id != id { + return + } + v.setLimitsNow(v.maxPeers, v.updateSchedule[0].totalCap) + v.updateSchedule = v.updateSchedule[1:] + if len(v.updateSchedule) != 0 { + v.scheduleCounter++ + id := v.scheduleCounter + v.updateSchedule[0].id = id + dt := time.Duration(v.updateSchedule[0].time - mclock.Now()) + time.AfterFunc(dt, func() { v.checkUpdate(id) }) + } +} + +// setLimits updates the allowed peer count and total capacity immediately +func (v *priorityClientPool) setLimitsNow(count int, totalCap uint64) { + if v.priorityCount > count || v.totalConnectedCap > totalCap { + for id, c := range v.clients { + if c.connected { + v.logger.Event(fmt.Sprintf("priorityClientPool: setLimitsNow kicked out, %x", id.Bytes())) + c.connected = false + v.totalConnectedCap -= c.cap + v.logTotalPriConn.Update(float64(v.totalConnectedCap)) + v.priorityCount-- + v.clients[id] = c + go v.ps.Unregister(c.peer.id) + if v.priorityCount <= count && v.totalConnectedCap <= totalCap { + break + } + } + } + } + v.maxPeers = count + v.totalCap = totalCap + if v.child != nil { + v.child.setLimits(v.maxPeers-v.priorityCount, v.totalCap-v.totalConnectedCap) + } +} + +// totalCapacity queries total available capacity for all clients +func (v *priorityClientPool) totalCapacity() uint64 { + v.lock.Lock() + defer v.lock.Unlock() + + return v.totalCapAnnounced +} + +// subscribeTotalCapacity subscribes to changed total capacity events +func (v *priorityClientPool) subscribeTotalCapacity(sub *tcSubscription) { + v.lock.Lock() + defer v.lock.Unlock() + + v.subs[sub] = struct{}{} +} + +// setClientCapacity sets the priority capacity assigned to a given client +func (v *priorityClientPool) setClientCapacity(id enode.ID, cap uint64) error { + v.lock.Lock() + defer v.lock.Unlock() + + c := v.clients[id] + if c.cap == cap { + return nil + } + if c.connected { + if v.totalConnectedCap+cap > v.totalCap+c.cap { + return ErrTotalCap + } + if c.cap == 0 { + if v.child != nil { + v.child.unregisterPeer(c.peer) + } + v.priorityCount++ + } + if cap == 0 { + v.priorityCount-- + } + v.totalConnectedCap += cap - c.cap + v.logTotalPriConn.Update(float64(v.totalConnectedCap)) + if v.child != nil { + v.child.setLimits(v.maxPeers-v.priorityCount, v.totalCap-v.totalConnectedCap) + } + if cap == 0 { + if v.child != nil { + v.child.registerPeer(c.peer) + } + c.peer.updateCapacity(v.freeClientCap) + } else { + c.peer.updateCapacity(cap) + } + } + if cap != 0 || c.connected { + c.cap = cap + v.clients[id] = c + } else { + delete(v.clients, id) + } + if c.connected { + v.logger.Event(fmt.Sprintf("priorityClientPool: changed capacity to %d, %x", cap, id.Bytes())) + } + return nil +} + +// Benchmark runs a request performance benchmark with a given set of measurement setups +// in multiple passes specified by passCount. The measurement time for each setup in each +// pass is specified in milliseconds by length. +// +// Note: measurement time is adjusted for each pass depending on the previous ones. +// Therefore a controlled total measurement time is achievable in multiple passes. +func (api *PrivateLightServerAPI) Benchmark(setups []map[string]interface{}, passCount, length int) ([]map[string]interface{}, error) { + benchmarks := make([]requestBenchmark, len(setups)) + for i, setup := range setups { + if t, ok := setup["type"].(string); ok { + getInt := func(field string, def int) int { + if value, ok := setup[field].(float64); ok { + return int(value) + } + return def + } + getBool := func(field string, def bool) bool { + if value, ok := setup[field].(bool); ok { + return value + } + return def + } + switch t { + case "header": + benchmarks[i] = &benchmarkBlockHeaders{ + amount: getInt("amount", 1), + skip: getInt("skip", 1), + byHash: getBool("byHash", false), + reverse: getBool("reverse", false), + } + case "body": + benchmarks[i] = &benchmarkBodiesOrReceipts{receipts: false} + case "receipts": + benchmarks[i] = &benchmarkBodiesOrReceipts{receipts: true} + case "proof": + benchmarks[i] = &benchmarkProofsOrCode{code: false} + case "code": + benchmarks[i] = &benchmarkProofsOrCode{code: true} + case "cht": + benchmarks[i] = &benchmarkHelperTrie{ + bloom: false, + reqCount: getInt("amount", 1), + } + case "bloom": + benchmarks[i] = &benchmarkHelperTrie{ + bloom: true, + reqCount: getInt("amount", 1), + } + case "txSend": + benchmarks[i] = &benchmarkTxSend{} + case "txStatus": + benchmarks[i] = &benchmarkTxStatus{} + default: + return nil, ErrUnknownBenchmarkType + } + } else { + return nil, ErrUnknownBenchmarkType + } + } + rs := api.server.protocolManager.runBenchmark(benchmarks, passCount, time.Millisecond*time.Duration(length)) + result := make([]map[string]interface{}, len(setups)) + for i, r := range rs { + res := make(map[string]interface{}) + if r.err == nil { + res["totalCount"] = r.totalCount + res["avgTime"] = r.avgTime + res["maxInSize"] = r.maxInSize + res["maxOutSize"] = r.maxOutSize + } else { + res["error"] = r.err.Error() + } + result[i] = res + } + return result, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/api_backend.go b/vendor/github.com/ethereum/go-ethereum/les/api_backend.go new file mode 100644 index 00000000..6de15e7b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/api_backend.go @@ -0,0 +1,219 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +type LesApiBackend struct { + extRPCEnabled bool + eth *LightEthereum + gpo *gasprice.Oracle +} + +func (b *LesApiBackend) ChainConfig() *params.ChainConfig { + return b.eth.chainConfig +} + +func (b *LesApiBackend) CurrentBlock() *types.Block { + return types.NewBlockWithHeader(b.eth.BlockChain().CurrentHeader()) +} + +func (b *LesApiBackend) SetHead(number uint64) { + b.eth.protocolManager.downloader.Cancel() + b.eth.blockchain.SetHead(number) +} + +func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { + if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber { + return b.eth.blockchain.CurrentHeader(), nil + } + return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr)) +} + +func (b *LesApiBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return b.eth.blockchain.GetHeaderByHash(hash), nil +} + +func (b *LesApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { + header, err := b.HeaderByNumber(ctx, blockNr) + if header == nil || err != nil { + return nil, err + } + return b.GetBlock(ctx, header.Hash()) +} + +func (b *LesApiBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { + header, err := b.HeaderByNumber(ctx, blockNr) + if err != nil { + return nil, nil, err + } + if header == nil { + return nil, nil, errors.New("header not found") + } + return light.NewState(ctx, header, b.eth.odr), header, nil +} + +func (b *LesApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) { + return b.eth.blockchain.GetBlockByHash(ctx, blockHash) +} + +func (b *LesApiBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { + if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil { + return light.GetBlockReceipts(ctx, b.eth.odr, hash, *number) + } + return nil, nil +} + +func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { + if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil { + return light.GetBlockLogs(ctx, b.eth.odr, hash, *number) + } + return nil, nil +} + +func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int { + return b.eth.blockchain.GetTdByHash(hash) +} + +func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) { + state.SetBalance(msg.From(), math.MaxBig256) + context := core.NewEVMContext(msg, header, b.eth.blockchain, nil) + return vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{}), state.Error, nil +} + +func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + return b.eth.txPool.Add(ctx, signedTx) +} + +func (b *LesApiBackend) RemoveTx(txHash common.Hash) { + b.eth.txPool.RemoveTx(txHash) +} + +func (b *LesApiBackend) GetPoolTransactions() (types.Transactions, error) { + return b.eth.txPool.GetTransactions() +} + +func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { + return b.eth.txPool.GetTransaction(txHash) +} + +func (b *LesApiBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) { + return light.GetTransaction(ctx, b.eth.odr, txHash) +} + +func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { + return b.eth.txPool.GetNonce(ctx, addr) +} + +func (b *LesApiBackend) Stats() (pending int, queued int) { + return b.eth.txPool.Stats(), 0 +} + +func (b *LesApiBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { + return b.eth.txPool.Content() +} + +func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { + return b.eth.txPool.SubscribeNewTxsEvent(ch) +} + +func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + return b.eth.blockchain.SubscribeChainEvent(ch) +} + +func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { + return b.eth.blockchain.SubscribeChainHeadEvent(ch) +} + +func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { + return b.eth.blockchain.SubscribeChainSideEvent(ch) +} + +func (b *LesApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + return b.eth.blockchain.SubscribeLogsEvent(ch) +} + +func (b *LesApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { + return b.eth.blockchain.SubscribeRemovedLogsEvent(ch) +} + +func (b *LesApiBackend) Downloader() *downloader.Downloader { + return b.eth.Downloader() +} + +func (b *LesApiBackend) ProtocolVersion() int { + return b.eth.LesVersion() + 10000 +} + +func (b *LesApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { + return b.gpo.SuggestPrice(ctx) +} + +func (b *LesApiBackend) ChainDb() ethdb.Database { + return b.eth.chainDb +} + +func (b *LesApiBackend) EventMux() *event.TypeMux { + return b.eth.eventMux +} + +func (b *LesApiBackend) AccountManager() *accounts.Manager { + return b.eth.accountManager +} + +func (b *LesApiBackend) ExtRPCEnabled() bool { + return b.extRPCEnabled +} + +func (b *LesApiBackend) RPCGasCap() *big.Int { + return b.eth.config.RPCGasCap +} + +func (b *LesApiBackend) BloomStatus() (uint64, uint64) { + if b.eth.bloomIndexer == nil { + return 0, 0 + } + sections, _, _ := b.eth.bloomIndexer.Sections() + return params.BloomBitsBlocksClient, sections +} + +func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { + for i := 0; i < bloomFilterThreads; i++ { + go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/backend.go b/vendor/github.com/ethereum/go-ethereum/les/backend.go new file mode 100644 index 00000000..ed0f4505 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/backend.go @@ -0,0 +1,290 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package les implements the Light Ethereum Subprotocol. +package les + +import ( + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/params" + rpc "github.com/ethereum/go-ethereum/rpc" +) + +type LightEthereum struct { + lesCommons + + odr *LesOdr + relay *LesTxRelay + chainConfig *params.ChainConfig + // Channel for shutting down the service + shutdownChan chan bool + + // Handlers + peers *peerSet + txPool *light.TxPool + blockchain *light.LightChain + serverPool *serverPool + reqDist *requestDistributor + retriever *retrieveManager + + bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests + bloomIndexer *core.ChainIndexer + + ApiBackend *LesApiBackend + + eventMux *event.TypeMux + engine consensus.Engine + accountManager *accounts.Manager + + networkId uint64 + netRPCService *ethapi.PublicNetAPI + + wg sync.WaitGroup +} + +func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { + chainDb, err := ctx.OpenDatabase("lightchaindata", config.DatabaseCache, config.DatabaseHandles, "eth/db/chaindata/") + if err != nil { + return nil, err + } + chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.ConstantinopleOverride) + if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { + return nil, genesisErr + } + log.Info("Initialised chain configuration", "config", chainConfig) + + peers := newPeerSet() + quitSync := make(chan struct{}) + + leth := &LightEthereum{ + lesCommons: lesCommons{ + chainDb: chainDb, + config: config, + iConfig: light.DefaultClientIndexerConfig, + }, + chainConfig: chainConfig, + eventMux: ctx.EventMux, + peers: peers, + reqDist: newRequestDistributor(peers, quitSync, &mclock.System{}), + accountManager: ctx.AccountManager, + engine: eth.CreateConsensusEngine(ctx, chainConfig, &config.Ethash, nil, false, chainDb), + shutdownChan: make(chan bool), + networkId: config.NetworkId, + bloomRequests: make(chan chan *bloombits.Retrieval), + bloomIndexer: eth.NewBloomIndexer(chainDb, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), + } + + var trustedNodes []string + if leth.config.ULC != nil { + trustedNodes = leth.config.ULC.TrustedServers + } + leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg, trustedNodes) + leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool) + leth.relay = NewLesTxRelay(peers, leth.retriever) + + leth.odr = NewLesOdr(chainDb, light.DefaultClientIndexerConfig, leth.retriever) + leth.chtIndexer = light.NewChtIndexer(chainDb, leth.odr, params.CHTFrequency, params.HelperTrieConfirmations) + leth.bloomTrieIndexer = light.NewBloomTrieIndexer(chainDb, leth.odr, params.BloomBitsBlocksClient, params.BloomTrieFrequency) + leth.odr.SetIndexers(leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer) + + // Note: NewLightChain adds the trusted checkpoint so it needs an ODR with + // indexers already set but not started yet + if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil { + return nil, err + } + // Note: AddChildIndexer starts the update process for the child + leth.bloomIndexer.AddChildIndexer(leth.bloomTrieIndexer) + leth.chtIndexer.Start(leth.blockchain) + leth.bloomIndexer.Start(leth.blockchain) + + // Rewind the chain in case of an incompatible config upgrade. + if compat, ok := genesisErr.(*params.ConfigCompatError); ok { + log.Warn("Rewinding chain to upgrade configuration", "err", compat) + leth.blockchain.SetHead(compat.RewindTo) + rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) + } + + leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay) + + if leth.protocolManager, err = NewProtocolManager( + leth.chainConfig, + light.DefaultClientIndexerConfig, + true, + config.NetworkId, + leth.eventMux, + leth.engine, + leth.peers, + leth.blockchain, + nil, + chainDb, + leth.odr, + leth.relay, + leth.serverPool, + quitSync, + &leth.wg, + config.ULC, + nil); err != nil { + return nil, err + } + + if leth.protocolManager.isULCEnabled() { + log.Warn("Ultra light client is enabled", "trustedNodes", len(leth.protocolManager.ulc.trustedKeys), "minTrustedFraction", leth.protocolManager.ulc.minTrustedFraction) + leth.blockchain.DisableCheckFreq() + } + leth.ApiBackend = &LesApiBackend{ctx.ExtRPCEnabled(), leth, nil} + + gpoParams := config.GPO + if gpoParams.Default == nil { + gpoParams.Default = config.Miner.GasPrice + } + leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams) + return leth, nil +} + +func lesTopic(genesisHash common.Hash, protocolVersion uint) discv5.Topic { + var name string + switch protocolVersion { + case lpv2: + name = "LES2" + default: + panic(nil) + } + return discv5.Topic(name + "@" + common.Bytes2Hex(genesisHash.Bytes()[0:8])) +} + +type LightDummyAPI struct{} + +// Etherbase is the address that mining rewards will be send to +func (s *LightDummyAPI) Etherbase() (common.Address, error) { + return common.Address{}, fmt.Errorf("mining is not supported in light mode") +} + +// Coinbase is the address that mining rewards will be send to (alias for Etherbase) +func (s *LightDummyAPI) Coinbase() (common.Address, error) { + return common.Address{}, fmt.Errorf("mining is not supported in light mode") +} + +// Hashrate returns the POW hashrate +func (s *LightDummyAPI) Hashrate() hexutil.Uint { + return 0 +} + +// Mining returns an indication if this node is currently mining. +func (s *LightDummyAPI) Mining() bool { + return false +} + +// APIs returns the collection of RPC services the ethereum package offers. +// NOTE, some of these services probably need to be moved to somewhere else. +func (s *LightEthereum) APIs() []rpc.API { + return append(ethapi.GetAPIs(s.ApiBackend), []rpc.API{ + { + Namespace: "eth", + Version: "1.0", + Service: &LightDummyAPI{}, + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: filters.NewPublicFilterAPI(s.ApiBackend, true), + Public: true, + }, { + Namespace: "net", + Version: "1.0", + Service: s.netRPCService, + Public: true, + }, + }...) +} + +func (s *LightEthereum) ResetWithGenesisBlock(gb *types.Block) { + s.blockchain.ResetWithGenesisBlock(gb) +} + +func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchain } +func (s *LightEthereum) TxPool() *light.TxPool { return s.txPool } +func (s *LightEthereum) Engine() consensus.Engine { return s.engine } +func (s *LightEthereum) LesVersion() int { return int(ClientProtocolVersions[0]) } +func (s *LightEthereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } +func (s *LightEthereum) EventMux() *event.TypeMux { return s.eventMux } + +// Protocols implements node.Service, returning all the currently configured +// network protocols to start. +func (s *LightEthereum) Protocols() []p2p.Protocol { + return s.makeProtocols(ClientProtocolVersions) +} + +// Start implements node.Service, starting all internal goroutines needed by the +// Ethereum protocol implementation. +func (s *LightEthereum) Start(srvr *p2p.Server) error { + log.Warn("Light client mode is an experimental feature") + s.startBloomHandlers(params.BloomBitsBlocksClient) + s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) + // clients are searching for the first advertised protocol in the list + protocolVersion := AdvertiseProtocolVersions[0] + s.serverPool.start(srvr, lesTopic(s.blockchain.Genesis().Hash(), protocolVersion)) + s.protocolManager.Start(s.config.LightPeers) + return nil +} + +// Stop implements node.Service, terminating all internal goroutines used by the +// Ethereum protocol. +func (s *LightEthereum) Stop() error { + s.odr.Stop() + s.relay.Stop() + s.bloomIndexer.Close() + s.chtIndexer.Close() + s.blockchain.Stop() + s.protocolManager.Stop() + s.txPool.Stop() + s.engine.Close() + + s.eventMux.Stop() + + time.Sleep(time.Millisecond * 200) + s.chainDb.Close() + close(s.shutdownChan) + + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/benchmark.go b/vendor/github.com/ethereum/go-ethereum/les/benchmark.go new file mode 100644 index 00000000..925d1d89 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/benchmark.go @@ -0,0 +1,352 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "encoding/binary" + "fmt" + "math/big" + "math/rand" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/les/flowcontrol" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// requestBenchmark is an interface for different randomized request generators +type requestBenchmark interface { + // init initializes the generator for generating the given number of randomized requests + init(pm *ProtocolManager, count int) error + // request initiates sending a single request to the given peer + request(peer *peer, index int) error +} + +// benchmarkBlockHeaders implements requestBenchmark +type benchmarkBlockHeaders struct { + amount, skip int + reverse, byHash bool + offset, randMax int64 + hashes []common.Hash +} + +func (b *benchmarkBlockHeaders) init(pm *ProtocolManager, count int) error { + d := int64(b.amount-1) * int64(b.skip+1) + b.offset = 0 + b.randMax = pm.blockchain.CurrentHeader().Number.Int64() + 1 - d + if b.randMax < 0 { + return fmt.Errorf("chain is too short") + } + if b.reverse { + b.offset = d + } + if b.byHash { + b.hashes = make([]common.Hash, count) + for i := range b.hashes { + b.hashes[i] = rawdb.ReadCanonicalHash(pm.chainDb, uint64(b.offset+rand.Int63n(b.randMax))) + } + } + return nil +} + +func (b *benchmarkBlockHeaders) request(peer *peer, index int) error { + if b.byHash { + return peer.RequestHeadersByHash(0, 0, b.hashes[index], b.amount, b.skip, b.reverse) + } else { + return peer.RequestHeadersByNumber(0, 0, uint64(b.offset+rand.Int63n(b.randMax)), b.amount, b.skip, b.reverse) + } +} + +// benchmarkBodiesOrReceipts implements requestBenchmark +type benchmarkBodiesOrReceipts struct { + receipts bool + hashes []common.Hash +} + +func (b *benchmarkBodiesOrReceipts) init(pm *ProtocolManager, count int) error { + randMax := pm.blockchain.CurrentHeader().Number.Int64() + 1 + b.hashes = make([]common.Hash, count) + for i := range b.hashes { + b.hashes[i] = rawdb.ReadCanonicalHash(pm.chainDb, uint64(rand.Int63n(randMax))) + } + return nil +} + +func (b *benchmarkBodiesOrReceipts) request(peer *peer, index int) error { + if b.receipts { + return peer.RequestReceipts(0, 0, []common.Hash{b.hashes[index]}) + } else { + return peer.RequestBodies(0, 0, []common.Hash{b.hashes[index]}) + } +} + +// benchmarkProofsOrCode implements requestBenchmark +type benchmarkProofsOrCode struct { + code bool + headHash common.Hash +} + +func (b *benchmarkProofsOrCode) init(pm *ProtocolManager, count int) error { + b.headHash = pm.blockchain.CurrentHeader().Hash() + return nil +} + +func (b *benchmarkProofsOrCode) request(peer *peer, index int) error { + key := make([]byte, 32) + rand.Read(key) + if b.code { + return peer.RequestCode(0, 0, []CodeReq{{BHash: b.headHash, AccKey: key}}) + } else { + return peer.RequestProofs(0, 0, []ProofReq{{BHash: b.headHash, Key: key}}) + } +} + +// benchmarkHelperTrie implements requestBenchmark +type benchmarkHelperTrie struct { + bloom bool + reqCount int + sectionCount, headNum uint64 +} + +func (b *benchmarkHelperTrie) init(pm *ProtocolManager, count int) error { + if b.bloom { + b.sectionCount, b.headNum, _ = pm.server.bloomTrieIndexer.Sections() + } else { + b.sectionCount, _, _ = pm.server.chtIndexer.Sections() + b.headNum = b.sectionCount*params.CHTFrequency - 1 + } + if b.sectionCount == 0 { + return fmt.Errorf("no processed sections available") + } + return nil +} + +func (b *benchmarkHelperTrie) request(peer *peer, index int) error { + reqs := make([]HelperTrieReq, b.reqCount) + + if b.bloom { + bitIdx := uint16(rand.Intn(2048)) + for i := range reqs { + key := make([]byte, 10) + binary.BigEndian.PutUint16(key[:2], bitIdx) + binary.BigEndian.PutUint64(key[2:], uint64(rand.Int63n(int64(b.sectionCount)))) + reqs[i] = HelperTrieReq{Type: htBloomBits, TrieIdx: b.sectionCount - 1, Key: key} + } + } else { + for i := range reqs { + key := make([]byte, 8) + binary.BigEndian.PutUint64(key[:], uint64(rand.Int63n(int64(b.headNum)))) + reqs[i] = HelperTrieReq{Type: htCanonical, TrieIdx: b.sectionCount - 1, Key: key, AuxReq: auxHeader} + } + } + + return peer.RequestHelperTrieProofs(0, 0, reqs) +} + +// benchmarkTxSend implements requestBenchmark +type benchmarkTxSend struct { + txs types.Transactions +} + +func (b *benchmarkTxSend) init(pm *ProtocolManager, count int) error { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + signer := types.NewEIP155Signer(big.NewInt(18)) + b.txs = make(types.Transactions, count) + + for i := range b.txs { + data := make([]byte, txSizeCostLimit) + rand.Read(data) + tx, err := types.SignTx(types.NewTransaction(0, addr, new(big.Int), 0, new(big.Int), data), signer, key) + if err != nil { + panic(err) + } + b.txs[i] = tx + } + return nil +} + +func (b *benchmarkTxSend) request(peer *peer, index int) error { + enc, _ := rlp.EncodeToBytes(types.Transactions{b.txs[index]}) + return peer.SendTxs(0, 0, enc) +} + +// benchmarkTxStatus implements requestBenchmark +type benchmarkTxStatus struct{} + +func (b *benchmarkTxStatus) init(pm *ProtocolManager, count int) error { + return nil +} + +func (b *benchmarkTxStatus) request(peer *peer, index int) error { + var hash common.Hash + rand.Read(hash[:]) + return peer.RequestTxStatus(0, 0, []common.Hash{hash}) +} + +// benchmarkSetup stores measurement data for a single benchmark type +type benchmarkSetup struct { + req requestBenchmark + totalCount int + totalTime, avgTime time.Duration + maxInSize, maxOutSize uint32 + err error +} + +// runBenchmark runs a benchmark cycle for all benchmark types in the specified +// number of passes +func (pm *ProtocolManager) runBenchmark(benchmarks []requestBenchmark, passCount int, targetTime time.Duration) []*benchmarkSetup { + setup := make([]*benchmarkSetup, len(benchmarks)) + for i, b := range benchmarks { + setup[i] = &benchmarkSetup{req: b} + } + for i := 0; i < passCount; i++ { + log.Info("Running benchmark", "pass", i+1, "total", passCount) + todo := make([]*benchmarkSetup, len(benchmarks)) + copy(todo, setup) + for len(todo) > 0 { + // select a random element + index := rand.Intn(len(todo)) + next := todo[index] + todo[index] = todo[len(todo)-1] + todo = todo[:len(todo)-1] + + if next.err == nil { + // calculate request count + count := 50 + if next.totalTime > 0 { + count = int(uint64(next.totalCount) * uint64(targetTime) / uint64(next.totalTime)) + } + if err := pm.measure(next, count); err != nil { + next.err = err + } + } + } + } + log.Info("Benchmark completed") + + for _, s := range setup { + if s.err == nil { + s.avgTime = s.totalTime / time.Duration(s.totalCount) + } + } + return setup +} + +// meteredPipe implements p2p.MsgReadWriter and remembers the largest single +// message size sent through the pipe +type meteredPipe struct { + rw p2p.MsgReadWriter + maxSize uint32 +} + +func (m *meteredPipe) ReadMsg() (p2p.Msg, error) { + return m.rw.ReadMsg() +} + +func (m *meteredPipe) WriteMsg(msg p2p.Msg) error { + if msg.Size > m.maxSize { + m.maxSize = msg.Size + } + return m.rw.WriteMsg(msg) +} + +// measure runs a benchmark for a single type in a single pass, with the given +// number of requests +func (pm *ProtocolManager) measure(setup *benchmarkSetup, count int) error { + clientPipe, serverPipe := p2p.MsgPipe() + clientMeteredPipe := &meteredPipe{rw: clientPipe} + serverMeteredPipe := &meteredPipe{rw: serverPipe} + var id enode.ID + rand.Read(id[:]) + clientPeer := pm.newPeer(lpv2, NetworkId, p2p.NewPeer(id, "client", nil), clientMeteredPipe) + serverPeer := pm.newPeer(lpv2, NetworkId, p2p.NewPeer(id, "server", nil), serverMeteredPipe) + serverPeer.sendQueue = newExecQueue(count) + serverPeer.announceType = announceTypeNone + serverPeer.fcCosts = make(requestCostTable) + c := &requestCosts{} + for code := range requests { + serverPeer.fcCosts[code] = c + } + serverPeer.fcParams = flowcontrol.ServerParams{BufLimit: 1, MinRecharge: 1} + serverPeer.fcClient = flowcontrol.NewClientNode(pm.server.fcManager, serverPeer.fcParams) + defer serverPeer.fcClient.Disconnect() + + if err := setup.req.init(pm, count); err != nil { + return err + } + + errCh := make(chan error, 10) + start := mclock.Now() + + go func() { + for i := 0; i < count; i++ { + if err := setup.req.request(clientPeer, i); err != nil { + errCh <- err + return + } + } + }() + go func() { + for i := 0; i < count; i++ { + if err := pm.handleMsg(serverPeer); err != nil { + errCh <- err + return + } + } + }() + go func() { + for i := 0; i < count; i++ { + msg, err := clientPipe.ReadMsg() + if err != nil { + errCh <- err + return + } + var i interface{} + msg.Decode(&i) + } + // at this point we can be sure that the other two + // goroutines finished successfully too + close(errCh) + }() + select { + case err := <-errCh: + if err != nil { + return err + } + case <-pm.quitSync: + clientPipe.Close() + serverPipe.Close() + return fmt.Errorf("Benchmark cancelled") + } + + setup.totalTime += time.Duration(mclock.Now() - start) + setup.totalCount += count + setup.maxInSize = clientMeteredPipe.maxSize + setup.maxOutSize = serverMeteredPipe.maxSize + clientPipe.Close() + serverPipe.Close() + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/commons.go b/vendor/github.com/ethereum/go-ethereum/les/commons.go new file mode 100644 index 00000000..d4647997 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/commons.go @@ -0,0 +1,108 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" +) + +// lesCommons contains fields needed by both server and client. +type lesCommons struct { + config *eth.Config + iConfig *light.IndexerConfig + chainDb ethdb.Database + protocolManager *ProtocolManager + chtIndexer, bloomTrieIndexer *core.ChainIndexer +} + +// NodeInfo represents a short summary of the Ethereum sub-protocol metadata +// known about the host peer. +type NodeInfo struct { + Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4) + Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain + Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block + Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules + Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block + CHT params.TrustedCheckpoint `json:"cht"` // Trused CHT checkpoint for fast catchup +} + +// makeProtocols creates protocol descriptors for the given LES versions. +func (c *lesCommons) makeProtocols(versions []uint) []p2p.Protocol { + protos := make([]p2p.Protocol, len(versions)) + for i, version := range versions { + version := version + protos[i] = p2p.Protocol{ + Name: "les", + Version: version, + Length: ProtocolLengths[version], + NodeInfo: c.nodeInfo, + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + return c.protocolManager.runPeer(version, p, rw) + }, + PeerInfo: func(id enode.ID) interface{} { + if p := c.protocolManager.peers.Peer(fmt.Sprintf("%x", id.Bytes())); p != nil { + return p.Info() + } + return nil + }, + } + } + return protos +} + +// nodeInfo retrieves some protocol metadata about the running host node. +func (c *lesCommons) nodeInfo() interface{} { + var cht params.TrustedCheckpoint + sections, _, _ := c.chtIndexer.Sections() + sections2, _, _ := c.bloomTrieIndexer.Sections() + + if sections2 < sections { + sections = sections2 + } + if sections > 0 { + sectionIndex := sections - 1 + sectionHead := c.bloomTrieIndexer.SectionHead(sectionIndex) + cht = params.TrustedCheckpoint{ + SectionIndex: sectionIndex, + SectionHead: sectionHead, + CHTRoot: light.GetChtRoot(c.chainDb, sectionIndex, sectionHead), + BloomRoot: light.GetBloomTrieRoot(c.chainDb, sectionIndex, sectionHead), + } + } + + chain := c.protocolManager.blockchain + head := chain.CurrentHeader() + hash := head.Hash() + return &NodeInfo{ + Network: c.config.NetworkId, + Difficulty: chain.GetTd(hash, head.Number.Uint64()), + Genesis: chain.Genesis().Hash(), + Config: chain.Config(), + Head: chain.CurrentHeader().Hash(), + CHT: cht, + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/costtracker.go b/vendor/github.com/ethereum/go-ethereum/les/costtracker.go new file mode 100644 index 00000000..e463c9f8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/costtracker.go @@ -0,0 +1,453 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more detailct. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "encoding/binary" + "fmt" + "math" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/les/csvlogger" + "github.com/ethereum/go-ethereum/les/flowcontrol" + "github.com/ethereum/go-ethereum/log" +) + +const makeCostStats = false // make request cost statistics during operation + +var ( + // average request cost estimates based on serving time + reqAvgTimeCost = requestCostTable{ + GetBlockHeadersMsg: {150000, 30000}, + GetBlockBodiesMsg: {0, 700000}, + GetReceiptsMsg: {0, 1000000}, + GetCodeMsg: {0, 450000}, + GetProofsV2Msg: {0, 600000}, + GetHelperTrieProofsMsg: {0, 1000000}, + SendTxV2Msg: {0, 450000}, + GetTxStatusMsg: {0, 250000}, + } + // maximum incoming message size estimates + reqMaxInSize = requestCostTable{ + GetBlockHeadersMsg: {40, 0}, + GetBlockBodiesMsg: {0, 40}, + GetReceiptsMsg: {0, 40}, + GetCodeMsg: {0, 80}, + GetProofsV2Msg: {0, 80}, + GetHelperTrieProofsMsg: {0, 20}, + SendTxV2Msg: {0, 16500}, + GetTxStatusMsg: {0, 50}, + } + // maximum outgoing message size estimates + reqMaxOutSize = requestCostTable{ + GetBlockHeadersMsg: {0, 556}, + GetBlockBodiesMsg: {0, 100000}, + GetReceiptsMsg: {0, 200000}, + GetCodeMsg: {0, 50000}, + GetProofsV2Msg: {0, 4000}, + GetHelperTrieProofsMsg: {0, 4000}, + SendTxV2Msg: {0, 100}, + GetTxStatusMsg: {0, 100}, + } + // request amounts that have to fit into the minimum buffer size minBufferMultiplier times + minBufferReqAmount = map[uint64]uint64{ + GetBlockHeadersMsg: 192, + GetBlockBodiesMsg: 1, + GetReceiptsMsg: 1, + GetCodeMsg: 1, + GetProofsV2Msg: 1, + GetHelperTrieProofsMsg: 16, + SendTxV2Msg: 8, + GetTxStatusMsg: 64, + } + minBufferMultiplier = 3 +) + +const ( + maxCostFactor = 2 // ratio of maximum and average cost estimates + gfUsageThreshold = 0.5 + gfUsageTC = time.Second + gfRaiseTC = time.Second * 200 + gfDropTC = time.Second * 50 + gfDbKey = "_globalCostFactorV3" +) + +// costTracker is responsible for calculating costs and cost estimates on the +// server side. It continuously updates the global cost factor which is defined +// as the number of cost units per nanosecond of serving time in a single thread. +// It is based on statistics collected during serving requests in high-load periods +// and practically acts as a one-dimension request price scaling factor over the +// pre-defined cost estimate table. Instead of scaling the cost values, the real +// value of cost units is changed by applying the factor to the serving times. This +// is more convenient because the changes in the cost factor can be applied immediately +// without always notifying the clients about the changed cost tables. +type costTracker struct { + db ethdb.Database + stopCh chan chan struct{} + + inSizeFactor, outSizeFactor float64 + gf, utilTarget float64 + minBufLimit uint64 + + gfUpdateCh chan gfUpdate + gfLock sync.RWMutex + totalRechargeCh chan uint64 + + stats map[uint64][]uint64 + logger *csvlogger.Logger + logRecentTime, logRecentAvg, logTotalRecharge, logRelCost *csvlogger.Channel +} + +// newCostTracker creates a cost tracker and loads the cost factor statistics from the database. +// It also returns the minimum capacity that can be assigned to any peer. +func newCostTracker(db ethdb.Database, config *eth.Config, logger *csvlogger.Logger) (*costTracker, uint64) { + utilTarget := float64(config.LightServ) * flowcontrol.FixedPointMultiplier / 100 + ct := &costTracker{ + db: db, + stopCh: make(chan chan struct{}), + utilTarget: utilTarget, + logger: logger, + logRelCost: logger.NewMinMaxChannel("relativeCost", true), + logRecentTime: logger.NewMinMaxChannel("recentTime", true), + logRecentAvg: logger.NewMinMaxChannel("recentAvg", true), + logTotalRecharge: logger.NewChannel("totalRecharge", 0.01), + } + if config.LightBandwidthIn > 0 { + ct.inSizeFactor = utilTarget / float64(config.LightBandwidthIn) + } + if config.LightBandwidthOut > 0 { + ct.outSizeFactor = utilTarget / float64(config.LightBandwidthOut) + } + if makeCostStats { + ct.stats = make(map[uint64][]uint64) + for code := range reqAvgTimeCost { + ct.stats[code] = make([]uint64, 10) + } + } + ct.gfLoop() + costList := ct.makeCostList(ct.globalFactor() * 1.25) + for _, c := range costList { + amount := minBufferReqAmount[c.MsgCode] + cost := c.BaseCost + amount*c.ReqCost + if cost > ct.minBufLimit { + ct.minBufLimit = cost + } + } + ct.minBufLimit *= uint64(minBufferMultiplier) + return ct, (ct.minBufLimit-1)/bufLimitRatio + 1 +} + +// stop stops the cost tracker and saves the cost factor statistics to the database +func (ct *costTracker) stop() { + stopCh := make(chan struct{}) + ct.stopCh <- stopCh + <-stopCh + if makeCostStats { + ct.printStats() + } +} + +// makeCostList returns upper cost estimates based on the hardcoded cost estimate +// tables and the optionally specified incoming/outgoing bandwidth limits +func (ct *costTracker) makeCostList(globalFactor float64) RequestCostList { + maxCost := func(avgTimeCost, inSize, outSize uint64) uint64 { + cost := avgTimeCost * maxCostFactor + inSizeCost := uint64(float64(inSize) * ct.inSizeFactor * globalFactor) + if inSizeCost > cost { + cost = inSizeCost + } + outSizeCost := uint64(float64(outSize) * ct.outSizeFactor * globalFactor) + if outSizeCost > cost { + cost = outSizeCost + } + return cost + } + var list RequestCostList + for code, data := range reqAvgTimeCost { + baseCost := maxCost(data.baseCost, reqMaxInSize[code].baseCost, reqMaxOutSize[code].baseCost) + reqCost := maxCost(data.reqCost, reqMaxInSize[code].reqCost, reqMaxOutSize[code].reqCost) + if ct.minBufLimit != 0 { + // if minBufLimit is set then always enforce maximum request cost <= minBufLimit + maxCost := baseCost + reqCost*minBufferReqAmount[code] + if maxCost > ct.minBufLimit { + mul := 0.999 * float64(ct.minBufLimit) / float64(maxCost) + baseCost = uint64(float64(baseCost) * mul) + reqCost = uint64(float64(reqCost) * mul) + } + } + + list = append(list, requestCostListItem{ + MsgCode: code, + BaseCost: baseCost, + ReqCost: reqCost, + }) + } + return list +} + +type gfUpdate struct { + avgTimeCost, servingTime float64 +} + +// gfLoop starts an event loop which updates the global cost factor which is +// calculated as a weighted average of the average estimate / serving time ratio. +// The applied weight equals the serving time if gfUsage is over a threshold, +// zero otherwise. gfUsage is the recent average serving time per time unit in +// an exponential moving window. This ensures that statistics are collected only +// under high-load circumstances where the measured serving times are relevant. +// The total recharge parameter of the flow control system which controls the +// total allowed serving time per second but nominated in cost units, should +// also be scaled with the cost factor and is also updated by this loop. +func (ct *costTracker) gfLoop() { + var gfLog, recentTime, recentAvg float64 + lastUpdate := mclock.Now() + expUpdate := lastUpdate + + data, _ := ct.db.Get([]byte(gfDbKey)) + if len(data) == 8 { + gfLog = math.Float64frombits(binary.BigEndian.Uint64(data[:])) + } + gf := math.Exp(gfLog) + ct.gf = gf + totalRecharge := ct.utilTarget * gf + ct.gfUpdateCh = make(chan gfUpdate, 100) + threshold := gfUsageThreshold * float64(gfUsageTC) * ct.utilTarget / 1000000 + + go func() { + saveCostFactor := func() { + var data [8]byte + binary.BigEndian.PutUint64(data[:], math.Float64bits(gfLog)) + ct.db.Put([]byte(gfDbKey), data[:]) + log.Debug("global cost factor saved", "value", gf) + } + saveTicker := time.NewTicker(time.Minute * 10) + + for { + select { + case r := <-ct.gfUpdateCh: + now := mclock.Now() + if ct.logRelCost != nil && r.avgTimeCost > 1e-20 { + ct.logRelCost.Update(r.servingTime * gf / r.avgTimeCost) + } + if r.servingTime > 1000000000 { + ct.logger.Event(fmt.Sprintf("Very long servingTime = %f avgTimeCost = %f costFactor = %f", r.servingTime, r.avgTimeCost, gf)) + } + dt := float64(now - expUpdate) + expUpdate = now + exp := math.Exp(-dt / float64(gfUsageTC)) + // calculate gf correction until now, based on previous values + var gfCorr float64 + max := recentTime + if recentAvg > max { + max = recentAvg + } + // we apply continuous correction when MAX(recentTime, recentAvg) > threshold + if max > threshold { + // calculate correction time between last expUpdate and now + if max*exp >= threshold { + gfCorr = dt + } else { + gfCorr = math.Log(max/threshold) * float64(gfUsageTC) + } + // calculate log(gf) correction with the right direction and time constant + if recentTime > recentAvg { + // drop gf if actual serving times are larger than average estimates + gfCorr /= -float64(gfDropTC) + } else { + // raise gf if actual serving times are smaller than average estimates + gfCorr /= float64(gfRaiseTC) + } + } + // update recent cost values with current request + recentTime = recentTime*exp + r.servingTime + recentAvg = recentAvg*exp + r.avgTimeCost/gf + + if gfCorr != 0 { + gfLog += gfCorr + gf = math.Exp(gfLog) + if time.Duration(now-lastUpdate) > time.Second { + totalRecharge = ct.utilTarget * gf + lastUpdate = now + ct.gfLock.Lock() + ct.gf = gf + ch := ct.totalRechargeCh + ct.gfLock.Unlock() + if ch != nil { + select { + case ct.totalRechargeCh <- uint64(totalRecharge): + default: + } + } + log.Debug("global cost factor updated", "gf", gf) + } + } + ct.logRecentTime.Update(recentTime) + ct.logRecentAvg.Update(recentAvg) + ct.logTotalRecharge.Update(totalRecharge) + + case <-saveTicker.C: + saveCostFactor() + + case stopCh := <-ct.stopCh: + saveCostFactor() + close(stopCh) + return + } + } + }() +} + +// globalFactor returns the current value of the global cost factor +func (ct *costTracker) globalFactor() float64 { + ct.gfLock.RLock() + defer ct.gfLock.RUnlock() + + return ct.gf +} + +// totalRecharge returns the current total recharge parameter which is used by +// flowcontrol.ClientManager and is scaled by the global cost factor +func (ct *costTracker) totalRecharge() uint64 { + ct.gfLock.RLock() + defer ct.gfLock.RUnlock() + + return uint64(ct.gf * ct.utilTarget) +} + +// subscribeTotalRecharge returns all future updates to the total recharge value +// through a channel and also returns the current value +func (ct *costTracker) subscribeTotalRecharge(ch chan uint64) uint64 { + ct.gfLock.Lock() + defer ct.gfLock.Unlock() + + ct.totalRechargeCh = ch + return uint64(ct.gf * ct.utilTarget) +} + +// updateStats updates the global cost factor and (if enabled) the real cost vs. +// average estimate statistics +func (ct *costTracker) updateStats(code, amount, servingTime, realCost uint64) { + avg := reqAvgTimeCost[code] + avgTimeCost := avg.baseCost + amount*avg.reqCost + select { + case ct.gfUpdateCh <- gfUpdate{float64(avgTimeCost), float64(servingTime)}: + default: + } + if makeCostStats { + realCost <<= 4 + l := 0 + for l < 9 && realCost > avgTimeCost { + l++ + realCost >>= 1 + } + atomic.AddUint64(&ct.stats[code][l], 1) + } +} + +// realCost calculates the final cost of a request based on actual serving time, +// incoming and outgoing message size +// +// Note: message size is only taken into account if bandwidth limitation is applied +// and the cost based on either message size is greater than the cost based on +// serving time. A maximum of the three costs is applied instead of their sum +// because the three limited resources (serving thread time and i/o bandwidth) can +// also be maxed out simultaneously. +func (ct *costTracker) realCost(servingTime uint64, inSize, outSize uint32) uint64 { + cost := float64(servingTime) + inSizeCost := float64(inSize) * ct.inSizeFactor + if inSizeCost > cost { + cost = inSizeCost + } + outSizeCost := float64(outSize) * ct.outSizeFactor + if outSizeCost > cost { + cost = outSizeCost + } + return uint64(cost * ct.globalFactor()) +} + +// printStats prints the distribution of real request cost relative to the average estimates +func (ct *costTracker) printStats() { + if ct.stats == nil { + return + } + for code, arr := range ct.stats { + log.Info("Request cost statistics", "code", code, "1/16", arr[0], "1/8", arr[1], "1/4", arr[2], "1/2", arr[3], "1", arr[4], "2", arr[5], "4", arr[6], "8", arr[7], "16", arr[8], ">16", arr[9]) + } +} + +type ( + // requestCostTable assigns a cost estimate function to each request type + // which is a linear function of the requested amount + // (cost = baseCost + reqCost * amount) + requestCostTable map[uint64]*requestCosts + requestCosts struct { + baseCost, reqCost uint64 + } + + // RequestCostList is a list representation of request costs which is used for + // database storage and communication through the network + RequestCostList []requestCostListItem + requestCostListItem struct { + MsgCode, BaseCost, ReqCost uint64 + } +) + +// getMaxCost calculates the estimated cost for a given request type and amount +func (table requestCostTable) getMaxCost(code, amount uint64) uint64 { + costs := table[code] + return costs.baseCost + amount*costs.reqCost +} + +// decode converts a cost list to a cost table +func (list RequestCostList) decode(protocolLength uint64) requestCostTable { + table := make(requestCostTable) + for _, e := range list { + if e.MsgCode < protocolLength { + table[e.MsgCode] = &requestCosts{ + baseCost: e.BaseCost, + reqCost: e.ReqCost, + } + } + } + return table +} + +// testCostList returns a dummy request cost list used by tests +func testCostList(testCost uint64) RequestCostList { + cl := make(RequestCostList, len(reqAvgTimeCost)) + var max uint64 + for code := range reqAvgTimeCost { + if code > max { + max = code + } + } + i := 0 + for code := uint64(0); code <= max; code++ { + if _, ok := reqAvgTimeCost[code]; ok { + cl[i].MsgCode = code + cl[i].BaseCost = testCost + cl[i].ReqCost = 0 + i++ + } + } + return cl +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/csvlogger/csvlogger.go b/vendor/github.com/ethereum/go-ethereum/les/csvlogger/csvlogger.go new file mode 100644 index 00000000..9a4093cb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/csvlogger/csvlogger.go @@ -0,0 +1,227 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package csvlogger + +import ( + "fmt" + "os" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/log" +) + +// Logger is a metrics/events logger that writes logged values and events into a comma separated file +type Logger struct { + file *os.File + started mclock.AbsTime + channels []*Channel + period time.Duration + stopCh, stopped chan struct{} + storeCh chan string + eventHeader string +} + +// NewLogger creates a new Logger +func NewLogger(fileName string, updatePeriod time.Duration, eventHeader string) *Logger { + if fileName == "" { + return nil + } + f, err := os.Create(fileName) + if err != nil { + log.Error("Error creating log file", "name", fileName, "error", err) + return nil + } + return &Logger{ + file: f, + period: updatePeriod, + stopCh: make(chan struct{}), + storeCh: make(chan string, 1), + eventHeader: eventHeader, + } +} + +// NewChannel creates a new value logger channel that writes values in a single +// column. If the relative change of the value is bigger than the given threshold +// then a new line is added immediately (threshold can also be 0). +func (l *Logger) NewChannel(name string, threshold float64) *Channel { + if l == nil { + return nil + } + c := &Channel{ + logger: l, + name: name, + threshold: threshold, + } + l.channels = append(l.channels, c) + return c +} + +// NewMinMaxChannel creates a new value logger channel that writes the minimum and +// maximum of the tracked value in two columns. It never triggers adding a new line. +// If zeroDefault is true then 0 is written to both min and max columns if no update +// was given during the last period. If it is false then the last update will appear +// in both columns. +func (l *Logger) NewMinMaxChannel(name string, zeroDefault bool) *Channel { + if l == nil { + return nil + } + c := &Channel{ + logger: l, + name: name, + minmax: true, + mmZeroDefault: zeroDefault, + } + l.channels = append(l.channels, c) + return c +} + +func (l *Logger) store(event string) { + s := fmt.Sprintf("%g", float64(mclock.Now()-l.started)/1000000000) + for _, ch := range l.channels { + s += ", " + ch.store() + } + if event != "" { + s += ", " + event + } + l.file.WriteString(s + "\n") +} + +// Start writes the header line and starts the logger +func (l *Logger) Start() { + if l == nil { + return + } + l.started = mclock.Now() + s := "Time" + for _, ch := range l.channels { + s += ", " + ch.header() + } + if l.eventHeader != "" { + s += ", " + l.eventHeader + } + l.file.WriteString(s + "\n") + go func() { + timer := time.NewTimer(l.period) + for { + select { + case <-timer.C: + l.store("") + timer.Reset(l.period) + case event := <-l.storeCh: + l.store(event) + if !timer.Stop() { + <-timer.C + } + timer.Reset(l.period) + case <-l.stopCh: + close(l.stopped) + return + } + } + }() +} + +// Stop stops the logger and closes the file +func (l *Logger) Stop() { + if l == nil { + return + } + l.stopped = make(chan struct{}) + close(l.stopCh) + <-l.stopped + l.file.Close() +} + +// Event immediately adds a new line and adds the given event string in the last column +func (l *Logger) Event(event string) { + if l == nil { + return + } + select { + case l.storeCh <- event: + case <-l.stopCh: + } +} + +// Channel represents a logger channel tracking a single value +type Channel struct { + logger *Logger + lock sync.Mutex + name string + threshold, storeMin, storeMax, lastValue, min, max float64 + minmax, mmSet, mmZeroDefault bool +} + +// Update updates the tracked value +func (lc *Channel) Update(value float64) { + if lc == nil { + return + } + lc.lock.Lock() + defer lc.lock.Unlock() + + lc.lastValue = value + if lc.minmax { + if value > lc.max || !lc.mmSet { + lc.max = value + } + if value < lc.min || !lc.mmSet { + lc.min = value + } + lc.mmSet = true + } else { + if value < lc.storeMin || value > lc.storeMax { + select { + case lc.logger.storeCh <- "": + default: + } + } + } +} + +func (lc *Channel) store() (s string) { + lc.lock.Lock() + defer lc.lock.Unlock() + + if lc.minmax { + s = fmt.Sprintf("%g, %g", lc.min, lc.max) + lc.mmSet = false + if lc.mmZeroDefault { + lc.min = 0 + } else { + lc.min = lc.lastValue + } + lc.max = lc.min + } else { + s = fmt.Sprintf("%g", lc.lastValue) + lc.storeMin = lc.lastValue * (1 - lc.threshold) + lc.storeMax = lc.lastValue * (1 + lc.threshold) + if lc.lastValue < 0 { + lc.storeMin, lc.storeMax = lc.storeMax, lc.storeMin + } + } + return +} + +func (lc *Channel) header() string { + if lc.minmax { + return lc.name + " (min), " + lc.name + " (max)" + } + return lc.name +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/distributor.go b/vendor/github.com/ethereum/go-ethereum/les/distributor.go new file mode 100644 index 00000000..9235adc0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/distributor.go @@ -0,0 +1,296 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "container/list" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" +) + +// requestDistributor implements a mechanism that distributes requests to +// suitable peers, obeying flow control rules and prioritizing them in creation +// order (even when a resend is necessary). +type requestDistributor struct { + clock mclock.Clock + reqQueue *list.List + lastReqOrder uint64 + peers map[distPeer]struct{} + peerLock sync.RWMutex + stopChn, loopChn chan struct{} + loopNextSent bool + lock sync.Mutex +} + +// distPeer is an LES server peer interface for the request distributor. +// waitBefore returns either the necessary waiting time before sending a request +// with the given upper estimated cost or the estimated remaining relative buffer +// value after sending such a request (in which case the request can be sent +// immediately). At least one of these values is always zero. +type distPeer interface { + waitBefore(uint64) (time.Duration, float64) + canQueue() bool + queueSend(f func()) +} + +// distReq is the request abstraction used by the distributor. It is based on +// three callback functions: +// - getCost returns the upper estimate of the cost of sending the request to a given peer +// - canSend tells if the server peer is suitable to serve the request +// - request prepares sending the request to the given peer and returns a function that +// does the actual sending. Request order should be preserved but the callback itself should not +// block until it is sent because other peers might still be able to receive requests while +// one of them is blocking. Instead, the returned function is put in the peer's send queue. +type distReq struct { + getCost func(distPeer) uint64 + canSend func(distPeer) bool + request func(distPeer) func() + + reqOrder uint64 + sentChn chan distPeer + element *list.Element + waitForPeers mclock.AbsTime +} + +// newRequestDistributor creates a new request distributor +func newRequestDistributor(peers *peerSet, stopChn chan struct{}, clock mclock.Clock) *requestDistributor { + d := &requestDistributor{ + clock: clock, + reqQueue: list.New(), + loopChn: make(chan struct{}, 2), + stopChn: stopChn, + peers: make(map[distPeer]struct{}), + } + if peers != nil { + peers.notify(d) + } + go d.loop() + return d +} + +// registerPeer implements peerSetNotify +func (d *requestDistributor) registerPeer(p *peer) { + d.peerLock.Lock() + d.peers[p] = struct{}{} + d.peerLock.Unlock() +} + +// unregisterPeer implements peerSetNotify +func (d *requestDistributor) unregisterPeer(p *peer) { + d.peerLock.Lock() + delete(d.peers, p) + d.peerLock.Unlock() +} + +// registerTestPeer adds a new test peer +func (d *requestDistributor) registerTestPeer(p distPeer) { + d.peerLock.Lock() + d.peers[p] = struct{}{} + d.peerLock.Unlock() +} + +// distMaxWait is the maximum waiting time after which further necessary waiting +// times are recalculated based on new feedback from the servers +const distMaxWait = time.Millisecond * 50 + +// waitForPeers is the time window in which a request does not fail even if it +// has no suitable peers to send to at the moment +const waitForPeers = time.Second * 3 + +// main event loop +func (d *requestDistributor) loop() { + for { + select { + case <-d.stopChn: + d.lock.Lock() + elem := d.reqQueue.Front() + for elem != nil { + req := elem.Value.(*distReq) + close(req.sentChn) + req.sentChn = nil + elem = elem.Next() + } + d.lock.Unlock() + return + case <-d.loopChn: + d.lock.Lock() + d.loopNextSent = false + loop: + for { + peer, req, wait := d.nextRequest() + if req != nil && wait == 0 { + chn := req.sentChn // save sentChn because remove sets it to nil + d.remove(req) + send := req.request(peer) + if send != nil { + peer.queueSend(send) + } + chn <- peer + close(chn) + } else { + if wait == 0 { + // no request to send and nothing to wait for; the next + // queued request will wake up the loop + break loop + } + d.loopNextSent = true // a "next" signal has been sent, do not send another one until this one has been received + if wait > distMaxWait { + // waiting times may be reduced by incoming request replies, if it is too long, recalculate it periodically + wait = distMaxWait + } + go func() { + d.clock.Sleep(wait) + d.loopChn <- struct{}{} + }() + break loop + } + } + d.lock.Unlock() + } + } +} + +// selectPeerItem represents a peer to be selected for a request by weightedRandomSelect +type selectPeerItem struct { + peer distPeer + req *distReq + weight int64 +} + +// Weight implements wrsItem interface +func (sp selectPeerItem) Weight() int64 { + return sp.weight +} + +// nextRequest returns the next possible request from any peer, along with the +// associated peer and necessary waiting time +func (d *requestDistributor) nextRequest() (distPeer, *distReq, time.Duration) { + checkedPeers := make(map[distPeer]struct{}) + elem := d.reqQueue.Front() + var ( + bestWait time.Duration + sel *weightedRandomSelect + ) + + d.peerLock.RLock() + defer d.peerLock.RUnlock() + + peerCount := len(d.peers) + for (len(checkedPeers) < peerCount || elem == d.reqQueue.Front()) && elem != nil { + req := elem.Value.(*distReq) + canSend := false + now := d.clock.Now() + if req.waitForPeers > now { + canSend = true + wait := time.Duration(req.waitForPeers - now) + if bestWait == 0 || wait < bestWait { + bestWait = wait + } + } + for peer := range d.peers { + if _, ok := checkedPeers[peer]; !ok && peer.canQueue() && req.canSend(peer) { + canSend = true + cost := req.getCost(peer) + wait, bufRemain := peer.waitBefore(cost) + if wait == 0 { + if sel == nil { + sel = newWeightedRandomSelect() + } + sel.update(selectPeerItem{peer: peer, req: req, weight: int64(bufRemain*1000000) + 1}) + } else { + if bestWait == 0 || wait < bestWait { + bestWait = wait + } + } + checkedPeers[peer] = struct{}{} + } + } + next := elem.Next() + if !canSend && elem == d.reqQueue.Front() { + close(req.sentChn) + d.remove(req) + } + elem = next + } + + if sel != nil { + c := sel.choose().(selectPeerItem) + return c.peer, c.req, 0 + } + return nil, nil, bestWait +} + +// queue adds a request to the distribution queue, returns a channel where the +// receiving peer is sent once the request has been sent (request callback returned). +// If the request is cancelled or timed out without suitable peers, the channel is +// closed without sending any peer references to it. +func (d *requestDistributor) queue(r *distReq) chan distPeer { + d.lock.Lock() + defer d.lock.Unlock() + + if r.reqOrder == 0 { + d.lastReqOrder++ + r.reqOrder = d.lastReqOrder + r.waitForPeers = d.clock.Now() + mclock.AbsTime(waitForPeers) + } + + back := d.reqQueue.Back() + if back == nil || r.reqOrder > back.Value.(*distReq).reqOrder { + r.element = d.reqQueue.PushBack(r) + } else { + before := d.reqQueue.Front() + for before.Value.(*distReq).reqOrder < r.reqOrder { + before = before.Next() + } + r.element = d.reqQueue.InsertBefore(r, before) + } + + if !d.loopNextSent { + d.loopNextSent = true + d.loopChn <- struct{}{} + } + + r.sentChn = make(chan distPeer, 1) + return r.sentChn +} + +// cancel removes a request from the queue if it has not been sent yet (returns +// false if it has been sent already). It is guaranteed that the callback functions +// will not be called after cancel returns. +func (d *requestDistributor) cancel(r *distReq) bool { + d.lock.Lock() + defer d.lock.Unlock() + + if r.sentChn == nil { + return false + } + + close(r.sentChn) + d.remove(r) + return true +} + +// remove removes a request from the queue +func (d *requestDistributor) remove(r *distReq) { + r.sentChn = nil + if r.element != nil { + d.reqQueue.Remove(r.element) + r.element = nil + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/execqueue.go b/vendor/github.com/ethereum/go-ethereum/les/execqueue.go new file mode 100644 index 00000000..e0c88a99 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/execqueue.go @@ -0,0 +1,104 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import "sync" + +// execQueue implements a queue that executes function calls in a single thread, +// in the same order as they have been queued. +type execQueue struct { + mu sync.Mutex + cond *sync.Cond + funcs []func() + closeWait chan struct{} +} + +// newExecQueue creates a new execution queue. +func newExecQueue(capacity int) *execQueue { + q := &execQueue{funcs: make([]func(), 0, capacity)} + q.cond = sync.NewCond(&q.mu) + go q.loop() + return q +} + +func (q *execQueue) loop() { + for f := q.waitNext(false); f != nil; f = q.waitNext(true) { + f() + } + close(q.closeWait) +} + +func (q *execQueue) waitNext(drop bool) (f func()) { + q.mu.Lock() + if drop && len(q.funcs) > 0 { + // Remove the function that just executed. We do this here instead of when + // dequeuing so len(q.funcs) includes the function that is running. + q.funcs = append(q.funcs[:0], q.funcs[1:]...) + } + for !q.isClosed() { + if len(q.funcs) > 0 { + f = q.funcs[0] + break + } + q.cond.Wait() + } + q.mu.Unlock() + return f +} + +func (q *execQueue) isClosed() bool { + return q.closeWait != nil +} + +// canQueue returns true if more function calls can be added to the execution queue. +func (q *execQueue) canQueue() bool { + q.mu.Lock() + ok := !q.isClosed() && len(q.funcs) < cap(q.funcs) + q.mu.Unlock() + return ok +} + +// queue adds a function call to the execution queue. Returns true if successful. +func (q *execQueue) queue(f func()) bool { + q.mu.Lock() + ok := !q.isClosed() && len(q.funcs) < cap(q.funcs) + if ok { + q.funcs = append(q.funcs, f) + q.cond.Signal() + } + q.mu.Unlock() + return ok +} + +// clear drops all queued functions +func (q *execQueue) clear() { + q.mu.Lock() + q.funcs = q.funcs[:0] + q.mu.Unlock() +} + +// quit stops the exec queue. +// quit waits for the current execution to finish before returning. +func (q *execQueue) quit() { + q.mu.Lock() + if !q.isClosed() { + q.closeWait = make(chan struct{}) + q.cond.Signal() + } + q.mu.Unlock() + <-q.closeWait +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/fetcher.go b/vendor/github.com/ethereum/go-ethereum/les/fetcher.go new file mode 100644 index 00000000..fa02be9a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/fetcher.go @@ -0,0 +1,905 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" +) + +const ( + blockDelayTimeout = time.Second * 10 // timeout for a peer to announce a head that has already been confirmed by others + maxNodeCount = 20 // maximum number of fetcherTreeNode entries remembered for each peer + serverStateAvailable = 100 // number of recent blocks where state availability is assumed +) + +// lightFetcher implements retrieval of newly announced headers. It also provides a peerHasBlock function for the +// ODR system to ensure that we only request data related to a certain block from peers who have already processed +// and announced that block. +type lightFetcher struct { + pm *ProtocolManager + odr *LesOdr + chain lightChain + + lock sync.Mutex // lock protects access to the fetcher's internal state variables except sent requests + maxConfirmedTd *big.Int + peers map[*peer]*fetcherPeerInfo + lastUpdateStats *updateStatsEntry + syncing bool + syncDone chan *peer + + reqMu sync.RWMutex // reqMu protects access to sent header fetch requests + requested map[uint64]fetchRequest + deliverChn chan fetchResponse + timeoutChn chan uint64 + requestTriggered bool + requestTrigger chan struct{} + lastTrustedHeader *types.Header +} + +// lightChain extends the BlockChain interface by locking. +type lightChain interface { + BlockChain + LockChain() + UnlockChain() +} + +// fetcherPeerInfo holds fetcher-specific information about each active peer +type fetcherPeerInfo struct { + root, lastAnnounced *fetcherTreeNode + nodeCnt int + confirmedTd *big.Int + bestConfirmed *fetcherTreeNode + nodeByHash map[common.Hash]*fetcherTreeNode + firstUpdateStats *updateStatsEntry +} + +// fetcherTreeNode is a node of a tree that holds information about blocks recently +// announced and confirmed by a certain peer. Each new announce message from a peer +// adds nodes to the tree, based on the previous announced head and the reorg depth. +// There are three possible states for a tree node: +// - announced: not downloaded (known) yet, but we know its head, number and td +// - intermediate: not known, hash and td are empty, they are filled out when it becomes known +// - known: both announced by this peer and downloaded (from any peer). +// This structure makes it possible to always know which peer has a certain block, +// which is necessary for selecting a suitable peer for ODR requests and also for +// canonizing new heads. It also helps to always download the minimum necessary +// amount of headers with a single request. +type fetcherTreeNode struct { + hash common.Hash + number uint64 + td *big.Int + known, requested bool + parent *fetcherTreeNode + children []*fetcherTreeNode +} + +// fetchRequest represents a header download request +type fetchRequest struct { + hash common.Hash + amount uint64 + peer *peer + sent mclock.AbsTime + timeout bool +} + +// fetchResponse represents a header download response +type fetchResponse struct { + reqID uint64 + headers []*types.Header + peer *peer +} + +// newLightFetcher creates a new light fetcher +func newLightFetcher(pm *ProtocolManager) *lightFetcher { + f := &lightFetcher{ + pm: pm, + chain: pm.blockchain.(*light.LightChain), + odr: pm.odr, + peers: make(map[*peer]*fetcherPeerInfo), + deliverChn: make(chan fetchResponse, 100), + requested: make(map[uint64]fetchRequest), + timeoutChn: make(chan uint64), + requestTrigger: make(chan struct{}, 1), + syncDone: make(chan *peer), + maxConfirmedTd: big.NewInt(0), + } + pm.peers.notify(f) + + f.pm.wg.Add(1) + go f.syncLoop() + return f +} + +// syncLoop is the main event loop of the light fetcher +func (f *lightFetcher) syncLoop() { + defer f.pm.wg.Done() + for { + select { + case <-f.pm.quitSync: + return + // request loop keeps running until no further requests are necessary or possible + case <-f.requestTrigger: + f.lock.Lock() + var ( + rq *distReq + reqID uint64 + syncing bool + ) + if !f.syncing { + rq, reqID, syncing = f.nextRequest() + } + f.requestTriggered = rq != nil + f.lock.Unlock() + + if rq != nil { + if _, ok := <-f.pm.reqDist.queue(rq); ok { + if syncing { + f.lock.Lock() + f.syncing = true + f.lock.Unlock() + } else { + go func() { + time.Sleep(softRequestTimeout) + f.reqMu.Lock() + req, ok := f.requested[reqID] + if ok { + req.timeout = true + f.requested[reqID] = req + } + f.reqMu.Unlock() + // keep starting new requests while possible + f.requestTrigger <- struct{}{} + }() + } + } else { + f.requestTrigger <- struct{}{} + } + } + case reqID := <-f.timeoutChn: + f.reqMu.Lock() + req, ok := f.requested[reqID] + if ok { + delete(f.requested, reqID) + } + f.reqMu.Unlock() + if ok { + f.pm.serverPool.adjustResponseTime(req.peer.poolEntry, time.Duration(mclock.Now()-req.sent), true) + req.peer.Log().Debug("Fetching data timed out hard") + go f.pm.removePeer(req.peer.id) + } + case resp := <-f.deliverChn: + f.reqMu.Lock() + req, ok := f.requested[resp.reqID] + if ok && req.peer != resp.peer { + ok = false + } + if ok { + delete(f.requested, resp.reqID) + } + f.reqMu.Unlock() + if ok { + f.pm.serverPool.adjustResponseTime(req.peer.poolEntry, time.Duration(mclock.Now()-req.sent), req.timeout) + } + f.lock.Lock() + if !ok || !(f.syncing || f.processResponse(req, resp)) { + resp.peer.Log().Debug("Failed processing response") + go f.pm.removePeer(resp.peer.id) + } + f.lock.Unlock() + case p := <-f.syncDone: + f.lock.Lock() + p.Log().Debug("Done synchronising with peer") + f.checkSyncedHeaders(p) + f.syncing = false + f.lock.Unlock() + f.requestTrigger <- struct{}{} // f.requestTriggered is always true here + } + } +} + +// registerPeer adds a new peer to the fetcher's peer set +func (f *lightFetcher) registerPeer(p *peer) { + p.lock.Lock() + p.hasBlock = func(hash common.Hash, number uint64, hasState bool) bool { + return f.peerHasBlock(p, hash, number, hasState) + } + p.lock.Unlock() + + f.lock.Lock() + defer f.lock.Unlock() + f.peers[p] = &fetcherPeerInfo{nodeByHash: make(map[common.Hash]*fetcherTreeNode)} +} + +// unregisterPeer removes a new peer from the fetcher's peer set +func (f *lightFetcher) unregisterPeer(p *peer) { + p.lock.Lock() + p.hasBlock = nil + p.lock.Unlock() + + f.lock.Lock() + defer f.lock.Unlock() + + // check for potential timed out block delay statistics + f.checkUpdateStats(p, nil) + delete(f.peers, p) +} + +// announce processes a new announcement message received from a peer, adding new +// nodes to the peer's block tree and removing old nodes if necessary +func (f *lightFetcher) announce(p *peer, head *announceData) { + f.lock.Lock() + defer f.lock.Unlock() + p.Log().Debug("Received new announcement", "number", head.Number, "hash", head.Hash, "reorg", head.ReorgDepth) + + fp := f.peers[p] + if fp == nil { + p.Log().Debug("Announcement from unknown peer") + return + } + + if fp.lastAnnounced != nil && head.Td.Cmp(fp.lastAnnounced.td) <= 0 { + // announced tds should be strictly monotonic + p.Log().Debug("Received non-monotonic td", "current", head.Td, "previous", fp.lastAnnounced.td) + go f.pm.removePeer(p.id) + return + } + + n := fp.lastAnnounced + for i := uint64(0); i < head.ReorgDepth; i++ { + if n == nil { + break + } + n = n.parent + } + // n is now the reorg common ancestor, add a new branch of nodes + if n != nil && (head.Number >= n.number+maxNodeCount || head.Number <= n.number) { + // if announced head block height is lower or same as n or too far from it to add + // intermediate nodes then discard previous announcement info and trigger a resync + n = nil + fp.nodeCnt = 0 + fp.nodeByHash = make(map[common.Hash]*fetcherTreeNode) + } + // check if the node count is too high to add new nodes, discard oldest ones if necessary + if n != nil { + // n is now the reorg common ancestor, add a new branch of nodes + // check if the node count is too high to add new nodes + locked := false + for uint64(fp.nodeCnt)+head.Number-n.number > maxNodeCount && fp.root != nil { + if !locked { + f.chain.LockChain() + defer f.chain.UnlockChain() + locked = true + } + // if one of root's children is canonical, keep it, delete other branches and root itself + var newRoot *fetcherTreeNode + for i, nn := range fp.root.children { + if rawdb.ReadCanonicalHash(f.pm.chainDb, nn.number) == nn.hash { + fp.root.children = append(fp.root.children[:i], fp.root.children[i+1:]...) + nn.parent = nil + newRoot = nn + break + } + } + fp.deleteNode(fp.root) + if n == fp.root { + n = newRoot + } + fp.root = newRoot + if newRoot == nil || !f.checkKnownNode(p, newRoot) { + fp.bestConfirmed = nil + fp.confirmedTd = nil + } + + if n == nil { + break + } + } + if n != nil { + for n.number < head.Number { + nn := &fetcherTreeNode{number: n.number + 1, parent: n} + n.children = append(n.children, nn) + n = nn + fp.nodeCnt++ + } + n.hash = head.Hash + n.td = head.Td + fp.nodeByHash[n.hash] = n + } + } + + if n == nil { + // could not find reorg common ancestor or had to delete entire tree, a new root and a resync is needed + if fp.root != nil { + fp.deleteNode(fp.root) + } + n = &fetcherTreeNode{hash: head.Hash, number: head.Number, td: head.Td} + fp.root = n + fp.nodeCnt++ + fp.nodeByHash[n.hash] = n + fp.bestConfirmed = nil + fp.confirmedTd = nil + } + + f.checkKnownNode(p, n) + p.lock.Lock() + p.headInfo = head + fp.lastAnnounced = n + p.lock.Unlock() + f.checkUpdateStats(p, nil) + if !f.requestTriggered { + f.requestTriggered = true + f.requestTrigger <- struct{}{} + } +} + +// peerHasBlock returns true if we can assume the peer knows the given block +// based on its announcements +func (f *lightFetcher) peerHasBlock(p *peer, hash common.Hash, number uint64, hasState bool) bool { + f.lock.Lock() + defer f.lock.Unlock() + + fp := f.peers[p] + if fp == nil || fp.root == nil { + return false + } + + if hasState { + if fp.lastAnnounced == nil || fp.lastAnnounced.number > number+serverStateAvailable { + return false + } + } + + if f.syncing { + // always return true when syncing + // false positives are acceptable, a more sophisticated condition can be implemented later + return true + } + + if number >= fp.root.number { + // it is recent enough that if it is known, is should be in the peer's block tree + return fp.nodeByHash[hash] != nil + } + f.chain.LockChain() + defer f.chain.UnlockChain() + // if it's older than the peer's block tree root but it's in the same canonical chain + // as the root, we can still be sure the peer knows it + // + // when syncing, just check if it is part of the known chain, there is nothing better we + // can do since we do not know the most recent block hash yet + return rawdb.ReadCanonicalHash(f.pm.chainDb, fp.root.number) == fp.root.hash && rawdb.ReadCanonicalHash(f.pm.chainDb, number) == hash +} + +// requestAmount calculates the amount of headers to be downloaded starting +// from a certain head backwards +func (f *lightFetcher) requestAmount(p *peer, n *fetcherTreeNode) uint64 { + amount := uint64(0) + nn := n + for nn != nil && !f.checkKnownNode(p, nn) { + nn = nn.parent + amount++ + } + if nn == nil { + amount = n.number + } + return amount +} + +// requestedID tells if a certain reqID has been requested by the fetcher +func (f *lightFetcher) requestedID(reqID uint64) bool { + f.reqMu.RLock() + _, ok := f.requested[reqID] + f.reqMu.RUnlock() + return ok +} + +// nextRequest selects the peer and announced head to be requested next, amount +// to be downloaded starting from the head backwards is also returned +func (f *lightFetcher) nextRequest() (*distReq, uint64, bool) { + var ( + bestHash common.Hash + bestAmount uint64 + bestTd *big.Int + bestSyncing bool + ) + bestHash, bestAmount, bestTd, bestSyncing = f.findBestRequest() + + if bestTd == f.maxConfirmedTd { + return nil, 0, false + } + + var rq *distReq + reqID := genReqID() + if bestSyncing { + rq = f.newFetcherDistReqForSync(bestHash) + } else { + rq = f.newFetcherDistReq(bestHash, reqID, bestAmount) + } + return rq, reqID, bestSyncing +} + +// findBestRequest finds the best head to request that has been announced by but not yet requested from a known peer. +// It also returns the announced Td (which should be verified after fetching the head), +// the necessary amount to request and whether a downloader sync is necessary instead of a normal header request. +func (f *lightFetcher) findBestRequest() (bestHash common.Hash, bestAmount uint64, bestTd *big.Int, bestSyncing bool) { + bestTd = f.maxConfirmedTd + bestSyncing = false + + for p, fp := range f.peers { + for hash, n := range fp.nodeByHash { + if f.checkKnownNode(p, n) || n.requested { + continue + } + + //if ulc mode is disabled, isTrustedHash returns true + amount := f.requestAmount(p, n) + if (bestTd == nil || n.td.Cmp(bestTd) > 0 || amount < bestAmount) && (f.isTrustedHash(hash) || f.maxConfirmedTd.Int64() == 0) { + bestHash = hash + bestTd = n.td + bestAmount = amount + bestSyncing = fp.bestConfirmed == nil || fp.root == nil || !f.checkKnownNode(p, fp.root) + } + } + } + return +} + +// isTrustedHash checks if the block can be trusted by the minimum trusted fraction. +func (f *lightFetcher) isTrustedHash(hash common.Hash) bool { + if !f.pm.isULCEnabled() { + return true + } + + var numAgreed int + for p, fp := range f.peers { + if !p.isTrusted { + continue + } + if _, ok := fp.nodeByHash[hash]; !ok { + continue + } + + numAgreed++ + } + + return 100*numAgreed/len(f.pm.ulc.trustedKeys) >= f.pm.ulc.minTrustedFraction +} + +func (f *lightFetcher) newFetcherDistReqForSync(bestHash common.Hash) *distReq { + return &distReq{ + getCost: func(dp distPeer) uint64 { + return 0 + }, + canSend: func(dp distPeer) bool { + p := dp.(*peer) + f.lock.Lock() + defer f.lock.Unlock() + + if p.isOnlyAnnounce { + return false + } + + fp := f.peers[p] + return fp != nil && fp.nodeByHash[bestHash] != nil + }, + request: func(dp distPeer) func() { + if f.pm.isULCEnabled() { + //keep last trusted header before sync + f.setLastTrustedHeader(f.chain.CurrentHeader()) + } + go func() { + p := dp.(*peer) + p.Log().Debug("Synchronisation started") + f.pm.synchronise(p) + f.syncDone <- p + }() + return nil + }, + } +} + +// newFetcherDistReq creates a new request for the distributor. +func (f *lightFetcher) newFetcherDistReq(bestHash common.Hash, reqID uint64, bestAmount uint64) *distReq { + return &distReq{ + getCost: func(dp distPeer) uint64 { + p := dp.(*peer) + return p.GetRequestCost(GetBlockHeadersMsg, int(bestAmount)) + }, + canSend: func(dp distPeer) bool { + p := dp.(*peer) + f.lock.Lock() + defer f.lock.Unlock() + + if p.isOnlyAnnounce { + return false + } + + fp := f.peers[p] + if fp == nil { + return false + } + n := fp.nodeByHash[bestHash] + return n != nil && !n.requested + }, + request: func(dp distPeer) func() { + p := dp.(*peer) + f.lock.Lock() + fp := f.peers[p] + if fp != nil { + n := fp.nodeByHash[bestHash] + if n != nil { + n.requested = true + } + } + f.lock.Unlock() + + cost := p.GetRequestCost(GetBlockHeadersMsg, int(bestAmount)) + p.fcServer.QueuedRequest(reqID, cost) + f.reqMu.Lock() + f.requested[reqID] = fetchRequest{hash: bestHash, amount: bestAmount, peer: p, sent: mclock.Now()} + f.reqMu.Unlock() + go func() { + time.Sleep(hardRequestTimeout) + f.timeoutChn <- reqID + }() + return func() { p.RequestHeadersByHash(reqID, cost, bestHash, int(bestAmount), 0, true) } + }, + } +} + +// deliverHeaders delivers header download request responses for processing +func (f *lightFetcher) deliverHeaders(peer *peer, reqID uint64, headers []*types.Header) { + f.deliverChn <- fetchResponse{reqID: reqID, headers: headers, peer: peer} +} + +// processResponse processes header download request responses, returns true if successful +func (f *lightFetcher) processResponse(req fetchRequest, resp fetchResponse) bool { + if uint64(len(resp.headers)) != req.amount || resp.headers[0].Hash() != req.hash { + req.peer.Log().Debug("Response content mismatch", "requested", len(resp.headers), "reqfrom", resp.headers[0], "delivered", req.amount, "delfrom", req.hash) + return false + } + headers := make([]*types.Header, req.amount) + for i, header := range resp.headers { + headers[int(req.amount)-1-i] = header + } + + if _, err := f.chain.InsertHeaderChain(headers, 1); err != nil { + if err == consensus.ErrFutureBlock { + return true + } + log.Debug("Failed to insert header chain", "err", err) + return false + } + tds := make([]*big.Int, len(headers)) + for i, header := range headers { + td := f.chain.GetTd(header.Hash(), header.Number.Uint64()) + if td == nil { + log.Debug("Total difficulty not found for header", "index", i+1, "number", header.Number, "hash", header.Hash()) + return false + } + tds[i] = td + } + f.newHeaders(headers, tds) + return true +} + +// newHeaders updates the block trees of all active peers according to a newly +// downloaded and validated batch or headers +func (f *lightFetcher) newHeaders(headers []*types.Header, tds []*big.Int) { + var maxTd *big.Int + + for p, fp := range f.peers { + if !f.checkAnnouncedHeaders(fp, headers, tds) { + p.Log().Debug("Inconsistent announcement") + go f.pm.removePeer(p.id) + } + if fp.confirmedTd != nil && (maxTd == nil || maxTd.Cmp(fp.confirmedTd) > 0) { + maxTd = fp.confirmedTd + } + } + + if maxTd != nil { + f.updateMaxConfirmedTd(maxTd) + } +} + +// checkAnnouncedHeaders updates peer's block tree if necessary after validating +// a batch of headers. It searches for the latest header in the batch that has a +// matching tree node (if any), and if it has not been marked as known already, +// sets it and its parents to known (even those which are older than the currently +// validated ones). Return value shows if all hashes, numbers and Tds matched +// correctly to the announced values (otherwise the peer should be dropped). +func (f *lightFetcher) checkAnnouncedHeaders(fp *fetcherPeerInfo, headers []*types.Header, tds []*big.Int) bool { + var ( + n *fetcherTreeNode + header *types.Header + td *big.Int + ) + + for i := len(headers) - 1; ; i-- { + if i < 0 { + if n == nil { + // no more headers and nothing to match + return true + } + // we ran out of recently delivered headers but have not reached a node known by this peer yet, continue matching + hash, number := header.ParentHash, header.Number.Uint64()-1 + td = f.chain.GetTd(hash, number) + header = f.chain.GetHeader(hash, number) + if header == nil || td == nil { + log.Error("Missing parent of validated header", "hash", hash, "number", number) + return false + } + } else { + header = headers[i] + td = tds[i] + } + hash := header.Hash() + number := header.Number.Uint64() + if n == nil { + n = fp.nodeByHash[hash] + } + if n != nil { + if n.td == nil { + // node was unannounced + if nn := fp.nodeByHash[hash]; nn != nil { + // if there was already a node with the same hash, continue there and drop this one + nn.children = append(nn.children, n.children...) + n.children = nil + fp.deleteNode(n) + n = nn + } else { + n.hash = hash + n.td = td + fp.nodeByHash[hash] = n + } + } + // check if it matches the header + if n.hash != hash || n.number != number || n.td.Cmp(td) != 0 { + // peer has previously made an invalid announcement + return false + } + if n.known { + // we reached a known node that matched our expectations, return with success + return true + } + n.known = true + if fp.confirmedTd == nil || td.Cmp(fp.confirmedTd) > 0 { + fp.confirmedTd = td + fp.bestConfirmed = n + } + n = n.parent + if n == nil { + return true + } + } + } +} + +// checkSyncedHeaders updates peer's block tree after synchronisation by marking +// downloaded headers as known. If none of the announced headers are found after +// syncing, the peer is dropped. +func (f *lightFetcher) checkSyncedHeaders(p *peer) { + fp := f.peers[p] + if fp == nil { + p.Log().Debug("Unknown peer to check sync headers") + return + } + + n := fp.lastAnnounced + var td *big.Int + + var h *types.Header + if f.pm.isULCEnabled() { + var unapprovedHashes []common.Hash + // Overwrite last announced for ULC mode + h, unapprovedHashes = f.lastTrustedTreeNode(p) + //rollback untrusted blocks + f.chain.Rollback(unapprovedHashes) + //overwrite to last trusted + n = fp.nodeByHash[h.Hash()] + } + + //find last valid block + for n != nil { + if td = f.chain.GetTd(n.hash, n.number); td != nil { + break + } + n = n.parent + } + + // Now n is the latest downloaded/approved header after syncing + if n == nil { + p.Log().Debug("Synchronisation failed") + go f.pm.removePeer(p.id) + return + } + header := f.chain.GetHeader(n.hash, n.number) + f.newHeaders([]*types.Header{header}, []*big.Int{td}) +} + +// lastTrustedTreeNode return last approved treeNode and a list of unapproved hashes +func (f *lightFetcher) lastTrustedTreeNode(p *peer) (*types.Header, []common.Hash) { + unapprovedHashes := make([]common.Hash, 0) + current := f.chain.CurrentHeader() + + if f.lastTrustedHeader == nil { + return current, unapprovedHashes + } + + canonical := f.chain.CurrentHeader() + if canonical.Number.Uint64() > f.lastTrustedHeader.Number.Uint64() { + canonical = f.chain.GetHeaderByNumber(f.lastTrustedHeader.Number.Uint64()) + } + commonAncestor := rawdb.FindCommonAncestor(f.pm.chainDb, canonical, f.lastTrustedHeader) + if commonAncestor == nil { + log.Error("Common ancestor of last trusted header and canonical header is nil", "canonical hash", canonical.Hash(), "trusted hash", f.lastTrustedHeader.Hash()) + return current, unapprovedHashes + } + + for current.Hash() == commonAncestor.Hash() { + if f.isTrustedHash(current.Hash()) { + break + } + unapprovedHashes = append(unapprovedHashes, current.Hash()) + current = f.chain.GetHeader(current.ParentHash, current.Number.Uint64()-1) + } + return current, unapprovedHashes +} + +func (f *lightFetcher) setLastTrustedHeader(h *types.Header) { + f.lock.Lock() + defer f.lock.Unlock() + f.lastTrustedHeader = h +} + +// checkKnownNode checks if a block tree node is known (downloaded and validated) +// If it was not known previously but found in the database, sets its known flag +func (f *lightFetcher) checkKnownNode(p *peer, n *fetcherTreeNode) bool { + if n.known { + return true + } + td := f.chain.GetTd(n.hash, n.number) + if td == nil { + return false + } + header := f.chain.GetHeader(n.hash, n.number) + // check the availability of both header and td because reads are not protected by chain db mutex + // Note: returning false is always safe here + if header == nil { + return false + } + + fp := f.peers[p] + if fp == nil { + p.Log().Debug("Unknown peer to check known nodes") + return false + } + if !f.checkAnnouncedHeaders(fp, []*types.Header{header}, []*big.Int{td}) { + p.Log().Debug("Inconsistent announcement") + go f.pm.removePeer(p.id) + } + if fp.confirmedTd != nil { + f.updateMaxConfirmedTd(fp.confirmedTd) + } + return n.known +} + +// deleteNode deletes a node and its child subtrees from a peer's block tree +func (fp *fetcherPeerInfo) deleteNode(n *fetcherTreeNode) { + if n.parent != nil { + for i, nn := range n.parent.children { + if nn == n { + n.parent.children = append(n.parent.children[:i], n.parent.children[i+1:]...) + break + } + } + } + for { + if n.td != nil { + delete(fp.nodeByHash, n.hash) + } + fp.nodeCnt-- + if len(n.children) == 0 { + return + } + for i, nn := range n.children { + if i == 0 { + n = nn + } else { + fp.deleteNode(nn) + } + } + } +} + +// updateStatsEntry items form a linked list that is expanded with a new item every time a new head with a higher Td +// than the previous one has been downloaded and validated. The list contains a series of maximum confirmed Td values +// and the time these values have been confirmed, both increasing monotonically. A maximum confirmed Td is calculated +// both globally for all peers and also for each individual peer (meaning that the given peer has announced the head +// and it has also been downloaded from any peer, either before or after the given announcement). +// The linked list has a global tail where new confirmed Td entries are added and a separate head for each peer, +// pointing to the next Td entry that is higher than the peer's max confirmed Td (nil if it has already confirmed +// the current global head). +type updateStatsEntry struct { + time mclock.AbsTime + td *big.Int + next *updateStatsEntry +} + +// updateMaxConfirmedTd updates the block delay statistics of active peers. Whenever a new highest Td is confirmed, +// adds it to the end of a linked list together with the time it has been confirmed. Then checks which peers have +// already confirmed a head with the same or higher Td (which counts as zero block delay) and updates their statistics. +// Those who have not confirmed such a head by now will be updated by a subsequent checkUpdateStats call with a +// positive block delay value. +func (f *lightFetcher) updateMaxConfirmedTd(td *big.Int) { + if f.maxConfirmedTd == nil || td.Cmp(f.maxConfirmedTd) > 0 { + f.maxConfirmedTd = td + newEntry := &updateStatsEntry{ + time: mclock.Now(), + td: td, + } + if f.lastUpdateStats != nil { + f.lastUpdateStats.next = newEntry + } + + f.lastUpdateStats = newEntry + for p := range f.peers { + f.checkUpdateStats(p, newEntry) + } + } +} + +// checkUpdateStats checks those peers who have not confirmed a certain highest Td (or a larger one) by the time it +// has been confirmed by another peer. If they have confirmed such a head by now, their stats are updated with the +// block delay which is (this peer's confirmation time)-(first confirmation time). After blockDelayTimeout has passed, +// the stats are updated with blockDelayTimeout value. In either case, the confirmed or timed out updateStatsEntry +// items are removed from the head of the linked list. +// If a new entry has been added to the global tail, it is passed as a parameter here even though this function +// assumes that it has already been added, so that if the peer's list is empty (all heads confirmed, head is nil), +// it can set the new head to newEntry. +func (f *lightFetcher) checkUpdateStats(p *peer, newEntry *updateStatsEntry) { + now := mclock.Now() + fp := f.peers[p] + if fp == nil { + p.Log().Debug("Unknown peer to check update stats") + return + } + + if newEntry != nil && fp.firstUpdateStats == nil { + fp.firstUpdateStats = newEntry + } + for fp.firstUpdateStats != nil && fp.firstUpdateStats.time <= now-mclock.AbsTime(blockDelayTimeout) { + f.pm.serverPool.adjustBlockDelay(p.poolEntry, blockDelayTimeout) + fp.firstUpdateStats = fp.firstUpdateStats.next + } + if fp.confirmedTd != nil { + for fp.firstUpdateStats != nil && fp.firstUpdateStats.td.Cmp(fp.confirmedTd) <= 0 { + f.pm.serverPool.adjustBlockDelay(p.poolEntry, time.Duration(now-fp.firstUpdateStats.time)) + fp.firstUpdateStats = fp.firstUpdateStats.next + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/control.go b/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/control.go new file mode 100644 index 00000000..49001367 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/control.go @@ -0,0 +1,429 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package flowcontrol implements a client side flow control mechanism +package flowcontrol + +import ( + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/log" +) + +const ( + // fcTimeConst is the time constant applied for MinRecharge during linear + // buffer recharge period + fcTimeConst = time.Millisecond + // DecParamDelay is applied at server side when decreasing capacity in order to + // avoid a buffer underrun error due to requests sent by the client before + // receiving the capacity update announcement + DecParamDelay = time.Second * 2 + // keepLogs is the duration of keeping logs; logging is not used if zero + keepLogs = 0 +) + +// ServerParams are the flow control parameters specified by a server for a client +// +// Note: a server can assign different amounts of capacity to each client by giving +// different parameters to them. +type ServerParams struct { + BufLimit, MinRecharge uint64 +} + +// scheduledUpdate represents a delayed flow control parameter update +type scheduledUpdate struct { + time mclock.AbsTime + params ServerParams +} + +// ClientNode is the flow control system's representation of a client +// (used in server mode only) +type ClientNode struct { + params ServerParams + bufValue int64 + lastTime mclock.AbsTime + updateSchedule []scheduledUpdate + sumCost uint64 // sum of req costs received from this client + accepted map[uint64]uint64 // value = sumCost after accepting the given req + connected bool + lock sync.Mutex + cm *ClientManager + log *logger + cmNodeFields +} + +// NewClientNode returns a new ClientNode +func NewClientNode(cm *ClientManager, params ServerParams) *ClientNode { + node := &ClientNode{ + cm: cm, + params: params, + bufValue: int64(params.BufLimit), + lastTime: cm.clock.Now(), + accepted: make(map[uint64]uint64), + connected: true, + } + if keepLogs > 0 { + node.log = newLogger(keepLogs) + } + cm.connect(node) + return node +} + +// Disconnect should be called when a client is disconnected +func (node *ClientNode) Disconnect() { + node.lock.Lock() + defer node.lock.Unlock() + + node.connected = false + node.cm.disconnect(node) +} + +// BufferStatus returns the current buffer value and limit +func (node *ClientNode) BufferStatus() (uint64, uint64) { + node.lock.Lock() + defer node.lock.Unlock() + + if !node.connected { + return 0, 0 + } + now := node.cm.clock.Now() + node.update(now) + node.cm.updateBuffer(node, 0, now) + bv := node.bufValue + if bv < 0 { + bv = 0 + } + return uint64(bv), node.params.BufLimit +} + +// OneTimeCost subtracts the given amount from the node's buffer. +// +// Note: this call can take the buffer into the negative region internally. +// In this case zero buffer value is returned by exported calls and no requests +// are accepted. +func (node *ClientNode) OneTimeCost(cost uint64) { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.cm.clock.Now() + node.update(now) + node.bufValue -= int64(cost) + node.cm.updateBuffer(node, -int64(cost), now) +} + +// Freeze notifies the client manager about a client freeze event in which case +// the total capacity allowance is slightly reduced. +func (node *ClientNode) Freeze() { + node.lock.Lock() + frozenCap := node.params.MinRecharge + node.lock.Unlock() + node.cm.reduceTotalCapacity(frozenCap) +} + +// update recalculates the buffer value at a specified time while also performing +// scheduled flow control parameter updates if necessary +func (node *ClientNode) update(now mclock.AbsTime) { + for len(node.updateSchedule) > 0 && node.updateSchedule[0].time <= now { + node.recalcBV(node.updateSchedule[0].time) + node.updateParams(node.updateSchedule[0].params, now) + node.updateSchedule = node.updateSchedule[1:] + } + node.recalcBV(now) +} + +// recalcBV recalculates the buffer value at a specified time +func (node *ClientNode) recalcBV(now mclock.AbsTime) { + dt := uint64(now - node.lastTime) + if now < node.lastTime { + dt = 0 + } + node.bufValue += int64(node.params.MinRecharge * dt / uint64(fcTimeConst)) + if node.bufValue > int64(node.params.BufLimit) { + node.bufValue = int64(node.params.BufLimit) + } + if node.log != nil { + node.log.add(now, fmt.Sprintf("updated bv=%d MRR=%d BufLimit=%d", node.bufValue, node.params.MinRecharge, node.params.BufLimit)) + } + node.lastTime = now +} + +// UpdateParams updates the flow control parameters of a client node +func (node *ClientNode) UpdateParams(params ServerParams) { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.cm.clock.Now() + node.update(now) + if params.MinRecharge >= node.params.MinRecharge { + node.updateSchedule = nil + node.updateParams(params, now) + } else { + for i, s := range node.updateSchedule { + if params.MinRecharge >= s.params.MinRecharge { + s.params = params + node.updateSchedule = node.updateSchedule[:i+1] + return + } + } + node.updateSchedule = append(node.updateSchedule, scheduledUpdate{time: now + mclock.AbsTime(DecParamDelay), params: params}) + } +} + +// updateParams updates the flow control parameters of the node +func (node *ClientNode) updateParams(params ServerParams, now mclock.AbsTime) { + diff := int64(params.BufLimit - node.params.BufLimit) + if diff > 0 { + node.bufValue += diff + } else if node.bufValue > int64(params.BufLimit) { + node.bufValue = int64(params.BufLimit) + } + node.cm.updateParams(node, params, now) +} + +// AcceptRequest returns whether a new request can be accepted and the missing +// buffer amount if it was rejected due to a buffer underrun. If accepted, maxCost +// is deducted from the flow control buffer. +func (node *ClientNode) AcceptRequest(reqID, index, maxCost uint64) (accepted bool, bufShort uint64, priority int64) { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.cm.clock.Now() + node.update(now) + if int64(maxCost) > node.bufValue { + if node.log != nil { + node.log.add(now, fmt.Sprintf("rejected reqID=%d bv=%d maxCost=%d", reqID, node.bufValue, maxCost)) + node.log.dump(now) + } + return false, maxCost - uint64(node.bufValue), 0 + } + node.bufValue -= int64(maxCost) + node.sumCost += maxCost + if node.log != nil { + node.log.add(now, fmt.Sprintf("accepted reqID=%d bv=%d maxCost=%d sumCost=%d", reqID, node.bufValue, maxCost, node.sumCost)) + } + node.accepted[index] = node.sumCost + return true, 0, node.cm.accepted(node, maxCost, now) +} + +// RequestProcessed should be called when the request has been processed +func (node *ClientNode) RequestProcessed(reqID, index, maxCost, realCost uint64) uint64 { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.cm.clock.Now() + node.update(now) + node.cm.processed(node, maxCost, realCost, now) + bv := node.bufValue + int64(node.sumCost-node.accepted[index]) + if node.log != nil { + node.log.add(now, fmt.Sprintf("processed reqID=%d bv=%d maxCost=%d realCost=%d sumCost=%d oldSumCost=%d reportedBV=%d", reqID, node.bufValue, maxCost, realCost, node.sumCost, node.accepted[index], bv)) + } + delete(node.accepted, index) + if bv < 0 { + return 0 + } + return uint64(bv) +} + +// ServerNode is the flow control system's representation of a server +// (used in client mode only) +type ServerNode struct { + clock mclock.Clock + bufEstimate uint64 + bufRecharge bool + lastTime mclock.AbsTime + params ServerParams + sumCost uint64 // sum of req costs sent to this server + pending map[uint64]uint64 // value = sumCost after sending the given req + log *logger + lock sync.RWMutex +} + +// NewServerNode returns a new ServerNode +func NewServerNode(params ServerParams, clock mclock.Clock) *ServerNode { + node := &ServerNode{ + clock: clock, + bufEstimate: params.BufLimit, + bufRecharge: false, + lastTime: clock.Now(), + params: params, + pending: make(map[uint64]uint64), + } + if keepLogs > 0 { + node.log = newLogger(keepLogs) + } + return node +} + +// UpdateParams updates the flow control parameters of the node +func (node *ServerNode) UpdateParams(params ServerParams) { + node.lock.Lock() + defer node.lock.Unlock() + + node.recalcBLE(mclock.Now()) + if params.BufLimit > node.params.BufLimit { + node.bufEstimate += params.BufLimit - node.params.BufLimit + } else { + if node.bufEstimate > params.BufLimit { + node.bufEstimate = params.BufLimit + } + } + node.params = params +} + +// recalcBLE recalculates the lowest estimate for the client's buffer value at +// the given server at the specified time +func (node *ServerNode) recalcBLE(now mclock.AbsTime) { + if now < node.lastTime { + return + } + if node.bufRecharge { + dt := uint64(now - node.lastTime) + node.bufEstimate += node.params.MinRecharge * dt / uint64(fcTimeConst) + if node.bufEstimate >= node.params.BufLimit { + node.bufEstimate = node.params.BufLimit + node.bufRecharge = false + } + } + node.lastTime = now + if node.log != nil { + node.log.add(now, fmt.Sprintf("updated bufEst=%d MRR=%d BufLimit=%d", node.bufEstimate, node.params.MinRecharge, node.params.BufLimit)) + } +} + +// safetyMargin is added to the flow control waiting time when estimated buffer value is low +const safetyMargin = time.Millisecond + +// CanSend returns the minimum waiting time required before sending a request +// with the given maximum estimated cost. Second return value is the relative +// estimated buffer level after sending the request (divided by BufLimit). +func (node *ServerNode) CanSend(maxCost uint64) (time.Duration, float64) { + node.lock.RLock() + defer node.lock.RUnlock() + + now := node.clock.Now() + node.recalcBLE(now) + maxCost += uint64(safetyMargin) * node.params.MinRecharge / uint64(fcTimeConst) + if maxCost > node.params.BufLimit { + maxCost = node.params.BufLimit + } + if node.bufEstimate >= maxCost { + relBuf := float64(node.bufEstimate-maxCost) / float64(node.params.BufLimit) + if node.log != nil { + node.log.add(now, fmt.Sprintf("canSend bufEst=%d maxCost=%d true relBuf=%f", node.bufEstimate, maxCost, relBuf)) + } + return 0, relBuf + } + timeLeft := time.Duration((maxCost - node.bufEstimate) * uint64(fcTimeConst) / node.params.MinRecharge) + if node.log != nil { + node.log.add(now, fmt.Sprintf("canSend bufEst=%d maxCost=%d false timeLeft=%v", node.bufEstimate, maxCost, timeLeft)) + } + return timeLeft, 0 +} + +// QueuedRequest should be called when the request has been assigned to the given +// server node, before putting it in the send queue. It is mandatory that requests +// are sent in the same order as the QueuedRequest calls are made. +func (node *ServerNode) QueuedRequest(reqID, maxCost uint64) { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.clock.Now() + node.recalcBLE(now) + // Note: we do not know when requests actually arrive to the server so bufRecharge + // is not turned on here if buffer was full; in this case it is going to be turned + // on by the first reply's bufValue feedback + if node.bufEstimate >= maxCost { + node.bufEstimate -= maxCost + } else { + log.Error("Queued request with insufficient buffer estimate") + node.bufEstimate = 0 + } + node.sumCost += maxCost + node.pending[reqID] = node.sumCost + if node.log != nil { + node.log.add(now, fmt.Sprintf("queued reqID=%d bufEst=%d maxCost=%d sumCost=%d", reqID, node.bufEstimate, maxCost, node.sumCost)) + } +} + +// ReceivedReply adjusts estimated buffer value according to the value included in +// the latest request reply. +func (node *ServerNode) ReceivedReply(reqID, bv uint64) { + node.lock.Lock() + defer node.lock.Unlock() + + now := node.clock.Now() + node.recalcBLE(now) + if bv > node.params.BufLimit { + bv = node.params.BufLimit + } + sc, ok := node.pending[reqID] + if !ok { + return + } + delete(node.pending, reqID) + cc := node.sumCost - sc + newEstimate := uint64(0) + if bv > cc { + newEstimate = bv - cc + } + if newEstimate > node.bufEstimate { + // Note: we never reduce the buffer estimate based on the reported value because + // this can only happen because of the delayed delivery of the latest reply. + // The lowest estimate based on the previous reply can still be considered valid. + node.bufEstimate = newEstimate + } + + node.bufRecharge = node.bufEstimate < node.params.BufLimit + node.lastTime = now + if node.log != nil { + node.log.add(now, fmt.Sprintf("received reqID=%d bufEst=%d reportedBv=%d sumCost=%d oldSumCost=%d", reqID, node.bufEstimate, bv, node.sumCost, sc)) + } +} + +// ResumeFreeze cleans all pending requests and sets the buffer estimate to the +// reported value after resuming from a frozen state +func (node *ServerNode) ResumeFreeze(bv uint64) { + node.lock.Lock() + defer node.lock.Unlock() + + for reqID := range node.pending { + delete(node.pending, reqID) + } + now := node.clock.Now() + node.recalcBLE(now) + if bv > node.params.BufLimit { + bv = node.params.BufLimit + } + node.bufEstimate = bv + node.bufRecharge = node.bufEstimate < node.params.BufLimit + node.lastTime = now + if node.log != nil { + node.log.add(now, fmt.Sprintf("unfreeze bv=%d sumCost=%d", bv, node.sumCost)) + } +} + +// DumpLogs dumps the event log if logging is used +func (node *ServerNode) DumpLogs() { + node.lock.Lock() + defer node.lock.Unlock() + + if node.log != nil { + node.log.dump(node.clock.Now()) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/manager.go b/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/manager.go new file mode 100644 index 00000000..68f1a47c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/flowcontrol/manager.go @@ -0,0 +1,462 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package flowcontrol + +import ( + "fmt" + "math" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/common/prque" +) + +// cmNodeFields are ClientNode fields used by the client manager +// Note: these fields are locked by the client manager's mutex +type cmNodeFields struct { + corrBufValue int64 // buffer value adjusted with the extra recharge amount + rcLastIntValue int64 // past recharge integrator value when corrBufValue was last updated + rcFullIntValue int64 // future recharge integrator value when corrBufValue will reach maximum + queueIndex int // position in the recharge queue (-1 if not queued) +} + +// FixedPointMultiplier is applied to the recharge integrator and the recharge curve. +// +// Note: fixed point arithmetic is required for the integrator because it is a +// constantly increasing value that can wrap around int64 limits (which behavior is +// also supported by the priority queue). A floating point value would gradually lose +// precision in this application. +// The recharge curve and all recharge values are encoded as fixed point because +// sumRecharge is frequently updated by adding or subtracting individual recharge +// values and perfect precision is required. +const FixedPointMultiplier = 1000000 + +var ( + capacityDropFactor = 0.1 + capacityRaiseTC = 1 / (3 * float64(time.Hour)) // time constant for raising the capacity factor + capacityRaiseThresholdRatio = 1.125 // total/connected capacity ratio threshold for raising the capacity factor +) + +// ClientManager controls the capacity assigned to the clients of a server. +// Since ServerParams guarantee a safe lower estimate for processable requests +// even in case of all clients being active, ClientManager calculates a +// corrigated buffer value and usually allows a higher remaining buffer value +// to be returned with each reply. +type ClientManager struct { + clock mclock.Clock + lock sync.Mutex + enabledCh chan struct{} + stop chan chan struct{} + + curve PieceWiseLinear + sumRecharge, totalRecharge, totalConnected uint64 + logTotalCap, totalCapacity float64 + logTotalCapRaiseLimit float64 + minLogTotalCap, maxLogTotalCap float64 + capacityRaiseThreshold uint64 + capLastUpdate mclock.AbsTime + totalCapacityCh chan uint64 + + // recharge integrator is increasing in each moment with a rate of + // (totalRecharge / sumRecharge)*FixedPointMultiplier or 0 if sumRecharge==0 + rcLastUpdate mclock.AbsTime // last time the recharge integrator was updated + rcLastIntValue int64 // last updated value of the recharge integrator + // recharge queue is a priority queue with currently recharging client nodes + // as elements. The priority value is rcFullIntValue which allows to quickly + // determine which client will first finish recharge. + rcQueue *prque.Prque +} + +// NewClientManager returns a new client manager. +// Client manager enhances flow control performance by allowing client buffers +// to recharge quicker than the minimum guaranteed recharge rate if possible. +// The sum of all minimum recharge rates (sumRecharge) is updated each time +// a clients starts or finishes buffer recharging. Then an adjusted total +// recharge rate is calculated using a piecewise linear recharge curve: +// +// totalRecharge = curve(sumRecharge) +// (totalRecharge >= sumRecharge is enforced) +// +// Then the "bonus" buffer recharge is distributed between currently recharging +// clients proportionally to their minimum recharge rates. +// +// Note: total recharge is proportional to the average number of parallel running +// serving threads. A recharge value of 1000000 corresponds to one thread in average. +// The maximum number of allowed serving threads should always be considerably +// higher than the targeted average number. +// +// Note 2: although it is possible to specify a curve allowing the total target +// recharge starting from zero sumRecharge, it makes sense to add a linear ramp +// starting from zero in order to not let a single low-priority client use up +// the entire server capacity and thus ensure quick availability for others at +// any moment. +func NewClientManager(curve PieceWiseLinear, clock mclock.Clock) *ClientManager { + cm := &ClientManager{ + clock: clock, + rcQueue: prque.New(func(a interface{}, i int) { a.(*ClientNode).queueIndex = i }), + capLastUpdate: clock.Now(), + stop: make(chan chan struct{}), + } + if curve != nil { + cm.SetRechargeCurve(curve) + } + go func() { + // regularly recalculate and update total capacity + for { + select { + case <-time.After(time.Minute): + cm.lock.Lock() + cm.updateTotalCapacity(cm.clock.Now(), true) + cm.lock.Unlock() + case stop := <-cm.stop: + close(stop) + return + } + } + }() + return cm +} + +// Stop stops the client manager +func (cm *ClientManager) Stop() { + stop := make(chan struct{}) + cm.stop <- stop + <-stop +} + +// SetRechargeCurve updates the recharge curve +func (cm *ClientManager) SetRechargeCurve(curve PieceWiseLinear) { + cm.lock.Lock() + defer cm.lock.Unlock() + + now := cm.clock.Now() + cm.updateRecharge(now) + cm.curve = curve + if len(curve) > 0 { + cm.totalRecharge = curve[len(curve)-1].Y + } else { + cm.totalRecharge = 0 + } +} + +// SetCapacityRaiseThreshold sets a threshold value used for raising capFactor. +// Either if the difference between total allowed and connected capacity is less +// than this threshold or if their ratio is less than capacityRaiseThresholdRatio +// then capFactor is allowed to slowly raise. +func (cm *ClientManager) SetCapacityLimits(min, max, raiseThreshold uint64) { + if min < 1 { + min = 1 + } + cm.minLogTotalCap = math.Log(float64(min)) + if max < 1 { + max = 1 + } + cm.maxLogTotalCap = math.Log(float64(max)) + cm.logTotalCap = cm.maxLogTotalCap + cm.capacityRaiseThreshold = raiseThreshold + cm.refreshCapacity() +} + +// connect should be called when a client is connected, before passing it to any +// other ClientManager function +func (cm *ClientManager) connect(node *ClientNode) { + cm.lock.Lock() + defer cm.lock.Unlock() + + now := cm.clock.Now() + cm.updateRecharge(now) + node.corrBufValue = int64(node.params.BufLimit) + node.rcLastIntValue = cm.rcLastIntValue + node.queueIndex = -1 + cm.updateTotalCapacity(now, true) + cm.totalConnected += node.params.MinRecharge + cm.updateRaiseLimit() +} + +// disconnect should be called when a client is disconnected +func (cm *ClientManager) disconnect(node *ClientNode) { + cm.lock.Lock() + defer cm.lock.Unlock() + + now := cm.clock.Now() + cm.updateRecharge(cm.clock.Now()) + cm.updateTotalCapacity(now, true) + cm.totalConnected -= node.params.MinRecharge + cm.updateRaiseLimit() +} + +// accepted is called when a request with given maximum cost is accepted. +// It returns a priority indicator for the request which is used to determine placement +// in the serving queue. Older requests have higher priority by default. If the client +// is almost out of buffer, request priority is reduced. +func (cm *ClientManager) accepted(node *ClientNode, maxCost uint64, now mclock.AbsTime) (priority int64) { + cm.lock.Lock() + defer cm.lock.Unlock() + + cm.updateNodeRc(node, -int64(maxCost), &node.params, now) + rcTime := (node.params.BufLimit - uint64(node.corrBufValue)) * FixedPointMultiplier / node.params.MinRecharge + return -int64(now) - int64(rcTime) +} + +// processed updates the client buffer according to actual request cost after +// serving has been finished. +// +// Note: processed should always be called for all accepted requests +func (cm *ClientManager) processed(node *ClientNode, maxCost, realCost uint64, now mclock.AbsTime) { + if realCost > maxCost { + realCost = maxCost + } + cm.updateBuffer(node, int64(maxCost-realCost), now) +} + +// updateBuffer recalulates the corrected buffer value, adds the given value to it +// and updates the node's actual buffer value if possible +func (cm *ClientManager) updateBuffer(node *ClientNode, add int64, now mclock.AbsTime) { + cm.lock.Lock() + defer cm.lock.Unlock() + + cm.updateNodeRc(node, add, &node.params, now) + if node.corrBufValue > node.bufValue { + if node.log != nil { + node.log.add(now, fmt.Sprintf("corrected bv=%d oldBv=%d", node.corrBufValue, node.bufValue)) + } + node.bufValue = node.corrBufValue + } +} + +// updateParams updates the flow control parameters of a client node +func (cm *ClientManager) updateParams(node *ClientNode, params ServerParams, now mclock.AbsTime) { + cm.lock.Lock() + defer cm.lock.Unlock() + + cm.updateRecharge(now) + cm.updateTotalCapacity(now, true) + cm.totalConnected += params.MinRecharge - node.params.MinRecharge + cm.updateRaiseLimit() + cm.updateNodeRc(node, 0, ¶ms, now) +} + +// updateRaiseLimit recalculates the limiting value until which logTotalCap +// can be raised when no client freeze events occur +func (cm *ClientManager) updateRaiseLimit() { + if cm.capacityRaiseThreshold == 0 { + cm.logTotalCapRaiseLimit = 0 + return + } + limit := float64(cm.totalConnected + cm.capacityRaiseThreshold) + limit2 := float64(cm.totalConnected) * capacityRaiseThresholdRatio + if limit2 > limit { + limit = limit2 + } + if limit < 1 { + limit = 1 + } + cm.logTotalCapRaiseLimit = math.Log(limit) +} + +// updateRecharge updates the recharge integrator and checks the recharge queue +// for nodes with recently filled buffers +func (cm *ClientManager) updateRecharge(now mclock.AbsTime) { + lastUpdate := cm.rcLastUpdate + cm.rcLastUpdate = now + // updating is done in multiple steps if node buffers are filled and sumRecharge + // is decreased before the given target time + for cm.sumRecharge > 0 { + sumRecharge := cm.sumRecharge + if sumRecharge > cm.totalRecharge { + sumRecharge = cm.totalRecharge + } + bonusRatio := float64(1) + v := cm.curve.ValueAt(sumRecharge) + s := float64(sumRecharge) + if v > s && s > 0 { + bonusRatio = v / s + } + dt := now - lastUpdate + // fetch the client that finishes first + rcqNode := cm.rcQueue.PopItem().(*ClientNode) // if sumRecharge > 0 then the queue cannot be empty + // check whether it has already finished + dtNext := mclock.AbsTime(float64(rcqNode.rcFullIntValue-cm.rcLastIntValue) / bonusRatio) + if dt < dtNext { + // not finished yet, put it back, update integrator according + // to current bonusRatio and return + cm.rcQueue.Push(rcqNode, -rcqNode.rcFullIntValue) + cm.rcLastIntValue += int64(bonusRatio * float64(dt)) + return + } + lastUpdate += dtNext + // finished recharging, update corrBufValue and sumRecharge if necessary and do next step + if rcqNode.corrBufValue < int64(rcqNode.params.BufLimit) { + rcqNode.corrBufValue = int64(rcqNode.params.BufLimit) + cm.sumRecharge -= rcqNode.params.MinRecharge + } + cm.rcLastIntValue = rcqNode.rcFullIntValue + } +} + +// updateNodeRc updates a node's corrBufValue and adds an external correction value. +// It also adds or removes the rcQueue entry and updates ServerParams and sumRecharge if necessary. +func (cm *ClientManager) updateNodeRc(node *ClientNode, bvc int64, params *ServerParams, now mclock.AbsTime) { + cm.updateRecharge(now) + wasFull := true + if node.corrBufValue != int64(node.params.BufLimit) { + wasFull = false + node.corrBufValue += (cm.rcLastIntValue - node.rcLastIntValue) * int64(node.params.MinRecharge) / FixedPointMultiplier + if node.corrBufValue > int64(node.params.BufLimit) { + node.corrBufValue = int64(node.params.BufLimit) + } + node.rcLastIntValue = cm.rcLastIntValue + } + node.corrBufValue += bvc + diff := int64(params.BufLimit - node.params.BufLimit) + if diff > 0 { + node.corrBufValue += diff + } + isFull := false + if node.corrBufValue >= int64(params.BufLimit) { + node.corrBufValue = int64(params.BufLimit) + isFull = true + } + if !wasFull { + cm.sumRecharge -= node.params.MinRecharge + } + if params != &node.params { + node.params = *params + } + if !isFull { + cm.sumRecharge += node.params.MinRecharge + if node.queueIndex != -1 { + cm.rcQueue.Remove(node.queueIndex) + } + node.rcLastIntValue = cm.rcLastIntValue + node.rcFullIntValue = cm.rcLastIntValue + (int64(node.params.BufLimit)-node.corrBufValue)*FixedPointMultiplier/int64(node.params.MinRecharge) + cm.rcQueue.Push(node, -node.rcFullIntValue) + } +} + +// reduceTotalCapacity reduces the total capacity allowance in case of a client freeze event +func (cm *ClientManager) reduceTotalCapacity(frozenCap uint64) { + cm.lock.Lock() + defer cm.lock.Unlock() + + ratio := float64(1) + if frozenCap < cm.totalConnected { + ratio = float64(frozenCap) / float64(cm.totalConnected) + } + now := cm.clock.Now() + cm.updateTotalCapacity(now, false) + cm.logTotalCap -= capacityDropFactor * ratio + if cm.logTotalCap < cm.minLogTotalCap { + cm.logTotalCap = cm.minLogTotalCap + } + cm.updateTotalCapacity(now, true) +} + +// updateTotalCapacity updates the total capacity factor. The capacity factor allows +// the total capacity of the system to go over the allowed total recharge value +// if clients go to frozen state sufficiently rarely. +// The capacity factor is dropped instantly by a small amount if a clients is frozen. +// It is raised slowly (with a large time constant) if the total connected capacity +// is close to the total allowed amount and no clients are frozen. +func (cm *ClientManager) updateTotalCapacity(now mclock.AbsTime, refresh bool) { + dt := now - cm.capLastUpdate + cm.capLastUpdate = now + + if cm.logTotalCap < cm.logTotalCapRaiseLimit { + cm.logTotalCap += capacityRaiseTC * float64(dt) + if cm.logTotalCap > cm.logTotalCapRaiseLimit { + cm.logTotalCap = cm.logTotalCapRaiseLimit + } + } + if cm.logTotalCap > cm.maxLogTotalCap { + cm.logTotalCap = cm.maxLogTotalCap + } + if refresh { + cm.refreshCapacity() + } +} + +// refreshCapacity recalculates the total capacity value and sends an update to the subscription +// channel if the relative change of the value since the last update is more than 0.1 percent +func (cm *ClientManager) refreshCapacity() { + totalCapacity := math.Exp(cm.logTotalCap) + if totalCapacity >= cm.totalCapacity*0.999 && totalCapacity <= cm.totalCapacity*1.001 { + return + } + cm.totalCapacity = totalCapacity + if cm.totalCapacityCh != nil { + select { + case cm.totalCapacityCh <- uint64(cm.totalCapacity): + default: + } + } +} + +// SubscribeTotalCapacity returns all future updates to the total capacity value +// through a channel and also returns the current value +func (cm *ClientManager) SubscribeTotalCapacity(ch chan uint64) uint64 { + cm.lock.Lock() + defer cm.lock.Unlock() + + cm.totalCapacityCh = ch + return uint64(cm.totalCapacity) +} + +// PieceWiseLinear is used to describe recharge curves +type PieceWiseLinear []struct{ X, Y uint64 } + +// ValueAt returns the curve's value at a given point +func (pwl PieceWiseLinear) ValueAt(x uint64) float64 { + l := 0 + h := len(pwl) + if h == 0 { + return 0 + } + for h != l { + m := (l + h) / 2 + if x > pwl[m].X { + l = m + 1 + } else { + h = m + } + } + if l == 0 { + return float64(pwl[0].Y) + } + l-- + if h == len(pwl) { + return float64(pwl[l].Y) + } + dx := pwl[h].X - pwl[l].X + if dx < 1 { + return float64(pwl[l].Y) + } + return float64(pwl[l].Y) + float64(pwl[h].Y-pwl[l].Y)*float64(x-pwl[l].X)/float64(dx) +} + +// Valid returns true if the X coordinates of the curve points are non-strictly monotonic +func (pwl PieceWiseLinear) Valid() bool { + var lastX uint64 + for _, i := range pwl { + if i.X < lastX { + return false + } + lastX = i.X + } + return true +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/freeclient.go b/vendor/github.com/ethereum/go-ethereum/les/freeclient.go new file mode 100644 index 00000000..f434ea0b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/freeclient.go @@ -0,0 +1,358 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "io" + "math" + "net" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/les/csvlogger" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +// freeClientPool implements a client database that limits the connection time +// of each client and manages accepting/rejecting incoming connections and even +// kicking out some connected clients. The pool calculates recent usage time +// for each known client (a value that increases linearly when the client is +// connected and decreases exponentially when not connected). Clients with lower +// recent usage are preferred, unknown nodes have the highest priority. Already +// connected nodes receive a small bias in their favor in order to avoid accepting +// and instantly kicking out clients. +// +// Note: the pool can use any string for client identification. Using signature +// keys for that purpose would not make sense when being known has a negative +// value for the client. Currently the LES protocol manager uses IP addresses +// (without port address) to identify clients. +type freeClientPool struct { + db ethdb.Database + lock sync.Mutex + clock mclock.Clock + closed bool + removePeer func(string) + + connectedLimit, totalLimit int + freeClientCap uint64 + logger *csvlogger.Logger + logTotalFreeConn *csvlogger.Channel + + addressMap map[string]*freeClientPoolEntry + connPool, disconnPool *prque.Prque + startupTime mclock.AbsTime + logOffsetAtStartup int64 +} + +const ( + recentUsageExpTC = time.Hour // time constant of the exponential weighting window for "recent" server usage + fixedPointMultiplier = 0x1000000 // constant to convert logarithms to fixed point format + connectedBias = time.Minute // this bias is applied in favor of already connected clients in order to avoid kicking them out very soon +) + +// newFreeClientPool creates a new free client pool +func newFreeClientPool(db ethdb.Database, freeClientCap uint64, totalLimit int, clock mclock.Clock, removePeer func(string), metricsLogger, eventLogger *csvlogger.Logger) *freeClientPool { + pool := &freeClientPool{ + db: db, + clock: clock, + addressMap: make(map[string]*freeClientPoolEntry), + connPool: prque.New(poolSetIndex), + disconnPool: prque.New(poolSetIndex), + freeClientCap: freeClientCap, + totalLimit: totalLimit, + logger: eventLogger, + logTotalFreeConn: metricsLogger.NewChannel("totalFreeConn", 0), + removePeer: removePeer, + } + pool.loadFromDb() + return pool +} + +func (f *freeClientPool) stop() { + f.lock.Lock() + f.closed = true + f.saveToDb() + f.lock.Unlock() +} + +// freeClientId returns a string identifier for the peer. Multiple peers with the +// same identifier can not be in the free client pool simultaneously. +func freeClientId(p *peer) string { + if addr, ok := p.RemoteAddr().(*net.TCPAddr); ok { + if addr.IP.IsLoopback() { + // using peer id instead of loopback ip address allows multiple free + // connections from local machine to own server + return p.id + } else { + return addr.IP.String() + } + } + return "" +} + +// registerPeer implements clientPool +func (f *freeClientPool) registerPeer(p *peer) { + if freeId := freeClientId(p); freeId != "" { + if !f.connect(freeId, p.id) { + f.removePeer(p.id) + } + } +} + +// connect should be called after a successful handshake. If the connection was +// rejected, there is no need to call disconnect. +func (f *freeClientPool) connect(address, id string) bool { + f.lock.Lock() + defer f.lock.Unlock() + + if f.closed { + return false + } + + f.logger.Event("freeClientPool: connecting from " + address + ", " + id) + if f.connectedLimit == 0 { + f.logger.Event("freeClientPool: rejected, " + id) + log.Debug("Client rejected", "address", address) + return false + } + e := f.addressMap[address] + now := f.clock.Now() + var recentUsage int64 + if e == nil { + e = &freeClientPoolEntry{address: address, index: -1, id: id} + f.addressMap[address] = e + } else { + if e.connected { + f.logger.Event("freeClientPool: already connected, " + id) + log.Debug("Client already connected", "address", address) + return false + } + recentUsage = int64(math.Exp(float64(e.logUsage-f.logOffset(now)) / fixedPointMultiplier)) + } + e.linUsage = recentUsage - int64(now) + // check whether (linUsage+connectedBias) is smaller than the highest entry in the connected pool + if f.connPool.Size() == f.connectedLimit { + i := f.connPool.PopItem().(*freeClientPoolEntry) + if e.linUsage+int64(connectedBias)-i.linUsage < 0 { + // kick it out and accept the new client + f.dropClient(i, now) + f.logger.Event("freeClientPool: kicked out, " + i.id) + } else { + // keep the old client and reject the new one + f.connPool.Push(i, i.linUsage) + f.logger.Event("freeClientPool: rejected, " + id) + log.Debug("Client rejected", "address", address) + return false + } + } + f.disconnPool.Remove(e.index) + e.connected = true + e.id = id + f.connPool.Push(e, e.linUsage) + f.logTotalFreeConn.Update(float64(uint64(f.connPool.Size()) * f.freeClientCap)) + if f.connPool.Size()+f.disconnPool.Size() > f.totalLimit { + f.disconnPool.Pop() + } + f.logger.Event("freeClientPool: accepted, " + id) + log.Debug("Client accepted", "address", address) + return true +} + +// unregisterPeer implements clientPool +func (f *freeClientPool) unregisterPeer(p *peer) { + if freeId := freeClientId(p); freeId != "" { + f.disconnect(freeId) + } +} + +// disconnect should be called when a connection is terminated. If the disconnection +// was initiated by the pool itself using disconnectFn then calling disconnect is +// not necessary but permitted. +func (f *freeClientPool) disconnect(address string) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.closed { + return + } + // Short circuit if the peer hasn't been registered. + e := f.addressMap[address] + if e == nil { + return + } + now := f.clock.Now() + if !e.connected { + log.Debug("Client already disconnected", "address", address) + return + } + + f.connPool.Remove(e.index) + f.logTotalFreeConn.Update(float64(uint64(f.connPool.Size()) * f.freeClientCap)) + f.calcLogUsage(e, now) + e.connected = false + f.disconnPool.Push(e, -e.logUsage) + f.logger.Event("freeClientPool: disconnected, " + e.id) + log.Debug("Client disconnected", "address", address) +} + +// setConnLimit sets the maximum number of free client slots and also drops +// some peers if necessary +func (f *freeClientPool) setLimits(count int, totalCap uint64) { + f.lock.Lock() + defer f.lock.Unlock() + + f.connectedLimit = int(totalCap / f.freeClientCap) + if count < f.connectedLimit { + f.connectedLimit = count + } + now := mclock.Now() + for f.connPool.Size() > f.connectedLimit { + i := f.connPool.PopItem().(*freeClientPoolEntry) + f.dropClient(i, now) + f.logger.Event("freeClientPool: setLimits kicked out, " + i.id) + } +} + +// dropClient disconnects a client and also moves it from the connected to the +// disconnected pool +func (f *freeClientPool) dropClient(i *freeClientPoolEntry, now mclock.AbsTime) { + f.connPool.Remove(i.index) + f.logTotalFreeConn.Update(float64(uint64(f.connPool.Size()) * f.freeClientCap)) + f.calcLogUsage(i, now) + i.connected = false + f.disconnPool.Push(i, -i.logUsage) + log.Debug("Client kicked out", "address", i.address) + f.removePeer(i.id) +} + +// logOffset calculates the time-dependent offset for the logarithmic +// representation of recent usage +func (f *freeClientPool) logOffset(now mclock.AbsTime) int64 { + // Note: fixedPointMultiplier acts as a multiplier here; the reason for dividing the divisor + // is to avoid int64 overflow. We assume that int64(recentUsageExpTC) >> fixedPointMultiplier. + logDecay := int64((time.Duration(now - f.startupTime)) / (recentUsageExpTC / fixedPointMultiplier)) + return f.logOffsetAtStartup + logDecay +} + +// calcLogUsage converts recent usage from linear to logarithmic representation +// when disconnecting a peer or closing the client pool +func (f *freeClientPool) calcLogUsage(e *freeClientPoolEntry, now mclock.AbsTime) { + dt := e.linUsage + int64(now) + if dt < 1 { + dt = 1 + } + e.logUsage = int64(math.Log(float64(dt))*fixedPointMultiplier) + f.logOffset(now) +} + +// freeClientPoolStorage is the RLP representation of the pool's database storage +type freeClientPoolStorage struct { + LogOffset uint64 + List []*freeClientPoolEntry +} + +// loadFromDb restores pool status from the database storage +// (automatically called at initialization) +func (f *freeClientPool) loadFromDb() { + enc, err := f.db.Get([]byte("freeClientPool")) + if err != nil { + return + } + var storage freeClientPoolStorage + err = rlp.DecodeBytes(enc, &storage) + if err != nil { + log.Error("Failed to decode client list", "err", err) + return + } + f.logOffsetAtStartup = int64(storage.LogOffset) + f.startupTime = f.clock.Now() + for _, e := range storage.List { + log.Debug("Loaded free client record", "address", e.address, "logUsage", e.logUsage) + f.addressMap[e.address] = e + f.disconnPool.Push(e, -e.logUsage) + } +} + +// saveToDb saves pool status to the database storage +// (automatically called during shutdown) +func (f *freeClientPool) saveToDb() { + now := f.clock.Now() + storage := freeClientPoolStorage{ + LogOffset: uint64(f.logOffset(now)), + List: make([]*freeClientPoolEntry, len(f.addressMap)), + } + i := 0 + for _, e := range f.addressMap { + if e.connected { + f.calcLogUsage(e, now) + } + storage.List[i] = e + i++ + } + enc, err := rlp.EncodeToBytes(storage) + if err != nil { + log.Error("Failed to encode client list", "err", err) + } else { + f.db.Put([]byte("freeClientPool"), enc) + } +} + +// freeClientPoolEntry represents a client address known by the pool. +// When connected, recent usage is calculated as linUsage + int64(clock.Now()) +// When disconnected, it is calculated as exp(logUsage - logOffset) where logOffset +// also grows linearly with time while the server is running. +// Conversion between linear and logarithmic representation happens when connecting +// or disconnecting the node. +// +// Note: linUsage and logUsage are values used with constantly growing offsets so +// even though they are close to each other at any time they may wrap around int64 +// limits over time. Comparison should be performed accordingly. +type freeClientPoolEntry struct { + address, id string + connected bool + disconnectFn func() + linUsage, logUsage int64 + index int +} + +func (e *freeClientPoolEntry) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{e.address, uint64(e.logUsage)}) +} + +func (e *freeClientPoolEntry) DecodeRLP(s *rlp.Stream) error { + var entry struct { + Address string + LogUsage uint64 + } + if err := s.Decode(&entry); err != nil { + return err + } + e.address = entry.Address + e.logUsage = int64(entry.LogUsage) + e.connected = false + e.index = -1 + return nil +} + +// poolSetIndex callback is used by both priority queues to set/update the index of +// the element in the queue. Index is needed to remove elements other than the top one. +func poolSetIndex(a interface{}, i int) { + a.(*freeClientPoolEntry).index = i +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/handler.go b/vendor/github.com/ethereum/go-ethereum/les/handler.go new file mode 100644 index 00000000..c7bd2310 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/handler.go @@ -0,0 +1,1295 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "math/big" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/les/csvlogger" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +var errTooManyInvalidRequest = errors.New("too many invalid requests made") + +const ( + softResponseLimit = 2 * 1024 * 1024 // Target maximum size of returned blocks, headers or node data. + estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header + + ethVersion = 63 // equivalent eth version for the downloader + + MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request + MaxBodyFetch = 32 // Amount of block bodies to be fetched per retrieval request + MaxReceiptFetch = 128 // Amount of transaction receipts to allow fetching per request + MaxCodeFetch = 64 // Amount of contract codes to allow fetching per request + MaxProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request + MaxHelperTrieProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request + MaxTxSend = 64 // Amount of transactions to be send per request + MaxTxStatus = 256 // Amount of transactions to queried per request + + disableClientRemovePeer = false +) + +func errResp(code errCode, format string, v ...interface{}) error { + return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) +} + +type BlockChain interface { + Config() *params.ChainConfig + HasHeader(hash common.Hash, number uint64) bool + GetHeader(hash common.Hash, number uint64) *types.Header + GetHeaderByHash(hash common.Hash) *types.Header + CurrentHeader() *types.Header + GetTd(hash common.Hash, number uint64) *big.Int + StateCache() state.Database + InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) + Rollback(chain []common.Hash) + GetHeaderByNumber(number uint64) *types.Header + GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) + Genesis() *types.Block + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription +} + +type txPool interface { + AddRemotes(txs []*types.Transaction) []error + Status(hashes []common.Hash) []core.TxStatus +} + +type ProtocolManager struct { + // Configs + chainConfig *params.ChainConfig + iConfig *light.IndexerConfig + + client bool // The indicator whether the node is light client + maxPeers int // The maximum number peers allowed to connect. + networkId uint64 // The identity of network. + + txpool txPool + txrelay *LesTxRelay + blockchain BlockChain + chainDb ethdb.Database + odr *LesOdr + server *LesServer + serverPool *serverPool + lesTopic discv5.Topic + reqDist *requestDistributor + retriever *retrieveManager + servingQueue *servingQueue + downloader *downloader.Downloader + fetcher *lightFetcher + ulc *ulc + peers *peerSet + + // channels for fetcher, syncer, txsyncLoop + newPeerCh chan *peer + quitSync chan struct{} + noMorePeers chan struct{} + + wg *sync.WaitGroup + eventMux *event.TypeMux + logger *csvlogger.Logger + + // Callbacks + synced func() bool +} + +// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable +// with the ethereum network. +func NewProtocolManager( + chainConfig *params.ChainConfig, + indexerConfig *light.IndexerConfig, + client bool, + networkId uint64, + mux *event.TypeMux, + engine consensus.Engine, + peers *peerSet, + blockchain BlockChain, + txpool txPool, + chainDb ethdb.Database, + odr *LesOdr, + txrelay *LesTxRelay, + serverPool *serverPool, + quitSync chan struct{}, + wg *sync.WaitGroup, + ulcConfig *eth.ULCConfig, synced func() bool) (*ProtocolManager, error) { + // Create the protocol manager with the base fields + manager := &ProtocolManager{ + client: client, + eventMux: mux, + blockchain: blockchain, + chainConfig: chainConfig, + iConfig: indexerConfig, + chainDb: chainDb, + odr: odr, + networkId: networkId, + txpool: txpool, + txrelay: txrelay, + serverPool: serverPool, + peers: peers, + newPeerCh: make(chan *peer), + quitSync: quitSync, + wg: wg, + noMorePeers: make(chan struct{}), + synced: synced, + } + if odr != nil { + manager.retriever = odr.retriever + manager.reqDist = odr.retriever.dist + } + + if ulcConfig != nil { + manager.ulc = newULC(ulcConfig) + } + + removePeer := manager.removePeer + if disableClientRemovePeer { + removePeer = func(id string) {} + } + if client { + var checkpoint uint64 + if cht, ok := params.TrustedCheckpoints[blockchain.Genesis().Hash()]; ok { + checkpoint = (cht.SectionIndex+1)*params.CHTFrequency - 1 + } + manager.downloader = downloader.New(checkpoint, chainDb, nil, manager.eventMux, nil, blockchain, removePeer) + manager.peers.notify((*downloaderPeerNotify)(manager)) + manager.fetcher = newLightFetcher(manager) + } + return manager, nil +} + +// removePeer initiates disconnection from a peer by removing it from the peer set +func (pm *ProtocolManager) removePeer(id string) { + pm.peers.Unregister(id) +} + +func (pm *ProtocolManager) Start(maxPeers int) { + pm.maxPeers = maxPeers + if pm.client { + go pm.syncer() + } else { + go func() { + for range pm.newPeerCh { + } + }() + } +} + +func (pm *ProtocolManager) Stop() { + // Showing a log message. During download / process this could actually + // take between 5 to 10 seconds and therefor feedback is required. + log.Info("Stopping light Ethereum protocol") + + // Quit the sync loop. + // After this send has completed, no new peers will be accepted. + pm.noMorePeers <- struct{}{} + + close(pm.quitSync) // quits syncer, fetcher + + if pm.servingQueue != nil { + pm.servingQueue.stop() + } + + // Disconnect existing sessions. + // This also closes the gate for any new registrations on the peer set. + // sessions which are already established but not added to pm.peers yet + // will exit when they try to register. + pm.peers.Close() + + // Wait for any process action + pm.wg.Wait() + + log.Info("Light Ethereum protocol stopped") +} + +// runPeer is the p2p protocol run function for the given version. +func (pm *ProtocolManager) runPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) error { + var entry *poolEntry + peer := pm.newPeer(int(version), pm.networkId, p, rw) + if pm.serverPool != nil { + entry = pm.serverPool.connect(peer, peer.Node()) + } + peer.poolEntry = entry + select { + case pm.newPeerCh <- peer: + pm.wg.Add(1) + defer pm.wg.Done() + err := pm.handle(peer) + if entry != nil { + pm.serverPool.disconnect(entry) + } + return err + case <-pm.quitSync: + if entry != nil { + pm.serverPool.disconnect(entry) + } + return p2p.DiscQuitting + } +} + +func (pm *ProtocolManager) newPeer(pv int, nv uint64, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { + var isTrusted bool + if pm.isULCEnabled() { + isTrusted = pm.ulc.isTrusted(p.ID()) + } + return newPeer(pv, nv, isTrusted, p, newMeteredMsgWriter(rw)) +} + +// handle is the callback invoked to manage the life cycle of a les peer. When +// this function terminates, the peer is disconnected. +func (pm *ProtocolManager) handle(p *peer) error { + // Ignore maxPeers if this is a trusted peer + // In server mode we try to check into the client pool after handshake + if pm.client && pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted { + pm.logger.Event("Rejected (too many peers), " + p.id) + return p2p.DiscTooManyPeers + } + // Reject light clients if server is not synced. + if !pm.client && !pm.synced() { + return p2p.DiscRequested + } + p.Log().Debug("Light Ethereum peer connected", "name", p.Name()) + + // Execute the LES handshake + var ( + genesis = pm.blockchain.Genesis() + head = pm.blockchain.CurrentHeader() + hash = head.Hash() + number = head.Number.Uint64() + td = pm.blockchain.GetTd(hash, number) + ) + if err := p.Handshake(td, hash, number, genesis.Hash(), pm.server); err != nil { + p.Log().Debug("Light Ethereum handshake failed", "err", err) + pm.logger.Event("Handshake error: " + err.Error() + ", " + p.id) + return err + } + if p.fcClient != nil { + defer p.fcClient.Disconnect() + } + + if rw, ok := p.rw.(*meteredMsgReadWriter); ok { + rw.Init(p.version) + } + + // Register the peer locally + if err := pm.peers.Register(p); err != nil { + p.Log().Error("Light Ethereum peer registration failed", "err", err) + pm.logger.Event("Peer registration error: " + err.Error() + ", " + p.id) + return err + } + pm.logger.Event("Connection established, " + p.id) + defer func() { + pm.logger.Event("Closed connection, " + p.id) + pm.removePeer(p.id) + }() + + // Register the peer in the downloader. If the downloader considers it banned, we disconnect + if pm.client { + p.lock.Lock() + head := p.headInfo + p.lock.Unlock() + if pm.fetcher != nil { + pm.fetcher.announce(p, head) + } + + if p.poolEntry != nil { + pm.serverPool.registered(p.poolEntry) + } + } + + // main loop. handle incoming messages. + for { + if err := pm.handleMsg(p); err != nil { + pm.logger.Event("Message handling error: " + err.Error() + ", " + p.id) + p.Log().Debug("Light Ethereum message handling failed", "err", err) + if p.fcServer != nil { + p.fcServer.DumpLogs() + } + return err + } + } +} + +// handleMsg is invoked whenever an inbound message is received from a remote +// peer. The remote connection is torn down upon returning any error. +func (pm *ProtocolManager) handleMsg(p *peer) error { + select { + case err := <-p.errCh: + return err + default: + } + // Read the next message from the remote peer, and ensure it's fully consumed + msg, err := p.rw.ReadMsg() + if err != nil { + return err + } + p.Log().Trace("Light Ethereum message arrived", "code", msg.Code, "bytes", msg.Size) + + p.responseCount++ + responseCount := p.responseCount + var ( + maxCost uint64 + task *servingTask + ) + + accept := func(reqID, reqCnt, maxCnt uint64) bool { + inSizeCost := func() uint64 { + if pm.server.costTracker != nil { + return pm.server.costTracker.realCost(0, msg.Size, 0) + } + return 0 + } + if p.isFrozen() || reqCnt == 0 || p.fcClient == nil || reqCnt > maxCnt { + p.fcClient.OneTimeCost(inSizeCost()) + return false + } + maxCost = p.fcCosts.getMaxCost(msg.Code, reqCnt) + gf := float64(1) + if pm.server.costTracker != nil { + gf = pm.server.costTracker.globalFactor() + if gf < 0.001 { + p.Log().Error("Invalid global cost factor", "globalFactor", gf) + gf = 1 + } + } + maxTime := uint64(float64(maxCost) / gf) + + if accepted, bufShort, servingPriority := p.fcClient.AcceptRequest(reqID, responseCount, maxCost); !accepted { + p.freezeClient() + p.Log().Warn("Request came too early", "remaining", common.PrettyDuration(time.Duration(bufShort*1000000/p.fcParams.MinRecharge))) + p.fcClient.OneTimeCost(inSizeCost()) + return false + } else { + task = pm.servingQueue.newTask(p, maxTime, servingPriority) + } + if task.start() { + return true + } + p.fcClient.RequestProcessed(reqID, responseCount, maxCost, inSizeCost()) + return false + } + + if msg.Size > ProtocolMaxMsgSize { + return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) + } + defer msg.Discard() + + var deliverMsg *Msg + + sendResponse := func(reqID, amount uint64, reply *reply, servingTime uint64) { + p.responseLock.Lock() + defer p.responseLock.Unlock() + + if p.isFrozen() { + amount = 0 + reply = nil + } + var replySize uint32 + if reply != nil { + replySize = reply.size() + } + var realCost uint64 + if pm.server.costTracker != nil { + realCost = pm.server.costTracker.realCost(servingTime, msg.Size, replySize) + if amount != 0 { + pm.server.costTracker.updateStats(msg.Code, amount, servingTime, realCost) + } + } else { + realCost = maxCost + } + bv := p.fcClient.RequestProcessed(reqID, responseCount, maxCost, realCost) + if reply != nil { + p.queueSend(func() { + if err := reply.send(bv); err != nil { + select { + case p.errCh <- err: + default: + } + } + }) + } + } + + // Handle the message depending on its contents + switch msg.Code { + case StatusMsg: + p.Log().Trace("Received status message") + // Status messages should never arrive after the handshake + return errResp(ErrExtraStatusMsg, "uncontrolled status message") + + // Block header query, collect the requested headers and reply + case AnnounceMsg: + p.Log().Trace("Received announce message") + var req announceData + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "%v: %v", msg, err) + } + + update, size := req.Update.decode() + if p.rejectUpdate(size) { + return errResp(ErrRequestRejected, "") + } + p.updateFlowControl(update) + + if req.Hash != (common.Hash{}) { + if p.announceType == announceTypeNone { + return errResp(ErrUnexpectedResponse, "") + } + if p.announceType == announceTypeSigned { + if err := req.checkSignature(p.ID(), update); err != nil { + p.Log().Trace("Invalid announcement signature", "err", err) + return err + } + p.Log().Trace("Valid announcement signature") + } + + p.Log().Trace("Announce message content", "number", req.Number, "hash", req.Hash, "td", req.Td, "reorg", req.ReorgDepth) + if pm.fetcher != nil { + pm.fetcher.announce(p, &req) + } + } + + case GetBlockHeadersMsg: + p.Log().Trace("Received block header request") + // Decode the complex header query + var req struct { + ReqID uint64 + Query getBlockHeadersData + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "%v: %v", msg, err) + } + + query := req.Query + if accept(req.ReqID, query.Amount, MaxHeaderFetch) { + go func() { + hashMode := query.Origin.Hash != (common.Hash{}) + first := true + maxNonCanonical := uint64(100) + + // Gather headers until the fetch or network limits is reached + var ( + bytes common.StorageSize + headers []*types.Header + unknown bool + ) + for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit { + if !first && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + // Retrieve the next header satisfying the query + var origin *types.Header + if hashMode { + if first { + origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash) + if origin != nil { + query.Origin.Number = origin.Number.Uint64() + } + } else { + origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number) + } + } else { + origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number) + } + if origin == nil { + atomic.AddUint32(&p.invalidCount, 1) + break + } + headers = append(headers, origin) + bytes += estHeaderRlpSize + + // Advance to the next header of the query + switch { + case hashMode && query.Reverse: + // Hash based traversal towards the genesis block + ancestor := query.Skip + 1 + if ancestor == 0 { + unknown = true + } else { + query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical) + unknown = (query.Origin.Hash == common.Hash{}) + } + case hashMode && !query.Reverse: + // Hash based traversal towards the leaf block + var ( + current = origin.Number.Uint64() + next = current + query.Skip + 1 + ) + if next <= current { + infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ") + p.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos) + unknown = true + } else { + if header := pm.blockchain.GetHeaderByNumber(next); header != nil { + nextHash := header.Hash() + expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical) + if expOldHash == query.Origin.Hash { + query.Origin.Hash, query.Origin.Number = nextHash, next + } else { + unknown = true + } + } else { + unknown = true + } + } + case query.Reverse: + // Number based traversal towards the genesis block + if query.Origin.Number >= query.Skip+1 { + query.Origin.Number -= query.Skip + 1 + } else { + unknown = true + } + case !query.Reverse: + // Number based traversal towards the leaf block + query.Origin.Number += query.Skip + 1 + } + first = false + } + sendResponse(req.ReqID, query.Amount, p.ReplyBlockHeaders(req.ReqID, headers), task.done()) + }() + } + + case BlockHeadersMsg: + if pm.downloader == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received block header response message") + // A batch of headers arrived to one of our previous requests + var resp struct { + ReqID, BV uint64 + Headers []*types.Header + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + if pm.fetcher != nil && pm.fetcher.requestedID(resp.ReqID) { + pm.fetcher.deliverHeaders(p, resp.ReqID, resp.Headers) + } else { + err := pm.downloader.DeliverHeaders(p.id, resp.Headers) + if err != nil { + log.Debug(fmt.Sprint(err)) + } + } + + case GetBlockBodiesMsg: + p.Log().Trace("Received block bodies request") + // Decode the retrieval message + var req struct { + ReqID uint64 + Hashes []common.Hash + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Gather blocks until the fetch or network limits is reached + var ( + bytes int + bodies []rlp.RawValue + ) + reqCnt := len(req.Hashes) + if accept(req.ReqID, uint64(reqCnt), MaxBodyFetch) { + go func() { + for i, hash := range req.Hashes { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + // Retrieve the requested block body, stopping if enough was found + if bytes >= softResponseLimit { + break + } + number := rawdb.ReadHeaderNumber(pm.chainDb, hash) + if number == nil { + atomic.AddUint32(&p.invalidCount, 1) + continue + } + if data := rawdb.ReadBodyRLP(pm.chainDb, hash, *number); len(data) != 0 { + bodies = append(bodies, data) + bytes += len(data) + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyBlockBodiesRLP(req.ReqID, bodies), task.done()) + }() + } + + case BlockBodiesMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received block bodies response") + // A batch of block bodies arrived to one of our previous requests + var resp struct { + ReqID, BV uint64 + Data []*types.Body + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + deliverMsg = &Msg{ + MsgType: MsgBlockBodies, + ReqID: resp.ReqID, + Obj: resp.Data, + } + + case GetCodeMsg: + p.Log().Trace("Received code request") + // Decode the retrieval message + var req struct { + ReqID uint64 + Reqs []CodeReq + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Gather state data until the fetch or network limits is reached + var ( + bytes int + data [][]byte + ) + reqCnt := len(req.Reqs) + if accept(req.ReqID, uint64(reqCnt), MaxCodeFetch) { + go func() { + for i, request := range req.Reqs { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + // Look up the root hash belonging to the request + number := rawdb.ReadHeaderNumber(pm.chainDb, request.BHash) + if number == nil { + p.Log().Warn("Failed to retrieve block num for code", "hash", request.BHash) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + header := rawdb.ReadHeader(pm.chainDb, request.BHash, *number) + if header == nil { + p.Log().Warn("Failed to retrieve header for code", "block", *number, "hash", request.BHash) + continue + } + // Refuse to search stale state data in the database since looking for + // a non-exist key is kind of expensive. + local := pm.blockchain.CurrentHeader().Number.Uint64() + if !pm.server.archiveMode && header.Number.Uint64()+core.TriesInMemory <= local { + p.Log().Debug("Reject stale code request", "number", header.Number.Uint64(), "head", local) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + triedb := pm.blockchain.StateCache().TrieDB() + + account, err := pm.getAccount(triedb, header.Root, common.BytesToHash(request.AccKey)) + if err != nil { + p.Log().Warn("Failed to retrieve account for code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "err", err) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + code, err := triedb.Node(common.BytesToHash(account.CodeHash)) + if err != nil { + p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "codehash", common.BytesToHash(account.CodeHash), "err", err) + continue + } + // Accumulate the code and abort if enough data was retrieved + data = append(data, code) + if bytes += len(code); bytes >= softResponseLimit { + break + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyCode(req.ReqID, data), task.done()) + }() + } + + case CodeMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received code response") + // A batch of node state data arrived to one of our previous requests + var resp struct { + ReqID, BV uint64 + Data [][]byte + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + deliverMsg = &Msg{ + MsgType: MsgCode, + ReqID: resp.ReqID, + Obj: resp.Data, + } + + case GetReceiptsMsg: + p.Log().Trace("Received receipts request") + // Decode the retrieval message + var req struct { + ReqID uint64 + Hashes []common.Hash + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Gather state data until the fetch or network limits is reached + var ( + bytes int + receipts []rlp.RawValue + ) + reqCnt := len(req.Hashes) + if accept(req.ReqID, uint64(reqCnt), MaxReceiptFetch) { + go func() { + for i, hash := range req.Hashes { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + if bytes >= softResponseLimit { + break + } + // Retrieve the requested block's receipts, skipping if unknown to us + var results types.Receipts + number := rawdb.ReadHeaderNumber(pm.chainDb, hash) + if number == nil { + atomic.AddUint32(&p.invalidCount, 1) + continue + } + results = rawdb.ReadRawReceipts(pm.chainDb, hash, *number) + if results == nil { + if header := pm.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash { + continue + } + } + // If known, encode and queue for response packet + if encoded, err := rlp.EncodeToBytes(results); err != nil { + log.Error("Failed to encode receipt", "err", err) + } else { + receipts = append(receipts, encoded) + bytes += len(encoded) + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyReceiptsRLP(req.ReqID, receipts), task.done()) + }() + } + + case ReceiptsMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received receipts response") + // A batch of receipts arrived to one of our previous requests + var resp struct { + ReqID, BV uint64 + Receipts []types.Receipts + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + deliverMsg = &Msg{ + MsgType: MsgReceipts, + ReqID: resp.ReqID, + Obj: resp.Receipts, + } + + case GetProofsV2Msg: + p.Log().Trace("Received les/2 proofs request") + // Decode the retrieval message + var req struct { + ReqID uint64 + Reqs []ProofReq + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Gather state data until the fetch or network limits is reached + var ( + lastBHash common.Hash + root common.Hash + ) + reqCnt := len(req.Reqs) + if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) { + go func() { + nodes := light.NewNodeSet() + + for i, request := range req.Reqs { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + // Look up the root hash belonging to the request + var ( + number *uint64 + header *types.Header + trie state.Trie + ) + if request.BHash != lastBHash { + root, lastBHash = common.Hash{}, request.BHash + + if number = rawdb.ReadHeaderNumber(pm.chainDb, request.BHash); number == nil { + p.Log().Warn("Failed to retrieve block num for proof", "hash", request.BHash) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + if header = rawdb.ReadHeader(pm.chainDb, request.BHash, *number); header == nil { + p.Log().Warn("Failed to retrieve header for proof", "block", *number, "hash", request.BHash) + continue + } + // Refuse to search stale state data in the database since looking for + // a non-exist key is kind of expensive. + local := pm.blockchain.CurrentHeader().Number.Uint64() + if !pm.server.archiveMode && header.Number.Uint64()+core.TriesInMemory <= local { + p.Log().Debug("Reject stale trie request", "number", header.Number.Uint64(), "head", local) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + root = header.Root + } + // If a header lookup failed (non existent), ignore subsequent requests for the same header + if root == (common.Hash{}) { + atomic.AddUint32(&p.invalidCount, 1) + continue + } + // Open the account or storage trie for the request + statedb := pm.blockchain.StateCache() + + switch len(request.AccKey) { + case 0: + // No account key specified, open an account trie + trie, err = statedb.OpenTrie(root) + if trie == nil || err != nil { + p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "root", root, "err", err) + continue + } + default: + // Account key specified, open a storage trie + account, err := pm.getAccount(statedb.TrieDB(), root, common.BytesToHash(request.AccKey)) + if err != nil { + p.Log().Warn("Failed to retrieve account for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "err", err) + atomic.AddUint32(&p.invalidCount, 1) + continue + } + trie, err = statedb.OpenStorageTrie(common.BytesToHash(request.AccKey), account.Root) + if trie == nil || err != nil { + p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "root", account.Root, "err", err) + continue + } + } + // Prove the user's request from the account or stroage trie + if err := trie.Prove(request.Key, request.FromLevel, nodes); err != nil { + p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err) + continue + } + if nodes.DataSize() >= softResponseLimit { + break + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyProofsV2(req.ReqID, nodes.NodeList()), task.done()) + }() + } + + case ProofsV2Msg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received les/2 proofs response") + // A batch of merkle proofs arrived to one of our previous requests + var resp struct { + ReqID, BV uint64 + Data light.NodeList + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + deliverMsg = &Msg{ + MsgType: MsgProofsV2, + ReqID: resp.ReqID, + Obj: resp.Data, + } + + case GetHelperTrieProofsMsg: + p.Log().Trace("Received helper trie proof request") + // Decode the retrieval message + var req struct { + ReqID uint64 + Reqs []HelperTrieReq + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + // Gather state data until the fetch or network limits is reached + var ( + auxBytes int + auxData [][]byte + ) + reqCnt := len(req.Reqs) + if accept(req.ReqID, uint64(reqCnt), MaxHelperTrieProofsFetch) { + go func() { + + var ( + lastIdx uint64 + lastType uint + root common.Hash + auxTrie *trie.Trie + ) + nodes := light.NewNodeSet() + for i, request := range req.Reqs { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + if auxTrie == nil || request.Type != lastType || request.TrieIdx != lastIdx { + auxTrie, lastType, lastIdx = nil, request.Type, request.TrieIdx + + var prefix string + if root, prefix = pm.getHelperTrie(request.Type, request.TrieIdx); root != (common.Hash{}) { + auxTrie, _ = trie.New(root, trie.NewDatabase(rawdb.NewTable(pm.chainDb, prefix))) + } + } + if request.AuxReq == auxRoot { + var data []byte + if root != (common.Hash{}) { + data = root[:] + } + auxData = append(auxData, data) + auxBytes += len(data) + } else { + if auxTrie != nil { + auxTrie.Prove(request.Key, request.FromLevel, nodes) + } + if request.AuxReq != 0 { + data := pm.getHelperTrieAuxData(request) + auxData = append(auxData, data) + auxBytes += len(data) + } + } + if nodes.DataSize()+auxBytes >= softResponseLimit { + break + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyHelperTrieProofs(req.ReqID, HelperTrieResps{Proofs: nodes.NodeList(), AuxData: auxData}), task.done()) + }() + } + + case HelperTrieProofsMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received helper trie proof response") + var resp struct { + ReqID, BV uint64 + Data HelperTrieResps + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + deliverMsg = &Msg{ + MsgType: MsgHelperTrieProofs, + ReqID: resp.ReqID, + Obj: resp.Data, + } + + case SendTxV2Msg: + if pm.txpool == nil { + return errResp(ErrRequestRejected, "") + } + // Transactions arrived, parse all of them and deliver to the pool + var req struct { + ReqID uint64 + Txs []*types.Transaction + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + reqCnt := len(req.Txs) + if accept(req.ReqID, uint64(reqCnt), MaxTxSend) { + go func() { + stats := make([]light.TxStatus, len(req.Txs)) + for i, tx := range req.Txs { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + hash := tx.Hash() + stats[i] = pm.txStatus(hash) + if stats[i].Status == core.TxStatusUnknown { + if errs := pm.txpool.AddRemotes([]*types.Transaction{tx}); errs[0] != nil { + stats[i].Error = errs[0].Error() + continue + } + stats[i] = pm.txStatus(hash) + } + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyTxStatus(req.ReqID, stats), task.done()) + }() + } + + case GetTxStatusMsg: + if pm.txpool == nil { + return errResp(ErrUnexpectedResponse, "") + } + // Transactions arrived, parse all of them and deliver to the pool + var req struct { + ReqID uint64 + Hashes []common.Hash + } + if err := msg.Decode(&req); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + reqCnt := len(req.Hashes) + if accept(req.ReqID, uint64(reqCnt), MaxTxStatus) { + go func() { + stats := make([]light.TxStatus, len(req.Hashes)) + for i, hash := range req.Hashes { + if i != 0 && !task.waitOrStop() { + sendResponse(req.ReqID, 0, nil, task.servingTime) + return + } + stats[i] = pm.txStatus(hash) + } + sendResponse(req.ReqID, uint64(reqCnt), p.ReplyTxStatus(req.ReqID, stats), task.done()) + }() + } + + case TxStatusMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + + p.Log().Trace("Received tx status response") + var resp struct { + ReqID, BV uint64 + Status []light.TxStatus + } + if err := msg.Decode(&resp); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + + p.fcServer.ReceivedReply(resp.ReqID, resp.BV) + + p.Log().Trace("Received helper trie proof response") + deliverMsg = &Msg{ + MsgType: MsgTxStatus, + ReqID: resp.ReqID, + Obj: resp.Status, + } + + case StopMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + p.freezeServer(true) + pm.retriever.frozen(p) + p.Log().Warn("Service stopped") + + case ResumeMsg: + if pm.odr == nil { + return errResp(ErrUnexpectedResponse, "") + } + var bv uint64 + if err := msg.Decode(&bv); err != nil { + return errResp(ErrDecode, "msg %v: %v", msg, err) + } + p.fcServer.ResumeFreeze(bv) + p.freezeServer(false) + p.Log().Warn("Service resumed") + + default: + p.Log().Trace("Received unknown message", "code", msg.Code) + return errResp(ErrInvalidMsgCode, "%v", msg.Code) + } + + if deliverMsg != nil { + err := pm.retriever.deliver(p, deliverMsg) + if err != nil { + p.responseErrors++ + if p.responseErrors > maxResponseErrors { + return err + } + } + } + // If the client has made too much invalid request(e.g. request a non-exist data), + // reject them to prevent SPAM attack. + if atomic.LoadUint32(&p.invalidCount) > maxRequestErrors { + return errTooManyInvalidRequest + } + return nil +} + +// getAccount retrieves an account from the state based at root. +func (pm *ProtocolManager) getAccount(triedb *trie.Database, root, hash common.Hash) (state.Account, error) { + trie, err := trie.New(root, triedb) + if err != nil { + return state.Account{}, err + } + blob, err := trie.TryGet(hash[:]) + if err != nil { + return state.Account{}, err + } + var account state.Account + if err = rlp.DecodeBytes(blob, &account); err != nil { + return state.Account{}, err + } + return account, nil +} + +// getHelperTrie returns the post-processed trie root for the given trie ID and section index +func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) { + switch id { + case htCanonical: + sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.iConfig.ChtSize-1) + return light.GetChtRoot(pm.chainDb, idx, sectionHead), light.ChtTablePrefix + case htBloomBits: + sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.iConfig.BloomTrieSize-1) + return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix + } + return common.Hash{}, "" +} + +// getHelperTrieAuxData returns requested auxiliary data for the given HelperTrie request +func (pm *ProtocolManager) getHelperTrieAuxData(req HelperTrieReq) []byte { + if req.Type == htCanonical && req.AuxReq == auxHeader && len(req.Key) == 8 { + blockNum := binary.BigEndian.Uint64(req.Key) + hash := rawdb.ReadCanonicalHash(pm.chainDb, blockNum) + return rawdb.ReadHeaderRLP(pm.chainDb, hash, blockNum) + } + return nil +} + +func (pm *ProtocolManager) txStatus(hash common.Hash) light.TxStatus { + var stat light.TxStatus + stat.Status = pm.txpool.Status([]common.Hash{hash})[0] + // If the transaction is unknown to the pool, try looking it up locally + if stat.Status == core.TxStatusUnknown { + if tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(pm.chainDb, hash); tx != nil { + stat.Status = core.TxStatusIncluded + stat.Lookup = &rawdb.LegacyTxLookupEntry{BlockHash: blockHash, BlockIndex: blockNumber, Index: txIndex} + } + } + return stat +} + +// isULCEnabled returns true if we can use ULC +func (pm *ProtocolManager) isULCEnabled() bool { + if pm.ulc == nil || len(pm.ulc.trustedKeys) == 0 { + return false + } + return true +} + +// downloaderPeerNotify implements peerSetNotify +type downloaderPeerNotify ProtocolManager + +type peerConnection struct { + manager *ProtocolManager + peer *peer +} + +func (pc *peerConnection) Head() (common.Hash, *big.Int) { + return pc.peer.HeadAndTd() +} + +func (pc *peerConnection) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { + reqID := genReqID() + rq := &distReq{ + getCost: func(dp distPeer) uint64 { + peer := dp.(*peer) + return peer.GetRequestCost(GetBlockHeadersMsg, amount) + }, + canSend: func(dp distPeer) bool { + return dp.(*peer) == pc.peer + }, + request: func(dp distPeer) func() { + peer := dp.(*peer) + cost := peer.GetRequestCost(GetBlockHeadersMsg, amount) + peer.fcServer.QueuedRequest(reqID, cost) + return func() { peer.RequestHeadersByHash(reqID, cost, origin, amount, skip, reverse) } + }, + } + _, ok := <-pc.manager.reqDist.queue(rq) + if !ok { + return light.ErrNoPeers + } + return nil +} + +func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { + reqID := genReqID() + rq := &distReq{ + getCost: func(dp distPeer) uint64 { + peer := dp.(*peer) + return peer.GetRequestCost(GetBlockHeadersMsg, amount) + }, + canSend: func(dp distPeer) bool { + return dp.(*peer) == pc.peer + }, + request: func(dp distPeer) func() { + peer := dp.(*peer) + cost := peer.GetRequestCost(GetBlockHeadersMsg, amount) + peer.fcServer.QueuedRequest(reqID, cost) + return func() { peer.RequestHeadersByNumber(reqID, cost, origin, amount, skip, reverse) } + }, + } + _, ok := <-pc.manager.reqDist.queue(rq) + if !ok { + return light.ErrNoPeers + } + return nil +} + +func (d *downloaderPeerNotify) registerPeer(p *peer) { + pm := (*ProtocolManager)(d) + pc := &peerConnection{ + manager: pm, + peer: p, + } + pm.downloader.RegisterLightPeer(p.id, ethVersion, pc) +} + +func (d *downloaderPeerNotify) unregisterPeer(p *peer) { + pm := (*ProtocolManager)(d) + pm.downloader.UnregisterPeer(p.id) +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/odr.go b/vendor/github.com/ethereum/go-ethereum/les/odr.go new file mode 100644 index 00000000..9176924c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/odr.go @@ -0,0 +1,131 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "context" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" +) + +// LesOdr implements light.OdrBackend +type LesOdr struct { + db ethdb.Database + indexerConfig *light.IndexerConfig + chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer + retriever *retrieveManager + stop chan struct{} +} + +func NewLesOdr(db ethdb.Database, config *light.IndexerConfig, retriever *retrieveManager) *LesOdr { + return &LesOdr{ + db: db, + indexerConfig: config, + retriever: retriever, + stop: make(chan struct{}), + } +} + +// Stop cancels all pending retrievals +func (odr *LesOdr) Stop() { + close(odr.stop) +} + +// Database returns the backing database +func (odr *LesOdr) Database() ethdb.Database { + return odr.db +} + +// SetIndexers adds the necessary chain indexers to the ODR backend +func (odr *LesOdr) SetIndexers(chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer) { + odr.chtIndexer = chtIndexer + odr.bloomTrieIndexer = bloomTrieIndexer + odr.bloomIndexer = bloomIndexer +} + +// ChtIndexer returns the CHT chain indexer +func (odr *LesOdr) ChtIndexer() *core.ChainIndexer { + return odr.chtIndexer +} + +// BloomTrieIndexer returns the bloom trie chain indexer +func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer { + return odr.bloomTrieIndexer +} + +// BloomIndexer returns the bloombits chain indexer +func (odr *LesOdr) BloomIndexer() *core.ChainIndexer { + return odr.bloomIndexer +} + +// IndexerConfig returns the indexer config. +func (odr *LesOdr) IndexerConfig() *light.IndexerConfig { + return odr.indexerConfig +} + +const ( + MsgBlockBodies = iota + MsgCode + MsgReceipts + MsgProofsV2 + MsgHelperTrieProofs + MsgTxStatus +) + +// Msg encodes a LES message that delivers reply data for a request +type Msg struct { + MsgType int + ReqID uint64 + Obj interface{} +} + +// Retrieve tries to fetch an object from the LES network. +// If the network retrieval was successful, it stores the object in local db. +func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error) { + lreq := LesRequest(req) + + reqID := genReqID() + rq := &distReq{ + getCost: func(dp distPeer) uint64 { + return lreq.GetCost(dp.(*peer)) + }, + canSend: func(dp distPeer) bool { + p := dp.(*peer) + if !p.isOnlyAnnounce { + return lreq.CanSend(p) + } + return false + }, + request: func(dp distPeer) func() { + p := dp.(*peer) + cost := lreq.GetCost(p) + p.fcServer.QueuedRequest(reqID, cost) + return func() { lreq.Request(reqID, p) } + }, + } + + if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil { + // retrieved from network, store in db + req.StoreResult(odr.db) + } else { + log.Debug("Failed to retrieve data from network", "err", err) + } + return +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/odr_requests.go b/vendor/github.com/ethereum/go-ethereum/les/odr_requests.go new file mode 100644 index 00000000..89c60917 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/odr_requests.go @@ -0,0 +1,534 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "encoding/binary" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +var ( + errInvalidMessageType = errors.New("invalid message type") + errInvalidEntryCount = errors.New("invalid number of response entries") + errHeaderUnavailable = errors.New("header unavailable") + errTxHashMismatch = errors.New("transaction hash mismatch") + errUncleHashMismatch = errors.New("uncle hash mismatch") + errReceiptHashMismatch = errors.New("receipt hash mismatch") + errDataHashMismatch = errors.New("data hash mismatch") + errCHTHashMismatch = errors.New("cht hash mismatch") + errCHTNumberMismatch = errors.New("cht number mismatch") + errUselessNodes = errors.New("useless nodes in merkle proof nodeset") +) + +type LesOdrRequest interface { + GetCost(*peer) uint64 + CanSend(*peer) bool + Request(uint64, *peer) error + Validate(ethdb.Database, *Msg) error +} + +func LesRequest(req light.OdrRequest) LesOdrRequest { + switch r := req.(type) { + case *light.BlockRequest: + return (*BlockRequest)(r) + case *light.ReceiptsRequest: + return (*ReceiptsRequest)(r) + case *light.TrieRequest: + return (*TrieRequest)(r) + case *light.CodeRequest: + return (*CodeRequest)(r) + case *light.ChtRequest: + return (*ChtRequest)(r) + case *light.BloomRequest: + return (*BloomRequest)(r) + case *light.TxStatusRequest: + return (*TxStatusRequest)(r) + default: + return nil + } +} + +// BlockRequest is the ODR request type for block bodies +type BlockRequest light.BlockRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *BlockRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetBlockBodiesMsg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *BlockRequest) CanSend(peer *peer) bool { + return peer.HasBlock(r.Hash, r.Number, false) +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *BlockRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting block body", "hash", r.Hash) + return peer.RequestBodies(reqID, r.GetCost(peer), []common.Hash{r.Hash}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *BlockRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating block body", "hash", r.Hash) + + // Ensure we have a correct message with a single block body + if msg.MsgType != MsgBlockBodies { + return errInvalidMessageType + } + bodies := msg.Obj.([]*types.Body) + if len(bodies) != 1 { + return errInvalidEntryCount + } + body := bodies[0] + + // Retrieve our stored header and validate block content against it + header := rawdb.ReadHeader(db, r.Hash, r.Number) + if header == nil { + return errHeaderUnavailable + } + if header.TxHash != types.DeriveSha(types.Transactions(body.Transactions)) { + return errTxHashMismatch + } + if header.UncleHash != types.CalcUncleHash(body.Uncles) { + return errUncleHashMismatch + } + // Validations passed, encode and store RLP + data, err := rlp.EncodeToBytes(body) + if err != nil { + return err + } + r.Rlp = data + return nil +} + +// ReceiptsRequest is the ODR request type for block receipts by block hash +type ReceiptsRequest light.ReceiptsRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *ReceiptsRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetReceiptsMsg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *ReceiptsRequest) CanSend(peer *peer) bool { + return peer.HasBlock(r.Hash, r.Number, false) +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *ReceiptsRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting block receipts", "hash", r.Hash) + return peer.RequestReceipts(reqID, r.GetCost(peer), []common.Hash{r.Hash}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *ReceiptsRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating block receipts", "hash", r.Hash) + + // Ensure we have a correct message with a single block receipt + if msg.MsgType != MsgReceipts { + return errInvalidMessageType + } + receipts := msg.Obj.([]types.Receipts) + if len(receipts) != 1 { + return errInvalidEntryCount + } + receipt := receipts[0] + + // Retrieve our stored header and validate receipt content against it + header := rawdb.ReadHeader(db, r.Hash, r.Number) + if header == nil { + return errHeaderUnavailable + } + if header.ReceiptHash != types.DeriveSha(receipt) { + return errReceiptHashMismatch + } + // Validations passed, store and return + r.Receipts = receipt + return nil +} + +type ProofReq struct { + BHash common.Hash + AccKey, Key []byte + FromLevel uint +} + +// ODR request type for state/storage trie entries, see LesOdrRequest interface +type TrieRequest light.TrieRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *TrieRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetProofsV2Msg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *TrieRequest) CanSend(peer *peer) bool { + return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber, true) +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *TrieRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting trie proof", "root", r.Id.Root, "key", r.Key) + req := ProofReq{ + BHash: r.Id.BlockHash, + AccKey: r.Id.AccKey, + Key: r.Key, + } + return peer.RequestProofs(reqID, r.GetCost(peer), []ProofReq{req}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *TrieRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating trie proof", "root", r.Id.Root, "key", r.Key) + + if msg.MsgType != MsgProofsV2 { + return errInvalidMessageType + } + proofs := msg.Obj.(light.NodeList) + // Verify the proof and store if checks out + nodeSet := proofs.NodeSet() + reads := &readTraceDB{db: nodeSet} + if _, _, err := trie.VerifyProof(r.Id.Root, r.Key, reads); err != nil { + return fmt.Errorf("merkle proof verification failed: %v", err) + } + // check if all nodes have been read by VerifyProof + if len(reads.reads) != nodeSet.KeyCount() { + return errUselessNodes + } + r.Proof = nodeSet + return nil +} + +type CodeReq struct { + BHash common.Hash + AccKey []byte +} + +// ODR request type for node data (used for retrieving contract code), see LesOdrRequest interface +type CodeRequest light.CodeRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *CodeRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetCodeMsg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *CodeRequest) CanSend(peer *peer) bool { + return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber, true) +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *CodeRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting code data", "hash", r.Hash) + req := CodeReq{ + BHash: r.Id.BlockHash, + AccKey: r.Id.AccKey, + } + return peer.RequestCode(reqID, r.GetCost(peer), []CodeReq{req}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *CodeRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating code data", "hash", r.Hash) + + // Ensure we have a correct message with a single code element + if msg.MsgType != MsgCode { + return errInvalidMessageType + } + reply := msg.Obj.([][]byte) + if len(reply) != 1 { + return errInvalidEntryCount + } + data := reply[0] + + // Verify the data and store if checks out + if hash := crypto.Keccak256Hash(data); r.Hash != hash { + return errDataHashMismatch + } + r.Data = data + return nil +} + +const ( + // helper trie type constants + htCanonical = iota // Canonical hash trie + htBloomBits // BloomBits trie + + // applicable for all helper trie requests + auxRoot = 1 + // applicable for htCanonical + auxHeader = 2 +) + +type HelperTrieReq struct { + Type uint + TrieIdx uint64 + Key []byte + FromLevel, AuxReq uint +} + +type HelperTrieResps struct { // describes all responses, not just a single one + Proofs light.NodeList + AuxData [][]byte +} + +// ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface +type ChtRequest light.ChtRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *ChtRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetHelperTrieProofsMsg, 1) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *ChtRequest) CanSend(peer *peer) bool { + peer.lock.RLock() + defer peer.lock.RUnlock() + + return peer.headInfo.Number >= r.Config.ChtConfirms && r.ChtNum <= (peer.headInfo.Number-r.Config.ChtConfirms)/r.Config.ChtSize +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *ChtRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting CHT", "cht", r.ChtNum, "block", r.BlockNum) + var encNum [8]byte + binary.BigEndian.PutUint64(encNum[:], r.BlockNum) + req := HelperTrieReq{ + Type: htCanonical, + TrieIdx: r.ChtNum, + Key: encNum[:], + AuxReq: auxHeader, + } + return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), []HelperTrieReq{req}) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating CHT", "cht", r.ChtNum, "block", r.BlockNum) + + if msg.MsgType != MsgHelperTrieProofs { + return errInvalidMessageType + } + resp := msg.Obj.(HelperTrieResps) + if len(resp.AuxData) != 1 { + return errInvalidEntryCount + } + nodeSet := resp.Proofs.NodeSet() + headerEnc := resp.AuxData[0] + if len(headerEnc) == 0 { + return errHeaderUnavailable + } + header := new(types.Header) + if err := rlp.DecodeBytes(headerEnc, header); err != nil { + return errHeaderUnavailable + } + + // Verify the CHT + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], r.BlockNum) + + reads := &readTraceDB{db: nodeSet} + value, _, err := trie.VerifyProof(r.ChtRoot, encNumber[:], reads) + if err != nil { + return fmt.Errorf("merkle proof verification failed: %v", err) + } + if len(reads.reads) != nodeSet.KeyCount() { + return errUselessNodes + } + + var node light.ChtNode + if err := rlp.DecodeBytes(value, &node); err != nil { + return err + } + if node.Hash != header.Hash() { + return errCHTHashMismatch + } + if r.BlockNum != header.Number.Uint64() { + return errCHTNumberMismatch + } + // Verifications passed, store and return + r.Header = header + r.Proof = nodeSet + r.Td = node.Td + return nil +} + +type BloomReq struct { + BloomTrieNum, BitIdx, SectionIndex, FromLevel uint64 +} + +// ODR request type for requesting headers by Canonical Hash Trie, see LesOdrRequest interface +type BloomRequest light.BloomRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *BloomRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetHelperTrieProofsMsg, len(r.SectionIndexList)) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *BloomRequest) CanSend(peer *peer) bool { + peer.lock.RLock() + defer peer.lock.RUnlock() + + if peer.version < lpv2 { + return false + } + return peer.headInfo.Number >= r.Config.BloomTrieConfirms && r.BloomTrieNum <= (peer.headInfo.Number-r.Config.BloomTrieConfirms)/r.Config.BloomTrieSize +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *BloomRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIndexList) + reqs := make([]HelperTrieReq, len(r.SectionIndexList)) + + var encNumber [10]byte + binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx)) + + for i, sectionIdx := range r.SectionIndexList { + binary.BigEndian.PutUint64(encNumber[2:], sectionIdx) + reqs[i] = HelperTrieReq{ + Type: htBloomBits, + TrieIdx: r.BloomTrieNum, + Key: common.CopyBytes(encNumber[:]), + } + } + return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), reqs) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating BloomBits", "bloomTrie", r.BloomTrieNum, "bitIdx", r.BitIdx, "sections", r.SectionIndexList) + + // Ensure we have a correct message with a single proof element + if msg.MsgType != MsgHelperTrieProofs { + return errInvalidMessageType + } + resps := msg.Obj.(HelperTrieResps) + proofs := resps.Proofs + nodeSet := proofs.NodeSet() + reads := &readTraceDB{db: nodeSet} + + r.BloomBits = make([][]byte, len(r.SectionIndexList)) + + // Verify the proofs + var encNumber [10]byte + binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx)) + + for i, idx := range r.SectionIndexList { + binary.BigEndian.PutUint64(encNumber[2:], idx) + value, _, err := trie.VerifyProof(r.BloomTrieRoot, encNumber[:], reads) + if err != nil { + return err + } + r.BloomBits[i] = value + } + + if len(reads.reads) != nodeSet.KeyCount() { + return errUselessNodes + } + r.Proofs = nodeSet + return nil +} + +// TxStatusRequest is the ODR request type for transaction status +type TxStatusRequest light.TxStatusRequest + +// GetCost returns the cost of the given ODR request according to the serving +// peer's cost table (implementation of LesOdrRequest) +func (r *TxStatusRequest) GetCost(peer *peer) uint64 { + return peer.GetRequestCost(GetTxStatusMsg, len(r.Hashes)) +} + +// CanSend tells if a certain peer is suitable for serving the given request +func (r *TxStatusRequest) CanSend(peer *peer) bool { + return peer.version >= lpv2 +} + +// Request sends an ODR request to the LES network (implementation of LesOdrRequest) +func (r *TxStatusRequest) Request(reqID uint64, peer *peer) error { + peer.Log().Debug("Requesting transaction status", "count", len(r.Hashes)) + return peer.RequestTxStatus(reqID, r.GetCost(peer), r.Hashes) +} + +// Valid processes an ODR request reply message from the LES network +// returns true and stores results in memory if the message was a valid reply +// to the request (implementation of LesOdrRequest) +func (r *TxStatusRequest) Validate(db ethdb.Database, msg *Msg) error { + log.Debug("Validating transaction status", "count", len(r.Hashes)) + + // Ensure we have a correct message with a single block body + if msg.MsgType != MsgTxStatus { + return errInvalidMessageType + } + status := msg.Obj.([]light.TxStatus) + if len(status) != len(r.Hashes) { + return errInvalidEntryCount + } + r.Status = status + return nil +} + +// readTraceDB stores the keys of database reads. We use this to check that received node +// sets contain only the trie nodes necessary to make proofs pass. +type readTraceDB struct { + db ethdb.KeyValueReader + reads map[string]struct{} +} + +// Get returns a stored node +func (db *readTraceDB) Get(k []byte) ([]byte, error) { + if db.reads == nil { + db.reads = make(map[string]struct{}) + } + db.reads[string(k)] = struct{}{} + return db.db.Get(k) +} + +// Has returns true if the node set contains the given key +func (db *readTraceDB) Has(key []byte) (bool, error) { + _, err := db.Get(key) + return err == nil, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/peer.go b/vendor/github.com/ethereum/go-ethereum/les/peer.go new file mode 100644 index 00000000..a615c9b7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/peer.go @@ -0,0 +1,878 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "errors" + "fmt" + "math/big" + "math/rand" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/les/flowcontrol" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + errClosed = errors.New("peer set is closed") + errAlreadyRegistered = errors.New("peer is already registered") + errNotRegistered = errors.New("peer is not registered") +) + +const ( + maxRequestErrors = 20 // number of invalid requests tolerated (makes the protocol less brittle but still avoids spam) + maxResponseErrors = 50 // number of invalid responses tolerated (makes the protocol less brittle but still avoids spam) +) + +// capacity limitation for parameter updates +const ( + allowedUpdateBytes = 100000 // initial/maximum allowed update size + allowedUpdateRate = time.Millisecond * 10 // time constant for recharging one byte of allowance +) + +const ( + freezeTimeBase = time.Millisecond * 700 // fixed component of client freeze time + freezeTimeRandom = time.Millisecond * 600 // random component of client freeze time + freezeCheckPeriod = time.Millisecond * 100 // buffer value recheck period after initial freeze time has elapsed +) + +// if the total encoded size of a sent transaction batch is over txSizeCostLimit +// per transaction then the request cost is calculated as proportional to the +// encoded size instead of the transaction count +const txSizeCostLimit = 0x4000 + +const ( + announceTypeNone = iota + announceTypeSimple + announceTypeSigned +) + +type peer struct { + *p2p.Peer + rw p2p.MsgReadWriter + + version int // Protocol version negotiated + network uint64 // Network ID being on + + announceType uint64 + + id string + + headInfo *announceData + lock sync.RWMutex + + sendQueue *execQueue + + errCh chan error + // responseLock ensures that responses are queued in the same order as + // RequestProcessed is called + responseLock sync.Mutex + responseCount uint64 + invalidCount uint32 + + poolEntry *poolEntry + hasBlock func(common.Hash, uint64, bool) bool + responseErrors int + updateCounter uint64 + updateTime mclock.AbsTime + frozen uint32 // 1 if client is in frozen state + + fcClient *flowcontrol.ClientNode // nil if the peer is server only + fcServer *flowcontrol.ServerNode // nil if the peer is client only + fcParams flowcontrol.ServerParams + fcCosts requestCostTable + + isTrusted bool + isOnlyAnnounce bool + chainSince, chainRecent uint64 + stateSince, stateRecent uint64 +} + +func newPeer(version int, network uint64, isTrusted bool, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { + return &peer{ + Peer: p, + rw: rw, + version: version, + network: network, + id: fmt.Sprintf("%x", p.ID().Bytes()), + isTrusted: isTrusted, + errCh: make(chan error, 1), + } +} + +// rejectUpdate returns true if a parameter update has to be rejected because +// the size and/or rate of updates exceed the capacity limitation +func (p *peer) rejectUpdate(size uint64) bool { + now := mclock.Now() + if p.updateCounter == 0 { + p.updateTime = now + } else { + dt := now - p.updateTime + r := uint64(dt / mclock.AbsTime(allowedUpdateRate)) + if p.updateCounter > r { + p.updateCounter -= r + p.updateTime += mclock.AbsTime(allowedUpdateRate * time.Duration(r)) + } else { + p.updateCounter = 0 + p.updateTime = now + } + } + p.updateCounter += size + return p.updateCounter > allowedUpdateBytes +} + +// freezeClient temporarily puts the client in a frozen state which means all +// unprocessed and subsequent requests are dropped. Unfreezing happens automatically +// after a short time if the client's buffer value is at least in the slightly positive +// region. The client is also notified about being frozen/unfrozen with a Stop/Resume +// message. +func (p *peer) freezeClient() { + if p.version < lpv3 { + // if Stop/Resume is not supported then just drop the peer after setting + // its frozen status permanently + atomic.StoreUint32(&p.frozen, 1) + p.Peer.Disconnect(p2p.DiscUselessPeer) + return + } + if atomic.SwapUint32(&p.frozen, 1) == 0 { + go func() { + p.SendStop() + time.Sleep(freezeTimeBase + time.Duration(rand.Int63n(int64(freezeTimeRandom)))) + for { + bufValue, bufLimit := p.fcClient.BufferStatus() + if bufLimit == 0 { + return + } + if bufValue <= bufLimit/8 { + time.Sleep(freezeCheckPeriod) + } else { + atomic.StoreUint32(&p.frozen, 0) + p.SendResume(bufValue) + break + } + } + }() + } +} + +// freezeServer processes Stop/Resume messages from the given server +func (p *peer) freezeServer(frozen bool) { + var f uint32 + if frozen { + f = 1 + } + if atomic.SwapUint32(&p.frozen, f) != f && frozen { + p.sendQueue.clear() + } +} + +// isFrozen returns true if the client is frozen or the server has put our +// client in frozen state +func (p *peer) isFrozen() bool { + return atomic.LoadUint32(&p.frozen) != 0 +} + +func (p *peer) canQueue() bool { + return p.sendQueue.canQueue() && !p.isFrozen() +} + +func (p *peer) queueSend(f func()) { + p.sendQueue.queue(f) +} + +// Info gathers and returns a collection of metadata known about a peer. +func (p *peer) Info() *eth.PeerInfo { + return ð.PeerInfo{ + Version: p.version, + Difficulty: p.Td(), + Head: fmt.Sprintf("%x", p.Head()), + } +} + +// Head retrieves a copy of the current head (most recent) hash of the peer. +func (p *peer) Head() (hash common.Hash) { + p.lock.RLock() + defer p.lock.RUnlock() + + copy(hash[:], p.headInfo.Hash[:]) + return hash +} + +func (p *peer) HeadAndTd() (hash common.Hash, td *big.Int) { + p.lock.RLock() + defer p.lock.RUnlock() + + copy(hash[:], p.headInfo.Hash[:]) + return hash, p.headInfo.Td +} + +func (p *peer) headBlockInfo() blockInfo { + p.lock.RLock() + defer p.lock.RUnlock() + + return blockInfo{Hash: p.headInfo.Hash, Number: p.headInfo.Number, Td: p.headInfo.Td} +} + +// Td retrieves the current total difficulty of a peer. +func (p *peer) Td() *big.Int { + p.lock.RLock() + defer p.lock.RUnlock() + + return new(big.Int).Set(p.headInfo.Td) +} + +// waitBefore implements distPeer interface +func (p *peer) waitBefore(maxCost uint64) (time.Duration, float64) { + return p.fcServer.CanSend(maxCost) +} + +// updateCapacity updates the request serving capacity assigned to a given client +// and also sends an announcement about the updated flow control parameters +func (p *peer) updateCapacity(cap uint64) { + p.responseLock.Lock() + defer p.responseLock.Unlock() + + p.fcParams = flowcontrol.ServerParams{MinRecharge: cap, BufLimit: cap * bufLimitRatio} + p.fcClient.UpdateParams(p.fcParams) + var kvList keyValueList + kvList = kvList.add("flowControl/MRR", cap) + kvList = kvList.add("flowControl/BL", cap*bufLimitRatio) + p.queueSend(func() { p.SendAnnounce(announceData{Update: kvList}) }) +} + +func sendRequest(w p2p.MsgWriter, msgcode, reqID, cost uint64, data interface{}) error { + type req struct { + ReqID uint64 + Data interface{} + } + return p2p.Send(w, msgcode, req{reqID, data}) +} + +// reply struct represents a reply with the actual data already RLP encoded and +// only the bv (buffer value) missing. This allows the serving mechanism to +// calculate the bv value which depends on the data size before sending the reply. +type reply struct { + w p2p.MsgWriter + msgcode, reqID uint64 + data rlp.RawValue +} + +// send sends the reply with the calculated buffer value +func (r *reply) send(bv uint64) error { + type resp struct { + ReqID, BV uint64 + Data rlp.RawValue + } + return p2p.Send(r.w, r.msgcode, resp{r.reqID, bv, r.data}) +} + +// size returns the RLP encoded size of the message data +func (r *reply) size() uint32 { + return uint32(len(r.data)) +} + +func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 { + p.lock.RLock() + defer p.lock.RUnlock() + + costs := p.fcCosts[msgcode] + if costs == nil { + return 0 + } + cost := costs.baseCost + costs.reqCost*uint64(amount) + if cost > p.fcParams.BufLimit { + cost = p.fcParams.BufLimit + } + return cost +} + +func (p *peer) GetTxRelayCost(amount, size int) uint64 { + p.lock.RLock() + defer p.lock.RUnlock() + + costs := p.fcCosts[SendTxV2Msg] + if costs == nil { + return 0 + } + cost := costs.baseCost + costs.reqCost*uint64(amount) + sizeCost := costs.baseCost + costs.reqCost*uint64(size)/txSizeCostLimit + if sizeCost > cost { + cost = sizeCost + } + + if cost > p.fcParams.BufLimit { + cost = p.fcParams.BufLimit + } + return cost +} + +// HasBlock checks if the peer has a given block +func (p *peer) HasBlock(hash common.Hash, number uint64, hasState bool) bool { + var head, since, recent uint64 + p.lock.RLock() + if p.headInfo != nil { + head = p.headInfo.Number + } + if hasState { + since = p.stateSince + recent = p.stateRecent + } else { + since = p.chainSince + recent = p.chainRecent + } + hasBlock := p.hasBlock + p.lock.RUnlock() + return head >= number && number >= since && (recent == 0 || number+recent+4 > head) && hasBlock != nil && hasBlock(hash, number, hasState) +} + +// SendAnnounce announces the availability of a number of blocks through +// a hash notification. +func (p *peer) SendAnnounce(request announceData) error { + return p2p.Send(p.rw, AnnounceMsg, request) +} + +// SendStop notifies the client about being in frozen state +func (p *peer) SendStop() error { + return p2p.Send(p.rw, StopMsg, struct{}{}) +} + +// SendResume notifies the client about getting out of frozen state +func (p *peer) SendResume(bv uint64) error { + return p2p.Send(p.rw, ResumeMsg, bv) +} + +// ReplyBlockHeaders creates a reply with a batch of block headers +func (p *peer) ReplyBlockHeaders(reqID uint64, headers []*types.Header) *reply { + data, _ := rlp.EncodeToBytes(headers) + return &reply{p.rw, BlockHeadersMsg, reqID, data} +} + +// ReplyBlockBodiesRLP creates a reply with a batch of block contents from +// an already RLP encoded format. +func (p *peer) ReplyBlockBodiesRLP(reqID uint64, bodies []rlp.RawValue) *reply { + data, _ := rlp.EncodeToBytes(bodies) + return &reply{p.rw, BlockBodiesMsg, reqID, data} +} + +// ReplyCode creates a reply with a batch of arbitrary internal data, corresponding to the +// hashes requested. +func (p *peer) ReplyCode(reqID uint64, codes [][]byte) *reply { + data, _ := rlp.EncodeToBytes(codes) + return &reply{p.rw, CodeMsg, reqID, data} +} + +// ReplyReceiptsRLP creates a reply with a batch of transaction receipts, corresponding to the +// ones requested from an already RLP encoded format. +func (p *peer) ReplyReceiptsRLP(reqID uint64, receipts []rlp.RawValue) *reply { + data, _ := rlp.EncodeToBytes(receipts) + return &reply{p.rw, ReceiptsMsg, reqID, data} +} + +// ReplyProofsV2 creates a reply with a batch of merkle proofs, corresponding to the ones requested. +func (p *peer) ReplyProofsV2(reqID uint64, proofs light.NodeList) *reply { + data, _ := rlp.EncodeToBytes(proofs) + return &reply{p.rw, ProofsV2Msg, reqID, data} +} + +// ReplyHelperTrieProofs creates a reply with a batch of HelperTrie proofs, corresponding to the ones requested. +func (p *peer) ReplyHelperTrieProofs(reqID uint64, resp HelperTrieResps) *reply { + data, _ := rlp.EncodeToBytes(resp) + return &reply{p.rw, HelperTrieProofsMsg, reqID, data} +} + +// ReplyTxStatus creates a reply with a batch of transaction status records, corresponding to the ones requested. +func (p *peer) ReplyTxStatus(reqID uint64, stats []light.TxStatus) *reply { + data, _ := rlp.EncodeToBytes(stats) + return &reply{p.rw, TxStatusMsg, reqID, data} +} + +// RequestHeadersByHash fetches a batch of blocks' headers corresponding to the +// specified header query, based on the hash of an origin block. +func (p *peer) RequestHeadersByHash(reqID, cost uint64, origin common.Hash, amount int, skip int, reverse bool) error { + p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) + return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) +} + +// RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the +// specified header query, based on the number of an origin block. +func (p *peer) RequestHeadersByNumber(reqID, cost, origin uint64, amount int, skip int, reverse bool) error { + p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) + return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) +} + +// RequestBodies fetches a batch of blocks' bodies corresponding to the hashes +// specified. +func (p *peer) RequestBodies(reqID, cost uint64, hashes []common.Hash) error { + p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) + return sendRequest(p.rw, GetBlockBodiesMsg, reqID, cost, hashes) +} + +// RequestCode fetches a batch of arbitrary data from a node's known state +// data, corresponding to the specified hashes. +func (p *peer) RequestCode(reqID, cost uint64, reqs []CodeReq) error { + p.Log().Debug("Fetching batch of codes", "count", len(reqs)) + return sendRequest(p.rw, GetCodeMsg, reqID, cost, reqs) +} + +// RequestReceipts fetches a batch of transaction receipts from a remote node. +func (p *peer) RequestReceipts(reqID, cost uint64, hashes []common.Hash) error { + p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) + return sendRequest(p.rw, GetReceiptsMsg, reqID, cost, hashes) +} + +// RequestProofs fetches a batch of merkle proofs from a remote node. +func (p *peer) RequestProofs(reqID, cost uint64, reqs []ProofReq) error { + p.Log().Debug("Fetching batch of proofs", "count", len(reqs)) + return sendRequest(p.rw, GetProofsV2Msg, reqID, cost, reqs) +} + +// RequestHelperTrieProofs fetches a batch of HelperTrie merkle proofs from a remote node. +func (p *peer) RequestHelperTrieProofs(reqID, cost uint64, reqs []HelperTrieReq) error { + p.Log().Debug("Fetching batch of HelperTrie proofs", "count", len(reqs)) + return sendRequest(p.rw, GetHelperTrieProofsMsg, reqID, cost, reqs) +} + +// RequestTxStatus fetches a batch of transaction status records from a remote node. +func (p *peer) RequestTxStatus(reqID, cost uint64, txHashes []common.Hash) error { + p.Log().Debug("Requesting transaction status", "count", len(txHashes)) + return sendRequest(p.rw, GetTxStatusMsg, reqID, cost, txHashes) +} + +// SendTxStatus creates a reply with a batch of transactions to be added to the remote transaction pool. +func (p *peer) SendTxs(reqID, cost uint64, txs rlp.RawValue) error { + p.Log().Debug("Sending batch of transactions", "size", len(txs)) + return sendRequest(p.rw, SendTxV2Msg, reqID, cost, txs) +} + +type keyValueEntry struct { + Key string + Value rlp.RawValue +} +type keyValueList []keyValueEntry +type keyValueMap map[string]rlp.RawValue + +func (l keyValueList) add(key string, val interface{}) keyValueList { + var entry keyValueEntry + entry.Key = key + if val == nil { + val = uint64(0) + } + enc, err := rlp.EncodeToBytes(val) + if err == nil { + entry.Value = enc + } + return append(l, entry) +} + +func (l keyValueList) decode() (keyValueMap, uint64) { + m := make(keyValueMap) + var size uint64 + for _, entry := range l { + m[entry.Key] = entry.Value + size += uint64(len(entry.Key)) + uint64(len(entry.Value)) + 8 + } + return m, size +} + +func (m keyValueMap) get(key string, val interface{}) error { + enc, ok := m[key] + if !ok { + return errResp(ErrMissingKey, "%s", key) + } + if val == nil { + return nil + } + return rlp.DecodeBytes(enc, val) +} + +func (p *peer) sendReceiveHandshake(sendList keyValueList) (keyValueList, error) { + // Send out own handshake in a new thread + errc := make(chan error, 1) + go func() { + errc <- p2p.Send(p.rw, StatusMsg, sendList) + }() + // In the mean time retrieve the remote status message + msg, err := p.rw.ReadMsg() + if err != nil { + return nil, err + } + if msg.Code != StatusMsg { + return nil, errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) + } + if msg.Size > ProtocolMaxMsgSize { + return nil, errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) + } + // Decode the handshake + var recvList keyValueList + if err := msg.Decode(&recvList); err != nil { + return nil, errResp(ErrDecode, "msg %v: %v", msg, err) + } + if err := <-errc; err != nil { + return nil, err + } + return recvList, nil +} + +// Handshake executes the les protocol handshake, negotiating version number, +// network IDs, difficulties, head and genesis blocks. +func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, server *LesServer) error { + p.lock.Lock() + defer p.lock.Unlock() + + var send keyValueList + send = send.add("protocolVersion", uint64(p.version)) + send = send.add("networkId", p.network) + send = send.add("headTd", td) + send = send.add("headHash", head) + send = send.add("headNum", headNum) + send = send.add("genesisHash", genesis) + if server != nil { + if !server.onlyAnnounce { + send = send.add("serveHeaders", nil) + send = send.add("serveChainSince", uint64(0)) + send = send.add("serveStateSince", uint64(0)) + + // If local ethereum node is running in archive mode, advertise ourselves we have + // all version state data. Otherwise only recent state is available. + stateRecent := uint64(core.TriesInMemory - 4) + if server.archiveMode { + stateRecent = 0 + } + send = send.add("serveRecentState", stateRecent) + send = send.add("txRelay", nil) + } + send = send.add("flowControl/BL", server.defParams.BufLimit) + send = send.add("flowControl/MRR", server.defParams.MinRecharge) + var costList RequestCostList + if server.costTracker != nil { + costList = server.costTracker.makeCostList(server.costTracker.globalFactor()) + } else { + costList = testCostList(server.testCost) + } + send = send.add("flowControl/MRC", costList) + p.fcCosts = costList.decode(ProtocolLengths[uint(p.version)]) + p.fcParams = server.defParams + } else { + //on client node + p.announceType = announceTypeSimple + if p.isTrusted { + p.announceType = announceTypeSigned + } + send = send.add("announceType", p.announceType) + } + + recvList, err := p.sendReceiveHandshake(send) + if err != nil { + return err + } + recv, size := recvList.decode() + if p.rejectUpdate(size) { + return errResp(ErrRequestRejected, "") + } + + var rGenesis, rHash common.Hash + var rVersion, rNetwork, rNum uint64 + var rTd *big.Int + + if err := recv.get("protocolVersion", &rVersion); err != nil { + return err + } + if err := recv.get("networkId", &rNetwork); err != nil { + return err + } + if err := recv.get("headTd", &rTd); err != nil { + return err + } + if err := recv.get("headHash", &rHash); err != nil { + return err + } + if err := recv.get("headNum", &rNum); err != nil { + return err + } + if err := recv.get("genesisHash", &rGenesis); err != nil { + return err + } + + if rGenesis != genesis { + return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", rGenesis[:8], genesis[:8]) + } + if rNetwork != p.network { + return errResp(ErrNetworkIdMismatch, "%d (!= %d)", rNetwork, p.network) + } + if int(rVersion) != p.version { + return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", rVersion, p.version) + } + + if server != nil { + // until we have a proper peer connectivity API, allow LES connection to other servers + /*if recv.get("serveStateSince", nil) == nil { + return errResp(ErrUselessPeer, "wanted client, got server") + }*/ + if recv.get("announceType", &p.announceType) != nil { + //set default announceType on server side + p.announceType = announceTypeSimple + } + p.fcClient = flowcontrol.NewClientNode(server.fcManager, server.defParams) + } else { + //mark OnlyAnnounce server if "serveHeaders", "serveChainSince", "serveStateSince" or "txRelay" fields don't exist + if recv.get("serveChainSince", &p.chainSince) != nil { + p.isOnlyAnnounce = true + } + if recv.get("serveRecentChain", &p.chainRecent) != nil { + p.chainRecent = 0 + } + if recv.get("serveStateSince", &p.stateSince) != nil { + p.isOnlyAnnounce = true + } + if recv.get("serveRecentState", &p.stateRecent) != nil { + p.stateRecent = 0 + } + if recv.get("txRelay", nil) != nil { + p.isOnlyAnnounce = true + } + + if p.isOnlyAnnounce && !p.isTrusted { + return errResp(ErrUselessPeer, "peer cannot serve requests") + } + + var params flowcontrol.ServerParams + if err := recv.get("flowControl/BL", ¶ms.BufLimit); err != nil { + return err + } + if err := recv.get("flowControl/MRR", ¶ms.MinRecharge); err != nil { + return err + } + var MRC RequestCostList + if err := recv.get("flowControl/MRC", &MRC); err != nil { + return err + } + p.fcParams = params + p.fcServer = flowcontrol.NewServerNode(params, &mclock.System{}) + p.fcCosts = MRC.decode(ProtocolLengths[uint(p.version)]) + if !p.isOnlyAnnounce { + for msgCode := range reqAvgTimeCost { + if p.fcCosts[msgCode] == nil { + return errResp(ErrUselessPeer, "peer does not support message %d", msgCode) + } + } + } + } + p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum} + return nil +} + +// updateFlowControl updates the flow control parameters belonging to the server +// node if the announced key/value set contains relevant fields +func (p *peer) updateFlowControl(update keyValueMap) { + if p.fcServer == nil { + return + } + params := p.fcParams + updateParams := false + if update.get("flowControl/BL", ¶ms.BufLimit) == nil { + updateParams = true + } + if update.get("flowControl/MRR", ¶ms.MinRecharge) == nil { + updateParams = true + } + if updateParams { + p.fcParams = params + p.fcServer.UpdateParams(params) + } + var MRC RequestCostList + if update.get("flowControl/MRC", &MRC) == nil { + costUpdate := MRC.decode(ProtocolLengths[uint(p.version)]) + for code, cost := range costUpdate { + p.fcCosts[code] = cost + } + } +} + +// String implements fmt.Stringer. +func (p *peer) String() string { + return fmt.Sprintf("Peer %s [%s]", p.id, + fmt.Sprintf("les/%d", p.version), + ) +} + +// peerSetNotify is a callback interface to notify services about added or +// removed peers +type peerSetNotify interface { + registerPeer(*peer) + unregisterPeer(*peer) +} + +// peerSet represents the collection of active peers currently participating in +// the Light Ethereum sub-protocol. +type peerSet struct { + peers map[string]*peer + lock sync.RWMutex + notifyList []peerSetNotify + closed bool +} + +// newPeerSet creates a new peer set to track the active participants. +func newPeerSet() *peerSet { + return &peerSet{ + peers: make(map[string]*peer), + } +} + +// notify adds a service to be notified about added or removed peers +func (ps *peerSet) notify(n peerSetNotify) { + ps.lock.Lock() + ps.notifyList = append(ps.notifyList, n) + peers := make([]*peer, 0, len(ps.peers)) + for _, p := range ps.peers { + peers = append(peers, p) + } + ps.lock.Unlock() + + for _, p := range peers { + n.registerPeer(p) + } +} + +// Register injects a new peer into the working set, or returns an error if the +// peer is already known. +func (ps *peerSet) Register(p *peer) error { + ps.lock.Lock() + if ps.closed { + ps.lock.Unlock() + return errClosed + } + if _, ok := ps.peers[p.id]; ok { + ps.lock.Unlock() + return errAlreadyRegistered + } + ps.peers[p.id] = p + p.sendQueue = newExecQueue(100) + peers := make([]peerSetNotify, len(ps.notifyList)) + copy(peers, ps.notifyList) + ps.lock.Unlock() + + for _, n := range peers { + n.registerPeer(p) + } + return nil +} + +// Unregister removes a remote peer from the active set, disabling any further +// actions to/from that particular entity. It also initiates disconnection at the networking layer. +func (ps *peerSet) Unregister(id string) error { + ps.lock.Lock() + if p, ok := ps.peers[id]; !ok { + ps.lock.Unlock() + return errNotRegistered + } else { + delete(ps.peers, id) + peers := make([]peerSetNotify, len(ps.notifyList)) + copy(peers, ps.notifyList) + ps.lock.Unlock() + + for _, n := range peers { + n.unregisterPeer(p) + } + + p.sendQueue.quit() + p.Peer.Disconnect(p2p.DiscUselessPeer) + + return nil + } +} + +// AllPeerIDs returns a list of all registered peer IDs +func (ps *peerSet) AllPeerIDs() []string { + ps.lock.RLock() + defer ps.lock.RUnlock() + + res := make([]string, len(ps.peers)) + idx := 0 + for id := range ps.peers { + res[idx] = id + idx++ + } + return res +} + +// Peer retrieves the registered peer with the given id. +func (ps *peerSet) Peer(id string) *peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + return ps.peers[id] +} + +// Len returns if the current number of peers in the set. +func (ps *peerSet) Len() int { + ps.lock.RLock() + defer ps.lock.RUnlock() + + return len(ps.peers) +} + +// BestPeer retrieves the known peer with the currently highest total difficulty. +func (ps *peerSet) BestPeer() *peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + var ( + bestPeer *peer + bestTd *big.Int + ) + for _, p := range ps.peers { + if td := p.Td(); bestPeer == nil || td.Cmp(bestTd) > 0 { + bestPeer, bestTd = p, td + } + } + return bestPeer +} + +// AllPeers returns all peers in a list +func (ps *peerSet) AllPeers() []*peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + list := make([]*peer, len(ps.peers)) + i := 0 + for _, peer := range ps.peers { + list[i] = peer + i++ + } + return list +} + +// Close disconnects all peers. +// No new peers can be registered after Close has returned. +func (ps *peerSet) Close() { + ps.lock.Lock() + defer ps.lock.Unlock() + + for _, p := range ps.peers { + p.Disconnect(p2p.DiscQuitting) + } + ps.closed = true +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/protocol.go b/vendor/github.com/ethereum/go-ethereum/les/protocol.go new file mode 100644 index 00000000..ebf58147 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/protocol.go @@ -0,0 +1,231 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "crypto/ecdsa" + "errors" + "fmt" + "io" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rlp" +) + +// Constants to match up protocol versions and messages +const ( + lpv2 = 2 + lpv3 = 3 +) + +// Supported versions of the les protocol (first is primary) +var ( + ClientProtocolVersions = []uint{lpv2, lpv3} + ServerProtocolVersions = []uint{lpv2, lpv3} + AdvertiseProtocolVersions = []uint{lpv2} // clients are searching for the first advertised protocol in the list +) + +// Number of implemented message corresponding to different protocol versions. +var ProtocolLengths = map[uint]uint64{lpv2: 22, lpv3: 24} + +const ( + NetworkId = 1 + ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message +) + +// les protocol message codes +const ( + // Protocol messages inherited from LPV1 + StatusMsg = 0x00 + AnnounceMsg = 0x01 + GetBlockHeadersMsg = 0x02 + BlockHeadersMsg = 0x03 + GetBlockBodiesMsg = 0x04 + BlockBodiesMsg = 0x05 + GetReceiptsMsg = 0x06 + ReceiptsMsg = 0x07 + GetCodeMsg = 0x0a + CodeMsg = 0x0b + // Protocol messages introduced in LPV2 + GetProofsV2Msg = 0x0f + ProofsV2Msg = 0x10 + GetHelperTrieProofsMsg = 0x11 + HelperTrieProofsMsg = 0x12 + SendTxV2Msg = 0x13 + GetTxStatusMsg = 0x14 + TxStatusMsg = 0x15 + // Protocol messages introduced in LPV3 + StopMsg = 0x16 + ResumeMsg = 0x17 +) + +type requestInfo struct { + name string + maxCount uint64 +} + +var requests = map[uint64]requestInfo{ + GetBlockHeadersMsg: {"GetBlockHeaders", MaxHeaderFetch}, + GetBlockBodiesMsg: {"GetBlockBodies", MaxBodyFetch}, + GetReceiptsMsg: {"GetReceipts", MaxReceiptFetch}, + GetCodeMsg: {"GetCode", MaxCodeFetch}, + GetProofsV2Msg: {"GetProofsV2", MaxProofsFetch}, + GetHelperTrieProofsMsg: {"GetHelperTrieProofs", MaxHelperTrieProofsFetch}, + SendTxV2Msg: {"SendTxV2", MaxTxSend}, + GetTxStatusMsg: {"GetTxStatus", MaxTxStatus}, +} + +type errCode int + +const ( + ErrMsgTooLarge = iota + ErrDecode + ErrInvalidMsgCode + ErrProtocolVersionMismatch + ErrNetworkIdMismatch + ErrGenesisBlockMismatch + ErrNoStatusMsg + ErrExtraStatusMsg + ErrSuspendedPeer + ErrUselessPeer + ErrRequestRejected + ErrUnexpectedResponse + ErrInvalidResponse + ErrTooManyTimeouts + ErrMissingKey +) + +func (e errCode) String() string { + return errorToString[int(e)] +} + +// XXX change once legacy code is out +var errorToString = map[int]string{ + ErrMsgTooLarge: "Message too long", + ErrDecode: "Invalid message", + ErrInvalidMsgCode: "Invalid message code", + ErrProtocolVersionMismatch: "Protocol version mismatch", + ErrNetworkIdMismatch: "NetworkId mismatch", + ErrGenesisBlockMismatch: "Genesis block mismatch", + ErrNoStatusMsg: "No status message", + ErrExtraStatusMsg: "Extra status message", + ErrSuspendedPeer: "Suspended peer", + ErrRequestRejected: "Request rejected", + ErrUnexpectedResponse: "Unexpected response", + ErrInvalidResponse: "Invalid response", + ErrTooManyTimeouts: "Too many request timeouts", + ErrMissingKey: "Key missing from list", +} + +type announceBlock struct { + Hash common.Hash // Hash of one particular block being announced + Number uint64 // Number of one particular block being announced + Td *big.Int // Total difficulty of one particular block being announced +} + +// announceData is the network packet for the block announcements. +type announceData struct { + Hash common.Hash // Hash of one particular block being announced + Number uint64 // Number of one particular block being announced + Td *big.Int // Total difficulty of one particular block being announced + ReorgDepth uint64 + Update keyValueList +} + +// sign adds a signature to the block announcement by the given privKey +func (a *announceData) sign(privKey *ecdsa.PrivateKey) { + rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td}) + sig, _ := crypto.Sign(crypto.Keccak256(rlp), privKey) + a.Update = a.Update.add("sign", sig) +} + +// checkSignature verifies if the block announcement has a valid signature by the given pubKey +func (a *announceData) checkSignature(id enode.ID, update keyValueMap) error { + var sig []byte + if err := update.get("sign", &sig); err != nil { + return err + } + rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td}) + recPubkey, err := crypto.SigToPub(crypto.Keccak256(rlp), sig) + if err != nil { + return err + } + if id == enode.PubkeyToIDV4(recPubkey) { + return nil + } + return errors.New("wrong signature") +} + +type blockInfo struct { + Hash common.Hash // Hash of one particular block being announced + Number uint64 // Number of one particular block being announced + Td *big.Int // Total difficulty of one particular block being announced +} + +// getBlockHeadersData represents a block header query. +type getBlockHeadersData struct { + Origin hashOrNumber // Block from which to retrieve headers + Amount uint64 // Maximum number of headers to retrieve + Skip uint64 // Blocks to skip between consecutive headers + Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) +} + +// hashOrNumber is a combined field for specifying an origin block. +type hashOrNumber struct { + Hash common.Hash // Block hash from which to retrieve headers (excludes Number) + Number uint64 // Block hash from which to retrieve headers (excludes Hash) +} + +// EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the +// two contained union fields. +func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { + if hn.Hash == (common.Hash{}) { + return rlp.Encode(w, hn.Number) + } + if hn.Number != 0 { + return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) + } + return rlp.Encode(w, hn.Hash) +} + +// DecodeRLP is a specialized decoder for hashOrNumber to decode the contents +// into either a block hash or a block number. +func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { + _, size, _ := s.Kind() + origin, err := s.Raw() + if err == nil { + switch { + case size == 32: + err = rlp.DecodeBytes(origin, &hn.Hash) + case size <= 8: + err = rlp.DecodeBytes(origin, &hn.Number) + default: + err = fmt.Errorf("invalid input size %d for origin", size) + } + } + return err +} + +// CodeData is the network response packet for a node data retrieval. +type CodeData []struct { + Value []byte +} + +type proofsData [][]rlp.RawValue diff --git a/vendor/github.com/ethereum/go-ethereum/les/retrieve.go b/vendor/github.com/ethereum/go-ethereum/les/retrieve.go new file mode 100644 index 00000000..d17a02e1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/retrieve.go @@ -0,0 +1,448 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "context" + "crypto/rand" + "encoding/binary" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/light" +) + +var ( + retryQueue = time.Millisecond * 100 + softRequestTimeout = time.Millisecond * 500 + hardRequestTimeout = time.Second * 10 +) + +// retrieveManager is a layer on top of requestDistributor which takes care of +// matching replies by request ID and handles timeouts and resends if necessary. +type retrieveManager struct { + dist *requestDistributor + peers *peerSet + serverPool peerSelector + + lock sync.RWMutex + sentReqs map[uint64]*sentReq +} + +// validatorFunc is a function that processes a reply message +type validatorFunc func(distPeer, *Msg) error + +// peerSelector receives feedback info about response times and timeouts +type peerSelector interface { + adjustResponseTime(*poolEntry, time.Duration, bool) +} + +// sentReq represents a request sent and tracked by retrieveManager +type sentReq struct { + rm *retrieveManager + req *distReq + id uint64 + validate validatorFunc + + eventsCh chan reqPeerEvent + stopCh chan struct{} + stopped bool + err error + + lock sync.RWMutex // protect access to sentTo map + sentTo map[distPeer]sentReqToPeer + + lastReqQueued bool // last request has been queued but not sent + lastReqSentTo distPeer // if not nil then last request has been sent to given peer but not timed out + reqSrtoCount int // number of requests that reached soft (but not hard) timeout +} + +// sentReqToPeer notifies the request-from-peer goroutine (tryRequest) about a response +// delivered by the given peer. Only one delivery is allowed per request per peer, +// after which delivered is set to true, the validity of the response is sent on the +// valid channel and no more responses are accepted. +type sentReqToPeer struct { + delivered, frozen bool + event chan int +} + +// reqPeerEvent is sent by the request-from-peer goroutine (tryRequest) to the +// request state machine (retrieveLoop) through the eventsCh channel. +type reqPeerEvent struct { + event int + peer distPeer +} + +const ( + rpSent = iota // if peer == nil, not sent (no suitable peers) + rpSoftTimeout + rpHardTimeout + rpDeliveredValid + rpDeliveredInvalid + rpNotDelivered +) + +// newRetrieveManager creates the retrieve manager +func newRetrieveManager(peers *peerSet, dist *requestDistributor, serverPool peerSelector) *retrieveManager { + return &retrieveManager{ + peers: peers, + dist: dist, + serverPool: serverPool, + sentReqs: make(map[uint64]*sentReq), + } +} + +// retrieve sends a request (to multiple peers if necessary) and waits for an answer +// that is delivered through the deliver function and successfully validated by the +// validator callback. It returns when a valid answer is delivered or the context is +// cancelled. +func (rm *retrieveManager) retrieve(ctx context.Context, reqID uint64, req *distReq, val validatorFunc, shutdown chan struct{}) error { + sentReq := rm.sendReq(reqID, req, val) + select { + case <-sentReq.stopCh: + case <-ctx.Done(): + sentReq.stop(ctx.Err()) + case <-shutdown: + sentReq.stop(fmt.Errorf("Client is shutting down")) + } + return sentReq.getError() +} + +// sendReq starts a process that keeps trying to retrieve a valid answer for a +// request from any suitable peers until stopped or succeeded. +func (rm *retrieveManager) sendReq(reqID uint64, req *distReq, val validatorFunc) *sentReq { + r := &sentReq{ + rm: rm, + req: req, + id: reqID, + sentTo: make(map[distPeer]sentReqToPeer), + stopCh: make(chan struct{}), + eventsCh: make(chan reqPeerEvent, 10), + validate: val, + } + + canSend := req.canSend + req.canSend = func(p distPeer) bool { + // add an extra check to canSend: the request has not been sent to the same peer before + r.lock.RLock() + _, sent := r.sentTo[p] + r.lock.RUnlock() + return !sent && canSend(p) + } + + request := req.request + req.request = func(p distPeer) func() { + // before actually sending the request, put an entry into the sentTo map + r.lock.Lock() + r.sentTo[p] = sentReqToPeer{delivered: false, frozen: false, event: make(chan int, 1)} + r.lock.Unlock() + return request(p) + } + rm.lock.Lock() + rm.sentReqs[reqID] = r + rm.lock.Unlock() + + go r.retrieveLoop() + return r +} + +// deliver is called by the LES protocol manager to deliver reply messages to waiting requests +func (rm *retrieveManager) deliver(peer distPeer, msg *Msg) error { + rm.lock.RLock() + req, ok := rm.sentReqs[msg.ReqID] + rm.lock.RUnlock() + + if ok { + return req.deliver(peer, msg) + } + return errResp(ErrUnexpectedResponse, "reqID = %v", msg.ReqID) +} + +// frozen is called by the LES protocol manager when a server has suspended its service and we +// should not expect an answer for the requests already sent there +func (rm *retrieveManager) frozen(peer distPeer) { + rm.lock.RLock() + defer rm.lock.RUnlock() + + for _, req := range rm.sentReqs { + req.frozen(peer) + } +} + +// reqStateFn represents a state of the retrieve loop state machine +type reqStateFn func() reqStateFn + +// retrieveLoop is the retrieval state machine event loop +func (r *sentReq) retrieveLoop() { + go r.tryRequest() + r.lastReqQueued = true + state := r.stateRequesting + + for state != nil { + state = state() + } + + r.rm.lock.Lock() + delete(r.rm.sentReqs, r.id) + r.rm.lock.Unlock() +} + +// stateRequesting: a request has been queued or sent recently; when it reaches soft timeout, +// a new request is sent to a new peer +func (r *sentReq) stateRequesting() reqStateFn { + select { + case ev := <-r.eventsCh: + r.update(ev) + switch ev.event { + case rpSent: + if ev.peer == nil { + // request send failed, no more suitable peers + if r.waiting() { + // we are already waiting for sent requests which may succeed so keep waiting + return r.stateNoMorePeers + } + // nothing to wait for, no more peers to ask, return with error + r.stop(light.ErrNoPeers) + // no need to go to stopped state because waiting() already returned false + return nil + } + case rpSoftTimeout: + // last request timed out, try asking a new peer + go r.tryRequest() + r.lastReqQueued = true + return r.stateRequesting + case rpDeliveredInvalid, rpNotDelivered: + // if it was the last sent request (set to nil by update) then start a new one + if !r.lastReqQueued && r.lastReqSentTo == nil { + go r.tryRequest() + r.lastReqQueued = true + } + return r.stateRequesting + case rpDeliveredValid: + r.stop(nil) + return r.stateStopped + } + return r.stateRequesting + case <-r.stopCh: + return r.stateStopped + } +} + +// stateNoMorePeers: could not send more requests because no suitable peers are available. +// Peers may become suitable for a certain request later or new peers may appear so we +// keep trying. +func (r *sentReq) stateNoMorePeers() reqStateFn { + select { + case <-time.After(retryQueue): + go r.tryRequest() + r.lastReqQueued = true + return r.stateRequesting + case ev := <-r.eventsCh: + r.update(ev) + if ev.event == rpDeliveredValid { + r.stop(nil) + return r.stateStopped + } + if r.waiting() { + return r.stateNoMorePeers + } + r.stop(light.ErrNoPeers) + return nil + case <-r.stopCh: + return r.stateStopped + } +} + +// stateStopped: request succeeded or cancelled, just waiting for some peers +// to either answer or time out hard +func (r *sentReq) stateStopped() reqStateFn { + for r.waiting() { + r.update(<-r.eventsCh) + } + return nil +} + +// update updates the queued/sent flags and timed out peers counter according to the event +func (r *sentReq) update(ev reqPeerEvent) { + switch ev.event { + case rpSent: + r.lastReqQueued = false + r.lastReqSentTo = ev.peer + case rpSoftTimeout: + r.lastReqSentTo = nil + r.reqSrtoCount++ + case rpHardTimeout: + r.reqSrtoCount-- + case rpDeliveredValid, rpDeliveredInvalid, rpNotDelivered: + if ev.peer == r.lastReqSentTo { + r.lastReqSentTo = nil + } else { + r.reqSrtoCount-- + } + } +} + +// waiting returns true if the retrieval mechanism is waiting for an answer from +// any peer +func (r *sentReq) waiting() bool { + return r.lastReqQueued || r.lastReqSentTo != nil || r.reqSrtoCount > 0 +} + +// tryRequest tries to send the request to a new peer and waits for it to either +// succeed or time out if it has been sent. It also sends the appropriate reqPeerEvent +// messages to the request's event channel. +func (r *sentReq) tryRequest() { + sent := r.rm.dist.queue(r.req) + var p distPeer + select { + case p = <-sent: + case <-r.stopCh: + if r.rm.dist.cancel(r.req) { + p = nil + } else { + p = <-sent + } + } + + r.eventsCh <- reqPeerEvent{rpSent, p} + if p == nil { + return + } + + reqSent := mclock.Now() + srto, hrto := false, false + + r.lock.RLock() + s, ok := r.sentTo[p] + r.lock.RUnlock() + if !ok { + panic(nil) + } + + defer func() { + // send feedback to server pool and remove peer if hard timeout happened + pp, ok := p.(*peer) + if ok && r.rm.serverPool != nil { + respTime := time.Duration(mclock.Now() - reqSent) + r.rm.serverPool.adjustResponseTime(pp.poolEntry, respTime, srto) + } + if hrto { + pp.Log().Debug("Request timed out hard") + if r.rm.peers != nil { + r.rm.peers.Unregister(pp.id) + } + } + + r.lock.Lock() + delete(r.sentTo, p) + r.lock.Unlock() + }() + + select { + case event := <-s.event: + if event == rpNotDelivered { + r.lock.Lock() + delete(r.sentTo, p) + r.lock.Unlock() + } + r.eventsCh <- reqPeerEvent{event, p} + return + case <-time.After(softRequestTimeout): + srto = true + r.eventsCh <- reqPeerEvent{rpSoftTimeout, p} + } + + select { + case event := <-s.event: + if event == rpNotDelivered { + r.lock.Lock() + delete(r.sentTo, p) + r.lock.Unlock() + } + r.eventsCh <- reqPeerEvent{event, p} + case <-time.After(hardRequestTimeout): + hrto = true + r.eventsCh <- reqPeerEvent{rpHardTimeout, p} + } +} + +// deliver a reply belonging to this request +func (r *sentReq) deliver(peer distPeer, msg *Msg) error { + r.lock.Lock() + defer r.lock.Unlock() + + s, ok := r.sentTo[peer] + if !ok || s.delivered { + return errResp(ErrUnexpectedResponse, "reqID = %v", msg.ReqID) + } + if s.frozen { + return nil + } + valid := r.validate(peer, msg) == nil + r.sentTo[peer] = sentReqToPeer{delivered: true, frozen: false, event: s.event} + if valid { + s.event <- rpDeliveredValid + } else { + s.event <- rpDeliveredInvalid + } + if !valid { + return errResp(ErrInvalidResponse, "reqID = %v", msg.ReqID) + } + return nil +} + +// frozen sends a "not delivered" event to the peer event channel belonging to the +// given peer if the request has been sent there, causing the state machine to not +// expect an answer and potentially even send the request to the same peer again +// when canSend allows it. +func (r *sentReq) frozen(peer distPeer) { + r.lock.Lock() + defer r.lock.Unlock() + + s, ok := r.sentTo[peer] + if ok && !s.delivered && !s.frozen { + r.sentTo[peer] = sentReqToPeer{delivered: false, frozen: true, event: s.event} + s.event <- rpNotDelivered + } +} + +// stop stops the retrieval process and sets an error code that will be returned +// by getError +func (r *sentReq) stop(err error) { + r.lock.Lock() + if !r.stopped { + r.stopped = true + r.err = err + close(r.stopCh) + } + r.lock.Unlock() +} + +// getError returns any retrieval error (either internally generated or set by the +// stop function) after stopCh has been closed +func (r *sentReq) getError() error { + return r.err +} + +// genReqID generates a new random request ID +func genReqID() uint64 { + var rnd [8]byte + rand.Read(rnd[:]) + return binary.BigEndian.Uint64(rnd[:]) +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/server.go b/vendor/github.com/ethereum/go-ethereum/les/server.go new file mode 100644 index 00000000..fbdf6cf1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/server.go @@ -0,0 +1,365 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "crypto/ecdsa" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/les/csvlogger" + "github.com/ethereum/go-ethereum/les/flowcontrol" + "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +const bufLimitRatio = 6000 // fixed bufLimit/MRR ratio + +const ( + logFileName = "" // csv log file name (disabled if empty) + logClientPoolMetrics = true // log client pool metrics + logClientPoolEvents = false // detailed client pool event logging + logRequestServing = true // log request serving metrics and events + logBlockProcEvents = true // log block processing events + logProtocolHandler = true // log protocol handler events +) + +type LesServer struct { + lesCommons + + archiveMode bool // Flag whether the ethereum node runs in archive mode. + + fcManager *flowcontrol.ClientManager // nil if our node is client only + costTracker *costTracker + testCost uint64 + defParams flowcontrol.ServerParams + lesTopics []discv5.Topic + privateKey *ecdsa.PrivateKey + quitSync chan struct{} + onlyAnnounce bool + csvLogger *csvlogger.Logger + logTotalCap *csvlogger.Channel + + thcNormal, thcBlockProcessing int // serving thread count for normal operation and block processing mode + + maxPeers int + minCapacity, freeClientCap uint64 + freeClientPool *freeClientPool + priorityClientPool *priorityClientPool +} + +func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) { + var csvLogger *csvlogger.Logger + if logFileName != "" { + csvLogger = csvlogger.NewLogger(logFileName, time.Second*10, "event, peerId") + } + + quitSync := make(chan struct{}) + pm, err := NewProtocolManager( + eth.BlockChain().Config(), + light.DefaultServerIndexerConfig, + false, + config.NetworkId, + eth.EventMux(), + eth.Engine(), + newPeerSet(), + eth.BlockChain(), + eth.TxPool(), + eth.ChainDb(), + nil, + nil, + nil, + quitSync, + new(sync.WaitGroup), + config.ULC, + eth.Synced) + if err != nil { + return nil, err + } + if logProtocolHandler { + pm.logger = csvLogger + } + requestLogger := csvLogger + if !logRequestServing { + requestLogger = nil + } + pm.servingQueue = newServingQueue(int64(time.Millisecond*10), float64(config.LightServ)/100, requestLogger) + + lesTopics := make([]discv5.Topic, len(AdvertiseProtocolVersions)) + for i, pv := range AdvertiseProtocolVersions { + lesTopics[i] = lesTopic(eth.BlockChain().Genesis().Hash(), pv) + } + + srv := &LesServer{ + lesCommons: lesCommons{ + config: config, + chainDb: eth.ChainDb(), + iConfig: light.DefaultServerIndexerConfig, + chtIndexer: light.NewChtIndexer(eth.ChainDb(), nil, params.CHTFrequency, params.HelperTrieProcessConfirmations), + bloomTrieIndexer: light.NewBloomTrieIndexer(eth.ChainDb(), nil, params.BloomBitsBlocks, params.BloomTrieFrequency), + protocolManager: pm, + }, + archiveMode: eth.ArchiveMode(), + quitSync: quitSync, + lesTopics: lesTopics, + onlyAnnounce: config.OnlyAnnounce, + csvLogger: csvLogger, + logTotalCap: requestLogger.NewChannel("totalCapacity", 0.01), + } + srv.costTracker, srv.minCapacity = newCostTracker(eth.ChainDb(), config, requestLogger) + + logger := log.New() + pm.server = srv + srv.thcNormal = config.LightServ * 4 / 100 + if srv.thcNormal < 4 { + srv.thcNormal = 4 + } + srv.thcBlockProcessing = config.LightServ/100 + 1 + srv.fcManager = flowcontrol.NewClientManager(nil, &mclock.System{}) + + chtSectionCount, _, _ := srv.chtIndexer.Sections() + if chtSectionCount != 0 { + chtLastSection := chtSectionCount - 1 + chtSectionHead := srv.chtIndexer.SectionHead(chtLastSection) + chtRoot := light.GetChtRoot(pm.chainDb, chtLastSection, chtSectionHead) + logger.Info("Loaded CHT", "section", chtLastSection, "head", chtSectionHead, "root", chtRoot) + } + bloomTrieSectionCount, _, _ := srv.bloomTrieIndexer.Sections() + if bloomTrieSectionCount != 0 { + bloomTrieLastSection := bloomTrieSectionCount - 1 + bloomTrieSectionHead := srv.bloomTrieIndexer.SectionHead(bloomTrieLastSection) + bloomTrieRoot := light.GetBloomTrieRoot(pm.chainDb, bloomTrieLastSection, bloomTrieSectionHead) + logger.Info("Loaded bloom trie", "section", bloomTrieLastSection, "head", bloomTrieSectionHead, "root", bloomTrieRoot) + } + + srv.chtIndexer.Start(eth.BlockChain()) + return srv, nil +} + +func (s *LesServer) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: "les", + Version: "1.0", + Service: NewPrivateLightServerAPI(s), + Public: false, + }, + } +} + +// startEventLoop starts an event handler loop that updates the recharge curve of +// the client manager and adjusts the client pool's size according to the total +// capacity updates coming from the client manager +func (s *LesServer) startEventLoop() { + s.protocolManager.wg.Add(1) + + blockProcLogger := s.csvLogger + if !logBlockProcEvents { + blockProcLogger = nil + } + var processing, procLast bool + blockProcFeed := make(chan bool, 100) + s.protocolManager.blockchain.(*core.BlockChain).SubscribeBlockProcessingEvent(blockProcFeed) + totalRechargeCh := make(chan uint64, 100) + totalRecharge := s.costTracker.subscribeTotalRecharge(totalRechargeCh) + totalCapacityCh := make(chan uint64, 100) + updateRecharge := func() { + if processing { + if !procLast { + blockProcLogger.Event("block processing started") + } + s.protocolManager.servingQueue.setThreads(s.thcBlockProcessing) + s.fcManager.SetRechargeCurve(flowcontrol.PieceWiseLinear{{0, 0}, {totalRecharge, totalRecharge}}) + } else { + if procLast { + blockProcLogger.Event("block processing finished") + } + s.protocolManager.servingQueue.setThreads(s.thcNormal) + s.fcManager.SetRechargeCurve(flowcontrol.PieceWiseLinear{{0, 0}, {totalRecharge / 16, totalRecharge / 2}, {totalRecharge / 2, totalRecharge / 2}, {totalRecharge, totalRecharge}}) + } + procLast = processing + } + updateRecharge() + totalCapacity := s.fcManager.SubscribeTotalCapacity(totalCapacityCh) + s.priorityClientPool.setLimits(s.maxPeers, totalCapacity) + + var maxFreePeers uint64 + go func() { + for { + select { + case processing = <-blockProcFeed: + updateRecharge() + case totalRecharge = <-totalRechargeCh: + updateRecharge() + case totalCapacity = <-totalCapacityCh: + s.logTotalCap.Update(float64(totalCapacity)) + newFreePeers := totalCapacity / s.freeClientCap + if newFreePeers < maxFreePeers && newFreePeers < uint64(s.maxPeers) { + log.Warn("Reduced total capacity", "maxFreePeers", newFreePeers) + } + maxFreePeers = newFreePeers + s.priorityClientPool.setLimits(s.maxPeers, totalCapacity) + case <-s.protocolManager.quitSync: + s.protocolManager.wg.Done() + return + } + } + }() +} + +func (s *LesServer) Protocols() []p2p.Protocol { + return s.makeProtocols(ServerProtocolVersions) +} + +// Start starts the LES server +func (s *LesServer) Start(srvr *p2p.Server) { + s.maxPeers = s.config.LightPeers + totalRecharge := s.costTracker.totalRecharge() + if s.maxPeers > 0 { + s.freeClientCap = s.minCapacity //totalRecharge / uint64(s.maxPeers) + if s.freeClientCap < s.minCapacity { + s.freeClientCap = s.minCapacity + } + if s.freeClientCap > 0 { + s.defParams = flowcontrol.ServerParams{ + BufLimit: s.freeClientCap * bufLimitRatio, + MinRecharge: s.freeClientCap, + } + } + } + + maxCapacity := s.freeClientCap * uint64(s.maxPeers) + if totalRecharge > maxCapacity { + maxCapacity = totalRecharge + } + s.fcManager.SetCapacityLimits(s.freeClientCap, maxCapacity, s.freeClientCap*2) + poolMetricsLogger := s.csvLogger + if !logClientPoolMetrics { + poolMetricsLogger = nil + } + poolEventLogger := s.csvLogger + if !logClientPoolEvents { + poolEventLogger = nil + } + s.freeClientPool = newFreeClientPool(s.chainDb, s.freeClientCap, 10000, mclock.System{}, func(id string) { go s.protocolManager.removePeer(id) }, poolMetricsLogger, poolEventLogger) + s.priorityClientPool = newPriorityClientPool(s.freeClientCap, s.protocolManager.peers, s.freeClientPool, poolMetricsLogger, poolEventLogger) + + s.protocolManager.peers.notify(s.priorityClientPool) + s.csvLogger.Start() + s.startEventLoop() + s.protocolManager.Start(s.config.LightPeers) + if srvr.DiscV5 != nil { + for _, topic := range s.lesTopics { + topic := topic + go func() { + logger := log.New("topic", topic) + logger.Info("Starting topic registration") + defer logger.Info("Terminated topic registration") + + srvr.DiscV5.RegisterTopic(topic, s.quitSync) + }() + } + } + s.privateKey = srvr.PrivateKey + s.protocolManager.blockLoop() +} + +func (s *LesServer) SetBloomBitsIndexer(bloomIndexer *core.ChainIndexer) { + bloomIndexer.AddChildIndexer(s.bloomTrieIndexer) +} + +// Stop stops the LES service +func (s *LesServer) Stop() { + s.fcManager.Stop() + s.chtIndexer.Close() + // bloom trie indexer is closed by parent bloombits indexer + go func() { + <-s.protocolManager.noMorePeers + }() + s.freeClientPool.stop() + s.costTracker.stop() + s.protocolManager.Stop() + s.csvLogger.Stop() +} + +// todo(rjl493456442) separate client and server implementation. +func (pm *ProtocolManager) blockLoop() { + pm.wg.Add(1) + headCh := make(chan core.ChainHeadEvent, 10) + headSub := pm.blockchain.SubscribeChainHeadEvent(headCh) + go func() { + var lastHead *types.Header + lastBroadcastTd := common.Big0 + for { + select { + case ev := <-headCh: + peers := pm.peers.AllPeers() + if len(peers) > 0 { + header := ev.Block.Header() + hash := header.Hash() + number := header.Number.Uint64() + td := rawdb.ReadTd(pm.chainDb, hash, number) + if td != nil && td.Cmp(lastBroadcastTd) > 0 { + var reorg uint64 + if lastHead != nil { + reorg = lastHead.Number.Uint64() - rawdb.FindCommonAncestor(pm.chainDb, header, lastHead).Number.Uint64() + } + lastHead = header + lastBroadcastTd = td + + log.Debug("Announcing block to peers", "number", number, "hash", hash, "td", td, "reorg", reorg) + + announce := announceData{Hash: hash, Number: number, Td: td, ReorgDepth: reorg} + var ( + signed bool + signedAnnounce announceData + ) + + for _, p := range peers { + p := p + switch p.announceType { + case announceTypeSimple: + p.queueSend(func() { p.SendAnnounce(announce) }) + case announceTypeSigned: + if !signed { + signedAnnounce = announce + signedAnnounce.sign(pm.server.privateKey) + signed = true + } + p.queueSend(func() { p.SendAnnounce(signedAnnounce) }) + } + } + } + } + case <-pm.quitSync: + headSub.Unsubscribe() + pm.wg.Done() + return + } + } + }() +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/serverpool.go b/vendor/github.com/ethereum/go-ethereum/les/serverpool.go new file mode 100644 index 00000000..3e8cdee4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/serverpool.go @@ -0,0 +1,895 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "crypto/ecdsa" + "fmt" + "io" + "math" + "math/rand" + "net" + "strconv" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + // After a connection has been ended or timed out, there is a waiting period + // before it can be selected for connection again. + // waiting period = base delay * (1 + random(1)) + // base delay = shortRetryDelay for the first shortRetryCnt times after a + // successful connection, after that longRetryDelay is applied + shortRetryCnt = 5 + shortRetryDelay = time.Second * 5 + longRetryDelay = time.Minute * 10 + // maxNewEntries is the maximum number of newly discovered (never connected) nodes. + // If the limit is reached, the least recently discovered one is thrown out. + maxNewEntries = 1000 + // maxKnownEntries is the maximum number of known (already connected) nodes. + // If the limit is reached, the least recently connected one is thrown out. + // (not that unlike new entries, known entries are persistent) + maxKnownEntries = 1000 + // target for simultaneously connected servers + targetServerCount = 5 + // target for servers selected from the known table + // (we leave room for trying new ones if there is any) + targetKnownSelect = 3 + // after dialTimeout, consider the server unavailable and adjust statistics + dialTimeout = time.Second * 30 + // targetConnTime is the minimum expected connection duration before a server + // drops a client without any specific reason + targetConnTime = time.Minute * 10 + // new entry selection weight calculation based on most recent discovery time: + // unity until discoverExpireStart, then exponential decay with discoverExpireConst + discoverExpireStart = time.Minute * 20 + discoverExpireConst = time.Minute * 20 + // known entry selection weight is dropped by a factor of exp(-failDropLn) after + // each unsuccessful connection (restored after a successful one) + failDropLn = 0.1 + // known node connection success and quality statistics have a long term average + // and a short term value which is adjusted exponentially with a factor of + // pstatRecentAdjust with each dial/connection and also returned exponentially + // to the average with the time constant pstatReturnToMeanTC + pstatReturnToMeanTC = time.Hour + // node address selection weight is dropped by a factor of exp(-addrFailDropLn) after + // each unsuccessful connection (restored after a successful one) + addrFailDropLn = math.Ln2 + // responseScoreTC and delayScoreTC are exponential decay time constants for + // calculating selection chances from response times and block delay times + responseScoreTC = time.Millisecond * 100 + delayScoreTC = time.Second * 5 + timeoutPow = 10 + // initStatsWeight is used to initialize previously unknown peers with good + // statistics to give a chance to prove themselves + initStatsWeight = 1 +) + +// connReq represents a request for peer connection. +type connReq struct { + p *peer + node *enode.Node + result chan *poolEntry +} + +// disconnReq represents a request for peer disconnection. +type disconnReq struct { + entry *poolEntry + stopped bool + done chan struct{} +} + +// registerReq represents a request for peer registration. +type registerReq struct { + entry *poolEntry + done chan struct{} +} + +// serverPool implements a pool for storing and selecting newly discovered and already +// known light server nodes. It received discovered nodes, stores statistics about +// known nodes and takes care of always having enough good quality servers connected. +type serverPool struct { + db ethdb.Database + dbKey []byte + server *p2p.Server + quit chan struct{} + wg *sync.WaitGroup + connWg sync.WaitGroup + + topic discv5.Topic + + discSetPeriod chan time.Duration + discNodes chan *enode.Node + discLookups chan bool + + trustedNodes map[enode.ID]*enode.Node + entries map[enode.ID]*poolEntry + timeout, enableRetry chan *poolEntry + adjustStats chan poolStatAdjust + + knownQueue, newQueue poolEntryQueue + knownSelect, newSelect *weightedRandomSelect + knownSelected, newSelected int + fastDiscover bool + connCh chan *connReq + disconnCh chan *disconnReq + registerCh chan *registerReq +} + +// newServerPool creates a new serverPool instance +func newServerPool(db ethdb.Database, quit chan struct{}, wg *sync.WaitGroup, trustedNodes []string) *serverPool { + pool := &serverPool{ + db: db, + quit: quit, + wg: wg, + entries: make(map[enode.ID]*poolEntry), + timeout: make(chan *poolEntry, 1), + adjustStats: make(chan poolStatAdjust, 100), + enableRetry: make(chan *poolEntry, 1), + connCh: make(chan *connReq), + disconnCh: make(chan *disconnReq), + registerCh: make(chan *registerReq), + knownSelect: newWeightedRandomSelect(), + newSelect: newWeightedRandomSelect(), + fastDiscover: true, + trustedNodes: parseTrustedNodes(trustedNodes), + } + + pool.knownQueue = newPoolEntryQueue(maxKnownEntries, pool.removeEntry) + pool.newQueue = newPoolEntryQueue(maxNewEntries, pool.removeEntry) + return pool +} + +func (pool *serverPool) start(server *p2p.Server, topic discv5.Topic) { + pool.server = server + pool.topic = topic + pool.dbKey = append([]byte("serverPool/"), []byte(topic)...) + pool.wg.Add(1) + pool.loadNodes() + pool.connectToTrustedNodes() + + if pool.server.DiscV5 != nil { + pool.discSetPeriod = make(chan time.Duration, 1) + pool.discNodes = make(chan *enode.Node, 100) + pool.discLookups = make(chan bool, 100) + go pool.discoverNodes() + } + pool.checkDial() + go pool.eventLoop() +} + +// discoverNodes wraps SearchTopic, converting result nodes to enode.Node. +func (pool *serverPool) discoverNodes() { + ch := make(chan *discv5.Node) + go func() { + pool.server.DiscV5.SearchTopic(pool.topic, pool.discSetPeriod, ch, pool.discLookups) + close(ch) + }() + for n := range ch { + pubkey, err := decodePubkey64(n.ID[:]) + if err != nil { + continue + } + pool.discNodes <- enode.NewV4(pubkey, n.IP, int(n.TCP), int(n.UDP)) + } +} + +// connect should be called upon any incoming connection. If the connection has been +// dialed by the server pool recently, the appropriate pool entry is returned. +// Otherwise, the connection should be rejected. +// Note that whenever a connection has been accepted and a pool entry has been returned, +// disconnect should also always be called. +func (pool *serverPool) connect(p *peer, node *enode.Node) *poolEntry { + log.Debug("Connect new entry", "enode", p.id) + req := &connReq{p: p, node: node, result: make(chan *poolEntry, 1)} + select { + case pool.connCh <- req: + case <-pool.quit: + return nil + } + return <-req.result +} + +// registered should be called after a successful handshake +func (pool *serverPool) registered(entry *poolEntry) { + log.Debug("Registered new entry", "enode", entry.node.ID()) + req := ®isterReq{entry: entry, done: make(chan struct{})} + select { + case pool.registerCh <- req: + case <-pool.quit: + return + } + <-req.done +} + +// disconnect should be called when ending a connection. Service quality statistics +// can be updated optionally (not updated if no registration happened, in this case +// only connection statistics are updated, just like in case of timeout) +func (pool *serverPool) disconnect(entry *poolEntry) { + stopped := false + select { + case <-pool.quit: + stopped = true + default: + } + log.Debug("Disconnected old entry", "enode", entry.node.ID()) + req := &disconnReq{entry: entry, stopped: stopped, done: make(chan struct{})} + + // Block until disconnection request is served. + pool.disconnCh <- req + <-req.done +} + +const ( + pseBlockDelay = iota + pseResponseTime + pseResponseTimeout +) + +// poolStatAdjust records are sent to adjust peer block delay/response time statistics +type poolStatAdjust struct { + adjustType int + entry *poolEntry + time time.Duration +} + +// adjustBlockDelay adjusts the block announce delay statistics of a node +func (pool *serverPool) adjustBlockDelay(entry *poolEntry, time time.Duration) { + if entry == nil { + return + } + pool.adjustStats <- poolStatAdjust{pseBlockDelay, entry, time} +} + +// adjustResponseTime adjusts the request response time statistics of a node +func (pool *serverPool) adjustResponseTime(entry *poolEntry, time time.Duration, timeout bool) { + if entry == nil { + return + } + if timeout { + pool.adjustStats <- poolStatAdjust{pseResponseTimeout, entry, time} + } else { + pool.adjustStats <- poolStatAdjust{pseResponseTime, entry, time} + } +} + +// eventLoop handles pool events and mutex locking for all internal functions +func (pool *serverPool) eventLoop() { + lookupCnt := 0 + var convTime mclock.AbsTime + if pool.discSetPeriod != nil { + pool.discSetPeriod <- time.Millisecond * 100 + } + + // disconnect updates service quality statistics depending on the connection time + // and disconnection initiator. + disconnect := func(req *disconnReq, stopped bool) { + // Handle peer disconnection requests. + entry := req.entry + if entry.state == psRegistered { + connAdjust := float64(mclock.Now()-entry.regTime) / float64(targetConnTime) + if connAdjust > 1 { + connAdjust = 1 + } + if stopped { + // disconnect requested by ourselves. + entry.connectStats.add(1, connAdjust) + } else { + // disconnect requested by server side. + entry.connectStats.add(connAdjust, 1) + } + } + entry.state = psNotConnected + + if entry.knownSelected { + pool.knownSelected-- + } else { + pool.newSelected-- + } + pool.setRetryDial(entry) + pool.connWg.Done() + close(req.done) + } + + for { + select { + case entry := <-pool.timeout: + if !entry.removed { + pool.checkDialTimeout(entry) + } + + case entry := <-pool.enableRetry: + if !entry.removed { + entry.delayedRetry = false + pool.updateCheckDial(entry) + } + + case adj := <-pool.adjustStats: + switch adj.adjustType { + case pseBlockDelay: + adj.entry.delayStats.add(float64(adj.time), 1) + case pseResponseTime: + adj.entry.responseStats.add(float64(adj.time), 1) + adj.entry.timeoutStats.add(0, 1) + case pseResponseTimeout: + adj.entry.timeoutStats.add(1, 1) + } + + case node := <-pool.discNodes: + if pool.trustedNodes[node.ID()] == nil { + entry := pool.findOrNewNode(node) + pool.updateCheckDial(entry) + } + + case conv := <-pool.discLookups: + if conv { + if lookupCnt == 0 { + convTime = mclock.Now() + } + lookupCnt++ + if pool.fastDiscover && (lookupCnt == 50 || time.Duration(mclock.Now()-convTime) > time.Minute) { + pool.fastDiscover = false + if pool.discSetPeriod != nil { + pool.discSetPeriod <- time.Minute + } + } + } + + case req := <-pool.connCh: + if pool.trustedNodes[req.p.ID()] != nil { + // ignore trusted nodes + req.result <- nil + } else { + // Handle peer connection requests. + entry := pool.entries[req.p.ID()] + if entry == nil { + entry = pool.findOrNewNode(req.node) + } + if entry.state == psConnected || entry.state == psRegistered { + req.result <- nil + continue + } + pool.connWg.Add(1) + entry.peer = req.p + entry.state = psConnected + addr := &poolEntryAddress{ + ip: req.node.IP(), + port: uint16(req.node.TCP()), + lastSeen: mclock.Now(), + } + entry.lastConnected = addr + entry.addr = make(map[string]*poolEntryAddress) + entry.addr[addr.strKey()] = addr + entry.addrSelect = *newWeightedRandomSelect() + entry.addrSelect.update(addr) + req.result <- entry + } + + case req := <-pool.registerCh: + // Handle peer registration requests. + entry := req.entry + entry.state = psRegistered + entry.regTime = mclock.Now() + if !entry.known { + pool.newQueue.remove(entry) + entry.known = true + } + pool.knownQueue.setLatest(entry) + entry.shortRetry = shortRetryCnt + close(req.done) + + case req := <-pool.disconnCh: + // Handle peer disconnection requests. + disconnect(req, req.stopped) + + case <-pool.quit: + if pool.discSetPeriod != nil { + close(pool.discSetPeriod) + } + + // Spawn a goroutine to close the disconnCh after all connections are disconnected. + go func() { + pool.connWg.Wait() + close(pool.disconnCh) + }() + + // Handle all remaining disconnection requests before exit. + for req := range pool.disconnCh { + disconnect(req, true) + } + pool.saveNodes() + pool.wg.Done() + return + } + } +} + +func (pool *serverPool) findOrNewNode(node *enode.Node) *poolEntry { + now := mclock.Now() + entry := pool.entries[node.ID()] + if entry == nil { + log.Debug("Discovered new entry", "id", node.ID()) + entry = &poolEntry{ + node: node, + addr: make(map[string]*poolEntryAddress), + addrSelect: *newWeightedRandomSelect(), + shortRetry: shortRetryCnt, + } + pool.entries[node.ID()] = entry + // initialize previously unknown peers with good statistics to give a chance to prove themselves + entry.connectStats.add(1, initStatsWeight) + entry.delayStats.add(0, initStatsWeight) + entry.responseStats.add(0, initStatsWeight) + entry.timeoutStats.add(0, initStatsWeight) + } + entry.lastDiscovered = now + addr := &poolEntryAddress{ip: node.IP(), port: uint16(node.TCP())} + if a, ok := entry.addr[addr.strKey()]; ok { + addr = a + } else { + entry.addr[addr.strKey()] = addr + } + addr.lastSeen = now + entry.addrSelect.update(addr) + if !entry.known { + pool.newQueue.setLatest(entry) + } + return entry +} + +// loadNodes loads known nodes and their statistics from the database +func (pool *serverPool) loadNodes() { + enc, err := pool.db.Get(pool.dbKey) + if err != nil { + return + } + var list []*poolEntry + err = rlp.DecodeBytes(enc, &list) + if err != nil { + log.Debug("Failed to decode node list", "err", err) + return + } + for _, e := range list { + log.Debug("Loaded server stats", "id", e.node.ID(), "fails", e.lastConnected.fails, + "conn", fmt.Sprintf("%v/%v", e.connectStats.avg, e.connectStats.weight), + "delay", fmt.Sprintf("%v/%v", time.Duration(e.delayStats.avg), e.delayStats.weight), + "response", fmt.Sprintf("%v/%v", time.Duration(e.responseStats.avg), e.responseStats.weight), + "timeout", fmt.Sprintf("%v/%v", e.timeoutStats.avg, e.timeoutStats.weight)) + pool.entries[e.node.ID()] = e + if pool.trustedNodes[e.node.ID()] == nil { + pool.knownQueue.setLatest(e) + pool.knownSelect.update((*knownEntry)(e)) + } + } +} + +// connectToTrustedNodes adds trusted server nodes as static trusted peers. +// +// Note: trusted nodes are not handled by the server pool logic, they are not +// added to either the known or new selection pools. They are connected/reconnected +// by p2p.Server whenever possible. +func (pool *serverPool) connectToTrustedNodes() { + //connect to trusted nodes + for _, node := range pool.trustedNodes { + pool.server.AddTrustedPeer(node) + pool.server.AddPeer(node) + log.Debug("Added trusted node", "id", node.ID().String()) + } +} + +// parseTrustedNodes returns valid and parsed enodes +func parseTrustedNodes(trustedNodes []string) map[enode.ID]*enode.Node { + nodes := make(map[enode.ID]*enode.Node) + + for _, node := range trustedNodes { + node, err := enode.Parse(enode.ValidSchemes, node) + if err != nil { + log.Warn("Trusted node URL invalid", "enode", node, "err", err) + continue + } + nodes[node.ID()] = node + } + return nodes +} + +// saveNodes saves known nodes and their statistics into the database. Nodes are +// ordered from least to most recently connected. +func (pool *serverPool) saveNodes() { + list := make([]*poolEntry, len(pool.knownQueue.queue)) + for i := range list { + list[i] = pool.knownQueue.fetchOldest() + } + enc, err := rlp.EncodeToBytes(list) + if err == nil { + pool.db.Put(pool.dbKey, enc) + } +} + +// removeEntry removes a pool entry when the entry count limit is reached. +// Note that it is called by the new/known queues from which the entry has already +// been removed so removing it from the queues is not necessary. +func (pool *serverPool) removeEntry(entry *poolEntry) { + pool.newSelect.remove((*discoveredEntry)(entry)) + pool.knownSelect.remove((*knownEntry)(entry)) + entry.removed = true + delete(pool.entries, entry.node.ID()) +} + +// setRetryDial starts the timer which will enable dialing a certain node again +func (pool *serverPool) setRetryDial(entry *poolEntry) { + delay := longRetryDelay + if entry.shortRetry > 0 { + entry.shortRetry-- + delay = shortRetryDelay + } + delay += time.Duration(rand.Int63n(int64(delay) + 1)) + entry.delayedRetry = true + go func() { + select { + case <-pool.quit: + case <-time.After(delay): + select { + case <-pool.quit: + case pool.enableRetry <- entry: + } + } + }() +} + +// updateCheckDial is called when an entry can potentially be dialed again. It updates +// its selection weights and checks if new dials can/should be made. +func (pool *serverPool) updateCheckDial(entry *poolEntry) { + pool.newSelect.update((*discoveredEntry)(entry)) + pool.knownSelect.update((*knownEntry)(entry)) + pool.checkDial() +} + +// checkDial checks if new dials can/should be made. It tries to select servers both +// based on good statistics and recent discovery. +func (pool *serverPool) checkDial() { + fillWithKnownSelects := !pool.fastDiscover + for pool.knownSelected < targetKnownSelect { + entry := pool.knownSelect.choose() + if entry == nil { + fillWithKnownSelects = false + break + } + pool.dial((*poolEntry)(entry.(*knownEntry)), true) + } + for pool.knownSelected+pool.newSelected < targetServerCount { + entry := pool.newSelect.choose() + if entry == nil { + break + } + pool.dial((*poolEntry)(entry.(*discoveredEntry)), false) + } + if fillWithKnownSelects { + // no more newly discovered nodes to select and since fast discover period + // is over, we probably won't find more in the near future so select more + // known entries if possible + for pool.knownSelected < targetServerCount { + entry := pool.knownSelect.choose() + if entry == nil { + break + } + pool.dial((*poolEntry)(entry.(*knownEntry)), true) + } + } +} + +// dial initiates a new connection +func (pool *serverPool) dial(entry *poolEntry, knownSelected bool) { + if pool.server == nil || entry.state != psNotConnected { + return + } + entry.state = psDialed + entry.knownSelected = knownSelected + if knownSelected { + pool.knownSelected++ + } else { + pool.newSelected++ + } + addr := entry.addrSelect.choose().(*poolEntryAddress) + log.Debug("Dialing new peer", "lesaddr", entry.node.ID().String()+"@"+addr.strKey(), "set", len(entry.addr), "known", knownSelected) + entry.dialed = addr + go func() { + pool.server.AddPeer(entry.node) + select { + case <-pool.quit: + case <-time.After(dialTimeout): + select { + case <-pool.quit: + case pool.timeout <- entry: + } + } + }() +} + +// checkDialTimeout checks if the node is still in dialed state and if so, resets it +// and adjusts connection statistics accordingly. +func (pool *serverPool) checkDialTimeout(entry *poolEntry) { + if entry.state != psDialed { + return + } + log.Debug("Dial timeout", "lesaddr", entry.node.ID().String()+"@"+entry.dialed.strKey()) + entry.state = psNotConnected + if entry.knownSelected { + pool.knownSelected-- + } else { + pool.newSelected-- + } + entry.connectStats.add(0, 1) + entry.dialed.fails++ + pool.setRetryDial(entry) +} + +const ( + psNotConnected = iota + psDialed + psConnected + psRegistered +) + +// poolEntry represents a server node and stores its current state and statistics. +type poolEntry struct { + peer *peer + pubkey [64]byte // secp256k1 key of the node + addr map[string]*poolEntryAddress + node *enode.Node + lastConnected, dialed *poolEntryAddress + addrSelect weightedRandomSelect + + lastDiscovered mclock.AbsTime + known, knownSelected bool + connectStats, delayStats poolStats + responseStats, timeoutStats poolStats + state int + regTime mclock.AbsTime + queueIdx int + removed bool + + delayedRetry bool + shortRetry int +} + +// poolEntryEnc is the RLP encoding of poolEntry. +type poolEntryEnc struct { + Pubkey []byte + IP net.IP + Port uint16 + Fails uint + CStat, DStat, RStat, TStat poolStats +} + +func (e *poolEntry) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, &poolEntryEnc{ + Pubkey: encodePubkey64(e.node.Pubkey()), + IP: e.lastConnected.ip, + Port: e.lastConnected.port, + Fails: e.lastConnected.fails, + CStat: e.connectStats, + DStat: e.delayStats, + RStat: e.responseStats, + TStat: e.timeoutStats, + }) +} + +func (e *poolEntry) DecodeRLP(s *rlp.Stream) error { + var entry poolEntryEnc + if err := s.Decode(&entry); err != nil { + return err + } + pubkey, err := decodePubkey64(entry.Pubkey) + if err != nil { + return err + } + addr := &poolEntryAddress{ip: entry.IP, port: entry.Port, fails: entry.Fails, lastSeen: mclock.Now()} + e.node = enode.NewV4(pubkey, entry.IP, int(entry.Port), int(entry.Port)) + e.addr = make(map[string]*poolEntryAddress) + e.addr[addr.strKey()] = addr + e.addrSelect = *newWeightedRandomSelect() + e.addrSelect.update(addr) + e.lastConnected = addr + e.connectStats = entry.CStat + e.delayStats = entry.DStat + e.responseStats = entry.RStat + e.timeoutStats = entry.TStat + e.shortRetry = shortRetryCnt + e.known = true + return nil +} + +func encodePubkey64(pub *ecdsa.PublicKey) []byte { + return crypto.FromECDSAPub(pub)[1:] +} + +func decodePubkey64(b []byte) (*ecdsa.PublicKey, error) { + return crypto.UnmarshalPubkey(append([]byte{0x04}, b...)) +} + +// discoveredEntry implements wrsItem +type discoveredEntry poolEntry + +// Weight calculates random selection weight for newly discovered entries +func (e *discoveredEntry) Weight() int64 { + if e.state != psNotConnected || e.delayedRetry { + return 0 + } + t := time.Duration(mclock.Now() - e.lastDiscovered) + if t <= discoverExpireStart { + return 1000000000 + } + return int64(1000000000 * math.Exp(-float64(t-discoverExpireStart)/float64(discoverExpireConst))) +} + +// knownEntry implements wrsItem +type knownEntry poolEntry + +// Weight calculates random selection weight for known entries +func (e *knownEntry) Weight() int64 { + if e.state != psNotConnected || !e.known || e.delayedRetry { + return 0 + } + return int64(1000000000 * e.connectStats.recentAvg() * math.Exp(-float64(e.lastConnected.fails)*failDropLn-e.responseStats.recentAvg()/float64(responseScoreTC)-e.delayStats.recentAvg()/float64(delayScoreTC)) * math.Pow(1-e.timeoutStats.recentAvg(), timeoutPow)) +} + +// poolEntryAddress is a separate object because currently it is necessary to remember +// multiple potential network addresses for a pool entry. This will be removed after +// the final implementation of v5 discovery which will retrieve signed and serial +// numbered advertisements, making it clear which IP/port is the latest one. +type poolEntryAddress struct { + ip net.IP + port uint16 + lastSeen mclock.AbsTime // last time it was discovered, connected or loaded from db + fails uint // connection failures since last successful connection (persistent) +} + +func (a *poolEntryAddress) Weight() int64 { + t := time.Duration(mclock.Now() - a.lastSeen) + return int64(1000000*math.Exp(-float64(t)/float64(discoverExpireConst)-float64(a.fails)*addrFailDropLn)) + 1 +} + +func (a *poolEntryAddress) strKey() string { + return a.ip.String() + ":" + strconv.Itoa(int(a.port)) +} + +// poolStats implement statistics for a certain quantity with a long term average +// and a short term value which is adjusted exponentially with a factor of +// pstatRecentAdjust with each update and also returned exponentially to the +// average with the time constant pstatReturnToMeanTC +type poolStats struct { + sum, weight, avg, recent float64 + lastRecalc mclock.AbsTime +} + +// init initializes stats with a long term sum/update count pair retrieved from the database +func (s *poolStats) init(sum, weight float64) { + s.sum = sum + s.weight = weight + var avg float64 + if weight > 0 { + avg = s.sum / weight + } + s.avg = avg + s.recent = avg + s.lastRecalc = mclock.Now() +} + +// recalc recalculates recent value return-to-mean and long term average +func (s *poolStats) recalc() { + now := mclock.Now() + s.recent = s.avg + (s.recent-s.avg)*math.Exp(-float64(now-s.lastRecalc)/float64(pstatReturnToMeanTC)) + if s.sum == 0 { + s.avg = 0 + } else { + if s.sum > s.weight*1e30 { + s.avg = 1e30 + } else { + s.avg = s.sum / s.weight + } + } + s.lastRecalc = now +} + +// add updates the stats with a new value +func (s *poolStats) add(value, weight float64) { + s.weight += weight + s.sum += value * weight + s.recalc() +} + +// recentAvg returns the short-term adjusted average +func (s *poolStats) recentAvg() float64 { + s.recalc() + return s.recent +} + +func (s *poolStats) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{math.Float64bits(s.sum), math.Float64bits(s.weight)}) +} + +func (s *poolStats) DecodeRLP(st *rlp.Stream) error { + var stats struct { + SumUint, WeightUint uint64 + } + if err := st.Decode(&stats); err != nil { + return err + } + s.init(math.Float64frombits(stats.SumUint), math.Float64frombits(stats.WeightUint)) + return nil +} + +// poolEntryQueue keeps track of its least recently accessed entries and removes +// them when the number of entries reaches the limit +type poolEntryQueue struct { + queue map[int]*poolEntry // known nodes indexed by their latest lastConnCnt value + newPtr, oldPtr, maxCnt int + removeFromPool func(*poolEntry) +} + +// newPoolEntryQueue returns a new poolEntryQueue +func newPoolEntryQueue(maxCnt int, removeFromPool func(*poolEntry)) poolEntryQueue { + return poolEntryQueue{queue: make(map[int]*poolEntry), maxCnt: maxCnt, removeFromPool: removeFromPool} +} + +// fetchOldest returns and removes the least recently accessed entry +func (q *poolEntryQueue) fetchOldest() *poolEntry { + if len(q.queue) == 0 { + return nil + } + for { + if e := q.queue[q.oldPtr]; e != nil { + delete(q.queue, q.oldPtr) + q.oldPtr++ + return e + } + q.oldPtr++ + } +} + +// remove removes an entry from the queue +func (q *poolEntryQueue) remove(entry *poolEntry) { + if q.queue[entry.queueIdx] == entry { + delete(q.queue, entry.queueIdx) + } +} + +// setLatest adds or updates a recently accessed entry. It also checks if an old entry +// needs to be removed and removes it from the parent pool too with a callback function. +func (q *poolEntryQueue) setLatest(entry *poolEntry) { + if q.queue[entry.queueIdx] == entry { + delete(q.queue, entry.queueIdx) + } else { + if len(q.queue) == q.maxCnt { + e := q.fetchOldest() + q.remove(e) + q.removeFromPool(e) + } + } + entry.queueIdx = q.newPtr + q.queue[entry.queueIdx] = entry + q.newPtr++ +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/servingqueue.go b/vendor/github.com/ethereum/go-ethereum/les/servingqueue.go new file mode 100644 index 00000000..26656ec0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/servingqueue.go @@ -0,0 +1,394 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "fmt" + "sort" + "sync" + "sync/atomic" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/les/csvlogger" +) + +// servingQueue allows running tasks in a limited number of threads and puts the +// waiting tasks in a priority queue +type servingQueue struct { + recentTime, queuedTime, servingTimeDiff uint64 + burstLimit, burstDropLimit uint64 + burstDecRate float64 + lastUpdate mclock.AbsTime + + queueAddCh, queueBestCh chan *servingTask + stopThreadCh, quit chan struct{} + setThreadsCh chan int + + wg sync.WaitGroup + threadCount int // number of currently running threads + queue *prque.Prque // priority queue for waiting or suspended tasks + best *servingTask // the highest priority task (not included in the queue) + suspendBias int64 // priority bias against suspending an already running task + + logger *csvlogger.Logger + logRecentTime *csvlogger.Channel + logQueuedTime *csvlogger.Channel +} + +// servingTask represents a request serving task. Tasks can be implemented to +// run in multiple steps, allowing the serving queue to suspend execution between +// steps if higher priority tasks are entered. The creator of the task should +// set the following fields: +// +// - priority: greater value means higher priority; values can wrap around the int64 range +// - run: execute a single step; return true if finished +// - after: executed after run finishes or returns an error, receives the total serving time +type servingTask struct { + sq *servingQueue + servingTime, timeAdded, maxTime, expTime uint64 + peer *peer + priority int64 + biasAdded bool + token runToken + tokenCh chan runToken +} + +// runToken received by servingTask.start allows the task to run. Closing the +// channel by servingTask.stop signals the thread controller to allow a new task +// to start running. +type runToken chan struct{} + +// start blocks until the task can start and returns true if it is allowed to run. +// Returning false means that the task should be cancelled. +func (t *servingTask) start() bool { + if t.peer.isFrozen() { + return false + } + t.tokenCh = make(chan runToken, 1) + select { + case t.sq.queueAddCh <- t: + case <-t.sq.quit: + return false + } + select { + case t.token = <-t.tokenCh: + case <-t.sq.quit: + return false + } + if t.token == nil { + return false + } + t.servingTime -= uint64(mclock.Now()) + return true +} + +// done signals the thread controller about the task being finished and returns +// the total serving time of the task in nanoseconds. +func (t *servingTask) done() uint64 { + t.servingTime += uint64(mclock.Now()) + close(t.token) + diff := t.servingTime - t.timeAdded + t.timeAdded = t.servingTime + if t.expTime > diff { + t.expTime -= diff + atomic.AddUint64(&t.sq.servingTimeDiff, t.expTime) + } else { + t.expTime = 0 + } + return t.servingTime +} + +// waitOrStop can be called during the execution of the task. It blocks if there +// is a higher priority task waiting (a bias is applied in favor of the currently +// running task). Returning true means that the execution can be resumed. False +// means the task should be cancelled. +func (t *servingTask) waitOrStop() bool { + t.done() + if !t.biasAdded { + t.priority += t.sq.suspendBias + t.biasAdded = true + } + return t.start() +} + +// newServingQueue returns a new servingQueue +func newServingQueue(suspendBias int64, utilTarget float64, logger *csvlogger.Logger) *servingQueue { + sq := &servingQueue{ + queue: prque.New(nil), + suspendBias: suspendBias, + queueAddCh: make(chan *servingTask, 100), + queueBestCh: make(chan *servingTask), + stopThreadCh: make(chan struct{}), + quit: make(chan struct{}), + setThreadsCh: make(chan int, 10), + burstLimit: uint64(utilTarget * bufLimitRatio * 1200000), + burstDropLimit: uint64(utilTarget * bufLimitRatio * 1000000), + burstDecRate: utilTarget, + lastUpdate: mclock.Now(), + logger: logger, + logRecentTime: logger.NewMinMaxChannel("recentTime", false), + logQueuedTime: logger.NewMinMaxChannel("queuedTime", false), + } + sq.wg.Add(2) + go sq.queueLoop() + go sq.threadCountLoop() + return sq +} + +// newTask creates a new task with the given priority +func (sq *servingQueue) newTask(peer *peer, maxTime uint64, priority int64) *servingTask { + return &servingTask{ + sq: sq, + peer: peer, + maxTime: maxTime, + expTime: maxTime, + priority: priority, + } +} + +// threadController is started in multiple goroutines and controls the execution +// of tasks. The number of active thread controllers equals the allowed number of +// concurrently running threads. It tries to fetch the highest priority queued +// task first. If there are no queued tasks waiting then it can directly catch +// run tokens from the token channel and allow the corresponding tasks to run +// without entering the priority queue. +func (sq *servingQueue) threadController() { + for { + token := make(runToken) + select { + case best := <-sq.queueBestCh: + best.tokenCh <- token + case <-sq.stopThreadCh: + sq.wg.Done() + return + case <-sq.quit: + sq.wg.Done() + return + } + <-token + select { + case <-sq.stopThreadCh: + sq.wg.Done() + return + case <-sq.quit: + sq.wg.Done() + return + default: + } + } +} + +type ( + // peerTasks lists the tasks received from a given peer when selecting peers to freeze + peerTasks struct { + peer *peer + list []*servingTask + sumTime uint64 + priority float64 + } + // peerList is a sortable list of peerTasks + peerList []*peerTasks +) + +func (l peerList) Len() int { + return len(l) +} + +func (l peerList) Less(i, j int) bool { + return l[i].priority < l[j].priority +} + +func (l peerList) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} + +// freezePeers selects the peers with the worst priority queued tasks and freezes +// them until burstTime goes under burstDropLimit or all peers are frozen +func (sq *servingQueue) freezePeers() { + peerMap := make(map[*peer]*peerTasks) + var peerList peerList + if sq.best != nil { + sq.queue.Push(sq.best, sq.best.priority) + } + sq.best = nil + for sq.queue.Size() > 0 { + task := sq.queue.PopItem().(*servingTask) + tasks := peerMap[task.peer] + if tasks == nil { + bufValue, bufLimit := task.peer.fcClient.BufferStatus() + if bufLimit < 1 { + bufLimit = 1 + } + tasks = &peerTasks{ + peer: task.peer, + priority: float64(bufValue) / float64(bufLimit), // lower value comes first + } + peerMap[task.peer] = tasks + peerList = append(peerList, tasks) + } + tasks.list = append(tasks.list, task) + tasks.sumTime += task.expTime + } + sort.Sort(peerList) + drop := true + sq.logger.Event("freezing peers") + for _, tasks := range peerList { + if drop { + tasks.peer.freezeClient() + tasks.peer.fcClient.Freeze() + sq.queuedTime -= tasks.sumTime + if sq.logQueuedTime != nil { + sq.logQueuedTime.Update(float64(sq.queuedTime) / 1000) + } + sq.logger.Event(fmt.Sprintf("frozen peer sumTime=%d, %v", tasks.sumTime, tasks.peer.id)) + drop = sq.recentTime+sq.queuedTime > sq.burstDropLimit + for _, task := range tasks.list { + task.tokenCh <- nil + } + } else { + for _, task := range tasks.list { + sq.queue.Push(task, task.priority) + } + } + } + if sq.queue.Size() > 0 { + sq.best = sq.queue.PopItem().(*servingTask) + } +} + +// updateRecentTime recalculates the recent serving time value +func (sq *servingQueue) updateRecentTime() { + subTime := atomic.SwapUint64(&sq.servingTimeDiff, 0) + now := mclock.Now() + dt := now - sq.lastUpdate + sq.lastUpdate = now + if dt > 0 { + subTime += uint64(float64(dt) * sq.burstDecRate) + } + if sq.recentTime > subTime { + sq.recentTime -= subTime + } else { + sq.recentTime = 0 + } +} + +// addTask inserts a task into the priority queue +func (sq *servingQueue) addTask(task *servingTask) { + if sq.best == nil { + sq.best = task + } else if task.priority > sq.best.priority { + sq.queue.Push(sq.best, sq.best.priority) + sq.best = task + } else { + sq.queue.Push(task, task.priority) + } + sq.updateRecentTime() + sq.queuedTime += task.expTime + if sq.logQueuedTime != nil { + sq.logRecentTime.Update(float64(sq.recentTime) / 1000) + sq.logQueuedTime.Update(float64(sq.queuedTime) / 1000) + } + if sq.recentTime+sq.queuedTime > sq.burstLimit { + sq.freezePeers() + } +} + +// queueLoop is an event loop running in a goroutine. It receives tasks from queueAddCh +// and always tries to send the highest priority task to queueBestCh. Successfully sent +// tasks are removed from the queue. +func (sq *servingQueue) queueLoop() { + for { + if sq.best != nil { + expTime := sq.best.expTime + select { + case task := <-sq.queueAddCh: + sq.addTask(task) + case sq.queueBestCh <- sq.best: + sq.updateRecentTime() + sq.queuedTime -= expTime + sq.recentTime += expTime + if sq.logQueuedTime != nil { + sq.logRecentTime.Update(float64(sq.recentTime) / 1000) + sq.logQueuedTime.Update(float64(sq.queuedTime) / 1000) + } + if sq.queue.Size() == 0 { + sq.best = nil + } else { + sq.best, _ = sq.queue.PopItem().(*servingTask) + } + case <-sq.quit: + sq.wg.Done() + return + } + } else { + select { + case task := <-sq.queueAddCh: + sq.addTask(task) + case <-sq.quit: + sq.wg.Done() + return + } + } + } +} + +// threadCountLoop is an event loop running in a goroutine. It adjusts the number +// of active thread controller goroutines. +func (sq *servingQueue) threadCountLoop() { + var threadCountTarget int + for { + for threadCountTarget > sq.threadCount { + sq.wg.Add(1) + go sq.threadController() + sq.threadCount++ + } + if threadCountTarget < sq.threadCount { + select { + case threadCountTarget = <-sq.setThreadsCh: + case sq.stopThreadCh <- struct{}{}: + sq.threadCount-- + case <-sq.quit: + sq.wg.Done() + return + } + } else { + select { + case threadCountTarget = <-sq.setThreadsCh: + case <-sq.quit: + sq.wg.Done() + return + } + } + } +} + +// setThreads sets the allowed processing thread count, suspending tasks as soon as +// possible if necessary. +func (sq *servingQueue) setThreads(threadCount int) { + select { + case sq.setThreadsCh <- threadCount: + case <-sq.quit: + return + } +} + +// stop stops task processing as soon as possible and shuts down the serving queue. +func (sq *servingQueue) stop() { + close(sq.quit) + sq.wg.Wait() +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/transactions.rlp b/vendor/github.com/ethereum/go-ethereum/les/transactions.rlp new file mode 100755 index 00000000..e69de29b diff --git a/vendor/github.com/ethereum/go-ethereum/les/txrelay.go b/vendor/github.com/ethereum/go-ethereum/les/txrelay.go new file mode 100644 index 00000000..5ebef1c2 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/txrelay.go @@ -0,0 +1,184 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "context" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +type ltrInfo struct { + tx *types.Transaction + sentTo map[*peer]struct{} +} + +type LesTxRelay struct { + txSent map[common.Hash]*ltrInfo + txPending map[common.Hash]struct{} + ps *peerSet + peerList []*peer + peerStartPos int + lock sync.RWMutex + stop chan struct{} + + retriever *retrieveManager +} + +func NewLesTxRelay(ps *peerSet, retriever *retrieveManager) *LesTxRelay { + r := &LesTxRelay{ + txSent: make(map[common.Hash]*ltrInfo), + txPending: make(map[common.Hash]struct{}), + ps: ps, + retriever: retriever, + stop: make(chan struct{}), + } + ps.notify(r) + return r +} + +func (self *LesTxRelay) Stop() { + close(self.stop) +} + +func (self *LesTxRelay) registerPeer(p *peer) { + self.lock.Lock() + defer self.lock.Unlock() + + self.peerList = self.ps.AllPeers() +} + +func (self *LesTxRelay) unregisterPeer(p *peer) { + self.lock.Lock() + defer self.lock.Unlock() + + self.peerList = self.ps.AllPeers() +} + +// send sends a list of transactions to at most a given number of peers at +// once, never resending any particular transaction to the same peer twice +func (self *LesTxRelay) send(txs types.Transactions, count int) { + sendTo := make(map[*peer]types.Transactions) + + self.peerStartPos++ // rotate the starting position of the peer list + if self.peerStartPos >= len(self.peerList) { + self.peerStartPos = 0 + } + + for _, tx := range txs { + hash := tx.Hash() + ltr, ok := self.txSent[hash] + if !ok { + ltr = <rInfo{ + tx: tx, + sentTo: make(map[*peer]struct{}), + } + self.txSent[hash] = ltr + self.txPending[hash] = struct{}{} + } + + if len(self.peerList) > 0 { + cnt := count + pos := self.peerStartPos + for { + peer := self.peerList[pos] + if _, ok := ltr.sentTo[peer]; !ok { + sendTo[peer] = append(sendTo[peer], tx) + ltr.sentTo[peer] = struct{}{} + cnt-- + } + if cnt == 0 { + break // sent it to the desired number of peers + } + pos++ + if pos == len(self.peerList) { + pos = 0 + } + if pos == self.peerStartPos { + break // tried all available peers + } + } + } + } + + for p, list := range sendTo { + pp := p + ll := list + enc, _ := rlp.EncodeToBytes(ll) + + reqID := genReqID() + rq := &distReq{ + getCost: func(dp distPeer) uint64 { + peer := dp.(*peer) + return peer.GetTxRelayCost(len(ll), len(enc)) + }, + canSend: func(dp distPeer) bool { + return !dp.(*peer).isOnlyAnnounce && dp.(*peer) == pp + }, + request: func(dp distPeer) func() { + peer := dp.(*peer) + cost := peer.GetTxRelayCost(len(ll), len(enc)) + peer.fcServer.QueuedRequest(reqID, cost) + return func() { peer.SendTxs(reqID, cost, enc) } + }, + } + go self.retriever.retrieve(context.Background(), reqID, rq, func(p distPeer, msg *Msg) error { return nil }, self.stop) + } +} + +func (self *LesTxRelay) Send(txs types.Transactions) { + self.lock.Lock() + defer self.lock.Unlock() + + self.send(txs, 3) +} + +func (self *LesTxRelay) NewHead(head common.Hash, mined []common.Hash, rollback []common.Hash) { + self.lock.Lock() + defer self.lock.Unlock() + + for _, hash := range mined { + delete(self.txPending, hash) + } + + for _, hash := range rollback { + self.txPending[hash] = struct{}{} + } + + if len(self.txPending) > 0 { + txs := make(types.Transactions, len(self.txPending)) + i := 0 + for hash := range self.txPending { + txs[i] = self.txSent[hash].tx + i++ + } + self.send(txs, 1) + } +} + +func (self *LesTxRelay) Discard(hashes []common.Hash) { + self.lock.Lock() + defer self.lock.Unlock() + + for _, hash := range hashes { + delete(self.txSent, hash) + delete(self.txPending, hash) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/les/ulc.go b/vendor/github.com/ethereum/go-ethereum/les/ulc.go new file mode 100644 index 00000000..8792f60d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/les/ulc.go @@ -0,0 +1,54 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package les + +import ( + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +type ulc struct { + trustedKeys map[string]struct{} + minTrustedFraction int +} + +// newULC creates and returns a ultra light client instance. +func newULC(ulcConfig *eth.ULCConfig) *ulc { + if ulcConfig == nil { + return nil + } + m := make(map[string]struct{}, len(ulcConfig.TrustedServers)) + for _, id := range ulcConfig.TrustedServers { + node, err := enode.Parse(enode.ValidSchemes, id) + if err != nil { + log.Debug("Failed to parse trusted server", "id", id, "err", err) + continue + } + m[node.ID().String()] = struct{}{} + } + return &ulc{m, ulcConfig.MinTrustedFraction} +} + +// isTrusted return an indicator that whether the specified peer is trusted. +func (u *ulc) isTrusted(p enode.ID) bool { + if u.trustedKeys == nil { + return false + } + _, ok := u.trustedKeys[p.String()] + return ok +} diff --git a/vendor/github.com/ethereum/go-ethereum/light/lightchain.go b/vendor/github.com/ethereum/go-ethereum/light/lightchain.go new file mode 100644 index 00000000..f0beec47 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/lightchain.go @@ -0,0 +1,542 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package light implements on-demand retrieval capable state and chain objects +// for the Ethereum Light Client. +package light + +import ( + "context" + "errors" + "math/big" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + lru "github.com/hashicorp/golang-lru" +) + +var ( + bodyCacheLimit = 256 + blockCacheLimit = 256 +) + +// LightChain represents a canonical chain that by default only handles block +// headers, downloading block bodies and receipts on demand through an ODR +// interface. It only does header validation during chain insertion. +type LightChain struct { + hc *core.HeaderChain + indexerConfig *IndexerConfig + chainDb ethdb.Database + engine consensus.Engine + odr OdrBackend + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block + + bodyCache *lru.Cache // Cache for the most recent block bodies + bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format + blockCache *lru.Cache // Cache for the most recent entire blocks + + chainmu sync.RWMutex // protects header inserts + quit chan struct{} + wg sync.WaitGroup + + // Atomic boolean switches: + running int32 // whether LightChain is running or stopped + procInterrupt int32 // interrupts chain insert + disableCheckFreq int32 // disables header verification +} + +// NewLightChain returns a fully initialised light chain using information +// available in the database. It initialises the default Ethereum header +// validator. +func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) { + bodyCache, _ := lru.New(bodyCacheLimit) + bodyRLPCache, _ := lru.New(bodyCacheLimit) + blockCache, _ := lru.New(blockCacheLimit) + + bc := &LightChain{ + chainDb: odr.Database(), + indexerConfig: odr.IndexerConfig(), + odr: odr, + quit: make(chan struct{}), + bodyCache: bodyCache, + bodyRLPCache: bodyRLPCache, + blockCache: blockCache, + engine: engine, + } + var err error + bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt) + if err != nil { + return nil, err + } + bc.genesisBlock, _ = bc.GetBlockByNumber(NoOdr, 0) + if bc.genesisBlock == nil { + return nil, core.ErrNoGenesis + } + if cp, ok := params.TrustedCheckpoints[bc.genesisBlock.Hash()]; ok { + bc.addTrustedCheckpoint(cp) + } + if err := bc.loadLastState(); err != nil { + return nil, err + } + // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain + for hash := range core.BadHashes { + if header := bc.GetHeaderByHash(hash); header != nil { + log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) + bc.SetHead(header.Number.Uint64() - 1) + log.Error("Chain rewind was successful, resuming normal operation") + } + } + return bc, nil +} + +// addTrustedCheckpoint adds a trusted checkpoint to the blockchain +func (lc *LightChain) addTrustedCheckpoint(cp *params.TrustedCheckpoint) { + if lc.odr.ChtIndexer() != nil { + StoreChtRoot(lc.chainDb, cp.SectionIndex, cp.SectionHead, cp.CHTRoot) + lc.odr.ChtIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead) + } + if lc.odr.BloomTrieIndexer() != nil { + StoreBloomTrieRoot(lc.chainDb, cp.SectionIndex, cp.SectionHead, cp.BloomRoot) + lc.odr.BloomTrieIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead) + } + if lc.odr.BloomIndexer() != nil { + lc.odr.BloomIndexer().AddCheckpoint(cp.SectionIndex, cp.SectionHead) + } + log.Info("Added trusted checkpoint", "chain", cp.Name, "block", (cp.SectionIndex+1)*lc.indexerConfig.ChtSize-1, "hash", cp.SectionHead) +} + +func (lc *LightChain) getProcInterrupt() bool { + return atomic.LoadInt32(&lc.procInterrupt) == 1 +} + +// Odr returns the ODR backend of the chain +func (lc *LightChain) Odr() OdrBackend { + return lc.odr +} + +// loadLastState loads the last known chain state from the database. This method +// assumes that the chain manager mutex is held. +func (lc *LightChain) loadLastState() error { + if head := rawdb.ReadHeadHeaderHash(lc.chainDb); head == (common.Hash{}) { + // Corrupt or empty database, init from scratch + lc.Reset() + } else { + if header := lc.GetHeaderByHash(head); header != nil { + lc.hc.SetCurrentHeader(header) + } + } + + // Issue a status log and return + header := lc.hc.CurrentHeader() + headerTd := lc.GetTd(header.Hash(), header.Number.Uint64()) + log.Info("Loaded most recent local header", "number", header.Number, "hash", header.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(header.Time), 0))) + + return nil +} + +// SetHead rewinds the local chain to a new head. Everything above the new +// head will be deleted and the new one set. +func (lc *LightChain) SetHead(head uint64) error { + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + + lc.hc.SetHead(head, nil, nil) + return lc.loadLastState() +} + +// GasLimit returns the gas limit of the current HEAD block. +func (lc *LightChain) GasLimit() uint64 { + return lc.hc.CurrentHeader().GasLimit +} + +// Reset purges the entire blockchain, restoring it to its genesis state. +func (lc *LightChain) Reset() { + lc.ResetWithGenesisBlock(lc.genesisBlock) +} + +// ResetWithGenesisBlock purges the entire blockchain, restoring it to the +// specified genesis state. +func (lc *LightChain) ResetWithGenesisBlock(genesis *types.Block) { + // Dump the entire block chain and purge the caches + lc.SetHead(0) + + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + + // Prepare the genesis block and reinitialise the chain + rawdb.WriteTd(lc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) + rawdb.WriteBlock(lc.chainDb, genesis) + + lc.genesisBlock = genesis + lc.hc.SetGenesis(lc.genesisBlock.Header()) + lc.hc.SetCurrentHeader(lc.genesisBlock.Header()) +} + +// Accessors + +// Engine retrieves the light chain's consensus engine. +func (lc *LightChain) Engine() consensus.Engine { return lc.engine } + +// Genesis returns the genesis block +func (lc *LightChain) Genesis() *types.Block { + return lc.genesisBlock +} + +func (lc *LightChain) StateCache() state.Database { + panic("not implemented") +} + +// GetBody retrieves a block body (transactions and uncles) from the database +// or ODR service by hash, caching it if found. +func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) { + // Short circuit if the body's already in the cache, retrieve otherwise + if cached, ok := lc.bodyCache.Get(hash); ok { + body := cached.(*types.Body) + return body, nil + } + number := lc.hc.GetBlockNumber(hash) + if number == nil { + return nil, errors.New("unknown block") + } + body, err := GetBody(ctx, lc.odr, hash, *number) + if err != nil { + return nil, err + } + // Cache the found body for next time and return + lc.bodyCache.Add(hash, body) + return body, nil +} + +// GetBodyRLP retrieves a block body in RLP encoding from the database or +// ODR service by hash, caching it if found. +func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) { + // Short circuit if the body's already in the cache, retrieve otherwise + if cached, ok := lc.bodyRLPCache.Get(hash); ok { + return cached.(rlp.RawValue), nil + } + number := lc.hc.GetBlockNumber(hash) + if number == nil { + return nil, errors.New("unknown block") + } + body, err := GetBodyRLP(ctx, lc.odr, hash, *number) + if err != nil { + return nil, err + } + // Cache the found body for next time and return + lc.bodyRLPCache.Add(hash, body) + return body, nil +} + +// HasBlock checks if a block is fully present in the database or not, caching +// it if present. +func (lc *LightChain) HasBlock(hash common.Hash, number uint64) bool { + blk, _ := lc.GetBlock(NoOdr, hash, number) + return blk != nil +} + +// GetBlock retrieves a block from the database or ODR service by hash and number, +// caching it if found. +func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) { + // Short circuit if the block's already in the cache, retrieve otherwise + if block, ok := lc.blockCache.Get(hash); ok { + return block.(*types.Block), nil + } + block, err := GetBlock(ctx, lc.odr, hash, number) + if err != nil { + return nil, err + } + // Cache the found block for next time and return + lc.blockCache.Add(block.Hash(), block) + return block, nil +} + +// GetBlockByHash retrieves a block from the database or ODR service by hash, +// caching it if found. +func (lc *LightChain) GetBlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + number := lc.hc.GetBlockNumber(hash) + if number == nil { + return nil, errors.New("unknown block") + } + return lc.GetBlock(ctx, hash, *number) +} + +// GetBlockByNumber retrieves a block from the database or ODR service by +// number, caching it (associated with its hash) if found. +func (lc *LightChain) GetBlockByNumber(ctx context.Context, number uint64) (*types.Block, error) { + hash, err := GetCanonicalHash(ctx, lc.odr, number) + if hash == (common.Hash{}) || err != nil { + return nil, err + } + return lc.GetBlock(ctx, hash, number) +} + +// Stop stops the blockchain service. If any imports are currently in progress +// it will abort them using the procInterrupt. +func (lc *LightChain) Stop() { + if !atomic.CompareAndSwapInt32(&lc.running, 0, 1) { + return + } + close(lc.quit) + atomic.StoreInt32(&lc.procInterrupt, 1) + + lc.wg.Wait() + log.Info("Blockchain manager stopped") +} + +// Rollback is designed to remove a chain of links from the database that aren't +// certain enough to be valid. +func (lc *LightChain) Rollback(chain []common.Hash) { + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + + for i := len(chain) - 1; i >= 0; i-- { + hash := chain[i] + + if head := lc.hc.CurrentHeader(); head.Hash() == hash { + lc.hc.SetCurrentHeader(lc.GetHeader(head.ParentHash, head.Number.Uint64()-1)) + } + } +} + +// postChainEvents iterates over the events generated by a chain insertion and +// posts them into the event feed. +func (lc *LightChain) postChainEvents(events []interface{}) { + for _, event := range events { + switch ev := event.(type) { + case core.ChainEvent: + if lc.CurrentHeader().Hash() == ev.Hash { + lc.chainHeadFeed.Send(core.ChainHeadEvent{Block: ev.Block}) + } + lc.chainFeed.Send(ev) + case core.ChainSideEvent: + lc.chainSideFeed.Send(ev) + } + } +} + +// InsertHeaderChain attempts to insert the given header chain in to the local +// chain, possibly creating a reorg. If an error is returned, it will return the +// index number of the failing header as well an error describing what went wrong. +// +// The verify parameter can be used to fine tune whether nonce verification +// should be done or not. The reason behind the optional check is because some +// of the header retrieval mechanisms already need to verfy nonces, as well as +// because nonces can be verified sparsely, not needing to check each. +// +// In the case of a light chain, InsertHeaderChain also creates and posts light +// chain events when necessary. +func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + if atomic.LoadInt32(&lc.disableCheckFreq) == 1 { + checkFreq = 0 + } + start := time.Now() + if i, err := lc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { + return i, err + } + + // Make sure only one thread manipulates the chain at once + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + + lc.wg.Add(1) + defer lc.wg.Done() + + var events []interface{} + whFunc := func(header *types.Header) error { + status, err := lc.hc.WriteHeader(header) + + switch status { + case core.CanonStatTy: + log.Debug("Inserted new header", "number", header.Number, "hash", header.Hash()) + events = append(events, core.ChainEvent{Block: types.NewBlockWithHeader(header), Hash: header.Hash()}) + + case core.SideStatTy: + log.Debug("Inserted forked header", "number", header.Number, "hash", header.Hash()) + events = append(events, core.ChainSideEvent{Block: types.NewBlockWithHeader(header)}) + } + return err + } + i, err := lc.hc.InsertHeaderChain(chain, whFunc, start) + lc.postChainEvents(events) + return i, err +} + +// CurrentHeader retrieves the current head header of the canonical chain. The +// header is retrieved from the HeaderChain's internal cache. +func (lc *LightChain) CurrentHeader() *types.Header { + return lc.hc.CurrentHeader() +} + +// GetTd retrieves a block's total difficulty in the canonical chain from the +// database by hash and number, caching it if found. +func (lc *LightChain) GetTd(hash common.Hash, number uint64) *big.Int { + return lc.hc.GetTd(hash, number) +} + +// GetTdByHash retrieves a block's total difficulty in the canonical chain from the +// database by hash, caching it if found. +func (lc *LightChain) GetTdByHash(hash common.Hash) *big.Int { + return lc.hc.GetTdByHash(hash) +} + +// GetHeader retrieves a block header from the database by hash and number, +// caching it if found. +func (lc *LightChain) GetHeader(hash common.Hash, number uint64) *types.Header { + return lc.hc.GetHeader(hash, number) +} + +// GetHeaderByHash retrieves a block header from the database by hash, caching it if +// found. +func (lc *LightChain) GetHeaderByHash(hash common.Hash) *types.Header { + return lc.hc.GetHeaderByHash(hash) +} + +// HasHeader checks if a block header is present in the database or not, caching +// it if present. +func (lc *LightChain) HasHeader(hash common.Hash, number uint64) bool { + return lc.hc.HasHeader(hash, number) +} + +// GetBlockHashesFromHash retrieves a number of block hashes starting at a given +// hash, fetching towards the genesis block. +func (lc *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { + return lc.hc.GetBlockHashesFromHash(hash, max) +} + +// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or +// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the +// number of blocks to be individually checked before we reach the canonical chain. +// +// Note: ancestor == 0 returns the same block, 1 returns its parent and so on. +func (lc *LightChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { + lc.chainmu.RLock() + defer lc.chainmu.RUnlock() + + return lc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) +} + +// GetHeaderByNumber retrieves a block header from the database by number, +// caching it (associated with its hash) if found. +func (lc *LightChain) GetHeaderByNumber(number uint64) *types.Header { + return lc.hc.GetHeaderByNumber(number) +} + +// GetHeaderByNumberOdr retrieves a block header from the database or network +// by number, caching it (associated with its hash) if found. +func (lc *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64) (*types.Header, error) { + if header := lc.hc.GetHeaderByNumber(number); header != nil { + return header, nil + } + return GetHeaderByNumber(ctx, lc.odr, number) +} + +// Config retrieves the header chain's chain configuration. +func (lc *LightChain) Config() *params.ChainConfig { return lc.hc.Config() } + +func (lc *LightChain) SyncCht(ctx context.Context) bool { + // If we don't have a CHT indexer, abort + if lc.odr.ChtIndexer() == nil { + return false + } + // Ensure the remote CHT head is ahead of us + head := lc.CurrentHeader().Number.Uint64() + sections, _, _ := lc.odr.ChtIndexer().Sections() + + latest := sections*lc.indexerConfig.ChtSize - 1 + if clique := lc.hc.Config().Clique; clique != nil { + latest -= latest % clique.Epoch // epoch snapshot for clique + } + if head >= latest { + return false + } + // Retrieve the latest useful header and update to it + if header, err := GetHeaderByNumber(ctx, lc.odr, latest); header != nil && err == nil { + lc.chainmu.Lock() + defer lc.chainmu.Unlock() + + // Ensure the chain didn't move past the latest block while retrieving it + if lc.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { + log.Info("Updated latest header based on CHT", "number", header.Number, "hash", header.Hash(), "age", common.PrettyAge(time.Unix(int64(header.Time), 0))) + lc.hc.SetCurrentHeader(header) + } + return true + } + return false +} + +// LockChain locks the chain mutex for reading so that multiple canonical hashes can be +// retrieved while it is guaranteed that they belong to the same version of the chain +func (lc *LightChain) LockChain() { + lc.chainmu.RLock() +} + +// UnlockChain unlocks the chain mutex +func (lc *LightChain) UnlockChain() { + lc.chainmu.RUnlock() +} + +// SubscribeChainEvent registers a subscription of ChainEvent. +func (lc *LightChain) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + return lc.scope.Track(lc.chainFeed.Subscribe(ch)) +} + +// SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. +func (lc *LightChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { + return lc.scope.Track(lc.chainHeadFeed.Subscribe(ch)) +} + +// SubscribeChainSideEvent registers a subscription of ChainSideEvent. +func (lc *LightChain) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { + return lc.scope.Track(lc.chainSideFeed.Subscribe(ch)) +} + +// SubscribeLogsEvent implements the interface of filters.Backend +// LightChain does not send logs events, so return an empty subscription. +func (lc *LightChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + return lc.scope.Track(new(event.Feed).Subscribe(ch)) +} + +// SubscribeRemovedLogsEvent implements the interface of filters.Backend +// LightChain does not send core.RemovedLogsEvent, so return an empty subscription. +func (lc *LightChain) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { + return lc.scope.Track(new(event.Feed).Subscribe(ch)) +} + +// DisableCheckFreq disables header validation. This is used for ultralight mode. +func (lc *LightChain) DisableCheckFreq() { + atomic.StoreInt32(&lc.disableCheckFreq, 1) +} + +// EnableCheckFreq enables header validation. +func (lc *LightChain) EnableCheckFreq() { + atomic.StoreInt32(&lc.disableCheckFreq, 0) +} diff --git a/vendor/github.com/ethereum/go-ethereum/light/nodeset.go b/vendor/github.com/ethereum/go-ethereum/light/nodeset.go new file mode 100644 index 00000000..36625967 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/nodeset.go @@ -0,0 +1,162 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package light + +import ( + "errors" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rlp" +) + +// NodeSet stores a set of trie nodes. It implements trie.Database and can also +// act as a cache for another trie.Database. +type NodeSet struct { + nodes map[string][]byte + order []string + + dataSize int + lock sync.RWMutex +} + +// NewNodeSet creates an empty node set +func NewNodeSet() *NodeSet { + return &NodeSet{ + nodes: make(map[string][]byte), + } +} + +// Put stores a new node in the set +func (db *NodeSet) Put(key []byte, value []byte) error { + db.lock.Lock() + defer db.lock.Unlock() + + if _, ok := db.nodes[string(key)]; ok { + return nil + } + keystr := string(key) + + db.nodes[keystr] = common.CopyBytes(value) + db.order = append(db.order, keystr) + db.dataSize += len(value) + + return nil +} + +// Delete removes a node from the set +func (db *NodeSet) Delete(key []byte) error { + db.lock.Lock() + defer db.lock.Unlock() + + delete(db.nodes, string(key)) + return nil +} + +// Get returns a stored node +func (db *NodeSet) Get(key []byte) ([]byte, error) { + db.lock.RLock() + defer db.lock.RUnlock() + + if entry, ok := db.nodes[string(key)]; ok { + return entry, nil + } + return nil, errors.New("not found") +} + +// Has returns true if the node set contains the given key +func (db *NodeSet) Has(key []byte) (bool, error) { + _, err := db.Get(key) + return err == nil, nil +} + +// KeyCount returns the number of nodes in the set +func (db *NodeSet) KeyCount() int { + db.lock.RLock() + defer db.lock.RUnlock() + + return len(db.nodes) +} + +// DataSize returns the aggregated data size of nodes in the set +func (db *NodeSet) DataSize() int { + db.lock.RLock() + defer db.lock.RUnlock() + + return db.dataSize +} + +// NodeList converts the node set to a NodeList +func (db *NodeSet) NodeList() NodeList { + db.lock.RLock() + defer db.lock.RUnlock() + + var values NodeList + for _, key := range db.order { + values = append(values, db.nodes[key]) + } + return values +} + +// Store writes the contents of the set to the given database +func (db *NodeSet) Store(target ethdb.KeyValueWriter) { + db.lock.RLock() + defer db.lock.RUnlock() + + for key, value := range db.nodes { + target.Put([]byte(key), value) + } +} + +// NodeList stores an ordered list of trie nodes. It implements ethdb.KeyValueWriter. +type NodeList []rlp.RawValue + +// Store writes the contents of the list to the given database +func (n NodeList) Store(db ethdb.KeyValueWriter) { + for _, node := range n { + db.Put(crypto.Keccak256(node), node) + } +} + +// NodeSet converts the node list to a NodeSet +func (n NodeList) NodeSet() *NodeSet { + db := NewNodeSet() + n.Store(db) + return db +} + +// Put stores a new node at the end of the list +func (n *NodeList) Put(key []byte, value []byte) error { + *n = append(*n, value) + return nil +} + +// Delete panics as there's no reason to remove a node from the list. +func (n *NodeList) Delete(key []byte) error { + panic("not supported") +} + +// DataSize returns the aggregated data size of nodes in the list +func (n NodeList) DataSize() int { + var size int + for _, node := range n { + size += len(node) + } + return size +} diff --git a/vendor/github.com/ethereum/go-ethereum/light/odr.go b/vendor/github.com/ethereum/go-ethereum/light/odr.go new file mode 100644 index 00000000..d1185e4e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/odr.go @@ -0,0 +1,194 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package light + +import ( + "context" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +// NoOdr is the default context passed to an ODR capable function when the ODR +// service is not required. +var NoOdr = context.Background() + +// ErrNoPeers is returned if no peers capable of serving a queued request are available +var ErrNoPeers = errors.New("no suitable peers available") + +// OdrBackend is an interface to a backend service that handles ODR retrievals type +type OdrBackend interface { + Database() ethdb.Database + ChtIndexer() *core.ChainIndexer + BloomTrieIndexer() *core.ChainIndexer + BloomIndexer() *core.ChainIndexer + Retrieve(ctx context.Context, req OdrRequest) error + IndexerConfig() *IndexerConfig +} + +// OdrRequest is an interface for retrieval requests +type OdrRequest interface { + StoreResult(db ethdb.Database) +} + +// TrieID identifies a state or account storage trie +type TrieID struct { + BlockHash, Root common.Hash + BlockNumber uint64 + AccKey []byte +} + +// StateTrieID returns a TrieID for a state trie belonging to a certain block +// header. +func StateTrieID(header *types.Header) *TrieID { + return &TrieID{ + BlockHash: header.Hash(), + BlockNumber: header.Number.Uint64(), + AccKey: nil, + Root: header.Root, + } +} + +// StorageTrieID returns a TrieID for a contract storage trie at a given account +// of a given state trie. It also requires the root hash of the trie for +// checking Merkle proofs. +func StorageTrieID(state *TrieID, addrHash, root common.Hash) *TrieID { + return &TrieID{ + BlockHash: state.BlockHash, + BlockNumber: state.BlockNumber, + AccKey: addrHash[:], + Root: root, + } +} + +// TrieRequest is the ODR request type for state/storage trie entries +type TrieRequest struct { + OdrRequest + Id *TrieID + Key []byte + Proof *NodeSet +} + +// StoreResult stores the retrieved data in local database +func (req *TrieRequest) StoreResult(db ethdb.Database) { + req.Proof.Store(db) +} + +// CodeRequest is the ODR request type for retrieving contract code +type CodeRequest struct { + OdrRequest + Id *TrieID // references storage trie of the account + Hash common.Hash + Data []byte +} + +// StoreResult stores the retrieved data in local database +func (req *CodeRequest) StoreResult(db ethdb.Database) { + db.Put(req.Hash[:], req.Data) +} + +// BlockRequest is the ODR request type for retrieving block bodies +type BlockRequest struct { + OdrRequest + Hash common.Hash + Number uint64 + Rlp []byte +} + +// StoreResult stores the retrieved data in local database +func (req *BlockRequest) StoreResult(db ethdb.Database) { + rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp) +} + +// ReceiptsRequest is the ODR request type for retrieving block bodies +type ReceiptsRequest struct { + OdrRequest + Hash common.Hash + Number uint64 + Receipts types.Receipts +} + +// StoreResult stores the retrieved data in local database +func (req *ReceiptsRequest) StoreResult(db ethdb.Database) { + rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts) +} + +// ChtRequest is the ODR request type for state/storage trie entries +type ChtRequest struct { + OdrRequest + Config *IndexerConfig + ChtNum, BlockNum uint64 + ChtRoot common.Hash + Header *types.Header + Td *big.Int + Proof *NodeSet +} + +// StoreResult stores the retrieved data in local database +func (req *ChtRequest) StoreResult(db ethdb.Database) { + hash, num := req.Header.Hash(), req.Header.Number.Uint64() + + rawdb.WriteHeader(db, req.Header) + rawdb.WriteTd(db, hash, num, req.Td) + rawdb.WriteCanonicalHash(db, hash, num) +} + +// BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure +type BloomRequest struct { + OdrRequest + Config *IndexerConfig + BloomTrieNum uint64 + BitIdx uint + SectionIndexList []uint64 + BloomTrieRoot common.Hash + BloomBits [][]byte + Proofs *NodeSet +} + +// StoreResult stores the retrieved data in local database +func (req *BloomRequest) StoreResult(db ethdb.Database) { + for i, sectionIdx := range req.SectionIndexList { + sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.Config.BloomTrieSize-1) + // if we don't have the canonical hash stored for this section head number, we'll still store it under + // a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical + // hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the + // bit vector again from the network. + rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i]) + } +} + +// TxStatus describes the status of a transaction +type TxStatus struct { + Status core.TxStatus + Lookup *rawdb.LegacyTxLookupEntry `rlp:"nil"` + Error string +} + +// TxStatusRequest is the ODR request type for retrieving transaction status +type TxStatusRequest struct { + OdrRequest + Hashes []common.Hash + Status []TxStatus +} + +// StoreResult stores the retrieved data in local database +func (req *TxStatusRequest) StoreResult(db ethdb.Database) {} diff --git a/vendor/github.com/ethereum/go-ethereum/light/odr_util.go b/vendor/github.com/ethereum/go-ethereum/light/odr_util.go new file mode 100644 index 00000000..100bd584 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/odr_util.go @@ -0,0 +1,250 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package light + +import ( + "bytes" + "context" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" +) + +var sha3Nil = crypto.Keccak256Hash(nil) + +func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) { + db := odr.Database() + hash := rawdb.ReadCanonicalHash(db, number) + if (hash != common.Hash{}) { + // if there is a canonical hash, there is a header too + header := rawdb.ReadHeader(db, hash, number) + if header == nil { + panic("Canonical hash present but header not found") + } + return header, nil + } + + var ( + chtCount, sectionHeadNum uint64 + sectionHead common.Hash + ) + if odr.ChtIndexer() != nil { + chtCount, sectionHeadNum, sectionHead = odr.ChtIndexer().Sections() + canonicalHash := rawdb.ReadCanonicalHash(db, sectionHeadNum) + // if the CHT was injected as a trusted checkpoint, we have no canonical hash yet so we accept zero hash too + for chtCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { + chtCount-- + if chtCount > 0 { + sectionHeadNum = chtCount*odr.IndexerConfig().ChtSize - 1 + sectionHead = odr.ChtIndexer().SectionHead(chtCount - 1) + canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) + } + } + } + if number >= chtCount*odr.IndexerConfig().ChtSize { + return nil, ErrNoTrustedCht + } + r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number, Config: odr.IndexerConfig()} + if err := odr.Retrieve(ctx, r); err != nil { + return nil, err + } + return r.Header, nil +} + +func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (common.Hash, error) { + hash := rawdb.ReadCanonicalHash(odr.Database(), number) + if (hash != common.Hash{}) { + return hash, nil + } + header, err := GetHeaderByNumber(ctx, odr, number) + if header != nil { + return header.Hash(), nil + } + return common.Hash{}, err +} + +// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. +func GetBodyRLP(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (rlp.RawValue, error) { + if data := rawdb.ReadBodyRLP(odr.Database(), hash, number); data != nil { + return data, nil + } + r := &BlockRequest{Hash: hash, Number: number} + if err := odr.Retrieve(ctx, r); err != nil { + return nil, err + } else { + return r.Rlp, nil + } +} + +// GetBody retrieves the block body (transactons, uncles) corresponding to the +// hash. +func GetBody(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (*types.Body, error) { + data, err := GetBodyRLP(ctx, odr, hash, number) + if err != nil { + return nil, err + } + body := new(types.Body) + if err := rlp.Decode(bytes.NewReader(data), body); err != nil { + return nil, err + } + return body, nil +} + +// GetBlock retrieves an entire block corresponding to the hash, assembling it +// back from the stored header and body. +func GetBlock(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (*types.Block, error) { + // Retrieve the block header and body contents + header := rawdb.ReadHeader(odr.Database(), hash, number) + if header == nil { + return nil, ErrNoHeader + } + body, err := GetBody(ctx, odr, hash, number) + if err != nil { + return nil, err + } + // Reassemble the block and return + return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles), nil +} + +// GetBlockReceipts retrieves the receipts generated by the transactions included +// in a block given by its hash. +func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) (types.Receipts, error) { + // Assume receipts are already stored locally and attempt to retrieve. + receipts := rawdb.ReadRawReceipts(odr.Database(), hash, number) + if receipts == nil { + r := &ReceiptsRequest{Hash: hash, Number: number} + if err := odr.Retrieve(ctx, r); err != nil { + return nil, err + } + receipts = r.Receipts + } + // If the receipts are incomplete, fill the derived fields + if len(receipts) > 0 && receipts[0].TxHash == (common.Hash{}) { + block, err := GetBlock(ctx, odr, hash, number) + if err != nil { + return nil, err + } + genesis := rawdb.ReadCanonicalHash(odr.Database(), 0) + config := rawdb.ReadChainConfig(odr.Database(), genesis) + + if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Transactions()); err != nil { + return nil, err + } + rawdb.WriteReceipts(odr.Database(), hash, number, receipts) + } + return receipts, nil +} + +// GetBlockLogs retrieves the logs generated by the transactions included in a +// block given by its hash. +func GetBlockLogs(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64) ([][]*types.Log, error) { + // Retrieve the potentially incomplete receipts from disk or network + receipts, err := GetBlockReceipts(ctx, odr, hash, number) + if err != nil { + return nil, err + } + // Return the logs without deriving any computed fields on the receipts + logs := make([][]*types.Log, len(receipts)) + for i, receipt := range receipts { + logs[i] = receipt.Logs + } + return logs, nil +} + +// GetBloomBits retrieves a batch of compressed bloomBits vectors belonging to the given bit index and section indexes +func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxList []uint64) ([][]byte, error) { + var ( + db = odr.Database() + result = make([][]byte, len(sectionIdxList)) + reqList []uint64 + reqIdx []int + ) + + var ( + bloomTrieCount, sectionHeadNum uint64 + sectionHead common.Hash + ) + if odr.BloomTrieIndexer() != nil { + bloomTrieCount, sectionHeadNum, sectionHead = odr.BloomTrieIndexer().Sections() + canonicalHash := rawdb.ReadCanonicalHash(db, sectionHeadNum) + // if the BloomTrie was injected as a trusted checkpoint, we have no canonical hash yet so we accept zero hash too + for bloomTrieCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { + bloomTrieCount-- + if bloomTrieCount > 0 { + sectionHeadNum = bloomTrieCount*odr.IndexerConfig().BloomTrieSize - 1 + sectionHead = odr.BloomTrieIndexer().SectionHead(bloomTrieCount - 1) + canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) + } + } + } + + for i, sectionIdx := range sectionIdxList { + sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*odr.IndexerConfig().BloomSize-1) + // if we don't have the canonical hash stored for this section head number, we'll still look for + // an entry with a zero sectionHead (we store it with zero section head too if we don't know it + // at the time of the retrieval) + bloomBits, err := rawdb.ReadBloomBits(db, bitIdx, sectionIdx, sectionHead) + if err == nil { + result[i] = bloomBits + } else { + // TODO(rjl493456442) Convert sectionIndex to BloomTrie relative index + if sectionIdx >= bloomTrieCount { + return nil, ErrNoTrustedBloomTrie + } + reqList = append(reqList, sectionIdx) + reqIdx = append(reqIdx, i) + } + } + if reqList == nil { + return result, nil + } + + r := &BloomRequest{BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1, + BitIdx: bitIdx, SectionIndexList: reqList, Config: odr.IndexerConfig()} + if err := odr.Retrieve(ctx, r); err != nil { + return nil, err + } else { + for i, idx := range reqIdx { + result[idx] = r.BloomBits[i] + } + return result, nil + } +} + +// GetTransaction retrieves a canonical transaction by hash and also returns its position in the chain +func GetTransaction(ctx context.Context, odr OdrBackend, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) { + r := &TxStatusRequest{Hashes: []common.Hash{txHash}} + if err := odr.Retrieve(ctx, r); err != nil || r.Status[0].Status != core.TxStatusIncluded { + return nil, common.Hash{}, 0, 0, err + } else { + pos := r.Status[0].Lookup + // first ensure that we have the header, otherwise block body retrieval will fail + // also verify if this is a canonical block by getting the header by number and checking its hash + if header, err := GetHeaderByNumber(ctx, odr, pos.BlockIndex); err != nil || header.Hash() != pos.BlockHash { + return nil, common.Hash{}, 0, 0, err + } + if body, err := GetBody(ctx, odr, pos.BlockHash, pos.BlockIndex); err != nil || uint64(len(body.Transactions)) <= pos.Index || body.Transactions[pos.Index].Hash() != txHash { + return nil, common.Hash{}, 0, 0, err + } else { + return body.Transactions[pos.Index], pos.BlockHash, pos.BlockIndex, pos.Index, nil + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/light/postprocess.go b/vendor/github.com/ethereum/go-ethereum/light/postprocess.go new file mode 100644 index 00000000..bf632a44 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/postprocess.go @@ -0,0 +1,389 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package light + +import ( + "context" + "encoding/binary" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/bitutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +// IndexerConfig includes a set of configs for chain indexers. +type IndexerConfig struct { + // The block frequency for creating CHTs. + ChtSize uint64 + + // The number of confirmations needed to generate/accept a canonical hash help trie. + ChtConfirms uint64 + + // The block frequency for creating new bloom bits. + BloomSize uint64 + + // The number of confirmation needed before a bloom section is considered probably final and its rotated bits + // are calculated. + BloomConfirms uint64 + + // The block frequency for creating BloomTrie. + BloomTrieSize uint64 + + // The number of confirmations needed to generate/accept a bloom trie. + BloomTrieConfirms uint64 +} + +var ( + // DefaultServerIndexerConfig wraps a set of configs as a default indexer config for server side. + DefaultServerIndexerConfig = &IndexerConfig{ + ChtSize: params.CHTFrequency, + ChtConfirms: params.HelperTrieProcessConfirmations, + BloomSize: params.BloomBitsBlocks, + BloomConfirms: params.BloomConfirms, + BloomTrieSize: params.BloomTrieFrequency, + BloomTrieConfirms: params.HelperTrieProcessConfirmations, + } + // DefaultClientIndexerConfig wraps a set of configs as a default indexer config for client side. + DefaultClientIndexerConfig = &IndexerConfig{ + ChtSize: params.CHTFrequency, + ChtConfirms: params.HelperTrieConfirmations, + BloomSize: params.BloomBitsBlocksClient, + BloomConfirms: params.HelperTrieConfirmations, + BloomTrieSize: params.BloomTrieFrequency, + BloomTrieConfirms: params.HelperTrieConfirmations, + } + // TestServerIndexerConfig wraps a set of configs as a test indexer config for server side. + TestServerIndexerConfig = &IndexerConfig{ + ChtSize: 512, + ChtConfirms: 4, + BloomSize: 64, + BloomConfirms: 4, + BloomTrieSize: 512, + BloomTrieConfirms: 4, + } + // TestClientIndexerConfig wraps a set of configs as a test indexer config for client side. + TestClientIndexerConfig = &IndexerConfig{ + ChtSize: 512, + ChtConfirms: 32, + BloomSize: 512, + BloomConfirms: 32, + BloomTrieSize: 512, + BloomTrieConfirms: 32, + } +) + +var ( + ErrNoTrustedCht = errors.New("no trusted canonical hash trie") + ErrNoTrustedBloomTrie = errors.New("no trusted bloom trie") + ErrNoHeader = errors.New("header not found") + chtPrefix = []byte("chtRootV2-") // chtPrefix + chtNum (uint64 big endian) -> trie root hash + ChtTablePrefix = "cht-" +) + +// ChtNode structures are stored in the Canonical Hash Trie in an RLP encoded format +type ChtNode struct { + Hash common.Hash + Td *big.Int +} + +// GetChtRoot reads the CHT root associated to the given section from the database +func GetChtRoot(db ethdb.Database, sectionIdx uint64, sectionHead common.Hash) common.Hash { + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], sectionIdx) + data, _ := db.Get(append(append(chtPrefix, encNumber[:]...), sectionHead.Bytes()...)) + return common.BytesToHash(data) +} + +// StoreChtRoot writes the CHT root associated to the given section into the database +func StoreChtRoot(db ethdb.Database, sectionIdx uint64, sectionHead, root common.Hash) { + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], sectionIdx) + db.Put(append(append(chtPrefix, encNumber[:]...), sectionHead.Bytes()...), root.Bytes()) +} + +// ChtIndexerBackend implements core.ChainIndexerBackend. +type ChtIndexerBackend struct { + diskdb, trieTable ethdb.Database + odr OdrBackend + triedb *trie.Database + section, sectionSize uint64 + lastHash common.Hash + trie *trie.Trie +} + +// NewChtIndexer creates a Cht chain indexer +func NewChtIndexer(db ethdb.Database, odr OdrBackend, size, confirms uint64) *core.ChainIndexer { + trieTable := rawdb.NewTable(db, ChtTablePrefix) + backend := &ChtIndexerBackend{ + diskdb: db, + odr: odr, + trieTable: trieTable, + triedb: trie.NewDatabaseWithCache(trieTable, 1), // Use a tiny cache only to keep memory down + sectionSize: size, + } + return core.NewChainIndexer(db, rawdb.NewTable(db, "chtIndexV2-"), backend, size, confirms, time.Millisecond*100, "cht") +} + +// fetchMissingNodes tries to retrieve the last entry of the latest trusted CHT from the +// ODR backend in order to be able to add new entries and calculate subsequent root hashes +func (c *ChtIndexerBackend) fetchMissingNodes(ctx context.Context, section uint64, root common.Hash) error { + batch := c.trieTable.NewBatch() + r := &ChtRequest{ChtRoot: root, ChtNum: section - 1, BlockNum: section*c.sectionSize - 1, Config: c.odr.IndexerConfig()} + for { + err := c.odr.Retrieve(ctx, r) + switch err { + case nil: + r.Proof.Store(batch) + return batch.Write() + case ErrNoPeers: + // if there are no peers to serve, retry later + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Second * 10): + // stay in the loop and try again + } + default: + return err + } + } +} + +// Reset implements core.ChainIndexerBackend +func (c *ChtIndexerBackend) Reset(ctx context.Context, section uint64, lastSectionHead common.Hash) error { + var root common.Hash + if section > 0 { + root = GetChtRoot(c.diskdb, section-1, lastSectionHead) + } + var err error + c.trie, err = trie.New(root, c.triedb) + + if err != nil && c.odr != nil { + err = c.fetchMissingNodes(ctx, section, root) + if err == nil { + c.trie, err = trie.New(root, c.triedb) + } + } + + c.section = section + return err +} + +// Process implements core.ChainIndexerBackend +func (c *ChtIndexerBackend) Process(ctx context.Context, header *types.Header) error { + hash, num := header.Hash(), header.Number.Uint64() + c.lastHash = hash + + td := rawdb.ReadTd(c.diskdb, hash, num) + if td == nil { + panic(nil) + } + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], num) + data, _ := rlp.EncodeToBytes(ChtNode{hash, td}) + c.trie.Update(encNumber[:], data) + return nil +} + +// Commit implements core.ChainIndexerBackend +func (c *ChtIndexerBackend) Commit() error { + root, err := c.trie.Commit(nil) + if err != nil { + return err + } + c.triedb.Commit(root, false) + + log.Info("Storing CHT", "section", c.section, "head", fmt.Sprintf("%064x", c.lastHash), "root", fmt.Sprintf("%064x", root)) + StoreChtRoot(c.diskdb, c.section, c.lastHash, root) + return nil +} + +var ( + bloomTriePrefix = []byte("bltRoot-") // bloomTriePrefix + bloomTrieNum (uint64 big endian) -> trie root hash + BloomTrieTablePrefix = "blt-" +) + +// GetBloomTrieRoot reads the BloomTrie root assoctiated to the given section from the database +func GetBloomTrieRoot(db ethdb.Database, sectionIdx uint64, sectionHead common.Hash) common.Hash { + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], sectionIdx) + data, _ := db.Get(append(append(bloomTriePrefix, encNumber[:]...), sectionHead.Bytes()...)) + return common.BytesToHash(data) +} + +// StoreBloomTrieRoot writes the BloomTrie root assoctiated to the given section into the database +func StoreBloomTrieRoot(db ethdb.Database, sectionIdx uint64, sectionHead, root common.Hash) { + var encNumber [8]byte + binary.BigEndian.PutUint64(encNumber[:], sectionIdx) + db.Put(append(append(bloomTriePrefix, encNumber[:]...), sectionHead.Bytes()...), root.Bytes()) +} + +// BloomTrieIndexerBackend implements core.ChainIndexerBackend +type BloomTrieIndexerBackend struct { + diskdb, trieTable ethdb.Database + triedb *trie.Database + odr OdrBackend + section uint64 + parentSize uint64 + size uint64 + bloomTrieRatio uint64 + trie *trie.Trie + sectionHeads []common.Hash +} + +// NewBloomTrieIndexer creates a BloomTrie chain indexer +func NewBloomTrieIndexer(db ethdb.Database, odr OdrBackend, parentSize, size uint64) *core.ChainIndexer { + trieTable := rawdb.NewTable(db, BloomTrieTablePrefix) + backend := &BloomTrieIndexerBackend{ + diskdb: db, + odr: odr, + trieTable: trieTable, + triedb: trie.NewDatabaseWithCache(trieTable, 1), // Use a tiny cache only to keep memory down + parentSize: parentSize, + size: size, + } + backend.bloomTrieRatio = size / parentSize + backend.sectionHeads = make([]common.Hash, backend.bloomTrieRatio) + return core.NewChainIndexer(db, rawdb.NewTable(db, "bltIndex-"), backend, size, 0, time.Millisecond*100, "bloomtrie") +} + +// fetchMissingNodes tries to retrieve the last entries of the latest trusted bloom trie from the +// ODR backend in order to be able to add new entries and calculate subsequent root hashes +func (b *BloomTrieIndexerBackend) fetchMissingNodes(ctx context.Context, section uint64, root common.Hash) error { + indexCh := make(chan uint, types.BloomBitLength) + type res struct { + nodes *NodeSet + err error + } + resCh := make(chan res, types.BloomBitLength) + for i := 0; i < 20; i++ { + go func() { + for bitIndex := range indexCh { + r := &BloomRequest{BloomTrieRoot: root, BloomTrieNum: section - 1, BitIdx: bitIndex, SectionIndexList: []uint64{section - 1}, Config: b.odr.IndexerConfig()} + for { + if err := b.odr.Retrieve(ctx, r); err == ErrNoPeers { + // if there are no peers to serve, retry later + select { + case <-ctx.Done(): + resCh <- res{nil, ctx.Err()} + return + case <-time.After(time.Second * 10): + // stay in the loop and try again + } + } else { + resCh <- res{r.Proofs, err} + break + } + } + } + }() + } + + for i := uint(0); i < types.BloomBitLength; i++ { + indexCh <- i + } + close(indexCh) + batch := b.trieTable.NewBatch() + for i := uint(0); i < types.BloomBitLength; i++ { + res := <-resCh + if res.err != nil { + return res.err + } + res.nodes.Store(batch) + } + return batch.Write() +} + +// Reset implements core.ChainIndexerBackend +func (b *BloomTrieIndexerBackend) Reset(ctx context.Context, section uint64, lastSectionHead common.Hash) error { + var root common.Hash + if section > 0 { + root = GetBloomTrieRoot(b.diskdb, section-1, lastSectionHead) + } + var err error + b.trie, err = trie.New(root, b.triedb) + if err != nil && b.odr != nil { + err = b.fetchMissingNodes(ctx, section, root) + if err == nil { + b.trie, err = trie.New(root, b.triedb) + } + } + b.section = section + return err +} + +// Process implements core.ChainIndexerBackend +func (b *BloomTrieIndexerBackend) Process(ctx context.Context, header *types.Header) error { + num := header.Number.Uint64() - b.section*b.size + if (num+1)%b.parentSize == 0 { + b.sectionHeads[num/b.parentSize] = header.Hash() + } + return nil +} + +// Commit implements core.ChainIndexerBackend +func (b *BloomTrieIndexerBackend) Commit() error { + var compSize, decompSize uint64 + + for i := uint(0); i < types.BloomBitLength; i++ { + var encKey [10]byte + binary.BigEndian.PutUint16(encKey[0:2], uint16(i)) + binary.BigEndian.PutUint64(encKey[2:10], b.section) + var decomp []byte + for j := uint64(0); j < b.bloomTrieRatio; j++ { + data, err := rawdb.ReadBloomBits(b.diskdb, i, b.section*b.bloomTrieRatio+j, b.sectionHeads[j]) + if err != nil { + return err + } + decompData, err2 := bitutil.DecompressBytes(data, int(b.parentSize/8)) + if err2 != nil { + return err2 + } + decomp = append(decomp, decompData...) + } + comp := bitutil.CompressBytes(decomp) + + decompSize += uint64(len(decomp)) + compSize += uint64(len(comp)) + if len(comp) > 0 { + b.trie.Update(encKey[:], comp) + } else { + b.trie.Delete(encKey[:]) + } + } + root, err := b.trie.Commit(nil) + if err != nil { + return err + } + b.triedb.Commit(root, false) + + sectionHead := b.sectionHeads[b.bloomTrieRatio-1] + log.Info("Storing bloom trie", "section", b.section, "head", fmt.Sprintf("%064x", sectionHead), "root", fmt.Sprintf("%064x", root), "compression", float64(compSize)/float64(decompSize)) + StoreBloomTrieRoot(b.diskdb, b.section, sectionHead, root) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/light/trie.go b/vendor/github.com/ethereum/go-ethereum/light/trie.go new file mode 100644 index 00000000..e512bf6f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/light/trie.go @@ -0,0 +1,243 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package light + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" +) + +func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB { + state, _ := state.New(head.Root, NewStateDatabase(ctx, head, odr)) + return state +} + +func NewStateDatabase(ctx context.Context, head *types.Header, odr OdrBackend) state.Database { + return &odrDatabase{ctx, StateTrieID(head), odr} +} + +type odrDatabase struct { + ctx context.Context + id *TrieID + backend OdrBackend +} + +func (db *odrDatabase) OpenTrie(root common.Hash) (state.Trie, error) { + return &odrTrie{db: db, id: db.id}, nil +} + +func (db *odrDatabase) OpenStorageTrie(addrHash, root common.Hash) (state.Trie, error) { + return &odrTrie{db: db, id: StorageTrieID(db.id, addrHash, root)}, nil +} + +func (db *odrDatabase) CopyTrie(t state.Trie) state.Trie { + switch t := t.(type) { + case *odrTrie: + cpy := &odrTrie{db: t.db, id: t.id} + if t.trie != nil { + cpytrie := *t.trie + cpy.trie = &cpytrie + } + return cpy + default: + panic(fmt.Errorf("unknown trie type %T", t)) + } +} + +func (db *odrDatabase) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) { + if codeHash == sha3Nil { + return nil, nil + } + if code, err := db.backend.Database().Get(codeHash[:]); err == nil { + return code, nil + } + id := *db.id + id.AccKey = addrHash[:] + req := &CodeRequest{Id: &id, Hash: codeHash} + err := db.backend.Retrieve(db.ctx, req) + return req.Data, err +} + +func (db *odrDatabase) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) { + code, err := db.ContractCode(addrHash, codeHash) + return len(code), err +} + +func (db *odrDatabase) TrieDB() *trie.Database { + return nil +} + +type odrTrie struct { + db *odrDatabase + id *TrieID + trie *trie.Trie +} + +func (t *odrTrie) TryGet(key []byte) ([]byte, error) { + key = crypto.Keccak256(key) + var res []byte + err := t.do(key, func() (err error) { + res, err = t.trie.TryGet(key) + return err + }) + return res, err +} + +func (t *odrTrie) TryUpdate(key, value []byte) error { + key = crypto.Keccak256(key) + return t.do(key, func() error { + return t.trie.TryUpdate(key, value) + }) +} + +func (t *odrTrie) TryDelete(key []byte) error { + key = crypto.Keccak256(key) + return t.do(key, func() error { + return t.trie.TryDelete(key) + }) +} + +func (t *odrTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) { + if t.trie == nil { + return t.id.Root, nil + } + return t.trie.Commit(onleaf) +} + +func (t *odrTrie) Hash() common.Hash { + if t.trie == nil { + return t.id.Root + } + return t.trie.Hash() +} + +func (t *odrTrie) NodeIterator(startkey []byte) trie.NodeIterator { + return newNodeIterator(t, startkey) +} + +func (t *odrTrie) GetKey(sha []byte) []byte { + return nil +} + +func (t *odrTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error { + return errors.New("not implemented, needs client/server interface split") +} + +// do tries and retries to execute a function until it returns with no error or +// an error type other than MissingNodeError +func (t *odrTrie) do(key []byte, fn func() error) error { + for { + var err error + if t.trie == nil { + t.trie, err = trie.New(t.id.Root, trie.NewDatabase(t.db.backend.Database())) + } + if err == nil { + err = fn() + } + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + r := &TrieRequest{Id: t.id, Key: key} + if err := t.db.backend.Retrieve(t.db.ctx, r); err != nil { + return err + } + } +} + +type nodeIterator struct { + trie.NodeIterator + t *odrTrie + err error +} + +func newNodeIterator(t *odrTrie, startkey []byte) trie.NodeIterator { + it := &nodeIterator{t: t} + // Open the actual non-ODR trie if that hasn't happened yet. + if t.trie == nil { + it.do(func() error { + t, err := trie.New(t.id.Root, trie.NewDatabase(t.db.backend.Database())) + if err == nil { + it.t.trie = t + } + return err + }) + } + it.do(func() error { + it.NodeIterator = it.t.trie.NodeIterator(startkey) + return it.NodeIterator.Error() + }) + return it +} + +func (it *nodeIterator) Next(descend bool) bool { + var ok bool + it.do(func() error { + ok = it.NodeIterator.Next(descend) + return it.NodeIterator.Error() + }) + return ok +} + +// do runs fn and attempts to fill in missing nodes by retrieving. +func (it *nodeIterator) do(fn func() error) { + var lasthash common.Hash + for { + it.err = fn() + missing, ok := it.err.(*trie.MissingNodeError) + if !ok { + return + } + if missing.NodeHash == lasthash { + it.err = fmt.Errorf("retrieve loop for trie node %x", missing.NodeHash) + return + } + lasthash = missing.NodeHash + r := &TrieRequest{Id: it.t.id, Key: nibblesToKey(missing.Path)} + if it.err = it.t.db.backend.Retrieve(it.t.db.ctx, r); it.err != nil { + return + } + } +} + +func (it *nodeIterator) Error() error { + if it.err != nil { + return it.err + } + return it.NodeIterator.Error() +} + +func nibblesToKey(nib []byte) []byte { + if len(nib) > 0 && nib[len(nib)-1] == 0x10 { + nib = nib[:len(nib)-1] // drop terminator + } + if len(nib)&1 == 1 { + nib = append(nib, 0) // make even + } + key := make([]byte, len(nib)/2) + for bi, ni := 0, 0; ni < len(nib); bi, ni = bi+1, ni+2 { + key[bi] = nib[ni]<<4 | nib[ni+1] + } + return key +} diff --git a/vendor/github.com/ethereum/go-ethereum/log/format.go b/vendor/github.com/ethereum/go-ethereum/log/format.go new file mode 100644 index 00000000..a1b5dac6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/log/format.go @@ -0,0 +1,406 @@ +package log + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + "unicode/utf8" +) + +const ( + timeFormat = "2006-01-02T15:04:05-0700" + termTimeFormat = "01-02|15:04:05.000" + floatFormat = 'f' + termMsgJust = 40 + termCtxMaxPadding = 40 +) + +// locationTrims are trimmed for display to avoid unwieldy log lines. +var locationTrims = []string{ + "github.com/ethereum/go-ethereum/", +} + +// PrintOrigins sets or unsets log location (file:line) printing for terminal +// format output. +func PrintOrigins(print bool) { + if print { + atomic.StoreUint32(&locationEnabled, 1) + } else { + atomic.StoreUint32(&locationEnabled, 0) + } +} + +// locationEnabled is an atomic flag controlling whether the terminal formatter +// should append the log locations too when printing entries. +var locationEnabled uint32 + +// locationLength is the maxmimum path length encountered, which all logs are +// padded to to aid in alignment. +var locationLength uint32 + +// fieldPadding is a global map with maximum field value lengths seen until now +// to allow padding log contexts in a bit smarter way. +var fieldPadding = make(map[string]int) + +// fieldPaddingLock is a global mutex protecting the field padding map. +var fieldPaddingLock sync.RWMutex + +type Format interface { + Format(r *Record) []byte +} + +// FormatFunc returns a new Format object which uses +// the given function to perform record formatting. +func FormatFunc(f func(*Record) []byte) Format { + return formatFunc(f) +} + +type formatFunc func(*Record) []byte + +func (f formatFunc) Format(r *Record) []byte { + return f(r) +} + +// TerminalStringer is an analogous interface to the stdlib stringer, allowing +// own types to have custom shortened serialization formats when printed to the +// screen. +type TerminalStringer interface { + TerminalString() string +} + +// TerminalFormat formats log records optimized for human readability on +// a terminal with color-coded level output and terser human friendly timestamp. +// This format should only be used for interactive programs or while developing. +// +// [LEVEL] [TIME] MESAGE key=value key=value ... +// +// Example: +// +// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002 +// +func TerminalFormat(usecolor bool) Format { + return FormatFunc(func(r *Record) []byte { + var color = 0 + if usecolor { + switch r.Lvl { + case LvlCrit: + color = 35 + case LvlError: + color = 31 + case LvlWarn: + color = 33 + case LvlInfo: + color = 32 + case LvlDebug: + color = 36 + case LvlTrace: + color = 34 + } + } + + b := &bytes.Buffer{} + lvl := r.Lvl.AlignedString() + if atomic.LoadUint32(&locationEnabled) != 0 { + // Log origin printing was requested, format the location path and line number + location := fmt.Sprintf("%+v", r.Call) + for _, prefix := range locationTrims { + location = strings.TrimPrefix(location, prefix) + } + // Maintain the maximum location length for fancyer alignment + align := int(atomic.LoadUint32(&locationLength)) + if align < len(location) { + align = len(location) + atomic.StoreUint32(&locationLength, uint32(align)) + } + padding := strings.Repeat(" ", align-len(location)) + + // Assemble and print the log heading + if color > 0 { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s|%s]%s %s ", color, lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg) + } else { + fmt.Fprintf(b, "%s[%s|%s]%s %s ", lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg) + } + } else { + if color > 0 { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %s ", color, lvl, r.Time.Format(termTimeFormat), r.Msg) + } else { + fmt.Fprintf(b, "%s[%s] %s ", lvl, r.Time.Format(termTimeFormat), r.Msg) + } + } + // try to justify the log output for short messages + length := utf8.RuneCountInString(r.Msg) + if len(r.Ctx) > 0 && length < termMsgJust { + b.Write(bytes.Repeat([]byte{' '}, termMsgJust-length)) + } + // print the keys logfmt style + logfmt(b, r.Ctx, color, true) + return b.Bytes() + }) +} + +// LogfmtFormat prints records in logfmt format, an easy machine-parseable but human-readable +// format for key/value pairs. +// +// For more details see: http://godoc.org/github.com/kr/logfmt +// +func LogfmtFormat() Format { + return FormatFunc(func(r *Record) []byte { + common := []interface{}{r.KeyNames.Time, r.Time, r.KeyNames.Lvl, r.Lvl, r.KeyNames.Msg, r.Msg} + buf := &bytes.Buffer{} + logfmt(buf, append(common, r.Ctx...), 0, false) + return buf.Bytes() + }) +} + +func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) { + for i := 0; i < len(ctx); i += 2 { + if i != 0 { + buf.WriteByte(' ') + } + + k, ok := ctx[i].(string) + v := formatLogfmtValue(ctx[i+1], term) + if !ok { + k, v = errorKey, formatLogfmtValue(k, term) + } + + // XXX: we should probably check that all of your key bytes aren't invalid + fieldPaddingLock.RLock() + padding := fieldPadding[k] + fieldPaddingLock.RUnlock() + + length := utf8.RuneCountInString(v) + if padding < length && length <= termCtxMaxPadding { + padding = length + + fieldPaddingLock.Lock() + fieldPadding[k] = padding + fieldPaddingLock.Unlock() + } + if color > 0 { + fmt.Fprintf(buf, "\x1b[%dm%s\x1b[0m=", color, k) + } else { + buf.WriteString(k) + buf.WriteByte('=') + } + buf.WriteString(v) + if i < len(ctx)-2 && padding > length { + buf.Write(bytes.Repeat([]byte{' '}, padding-length)) + } + } + buf.WriteByte('\n') +} + +// JSONFormat formats log records as JSON objects separated by newlines. +// It is the equivalent of JSONFormatEx(false, true). +func JSONFormat() Format { + return JSONFormatEx(false, true) +} + +// JSONFormatOrderedEx formats log records as JSON arrays. If pretty is true, +// records will be pretty-printed. If lineSeparated is true, records +// will be logged with a new line between each record. +func JSONFormatOrderedEx(pretty, lineSeparated bool) Format { + jsonMarshal := json.Marshal + if pretty { + jsonMarshal = func(v interface{}) ([]byte, error) { + return json.MarshalIndent(v, "", " ") + } + } + return FormatFunc(func(r *Record) []byte { + props := make(map[string]interface{}) + + props[r.KeyNames.Time] = r.Time + props[r.KeyNames.Lvl] = r.Lvl.String() + props[r.KeyNames.Msg] = r.Msg + + ctx := make([]string, len(r.Ctx)) + for i := 0; i < len(r.Ctx); i += 2 { + k, ok := r.Ctx[i].(string) + if !ok { + props[errorKey] = fmt.Sprintf("%+v is not a string key,", r.Ctx[i]) + } + ctx[i] = k + ctx[i+1] = formatLogfmtValue(r.Ctx[i+1], true) + } + props[r.KeyNames.Ctx] = ctx + + b, err := jsonMarshal(props) + if err != nil { + b, _ = jsonMarshal(map[string]string{ + errorKey: err.Error(), + }) + return b + } + if lineSeparated { + b = append(b, '\n') + } + return b + }) +} + +// JSONFormatEx formats log records as JSON objects. If pretty is true, +// records will be pretty-printed. If lineSeparated is true, records +// will be logged with a new line between each record. +func JSONFormatEx(pretty, lineSeparated bool) Format { + jsonMarshal := json.Marshal + if pretty { + jsonMarshal = func(v interface{}) ([]byte, error) { + return json.MarshalIndent(v, "", " ") + } + } + + return FormatFunc(func(r *Record) []byte { + props := make(map[string]interface{}) + + props[r.KeyNames.Time] = r.Time + props[r.KeyNames.Lvl] = r.Lvl.String() + props[r.KeyNames.Msg] = r.Msg + + for i := 0; i < len(r.Ctx); i += 2 { + k, ok := r.Ctx[i].(string) + if !ok { + props[errorKey] = fmt.Sprintf("%+v is not a string key", r.Ctx[i]) + } + props[k] = formatJSONValue(r.Ctx[i+1]) + } + + b, err := jsonMarshal(props) + if err != nil { + b, _ = jsonMarshal(map[string]string{ + errorKey: err.Error(), + }) + return b + } + + if lineSeparated { + b = append(b, '\n') + } + + return b + }) +} + +func formatShared(value interface{}) (result interface{}) { + defer func() { + if err := recover(); err != nil { + if v := reflect.ValueOf(value); v.Kind() == reflect.Ptr && v.IsNil() { + result = "nil" + } else { + panic(err) + } + } + }() + + switch v := value.(type) { + case time.Time: + return v.Format(timeFormat) + + case error: + return v.Error() + + case fmt.Stringer: + return v.String() + + default: + return v + } +} + +func formatJSONValue(value interface{}) interface{} { + value = formatShared(value) + switch value.(type) { + case int, int8, int16, int32, int64, float32, float64, uint, uint8, uint16, uint32, uint64, string: + return value + default: + return fmt.Sprintf("%+v", value) + } +} + +// formatValue formats a value for serialization +func formatLogfmtValue(value interface{}, term bool) string { + if value == nil { + return "nil" + } + + if t, ok := value.(time.Time); ok { + // Performance optimization: No need for escaping since the provided + // timeFormat doesn't have any escape characters, and escaping is + // expensive. + return t.Format(timeFormat) + } + if term { + if s, ok := value.(TerminalStringer); ok { + // Custom terminal stringer provided, use that + return escapeString(s.TerminalString()) + } + } + value = formatShared(value) + switch v := value.(type) { + case bool: + return strconv.FormatBool(v) + case float32: + return strconv.FormatFloat(float64(v), floatFormat, 3, 64) + case float64: + return strconv.FormatFloat(v, floatFormat, 3, 64) + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + return fmt.Sprintf("%d", value) + case string: + return escapeString(v) + default: + return escapeString(fmt.Sprintf("%+v", value)) + } +} + +var stringBufPool = sync.Pool{ + New: func() interface{} { return new(bytes.Buffer) }, +} + +func escapeString(s string) string { + needsQuotes := false + needsEscape := false + for _, r := range s { + if r <= ' ' || r == '=' || r == '"' { + needsQuotes = true + } + if r == '\\' || r == '"' || r == '\n' || r == '\r' || r == '\t' { + needsEscape = true + } + } + if !needsEscape && !needsQuotes { + return s + } + e := stringBufPool.Get().(*bytes.Buffer) + e.WriteByte('"') + for _, r := range s { + switch r { + case '\\', '"': + e.WriteByte('\\') + e.WriteByte(byte(r)) + case '\n': + e.WriteString("\\n") + case '\r': + e.WriteString("\\r") + case '\t': + e.WriteString("\\t") + default: + e.WriteRune(r) + } + } + e.WriteByte('"') + var ret string + if needsQuotes { + ret = e.String() + } else { + ret = string(e.Bytes()[1 : e.Len()-1]) + } + e.Reset() + stringBufPool.Put(e) + return ret +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/cpu.go b/vendor/github.com/ethereum/go-ethereum/metrics/cpu.go new file mode 100644 index 00000000..3278d816 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/cpu.go @@ -0,0 +1,36 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package metrics + +import "github.com/elastic/gosigar" + +// CPUStats is the system and process CPU stats. +type CPUStats struct { + GlobalTime int64 // Time spent by the CPU working on all processes + GlobalWait int64 // Time spent by waiting on disk for all processes + LocalTime int64 // Time spent by the CPU working on this process +} + +// ReadCPUStats retrieves the current CPU stats. +func ReadCPUStats(stats *CPUStats) { + global := gosigar.Cpu{} + global.Get() + + stats.GlobalTime = int64(global.User + global.Nice + global.Sys) + stats.GlobalWait = int64(global.Wait) + stats.LocalTime = getProcessCPUTime() +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/cpu_syscall.go b/vendor/github.com/ethereum/go-ethereum/metrics/cpu_syscall.go new file mode 100644 index 00000000..e245453e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/cpu_syscall.go @@ -0,0 +1,35 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build !windows + +package metrics + +import ( + "syscall" + + "github.com/ethereum/go-ethereum/log" +) + +// getProcessCPUTime retrieves the process' CPU time since program startup. +func getProcessCPUTime() int64 { + var usage syscall.Rusage + if err := syscall.Getrusage(syscall.RUSAGE_SELF, &usage); err != nil { + log.Warn("Failed to retrieve CPU time", "err", err) + return 0 + } + return int64(usage.Utime.Sec+usage.Stime.Sec)*100 + int64(usage.Utime.Usec+usage.Stime.Usec)/10000 //nolint:unconvert +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/cpu_windows.go b/vendor/github.com/ethereum/go-ethereum/metrics/cpu_windows.go new file mode 100644 index 00000000..fb29a52a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/cpu_windows.go @@ -0,0 +1,23 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package metrics + +// getProcessCPUTime returns 0 on Windows as there is no system call to resolve +// the actual process' CPU time. +func getProcessCPUTime() int64 { + return 0 +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/exp/exp.go b/vendor/github.com/ethereum/go-ethereum/metrics/exp/exp.go new file mode 100644 index 00000000..55820f1a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/exp/exp.go @@ -0,0 +1,171 @@ +// Hook go-metrics into expvar +// on any /debug/metrics request, load all vars from the registry into expvar, and execute regular expvar handler +package exp + +import ( + "expvar" + "fmt" + "net/http" + "sync" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/prometheus" +) + +type exp struct { + expvarLock sync.Mutex // expvar panics if you try to register the same var twice, so we must probe it safely + registry metrics.Registry +} + +func (exp *exp) expHandler(w http.ResponseWriter, r *http.Request) { + // load our variables into expvar + exp.syncToExpvar() + + // now just run the official expvar handler code (which is not publicly callable, so pasted inline) + w.Header().Set("Content-Type", "application/json; charset=utf-8") + fmt.Fprintf(w, "{\n") + first := true + expvar.Do(func(kv expvar.KeyValue) { + if !first { + fmt.Fprintf(w, ",\n") + } + first = false + fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) + }) + fmt.Fprintf(w, "\n}\n") +} + +// Exp will register an expvar powered metrics handler with http.DefaultServeMux on "/debug/vars" +func Exp(r metrics.Registry) { + h := ExpHandler(r) + // this would cause a panic: + // panic: http: multiple registrations for /debug/vars + // http.HandleFunc("/debug/vars", e.expHandler) + // haven't found an elegant way, so just use a different endpoint + http.Handle("/debug/metrics", h) + http.Handle("/debug/metrics/prometheus", prometheus.Handler(r)) +} + +// ExpHandler will return an expvar powered metrics handler. +func ExpHandler(r metrics.Registry) http.Handler { + e := exp{sync.Mutex{}, r} + return http.HandlerFunc(e.expHandler) +} + +func (exp *exp) getInt(name string) *expvar.Int { + var v *expvar.Int + exp.expvarLock.Lock() + p := expvar.Get(name) + if p != nil { + v = p.(*expvar.Int) + } else { + v = new(expvar.Int) + expvar.Publish(name, v) + } + exp.expvarLock.Unlock() + return v +} + +func (exp *exp) getFloat(name string) *expvar.Float { + var v *expvar.Float + exp.expvarLock.Lock() + p := expvar.Get(name) + if p != nil { + v = p.(*expvar.Float) + } else { + v = new(expvar.Float) + expvar.Publish(name, v) + } + exp.expvarLock.Unlock() + return v +} + +func (exp *exp) publishCounter(name string, metric metrics.Counter) { + v := exp.getInt(name) + v.Set(metric.Count()) +} + +func (exp *exp) publishGauge(name string, metric metrics.Gauge) { + v := exp.getInt(name) + v.Set(metric.Value()) +} +func (exp *exp) publishGaugeFloat64(name string, metric metrics.GaugeFloat64) { + exp.getFloat(name).Set(metric.Value()) +} + +func (exp *exp) publishHistogram(name string, metric metrics.Histogram) { + h := metric.Snapshot() + ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) + exp.getInt(name + ".count").Set(h.Count()) + exp.getFloat(name + ".min").Set(float64(h.Min())) + exp.getFloat(name + ".max").Set(float64(h.Max())) + exp.getFloat(name + ".mean").Set(h.Mean()) + exp.getFloat(name + ".std-dev").Set(h.StdDev()) + exp.getFloat(name + ".50-percentile").Set(ps[0]) + exp.getFloat(name + ".75-percentile").Set(ps[1]) + exp.getFloat(name + ".95-percentile").Set(ps[2]) + exp.getFloat(name + ".99-percentile").Set(ps[3]) + exp.getFloat(name + ".999-percentile").Set(ps[4]) +} + +func (exp *exp) publishMeter(name string, metric metrics.Meter) { + m := metric.Snapshot() + exp.getInt(name + ".count").Set(m.Count()) + exp.getFloat(name + ".one-minute").Set(m.Rate1()) + exp.getFloat(name + ".five-minute").Set(m.Rate5()) + exp.getFloat(name + ".fifteen-minute").Set((m.Rate15())) + exp.getFloat(name + ".mean").Set(m.RateMean()) +} + +func (exp *exp) publishTimer(name string, metric metrics.Timer) { + t := metric.Snapshot() + ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) + exp.getInt(name + ".count").Set(t.Count()) + exp.getFloat(name + ".min").Set(float64(t.Min())) + exp.getFloat(name + ".max").Set(float64(t.Max())) + exp.getFloat(name + ".mean").Set(t.Mean()) + exp.getFloat(name + ".std-dev").Set(t.StdDev()) + exp.getFloat(name + ".50-percentile").Set(ps[0]) + exp.getFloat(name + ".75-percentile").Set(ps[1]) + exp.getFloat(name + ".95-percentile").Set(ps[2]) + exp.getFloat(name + ".99-percentile").Set(ps[3]) + exp.getFloat(name + ".999-percentile").Set(ps[4]) + exp.getFloat(name + ".one-minute").Set(t.Rate1()) + exp.getFloat(name + ".five-minute").Set(t.Rate5()) + exp.getFloat(name + ".fifteen-minute").Set(t.Rate15()) + exp.getFloat(name + ".mean-rate").Set(t.RateMean()) +} + +func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer) { + t := metric.Snapshot() + ps := t.Percentiles([]float64{50, 75, 95, 99}) + exp.getInt(name + ".count").Set(int64(len(t.Values()))) + exp.getFloat(name + ".mean").Set(t.Mean()) + exp.getInt(name + ".50-percentile").Set(ps[0]) + exp.getInt(name + ".75-percentile").Set(ps[1]) + exp.getInt(name + ".95-percentile").Set(ps[2]) + exp.getInt(name + ".99-percentile").Set(ps[3]) +} + +func (exp *exp) syncToExpvar() { + exp.registry.Each(func(name string, i interface{}) { + switch i := i.(type) { + case metrics.Counter: + exp.publishCounter(name, i) + case metrics.Gauge: + exp.publishGauge(name, i) + case metrics.GaugeFloat64: + exp.publishGaugeFloat64(name, i) + case metrics.Histogram: + exp.publishHistogram(name, i) + case metrics.Meter: + exp.publishMeter(name, i) + case metrics.Timer: + exp.publishTimer(name, i) + case metrics.ResettingTimer: + exp.publishResettingTimer(name, i) + default: + panic(fmt.Sprintf("unsupported type for '%s': %T", name, i)) + } + }) +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/metrics.go b/vendor/github.com/ethereum/go-ethereum/metrics/metrics.go new file mode 100644 index 00000000..98e8ced2 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/metrics.go @@ -0,0 +1,126 @@ +// Go port of Coda Hale's Metrics library +// +// +// +// Coda Hale's original work: +package metrics + +import ( + "os" + "runtime" + "strings" + "time" + + "github.com/ethereum/go-ethereum/log" +) + +// Enabled is checked by the constructor functions for all of the +// standard metrics. If it is true, the metric returned is a stub. +// +// This global kill-switch helps quantify the observer effect and makes +// for less cluttered pprof profiles. +var Enabled = false + +// EnabledExpensive is a soft-flag meant for external packages to check if costly +// metrics gathering is allowed or not. The goal is to separate standard metrics +// for health monitoring and debug metrics that might impact runtime performance. +var EnabledExpensive = false + +// enablerFlags is the CLI flag names to use to enable metrics collections. +var enablerFlags = []string{"metrics", "dashboard"} + +// expensiveEnablerFlags is the CLI flag names to use to enable metrics collections. +var expensiveEnablerFlags = []string{"metrics.expensive"} + +// Init enables or disables the metrics system. Since we need this to run before +// any other code gets to create meters and timers, we'll actually do an ugly hack +// and peek into the command line args for the metrics flag. +func init() { + for _, arg := range os.Args { + flag := strings.TrimLeft(arg, "-") + + for _, enabler := range enablerFlags { + if !Enabled && flag == enabler { + log.Info("Enabling metrics collection") + Enabled = true + } + } + for _, enabler := range expensiveEnablerFlags { + if !EnabledExpensive && flag == enabler { + log.Info("Enabling expensive metrics collection") + EnabledExpensive = true + } + } + } +} + +// CollectProcessMetrics periodically collects various metrics about the running +// process. +func CollectProcessMetrics(refresh time.Duration) { + // Short circuit if the metrics system is disabled + if !Enabled { + return + } + refreshFreq := int64(refresh / time.Second) + + // Create the various data collectors + cpuStats := make([]*CPUStats, 2) + memstats := make([]*runtime.MemStats, 2) + diskstats := make([]*DiskStats, 2) + for i := 0; i < len(memstats); i++ { + cpuStats[i] = new(CPUStats) + memstats[i] = new(runtime.MemStats) + diskstats[i] = new(DiskStats) + } + // Define the various metrics to collect + cpuSysLoad := GetOrRegisterGauge("system/cpu/sysload", DefaultRegistry) + cpuSysWait := GetOrRegisterGauge("system/cpu/syswait", DefaultRegistry) + cpuProcLoad := GetOrRegisterGauge("system/cpu/procload", DefaultRegistry) + + memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry) + memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry) + memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry) + memHeld := GetOrRegisterGauge("system/memory/held", DefaultRegistry) + memUsed := GetOrRegisterGauge("system/memory/used", DefaultRegistry) + + var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter + var diskReadBytesCounter, diskWriteBytesCounter Counter + if err := ReadDiskStats(diskstats[0]); err == nil { + diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) + diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) + diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry) + diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) + diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) + diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry) + } else { + log.Debug("Failed to read disk metrics", "err", err) + } + // Iterate loading the different stats and updating the meters + for i := 1; ; i++ { + location1 := i % 2 + location2 := (i - 1) % 2 + + ReadCPUStats(cpuStats[location1]) + cpuSysLoad.Update((cpuStats[location1].GlobalTime - cpuStats[location2].GlobalTime) / refreshFreq) + cpuSysWait.Update((cpuStats[location1].GlobalWait - cpuStats[location2].GlobalWait) / refreshFreq) + cpuProcLoad.Update((cpuStats[location1].LocalTime - cpuStats[location2].LocalTime) / refreshFreq) + + runtime.ReadMemStats(memstats[location1]) + memPauses.Mark(int64(memstats[location1].PauseTotalNs - memstats[location2].PauseTotalNs)) + memAllocs.Mark(int64(memstats[location1].Mallocs - memstats[location2].Mallocs)) + memFrees.Mark(int64(memstats[location1].Frees - memstats[location2].Frees)) + memHeld.Update(int64(memstats[location1].HeapSys - memstats[location1].HeapReleased)) + memUsed.Update(int64(memstats[location1].Alloc)) + + if ReadDiskStats(diskstats[location1]) == nil { + diskReads.Mark(diskstats[location1].ReadCount - diskstats[location2].ReadCount) + diskReadBytes.Mark(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) + diskWrites.Mark(diskstats[location1].WriteCount - diskstats[location2].WriteCount) + diskWriteBytes.Mark(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) + + diskReadBytesCounter.Inc(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) + diskWriteBytesCounter.Inc(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) + } + time.Sleep(refresh) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/collector.go b/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/collector.go new file mode 100644 index 00000000..8350fa2a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/collector.go @@ -0,0 +1,115 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package prometheus + +import ( + "bytes" + "fmt" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/metrics" +) + +var ( + typeGaugeTpl = "# TYPE %s gauge\n" + typeCounterTpl = "# TYPE %s counter\n" + typeSummaryTpl = "# TYPE %s summary\n" + keyValueTpl = "%s %v\n\n" + keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n\n" +) + +// collector is a collection of byte buffers that aggregate Prometheus reports +// for different metric types. +type collector struct { + buff *bytes.Buffer +} + +// newCollector createa a new Prometheus metric aggregator. +func newCollector() *collector { + return &collector{ + buff: &bytes.Buffer{}, + } +} + +func (c *collector) addCounter(name string, m metrics.Counter) { + c.writeGaugeCounter(name, m.Count()) +} + +func (c *collector) addGauge(name string, m metrics.Gauge) { + c.writeGaugeCounter(name, m.Value()) +} + +func (c *collector) addGaugeFloat64(name string, m metrics.GaugeFloat64) { + c.writeGaugeCounter(name, m.Value()) +} + +func (c *collector) addHistogram(name string, m metrics.Histogram) { + pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} + ps := m.Percentiles(pv) + c.writeSummaryCounter(name, m.Count()) + for i := range pv { + c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) + } +} + +func (c *collector) addMeter(name string, m metrics.Meter) { + c.writeGaugeCounter(name, m.Count()) +} + +func (c *collector) addTimer(name string, m metrics.Timer) { + pv := []float64{0.5, 0.75, 0.95, 0.99, 0.999, 0.9999} + ps := m.Percentiles(pv) + c.writeSummaryCounter(name, m.Count()) + for i := range pv { + c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) + } +} + +func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) { + if len(m.Values()) <= 0 { + return + } + ps := m.Percentiles([]float64{50, 95, 99}) + val := m.Values() + c.writeSummaryCounter(name, len(val)) + c.writeSummaryPercentile(name, "0.50", ps[0]) + c.writeSummaryPercentile(name, "0.95", ps[1]) + c.writeSummaryPercentile(name, "0.99", ps[2]) +} + +func (c *collector) writeGaugeCounter(name string, value interface{}) { + name = mutateKey(name) + c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name)) + c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) +} + +func (c *collector) writeSummaryCounter(name string, value interface{}) { + name = mutateKey(name + "_count") + c.buff.WriteString(fmt.Sprintf(typeCounterTpl, name)) + c.buff.WriteString(fmt.Sprintf(keyValueTpl, name, value)) +} + +func (c *collector) writeSummaryPercentile(name, p string, value interface{}) { + name = mutateKey(name) + c.buff.WriteString(fmt.Sprintf(typeSummaryTpl, name)) + c.buff.WriteString(fmt.Sprintf(keyQuantileTagValueTpl, name, p, value)) +} + +func mutateKey(key string) string { + return strings.Replace(key, "/", "_", -1) +} diff --git a/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/prometheus.go b/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/prometheus.go new file mode 100644 index 00000000..9ad5ec7e --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/metrics/prometheus/prometheus.go @@ -0,0 +1,68 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package prometheus exposes go-metrics into a Prometheus format. +package prometheus + +import ( + "fmt" + "net/http" + "sort" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +// Handler returns an HTTP handler which dump metrics in Prometheus format. +func Handler(reg metrics.Registry) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Gather and pre-sort the metrics to avoid random listings + var names []string + reg.Each(func(name string, i interface{}) { + names = append(names, name) + }) + sort.Strings(names) + + // Aggregate all the metris into a Prometheus collector + c := newCollector() + + for _, name := range names { + i := reg.Get(name) + + switch m := i.(type) { + case metrics.Counter: + c.addCounter(name, m.Snapshot()) + case metrics.Gauge: + c.addGauge(name, m.Snapshot()) + case metrics.GaugeFloat64: + c.addGaugeFloat64(name, m.Snapshot()) + case metrics.Histogram: + c.addHistogram(name, m.Snapshot()) + case metrics.Meter: + c.addMeter(name, m.Snapshot()) + case metrics.Timer: + c.addTimer(name, m.Snapshot()) + case metrics.ResettingTimer: + c.addResettingTimer(name, m.Snapshot()) + default: + log.Warn("Unknown Prometheus metric type", "type", fmt.Sprintf("%T", i)) + } + } + w.Header().Add("Content-Type", "text/plain") + w.Header().Add("Content-Length", fmt.Sprint(c.buff.Len())) + w.Write(c.buff.Bytes()) + }) +} diff --git a/vendor/github.com/ethereum/go-ethereum/miner/miner.go b/vendor/github.com/ethereum/go-ethereum/miner/miner.go new file mode 100644 index 00000000..ab97b0c0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/miner/miner.go @@ -0,0 +1,184 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package miner implements Ethereum block creation and mining. +package miner + +import ( + "fmt" + "math/big" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +// Backend wraps all methods required for mining. +type Backend interface { + BlockChain() *core.BlockChain + TxPool() *core.TxPool +} + +// Config is the configuration parameters of mining. +type Config struct { + Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account) + Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). + ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner + GasFloor uint64 // Target gas floor for mined blocks. + GasCeil uint64 // Target gas ceiling for mined blocks. + GasPrice *big.Int // Minimum gas price for mining a transaction + Recommit time.Duration // The time interval for miner to re-create mining work. + Noverify bool // Disable remote mining solution verification(only useful in ethash). +} + +// Miner creates blocks and searches for proof-of-work values. +type Miner struct { + mux *event.TypeMux + worker *worker + coinbase common.Address + eth Backend + engine consensus.Engine + exitCh chan struct{} + + canStart int32 // can start indicates whether we can start the mining operation + shouldStart int32 // should start indicates whether we should start after sync +} + +func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool) *Miner { + miner := &Miner{ + eth: eth, + mux: mux, + engine: engine, + exitCh: make(chan struct{}), + worker: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock), + canStart: 1, + } + go miner.update() + + return miner +} + +// update keeps track of the downloader events. Please be aware that this is a one shot type of update loop. +// It's entered once and as soon as `Done` or `Failed` has been broadcasted the events are unregistered and +// the loop is exited. This to prevent a major security vuln where external parties can DOS you with blocks +// and halt your mining operation for as long as the DOS continues. +func (self *Miner) update() { + events := self.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) + defer events.Unsubscribe() + + for { + select { + case ev := <-events.Chan(): + if ev == nil { + return + } + switch ev.Data.(type) { + case downloader.StartEvent: + atomic.StoreInt32(&self.canStart, 0) + if self.Mining() { + self.Stop() + atomic.StoreInt32(&self.shouldStart, 1) + log.Info("Mining aborted due to sync") + } + case downloader.DoneEvent, downloader.FailedEvent: + shouldStart := atomic.LoadInt32(&self.shouldStart) == 1 + + atomic.StoreInt32(&self.canStart, 1) + atomic.StoreInt32(&self.shouldStart, 0) + if shouldStart { + self.Start(self.coinbase) + } + // stop immediately and ignore all further pending events + return + } + case <-self.exitCh: + return + } + } +} + +func (self *Miner) Start(coinbase common.Address) { + atomic.StoreInt32(&self.shouldStart, 1) + self.SetEtherbase(coinbase) + + if atomic.LoadInt32(&self.canStart) == 0 { + log.Info("Network syncing, will start miner afterwards") + return + } + self.worker.start() +} + +func (self *Miner) Stop() { + self.worker.stop() + atomic.StoreInt32(&self.shouldStart, 0) +} + +func (self *Miner) Close() { + self.worker.close() + close(self.exitCh) +} + +func (self *Miner) Mining() bool { + return self.worker.isRunning() +} + +func (self *Miner) HashRate() uint64 { + if pow, ok := self.engine.(consensus.PoW); ok { + return uint64(pow.Hashrate()) + } + return 0 +} + +func (self *Miner) SetExtra(extra []byte) error { + if uint64(len(extra)) > params.MaximumExtraDataSize { + return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) + } + self.worker.setExtra(extra) + return nil +} + +// SetRecommitInterval sets the interval for sealing work resubmitting. +func (self *Miner) SetRecommitInterval(interval time.Duration) { + self.worker.setRecommitInterval(interval) +} + +// Pending returns the currently pending block and associated state. +func (self *Miner) Pending() (*types.Block, *state.StateDB) { + return self.worker.pending() +} + +// PendingBlock returns the currently pending block. +// +// Note, to access both the pending block and the pending state +// simultaneously, please use Pending(), as the pending state can +// change between multiple method calls +func (self *Miner) PendingBlock() *types.Block { + return self.worker.pendingBlock() +} + +func (self *Miner) SetEtherbase(addr common.Address) { + self.coinbase = addr + self.worker.setEtherbase(addr) +} diff --git a/vendor/github.com/ethereum/go-ethereum/miner/stress_clique.go b/vendor/github.com/ethereum/go-ethereum/miner/stress_clique.go new file mode 100644 index 00000000..7f5db2e5 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/miner/stress_clique.go @@ -0,0 +1,214 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build none + +// This file contains a miner stress test based on the Clique consensus engine. +package main + +import ( + "bytes" + "crypto/ecdsa" + "io/ioutil" + "math/big" + "math/rand" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" +) + +func main() { + log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) + + // Generate a batch of accounts to seal and fund with + faucets := make([]*ecdsa.PrivateKey, 128) + for i := 0; i < len(faucets); i++ { + faucets[i], _ = crypto.GenerateKey() + } + sealers := make([]*ecdsa.PrivateKey, 4) + for i := 0; i < len(sealers); i++ { + sealers[i], _ = crypto.GenerateKey() + } + // Create a Clique network based off of the Rinkeby config + genesis := makeGenesis(faucets, sealers) + + var ( + nodes []*node.Node + enodes []*enode.Node + ) + for _, sealer := range sealers { + // Start the node and wait until it's up + node, err := makeSealer(genesis) + if err != nil { + panic(err) + } + defer node.Close() + + for node.Server().NodeInfo().Ports.Listener == 0 { + time.Sleep(250 * time.Millisecond) + } + // Connect the node to al the previous ones + for _, n := range enodes { + node.Server().AddPeer(n) + } + // Start tracking the node and it's enode + nodes = append(nodes, node) + enodes = append(enodes, node.Server().Self()) + + // Inject the signer key and start sealing with it + store := node.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + signer, err := store.ImportECDSA(sealer, "") + if err != nil { + panic(err) + } + if err := store.Unlock(signer, ""); err != nil { + panic(err) + } + } + // Iterate over all the nodes and start signing with them + time.Sleep(3 * time.Second) + + for _, node := range nodes { + var ethereum *eth.Ethereum + if err := node.Service(ðereum); err != nil { + panic(err) + } + if err := ethereum.StartMining(1); err != nil { + panic(err) + } + } + time.Sleep(3 * time.Second) + + // Start injecting transactions from the faucet like crazy + nonces := make([]uint64, len(faucets)) + for { + index := rand.Intn(len(faucets)) + + // Fetch the accessor for the relevant signer + var ethereum *eth.Ethereum + if err := nodes[index%len(nodes)].Service(ðereum); err != nil { + panic(err) + } + // Create a self transaction and inject into the pool + tx, err := types.SignTx(types.NewTransaction(nonces[index], crypto.PubkeyToAddress(faucets[index].PublicKey), new(big.Int), 21000, big.NewInt(100000000000), nil), types.HomesteadSigner{}, faucets[index]) + if err != nil { + panic(err) + } + if err := ethereum.TxPool().AddLocal(tx); err != nil { + panic(err) + } + nonces[index]++ + + // Wait if we're too saturated + if pend, _ := ethereum.TxPool().Stats(); pend > 2048 { + time.Sleep(100 * time.Millisecond) + } + } +} + +// makeGenesis creates a custom Clique genesis block based on some pre-defined +// signer and faucet accounts. +func makeGenesis(faucets []*ecdsa.PrivateKey, sealers []*ecdsa.PrivateKey) *core.Genesis { + // Create a Clique network based off of the Rinkeby config + genesis := core.DefaultRinkebyGenesisBlock() + genesis.GasLimit = 25000000 + + genesis.Config.ChainID = big.NewInt(18) + genesis.Config.Clique.Period = 1 + genesis.Config.EIP150Hash = common.Hash{} + + genesis.Alloc = core.GenesisAlloc{} + for _, faucet := range faucets { + genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = core.GenesisAccount{ + Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil), + } + } + // Sort the signers and embed into the extra-data section + signers := make([]common.Address, len(sealers)) + for i, sealer := range sealers { + signers[i] = crypto.PubkeyToAddress(sealer.PublicKey) + } + for i := 0; i < len(signers); i++ { + for j := i + 1; j < len(signers); j++ { + if bytes.Compare(signers[i][:], signers[j][:]) > 0 { + signers[i], signers[j] = signers[j], signers[i] + } + } + } + genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) + for i, signer := range signers { + copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) + } + // Return the genesis block for initialization + return genesis +} + +func makeSealer(genesis *core.Genesis) (*node.Node, error) { + // Define the basic configurations for the Ethereum node + datadir, _ := ioutil.TempDir("", "") + + config := &node.Config{ + Name: "geth", + Version: params.Version, + DataDir: datadir, + P2P: p2p.Config{ + ListenAddr: "0.0.0.0:0", + NoDiscovery: true, + MaxPeers: 25, + }, + NoUSB: true, + } + // Start the node and configure a full Ethereum node on it + stack, err := node.New(config) + if err != nil { + return nil, err + } + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return eth.New(ctx, ð.Config{ + Genesis: genesis, + NetworkId: genesis.Config.ChainID.Uint64(), + SyncMode: downloader.FullSync, + DatabaseCache: 256, + DatabaseHandles: 256, + TxPool: core.DefaultTxPoolConfig, + GPO: eth.DefaultConfig.GPO, + Miner: Config{ + GasFloor: genesis.GasLimit * 9 / 10, + GasCeil: genesis.GasLimit * 11 / 10, + GasPrice: big.NewInt(1), + Recommit: time.Second, + }, + }) + }); err != nil { + return nil, err + } + // Start the node and return if successful + return stack, stack.Start() +} diff --git a/vendor/github.com/ethereum/go-ethereum/miner/stress_ethash.go b/vendor/github.com/ethereum/go-ethereum/miner/stress_ethash.go new file mode 100644 index 00000000..7d4a7d24 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/miner/stress_ethash.go @@ -0,0 +1,194 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build none + +// This file contains a miner stress test based on the Ethash consensus engine. +package main + +import ( + "crypto/ecdsa" + "io/ioutil" + "math/big" + "math/rand" + "os" + "path/filepath" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" +) + +func main() { + log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) + fdlimit.Raise(2048) + + // Generate a batch of accounts to seal and fund with + faucets := make([]*ecdsa.PrivateKey, 128) + for i := 0; i < len(faucets); i++ { + faucets[i], _ = crypto.GenerateKey() + } + // Pre-generate the ethash mining DAG so we don't race + ethash.MakeDataset(1, filepath.Join(os.Getenv("HOME"), ".ethash")) + + // Create an Ethash network based off of the Ropsten config + genesis := makeGenesis(faucets) + + var ( + nodes []*node.Node + enodes []*enode.Node + ) + for i := 0; i < 4; i++ { + // Start the node and wait until it's up + node, err := makeMiner(genesis) + if err != nil { + panic(err) + } + defer node.Close() + + for node.Server().NodeInfo().Ports.Listener == 0 { + time.Sleep(250 * time.Millisecond) + } + // Connect the node to al the previous ones + for _, n := range enodes { + node.Server().AddPeer(n) + } + // Start tracking the node and it's enode + nodes = append(nodes, node) + enodes = append(enodes, node.Server().Self()) + + // Inject the signer key and start sealing with it + store := node.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + if _, err := store.NewAccount(""); err != nil { + panic(err) + } + } + // Iterate over all the nodes and start signing with them + time.Sleep(3 * time.Second) + + for _, node := range nodes { + var ethereum *eth.Ethereum + if err := node.Service(ðereum); err != nil { + panic(err) + } + if err := ethereum.StartMining(1); err != nil { + panic(err) + } + } + time.Sleep(3 * time.Second) + + // Start injecting transactions from the faucets like crazy + nonces := make([]uint64, len(faucets)) + for { + index := rand.Intn(len(faucets)) + + // Fetch the accessor for the relevant signer + var ethereum *eth.Ethereum + if err := nodes[index%len(nodes)].Service(ðereum); err != nil { + panic(err) + } + // Create a self transaction and inject into the pool + tx, err := types.SignTx(types.NewTransaction(nonces[index], crypto.PubkeyToAddress(faucets[index].PublicKey), new(big.Int), 21000, big.NewInt(100000000000+rand.Int63n(65536)), nil), types.HomesteadSigner{}, faucets[index]) + if err != nil { + panic(err) + } + if err := ethereum.TxPool().AddLocal(tx); err != nil { + panic(err) + } + nonces[index]++ + + // Wait if we're too saturated + if pend, _ := ethereum.TxPool().Stats(); pend > 2048 { + time.Sleep(100 * time.Millisecond) + } + } +} + +// makeGenesis creates a custom Ethash genesis block based on some pre-defined +// faucet accounts. +func makeGenesis(faucets []*ecdsa.PrivateKey) *core.Genesis { + genesis := core.DefaultTestnetGenesisBlock() + genesis.Difficulty = params.MinimumDifficulty + genesis.GasLimit = 25000000 + + genesis.Config.ChainID = big.NewInt(18) + genesis.Config.EIP150Hash = common.Hash{} + + genesis.Alloc = core.GenesisAlloc{} + for _, faucet := range faucets { + genesis.Alloc[crypto.PubkeyToAddress(faucet.PublicKey)] = core.GenesisAccount{ + Balance: new(big.Int).Exp(big.NewInt(2), big.NewInt(128), nil), + } + } + return genesis +} + +func makeMiner(genesis *core.Genesis) (*node.Node, error) { + // Define the basic configurations for the Ethereum node + datadir, _ := ioutil.TempDir("", "") + + config := &node.Config{ + Name: "geth", + Version: params.Version, + DataDir: datadir, + P2P: p2p.Config{ + ListenAddr: "0.0.0.0:0", + NoDiscovery: true, + MaxPeers: 25, + }, + NoUSB: true, + UseLightweightKDF: true, + } + // Start the node and configure a full Ethereum node on it + stack, err := node.New(config) + if err != nil { + return nil, err + } + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return eth.New(ctx, ð.Config{ + Genesis: genesis, + NetworkId: genesis.Config.ChainID.Uint64(), + SyncMode: downloader.FullSync, + DatabaseCache: 256, + DatabaseHandles: 256, + TxPool: core.DefaultTxPoolConfig, + GPO: eth.DefaultConfig.GPO, + Ethash: eth.DefaultConfig.Ethash, + Miner: Config{ + GasFloor: genesis.GasLimit * 9 / 10, + GasCeil: genesis.GasLimit * 11 / 10, + GasPrice: big.NewInt(1), + Recommit: time.Second, + }, + }) + }); err != nil { + return nil, err + } + // Start the node and return if successful + return stack, stack.Start() +} diff --git a/vendor/github.com/ethereum/go-ethereum/miner/worker.go b/vendor/github.com/ethereum/go-ethereum/miner/worker.go new file mode 100644 index 00000000..64ac21cc --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/miner/worker.go @@ -0,0 +1,988 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package miner + +import ( + "bytes" + "errors" + "math/big" + "sync" + "sync/atomic" + "time" + + mapset "github.com/deckarep/golang-set" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +const ( + // resultQueueSize is the size of channel listening to sealing result. + resultQueueSize = 10 + + // txChanSize is the size of channel listening to NewTxsEvent. + // The number is referenced from the size of tx pool. + txChanSize = 4096 + + // chainHeadChanSize is the size of channel listening to ChainHeadEvent. + chainHeadChanSize = 10 + + // chainSideChanSize is the size of channel listening to ChainSideEvent. + chainSideChanSize = 10 + + // resubmitAdjustChanSize is the size of resubmitting interval adjustment channel. + resubmitAdjustChanSize = 10 + + // miningLogAtDepth is the number of confirmations before logging successful mining. + miningLogAtDepth = 7 + + // minRecommitInterval is the minimal time interval to recreate the mining block with + // any newly arrived transactions. + minRecommitInterval = 1 * time.Second + + // maxRecommitInterval is the maximum time interval to recreate the mining block with + // any newly arrived transactions. + maxRecommitInterval = 15 * time.Second + + // intervalAdjustRatio is the impact a single interval adjustment has on sealing work + // resubmitting interval. + intervalAdjustRatio = 0.1 + + // intervalAdjustBias is applied during the new resubmit interval calculation in favor of + // increasing upper limit or decreasing lower limit so that the limit can be reachable. + intervalAdjustBias = 200 * 1000.0 * 1000.0 + + // staleThreshold is the maximum depth of the acceptable stale block. + staleThreshold = 7 +) + +// environment is the worker's current environment and holds all of the current state information. +type environment struct { + signer types.Signer + + state *state.StateDB // apply state changes here + ancestors mapset.Set // ancestor set (used for checking uncle parent validity) + family mapset.Set // family set (used for checking uncle invalidity) + uncles mapset.Set // uncle set + tcount int // tx count in cycle + gasPool *core.GasPool // available gas used to pack transactions + + header *types.Header + txs []*types.Transaction + receipts []*types.Receipt +} + +// task contains all information for consensus engine sealing and result submitting. +type task struct { + receipts []*types.Receipt + state *state.StateDB + block *types.Block + createdAt time.Time +} + +const ( + commitInterruptNone int32 = iota + commitInterruptNewHead + commitInterruptResubmit +) + +// newWorkReq represents a request for new sealing work submitting with relative interrupt notifier. +type newWorkReq struct { + interrupt *int32 + noempty bool + timestamp int64 +} + +// intervalAdjust represents a resubmitting interval adjustment. +type intervalAdjust struct { + ratio float64 + inc bool +} + +// worker is the main object which takes care of submitting new work to consensus engine +// and gathering the sealing result. +type worker struct { + config *Config + chainConfig *params.ChainConfig + engine consensus.Engine + eth Backend + chain *core.BlockChain + + // Subscriptions + mux *event.TypeMux + txsCh chan core.NewTxsEvent + txsSub event.Subscription + chainHeadCh chan core.ChainHeadEvent + chainHeadSub event.Subscription + chainSideCh chan core.ChainSideEvent + chainSideSub event.Subscription + + // Channels + newWorkCh chan *newWorkReq + taskCh chan *task + resultCh chan *types.Block + startCh chan struct{} + exitCh chan struct{} + resubmitIntervalCh chan time.Duration + resubmitAdjustCh chan *intervalAdjust + + current *environment // An environment for current running cycle. + localUncles map[common.Hash]*types.Block // A set of side blocks generated locally as the possible uncle blocks. + remoteUncles map[common.Hash]*types.Block // A set of side blocks as the possible uncle blocks. + unconfirmed *unconfirmedBlocks // A set of locally mined blocks pending canonicalness confirmations. + + mu sync.RWMutex // The lock used to protect the coinbase and extra fields + coinbase common.Address + extra []byte + + pendingMu sync.RWMutex + pendingTasks map[common.Hash]*task + + snapshotMu sync.RWMutex // The lock used to protect the block snapshot and state snapshot + snapshotBlock *types.Block + snapshotState *state.StateDB + + // atomic status counters + running int32 // The indicator whether the consensus engine is running or not. + newTxs int32 // New arrival transaction count since last sealing work submitting. + + // External functions + isLocalBlock func(block *types.Block) bool // Function used to determine whether the specified block is mined by local miner. + + // Test hooks + newTaskHook func(*task) // Method to call upon receiving a new sealing task. + skipSealHook func(*task) bool // Method to decide whether skipping the sealing. + fullTaskHook func() // Method to call before pushing the full sealing task. + resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. +} + +func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool) *worker { + worker := &worker{ + config: config, + chainConfig: chainConfig, + engine: engine, + eth: eth, + mux: mux, + chain: eth.BlockChain(), + isLocalBlock: isLocalBlock, + localUncles: make(map[common.Hash]*types.Block), + remoteUncles: make(map[common.Hash]*types.Block), + unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), miningLogAtDepth), + pendingTasks: make(map[common.Hash]*task), + txsCh: make(chan core.NewTxsEvent, txChanSize), + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), + chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize), + newWorkCh: make(chan *newWorkReq), + taskCh: make(chan *task), + resultCh: make(chan *types.Block, resultQueueSize), + exitCh: make(chan struct{}), + startCh: make(chan struct{}, 1), + resubmitIntervalCh: make(chan time.Duration), + resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize), + } + // Subscribe NewTxsEvent for tx pool + worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh) + // Subscribe events for blockchain + worker.chainHeadSub = eth.BlockChain().SubscribeChainHeadEvent(worker.chainHeadCh) + worker.chainSideSub = eth.BlockChain().SubscribeChainSideEvent(worker.chainSideCh) + + // Sanitize recommit interval if the user-specified one is too short. + recommit := worker.config.Recommit + if recommit < minRecommitInterval { + log.Warn("Sanitizing miner recommit interval", "provided", recommit, "updated", minRecommitInterval) + recommit = minRecommitInterval + } + + go worker.mainLoop() + go worker.newWorkLoop(recommit) + go worker.resultLoop() + go worker.taskLoop() + + // Submit first work to initialize pending state. + worker.startCh <- struct{}{} + + return worker +} + +// setEtherbase sets the etherbase used to initialize the block coinbase field. +func (w *worker) setEtherbase(addr common.Address) { + w.mu.Lock() + defer w.mu.Unlock() + w.coinbase = addr +} + +// setExtra sets the content used to initialize the block extra field. +func (w *worker) setExtra(extra []byte) { + w.mu.Lock() + defer w.mu.Unlock() + w.extra = extra +} + +// setRecommitInterval updates the interval for miner sealing work recommitting. +func (w *worker) setRecommitInterval(interval time.Duration) { + w.resubmitIntervalCh <- interval +} + +// pending returns the pending state and corresponding block. +func (w *worker) pending() (*types.Block, *state.StateDB) { + // return a snapshot to avoid contention on currentMu mutex + w.snapshotMu.RLock() + defer w.snapshotMu.RUnlock() + if w.snapshotState == nil { + return nil, nil + } + return w.snapshotBlock, w.snapshotState.Copy() +} + +// pendingBlock returns pending block. +func (w *worker) pendingBlock() *types.Block { + // return a snapshot to avoid contention on currentMu mutex + w.snapshotMu.RLock() + defer w.snapshotMu.RUnlock() + return w.snapshotBlock +} + +// start sets the running status as 1 and triggers new work submitting. +func (w *worker) start() { + atomic.StoreInt32(&w.running, 1) + w.startCh <- struct{}{} +} + +// stop sets the running status as 0. +func (w *worker) stop() { + atomic.StoreInt32(&w.running, 0) +} + +// isRunning returns an indicator whether worker is running or not. +func (w *worker) isRunning() bool { + return atomic.LoadInt32(&w.running) == 1 +} + +// close terminates all background threads maintained by the worker. +// Note the worker does not support being closed multiple times. +func (w *worker) close() { + close(w.exitCh) +} + +// newWorkLoop is a standalone goroutine to submit new mining work upon received events. +func (w *worker) newWorkLoop(recommit time.Duration) { + var ( + interrupt *int32 + minRecommit = recommit // minimal resubmit interval specified by user. + timestamp int64 // timestamp for each round of mining. + ) + + timer := time.NewTimer(0) + <-timer.C // discard the initial tick + + // commit aborts in-flight transaction execution with given signal and resubmits a new one. + commit := func(noempty bool, s int32) { + if interrupt != nil { + atomic.StoreInt32(interrupt, s) + } + interrupt = new(int32) + w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp} + timer.Reset(recommit) + atomic.StoreInt32(&w.newTxs, 0) + } + // recalcRecommit recalculates the resubmitting interval upon feedback. + recalcRecommit := func(target float64, inc bool) { + var ( + prev = float64(recommit.Nanoseconds()) + next float64 + ) + if inc { + next = prev*(1-intervalAdjustRatio) + intervalAdjustRatio*(target+intervalAdjustBias) + // Recap if interval is larger than the maximum time interval + if next > float64(maxRecommitInterval.Nanoseconds()) { + next = float64(maxRecommitInterval.Nanoseconds()) + } + } else { + next = prev*(1-intervalAdjustRatio) + intervalAdjustRatio*(target-intervalAdjustBias) + // Recap if interval is less than the user specified minimum + if next < float64(minRecommit.Nanoseconds()) { + next = float64(minRecommit.Nanoseconds()) + } + } + recommit = time.Duration(int64(next)) + } + // clearPending cleans the stale pending tasks. + clearPending := func(number uint64) { + w.pendingMu.Lock() + for h, t := range w.pendingTasks { + if t.block.NumberU64()+staleThreshold <= number { + delete(w.pendingTasks, h) + } + } + w.pendingMu.Unlock() + } + + for { + select { + case <-w.startCh: + clearPending(w.chain.CurrentBlock().NumberU64()) + timestamp = time.Now().Unix() + commit(false, commitInterruptNewHead) + + case head := <-w.chainHeadCh: + clearPending(head.Block.NumberU64()) + timestamp = time.Now().Unix() + commit(false, commitInterruptNewHead) + + case <-timer.C: + // If mining is running resubmit a new work cycle periodically to pull in + // higher priced transactions. Disable this overhead for pending blocks. + if w.isRunning() && (w.chainConfig.Clique == nil || w.chainConfig.Clique.Period > 0) { + // Short circuit if no new transaction arrives. + if atomic.LoadInt32(&w.newTxs) == 0 { + timer.Reset(recommit) + continue + } + commit(true, commitInterruptResubmit) + } + + case interval := <-w.resubmitIntervalCh: + // Adjust resubmit interval explicitly by user. + if interval < minRecommitInterval { + log.Warn("Sanitizing miner recommit interval", "provided", interval, "updated", minRecommitInterval) + interval = minRecommitInterval + } + log.Info("Miner recommit interval update", "from", minRecommit, "to", interval) + minRecommit, recommit = interval, interval + + if w.resubmitHook != nil { + w.resubmitHook(minRecommit, recommit) + } + + case adjust := <-w.resubmitAdjustCh: + // Adjust resubmit interval by feedback. + if adjust.inc { + before := recommit + recalcRecommit(float64(recommit.Nanoseconds())/adjust.ratio, true) + log.Trace("Increase miner recommit interval", "from", before, "to", recommit) + } else { + before := recommit + recalcRecommit(float64(minRecommit.Nanoseconds()), false) + log.Trace("Decrease miner recommit interval", "from", before, "to", recommit) + } + + if w.resubmitHook != nil { + w.resubmitHook(minRecommit, recommit) + } + + case <-w.exitCh: + return + } + } +} + +// mainLoop is a standalone goroutine to regenerate the sealing task based on the received event. +func (w *worker) mainLoop() { + defer w.txsSub.Unsubscribe() + defer w.chainHeadSub.Unsubscribe() + defer w.chainSideSub.Unsubscribe() + + for { + select { + case req := <-w.newWorkCh: + w.commitNewWork(req.interrupt, req.noempty, req.timestamp) + + case ev := <-w.chainSideCh: + // Short circuit for duplicate side blocks + if _, exist := w.localUncles[ev.Block.Hash()]; exist { + continue + } + if _, exist := w.remoteUncles[ev.Block.Hash()]; exist { + continue + } + // Add side block to possible uncle block set depending on the author. + if w.isLocalBlock != nil && w.isLocalBlock(ev.Block) { + w.localUncles[ev.Block.Hash()] = ev.Block + } else { + w.remoteUncles[ev.Block.Hash()] = ev.Block + } + // If our mining block contains less than 2 uncle blocks, + // add the new uncle block if valid and regenerate a mining block. + if w.isRunning() && w.current != nil && w.current.uncles.Cardinality() < 2 { + start := time.Now() + if err := w.commitUncle(w.current, ev.Block.Header()); err == nil { + var uncles []*types.Header + w.current.uncles.Each(func(item interface{}) bool { + hash, ok := item.(common.Hash) + if !ok { + return false + } + uncle, exist := w.localUncles[hash] + if !exist { + uncle, exist = w.remoteUncles[hash] + } + if !exist { + return false + } + uncles = append(uncles, uncle.Header()) + return false + }) + w.commit(uncles, nil, true, start) + } + } + + case ev := <-w.txsCh: + // Apply transactions to the pending state if we're not mining. + // + // Note all transactions received may not be continuous with transactions + // already included in the current mining block. These transactions will + // be automatically eliminated. + if !w.isRunning() && w.current != nil { + w.mu.RLock() + coinbase := w.coinbase + w.mu.RUnlock() + + txs := make(map[common.Address]types.Transactions) + for _, tx := range ev.Txs { + acc, _ := types.Sender(w.current.signer, tx) + txs[acc] = append(txs[acc], tx) + } + txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs) + w.commitTransactions(txset, coinbase, nil) + w.updateSnapshot() + } else { + // If clique is running in dev mode(period is 0), disable + // advance sealing here. + if w.chainConfig.Clique != nil && w.chainConfig.Clique.Period == 0 { + w.commitNewWork(nil, true, time.Now().Unix()) + } + } + atomic.AddInt32(&w.newTxs, int32(len(ev.Txs))) + + // System stopped + case <-w.exitCh: + return + case <-w.txsSub.Err(): + return + case <-w.chainHeadSub.Err(): + return + case <-w.chainSideSub.Err(): + return + } + } +} + +// taskLoop is a standalone goroutine to fetch sealing task from the generator and +// push them to consensus engine. +func (w *worker) taskLoop() { + var ( + stopCh chan struct{} + prev common.Hash + ) + + // interrupt aborts the in-flight sealing task. + interrupt := func() { + if stopCh != nil { + close(stopCh) + stopCh = nil + } + } + for { + select { + case task := <-w.taskCh: + if w.newTaskHook != nil { + w.newTaskHook(task) + } + // Reject duplicate sealing work due to resubmitting. + sealHash := w.engine.SealHash(task.block.Header()) + if sealHash == prev { + continue + } + // Interrupt previous sealing operation + interrupt() + stopCh, prev = make(chan struct{}), sealHash + + if w.skipSealHook != nil && w.skipSealHook(task) { + continue + } + w.pendingMu.Lock() + w.pendingTasks[w.engine.SealHash(task.block.Header())] = task + w.pendingMu.Unlock() + + if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil { + log.Warn("Block sealing failed", "err", err) + } + case <-w.exitCh: + interrupt() + return + } + } +} + +// resultLoop is a standalone goroutine to handle sealing result submitting +// and flush relative data to the database. +func (w *worker) resultLoop() { + for { + select { + case block := <-w.resultCh: + // Short circuit when receiving empty result. + if block == nil { + continue + } + // Short circuit when receiving duplicate result caused by resubmitting. + if w.chain.HasBlock(block.Hash(), block.NumberU64()) { + continue + } + var ( + sealhash = w.engine.SealHash(block.Header()) + hash = block.Hash() + ) + w.pendingMu.RLock() + task, exist := w.pendingTasks[sealhash] + w.pendingMu.RUnlock() + if !exist { + log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash) + continue + } + // Different block could share same sealhash, deep copy here to prevent write-write conflict. + var ( + receipts = make([]*types.Receipt, len(task.receipts)) + logs []*types.Log + ) + for i, receipt := range task.receipts { + // add block location fields + receipt.BlockHash = hash + receipt.BlockNumber = block.Number() + receipt.TransactionIndex = uint(i) + + receipts[i] = new(types.Receipt) + *receipts[i] = *receipt + // Update the block hash in all logs since it is now available and not when the + // receipt/log of individual transactions were created. + for _, log := range receipt.Logs { + log.BlockHash = hash + } + logs = append(logs, receipt.Logs...) + } + // Commit block and state to database. + stat, err := w.chain.WriteBlockWithState(block, receipts, task.state) + if err != nil { + log.Error("Failed writing block to chain", "err", err) + continue + } + log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, + "elapsed", common.PrettyDuration(time.Since(task.createdAt))) + + // Broadcast the block and announce chain insertion event + w.mux.Post(core.NewMinedBlockEvent{Block: block}) + + var events []interface{} + switch stat { + case core.CanonStatTy: + events = append(events, core.ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) + events = append(events, core.ChainHeadEvent{Block: block}) + case core.SideStatTy: + events = append(events, core.ChainSideEvent{Block: block}) + } + w.chain.PostChainEvents(events, logs) + + // Insert the block into the set of pending ones to resultLoop for confirmations + w.unconfirmed.Insert(block.NumberU64(), block.Hash()) + + case <-w.exitCh: + return + } + } +} + +// makeCurrent creates a new environment for the current cycle. +func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { + state, err := w.chain.StateAt(parent.Root()) + if err != nil { + return err + } + env := &environment{ + signer: types.NewEIP155Signer(w.chainConfig.ChainID), + state: state, + ancestors: mapset.NewSet(), + family: mapset.NewSet(), + uncles: mapset.NewSet(), + header: header, + } + + // when 08 is processed ancestors contain 07 (quick block) + for _, ancestor := range w.chain.GetBlocksFromHash(parent.Hash(), 7) { + for _, uncle := range ancestor.Uncles() { + env.family.Add(uncle.Hash()) + } + env.family.Add(ancestor.Hash()) + env.ancestors.Add(ancestor.Hash()) + } + + // Keep track of transactions which return errors so they can be removed + env.tcount = 0 + w.current = env + return nil +} + +// commitUncle adds the given block to uncle block set, returns error if failed to add. +func (w *worker) commitUncle(env *environment, uncle *types.Header) error { + hash := uncle.Hash() + if env.uncles.Contains(hash) { + return errors.New("uncle not unique") + } + if env.header.ParentHash == uncle.ParentHash { + return errors.New("uncle is sibling") + } + if !env.ancestors.Contains(uncle.ParentHash) { + return errors.New("uncle's parent unknown") + } + if env.family.Contains(hash) { + return errors.New("uncle already included") + } + env.uncles.Add(uncle.Hash()) + return nil +} + +// updateSnapshot updates pending snapshot block and state. +// Note this function assumes the current variable is thread safe. +func (w *worker) updateSnapshot() { + w.snapshotMu.Lock() + defer w.snapshotMu.Unlock() + + var uncles []*types.Header + w.current.uncles.Each(func(item interface{}) bool { + hash, ok := item.(common.Hash) + if !ok { + return false + } + uncle, exist := w.localUncles[hash] + if !exist { + uncle, exist = w.remoteUncles[hash] + } + if !exist { + return false + } + uncles = append(uncles, uncle.Header()) + return false + }) + + w.snapshotBlock = types.NewBlock( + w.current.header, + w.current.txs, + uncles, + w.current.receipts, + ) + + w.snapshotState = w.current.state.Copy() +} + +func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Address) ([]*types.Log, error) { + snap := w.current.state.Snapshot() + + receipt, _, err := core.ApplyTransaction(w.chainConfig, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, *w.chain.GetVMConfig()) + if err != nil { + w.current.state.RevertToSnapshot(snap) + return nil, err + } + w.current.txs = append(w.current.txs, tx) + w.current.receipts = append(w.current.receipts, receipt) + + return receipt.Logs, nil +} + +func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coinbase common.Address, interrupt *int32) bool { + // Short circuit if current is nil + if w.current == nil { + return true + } + + if w.current.gasPool == nil { + w.current.gasPool = new(core.GasPool).AddGas(w.current.header.GasLimit) + } + + var coalescedLogs []*types.Log + + for { + // In the following three cases, we will interrupt the execution of the transaction. + // (1) new head block event arrival, the interrupt signal is 1 + // (2) worker start or restart, the interrupt signal is 1 + // (3) worker recreate the mining block with any newly arrived transactions, the interrupt signal is 2. + // For the first two cases, the semi-finished work will be discarded. + // For the third case, the semi-finished work will be submitted to the consensus engine. + if interrupt != nil && atomic.LoadInt32(interrupt) != commitInterruptNone { + // Notify resubmit loop to increase resubmitting interval due to too frequent commits. + if atomic.LoadInt32(interrupt) == commitInterruptResubmit { + ratio := float64(w.current.header.GasLimit-w.current.gasPool.Gas()) / float64(w.current.header.GasLimit) + if ratio < 0.1 { + ratio = 0.1 + } + w.resubmitAdjustCh <- &intervalAdjust{ + ratio: ratio, + inc: true, + } + } + return atomic.LoadInt32(interrupt) == commitInterruptNewHead + } + // If we don't have enough gas for any further transactions then we're done + if w.current.gasPool.Gas() < params.TxGas { + log.Trace("Not enough gas for further transactions", "have", w.current.gasPool, "want", params.TxGas) + break + } + // Retrieve the next transaction and abort if all done + tx := txs.Peek() + if tx == nil { + break + } + // Error may be ignored here. The error has already been checked + // during transaction acceptance is the transaction pool. + // + // We use the eip155 signer regardless of the current hf. + from, _ := types.Sender(w.current.signer, tx) + // Check whether the tx is replay protected. If we're not in the EIP155 hf + // phase, start ignoring the sender until we do. + if tx.Protected() && !w.chainConfig.IsEIP155(w.current.header.Number) { + log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", w.chainConfig.EIP155Block) + + txs.Pop() + continue + } + // Start executing the transaction + w.current.state.Prepare(tx.Hash(), common.Hash{}, w.current.tcount) + + logs, err := w.commitTransaction(tx, coinbase) + switch err { + case core.ErrGasLimitReached: + // Pop the current out-of-gas transaction without shifting in the next from the account + log.Trace("Gas limit exceeded for current block", "sender", from) + txs.Pop() + + case core.ErrNonceTooLow: + // New head notification data race between the transaction pool and miner, shift + log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce()) + txs.Shift() + + case core.ErrNonceTooHigh: + // Reorg notification data race between the transaction pool and miner, skip account = + log.Trace("Skipping account with hight nonce", "sender", from, "nonce", tx.Nonce()) + txs.Pop() + + case nil: + // Everything ok, collect the logs and shift in the next transaction from the same account + coalescedLogs = append(coalescedLogs, logs...) + w.current.tcount++ + txs.Shift() + + default: + // Strange error, discard the transaction and get the next in line (note, the + // nonce-too-high clause will prevent us from executing in vain). + log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err) + txs.Shift() + } + } + + if !w.isRunning() && len(coalescedLogs) > 0 { + // We don't push the pendingLogsEvent while we are mining. The reason is that + // when we are mining, the worker will regenerate a mining block every 3 seconds. + // In order to avoid pushing the repeated pendingLog, we disable the pending log pushing. + + // make a copy, the state caches the logs and these logs get "upgraded" from pending to mined + // logs by filling in the block hash when the block was mined by the local miner. This can + // cause a race condition if a log was "upgraded" before the PendingLogsEvent is processed. + cpy := make([]*types.Log, len(coalescedLogs)) + for i, l := range coalescedLogs { + cpy[i] = new(types.Log) + *cpy[i] = *l + } + go w.mux.Post(core.PendingLogsEvent{Logs: cpy}) + } + // Notify resubmit loop to decrease resubmitting interval if current interval is larger + // than the user-specified one. + if interrupt != nil { + w.resubmitAdjustCh <- &intervalAdjust{inc: false} + } + return false +} + +// commitNewWork generates several new sealing tasks based on the parent block. +func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) { + w.mu.RLock() + defer w.mu.RUnlock() + + tstart := time.Now() + parent := w.chain.CurrentBlock() + + if parent.Time() >= uint64(timestamp) { + timestamp = int64(parent.Time() + 1) + } + // this will ensure we're not going off too far in the future + if now := time.Now().Unix(); timestamp > now+1 { + wait := time.Duration(timestamp-now) * time.Second + log.Info("Mining too far in the future", "wait", common.PrettyDuration(wait)) + time.Sleep(wait) + } + + num := parent.Number() + header := &types.Header{ + ParentHash: parent.Hash(), + Number: num.Add(num, common.Big1), + GasLimit: core.CalcGasLimit(parent, w.config.GasFloor, w.config.GasCeil), + Extra: w.extra, + Time: uint64(timestamp), + } + // Only set the coinbase if our consensus engine is running (avoid spurious block rewards) + if w.isRunning() { + if w.coinbase == (common.Address{}) { + log.Error("Refusing to mine without etherbase") + return + } + header.Coinbase = w.coinbase + } + if err := w.engine.Prepare(w.chain, header); err != nil { + log.Error("Failed to prepare header for mining", "err", err) + return + } + // If we are care about TheDAO hard-fork check whether to override the extra-data or not + if daoBlock := w.chainConfig.DAOForkBlock; daoBlock != nil { + // Check whether the block is among the fork extra-override range + limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) + if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 { + // Depending whether we support or oppose the fork, override differently + if w.chainConfig.DAOForkSupport { + header.Extra = common.CopyBytes(params.DAOForkBlockExtra) + } else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { + header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data + } + } + } + // Could potentially happen if starting to mine in an odd state. + err := w.makeCurrent(parent, header) + if err != nil { + log.Error("Failed to create mining context", "err", err) + return + } + // Create the current work task and check any fork transitions needed + env := w.current + if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { + misc.ApplyDAOHardFork(env.state) + } + // Accumulate the uncles for the current block + uncles := make([]*types.Header, 0, 2) + commitUncles := func(blocks map[common.Hash]*types.Block) { + // Clean up stale uncle blocks first + for hash, uncle := range blocks { + if uncle.NumberU64()+staleThreshold <= header.Number.Uint64() { + delete(blocks, hash) + } + } + for hash, uncle := range blocks { + if len(uncles) == 2 { + break + } + if err := w.commitUncle(env, uncle.Header()); err != nil { + log.Trace("Possible uncle rejected", "hash", hash, "reason", err) + } else { + log.Debug("Committing new uncle to block", "hash", hash) + uncles = append(uncles, uncle.Header()) + } + } + } + // Prefer to locally generated uncle + commitUncles(w.localUncles) + commitUncles(w.remoteUncles) + + if !noempty { + // Create an empty block based on temporary copied state for sealing in advance without waiting block + // execution finished. + w.commit(uncles, nil, false, tstart) + } + + // Fill the block with all available pending transactions. + pending, err := w.eth.TxPool().Pending() + if err != nil { + log.Error("Failed to fetch pending transactions", "err", err) + return + } + // Short circuit if there is no available pending transactions + if len(pending) == 0 { + w.updateSnapshot() + return + } + // Split the pending transactions into locals and remotes + localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending + for _, account := range w.eth.TxPool().Locals() { + if txs := remoteTxs[account]; len(txs) > 0 { + delete(remoteTxs, account) + localTxs[account] = txs + } + } + if len(localTxs) > 0 { + txs := types.NewTransactionsByPriceAndNonce(w.current.signer, localTxs) + if w.commitTransactions(txs, w.coinbase, interrupt) { + return + } + } + if len(remoteTxs) > 0 { + txs := types.NewTransactionsByPriceAndNonce(w.current.signer, remoteTxs) + if w.commitTransactions(txs, w.coinbase, interrupt) { + return + } + } + w.commit(uncles, w.fullTaskHook, true, tstart) +} + +// commit runs any post-transaction state modifications, assembles the final block +// and commits new work if consensus engine is running. +func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error { + // Deep copy receipts here to avoid interaction between different tasks. + receipts := make([]*types.Receipt, len(w.current.receipts)) + for i, l := range w.current.receipts { + receipts[i] = new(types.Receipt) + *receipts[i] = *l + } + s := w.current.state.Copy() + block, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts) + if err != nil { + return err + } + if w.isRunning() { + if interval != nil { + interval() + } + select { + case w.taskCh <- &task{receipts: receipts, state: s, block: block, createdAt: time.Now()}: + w.unconfirmed.Shift(block.NumberU64() - 1) + + feesWei := new(big.Int) + for i, tx := range block.Transactions() { + feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), tx.GasPrice())) + } + feesEth := new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether))) + + log.Info("Commit new mining work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), + "uncles", len(uncles), "txs", w.current.tcount, "gas", block.GasUsed(), "fees", feesEth, "elapsed", common.PrettyDuration(time.Since(start))) + + case <-w.exitCh: + log.Info("Worker has exited") + } + } + if update { + w.updateSnapshot() + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/mobile/types.go b/vendor/github.com/ethereum/go-ethereum/mobile/types.go new file mode 100644 index 00000000..b9c44c25 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/mobile/types.go @@ -0,0 +1,439 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains all the wrappers from the core/types package. + +package geth + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" +) + +// A Nonce is a 64-bit hash which proves (combined with the mix-hash) that +// a sufficient amount of computation has been carried out on a block. +type Nonce struct { + nonce types.BlockNonce +} + +// GetBytes retrieves the byte representation of the block nonce. +func (n *Nonce) GetBytes() []byte { + return n.nonce[:] +} + +// GetHex retrieves the hex string representation of the block nonce. +func (n *Nonce) GetHex() string { + return fmt.Sprintf("0x%x", n.nonce[:]) +} + +// Bloom represents a 256 bit bloom filter. +type Bloom struct { + bloom types.Bloom +} + +// GetBytes retrieves the byte representation of the bloom filter. +func (b *Bloom) GetBytes() []byte { + return b.bloom[:] +} + +// GetHex retrieves the hex string representation of the bloom filter. +func (b *Bloom) GetHex() string { + return fmt.Sprintf("0x%x", b.bloom[:]) +} + +// Header represents a block header in the Ethereum blockchain. +type Header struct { + header *types.Header +} + +// NewHeaderFromRLP parses a header from an RLP data dump. +func NewHeaderFromRLP(data []byte) (*Header, error) { + h := &Header{ + header: new(types.Header), + } + if err := rlp.DecodeBytes(common.CopyBytes(data), h.header); err != nil { + return nil, err + } + return h, nil +} + +// EncodeRLP encodes a header into an RLP data dump. +func (h *Header) EncodeRLP() ([]byte, error) { + return rlp.EncodeToBytes(h.header) +} + +// NewHeaderFromJSON parses a header from a JSON data dump. +func NewHeaderFromJSON(data string) (*Header, error) { + h := &Header{ + header: new(types.Header), + } + if err := json.Unmarshal([]byte(data), h.header); err != nil { + return nil, err + } + return h, nil +} + +// EncodeJSON encodes a header into a JSON data dump. +func (h *Header) EncodeJSON() (string, error) { + data, err := json.Marshal(h.header) + return string(data), err +} + +func (h *Header) GetParentHash() *Hash { return &Hash{h.header.ParentHash} } +func (h *Header) GetUncleHash() *Hash { return &Hash{h.header.UncleHash} } +func (h *Header) GetCoinbase() *Address { return &Address{h.header.Coinbase} } +func (h *Header) GetRoot() *Hash { return &Hash{h.header.Root} } +func (h *Header) GetTxHash() *Hash { return &Hash{h.header.TxHash} } +func (h *Header) GetReceiptHash() *Hash { return &Hash{h.header.ReceiptHash} } +func (h *Header) GetBloom() *Bloom { return &Bloom{h.header.Bloom} } +func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} } +func (h *Header) GetNumber() int64 { return h.header.Number.Int64() } +func (h *Header) GetGasLimit() int64 { return int64(h.header.GasLimit) } +func (h *Header) GetGasUsed() int64 { return int64(h.header.GasUsed) } +func (h *Header) GetTime() int64 { return int64(h.header.Time) } +func (h *Header) GetExtra() []byte { return h.header.Extra } +func (h *Header) GetMixDigest() *Hash { return &Hash{h.header.MixDigest} } +func (h *Header) GetNonce() *Nonce { return &Nonce{h.header.Nonce} } +func (h *Header) GetHash() *Hash { return &Hash{h.header.Hash()} } + +// Headers represents a slice of headers. +type Headers struct{ headers []*types.Header } + +// Size returns the number of headers in the slice. +func (h *Headers) Size() int { + return len(h.headers) +} + +// Get returns the header at the given index from the slice. +func (h *Headers) Get(index int) (header *Header, _ error) { + if index < 0 || index >= len(h.headers) { + return nil, errors.New("index out of bounds") + } + return &Header{h.headers[index]}, nil +} + +// Block represents an entire block in the Ethereum blockchain. +type Block struct { + block *types.Block +} + +// NewBlockFromRLP parses a block from an RLP data dump. +func NewBlockFromRLP(data []byte) (*Block, error) { + b := &Block{ + block: new(types.Block), + } + if err := rlp.DecodeBytes(common.CopyBytes(data), b.block); err != nil { + return nil, err + } + return b, nil +} + +// EncodeRLP encodes a block into an RLP data dump. +func (b *Block) EncodeRLP() ([]byte, error) { + return rlp.EncodeToBytes(b.block) +} + +// NewBlockFromJSON parses a block from a JSON data dump. +func NewBlockFromJSON(data string) (*Block, error) { + b := &Block{ + block: new(types.Block), + } + if err := json.Unmarshal([]byte(data), b.block); err != nil { + return nil, err + } + return b, nil +} + +// EncodeJSON encodes a block into a JSON data dump. +func (b *Block) EncodeJSON() (string, error) { + data, err := json.Marshal(b.block) + return string(data), err +} + +func (b *Block) GetParentHash() *Hash { return &Hash{b.block.ParentHash()} } +func (b *Block) GetUncleHash() *Hash { return &Hash{b.block.UncleHash()} } +func (b *Block) GetCoinbase() *Address { return &Address{b.block.Coinbase()} } +func (b *Block) GetRoot() *Hash { return &Hash{b.block.Root()} } +func (b *Block) GetTxHash() *Hash { return &Hash{b.block.TxHash()} } +func (b *Block) GetReceiptHash() *Hash { return &Hash{b.block.ReceiptHash()} } +func (b *Block) GetBloom() *Bloom { return &Bloom{b.block.Bloom()} } +func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} } +func (b *Block) GetNumber() int64 { return b.block.Number().Int64() } +func (b *Block) GetGasLimit() int64 { return int64(b.block.GasLimit()) } +func (b *Block) GetGasUsed() int64 { return int64(b.block.GasUsed()) } +func (b *Block) GetTime() int64 { return int64(b.block.Time()) } +func (b *Block) GetExtra() []byte { return b.block.Extra() } +func (b *Block) GetMixDigest() *Hash { return &Hash{b.block.MixDigest()} } +func (b *Block) GetNonce() int64 { return int64(b.block.Nonce()) } +func (b *Block) GetHash() *Hash { return &Hash{b.block.Hash()} } +func (b *Block) GetHeader() *Header { return &Header{b.block.Header()} } +func (b *Block) GetUncles() *Headers { return &Headers{b.block.Uncles()} } +func (b *Block) GetTransactions() *Transactions { return &Transactions{b.block.Transactions()} } +func (b *Block) GetTransaction(hash *Hash) *Transaction { + return &Transaction{b.block.Transaction(hash.hash)} +} + +// Transaction represents a single Ethereum transaction. +type Transaction struct { + tx *types.Transaction +} + +// NewContractCreation creates a new transaction for deploying a new contract with +// the given properties. +func NewContractCreation(nonce int64, amount *BigInt, gasLimit int64, gasPrice *BigInt, data []byte) *Transaction { + return &Transaction{types.NewContractCreation(uint64(nonce), amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data))} +} + +// NewTransaction creates a new transaction with the given properties. Contracts +// can be created by transacting with a nil recipient. +func NewTransaction(nonce int64, to *Address, amount *BigInt, gasLimit int64, gasPrice *BigInt, data []byte) *Transaction { + if to == nil { + return &Transaction{types.NewContractCreation(uint64(nonce), amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data))} + } + return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data))} +} + +// NewTransactionFromRLP parses a transaction from an RLP data dump. +func NewTransactionFromRLP(data []byte) (*Transaction, error) { + tx := &Transaction{ + tx: new(types.Transaction), + } + if err := rlp.DecodeBytes(common.CopyBytes(data), tx.tx); err != nil { + return nil, err + } + return tx, nil +} + +// EncodeRLP encodes a transaction into an RLP data dump. +func (tx *Transaction) EncodeRLP() ([]byte, error) { + return rlp.EncodeToBytes(tx.tx) +} + +// NewTransactionFromJSON parses a transaction from a JSON data dump. +func NewTransactionFromJSON(data string) (*Transaction, error) { + tx := &Transaction{ + tx: new(types.Transaction), + } + if err := json.Unmarshal([]byte(data), tx.tx); err != nil { + return nil, err + } + return tx, nil +} + +// EncodeJSON encodes a transaction into a JSON data dump. +func (tx *Transaction) EncodeJSON() (string, error) { + data, err := json.Marshal(tx.tx) + return string(data), err +} + +func (tx *Transaction) GetData() []byte { return tx.tx.Data() } +func (tx *Transaction) GetGas() int64 { return int64(tx.tx.Gas()) } +func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} } +func (tx *Transaction) GetValue() *BigInt { return &BigInt{tx.tx.Value()} } +func (tx *Transaction) GetNonce() int64 { return int64(tx.tx.Nonce()) } + +func (tx *Transaction) GetHash() *Hash { return &Hash{tx.tx.Hash()} } +func (tx *Transaction) GetCost() *BigInt { return &BigInt{tx.tx.Cost()} } + +// Deprecated: GetSigHash cannot know which signer to use. +func (tx *Transaction) GetSigHash() *Hash { return &Hash{types.HomesteadSigner{}.Hash(tx.tx)} } + +// Deprecated: use EthereumClient.TransactionSender +func (tx *Transaction) GetFrom(chainID *BigInt) (address *Address, _ error) { + var signer types.Signer = types.HomesteadSigner{} + if chainID != nil { + signer = types.NewEIP155Signer(chainID.bigint) + } + from, err := types.Sender(signer, tx.tx) + return &Address{from}, err +} + +func (tx *Transaction) GetTo() *Address { + if to := tx.tx.To(); to != nil { + return &Address{*to} + } + return nil +} + +func (tx *Transaction) WithSignature(sig []byte, chainID *BigInt) (signedTx *Transaction, _ error) { + var signer types.Signer = types.HomesteadSigner{} + if chainID != nil { + signer = types.NewEIP155Signer(chainID.bigint) + } + rawTx, err := tx.tx.WithSignature(signer, common.CopyBytes(sig)) + return &Transaction{rawTx}, err +} + +// Transactions represents a slice of transactions. +type Transactions struct{ txs types.Transactions } + +// Size returns the number of transactions in the slice. +func (txs *Transactions) Size() int { + return len(txs.txs) +} + +// Get returns the transaction at the given index from the slice. +func (txs *Transactions) Get(index int) (tx *Transaction, _ error) { + if index < 0 || index >= len(txs.txs) { + return nil, errors.New("index out of bounds") + } + return &Transaction{txs.txs[index]}, nil +} + +// Receipt represents the results of a transaction. +type Receipt struct { + receipt *types.Receipt +} + +// NewReceiptFromRLP parses a transaction receipt from an RLP data dump. +func NewReceiptFromRLP(data []byte) (*Receipt, error) { + r := &Receipt{ + receipt: new(types.Receipt), + } + if err := rlp.DecodeBytes(common.CopyBytes(data), r.receipt); err != nil { + return nil, err + } + return r, nil +} + +// EncodeRLP encodes a transaction receipt into an RLP data dump. +func (r *Receipt) EncodeRLP() ([]byte, error) { + return rlp.EncodeToBytes(r.receipt) +} + +// NewReceiptFromJSON parses a transaction receipt from a JSON data dump. +func NewReceiptFromJSON(data string) (*Receipt, error) { + r := &Receipt{ + receipt: new(types.Receipt), + } + if err := json.Unmarshal([]byte(data), r.receipt); err != nil { + return nil, err + } + return r, nil +} + +// EncodeJSON encodes a transaction receipt into a JSON data dump. +func (r *Receipt) EncodeJSON() (string, error) { + data, err := rlp.EncodeToBytes(r.receipt) + return string(data), err +} + +func (r *Receipt) GetStatus() int { return int(r.receipt.Status) } +func (r *Receipt) GetPostState() []byte { return r.receipt.PostState } +func (r *Receipt) GetCumulativeGasUsed() int64 { return int64(r.receipt.CumulativeGasUsed) } +func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} } +func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} } +func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} } +func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} } +func (r *Receipt) GetGasUsed() int64 { return int64(r.receipt.GasUsed) } + +// Info represents a diagnostic information about the whisper node. +type Info struct { + info *whisper.Info +} + +// NewMessage represents a new whisper message that is posted through the RPC. +type NewMessage struct { + newMessage *whisper.NewMessage +} + +func NewNewMessage() *NewMessage { + nm := &NewMessage{ + newMessage: new(whisper.NewMessage), + } + return nm +} + +func (nm *NewMessage) GetSymKeyID() string { return nm.newMessage.SymKeyID } +func (nm *NewMessage) SetSymKeyID(symKeyID string) { nm.newMessage.SymKeyID = symKeyID } +func (nm *NewMessage) GetPublicKey() []byte { return nm.newMessage.PublicKey } +func (nm *NewMessage) SetPublicKey(publicKey []byte) { + nm.newMessage.PublicKey = common.CopyBytes(publicKey) +} +func (nm *NewMessage) GetSig() string { return nm.newMessage.Sig } +func (nm *NewMessage) SetSig(sig string) { nm.newMessage.Sig = sig } +func (nm *NewMessage) GetTTL() int64 { return int64(nm.newMessage.TTL) } +func (nm *NewMessage) SetTTL(ttl int64) { nm.newMessage.TTL = uint32(ttl) } +func (nm *NewMessage) GetPayload() []byte { return nm.newMessage.Payload } +func (nm *NewMessage) SetPayload(payload []byte) { nm.newMessage.Payload = common.CopyBytes(payload) } +func (nm *NewMessage) GetPowTime() int64 { return int64(nm.newMessage.PowTime) } +func (nm *NewMessage) SetPowTime(powTime int64) { nm.newMessage.PowTime = uint32(powTime) } +func (nm *NewMessage) GetPowTarget() float64 { return nm.newMessage.PowTarget } +func (nm *NewMessage) SetPowTarget(powTarget float64) { nm.newMessage.PowTarget = powTarget } +func (nm *NewMessage) GetTargetPeer() string { return nm.newMessage.TargetPeer } +func (nm *NewMessage) SetTargetPeer(targetPeer string) { nm.newMessage.TargetPeer = targetPeer } +func (nm *NewMessage) GetTopic() []byte { return nm.newMessage.Topic[:] } +func (nm *NewMessage) SetTopic(topic []byte) { nm.newMessage.Topic = whisper.BytesToTopic(topic) } + +// Message represents a whisper message. +type Message struct { + message *whisper.Message +} + +func (m *Message) GetSig() []byte { return m.message.Sig } +func (m *Message) GetTTL() int64 { return int64(m.message.TTL) } +func (m *Message) GetTimestamp() int64 { return int64(m.message.Timestamp) } +func (m *Message) GetPayload() []byte { return m.message.Payload } +func (m *Message) GetPoW() float64 { return m.message.PoW } +func (m *Message) GetHash() []byte { return m.message.Hash } +func (m *Message) GetDst() []byte { return m.message.Dst } + +// Messages represents an array of messages. +type Messages struct { + messages []*whisper.Message +} + +// Size returns the number of messages in the slice. +func (m *Messages) Size() int { + return len(m.messages) +} + +// Get returns the message at the given index from the slice. +func (m *Messages) Get(index int) (message *Message, _ error) { + if index < 0 || index >= len(m.messages) { + return nil, errors.New("index out of bounds") + } + return &Message{m.messages[index]}, nil +} + +// Criteria holds various filter options for inbound messages. +type Criteria struct { + criteria *whisper.Criteria +} + +func NewCriteria(topic []byte) *Criteria { + c := &Criteria{ + criteria: new(whisper.Criteria), + } + encodedTopic := whisper.BytesToTopic(topic) + c.criteria.Topics = []whisper.TopicType{encodedTopic} + return c +} + +func (c *Criteria) GetSymKeyID() string { return c.criteria.SymKeyID } +func (c *Criteria) SetSymKeyID(symKeyID string) { c.criteria.SymKeyID = symKeyID } +func (c *Criteria) GetPrivateKeyID() string { return c.criteria.PrivateKeyID } +func (c *Criteria) SetPrivateKeyID(privateKeyID string) { c.criteria.PrivateKeyID = privateKeyID } +func (c *Criteria) GetSig() []byte { return c.criteria.Sig } +func (c *Criteria) SetSig(sig []byte) { c.criteria.Sig = common.CopyBytes(sig) } +func (c *Criteria) GetMinPow() float64 { return c.criteria.MinPow } +func (c *Criteria) SetMinPow(pow float64) { c.criteria.MinPow = pow } diff --git a/vendor/github.com/ethereum/go-ethereum/node/api.go b/vendor/github.com/ethereum/go-ethereum/node/api.go new file mode 100644 index 00000000..66cd1dde --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/node/api.go @@ -0,0 +1,317 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package node + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rpc" +) + +// PrivateAdminAPI is the collection of administrative API methods exposed only +// over a secure RPC channel. +type PrivateAdminAPI struct { + node *Node // Node interfaced by this API +} + +// NewPrivateAdminAPI creates a new API definition for the private admin methods +// of the node itself. +func NewPrivateAdminAPI(node *Node) *PrivateAdminAPI { + return &PrivateAdminAPI{node: node} +} + +// AddPeer requests connecting to a remote node, and also maintaining the new +// connection at all times, even reconnecting if it is lost. +func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + // Try to add the url as a static peer and return + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return false, fmt.Errorf("invalid enode: %v", err) + } + server.AddPeer(node) + return true, nil +} + +// RemovePeer disconnects from a remote node if the connection exists +func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + // Try to remove the url as a static peer and return + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return false, fmt.Errorf("invalid enode: %v", err) + } + server.RemovePeer(node) + return true, nil +} + +// AddTrustedPeer allows a remote node to always connect, even if slots are full +func (api *PrivateAdminAPI) AddTrustedPeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return false, fmt.Errorf("invalid enode: %v", err) + } + server.AddTrustedPeer(node) + return true, nil +} + +// RemoveTrustedPeer removes a remote node from the trusted peer set, but it +// does not disconnect it automatically. +func (api *PrivateAdminAPI) RemoveTrustedPeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return false, fmt.Errorf("invalid enode: %v", err) + } + server.RemoveTrustedPeer(node) + return true, nil +} + +// PeerEvents creates an RPC subscription which receives peer events from the +// node's p2p.Server +func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return nil, ErrNodeStopped + } + + // Create the subscription + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + rpcSub := notifier.CreateSubscription() + + go func() { + events := make(chan *p2p.PeerEvent) + sub := server.SubscribeEvents(events) + defer sub.Unsubscribe() + + for { + select { + case event := <-events: + notifier.Notify(rpcSub.ID, event) + case <-sub.Err(): + return + case <-rpcSub.Err(): + return + case <-notifier.Closed(): + return + } + } + }() + + return rpcSub, nil +} + +// StartRPC starts the HTTP RPC API server. +func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis *string, vhosts *string) (bool, error) { + api.node.lock.Lock() + defer api.node.lock.Unlock() + + if api.node.httpHandler != nil { + return false, fmt.Errorf("HTTP RPC already running on %s", api.node.httpEndpoint) + } + + if host == nil { + h := DefaultHTTPHost + if api.node.config.HTTPHost != "" { + h = api.node.config.HTTPHost + } + host = &h + } + if port == nil { + port = &api.node.config.HTTPPort + } + + allowedOrigins := api.node.config.HTTPCors + if cors != nil { + allowedOrigins = nil + for _, origin := range strings.Split(*cors, ",") { + allowedOrigins = append(allowedOrigins, strings.TrimSpace(origin)) + } + } + + allowedVHosts := api.node.config.HTTPVirtualHosts + if vhosts != nil { + allowedVHosts = nil + for _, vhost := range strings.Split(*host, ",") { + allowedVHosts = append(allowedVHosts, strings.TrimSpace(vhost)) + } + } + + modules := api.node.httpWhitelist + if apis != nil { + modules = nil + for _, m := range strings.Split(*apis, ",") { + modules = append(modules, strings.TrimSpace(m)) + } + } + + if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, allowedOrigins, allowedVHosts, api.node.config.HTTPTimeouts); err != nil { + return false, err + } + return true, nil +} + +// StopRPC terminates an already running HTTP RPC API endpoint. +func (api *PrivateAdminAPI) StopRPC() (bool, error) { + api.node.lock.Lock() + defer api.node.lock.Unlock() + + if api.node.httpHandler == nil { + return false, fmt.Errorf("HTTP RPC not running") + } + api.node.stopHTTP() + return true, nil +} + +// StartWS starts the websocket RPC API server. +func (api *PrivateAdminAPI) StartWS(host *string, port *int, allowedOrigins *string, apis *string) (bool, error) { + api.node.lock.Lock() + defer api.node.lock.Unlock() + + if api.node.wsHandler != nil { + return false, fmt.Errorf("WebSocket RPC already running on %s", api.node.wsEndpoint) + } + + if host == nil { + h := DefaultWSHost + if api.node.config.WSHost != "" { + h = api.node.config.WSHost + } + host = &h + } + if port == nil { + port = &api.node.config.WSPort + } + + origins := api.node.config.WSOrigins + if allowedOrigins != nil { + origins = nil + for _, origin := range strings.Split(*allowedOrigins, ",") { + origins = append(origins, strings.TrimSpace(origin)) + } + } + + modules := api.node.config.WSModules + if apis != nil { + modules = nil + for _, m := range strings.Split(*apis, ",") { + modules = append(modules, strings.TrimSpace(m)) + } + } + + if err := api.node.startWS(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, origins, api.node.config.WSExposeAll); err != nil { + return false, err + } + return true, nil +} + +// StopWS terminates an already running websocket RPC API endpoint. +func (api *PrivateAdminAPI) StopWS() (bool, error) { + api.node.lock.Lock() + defer api.node.lock.Unlock() + + if api.node.wsHandler == nil { + return false, fmt.Errorf("WebSocket RPC not running") + } + api.node.stopWS() + return true, nil +} + +// PublicAdminAPI is the collection of administrative API methods exposed over +// both secure and unsecure RPC channels. +type PublicAdminAPI struct { + node *Node // Node interfaced by this API +} + +// NewPublicAdminAPI creates a new API definition for the public admin methods +// of the node itself. +func NewPublicAdminAPI(node *Node) *PublicAdminAPI { + return &PublicAdminAPI{node: node} +} + +// Peers retrieves all the information we know about each individual peer at the +// protocol granularity. +func (api *PublicAdminAPI) Peers() ([]*p2p.PeerInfo, error) { + server := api.node.Server() + if server == nil { + return nil, ErrNodeStopped + } + return server.PeersInfo(), nil +} + +// NodeInfo retrieves all the information we know about the host node at the +// protocol granularity. +func (api *PublicAdminAPI) NodeInfo() (*p2p.NodeInfo, error) { + server := api.node.Server() + if server == nil { + return nil, ErrNodeStopped + } + return server.NodeInfo(), nil +} + +// Datadir retrieves the current data directory the node is using. +func (api *PublicAdminAPI) Datadir() string { + return api.node.DataDir() +} + +// PublicWeb3API offers helper utils +type PublicWeb3API struct { + stack *Node +} + +// NewPublicWeb3API creates a new Web3Service instance +func NewPublicWeb3API(stack *Node) *PublicWeb3API { + return &PublicWeb3API{stack} +} + +// ClientVersion returns the node name +func (s *PublicWeb3API) ClientVersion() string { + return s.stack.Server().Name +} + +// Sha3 applies the ethereum sha3 implementation on the input. +// It assumes the input is hex encoded. +func (s *PublicWeb3API) Sha3(input hexutil.Bytes) hexutil.Bytes { + return crypto.Keccak256(input) +} diff --git a/vendor/github.com/ethereum/go-ethereum/node/config.go b/vendor/github.com/ethereum/go-ethereum/node/config.go new file mode 100644 index 00000000..1905ac7f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/node/config.go @@ -0,0 +1,545 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package node + +import ( + "crypto/ecdsa" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/external" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/scwallet" + "github.com/ethereum/go-ethereum/accounts/usbwallet" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rpc" +) + +const ( + datadirPrivateKey = "nodekey" // Path within the datadir to the node's private key + datadirDefaultKeyStore = "keystore" // Path within the datadir to the keystore + datadirStaticNodes = "static-nodes.json" // Path within the datadir to the static node list + datadirTrustedNodes = "trusted-nodes.json" // Path within the datadir to the trusted node list + datadirNodeDatabase = "nodes" // Path within the datadir to store the node infos +) + +// Config represents a small collection of configuration values to fine tune the +// P2P network layer of a protocol stack. These values can be further extended by +// all registered services. +type Config struct { + // Name sets the instance name of the node. It must not contain the / character and is + // used in the devp2p node identifier. The instance name of geth is "geth". If no + // value is specified, the basename of the current executable is used. + Name string `toml:"-"` + + // UserIdent, if set, is used as an additional component in the devp2p node identifier. + UserIdent string `toml:",omitempty"` + + // Version should be set to the version number of the program. It is used + // in the devp2p node identifier. + Version string `toml:"-"` + + // DataDir is the file system folder the node should use for any data storage + // requirements. The configured data directory will not be directly shared with + // registered services, instead those can use utility methods to create/access + // databases or flat files. This enables ephemeral nodes which can fully reside + // in memory. + DataDir string + + // Configuration of peer-to-peer networking. + P2P p2p.Config + + // KeyStoreDir is the file system folder that contains private keys. The directory can + // be specified as a relative path, in which case it is resolved relative to the + // current directory. + // + // If KeyStoreDir is empty, the default location is the "keystore" subdirectory of + // DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory + // is created by New and destroyed when the node is stopped. + KeyStoreDir string `toml:",omitempty"` + + // ExternalSigner specifies an external URI for a clef-type signer + ExternalSigner string `toml:"omitempty"` + + // UseLightweightKDF lowers the memory and CPU requirements of the key store + // scrypt KDF at the expense of security. + UseLightweightKDF bool `toml:",omitempty"` + + // InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment. + InsecureUnlockAllowed bool `toml:",omitempty"` + + // NoUSB disables hardware wallet monitoring and connectivity. + NoUSB bool `toml:",omitempty"` + + // SmartCardDaemonPath is the path to the smartcard daemon's socket + SmartCardDaemonPath string `toml:",omitempty"` + + // IPCPath is the requested location to place the IPC endpoint. If the path is + // a simple file name, it is placed inside the data directory (or on the root + // pipe path on Windows), whereas if it's a resolvable path name (absolute or + // relative), then that specific path is enforced. An empty path disables IPC. + IPCPath string `toml:",omitempty"` + + // HTTPHost is the host interface on which to start the HTTP RPC server. If this + // field is empty, no HTTP API endpoint will be started. + HTTPHost string `toml:",omitempty"` + + // HTTPPort is the TCP port number on which to start the HTTP RPC server. The + // default zero value is/ valid and will pick a port number randomly (useful + // for ephemeral nodes). + HTTPPort int `toml:",omitempty"` + + // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting + // clients. Please be aware that CORS is a browser enforced security, it's fully + // useless for custom HTTP clients. + HTTPCors []string `toml:",omitempty"` + + // HTTPVirtualHosts is the list of virtual hostnames which are allowed on incoming requests. + // This is by default {'localhost'}. Using this prevents attacks like + // DNS rebinding, which bypasses SOP by simply masquerading as being within the same + // origin. These attacks do not utilize CORS, since they are not cross-domain. + // By explicitly checking the Host-header, the server will not allow requests + // made against the server with a malicious host domain. + // Requests using ip address directly are not affected + HTTPVirtualHosts []string `toml:",omitempty"` + + // HTTPModules is a list of API modules to expose via the HTTP RPC interface. + // If the module list is empty, all RPC API endpoints designated public will be + // exposed. + HTTPModules []string `toml:",omitempty"` + + // HTTPTimeouts allows for customization of the timeout values used by the HTTP RPC + // interface. + HTTPTimeouts rpc.HTTPTimeouts + + // WSHost is the host interface on which to start the websocket RPC server. If + // this field is empty, no websocket API endpoint will be started. + WSHost string `toml:",omitempty"` + + // WSPort is the TCP port number on which to start the websocket RPC server. The + // default zero value is/ valid and will pick a port number randomly (useful for + // ephemeral nodes). + WSPort int `toml:",omitempty"` + + // WSOrigins is the list of domain to accept websocket requests from. Please be + // aware that the server can only act upon the HTTP request the client sends and + // cannot verify the validity of the request header. + WSOrigins []string `toml:",omitempty"` + + // WSModules is a list of API modules to expose via the websocket RPC interface. + // If the module list is empty, all RPC API endpoints designated public will be + // exposed. + WSModules []string `toml:",omitempty"` + + // WSExposeAll exposes all API modules via the WebSocket RPC interface rather + // than just the public ones. + // + // *WARNING* Only set this if the node is running in a trusted network, exposing + // private APIs to untrusted users is a major security risk. + WSExposeAll bool `toml:",omitempty"` + + // GraphQLHost is the host interface on which to start the GraphQL server. If this + // field is empty, no GraphQL API endpoint will be started. + GraphQLHost string `toml:",omitempty"` + + // GraphQLPort is the TCP port number on which to start the GraphQL server. The + // default zero value is/ valid and will pick a port number randomly (useful + // for ephemeral nodes). + GraphQLPort int `toml:",omitempty"` + + // GraphQLCors is the Cross-Origin Resource Sharing header to send to requesting + // clients. Please be aware that CORS is a browser enforced security, it's fully + // useless for custom HTTP clients. + GraphQLCors []string `toml:",omitempty"` + + // GraphQLVirtualHosts is the list of virtual hostnames which are allowed on incoming requests. + // This is by default {'localhost'}. Using this prevents attacks like + // DNS rebinding, which bypasses SOP by simply masquerading as being within the same + // origin. These attacks do not utilize CORS, since they are not cross-domain. + // By explicitly checking the Host-header, the server will not allow requests + // made against the server with a malicious host domain. + // Requests using ip address directly are not affected + GraphQLVirtualHosts []string `toml:",omitempty"` + + // Logger is a custom logger to use with the p2p.Server. + Logger log.Logger `toml:",omitempty"` + + staticNodesWarning bool + trustedNodesWarning bool + oldGethResourceWarning bool +} + +// IPCEndpoint resolves an IPC endpoint based on a configured value, taking into +// account the set data folders as well as the designated platform we're currently +// running on. +func (c *Config) IPCEndpoint() string { + // Short circuit if IPC has not been enabled + if c.IPCPath == "" { + return "" + } + // On windows we can only use plain top-level pipes + if runtime.GOOS == "windows" { + if strings.HasPrefix(c.IPCPath, `\\.\pipe\`) { + return c.IPCPath + } + return `\\.\pipe\` + c.IPCPath + } + // Resolve names into the data directory full paths otherwise + if filepath.Base(c.IPCPath) == c.IPCPath { + if c.DataDir == "" { + return filepath.Join(os.TempDir(), c.IPCPath) + } + return filepath.Join(c.DataDir, c.IPCPath) + } + return c.IPCPath +} + +// NodeDB returns the path to the discovery node database. +func (c *Config) NodeDB() string { + if c.DataDir == "" { + return "" // ephemeral + } + return c.ResolvePath(datadirNodeDatabase) +} + +// DefaultIPCEndpoint returns the IPC path used by default. +func DefaultIPCEndpoint(clientIdentifier string) string { + if clientIdentifier == "" { + clientIdentifier = strings.TrimSuffix(filepath.Base(os.Args[0]), ".exe") + if clientIdentifier == "" { + panic("empty executable name") + } + } + config := &Config{DataDir: DefaultDataDir(), IPCPath: clientIdentifier + ".ipc"} + return config.IPCEndpoint() +} + +// HTTPEndpoint resolves an HTTP endpoint based on the configured host interface +// and port parameters. +func (c *Config) HTTPEndpoint() string { + if c.HTTPHost == "" { + return "" + } + return fmt.Sprintf("%s:%d", c.HTTPHost, c.HTTPPort) +} + +// GraphQLEndpoint resolves a GraphQL endpoint based on the configured host interface +// and port parameters. +func (c *Config) GraphQLEndpoint() string { + if c.GraphQLHost == "" { + return "" + } + return fmt.Sprintf("%s:%d", c.GraphQLHost, c.GraphQLPort) +} + +// DefaultHTTPEndpoint returns the HTTP endpoint used by default. +func DefaultHTTPEndpoint() string { + config := &Config{HTTPHost: DefaultHTTPHost, HTTPPort: DefaultHTTPPort} + return config.HTTPEndpoint() +} + +// WSEndpoint resolves a websocket endpoint based on the configured host interface +// and port parameters. +func (c *Config) WSEndpoint() string { + if c.WSHost == "" { + return "" + } + return fmt.Sprintf("%s:%d", c.WSHost, c.WSPort) +} + +// DefaultWSEndpoint returns the websocket endpoint used by default. +func DefaultWSEndpoint() string { + config := &Config{WSHost: DefaultWSHost, WSPort: DefaultWSPort} + return config.WSEndpoint() +} + +// ExtRPCEnabled returns the indicator whether node enables the external +// RPC(http, ws or graphql). +func (c *Config) ExtRPCEnabled() bool { + return c.HTTPHost != "" || c.WSHost != "" || c.GraphQLHost != "" +} + +// NodeName returns the devp2p node identifier. +func (c *Config) NodeName() string { + name := c.name() + // Backwards compatibility: previous versions used title-cased "Geth", keep that. + if name == "geth" || name == "geth-testnet" { + name = "Geth" + } + if c.UserIdent != "" { + name += "/" + c.UserIdent + } + if c.Version != "" { + name += "/v" + c.Version + } + name += "/" + runtime.GOOS + "-" + runtime.GOARCH + name += "/" + runtime.Version() + return name +} + +func (c *Config) name() string { + if c.Name == "" { + progname := strings.TrimSuffix(filepath.Base(os.Args[0]), ".exe") + if progname == "" { + panic("empty executable name, set Config.Name") + } + return progname + } + return c.Name +} + +// These resources are resolved differently for "geth" instances. +var isOldGethResource = map[string]bool{ + "chaindata": true, + "nodes": true, + "nodekey": true, + "static-nodes.json": false, // no warning for these because they have their + "trusted-nodes.json": false, // own separate warning. +} + +// ResolvePath resolves path in the instance directory. +func (c *Config) ResolvePath(path string) string { + if filepath.IsAbs(path) { + return path + } + if c.DataDir == "" { + return "" + } + // Backwards-compatibility: ensure that data directory files created + // by geth 1.4 are used if they exist. + if warn, isOld := isOldGethResource[path]; isOld { + oldpath := "" + if c.name() == "geth" { + oldpath = filepath.Join(c.DataDir, path) + } + if oldpath != "" && common.FileExist(oldpath) { + if warn { + c.warnOnce(&c.oldGethResourceWarning, "Using deprecated resource file %s, please move this file to the 'geth' subdirectory of datadir.", oldpath) + } + return oldpath + } + } + return filepath.Join(c.instanceDir(), path) +} + +func (c *Config) instanceDir() string { + if c.DataDir == "" { + return "" + } + return filepath.Join(c.DataDir, c.name()) +} + +// NodeKey retrieves the currently configured private key of the node, checking +// first any manually set key, falling back to the one found in the configured +// data folder. If no key can be found, a new one is generated. +func (c *Config) NodeKey() *ecdsa.PrivateKey { + // Use any specifically configured key. + if c.P2P.PrivateKey != nil { + return c.P2P.PrivateKey + } + // Generate ephemeral key if no datadir is being used. + if c.DataDir == "" { + key, err := crypto.GenerateKey() + if err != nil { + log.Crit(fmt.Sprintf("Failed to generate ephemeral node key: %v", err)) + } + return key + } + + keyfile := c.ResolvePath(datadirPrivateKey) + if key, err := crypto.LoadECDSA(keyfile); err == nil { + return key + } + // No persistent key found, generate and store a new one. + key, err := crypto.GenerateKey() + if err != nil { + log.Crit(fmt.Sprintf("Failed to generate node key: %v", err)) + } + instanceDir := filepath.Join(c.DataDir, c.name()) + if err := os.MkdirAll(instanceDir, 0700); err != nil { + log.Error(fmt.Sprintf("Failed to persist node key: %v", err)) + return key + } + keyfile = filepath.Join(instanceDir, datadirPrivateKey) + if err := crypto.SaveECDSA(keyfile, key); err != nil { + log.Error(fmt.Sprintf("Failed to persist node key: %v", err)) + } + return key +} + +// StaticNodes returns a list of node enode URLs configured as static nodes. +func (c *Config) StaticNodes() []*enode.Node { + return c.parsePersistentNodes(&c.staticNodesWarning, c.ResolvePath(datadirStaticNodes)) +} + +// TrustedNodes returns a list of node enode URLs configured as trusted nodes. +func (c *Config) TrustedNodes() []*enode.Node { + return c.parsePersistentNodes(&c.trustedNodesWarning, c.ResolvePath(datadirTrustedNodes)) +} + +// parsePersistentNodes parses a list of discovery node URLs loaded from a .json +// file from within the data directory. +func (c *Config) parsePersistentNodes(w *bool, path string) []*enode.Node { + // Short circuit if no node config is present + if c.DataDir == "" { + return nil + } + if _, err := os.Stat(path); err != nil { + return nil + } + c.warnOnce(w, "Found deprecated node list file %s, please use the TOML config file instead.", path) + + // Load the nodes from the config file. + var nodelist []string + if err := common.LoadJSON(path, &nodelist); err != nil { + log.Error(fmt.Sprintf("Can't load node list file: %v", err)) + return nil + } + // Interpret the list as a discovery node array + var nodes []*enode.Node + for _, url := range nodelist { + if url == "" { + continue + } + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + log.Error(fmt.Sprintf("Node URL %s: %v\n", url, err)) + continue + } + nodes = append(nodes, node) + } + return nodes +} + +// AccountConfig determines the settings for scrypt and keydirectory +func (c *Config) AccountConfig() (int, int, string, error) { + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if c.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } + + var ( + keydir string + err error + ) + switch { + case filepath.IsAbs(c.KeyStoreDir): + keydir = c.KeyStoreDir + case c.DataDir != "": + if c.KeyStoreDir == "" { + keydir = filepath.Join(c.DataDir, datadirDefaultKeyStore) + } else { + keydir, err = filepath.Abs(c.KeyStoreDir) + } + case c.KeyStoreDir != "": + keydir, err = filepath.Abs(c.KeyStoreDir) + } + return scryptN, scryptP, keydir, err +} + +func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { + scryptN, scryptP, keydir, err := conf.AccountConfig() + var ephemeral string + if keydir == "" { + // There is no datadir. + keydir, err = ioutil.TempDir("", "go-ethereum-keystore") + ephemeral = keydir + } + + if err != nil { + return nil, "", err + } + if err := os.MkdirAll(keydir, 0700); err != nil { + return nil, "", err + } + // Assemble the account manager and supported backends + var backends []accounts.Backend + if len(conf.ExternalSigner) > 0 { + log.Info("Using external signer", "url", conf.ExternalSigner) + if extapi, err := external.NewExternalBackend(conf.ExternalSigner); err == nil { + backends = append(backends, extapi) + } else { + return nil, "", fmt.Errorf("error connecting to external signer: %v", err) + } + } + if len(backends) == 0 { + // For now, we're using EITHER external signer OR local signers. + // If/when we implement some form of lockfile for USB and keystore wallets, + // we can have both, but it's very confusing for the user to see the same + // accounts in both externally and locally, plus very racey. + backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP)) + if !conf.NoUSB { + // Start a USB hub for Ledger hardware wallets + if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) + } else { + backends = append(backends, ledgerhub) + } + // Start a USB hub for Trezor hardware wallets (HID version) + if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { + log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + } + // Start a USB hub for Trezor hardware wallets (WebUSB version) + if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { + log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + } + } + if len(conf.SmartCardDaemonPath) > 0 { + // Start a smart card hub + if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + backends = append(backends, schub) + } + } + } + + return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil +} + +var warnLock sync.Mutex + +func (c *Config) warnOnce(w *bool, format string, args ...interface{}) { + warnLock.Lock() + defer warnLock.Unlock() + + if *w { + return + } + l := c.Logger + if l == nil { + l = log.Root() + } + l.Warn(fmt.Sprintf(format, args...)) + *w = true +} diff --git a/vendor/github.com/ethereum/go-ethereum/node/defaults.go b/vendor/github.com/ethereum/go-ethereum/node/defaults.go new file mode 100644 index 00000000..564bb35b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/node/defaults.go @@ -0,0 +1,111 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package node + +import ( + "os" + "os/user" + "path/filepath" + "runtime" + + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/rpc" +) + +const ( + DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server + DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server + DefaultWSHost = "localhost" // Default host interface for the websocket RPC server + DefaultWSPort = 8546 // Default TCP port for the websocket RPC server + DefaultGraphQLHost = "localhost" // Default host interface for the GraphQL server + DefaultGraphQLPort = 8547 // Default TCP port for the GraphQL server +) + +// DefaultConfig contains reasonable default settings. +var DefaultConfig = Config{ + DataDir: DefaultDataDir(), + HTTPPort: DefaultHTTPPort, + HTTPModules: []string{"net", "web3"}, + HTTPVirtualHosts: []string{"localhost"}, + HTTPTimeouts: rpc.DefaultHTTPTimeouts, + WSPort: DefaultWSPort, + WSModules: []string{"net", "web3"}, + P2P: p2p.Config{ + ListenAddr: ":30303", + MaxPeers: 50, + NAT: nat.Any(), + }, +} + +// DefaultDataDir is the default data directory to use for the databases and other +// persistence requirements. +func DefaultDataDir() string { + // Try to place the data folder in the user's home dir + home := homeDir() + if home != "" { + switch runtime.GOOS { + case "darwin": + return filepath.Join(home, "Library", "Ethereum") + case "windows": + // We used to put everything in %HOME%\AppData\Roaming, but this caused + // problems with non-typical setups. If this fallback location exists and + // is non-empty, use it, otherwise DTRT and check %LOCALAPPDATA%. + fallback := filepath.Join(home, "AppData", "Roaming", "Ethereum") + appdata := windowsAppData() + if appdata == "" || isNonEmptyDir(fallback) { + return fallback + } + return filepath.Join(appdata, "Ethereum") + default: + return filepath.Join(home, ".ethereum") + } + } + // As we cannot guess a stable location, return empty and handle later + return "" +} + +func windowsAppData() string { + v := os.Getenv("LOCALAPPDATA") + if v == "" { + // Windows XP and below don't have LocalAppData. Crash here because + // we don't support Windows XP and undefining the variable will cause + // other issues. + panic("environment variable LocalAppData is undefined") + } + return v +} + +func isNonEmptyDir(dir string) bool { + f, err := os.Open(dir) + if err != nil { + return false + } + names, _ := f.Readdir(1) + f.Close() + return len(names) > 0 +} + +func homeDir() string { + if home := os.Getenv("HOME"); home != "" { + return home + } + if usr, err := user.Current(); err == nil { + return usr.HomeDir + } + return "" +} diff --git a/vendor/github.com/ethereum/go-ethereum/node/node.go b/vendor/github.com/ethereum/go-ethereum/node/node.go new file mode 100644 index 00000000..08daeeee --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/node/node.go @@ -0,0 +1,665 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package node + +import ( + "errors" + "fmt" + "net" + "os" + "path/filepath" + "reflect" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/debug" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" + "github.com/prometheus/tsdb/fileutil" +) + +// Node is a container on which services can be registered. +type Node struct { + eventmux *event.TypeMux // Event multiplexer used between the services of a stack + config *Config + accman *accounts.Manager + + ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop + instanceDirLock fileutil.Releaser // prevents concurrent use of instance directory + + serverConfig p2p.Config + server *p2p.Server // Currently running P2P networking layer + + serviceFuncs []ServiceConstructor // Service constructors (in dependency order) + services map[reflect.Type]Service // Currently running services + + rpcAPIs []rpc.API // List of APIs currently provided by the node + inprocHandler *rpc.Server // In-process RPC request handler to process the API requests + + ipcEndpoint string // IPC endpoint to listen at (empty = IPC disabled) + ipcListener net.Listener // IPC RPC listener socket to serve API requests + ipcHandler *rpc.Server // IPC RPC request handler to process the API requests + + httpEndpoint string // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled) + httpWhitelist []string // HTTP RPC modules to allow through this endpoint + httpListener net.Listener // HTTP RPC listener socket to server API requests + httpHandler *rpc.Server // HTTP RPC request handler to process the API requests + + wsEndpoint string // Websocket endpoint (interface + port) to listen at (empty = websocket disabled) + wsListener net.Listener // Websocket RPC listener socket to server API requests + wsHandler *rpc.Server // Websocket RPC request handler to process the API requests + + stop chan struct{} // Channel to wait for termination notifications + lock sync.RWMutex + + log log.Logger +} + +// New creates a new P2P node, ready for protocol registration. +func New(conf *Config) (*Node, error) { + // Copy config and resolve the datadir so future changes to the current + // working directory don't affect the node. + confCopy := *conf + conf = &confCopy + if conf.DataDir != "" { + absdatadir, err := filepath.Abs(conf.DataDir) + if err != nil { + return nil, err + } + conf.DataDir = absdatadir + } + // Ensure that the instance name doesn't cause weird conflicts with + // other files in the data directory. + if strings.ContainsAny(conf.Name, `/\`) { + return nil, errors.New(`Config.Name must not contain '/' or '\'`) + } + if conf.Name == datadirDefaultKeyStore { + return nil, errors.New(`Config.Name cannot be "` + datadirDefaultKeyStore + `"`) + } + if strings.HasSuffix(conf.Name, ".ipc") { + return nil, errors.New(`Config.Name cannot end in ".ipc"`) + } + // Ensure that the AccountManager method works before the node has started. + // We rely on this in cmd/geth. + am, ephemeralKeystore, err := makeAccountManager(conf) + if err != nil { + return nil, err + } + if conf.Logger == nil { + conf.Logger = log.New() + } + // Note: any interaction with Config that would create/touch files + // in the data directory or instance directory is delayed until Start. + return &Node{ + accman: am, + ephemeralKeystore: ephemeralKeystore, + config: conf, + serviceFuncs: []ServiceConstructor{}, + ipcEndpoint: conf.IPCEndpoint(), + httpEndpoint: conf.HTTPEndpoint(), + wsEndpoint: conf.WSEndpoint(), + eventmux: new(event.TypeMux), + log: conf.Logger, + }, nil +} + +// Close stops the Node and releases resources acquired in +// Node constructor New. +func (n *Node) Close() error { + var errs []error + + // Terminate all subsystems and collect any errors + if err := n.Stop(); err != nil && err != ErrNodeStopped { + errs = append(errs, err) + } + if err := n.accman.Close(); err != nil { + errs = append(errs, err) + } + // Report any errors that might have occurred + switch len(errs) { + case 0: + return nil + case 1: + return errs[0] + default: + return fmt.Errorf("%v", errs) + } +} + +// Register injects a new service into the node's stack. The service created by +// the passed constructor must be unique in its type with regard to sibling ones. +func (n *Node) Register(constructor ServiceConstructor) error { + n.lock.Lock() + defer n.lock.Unlock() + + if n.server != nil { + return ErrNodeRunning + } + n.serviceFuncs = append(n.serviceFuncs, constructor) + return nil +} + +// Start create a live P2P node and starts running it. +func (n *Node) Start() error { + n.lock.Lock() + defer n.lock.Unlock() + + // Short circuit if the node's already running + if n.server != nil { + return ErrNodeRunning + } + if err := n.openDataDir(); err != nil { + return err + } + + // Initialize the p2p server. This creates the node key and + // discovery databases. + n.serverConfig = n.config.P2P + n.serverConfig.PrivateKey = n.config.NodeKey() + n.serverConfig.Name = n.config.NodeName() + n.serverConfig.Logger = n.log + if n.serverConfig.StaticNodes == nil { + n.serverConfig.StaticNodes = n.config.StaticNodes() + } + if n.serverConfig.TrustedNodes == nil { + n.serverConfig.TrustedNodes = n.config.TrustedNodes() + } + if n.serverConfig.NodeDatabase == "" { + n.serverConfig.NodeDatabase = n.config.NodeDB() + } + running := &p2p.Server{Config: n.serverConfig} + n.log.Info("Starting peer-to-peer node", "instance", n.serverConfig.Name) + + // Otherwise copy and specialize the P2P configuration + services := make(map[reflect.Type]Service) + for _, constructor := range n.serviceFuncs { + // Create a new context for the particular service + ctx := &ServiceContext{ + config: n.config, + services: make(map[reflect.Type]Service), + EventMux: n.eventmux, + AccountManager: n.accman, + } + for kind, s := range services { // copy needed for threaded access + ctx.services[kind] = s + } + // Construct and save the service + service, err := constructor(ctx) + if err != nil { + return err + } + kind := reflect.TypeOf(service) + if _, exists := services[kind]; exists { + return &DuplicateServiceError{Kind: kind} + } + services[kind] = service + } + // Gather the protocols and start the freshly assembled P2P server + for _, service := range services { + running.Protocols = append(running.Protocols, service.Protocols()...) + } + if err := running.Start(); err != nil { + return convertFileLockError(err) + } + // Start each of the services + var started []reflect.Type + for kind, service := range services { + // Start the next service, stopping all previous upon failure + if err := service.Start(running); err != nil { + for _, kind := range started { + services[kind].Stop() + } + running.Stop() + + return err + } + // Mark the service started for potential cleanup + started = append(started, kind) + } + // Lastly start the configured RPC interfaces + if err := n.startRPC(services); err != nil { + for _, service := range services { + service.Stop() + } + running.Stop() + return err + } + // Finish initializing the startup + n.services = services + n.server = running + n.stop = make(chan struct{}) + + return nil +} + +// Config returns the configuration of node. +func (n *Node) Config() *Config { + return n.config +} + +func (n *Node) openDataDir() error { + if n.config.DataDir == "" { + return nil // ephemeral + } + + instdir := filepath.Join(n.config.DataDir, n.config.name()) + if err := os.MkdirAll(instdir, 0700); err != nil { + return err + } + // Lock the instance directory to prevent concurrent use by another instance as well as + // accidental use of the instance directory as a database. + release, _, err := fileutil.Flock(filepath.Join(instdir, "LOCK")) + if err != nil { + return convertFileLockError(err) + } + n.instanceDirLock = release + return nil +} + +// startRPC is a helper method to start all the various RPC endpoint during node +// startup. It's not meant to be called at any time afterwards as it makes certain +// assumptions about the state of the node. +func (n *Node) startRPC(services map[reflect.Type]Service) error { + // Gather all the possible APIs to surface + apis := n.apis() + for _, service := range services { + apis = append(apis, service.APIs()...) + } + // Start the various API endpoints, terminating all in case of errors + if err := n.startInProc(apis); err != nil { + return err + } + if err := n.startIPC(apis); err != nil { + n.stopInProc() + return err + } + if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors, n.config.HTTPVirtualHosts, n.config.HTTPTimeouts); err != nil { + n.stopIPC() + n.stopInProc() + return err + } + if err := n.startWS(n.wsEndpoint, apis, n.config.WSModules, n.config.WSOrigins, n.config.WSExposeAll); err != nil { + n.stopHTTP() + n.stopIPC() + n.stopInProc() + return err + } + // All API endpoints started successfully + n.rpcAPIs = apis + return nil +} + +// startInProc initializes an in-process RPC endpoint. +func (n *Node) startInProc(apis []rpc.API) error { + // Register all the APIs exposed by the services + handler := rpc.NewServer() + for _, api := range apis { + if err := handler.RegisterName(api.Namespace, api.Service); err != nil { + return err + } + n.log.Debug("InProc registered", "namespace", api.Namespace) + } + n.inprocHandler = handler + return nil +} + +// stopInProc terminates the in-process RPC endpoint. +func (n *Node) stopInProc() { + if n.inprocHandler != nil { + n.inprocHandler.Stop() + n.inprocHandler = nil + } +} + +// startIPC initializes and starts the IPC RPC endpoint. +func (n *Node) startIPC(apis []rpc.API) error { + if n.ipcEndpoint == "" { + return nil // IPC disabled. + } + listener, handler, err := rpc.StartIPCEndpoint(n.ipcEndpoint, apis) + if err != nil { + return err + } + n.ipcListener = listener + n.ipcHandler = handler + n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint) + return nil +} + +// stopIPC terminates the IPC RPC endpoint. +func (n *Node) stopIPC() { + if n.ipcListener != nil { + n.ipcListener.Close() + n.ipcListener = nil + + n.log.Info("IPC endpoint closed", "url", n.ipcEndpoint) + } + if n.ipcHandler != nil { + n.ipcHandler.Stop() + n.ipcHandler = nil + } +} + +// startHTTP initializes and starts the HTTP RPC endpoint. +func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) error { + // Short circuit if the HTTP endpoint isn't being exposed + if endpoint == "" { + return nil + } + listener, handler, err := rpc.StartHTTPEndpoint(endpoint, apis, modules, cors, vhosts, timeouts) + if err != nil { + return err + } + n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%s", endpoint), "cors", strings.Join(cors, ","), "vhosts", strings.Join(vhosts, ",")) + // All listeners booted successfully + n.httpEndpoint = endpoint + n.httpListener = listener + n.httpHandler = handler + + return nil +} + +// stopHTTP terminates the HTTP RPC endpoint. +func (n *Node) stopHTTP() { + if n.httpListener != nil { + n.httpListener.Close() + n.httpListener = nil + + n.log.Info("HTTP endpoint closed", "url", fmt.Sprintf("http://%s", n.httpEndpoint)) + } + if n.httpHandler != nil { + n.httpHandler.Stop() + n.httpHandler = nil + } +} + +// startWS initializes and starts the websocket RPC endpoint. +func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrigins []string, exposeAll bool) error { + // Short circuit if the WS endpoint isn't being exposed + if endpoint == "" { + return nil + } + listener, handler, err := rpc.StartWSEndpoint(endpoint, apis, modules, wsOrigins, exposeAll) + if err != nil { + return err + } + n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%s", listener.Addr())) + // All listeners booted successfully + n.wsEndpoint = endpoint + n.wsListener = listener + n.wsHandler = handler + + return nil +} + +// stopWS terminates the websocket RPC endpoint. +func (n *Node) stopWS() { + if n.wsListener != nil { + n.wsListener.Close() + n.wsListener = nil + + n.log.Info("WebSocket endpoint closed", "url", fmt.Sprintf("ws://%s", n.wsEndpoint)) + } + if n.wsHandler != nil { + n.wsHandler.Stop() + n.wsHandler = nil + } +} + +// Stop terminates a running node along with all it's services. In the node was +// not started, an error is returned. +func (n *Node) Stop() error { + n.lock.Lock() + defer n.lock.Unlock() + + // Short circuit if the node's not running + if n.server == nil { + return ErrNodeStopped + } + + // Terminate the API, services and the p2p server. + n.stopWS() + n.stopHTTP() + n.stopIPC() + n.rpcAPIs = nil + failure := &StopError{ + Services: make(map[reflect.Type]error), + } + for kind, service := range n.services { + if err := service.Stop(); err != nil { + failure.Services[kind] = err + } + } + n.server.Stop() + n.services = nil + n.server = nil + + // Release instance directory lock. + if n.instanceDirLock != nil { + if err := n.instanceDirLock.Release(); err != nil { + n.log.Error("Can't release datadir lock", "err", err) + } + n.instanceDirLock = nil + } + + // unblock n.Wait + close(n.stop) + + // Remove the keystore if it was created ephemerally. + var keystoreErr error + if n.ephemeralKeystore != "" { + keystoreErr = os.RemoveAll(n.ephemeralKeystore) + } + + if len(failure.Services) > 0 { + return failure + } + if keystoreErr != nil { + return keystoreErr + } + return nil +} + +// Wait blocks the thread until the node is stopped. If the node is not running +// at the time of invocation, the method immediately returns. +func (n *Node) Wait() { + n.lock.RLock() + if n.server == nil { + n.lock.RUnlock() + return + } + stop := n.stop + n.lock.RUnlock() + + <-stop +} + +// Restart terminates a running node and boots up a new one in its place. If the +// node isn't running, an error is returned. +func (n *Node) Restart() error { + if err := n.Stop(); err != nil { + return err + } + if err := n.Start(); err != nil { + return err + } + return nil +} + +// Attach creates an RPC client attached to an in-process API handler. +func (n *Node) Attach() (*rpc.Client, error) { + n.lock.RLock() + defer n.lock.RUnlock() + + if n.server == nil { + return nil, ErrNodeStopped + } + return rpc.DialInProc(n.inprocHandler), nil +} + +// RPCHandler returns the in-process RPC request handler. +func (n *Node) RPCHandler() (*rpc.Server, error) { + n.lock.RLock() + defer n.lock.RUnlock() + + if n.inprocHandler == nil { + return nil, ErrNodeStopped + } + return n.inprocHandler, nil +} + +// Server retrieves the currently running P2P network layer. This method is meant +// only to inspect fields of the currently running server, life cycle management +// should be left to this Node entity. +func (n *Node) Server() *p2p.Server { + n.lock.RLock() + defer n.lock.RUnlock() + + return n.server +} + +// Service retrieves a currently running service registered of a specific type. +func (n *Node) Service(service interface{}) error { + n.lock.RLock() + defer n.lock.RUnlock() + + // Short circuit if the node's not running + if n.server == nil { + return ErrNodeStopped + } + // Otherwise try to find the service to return + element := reflect.ValueOf(service).Elem() + if running, ok := n.services[element.Type()]; ok { + element.Set(reflect.ValueOf(running)) + return nil + } + return ErrServiceUnknown +} + +// DataDir retrieves the current datadir used by the protocol stack. +// Deprecated: No files should be stored in this directory, use InstanceDir instead. +func (n *Node) DataDir() string { + return n.config.DataDir +} + +// InstanceDir retrieves the instance directory used by the protocol stack. +func (n *Node) InstanceDir() string { + return n.config.instanceDir() +} + +// AccountManager retrieves the account manager used by the protocol stack. +func (n *Node) AccountManager() *accounts.Manager { + return n.accman +} + +// IPCEndpoint retrieves the current IPC endpoint used by the protocol stack. +func (n *Node) IPCEndpoint() string { + return n.ipcEndpoint +} + +// HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack. +func (n *Node) HTTPEndpoint() string { + n.lock.Lock() + defer n.lock.Unlock() + + if n.httpListener != nil { + return n.httpListener.Addr().String() + } + return n.httpEndpoint +} + +// WSEndpoint retrieves the current WS endpoint used by the protocol stack. +func (n *Node) WSEndpoint() string { + n.lock.Lock() + defer n.lock.Unlock() + + if n.wsListener != nil { + return n.wsListener.Addr().String() + } + return n.wsEndpoint +} + +// EventMux retrieves the event multiplexer used by all the network services in +// the current protocol stack. +func (n *Node) EventMux() *event.TypeMux { + return n.eventmux +} + +// OpenDatabase opens an existing database with the given name (or creates one if no +// previous can be found) from within the node's instance directory. If the node is +// ephemeral, a memory database is returned. +func (n *Node) OpenDatabase(name string, cache, handles int, namespace string) (ethdb.Database, error) { + if n.config.DataDir == "" { + return rawdb.NewMemoryDatabase(), nil + } + return rawdb.NewLevelDBDatabase(n.config.ResolvePath(name), cache, handles, namespace) +} + +// OpenDatabaseWithFreezer opens an existing database with the given name (or +// creates one if no previous can be found) from within the node's data directory, +// also attaching a chain freezer to it that moves ancient chain data from the +// database to immutable append-only files. If the node is an ephemeral one, a +// memory database is returned. +func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, namespace string) (ethdb.Database, error) { + if n.config.DataDir == "" { + return rawdb.NewMemoryDatabase(), nil + } + root := n.config.ResolvePath(name) + + switch { + case freezer == "": + freezer = filepath.Join(root, "ancient") + case !filepath.IsAbs(freezer): + freezer = n.config.ResolvePath(freezer) + } + return rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace) +} + +// ResolvePath returns the absolute path of a resource in the instance directory. +func (n *Node) ResolvePath(x string) string { + return n.config.ResolvePath(x) +} + +// apis returns the collection of RPC descriptors this node offers. +func (n *Node) apis() []rpc.API { + return []rpc.API{ + { + Namespace: "admin", + Version: "1.0", + Service: NewPrivateAdminAPI(n), + }, { + Namespace: "admin", + Version: "1.0", + Service: NewPublicAdminAPI(n), + Public: true, + }, { + Namespace: "debug", + Version: "1.0", + Service: debug.Handler, + }, { + Namespace: "web3", + Version: "1.0", + Service: NewPublicWeb3API(n), + Public: true, + }, + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/node/service.go b/vendor/github.com/ethereum/go-ethereum/node/service.go new file mode 100644 index 00000000..4dea0099 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/node/service.go @@ -0,0 +1,122 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package node + +import ( + "path/filepath" + "reflect" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" +) + +// ServiceContext is a collection of service independent options inherited from +// the protocol stack, that is passed to all constructors to be optionally used; +// as well as utility methods to operate on the service environment. +type ServiceContext struct { + config *Config + services map[reflect.Type]Service // Index of the already constructed services + EventMux *event.TypeMux // Event multiplexer used for decoupled notifications + AccountManager *accounts.Manager // Account manager created by the node. +} + +// OpenDatabase opens an existing database with the given name (or creates one +// if no previous can be found) from within the node's data directory. If the +// node is an ephemeral one, a memory database is returned. +func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int, namespace string) (ethdb.Database, error) { + if ctx.config.DataDir == "" { + return rawdb.NewMemoryDatabase(), nil + } + return rawdb.NewLevelDBDatabase(ctx.config.ResolvePath(name), cache, handles, namespace) +} + +// OpenDatabaseWithFreezer opens an existing database with the given name (or +// creates one if no previous can be found) from within the node's data directory, +// also attaching a chain freezer to it that moves ancient chain data from the +// database to immutable append-only files. If the node is an ephemeral one, a +// memory database is returned. +func (ctx *ServiceContext) OpenDatabaseWithFreezer(name string, cache int, handles int, freezer string, namespace string) (ethdb.Database, error) { + if ctx.config.DataDir == "" { + return rawdb.NewMemoryDatabase(), nil + } + root := ctx.config.ResolvePath(name) + + switch { + case freezer == "": + freezer = filepath.Join(root, "ancient") + case !filepath.IsAbs(freezer): + freezer = ctx.config.ResolvePath(freezer) + } + return rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace) +} + +// ResolvePath resolves a user path into the data directory if that was relative +// and if the user actually uses persistent storage. It will return an empty string +// for emphemeral storage and the user's own input for absolute paths. +func (ctx *ServiceContext) ResolvePath(path string) string { + return ctx.config.ResolvePath(path) +} + +// Service retrieves a currently running service registered of a specific type. +func (ctx *ServiceContext) Service(service interface{}) error { + element := reflect.ValueOf(service).Elem() + if running, ok := ctx.services[element.Type()]; ok { + element.Set(reflect.ValueOf(running)) + return nil + } + return ErrServiceUnknown +} + +// ExtRPCEnabled returns the indicator whether node enables the external +// RPC(http, ws or graphql). +func (ctx *ServiceContext) ExtRPCEnabled() bool { + return ctx.config.ExtRPCEnabled() +} + +// ServiceConstructor is the function signature of the constructors needed to be +// registered for service instantiation. +type ServiceConstructor func(ctx *ServiceContext) (Service, error) + +// Service is an individual protocol that can be registered into a node. +// +// Notes: +// +// • Service life-cycle management is delegated to the node. The service is allowed to +// initialize itself upon creation, but no goroutines should be spun up outside of the +// Start method. +// +// • Restart logic is not required as the node will create a fresh instance +// every time a service is started. +type Service interface { + // Protocols retrieves the P2P protocols the service wishes to start. + Protocols() []p2p.Protocol + + // APIs retrieves the list of RPC descriptors the service provides + APIs() []rpc.API + + // Start is called after all services have been constructed and the networking + // layer was also initialized to spawn any goroutines required by the service. + Start(server *p2p.Server) error + + // Stop terminates all goroutines belonging to the service, blocking until they + // are all terminated. + Stop() error +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/dial.go b/vendor/github.com/ethereum/go-ethereum/p2p/dial.go new file mode 100644 index 00000000..8dee5063 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/dial.go @@ -0,0 +1,378 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package p2p + +import ( + "errors" + "fmt" + "net" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +const ( + // This is the amount of time spent waiting in between redialing a certain node. The + // limit is a bit higher than inboundThrottleTime to prevent failing dials in small + // private networks. + dialHistoryExpiration = inboundThrottleTime + 5*time.Second + + // Discovery lookups are throttled and can only run + // once every few seconds. + lookupInterval = 4 * time.Second + + // If no peers are found for this amount of time, the initial bootnodes are + // attempted to be connected. + fallbackInterval = 20 * time.Second + + // Endpoint resolution is throttled with bounded backoff. + initialResolveDelay = 60 * time.Second + maxResolveDelay = time.Hour +) + +// NodeDialer is used to connect to nodes in the network, typically by using +// an underlying net.Dialer but also using net.Pipe in tests +type NodeDialer interface { + Dial(*enode.Node) (net.Conn, error) +} + +// TCPDialer implements the NodeDialer interface by using a net.Dialer to +// create TCP connections to nodes in the network +type TCPDialer struct { + *net.Dialer +} + +// Dial creates a TCP connection to the node +func (t TCPDialer) Dial(dest *enode.Node) (net.Conn, error) { + addr := &net.TCPAddr{IP: dest.IP(), Port: dest.TCP()} + return t.Dialer.Dial("tcp", addr.String()) +} + +// dialstate schedules dials and discovery lookups. +// It gets a chance to compute new tasks on every iteration +// of the main loop in Server.run. +type dialstate struct { + maxDynDials int + ntab discoverTable + netrestrict *netutil.Netlist + self enode.ID + bootnodes []*enode.Node // default dials when there are no peers + log log.Logger + + start time.Time // time when the dialer was first used + lookupRunning bool + dialing map[enode.ID]connFlag + lookupBuf []*enode.Node // current discovery lookup results + randomNodes []*enode.Node // filled from Table + static map[enode.ID]*dialTask + hist expHeap +} + +type discoverTable interface { + Close() + Resolve(*enode.Node) *enode.Node + LookupRandom() []*enode.Node + ReadRandomNodes([]*enode.Node) int +} + +type task interface { + Do(*Server) +} + +// A dialTask is generated for each node that is dialed. Its +// fields cannot be accessed while the task is running. +type dialTask struct { + flags connFlag + dest *enode.Node + lastResolved time.Time + resolveDelay time.Duration +} + +// discoverTask runs discovery table operations. +// Only one discoverTask is active at any time. +// discoverTask.Do performs a random lookup. +type discoverTask struct { + results []*enode.Node +} + +// A waitExpireTask is generated if there are no other tasks +// to keep the loop in Server.run ticking. +type waitExpireTask struct { + time.Duration +} + +func newDialState(self enode.ID, ntab discoverTable, maxdyn int, cfg *Config) *dialstate { + s := &dialstate{ + maxDynDials: maxdyn, + ntab: ntab, + self: self, + netrestrict: cfg.NetRestrict, + log: cfg.Logger, + static: make(map[enode.ID]*dialTask), + dialing: make(map[enode.ID]connFlag), + bootnodes: make([]*enode.Node, len(cfg.BootstrapNodes)), + randomNodes: make([]*enode.Node, maxdyn/2), + } + copy(s.bootnodes, cfg.BootstrapNodes) + if s.log == nil { + s.log = log.Root() + } + for _, n := range cfg.StaticNodes { + s.addStatic(n) + } + return s +} + +func (s *dialstate) addStatic(n *enode.Node) { + // This overwrites the task instead of updating an existing + // entry, giving users the opportunity to force a resolve operation. + s.static[n.ID()] = &dialTask{flags: staticDialedConn, dest: n} +} + +func (s *dialstate) removeStatic(n *enode.Node) { + // This removes a task so future attempts to connect will not be made. + delete(s.static, n.ID()) +} + +func (s *dialstate) newTasks(nRunning int, peers map[enode.ID]*Peer, now time.Time) []task { + if s.start.IsZero() { + s.start = now + } + + var newtasks []task + addDial := func(flag connFlag, n *enode.Node) bool { + if err := s.checkDial(n, peers); err != nil { + s.log.Trace("Skipping dial candidate", "id", n.ID(), "addr", &net.TCPAddr{IP: n.IP(), Port: n.TCP()}, "err", err) + return false + } + s.dialing[n.ID()] = flag + newtasks = append(newtasks, &dialTask{flags: flag, dest: n}) + return true + } + + // Compute number of dynamic dials necessary at this point. + needDynDials := s.maxDynDials + for _, p := range peers { + if p.rw.is(dynDialedConn) { + needDynDials-- + } + } + for _, flag := range s.dialing { + if flag&dynDialedConn != 0 { + needDynDials-- + } + } + + // Expire the dial history on every invocation. + s.hist.expire(now) + + // Create dials for static nodes if they are not connected. + for id, t := range s.static { + err := s.checkDial(t.dest, peers) + switch err { + case errNotWhitelisted, errSelf: + s.log.Warn("Removing static dial candidate", "id", t.dest.ID, "addr", &net.TCPAddr{IP: t.dest.IP(), Port: t.dest.TCP()}, "err", err) + delete(s.static, t.dest.ID()) + case nil: + s.dialing[id] = t.flags + newtasks = append(newtasks, t) + } + } + // If we don't have any peers whatsoever, try to dial a random bootnode. This + // scenario is useful for the testnet (and private networks) where the discovery + // table might be full of mostly bad peers, making it hard to find good ones. + if len(peers) == 0 && len(s.bootnodes) > 0 && needDynDials > 0 && now.Sub(s.start) > fallbackInterval { + bootnode := s.bootnodes[0] + s.bootnodes = append(s.bootnodes[:0], s.bootnodes[1:]...) + s.bootnodes = append(s.bootnodes, bootnode) + + if addDial(dynDialedConn, bootnode) { + needDynDials-- + } + } + // Use random nodes from the table for half of the necessary + // dynamic dials. + randomCandidates := needDynDials / 2 + if randomCandidates > 0 { + n := s.ntab.ReadRandomNodes(s.randomNodes) + for i := 0; i < randomCandidates && i < n; i++ { + if addDial(dynDialedConn, s.randomNodes[i]) { + needDynDials-- + } + } + } + // Create dynamic dials from random lookup results, removing tried + // items from the result buffer. + i := 0 + for ; i < len(s.lookupBuf) && needDynDials > 0; i++ { + if addDial(dynDialedConn, s.lookupBuf[i]) { + needDynDials-- + } + } + s.lookupBuf = s.lookupBuf[:copy(s.lookupBuf, s.lookupBuf[i:])] + // Launch a discovery lookup if more candidates are needed. + if len(s.lookupBuf) < needDynDials && !s.lookupRunning { + s.lookupRunning = true + newtasks = append(newtasks, &discoverTask{}) + } + + // Launch a timer to wait for the next node to expire if all + // candidates have been tried and no task is currently active. + // This should prevent cases where the dialer logic is not ticked + // because there are no pending events. + if nRunning == 0 && len(newtasks) == 0 && s.hist.Len() > 0 { + t := &waitExpireTask{s.hist.nextExpiry().Sub(now)} + newtasks = append(newtasks, t) + } + return newtasks +} + +var ( + errSelf = errors.New("is self") + errAlreadyDialing = errors.New("already dialing") + errAlreadyConnected = errors.New("already connected") + errRecentlyDialed = errors.New("recently dialed") + errNotWhitelisted = errors.New("not contained in netrestrict whitelist") +) + +func (s *dialstate) checkDial(n *enode.Node, peers map[enode.ID]*Peer) error { + _, dialing := s.dialing[n.ID()] + switch { + case dialing: + return errAlreadyDialing + case peers[n.ID()] != nil: + return errAlreadyConnected + case n.ID() == s.self: + return errSelf + case s.netrestrict != nil && !s.netrestrict.Contains(n.IP()): + return errNotWhitelisted + case s.hist.contains(string(n.ID().Bytes())): + return errRecentlyDialed + } + return nil +} + +func (s *dialstate) taskDone(t task, now time.Time) { + switch t := t.(type) { + case *dialTask: + s.hist.add(string(t.dest.ID().Bytes()), now.Add(dialHistoryExpiration)) + delete(s.dialing, t.dest.ID()) + case *discoverTask: + s.lookupRunning = false + s.lookupBuf = append(s.lookupBuf, t.results...) + } +} + +func (t *dialTask) Do(srv *Server) { + if t.dest.Incomplete() { + if !t.resolve(srv) { + return + } + } + err := t.dial(srv, t.dest) + if err != nil { + srv.log.Trace("Dial error", "task", t, "err", err) + // Try resolving the ID of static nodes if dialing failed. + if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 { + if t.resolve(srv) { + t.dial(srv, t.dest) + } + } + } +} + +// resolve attempts to find the current endpoint for the destination +// using discovery. +// +// Resolve operations are throttled with backoff to avoid flooding the +// discovery network with useless queries for nodes that don't exist. +// The backoff delay resets when the node is found. +func (t *dialTask) resolve(srv *Server) bool { + if srv.ntab == nil { + srv.log.Debug("Can't resolve node", "id", t.dest.ID, "err", "discovery is disabled") + return false + } + if t.resolveDelay == 0 { + t.resolveDelay = initialResolveDelay + } + if time.Since(t.lastResolved) < t.resolveDelay { + return false + } + resolved := srv.ntab.Resolve(t.dest) + t.lastResolved = time.Now() + if resolved == nil { + t.resolveDelay *= 2 + if t.resolveDelay > maxResolveDelay { + t.resolveDelay = maxResolveDelay + } + srv.log.Debug("Resolving node failed", "id", t.dest.ID, "newdelay", t.resolveDelay) + return false + } + // The node was found. + t.resolveDelay = initialResolveDelay + t.dest = resolved + srv.log.Debug("Resolved node", "id", t.dest.ID, "addr", &net.TCPAddr{IP: t.dest.IP(), Port: t.dest.TCP()}) + return true +} + +type dialError struct { + error +} + +// dial performs the actual connection attempt. +func (t *dialTask) dial(srv *Server, dest *enode.Node) error { + fd, err := srv.Dialer.Dial(dest) + if err != nil { + return &dialError{err} + } + mfd := newMeteredConn(fd, false, dest.IP()) + return srv.SetupConn(mfd, t.flags, dest) +} + +func (t *dialTask) String() string { + id := t.dest.ID() + return fmt.Sprintf("%v %x %v:%d", t.flags, id[:8], t.dest.IP(), t.dest.TCP()) +} + +func (t *discoverTask) Do(srv *Server) { + // newTasks generates a lookup task whenever dynamic dials are + // necessary. Lookups need to take some time, otherwise the + // event loop spins too fast. + next := srv.lastLookup.Add(lookupInterval) + if now := time.Now(); now.Before(next) { + time.Sleep(next.Sub(now)) + } + srv.lastLookup = time.Now() + t.results = srv.ntab.LookupRandom() +} + +func (t *discoverTask) String() string { + s := "discovery lookup" + if len(t.results) > 0 { + s += fmt.Sprintf(" (%d results)", len(t.results)) + } + return s +} + +func (t waitExpireTask) Do(*Server) { + time.Sleep(t.Duration) +} +func (t waitExpireTask) String() string { + return fmt.Sprintf("wait for dial hist expire (%v)", t.Duration) +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/discover/common.go b/vendor/github.com/ethereum/go-ethereum/p2p/discover/common.go new file mode 100644 index 00000000..3c080359 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/discover/common.go @@ -0,0 +1,57 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discover + +import ( + "crypto/ecdsa" + "net" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +type UDPConn interface { + ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) + WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error) + Close() error + LocalAddr() net.Addr +} + +// Config holds Table-related settings. +type Config struct { + // These settings are required and configure the UDP listener: + PrivateKey *ecdsa.PrivateKey + + // These settings are optional: + NetRestrict *netutil.Netlist // network whitelist + Bootnodes []*enode.Node // list of bootstrap nodes + Unhandled chan<- ReadPacket // unhandled packets are sent on this channel + Log log.Logger // if set, log messages go here +} + +// ListenUDP starts listening for discovery packets on the given UDP socket. +func ListenUDP(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { + return ListenV4(c, ln, cfg) +} + +// ReadPacket is a packet that couldn't be handled. Those packets are sent to the unhandled +// channel if configured. +type ReadPacket struct { + Data []byte + Addr *net.UDPAddr +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/discover/node.go b/vendor/github.com/ethereum/go-ethereum/p2p/discover/node.go new file mode 100644 index 00000000..a7d9ce73 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/discover/node.go @@ -0,0 +1,104 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discover + +import ( + "crypto/ecdsa" + "errors" + "math/big" + "net" + "time" + + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +// node represents a host on the network. +// The fields of Node may not be modified. +type node struct { + enode.Node + addedAt time.Time // time when the node was added to the table + livenessChecks uint // how often liveness was checked +} + +type encPubkey [64]byte + +func encodePubkey(key *ecdsa.PublicKey) encPubkey { + var e encPubkey + math.ReadBits(key.X, e[:len(e)/2]) + math.ReadBits(key.Y, e[len(e)/2:]) + return e +} + +func decodePubkey(e encPubkey) (*ecdsa.PublicKey, error) { + p := &ecdsa.PublicKey{Curve: crypto.S256(), X: new(big.Int), Y: new(big.Int)} + half := len(e) / 2 + p.X.SetBytes(e[:half]) + p.Y.SetBytes(e[half:]) + if !p.Curve.IsOnCurve(p.X, p.Y) { + return nil, errors.New("invalid secp256k1 curve point") + } + return p, nil +} + +func (e encPubkey) id() enode.ID { + return enode.ID(crypto.Keccak256Hash(e[:])) +} + +// recoverNodeKey computes the public key used to sign the +// given hash from the signature. +func recoverNodeKey(hash, sig []byte) (key encPubkey, err error) { + pubkey, err := crypto.Ecrecover(hash, sig) + if err != nil { + return key, err + } + copy(key[:], pubkey[1:]) + return key, nil +} + +func wrapNode(n *enode.Node) *node { + return &node{Node: *n} +} + +func wrapNodes(ns []*enode.Node) []*node { + result := make([]*node, len(ns)) + for i, n := range ns { + result[i] = wrapNode(n) + } + return result +} + +func unwrapNode(n *node) *enode.Node { + return &n.Node +} + +func unwrapNodes(ns []*node) []*enode.Node { + result := make([]*enode.Node, len(ns)) + for i, n := range ns { + result[i] = unwrapNode(n) + } + return result +} + +func (n *node) addr() *net.UDPAddr { + return &net.UDPAddr{IP: n.IP(), Port: n.UDP()} +} + +func (n *node) String() string { + return n.Node.String() +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/discover/table.go b/vendor/github.com/ethereum/go-ethereum/p2p/discover/table.go new file mode 100644 index 00000000..e0a46792 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/discover/table.go @@ -0,0 +1,676 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package discover implements the Node Discovery Protocol. +// +// The Node Discovery protocol provides a way to find RLPx nodes that +// can be connected to. It uses a Kademlia-like protocol to maintain a +// distributed database of the IDs and endpoints of all listening +// nodes. +package discover + +import ( + crand "crypto/rand" + "encoding/binary" + "fmt" + mrand "math/rand" + "net" + "sort" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +const ( + alpha = 3 // Kademlia concurrency factor + bucketSize = 16 // Kademlia bucket size + maxReplacements = 10 // Size of per-bucket replacement list + + // We keep buckets for the upper 1/15 of distances because + // it's very unlikely we'll ever encounter a node that's closer. + hashBits = len(common.Hash{}) * 8 + nBuckets = hashBits / 15 // Number of buckets + bucketMinDistance = hashBits - nBuckets // Log distance of closest bucket + + // IP address limits. + bucketIPLimit, bucketSubnet = 2, 24 // at most 2 addresses from the same /24 + tableIPLimit, tableSubnet = 10, 24 + + refreshInterval = 30 * time.Minute + revalidateInterval = 10 * time.Second + copyNodesInterval = 30 * time.Second + seedMinTableTime = 5 * time.Minute + seedCount = 30 + seedMaxAge = 5 * 24 * time.Hour +) + +// Table is the 'node table', a Kademlia-like index of neighbor nodes. The table keeps +// itself up-to-date by verifying the liveness of neighbors and requesting their node +// records when announcements of a new record version are received. +type Table struct { + mutex sync.Mutex // protects buckets, bucket content, nursery, rand + buckets [nBuckets]*bucket // index of known nodes by distance + nursery []*node // bootstrap nodes + rand *mrand.Rand // source of randomness, periodically reseeded + ips netutil.DistinctNetSet + + log log.Logger + db *enode.DB // database of known nodes + net transport + refreshReq chan chan struct{} + initDone chan struct{} + closeReq chan struct{} + closed chan struct{} + + nodeAddedHook func(*node) // for testing +} + +// transport is implemented by the UDP transports. +type transport interface { + Self() *enode.Node + RequestENR(*enode.Node) (*enode.Node, error) + lookupRandom() []*enode.Node + lookupSelf() []*enode.Node + ping(*enode.Node) (seq uint64, err error) +} + +// bucket contains nodes, ordered by their last activity. the entry +// that was most recently active is the first element in entries. +type bucket struct { + entries []*node // live entries, sorted by time of last contact + replacements []*node // recently seen nodes to be used if revalidation fails + ips netutil.DistinctNetSet +} + +func newTable(t transport, db *enode.DB, bootnodes []*enode.Node, log log.Logger) (*Table, error) { + tab := &Table{ + net: t, + db: db, + refreshReq: make(chan chan struct{}), + initDone: make(chan struct{}), + closeReq: make(chan struct{}), + closed: make(chan struct{}), + rand: mrand.New(mrand.NewSource(0)), + ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit}, + log: log, + } + if err := tab.setFallbackNodes(bootnodes); err != nil { + return nil, err + } + for i := range tab.buckets { + tab.buckets[i] = &bucket{ + ips: netutil.DistinctNetSet{Subnet: bucketSubnet, Limit: bucketIPLimit}, + } + } + tab.seedRand() + tab.loadSeedNodes() + + return tab, nil +} + +func (tab *Table) self() *enode.Node { + return tab.net.Self() +} + +func (tab *Table) seedRand() { + var b [8]byte + crand.Read(b[:]) + + tab.mutex.Lock() + tab.rand.Seed(int64(binary.BigEndian.Uint64(b[:]))) + tab.mutex.Unlock() +} + +// ReadRandomNodes fills the given slice with random nodes from the table. The results +// are guaranteed to be unique for a single invocation, no node will appear twice. +func (tab *Table) ReadRandomNodes(buf []*enode.Node) (n int) { + if !tab.isInitDone() { + return 0 + } + tab.mutex.Lock() + defer tab.mutex.Unlock() + + // Find all non-empty buckets and get a fresh slice of their entries. + var buckets [][]*node + for _, b := range &tab.buckets { + if len(b.entries) > 0 { + buckets = append(buckets, b.entries) + } + } + if len(buckets) == 0 { + return 0 + } + // Shuffle the buckets. + for i := len(buckets) - 1; i > 0; i-- { + j := tab.rand.Intn(len(buckets)) + buckets[i], buckets[j] = buckets[j], buckets[i] + } + // Move head of each bucket into buf, removing buckets that become empty. + var i, j int + for ; i < len(buf); i, j = i+1, (j+1)%len(buckets) { + b := buckets[j] + buf[i] = unwrapNode(b[0]) + buckets[j] = b[1:] + if len(b) == 1 { + buckets = append(buckets[:j], buckets[j+1:]...) + } + if len(buckets) == 0 { + break + } + } + return i + 1 +} + +// getNode returns the node with the given ID or nil if it isn't in the table. +func (tab *Table) getNode(id enode.ID) *enode.Node { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + b := tab.bucket(id) + for _, e := range b.entries { + if e.ID() == id { + return unwrapNode(e) + } + } + return nil +} + +// close terminates the network listener and flushes the node database. +func (tab *Table) close() { + close(tab.closeReq) + <-tab.closed +} + +// setFallbackNodes sets the initial points of contact. These nodes +// are used to connect to the network if the table is empty and there +// are no known nodes in the database. +func (tab *Table) setFallbackNodes(nodes []*enode.Node) error { + for _, n := range nodes { + if err := n.ValidateComplete(); err != nil { + return fmt.Errorf("bad bootstrap node %q: %v", n, err) + } + } + tab.nursery = wrapNodes(nodes) + return nil +} + +// isInitDone returns whether the table's initial seeding procedure has completed. +func (tab *Table) isInitDone() bool { + select { + case <-tab.initDone: + return true + default: + return false + } +} + +func (tab *Table) refresh() <-chan struct{} { + done := make(chan struct{}) + select { + case tab.refreshReq <- done: + case <-tab.closeReq: + close(done) + } + return done +} + +// loop schedules runs of doRefresh, doRevalidate and copyLiveNodes. +func (tab *Table) loop() { + var ( + revalidate = time.NewTimer(tab.nextRevalidateTime()) + refresh = time.NewTicker(refreshInterval) + copyNodes = time.NewTicker(copyNodesInterval) + refreshDone = make(chan struct{}) // where doRefresh reports completion + revalidateDone chan struct{} // where doRevalidate reports completion + waiting = []chan struct{}{tab.initDone} // holds waiting callers while doRefresh runs + ) + defer refresh.Stop() + defer revalidate.Stop() + defer copyNodes.Stop() + + // Start initial refresh. + go tab.doRefresh(refreshDone) + +loop: + for { + select { + case <-refresh.C: + tab.seedRand() + if refreshDone == nil { + refreshDone = make(chan struct{}) + go tab.doRefresh(refreshDone) + } + case req := <-tab.refreshReq: + waiting = append(waiting, req) + if refreshDone == nil { + refreshDone = make(chan struct{}) + go tab.doRefresh(refreshDone) + } + case <-refreshDone: + for _, ch := range waiting { + close(ch) + } + waiting, refreshDone = nil, nil + case <-revalidate.C: + revalidateDone = make(chan struct{}) + go tab.doRevalidate(revalidateDone) + case <-revalidateDone: + revalidate.Reset(tab.nextRevalidateTime()) + revalidateDone = nil + case <-copyNodes.C: + go tab.copyLiveNodes() + case <-tab.closeReq: + break loop + } + } + + if refreshDone != nil { + <-refreshDone + } + for _, ch := range waiting { + close(ch) + } + if revalidateDone != nil { + <-revalidateDone + } + close(tab.closed) +} + +// doRefresh performs a lookup for a random target to keep buckets full. seed nodes are +// inserted if the table is empty (initial bootstrap or discarded faulty peers). +func (tab *Table) doRefresh(done chan struct{}) { + defer close(done) + + // Load nodes from the database and insert + // them. This should yield a few previously seen nodes that are + // (hopefully) still alive. + tab.loadSeedNodes() + + // Run self lookup to discover new neighbor nodes. + tab.net.lookupSelf() + + // The Kademlia paper specifies that the bucket refresh should + // perform a lookup in the least recently used bucket. We cannot + // adhere to this because the findnode target is a 512bit value + // (not hash-sized) and it is not easily possible to generate a + // sha3 preimage that falls into a chosen bucket. + // We perform a few lookups with a random target instead. + for i := 0; i < 3; i++ { + tab.net.lookupRandom() + } +} + +func (tab *Table) loadSeedNodes() { + seeds := wrapNodes(tab.db.QuerySeeds(seedCount, seedMaxAge)) + seeds = append(seeds, tab.nursery...) + for i := range seeds { + seed := seeds[i] + age := log.Lazy{Fn: func() interface{} { return time.Since(tab.db.LastPongReceived(seed.ID(), seed.IP())) }} + tab.log.Trace("Found seed node in database", "id", seed.ID(), "addr", seed.addr(), "age", age) + tab.addSeenNode(seed) + } +} + +// doRevalidate checks that the last node in a random bucket is still live and replaces or +// deletes the node if it isn't. +func (tab *Table) doRevalidate(done chan<- struct{}) { + defer func() { done <- struct{}{} }() + + last, bi := tab.nodeToRevalidate() + if last == nil { + // No non-empty bucket found. + return + } + + // Ping the selected node and wait for a pong. + remoteSeq, err := tab.net.ping(unwrapNode(last)) + + // Also fetch record if the node replied and returned a higher sequence number. + if last.Seq() < remoteSeq { + n, err := tab.net.RequestENR(unwrapNode(last)) + if err != nil { + tab.log.Debug("ENR request failed", "id", last.ID(), "addr", last.addr(), "err", err) + } else { + last = &node{Node: *n, addedAt: last.addedAt, livenessChecks: last.livenessChecks} + } + } + + tab.mutex.Lock() + defer tab.mutex.Unlock() + b := tab.buckets[bi] + if err == nil { + // The node responded, move it to the front. + last.livenessChecks++ + tab.log.Debug("Revalidated node", "b", bi, "id", last.ID(), "checks", last.livenessChecks) + tab.bumpInBucket(b, last) + return + } + // No reply received, pick a replacement or delete the node if there aren't + // any replacements. + if r := tab.replace(b, last); r != nil { + tab.log.Debug("Replaced dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks, "r", r.ID(), "rip", r.IP()) + } else { + tab.log.Debug("Removed dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks) + } +} + +// nodeToRevalidate returns the last node in a random, non-empty bucket. +func (tab *Table) nodeToRevalidate() (n *node, bi int) { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + for _, bi = range tab.rand.Perm(len(tab.buckets)) { + b := tab.buckets[bi] + if len(b.entries) > 0 { + last := b.entries[len(b.entries)-1] + return last, bi + } + } + return nil, 0 +} + +func (tab *Table) nextRevalidateTime() time.Duration { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + return time.Duration(tab.rand.Int63n(int64(revalidateInterval))) +} + +// copyLiveNodes adds nodes from the table to the database if they have been in the table +// longer then minTableTime. +func (tab *Table) copyLiveNodes() { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + now := time.Now() + for _, b := range &tab.buckets { + for _, n := range b.entries { + if n.livenessChecks > 0 && now.Sub(n.addedAt) >= seedMinTableTime { + tab.db.UpdateNode(unwrapNode(n)) + } + } + } +} + +// closest returns the n nodes in the table that are closest to the +// given id. The caller must hold tab.mutex. +func (tab *Table) closest(target enode.ID, nresults int, checklive bool) *nodesByDistance { + // This is a very wasteful way to find the closest nodes but + // obviously correct. I believe that tree-based buckets would make + // this easier to implement efficiently. + close := &nodesByDistance{target: target} + for _, b := range &tab.buckets { + for _, n := range b.entries { + if checklive && n.livenessChecks == 0 { + continue + } + close.push(n, nresults) + } + } + return close +} + +// len returns the number of nodes in the table. +func (tab *Table) len() (n int) { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + for _, b := range &tab.buckets { + n += len(b.entries) + } + return n +} + +// bucket returns the bucket for the given node ID hash. +func (tab *Table) bucket(id enode.ID) *bucket { + d := enode.LogDist(tab.self().ID(), id) + if d <= bucketMinDistance { + return tab.buckets[0] + } + return tab.buckets[d-bucketMinDistance-1] +} + +// addSeenNode adds a node which may or may not be live to the end of a bucket. If the +// bucket has space available, adding the node succeeds immediately. Otherwise, the node is +// added to the replacements list. +// +// The caller must not hold tab.mutex. +func (tab *Table) addSeenNode(n *node) { + if n.ID() == tab.self().ID() { + return + } + + tab.mutex.Lock() + defer tab.mutex.Unlock() + b := tab.bucket(n.ID()) + if contains(b.entries, n.ID()) { + // Already in bucket, don't add. + return + } + if len(b.entries) >= bucketSize { + // Bucket full, maybe add as replacement. + tab.addReplacement(b, n) + return + } + if !tab.addIP(b, n.IP()) { + // Can't add: IP limit reached. + return + } + // Add to end of bucket: + b.entries = append(b.entries, n) + b.replacements = deleteNode(b.replacements, n) + n.addedAt = time.Now() + if tab.nodeAddedHook != nil { + tab.nodeAddedHook(n) + } +} + +// addVerifiedNode adds a node whose existence has been verified recently to the front of a +// bucket. If the node is already in the bucket, it is moved to the front. If the bucket +// has no space, the node is added to the replacements list. +// +// There is an additional safety measure: if the table is still initializing the node +// is not added. This prevents an attack where the table could be filled by just sending +// ping repeatedly. +// +// The caller must not hold tab.mutex. +func (tab *Table) addVerifiedNode(n *node) { + if !tab.isInitDone() { + return + } + if n.ID() == tab.self().ID() { + return + } + + tab.mutex.Lock() + defer tab.mutex.Unlock() + b := tab.bucket(n.ID()) + if tab.bumpInBucket(b, n) { + // Already in bucket, moved to front. + return + } + if len(b.entries) >= bucketSize { + // Bucket full, maybe add as replacement. + tab.addReplacement(b, n) + return + } + if !tab.addIP(b, n.IP()) { + // Can't add: IP limit reached. + return + } + // Add to front of bucket. + b.entries, _ = pushNode(b.entries, n, bucketSize) + b.replacements = deleteNode(b.replacements, n) + n.addedAt = time.Now() + if tab.nodeAddedHook != nil { + tab.nodeAddedHook(n) + } +} + +// delete removes an entry from the node table. It is used to evacuate dead nodes. +func (tab *Table) delete(node *node) { + tab.mutex.Lock() + defer tab.mutex.Unlock() + + tab.deleteInBucket(tab.bucket(node.ID()), node) +} + +func (tab *Table) addIP(b *bucket, ip net.IP) bool { + if netutil.IsLAN(ip) { + return true + } + if !tab.ips.Add(ip) { + tab.log.Debug("IP exceeds table limit", "ip", ip) + return false + } + if !b.ips.Add(ip) { + tab.log.Debug("IP exceeds bucket limit", "ip", ip) + tab.ips.Remove(ip) + return false + } + return true +} + +func (tab *Table) removeIP(b *bucket, ip net.IP) { + if netutil.IsLAN(ip) { + return + } + tab.ips.Remove(ip) + b.ips.Remove(ip) +} + +func (tab *Table) addReplacement(b *bucket, n *node) { + for _, e := range b.replacements { + if e.ID() == n.ID() { + return // already in list + } + } + if !tab.addIP(b, n.IP()) { + return + } + var removed *node + b.replacements, removed = pushNode(b.replacements, n, maxReplacements) + if removed != nil { + tab.removeIP(b, removed.IP()) + } +} + +// replace removes n from the replacement list and replaces 'last' with it if it is the +// last entry in the bucket. If 'last' isn't the last entry, it has either been replaced +// with someone else or became active. +func (tab *Table) replace(b *bucket, last *node) *node { + if len(b.entries) == 0 || b.entries[len(b.entries)-1].ID() != last.ID() { + // Entry has moved, don't replace it. + return nil + } + // Still the last entry. + if len(b.replacements) == 0 { + tab.deleteInBucket(b, last) + return nil + } + r := b.replacements[tab.rand.Intn(len(b.replacements))] + b.replacements = deleteNode(b.replacements, r) + b.entries[len(b.entries)-1] = r + tab.removeIP(b, last.IP()) + return r +} + +// bumpInBucket moves the given node to the front of the bucket entry list +// if it is contained in that list. +func (tab *Table) bumpInBucket(b *bucket, n *node) bool { + for i := range b.entries { + if b.entries[i].ID() == n.ID() { + if !n.IP().Equal(b.entries[i].IP()) { + // Endpoint has changed, ensure that the new IP fits into table limits. + tab.removeIP(b, b.entries[i].IP()) + if !tab.addIP(b, n.IP()) { + // It doesn't, put the previous one back. + tab.addIP(b, b.entries[i].IP()) + return false + } + } + // Move it to the front. + copy(b.entries[1:], b.entries[:i]) + b.entries[0] = n + return true + } + } + return false +} + +func (tab *Table) deleteInBucket(b *bucket, n *node) { + b.entries = deleteNode(b.entries, n) + tab.removeIP(b, n.IP()) +} + +func contains(ns []*node, id enode.ID) bool { + for _, n := range ns { + if n.ID() == id { + return true + } + } + return false +} + +// pushNode adds n to the front of list, keeping at most max items. +func pushNode(list []*node, n *node, max int) ([]*node, *node) { + if len(list) < max { + list = append(list, nil) + } + removed := list[len(list)-1] + copy(list[1:], list) + list[0] = n + return list, removed +} + +// deleteNode removes n from list. +func deleteNode(list []*node, n *node) []*node { + for i := range list { + if list[i].ID() == n.ID() { + return append(list[:i], list[i+1:]...) + } + } + return list +} + +// nodesByDistance is a list of nodes, ordered by distance to target. +type nodesByDistance struct { + entries []*node + target enode.ID +} + +// push adds the given node to the list, keeping the total size below maxElems. +func (h *nodesByDistance) push(n *node, maxElems int) { + ix := sort.Search(len(h.entries), func(i int) bool { + return enode.DistCmp(h.target, h.entries[i].ID(), n.ID()) > 0 + }) + if len(h.entries) < maxElems { + h.entries = append(h.entries, n) + } + if ix == len(h.entries) { + // farther away than all nodes we already have. + // if there was room for it, the node is now the last element. + } else { + // slide existing entries down to make room + // this will overwrite the entry we just appended. + copy(h.entries[ix+1:], h.entries[ix:]) + h.entries[ix] = n + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/discover/v4_udp.go b/vendor/github.com/ethereum/go-ethereum/p2p/discover/v4_udp.go new file mode 100644 index 00000000..b2a5d85c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/discover/v4_udp.go @@ -0,0 +1,1037 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discover + +import ( + "bytes" + "container/list" + "crypto/ecdsa" + crand "crypto/rand" + "errors" + "fmt" + "io" + "net" + "sync" + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/p2p/netutil" + "github.com/ethereum/go-ethereum/rlp" +) + +// Errors +var ( + errPacketTooSmall = errors.New("too small") + errBadHash = errors.New("bad hash") + errExpired = errors.New("expired") + errUnsolicitedReply = errors.New("unsolicited reply") + errUnknownNode = errors.New("unknown node") + errTimeout = errors.New("RPC timeout") + errClockWarp = errors.New("reply deadline too far in the future") + errClosed = errors.New("socket closed") +) + +const ( + respTimeout = 500 * time.Millisecond + expiration = 20 * time.Second + bondExpiration = 24 * time.Hour + + maxFindnodeFailures = 5 // nodes exceeding this limit are dropped + ntpFailureThreshold = 32 // Continuous timeouts after which to check NTP + ntpWarningCooldown = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning + driftThreshold = 10 * time.Second // Allowed clock drift before warning user + + // Discovery packets are defined to be no larger than 1280 bytes. + // Packets larger than this size will be cut at the end and treated + // as invalid because their hash won't match. + maxPacketSize = 1280 +) + +// RPC packet types +const ( + p_pingV4 = iota + 1 // zero is 'reserved' + p_pongV4 + p_findnodeV4 + p_neighborsV4 + p_enrRequestV4 + p_enrResponseV4 +) + +// RPC request structures +type ( + pingV4 struct { + senderKey *ecdsa.PublicKey // filled in by preverify + + Version uint + From, To rpcEndpoint + Expiration uint64 + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + // pongV4 is the reply to pingV4. + pongV4 struct { + // This field should mirror the UDP envelope address + // of the ping packet, which provides a way to discover the + // the external address (after NAT). + To rpcEndpoint + + ReplyTok []byte // This contains the hash of the ping packet. + Expiration uint64 // Absolute timestamp at which the packet becomes invalid. + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + // findnodeV4 is a query for nodes close to the given target. + findnodeV4 struct { + Target encPubkey + Expiration uint64 + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + // neighborsV4 is the reply to findnodeV4. + neighborsV4 struct { + Nodes []rpcNode + Expiration uint64 + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + // enrRequestV4 queries for the remote node's record. + enrRequestV4 struct { + Expiration uint64 + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + // enrResponseV4 is the reply to enrRequestV4. + enrResponseV4 struct { + ReplyTok []byte // Hash of the enrRequest packet. + Record enr.Record + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` + } + + rpcNode struct { + IP net.IP // len 4 for IPv4 or 16 for IPv6 + UDP uint16 // for discovery protocol + TCP uint16 // for RLPx protocol + ID encPubkey + } + + rpcEndpoint struct { + IP net.IP // len 4 for IPv4 or 16 for IPv6 + UDP uint16 // for discovery protocol + TCP uint16 // for RLPx protocol + } +) + +// packetV4 is implemented by all v4 protocol messages. +type packetV4 interface { + // preverify checks whether the packet is valid and should be handled at all. + preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error + // handle handles the packet. + handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) + // packet name and type for logging purposes. + name() string + kind() byte +} + +func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint { + ip := net.IP{} + if ip4 := addr.IP.To4(); ip4 != nil { + ip = ip4 + } else if ip6 := addr.IP.To16(); ip6 != nil { + ip = ip6 + } + return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort} +} + +func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) { + if rn.UDP <= 1024 { + return nil, errors.New("low port") + } + if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil { + return nil, err + } + if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) { + return nil, errors.New("not contained in netrestrict whitelist") + } + key, err := decodePubkey(rn.ID) + if err != nil { + return nil, err + } + n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP))) + err = n.ValidateComplete() + return n, err +} + +func nodeToRPC(n *node) rpcNode { + var key ecdsa.PublicKey + var ekey encPubkey + if err := n.Load((*enode.Secp256k1)(&key)); err == nil { + ekey = encodePubkey(&key) + } + return rpcNode{ID: ekey, IP: n.IP(), UDP: uint16(n.UDP()), TCP: uint16(n.TCP())} +} + +// UDPv4 implements the v4 wire protocol. +type UDPv4 struct { + conn UDPConn + log log.Logger + netrestrict *netutil.Netlist + priv *ecdsa.PrivateKey + localNode *enode.LocalNode + db *enode.DB + tab *Table + closeOnce sync.Once + wg sync.WaitGroup + + addReplyMatcher chan *replyMatcher + gotreply chan reply + closing chan struct{} +} + +// replyMatcher represents a pending reply. +// +// Some implementations of the protocol wish to send more than one +// reply packet to findnode. In general, any neighbors packet cannot +// be matched up with a specific findnode packet. +// +// Our implementation handles this by storing a callback function for +// each pending reply. Incoming packets from a node are dispatched +// to all callback functions for that node. +type replyMatcher struct { + // these fields must match in the reply. + from enode.ID + ip net.IP + ptype byte + + // time when the request must complete + deadline time.Time + + // callback is called when a matching reply arrives. If it returns matched == true, the + // reply was acceptable. The second return value indicates whether the callback should + // be removed from the pending reply queue. If it returns false, the reply is considered + // incomplete and the callback will be invoked again for the next matching reply. + callback replyMatchFunc + + // errc receives nil when the callback indicates completion or an + // error if no further reply is received within the timeout. + errc chan error + + // reply contains the most recent reply. This field is safe for reading after errc has + // received a value. + reply packetV4 +} + +type replyMatchFunc func(interface{}) (matched bool, requestDone bool) + +// reply is a reply packet from a certain node. +type reply struct { + from enode.ID + ip net.IP + data packetV4 + // loop indicates whether there was + // a matching request by sending on this channel. + matched chan<- bool +} + +func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { + t := &UDPv4{ + conn: c, + priv: cfg.PrivateKey, + netrestrict: cfg.NetRestrict, + localNode: ln, + db: ln.Database(), + closing: make(chan struct{}), + gotreply: make(chan reply), + addReplyMatcher: make(chan *replyMatcher), + log: cfg.Log, + } + if t.log == nil { + t.log = log.Root() + } + tab, err := newTable(t, ln.Database(), cfg.Bootnodes, t.log) + if err != nil { + return nil, err + } + t.tab = tab + go tab.loop() + + t.wg.Add(2) + go t.loop() + go t.readLoop(cfg.Unhandled) + return t, nil +} + +// Self returns the local node. +func (t *UDPv4) Self() *enode.Node { + return t.localNode.Node() +} + +// Close shuts down the socket and aborts any running queries. +func (t *UDPv4) Close() { + t.closeOnce.Do(func() { + close(t.closing) + t.conn.Close() + t.wg.Wait() + t.tab.close() + }) +} + +// ReadRandomNodes reads random nodes from the local table. +func (t *UDPv4) ReadRandomNodes(buf []*enode.Node) int { + return t.tab.ReadRandomNodes(buf) +} + +// LookupRandom finds random nodes in the network. +func (t *UDPv4) LookupRandom() []*enode.Node { + if t.tab.len() == 0 { + // All nodes were dropped, refresh. The very first query will hit this + // case and run the bootstrapping logic. + <-t.tab.refresh() + } + return t.lookupRandom() +} + +func (t *UDPv4) LookupPubkey(key *ecdsa.PublicKey) []*enode.Node { + if t.tab.len() == 0 { + // All nodes were dropped, refresh. The very first query will hit this + // case and run the bootstrapping logic. + <-t.tab.refresh() + } + return unwrapNodes(t.lookup(encodePubkey(key))) +} + +func (t *UDPv4) lookupRandom() []*enode.Node { + var target encPubkey + crand.Read(target[:]) + return unwrapNodes(t.lookup(target)) +} + +func (t *UDPv4) lookupSelf() []*enode.Node { + return unwrapNodes(t.lookup(encodePubkey(&t.priv.PublicKey))) +} + +// lookup performs a network search for nodes close to the given target. It approaches the +// target by querying nodes that are closer to it on each iteration. The given target does +// not need to be an actual node identifier. +func (t *UDPv4) lookup(targetKey encPubkey) []*node { + var ( + target = enode.ID(crypto.Keccak256Hash(targetKey[:])) + asked = make(map[enode.ID]bool) + seen = make(map[enode.ID]bool) + reply = make(chan []*node, alpha) + pendingQueries = 0 + result *nodesByDistance + ) + // Don't query further if we hit ourself. + // Unlikely to happen often in practice. + asked[t.Self().ID()] = true + + // Generate the initial result set. + t.tab.mutex.Lock() + result = t.tab.closest(target, bucketSize, false) + t.tab.mutex.Unlock() + + for { + // ask the alpha closest nodes that we haven't asked yet + for i := 0; i < len(result.entries) && pendingQueries < alpha; i++ { + n := result.entries[i] + if !asked[n.ID()] { + asked[n.ID()] = true + pendingQueries++ + go t.lookupWorker(n, targetKey, reply) + } + } + if pendingQueries == 0 { + // we have asked all closest nodes, stop the search + break + } + select { + case nodes := <-reply: + for _, n := range nodes { + if n != nil && !seen[n.ID()] { + seen[n.ID()] = true + result.push(n, bucketSize) + } + } + case <-t.tab.closeReq: + return nil // shutdown, no need to continue. + } + pendingQueries-- + } + return result.entries +} + +func (t *UDPv4) lookupWorker(n *node, targetKey encPubkey, reply chan<- []*node) { + fails := t.db.FindFails(n.ID(), n.IP()) + r, err := t.findnode(n.ID(), n.addr(), targetKey) + if err == errClosed { + // Avoid recording failures on shutdown. + reply <- nil + return + } else if len(r) == 0 { + fails++ + t.db.UpdateFindFails(n.ID(), n.IP(), fails) + t.log.Trace("Findnode failed", "id", n.ID(), "failcount", fails, "err", err) + if fails >= maxFindnodeFailures { + t.log.Trace("Too many findnode failures, dropping", "id", n.ID(), "failcount", fails) + t.tab.delete(n) + } + } else if fails > 0 { + // Reset failure counter because it counts _consecutive_ failures. + t.db.UpdateFindFails(n.ID(), n.IP(), 0) + } + + // Grab as many nodes as possible. Some of them might not be alive anymore, but we'll + // just remove those again during revalidation. + for _, n := range r { + t.tab.addSeenNode(n) + } + reply <- r +} + +// Resolve searches for a specific node with the given ID and tries to get the most recent +// version of the node record for it. It returns n if the node could not be resolved. +func (t *UDPv4) Resolve(n *enode.Node) *enode.Node { + // Try asking directly. This works if the node is still responding on the endpoint we have. + if rn, err := t.RequestENR(n); err == nil { + return rn + } + // Check table for the ID, we might have a newer version there. + if intable := t.tab.getNode(n.ID()); intable != nil && intable.Seq() > n.Seq() { + n = intable + if rn, err := t.RequestENR(n); err == nil { + return rn + } + } + // Otherwise perform a network lookup. + var key enode.Secp256k1 + if n.Load(&key) != nil { + return n // no secp256k1 key + } + result := t.LookupPubkey((*ecdsa.PublicKey)(&key)) + for _, rn := range result { + if rn.ID() == n.ID() { + if rn, err := t.RequestENR(rn); err == nil { + return rn + } + } + } + return n +} + +func (t *UDPv4) ourEndpoint() rpcEndpoint { + n := t.Self() + a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} + return makeEndpoint(a, uint16(n.TCP())) +} + +// Ping sends a ping message to the given node. +func (t *UDPv4) Ping(n *enode.Node) error { + _, err := t.ping(n) + return err +} + +// ping sends a ping message to the given node and waits for a reply. +func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) { + rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil) + if err = <-rm.errc; err == nil { + seq = seqFromTail(rm.reply.(*pongV4).Rest) + } + return seq, err +} + +// sendPing sends a ping message to the given node and invokes the callback +// when the reply arrives. +func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher { + req := t.makePing(toaddr) + packet, hash, err := t.encode(t.priv, req) + if err != nil { + errc := make(chan error, 1) + errc <- err + return &replyMatcher{errc: errc} + } + // Add a matcher for the reply to the pending reply queue. Pongs are matched if they + // reference the ping we're about to send. + rm := t.pending(toid, toaddr.IP, p_pongV4, func(p interface{}) (matched bool, requestDone bool) { + matched = bytes.Equal(p.(*pongV4).ReplyTok, hash) + if matched && callback != nil { + callback() + } + return matched, matched + }) + // Send the packet. + t.localNode.UDPContact(toaddr) + t.write(toaddr, toid, req.name(), packet) + return rm +} + +func (t *UDPv4) makePing(toaddr *net.UDPAddr) *pingV4 { + seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq()) + return &pingV4{ + Version: 4, + From: t.ourEndpoint(), + To: makeEndpoint(toaddr, 0), + Expiration: uint64(time.Now().Add(expiration).Unix()), + Rest: []rlp.RawValue{seq}, + } +} + +// findnode sends a findnode request to the given node and waits until +// the node has sent up to k neighbors. +func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target encPubkey) ([]*node, error) { + t.ensureBond(toid, toaddr) + + // Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is + // active until enough nodes have been received. + nodes := make([]*node, 0, bucketSize) + nreceived := 0 + rm := t.pending(toid, toaddr.IP, p_neighborsV4, func(r interface{}) (matched bool, requestDone bool) { + reply := r.(*neighborsV4) + for _, rn := range reply.Nodes { + nreceived++ + n, err := t.nodeFromRPC(toaddr, rn) + if err != nil { + t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err) + continue + } + nodes = append(nodes, n) + } + return true, nreceived >= bucketSize + }) + t.send(toaddr, toid, &findnodeV4{ + Target: target, + Expiration: uint64(time.Now().Add(expiration).Unix()), + }) + return nodes, <-rm.errc +} + +// RequestENR sends enrRequest to the given node and waits for a response. +func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { + addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} + t.ensureBond(n.ID(), addr) + + req := &enrRequestV4{ + Expiration: uint64(time.Now().Add(expiration).Unix()), + } + packet, hash, err := t.encode(t.priv, req) + if err != nil { + return nil, err + } + // Add a matcher for the reply to the pending reply queue. Responses are matched if + // they reference the request we're about to send. + rm := t.pending(n.ID(), addr.IP, p_enrResponseV4, func(r interface{}) (matched bool, requestDone bool) { + matched = bytes.Equal(r.(*enrResponseV4).ReplyTok, hash) + return matched, matched + }) + // Send the packet and wait for the reply. + t.write(addr, n.ID(), req.name(), packet) + if err := <-rm.errc; err != nil { + return nil, err + } + // Verify the response record. + respN, err := enode.New(enode.ValidSchemes, &rm.reply.(*enrResponseV4).Record) + if err != nil { + return nil, err + } + if respN.ID() != n.ID() { + return nil, fmt.Errorf("invalid ID in response record") + } + if respN.Seq() < n.Seq() { + return n, nil // response record is older + } + if err := netutil.CheckRelayIP(addr.IP, respN.IP()); err != nil { + return nil, fmt.Errorf("invalid IP in response record: %v", err) + } + return respN, nil +} + +// pending adds a reply matcher to the pending reply queue. +// see the documentation of type replyMatcher for a detailed explanation. +func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchFunc) *replyMatcher { + ch := make(chan error, 1) + p := &replyMatcher{from: id, ip: ip, ptype: ptype, callback: callback, errc: ch} + select { + case t.addReplyMatcher <- p: + // loop will handle it + case <-t.closing: + ch <- errClosed + } + return p +} + +// handleReply dispatches a reply packet, invoking reply matchers. It returns +// whether any matcher considered the packet acceptable. +func (t *UDPv4) handleReply(from enode.ID, fromIP net.IP, req packetV4) bool { + matched := make(chan bool, 1) + select { + case t.gotreply <- reply{from, fromIP, req, matched}: + // loop will handle it + return <-matched + case <-t.closing: + return false + } +} + +// loop runs in its own goroutine. it keeps track of +// the refresh timer and the pending reply queue. +func (t *UDPv4) loop() { + defer t.wg.Done() + + var ( + plist = list.New() + timeout = time.NewTimer(0) + nextTimeout *replyMatcher // head of plist when timeout was last reset + contTimeouts = 0 // number of continuous timeouts to do NTP checks + ntpWarnTime = time.Unix(0, 0) + ) + <-timeout.C // ignore first timeout + defer timeout.Stop() + + resetTimeout := func() { + if plist.Front() == nil || nextTimeout == plist.Front().Value { + return + } + // Start the timer so it fires when the next pending reply has expired. + now := time.Now() + for el := plist.Front(); el != nil; el = el.Next() { + nextTimeout = el.Value.(*replyMatcher) + if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout { + timeout.Reset(dist) + return + } + // Remove pending replies whose deadline is too far in the + // future. These can occur if the system clock jumped + // backwards after the deadline was assigned. + nextTimeout.errc <- errClockWarp + plist.Remove(el) + } + nextTimeout = nil + timeout.Stop() + } + + for { + resetTimeout() + + select { + case <-t.closing: + for el := plist.Front(); el != nil; el = el.Next() { + el.Value.(*replyMatcher).errc <- errClosed + } + return + + case p := <-t.addReplyMatcher: + p.deadline = time.Now().Add(respTimeout) + plist.PushBack(p) + + case r := <-t.gotreply: + var matched bool // whether any replyMatcher considered the reply acceptable. + for el := plist.Front(); el != nil; el = el.Next() { + p := el.Value.(*replyMatcher) + if p.from == r.from && p.ptype == r.data.kind() && p.ip.Equal(r.ip) { + ok, requestDone := p.callback(r.data) + matched = matched || ok + // Remove the matcher if callback indicates that all replies have been received. + if requestDone { + p.reply = r.data + p.errc <- nil + plist.Remove(el) + } + // Reset the continuous timeout counter (time drift detection) + contTimeouts = 0 + } + } + r.matched <- matched + + case now := <-timeout.C: + nextTimeout = nil + + // Notify and remove callbacks whose deadline is in the past. + for el := plist.Front(); el != nil; el = el.Next() { + p := el.Value.(*replyMatcher) + if now.After(p.deadline) || now.Equal(p.deadline) { + p.errc <- errTimeout + plist.Remove(el) + contTimeouts++ + } + } + // If we've accumulated too many timeouts, do an NTP time sync check + if contTimeouts > ntpFailureThreshold { + if time.Since(ntpWarnTime) >= ntpWarningCooldown { + ntpWarnTime = time.Now() + go checkClockDrift() + } + contTimeouts = 0 + } + } + } +} + +const ( + macSize = 256 / 8 + sigSize = 520 / 8 + headSize = macSize + sigSize // space of packet frame data +) + +var ( + headSpace = make([]byte, headSize) + + // Neighbors replies are sent across multiple packets to + // stay below the packet size limit. We compute the maximum number + // of entries by stuffing a packet until it grows too large. + maxNeighbors int +) + +func init() { + p := neighborsV4{Expiration: ^uint64(0)} + maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)} + for n := 0; ; n++ { + p.Nodes = append(p.Nodes, maxSizeNode) + size, _, err := rlp.EncodeToReader(p) + if err != nil { + // If this ever happens, it will be caught by the unit tests. + panic("cannot encode: " + err.Error()) + } + if headSize+size+1 >= maxPacketSize { + maxNeighbors = n + break + } + } +} + +func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req packetV4) ([]byte, error) { + packet, hash, err := t.encode(t.priv, req) + if err != nil { + return hash, err + } + return hash, t.write(toaddr, toid, req.name(), packet) +} + +func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error { + _, err := t.conn.WriteToUDP(packet, toaddr) + t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err) + return err +} + +func (t *UDPv4) encode(priv *ecdsa.PrivateKey, req packetV4) (packet, hash []byte, err error) { + name := req.name() + b := new(bytes.Buffer) + b.Write(headSpace) + b.WriteByte(req.kind()) + if err := rlp.Encode(b, req); err != nil { + t.log.Error(fmt.Sprintf("Can't encode %s packet", name), "err", err) + return nil, nil, err + } + packet = b.Bytes() + sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv) + if err != nil { + t.log.Error(fmt.Sprintf("Can't sign %s packet", name), "err", err) + return nil, nil, err + } + copy(packet[macSize:], sig) + // add the hash to the front. Note: this doesn't protect the + // packet in any way. Our public key will be part of this hash in + // The future. + hash = crypto.Keccak256(packet[macSize:]) + copy(packet, hash) + return packet, hash, nil +} + +// readLoop runs in its own goroutine. it handles incoming UDP packets. +func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { + defer t.wg.Done() + if unhandled != nil { + defer close(unhandled) + } + + buf := make([]byte, maxPacketSize) + for { + nbytes, from, err := t.conn.ReadFromUDP(buf) + if netutil.IsTemporaryError(err) { + // Ignore temporary read errors. + t.log.Debug("Temporary UDP read error", "err", err) + continue + } else if err != nil { + // Shut down the loop for permament errors. + if err != io.EOF { + t.log.Debug("UDP read error", "err", err) + } + return + } + if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil { + select { + case unhandled <- ReadPacket{buf[:nbytes], from}: + default: + } + } + } +} + +func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error { + packet, fromKey, hash, err := decodeV4(buf) + if err != nil { + t.log.Debug("Bad discv4 packet", "addr", from, "err", err) + return err + } + fromID := fromKey.id() + if err == nil { + err = packet.preverify(t, from, fromID, fromKey) + } + t.log.Trace("<< "+packet.name(), "id", fromID, "addr", from, "err", err) + if err == nil { + packet.handle(t, from, fromID, hash) + } + return err +} + +func decodeV4(buf []byte) (packetV4, encPubkey, []byte, error) { + if len(buf) < headSize+1 { + return nil, encPubkey{}, nil, errPacketTooSmall + } + hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:] + shouldhash := crypto.Keccak256(buf[macSize:]) + if !bytes.Equal(hash, shouldhash) { + return nil, encPubkey{}, nil, errBadHash + } + fromKey, err := recoverNodeKey(crypto.Keccak256(buf[headSize:]), sig) + if err != nil { + return nil, fromKey, hash, err + } + + var req packetV4 + switch ptype := sigdata[0]; ptype { + case p_pingV4: + req = new(pingV4) + case p_pongV4: + req = new(pongV4) + case p_findnodeV4: + req = new(findnodeV4) + case p_neighborsV4: + req = new(neighborsV4) + case p_enrRequestV4: + req = new(enrRequestV4) + case p_enrResponseV4: + req = new(enrResponseV4) + default: + return nil, fromKey, hash, fmt.Errorf("unknown type: %d", ptype) + } + s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0) + err = s.Decode(req) + return req, fromKey, hash, err +} + +// checkBond checks if the given node has a recent enough endpoint proof. +func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool { + return time.Since(t.db.LastPongReceived(id, ip)) < bondExpiration +} + +// ensureBond solicits a ping from a node if we haven't seen a ping from it for a while. +// This ensures there is a valid endpoint proof on the remote end. +func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) { + tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration + if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures { + rm := t.sendPing(toid, toaddr, nil) + <-rm.errc + // Wait for them to ping back and process our pong. + time.Sleep(respTimeout) + } +} + +// expired checks whether the given UNIX time stamp is in the past. +func expired(ts uint64) bool { + return time.Unix(int64(ts), 0).Before(time.Now()) +} + +func seqFromTail(tail []rlp.RawValue) uint64 { + if len(tail) == 0 { + return 0 + } + var seq uint64 + rlp.DecodeBytes(tail[0], &seq) + return seq +} + +// PING/v4 + +func (req *pingV4) name() string { return "PING/v4" } +func (req *pingV4) kind() byte { return p_pingV4 } + +func (req *pingV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if expired(req.Expiration) { + return errExpired + } + key, err := decodePubkey(fromKey) + if err != nil { + return errors.New("invalid public key") + } + req.senderKey = key + return nil +} + +func (req *pingV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { + // Reply. + seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq()) + t.send(from, fromID, &pongV4{ + To: makeEndpoint(from, req.From.TCP), + ReplyTok: mac, + Expiration: uint64(time.Now().Add(expiration).Unix()), + Rest: []rlp.RawValue{seq}, + }) + + // Ping back if our last pong on file is too far in the past. + n := wrapNode(enode.NewV4(req.senderKey, from.IP, int(req.From.TCP), from.Port)) + if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration { + t.sendPing(fromID, from, func() { + t.tab.addVerifiedNode(n) + }) + } else { + t.tab.addVerifiedNode(n) + } + + // Update node database and endpoint predictor. + t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now()) + t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) +} + +// PONG/v4 + +func (req *pongV4) name() string { return "PONG/v4" } +func (req *pongV4) kind() byte { return p_pongV4 } + +func (req *pongV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if expired(req.Expiration) { + return errExpired + } + if !t.handleReply(fromID, from.IP, req) { + return errUnsolicitedReply + } + return nil +} + +func (req *pongV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { + t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}) + t.db.UpdateLastPongReceived(fromID, from.IP, time.Now()) +} + +// FINDNODE/v4 + +func (req *findnodeV4) name() string { return "FINDNODE/v4" } +func (req *findnodeV4) kind() byte { return p_findnodeV4 } + +func (req *findnodeV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if expired(req.Expiration) { + return errExpired + } + if !t.checkBond(fromID, from.IP) { + // No endpoint proof pong exists, we don't process the packet. This prevents an + // attack vector where the discovery protocol could be used to amplify traffic in a + // DDOS attack. A malicious actor would send a findnode request with the IP address + // and UDP port of the target as the source address. The recipient of the findnode + // packet would then send a neighbors packet (which is a much bigger packet than + // findnode) to the victim. + return errUnknownNode + } + return nil +} + +func (req *findnodeV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { + // Determine closest nodes. + target := enode.ID(crypto.Keccak256Hash(req.Target[:])) + t.tab.mutex.Lock() + closest := t.tab.closest(target, bucketSize, true).entries + t.tab.mutex.Unlock() + + // Send neighbors in chunks with at most maxNeighbors per packet + // to stay below the packet size limit. + p := neighborsV4{Expiration: uint64(time.Now().Add(expiration).Unix())} + var sent bool + for _, n := range closest { + if netutil.CheckRelayIP(from.IP, n.IP()) == nil { + p.Nodes = append(p.Nodes, nodeToRPC(n)) + } + if len(p.Nodes) == maxNeighbors { + t.send(from, fromID, &p) + p.Nodes = p.Nodes[:0] + sent = true + } + } + if len(p.Nodes) > 0 || !sent { + t.send(from, fromID, &p) + } +} + +// NEIGHBORS/v4 + +func (req *neighborsV4) name() string { return "NEIGHBORS/v4" } +func (req *neighborsV4) kind() byte { return p_neighborsV4 } + +func (req *neighborsV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if expired(req.Expiration) { + return errExpired + } + if !t.handleReply(fromID, from.IP, req) { + return errUnsolicitedReply + } + return nil +} + +func (req *neighborsV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { +} + +// ENRREQUEST/v4 + +func (req *enrRequestV4) name() string { return "ENRREQUEST/v4" } +func (req *enrRequestV4) kind() byte { return p_enrRequestV4 } + +func (req *enrRequestV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if expired(req.Expiration) { + return errExpired + } + if !t.checkBond(fromID, from.IP) { + return errUnknownNode + } + return nil +} + +func (req *enrRequestV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { + t.send(from, fromID, &enrResponseV4{ + ReplyTok: mac, + Record: *t.localNode.Node().Record(), + }) +} + +// ENRRESPONSE/v4 + +func (req *enrResponseV4) name() string { return "ENRRESPONSE/v4" } +func (req *enrResponseV4) kind() byte { return p_enrResponseV4 } + +func (req *enrResponseV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error { + if !t.handleReply(fromID, from.IP, req) { + return errUnsolicitedReply + } + return nil +} + +func (req *enrResponseV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) { +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/enode/localnode.go b/vendor/github.com/ethereum/go-ethereum/p2p/enode/localnode.go new file mode 100644 index 00000000..d8aa02a7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/enode/localnode.go @@ -0,0 +1,290 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package enode + +import ( + "crypto/ecdsa" + "fmt" + "net" + "reflect" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +const ( + // IP tracker configuration + iptrackMinStatements = 10 + iptrackWindow = 5 * time.Minute + iptrackContactWindow = 10 * time.Minute +) + +// LocalNode produces the signed node record of a local node, i.e. a node run in the +// current process. Setting ENR entries via the Set method updates the record. A new version +// of the record is signed on demand when the Node method is called. +type LocalNode struct { + cur atomic.Value // holds a non-nil node pointer while the record is up-to-date. + id ID + key *ecdsa.PrivateKey + db *DB + + // everything below is protected by a lock + mu sync.Mutex + seq uint64 + entries map[string]enr.Entry + endpoint4 lnEndpoint + endpoint6 lnEndpoint +} + +type lnEndpoint struct { + track *netutil.IPTracker + staticIP, fallbackIP net.IP + fallbackUDP int +} + +// NewLocalNode creates a local node. +func NewLocalNode(db *DB, key *ecdsa.PrivateKey) *LocalNode { + ln := &LocalNode{ + id: PubkeyToIDV4(&key.PublicKey), + db: db, + key: key, + entries: make(map[string]enr.Entry), + endpoint4: lnEndpoint{ + track: netutil.NewIPTracker(iptrackWindow, iptrackContactWindow, iptrackMinStatements), + }, + endpoint6: lnEndpoint{ + track: netutil.NewIPTracker(iptrackWindow, iptrackContactWindow, iptrackMinStatements), + }, + } + ln.seq = db.localSeq(ln.id) + ln.invalidate() + return ln +} + +// Database returns the node database associated with the local node. +func (ln *LocalNode) Database() *DB { + return ln.db +} + +// Node returns the current version of the local node record. +func (ln *LocalNode) Node() *Node { + n := ln.cur.Load().(*Node) + if n != nil { + return n + } + // Record was invalidated, sign a new copy. + ln.mu.Lock() + defer ln.mu.Unlock() + ln.sign() + return ln.cur.Load().(*Node) +} + +// Seq returns the current sequence number of the local node record. +func (ln *LocalNode) Seq() uint64 { + ln.mu.Lock() + defer ln.mu.Unlock() + + return ln.seq +} + +// ID returns the local node ID. +func (ln *LocalNode) ID() ID { + return ln.id +} + +// Set puts the given entry into the local record, overwriting any existing value. +// Use Set*IP and SetFallbackUDP to set IP addresses and UDP port, otherwise they'll +// be overwritten by the endpoint predictor. +func (ln *LocalNode) Set(e enr.Entry) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.set(e) +} + +func (ln *LocalNode) set(e enr.Entry) { + val, exists := ln.entries[e.ENRKey()] + if !exists || !reflect.DeepEqual(val, e) { + ln.entries[e.ENRKey()] = e + ln.invalidate() + } +} + +// Delete removes the given entry from the local record. +func (ln *LocalNode) Delete(e enr.Entry) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.delete(e) +} + +func (ln *LocalNode) delete(e enr.Entry) { + _, exists := ln.entries[e.ENRKey()] + if exists { + delete(ln.entries, e.ENRKey()) + ln.invalidate() + } +} + +func (ln *LocalNode) endpointForIP(ip net.IP) *lnEndpoint { + if ip.To4() != nil { + return &ln.endpoint4 + } + return &ln.endpoint6 +} + +// SetStaticIP sets the local IP to the given one unconditionally. +// This disables endpoint prediction. +func (ln *LocalNode) SetStaticIP(ip net.IP) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.endpointForIP(ip).staticIP = ip + ln.updateEndpoints() +} + +// SetFallbackIP sets the last-resort IP address. This address is used +// if no endpoint prediction can be made and no static IP is set. +func (ln *LocalNode) SetFallbackIP(ip net.IP) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.endpointForIP(ip).fallbackIP = ip + ln.updateEndpoints() +} + +// SetFallbackUDP sets the last-resort UDP-on-IPv4 port. This port is used +// if no endpoint prediction can be made. +func (ln *LocalNode) SetFallbackUDP(port int) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.endpoint4.fallbackUDP = port + ln.endpoint6.fallbackUDP = port + ln.updateEndpoints() +} + +// UDPEndpointStatement should be called whenever a statement about the local node's +// UDP endpoint is received. It feeds the local endpoint predictor. +func (ln *LocalNode) UDPEndpointStatement(fromaddr, endpoint *net.UDPAddr) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.endpointForIP(endpoint.IP).track.AddStatement(fromaddr.String(), endpoint.String()) + ln.updateEndpoints() +} + +// UDPContact should be called whenever the local node has announced itself to another node +// via UDP. It feeds the local endpoint predictor. +func (ln *LocalNode) UDPContact(toaddr *net.UDPAddr) { + ln.mu.Lock() + defer ln.mu.Unlock() + + ln.endpointForIP(toaddr.IP).track.AddContact(toaddr.String()) + ln.updateEndpoints() +} + +// updateEndpoints updates the record with predicted endpoints. +func (ln *LocalNode) updateEndpoints() { + ip4, udp4 := ln.endpoint4.get() + ip6, udp6 := ln.endpoint6.get() + + if ip4 != nil && !ip4.IsUnspecified() { + ln.set(enr.IPv4(ip4)) + } else { + ln.delete(enr.IPv4{}) + } + if ip6 != nil && !ip6.IsUnspecified() { + ln.set(enr.IPv6(ip6)) + } else { + ln.delete(enr.IPv6{}) + } + if udp4 != 0 { + ln.set(enr.UDP(udp4)) + } else { + ln.delete(enr.UDP(0)) + } + if udp6 != 0 && udp6 != udp4 { + ln.set(enr.UDP6(udp6)) + } else { + ln.delete(enr.UDP6(0)) + } +} + +// get returns the endpoint with highest precedence. +func (e *lnEndpoint) get() (newIP net.IP, newPort int) { + newPort = e.fallbackUDP + if e.fallbackIP != nil { + newIP = e.fallbackIP + } + if e.staticIP != nil { + newIP = e.staticIP + } else if ip, port := predictAddr(e.track); ip != nil { + newIP = ip + newPort = port + } + return newIP, newPort +} + +// predictAddr wraps IPTracker.PredictEndpoint, converting from its string-based +// endpoint representation to IP and port types. +func predictAddr(t *netutil.IPTracker) (net.IP, int) { + ep := t.PredictEndpoint() + if ep == "" { + return nil, 0 + } + ipString, portString, _ := net.SplitHostPort(ep) + ip := net.ParseIP(ipString) + port, _ := strconv.Atoi(portString) + return ip, port +} + +func (ln *LocalNode) invalidate() { + ln.cur.Store((*Node)(nil)) +} + +func (ln *LocalNode) sign() { + if n := ln.cur.Load().(*Node); n != nil { + return // no changes + } + + var r enr.Record + for _, e := range ln.entries { + r.Set(e) + } + ln.bumpSeq() + r.SetSeq(ln.seq) + if err := SignV4(&r, ln.key); err != nil { + panic(fmt.Errorf("enode: can't sign record: %v", err)) + } + n, err := New(ValidSchemes, &r) + if err != nil { + panic(fmt.Errorf("enode: can't verify local record: %v", err)) + } + ln.cur.Store(n) + log.Info("New local node record", "seq", ln.seq, "id", n.ID(), "ip", n.IP(), "udp", n.UDP(), "tcp", n.TCP()) +} + +func (ln *LocalNode) bumpSeq() { + ln.seq++ + ln.db.storeLocalSeq(ln.id, ln.seq) +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/enode/node.go b/vendor/github.com/ethereum/go-ethereum/p2p/enode/node.go new file mode 100644 index 00000000..9eb2544f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/enode/node.go @@ -0,0 +1,300 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package enode + +import ( + "crypto/ecdsa" + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "math/bits" + "math/rand" + "net" + "strings" + + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/rlp" +) + +var errMissingPrefix = errors.New("missing 'enr:' prefix for base64-encoded record") + +// Node represents a host on the network. +type Node struct { + r enr.Record + id ID +} + +// New wraps a node record. The record must be valid according to the given +// identity scheme. +func New(validSchemes enr.IdentityScheme, r *enr.Record) (*Node, error) { + if err := r.VerifySignature(validSchemes); err != nil { + return nil, err + } + node := &Node{r: *r} + if n := copy(node.id[:], validSchemes.NodeAddr(&node.r)); n != len(ID{}) { + return nil, fmt.Errorf("invalid node ID length %d, need %d", n, len(ID{})) + } + return node, nil +} + +// MustParse parses a node record or enode:// URL. It panics if the input is invalid. +func MustParse(rawurl string) *Node { + n, err := Parse(ValidSchemes, rawurl) + if err != nil { + panic("invalid node: " + err.Error()) + } + return n +} + +// Parse decodes and verifies a base64-encoded node record. +func Parse(validSchemes enr.IdentityScheme, input string) (*Node, error) { + if strings.HasPrefix(input, "enode://") { + return ParseV4(input) + } + if !strings.HasPrefix(input, "enr:") { + return nil, errMissingPrefix + } + bin, err := base64.RawURLEncoding.DecodeString(input[4:]) + if err != nil { + return nil, err + } + var r enr.Record + if err := rlp.DecodeBytes(bin, &r); err != nil { + return nil, err + } + return New(validSchemes, &r) +} + +// ID returns the node identifier. +func (n *Node) ID() ID { + return n.id +} + +// Seq returns the sequence number of the underlying record. +func (n *Node) Seq() uint64 { + return n.r.Seq() +} + +// Incomplete returns true for nodes with no IP address. +func (n *Node) Incomplete() bool { + return n.IP() == nil +} + +// Load retrieves an entry from the underlying record. +func (n *Node) Load(k enr.Entry) error { + return n.r.Load(k) +} + +// IP returns the IP address of the node. This prefers IPv4 addresses. +func (n *Node) IP() net.IP { + var ( + ip4 enr.IPv4 + ip6 enr.IPv6 + ) + if n.Load(&ip4) == nil { + return net.IP(ip4) + } + if n.Load(&ip6) == nil { + return net.IP(ip6) + } + return nil +} + +// UDP returns the UDP port of the node. +func (n *Node) UDP() int { + var port enr.UDP + n.Load(&port) + return int(port) +} + +// UDP returns the TCP port of the node. +func (n *Node) TCP() int { + var port enr.TCP + n.Load(&port) + return int(port) +} + +// Pubkey returns the secp256k1 public key of the node, if present. +func (n *Node) Pubkey() *ecdsa.PublicKey { + var key ecdsa.PublicKey + if n.Load((*Secp256k1)(&key)) != nil { + return nil + } + return &key +} + +// Record returns the node's record. The return value is a copy and may +// be modified by the caller. +func (n *Node) Record() *enr.Record { + cpy := n.r + return &cpy +} + +// ValidateComplete checks whether n has a valid IP and UDP port. +// Deprecated: don't use this method. +func (n *Node) ValidateComplete() error { + if n.Incomplete() { + return errors.New("missing IP address") + } + if n.UDP() == 0 { + return errors.New("missing UDP port") + } + ip := n.IP() + if ip.IsMulticast() || ip.IsUnspecified() { + return errors.New("invalid IP (multicast/unspecified)") + } + // Validate the node key (on curve, etc.). + var key Secp256k1 + return n.Load(&key) +} + +// String returns the text representation of the record. +func (n *Node) String() string { + if isNewV4(n) { + return n.URLv4() // backwards-compatibility glue for NewV4 nodes + } + enc, _ := rlp.EncodeToBytes(&n.r) // always succeeds because record is valid + b64 := base64.RawURLEncoding.EncodeToString(enc) + return "enr:" + b64 +} + +// MarshalText implements encoding.TextMarshaler. +func (n *Node) MarshalText() ([]byte, error) { + return []byte(n.String()), nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (n *Node) UnmarshalText(text []byte) error { + dec, err := Parse(ValidSchemes, string(text)) + if err == nil { + *n = *dec + } + return err +} + +// ID is a unique identifier for each node. +type ID [32]byte + +// Bytes returns a byte slice representation of the ID +func (n ID) Bytes() []byte { + return n[:] +} + +// ID prints as a long hexadecimal number. +func (n ID) String() string { + return fmt.Sprintf("%x", n[:]) +} + +// The Go syntax representation of a ID is a call to HexID. +func (n ID) GoString() string { + return fmt.Sprintf("enode.HexID(\"%x\")", n[:]) +} + +// TerminalString returns a shortened hex string for terminal logging. +func (n ID) TerminalString() string { + return hex.EncodeToString(n[:8]) +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (n ID) MarshalText() ([]byte, error) { + return []byte(hex.EncodeToString(n[:])), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (n *ID) UnmarshalText(text []byte) error { + id, err := parseID(string(text)) + if err != nil { + return err + } + *n = id + return nil +} + +// HexID converts a hex string to an ID. +// The string may be prefixed with 0x. +// It panics if the string is not a valid ID. +func HexID(in string) ID { + id, err := parseID(in) + if err != nil { + panic(err) + } + return id +} + +func parseID(in string) (ID, error) { + var id ID + b, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) + if err != nil { + return id, err + } else if len(b) != len(id) { + return id, fmt.Errorf("wrong length, want %d hex chars", len(id)*2) + } + copy(id[:], b) + return id, nil +} + +// DistCmp compares the distances a->target and b->target. +// Returns -1 if a is closer to target, 1 if b is closer to target +// and 0 if they are equal. +func DistCmp(target, a, b ID) int { + for i := range target { + da := a[i] ^ target[i] + db := b[i] ^ target[i] + if da > db { + return 1 + } else if da < db { + return -1 + } + } + return 0 +} + +// LogDist returns the logarithmic distance between a and b, log2(a ^ b). +func LogDist(a, b ID) int { + lz := 0 + for i := range a { + x := a[i] ^ b[i] + if x == 0 { + lz += 8 + } else { + lz += bits.LeadingZeros8(x) + break + } + } + return len(a)*8 - lz +} + +// RandomID returns a random ID b such that logdist(a, b) == n. +func RandomID(a ID, n int) (b ID) { + if n == 0 { + return a + } + // flip bit at position n, fill the rest with random bits + b = a + pos := len(a) - n/8 - 1 + bit := byte(0x01) << (byte(n%8) - 1) + if bit == 0 { + pos++ + bit = 0x80 + } + b[pos] = a[pos]&^bit | ^a[pos]&bit // TODO: randomize end bits + for i := pos + 1; i < len(a); i++ { + b[i] = byte(rand.Intn(255)) + } + return b +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/enode/urlv4.go b/vendor/github.com/ethereum/go-ethereum/p2p/enode/urlv4.go new file mode 100644 index 00000000..2372d482 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/enode/urlv4.go @@ -0,0 +1,196 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package enode + +import ( + "crypto/ecdsa" + "encoding/hex" + "errors" + "fmt" + "net" + "net/url" + "regexp" + "strconv" + + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/enr" +) + +var incompleteNodeURL = regexp.MustCompile("(?i)^(?:enode://)?([0-9a-f]+)$") + +// MustParseV4 parses a node URL. It panics if the URL is not valid. +func MustParseV4(rawurl string) *Node { + n, err := ParseV4(rawurl) + if err != nil { + panic("invalid node URL: " + err.Error()) + } + return n +} + +// ParseV4 parses a node URL. +// +// There are two basic forms of node URLs: +// +// - incomplete nodes, which only have the public key (node ID) +// - complete nodes, which contain the public key and IP/Port information +// +// For incomplete nodes, the designator must look like one of these +// +// enode:// +// +// +// For complete nodes, the node ID is encoded in the username portion +// of the URL, separated from the host by an @ sign. The hostname can +// only be given as an IP address, DNS domain names are not allowed. +// The port in the host name section is the TCP listening port. If the +// TCP and UDP (discovery) ports differ, the UDP port is specified as +// query parameter "discport". +// +// In the following example, the node URL describes +// a node with IP address 10.3.58.6, TCP listening port 30303 +// and UDP discovery port 30301. +// +// enode://@10.3.58.6:30303?discport=30301 +func ParseV4(rawurl string) (*Node, error) { + if m := incompleteNodeURL.FindStringSubmatch(rawurl); m != nil { + id, err := parsePubkey(m[1]) + if err != nil { + return nil, fmt.Errorf("invalid public key (%v)", err) + } + return NewV4(id, nil, 0, 0), nil + } + return parseComplete(rawurl) +} + +// NewV4 creates a node from discovery v4 node information. The record +// contained in the node has a zero-length signature. +func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp int) *Node { + var r enr.Record + if len(ip) > 0 { + r.Set(enr.IP(ip)) + } + if udp != 0 { + r.Set(enr.UDP(udp)) + } + if tcp != 0 { + r.Set(enr.TCP(tcp)) + } + signV4Compat(&r, pubkey) + n, err := New(v4CompatID{}, &r) + if err != nil { + panic(err) + } + return n +} + +// isNewV4 returns true for nodes created by NewV4. +func isNewV4(n *Node) bool { + var k s256raw + return n.r.IdentityScheme() == "" && n.r.Load(&k) == nil && len(n.r.Signature()) == 0 +} + +func parseComplete(rawurl string) (*Node, error) { + var ( + id *ecdsa.PublicKey + ip net.IP + tcpPort, udpPort uint64 + ) + u, err := url.Parse(rawurl) + if err != nil { + return nil, err + } + if u.Scheme != "enode" { + return nil, errors.New("invalid URL scheme, want \"enode\"") + } + // Parse the Node ID from the user portion. + if u.User == nil { + return nil, errors.New("does not contain node ID") + } + if id, err = parsePubkey(u.User.String()); err != nil { + return nil, fmt.Errorf("invalid public key (%v)", err) + } + // Parse the IP address. + host, port, err := net.SplitHostPort(u.Host) + if err != nil { + return nil, fmt.Errorf("invalid host: %v", err) + } + if ip = net.ParseIP(host); ip == nil { + return nil, errors.New("invalid IP address") + } + // Parse the port numbers. + if tcpPort, err = strconv.ParseUint(port, 10, 16); err != nil { + return nil, errors.New("invalid port") + } + udpPort = tcpPort + qv := u.Query() + if qv.Get("discport") != "" { + udpPort, err = strconv.ParseUint(qv.Get("discport"), 10, 16) + if err != nil { + return nil, errors.New("invalid discport in query") + } + } + return NewV4(id, ip, int(tcpPort), int(udpPort)), nil +} + +// parsePubkey parses a hex-encoded secp256k1 public key. +func parsePubkey(in string) (*ecdsa.PublicKey, error) { + b, err := hex.DecodeString(in) + if err != nil { + return nil, err + } else if len(b) != 64 { + return nil, fmt.Errorf("wrong length, want %d hex chars", 128) + } + b = append([]byte{0x4}, b...) + return crypto.UnmarshalPubkey(b) +} + +func (n *Node) URLv4() string { + var ( + scheme enr.ID + nodeid string + key ecdsa.PublicKey + ) + n.Load(&scheme) + n.Load((*Secp256k1)(&key)) + switch { + case scheme == "v4" || key != ecdsa.PublicKey{}: + nodeid = fmt.Sprintf("%x", crypto.FromECDSAPub(&key)[1:]) + default: + nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:]) + } + u := url.URL{Scheme: "enode"} + if n.Incomplete() { + u.Host = nodeid + } else { + addr := net.TCPAddr{IP: n.IP(), Port: n.TCP()} + u.User = url.User(nodeid) + u.Host = addr.String() + if n.UDP() != n.TCP() { + u.RawQuery = "discport=" + strconv.Itoa(n.UDP()) + } + } + return u.String() +} + +// PubkeyToIDV4 derives the v4 node address from the given public key. +func PubkeyToIDV4(key *ecdsa.PublicKey) ID { + e := make([]byte, 64) + math.ReadBits(key.X, e[:len(e)/2]) + math.ReadBits(key.Y, e[len(e)/2:]) + return ID(crypto.Keccak256Hash(e)) +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/enr/enr.go b/vendor/github.com/ethereum/go-ethereum/p2p/enr/enr.go new file mode 100644 index 00000000..c36ae9e3 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/enr/enr.go @@ -0,0 +1,310 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package enr implements Ethereum Node Records as defined in EIP-778. A node record holds +// arbitrary information about a node on the peer-to-peer network. Node information is +// stored in key/value pairs. To store and retrieve key/values in a record, use the Entry +// interface. +// +// Signature Handling +// +// Records must be signed before transmitting them to another node. +// +// Decoding a record doesn't check its signature. Code working with records from an +// untrusted source must always verify two things: that the record uses an identity scheme +// deemed secure, and that the signature is valid according to the declared scheme. +// +// When creating a record, set the entries you want and use a signing function provided by +// the identity scheme to add the signature. Modifying a record invalidates the signature. +// +// Package enr supports the "secp256k1-keccak" identity scheme. +package enr + +import ( + "bytes" + "errors" + "fmt" + "io" + "sort" + + "github.com/ethereum/go-ethereum/rlp" +) + +const SizeLimit = 300 // maximum encoded size of a node record in bytes + +var ( + ErrInvalidSig = errors.New("invalid signature on node record") + errNotSorted = errors.New("record key/value pairs are not sorted by key") + errDuplicateKey = errors.New("record contains duplicate key") + errIncompletePair = errors.New("record contains incomplete k/v pair") + errTooBig = fmt.Errorf("record bigger than %d bytes", SizeLimit) + errEncodeUnsigned = errors.New("can't encode unsigned record") + errNotFound = errors.New("no such key in record") +) + +// An IdentityScheme is capable of verifying record signatures and +// deriving node addresses. +type IdentityScheme interface { + Verify(r *Record, sig []byte) error + NodeAddr(r *Record) []byte +} + +// SchemeMap is a registry of named identity schemes. +type SchemeMap map[string]IdentityScheme + +func (m SchemeMap) Verify(r *Record, sig []byte) error { + s := m[r.IdentityScheme()] + if s == nil { + return ErrInvalidSig + } + return s.Verify(r, sig) +} + +func (m SchemeMap) NodeAddr(r *Record) []byte { + s := m[r.IdentityScheme()] + if s == nil { + return nil + } + return s.NodeAddr(r) +} + +// Record represents a node record. The zero value is an empty record. +type Record struct { + seq uint64 // sequence number + signature []byte // the signature + raw []byte // RLP encoded record + pairs []pair // sorted list of all key/value pairs +} + +// pair is a key/value pair in a record. +type pair struct { + k string + v rlp.RawValue +} + +// Seq returns the sequence number. +func (r *Record) Seq() uint64 { + return r.seq +} + +// SetSeq updates the record sequence number. This invalidates any signature on the record. +// Calling SetSeq is usually not required because setting any key in a signed record +// increments the sequence number. +func (r *Record) SetSeq(s uint64) { + r.signature = nil + r.raw = nil + r.seq = s +} + +// Load retrieves the value of a key/value pair. The given Entry must be a pointer and will +// be set to the value of the entry in the record. +// +// Errors returned by Load are wrapped in KeyError. You can distinguish decoding errors +// from missing keys using the IsNotFound function. +func (r *Record) Load(e Entry) error { + i := sort.Search(len(r.pairs), func(i int) bool { return r.pairs[i].k >= e.ENRKey() }) + if i < len(r.pairs) && r.pairs[i].k == e.ENRKey() { + if err := rlp.DecodeBytes(r.pairs[i].v, e); err != nil { + return &KeyError{Key: e.ENRKey(), Err: err} + } + return nil + } + return &KeyError{Key: e.ENRKey(), Err: errNotFound} +} + +// Set adds or updates the given entry in the record. It panics if the value can't be +// encoded. If the record is signed, Set increments the sequence number and invalidates +// the sequence number. +func (r *Record) Set(e Entry) { + blob, err := rlp.EncodeToBytes(e) + if err != nil { + panic(fmt.Errorf("enr: can't encode %s: %v", e.ENRKey(), err)) + } + r.invalidate() + + pairs := make([]pair, len(r.pairs)) + copy(pairs, r.pairs) + i := sort.Search(len(pairs), func(i int) bool { return pairs[i].k >= e.ENRKey() }) + switch { + case i < len(pairs) && pairs[i].k == e.ENRKey(): + // element is present at r.pairs[i] + pairs[i].v = blob + case i < len(r.pairs): + // insert pair before i-th elem + el := pair{e.ENRKey(), blob} + pairs = append(pairs, pair{}) + copy(pairs[i+1:], pairs[i:]) + pairs[i] = el + default: + // element should be placed at the end of r.pairs + pairs = append(pairs, pair{e.ENRKey(), blob}) + } + r.pairs = pairs +} + +func (r *Record) invalidate() { + if r.signature != nil { + r.seq++ + } + r.signature = nil + r.raw = nil +} + +// Signature returns the signature of the record. +func (r *Record) Signature() []byte { + if r.signature == nil { + return nil + } + cpy := make([]byte, len(r.signature)) + copy(cpy, r.signature) + return cpy +} + +// EncodeRLP implements rlp.Encoder. Encoding fails if +// the record is unsigned. +func (r Record) EncodeRLP(w io.Writer) error { + if r.signature == nil { + return errEncodeUnsigned + } + _, err := w.Write(r.raw) + return err +} + +// DecodeRLP implements rlp.Decoder. Decoding doesn't verify the signature. +func (r *Record) DecodeRLP(s *rlp.Stream) error { + dec, raw, err := decodeRecord(s) + if err != nil { + return err + } + *r = dec + r.raw = raw + return nil +} + +func decodeRecord(s *rlp.Stream) (dec Record, raw []byte, err error) { + raw, err = s.Raw() + if err != nil { + return dec, raw, err + } + if len(raw) > SizeLimit { + return dec, raw, errTooBig + } + + // Decode the RLP container. + s = rlp.NewStream(bytes.NewReader(raw), 0) + if _, err := s.List(); err != nil { + return dec, raw, err + } + if err = s.Decode(&dec.signature); err != nil { + return dec, raw, err + } + if err = s.Decode(&dec.seq); err != nil { + return dec, raw, err + } + // The rest of the record contains sorted k/v pairs. + var prevkey string + for i := 0; ; i++ { + var kv pair + if err := s.Decode(&kv.k); err != nil { + if err == rlp.EOL { + break + } + return dec, raw, err + } + if err := s.Decode(&kv.v); err != nil { + if err == rlp.EOL { + return dec, raw, errIncompletePair + } + return dec, raw, err + } + if i > 0 { + if kv.k == prevkey { + return dec, raw, errDuplicateKey + } + if kv.k < prevkey { + return dec, raw, errNotSorted + } + } + dec.pairs = append(dec.pairs, kv) + prevkey = kv.k + } + return dec, raw, s.ListEnd() +} + +// IdentityScheme returns the name of the identity scheme in the record. +func (r *Record) IdentityScheme() string { + var id ID + r.Load(&id) + return string(id) +} + +// VerifySignature checks whether the record is signed using the given identity scheme. +func (r *Record) VerifySignature(s IdentityScheme) error { + return s.Verify(r, r.signature) +} + +// SetSig sets the record signature. It returns an error if the encoded record is larger +// than the size limit or if the signature is invalid according to the passed scheme. +// +// You can also use SetSig to remove the signature explicitly by passing a nil scheme +// and signature. +// +// SetSig panics when either the scheme or the signature (but not both) are nil. +func (r *Record) SetSig(s IdentityScheme, sig []byte) error { + switch { + // Prevent storing invalid data. + case s == nil && sig != nil: + panic("enr: invalid call to SetSig with non-nil signature but nil scheme") + case s != nil && sig == nil: + panic("enr: invalid call to SetSig with nil signature but non-nil scheme") + // Verify if we have a scheme. + case s != nil: + if err := s.Verify(r, sig); err != nil { + return err + } + raw, err := r.encode(sig) + if err != nil { + return err + } + r.signature, r.raw = sig, raw + // Reset otherwise. + default: + r.signature, r.raw = nil, nil + } + return nil +} + +// AppendElements appends the sequence number and entries to the given slice. +func (r *Record) AppendElements(list []interface{}) []interface{} { + list = append(list, r.seq) + for _, p := range r.pairs { + list = append(list, p.k, p.v) + } + return list +} + +func (r *Record) encode(sig []byte) (raw []byte, err error) { + list := make([]interface{}, 1, 2*len(r.pairs)+1) + list[0] = sig + list = r.AppendElements(list) + if raw, err = rlp.EncodeToBytes(list); err != nil { + return nil, err + } + if len(raw) > SizeLimit { + return nil, errTooBig + } + return raw, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/enr/entries.go b/vendor/github.com/ethereum/go-ethereum/p2p/enr/entries.go new file mode 100644 index 00000000..f2118401 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/enr/entries.go @@ -0,0 +1,188 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package enr + +import ( + "fmt" + "io" + "net" + + "github.com/ethereum/go-ethereum/rlp" +) + +// Entry is implemented by known node record entry types. +// +// To define a new entry that is to be included in a node record, +// create a Go type that satisfies this interface. The type should +// also implement rlp.Decoder if additional checks are needed on the value. +type Entry interface { + ENRKey() string +} + +type generic struct { + key string + value interface{} +} + +func (g generic) ENRKey() string { return g.key } + +func (g generic) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, g.value) +} + +func (g *generic) DecodeRLP(s *rlp.Stream) error { + return s.Decode(g.value) +} + +// WithEntry wraps any value with a key name. It can be used to set and load arbitrary values +// in a record. The value v must be supported by rlp. To use WithEntry with Load, the value +// must be a pointer. +func WithEntry(k string, v interface{}) Entry { + return &generic{key: k, value: v} +} + +// TCP is the "tcp" key, which holds the TCP port of the node. +type TCP uint16 + +func (v TCP) ENRKey() string { return "tcp" } + +// UDP is the "udp" key, which holds the IPv6-specific UDP port of the node. +type TCP6 uint16 + +func (v TCP6) ENRKey() string { return "tcp6" } + +// UDP is the "udp" key, which holds the UDP port of the node. +type UDP uint16 + +func (v UDP) ENRKey() string { return "udp" } + +// UDP is the "udp" key, which holds the IPv6-specific UDP port of the node. +type UDP6 uint16 + +func (v UDP6) ENRKey() string { return "udp6" } + +// ID is the "id" key, which holds the name of the identity scheme. +type ID string + +const IDv4 = ID("v4") // the default identity scheme + +func (v ID) ENRKey() string { return "id" } + +// IP is either the "ip" or "ip6" key, depending on the value. +// Use this value to encode IP addresses that can be either v4 or v6. +// To load an address from a record use the IPv4 or IPv6 types. +type IP net.IP + +func (v IP) ENRKey() string { + if net.IP(v).To4() == nil { + return "ip6" + } + return "ip" +} + +// EncodeRLP implements rlp.Encoder. +func (v IP) EncodeRLP(w io.Writer) error { + if ip4 := net.IP(v).To4(); ip4 != nil { + return rlp.Encode(w, ip4) + } + if ip6 := net.IP(v).To16(); ip6 != nil { + return rlp.Encode(w, ip6) + } + return fmt.Errorf("invalid IP address: %v", net.IP(v)) +} + +// DecodeRLP implements rlp.Decoder. +func (v *IP) DecodeRLP(s *rlp.Stream) error { + if err := s.Decode((*net.IP)(v)); err != nil { + return err + } + if len(*v) != 4 && len(*v) != 16 { + return fmt.Errorf("invalid IP address, want 4 or 16 bytes: %v", *v) + } + return nil +} + +// IPv4 is the "ip" key, which holds the IP address of the node. +type IPv4 net.IP + +func (v IPv4) ENRKey() string { return "ip" } + +// EncodeRLP implements rlp.Encoder. +func (v IPv4) EncodeRLP(w io.Writer) error { + ip4 := net.IP(v).To4() + if ip4 == nil { + return fmt.Errorf("invalid IPv4 address: %v", net.IP(v)) + } + return rlp.Encode(w, ip4) +} + +// DecodeRLP implements rlp.Decoder. +func (v *IPv4) DecodeRLP(s *rlp.Stream) error { + if err := s.Decode((*net.IP)(v)); err != nil { + return err + } + if len(*v) != 4 { + return fmt.Errorf("invalid IPv4 address, want 4 bytes: %v", *v) + } + return nil +} + +// IPv6 is the "ip6" key, which holds the IP address of the node. +type IPv6 net.IP + +func (v IPv6) ENRKey() string { return "ip6" } + +// EncodeRLP implements rlp.Encoder. +func (v IPv6) EncodeRLP(w io.Writer) error { + ip6 := net.IP(v).To16() + if ip6 == nil { + return fmt.Errorf("invalid IPv6 address: %v", net.IP(v)) + } + return rlp.Encode(w, ip6) +} + +// DecodeRLP implements rlp.Decoder. +func (v *IPv6) DecodeRLP(s *rlp.Stream) error { + if err := s.Decode((*net.IP)(v)); err != nil { + return err + } + if len(*v) != 16 { + return fmt.Errorf("invalid IPv6 address, want 16 bytes: %v", *v) + } + return nil +} + +// KeyError is an error related to a key. +type KeyError struct { + Key string + Err error +} + +// Error implements error. +func (err *KeyError) Error() string { + if err.Err == errNotFound { + return fmt.Sprintf("missing ENR key %q", err.Key) + } + return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err) +} + +// IsNotFound reports whether the given error means that a key/value pair is +// missing from a record. +func IsNotFound(err error) bool { + kerr, ok := err.(*KeyError) + return ok && kerr.Err == errNotFound +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/metrics.go b/vendor/github.com/ethereum/go-ethereum/p2p/metrics.go new file mode 100644 index 00000000..c04e5ab4 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/metrics.go @@ -0,0 +1,238 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains the meters and timers used by the networking layer. + +package p2p + +import ( + "fmt" + "net" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +const ( + MetricsInboundTraffic = "p2p/ingress" // Name for the registered inbound traffic meter + MetricsOutboundTraffic = "p2p/egress" // Name for the registered outbound traffic meter + MetricsOutboundConnects = "p2p/dials" // Name for the registered outbound connects meter + MetricsInboundConnects = "p2p/serves" // Name for the registered inbound connects meter + + MeteredPeerLimit = 1024 // This amount of peers are individually metered +) + +var ( + ingressConnectMeter = metrics.NewRegisteredMeter(MetricsInboundConnects, nil) // Meter counting the ingress connections + ingressTrafficMeter = metrics.NewRegisteredMeter(MetricsInboundTraffic, nil) // Meter metering the cumulative ingress traffic + egressConnectMeter = metrics.NewRegisteredMeter(MetricsOutboundConnects, nil) // Meter counting the egress connections + egressTrafficMeter = metrics.NewRegisteredMeter(MetricsOutboundTraffic, nil) // Meter metering the cumulative egress traffic + activePeerCounter = metrics.NewRegisteredCounter("p2p/peers", nil) // Gauge tracking the current peer count + + PeerIngressRegistry = metrics.NewPrefixedChildRegistry(metrics.EphemeralRegistry, MetricsInboundTraffic+"/") // Registry containing the peer ingress + PeerEgressRegistry = metrics.NewPrefixedChildRegistry(metrics.EphemeralRegistry, MetricsOutboundTraffic+"/") // Registry containing the peer egress + + meteredPeerFeed event.Feed // Event feed for peer metrics + meteredPeerCount int32 // Actually stored peer connection count +) + +// MeteredPeerEventType is the type of peer events emitted by a metered connection. +type MeteredPeerEventType int + +const ( + // PeerConnected is the type of event emitted when a peer successfully + // made the handshake. + PeerConnected MeteredPeerEventType = iota + + // PeerDisconnected is the type of event emitted when a peer disconnects. + PeerDisconnected + + // PeerHandshakeFailed is the type of event emitted when a peer fails to + // make the handshake or disconnects before the handshake. + PeerHandshakeFailed +) + +// MeteredPeerEvent is an event emitted when peers connect or disconnect. +type MeteredPeerEvent struct { + Type MeteredPeerEventType // Type of peer event + IP net.IP // IP address of the peer + ID enode.ID // NodeID of the peer + Elapsed time.Duration // Time elapsed between the connection and the handshake/disconnection + Ingress uint64 // Ingress count at the moment of the event + Egress uint64 // Egress count at the moment of the event +} + +// SubscribeMeteredPeerEvent registers a subscription for peer life-cycle events +// if metrics collection is enabled. +func SubscribeMeteredPeerEvent(ch chan<- MeteredPeerEvent) event.Subscription { + return meteredPeerFeed.Subscribe(ch) +} + +// meteredConn is a wrapper around a net.Conn that meters both the +// inbound and outbound network traffic. +type meteredConn struct { + net.Conn // Network connection to wrap with metering + + connected time.Time // Connection time of the peer + ip net.IP // IP address of the peer + id enode.ID // NodeID of the peer + + // trafficMetered denotes if the peer is registered in the traffic registries. + // Its value is true if the metered peer count doesn't reach the limit in the + // moment of the peer's connection. + trafficMetered bool + ingressMeter metrics.Meter // Meter for the read bytes of the peer + egressMeter metrics.Meter // Meter for the written bytes of the peer + + lock sync.RWMutex // Lock protecting the metered connection's internals +} + +// newMeteredConn creates a new metered connection, bumps the ingress or egress +// connection meter and also increases the metered peer count. If the metrics +// system is disabled or the IP address is unspecified, this function returns +// the original object. +func newMeteredConn(conn net.Conn, ingress bool, ip net.IP) net.Conn { + // Short circuit if metrics are disabled + if !metrics.Enabled { + return conn + } + if ip.IsUnspecified() { + log.Warn("Peer IP is unspecified") + return conn + } + // Bump the connection counters and wrap the connection + if ingress { + ingressConnectMeter.Mark(1) + } else { + egressConnectMeter.Mark(1) + } + activePeerCounter.Inc(1) + + return &meteredConn{ + Conn: conn, + ip: ip, + connected: time.Now(), + } +} + +// Read delegates a network read to the underlying connection, bumping the common +// and the peer ingress traffic meters along the way. +func (c *meteredConn) Read(b []byte) (n int, err error) { + n, err = c.Conn.Read(b) + ingressTrafficMeter.Mark(int64(n)) + c.lock.RLock() + if c.trafficMetered { + c.ingressMeter.Mark(int64(n)) + } + c.lock.RUnlock() + return n, err +} + +// Write delegates a network write to the underlying connection, bumping the common +// and the peer egress traffic meters along the way. +func (c *meteredConn) Write(b []byte) (n int, err error) { + n, err = c.Conn.Write(b) + egressTrafficMeter.Mark(int64(n)) + c.lock.RLock() + if c.trafficMetered { + c.egressMeter.Mark(int64(n)) + } + c.lock.RUnlock() + return n, err +} + +// handshakeDone is called when a peer handshake is done. Registers the peer to +// the ingress and the egress traffic registries using the peer's IP and node ID, +// also emits connect event. +func (c *meteredConn) handshakeDone(id enode.ID) { + // TODO (kurkomisi): use the node URL instead of the pure node ID. (the String() method of *Node) + if atomic.AddInt32(&meteredPeerCount, 1) >= MeteredPeerLimit { + // Don't register the peer in the traffic registries. + atomic.AddInt32(&meteredPeerCount, -1) + c.lock.Lock() + c.id, c.trafficMetered = id, false + c.lock.Unlock() + log.Warn("Metered peer count reached the limit") + } else { + key := fmt.Sprintf("%s/%s", c.ip, id.String()) + c.lock.Lock() + c.id, c.trafficMetered = id, true + c.ingressMeter = metrics.NewRegisteredMeter(key, PeerIngressRegistry) + c.egressMeter = metrics.NewRegisteredMeter(key, PeerEgressRegistry) + c.lock.Unlock() + } + meteredPeerFeed.Send(MeteredPeerEvent{ + Type: PeerConnected, + IP: c.ip, + ID: id, + Elapsed: time.Since(c.connected), + }) +} + +// Close delegates a close operation to the underlying connection, unregisters +// the peer from the traffic registries and emits close event. +func (c *meteredConn) Close() error { + err := c.Conn.Close() + c.lock.RLock() + if c.id == (enode.ID{}) { + // If the peer disconnects before the handshake. + c.lock.RUnlock() + meteredPeerFeed.Send(MeteredPeerEvent{ + Type: PeerHandshakeFailed, + IP: c.ip, + Elapsed: time.Since(c.connected), + }) + activePeerCounter.Dec(1) + return err + } + id := c.id + if !c.trafficMetered { + // If the peer isn't registered in the traffic registries. + c.lock.RUnlock() + meteredPeerFeed.Send(MeteredPeerEvent{ + Type: PeerDisconnected, + IP: c.ip, + ID: id, + }) + activePeerCounter.Dec(1) + return err + } + ingress, egress := uint64(c.ingressMeter.Count()), uint64(c.egressMeter.Count()) + c.lock.RUnlock() + + // Decrement the metered peer count + atomic.AddInt32(&meteredPeerCount, -1) + + // Unregister the peer from the traffic registries + key := fmt.Sprintf("%s/%s", c.ip, id) + PeerIngressRegistry.Unregister(key) + PeerEgressRegistry.Unregister(key) + + meteredPeerFeed.Send(MeteredPeerEvent{ + Type: PeerDisconnected, + IP: c.ip, + ID: id, + Ingress: ingress, + Egress: egress, + }) + activePeerCounter.Dec(1) + return err +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/netutil/addrutil.go b/vendor/github.com/ethereum/go-ethereum/p2p/netutil/addrutil.go new file mode 100644 index 00000000..b261a529 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/netutil/addrutil.go @@ -0,0 +1,33 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package netutil + +import "net" + +// AddrIP gets the IP address contained in addr. It returns nil if no address is present. +func AddrIP(addr net.Addr) net.IP { + switch a := addr.(type) { + case *net.IPAddr: + return a.IP + case *net.TCPAddr: + return a.IP + case *net.UDPAddr: + return a.IP + default: + return nil + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/peer.go b/vendor/github.com/ethereum/go-ethereum/p2p/peer.go new file mode 100644 index 00000000..98ea6835 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/peer.go @@ -0,0 +1,476 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package p2p + +import ( + "errors" + "fmt" + "io" + "net" + "sort" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + ErrShuttingDown = errors.New("shutting down") +) + +const ( + baseProtocolVersion = 5 + baseProtocolLength = uint64(16) + baseProtocolMaxMsgSize = 2 * 1024 + + snappyProtocolVersion = 5 + + pingInterval = 15 * time.Second +) + +const ( + // devp2p message codes + handshakeMsg = 0x00 + discMsg = 0x01 + pingMsg = 0x02 + pongMsg = 0x03 +) + +// protoHandshake is the RLP structure of the protocol handshake. +type protoHandshake struct { + Version uint64 + Name string + Caps []Cap + ListenPort uint64 + ID []byte // secp256k1 public key + + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` +} + +// PeerEventType is the type of peer events emitted by a p2p.Server +type PeerEventType string + +const ( + // PeerEventTypeAdd is the type of event emitted when a peer is added + // to a p2p.Server + PeerEventTypeAdd PeerEventType = "add" + + // PeerEventTypeDrop is the type of event emitted when a peer is + // dropped from a p2p.Server + PeerEventTypeDrop PeerEventType = "drop" + + // PeerEventTypeMsgSend is the type of event emitted when a + // message is successfully sent to a peer + PeerEventTypeMsgSend PeerEventType = "msgsend" + + // PeerEventTypeMsgRecv is the type of event emitted when a + // message is received from a peer + PeerEventTypeMsgRecv PeerEventType = "msgrecv" +) + +// PeerEvent is an event emitted when peers are either added or dropped from +// a p2p.Server or when a message is sent or received on a peer connection +type PeerEvent struct { + Type PeerEventType `json:"type"` + Peer enode.ID `json:"peer"` + Error string `json:"error,omitempty"` + Protocol string `json:"protocol,omitempty"` + MsgCode *uint64 `json:"msg_code,omitempty"` + MsgSize *uint32 `json:"msg_size,omitempty"` +} + +// Peer represents a connected remote node. +type Peer struct { + rw *conn + running map[string]*protoRW + log log.Logger + created mclock.AbsTime + + wg sync.WaitGroup + protoErr chan error + closed chan struct{} + disc chan DiscReason + + // events receives message send / receive events if set + events *event.Feed +} + +// NewPeer returns a peer for testing purposes. +func NewPeer(id enode.ID, name string, caps []Cap) *Peer { + pipe, _ := net.Pipe() + node := enode.SignNull(new(enr.Record), id) + conn := &conn{fd: pipe, transport: nil, node: node, caps: caps, name: name} + peer := newPeer(log.Root(), conn, nil) + close(peer.closed) // ensures Disconnect doesn't block + return peer +} + +// ID returns the node's public key. +func (p *Peer) ID() enode.ID { + return p.rw.node.ID() +} + +// Node returns the peer's node descriptor. +func (p *Peer) Node() *enode.Node { + return p.rw.node +} + +// Name returns the node name that the remote node advertised. +func (p *Peer) Name() string { + return p.rw.name +} + +// Caps returns the capabilities (supported subprotocols) of the remote peer. +func (p *Peer) Caps() []Cap { + // TODO: maybe return copy + return p.rw.caps +} + +// RemoteAddr returns the remote address of the network connection. +func (p *Peer) RemoteAddr() net.Addr { + return p.rw.fd.RemoteAddr() +} + +// LocalAddr returns the local address of the network connection. +func (p *Peer) LocalAddr() net.Addr { + return p.rw.fd.LocalAddr() +} + +// Disconnect terminates the peer connection with the given reason. +// It returns immediately and does not wait until the connection is closed. +func (p *Peer) Disconnect(reason DiscReason) { + select { + case p.disc <- reason: + case <-p.closed: + } +} + +// String implements fmt.Stringer. +func (p *Peer) String() string { + id := p.ID() + return fmt.Sprintf("Peer %x %v", id[:8], p.RemoteAddr()) +} + +// Inbound returns true if the peer is an inbound connection +func (p *Peer) Inbound() bool { + return p.rw.is(inboundConn) +} + +func newPeer(log log.Logger, conn *conn, protocols []Protocol) *Peer { + protomap := matchProtocols(protocols, conn.caps, conn) + p := &Peer{ + rw: conn, + running: protomap, + created: mclock.Now(), + disc: make(chan DiscReason), + protoErr: make(chan error, len(protomap)+1), // protocols + pingLoop + closed: make(chan struct{}), + log: log.New("id", conn.node.ID(), "conn", conn.flags), + } + return p +} + +func (p *Peer) Log() log.Logger { + return p.log +} + +func (p *Peer) run() (remoteRequested bool, err error) { + var ( + writeStart = make(chan struct{}, 1) + writeErr = make(chan error, 1) + readErr = make(chan error, 1) + reason DiscReason // sent to the peer + ) + p.wg.Add(2) + go p.readLoop(readErr) + go p.pingLoop() + + // Start all protocol handlers. + writeStart <- struct{}{} + p.startProtocols(writeStart, writeErr) + + // Wait for an error or disconnect. +loop: + for { + select { + case err = <-writeErr: + // A write finished. Allow the next write to start if + // there was no error. + if err != nil { + reason = DiscNetworkError + break loop + } + writeStart <- struct{}{} + case err = <-readErr: + if r, ok := err.(DiscReason); ok { + remoteRequested = true + reason = r + } else { + reason = DiscNetworkError + } + break loop + case err = <-p.protoErr: + reason = discReasonForError(err) + break loop + case err = <-p.disc: + reason = discReasonForError(err) + break loop + } + } + + close(p.closed) + p.rw.close(reason) + p.wg.Wait() + return remoteRequested, err +} + +func (p *Peer) pingLoop() { + ping := time.NewTimer(pingInterval) + defer p.wg.Done() + defer ping.Stop() + for { + select { + case <-ping.C: + if err := SendItems(p.rw, pingMsg); err != nil { + p.protoErr <- err + return + } + ping.Reset(pingInterval) + case <-p.closed: + return + } + } +} + +func (p *Peer) readLoop(errc chan<- error) { + defer p.wg.Done() + for { + msg, err := p.rw.ReadMsg() + if err != nil { + errc <- err + return + } + msg.ReceivedAt = time.Now() + if err = p.handle(msg); err != nil { + errc <- err + return + } + } +} + +func (p *Peer) handle(msg Msg) error { + switch { + case msg.Code == pingMsg: + msg.Discard() + go SendItems(p.rw, pongMsg) + case msg.Code == discMsg: + var reason [1]DiscReason + // This is the last message. We don't need to discard or + // check errors because, the connection will be closed after it. + rlp.Decode(msg.Payload, &reason) + return reason[0] + case msg.Code < baseProtocolLength: + // ignore other base protocol messages + return msg.Discard() + default: + // it's a subprotocol message + proto, err := p.getProto(msg.Code) + if err != nil { + return fmt.Errorf("msg code out of range: %v", msg.Code) + } + select { + case proto.in <- msg: + return nil + case <-p.closed: + return io.EOF + } + } + return nil +} + +func countMatchingProtocols(protocols []Protocol, caps []Cap) int { + n := 0 + for _, cap := range caps { + for _, proto := range protocols { + if proto.Name == cap.Name && proto.Version == cap.Version { + n++ + } + } + } + return n +} + +// matchProtocols creates structures for matching named subprotocols. +func matchProtocols(protocols []Protocol, caps []Cap, rw MsgReadWriter) map[string]*protoRW { + sort.Sort(capsByNameAndVersion(caps)) + offset := baseProtocolLength + result := make(map[string]*protoRW) + +outer: + for _, cap := range caps { + for _, proto := range protocols { + if proto.Name == cap.Name && proto.Version == cap.Version { + // If an old protocol version matched, revert it + if old := result[cap.Name]; old != nil { + offset -= old.Length + } + // Assign the new match + result[cap.Name] = &protoRW{Protocol: proto, offset: offset, in: make(chan Msg), w: rw} + offset += proto.Length + + continue outer + } + } + } + return result +} + +func (p *Peer) startProtocols(writeStart <-chan struct{}, writeErr chan<- error) { + p.wg.Add(len(p.running)) + for _, proto := range p.running { + proto := proto + proto.closed = p.closed + proto.wstart = writeStart + proto.werr = writeErr + var rw MsgReadWriter = proto + if p.events != nil { + rw = newMsgEventer(rw, p.events, p.ID(), proto.Name) + } + p.log.Trace(fmt.Sprintf("Starting protocol %s/%d", proto.Name, proto.Version)) + go func() { + err := proto.Run(p, rw) + if err == nil { + p.log.Trace(fmt.Sprintf("Protocol %s/%d returned", proto.Name, proto.Version)) + err = errProtocolReturned + } else if err != io.EOF { + p.log.Trace(fmt.Sprintf("Protocol %s/%d failed", proto.Name, proto.Version), "err", err) + } + p.protoErr <- err + p.wg.Done() + }() + } +} + +// getProto finds the protocol responsible for handling +// the given message code. +func (p *Peer) getProto(code uint64) (*protoRW, error) { + for _, proto := range p.running { + if code >= proto.offset && code < proto.offset+proto.Length { + return proto, nil + } + } + return nil, newPeerError(errInvalidMsgCode, "%d", code) +} + +type protoRW struct { + Protocol + in chan Msg // receives read messages + closed <-chan struct{} // receives when peer is shutting down + wstart <-chan struct{} // receives when write may start + werr chan<- error // for write results + offset uint64 + w MsgWriter +} + +func (rw *protoRW) WriteMsg(msg Msg) (err error) { + if msg.Code >= rw.Length { + return newPeerError(errInvalidMsgCode, "not handled") + } + msg.Code += rw.offset + select { + case <-rw.wstart: + err = rw.w.WriteMsg(msg) + // Report write status back to Peer.run. It will initiate + // shutdown if the error is non-nil and unblock the next write + // otherwise. The calling protocol code should exit for errors + // as well but we don't want to rely on that. + rw.werr <- err + case <-rw.closed: + err = ErrShuttingDown + } + return err +} + +func (rw *protoRW) ReadMsg() (Msg, error) { + select { + case msg := <-rw.in: + msg.Code -= rw.offset + return msg, nil + case <-rw.closed: + return Msg{}, io.EOF + } +} + +// PeerInfo represents a short summary of the information known about a connected +// peer. Sub-protocol independent fields are contained and initialized here, with +// protocol specifics delegated to all connected sub-protocols. +type PeerInfo struct { + Enode string `json:"enode"` // Node URL + ID string `json:"id"` // Unique node identifier + Name string `json:"name"` // Name of the node, including client type, version, OS, custom data + Caps []string `json:"caps"` // Protocols advertised by this peer + Network struct { + LocalAddress string `json:"localAddress"` // Local endpoint of the TCP data connection + RemoteAddress string `json:"remoteAddress"` // Remote endpoint of the TCP data connection + Inbound bool `json:"inbound"` + Trusted bool `json:"trusted"` + Static bool `json:"static"` + } `json:"network"` + Protocols map[string]interface{} `json:"protocols"` // Sub-protocol specific metadata fields +} + +// Info gathers and returns a collection of metadata known about a peer. +func (p *Peer) Info() *PeerInfo { + // Gather the protocol capabilities + var caps []string + for _, cap := range p.Caps() { + caps = append(caps, cap.String()) + } + // Assemble the generic peer metadata + info := &PeerInfo{ + Enode: p.Node().String(), + ID: p.ID().String(), + Name: p.Name(), + Caps: caps, + Protocols: make(map[string]interface{}), + } + info.Network.LocalAddress = p.LocalAddr().String() + info.Network.RemoteAddress = p.RemoteAddr().String() + info.Network.Inbound = p.rw.is(inboundConn) + info.Network.Trusted = p.rw.is(trustedConn) + info.Network.Static = p.rw.is(staticDialedConn) + + // Gather all the running protocol infos + for _, proto := range p.running { + protoInfo := interface{}("unknown") + if query := proto.Protocol.PeerInfo; query != nil { + if metadata := query(p.ID()); metadata != nil { + protoInfo = metadata + } else { + protoInfo = "handshake" + } + } + info.Protocols[proto.Name] = protoInfo + } + return info +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/rlpx.go b/vendor/github.com/ethereum/go-ethereum/p2p/rlpx.go new file mode 100644 index 00000000..0636431f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/rlpx.go @@ -0,0 +1,733 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package p2p + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/hmac" + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + "hash" + "io" + "io/ioutil" + mrand "math/rand" + "net" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/bitutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/ecies" + "github.com/ethereum/go-ethereum/rlp" + "github.com/golang/snappy" + "golang.org/x/crypto/sha3" +) + +const ( + maxUint24 = ^uint32(0) >> 8 + + sskLen = 16 // ecies.MaxSharedKeyLength(pubKey) / 2 + sigLen = 65 // elliptic S256 + pubLen = 64 // 512 bit pubkey in uncompressed representation without format byte + shaLen = 32 // hash length (for nonce etc) + + authMsgLen = sigLen + shaLen + pubLen + shaLen + 1 + authRespLen = pubLen + shaLen + 1 + + eciesOverhead = 65 /* pubkey */ + 16 /* IV */ + 32 /* MAC */ + + encAuthMsgLen = authMsgLen + eciesOverhead // size of encrypted pre-EIP-8 initiator handshake + encAuthRespLen = authRespLen + eciesOverhead // size of encrypted pre-EIP-8 handshake reply + + // total timeout for encryption handshake and protocol + // handshake in both directions. + handshakeTimeout = 5 * time.Second + + // This is the timeout for sending the disconnect reason. + // This is shorter than the usual timeout because we don't want + // to wait if the connection is known to be bad anyway. + discWriteTimeout = 1 * time.Second +) + +// errPlainMessageTooLarge is returned if a decompressed message length exceeds +// the allowed 24 bits (i.e. length >= 16MB). +var errPlainMessageTooLarge = errors.New("message length >= 16MB") + +// rlpx is the transport protocol used by actual (non-test) connections. +// It wraps the frame encoder with locks and read/write deadlines. +type rlpx struct { + fd net.Conn + + rmu, wmu sync.Mutex + rw *rlpxFrameRW +} + +func newRLPX(fd net.Conn) transport { + fd.SetDeadline(time.Now().Add(handshakeTimeout)) + return &rlpx{fd: fd} +} + +func (t *rlpx) ReadMsg() (Msg, error) { + t.rmu.Lock() + defer t.rmu.Unlock() + t.fd.SetReadDeadline(time.Now().Add(frameReadTimeout)) + return t.rw.ReadMsg() +} + +func (t *rlpx) WriteMsg(msg Msg) error { + t.wmu.Lock() + defer t.wmu.Unlock() + t.fd.SetWriteDeadline(time.Now().Add(frameWriteTimeout)) + return t.rw.WriteMsg(msg) +} + +func (t *rlpx) close(err error) { + t.wmu.Lock() + defer t.wmu.Unlock() + // Tell the remote end why we're disconnecting if possible. + if t.rw != nil { + if r, ok := err.(DiscReason); ok && r != DiscNetworkError { + // rlpx tries to send DiscReason to disconnected peer + // if the connection is net.Pipe (in-memory simulation) + // it hangs forever, since net.Pipe does not implement + // a write deadline. Because of this only try to send + // the disconnect reason message if there is no error. + if err := t.fd.SetWriteDeadline(time.Now().Add(discWriteTimeout)); err == nil { + SendItems(t.rw, discMsg, r) + } + } + } + t.fd.Close() +} + +func (t *rlpx) doProtoHandshake(our *protoHandshake) (their *protoHandshake, err error) { + // Writing our handshake happens concurrently, we prefer + // returning the handshake read error. If the remote side + // disconnects us early with a valid reason, we should return it + // as the error so it can be tracked elsewhere. + werr := make(chan error, 1) + go func() { werr <- Send(t.rw, handshakeMsg, our) }() + if their, err = readProtocolHandshake(t.rw); err != nil { + <-werr // make sure the write terminates too + return nil, err + } + if err := <-werr; err != nil { + return nil, fmt.Errorf("write error: %v", err) + } + // If the protocol version supports Snappy encoding, upgrade immediately + t.rw.snappy = their.Version >= snappyProtocolVersion + + return their, nil +} + +func readProtocolHandshake(rw MsgReader) (*protoHandshake, error) { + msg, err := rw.ReadMsg() + if err != nil { + return nil, err + } + if msg.Size > baseProtocolMaxMsgSize { + return nil, fmt.Errorf("message too big") + } + if msg.Code == discMsg { + // Disconnect before protocol handshake is valid according to the + // spec and we send it ourself if the post-handshake checks fail. + // We can't return the reason directly, though, because it is echoed + // back otherwise. Wrap it in a string instead. + var reason [1]DiscReason + rlp.Decode(msg.Payload, &reason) + return nil, reason[0] + } + if msg.Code != handshakeMsg { + return nil, fmt.Errorf("expected handshake, got %x", msg.Code) + } + var hs protoHandshake + if err := msg.Decode(&hs); err != nil { + return nil, err + } + if len(hs.ID) != 64 || !bitutil.TestBytes(hs.ID) { + return nil, DiscInvalidIdentity + } + return &hs, nil +} + +// doEncHandshake runs the protocol handshake using authenticated +// messages. the protocol handshake is the first authenticated message +// and also verifies whether the encryption handshake 'worked' and the +// remote side actually provided the right public key. +func (t *rlpx) doEncHandshake(prv *ecdsa.PrivateKey, dial *ecdsa.PublicKey) (*ecdsa.PublicKey, error) { + var ( + sec secrets + err error + ) + if dial == nil { + sec, err = receiverEncHandshake(t.fd, prv) + } else { + sec, err = initiatorEncHandshake(t.fd, prv, dial) + } + if err != nil { + return nil, err + } + t.wmu.Lock() + t.rw = newRLPXFrameRW(t.fd, sec) + t.wmu.Unlock() + return sec.Remote.ExportECDSA(), nil +} + +// encHandshake contains the state of the encryption handshake. +type encHandshake struct { + initiator bool + remote *ecies.PublicKey // remote-pubk + initNonce, respNonce []byte // nonce + randomPrivKey *ecies.PrivateKey // ecdhe-random + remoteRandomPub *ecies.PublicKey // ecdhe-random-pubk +} + +// secrets represents the connection secrets +// which are negotiated during the encryption handshake. +type secrets struct { + Remote *ecies.PublicKey + AES, MAC []byte + EgressMAC, IngressMAC hash.Hash + Token []byte +} + +// RLPx v4 handshake auth (defined in EIP-8). +type authMsgV4 struct { + gotPlain bool // whether read packet had plain format. + + Signature [sigLen]byte + InitiatorPubkey [pubLen]byte + Nonce [shaLen]byte + Version uint + + // Ignore additional fields (forward-compatibility) + Rest []rlp.RawValue `rlp:"tail"` +} + +// RLPx v4 handshake response (defined in EIP-8). +type authRespV4 struct { + RandomPubkey [pubLen]byte + Nonce [shaLen]byte + Version uint + + // Ignore additional fields (forward-compatibility) + Rest []rlp.RawValue `rlp:"tail"` +} + +// secrets is called after the handshake is completed. +// It extracts the connection secrets from the handshake values. +func (h *encHandshake) secrets(auth, authResp []byte) (secrets, error) { + ecdheSecret, err := h.randomPrivKey.GenerateShared(h.remoteRandomPub, sskLen, sskLen) + if err != nil { + return secrets{}, err + } + + // derive base secrets from ephemeral key agreement + sharedSecret := crypto.Keccak256(ecdheSecret, crypto.Keccak256(h.respNonce, h.initNonce)) + aesSecret := crypto.Keccak256(ecdheSecret, sharedSecret) + s := secrets{ + Remote: h.remote, + AES: aesSecret, + MAC: crypto.Keccak256(ecdheSecret, aesSecret), + } + + // setup sha3 instances for the MACs + mac1 := sha3.NewLegacyKeccak256() + mac1.Write(xor(s.MAC, h.respNonce)) + mac1.Write(auth) + mac2 := sha3.NewLegacyKeccak256() + mac2.Write(xor(s.MAC, h.initNonce)) + mac2.Write(authResp) + if h.initiator { + s.EgressMAC, s.IngressMAC = mac1, mac2 + } else { + s.EgressMAC, s.IngressMAC = mac2, mac1 + } + + return s, nil +} + +// staticSharedSecret returns the static shared secret, the result +// of key agreement between the local and remote static node key. +func (h *encHandshake) staticSharedSecret(prv *ecdsa.PrivateKey) ([]byte, error) { + return ecies.ImportECDSA(prv).GenerateShared(h.remote, sskLen, sskLen) +} + +// initiatorEncHandshake negotiates a session token on conn. +// it should be called on the dialing side of the connection. +// +// prv is the local client's private key. +func initiatorEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s secrets, err error) { + h := &encHandshake{initiator: true, remote: ecies.ImportECDSAPublic(remote)} + authMsg, err := h.makeAuthMsg(prv) + if err != nil { + return s, err + } + authPacket, err := sealEIP8(authMsg, h) + if err != nil { + return s, err + } + if _, err = conn.Write(authPacket); err != nil { + return s, err + } + + authRespMsg := new(authRespV4) + authRespPacket, err := readHandshakeMsg(authRespMsg, encAuthRespLen, prv, conn) + if err != nil { + return s, err + } + if err := h.handleAuthResp(authRespMsg); err != nil { + return s, err + } + return h.secrets(authPacket, authRespPacket) +} + +// makeAuthMsg creates the initiator handshake message. +func (h *encHandshake) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) { + // Generate random initiator nonce. + h.initNonce = make([]byte, shaLen) + _, err := rand.Read(h.initNonce) + if err != nil { + return nil, err + } + // Generate random keypair to for ECDH. + h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil) + if err != nil { + return nil, err + } + + // Sign known message: static-shared-secret ^ nonce + token, err := h.staticSharedSecret(prv) + if err != nil { + return nil, err + } + signed := xor(token, h.initNonce) + signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA()) + if err != nil { + return nil, err + } + + msg := new(authMsgV4) + copy(msg.Signature[:], signature) + copy(msg.InitiatorPubkey[:], crypto.FromECDSAPub(&prv.PublicKey)[1:]) + copy(msg.Nonce[:], h.initNonce) + msg.Version = 4 + return msg, nil +} + +func (h *encHandshake) handleAuthResp(msg *authRespV4) (err error) { + h.respNonce = msg.Nonce[:] + h.remoteRandomPub, err = importPublicKey(msg.RandomPubkey[:]) + return err +} + +// receiverEncHandshake negotiates a session token on conn. +// it should be called on the listening side of the connection. +// +// prv is the local client's private key. +func receiverEncHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s secrets, err error) { + authMsg := new(authMsgV4) + authPacket, err := readHandshakeMsg(authMsg, encAuthMsgLen, prv, conn) + if err != nil { + return s, err + } + h := new(encHandshake) + if err := h.handleAuthMsg(authMsg, prv); err != nil { + return s, err + } + + authRespMsg, err := h.makeAuthResp() + if err != nil { + return s, err + } + var authRespPacket []byte + if authMsg.gotPlain { + authRespPacket, err = authRespMsg.sealPlain(h) + } else { + authRespPacket, err = sealEIP8(authRespMsg, h) + } + if err != nil { + return s, err + } + if _, err = conn.Write(authRespPacket); err != nil { + return s, err + } + return h.secrets(authPacket, authRespPacket) +} + +func (h *encHandshake) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) error { + // Import the remote identity. + rpub, err := importPublicKey(msg.InitiatorPubkey[:]) + if err != nil { + return err + } + h.initNonce = msg.Nonce[:] + h.remote = rpub + + // Generate random keypair for ECDH. + // If a private key is already set, use it instead of generating one (for testing). + if h.randomPrivKey == nil { + h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil) + if err != nil { + return err + } + } + + // Check the signature. + token, err := h.staticSharedSecret(prv) + if err != nil { + return err + } + signedMsg := xor(token, h.initNonce) + remoteRandomPub, err := crypto.Ecrecover(signedMsg, msg.Signature[:]) + if err != nil { + return err + } + h.remoteRandomPub, _ = importPublicKey(remoteRandomPub) + return nil +} + +func (h *encHandshake) makeAuthResp() (msg *authRespV4, err error) { + // Generate random nonce. + h.respNonce = make([]byte, shaLen) + if _, err = rand.Read(h.respNonce); err != nil { + return nil, err + } + + msg = new(authRespV4) + copy(msg.Nonce[:], h.respNonce) + copy(msg.RandomPubkey[:], exportPubkey(&h.randomPrivKey.PublicKey)) + msg.Version = 4 + return msg, nil +} + +func (msg *authMsgV4) sealPlain(h *encHandshake) ([]byte, error) { + buf := make([]byte, authMsgLen) + n := copy(buf, msg.Signature[:]) + n += copy(buf[n:], crypto.Keccak256(exportPubkey(&h.randomPrivKey.PublicKey))) + n += copy(buf[n:], msg.InitiatorPubkey[:]) + n += copy(buf[n:], msg.Nonce[:]) + buf[n] = 0 // token-flag + return ecies.Encrypt(rand.Reader, h.remote, buf, nil, nil) +} + +func (msg *authMsgV4) decodePlain(input []byte) { + n := copy(msg.Signature[:], input) + n += shaLen // skip sha3(initiator-ephemeral-pubk) + n += copy(msg.InitiatorPubkey[:], input[n:]) + copy(msg.Nonce[:], input[n:]) + msg.Version = 4 + msg.gotPlain = true +} + +func (msg *authRespV4) sealPlain(hs *encHandshake) ([]byte, error) { + buf := make([]byte, authRespLen) + n := copy(buf, msg.RandomPubkey[:]) + copy(buf[n:], msg.Nonce[:]) + return ecies.Encrypt(rand.Reader, hs.remote, buf, nil, nil) +} + +func (msg *authRespV4) decodePlain(input []byte) { + n := copy(msg.RandomPubkey[:], input) + copy(msg.Nonce[:], input[n:]) + msg.Version = 4 +} + +var padSpace = make([]byte, 300) + +func sealEIP8(msg interface{}, h *encHandshake) ([]byte, error) { + buf := new(bytes.Buffer) + if err := rlp.Encode(buf, msg); err != nil { + return nil, err + } + // pad with random amount of data. the amount needs to be at least 100 bytes to make + // the message distinguishable from pre-EIP-8 handshakes. + pad := padSpace[:mrand.Intn(len(padSpace)-100)+100] + buf.Write(pad) + prefix := make([]byte, 2) + binary.BigEndian.PutUint16(prefix, uint16(buf.Len()+eciesOverhead)) + + enc, err := ecies.Encrypt(rand.Reader, h.remote, buf.Bytes(), nil, prefix) + return append(prefix, enc...), err +} + +type plainDecoder interface { + decodePlain([]byte) +} + +func readHandshakeMsg(msg plainDecoder, plainSize int, prv *ecdsa.PrivateKey, r io.Reader) ([]byte, error) { + buf := make([]byte, plainSize) + if _, err := io.ReadFull(r, buf); err != nil { + return buf, err + } + // Attempt decoding pre-EIP-8 "plain" format. + key := ecies.ImportECDSA(prv) + if dec, err := key.Decrypt(buf, nil, nil); err == nil { + msg.decodePlain(dec) + return buf, nil + } + // Could be EIP-8 format, try that. + prefix := buf[:2] + size := binary.BigEndian.Uint16(prefix) + if size < uint16(plainSize) { + return buf, fmt.Errorf("size underflow, need at least %d bytes", plainSize) + } + buf = append(buf, make([]byte, size-uint16(plainSize)+2)...) + if _, err := io.ReadFull(r, buf[plainSize:]); err != nil { + return buf, err + } + dec, err := key.Decrypt(buf[2:], nil, prefix) + if err != nil { + return buf, err + } + // Can't use rlp.DecodeBytes here because it rejects + // trailing data (forward-compatibility). + s := rlp.NewStream(bytes.NewReader(dec), 0) + return buf, s.Decode(msg) +} + +// importPublicKey unmarshals 512 bit public keys. +func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) { + var pubKey65 []byte + switch len(pubKey) { + case 64: + // add 'uncompressed key' flag + pubKey65 = append([]byte{0x04}, pubKey...) + case 65: + pubKey65 = pubKey + default: + return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey)) + } + // TODO: fewer pointless conversions + pub, err := crypto.UnmarshalPubkey(pubKey65) + if err != nil { + return nil, err + } + return ecies.ImportECDSAPublic(pub), nil +} + +func exportPubkey(pub *ecies.PublicKey) []byte { + if pub == nil { + panic("nil pubkey") + } + return elliptic.Marshal(pub.Curve, pub.X, pub.Y)[1:] +} + +func xor(one, other []byte) (xor []byte) { + xor = make([]byte, len(one)) + for i := 0; i < len(one); i++ { + xor[i] = one[i] ^ other[i] + } + return xor +} + +var ( + // this is used in place of actual frame header data. + // TODO: replace this when Msg contains the protocol type code. + zeroHeader = []byte{0xC2, 0x80, 0x80} + // sixteen zero bytes + zero16 = make([]byte, 16) +) + +// rlpxFrameRW implements a simplified version of RLPx framing. +// chunked messages are not supported and all headers are equal to +// zeroHeader. +// +// rlpxFrameRW is not safe for concurrent use from multiple goroutines. +type rlpxFrameRW struct { + conn io.ReadWriter + enc cipher.Stream + dec cipher.Stream + + macCipher cipher.Block + egressMAC hash.Hash + ingressMAC hash.Hash + + snappy bool +} + +func newRLPXFrameRW(conn io.ReadWriter, s secrets) *rlpxFrameRW { + macc, err := aes.NewCipher(s.MAC) + if err != nil { + panic("invalid MAC secret: " + err.Error()) + } + encc, err := aes.NewCipher(s.AES) + if err != nil { + panic("invalid AES secret: " + err.Error()) + } + // we use an all-zeroes IV for AES because the key used + // for encryption is ephemeral. + iv := make([]byte, encc.BlockSize()) + return &rlpxFrameRW{ + conn: conn, + enc: cipher.NewCTR(encc, iv), + dec: cipher.NewCTR(encc, iv), + macCipher: macc, + egressMAC: s.EgressMAC, + ingressMAC: s.IngressMAC, + } +} + +func (rw *rlpxFrameRW) WriteMsg(msg Msg) error { + ptype, _ := rlp.EncodeToBytes(msg.Code) + + // if snappy is enabled, compress message now + if rw.snappy { + if msg.Size > maxUint24 { + return errPlainMessageTooLarge + } + payload, _ := ioutil.ReadAll(msg.Payload) + payload = snappy.Encode(nil, payload) + + msg.Payload = bytes.NewReader(payload) + msg.Size = uint32(len(payload)) + } + // write header + headbuf := make([]byte, 32) + fsize := uint32(len(ptype)) + msg.Size + if fsize > maxUint24 { + return errors.New("message size overflows uint24") + } + putInt24(fsize, headbuf) // TODO: check overflow + copy(headbuf[3:], zeroHeader) + rw.enc.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now encrypted + + // write header MAC + copy(headbuf[16:], updateMAC(rw.egressMAC, rw.macCipher, headbuf[:16])) + if _, err := rw.conn.Write(headbuf); err != nil { + return err + } + + // write encrypted frame, updating the egress MAC hash with + // the data written to conn. + tee := cipher.StreamWriter{S: rw.enc, W: io.MultiWriter(rw.conn, rw.egressMAC)} + if _, err := tee.Write(ptype); err != nil { + return err + } + if _, err := io.Copy(tee, msg.Payload); err != nil { + return err + } + if padding := fsize % 16; padding > 0 { + if _, err := tee.Write(zero16[:16-padding]); err != nil { + return err + } + } + + // write frame MAC. egress MAC hash is up to date because + // frame content was written to it as well. + fmacseed := rw.egressMAC.Sum(nil) + mac := updateMAC(rw.egressMAC, rw.macCipher, fmacseed) + _, err := rw.conn.Write(mac) + return err +} + +func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) { + // read the header + headbuf := make([]byte, 32) + if _, err := io.ReadFull(rw.conn, headbuf); err != nil { + return msg, err + } + // verify header mac + shouldMAC := updateMAC(rw.ingressMAC, rw.macCipher, headbuf[:16]) + if !hmac.Equal(shouldMAC, headbuf[16:]) { + return msg, errors.New("bad header MAC") + } + rw.dec.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now decrypted + fsize := readInt24(headbuf) + // ignore protocol type for now + + // read the frame content + var rsize = fsize // frame size rounded up to 16 byte boundary + if padding := fsize % 16; padding > 0 { + rsize += 16 - padding + } + framebuf := make([]byte, rsize) + if _, err := io.ReadFull(rw.conn, framebuf); err != nil { + return msg, err + } + + // read and validate frame MAC. we can re-use headbuf for that. + rw.ingressMAC.Write(framebuf) + fmacseed := rw.ingressMAC.Sum(nil) + if _, err := io.ReadFull(rw.conn, headbuf[:16]); err != nil { + return msg, err + } + shouldMAC = updateMAC(rw.ingressMAC, rw.macCipher, fmacseed) + if !hmac.Equal(shouldMAC, headbuf[:16]) { + return msg, errors.New("bad frame MAC") + } + + // decrypt frame content + rw.dec.XORKeyStream(framebuf, framebuf) + + // decode message code + content := bytes.NewReader(framebuf[:fsize]) + if err := rlp.Decode(content, &msg.Code); err != nil { + return msg, err + } + msg.Size = uint32(content.Len()) + msg.Payload = content + + // if snappy is enabled, verify and decompress message + if rw.snappy { + payload, err := ioutil.ReadAll(msg.Payload) + if err != nil { + return msg, err + } + size, err := snappy.DecodedLen(payload) + if err != nil { + return msg, err + } + if size > int(maxUint24) { + return msg, errPlainMessageTooLarge + } + payload, err = snappy.Decode(nil, payload) + if err != nil { + return msg, err + } + msg.Size, msg.Payload = uint32(size), bytes.NewReader(payload) + } + return msg, nil +} + +// updateMAC reseeds the given hash with encrypted seed. +// it returns the first 16 bytes of the hash sum after seeding. +func updateMAC(mac hash.Hash, block cipher.Block, seed []byte) []byte { + aesbuf := make([]byte, aes.BlockSize) + block.Encrypt(aesbuf, mac.Sum(nil)) + for i := range aesbuf { + aesbuf[i] ^= seed[i] + } + mac.Write(aesbuf) + return mac.Sum(nil)[:16] +} + +func readInt24(b []byte) uint32 { + return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16 +} + +func putInt24(v uint32, b []byte) { + b[0] = byte(v >> 16) + b[1] = byte(v >> 8) + b[2] = byte(v) +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/server.go b/vendor/github.com/ethereum/go-ethereum/p2p/server.go new file mode 100644 index 00000000..a373904f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/server.go @@ -0,0 +1,1100 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package p2p implements the Ethereum p2p network protocols. +package p2p + +import ( + "bytes" + "crypto/ecdsa" + "encoding/hex" + "errors" + "fmt" + "net" + "sort" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/discv5" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" +) + +const ( + defaultDialTimeout = 15 * time.Second + + // Connectivity defaults. + maxActiveDialTasks = 16 + defaultMaxPendingPeers = 50 + defaultDialRatio = 3 + + // This time limits inbound connection attempts per source IP. + inboundThrottleTime = 30 * time.Second + + // Maximum time allowed for reading a complete message. + // This is effectively the amount of time a connection can be idle. + frameReadTimeout = 30 * time.Second + + // Maximum amount of time allowed for writing a complete message. + frameWriteTimeout = 20 * time.Second +) + +var errServerStopped = errors.New("server stopped") + +// Config holds Server options. +type Config struct { + // This field must be set to a valid secp256k1 private key. + PrivateKey *ecdsa.PrivateKey `toml:"-"` + + // MaxPeers is the maximum number of peers that can be + // connected. It must be greater than zero. + MaxPeers int + + // MaxPendingPeers is the maximum number of peers that can be pending in the + // handshake phase, counted separately for inbound and outbound connections. + // Zero defaults to preset values. + MaxPendingPeers int `toml:",omitempty"` + + // DialRatio controls the ratio of inbound to dialed connections. + // Example: a DialRatio of 2 allows 1/2 of connections to be dialed. + // Setting DialRatio to zero defaults it to 3. + DialRatio int `toml:",omitempty"` + + // NoDiscovery can be used to disable the peer discovery mechanism. + // Disabling is useful for protocol debugging (manual topology). + NoDiscovery bool + + // DiscoveryV5 specifies whether the new topic-discovery based V5 discovery + // protocol should be started or not. + DiscoveryV5 bool `toml:",omitempty"` + + // Name sets the node name of this server. + // Use common.MakeName to create a name that follows existing conventions. + Name string `toml:"-"` + + // BootstrapNodes are used to establish connectivity + // with the rest of the network. + BootstrapNodes []*enode.Node + + // BootstrapNodesV5 are used to establish connectivity + // with the rest of the network using the V5 discovery + // protocol. + BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` + + // Static nodes are used as pre-configured connections which are always + // maintained and re-connected on disconnects. + StaticNodes []*enode.Node + + // Trusted nodes are used as pre-configured connections which are always + // allowed to connect, even above the peer limit. + TrustedNodes []*enode.Node + + // Connectivity can be restricted to certain IP networks. + // If this option is set to a non-nil value, only hosts which match one of the + // IP networks contained in the list are considered. + NetRestrict *netutil.Netlist `toml:",omitempty"` + + // NodeDatabase is the path to the database containing the previously seen + // live nodes in the network. + NodeDatabase string `toml:",omitempty"` + + // Protocols should contain the protocols supported + // by the server. Matching protocols are launched for + // each peer. + Protocols []Protocol `toml:"-"` + + // If ListenAddr is set to a non-nil address, the server + // will listen for incoming connections. + // + // If the port is zero, the operating system will pick a port. The + // ListenAddr field will be updated with the actual address when + // the server is started. + ListenAddr string + + // If set to a non-nil value, the given NAT port mapper + // is used to make the listening port available to the + // Internet. + NAT nat.Interface `toml:",omitempty"` + + // If Dialer is set to a non-nil value, the given Dialer + // is used to dial outbound peer connections. + Dialer NodeDialer `toml:"-"` + + // If NoDial is true, the server will not dial any peers. + NoDial bool `toml:",omitempty"` + + // If EnableMsgEvents is set then the server will emit PeerEvents + // whenever a message is sent to or received from a peer + EnableMsgEvents bool + + // Logger is a custom logger to use with the p2p.Server. + Logger log.Logger `toml:",omitempty"` +} + +// Server manages all peer connections. +type Server struct { + // Config fields may not be modified while the server is running. + Config + + // Hooks for testing. These are useful because we can inhibit + // the whole protocol stack. + newTransport func(net.Conn) transport + newPeerHook func(*Peer) + listenFunc func(network, addr string) (net.Listener, error) + + lock sync.Mutex // protects running + running bool + + nodedb *enode.DB + localnode *enode.LocalNode + ntab discoverTable + listener net.Listener + ourHandshake *protoHandshake + DiscV5 *discv5.Network + loopWG sync.WaitGroup // loop, listenLoop + peerFeed event.Feed + log log.Logger + + // Channels into the run loop. + quit chan struct{} + addstatic chan *enode.Node + removestatic chan *enode.Node + addtrusted chan *enode.Node + removetrusted chan *enode.Node + peerOp chan peerOpFunc + peerOpDone chan struct{} + delpeer chan peerDrop + checkpointPostHandshake chan *conn + checkpointAddPeer chan *conn + + // State of run loop and listenLoop. + lastLookup time.Time + inboundHistory expHeap +} + +type peerOpFunc func(map[enode.ID]*Peer) + +type peerDrop struct { + *Peer + err error + requested bool // true if signaled by the peer +} + +type connFlag int32 + +const ( + dynDialedConn connFlag = 1 << iota + staticDialedConn + inboundConn + trustedConn +) + +// conn wraps a network connection with information gathered +// during the two handshakes. +type conn struct { + fd net.Conn + transport + node *enode.Node + flags connFlag + cont chan error // The run loop uses cont to signal errors to SetupConn. + caps []Cap // valid after the protocol handshake + name string // valid after the protocol handshake +} + +type transport interface { + // The two handshakes. + doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) + doProtoHandshake(our *protoHandshake) (*protoHandshake, error) + // The MsgReadWriter can only be used after the encryption + // handshake has completed. The code uses conn.id to track this + // by setting it to a non-nil value after the encryption handshake. + MsgReadWriter + // transports must provide Close because we use MsgPipe in some of + // the tests. Closing the actual network connection doesn't do + // anything in those tests because MsgPipe doesn't use it. + close(err error) +} + +func (c *conn) String() string { + s := c.flags.String() + if (c.node.ID() != enode.ID{}) { + s += " " + c.node.ID().String() + } + s += " " + c.fd.RemoteAddr().String() + return s +} + +func (f connFlag) String() string { + s := "" + if f&trustedConn != 0 { + s += "-trusted" + } + if f&dynDialedConn != 0 { + s += "-dyndial" + } + if f&staticDialedConn != 0 { + s += "-staticdial" + } + if f&inboundConn != 0 { + s += "-inbound" + } + if s != "" { + s = s[1:] + } + return s +} + +func (c *conn) is(f connFlag) bool { + flags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) + return flags&f != 0 +} + +func (c *conn) set(f connFlag, val bool) { + for { + oldFlags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) + flags := oldFlags + if val { + flags |= f + } else { + flags &= ^f + } + if atomic.CompareAndSwapInt32((*int32)(&c.flags), int32(oldFlags), int32(flags)) { + return + } + } +} + +// Peers returns all connected peers. +func (srv *Server) Peers() []*Peer { + var ps []*Peer + select { + // Note: We'd love to put this function into a variable but + // that seems to cause a weird compiler error in some + // environments. + case srv.peerOp <- func(peers map[enode.ID]*Peer) { + for _, p := range peers { + ps = append(ps, p) + } + }: + <-srv.peerOpDone + case <-srv.quit: + } + return ps +} + +// PeerCount returns the number of connected peers. +func (srv *Server) PeerCount() int { + var count int + select { + case srv.peerOp <- func(ps map[enode.ID]*Peer) { count = len(ps) }: + <-srv.peerOpDone + case <-srv.quit: + } + return count +} + +// AddPeer connects to the given node and maintains the connection until the +// server is shut down. If the connection fails for any reason, the server will +// attempt to reconnect the peer. +func (srv *Server) AddPeer(node *enode.Node) { + select { + case srv.addstatic <- node: + case <-srv.quit: + } +} + +// RemovePeer disconnects from the given node +func (srv *Server) RemovePeer(node *enode.Node) { + select { + case srv.removestatic <- node: + case <-srv.quit: + } +} + +// AddTrustedPeer adds the given node to a reserved whitelist which allows the +// node to always connect, even if the slot are full. +func (srv *Server) AddTrustedPeer(node *enode.Node) { + select { + case srv.addtrusted <- node: + case <-srv.quit: + } +} + +// RemoveTrustedPeer removes the given node from the trusted peer set. +func (srv *Server) RemoveTrustedPeer(node *enode.Node) { + select { + case srv.removetrusted <- node: + case <-srv.quit: + } +} + +// SubscribePeers subscribes the given channel to peer events +func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { + return srv.peerFeed.Subscribe(ch) +} + +// Self returns the local node's endpoint information. +func (srv *Server) Self() *enode.Node { + srv.lock.Lock() + ln := srv.localnode + srv.lock.Unlock() + + if ln == nil { + return enode.NewV4(&srv.PrivateKey.PublicKey, net.ParseIP("0.0.0.0"), 0, 0) + } + return ln.Node() +} + +// Stop terminates the server and all active peer connections. +// It blocks until all active connections have been closed. +func (srv *Server) Stop() { + srv.lock.Lock() + if !srv.running { + srv.lock.Unlock() + return + } + srv.running = false + if srv.listener != nil { + // this unblocks listener Accept + srv.listener.Close() + } + close(srv.quit) + srv.lock.Unlock() + srv.loopWG.Wait() +} + +// sharedUDPConn implements a shared connection. Write sends messages to the underlying connection while read returns +// messages that were found unprocessable and sent to the unhandled channel by the primary listener. +type sharedUDPConn struct { + *net.UDPConn + unhandled chan discover.ReadPacket +} + +// ReadFromUDP implements discv5.conn +func (s *sharedUDPConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { + packet, ok := <-s.unhandled + if !ok { + return 0, nil, errors.New("Connection was closed") + } + l := len(packet.Data) + if l > len(b) { + l = len(b) + } + copy(b[:l], packet.Data[:l]) + return l, packet.Addr, nil +} + +// Close implements discv5.conn +func (s *sharedUDPConn) Close() error { + return nil +} + +// Start starts running the server. +// Servers can not be re-used after stopping. +func (srv *Server) Start() (err error) { + srv.lock.Lock() + defer srv.lock.Unlock() + if srv.running { + return errors.New("server already running") + } + srv.running = true + srv.log = srv.Config.Logger + if srv.log == nil { + srv.log = log.Root() + } + if srv.NoDial && srv.ListenAddr == "" { + srv.log.Warn("P2P server will be useless, neither dialing nor listening") + } + + // static fields + if srv.PrivateKey == nil { + return errors.New("Server.PrivateKey must be set to a non-nil key") + } + if srv.newTransport == nil { + srv.newTransport = newRLPX + } + if srv.listenFunc == nil { + srv.listenFunc = net.Listen + } + if srv.Dialer == nil { + srv.Dialer = TCPDialer{&net.Dialer{Timeout: defaultDialTimeout}} + } + srv.quit = make(chan struct{}) + srv.delpeer = make(chan peerDrop) + srv.checkpointPostHandshake = make(chan *conn) + srv.checkpointAddPeer = make(chan *conn) + srv.addstatic = make(chan *enode.Node) + srv.removestatic = make(chan *enode.Node) + srv.addtrusted = make(chan *enode.Node) + srv.removetrusted = make(chan *enode.Node) + srv.peerOp = make(chan peerOpFunc) + srv.peerOpDone = make(chan struct{}) + + if err := srv.setupLocalNode(); err != nil { + return err + } + if srv.ListenAddr != "" { + if err := srv.setupListening(); err != nil { + return err + } + } + if err := srv.setupDiscovery(); err != nil { + return err + } + + dynPeers := srv.maxDialedConns() + dialer := newDialState(srv.localnode.ID(), srv.ntab, dynPeers, &srv.Config) + srv.loopWG.Add(1) + go srv.run(dialer) + return nil +} + +func (srv *Server) setupLocalNode() error { + // Create the devp2p handshake. + pubkey := crypto.FromECDSAPub(&srv.PrivateKey.PublicKey) + srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: pubkey[1:]} + for _, p := range srv.Protocols { + srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) + } + sort.Sort(capsByNameAndVersion(srv.ourHandshake.Caps)) + + // Create the local node. + db, err := enode.OpenDB(srv.Config.NodeDatabase) + if err != nil { + return err + } + srv.nodedb = db + srv.localnode = enode.NewLocalNode(db, srv.PrivateKey) + srv.localnode.SetFallbackIP(net.IP{127, 0, 0, 1}) + srv.localnode.Set(capsByNameAndVersion(srv.ourHandshake.Caps)) + // TODO: check conflicts + for _, p := range srv.Protocols { + for _, e := range p.Attributes { + srv.localnode.Set(e) + } + } + switch srv.NAT.(type) { + case nil: + // No NAT interface, do nothing. + case nat.ExtIP: + // ExtIP doesn't block, set the IP right away. + ip, _ := srv.NAT.ExternalIP() + srv.localnode.SetStaticIP(ip) + default: + // Ask the router about the IP. This takes a while and blocks startup, + // do it in the background. + srv.loopWG.Add(1) + go func() { + defer srv.loopWG.Done() + if ip, err := srv.NAT.ExternalIP(); err == nil { + srv.localnode.SetStaticIP(ip) + } + }() + } + return nil +} + +func (srv *Server) setupDiscovery() error { + if srv.NoDiscovery && !srv.DiscoveryV5 { + return nil + } + + addr, err := net.ResolveUDPAddr("udp", srv.ListenAddr) + if err != nil { + return err + } + conn, err := net.ListenUDP("udp", addr) + if err != nil { + return err + } + realaddr := conn.LocalAddr().(*net.UDPAddr) + srv.log.Debug("UDP listener up", "addr", realaddr) + if srv.NAT != nil { + if !realaddr.IP.IsLoopback() { + go nat.Map(srv.NAT, srv.quit, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") + } + } + srv.localnode.SetFallbackUDP(realaddr.Port) + + // Discovery V4 + var unhandled chan discover.ReadPacket + var sconn *sharedUDPConn + if !srv.NoDiscovery { + if srv.DiscoveryV5 { + unhandled = make(chan discover.ReadPacket, 100) + sconn = &sharedUDPConn{conn, unhandled} + } + cfg := discover.Config{ + PrivateKey: srv.PrivateKey, + NetRestrict: srv.NetRestrict, + Bootnodes: srv.BootstrapNodes, + Unhandled: unhandled, + Log: srv.log, + } + ntab, err := discover.ListenUDP(conn, srv.localnode, cfg) + if err != nil { + return err + } + srv.ntab = ntab + } + // Discovery V5 + if srv.DiscoveryV5 { + var ntab *discv5.Network + var err error + if sconn != nil { + ntab, err = discv5.ListenUDP(srv.PrivateKey, sconn, "", srv.NetRestrict) + } else { + ntab, err = discv5.ListenUDP(srv.PrivateKey, conn, "", srv.NetRestrict) + } + if err != nil { + return err + } + if err := ntab.SetFallbackNodes(srv.BootstrapNodesV5); err != nil { + return err + } + srv.DiscV5 = ntab + } + return nil +} + +func (srv *Server) setupListening() error { + // Launch the listener. + listener, err := srv.listenFunc("tcp", srv.ListenAddr) + if err != nil { + return err + } + srv.listener = listener + srv.ListenAddr = listener.Addr().String() + + // Update the local node record and map the TCP listening port if NAT is configured. + if tcp, ok := listener.Addr().(*net.TCPAddr); ok { + srv.localnode.Set(enr.TCP(tcp.Port)) + if !tcp.IP.IsLoopback() && srv.NAT != nil { + srv.loopWG.Add(1) + go func() { + nat.Map(srv.NAT, srv.quit, "tcp", tcp.Port, tcp.Port, "ethereum p2p") + srv.loopWG.Done() + }() + } + } + + srv.loopWG.Add(1) + go srv.listenLoop() + return nil +} + +type dialer interface { + newTasks(running int, peers map[enode.ID]*Peer, now time.Time) []task + taskDone(task, time.Time) + addStatic(*enode.Node) + removeStatic(*enode.Node) +} + +func (srv *Server) run(dialstate dialer) { + srv.log.Info("Started P2P networking", "self", srv.localnode.Node().URLv4()) + defer srv.loopWG.Done() + defer srv.nodedb.Close() + + var ( + peers = make(map[enode.ID]*Peer) + inboundCount = 0 + trusted = make(map[enode.ID]bool, len(srv.TrustedNodes)) + taskdone = make(chan task, maxActiveDialTasks) + runningTasks []task + queuedTasks []task // tasks that can't run yet + ) + // Put trusted nodes into a map to speed up checks. + // Trusted peers are loaded on startup or added via AddTrustedPeer RPC. + for _, n := range srv.TrustedNodes { + trusted[n.ID()] = true + } + + // removes t from runningTasks + delTask := func(t task) { + for i := range runningTasks { + if runningTasks[i] == t { + runningTasks = append(runningTasks[:i], runningTasks[i+1:]...) + break + } + } + } + // starts until max number of active tasks is satisfied + startTasks := func(ts []task) (rest []task) { + i := 0 + for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ { + t := ts[i] + srv.log.Trace("New dial task", "task", t) + go func() { t.Do(srv); taskdone <- t }() + runningTasks = append(runningTasks, t) + } + return ts[i:] + } + scheduleTasks := func() { + // Start from queue first. + queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...) + // Query dialer for new tasks and start as many as possible now. + if len(runningTasks) < maxActiveDialTasks { + nt := dialstate.newTasks(len(runningTasks)+len(queuedTasks), peers, time.Now()) + queuedTasks = append(queuedTasks, startTasks(nt)...) + } + } + +running: + for { + scheduleTasks() + + select { + case <-srv.quit: + // The server was stopped. Run the cleanup logic. + break running + + case n := <-srv.addstatic: + // This channel is used by AddPeer to add to the + // ephemeral static peer list. Add it to the dialer, + // it will keep the node connected. + srv.log.Trace("Adding static node", "node", n) + dialstate.addStatic(n) + + case n := <-srv.removestatic: + // This channel is used by RemovePeer to send a + // disconnect request to a peer and begin the + // stop keeping the node connected. + srv.log.Trace("Removing static node", "node", n) + dialstate.removeStatic(n) + if p, ok := peers[n.ID()]; ok { + p.Disconnect(DiscRequested) + } + + case n := <-srv.addtrusted: + // This channel is used by AddTrustedPeer to add an enode + // to the trusted node set. + srv.log.Trace("Adding trusted node", "node", n) + trusted[n.ID()] = true + // Mark any already-connected peer as trusted + if p, ok := peers[n.ID()]; ok { + p.rw.set(trustedConn, true) + } + + case n := <-srv.removetrusted: + // This channel is used by RemoveTrustedPeer to remove an enode + // from the trusted node set. + srv.log.Trace("Removing trusted node", "node", n) + delete(trusted, n.ID()) + + // Unmark any already-connected peer as trusted + if p, ok := peers[n.ID()]; ok { + p.rw.set(trustedConn, false) + } + + case op := <-srv.peerOp: + // This channel is used by Peers and PeerCount. + op(peers) + srv.peerOpDone <- struct{}{} + + case t := <-taskdone: + // A task got done. Tell dialstate about it so it + // can update its state and remove it from the active + // tasks list. + srv.log.Trace("Dial task done", "task", t) + dialstate.taskDone(t, time.Now()) + delTask(t) + + case c := <-srv.checkpointPostHandshake: + // A connection has passed the encryption handshake so + // the remote identity is known (but hasn't been verified yet). + if trusted[c.node.ID()] { + // Ensure that the trusted flag is set before checking against MaxPeers. + c.flags |= trustedConn + } + // TODO: track in-progress inbound node IDs (pre-Peer) to avoid dialing them. + c.cont <- srv.postHandshakeChecks(peers, inboundCount, c) + + case c := <-srv.checkpointAddPeer: + // At this point the connection is past the protocol handshake. + // Its capabilities are known and the remote identity is verified. + err := srv.addPeerChecks(peers, inboundCount, c) + if err == nil { + // The handshakes are done and it passed all checks. + p := newPeer(srv.log, c, srv.Protocols) + // If message events are enabled, pass the peerFeed + // to the peer + if srv.EnableMsgEvents { + p.events = &srv.peerFeed + } + name := truncateName(c.name) + srv.log.Debug("Adding p2p peer", "name", name, "addr", c.fd.RemoteAddr(), "peers", len(peers)+1) + go srv.runPeer(p) + peers[c.node.ID()] = p + if p.Inbound() { + inboundCount++ + } + } + // The dialer logic relies on the assumption that + // dial tasks complete after the peer has been added or + // discarded. Unblock the task last. + c.cont <- err + + case pd := <-srv.delpeer: + // A peer disconnected. + d := common.PrettyDuration(mclock.Now() - pd.created) + pd.log.Debug("Removing p2p peer", "duration", d, "peers", len(peers)-1, "req", pd.requested, "err", pd.err) + delete(peers, pd.ID()) + if pd.Inbound() { + inboundCount-- + } + } + } + + srv.log.Trace("P2P networking is spinning down") + + // Terminate discovery. If there is a running lookup it will terminate soon. + if srv.ntab != nil { + srv.ntab.Close() + } + if srv.DiscV5 != nil { + srv.DiscV5.Close() + } + // Disconnect all peers. + for _, p := range peers { + p.Disconnect(DiscQuitting) + } + // Wait for peers to shut down. Pending connections and tasks are + // not handled here and will terminate soon-ish because srv.quit + // is closed. + for len(peers) > 0 { + p := <-srv.delpeer + p.log.Trace("<-delpeer (spindown)", "remainingTasks", len(runningTasks)) + delete(peers, p.ID()) + } +} + +func (srv *Server) postHandshakeChecks(peers map[enode.ID]*Peer, inboundCount int, c *conn) error { + switch { + case !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers: + return DiscTooManyPeers + case !c.is(trustedConn) && c.is(inboundConn) && inboundCount >= srv.maxInboundConns(): + return DiscTooManyPeers + case peers[c.node.ID()] != nil: + return DiscAlreadyConnected + case c.node.ID() == srv.localnode.ID(): + return DiscSelf + default: + return nil + } +} + +func (srv *Server) addPeerChecks(peers map[enode.ID]*Peer, inboundCount int, c *conn) error { + // Drop connections with no matching protocols. + if len(srv.Protocols) > 0 && countMatchingProtocols(srv.Protocols, c.caps) == 0 { + return DiscUselessPeer + } + // Repeat the post-handshake checks because the + // peer set might have changed since those checks were performed. + return srv.postHandshakeChecks(peers, inboundCount, c) +} + +func (srv *Server) maxInboundConns() int { + return srv.MaxPeers - srv.maxDialedConns() +} + +func (srv *Server) maxDialedConns() int { + if srv.NoDiscovery || srv.NoDial { + return 0 + } + r := srv.DialRatio + if r == 0 { + r = defaultDialRatio + } + return srv.MaxPeers / r +} + +// listenLoop runs in its own goroutine and accepts +// inbound connections. +func (srv *Server) listenLoop() { + defer srv.loopWG.Done() + srv.log.Debug("TCP listener up", "addr", srv.listener.Addr()) + + tokens := defaultMaxPendingPeers + if srv.MaxPendingPeers > 0 { + tokens = srv.MaxPendingPeers + } + slots := make(chan struct{}, tokens) + for i := 0; i < tokens; i++ { + slots <- struct{}{} + } + + for { + // Wait for a free slot before accepting. + <-slots + + var ( + fd net.Conn + err error + ) + for { + fd, err = srv.listener.Accept() + if netutil.IsTemporaryError(err) { + srv.log.Debug("Temporary read error", "err", err) + continue + } else if err != nil { + srv.log.Debug("Read error", "err", err) + return + } + break + } + + remoteIP := netutil.AddrIP(fd.RemoteAddr()) + if err := srv.checkInboundConn(fd, remoteIP); err != nil { + srv.log.Debug("Rejected inbound connnection", "addr", fd.RemoteAddr(), "err", err) + fd.Close() + slots <- struct{}{} + continue + } + if remoteIP != nil { + fd = newMeteredConn(fd, true, remoteIP) + } + srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr()) + go func() { + srv.SetupConn(fd, inboundConn, nil) + slots <- struct{}{} + }() + } +} + +func (srv *Server) checkInboundConn(fd net.Conn, remoteIP net.IP) error { + if remoteIP != nil { + // Reject connections that do not match NetRestrict. + if srv.NetRestrict != nil && !srv.NetRestrict.Contains(remoteIP) { + return fmt.Errorf("not whitelisted in NetRestrict") + } + // Reject Internet peers that try too often. + srv.inboundHistory.expire(time.Now()) + if !netutil.IsLAN(remoteIP) && srv.inboundHistory.contains(remoteIP.String()) { + return fmt.Errorf("too many attempts") + } + srv.inboundHistory.add(remoteIP.String(), time.Now().Add(inboundThrottleTime)) + } + return nil +} + +// SetupConn runs the handshakes and attempts to add the connection +// as a peer. It returns when the connection has been added as a peer +// or the handshakes have failed. +func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) error { + c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)} + err := srv.setupConn(c, flags, dialDest) + if err != nil { + c.close(err) + srv.log.Trace("Setting up connection failed", "addr", fd.RemoteAddr(), "err", err) + } + return err +} + +func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) error { + // Prevent leftover pending conns from entering the handshake. + srv.lock.Lock() + running := srv.running + srv.lock.Unlock() + if !running { + return errServerStopped + } + + // If dialing, figure out the remote public key. + var dialPubkey *ecdsa.PublicKey + if dialDest != nil { + dialPubkey = new(ecdsa.PublicKey) + if err := dialDest.Load((*enode.Secp256k1)(dialPubkey)); err != nil { + return errors.New("dial destination doesn't have a secp256k1 public key") + } + } + + // Run the RLPx handshake. + remotePubkey, err := c.doEncHandshake(srv.PrivateKey, dialPubkey) + if err != nil { + srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) + return err + } + if dialDest != nil { + // For dialed connections, check that the remote public key matches. + if dialPubkey.X.Cmp(remotePubkey.X) != 0 || dialPubkey.Y.Cmp(remotePubkey.Y) != 0 { + return DiscUnexpectedIdentity + } + c.node = dialDest + } else { + c.node = nodeFromConn(remotePubkey, c.fd) + } + if conn, ok := c.fd.(*meteredConn); ok { + conn.handshakeDone(c.node.ID()) + } + clog := srv.log.New("id", c.node.ID(), "addr", c.fd.RemoteAddr(), "conn", c.flags) + err = srv.checkpoint(c, srv.checkpointPostHandshake) + if err != nil { + clog.Trace("Rejected peer", "err", err) + return err + } + + // Run the capability negotiation handshake. + phs, err := c.doProtoHandshake(srv.ourHandshake) + if err != nil { + clog.Trace("Failed proto handshake", "err", err) + return err + } + if id := c.node.ID(); !bytes.Equal(crypto.Keccak256(phs.ID), id[:]) { + clog.Trace("Wrong devp2p handshake identity", "phsid", hex.EncodeToString(phs.ID)) + return DiscUnexpectedIdentity + } + c.caps, c.name = phs.Caps, phs.Name + err = srv.checkpoint(c, srv.checkpointAddPeer) + if err != nil { + clog.Trace("Rejected peer", "err", err) + return err + } + + // If the checks completed successfully, the connection has been added as a peer and + // runPeer has been launched. + clog.Trace("Connection set up", "inbound", dialDest == nil) + return nil +} + +func nodeFromConn(pubkey *ecdsa.PublicKey, conn net.Conn) *enode.Node { + var ip net.IP + var port int + if tcp, ok := conn.RemoteAddr().(*net.TCPAddr); ok { + ip = tcp.IP + port = tcp.Port + } + return enode.NewV4(pubkey, ip, port, port) +} + +func truncateName(s string) string { + if len(s) > 20 { + return s[:20] + "..." + } + return s +} + +// checkpoint sends the conn to run, which performs the +// post-handshake checks for the stage (posthandshake, addpeer). +func (srv *Server) checkpoint(c *conn, stage chan<- *conn) error { + select { + case stage <- c: + case <-srv.quit: + return errServerStopped + } + return <-c.cont +} + +// runPeer runs in its own goroutine for each peer. +// it waits until the Peer logic returns and removes +// the peer. +func (srv *Server) runPeer(p *Peer) { + if srv.newPeerHook != nil { + srv.newPeerHook(p) + } + + // broadcast peer add + srv.peerFeed.Send(&PeerEvent{ + Type: PeerEventTypeAdd, + Peer: p.ID(), + }) + + // run the protocol + remoteRequested, err := p.run() + + // broadcast peer drop + srv.peerFeed.Send(&PeerEvent{ + Type: PeerEventTypeDrop, + Peer: p.ID(), + Error: err.Error(), + }) + + // Note: run waits for existing peers to be sent on srv.delpeer + // before returning, so this send should not select on srv.quit. + srv.delpeer <- peerDrop{p, err, remoteRequested} +} + +// NodeInfo represents a short summary of the information known about the host. +type NodeInfo struct { + ID string `json:"id"` // Unique node identifier (also the encryption key) + Name string `json:"name"` // Name of the node, including client type, version, OS, custom data + Enode string `json:"enode"` // Enode URL for adding this peer from remote peers + ENR string `json:"enr"` // Ethereum Node Record + IP string `json:"ip"` // IP address of the node + Ports struct { + Discovery int `json:"discovery"` // UDP listening port for discovery protocol + Listener int `json:"listener"` // TCP listening port for RLPx + } `json:"ports"` + ListenAddr string `json:"listenAddr"` + Protocols map[string]interface{} `json:"protocols"` +} + +// NodeInfo gathers and returns a collection of metadata known about the host. +func (srv *Server) NodeInfo() *NodeInfo { + // Gather and assemble the generic node infos + node := srv.Self() + info := &NodeInfo{ + Name: srv.Name, + Enode: node.URLv4(), + ID: node.ID().String(), + IP: node.IP().String(), + ListenAddr: srv.ListenAddr, + Protocols: make(map[string]interface{}), + } + info.Ports.Discovery = node.UDP() + info.Ports.Listener = node.TCP() + info.ENR = node.String() + + // Gather all the running protocol infos (only once per protocol type) + for _, proto := range srv.Protocols { + if _, ok := info.Protocols[proto.Name]; !ok { + nodeInfo := interface{}("unknown") + if query := proto.NodeInfo; query != nil { + nodeInfo = proto.NodeInfo() + } + info.Protocols[proto.Name] = nodeInfo + } + } + return info +} + +// PeersInfo returns an array of metadata objects describing connected peers. +func (srv *Server) PeersInfo() []*PeerInfo { + // Gather all the generic and sub-protocol specific infos + infos := make([]*PeerInfo, 0, srv.PeerCount()) + for _, peer := range srv.Peers() { + if peer != nil { + infos = append(infos, peer.Info()) + } + } + // Sort the result array alphabetically by node identifier + for i := 0; i < len(infos); i++ { + for j := i + 1; j < len(infos); j++ { + if infos[i].ID > infos[j].ID { + infos[i], infos[j] = infos[j], infos[i] + } + } + } + return infos +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/testing/peerpool.go b/vendor/github.com/ethereum/go-ethereum/p2p/testing/peerpool.go new file mode 100644 index 00000000..09db4b24 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/testing/peerpool.go @@ -0,0 +1,67 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package testing + +import ( + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +type TestPeer interface { + ID() enode.ID + Drop() +} + +// TestPeerPool is an example peerPool to demonstrate registration of peer connections +type TestPeerPool struct { + lock sync.Mutex + peers map[enode.ID]TestPeer +} + +func NewTestPeerPool() *TestPeerPool { + return &TestPeerPool{peers: make(map[enode.ID]TestPeer)} +} + +func (p *TestPeerPool) Add(peer TestPeer) { + p.lock.Lock() + defer p.lock.Unlock() + log.Trace(fmt.Sprintf("pp add peer %v", peer.ID())) + p.peers[peer.ID()] = peer + +} + +func (p *TestPeerPool) Remove(peer TestPeer) { + p.lock.Lock() + defer p.lock.Unlock() + delete(p.peers, peer.ID()) +} + +func (p *TestPeerPool) Has(id enode.ID) bool { + p.lock.Lock() + defer p.lock.Unlock() + _, ok := p.peers[id] + return ok +} + +func (p *TestPeerPool) Get(id enode.ID) TestPeer { + p.lock.Lock() + defer p.lock.Unlock() + return p.peers[id] +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/testing/protocoltester.go b/vendor/github.com/ethereum/go-ethereum/p2p/testing/protocoltester.go new file mode 100644 index 00000000..e798240a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/testing/protocoltester.go @@ -0,0 +1,284 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +/* +the p2p/testing package provides a unit test scheme to check simple +protocol message exchanges with one pivot node and a number of dummy peers +The pivot test node runs a node.Service, the dummy peers run a mock node +that can be used to send and receive messages +*/ + +package testing + +import ( + "bytes" + "crypto/ecdsa" + "fmt" + "io" + "io/ioutil" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" +) + +// ProtocolTester is the tester environment used for unit testing protocol +// message exchanges. It uses p2p/simulations framework +type ProtocolTester struct { + *ProtocolSession + network *simulations.Network +} + +// NewProtocolTester constructs a new ProtocolTester +// it takes as argument the pivot node id, the number of dummy peers and the +// protocol run function called on a peer connection by the p2p server +func NewProtocolTester(prvkey *ecdsa.PrivateKey, nodeCount int, run func(*p2p.Peer, p2p.MsgReadWriter) error) *ProtocolTester { + services := adapters.Services{ + "test": func(ctx *adapters.ServiceContext) (node.Service, error) { + return &testNode{run}, nil + }, + "mock": func(ctx *adapters.ServiceContext) (node.Service, error) { + return newMockNode(), nil + }, + } + adapter := adapters.NewSimAdapter(services) + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{}) + nodeConfig := &adapters.NodeConfig{ + PrivateKey: prvkey, + EnableMsgEvents: true, + Services: []string{"test"}, + } + if _, err := net.NewNodeWithConfig(nodeConfig); err != nil { + panic(err.Error()) + } + if err := net.Start(nodeConfig.ID); err != nil { + panic(err.Error()) + } + + node := net.GetNode(nodeConfig.ID).Node.(*adapters.SimNode) + peers := make([]*adapters.NodeConfig, nodeCount) + nodes := make([]*enode.Node, nodeCount) + for i := 0; i < nodeCount; i++ { + peers[i] = adapters.RandomNodeConfig() + peers[i].Services = []string{"mock"} + if _, err := net.NewNodeWithConfig(peers[i]); err != nil { + panic(fmt.Sprintf("error initializing peer %v: %v", peers[i].ID, err)) + } + if err := net.Start(peers[i].ID); err != nil { + panic(fmt.Sprintf("error starting peer %v: %v", peers[i].ID, err)) + } + nodes[i] = peers[i].Node() + } + events := make(chan *p2p.PeerEvent, 1000) + node.SubscribeEvents(events) + ps := &ProtocolSession{ + Server: node.Server(), + Nodes: nodes, + adapter: adapter, + events: events, + } + self := &ProtocolTester{ + ProtocolSession: ps, + network: net, + } + + self.Connect(nodeConfig.ID, peers...) + + return self +} + +// Stop stops the p2p server +func (t *ProtocolTester) Stop() { + t.Server.Stop() + t.network.Shutdown() +} + +// Connect brings up the remote peer node and connects it using the +// p2p/simulations network connection with the in memory network adapter +func (t *ProtocolTester) Connect(selfID enode.ID, peers ...*adapters.NodeConfig) { + for _, peer := range peers { + log.Trace(fmt.Sprintf("connect to %v", peer.ID)) + if err := t.network.Connect(selfID, peer.ID); err != nil { + panic(fmt.Sprintf("error connecting to peer %v: %v", peer.ID, err)) + } + } + +} + +// testNode wraps a protocol run function and implements the node.Service +// interface +type testNode struct { + run func(*p2p.Peer, p2p.MsgReadWriter) error +} + +func (t *testNode) Protocols() []p2p.Protocol { + return []p2p.Protocol{{ + Length: 100, + Run: t.run, + }} +} + +func (t *testNode) APIs() []rpc.API { + return nil +} + +func (t *testNode) Start(server *p2p.Server) error { + return nil +} + +func (t *testNode) Stop() error { + return nil +} + +// mockNode is a testNode which doesn't actually run a protocol, instead +// exposing channels so that tests can manually trigger and expect certain +// messages +type mockNode struct { + testNode + + trigger chan *Trigger + expect chan []Expect + err chan error + stop chan struct{} + stopOnce sync.Once +} + +func newMockNode() *mockNode { + mock := &mockNode{ + trigger: make(chan *Trigger), + expect: make(chan []Expect), + err: make(chan error), + stop: make(chan struct{}), + } + mock.testNode.run = mock.Run + return mock +} + +// Run is a protocol run function which just loops waiting for tests to +// instruct it to either trigger or expect a message from the peer +func (m *mockNode) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { + for { + select { + case trig := <-m.trigger: + wmsg := Wrap(trig.Msg) + m.err <- p2p.Send(rw, trig.Code, wmsg) + case exps := <-m.expect: + m.err <- expectMsgs(rw, exps) + case <-m.stop: + return nil + } + } +} + +func (m *mockNode) Trigger(trig *Trigger) error { + m.trigger <- trig + return <-m.err +} + +func (m *mockNode) Expect(exp ...Expect) error { + m.expect <- exp + return <-m.err +} + +func (m *mockNode) Stop() error { + m.stopOnce.Do(func() { close(m.stop) }) + return nil +} + +func expectMsgs(rw p2p.MsgReadWriter, exps []Expect) error { + matched := make([]bool, len(exps)) + for { + msg, err := rw.ReadMsg() + if err != nil { + if err == io.EOF { + break + } + return err + } + actualContent, err := ioutil.ReadAll(msg.Payload) + if err != nil { + return err + } + var found bool + for i, exp := range exps { + if exp.Code == msg.Code && bytes.Equal(actualContent, mustEncodeMsg(Wrap(exp.Msg))) { + if matched[i] { + return fmt.Errorf("message #%d received two times", i) + } + matched[i] = true + found = true + break + } + } + if !found { + expected := make([]string, 0) + for i, exp := range exps { + if matched[i] { + continue + } + expected = append(expected, fmt.Sprintf("code %d payload %x", exp.Code, mustEncodeMsg(Wrap(exp.Msg)))) + } + return fmt.Errorf("unexpected message code %d payload %x, expected %s", msg.Code, actualContent, strings.Join(expected, " or ")) + } + done := true + for _, m := range matched { + if !m { + done = false + break + } + } + if done { + return nil + } + } + for i, m := range matched { + if !m { + return fmt.Errorf("expected message #%d not received", i) + } + } + return nil +} + +// mustEncodeMsg uses rlp to encode a message. +// In case of error it panics. +func mustEncodeMsg(msg interface{}) []byte { + contentEnc, err := rlp.EncodeToBytes(msg) + if err != nil { + panic("content encode error: " + err.Error()) + } + return contentEnc +} + +type WrappedMsg struct { + Context []byte + Size uint32 + Payload []byte +} + +func Wrap(msg interface{}) interface{} { + data, _ := rlp.EncodeToBytes(msg) + return &WrappedMsg{ + Size: uint32(len(data)), + Payload: data, + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/p2p/util.go b/vendor/github.com/ethereum/go-ethereum/p2p/util.go new file mode 100644 index 00000000..2a6edf5c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/p2p/util.go @@ -0,0 +1,82 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package p2p + +import ( + "container/heap" + "time" +) + +// expHeap tracks strings and their expiry time. +type expHeap []expItem + +// expItem is an entry in addrHistory. +type expItem struct { + item string + exp time.Time +} + +// nextExpiry returns the next expiry time. +func (h *expHeap) nextExpiry() time.Time { + return (*h)[0].exp +} + +// add adds an item and sets its expiry time. +func (h *expHeap) add(item string, exp time.Time) { + heap.Push(h, expItem{item, exp}) +} + +// remove removes an item. +func (h *expHeap) remove(item string) bool { + for i, v := range *h { + if v.item == item { + heap.Remove(h, i) + return true + } + } + return false +} + +// contains checks whether an item is present. +func (h expHeap) contains(item string) bool { + for _, v := range h { + if v.item == item { + return true + } + } + return false +} + +// expire removes items with expiry time before 'now'. +func (h *expHeap) expire(now time.Time) { + for h.Len() > 0 && h.nextExpiry().Before(now) { + heap.Pop(h) + } +} + +// heap.Interface boilerplate +func (h expHeap) Len() int { return len(h) } +func (h expHeap) Less(i, j int) bool { return h[i].exp.Before(h[j].exp) } +func (h expHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *expHeap) Push(x interface{}) { *h = append(*h, x.(expItem)) } +func (h *expHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} diff --git a/vendor/github.com/ethereum/go-ethereum/params/config.go b/vendor/github.com/ethereum/go-ethereum/params/config.go new file mode 100644 index 00000000..c59c748a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/params/config.go @@ -0,0 +1,457 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package params + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +// Genesis hashes to enforce below configs on. +var ( + MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") + TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") + RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") + GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") +) + +// TrustedCheckpoints associates each known checkpoint with the genesis hash of +// the chain it belongs to. +var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{ + MainnetGenesisHash: MainnetTrustedCheckpoint, + TestnetGenesisHash: TestnetTrustedCheckpoint, + RinkebyGenesisHash: RinkebyTrustedCheckpoint, + GoerliGenesisHash: GoerliTrustedCheckpoint, +} + +var ( + // MainnetChainConfig is the chain parameters to run a node on the main network. + MainnetChainConfig = &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(1150000), + DAOForkBlock: big.NewInt(1920000), + DAOForkSupport: true, + EIP150Block: big.NewInt(2463000), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(2675000), + EIP158Block: big.NewInt(2675000), + ByzantiumBlock: big.NewInt(4370000), + ConstantinopleBlock: big.NewInt(7280000), + PetersburgBlock: big.NewInt(7280000), + Ethash: new(EthashConfig), + } + + // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. + MainnetTrustedCheckpoint = &TrustedCheckpoint{ + Name: "mainnet", + SectionIndex: 227, + SectionHead: common.HexToHash("0xa2e0b25d72c2fc6e35a7f853cdacb193b4b4f95c606accf7f8fa8415283582c7"), + CHTRoot: common.HexToHash("0xf69bdd4053b95b61a27b106a0e86103d791edd8574950dc96aa351ab9b9f1aa0"), + BloomRoot: common.HexToHash("0xec1b454d4c6322c78ccedf76ac922a8698c3cac4d98748a84af4995b7bd3d744"), + } + + // TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network. + TestnetChainConfig = &ChainConfig{ + ChainID: big.NewInt(3), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), + EIP155Block: big.NewInt(10), + EIP158Block: big.NewInt(10), + ByzantiumBlock: big.NewInt(1700000), + ConstantinopleBlock: big.NewInt(4230000), + PetersburgBlock: big.NewInt(4939394), + Ethash: new(EthashConfig), + } + + // TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network. + TestnetTrustedCheckpoint = &TrustedCheckpoint{ + Name: "testnet", + SectionIndex: 161, + SectionHead: common.HexToHash("0x5378afa734e1feafb34bcca1534c4d96952b754579b96a4afb23d5301ecececc"), + CHTRoot: common.HexToHash("0x1cf2b071e7443a62914362486b613ff30f60cea0d9c268ed8c545f876a3ee60c"), + BloomRoot: common.HexToHash("0x5ac25c84bd18a9cbe878d4609a80220f57f85037a112644532412ba0d498a31b"), + } + + // RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network. + RinkebyChainConfig = &ChainConfig{ + ChainID: big.NewInt(4), + HomesteadBlock: big.NewInt(1), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(2), + EIP150Hash: common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), + EIP155Block: big.NewInt(3), + EIP158Block: big.NewInt(3), + ByzantiumBlock: big.NewInt(1035301), + ConstantinopleBlock: big.NewInt(3660663), + PetersburgBlock: big.NewInt(4321234), + Clique: &CliqueConfig{ + Period: 15, + Epoch: 30000, + }, + } + + // RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network. + RinkebyTrustedCheckpoint = &TrustedCheckpoint{ + Name: "rinkeby", + SectionIndex: 125, + SectionHead: common.HexToHash("0x8a738386f6bb34add15846f8f49c4c519a2f32519096e792b9f43bcb407c831c"), + CHTRoot: common.HexToHash("0xa1e5720a9bad4dce794f129e4ac6744398197b652868011486a6f89c8ec84a75"), + BloomRoot: common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"), + } + + // GoerliChainConfig contains the chain parameters to run a node on the Görli test network. + GoerliChainConfig = &ChainConfig{ + ChainID: big.NewInt(5), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + Clique: &CliqueConfig{ + Period: 15, + Epoch: 30000, + }, + } + + // GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network. + GoerliTrustedCheckpoint = &TrustedCheckpoint{ + Name: "goerli", + SectionIndex: 9, + SectionHead: common.HexToHash("0x8e223d827391eee53b07cb8ee057dbfa11c93e0b45352188c783affd7840a921"), + CHTRoot: common.HexToHash("0xe0a817ac69b36c1e437c5b0cff9e764853f5115702b5f66d451b665d6afb7e78"), + BloomRoot: common.HexToHash("0x50d672aeb655b723284969c7c1201fb6ca003c23ed144bcb9f2d1b30e2971c1b"), + } + + // AllEthashProtocolChanges contains every protocol change (EIPs) introduced + // and accepted by the Ethereum core developers into the Ethash consensus. + // + // This configuration is intentionally not using keyed fields to force anyone + // adding flags to the config to also have to set these fields. + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + + // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced + // and accepted by the Ethereum core developers into the Clique consensus. + // + // This configuration is intentionally not using keyed fields to force anyone + // adding flags to the config to also have to set these fields. + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + TestRules = TestChainConfig.Rules(new(big.Int)) +) + +// TrustedCheckpoint represents a set of post-processed trie roots (CHT and +// BloomTrie) associated with the appropriate section index and head hash. It is +// used to start light syncing from this checkpoint and avoid downloading the +// entire header chain while still being able to securely access old headers/logs. +type TrustedCheckpoint struct { + Name string `json:"-"` + SectionIndex uint64 `json:"sectionIndex"` + SectionHead common.Hash `json:"sectionHead"` + CHTRoot common.Hash `json:"chtRoot"` + BloomRoot common.Hash `json:"bloomRoot"` +} + +// ChainConfig is the core config which determines the blockchain settings. +// +// ChainConfig is stored in the database on a per block basis. This means +// that any network, identified by its genesis block, can have its own +// set of configuration options. +type ChainConfig struct { + ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection + + HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) + + DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) + DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork + + // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) + EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) + EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) + + EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block + EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block + + ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) + ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) + PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) + EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) + + // Various consensus engines + Ethash *EthashConfig `json:"ethash,omitempty"` + Clique *CliqueConfig `json:"clique,omitempty"` +} + +// EthashConfig is the consensus engine configs for proof-of-work based sealing. +type EthashConfig struct{} + +// String implements the stringer interface, returning the consensus engine details. +func (c *EthashConfig) String() string { + return "ethash" +} + +// CliqueConfig is the consensus engine configs for proof-of-authority based sealing. +type CliqueConfig struct { + Period uint64 `json:"period"` // Number of seconds between blocks to enforce + Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint +} + +// String implements the stringer interface, returning the consensus engine details. +func (c *CliqueConfig) String() string { + return "clique" +} + +// String implements the fmt.Stringer interface. +func (c *ChainConfig) String() string { + var engine interface{} + switch { + case c.Ethash != nil: + engine = c.Ethash + case c.Clique != nil: + engine = c.Clique + default: + engine = "unknown" + } + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v ConstantinopleFix: %v Engine: %v}", + c.ChainID, + c.HomesteadBlock, + c.DAOForkBlock, + c.DAOForkSupport, + c.EIP150Block, + c.EIP155Block, + c.EIP158Block, + c.ByzantiumBlock, + c.ConstantinopleBlock, + c.PetersburgBlock, + engine, + ) +} + +// IsHomestead returns whether num is either equal to the homestead block or greater. +func (c *ChainConfig) IsHomestead(num *big.Int) bool { + return isForked(c.HomesteadBlock, num) +} + +// IsDAOFork returns whether num is either equal to the DAO fork block or greater. +func (c *ChainConfig) IsDAOFork(num *big.Int) bool { + return isForked(c.DAOForkBlock, num) +} + +// IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. +func (c *ChainConfig) IsEIP150(num *big.Int) bool { + return isForked(c.EIP150Block, num) +} + +// IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. +func (c *ChainConfig) IsEIP155(num *big.Int) bool { + return isForked(c.EIP155Block, num) +} + +// IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. +func (c *ChainConfig) IsEIP158(num *big.Int) bool { + return isForked(c.EIP158Block, num) +} + +// IsByzantium returns whether num is either equal to the Byzantium fork block or greater. +func (c *ChainConfig) IsByzantium(num *big.Int) bool { + return isForked(c.ByzantiumBlock, num) +} + +// IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. +func (c *ChainConfig) IsConstantinople(num *big.Int) bool { + return isForked(c.ConstantinopleBlock, num) +} + +// IsPetersburg returns whether num is either +// - equal to or greater than the PetersburgBlock fork block, +// - OR is nil, and Constantinople is active +func (c *ChainConfig) IsPetersburg(num *big.Int) bool { + return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) +} + +// IsEWASM returns whether num represents a block number after the EWASM fork +func (c *ChainConfig) IsEWASM(num *big.Int) bool { + return isForked(c.EWASMBlock, num) +} + +// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice). +// +// The returned GasTable's fields shouldn't, under any circumstances, be changed. +func (c *ChainConfig) GasTable(num *big.Int) GasTable { + if num == nil { + return GasTableHomestead + } + switch { + case c.IsConstantinople(num): + return GasTableConstantinople + case c.IsEIP158(num): + return GasTableEIP158 + case c.IsEIP150(num): + return GasTableEIP150 + default: + return GasTableHomestead + } +} + +// CheckCompatible checks whether scheduled fork transitions have been imported +// with a mismatching chain configuration. +func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { + bhead := new(big.Int).SetUint64(height) + + // Iterate checkCompatible to find the lowest conflict. + var lasterr *ConfigCompatError + for { + err := c.checkCompatible(newcfg, bhead) + if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { + break + } + lasterr = err + bhead.SetUint64(err.RewindTo) + } + return lasterr +} + +func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { + if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { + return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) + } + if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { + return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) + } + if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { + return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) + } + if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { + return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) + } + if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { + return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) + } + if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { + return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) + } + if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { + return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) + } + if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { + return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) + } + if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { + return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) + } + if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { + return newCompatError("ConstantinopleFix fork block", c.PetersburgBlock, newcfg.PetersburgBlock) + } + if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { + return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) + } + return nil +} + +// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to +// block s2 because head is already past the fork. +func isForkIncompatible(s1, s2, head *big.Int) bool { + return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) +} + +// isForked returns whether a fork scheduled at block s is active at the given head block. +func isForked(s, head *big.Int) bool { + if s == nil || head == nil { + return false + } + return s.Cmp(head) <= 0 +} + +func configNumEqual(x, y *big.Int) bool { + if x == nil { + return y == nil + } + if y == nil { + return x == nil + } + return x.Cmp(y) == 0 +} + +// ConfigCompatError is raised if the locally-stored blockchain is initialised with a +// ChainConfig that would alter the past. +type ConfigCompatError struct { + What string + // block numbers of the stored and new configurations + StoredConfig, NewConfig *big.Int + // the block number to which the local chain must be rewound to correct the error + RewindTo uint64 +} + +func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { + var rew *big.Int + switch { + case storedblock == nil: + rew = newblock + case newblock == nil || storedblock.Cmp(newblock) < 0: + rew = storedblock + default: + rew = newblock + } + err := &ConfigCompatError{what, storedblock, newblock, 0} + if rew != nil && rew.Sign() > 0 { + err.RewindTo = rew.Uint64() - 1 + } + return err +} + +func (err *ConfigCompatError) Error() string { + return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) +} + +// Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions +// that do not have or require information about the block. +// +// Rules is a one time interface meaning that it shouldn't be used in between transition +// phases. +type Rules struct { + ChainID *big.Int + IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool + IsByzantium, IsConstantinople, IsPetersburg bool +} + +// Rules ensures c's ChainID is not nil. +func (c *ChainConfig) Rules(num *big.Int) Rules { + chainID := c.ChainID + if chainID == nil { + chainID = new(big.Int) + } + return Rules{ + ChainID: new(big.Int).Set(chainID), + IsHomestead: c.IsHomestead(num), + IsEIP150: c.IsEIP150(num), + IsEIP155: c.IsEIP155(num), + IsEIP158: c.IsEIP158(num), + IsByzantium: c.IsByzantium(num), + IsConstantinople: c.IsConstantinople(num), + IsPetersburg: c.IsPetersburg(num), + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/params/network_params.go b/vendor/github.com/ethereum/go-ethereum/params/network_params.go new file mode 100644 index 00000000..a949b845 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/params/network_params.go @@ -0,0 +1,55 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package params + +// These are network parameters that need to be constant between clients, but +// aren't necessarily consensus related. + +const ( + // BloomBitsBlocks is the number of blocks a single bloom bit section vector + // contains on the server side. + BloomBitsBlocks uint64 = 4096 + + // BloomBitsBlocksClient is the number of blocks a single bloom bit section vector + // contains on the light client side + BloomBitsBlocksClient uint64 = 32768 + + // BloomConfirms is the number of confirmation blocks before a bloom section is + // considered probably final and its rotated bits are calculated. + BloomConfirms = 256 + + // CHTFrequency is the block frequency for creating CHTs + CHTFrequency = 32768 + + // BloomTrieFrequency is the block frequency for creating BloomTrie on both + // server/client sides. + BloomTrieFrequency = 32768 + + // HelperTrieConfirmations is the number of confirmations before a client is expected + // to have the given HelperTrie available. + HelperTrieConfirmations = 2048 + + // HelperTrieProcessConfirmations is the number of confirmations before a HelperTrie + // is generated + HelperTrieProcessConfirmations = 256 + + // ImmutabilityThreshold is the number of blocks after which a chain segment is + // considered immutable (i.e. soft finality). It is used by the downloader as a + // hard limit against deep ancestors, by the blockchain against deep reorgs, by + // the freezer as the cutoff treshold and by clique as the snapshot trust limit. + ImmutabilityThreshold = 90000 +) diff --git a/vendor/github.com/ethereum/go-ethereum/params/version.go b/vendor/github.com/ethereum/go-ethereum/params/version.go new file mode 100644 index 00000000..c91a26ed --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/params/version.go @@ -0,0 +1,67 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package params + +import ( + "fmt" +) + +const ( + VersionMajor = 1 // Major version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release + VersionMeta = "unstable" // Version metadata to append to the version string +) + +// Version holds the textual version string. +var Version = func() string { + return fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) +}() + +// VersionWithMeta holds the textual version string including the metadata. +var VersionWithMeta = func() string { + v := Version + if VersionMeta != "" { + v += "-" + VersionMeta + } + return v +}() + +// ArchiveVersion holds the textual version string used for Geth archives. +// e.g. "1.8.11-dea1ce05" for stable releases, or +// "1.8.13-unstable-21c059b6" for unstable releases +func ArchiveVersion(gitCommit string) string { + vsn := Version + if VersionMeta != "stable" { + vsn += "-" + VersionMeta + } + if len(gitCommit) >= 8 { + vsn += "-" + gitCommit[:8] + } + return vsn +} + +func VersionWithCommit(gitCommit, gitDate string) string { + vsn := VersionWithMeta + if len(gitCommit) >= 8 { + vsn += "-" + gitCommit[:8] + } + if (VersionMeta != "stable") && (gitDate != "") { + vsn += "-" + gitDate + } + return vsn +} diff --git a/vendor/github.com/ethereum/go-ethereum/rlp/decode.go b/vendor/github.com/ethereum/go-ethereum/rlp/decode.go new file mode 100644 index 00000000..4f29f2fb --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rlp/decode.go @@ -0,0 +1,1049 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rlp + +import ( + "bufio" + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math/big" + "reflect" + "strings" + "sync" +) + +var ( + // EOL is returned when the end of the current list + // has been reached during streaming. + EOL = errors.New("rlp: end of list") + + // Actual Errors + ErrExpectedString = errors.New("rlp: expected String or Byte") + ErrExpectedList = errors.New("rlp: expected List") + ErrCanonInt = errors.New("rlp: non-canonical integer format") + ErrCanonSize = errors.New("rlp: non-canonical size information") + ErrElemTooLarge = errors.New("rlp: element is larger than containing list") + ErrValueTooLarge = errors.New("rlp: value size exceeds available input length") + ErrMoreThanOneValue = errors.New("rlp: input contains more than one value") + + // internal errors + errNotInList = errors.New("rlp: call of ListEnd outside of any list") + errNotAtEOL = errors.New("rlp: call of ListEnd not positioned at EOL") + errUintOverflow = errors.New("rlp: uint overflow") + errNoPointer = errors.New("rlp: interface given to Decode must be a pointer") + errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil") + + streamPool = sync.Pool{ + New: func() interface{} { return new(Stream) }, + } +) + +// Decoder is implemented by types that require custom RLP +// decoding rules or need to decode into private fields. +// +// The DecodeRLP method should read one value from the given +// Stream. It is not forbidden to read less or more, but it might +// be confusing. +type Decoder interface { + DecodeRLP(*Stream) error +} + +// Decode parses RLP-encoded data from r and stores the result in the +// value pointed to by val. Val must be a non-nil pointer. If r does +// not implement ByteReader, Decode will do its own buffering. +// +// Decode uses the following type-dependent decoding rules: +// +// If the type implements the Decoder interface, decode calls +// DecodeRLP. +// +// To decode into a pointer, Decode will decode into the value pointed +// to. If the pointer is nil, a new value of the pointer's element +// type is allocated. If the pointer is non-nil, the existing value +// will be reused. +// +// To decode into a struct, Decode expects the input to be an RLP +// list. The decoded elements of the list are assigned to each public +// field in the order given by the struct's definition. The input list +// must contain an element for each decoded field. Decode returns an +// error if there are too few or too many elements. +// +// The decoding of struct fields honours certain struct tags, "tail", +// "nil" and "-". +// +// The "-" tag ignores fields. +// +// For an explanation of "tail", see the example. +// +// The "nil" tag applies to pointer-typed fields and changes the decoding +// rules for the field such that input values of size zero decode as a nil +// pointer. This tag can be useful when decoding recursive types. +// +// type StructWithEmptyOK struct { +// Foo *[20]byte `rlp:"nil"` +// } +// +// To decode into a slice, the input must be a list and the resulting +// slice will contain the input elements in order. For byte slices, +// the input must be an RLP string. Array types decode similarly, with +// the additional restriction that the number of input elements (or +// bytes) must match the array's length. +// +// To decode into a Go string, the input must be an RLP string. The +// input bytes are taken as-is and will not necessarily be valid UTF-8. +// +// To decode into an unsigned integer type, the input must also be an RLP +// string. The bytes are interpreted as a big endian representation of +// the integer. If the RLP string is larger than the bit size of the +// type, Decode will return an error. Decode also supports *big.Int. +// There is no size limit for big integers. +// +// To decode into a boolean, the input must contain an unsigned integer +// of value zero (false) or one (true). +// +// To decode into an interface value, Decode stores one of these +// in the value: +// +// []interface{}, for RLP lists +// []byte, for RLP strings +// +// Non-empty interface types are not supported, nor are signed integers, +// floating point numbers, maps, channels and functions. +// +// Note that Decode does not set an input limit for all readers +// and may be vulnerable to panics cause by huge value sizes. If +// you need an input limit, use +// +// NewStream(r, limit).Decode(val) +func Decode(r io.Reader, val interface{}) error { + stream := streamPool.Get().(*Stream) + defer streamPool.Put(stream) + + stream.Reset(r, 0) + return stream.Decode(val) +} + +// DecodeBytes parses RLP data from b into val. +// Please see the documentation of Decode for the decoding rules. +// The input must contain exactly one value and no trailing data. +func DecodeBytes(b []byte, val interface{}) error { + r := bytes.NewReader(b) + + stream := streamPool.Get().(*Stream) + defer streamPool.Put(stream) + + stream.Reset(r, uint64(len(b))) + if err := stream.Decode(val); err != nil { + return err + } + if r.Len() > 0 { + return ErrMoreThanOneValue + } + return nil +} + +type decodeError struct { + msg string + typ reflect.Type + ctx []string +} + +func (err *decodeError) Error() string { + ctx := "" + if len(err.ctx) > 0 { + ctx = ", decoding into " + for i := len(err.ctx) - 1; i >= 0; i-- { + ctx += err.ctx[i] + } + } + return fmt.Sprintf("rlp: %s for %v%s", err.msg, err.typ, ctx) +} + +func wrapStreamError(err error, typ reflect.Type) error { + switch err { + case ErrCanonInt: + return &decodeError{msg: "non-canonical integer (leading zero bytes)", typ: typ} + case ErrCanonSize: + return &decodeError{msg: "non-canonical size information", typ: typ} + case ErrExpectedList: + return &decodeError{msg: "expected input list", typ: typ} + case ErrExpectedString: + return &decodeError{msg: "expected input string or byte", typ: typ} + case errUintOverflow: + return &decodeError{msg: "input string too long", typ: typ} + case errNotAtEOL: + return &decodeError{msg: "input list has too many elements", typ: typ} + } + return err +} + +func addErrorContext(err error, ctx string) error { + if decErr, ok := err.(*decodeError); ok { + decErr.ctx = append(decErr.ctx, ctx) + } + return err +} + +var ( + decoderInterface = reflect.TypeOf(new(Decoder)).Elem() + bigInt = reflect.TypeOf(big.Int{}) +) + +func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { + kind := typ.Kind() + switch { + case typ == rawValueType: + return decodeRawValue, nil + case typ.Implements(decoderInterface): + return decodeDecoder, nil + case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface): + return decodeDecoderNoPtr, nil + case typ.AssignableTo(reflect.PtrTo(bigInt)): + return decodeBigInt, nil + case typ.AssignableTo(bigInt): + return decodeBigIntNoPtr, nil + case isUint(kind): + return decodeUint, nil + case kind == reflect.Bool: + return decodeBool, nil + case kind == reflect.String: + return decodeString, nil + case kind == reflect.Slice || kind == reflect.Array: + return makeListDecoder(typ, tags) + case kind == reflect.Struct: + return makeStructDecoder(typ) + case kind == reflect.Ptr: + if tags.nilOK { + return makeOptionalPtrDecoder(typ) + } + return makePtrDecoder(typ) + case kind == reflect.Interface: + return decodeInterface, nil + default: + return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) + } +} + +func decodeRawValue(s *Stream, val reflect.Value) error { + r, err := s.Raw() + if err != nil { + return err + } + val.SetBytes(r) + return nil +} + +func decodeUint(s *Stream, val reflect.Value) error { + typ := val.Type() + num, err := s.uint(typ.Bits()) + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetUint(num) + return nil +} + +func decodeBool(s *Stream, val reflect.Value) error { + b, err := s.Bool() + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetBool(b) + return nil +} + +func decodeString(s *Stream, val reflect.Value) error { + b, err := s.Bytes() + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetString(string(b)) + return nil +} + +func decodeBigIntNoPtr(s *Stream, val reflect.Value) error { + return decodeBigInt(s, val.Addr()) +} + +func decodeBigInt(s *Stream, val reflect.Value) error { + b, err := s.Bytes() + if err != nil { + return wrapStreamError(err, val.Type()) + } + i := val.Interface().(*big.Int) + if i == nil { + i = new(big.Int) + val.Set(reflect.ValueOf(i)) + } + // Reject leading zero bytes + if len(b) > 0 && b[0] == 0 { + return wrapStreamError(ErrCanonInt, val.Type()) + } + i.SetBytes(b) + return nil +} + +func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { + etype := typ.Elem() + if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { + if typ.Kind() == reflect.Array { + return decodeByteArray, nil + } + return decodeByteSlice, nil + } + etypeinfo := cachedTypeInfo1(etype, tags{}) + if etypeinfo.decoderErr != nil { + return nil, etypeinfo.decoderErr + } + var dec decoder + switch { + case typ.Kind() == reflect.Array: + dec = func(s *Stream, val reflect.Value) error { + return decodeListArray(s, val, etypeinfo.decoder) + } + case tag.tail: + // A slice with "tail" tag can occur as the last field + // of a struct and is supposed to swallow all remaining + // list elements. The struct decoder already called s.List, + // proceed directly to decoding the elements. + dec = func(s *Stream, val reflect.Value) error { + return decodeSliceElems(s, val, etypeinfo.decoder) + } + default: + dec = func(s *Stream, val reflect.Value) error { + return decodeListSlice(s, val, etypeinfo.decoder) + } + } + return dec, nil +} + +func decodeListSlice(s *Stream, val reflect.Value, elemdec decoder) error { + size, err := s.List() + if err != nil { + return wrapStreamError(err, val.Type()) + } + if size == 0 { + val.Set(reflect.MakeSlice(val.Type(), 0, 0)) + return s.ListEnd() + } + if err := decodeSliceElems(s, val, elemdec); err != nil { + return err + } + return s.ListEnd() +} + +func decodeSliceElems(s *Stream, val reflect.Value, elemdec decoder) error { + i := 0 + for ; ; i++ { + // grow slice if necessary + if i >= val.Cap() { + newcap := val.Cap() + val.Cap()/2 + if newcap < 4 { + newcap = 4 + } + newv := reflect.MakeSlice(val.Type(), val.Len(), newcap) + reflect.Copy(newv, val) + val.Set(newv) + } + if i >= val.Len() { + val.SetLen(i + 1) + } + // decode into element + if err := elemdec(s, val.Index(i)); err == EOL { + break + } else if err != nil { + return addErrorContext(err, fmt.Sprint("[", i, "]")) + } + } + if i < val.Len() { + val.SetLen(i) + } + return nil +} + +func decodeListArray(s *Stream, val reflect.Value, elemdec decoder) error { + if _, err := s.List(); err != nil { + return wrapStreamError(err, val.Type()) + } + vlen := val.Len() + i := 0 + for ; i < vlen; i++ { + if err := elemdec(s, val.Index(i)); err == EOL { + break + } else if err != nil { + return addErrorContext(err, fmt.Sprint("[", i, "]")) + } + } + if i < vlen { + return &decodeError{msg: "input list has too few elements", typ: val.Type()} + } + return wrapStreamError(s.ListEnd(), val.Type()) +} + +func decodeByteSlice(s *Stream, val reflect.Value) error { + b, err := s.Bytes() + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetBytes(b) + return nil +} + +func decodeByteArray(s *Stream, val reflect.Value) error { + kind, size, err := s.Kind() + if err != nil { + return err + } + vlen := val.Len() + switch kind { + case Byte: + if vlen == 0 { + return &decodeError{msg: "input string too long", typ: val.Type()} + } + if vlen > 1 { + return &decodeError{msg: "input string too short", typ: val.Type()} + } + bv, _ := s.Uint() + val.Index(0).SetUint(bv) + case String: + if uint64(vlen) < size { + return &decodeError{msg: "input string too long", typ: val.Type()} + } + if uint64(vlen) > size { + return &decodeError{msg: "input string too short", typ: val.Type()} + } + slice := val.Slice(0, vlen).Interface().([]byte) + if err := s.readFull(slice); err != nil { + return err + } + // Reject cases where single byte encoding should have been used. + if size == 1 && slice[0] < 128 { + return wrapStreamError(ErrCanonSize, val.Type()) + } + case List: + return wrapStreamError(ErrExpectedString, val.Type()) + } + return nil +} + +func makeStructDecoder(typ reflect.Type) (decoder, error) { + fields, err := structFields(typ) + if err != nil { + return nil, err + } + dec := func(s *Stream, val reflect.Value) (err error) { + if _, err := s.List(); err != nil { + return wrapStreamError(err, typ) + } + for _, f := range fields { + err := f.info.decoder(s, val.Field(f.index)) + if err == EOL { + return &decodeError{msg: "too few elements", typ: typ} + } else if err != nil { + return addErrorContext(err, "."+typ.Field(f.index).Name) + } + } + return wrapStreamError(s.ListEnd(), typ) + } + return dec, nil +} + +// makePtrDecoder creates a decoder that decodes into +// the pointer's element type. +func makePtrDecoder(typ reflect.Type) (decoder, error) { + etype := typ.Elem() + etypeinfo := cachedTypeInfo1(etype, tags{}) + if etypeinfo.decoderErr != nil { + return nil, etypeinfo.decoderErr + } + dec := func(s *Stream, val reflect.Value) (err error) { + newval := val + if val.IsNil() { + newval = reflect.New(etype) + } + if err = etypeinfo.decoder(s, newval.Elem()); err == nil { + val.Set(newval) + } + return err + } + return dec, nil +} + +// makeOptionalPtrDecoder creates a decoder that decodes empty values +// as nil. Non-empty values are decoded into a value of the element type, +// just like makePtrDecoder does. +// +// This decoder is used for pointer-typed struct fields with struct tag "nil". +func makeOptionalPtrDecoder(typ reflect.Type) (decoder, error) { + etype := typ.Elem() + etypeinfo := cachedTypeInfo1(etype, tags{}) + if etypeinfo.decoderErr != nil { + return nil, etypeinfo.decoderErr + } + dec := func(s *Stream, val reflect.Value) (err error) { + kind, size, err := s.Kind() + if err != nil || size == 0 && kind != Byte { + // rearm s.Kind. This is important because the input + // position must advance to the next value even though + // we don't read anything. + s.kind = -1 + // set the pointer to nil. + val.Set(reflect.Zero(typ)) + return err + } + newval := val + if val.IsNil() { + newval = reflect.New(etype) + } + if err = etypeinfo.decoder(s, newval.Elem()); err == nil { + val.Set(newval) + } + return err + } + return dec, nil +} + +var ifsliceType = reflect.TypeOf([]interface{}{}) + +func decodeInterface(s *Stream, val reflect.Value) error { + if val.Type().NumMethod() != 0 { + return fmt.Errorf("rlp: type %v is not RLP-serializable", val.Type()) + } + kind, _, err := s.Kind() + if err != nil { + return err + } + if kind == List { + slice := reflect.New(ifsliceType).Elem() + if err := decodeListSlice(s, slice, decodeInterface); err != nil { + return err + } + val.Set(slice) + } else { + b, err := s.Bytes() + if err != nil { + return err + } + val.Set(reflect.ValueOf(b)) + } + return nil +} + +// This decoder is used for non-pointer values of types +// that implement the Decoder interface using a pointer receiver. +func decodeDecoderNoPtr(s *Stream, val reflect.Value) error { + return val.Addr().Interface().(Decoder).DecodeRLP(s) +} + +func decodeDecoder(s *Stream, val reflect.Value) error { + // Decoder instances are not handled using the pointer rule if the type + // implements Decoder with pointer receiver (i.e. always) + // because it might handle empty values specially. + // We need to allocate one here in this case, like makePtrDecoder does. + if val.Kind() == reflect.Ptr && val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + return val.Interface().(Decoder).DecodeRLP(s) +} + +// Kind represents the kind of value contained in an RLP stream. +type Kind int + +const ( + Byte Kind = iota + String + List +) + +func (k Kind) String() string { + switch k { + case Byte: + return "Byte" + case String: + return "String" + case List: + return "List" + default: + return fmt.Sprintf("Unknown(%d)", k) + } +} + +// ByteReader must be implemented by any input reader for a Stream. It +// is implemented by e.g. bufio.Reader and bytes.Reader. +type ByteReader interface { + io.Reader + io.ByteReader +} + +// Stream can be used for piecemeal decoding of an input stream. This +// is useful if the input is very large or if the decoding rules for a +// type depend on the input structure. Stream does not keep an +// internal buffer. After decoding a value, the input reader will be +// positioned just before the type information for the next value. +// +// When decoding a list and the input position reaches the declared +// length of the list, all operations will return error EOL. +// The end of the list must be acknowledged using ListEnd to continue +// reading the enclosing list. +// +// Stream is not safe for concurrent use. +type Stream struct { + r ByteReader + + // number of bytes remaining to be read from r. + remaining uint64 + limited bool + + // auxiliary buffer for integer decoding + uintbuf []byte + + kind Kind // kind of value ahead + size uint64 // size of value ahead + byteval byte // value of single byte in type tag + kinderr error // error from last readKind + stack []listpos +} + +type listpos struct{ pos, size uint64 } + +// NewStream creates a new decoding stream reading from r. +// +// If r implements the ByteReader interface, Stream will +// not introduce any buffering. +// +// For non-toplevel values, Stream returns ErrElemTooLarge +// for values that do not fit into the enclosing list. +// +// Stream supports an optional input limit. If a limit is set, the +// size of any toplevel value will be checked against the remaining +// input length. Stream operations that encounter a value exceeding +// the remaining input length will return ErrValueTooLarge. The limit +// can be set by passing a non-zero value for inputLimit. +// +// If r is a bytes.Reader or strings.Reader, the input limit is set to +// the length of r's underlying data unless an explicit limit is +// provided. +func NewStream(r io.Reader, inputLimit uint64) *Stream { + s := new(Stream) + s.Reset(r, inputLimit) + return s +} + +// NewListStream creates a new stream that pretends to be positioned +// at an encoded list of the given length. +func NewListStream(r io.Reader, len uint64) *Stream { + s := new(Stream) + s.Reset(r, len) + s.kind = List + s.size = len + return s +} + +// Bytes reads an RLP string and returns its contents as a byte slice. +// If the input does not contain an RLP string, the returned +// error will be ErrExpectedString. +func (s *Stream) Bytes() ([]byte, error) { + kind, size, err := s.Kind() + if err != nil { + return nil, err + } + switch kind { + case Byte: + s.kind = -1 // rearm Kind + return []byte{s.byteval}, nil + case String: + b := make([]byte, size) + if err = s.readFull(b); err != nil { + return nil, err + } + if size == 1 && b[0] < 128 { + return nil, ErrCanonSize + } + return b, nil + default: + return nil, ErrExpectedString + } +} + +// Raw reads a raw encoded value including RLP type information. +func (s *Stream) Raw() ([]byte, error) { + kind, size, err := s.Kind() + if err != nil { + return nil, err + } + if kind == Byte { + s.kind = -1 // rearm Kind + return []byte{s.byteval}, nil + } + // the original header has already been read and is no longer + // available. read content and put a new header in front of it. + start := headsize(size) + buf := make([]byte, uint64(start)+size) + if err := s.readFull(buf[start:]); err != nil { + return nil, err + } + if kind == String { + puthead(buf, 0x80, 0xB7, size) + } else { + puthead(buf, 0xC0, 0xF7, size) + } + return buf, nil +} + +// Uint reads an RLP string of up to 8 bytes and returns its contents +// as an unsigned integer. If the input does not contain an RLP string, the +// returned error will be ErrExpectedString. +func (s *Stream) Uint() (uint64, error) { + return s.uint(64) +} + +func (s *Stream) uint(maxbits int) (uint64, error) { + kind, size, err := s.Kind() + if err != nil { + return 0, err + } + switch kind { + case Byte: + if s.byteval == 0 { + return 0, ErrCanonInt + } + s.kind = -1 // rearm Kind + return uint64(s.byteval), nil + case String: + if size > uint64(maxbits/8) { + return 0, errUintOverflow + } + v, err := s.readUint(byte(size)) + switch { + case err == ErrCanonSize: + // Adjust error because we're not reading a size right now. + return 0, ErrCanonInt + case err != nil: + return 0, err + case size > 0 && v < 128: + return 0, ErrCanonSize + default: + return v, nil + } + default: + return 0, ErrExpectedString + } +} + +// Bool reads an RLP string of up to 1 byte and returns its contents +// as a boolean. If the input does not contain an RLP string, the +// returned error will be ErrExpectedString. +func (s *Stream) Bool() (bool, error) { + num, err := s.uint(8) + if err != nil { + return false, err + } + switch num { + case 0: + return false, nil + case 1: + return true, nil + default: + return false, fmt.Errorf("rlp: invalid boolean value: %d", num) + } +} + +// List starts decoding an RLP list. If the input does not contain a +// list, the returned error will be ErrExpectedList. When the list's +// end has been reached, any Stream operation will return EOL. +func (s *Stream) List() (size uint64, err error) { + kind, size, err := s.Kind() + if err != nil { + return 0, err + } + if kind != List { + return 0, ErrExpectedList + } + s.stack = append(s.stack, listpos{0, size}) + s.kind = -1 + s.size = 0 + return size, nil +} + +// ListEnd returns to the enclosing list. +// The input reader must be positioned at the end of a list. +func (s *Stream) ListEnd() error { + if len(s.stack) == 0 { + return errNotInList + } + tos := s.stack[len(s.stack)-1] + if tos.pos != tos.size { + return errNotAtEOL + } + s.stack = s.stack[:len(s.stack)-1] // pop + if len(s.stack) > 0 { + s.stack[len(s.stack)-1].pos += tos.size + } + s.kind = -1 + s.size = 0 + return nil +} + +// Decode decodes a value and stores the result in the value pointed +// to by val. Please see the documentation for the Decode function +// to learn about the decoding rules. +func (s *Stream) Decode(val interface{}) error { + if val == nil { + return errDecodeIntoNil + } + rval := reflect.ValueOf(val) + rtyp := rval.Type() + if rtyp.Kind() != reflect.Ptr { + return errNoPointer + } + if rval.IsNil() { + return errDecodeIntoNil + } + decoder, err := cachedDecoder(rtyp.Elem()) + if err != nil { + return err + } + + err = decoder(s, rval.Elem()) + if decErr, ok := err.(*decodeError); ok && len(decErr.ctx) > 0 { + // add decode target type to error so context has more meaning + decErr.ctx = append(decErr.ctx, fmt.Sprint("(", rtyp.Elem(), ")")) + } + return err +} + +// Reset discards any information about the current decoding context +// and starts reading from r. This method is meant to facilitate reuse +// of a preallocated Stream across many decoding operations. +// +// If r does not also implement ByteReader, Stream will do its own +// buffering. +func (s *Stream) Reset(r io.Reader, inputLimit uint64) { + if inputLimit > 0 { + s.remaining = inputLimit + s.limited = true + } else { + // Attempt to automatically discover + // the limit when reading from a byte slice. + switch br := r.(type) { + case *bytes.Reader: + s.remaining = uint64(br.Len()) + s.limited = true + case *strings.Reader: + s.remaining = uint64(br.Len()) + s.limited = true + default: + s.limited = false + } + } + // Wrap r with a buffer if it doesn't have one. + bufr, ok := r.(ByteReader) + if !ok { + bufr = bufio.NewReader(r) + } + s.r = bufr + // Reset the decoding context. + s.stack = s.stack[:0] + s.size = 0 + s.kind = -1 + s.kinderr = nil + if s.uintbuf == nil { + s.uintbuf = make([]byte, 8) + } + s.byteval = 0 +} + +// Kind returns the kind and size of the next value in the +// input stream. +// +// The returned size is the number of bytes that make up the value. +// For kind == Byte, the size is zero because the value is +// contained in the type tag. +// +// The first call to Kind will read size information from the input +// reader and leave it positioned at the start of the actual bytes of +// the value. Subsequent calls to Kind (until the value is decoded) +// will not advance the input reader and return cached information. +func (s *Stream) Kind() (kind Kind, size uint64, err error) { + var tos *listpos + if len(s.stack) > 0 { + tos = &s.stack[len(s.stack)-1] + } + if s.kind < 0 { + s.kinderr = nil + // Don't read further if we're at the end of the + // innermost list. + if tos != nil && tos.pos == tos.size { + return 0, 0, EOL + } + s.kind, s.size, s.kinderr = s.readKind() + if s.kinderr == nil { + if tos == nil { + // At toplevel, check that the value is smaller + // than the remaining input length. + if s.limited && s.size > s.remaining { + s.kinderr = ErrValueTooLarge + } + } else { + // Inside a list, check that the value doesn't overflow the list. + if s.size > tos.size-tos.pos { + s.kinderr = ErrElemTooLarge + } + } + } + } + // Note: this might return a sticky error generated + // by an earlier call to readKind. + return s.kind, s.size, s.kinderr +} + +func (s *Stream) readKind() (kind Kind, size uint64, err error) { + b, err := s.readByte() + if err != nil { + if len(s.stack) == 0 { + // At toplevel, Adjust the error to actual EOF. io.EOF is + // used by callers to determine when to stop decoding. + switch err { + case io.ErrUnexpectedEOF: + err = io.EOF + case ErrValueTooLarge: + err = io.EOF + } + } + return 0, 0, err + } + s.byteval = 0 + switch { + case b < 0x80: + // For a single byte whose value is in the [0x00, 0x7F] range, that byte + // is its own RLP encoding. + s.byteval = b + return Byte, 0, nil + case b < 0xB8: + // Otherwise, if a string is 0-55 bytes long, + // the RLP encoding consists of a single byte with value 0x80 plus the + // length of the string followed by the string. The range of the first + // byte is thus [0x80, 0xB7]. + return String, uint64(b - 0x80), nil + case b < 0xC0: + // If a string is more than 55 bytes long, the + // RLP encoding consists of a single byte with value 0xB7 plus the length + // of the length of the string in binary form, followed by the length of + // the string, followed by the string. For example, a length-1024 string + // would be encoded as 0xB90400 followed by the string. The range of + // the first byte is thus [0xB8, 0xBF]. + size, err = s.readUint(b - 0xB7) + if err == nil && size < 56 { + err = ErrCanonSize + } + return String, size, err + case b < 0xF8: + // If the total payload of a list + // (i.e. the combined length of all its items) is 0-55 bytes long, the + // RLP encoding consists of a single byte with value 0xC0 plus the length + // of the list followed by the concatenation of the RLP encodings of the + // items. The range of the first byte is thus [0xC0, 0xF7]. + return List, uint64(b - 0xC0), nil + default: + // If the total payload of a list is more than 55 bytes long, + // the RLP encoding consists of a single byte with value 0xF7 + // plus the length of the length of the payload in binary + // form, followed by the length of the payload, followed by + // the concatenation of the RLP encodings of the items. The + // range of the first byte is thus [0xF8, 0xFF]. + size, err = s.readUint(b - 0xF7) + if err == nil && size < 56 { + err = ErrCanonSize + } + return List, size, err + } +} + +func (s *Stream) readUint(size byte) (uint64, error) { + switch size { + case 0: + s.kind = -1 // rearm Kind + return 0, nil + case 1: + b, err := s.readByte() + return uint64(b), err + default: + start := int(8 - size) + for i := 0; i < start; i++ { + s.uintbuf[i] = 0 + } + if err := s.readFull(s.uintbuf[start:]); err != nil { + return 0, err + } + if s.uintbuf[start] == 0 { + // Note: readUint is also used to decode integer + // values. The error needs to be adjusted to become + // ErrCanonInt in this case. + return 0, ErrCanonSize + } + return binary.BigEndian.Uint64(s.uintbuf), nil + } +} + +func (s *Stream) readFull(buf []byte) (err error) { + if err := s.willRead(uint64(len(buf))); err != nil { + return err + } + var nn, n int + for n < len(buf) && err == nil { + nn, err = s.r.Read(buf[n:]) + n += nn + } + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return err +} + +func (s *Stream) readByte() (byte, error) { + if err := s.willRead(1); err != nil { + return 0, err + } + b, err := s.r.ReadByte() + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return b, err +} + +func (s *Stream) willRead(n uint64) error { + s.kind = -1 // rearm Kind + + if len(s.stack) > 0 { + // check list overflow + tos := s.stack[len(s.stack)-1] + if n > tos.size-tos.pos { + return ErrElemTooLarge + } + s.stack[len(s.stack)-1].pos += n + } + if s.limited { + if n > s.remaining { + return ErrValueTooLarge + } + s.remaining -= n + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/rlp/encode.go b/vendor/github.com/ethereum/go-ethereum/rlp/encode.go new file mode 100644 index 00000000..f255c38a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rlp/encode.go @@ -0,0 +1,651 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rlp + +import ( + "fmt" + "io" + "math/big" + "reflect" + "sync" +) + +var ( + // Common encoded values. + // These are useful when implementing EncodeRLP. + EmptyString = []byte{0x80} + EmptyList = []byte{0xC0} +) + +// Encoder is implemented by types that require custom +// encoding rules or want to encode private fields. +type Encoder interface { + // EncodeRLP should write the RLP encoding of its receiver to w. + // If the implementation is a pointer method, it may also be + // called for nil pointers. + // + // Implementations should generate valid RLP. The data written is + // not verified at the moment, but a future version might. It is + // recommended to write only a single value but writing multiple + // values or no value at all is also permitted. + EncodeRLP(io.Writer) error +} + +// Encode writes the RLP encoding of val to w. Note that Encode may +// perform many small writes in some cases. Consider making w +// buffered. +// +// Encode uses the following type-dependent encoding rules: +// +// If the type implements the Encoder interface, Encode calls +// EncodeRLP. This is true even for nil pointers, please see the +// documentation for Encoder. +// +// To encode a pointer, the value being pointed to is encoded. For nil +// pointers, Encode will encode the zero value of the type. A nil +// pointer to a struct type always encodes as an empty RLP list. +// A nil pointer to an array encodes as an empty list (or empty string +// if the array has element type byte). +// +// Struct values are encoded as an RLP list of all their encoded +// public fields. Recursive struct types are supported. +// +// To encode slices and arrays, the elements are encoded as an RLP +// list of the value's elements. Note that arrays and slices with +// element type uint8 or byte are always encoded as an RLP string. +// +// A Go string is encoded as an RLP string. +// +// An unsigned integer value is encoded as an RLP string. Zero always +// encodes as an empty RLP string. Encode also supports *big.Int. +// +// Boolean values are encoded as unsigned integers zero (false) and one (true). +// +// An interface value encodes as the value contained in the interface. +// +// Signed integers are not supported, nor are floating point numbers, maps, +// channels and functions. +func Encode(w io.Writer, val interface{}) error { + if outer, ok := w.(*encbuf); ok { + // Encode was called by some type's EncodeRLP. + // Avoid copying by writing to the outer encbuf directly. + return outer.encode(val) + } + eb := encbufPool.Get().(*encbuf) + defer encbufPool.Put(eb) + eb.reset() + if err := eb.encode(val); err != nil { + return err + } + return eb.toWriter(w) +} + +// EncodeToBytes returns the RLP encoding of val. +// Please see the documentation of Encode for the encoding rules. +func EncodeToBytes(val interface{}) ([]byte, error) { + eb := encbufPool.Get().(*encbuf) + defer encbufPool.Put(eb) + eb.reset() + if err := eb.encode(val); err != nil { + return nil, err + } + return eb.toBytes(), nil +} + +// EncodeToReader returns a reader from which the RLP encoding of val +// can be read. The returned size is the total size of the encoded +// data. +// +// Please see the documentation of Encode for the encoding rules. +func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { + eb := encbufPool.Get().(*encbuf) + eb.reset() + if err := eb.encode(val); err != nil { + return 0, nil, err + } + return eb.size(), &encReader{buf: eb}, nil +} + +type encbuf struct { + str []byte // string data, contains everything except list headers + lheads []*listhead // all list headers + lhsize int // sum of sizes of all encoded list headers + sizebuf []byte // 9-byte auxiliary buffer for uint encoding +} + +type listhead struct { + offset int // index of this header in string data + size int // total size of encoded data (including list headers) +} + +// encode writes head to the given buffer, which must be at least +// 9 bytes long. It returns the encoded bytes. +func (head *listhead) encode(buf []byte) []byte { + return buf[:puthead(buf, 0xC0, 0xF7, uint64(head.size))] +} + +// headsize returns the size of a list or string header +// for a value of the given size. +func headsize(size uint64) int { + if size < 56 { + return 1 + } + return 1 + intsize(size) +} + +// puthead writes a list or string header to buf. +// buf must be at least 9 bytes long. +func puthead(buf []byte, smalltag, largetag byte, size uint64) int { + if size < 56 { + buf[0] = smalltag + byte(size) + return 1 + } + sizesize := putint(buf[1:], size) + buf[0] = largetag + byte(sizesize) + return sizesize + 1 +} + +// encbufs are pooled. +var encbufPool = sync.Pool{ + New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} }, +} + +func (w *encbuf) reset() { + w.lhsize = 0 + if w.str != nil { + w.str = w.str[:0] + } + if w.lheads != nil { + w.lheads = w.lheads[:0] + } +} + +// encbuf implements io.Writer so it can be passed it into EncodeRLP. +func (w *encbuf) Write(b []byte) (int, error) { + w.str = append(w.str, b...) + return len(b), nil +} + +func (w *encbuf) encode(val interface{}) error { + rval := reflect.ValueOf(val) + writer, err := cachedWriter(rval.Type()) + if err != nil { + return err + } + return writer(rval, w) +} + +func (w *encbuf) encodeStringHeader(size int) { + if size < 56 { + w.str = append(w.str, 0x80+byte(size)) + } else { + // TODO: encode to w.str directly + sizesize := putint(w.sizebuf[1:], uint64(size)) + w.sizebuf[0] = 0xB7 + byte(sizesize) + w.str = append(w.str, w.sizebuf[:sizesize+1]...) + } +} + +func (w *encbuf) encodeString(b []byte) { + if len(b) == 1 && b[0] <= 0x7F { + // fits single byte, no string header + w.str = append(w.str, b[0]) + } else { + w.encodeStringHeader(len(b)) + w.str = append(w.str, b...) + } +} + +func (w *encbuf) list() *listhead { + lh := &listhead{offset: len(w.str), size: w.lhsize} + w.lheads = append(w.lheads, lh) + return lh +} + +func (w *encbuf) listEnd(lh *listhead) { + lh.size = w.size() - lh.offset - lh.size + if lh.size < 56 { + w.lhsize++ // length encoded into kind tag + } else { + w.lhsize += 1 + intsize(uint64(lh.size)) + } +} + +func (w *encbuf) size() int { + return len(w.str) + w.lhsize +} + +func (w *encbuf) toBytes() []byte { + out := make([]byte, w.size()) + strpos := 0 + pos := 0 + for _, head := range w.lheads { + // write string data before header + n := copy(out[pos:], w.str[strpos:head.offset]) + pos += n + strpos += n + // write the header + enc := head.encode(out[pos:]) + pos += len(enc) + } + // copy string data after the last list header + copy(out[pos:], w.str[strpos:]) + return out +} + +func (w *encbuf) toWriter(out io.Writer) (err error) { + strpos := 0 + for _, head := range w.lheads { + // write string data before header + if head.offset-strpos > 0 { + n, err := out.Write(w.str[strpos:head.offset]) + strpos += n + if err != nil { + return err + } + } + // write the header + enc := head.encode(w.sizebuf) + if _, err = out.Write(enc); err != nil { + return err + } + } + if strpos < len(w.str) { + // write string data after the last list header + _, err = out.Write(w.str[strpos:]) + } + return err +} + +// encReader is the io.Reader returned by EncodeToReader. +// It releases its encbuf at EOF. +type encReader struct { + buf *encbuf // the buffer we're reading from. this is nil when we're at EOF. + lhpos int // index of list header that we're reading + strpos int // current position in string buffer + piece []byte // next piece to be read +} + +func (r *encReader) Read(b []byte) (n int, err error) { + for { + if r.piece = r.next(); r.piece == nil { + // Put the encode buffer back into the pool at EOF when it + // is first encountered. Subsequent calls still return EOF + // as the error but the buffer is no longer valid. + if r.buf != nil { + encbufPool.Put(r.buf) + r.buf = nil + } + return n, io.EOF + } + nn := copy(b[n:], r.piece) + n += nn + if nn < len(r.piece) { + // piece didn't fit, see you next time. + r.piece = r.piece[nn:] + return n, nil + } + r.piece = nil + } +} + +// next returns the next piece of data to be read. +// it returns nil at EOF. +func (r *encReader) next() []byte { + switch { + case r.buf == nil: + return nil + + case r.piece != nil: + // There is still data available for reading. + return r.piece + + case r.lhpos < len(r.buf.lheads): + // We're before the last list header. + head := r.buf.lheads[r.lhpos] + sizebefore := head.offset - r.strpos + if sizebefore > 0 { + // String data before header. + p := r.buf.str[r.strpos:head.offset] + r.strpos += sizebefore + return p + } + r.lhpos++ + return head.encode(r.buf.sizebuf) + + case r.strpos < len(r.buf.str): + // String data at the end, after all list headers. + p := r.buf.str[r.strpos:] + r.strpos = len(r.buf.str) + return p + + default: + return nil + } +} + +var ( + encoderInterface = reflect.TypeOf(new(Encoder)).Elem() + big0 = big.NewInt(0) +) + +// makeWriter creates a writer function for the given type. +func makeWriter(typ reflect.Type, ts tags) (writer, error) { + kind := typ.Kind() + switch { + case typ == rawValueType: + return writeRawValue, nil + case typ.Implements(encoderInterface): + return writeEncoder, nil + case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): + return writeEncoderNoPtr, nil + case kind == reflect.Interface: + return writeInterface, nil + case typ.AssignableTo(reflect.PtrTo(bigInt)): + return writeBigIntPtr, nil + case typ.AssignableTo(bigInt): + return writeBigIntNoPtr, nil + case isUint(kind): + return writeUint, nil + case kind == reflect.Bool: + return writeBool, nil + case kind == reflect.String: + return writeString, nil + case kind == reflect.Slice && isByte(typ.Elem()): + return writeBytes, nil + case kind == reflect.Array && isByte(typ.Elem()): + return writeByteArray, nil + case kind == reflect.Slice || kind == reflect.Array: + return makeSliceWriter(typ, ts) + case kind == reflect.Struct: + return makeStructWriter(typ) + case kind == reflect.Ptr: + return makePtrWriter(typ) + default: + return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) + } +} + +func isByte(typ reflect.Type) bool { + return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) +} + +func writeRawValue(val reflect.Value, w *encbuf) error { + w.str = append(w.str, val.Bytes()...) + return nil +} + +func writeUint(val reflect.Value, w *encbuf) error { + i := val.Uint() + if i == 0 { + w.str = append(w.str, 0x80) + } else if i < 128 { + // fits single byte + w.str = append(w.str, byte(i)) + } else { + // TODO: encode int to w.str directly + s := putint(w.sizebuf[1:], i) + w.sizebuf[0] = 0x80 + byte(s) + w.str = append(w.str, w.sizebuf[:s+1]...) + } + return nil +} + +func writeBool(val reflect.Value, w *encbuf) error { + if val.Bool() { + w.str = append(w.str, 0x01) + } else { + w.str = append(w.str, 0x80) + } + return nil +} + +func writeBigIntPtr(val reflect.Value, w *encbuf) error { + ptr := val.Interface().(*big.Int) + if ptr == nil { + w.str = append(w.str, 0x80) + return nil + } + return writeBigInt(ptr, w) +} + +func writeBigIntNoPtr(val reflect.Value, w *encbuf) error { + i := val.Interface().(big.Int) + return writeBigInt(&i, w) +} + +func writeBigInt(i *big.Int, w *encbuf) error { + if cmp := i.Cmp(big0); cmp == -1 { + return fmt.Errorf("rlp: cannot encode negative *big.Int") + } else if cmp == 0 { + w.str = append(w.str, 0x80) + } else { + w.encodeString(i.Bytes()) + } + return nil +} + +func writeBytes(val reflect.Value, w *encbuf) error { + w.encodeString(val.Bytes()) + return nil +} + +func writeByteArray(val reflect.Value, w *encbuf) error { + if !val.CanAddr() { + // Slice requires the value to be addressable. + // Make it addressable by copying. + copy := reflect.New(val.Type()).Elem() + copy.Set(val) + val = copy + } + size := val.Len() + slice := val.Slice(0, size).Bytes() + w.encodeString(slice) + return nil +} + +func writeString(val reflect.Value, w *encbuf) error { + s := val.String() + if len(s) == 1 && s[0] <= 0x7f { + // fits single byte, no string header + w.str = append(w.str, s[0]) + } else { + w.encodeStringHeader(len(s)) + w.str = append(w.str, s...) + } + return nil +} + +func writeEncoder(val reflect.Value, w *encbuf) error { + return val.Interface().(Encoder).EncodeRLP(w) +} + +// writeEncoderNoPtr handles non-pointer values that implement Encoder +// with a pointer receiver. +func writeEncoderNoPtr(val reflect.Value, w *encbuf) error { + if !val.CanAddr() { + // We can't get the address. It would be possible to make the + // value addressable by creating a shallow copy, but this + // creates other problems so we're not doing it (yet). + // + // package json simply doesn't call MarshalJSON for cases like + // this, but encodes the value as if it didn't implement the + // interface. We don't want to handle it that way. + return fmt.Errorf("rlp: game over: unadressable value of type %v, EncodeRLP is pointer method", val.Type()) + } + return val.Addr().Interface().(Encoder).EncodeRLP(w) +} + +func writeInterface(val reflect.Value, w *encbuf) error { + if val.IsNil() { + // Write empty list. This is consistent with the previous RLP + // encoder that we had and should therefore avoid any + // problems. + w.str = append(w.str, 0xC0) + return nil + } + eval := val.Elem() + writer, err := cachedWriter(eval.Type()) + if err != nil { + return err + } + return writer(eval, w) +} + +func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { + etypeinfo := cachedTypeInfo1(typ.Elem(), tags{}) + if etypeinfo.writerErr != nil { + return nil, etypeinfo.writerErr + } + writer := func(val reflect.Value, w *encbuf) error { + if !ts.tail { + defer w.listEnd(w.list()) + } + vlen := val.Len() + for i := 0; i < vlen; i++ { + if err := etypeinfo.writer(val.Index(i), w); err != nil { + return err + } + } + return nil + } + return writer, nil +} + +func makeStructWriter(typ reflect.Type) (writer, error) { + fields, err := structFields(typ) + if err != nil { + return nil, err + } + writer := func(val reflect.Value, w *encbuf) error { + lh := w.list() + for _, f := range fields { + if err := f.info.writer(val.Field(f.index), w); err != nil { + return err + } + } + w.listEnd(lh) + return nil + } + return writer, nil +} + +func makePtrWriter(typ reflect.Type) (writer, error) { + etypeinfo := cachedTypeInfo1(typ.Elem(), tags{}) + if etypeinfo.writerErr != nil { + return nil, etypeinfo.writerErr + } + + // determine nil pointer handler + var nilfunc func(*encbuf) error + kind := typ.Elem().Kind() + switch { + case kind == reflect.Array && isByte(typ.Elem().Elem()): + nilfunc = func(w *encbuf) error { + w.str = append(w.str, 0x80) + return nil + } + case kind == reflect.Struct || kind == reflect.Array: + nilfunc = func(w *encbuf) error { + // encoding the zero value of a struct/array could trigger + // infinite recursion, avoid that. + w.listEnd(w.list()) + return nil + } + default: + zero := reflect.Zero(typ.Elem()) + nilfunc = func(w *encbuf) error { + return etypeinfo.writer(zero, w) + } + } + + writer := func(val reflect.Value, w *encbuf) error { + if val.IsNil() { + return nilfunc(w) + } + return etypeinfo.writer(val.Elem(), w) + } + return writer, nil +} + +// putint writes i to the beginning of b in big endian byte +// order, using the least number of bytes needed to represent i. +func putint(b []byte, i uint64) (size int) { + switch { + case i < (1 << 8): + b[0] = byte(i) + return 1 + case i < (1 << 16): + b[0] = byte(i >> 8) + b[1] = byte(i) + return 2 + case i < (1 << 24): + b[0] = byte(i >> 16) + b[1] = byte(i >> 8) + b[2] = byte(i) + return 3 + case i < (1 << 32): + b[0] = byte(i >> 24) + b[1] = byte(i >> 16) + b[2] = byte(i >> 8) + b[3] = byte(i) + return 4 + case i < (1 << 40): + b[0] = byte(i >> 32) + b[1] = byte(i >> 24) + b[2] = byte(i >> 16) + b[3] = byte(i >> 8) + b[4] = byte(i) + return 5 + case i < (1 << 48): + b[0] = byte(i >> 40) + b[1] = byte(i >> 32) + b[2] = byte(i >> 24) + b[3] = byte(i >> 16) + b[4] = byte(i >> 8) + b[5] = byte(i) + return 6 + case i < (1 << 56): + b[0] = byte(i >> 48) + b[1] = byte(i >> 40) + b[2] = byte(i >> 32) + b[3] = byte(i >> 24) + b[4] = byte(i >> 16) + b[5] = byte(i >> 8) + b[6] = byte(i) + return 7 + default: + b[0] = byte(i >> 56) + b[1] = byte(i >> 48) + b[2] = byte(i >> 40) + b[3] = byte(i >> 32) + b[4] = byte(i >> 24) + b[5] = byte(i >> 16) + b[6] = byte(i >> 8) + b[7] = byte(i) + return 8 + } +} + +// intsize computes the minimum number of bytes required to store i. +func intsize(i uint64) (size int) { + for size = 1; ; size++ { + if i >>= 8; i == 0 { + return size + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/rlp/typecache.go b/vendor/github.com/ethereum/go-ethereum/rlp/typecache.go new file mode 100644 index 00000000..ab5ee3da --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rlp/typecache.go @@ -0,0 +1,165 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rlp + +import ( + "fmt" + "reflect" + "strings" + "sync" +) + +var ( + typeCacheMutex sync.RWMutex + typeCache = make(map[typekey]*typeinfo) +) + +type typeinfo struct { + decoder decoder + decoderErr error // error from makeDecoder + writer writer + writerErr error // error from makeWriter +} + +// represents struct tags +type tags struct { + // rlp:"nil" controls whether empty input results in a nil pointer. + nilOK bool + // rlp:"tail" controls whether this field swallows additional list + // elements. It can only be set for the last field, which must be + // of slice type. + tail bool + // rlp:"-" ignores fields. + ignored bool +} + +type typekey struct { + reflect.Type + // the key must include the struct tags because they + // might generate a different decoder. + tags +} + +type decoder func(*Stream, reflect.Value) error + +type writer func(reflect.Value, *encbuf) error + +func cachedDecoder(typ reflect.Type) (decoder, error) { + info := cachedTypeInfo(typ, tags{}) + return info.decoder, info.decoderErr +} + +func cachedWriter(typ reflect.Type) (writer, error) { + info := cachedTypeInfo(typ, tags{}) + return info.writer, info.writerErr +} + +func cachedTypeInfo(typ reflect.Type, tags tags) *typeinfo { + typeCacheMutex.RLock() + info := typeCache[typekey{typ, tags}] + typeCacheMutex.RUnlock() + if info != nil { + return info + } + // not in the cache, need to generate info for this type. + typeCacheMutex.Lock() + defer typeCacheMutex.Unlock() + return cachedTypeInfo1(typ, tags) +} + +func cachedTypeInfo1(typ reflect.Type, tags tags) *typeinfo { + key := typekey{typ, tags} + info := typeCache[key] + if info != nil { + // another goroutine got the write lock first + return info + } + // put a dummy value into the cache before generating. + // if the generator tries to lookup itself, it will get + // the dummy value and won't call itself recursively. + info = new(typeinfo) + typeCache[key] = info + info.generate(typ, tags) + return info +} + +type field struct { + index int + info *typeinfo +} + +func structFields(typ reflect.Type) (fields []field, err error) { + lastPublic := lastPublicField(typ) + for i := 0; i < typ.NumField(); i++ { + if f := typ.Field(i); f.PkgPath == "" { // exported + tags, err := parseStructTag(typ, i, lastPublic) + if err != nil { + return nil, err + } + if tags.ignored { + continue + } + info := cachedTypeInfo1(f.Type, tags) + fields = append(fields, field{i, info}) + } + } + return fields, nil +} + +func parseStructTag(typ reflect.Type, fi, lastPublic int) (tags, error) { + f := typ.Field(fi) + var ts tags + for _, t := range strings.Split(f.Tag.Get("rlp"), ",") { + switch t = strings.TrimSpace(t); t { + case "": + case "-": + ts.ignored = true + case "nil": + ts.nilOK = true + case "tail": + ts.tail = true + if fi != lastPublic { + return ts, fmt.Errorf(`rlp: invalid struct tag "tail" for %v.%s (must be on last field)`, typ, f.Name) + } + if f.Type.Kind() != reflect.Slice { + return ts, fmt.Errorf(`rlp: invalid struct tag "tail" for %v.%s (field type is not slice)`, typ, f.Name) + } + default: + return ts, fmt.Errorf("rlp: unknown struct tag %q on %v.%s", t, typ, f.Name) + } + } + return ts, nil +} + +func lastPublicField(typ reflect.Type) int { + last := 0 + for i := 0; i < typ.NumField(); i++ { + if typ.Field(i).PkgPath == "" { + last = i + } + } + return last +} + +func (i *typeinfo) generate(typ reflect.Type, tags tags) { + i.decoder, i.decoderErr = makeDecoder(typ, tags) + i.writer, i.writerErr = makeWriter(typ, tags) +} + +func isUint(k reflect.Kind) bool { + return k >= reflect.Uint && k <= reflect.Uintptr +} diff --git a/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix.go b/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix.go new file mode 100644 index 00000000..2f98d649 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix.go @@ -0,0 +1,33 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris + +package rpc + +/* +#include + +int max_socket_path_size() { +struct sockaddr_un s; +return sizeof(s.sun_path); +} +*/ +import "C" + +var ( + max_path_size = C.max_socket_path_size() +) diff --git a/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix_nocgo.go b/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix_nocgo.go new file mode 100644 index 00000000..ecb231f9 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rpc/constants_unix_nocgo.go @@ -0,0 +1,25 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build !cgo,!windows + +package rpc + +var ( + // On Linux, sun_path is 108 bytes in size + // see http://man7.org/linux/man-pages/man7/unix.7.html + max_path_size = 108 +) diff --git a/vendor/github.com/ethereum/go-ethereum/rpc/handler.go b/vendor/github.com/ethereum/go-ethereum/rpc/handler.go new file mode 100644 index 00000000..02ab06b6 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rpc/handler.go @@ -0,0 +1,397 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rpc + +import ( + "context" + "encoding/json" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" +) + +// handler handles JSON-RPC messages. There is one handler per connection. Note that +// handler is not safe for concurrent use. Message handling never blocks indefinitely +// because RPCs are processed on background goroutines launched by handler. +// +// The entry points for incoming messages are: +// +// h.handleMsg(message) +// h.handleBatch(message) +// +// Outgoing calls use the requestOp struct. Register the request before sending it +// on the connection: +// +// op := &requestOp{ids: ...} +// h.addRequestOp(op) +// +// Now send the request, then wait for the reply to be delivered through handleMsg: +// +// if err := op.wait(...); err != nil { +// h.removeRequestOp(op) // timeout, etc. +// } +// +type handler struct { + reg *serviceRegistry + unsubscribeCb *callback + idgen func() ID // subscription ID generator + respWait map[string]*requestOp // active client requests + clientSubs map[string]*ClientSubscription // active client subscriptions + callWG sync.WaitGroup // pending call goroutines + rootCtx context.Context // canceled by close() + cancelRoot func() // cancel function for rootCtx + conn jsonWriter // where responses will be sent + log log.Logger + allowSubscribe bool + + subLock sync.Mutex + serverSubs map[ID]*Subscription +} + +type callProc struct { + ctx context.Context + notifiers []*Notifier +} + +func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg *serviceRegistry) *handler { + rootCtx, cancelRoot := context.WithCancel(connCtx) + h := &handler{ + reg: reg, + idgen: idgen, + conn: conn, + respWait: make(map[string]*requestOp), + clientSubs: make(map[string]*ClientSubscription), + rootCtx: rootCtx, + cancelRoot: cancelRoot, + allowSubscribe: true, + serverSubs: make(map[ID]*Subscription), + log: log.Root(), + } + if conn.RemoteAddr() != "" { + h.log = h.log.New("conn", conn.RemoteAddr()) + } + h.unsubscribeCb = newCallback(reflect.Value{}, reflect.ValueOf(h.unsubscribe)) + return h +} + +// handleBatch executes all messages in a batch and returns the responses. +func (h *handler) handleBatch(msgs []*jsonrpcMessage) { + // Emit error response for empty batches: + if len(msgs) == 0 { + h.startCallProc(func(cp *callProc) { + h.conn.Write(cp.ctx, errorMessage(&invalidRequestError{"empty batch"})) + }) + return + } + + // Handle non-call messages first: + calls := make([]*jsonrpcMessage, 0, len(msgs)) + for _, msg := range msgs { + if handled := h.handleImmediate(msg); !handled { + calls = append(calls, msg) + } + } + if len(calls) == 0 { + return + } + // Process calls on a goroutine because they may block indefinitely: + h.startCallProc(func(cp *callProc) { + answers := make([]*jsonrpcMessage, 0, len(msgs)) + for _, msg := range calls { + if answer := h.handleCallMsg(cp, msg); answer != nil { + answers = append(answers, answer) + } + } + h.addSubscriptions(cp.notifiers) + if len(answers) > 0 { + h.conn.Write(cp.ctx, answers) + } + for _, n := range cp.notifiers { + n.activate() + } + }) +} + +// handleMsg handles a single message. +func (h *handler) handleMsg(msg *jsonrpcMessage) { + if ok := h.handleImmediate(msg); ok { + return + } + h.startCallProc(func(cp *callProc) { + answer := h.handleCallMsg(cp, msg) + h.addSubscriptions(cp.notifiers) + if answer != nil { + h.conn.Write(cp.ctx, answer) + } + for _, n := range cp.notifiers { + n.activate() + } + }) +} + +// close cancels all requests except for inflightReq and waits for +// call goroutines to shut down. +func (h *handler) close(err error, inflightReq *requestOp) { + h.cancelAllRequests(err, inflightReq) + h.callWG.Wait() + h.cancelRoot() + h.cancelServerSubscriptions(err) +} + +// addRequestOp registers a request operation. +func (h *handler) addRequestOp(op *requestOp) { + for _, id := range op.ids { + h.respWait[string(id)] = op + } +} + +// removeRequestOps stops waiting for the given request IDs. +func (h *handler) removeRequestOp(op *requestOp) { + for _, id := range op.ids { + delete(h.respWait, string(id)) + } +} + +// cancelAllRequests unblocks and removes pending requests and active subscriptions. +func (h *handler) cancelAllRequests(err error, inflightReq *requestOp) { + didClose := make(map[*requestOp]bool) + if inflightReq != nil { + didClose[inflightReq] = true + } + + for id, op := range h.respWait { + // Remove the op so that later calls will not close op.resp again. + delete(h.respWait, id) + + if !didClose[op] { + op.err = err + close(op.resp) + didClose[op] = true + } + } + for id, sub := range h.clientSubs { + delete(h.clientSubs, id) + sub.quitWithError(err, false) + } +} + +func (h *handler) addSubscriptions(nn []*Notifier) { + h.subLock.Lock() + defer h.subLock.Unlock() + + for _, n := range nn { + if sub := n.takeSubscription(); sub != nil { + h.serverSubs[sub.ID] = sub + } + } +} + +// cancelServerSubscriptions removes all subscriptions and closes their error channels. +func (h *handler) cancelServerSubscriptions(err error) { + h.subLock.Lock() + defer h.subLock.Unlock() + + for id, s := range h.serverSubs { + s.err <- err + close(s.err) + delete(h.serverSubs, id) + } +} + +// startCallProc runs fn in a new goroutine and starts tracking it in the h.calls wait group. +func (h *handler) startCallProc(fn func(*callProc)) { + h.callWG.Add(1) + go func() { + ctx, cancel := context.WithCancel(h.rootCtx) + defer h.callWG.Done() + defer cancel() + fn(&callProc{ctx: ctx}) + }() +} + +// handleImmediate executes non-call messages. It returns false if the message is a +// call or requires a reply. +func (h *handler) handleImmediate(msg *jsonrpcMessage) bool { + start := time.Now() + switch { + case msg.isNotification(): + if strings.HasSuffix(msg.Method, notificationMethodSuffix) { + h.handleSubscriptionResult(msg) + return true + } + return false + case msg.isResponse(): + h.handleResponse(msg) + h.log.Trace("Handled RPC response", "reqid", idForLog{msg.ID}, "t", time.Since(start)) + return true + default: + return false + } +} + +// handleSubscriptionResult processes subscription notifications. +func (h *handler) handleSubscriptionResult(msg *jsonrpcMessage) { + var result subscriptionResult + if err := json.Unmarshal(msg.Params, &result); err != nil { + h.log.Debug("Dropping invalid subscription message") + return + } + if h.clientSubs[result.ID] != nil { + h.clientSubs[result.ID].deliver(result.Result) + } +} + +// handleResponse processes method call responses. +func (h *handler) handleResponse(msg *jsonrpcMessage) { + op := h.respWait[string(msg.ID)] + if op == nil { + h.log.Debug("Unsolicited RPC response", "reqid", idForLog{msg.ID}) + return + } + delete(h.respWait, string(msg.ID)) + // For normal responses, just forward the reply to Call/BatchCall. + if op.sub == nil { + op.resp <- msg + return + } + // For subscription responses, start the subscription if the server + // indicates success. EthSubscribe gets unblocked in either case through + // the op.resp channel. + defer close(op.resp) + if msg.Error != nil { + op.err = msg.Error + return + } + if op.err = json.Unmarshal(msg.Result, &op.sub.subid); op.err == nil { + go op.sub.start() + h.clientSubs[op.sub.subid] = op.sub + } +} + +// handleCallMsg executes a call message and returns the answer. +func (h *handler) handleCallMsg(ctx *callProc, msg *jsonrpcMessage) *jsonrpcMessage { + start := time.Now() + switch { + case msg.isNotification(): + h.handleCall(ctx, msg) + h.log.Debug("Served "+msg.Method, "t", time.Since(start)) + return nil + case msg.isCall(): + resp := h.handleCall(ctx, msg) + if resp.Error != nil { + h.log.Warn("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start), "err", resp.Error.Message) + } else { + h.log.Debug("Served "+msg.Method, "reqid", idForLog{msg.ID}, "t", time.Since(start)) + } + return resp + case msg.hasValidID(): + return msg.errorResponse(&invalidRequestError{"invalid request"}) + default: + return errorMessage(&invalidRequestError{"invalid request"}) + } +} + +// handleCall processes method calls. +func (h *handler) handleCall(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage { + if msg.isSubscribe() { + return h.handleSubscribe(cp, msg) + } + var callb *callback + if msg.isUnsubscribe() { + callb = h.unsubscribeCb + } else { + callb = h.reg.callback(msg.Method) + } + if callb == nil { + return msg.errorResponse(&methodNotFoundError{method: msg.Method}) + } + args, err := parsePositionalArguments(msg.Params, callb.argTypes) + if err != nil { + return msg.errorResponse(&invalidParamsError{err.Error()}) + } + + return h.runMethod(cp.ctx, msg, callb, args) +} + +// handleSubscribe processes *_subscribe method calls. +func (h *handler) handleSubscribe(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage { + if !h.allowSubscribe { + return msg.errorResponse(ErrNotificationsUnsupported) + } + + // Subscription method name is first argument. + name, err := parseSubscriptionName(msg.Params) + if err != nil { + return msg.errorResponse(&invalidParamsError{err.Error()}) + } + namespace := msg.namespace() + callb := h.reg.subscription(namespace, name) + if callb == nil { + return msg.errorResponse(&subscriptionNotFoundError{namespace, name}) + } + + // Parse subscription name arg too, but remove it before calling the callback. + argTypes := append([]reflect.Type{stringType}, callb.argTypes...) + args, err := parsePositionalArguments(msg.Params, argTypes) + if err != nil { + return msg.errorResponse(&invalidParamsError{err.Error()}) + } + args = args[1:] + + // Install notifier in context so the subscription handler can find it. + n := &Notifier{h: h, namespace: namespace} + cp.notifiers = append(cp.notifiers, n) + ctx := context.WithValue(cp.ctx, notifierKey{}, n) + + return h.runMethod(ctx, msg, callb, args) +} + +// runMethod runs the Go callback for an RPC method. +func (h *handler) runMethod(ctx context.Context, msg *jsonrpcMessage, callb *callback, args []reflect.Value) *jsonrpcMessage { + result, err := callb.call(ctx, msg.Method, args) + if err != nil { + return msg.errorResponse(err) + } + return msg.response(result) +} + +// unsubscribe is the callback function for all *_unsubscribe calls. +func (h *handler) unsubscribe(ctx context.Context, id ID) (bool, error) { + h.subLock.Lock() + defer h.subLock.Unlock() + + s := h.serverSubs[id] + if s == nil { + return false, ErrSubscriptionNotFound + } + close(s.err) + delete(h.serverSubs, id) + return true, nil +} + +type idForLog struct{ json.RawMessage } + +func (id idForLog) String() string { + if s, err := strconv.Unquote(string(id.RawMessage)); err == nil { + return s + } + return string(id.RawMessage) +} diff --git a/vendor/github.com/ethereum/go-ethereum/rpc/ipc_unix.go b/vendor/github.com/ethereum/go-ethereum/rpc/ipc_unix.go new file mode 100644 index 00000000..da6ce294 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/rpc/ipc_unix.go @@ -0,0 +1,54 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris + +package rpc + +import ( + "context" + "fmt" + "net" + "os" + "path/filepath" + + "github.com/ethereum/go-ethereum/log" +) + +// ipcListen will create a Unix socket on the given endpoint. +func ipcListen(endpoint string) (net.Listener, error) { + if len(endpoint) > int(max_path_size) { + log.Warn(fmt.Sprintf("The ipc endpoint is longer than %d characters. ", max_path_size), + "endpoint", endpoint) + } + + // Ensure the IPC path exists and remove any previous leftover + if err := os.MkdirAll(filepath.Dir(endpoint), 0751); err != nil { + return nil, err + } + os.Remove(endpoint) + l, err := net.Listen("unix", endpoint) + if err != nil { + return nil, err + } + os.Chmod(endpoint, 0600) + return l, nil +} + +// newIPCConnection will connect to a Unix socket on the given endpoint. +func newIPCConnection(ctx context.Context, endpoint string) (net.Conn, error) { + return dialContext(ctx, "unix", endpoint) +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/api.go b/vendor/github.com/ethereum/go-ethereum/signer/core/api.go new file mode 100644 index 00000000..251ee55d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/api.go @@ -0,0 +1,567 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package core + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "reflect" + "strings" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/scwallet" + "github.com/ethereum/go-ethereum/accounts/usbwallet" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/signer/storage" +) + +const ( + // numberOfAccountsToDerive For hardware wallets, the number of accounts to derive + numberOfAccountsToDerive = 10 + // ExternalAPIVersion -- see extapi_changelog.md + ExternalAPIVersion = "6.0.0" + // InternalAPIVersion -- see intapi_changelog.md + InternalAPIVersion = "6.0.0" +) + +// ExternalAPI defines the external API through which signing requests are made. +type ExternalAPI interface { + // List available accounts + List(ctx context.Context) ([]common.Address, error) + // New request to create a new account + New(ctx context.Context) (common.Address, error) + // SignTransaction request to sign the specified transaction + SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) + // SignData - request to sign the given data (plus prefix) + SignData(ctx context.Context, contentType string, addr common.MixedcaseAddress, data interface{}) (hexutil.Bytes, error) + // SignTypedData - request to sign the given structured data (plus prefix) + SignTypedData(ctx context.Context, addr common.MixedcaseAddress, data TypedData) (hexutil.Bytes, error) + // EcRecover - recover public key from given message and signature + EcRecover(ctx context.Context, data hexutil.Bytes, sig hexutil.Bytes) (common.Address, error) + // Version info about the APIs + Version(ctx context.Context) (string, error) +} + +// UIClientAPI specifies what method a UI needs to implement to be able to be used as a +// UI for the signer +type UIClientAPI interface { + // ApproveTx prompt the user for confirmation to request to sign Transaction + ApproveTx(request *SignTxRequest) (SignTxResponse, error) + // ApproveSignData prompt the user for confirmation to request to sign data + ApproveSignData(request *SignDataRequest) (SignDataResponse, error) + // ApproveListing prompt the user for confirmation to list accounts + // the list of accounts to list can be modified by the UI + ApproveListing(request *ListRequest) (ListResponse, error) + // ApproveNewAccount prompt the user for confirmation to create new Account, and reveal to caller + ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) + // ShowError displays error message to user + ShowError(message string) + // ShowInfo displays info message to user + ShowInfo(message string) + // OnApprovedTx notifies the UI about a transaction having been successfully signed. + // This method can be used by a UI to keep track of e.g. how much has been sent to a particular recipient. + OnApprovedTx(tx ethapi.SignTransactionResult) + // OnSignerStartup is invoked when the signer boots, and tells the UI info about external API location and version + // information + OnSignerStartup(info StartupInfo) + // OnInputRequired is invoked when clef requires user input, for example master password or + // pin-code for unlocking hardware wallets + OnInputRequired(info UserInputRequest) (UserInputResponse, error) + // RegisterUIServer tells the UI to use the given UIServerAPI for ui->clef communication + RegisterUIServer(api *UIServerAPI) +} + +// Validator defines the methods required to validate a transaction against some +// sanity defaults as well as any underlying 4byte method database. +// +// Use fourbyte.Database as an implementation. It is separated out of this package +// to allow pieces of the signer package to be used without having to load the +// 7MB embedded 4byte dump. +type Validator interface { + // ValidateTransaction does a number of checks on the supplied transaction, and + // returns either a list of warnings, or an error (indicating that the transaction + // should be immediately rejected). + ValidateTransaction(selector *string, tx *SendTxArgs) (*ValidationMessages, error) +} + +// SignerAPI defines the actual implementation of ExternalAPI +type SignerAPI struct { + chainID *big.Int + am *accounts.Manager + UI UIClientAPI + validator Validator + rejectMode bool + credentials storage.Storage +} + +// Metadata about a request +type Metadata struct { + Remote string `json:"remote"` + Local string `json:"local"` + Scheme string `json:"scheme"` + UserAgent string `json:"User-Agent"` + Origin string `json:"Origin"` +} + +func StartClefAccountManager(ksLocation string, nousb, lightKDF bool, scpath string) *accounts.Manager { + var ( + backends []accounts.Backend + n, p = keystore.StandardScryptN, keystore.StandardScryptP + ) + if lightKDF { + n, p = keystore.LightScryptN, keystore.LightScryptP + } + // support password based accounts + if len(ksLocation) > 0 { + backends = append(backends, keystore.NewKeyStore(ksLocation, n, p)) + } + if !nousb { + // Start a USB hub for Ledger hardware wallets + if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) + } else { + backends = append(backends, ledgerhub) + log.Debug("Ledger support enabled") + } + // Start a USB hub for Trezor hardware wallets (HID version) + if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { + log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + log.Debug("Trezor support enabled via HID") + } + // Start a USB hub for Trezor hardware wallets (WebUSB version) + if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { + log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + log.Debug("Trezor support enabled via WebUSB") + } + } + + // Start a smart card hub + if len(scpath) > 0 { + // Sanity check that the smartcard path is valid + fi, err := os.Stat(scpath) + if err != nil { + log.Info("Smartcard socket file missing, disabling", "err", err) + } else { + if fi.Mode()&os.ModeType != os.ModeSocket { + log.Error("Invalid smartcard socket file type", "path", scpath, "type", fi.Mode().String()) + } else { + if schub, err := scwallet.NewHub(scpath, scwallet.Scheme, ksLocation); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + backends = append(backends, schub) + } + } + } + } + + // Clef doesn't allow insecure http account unlock. + return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: false}, backends...) +} + +// MetadataFromContext extracts Metadata from a given context.Context +func MetadataFromContext(ctx context.Context) Metadata { + m := Metadata{"NA", "NA", "NA", "", ""} // batman + + if v := ctx.Value("remote"); v != nil { + m.Remote = v.(string) + } + if v := ctx.Value("scheme"); v != nil { + m.Scheme = v.(string) + } + if v := ctx.Value("local"); v != nil { + m.Local = v.(string) + } + if v := ctx.Value("Origin"); v != nil { + m.Origin = v.(string) + } + if v := ctx.Value("User-Agent"); v != nil { + m.UserAgent = v.(string) + } + return m +} + +// String implements Stringer interface +func (m Metadata) String() string { + s, err := json.Marshal(m) + if err == nil { + return string(s) + } + return err.Error() +} + +// types for the requests/response types between signer and UI +type ( + // SignTxRequest contains info about a Transaction to sign + SignTxRequest struct { + Transaction SendTxArgs `json:"transaction"` + Callinfo []ValidationInfo `json:"call_info"` + Meta Metadata `json:"meta"` + } + // SignTxResponse result from SignTxRequest + SignTxResponse struct { + //The UI may make changes to the TX + Transaction SendTxArgs `json:"transaction"` + Approved bool `json:"approved"` + } + SignDataRequest struct { + ContentType string `json:"content_type"` + Address common.MixedcaseAddress `json:"address"` + Rawdata []byte `json:"raw_data"` + Message []*NameValueType `json:"message"` + Hash hexutil.Bytes `json:"hash"` + Meta Metadata `json:"meta"` + } + SignDataResponse struct { + Approved bool `json:"approved"` + } + NewAccountRequest struct { + Meta Metadata `json:"meta"` + } + NewAccountResponse struct { + Approved bool `json:"approved"` + } + ListRequest struct { + Accounts []accounts.Account `json:"accounts"` + Meta Metadata `json:"meta"` + } + ListResponse struct { + Accounts []accounts.Account `json:"accounts"` + } + Message struct { + Text string `json:"text"` + } + StartupInfo struct { + Info map[string]interface{} `json:"info"` + } + UserInputRequest struct { + Title string `json:"title"` + Prompt string `json:"prompt"` + IsPassword bool `json:"isPassword"` + } + UserInputResponse struct { + Text string `json:"text"` + } +) + +var ErrRequestDenied = errors.New("Request denied") + +// NewSignerAPI creates a new API that can be used for Account management. +// ksLocation specifies the directory where to store the password protected private +// key that is generated when a new Account is created. +// noUSB disables USB support that is required to support hardware devices such as +// ledger and trezor. +func NewSignerAPI(am *accounts.Manager, chainID int64, noUSB bool, ui UIClientAPI, validator Validator, advancedMode bool, credentials storage.Storage) *SignerAPI { + if advancedMode { + log.Info("Clef is in advanced mode: will warn instead of reject") + } + signer := &SignerAPI{big.NewInt(chainID), am, ui, validator, !advancedMode, credentials} + if !noUSB { + signer.startUSBListener() + } + return signer +} +func (api *SignerAPI) openTrezor(url accounts.URL) { + resp, err := api.UI.OnInputRequired(UserInputRequest{ + Prompt: "Pin required to open Trezor wallet\n" + + "Look at the device for number positions\n\n" + + "7 | 8 | 9\n" + + "--+---+--\n" + + "4 | 5 | 6\n" + + "--+---+--\n" + + "1 | 2 | 3\n\n", + IsPassword: true, + Title: "Trezor unlock", + }) + if err != nil { + log.Warn("failed getting trezor pin", "err", err) + return + } + // We're using the URL instead of the pointer to the + // Wallet -- perhaps it is not actually present anymore + w, err := api.am.Wallet(url.String()) + if err != nil { + log.Warn("wallet unavailable", "url", url) + return + } + err = w.Open(resp.Text) + if err != nil { + log.Warn("failed to open wallet", "wallet", url, "err", err) + return + } + +} + +// startUSBListener starts a listener for USB events, for hardware wallet interaction +func (api *SignerAPI) startUSBListener() { + events := make(chan accounts.WalletEvent, 16) + am := api.am + am.Subscribe(events) + go func() { + + // Open any wallets already attached + for _, wallet := range am.Wallets() { + if err := wallet.Open(""); err != nil { + log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) + if err == usbwallet.ErrTrezorPINNeeded { + go api.openTrezor(wallet.URL()) + } + } + } + // Listen for wallet event till termination + for event := range events { + switch event.Kind { + case accounts.WalletArrived: + if err := event.Wallet.Open(""); err != nil { + log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) + if err == usbwallet.ErrTrezorPINNeeded { + go api.openTrezor(event.Wallet.URL()) + } + } + case accounts.WalletOpened: + status, _ := event.Wallet.Status() + log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) + + // Derive first N accounts, hardcoded for now + var nextPath = make(accounts.DerivationPath, len(accounts.DefaultBaseDerivationPath)) + copy(nextPath[:], accounts.DefaultBaseDerivationPath[:]) + + for i := 0; i < numberOfAccountsToDerive; i++ { + acc, err := event.Wallet.Derive(nextPath, true) + if err != nil { + log.Warn("account derivation failed", "error", err) + } else { + log.Info("derived account", "address", acc.Address) + } + nextPath[len(nextPath)-1]++ + } + case accounts.WalletDropped: + log.Info("Old wallet dropped", "url", event.Wallet.URL()) + event.Wallet.Close() + } + } + }() +} + +// List returns the set of wallet this signer manages. Each wallet can contain +// multiple accounts. +func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) { + var accs []accounts.Account + for _, wallet := range api.am.Wallets() { + accs = append(accs, wallet.Accounts()...) + } + result, err := api.UI.ApproveListing(&ListRequest{Accounts: accs, Meta: MetadataFromContext(ctx)}) + if err != nil { + return nil, err + } + if result.Accounts == nil { + return nil, ErrRequestDenied + + } + addresses := make([]common.Address, 0) + for _, acc := range result.Accounts { + addresses = append(addresses, acc.Address) + } + + return addresses, nil +} + +// New creates a new password protected Account. The private key is protected with +// the given password. Users are responsible to backup the private key that is stored +// in the keystore location thas was specified when this API was created. +func (api *SignerAPI) New(ctx context.Context) (common.Address, error) { + be := api.am.Backends(keystore.KeyStoreType) + if len(be) == 0 { + return common.Address{}, errors.New("password based accounts not supported") + } + if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil { + return common.Address{}, err + } else if !resp.Approved { + return common.Address{}, ErrRequestDenied + } + + // Three retries to get a valid password + for i := 0; i < 3; i++ { + resp, err := api.UI.OnInputRequired(UserInputRequest{ + "New account password", + fmt.Sprintf("Please enter a password for the new account to be created (attempt %d of 3)", i), + true}) + if err != nil { + log.Warn("error obtaining password", "attempt", i, "error", err) + continue + } + if pwErr := ValidatePasswordFormat(resp.Text); pwErr != nil { + api.UI.ShowError(fmt.Sprintf("Account creation attempt #%d failed due to password requirements: %v", (i + 1), pwErr)) + } else { + // No error + acc, err := be[0].(*keystore.KeyStore).NewAccount(resp.Text) + log.Info("Your new key was generated", "address", acc.Address) + log.Warn("Please backup your key file!", "path", acc.URL.Path) + log.Warn("Please remember your password!") + return acc.Address, err + } + } + // Otherwise fail, with generic error message + return common.Address{}, errors.New("account creation failed") +} + +// logDiff logs the difference between the incoming (original) transaction and the one returned from the signer. +// it also returns 'true' if the transaction was modified, to make it possible to configure the signer not to allow +// UI-modifications to requests +func logDiff(original *SignTxRequest, new *SignTxResponse) bool { + modified := false + if f0, f1 := original.Transaction.From, new.Transaction.From; !reflect.DeepEqual(f0, f1) { + log.Info("Sender-account changed by UI", "was", f0, "is", f1) + modified = true + } + if t0, t1 := original.Transaction.To, new.Transaction.To; !reflect.DeepEqual(t0, t1) { + log.Info("Recipient-account changed by UI", "was", t0, "is", t1) + modified = true + } + if g0, g1 := original.Transaction.Gas, new.Transaction.Gas; g0 != g1 { + modified = true + log.Info("Gas changed by UI", "was", g0, "is", g1) + } + if g0, g1 := big.Int(original.Transaction.GasPrice), big.Int(new.Transaction.GasPrice); g0.Cmp(&g1) != 0 { + modified = true + log.Info("GasPrice changed by UI", "was", g0, "is", g1) + } + if v0, v1 := big.Int(original.Transaction.Value), big.Int(new.Transaction.Value); v0.Cmp(&v1) != 0 { + modified = true + log.Info("Value changed by UI", "was", v0, "is", v1) + } + if d0, d1 := original.Transaction.Data, new.Transaction.Data; d0 != d1 { + d0s := "" + d1s := "" + if d0 != nil { + d0s = hexutil.Encode(*d0) + } + if d1 != nil { + d1s = hexutil.Encode(*d1) + } + if d1s != d0s { + modified = true + log.Info("Data changed by UI", "was", d0s, "is", d1s) + } + } + if n0, n1 := original.Transaction.Nonce, new.Transaction.Nonce; n0 != n1 { + modified = true + log.Info("Nonce changed by UI", "was", n0, "is", n1) + } + return modified +} + +func (api *SignerAPI) lookupPassword(address common.Address) string { + return api.credentials.Get(strings.ToLower(address.String())) +} +func (api *SignerAPI) lookupOrQueryPassword(address common.Address, title, prompt string) (string, error) { + if pw := api.lookupPassword(address); pw != "" { + return pw, nil + } else { + pwResp, err := api.UI.OnInputRequired(UserInputRequest{title, prompt, true}) + if err != nil { + log.Warn("error obtaining password", "error", err) + // We'll not forward the error here, in case the error contains info about the response from the UI, + // which could leak the password if it was malformed json or something + return "", errors.New("internal error") + } + return pwResp.Text, nil + } +} + +// SignTransaction signs the given Transaction and returns it both as json and rlp-encoded form +func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, methodSelector *string) (*ethapi.SignTransactionResult, error) { + var ( + err error + result SignTxResponse + ) + msgs, err := api.validator.ValidateTransaction(methodSelector, &args) + if err != nil { + return nil, err + } + // If we are in 'rejectMode', then reject rather than show the user warnings + if api.rejectMode { + if err := msgs.getWarnings(); err != nil { + return nil, err + } + } + req := SignTxRequest{ + Transaction: args, + Meta: MetadataFromContext(ctx), + Callinfo: msgs.Messages, + } + // Process approval + result, err = api.UI.ApproveTx(&req) + if err != nil { + return nil, err + } + if !result.Approved { + return nil, ErrRequestDenied + } + // Log changes made by the UI to the signing-request + logDiff(&req, &result) + var ( + acc accounts.Account + wallet accounts.Wallet + ) + acc = accounts.Account{Address: result.Transaction.From.Address()} + wallet, err = api.am.Find(acc) + if err != nil { + return nil, err + } + // Convert fields into a real transaction + var unsignedTx = result.Transaction.toTransaction() + // Get the password for the transaction + pw, err := api.lookupOrQueryPassword(acc.Address, "Account password", + fmt.Sprintf("Please enter the password for account %s", acc.Address.String())) + if err != nil { + return nil, err + } + // The one to sign is the one that was returned from the UI + signedTx, err := wallet.SignTxWithPassphrase(acc, pw, unsignedTx, api.chainID) + if err != nil { + api.UI.ShowError(err.Error()) + return nil, err + } + + rlpdata, err := rlp.EncodeToBytes(signedTx) + response := ethapi.SignTransactionResult{Raw: rlpdata, Tx: signedTx} + + // Finally, send the signed tx to the UI + api.UI.OnApprovedTx(response) + // ...and to the external caller + return &response, nil + +} + +// Returns the external api version. This method does not require user acceptance. Available methods are +// available via enumeration anyway, and this info does not contain user-specific data +func (api *SignerAPI) Version(ctx context.Context) (string, error) { + return ExternalAPIVersion, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/signed_data.go b/vendor/github.com/ethereum/go-ethereum/signer/core/signed_data.go new file mode 100644 index 00000000..27eca918 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/signed_data.go @@ -0,0 +1,1005 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . +// +package core + +import ( + "bytes" + "context" + "errors" + "fmt" + "math/big" + "mime" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "unicode" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" +) + +type SigFormat struct { + Mime string + ByteVersion byte +} + +var ( + IntendedValidator = SigFormat{ + accounts.MimetypeDataWithValidator, + 0x00, + } + DataTyped = SigFormat{ + accounts.MimetypeTypedData, + 0x01, + } + ApplicationClique = SigFormat{ + accounts.MimetypeClique, + 0x02, + } + TextPlain = SigFormat{ + accounts.MimetypeTextPlain, + 0x45, + } +) + +type ValidatorData struct { + Address common.Address + Message hexutil.Bytes +} + +type TypedData struct { + Types Types `json:"types"` + PrimaryType string `json:"primaryType"` + Domain TypedDataDomain `json:"domain"` + Message TypedDataMessage `json:"message"` +} + +type Type struct { + Name string `json:"name"` + Type string `json:"type"` +} + +func (t *Type) isArray() bool { + return strings.HasSuffix(t.Type, "[]") +} + +// typeName returns the canonical name of the type. If the type is 'Person[]', then +// this method returns 'Person' +func (t *Type) typeName() string { + if strings.HasSuffix(t.Type, "[]") { + return strings.TrimSuffix(t.Type, "[]") + } + return t.Type +} + +func (t *Type) isReferenceType() bool { + if len(t.Type) == 0 { + return false + } + // Reference types must have a leading uppercase characer + return unicode.IsUpper([]rune(t.Type)[0]) +} + +type Types map[string][]Type + +type TypePriority struct { + Type string + Value uint +} + +type TypedDataMessage = map[string]interface{} + +type TypedDataDomain struct { + Name string `json:"name"` + Version string `json:"version"` + ChainId *math.HexOrDecimal256 `json:"chainId"` + VerifyingContract string `json:"verifyingContract"` + Salt string `json:"salt"` +} + +var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`) + +// sign receives a request and produces a signature + +// Note, the produced signature conforms to the secp256k1 curve R, S and V values, +// where the V value will be 27 or 28 for legacy reasons, if legacyV==true. +func (api *SignerAPI) sign(addr common.MixedcaseAddress, req *SignDataRequest, legacyV bool) (hexutil.Bytes, error) { + + // We make the request prior to looking up if we actually have the account, to prevent + // account-enumeration via the API + res, err := api.UI.ApproveSignData(req) + if err != nil { + return nil, err + } + if !res.Approved { + return nil, ErrRequestDenied + } + // Look up the wallet containing the requested signer + account := accounts.Account{Address: addr.Address()} + wallet, err := api.am.Find(account) + if err != nil { + return nil, err + } + pw, err := api.lookupOrQueryPassword(account.Address, + "Password for signing", + fmt.Sprintf("Please enter password for signing data with account %s", account.Address.Hex())) + if err != nil { + return nil, err + } + // Sign the data with the wallet + signature, err := wallet.SignDataWithPassphrase(account, pw, req.ContentType, req.Rawdata) + if err != nil { + return nil, err + } + if legacyV { + signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper + } + return signature, nil +} + +// SignData signs the hash of the provided data, but does so differently +// depending on the content-type specified. +// +// Different types of validation occur. +func (api *SignerAPI) SignData(ctx context.Context, contentType string, addr common.MixedcaseAddress, data interface{}) (hexutil.Bytes, error) { + var req, transformV, err = api.determineSignatureFormat(ctx, contentType, addr, data) + if err != nil { + return nil, err + } + + signature, err := api.sign(addr, req, transformV) + if err != nil { + api.UI.ShowError(err.Error()) + return nil, err + } + return signature, nil +} + +// determineSignatureFormat determines which signature method should be used based upon the mime type +// In the cases where it matters ensure that the charset is handled. The charset +// resides in the 'params' returned as the second returnvalue from mime.ParseMediaType +// charset, ok := params["charset"] +// As it is now, we accept any charset and just treat it as 'raw'. +// This method returns the mimetype for signing along with the request +func (api *SignerAPI) determineSignatureFormat(ctx context.Context, contentType string, addr common.MixedcaseAddress, data interface{}) (*SignDataRequest, bool, error) { + var ( + req *SignDataRequest + useEthereumV = true // Default to use V = 27 or 28, the legacy Ethereum format + ) + mediaType, _, err := mime.ParseMediaType(contentType) + if err != nil { + return nil, useEthereumV, err + } + + switch mediaType { + case IntendedValidator.Mime: + // Data with an intended validator + validatorData, err := UnmarshalValidatorData(data) + if err != nil { + return nil, useEthereumV, err + } + sighash, msg := SignTextValidator(validatorData) + message := []*NameValueType{ + { + Name: "This is a request to sign data intended for a particular validator (see EIP 191 version 0)", + Typ: "description", + Value: "", + }, + { + Name: "Intended validator address", + Typ: "address", + Value: validatorData.Address.String(), + }, + { + Name: "Application-specific data", + Typ: "hexdata", + Value: validatorData.Message, + }, + { + Name: "Full message for signing", + Typ: "hexdata", + Value: fmt.Sprintf("0x%x", msg), + }, + } + req = &SignDataRequest{ContentType: mediaType, Rawdata: []byte(msg), Message: message, Hash: sighash} + case ApplicationClique.Mime: + // Clique is the Ethereum PoA standard + stringData, ok := data.(string) + if !ok { + return nil, useEthereumV, fmt.Errorf("input for %v must be an hex-encoded string", ApplicationClique.Mime) + } + cliqueData, err := hexutil.Decode(stringData) + if err != nil { + return nil, useEthereumV, err + } + header := &types.Header{} + if err := rlp.DecodeBytes(cliqueData, header); err != nil { + return nil, useEthereumV, err + } + // The incoming clique header is already truncated, sent to us with a extradata already shortened + if len(header.Extra) < 65 { + // Need to add it back, to get a suitable length for hashing + newExtra := make([]byte, len(header.Extra)+65) + copy(newExtra, header.Extra) + header.Extra = newExtra + } + // Get back the rlp data, encoded by us + sighash, cliqueRlp, err := cliqueHeaderHashAndRlp(header) + if err != nil { + return nil, useEthereumV, err + } + message := []*NameValueType{ + { + Name: "Clique header", + Typ: "clique", + Value: fmt.Sprintf("clique header %d [0x%x]", header.Number, header.Hash()), + }, + } + // Clique uses V on the form 0 or 1 + useEthereumV = false + req = &SignDataRequest{ContentType: mediaType, Rawdata: cliqueRlp, Message: message, Hash: sighash} + default: // also case TextPlain.Mime: + // Calculates an Ethereum ECDSA signature for: + // hash = keccak256("\x19${byteVersion}Ethereum Signed Message:\n${message length}${message}") + // We expect it to be a string + if stringData, ok := data.(string); !ok { + return nil, useEthereumV, fmt.Errorf("input for text/plain must be an hex-encoded string") + } else { + if textData, err := hexutil.Decode(stringData); err != nil { + return nil, useEthereumV, err + } else { + sighash, msg := accounts.TextAndHash(textData) + message := []*NameValueType{ + { + Name: "message", + Typ: accounts.MimetypeTextPlain, + Value: msg, + }, + } + req = &SignDataRequest{ContentType: mediaType, Rawdata: []byte(msg), Message: message, Hash: sighash} + } + } + } + req.Address = addr + req.Meta = MetadataFromContext(ctx) + return req, useEthereumV, nil + +} + +// SignTextWithValidator signs the given message which can be further recovered +// with the given validator. +// hash = keccak256("\x19\x00"${address}${data}). +func SignTextValidator(validatorData ValidatorData) (hexutil.Bytes, string) { + msg := fmt.Sprintf("\x19\x00%s%s", string(validatorData.Address.Bytes()), string(validatorData.Message)) + return crypto.Keccak256([]byte(msg)), msg +} + +// cliqueHeaderHashAndRlp returns the hash which is used as input for the proof-of-authority +// signing. It is the hash of the entire header apart from the 65 byte signature +// contained at the end of the extra data. +// +// The method requires the extra data to be at least 65 bytes -- the original implementation +// in clique.go panics if this is the case, thus it's been reimplemented here to avoid the panic +// and simply return an error instead +func cliqueHeaderHashAndRlp(header *types.Header) (hash, rlp []byte, err error) { + if len(header.Extra) < 65 { + err = fmt.Errorf("clique header extradata too short, %d < 65", len(header.Extra)) + return + } + rlp = clique.CliqueRLP(header) + hash = clique.SealHash(header).Bytes() + return hash, rlp, err +} + +// SignTypedData signs EIP-712 conformant typed data +// hash = keccak256("\x19${byteVersion}${domainSeparator}${hashStruct(message)}") +func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAddress, typedData TypedData) (hexutil.Bytes, error) { + domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) + if err != nil { + return nil, err + } + typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) + if err != nil { + return nil, err + } + rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) + sighash := crypto.Keccak256(rawData) + message, err := typedData.Format() + if err != nil { + return nil, err + } + req := &SignDataRequest{ContentType: DataTyped.Mime, Rawdata: rawData, Message: message, Hash: sighash} + signature, err := api.sign(addr, req, true) + if err != nil { + api.UI.ShowError(err.Error()) + return nil, err + } + return signature, nil +} + +// HashStruct generates a keccak256 hash of the encoding of the provided data +func (typedData *TypedData) HashStruct(primaryType string, data TypedDataMessage) (hexutil.Bytes, error) { + encodedData, err := typedData.EncodeData(primaryType, data, 1) + if err != nil { + return nil, err + } + return crypto.Keccak256(encodedData), nil +} + +// Dependencies returns an array of custom types ordered by their hierarchical reference tree +func (typedData *TypedData) Dependencies(primaryType string, found []string) []string { + includes := func(arr []string, str string) bool { + for _, obj := range arr { + if obj == str { + return true + } + } + return false + } + + if includes(found, primaryType) { + return found + } + if typedData.Types[primaryType] == nil { + return found + } + found = append(found, primaryType) + for _, field := range typedData.Types[primaryType] { + for _, dep := range typedData.Dependencies(field.Type, found) { + if !includes(found, dep) { + found = append(found, dep) + } + } + } + return found +} + +// EncodeType generates the following encoding: +// `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"` +// +// each member is written as `type ‖ " " ‖ name` encodings cascade down and are sorted by name +func (typedData *TypedData) EncodeType(primaryType string) hexutil.Bytes { + // Get dependencies primary first, then alphabetical + deps := typedData.Dependencies(primaryType, []string{}) + if len(deps) > 0 { + slicedDeps := deps[1:] + sort.Strings(slicedDeps) + deps = append([]string{primaryType}, slicedDeps...) + } + + // Format as a string with fields + var buffer bytes.Buffer + for _, dep := range deps { + buffer.WriteString(dep) + buffer.WriteString("(") + for _, obj := range typedData.Types[dep] { + buffer.WriteString(obj.Type) + buffer.WriteString(" ") + buffer.WriteString(obj.Name) + buffer.WriteString(",") + } + buffer.Truncate(buffer.Len() - 1) + buffer.WriteString(")") + } + return buffer.Bytes() +} + +// TypeHash creates the keccak256 hash of the data +func (typedData *TypedData) TypeHash(primaryType string) hexutil.Bytes { + return crypto.Keccak256(typedData.EncodeType(primaryType)) +} + +// EncodeData generates the following encoding: +// `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)` +// +// each encoded member is 32-byte long +func (typedData *TypedData) EncodeData(primaryType string, data map[string]interface{}, depth int) (hexutil.Bytes, error) { + if err := typedData.validate(); err != nil { + return nil, err + } + + buffer := bytes.Buffer{} + + // Verify extra data + if len(typedData.Types[primaryType]) < len(data) { + return nil, errors.New("there is extra data provided in the message") + } + + // Add typehash + buffer.Write(typedData.TypeHash(primaryType)) + + // Add field contents. Structs and arrays have special handlers. + for _, field := range typedData.Types[primaryType] { + encType := field.Type + encValue := data[field.Name] + if encType[len(encType)-1:] == "]" { + arrayValue, ok := encValue.([]interface{}) + if !ok { + return nil, dataMismatchError(encType, encValue) + } + + arrayBuffer := bytes.Buffer{} + parsedType := strings.Split(encType, "[")[0] + for _, item := range arrayValue { + if typedData.Types[parsedType] != nil { + mapValue, ok := item.(map[string]interface{}) + if !ok { + return nil, dataMismatchError(parsedType, item) + } + encodedData, err := typedData.EncodeData(parsedType, mapValue, depth+1) + if err != nil { + return nil, err + } + arrayBuffer.Write(encodedData) + } else { + bytesValue, err := typedData.EncodePrimitiveValue(parsedType, item, depth) + if err != nil { + return nil, err + } + arrayBuffer.Write(bytesValue) + } + } + + buffer.Write(crypto.Keccak256(arrayBuffer.Bytes())) + } else if typedData.Types[field.Type] != nil { + mapValue, ok := encValue.(map[string]interface{}) + if !ok { + return nil, dataMismatchError(encType, encValue) + } + encodedData, err := typedData.EncodeData(field.Type, mapValue, depth+1) + if err != nil { + return nil, err + } + buffer.Write(crypto.Keccak256(encodedData)) + } else { + byteValue, err := typedData.EncodePrimitiveValue(encType, encValue, depth) + if err != nil { + return nil, err + } + buffer.Write(byteValue) + } + } + return buffer.Bytes(), nil +} + +func parseInteger(encType string, encValue interface{}) (*big.Int, error) { + var ( + length = 0 + signed = strings.HasPrefix(encType, "int") + b *big.Int + ) + if encType == "int" || encType == "uint" { + length = 256 + } else { + lengthStr := "" + if strings.HasPrefix(encType, "uint") { + lengthStr = strings.TrimPrefix(encType, "uint") + } else { + lengthStr = strings.TrimPrefix(encType, "int") + } + atoiSize, err := strconv.Atoi(lengthStr) + if err != nil { + return nil, fmt.Errorf("invalid size on integer: %v", lengthStr) + } + length = atoiSize + } + switch v := encValue.(type) { + case *math.HexOrDecimal256: + b = (*big.Int)(v) + case string: + var hexIntValue math.HexOrDecimal256 + if err := hexIntValue.UnmarshalText([]byte(v)); err != nil { + return nil, err + } + b = (*big.Int)(&hexIntValue) + case float64: + // JSON parses non-strings as float64. Fail if we cannot + // convert it losslessly + if float64(int64(v)) == v { + b = big.NewInt(int64(v)) + } else { + return nil, fmt.Errorf("invalid float value %v for type %v", v, encType) + } + } + if b == nil { + return nil, fmt.Errorf("invalid integer value %v/%v for type %v", encValue, reflect.TypeOf(encValue), encType) + } + if b.BitLen() > length { + return nil, fmt.Errorf("integer larger than '%v'", encType) + } + if !signed && b.Sign() == -1 { + return nil, fmt.Errorf("invalid negative value for unsigned type %v", encType) + } + return b, nil +} + +// EncodePrimitiveValue deals with the primitive values found +// while searching through the typed data +func (typedData *TypedData) EncodePrimitiveValue(encType string, encValue interface{}, depth int) ([]byte, error) { + switch encType { + case "address": + stringValue, ok := encValue.(string) + if !ok || !common.IsHexAddress(stringValue) { + return nil, dataMismatchError(encType, encValue) + } + retval := make([]byte, 32) + copy(retval[12:], common.HexToAddress(stringValue).Bytes()) + return retval, nil + case "bool": + boolValue, ok := encValue.(bool) + if !ok { + return nil, dataMismatchError(encType, encValue) + } + if boolValue { + return math.PaddedBigBytes(common.Big1, 32), nil + } + return math.PaddedBigBytes(common.Big0, 32), nil + case "string": + strVal, ok := encValue.(string) + if !ok { + return nil, dataMismatchError(encType, encValue) + } + return crypto.Keccak256([]byte(strVal)), nil + case "bytes": + bytesValue, ok := encValue.([]byte) + if !ok { + return nil, dataMismatchError(encType, encValue) + } + return crypto.Keccak256(bytesValue), nil + } + if strings.HasPrefix(encType, "bytes") { + lengthStr := strings.TrimPrefix(encType, "bytes") + length, err := strconv.Atoi(lengthStr) + if err != nil { + return nil, fmt.Errorf("invalid size on bytes: %v", lengthStr) + } + if length < 0 || length > 32 { + return nil, fmt.Errorf("invalid size on bytes: %d", length) + } + if byteValue, ok := encValue.(hexutil.Bytes); !ok { + return nil, dataMismatchError(encType, encValue) + } else { + return math.PaddedBigBytes(new(big.Int).SetBytes(byteValue), 32), nil + } + } + if strings.HasPrefix(encType, "int") || strings.HasPrefix(encType, "uint") { + b, err := parseInteger(encType, encValue) + if err != nil { + return nil, err + } + return abi.U256(b), nil + } + return nil, fmt.Errorf("unrecognized type '%s'", encType) + +} + +// dataMismatchError generates an error for a mismatch between +// the provided type and data +func dataMismatchError(encType string, encValue interface{}) error { + return fmt.Errorf("provided data '%v' doesn't match type '%s'", encValue, encType) +} + +// EcRecover recovers the address associated with the given sig. +// Only compatible with `text/plain` +func (api *SignerAPI) EcRecover(ctx context.Context, data hexutil.Bytes, sig hexutil.Bytes) (common.Address, error) { + // Returns the address for the Account that was used to create the signature. + // + // Note, this function is compatible with eth_sign and personal_sign. As such it recovers + // the address of: + // hash = keccak256("\x19${byteVersion}Ethereum Signed Message:\n${message length}${message}") + // addr = ecrecover(hash, signature) + // + // Note, the signature must conform to the secp256k1 curve R, S and V values, where + // the V value must be be 27 or 28 for legacy reasons. + // + // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover + if len(sig) != 65 { + return common.Address{}, fmt.Errorf("signature must be 65 bytes long") + } + if sig[64] != 27 && sig[64] != 28 { + return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") + } + sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1 + hash := accounts.TextHash(data) + rpk, err := crypto.SigToPub(hash, sig) + if err != nil { + return common.Address{}, err + } + return crypto.PubkeyToAddress(*rpk), nil +} + +// UnmarshalValidatorData converts the bytes input to typed data +func UnmarshalValidatorData(data interface{}) (ValidatorData, error) { + raw, ok := data.(map[string]interface{}) + if !ok { + return ValidatorData{}, errors.New("validator input is not a map[string]interface{}") + } + addr, ok := raw["address"].(string) + if !ok { + return ValidatorData{}, errors.New("validator address is not sent as a string") + } + addrBytes, err := hexutil.Decode(addr) + if err != nil { + return ValidatorData{}, err + } + if !ok || len(addrBytes) == 0 { + return ValidatorData{}, errors.New("validator address is undefined") + } + + message, ok := raw["message"].(string) + if !ok { + return ValidatorData{}, errors.New("message is not sent as a string") + } + messageBytes, err := hexutil.Decode(message) + if err != nil { + return ValidatorData{}, err + } + if !ok || len(messageBytes) == 0 { + return ValidatorData{}, errors.New("message is undefined") + } + + return ValidatorData{ + Address: common.BytesToAddress(addrBytes), + Message: messageBytes, + }, nil +} + +// validate makes sure the types are sound +func (typedData *TypedData) validate() error { + if err := typedData.Types.validate(); err != nil { + return err + } + if err := typedData.Domain.validate(); err != nil { + return err + } + return nil +} + +// Map generates a map version of the typed data +func (typedData *TypedData) Map() map[string]interface{} { + dataMap := map[string]interface{}{ + "types": typedData.Types, + "domain": typedData.Domain.Map(), + "primaryType": typedData.PrimaryType, + "message": typedData.Message, + } + return dataMap +} + +// Format returns a representation of typedData, which can be easily displayed by a user-interface +// without in-depth knowledge about 712 rules +func (typedData *TypedData) Format() ([]*NameValueType, error) { + domain, err := typedData.formatData("EIP712Domain", typedData.Domain.Map()) + if err != nil { + return nil, err + } + ptype, err := typedData.formatData(typedData.PrimaryType, typedData.Message) + if err != nil { + return nil, err + } + var nvts []*NameValueType + nvts = append(nvts, &NameValueType{ + Name: "EIP712Domain", + Value: domain, + Typ: "domain", + }) + nvts = append(nvts, &NameValueType{ + Name: typedData.PrimaryType, + Value: ptype, + Typ: "primary type", + }) + return nvts, nil +} + +func (typedData *TypedData) formatData(primaryType string, data map[string]interface{}) ([]*NameValueType, error) { + var output []*NameValueType + + // Add field contents. Structs and arrays have special handlers. + for _, field := range typedData.Types[primaryType] { + encName := field.Name + encValue := data[encName] + item := &NameValueType{ + Name: encName, + Typ: field.Type, + } + if field.isArray() { + arrayValue, _ := encValue.([]interface{}) + parsedType := field.typeName() + for _, v := range arrayValue { + if typedData.Types[parsedType] != nil { + mapValue, _ := v.(map[string]interface{}) + mapOutput, err := typedData.formatData(parsedType, mapValue) + if err != nil { + return nil, err + } + item.Value = mapOutput + } else { + primitiveOutput, err := formatPrimitiveValue(field.Type, encValue) + if err != nil { + return nil, err + } + item.Value = primitiveOutput + } + } + } else if typedData.Types[field.Type] != nil { + if mapValue, ok := encValue.(map[string]interface{}); ok { + mapOutput, err := typedData.formatData(field.Type, mapValue) + if err != nil { + return nil, err + } + item.Value = mapOutput + } else { + item.Value = "" + } + } else { + primitiveOutput, err := formatPrimitiveValue(field.Type, encValue) + if err != nil { + return nil, err + } + item.Value = primitiveOutput + } + output = append(output, item) + } + return output, nil +} + +func formatPrimitiveValue(encType string, encValue interface{}) (string, error) { + switch encType { + case "address": + if stringValue, ok := encValue.(string); !ok { + return "", fmt.Errorf("could not format value %v as address", encValue) + } else { + return common.HexToAddress(stringValue).String(), nil + } + case "bool": + if boolValue, ok := encValue.(bool); !ok { + return "", fmt.Errorf("could not format value %v as bool", encValue) + } else { + return fmt.Sprintf("%t", boolValue), nil + } + case "bytes", "string": + return fmt.Sprintf("%s", encValue), nil + } + if strings.HasPrefix(encType, "bytes") { + return fmt.Sprintf("%s", encValue), nil + + } + if strings.HasPrefix(encType, "uint") || strings.HasPrefix(encType, "int") { + if b, err := parseInteger(encType, encValue); err != nil { + return "", err + } else { + return fmt.Sprintf("%d (0x%x)", b, b), nil + } + } + return "", fmt.Errorf("unhandled type %v", encType) +} + +// NameValueType is a very simple struct with Name, Value and Type. It's meant for simple +// json structures used to communicate signing-info about typed data with the UI +type NameValueType struct { + Name string `json:"name"` + Value interface{} `json:"value"` + Typ string `json:"type"` +} + +// Pprint returns a pretty-printed version of nvt +func (nvt *NameValueType) Pprint(depth int) string { + output := bytes.Buffer{} + output.WriteString(strings.Repeat("\u00a0", depth*2)) + output.WriteString(fmt.Sprintf("%s [%s]: ", nvt.Name, nvt.Typ)) + if nvts, ok := nvt.Value.([]*NameValueType); ok { + output.WriteString("\n") + for _, next := range nvts { + sublevel := next.Pprint(depth + 1) + output.WriteString(sublevel) + } + } else { + output.WriteString(fmt.Sprintf("%q\n", nvt.Value)) + } + return output.String() +} + +// Validate checks if the types object is conformant to the specs +func (t Types) validate() error { + for typeKey, typeArr := range t { + if len(typeKey) == 0 { + return fmt.Errorf("empty type key") + } + for i, typeObj := range typeArr { + if len(typeObj.Type) == 0 { + return fmt.Errorf("type %v:%d: empty Type", typeKey, i) + } + if len(typeObj.Name) == 0 { + return fmt.Errorf("type %v:%d: empty Name", typeKey, i) + } + if typeKey == typeObj.Type { + return fmt.Errorf("type '%s' cannot reference itself", typeObj.Type) + } + if typeObj.isReferenceType() { + if _, exist := t[typeObj.typeName()]; !exist { + return fmt.Errorf("reference type '%s' is undefined", typeObj.Type) + } + if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) { + return fmt.Errorf("unknown reference type '%s", typeObj.Type) + } + } else if !isPrimitiveTypeValid(typeObj.Type) { + return fmt.Errorf("unknown type '%s'", typeObj.Type) + } + } + } + return nil +} + +// Checks if the primitive value is valid +func isPrimitiveTypeValid(primitiveType string) bool { + if primitiveType == "address" || + primitiveType == "address[]" || + primitiveType == "bool" || + primitiveType == "bool[]" || + primitiveType == "string" || + primitiveType == "string[]" { + return true + } + if primitiveType == "bytes" || + primitiveType == "bytes[]" || + primitiveType == "bytes1" || + primitiveType == "bytes1[]" || + primitiveType == "bytes2" || + primitiveType == "bytes2[]" || + primitiveType == "bytes3" || + primitiveType == "bytes3[]" || + primitiveType == "bytes4" || + primitiveType == "bytes4[]" || + primitiveType == "bytes5" || + primitiveType == "bytes5[]" || + primitiveType == "bytes6" || + primitiveType == "bytes6[]" || + primitiveType == "bytes7" || + primitiveType == "bytes7[]" || + primitiveType == "bytes8" || + primitiveType == "bytes8[]" || + primitiveType == "bytes9" || + primitiveType == "bytes9[]" || + primitiveType == "bytes10" || + primitiveType == "bytes10[]" || + primitiveType == "bytes11" || + primitiveType == "bytes11[]" || + primitiveType == "bytes12" || + primitiveType == "bytes12[]" || + primitiveType == "bytes13" || + primitiveType == "bytes13[]" || + primitiveType == "bytes14" || + primitiveType == "bytes14[]" || + primitiveType == "bytes15" || + primitiveType == "bytes15[]" || + primitiveType == "bytes16" || + primitiveType == "bytes16[]" || + primitiveType == "bytes17" || + primitiveType == "bytes17[]" || + primitiveType == "bytes18" || + primitiveType == "bytes18[]" || + primitiveType == "bytes19" || + primitiveType == "bytes19[]" || + primitiveType == "bytes20" || + primitiveType == "bytes20[]" || + primitiveType == "bytes21" || + primitiveType == "bytes21[]" || + primitiveType == "bytes22" || + primitiveType == "bytes22[]" || + primitiveType == "bytes23" || + primitiveType == "bytes23[]" || + primitiveType == "bytes24" || + primitiveType == "bytes24[]" || + primitiveType == "bytes25" || + primitiveType == "bytes25[]" || + primitiveType == "bytes26" || + primitiveType == "bytes26[]" || + primitiveType == "bytes27" || + primitiveType == "bytes27[]" || + primitiveType == "bytes28" || + primitiveType == "bytes28[]" || + primitiveType == "bytes29" || + primitiveType == "bytes29[]" || + primitiveType == "bytes30" || + primitiveType == "bytes30[]" || + primitiveType == "bytes31" || + primitiveType == "bytes31[]" { + return true + } + if primitiveType == "int" || + primitiveType == "int[]" || + primitiveType == "int8" || + primitiveType == "int8[]" || + primitiveType == "int16" || + primitiveType == "int16[]" || + primitiveType == "int32" || + primitiveType == "int32[]" || + primitiveType == "int64" || + primitiveType == "int64[]" || + primitiveType == "int128" || + primitiveType == "int128[]" || + primitiveType == "int256" || + primitiveType == "int256[]" { + return true + } + if primitiveType == "uint" || + primitiveType == "uint[]" || + primitiveType == "uint8" || + primitiveType == "uint8[]" || + primitiveType == "uint16" || + primitiveType == "uint16[]" || + primitiveType == "uint32" || + primitiveType == "uint32[]" || + primitiveType == "uint64" || + primitiveType == "uint64[]" || + primitiveType == "uint128" || + primitiveType == "uint128[]" || + primitiveType == "uint256" || + primitiveType == "uint256[]" { + return true + } + return false +} + +// validate checks if the given domain is valid, i.e. contains at least +// the minimum viable keys and values +func (domain *TypedDataDomain) validate() error { + if domain.ChainId == nil { + return errors.New("chainId must be specified according to EIP-155") + } + + if len(domain.Name) == 0 && len(domain.Version) == 0 && len(domain.VerifyingContract) == 0 && len(domain.Salt) == 0 { + return errors.New("domain is undefined") + } + + return nil +} + +// Map is a helper function to generate a map version of the domain +func (domain *TypedDataDomain) Map() map[string]interface{} { + dataMap := map[string]interface{}{} + + if domain.ChainId != nil { + dataMap["chainId"] = domain.ChainId + } + + if len(domain.Name) > 0 { + dataMap["name"] = domain.Name + } + + if len(domain.Version) > 0 { + dataMap["version"] = domain.Version + } + + if len(domain.VerifyingContract) > 0 { + dataMap["verifyingContract"] = domain.VerifyingContract + } + + if len(domain.Salt) > 0 { + dataMap["salt"] = domain.Salt + } + return dataMap +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/README.md b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/README.md new file mode 100644 index 00000000..f425450a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/README.md @@ -0,0 +1,5 @@ +### EIP 712 tests + +These tests are json files which are converted into eip-712 typed data. +All files are expected to be proper json, and tests will fail if they are not. +Files that begin with `expfail' are expected to not pass the hashstruct construction. diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/arrays-1.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/arrays-1.json new file mode 100644 index 00000000..fea82b42 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/arrays-1.json @@ -0,0 +1,60 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Foo": [ + { + "name": "addys", + "type": "address[]" + }, + { + "name": "stringies", + "type": "string[]" + }, + { + "name": "inties", + "type": "uint[]" + } + ] + }, + "primaryType": "Foo", + "domain": { + "name": "Lorem", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "addys": [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003" + ], + "stringies": [ + "lorem", + "ipsum", + "dolores" + ], + "inties": [ + "0x0000000000000000000000000000000000000001", + "3", + 4.0 + ] + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/custom_arraytype.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/custom_arraytype.json new file mode 100644 index 00000000..078de88c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/custom_arraytype.json @@ -0,0 +1,54 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person[]" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { "name": "Cow"}, + "to": [{ "name": "Moose"},{ "name": "Goose"}], + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/eip712.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/eip712.json new file mode 100644 index 00000000..7b1cb8ae --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/eip712.json @@ -0,0 +1,76 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "test", + "type": "uint8" + }, + { + "name": "test2", + "type": "uint8" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "test": "3", + "test2": 5.0, + "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "test": "0", + "test2": 5, + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_arraytype_overload.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_arraytype_overload.json new file mode 100644 index 00000000..786487f1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_arraytype_overload.json @@ -0,0 +1,67 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Person[]": [ + { + "name": "baz", + "type": "string" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person[]" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": {"baz": "foo"}, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_datamismatch_1.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_datamismatch_1.json new file mode 100644 index 00000000..d19d470d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_datamismatch_1.json @@ -0,0 +1,64 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "Person" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-1.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-1.json new file mode 100644 index 00000000..fd704209 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-1.json @@ -0,0 +1,76 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256 ... and now for something completely different" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "test", + "type": "uint8" + }, + { + "name": "test2", + "type": "uint8" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "test": "3", + "test2": 5.0, + "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "test": "0", + "test2": 5, + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-2.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-2.json new file mode 100644 index 00000000..10f91c23 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_extradata-2.json @@ -0,0 +1,77 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "test", + "type": "uint8" + }, + { + "name": "test2", + "type": "uint8" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "blahonga": "zonk bonk", + "from": { + "name": "Cow", + "test": "3", + "test2": 5.0, + "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "test": "0", + "test2": 5, + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_malformeddomainkeys.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_malformeddomainkeys.json new file mode 100644 index 00000000..354b3cc8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_malformeddomainkeys.json @@ -0,0 +1,64 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "vFAILFAILerifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_nonexistant_type.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_nonexistant_type.json new file mode 100644 index 00000000..d06bc20b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_nonexistant_type.json @@ -0,0 +1,64 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "Blahonga" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint.json new file mode 100644 index 00000000..9854b65b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint.json @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test":"257" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint2.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint2.json new file mode 100644 index 00000000..c63ed41f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_toolargeuint2.json @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test":257 + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat.json new file mode 100644 index 00000000..8229a333 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat.json @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test":"255.3" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat2.json b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat2.json new file mode 100644 index 00000000..59e6d38d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/expfail_unconvertiblefloat2.json @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test": 255.3 + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/2850f6ccf2d7f5f846dfb73119b60e09e712783f b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/2850f6ccf2d7f5f846dfb73119b60e09e712783f new file mode 100644 index 00000000..8229a333 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/2850f6ccf2d7f5f846dfb73119b60e09e712783f @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test":"255.3" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/36fb987a774011dc675e1b5246ac5c1d44d84d92 b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/36fb987a774011dc675e1b5246ac5c1d44d84d92 new file mode 100644 index 00000000..fea82b42 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/36fb987a774011dc675e1b5246ac5c1d44d84d92 @@ -0,0 +1,60 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Foo": [ + { + "name": "addys", + "type": "address[]" + }, + { + "name": "stringies", + "type": "string[]" + }, + { + "name": "inties", + "type": "uint[]" + } + ] + }, + "primaryType": "Foo", + "domain": { + "name": "Lorem", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "addys": [ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003" + ], + "stringies": [ + "lorem", + "ipsum", + "dolores" + ], + "inties": [ + "0x0000000000000000000000000000000000000001", + "3", + 4.0 + ] + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/37ec7b55c7ba014cced204c5f9989d2d0eb9ff6d b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/37ec7b55c7ba014cced204c5f9989d2d0eb9ff6d new file mode 100644 index 00000000..c63ed41f --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/37ec7b55c7ba014cced204c5f9989d2d0eb9ff6d @@ -0,0 +1,38 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Mail": [ + { + "name": "test", + "type": "uint8" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "Ether Mail", + "version": "1", + "chainId": "1", + "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "test":257 + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/582fa92154b784daa1faa293b695fa388fe34bf1 b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/582fa92154b784daa1faa293b695fa388fe34bf1 new file mode 100644 index 00000000..9bc43938 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/582fa92154b784daa1faa293b695fa388fe34bf1 @@ -0,0 +1 @@ +{"domain":{"version":"0","chainId":""}} \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/ab57cb2b2b5ce614efe13a47bc73814580f2cce8 b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/ab57cb2b2b5ce614efe13a47bc73814580f2cce8 new file mode 100644 index 00000000..fe27de91 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/ab57cb2b2b5ce614efe13a47bc73814580f2cce8 @@ -0,0 +1,54 @@ +{ "types": { "":[ { + "name": "name", + "type":"string" }, + { + "name":"version", + "type": "string" }, { + "name": "chaiI", + "type":"uint256 . ad nowretig omeedifere" }, { + "ae": "eifinC", + "ty":"dess" + } + ], + "Person":[ + { + "name":"name", + "type": "string" + }, { + "name":"tes", "type":"it8" + }, + { "name":"t", "tye":"uit8" + }, + { + "a":"ale", + "type": "ress" + } + ], + "Mail": [ + { + "name":"from", "type":"Person" }, + { + "name": "to", "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] + }, "primaryType": "Mail", + "domain": { +"name":"theMail", "version": "1", + "chainId": "1", + "verifyingntract": "0xCcccCCCcCCCCCCCcCCcCCCcCcccccC" + }, + "message": { "from": { + "name": "Cow", + "test": "3", + "est2":5.0, + "llt": "0xcD2a3938E13D947E0bE734DfDD86" }, "to": { "name": "Bob", + "ts":"", + "tet2": 5, + "allet": "0bBBBBbbBBbbbbBbbBbbbbBBBbB" + }, + "contents": "Hello, Bob!" } +} \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/e4303e23ca34fbbc43164a232b2caa7a3af2bf8d b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/e4303e23ca34fbbc43164a232b2caa7a3af2bf8d new file mode 100644 index 00000000..c5e14b39 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/e4303e23ca34fbbc43164a232b2caa7a3af2bf8d @@ -0,0 +1,64 @@ +{ + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "int" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Mail" + }, + { + "name": "s", + "type": "Person" + } + ] + }, + "primaryType": "Mail", + "domain": { + "name": "l", + "version": "1", + "chainId": "", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" + }, + "message": { + "from": { + "name": "", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "": "" + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/f658340af009dd4a35abe645a00a7b732bc30921 b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/f658340af009dd4a35abe645a00a7b732bc30921 new file mode 100644 index 00000000..c4841cb0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/testdata/fuzzing/f658340af009dd4a35abe645a00a7b732bc30921 @@ -0,0 +1 @@ +{"types":{"0":[{}]}} \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/types.go b/vendor/github.com/ethereum/go-ethereum/signer/core/types.go new file mode 100644 index 00000000..91443b24 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/types.go @@ -0,0 +1,100 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package core + +import ( + "encoding/json" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +type ValidationInfo struct { + Typ string `json:"type"` + Message string `json:"message"` +} +type ValidationMessages struct { + Messages []ValidationInfo +} + +const ( + WARN = "WARNING" + CRIT = "CRITICAL" + INFO = "Info" +) + +func (vs *ValidationMessages) Crit(msg string) { + vs.Messages = append(vs.Messages, ValidationInfo{CRIT, msg}) +} +func (vs *ValidationMessages) Warn(msg string) { + vs.Messages = append(vs.Messages, ValidationInfo{WARN, msg}) +} +func (vs *ValidationMessages) Info(msg string) { + vs.Messages = append(vs.Messages, ValidationInfo{INFO, msg}) +} + +/// getWarnings returns an error with all messages of type WARN of above, or nil if no warnings were present +func (v *ValidationMessages) getWarnings() error { + var messages []string + for _, msg := range v.Messages { + if msg.Typ == WARN || msg.Typ == CRIT { + messages = append(messages, msg.Message) + } + } + if len(messages) > 0 { + return fmt.Errorf("Validation failed: %s", strings.Join(messages, ",")) + } + return nil +} + +// SendTxArgs represents the arguments to submit a transaction +type SendTxArgs struct { + From common.MixedcaseAddress `json:"from"` + To *common.MixedcaseAddress `json:"to"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice hexutil.Big `json:"gasPrice"` + Value hexutil.Big `json:"value"` + Nonce hexutil.Uint64 `json:"nonce"` + // We accept "data" and "input" for backwards-compatibility reasons. + Data *hexutil.Bytes `json:"data"` + Input *hexutil.Bytes `json:"input,omitempty"` +} + +func (args SendTxArgs) String() string { + s, err := json.Marshal(args) + if err == nil { + return string(s) + } + return err.Error() +} + +func (args *SendTxArgs) toTransaction() *types.Transaction { + var input []byte + if args.Data != nil { + input = *args.Data + } else if args.Input != nil { + input = *args.Input + } + if args.To == nil { + return types.NewContractCreation(uint64(args.Nonce), (*big.Int)(&args.Value), uint64(args.Gas), (*big.Int)(&args.GasPrice), input) + } + return types.NewTransaction(uint64(args.Nonce), args.To.Address(), (*big.Int)(&args.Value), (uint64)(args.Gas), (*big.Int)(&args.GasPrice), input) +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/core/validation.go b/vendor/github.com/ethereum/go-ethereum/signer/core/validation.go new file mode 100644 index 00000000..164d5112 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/core/validation.go @@ -0,0 +1,36 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package core + +import ( + "errors" + "regexp" +) + +var printable7BitAscii = regexp.MustCompile("^[A-Za-z0-9!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ]+$") + +// ValidatePasswordFormat returns an error if the password is too short, or consists of characters +// outside the range of the printable 7bit ascii set +func ValidatePasswordFormat(password string) error { + if len(password) < 10 { + return errors.New("password too short (<10 characters)") + } + if !printable7BitAscii.MatchString(password) { + return errors.New("password contains invalid characters - only 7bit printable ascii allowed") + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.go b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.go new file mode 100644 index 00000000..9ec51047 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.go @@ -0,0 +1,271 @@ +// Code generated by go-bindata. DO NOT EDIT. +// sources: +// 4byte.json (5.505MB) + +package fourbyte + +import ( + "bytes" + "compress/gzip" + "crypto/sha256" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo + digest [sha256.Size]byte +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (fi bindataFileInfo) Name() string { + return fi.name +} +func (fi bindataFileInfo) Size() int64 { + return fi.size +} +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} +func (fi bindataFileInfo) IsDir() bool { + return false +} +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var __4byteJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\xbd\x49\x73\x23\xb9\xf1\x37\xfc\x5d\xe6\xd4\x6f\xc4\x1c\x0a\xa8\xdd\x37\x92\xa2\xba\xe5\xd1\x42\x8b\xec\xee\xb1\x1d\xff\x60\x60\x49\x90\x65\x15\x0b\x74\x2d\x52\x73\xde\x2f\xff\x04\x12\x40\x6d\xa2\x7a\xc6\x3e\x8c\xda\x04\x6a\x03\x12\xb9\xfe\x32\xf3\xff\xff\x25\xb0\xff\x23\xbf\xfc\xed\x17\x26\x84\xee\xaa\x76\x5f\x54\x4a\xef\x6b\xdd\xb2\x16\xf6\x6d\x51\xc1\xa7\xae\xa8\x5a\x1a\x27\xff\xdf\x2f\xbf\xfa\xe9\xf4\x97\xbf\xfd\x52\xb3\x3f\x74\xbd\xe7\xac\x64\x95\x80\x4f\x5c\xeb\x72\x34\x41\xfc\xf2\xb7\x5f\x0e\xdd\xe9\xf7\x7f\xad\xfe\xf5\x69\xf8\x39\x0c\x7f\xf9\xdb\x2f\x27\xd6\x8a\xe3\x4e\xbf\x40\xf5\x54\x4b\xa8\x97\x97\x85\x3c\x15\xd5\xfe\x25\x8a\xfe\xe3\x9f\xf4\xef\xff\x1b\x5d\x93\xff\xf2\xb7\x5f\x7e\xff\xfd\xf7\x7d\x57\xd5\x20\xf4\xa1\x2a\xfe\x00\xb9\x67\x92\x9d\x5b\xa8\x3f\x35\x6d\x5d\x54\x87\xd1\x6c\x66\x1e\xac\xb5\xdc\x9f\x8a\xba\xd6\xb5\xbf\xe3\xaf\xe6\x6f\x48\x87\x89\x89\x7b\x95\xa3\xfb\xd2\xc9\x44\xff\x37\x89\xdc\x9f\xd1\x75\xf0\xcb\xdf\x7e\x91\x45\x73\x2e\xd9\x65\xcf\xca\x52\xbf\x5d\xbd\xf2\xda\x23\xb3\xe0\x97\xbf\xfd\x22\x74\x25\x3b\xd1\xee\x59\xd7\xea\x8f\xae\x1c\x5d\x62\x16\x9a\xd5\x2d\x28\x26\xda\xfd\x0b\xc0\xf9\x13\xbf\xb4\xd0\x90\x61\x0a\x33\x77\x6d\x6b\x80\x7d\xd3\xd6\xc0\x4e\x76\xc2\xaf\xf8\xdf\xd1\x2c\xb3\xc1\xe7\xa2\x69\x75\xb9\x7f\x65\xe5\x2b\x7c\xb8\x30\x3c\xf1\x7b\xe4\x77\x66\xf7\xf6\x25\x4c\xae\x6d\x8d\x88\x7e\xf9\xdb\x2f\x0a\x9a\xb6\x78\x65\xe5\xfe\xc8\xce\xe7\xcb\xfc\x93\x46\x93\xd3\x5f\xfe\xf6\x4b\x09\x95\xdc\xcb\xce\xec\xd9\xcf\x16\x7c\xfc\x3e\xd2\xec\xe8\xa9\x6b\x44\x09\xfb\x16\x98\x38\x7e\xba\x72\x41\x36\x9a\xcf\x7f\xf9\xdb\x2f\xaf\x05\xe3\x25\xec\xcf\x75\x51\xb5\x1f\x3c\x68\x74\x85\xd9\xd2\x73\x09\xf2\x00\x7b\xd5\xb5\x5d\x3d\x5f\x9c\xf9\x23\x40\xda\xd3\x02\x4d\xb3\x17\x5a\xe8\xaa\x6b\xf7\xac\x64\xf5\xe9\xfd\x49\x51\xb1\xd9\xf3\x23\xd4\xf5\x65\xdf\xea\x93\xae\xeb\x19\xc1\x24\xd1\xaf\xd3\xa3\xa3\x32\x73\xb6\xe0\xbf\x5d\x51\x83\x34\x7b\x2a\x74\xf5\xea\xe8\xfc\xd7\x29\xb9\x67\x79\x62\xe8\xa3\x35\x67\xc9\xcf\xc0\x57\x9d\xcd\x63\xc0\x91\xda\x8b\x43\xcd\x5a\xf0\xdb\x7a\xf3\x8f\x6f\xef\x36\x95\x50\x95\x99\xf5\xbb\x67\x6d\xd1\x9d\x7e\xf7\x47\x97\x44\x71\x60\x9f\xd4\xb2\xf2\xae\x52\x20\x5a\x90\xfd\x60\x6c\x69\xf0\x66\xfd\x6d\xbf\x5b\x2f\x1e\xf6\xdb\xdd\xe2\xb7\xb5\x1f\xa5\x01\xa3\xe6\x8b\xbe\xb0\xb2\xc5\x43\xbf\x28\xcb\xa7\x33\xd4\xac\x2d\x74\xd5\x4f\x4a\x52\x66\x68\xe9\x00\xed\x57\xb3\x63\xfd\xcf\x40\x42\xbb\x7e\xe2\x65\xd1\xbe\x2c\x75\xd3\xfc\xa3\x83\xa6\xfd\xc4\xa4\xac\xa1\xf1\xf4\x4d\xd3\x34\x34\xd4\xc5\x0a\xa1\xab\xb6\x66\x62\xb8\x03\x63\x38\x52\x17\xe2\xd8\x42\xd3\xbe\xbc\xf4\x8b\xff\xf1\x7a\x51\x41\xa4\xe1\x5f\x7f\xd7\xc7\xaa\xd1\xd5\x6b\x51\x96\xe0\x6f\x18\x25\x82\x28\xbf\x12\x37\x35\x3b\xe8\xaa\xf1\x63\x31\x8d\x95\xa1\x8c\x5a\xf3\x95\x2e\xfa\x8f\x8b\x59\x8c\x7c\x6f\xa5\x59\x59\x88\x23\x2b\x2a\x5c\x87\x7e\x98\x2b\x9e\xe2\xb7\x9f\x4e\x97\x87\xae\x29\xc4\xbd\x16\x2f\xbb\xe2\xd4\x3f\x33\x25\xa1\x32\x24\x7a\x57\x15\x6d\x61\x58\x95\xfb\xfa\xab\x0c\xc7\xfc\x1d\x11\x54\x1a\x13\x6e\x96\xff\x5e\x1f\xd6\x3f\x5a\xa8\xe4\x96\x95\x73\x86\x9e\x26\x79\x64\x5e\xb0\xab\x4a\x2d\x5e\xa0\xee\x9f\x9b\x48\x48\x2d\xb7\x33\xa7\x69\x0b\x65\x09\xf5\xca\x70\xfb\x12\xef\x40\x92\x5f\xfd\x9b\x4c\xf7\x23\x8b\x25\x8d\x71\x21\xba\x4a\x86\xfe\x76\x99\xca\xa4\xc2\xdd\x64\xd5\x01\xee\x84\xbe\x2d\xaa\xa2\x39\xce\x5e\x26\x8f\x48\x62\x78\xd5\x6e\xfd\xfc\xb0\xdd\x2f\x1e\x6f\xf6\xab\xa7\xc7\x9b\xbb\xdd\xdd\xd3\xe3\xd6\xdf\x29\x4f\xa2\xc4\x48\x85\x45\x27\x0c\x15\xad\x6a\x60\x86\x1e\xfd\xe7\xff\xd9\xf2\xcc\x1e\x98\x05\x21\x47\x96\xf7\x02\x9b\x5a\xff\x07\x44\x4f\x5e\x63\x1a\xb9\x72\x61\x2e\xf0\x7b\xde\x8a\xf6\x28\x6b\xf6\x86\xbb\xda\x84\xb3\xef\x61\x11\x4b\x0d\x07\xe3\xcc\x90\xf0\x5d\x25\xe1\xc7\x9f\xb0\x7d\x26\x88\x32\xf7\x65\x52\x9e\x59\xdd\x36\x96\xa1\x3b\x2e\xf4\x93\xcb\xa4\x48\xcc\x6e\xf1\xee\xb2\x6f\x8f\xb0\x47\xae\xd0\x4c\x05\x24\x4f\x12\x69\x76\xba\x81\xf6\x4e\xe8\x6d\xcb\xea\x16\x09\x6d\x7a\x27\x9e\xa7\xd4\x08\x81\x87\xa2\x6a\x8b\xea\xb0\x9a\x9d\x29\x0e\x61\x6c\x86\xe1\xc7\xd9\xb0\xa8\xa5\x21\x1a\x3f\x26\x08\x65\xe6\xdd\x77\x4f\xbb\xc5\xfd\x7e\xf7\xf4\xdb\xfa\xb1\xd9\x6f\xbf\x6e\x36\xf7\xff\xec\xa7\x24\xb1\x08\x47\xcb\xf6\xed\x71\xbd\x9b\x53\xb4\x9f\xca\xe2\x0c\x90\x1b\xaa\xae\x92\xcf\xf0\x5f\x73\xf6\xcd\x0b\x8f\x1f\x29\x19\xc4\xe6\xb4\x8a\x92\x15\x27\x56\xb5\x2b\x73\x62\xc5\x88\x1e\xdc\x3c\x08\xa8\x34\x6c\x4a\x15\xaf\xf0\xa5\xab\x64\x0d\x72\x77\xd4\x5d\xc3\xaa\x9e\x93\x01\xcd\xfc\xf2\xdc\xb3\x4a\x36\xf7\xc5\xa9\x68\x37\x50\x2f\x8b\x77\x37\xa3\x0a\x35\x0d\x64\x03\xf7\xcb\xad\x2e\xe5\xfe\xf3\xfa\x71\xfd\xbc\xb8\xdf\x93\xfe\x76\x89\x65\xe6\x67\xa8\x64\x51\x1d\x96\xd0\x36\x4b\xa7\x2d\xf9\x19\xa9\x62\x38\xa3\x86\x86\x95\xb0\xa9\x8b\x61\x4c\x05\x12\xe5\x8c\xd4\x8b\xa2\x96\xb5\x3e\x7f\xb0\x48\x2a\x25\x4e\x64\x88\x02\x5e\xe1\x11\x0e\xcf\xf0\xdf\x9f\xea\x24\x03\xf7\xb3\xb7\x20\x46\x3d\x30\xb7\x78\x84\xb7\x8d\x2e\xcb\xa9\xb0\xb9\x4e\x6e\x24\x00\x99\xe7\x96\x65\x2f\x6b\x76\x38\x40\x3d\xa3\x6e\x37\x8f\x84\x10\x64\x6e\x9e\xfd\x78\xcf\x2f\x09\x89\x05\x37\x8b\xf8\xf5\x2c\x59\x8b\xec\x65\x71\x80\xaa\x5d\x1a\x25\xf4\x32\x65\xf1\x84\x46\x09\x98\x53\xca\x5e\x59\x51\x1a\x6e\x74\x5b\x1e\xfc\x7d\xa8\xcc\x03\x73\x9f\xe5\xe3\x72\xff\x65\xf1\x7c\xb3\x5f\x2d\x36\x7e\x2c\x0c\x73\x1e\xe0\x0a\x17\x7f\xc0\x46\xeb\x72\x67\x76\xcc\x1e\xa9\xc8\xcf\x49\x25\x6a\x75\x67\x10\x5d\xb9\xc0\xa7\xf6\x97\x4b\x16\x9b\xcb\x25\x94\xf7\x45\xd3\x7e\xfa\xe9\x92\x84\xc0\x23\xf3\x8e\x45\xb3\xfe\x51\xcc\x85\x14\x89\x54\x8e\xc7\xe6\x00\xed\x33\x34\xba\xab\x05\x34\x77\x95\xd2\xb3\x69\x31\xcd\x69\x64\x69\x70\x0b\xa5\xf2\x87\x6f\x61\x27\xcd\x27\x73\x48\x09\x1e\x45\x10\x5d\x5b\xbc\xc2\x93\x52\x85\x80\xda\xcf\x76\xd3\x92\x24\xe5\xdc\x3e\x7a\x73\xb7\x07\x59\xb4\xfb\x30\xf2\x83\x69\x28\x93\xd8\x0e\x6e\x8f\xba\x2b\xe5\x67\xa8\x8c\x78\x86\x9b\x8a\xf5\x73\xd2\x10\x12\xab\xbc\xbe\x42\xdd\x3e\x40\xbb\xd3\xeb\xf6\x78\x5d\xd9\x23\xa9\x90\xa8\x44\x6c\x9e\xef\x1e\xd6\xfd\x2d\x80\x08\x65\x1f\xb3\x03\x76\x7a\x64\x27\xb8\xd5\xf5\xf5\xcf\xca\x38\xc1\x73\x78\x3e\xf7\x9f\x90\xf1\x04\xdf\xf2\xa5\x28\x4b\x64\xb4\x33\xae\x44\xf2\x40\x25\x4e\x85\xd8\xb6\xac\xed\x9a\x7b\x7d\xe8\xaf\xce\x73\x9e\x1a\x62\xdd\x77\x48\x6a\xf7\xa3\xdd\xf9\xf7\xff\xcd\x85\x98\x57\x86\x48\xce\xa2\xc4\x2e\x5b\x15\xac\xba\xb6\x00\x27\x68\x56\x86\x40\xfb\x5b\x8b\x3c\x45\xa1\x0f\x12\xe0\xb4\xd1\xe7\x19\xfd\xb3\x48\xc5\x86\xb8\x04\x5e\xfb\x08\x6f\xcf\xf0\x5a\x34\x46\xf7\xf1\x6c\xdd\xfd\xf5\xf3\x59\x80\xcc\xd7\xb3\xc7\x07\x56\x1f\x8a\x6a\x53\xc3\xb6\x38\x54\x20\x9d\x76\xff\x3f\x89\x38\xc2\x38\x11\xd2\xd2\xd4\xa2\x59\x76\x75\x05\x75\xcf\x4c\x06\x5d\x81\x30\x9e\xe7\x66\xd9\xbf\xed\xa0\x69\x6f\x0a\x43\xeb\xbc\x43\x35\xed\x83\xc7\xb9\xeb\x38\x89\x22\x43\x85\xeb\xf6\x08\x75\x05\x3f\xfa\xb5\xe1\x44\x28\xd4\x0c\x3b\x56\x1a\x61\x62\xce\xad\xd5\x7d\xae\xea\x0d\x84\x87\xca\x92\x19\xab\xe5\x9e\x97\x1d\xec\x55\x51\x37\xc3\xed\x58\x0a\xe6\x9c\x37\xc5\xa1\xfa\x5e\xb4\xd5\x88\xc2\x39\x63\x59\xde\xaf\xb2\x5c\x5e\x66\xbb\xc0\x45\x92\x33\x4b\x1d\x9f\x8d\xea\xd9\x76\x12\x9a\x27\x35\xa3\x3b\xa1\xe2\xd4\x88\xd0\x37\xf1\x54\xad\x6a\xfd\x26\x0d\x53\xbe\x65\x45\x69\x4c\x02\x37\x47\xa6\x5c\xb9\x63\x7c\x57\xbd\x42\xd3\x9e\xa0\x6a\x17\x75\xcd\x2e\xfd\x0c\x9e\x46\x66\xb5\x6f\x6b\x80\x7b\xfd\x3a\x5c\xc9\x21\x73\xef\xb0\xd5\xaa\x7d\x63\x35\xac\x7f\x80\x78\x06\xa1\x6b\x79\x0f\xd5\xa1\x3d\xfa\xa9\x20\x03\x42\xad\x5c\x78\x2d\x74\xe7\xf6\xac\xff\x5a\x80\x84\xe3\x30\xab\xdb\x42\x14\x67\xd6\xc2\x67\xe6\xc4\xb8\xd3\x13\xe6\x7f\xdc\x95\x2a\x88\xd2\xbc\x67\x42\x5d\xd9\x3e\xb0\xe6\xe5\x83\x63\xac\xa2\x14\xdd\x02\xeb\x1f\xec\x74\x2e\x07\xb6\xad\x32\x49\x08\x52\xfc\x49\xbf\xc2\x86\x89\x17\x76\x80\x9e\x9a\x27\x82\x45\xe5\x44\x20\xf1\x77\x35\x6b\xf5\x9c\x2d\xa9\x9c\x8b\xc0\x92\xe5\x9e\xd5\xbc\x68\x9b\xbd\x13\x84\x7b\x7d\x1e\x11\xc9\x40\xa2\x34\x20\x80\xba\xf4\xf2\xe9\xf1\xeb\x76\x9f\xec\x6f\x16\xff\xf4\x5a\x21\x0d\x42\x42\x50\x2f\xa9\x24\xae\xc6\x98\x68\xb3\x7e\x4e\x98\x39\x66\x87\x82\x60\x89\x06\x59\x51\x1d\xee\x5a\x38\xf9\x1b\x11\x9a\xa0\x26\x75\xda\xe3\x81\xd7\x75\x3f\x20\x43\xcf\x63\x1e\x9f\xbe\xe9\x16\x9a\xe5\x65\x5d\xb5\x45\x3b\x23\x37\x4a\x13\xe0\xee\x31\x37\x70\xd6\x4d\xd1\x3e\x76\xfd\xed\x69\x9a\xa2\x09\x51\x75\xa7\x85\x7c\x2d\x1a\xa8\xdd\x1c\xbf\x30\x34\x0c\x33\x40\x2d\xea\x7e\xbb\xea\x7f\x93\x40\x73\x6f\xec\x35\xcf\x20\xa0\x78\x05\x39\x3f\x48\xef\x18\xc3\x3b\x67\x00\x8d\x62\x4a\xcd\xaa\x7f\x59\xfc\xfd\x66\xf7\x73\xcb\x91\x46\x4e\xa2\x1d\xa0\x5d\xe9\xd3\x99\x55\x97\x45\x59\x6a\x61\x6d\xb7\xe9\x27\xa7\x69\x96\x99\x9d\x31\xcc\xdd\x6a\xc2\x5f\x74\x29\x47\x8c\xe6\xea\x91\xa7\x19\xcf\x71\x31\x7a\x76\xa3\xdf\x5d\xe1\x66\xe6\x31\x89\x14\x4a\x95\xa7\xd5\x7a\xbb\x5d\x7a\x85\x92\xe6\x69\x82\x42\x50\xa0\x65\xf2\x54\xa1\x26\xe1\x07\x19\x25\x48\x30\x96\x31\xac\x8a\xb6\xf8\x03\x2a\x6f\xbd\x8c\xfe\x64\xbf\xce\xd8\xf1\x94\x2d\x53\x46\x69\x66\xb4\xcc\xa2\x2a\xda\x2d\xcc\x95\x4b\xca\x22\x4e\x0c\x65\x3c\x16\x15\xf4\x8f\x8e\x85\x70\x67\x6d\x57\x88\x17\x68\xed\x82\x34\xb3\x4b\x39\x00\x9e\x91\xae\x52\xb5\xfe\x03\xe6\x56\x8c\x9b\x25\x08\xcb\xad\x8e\x52\x0b\xf8\xc0\xa7\x31\xdc\x53\x64\x11\xea\x1a\xad\x7e\x3a\x43\x65\x28\xd5\xbf\x94\x80\x24\x4c\xec\x99\x6b\xeb\xae\x69\x01\xbe\xb1\xae\x44\xf5\x62\xca\x0c\xa9\x4c\x45\x2e\xad\xcc\x17\x65\x27\xe1\xd6\xb0\x62\x67\x71\xf9\xbb\x49\x91\x2a\xb3\xf4\x2b\x34\xe9\x36\x50\x17\xda\x2b\xd3\x14\x02\x86\xd6\x63\x5b\xb3\xaa\x51\x50\x5b\x8f\x5f\xd7\x5e\x57\x63\x29\x90\x90\x58\xcf\xd3\x8f\x81\xaf\xf6\xf7\x22\x32\x35\x5f\x7f\xbf\x32\xdf\x63\x2c\x00\xdd\xb5\x9f\xa6\x3b\xa4\x48\x2c\xd8\xa0\x7d\xd9\x9b\xe8\xf9\x57\x19\x25\xcc\x6c\x0a\xb3\x74\x0c\xd2\xd2\xaa\x7f\x90\x92\x41\x6a\xb6\x79\xcf\xce\xe7\xda\xf0\xee\x9f\x4a\xbe\x30\x48\x23\xe5\x94\x9a\xdb\x5a\x57\xc6\xbe\xfe\xd4\x0f\x65\xa8\x78\x5a\xa3\x7a\xa7\x67\x36\xa5\x9b\x45\x02\x20\x76\x3b\xca\xf2\xbb\x2e\x5f\xa6\xb4\x11\x92\x9c\x31\xb3\x07\x7b\xbf\x88\x4c\xbe\x1a\x2a\x7f\x7f\xee\x67\xd7\xb1\x08\x0d\xa7\xd3\xe5\x6e\xf5\xe4\xdf\x88\x52\xce\xed\xb3\x2a\xb9\x29\x59\xab\x74\x7d\x7a\x60\x85\x79\xeb\x91\x4d\x12\xd2\x38\x47\x29\xfb\xaa\x5b\xb0\x32\xa2\x1f\x49\x89\x8c\xbd\x3b\xc6\x28\x59\xc6\x5e\xd6\x6a\xaa\xc8\xfc\xda\xbb\x94\xde\xf3\x9e\x30\x0c\xc3\x34\x46\x4f\x54\x55\x9c\x3a\x7c\xfa\x96\x95\xf0\xcc\x8a\xa6\x7f\x7e\x18\x66\xd6\x9d\x54\xb3\xb7\xa7\xb3\xff\x35\x8a\x62\x82\x1b\xc3\xbb\xa2\x94\x77\x55\x0b\x75\xc5\xca\x2d\x2b\xed\x51\x20\x34\xfb\x90\x05\x8e\xdd\x7d\x61\x94\xf0\x38\xb5\xf4\xff\x45\xcb\x12\xea\x6d\xcb\x5e\xde\x6d\xb3\x9f\x9c\xc7\xde\x2d\xf5\xa5\x38\x1c\xa1\x69\x97\x85\x94\xbd\x83\x24\x8c\xb8\x75\xf8\x18\x5d\xad\x66\x6f\xb7\x5d\x25\x77\xc0\xc4\x11\xea\xd9\x3e\x46\x2a\x46\xe6\xbd\xaf\xad\x0d\x8b\x14\xda\x4c\x9e\xea\xe9\x38\x8c\xc3\x4c\xc4\xc8\x48\x9b\xf6\x19\x0e\x86\x2f\xb2\x91\xba\x36\xa6\xf9\x30\x8e\x72\x5c\xcf\x6f\xcf\xff\x1c\x79\x9c\xc2\x38\xb7\x36\x97\x93\xa6\xd6\xcf\x02\x72\xd1\xef\x64\xcc\x22\xb4\x99\x8b\xc6\xf0\xf3\x37\x73\x0a\x36\x5d\x2d\x8e\x6c\xd8\x86\x58\x00\x37\x47\x7b\x59\x17\xd5\xcb\x1f\x63\x8f\x55\x98\x04\x71\x2e\xd0\x45\xb3\xdd\xad\x9f\xe7\x0e\xb5\x09\x7d\x27\x01\x4f\xd0\x95\x70\x79\xd0\x55\xd3\x42\x7d\x27\x9b\x0f\x16\x3b\xa1\x11\x35\x8b\xb9\xd1\x6f\x50\xd3\xdf\xfb\x87\xd1\x38\xc8\xad\x03\xeb\x7b\xf1\xa1\x26\xfa\xee\x5e\x2c\x8f\xd1\x76\xae\x46\xfe\x32\x3f\x18\x09\x34\x25\x39\xda\x99\x0f\xac\x62\x07\x30\xcc\xe6\x3b\x2b\x4b\x68\xa7\x3a\x4a\x98\x24\x34\x32\xa7\x61\x71\x32\xb3\xdf\x89\xdd\xe9\x63\xd3\x20\xe6\x62\xa4\x5d\x7c\xdd\xde\xdc\x55\x13\x06\x13\xa6\x52\x46\xa9\x75\xee\x7c\xad\x8a\xff\x76\x60\xe8\xdf\x4d\xb9\x7e\xd3\x2c\x94\x68\xdd\x9e\xd8\x0f\x63\x02\x74\xfd\x91\xc8\xd2\x34\x74\xde\x0a\xa3\xef\xb8\xb3\x3a\x5e\x10\xa7\xf5\x84\x79\x4c\xa9\x79\x2f\x38\x41\x7d\x80\x4a\x5c\xbe\x3b\xe3\x82\x95\x33\x42\xcd\xe3\x0c\xa8\x5d\x6d\xeb\xa4\x45\xa5\x6d\xb6\x80\x79\x9a\xf8\x6f\xd8\x69\xa3\xe5\xa2\x59\x5f\xe3\x27\xaf\x59\x5d\xfd\x29\x7b\xca\x99\x4c\xcc\x56\x3f\x3f\x7d\x7d\xbc\xd9\xee\x7f\x5b\x6f\x76\xfe\xa3\x58\x28\x31\x4c\xf2\x19\x5a\xf4\x54\xfa\x9f\x63\x1e\x78\xe3\x59\x77\x95\x5c\x57\xce\xef\x34\x39\x3a\x2c\x49\x88\xb5\xc5\x2a\xdd\x55\x02\x9e\xde\x2a\x90\xe6\x3f\x75\x73\x2c\xce\xb3\xaf\x60\xdc\xba\xd9\xda\xe2\x04\x35\xf4\xea\x59\xc8\x03\x16\xf6\x3c\x1d\xe0\xa6\xa8\x74\x3f\x94\xcb\x2c\x73\xfe\x21\x43\xa5\xb7\x60\x64\x9e\x91\xc7\x46\x03\x1e\xaf\x38\x67\x04\x9c\xc5\xf5\xac\xf5\xcc\x15\x10\x72\xc1\x43\xc3\x57\xde\x91\xd3\x84\x83\xba\xc9\x42\x2a\x34\x08\xef\x8b\x93\xb7\xc7\x43\x01\x10\x1b\x9a\xf8\x72\xbf\x9a\xda\x53\x1f\x7b\x6e\xfc\x9b\x49\x9e\xa2\x9e\xd6\x9f\xf7\xbf\x64\x42\x1a\xed\x33\x0c\xc6\x26\x47\xd5\xae\x4a\xf6\xc6\x99\x78\x41\xb3\x6f\x46\x47\x90\xcb\xd8\x9c\xb1\xdb\xa2\x2c\x31\xca\x77\xdd\xc6\x08\x81\xc9\x58\xd9\x75\xda\x7c\x5b\x2f\x59\xdb\x96\x70\x0b\x33\x87\x64\xa8\x82\x54\x59\xd1\xfe\x8d\x95\x85\xbc\xea\x34\x08\x95\x0c\x71\x4d\x56\x4f\x8f\xbb\xbb\xc7\xaf\xeb\xfd\xc3\x9d\xf9\xc7\x67\xb7\x66\x51\x10\xe5\xf8\x05\xab\xfa\x72\x6e\xf5\x73\x71\x61\x65\x3f\x14\x87\x31\xb1\x5b\xfe\x9d\xd5\x75\xa1\xeb\x95\x61\xf6\x0b\xef\x6b\x1a\xe6\x25\x18\xc5\x7a\x35\x6f\x61\xac\x79\x76\x02\x2f\x8a\xd6\xbb\x89\xab\x35\x0a\xd2\x1c\xa5\xed\xca\x08\x4b\x63\xe7\xcd\x86\x95\x4a\x44\xef\x0c\x37\x9f\xec\x06\x08\x48\x00\xcb\xbb\x07\xd6\x80\x8e\x48\x3f\x83\x46\x01\xe0\xb9\x47\xf7\xad\x51\x0c\x98\x98\x58\xe9\x57\x0f\x5d\x44\x93\x08\xfd\xae\xfa\x15\x6a\x55\xea\xb7\xfe\x76\x2c\xe4\x80\x8b\xbb\xe9\x78\x59\x34\xc7\xa9\x5e\x15\x85\x54\xa8\xd0\xd9\x00\x5d\x5d\x43\xd5\x5a\x97\x84\xe5\x88\x7f\x6a\x80\x5c\xdd\xf7\x28\x14\xc2\x2a\x87\x20\x8e\x95\x2e\xf5\xe1\xb2\x3d\xb2\xde\xc8\x8e\x22\xca\x02\x1b\x13\x69\xef\x35\xab\x56\xba\x52\xc5\x61\x4a\x14\x51\x4c\xad\x26\xfb\xf9\x87\x65\xe1\xd2\xf2\xef\x29\x55\x44\x71\x42\x13\x85\x2c\xa1\xed\xea\x6a\xbd\xfb\xb2\xbc\x20\x43\xf0\x4f\x8a\x59\x24\x23\xfb\xf5\xda\xa8\x42\xf5\xda\x7a\xb5\xc7\xa7\x39\x4a\xb3\x38\x70\x96\xfb\x93\x52\x50\xa3\x03\x68\x79\x99\x1c\xbd\x7e\xaa\xca\xcc\x9b\xef\xee\xbc\xe5\x16\x65\x34\x44\x37\x52\x03\xed\x53\x7d\x60\x95\xa1\x9a\x29\x31\x64\x32\x41\xa6\xd7\x42\x63\x37\x54\x41\x8d\xe6\xa5\xbf\x45\x9e\x51\xd4\x5a\x4e\xec\xc7\x77\x28\x76\x05\xd4\xb4\x1f\x52\x41\x62\x78\x92\xb6\x1e\x31\x63\x42\xbd\xb3\x21\x66\x8b\xcf\x09\xa0\xd6\x60\xc9\x66\xd1\xb5\x47\x5d\x17\x0d\x7a\x4d\xfc\x0c\x99\xb3\xd8\xb1\x2f\xd6\x42\x3c\x5b\x7a\x91\x47\x14\x90\x7f\xa1\x36\xb3\xbf\x29\x5e\x0b\x09\x95\xec\xdf\x57\x86\x39\x2a\x0f\x5f\xd8\xeb\x2b\x54\x9f\x75\x29\xfb\x91\x08\x64\xee\xee\x0c\x87\x91\x19\x39\x7b\x47\xc9\xc3\x14\xb5\x40\xf6\x56\x8d\x54\x9b\x48\x0a\x49\x86\x73\xb3\xac\x0b\xf1\x2e\xa2\x37\xfd\xe3\x88\xf9\xdf\xff\x37\x7b\x00\x70\x86\xae\xf7\xa6\x28\xf5\x1e\x65\x80\x7f\x04\xa8\x44\x24\xa8\x1f\xe8\x0f\x5c\x23\x91\x0a\x21\x33\x53\x94\xae\x05\xb8\x88\x98\x1f\x8a\x82\x08\x43\xa5\xec\x05\x16\x65\xb9\xd1\x4d\x53\x18\x16\xe2\x9d\x8b\xe1\xff\x0d\xaf\x32\xfd\x3f\xf6\x5f\x99\x57\x9c\xf1\x9d\x67\xff\x8a\xfa\x87\x64\x41\x88\x10\x8c\xa2\x99\x31\xcb\x48\x71\x16\x04\x56\x3a\x63\x9c\xf7\x2a\xb7\x8c\x03\x12\xc7\xc8\x44\x3a\xfe\x45\x77\x83\x51\x3a\xfd\xd0\x38\x20\x09\xeb\x23\xb0\xcf\x78\x86\xbe\xb1\xb2\x1b\xc3\x3d\xe2\x20\x8f\x62\x2b\x75\x15\xd4\x35\xd4\xf7\xf0\x0a\x25\xb5\x52\xc1\x4f\x61\x21\x71\xfe\x10\x74\xa9\x14\xba\xda\xcd\xec\xe0\x38\xe0\x21\x86\xd3\x2a\x78\x5b\x94\xf0\x63\xf6\xbe\x34\xcf\x91\xe4\x78\x77\xb9\xd5\xf5\xdc\xb8\xbb\x1a\xd6\x88\xc3\x20\xb7\xce\xa2\xee\xb2\x68\x1a\x68\x67\x0f\x8c\x48\x8a\x46\xf2\x7f\x98\x78\xd9\xe8\x76\xe9\x5f\x36\x8a\xc2\x4c\x8e\xb8\xfc\x33\x2a\xd1\x3f\xb7\x04\xe3\x98\x0b\xd4\x89\xbd\xdb\x76\xd1\x3e\x19\x9b\x6a\x3a\x29\x11\x91\xa0\x5e\x3f\x34\x7c\xfd\x56\xd7\xdf\xa1\xf8\x4b\x00\x92\x38\x11\x90\xe5\x7e\x0d\x8d\x08\xdb\x14\x62\x8c\x55\x70\xd3\xd2\xd0\xba\xea\xd7\x0f\x77\xdb\xed\xdd\xd3\xe3\xfe\xf6\xe9\x79\xbf\x5d\xdc\xaf\xb7\xbb\xc5\xe7\xf5\xfd\x62\xeb\x55\xad\x38\x0d\xb3\xd8\x69\x33\x35\x6b\xe1\x4e\xe8\xf9\xad\x80\x64\x5e\x38\x5f\xb1\x17\xa7\x1b\x94\x42\x86\x8c\xb4\xc6\x8d\x81\x9d\x5e\xe9\xd2\xb3\xe4\xe9\x6d\xf3\x1c\x92\x78\xb4\x0a\x56\x3f\xb8\xea\xf4\x89\x59\x2a\xd1\x6f\xab\x74\x6d\xac\x2b\xff\xea\x8c\x5b\xfa\xbf\xd7\x07\x6b\x22\x7d\x78\x03\x1e\x51\x61\x98\xaf\x37\x35\xc7\x21\xb6\x98\x47\x11\x32\x6b\x8c\xe2\x6d\xd8\xc5\x58\x01\x4d\x3f\x98\x0a\x30\xcb\xb3\xbd\xfb\xfc\xb0\xd8\xaf\x7f\xdf\x3d\x2f\x56\x3b\xb3\xa0\xcb\xc5\x76\xdd\x4f\xca\x79\x94\x39\xfb\x7d\x51\x15\x27\xa7\x50\xf7\x9b\xc6\x79\x8a\x7e\x21\x54\x56\x9b\xb1\x15\x15\x0b\x43\x81\x68\xdb\x9b\xa7\x2f\x44\x5b\xbc\xc2\x12\x86\xe7\x8b\x30\x04\xeb\x66\x45\x25\xd1\x7c\x7e\x3f\x26\x69\x80\x2e\x66\xc9\x5a\x76\x27\xa1\x6a\x0b\x55\x0c\xfe\xe1\x18\xb2\x0c\x63\x0e\x07\x68\x31\x6a\x30\x3b\xde\xc4\xef\x04\xa8\x08\x84\x67\xc6\x0d\xd4\xaf\xde\x1d\x32\x0e\x90\xfc\x5c\x92\xc7\x2a\x22\x42\xf4\x0e\xb6\xff\x01\x9a\x90\x04\x24\x43\xff\x72\x03\xed\x6a\xf5\xc5\x86\xa5\xa2\x89\x60\x4c\x02\x22\x51\x4b\xe2\x9a\xd5\x72\x6a\xda\x8c\x95\xda\x24\x08\x09\xb5\xf1\xa9\xd3\xb9\x6b\xe1\x51\x4b\xb8\x93\xd7\x03\x2c\x49\x10\x65\x71\xe4\xdc\xf3\x9b\xcd\x48\xb6\x24\x81\x48\xd3\xac\x77\x6c\x3b\x87\xe7\x54\x1b\x4a\x48\x08\x14\x01\x25\x73\xb2\x1b\x5e\x8a\xcc\x7c\x77\x09\x11\x29\x7a\x63\x36\xec\xa2\xbb\xf6\xae\x32\x4b\xd5\x80\xbc\xce\x72\x13\x02\x1c\x4d\x87\x91\x66\x77\x0b\x60\x3d\x6c\x33\xb7\x63\x42\x45\x86\xd4\x2d\x58\xb5\x62\x65\x69\xcc\xba\x47\xfd\xd4\xbb\x20\x93\x30\x0a\xd0\x61\x7d\x0f\x8d\xd0\xc5\x07\x61\x97\x24\xcc\x43\x92\x63\xbc\xbf\x34\x87\xb7\x82\xfd\x92\x55\x2f\xf7\x85\x80\xaa\x81\x6d\x87\x38\x27\xd5\x95\xd3\xad\x89\x82\x1c\xe1\x5f\x2e\x2c\x75\x6d\xdf\x9d\x4f\x95\x24\x63\x1f\x50\x12\xc5\xa9\x55\xf9\x8f\xc5\xab\x37\x68\x92\x88\xdb\x20\xf6\x81\x9d\x60\x70\x95\x27\x91\x4c\x30\x30\xcd\xa4\xdc\x5b\xf1\xc2\xca\x0f\xc0\x19\xee\x8a\x38\x24\x18\x7b\x94\x5e\x25\x99\x07\x79\x92\x58\xa6\x28\x1f\xd1\x2d\x5b\xc2\x6d\xad\x4f\xd6\xee\x18\x88\x8c\x4c\x4c\xa6\x24\x49\xe3\x10\x06\xba\x80\xda\x1e\xb7\xd9\x7d\x53\x96\x2b\x8e\x0e\x13\xfd\x02\xf5\xdd\xe9\xfc\x91\x3e\x7e\x5d\x2b\x4b\x52\xce\xd0\x33\x79\xbb\xb3\xb8\x09\x64\xda\xa3\x50\x76\x92\x25\x69\x44\x46\xa4\xb7\xa9\xf5\x0f\x23\x0c\x67\xef\x91\x93\x1c\xa3\x17\xdb\xaf\x9b\xf5\xf3\xfe\xcb\xfa\xf9\x69\xff\xf0\xf5\x7e\x77\xb7\xb9\xbf\x5b\x3f\xfb\x7b\xe5\x21\xc5\x88\xf0\xdb\xb1\x68\xa1\x2c\x9a\x76\x51\x96\x4e\x51\xe8\xb5\xce\x24\x67\x24\x34\xe2\x6a\xd1\x1c\xa1\xfa\xa6\x0b\xcf\x7e\x13\x66\x2c\x37\xc4\xcc\xb1\x0a\xda\x95\xae\x65\x51\x31\xa3\xae\x4e\xbf\x88\x25\x80\xa1\xb2\x19\x6b\xf8\x5f\xff\xce\x6e\x2a\x22\xae\x10\xc6\x51\xc9\x47\xf8\xd1\x3e\xe8\x6a\x14\x88\x46\x42\xf3\x67\x95\x19\x2b\xd4\x68\xa1\xfa\x0c\x63\xd6\x9b\x70\xa2\x24\xe2\x21\x9d\x0d\x3c\x89\xe8\x26\x5c\x70\x8c\x27\xbc\xb9\x10\xa3\x67\x23\xd3\x65\x16\x24\x40\xf1\xd0\xd6\x46\x7d\xf8\xc0\x98\xf6\x73\x29\x43\xbf\xd0\xb9\x2e\x5e\x59\x8b\x76\xdd\xba\x92\x37\xac\x77\xcb\x27\x22\xb3\x11\x6f\xeb\x90\x43\xc7\x74\x3f\xa4\x00\x15\xd5\xbd\x84\x12\x0e\xac\x05\xd4\x65\xd0\x88\x59\x48\x09\xf2\x83\xf7\x93\x79\x02\x86\xcc\x8f\xac\xb1\x1e\x7e\x3c\xc6\x1f\x70\x00\x29\x19\x84\xbd\x56\xfd\xaa\x5b\x27\x27\xa7\x9f\x01\x21\x43\xf7\x0a\xfc\x28\xda\xa7\x57\xa8\x37\x25\xbb\xf4\x3a\x5e\xa2\x72\x22\x0d\xb5\x3c\x17\xcd\xcb\x70\x35\xa1\x8e\x29\xbe\xff\xeb\xaf\xe3\xd6\xa9\x62\x9f\xbd\x85\xb2\xfc\x0c\x15\x34\x93\x17\x98\xae\x67\x1a\x84\x12\xa5\xae\x21\xac\x7a\x05\xa5\x64\x7f\x8a\x77\xb9\xe2\x0a\x49\x03\x11\x22\x2e\x12\x0f\xd2\xf4\x14\xa5\x81\x88\x11\x38\x58\x38\x6e\xfd\x0e\x02\x94\x92\xcc\x82\x85\x6e\x17\x4f\xde\xd4\x4b\x69\x42\x06\x2c\x12\xc8\xa5\xe1\x28\xb3\x53\x91\xd2\x4c\xa5\xe6\x54\x18\x0d\xb6\xa8\x0e\xce\x8c\xf6\x83\x32\xc5\xc0\xa1\x7b\x19\xbb\xc1\xd3\x37\x0b\x29\x21\xa1\xf7\x60\x97\x12\xea\xbb\xca\x68\x66\x6c\xec\x02\xf0\x53\x73\x45\xd9\xb0\xb4\x2d\xab\xdb\x9b\x11\xd4\xd9\xcf\x12\x29\x32\x1e\x07\xf3\x1b\x21\x0f\xd3\x28\x4a\x11\xdc\x60\x38\xc4\x43\x57\xb6\xc5\xb9\x84\xbb\x16\x4e\xcd\xa7\xa9\xd1\x32\xe6\x6a\x13\x79\x99\xc6\x2c\x24\xa9\xf5\xf8\xb7\x1f\x04\x41\xd2\x84\xa4\x21\x19\x62\x74\x1e\xd8\xf1\x97\x60\x6f\x69\x1a\x85\x89\x45\xe8\x9c\x4b\xed\xa4\xb5\x1b\xca\x53\x85\xe1\xfc\x23\x6b\xf6\xd6\x13\x3c\x5f\xcb\x1c\x14\x06\x69\xbc\xd6\xee\xa1\x5b\x29\x63\x41\x8e\xba\x09\xab\xf6\x3d\x8f\x9c\x5d\xcc\x18\xc3\xf8\x5e\x83\xdc\x18\xfd\x3c\x57\x4e\x4d\xca\x29\x43\x5d\xd5\x58\xc1\xc8\x85\xd6\xcf\x2b\x1a\xf8\x07\x71\x69\xdd\xdb\x07\x04\xdd\x94\x3b\xa8\x4f\x9e\xff\xa6\x82\x58\x68\xc9\x5d\xaf\x6f\xa6\x82\x87\x28\x64\x2c\x8e\xe5\xa9\x66\xa2\x2c\xfe\x80\xcf\xac\xb9\xf6\x64\x21\x28\x42\x89\x9e\xd7\xdb\xf5\xf3\xb7\xf5\x8d\x95\x2b\x5b\xb4\x08\x36\xf7\x8b\xdd\xed\xd3\xf3\xc3\xfe\x69\xb3\x7e\x5e\x8c\xd1\x95\xa9\xcc\x02\xf4\x86\x15\x4d\xd3\xc1\xa2\x92\x46\x51\xfa\xe3\x4f\xec\x9f\x14\x62\x89\x21\x07\xfb\x62\x73\xcf\x59\x0a\x79\x18\xc7\xd6\xad\xbb\x28\xcb\xd5\xd1\xd8\x05\xd5\x01\x9a\xe5\x65\xf1\xb5\x99\x8b\xd2\x2c\x08\x02\xe9\xe0\x46\xaa\x38\x8c\x11\xab\x3f\x27\x86\x2c\x48\x12\x74\xba\x49\xad\x5a\xe7\x15\x72\x6f\x90\x11\x99\x40\xdc\xbf\xe0\xe7\x9a\xbd\xb2\x96\xd5\x77\x27\x76\x98\x3a\x63\x32\x1a\x10\x74\x4d\xe1\x5e\x6d\x75\xf9\x4e\x4f\x7b\x47\xf1\xd7\x88\x3a\xa3\x84\x67\x04\x55\xd7\xaa\x6b\x56\xac\x14\x5d\x79\x25\x6c\x9e\x51\x22\x91\xf3\x9e\x59\x0d\xd5\x2c\xf8\x90\x51\x1a\x23\xc6\xce\x70\xfe\x16\x1e\x98\xa1\xb3\x4a\x4b\x98\xdf\x23\x0e\xf0\xd3\x94\xae\xdb\xae\x82\x7d\x05\xde\xb9\x97\x85\x29\x47\xc3\xdb\x65\x69\xac\xdb\xe3\x6c\xa9\xa3\x5c\x8d\xb8\xaf\x31\x32\x56\xba\x2c\x41\xbc\xe7\x26\x59\x24\x39\xa2\xd9\x31\xe8\xf7\xa4\xd0\xc0\xbf\x81\xb2\xf5\x4a\x5c\x16\x29\x88\x2d\x60\x04\x6a\x51\x7c\x24\x0d\xb3\x98\x84\x78\x20\x5a\x6f\x02\x6f\x0b\x63\x64\x7b\x38\x5f\x16\xc7\x29\x0a\x92\x65\x77\xf1\x88\x16\x63\x35\xd8\xff\x4c\x5f\x29\x16\x36\x12\x61\x2c\xd4\x1a\xee\x56\x4f\x5e\xac\x4e\x9f\x98\x50\x11\x0a\x4c\xa4\x70\xfe\xd4\xaf\x16\xe9\xdc\x13\x47\x12\xab\xdc\x01\x6a\x1a\xf8\x7b\xa3\x2b\x04\xf4\x2c\x2a\xf9\x19\x5a\x8c\x7b\xaf\x4b\x0c\x11\x2d\x9a\xc7\xee\xc4\x67\x69\x27\x59\x92\x27\xb9\xb2\x0c\xb4\x61\xa5\x7e\xc3\x03\x53\x54\x87\xd9\xfa\x25\x9c\xa3\xd6\xd4\x02\x3b\xf9\x17\x58\x28\xc3\x3a\xca\x42\xa9\xfe\x55\x04\xa0\x69\x77\xaf\x0f\x16\x17\x29\x3d\x0a\xf5\x86\xd9\xf5\xc8\x66\xeb\x99\x86\x21\x2a\x7c\xc6\xf8\x61\x75\xd1\xe8\x4a\x1c\x67\x6f\x98\x86\x22\x37\x53\x56\xf7\x1b\xcf\x5e\xc7\x0a\x51\x96\xd1\x00\xc7\x87\x3d\x75\x90\x94\xd9\x42\x66\x49\x8e\x8e\xca\x7b\x7d\x58\x19\x11\xf7\x0c\x6f\x46\x67\xbe\xaa\xa9\x65\x99\x12\xd6\xc3\x66\xe4\xce\xfe\xa0\xf7\xff\xed\x8a\x3f\xae\x25\x32\x64\x99\x02\xe9\x02\x4a\x16\x42\x7a\x55\x4b\xc9\x58\x28\x98\x55\x80\x5f\xa1\x6e\x60\x7b\x2e\xdd\x0b\x3a\x43\x63\x6c\x19\x7a\x01\x94\xb1\x58\xd0\xc1\x7d\xbd\x66\x75\x79\xb9\xab\x84\x3e\x61\x1a\x04\xde\x1d\x03\x4a\x1f\x7c\x03\x4b\x03\xf4\xdd\x6e\x6a\xb4\xed\xfb\x5f\xad\xc7\x0b\xc5\xbc\x77\x7e\x5a\x07\xf6\xec\x72\x19\x62\xd8\xca\x9e\xae\x7b\x2d\x5e\x56\xba\x31\x7b\xf9\x45\x77\xb3\x90\x49\xc6\xa5\x24\x56\x05\x34\x66\x9c\xf5\x56\x18\x59\x3c\xf6\xfd\x67\x1c\x64\xe8\x2c\xfb\xc5\xa1\x06\x24\xca\xb1\xf2\x9a\x09\xc2\x31\xdd\x62\xf3\xb4\xdd\xa1\x01\xb1\xdd\x2d\x9e\x77\xfd\x68\x48\x89\x53\x2f\x9e\xe1\x5c\x16\xf0\x4e\x21\xfc\xf7\xff\x5d\x8b\xe3\x66\x22\xcb\x11\x34\x24\x6c\x04\x60\x77\x39\x43\x7f\x4f\x96\x21\x84\xa1\x68\xd0\xbf\xc2\xba\x66\x38\x57\x82\x0b\x44\xcd\x68\x27\xa8\xf6\xff\xed\xa0\xbe\xcc\x1d\xb6\xb8\x79\xff\x8e\x1c\xec\x32\x93\x2a\x42\x03\x1d\x53\x44\x66\x8b\x04\x81\x22\x7c\x40\x91\xce\x47\x93\x0c\x3d\x4b\xbc\xbb\x58\xc4\xcd\x3b\xd6\x3d\x25\x28\xc8\x48\x18\x7b\xf6\xa1\xcd\x36\xd6\xcf\xac\x85\x2f\x45\xd3\xea\xfa\x5d\x2a\x93\xb7\x69\x7b\x0f\x46\xa6\x8c\x88\x75\xd9\x3a\xd0\x60\xa8\xc2\x2a\x20\x83\xae\xfb\x57\xc2\x23\x49\x34\x36\x90\x33\x95\x71\x7c\x2b\xb7\xd6\x48\x9e\x08\x14\xf6\xe3\x42\xe4\x91\x3d\x57\x07\x18\x33\x3c\xa7\xd7\xe6\x41\x28\x50\xa1\xfb\x0d\x46\x3e\xd8\x3c\x80\x1c\x5f\xd6\x43\x49\x96\x46\x30\xc1\xcc\x2f\x9c\x93\x4c\xa4\x88\x61\x16\xda\xc2\x79\x46\xea\x60\x4e\x64\x86\x09\x47\x0f\x45\xc5\x7e\x14\x5e\x4c\xe5\x94\x4a\x07\x2c\x11\xba\x92\xdf\x01\x5e\xf0\xde\x77\x95\xf9\x67\x3f\x29\x54\x08\x60\x42\xae\xef\xf0\x0f\x93\xdd\xcb\xc3\x34\x40\x2e\xcd\x59\xf5\x82\x11\x9f\xfa\x74\xfd\x54\xe6\x11\x89\x89\x8b\xa8\x38\xcb\x0b\x75\x8d\xe9\xa4\x38\x25\x78\x74\x45\xad\xdf\x2a\x07\x3d\x9f\x3b\x03\xf2\x84\x84\x48\xd7\x96\x12\x77\x7a\x94\x7d\x94\xa7\x24\x0c\xc0\x82\x36\x58\xe9\x6f\x50\x8d\xfd\xda\x79\x4a\x58\x68\x93\xfa\xba\x7a\xb8\x2e\xe6\xcc\x2c\xc7\x1e\x81\x36\xe1\xcd\x07\x1f\x91\xf2\x24\xe8\x83\x89\xcf\xac\x86\xbb\x99\x85\x91\x67\x61\xe4\x1d\x64\x36\x48\x33\x03\xe6\x5f\xbf\x6f\x96\xd2\x24\x1e\xb2\xbd\x76\xc7\x5a\x77\x87\xe3\xa2\x2c\x6f\x75\xfd\xd2\xef\x59\x66\xec\x10\x7b\x54\x7e\x37\xf7\xb9\xd5\x75\xaf\x78\x7f\x70\xdf\x2c\xb3\x58\x4e\x56\x0a\x63\x78\x6f\xea\xe2\x8f\x9e\x32\xb2\x8c\x21\x13\x58\xb7\xc7\x87\x62\x88\x44\x15\xba\x72\x42\xec\xba\x2e\x90\x67\x0a\x28\xef\x33\x3c\xbe\x1b\x4d\xfb\xaf\xa9\x7a\xb9\x21\x46\xb0\x8b\xf3\xc0\x5e\xde\x07\x8d\xf3\x5c\x86\x99\x85\x83\xa2\x55\x53\x33\xd9\xbf\x2d\x23\x8a\xb9\x10\xff\xb6\x3b\x3d\xa9\xcf\xec\xc4\xcb\xa2\x3a\x6c\x58\xdd\x16\xd0\x20\xf5\x6e\xb4\x9e\x81\x23\x72\xa6\x32\x8f\x1d\xaa\xe0\x87\x3b\x98\xf3\x4d\xe3\x61\x86\xb1\x6a\xc1\xaa\x25\xdc\x16\x15\x33\x7c\x4f\x3e\x0e\x59\x7f\x7e\x5e\x1e\x26\xce\x9d\xff\x4d\xb7\xe0\xf4\x8a\xe9\x1c\xc1\x62\xf4\x31\x9c\xd8\x0f\x14\xd7\xdf\x0b\x17\x7d\x71\xe3\x40\x29\x8a\xed\xad\x83\x2a\xac\x76\xb3\x1b\xa8\x9c\xe2\x81\x6d\xa0\x5d\xb7\xc7\x2b\x36\x02\x0b\x48\x8e\x44\xbe\xbc\xbb\xb9\xb9\x7b\xfc\xbc\xbf\xf9\x6a\xad\x81\x4f\x7e\x3c\x26\x88\xaa\xbb\x2d\x56\xba\xa8\x8c\x7e\xe8\x35\x03\x3f\x21\xb7\xf9\x4d\x12\x5e\xad\x6e\x35\x56\x2c\x58\x20\x1d\x99\xb1\x56\x1c\xd7\x98\xa5\x00\xf3\xa4\x43\x46\xc2\x1c\xe9\x9c\x77\x75\xf5\x0c\x27\x56\xf4\x70\x19\x46\x12\xc1\xb8\x8f\x3f\xad\xba\x56\x2b\xd5\x2c\xcd\xbd\x46\xf0\x7d\xeb\xf3\x09\xc6\x91\x34\x7f\x75\xc6\x43\x07\x30\x36\xd2\x62\x16\x09\xfb\x33\xc7\x93\xbb\x09\x25\xb9\x8a\x50\x37\xbc\xdc\xea\xfa\x06\x4e\x5a\xd4\x4c\xcc\xfc\xc2\x8c\x52\x00\x33\x6b\xfd\xfb\xd3\x55\x84\xfb\x9f\x3c\x24\xa4\x24\x71\xc8\x21\x73\xb6\xdc\x1a\x63\xd4\xc0\x6a\x44\xfd\x3c\x86\x2e\xb5\xc5\xdd\xf3\xcd\xf3\xd3\x66\xff\x7d\x71\x7f\xbf\xde\xf5\xa3\x31\x63\xb4\xb7\x17\x96\x5a\x97\x2e\x58\x37\x79\xd5\x28\x0d\x30\x11\x4a\xea\xbb\xea\xf5\x27\x07\xce\x4f\xe7\x24\x32\x8f\xdc\xde\xac\x26\x5b\x1b\x87\x71\x9e\x8d\x41\x45\x3b\x7d\x38\xf4\x16\x1f\x8b\x33\x86\xbe\x87\x95\x56\x0a\x86\x5f\x21\x45\x05\x64\x57\x17\x67\x43\x50\x66\x5b\xb6\xdd\xf9\x5c\xfa\xd0\x33\x4b\x68\xe2\xf1\xf5\x8b\xd5\xfd\xb3\x2e\x21\x25\x34\xcc\x83\x9c\x1a\x32\x49\xe3\x8c\x04\x39\xed\x27\xa7\x89\x72\x87\xc8\x89\x94\xe9\xa7\x26\x12\x84\x43\xbb\x6e\xd8\x05\xea\xcd\x75\xf4\xac\x9b\x9d\x06\x80\x86\xc9\xd9\x9c\x93\x27\xe5\x54\x08\x3f\x28\x13\xde\x47\x42\x7d\x90\xfe\xb6\xd6\xa7\x9d\xbe\x5b\x2d\x36\x73\x80\xde\xfc\xd6\x4a\x2a\x94\x6d\x85\x6c\xf6\x62\xa4\xb0\xb1\x8c\x58\x27\x29\x9c\x8a\xd6\x7c\xed\x33\x3a\x99\xe5\x35\xf4\x3a\xcb\x40\x21\xfe\xa4\xe9\xb8\x4f\x24\x9b\x3e\x26\x53\x14\x7d\x4b\x25\x6b\xda\x1e\x33\xba\x6f\xda\xc1\xd3\xc8\xf2\x88\x63\xb2\xd3\xcf\x55\x32\xfb\xe7\xdf\xf1\x2c\x6a\xce\x18\x25\x18\x5d\x6c\x47\x0b\x80\xee\xc5\xb9\x17\xf2\xba\x70\x62\x8c\xc6\x98\xb9\xb0\xff\x19\x94\x87\x31\x91\xa3\x13\xff\x73\x5d\x80\x1a\xa5\x8a\xbb\x61\x11\x25\x49\x38\xc0\x75\x58\xd5\x5e\xfe\xd1\xe9\xd6\xdb\xf1\x7f\x0d\x82\xc2\x44\x9a\x22\xce\x54\xbf\x55\x50\x6f\xa1\x5d\xb1\x6a\xd9\xd5\xd5\x28\xb2\xcd\x64\xc8\xd0\x76\x78\x5e\xdf\xaf\x17\xdb\xf5\x7e\xb3\x7e\xbe\x7b\xba\xf1\x8e\x12\x26\x33\x5b\xe7\xa0\x62\xf3\x14\x4a\x33\x84\x3a\xdc\xf6\xad\xa8\x0e\x0e\xfb\xbc\xdd\x0c\x60\x5c\x26\xb3\x04\x71\xef\xcf\xeb\xc5\x4d\x9f\x24\xc5\x64\xc6\x51\x28\xd4\x50\x02\x6b\xe0\x9b\x73\x11\x0e\x98\x7b\x3f\x4f\x84\xb6\x32\x80\xfd\xd2\x2f\xac\x99\xd9\xf5\x0c\x58\x9c\x5b\xc1\xfa\x5a\xc0\xdb\xa2\x93\x73\x5b\x8e\x81\x08\xd0\x88\x59\xae\xd7\xab\xc5\xf6\xcb\x72\xb1\xfa\xed\xcb\xd3\xf0\x2a\x00\x2a\xb3\x7c\x7d\x62\x08\x7e\xb0\x98\x2a\xa2\x69\x34\x8b\x6c\x4f\x70\x61\x13\x3a\x56\x79\x86\x19\x24\x0e\x55\x20\xe1\x74\xc6\x30\x57\x57\xaa\xa2\x2c\x07\x97\xb6\x9f\x2e\x69\xee\x02\xc6\x8b\xb2\x5c\x41\x59\x1a\x75\xd8\x90\xde\x7e\xf7\xae\x86\x42\x7f\x8d\xc0\x14\x8a\xf5\x7d\x51\x79\x1d\x94\x07\x59\x8c\x61\xc2\xcf\xbf\xaf\xbe\xf8\xdf\x48\x4a\xa5\x4b\x9b\xed\xdf\x7c\x53\xeb\xb3\x6e\x06\x70\xe4\x94\x59\x73\x1a\xa6\x91\xa1\x9c\x6f\x50\x37\x5d\xb3\xa8\xa1\x62\x63\xce\xc8\x69\x4c\x10\xde\xf8\x0a\xad\x7e\xd0\xef\x9d\x3e\x3c\x8c\xd2\xc8\x5a\xec\x56\xe3\xb2\x89\xdd\xa8\x28\xf8\x7b\x84\x69\x10\x45\x7d\x9e\xb9\x73\x5e\xfa\x31\x91\x60\xbc\xce\xe8\x0d\xdb\xd7\x73\x10\x90\x9f\x3b\xe7\x78\x14\xa5\x98\xc5\xc8\x84\x80\x73\xfb\x00\x46\xd5\x18\x23\x22\x7f\x9d\xb8\x15\xae\x1f\x5d\x1e\x93\x18\x55\xb5\x6f\x05\x87\xdf\x57\xf3\x34\x76\x1e\xd3\x04\x05\x20\x6a\xbd\x76\x25\x1f\x58\xd5\xb1\xb2\xbc\xfc\xc9\xdb\xc5\x34\x4d\x59\x0f\x2b\x87\x72\xa6\x76\xf1\x38\x8e\xd1\x1e\xec\x05\xcd\x4d\xad\xcf\xeb\x3e\x59\x8a\xc7\x09\x63\xa9\xe3\xa0\xdb\x4b\xd5\x1e\x3d\x0b\xb5\x90\x99\xd9\xe6\xc5\x79\x86\x7a\xa3\x45\xe5\x77\xb5\x39\xbc\x23\x89\x30\x9c\x7e\x1e\x73\x8a\xa7\xdf\x05\x95\x9f\xa1\x39\xeb\x6a\xe6\xd5\xf2\xa1\x74\x9e\x64\x11\xfa\x80\x58\x51\xdf\x8c\x72\x75\xbd\x2a\xc2\x13\x9e\xa2\xb6\x6f\xb7\xe0\xe7\x00\x2d\x9e\x26\x21\x4e\x76\x69\x15\x75\xf1\x5a\x94\x70\x80\x49\x42\xd4\xf8\x4d\xd3\xc4\xe2\x23\xd7\xaf\xd6\x87\x88\xb8\x9f\xeb\x4e\x14\x9e\xe6\x12\x01\x58\x2d\xfb\x51\xbe\x96\x6b\xa1\x2b\x7d\xba\x7c\xba\x0a\x9d\xba\xe2\x08\xe0\xa9\xa2\x81\x85\x62\xde\x00\x1f\x52\xa3\x78\xc6\x52\x34\xde\xee\xaa\x16\x8c\xdd\x51\xbc\x82\x05\x7f\x4c\x88\x24\x27\x59\x2e\x07\x7f\x9d\xd0\x73\x9b\xc3\xcf\xcb\x22\x7c\xca\xcd\xf2\xe6\xcb\xf4\x06\xb9\x42\x87\x82\x61\x6a\x34\xeb\x7f\x05\x8e\xf2\xc2\x68\x14\xd6\xd5\xf2\xce\x85\x34\x5b\x61\x16\xe4\xd4\x02\xe0\xf7\xce\xcc\xf6\xf7\x62\x21\xc4\x41\xef\x13\x90\x9d\x68\x17\xad\x83\xd5\x35\x1f\xa4\xff\x4e\x57\x88\x49\xe1\x53\xcc\xc4\xab\x6e\xa1\x29\xe4\xa7\xe9\x04\x60\xa8\x03\x9d\x59\xd3\x3e\x55\x70\xd3\x67\x0e\x72\x0e\x02\xc1\x6d\x67\x76\xd9\x42\xfd\x5a\x08\xf0\x6e\x09\x3f\x43\x64\x21\x33\xbb\xf7\xe3\xcf\x60\xbf\x33\x27\x21\x17\x2c\xc5\xb7\x42\x5d\x60\xaf\x67\x76\x30\x17\xdc\x66\x6f\x79\xce\x67\x03\x4f\x73\x2a\xbd\x16\x71\xe7\x32\x8c\xb1\xc2\x84\x27\xbe\x9d\xb6\xe1\xf4\xc9\xa9\xf7\xf9\x17\x5c\x26\x2a\x12\x93\xac\xa0\xb9\x56\xde\x8d\x43\xb9\x63\x2a\x97\x10\x84\x2e\x70\x7f\xd3\xd9\xfa\x21\x5e\x14\x73\xa9\x38\x66\xb8\x16\x55\xd3\x32\x14\x21\x76\x40\x04\x34\xc4\x02\x32\x35\xbc\xea\x17\xe8\xb7\xf2\x9d\xba\x36\x72\xc0\x08\x92\x5a\x5d\xbe\x81\x76\x8a\x3c\xfd\xf5\xaa\x96\x74\x9d\xad\x09\x02\x36\xdf\xdb\x3d\xc9\x98\x4e\x2e\xb3\xdd\x4d\xa0\x79\x84\x47\x46\x82\x28\x59\x0d\xdf\x8b\xaa\x9a\x5b\x80\x82\x72\x0b\x1d\x31\x84\x74\xab\x3f\x40\x51\x8b\x30\xb4\x01\xb4\x73\x0d\x67\x56\xcc\xa2\x29\x22\xa2\x24\xb5\x05\x17\xcc\x03\x6e\xa0\x85\xfa\x54\x54\x30\x8e\x3f\x8b\x28\x8c\x9d\x4f\xbe\x65\xa5\xc5\xf9\x35\xfd\x98\x00\x65\x6b\x1d\xfc\x06\x17\x6b\x50\x5c\xa1\x7b\x11\x27\x49\xea\x9c\x69\x8f\x70\x40\x0e\xf0\xb9\xd6\x6f\xed\xf1\xd3\xe4\x5d\x63\x65\x03\x5e\x67\xf4\xd7\x4f\x74\x7f\x91\x52\xc2\x9c\x5f\xe7\x0b\xab\x66\x96\xb5\xc8\x28\xc5\xd8\xd7\x4c\x73\x9d\x38\x11\xe9\x4c\x61\x15\x19\xe7\x91\xf3\x78\x3e\x40\x09\xb0\xc1\x8a\x1a\x9d\x05\x5a\xba\x39\x79\xc0\x44\x86\xe5\x44\x5a\x6d\x58\x88\x51\xd3\xfe\x24\xe6\xe3\xaf\xcc\x32\xc8\x9c\x8f\x09\x93\x85\x57\x2e\x59\xae\xa7\xbf\x3c\xa7\x81\xb3\x40\x06\xa0\xd6\x54\xbf\x11\xb9\xc8\x30\xe2\xb4\x37\x12\xec\x16\x60\x0b\xef\x04\x84\x9b\xc9\x78\x86\xb8\x5a\x23\xbc\xdc\xb9\xb1\x1b\x72\x95\xcb\x09\x06\x31\x42\x2a\x1b\x3d\x2e\xf8\x34\x7d\x38\x27\x0c\x89\xfd\x04\xed\x51\xcb\xdd\x91\xb5\xbb\x63\xad\xdf\x9a\x91\x1e\x2c\x78\x44\xc0\x2b\xdc\x3e\x73\x84\x97\x70\xc3\x06\x88\xb2\x30\x62\x5c\xb9\xd4\xae\xea\x70\x5b\xf4\x79\xcf\x42\x90\x18\x83\xac\x25\xa6\x38\xaf\x2b\xf1\x2e\x82\x25\x44\x94\xa1\xcb\xcc\x06\xe7\x10\x56\xbf\xb9\x16\x29\x10\x82\x0b\x44\x3b\x63\x5e\xf8\xa0\x39\x3a\x20\x72\xff\x44\x25\x19\xef\x01\x3b\xb7\xba\x3e\x14\xaf\x20\x57\x47\x56\x7f\xba\xc6\xb2\x85\xe4\xb6\xa8\x8f\x95\x1d\xa8\x4d\x4f\x17\x49\x82\x85\xcb\x38\xbd\x7c\x61\x0b\xa5\x5d\x97\xb0\x02\x68\x10\xdb\xc4\xc7\xe2\x70\x80\xda\xe1\x0a\xfd\xbb\x41\x14\x25\x74\x84\xe2\xd9\xbf\x15\xed\x71\x8f\x51\x3d\x3f\x23\x03\xef\xe3\xff\xda\x0c\xa8\x3e\x01\xb9\xf2\xf9\xe3\x1b\x38\x1c\x1c\x56\x6f\xba\xff\x57\xdf\x48\x12\x42\xf1\x10\x3c\xb0\xb2\xd4\xf5\x0c\xea\x20\x49\x9a\xba\x28\xa3\x32\x96\xdc\x95\x22\x07\x92\x8a\x10\x91\x1f\x07\x73\x30\x9b\xe3\xb6\x38\x54\xac\xed\xea\x39\xe2\x47\x86\x01\xf0\xdc\x6f\xcf\x77\x80\x17\x1b\x95\x43\x87\xda\xf3\xc0\x6e\x64\x48\x59\x1a\x7b\x8c\x9b\x82\xfa\xe6\xf6\xf1\xe7\x02\x5b\x86\x71\x8a\x90\x9d\x55\xd7\xb4\xfa\x24\x74\x31\x24\xe8\xcf\x3e\x27\x54\x31\x61\xa8\xa7\xd6\x6d\x67\x98\x19\x2b\x8b\xf6\x82\x0a\xab\x7f\x7c\xc4\x53\xa4\x22\x27\xfa\x1f\x0a\x69\xe3\x82\x23\x5f\xb7\x8c\x78\x1e\xe7\xd6\x11\x4e\x90\x2b\xfa\x81\x98\x86\x08\xf0\x2e\x75\x63\xb3\xee\xfd\xef\x89\x44\xd8\xd0\xb6\x65\x07\xd8\xbd\xe9\x75\x35\x0a\x80\xcb\x58\xb2\xc0\x79\xe2\xf0\x51\x37\xd0\x88\xba\x40\xe2\x9d\x68\x07\x32\xe5\x56\xc2\xaf\x7f\xe8\xc6\xbb\xfc\x65\x0a\x39\x16\xcf\x28\x59\x25\xd1\x8b\xb7\x71\x85\x01\xfa\x09\x2a\x96\x58\x65\xab\x3b\xb1\x8a\x6c\x5b\x56\x49\x56\x5b\x02\x99\x9b\xf6\xdd\xbb\x34\x6f\x99\x05\xe0\xd3\x2d\x3e\x77\xac\x96\x05\xab\xde\x97\x89\x92\x59\xa4\xe4\x00\x8f\x9c\xe0\x5c\x65\x9e\xe4\x91\x43\x92\xda\xcd\xb6\x95\x9f\xa6\x37\xc8\x15\x8d\xa0\xaf\xf7\xf2\xd8\x9d\x2c\x80\x68\x4e\x44\x3c\x0f\xa4\xc7\x85\xb2\xca\x33\x9c\x25\x28\x5d\xc3\xba\x92\x23\xc6\x24\x39\xcb\xd0\x02\x37\xf2\xac\x2f\x2e\xb1\x6d\x75\xcd\x0e\x30\x2b\x10\x62\xe6\x22\x16\x12\x41\x10\x4f\x9b\x6d\x8f\x80\xf8\xfb\xd3\xdd\xe3\xce\x42\x23\xfa\xb9\xc0\x43\x97\x10\xb4\xa9\xf5\x49\xaf\xb4\x84\xde\xa2\x75\xa0\x46\x37\x15\x08\xf0\x08\xad\x04\x65\xbe\x19\xea\xc6\xca\x34\xeb\xc8\x2c\x2a\x1f\xd6\x96\x90\x85\x58\x5d\x63\x0b\xad\x0d\xe9\x5d\x95\xe5\x12\x20\xc2\xf4\xb3\xa2\x2a\x5a\x57\x80\xc9\xdf\x41\x45\x24\x1e\xa5\x06\xfd\xeb\x87\x58\xb1\x73\x3f\xc8\x14\xe6\xaa\x1a\x41\xc7\xea\x17\xf8\x53\xfc\xee\xec\xb9\x4a\x52\xc2\x06\xae\x73\xa3\xc5\x9d\xbc\x9a\xa0\x2a\x95\x0a\x91\x5f\xdc\x16\x5c\x57\x7f\x14\xfd\x0b\xa8\x04\x75\xf6\x33\xab\xdb\x0a\xea\xd1\xc9\x9f\x1e\x50\x08\x92\x10\xd1\x70\x4e\x80\xfd\x03\xa5\xf8\x6c\x8a\x88\x71\x11\x8e\x43\xe6\x08\x10\x92\x13\x97\x39\xb2\x2a\xd9\x69\xc7\x7e\x8c\x83\x5e\x40\xf2\x0c\x8d\xee\x43\xcd\xaa\xf6\x1b\x34\x43\x6a\xf7\x07\x21\xb7\xee\x7d\x7d\x47\xa0\x79\xe4\x12\xfc\x4a\xe5\x81\xe5\x37\x77\x8f\x86\x06\x9f\x01\xa5\xe8\x4c\xb9\x82\x90\x24\x08\xf0\x3e\x69\x59\xa8\xcb\xe7\xce\x68\xb2\xdd\x50\x78\x63\xfe\x80\x30\x4d\x30\xf3\x0f\xfd\xe1\xcf\x18\xf4\xf8\xe3\xb6\xf8\x31\xf8\xfb\xe6\x79\x2a\x10\x66\x11\x09\xfa\x38\x41\x51\x1d\x1e\xa0\x65\x92\xb5\x6c\x7a\x6a\x20\x0a\x01\xdc\xf2\x3c\x60\xe4\xc7\xa8\xc7\x58\x08\xe7\xba\x2e\x01\x51\x62\x71\xb0\x78\x01\xa6\x63\x6f\x58\xd3\x5c\xcf\x67\x84\x28\x4d\x32\x1f\x71\xc3\x28\xc2\x55\x2e\x0d\x51\x9a\xa2\x88\x62\x52\x5a\xbc\xa1\xae\x2f\x77\xf2\x81\x9d\xcf\x23\x38\xc4\x74\x45\x22\x25\x70\x01\x3d\x04\xeb\x11\x5a\xf5\x0c\xaf\x50\x75\x33\xfe\x03\x31\xb5\x7e\x6b\x54\x93\xb6\x2f\x45\x59\xae\x5f\x59\xd9\x8d\x61\x5d\xbf\x5e\x77\x68\x5c\xa5\x78\x88\x95\x40\x20\x72\xcd\xde\x6c\xb2\xd5\x74\x7d\x12\x12\x28\x6b\x8c\x35\xcd\x9b\xae\xa5\x39\x8c\xd7\x8d\x14\x7f\x32\x20\xa1\x09\x46\x13\xff\xd0\x37\xac\x28\x2f\xe3\xc8\x3d\x24\x91\x4a\x6c\x96\xcc\xa1\x2b\x59\x8d\x2e\x9d\x62\x28\x1e\x08\x09\xe3\x98\x86\xb7\x3e\x1c\x6e\x99\x68\xdf\x89\x69\x48\x78\x8e\x10\x69\xb3\xff\xe5\xd8\x28\x86\x34\x4e\x10\x82\x5f\xeb\x12\xdc\xa1\x5a\x94\x05\x6b\x7a\xb3\x11\x52\x49\xb3\x7c\xa4\x74\xdc\x9b\xff\x56\xef\x20\x2a\x90\xc5\x24\x61\xd6\x19\xb6\x75\x45\x5f\xae\x13\x4f\x16\x53\xac\x23\x83\xce\xd3\xfb\xa1\x1a\x1b\x64\x79\x68\xa3\x84\x5e\x3a\xe3\x9b\x22\xcd\xdc\x40\xa5\x4f\x45\x35\x2a\xa8\x02\x79\x9a\x21\x9a\xde\x55\xb5\x78\x66\x2f\xd0\x0f\x89\x00\x15\x67\x1b\xcb\x18\xa7\x39\x4e\x77\x91\x11\x82\x39\x0c\x82\x95\x62\xc5\x5e\x1c\x9c\x72\x36\x27\xb4\x21\x8c\xb3\x6e\xda\xcf\x5a\xcb\x39\xb4\xd0\x4f\xcb\x08\xd6\xa3\x39\x5d\xdb\xe9\x8f\xb2\xca\xfa\x7f\xf5\x37\xb1\xb5\x28\x4f\x0e\x82\xd0\x6f\x30\x93\x29\xa2\xf1\x66\xc8\x84\xa9\x21\xea\xe7\x82\x14\x56\xd4\xb6\x75\x01\xaf\xf0\x8d\x55\x45\x7b\xb9\xd5\xf5\xb5\x1c\x47\xe0\x31\x55\x4e\xb7\xb8\x6b\x30\x91\x04\xcf\xc4\x20\x27\x81\x8b\x3c\x71\xc1\xd2\x5e\x6d\x5a\x57\xf2\x7d\xed\x3f\x90\x01\x89\xdd\x41\x5f\xef\xbe\x7c\x70\xcc\x25\x8d\x73\xea\x2a\x49\xa0\xd9\x7f\x9d\xc9\xf6\x17\xa8\x20\xa6\x3e\xa8\xb3\x2c\xe4\xf2\xe2\xca\x28\x7c\x00\x8c\x77\x17\x11\x4a\x50\x03\xdb\x9e\x41\xb4\x75\x77\x7a\x84\xf6\x4d\xd7\x2f\xee\xcf\x27\x3f\x2b\x4d\xd1\x3b\xe8\x8a\x17\x2f\xda\x89\xb9\xa9\x88\x48\x7d\x8a\xcb\xe0\x46\xbf\x05\xb8\x4e\x02\x8a\xe6\x12\x71\x8a\x45\x83\x59\x49\xf3\xd4\x6c\x7f\xd2\x15\x15\x11\xe1\x8e\xea\xba\x92\xb5\xb0\x73\x29\x44\xba\x6b\x2d\x09\x2e\x2a\xb9\xd2\xa7\x53\xd1\x34\x83\xdf\x5e\x85\x04\x52\x8b\x95\xd9\xd4\xd0\x18\xab\x60\x7a\xdb\x30\x0b\x94\x55\x26\x4e\xa7\x0e\xb7\x7c\x48\x7a\x52\x21\xa4\x16\x4a\x5b\x0f\x9a\xb4\x8a\x82\x2c\x74\xe5\x11\x76\xfa\xad\x12\x75\x01\xf5\x8a\x95\x25\x67\x2e\x31\x72\x90\x74\xd3\x47\x45\xa1\xe5\x47\xdb\xc2\x9c\xf3\x3d\xc2\xb9\xb0\x66\xee\x0e\x4e\x67\x5d\x63\x91\x65\x5b\x1b\xc3\x5f\x10\x47\x61\xd6\xa3\x74\xad\xbe\xac\xad\xaa\x41\x03\x92\xf7\xd3\x72\x8a\x9e\x84\x2f\xac\x96\xfb\x41\x3f\x51\x71\x14\x8b\x91\x3b\x64\x09\xa5\xae\x0e\xcd\x4e\xff\xd4\x96\x52\x71\xa4\x50\xa9\xb0\x74\x4f\xfb\x9b\xc5\x11\xd6\x02\xd2\x67\xa8\x3e\xbf\x8b\xbe\xa8\x38\x96\xe8\x66\x94\xd0\xb4\xb5\x9e\x31\x52\x95\x50\xbb\x8e\x46\xf0\x21\x08\x0f\xc3\xac\xfd\x59\xe8\x57\x28\x89\x00\x6b\x57\xe0\x2a\x6c\xb4\x2e\x87\xf0\x8d\x4a\x92\x04\xb3\xdd\xfe\xd1\x41\x07\x16\x69\x5a\xf7\x63\x82\x21\xdd\xd6\x5d\xb5\xaa\x41\x0e\x75\x9d\x54\x4a\x22\x64\x8e\x5e\xd6\x5d\x67\xae\x2a\x0d\x43\x14\xe5\xe7\x02\x84\x51\x3b\x47\x85\x10\x54\x9a\x45\xa8\xe6\x21\x79\x4e\xe0\xe1\x7f\x2d\xec\xa5\x52\x11\x73\x5b\x6e\xc8\x0b\x83\xab\x31\x38\x95\x51\xc2\x1c\x26\xcf\x48\xbe\xeb\x8e\x5a\x95\x33\x91\xba\x1c\x42\x23\x43\xaf\x4a\x2e\xc5\x82\x8c\xd8\x22\xce\x88\x20\x2f\xc4\x48\x04\x28\x96\x72\x04\xaf\xae\xab\xd6\xc5\xc9\xfa\x11\x91\x62\xe9\x0d\xc3\xac\x1a\x09\x4c\x96\x43\x71\x25\xc5\x54\x24\xe5\x28\xe0\x74\x53\xbc\x16\xcd\x70\x57\xc1\xa2\xc4\x6b\xd1\x05\x2b\x5d\xd9\x22\xcf\xf2\xdc\x24\x29\x52\xd4\x32\x7b\x33\xb0\x9a\x15\x41\x51\x52\xda\x02\xa4\x7c\x0e\x1f\x9a\x2d\x2a\x04\x21\x3a\x48\x0a\xa1\xb7\x5a\xb5\x2b\x76\xbe\xab\xbe\x83\x57\x8d\x15\x44\x29\x8a\x5f\xd4\xfa\x6c\x49\x84\xdf\x7c\x61\x84\x31\x94\xde\xfa\xb0\xfe\xcf\x5f\x95\xc7\xb9\xd3\xfc\x1e\xd8\x8f\x3b\x73\x86\xfb\x1b\x8a\x08\x2b\x67\x32\xd5\x42\x7d\xab\xeb\x17\x24\x61\x87\x21\xe9\xe7\xb8\xc2\x9b\xc5\x2b\xdc\xe8\xb7\x0f\xe2\x01\x4a\x51\xe5\x5c\x4a\x87\x3d\x9d\x9d\x23\x95\x58\xf8\xc8\x0d\x28\xa8\x9a\x5e\xfa\x7c\xec\x05\xb5\xea\x22\x09\x82\x24\xc1\xba\x45\xff\xd1\x45\x85\xa0\x9e\xfb\x39\x7c\x9e\x04\x41\x46\x53\xe7\x99\xdb\x40\xdd\xe8\x8a\x95\x86\x5d\x5c\x5b\x60\x12\xd0\x30\x40\xb1\x54\xea\x83\x39\xef\x37\x46\xff\xbd\x96\x25\xdd\x2f\x65\x77\xad\xa6\x97\xbf\x59\x64\x35\xdf\xa7\x0a\x36\x66\xb7\x27\x45\xad\x48\x40\x95\x40\xc5\x4f\xfa\x92\x64\x30\x94\x10\x71\x53\xc2\x88\x22\x9f\x66\xaf\x60\x4c\xcd\x59\x62\x29\x09\x42\x91\x63\xac\xac\x6b\xa0\xf6\x91\xfa\xe9\xd7\x47\x51\x12\x3a\x99\x7d\x03\xaf\x50\xea\x33\xd4\x8d\x33\x58\xa6\x9f\x1e\x65\x31\xaa\xa9\x27\x61\x8b\xca\x8c\x5d\xa6\x24\x88\x93\x30\x71\xc6\x72\x77\x36\xd2\xe2\x5a\x65\xf5\xe9\xa3\x13\x92\x22\x32\xa3\xa8\x10\x7a\x86\x90\x58\x4f\xf8\x08\x36\xf1\x4e\x3d\x33\x95\xc1\x50\xea\x6f\x51\xa3\xe4\x6d\x96\x97\x2d\x6e\xf9\x38\x1c\xd2\x2f\x6e\x12\x65\x08\x18\x32\x1f\xa6\x45\x77\x1a\x09\xb9\x99\xf2\xe4\x2f\x48\xe3\xc8\x39\x17\x37\x08\x82\x5f\x8d\xe5\x81\x9f\x94\xa5\x88\x71\x5e\x2c\xef\xaf\xd2\x31\x09\x12\x2e\x10\x69\xb4\xf9\xb6\xf6\x6f\x9f\x86\xc4\xd5\x17\xac\x24\xa6\x4c\x83\x44\xb7\xf2\xf4\xf9\x29\x8b\xb0\x1c\xd0\xef\xcf\xcf\x58\x80\xad\xa7\x83\x94\x65\x93\xfa\xce\x7b\x84\xf2\xfb\xd1\x2c\x10\xc8\x61\x98\xd3\xb7\xfa\xe0\xf1\xa2\xe6\x45\x5b\xbf\xc7\xfa\x93\x20\x0f\x62\xac\x62\xf6\xfd\xee\x5f\x77\xdb\x2f\x4f\x9b\xcd\xdd\xe3\xe7\xd5\xd3\xdd\xe3\xa7\x7e\x5c\x44\x0e\x70\x88\x95\x15\x6b\xfd\xe3\xe2\x65\xcb\xf4\x63\xf3\x40\x20\x98\x12\x6b\x25\x3d\xa9\x4d\xd7\x16\xfd\x6b\xe7\xb1\xad\x0a\xdf\xbb\xc9\x8d\xd2\x87\x5e\xb3\xab\x69\x22\x24\xc8\x15\xc5\xd4\x7a\xd4\x0c\x07\x59\x43\x02\x16\x66\x6a\x9c\xa8\x7d\x27\xfb\x91\xd4\xd6\x8c\x6d\xeb\x8b\x77\xe1\x7d\x70\x70\x19\xe7\xd2\x31\xb1\x15\xab\x6d\x31\x9e\xd9\xf3\x19\xc4\xe8\x9d\x14\x28\x2c\xc7\xe5\x92\x48\xc0\x94\xb0\xb8\x63\xa3\x9e\x7c\xaf\xd9\xf9\x0c\x72\x28\x89\x7b\x1a\xbe\x9a\x27\x09\x96\xf1\x3f\xb9\x3c\xef\x41\xf5\x20\x01\xcf\x6c\x21\xcb\x23\x6b\xb6\x1d\x6f\x26\xb4\x3b\xf2\x83\x91\x80\xb3\x08\xab\x1f\x59\x76\xdf\x5f\x2e\x29\xea\x84\x37\x9b\xc7\x8f\x8b\x97\x92\x40\x88\x3c\x1d\x47\xb6\xac\x6a\x74\x57\x19\xc3\xa6\x78\x05\x0c\x00\x7d\xb0\x48\x92\x12\xdc\x78\xef\xeb\xda\xd4\x5a\x15\xd7\x71\x98\x66\x72\x14\x25\xbd\x6f\x8a\x97\x70\x9a\xad\xa7\x0c\x6d\x85\x52\xde\x5d\xbe\x36\x45\x75\x78\x06\x35\x71\xc3\xcc\xde\x5b\x72\xe5\x34\xe4\x21\xf2\x3e\x84\xdd\x48\x00\x61\x8e\x7e\x33\x9b\xc1\xf5\x02\x15\x02\x24\xe0\x9d\xfb\x75\xf6\x9a\x10\xda\x58\xa6\x31\x4a\x2a\x65\x73\x5f\x6c\x3c\x7b\xf6\xba\x90\x51\x0c\x08\xb1\x49\xd0\x7a\x2c\x4d\x54\x9a\x86\xb1\xc3\x07\x5e\x73\x69\xda\x69\x24\x00\x86\xca\xf5\x8e\x19\x55\xe2\xf7\x3f\xf5\x7b\x12\x42\x22\xe9\x51\x2b\x7d\x06\x7a\xe8\xea\xd5\x13\x42\x98\xad\xd7\x7a\x62\x3f\x8a\x53\x77\x42\x47\x3b\xe6\x6b\x7c\xee\x58\x6d\x9e\x01\x72\x5c\xf1\x90\x10\x4a\x25\x36\x9f\xc0\xd5\x5e\x57\xb5\xc6\x40\xe4\xcf\x2c\x23\x42\x68\x16\xcb\x99\x6e\x34\x88\x22\x42\x81\x62\x92\xf5\x4a\xb7\xed\x38\x85\x95\x90\x90\xf2\xd4\x79\x6f\x7e\xdf\x7d\x73\x36\xd1\xba\x92\xba\x6e\xae\x15\xf7\x25\x24\xe4\x34\x71\x2e\x4d\xab\x27\x3c\x29\xcc\x58\xb8\x56\x94\x92\x90\x28\xc9\x10\x7e\x52\x6a\x26\x07\x1b\x84\x90\x88\x29\x62\xd3\x22\x7d\x89\xc6\xbd\x7b\x96\x9f\x91\xe4\xd6\x3b\x68\xcd\x84\x75\x7b\xdc\xbd\x54\x37\x36\x73\xf5\x5a\x8d\xa2\x09\x2d\x92\x84\x8b\xd8\xb6\x4a\x68\xda\x95\x91\xb7\x63\xd1\x42\x12\xae\x90\x9f\x2f\xbb\xcb\xd7\xf3\x01\x01\xbd\xd3\xb7\x4e\x69\x10\xa0\x4a\xa1\x54\x51\x16\xe3\x5c\xc2\x7e\x02\x61\x4e\x6b\xfc\x66\xab\x7b\x5c\xa9\x6e\xec\xe7\x86\x2c\x9d\xd0\xfd\x94\x07\x93\x94\x87\xd4\x39\x5c\x77\xd0\xb4\xc5\x49\x57\x85\x8f\x12\x10\x92\x51\x5b\xaf\xd0\x95\x0e\xfc\x5e\x54\x33\xec\xa1\x9f\x17\xa5\x08\xd9\x2c\x10\x8a\xe9\xf2\x69\xfc\x58\x9c\x22\xef\xe4\xb6\xa8\x3d\xd4\xad\xd7\xee\x08\xc9\xd2\x5c\xf2\x7e\x99\xbd\x06\x33\x81\xa6\x7c\x90\x71\x4b\x48\x96\xe5\x98\xa5\x5a\x63\xcd\x07\xe7\x86\xba\xbe\x08\x19\x24\x28\x4c\xb6\x05\xbc\x80\x38\x76\x43\xb9\x04\x1c\xcb\xac\x31\xdb\xf3\x02\x5b\xc5\xa2\x9f\xa0\x58\x34\x90\xc2\xf5\x43\x9b\x33\x69\xc1\x3b\x65\x81\xbe\xa1\x99\x9e\x44\x58\x64\xd3\xbd\x31\x31\xfa\x76\x2c\x9f\x09\xcb\x00\x1b\x67\xdc\x20\xc7\x84\x33\xab\x01\x9d\x11\xb3\x15\x66\x8c\x63\xe4\xe5\x49\x74\xe5\xe0\x35\xbd\x02\x6e\x21\x84\x29\x89\x58\xb0\x23\x94\xa5\xa6\xfe\x39\x9c\xb0\x94\xcf\x9c\x27\xd3\xec\xe4\xc9\x4d\x38\xcd\x47\xb9\xd4\x2b\xdd\xd5\xcd\x9c\x4e\xb9\xa0\x40\xc6\xde\x03\x1b\xfb\xef\xcf\x90\x08\xa5\xaf\x76\xe7\x4a\x6e\x6d\x5b\xd6\xce\xcf\xa8\x80\x10\x0f\x0b\xca\xd4\x67\x10\xac\x2c\x3f\xd8\x45\x19\xa4\xc2\x5b\x12\x97\x3b\x09\xac\x7f\x92\x0c\x38\xd6\x80\xe1\xdd\xc5\xa8\xe8\x46\x30\xa2\x76\x14\xfb\xf1\x34\x47\x6d\x6e\xe4\x35\x62\xbc\x87\x57\x10\x22\x79\x8c\x6c\xa8\xff\x92\x27\xde\xb2\xa2\x9a\x15\xaa\x20\x44\x42\xca\xac\xce\xd9\x1a\x92\x2b\x17\xef\xfb\x4e\x10\x02\x01\x41\x62\xbb\x2d\xa1\x16\x23\x42\x83\x24\x42\x77\x93\x05\x88\xd9\x7a\x14\xfd\x18\x27\x99\x18\x34\x54\x87\xb5\xa8\xf5\xc9\x97\x2f\x9c\xda\xb5\x84\x06\x44\x04\x3e\x83\xe8\x08\x13\x6d\x83\x06\xb9\x44\x51\x64\xc3\xd0\x88\x6b\xfd\x40\x6a\x52\x92\x64\xd6\x76\xfc\xf0\xfc\xf5\xdf\x45\x49\xa2\x90\x2d\x99\x45\x5a\xb7\xc7\xbe\xea\xdf\x6c\x16\xcf\xf1\x8e\xaf\x7a\x96\xbf\x68\x86\x00\x7d\xe4\x7b\x97\x21\x3d\xcf\xb9\x23\x7e\x62\x18\x46\xc8\xb3\xcc\x4e\xdd\x55\x9b\x5a\x1f\xd0\xd7\xe2\xbf\x2f\xcc\x53\xa5\x7c\x78\x16\x9b\xb3\x9c\x47\x56\x0b\x0d\x73\x86\x0a\xef\x89\xfd\xd8\xe8\x7e\x51\x42\xa6\xd0\xd6\x59\x76\x35\x56\xe2\x1a\x8b\x21\x1a\x91\x0c\x6b\x25\xad\x16\x77\xcf\x93\x81\x38\xb0\x69\x8c\xab\x9a\x15\x87\xcf\x46\x5c\xae\x59\x7b\x53\x78\x47\x31\xa1\x71\xa8\xf0\x60\xb7\xc7\x1a\x9a\xa3\x2e\x25\xe9\x47\x18\xf8\xa4\x85\x07\x68\xa1\xc6\xc2\x6c\x9f\x66\xee\xd2\xc9\xfa\xc4\x32\x45\x77\xe9\xdd\x66\xf1\x4f\x0c\xe4\xf9\x5b\x25\x3c\xc3\xcc\x24\x34\xbc\x7d\x65\x05\xbb\xe7\x36\x9e\x88\xe5\xdc\x46\x7e\xf0\x77\x49\x04\x84\xa6\x54\x50\xeb\x60\xae\xc6\x09\x0c\x5e\x2a\xd1\x14\x78\x80\xfd\xa0\xaa\x03\x94\x93\x8a\x5b\x6e\x42\x46\x12\xac\xdb\x61\x4b\xc7\x61\xb1\xb0\x11\xb6\x6a\x52\xcf\xbf\xbf\x22\x43\x6b\xe7\x05\x84\x60\x2f\x34\x4e\x0c\xe5\xcc\xe8\x38\x8b\x98\xab\xb7\x34\x23\xfc\x8d\x2d\x32\xf1\x81\xd9\x4d\xb3\x34\xc2\x8a\x5e\xeb\xf6\xd8\x3c\xc0\xa6\x9e\x16\xb7\x9a\xcd\xcd\x01\xbb\x9c\x2c\x5e\xa1\x12\x13\xfd\x83\xe6\x21\x8f\xc5\x00\x1a\xf8\xfa\x7c\xb7\xee\xb5\x04\xca\x82\x0c\x43\x15\xfb\x31\x2d\xbf\xcf\xdf\x25\x94\x31\x1a\xc3\x80\xab\xd8\x8d\x5b\xd6\x5c\x05\x02\x98\x4b\x32\x3c\xa3\x77\xd6\x7a\x35\x14\xf9\xb5\x99\x25\x71\x13\xca\x89\x42\xcc\x13\xab\x6c\x25\xd0\x75\x25\x31\xcd\xa7\xa7\x75\xce\x6c\x5a\x28\x93\x78\x0b\x2c\x83\x3b\x36\xd3\x3f\x78\x3a\x07\x9b\xf3\xff\x0a\x46\xd5\x72\xe5\x79\xbd\x31\x4e\x85\x24\x01\x96\xdb\xd1\xaf\x23\xfd\xd8\x0d\xca\x84\x80\xcd\x72\xb9\x3c\x83\x2c\x6a\xe8\xd5\x12\x2a\xc1\xaa\xe0\x47\x56\x1b\xb5\x6a\x9a\xc5\x40\x28\xb0\x30\xb5\xe9\xcb\x35\x26\x69\xd7\x00\x78\x26\xde\x15\x6d\xbb\xae\x63\x52\x15\x53\x2c\x29\x09\x8d\x40\x64\xcf\x6c\x54\x06\xe8\x9c\x5a\xe3\xa8\x73\xc7\xbe\x7b\x7b\x05\x02\x17\xf4\x37\xf6\xd2\x35\xc7\x29\x17\x08\x83\x30\x45\x07\xdf\xc3\xe2\x77\xd7\xec\x67\xff\xb8\x1c\x1f\x44\x33\xc3\x95\x56\x52\xe6\xb8\x3f\xe8\x8a\xd5\xe2\x78\x31\x3b\xd2\x4c\x94\x9e\x30\x88\x23\x97\x53\x29\x01\x4e\x13\x75\xdf\xcf\x48\x43\x74\x44\xcb\xa2\x39\xdb\x30\xea\x5b\x8f\x75\x70\x53\x48\x18\xd8\x48\x8e\x51\xdd\x59\x39\x14\x14\x37\x52\x67\xe7\x18\x8e\x9f\x4c\x13\x81\x31\x59\x51\x02\xab\x67\x45\x70\x48\x48\x85\xc8\xfa\x26\x6b\xb7\x36\xc4\x3f\x6d\xd0\x45\xc2\x30\x24\x18\x0d\xb0\xb1\xaa\x7e\x74\x42\xeb\x61\x98\x0b\x8a\x8e\x36\xd6\x55\xe2\xd8\x5f\x2a\x39\x1e\xb1\x8a\x9d\xe0\x49\x5d\x75\x08\x93\x30\x04\x82\x08\xbc\x67\x73\x65\xf7\xd7\x50\x1d\x24\x8c\x02\x1b\xa5\x31\xbb\xb2\x7a\x7a\xdc\x3d\xdf\x2d\xbf\x62\x01\xb3\xaf\xdb\x1b\xff\xf8\x28\x8e\x6d\x7d\xb2\xbf\xdf\x4f\x16\x30\x8a\xad\xdc\x1f\xe3\xf9\x3f\xd7\xec\x7c\x84\x0a\xd0\xe9\xe0\x27\xc6\x84\xa2\xb6\xb3\x5a\x2c\xdb\xf1\x0d\x92\x30\xc6\xf0\xc2\x3b\x37\xf3\x10\x67\xf5\x1c\x36\x4c\xe2\xc8\x85\xfa\x58\x7b\xbc\x61\x2d\xdb\x2b\x1f\x4f\x20\x61\x92\xa6\x58\x54\x60\x53\x5f\xfe\x40\x47\xdb\x6c\x59\x53\x9a\x63\x2e\x41\x8b\xa8\xb5\xef\x47\xa8\x5c\x04\x0c\x3b\x2e\x19\x1e\x7f\x83\x95\x41\x8a\xea\xb0\x78\xdc\xf9\xbb\x66\x8c\x09\x32\xa0\x1d\xfa\xec\xce\x9f\x18\xf8\x61\x06\x21\xee\xf2\xfe\x3f\x0b\xf9\x71\x51\x88\x29\xad\xe6\x71\x88\xc0\x36\x86\x31\xa1\x5b\xc3\x32\x54\x57\xc9\x3b\xe5\xdc\xc4\x8f\xba\x7d\xc6\x8a\xe1\x3d\x35\xe6\xb1\x0c\xfb\xea\x08\xa8\x66\xa2\x2b\xf9\x56\xf7\xf9\xff\xa3\xbb\x0b\x5b\x1e\xfe\x8c\x71\xa7\x0f\x01\x1f\xc8\x78\xa7\x57\xb2\x00\x30\x3d\xe4\xcc\x8a\xfa\xad\x68\xe0\xa9\xfe\x34\x8a\xca\x93\x90\x65\x21\x16\xf6\xe7\xc0\xa6\xd8\xf8\xb1\x61\x1e\xb2\x5c\x20\x56\xda\xea\x4b\x33\xef\xf0\xf4\x81\x3c\xca\x11\xa9\x63\xa7\xde\xb0\x39\xec\xd7\x4d\x13\x2a\x40\x9c\xc1\xd9\xe1\x90\x67\xcc\x2a\x94\x51\xc6\xa5\x47\x2a\x41\xd3\x4c\x11\x0e\x7e\x52\x12\x71\xd9\x03\x88\x56\x63\xbd\x78\x86\x64\x1e\xec\xe3\x50\x72\x6b\xd9\x8a\x41\xc5\xb7\xda\x93\xdf\x18\x88\x23\x5f\xc3\xf2\xb3\x2e\xa5\xa1\xd3\x77\x79\x1b\x24\x84\x54\x84\x6e\xd6\xd7\xba\x44\x57\xe6\x28\x6a\x30\xfd\x58\x90\x11\xe6\xea\x33\x4c\xee\x25\xfd\x2d\x80\x4b\x87\xc6\x3a\xb1\x1f\x82\xd5\x72\x94\x30\x46\x42\x50\xb6\xbb\x52\x6b\x23\x70\xeb\xf6\xb8\x7d\x63\xe7\xa7\xae\x3d\x77\x3f\xcf\xd2\x21\xa1\xca\x42\x31\x18\x64\x98\x40\x3f\x45\xf8\xf4\x47\x52\x65\x91\x62\x7d\xca\x8d\x77\x18\x0c\xe5\x09\x49\xa8\x04\x45\x3d\x62\x7b\x2a\xca\x12\x9a\x91\x61\x18\x05\x10\x62\x00\xac\x69\x47\x20\x5e\x4b\x38\x83\xb3\x7e\x04\xd1\xf8\xc0\x4f\x1f\x05\xc0\x32\xa7\x08\x3e\xea\xfa\xc4\xca\x67\xad\x4f\x0f\xc5\x4c\x1e\x44\x04\x6c\xfb\xaf\xbb\xd5\x13\xbb\x46\x54\x11\xcd\x69\xe4\xdc\x3c\xdf\x50\x6e\x2f\xce\xbd\xa7\xa5\xb1\xde\xe6\x31\xe3\x8c\x28\xcf\x10\x80\x76\x62\x2f\xf0\x00\xf5\x4b\xe9\xa2\xc5\xd7\x57\x35\xa2\x22\x93\x30\x84\x91\xac\x4f\x68\x40\x3b\x9a\x09\x39\xb3\x15\x96\xb7\xba\xc4\xce\x15\x7e\x40\x46\x88\xf4\xac\x74\xfb\xa5\xab\x0e\xf5\xec\x7c\x47\x54\xa6\x88\x2d\xb3\x04\x62\xc8\x6c\xe9\x5d\x60\x1f\x18\xec\x11\x55\x39\xaa\x20\xbe\xe2\x8c\xb5\x54\xb5\x7a\x2e\x0e\x1f\xaa\x0b\xee\xd2\x90\xa6\xb6\x84\xa9\xaf\x77\xe4\x90\x0a\xd3\xc5\x0c\xa3\x18\x75\xed\xed\xfa\xf1\x66\xfd\xbc\x5f\x2e\xee\x17\x8f\x2b\xef\x72\x8f\xa2\x14\x30\x30\xe5\x6a\x49\xcd\xd5\x88\x28\x86\x10\xb9\x5b\x51\x15\x7f\xb9\x74\xb4\xbb\x34\x89\x52\x1b\x73\x99\x75\xe6\x18\x90\xfb\x24\x4a\x52\x1b\x26\x72\x73\xcc\x2e\x14\x7a\xba\xb9\x89\x0c\x5c\x7c\xa2\x92\xdf\x86\xa4\x41\x37\x9a\x13\x15\xd8\x48\x5d\x03\x66\x0b\xef\xaa\xd5\x50\x13\x94\x44\x39\x65\x01\xf7\xed\x71\x8b\xea\x30\xb5\x86\xa3\x1c\x00\x53\x0a\x5f\x0b\x78\xdb\x1f\xa0\xdd\xef\x6a\x60\x4d\xdf\x3c\x8a\x44\x2c\x8d\xe2\x70\xda\x88\x8d\xd2\x7e\x30\xb3\xe5\x9e\x70\x7f\xf7\xfd\xcf\x3c\x48\x31\x52\xe4\xcb\xd1\xda\x4c\xf6\x9f\xfa\xd1\x22\x0e\x32\xf3\x95\x03\x50\xf2\xec\xf4\x6f\xba\x78\x81\x2b\xea\x54\x24\x42\x89\x70\x3c\x47\xbe\x7b\xf8\x61\x0b\x9a\xef\xf9\xd0\x65\x91\x44\x22\x63\xa8\x51\xad\x96\x63\x3d\x21\x92\x81\x42\x24\xed\x91\xd5\x72\xc5\xce\x5f\x8a\xc3\xf1\x6b\xd3\xaf\x87\x0c\x13\xdc\xb2\x85\xaa\x47\xec\x01\x62\x85\xe7\x65\xf1\xfc\x1b\xfa\xe7\x74\x59\x42\xbd\x27\xfb\x20\xe8\x67\x24\x79\x6e\xa4\xe6\xbf\x76\xb7\xfd\x4f\x79\x8c\x84\x85\x0d\x6c\xfb\x08\x2d\x89\x54\xaa\x28\x75\x91\xc6\x11\x64\x99\x44\x4a\x90\x24\xf7\xb5\xfa\xc5\xcb\xcf\x81\x06\x24\x0e\x02\x8b\xac\xaf\xe1\x5e\x33\x89\x25\x11\xae\x9f\xb0\x38\x08\x58\x9e\x8e\x54\x23\xac\x9c\xe0\xe0\x1a\x1f\x5d\x42\xc2\x68\xd4\x48\xd5\xea\x00\x9f\xfc\x20\x8d\xb0\x80\x99\xc2\x32\x5b\x3e\x9c\xd2\xf4\xc3\x3c\x0e\x83\x01\x37\x01\xcd\xb8\x53\x18\x89\x09\xcd\x19\x71\xde\x7b\x3c\xea\xeb\xf1\x98\xe4\x43\xf4\xee\xce\xb9\x5e\x56\x1a\x94\x2a\x44\xd1\x07\xe6\xe8\xec\x6d\x49\x6c\xfd\x5d\x6f\x50\xec\xb4\x73\x56\xf4\xb7\xcc\x64\xea\x7b\xc8\xfc\x63\x9c\x38\xec\xc7\x85\x22\xb2\xc7\x03\x14\xd5\xc1\x65\xb5\x4c\x17\x3b\xcc\x32\xa4\x9a\xbd\x47\x43\x7f\x7d\xbe\xbb\xea\x4c\x8b\xa3\x3c\xe4\x2e\x15\x07\x75\x6f\xe4\xd9\x57\x40\x50\x24\x8e\x64\x88\x6d\x6b\x2a\xdd\xc2\x8f\xa2\x69\x25\x9c\xa7\x6c\x3d\x4e\xd2\x14\xa1\x32\x1c\x2a\x30\x0b\xc0\xea\x62\x06\xfa\x23\x71\x92\xe5\x88\x52\x69\xa1\x69\x1d\x71\x5a\x3c\xfc\xf7\xa2\x3d\xda\xf0\x64\x63\xff\x6c\xd9\x09\x4b\xe1\xf5\x41\xb1\x38\xe1\x21\x9a\x94\x0e\x75\xe2\xf4\xe6\x5a\x9f\xae\x6b\xf5\x71\x9a\x86\xae\x6c\x4a\xbb\x77\x95\x21\xf7\xd8\xfc\xcc\xc2\xcd\xa7\x0b\x9b\xc5\x11\x9a\xd4\xff\xed\x74\x8b\xc5\x08\xdd\xef\x39\xcb\x89\xef\xd2\xc4\x5a\x40\x0f\xea\x9f\x65\xf1\x91\x98\x91\xcc\xb6\xa7\x68\x59\x3d\xc5\x20\x91\x98\x45\xc0\xac\xe6\xae\x34\xb6\x37\x9f\xbe\x35\x03\xeb\xb0\x35\xac\xe5\xc3\x6c\xaa\x6b\xf0\x48\x12\x33\xc5\x30\x90\x66\x13\x91\xee\x7a\xbf\x54\xcc\x15\xc5\x10\x93\xcb\x35\x9e\x86\xc1\xaf\x5b\xe2\xb1\x20\x22\xb5\x59\x49\xb6\xab\xf4\xb4\x1b\xc1\x6c\x2e\x0f\xd1\xef\x75\x66\x5d\x33\xaa\x6f\x68\x06\x32\x61\xcb\x53\xfc\x28\x58\x25\x86\x1c\x01\x12\x0b\x21\x11\x13\x7f\x83\xcc\xe3\x9d\xfb\x3f\x96\x34\x08\x94\x4b\xc5\x71\xe6\xc3\x62\x50\x34\xfd\x24\x50\x71\x5f\x51\xc0\x82\x63\x56\xfe\x01\x10\xd9\x16\xb2\x07\x9f\x65\xf6\x75\xe4\xe6\x1a\x09\xb5\x18\x62\x2a\x7c\xc0\xcf\x17\x25\x09\xe9\xc4\x03\x16\xab\x90\x62\x21\x04\x81\x11\x52\x63\x26\x0d\xcd\x7d\xfd\x14\x96\x08\x27\x13\xbe\x43\xb1\x62\xe7\x19\x85\x29\x15\x62\x06\xeb\xe7\xc7\xa7\xed\x9d\x43\xc2\x93\x24\x48\x63\x1f\xc6\x73\x45\x29\x58\x7d\xd9\xab\xae\x7a\x8f\xc5\x24\x49\x90\x29\x84\x2a\x58\x6b\x67\x56\x6c\x87\x24\x01\x58\x14\xa0\x6b\xd4\x86\xc9\x0f\x93\xe2\xdf\xff\x0e\xc7\xa5\xf1\x47\xda\x79\x82\x3e\x12\xcb\x05\x0b\x73\x99\xb1\xe9\xad\x98\x9a\x03\xf9\xbc\x0a\x9b\x10\x19\x63\xf3\x49\xef\x33\x3d\x9d\x59\x71\x78\xdf\x40\xe8\x83\xb6\x6f\x53\xd2\x4d\x28\x21\x58\x97\x13\x21\x00\xf3\x7c\x7c\x33\x1c\x23\x8e\xd5\x1c\xfd\x75\x7b\xbc\x81\xd7\xa6\x1f\x0a\x6d\x32\x21\x67\x4d\x21\x46\x5a\x61\x42\x33\x9a\x0a\x7f\xcb\x80\x0e\xee\xb3\x84\xaa\xd4\xb7\xd6\x75\xce\x3c\xe7\xa6\xbb\xb5\x09\x06\x63\x39\x97\x84\xa9\x75\xcf\x1a\x4d\xdd\x43\xae\x67\xdb\x12\xca\x0c\xc9\xff\x41\x37\xed\x37\x56\x76\xa8\x99\x0d\x02\x39\x89\x22\x60\xa9\x2f\x17\x7e\x3a\xf7\xda\x5a\x12\xa5\x53\xbc\x9a\xd1\xc0\x3f\x8c\x62\x27\x71\x0c\x98\x34\xe1\x0b\x08\xf2\xd2\x30\x2a\xc4\x75\xbd\xaf\xff\x73\x1d\x9b\x92\xc4\x79\x86\xa5\x1d\xf6\xc1\x8f\x65\xd1\x0a\x5d\x54\x82\x35\xc7\xb1\xca\x91\x24\xb1\xcd\xa3\x58\xde\x3f\xad\x7e\x7b\x5e\xdc\xdc\x3d\xf9\x91\x34\x8d\x10\x37\x67\x6b\x7d\xb6\x57\xc0\x34\x49\x0a\xdc\xa5\xc1\xea\xaa\xff\xcc\x8c\x30\xeb\x70\x7e\x03\x38\xcf\x68\x36\xcb\x73\x54\x56\x0c\x6b\xea\xd7\x3c\x03\xeb\xf4\xf8\x3b\xda\x0f\xc3\x42\x66\x2a\x48\x7a\xdb\x7d\xe1\x0f\x81\x1b\x64\x99\x50\xb6\x27\xdf\xf9\xeb\x79\x66\x77\x59\x2f\x7e\xee\xa9\x8d\x71\x9b\x21\x6c\x0e\x9d\xab\x2e\x37\x02\x40\x5f\x29\x15\x44\x12\x1e\x64\x68\x2b\xad\x9a\xfe\x2d\x45\x92\x20\xec\x61\xef\x2a\xc8\x4f\x0a\xf7\x90\x44\x26\x01\x16\x34\xe1\xdd\x65\xdb\xea\x1a\x56\xba\xfe\x79\x29\x18\x92\xc8\x54\x64\xa1\xe7\xa3\xf7\xba\x6d\xbd\x02\x90\xf9\x09\x20\x46\xc5\xe0\x7d\xf4\x75\x7b\x06\x51\xb0\x49\xfd\x70\x92\x40\x10\x72\xe7\x81\xb1\x62\x74\xa7\x3d\xc8\x64\xfa\x50\x20\xd4\x76\x13\x46\x50\x84\x87\x48\x7c\x10\xb5\x4d\x80\xa5\xa9\x2d\x5e\xfa\xa8\x5b\x04\xe0\xb6\x2d\xcc\x7c\x46\x09\xf0\xcc\xb6\xdd\x9e\x26\x3b\xbc\xff\x60\x15\x46\x28\x0b\x05\x2b\xcb\x83\x73\xd9\xf8\xf5\x53\x2c\x20\x59\x8f\x5b\x6a\xab\x0f\x90\x5e\x29\x8d\xad\xcd\x20\xe1\xe4\xf2\xb9\x48\x1a\x66\xe0\x1b\xf2\xba\x00\xdf\xf4\xa3\xd3\x10\x42\x15\x0d\xee\xe9\x19\x19\xa7\x11\x10\xc4\x97\x9d\x2e\x3f\xfc\x2d\xe3\x80\xc4\xd4\x7d\xb8\x9c\xbf\x43\x92\xf3\x30\x75\x6a\x9b\xaf\xd2\xb4\x85\xd7\xbf\x5e\xa6\xe8\xa7\x65\x5d\x48\x9a\xf0\x18\x15\xf6\x9b\x1a\xd8\x69\xd9\xd3\x58\x9a\x06\x80\x5e\x9f\xc7\xdf\x76\xe3\x33\x9c\xa6\xb1\x42\x55\x69\x2f\x4a\xdd\xc0\x52\x6b\x5f\x98\x8c\xa4\x69\xc6\xd1\x71\xf8\xcf\x4a\x21\x78\xd3\xff\x9e\x05\xd6\x81\xd4\xea\xed\x97\x05\x8d\x93\x09\x35\xa5\x59\x26\x51\x0d\xba\x01\xc1\x78\xef\xbc\x35\x3f\xc7\xc9\x18\xbf\x69\x8e\x91\x38\xc2\xd5\x9a\xd9\x24\xcd\x78\xc6\x6d\xb3\x20\x97\xeb\x33\x11\x02\x69\xa6\xc0\x77\x06\xbb\x99\x27\xe0\x90\x34\x8f\xac\x85\x62\xe3\xbe\x37\xba\x2c\x59\x7d\x05\x6e\x95\xe6\x29\xf5\xc5\xc7\xec\x49\x46\x1d\xf1\x5d\xd2\x29\x49\x79\x20\x11\xa6\x78\xec\x5b\x0f\xde\xea\x7a\x6d\xe5\xdf\xec\x9e\x3c\xcc\x3d\x07\x7f\x28\xaa\xc2\xa8\x09\x66\xa2\x6f\x45\x4f\x52\x0e\x2a\x71\x68\xde\xf5\x8f\x73\xa9\x2d\x3e\x6d\x79\xd9\x7a\x90\xc5\x87\x87\x3e\x85\xd0\x36\x8f\x1b\x82\xd1\x9f\xd9\x09\xb6\x2d\x9c\xfb\x65\x86\xc4\xca\xfd\x1a\xb0\xc1\x51\xf1\x07\xb8\xa6\x42\x6d\x31\xec\x85\xa2\x29\xc2\x2a\x31\x36\xd9\xac\xcc\xc6\xcb\x7e\x8c\x91\x80\xf7\x5d\x9a\xbe\x5a\xb4\xc2\xa7\x09\x6a\x21\x55\x2c\xb6\xa6\x05\x36\x29\x7f\x86\x57\xa8\xdb\x8d\xb1\xad\x07\x35\x21\x55\x90\x05\x5e\x72\xa2\x97\x7a\xf2\x29\x19\xcd\x00\x31\x30\xff\xe8\x60\x14\x5f\xce\xc2\x24\xc0\xd3\xa1\x7a\x0b\x03\x0b\x77\xf7\xc3\x99\x42\x3e\xca\xa4\x1c\xb5\xf8\xc8\xa6\xb4\x93\x85\x2a\xc4\x3c\xad\xb3\xf6\x05\x56\x66\x0f\x37\x26\x2c\xd6\xec\x79\x1b\xf5\xb2\xf0\x63\xca\x7a\x0d\x85\x87\xe0\x4d\x43\x88\x59\xac\x22\xff\x5d\xbe\xf5\x8d\x9f\x31\xbd\x51\x12\x2a\xcc\xcb\x69\x8f\x45\x63\xd8\x2f\x13\x6d\x33\x89\x71\x67\x09\xb3\x95\xfa\x9e\x7e\x2c\x0b\x3d\x3e\x94\x59\x22\xc2\x04\x26\x1b\xbd\xfe\x21\x8e\xec\x00\xeb\xdd\x17\x3f\x27\x4d\x72\xf4\x11\x7d\x83\xba\xf8\x31\xca\xa9\x25\x59\xca\x12\x2c\xb6\xcd\xb9\x96\xae\x78\xc5\x2c\x3c\x96\xa5\x90\xa7\xb6\xc8\x44\x21\x8a\xea\xb0\xc5\xb6\x33\x87\xeb\x75\x36\xdf\xd1\x61\x96\x89\xc0\x56\x58\x29\x5b\x0c\x6b\xce\x46\x95\x55\x10\xb1\x1c\x20\xe2\xb5\x7c\xf9\xe0\x61\x4e\x1e\x64\x58\xb7\xa7\xef\x73\xe1\x5e\xe4\xd3\x4c\x75\xcc\x72\x2e\xa3\x21\xfd\x53\xab\x27\xb5\x81\x5a\x21\xc6\x1a\xdb\x9e\xe2\x7f\xa6\xa7\x35\x63\xd4\xd6\xea\x3b\x40\xbb\xec\x2e\x63\x34\x70\xc6\x38\x1b\x61\x05\x36\x25\xc8\xc3\xcf\xcb\x69\x93\x8c\x07\x89\x52\xae\x18\x6c\x75\xb5\x5d\x3b\xc9\x78\x12\xa1\xfd\xe8\xc0\x07\x36\xb2\x7c\x05\x71\xe6\xa6\xcb\x30\x42\x38\x39\x6b\x9a\xe2\x50\x61\xe9\xf0\xf7\xe9\x5d\xfd\x12\xc8\x44\xa1\x79\xd5\x1c\xf5\x1b\xb4\x47\xa1\xab\x99\x36\x9f\x49\x88\xb1\x4f\xe9\x00\x93\x5e\x2d\x57\xef\xe3\xe8\xf3\xb7\x50\x8c\x79\xc0\xc8\xea\x5d\xaa\x16\xc9\x80\x84\x88\x79\xaa\xba\xd3\x93\xf2\x64\x78\xd6\x7d\xc0\x2c\x53\x71\x94\x5a\x39\xf7\xbe\x72\x38\xc9\x14\xb3\xd5\xe0\x87\xc6\xdb\x1f\x00\x38\x32\xc5\x15\x92\xd3\x91\x35\xc7\x85\x6b\x22\xeb\x5e\x22\x0f\x72\x5b\xb4\x7e\x8f\xad\x8c\xb6\xd0\xb6\x45\x75\x30\x2c\xdf\x6e\xfc\x35\xc3\x34\x9b\x17\xe5\x9c\x46\x1a\xfc\x8d\x79\x86\x48\x10\x90\x45\x6b\x71\xd7\xac\x76\xdd\x14\xbf\xcf\xab\xcc\x8f\xb6\x3a\x0f\x20\xc3\x7c\x97\x65\xd1\x36\x42\xd7\x83\xee\x9a\x93\xdc\xb6\xe2\x68\xa0\x5d\x96\xfa\x50\xfb\x23\x37\xf9\xd8\x9c\xc8\x10\xa3\xf5\x4d\x77\x3a\xb9\x18\x66\x43\xfb\x5b\x48\x81\x71\x42\x5c\x72\x04\x30\x78\x66\x91\x87\x81\x2d\x16\x27\x59\xfd\x52\x69\x09\x37\xe0\xa3\x79\xd8\x4d\x76\xfa\x90\x30\x14\x08\xe4\xde\x3d\x7d\x7f\xb4\x65\x87\xf7\x9b\xe7\xbb\xde\x37\x9c\x47\x8c\xa3\xe0\x3b\xd7\xba\xd4\x3e\xab\xd9\xfc\x2c\x90\x21\xe1\xf1\x42\x13\xfc\xf6\xeb\xe3\xcf\x60\x5a\x79\x24\xb9\x2d\xfd\xd9\x9d\xe6\x47\x37\x4f\x32\x86\x12\xff\x54\x54\xa3\x84\xaf\xeb\x47\x22\x4f\x03\x8b\xa0\x6a\xa0\x35\xf2\xec\xa9\x82\x31\x2a\xe9\xdd\x64\x81\xf5\x64\x5b\x60\x27\x63\x00\xcb\x7e\x95\x52\x99\x23\x49\x7e\x5b\x6f\x77\x77\x8f\x9f\x5d\x99\x38\x3f\x9a\x45\x99\x5d\x5e\x36\x0f\x09\x1b\x5b\x87\xfa\x8a\x0e\xbe\x15\x89\x2b\x3a\xd4\xdf\x3c\x63\x16\x86\x88\x98\x1d\x23\x3b\x9f\xce\x3d\xcb\xce\x73\x12\xda\x5e\x10\xe2\x08\xb2\x2b\x61\x12\xeb\x72\xe5\xaf\xa6\x5f\x91\x27\x39\x86\x53\xa1\x3d\x6e\xa0\x1e\x59\x15\xa3\x64\x55\x92\xe7\x99\x05\x97\x7c\x2e\x35\x67\x16\xd4\xe2\x1b\x10\x4d\xbf\x20\x17\x29\x77\xb4\x83\x11\x22\x8f\x26\x75\xc3\x9c\xc4\xa9\xd5\xbf\xc4\x4b\x77\x9e\x0a\xb5\x9c\x87\x14\x95\xeb\xa1\x14\x90\x91\x7c\x8d\x53\xa6\x67\x0f\x12\xa1\x42\xe9\x59\xc1\xdb\xc8\xbe\xbc\x16\x05\xbf\x26\x49\xae\xcf\x9a\x10\x95\x88\x6d\xf9\x1a\xac\x2e\xba\xd2\xc6\x0c\x9e\xe3\xb0\x72\x49\x53\x6c\xe3\xec\x43\x10\x23\x2f\x4d\x0e\x71\x82\xbd\xa0\x55\x51\x49\xc7\xb7\xe6\xbd\x79\x48\xae\x62\x81\xf1\x89\x8a\xd5\x42\xa3\xc1\xe5\x07\x92\x48\xb8\xca\x4f\x4b\xd6\x7b\xdd\x73\x95\x05\xdc\xda\x8c\x5b\xac\xad\xfc\x01\x69\xaa\x0c\xb0\xae\x1d\xe6\x83\x5d\xcd\x18\xc8\x15\x28\xdb\x31\x10\x1a\x68\x6f\x8b\x0a\x26\x1c\x8f\x05\x01\x25\x2e\x3b\xef\x41\xcf\x36\x99\x05\x24\xf6\xed\x51\x17\xf6\xcb\xeb\xe6\x1a\x7e\x9e\x05\x51\x86\x2d\x46\xcd\xe1\x43\xa7\x3b\xb0\xd3\x34\x5a\xe5\x27\x66\x2c\x73\x20\xbc\xef\xba\x7e\x81\x1a\x1d\x5b\x57\x0f\x29\x0b\x24\x20\x6e\xa6\x70\x8a\x4f\x33\x49\x80\x61\x84\x2a\x19\x0e\x38\xa8\xd2\xa2\x64\xa7\x8f\x23\xb1\xcd\x8d\xef\xa1\xbc\xcd\xbd\x2d\xff\x3f\xa3\x8f\x9f\xca\x64\x46\xb8\xc5\xb0\x70\x2c\x6f\xd5\xfb\x7d\x19\x4d\x33\x5b\xd9\xda\xd1\xf1\xa6\x06\xdb\x14\x6b\xd9\x95\x2f\x23\x81\x78\x05\x62\xf6\xe1\xbf\x3e\xe8\x02\xe9\x9f\xa8\xa2\x6c\x30\x35\xb0\x1f\xd0\x86\xcd\xba\x8f\xcc\x5e\x9e\xaa\x34\x7e\x6f\x99\xff\x59\x8d\x08\x77\x71\x18\x05\xd8\x0e\x14\x1d\xd3\x4b\xdd\x1d\x8e\xed\x4a\x97\x3e\xdb\x8e\xb0\x88\x84\x3c\x77\x95\xbb\x6b\x5d\x96\xb3\xf6\x1f\x84\xc5\x41\x10\xd8\x48\x84\x51\x7e\xd7\xaf\x50\x5f\x48\x60\xfe\x77\x53\xb3\xb7\x74\x7a\xca\x58\x4c\x89\x74\xfe\xce\xad\x51\x68\xbc\x5d\xdd\xf4\x0a\x81\xd3\x78\x9a\xab\x8b\x3b\xdd\xfa\x38\x94\x21\x1f\x40\xfc\xcb\x0e\xcf\x97\xc3\x55\x8c\x63\x7b\x2c\x86\x50\xd9\x28\x6d\x2f\x8a\x67\x95\x28\x09\x4b\x32\x2a\xc8\x34\x80\x7e\xed\x1c\x24\x19\xc3\x0a\xed\x52\x57\x2f\x70\x19\x79\x88\x58\xc2\x38\x3a\xaf\x36\xac\x69\x40\x7e\x66\x2d\xbc\xb1\x0f\xa2\x46\x2c\x4d\x13\x1a\xa3\x16\xd2\xf1\xf5\xa8\xc7\xd5\xf4\x03\x53\x96\x61\x60\x8e\xb3\xf6\x5d\x75\x66\xc2\xb2\x20\x49\x86\x88\xbf\xb7\x1d\x66\x48\x8d\xeb\x8f\xcf\x32\x85\xe1\x48\xde\x5d\xb6\x00\xbd\xb4\x63\x99\x0c\x52\xe7\x8a\x75\x69\xdc\x1f\xdc\x67\x76\xbf\x3c\x54\x16\x11\x5f\xbc\xc2\xe2\x8d\x5d\xae\xf7\xe5\x26\x2c\x4f\x78\xee\x42\x3e\x7b\x2c\x71\xbf\xbf\x29\x1a\xf1\x5e\x55\x64\x9c\xb2\xc4\xfb\xc5\xb1\x90\x8c\xb7\x76\x19\xa7\x0a\x51\x4d\x0f\x6c\x48\xd8\x62\x3c\xcf\x10\x65\xb4\xfc\xfa\xcf\xe1\x27\x85\x25\x45\xf6\x0d\x53\x57\x64\xa7\x9b\x25\xc3\x18\xc2\x09\xf7\x70\x21\x3f\xf6\x91\x2b\x94\xc9\x30\xc7\xde\xc4\x56\xd7\x06\xe9\x83\xb0\x2e\xd5\x0f\x91\x68\x86\x78\xfc\xf4\xc4\x62\x29\x8c\xed\xc0\xc4\x0b\x54\xbe\x71\xa6\x1b\x07\x92\xe3\x89\xb8\xd7\x87\xfb\xa7\xdd\x47\x19\x57\x7f\x72\x88\x41\xa5\xb1\x73\x2a\x2e\xa1\xc1\xdc\x21\xc6\x8b\xb2\x68\x27\x2e\x3c\xa6\x64\x8c\xed\x9e\x59\xe9\x6b\xde\x9b\xcf\x7d\x60\xd5\xc5\x05\x50\xaf\x9e\x3a\x7f\x31\x70\x26\x2c\x14\x43\x0f\x6a\x0a\x0f\xe2\x94\x5b\xa7\x1c\xaa\x12\xdb\xfe\xcb\x78\x90\x2a\x97\x04\xfa\x9f\xce\x3a\xa7\xa1\x1f\x12\x89\xcd\x1e\xb0\xe2\xfe\xcf\xd2\x9c\xdd\x55\x84\xa4\xb9\x85\xeb\x1d\x0e\x25\xdc\x8f\xba\xbc\x10\x4e\x68\x8c\xc5\x8b\x51\x06\xee\xb0\xe5\xef\xf8\xd8\x72\x12\x91\xc8\x59\xd9\xb7\xbe\x34\xeb\x4c\x72\x71\x1a\xd2\xc0\xb7\xd6\x6c\x59\xdd\x0e\x5d\xe8\x87\x77\xa0\x86\x21\x3a\x10\x81\x31\x94\x55\x81\xad\xe2\xfd\x6b\x44\x79\x00\x0e\x33\x7d\x33\x36\xc0\x79\x1c\xa5\x91\xa3\xfc\xfb\xfb\x6f\x0e\x1e\x10\x4d\xdf\x31\xce\xad\x1b\xcc\x77\xd2\x05\xf9\xf4\x81\x76\xcb\x63\xa5\x84\x3b\xa8\xae\x90\xf0\x5f\x4d\x15\x9f\x20\xc7\xdc\xdd\x12\x1e\xa3\xcb\xee\xb5\x80\xb7\x87\xcb\xb8\xc2\xff\xc8\x01\xc3\xd3\x48\xa2\x89\xbf\x5b\x2f\x1e\xf6\xdb\x2f\x8b\x67\x2c\x9a\xbc\x5a\x3f\xee\x16\x9f\xbd\x21\xc0\xd3\x8c\x13\x6a\xad\x19\xa1\x8b\xea\x41\xf7\x81\x14\x9e\xc5\x14\x11\x4a\x58\xe4\x06\x5d\x68\xab\xfa\xad\x1f\x4c\x72\x45\x06\xb4\xf0\xb8\xce\xce\xf0\x67\x74\x72\x79\xc6\x02\x3e\xc6\x3b\xe1\x22\xac\xab\xd7\xa2\xd6\xd5\x50\x93\x8d\xf0\x3c\x61\x68\x99\xbc\xb1\x57\x58\xb1\x33\xed\x7f\xcf\x32\xb4\x0f\x0c\xb3\x6e\x5d\x1b\x2c\x3f\xc4\xc2\x3c\xf5\x71\x31\x5b\xca\x6b\xae\xed\xf1\x5c\x01\xe2\xa0\x5a\x68\xb0\x94\xd3\xa7\xc9\xf6\x30\xca\xb1\x3b\xa1\x6f\xa2\xbd\x28\x6a\x59\x6b\xef\x5e\xe6\x2c\xb1\xa6\x62\xa9\x9b\x71\xdb\xa6\xd9\x1e\x33\x46\x61\xdc\x91\x7e\xf0\x4f\x73\x1e\x01\xa2\xf9\x9f\x17\x77\x4f\xa3\x82\x86\x57\xe4\x15\xe7\x49\x8a\xfe\x70\x2b\x1f\xac\x23\xc1\xa6\xd2\x5c\x7f\x2a\x4f\x21\x66\xbe\x3d\xbb\x78\xc1\xa2\x92\xac\x28\x3f\xc0\x24\x71\x9e\xc5\x58\xb3\x60\xbf\x6f\x86\x23\x33\x7d\x01\x6e\x9b\x26\xbc\x9a\xd3\x72\x31\x47\x13\xe7\xcc\xc3\xc9\x7f\x46\xbe\x93\xd8\xdd\x84\x12\xb8\xb1\x1f\x6c\xdc\xe7\xdc\x8b\x77\xd7\xf3\x76\x14\xc8\xe3\x82\x86\xa9\x74\x2c\x82\xd5\xe2\x08\xf3\xfc\x11\x2e\xa2\x10\x1d\x18\xcd\x91\x79\x07\xe5\x34\x56\xc8\x45\x14\x23\x0d\xef\xd9\x28\x41\x95\x8b\x34\x4e\xdd\x9a\x35\x6d\x27\xa1\x6a\xb1\xa7\xcb\x74\xa5\x44\x1e\x87\x7d\x19\x4e\x2b\x6b\x3e\x63\x63\xb8\x76\xe0\x62\x32\xb2\xed\xd9\x64\xd1\xe8\xb7\x6a\xba\x8e\x60\x88\x0a\x23\x7d\x5d\xd5\x0e\xce\x39\x0e\x3c\x15\xce\x3b\xb6\x64\xf2\x00\xd8\xa2\xfb\xdd\xf2\x5e\x29\x71\xd3\x5f\xaf\xc2\xa1\x3e\xa3\xa3\x54\x2c\x74\x67\x3d\x22\xef\xe0\x94\x5c\x25\x49\x34\x14\x8b\xbb\xad\xf5\xe9\x83\x84\x04\x61\xcc\x6a\xc3\xd1\xf6\xe7\x5a\x0b\x68\x1a\x87\x8e\x99\xac\xa9\x20\x44\x62\x80\xe1\x61\xf1\xfb\xc4\xa9\x20\x88\xc8\x52\x77\x0e\x57\x47\x76\x3a\xbf\xf3\x8d\x0b\x22\x01\x2f\x55\x20\x8e\xdf\xb4\x51\x82\x94\xbe\xd5\xd8\x5f\xbf\x5e\x5e\xf0\x23\xae\xd3\xad\xa0\x11\xcb\x5d\x3d\x20\xa3\x3b\xee\x5d\x14\xc1\x3f\x9a\x66\x29\xe6\xbf\x99\x25\xd9\x43\x1f\xbe\x15\x94\x27\x48\x6b\x02\xa3\x4f\x37\xbe\x70\xc5\xf4\x83\xc2\xd8\x96\xe6\x64\xe7\xf3\x16\x8c\x7c\xd3\xb5\x83\xfd\x3b\x08\xae\x88\x42\x6a\x83\xaf\xb5\xae\x6c\xb7\x2d\xa8\x9f\xea\xaf\x15\x26\xd4\x4e\x4a\x8e\x10\x11\xb1\x00\x33\xcb\x85\x4d\x13\x74\x4a\x20\x09\x82\x56\xa7\xc1\x6c\xbd\x63\x92\x70\x32\x06\xba\x8e\xdf\x3d\x8e\x42\x44\xdf\x63\xbe\xf5\x53\x0d\x4f\x55\x79\x31\x9b\x87\x36\xc6\x3c\x34\x27\x62\x4e\x6d\x88\x5d\x9f\xce\xe6\x09\xcb\x71\x9b\xe6\x7f\x67\xc4\xa9\x05\x22\x89\x44\xdf\xc7\xe4\xc7\xe7\x3e\xfb\x4c\x24\x79\x84\x46\x3d\xaf\x59\x25\x7b\xf5\x62\xfa\x8c\x84\x49\xb4\x29\xc7\x1d\x07\x3e\xd8\xaf\x44\x11\x1b\xe4\x70\xe6\xc1\x73\x57\x2d\x2f\x63\x27\xe1\x54\x75\x16\xa9\xb0\xc9\x6f\xae\x53\xce\x43\x51\x02\x33\x67\x83\x79\xa5\x36\xbb\xae\x1a\x8b\x2c\x8c\xb1\x66\x89\x0d\x57\xd8\x4a\x7f\xef\xb3\x10\x44\x26\x72\x19\x4d\x1c\xea\x36\x0f\x7b\x38\x26\x22\x4f\x24\x06\x85\xff\x05\x5d\xb3\x3d\x16\x50\xca\x91\xb5\x20\x18\x91\xa9\xef\x17\x8f\x9f\xaf\xeb\xd3\x08\x42\x20\x78\xd0\xe7\xf4\x7e\x87\xe2\x70\x6c\xc1\x42\x1a\x5d\x47\x94\xd9\x5b\xf3\x90\xdb\x5c\xfa\x23\x88\x97\xcf\x1a\x4b\x63\x8e\x90\xe7\x82\x27\x21\xee\x12\xab\x6b\x76\xc1\x42\x10\x4f\x5d\xfb\xa4\x96\xba\xab\x64\x73\x73\xa9\xd8\xa9\x10\xb3\xcd\x11\xc0\x43\x57\xfe\x65\xfd\xe3\x5c\xcc\x91\x07\x42\x8a\x30\x75\x2f\xb8\x5a\x2e\x46\xde\xa6\x07\x68\x1a\x5c\x6b\xc4\xb2\x4d\xb7\x05\x62\x40\x9d\x10\x7d\x6c\x2b\x7d\xe2\x45\x05\x72\xac\x1a\x0a\x48\x48\x32\x38\xfb\xdf\xa0\xb8\x52\xf5\x8b\x08\xa5\x88\xcf\xee\xf6\x00\xe6\xde\x30\x75\xe8\x98\x51\x81\x2e\x33\x9f\x91\x31\xb0\xef\x7b\xd1\x1e\xed\x86\x4d\xee\x2b\x83\x9c\x85\xc2\xc3\xcb\x6d\xa5\x25\x43\xd3\xb3\x49\x4c\xb8\x88\x16\x4a\xf7\x9f\x74\xdf\x25\x92\x88\x14\x5d\x47\xcb\xdd\x6a\xbb\x5f\xef\xbe\xac\x9f\x87\xb6\xcf\x44\x52\x1a\x7a\xdc\xce\x1e\xab\x0c\x16\x20\xf7\x6f\xd0\x1e\xf7\x57\xd1\xce\x92\x4a\x8e\xf9\x3c\xae\xc3\xc6\x6f\x97\x59\xe6\x98\x8c\x68\x6a\x0b\x15\x1c\x8b\xa6\x68\x58\xd9\x68\x55\xcc\x8a\x2d\x9b\x49\x2c\xb7\x9d\x6c\x75\x83\xcd\xc7\x2b\xf8\xc0\x41\x23\xa3\x3c\x50\x72\x54\x5c\xce\x29\x9b\x5b\xe7\x93\xfc\x5f\x95\x4e\x7f\x57\xc5\xf1\x2d\x91\x0a\x7e\x03\x38\xf7\xdc\x4e\xc6\x84\x38\x3d\xd0\x56\xfd\xbd\xa2\xd2\xc8\x58\xd8\x4a\x8e\x07\x38\xad\xea\xa2\x2d\x04\x2b\x9f\xad\xe3\xe3\x15\xea\xa1\x24\x17\x91\x09\x84\xe8\x92\xeb\x2a\x07\xc0\xfc\xc0\x67\x25\x53\xe7\xb3\x62\x25\x16\x2a\x1a\x2a\xb1\x4c\xdf\x3b\x23\x04\xd3\x7c\x98\xcb\x36\x44\x2d\xbd\xd0\xd5\x90\x83\x84\x8d\xc6\x46\x80\xb2\xf7\x39\x87\x32\x23\xcc\x16\xa1\x2f\x0b\x31\x06\x9f\x8f\xbb\xde\x13\x99\xa5\xc4\x85\x5d\xcf\x25\x13\x30\x73\xfc\xcd\x88\x2c\x13\x80\x86\xd1\x6f\x67\x7d\xc6\x96\x15\x7e\x01\xf2\x80\xf3\x69\x7c\xd7\xb0\xcc\x07\xf6\x63\x5a\x0c\x89\xc8\x9c\xda\xa2\x74\x5d\xd5\xe8\x52\x3a\xe7\xba\xae\xfc\x3e\xcb\x7e\x5e\xaa\x82\xcc\x9f\x4e\x5b\xf9\xf1\x2a\xa8\x4a\xe6\x99\x44\x7b\xc7\xba\xb1\x9a\x1b\xa8\x8a\xe1\x2e\x2c\xb4\xa9\xfa\xfb\x06\xda\x0d\xd4\xbe\x90\xda\x9c\x98\xa6\x3d\x1e\x46\x1a\x88\x64\x69\xe8\x42\x68\x78\x0e\x3c\x0d\x8f\xd4\x1a\xc9\xd2\xbe\xcc\xeb\x92\x55\x2f\x8f\xef\x3c\xf4\x92\x27\x04\xbb\x68\x7f\x59\x3c\xdf\x98\x43\xb9\x5f\x7f\x7d\xf6\x6f\xc8\xa5\xc2\xd7\x47\x70\xdf\xe2\x83\xc4\x17\x29\x73\x5b\x84\x46\xe9\x5a\x80\x87\xe2\xf4\x5f\x29\x19\x0d\x86\xae\xb4\x1e\x61\x32\xbb\x83\xc8\x63\x67\x72\xee\x58\x7d\x00\xab\x40\x4f\x60\xc0\x52\x2a\x96\xdb\x33\xa8\xa0\x66\x25\x16\x9b\x9f\x68\x2b\x12\x52\x46\x86\x04\x1c\x9b\x07\xf1\x38\x2a\x9d\x36\x3d\x3e\x00\x01\xed\x4b\xbf\x9c\xb8\xd5\xef\x67\xef\xa5\x92\x2c\x1b\x97\x87\xf1\x46\x40\x37\x4a\x24\x92\x2a\x55\x08\x5f\xf6\x06\x8a\x6d\x30\x00\x72\x77\xac\x75\x05\x1f\x94\xd7\xbf\xba\x92\x10\x70\x86\x80\x49\x8b\xc1\xb3\xda\x82\x6d\x8e\x35\x9d\x47\x88\x40\x2f\xfd\x16\xca\x71\x9d\x4c\x02\x84\x0b\x95\x3a\x0c\xf9\x9d\xd0\xb6\x42\x6d\x3f\x28\x32\x94\xa5\xa7\xa2\xfa\x0e\xc5\x58\xdc\x00\x91\x84\xf4\xbd\x58\x50\x13\x6a\xfa\x21\x10\x3c\x9a\x27\xb0\x2e\x2a\x89\x95\x82\x6f\x75\xbd\xf6\x3d\x4b\x46\x45\x34\x20\x0c\x18\x7a\xd0\x78\x71\x18\xdb\xd1\x28\x68\xfb\x39\x61\x82\xba\x8c\x87\xde\x5d\x6f\x2a\x36\xfd\xf0\x30\x0a\xa5\x2b\x54\xf0\xa4\x54\x03\x33\x81\x08\xa1\x0c\xa3\x51\x3f\x7e\x5b\xc7\xf8\x6a\xc3\x2a\x33\x37\x25\x99\x57\xbb\x5a\x7d\x9d\xf5\x43\x14\xa8\xd8\xf9\xf1\x6f\x01\xbe\x17\x95\xd4\x6f\x98\xa2\x82\x74\x3a\x59\xc4\x28\x8d\x90\xfe\xd6\x7c\xb4\x7c\x11\xe3\x3d\x26\x75\x6e\x1e\xfc\x3a\x85\xc8\xb9\x2b\xe2\x24\x27\x83\x1f\xfb\x4a\x59\xd0\x0f\xc5\xcc\xe4\x60\x43\x9c\x08\x6b\x37\xb4\xfa\x6c\xcb\x36\xf6\x2f\x15\xa7\x0c\xe1\x20\xb2\x3f\x5e\x10\x33\xe6\x4b\xb2\xdf\x35\x4d\x07\x35\xf6\x07\x9e\xaa\xf4\x90\x64\x02\x8b\xc4\xb7\xc5\x09\x9a\x96\x9d\xce\xfb\x53\xe3\xa3\x9c\x90\xb0\x14\xfd\x46\xeb\xf6\x88\xc7\xf2\xae\x7a\xd5\xc5\x1c\x2b\x06\x69\xc8\x53\x8b\xc9\x2b\x5f\xbe\xe9\x77\xad\xf2\x08\xa4\x0a\xd0\x49\xcd\xa4\xc4\x66\x85\x36\x76\xfc\xc1\xee\x64\x19\x0d\x1c\xcc\xcd\xb1\xcf\x99\x4c\x83\x8c\x27\x38\x03\x73\x75\xf7\xdb\xf5\xea\xe9\xf1\x66\xbf\xfe\x7d\xf5\x65\xf1\xf8\x79\xbd\x7f\x5e\xec\xbc\x9d\x05\x39\xc9\x50\x15\xbd\x59\xaf\xae\xe6\x9f\x8e\xb9\x07\xb0\x84\xa6\xa3\xbe\x7b\x16\xa0\x3d\x55\x56\x66\xdb\xc1\x13\x85\xe5\xfc\x4e\xae\xaa\x73\xef\xcf\xf1\xe3\xc2\x76\xed\x39\x63\x3d\x23\x26\xe7\x4d\xc1\xcc\x0c\x81\xbe\x1e\xac\xc7\x85\x2d\x04\xe6\xf8\x63\xe0\x32\xc4\x08\xae\xed\x08\xb9\x1f\xe5\x25\x81\xb1\x70\xa9\xad\xda\xda\x95\x45\x8f\x6c\x02\x11\xa4\xb9\x05\x70\x6b\x55\xb4\xcd\xbb\x5b\x0a\x92\x20\xec\xe4\xb9\x2b\xa1\x71\x21\xd2\x49\x11\x92\x3f\xe1\x69\xc2\xa5\x76\x9f\x40\xb2\xf2\x86\xb5\x6c\x56\xb1\x06\x04\x13\x18\x7a\xb1\x32\xf2\xe9\xdb\x6a\x03\xd3\xc6\x5a\x6e\x9e\x4c\x15\x6a\x27\x03\x1a\xe3\xe7\x29\x42\x20\x39\xc1\x7c\x09\xc9\x2e\x77\xd2\xa3\x08\x41\x25\x02\xa5\x2e\x93\xf2\xef\x9a\xfb\x97\xb9\x05\x90\x7d\x41\xd1\x79\xd2\xb1\xbf\x32\x8d\x50\x29\xb3\xb0\xdb\xbd\x8d\xf4\x34\x7b\x36\x0b\x05\x81\xe2\x89\x70\x38\x19\xc4\x7e\x0f\x9d\x6d\x89\xa2\x8c\x0a\xd7\xbf\xf7\x56\xd7\xcb\x56\xfc\x6f\x2e\x6e\x15\x05\x2c\x8b\x7d\xe7\xfa\x5e\x7d\xb9\x7a\x38\x54\x9c\x4b\x8c\x78\x9e\xd8\x8f\xc1\x37\xab\x62\xa6\x7c\xb6\xcd\xdf\x35\xdf\x9e\x75\xd5\x68\x1b\xa4\xf8\x09\xbd\xab\x44\x32\x04\xad\xd4\xbe\xe6\xfb\x5e\xe9\x7a\x4c\x5f\x2a\x81\x04\x9d\x7d\xac\x29\x0e\x15\xab\x6f\xaa\x62\xba\x7f\x2a\xcd\x94\xaf\x82\x77\x5b\x03\xac\xbe\xdc\xad\x86\xf4\x79\x95\x42\x94\xb3\x89\x37\xc5\x21\xc2\xdf\xa1\x46\xdc\x05\x19\x71\xce\x73\x63\xc7\x2f\x6b\xfd\x32\xf6\x40\xab\x2c\x89\x85\xc3\x3d\x7c\x54\x98\x48\x65\xb9\x44\xcd\xe7\xec\x96\x11\x8b\x45\x35\x4f\xca\x15\x01\x9c\xcd\xce\x73\x86\x39\xab\x25\xa8\x36\x9f\x8f\xb1\x80\xb9\x8a\x80\x4f\xae\x26\x1d\xa6\x0e\x3d\xb0\x1f\xef\x8b\xc0\x28\x16\x42\xec\x0a\x33\x6c\x35\xc2\x86\x3f\x54\x93\x15\xe3\xd2\x97\x90\xf4\x55\xf7\xe6\x4e\x58\xc5\xa0\xcf\xb2\x71\xdd\x01\xa6\xed\x92\x89\xe2\x4c\x21\xdc\x1e\xc5\xfb\x3d\xab\x61\x3b\x14\x07\x50\x22\xce\xa1\x6f\x55\x77\x37\x73\x4b\x29\x01\x34\x75\x72\x01\x2b\xc1\xfa\xab\x24\xe1\xc4\x81\x01\x58\x59\xfc\x61\x8b\x0e\xb3\xa2\xfc\xa2\xf5\x4b\x3f\x27\xcb\x99\x33\x4f\x6f\x4b\x76\x68\xbc\xd5\xee\x86\x21\x8c\x30\xea\xb4\xfe\xbe\x82\xba\x2d\x94\xcb\x57\x5d\x41\xd5\xc2\xbc\x11\xf0\x84\x18\x01\xc0\x27\x04\xec\x8a\xb6\x84\x1b\x0c\xde\x4d\xdf\x5b\x25\x14\x1b\xa4\x20\x48\x50\x40\x5d\xbd\x6f\xf6\xe4\x67\x66\xb9\x77\x31\x6c\x74\xdd\x2a\x5d\x0e\x3d\xb9\xe7\x53\x85\x05\xa1\x36\xdd\xf9\xac\xeb\xb6\xc1\x0c\x0d\xc5\xbc\x01\x63\x35\x42\x1a\x04\x9c\x04\x72\x88\xeb\x80\xd5\x95\x1c\xc7\xa5\x01\xe1\xb1\x8c\x47\xfe\x9e\xa7\xd7\x3e\x00\x7c\x8b\xa0\x9b\x9f\xe9\x40\x34\x20\x40\x91\x7c\xbe\x1f\xf5\x17\x5d\xca\x66\xc3\x5a\x87\xc4\x18\xaf\x00\x0d\xa8\xb2\xe9\x62\xc6\x4c\x7b\xeb\x93\xee\x76\x7a\x42\x3d\x34\x08\x43\xe2\xcb\xcc\xde\x1a\xae\x3c\xee\xfd\x40\x83\x30\xce\x11\xab\xec\xcf\xc8\x6f\x45\x75\x90\x7a\x16\x13\x1e\x6c\x12\x1a\x44\x82\x60\x82\x80\x61\x3a\x4c\x82\xee\xb0\xbd\x44\x51\x7a\x46\x41\x83\x48\x06\xca\x1a\x59\x46\xc9\xc7\x18\xe9\xd0\xa7\x89\x06\x71\x4c\xd0\xe7\xb8\x28\xe1\x07\xf3\x3f\x26\xa1\x44\x21\x25\x58\x29\x1e\xd8\x8f\x49\x08\x98\x06\x49\x14\x52\x69\xab\x2a\xfd\x30\x04\xd4\xfb\x97\xcc\x10\xc7\x56\x26\x42\x57\x4d\x57\xee\x47\xc5\x80\x68\x90\xc4\x0a\xdb\x7a\x15\xcd\xbd\x66\xd8\xf8\xd7\x5b\x2d\x34\x48\x52\x48\x5c\x99\xff\xd1\x49\xa2\x41\x22\x01\xb3\x64\xba\xaa\x68\x1b\x04\x14\xdd\xea\xda\x57\xb0\xb2\x39\x49\x87\xe1\x01\x90\xba\x22\xcd\x42\x4b\xd8\xb0\x9a\x9d\x66\x0e\x46\x1a\xa4\x34\x4e\x73\xdf\x28\x11\xf3\x44\xfb\xd8\x21\x0d\xd2\x8c\x60\xfc\xb7\xab\x78\x67\x28\x78\x77\x39\x4f\xea\x39\xd1\x20\x05\x89\xd5\x17\x1e\x9f\xbe\x2d\xfe\xb4\x60\x06\x0d\xb2\x10\x30\x8b\xe7\x79\xed\x5b\xea\xd2\x20\x0f\x01\x4b\x42\xba\x93\x0c\xb4\x1f\x48\x18\x6a\x24\x36\xd7\xa9\x59\x5e\xec\x77\x8a\xcb\xec\x13\xf2\xdc\xee\x98\xed\xac\x55\x34\xfd\xf7\xe7\x2a\xcf\x6c\xa1\x93\x53\x51\xf5\x2d\xde\x68\xc0\x02\xa5\xe2\xbe\xcf\x45\x71\x9a\x34\x0b\xf1\x73\x04\xc7\x0d\xc0\x1a\x4e\x64\x39\xd4\x25\xa5\x01\x97\x2a\x8e\x06\x41\xb2\x6d\xeb\xe2\x7c\x1e\x9d\x2f\x19\x06\x99\xec\x45\x89\xab\xcc\x77\xbd\x00\x10\x0d\x64\x64\x5d\xdc\x4f\xa7\xd3\xa4\x38\x33\x0d\x24\x64\xa9\x67\xab\xcc\x4a\x97\x67\x36\x03\x4c\xd1\x40\xaa\x20\x1a\xaa\xd4\x2d\x59\xbd\xd2\x12\x66\x27\x51\xaa\xdc\x77\xd5\x76\x81\x05\x97\x73\x5a\xcf\xce\x22\x50\x19\x39\xcd\x01\xd5\xef\x2f\xac\x39\xde\x17\xbc\xbe\xcc\x6e\x08\x3c\x81\x01\xa4\xf1\x5d\xd7\x2f\x93\x24\xb3\x5f\xbb\x11\xac\x9c\x06\x2a\xcb\x51\xb4\x1e\x2f\xbc\x2e\xa4\xe3\xd5\xef\x71\xfb\x94\x04\x32\xf5\x28\xa8\x07\x5b\xb8\xc6\xad\x05\x21\x11\x21\xa4\xe7\x25\x3e\x78\xe5\x07\x45\x84\x56\x81\xf3\x78\x8e\x17\x91\x50\x69\xe3\x93\x67\x76\x59\x5e\xae\x14\xff\xa5\x84\x2a\x89\x9d\xa9\x5c\xb6\x9b\x4d\x7d\x7b\x66\xe7\x42\xa2\x1d\xea\x6f\x14\x46\xb6\x95\x9c\xd5\x12\xff\xa5\x4f\xbc\xb0\x8e\xa7\x99\x38\xa4\x24\x8c\xe3\xd0\x3b\x45\x8b\xea\x3f\x6c\xf6\xbc\x30\x8b\x13\x97\x14\xf4\xe4\xd1\x69\x94\x44\x81\x2d\x0c\x86\x45\x74\xf5\x97\xce\xbc\x4c\x33\xf9\x92\xc8\x35\x28\x3a\x63\x57\xc7\xdb\xa2\x2a\x9a\xe3\xce\xdb\x41\x7e\x52\xa2\x62\xdb\xd3\xd4\xb1\x5b\x5b\x4e\xeb\xdd\x2b\xa6\x04\x50\x27\x2e\x8d\x11\xb9\xd2\x55\xd3\xb2\xaa\xff\xd2\x94\xda\x0e\xc7\xae\xb9\x96\xd5\xb5\xdf\x8b\x41\x4a\xd2\x98\x83\x37\x86\xff\x98\x3f\x22\x63\x44\xf4\xc0\xcf\xfa\x8a\x87\xea\x3d\xef\x26\x79\xc0\x2c\x7e\xdf\xec\xf2\x33\x88\xae\x36\x33\x96\x45\x59\x16\xd5\xa1\xcf\x46\xfc\x5f\x14\x56\x4a\xf2\x34\xc7\xf7\x78\x2b\xc5\x44\xef\xa7\x24\xcf\x09\x38\x67\xf4\x12\xda\x66\x0c\x64\xa0\x84\x11\x22\x83\xbe\x41\xa1\x6d\x21\xbb\x7a\xba\x7e\x86\x09\x67\xb6\x18\xd7\xea\x7e\xf1\x7d\xb9\x58\xfd\x36\x81\xa7\x52\xc2\x79\x1e\xa5\xae\xb8\x2a\x56\x37\xbd\x13\xba\x1f\x13\x79\x1a\x79\xe5\x67\xa3\x75\x39\xf1\x29\x51\x22\xc2\x00\xcf\x0e\x66\xcb\x2c\x67\x2d\x87\xb2\x79\xbd\x18\x4a\x44\x64\xb3\xb9\x1f\x97\xff\xec\x6f\x91\xda\x62\x27\x18\xd5\x6a\xce\x18\x08\xbb\x93\xb3\xed\x92\xcc\x96\x61\x2f\xaa\x62\x54\x99\xea\xa3\x25\xbe\xbe\x0c\x52\x50\x25\xbc\x7d\x82\x89\x0d\xd5\xc1\x95\x78\xe8\x2b\xb5\x53\x22\x65\x66\x8b\xbd\x99\x2f\x7e\xd4\xad\x5b\xf7\xab\xba\x86\xb1\xc6\xd1\xdc\xc0\xe2\x4a\x8b\xd5\x6e\xbf\xb8\xbf\x7f\xfa\x3e\x94\xc3\xa0\x04\x58\x84\xae\x3b\x54\xc3\x77\x45\x89\x58\x1a\xec\x54\x5e\x54\x07\x8c\x4c\x21\x33\x1a\xe1\xff\xc6\x14\x07\x0a\x3c\x1e\x65\xc3\xde\xaa\xf7\xb5\x93\x29\x51\x41\x88\xc7\x61\x6f\x54\xe0\x06\x75\xdc\x0f\x5e\x56\x85\x09\x1b\x9c\xad\xcf\xd0\xe8\xae\x16\x33\x5e\x4c\x14\xc4\xc8\x6e\xbe\x7d\xdd\xd8\x30\x2c\xc8\x5b\x5d\x9b\xf5\xb9\x7a\x53\x1a\x24\x04\x0b\x7f\xb5\x85\x31\xb7\xef\x59\xd3\x6e\x3a\x5e\x16\x8d\x73\x9c\x50\x1a\xa4\x39\x76\x9b\x05\x71\xea\x4a\xc4\xc2\xfc\x69\xba\xc7\xfc\x11\x2c\x46\x9a\xb1\x5d\x2b\xd9\xb4\x60\x07\xa5\x81\xb2\x05\x4a\x99\x94\x1b\x5d\x16\xe2\x32\x24\xa5\x77\xef\x7a\x00\x39\x3a\xa4\x24\x08\x33\xdb\xaa\xea\xf2\xf4\xbe\x6e\x92\x9f\x94\x31\x69\xab\x52\x35\x4b\x36\xcd\xfe\xa6\x94\x28\xdb\x8b\x72\xe9\x6b\x09\x94\xfe\x8b\xa9\xb2\xad\x56\x36\xfa\x7c\xbe\xf8\x1f\xc3\x4c\x60\x5c\x7e\xef\xab\x85\xdf\xc0\x6b\x31\x5f\x7d\x1a\x66\x80\x36\xa0\xad\x10\x56\xc1\x5b\x3d\x78\x04\x29\x8d\xa4\x20\x23\x5f\xcd\xe2\x7e\x4d\xf6\x9b\xe7\x75\x3f\x0c\x56\xfb\x96\xf0\x7a\x0b\xbd\x6c\xa2\x71\x96\xa2\x41\x5b\x69\xe9\xf3\x71\x46\x99\xcb\x94\xc6\x39\x0f\xdc\xf9\xdb\x2c\x77\xbb\x5b\x5d\xcf\x63\x59\x94\x26\x54\x80\xf4\xe8\x01\x84\xa7\xf9\xe2\x9a\xb3\x55\x49\xa2\x00\xcd\x1e\xec\x0a\xb4\x83\x09\xa0\xcb\x8c\xf2\xc4\x25\xc3\x63\xad\x83\x9f\x76\xc1\xa0\x34\x61\x16\x46\x71\x86\xf6\xa9\xb2\x41\x59\xde\xc7\x97\x9d\x7f\x99\xd2\x04\xac\x52\x60\xc9\x7a\x84\x57\x9f\xbd\x5a\x16\xc7\x38\xef\x96\xd5\xa7\x2f\xfa\x0c\x9b\x5a\xff\x07\xc4\xb8\x3b\x31\xa5\x19\x04\x08\x6b\x79\x43\xf0\x9d\xb1\xb2\x87\x3e\x03\x6e\x4a\x4e\x22\x5c\x65\xfc\xc2\x66\xf6\x8c\x3c\x8f\xf2\x01\x25\x71\xb7\x7a\x72\xd5\xa9\xfc\x30\xf3\xf9\xd1\xcd\x49\x8f\xd4\x70\x9a\x73\x8a\xde\x45\x4c\xab\x35\x1b\xdb\x0f\x08\x5b\x9a\xde\xdb\x27\xae\x4f\xd7\x2d\xc0\xcf\xfb\xf4\x8e\x69\x3d\x87\x08\x3f\xdc\x75\xa7\x7b\xe8\xca\x6d\x71\x98\x20\xf1\x29\xe5\x69\x14\x3a\x9b\xfb\xd3\x95\xf2\x4c\x7e\x56\x66\xdd\xd6\x07\x68\xef\xa4\x5b\xbf\xfe\x0e\xb9\x2d\xd1\xfd\xd9\x28\x47\x53\x29\x41\xb9\x48\x89\x4f\x78\x84\x1f\x18\x33\xdd\x16\xbc\x1c\x49\x5d\x3f\x51\x52\x6c\x22\x78\xbc\x9c\x61\x4e\x83\x82\xc6\xd8\x0c\xe4\x0c\xd8\xe2\xc0\xba\xda\xe6\x1b\x20\x98\x85\x1f\x9a\xc5\xfd\x56\xc0\xdb\x64\x77\x81\x58\x34\xd6\xd7\xed\x72\xbd\xbe\xed\x7f\x15\xf9\x08\xd9\xe2\xea\x79\x5f\xe7\x44\x20\xa5\x2f\xed\x65\xeb\x1c\xaf\x7a\x8c\xa0\x9b\xa1\x44\x96\x8d\xca\x0f\x4d\x7d\xf6\x93\x9b\x85\x41\x60\x9d\xc5\xce\x58\x7b\xb6\xf1\x03\x7f\xd8\xc3\x80\x05\xa9\x18\xe2\x0a\xc6\x86\x9f\x2e\x56\x18\xc8\x0c\x7d\xac\x6d\x01\xf5\xee\x58\x3b\xf5\xdb\x0d\xd2\x9c\xd1\xdc\x53\xd4\x80\x37\xa0\x61\x98\x26\xa8\x6c\x4b\xd7\x9a\xe1\x6e\x73\xbb\xc5\xd4\x53\x3f\x2e\xf3\xc8\xd9\xbb\xb6\x1e\x64\xb3\xbc\xa0\x7e\x3f\x5d\xe9\xd0\x68\x84\x43\x77\xae\x6f\x45\xc3\xfa\x4a\xaa\x57\x17\x2f\x8c\x93\x1c\x9d\x40\x0f\xba\x2a\x46\xb4\x1f\xc6\x09\x88\xa0\x87\x52\xac\x74\x77\x1e\x05\xf9\xa6\x5f\x1c\x67\x29\x3a\xc7\x7f\xbf\xbd\xff\x89\x37\x8e\x86\x71\x6e\x7d\xc9\xfe\x8d\x30\xd5\xf4\x5d\xf1\x2b\x37\x39\x21\xb6\xfa\x91\x8d\xed\x94\xe5\xd8\x44\x0d\x13\xce\x63\x36\xe0\x56\xaf\x95\xac\xa3\x61\x0a\x8a\x50\x6f\xa3\xba\x50\xce\x58\xa7\x08\xb3\x34\x4d\x9d\x6e\xbc\x1a\xf5\x09\x76\x3d\x0c\xc6\x07\x31\xcc\x78\x8c\xab\xd4\x42\xd3\x0e\x9d\xb1\xfb\xc1\x14\x77\x1c\x2a\x6c\xdd\xdc\xc7\xae\x68\x98\x47\x99\xc7\x89\x18\x19\x8c\xf1\xc1\x2f\x08\x08\xe9\x67\xc4\xb6\xde\x5f\x79\x16\xfe\x27\x96\x50\x3c\x51\xb5\x99\x47\xc8\xf4\xbc\x85\x9c\xa7\x48\x08\x37\x8b\xdd\xda\x88\x19\xc3\x96\x6c\x52\x97\xbf\x5e\x90\x1c\xf1\x49\x0f\x97\xef\x45\x73\x1c\xe5\x82\xd2\x50\x50\x1b\x88\xc2\x82\x12\x7f\xcc\x0c\xa9\x50\x24\x41\xd4\x57\xd4\x14\x1e\xb0\x68\x7e\x27\x58\x99\x0b\xdd\x10\x7b\x76\xe8\x01\x9a\x34\x14\x19\x07\xea\x1d\x96\xbe\x16\xc5\xcf\x22\x0a\x34\x94\x89\xc0\x84\x97\xe7\xf5\xe6\x69\xbf\xd8\x6c\xf6\x8f\x8b\x07\xcf\x58\x43\x20\xae\xe4\xa7\x2f\xdc\x34\x8e\xc3\x8d\x5a\x20\xfa\xe9\x61\x82\x9d\x4f\x2b\xec\x13\xb8\x62\x4d\xff\x62\xa0\x94\x6f\xfb\x8f\xe0\xcd\xee\xc3\x72\x76\x34\x54\x11\x41\x4d\x1b\x49\xad\x7f\xe0\x70\xe6\x55\x64\xf1\xec\xe8\xbd\xde\x69\x87\x4e\x9c\x2d\x9e\x62\x52\x3a\x18\xe1\x33\x56\x48\x05\x89\x41\x33\x3b\x1c\x05\x41\x86\xbd\x34\xce\x4e\x0d\xb3\xfe\x2a\xea\x47\x23\x0e\x30\x6d\x57\xdd\x57\x12\x31\xa3\x4a\x70\x6b\xfb\x2d\x59\xc5\x3c\x42\x80\x46\x01\xe3\xa1\x2d\x1b\x6d\xcc\xba\x67\xdb\x93\xae\xef\x4b\x4a\xa3\x40\x72\x14\x1f\xe3\xec\xc2\xc8\x0f\x92\xc0\x96\xbd\x28\xb0\x01\xc6\x8c\xcf\x45\x24\x8d\xf0\x6c\xf8\x9a\xd8\xcb\xdd\xea\x3a\xc3\x8c\x48\x96\x32\x57\x3c\x48\xea\xb7\xe0\x5d\x2b\x1c\x1a\x11\xc5\x9d\x43\x05\x59\xc9\xb1\x28\x8d\xf2\x6a\xab\x35\x3d\xc2\xb4\x8e\x11\x8d\x28\x11\x28\xc9\xb7\x4c\xca\x12\x6e\xb7\xd3\x75\x8e\x68\x42\xb1\xc2\x82\xd5\x2b\x1e\xba\xb2\x2d\x9a\x41\x6e\xce\x6e\xc5\x62\x6b\x5a\x40\xd3\x3e\x83\xd0\xaf\x30\xf8\x24\x7e\xfd\x09\x45\x44\x94\x33\xcc\xff\xbb\x7d\x1a\x4b\xaa\x88\x8a\x08\x75\xb6\xd5\xb8\xd3\xda\xbb\x6a\x8d\xa3\x77\x95\xc0\xb3\x11\x00\x07\x8d\xd1\x13\xc8\x82\xcd\x12\x41\x69\x44\x15\xc1\x78\xd5\x6e\xe2\x08\x8c\xa8\x0a\xbd\x6f\x03\xc3\x8e\xfd\xcf\x02\x95\xeb\x57\xdd\xc2\xe3\xa4\x8e\x1e\x8d\x42\x12\x51\xa7\x78\x6f\xbb\x33\xd4\x36\x05\xe3\x3a\xeb\x8e\xc2\x50\x62\xb1\xa4\xaa\x3b\xed\x8f\xe3\x14\x41\x1a\x85\xa9\x75\x83\xd9\x0c\x80\xb1\x0f\xe9\xba\x41\x10\x85\x8c\x11\x3e\xc1\xab\x3c\xf2\xf1\x4b\x47\xa1\xf5\xc6\xe8\x0a\x5c\xb5\x07\x87\x0e\xf3\xe3\x9c\x21\xdf\xfb\xd2\xf1\x3e\x2c\x45\xa3\x08\x2c\x8d\x9b\x3d\x44\x3f\xf3\xa2\x76\xd9\x03\x37\x9d\xf9\xea\xa1\x2f\x0e\x8d\x62\x61\x4b\x20\x16\xa7\xb3\xae\xdb\x2d\xfc\xb7\x83\x41\xdd\x89\x92\x40\x12\xf0\x6d\x4a\x6d\x3e\xe4\x73\x9f\x34\xfb\x0e\x73\x3b\xfd\xb6\x34\xb2\x51\xf7\x33\xbb\x48\x76\xb9\xad\xed\xad\x2f\x77\xd5\x0d\xbb\xf4\x2b\x96\x46\x02\x15\x99\xd3\xc5\xa6\x92\xcf\x9d\xd6\x51\x0a\x01\x92\x55\xd3\x71\xc4\x6e\xda\x41\x9f\xcd\x81\x01\xb7\xeb\x84\x94\x05\x81\x72\x92\x0a\x83\x4b\x50\x0c\xa1\x10\x1a\x65\x71\xc6\xc9\x38\xf4\x2e\xdf\x75\x51\xfc\xb9\x0d\x1e\xe5\xc4\x42\xde\xad\x1f\xe9\x5e\xb7\xed\x58\x0f\x8e\x72\x48\x70\x67\x56\x5a\xc2\x03\x2b\x8c\x2c\xee\x9d\x47\x11\x8b\xad\xfd\x6a\x36\xe8\xae\x99\x2b\xe6\x11\x93\x1c\x01\x2b\xf7\xfa\x60\x53\xf4\xdf\x8a\x56\x1c\xc7\xde\xe9\x48\x44\x24\xb7\x8d\x66\xa4\xed\x7f\xfa\x01\x56\x8a\x46\x22\xb1\xc5\x04\x96\x4f\x8f\x5f\xb7\xfb\xbb\xd5\xd3\xfe\xfb\x7a\xfd\xdb\x7e\xf7\xdd\x4b\xdc\x48\xa4\x49\xa4\x7a\xd8\x71\x59\x02\xb6\x7a\xd0\xa5\xd4\x6f\xd5\xbb\xa0\x16\x8d\x84\x08\x6c\x35\x64\xd4\x32\x9f\x41\x14\xe7\xe2\xff\xd1\xf6\x66\xcd\x8d\xe3\xd6\x1f\xe8\x77\xf9\x3f\xcd\x43\x1e\x48\x2c\x24\x78\xdf\x64\x5b\xee\x76\xc6\x5b\x2c\x75\xf7\x4c\x52\x29\x15\x96\x03\x9b\x31\x45\x2a\x24\x65\xb7\xe7\xd3\xdf\xe2\x01\xc0\x4d\x94\x67\x72\xab\x6e\x1e\xd2\x53\x26\x44\x51\x24\x08\x9c\xe5\xb7\x04\x04\xf8\xac\xe2\x34\xa5\x91\xfb\xcf\x1b\x03\xce\x1c\xb6\xae\xab\x7a\x14\xcf\x31\x30\xae\x03\xa6\x8e\x1f\x5f\xa1\xae\x66\x5f\x6b\xb5\x4e\x74\xdf\xf0\xf6\xaa\x0c\xe1\x27\x58\x93\x20\xc6\x0c\xb7\x61\xbc\x9f\xfd\x81\x0c\x03\x9a\x2f\x63\x79\x08\xc2\xa3\x48\xa0\xdf\x89\x3a\x7e\x5c\x75\xdb\xa3\xae\xf2\xb2\x59\x3d\xcb\xbc\x44\xcd\xab\xbe\x80\xcd\x23\xe2\x7a\x9d\xee\xc7\xae\xf7\x87\xa2\xfa\x80\x65\x5e\x62\x37\x38\x15\xdd\x32\x7c\x7d\xb5\xfd\xf3\x0a\x3d\x8f\x94\x21\x53\x55\x69\x84\x30\x4d\xc6\x90\x58\x61\x63\xb7\x91\x6f\xb0\xfd\xd9\xce\x0e\x26\x0e\x28\xad\x1c\xf5\x04\xab\x15\xfa\x57\x98\x15\xed\x39\x51\x59\x86\xa1\x3e\x2a\x9d\x4c\x84\xd4\x08\xa7\x31\x45\xcb\x96\x43\x5d\xfd\x74\x2c\xb6\xfe\x88\xcc\x02\x2f\xe2\x4e\xfe\xbc\x83\xfa\x79\xf8\x10\x64\x94\x87\x26\xa8\x71\x0e\xbc\x0e\xc2\xe5\x64\xe1\x66\x17\x40\xad\x72\x12\xb4\xd5\xfe\x5a\xaa\x70\x12\x16\x31\x04\x14\xbb\x9e\xc3\x93\xcc\x1b\x30\xbd\x98\x37\xe1\x8c\x92\x80\xc6\x0d\x94\x39\x4c\xc0\x1f\xac\xed\x87\x08\x81\x31\xc6\xf6\x61\xbb\xba\x1d\x50\xa6\x5d\x72\x25\x99\x4b\x4e\xf7\xfb\xaa\xec\x45\x24\x09\x67\x90\xe0\x03\xfa\x52\x99\x62\x44\x65\xec\x0e\x58\x5c\xd3\xb1\x21\x79\x07\x26\x3f\xee\xc3\xa1\x60\xfe\x70\x98\xf8\x58\x85\x83\x89\xc1\xc6\xa6\x9b\x1e\x77\xf2\x3f\x55\xbd\xad\x61\x56\x0b\xe1\x09\x4f\xa8\x2b\x44\xd7\x39\x98\xc9\x46\xcf\x13\x9d\x62\x87\x64\x65\x87\xab\x49\xc0\x39\x09\xbb\xa9\xee\x7b\xff\x4b\x5e\x78\xff\x53\xf5\x89\xa7\xb1\xc2\x8b\xc5\x7c\x7f\x76\x89\x29\x89\xf1\x06\x5c\x57\xf5\x33\x5c\x5e\xdd\x87\x4b\x49\xa9\xf5\x0a\xf6\x4e\x57\xa0\x28\x64\x1d\x98\x97\xfd\x18\xe9\x04\xea\xab\xd2\xcb\x68\x05\xc6\xb9\xf9\x65\x84\x7b\x21\x3c\xd5\x4c\x38\x7c\xc8\x60\x78\x38\xdd\x5b\xb9\x88\x25\xea\x78\x55\x5d\xba\xe3\xfc\xfb\xcc\xe3\xc8\x39\xf4\xe2\x63\x1e\x28\x2f\xff\x54\x11\x6b\xe3\xbc\x18\xec\xb1\x34\x08\xe7\x06\x73\x01\xed\xec\x57\x0b\x1a\xc9\xa1\xd5\x60\x1c\xb6\xe0\x0a\x64\x71\x4a\x04\x0d\x9f\x60\x1c\xe5\x8f\xdb\x97\xbc\x7c\xdd\xca\xf2\xb5\xdb\x5f\xa7\xb9\x0d\x17\x29\xc7\x46\x93\xae\xf6\x07\x59\xe2\x15\x87\x43\x19\x25\x08\x2f\x56\x79\x9b\xbf\xfe\x91\xbf\x4e\x16\xa5\x8c\xa6\x08\x07\xdb\x6e\x9d\xc0\xd4\x06\x8a\x62\x38\xa6\x31\x84\xdb\x6d\x0e\x45\xdf\x0e\xe5\x32\xb1\xce\x0e\xa8\xd9\xe7\xc7\xfd\x4c\xa0\x98\x70\xa9\x0c\x17\x23\x50\x63\xa8\x65\x4c\x56\x11\x45\x88\x1a\xb0\x94\x37\xdd\x93\xeb\x92\xe9\x89\xd4\x44\x18\x9a\xa5\x41\xb0\xfc\xb1\xae\xde\x72\x74\x6d\xdd\xcf\x34\xac\x09\x57\xca\xb9\xa0\x96\xf0\x8e\x91\x86\xef\x33\x9f\x79\x54\x5a\x03\x46\xf9\xab\xbb\x6f\xb7\xeb\xed\x26\x5c\xbb\xb6\x22\xb3\x33\x0b\xf8\x25\x35\x00\xc2\x8d\x89\x10\xea\xfe\x50\x06\x7d\xd7\x71\x51\x8d\x43\x44\x32\x15\xa4\xe1\x64\x3d\x79\x87\xc4\xec\x5a\x80\x27\xc8\xbf\xbf\x87\x63\x5d\x5d\xad\xc2\x0e\xc9\x21\xd5\x64\x54\x29\x9b\x7d\x48\x44\xd9\xb8\xc9\x7f\x09\x67\xbc\x8b\x08\x07\xed\xcc\x63\x9f\xa1\xbd\x70\x13\xd1\x15\x15\xa7\xb3\xd2\x66\x0e\x48\xe8\x9e\x88\x13\x92\x2b\x6d\x55\xef\xdd\x33\x59\x28\x13\x70\x6b\x63\x32\x4e\xdd\x66\xa1\xc0\x09\xdc\x84\x24\x71\xe2\xd4\xe0\x9a\x63\x39\xf4\xde\x92\x58\x64\x68\xde\x71\x91\x63\xf0\x1f\x74\xa3\xba\x03\x80\xda\x18\xab\xa2\x9d\xf7\x86\x97\xea\x16\x49\x2c\x19\x66\xac\x98\xff\x5d\xdd\x5c\x2d\xdf\x90\x24\x06\x03\xba\xd7\x0d\xc5\x2a\xc2\xc5\xc7\xcd\xd5\x64\x86\x26\xc4\x68\xa4\xa0\x3a\x1e\x4f\x39\xc5\x19\x92\x84\xd2\xd4\x3d\x60\x6c\x61\x49\xaf\x70\x1a\xde\xc6\x84\x32\x8e\x98\x19\x0c\x2f\xeb\x29\x24\x8d\x24\x4c\x49\xc2\x82\x82\x76\xf7\x2c\xb6\xd5\xdf\xa5\x7e\xed\xf5\x11\x49\xc2\x63\x47\x52\x55\x49\xe2\xb3\xd8\xe9\xf9\x13\xee\x4c\xbd\x1e\xab\xaa\x58\x9c\xa0\x49\x92\xba\x7a\xc5\x6b\x5e\x14\x8f\xf2\xa3\xff\xa0\x92\xf8\xf2\x8e\x11\x4f\xfd\xe3\x49\x6c\xc4\x58\x6f\x6b\x86\x8e\xcd\xe1\x73\x82\xb8\x35\xb2\x81\x2e\x13\x74\xe4\xea\x53\x24\xc9\xf4\x12\x04\x17\x10\x32\xed\x6e\xa3\x72\xd4\x8b\xfa\xa6\x44\x34\x7a\x51\xf4\x35\xf6\x44\x80\x13\xbe\xb9\xfb\xc0\x38\x68\x8b\xa2\x05\xe1\x60\x16\x81\xf5\xbd\xba\x9b\xcb\x87\xf5\xcc\x3a\x2c\x0c\xca\x28\x38\x65\x2a\x23\xcf\x14\x34\x12\x49\x23\x6c\x5a\xec\xb0\x37\xd5\x03\xbf\x16\x8d\x99\x49\x22\x33\x1d\x80\x2b\x8f\x55\x2b\xdb\x59\x68\x98\xa8\xd8\x70\x3b\x12\x95\xf5\x7f\xd6\x91\x41\x17\xd5\xa7\xaf\x21\x32\x48\x4c\x04\x8e\xb7\x5f\x4b\x47\x0d\xb8\xcd\x35\x94\x23\x5c\xdd\x64\xe2\x99\x38\xc3\xe0\xef\x07\xd2\x6d\xa7\x15\xd0\x53\xbf\xe0\x93\xa5\x2d\x31\x89\x4c\xd2\xd0\x99\x95\x75\xbb\x69\xab\x03\xd6\xb3\xce\x14\xf0\x12\x60\x11\x09\xde\x2b\x13\x24\xc3\x6c\x98\x96\xae\x4a\xe7\x92\x17\x79\x78\xac\xbc\xdd\xa5\x4f\x0f\x12\x9b\x39\xad\xc0\xcd\x43\x28\x71\x25\x56\x5b\x11\xda\xc4\xb2\x00\xd7\xd6\xee\x0f\xda\x88\x43\x5f\x02\xc5\x66\x9e\x3b\x92\x46\x4c\x3a\xef\xab\x87\x9b\xfb\xe0\x87\xd3\x25\x11\x8f\x5f\x57\x9b\xf5\x8e\x86\x61\x71\x9c\x20\x1c\xdd\x57\x8b\xef\xe1\xdd\x49\x22\x8c\x8b\x32\x29\xcd\x62\x65\xfd\xcb\x76\x57\x95\xf0\xe1\x3c\x4d\xd6\x33\xc2\x0e\x49\x19\x61\x98\x00\x1d\x6a\xf0\x36\xc0\xed\xf8\x9d\xeb\x32\x4b\x15\x05\xc8\xc8\xd8\xa7\x8f\xa4\xcc\x70\x4c\xfb\x9a\xea\x58\xdc\x34\xdd\x45\x98\x8b\x59\xe1\x20\x65\x20\x51\x51\xfe\x3f\xf2\xcf\xbd\x4f\x96\x1f\x6d\x9a\x24\x1c\x29\x51\x79\x69\xf2\xb7\xdc\x1c\x9d\xdf\x73\x38\xd8\x85\x31\xee\x56\x77\x8b\xc9\x63\x35\xa1\xc7\xce\xce\x24\x22\xa7\x35\x77\x7b\x1f\xe0\x38\xa9\x88\x33\x14\x61\xd9\xb4\xb2\x34\x3d\x11\x6f\xf6\x31\x65\x10\x18\x22\x9b\xd7\xbf\x24\x7c\x42\x52\x61\x25\x52\xe6\xb6\x20\xf7\xaa\xee\x22\xb9\xb1\x30\x03\x49\xb3\x88\x06\xd5\x39\xbf\xd0\x99\x25\x18\x47\x9a\x71\xe7\xf2\x83\x8f\xc4\x19\xc3\xce\xee\xaf\x64\xee\xf1\xe1\x0a\x02\xc7\xfd\x55\x2e\xf7\x55\xdf\xfc\x4b\x51\x9d\x64\xa8\xf0\x7e\xf7\x1c\xa6\x51\x06\x9c\xca\xd4\x6b\xaf\x06\xe7\x87\xeb\xbc\x6e\xda\xcb\xe3\x0c\x3b\x94\x4a\x99\x05\x57\xdf\x6f\x65\x6f\x4e\x4f\x52\x15\x5b\x5c\x23\x9d\x04\xf0\xa6\xad\xea\xa1\x02\x9a\x2a\x25\x30\xb5\xb8\xbe\x1d\x0b\x79\x92\x54\x99\x4c\x8a\x91\xd9\x61\x51\xd5\x5f\x6a\x18\x1d\xb7\x12\xbb\xb7\xc6\xe7\x23\x60\x6e\xb4\x4b\x2b\x9b\x51\x69\x21\xd5\xd4\x79\x95\x0f\x7e\x00\x4b\x72\x53\x24\xd5\x2a\x45\x29\x6c\xb4\x6a\x1a\x2a\x90\x29\xa4\x32\xb2\x21\x6a\x6b\x65\xf1\x45\xee\xe1\xb1\xdf\x8f\x52\xd0\x82\x85\xc4\xe8\xe8\xe2\xa2\x07\x7b\x3b\x17\x6e\x20\x29\x58\x70\xb2\xaa\xf2\x15\x5c\x8b\x33\x10\x0b\xfa\xfc\xdc\x8d\x14\x51\xc4\x89\x6f\x89\xfe\x3a\x5c\x87\x88\x63\x81\x6a\xfc\x8f\x4f\xeb\x8b\x6f\xbf\xef\x1e\x1f\x9e\xd0\x70\xe9\x6e\xf5\x5b\x3f\x82\x29\xe1\x61\xc7\xbd\xac\x22\x11\xb1\x4a\x1d\xb6\xa4\x0b\x0d\x77\x0d\xb4\xbb\x53\x84\xc2\xe4\x52\x05\xe1\xd2\xe0\xaa\xfc\xe6\x74\xb4\xf1\x9e\xd2\x28\x9c\x90\x26\x16\xf7\xe8\x23\xfa\xa4\x8e\xae\x90\x5a\xa6\xbc\xb0\xec\x63\x5d\x1d\xa0\x6e\x3f\xae\xab\x1a\x57\xaf\x25\x4d\x54\x22\x58\xb7\x11\xf6\x78\xb1\x8b\x63\x3d\xd7\xe6\x22\x82\x1b\xce\xc7\xb8\x9e\x1f\x79\xfb\x32\x95\x0f\x58\x5c\x93\x45\x2a\x22\x94\xc6\xc6\x10\x31\xd4\xf5\xff\x39\xe3\x83\x12\x91\x66\x16\xa9\x88\xee\x92\xcd\x51\xb7\xbf\x2c\x0a\x79\x2d\x05\x55\x42\xb0\xcc\xb9\x0b\xf7\x16\x2a\xb7\xd5\x73\xae\x97\xfb\x2f\x42\x64\x96\xf4\xc6\x9b\x4d\x5b\x99\x5c\x7a\xe1\xb3\x27\xf8\xef\x34\xe4\x14\x42\x52\x67\x97\xe2\x2f\xfc\x0a\x8a\x3e\x50\x11\x42\x2a\x8e\x5e\x1e\x97\x97\xfd\x9f\x74\x84\xc2\x01\xa1\x99\x7b\x55\xed\x65\x5e\xfe\xb2\x54\xef\x11\x19\x64\x98\xa6\x97\xf0\xee\x5f\xf5\x59\xe1\x5c\x48\x2e\xd0\xb4\xdb\xe6\xa5\x59\x97\xe6\x50\xe5\x65\x7b\x92\xe9\x85\xb1\x19\xc7\x6f\xee\xb6\xd1\xa7\x00\x51\x9f\x44\x64\x42\x2a\xa7\xc6\xbc\xdb\x3d\xc3\x19\x40\x84\x90\x40\x55\x00\xea\x05\x83\xdd\x13\x3e\x3f\x11\xd2\xa6\x01\xc9\xbe\xe9\x56\xc4\x00\x00\xbd\x93\xa1\x20\x37\x9c\x52\xa5\xc2\xcd\x1c\x34\xef\xea\xf6\x58\xb7\xbe\xde\x94\xba\xaa\x6b\xd0\x5e\x2b\xc2\x8f\x86\xd8\xa5\x9e\x17\xb9\x91\x58\x89\x98\x9e\x0c\x68\x4a\x47\x9e\x5e\xcd\xc5\xc7\x55\xa5\x07\x5d\xdd\x30\x2a\xd1\x89\x73\x30\x6e\x1f\x6a\xa7\x22\xbb\xbc\xcb\x08\x50\x3a\xc8\xb1\x04\x25\xd3\xe5\x60\x4b\x58\x95\x60\x01\xde\x85\x02\x4f\x60\xa7\x53\x25\x8b\x18\x95\x83\x57\xe3\x45\x21\xf5\x6b\x17\xba\x6d\x0e\x50\x9a\xf9\xdb\x94\xc5\xb1\x46\x8a\xcf\x02\x93\xe3\x93\x3c\x2c\x8b\x53\xcb\x64\xcf\x7d\x90\x6d\x7d\xce\xd4\x97\x64\xb1\xca\xf0\x61\xff\xe7\x68\x9e\xe1\xa6\x41\x1a\xf8\x95\xcc\x8b\x8f\x09\xd4\xf4\x6f\x4b\x37\x25\x23\xa9\x21\x3e\x9c\x3d\x1e\xf0\x25\x6f\xbe\xe6\x4d\x5b\xcd\x3b\x0d\x19\xb1\x42\xc8\x00\x1a\x69\xe0\x0a\xca\x0a\xf1\x3b\x79\xb5\xdc\x47\xcd\xa8\xef\xcf\xfb\xc7\xe7\xf4\x7b\x67\x43\x88\xe5\x3d\x96\x36\x28\xfa\x87\x39\x9c\x51\x99\x86\x2e\xa8\xf3\xd1\x70\x45\x9b\xc5\x68\x3a\xa3\x56\x62\xcf\x66\x75\x35\x36\xb4\x21\x19\x8b\x8c\xef\xcb\x6b\x28\xdb\x63\x7d\xac\x86\x43\x24\x25\xcc\x57\xc7\xc7\x5b\x7d\x38\x9c\x29\x8c\xa2\xc2\x75\x4d\x4e\xcb\x4d\x8a\x4d\x0b\x6f\xb2\xe3\xbb\xfe\x23\xcd\x45\x92\x25\x9c\xa0\xa2\x8c\x4b\x61\x77\x2f\xae\x7f\x3b\xbd\xfb\x89\xa2\xb8\xdd\x6e\xb6\xab\xa7\xdb\x9b\x2f\x5f\x43\xa4\x9a\xa5\x42\x39\xf5\x59\xb9\x87\xaf\x55\x33\x5b\xd7\xb2\x54\xba\xf2\x42\x17\x3e\x74\xdf\x79\x27\x7f\x0e\x66\x98\x24\x13\x7e\xca\x85\x05\xbc\xfb\x69\xa3\xac\x20\x13\xa9\xc1\xf9\x7d\xe8\xed\xe8\x1e\xa1\xde\xc8\xb6\x6a\x5e\xf2\x7e\x4c\x66\xb0\xf8\xb0\x81\xa2\x70\x78\xdb\x33\x3d\x81\x30\xde\x70\x44\x22\x78\x7a\xee\x26\x7f\x2e\x65\x7b\xac\x61\x85\xdd\x6d\xb9\x4c\xf4\xf5\x9f\x95\x84\x3b\xfd\xbb\x2e\xbb\xbd\xaa\xca\xa9\x85\xf5\xbf\xc8\x90\xba\x8b\x7f\x4f\x1b\x70\xff\x22\xff\x0e\xe7\x10\x0a\xa3\x6f\x34\x5e\x1f\x83\x69\x33\x69\xa2\x40\xf6\xdb\x95\x6a\x36\x05\x95\x96\xa9\x83\xc5\x3f\xd6\xb0\xcf\x8f\xfb\xd9\x13\xd2\xb1\xc3\x39\x38\x7d\x26\x93\xb7\x17\xd5\xbc\xd8\x95\x99\xd8\xa9\xbf\xe3\xfc\x5c\xcd\xec\xac\xa6\xa7\x33\x4c\x61\x9c\x91\x37\x3d\x9a\xf6\xa6\x6c\x72\x03\x4f\x63\x27\xfd\xe5\xe8\x35\x33\x32\x46\xf7\x78\x8f\x67\x72\x9d\x59\xd2\x5f\x85\x4e\x0c\x96\xb1\xf3\xe7\xe7\x8f\x6d\x35\x09\x6c\x33\x03\xa0\x06\x67\xbf\x6f\x87\xaa\xc6\x78\x1c\x8d\x95\x51\x39\x78\x6e\xd2\x3a\xbd\x4b\x20\x15\xb6\x92\xc7\x98\x88\xfe\xe7\xdb\xd8\x20\x15\xf2\xd8\xc0\x84\x81\xec\x0e\xcb\x38\x32\x22\x0d\x15\x33\x74\x7c\x5c\x3b\xc0\xc3\x2f\x61\x80\x20\x26\x0e\x90\xd1\x40\xaa\xbf\x94\x87\x1b\x5d\x3d\xbe\xc8\x06\xb6\xef\xd5\x23\x6a\x56\x4c\x4a\xa9\x12\xa5\xf2\xf0\x56\xe2\x82\x77\x89\x4e\x29\xe1\x9c\x84\xc7\xa8\xc0\xf6\x86\xa6\x45\x63\x5b\x7f\x22\x49\x22\x82\xe4\x56\xb7\x30\xb9\x1b\x85\x25\x97\xe9\x85\x13\x2d\x30\x77\x7e\xfd\xd0\xa8\xaf\x33\x23\x0b\x76\x03\x5c\xe9\xf1\xfe\xe1\xd7\xdd\xc3\xbe\xcc\x9d\xc0\x55\xff\x35\x10\x23\x15\xfc\xe9\xf7\xd5\xfd\xc8\x3b\x95\x48\x62\x23\x44\x14\x3a\x6c\x55\xff\x8c\x24\x8d\x28\x36\x95\xf2\x32\x6f\x63\xe7\xd6\x15\x56\x0d\x3f\x82\x81\x13\x41\x30\xd0\xa5\xbd\x0d\xf4\x2e\xb7\x8f\x75\xf5\xf3\xe3\xf3\xe8\x4c\x32\x10\x01\x7d\x3a\xd1\x94\xcf\xc2\xd9\x79\x92\x60\x69\xf3\x47\xf5\x31\x68\xd1\x10\xc9\x33\x90\xae\x8c\xb5\x2e\xdb\xbc\x2d\x10\x42\x7a\x59\x1c\x9b\xb9\x2e\x27\x91\x5c\x47\xd8\xd6\x72\xfd\xc0\x8d\x7c\x96\xa8\x4c\xe0\xcb\x68\x4b\x97\x37\x41\xa4\xc9\x84\x6a\x34\x50\x44\xfe\xca\x1e\x5c\x62\x85\x8b\xcf\xaa\x79\x3d\x41\xc5\x4d\xbf\x3b\xb1\x04\x43\xac\x33\x0e\xc8\x67\x3e\x95\x12\xc9\x7a\x14\x31\xda\x5a\xfb\x74\x7d\x3a\x4c\x24\x29\x66\xcb\x2e\xea\x9c\xbe\xfe\x52\x48\x67\x77\xda\xed\x8c\xc7\xba\x74\xb0\x55\x6c\xea\x8d\xc0\xbf\x52\x92\x04\x71\x13\x28\xbf\x28\xdb\xeb\xaa\x3e\x35\xb7\xef\x46\xa5\x4c\x05\x7f\xac\x1a\x95\xe5\xa7\x8a\x08\x61\x5c\x42\x83\x59\xc5\x55\x88\x2b\x46\xef\xa4\x94\x99\x03\xd8\x1c\x4b\xb4\x6c\x5e\x9e\x11\x8a\xb9\x5f\x15\xf6\x3f\xe7\x4c\x31\xfd\x22\xa5\x18\x52\x38\xef\xf2\xa1\x2f\x26\xb5\x88\xd1\xef\xeb\x76\x64\x7d\x4b\xa4\x56\x12\x27\x4a\x5f\x83\xbf\x43\x77\xf8\xfe\xb0\x4e\xb0\x08\xf9\xe5\xde\xa5\x9c\xeb\xa7\x4b\x12\x7d\x56\x40\x95\xda\xa8\x10\xb0\xad\xca\x8f\xaa\x84\xb9\xfb\xa7\xbf\x35\xa3\xbb\x0c\x82\x62\x11\xb8\xad\x83\xcd\xcc\x99\xa0\x49\x82\xd0\x46\x0f\xbe\xac\x2e\x0f\x99\x0d\xd1\x04\x99\x6d\x8f\x75\x5e\xb6\x52\x15\x1e\x00\xb8\x9c\xac\x4c\xa3\x2c\x7f\x06\x4b\x5c\x5d\x7c\x2f\x9b\x66\x2e\xf3\x78\x5a\x90\x56\x11\xa3\x02\xfd\xf5\x6e\x9e\xae\x9e\x1e\x1e\x77\xab\xab\xab\xa7\xf5\x26\xf4\x03\x54\x94\x49\xed\xb9\xc3\x75\xde\x7e\xa0\x9f\x7d\x38\x46\x89\x74\x55\x80\x2e\x5b\x1f\x87\x2a\x8a\xd2\xcc\xc9\x27\xdc\x6d\xa7\x4c\xef\xc9\x8f\x55\x54\x51\x04\x22\x5d\xe5\x6f\x43\xe7\x4f\x31\xc5\x11\x3f\x9f\x37\xb7\xd5\x73\x85\xfe\xa8\xfd\x22\xab\x78\x2c\x6c\x70\x53\x41\x3a\xf1\x99\x05\x68\x79\x3b\x53\x1c\x34\xc2\x2e\x6a\xd9\xc2\xaa\x7c\x86\xa2\xb9\x92\x1f\xbd\x6d\x12\x51\x89\x50\xca\x8e\xf5\x40\x9b\x9b\x16\xf6\x41\xe4\x67\x32\x4d\x55\x02\x16\x99\x0d\x97\x4f\x95\xbd\x93\xaf\x50\x5f\x38\xc5\xa3\xe5\x87\xaf\x12\x4b\x30\x6b\xc7\x1b\x72\x22\x9e\x7b\x5a\xd7\xf4\x0b\x94\x4a\x23\xc5\xe2\x60\xe3\x52\xda\x3c\xf4\x23\x16\x53\x6d\x95\xc6\x0c\x41\x05\x6e\xd3\xbd\x7c\x01\xfd\x8a\x79\xdd\x72\x08\xab\x52\x26\x53\x08\xa1\x38\x82\x1e\xce\x3a\x7c\xf6\x33\x46\xf0\x14\xd5\x3d\x1d\xbd\xb0\x7b\xe1\xba\x9d\x35\x0e\xb7\x30\x13\x1c\x9b\x39\xb2\x3e\x0d\xdf\x96\x1f\x8a\xa4\xae\xfc\x5a\xc2\xcf\x16\x2b\xdb\xf1\xe0\x62\x1d\x86\x24\x56\xf8\x52\xb4\x4f\x15\xd6\x65\x5b\x9f\xf0\x00\xc2\xe8\x94\xe1\x09\xe1\x67\x0b\xa5\xf1\x56\x1a\x23\x95\xd8\xf9\x70\x91\x32\xe2\xeb\xa3\x93\xf5\x68\x3e\x4e\x5a\xf4\x7e\x28\x64\xd3\x76\xd3\x72\x4e\x4e\x52\x8a\xb8\x69\x0f\x58\xc2\xaf\xae\x8e\x4d\x3b\x32\x71\x20\x4a\x71\x93\xf8\xbb\xbd\x7e\x70\x3b\xcd\xa9\x2d\x1c\x51\x4a\xb0\x84\x0f\xd4\x9c\xb0\x62\x8b\xa5\x05\x4b\x69\xdf\x07\xf1\x5d\xcf\x4d\xde\x07\x39\x0a\x04\x30\x18\x78\xff\x5d\xa4\xb8\x99\x6b\xe5\x12\x05\x00\x88\xde\xef\xb2\xf6\xb5\x6b\x42\xba\xaf\x0b\x32\xd2\x7e\x9c\xa5\x31\x5e\x95\x57\x46\xfb\x56\x3a\x60\x70\x38\x9a\x5a\xe4\x1a\xfd\xfd\xb8\x3f\x8c\x3a\xfc\xca\x66\x80\xe0\x3c\xa7\xca\xd8\x47\xe8\x73\x8c\xd7\x67\x10\x37\x65\xc1\x61\xd3\x30\x65\x7b\xcc\x75\x35\xe0\x15\x74\x94\x28\xed\x60\x02\xf0\x36\xd1\x88\xf0\xc7\x63\xe3\x54\x0b\xf3\x4d\x17\x7f\xde\xc3\xfb\x70\x04\xb4\x37\xea\x69\x8f\xb5\xa3\x74\xbb\x32\x4d\x18\x40\x04\x8b\xa3\xa0\xac\xaf\x8a\x5c\xcf\x3d\xdb\x88\x26\x19\xc5\xf8\xc6\xe6\x3f\xcf\x62\x4a\xc3\x50\xe9\xc0\xb0\x70\xc8\x1b\xc4\x26\x8d\xc4\xf7\x88\xa6\x26\xc5\x9d\x1a\x4a\xb3\x1b\x40\xb9\x9a\x89\x2c\xf5\x38\xb5\xd5\xb1\xad\xea\xc7\x5c\xe3\xdd\x9b\xdc\x1f\xcd\xb2\x04\x83\xe1\x9b\xb2\x39\x06\x5b\xce\x6b\x38\xb3\x03\x6b\x96\xb9\x50\xf4\xe2\x21\x94\x95\x74\x42\x05\x96\x0e\xf1\x06\xfe\x8f\x3a\xaf\xe1\x14\xc6\x61\x27\x9e\xa1\xed\xf2\x47\x2d\x6b\x73\xa8\x1a\xb2\xbc\xec\xe8\xc4\x32\x1c\x1d\x40\xc1\xb7\xeb\xef\xeb\xdb\x5d\xc0\x7b\xea\x34\x36\x59\x10\xea\x2f\xaa\x12\xcc\x13\x1c\xaa\xfe\x60\x62\xb0\x71\xbd\xcf\xcb\xf6\xb2\xaa\x8a\xab\xea\xbd\x7f\x1e\x29\xa4\xd2\x75\x21\xfa\xba\xb0\x16\x3c\xcb\xe2\x49\x2d\xa4\x5b\xb2\x46\xbf\xf0\x74\x53\xd4\x59\xc4\x71\x53\xec\xd2\x0b\xff\x38\x91\x71\x35\x7f\xa8\x19\x37\xa1\x84\xfb\x55\x16\xed\x8d\xae\x46\xc0\x2a\x9d\x65\x29\x6e\x64\xdb\x9b\xcb\x5f\x77\xdb\x9b\x1e\x3a\xac\x33\xe0\xd4\xf9\x84\x43\x73\x6c\x66\x33\x56\xf2\x2c\x63\x23\x24\xe6\x27\x0c\x00\xad\x01\x22\x5f\xae\xb8\xaf\x5a\xb8\x0d\x9a\xfc\xc3\x08\x13\x59\xe7\xaa\x15\x24\x24\x67\x87\x75\x0c\x7e\x45\xda\x40\x69\xbe\x54\xe6\x8f\xd9\x08\xe0\x02\xbb\xc0\xbd\xa3\xf3\xa4\xef\xa3\x81\x5b\xed\xb8\xa0\x4e\x62\xb4\xbb\xb7\xae\xa4\x73\xe6\x92\x21\x25\x62\xd8\xa0\xc6\x25\xea\xfe\x94\x42\x22\x69\x27\x14\x45\x37\x23\xa2\x9e\x1b\x62\xa2\x58\x60\x3f\xf1\xab\xdc\xe7\x63\xbd\x44\x62\x22\xce\xfb\x02\x5e\x9d\x8f\xdb\x60\x26\xe2\x66\xb0\xd0\xe9\x61\x34\x26\x4a\x0c\xe6\x4c\xf8\x4e\x6d\x2b\x74\xd0\x1c\x15\x0a\x4c\x9c\x59\xac\x7b\xb4\xd0\x04\xeb\x82\x1f\x79\x51\xdc\x57\x2d\xb6\x73\x3f\xfa\x84\x28\x9c\x30\xd6\x31\x04\x7f\x5b\x5c\x74\x67\x9e\x6e\xcb\xb9\x92\x89\x0d\xb7\x10\x6c\x67\x9a\xfc\xb9\xff\x49\x84\x6a\x08\xed\xbb\x6e\x95\xf1\x22\xc2\x9f\x22\x71\x0c\xb1\x6e\x65\xea\xf6\x2a\x97\x8a\x4e\x16\x37\x43\xbb\x18\xad\x7b\x2b\x6a\xf9\x8e\x2d\x97\x66\xd0\x09\x1a\x5e\x87\xe9\x6b\x6b\xa8\x72\x7a\x27\x3a\xaf\xb1\x3d\x94\x97\xcf\x0e\x55\xb5\xeb\x4f\x6b\x0d\x3e\x3b\x75\xac\xcb\xbb\x7e\x17\x30\x8c\x01\x0f\x7b\xcc\x05\x8c\x36\xce\xc9\x42\x66\x58\x66\xb0\xbb\xb7\x73\x1d\xd6\xaf\xb9\x77\x1c\x1e\x91\x62\xfd\x48\x4e\xac\x63\x22\x3a\x3b\x24\xcf\x64\x5a\xd2\x21\x23\x86\x67\x0e\x79\xef\x73\xef\x00\x67\x9d\x9d\x31\x49\x1c\xe2\xea\x45\x36\x1b\xfd\x02\x7b\x39\xbb\xb6\x04\x9c\x75\x38\xc6\xee\xbf\x9d\xcc\x5a\x93\x58\x47\x92\xf3\x9c\xf9\x3f\xc6\x4b\xe8\xf4\xd1\xa4\x69\x16\xd8\xf5\xdf\xab\x16\xe6\xb1\x8e\x49\xb5\x7b\xde\xdf\x1e\x77\xef\x79\x39\xfe\x0e\x11\x45\x08\xdb\x30\x10\x38\x80\xbf\xc2\xc7\x04\xb4\x61\x44\xcc\x30\xc4\x70\x8d\xdb\x49\x41\xc6\x64\x2c\xc5\x13\xbf\x55\xa7\x06\x44\x61\x48\x96\xe0\xca\x84\x35\x73\x27\x18\x6b\x3e\x6d\xc3\xcc\x7e\x9b\x4c\x0c\xe6\xa5\xdd\xb4\xbb\x92\x61\xcd\x36\x8a\x18\x2c\xb6\xed\x3f\xbc\x32\xef\xf4\x5b\x95\xa5\x18\x95\x5f\x06\x7d\x6f\x62\x34\x01\xa4\x01\xfe\xf7\x08\x47\x78\x94\x1f\x7b\x98\xbd\x96\xda\x6a\xe1\x57\x2e\xac\xbc\x21\x61\xf1\xf3\x8b\x33\x89\x2b\xee\x7b\x0b\xed\xd5\x21\xf7\x92\x9a\xc3\x9a\x6d\x4c\x46\x34\x1b\xd3\x1b\x1e\xfa\x49\x0c\x44\x5b\x57\x94\xb8\xed\xe2\xe4\xf6\xb1\x06\xdf\x51\x19\x63\x0f\xa7\xb1\x8b\xb1\x91\x42\xed\x13\x03\x87\x1a\xb4\x6c\xe1\xe2\x63\xa6\x00\x43\x8c\x65\xdc\x35\x40\x8b\xaa\x01\xbf\xbc\x4e\xae\x1c\x22\x49\xac\x4f\x4b\x7a\xf9\xd1\x8b\x31\x41\x0e\x22\x45\x50\xbf\xe3\xb6\x7a\xfe\xbe\x90\x7d\x7f\xbe\x7b\x43\xa4\x63\xe6\x2b\x8e\x53\xba\x07\x44\x86\x23\x65\x62\xf5\xdf\xa3\x1c\x2f\xb4\x10\x47\x14\xdb\xd1\xfb\xaa\xec\x76\xa9\xeb\x02\x46\xae\xc8\x04\x62\xea\x7c\x7a\xbb\x1f\x5d\xe8\x00\x5d\x6c\xce\x86\x25\x40\x12\x8d\xdd\xe1\x3a\xd7\x2f\xd0\x93\x51\x80\xe8\xbe\x61\xf4\x04\x16\x6a\xa8\x97\xa4\x86\x08\x10\xeb\x5c\x6e\xd6\xb5\x26\xd1\x76\xd4\x22\xf7\xc7\x29\x89\xbd\xd0\x22\x16\xe5\xaf\x40\xa3\x0b\x5f\x38\x4a\x0d\x76\xce\xbf\x7e\x98\x7a\x82\x58\x06\x96\x29\x24\x1f\x23\x19\x46\xe7\xed\xc7\x74\xb7\x06\x06\x36\x49\xc6\x7d\xcb\x45\x85\x6a\x02\xcc\x26\xe8\x21\x62\xaa\xb0\xe5\x9d\xad\x16\x4d\x7f\x58\x42\x9d\xe1\xc0\xea\x26\xc4\xbc\x90\x70\xf7\x5b\xaf\xf2\xe7\xbc\x95\x05\x42\x3a\x3e\x2b\x6a\x40\x22\x39\xd6\x1d\x6e\x6f\x2e\x97\xc7\x8d\x03\x7d\x48\xa4\xb3\x77\x7a\x94\x1f\xce\xe5\x77\x02\xdd\x82\x94\x65\xc8\x4d\x58\x3f\x5d\xc6\x09\x1f\xae\x4a\x10\x86\x25\xef\x1f\xe0\xc8\x79\x7f\x29\x6e\x04\x61\x9c\xf5\x48\x70\x9f\x1a\xab\xf1\x7d\xfa\x36\x43\x96\x3a\x2a\xdb\x8d\x37\xf9\x5c\x37\xed\xb0\x54\x42\x26\x00\xeb\x28\x26\xb7\xf6\x2e\x2f\x8f\x0b\x89\x6d\x18\x99\x01\x6e\x6a\x88\xf0\x9c\x59\x80\x2f\x3f\x92\x4c\x9a\xc4\xbb\xd6\x1d\x64\xab\x5f\xce\xf1\xe5\x21\x33\x1c\x9b\xd3\x52\x6b\x38\xb4\x17\xf9\x19\x56\x28\x28\x96\x62\xdb\xea\x29\x7f\x7e\x69\x57\xa5\x79\xaa\x0a\x68\xe6\xd8\x34\x50\x52\x48\x27\x4d\x6d\xf2\x01\xb2\xd5\x2f\x3b\xfd\x1a\x06\x3a\x4d\xb1\x2a\xff\x9f\x2a\x2f\x1f\xab\x29\x7a\x1d\x0c\x49\x5c\xe5\x1b\x21\xe9\x0e\x45\xf1\x89\x12\x42\xf8\x14\x73\x81\xee\xe3\xb1\xae\x7e\xfe\x39\xc8\x1e\x80\x92\x94\x07\xd4\x53\x5b\x6d\xfa\x1e\x0f\x00\x75\x12\x18\xdd\x52\x56\x14\x53\xa7\x32\x02\xc0\x23\x04\xb1\xad\x8b\xbc\x9d\xe8\x9c\x00\x24\x12\x85\xf7\x02\x0f\x66\x71\x57\x0a\x63\x2d\xc3\x1e\xdf\xb7\x5f\xfb\x4f\xdb\x14\x45\x32\xee\x64\xd3\xe4\x6f\x50\x7c\x20\x1b\xeb\x80\x25\x9e\x87\xb2\x0b\x8c\x47\xbd\x2c\xb0\x54\x30\xbf\x43\x5f\x74\xf3\x21\x87\xe6\xe2\x63\x51\x0b\x05\x2c\xa3\xda\x59\x47\xe9\xaa\x36\xe7\xf4\xe2\xce\x14\xee\xc2\x39\x38\x89\x61\x14\xf1\x3b\x04\xe0\x24\xec\x1f\x3d\x5d\x9b\x68\x07\x73\x0e\x18\x9d\x90\x79\xce\xaf\x4c\x19\x8c\x5b\x55\x37\x45\x43\xe0\x3a\x97\x7a\x0b\x93\xcb\x46\xdc\xe1\x28\x9e\x51\xce\xad\xcc\xcb\xe7\xb1\x14\x6b\x7f\xad\x36\x12\x1c\xcb\xb0\x18\x1f\xf4\x48\x9b\x5f\xc2\x51\x9d\x51\x27\x04\xf2\x71\xd3\xc2\xfe\xa4\x7c\xbe\xb0\x38\xd9\x58\x59\x69\x42\x09\xaa\xdb\x42\x9c\x04\xe8\xec\x7b\x63\x30\x99\x5b\x87\xdb\x87\x12\x6b\x82\xb2\x38\x4d\x0c\x2c\x89\x9c\x32\xd1\x4b\x5e\xb6\xdf\x9e\x6e\x67\xc4\x98\x7e\x90\xca\x74\xe0\x3f\x1e\xaa\x7a\x8e\x05\xf1\xc3\x58\x4c\x63\xe6\x1b\x50\x79\x79\x84\x71\xd1\x7b\xf6\xb5\x5c\x44\x68\xb6\x8d\xcd\xc4\x9d\xea\xe6\x4c\x80\x71\xd8\x84\x47\x98\x81\x01\x2a\xd5\xc0\xc2\x2a\x30\xfb\xde\x84\x3b\x27\x9f\x26\x28\xb6\x43\xbd\x7a\x1e\x4f\xf6\x61\x32\x58\x41\x9d\x55\x61\xc8\x95\x50\xc6\x69\xfc\xde\xd8\xcc\x1a\x4c\x65\xbf\x7e\xfd\xb2\xdd\x7e\x09\x7f\x95\x52\x21\x50\xcb\x42\xab\x5f\xb0\xdb\xd1\xc5\x25\xdd\x4c\xba\x83\x6e\x0a\x0f\x82\x38\x93\x49\x65\xa5\xce\x92\x1e\x91\xfd\x55\x36\x97\xf2\xb4\xc9\x12\x86\xda\x18\x1c\x85\xe1\xad\x7a\x05\x17\x69\x8d\xa8\x64\x67\x3e\xa5\x22\x8d\x88\x48\x39\xce\x32\xad\xea\xe2\x10\xf7\xc4\x7e\xcd\xdb\xf6\xe3\x0b\xb4\x0f\xf5\x7d\x35\xdb\x64\xad\x8e\x9d\x98\x4a\x77\x75\xc6\x1b\x23\xcf\x87\x10\x81\xf1\xdd\x76\xf5\xb8\x7b\x7c\xb8\xbd\xdd\x5d\x7d\x7b\x5a\x6d\x6f\x1e\x42\xa7\xcc\x6a\x22\x1d\x44\x56\x1d\x97\x4d\xb5\x88\xd5\x34\x26\x69\x88\xb1\x91\x1e\x11\xac\xa1\x67\x5f\x66\x32\x63\x9c\x67\x41\x17\x8a\xec\xae\x40\x17\xb2\x0e\x9c\x8a\x81\x9b\xfd\x69\x93\xdb\xda\xd8\x8e\xc8\x12\x57\xf0\x06\x6f\xd5\x01\xea\x95\xee\xe6\xe5\xec\x0b\xad\x8e\x54\x34\x71\xd9\x0b\x7d\x63\x68\x1e\xec\xed\xe9\x8b\x4f\xa3\x98\xbb\x56\x5b\x58\x7c\x50\x04\xf1\xb4\xf3\xee\x47\x93\x58\x8b\xb4\x57\xcd\xc7\xe4\xec\x4d\x4e\x45\x9d\x69\x44\x48\x42\x83\x25\xa5\x93\x5a\x98\x54\xbb\x68\x44\x74\x22\x1c\x16\x20\x74\x48\x69\x44\xe3\x0c\x5d\x57\x7d\xf9\xc9\x35\x1a\x3e\xdb\x87\x69\x44\x49\x22\x9d\x74\x5e\xf3\x72\x92\xd1\xd1\x88\xda\x04\x0b\x29\x98\x74\x76\xef\x45\x88\x1c\xfd\x71\x26\x62\x33\xc8\xa2\x3e\xd6\xd0\x38\xd0\xf5\xf4\x2c\x4c\x70\x34\xf0\xa8\x31\xcf\x84\x81\xe7\xd1\x1d\x92\x6c\xc0\x03\x7b\x0f\x9e\x93\xa5\x7f\x6c\x85\x32\x42\x20\xd0\x88\x19\xa0\xa1\xef\x06\x48\xe8\x83\x37\xa8\x1d\x33\x61\x69\x2a\xd0\x88\x0b\x29\x4d\x40\x70\xa2\x23\x90\x2c\x73\x0b\xb3\x60\x93\x46\x5c\x19\x2c\x25\x6c\xeb\xaa\x7c\xee\x4b\x61\x34\x4a\x22\x95\x88\x00\xfb\xaf\x61\xcc\x88\xa2\x51\x42\x62\xe1\x31\x57\xdf\xf3\x46\xde\x82\x3d\x6b\xed\x17\x3e\x21\x4c\x50\x5d\xf3\xaa\x22\x5b\xf8\xd9\x06\x2c\xc5\x6c\x52\xa4\x11\x61\x76\x62\x3a\xe5\x95\x4d\xe6\xc3\x24\xd6\x91\xef\x56\xf7\x5f\x57\xdb\xed\xea\xfe\xf1\xe9\xe1\xb7\xdf\x9f\x6e\xbe\x5f\x3d\x85\x0b\x4d\x63\x1a\x8a\x5e\x97\x97\x5f\xbd\xc5\x15\xed\x8f\x32\x8e\x39\xf2\xae\xdf\x1f\x7d\xf6\xb8\xad\x26\xe2\x47\xc3\x2a\x4a\xa3\x94\xf7\x36\xfc\x97\x55\x13\xa2\x91\xee\xef\x06\x45\x6b\x60\x9f\xa3\x66\x73\xf7\x92\x3f\x75\x3f\xee\x1b\x16\xaf\xcc\xfc\xda\x05\x8b\x93\xc1\x53\xe0\xc1\xce\xa2\xc9\xd9\x68\xa9\xa5\xf3\x5b\x39\x7c\x9c\xd6\x5e\xc2\x20\x2b\x90\x86\xbb\xa9\x0a\xb3\x58\x08\x1c\xef\x6c\x34\x12\x54\xe0\x33\xd4\xd5\xfe\x50\x35\x70\xf6\xb4\x59\x94\x21\x20\x73\x17\xd2\x96\xd5\x79\x73\xb4\xf0\x91\xc4\x69\xff\x1f\xbc\xf8\x7a\x6f\x80\xdd\xdf\xad\x2c\x23\xd8\x07\xcd\x75\x75\x27\x7f\x8e\x09\xd3\x34\xca\x74\x6a\x3d\x29\xf9\x56\x36\xed\x26\xff\xd9\x02\x94\xde\x97\x7a\xfa\x45\x32\x15\x4e\xe5\x63\xf5\xdb\x6e\x73\xb3\x5d\xef\x9c\x58\x51\x48\x34\x68\xa4\xe2\x14\xf5\xaa\x9e\x1e\x1e\xd7\xfd\xdf\x24\x41\xac\xe4\x89\x1e\xd0\xf8\x85\x53\x5a\xe3\xea\xf8\x8f\xdb\xd5\xfd\xe5\x9a\x84\xcf\x6a\x9a\xb8\xb2\xc0\xb1\x7c\x86\xaa\x74\x7d\xbf\x53\x5f\x69\x1a\x69\x1d\xc7\x0e\x0a\x81\xc8\xab\xcd\x11\xf7\x34\x7b\x2c\x76\xfd\xa9\x40\xeb\xb4\xd7\xa3\xfc\x65\xfc\xea\xfb\x6c\x9f\x46\x86\x45\x5e\x41\xba\xad\x3f\x9c\x6c\xf8\xec\x7b\x4c\xc6\xd0\x67\xf3\xf1\xee\xeb\xa2\x4e\xf6\x49\xbc\x4d\x23\xa0\x11\xaa\xeb\x35\xc7\x03\xd4\xbb\x45\x9f\x9b\xe5\xc7\x0a\x89\xca\x44\xe0\xac\x3b\x7d\xca\xbc\x7c\x76\x04\x81\x4b\x79\xf0\x1a\x39\x5f\x65\x6d\x7a\xa0\x3d\x8d\x20\x8b\xc4\x20\xb8\xb2\x2a\x8a\xcb\xea\xb5\x5f\x15\x41\x5a\xe9\x25\x46\xb6\x83\x83\x7c\x38\x6a\x79\x1a\x0d\x02\x0b\x0b\x9e\x2b\x34\x8e\x62\xcb\x92\x9e\x82\xda\x87\x5c\x7e\x89\x59\x7e\x9b\xe2\x38\xb2\x84\xf6\xe7\xc5\x20\x61\x76\xda\x98\x10\xac\x7e\xc1\xcf\x17\x79\x6c\xda\xcb\x97\x5c\xe5\xcb\x39\x61\x37\xd6\xc9\x3f\xee\x90\x57\xf1\x73\x7e\xa6\x2c\x42\x00\x87\x73\x93\x9d\x4c\xf4\x38\x96\xc2\xfa\x1d\xf8\xdb\xa1\xa8\xa4\xb9\x47\x95\xc7\xe9\x09\x08\x89\x18\x0d\x0d\xbe\xfd\xa1\x85\x1d\x8b\xc6\x59\x1a\x8d\x29\x61\x68\x66\xd6\x3f\xca\xab\xfc\x2d\x5f\x2e\xa9\xd3\x98\xa6\x06\x4f\xd7\x3d\xc3\x5d\x5e\x36\x50\xb7\x3b\x9b\xbb\x62\xf1\xd7\xbc\x6c\x1f\x6b\x78\x7b\x42\xd8\xa8\x71\x0b\xd7\x57\x90\xe6\x97\xe9\x29\x84\x73\xb1\x38\x74\xd9\xcb\x8e\xef\x06\x15\xea\x31\x03\x84\xc6\x34\xe3\xd4\xe1\x85\x0c\xfc\x9c\x68\x34\xd1\x98\xc5\x16\x5b\x71\x5d\x7e\xf1\x28\xf3\xfa\xba\xaa\x83\xfe\xc8\xb9\x52\xc7\xb0\x06\xc7\x8c\x4b\xac\xbf\xfe\xc8\x0b\x73\x7d\x1c\x0b\x85\xd2\x98\x65\x04\x73\xc6\x6e\x7f\xfc\xa8\xca\x2e\x12\x97\xaa\x77\x0b\xa1\x31\x53\x1a\x95\xd4\xae\xbf\xdd\x5f\x79\xb2\x4c\x38\xc4\x53\x81\x1d\x21\xff\x0e\x06\x4a\xc2\xe4\x95\x8c\xb9\xe4\x31\x0d\xc8\x16\xac\xa9\x8c\xc0\x7c\x34\x4e\x94\xc1\x75\xe3\xb2\x42\x01\xac\x7c\xa1\x69\x4b\xe3\x54\xb8\x36\x42\x17\x6c\x84\xcd\x28\x4e\xb5\x83\x5d\xe5\x0d\x76\x09\xc0\xcc\x5b\x01\xd3\x07\x99\x5a\x95\x3a\x72\xc9\x7e\x0e\xe9\x5b\xfe\x80\xa4\x09\x0a\xa6\xaf\x2f\x2e\xce\xb7\x89\x68\x2c\x45\x8c\x45\xc8\xde\xda\x0b\x8b\x5f\x17\x72\x46\x5e\xa0\xb1\x34\x16\x67\x6f\xdf\xec\xc9\xcb\xa9\xce\x17\x8d\x15\x75\xbc\x19\xeb\x34\x5a\x66\x77\x41\x19\xe6\xc2\x6b\x5c\xb3\x6f\x6f\xee\x6e\xb6\xe1\x83\x86\x1b\xef\xdf\x2b\x8d\x17\x32\xed\x0f\xa5\x8c\xc4\xa3\x40\x6a\xea\x3f\x3f\x0d\x82\x62\x93\xa5\x14\x42\xb5\xd4\x17\xf9\xa6\x8f\x13\x62\xe5\xfb\xe7\xa5\xf1\x88\xc5\x55\x69\x7a\x17\x81\x33\x37\x09\x20\xd6\x62\x8c\x37\x3c\x6d\x52\xff\x79\xb3\x9a\xc6\x96\x38\x37\x45\x74\x98\xdb\x6d\xb6\xab\x2f\xeb\x41\xf4\xa1\x3b\x9c\x52\x1d\x10\x71\x3f\xfd\x3e\x73\xf1\xb1\xfd\x38\xcc\x27\xa5\xa5\x2a\x96\xbd\x20\x7c\xf7\x1b\x26\x0b\x8d\x4d\x1d\x8f\x5f\x1d\x9f\x91\xa8\xff\x86\xd2\x20\xe1\x60\x66\x52\x4f\xbe\x45\x87\xf0\x4f\xe3\xb8\xd8\x6a\x40\x26\x6f\xf7\xc0\x51\x9c\x6f\xc6\xb5\xa5\x24\xb2\x10\x02\xcf\x6f\x0d\x98\x8b\x8f\x4d\x65\xdb\x77\x59\xc3\x6c\x5c\x9c\x24\x0e\x7b\x54\x95\xed\x4b\xf1\x11\x2a\x13\x88\x17\x1e\xe9\x59\x51\x12\x5b\x81\x92\x69\xa5\xdc\xe7\x58\x8a\xd9\xe4\xcf\xe3\x66\x05\x25\x44\x38\xb9\x17\x17\x9d\x6f\x5c\x1e\x71\x21\xcb\xa9\xbc\x9a\x1f\x4c\xa5\xe4\x7c\x00\x02\x5f\x41\x01\x7d\x08\x7a\xf2\xa0\xfe\xf6\x09\xec\x94\x12\xaa\x35\xf5\x6b\xc1\xaf\x65\xf5\x8e\xf4\xd5\x4d\x5e\x6a\xe8\xe2\x96\x6f\xcd\x94\x05\x4b\x09\x05\xe7\x4e\x7f\x73\x7f\xb3\xbd\x41\x39\x84\xa7\xab\xb1\xbb\x20\x25\xd4\x3a\x45\x12\x07\xdc\xdf\x1c\x15\x2e\xe5\x27\x01\x32\x61\x51\x9a\x4e\xa4\xe1\x10\xe1\x72\xd2\x2e\xa0\x84\xc5\x4e\xc8\xdf\x65\x95\x5f\xaa\x22\xf8\x2a\x53\xc2\x4c\x84\xd5\xea\x10\xfb\x7e\xaf\x5a\x18\x21\x50\x28\xe1\xb1\xec\x7d\x95\xf2\x65\x58\x16\x25\x5c\x01\x36\x71\x54\x2e\xdb\x97\xa2\x2a\xfb\x4d\xe8\xf3\xd5\x88\x24\x71\x84\x2d\xb0\x6d\xbe\x87\x2e\xfc\x2e\xc2\xb7\x26\xa9\xc6\xdc\xee\xf2\x66\xfb\xbb\x13\x00\x9b\xde\xa2\x44\x39\x2e\xfa\xc8\xa3\x29\x1c\xd1\x2e\x58\x3a\xb6\xd6\x89\xec\x7a\xcb\xa2\xf1\x66\x49\xd2\x38\xc3\x3b\x8c\x25\x4d\x07\xd5\xf8\x4c\xdc\xd5\x7f\x4a\x10\x86\x52\x70\x2b\x2c\xce\x82\x59\x1d\x0e\x85\x17\xc8\xff\x34\xc8\x26\x59\x2c\xb2\x9e\x63\xbd\xf2\x44\xc8\xc0\x18\xbf\x70\xb5\x9f\x33\x49\xe0\xbc\x1e\x86\x80\xcd\xf9\xd8\xe9\x04\xcb\x58\x12\x7b\xc9\x94\xc7\x5c\xbf\xca\x9f\x33\xc5\x42\x4a\x64\x24\x1d\x07\xd4\xdc\x0c\x33\x41\x0a\x47\xb6\x0b\x01\xf1\x43\x79\x01\x2f\xb2\xb0\xb3\x1a\x05\x25\x52\x2a\x5c\xf2\x5f\x64\xb3\xf3\x9a\x3d\xbb\xb6\x7b\x80\x30\xa8\xb5\x53\xa2\xbc\x70\x8b\xeb\xda\xbb\xe4\xf3\x09\xfc\x3c\x5e\x5c\x08\x89\x8a\x1d\xb8\xcf\x56\xc7\xba\x75\xda\x6e\xeb\xed\x65\x7f\x42\xca\x22\x1f\x25\xee\x86\xbe\x11\x25\x2a\x61\x58\x68\xf6\xaf\x7d\xf7\x44\x57\xc8\x4e\xba\x5a\x50\x75\x0a\x9f\xd1\x09\x4e\x92\xa9\x21\x7f\x38\x08\x91\x70\x8e\x3a\xfa\xb5\x0b\xb7\x8e\x65\x7b\x27\x7f\x86\xaf\xd3\x91\x13\xcb\x43\x6b\x77\x59\xf4\x7e\x38\x48\x31\x19\xaf\xb7\x44\x2b\xcd\xfd\x7a\x94\x97\x23\xdb\xe6\x70\x58\x5b\x5c\x36\x8c\xfc\xe8\x49\x83\x94\x68\x2b\x9d\x63\x7e\xb5\x87\xe2\x42\xaa\x91\xf8\x09\x25\x46\x49\xf0\x35\xf2\x6d\x3e\x5a\x73\x67\xbf\x0e\x22\x11\x92\x76\xa7\x2d\x18\x94\x58\x28\x01\x95\x21\xdd\xe3\xf2\xf2\xb7\xbf\x04\x6f\xa5\xc4\xca\x14\x8b\x91\x9b\xef\xe3\x2b\xb1\x3a\xc6\x4a\xc4\xfb\x8b\x6c\x9f\x06\xbd\x58\x4a\x63\x06\x18\x86\x36\x68\xdc\x11\xfe\x4a\x74\xe2\x24\x64\x4c\x17\x4d\xe4\x0d\x62\xc6\x42\x8f\xd6\x8f\xa1\xdc\x44\xcc\x41\xe1\xbe\x54\xa1\xd1\x46\x29\xcd\x64\x20\x8e\x3e\x55\xaa\x72\xcf\x23\x90\x07\x27\x13\x93\x52\xc3\x32\x8f\x1d\x47\x3a\xf1\x63\x95\x97\x33\x00\x0e\x0e\x42\x1d\x9d\x7f\xe6\x45\x01\x75\x7e\x0c\x9e\x26\xe3\xf0\x91\xb2\xd4\x09\x1c\x75\x31\xb1\xf7\x8b\x31\xf0\xf3\x7a\x00\x55\x2f\xbe\x79\x94\x41\x8a\x4d\xc1\xeb\xd5\xed\xe5\xc3\xfd\xf2\xd3\xa1\xdc\x38\xb7\xdd\x6f\x9b\xf5\xd3\xee\xcb\x7a\xbb\xbb\x7c\x7a\xf8\x71\x85\xa0\xa6\x11\x00\x9f\x52\x0e\x31\xc2\x5e\xba\x57\x2b\xe8\xb4\x84\x63\xa9\xc7\xc8\xf9\xb2\x76\xfe\x07\xfc\xf2\xe7\x34\x77\x4a\x53\x29\x11\x7f\xda\x7c\x34\x2d\xec\x57\x0e\x96\x17\xb8\xa9\xfd\xb9\x81\xa2\xfb\xc1\xd8\x5c\x6c\x70\xcd\xf7\x83\x04\x50\xc9\x7b\x55\xfc\x9b\xb2\xbd\xce\xa1\x30\x21\x41\xa6\x19\x57\xae\x07\xfc\xed\x12\xa9\xa8\xf8\xc3\x36\xfd\x51\xe1\xf9\xaa\x55\x51\x0c\xf7\x3c\xb3\x34\x72\x29\xe2\x5b\x3e\x14\x22\xa6\x4b\x04\x95\x51\x8c\x78\x0f\xa4\xac\x22\xda\xc0\xab\xf7\xfb\xee\x0c\x90\x53\x8c\x56\xf8\x28\x15\x18\x93\xbf\xc1\x4b\x0d\xff\x85\x9f\x79\xd3\x9e\x79\x8c\x32\xd1\xb2\xff\x92\x5d\x8d\x82\x87\xb3\x59\xa4\x44\x82\x13\xe4\xe6\xf2\xe1\xf2\x69\xbd\x0e\x95\x06\xaa\x24\x37\xc1\x1b\x35\x2f\x8a\x41\xe0\x8a\x52\xcd\x18\xf6\x7d\xf6\x3b\x44\x25\xba\x06\x77\xbf\x5e\x52\x9d\x00\x38\x2d\x9a\x63\xe9\x05\xdc\xfa\xd7\x47\x0b\x86\x11\xf4\x3e\x2f\x87\x0f\x18\x99\x46\xbe\x18\xb8\x48\x2e\x9d\x5e\xb0\xb1\x19\x72\x63\x9a\x16\x0e\x0f\xe5\x5c\x5e\x8a\x52\x48\x9d\x7f\x4b\x6f\xa7\x59\x85\x6e\xda\xe2\x5a\x4d\x41\xb8\x37\x3a\xf4\xaf\xc6\x52\xf1\x94\xda\x54\xe9\xe0\x41\xde\x9b\xd1\x6d\xda\xe0\x33\x4e\x19\xea\xae\xfd\xdf\xff\xf3\x7f\x5f\xab\x16\x8a\x2e\xe9\xfd\x6b\xab\x11\x8b\x88\xc4\x48\xe6\xb2\x38\xaa\xd0\xea\x98\xb6\x9b\x29\x8b\x12\x48\x3d\x9d\xd6\xb1\x94\x7b\x72\xd8\x99\x05\x93\xc5\xc2\x59\xa1\x36\xd0\xae\xdb\x97\x6d\x75\x09\x73\x47\x60\xca\x48\x9a\xf0\x24\x80\xad\xac\x3c\x16\x6d\x17\xd1\x3e\x41\x53\x15\xce\x47\xcf\xc9\x45\xf8\xd1\xd4\x70\x3e\x29\xab\xcb\x62\x84\x2c\xeb\x8e\xbb\x92\x87\x33\xf8\x29\xdf\x64\x9d\xcb\xb2\x2f\x23\x32\x16\x45\x84\x04\xa8\xca\x66\x52\x64\x1e\x65\xc0\x8c\x75\xd9\x9c\x87\x64\x2d\xe2\x63\x87\xcb\x4f\x22\x8b\xa2\x6c\x5e\x77\xc6\x27\x97\xe1\xfb\x12\xe9\x34\x66\xee\x56\xbf\xdd\xdc\xad\x6e\x77\x8f\xab\xa7\xed\xcd\xe5\xcd\xe3\xa8\xcf\x41\x59\xca\x62\xe9\x2a\x72\xad\xad\xea\xfd\x8f\x59\xe1\xcc\x8f\x12\xa9\xcb\x8c\x37\x37\x5f\x4e\xd5\x10\x28\x13\x22\x43\x5c\xca\xb1\xbc\xae\xba\x6b\x98\x4e\x53\x26\x32\x86\xec\xa2\x7d\x5e\xb6\x81\xea\x38\x94\x91\x98\x4c\x15\xaa\xbf\x36\xb2\x6a\x64\xc5\xfa\x3f\xeb\x14\x3b\x12\x4f\x0f\xb7\xeb\xdd\x97\xa7\xd5\xd5\x7a\xf7\xf8\xf4\xf0\xfd\xe6\x6a\x1d\x4a\xc0\x4c\x2b\x22\xbc\x85\x5d\xf7\x75\x43\x50\x33\xae\xf7\x31\x6d\x5c\x37\x44\x1d\xbd\x31\xc6\x97\xba\x7a\x6f\x5f\x6e\x73\x0b\xfd\x89\xac\x70\xd2\xbd\x61\xf6\x15\x47\xb5\x9c\x1f\x32\x13\x09\xd4\x7b\xbd\xaf\x2e\x1a\x47\x36\x0a\x27\x31\x54\x45\xe3\xe2\xe3\x36\x3f\x5c\x57\xf5\x15\xbc\x41\x51\xf5\x96\xb3\x94\x19\xe0\x08\x1f\x47\xa0\x75\xfb\xb2\x54\xfb\x62\x96\x73\x6c\xdd\xf7\xc5\xeb\xcd\xc0\x0e\x0c\x2d\x1b\x66\xb3\x34\x65\x23\xc7\xc3\x2e\x6f\xf3\xc9\xd3\xf4\xfe\x5b\x6d\xb9\x57\xd1\x73\xaa\xc8\x97\x8e\xe4\x64\x4e\xcc\xd6\x29\x8f\x94\x36\xce\xc1\xaa\xcb\xb5\xb0\xfa\x1f\x8e\x98\x08\xbb\x6a\x9b\xfc\x79\x49\x05\x89\xf2\x58\x24\x28\xe4\x9c\x97\x8e\x22\xf6\x58\xe7\x7f\x38\xe9\x9c\x91\x69\x13\xe5\x71\xe6\x74\x5a\xb1\x49\x7a\x9d\x97\xe1\x21\x70\x12\xc5\x01\xe5\x3c\x90\xf1\x3c\x81\x6b\x72\x7b\x38\x89\x78\x90\xcf\x7e\xbc\x71\x95\xff\x38\xea\x4f\x93\xb8\xe2\xc5\xed\xf5\xd5\x3d\x38\x83\x31\x7f\x84\xb2\x08\xcb\x24\x17\x79\x0b\x83\xca\x20\xe5\x2c\x75\x3e\x61\xd8\x2f\x9c\x95\x66\xc2\x10\x93\x20\xff\x45\x7a\x67\xf1\x62\x64\x99\x4a\x39\x8f\x88\xf5\x02\xa6\x97\xb2\x85\xe7\xaa\xfe\x58\xea\x25\x53\xce\xa9\xc0\x0b\xef\x9f\xab\xc3\xaa\x4f\xa6\xc0\xfc\x23\x2a\x8d\x7c\x17\x6d\x73\x90\x1a\xba\x0d\xdb\x29\xd6\x0e\x1d\x1d\x9e\x10\x47\x35\x76\xe1\xf2\xda\x67\x4f\x9f\x6e\x1e\x3c\xc9\x98\xf3\x41\xec\xf6\xe6\xea\xd8\x34\xad\x7c\x06\x33\xec\x6d\x3c\xb1\xe0\xfb\x77\x25\x34\x79\x83\x6b\xa1\xeb\xa6\x86\x11\x69\xe4\x44\xca\x5b\x27\x8e\xfa\x19\xf1\x85\xf2\x94\xa6\xb1\x19\x42\x90\x33\xa3\x44\x94\xa2\xb8\x8e\x6f\x93\x5f\x1d\x61\x5b\xdd\x94\xd8\x06\xce\xdb\x8f\x5f\x46\x33\x55\x10\xab\xf9\x08\x12\x56\xcb\x62\xd2\xde\x9b\x9d\x97\x66\xd8\x19\xb8\xaa\xf6\x79\x39\xf1\xae\xa2\x5c\x68\x92\x05\x68\xaf\x0f\xbe\xfc\x2c\xe8\x96\xc3\x7b\x78\x7f\xfa\xf2\xdb\xc8\x18\x89\x72\x61\xb2\x84\x07\xeb\xcc\xd3\xca\x3d\x97\x5a\x60\xb2\x56\xc8\x06\xf7\x63\x57\x6e\x0d\x9f\xd6\x36\x66\x64\x60\x43\xee\x8f\xfb\x89\xcd\x56\x17\x32\x0b\xac\xab\xef\x6a\xf8\xef\x31\xaf\xe1\x1f\x03\xf4\x71\xfa\x3d\x86\x3a\x1e\xaa\x4b\xe3\xbd\x0e\xf4\xd2\x82\xc2\x41\x64\x22\xcc\xa2\x25\x19\x41\xca\x21\x8b\x30\xe3\xda\x40\xbb\xeb\x77\x77\xf4\x58\x5a\x9e\x97\x36\xe2\xa9\x09\xa4\xe7\x1b\xff\xca\x87\x6d\xf1\x2c\xa6\x9e\x26\x11\x81\x0c\x02\x27\x37\x7f\x9b\x96\x15\x93\x28\x51\x34\x0a\x9a\x4d\xd5\xc1\xcb\x0f\x8d\x1e\x7b\x12\xc7\x80\xbd\x95\xeb\x1c\xc9\xcb\xe1\x83\x31\xd1\xca\xcf\x86\xb6\xe8\x6b\x68\x13\x10\xf3\xfc\x4a\x48\x0a\x88\x1c\xc3\x37\x7a\xd3\x1e\xcd\x90\xb7\x24\xc4\xc4\xd6\x07\x06\x5f\xe4\x5e\x15\x50\xcf\x3d\x69\xfa\x3b\x91\x50\x1e\x63\x8c\xab\xf2\x3f\xf4\x30\xab\x12\xaa\x62\x6c\x1e\xb4\xa8\x6e\x7b\x26\xbb\x5f\x28\x81\x27\x2c\x15\x28\x40\xe7\x1d\x28\xf0\x71\x5e\xca\x43\x17\x99\x84\x73\x73\xa2\x91\xd2\xe3\x8c\x21\x26\x41\x5f\xc2\x13\x83\x44\x1e\xf0\x00\xc3\x3b\x68\x5f\x2a\x73\x13\x4a\xcf\x33\x06\xa3\xff\x50\xc2\x04\xe2\x2b\x71\x3d\x7a\x42\x9e\xf6\x42\x6b\x33\x49\x89\xd3\x2b\x75\xb3\x7e\x87\x24\xcb\x72\x3e\xc6\x3a\x27\x3b\x24\x43\x60\xbf\x68\xd2\xcb\xf6\xa3\x44\x96\x48\xbf\xd8\x63\x80\x38\x51\x48\x5c\x2c\xc9\x25\x32\xa6\xb1\x3f\x71\x58\xf5\x89\x98\x94\x80\x12\x99\x24\xe8\x72\xf1\x05\x25\x12\x8d\xcb\x85\x1e\xa1\xde\x80\xae\x66\x70\x63\x9a\x48\x48\xb0\xdc\xe4\xa4\x36\x42\x2d\xfa\x88\x2e\x3a\x7e\x88\xa2\x4e\xaa\xea\x20\xeb\xb6\x84\x7a\xd2\x29\x4f\x94\xa1\xa2\x17\x61\x5f\xb7\x2f\x58\xd9\xbc\xae\x6a\x14\x4b\xea\xad\x8f\x68\xa2\xa9\xbb\xa8\x1a\x0a\xf9\xe1\xe2\x3e\x0f\x12\xb8\xec\x7e\x6d\xd1\x2b\x34\x7e\x86\xad\xf6\x02\x8e\x31\x11\x9f\x95\x9d\x13\x63\x22\x31\xf8\x32\x7f\x19\x14\x6d\xcf\xe4\x90\x8b\x7a\x37\x27\x8e\x55\x34\x81\x88\xab\x41\x47\xfc\xf1\xeb\x6f\x67\xde\x05\x60\x84\x44\x83\xd6\x79\x5e\xba\xb2\xda\x3f\x8e\x55\x7d\xdc\x3f\xce\x68\xae\x34\x01\x10\x18\x51\x3b\xae\x7c\x4f\x4e\xf1\x47\x6d\xe2\x70\xee\xdd\x62\x80\x77\x7e\x85\xc2\xde\xf3\x12\x41\x1a\xf1\xd8\xf9\x73\x75\xaf\x82\x2b\x5c\xcc\x06\x68\x57\x0f\xdd\xd5\x70\x90\x1f\xb7\x95\x3c\x53\xf2\x4c\x23\xed\xa4\x6b\x83\x85\xd6\xc8\xc2\x81\xa6\x11\x24\x58\xc5\x39\xf4\x52\x02\x60\x56\xe1\x95\x4c\xe3\xc8\x29\x24\xf4\x2d\x33\x5f\x82\x18\x02\xdd\x34\x8e\x12\x2c\xe1\x68\x59\x14\x27\xcc\xcf\x51\xc4\x9a\xc6\xcc\x95\xf2\xd0\x48\xcb\x75\x80\x9e\xa0\x81\x65\x9c\x23\x4d\x29\x38\x87\xd6\x81\x7b\xf6\x3f\xb1\xb6\x68\xca\xe2\x88\xf9\xc4\xa6\x2f\xfe\xc9\x5a\xe5\x6d\xe3\xd2\xda\xf0\x03\x98\xd5\x89\x0d\x4e\x62\x4d\x8b\xae\x18\x67\xae\x89\x47\x26\x73\xc1\x69\xfd\xd6\xbd\x7f\xf3\x85\x27\xcc\xd8\x34\x8d\x29\xa2\xa8\xba\xb5\x42\xcb\xc3\x97\x4a\x16\x28\xaa\x00\x7f\xaa\x0d\xd7\x9f\xc0\x12\x2f\x08\xff\x60\x6f\x4a\x5b\xc8\x81\x30\x1d\xf6\x95\x34\x05\x27\x6a\x92\xb7\xb0\xff\x35\x2f\xcd\x38\x6f\x4b\x85\x15\xc8\x08\x32\xd0\xb4\x75\xf5\x71\x2d\x9b\x97\xb1\x0b\xf8\x78\x45\x48\x33\x62\xb0\x07\xd9\x6d\xed\x9b\xa3\x72\xcb\xd6\xf1\x03\xea\x19\x7f\x83\xa6\x19\xa5\xc6\x53\x94\xf5\x66\xfb\x8f\xcf\x82\xbc\x34\xe3\x09\x56\x15\xd7\x37\x8f\x71\xc2\x7b\x15\xd8\x3e\xd2\x4a\x25\x8b\x53\x3d\x68\xca\xeb\xfe\xef\x99\xc1\xfd\x32\x47\x19\xf3\x8d\x33\xe2\x0a\xc7\x40\x78\x13\x83\xdb\x4a\x9a\x91\x32\xf5\xec\xcb\x15\xb7\x08\x0b\xef\x66\xdb\x4e\x2d\x85\xbf\xa9\x4e\x04\xea\x8f\x9a\xbc\x91\xcf\x35\xc0\xe4\xf6\xe9\x4c\x50\xd7\xd9\xe8\x92\x0a\xa4\xe0\x0f\x12\xf7\xdd\xe1\x4c\xf9\x2d\xdd\x05\x51\xcb\x57\xa1\xbd\xf3\xc1\xd7\xa3\x3a\xf5\x65\x5b\x9e\x63\x5a\x26\xf8\xca\xc9\xa2\x58\x3d\xe7\xe5\x33\xf2\x89\x9c\x8d\x51\x18\x61\x1d\x85\xf6\x45\x36\xae\x83\xbd\x5b\x2e\x6c\xa7\x86\x59\x2b\x86\x37\x60\xf7\xfa\xa1\x77\xaa\xbb\xda\x9d\x09\x6a\x43\x7d\xa8\x94\x02\x01\xa4\x12\xde\x94\xcd\xb1\x86\xc0\x58\xa7\x29\x18\x0a\xa3\xd8\x15\x2b\x59\x9f\xf7\x4a\x52\xb0\x19\x62\x85\xba\xb4\xa1\x5e\x34\xe6\xf7\x03\x6d\xa6\xad\x2b\xa4\xbd\xcb\xda\x8c\x01\x11\x18\x00\xf4\xbf\x44\x44\x40\xac\x6f\x5c\x7d\x95\xcd\xcb\x83\xdd\xbe\x40\x97\xb2\x81\xb9\xf2\x46\x3d\xfd\x48\x6b\x50\x24\xb6\x84\xf7\x9e\x8c\xe0\x0f\xc5\x9a\x24\x7e\x41\xf8\x1d\x64\x5d\x7c\x7c\xdb\x5c\x6d\x64\x21\xcf\x75\x63\x45\xac\x55\x00\xb1\x3d\x55\xef\xba\x2a\xe6\x4f\x39\xa8\xe5\x50\x41\x98\xc5\x4a\xce\x8b\x44\xdd\xbe\x87\x63\x7f\x41\x44\xa4\xc4\x59\xb4\x56\xb5\x41\x83\xb6\xa6\x47\x47\xc2\x44\x82\x85\x0a\x74\x71\xea\x6e\xdc\x0b\xe8\x57\x54\xe6\x3a\x0e\x9a\x1e\x93\xff\x9f\x2c\x37\x82\xd2\x0c\xe3\x0e\x47\xe4\xf8\x02\x41\x3f\x69\xfa\xf2\x0a\x4a\x15\xa2\xb2\xb0\x8f\x38\x76\x74\xc1\xef\x5b\x00\x8f\x09\x9a\xb9\xee\x43\xeb\xf6\x75\x0f\xa2\x81\x87\x72\xd8\x00\x04\x95\x09\x3e\x44\x3c\xc9\x6d\xbe\xef\xf5\xdb\xe4\x54\xf2\x8a\x0a\x46\x7c\x5d\x51\xfe\x5c\xcb\xba\xdb\x4e\x1a\x9c\x4e\xcd\x93\x93\xa3\x09\xc3\x92\x38\x08\xcb\x7a\x6b\x67\x30\x3e\x92\x1d\x6b\x7f\x52\xc1\x44\x86\x22\xb8\x7d\xcd\x77\x26\x8a\x38\x7b\x9c\x3c\xf2\x2a\x87\xb2\x00\x5f\x51\x9e\x15\xe4\x04\x4f\x0c\x62\x9d\x03\xe8\xb5\x2c\xc6\x02\xf6\x54\x24\x32\x72\x24\xc1\xa2\x6a\x4e\x98\x79\x7e\x4c\x4a\x38\xf3\xc8\x41\x59\x3f\xef\xe2\x5d\x5e\x1e\xe6\xc9\x94\x48\x55\x84\x31\x67\x6f\x32\x33\x7c\x87\x88\x94\x74\x82\xad\xc3\xa9\xff\x45\xfe\xbd\xdc\xa8\xf7\x9f\xc9\x58\x46\x82\xf7\xa6\x0e\x19\x78\x7f\x43\x55\xec\x6a\x10\x55\xd9\x45\x1b\xfb\xbc\x5c\x95\xe6\xbe\x72\x90\xa8\x30\x46\x6b\xc0\xbd\xc4\xc5\x58\xf7\x70\xe2\x3a\xf7\x69\x20\x77\x76\x23\x13\x26\xf5\x24\x5c\xf4\x9b\xe8\x95\xf6\xa9\x80\x24\xc1\x6d\x17\xbc\xa0\x67\xb7\xba\x0e\x7c\x40\x2a\x20\xe5\x69\xda\x0b\x05\xd8\xfc\x79\x20\xaf\xce\x4b\x86\xc2\xc6\xce\xd5\xc7\x01\xa4\x42\x7e\x15\x0e\x92\x58\x3a\x45\xc9\xc3\xb6\x1a\x64\xa1\xe2\xfe\xc3\x1c\x9c\x55\x57\x2d\xdf\x91\x6f\x3d\x3b\xb7\x50\x09\x0b\x54\x83\xeb\x3c\xd4\x67\xef\xab\xed\x4b\x3d\x20\xf9\xff\xe5\x9f\x4f\xc8\xc3\x84\x95\xae\x8a\x8d\xcd\xa0\xfd\x3e\x3c\x8b\x2c\x8a\x33\x2c\x3a\x5e\xdd\x5e\xfc\x45\xfc\x5b\x16\x71\x1b\x3b\x1a\x51\x55\xc3\xaf\x65\xa5\x5f\xab\x63\xdb\x9c\x38\xb2\x8e\xb9\x6d\x34\x8b\x12\x12\x0f\xf6\x3d\xdd\xd3\x76\xc8\xec\xe9\xaf\xcb\x22\x13\x23\x02\xf8\xf7\xea\x78\x05\xb2\x18\xb7\x96\x32\x62\x08\x4a\x61\xe6\x8d\x87\x38\xcf\x93\xad\xc9\x55\xd2\x98\xa1\x68\xde\x77\x8c\x7a\x31\x8e\x5c\x28\x04\x67\x2c\xd6\x58\xe0\xa8\xca\x77\xaf\x6e\x15\x0e\x28\x67\x97\xf5\x0c\xed\x0f\x90\x87\xaa\x1c\x6c\x9b\x68\xc6\x33\x15\x98\x72\x5d\x48\xb0\x28\x33\x48\xb3\x24\x72\x60\xc7\x5a\xe6\x25\x96\x8e\x27\x69\x78\x96\x64\x29\x02\x43\x37\x27\x2a\xa7\xb3\xd3\x18\x07\xa5\x0c\xae\xe5\x17\x1f\xeb\xbb\x87\xfb\xed\x2f\xa3\x8c\xe5\xa4\x13\x93\x25\xa0\xb1\xe1\xb9\x81\xf6\x78\x98\x41\xc3\xc2\x10\x9b\x60\xd1\xab\xef\xa7\x7c\xf6\x26\x05\x03\x66\x9a\xa5\xdc\x59\x1c\xef\xde\xba\x65\x5b\xb6\x70\x01\xa8\xcc\x88\x5c\xd3\xd1\x22\x90\xa5\x89\x8a\x20\x28\x0a\xb6\x6d\x01\x83\xa0\xfe\x79\x56\x02\xcd\x44\x24\x35\xf3\xe0\xd7\x17\x68\x4f\x3b\x74\x53\xa4\xe7\x38\xa6\xcf\x04\x67\x41\x0f\xf4\x6e\xee\x5c\x4d\xb3\x2c\x96\xbd\x42\x38\xd6\xc7\xba\x10\xf6\x7a\xb4\xd4\x67\x19\x61\xa9\x13\x65\x74\xd3\xc6\xe9\x6e\xb9\x3d\xf1\x6f\x8b\xf7\x39\xa3\x8e\x4f\xd4\xc0\x98\x32\x4b\xb3\x8c\x3b\x21\xb8\x97\xaa\xe8\x5e\xfe\x66\x8e\x05\xc8\xb2\x2c\xc5\x7a\x58\x5d\x1d\x0b\x68\x5b\x18\xaf\xeb\x59\xa6\x29\xa2\xbd\x65\xd3\xe4\xcf\xe5\x75\x0d\xf0\x04\x28\x0b\x3b\x85\x25\x86\x3b\x9d\x59\x81\x19\xf4\xea\x69\xbb\xbb\x5a\x5f\xde\xdc\xad\x6e\x37\xd7\xab\xcb\xed\x43\x28\xe2\x67\x92\xc4\x4e\xd6\xa3\xfe\x70\x2e\xce\x33\xc0\xd5\x74\x01\xcb\xa4\xcd\x40\x79\xb3\xc2\x59\x3b\x27\x53\x24\x71\x35\x29\xe3\x24\xea\x26\x12\x91\x61\x4c\xe2\xfc\xda\xdc\xf5\x87\x99\xba\x18\x9d\x65\x4a\x26\x6a\xa8\x55\x69\xe8\x65\x76\x69\xa6\x0c\x47\x7f\x16\x5d\x95\x4d\x5b\xeb\x21\x3a\xcc\xb4\x60\x58\xbe\x59\x99\x89\x01\x07\xcd\x74\xf7\x53\x7b\x57\x8c\x11\xc3\xb1\x27\xb7\x4f\xbf\x5d\x67\x8e\xb2\x83\x2d\x2f\x28\xef\x8f\xfb\xd9\xa4\x31\x91\xb2\x32\xa8\x36\x14\xf6\xa1\x5f\x8e\x8c\x70\xfe\xe2\x5f\x1e\x7e\xeb\xff\x04\xce\x4f\x75\xb0\xbb\x41\x7a\xfb\x99\x5a\x4b\x06\x0c\x9c\xef\x53\xde\x1e\xf1\x2e\xee\x74\xf0\x26\x0a\x67\x84\x0c\xb0\xec\xe5\x58\x8d\x7d\x60\xb1\x7a\xbc\xe9\x47\x58\x33\xe4\xe5\x3d\x50\x3c\x1c\xb5\x51\x3c\xe1\x2c\xdd\xff\xd4\xcb\x45\x85\xcc\x46\x90\xe9\x41\x0f\xe0\xf1\x78\x38\xfc\xb9\xf5\xef\xf8\x54\x71\xb2\xf8\x4f\x38\x7d\xa2\x50\xfa\xed\x1f\x47\x69\x6a\x59\x3a\x1e\x79\x3f\x5f\xac\x62\xb1\x47\xea\xed\x0c\x34\xba\xce\xb1\xfd\xb8\x7b\xe9\xad\x2e\xa9\x8c\x4c\x22\x1c\xa6\xf8\x90\xd7\x1f\xbb\x51\xb1\x57\xc6\x89\x40\x26\xe3\x7f\x9c\xad\xc1\xad\x6c\x5a\x0f\x77\x0f\x03\x32\x89\x84\x88\xbd\xfc\x79\x55\x57\x87\xe6\x11\xea\xed\xcf\xfe\xa0\x12\x6e\x42\xe3\xae\xd2\xd3\xa7\x97\xef\x93\x8c\x95\x71\x16\xe0\xd8\x04\xea\x96\xeb\x8b\x6a\x90\x40\x9e\x0d\x26\x3c\xb2\x59\x78\x38\x3f\xaa\x7a\x86\x01\x95\x34\xe2\x54\x0d\x0a\x6d\xdd\x5a\x34\xa5\xef\x48\x96\x2a\xdc\x24\xda\x8f\xfd\xec\x45\x94\x3c\x72\x2a\xb5\xd2\x98\xaf\x55\xdd\x80\xeb\x0b\x4c\x66\xaf\xe4\x5a\x20\x42\xb2\x35\x30\xd6\x12\xa1\x32\x11\x06\xa7\xea\xd3\x7a\xac\xa7\x4a\x65\x92\x09\x14\x3e\x45\x8d\x1e\x5f\x52\x0f\x35\xb1\xe1\x9f\xb3\x73\x20\xec\x12\x32\x4d\x2c\xd2\x39\xf4\xe0\x89\x37\x8a\x4d\x26\xef\x81\x4c\x53\x9d\xca\x5e\xb8\xf7\x58\x8c\xa9\x9f\x0b\xb5\x5b\x99\x2a\x86\x3b\xd0\x7f\x8f\x50\x7f\x3c\x16\x55\xeb\xf5\x62\x5c\xac\xd2\x7f\xc9\xb4\x12\x2d\x53\x65\xd0\xb9\x1c\x73\x87\x2e\x5e\x3e\xa5\xf5\x9e\x31\x47\x3b\xa2\xd7\x4a\xf8\x67\x31\xce\xf1\x9f\xf2\x8e\x2c\x54\xaa\x24\x46\x05\x22\x34\x06\xad\x65\x69\xa1\x7e\x28\x27\x48\x19\xa9\xb9\x30\x8e\xbf\x20\xdb\x97\x2e\x8a\xd8\x59\xd1\x1f\x4b\x49\x1c\xe0\x4a\x23\xe3\xc4\xd3\x8c\x48\x6a\x99\x3a\xaa\x88\x03\x6d\xde\x8e\xb0\x19\x7e\x84\x61\x6a\xe4\xdf\xd4\x2e\x04\x79\x61\xa0\x74\x38\x0a\xd9\x7d\xd7\x75\x55\xfb\x64\x47\x2f\x58\xb2\x2c\x9b\x9f\xcd\xa6\x80\xd1\x0a\xfb\xab\xef\xb2\x78\xbd\xa8\xaa\xd7\x49\x98\x2b\x8d\xd1\x98\xc7\x1f\x5c\x6f\xe7\xa4\x97\x31\x9b\x23\x06\x38\xc5\x66\x6d\x5b\xb7\x0e\x88\x3c\xc6\x5a\x4a\x88\xdc\x86\x79\x05\x5d\x84\x51\x9a\x66\x53\xca\x43\xf3\x52\x9d\x69\x27\x48\xa0\x8e\x6d\x24\xb1\xee\x37\x2e\x56\x86\x01\x4c\xe3\x1c\x43\x54\xef\xeb\xf0\x3d\xa0\x30\x78\xdf\x75\x69\x40\x91\x43\xe9\x8b\xa6\x67\xbe\xc6\x12\x8d\xb8\x3c\xf7\x16\x04\xa4\xcd\xa2\xfa\xcb\xb9\xff\x12\x4b\x1a\x31\xfd\xa4\xb6\x29\x35\xb4\x97\x53\x2b\x0a\xd0\x2d\x18\xe7\xee\x36\xb9\x7f\x2a\xe2\x3a\xf5\xb9\xee\x4d\xd3\x1c\x03\x42\xe0\x11\xea\xa1\x88\xae\x22\xc9\xb1\xf8\x9a\xeb\xea\xf1\xad\x5d\x8f\x6a\x37\x2a\x02\x86\xeb\xf7\xee\x58\x1e\xa4\x7e\x7d\x42\x85\x42\x2c\x35\x2d\x34\x1e\x54\x1c\x51\x8c\xb4\xbe\x8f\xd5\x4f\xa6\x71\x5b\xf8\x09\x8a\xf0\x08\xcb\xd3\x97\x5f\x2e\xc7\xef\x87\x62\x40\x22\xdd\x63\x79\x7d\x80\x81\xa4\x56\xd7\x1e\xbe\x3e\x5d\x24\xfc\x27\xb9\x74\x4e\x67\x79\xa9\xab\x7d\x5e\x3e\x3f\xc9\xd2\x54\x7b\xdf\x55\x5d\x88\x9f\x14\x37\x0c\xeb\xa8\xad\x7c\x85\x5e\xb0\x95\xaa\x84\x40\xec\x74\xd8\xdf\xa1\x69\xaf\xf2\x3e\x59\x54\x09\x28\x24\x55\x96\xe7\xc4\x37\xa9\x4a\x63\x01\x3e\xac\xb9\xec\x6e\xd5\x31\x77\x81\xe0\xc2\x4b\xac\x52\xee\xaa\x98\x4e\xab\xf2\x0c\xaf\xdd\x8f\x15\x92\x60\x57\xaa\xee\x82\x86\x59\x34\xa3\xb2\x58\x60\x95\xb1\xcb\xbb\xdf\x77\x0b\x6a\xbe\x54\x65\x42\x47\xbd\x79\xb9\xec\x1d\x35\xa9\xca\x14\xb3\x73\xf4\x5a\xb3\x9c\xe0\xaa\xcc\x46\xca\x55\x3d\x2d\xd4\x35\xd4\x38\x11\x46\xd9\xb2\x92\xc4\x69\xac\xf5\x30\x8d\x89\x5e\x31\x55\x92\xca\x70\x03\x73\x7b\x22\xd3\x7e\x92\xd3\x8f\x22\x6b\x25\x0d\x4f\xc6\xe2\xd7\xeb\xa7\x4b\x42\xe8\x49\xf2\x32\xfe\x88\xe2\x4e\x12\xa7\x3a\x40\xf9\x45\xee\xe1\x09\x9a\x63\xd1\xae\x4a\x73\x0f\xef\x5f\x46\x8a\xc6\x7f\x5b\x22\x91\x29\xa5\xa4\xc3\x20\x97\x1a\xca\x6e\x0f\x3d\x5f\x18\x54\x3a\x86\x38\x1b\x64\x00\x4b\x9c\x4e\xd3\x7b\xa7\x13\x83\x08\x16\xb9\x87\xd2\x5c\xc3\xfc\xd5\xd1\xa0\xf0\xd5\xc9\xcb\xbc\x7d\x28\x51\x26\x6f\x5e\x29\x56\xda\xc6\xb8\x79\x4b\x55\xd5\xed\xa8\x0c\xac\xb4\xe5\xd8\x13\x77\xce\xbf\x60\x5c\x91\xb7\x3a\xd6\x3a\x2f\x9f\xaf\xf2\xe6\x70\x6c\xe1\xa2\xb7\x29\xa1\xca\xc8\xd8\x4d\x26\x99\x37\x70\x27\x7f\xde\x1f\xf7\x17\x30\x07\x70\x29\x03\x1a\x81\xa4\xe8\x3c\x9d\x64\xb3\xa3\xa0\x63\x7c\x94\x97\x7d\x37\xea\x93\x22\xbc\xb2\xcc\x86\xcc\x19\x1d\x49\xeb\x66\x39\x79\x56\x56\xb8\xc6\xb1\xca\xeb\xf6\xc5\x71\xcc\xc2\x11\x70\xcd\x6d\xe4\x1a\xe7\xe6\x26\xfc\x1a\x1d\x29\xab\x78\x8f\x62\xfd\xd6\x40\xbd\x19\x64\x4a\xa8\x8e\x69\x1c\x5c\x45\xbc\x8b\x5a\x1d\x4f\xbf\x54\xc7\xa9\x73\xd6\xc9\x9b\x27\xe8\x9e\x71\xb7\x9a\x2e\x02\x3b\x74\x6c\x62\xe3\xa4\x20\x71\xd1\x75\xf8\xbb\xc5\x37\x56\x13\xe3\xdc\xb9\x4a\xf8\xd9\x76\xb3\xad\x07\x2b\xdd\xb9\x16\x16\x0a\xe7\xfb\xb1\x94\xa4\xb6\x6f\xed\xe5\xe5\xf3\x09\xf3\x53\xb3\x28\xc6\xed\x7c\x75\x75\xf5\xb4\xdb\xfe\xfa\x65\xf7\xfd\xb2\x3f\x14\x6b\xc4\x01\xdf\xc3\xfb\x37\xf4\x11\x01\xb3\xfc\x2c\xa6\xeb\xa5\x66\x9c\x22\x9d\xca\x7a\x2f\xe8\x49\x07\x56\xb3\x8c\x23\x50\x02\xc5\xe4\x1f\xec\x58\xb6\x72\xf8\x8d\xcc\x64\xd8\x9e\x38\x48\x24\xa2\x7c\xa9\x8a\x59\x57\x5b\x73\x15\x1b\xdf\x67\xfc\xc4\xb5\x9f\x6a\x6e\x49\x22\x11\x1e\xa9\x8a\x5c\x63\x11\xf7\x4b\x70\xf5\xfc\xa5\x1f\x23\x11\x72\xd9\xc4\xc4\xf7\x75\xfd\x81\x84\x8a\x24\xeb\xbb\x24\x53\x8b\xe3\x30\x44\x0b\x5c\xe6\xb6\x2f\xb0\xfe\xa9\x61\x52\x62\xd2\xa9\xd2\x9e\x8b\x68\x8c\x57\x37\x9e\x7e\x3a\x35\x12\xa5\xdc\xf6\x79\xe9\xc3\x90\x99\x35\x07\xd5\x82\x3a\xca\xf4\xa0\x81\x78\x95\xfb\xa0\x24\x0c\xc9\x98\x96\x49\x2f\x6a\x50\xd9\xf6\x52\x1e\x42\x3f\xce\x0f\x91\x91\xc4\xf2\xc0\x01\x6a\x5b\xd5\xfb\x8d\x57\x2f\xf5\x32\x20\xe8\xb5\xd4\x8f\x04\x30\x9e\x09\x9d\xd7\x80\x3e\x28\x7b\xa8\x6f\x46\xa7\xf2\x00\x46\xf3\x96\x37\xd5\x9c\x46\xa6\x25\x75\x32\x30\x3d\x35\xff\x2e\x9f\xf9\xcf\x51\x2d\xb9\x13\xf0\xaf\x41\x9a\x5d\x2e\xfa\x33\xa7\xb1\x49\x42\x6e\xac\x8f\x5d\x48\xe0\x4a\xf7\xe3\xb8\x52\xcb\x54\x69\xa7\xa4\xa6\x8e\xcf\xbb\x42\x36\xed\xce\x5b\x68\xf5\x97\xa8\x64\x84\x55\x14\xec\x06\xad\x4b\xb3\xcd\xf7\x40\x78\xd4\x1f\xd6\x96\xa7\xa1\x25\xea\x49\xa0\xab\xf6\x16\x9f\xee\x38\xa8\xd4\x3a\x06\xea\x31\x62\xbe\xea\xea\x3a\xd5\x7f\x92\xbf\x86\x58\x44\x6b\xce\x11\xe4\xff\x5e\x43\xd3\xf6\xcb\xaa\xd6\xdc\xf9\xa3\x76\x8b\x16\xe8\x97\x32\xd7\xb2\x70\xae\x90\xd3\xdb\xa4\x53\x85\xe8\xbd\xf2\xb8\xf7\x5c\xce\x9d\x57\x70\x1d\x7e\xaa\x16\x80\xfc\xc9\x0b\x68\x5f\xf2\xf2\xf9\x47\x55\x17\xe6\xf2\x18\xba\x17\xda\x50\x70\xa6\xf3\x7e\x77\xeb\xfd\xc9\x3f\x6d\x71\x69\x63\x14\x71\x66\x52\x07\xa4\x54\xfa\xba\x7b\xff\xad\x90\x68\xce\x83\x9b\xd8\xb7\xc3\x99\x77\x0f\x32\x8d\xd5\x06\x87\x27\x68\xa6\xfa\xda\x7e\x8c\x8d\x12\x34\x54\x50\xf9\xf3\x85\xec\xab\xda\xda\x32\x6b\x92\x90\x9d\x2f\xd3\x81\x4e\xc9\x61\x93\x7d\x56\xdb\x24\x45\xa0\xdb\x5b\x20\x7d\xba\xbf\x9b\x48\x58\x1a\x24\x8b\xbd\xfb\xea\x76\xfb\xc3\x79\x46\x1a\xd6\x8f\x52\x4e\x88\x69\xef\xd0\x5e\xd7\x00\x8f\xc5\xb1\x99\xbf\x7a\x26\xd2\xce\xcb\xe1\x19\xda\xdb\x50\x01\x30\x24\x8e\x52\x1b\x2c\x70\xd0\xe2\x65\x72\x65\x86\x10\x81\xcf\x35\x08\x67\x4d\x44\xca\x27\x01\x07\x5b\x4c\x1e\xa7\xde\x2f\xd4\x10\x1a\x3b\x1c\x55\xfe\x5c\x42\x7d\x5d\xc8\xe7\xe9\x4d\x36\x84\x3b\xe5\x94\x06\x3b\xa5\xb9\x9e\xb3\x9a\x0d\x11\x1c\x71\xd7\xa5\xdc\x43\x35\x7d\xdf\x0c\x81\x2c\xe9\x76\x88\x3f\xf2\xb2\xdd\x95\xd5\x7b\xf8\x95\x34\x35\xf8\xe4\x9a\x97\xea\xfd\xb1\xaa\x8a\x69\x40\x1c\x06\x09\x92\x25\x81\x74\x8c\x46\xf1\x3d\x86\x6d\x7a\x05\x54\x26\x6e\x23\x7f\x39\xa2\xd8\xfd\xf6\xeb\x6c\x00\x8b\x41\x25\x43\x6d\x63\xb2\xa9\x18\x96\x65\x48\x10\x0f\xb0\x1e\x6c\xb9\xdc\x5c\x3e\xf8\x8d\xd9\xf4\xe3\xa0\x87\xd4\x85\xf6\xd6\x24\xa7\x58\x9c\xc7\x86\x47\x29\x36\x5d\xfb\x72\xda\xfa\x67\xde\x8e\xe0\x6a\x27\xc0\xb5\xf9\xe7\x63\x19\x8d\x91\xca\x3b\x6c\x0a\xed\xda\xca\x5b\xd4\xcc\x46\x4b\x37\xfa\x31\x7f\x46\xe6\x55\xb8\x76\x6e\x19\x0a\x44\xf8\x6d\x75\x22\xf8\xeb\x87\x24\x59\x86\xf9\xe1\xef\xcf\xcf\xa6\x96\xcd\x0b\xc6\x6b\x7f\x26\x56\xf7\x79\x87\xcb\x24\x2a\xc1\x36\xc9\xfa\x90\x3f\x43\x79\x29\x6b\x38\x6d\xf5\x9f\xab\xe3\x2d\xe6\x53\x26\x31\xa9\x0a\x2e\x5b\xb2\x28\xee\xe4\xcf\xcb\xaa\x99\x11\x81\x4d\x4a\x9c\x18\xba\xc9\x35\xec\x9e\xe7\x36\x21\xd4\xa4\x3c\xc1\x06\x54\x77\x2b\xa7\x8d\x1d\x93\x72\xa7\x64\xd5\x40\xfb\xed\xc6\x7b\x60\x2f\x42\x7b\x4d\x9a\xb8\x5e\xa6\xbf\xbe\xeb\xe1\x66\x8b\x2e\x06\xc1\x4a\x5b\x75\xd8\xf6\xf5\x53\x93\x19\xc2\x07\xfd\xf4\xb3\x3d\xc4\x51\xb2\x60\x64\xc4\xb0\x2e\x73\xf1\x14\xf0\xfb\x46\x8a\x0c\xb7\x74\x3f\x1f\x64\x7d\x75\xf1\xf0\x3e\xf7\x55\xa3\x46\x47\xae\x46\x81\x92\x31\xaa\x00\x07\xab\x6e\x66\x37\x4a\x27\x14\x71\x40\xb8\x81\x78\x13\xe4\x73\xc2\x25\x46\x83\x34\x2e\x98\xa8\x41\xb7\x57\xa0\xf2\x76\x04\xc0\x9f\x7d\xbd\x4d\x3c\xbe\xfe\x38\xb9\xbd\x86\xcb\x38\xc8\x4e\x38\xb3\xc0\x55\x5d\xcb\xfe\x55\x34\x42\x04\x54\xc6\xaa\x69\xb6\x23\x28\x92\x31\x3a\x8e\x7a\xc3\x37\x6c\x8d\x3f\xbc\x41\x5d\xe7\x66\xfe\x70\x8d\x96\x90\x05\x52\x06\xc6\xf5\x83\xfa\xf8\x2c\x83\x1c\xbf\x7e\xfe\xd3\xa0\x59\x42\x43\x5f\xa6\x6c\x1f\xde\x67\x3e\x82\xd4\xd8\xd8\x91\x42\xd6\x97\x4f\x24\xfa\x5a\x95\xf0\xa1\xab\xbd\x9a\xfc\x4a\x9b\xc4\xc1\xa5\xe3\x1e\xde\xbd\x58\xa8\x8f\x34\xff\x12\x40\x0b\xa2\x54\x11\xdb\x43\x86\x9f\xc0\xae\xdb\x97\x3e\x19\xf7\x63\x62\x45\xb5\xfb\x96\xa2\xdb\x64\x5d\x28\x72\x71\xfc\x58\x8f\x4a\xc0\xe7\x50\xa8\xd3\x6f\x23\x11\xc7\x35\xaa\xdb\xa8\x8b\x3b\x59\x1e\x65\xe1\x64\xf6\xff\xac\x1a\x39\xb9\x33\x40\x04\x45\x4d\x4c\x27\xaf\x77\xdf\xe3\x64\x80\x28\x67\x1b\xd9\x7c\x94\x7a\x70\xe3\xa1\x40\x69\x8a\x3c\xab\xcd\xfa\x71\x52\x6f\x01\x9a\xc5\xd8\x09\xbe\x80\xe7\x67\x59\x4f\x0f\xa9\xd8\x57\xcb\x7a\xda\x6e\x90\xbc\x5a\x9e\x8b\x40\x6d\x12\xba\xe5\x01\x3e\x3b\x9d\x32\x40\xad\xc4\xf6\x09\x98\xbc\xdd\xe8\xaa\x86\x45\x51\x64\x3f\x98\x99\xde\x03\xf3\x4a\x7a\x00\xfc\xf4\x74\x9c\x5b\xec\x20\x74\xaf\xf9\xba\xd1\x75\xf5\x3e\x37\x6d\x98\xdd\x7f\x2e\x2d\xee\xa0\xd2\xf4\x0c\x0d\x7f\x83\x27\xc3\x12\x1d\xc7\x3e\xf4\xbc\xd1\x88\x93\xb9\xcd\x9b\xf6\xe2\xe3\x46\x57\x4f\xc7\x02\x6e\xce\xa4\x31\x90\x2a\x06\x9e\x51\x19\x98\x02\xb3\x2b\x16\x54\x61\xa2\x73\xf7\xb1\xd8\x78\x1f\x6f\xe9\x20\x12\x27\x51\xb2\x85\x06\x71\x77\x2e\xf5\x08\x99\x33\x3a\x3c\x8d\xfa\xa4\x67\x26\xe2\xbf\xf8\xbf\x97\x4f\x2e\x68\x3a\xf2\x4b\x3a\xf5\xc7\xa1\x90\x11\x81\x15\xfa\xad\xd4\x23\x1f\xbf\xc5\xb3\x65\x54\x11\x98\x90\x8a\x55\xbe\xc8\x98\x81\x8c\x67\x62\x70\x65\x77\xd5\xd4\x89\x51\x6a\x58\x32\x21\x4b\x2c\xd0\x9e\x96\x1b\x1c\x42\xc2\x41\x48\xa2\x2c\xac\x1e\xa7\x3c\x16\xd0\xb1\x52\xbd\x4a\x73\xa8\x7d\x0e\x8b\x1c\x74\x7b\x44\xdc\xcb\xac\x8d\x61\x48\xb3\x13\x19\xe9\x84\xb5\x43\x4d\xcb\xcb\x5d\x5c\xf7\xd6\x55\xa3\xa1\x36\xc3\x3a\xcc\xa1\x90\x7a\x5c\x02\x1a\x57\x1d\x01\x84\x8d\x7a\x25\x2c\xb0\x76\x92\xca\x00\xc8\x88\xb0\xc0\x7c\xdf\xd6\x20\x9b\xe3\x39\x60\x18\x80\x62\x58\xd3\x73\x2e\x2b\x6f\xcd\x13\x98\x4d\xf5\x93\xc5\x59\xf8\x8d\x36\xa2\xca\x13\xdb\x2f\x8e\xc5\xeb\x5d\x6e\xbe\x74\x8b\xf4\xa5\xac\xe7\x6b\xe3\xbc\x39\x03\x96\x48\xa2\x27\x9d\xe3\x13\x05\xf0\xd1\xee\x09\x56\x71\x8c\x5c\x55\x55\x9d\x98\xf6\xba\x21\x36\xd2\x1a\x11\x2c\x32\x98\x52\x5e\x56\x66\x4e\xb4\xb7\x71\xe4\xdc\xf9\x6e\xae\xee\x1e\xee\xd7\x41\x62\xc6\xc6\xb1\x48\x1d\xba\xb7\xc9\xcb\x65\xbb\x61\x6a\x63\xa6\xf0\xdd\xf3\xb2\xf7\xfb\x43\x51\x7d\x00\x4c\xe7\xe0\x72\xa8\x63\x63\x06\x18\xfe\x7a\xdf\x3f\x4f\x91\xed\xbf\x3d\x49\x0c\x4c\x98\x45\x3e\x40\x9c\x0a\xc9\xcd\xae\x26\xa5\x28\xbf\x71\xf1\xf0\x38\x9b\x26\x36\x16\x29\xc8\x11\x75\xf4\x1a\xc2\x32\x6d\x49\xac\x30\x32\x3c\xd4\xa8\x77\x80\x28\xe0\x79\xa9\xc1\x52\xe5\xf2\x96\xc6\xbd\xb9\xb8\x8c\x4e\x6e\x7a\x78\x83\x2c\xd5\x20\xe3\xa1\x48\x30\x13\x99\xb2\x14\x48\xd0\xc3\x40\xcd\xb5\x11\xd6\xc5\x52\x48\xb5\xe8\x97\xf2\x1f\x00\xaf\x6c\x02\x31\xf5\xc3\x98\x48\x30\x00\xfb\xcd\xff\x2f\xe2\xe1\x04\x2c\xcb\x94\xe8\x5b\xf2\xe3\x92\x9c\x4d\x58\x9a\x9a\x11\x6c\x75\x03\x6d\x7b\x0e\xed\x6c\x93\x14\xe2\x81\x7f\x55\x1c\xc8\x6c\xca\xa4\xd4\xbd\x4f\xd8\x6c\xdd\xdd\x5c\x3e\x90\xd9\x25\xa6\x8c\x21\x90\xe6\xef\xd0\x34\x39\xac\xcd\xd1\x6d\x65\xe3\xad\xce\x22\x48\xd5\xd1\xd7\x0e\xd2\x79\x57\x04\x1d\xa3\xd1\xbb\x6b\x45\x14\x89\xd1\x9a\x79\xb5\x7a\x58\xf0\x15\xa3\x36\x4b\x33\x1d\x20\x7e\xeb\xd2\xf5\x5c\x10\xdd\x9f\x57\x23\xb1\x79\x6a\x33\xe5\x44\x74\x6f\x2b\xfd\x7a\x3c\xb8\x87\x1c\x80\xe6\xfd\xa5\x65\x3a\xf5\x75\xe8\xb7\x13\x19\x42\x2b\x4d\x12\xec\x6e\x70\xa1\xeb\x1e\xee\xf4\xd7\x2b\x6a\x31\xca\xf2\x53\xfb\x2e\x7f\x76\x98\xa3\x09\x9e\xd9\x2a\xc9\x50\x8e\x77\x57\xbb\x4c\xec\xe2\xf8\x71\x0f\x3f\xdb\x27\x59\xce\x60\x49\x56\x83\x53\xb8\xf7\xb5\x1c\xbf\xe9\x4e\xbf\xd3\x08\x8d\xd0\xe0\x5e\x32\xd5\xe1\x18\xbf\xca\xe6\xe5\x13\xdb\x13\xff\x61\x4b\x22\x19\x07\x79\xf8\x6e\xea\xf8\xc2\x50\xb8\x54\xcb\x01\x5b\x5a\x18\xf2\x8f\xff\x9e\x45\xd8\x7b\xd8\xe7\x65\x4f\x95\x0a\x87\xa4\x93\x81\xbc\x2e\xf2\xe7\x97\x16\x1d\x80\xaf\x64\x2b\x95\x9c\x69\xcd\xb0\x28\x4e\x53\x4c\x6f\x03\x71\xef\xca\x09\xd6\x85\xaa\x1a\x8b\x62\x23\x32\x1f\xe1\xf8\xa4\xee\xb2\xc8\xad\xed\x42\x2d\xbc\x98\xf1\x6f\x61\x11\x89\x15\x92\xc8\x76\x81\xb7\xf9\x99\x38\x15\x8b\x48\xe6\x14\xd6\x76\xe8\x39\xf7\x7c\x9d\xff\x0c\x1b\xe3\x28\x2d\x9a\xc5\x88\xfe\x5d\x67\x11\x23\x8e\x49\x7f\xa8\xab\x16\xfb\x81\xe3\xd4\x9b\x45\x3c\x22\xa8\x3e\xbc\xde\xef\xf3\xe3\x7e\xa0\xe8\xb1\x88\x53\xb7\x13\x62\x14\x7f\x59\x1d\xeb\x66\xfe\x33\x38\x63\x91\x2b\xe2\xea\x63\x0d\x08\xb1\xf2\x47\x12\x42\x64\xb7\xe6\x7e\xbb\xbf\xd9\x7a\x1e\xdd\x17\xd9\xc2\xbb\xfc\x18\xd6\x12\x16\x25\x69\x6a\xdd\x5e\x5b\xb6\xc8\xe0\xe9\x0f\x88\x14\x4f\xec\x2e\xd5\x61\x20\xd0\x26\x12\x15\x40\x3c\x51\xbc\x09\xa3\x53\x42\x11\x5e\xfa\x05\x9c\xff\xc9\x20\x16\xc0\xa2\xd4\x68\xdc\x21\xf6\x60\x7a\x86\xe1\x0c\x7c\xc5\x22\x91\x69\x5c\x77\x56\xb7\xdb\x12\x7e\xb6\xe3\x9b\x20\xd3\x94\xc0\xe8\xcd\xee\x0b\x48\xd3\x33\xe8\x28\x66\xce\x3e\x03\x57\xa3\xfb\x81\x04\x14\x06\x50\xc9\x7d\xc3\xf5\x49\xea\x5e\x92\x80\x45\xda\x46\xc8\xde\xe9\xe5\x13\x97\x5a\x6c\x2c\x32\x9c\x69\x4f\xbb\xbe\xce\x07\xb2\xdd\x9c\x62\x74\x1a\x82\x75\x1f\x05\x41\x3c\xa1\x2a\x97\xc5\x75\x91\x4f\xcd\x3f\x58\x64\xa4\xc0\x02\xba\x07\xcc\x4c\xc4\xe5\x58\x04\x94\x62\x13\x62\xf3\xf5\x69\xb4\x36\xb2\xa8\x0b\xb2\xfd\x2e\x31\x28\x08\xf4\xf8\x67\x16\x81\x24\xb6\x4f\x17\x37\x8e\x7a\x98\xa3\xa8\xd3\x62\x13\x85\x45\x36\x93\x1c\x26\xc5\xce\xa9\xd9\xf5\x6c\xb4\x8c\x30\x63\xc8\x1b\xaf\x74\xeb\xc5\xcb\x26\x32\x42\x6e\x6c\x1c\x25\x5a\xf4\xa8\xa8\x2f\xce\x2f\xa7\x57\xea\x60\x71\x04\x1a\x0b\x7a\x35\x76\x86\x9f\x10\xee\x3f\xa3\x7e\xb3\x38\xb2\x52\xa7\x41\xcc\xc2\x69\xfa\x6d\xeb\x63\xd3\x82\x71\x0e\xd9\x7a\xd9\x5e\x9a\xc5\x31\x8f\x45\xea\x5b\x78\xc3\xc2\xc4\xe2\x58\x69\x19\x02\xbe\x50\x99\x5a\x95\xcd\x7b\xf7\xc3\x9b\x63\x31\xcd\x90\x58\x4c\x78\xea\xbd\x68\x06\xea\xf9\x20\x03\xbe\x78\x47\x63\x92\xe8\x60\x1c\xdc\x2d\xb2\x9b\xa3\xf2\xc9\x47\xef\xbb\xc7\x62\x46\x85\x93\xd4\x07\xbd\xdb\x07\x48\x42\x38\x26\x2c\x7a\xd4\x8d\xa8\x6d\xf3\xfc\x73\x41\xab\x9a\xc5\x3c\x72\xfa\xbf\x5e\x24\xe1\x62\xb2\xe4\xc4\x9c\x3a\x97\xa1\x1c\x89\x43\x1e\x89\x34\xc5\xb4\x84\x91\x3c\x45\xa2\x92\xd1\x65\x5b\x1f\x8a\xb3\x06\x79\x27\xff\xf6\xdd\x74\x16\xf3\xd4\x99\xf3\x87\x17\xec\x09\xcc\x6e\x31\x36\x63\x31\x57\x06\x73\x5e\xf7\x73\x4f\xbe\x6c\x21\xe3\x66\x71\xc2\x99\xf3\x4b\x97\xed\x0b\x62\x90\x1f\x0a\x73\xb2\xce\xf4\x93\x28\xd1\x31\x2e\x6c\xd8\xac\xec\xde\xc1\x45\x86\x16\x8b\x45\xa2\x43\x8b\x63\x50\xe6\x6a\x02\x62\x36\xdc\x48\x91\x31\x04\x44\x4a\xd3\xc5\x51\xaa\x00\x5d\xe5\xf3\xa9\x2f\xa4\xc6\x7c\xe8\x58\x3a\xf3\xa2\xde\x97\xd2\x1f\xcf\x58\x42\x9d\x51\x69\xf1\x1a\xca\x4f\xe6\x2c\x97\x98\xc5\x99\x17\x6c\x69\xa0\xfd\x9a\x7b\xd4\xcd\xf4\x2e\x66\x9e\x89\x9d\x3b\xe3\x2e\x30\xa7\xc5\x31\x16\x67\xa0\x51\xd8\xc6\xdd\xea\xcb\x97\x7c\xd6\x21\x64\xb1\x54\xce\x91\xba\x0d\x8e\x45\xa3\x39\x2b\xc1\xb1\xb5\x9d\x12\x62\xf8\xab\x8a\x9d\x33\x2b\x6e\x58\x8f\xd5\xd5\xdc\xc7\x81\xc5\x4a\x68\xe7\x0d\x5d\x57\xc7\x65\x4b\x42\x16\x6b\x2a\x31\xaa\x3f\x1c\xcb\x57\x2c\x2d\x0c\x6a\xe1\x7e\x84\x89\x34\x0a\xc6\xf8\x54\xfd\xb6\x92\xe6\x33\x9c\xfc\x6c\xc2\x98\x98\xeb\x2c\x78\xdb\xb9\x72\xd2\x60\xca\x34\xde\xb9\x63\xc3\x22\x44\xb5\xaa\xe3\x87\x57\x5d\x99\x4e\x12\x23\x0d\xcb\x82\xf8\x43\xb7\x3d\x1e\xaa\xa6\xed\x43\x92\xd8\x18\x87\x36\xc4\x6c\x64\xbc\x72\xc7\xc6\x50\x0c\x89\x10\xfb\xe6\x96\x10\x47\x32\xed\x82\xcc\x47\xd9\xc5\x83\x8d\xfb\xe7\xbe\x6a\x6f\xca\x6f\x4d\xbf\x20\x80\x77\x17\x75\x7a\x11\x79\x8b\xcb\xa8\x17\x95\x7e\x58\x96\x77\x64\x31\x24\x4a\x38\x58\xe3\x7f\x40\xb7\xbe\x17\xdd\xdf\xcd\x2e\x23\x42\x68\x55\xf0\xd5\x3f\x79\x6a\x56\x3a\x59\x62\x9c\x09\x59\xff\x39\x88\x51\x0f\xb5\x2a\xb1\x61\x80\x4b\x37\x72\x1e\x97\xda\x49\x8c\xc4\x54\xa2\xd1\x07\x36\x27\xeb\xb7\x5c\x43\xaf\xd7\x34\xb9\x5a\x12\xcb\x8c\x69\x8f\xa1\xda\x1c\x40\xe7\xb2\xd8\xca\x2e\x1d\x7b\x94\xfa\x55\x3e\x9f\x89\xd1\x08\x21\xc2\xf4\x5a\x47\x0e\x29\x89\x75\x55\xbc\x4d\xa7\x6b\xc9\x52\x4e\xc3\x08\x31\xc6\xfb\x1c\x75\x6b\xed\xa3\x3c\x36\xa1\xf7\xc1\x08\xcd\x52\x5c\x68\x0a\xd9\xb4\x68\x5d\x0c\xc6\x55\xbe\xfc\x71\xa6\x12\x54\x1e\xf7\xbe\x95\x81\x6c\xb4\x7c\x37\x98\xc9\xbc\x36\x55\xb7\x8f\x79\x3e\xd6\x92\xcd\x06\x23\x5c\x71\xc8\xfc\xf6\x95\xcb\xa2\xcb\x49\x16\x37\x1b\xc2\x3d\x4a\xbd\xe9\x76\x99\x76\xd2\x97\x39\x05\xe7\x77\xc3\x9d\x7b\xa6\x4b\xcb\x83\x25\xef\x94\xbc\x71\x26\xbc\x19\x56\x77\xc2\xb5\x56\xe8\x63\x5b\x1d\x55\x31\x80\xc5\x19\xe1\x90\x60\xe6\xb6\x59\xff\x76\xbf\x85\x66\xdc\x43\x64\x24\x49\x05\xc2\x24\x5f\xab\x20\x28\xc2\x48\x92\x29\x54\xc1\xbd\xb9\x7c\x98\x08\xd9\x32\x92\xe8\x04\x63\x7b\xdf\x12\x47\x84\xe2\xf2\x2d\x48\x8c\xf3\x0f\x73\xfd\x85\x4f\x83\x7a\x92\x72\x8a\x0b\xe9\xdd\xe5\xe4\xd2\x84\x4e\x70\xb2\x23\x05\xf0\x22\xaf\x67\xc5\xa4\x6e\x80\xc4\x3d\xd1\x15\x30\xfc\x75\x04\xe9\x80\xe9\xe5\x64\x94\xe0\xda\xbe\x77\x8d\x2a\x11\x85\x2f\xc9\x94\x5b\x3f\xf5\xc8\xd5\x76\xec\x9a\xde\x8d\xc8\xb4\x1c\x75\xe4\xc6\x8a\x7c\x8c\x48\x65\xb0\x49\xf0\xf8\xb4\xee\x32\xeb\xdd\xdd\xcd\xfd\xee\x72\xf5\xd8\x1f\x86\x04\x4d\x60\x5f\xf3\xa2\x58\xa9\x6a\x40\x44\x31\xa2\xb8\x03\x02\xf7\xa5\xb0\xe9\xbc\xd4\x69\x8c\x31\xe5\x15\xbc\x35\x7b\x59\x63\x28\x7e\x5d\x1d\xc3\x12\x4f\xb4\x8a\xb1\xf2\x8f\x74\x27\xdc\xa9\x96\x7b\xf7\x8c\x98\x84\x07\xb1\x03\x27\xf8\xd2\x05\x75\xc3\x75\x00\x17\xce\x8d\xd8\xe5\xb5\x2e\xe2\x6a\x96\xda\x4c\x8c\x40\x26\xf1\xcd\xf3\xfa\xeb\x4b\xce\x26\x8c\x58\xaa\x90\xe3\x70\x05\x8d\xb4\x79\xb5\x19\x60\xf7\x8c\x46\x4c\x71\x1f\x86\x7d\xdb\x5c\xad\xfb\x39\x47\xa3\xc4\x20\x40\xe5\xee\xe1\x61\x33\x9e\x05\x34\x02\xe6\x24\x8d\x11\xeb\x52\x0d\x5e\xf7\x8c\x76\xc1\x6c\xd4\x4b\x28\xf8\xe7\xef\x2a\x4e\x93\x7b\x49\x63\x42\x50\xa0\xc6\xb7\xc0\x27\x02\x8b\xfd\xc9\x44\x8a\x81\xda\x73\xfe\x86\xbb\xd0\xb6\xba\x82\x7d\xa5\xe7\x49\xc8\xdf\x66\x67\x36\x66\xf0\x53\xbe\x77\x4e\xe2\x7f\xca\x14\x63\x94\x58\x8b\x65\x0d\x27\x43\xfa\x63\xbd\xfe\x35\xf8\x8e\x32\x4a\xa9\x23\xe2\x49\x63\x1e\xca\x71\x1a\x41\x69\x92\xc4\x9e\x4f\xfc\x72\x5b\x55\x87\xf9\xa2\x12\x86\x09\x03\x1e\xd3\xef\xe6\xea\x63\x0d\xbd\x9d\x2b\xa3\x34\x8b\x99\x67\x44\xa3\xaf\xe9\x35\x80\x17\xad\x09\xb5\x9c\xfe\x79\x53\x9a\x71\x4c\x98\xd4\xf1\x63\xe5\x49\x23\x76\xe4\x5e\xb0\xd8\x2d\x1c\x95\x72\x19\x65\x34\x25\x1e\x77\xd2\x25\x8d\xb3\x55\x82\x32\xc9\xb0\x36\xa6\x2b\x03\x9b\xfc\x8f\x7e\x9a\x30\xe0\x32\xe9\xd7\x19\xf7\x7e\xfb\x5e\xfa\xec\x04\x16\x30\x00\x79\x81\x50\xcb\x60\x94\xd3\x58\xc5\xbd\xa5\x05\x0a\xdd\xce\x9a\xf4\x8c\x72\x99\x22\x11\xb1\x69\x65\x7f\x7b\x13\xa2\x89\x47\x40\xac\x9b\xe7\x6a\xfb\xdb\xe4\xe6\xa7\x9c\x2a\x27\xd2\xf9\x0a\x57\xa0\x27\xe2\xb9\xa3\x65\x98\x0a\x50\x81\x1e\xe7\x60\x56\x17\x78\xe9\xdd\x7f\x4f\xc4\x21\xa6\x6f\x16\xcd\xb2\x44\x93\xbe\x62\xe9\xdb\x67\xb2\x01\xe3\x4a\x8a\xa3\x2f\xc8\x6c\x6a\x58\xdf\xf9\xc7\x28\x78\x86\x82\x5f\x0c\xe9\xa9\x04\x89\xb1\x07\xca\x86\xbd\x1c\x95\x5b\x0c\xb6\xbd\xcd\x1d\xa3\x2a\x65\xd4\xf6\x75\xb4\xaa\xee\x42\xf3\xcd\x4b\x55\xb7\x88\xaa\x9a\xde\x78\xa5\x38\x84\xf6\x8f\x81\xb2\xcd\xdb\xfc\xc4\x2d\x8c\x51\x2d\x44\xec\x84\x89\xef\xc2\x97\x68\x1b\xc5\x32\x38\x89\x63\x25\xe5\x8c\x36\xc8\xf4\x2d\xea\x3f\x4d\x99\xb3\xda\x07\x93\xb7\x37\x57\xeb\xfb\xed\xcd\xf6\xf7\xd9\xb5\x99\x88\x20\x35\x24\x00\xb7\x72\x0d\x28\xfe\xbc\x4c\xfe\x67\xd4\x70\x8b\x97\xb4\xbe\xbf\xdc\xfc\x35\xae\x27\xa3\x46\xa6\xd4\x87\x7f\xf7\xf0\x13\x6d\xd5\xfc\x11\x90\xca\x74\xef\xd7\xd3\xb7\xef\x9e\x8b\xc4\x58\x14\x0b\xcc\x1e\x5f\xaa\xc6\xb3\xe7\x6c\xde\x4e\x63\x69\x16\x51\x27\x3e\xb4\x0d\x86\x3e\x68\xed\xd0\xaf\x76\x2c\xd2\x02\xcb\x53\x13\xa0\xf9\x29\xc6\x9c\xb1\x38\x49\x50\xb8\xe4\xb1\x2a\x0a\x57\x30\x42\xcc\xd7\x59\xf4\xc4\xff\xf8\x6f\x78\xb8\x8c\xc4\x5c\xf7\x60\xbd\xd9\x35\x50\x9a\x6a\xcf\x5c\x79\xac\xea\xd6\x56\x45\x3e\x9b\x41\x8c\x52\xa5\x74\xe8\xf2\x4c\xa5\xc2\xc6\x77\x9a\x31\x1a\xdb\xa8\x57\xda\xc2\x6a\xa7\xd3\xdd\x1f\xde\x09\xc6\x34\xc7\x90\x73\xb3\x79\x0c\xc2\xed\x4f\x80\x1b\xeb\x72\x1f\x96\x31\x1e\x73\x8c\x6d\x1f\x9f\x6e\xbe\xaf\xb6\xce\x00\xfa\xdb\xe6\x6a\xf7\xb8\x7e\xda\xdd\x6d\xd6\xf7\x97\xe1\xb6\x73\x4e\xbd\x43\x4a\x69\xf3\xe7\x63\x0d\x17\xd5\xc8\x6e\xaa\x1f\x04\x83\x86\x57\x83\x85\xbd\x51\x80\xc7\x92\xd8\xba\x16\x80\x3c\xd6\xc7\xbd\x7b\xb9\xef\xa0\x18\x82\x01\x96\x80\xab\x8c\xa8\xe3\x47\x6f\x5d\x73\x0a\xc8\x67\x2c\x65\x31\x12\x1a\xff\x9e\xff\xac\xfe\xda\x5e\xc3\x04\x64\x34\x60\x11\xbb\xf8\x7b\x7a\xd0\xa6\x98\x5a\x76\x9b\xcd\xc1\x29\x0c\xc8\xe5\xb3\x4e\x6a\x0a\xb8\xce\x87\xeb\x9b\xa6\xc5\x2c\x93\x12\xf7\x17\xe9\x48\xc8\xdb\xea\x02\x06\xb1\x38\xc6\x24\x8d\x50\x13\xda\xd7\x07\x51\xed\xf2\xcd\x53\x96\xbb\x18\xb1\x99\x35\x6b\x4f\x13\x6f\x26\xb9\xc5\x28\x74\xff\xbc\x1f\xcc\x39\xa0\xff\x02\x30\xe9\x40\x8f\x08\x4d\xae\xe5\x65\x97\xa9\x58\x45\x7e\x7f\x7a\xac\x2b\x55\xc0\xfe\x53\x3e\xcf\xe4\xde\x29\xeb\x96\x6c\xd4\xc6\x43\x56\x1d\x96\x5b\x97\xbf\x48\xc7\xc6\xed\x74\x93\x6e\x6e\x38\x98\x79\xac\x82\xeb\x69\x0d\xb0\xa4\x33\xe7\xca\x12\x5c\x09\x5c\x0d\xef\x44\x65\x29\x8c\x02\x1a\x0d\xdd\x25\x54\x89\x59\x5e\xff\x98\x89\x14\x56\x0b\x2a\xdf\x2e\xdf\x21\x7f\x6c\x7a\xd2\xa0\xa0\xc1\x18\xe8\x24\x48\x22\xef\xf6\x32\x2f\x66\x6f\xbe\x8d\x33\x65\x06\x47\x4c\xb8\xac\xea\x3a\x37\x81\xa0\xca\x98\xe5\x14\xc3\x9b\x87\xc7\xcb\x5f\x16\xc9\x52\x61\x5c\x26\x31\x2c\xb5\x79\x69\xb6\x2f\x75\x55\x22\xb8\x30\xa4\x71\x6e\x10\x8f\xb2\x0c\x11\x3c\x4b\xf8\x43\x3f\x24\x66\xb1\x13\x8e\xec\x36\xb2\x8b\xa2\x7a\x9e\xbc\x00\x3c\x4e\x09\xea\x2b\x87\x4a\xeb\x20\xa7\xcd\x38\x89\x62\x27\x22\x81\x55\x00\x6f\x89\xd8\x1f\xa4\x0e\x4d\xe6\x6a\x96\x79\x89\xfd\x92\xe9\xb9\x09\xcd\x10\x5f\xdc\x1c\x55\xdb\xa3\x05\x3f\x4d\x85\x38\x25\x11\x1d\x84\xe4\xd6\x33\xfe\xe4\xac\xa1\xc1\xa9\x74\xd0\x4e\x5d\xed\x3d\x81\x21\xa8\x04\x32\x8e\xe0\x94\xee\x39\x6c\x6f\x7e\x0b\x7f\x63\x99\x41\x29\x07\xaf\xb2\x34\xa1\x68\x30\xce\x23\x47\x2c\xb8\xfb\xe8\xb3\x44\xd2\x1f\x63\xae\xb6\xd7\xdd\x9e\xa9\xba\x33\xe3\x5c\x70\xc9\x02\x0e\xfe\x84\x67\xc7\x78\x22\x1c\x9d\xde\x51\x75\x57\xed\x65\xb5\xdf\x1f\xcb\xfc\x54\xa0\xde\x8f\x4f\x63\x12\xc7\x81\xe3\xf7\x0a\xa5\xaf\x42\x7f\xd6\x13\x63\x3c\x15\x16\xf5\x11\xfe\xbe\x3d\xe3\x2e\x1b\xc6\x99\x14\x85\x52\xee\xa0\x91\xa7\x3a\x7d\xd3\x39\xc8\x05\x89\xd0\xa0\xd0\xe3\xe5\xc3\x5f\x33\x16\xf2\x29\x57\xef\x19\x0e\x64\x08\x5c\xb9\xbc\xd8\x4e\x72\x18\x9e\x45\x12\x39\x62\x38\x81\x86\xf6\xe5\xf4\x17\x64\x59\x84\xda\x93\x5e\x03\xe9\xd4\xde\x85\x71\x19\x3b\xe1\xf4\xa3\x2b\x1c\xd5\x9b\xc0\x1b\x62\x5c\x6a\x50\x58\xdc\x6c\xfa\x25\x75\x3a\x19\x95\x87\x6e\xe6\xcd\x45\x0d\xf2\x35\x2f\x9f\xc3\x8c\xbc\x94\x67\x0a\x80\x5c\xa5\x06\x77\xf1\x7d\xde\xd3\xf9\xc2\x91\x4c\xa7\xa4\x4f\x60\xb6\x37\x77\xeb\xdd\xe3\x13\xee\xa2\x61\x84\x8e\x09\x12\x1f\x9a\x43\x55\x36\x55\x7d\xb5\xba\x59\x5e\x7d\xb8\x4e\x34\x78\x15\x36\xe8\x02\xe5\x25\xb1\x16\xc6\xb5\x16\x30\x62\x61\xff\xb3\x32\xb9\xd4\xdd\xad\x1c\xf7\x14\xff\x12\x1d\xfb\x6c\x84\xcc\xb5\xb6\xce\xb0\xe4\xa3\x85\x84\x6d\x2b\x67\xf6\xe0\x89\x14\xff\x4a\x98\x5f\x01\xb9\x89\xa8\xc8\x46\x1a\x87\x67\xee\x9e\x21\xd2\x64\xc3\xd3\xea\xdf\x4c\xc3\x1c\xc0\x6d\x0b\x72\x8f\x26\x21\xa7\x62\x63\xff\xea\xbf\x8a\x39\x69\x2e\xaf\xa7\x71\x2d\x75\x5b\xd5\x1f\xb3\x69\x61\x58\xbf\x11\xf9\xd5\x65\x59\x42\x82\x71\x20\x2c\x9a\x5b\x78\xbb\x96\xd2\xb6\xea\xc5\x97\xc3\xd8\xd4\xd1\x82\x43\x70\xb6\x36\x79\x3b\x88\xf6\xce\xce\x2b\x05\xa2\x91\x6d\xde\xbc\x7c\x6c\x64\xb1\x9f\x80\x07\x18\x07\x45\x11\xd7\x0d\x3f\x0f\x18\x89\x03\x3a\x3f\x8d\x38\xd3\x93\x1b\x07\x9a\x63\x43\xbe\x2e\xcd\x4d\xa9\x77\xfd\x49\x40\xa6\x23\x57\x06\x28\xec\x49\x73\x91\x5b\xc2\xb3\x80\x98\xac\xaa\x96\xcc\x66\x91\x4d\x9d\xe2\x9f\xcc\xeb\xab\xba\x3a\x37\xed\xad\x77\x38\xbc\x7c\xb8\xff\x76\xff\x17\x13\x02\x6e\xb3\x41\x0c\xc9\x01\x09\xc6\xc4\xbe\xee\x38\xe7\xde\x0d\xe7\x11\xce\xa5\x22\xdc\x5a\x67\xab\xb2\xbd\x59\x3f\x91\xf5\xbd\x17\x81\x67\x49\xa4\x08\x6e\xd1\x17\x3f\x07\x91\x4f\x96\xc4\x71\x8c\x05\x49\x69\xcc\xf7\xa1\x95\x39\xb9\xae\x24\x26\x06\xbb\xaa\x4e\x78\x76\x65\x66\xa1\x6b\x12\x4b\x8d\xc9\x92\x69\x41\xee\xd1\xf0\xb2\x8b\xc2\x69\xf8\x0a\x2a\x20\x96\x93\xb9\x75\x0a\xb3\x9d\x4e\x86\x84\x6a\x93\xfa\x67\x80\x38\xf9\x09\x71\x9f\x25\x14\x18\x9a\x61\x79\x3a\x65\xdf\x47\x46\xdf\xe9\x66\xb7\xfc\x4c\x12\x66\x19\x12\x2b\xbd\x42\xae\x13\xc4\x28\x07\x9a\x66\x37\x42\x98\x28\x80\xb1\x27\x02\x54\x2c\xe1\xb1\x44\x1a\x8d\xcd\xeb\xc6\x69\x34\xde\x5c\x3e\x0c\x5d\x94\x84\x0b\x8a\xbd\xed\x7d\x65\x72\xfb\x81\x75\x8e\x39\x01\xb1\x1b\x24\xd1\x48\xf5\xbe\x72\x68\x39\x5f\x2b\x6e\xfa\x93\x64\xc2\x51\x1c\xe5\xe1\x5b\x33\x9c\x5a\xa6\x28\x48\xea\x1b\x80\x3b\x3d\x5c\x55\xc2\x78\x34\xea\xa8\x5f\x7c\x7c\xa6\xff\xc2\x92\x24\x25\x48\x17\xc2\x8a\x5f\x5f\x8b\x99\xee\x61\x9e\x67\xcf\x92\x44\xa7\xb8\x49\x05\x35\x38\x8c\x10\xc6\xdb\x76\x92\x46\x3a\x33\x9e\x3d\xb2\x19\xd7\x7e\x66\x77\x3e\xa5\xb4\xf7\xeb\x74\x13\x7b\xd2\xea\x9a\x8f\x4e\x1c\x03\xed\xb9\x77\x95\x4b\xfb\x2f\xd4\x14\xeb\xd0\xdb\x97\xbc\x36\xe3\x58\x25\x11\x4c\x49\x3a\x58\x83\x4d\x9b\xdc\xe7\x16\x6f\xff\xd9\x2c\xe5\x0e\x2d\x9a\x97\xed\xea\xd8\xbe\x54\x5d\x5a\xfc\xcb\xd2\x76\x9e\x64\x99\xc4\x4d\xab\xcd\x0f\xaa\xea\x9f\x42\x66\x12\xe6\xa2\xe9\xaa\x86\x0d\xe8\x1a\x5c\xc5\x7e\x11\x7d\x90\x48\xa0\xb8\xd6\xfe\x5e\x1d\xeb\xc7\x8f\x5a\xee\xfb\xc4\x3f\xd1\x2c\x45\x98\xf4\xcd\xc3\xb7\xfe\x4f\xc2\x41\x4a\xbe\xd4\x52\xa3\x88\x45\x7f\x00\x22\xaf\x9c\xe8\x97\xf4\x39\x6c\xd8\x8f\x33\x34\xc2\x56\xfb\xce\x75\x75\x66\x33\xd2\x70\xcd\x69\xaf\xc0\x1c\xf8\x5f\x33\x15\xe4\xe5\x80\x29\x31\x3a\x4e\xfa\xb4\xf0\xb9\x3c\xd3\x37\x4f\x40\x70\x9b\x05\xe8\x7e\x13\xac\x74\xc7\x06\xf9\x7e\xa0\x4d\x8d\x24\x3d\xc3\xd0\xff\x35\x8d\x12\x8b\x6c\xd0\xe7\xfc\x0d\xc6\x08\xd2\xe6\x42\xea\x57\x57\x06\xb9\x38\x3e\x3f\xf7\x41\x68\x1a\x89\x54\xeb\x50\xac\x6e\x3d\x1f\x62\x12\x7b\xa4\x71\xe6\xee\xdd\x1e\xb1\xe1\x1b\xf0\xf0\xb1\x65\x5d\x12\x96\x92\x4c\x8a\x9e\x43\xde\x6c\xab\x40\xaa\x59\xf9\x90\xe6\x4c\x0b\x3c\x25\x92\x62\x57\xc6\x54\x7d\x3e\x76\xe7\x70\x6f\xe7\x60\xf3\xe1\x83\x96\x63\x33\xb2\x96\xe1\xe6\xa4\xc4\xa6\x88\x15\xdd\x79\xdd\xb7\x05\x7b\x27\x3f\x92\x42\x94\xe9\x65\x35\xb5\xd9\x48\x16\xb9\x5e\x60\xb7\x97\x97\xcf\x50\x7c\xa6\x7f\xce\x52\xa6\x18\xca\xf9\xac\x8a\xe2\x63\x28\x06\xa7\xcc\x30\xe9\x3a\xd4\x7e\x61\x9d\x11\xe4\x58\xca\x63\x4a\x7b\x0e\xc2\xdb\x75\x55\x83\x96\x7d\xc9\x30\xe5\x09\x43\x34\x98\xf3\xd7\xfe\xee\x84\xaf\xe6\x8d\xb3\x34\x35\x49\x50\xda\xf3\x3a\x8e\x7f\x12\xb0\xf9\xcf\x89\x88\x63\x46\xe2\x98\xec\xf8\x94\x77\x9b\xed\x45\xf8\x72\x91\x1a\xe4\x11\xbd\xe7\xe5\x45\x6e\xae\xe0\xb5\x90\x7f\x6d\xd1\x48\x33\x9e\x68\x3b\xc8\x30\xcd\x07\x0f\x95\xa5\x34\xb3\xda\x44\xa1\x90\x75\xe8\x02\x8e\x87\x3a\x7f\xce\x47\x7a\x49\x93\xed\x36\x95\x29\xd8\x78\x94\x4f\xd6\xa3\x2d\x2a\x95\xc2\x20\xd5\xe7\xef\xd0\xbe\x07\x30\xcf\xec\x56\x29\x99\xa0\x06\xf0\x6d\xf5\x8e\x2c\xed\xda\xd5\x0b\x4f\xb0\x05\xa9\x4e\x29\x0a\xe8\xbf\x9b\xfc\xcd\x16\x95\xaf\x70\x07\x85\xe6\x20\x36\xc2\x52\x6d\x01\xa3\xd0\x17\xd9\x0c\x96\x3b\xd3\x53\x99\xc4\x29\xf8\xa2\x5d\x28\x0a\x97\x7d\xdc\x5c\xcd\xc7\xc8\x0c\x6b\xc3\x4e\xa5\xde\x9b\x8b\x3c\xbc\x41\x6d\x8b\x40\xa4\x63\xa9\x81\x18\x9b\xb6\x5d\x18\x39\x02\xed\xb2\x14\x88\x22\x23\x59\xb8\x00\x1c\x9d\xfe\x74\x9b\x25\x08\x63\xda\xcb\xd7\x93\xdd\xe5\x5f\x21\xf8\x4e\x6d\x96\x61\xb3\x7b\xf7\x36\x5f\xa4\xc3\x2f\xb6\x3a\xc3\x17\xa3\x99\xac\x1a\x16\x84\xf2\xf3\xf8\x5b\xd9\x04\x27\x63\x5c\x87\x86\x21\x0e\x10\x1f\x4c\x7a\x4a\x78\x77\x1e\x34\x67\xf6\xe5\xe9\xa4\x12\x11\xd5\x24\x60\x50\x64\xe1\x69\x1b\x33\xe5\xec\xa9\x08\xd4\xa0\x9d\x33\xfa\xa3\x08\xa7\x63\x4e\xe8\xb1\x81\xa2\x38\x53\x23\x0f\x23\x75\x16\x80\x28\xdf\xca\x5c\x57\x75\xb9\x8c\xbf\x12\x11\x70\x6c\x01\xa0\xd1\xd8\x71\x3f\x59\x56\x45\x4c\x24\xc6\x65\x28\x2a\xe2\x94\x44\xc6\xf5\xac\x25\x76\x60\x48\x53\x44\xcc\x79\xe6\x53\xe2\xee\x8e\x61\xaa\x52\x57\xfb\x3b\xa8\x5f\x0b\xd8\xd6\x00\x4b\x2b\x98\x88\x33\x8e\x5a\xf1\xd8\x67\xee\x12\x49\xd6\x5f\x8b\x56\x88\x68\x76\x6b\xf6\xaa\xa8\x41\x9a\x0f\xe4\x59\x8d\xfa\xf8\xd3\xdf\x46\x78\x86\x22\x3d\xdf\xb6\x93\x2e\xb2\xa0\x91\x31\xbe\xab\xd3\x6d\xeb\x75\xb3\x3a\x65\xfd\x4f\x2f\x8b\x4a\x27\xd1\x51\xe0\xb3\x9f\x67\x54\x7e\x10\xd3\x29\xae\x20\xab\xc3\xe1\x13\xa1\x1b\x26\x78\xe4\xe0\xc7\xd2\x18\xaf\x54\xe7\xd5\x98\x96\xbf\x9b\x0b\x8b\xbd\x3b\x7c\xf3\xff\x71\xcc\xff\x58\x2a\xed\x89\x84\xc5\x38\x51\x1d\x60\xa0\x8b\x1d\x5d\x2e\x3f\x85\x2b\x8a\x84\x13\x7c\x2a\xaa\x92\xb5\xb9\x83\xbd\x82\x7a\x75\x0a\x2d\x13\x09\x77\x1a\xd8\x7d\xbb\xea\xf3\xfd\x4d\x24\x59\x84\xcb\xae\x67\x70\x7b\xcc\xcb\x49\x53\x70\xb6\x1c\x4d\xc2\x53\x91\xaa\x14\x33\x97\x6f\x65\xde\x7e\xd0\xb0\xd9\x88\x14\xc0\xf8\x20\x02\x45\x26\xba\x48\x01\x2b\xc3\xbf\x8c\xde\x93\xf0\x82\x88\x54\x60\x6a\xd2\x25\x2e\xb8\xb4\x3d\x58\x5f\xa8\x99\x5e\xaf\x30\xca\xaa\xbe\xd1\x60\xf3\x7a\xef\x35\x19\x3f\x7f\x9d\xb3\xd8\xc9\x91\x7a\x3f\x58\x8c\xbf\xfe\x59\xed\x55\x0e\xbb\x7f\x3e\x5c\xec\x9a\xbd\x2c\x8a\xc3\xb0\x7a\x88\x8c\x24\x72\x60\xed\xdc\xc9\x9f\x8f\x2f\xb2\x81\x78\x76\x31\x19\xd1\x58\x70\xbf\x58\x6d\xd6\x0e\x2c\xf0\x70\xbf\x7d\xba\xb9\xf8\x36\xd8\x22\x31\x91\xf1\x14\x33\x8d\x26\x37\x70\x01\xed\xa3\xfc\x98\xf8\x66\x85\x51\x22\xc1\xce\x44\xb0\x27\x41\x93\xd5\xfe\x98\x20\x10\x40\x0b\x48\xa8\x6c\xee\xe4\xe1\xd0\x33\x6c\x99\xc8\xac\x4c\xa3\xbe\x4c\x8e\xd0\xba\xb6\x05\x13\x56\x8e\x93\x5e\x9e\x90\x1e\xaf\xf0\xec\xf4\xfe\x66\x73\x4d\x42\xac\x1c\xe8\xc7\xa0\x82\xdd\xa3\xac\x9d\x2a\xdf\x99\xd7\x55\x45\x4e\xfb\x40\x1a\x13\x84\x19\xee\x9f\xe0\xbf\xab\xcb\xcb\xcf\xb3\x4b\xa1\xa8\x2b\xf9\xee\x9d\x63\xc2\xd8\x12\x86\x09\xa5\x5c\x59\xea\xf2\xe6\x69\x8a\x5c\x11\x9a\x72\x2c\x65\x39\xad\x85\xbc\xd9\xd5\xa0\xf3\x43\xde\x0b\x52\x33\xa1\x65\xe2\x4c\xc8\x6b\xa9\x5f\x31\xf6\xfc\x5e\x15\xc7\xfd\xe7\xbe\xb5\x4c\x68\xe5\x24\xf6\x2e\x65\x5d\x54\xcd\x9d\x6c\xab\xa6\x3f\xa3\x76\xbe\x80\x17\xc7\xba\x5c\x54\xd7\x9e\x9f\xca\x0a\x30\x5e\xb5\x3e\xd7\x70\x05\x7f\x01\x11\x2f\x0c\xf0\x60\x78\x81\xe5\x10\xbc\xdd\xa4\x3f\xa8\xe9\xd0\x09\xed\x75\x39\x16\x43\x7d\x01\x04\x32\x16\xbc\x5f\x9d\x2d\x49\xfe\xc7\xb9\xaf\x05\xa1\xb1\xbc\x77\x9d\x9b\xa1\xff\xb1\x1c\x49\x0b\xc8\x08\xd6\xd5\x50\x02\x63\xea\xfb\x34\x09\xb9\xe6\x1f\x53\x02\x45\xb6\x77\x4d\xd5\xe5\x84\x87\x7f\x1c\xa1\x19\xa3\xdd\x85\x8d\x12\x4b\x82\xec\x77\xd5\x2e\xc3\x21\xb2\x88\xf2\x6c\x8c\x7a\xf5\xd4\xa5\x31\x61\x88\x65\x11\x8b\x23\xde\x67\x52\xf9\x63\x55\x15\x6b\x93\xb7\xbb\x6c\x52\x5e\xca\x22\xce\x10\x6e\xf0\x28\x6b\xb9\x87\x16\xea\xfc\x8f\xf3\x86\xb4\xff\x7f\xfd\x1b\xae\x45\xa7\x48\xec\x3c\x96\xda\x6d\x8c\x67\x10\xf9\x59\x0c\x46\xba\x5c\xf3\x12\xea\x56\xe6\x65\x40\x98\xfd\xc5\xea\xe8\x28\x1c\xce\x48\x12\x61\xc9\x02\x0b\x20\x67\x7f\xf8\xe4\x9e\xd1\x54\x63\x06\x79\x55\xd5\xb0\xcf\x7f\x1b\x6f\xce\x19\x4b\x28\xd6\x23\x67\x9d\xa7\xc5\x02\xfe\xbf\xd8\xbf\x67\x77\x80\x47\x16\x41\x1c\xbf\xfe\xf8\x7a\x5d\xd5\x5f\x64\xff\x34\x39\x8b\x9c\x39\x53\x5b\x1f\x75\x7b\xac\xe1\xb1\x86\x1b\x5d\xfd\x32\xfb\xb8\x76\xf5\xd9\x7d\x85\xa0\x2f\xd9\xcb\xbc\x0f\x43\x12\xc8\xa4\xc3\xe1\xe7\xcf\xcf\xce\x38\x25\xaf\x61\x5d\xd7\x7d\x3f\x2b\x4b\x00\xd2\x74\x80\xda\x36\xf9\xf9\xe4\x2e\x4b\x93\x04\x71\xee\x97\x05\xc8\x3a\x3f\xee\x27\xf7\x42\xa4\x02\x83\xe7\xff\x8c\xda\xba\xfe\x50\x16\xc5\x09\x71\x5a\xf9\xae\x3f\x3b\x5b\x9b\xb3\x8c\x09\xdc\x92\x8f\xcd\x0c\x55\xd0\x1d\x51\xbe\x2a\x76\xf7\xf1\xa5\x96\x07\x18\x0e\x81\xc3\x78\x3b\x9b\x74\x67\x15\xfe\x63\x1d\x30\x0b\x99\x24\x06\xd9\x32\x38\xbb\x1e\x9d\x05\xcd\xf4\xa5\x91\xca\x62\x1d\x1c\x1f\x9a\x63\xc8\xba\xcd\xe3\x94\xf1\xc5\x32\x09\x29\xa2\xc2\x16\xa5\x42\x3e\x93\x08\xf1\x9f\x57\xa9\xe0\xbe\xc8\xbd\x2e\xe0\x4d\x8e\x57\x82\x4c\x67\x2a\x58\xa0\x05\x33\x01\xbf\x84\xcd\xae\x42\x4b\x1d\xf7\x98\x85\xe6\xdb\xc4\x30\x93\x65\x5a\x0b\x87\x1c\xaa\x0a\x73\x5d\x05\xdf\x1e\x7f\x10\x12\xd7\xb8\x34\xce\xaa\x11\xa3\xd1\x11\x70\x2a\x8c\x52\x04\xef\x89\x83\x7e\x5e\x78\xbc\xf2\x09\x8a\x6c\xfa\x7c\xc1\x6a\xac\xf2\x38\x0b\x19\xac\x8b\x0e\x3b\x75\x66\x15\x27\xbd\x53\xd4\x84\xe3\xcb\x64\x94\xa6\x98\xbf\xdf\x7d\x74\xf3\xf7\xbd\xaa\xcd\xd7\xbc\xdf\xd2\x64\xa4\x13\x84\x9d\xac\xe5\x73\x55\x4f\xec\xe8\x98\x8c\x75\x82\x1e\xf0\xce\x98\x42\xee\xe4\x18\xd6\x28\x63\x50\xd8\x26\x2b\x64\xe3\x2c\x86\x77\x36\x4e\xbe\xca\xe6\x65\xe7\xaf\x3c\x0c\x24\x54\x81\x5b\x5c\xfc\xc4\xbb\x29\x91\x93\x81\x7d\xc0\xa5\x5e\x81\x24\x8a\x60\x05\xad\xcb\x24\x31\x42\xb8\x94\xe5\x45\x0d\x52\xbf\xf4\xe7\x04\x19\x9c\x60\xb7\xf9\x1e\xce\xfa\xaa\x31\x49\x93\x0c\x7f\x84\x53\xe6\x3c\xed\xf2\xff\x6d\x36\x3c\xa5\x18\x74\x34\x24\x1a\xcb\x63\x31\x49\x35\x89\x1d\x64\xee\x43\xc1\x3d\xbc\x8f\xfc\x87\x99\xa4\xc6\x60\x50\xba\x93\xc6\x6c\x2b\x44\xdc\x7c\x85\xe2\x0c\x90\x4b\x32\xa1\x43\xaa\xbb\x1a\x05\x66\x9f\x96\x76\x25\x93\xd1\x80\xe9\xca\x35\xdc\x55\x25\x84\xc4\xac\x3b\x88\xad\xaf\xed\xc3\x76\x75\xbb\xfb\xed\xc2\x59\xdf\xee\xae\x1f\x9e\x76\x8f\x4f\xeb\xdd\xa8\xe9\x26\x99\x4a\xd3\xa4\x8f\x41\x1f\x0e\x50\x7a\x63\x92\xd9\x7d\xe3\xc4\xf5\x6b\x9a\x16\x0e\x7a\x20\xab\xc9\x24\x22\xb1\x8f\xf1\x2e\x3e\xb6\x1f\x07\xa4\x6f\xcd\x18\x76\x0b\x09\x89\x4c\x63\x9a\x42\x70\x2e\xaa\x8a\x02\x50\x24\xec\xcc\x1d\x4a\x05\x81\x3e\x25\xd2\x55\x6d\x2e\x9c\xd9\xc1\x89\x2e\xc1\x22\x02\x3a\x9c\x24\x83\xcc\xb5\x17\xa1\x34\xc1\x45\xe3\xd3\xf0\x4a\xa6\x5a\xe2\xde\x85\xf3\x69\xc9\x61\x8c\xc9\xd4\x5a\xa7\x08\xd2\x85\x7f\xbd\x66\x04\x93\x82\x48\x63\x07\x80\x86\x97\x8d\x37\xdf\xae\xb7\xfd\x08\x96\x61\xa4\x25\xdf\x64\x91\x4b\x55\x4c\x64\x7d\x98\xd4\x54\x21\xcc\xd8\xfd\x66\x54\xf2\xd9\x4e\x9c\xd9\x26\x31\x8b\xd4\xa9\x33\xbc\x0a\x31\x0b\x0a\xa4\x9e\x03\xf8\x4a\x2d\x59\x8f\xa4\x2a\x46\x9a\xb1\xfe\xb0\x4d\x25\xf1\x25\xac\x10\x22\xac\x4a\xf3\x28\x3f\x1e\xbc\xdb\x45\x0f\x2b\x98\xa0\x0b\xa4\x35\x04\x91\x8c\xf8\xe5\x8d\x33\xac\x39\x2e\x15\xd6\x55\x44\x9c\x33\x03\xd2\x12\x42\xbf\x4e\x45\xa9\x23\xb1\xb9\x0c\xc3\xdd\xf0\x59\x65\x50\xc5\x31\x23\xfe\xd2\xbf\x1c\xa1\x59\xe0\x0a\x33\x15\x4b\x8b\xe5\x0d\x75\xfc\x20\x01\xb7\xad\x62\xed\xcc\x4c\x6e\x2e\x1f\x46\x78\x6b\x45\x94\xcd\xbc\xae\x74\x0b\x9e\xd0\x11\x8e\xd1\x34\xc2\x96\x48\xae\xab\x87\x37\xa8\x43\xb1\x41\x31\xaa\x91\x3b\x14\x6e\xf6\x3f\x1f\x2e\xa6\xd3\x42\xb1\x14\x88\x23\xd8\x39\x2f\x9b\x1f\x79\xfb\xb2\x2e\xf5\x58\x97\x80\x29\x06\x29\x32\xcc\xe4\xbb\xac\x4d\xe3\xa6\xc8\x64\x97\x52\x3c\x25\x58\xba\x32\x39\x0a\xec\xdf\xc3\xfb\xa6\x95\xaf\x30\x1c\x57\x4e\x0f\xf1\x50\xe5\x65\xbb\xad\xa6\x9d\xc7\xc5\x39\xad\x12\xe6\xac\x72\xda\xfd\x61\xf3\x72\xb4\xb6\x00\x24\x7e\x2c\x2e\x7f\x2a\xe1\x80\x96\xad\x18\xaa\x6c\xb6\xab\x2f\x61\xdd\x50\x49\xe6\xbc\x83\xff\x53\xe9\x57\xf8\x38\x63\x42\xc1\x54\x22\x21\xe9\xee\x83\x95\x79\x01\xc6\x39\x01\x8c\xfb\x6c\x2a\x31\xd4\x29\x50\xf6\x56\xb6\x75\x75\x3c\xe4\x27\x8f\x3d\x8d\x78\x1a\x24\xb0\xda\xd5\x33\x9c\x3c\xf3\xd4\x68\xa4\x1e\xbd\xc8\xe6\xe5\x04\x58\xa3\x84\x96\x98\xaa\xdd\xad\x7e\x1f\xab\x40\xfb\xa3\x19\x51\xd8\x27\xae\xde\xa0\x36\xb5\xb4\xed\x6a\x28\xba\x87\x21\x0c\x30\x40\xf4\xbc\x25\xfa\x99\x43\x34\x53\x2a\x06\x7c\x6e\x6e\x55\xf5\x72\xe1\xa7\xc1\xb1\x52\xa9\xc3\x14\xe2\x9b\x7d\x9d\x97\xb2\xd4\xc3\x36\xae\x94\xc8\x0c\x06\xa5\xf2\x0d\xee\xf3\xa9\x16\x20\x53\x4a\x13\x04\xc6\xe7\x4d\xb7\x01\x20\xb9\xbe\x96\x2d\x3c\xf7\xbf\xca\x44\xdc\xf0\x9e\x07\x97\x57\x26\xd7\xb2\x78\x2c\x6f\xfb\xe3\x82\xdb\xbe\xfd\x79\xd8\x4a\x35\x7b\x76\x40\x2c\x8f\x7c\xa5\x1f\x0d\x2a\xc2\x07\x6d\x0c\xa8\x37\xfd\xf7\xb6\x5a\xf5\x54\x4f\xfa\xef\x70\x94\xc8\x5e\x01\x0e\xd5\xe7\x9d\xd6\x45\x55\x8f\x71\x58\x3a\x4a\x79\xe2\x2b\xc8\x17\x63\x3d\xa9\x70\x58\x58\xc4\x84\xa9\xaa\xae\xab\xf7\x53\x5d\x10\xa6\x63\xe1\xd8\x0e\x0a\x4a\xb0\xb9\xce\xe5\x1c\x2a\xae\x89\x8c\x30\x14\x47\x78\x24\x6c\xab\xdb\xaa\x19\xb8\xc3\x9a\x74\xbb\xe4\x80\x84\xfa\x15\x3e\x2e\xab\xb2\x69\xe5\x3c\x62\xd0\x34\xa6\xd6\x0b\xc8\xf9\x44\xf0\x8b\xdc\x03\x7a\x20\x58\x39\xd3\x93\x65\x9a\x65\x96\xe8\x1e\x4a\xee\xee\xfb\x32\x59\x4a\x27\x0c\x88\xb3\xb6\x79\x03\x59\xdc\x7d\x7c\xaf\xe6\x56\x12\xe7\xa5\x8b\xc2\x29\x64\xe6\xd3\x16\x59\xb7\x37\xba\xba\xae\x6a\x07\xca\x6c\x26\xe6\xed\x4c\x27\xd6\xa6\x4e\x38\xf2\x6d\x0b\xd2\xa5\x11\xd3\xb8\x5f\xa7\x89\x70\x0b\x21\x3a\x3e\xfa\xee\xe2\x82\x30\x49\x37\x52\xda\xf1\x5e\xe3\xf6\x62\x7f\x50\x44\x9a\xea\x3e\x47\xf8\xfa\x70\x75\xbb\x4b\xee\xfa\x83\x54\x38\x2d\xf7\x3a\x7f\xcb\x65\xb1\x7d\xa9\xa1\x79\x19\xa0\x9e\x3a\x4b\xa5\xf1\x20\x60\xec\xf9\x62\x54\xe5\xa7\xf7\xec\xee\x65\x42\x62\xed\x3c\x58\xa7\x4c\xe5\xa5\xba\xe3\x8a\xf4\xb4\x65\xef\x6d\x18\x8e\x49\x92\xba\xf2\xb7\x2c\x66\x2f\x67\x18\x20\x13\x2c\x01\xa3\xb2\xf3\x13\xc8\xa6\x5f\x08\xb4\x8a\x53\x69\x7a\x43\x22\xf7\x80\xd7\xa8\xd4\xd8\xff\x0a\xa5\xd3\x2c\xee\xeb\x5e\x05\xf8\x67\x12\x0e\xeb\x94\x22\xdf\xfd\x7b\xf5\x13\x8a\xd0\x95\xaf\x67\xa6\x31\x13\x4f\xb0\xf0\x41\x9b\x60\x38\xf2\xa3\x96\x87\x03\xd4\xb7\x95\x7e\x5d\xb7\x2f\x67\x0c\x33\xa7\xd3\xd2\xc4\x0e\x69\xe0\x37\x12\xb7\x10\x87\x0b\x32\x9c\x84\x32\x8e\xab\x73\x2e\x58\xf2\x32\x0d\xb1\xc4\xa5\xbc\x9d\x48\x6a\xc8\x13\xf5\x46\x3f\xdc\x32\x86\x6b\x2a\x34\x6d\xbe\x97\x2d\x74\xd3\xea\xed\x14\x7b\x6e\xa2\x8c\x60\x26\xe3\x92\xc6\x6e\x1f\x0b\x33\xd2\x44\xd2\x35\x01\x9f\x61\x49\xf5\xa8\x3b\xae\x99\xe8\xaf\xc8\x37\x9a\xfb\x0f\x6b\x27\x77\x38\x68\xc7\xc6\xd1\xdd\xf6\x66\x9e\x08\x9b\xc8\x02\x52\xff\x50\x0a\xed\xb1\x6f\xf2\x9b\x38\x72\x2a\x58\x79\xe3\x3c\xd5\x10\xb1\xf9\xf7\xa6\x8f\x6a\xc3\xb0\x84\x21\xdf\xa5\x69\xbb\x5c\x56\xcb\x96\x7d\x06\x07\x0e\x1f\x12\xae\x65\x1b\xe6\xee\xdf\xab\xbc\xdc\x1c\x8a\x7c\xf8\x72\x15\x47\x0e\xf2\xec\x56\x27\x97\xf5\xf8\xe0\xab\xef\xd4\x19\xa2\x8d\xb2\x21\x73\xd0\x70\x40\x1e\xf3\xec\x26\x11\x03\x3a\x19\xdf\xc4\xe9\x6b\x6f\x28\x25\x92\x8c\x6c\xa9\x01\x1c\x7a\xb2\x99\x93\xf8\x0d\x8b\x19\x06\x03\x2e\xd4\xad\xea\xbd\x2c\xfa\x06\x7d\x55\xdf\x98\x66\xde\x09\x36\x5c\x28\x6c\x01\xde\xd5\xef\xe3\xc2\x85\xe1\x9a\xe0\xb2\xd5\x56\xeb\x2f\x4f\xb3\xf9\x90\x88\x54\xd8\xe0\xc3\x76\x97\xeb\x3a\xc8\x9d\xcf\x86\x65\x12\x21\x9f\x9b\xd0\x97\x3b\x6d\xc9\x8e\xe3\x63\x93\x18\x15\xf5\x2b\xe5\x66\x01\x29\xfd\x79\xed\xcc\xa4\x8c\x38\xcd\xe5\xfe\xf3\x9f\x8f\x17\xcc\x3d\xc1\xcd\x8f\x3e\xd4\x34\x42\x38\xa2\xcf\xd5\xd5\xdf\x07\xb2\xa5\xc9\x62\x9d\xc8\x60\x95\x29\xf3\x10\x7c\x1a\x65\x08\xfa\x11\xdc\x56\x3d\xee\xd2\xc1\x1f\x96\x5f\x38\xa3\xa5\x11\x81\x51\x70\x95\xdb\xee\x51\x96\x0e\x18\x33\xb2\x77\x60\x46\x6b\xc6\x64\x48\x95\x0f\xcb\xd9\x84\xe9\x66\x4d\x80\xa6\xa1\x7d\xe3\xdb\xe6\x45\xd6\xf3\x57\xd7\x74\x41\xa0\x0f\xc5\x7b\x5d\x88\x1b\x73\x5d\xd5\xa7\xa8\x6a\x03\x2c\xc2\x53\xae\xca\xb2\x9a\x4c\x06\x48\x5d\x67\xfd\x7b\xde\x1c\x65\x31\x92\xfd\x64\x06\x24\x28\x6f\xfe\x56\xe7\xf0\x86\xe8\xe6\xc5\xf5\xcd\x00\x38\xd4\x63\x30\xc2\xbd\x98\x20\x9e\xce\x12\x03\x0c\xd8\x38\x22\x61\xe9\xdb\xcb\xbc\xf4\x6a\x87\x5d\x06\xfc\x60\x1d\xc8\x69\xf9\x76\xdb\x48\x62\xe2\xfb\x7a\x34\x55\x73\xf1\xe1\x9a\x65\xe1\xc2\x2d\x13\xd8\x94\xeb\x72\x8d\xdb\xf5\xf7\xf5\x6d\x4f\xd6\x33\x16\x9c\x4e\xfc\xad\x2c\xcd\x5e\xd6\xaf\x97\x55\x8e\x94\xaa\x6b\x3f\x00\x62\x6e\x80\x07\xb5\xb2\x59\xd4\x03\xb1\x88\xb8\xdf\x20\x9d\x24\xc1\x75\x55\x23\x96\xe3\xf3\xa8\x1f\x62\x41\x12\x9f\x35\xdd\x1f\xf7\x23\x30\xce\x9f\xb4\xa8\x81\x24\x04\x15\xa7\xde\x0b\x6c\x30\x5e\x8c\xd0\xee\xc0\x65\xe4\x25\xc2\x9d\xe6\xd6\xb7\x0b\x68\x9d\x68\xf5\x62\x1e\xbe\xfc\xcf\x62\x18\xfd\xb7\xa5\x77\x0a\x12\x9a\x61\xb6\x63\xa1\xd5\x2f\x9b\xa2\x5a\x16\xc6\x67\x90\xc8\x0c\xd5\x8e\x5a\x90\xfb\xb1\x09\xdc\xc9\x30\x47\xc4\x6d\xa0\xee\xa2\x25\x2c\x7a\x7c\x7e\x33\x52\x6e\x31\x3c\x59\x52\xb6\x9b\x4e\x48\x48\x85\x74\xc6\xf0\x2d\x22\xa7\x07\xb0\x55\xb8\x79\xa9\xb1\xda\xf6\x5a\xa1\xd0\x3e\xc9\xbc\x99\x83\xb9\x40\x44\x90\x85\x5a\x2c\xf2\xe8\x2f\xab\x43\x88\xef\x41\x24\x80\xe4\x4e\x2d\x0b\xdd\x9e\x54\x6c\x40\x08\xeb\x0c\xf2\xe5\x87\xdc\x9e\x12\xae\x20\x13\x1c\x51\x7a\x33\x41\xa9\xcb\x99\xa1\x25\x03\x49\x1c\xac\xe9\xfa\xf6\xdb\x6f\xf8\xfc\xc7\xaf\x2f\x48\x26\x83\xda\x86\x77\x45\x30\x8e\xe5\x3d\xb6\x76\xf8\xda\x9b\x4f\x31\x90\xde\x67\xfe\xf9\xed\x00\xbb\x03\xd4\xbb\x5f\xa1\x6f\x80\x81\xf2\x00\x9d\x6e\x7e\xe7\x75\xe3\x13\x97\x75\x69\xae\x46\xa2\x22\x61\xac\x8a\x8d\xb3\x5f\xdd\xef\xab\xb2\x07\x23\xff\x25\x3c\x0f\x28\xab\xb1\x38\x7c\x0c\x32\x8d\xa1\x08\x01\x3a\x8d\xa4\x33\x13\x6a\xa1\xde\xe7\x25\xac\xda\x56\xea\xee\x21\x3e\xd4\x57\x60\x5d\x94\xf1\x70\x6c\x75\xb5\xc7\xb7\xaf\xf5\xe1\xc5\x5f\x16\x58\x09\xdf\x63\x24\x76\x7f\xbb\xa4\xcd\xd5\x8d\xc7\x35\x44\x30\x11\xb1\xc9\xb0\x04\xcf\x17\x02\x43\x2d\xee\x1a\x5a\x3a\xdf\x8c\x6e\x4b\x22\xfd\x67\x13\x8b\xe5\x9d\x7d\x5e\x5e\x5e\x6d\xb7\xd5\x40\x5f\x86\x7e\x88\x74\xec\xa2\xdf\xab\x63\x97\x17\x9d\x79\x45\x80\x33\xdf\x5d\x7f\xab\x5e\xc1\x01\xbe\x4e\xc0\x5a\x00\x59\xea\xdc\x20\xda\xaa\x06\xe7\x16\xe6\xb6\x0b\x7f\xdc\xc6\x34\x80\x0e\x71\xea\x74\x8f\xaa\x3a\xb6\xe3\xea\xeb\x90\x13\x83\x8d\x13\x44\x72\xd8\xbc\x34\x63\x1f\xee\x70\x58\x12\xac\x96\x5a\x80\x3b\xf9\x0a\xeb\x9f\x87\xaa\xee\x2d\x56\x99\x8d\xe2\x04\x15\x42\x42\x39\xc1\xd5\xc1\x4e\x36\x80\x30\xda\x0b\x87\x76\x91\x7a\xb5\x87\xef\x72\x38\x0f\x73\xba\xe2\x17\xad\x5e\xb7\x2f\x4f\xa8\xb3\xd2\x1b\x8c\x8e\x4e\xc0\x2d\x86\xfa\xff\xa9\x8a\x89\x4a\x82\x8d\x44\x4f\x5b\x7f\xac\x8a\x5c\x7f\x8c\x34\xef\xba\xa3\xe0\x08\x97\xf2\x63\xce\xd8\x19\x9d\x5b\x4a\x06\x13\xd5\x8d\x85\xba\x87\x8d\x29\x20\x79\xae\x7b\xc5\xba\x3d\x25\x5c\x40\xcc\xa2\x2c\xd8\x58\xcf\xd5\x41\x5c\xef\x74\x1c\x92\xda\x38\x55\x18\x4f\x61\xac\x10\xf4\x2f\x16\x97\x36\x1b\x0b\xa7\x4d\x95\xeb\xca\x01\x16\xd6\xa3\x6f\x05\x06\x5e\xde\xd9\x00\xe2\x26\xaf\xa0\x38\xa5\xb8\xfd\x69\x03\x71\x9a\x0a\x9d\x4b\x86\x87\x59\x63\x09\x73\x1a\x72\x8f\x85\x2c\xa1\x95\xcf\x75\xb5\x9e\x71\x2d\xfc\x40\x1a\x29\xea\xd7\xab\xeb\x63\x7b\xac\x9d\xa8\xcf\x8d\xf9\x79\x02\xa6\x0e\x1f\x88\x25\x66\x21\x5e\xef\xe1\xe6\xf2\x61\x73\x00\x1d\x7e\x30\x65\xee\x35\x75\xa5\x7e\xb4\xf5\xfe\x6b\x2b\x90\xa5\x4a\x83\x63\x1d\x7a\xf2\x8d\xff\x3b\xcb\x24\x95\x83\x30\x77\x40\xbe\x4d\x02\x34\xcb\x0c\x23\x3e\x82\x6e\x5f\xae\x8f\xe5\x18\x58\x6b\x99\x75\x48\xee\x5f\x7f\x7f\x0a\xb0\x4d\xcb\x09\x09\x75\x89\x75\xfb\x72\x97\x97\x67\xd5\x59\x99\xe5\x94\xa0\xd9\xea\x06\x4a\x33\x08\x2e\xd8\x84\x13\x74\xa7\x59\xfd\xca\xd2\x91\xcc\x9b\x4d\x38\xcf\x9c\xab\x09\x74\xab\xd0\x0f\xc8\xfd\x5e\x16\x8e\x0b\x27\xb5\x63\x7a\xc7\xf7\x2f\xe0\x1c\x8a\x9b\x7e\x88\x74\xbb\xa5\xad\xea\x2e\xf7\x58\x6f\xbf\xb6\xd5\x66\x7b\x19\xa2\xb9\xd9\xf5\xa5\x4c\xa1\x1c\x0d\xc2\xfe\x16\x62\xbb\x53\xa3\xbb\xee\x8e\x24\x88\x5d\x57\xb2\x81\xcd\xb1\xdb\x30\xc6\x51\xb1\x4d\x41\xa4\x3a\x04\x5d\x17\xdd\x7e\x70\x06\x9e\x65\x45\x94\x05\x39\x66\x67\xc5\x7a\xce\x71\x29\x8c\x17\x26\x8d\x47\xe1\xfd\x57\x59\x1b\x64\xb4\x84\xaf\x16\x52\x22\xe6\xea\xa6\xda\xc2\x6f\xa1\xe5\x36\xfd\xce\x8c\x38\x45\x8b\x5c\xbb\xd0\xb9\xb9\x05\xdb\x7f\x3e\x33\x0e\xdc\xdc\x7d\xc1\x2e\x0f\x65\xa9\x9d\xee\x42\x70\x3f\x44\x1a\x82\x80\xe6\x1c\x0b\x5c\x1a\x7a\x9d\x23\xab\x84\x63\x08\xec\x0c\x14\xf9\x5b\xdf\xae\xfd\x8b\xaf\x67\x38\x49\x06\x22\x0e\x29\xdb\x13\xfc\xf7\x38\x6e\x91\x5a\x1d\xc7\xa1\x0c\xb9\xd2\x68\xb4\x15\x0e\xa4\x3a\x19\x8a\xa4\x5d\x0e\x1c\x5c\x96\x64\x01\x4d\xef\xf0\x36\x4b\xd8\xad\x96\xc6\xe1\x65\xbb\x34\xf4\x9f\xdb\xaf\x3f\xe4\x33\x0c\xc5\x17\x6b\x48\x86\xc6\x6b\x3f\x1e\x6e\xaf\x49\xff\xc7\xcc\xa2\x92\x21\xa2\x50\x31\xec\x7d\xb0\x0b\xca\x5a\xd6\xc8\x08\x61\x54\xbb\x76\xd2\x6a\x39\xb7\x6a\x7d\x9a\x72\x5a\xc8\x18\xce\x29\x74\xa7\xbe\x87\xf7\xa7\xf1\xfe\x71\x66\x51\xb0\x8a\xab\x71\x48\x3d\x4d\x6d\x17\x23\x67\xfc\x24\x8f\xa2\xcc\x22\x67\xd2\xd3\xdd\x2e\xf2\x53\xad\xf6\xff\xa5\xb6\xc8\xa3\xc8\x00\xea\x7d\xe1\x94\x82\xa6\x45\x92\xe0\xb0\x5c\xcc\x4c\xeb\xc3\x9b\xc6\xa3\xc8\xba\xcf\x61\x4a\xf5\x9c\x57\x65\xe0\x80\xe4\x3f\xa1\x38\xc5\x25\xf3\x28\x8e\xe2\x90\x9a\xbf\x82\x07\x4c\xf8\xc7\xc9\xa3\x98\x43\xea\x82\xbc\xc2\x8c\xea\x8c\x3c\x8a\x85\xc1\x9d\xb7\x52\xff\x01\xdd\x3e\xca\xbe\x6e\xc4\xa3\x58\x39\x8a\x7a\xa8\x2d\xb7\xbd\x70\x20\x8f\x62\xc3\xb9\x27\x31\xac\xf7\x50\x3f\x43\xa9\x3f\x7e\x19\x5d\x3d\x89\x35\xc2\x0c\xff\xbf\xcd\x80\x70\x12\xc2\x5d\xfa\x9c\xbf\x81\x7c\x97\xcb\x4b\x09\x8f\x48\x42\x51\x10\x5d\xe5\xad\xae\xf2\x72\x6a\x93\xce\x23\xa2\x65\xe2\x01\x72\x27\x0d\x59\x1e\xd1\x8c\x81\x8f\xf1\xbe\x48\x6c\x01\x74\xd1\xe8\x55\x2d\xdf\xfb\x22\x18\x8f\xa8\xa4\x88\xb1\xeb\x9b\x2b\x2f\xa8\x01\x31\x99\xf5\x3c\x62\x31\x0b\x48\xbc\x5e\x1d\xf1\x6c\xce\xcc\x23\x1e\x3b\xe5\xd2\x76\x68\xa4\x74\x11\xdd\x15\xe8\x7c\xdf\xaf\xe9\x3c\x4a\x08\xc1\x7d\x53\x75\x8f\xa0\x1c\x81\xee\x78\x94\x30\x82\xe0\x8b\x40\x87\x74\xa4\xdd\xd1\x4f\x4f\x12\x81\xbd\xda\x6a\x0f\xcf\x72\xca\xa3\xe6\x91\xc8\x9c\xb3\x98\x92\xfa\x75\x5d\x9a\x87\x03\xd4\xb2\xf7\x33\xe6\x91\x00\x93\x45\xa1\x14\xe0\x78\xfe\xf3\xa7\xb5\xfc\x38\xb2\x28\x01\x39\x2a\xba\x5d\xc9\xfd\x02\xc7\x69\x54\x91\xe5\x91\x24\x80\x94\x6e\x93\x6b\x78\xaa\x8a\x62\x52\x5b\xe3\x91\xa4\x04\x3b\x28\xab\x3a\x6f\x5f\x6e\x73\x15\xfe\xae\x84\x4e\xbc\x2f\x7d\x5e\x6e\xda\xda\xa3\x35\x97\xf9\x28\x3c\xd2\x51\x86\xed\x6f\xef\x7e\xd2\x67\x3a\xf3\x51\xce\x36\x68\xb5\xdf\xab\xb1\xe7\x00\x8f\xb4\x10\x51\xd0\x7c\xc7\x1c\xf4\x3a\x37\x72\xfe\xe9\x8c\xc6\xae\xe2\x8d\x82\xb3\xf7\x93\xe7\x65\x12\x19\x3c\x54\x37\x50\x14\xa3\x9d\x93\x47\xc6\x66\x16\x03\xaf\xaa\x2a\xdc\x1a\xee\x97\x87\xcf\xa2\x1f\x1e\x01\xe1\x32\x1a\xd4\x35\xff\x5f\xca\xbe\x6c\xb9\x51\x24\xfb\xfb\x75\xfa\x62\x2e\xd8\x72\xe1\x52\x92\x65\x97\xa6\xbd\x8d\xa5\xaa\xea\x9e\x2f\xfe\xa1\xc8\xe5\xa4\xcd\x94\x04\x1a\x40\x65\xbb\x9f\xfe\x0b\x4e\x2e\x2c\xc2\xae\x9e\x88\x89\xa8\x1e\x93\x42\x08\x92\xcc\xb3\xfc\x96\xff\x35\x40\xf4\x67\x91\x1c\xf5\x9c\x96\xe7\x77\x21\xbb\xad\xf8\x5c\x7f\x36\x73\x4d\x62\xd2\x1e\x05\xbd\xac\xaa\x43\x33\xb4\xb2\xa9\xaa\x83\x1f\x1a\x47\x34\xc3\xb2\x29\xaa\x1b\xbf\x54\xe7\x06\x02\x39\x81\xc4\x51\xee\xf4\x9a\x51\x03\x62\xac\xe0\x3e\x88\xaa\x49\x1c\x41\xcc\x5d\x12\xb7\x2d\xd5\x65\xd7\x85\xc4\x71\xac\x62\xb7\x5a\x6e\x5a\x38\xda\xb6\xcd\xf8\xd9\xc4\x31\xa3\x58\xbc\x87\x52\x7b\xd3\x9b\x0f\x10\xaf\xa3\x8d\xb9\xfb\x20\xa0\x3f\xa2\xaf\x33\xef\x66\x4d\x31\x43\xd8\x34\xbe\x5b\x71\x2c\x32\x0c\x03\x51\x56\xaa\x19\xb6\xae\x49\x9c\x44\xd6\xbc\xd5\x2b\x84\x35\xae\x6e\xe6\xd7\xed\x38\xe1\x0c\x61\x53\xd8\x76\x19\xdd\x93\xd4\x58\x3d\xd9\xaa\x5c\x9e\xeb\x72\xf2\x53\x33\x69\x55\xa5\xab\xd7\x12\xf4\x0e\x8e\xa7\x83\x68\x21\xdc\xac\x4c\x59\x6d\xf5\xa7\xf5\xe2\xf6\xf1\x20\x14\xb8\xdb\xf5\xf9\x5d\xa0\x11\xc7\x8e\xb7\x13\xe1\xbb\xb2\xbe\x7a\xdd\x1b\xb4\xba\x68\x73\x90\x98\x0a\x13\x05\xdf\xfb\xb2\xdb\x83\x37\x7a\x3a\x44\xe5\xd8\xff\x32\x75\xf5\x17\x94\xb3\xd5\x67\x37\x92\x65\x69\x6c\xbb\xdb\x20\x46\xe4\x09\x12\x33\xc2\x70\x6a\x88\xb2\xac\xce\xa5\x72\x79\xb3\x75\x2f\x99\x00\xee\x49\xcc\x33\x86\x31\x94\x7a\x29\x5c\xb9\xfb\x03\xee\xd6\xe4\xfb\xb9\x30\x3a\x40\xb6\x76\xd5\x58\x9d\xd7\x8d\xc9\x25\x47\xf2\xed\x0b\xd4\x95\xf3\x04\xfb\x2d\x1c\x92\x3c\xed\x99\x10\xdb\x56\xb4\x13\xb1\x7a\x12\xe7\xca\x6d\xd0\xa6\x9a\x4c\x6d\x91\x50\x34\x27\x28\xc5\x11\x1e\xcc\xe4\x63\x82\x12\xec\xb0\x69\x10\x87\xbd\xea\x82\xd2\xc3\xbe\xee\x77\x80\x58\x70\xaa\xdc\xf6\xd6\x4e\x7b\x91\xa3\x13\xc9\xc8\x9a\x25\xed\x91\xf5\x32\x17\xa0\x92\x58\x66\xe0\xab\x9f\xdb\x73\xfd\x13\xde\x51\x9e\x6a\x18\xad\x91\x58\x8a\x84\x45\x9e\x90\xf2\xbc\xc2\x2b\x5a\xd4\xcf\xe7\x6e\x35\x0c\x3f\x49\x65\x02\x2b\x90\x0b\xad\x07\xc4\x01\x3e\xf9\x3a\x25\x69\xea\x08\xd4\xad\x65\x01\xd8\x0a\xce\x4c\x7f\xcf\x7d\x42\xe7\x39\x56\x0b\x5c\x8e\x89\xf8\x76\x5d\x88\x72\xe5\xf4\xa8\xaa\xb7\xf7\xc9\xe5\x02\x51\x88\x64\x35\x85\x68\xed\x06\xe9\xaf\xd1\x64\x06\x25\x3b\xfc\x9e\xbf\xf0\x79\x00\x49\xa2\xcc\x26\x76\xcd\x50\x19\x77\x36\x5d\xe5\xfe\x13\xa0\xb1\x5b\x70\xfb\xe7\xee\x13\xc0\x03\x49\x62\x62\x0d\x7f\x6c\xf0\xb9\x6d\x45\xa9\x45\xad\x2f\xcb\x8e\x24\x49\x52\xab\xbb\x8b\x92\xa5\xb7\x45\xe3\xea\xd8\xbd\xb8\x33\x49\x52\x9a\xe3\xe2\x62\x11\x91\xb7\x1e\x89\x31\xb3\x01\x27\x24\xcd\x50\x54\xec\x1b\xd4\xc1\x5f\x1b\x75\xcc\x67\x7f\x95\xbf\x7b\x09\x51\x02\x93\xb8\x93\x50\x3f\x10\x99\x3d\x7e\x38\x8e\x57\x15\x86\xd3\x98\xe5\xe0\xcb\x44\xc5\xa1\x5b\x97\x1c\x52\xc8\xa9\x84\x8d\x9e\x4d\x42\x63\x01\x56\xdb\xa0\x14\x68\x26\x33\xbe\x03\x4c\x0b\x7c\x2f\xf6\xde\x43\xb7\x9b\x4a\xf7\xd5\xb4\xe1\x46\x12\x2e\x25\x96\x56\x8b\x66\x7b\x96\xc1\xc9\x7f\x82\xc5\x76\x63\x73\xc6\x30\x07\xbb\x2b\x5c\xd3\x67\x7a\x9c\x6b\x6f\x0c\x16\xd0\x96\x23\xa7\x55\x3f\x4e\x02\xc6\xa4\xaa\xa8\x9d\x2f\x07\x2e\xef\x73\xe8\x1e\x92\xe4\x1a\x22\x4f\xdd\x0e\x0e\xe7\x60\xbb\xe1\xfe\x9d\x49\x44\xc4\xa8\xe9\x5b\xcf\xbe\x15\xdf\xc7\xdc\x89\xa0\x1c\x0b\x04\xd6\xc3\xd3\xf6\xeb\xfb\x08\x23\x11\x3c\xc1\x6e\x69\x59\xb5\xa1\xdb\xd7\x9f\x5d\x66\x78\x10\x9f\xc0\xae\xfa\xda\x3d\xbd\x01\xd0\x84\x24\x32\x11\x82\xf5\xe9\x48\xd3\xbd\x16\xe1\x85\x4e\x24\x8f\x15\xeb\xa5\x05\x96\x42\x3f\xf7\x57\xae\x84\xd5\x2d\x82\x52\xef\xfd\xdf\x34\x61\xc8\x40\xfb\xe7\x9f\xc3\x10\x2b\xd1\x39\x30\x98\x08\x8c\x5f\xa8\x8e\x91\x44\x83\x45\x11\x79\xbd\xbc\x66\xd3\x4e\x77\xfb\xc4\xc4\x02\x0d\x82\x96\x37\x7f\x8c\xbe\xc2\x30\x8d\x15\x3a\x83\xef\x8b\xe7\x5b\x0c\x04\xa7\x07\x49\x58\x1a\xc5\x31\xb2\x6c\xc5\xb9\x7d\x81\xb2\xc5\xe7\xf2\x69\xea\x49\xd2\x48\x48\x2b\x55\xff\x6a\xe9\xda\x7a\xa8\x7b\x4c\xd2\x34\x62\x88\xeb\x38\x9d\xe5\xa1\x40\xcf\x09\x9b\x40\xfb\xc3\x86\x20\x63\xe3\x69\xb1\xd9\xae\xaf\xf6\x8b\xbb\x87\xaf\xf7\x3b\x7f\x30\x13\x32\x72\x10\x9a\x95\x38\x35\x96\xe4\x87\x04\x8c\xd1\x8b\x93\x92\x28\x89\x5c\x10\xea\x9e\xf2\xf8\x12\x49\x26\x91\xee\x82\x1e\x82\x38\x47\x9a\x45\x0d\xab\x43\xd5\xcc\x8b\x0b\x90\x94\x80\x62\x6c\xb0\xf7\x0f\x7a\x12\x57\x41\x64\x94\xa4\x94\x48\x19\xf5\x32\x47\xb1\xff\x3b\xa3\x94\x38\xaa\x8c\xab\xf8\xfb\x23\xb9\x2b\xcf\x5f\xed\x56\xab\xfd\xe6\xf6\xe1\xbb\xef\xf0\x91\x34\x4f\x58\x22\x7c\xab\xf8\xca\xbb\xc3\x91\x34\xe7\xce\xcd\x16\x9a\xb6\xae\xde\xaf\xeb\xea\x38\x7e\xf9\xd2\x9c\xeb\x8c\x04\xe3\xb5\xbb\x62\x5a\xa0\x20\x69\xae\x28\x06\xf9\xe5\xf9\xb8\x6f\xfe\x7b\x16\xfd\x7b\x96\xe6\x20\x85\x13\x69\x46\x02\xdc\xf2\xfc\x8e\x5a\x34\xfd\xa4\x10\x52\xe3\x23\x74\x8b\xf4\x8b\xa8\xa1\x5f\x2a\xb8\x1f\x04\x89\x12\x3e\x30\x2f\xea\x55\x75\xa8\xea\x4b\xcd\x40\x92\x4a\xae\x71\xc5\xb7\x52\xaa\x4b\xa1\x7e\x3c\xa3\x23\xea\xe6\x38\x15\x05\x25\xa9\x4a\x09\x96\xf4\x03\x69\xc3\xa3\x96\x47\x91\x61\xaa\x88\xc6\xba\x1e\xec\x3f\x35\x6e\x27\xa9\x96\x29\xfe\x54\xb4\xe1\x03\x8f\xee\x19\x2d\x0c\x29\xa4\x31\x36\x27\xbb\x45\x76\xeb\xa5\xab\x06\xbb\x4c\x0a\xa9\xf5\x33\x7c\x2d\x4a\x5d\xbd\xa6\x23\x47\x14\x92\x02\x8b\xfb\x00\xd7\x42\x7b\x25\xd4\x0f\x26\x2c\x87\x5d\xbc\xd6\xbd\x04\xa7\x8b\x02\x2a\x49\x4d\x9c\x61\x9f\xf0\x20\x9a\xd1\x52\x96\x1a\x62\x41\x29\x27\x6c\x09\x58\xe8\x51\x00\x0d\x93\xd4\xb0\x2c\x1f\x18\xaf\xe2\x47\x37\xe5\x95\x28\x0e\xef\x8b\xf3\xa0\xc4\x4b\xb2\x28\x4e\x90\x9c\xaf\x41\x9e\x4b\x7d\xf8\x30\xc5\x75\xc3\x63\x19\x61\xab\xd3\x0a\x6a\x39\x53\x11\xfb\xf2\xb9\xe7\x9e\x25\xd2\xb6\x5d\x9a\xb2\xdd\x3b\x7a\x90\xff\xb2\x34\x15\x09\xb5\x1e\x21\xf6\x36\x34\xdd\xdc\xc5\xb4\x6d\xb0\xd2\x66\x69\xc6\x71\x6e\x16\xaa\xda\x34\x0f\xa1\xa2\x4d\xb2\x8c\x70\x8f\x08\x5c\x3d\xfd\xf9\xb8\x7b\xb8\xdf\xaf\xbe\xfa\xc5\x21\x23\x24\x42\x16\x8b\x68\x1a\xa8\xdb\xf5\x7f\xb9\xbb\xae\x7f\x0c\xff\xf1\x4b\x44\x46\x72\x93\x75\xb7\xe8\x3b\xc0\x8f\xc3\xbb\x8b\x57\x97\xe3\xb7\x24\x23\x22\x4a\x1d\x7f\xf3\xa6\xae\xce\xa7\xde\x04\x65\xfc\xa0\x32\x62\x38\x4a\xb4\xda\x32\x44\x20\x82\x5c\xf8\x11\x93\x8c\x72\x85\xf7\x00\xcb\xfc\xe8\xfb\x3e\x3b\x35\x33\x2a\x58\x46\x07\x7c\x54\x70\xfb\xd5\xc4\x37\x85\x64\x2c\xb1\x26\x9e\x77\xf7\x88\x94\xf3\x77\x83\x49\x2b\xfc\x78\xb5\xbe\x7e\x7a\xd8\xee\xf6\x77\x0f\xf7\xbb\x2f\xb7\x7f\xee\x1f\xd7\x4f\xab\xf5\xfd\x6e\xff\xf0\xfd\x7e\xfd\xe4\x07\xe7\x91\xe5\xad\xef\x85\xd6\xf7\xf0\x8a\x0b\x72\x97\x12\x15\xe5\x73\xe3\xd1\xc0\x9f\x26\x08\x59\x6e\xac\x26\xf4\x33\xb4\xf8\xab\xad\x09\xc8\xa4\xc3\x47\x32\xc1\x95\x87\x49\xdc\x14\xf5\x61\x72\x17\x45\x6e\xac\xfc\xda\x4b\x75\xba\x39\x54\x3f\xc3\x9a\x94\x49\x41\xad\x54\x10\x2e\x12\xfb\x1f\x70\xa1\xe3\x10\x06\x0a\xac\x08\xfd\x47\x84\x29\x2e\x21\xf2\xf6\xf6\x9b\xa6\x39\x77\x01\x39\x1a\x6a\x4d\xbe\x5c\xa5\x8a\xc5\xc1\xd0\xba\x79\x28\xc7\x86\x00\xfd\x40\x9d\x08\xdc\xa2\x57\x2f\xe7\xd5\xb9\xbc\x2d\xca\xe7\xc5\xe6\xe6\xe1\x97\x3a\x4d\x24\xd3\x4a\x62\x2b\x70\xe1\x4c\xbf\xed\x03\xfd\x3b\xa9\x67\xa6\x41\x27\x32\x94\x73\x6b\xf1\x57\x51\x95\xd0\xa5\x3b\x1a\x55\x2f\x46\xcb\x5f\x06\x8e\xdc\xde\xad\x1a\x18\xc3\x6e\xc2\x1b\x68\x12\xca\x5d\x00\x7a\xb5\x12\x2d\x3c\x57\x75\x01\xcd\xfd\x78\xfb\xcc\x4c\xca\xf1\x15\x86\xb2\xad\xe1\x54\x43\x09\xe7\xf0\x0e\x1a\xa6\x31\x4e\xb2\x39\x6b\xf8\xab\xb2\xf6\x36\xff\x2e\x4e\xa7\xbe\xb0\x24\x0e\xa8\xac\x34\x9e\x03\x24\x4a\x04\x52\xca\x96\x0f\xf7\x5f\xb7\x63\xed\xb6\xee\x15\xce\x13\x33\xd0\x95\x71\x99\xe0\x5c\x36\x46\xe2\x4c\x60\x15\xe6\xb5\x28\x91\x58\x61\x2d\x54\x47\x0f\xab\x0b\x2d\xad\x09\x8a\xd6\xbe\x11\x10\x9a\xd8\xe5\x05\xd5\x98\x90\x44\xd9\xa2\xf3\x5d\x55\xb6\x2f\xc3\xb8\x85\xa4\xa9\xf5\xa1\xc7\xda\x55\xdb\x76\xaf\xc6\xfc\xab\xdb\x6d\x69\xd1\x50\xd8\x71\x4e\x73\x82\x90\x14\x62\x2c\x20\x87\xe0\xfe\x83\x93\x19\x8d\xe2\x5d\x45\xa9\x66\xdc\x59\x08\xc9\xba\xb0\xc8\xdd\x30\x64\x4b\x14\xb3\x1c\x5b\x42\x32\x29\x33\xfb\x0a\x21\x63\x65\x57\x21\xa2\x65\xf4\xe0\x09\x4d\x69\x0e\xc3\x34\x1f\xc9\x26\xfe\x0e\x50\x1e\x61\x60\x77\x72\x9b\x2a\x56\x3d\xc2\xea\x4c\xa8\xa0\xd4\x6d\xe4\xc5\xcf\x2e\xac\x82\x0f\x85\x44\x09\xa1\xbd\xb8\xc9\x46\x55\xd7\xdd\x82\xf1\x32\xf9\x65\x4c\x26\x9e\x3f\xe8\x25\x8a\xa6\x32\xe0\x7e\xa4\xb6\xd4\x0b\xef\x2f\x7f\x3e\x40\xb3\xfd\x58\x4c\x60\x7e\x09\x23\x3c\x66\x58\xb9\x3c\x8a\xb7\xd5\x8b\x08\x66\xfd\x84\xe4\x4c\x73\xe7\xb6\x37\xc2\x4f\x72\x7f\x5c\xc5\xe8\xb5\x62\xd9\x26\x5b\x38\x1c\x2c\xf3\x6e\x7c\x7a\xc1\x52\x94\x57\xf9\xba\x5d\x77\x0f\xc8\x9f\x5c\xe8\xcc\x7a\x73\xba\xe6\x46\x0f\x3d\x26\x44\x4a\x86\xcd\x59\xef\xcd\xef\x93\xa7\x4f\xcb\xcf\x44\x31\x85\x52\x8d\xcd\xa1\x50\xb0\xb4\xcf\x77\x51\xd7\x97\x5e\xdb\x1f\xdc\x07\x25\x25\x72\x0e\x56\xde\x51\xd1\xc2\x70\x3e\x22\x12\x0e\xd3\x68\xa2\x34\xe0\x4b\xe2\xc4\x5c\xa0\x7d\x28\x77\xd0\x65\xc5\x13\x1b\xd4\xc9\x37\x1a\x63\x1b\xc2\x07\x51\x1f\xdf\x46\x6f\x1d\x44\x80\x6b\xd9\x12\x0e\x22\xfc\x8d\x6a\x2c\xfc\x9d\x0e\xe2\xbd\x4b\x7b\x11\x2a\xb6\x2c\x26\xf5\x28\x02\x60\xe3\x32\x0c\x42\xf6\xb5\x2d\x59\xd9\x63\x34\x32\x26\xcb\xfc\x44\xbf\x83\x56\x68\xd1\x8a\xd9\xd2\x2b\x8d\x13\x5b\x44\xd8\xd5\xe2\x27\x1c\x06\x78\x14\x42\x63\x4d\x70\x25\xbb\xe9\xb6\x4a\x31\xe4\xd4\x12\x1a\x83\x31\xd4\xdb\x02\x55\x25\x74\x9b\xfd\xa0\x66\x76\x59\xbb\xa1\xb1\x51\xc8\x00\x43\xcb\xf5\xe6\x7c\xbc\x24\xd3\xcc\x3f\x30\x9a\x50\x6b\x2e\x87\xb0\x19\xa4\xac\xcc\xd9\xaa\xcf\xfc\x57\xf8\xbc\x35\x8a\xba\x5d\x2c\xd7\xeb\x5f\x19\xdf\x76\xc3\x0d\x9a\x19\xb5\xc5\x11\xdc\x1b\x77\x69\x26\x4c\x68\x22\x6d\x3d\x3f\x80\xfb\x2f\xb1\xe0\x84\xa6\x69\x82\xbc\x15\xa7\x15\x37\xcf\x58\x1d\xad\x63\x34\xcd\x08\x6a\x6f\x14\xaa\x0a\x78\x91\x6e\xe1\x4a\x50\xb2\xe6\xd7\xbe\xea\x1f\xfd\x3b\xf9\x16\x29\xf1\xf1\x59\xab\x08\x97\x24\x86\x2f\xd3\x84\xd8\x4d\xe2\x28\xb6\x27\xd1\x1f\xc8\x44\xee\x6b\x04\x8f\xd5\xe1\xe0\x0d\x2d\xfc\x51\x6d\x32\x1f\x65\xd9\x96\xff\x16\xfe\x7b\x86\xd2\x35\x32\x87\x8d\xd0\xfe\x0e\x11\xa1\x32\x57\x3a\xdd\xcb\x0b\x8f\x4f\x42\x89\xb2\xac\x92\xd3\xb9\x79\x41\x00\xa7\xc5\xf8\x1e\x61\xac\xa1\x33\xff\xe6\x51\x9a\x29\x8f\xcf\x7d\x82\x9f\xe8\x2c\xd0\x87\x3d\x73\x32\x74\x84\x52\xa9\x62\x17\xc2\x5d\x81\xac\x2d\x6b\x68\x4e\x0e\x89\x50\xaa\xa2\xc4\x41\xe7\xb1\xc8\x00\xa8\x4e\x34\x16\xf1\xed\x46\x59\x1b\x9c\x62\x25\x9a\xd1\x96\x4b\x59\x96\x21\x44\xab\x3c\x1f\x83\x24\xea\xf8\x62\x18\x70\xdc\xae\x7f\x14\x87\x0b\xd5\x39\x37\x84\xc7\x11\xd6\x2a\xf7\x0d\x94\xba\xd7\x5c\x22\x94\x77\xd9\x0c\xea\x3a\x76\xf9\xc2\x9d\x28\x0b\x03\x4d\x88\xa5\xc6\x73\x5e\xd0\x0c\x69\x78\x28\x78\x22\x5a\xd8\x94\x3f\xab\x42\x4d\x30\x65\x84\x0a\x49\x13\xef\x09\xfd\x58\x55\xe1\x92\x3c\xa9\x89\x50\x19\xc5\x08\xdd\x3e\x16\x65\x3b\x67\x74\x42\xa8\x4c\xd2\x08\xc5\xf8\xdf\xbe\x36\x50\x0f\x95\x3c\x09\x95\x3c\x46\x70\x92\x25\x2a\x6c\x4a\x14\xcd\x0c\x07\x45\x84\x01\xc5\xa8\xe1\xec\x8f\x81\xc9\x03\xf1\xd5\xe2\x2a\xea\x09\x1a\xc0\x8d\x54\x86\x22\x48\xf3\x7b\xd1\x96\x7d\x0d\x9e\x42\x1c\x61\x4a\xfd\x77\xe4\x12\x26\x3f\x08\x12\x82\x4e\xd1\x96\xe8\xb2\x51\x55\x3f\x43\xa7\x93\x19\x32\xbb\xd3\x62\xa6\xbc\x19\x51\xe4\x09\x05\x6e\x33\x69\xdb\xb6\xa8\xaa\x1f\xcd\xc8\x0a\x98\x50\xd0\x09\xc6\x5d\x6b\xa4\x60\x8e\xb0\xc9\xb3\x88\xe1\x71\xdf\xca\x9e\x84\xc5\x91\xb5\xf0\xf8\x64\x1d\x1c\x85\xf8\xfe\x63\x9a\x23\x6e\xfc\xda\x02\x8f\x2e\xc5\xff\xc7\x37\x85\xa5\x69\xce\x7d\x91\xc5\x03\x3f\xa7\xf0\x8c\x4b\xe1\x2a\xc2\x32\x6a\x7b\xcb\xf2\x3c\xb1\x28\x9f\x0c\xe3\x12\xe1\x73\xdd\xed\x19\xc2\x85\x09\xa3\xa9\x31\xcc\x33\x92\x6c\xd3\x31\x84\x70\x8c\x2a\x89\x21\xdc\x4f\xa8\x0b\xf3\xbe\x13\x75\xcf\x98\x71\x23\x18\xd3\x08\x32\x7a\xc2\x87\x39\x53\x20\x66\xcc\xc4\x44\x0d\x7a\xf2\x8d\xeb\xf6\x84\xc3\x14\x03\xfc\xc7\xa7\xf5\xfe\x6e\xf1\x47\xcf\xa0\x25\x8c\x13\xc8\x54\x5f\xb5\x58\x9e\xdf\xc3\x11\xce\xa2\xee\xa1\x3c\x15\x32\x68\xda\x11\xc6\x21\x75\x00\xf7\x45\x7b\x57\x35\xf3\x28\x6e\xc2\xb8\x49\x89\xdb\x89\x9d\x27\x45\x3f\x01\x47\x5d\x57\x8f\x64\x49\xc6\x72\x10\x31\x71\xe1\x31\xcb\x75\x82\x55\xbc\xd3\x10\x7c\x72\xd9\x1e\x66\xc2\xc4\x68\xb8\x0d\x6f\xbd\x14\x81\x3b\x24\xa3\x2c\xa6\x41\xe9\xe6\x0a\x5a\x51\x1c\xe6\xa9\xf9\x84\xc9\x98\x61\x53\xba\xdb\x68\x7b\x5f\x57\xc2\x24\xb3\x38\x97\xde\xf2\x1a\xfb\xc1\xf8\x98\x37\xab\x87\xc9\xf3\x90\x9a\x20\x77\xa6\x11\x03\x5c\x2a\x61\xd2\x09\x3f\x58\xf1\x85\xc4\xff\x59\xa5\xca\xfb\x89\xee\xcd\x41\x78\x00\x08\xd3\x89\xc2\x72\xfe\x3f\xfb\x05\x94\x69\x9d\x21\x30\xbc\xcf\x07\x8e\x27\x51\xbe\xaf\x2e\x5a\x83\x3c\x4a\x28\x46\xfb\x48\xff\xf5\x41\xfc\xae\xda\xac\x16\x8f\x5d\xae\x68\xf9\x42\xa5\xba\x50\x3e\x1d\x2d\x4d\x3c\x4a\x72\x64\x18\x15\x0a\x0d\x28\x82\x57\x36\xe1\x91\x26\xf8\x63\x8e\xa2\x69\x82\xe4\x51\xf3\x71\x03\x9f\xc7\x69\x86\x3b\x38\xc2\xf4\x50\x4f\xa3\x57\x28\x1c\x3d\x04\x9e\x44\x14\xc1\xe1\x9b\xd5\x72\xd5\x83\x15\x09\x4f\x63\x85\xb1\x9f\x46\x52\xe8\xf5\xb4\xd2\xc1\xd3\x5c\xa2\x49\x9f\x53\x10\xda\x41\xff\x49\x01\x88\x18\xdf\x3c\x0d\xe5\xe2\x08\xa7\x91\x7d\xf9\x9e\xa1\x5d\x16\x7a\xdc\x95\x1d\xa5\x69\x9c\xc6\xdc\x11\x0e\xbc\xee\xec\x5f\x70\xd1\xaf\x19\x2d\x6b\x9c\x26\x59\xea\x49\x3d\xd7\x87\x4a\xb4\xbf\x83\x73\x70\x09\x03\x28\xd6\x5e\x42\x00\x65\xb1\x85\xb3\xaf\x14\x67\x2a\x96\xc2\x59\x97\x7b\xc1\x7e\xac\xe5\x3d\x74\xb1\xd2\x47\x40\xc6\xf9\xa5\x90\x73\x6e\x94\xf6\xfb\xd6\x85\x8a\xf8\xb4\x1e\xf9\xc1\xff\x77\xe7\x12\x34\xe1\x66\x72\x67\xa6\x4f\x46\x08\x9b\xc8\xeb\xe2\x67\x70\x20\x22\x5c\x48\x8e\x78\xef\x75\xfb\x82\x3d\xc0\x81\xa6\x19\xe1\xc2\xe4\x58\xde\x28\xc5\x11\x36\xcd\x42\xff\x44\x7a\xda\xfc\x6b\xcb\x65\x1a\x63\x93\xf8\x6e\x71\xbf\xb8\x59\xdf\xad\xef\x77\xfb\xdf\xbd\x5b\x3e\xe1\x8a\xc4\x88\xa1\x69\x84\x81\xdf\x8b\xd0\x52\xe5\x3a\xd3\x3e\x21\x46\x1a\xc7\xaa\xaa\x0e\xba\x7a\xbd\x58\xe0\xf1\x5f\x27\x66\x47\xb8\x66\x59\x9a\x86\x5a\x7d\x01\xcd\xac\xfc\x22\xe1\x46\x44\xd4\xd5\xc0\x6e\x44\x63\xc9\x99\xd7\x55\x8d\x33\xff\xb6\xaa\xda\xee\x2d\x5c\x55\x65\x53\x1d\xac\x0d\x5d\x7d\xd1\x6d\xec\x1e\x12\xe4\x03\xfc\xa9\x7f\x8d\xb1\xfd\xe0\xc7\x00\xd3\x79\xaf\x65\x55\x3e\x3f\x0d\x6f\xd3\xe8\x7c\x79\x1c\x49\xc4\xdd\x29\xd4\x60\x71\xc9\x4e\x16\xf9\xa3\x24\xce\x7c\xdf\x69\xf7\x7e\xf2\x4f\x22\x8f\x59\x8a\xd5\xf8\x53\x75\xc2\xa5\x0f\x27\xdd\x21\x68\xc7\x4d\x5b\x9f\x79\xcc\x80\xf7\xd8\xd0\xd0\x52\x73\x25\x12\x98\xae\x11\xdc\x7f\x0c\x64\x62\x8d\x25\xaa\x63\xe5\x65\x06\xdd\xb1\x84\x59\x53\xbb\x97\xea\xf5\x4e\x94\xef\xa1\x90\x6f\xb1\x65\xe3\x1f\x99\xea\x24\xcb\x82\xfc\xec\x05\xc4\xd7\x8d\xca\x22\x96\xb8\xf7\xf9\xe6\x66\xe5\xe5\xbf\xfd\xb5\x64\x31\xc3\x26\xc0\xfe\x19\x1f\xb2\xf5\x04\xdd\xe8\x49\xb3\x38\xcf\x52\x8b\xad\xda\xad\x17\x77\xfb\xed\x97\xc5\x93\xaf\xa9\xe5\x44\x8a\x4c\x79\x65\xfa\x73\xa9\xef\x0a\xb7\x59\x2c\xdf\x97\x13\x3e\x24\xc9\x69\x9a\x66\x56\x23\xbd\x8b\x63\x1e\x42\x6b\x2b\xa7\x52\x63\xa7\x60\x1f\x7c\x92\xaf\x51\x8b\x61\xf2\x79\x46\x09\xda\x09\x21\x8a\x18\xde\x4e\x45\xfd\x1e\x0c\xd6\x51\x52\xe7\x3d\x8d\xa2\x28\xf2\x67\x65\x3c\xc3\xba\x71\x3b\x02\xff\x84\x0a\x29\x88\x63\x18\x69\x52\x21\x3e\x98\xc2\xd3\xa9\x7b\x3b\xd0\x64\x73\x1f\xe7\x39\xe4\x4e\x5f\x66\x71\x09\x5e\xc9\xf3\x18\x30\x48\xb8\xae\x01\x5e\x45\xab\x5e\x7e\x5d\xcf\xcd\x73\x65\x7b\x27\x0d\xcc\xd9\x47\x91\x5c\x90\x28\x52\xc1\xb7\xcd\xea\xc4\x8c\xbf\x55\x30\x8d\x9e\x01\x4a\xd4\x7a\x7d\xac\xfe\x53\x98\xc2\xc3\xde\xdc\x08\xc9\xad\x65\x9e\x73\x72\x08\x5e\x45\x9f\x87\x97\xb9\xe4\xb6\x5d\xe9\x10\x88\x37\xa2\x28\x9b\xe1\xbb\xe8\x86\xa9\x28\x42\x35\xcf\xed\xee\xf6\xb3\x94\x3f\x57\x44\xe1\xa4\xb0\xed\xa6\x6b\x80\x55\x75\x38\x80\xea\xc1\x92\xb9\x12\x42\x07\xd7\xe6\xaa\x1e\x41\x94\x72\x05\x39\xf1\x42\xa8\x88\xaf\x98\xae\xc9\xb9\xce\x88\x16\xa1\x84\xd6\xcd\xf2\x6f\x8f\xd6\x43\xb5\x17\x1f\x20\xb9\xce\x2d\x77\xf6\x1a\xba\x80\xa1\x19\xee\x9e\x39\x48\x62\x49\x6c\x7e\xff\xea\x9d\x9f\x48\x0e\x46\x5b\x71\x10\xb4\x95\x2b\x4e\xd8\x8c\x9c\x3c\x0b\xc3\x25\x46\x66\x77\x5f\x6f\x77\x9b\xc7\xdb\x4d\xe8\x8e\x88\x48\xd9\x56\xbd\xaf\x49\x0f\xc9\x33\xa3\x5d\x56\xc4\x51\x84\x2f\xb2\x1c\x00\xd2\xe6\x8b\x36\x22\x8e\x00\x41\xeb\xbe\x3c\x82\x7a\x2c\xe3\x66\xf5\x78\x5f\x11\x31\x33\x8a\x8e\x44\x12\xaf\x01\x2e\xc1\xd9\xf3\x5f\x97\x46\xdc\x88\x01\x3b\xbb\x16\x87\x6d\xf1\x5c\x9e\x4f\x73\xfd\x71\x91\x46\x16\x3a\x70\x10\x4d\xeb\x66\xee\x55\x8f\xa9\x12\x29\x4f\xb0\x2d\xa6\xba\xdb\x78\x3a\x78\x1f\x43\x22\x52\xb0\xba\xa8\xb5\x68\xe1\x11\xea\xef\x50\x58\x42\xda\xb0\xaa\x29\xb2\x2c\xc1\xe6\xe4\xae\xf6\x7e\x5f\x63\x31\x62\xbf\xb9\x09\x12\x51\x69\xb7\x44\x8b\x80\xe8\x8d\x07\x42\x2b\x5a\x10\xc9\xf1\xa6\xb8\x8c\xe5\xcd\xa9\xfd\x8e\x42\xa0\x80\x48\xfc\xc7\x67\x07\xfd\x09\x0d\xb7\x7c\x4b\x94\xdb\x71\x85\xe7\x45\xa9\x57\xe2\x70\x18\x01\x4c\x67\x31\xfb\x1f\xdc\x7d\xce\x52\xed\x48\x33\xbe\xd8\xb8\xbd\xd8\x61\x05\x97\x06\xb5\x65\xb6\xeb\x3f\xfe\xfc\x7d\xb3\xdb\xad\xef\x3f\x7b\x29\x45\x4e\x08\xaa\x26\xbf\x60\x03\xe9\x76\x80\xb5\x0e\x03\x0c\xa2\x25\x9c\x84\xa0\x2b\xe3\xfa\x83\x0a\x50\x0b\x0d\x6b\xb4\x77\xe1\xe1\xe4\x26\xe9\xb9\xf9\x4e\x82\x7a\x98\x3f\x0a\x01\x10\xf7\xee\xba\xdd\x8a\xbe\xc5\x62\x91\x3b\x2c\x33\x2b\xe3\xd5\x7c\xae\x8d\x4f\x84\x62\x39\xf2\xda\x77\xe2\x07\x36\xfd\x67\x52\x49\xa1\x80\xb0\xd4\x11\x33\x0b\x5b\x1a\xbf\x2b\x4a\x3b\xa5\xfc\xa2\x20\x80\x5a\x39\xd7\x73\x03\xf5\xe3\x59\x1e\x0a\xe5\x8a\x92\xeb\x2e\xa4\x39\x97\xed\x9d\x98\xc4\xf4\x02\x1c\x73\xf4\xe9\xea\xee\x46\x1c\x47\xf0\x14\x01\x12\x84\xf3\xc6\x2d\xad\x6b\x45\xef\x0e\x4a\x04\x28\x85\x62\x5a\x9b\xc5\xf1\x1b\xd4\xef\x8f\x55\x35\x42\x48\x0b\x13\xc5\x5e\x01\xe3\x6b\x03\xf5\xbf\xce\x05\x7a\x0d\x1c\x2b\x6b\x3a\x31\xbe\x0c\x93\x08\x84\x5a\x75\x9b\xc7\x15\xfc\x84\x43\x75\xb2\x02\x35\xfe\x38\x4d\x11\xb7\xff\x78\x2e\x7f\x4c\x29\xe8\xf3\xeb\xbe\x30\xc6\xd8\x6e\x51\xf3\x45\x94\xfa\x60\x65\xf1\xc7\x81\x82\x8c\xb8\xb5\x05\x39\x3e\x07\xe3\x85\xd1\x49\x64\x94\xdb\x9a\xfb\x33\xa0\xc5\x9b\x83\x70\xcf\x7e\xa1\x8c\xe3\x94\x0d\x89\x01\x36\x08\x9a\x1f\x9b\xc8\x08\x09\x69\x3d\xc4\xab\xa8\xca\x15\x36\x19\xc7\x77\x46\xa6\x59\x16\x47\x7e\x37\x29\xaa\x72\xb0\xf8\xc8\x94\xe4\x49\x3f\x43\xcf\x6f\xab\x01\xae\x52\xa6\x5a\x59\xda\x4b\x55\x1d\xbb\xad\xdc\xff\x3d\xa3\x64\x24\xb4\x75\x70\xa8\x8b\xf0\xc1\x2c\xa7\x48\x5d\x38\x81\xed\xc6\x6d\x1d\x45\x65\x8b\xd0\xc1\xf6\x03\x81\x59\x22\x33\x03\x58\xf7\x71\xab\xe4\xb5\xed\x8a\xce\xff\x7e\x92\x25\x3a\x0f\x4a\x32\x55\xdd\x8a\xc3\xcd\xd9\x4f\x1d\x49\x58\x8c\x6f\xce\xa1\x9b\x09\xfb\x74\xa4\x8a\xd8\x1d\x25\x28\x4c\x38\xa4\x56\x5c\xce\x06\x3f\x58\x46\x5a\x05\xdc\xe3\x76\xc4\xb6\xf1\x91\xb1\x24\x5a\x24\x2e\x75\xb0\x10\xd4\x11\xaa\x7c\x7c\x42\x9a\xe5\x79\xea\x77\x0f\x4c\xf9\x2c\xae\xd5\x86\x5c\x77\xb6\x5e\x13\xb8\x25\x61\xa6\x51\xa6\xb0\xdb\xbc\x2c\xda\x9b\x73\x71\xd0\x1f\x17\xe7\x3f\xed\x7e\x4b\xaa\x13\x5c\x18\x3d\xb2\x23\x9a\xab\xd1\x4a\xaa\x73\x5b\xf3\x0a\x42\x2d\xb0\xb4\x84\x98\x15\x52\x5a\xeb\xe7\x29\x07\x8c\x48\x96\x69\x6e\x61\x5d\x8f\x56\x5f\xef\xd1\x72\x0f\x87\x3e\xdc\x44\x32\x4a\x82\x8a\x85\x9d\xbb\x68\x90\xd0\x4e\xdf\x68\xc9\x65\x82\x71\xc6\x09\xf5\x35\x86\xb8\x36\x99\x13\x8e\x76\xc4\x80\x5b\x99\x5b\xa2\x6c\x6d\x6d\x7a\x96\x9c\xc6\xa8\x27\xff\x28\xde\x2d\x98\x7b\x7a\x5c\xc9\x34\xf0\x66\xae\xe0\x00\xcf\x43\xb1\x37\x22\x45\xa2\x11\xdd\xe6\x6c\xcd\xba\x5f\xdf\xad\xb0\x9b\xd2\x29\x59\x3e\x98\xef\x80\x7d\xf9\xf1\xf4\x94\xc6\x3a\x99\x5a\xb8\x59\xa5\x10\xb1\xfc\x58\x39\x30\xf4\x04\x3f\x23\x55\x9e\x63\x0d\x02\xda\x97\x7d\x33\x65\x13\x13\xa9\x94\xc6\x26\xd1\xfa\xe6\x66\xf5\xb0\xf1\xa8\x14\xa9\xb5\x45\xf7\x2d\xbe\xdd\xed\xa0\x69\xb7\xe7\xa2\x7f\xb1\x21\x63\xd8\xd6\x53\xe2\x80\xa9\xdd\x1f\x2d\x0a\x8e\x7e\x1e\x47\x49\x93\x5a\xb4\xe1\x75\x0b\xea\xa5\xf8\x6b\xe2\x32\x4f\xa4\xc9\xa0\xb7\x2e\x7a\xc4\xac\xb1\x2e\xda\x77\xd7\xc2\x9f\x14\xf1\xfa\xb7\xc3\x30\x4b\xfd\x6a\xa0\xbd\xee\x72\xa6\xb1\x71\xca\xf8\xb7\x9a\x1c\xb0\xa6\xbf\x59\x3d\x6c\xcf\xa8\x0a\x19\x92\x45\x15\xd1\x14\x13\x6f\xf7\xda\x5c\x41\x2b\xd4\xcb\x25\x80\x48\x45\x54\x4b\x4b\x45\xfd\x4f\x55\x3b\xc9\xdb\x31\x0c\x5e\x45\xdc\x06\xeb\x1e\x49\x76\x4d\xc3\x91\x3c\xb6\xdc\xe1\x06\xda\xd5\xfa\x61\xfc\x28\x54\xa4\x2d\xc1\xed\x6a\xfd\xf8\xb0\xdd\xec\xf6\xdf\x37\xf7\x57\x0f\xdf\xc3\x67\x21\xc3\x96\xc2\xea\xca\x76\xa0\x95\x8f\xda\x55\x6c\x08\x62\x75\x4e\x55\xa8\x92\x74\x7f\x33\xae\x46\x15\xd0\xbf\xe3\x37\x61\x7c\x6f\x54\x92\x65\xb8\xc7\xd5\x16\x4a\xb0\x3d\x04\xb0\x97\x9f\x49\x2a\x61\x11\x24\x5e\x81\x14\x7e\x16\xd5\xb9\x41\xb6\x9d\xdb\x77\x66\x1f\xbb\x4a\xe3\x2c\xf7\x6c\xd8\x7d\x55\xc2\xae\x3e\xc3\x02\x97\x87\xfb\xea\xce\xea\xb3\xfb\x6b\x4e\x09\x20\xd6\xfe\x6e\xb3\x5a\x7f\x16\x50\xa9\x54\x49\xde\xbb\xbc\x3d\x4f\xa2\x06\x95\x09\xe3\x33\xc8\xc7\xba\x6a\xab\x11\x91\x45\x65\xd2\x86\x78\xdb\xf2\x5d\x43\xdd\x0e\xa6\xa0\x22\x99\xd2\x36\xb3\xb8\xdf\x3c\x2d\xbe\x2c\xee\x36\x57\xfe\x10\xa3\xd1\x40\xdf\xef\x06\xca\x9b\xb3\xed\xe9\x8c\x7f\x2d\xe3\x39\x16\x13\xdb\x97\xa2\xd6\xdf\x01\x7e\x4c\xe5\x78\x88\x62\x4a\x67\xb2\x47\xfe\x2f\x30\x39\xee\x12\x5d\x5b\x60\xfd\x09\xf5\x25\x1e\xc2\x86\xac\x73\x7d\xfd\x0b\xaa\xbc\xff\x16\x43\xb0\x6d\xb1\x5c\xac\xb6\xfe\x9b\x39\x51\x99\x2b\xcb\xba\x70\xb0\x0e\xf3\x85\x0b\x4b\xe3\xbf\x86\xf3\x5f\xc1\x76\xc6\x1d\x13\x71\x8c\xc2\x25\xbb\xcd\x1d\xf9\x75\xb6\xad\x44\x4a\x08\x73\xd9\xf4\x42\x57\x08\x97\x7c\x30\xc1\x87\x8c\x4c\x26\x88\x48\x79\xe6\xe0\x5c\x0f\xae\x67\x35\x80\x5d\x28\xa1\x04\x16\xe9\x7c\xdc\x12\xca\xbf\xdb\x6e\x9a\x4e\x56\x5c\x25\x63\xc6\x6c\x7a\x6a\x53\xa7\xc7\x29\xce\x48\x49\x16\xa3\x8c\x2e\xda\xbc\xdd\x56\x55\x78\x6b\x55\x96\x6b\x3d\xda\x95\xa6\xf6\x6e\x44\x29\x96\x60\x87\xec\xba\x38\x1c\x9b\x6e\xc3\x1a\xdd\x27\x65\xac\x8d\x48\x51\x7a\xfa\xd5\xaa\x3a\x4a\x31\x9d\x23\x3a\x63\x18\x7a\xae\xdf\xd6\xff\x3d\x17\x6d\x78\x8d\x81\x10\xa3\xdc\xac\x2e\xe1\xe0\xb4\x55\x82\x53\xe7\x30\xe3\x52\x86\xd8\x52\xec\x11\xb4\xa5\x37\x23\x04\xdf\x9f\x4a\x47\x26\x26\xc1\x1b\x05\x67\xdf\x77\x28\xfc\xc1\x38\x4e\x10\x9c\x69\xdf\x9e\xd5\x8b\x75\x12\xfd\x5e\x94\x77\x95\x3e\x4f\x11\xff\x3a\x16\x06\x59\xa7\xe2\xdc\x20\xb2\x32\x9c\xc5\x28\x2c\x15\x2c\x36\x4f\x57\x4f\x0f\x8f\xfb\xbb\xc5\x1f\xfe\x50\x12\xa5\xf8\xed\x47\x6b\x85\x65\x31\x43\x61\xa5\xd5\x09\xe1\xde\x6d\xe5\xae\x78\x2b\xca\x67\xdb\x7d\x9f\x5f\x3f\x74\x42\xa5\xb2\x12\x40\xa0\xa7\x94\x58\x9d\x98\x14\x67\x2d\xaa\xad\x3f\xc1\xa9\x9a\x79\x77\xa6\x9f\xc8\x13\xe1\x1b\x1c\x7b\x0d\xa7\x0f\xc4\x38\x88\x4e\x89\xf5\xa5\x47\x91\xc8\xa2\xc5\xc8\x4c\x1c\xae\xee\x17\xfe\x77\x64\x69\xa4\x6d\x08\x8f\x0a\xc8\x18\xc0\x0f\x5f\x04\x9d\x51\x2b\x51\xb5\x7a\x7a\xf8\x7e\x85\xee\xe1\x08\xfc\xdc\x86\x13\xb0\x14\x6b\x29\xa2\x69\x8a\x52\x3c\x76\x2b\x6f\xa9\x3c\x78\x46\x93\x04\xa0\x3b\xfd\xc3\xdd\xe3\x5b\x28\x47\xfa\x63\x29\x8f\x9c\x84\x9b\x8b\x83\xe6\xaa\x03\x9a\x90\x08\xa3\x41\xdf\x0b\x76\x7b\xdb\xa4\x20\xa9\x09\xb5\xb2\x23\x37\xd0\x5e\xa1\x1a\xd7\xfd\xf9\xf8\x04\x3f\xab\x1f\x5d\x00\xd4\xa5\xd2\x70\xf1\x09\x26\xb0\xc9\xec\x80\xed\xfb\x01\xdf\x5a\x53\x6a\x3d\x07\x8e\xfb\xf6\xad\x09\x7f\x64\x19\x75\xe9\xd6\x0e\x3e\xce\x3c\x34\xcb\x22\xe4\xc9\x6e\xa1\xd4\x8f\x75\x10\x51\x26\xfe\x3c\x8c\x66\x6e\xb7\x2f\x75\x17\x98\x7f\x24\xc7\x44\x34\xe3\xd6\x7c\x5f\xd5\xa2\x85\xe6\xae\x78\xae\xb1\x34\x3c\x1e\xc4\x09\xe0\x13\xb8\x94\x81\x27\x9a\xd3\xd8\x58\xe9\x27\x67\x45\xbc\xd0\xdf\xaa\xb3\xea\x69\xc9\x9a\x53\x8a\x2f\xa1\x55\x02\xf3\x12\x2a\xb3\xdb\xab\xe6\xcc\xe0\x4c\xc5\x3e\xd6\x2d\x74\x89\xca\x83\x59\xd5\xa0\x2f\x5b\x37\x93\x5b\xc2\xa5\xc4\x7d\x5f\x68\x5d\xb8\x39\x08\x32\xcc\x04\xae\x18\xd6\x68\xf6\xf2\xfc\xfe\xa5\x50\xcd\x67\xa9\xbc\xce\x05\x41\x97\x9b\xe6\xb9\x4c\x9a\x67\xf1\xc1\x1b\x27\xa4\xc4\x9f\x65\xbd\x8d\xbe\x88\xa6\x47\xef\x68\xa1\x63\x15\xa4\x27\xba\x44\x7e\x0b\x6d\xbf\x26\x08\x88\xd1\xc6\x61\xf5\xd2\xc5\xf0\xdb\xf6\x63\x13\x3b\xa2\x65\x2a\xb9\x43\xbe\xbf\xf6\x6b\x53\x17\x63\xf0\x5e\x03\x69\x44\x4a\xd6\x3a\xb2\x33\x6b\xef\xb8\x1d\x3e\xd5\xbe\x08\x69\x2e\xfb\x88\x5a\x27\x29\x76\xd3\xf7\xf6\x0d\xbd\x11\xe3\x12\xb0\xd6\x94\x63\x4f\xef\x6e\x73\xbf\xb7\x22\xea\x96\xd0\xb2\xdf\x3d\xec\x9f\xd6\xab\xf5\xe6\xdb\x7a\x1f\x24\xfc\x88\xd6\x2c\xc5\xe6\x90\x37\x0a\xdc\xb6\x7d\xbb\x55\x6b\x6d\x27\xe9\x53\xd5\xbe\xa0\x87\x83\x3f\x00\x99\xf1\xf9\xba\xad\x99\xb6\xb6\x47\x30\x79\x6d\x81\x5a\xd9\x95\x1e\x9d\x8b\xcc\x95\xcf\x17\x36\x43\x00\xd9\xa5\x7f\x3c\x2e\x86\x9b\x92\x36\xcc\x26\x0b\xa6\xaa\x64\x68\x2a\x6b\x03\x1a\xa5\xa8\xb0\xe0\xef\x20\x48\xfe\x0d\x86\x58\x6a\xae\x86\x6d\xeb\x8d\x13\x84\xf8\x7c\xa6\x42\xac\xf2\xcc\x6a\x47\x21\x92\x6f\xda\xdb\x75\xa3\x92\xc8\xaa\x72\xef\xbd\xe2\x85\x07\x04\x4e\x01\x4c\x90\x64\x02\x97\xaf\xab\xcd\xd6\xda\x1f\xad\xaf\xf6\xdb\xdd\x62\xf7\xd5\xaf\xa0\x90\x48\x8a\x6a\x4e\x36\x2a\xdb\x77\x29\x4e\x7d\x89\x18\x87\x04\x00\x3c\x40\xb5\xae\xc5\xfb\xd0\xb4\xd9\xaf\x69\x90\xa6\x12\x5d\xb8\xc2\xaf\xbe\x13\xcd\x8f\xf9\x57\x04\xd2\xd4\xf6\x00\x05\x76\x79\x7a\x90\xf2\x78\x54\x96\x26\xe8\x51\xbc\xf8\xeb\xb5\x98\xf1\xea\xee\x06\x30\x49\x42\x53\x70\xdb\xc2\xe9\x43\x49\x31\xff\x89\x2c\x45\x3a\x09\x9a\x19\x7c\xa9\xda\xeb\xe2\x6d\x7a\x4e\x92\x11\x6f\xd9\xba\x40\x50\xcd\xa6\x71\x1d\xd6\x9e\xac\x0d\x19\x21\x48\x5a\x18\xb6\xcd\x06\x2a\xdd\x04\xb2\x5c\x63\x91\xc3\x14\xa5\xfe\x3e\x32\xee\xf1\x03\x04\x23\xae\x52\x7a\x3e\x39\xe3\xda\xf9\xb5\x0f\x48\x02\xc8\xfc\x2f\x1d\xa3\x66\x29\x1a\x68\xb0\xea\x3f\x3e\x25\x49\x09\xb6\xbe\xab\x93\x53\x96\xc4\x7b\x36\x6e\xea\x01\x61\x0a\x61\x3f\x2b\x2c\x35\xde\x54\x95\x1e\x4e\x77\xa0\xa9\x8d\x08\x10\x81\xb7\x2e\x75\x93\x86\x23\xd2\xda\x58\xee\xe1\x58\xb4\x16\xcb\xef\xf2\xb6\x27\xec\x65\x5c\x98\xc6\x4d\x6e\x3d\x05\xc0\xbe\xbb\x6c\x55\x0f\x4b\xf9\xb0\xa8\x3f\x07\xb0\x02\xc6\x38\x92\xc3\x6d\xe4\xe5\x36\xb7\x19\xa1\x5b\x02\x9c\x01\x86\x29\xdd\xae\x0f\x6d\x85\x80\xf1\x6d\xf1\x3c\x89\x03\x80\x73\x69\x9b\xac\x96\x21\xda\x63\xf5\x20\xcf\x13\xcc\xff\x5c\x61\xe5\x0a\xce\x81\x7b\x35\x0e\xdd\xc7\x57\x28\x63\x6e\x69\xb2\x75\xf5\x1f\x50\xed\xf2\xfc\x7c\x71\x69\x4a\x45\xa8\x3a\xda\x94\xe2\xd4\xbc\x54\xed\x62\xb2\x7c\x81\x4e\x94\x76\x35\xa8\xf6\x00\xcb\xe5\x15\x4a\x73\x0e\xfa\xb7\x53\x38\x8e\xff\x1c\xa3\x2a\xeb\xe5\xb1\x06\xdc\x2c\x80\x84\x21\xa2\xec\x49\xfc\x2c\x01\x46\x75\x03\x00\x96\xe0\x4b\x74\xc2\xda\xd8\xba\xd4\x88\x34\xae\x4a\x73\x28\x54\xbb\x39\x9e\x0e\xc3\xc5\x65\xe4\xb0\xd8\xf7\x16\x3e\x14\xc8\x19\xff\x74\xe0\x1a\x93\x2a\x4f\xe6\xc4\x7a\x9a\x38\x8c\x6c\xce\x08\x80\xce\xf1\xdd\x7a\x15\xb5\xe8\xee\x3d\x4a\x1e\xc2\x40\xcf\x04\x0c\xe5\x19\x1f\x68\x29\x3c\x56\x13\x43\x26\x62\xa2\x0c\xec\x49\xea\xa2\x05\x5b\x2d\xb7\x46\x18\xbf\x4d\x2f\x75\xf4\x34\x67\x93\x41\x13\x19\x8a\x10\x18\xeb\xf0\x0c\x77\xef\xeb\xe7\x50\x50\x35\x49\x94\xea\x3c\x28\xfe\x4d\x97\x6b\x93\xe4\xd2\xe2\xdf\x8e\xa2\x6e\xb7\x27\x00\xbd\x16\x75\xd9\x2b\xce\x98\x94\x26\x28\x19\x70\x5f\xb4\x75\xf5\x1c\x9e\x8b\x49\x85\x35\xe3\x69\x7f\x84\x3f\x65\xa9\xb4\xe4\xab\x00\x58\xaf\x87\x90\xa8\xf1\x3c\x32\x24\xb5\xc0\x9c\x67\x68\xb7\x3f\x8a\xc3\x61\xb8\x3e\x19\xa2\x2c\x87\xcc\xd6\x71\x6d\x35\xfe\x6f\xb2\x08\xc6\xd3\xce\xd0\x24\xb5\xe9\x90\x28\xb1\x45\xed\x8c\xff\xfc\x51\x66\x25\x27\xbf\x7e\xdd\x5e\x85\xbf\xe9\x14\x2f\xec\x50\x1c\x0b\xfb\x00\x3d\xde\xdf\x0d\x60\x94\xe2\x52\xb3\x3d\xa9\xcf\xea\x18\x86\x47\x16\x76\xdb\xbd\x29\x4d\x14\xcf\x47\xb2\x86\xcb\x48\xb9\x0a\xd7\xfa\x69\x35\x8f\x4c\x30\x5c\x52\x84\x83\xed\x6b\x78\x2d\x6a\xd8\x68\x28\xdb\xa2\x2d\xa0\xf9\xed\xc2\x91\x73\xf4\x6f\x98\x23\x5c\x13\xdc\x37\x84\xd6\x98\x62\x8f\x27\xb5\xc9\x23\x8e\xa5\xce\xcd\xea\xe1\x71\xfd\xb4\x79\x08\x37\x23\x97\xd6\x05\xc8\xe7\xe7\x8d\x23\x41\x5f\xf7\x98\x34\x93\x4b\x83\x5d\x82\xc5\xaf\xdd\x20\x3f\x7e\x4e\x22\xd2\x98\x4d\x39\xb9\xab\x5d\x71\x80\x45\xfb\x9b\x7d\xb5\x87\x3f\x44\x45\x04\x03\x21\x79\x7e\x77\xca\xf8\x17\x13\x63\xf4\x10\x94\x4e\x90\x97\x23\x3f\x17\x10\x9e\x46\x94\x46\x27\x89\xb6\x66\x09\x58\xac\xac\xa6\x35\x66\x03\x51\x8a\x17\x5c\x17\xcf\x2f\x6d\x1c\x45\x93\xe9\x0d\x32\x47\x40\xc5\xf6\xe1\xdb\x53\x60\x03\x1a\x50\x99\x84\xa1\x96\x83\x05\x58\x7c\x22\x39\x62\xc0\x68\xc1\x7c\x32\x58\xa8\x4b\x59\x52\x37\xce\x44\x9c\x2b\xdf\xdc\xc7\xaa\x36\x8a\x62\x4c\x06\xb1\x18\x19\x65\x41\xac\x61\xd4\x28\x30\x86\xe5\x96\x04\x83\x5d\x85\x75\xa3\xc4\xc9\xb7\x12\x86\xdd\x59\x1a\x45\x84\x11\x2f\x05\xf2\x04\xcf\xa3\x0a\x29\x8d\x22\xc1\x29\xf1\x85\xf1\x10\xe6\x06\xc4\x28\x8d\x22\xc9\xe3\x40\xfb\xb0\xe6\x4e\x13\x01\x04\x1a\xc5\xb1\x8c\x7d\x0b\xaf\x2c\xda\xe1\x8f\x99\x9d\x42\x34\x4a\x62\xcb\xd9\xf7\x4c\xae\xef\x55\xfd\xb9\x72\xb1\xff\x5c\x96\x60\xf3\x41\xb4\x2d\x1c\x4f\x28\x1c\x7a\x07\xed\x4b\x35\x4f\x09\xa5\x51\x42\x6d\xb3\x42\x68\x1d\xf0\x4b\x3b\xdb\x59\x1c\x2b\x6d\xf9\xf1\x8c\x33\xea\xb2\x5a\x2b\x45\xf8\x58\x57\xcf\xb5\x38\x7e\x66\xeb\x48\xa3\x2c\xa2\xc8\x43\xf1\x8c\xa4\x41\x2b\x84\x46\x99\x22\xbe\xc1\x79\x5d\xc3\x05\x5c\xcf\x8d\x22\x91\x05\xf9\x56\xd6\x1b\xd5\x7f\x98\xe8\x08\x53\xc0\x2e\x54\xc2\xb5\x77\xfb\x71\x79\x7f\xb4\xd7\xd0\x88\x69\xcb\xe3\xb3\x2d\xad\xd5\x4b\x35\xa0\xea\xbb\x21\x9c\x01\xd6\x87\x10\x3c\x77\xd0\x33\x01\x10\x8d\xb8\xc8\xb8\x2d\xe4\x79\x24\x3f\xea\xb3\x85\x7d\x87\x46\x79\xc4\x52\x8f\xad\xd4\xe7\x43\x7b\xa1\x98\x46\xa3\x9c\xe6\xc8\x28\x90\x78\x4f\x11\xea\x52\x40\xb8\x43\xb9\xb4\x90\x3c\x71\x84\x52\x3f\x41\x97\x8e\x85\xe6\x9b\x1b\x22\xa2\x04\x19\xa9\xfb\x17\xd1\x6c\x54\x35\x10\xbf\x47\xa8\xdb\xf8\x92\x45\x1c\x11\xeb\x00\xb4\x7e\x2b\x9a\x76\x68\x72\x36\x19\x48\xa8\x1e\x08\x2b\x58\x9e\x9a\x3b\x26\x93\x38\x71\xa1\xc1\xba\xd4\xe8\x8e\xf0\x60\x56\xe2\x78\x12\xc5\xf3\xd8\xdc\x95\x46\x52\x58\x83\xdc\x17\xa1\x7e\x2c\x34\x9c\xa6\xdf\xa3\x12\x27\x91\xfe\x02\xea\xc7\x9d\x78\x5b\xf5\xfd\xf5\xc9\x4c\x52\xcc\xe0\xad\x58\x7c\x5b\x6c\x6e\x17\xcb\xdb\x35\x3a\x87\xad\x17\x4f\xb7\x7f\xee\x37\xf7\xdf\xd6\xdb\xdd\xc3\xd3\xd6\x5f\xa2\x32\x19\x58\xab\x02\x8f\xeb\xa5\x91\x8e\x89\xf1\xe6\x2e\xdd\x34\xbf\x16\x88\x39\xfa\xfc\x75\xd4\x49\x84\x19\xd7\xb1\xd2\x85\x79\xbf\x10\xa2\xeb\xd5\x2d\x68\xa4\x33\x83\x3a\x11\x4a\x94\x57\xd5\x6b\x79\xa8\xc4\x25\x6e\x7f\x7c\x73\xb4\x50\x9e\x0b\x68\x79\x08\x93\x57\x69\xfe\x46\x80\xf3\xd1\x6b\xca\xf0\x44\x4c\x6a\x05\xe3\xbf\x4a\x18\x32\xde\x68\x64\xb2\x28\x92\x01\x0a\x85\xf8\xc6\x59\x68\x32\x8d\x0c\xe1\x2a\xed\xc1\x06\x03\x19\x64\x3f\x20\x8f\xbd\x37\xf6\x08\xba\x32\xfe\x49\x26\xcf\x31\x40\xfe\x77\x71\x38\x88\x9b\xab\xf1\xc5\x18\x99\xe7\xa1\xe7\x71\x2c\x1c\xe9\x73\xe6\x5e\xc6\x11\x44\xa9\x15\x99\x09\x7a\x25\xc3\xaf\x89\xe3\x28\x45\x15\xcb\x7f\x15\xc5\xf0\x2b\xe2\x38\xd3\x29\x75\xb5\x1f\x5b\xec\x5a\x7a\xba\x01\x8d\x63\x01\x48\x99\x12\xce\x11\x62\xd9\xa3\x19\xc6\xb7\x38\x4e\x12\x40\x83\x4b\xb7\x8d\x5b\xf7\xee\xf2\xbd\x8f\x9f\x68\x9c\x50\xae\x59\x8f\x5a\xee\xfb\x7a\x17\xe0\x8a\xf1\x95\xa7\x51\x2a\xec\xe7\xba\x10\x6e\xd3\x2c\x7e\x8a\xe2\x30\xd8\x56\xe2\x34\x62\x08\x54\x32\xc5\x9b\x6d\xa5\x3f\xd6\xd0\xed\x50\x73\x84\xc2\x6e\xb4\xea\x15\x21\x4e\x85\x5a\xb4\x16\xeb\x3d\xfe\x3d\x69\x22\x53\xde\xc7\x25\x73\xb2\x42\x23\xd7\x76\x1a\xa7\x4c\xe5\x2e\xd4\xda\x1f\xce\x13\x6e\x2f\x8d\xd3\xee\xbd\xed\x8d\xd2\xe7\xf6\x80\x70\x26\x9d\xa7\x34\x90\x53\x70\x19\x18\xa1\x02\x46\x91\x24\x8d\xb3\x38\x76\xdd\x11\x55\xfd\x84\x3a\xd4\xb3\x68\x4c\x08\xe4\xc8\xc8\x39\x9e\x0e\xd5\x3b\x80\xf5\x30\xdb\x55\xeb\xed\xc3\xe3\x78\xae\xc6\xc4\xbd\x22\x05\x02\xf8\x3f\x80\x36\xd0\x98\x18\xa6\xd2\x80\x02\xbd\xae\xea\xc7\xe5\x6e\x37\xb9\x75\x94\x10\x8c\x48\xfc\xfa\x86\x7c\xe0\xc9\xd7\xd1\xdc\xd0\x74\x64\xc6\x34\x86\xf5\x0d\x26\x36\x15\x80\x74\x0b\x67\x4d\x01\xab\x97\xe2\xf4\x79\x56\x10\xb8\x95\x34\xa6\x4a\x59\x77\x28\xbb\x99\xde\x55\x61\x2b\x8d\x59\x2c\x30\x34\x7e\x38\x79\x03\x4b\xef\x0c\x38\xbe\x54\xc6\x18\xe8\x61\x51\xed\xe1\x04\xa5\xaf\x9d\xa1\xd7\x3d\x9a\x2b\x4f\x6e\x02\x63\x52\xb8\x15\xdf\x31\xbe\x07\x70\x7f\x1a\xf3\x4c\x20\xb5\xf8\x58\x95\xed\xcb\xe1\x7d\xa8\x0b\xb5\x0a\xfd\x5e\x1a\x73\x15\x59\x8e\xdc\xfd\x62\xb5\xdb\x7c\xdb\xec\xfe\xf4\x47\xf2\x9c\x61\xb3\xb4\x16\x45\x03\x16\x26\x27\x0e\x1f\x2b\x66\xf5\x17\x26\xb8\xe5\x6a\x18\xcf\x94\xc2\xf6\x5c\xb8\x30\x21\xad\xd8\x5b\x6d\xbd\x0a\xeb\xdd\x6b\xe5\x0f\xc9\x34\x41\x55\x1b\x0f\xe2\xd9\x5d\x48\x73\x4f\xbe\x4a\x71\x1e\x79\x92\x79\xd9\x5e\xa4\xb8\xe3\xb1\x79\x94\x45\xfd\xeb\x81\x61\xdf\xfc\x14\xd4\xc4\xae\xdc\xb7\xc5\xcf\xa2\x7c\x6e\xda\xee\x8e\x15\x61\x39\xd3\xdc\xca\xc5\xec\x91\x6a\x67\x9b\x6c\x53\xfa\xf3\x45\x21\x99\xc6\x90\xe5\x99\x09\xea\x13\x93\x67\x09\x84\x23\x8a\xdc\xff\xf0\x01\xdb\x64\x76\xfe\xcd\x27\xec\x34\x06\xc6\x33\x32\x20\x8f\x4d\x79\x71\xf3\x77\x11\x04\x47\x04\x85\xb2\x90\xf1\x4b\xb9\x63\x1a\x1b\x46\x31\xe9\x68\xce\xa7\x53\x55\xb7\xcd\x65\x55\x92\x26\x51\x6c\x3d\x8f\xbb\xad\xe4\x76\xb1\x1b\x34\xaf\x69\x12\xc9\x04\xa1\x8c\x8f\x50\x8a\x7f\x9d\x45\xd9\x9e\x8f\xb7\x20\x4e\xc3\x7d\x22\x89\x33\x96\x38\xc3\xd5\xda\x62\x84\x27\x5f\x10\x0b\x03\x19\xfa\xbf\xd4\xcf\x45\xf9\x1c\xe0\xbf\x34\x89\x65\x66\xa8\x73\x24\x5b\x1c\x0e\xae\x2c\xf0\x77\x18\x25\x34\x49\x12\x89\xbd\x59\x79\x7e\xdf\x78\xd5\xec\xdf\x26\x43\x52\x5b\xf5\x7e\x86\xf6\xea\x69\x85\xd8\x8c\xe9\x08\x6e\xd7\x41\x53\x43\x40\xb1\x6e\x5a\x38\x7a\xf4\xeb\xf8\x87\x24\xc0\x6c\x2b\xdf\xc3\xa5\xfa\x6e\xff\xfd\xf9\x38\x14\xa9\xa5\x49\x9a\x58\xc1\xa9\xea\x04\xe5\xe2\xb9\x06\xe8\x05\x79\x3e\x9b\x0a\x49\xca\x62\x2c\x3b\xee\xbb\x40\xbe\x38\x74\x8b\x89\x5e\x56\x6f\x5d\x62\x1f\x56\xbe\x24\x65\x24\xa1\xbd\x2b\xfc\xa0\x52\x42\x93\x2c\xd2\xcc\xb5\x5b\xbf\x43\xb1\x29\x57\x17\x74\x4e\x9a\x64\x42\x79\x8b\x4d\xa7\x7a\xe5\xee\xdf\x25\x59\x98\x26\x44\xa7\x7e\x7f\x42\xd5\x90\x55\x55\xd5\xba\x28\xbb\xbd\x6f\x60\x98\x4b\x13\x9a\x98\xd8\x56\x06\xce\xb3\x41\x5d\xc2\x08\xa7\xd6\x9f\xf5\x80\xc8\xbd\x7b\x71\x9c\x2e\xff\x09\xcb\x35\xba\xf5\x23\x93\xaf\x4b\xf3\x7c\x0e\x99\x70\x46\xb1\x3b\xa0\x8b\x1a\x54\x7b\x05\xb2\x68\x2f\x40\xf7\x6e\x68\x1e\x59\x31\x4d\xdb\x37\x6a\xc1\xbb\x52\xda\x4a\x8a\x5d\xcc\xd1\x8b\x6f\xc6\x8c\x98\x26\xc2\xa4\x78\x03\x8b\xc6\xb9\xdc\x5e\xd0\xa6\xc6\x4f\xcc\x33\x87\x7b\x9b\x46\x51\x86\x17\x48\x4a\x20\x8e\x78\xb3\xd6\x45\x0b\x7a\x57\x9f\xa7\x97\xab\xa3\x9e\xb7\xdf\xb4\xe0\x83\xec\x44\x67\x22\xcd\x7a\x9f\x00\x57\x1a\x78\xb7\x19\x63\xcf\xc0\xa0\x89\x96\x84\xf5\x21\x96\x85\xb8\xfc\x0d\x63\x9e\xd9\x5f\x0f\x59\x8a\xd6\x3a\xaf\xa1\x19\x35\xb7\x66\x00\x49\xb1\x1c\x57\x94\xed\xf5\xb9\x54\xbf\x8d\xab\xab\xa3\xb9\x66\x20\x42\xac\xa1\xed\x85\xef\x43\xca\xe1\x2e\x3e\xed\xee\x9e\x53\x10\xfa\x5a\x22\xf9\x75\x36\x43\x4c\xa3\x5c\xe0\x86\xbd\x2d\x9a\x56\x0c\x81\x18\x34\x8d\xb4\x48\xb8\xa7\x06\x5f\x41\xf3\xc3\xea\x69\xce\xae\x1b\x69\x2c\x62\x94\x13\xf2\x40\xba\x85\x1e\x9a\xd8\xce\x7a\x16\xb9\x4f\x26\x22\x31\xe9\x40\x75\x7c\x02\xd2\x9d\x7c\x4f\x62\x18\x66\xeb\x4f\xa0\x75\xe1\x95\x09\xdf\xc7\x6f\x98\x8b\x16\xdd\x27\x52\xa5\xd3\xa4\x0f\x83\xdd\xe9\x57\x97\x1e\x17\x34\xcd\x98\x06\x2f\xb8\xe5\xf8\x68\x4e\xde\xac\x8b\x3b\xfa\xb0\x35\x9c\x9b\x30\xa2\xc1\x3d\xd6\xa2\x1c\x95\x0e\x52\x62\xac\x07\x91\xad\xa8\x5b\x6c\xf9\xa8\xc2\xea\xc6\x51\xcd\xfc\x72\x8a\x7a\x10\xa8\x19\x89\xf6\x87\x93\x81\x79\x42\x14\x9f\xfa\xba\x7f\x0c\xc3\xa7\x69\x9e\x29\xcc\x87\x6c\xd0\x10\xf4\xbe\xc7\x67\x15\x2c\xc3\xa0\x21\x98\x51\x35\x50\x3f\x4c\xc4\x79\x3f\x6f\xcf\xb8\x13\xc9\x98\x20\xe8\xe0\x24\xea\xf6\x7d\x57\x4d\xbe\x46\xf6\x65\x68\x9b\x33\x8c\x45\x71\x27\x57\x2e\x85\x42\xd4\xfd\x73\xf1\x13\x70\x75\xdc\x55\xdd\xca\xb2\x7c\x9f\x34\x41\xfc\x70\x0d\x88\x91\xbe\x5b\xfc\xb1\xff\xb6\xb8\xfd\x1a\xde\x02\x45\x99\x4a\xbc\x0f\x54\xab\x5e\x30\xcc\xf1\xc7\x04\x49\xbc\xa8\x6b\xd5\x34\x85\x3c\xc0\x5d\x25\x9b\xdf\xc6\x11\x6d\xaa\xc0\x8a\xb8\x9d\x6a\x28\xcf\xa7\x7e\xcf\xf1\x87\x8d\xf0\x66\xb0\x4e\x63\xda\x91\xba\x3e\xa4\x02\xd2\x2e\xdd\x40\xb7\x04\x7f\xcb\xff\x46\xf1\x2c\xd5\x92\x63\xbe\x70\x12\xef\x03\x40\xd5\xc5\x66\xde\xef\x0b\xa9\xd6\xc2\xca\xc6\x58\x68\xcb\xf2\x42\x4c\x83\xa6\x10\x4b\xe6\xb3\x7b\x5b\x16\x1a\x96\x7f\xc2\x2d\x00\x96\xd9\x92\x8c\x05\x0c\x58\xb2\xd3\xb8\x16\x99\x82\x4a\xf0\x3e\xdc\xad\xaf\x36\x8b\xfd\xf6\xeb\xe3\xe3\xc3\xd3\xce\xab\xaf\xf9\x41\x26\x23\x18\x74\xde\x56\xcf\xcb\x5f\xeb\x15\xd9\x0f\x65\x11\xb3\xca\x70\x37\xb5\x98\x4d\x58\xb2\xc8\x70\x6c\xa5\x3d\x2e\xfe\x5c\xdd\xae\x7b\xf8\x2d\xcd\xba\xe8\x34\xb1\xf2\x7d\xf5\x19\xf4\x55\xf1\x73\x3c\x2b\xb3\x24\x4f\x30\x6b\xb0\x9d\xef\x2b\xf1\x3f\xb8\x51\x4d\xae\x32\x65\x60\xe5\x94\x47\xbe\x53\x63\x85\x63\x9a\xa5\xd2\xca\x6d\xb5\x43\x32\xe9\xfc\x09\xb3\x0c\xf2\x78\x6e\x92\x0c\x2a\xc9\x34\x23\x79\x1c\x7b\x96\xea\xee\xa5\xae\x5e\x1b\x1f\x6f\xdd\x57\xad\xff\xcf\x41\xee\x9e\x11\x19\xcc\x8d\xef\xde\x51\xdd\xc7\xf2\x69\x3c\x46\x93\x66\x34\xb5\x4e\x0f\x1e\x7d\x17\x5c\x72\x70\xa9\xc9\xdc\x28\x16\xc5\xca\xf5\x07\x56\x2f\x1e\xd4\xe0\xd7\xc5\x8c\x65\x1a\x6f\x3c\x6e\x9a\x1b\x3d\x51\xb1\xa6\x19\x63\x69\xea\xdf\x4b\x84\xfd\xf8\xa2\xc0\xec\x0b\x93\x31\x19\xa3\xb6\xf8\xb6\xad\xea\x8f\x0d\x28\x47\xf1\x43\xc6\x0c\x45\xc0\xcf\x57\x7b\xd4\x65\x5d\xe3\xf3\xe6\x91\x41\xd6\x6d\xb7\xed\x78\xfc\x0d\xcd\x84\x88\x30\x04\x5e\xec\xee\x2e\x59\x3a\x34\x13\x26\x03\xf0\x75\xd7\x3a\x70\x5c\x3f\xad\x19\x64\x2a\x03\xa9\x9c\xf7\xc2\x15\xfc\xfc\x59\x39\x6f\x52\xff\x9d\x4a\x31\x67\x9e\x86\xf0\x76\x68\x96\xef\x0e\xe9\x3e\x5d\xb0\x33\xa5\xd9\x00\x78\x68\x55\xa0\x2f\x5c\xde\x68\xa6\x8c\x42\xe0\x1d\x96\x2d\x37\x4d\x97\x44\xfb\x2f\xd3\x99\xc6\xd2\xd4\xfe\xe8\x99\xb1\xe1\x88\x20\xe0\xa0\x35\xcb\xc5\xe2\xeb\x45\x2f\x7f\x7c\x25\x5a\xd0\xcc\x31\xdb\xac\xf0\x5b\x97\x6f\x3c\x77\x69\xff\x27\xe6\x61\x34\xd3\x4a\xc6\xcc\xa5\x27\xf3\x0c\xc0\x0f\xdf\xb9\x51\xf5\x66\x3e\xd4\xcf\xb4\xd6\x5e\x5c\xb9\xcb\x39\x9a\x51\x57\x91\x66\x26\x33\xb6\xba\x25\x5a\x58\x3c\xf7\x7f\x26\x5a\x59\x5d\x75\x05\xdd\x03\x3d\x14\x7f\x81\x5e\xab\xaa\xac\x8e\xef\x61\x0c\x65\x78\x77\xba\xbd\xdc\xa3\x1d\xc6\x77\xc4\x40\x82\xc0\xab\xcd\x5b\x51\x16\xe7\xa3\xa3\x3d\x0c\xf2\x65\x12\x25\x42\x45\x9e\x1a\xd7\xcd\xfc\xed\xa0\xd0\x39\xbe\x51\x04\x4d\xb4\x9d\xf9\x24\x80\x46\xbd\xde\x25\x84\xd8\x9d\x44\xd2\x1a\x48\xc9\xf3\xa1\x8b\x9a\xa6\xdb\x22\x89\x79\x86\x88\x44\x5f\xfb\x9f\xd4\xc0\xdc\xa8\x84\x58\xe4\xb0\x12\xa5\xa7\x4e\xf8\x2f\x48\x34\xc3\x76\xa8\x79\x0b\x26\x0e\x94\xa4\xd4\xea\xd2\xc8\xf3\xfb\xf2\xc7\xf3\xa2\x5d\xbf\xa9\x97\xe7\xbf\xb7\x96\x93\x4c\x59\xd2\xa9\x12\xa5\x45\x7f\x7c\xf0\xcb\x33\x23\xb1\x46\xdb\xed\xff\x1f\x53\xac\x28\x21\x89\x71\x01\x73\xf1\xb1\xfc\xc2\xf8\xe7\x12\x45\xb8\x2b\x12\x87\x04\x77\xdc\x38\x9f\x7c\x07\x4d\x08\xb3\xb2\x2b\x3b\xa8\x8f\xbd\x3e\x2b\x25\x54\xeb\x28\xf1\xba\x27\x83\x54\x68\x72\x83\x19\x51\xd8\xfb\x77\x35\xb1\xef\x00\xe1\x06\x33\xe7\x43\xde\xdb\x16\x9d\x6c\x74\x74\xb1\x0d\x5d\xd6\x50\x08\x33\x36\xa7\x30\x88\x0c\xde\xa8\x0f\x0a\x38\x84\x8b\x0c\x43\x2f\x8c\xae\xbf\x88\xe6\xc5\x0b\x34\xfa\xe3\x92\x20\x07\x12\xf5\xd4\x50\x86\xd8\x21\xbb\x86\x01\x08\xc9\xf3\x04\xab\x8c\xaf\x50\x3c\x42\x7d\x37\x02\x6d\x53\xd2\x2d\xd0\xdd\xb5\x1c\xe6\x79\xc0\xdc\x0f\x4b\xe3\xd4\xc5\xfa\x57\xa2\x15\xab\xea\x70\x10\xfb\xc5\x62\x1f\x25\xe3\x2f\x53\x54\x7a\x13\xbe\x5b\xf8\x09\x87\x89\xb5\xf2\xe4\x09\x69\xb0\x7c\x90\x63\x51\x16\x55\x69\xdf\xcc\xc9\x33\xd0\x60\xdb\xc4\xba\xae\x4e\xf7\xa0\x5a\x51\x5f\xbc\x2d\xda\x44\x96\x43\x6e\x7d\xa0\xaa\x12\xa3\xf5\xdd\x4c\xda\x77\x1e\xe7\x65\x1f\x2d\x52\x33\xe0\x25\x4a\x80\xa4\x74\x50\x20\xdd\x15\xfd\xdb\x06\x2a\x41\x70\xc0\xde\x6b\xe0\x06\x20\x52\x77\xcc\x26\x13\xe8\xac\xbb\x7b\xad\xae\xac\x28\xbc\x3f\x6c\x98\xc8\x79\x6f\x31\x6d\x85\x9b\x07\x9c\x74\x4a\x8c\xd2\xc6\x0c\x71\xf9\x45\x55\xee\x5e\xea\x69\x0f\x85\x18\x48\x30\x8e\x79\x01\xeb\xec\x7a\x28\xca\xc9\x10\x1a\x49\x2e\x93\x10\x34\x41\xfb\x32\x45\xf8\x53\x1a\xcb\xc4\x7b\xff\xa3\x44\xca\xe3\xea\xf7\xc9\x49\x62\x93\xb8\x55\xda\x56\x99\x71\xd8\xfd\xf9\xe8\xe2\xa6\xff\x97\xb9\xc7\x42\x93\x88\x6b\xf0\x45\x4d\x2b\x46\xee\x05\xd5\xc6\xdf\x99\xc4\x56\x81\x70\xf1\xef\xf5\xfa\x0e\xa3\xc0\xf3\x87\xa0\x11\xda\xbd\xd4\xd8\xb2\xf5\x6b\xe3\x50\x68\xd2\x0d\x49\x5d\x3f\x59\x9d\x9b\xb6\x3a\x06\x5e\x7e\x77\x40\xf9\xd2\xde\x3d\xbc\x8e\xb2\x3e\x9a\x72\x40\x24\xf1\x47\x9a\xcf\x7e\x9b\xa2\x59\x44\x91\x78\x7b\x5b\x55\xed\xda\xca\xc8\xf8\xca\x03\x25\x22\xa2\xbd\x2b\xc4\xd4\xbb\xe6\xd3\x25\x96\x12\xc5\x51\x3a\x57\x57\x53\x31\x70\x37\x80\xc6\x42\xea\x80\xd6\xf6\x7f\x4c\xa9\x16\x03\xb2\x15\x5e\xd1\x83\x71\x16\x64\x03\x83\x55\x4a\xa9\xb0\x43\x1b\x68\xbf\x96\x07\x14\x17\x86\x45\xa9\xaf\x61\x62\xba\x4c\x29\x55\x91\x97\x18\xf6\x1d\x91\x2e\x01\x5b\xbe\xdf\x8b\xe3\x48\xc2\x9c\x52\x96\x0a\xac\x92\x3f\x1c\x4b\x68\x66\x93\x4f\x37\x90\x1b\x8a\x9e\x07\x07\x71\x94\x55\xb3\x3b\x97\xa3\x32\x1d\x15\x82\x20\x55\x1f\xe7\xe6\xaa\xfa\x01\xa3\xf2\xe4\xa8\x30\x40\x85\x31\x3c\x75\x38\xaa\xf8\x09\x5c\x49\xe6\xc9\xa9\xac\x84\x3f\xa0\x1a\xaf\xf7\x8e\xa7\x54\x46\x29\x52\xa2\x3d\x39\x33\x8d\xdc\x83\x8d\xfe\x31\xfe\xd7\x3f\xe8\x6e\xcd\xa3\xbd\x43\xd4\xf6\xac\x14\x34\x8d\x39\x1f\x26\x13\x42\x6a\x85\x85\xbe\x5b\x78\x86\x52\xef\x9f\xaa\xf7\x21\x73\xf4\x23\xa2\x10\xa5\xd2\xc4\x16\x67\xdc\x05\x7a\x37\x95\x98\xd4\x89\xa9\xca\x33\x84\x8b\x1d\x8b\x72\xf7\xd6\x93\xbb\x29\x55\x3a\xc1\x10\xde\xce\x32\xe4\x16\xa1\x14\xcf\xc0\x50\x63\xba\xe2\x8d\x9f\xaf\x32\x04\xc9\x01\x3f\xc5\xf9\xd0\x5a\x9a\xba\xa8\xdf\xbf\x96\x16\xf2\xee\xbf\x46\x67\x56\xcc\x4c\x89\xc3\x01\xbd\x89\xad\xce\x5a\x38\xcc\xa8\xe9\xbd\xa5\xc6\xc0\xe3\xc9\xf7\x41\x66\xfd\x72\x7b\x44\xb5\x06\xb1\x3c\xcf\x6b\x63\x77\xc3\x15\xc6\xf1\x96\xbb\xdb\x05\xa7\x9f\x82\xbf\x29\x35\x5c\x60\x89\x72\x8f\x02\x8e\x65\x09\xaa\x75\x64\x1e\x3f\x40\x73\x6c\x0f\x0b\xdf\x11\x75\xc6\x40\xa3\x1b\xce\xa2\x28\xc1\xca\x65\xaf\x8f\x5b\x94\xcf\xa1\xfc\x1d\xbe\x8e\xc5\xa9\x4a\x1d\x7b\xf6\xed\x7d\x72\x8e\x84\x13\xdf\xca\x76\x6e\x4a\xab\xc7\x21\x77\x89\xb2\x44\xd9\x5f\x67\xd3\x80\xbb\xa2\xf4\x7d\x14\xfe\xff\x62\xc2\xdc\xea\xc9\x52\xc5\xa5\xad\xa2\xfe\x1b\xea\x49\x4d\x86\x65\x8c\x22\xb1\xd6\x4e\xe5\x41\x25\x9c\x65\xdc\x20\x3c\x78\x5f\xa3\x0d\xcf\x6f\xfe\xcf\x39\x43\x58\xf0\x6d\xf5\xec\x63\x27\xbb\xcb\xf8\x4e\xde\xf8\x07\x66\x46\x63\x87\x42\xfc\x84\x32\x48\xe2\x51\x46\x94\x8c\x3c\xb1\x69\x59\x55\x87\xf0\x77\xc8\xad\xc4\x98\xcb\x81\x36\x8d\x5b\x7e\xfc\x00\x2a\x84\x76\x0c\x1b\x2b\xbc\xe5\x16\xe6\xde\x95\x28\xe6\x7e\xa8\xd4\x78\x77\x3c\x15\x7b\x18\xac\x30\x16\x47\x58\xf2\x42\xb8\xce\xea\x20\x5e\xbb\xac\xcc\xb2\x48\xc2\x45\xb2\x44\x4a\xbb\x3c\x3f\x6f\x83\xbc\x62\x31\x75\x71\x74\x83\x79\x64\x55\xe4\x4e\x35\x6c\x54\x35\x54\x10\xa4\x8c\x67\xd2\x1a\xcc\x2c\xfe\xf8\xbe\xb9\xdf\x17\xe5\xee\xcb\xc3\xd7\xed\xe2\xfe\x6a\xf7\xc5\x55\x47\xb6\x61\x28\x93\xb9\x2b\xc7\x7c\x11\x07\x73\x5b\x18\x5b\x45\x1a\xdf\x55\xae\x12\x6e\xa3\xce\x16\xbc\xf7\xf5\x79\x04\xc7\x75\x03\xf3\x28\x45\x34\x89\xaf\x39\x67\xbf\x85\x03\x14\x9f\xae\xa5\x6d\x43\x5d\x85\x19\xce\xf2\x38\x47\xe1\x80\x25\xd4\xf5\xfb\xad\x97\x68\xe9\x8f\x1a\xac\x40\x42\xd9\x42\x3d\x14\xfc\x9c\x7e\x33\xcd\x45\xea\x4c\xcc\x92\x05\x7a\x27\xf4\x90\x23\x26\x62\xf0\x9a\x80\xb6\x2a\x6a\x3b\xb5\xe3\xb9\x29\x9c\xe5\xdc\x4d\x55\xa9\x17\x2f\x9c\xf2\xe9\x42\xc8\x04\x95\xd8\xb8\x3e\xbe\x3f\x0d\x7e\x91\xe0\xd6\x6a\xd0\x87\xd8\xe0\xc2\xba\xa1\xa9\xcd\xe4\xab\x35\x73\x1e\x11\xa6\x5b\xd8\xb0\x70\xd6\xf4\x2e\x8b\xdd\x00\x40\x66\x0a\xf2\x33\xb6\x00\xba\x47\xac\xb8\x11\x2a\xd1\x58\x58\x43\x02\xeb\xc4\x41\x83\x32\x65\x62\x9e\x0c\x62\x1f\x47\xb9\xb3\x84\xec\x49\x47\x9d\x41\x44\xc1\x7b\x28\x21\x57\xd3\x15\x4e\x47\x3f\x1d\x54\x84\x80\xc2\x3f\x7e\x28\xbf\xee\x32\x00\xc0\xba\x72\x0b\x47\xa7\x7a\xe3\xf2\xbf\x89\xa5\x02\x65\x46\x51\xcb\xb8\xb4\x3b\xef\xbc\x42\xbf\x1d\xcb\xa3\x84\xc6\xa9\x7b\x79\xaf\xab\x7a\x65\xf5\x8f\x1a\x9c\x0c\xa3\x49\xc0\xa3\xcc\x36\xbe\x7b\x85\x22\x24\x39\xcd\x2e\xbd\x3c\xd2\xc4\x01\xd5\x4e\x07\xa1\xc0\xf9\x76\x8f\xaf\x93\xc7\x02\xd0\x6a\xec\x7a\xf1\xb4\x1b\x94\xf9\x78\xac\x04\xba\x80\x1d\x8b\x03\x34\x6d\x35\x0e\x09\x78\xda\x45\xcf\x36\x5f\x45\xd9\x37\xbf\x68\x4c\x56\x2b\x9e\x32\x62\x3d\xe7\xec\xba\xbd\x7c\x9f\x99\x96\x3c\xd5\x84\x8a\x81\xd3\x48\x30\x88\x2f\xaa\x71\x29\x85\xa7\x5a\xa1\x85\xc3\x48\x03\x72\xf3\x61\x4d\x3d\x7c\xca\x68\x9f\x9d\x22\xf8\xd8\x14\x50\x37\xab\x0b\x62\x1d\xe5\x59\x6c\xb5\xe7\x02\x01\x68\xe3\x2d\x8c\x47\x85\x3a\x9e\x11\xe9\x99\xfd\xfe\x2a\x16\xb2\x38\x14\xed\xc0\xbe\xb5\x1b\xa5\xac\x5f\x59\xf5\x6c\x2b\x4a\x35\xa6\x51\xe2\x83\x37\x9c\x67\x2a\xb6\x51\x66\xa0\xf9\x8e\xcd\x64\xe6\x3f\x45\x12\x2b\x7f\x7d\x53\x8b\xe6\xb4\x3d\x8a\xda\x76\x7c\xf0\x05\x47\x79\x7e\x3f\x4e\x5a\x3d\x94\x21\xfa\x71\xf9\x6e\xd1\x70\x1f\x34\xa0\xba\xcf\x24\x56\x7d\x4c\x34\xaa\x0b\xb7\xdd\xdf\x29\x33\xb8\xa9\x0b\xab\x21\xb5\x08\x7f\xd7\x8a\x3b\x8b\xa2\xfb\xf5\xf7\xbf\x8b\x7a\x77\x1f\x66\x69\x16\x3b\xb4\x89\xaa\xaa\x83\x3e\x3b\xe1\x42\x1f\xcc\x71\x26\x25\xde\xcf\xa0\x15\x2a\xea\x0b\x9d\x50\xca\x79\x6c\x74\xec\x3d\xb1\x1b\x7b\xef\x6e\xa0\xbd\x5c\xf4\x39\xcf\x62\x2f\x86\x75\x0f\xa0\xbb\x9b\x35\xd0\xce\xe9\x8e\xdb\x95\xd9\x51\x88\x92\xf0\x77\x2a\xac\x28\xfc\xb9\x7e\x38\x41\xb9\x1c\x52\x01\xbb\xa3\x06\xc1\xd7\x87\xea\x19\xc3\xcd\x0f\xcc\xbb\x29\xe7\x32\x4e\x6d\x9d\x42\x15\xa7\x02\x82\x80\x2a\xe5\x1c\x94\x53\x0e\x84\x42\x55\x8b\x32\x68\xd9\xd9\xb7\x61\x92\x12\xf0\x3c\x33\xd8\xb8\xf5\x32\x48\xfe\x34\xb9\x8e\x30\x3d\x6d\x8b\x23\xec\xaa\x20\xb9\xe7\x0f\x0b\x61\x64\xf7\xf3\xee\xe1\xb4\x1e\xc1\x07\xb9\x80\x08\x27\xe2\xd5\x62\xb7\xde\xdf\x6e\xee\x36\xbb\xfe\x88\x94\x43\xca\xbb\xd7\x83\xf9\xc7\x79\x76\xa1\xe5\x92\xa5\x38\xe9\x8e\xe2\x2d\xd0\xbc\x29\x97\x4a\x73\xaf\x82\x70\xb9\xc6\xa9\x28\x66\x4e\xc3\x43\xd9\xb8\xf7\x83\x65\x53\x71\xc0\xfa\xc8\x0d\xb4\xb7\xa2\xd4\x28\x55\xee\x0f\xe5\x14\xa1\xff\x57\xb5\x78\xf5\x02\xb9\xe3\x6f\xd1\x24\xa5\xe9\x60\x23\xdf\xcb\xe2\xcd\x7f\x1a\x44\x22\x5c\xe2\x76\x2b\x5e\xdf\xfb\x4a\xfa\xe8\x14\x79\x14\x89\xcc\x9a\xfb\x0e\xcc\xa0\xbb\x3f\x2b\xac\xfd\x75\xc1\xe1\x63\x55\xfe\x55\x84\x03\xa9\x6d\x54\x54\x5d\x56\x50\x94\xcf\x5e\x38\xf8\x83\x37\xbb\x1b\x8f\xa0\x99\x9b\x6f\xeb\x70\x0a\x66\x1d\xf1\xe4\xf0\xb6\xf8\x63\xb9\x41\xd4\x90\x05\xc0\xcf\x09\x83\xd3\x3c\xd6\x11\x2a\x73\x0f\xab\x39\xff\x18\x44\xc0\x79\x12\x13\x94\x30\x2d\x54\x85\x5a\x59\x76\xc6\xf9\x28\x27\x4f\x62\x81\xce\x2d\xce\x71\xc5\x47\x59\x79\x9a\x31\x92\xfa\x3b\x56\x3e\x9f\xc5\xb3\xdd\x2f\x3c\xef\x9f\xe6\xa9\x8c\x85\x0b\x50\x87\x3b\x49\x9e\x02\x45\xba\x6a\x3b\x28\x1a\x5e\x57\x75\xc8\xb3\xc3\x30\xa0\xe0\xb5\x11\xa6\x9b\x7f\x9e\x71\xa7\xea\x5b\x16\xe1\x2d\xca\x33\x1d\x4b\x08\x90\xcb\x61\xb1\x3e\xcf\x4c\xae\xdd\x9b\xff\xaf\xf6\xfd\x9b\x6d\xca\x54\xa1\x18\x91\xd3\x98\x60\x41\xe9\x6a\xf1\xf0\xcb\x45\x6c\xfc\x10\x28\xcd\x10\xc7\xe8\x0c\xf0\xbb\x1c\x60\x6f\x89\x8a\xed\xcb\x97\xa2\x6c\xef\xe1\xad\x5d\xb4\x8f\x95\x0b\x7b\xfd\xa7\xa4\x48\xb2\x40\x74\xda\xa1\x66\x4d\x33\xd3\x96\xcb\x29\x58\xcf\xcf\xa7\xcd\xea\x4b\xaf\x84\xf4\x8b\x96\xb2\xfb\x2c\x17\xb6\x73\xad\xc1\x2a\x69\x7e\x87\xe2\x49\x20\xf3\x72\x3c\x2e\x8f\x6d\x06\xba\x47\x7b\x29\x34\x71\xb1\xb1\xd8\x10\x2f\x3e\x39\x77\x9e\x2a\x6c\x0c\x21\x27\xac\xf6\x7e\x80\x98\xc6\x3c\xc1\x51\x14\x3d\x2b\x8b\xe6\x39\xcf\x70\x8a\xe1\x5e\xf5\xad\x7a\xbd\x30\xf6\x98\xd4\xfa\x3e\xf8\xf3\xdf\xfe\xc7\x7f\xad\x8e\x58\x2f\x93\x72\x27\xde\xbe\x79\xf7\x7f\x9a\xe7\x26\x46\xbf\xfa\xdb\xe2\xf9\xa5\x1d\x29\xc2\xd3\x5c\x24\xc0\xd2\x41\xac\x6b\xb3\x57\x2b\x8d\x36\x69\x23\xe5\x82\xe6\xd6\x66\xbc\xd0\x1a\x74\xa1\x7c\x5f\x3c\x97\x84\xe4\x56\x96\x1c\xc9\xfe\xbb\x97\xba\x3a\x3f\xbf\x3c\x94\x70\x5d\xd5\x3f\xc2\xa0\x3c\xc1\x06\xde\xea\x05\xca\x3f\x0a\xe1\xa5\x4e\x3e\xa9\xb8\xe5\x52\xe7\x58\x66\x0e\xa6\xca\x73\xe6\x36\x34\x57\x39\xd3\x58\x98\x2b\x9f\xe1\xd0\xec\xbb\xc5\x63\xaf\xc5\x7b\x98\xef\xca\x98\x34\xf3\x0d\xcc\x63\x55\x23\x3b\xcb\x1d\xd3\x54\x23\xb5\x5d\x1d\xaa\x06\x2e\x4d\x69\x68\xae\x73\xab\x3c\xd2\xbc\x54\xaf\xb6\x01\xf1\x49\x77\x21\x07\x02\x24\x88\x7c\xc2\xba\xe9\x22\xd9\x5f\x62\x22\xe6\x27\x34\xe4\x1a\x8b\x30\xbe\xdc\xd8\x3d\x13\x59\x83\x08\x37\xd4\x10\xc3\x7c\x47\xb4\x28\x01\xf5\x1f\x07\xbe\x7c\x34\x37\x2c\xc3\x70\xfa\x2f\xa5\xfa\x3f\x01\x27\xde\xae\x0d\xe0\x47\x63\x5d\x36\x90\xee\xe0\x3f\x27\x22\x21\x71\x83\x04\xcb\x37\x6c\x1e\xa1\x1e\x98\xba\x50\x91\x64\x34\x8b\xbc\x77\xe2\x5b\xfb\x58\xb5\xfd\x11\xab\x35\x19\x1c\x94\xfc\x81\x34\xb5\x96\x0d\xcb\xcd\xee\xe1\x8f\x5f\xb5\x5d\x3e\xbf\x31\x22\xa5\xc2\xa7\x37\x5f\x1b\xa8\xbb\xcc\x6d\x92\x8f\x89\x8c\x32\x5c\x76\x4f\x67\xd9\x2d\x21\x57\x20\x34\x56\xa5\xfd\xe1\x3c\x35\x36\x75\xd0\x00\x73\x8e\xc1\x61\x9c\x51\xe0\x45\x11\xac\x91\x58\x98\x39\x82\xa4\x36\x9e\x0d\x65\xdb\x70\x80\x13\x70\x6a\xfa\x1b\xc7\x57\x0d\x5c\xc0\xf4\xff\xfe\xdf\xff\x7d\xbe\x90\x09\xa2\x24\x6a\x00\x82\xaa\x9a\xf7\xa6\x85\xe3\x18\x36\x21\x88\x89\x90\xe3\xd4\x14\xcf\xa5\x03\xfd\x8c\x4f\x40\x13\x8e\x42\x3b\x27\xa1\x7e\x0c\x8a\x77\x82\x2a\xab\xfc\x6d\xb5\x22\xaf\x8a\x9f\x85\x1e\x58\x9a\xba\x41\x2c\xb3\xef\x38\x4a\xac\x3f\x7f\x2f\xca\xc1\xd3\xe5\x31\x41\x7c\xc1\x1e\x31\x81\x7b\xdc\xd3\xf6\x8f\x5e\x45\x99\x0a\x4e\xac\x50\x96\x53\x45\xb4\x8e\x63\x3a\x48\x7d\x51\xc1\xa9\x5d\x7b\x1f\x97\xbb\xdd\x75\x55\xdf\x88\xf0\xa3\xb8\xe1\xb8\xc5\x89\x2e\xd4\xf0\x7b\x9c\xc8\x89\xc4\xb7\x49\x1e\x84\xfd\x5f\x38\xc0\x0d\xae\x68\xdd\xbc\xdf\x63\x42\x10\x8e\x38\x8f\x6c\xbb\x0e\x76\xbb\xe8\xbc\x3e\x16\x15\xb9\x8e\xd1\xd9\xb2\xdb\x3e\x6b\x51\x34\x45\xf9\x3c\x9d\x27\x22\x8b\xb0\xdc\x5b\xa8\xea\x3b\xc0\x8f\xd8\x02\x62\xfc\x41\x65\x59\x70\xcb\xba\xfa\xe1\x14\x57\xe7\xfb\x87\x42\x92\xdc\xeb\x08\x6e\xcf\xb2\xac\xb4\x6b\xe4\x4f\xd1\xd6\x93\x4f\x89\x08\xe2\x41\x7d\xdd\x29\xd2\xb9\xa3\x2a\x26\x68\xfc\xa2\xc4\xc9\x16\x8f\x26\xb3\x44\x25\x63\x9d\x8c\xe5\xb9\x6d\xc3\x8e\x2c\x14\xe1\x78\x97\x4e\x5d\xd2\x86\x64\xf8\x6e\xf7\x03\xfd\x28\x8a\x81\xa8\xc7\xa8\xd8\x2c\xb4\xb4\xe6\x5f\x5e\xaa\xda\xd7\xe7\xd7\x6f\x6d\x2d\xe6\x08\x9f\xe1\x93\x90\x67\xb6\x6a\xee\x9a\x9d\xc8\xd2\x0a\x57\x0a\x26\xa6\x2e\x1c\xf5\x82\xf4\xbd\xa2\xe5\xfc\x0d\x05\x43\x51\x4e\x65\xdf\xe3\xdc\x3f\x62\x69\xa2\xc7\x3c\x19\x78\xd2\x17\x7f\xc1\xea\x5c\xff\x84\x0f\xb0\xee\x3e\xb6\x17\x26\x55\xcc\xdb\x3c\x94\xf0\x66\x45\x57\xf6\x35\x28\xd1\xb4\x7b\x53\x57\xc7\x7d\xd1\xc2\x71\x7a\x16\xff\x61\x96\xe1\xdc\x40\xb1\x91\xa6\x5d\x38\xe3\xf9\xe3\x54\x05\x90\xca\x88\x24\x96\x4c\x27\x0c\x7c\x1f\xfb\x40\xf9\x11\x79\x3c\xaa\xc9\x7d\x96\x2e\xcb\x48\x59\xe5\x52\x2f\x62\x0c\xa5\x82\x61\x27\x69\x7c\x9d\x32\xa6\x56\xe3\xeb\x64\x9d\x5d\xbd\xad\xbb\xef\x77\xc8\x58\x66\xd6\x78\xa8\xd4\x41\x8d\xc7\x5f\x57\x0c\x06\xbd\x45\x4e\xe7\xe6\x05\x93\x93\xe1\xd6\x2d\x13\xae\xa0\x37\xc0\xf5\x8b\x0d\x56\x53\x5e\x40\xfd\x38\x75\x1b\xce\x87\x90\xb4\xe9\xdf\x47\x3f\x31\x91\x96\x6c\x72\x12\xef\xdb\xf6\x3d\x54\xed\x64\x02\x14\x35\x5e\x6e\xec\xea\xd3\x0c\x3c\x55\xa8\x4c\x0c\x24\x16\xd1\xe9\xc2\x35\x7b\x17\x87\xb1\xba\x4c\x8c\x85\xf6\x28\x51\xa2\x1a\xdc\xb4\x0d\x26\x53\xa9\xb4\x7b\x23\x37\x27\xe3\x29\x29\xe3\x9e\x8c\xcc\x54\x8a\xdc\xc0\xc5\x72\xf5\x49\x23\xd8\x0d\x26\xa9\x55\x15\xf9\xe7\xaa\x2a\xca\xbf\xfc\x85\x10\x46\x23\x97\x40\xae\x26\xfe\xc1\x0e\x24\x3e\x24\xaa\x48\x22\x74\xcc\x7b\x72\xd1\xfb\x2c\x98\x5a\x12\x99\xc4\xae\x75\x70\xaa\x1a\x98\x12\xba\xfc\x28\x13\x25\xda\x65\xa7\x41\x00\x76\x76\xfd\x94\x94\x72\x0c\xb8\xbb\x97\xc3\x99\xc3\xee\x1c\xfc\x69\xe3\x75\xa3\xa8\x64\x91\xc1\x0a\x3d\x6a\x86\x6f\x37\x37\x43\x57\x55\x2a\x59\x62\x3d\x96\x9b\x50\xd8\x99\x53\x57\xa5\x92\xb1\x9c\x05\x47\xad\x40\xc3\xe9\x8b\xf8\xe1\xee\xf3\xc4\xf6\x63\x34\xf8\x80\x76\x8b\x62\x18\x41\x4f\xd2\xa7\x82\x92\x77\x89\x40\xb7\x7c\x2f\x97\xfe\x6a\x38\x58\xf7\x31\x2b\xec\x3f\x98\xa7\xee\x78\x4e\x25\xd6\x85\xbf\x54\x87\x6a\xfb\xbf\x18\xa8\x8d\x7f\x8c\x88\x78\xde\x6b\xe7\x7c\x07\xd9\x14\x97\x2b\xdd\x28\x10\x96\x22\xc9\x3d\xaf\x79\x1b\x20\x50\x4e\x54\x6c\x1e\x0a\xea\x3e\x28\x63\x8e\xd8\xa1\x7b\x78\x5d\xd5\xbd\x78\xab\xff\x45\x52\x82\x17\xab\xec\x42\xa9\x25\xb4\x3d\xee\x6e\x7e\x33\x93\x8a\x01\xe2\x67\xac\xcf\xac\x0d\x70\xc6\xea\x28\x54\x2a\xb0\x68\xb1\x06\xda\xbd\xf3\xf9\xde\x8b\x5a\x16\x6d\xb3\x6f\x2f\xb9\x1f\x52\x99\x08\x1b\xeb\xf6\x86\xf4\xe9\xef\x78\x94\x66\x42\xa8\xb0\x8b\xea\xc2\x7a\xb1\x5d\x38\xbf\x53\x09\xdc\x5a\xe5\xef\xd1\xdb\x7c\x53\xfe\x2c\xa6\x58\xc8\xfe\xa4\x00\x09\x66\xd1\x2b\x51\xb7\xef\xbd\xae\xe0\x27\x49\x89\x8a\x62\x42\x62\x4f\xfd\xab\x8e\x57\xe5\x58\xce\xcb\x4f\x30\x15\x81\x05\x49\xf9\x75\x7b\x28\x2e\x4e\x55\x1c\xa5\x58\x7b\xf4\x92\x0c\xff\x0b\x6e\xba\xdb\xfb\x11\xdc\x78\xb3\xbb\x0d\xe7\x63\x0a\x99\x9b\x68\x69\x79\x0b\xe5\x73\xfb\x82\xe0\xce\x70\x9c\x53\x0c\xc0\x5b\xf1\x03\xfa\xde\xc3\xec\x9b\xad\x62\x2e\x50\xb5\x69\xf5\x2e\xa1\xfe\x06\xc5\x07\xd0\xee\xd9\x3b\xaa\x62\x19\xd9\xb4\x45\x23\x1d\x27\x98\xb2\x53\x15\x6b\x63\x2b\x5f\x68\x46\x89\x14\xf4\xf3\x71\x44\xfb\x56\x09\x25\x58\x00\xf8\xb6\x59\xad\x1e\x86\x45\x3b\x95\x30\x2b\xed\xfa\xe5\xa8\x82\xb3\x7c\xe0\xf8\xa8\x44\x12\x6c\x4b\x4a\xb0\x14\x9a\xf0\x77\x13\x91\xc8\x3b\xd2\x96\x7a\x57\x6d\xbb\x6d\x16\xe3\x25\xa7\xf4\x3b\x75\x50\xa7\x2a\xed\x1e\x1c\xee\xdd\xdf\xd6\x7f\xe0\x35\xac\x9f\x56\x49\x92\xfa\x73\xa6\x26\x4e\x99\x2f\x06\x35\xed\xfd\x13\x20\x0c\x1a\xe1\x97\x3f\x0b\x05\xae\x4b\x30\x6a\xf7\xa9\x8c\xa8\x44\x78\x4f\x6b\x74\xfc\x0f\x12\x0f\x13\xa4\xd6\xc7\xe8\x2d\x95\xf1\x18\x97\x70\xbb\x13\x7c\xbf\x7d\xbc\xec\x02\x2b\x22\x73\xac\xcf\xfe\x51\x88\xea\xee\xbc\x2c\x44\xd5\x5d\x7d\xe4\x2f\x9e\x2a\x2b\x3f\x75\x14\x4d\xe3\x94\xfb\x2f\x41\x97\xe1\x0b\x19\xc4\x48\x38\xda\xc2\x4f\x28\xb7\xad\x28\xb5\xa8\xf5\xec\x1b\x72\xd9\x5b\x53\x3c\xb2\x24\xc0\xda\x82\xdb\x17\xb2\xc1\x35\x02\x3f\xbe\x9f\x7f\x1d\x15\xcf\x29\x6a\x01\x3b\xce\xe2\x3c\x86\xca\xff\xdb\xbf\xf2\x8a\x1b\x83\x04\x50\xdb\x87\xf1\x36\xc6\x41\x02\xe2\xba\xae\x8e\x17\x2c\xf7\xf0\x2b\xf3\xd8\xb6\xc5\x9f\x7d\x85\x54\x89\x24\xc6\x4c\x49\x57\xee\xa5\x1d\x5f\xa5\xa0\x56\x48\x6d\x53\xea\xaa\x11\x93\x88\x4e\x89\xdc\x6a\xed\xe0\x3a\xb6\xbf\x87\xd7\xbe\xdf\x3a\x38\x85\x49\x31\x47\x84\x2e\x78\xbe\x72\xe6\x8f\x93\x31\x32\x02\x14\xb3\xb1\xcb\xe2\x62\x7a\x0a\x99\x59\xb5\xc0\x06\x4a\xed\xbd\x53\xdc\x21\x15\xc5\xd2\x2d\x95\xcb\xf3\x3b\x0a\x76\x35\xdd\x62\xb9\x3c\x4d\xea\xc4\x4a\x25\x91\xab\xd2\xff\xac\x7e\xc0\x75\x17\xcd\xc3\xf1\x34\x54\x0f\x0c\x03\x95\x76\x12\x73\x55\xad\xb7\xd5\xc1\xbe\xde\xd3\xd3\xd1\x14\xab\x49\xb6\xb9\xdf\x6d\x29\x98\x1d\x74\xe1\x61\x3a\x9f\x56\x28\xa5\x13\x74\x93\xc0\x37\x63\x2c\x68\xec\x46\xe8\xcc\x7a\xff\x3c\x9d\xe5\xa1\x78\x1b\x4f\xbf\xf1\x45\x9a\x24\x41\xa0\x8d\xaf\xdf\x77\xe1\xe6\x80\xf3\xff\x77\xb1\xc2\xf6\x6c\x3a\x8a\x24\x56\xf7\x75\x05\xcd\xc3\x6b\x39\x45\x36\xfb\x51\x59\xc4\xc0\xd3\x52\x4b\x30\x85\x2a\x44\xfd\x7e\x5d\x94\xbd\x88\x0f\xd5\x91\x96\xc8\x08\xa9\xd1\x5c\xa8\x2a\xe1\xfd\xeb\x69\x57\x7d\x7f\xa9\x0e\x70\x5d\x94\x25\xbc\xaf\x27\x0c\x6d\x1d\x67\xb6\x52\xfd\x0c\xad\x83\x04\x77\xd1\xce\x75\x85\x64\x9b\xf1\xb3\xd1\x31\x63\x18\xb4\xed\xbe\x3f\x6c\x2a\xdf\xcc\xe8\xfe\xaa\x9c\x89\xd7\x63\x55\x1d\x16\xc7\x36\x1c\xc9\x35\xe5\xbd\xe8\x41\x17\xec\x8a\x43\xd0\x9a\xec\x8e\x83\x4c\xfb\xfd\x78\x44\x2c\xfa\x9c\x0b\xaa\x53\xc6\x63\x0b\x8f\x1f\x33\xc3\x74\x96\x25\xd8\xde\x46\x11\x38\x54\x8d\x9d\xfc\x60\xc2\xad\xbd\xc0\x51\xbc\x3d\x5a\x4a\xd1\x6f\xe1\x88\xb1\xca\xb1\x07\x51\x1c\x17\x36\x89\xe8\x36\xd4\x5f\x6d\x48\x93\x4b\xa3\x44\x60\xe0\xe2\xc8\x2d\xd3\x2a\xbb\xee\x32\x2d\xe4\x84\xb8\xbe\xc5\x98\x8e\x36\x3d\x37\x4e\x06\xff\x49\x20\x71\xda\xe3\xe6\x7f\xff\x73\x35\x9f\xb7\x6a\x9e\x26\xb9\x53\x0d\xe8\x5e\x89\x7d\xcc\x46\x49\x53\x77\x1c\x41\x10\x88\x32\xc1\x0b\x9c\x44\x56\x9a\x53\xab\x57\xe1\x67\xf8\xef\x03\x94\x9f\x1b\x92\xc7\xe0\xa5\xf8\xd7\x6f\xd5\xe9\x20\xca\x29\x5b\x5a\xe7\xcc\xc2\x31\xad\x5d\xcf\x15\x9c\x44\xdd\x9e\x6b\xb8\x2d\x26\x78\x23\x2d\xd2\x14\x09\x91\x6e\x7d\xb9\xf4\x5b\xf6\xe3\x8c\x50\xee\x87\xdd\xd4\xf0\x3e\x43\x54\xd4\x32\x4d\xc1\x15\x61\xbf\x55\xc8\x56\x08\x25\xb5\x51\xce\xa9\x25\x17\xc6\x3a\xb8\x76\xeb\xf7\x8c\xa7\x2d\xd5\x8a\x68\xe4\x33\x60\x30\x69\x13\x73\x68\x7d\xfb\x56\x2b\x9e\x67\xf9\x85\xf9\x63\x37\x8d\x67\x96\x2c\xad\x34\xc1\x0d\x73\xb5\xd8\x21\x31\xd2\x9f\x45\x67\xb9\x57\x27\x53\x70\x09\x03\xfb\xd5\xff\x1f\xfe\xfb\x01\xed\x40\x1b\xaa\x70\x1f\x29\x1c\x30\xca\x73\xf5\x07\xc0\x11\x88\xa3\x04\xc9\x96\x1f\x78\xc5\xff\xdd\xd4\x63\x3c\x11\x21\xa6\x22\xa5\x43\x48\x31\x04\x33\x77\x0a\x71\xce\xb0\x28\x80\xe9\x98\x1a\x62\x3e\x21\x49\x13\xe5\x1e\xe2\xed\x59\xfd\x78\xc7\x46\xdd\x26\xf4\x94\x21\x21\x11\x8f\x7b\xed\xa3\xd9\xb5\x7a\x4a\xbe\xf9\xc7\x0c\xd5\x19\x12\x43\x54\x3c\x30\x64\xbb\xec\x6f\x43\x1a\x5b\x33\xdf\xeb\xc5\xfd\xdf\x76\xcd\xf0\x1f\xcd\x62\x62\xd5\x48\x0e\xed\x00\x38\xef\x8f\x0a\xe6\x35\x11\xf0\x1d\x2c\xca\xe7\x2d\x80\xbe\x18\xa6\x59\x20\x24\x39\x42\x93\x3b\x92\x25\x16\x95\xb6\x7f\x45\xfd\xce\x7f\x8a\x2e\x8f\x9c\xbc\x83\x90\xa5\x91\xe9\xbd\xaa\xe0\xd4\x7a\x99\x87\x70\x33\x33\x4e\x52\xde\x83\x8a\x3c\x19\xb3\x3f\xae\x53\xef\x86\xb9\xad\x4c\xbb\x12\xa7\x27\x10\x2a\xe8\x7d\x53\x20\x29\x10\xe5\xb9\xa9\xe7\xd2\x69\x6f\xf6\x47\x6d\xb9\xe3\xf5\xa5\x50\x2f\xa8\x3e\xbd\x69\x76\x2f\x45\x38\x3d\x31\xb6\x55\x80\x4a\xa5\xa1\x61\x79\x9e\x4a\x3a\xf2\x99\xd8\x0f\x68\x6a\xd0\xfa\xc2\xb6\x08\x67\xbc\x48\x28\xd0\x2c\xc7\x72\x4d\xbf\xef\x00\xcb\x09\xf0\xe0\x8c\x34\x65\x47\xcd\xae\x3c\xc0\x24\x11\x16\x88\x64\x65\xdb\x2f\xd6\x43\xe0\xa9\x95\x19\xf4\x75\x54\xdf\x7f\x0c\x87\x21\xf1\xc2\xd6\x7f\x2f\xc5\x01\x9e\x45\xb8\xc2\x06\xb9\x11\x14\x5c\x6e\xda\x42\x7d\x50\x2b\x81\x3c\xd6\x08\xb6\x7a\x7a\xf0\xea\x20\x90\xe7\x06\xfc\xf7\xae\xc3\xe2\x05\x22\x56\x5e\x60\x7c\xd1\x65\xcc\x16\xb7\x7e\x0d\xf0\x08\xf5\x3f\xcf\x17\xdb\x26\x88\x24\x47\xba\x6a\x59\xb5\xeb\xff\x9e\xc5\xe1\xb7\x90\x3d\x84\xff\x18\xdd\x76\x19\x29\xfc\xb9\x21\xb1\x89\xf6\xed\x50\x60\x78\xee\x51\x49\x2a\x54\x30\x7c\x7e\xb4\x98\xe4\x1b\xd1\xc2\x6b\xc8\xed\x40\xf2\x18\x15\xaf\x5e\xb0\x71\xb8\xde\x7d\x99\x3c\x04\x09\x56\x99\xb9\x28\x95\xe5\x30\xdd\x54\x95\x7e\x82\x0f\x68\x4c\xa0\x62\x8a\xf3\x47\x59\x13\xbd\xc9\xc9\x14\x4d\xac\x34\x81\x78\xb7\xd0\xac\x8f\xce\xc2\xad\x8c\x50\x03\xed\xca\x3b\x77\x8c\x56\x60\x50\x39\x65\x32\x14\x33\xbe\x9c\xe4\x7d\xa5\x61\x96\x30\x0c\x2a\x97\x68\x5c\xb3\xde\x7d\xd9\x3f\x3e\x6d\x56\xeb\x7d\x10\xa6\xa4\xa0\x04\x41\xad\x88\x73\xf9\x22\x0e\xe8\x30\xec\x0f\x28\xa5\xa4\xe3\x78\x3e\x42\xdd\x54\xa5\x38\x2c\x3e\xd1\xec\xa5\xa0\xa9\x75\xfd\x0a\x0a\x24\x5d\xf2\x32\x09\x03\xba\x41\xe8\x85\xd2\x05\xfe\x35\x28\xd1\xc2\x4a\xb4\xf0\x5c\x4d\x68\xed\xfd\xad\xd0\x4a\x63\x0b\xfe\x45\x20\x52\x00\xf4\xc3\x41\x63\x41\x68\x52\x69\x03\x48\xad\xb0\x2d\x5a\xdc\x20\x7d\x0c\xcd\x7e\x06\x60\x05\x80\x2c\xc7\x18\x0f\xd7\x8c\x3b\x81\x4c\x53\x7f\x48\x48\xd1\x7b\x55\x5e\xa3\x4f\x4b\x39\x38\x6e\x48\x8a\x95\x85\x6e\x57\x6e\x5a\x27\x6f\xec\x8f\x71\x82\xa0\x16\x68\x5f\x9e\xe0\x50\x80\x09\x07\x34\x60\xa2\x83\x65\x0b\x5f\xb7\xfc\x40\xef\x9d\x9a\x38\x8e\xb1\x02\xf8\xb4\xbe\x5e\x3f\x3d\x2d\x6e\xf7\xcb\x87\xfb\xaf\xdb\xfd\xed\xfa\xdb\xfa\xd6\x37\x96\x4c\x9c\xda\xbd\x03\xa5\x27\x87\x45\x60\x93\x48\x5b\xaf\xc4\xe8\x49\xcd\x30\xfe\x4d\x9a\xc6\x68\xa3\x88\x9a\xa5\x63\xef\xb7\xee\xa0\x80\xc4\x33\x1d\xba\x30\x4e\x4f\x21\xb9\xc3\x6d\xce\xa4\x54\x61\x94\xff\x02\x87\xd3\xb2\x2f\xe9\x9a\xd4\x28\xac\x0b\xdf\x89\x53\xa5\x26\xdf\x9f\xb1\x08\x0b\xcc\x1e\x27\x66\xbd\xdc\xc7\xcb\x82\xc9\x64\x9c\xf4\x82\xc7\x3b\x28\xc5\xb4\xf3\x60\x32\xc3\x74\xaf\x28\x79\x55\x3c\x17\xad\x38\x2c\xea\xf6\x43\xf4\xb9\x21\x4c\xe8\x20\x68\x02\x3f\x46\x5d\x4f\x43\xd3\x1c\x41\xf9\x6d\x01\x75\x3a\xf9\x2a\x4a\x23\x2f\x92\xe0\x08\x39\x43\x6d\x1b\x43\xb9\x89\x7b\x76\x10\x02\xfe\x97\xe7\xf7\xfb\xf3\x07\xdd\x15\x43\x73\x8e\x51\x86\xaa\xab\xa6\x9b\x64\x88\x6b\x1b\xa7\xc0\x86\x45\x09\x46\xf3\xa2\x6c\x5e\xa7\x19\xa5\x61\x99\x44\x61\x57\x14\xb9\x40\x10\x64\x19\xd0\x12\x86\x81\x05\x7b\x9c\x6a\xd8\xac\x1e\x86\x2d\x3f\xc3\x4c\x6a\x5c\xae\x87\x4b\xe7\xa3\x78\x9d\x50\x8a\x0c\x0f\xd4\x85\xf2\x09\xbb\xcb\x5f\x77\x7f\x3c\x8c\x7f\x47\x12\x0d\x36\xce\x49\x2e\x61\xb8\x50\xd8\x5b\x3f\x22\x1b\x74\xa0\x77\xed\x8e\x0b\x67\xbe\x7f\x27\x9a\x91\xaa\x92\x11\xb9\x36\x56\x93\xb0\x79\xf1\x00\x9c\x66\xa0\x10\x4a\xb3\xff\xf7\x7f\xf6\x9b\x7c\xa4\x6d\x04\x48\x09\x5e\xbf\xb4\x3a\x56\xbb\xca\xd9\x2a\x8d\xb2\x12\x23\x0d\x8d\xa8\xaf\x26\xd4\xb8\x17\x75\xcb\xd7\xf8\x77\xeb\xc8\xae\xd8\xfe\xa5\x09\xf3\x42\x13\x6b\x7f\x27\xcf\x75\x89\x99\x6f\x38\xa0\x01\x3b\x94\x28\x03\xd7\xff\x0d\x11\xb0\x4d\x5b\x9f\x55\x97\x92\xec\x7f\x8a\xba\x10\x65\xbb\x77\xa6\x3d\x96\xc5\x35\x78\x83\x34\x58\x31\xa9\xa7\xf5\xbf\xbe\x6e\x9e\xd6\x57\xd6\xd7\x77\xbb\xdf\x3d\xec\x97\xeb\xfd\xf2\x61\xf1\x74\xb5\xbf\x5b\xdf\x2d\x43\xcf\xc1\xa0\x30\xbf\x0b\x2d\xf1\x09\xd9\x66\xca\x6c\x0d\xc0\x40\xa4\x90\x08\x69\x09\x93\x77\x1e\x2d\x3c\xbe\x41\x10\x1b\xed\x2a\x82\x8f\x42\xfd\x10\xcf\x80\x6c\xa5\xf1\xa4\x85\x24\xc1\x49\x6e\x6f\xcf\x77\x51\xcc\xd4\xb8\x8d\xe1\x76\xf1\xff\x67\xf5\x3e\xcc\x9e\x8d\x51\xe0\x01\x68\xf8\xf7\x41\xff\x87\x45\x51\x62\x30\x64\x50\xa2\xdc\x34\xcd\x79\x7c\x4e\x16\x45\xd4\x42\x9d\x6d\x27\x0e\x1f\x74\xaf\x42\xcd\xa2\x98\x1a\xea\xd4\x28\x1e\x1f\x1e\x6e\xf7\xa0\x8b\x76\x9f\x90\x70\x58\x0b\x2c\x18\xa2\xe4\xb2\xcf\x06\xe6\xb6\x5b\x16\x25\xa9\xc0\x78\xd5\x16\x0c\xbe\x14\xcd\x1c\xf4\x76\xf2\x99\xb4\x5b\x89\x9d\x2a\xcf\xdb\xa9\x18\xb3\xf4\xa6\x63\x8d\xf1\xed\x37\x74\x5e\x07\x6d\x51\xf0\x50\x5b\x79\xb7\xf0\x93\x32\x4e\x84\x93\xfa\xb9\x39\x54\x52\x1c\x1e\xbb\xf7\x7c\xb4\x26\xb1\x28\xcb\x33\xc4\x76\x60\x0a\x83\xc0\xd8\x4d\x39\xc1\xeb\xcc\x4d\x09\x16\x91\x8c\x68\x3b\xd3\xdb\x2e\x64\x1c\x3e\x65\x16\x11\xce\x23\xeb\x20\x61\xcb\x1f\x3d\x44\x99\x45\x34\x51\xa6\x7b\x4e\xb6\x71\x11\xfe\x4a\x73\xac\x04\xba\x6e\xce\x60\x5f\x1b\x9f\x99\xa5\x0c\xb7\xac\xbd\x9f\x03\x01\x4c\xe8\xdd\x6a\x7f\xbb\x28\x8c\xb2\x88\x71\x96\x2a\xbf\xf2\x5a\x2c\xca\x50\xb7\xcd\x8f\x12\xb1\x7f\xc3\xbb\xad\x6a\xdd\xbe\xec\xaa\x71\xee\x36\x7e\x12\x3c\xa6\x26\x1e\x54\x21\x76\x20\x8e\xf1\x27\x7d\x69\x16\x71\xc2\x91\xf7\x8f\x8d\x3e\x8f\x03\x68\x26\x33\x35\x27\x96\x7c\x8e\xf9\xca\xc1\xa3\x66\xe2\x7f\x8c\xfe\xf1\x63\x75\x1c\xfb\x45\xc9\x2b\x26\xbb\x3a\xfd\xf8\xb7\xe5\xda\xa0\xa2\x1b\x32\xce\x26\x3c\x06\x16\x09\xce\x79\xdf\x7a\xb2\xdc\xac\x59\xb2\x28\x8b\x04\x38\x4b\x5f\x7c\x8f\x7c\x44\x86\xbf\xfa\x7b\xd1\xbe\xd8\x1d\x6d\xa6\xcb\xcb\x22\x99\xc7\x38\x71\x7f\x56\x43\x43\xbd\x51\x1d\x7b\xfa\x09\x95\x61\x8c\xb1\x77\xee\xd4\x5f\xcb\xe2\xbf\x67\x28\x3f\xd2\x38\xea\x3e\x40\x70\xde\x6d\xcf\xa7\x1a\x8e\x9b\x87\xdd\x65\x09\x86\x45\x12\x08\x66\xac\xcb\xed\xda\xcf\x3e\x15\x65\xd2\x35\xb3\x86\x71\x26\xfa\x80\x8d\x3f\xac\x52\x95\xb8\xf2\x19\x1a\xd0\xd9\xca\xf8\x00\x7b\xc3\x22\xc5\x19\x6e\x41\xd6\xc0\x71\xd0\x77\x60\x91\x12\x26\xb5\xf5\x6e\x17\x91\x58\xe4\xe5\xc7\x50\x3a\x16\x29\x13\x29\xeb\xf2\x14\x14\x74\xae\xcf\x87\xc3\xbb\x55\xc8\x9c\xbc\x77\x26\x02\xac\xac\xe1\xfa\x34\xa0\xa4\x84\x35\xc1\x10\x4b\x2f\x56\x22\x94\x59\xfa\x43\x0a\x8b\x5c\x18\x0d\xf8\x3a\x8b\x3f\xc6\x12\x74\x9f\xdb\xf7\xe8\x91\x9b\xb0\x5f\x75\x87\xf3\xc4\xd9\x0a\x96\x7a\xf9\x7e\x65\x33\xf5\x2e\x46\x55\x2f\x70\x21\xec\xf1\x81\x21\x72\xbf\xfd\xb3\xc8\x68\x99\x7b\xe5\x53\xf1\x03\x3b\xb2\x1f\xd6\x4f\x46\xcf\x27\x8e\xd3\x9c\xba\x95\xb4\x5f\xc7\xd3\xe1\x46\xc5\xe2\x24\xe2\x98\x38\xd9\x29\x7c\x8d\x70\x50\xe7\x5e\xf1\x8b\x3a\x92\x3f\x41\x6c\x5d\xaf\xf7\x35\xfc\xf7\x5c\xd4\xb0\x2c\xb4\xee\x15\xeb\x67\x9f\x63\x9c\xe4\x80\x3d\x9d\x6d\x71\x3c\x1d\xba\xb5\x65\x29\x4a\x3f\x65\xe2\x34\x55\x28\x6b\xf8\x65\x35\xd8\xef\x58\x9c\x66\x92\x07\x1b\xb5\xe6\x1e\x40\x83\xde\x55\x37\xdd\xfe\xfa\xde\x47\x43\x2c\x4e\x09\x73\xc4\xe4\x52\x1d\xce\x1a\x82\x5e\xf3\xf8\x12\xb2\xc4\x9a\x6b\x3c\x3e\xad\xf7\x68\x07\x76\xb7\xf8\x63\xbf\x5a\x3c\xfa\xd3\x64\x59\x86\x61\x87\x13\xdc\x9c\xf5\xcf\x61\x71\x46\x19\xea\xdb\x9f\x1b\xa8\x9f\x44\xf9\x63\x84\xb8\x62\x71\xa6\x28\x42\x4c\x44\x59\x75\xb3\x3a\x68\xe0\xb8\xc3\x24\xd5\xa9\x0c\x55\xa5\x76\xe8\x0f\xe0\x47\x50\x8e\xca\xed\xe6\x50\x9c\xb6\xaf\x45\xab\x5e\x76\x55\xdf\xd7\x66\x31\x91\x11\xe6\xd0\x65\x75\xfe\xd9\x6d\xb1\x8f\xbd\xf7\xc8\xf8\xe7\x12\x50\x88\x77\x5d\x97\xdd\x44\x6f\x41\x6f\x5f\x06\xe9\xe6\xc7\x4d\xb5\x49\xd6\xc8\x62\x9a\x53\x18\xf6\x53\xae\x17\x9b\xab\xed\x87\xfd\x42\x16\x33\x93\x5a\x13\xf9\xa2\x41\xd4\xf9\x23\xd4\x3f\xb0\x90\xe3\x88\x14\x69\xf2\x7f\x83\xf4\x87\xc5\xb9\x13\x34\x74\x8a\x74\xab\xc5\xe3\x3e\xe4\xce\x2c\x16\x84\x5a\x58\xaf\xf6\x02\xa8\x33\xd8\x08\x16\x0b\x46\xb0\xcf\xbe\x5c\xef\x16\xfe\xa3\x92\x59\x54\xf3\xf5\x47\x3a\x17\xb3\x85\x41\x16\x4b\x61\xac\x2f\x50\x11\x9e\x9b\xd4\x11\xb3\x8e\x6b\xc7\x6a\x72\x9f\xa5\x36\x38\xfb\x1e\x0f\xe2\xbd\x0f\xc5\x59\xac\xa2\x14\xb7\xd3\xa0\x82\xec\xbc\x46\x3c\x6f\x95\xc5\x8a\x5b\x0a\x4a\x23\x8a\x6f\xd5\x9b\xff\xab\x16\x16\x07\x81\x65\xed\x25\x1c\x04\x3a\xde\x6b\x7f\x18\x62\x6d\xd5\xcb\xeb\x4a\x41\xd3\xb8\xb6\xd0\xa7\xec\x30\x16\x43\x2e\x50\x91\x60\x60\xae\x38\x67\xd9\xe1\x47\x83\xed\xfc\xb8\xd2\x67\x17\xc6\x7a\xab\xd0\x8f\x0b\x44\x2c\x36\x42\x51\x17\x99\x2d\x0e\x87\x3b\xb4\x46\x0c\x85\x4a\x16\x1b\xc8\x65\x2f\x5c\xbc\x29\xb1\xac\xe0\x0e\x26\x51\x92\xf9\xf8\xd3\xd1\x96\x1f\xe4\x7f\x86\x50\x1d\x96\x44\x39\xe0\xdd\x0a\x2a\x93\x17\xdc\x00\x3f\xd0\x28\xc6\x43\x1b\xf8\xe1\xa2\xe5\xeb\x86\xc5\x54\x7a\xe5\x82\xee\x82\x5c\xe4\x65\x3b\x0d\x77\xe2\x34\xf9\xa9\xfe\x43\xdc\xd2\x8d\xe4\x19\x9f\x75\xf3\x0b\x15\x1b\xff\x29\xc7\x93\x44\xe5\xa7\xe3\xa9\x85\x7d\x92\x8f\xd6\xe4\x24\x89\x62\x0f\x4e\x5f\x42\x6b\xc5\x0e\x6c\x47\x6e\x3c\xdb\x92\xc4\x81\xec\x51\x33\xbf\x6c\xaf\x0f\xa2\xbd\x12\x85\x97\xeb\x60\x49\x16\xe7\x76\x87\x73\x29\xbf\x38\x4e\x45\x36\x58\x92\x65\x1c\x7b\x2b\xc7\x02\x95\x3a\x30\xb9\x1d\xe6\x12\x09\xa1\x31\xb3\x1d\x7f\x55\x95\x1a\x85\x54\x7a\xb1\x63\x96\x90\x5c\x47\x21\x1b\xb8\x11\xcd\x20\x8d\x67\x09\x01\x9e\x0f\xcd\x75\xba\xd4\xfc\x52\x0a\x97\x25\x34\x12\x59\xea\x34\x53\x61\x77\x21\xe0\xe5\x77\xc5\x2e\x2a\x1a\x6c\x8d\x09\xa5\x31\x96\x9d\x4a\x68\x5f\xab\xfa\x87\xb3\x83\xb7\xfa\x08\xbd\x6c\x09\x4b\x98\xd0\x38\x87\x0f\xa2\x69\xf7\x72\x68\xa6\xc2\x12\xae\x09\x78\x31\x19\xd7\x74\x07\x3d\x92\x7c\x9a\x7f\x8c\x79\x6a\x41\x7d\x0f\xdf\xef\xf7\x3f\x8a\x83\x7f\x8f\x93\x3c\x95\x28\x28\x7e\x14\x6f\x28\xb3\x92\x2c\xac\x0a\x7b\x51\x95\x8f\x50\x07\xf4\xb7\x1f\xcd\x13\xcc\x78\x6f\xec\x16\xe0\xdf\x8f\x44\xa6\xc6\x36\xac\x46\x91\xe5\xdf\x6d\x6f\x4e\x2e\x55\xf2\x04\xf7\xba\x6f\x8b\xc7\xb5\x2c\x06\x5f\x92\x2b\x04\xe1\x2e\xde\x8a\x2e\x34\x63\x49\xbc\x14\x0d\xac\x4b\x94\xcb\x0d\xba\x30\x38\x0e\xb3\x94\x46\xbd\xc0\x51\x8c\xc3\xac\x44\x6a\x29\xdd\x23\xde\x22\x0a\xaf\x99\xd3\xc9\x60\x89\x06\x66\xd2\x8b\x16\xdc\x65\xfb\x8d\x25\x90\x70\xe5\x0a\x66\xab\xa7\x3b\x51\x8a\xe7\x8b\xf9\x02\x59\x1a\xd9\x3e\x08\x32\xdd\x1e\xcc\x4c\x3f\x81\x25\x20\x68\x6c\x5f\x8f\xb6\x7e\x0f\xda\x53\x2c\x8d\x22\x62\x5c\x41\x66\x37\x94\xd0\x9b\xdd\x00\xd2\x28\xcb\x52\x87\xfa\xfd\xbd\x38\x1c\xc2\xe2\x9b\x46\x22\xc5\xdd\xfd\x13\x49\xfc\xd9\xe7\x91\xc6\x2c\xc6\x74\xf1\x16\x44\x03\xcb\xe2\x70\xb8\x08\xb5\x86\x3f\x23\x4d\x98\x2d\x5f\xca\xf3\xfb\xbe\x7d\x71\x20\xfb\x31\xc6\x94\xa5\x29\x85\x94\x04\xf7\x31\xd0\x2b\x71\xf2\xcf\x39\x4d\x25\xe7\x7c\xd0\x39\x6b\x16\xaa\x2d\x26\xe2\x46\x2c\xcd\x12\xcb\x47\xf7\xfe\x66\x16\x13\xd5\xe5\x31\xb8\xa6\x60\x7e\xed\xcf\x98\x11\x7b\x07\x97\x45\x7b\x35\xd0\xdb\xfb\x9f\xa6\x65\xca\x28\x0b\x1e\xbb\xb6\xc3\x79\xb1\x3a\xa5\xdd\x5b\x66\x7b\x39\xf7\x55\x8b\xe2\x13\x73\x77\x28\xcf\x34\x92\x08\xba\x15\xae\xcf\xb1\xe7\x1f\x67\xae\x34\xc6\xe7\x6d\x83\x1a\x2a\xa0\xfb\x07\x2a\x53\x89\xc9\x8a\xfb\x00\x62\x4f\xbe\x15\x87\x83\x78\x9e\xd4\xc4\x59\x2a\x33\x9b\x04\x1c\x8b\xb2\xfd\xd5\x53\x9f\xfc\x6c\xa5\x88\x75\xe3\x81\x57\x8f\x2b\x98\x06\x62\xbf\xea\x24\x0f\xd6\xc0\x54\x13\x83\x93\xc9\x13\x15\x6c\x0d\xe2\x83\xb6\x3c\x4b\x75\x6e\xe5\x78\x7d\xfc\x26\xec\x54\x70\x47\x21\x36\x88\x36\x78\x2e\x7e\x82\x12\xa5\x7e\x37\xb5\xd7\xed\x60\x29\x68\x08\xb0\x9c\x2e\xbb\x77\x3b\xf2\x3f\x2e\xff\xf1\x2f\x7d\x6a\x52\x7b\x9b\xee\xc4\x51\xb4\x7f\x0f\x25\xc6\xb2\x38\x8b\x5c\xbf\x4b\x9d\x6b\x98\x40\xd2\xc6\x3f\x27\x8b\x89\x15\x28\x76\x47\x1f\x0c\x7e\xc9\xd7\x06\xf4\xa2\xb1\xa9\xbb\x63\x72\xb2\x2c\xd6\x2a\x86\x29\x68\xde\xbe\x45\x7c\x3e\x52\xca\x92\x48\x64\xb1\x6b\xc8\x8d\x45\x5a\x26\x03\xbb\x9c\x25\xfb\x5f\xa5\x96\x2e\x51\x6b\x2c\xcb\x94\xed\x78\xb8\x6e\xf9\x97\xe2\xd4\xf7\x52\x58\x46\x54\x8c\x81\x11\x76\x62\x1e\xeb\xaa\x8f\x8c\x33\x1a\xdb\x54\xc3\xe2\x37\xee\xc4\xdb\x6c\xc8\x92\x51\x69\x90\xef\x2f\xcf\x56\xb6\x13\x1b\x32\x7e\x16\x8e\x7f\x13\x8b\x25\x62\xc8\xfb\x30\xd1\x89\xed\x7d\x3a\xbd\x33\x26\x24\x42\x73\xc6\x46\x95\x9f\x02\x71\x58\xc6\x20\x43\x7f\xe5\xd7\x53\xf8\xad\x3c\x17\xd8\xa9\xc3\xc8\xf7\xba\x28\xc5\x01\xb7\xd3\xfe\xb0\xc9\x13\x6f\x38\xd5\x54\x4e\x9b\xa5\x8b\x5c\x26\x3f\x43\xc4\xd6\x7b\x09\xc1\x64\x8b\xe7\x4f\xc2\xe3\x7f\x4c\x3f\x68\xe1\xb1\x27\x8b\x0a\x4d\xfc\x37\xcb\xd8\x92\xb0\xbd\xad\x79\x83\xde\xf3\xfb\x70\x98\x24\x28\x2f\x71\xb0\x18\xd0\x65\xa1\xc3\x11\x15\x47\xce\xb4\x72\x98\xd9\x66\x2a\xe2\x58\x08\x79\x7c\xb8\xab\xaa\xaa\x1a\xfc\x3d\x07\x4b\x0b\x6f\xc5\xa1\x7a\x0e\x7f\x76\x80\x0b\x57\x9f\x12\x2d\x3c\x1e\xc4\x65\xb6\xee\xde\xaf\xd1\x2e\x91\x29\x16\x23\x41\xa3\x8b\x6b\xc6\x42\xde\xe3\x55\x32\x53\x39\x45\x24\x80\xfd\x12\xac\xc9\xcc\xf8\x02\xb2\x4c\x09\x45\x55\x3f\x5f\xef\x8a\x12\xea\x6b\x6b\xc6\x88\x45\x91\xf1\x59\xbd\x0a\xc9\x5e\x68\x7d\x7b\x1e\x2c\xd1\xe3\x93\x42\x64\xbc\x93\xca\x9d\x78\xb3\x1e\x80\x5d\x3c\x12\xa2\xcb\xc9\x70\x9a\xe0\x82\x2a\x0f\x8e\x4e\xf2\x67\x75\xae\x1b\x38\x18\x7f\xc7\x80\xe7\x8e\xb6\x7e\x3c\x89\xf2\x7d\x86\x1c\xc5\x32\x13\x09\x7c\x7f\xac\xa0\x60\xd9\x62\x2d\x72\xfe\xde\x18\x65\x50\xfc\x76\x8f\x75\xe2\xdf\xe1\xfd\x82\x37\x34\xba\x3e\x12\xc5\x11\x4b\x03\x15\xb6\xa8\xca\x1b\xaf\x5e\x3d\x23\xe9\xcf\x48\x1c\x05\xbe\xce\x12\x6f\xc0\xf8\xe7\x92\x98\x2b\x1e\xaa\xd4\x2f\xa2\x79\x99\xe8\xe2\x32\x92\x70\x1e\x8b\x91\x63\xc5\xec\x7d\x26\x29\x8d\x2c\xbe\xae\xfa\x09\x36\x30\xd8\x55\x63\xd9\x16\x3f\x90\x09\xa4\x0f\x22\x23\x16\x33\xad\x9e\x31\xc0\x48\x9a\x47\x48\xc9\xbd\xad\x9e\x7d\x78\x6b\x9f\x19\x7c\xb0\x5c\x92\x54\x18\x4c\xe3\x6b\xa7\x9e\x83\x05\x8b\x0f\x99\xcc\x8c\xa4\x2a\x8d\x94\xe5\x90\xda\xd6\xf6\xe4\xfa\xb2\x24\xa5\xda\x53\xed\x9d\x2d\x18\x04\x47\x9d\xee\x38\xc1\x8c\x77\xd9\xdd\xf4\xf2\x67\xf3\x04\xe2\x70\x27\x74\x1d\xde\x4d\x92\xd1\x98\x39\x07\xec\x7e\xbd\x25\x59\xce\xd1\xd6\xc0\xd6\xa9\x56\x2f\x41\x02\xea\xd7\x85\x13\xff\x34\x33\x60\xe8\x42\x52\xa8\xca\xb8\xec\xdc\x1d\x21\x91\x25\x2c\x8a\x1a\x16\x07\xef\x5b\x7a\x7f\x3e\x8c\x15\xdd\x18\xa1\x91\x41\x28\xe1\x10\xc1\xea\x33\xf0\x4f\x02\x03\x42\x0d\xe1\xc6\x27\x36\xc6\x14\xea\x7c\x68\xdf\x17\xcd\x75\xf1\x06\xd6\xcb\x0c\xe9\x96\x47\x98\x48\xd8\x30\xc2\xe2\xd8\xd7\xdc\xa1\xd4\x3a\x20\xcf\x18\xe1\x59\x84\xc0\x38\xeb\xe1\xb6\x37\xbd\x76\x08\x23\x9c\x12\x8f\x03\xbb\x43\x3a\xd5\x77\x51\x5f\x81\xe8\xb9\x93\x8c\x70\x66\xa3\x8b\xdf\x8b\xa6\xb9\xfb\xb4\x7c\x40\x38\x8f\x91\x05\xe4\x3b\xda\xee\x7d\x19\x5f\x28\x17\x39\x62\x7b\x9b\x13\xa8\x42\x1c\x6c\x5f\x76\x3c\x33\x72\x91\x12\x57\x86\x58\xad\xbe\xb8\x0a\xa8\x2f\x41\x13\x91\x4a\xc2\x7a\x3c\xba\xde\xcd\x8b\x9f\x32\x22\x94\xb5\x75\x7c\x16\x4d\x00\xcd\x32\x22\x63\x81\x55\x62\x9b\x17\x6d\xc2\x64\x92\x52\x21\xc9\xfa\x69\xbd\x5d\x3f\x7d\x5b\x5f\xed\x5d\x31\x6b\xb7\xf9\xd7\xe3\x66\xb7\xdf\x3e\xdc\x7e\xdd\x6d\x1e\xee\xb7\x61\xbc\x61\x38\xf9\x5a\x0c\x5f\x5b\xdf\x77\x66\x44\x45\x99\xb0\xfa\x38\x96\x2b\xe7\x05\x4c\xe7\x2f\x52\xc5\x36\x93\x57\xe1\x15\x58\xbe\x3b\xcb\xe1\x5f\xd1\xea\xdc\x19\x74\xc6\x50\x52\xca\x99\xe1\xf9\xcb\xd0\x4c\xfa\x12\xd0\x55\x55\x3a\x65\x90\x3e\x68\x21\x1a\x64\xee\x1c\x72\x6e\x44\x29\x26\x8f\x00\x22\x81\xcc\x9f\xd7\xa2\xd4\xd5\x6b\x8a\x3f\x70\x94\x9e\x13\xc3\x41\x25\x43\x77\xff\x41\xe5\x8c\x18\xb0\xb6\xe2\xeb\xab\xab\xfe\x4f\xb6\x76\x3b\xb2\x30\x18\xb5\xc8\xe6\xb7\x74\x1a\xe7\x09\xb6\xbe\xac\x76\xa0\xdd\x07\xe6\xec\xa3\x18\x8d\x45\x14\x59\x35\x5b\xe8\x8b\x3f\x83\xb7\x8b\xc6\x8a\x58\xfb\xae\x4a\xfd\x70\x96\x13\xcd\xd7\xb2\x2d\x0e\x58\x91\xea\xa6\xd2\xad\x38\x97\xca\xdf\x43\x9a\xc4\x51\xea\xd3\xe4\x53\x55\x36\x15\xb2\x6d\x86\xc8\xed\xc9\xb5\x26\x54\x78\x0d\xa7\xc5\xa9\xd8\xe8\x51\x89\x88\x26\x2a\x8d\x7b\x99\xd9\x7b\x78\x7d\xac\xe6\x8b\x54\x34\x8d\xc0\x71\xa4\x9c\x0c\x6d\xb3\xab\x2c\x9c\x29\x94\x6a\xff\x31\x29\x6b\xd3\x34\x49\xac\x1d\x93\x86\x43\xf1\x13\xea\x47\x31\xd9\xab\xb9\x1f\x98\x29\x19\xda\x73\xe7\x53\x88\x5d\x68\x2a\x99\xd7\x47\x7e\xfc\xb6\x9e\x6f\x9f\xd1\xd4\xa4\x19\x84\x48\x0a\x6a\x17\x62\xbb\xa3\x99\x60\xc8\xc8\xbf\x2e\x4a\x0d\xf5\x97\xf7\x53\x58\x97\x69\x06\x52\xf7\x8c\xee\xf5\x1b\x16\xfa\xf5\x14\x1d\xd8\xcf\x50\x9a\x19\x02\x51\xef\xc9\x73\x05\xa7\x43\xf5\x7e\xa9\x87\xc5\x28\x8d\x22\xe4\xa8\x22\x92\xe7\xaa\xf8\xe9\x97\x37\x4a\xa3\x1c\xeb\x88\x8f\x35\x9c\x44\x0d\x23\x39\x70\x46\x59\x4a\x91\xab\x7e\x14\x6f\x1e\x16\xd9\xd3\xec\x19\x65\x24\xc7\x55\xe8\xeb\xe9\xb9\x16\x1a\x1e\xcf\xf5\xf3\xc5\x8c\x63\x3a\xc6\x2f\x78\x45\x4e\xf7\x74\x4f\xa7\x3c\xca\x64\x10\x02\x73\xbf\xf4\x1b\xd4\x85\x09\x26\x9a\x8c\x72\xe0\x78\xc7\x4e\xe2\x7d\x61\x4c\x71\x28\xb0\xca\x32\x47\x9f\x64\x34\x27\x29\xd6\xb0\x71\xbf\xac\x0e\x5b\x8f\xae\x98\x7c\x6d\x2e\x00\x4f\x69\xe7\xd9\xa2\x2c\x8e\xa0\xba\x67\xf4\x99\x08\xc9\xf8\x0c\x22\xb6\xd6\xd3\x7f\xf9\x34\xf9\xb6\x6a\xba\xb8\xb8\x6f\xce\x53\x91\xe6\x08\x11\xfb\xf2\xf0\x75\xbb\x5e\x5f\xdd\xac\x3f\xd1\x37\x64\x54\xd0\xcc\x4b\x4d\xdc\x89\x62\x5e\xe1\x95\x51\x01\x29\x52\xd3\xad\x21\x8f\xeb\xe2\xbb\x63\x92\x18\xa4\xd1\x5f\x07\xc5\x11\x77\x40\x65\x9c\x05\x49\xc7\x0f\x4e\xac\x48\x82\x40\x79\x09\x5e\x05\x8c\x51\xa5\x24\x02\xd9\x5b\x68\xda\x5b\xd0\xcf\x50\xff\x1b\xea\x0a\x75\xa9\x5b\xa8\xc3\x7a\x4e\x21\xe6\xc2\x15\xb6\x9d\x28\x65\x5f\x04\x0b\x6a\x51\x8c\x1a\x6d\x7c\x87\xfe\xb6\x52\x3f\x9c\xa1\x46\xd3\x8a\xe3\xc9\xf3\xd8\x18\x35\x46\xa0\x26\xc4\x7e\xbf\x2f\x7c\x41\xc7\x1e\x62\x91\xb0\x01\x99\xd0\xff\x39\x37\xbe\x14\xfa\x69\xd6\xc6\xe2\x94\x88\x81\xf4\xb3\xcb\xa3\x17\xd6\x3f\xd2\x4f\x30\x16\x13\x83\x71\xe0\xd2\x33\xf1\x7e\x1d\x07\x0d\xbe\x82\x6a\xa4\x0b\xbd\x88\xc6\xeb\x04\x8c\xe7\x24\x8b\xb9\xc0\x7e\xd8\x52\x94\x3f\xb0\x4a\xbc\xf7\xbc\x8e\xab\xaa\x14\x16\xbd\xe4\x86\xa6\x11\x20\xda\x71\x79\xae\xcb\x45\x30\x00\xf0\x07\xb3\x08\xf5\xd0\x83\x6f\x73\xa9\xad\x35\xf9\x07\x75\xe5\xf9\xeb\x4d\x85\x40\xb0\xb3\x73\x48\xe8\xe2\x63\xa8\x9b\x19\xfb\x23\xc6\x52\xa0\x8e\xe0\xa8\x1f\xa1\x76\xcc\xaa\x8b\x6d\xda\x2f\xaf\x2c\x63\x0c\xd5\xb1\xbb\xd8\x48\x3c\x0f\xc5\x31\x19\x86\xff\x51\xf0\x0e\x3d\x41\xed\xd9\xf5\x8c\xd1\x04\xac\xf4\x4d\x01\xaf\x77\xe7\x43\x1b\xfe\x0e\x99\x71\x52\xca\xa1\xb8\x3d\xbb\xa7\x30\x46\x6c\xc5\x6d\x18\x4a\x56\xe7\x60\x20\xfa\x81\xd8\x11\x63\x8c\x46\x49\xf0\xb0\x72\x15\xfc\xa1\xb5\xea\xf8\x15\x61\x8c\x59\xb6\x85\xff\x1a\x6c\xf0\xaa\x1f\xbb\xea\x82\xa8\xd4\x0d\xa5\x89\x35\x40\x75\x4e\x15\xd3\x49\xc1\x8c\xc0\xe0\xc2\xc2\x03\x7e\x5f\xf9\x5f\xcd\xb3\x84\x88\xfe\x46\xa1\xac\xd8\xf2\x7d\xc6\xf2\x88\x31\x4e\x75\xe4\xb7\xc0\xc5\x60\x8b\x61\xb9\x30\x40\x3f\x02\x7a\x8f\x6f\x41\xae\x23\x43\x82\xb6\xd6\xe2\x34\x03\xa6\x60\x22\x22\xae\xb3\x73\x38\x6c\x6d\x4c\x1a\xba\x1e\x9e\x65\x3d\x7f\x76\xc1\x01\x7b\xde\x42\x8a\x52\x57\x25\xe8\x8d\xaa\x82\x4b\xb4\x1b\x23\xe3\x08\x79\x3e\x7b\xdc\x02\xec\x32\x33\x0a\x0a\x98\x8c\x13\xb4\xc0\x13\x5a\x6f\xcf\xa7\x41\xb3\x61\x7c\x99\x4a\x67\x28\x89\x76\x82\xf6\xcb\x69\xf7\x52\x43\xf3\x12\x6c\xff\x18\xd3\x89\xd5\xa6\x2c\x54\xe5\x3f\xdf\x04\xd6\xe4\x78\x77\x60\x3a\x35\x28\x1a\xbd\x2e\x9f\x6b\x38\x8a\x70\x0a\xa1\x71\x89\xec\x22\x4f\xf7\x2b\xb0\xa8\xdc\x14\xcf\x93\x4b\x81\x2c\x95\x59\x4f\x9c\x5d\x8a\xc3\xa1\x0a\xf3\x1a\x68\x8a\x6d\x30\x28\xf5\x00\x33\xc5\x4c\x1c\x45\x76\xa9\xfa\x39\xb0\x89\x9b\x7f\x87\x4d\x92\x64\x62\x24\xf4\x31\x6f\xde\x68\x87\xf3\x28\x96\xc8\x8e\x28\xe1\xad\x45\x5e\xde\xcd\xc3\x6e\xf5\x45\x04\x74\xd2\x6f\x7e\x9c\x93\xd2\xfb\x4f\x55\x94\x37\x43\xa3\xbc\xf1\xd7\xf3\x88\xca\xd8\xd2\x8e\x6a\xed\x44\xf9\xec\x46\xdb\x0c\x28\xce\x8c\x47\x22\xce\x7b\x09\x6d\x3b\xf0\x83\x33\xc6\xca\x3a\x10\x06\xfe\xd2\x27\x65\xe7\x3e\xfe\xe1\xb1\xc9\x70\xed\x85\x63\xd1\xf6\x22\xba\x8c\x27\x89\x95\xb5\xec\x96\x14\x61\x81\x03\x87\xe2\xb2\xc4\xe7\x47\xb3\x28\x77\x0b\xcd\xef\x75\xf3\xb5\xb9\xa4\xe0\x30\x9e\x18\xe5\xd8\xa3\x98\x52\x61\x27\xd1\x97\x60\x79\xaa\x12\x0f\xfa\x5d\x9c\x75\x61\x51\x0f\x93\x13\xa4\xda\x5a\x54\x75\x81\xf2\x7b\xf3\x64\xc5\xb5\x3e\xdf\xbd\x78\x26\x22\x36\xb2\x25\x00\x3d\xb2\xe4\x70\xc3\x48\x14\x61\x3f\x48\xe0\x5f\x51\xe4\xdc\x1f\x21\x06\x57\x64\x5b\x58\x3d\x08\x55\x94\xcf\x8f\x81\xdc\xd2\x7f\x11\xe1\x26\x02\x2f\xb5\xd9\xcd\x55\xdb\xcc\x3c\xcf\xc1\x6f\x38\x51\xc2\x3a\x66\xd8\x57\x00\xc5\x23\xa6\xe7\x53\x12\x8b\x93\x57\x28\x9d\xbe\x2c\x6a\xcf\xfa\x60\x9c\x9a\x28\x0e\x06\x41\xd5\x8f\xaf\xa7\x8b\xe6\x08\xa7\x86\x25\x0e\x1e\x0f\xf5\xb8\x9e\xc5\x59\x14\xd1\xd0\x65\x6e\x8a\xe7\x12\xea\x2e\x4d\x0a\xfa\x4a\x8c\x33\xa9\x12\x0b\x6a\xae\xba\xec\xb2\x9e\x44\x88\x9c\xa7\x56\x30\xeb\xae\x98\x56\xfd\x38\x27\x56\xf5\xc4\x41\x6f\xba\xfd\xa3\x1c\x10\xe2\xfe\x16\xc6\xc9\x9f\x2a\x27\x48\x9c\xb9\x91\x00\xff\x1b\x9d\x9c\x71\x6e\x68\xee\x38\xcd\xab\xa2\x7d\x7f\x2c\x46\x11\xec\x78\x6c\x9e\x49\xbc\x9d\xdd\x4a\x70\x27\xea\x6e\x35\xf0\x37\x22\x37\xca\xd6\x65\xcf\xa8\x6d\x36\x50\x01\x70\x03\x84\x20\xb8\x3a\xb7\x08\x09\xb0\xae\x27\x7d\xf2\x74\x1e\x23\x5e\xb8\x4c\x32\x64\xff\x36\x2f\xd5\xf9\xa0\x97\xb0\xeb\x22\x82\x72\x10\x46\x71\x49\xac\x1a\x98\x7d\xdf\x6f\x0b\x59\x8b\x5e\xa2\x65\x74\xd5\x52\x27\xf8\x8c\xaa\x73\x7b\x3a\xb7\x93\xcc\x9a\xab\x28\x23\xae\xe6\xff\xcf\x4a\xae\xaa\xe3\xe9\x00\xad\xc7\xc1\xf9\x31\xa9\xc1\xce\xc4\x3e\x00\x33\xab\xcd\x6a\xf1\xd8\xed\xfc\x41\x0d\x68\x4a\x10\x19\x5f\x83\xca\xac\xa1\x88\xe3\xa8\xd8\x69\xec\x8f\xa9\x58\xc9\x01\x2f\x0e\xea\x06\x15\x08\x66\x73\x0e\xae\x0c\xe0\x99\xfa\xd5\xf8\xb1\xee\x6d\x33\x7e\xd5\x25\x19\x4f\x41\x1d\x27\xc4\x35\x7e\xae\xeb\xaa\x69\xe7\x0b\x9d\xd3\x0f\x71\x8e\x80\x0d\xa7\x7f\x09\x7a\x16\x9c\xc9\xb5\xcc\x91\x82\x71\x07\xa7\xea\x7c\x0a\xd3\x40\x1b\x89\xc6\x4d\xfe\x4e\x5e\x86\x41\x16\xa0\xd0\x2f\xbb\x10\xe5\xf8\x12\x42\xa9\x1f\xcf\xf2\x50\xa8\x8d\x17\x48\x64\xdc\x70\x0b\xfe\x5a\x55\xe5\x4f\x6b\x65\xba\x90\x55\xdd\x5e\xd8\x5d\xfa\xe1\x79\xca\x7a\x8f\xb9\x47\x51\x8b\x23\xb4\x83\x97\xf6\xef\xf5\x5c\xb9\xd1\x39\xbe\x6e\x8d\x38\xc0\x4a\x38\xc9\x47\x96\x47\x39\x11\xdd\x9c\xfd\xf6\xf5\x76\xb5\xb8\xdf\x3f\x3e\x5c\x85\x23\xc0\x79\xe4\x41\xb5\x95\xfa\x21\x4e\xd6\x78\x7b\xfc\x68\xf3\x38\x12\xcc\x95\x37\xe2\x68\x14\x8d\xe7\x31\x4b\x10\x5a\x73\xaa\xab\xca\x6c\xbd\xa4\x3d\xcb\x13\x16\x7b\x01\x9b\x90\x0f\x4c\xde\xf9\xf1\x77\xa4\x11\xcd\xb2\x31\x0f\x67\xa1\xc5\xa9\xed\xeb\xe8\x7e\x60\x62\xeb\x69\xff\x39\x6b\xf7\xa6\x72\x7f\x24\x17\x58\x36\x59\x7e\xfd\x73\xfd\xb4\xdf\xee\xd6\x8f\xfb\x74\x96\x1e\xc5\x72\xc2\xac\xc5\xce\xcf\x2e\xc9\x7e\xff\x45\xc8\x9b\x53\x95\xa2\x33\xf8\x6d\x25\x06\x35\xde\x9c\x9a\x1c\x99\x0e\xd7\x9b\xa7\xed\x6e\x7f\xb5\xf8\x73\xbf\xbe\x0f\xb7\x96\xa5\x0a\x29\x27\xe7\x06\xea\x01\xe1\x88\xe5\x8c\x58\xf9\x7c\xdd\x65\x3d\x70\x55\x8a\x11\xdf\x6b\xee\x41\xfb\xdf\xc7\x84\x96\x56\x8a\x59\xe8\x75\xf9\x5c\x94\x00\xf5\xc3\x61\x20\x14\xcc\x72\x4e\x09\xb6\xf5\x6e\xaa\xea\xf9\x00\x48\xd8\x9a\x0b\x4c\xff\xf6\xbf\xf3\xf7\x83\x6b\x06\x26\xc0\xae\x1e\xd1\xd1\xc0\xb2\xfc\x2e\x40\x94\x79\x9e\x1a\x6f\xb5\xf6\x28\x4e\xd3\x2a\x6f\x9e\x0b\xab\x9d\xdc\x3a\xb1\xe7\xfb\xdd\xd3\x9f\x9f\x07\xeb\x79\x6e\x62\x99\x0c\x14\x4c\xff\xbd\xfb\xdd\x2e\x5b\xf3\xf9\xea\x67\x55\x8c\xc9\x5f\xe7\x5e\xaa\x5c\xc4\x79\xda\x3b\xa4\x5e\x18\x1f\x4f\x47\x0b\x89\x68\x0c\xec\xff\x77\x51\x75\xdd\x43\x53\x72\x99\x52\x62\x4b\x62\xa7\x0a\x5b\xbc\xa6\x68\x7f\x1b\xc4\x73\x93\xdb\xac\x22\x0b\x0f\xc4\x02\xf3\xfe\xfb\x66\xf7\xe5\xea\x69\xf1\x7d\x71\xbb\xdf\xee\x16\x4f\xdd\x84\xdb\x79\x58\x77\xae\xd2\x8c\x58\x5c\xd2\x7f\xaa\xe9\x2d\x56\xb9\xc1\x46\x90\x28\xea\xab\xba\x3a\x6d\x07\x9d\xbb\x89\xef\x1e\xcb\x95\x10\xa8\x63\xf7\x5c\x8b\xb2\xf5\x32\xdd\xe3\xd5\xd7\x8f\x84\x34\xb1\xd5\xf5\xee\xad\xf8\xa3\x1c\x10\x60\xe6\x57\xa7\x5c\x19\x46\xc1\x03\x55\xaa\x49\x96\x9d\xeb\x24\x41\x80\x8a\xa9\x01\xbd\x75\xbe\x9e\x06\xf5\xfa\xf1\x89\x74\x62\x31\xd3\x9b\xc6\xc3\x7f\x03\xf0\x72\xf2\xd3\x35\xb3\xba\x01\xaf\x56\xd9\x2c\x48\x5b\xb2\x1c\x22\xc0\x58\x0f\x09\x81\xcb\x73\x71\xd0\x83\x4d\xff\xf2\x3f\xce\x56\x0f\xdc\x7f\x58\x18\x6f\x0f\x8d\x49\xef\xcc\xe6\x9e\x03\x50\x2c\xab\x0b\xad\x83\x03\x40\xd9\x7e\x8c\xa5\x15\xb1\x12\xc8\xa8\x85\x52\x0f\x9b\xab\xc3\x78\x4a\x24\x42\x28\x3b\xf5\x51\xae\x6e\xf9\x1e\xe4\x49\x99\x48\x54\x86\x8d\xcb\x2b\x51\x8a\x76\x50\x63\x17\x69\xc4\x51\x2d\x64\x55\x95\x96\x66\xb5\x7c\xf7\x46\x26\xb3\x0f\x4a\x64\x29\x18\xdc\xd8\xde\xd0\x73\xc2\xfd\x95\x32\x23\x1d\x94\x6e\x7f\x9a\xca\x9c\x33\x41\x21\xf3\xb0\xc6\xab\x4a\x4d\x72\x49\xc1\x92\x98\xdb\x8a\x7b\x8d\x5a\x7c\x4b\x3b\x53\x86\xc1\x8c\x60\x19\x25\xa6\xd7\x7c\x83\x52\x8b\xb2\x6d\x1e\xcc\xee\x65\x2a\x08\xc1\x04\x63\x19\x76\x5d\xf7\x45\xf3\x50\x2e\xe6\x40\xd1\x82\x27\x81\xf6\x65\x25\xc1\xd6\x4e\xdd\x76\x3c\xf1\x04\x67\x1c\x79\xf9\xab\xdb\xc7\x61\xad\x46\x70\x61\x90\x6d\x0f\x6f\xa7\xa2\x1e\x01\xa4\x04\xd7\x26\xb3\xdc\x82\xd3\x26\x44\x3b\x3e\x00\x14\x79\x06\x98\x8e\x9d\xaa\x57\xa8\xaf\x44\xaf\x18\x8d\xe7\x98\x32\x52\x44\x4e\x18\x66\xb1\x76\x7d\xb9\x05\xa1\xa1\xf6\x1d\xc0\xe1\x8c\x12\x39\x01\x9e\x86\x22\xc5\xd7\x52\x59\x3e\x2a\xb6\xef\xa7\xf7\x3b\xcf\x53\x20\x03\x73\x35\x47\x87\x2e\xa0\xc1\xa5\x72\x5a\x44\x11\xb9\x66\x58\x21\x7c\x11\xcd\xca\x12\xef\x40\x2f\x4e\xa7\x43\xa1\x86\x86\xba\xe3\xcf\x48\x91\xa6\xda\xfb\x0d\xbc\x4d\xb2\x08\xa1\x62\x02\x49\x4f\x01\x1d\xf2\x46\x84\xe2\x56\xd1\xf6\x19\xda\x7f\x9d\x0b\xf5\x63\x79\x7e\xc7\x5f\x61\xcb\x92\xa3\x54\x47\xe8\xd4\x5a\xd9\x1c\x44\xd3\xf6\xd2\x7e\x36\x1e\xd5\xa1\x72\x1a\x46\xe7\x60\x43\x56\x61\x60\x3b\xac\xfb\x8c\x2f\x0e\x12\x66\x73\x8b\x2e\x11\xd8\x5f\x05\xe9\x68\x26\x20\xb5\xa2\x30\x0d\xb4\xf7\x55\x7b\x57\xd5\xb0\x7b\x11\xd3\xa9\x05\x86\x21\x7a\x65\x79\x73\x33\x9a\x32\x5d\x08\xe9\xd6\x05\x74\xc9\xb2\x4a\xe3\xda\x39\x66\x8d\xee\x9e\x8c\x33\xe6\xba\xde\xf2\xfc\xfc\x4d\x1c\x9c\xdc\x18\x43\x8b\x6c\x17\x39\x39\x6e\x4a\x8f\x31\xfd\x7c\x67\x94\xb1\xb4\x1e\xd7\x5e\xe9\xfc\x51\x14\xb5\x05\xf6\x76\x4b\xd0\xdf\x43\xc6\xc8\x84\x5a\x2d\x29\xa1\xad\x67\x4d\x32\xb9\xf0\x84\x26\x31\x0b\x9b\xbf\x5b\x79\xad\x59\xc8\x45\xda\xe4\x3f\xc2\x18\xae\xed\x4b\xd1\x14\xea\x09\x9e\xcf\x87\xa1\x67\xed\x07\xd7\x91\x32\xab\x4a\xe2\x24\x4b\x9e\x50\x87\xca\xdf\xa4\x34\x0f\x3e\x50\xb8\x23\xfb\xf8\xe9\xf6\x02\xfc\x2d\x09\x0b\x65\xf9\x9b\x33\x34\xed\x7d\x4f\xe7\x91\xc4\x28\xd2\xa3\x6d\xbc\x68\x69\x73\x1d\x20\xbc\x92\x12\x86\xac\xc1\x6e\xfa\xe1\x1c\xde\xff\x8c\x59\x38\x28\x19\xb5\xcb\x31\x42\x9b\xaf\xcf\x87\x43\x97\x4f\xf7\x31\xc2\xe8\x07\x51\x43\xd1\xaa\x15\x7d\x98\xa1\x69\xbf\x88\xba\x84\xa6\x59\x9c\x43\x59\x40\x72\x2a\xb3\xc0\xb3\x13\xb8\xaa\x35\x0f\xe5\x7d\xf5\xfa\x6d\x62\xd9\xc6\x24\xe7\x4a\x0e\x75\xdc\x1f\x9c\x0b\xc3\x47\x22\xc3\x93\xbb\xcb\xc1\xe0\x54\xf9\x59\xb5\xd0\x6c\xcf\xa7\xc1\x4a\x2f\xf3\x3c\xa5\x3e\x93\x5b\xbf\x15\xed\x38\x00\x97\xb9\x50\xa8\x64\xd8\x6d\x21\xbb\xfa\xdc\xb4\xd3\x52\xbf\x14\x49\x6c\x1f\x5d\x55\x94\xdd\x04\x1e\xc1\x10\xbb\xa3\xd8\x32\x3e\x89\xf7\x78\xfa\x41\x91\x62\x5b\x74\xf1\xf4\x47\x0f\xf9\x77\xc7\xa4\xb4\x39\xd2\xb2\x3a\xa3\xd9\xfb\x67\x19\xe1\x07\x53\x4a\x51\x83\xda\x21\xaf\x53\x41\xa9\x51\xed\x62\x9a\x2c\x48\xc5\x39\x96\x7a\x9a\x97\xea\x75\xd7\xad\x74\xfe\xef\x26\xc2\x26\xcd\xea\xfa\x8f\xe1\x32\x20\x21\x4a\x3c\x6b\xfc\xd1\xf6\xda\xa7\x49\x8c\x04\x0a\x26\x40\xe7\x4f\x2b\x0b\x5d\xda\x5a\xe0\x5f\x8f\xb0\xef\x96\x13\x6c\x84\xd8\x25\x1f\xe9\x0d\x9f\x17\xcb\x24\x28\x4a\x1d\x6b\x61\xaa\x63\xc7\x24\x40\x66\xa1\x08\x55\x2b\x0e\x77\x2e\x37\xb0\x90\xda\xc1\xf6\x26\x0d\xe1\x58\x00\x3d\x97\x8e\x79\x02\xfa\x5f\x67\xe8\xf6\xc0\x66\x7a\x46\x93\x5b\xe7\x20\xab\xb9\xb0\x5d\x2d\x6e\xd7\xe1\x2c\x42\x38\x27\x8c\x65\x9a\x5c\x72\x20\xfb\x8d\x5f\x1a\x05\xa9\xd5\x10\x0b\xb9\x95\x8a\x52\x86\x55\x99\xfb\xe2\x34\xbc\xb7\x2a\xc9\x22\x4e\x7b\x51\x2f\x3d\x12\xf0\x66\x2a\xc9\xad\x3a\x0a\xec\x3e\x5f\x5d\x54\x02\xb1\x87\xb6\xa1\x09\x40\x63\x25\x34\xfd\x79\xd2\xcc\xbb\x24\x60\xa1\x13\x4b\x99\x71\x38\xc8\x09\xa2\xc9\x9e\xee\x96\xa3\x6b\x4b\x75\x8e\x6d\x71\xe9\x3d\xb4\x10\x0d\x11\x36\xea\xbb\xe2\xe0\x77\x40\x95\xa5\x11\x32\x89\x9e\x2a\x59\x94\x23\x0c\xc7\x4c\x2c\xd9\x05\x76\x23\x99\xbb\xeb\xaa\xb6\x16\x2d\x9f\x6e\x07\x2a\x83\x1c\x1b\x97\xbb\xea\xf9\xf9\xe0\x5c\xc0\x2f\xdd\xca\x99\x22\x69\x2a\xba\x3d\xef\x6e\xb7\x1d\xc4\x8d\x8a\xe4\x39\xe2\xb8\x90\x94\x64\x44\xd3\xb6\xc3\x1f\x4b\x65\x82\x7d\xa9\xbd\xd0\x98\x81\x6e\xdb\x1a\xc4\x71\x9a\x83\x8d\x66\xbd\x62\xc2\x8a\xa3\x04\xe7\xaa\xf6\xfd\xd1\xd5\x27\xc7\x0b\x81\x62\x52\x20\xf2\xf7\xb6\x7a\x0e\x98\xaf\x0b\xbd\xf1\x71\x19\x5c\x71\x20\x38\xf5\xaf\x51\xe4\xe9\xe3\x48\x5b\x71\x23\x31\x03\xff\x02\x87\x13\xd4\x5b\x10\x75\x40\x72\xa8\x5c\x69\x64\x0f\xab\xde\x10\x72\x7c\xb3\x44\x9c\xa1\x56\x73\x89\x62\x18\x0f\xc6\xa7\x20\x3e\x82\x50\x22\x95\x28\x9e\x73\xc2\xc5\xb8\xbf\x3c\x41\x73\x5c\xfe\xb7\x6d\x2d\x5a\x78\x7e\x1f\xc7\x39\xaa\xcb\xed\x7b\x3f\xd7\x55\xfd\x7e\x6a\xab\xc5\x4f\xd1\x8a\x0b\x39\xfb\x8f\x92\x74\x7f\x22\x93\x63\xff\x5b\xd8\xec\x0d\xd5\x35\x6e\x2b\xf5\xa3\x97\xbe\x63\x4a\xa6\x29\xe6\x0a\x4f\x38\xbd\x03\x63\x2d\x1c\xce\xb2\xd8\xb3\x5f\x7c\x77\xc4\x19\x76\x0e\x7e\x90\x04\x8e\xf8\xa5\x1a\x5d\x57\xba\x9c\x6d\xa6\x6d\xa6\x94\x73\x8d\x5d\xde\x2f\xef\xb7\xce\x50\xcf\x37\x3d\x95\xa2\x11\x42\x27\x44\x51\x8f\x8a\xf9\x4a\x09\x6d\xfb\x82\xeb\xc5\xdd\x1e\xe9\xad\x16\x65\xe5\x8f\xeb\xcc\x16\xfb\x3d\x76\xea\x6a\x60\x59\x3c\xe0\xdd\x29\x4d\xac\x9c\x03\xa6\x79\x16\xb7\xf8\xc9\xc4\xd0\x00\x96\x97\x53\xf9\x42\x9e\x02\x42\x30\x7a\x40\x59\x4b\x04\x2a\x17\x7f\x01\x1a\xd8\x7f\x04\x7e\x76\x1f\x34\x22\x8e\xbb\xe7\xf9\x7d\x7d\x7b\xbd\x78\x5a\xef\xbf\x2c\xee\xaf\x1e\xbe\xee\xfc\x79\x8d\xa1\x26\x19\x28\x8b\x7c\xa4\x41\x30\x3e\xab\x8e\x5c\x4f\x6e\x88\xf7\x19\x40\x55\x74\xa4\x05\x96\xa7\xef\xab\xfa\xe8\xfa\x93\x9f\x88\xaa\xba\xc2\x92\x8e\x89\xc1\x84\x6f\xdb\x42\x5d\x1c\x8a\xf3\x71\x38\x1b\x74\xac\x32\x5c\x8a\x37\xab\x07\xb7\x43\x55\xc7\xaa\x3f\x68\x65\x42\x4b\xc4\x6f\xfb\xd9\xac\x93\x08\x1c\x75\x11\xb6\x01\xbe\xed\x0f\xa6\x31\x45\x6d\x80\xb6\x0b\x1e\xae\x40\x5c\xf4\x74\x75\x2a\xad\x54\x48\x33\xf1\xe7\xff\xb0\x2e\xaf\x53\x9d\x63\xe4\xb4\xda\x3c\xad\xbe\xde\x2e\x76\x9b\xfb\x9b\xfd\x72\x11\x78\xef\x3a\xd3\x32\x1d\x76\xad\x9f\xa0\x29\xf4\x59\x1c\xb6\x0a\x91\x4d\x1f\xf4\xf8\x34\x49\x08\x52\xdc\x4e\x43\x39\xb4\x21\x00\xfb\x82\xca\xaf\x49\x66\x1b\xf6\x0f\xf5\xe9\x05\xce\xcd\x43\xfd\x2c\xca\x42\x35\xbb\x97\x2e\x50\xf6\xda\x67\x4c\x13\xc9\x13\x67\x91\xbf\x38\x1c\x9c\xcc\x7b\x33\x5f\xae\xd4\x04\xa4\x71\x2c\xa5\xab\xba\x2a\xfb\xfb\x4c\x05\x41\xcc\x86\xae\x8b\xd3\xc7\x9e\x08\x4c\xb3\xd8\xee\x67\x8e\xb0\xd9\xbd\x0d\xc8\x0e\x40\x60\xf0\x14\x23\xaa\x19\x15\x90\x0f\x36\xc7\xee\x19\x6d\x4f\x10\x52\x5c\xcd\x38\x24\xd8\x54\xa9\xca\x33\xda\x5e\x6e\x4a\xd7\x58\x89\xc3\x10\xc3\x91\xdb\xb3\xb8\xff\xf2\x75\xb3\x5f\xdc\xdf\x7f\xdd\xec\xfe\xdc\x5f\x2d\x1e\xf6\xa9\x4f\x75\x34\xa7\x0c\x8b\x65\xc6\xbd\x57\x4f\x80\x5b\xe5\xe4\x6a\xf2\xcc\xfa\x3e\x2b\x51\x76\x29\xdd\x77\x90\x37\x85\xf1\x2b\x85\x16\xb1\x95\xf5\x58\x68\xe4\xf5\x7d\xda\x31\xd6\x82\x72\xbc\x8f\x4d\xeb\x0d\x91\x98\x96\x29\x83\x31\xb0\x72\x3e\xdf\xd5\x32\x4b\x10\x27\x21\x7b\xd5\xd7\xc0\xa6\xf2\x01\xa5\x1f\xca\x0c\x78\x0b\x8a\x87\x72\x4e\xd7\x98\xff\xaa\xd4\x3a\xde\x3a\xb5\xd4\x24\x71\x8f\xe4\x16\x44\xd3\xae\xdf\x4e\x50\x36\xc5\x4f\xb7\x53\xdc\x88\x63\x00\xd0\x69\x45\xa5\xb7\x0c\xc4\xe7\x8b\xfd\x04\xd7\x94\xfe\xbb\x95\xdf\x70\x2a\xab\xd4\xf4\xff\x69\xfb\x93\xe6\xc6\x71\x6c\x7f\x18\xfe\x3a\xb5\xe8\x05\x67\x00\x4b\x59\x96\x33\x5d\x65\x5b\x6e\x4b\x99\x59\xdd\xff\xb8\xa1\x38\x00\x0e\x6c\x5e\x4b\xa4\x9a\xa4\xec\x74\x7f\xfa\x37\x78\x30\x70\x90\x9c\x55\x37\xe2\x7d\x36\x95\xdd\x26\x44\x89\x24\x08\x9c\xe1\x37\xd8\x00\x34\x28\x27\xfd\x32\xb7\xd0\xca\x20\xe1\x06\xaf\xbf\x3d\xdd\x2e\x1e\x6e\xfe\xf4\xbf\x4b\xf3\x84\xc5\x83\x7b\x26\xc9\xdd\x9d\xbd\xfa\x9a\x23\x95\x5b\x0f\xd8\x8c\x48\xc8\xb3\x2f\x0c\xaf\xbd\x86\x82\xe8\xab\x6f\x25\xbe\xb3\x28\x7c\x91\x2e\xac\x25\xd7\x6b\x59\x5d\x05\x21\x33\xa6\xb1\x60\xda\xfa\x3f\xbe\xe2\xf7\xb2\x2d\x7d\xc1\xd0\x3b\x77\x33\x8d\x1c\x69\x7d\xf5\x0f\xd6\x01\xe8\xf6\xe7\x80\xb1\x79\x92\xab\xd1\x70\x0a\x0c\x3a\x84\x43\xeb\x54\xde\xc7\x85\x7f\x8d\x46\x11\x56\xf3\x58\xfe\xf7\xbf\x30\x96\x66\x64\xda\xc4\x5c\xa7\x2e\x35\x8c\xbe\xd7\x01\x93\xad\x8d\x6b\xf0\x59\x56\x20\xa9\xfd\xe8\x9b\xba\xb9\xb2\xef\x9d\x45\x2e\x0d\x67\x71\x9a\x7b\x8b\xbb\xbb\xf5\x72\xb7\xb8\xfe\x7e\xbb\x59\x3f\x6d\x76\x57\xeb\x6f\x0f\xdb\x5b\x6f\x6e\xc7\x30\x8a\x24\x45\x61\xaf\x65\xdb\x5e\x6d\x97\x4b\xd8\xef\x25\x0c\xcd\xeb\xe9\x65\x61\x94\x25\xb1\x71\x35\xeb\xb6\x45\x2b\x2b\x4d\x80\xd8\x70\x3e\xb4\xe2\x30\xe3\x56\xcf\x27\x4d\xe2\xf9\x4d\xc3\x38\xc9\xc0\xb5\x8f\xfa\xe8\xdf\xb6\x12\x7e\x9b\x8d\x11\x05\x73\xc0\x04\xef\xc4\xf6\x02\x0d\x3e\x9d\xf6\xf8\xa5\xa9\x4f\xc7\xdb\x4f\xaa\x3c\x98\x30\x91\xdb\xec\x49\x9f\x14\x3a\xdf\x9b\x59\xa5\x0c\xd3\x34\x8e\x5c\xb9\xe5\x1e\x3b\x78\x6c\xea\xff\x9d\x0b\x10\x32\x4c\xf3\x24\x2b\x06\xf8\xfb\xe1\x74\xf8\x51\xb6\x2f\x5b\xb7\x5c\xf8\x41\xa0\xa9\xce\x1a\x04\x7b\x46\x52\x62\x0c\x8b\x34\x8b\x13\x6f\x12\x49\xb4\xaf\xe9\xef\x28\xf2\x9c\xf8\x40\x0d\xb6\xd8\xf9\x40\x23\x7c\xb8\x10\x8a\xca\x9d\x36\x2c\x9d\x6b\x78\x4c\x7f\x6c\xbf\xb7\xf4\x97\xfd\xef\x6f\x7f\x8c\xf7\x71\x64\x46\x64\xde\x49\xb4\xff\x65\xd8\x7e\xbe\x9f\x22\x4f\xc0\x75\xd4\x35\xfe\x74\x78\xd5\xd8\x0f\x8c\xc7\x71\x37\x72\x81\x64\x39\xf1\xf8\xed\xea\xee\x76\x69\xf5\x36\x48\x30\xd1\x7f\x31\xd7\x09\xcf\xc6\xcc\xcb\xc7\xfa\x1d\x9b\x3d\xbe\xe1\xac\xa8\x81\xc2\xd8\xda\x52\x8b\xdd\x35\x1a\x55\x57\x44\x48\x1f\xcb\x05\x33\x84\x22\x57\x7c\x40\x15\x2d\xf6\x23\xc1\xd1\xc9\x1d\x05\x48\xf9\xd0\xb8\xd9\x20\x61\x63\xda\x5d\x5d\xed\x3f\x76\xd7\xf8\xf6\xcb\xb0\x7a\x2c\xe6\xcf\x50\x16\x31\x49\xe1\xdc\xd5\xcf\x56\x60\xe2\x91\xa4\xe2\xfc\xf5\x49\x96\x27\xe8\x75\xaa\x5a\xcf\x3d\x9a\xea\xd1\xa0\x8a\x90\x6a\x0f\x9e\xad\xaf\x5e\xdc\x64\xbe\xd8\x4d\x47\x95\x49\x8a\x91\x4e\x55\xa9\xea\xa6\xba\x6a\x10\x75\x59\x3d\x4f\x93\x06\x54\xda\xd0\x46\xfd\xe7\xe2\x5b\x3b\x79\xd6\x5a\x46\xb4\x5d\xf4\x49\x7e\xdb\x35\xe8\x66\xe4\xa7\x25\xc0\xd1\xe3\x44\xa1\x29\x32\x7d\xb8\xde\x26\x93\x73\x9a\x14\x21\xb6\xa2\x29\x0a\x1f\xf0\x67\x37\xa6\xec\xa1\xe1\x32\x25\xff\xa9\xed\x97\xf0\x27\x61\x91\xbf\x1a\x89\x48\x6b\x63\xc0\x0b\xe1\xad\xbf\xcd\x46\x1a\xeb\xd3\xba\xfa\xbe\xba\x5b\x3f\xae\x9e\x36\x37\xdf\x42\x43\xd5\x44\xac\x70\xce\xfe\x44\x98\xb3\x9c\x91\x76\x7a\x43\x4c\x24\x18\x79\x92\x52\x39\xf9\xae\xee\x3a\x1f\xa8\x9a\x38\xc9\x91\x05\x0a\x65\x37\xa1\x9a\xcd\x1a\x7f\x97\xff\xaf\x3f\x0f\x8b\x25\xf3\x50\xed\x2f\x75\x9f\xea\xeb\x71\xcd\xc6\xc4\x28\x23\x1d\xbe\xa8\x5f\x2b\xa6\xea\x5d\x96\x92\x30\x7d\xfb\x4d\x1a\x19\xc2\xe5\x11\x36\x39\x59\xff\xe1\x4f\x96\x1a\x56\x50\x57\xa5\xd6\xf7\xb5\xfe\x54\xd8\xde\x8d\xce\x32\x4b\x1e\x34\x24\xf4\xb3\x3f\xbe\x80\x53\xd8\xf0\xa7\xcb\x72\x9b\x22\xff\x71\xbb\x08\x7f\x42\x50\x38\x14\x54\x26\x69\x98\xc9\x4c\x4a\x12\x13\xd6\xfd\xff\x42\x7a\x67\x72\xce\xe9\x25\x7b\xab\x3b\x8c\x92\x7f\xe1\xd8\x61\x89\x99\x5c\x32\x42\xce\x5b\x40\xdb\x25\x6f\xcf\xe9\xd9\x8a\x8c\x51\xa3\xfd\xb9\xee\x46\x4d\xb3\xf0\x74\x99\xd0\x44\xb3\x70\x16\x33\xeb\x23\x56\x0e\x3e\x1d\x46\x00\x90\x51\x18\x58\x5e\xf1\xbc\xad\xee\x46\x71\x13\x47\x81\x69\x4b\x39\xbe\x3b\x20\x22\xa4\x9e\xd1\x9e\xec\x8d\x82\x6b\x24\x33\x22\x37\xca\x33\xc8\xec\x2f\x3b\xed\xa1\xa1\xaa\xfa\x78\xd5\xf8\x7f\xd9\xff\xcc\xae\x48\x18\xe6\xcd\x21\x08\xfd\x44\x88\xf5\x72\xce\x38\x37\x90\x45\x54\xaa\xf1\x95\x49\xd7\x0e\x99\x8d\x92\x69\x41\x05\x47\x05\x47\xcf\x48\x35\x32\x65\x94\x01\x58\x98\xef\x64\x26\xca\xac\xa0\x42\xed\x66\x39\x41\xc8\x1b\xc9\x94\x57\x60\xf9\xe3\xa4\xeb\x76\x83\x55\x67\xd3\xf7\xcb\x91\xaf\xd1\x69\x41\xfd\x1a\x07\x49\x74\x7f\xc5\xd8\xb2\x40\xbe\xde\x8d\xaa\x46\x06\x31\x81\x62\x78\x46\xae\x51\xb3\xe8\x86\xe3\x79\xe4\x38\x5b\x0f\xae\x84\xe2\x05\x40\x87\x53\x9b\x38\xb3\x0e\xf2\x7d\x18\x46\x7c\x96\x0d\x18\x9c\xc8\x39\x0c\x5b\xd7\x10\x5b\xcc\xa2\x43\x63\x0c\x90\x5a\xc7\xd1\x02\x91\xbc\x02\xc8\xe8\x26\xf1\x28\x4a\x0d\xe3\x0e\x1f\x36\x4e\x53\x79\x14\x41\x94\xdb\x8a\x4c\x1f\x61\x7b\x68\x98\x3f\x28\xb9\xf0\x00\x3e\xab\xc4\x5b\x62\xeb\x9c\xee\x27\x4f\x8d\x47\x11\x5a\x2b\x4c\xa2\xd1\x1c\x0e\x38\x03\xdc\x71\x52\x64\xd4\xde\x0c\xd8\x16\x29\x82\x06\xfa\x03\xc9\x75\x04\x4d\x11\x1e\xc5\x12\x14\x39\xf2\xc2\xfe\x75\x5b\xff\xa8\x9b\xfd\x84\x3c\xc4\xa3\x24\x4a\x8b\x78\x2a\x00\x54\xfe\x3c\x37\x36\x98\x85\x62\x3c\x4a\xd2\xdc\xc5\xaf\x6d\x47\x4e\x42\xab\x9f\xa8\x4e\xd6\x0e\x82\xb2\x40\xea\x1c\x4e\x40\x97\x3c\x4a\x44\x4c\x72\x8e\x16\x4c\x7c\x73\xf2\xf9\x2d\x8f\x52\x6e\xf1\x91\xae\x9e\x05\xcd\xb8\x18\xe1\xc6\x64\x3a\xa2\xc7\xfc\xe8\xcb\xcc\x23\xf9\xd3\x5f\x95\x6f\x79\x94\xc7\x96\xc1\xb5\xd0\xfa\x01\xdf\x27\x60\xce\xff\x53\x86\xc3\xa3\x3c\x33\xae\x14\xf6\x56\xbf\x62\x20\x74\xf3\x28\x67\x31\x3a\x87\xe7\x6e\x51\xe9\xcf\x74\x20\xdc\xe8\x22\x8f\x08\xdc\x20\xcb\xe7\xdb\x70\x8a\x42\x24\xd2\x6d\x05\xf4\x42\xd3\xc4\xbb\xad\xbe\x6d\xae\xa7\xf7\x81\xc5\x8a\xee\x22\x68\x5d\x5e\x86\xe7\xf2\x88\xc7\xa9\x15\xfd\xdc\x23\x34\x44\x60\x1a\x8b\xbd\x8e\xc6\xa5\x11\x15\x3a\xca\xd6\x31\xd1\xc6\x0a\xee\x2e\x9d\xe4\x11\x37\xa9\x63\x9f\x57\x57\xa7\x8f\xd9\x84\x15\xa9\xa1\x8e\xf8\xb1\x6e\xbb\x99\xb7\xdc\x59\xa4\xc8\x23\xc1\xd3\xb4\x18\xaa\xde\xe4\x20\x5a\xef\xb7\xf5\x16\xe1\xe0\x6f\x84\x10\xb1\xad\x44\x37\xa7\xb6\xdb\x63\xdb\xee\xe6\xce\xbe\xbf\x54\x60\xe7\x91\x30\x82\x16\x66\x6a\xa5\x4e\x6f\x1e\xe4\x56\x84\xf0\xdd\x8b\x3f\x9d\x01\xd8\x78\x24\x93\x34\x77\x28\xc7\xd5\x9f\xb3\xb7\x4f\x26\xc0\xbd\x02\x9f\x55\x8a\x5f\x8e\x67\xb8\x4c\x59\x3c\x18\xfc\x8e\x15\xac\x79\x24\xb5\xa1\xae\xb9\x24\x47\x50\x47\xd8\x6a\xa6\xda\xdd\x3c\x92\x46\xa3\xcd\xb7\x2a\x3d\x39\xb5\xe2\xc0\x6d\x9f\x85\x9a\xe3\x23\x71\xc0\x49\xf2\xcf\x23\x05\x29\xe9\x1f\x53\xdf\xc6\x76\x29\xc3\x1c\xd3\x3c\x8b\x5c\x23\xe3\x09\x2a\x5d\x3b\x75\xdb\xe9\x09\x90\x65\xc6\x76\x58\xba\xab\x8f\x5b\x3d\x3b\x6a\x12\x2b\xde\xd3\x27\xd1\xbb\x06\x41\x7f\x0c\x5b\x2a\x8f\x8c\x44\x69\x75\xeb\xbb\xd3\x99\x81\xd8\x3f\xa6\xf7\xd9\xe8\x84\x5b\x43\x3d\xd7\xe3\x75\xfa\x1e\xfa\x8f\x0f\x15\x2a\xfd\x76\x6c\x1c\x6b\x4d\xd1\xe1\xa6\xde\x43\xb3\x52\xfb\xf2\xd8\x8e\xab\xd0\x3c\x4e\x92\x84\x5e\x29\xb7\x97\xd3\x1a\xf4\x15\xda\x97\xdd\xf4\xe7\xc7\x89\x32\xd2\x8c\x3a\xa1\x9e\xd8\x30\x13\xaf\x75\xa3\x33\x6e\xac\xa3\x79\x79\xc0\x79\x87\x8c\xc7\x99\x48\x63\x70\xe2\x41\xf0\x8a\xb3\xcf\xe6\xb1\xb6\xa5\xf5\xae\xbb\x90\x30\x8f\x7a\x5a\x3c\xce\x59\x4c\x27\x7a\x39\x58\x6f\xaa\x33\x8a\x96\x1b\x57\xe4\xd6\x0d\x69\x0b\xcd\x47\x35\xb9\xfc\x82\x81\x27\x6a\xff\xde\xd6\xd5\xb6\xb6\x0f\xf6\x17\xf5\x2d\x1e\xb3\x58\xd3\xd9\xaa\xd3\xa1\xdf\x56\xfb\x54\x05\x35\xd5\x6b\x47\xfc\x2a\x1e\x33\x1e\x59\xe5\xb0\x7e\x2d\x71\x8d\xf5\xe9\x3d\x65\x68\xed\x38\x4e\x96\xd3\x78\x9f\x5f\x8c\x0c\x78\xcc\xe3\xc4\x28\xcf\x63\xb5\x8f\x7a\x76\x47\xb9\x8e\xa9\xfe\xef\x64\x53\x3e\xb3\xbf\xfb\x3b\x00\x57\x1e\x8b\x48\xd1\xc9\xbe\x6e\xfd\xa5\x88\x1c\xc9\xb3\xe9\x00\xaf\x04\xb5\x23\x39\xdb\x2c\x1c\xe5\x31\x01\xee\xdc\xd9\x07\x99\xec\x5f\xae\x36\xb1\xd4\xe8\x29\xcf\xdb\x66\xcc\x8e\x9d\xde\x24\x69\x12\xea\x93\x96\xed\x7a\x7d\xf5\xdb\x3c\x6d\xe4\xb1\x42\x8b\x81\xd5\x65\x0b\xfb\x7d\xfd\xbe\xf0\xf9\xef\x06\x9d\x29\xd4\x27\x77\x55\x27\x11\x65\x31\xc7\x3d\xa9\x39\x0e\xf6\x30\x3c\xc6\x58\xda\x32\x42\xf9\x66\x85\x3b\xc2\x81\x24\x26\xb2\x0d\x78\xf0\xc1\x23\x94\xfb\x7d\xf9\x09\xd3\x91\xc7\xc8\x2d\x85\xe0\x11\x3e\xd6\x67\xaf\x81\x61\x19\xd9\xfb\x2c\x1a\xf5\x42\x35\x46\x84\x41\xda\x92\xc7\x46\xc4\xa2\xbf\xe9\x7d\x40\x35\x9e\xb3\x49\x24\x19\x15\xde\x6c\xc3\xdf\x4b\xab\x4e\xce\x9d\xc4\x51\x46\x92\x6c\xb2\xfe\xb9\x7c\xa9\xe7\x82\x1f\x3c\x89\xf3\x44\x66\x67\x7d\xe3\xb9\x72\x2a\x4f\xe2\x42\x8d\x1a\x66\x5f\x4f\x07\xf8\x3f\x3a\xd6\xf1\x24\xe6\x4a\x38\xb9\xa4\x21\xb7\xfa\x7f\xe9\xb0\xc7\x65\xff\x33\x25\x11\xfa\xcf\x29\x6e\x49\x00\x50\xdd\xc3\xcf\x9b\xc6\x23\x3c\x79\x92\x66\x85\x16\x83\x35\xeb\x62\xbf\xb7\xea\x8b\xe3\xb2\x7e\x91\xfd\x23\x28\x81\xfe\xe3\xbc\x02\x93\xfc\x8f\x3f\x97\x4c\xb9\x1e\x6b\xaa\x2d\xde\xb0\x0f\x41\x1f\xcb\x9f\xe8\xf4\xf4\xfd\x4f\x8e\x8b\xff\xb9\xfc\xc6\x24\xa9\x4e\x49\xdb\xe0\x7b\x3d\x51\x9a\xae\xeb\xfd\xf4\x56\x64\x59\x42\x95\x71\x83\xf8\x08\x1f\xc3\x05\x65\xb9\xa1\x47\x4d\xae\xc6\xb2\xbd\x2f\xc3\xb3\xce\x13\x43\x3d\x9a\x65\xad\x49\x62\x72\x32\x11\x98\xc8\xe8\xe1\xfc\xe7\x54\x06\x5b\x93\x10\xc3\x26\x0c\x64\x96\xfa\xaa\x66\x3f\xbb\xe3\xc8\x1f\xe2\x4c\x08\xc7\x39\xd8\x96\xd8\xb4\x24\x5e\x3d\xa9\x5c\xff\xc2\x3b\xb1\xcf\xbf\xdc\x79\x44\xa4\x55\x1e\x54\x66\x36\xe7\xd3\x10\x32\xeb\xe1\xe5\xdd\x0a\xf7\xfb\x75\xa5\x70\xa0\xa2\xf1\x04\x18\x52\x9a\xb4\xf6\xda\x04\x3c\x01\xae\x68\x4d\x86\x06\x2b\x98\xed\xf3\x89\xcc\x19\x15\x63\xb6\xb7\xab\xa7\x6c\x5c\x01\xe3\x89\x64\x8a\xa4\x28\x6e\x10\xdb\x0b\x0e\x83\x3c\x91\x3a\x23\x3a\xea\xd5\xdd\xe2\xf6\xc1\xea\x1d\x4e\xee\xa7\x4a\x72\xda\xe5\xef\x87\xdf\xa2\x1d\xc2\xbe\x8f\x4f\x6f\xca\xf6\x65\xd6\xd7\x0c\xb3\x8b\x5f\xf8\xd7\xd9\x02\xf8\x18\x2e\xd1\xdc\x0a\x12\xee\xd1\x74\x59\x3c\xfb\x6d\x18\x59\x20\x64\xbf\xc4\x9e\x8e\x77\xf8\x8c\xfd\x4b\xf6\x31\x1f\x95\xf0\x38\xf3\x39\x75\x40\x52\x3d\x62\x53\xd6\x3e\x56\x49\xb0\xd0\xdc\x8a\x2b\x29\xa4\xf5\xa1\x54\x84\xf5\x75\x6a\xaf\xd3\x13\x9a\x42\x50\x86\x65\x27\x89\x7b\x4a\x16\xf8\xe7\xcf\x67\x80\x39\xb2\x60\x9f\xb7\x3d\x62\xb3\x6d\x4e\x95\x7a\xf1\x93\x37\x8d\x0a\xab\xba\xea\x23\x03\x82\x7e\x8d\xa7\x7d\x4a\xbe\xdf\xfd\x2a\xb8\xf8\xd7\xfa\xdb\x76\x77\xf3\xb4\x58\xee\xae\xd6\x7e\x77\x49\xe3\x8c\x09\xee\x66\xa3\xe5\xe4\x5d\x66\x70\xf0\x34\x36\xd2\xe3\x49\x6c\x8c\x78\x57\xb6\xdd\x18\x53\xc2\xd3\x44\x0a\x2a\x6e\xc0\x19\x84\x7c\xde\x4e\x99\xac\xd4\x69\xa2\x0c\xb9\xf7\xdd\x6c\x1f\xb6\x43\xa6\xcd\xd3\xc4\x98\xdc\x12\x59\xaa\xae\x6e\xd5\xe8\x48\x06\xd2\xe1\x53\x2b\x85\xfb\x1f\xf0\x6c\x81\x0a\xcd\x54\x95\x80\xa7\x99\x8e\x91\x05\x29\xd2\x76\x73\x3a\x5c\x7d\x50\x6f\x7b\xd6\x11\xe4\x69\x66\x90\x10\x28\x77\x65\x87\xfd\x37\xad\xab\x70\x93\x73\xe9\xbc\xe5\xfa\x27\x93\x50\x65\xd9\x3e\xf5\x24\x8c\x40\x46\x28\x3b\xdb\xb4\x7e\xda\x6c\x67\x3f\xa3\x28\x94\x18\xcc\x3c\x97\xff\x7e\x9a\x08\xfc\x4d\x7f\x48\xa1\xad\x48\x5a\xe0\x8e\xfb\x99\xf6\xc9\x78\xc6\x23\xd2\x13\xd0\xf0\x31\x33\x00\xe4\xa9\x88\x52\x8d\xde\x8b\x60\xd0\x29\xb4\xdd\xfd\xe9\x4f\x14\x18\x19\x39\x56\x79\x7a\xb2\x53\xb8\xd9\xd9\xb0\xd8\x0f\x33\x09\x49\x60\xfd\x28\x2b\x59\x5e\x96\xc4\x9b\xcc\x1a\x88\xb2\xd4\xe5\x1e\x1b\x74\x5a\x83\x16\xf6\x47\xa4\x8e\xe9\xa5\x40\x0a\x84\x2e\x6d\xb0\x0b\xb5\x8a\x6d\x3d\x15\x37\xe7\x29\xc8\x54\xa4\xbe\x35\xbb\xf5\x0b\x2c\xd5\xd1\xb7\x2f\xc3\x4e\x95\x02\x46\x04\x80\xef\x93\xbc\x1f\xa5\x37\x8c\x1f\xef\xb0\x29\x60\x6c\xbc\x5d\x88\xb5\xb9\x98\xbe\x3c\x32\xb1\x86\x68\xca\x77\x90\xfc\xdf\xc1\xc4\xde\x49\xff\x38\x94\xf1\x9c\x23\xf4\xec\xce\xaa\x22\xa5\xda\x3a\x56\x7a\x84\x11\xe6\xa9\x02\x4d\x5e\x79\x2e\xfa\x0f\xad\xc7\xcb\x8f\x59\x29\xeb\x9f\xb3\x73\x8a\xde\x17\x35\x8f\x2f\x6f\x91\xa9\x8e\x53\x35\xbb\xaf\xce\x5b\xc6\x32\x58\xfd\xba\x9a\x0c\xdb\x0d\x77\x4b\x69\xd8\xc8\xfd\xa6\x9d\xea\x0c\x08\x4b\xf5\xcf\x7a\xbc\x7e\xa7\x5a\x20\x45\x5b\x47\x7a\x33\xb2\xe0\x81\xc6\x53\x94\xd6\x47\xa5\x54\x04\xe4\xf8\x0a\x8d\x0e\xd4\x2d\x9e\xa2\xb6\xf6\x9a\xcf\xd8\xb9\xde\x5a\xf3\x7b\x2d\xdb\x9b\xba\xe9\xa3\x0e\x4a\xb8\x1b\x8b\x6e\xbf\x1c\xe6\xa5\x88\x40\xf1\xe2\xb7\xca\x58\x91\x84\xc9\xb5\x67\x51\x06\xd4\x4c\x21\x0c\x8a\x46\xa7\x4c\xcd\xb3\x48\x58\xf2\x69\x8b\xdd\x72\xc8\x3a\xdc\xc1\x18\x24\x61\x3e\x2c\x79\xea\x01\x7f\x76\xdb\x53\x73\xa6\x42\x34\x8e\xa3\x52\xbf\xf5\xc4\xac\x70\x77\x2a\x4b\xe2\x22\x1b\x14\x18\x5c\xac\xd8\xbf\x9e\xd4\xd7\xbc\x9c\x2e\x65\x49\x8c\xcc\x1a\xf9\x10\x37\xb5\xbd\xba\x48\x46\xe4\x59\x9a\x21\x85\x33\xde\xe6\xc1\x0a\x3e\xe3\x60\x23\x30\x0d\xe5\xb3\xb4\xc8\xbd\x88\xea\xb7\x16\x9b\x76\xf1\x0e\x65\x9f\xae\xdc\xd4\x8d\x7f\xd1\x8e\x71\xee\xa3\x94\x2c\x63\x40\x04\x28\x2a\x9f\x06\x4d\xd2\xd3\x65\xfe\x58\x3f\x5c\x51\x63\x76\x53\xee\xdf\xb0\x39\x53\xa9\x1e\xba\x2f\x3c\xcb\xb9\x05\xc7\x52\x1b\x70\x30\xf2\xf5\x5f\x9c\x8b\x84\x7a\xb7\xfd\x4c\x1d\xfd\x15\x13\x52\x09\xdd\x94\x55\x9f\x77\x37\x65\xf7\xb1\xc5\xd6\x8b\x1a\xf2\xac\xc8\x64\xc1\x07\x0a\xd3\xd3\xea\xe6\x82\xd0\x05\xcf\x0a\x15\xa1\xed\xf9\xbd\x39\x0a\xe5\xf4\xb9\x17\x0a\x52\x15\xcc\xd3\x5c\x7a\x3d\x67\x7c\xf1\x8c\x65\x9a\x34\x22\x89\xa0\xe7\x36\x6e\x9b\x64\xae\x7e\xce\x11\xa4\x3c\x63\x22\xa3\xf9\xbf\xd3\xf8\xd6\x87\x47\x54\xbd\xf1\xc7\x50\x10\x94\xa6\x3a\x1d\xae\xa1\x79\xad\x6a\x8d\x6d\x3f\xdd\x56\xc7\xda\x23\xf6\x78\x26\x84\x2d\x38\x5b\xf9\xba\x19\x59\x79\x94\x8e\x65\x02\x62\xf2\x79\x5a\xbd\x61\xd5\x39\xb1\x9e\x25\x4c\x0b\x7a\x53\xa7\x43\xff\x41\xa5\x84\xc3\x5e\x2c\x9a\x06\x3e\x26\xdb\x7a\x06\x59\x44\xa4\xfd\x50\x7f\xa2\x2d\x70\x13\x4c\x0b\x78\x06\xb2\x70\xea\x12\x34\x0d\xef\x6a\xf8\xbc\x11\x77\x56\x53\x98\x47\xea\x99\xcc\xe2\xc8\xd3\x2e\x08\xe5\x75\xbe\xb1\x67\x92\x87\x7e\xb5\x65\x20\xf4\x1b\x6f\xe7\x05\x2b\x2e\x1a\x1b\xf7\x1f\x32\x5c\x5f\x36\xf1\x6f\xeb\xfd\x2c\x22\xc8\xa4\xb4\x9d\x16\xfb\x86\xed\x2c\x9a\x73\x06\xff\xf4\x43\x35\x10\x1e\xe4\x8d\xec\x6e\xae\x3c\x3a\xf6\xf2\x52\x9e\x29\x65\x31\xf0\xea\x6a\x71\x16\x43\x65\x0a\x6d\xc4\x77\x84\x8f\x4f\x71\x7c\x3c\xd3\x71\x9c\x4a\xdf\xd3\x6f\x5e\xf7\xb8\x6d\x10\x89\x73\x36\x5a\xb5\xc7\x5b\x5d\xa6\x99\x75\x0b\x71\xe1\x5b\x59\x3d\x3b\x44\xd6\xec\xaa\x11\x0b\x9b\x74\x12\xaf\xb7\xfb\x81\xa5\x33\xce\x69\x67\x03\x0d\x58\x6d\xf4\x27\x30\xc6\x85\xb6\x4e\x3e\x77\x06\xee\xe2\x79\xc4\x25\xb7\x56\x8a\xed\x15\xd2\xde\xd3\xaf\xf3\xb3\x47\x9a\x47\x1a\x29\x03\xe8\x03\x8e\x7e\x89\x1a\xbb\xfa\xfc\x15\x96\xc8\x9f\x02\x33\x42\x11\x6c\x4e\x55\xf5\xe1\x17\x87\x3c\x66\x05\xbd\xae\x5d\x50\x70\x52\xaf\xa8\x2f\x82\xc9\x66\x3f\x3c\xd6\x11\xf7\x0c\xfd\x17\x28\xab\xed\xc7\x71\xba\x62\xe4\x09\xb7\x85\x02\x17\x5c\xcd\x99\x1f\x7e\x14\x80\x13\x55\x07\x03\xaf\x30\xde\x38\xf3\x34\xb3\xea\xd6\xc7\x81\x4b\xee\x96\x94\xf9\x0d\x4a\x65\x44\x51\x07\x31\x35\xec\x3d\x0a\x27\x41\xce\xf2\x20\x99\x44\x6e\xfc\xbf\xd8\x64\xf2\x14\x81\x76\xa6\xdd\x9c\xad\x76\x21\x84\xcb\x53\xc3\xa8\xba\x6b\x9a\xba\xea\x9e\x4e\x7d\xe8\x3f\x49\x7a\xf2\x2c\xe2\x0e\x42\x75\x18\x75\x24\x03\x5c\xf6\xc6\x05\x4f\xb4\x2b\x8c\xe9\x2b\xb3\x87\x97\xa5\xb1\x9f\xa1\x5f\xe0\x40\x8e\x6c\x4d\x89\x1d\x34\x1f\xe7\xa1\x62\x9e\x19\x9e\x17\x1e\x6c\x52\xef\xfb\xb9\xe2\xad\xd4\xa6\x67\xcd\x63\xc8\x53\x27\x6a\x33\xdc\xaf\x3c\xd6\xa9\x35\x8f\xdc\x77\x5e\xf1\xac\x0d\x07\xf3\x8c\x20\x49\xd7\x5f\xbf\x5d\x0d\x7f\x83\xc8\x42\x74\x54\x5d\x69\xc2\x05\x3c\x11\x2a\xf8\xb6\x0a\xca\x57\x3c\x2f\xd2\x0c\x07\x49\xf0\x3e\xb8\x3a\x85\xb3\xb2\x14\x22\x39\x50\x69\x1e\x4f\xd5\xeb\x60\x27\x30\xbd\x38\xce\xac\xc3\xc5\x6e\xa2\x10\xe8\x0e\x8a\x1c\xa9\xe2\x77\x3c\x1d\x8f\x1f\x9b\x63\xdd\x74\xe1\x2b\x04\xf2\xc0\x30\xef\x5e\xce\xd4\x4d\x78\x0e\xb1\x26\x30\x92\xb5\xc2\xb4\x4e\xa4\xc3\xde\x9b\x43\x6a\x25\x83\x77\xde\xd3\xe8\x1e\xba\xa6\xae\x36\x65\x33\x52\xd9\x9c\x4d\x25\xc8\x18\x75\x76\xca\xb6\x3d\xa1\x6d\x5e\x5c\x96\x63\x98\x56\xa9\x86\x80\x20\x97\x90\xe7\x72\x24\xef\x4e\x37\x77\x55\xe9\x50\x18\x19\xbe\x4c\x2a\xe9\x29\x98\x1b\x38\x1c\xf7\x84\xf0\xfc\xbd\xac\x9e\xe7\xb9\x75\xae\x62\x45\x3b\x7d\xe7\x25\xd5\x47\x50\x25\x9e\x2b\xb0\x15\xba\x23\xa1\xb1\x56\xd3\xc0\x3c\x57\x50\x30\x67\xb6\xb6\x70\x8c\xe2\x17\xd0\xf5\xfb\x16\x2c\xdc\x7d\x76\x07\x14\x08\x2a\x99\x1c\xe1\xe3\xa6\x84\xbf\xe8\xeb\xe5\x0a\x65\x3a\xf8\x89\x0e\x81\x70\xae\x63\xe1\x01\xac\x81\x10\x50\x37\x57\x1f\x56\xae\x72\x7a\x12\x9d\x71\x9e\x8e\xb4\x4f\xc2\x39\x44\x6a\x55\xf4\x87\x9c\xe4\x5c\x55\x94\xe7\x1a\x35\xe1\xd9\xca\xea\xbc\x19\xf7\x7f\xb2\x01\xff\x0c\xc6\xcd\x73\x2c\x72\xbf\x72\x3a\x29\xa9\x4b\x01\x59\x8e\x22\x67\x22\x74\x8e\x8f\x1d\xee\xd2\xdc\x5f\x8c\xe1\x28\x07\x63\xf8\xba\x39\x8c\xf7\x98\xf9\x3f\xfe\x33\x90\x47\x03\xd5\xf4\x1e\x9c\xa0\x2e\xa8\xee\xd6\x5a\x4b\x5e\x5e\x7a\x8c\x8e\xa9\xb4\x53\xa7\x13\xb4\x0d\xcf\x8d\x49\x45\x50\xe9\xc2\x43\x79\x3a\x2c\xa1\xe9\x27\xdd\x77\x6b\xe2\x38\x7d\x2e\x45\x14\xa7\xca\xc1\x2e\x94\x95\x80\x9b\x76\x1d\x8a\x3e\x1b\x2e\x9c\x42\x13\x55\x21\xed\xd3\xf5\x47\x41\x50\x07\x94\x30\x32\x57\xa7\xa6\x1a\x4b\x83\xfb\x41\x71\xa2\xbc\x9f\x83\x03\xfc\xe9\xd1\xfe\xcc\xfd\xa8\x2c\xb5\xf4\x41\xd2\x60\xb8\xc0\x6f\xef\x87\x14\x3a\x99\xa8\xf9\x4d\x96\xf5\x22\xe1\x89\x74\xcf\xe6\xf6\x68\xda\xaf\xd0\x7a\x0f\xbd\x5b\x7d\x69\xa3\x28\x12\xa3\xa9\xd4\x44\x45\xfd\xf1\x1e\x57\xa4\x4c\x27\x83\xf0\xee\x40\x5f\xe0\x45\xce\x73\x4a\x8e\x6f\x1a\xe8\x9f\xcf\xe2\xa4\xba\x4f\x1a\x40\xd3\x47\x56\xe4\x1a\xb4\x9b\x60\xc4\x14\x3a\xd3\x97\x18\x56\x98\xa2\x88\x23\xba\x52\x75\x6a\x9a\xc7\x52\xf5\x57\xe2\xbf\xbf\x60\xd6\x32\xf6\xe8\x9c\x8c\xef\xe1\xa7\x0a\xef\x64\x51\xa0\x51\xca\x6a\x78\xe2\xa2\x19\x71\xce\x79\xc1\x50\x99\x91\xb6\xf2\xa9\xed\x6a\x5d\x42\x38\xcc\x63\x5b\xca\xe8\xca\x03\xae\xcd\x1d\xb4\x56\x6a\xc9\x17\x75\x20\xdc\x00\x11\xdb\x90\xa5\x0f\x46\xaf\xfb\xfd\x7f\x54\xfe\x2b\x84\x4c\xbd\x75\xf6\xd5\x80\xc9\xf6\x73\xf4\xf2\x8d\x11\xda\x2e\x30\x48\xf8\xe2\x4a\x7d\x0c\xdf\x49\x32\x8b\x83\x92\x0f\x2f\x20\x96\xd4\x19\x7e\xa7\x77\x93\x60\xb7\xfd\x03\x0a\x87\x85\xa2\xac\x6b\xa1\xf5\xbd\x6d\xf2\x21\x91\x15\x26\x6b\x86\x9f\x71\xa0\x0a\x1d\x90\x8d\x4e\xe7\x7a\x16\x52\x17\xe0\xf8\x5a\xfd\x94\xb3\x6a\x4e\xdf\xda\x99\xf1\x1d\x2f\xc0\x30\x42\xa1\xf7\xc1\xc4\xf8\x05\xd8\x0e\x7e\x01\xbc\x90\xa9\xf5\xe5\x92\xd0\xe2\x62\x79\x17\xfe\x5c\x44\x5a\x8f\xa1\xee\x65\xed\x70\x69\xb3\xc9\x2f\x79\x9a\xc6\x2e\x63\x29\x1b\xd4\x36\x26\xbc\xa9\x1b\xb2\x69\x7c\x1a\x0b\x7b\xfb\x4f\x68\x43\xe0\xd7\x0a\x0e\xfd\x5c\xb8\x58\x24\x2d\x54\x82\x24\xa9\x1c\x10\x4e\xfe\xd3\x8a\x33\xda\xe4\x1e\xf0\x7d\xb9\xaf\x2b\xfc\x9c\xca\xc0\x0b\x6d\x2c\xf2\xc6\x43\xa5\x1e\xeb\xf7\x97\x41\xcb\x95\x17\x98\xa1\xd7\x4d\xf2\x0e\x4c\x13\x57\x3c\x5e\x18\x19\x1b\x57\xd5\x75\xec\xa8\xe7\x55\x15\x58\x49\xbc\x30\x3a\xf3\x36\x0d\xc1\x89\x70\x02\x0a\x60\x51\x64\x28\x5a\xb9\xaf\x2b\x20\x9f\x97\xbf\xf5\x56\xb2\x28\xe5\x44\x6f\x6d\xc9\xec\xed\xae\xfc\xcf\xa9\xd4\x7d\xd6\x34\xbc\x8c\x2c\x2a\x22\x16\x54\xfe\xe4\x99\xa4\x22\x67\xe4\xa1\xea\x2e\x8f\x80\x49\xcb\x93\x65\x7e\x8c\xad\x1c\xcf\x0a\x22\x2c\xe2\x11\x91\xf5\xb7\xd8\x1c\xda\xb5\xf9\xb6\xc1\x70\x2d\x26\x26\xd9\x24\x67\x2f\xe6\xe5\x16\x17\xfa\x82\xcd\xc8\x84\xef\xf2\xf7\x7a\xb6\x2c\xce\x24\x25\xf1\x5b\x6c\xbb\x59\xcb\x84\xc5\xa2\xe0\xd6\xf2\x71\xfd\x16\x6c\x05\x89\x8b\x7a\x41\xa9\x9e\xb3\x24\xca\x4d\x34\x32\x9c\xba\xfa\xb8\xbd\x9e\xbe\x43\x2c\x49\x90\xe0\x5c\xd8\xbd\x10\x1e\xc3\x3f\x54\x96\x28\x6e\x71\x1c\xfb\xba\xc5\x2b\xf4\x92\x39\x9c\x65\x12\xc8\xe2\xea\x48\x80\xd2\x7c\x26\x29\xc0\x59\x1e\x25\x34\xdf\x1e\xd7\x7f\x5e\xc4\xd0\xfa\x61\x09\x2f\x9c\xf7\x86\x15\x43\x99\x74\x2e\xfd\xeb\xcb\xf2\x34\xa2\x46\xcf\xfd\x62\xbb\x23\x72\xdb\xe6\xdb\xe3\xe3\xdd\xbf\x76\x77\xb7\xf7\xb7\xbe\xed\xc0\xfa\xfd\x89\x76\x3a\x5f\x66\xfe\x1c\xb7\x3b\xe4\xb0\xac\xe0\xca\xaa\x5a\x23\x01\xb1\x5a\x2b\xf2\x71\x55\x57\xfa\x22\x0c\x92\xb3\x02\x65\x14\x04\x71\xef\x7d\x65\x7b\x36\x88\x65\x59\x3c\xa4\x70\x57\x4d\xa9\x67\x06\xe9\x9c\xf1\x24\xa3\x4b\x5f\xbc\x96\xfb\xda\xbf\x87\x8c\x67\x09\xa9\xee\xbd\xd5\x1d\x5c\xae\xba\x31\xce\xad\x82\x84\xa9\x4f\x4d\xf7\xb2\x0b\x15\x14\x12\xb5\x2d\xc3\xf2\xc0\xb8\xc8\x13\xbb\x1c\xbd\xd5\xaf\xf8\x54\x5f\x76\x06\xe4\x8c\x4b\xe5\xf5\xe0\x17\x5d\x07\xea\x05\xdb\xae\x1e\x6f\xfc\x4c\x44\xb9\x12\x63\x1d\xfb\x71\x29\x89\x89\x02\x1d\x60\xb9\x4f\xc1\xaf\xb6\xdb\xcd\xe4\xcd\xfa\x25\x8d\x67\xaa\x0e\xc6\x99\x94\x05\xdd\xb7\x6f\x9b\xeb\x3f\xbf\xf8\x46\x20\x53\x51\x94\xbb\xb6\xe4\xad\xaa\xfb\x65\x95\x64\xc5\x67\x93\x58\x31\x4b\xc0\xee\xb0\xed\xba\xfa\x98\x84\x4f\x43\x5e\xb8\x85\xeb\x4b\xbf\x27\x35\x1f\xeb\x0a\xcf\x4d\x33\x38\x53\x52\x7b\x15\xe5\x4d\x57\x37\xf3\x07\xa6\x94\x25\xe8\x10\xb1\x72\x75\x7d\xbb\xdd\xa5\xe1\x2b\xd0\xba\x69\x2c\x1f\x97\x2b\xa7\xdf\x36\x31\x5a\xe7\x4c\x03\x8b\xf3\x90\xcf\x7a\x58\xe4\xe4\x39\x68\xd4\x85\xc5\xa4\x96\x7b\x4d\xa5\x81\x30\x2b\x30\xca\xbd\xb0\x2b\x09\x8d\x3c\x5f\xf5\xe1\xce\x78\x1a\x63\x2e\x09\x76\xb9\x79\x29\xcd\xd9\x82\x81\x22\x29\x5c\x5c\x13\x60\x76\x0c\xd1\xa2\x15\x1a\xc2\x3f\x4d\xbb\xc5\x6e\x88\xc9\xd0\xca\x38\xf4\x6b\x0b\x19\x49\x7d\x78\xe9\x37\xce\xa3\x22\x26\x98\xde\xa1\x26\x69\x11\xac\x34\x36\x83\x44\xf7\xf4\x4c\x3c\x32\x92\x62\xd4\x33\x9d\x38\xff\xaa\xba\x71\x31\x28\x9d\x7a\xef\xfc\xd2\x65\x93\x21\xb6\xe0\xb1\x01\x8b\x12\x7f\xf1\x4c\x34\xce\x93\xcc\xc8\x41\xf6\x7d\x59\x76\xe5\xa8\x60\x3f\x5d\x6e\x78\x52\x14\xd2\x26\x96\xcb\x3d\x42\x33\x6a\x6b\xf1\x34\xb1\x3a\x9c\x84\x6a\xe8\xc3\x9b\xaf\xe5\xb9\x86\xcb\xa7\xb4\xb3\xcf\x12\x98\xd1\x23\xe2\xa9\x92\xb4\xd2\x50\xd7\xc0\xca\xcd\x5f\x5c\x14\x79\x86\x39\x19\x3d\x3c\x91\x8e\xfe\x28\x40\xe4\x79\x9a\x53\x33\x94\x84\x58\x0b\x1b\xc2\x3c\xe1\x01\xaa\xa0\xaf\xc6\x79\xc1\x2c\xe8\xfa\x69\x75\xf3\xed\xe1\x7a\xf7\xb8\xbe\xbb\xdb\x5d\x7f\x7b\x5a\x6c\x6f\xd7\x0f\x7e\x0c\xe3\x0c\xdc\x6d\xa6\x20\xcc\x2a\xe7\x4e\xa0\x52\x97\x7f\x1a\x07\x4d\x65\xc6\xc7\x9b\xe5\x72\x4c\x31\xf7\x27\x16\xb1\x8a\x9c\xea\xf3\xf7\xba\x3b\x87\xd1\x4c\x97\x32\x2e\x32\x46\x4b\xc7\xa9\x2a\xdf\xb0\xe9\xc3\x55\xef\x8b\x3f\x62\xcd\x73\x0e\x58\xe0\x48\x40\xf5\x9c\x26\xc6\xb9\xcc\xe3\xd4\xe1\xbe\x82\xce\xbb\x9d\x93\xd3\x48\x90\xab\x24\xa2\xe0\xfc\x56\xfd\x9c\x76\x1a\xa7\x17\xaa\xa4\x61\xb6\xaa\xaf\x1a\x0a\x65\x46\x70\x22\xae\x4d\x11\x27\xa1\x53\x3c\xc0\xf4\xc7\xab\x9a\x1b\x8a\x69\x4e\xa0\xa8\x2f\xf5\x5e\x7f\xc7\xf2\x13\x5e\xb1\x1f\x8c\x8c\x4a\x3d\x36\xa5\xb1\x69\x11\x91\xd7\x46\x0e\x18\x9c\x9b\x38\xb6\x29\xd1\xa9\x7a\x6d\x49\xc0\x84\x82\xcc\x73\xb4\x06\x37\x39\x92\x20\x24\x45\xed\x54\xf0\xbe\xfc\x76\x9a\x7e\x85\x19\x84\x9c\xf7\x65\xe8\xe5\x4d\x97\x40\x6e\x54\x0c\x3e\x8c\x7e\x44\x8a\x7c\xb6\xb5\xe3\x08\x4d\xbf\x5b\x44\xb1\xa1\xb5\x03\x7f\x1e\xa1\x1a\xc9\x84\xf9\xc3\xdc\x26\xe9\x7f\x2c\xee\xc6\x7c\x19\x2e\x22\xe4\x84\x5f\x2c\x55\xed\x49\x63\xa1\x16\x26\xe2\xc8\x8a\x53\x93\x63\x44\x59\x3d\x61\x7b\xda\x77\x67\x49\xcb\xf4\xea\x44\x1c\x2b\xed\x76\x8f\xce\xb5\x29\xa9\x25\x38\xbd\x36\x11\x9b\xd4\xcb\x2b\x3d\x42\x59\x75\xa8\x09\x32\x64\x43\xd8\xb3\x8e\xd9\x3f\xa6\xfd\x0f\x77\x8e\x84\x01\xa9\x10\xfd\x3e\xc2\x15\x88\x34\xb1\xe9\xe0\xfd\xc7\xe4\x42\xd3\x54\xc7\x6e\xdb\xfd\xbd\x2e\x2d\x3b\x70\xf6\x93\xd2\x02\x28\xf5\xdf\x4d\xab\xa0\x97\x43\x7c\x91\x32\x53\x24\xa3\x35\xd6\x79\xf3\x3c\x42\xf3\x0b\xde\xfd\xaf\x62\x23\x91\xc5\x69\x14\x6e\x89\x57\xd7\xa4\x4c\xd7\x3f\xce\xd8\xb7\x70\x45\x16\xf3\xd4\xb1\x06\x14\xd6\xc6\x5f\x65\x56\x44\xdc\x05\xde\xfd\x04\x6d\x3d\xbc\x32\x1c\x77\xc6\xbb\x81\xd8\xb0\x7d\xaf\xc3\x31\x69\x39\x55\x94\xa9\xbe\xc0\xde\x9c\x3d\xb3\x4c\x15\x04\xb8\xfc\xcf\x09\x6d\x45\x77\xde\xf0\x76\xe3\xf2\x82\x51\x67\x07\x9b\xba\x2b\x7f\xf6\x71\x9e\xcb\x3d\x87\x70\x49\xe4\x85\xb1\xf9\xcd\x47\xa5\x6e\x06\x17\x1f\x2e\x72\xce\x94\xf6\x70\x83\xe6\x6d\xf8\x44\x91\x44\x13\xe9\xf8\x2f\x0d\x54\xf4\x2c\xa9\x1b\x77\xf1\x55\x13\x05\xcf\x88\xc0\x7e\xaa\x0c\x29\x8b\xcc\xde\xb3\xf9\x68\x91\xd2\x2a\x44\xbf\x76\x8e\xa5\x3f\x6f\xe1\x08\x26\x2d\xe8\xc8\x9b\xf7\xd8\x06\xe2\x24\x0b\x13\x3c\xcf\x08\x9f\x70\x77\xf7\xe5\x57\x28\x0b\xc1\x39\xb7\x7a\x2d\xd0\x8c\x6b\xb0\xd3\x89\xe2\xfe\x3b\xbd\xdb\x22\xb6\x99\xe0\x80\xcf\xfe\x84\xf4\xcc\x85\x48\x12\x99\x3b\x1e\xc9\x37\x4b\xda\x9b\xad\x23\x82\x03\xf5\x6e\xc7\xd9\xf7\x12\x8e\xe3\x12\xb9\x10\x5c\x11\x7a\xc3\x02\x28\xaf\xc6\x66\xb6\x5c\x08\x10\xa4\x5a\xa6\xc0\x2e\xa6\xfe\xef\x10\xe7\x54\x37\x68\xeb\xea\x79\x5b\x76\xfb\xe1\x00\x70\xd2\xf1\x78\xc7\x92\xdc\x69\x49\xaa\xee\xeb\xfa\xe1\x4b\x18\xa0\xd2\x62\x2a\xad\xbd\x24\x0b\xa2\xe9\x0f\x07\xb4\x62\x5b\xab\xf5\xe6\xcb\xfa\xee\x3a\x7c\xd8\x88\xd8\x21\x37\xec\x84\xf7\x07\x64\xa6\xb3\x60\xee\xb7\xac\xeb\xd7\x72\x6c\x5d\xee\x07\x49\x21\x86\x5a\xe4\x03\x1c\x70\x51\xe9\xcd\xc7\x41\xd6\xfb\x4b\xe5\x33\x21\x11\x88\xd4\x6e\xc7\xaf\x4f\x9f\x18\xb8\x71\xa1\x92\x04\xf4\x00\xc1\xfc\x58\x98\x6e\xd6\x92\x11\x4a\x88\xc2\x67\x4a\x4d\x39\x92\x89\x73\xc7\x75\x9c\x10\x87\x62\xd3\x56\xca\x7f\x46\xe7\x09\x25\x4b\x3f\x6e\xef\xee\x48\x8b\xe4\xaf\xf1\xa5\x42\xe7\x2a\xb3\x70\xf8\x63\xb8\x39\x5a\x09\x12\x3b\x3a\x40\xf3\xba\x68\x5d\xd0\x18\x7e\x19\x46\x60\x3d\xb8\x4e\xe5\x5e\x5f\x6f\xee\x43\xb1\x4d\x18\x66\x28\x71\x7c\x81\xf6\xa9\x6c\xcf\xfc\x4f\x7f\x29\xea\xc6\x85\x01\x2e\xad\xb0\xd8\xc7\xa6\xde\x9f\x02\x7b\xd8\x6b\x5a\x72\x88\x4c\x9a\x38\xe1\xa8\x87\xfa\x7d\x3a\x03\x20\x8e\x0c\xbd\x69\xb0\xdf\x3f\xe1\xfb\x23\x04\x96\x0c\xc4\x89\x14\xc1\x5a\xfb\x83\x5c\xf0\xf5\xbc\x35\x07\x71\x5a\x50\x2c\x45\xce\x53\x6a\x63\xd5\x89\x9f\xb0\x4f\xd0\x86\x13\xc9\x9c\x65\xa3\xdc\xde\xd7\x21\x9c\xb2\xbe\x1f\x96\x40\x4a\x35\x39\x52\xc7\xab\x6b\x73\x19\x9a\x0d\x69\x01\xa4\x0f\x43\x53\xd0\x96\xb8\x08\x06\x37\x7c\x5f\xc6\x12\xc2\xa0\xde\x2d\x97\xe3\xcd\x0c\x32\xa6\x52\xb7\x54\x3b\xc8\x3a\xa5\x0a\xa3\x24\x12\x32\x13\xb1\x64\xb4\x99\xcc\xde\x17\x28\x22\x4b\x4e\xba\xdb\x5c\x9f\xcb\x2d\xf5\x87\x19\x53\xbe\xc7\x31\x16\xae\xf1\x3f\xa1\x48\xb4\xed\xa6\x75\xf5\x91\x98\x58\x43\x4c\x0c\x45\x9e\x8b\xd8\x6a\x1c\x7f\x59\xaf\xaf\x37\x3f\x6e\xb7\x5f\x97\x4f\xff\x7a\xdc\xae\xaf\xd7\xdb\xe5\xfa\x3e\x8c\x33\x56\x87\xd6\x17\x80\xdb\xcb\x35\x00\x60\x71\x2a\x8a\x01\x65\x69\x5f\x99\xd9\x18\x1e\x19\x33\x71\x5c\xe9\x4f\x78\xa6\x99\xec\x07\x2b\x8c\x1d\x5d\xe4\x06\x54\x47\xbc\xb8\xd1\x3a\x3f\x04\x94\x20\x62\xe6\xb3\xf5\xfb\x8f\x1b\x28\x43\x01\x0e\x84\x04\xee\xde\xcf\x4d\x7d\x6a\x14\x4e\xd0\xce\x7e\x90\xd6\x89\xeb\x43\xad\x2a\xbd\xd2\x21\x43\x05\x81\x8a\x85\x3e\xde\xf5\xe2\x78\x9c\x06\xce\x00\x69\x4e\xb1\xcd\xd5\xfd\x63\x83\xbb\xa1\x6c\x0a\x50\x58\xfe\x6c\x59\xe9\xd3\x20\x53\xd4\xff\xdd\xaa\xea\xf8\x7b\x58\x37\xd3\xea\xd8\xc5\x1d\x01\x64\x16\x11\xde\xa4\x74\xb2\xab\x21\xc9\x06\x09\x39\x4c\x15\x0d\xfc\x4a\x3f\x3b\x83\x66\x54\x9a\x03\xad\x09\x78\xb2\xad\xcf\xb0\x43\xe1\xfd\x55\x31\x27\x7b\x10\x43\x61\x89\x6b\x59\x8c\x64\xdd\x38\xa8\x34\x89\x30\x68\xc0\x7c\xe9\x57\xdc\x31\x97\x0f\x54\x9e\x50\xd3\xf8\x00\x3f\x9d\x84\x7a\xb0\xf4\xe7\xa0\x18\x27\x2e\x69\xbf\x13\x4e\x01\x0f\xff\xb8\x58\xe8\x02\x6d\x98\x8c\xc7\x9a\x65\x4d\x7d\xb8\x87\xe6\x15\xbb\xe3\x1e\xd4\xaf\x99\xcc\x1c\x90\x17\x64\x02\x77\xbc\xbd\xa6\x1e\xd0\xce\xff\x0e\xd4\xe0\xad\xc7\x56\xcf\xd6\xc5\x81\x9a\xe6\xee\xb0\xc9\x34\x4d\xfb\x31\xdf\x62\x36\x6f\x4c\x81\x52\x85\x36\x30\x36\x8e\x22\x3d\xd9\xc2\xc0\xb0\x84\x92\xb0\x80\xbd\xdf\xbc\xc0\xb4\x8a\x0c\x86\x67\xc6\xd5\x58\x02\xb7\xdb\x19\x19\x5e\xbe\x26\x63\x04\x31\xe4\xc7\x1a\xab\x97\x73\x36\x19\xa1\xa0\x42\xb9\xd3\xd2\x1f\xa3\x53\x6f\xea\x26\x78\x5f\x72\x19\x67\x11\xf5\x79\x56\xae\x9d\x81\xe1\x00\xd8\x6e\xd3\x13\x51\xa1\x7e\xc5\xac\x74\x1f\x48\x18\xd2\x15\x0f\xb6\x4a\x1f\x94\xde\x9f\x93\xbe\xb9\x4c\x23\x41\x0d\x62\xd2\xed\xd9\x1d\x47\x74\x5a\x99\x66\xcc\xc5\x28\x7b\x75\xbb\xa6\x08\xdb\x63\x24\xe3\xe8\x7f\xfc\x20\x16\x91\x36\xba\xea\xe3\x7a\x02\x85\x4d\x0d\xcf\xb9\xcc\x22\x46\x44\x9f\xd0\xa6\xf9\xe4\x46\xf5\x97\x4f\xe2\xbd\x8f\x5f\x1e\x57\x4f\xab\x2f\x4f\xb7\x0f\xbe\xd6\x26\xb3\x34\x26\x0c\xe3\x01\x7e\xf6\xc9\xd7\x13\x6a\xc4\xc3\xe0\x7c\xcf\x65\x26\x22\x7a\x82\xab\xc5\xd3\xdd\xbf\x76\xb7\x0f\xdf\x57\x9b\xed\xfa\x69\xb7\xb8\x5f\x7f\x7b\xd8\x86\x41\x06\xa8\x20\xf6\x05\xbb\xe5\xbe\x54\xaf\x63\xf2\xb0\xcc\x45\x0c\xb9\xd3\x63\x86\xfd\xfa\x38\x5f\xeb\x65\x0e\x3c\x87\x11\x02\x7d\x55\xe9\x63\x5d\x56\x53\x0a\xa3\x2c\xb8\x05\xd2\x40\xdb\x96\xcf\x15\xf1\xcb\x27\x6a\xaf\x17\xf7\x74\x59\x48\x99\x0f\x85\xeb\x11\x76\xf8\x4c\x04\x95\x4b\x96\x4a\xdf\x35\x20\x53\xad\x3e\x26\xda\xd4\x7b\x7d\xc1\xf6\x97\x4b\x96\x69\xc2\xf9\xdd\xd5\xcf\x8f\xf5\xbe\x54\x1f\xab\x9f\xc7\xb2\x99\xb7\xab\x24\x53\x16\x65\x45\x8a\xfd\xc3\x33\x4c\xa2\x70\x9c\x53\xa4\xe3\x1b\x35\xbf\x83\x7a\x7d\xac\xcf\x7e\x99\x01\xfa\x65\x96\x0c\x10\x34\xa6\xb8\xe4\xa9\x24\xa8\x17\x1c\x8f\xfe\xde\xfa\x23\xda\x82\xb0\xda\x51\x85\xe4\xb1\xa9\x9f\x1b\x38\x7c\x92\xdb\xba\x0f\x02\x43\xaf\x01\x41\x37\x19\xcf\x93\xe0\x4f\xfe\xf5\x27\xd0\xb1\x0b\xcf\x15\x1e\xbb\x49\x24\x75\xfe\x7c\xa4\x16\xe4\xb2\xfc\xbc\xaf\x25\xec\xb7\x23\x78\x95\xbf\x10\x05\x39\xd5\x12\xc1\x0a\xfc\xe2\x27\x8a\xe7\x5c\xea\xcc\xee\x75\xb7\xcb\xf5\x6e\xb9\x78\xf4\x1b\x89\xd4\x05\x66\xd6\x72\x99\xf2\x85\x0a\xdb\xd6\x01\x1b\x3f\xf9\x4d\x5a\x9b\xd4\x29\xd6\xaa\x13\x2e\x28\x9c\x1b\x9b\x8e\xfa\x61\x68\x45\x05\xda\x7e\x6b\xf6\xbb\xde\xfc\xc9\x61\x2e\x69\x89\xd9\xe9\x7a\xc2\xcc\xff\x65\xaf\x62\x14\x00\x48\xe4\x2c\x8a\x7c\x65\x0a\x5a\xec\x27\xc8\xb1\xfe\x84\x00\x2d\x4d\xa2\x3d\xee\x91\xa8\xa0\x57\x75\x7d\x59\xb3\x88\x4b\xa3\x35\xa5\xe2\x0d\x9a\x53\x8b\xe7\x4b\x9f\xdf\x34\x55\x14\x23\xf5\x1d\x37\xaa\x24\xad\x5a\x77\x5f\x55\x1c\x89\xc8\x83\x6e\x9c\x11\xb8\x9f\x59\xd6\x52\xde\x8d\x4b\x30\x82\x22\x94\x9b\xb6\x35\x85\xc0\xed\xad\xd9\xd4\xa6\x5b\xc2\xf1\xa1\xee\x7c\x94\x3b\xf9\x81\x2a\x2d\x90\x9c\x1c\xda\x34\xb2\x27\x8c\xfd\x01\x96\x50\xbf\xbb\xa4\xdf\xbc\xe9\xf0\xd8\xce\x3f\xca\xac\xa8\xca\xaa\x69\xea\x89\x43\x18\x57\xa9\x34\xa9\x18\x48\x9b\xcb\xba\xac\x24\xb4\xb3\xb8\x49\x65\x91\x20\xe0\x48\x10\xb0\xc4\xfd\xbe\xb5\xa2\xba\xfe\xf2\x73\x96\x48\x67\x87\x79\xab\xea\xb1\x9d\x6b\x7f\x8c\x53\x70\x7a\xfd\xcd\x3b\xed\x72\xc5\x94\xb1\x09\x36\x2d\xb1\x97\x9b\x86\x17\x27\xb6\x62\xc8\xc8\x93\xcb\xa0\x7a\x21\x64\x13\xed\xf6\x57\x1f\x54\x43\x7a\x38\x1d\x66\x17\xcf\x19\xa7\x7d\xf1\x00\x3f\xa9\x73\x4b\x88\xa8\xb9\x80\x2d\x57\x5c\x5a\x5b\x13\xe2\x40\x10\x8e\x75\x55\xe9\xeb\xa1\xec\xa9\xb8\x04\x9a\x79\x04\xff\x59\xc2\x5e\x3d\x86\xbe\x95\x12\x8c\x05\xa1\x18\xf8\x79\x8d\x3f\xc9\xeb\x73\xfa\x3b\x04\x28\x6a\x48\xe9\xfa\x24\xf7\x18\xbc\xdc\xa6\x37\x1a\x00\x28\x0d\xfe\x76\xdc\xd7\xa0\xef\x4f\x6d\xa9\xe6\x39\xe3\x18\x8d\x71\x79\x95\x57\xa0\xa3\xdc\x56\x52\xeb\xd7\x99\x0f\x14\x57\x32\x41\x0a\x4c\x17\xbf\x5f\x8f\x93\x18\x25\x53\x49\x8c\x9b\x2f\xd8\x7d\xab\x8e\x7d\xba\x36\x3d\xa9\xcc\x94\x1c\x95\xa1\xed\x2e\xf0\x48\x6a\xf5\xfe\x14\x98\xc4\x69\xe1\xab\x60\x63\xbd\x23\xae\x50\x30\x42\x75\x5a\xe8\x2f\x91\xb7\xca\xff\xe2\x17\x98\x4d\x55\x1d\x15\x8c\x22\xad\xb2\xd2\x2e\x95\x9a\xb6\x92\x74\x04\xcc\xc5\x01\x7d\x74\x73\x16\xdb\xfa\x51\x0a\xa8\xfc\xb0\xfd\x76\xfb\xb0\xda\xfe\x58\x3f\xfd\xe1\x3f\x1f\x47\x4a\x04\xbf\xb4\x6f\x55\x59\x4f\x18\xd4\x3a\x49\x53\xad\xbc\x54\xcf\xb8\x10\xa6\x13\x21\x48\x95\x65\xd7\x62\xb7\x3e\x75\x6d\x07\xb6\xf7\x5d\xbf\xcf\xd1\x86\x3a\x8d\x59\xb0\xfd\x5b\x36\x1f\x6d\x07\xfb\xcb\xab\x8e\x4e\x53\xcc\x3c\xe6\x26\x28\xb6\xcf\x02\x1b\x9d\x8a\x94\x47\x5e\x79\xfe\xa6\x3e\x35\x63\x44\x8b\xce\x22\x46\xa5\x47\xeb\x54\xd6\xfc\x2d\xeb\xa4\xf0\x51\xa4\xc0\xeb\x6f\x99\xb4\x73\x9d\x09\x1d\x5b\x22\x45\xd3\xe2\x03\xbe\xd3\x92\x6a\xbf\x2a\xc9\xa6\xad\xcd\xb9\x52\x88\xce\x14\x88\x84\x7a\x4f\xb7\x07\x78\xc6\x75\x75\x5e\xb0\xd7\x99\x96\x71\x16\xea\x02\x17\x7a\x94\x3a\x8f\x90\x04\xcc\xfb\x0d\xcd\x5f\x7f\x11\xe5\x54\x27\xdd\x36\xa7\x89\x16\x80\x2e\xb8\xa4\x5c\x6a\xf7\xec\x9c\x8a\x96\x75\xdb\x8d\x3a\x7d\x0e\xe9\xc6\xfd\x70\x69\x75\xb3\x9f\xeb\xbd\x1e\xf4\xde\xb9\x66\xb9\xf5\x75\xa6\xb2\xc0\xb7\x56\xcf\xca\x2f\x9a\x09\x46\xf6\x39\xdb\x72\xdf\xef\x07\x53\xcd\x17\xcd\x00\xe8\x16\xbf\xd4\xa7\x16\xb7\xf5\xf1\xdb\x31\x1c\x91\x3a\xb1\x84\xd6\x69\x27\xe6\xf2\xa3\x22\x7c\x7e\x50\xdf\x45\x6d\xa5\x7b\xac\xb6\xee\x68\x7f\xd4\x22\xd2\x54\x13\xbe\x5a\x7c\x5d\x2c\x17\x67\x05\xa7\xf1\xda\xaf\x05\xb0\x80\x1b\x81\x3d\x5e\x82\x13\x6a\x00\x43\xe5\xa8\xdd\xb1\xc1\x43\x10\xcd\xe6\x5a\xca\x98\xa3\xb7\x63\xa8\x9b\xd3\xe1\xdc\xb9\x8f\x6b\x55\xc4\xb9\x27\x38\x42\xd3\x40\xd5\x7d\x5c\x44\x5f\x6a\x65\x32\x13\xd4\x27\xf7\xfb\x8b\x49\x98\xd6\x71\x66\x2c\x95\xc4\xc0\x69\xdf\xf5\xbb\xcc\xf8\x3d\xc0\x82\x5b\x64\x59\x5d\x77\x92\x3a\xdd\x0b\xa5\xb0\x6d\x9d\x1c\x63\x18\xc6\xac\x2a\x48\x87\x6d\xf7\xa5\xdf\xaa\x15\x96\xc7\xce\x57\x8c\x46\xf5\x7f\x8d\xd2\xd6\x5e\xb1\x6a\x4f\xe4\x58\x53\x5d\xcc\xb8\x35\x9a\xc8\xf6\x99\xca\xaa\x1b\xa6\x8d\xe1\x05\x01\xcd\x6e\x4e\x1d\x34\xea\xe5\x23\xfc\x1d\x0d\xbd\xf1\xa7\x63\x8b\x4d\xff\xd2\x9f\x17\xb4\x07\x5c\xc0\x74\x12\x60\x94\x4b\xaa\xe7\x95\x55\xbf\xfa\x58\x50\xfa\x59\xc0\xff\x7f\x41\x97\x06\x32\xda\x5c\xc5\x7e\x1a\xc3\x62\x9c\x80\x4e\x07\x4d\x84\xb5\xa1\x34\x6f\xbd\x9f\x10\xb8\x31\x4e\x23\x25\x82\xf7\x9b\xdc\xcf\x77\x37\x8c\xf3\x88\xb0\x4c\x77\xf5\xb3\x5d\x72\x2e\x2f\x34\x98\x24\x9c\xb9\x79\x63\xb3\xe3\xef\xfd\x03\x6f\xad\xf6\xf6\x6f\xb3\xb1\x4a\x47\x9e\x6c\x7e\x03\x65\x88\x99\xaf\xd0\xd4\x0d\x4e\x45\x11\x39\xa6\xa9\x10\x8e\x37\xf1\x72\xf6\xf3\xd2\xcc\x12\xc5\xb0\xd2\x13\xd4\x1e\x66\x85\x42\xa7\x38\xd9\xcf\xa8\x45\xa5\x49\xd7\x88\x0a\x79\x33\x54\xc9\x94\x2e\x4d\x84\xea\xf0\xbf\xfc\xd9\x78\x46\x6d\x44\x5d\xaf\x5a\x05\xae\x4e\x38\x93\xe4\xc1\x4c\x14\xf4\x95\x6f\xfd\x95\x3b\x9d\x5c\x27\x0e\xef\x7f\x55\x21\x33\xaa\x57\x92\xfe\xed\x1d\x3e\x83\x0a\x3f\x98\x47\x51\x34\xee\xcd\x6c\x50\x9d\x9a\xb2\xfb\x98\xf7\x5b\xa6\xd7\xcf\x39\x90\x58\x5f\x85\xef\x9e\xbb\x39\x7b\x3e\xe1\x1a\x38\x07\xbb\x58\x96\x6f\x38\x05\x32\x7e\xfa\x09\x50\xa4\xc3\xf6\x82\x3f\x37\x5d\xe3\xf8\x11\x93\x58\x14\x45\x22\xa8\xfc\xf3\xaf\x53\xf5\x7b\x09\xf7\xe5\x64\x72\x09\x61\x45\xe3\x9c\x23\xd5\xa4\x0c\x85\x42\x5b\x06\x25\xd5\xc5\xa8\x7a\x38\x9d\x24\xc2\x30\x7a\x45\xbf\x60\x85\x4d\xa9\x06\x9f\x88\x5f\xa6\x6e\x28\x33\x14\x3c\x74\xba\xc3\x8b\x9a\x0f\xad\xa7\x62\xb6\xcf\xa1\x94\x46\x59\x91\xa9\x43\x59\xd9\x05\xc8\xcf\xc8\xe6\x5c\xc2\xc4\x7f\x48\xa7\xf4\x7a\xfd\x71\xf5\xc7\xe4\x9a\x55\x6c\xa5\xf0\xfa\xb9\x7d\x8d\xfa\xa4\xc6\x70\x08\x54\x45\x4c\x1d\x09\x55\xef\xeb\x2a\xc8\x0a\x0f\x47\xf3\xd8\x8c\x2c\x64\x5f\xf7\x70\x55\xea\xb9\x0a\xe8\xf8\xdf\xd8\x5f\x83\x8e\x92\xb4\x08\x68\x7d\xdd\xd4\x47\xc7\xbb\x18\xf6\x19\xd4\x5c\xc7\x6e\xcc\xd6\xc6\x69\xd3\xa3\x96\x78\x74\xb0\x3d\xec\xfe\x8b\xf7\xfb\xfa\x3d\x6c\x9a\xa8\x4d\x4e\x1c\x07\x9a\xbb\x5f\x63\xff\x67\x4c\x53\x70\x76\x4e\x4f\x3a\x98\xa0\x71\x44\x66\xcd\xf4\x02\x69\x7f\x89\x55\xd7\xfe\x40\x7c\x1d\x48\xe5\x68\x72\x61\xcc\x48\xab\x74\xf3\xd1\x76\x17\x32\x8b\xff\xe3\xbf\xfe\xe4\x1a\x69\xfa\x5d\xff\xf9\xaf\xf1\x23\x32\x91\x8c\x29\x2b\x7b\x7c\x5a\xed\x7e\xdc\x3e\xec\xee\xbf\xdd\x6d\x6f\x1f\xef\x56\xbb\xc7\xd5\x93\x1f\x13\x47\x82\xb8\x80\x12\x81\x78\x38\xe1\xef\x49\xe6\x9d\xbd\xfb\x0c\x9f\x54\x96\x26\xdf\x6a\xe2\x4c\x13\x5c\x78\x59\x1f\x8e\xa7\x0e\xef\x3f\x46\xa0\x55\x93\x44\x45\x1a\xf9\xdd\xb5\xdf\xba\xfd\xb6\x39\x7e\xa9\x4c\x92\xe6\xa8\xbc\x43\x16\x6d\x9c\xce\xa3\x35\x9c\x06\x13\x1f\x82\x0e\xfc\xe0\xdf\x6b\x69\xf7\xe9\xbf\xd8\x5d\xc2\x39\x18\x75\x2f\xee\xaf\x96\x03\x12\xdc\x64\x85\xa4\xb4\xef\x0e\xe1\x38\x9a\xb8\x26\xe3\xb6\x68\xec\x42\xa5\x55\xd5\xef\x15\xb3\xfe\x8f\xc9\x53\xeb\x97\xe5\x22\x63\x12\x3f\xb8\x18\x17\x98\x3e\xce\x23\x51\x28\xec\x2c\x97\x68\xbb\x85\x59\x80\x61\x0a\xb4\xb6\xd2\xa4\x6b\xfc\xaf\xdd\xea\xcf\xe5\xd7\xc5\xc3\x97\xd5\xee\x29\xf8\xe1\x71\xc3\x72\x4d\xbc\xe9\x43\xfd\x86\x3b\x5b\x9d\x9b\x10\x6f\xb8\x1f\xa7\x73\x16\x8d\xc1\x31\xb0\xbf\x25\xc7\xce\xbf\x19\x76\x1b\xc1\x52\x2a\x32\xde\x58\xde\x39\x36\x5b\x68\x9e\x31\x3c\x10\xc1\x38\xd5\x27\x83\x6e\x00\xd1\x76\xdc\x41\x88\x50\x38\xf0\xcd\xf6\xaf\x14\x68\xfc\x47\x90\xd1\xae\x7b\xbb\x5c\xef\x1e\xbf\x2e\x36\xab\x78\x67\xad\x57\x1e\x57\x4f\xcb\xd5\xc3\x76\x11\xa0\x86\x46\x72\xe0\x7c\x24\x7f\x4b\xfd\xfe\xe9\xdd\x56\x89\x15\x5b\x71\x6c\xcf\x7b\xf8\x39\xc9\xf5\x8d\x12\xa8\xec\x29\x4e\xd5\x6b\x71\xdb\xda\xae\x87\x3f\x88\x8a\x8b\xe0\x94\x85\x4f\xe4\x69\x58\x56\xcf\x5f\xa0\xb5\xe1\xfe\xb0\x86\x18\xcd\x8b\x62\xc4\x1c\xde\xef\x97\xf5\x1b\x36\x94\x3d\x84\x57\x00\x93\x94\x84\x0d\xdb\xff\xcc\x9e\xb7\xc9\x85\x53\xec\xc2\x66\xa7\xe0\x18\xfa\x28\xc6\x28\xeb\x77\x75\x6c\x50\x63\xbf\x3c\xd7\xd3\x04\x59\x44\x51\x9c\xdb\x97\x6e\xfd\x70\x73\xfb\x65\x77\xbf\xf8\x73\xf7\x7d\x71\xf7\x6d\x15\x8e\x67\x28\x63\x0f\xb9\x77\xa8\x22\xee\x8f\x31\xee\x9d\x2b\x57\xeb\xcd\x1f\xf8\x71\x53\x5f\x16\x53\x12\x51\x64\xa2\x38\x1a\x2a\x2f\xbf\x4d\x8f\xc6\x11\x12\xc9\xce\x49\xff\x7a\xf0\x43\xb8\x3f\x22\x8a\x85\xa2\xa2\x0e\x56\x23\xbf\x53\xfb\xe0\xf9\x18\x97\x23\xa2\x18\x52\x8a\xae\x9d\x2b\xd6\x38\xd1\x1c\xdf\x35\x11\x25\x32\x71\x8e\x90\x3f\x47\x50\x7b\x11\x25\x8e\x88\x40\x32\x8f\xf5\xb7\xb2\xea\x46\x81\xb2\x88\x12\x13\x83\x9a\xf0\x67\xc2\xbd\x4c\x0c\x4b\x5c\x37\xca\x66\x8b\xe3\xcc\x56\x44\x7d\x34\xd6\x7f\x21\x54\x55\x7d\xb2\x42\x80\xd5\x27\xbd\x10\x11\x65\x85\x55\xb8\xba\xd9\xde\x3c\xf8\xee\xc6\x68\x2d\x16\x51\xa6\x24\x29\xe6\x3c\xc3\xc1\x6b\x88\xce\x2e\x30\x07\xa0\x84\xc4\x97\x97\x27\xea\x9d\x22\xca\x4d\x5e\x4c\x88\x1e\xa4\x9f\xeb\x0e\x16\x29\xa3\xe8\xe8\x8b\x2d\x04\xff\x76\x2e\xf2\x24\x48\x26\x8d\x1c\x88\xea\x1b\xc4\xc7\xba\xfa\x6f\xf9\x5b\x38\x62\x61\xc6\xdb\xe5\x6a\xf2\x9b\x45\x9a\x72\x70\x3e\xec\x5f\x11\x9a\xee\x0a\x61\xe0\xfb\xb9\xe5\x63\xf2\x1d\x22\xb3\x62\x74\xd8\xbd\xb8\x8c\xcd\x1f\x10\x9c\xe4\xe3\x3e\x93\x4b\x1b\x3f\x32\x81\x9c\xc4\xfd\x36\x60\xb0\xbf\xc8\x81\xc7\x32\x9d\x86\x10\x1b\x61\x61\x30\xc7\xd2\xa2\x72\xfd\xb7\x49\xc6\xd1\xbd\xca\xd6\xd0\xcb\xe6\x02\x5f\xa1\xd2\x73\x6f\x0e\x11\x49\xae\x29\x47\xde\x3c\xde\x5e\xaf\x9e\xc8\x64\x63\xf7\xb4\xfa\x67\x38\x97\x14\x29\xa9\x05\x75\x6a\x00\x1a\x8a\x48\x9a\x94\xb0\xad\x7b\x34\x5d\x22\x66\x8f\x52\x45\x31\xa1\x1e\x50\x97\xb6\x65\x79\xd9\x99\x52\x44\x0a\x25\x85\x05\xa7\xea\x1a\xf7\xf8\xec\xb3\xd4\xb3\xd4\xc7\x0f\x37\x16\xa7\x7a\x5d\xc2\xa1\xae\x34\x69\xe4\x4c\x9e\x98\x4e\x52\x29\xbc\xe3\x7b\xf5\x3a\xbb\x52\x9d\x5b\xac\xc1\x97\xeb\xf5\x42\xbf\xfd\x22\xfd\x16\x91\x16\x19\x25\xac\x03\x9b\xa8\xa5\x8e\xc5\xec\x84\x42\x90\x7e\x6f\xb0\x79\xf6\x34\xc4\x25\x1c\xb7\x25\x36\xf1\xec\xbe\x60\x9e\x15\xae\xf1\x5e\x56\x21\x84\x12\x11\x72\x36\x8a\x07\x1f\xf0\x7d\x73\x92\xdd\x25\x08\xe8\xec\xf6\x21\x14\xc6\xd9\xaa\x90\x91\xf7\x3d\x54\xf0\x4c\xdb\xde\xa5\xdd\x58\x44\x26\xb3\xdf\x7f\x24\xc9\xaa\xeb\xd1\xe3\x34\x22\xa1\x39\xf7\x5a\x76\x9d\x43\xee\x12\x9c\xde\xa3\x37\xed\xb0\x38\x52\x16\x2b\x2e\xfb\x5b\xf5\xc7\x87\xfe\xf8\x3a\xa7\xd4\x8b\x38\xce\x99\x37\x85\xda\x60\xe3\xbc\x34\xe7\x46\x02\x7e\xac\xd4\x86\x4d\xe1\xaa\xa3\xbe\xd7\x7c\xb0\x46\x5a\x2a\xff\x59\x1f\x8f\x30\xc4\x2c\x22\x4e\x74\x4a\x8c\x0f\x8f\x3a\x76\x35\xa0\x5f\xde\xbb\x38\x31\x20\xad\x1a\x5b\xf5\xa3\x19\xeb\xad\x4c\xa6\x5c\x9c\x46\x12\xe2\x51\x77\x99\x7a\x02\x17\x2b\xe2\xe1\x03\xc6\xdb\x94\x2e\xf6\x7b\x87\xac\x6c\x6f\xea\x66\xb1\xdf\xd3\x19\xd6\xd5\x14\x04\x2f\xe2\x34\x2f\x94\x83\x02\x3d\x36\x7d\xc0\xfe\x3c\xbf\x4f\xa9\x51\x34\xd1\xf6\x88\xaf\x9b\x0e\x61\xff\x58\x77\x3b\xff\xf1\xac\x28\x28\xd7\xd8\xc9\x53\x53\xfd\x76\xc1\x8c\x5b\xc4\x19\xa4\x44\x40\x50\xb5\xa9\x4f\x95\xc6\xa6\x1d\x07\x06\x22\xce\x63\xcb\xf6\xa2\xca\x2a\x25\xb2\x8f\x4d\xf9\x5f\x6c\x7f\x58\xd5\x94\x30\x2c\x35\xb4\x88\x9f\x88\xa7\xe6\x6a\xc0\xd3\x1d\x3a\xce\xb5\x24\x65\x9c\x55\xa5\x85\xff\x5b\x91\x58\x40\xfe\x33\xf6\xeb\xa8\xb6\x4b\xe3\xd0\xe6\x17\x71\x21\x62\xba\x03\x8b\xe7\xa6\xa4\x95\xec\x01\x7f\x76\x83\x0f\xb6\x88\x0b\xb0\xd2\x8c\xed\x4b\xfd\xee\xcd\xaf\x2e\x77\x05\x45\xcc\xd2\x8c\x30\xc3\x4f\xeb\xab\x55\xf7\x32\xee\xb5\xfb\xb3\x31\xc3\xc9\xeb\xf8\xf7\x1a\xaa\x6a\xac\x4f\x20\x62\x91\x19\x74\xc6\xa9\x33\xbd\xdd\xc9\xec\x01\x26\xa4\x83\x0c\x7d\xaf\x3b\x5c\x54\x64\x5d\x7a\x79\x95\x8b\x81\x01\x41\x39\xd6\x47\x2b\xfd\x6c\xc3\xae\x71\xaf\xc0\x0f\x54\x3c\x2a\xc6\xd6\x96\x75\x87\x56\x31\x6f\x3a\x29\x65\x6a\xd5\x87\x7c\x09\xe1\xbe\xdc\x63\xdb\xd5\x55\xb8\x40\x09\xa9\x76\x88\xa3\x06\xfb\xfb\xb8\xa8\xf4\x48\x47\xd6\x8d\x52\x1a\xa9\x2b\x76\x5d\xb6\xf2\xd4\xb4\xb4\x70\x5c\xdc\x23\x62\x9d\x58\x63\x9f\x2f\x8b\xcd\x98\xd9\x24\x62\xcd\x22\x8a\x38\xed\xca\xf5\xbd\x6c\xe1\x2c\x2b\xb9\xe4\x80\x24\x62\x2d\x25\x85\x2d\x2e\xee\x21\x0d\x17\xcf\x00\xe9\x8f\x2a\x62\xd0\xfa\x37\xc5\x69\xec\xff\x15\xb7\x61\xfe\x15\x86\x78\xb0\x14\x84\x5d\x95\xfa\xa6\x6e\x1e\x4f\xd5\xeb\x6c\xb9\xd2\xc6\x50\x98\xea\xc3\x8e\x9b\xa6\x3e\x50\x49\xcb\xff\x16\x4c\x8d\x57\x57\x77\x33\xa2\x7d\x29\x8f\x4e\x37\xfb\xb3\x9a\x8a\x88\x51\x58\x19\xe3\x16\xf7\xfb\xaa\xd6\xf3\x55\x12\x05\x14\x16\x18\xf8\x31\x5e\xca\x10\x81\x9b\xd1\xaf\x21\xa4\xf4\x35\xd4\xfe\xb8\x49\x8c\x87\x66\xd3\xa1\x06\xab\x8b\x5c\x2c\x91\x44\x3c\x11\xb6\x80\x7c\x28\x2b\x8a\x8b\xda\x6e\xf3\x52\x1f\x07\x4d\x6f\x91\x44\x3a\x25\x10\x10\x81\x44\x9d\xb2\x49\x38\x24\xbc\xcb\xea\x83\x73\x3c\x68\x89\x2f\x1a\xb8\xfa\x01\xd0\x7c\xe9\x29\xb8\x98\x3b\x89\x33\x20\x9c\xb6\x65\x48\x8e\x0c\x26\x44\x12\x73\xa4\x66\xcf\xd1\x89\xb8\xfa\xbf\x27\x98\x13\x82\xcd\x49\x42\x5d\x70\xec\x99\xdc\xc9\x24\x8d\x0b\xcf\x1a\xf6\xa9\x8a\x6d\x1e\xce\x86\x15\x31\xc9\xa8\x2f\x1b\x30\xdd\x01\xf7\xc3\x17\x66\xb1\x45\x82\xbe\x43\xbb\x39\x51\x55\xc8\x9c\xf6\xe1\xa0\x91\xd4\x59\xba\x3d\x04\xe6\xba\x48\xf2\x28\x86\x28\x50\x52\xbd\xa4\xd3\x38\xae\x4f\xf2\x98\x83\x95\xd8\xff\x65\x75\x6f\x76\x2d\x45\xa4\x2d\x63\xe8\x34\xff\xf9\x45\x52\xd0\xf9\xae\xca\xae\x8f\x7a\x76\x30\x59\x75\x93\x22\x31\x64\xc5\x54\xb6\xbb\xb6\x7c\xae\x3e\x8b\x30\xc3\xcf\x2b\x72\x4e\x35\x1e\xd3\x20\x7e\x21\xe9\xc6\x5a\x9f\xd4\xdc\x0e\xcd\x0f\x66\x8c\x4a\xdb\x55\xdd\x41\xbf\x2d\x6c\xdf\xeb\x33\x75\x39\x91\x14\x32\x4d\x60\x04\xf8\xdc\xf4\x1b\xc8\xfc\x2a\xb0\xa0\xa2\xd9\xff\xf6\x81\x1b\xc2\x61\x76\x98\x45\x68\x5c\x5d\x21\x5c\xe0\x64\x21\x4a\x58\x81\x24\x56\x52\xd5\x1d\x69\x73\xfb\xeb\xe7\x79\x46\x3c\x1c\xe5\x41\x7e\x22\x81\xc4\xba\x90\x92\x60\xb3\xad\xf6\x2d\x9c\x05\xf2\xf5\xe5\x9d\x23\x81\x5c\x11\x33\x44\x63\xdb\x35\xf5\xc7\x6c\x9f\x4e\x20\x37\x04\xb7\xbf\xc6\xb7\x7a\xff\x86\xcd\xce\xe9\x8b\xcf\xae\x02\x94\xa0\xdf\xe2\x94\xee\xae\x3e\xae\x2e\xdf\x56\x99\xe4\x3e\x4a\xb7\xe2\x09\x97\xb6\xee\x44\x39\x21\xfa\x03\xfc\xdc\x7c\xd9\x4e\xb6\xed\x44\xa7\x1a\x33\xcf\x81\x5d\x54\x1f\x5f\x60\x1e\x8d\x25\x5a\x23\x69\xdf\x5c\x75\x84\x1f\x18\xef\x75\x09\x2a\x43\x45\xea\x86\xde\x7c\x8b\x1c\x19\xd7\x6e\x45\x62\xd2\x22\x71\x01\x26\x75\xe9\xae\x6b\xfb\xef\x98\x69\x31\x9b\x59\x46\x68\xa2\xcf\x5c\xaf\x1f\x88\xd8\xb5\xfb\xb1\xb8\xbb\x5b\x6d\xc3\x19\x31\x77\x3a\xae\x95\xa6\x96\xff\xe5\xb7\x3a\x8d\x84\xe5\x4d\xff\x17\x9b\x7a\x1a\x61\xa4\x91\x49\xe8\xd0\x3f\xbf\x4f\x85\x27\xfb\x23\x85\x76\xa1\x27\xe1\x96\x9b\x09\x11\x6c\x3a\x36\x8e\x14\xad\x07\xf7\x65\x75\xea\xf0\x00\x93\x5b\x93\xc6\x0a\x0b\xc7\x2f\x59\x54\xe5\x01\xf6\x63\xa6\x82\x48\x13\x95\xaa\xc2\x07\xde\xa5\x95\x99\x1d\x9b\x69\x8a\x34\x65\x85\xf7\x0c\xb6\x7e\xb4\xb3\xaf\x27\x69\x49\x6f\x83\x4e\x6f\xec\x8c\xa8\x2c\xd2\x14\x0a\xaa\x65\xd5\xc6\x90\x1d\xf4\xf4\xc9\xa6\xa9\x14\xa9\x95\x26\xae\xf0\xfd\x1e\x0f\xd2\xc1\x77\xfd\x61\xb4\x42\xc1\xad\xd7\x91\xbf\x08\x18\x16\x69\xce\x52\x5f\xcb\xbb\x3a\x7d\x4c\xa2\xa5\xe9\xf7\xe5\x3c\x77\x96\xff\xf0\x8c\x93\x79\x98\xe6\x46\x91\x37\xe0\xd5\x4b\x59\x55\xf8\x0a\xb3\xaf\x28\x12\x28\x06\x6a\x00\xcd\xf5\x7e\x09\x99\x0d\x2a\xac\xcb\xbe\xae\xdf\x2b\x5d\xd7\xb3\xf5\x2f\x65\x12\xad\x90\x3b\x05\x1a\xe4\x80\x61\x39\x00\xdf\x8f\xc6\xe2\x92\x3f\x7e\x9b\x7a\xd4\x86\xfd\x68\xde\xf5\xbe\x1c\x2e\xa4\x0c\x0b\xca\xf6\xc3\xbe\x33\x7a\xde\x64\xd5\xe2\xb2\x80\x3e\x52\x99\x89\x89\xcd\xce\xc4\x0b\x45\xb3\x63\x8f\xcf\xcf\xe5\x7d\xfb\x3c\xbb\x14\x2e\x91\xde\xe8\xa7\x5a\xbd\x6e\x54\xd9\xb6\x75\xf3\x08\xc7\x79\xcc\x95\x8a\x08\x8c\xdb\xea\x5d\x8f\x09\x9e\x71\x8a\xef\x9b\x7d\xaf\x40\xee\x82\x64\x68\xf0\x65\x64\x48\x27\x52\x61\x0a\x5a\x59\x83\x5c\xd5\xe7\x58\x02\x91\x02\x2f\x2c\xd5\x15\x3a\x7c\x0f\x5e\xfa\x22\x05\x95\x13\xb9\xf0\xfe\xf6\x61\xb9\x78\x74\x0e\xae\x03\xde\x5a\xa4\x80\x82\x4a\x09\xab\xed\xd7\xdd\xea\x1b\x15\x30\xfd\x21\x95\xa1\xe7\xc7\x39\x4d\x3f\xdf\xb0\x9d\x2c\x1f\xa9\xca\xad\xb7\x98\x2d\xb0\x92\x9a\xb0\x3f\x85\x8e\x63\x9f\x8a\xf5\xef\x5b\x3b\x55\xba\x98\x5d\x83\xce\x8d\x76\xc5\x3e\x1b\x76\x97\x75\x35\xf1\x84\x16\x29\x8a\x22\x75\x54\xd3\x07\x7c\xf7\x05\xf8\x33\x64\xba\x48\x4d\x1e\x53\xab\xe9\x30\x72\x10\x98\x6c\xe0\x71\xc2\xfd\xbf\xf6\x23\x59\x94\xdb\xfe\x8f\xfd\xfa\x6a\x09\x95\x26\x01\x46\x7f\x2f\xb3\x38\x8e\x89\xb2\x7d\xb3\xbc\x5f\xae\x6f\x7f\x85\x05\x10\x59\x9c\x48\xaa\x37\x6a\xdc\x5f\xd5\x97\x1b\x84\x22\x8b\x59\x4c\x25\xcb\x7e\xfb\x87\xee\xd4\xe0\xd5\xa9\xa9\x7c\x6f\x68\x7c\x8b\xb3\x04\xb4\xcf\xc6\x1e\x6d\x99\x74\x83\xa1\x2f\xe7\xb4\x85\x44\x96\x25\xba\x28\x26\x7a\x39\x03\xee\x2e\x5c\x45\x96\xe7\x2a\x0b\xec\x0d\xfd\x0b\x39\x9b\xc9\xd3\xc9\x32\x91\x7a\xb1\x9d\xc5\xa3\x5b\xde\x87\x7b\x93\x61\x4a\x29\x74\xbf\x22\xea\xa1\x1f\x78\xf9\x54\x79\x5a\x90\x7e\x0a\x2d\xdf\xd6\x7a\x77\x12\x88\x5e\xbc\xa3\x8c\x5b\x66\xf6\x8e\x80\x23\x94\x96\x5f\x93\x74\x90\x0f\x8d\x33\x11\x67\xd4\xb8\x68\x0f\xad\xf3\x01\xd1\xd4\xb8\xba\x3a\x86\x9f\x29\x8c\xf2\x72\xba\x56\xb2\x75\x59\xef\xf7\xd0\x61\x43\x25\x8f\xd9\xeb\x9c\x49\x91\x91\xeb\xe9\xd5\xd3\xfa\x8f\xd5\xd3\xee\x69\xb5\x59\x3d\x7d\x5f\x39\xb9\x08\x7f\x4a\x95\x08\x22\x78\x1d\xb1\x31\x75\x73\xa0\xc2\x44\x12\x0e\x66\x22\xb6\x92\x6a\xa4\x88\x5b\xca\xd1\x86\x95\xa9\xc2\x08\x3e\x76\xe6\xba\x81\x72\x1f\x0e\x72\x49\xf2\x60\xd6\x98\x84\xd8\x8e\xe1\x10\x58\x84\xce\x93\xb5\xf0\x3c\x75\x2f\x75\x33\x12\x7e\xf4\xa3\x74\x8e\x18\xea\xfd\x8f\xf5\x4c\xf5\x53\x64\x3a\xe7\x84\x1d\xde\x55\xf8\xfe\x65\x50\xe5\xbe\x64\x52\xfc\x77\xfb\x7a\x22\xd3\x32\xcf\xe4\xa0\x15\xb8\xb3\x08\x3e\x6a\xa6\x3e\xd5\xfb\xfd\x2c\xee\xca\x8c\xe4\x45\x90\xdb\xb1\x26\xde\x57\x27\xfd\x8c\xe7\x16\x29\x22\x8f\xb8\xf2\xd2\x3c\xb6\xd1\x81\xda\x99\xe8\xfe\xe6\x47\x60\x06\xde\xfd\xf1\x01\x7f\x76\xe7\x90\x27\x91\x47\xc6\x8a\x93\x10\xaf\x85\x10\xa2\xcb\xaf\x37\xb3\x31\x31\x67\xb6\x59\xe0\x99\x07\x56\xe9\xe4\x12\x86\x4a\xe4\xb1\x4c\x41\x0d\x82\xea\x7a\x50\xc3\x76\x03\x92\x84\x13\xd0\xef\xe4\xe4\x7f\xe7\x12\x8d\xfd\x08\xcd\xcc\x20\xbc\xa7\x87\x8e\x42\x38\x87\xca\xa3\x6c\x90\x2f\x0d\xc4\x9f\x39\x8b\xd3\x0d\x4f\xd3\xd4\x7b\x37\x07\x44\x1f\xea\x33\x25\x1b\x91\x67\x91\x4d\x79\x40\x6b\x12\x88\x3a\xf8\xdc\xe7\x92\x6d\xf5\x7c\x19\xbd\xe0\x2f\x2f\xf2\x2c\xd6\x64\x11\xa8\xcb\xf6\x3f\x27\xd8\x97\xe6\xe3\xaa\xd4\xf3\x6f\xe5\xa2\x08\x44\xd4\x7e\x81\xfa\x56\xb5\x33\xa4\x94\xc8\xf3\x54\xd2\x22\xe1\xfe\x7a\x8d\x6f\xfe\x66\xe4\x80\x41\x0b\x76\xb8\xcd\x2c\xe3\x71\x34\xdf\x3d\xc6\x8c\x12\x91\x33\xc5\x23\xe6\xa5\xe4\x6f\xea\xe6\x75\xa8\x93\xe5\x4c\x23\x91\xe8\x4e\x23\x3d\xa7\x49\x3f\x20\xe7\x20\xf3\xc8\x42\xee\x68\x55\x9d\xb4\xe0\x45\xce\x8d\xa5\x2c\x4f\x84\xee\x2f\xf1\x55\x63\x3f\x73\x04\xd7\x46\x8f\xac\x97\xaf\xb0\x1b\x37\xbf\x72\x21\x75\x6c\x89\x0b\x13\x48\xef\x14\x40\x2d\x72\x10\x82\x5b\xd7\xc7\x6f\x21\xdd\xcd\x65\x21\x58\x10\x8f\x46\x68\x48\x55\xa8\x54\xb8\xac\xf5\xa4\xa0\x94\x4b\x89\xa4\x60\x6f\xca\x41\xa3\xe6\xea\xe3\xbe\xd6\x5b\xfc\xd9\x4d\xa7\xa9\x54\x5a\x8e\x65\x37\x7e\xc9\x8d\x10\xb9\x8a\x18\xc9\x40\x3e\x9f\x08\xe3\xd3\xce\x71\x9d\x22\x57\x26\x57\x01\xf4\x30\x40\x7f\xdc\x51\x9d\x03\x1b\xa9\x8f\x13\xce\x78\x3e\x04\x42\xeb\x90\x04\x22\x3c\x61\xf1\x72\x80\x91\x6b\x95\x2b\x13\x64\x53\xbe\xdf\x3e\xce\x4e\x87\x69\xe1\xd9\x59\x56\x99\xe6\x07\x58\x77\x6e\x7f\x57\x31\x17\xc4\xd5\x75\x8c\xb1\xef\xf5\xd9\xd4\x46\x2e\x40\xf9\x36\x0e\x54\x2d\x69\xad\x9e\x47\xe6\x39\x02\x23\xe4\xa5\xbb\xb8\x4f\x7e\xb0\x49\x0c\xa1\x42\x3a\xf4\x02\x39\xa2\x88\xa2\x28\x19\x5b\x2d\x2d\x8c\x09\x87\xd2\x98\xa0\xd9\xfd\xbd\xd8\xd9\xf7\x79\x3f\xdb\x16\x8a\x88\x59\xe9\x48\xef\x81\x3a\xdf\x16\xa8\x9c\xa1\x46\xb3\x72\xf5\xb3\xec\xa6\x2b\x71\x11\x8b\x98\xf0\xb8\x68\xdd\xe9\x46\xc2\x6f\xb3\x73\x25\xc6\x0a\x32\xed\x9e\x27\xb5\xe3\x22\xcd\x02\x90\x71\xf3\xe8\x83\xca\xe9\xef\x4c\x45\xca\x06\xcf\xaf\x7f\xd7\x07\x59\xce\x15\xbe\xfc\x48\x19\x53\x21\x9c\xba\x2f\x1e\xc7\x79\xf1\x7e\x16\xa9\xce\xa4\xf7\xeb\xf0\xb6\x9c\xae\x54\x3c\x5d\xd4\xdc\xf8\x2c\xb5\xe8\x69\xdb\xe5\x08\x1b\x4d\x91\xf1\xd8\x99\x68\x98\x53\xa5\xaf\x11\xf4\xbe\xac\x70\x10\x80\xe9\x47\x58\x3d\xdd\x67\x74\x0a\xf6\xd3\x3b\x98\xcb\x88\x7e\x88\x41\xf5\xb2\xd8\xef\x6f\xea\x26\x84\x9b\x57\x1f\xb6\xe4\x36\xfd\xe5\xb9\x44\xda\x28\x0f\xd4\x2e\x6a\x56\xdb\xaf\x72\x90\x0b\xed\x0f\x1b\xa6\x07\x44\x9d\x7f\x0f\x86\xe3\x2a\xa3\xda\xb7\xf2\x1a\x38\x0f\xd7\x8b\x75\x38\x68\x0a\x3b\x67\x4f\x47\xf2\xc7\x7b\x2b\xf7\xf8\x8c\x84\xee\x0d\x23\x34\xe5\x52\x77\xf0\xf3\x50\x52\xed\x73\x16\xfb\x9e\xe6\xc4\x6b\x51\x14\x91\x35\x77\x71\x62\xb9\x67\x68\x1c\x51\x14\xa9\x42\xe3\xab\x4f\x1d\xec\xa7\x91\xad\x1b\xc4\x62\x43\xf3\xd5\xa9\x91\x9e\x51\xa5\x44\xc1\xb2\x98\x05\x0e\xd4\x91\xae\xee\xfc\x85\x2b\x98\x32\x9e\x2a\x18\xc2\xd3\xc1\x8d\x62\x3a\x96\xa7\x39\x71\xeb\x08\x93\x6d\x91\xf5\xff\x3c\x61\xc8\x56\xfd\x28\x1e\x45\xde\xf6\xca\x2b\xf4\xf6\x0f\x72\x5f\xe2\x27\x5a\x3f\xe1\xf1\x73\x93\x14\x63\xab\xd1\xf1\x8a\x5c\x88\x88\x53\x15\x7a\x07\x1a\x8f\x63\x95\x4a\x51\x88\xc2\xc4\xe0\x6f\x86\xb3\x29\x98\x70\xb8\x45\x21\x44\xee\x25\x32\x1e\x6f\x77\xa8\xcb\x6e\x17\xa7\xd3\x1f\x2e\xc0\xb6\x2e\x1f\xd7\xcb\x2f\xfe\x63\x10\xc7\xa9\x9b\xaf\xcb\xf2\xf8\x72\x6e\x0a\xe8\xc7\xa5\x8c\xc2\x27\x22\x90\xf6\x1b\xd6\x50\x3f\x29\x80\x83\x64\xa3\xb5\xcf\x76\x04\x6f\x70\x7e\x7b\x01\x34\x95\xec\xea\x79\x14\x43\x4f\x37\x6c\xd7\x05\xa8\x94\x42\x89\xe7\x13\x3c\x9f\x7c\x5b\xa9\x90\x99\x35\x57\x94\x65\xb7\x3f\x1d\xb0\x6a\xaf\x71\x5f\xbe\x0d\xb4\x72\x51\xa8\x48\x51\xab\x08\x28\xd9\x5c\x9b\xbb\xfa\x2d\x98\x40\x8b\x42\x65\xb9\x8c\x43\xed\x99\xd4\x1d\xa7\x3f\x4f\x09\x5d\x98\xf0\xea\x36\xdd\xd7\xfa\xd4\x3c\xef\xa1\x9d\xe5\x64\x85\x32\x29\x75\xd9\xeb\x6a\xff\x71\x8d\x03\x48\xa3\xd0\x2c\xa3\x1e\x4d\xdb\xd5\xc7\x1f\x75\xf3\xea\xff\x8e\x09\xd3\xd6\x16\x72\xbc\x62\x5e\x4c\x0d\x0b\xcc\x18\xb5\x38\x36\x4e\xa3\xab\x39\x4c\xf6\x3f\x8f\x36\x1e\x6e\xbe\xc9\x22\x4a\x7e\x0e\x65\x85\x83\x5e\x4c\xff\x77\x20\x5b\x21\x9a\xf4\x94\x64\x78\xcd\x94\x4b\x2b\x1e\x4b\xb8\x5d\x28\x0e\x1e\x87\xe4\x5b\x96\x2c\xe5\x9a\x30\x83\xce\xa4\x78\x62\x92\x21\x58\x96\x2b\xcb\xe2\x7a\x81\xa6\xfc\xcf\xa8\x3d\xc2\x32\x23\x32\x35\xf0\x68\xcb\xff\x7e\x8a\x12\xfd\xcb\x7f\x7f\x99\x7a\xb0\x5c\xa5\x84\x88\xbd\xfe\xe3\x8f\xdd\xfa\x50\x95\xba\x4f\xed\xfc\x64\x62\x85\xc8\xd0\x85\x0a\x37\xe5\x1e\x2f\xe1\xe6\x05\x2b\x50\x80\xed\x6d\x77\xea\x65\xbc\x41\xf8\x6f\x4b\x93\xe9\xed\x62\x89\xe1\x6e\xae\xb8\x72\xde\xb8\x06\xc5\x18\xe7\xd4\x31\x5b\x5c\x3f\xae\x7f\x78\x00\xa3\x60\x4c\xf0\x74\x80\x85\xfd\x81\x78\x56\x49\x62\x9c\x01\xb5\x79\x2a\x7c\x9f\x19\xd6\x4e\x7f\x80\xe0\x48\xd1\x80\xeb\xc9\x1d\x1b\x2c\x55\x3d\xde\x1a\x98\x10\x8a\xcc\x7e\xfb\xd9\x38\x82\x0f\x30\x21\x70\xa2\xd1\xb1\xad\x37\x74\xe2\xd9\x2d\x11\x86\x51\xb2\xf9\xde\x6f\x3b\xfd\xf2\x7c\x53\x37\xbf\xaa\xe2\x30\x99\x16\x56\xe0\x94\x36\x6e\xca\x39\x7c\x14\x3c\xf9\xe5\x32\x43\x74\xe2\x5e\xdb\xda\x33\xfc\x3e\xe9\x0f\x33\x99\xe7\x94\x21\x9d\x7b\xef\xfb\xe2\x07\x93\x22\x23\x71\x92\x03\xea\xd2\xf6\x87\x5b\xa7\xb6\xe2\x0a\x9f\xb3\x33\x2a\x13\x76\x0d\x6a\xf1\x53\xc5\x77\x52\x6d\x62\x2a\xb5\xb7\x68\xa1\xf5\x97\xd2\x5c\xac\x93\x4c\x0d\xe4\xfc\xe7\x4c\x4a\x45\xfa\x7b\xac\x9e\xc7\xeb\x37\xd3\x99\x85\xaa\xb7\xd8\x3d\xdc\x6c\xe7\x44\xd9\xe9\x7d\xd4\x79\x4c\x32\x85\x2f\x7d\x3a\x32\x44\x16\x4c\x2b\xd4\x03\xf3\xeb\x0e\xde\x3f\x3e\x5b\xac\x99\x36\x40\x93\x83\x16\x6b\xbf\x45\x5d\xc0\x8d\x31\xe4\x06\xdc\xea\xbf\x7d\x41\x4f\x5f\xf2\xdf\x68\xe2\x98\x40\x4b\xf7\x65\x35\xac\xa3\x3c\x8a\xf3\xc8\xd9\xc0\x9c\x19\x03\x7d\x82\x72\x0d\x9f\x64\x94\x86\x5d\xaf\x7f\x3c\xec\xde\xcb\x6a\xd4\xe6\xe7\x49\x1c\x09\x27\xaf\x75\x0d\xe5\xfe\xe3\x7b\xdd\x2f\xf2\xfd\x42\x33\xb9\x3b\x3c\xc9\x80\x47\xa3\x28\xf8\x9c\x22\x2f\x78\xc2\x81\xc8\xbf\xc7\xa6\x3e\xd4\x8f\x70\x6a\xc3\xb7\xa4\x51\x44\xfc\xcb\xe7\x7a\xaf\xaf\x51\x51\xb3\x20\x1c\xe3\x52\x3b\x7e\xa3\x03\xa7\x90\x8a\xbe\x3f\x9c\x99\x48\xc5\xae\x19\x72\x8f\x6d\xdb\x87\x6a\x67\xae\xb1\xe3\x26\x1b\xcf\xa3\x8c\x2e\xe9\x50\x56\xa7\xf6\x86\x74\x9a\x56\xbf\xc2\x1e\xf0\x22\x96\xb4\x85\x9b\x7d\x5d\x37\xa8\x37\x27\xf9\xd9\x40\x2c\x32\xd7\xf1\x70\x13\x77\x7a\x9c\x09\x2b\x1a\x54\xc1\x01\x5f\xa0\x7d\x99\x84\x01\x9c\x17\x05\xed\x0c\x67\xe9\xdc\x74\x94\x02\x1e\x08\x7c\x9f\xc9\x7e\x0a\x2e\xb2\x2c\x09\x2e\xf3\xad\xd5\x99\xb3\x1d\xb2\x33\x6c\x41\xd8\xb3\xb8\xc8\x0b\x70\x8e\x3f\xeb\xbd\x93\x97\xba\xad\xbe\x96\xfd\xe4\xfb\x70\x9e\xa8\xd3\x2b\x02\x96\x50\xb6\x0a\x5a\x13\x7f\x9e\x44\x32\x6e\xa7\xdb\xa2\x6b\x23\x8c\x0a\xbc\x93\xe0\x8b\x03\x4b\x89\x38\x4a\x56\xdf\xd7\x27\x1c\x2d\x8a\x1c\x64\x41\xf5\xea\xb6\x82\x63\xfb\x52\x4f\x3a\x0a\x1c\x90\x13\xeb\xe1\x09\x09\x9d\x3c\x08\x48\x5c\x6a\x02\x72\x29\xac\x30\x7b\xd9\xae\xaa\xfa\xf4\xfc\x32\x0c\xbf\x80\x74\xe4\xd2\xe4\x24\xeb\xe6\x0a\x3c\x3e\x22\x5a\x9b\xd5\xf6\xeb\xe5\x05\x82\x2b\x9e\x52\x2d\xb3\xaa\x83\x44\xe7\xe3\x05\x4e\xc4\x8c\x3a\x28\xb8\x96\x86\x92\x2f\x97\xbd\x7d\x66\xaa\x3d\xbb\x1c\x8d\x48\x55\x2c\xeb\xd7\xaf\xea\x66\xa8\x9d\x70\x4c\x33\xab\x23\x65\x37\x21\x8a\x54\x06\x89\xb7\x30\xaa\xc8\x09\xa6\x2d\xfb\xcd\xd5\x82\x2a\xad\x12\xd8\x69\xe4\x8c\xf8\xb9\xb9\xe4\xac\xec\xc1\x91\x5b\x66\x48\x8b\x1d\xc9\x16\xfe\xba\x1a\xc1\x51\x5a\x13\xba\xa0\xfc\x85\x97\xac\x10\xfc\x60\x6d\x0b\x45\x47\x5b\x20\xf7\x36\x4b\x93\xdd\x81\x9b\x88\x59\x6d\xc1\xf6\x09\xff\xd7\x0a\x8b\x4e\xcf\x62\x64\x96\x7b\x26\x00\xe2\x58\x65\xa8\x5d\x90\x89\x44\x77\x6a\xb7\x2f\x0d\xb6\xfd\x12\x1f\x6e\x93\x51\x16\xc7\x7c\xf7\xb1\xff\x2b\xf3\x3a\x21\xa2\x38\xd7\xc2\x93\x29\xaf\x4e\x4d\x85\x7a\x6d\x82\x58\x52\xf8\x29\x22\xca\x54\xe4\x54\x75\xeb\xb6\xec\x26\x85\x2d\x11\xe5\x52\x4b\x4f\x33\xbe\xa9\x9d\x89\xb6\x72\x58\xf9\xa0\x8c\x26\x44\x2c\xa5\xa3\x7e\xbf\xe2\xe6\x88\xcd\xac\x62\x23\x62\x93\x07\x1b\xa8\xb2\x7a\xee\x97\x38\x4a\x88\xea\x41\x51\x54\x88\x24\xc9\xac\x45\x67\x83\x3f\xc7\x9b\xa3\x48\x84\xed\x0a\xf8\xc9\x2c\xc7\xca\x6b\x42\x24\xce\x39\x47\x0d\x70\x96\x7b\xf8\xd9\xef\x0c\x17\x9f\xa1\x48\x63\xa4\x4b\xfe\xe7\x8f\xba\xd6\xd7\x8b\xf5\x5f\xb3\x42\x85\x48\x0b\x45\x5a\xa9\x37\x77\x68\xcd\x1c\x2f\x46\x23\x22\x45\xce\x1c\x33\x66\x83\xfb\xbd\xaf\xad\xcd\xee\x79\x96\x58\xa2\xab\x83\x7f\x6c\xe0\x00\x4d\xd9\x41\x35\xe9\xc3\x8a\x0c\x22\xc2\xa5\x5c\x6f\x7c\x91\x21\x3c\x97\x9c\x21\x55\x4f\x2a\x7c\x27\x40\xe7\x54\x31\x6f\xfa\x65\x39\xb7\x3e\x8a\x8f\x4f\xab\xcd\xe2\x6e\x65\x1b\x7d\xbb\xdb\x87\xdd\x8f\xd5\x6d\x38\x9f\xc8\x52\xe1\x97\xf2\x5d\xf3\x32\x12\x86\x99\x16\x71\x45\x2e\x80\xb6\xac\xdf\x97\x3f\x96\x7f\x3d\x09\x73\x34\x5e\x07\xf7\x85\xfc\x2c\x34\x4e\x80\x35\xa2\x80\x82\x52\x87\xfb\xcd\xe3\x63\x1f\x8a\xd8\x3e\xe7\xfd\xd8\x61\xf2\x93\x7f\xfd\x09\xa4\x85\xf6\x5e\x95\xdd\xf2\xa5\x6e\xf4\x19\xe1\xcc\x8f\xc3\x88\x60\x1c\xd6\xe2\xef\x76\xbb\xde\x1d\xfa\x1f\x34\x11\xf8\x13\x82\x33\x93\x86\x2d\x6d\x31\x93\x53\x13\x82\x0b\xe5\xe5\x8d\x96\xa6\x5c\xb5\x5d\x79\xc1\xb6\x47\x08\x11\x15\xd6\x73\x8c\x84\xfd\xae\x3a\xe5\x3f\x2f\x44\x66\x35\xc0\x4f\x72\x62\x33\x36\x7d\x60\x10\xc5\xbe\x40\x74\x35\x7c\x37\xe4\x40\xaa\x0f\x64\xa0\xb4\xaf\xd5\xeb\xee\x2d\x21\xbf\x75\xf7\xe1\x30\x0e\x0b\x2a\x4c\x99\x7d\xfd\x8e\xcd\x62\x2c\xeb\xd7\x1f\xb4\x4e\x40\x65\xfb\x63\x52\xe3\x16\x52\xe4\xa4\xf3\xa2\xbc\x86\xd6\x7b\xd5\x76\x2f\x65\x7b\x80\xea\xe3\x31\xbd\xf6\xc3\x54\xa6\x98\x6b\x92\x2d\xe1\xd8\x9e\x13\x6a\xfd\x1a\x2c\x14\x03\xca\x16\x4d\x83\x68\x5b\xfb\x3e\xb2\x71\x03\xb4\x52\xca\xed\xf0\x5b\x84\x83\xcd\x91\x6c\xdc\x1b\x86\x68\x8c\x98\x8b\xb7\x46\xbc\x1d\x21\x30\x02\x12\xb7\xdc\x97\x6d\xf7\x08\x65\xd8\x48\x04\x66\x31\x35\x81\x25\xa8\x57\x0c\xc5\x59\x61\xb2\x08\x68\x2d\x7c\x69\xea\xf7\xf6\xc7\x0b\x56\x8e\xad\x5a\x56\xcf\x0f\x75\xb7\xaa\x34\xea\x11\x30\x1a\xa2\xc8\x50\x21\xe0\x56\x8d\x7d\x22\x05\x44\x49\x5e\x78\xd7\x11\xac\xda\xba\xf9\xac\x9c\x08\x51\x1a\x51\xd5\xad\x2b\x8f\x77\xb5\x7a\x25\x12\xeb\x34\xb2\x86\x48\x19\x0b\xf7\xa1\x54\x6f\xf9\x02\x87\x63\xfb\x30\x96\xa6\xbf\x14\x3b\x40\x9c\x39\xa4\x49\x59\xbd\x6e\x70\xef\x0b\xbc\x90\x48\xdb\xe0\x82\xf6\xe0\x64\x1a\xa7\x9f\x4b\x39\x67\x56\xcc\xd7\xc6\xfa\x33\x95\xb0\xcb\x57\x91\x72\x43\xf7\xd9\x20\xea\x38\x8a\x16\xfd\xde\x3d\x2b\xe4\x42\x2a\x18\x73\x1b\x62\xbf\xd5\xf5\xf3\xca\x33\x42\xc2\x08\x9b\x3a\x5b\x9b\x92\x85\x0e\x51\xd1\x04\xd1\x31\x59\x38\x20\x95\x88\x66\x64\xed\xfb\xed\xe9\xf6\x62\x89\x17\xb2\x2c\x4d\x87\xbb\xb8\xf2\xa6\x50\xbf\x5c\xcc\x21\xcf\x18\xf5\xcc\x5d\x89\x7d\x51\x69\x32\xa9\xba\x88\x75\x9d\xfe\xae\x3c\xcf\x55\x14\x14\xe2\x2d\x2b\xfe\x93\xef\xc8\x25\xa1\xf3\xdf\xea\x0e\x1f\x1b\x0c\xfd\x87\xe9\xa8\x42\x58\x0c\x36\x75\x2e\xcf\x10\x5b\xc0\x62\xab\x84\xd2\x67\xc2\xd0\xbe\x5e\x5e\xe7\xff\x5e\x11\x04\x58\x6c\xc8\x12\xd0\x20\xb6\x8f\x4d\x6d\xca\x6e\xa2\xf7\x21\x80\x69\x29\x2d\xaa\x84\x2a\xc1\x4f\x64\xb8\xda\x0e\x47\x2d\x67\xef\xf1\x69\xb5\xbb\x5d\xae\x77\x9b\xdb\x07\xef\xa0\x2d\x80\xeb\x94\x34\x08\xeb\x0a\x57\x21\x0c\x02\x91\x01\x55\x0e\x77\xb6\xc0\xd3\xe1\x72\x0f\xe5\xe1\xb7\x4b\xcd\x41\x10\x4c\x52\x69\x6d\x47\xfd\xde\x0e\x9f\xeb\xe6\xe3\x56\xcf\xaa\x30\x00\xa9\x56\x66\x94\x81\xf9\xcc\xd5\x7f\x23\x14\x42\x0d\x82\xd9\x37\xfb\x32\xc8\xe6\x08\x00\x26\x09\x04\xb6\x3b\x94\x33\x47\x15\x01\x32\x8f\x48\xcd\xea\x76\x83\xf8\xbd\x2e\xd5\x84\xed\x04\x92\x43\x94\x0e\x9d\xeb\xe9\x42\x06\x92\x5b\x4c\xa9\x76\x9c\x97\xc5\x99\x81\xf4\xec\xbb\x40\x80\xb4\xb0\x1a\x1b\x6c\xcd\x58\x44\x6e\x98\x4a\xad\xfd\x43\x43\xe4\x0d\x8d\xcd\x24\x32\x03\x1d\x2b\x9f\xe0\x7d\x6b\xb1\xb1\xb6\xe5\x17\xfb\x25\xa0\xb9\x7d\x97\xb6\x57\x9b\xed\x1f\x71\x38\x01\xb7\xc2\xe3\x16\x12\x4c\xf0\xe3\xd0\x1c\xbd\x40\xc6\x14\xa0\x85\x26\x1c\x11\x51\x8a\xc8\x3f\x7d\x1a\x44\x00\x26\x82\x34\x3b\x09\x52\xb6\x4b\x77\x76\x89\xd9\xd4\xfb\xb0\x12\xa0\xc8\xc8\xfc\xc5\x0a\xd6\x10\xc9\x85\x34\x99\x3e\x0b\xd0\x3f\x99\xc9\x08\x3c\xf7\xa5\x35\xf8\x49\xe4\xcc\xe9\x6b\x63\xa2\x38\xb3\x8d\x30\x53\xee\xf7\x13\x9d\x5e\x01\x26\x93\x31\x09\xb3\xd7\xf8\x73\x54\x8d\x04\xc3\xad\x8a\xea\xb8\x29\x39\x99\xa3\x32\x4a\x32\xfa\xde\xbb\x3a\x6c\x9c\x32\x52\x48\x11\xc3\xf5\xf2\xfb\x78\xce\xc8\x38\xd5\xc4\x56\x36\xa7\x4a\x37\x50\xf6\x41\xaf\x65\xec\x8d\x9b\xf7\x32\x66\xd6\x6f\x64\xb7\xdb\x1d\xfb\xbb\x61\xf3\x62\x77\x30\x49\x20\xd3\x41\x2d\xd1\xd2\xc3\xc3\xb1\x34\xf2\x5a\xd1\x14\x60\x6e\x8e\xe8\x68\x61\x23\x37\x38\x21\x93\xdc\x92\xcf\x70\x04\x04\xbc\x55\x75\x38\xdc\x07\x60\xfd\x6b\xdb\x94\xcf\xfd\x86\x38\x2a\xb7\xc8\x34\x42\x52\x33\x87\x3e\x99\x5e\xd9\x84\x70\x3a\xb1\x64\xc6\x2d\x23\xfb\xee\x76\x71\x75\x7b\x77\xbb\xbd\x5d\x6d\xfc\xa7\xf3\x22\x27\x2e\x93\x2d\x45\x59\x64\xed\xe6\x74\xb8\xbc\x5b\xca\xdc\xa1\x33\xfc\x8c\xf8\xa5\x98\xb3\x90\x85\xeb\xbd\xed\x1c\xfd\xc5\x7f\x29\x73\xf2\xbc\x2d\xee\xf7\x5f\xb0\xc2\x4f\x78\x6a\x92\x29\xcb\xa1\x06\xad\x6f\xad\x74\xe7\x6d\x87\x67\xbf\xed\x1f\x17\x21\x0e\xee\x14\xbc\x30\x3c\xf3\x16\x8e\xd5\x7f\xcb\x0b\x42\xc5\x42\x72\x4c\x29\x36\x75\x7a\x9d\xd8\xdf\xc5\x49\xa1\x45\x72\xc3\x98\x93\xbb\x38\xd6\x4e\x47\xfb\x0d\x9b\x8f\x3f\xd0\x67\x01\x12\x32\xc8\x26\x1a\x85\x07\x28\xf7\xd3\xb3\xc8\xc8\x52\xae\xfb\x28\x1b\x0f\xe5\xa0\x8d\x2a\xa4\x4c\x63\x8a\x43\x6e\x1a\xd4\x93\xf9\x29\x59\x4c\xa1\x8c\xad\xc5\x7e\xb1\xd8\xc0\x70\x50\x24\x1e\x2f\x3b\x80\x2b\xa4\x14\x96\xaf\x57\xb6\x54\x16\xdd\x1c\x41\xe1\x15\x74\x41\xd1\x5a\x48\x15\x5b\x33\x4d\x52\xe7\x1d\x32\x45\x27\xef\x3c\x7d\x08\x2a\x8b\x88\x18\xa0\xf1\x0d\xf7\x75\x1f\x1b\x6c\xbd\xe4\x80\x0a\x9c\xf9\x7e\x98\x95\xe5\xb4\x2a\xe6\x83\xa2\xb0\x3f\x2c\x22\x42\x90\x3f\x62\xb3\x9f\x5c\x9f\x8e\xad\x81\x04\x89\x95\xcc\x98\x7b\x52\xa7\x5c\x64\xd4\x42\xa9\xf4\xd4\x5e\x6e\x36\x53\x74\x6e\x79\x1d\x2f\x81\x6b\x2f\xa4\x16\x1c\xb2\xb0\x70\x0e\x30\x13\x89\x32\x8a\xdd\x06\xab\xf3\x68\xf6\x95\x26\xe1\x56\x8c\xa6\x82\x4a\xbd\x84\x0a\xaa\x34\x05\x66\x14\x27\x9f\xba\x93\x6d\x9f\x8c\xe9\x2a\x2a\x32\x8c\xb9\xde\x84\xab\xac\xdc\x87\x38\xc0\x2d\xcc\x2a\x8e\x23\x8b\xa4\xfc\x2f\x01\x2c\x57\x43\xb1\x6f\x7a\x35\x2a\x4e\x94\xe7\xf2\x3d\x58\x0f\xbf\x03\x56\x63\xe2\xa0\x8a\xc1\x2a\x33\x51\xd1\xe0\xb6\x6d\x4f\xfd\xc2\x39\x62\x6e\xa9\x24\xc7\xc2\x99\xca\x51\xab\x68\xf5\xd3\xf1\xca\xc3\x00\xc9\x48\xdd\xfe\xfe\xf6\x61\xb9\x7e\xd8\x3e\xdd\x5e\x7d\x1b\x0c\x41\x84\x4a\xb9\xa4\xa8\xbf\x6c\x5d\x66\x62\x49\x8e\xfe\x76\xa8\x0c\x12\x0a\x53\xcb\xf6\x3b\x76\x67\x9b\xa2\xca\xa4\x4c\xe4\xa0\x8c\x76\xde\xa0\x55\x99\xe1\x84\xc4\xfc\x82\xa1\xf4\x45\x5d\xf6\x2d\x36\x87\x92\x30\x81\xeb\x3f\xfc\x97\xe5\xb1\x24\x7d\x46\x68\x5b\x6c\xba\x0d\x54\xf8\x75\x7b\xb7\x0c\x37\x6f\x72\xde\x1c\xad\x4b\xb2\x2b\x8d\x8d\xdb\xb2\x2a\x47\xe9\xbd\x05\x82\x7d\xf2\x5d\xfd\x5c\xaa\x19\xe5\x40\x15\x09\xd0\x0c\x59\x3f\xac\xc6\xb2\xd6\xfd\x01\x45\xf5\xa0\x37\xa8\x24\xfe\xec\xf3\xa1\x29\x4a\x5e\xb1\xb8\x10\xc1\x79\xd3\x9b\xd2\x5e\xde\x3b\xa7\x77\x8c\x25\x92\x42\x78\x6a\xfc\xdc\x56\x24\xc9\x5b\x84\xb3\x16\x39\xcd\xae\xda\x6f\xfc\x8b\x59\x07\x5d\x89\x24\x41\x87\xc3\xa1\x7e\x37\x7e\x81\xf6\x02\x1f\x47\x09\x96\x6b\x33\x98\xe3\xcd\xdd\xce\x26\xfb\xa8\x12\x42\x53\x1d\x6b\xd7\x76\xb0\xc7\x03\x8c\x2a\x8d\x6e\x04\x64\xe1\x8e\x7a\x7b\xc7\x7e\x97\x1b\x77\x77\xc2\xd9\xa0\xb0\x65\x77\xbb\x92\xdd\xc1\x41\xd6\x17\xd3\x1a\xdf\x0e\x52\x32\x49\x68\x67\x93\x54\x7c\x7b\x24\xc2\x9d\xff\x62\x95\x19\x91\x8f\x44\x2f\xb7\x9b\xd9\x85\xaa\x3c\x27\x76\x79\x47\x02\x63\xe3\x65\x58\x61\x06\x44\x81\x7a\xba\x5b\x3e\x62\xb3\x59\x6c\xd7\x9b\xaf\x3e\x38\x52\x28\x99\x74\x76\x23\x36\x56\x21\xfc\xa9\x47\x83\x2a\x13\xa5\x24\x21\x6a\x53\xa7\xe6\x8f\x0b\xdc\xa2\x5f\xd6\x41\x94\xe1\xcc\x02\x7c\x1b\xa0\x9b\xd5\x07\xaa\x3e\x3a\x6e\xc6\x73\x4d\x47\x89\xf4\x52\xee\x4f\x70\xd0\xf5\xa1\x1a\xe6\x99\x8e\x52\x4d\xf3\xec\xc6\xee\xac\xdf\xaa\xb1\x5b\xc8\x74\x39\xd1\x91\x8c\x29\x15\xfd\x5e\xe2\xbb\x67\xc6\x4e\xdf\x57\x1d\x49\x6b\xc7\xf4\x80\xb5\x2e\x4f\x87\x07\xec\xde\x87\xae\xb7\x8e\x63\x15\xf7\x9b\xd3\xbf\xfb\xd8\x64\xf2\x1b\x93\x38\x22\x35\xd1\xc5\xf5\xea\x62\x71\xce\x0f\xcb\x03\x2d\xe3\xd1\x8a\x64\x8c\x22\x18\x9d\xe8\xc8\xd3\xc7\x37\xd8\xbc\xf5\xf3\xc7\x56\x6b\x2f\x90\x35\x75\x1a\x6b\xb2\x57\x07\xad\x1f\x29\x4f\xbd\x68\xc3\x2e\x74\x9a\x9a\xd8\x8d\x7b\xb2\x05\xf9\x4f\xee\x4e\xca\x6c\x90\x71\x3c\xb5\x2f\xd4\xf4\x98\xf5\x71\x75\xaa\xa4\x76\x32\xe3\x96\x10\x79\x8d\xfb\x79\x76\xad\xb3\x3c\xa6\x64\x21\xe0\x4d\x69\xeb\x6d\x2f\x08\x03\xf7\x63\xed\x4f\xdb\x59\x5c\xaf\xeb\xd9\x4e\x5e\x3d\x9d\x15\x11\xe5\x9b\x36\x79\x7d\xbe\x2c\xde\xa0\xf3\x4c\x26\x71\x28\x83\xd9\x5f\xfd\xf7\x9a\x01\xba\x88\xa2\x42\x78\x7b\xab\xdf\x2e\xac\xa4\xba\x88\x34\x15\x57\x48\x90\x08\x2f\xe1\x29\x75\x91\x31\x9a\xa2\xd7\xf8\x76\x53\x37\x0a\x07\x79\x61\xa1\x0b\x66\x81\x76\xf5\xa9\xd9\x75\x7f\x43\xd8\xd6\x7f\x4c\x46\xe4\x44\xf5\x19\x42\xf1\xbc\x84\xa5\x0b\x9d\x12\x4d\xfb\x01\xdf\x97\xa7\xe3\x65\x46\xb9\x66\x99\x52\x79\x58\x7d\x7e\xaf\xd5\x2b\x9e\x13\xca\xff\xff\xf5\xef\xf4\x56\x33\x66\xa5\xe2\xfa\xbd\x7c\x04\xb6\xd1\x8c\x23\xa9\x08\xaf\xb6\xcb\xbb\x5a\x51\x95\xef\xe2\x9a\xa1\x19\x37\x94\xb9\xda\xfd\x6f\xf5\x9f\xcc\x4e\x96\xcc\x5e\x62\xe6\x47\x81\xa4\x18\xd5\x99\xea\xf7\x81\xb5\xeb\xcb\x30\x7f\xa7\x18\x0a\x65\x53\x60\x55\x6b\xd4\xb6\x77\xe3\x8e\xf1\xcc\x36\x63\x64\x49\x22\x9e\x9b\x03\x34\xdd\xad\xc6\xaa\x23\x6b\xcd\xc9\xbd\xe4\x0c\x5c\xb5\xd8\xcd\x39\x07\x60\xff\xef\x27\x72\x5e\x42\x73\xc1\x28\x0c\xa7\x1c\xf0\x61\xec\x61\x26\x34\xd7\x90\xd8\x26\xcc\x20\xea\x2c\xb4\x48\x84\x2e\x86\x08\xa2\x3f\xe4\xd6\xba\xd6\xa7\xc6\x1a\xf2\x84\x78\x8d\xcf\x0d\x0e\xd8\xe3\x49\x1d\x48\x43\x6e\x0d\x81\xfa\x2d\xbf\x86\x46\x5f\xd2\x2b\x14\x5a\xe6\x56\x18\xba\xaa\xfb\x24\x7d\x12\x80\x6b\x09\x11\x61\x73\xbf\x2c\xfd\x5f\x54\x51\x90\x24\xd7\x97\xed\xaf\x6a\xea\x5a\x47\xc8\xfd\x57\xf7\xab\xb3\x7a\x81\xb2\xfa\x8a\xe0\xb3\x6c\xad\x63\x46\x5c\x38\x20\x93\xc5\xc7\xc6\xf5\xf5\xa7\x77\x4e\x33\x99\x3a\xe3\xef\x4d\x50\xed\x13\x5a\xab\x9c\xa7\x7e\x45\xed\xc3\x82\x6e\x30\xb0\xf7\xe8\x64\x8d\x59\x9c\xb9\xd2\xed\x8f\xb2\x9a\x06\xec\x1a\x45\x42\x49\xd8\xd3\xea\x61\xe5\xeb\x43\xda\x44\x05\xe1\xbf\xb6\xb7\xc3\x9f\xd2\x84\x4e\x62\x5d\x47\x9c\xd4\x8b\x13\xdc\x98\x71\x01\xb4\xc9\x23\x0a\xc3\xf7\xf5\x73\x7d\xea\xce\xc1\xea\xda\x68\xc5\x46\xba\x3b\x8f\x1f\x0d\x1c\x4a\xff\x50\x16\xc7\x3e\xb7\x2e\xfb\x38\x23\x34\x57\xb4\xc1\x94\x24\xbd\x76\xb4\xc6\xf5\xf9\xdf\x1c\x84\x88\x11\x78\x27\x90\x3e\x18\x0e\x59\x33\x46\x20\x30\x74\x2b\xaf\xca\xb9\xe7\x98\xc0\x18\x62\xca\xba\xdd\x9e\x14\x8a\x54\xbf\x5c\xa1\x30\x56\xd6\x70\x63\x79\xfd\x18\x02\x21\x4c\xb2\x9c\x60\xbe\xff\xc6\xe3\x72\x5f\x9f\x74\xf8\x7b\x1e\x53\x7a\x23\x4b\x7d\x5b\x4d\x8b\xfc\x98\x18\x27\x83\xae\x75\xc8\xc2\x06\xe9\xa5\xc9\x8d\xc3\x2c\x16\x04\x8d\xf1\x70\xc3\xbb\xba\x7a\xee\x43\x65\x7a\x27\x28\x24\xb4\xa4\x0b\x7f\xee\x9c\x33\xb0\xd0\x93\x43\xa9\xca\x20\xd9\x83\x05\x44\xc4\x19\x5c\x2d\x36\xdb\xc5\xf5\x46\x91\xb9\xa9\x8f\x2a\x90\x39\xb6\xf6\x33\x76\xdf\x4b\x8d\xf5\x17\x38\xa0\xd7\x01\x9d\xde\x04\xc6\x73\xc2\x62\x59\x4d\x13\x42\x8f\xbc\x79\x1d\x46\x81\x4c\x5b\xcd\xfa\x06\x41\xbd\x7c\xa9\x47\x07\x9c\xa7\xc8\x33\xf6\x9f\x49\xf2\xe2\x1e\x3c\xde\x1d\x79\x94\x51\x91\xc3\x9c\xf6\x7b\x53\xee\xf7\x0b\xfd\x56\xb6\xc1\x3b\x43\xa0\x88\x15\xd5\x45\x3b\x27\x53\x3c\xfc\x6c\xc1\x44\x70\x81\xfb\xcf\x09\x1a\x9c\x04\xa1\x7e\x90\x60\xa4\xde\x70\x8f\x1d\x68\xe8\xc0\xee\xe5\x67\x7d\x81\xc9\x3b\x8c\x42\x59\x95\x3d\xbb\x6b\x5c\xd5\xf5\xab\x87\x57\x9d\x63\x13\xc6\xff\x9c\x6d\x02\xd8\x2f\xbe\x49\x00\xae\x07\xa8\xf0\xec\xb6\x0a\xe4\xb9\xcd\x9b\x40\x2f\xf6\xfb\xfe\x0d\x0a\x57\x09\x45\x4a\x90\x56\x87\xf6\x7a\x6c\xd0\x32\x58\xc7\xd8\x95\xec\x13\xb9\xf8\x8b\x61\x19\x4a\xa5\x3d\x75\xc7\x52\x69\xfb\xef\x23\xe1\x8b\x8b\xab\x38\xaa\x42\xa9\x91\x6e\xcc\x58\x20\xdf\x8f\xc0\x82\xa8\x88\xae\x90\x4c\x36\x11\x93\xbd\x03\x95\xc9\xe2\xa1\xe0\x44\xd3\xf7\xf2\x8c\xd7\x31\x23\x79\xdf\xa0\xc9\xe0\xa6\xea\xf4\x0b\xfb\x40\x89\xd9\x7e\x75\xd0\xe1\xe8\xb3\x7a\x42\xb2\x58\xc5\xea\x72\x4f\xbe\x58\xed\x11\x14\x5e\xac\x69\xa3\xce\x0b\x96\x86\xe4\xfd\x74\xac\xab\x01\xce\x1a\x7a\xb9\xa8\x8d\x55\x56\xfb\xb9\xeb\x17\xf1\xe1\xd5\xc7\x14\x89\x81\xff\x85\x0c\x0a\x76\x36\x0f\x52\x1f\x3b\x27\xfc\x15\x86\xb1\x1c\x2c\xd3\x56\x9d\xfa\x74\xfe\xb6\x9b\xcc\xa3\x22\x1b\xe9\xa3\x4e\x2b\x5a\x93\x19\x89\x4a\x13\x1e\xb1\x6c\xa9\x5a\x15\x08\x27\x9f\x3c\x62\x34\x19\x6d\x1f\x2f\xd0\x7e\xaf\xcf\xf2\x74\x34\xae\xae\x59\xb6\xbb\x0a\x0e\xb8\x3b\xcd\x9d\xd2\x05\x1a\x25\xb9\xa5\xb8\x80\x6f\x44\xf8\x29\x69\xa2\x54\xc3\xd4\xdd\xbf\xcf\xf4\x47\xb1\xbd\x89\x0c\x52\x82\xb0\x87\x83\xc6\x6a\x0b\x27\x7f\x20\xce\x20\x71\x1d\x13\x4a\x8f\x37\xe5\xf3\x05\xc3\xb2\x7e\x9c\xd5\x66\x27\xa4\xf1\x06\xbb\x31\x55\xda\xb6\x84\x27\x17\x6c\x12\x2e\x08\x39\xfc\x97\x82\xa6\x7f\xaf\x1b\x63\x12\xa1\x1d\xfd\xaf\x6b\x4a\x7c\x9b\xf5\xe3\xfc\x20\x59\x50\xdf\xd2\x16\x76\x97\xcb\x5f\xc5\x05\x26\x8d\x10\x6c\x85\xa9\x24\xa1\xd0\x8d\x6f\x29\xdd\xe1\x1b\x06\x10\x9b\x49\x13\x41\x19\xc0\x1e\xda\xce\xce\xfd\xba\x79\x84\x0f\xd4\xeb\x53\x17\xc6\x80\xa6\xa2\x41\x9f\x75\x50\x9e\x3a\xfb\x5d\x59\x11\x67\x7a\x00\xc1\xf8\xc0\xc9\x64\xc6\xb2\xf0\x29\x39\xb2\xb0\xcd\xcb\xd9\x91\xc9\x79\x24\xad\xc4\xff\xbe\x7c\x0b\x50\x5c\x93\x2b\x20\xfe\xd6\x97\xbb\xab\x71\xb0\x64\x8a\x4c\xbb\x58\xee\x56\x59\xbc\x9e\x0e\x87\x38\x8a\x81\xbc\xdf\xa7\xbd\x9b\xb3\xee\xbf\x29\x94\x7b\x9d\x9d\x3e\x4d\xf7\x32\x2e\x93\x1b\x16\xd9\xd3\x53\x17\x8e\x92\xba\xc1\x1a\xe7\x33\xb0\x94\x61\x85\x35\x33\xd5\x08\xdd\x8b\x25\xad\xef\x4a\x5f\x2c\x35\x3c\xd2\x04\xbf\x31\x88\xcd\x68\xde\xf2\x8c\xf9\x8d\xea\x69\xf0\x43\xf6\x2f\xeb\x70\x72\xae\x14\x01\xca\x9c\x64\xe1\xe2\x19\x2b\xb7\x96\xfa\x33\x89\x28\xa6\x09\x69\x5c\x31\x68\x9a\x9f\xf8\x41\x8e\xab\xff\x5e\x37\x9a\xc2\xbc\xc9\x8c\x11\x45\x4a\x38\xcd\xab\xd5\xf6\xeb\x05\x94\xa4\x11\x32\xa5\xdc\xe6\x19\x3b\xb2\x9c\x9c\x36\x52\x0c\x14\x86\xee\xfc\xbb\x75\xb8\x6f\xaf\xa0\x25\xfd\x0c\x7f\x58\x44\xc4\x63\xb2\x06\x2b\xd3\x1f\x2f\xe3\xa2\x18\x60\xce\xf7\xf0\xf3\xca\xc6\xee\xd7\x67\x58\x19\x23\x21\xa5\xd8\x0f\xf6\xfd\xe6\xf5\xf1\x15\x9a\x37\x0c\x1a\x78\xe1\xcb\xa4\x4c\x12\x2b\x61\x69\xeb\x36\x76\xd1\xa4\xf8\x01\xdb\xee\x52\xba\x6c\x54\x0c\x18\x0d\x25\xab\x2d\x6d\x2a\xb3\x21\xa9\x22\xb6\xa7\x3c\x35\xd5\x0f\x68\x9a\xb2\x6e\xe6\x23\x58\x44\x2e\x12\x74\xd3\x9d\xd4\x72\x32\x2e\x0e\x1a\xc5\x0d\xc5\x07\xa5\xad\x6f\x3b\x03\x98\xd9\x6a\x68\x94\x48\x43\x3e\xe1\x4b\x88\xfd\x22\x34\x7d\x20\x0a\x04\x85\x88\xa0\xd4\xe9\x40\xe5\x00\xbd\x33\x03\xa7\xde\x28\x0d\x64\x2d\xfb\x08\x1f\x8f\xd8\x7c\x2f\xf1\xdd\x1f\xd1\x91\x15\x91\x27\xd2\x5f\x9f\x77\x9f\x01\x83\x67\x13\x50\xf3\x24\x76\x2e\x02\xd5\x65\xeb\x07\x61\x30\x37\xd4\x46\xef\x9f\xdc\x23\xbc\x87\x87\x81\x5c\x50\x91\xd7\xf5\x4b\x6d\x99\xd2\x1d\x33\x59\x4e\x49\xf5\xe3\xcd\x66\xf8\x93\x64\xb9\xf3\x27\xa9\x86\x8b\x31\x06\xa9\xd5\xee\x33\xf6\x6d\x4d\x4a\xcf\x93\x07\x00\x51\xc4\xb8\xb4\xab\xde\x06\x2f\x93\xe9\x21\x8a\x78\x16\x59\x54\x0f\xec\xf7\x58\x3d\xe3\xee\x38\x32\x9c\x84\x28\x12\x89\xa4\xbe\x1e\xbc\x62\xd3\xbe\xb5\xd6\x0f\xbb\x0d\x87\x11\x29\xd6\xbe\x7d\x78\x58\x8f\x56\x25\x88\xe2\x3c\xb7\x98\xa2\x3e\x81\xd6\xb3\x1f\x16\x83\xce\x46\xbc\x2b\xa7\xb7\x19\x0e\xda\x53\x6e\x4e\x47\x6c\xaa\xfa\x0d\xc2\x01\xa9\x08\x97\x1d\x6e\xb9\x0b\x62\xca\xf6\x8e\x88\xba\xbf\x4d\xaf\x2c\x89\x52\x0b\x55\x2f\x9b\xfd\xfa\x18\x7e\x71\x12\x09\xdb\x08\x0b\x7c\xd5\x75\x65\xdd\x62\xc2\x08\xc6\x6d\x00\x6a\x17\xc4\x3e\xec\x1d\x0e\x09\xaa\xe0\x6b\xec\xa8\x66\x8e\xd7\x65\x4b\x65\xb3\x3e\x78\x51\x2f\xe8\xc7\xa5\x71\x4a\x9b\x53\xd9\xd1\x0a\x47\x61\xc3\xec\x1e\xa4\xb9\xad\xb4\xee\x9e\x9d\x28\xce\xc3\xcd\x76\x39\xae\xc0\xb9\x71\x99\xd6\x24\xd3\xb6\x7d\x81\xaa\x6e\xff\xbc\x88\x2b\x3b\xcd\x79\x64\x10\xe5\xb1\xd5\x45\xbb\x5d\xad\x09\xc2\xe3\x7f\x59\x61\xd2\x1c\x47\xf2\xd4\xd8\x06\x66\x42\xeb\xd7\x5b\xb7\x9c\x07\xb1\x78\x88\x58\x0e\xd6\x5a\xf2\x08\xef\xd5\x03\xbe\xff\x1b\x9b\x9a\x54\x67\xfd\x71\x04\x6b\x35\x42\x62\xd7\xb6\x60\xd5\xde\x97\xb3\x75\x05\x22\x66\x52\x12\xb5\x55\x75\xd5\x91\xb7\xfe\x10\x47\x71\x37\x84\x67\x19\x4b\x7d\xca\xf1\x88\x4d\xc0\x4c\x00\xd9\x26\x38\xc4\x5c\x5d\x75\xcd\x89\xf0\xa8\x43\xfd\x0b\x22\x11\xd9\x6e\x8f\x3c\x7d\xfc\x59\x8d\x89\xc4\x93\xc8\xdc\x2d\x2c\x10\x89\x84\x53\xfb\x10\x2b\xdd\x2e\xc2\x33\x16\xdc\xb2\x2c\x9d\xb4\xf0\x78\x2d\x85\x08\x12\x4e\xc5\xf7\xd7\x72\xbf\x77\xaa\x80\xe1\x10\x67\x54\x7c\x6b\xbb\xfa\xb8\x71\xad\x67\x7f\x4c\xa6\x31\x61\x08\xbd\x3d\xc0\xba\xea\xff\x8b\x7a\x5a\xdb\x87\x48\xe5\x36\x74\x03\xad\x37\x5e\xdd\xe2\x42\x88\x06\x91\x62\xc1\x87\xd1\x0b\x4e\x6e\x60\x3f\xa2\x92\xfe\x63\x7a\xe3\x95\xe6\xca\x51\x28\x4e\xc7\xeb\x10\xb7\x43\xa4\xf3\x9c\xc0\xa9\xca\x6a\x7b\xf7\xb1\xe4\x79\x54\x03\x11\xa6\x8a\xae\xbb\xc2\x9f\x5d\xff\x5c\x6f\x90\x50\x3b\xf3\x51\x8c\x53\x85\xc4\x6b\x9c\x9e\xb9\xc8\xd0\x10\x74\x09\xf8\xc3\x7a\xe3\x05\xfe\x2f\xff\x68\xc3\x63\xbb\x13\xe2\x54\x18\x09\x22\x03\x8a\x7a\x5d\x65\x4b\x6d\xf1\x75\xe3\x6c\xe6\xa7\xaf\x8e\x91\x05\x79\x20\xfb\x55\x32\xa4\x6f\x7d\x04\x73\xa1\xf4\xf7\xb7\x20\x16\x10\x47\xa9\x7d\xd0\x15\xbe\x3f\xe1\x71\xff\x41\x3a\x39\x67\x75\xcd\xcf\x3d\xe6\x21\x8e\x18\xa8\x74\xc6\x36\x14\xe3\xf8\x03\xe2\x48\x1b\xe6\xcd\x93\xca\xea\xd9\x0b\x06\x42\x1c\x67\x96\xdf\x8d\x3f\x3b\xac\x34\xf9\xdb\xc1\x18\xd6\xe5\x86\x25\x60\x5d\xfd\xef\xea\xe7\x20\x0d\x75\x99\x2f\x0d\x71\xa2\xb8\xe8\xd7\x84\xab\xed\xed\x18\xff\x73\x36\x4a\x50\x44\xb4\xd0\xfa\x01\xdf\x97\x7e\xbf\xf8\xcb\x82\x2e\x39\x88\x4c\xae\x2d\x4b\xad\x04\x6b\x7d\x44\x67\x1f\x3f\x15\x32\xf1\xcb\x4e\x9c\xe5\x11\x35\x86\x8f\xbe\xfc\x35\x63\x04\x43\x9c\xf1\x4c\xb8\xe5\xac\x5f\x08\xae\xb0\x3b\x27\xa8\x41\x9c\x3b\xb5\xf0\x6d\x7d\x6a\x96\x63\x41\xaf\x0b\xaf\x56\x9c\xf7\xcb\x54\xa8\x1a\x78\x43\xec\xcb\xf7\x24\xd7\x29\x58\x19\xa0\x9b\x5f\x15\x26\x21\x2e\x8a\x28\xc7\x41\xee\x62\x73\xb4\xc6\xfd\xbf\x72\x1e\xef\x3f\xe4\xe4\xc3\x09\xe0\x39\x8a\xca\x21\x2e\x44\x4c\xc1\xab\x17\x57\x79\x5c\xaf\xef\x9c\x4c\x51\x18\x02\x79\xea\x60\x82\xcb\xb2\x2b\xff\x3b\x0b\x61\x21\x2e\x30\x49\x5c\x08\xdb\x07\x82\x4d\x39\x53\xcc\xea\x47\x18\xeb\x7d\x0f\x5a\x93\xfc\x5f\xd7\xa1\x0e\x0e\xab\x17\xe9\x53\x10\x33\x6d\x39\x2d\x65\xdb\xef\x12\x97\xf8\x77\x10\xf3\xdc\xca\x97\x5d\x95\x84\x03\xbf\x1c\x9b\xc4\x5c\x59\xfc\xe2\x35\x56\x3e\x0d\x82\x98\xa3\x36\x16\xf3\xd1\x9d\x9a\x6a\x49\xa5\x03\x02\x10\x36\x63\xb4\xf1\xff\x4b\xff\x67\xba\xd8\xc7\xdc\xd8\xaa\xf4\x71\x0f\x1f\x37\x75\xa3\x4a\xe9\x0b\x9e\x10\x8b\x84\x13\x50\x69\x67\x6b\x4e\xcb\xe6\xe3\xd8\xb5\x1f\xbf\x9d\xd7\x98\x66\x2d\x2f\x88\x45\x6a\x19\xe9\x77\xf5\x33\xc9\xea\xfc\x95\xf7\x65\xff\x89\xc2\xe3\x40\x68\xbb\x9f\x79\x16\x43\x2c\x64\x4c\xbb\x52\xf7\xff\x9d\xaf\x8e\xfb\x26\x28\x98\x43\x2c\x43\xa3\x5e\xba\x72\x1c\xd9\xc5\xc0\x23\xca\xfb\x48\x2c\xe6\x11\xc2\xbd\x02\xc9\xc8\xff\x08\x9a\x06\x3e\xd6\xc6\x93\x3c\xb6\x2f\xd0\x7d\x85\x37\x0b\x63\x9c\x07\x7c\xb1\x42\x49\x12\x11\xa7\x16\x3e\x73\x9d\x83\x58\x1b\x49\x8e\xa3\xfd\x1e\xf3\x80\x3f\x07\x80\x37\xc4\x98\x5a\x5e\x27\x15\xc4\xdb\x17\x0b\xb9\xea\xef\xf5\xa5\xaa\xcd\xe7\xa5\x1c\x88\x91\xc5\x3a\x24\xcb\xb3\x1f\x89\x8c\x11\xe5\x73\xd1\x35\x30\x02\x9b\xf5\x07\x80\x0b\x4f\x6d\x3e\x69\xac\x7c\x26\x1c\x06\x08\x43\x6f\xb7\x8b\x27\x4f\xe1\x80\x89\xb4\xb0\x95\x8c\x39\x17\x0f\x62\x13\x8b\x6c\x58\x67\xa8\xb2\x37\xdb\xc0\x62\x93\x73\x02\x22\xf5\x91\xa6\x0d\x56\x03\x77\x18\x62\xc3\x0b\xa2\x98\x19\x77\x5a\x98\xd5\xda\x21\x89\x40\x42\x16\x2c\x19\xd7\xdd\x0b\x36\x34\xb5\x2f\x7b\x75\x42\x12\xa7\xd6\x53\x72\xfb\xe3\xf6\x7e\x1c\xcc\x27\x09\x4f\xa0\xbf\x3e\xef\x83\xea\xff\x8c\xc8\x9c\xa7\x68\x3f\x07\x9c\x95\xea\x64\x06\xba\x91\x99\xca\x89\x39\xf8\x81\xd0\xec\x3f\xfa\x00\x62\xb8\x90\xa4\x48\x4c\xc6\x7d\x95\xc2\x6a\xc0\x9f\xa3\x57\x20\x61\x45\xc1\xc7\x39\xcf\x99\x8d\xf7\xec\x6a\x18\xb7\xdc\x7c\xaf\xc8\xa1\xbf\xd6\xfb\x7e\xcd\x6d\x17\x95\xde\x22\x1c\x26\x81\x5d\xc2\x95\x95\x96\xb6\x82\x09\x6b\xf3\xa3\xec\x5e\xa8\xbb\x73\xf9\xe4\x82\x47\xa9\x2b\xe3\xde\x34\x88\x57\xa7\xfd\x3e\x9c\x4a\x98\x3c\xb2\xf5\x89\x7d\x0d\xda\x46\x1c\xae\xe1\x3c\x9e\x8b\x09\x08\x88\x5c\x45\x68\x6a\x7a\x36\xfb\x2e\xd0\x91\x49\x9d\xce\x91\x93\xc5\x98\x4c\x93\x44\x45\xaa\x70\x0b\xf9\xe2\x0d\xca\x7d\xff\x8e\x59\x06\xe8\x28\xdb\x86\x44\x81\xa1\x22\xd8\xd5\xe3\x93\x1a\x34\xf4\x21\xd1\x69\x0c\xda\x53\x8a\xd7\xc7\xfe\xbd\xb2\x1a\xfb\xb3\xb5\x65\xc2\x2b\x1b\x0a\xa7\x53\x86\x19\x24\x9a\x15\xd4\xd8\x3b\xd4\x55\xf7\x12\x27\x0e\x26\xe1\x0f\x8a\x82\xc9\x60\x10\x6f\xdf\xc2\xd0\x9e\x85\x44\x9b\x18\xad\x54\xf9\x7e\xef\x42\xba\x51\xbf\x15\x12\x94\x69\x14\xbb\x2e\xe8\xa1\xac\xca\xb6\x23\x99\xe9\xd9\xfd\x40\xa9\x28\xda\x7e\xf8\x7e\xbb\xb9\x5d\x3f\x2c\x17\x9b\xaf\xfe\xfb\x8d\xb6\x10\x15\x0f\x3b\xfc\x03\x3f\x2e\x36\xaf\x21\x4d\x52\xa3\x6d\x15\x0e\x1a\x3d\x48\x03\x40\x9a\x2a\x8b\x9e\x6b\xfb\x9c\xf1\x52\x1d\x1d\xd2\x1c\xac\x83\x38\xe5\x0f\x25\x36\x83\x88\x0b\xa4\x45\x91\x79\x80\xee\xe6\xa5\x3e\xd2\x2c\x76\x8a\x72\x34\x6c\x3c\x45\x52\xc6\x4c\x0a\x83\xc4\xd5\x1f\x0f\xcb\x0b\xf6\x78\x90\xf2\xac\xa0\x09\x10\xc8\xb7\x63\xc8\x2f\xa4\x5c\x66\xce\xad\xb6\xcf\x5a\x51\x97\xa0\xeb\x66\x71\x6c\xea\x37\x20\x81\xd7\x93\x82\xf1\x53\x48\x45\x96\x90\x92\xaa\xae\xb1\xf5\xb5\xca\x65\xad\x5d\x1a\x3b\xf9\x81\x02\x13\xda\xec\xc7\x68\x03\x5f\x84\xbf\x18\x1e\xa4\x10\x59\x36\xcd\x01\xaa\x13\xec\x2f\xc9\x96\x4e\xa7\x7f\x2a\x23\xc8\x9c\x79\xc7\xec\xb2\x65\xac\xb4\xdb\x4a\xbf\xd6\xdd\xfb\xa5\x3b\x23\x99\x76\x91\xdf\x2b\x56\xf7\xa0\x9a\x1a\xaa\xd6\xef\x65\xa9\x8a\x2c\x94\x46\x52\x35\xdc\x52\x43\xfc\xa1\x34\x22\x1d\xf0\xc5\xd3\xed\xbf\xd7\xde\x99\xbb\xff\x73\x46\x0d\xb1\x36\xc8\x27\x8f\x34\x3b\xda\x5d\x18\x96\x69\x42\x34\x1d\xb0\x51\xa7\xfd\x34\x19\x4c\x95\x2c\x8a\x01\xb6\xf9\x38\x2e\xb7\xa4\x9a\x59\x5d\x5e\x0f\x3b\x48\x98\xb3\xa6\x66\xff\x98\xfc\x1b\xa6\xa9\x36\x92\x08\x24\xcf\xa5\xe9\x96\x2f\xd0\x80\xea\x66\x00\x0e\x1e\x46\x5a\x64\xd9\x1f\x64\x7c\xb0\x85\xfd\x2b\xce\x1e\x26\xe6\x2c\xb6\xfd\xb2\xb7\xfa\x15\xbd\x21\x84\x63\xe0\x5e\x48\x32\x52\x54\x9a\x30\x46\xfd\x30\xab\x19\xd6\x8e\xf1\x67\x90\x9a\x28\x4e\xcd\x14\x93\x38\x12\x7e\x85\xd4\xe4\x9c\xcc\x31\xbd\x2e\xca\x90\xec\x67\x51\x1c\x91\x85\x45\xc0\xdf\xf9\x8e\x26\x64\x51\xc2\x08\x17\xea\xcd\xa7\x1f\xea\xe6\x00\xfb\xfe\xe4\xfd\xce\x72\x86\x57\xfd\x75\x3a\x97\x45\x89\xad\x6d\xdc\x81\x86\x5f\xb0\xf6\x5c\x44\x35\x99\x5e\x59\xc4\x19\x29\xa9\xae\xfe\xdc\x2c\xeb\xb2\xda\x20\xa9\x77\xfb\x83\x26\xa6\x37\xdd\x89\x1d\xed\x2f\x11\x9e\xfb\x51\x92\xb6\xf1\x23\x36\x4e\x5e\xfb\x1e\x9a\xd7\xd1\x33\x1c\x5e\xcc\x2c\x4e\x80\x68\x51\x20\xeb\xb7\xfe\x5a\xcb\xc3\xe9\x30\xa5\x79\x40\x16\x67\x59\xe2\xc2\xfe\x07\x7c\xb7\xcb\x45\x3c\x7d\x2b\xb2\x58\x1b\x12\x39\xb4\x4d\xc5\x9d\x01\x85\xbb\x63\x53\xd7\x66\xd7\x4c\x02\x9b\x2c\xc9\xc1\x0b\x87\x6e\x1b\xc4\xdb\x99\xdd\x36\x64\x89\xe1\x5e\xf5\xe5\x86\x3e\x5b\x79\xfb\x3f\xc8\x32\x29\x88\x90\x62\x05\x65\x6e\x17\x87\x75\xd0\x7d\x83\x2c\xcf\x52\x32\x04\xbb\xaf\xab\xba\xc1\x99\xfb\xa8\x1b\x53\x24\x39\x81\x3e\x06\xe9\x4a\xbf\xc7\x66\x45\x9e\x53\xc1\xa9\xac\xfa\xf7\xe4\x22\x1e\x0d\xb2\x82\x45\x36\xff\xaf\x97\xf5\x61\x76\x6e\x16\xf3\xdc\xed\x34\xea\x01\xde\x2e\x57\x20\x32\x96\x45\xe4\xda\xa2\x4b\x0a\x5c\x07\x1e\x1c\x64\x0c\x18\xb1\x76\x0f\xa7\xae\x3c\xc3\x7f\x7d\xc6\xfd\x83\x8c\x6b\xe5\x15\xcc\xb0\xd2\xdf\xfa\x39\x15\x24\x44\xc6\x13\xcd\x0d\x17\x45\x46\x97\x40\x3c\x98\xb2\x1e\x89\x3e\x40\x26\x34\x2a\x0c\x48\x74\xdc\xd7\xc7\x03\x56\xa4\x77\x3b\x69\x46\x40\x26\x30\xf7\x9a\xbe\x8f\x75\xbd\x1f\x57\xfb\x86\x4b\xed\x5f\x56\x08\xe0\xe0\x41\x3a\x67\x94\xfd\xf8\x1f\x05\xb9\xe5\x18\xb8\x2a\xde\x6f\x67\xf1\x81\x1b\x27\x65\xe2\x95\xff\x6f\x3b\x3c\x2c\x2a\xbd\x20\x0e\xef\xa5\x9a\x48\x26\x0d\x50\x2f\xe0\xf6\xfe\x7a\xf5\xa7\x6f\x40\x4f\x3a\x2f\xb3\x0f\xa8\x94\x51\x9e\x24\xcb\xa6\x7b\x79\xc4\x66\x1b\xe2\xd5\x4c\x15\x40\x1b\xd8\x76\xb5\xb8\xdf\x7d\x7b\xb8\x79\x5a\xad\xfe\xbd\x0a\x07\xc1\x2a\x81\x8c\xf4\x79\x3f\x9e\x46\x16\x3a\xb3\xaf\xd1\x79\x41\x35\x88\x6d\x89\xdf\x8e\x77\x75\xdd\xe2\x2a\xa8\x54\x42\xa6\x99\xd2\x4e\xbc\x89\x1a\xf9\x0e\xbc\x75\x5d\xab\x89\x01\x1e\x64\x1a\x12\x52\xe9\xbd\xff\x58\xe8\xb7\xfe\xe1\xd8\x78\xfe\x7b\xf2\xab\xb2\x41\xa6\xd1\x86\x88\xdf\x57\xdb\xa7\xdb\x5f\x8e\x34\x90\xd8\x91\x25\xbe\xef\xc8\x0a\x69\xef\x81\x89\x76\x73\xda\x39\x85\xdc\xc9\xd5\xe5\x11\xa6\x0e\x7d\x52\x51\xa5\xda\xae\xe2\x93\x82\x7c\x1e\xa7\x92\x20\x08\xcb\xfb\x2b\xd7\xa1\xe9\xdf\x85\xf3\xa6\x18\x90\x02\x68\x36\x10\x89\x97\x6b\xc2\x51\x66\xfe\x44\x89\x8e\x89\x5a\x70\x84\x8f\x91\x99\xc0\x2f\xd3\xe5\x3c\x37\xd2\xc3\x58\x2d\x0d\xf6\x72\xad\x20\x2f\x22\x41\x2d\x85\x45\x53\x62\x3b\x4e\x5e\xf2\x22\x11\x94\x07\xf4\x61\xe8\x24\xe6\xcf\x8b\xcc\x72\xd7\xfa\x0b\xa7\xc9\x9e\x84\x23\x02\xb9\x97\x66\xd8\xbc\x40\x33\xcf\x55\xf3\x02\x2c\x87\xa7\x32\x6d\xff\x4a\xdd\xa1\xf1\x6b\x66\x2e\x98\xa6\x1d\xb9\x3c\x1c\xf7\x3b\xd0\xba\xb4\x9b\x97\xed\x37\x87\xef\x16\x9c\x53\xe5\x68\x8b\xcd\x21\xfc\x4d\x72\xea\x7b\x1f\xb0\x85\xd6\x33\xdf\xc2\x31\xeb\x5b\xd3\x92\x46\x76\xdb\x9f\xb1\x6c\x69\x49\x58\xce\x35\x6a\x21\x17\xaa\x20\x8d\x85\xc5\x49\x75\x27\x7b\x37\x7c\xb1\xfa\xef\x74\xe0\x21\x87\xc8\xe2\xc6\xbd\xca\xd1\x2f\xe1\x59\x90\xf7\x19\xb0\x77\x16\xb9\xee\x5f\xdb\x32\xf4\x5b\x72\xc8\x90\xb8\x91\x8b\xfb\xab\xc5\x66\xb3\xb8\x5e\x3f\xed\x36\xdb\xc5\x1f\xab\x70\x3c\x97\x71\x3c\x84\x08\x1b\xf2\x4e\x0c\x07\x65\x4c\xb0\xdd\x37\xfb\xeb\xc7\x48\x58\xc8\x95\x92\x89\x0d\x8e\xd5\x1e\xe1\x6f\x13\xe5\x46\x1b\x6a\xae\x94\x95\x62\x97\x75\xfd\xfa\x54\xd7\x87\xd9\xd2\x34\x52\x52\x9f\x25\x09\x17\x4f\x66\x04\x25\xb9\x0f\x78\x6a\x5c\x64\x1b\xe2\xc9\x5c\xab\x24\xf3\x66\x49\x16\xb9\x69\x9f\x9e\x7b\x2b\xa7\xb3\x4b\xab\x9c\xda\x47\xb2\x9f\xb3\x4e\x2e\xa7\x1d\x03\x79\xfd\x38\x64\xf4\x8d\x87\x52\xaf\xcd\x6c\x0e\x20\x0a\x42\x11\x6c\x3a\x78\x45\xef\xd7\x7d\x56\xac\xfd\xe4\xb2\xdc\x39\x4c\x9e\x53\x67\xf4\x50\x56\xdd\x54\x15\x6a\xb8\x41\xbf\x82\xde\x43\x6e\x78\x64\xb2\x80\x64\x5c\x68\xfd\xcb\x8a\x67\x11\xb1\x82\x76\xc7\x3e\x90\xea\x17\x99\x1b\xbf\x03\x0d\x43\xe2\xc4\x4a\x1d\x35\x48\x41\xe3\x64\x19\xf2\xbb\x6c\x11\xf3\xcc\x6a\xe5\x55\xf8\xf5\x54\xe9\xa0\x72\x07\x45\x92\x02\x4d\xb7\xd0\xc1\x1b\x0b\xdc\xfb\xce\xd7\xf8\xdf\xfe\x01\xcf\x77\xb6\x22\xd1\x92\xe2\xa2\x7f\xfd\x95\xcc\x03\x14\xa9\x60\x84\x17\xa9\xf7\xda\x4a\xc9\x52\x5b\x7f\x5c\xcc\x2d\x52\x81\xda\xa6\x8b\x06\xaf\xcb\xb7\x9d\x46\x75\x39\x1e\x29\x52\x40\x92\x40\x7b\x38\xbd\xe2\x45\x97\x03\x28\xb2\x38\x4b\x83\x51\xbc\x8f\xe1\xab\xf9\xa0\x44\x3b\x02\x6d\xd7\x40\xd9\x79\x5f\x4a\x28\x32\x69\x01\xe8\xbb\x37\x6c\x4a\xf3\x61\xab\x01\xfd\x0a\x77\x8d\xa6\x81\x59\xa9\xb2\x28\x74\x21\x2c\x63\x69\x83\x30\x37\x4f\x85\x82\xe9\x84\x36\x0e\xbf\x2c\x9c\x1d\x36\x52\x0e\x3a\xb6\xd6\xb8\xcf\x6a\xf9\x4f\x07\xf2\xd8\x50\x45\xfe\x61\xf5\xe7\x76\xf7\xb8\xde\xee\x6e\x9e\x16\xcb\xdd\xd5\x7a\xeb\x7f\x35\x37\xa9\xa7\x6d\x2c\xb6\x65\xd7\x7d\xcc\xe6\x8c\x48\xd2\x8c\x8d\x70\x6d\x57\x30\xdc\xfc\x3e\xee\xa1\x3c\x3f\xad\x26\xfb\x46\x01\xa8\xac\x93\xd8\xbe\xae\x7c\x55\xaa\x26\x23\xf0\x30\x99\x64\xca\x6c\xec\x7e\x6a\x5f\xe8\xb3\xb7\xf3\xd9\x2a\x31\x42\xd2\x42\xb7\x11\x99\x1e\xb9\x31\xf6\x07\x81\x00\x12\xc7\xa6\xac\x54\x79\xdc\x4f\x20\x28\x50\xa8\xa8\xb0\xf4\x37\xd2\xbf\x7e\xb4\x05\xee\xd9\x06\x5e\x20\x32\xd2\xb6\xfc\x7e\xbb\xd9\x2e\x82\x5a\xe1\x63\x7c\x79\x9b\x2c\x10\x05\xdd\x89\x7e\xfa\x9d\x8e\x53\x0e\x16\x14\x26\x09\x4f\x84\x98\xda\xfd\x43\x5b\x6d\xbf\x8e\x6a\x03\x85\xc9\x35\x2d\x09\xbb\xff\x05\xf5\x7a\xac\xbb\xb9\xc9\x2d\x14\x46\x4a\x32\xdc\xd9\x90\x13\xd3\xac\xff\xc7\xa2\x34\x27\xf9\xac\xdd\xce\x58\xdf\xd9\xe9\xa7\x59\xa4\x22\xe3\x35\xd5\xea\xe7\xe7\x3d\x9e\x6b\xc4\xf4\x83\x02\x3c\xc5\xdd\x58\xbf\x73\xb3\x58\x64\x94\x71\x3e\x8e\xba\xb7\xd3\xe9\xc4\x62\x1d\x39\x18\xdc\xff\x9e\xda\xee\x06\xa9\xcb\x7a\xe9\x6b\x92\xc8\xd0\x32\x6c\x03\x8f\x8d\x07\x0c\xfc\xed\x8d\x66\x76\xb6\x9c\x6b\xaf\x62\x07\x07\x24\xc5\xfb\x66\x24\xc2\x75\x49\x53\x06\x58\xc2\xad\xd9\xfe\x3d\xbc\x62\xbf\x2a\x4e\x74\xe8\x3e\xed\x06\x4c\x2f\x38\x4d\xb4\x77\x46\x0d\x10\xbd\x69\x43\x95\xa5\x79\xa6\x5d\x89\x7b\xfd\x5e\xa1\xde\xbc\x94\xc7\xf6\xea\xe3\x62\x79\x8b\xa5\x3c\xa5\x25\x6d\xc0\xbe\x9c\x6d\x27\x61\xc2\xb0\x94\xe7\xa4\x3d\xb6\x28\x3b\x68\x47\xde\x9d\xc0\x52\xc3\x88\xfd\xf0\xe5\xe1\xe1\xfe\x57\x4b\x68\x9f\x84\xb1\xcc\x63\x4b\xaf\xa1\xc3\xd6\x9b\x47\x5f\xdc\x45\x58\x26\x2c\xe7\x97\x52\xc6\xfa\x38\xd7\x80\x3c\x0f\x08\xc6\x58\xb6\x7f\x4c\x13\x36\x96\x81\x15\x2d\xb6\xe0\xd9\x3e\x97\xc7\x4a\x77\x67\xe5\x69\x96\x17\x26\x12\x83\x9d\xf4\x60\x3e\x06\xac\x48\x24\xbd\xc8\x8f\x4f\xeb\xfb\xd5\xf6\xeb\xea\xdb\x66\xf7\x7d\xfd\x6d\xf9\x75\xf5\x64\xb5\x02\xc2\xb8\x42\x19\x70\x1c\xed\x51\x80\xec\x8e\x32\x19\x91\x86\xac\x47\x63\x86\xbf\xab\x94\x6a\xa6\xfd\x53\xbd\x3e\x35\x44\xa6\xef\x7f\xe6\xa4\xb0\xc4\x78\x2c\x69\x23\x2e\x47\xd5\x50\xc6\xd1\x3a\xcd\xd2\xaa\xd6\x3c\x20\xea\x27\x34\x0d\xb6\x2f\x9f\xdc\x58\x11\x21\x99\x36\xdc\x2f\xfe\xdc\x2d\xb6\x5f\x57\x0f\xb7\x8b\xd0\x6f\xec\x0f\x3a\x1d\x5b\xe2\x93\xcd\x5f\x7c\xc1\x0d\x39\x1e\xd7\x47\x2b\x37\x5d\xe1\xa7\xc2\x87\xfe\x13\x22\xcf\x5d\x6e\x45\x54\x2c\x7b\x59\xa3\xc5\x88\x41\x64\x05\xc7\xf0\x0d\xf6\x27\xe8\x48\x59\xd7\x1f\x8a\x95\x15\x08\x18\x01\xd2\x81\x41\x62\x48\xee\x01\x0f\x65\xb7\x84\x23\xc8\x72\x5f\x76\x1f\xd6\x11\x62\xf6\x26\x66\xe3\x94\x97\x81\xa3\xd5\xb7\xd8\xdd\xd7\xd5\x2b\x4e\x44\x8d\x81\x01\xe3\x29\x78\x83\xe1\x73\x5c\xc1\xaf\xda\x53\x93\x6f\xe1\x8a\x72\xf0\x3e\x5b\xa6\x2a\x50\xb8\x1c\x15\x0b\xaa\xb3\xca\xb2\xc3\x9f\xfb\xf2\x0d\x87\x03\x2a\xa5\xd2\x6f\xff\x99\xd9\xe6\xc0\x54\x8c\x82\x36\x4e\x94\x78\x9a\xec\x6e\x4c\x99\x84\x00\x24\xef\x58\x4e\x34\x69\x81\xe9\x44\x00\x04\x24\xf7\x89\xfa\xd4\xfe\x18\x82\x26\x31\xff\x5d\x50\xcc\xbe\xc8\xe2\x70\xa3\x4d\x96\xa4\xde\x71\xc0\xb6\x88\xfa\xd3\x5d\x8e\x5b\x98\xc9\x0b\xaa\x96\xdd\x86\x22\xb5\x67\xea\x03\x33\x2c\x25\x32\xb2\xff\xda\xed\x99\x23\xbc\x1f\x28\x59\x56\x84\x9e\x5a\x30\x8b\x9c\x70\xe0\xc6\x37\xdc\xa8\x94\xa8\xb9\x9b\x3e\x6d\x7f\x1b\x6a\x2b\x3c\x42\x96\xe4\x4e\xa5\x8e\xaa\xd9\x36\xee\x5d\xb4\xce\x73\x2e\x0c\x33\x99\xeb\xbc\xdc\xb6\xcb\x7d\xdd\x0e\x87\xe2\xd8\x90\xc0\xc1\x75\xf9\x5c\x92\x4a\x77\x5b\x0f\x0c\x2c\xe0\x89\xb1\xb5\x29\xcb\x47\x1c\x4c\xc5\xa7\x4f\x90\x27\x46\xc7\x6a\x64\x47\xd2\x74\xa6\xde\x97\xb3\xce\x25\x4f\x33\xa0\x3e\xfd\x66\xbb\x78\xda\xee\xb6\xde\x49\x1d\x78\x1e\x47\x84\x20\xb8\xab\x9f\x3f\xab\x51\x4d\xef\x20\xcf\xa5\x74\x17\xfe\x39\xc1\x6c\x04\xa3\x05\x5e\x64\x09\x29\x04\x6e\xef\xaf\x96\x9b\x0e\x2a\x0d\x8d\xfe\x9b\x20\x35\x5e\x14\xc6\xbf\x36\xdb\x97\x51\x05\x6c\xde\xb6\x9e\x7e\xc8\x14\x64\xe3\xd5\x61\xdb\xed\xa2\x5d\xff\xcf\x15\xb4\xa5\xda\xfe\x1c\xda\xc2\x6e\x28\x4b\x45\xac\x42\x03\xb4\x6e\x5a\xdf\xad\x0e\x03\x32\x6d\x48\x2c\xab\xae\x5f\x4f\xb3\x06\x2d\x67\x79\x4e\x10\x9c\xdb\xe5\x7a\xb7\x7a\xb8\xde\x6d\x6f\xef\xc3\x8d\xe5\x29\x23\x2e\xf0\x11\x3e\x9a\xba\x5f\xad\x87\x76\x0b\xe7\x1c\x28\x70\x0c\x95\xeb\xe0\xf0\x37\x3d\xbf\x60\x09\x29\x96\xdf\xd5\x6f\xb8\x28\x9b\x65\x6d\x0c\xce\x9f\xbf\xe0\x19\xa9\xfb\x55\xb5\xc6\xf6\x3b\x84\x02\x28\x17\x18\x59\x00\x18\xd9\x4d\xde\xd7\x1a\x37\xf5\xba\xda\x7f\xac\xbc\x69\xf8\xa6\xab\x8f\xed\xa2\xd2\xab\x56\xc1\x11\xbf\x5a\xcb\x97\x25\x54\x57\xf8\x6d\x34\x4b\x21\xc9\x2c\x19\x81\x6c\x7d\x2e\xe0\xa4\x81\x4b\xce\xe9\x1e\x6d\x56\xcb\xf5\xc3\xf5\xee\xfb\xfa\xee\xdb\xfd\xca\x7a\xf7\xfb\xb3\x48\xa5\x89\x4d\x3c\x76\x16\x9d\x75\x81\xdc\x48\x15\xa7\x14\x3e\x3e\x2c\x16\x57\x5f\x17\xe3\x15\x89\xab\xd8\xb6\xe6\x68\xd7\x1e\xd1\x24\x81\xeb\x28\xa5\xda\xc7\x3f\x4f\x50\x75\xce\xa2\x33\x1c\xcb\x0d\x49\xbf\x75\xa8\x5e\x1e\x9b\xfa\xad\x0c\x2c\x11\xe0\xc8\x05\x29\xb6\xdf\xa3\x56\x41\xa4\xa2\xff\x33\x46\x5e\xfe\x22\x0d\x7f\xd4\xa9\x35\xd4\x23\x8e\x78\xa8\xc5\x5f\x9e\xfa\x7e\x53\xe3\x86\x1b\x69\x85\x55\xdf\xca\x16\x9b\x76\xc2\x3f\x01\x6e\x50\x73\xe1\x51\x77\x97\x53\x3a\x11\x45\x71\x6c\xc2\x2e\x37\xaa\x05\x4c\xc2\x14\xee\x47\x3b\x79\x16\x07\x54\xa9\x0f\x87\x53\x55\x76\x1f\xbf\xc4\x41\xfc\xcd\x30\xf5\x32\x70\xeb\x97\x31\xad\x88\xe3\x88\x94\xec\x1e\xf0\xfd\x1a\x3a\xf0\xb0\x88\xd3\x67\xd0\x2f\x11\x0b\x2b\x09\xf4\xcf\x6f\xab\xd5\xc3\x76\xe5\xb4\x2f\x40\xc4\xca\xca\xd3\x54\xf8\xb3\x73\xc5\x8a\x41\x7b\x03\x44\x6c\x12\x70\xeb\xec\x8e\x58\x29\xbb\x99\xda\x09\x88\x24\xcf\x30\xf3\x94\x71\xff\xb9\x44\x26\x45\x36\xa1\x14\xfc\xad\xfa\x97\x48\x33\xf9\xff\xe3\xec\x4d\xb6\x1b\xc7\x91\xef\xe1\xd7\xa9\xc5\x6f\x41\x70\xc6\x52\x96\xe5\xb4\xba\x3c\xb5\xa4\xcc\xac\xea\x3e\x7d\x74\x02\x40\xc0\x66\x25\x45\xaa\x49\xca\x4e\xf5\xd3\x7f\x87\x01\x80\x93\x28\x67\x7d\xff\xda\x38\x4b\x00\x67\x0c\x31\xdc\xb8\x97\x68\x06\x0f\x90\x91\xc4\x54\x2f\x2d\x34\xb1\x85\x79\xe8\x19\xd2\xea\x2f\xd9\x2b\x18\xe6\xb0\xf5\xa7\xf1\x00\x1e\xa2\x24\x8f\xb0\x7d\xd2\xaf\x83\x0a\x06\x77\xcb\x91\xc7\x18\x3a\x63\xbd\xfd\xc8\xc6\x10\x78\x3a\x1d\x76\x99\xfc\x51\x1b\x6d\x63\xd7\x57\x86\x74\x9b\xa4\x8a\xf9\x7c\x6a\xb6\x1f\x88\x5d\xe4\x8d\x47\x4a\x90\x39\x69\x99\xdc\x86\xa5\xa1\xe3\x61\xcc\x63\x3f\x16\x16\x4d\xfa\x90\xfd\x77\xc6\x15\xe2\x71\xaa\x22\x83\x9b\xa9\x4f\x48\x6a\x96\x14\x30\x1d\x4e\x45\x9e\xf0\xc8\x28\xf6\xca\x4b\x25\x6a\xe0\x69\x98\x3a\x89\x17\xca\xdd\x0f\x31\xf3\x03\x7f\x81\xa7\x71\x64\x18\x67\xdf\xb2\x02\xb2\x42\x76\xc7\xa7\x29\xd1\x69\xd7\xf0\x8e\xb6\xf0\x69\x51\x89\xac\x31\x4b\xec\x1d\x0e\x44\xb2\xc7\x0f\x47\x3e\x65\x57\x4f\x71\x8b\xef\x6d\xdf\xd6\xb1\x99\x7c\x49\x48\x52\xb2\xd2\xf3\xf2\x75\x91\xe7\xed\xf2\xe9\x2e\x0d\x10\x99\x92\x7f\xc8\xf3\xc5\x23\x36\x6f\xa5\x62\xbf\x82\x3d\xba\x43\x65\xe0\x92\x0d\xe6\x3b\x62\x35\xc7\xfb\x01\x1c\x30\xa6\x4f\x29\x84\xbb\xaa\x0a\x91\x02\x5d\x7b\x61\x65\xd8\x2d\x9c\x2b\x1e\x03\xd2\x5c\x6f\xf4\x53\x2b\x20\x65\xc1\x9e\x13\xf2\x9e\xbf\xf9\xd7\x9e\x0e\xfd\x50\x32\x57\x2a\x56\x15\x73\xa8\x03\x8e\xda\x94\x7d\x15\xf8\xb1\xcb\x0e\x56\x19\xf4\x33\x24\x0b\xd7\xd2\xa3\x6c\xa1\x09\x2e\x75\xb4\x7f\x53\x6f\x76\x3a\x47\xe7\xcc\x00\xae\x51\x52\x52\xab\x36\x7e\x4e\xe7\x9d\x5b\x0a\x16\xd7\x4b\x1b\x59\xd7\xf7\xb2\xc1\xaf\xeb\xdb\xfe\x67\xa1\x0d\xea\x99\x32\x5d\x4e\x7c\x6c\x32\xe8\xb5\x36\x1a\xc5\x2e\xcf\xfc\x49\x36\x0a\x3c\xee\xd1\xc2\xf6\xb8\x7e\x5a\x3f\x7e\x7d\xdc\x3b\x46\xd9\x97\xaf\x9b\xe5\xfd\x62\xbb\xda\x2f\x1e\x9f\xbf\x3e\xed\x46\xb4\x70\x00\x9e\x30\x71\xb8\x57\x53\xe2\x7d\xbe\x19\x02\x76\xc0\xd3\x82\x6a\x28\x8a\x9e\xaf\x67\x9c\xd9\x03\x06\x68\xa8\x51\x1e\x97\xbb\xee\x37\x44\x4a\x58\x1d\x8c\xb2\x02\x39\xe9\x03\x00\x0a\xf8\x9e\x41\x6d\x91\x5a\xf0\xaf\x33\x97\xee\xa8\x50\x47\x7d\xd0\xc4\x71\xdd\x8f\x0a\x16\xe6\x2d\x4a\xf0\x53\xe3\x18\xd7\xc7\xbc\x5d\x1c\x2d\xdd\x48\x77\x37\xc2\xd4\x81\xca\xd3\x61\x83\xff\x7d\x84\x4a\x74\x92\x7d\x6d\xa3\x20\x23\x27\x87\xba\xf9\x9e\xe5\xb9\xe3\x28\xe9\x9a\x4d\x5c\x90\x2c\x41\x3f\xde\x1b\xd0\x04\xc9\x93\xc0\x2b\xfa\x9e\xe7\x11\x78\xa7\x3b\x5d\x10\x4a\x32\xe8\x8c\x2b\xff\x8f\xc7\x99\xd2\x27\x80\x00\x4c\xf1\xa3\xe1\xc7\xbb\xf2\xb5\xc3\x58\x12\x52\xa2\xbd\x32\x09\x85\xdd\x64\x84\xeb\x27\xf0\xf1\xf3\xf3\x8d\xbb\x62\x14\x32\x12\xba\x58\x57\x1a\x8a\xbb\xaa\xfb\x39\x0e\x0c\xb0\x3d\x87\xec\xb0\x2d\x65\x06\xb9\xa5\x7f\xe9\xd8\x1f\xae\x05\xea\x4f\x73\xb8\x4e\x77\x5a\xae\x09\x5b\x7f\x20\x15\xae\xbb\xec\x1d\x5f\x72\xe8\xde\x56\x04\xe0\x0f\xa5\xf4\x17\x85\x7a\x2a\x9b\x4c\x9f\x3f\xcf\xc0\x41\xac\x42\xca\x94\x97\x56\xd3\x67\x5f\xd1\x4e\x7a\xbb\x35\x90\x01\x2a\xa3\x3f\xef\x89\x32\x78\x58\x16\xed\xee\x6e\x34\x6b\x21\x49\x53\x0a\x57\x3e\x66\x45\xd3\x67\x11\x67\xaf\x9b\x70\x2d\xe3\x4e\x2d\x6a\xc0\x80\x30\x5e\x86\x20\x0d\x74\x64\x39\x38\xea\xd3\x01\x7f\x9b\x59\x1d\x21\x8d\x13\xa2\x1f\x7a\x3a\xfd\x05\x43\x5a\x36\x00\x1e\x68\xca\xf0\x9b\x31\x71\x63\xee\xbc\x5b\x9c\x87\x40\x37\x77\x00\x18\x04\xd0\x11\xce\x2f\xd5\x50\x96\x65\x64\xae\x7d\xbe\x2d\x00\x97\x11\x91\x25\xb7\x43\xec\xb9\xfa\x3d\x73\x71\xbd\xd1\x8a\x67\xfb\x02\x47\xf2\x69\x77\x4f\xdd\x14\x17\x10\x9a\x72\x1c\xc8\xb1\xb6\x48\x3f\xdb\x24\x99\xd7\xd5\x55\x7f\xc0\xf1\xf9\xd4\xbc\x96\x53\x79\x12\x00\x19\x29\x17\x65\x25\x4b\x7b\xa8\xbf\x02\x20\x2d\xb8\xf1\xd8\x3e\x9f\xc9\x05\x77\x73\x48\x31\x1d\x08\x2b\xc1\xb5\x3d\x1d\x9e\x4e\x87\x39\x15\xae\xf9\x59\x83\x09\x90\xcf\x9b\x0d\xca\xdd\x5d\x93\xe6\xc4\xe5\x00\x4a\x3d\x42\x71\xbe\xa8\xaa\xeb\x5e\xbf\x86\x90\x90\xc4\xeb\xe7\x6f\xa3\x82\x33\xd0\x68\x1c\x81\x7f\xf6\x58\x65\xe1\x05\x48\x09\x55\x9a\xa6\x26\x1f\xb7\xb1\x54\x81\x1d\x0b\xd7\x6b\x1f\x91\x14\x9e\x8c\x65\x4f\xde\x51\xb4\x03\xf4\x65\xa2\xcf\x0c\x82\x25\x21\xb1\xe5\x9c\xe8\x04\x3f\x26\xad\x3e\x53\x36\x0a\x56\xc8\x55\xf3\x36\xb0\x80\x84\x0f\x9c\xee\xf0\x50\xaa\x4c\x9f\xff\x71\xaa\x0c\xbb\xc8\xf8\xf8\x40\x08\x73\xcb\x65\x03\xb9\x8d\xbe\x7c\x29\x21\x5f\x17\xeb\x9b\xa5\x3b\x53\x68\x19\xcf\xf6\xba\xac\x34\x66\xcd\x38\x45\x3d\x7e\xeb\x22\x0c\x4d\xf4\x74\x91\xe7\x4f\xf8\x51\x2f\x7b\x4f\x48\x84\x69\x18\xcb\x4e\x67\xf5\x01\xea\x26\xa1\x3c\xcd\xe4\x04\xd2\x23\x74\x61\x7d\x12\xaa\x6c\xa7\xf9\x48\xc3\x7d\xc6\xc6\x15\xa1\x84\x28\x9a\x88\x3a\xfe\xd1\xde\xdd\x04\x02\xd5\xbb\x18\xa9\x3b\x52\x21\x95\x4d\xd6\x6f\x65\xd5\xdc\x9c\xba\x2f\x19\x31\x41\xd6\x23\x9c\x0e\xdd\x4f\xa9\x91\x99\xd9\x66\xc5\xeb\x29\x87\xea\x76\xf7\x6d\x10\x74\x15\x91\x40\x02\x5c\x1c\x73\x68\x48\x61\xd6\xfa\xa6\xe3\x3d\x44\xc4\xb1\xa0\x35\xf3\x08\xe7\xed\x49\xd4\xb2\xca\x8e\x17\xac\xe5\x20\xe2\x34\x49\xec\xf0\x74\x15\x7f\xf3\xee\x9c\x88\x11\xa8\xac\x6f\x75\x55\x75\x1a\x44\x6c\x35\xb6\x25\x1c\x29\x34\x54\x96\xf9\xb3\x9e\x5e\x51\x6b\x66\x25\x3b\xee\x4e\x39\x8d\x84\xdd\x1f\x57\xae\x99\x44\x09\x45\xb1\x9c\xfb\xbd\x5a\xbf\x24\x49\xf2\xf9\xb6\x2c\x92\xd8\x58\xa6\xc7\x32\x3f\x1b\xd1\x43\xac\xea\x71\x56\x40\x24\x89\xc9\xb5\x02\x85\xbd\xbe\x16\x59\xb3\x21\x01\xfd\xd1\xc2\xe7\xfa\xa2\xb4\x50\xd5\xbf\x50\x36\x2f\x86\xf1\x7a\xd2\x27\x0d\x91\xb2\x0c\xc7\xec\xfd\xa7\xbb\x46\x1a\x81\x13\x20\x25\x39\x3b\x87\x93\x18\xae\xdf\x22\x4d\x0d\x43\x7d\x85\xed\x12\x3f\x18\x17\xa9\xc5\x34\x83\x21\x1e\x99\x24\xb4\x04\xf7\x22\xde\x36\x3f\x57\xc7\x37\xa7\x7b\x3f\xbe\x25\x1e\x70\x62\xc7\xf9\x82\x43\xd5\x12\x10\x3c\x34\x44\xf3\xa0\x94\x79\x6d\x33\x7c\x5d\x20\xb8\x12\x91\xa1\xbb\x29\x7e\x74\x71\x07\x01\x49\xa0\x3a\x8a\x50\xc8\x2f\x34\xfc\x40\x40\x8a\xc4\xc5\x2c\xaa\xf2\x07\x56\xeb\x0e\x10\x29\x80\xa7\x54\x64\x75\x2a\x28\xf7\xdf\x7e\xf6\x7a\x5d\xac\x6a\x59\x95\x1f\x9f\xb2\x8b\x81\x10\xb1\x11\x4d\x16\xa7\x73\x51\xaa\xe9\xba\x22\xd2\xd0\xe3\x3d\x06\x6c\xb5\xbb\x1f\x9b\x92\x42\x68\x9f\x2a\x23\x76\x08\x07\x32\xe5\x3f\x45\xb3\x4d\x06\x93\x14\x42\x2a\x27\x71\xf1\x96\x35\x4b\xa2\x06\x19\xdf\x9f\x62\x09\xb3\xc9\x45\xda\x00\x66\x63\x15\x93\x43\x7c\x41\x20\x19\x53\x0b\xda\x4b\x11\x81\x40\x0b\xea\x31\x6c\x0a\x19\xc1\x2e\x47\xc7\x4a\x4f\x04\x4c\x0f\xd9\xe1\x48\x36\xf7\x98\x67\x64\xf9\xcc\xd4\x38\x4a\xe6\x49\xaf\x97\xe0\x9a\x02\x66\xe6\xb6\xf9\x38\x1c\xff\x71\x27\x8a\x8c\xb6\x31\xa1\x37\x1c\xd9\x0e\x48\x16\xa7\xa6\x3a\xb5\xfd\xdd\x0c\xf3\xae\x09\x7c\x4a\x32\x91\x30\xe1\xbb\xc9\xa5\x7f\x9a\xd3\x93\x7e\x84\x64\x48\x99\x9b\x7d\xa9\xca\x43\xb9\xcc\xcb\x8f\xe2\x93\x54\x9c\xf4\x53\x13\xd4\xee\xd5\x72\x14\x12\x30\x75\x7a\xa9\xe1\x62\x2e\x7d\x9e\x2a\x39\x8c\xbd\xb8\x9b\xf6\x81\x51\x7a\x9f\xe8\x33\xad\x9c\x60\x4f\xfe\xdd\xb6\x23\xf9\x87\xc6\xf1\x75\x53\xd3\x49\x43\x4e\xb7\x82\xc9\xfb\xfd\x77\xf4\x9f\xb9\xad\x45\xfa\x5a\x3b\xde\x85\xc7\xac\xc8\x6e\xce\x23\xb9\x24\xdb\x29\x60\x01\x5a\x26\xfa\xd6\x02\x76\xac\x44\x93\x4e\x52\x52\xfa\x91\x88\x3c\xbe\xfe\x59\x92\x1a\xce\xec\x02\x2b\x43\x3f\x0a\x2c\x89\x30\x21\x66\x09\x9b\x32\x39\x5d\xe4\x01\x61\xae\x96\x2f\xf3\xda\x1f\x97\xe1\x6f\x19\x31\xe1\xd6\x89\x0e\x19\x4d\x30\x9f\x17\x53\xe6\xd4\x9a\x5d\xfd\xdc\x33\x87\xfe\xfb\x3f\x5d\x82\x72\xb4\x14\xc9\x08\xe2\xc4\x0a\x8b\x1d\xb0\x68\x2c\x6b\xb1\x5b\xca\x65\xa4\xc3\xd0\x92\x47\x19\x94\xf2\x5d\x59\x19\xf2\x81\xf9\xf1\x15\xfb\xe8\xf9\x94\x29\x1b\xc4\x93\x07\xb9\x37\x19\x27\x46\x42\x8f\x88\x8c\x3e\x86\x00\x77\x99\x04\xa6\xee\x76\xbd\x79\x7e\x6a\x9c\x4a\xfb\x95\x57\x9b\x70\x4e\xf6\x77\xc7\x57\xf8\xc7\xd8\xcb\x9e\xdd\xbc\x64\x22\x13\x01\x23\x00\x80\x13\x15\x1b\xf6\x77\x92\x56\xdc\x6e\x23\x32\x55\x86\x83\xe5\x0b\x36\x0f\x50\xa8\xf5\xc5\x24\xb3\xfd\xb8\x1f\x52\xf1\xec\x23\x55\x4c\x5c\x79\x43\x3c\x34\x42\xa6\x96\xf5\x76\x18\xfb\x74\xfb\x96\xe4\x31\xf3\x02\x77\x9f\x35\x7e\xad\x1c\x1e\x4c\x72\x21\x0c\xfd\x1d\xfe\x6c\xb6\x68\x4a\x92\xbb\xb0\xbc\xe4\x2a\x88\x1c\xe3\xbf\x09\x5c\x5a\x49\xee\xf1\x7d\x82\x97\x12\x3d\x12\xc5\xff\xbe\x64\xef\xb8\xe8\x88\xaa\x41\x42\x12\x5a\x66\x7e\xca\x99\xed\xeb\x8f\x81\xe8\xcf\xfc\x6b\x05\xae\x68\xde\x10\xb2\x8a\x98\xdc\xdd\xf0\xf3\xfb\xb5\x3f\xf9\xcf\xd8\x09\xfd\xb7\xff\x1f\x77\x38\xa8\xd0\xae\x14\xdf\x31\xeb\xcb\x8e\x27\xb8\x20\x09\x56\x2f\xd2\x80\xc2\x56\x9d\xcd\x26\x45\x28\x8d\x78\xb9\x34\xd9\x38\x43\xab\xeb\x5a\x65\x18\xa4\x7e\x37\xf5\x49\xe7\xce\x19\x75\xc3\x98\x8f\x54\x32\xa0\x24\xef\xfe\xb6\xcc\xde\xc0\xa6\x20\x52\xd7\xa8\x62\x4a\x89\xee\x9e\x77\x8b\x87\xfd\xf6\xf9\xe1\xd6\x8a\xfe\x6c\xbf\xbe\xbc\x3c\xfc\xb9\x7f\x58\x3f\xae\x9d\x9f\x25\x31\x95\xdc\xe6\xa7\x5c\xa5\xfa\x68\x02\x23\x0f\x63\x1b\xdf\x3f\xc0\xcf\x51\x2d\xcb\xf8\xc5\x6a\x4f\x50\xda\x03\xd4\x21\xa3\x74\xd0\xde\x38\x01\x73\x49\x49\xa9\xc3\x84\x5c\x2c\x0a\x93\x52\x52\x71\x62\xd6\x48\x1d\x0a\x92\x4a\x1d\x2c\xfe\xe3\x59\x33\x87\xb0\x56\x1e\x98\x3a\xb2\x76\x55\xb4\x09\x5b\x8a\x26\x5f\x50\xc1\xcf\xec\x1d\x8a\x05\x06\xac\x61\x73\x2c\xbf\x0a\x2b\xba\xa3\x52\x5f\x48\xb7\xc2\x99\xf2\xd2\x49\x07\xe9\x6b\x3b\x91\xe7\xf3\xc2\xca\xf7\x92\xd0\x6c\xa6\xaf\x86\x33\x81\x82\xdc\x9f\x0f\x64\xe5\x7b\x9c\x85\x23\xd2\xa2\x9b\xb3\xfd\x07\xce\xb2\xfd\x81\xf2\x03\x70\x62\x8e\x66\xae\x3d\xeb\x0d\xb4\x16\xc0\xdd\x3c\x3f\x20\x28\x3f\x8c\x68\xb4\x5e\x04\x0e\x95\x9f\x24\x3c\xed\x75\xc3\x6c\x96\x7c\xde\x1b\x50\xa1\x17\x90\x48\xcc\xef\x7f\x2e\xaf\x74\x9c\x0f\x22\xa8\xd0\x53\x9a\xb9\x4a\xe2\x42\x67\xaf\xa7\x39\x26\x00\x15\x0a\xa3\x69\xaf\x33\x51\x16\x20\x65\x66\x2a\xe4\x6d\x6b\xe4\x49\x5a\xe7\xc5\xe9\xec\x48\x2d\xd7\xc5\x6a\x77\x3f\x64\xb5\x04\x15\x85\xd2\xac\x25\x04\x14\x31\x40\x0c\x92\x31\x1e\xc6\x9f\x54\xc4\x35\x51\x93\x2d\x4b\x09\xcb\x32\x77\xc4\x2d\x2a\x0e\x12\xe2\x93\x7c\xcf\xaa\xe6\x84\x06\x6c\xf2\x52\x66\x7d\x1e\x56\xc5\x11\xa3\x57\x99\x97\xaf\x8e\xac\x98\x78\x01\xe6\x55\x0a\x40\xc5\x00\xd4\xdf\x52\xb4\x90\xaa\x86\xea\xa8\xd8\xdb\x76\x99\x1a\xf6\x99\xab\x91\x34\xdb\x33\xd1\x3e\xad\x07\x4b\x38\x1c\x21\x7b\x75\x9c\xeb\xd3\xc1\x38\x39\x2a\xf5\x34\xed\xa6\xdf\xcb\x2a\x57\x23\x52\xbe\x39\xa3\x45\xf1\x48\x50\xca\x5a\x54\x99\xc0\x0e\xd6\xa0\x78\xaa\xc8\xf7\xa8\xdf\xca\x0f\xf2\x7d\xba\x06\xa9\x8d\xe0\x0b\x95\x7c\xba\x18\x6d\x85\x6a\x59\x66\xe3\x54\xc7\xfc\x90\xe2\xca\x23\x2d\x91\x43\xa9\xb0\x3b\x29\x40\x42\x4c\x3e\xf8\xf3\x98\x55\xb8\xa8\xeb\x52\x66\x17\xb5\xa4\x0a\x90\x27\xbe\xc1\xc7\x42\x96\xd7\x53\xbf\x54\x09\x16\x10\xc4\x7f\x93\x1d\x4e\xe5\x7b\xf6\x52\x95\x1a\xeb\xba\xac\xa6\xe7\x91\xa0\xc8\x6a\xb4\x0c\x38\xfb\xf7\x4b\x0a\x1c\x25\x95\x09\xef\x56\xa8\x10\x0f\x83\x50\x89\x52\x9e\x69\x39\xc0\x4f\x13\x6a\x6e\x4d\x9a\x6e\xb4\xa8\x94\x51\x8a\xc8\x92\x28\xbc\x4c\xd4\x41\x40\x29\x0c\x53\x6b\x58\xb9\x95\x6e\xb8\x43\x28\x0c\x39\xa5\x7a\x8c\x5f\xd1\x9a\x2e\x93\xd4\xb1\xc2\x84\x99\x1e\x8e\x1a\xff\x36\xab\x50\x36\xb7\x28\xb2\xe9\x02\x85\x3c\xf4\x79\xaf\x1c\x70\x8d\x3b\xea\xca\x24\x46\x91\x78\x7d\x76\xea\x9f\x27\xa2\x38\xcf\xcf\x9b\x01\xd5\xc5\xe4\x08\x1d\x04\xc6\x8f\x6a\xa0\xc1\xad\xa9\x43\x9c\xbc\x58\x9d\x70\xd6\xc9\x8a\xde\x62\xdd\x54\xe5\x79\xe0\x51\x8c\xef\x5f\x8b\x90\x58\x32\x57\x39\xb6\x6f\xb9\x1f\x85\x5a\x18\x81\x07\x53\x8c\xeb\xe4\xb4\x40\x69\x25\x43\x87\x12\x6d\x9d\x18\x54\x16\x1b\xfe\x1d\xb2\xc6\xe0\xf7\x27\x37\x84\x5e\x9a\xf0\xa0\xcf\xb7\x2c\x0a\x75\xa9\xfa\x05\xc8\x3c\x8f\x10\x92\x06\x45\x05\xc5\xdd\xa9\x18\x19\xee\xa3\x49\x85\x4c\x98\xfa\xee\x63\xd9\x55\xcd\x4e\x3a\x68\x83\x8a\x21\xed\xcd\x69\x31\x0a\xfa\x91\xa4\x30\x5e\x5f\x6a\xd4\x7a\xbe\xdb\x06\x8f\xe1\xe4\xe6\x03\x66\xa8\xbc\x6a\x6c\x8c\x1a\x65\xcf\xdd\x3f\xbb\x3a\x60\xe0\x23\xcd\x21\xe2\x6e\xbf\x2f\x8b\xd7\x9b\xac\x18\xc6\x2a\x31\xf2\x80\x80\x51\x5f\x2c\xf5\x53\xf7\x3b\x26\x06\x30\x55\x41\xd1\x2c\xcc\x97\x1d\x9f\x3a\x8e\x53\xdf\x21\x5f\x4f\xe7\xcb\xd2\x0f\x4c\x22\xa4\x20\xa3\x53\x71\xbf\xd9\x2c\xea\x4e\x65\x08\x30\x81\x80\x75\x5a\x09\x8f\xd8\xc0\xe4\xf0\xd4\x93\xc4\x22\xfb\x23\x93\x46\xaa\xac\x75\xb2\xd6\xcb\xe7\xc9\x6d\xa4\x89\x47\xaf\xe4\xf1\xaf\x32\x2f\xb2\xee\xfe\x53\xed\x3b\x5d\x6f\x97\xdc\xdb\xe1\xcf\x86\x64\x64\x86\x2a\xa0\x80\x10\x26\xbd\x61\x70\x98\x1a\xb6\x08\x52\x44\x38\x0a\x0a\xc9\xb2\x4f\xe4\xa0\xf0\x74\xd2\xbe\xa7\xaf\x35\x56\x4e\x10\x6b\x7b\x2d\xeb\x88\x82\x45\xb4\x1a\x9a\x5a\xc1\x6d\xd3\xae\x47\xaf\x96\x5f\x9b\x45\x17\xf3\x74\x34\x86\x44\x68\x24\x22\x68\xa1\x5f\x5a\xc4\x74\x57\xd5\x81\x22\x16\xe1\x50\x4f\x79\x9c\x82\x9e\xde\x07\x1a\x49\x0d\xb2\xd6\x27\x0f\x2c\xa5\xe4\x36\x3b\xbe\x95\xed\x2e\xf1\x39\x86\xd0\x1d\x85\x7e\x60\xdf\xe2\x1d\x3a\x9d\xa7\xd1\x79\x55\x60\xb2\xa4\x0d\xd6\xcd\xba\x5e\xf6\x75\xa2\x6d\x0b\x30\xe7\xbf\xc1\x14\x57\x8e\x2a\x02\xca\x79\x3f\xc1\x21\xeb\x10\xa7\xe3\x41\xd0\xee\x82\xa6\xfc\xba\x9d\xf2\xad\x57\x39\xf4\x02\x51\xa5\x66\x16\x54\x65\x33\x20\xdd\x1d\xd8\x94\xa8\xb8\x34\x65\x7a\xc6\x34\xdc\x96\xb9\xba\x2b\xab\xdd\x5b\x56\x7f\x81\x2e\x8c\x80\x3a\x8d\x8c\xce\xdb\xc1\x21\x08\x47\x7a\x4f\x6d\x87\x98\xa2\xcd\x2f\x7f\x3c\x38\x13\x66\x72\xa7\x5a\x46\x94\x14\xf9\xfd\x2c\xb0\xba\x87\x42\xe5\xd7\xea\xc8\x50\x6b\xa0\x60\xf7\x6a\x77\xbf\x7f\x5c\x3f\xed\xbf\x3c\x2f\x1e\xec\x85\x34\x8b\x34\xb9\xf8\x86\xe1\x8b\x98\x6b\x46\x52\x4a\xae\x5b\xc2\x5d\x4d\xe0\xed\xd3\xd6\x0d\xdd\x51\x52\xcc\xf5\xd4\xc8\xec\x37\x58\xe4\xf9\xcb\xc6\x01\xaa\xb4\x1f\x08\xb3\x26\xef\xee\x57\x9b\xcd\xea\x76\x28\x7e\x0a\x3a\xe0\x5e\xe0\xb2\x8f\xad\x8b\xda\xbe\xb1\xae\x0d\xe3\xd8\x2e\x10\xa6\x96\x62\x3d\xf1\xbe\x74\xc8\xd2\x44\x75\x17\xfd\x44\x8e\x0d\x74\x18\xfb\x54\x93\xd9\x5e\x68\x83\x43\x17\x44\x87\x52\xc5\xd6\xf8\xbc\x87\x7c\x2a\x93\x00\x3a\x8e\x8c\x6b\x6a\x84\x0d\x0d\xf1\x33\x15\x51\x0c\x93\x9b\xfd\x58\xd0\xb1\x34\x71\x00\x32\x66\xf3\x2b\x30\x82\xff\x9b\x5c\x43\x1b\x89\x0b\x33\x3a\x09\x45\x33\x83\xdc\x1a\xb8\x56\x3a\xf1\x0d\xcc\x28\xab\xbb\x65\xc0\xb6\xa4\x7e\x44\x7c\x79\x5d\x1c\xe2\x97\xea\xec\xc3\x0f\x99\x0a\x45\x81\xf2\xdd\xfa\x76\x31\xc4\xb8\x6b\x1e\x25\x91\x25\x42\xb5\x3e\xed\x6c\x64\x5c\x73\x95\x72\xe9\x80\x00\x59\xd1\xd8\xa1\x35\x67\xd0\x6b\x08\x12\x2a\x8a\xfb\xe3\x71\xf1\x87\xbb\x0e\xc4\x4a\xd9\x05\xd3\xee\x4d\x0f\x65\x3d\xbd\x08\x70\x83\x56\xeb\xd8\xf7\xe6\xec\x01\x2d\xb8\x66\x93\x45\xfc\xe6\xbc\x56\xeb\x66\x72\x37\x93\x8f\x21\x3d\x88\x86\x44\x72\x63\x0d\xcd\x71\x5f\xe5\x33\x2a\xbb\xd3\x90\xe5\xc3\xd8\x50\xd7\x9c\x24\x3d\x03\x6a\x3b\xe3\x69\x97\x34\x63\x62\xd6\x17\xd3\x2a\x0a\x53\xd5\xf1\x80\x55\x30\x4c\x06\x5c\xc5\xc0\xb8\x63\xa5\x91\xed\xa5\x82\x4d\x22\xae\x77\x16\xf7\xe3\xf6\xf1\xd7\x25\xdd\x5a\xfb\x9e\x13\xe4\x79\x80\xda\x45\x1b\x1d\x63\x9b\xf0\x3c\x1e\x51\x05\xe4\x9f\xe5\x69\xa8\x36\x23\x3c\x0f\x18\x4d\xff\x2e\xdb\x39\xe5\x47\x1f\xde\xa7\xf0\x3c\x85\xf4\x8c\xa7\xc2\x6d\x37\xdf\xcb\xea\x07\x56\x0b\xad\x51\x36\x63\xee\xa9\xc9\x91\xed\xfb\x71\xf5\xd0\x8b\xdb\xdb\x8d\xbb\x03\x16\xb1\xc4\x0d\x3b\x72\xcb\x46\x49\x01\xe1\x11\x51\x97\x33\xa1\x8c\x32\xe1\x84\xc3\x41\x78\x3e\x4b\x3a\x14\x46\x81\x4d\x5f\x72\x36\xfc\xa8\xc2\x0b\x40\xd1\xc3\xf6\x77\x3f\x17\xb2\xb0\x9d\x63\x2f\x25\x34\xe6\x43\x99\x43\x8f\x9a\x16\x5e\xe2\xa5\xb4\x63\xdc\xc2\x6b\xd3\xfd\x16\xa4\x26\x3d\xf9\x06\x15\x06\xdd\xaf\xa1\x07\x76\x42\x90\x80\x41\xeb\xf3\xee\x4a\x63\x6d\x8d\x6f\x2c\x49\x34\x01\xf2\xbe\xbf\x41\x07\x3d\x11\x5e\x92\x9a\xa8\xf7\x75\x22\x0e\xdb\x11\x42\x41\x5f\x17\xea\x1f\xf7\x5d\x6a\x55\x78\x22\x56\x91\x21\x0a\x39\x1e\xcb\xaa\x59\x1f\x8e\x08\xf2\xed\xd0\x01\xfd\x84\x27\x84\xa2\xfb\x6e\x5f\xc0\xae\x5c\xd4\x32\xcb\x2c\x0f\xc0\xf8\xe3\x49\x1f\x0d\xef\x11\xd6\xcd\x5e\x40\x9d\xc9\xf6\x15\xef\x3e\xca\x05\xdd\xda\xee\xad\x2a\x3f\xdc\x39\x65\x14\x53\xd5\xc3\x6a\x14\xb7\x1c\x2e\xb7\x93\x91\x21\x53\x33\xd9\xb3\x22\x6b\x48\x7e\xe4\xd7\xd1\x57\xe1\x49\xee\x0b\xa3\x5d\x5a\x9b\xc9\x56\x56\x77\xe5\x25\xb0\xbc\x5b\xdd\x85\xa7\xbc\x80\xb2\x15\x1a\x3b\x11\x7b\x45\x88\x87\xfa\xce\x30\x6c\x57\xbf\x75\x3d\x4d\x15\x49\xcf\x6c\x7b\x83\x05\xea\x4c\x66\x50\x65\xfd\xe7\x41\x16\x28\xa7\x99\x8e\x64\xd8\xef\x3e\xca\xae\x51\x19\xf1\x17\x12\x20\x29\x7f\xcc\x94\x3d\xdb\x8e\x3a\x49\xc2\xc0\xa1\x1a\xd5\x20\xff\x27\x98\xe7\x01\xa1\x4a\x8e\x65\x9e\xc9\x0c\xeb\x71\x63\xc2\x8d\x48\xa2\x83\xc8\x3f\x4f\xb2\x5d\x82\x79\xc2\x70\x98\xdf\x67\x55\x79\x3e\xfd\xc8\x88\xc1\x19\x9c\xbe\x93\x60\x0c\x62\xca\x3b\xaf\x36\x5f\x9e\xd7\x4f\xdd\xaf\xa8\x62\x7b\xe7\xfd\xf2\x7f\x57\x56\xdf\xb3\x42\x95\x1f\xb3\xab\xa9\x60\xbe\xe7\x39\xb1\x24\x2b\x9a\x3a\x51\x18\x1b\xdf\x99\xcf\xe4\x00\x42\x4c\xf2\x4b\xd7\xc0\x8c\xee\x08\x30\x9a\x26\xfb\x1e\x5c\xf8\x64\xc4\xd5\xd7\xc5\xf1\xd4\x4c\xcf\x8f\x46\x75\xa1\x2e\xcb\x8f\x37\xe8\xde\x59\x10\x79\x86\x0d\xa4\x26\x9e\xaf\xf2\xe7\xd9\xb5\x84\xcc\x60\x0d\xcb\xa2\xfd\x92\xeb\x7a\xdb\x88\xae\x29\x08\xdc\x5e\x74\xc9\x74\x39\xb9\xcb\x88\xa5\xac\x93\x9d\x29\x4e\xf5\xcd\xf9\x76\x68\x77\x4e\x3a\xc7\x11\x45\x50\x2b\x28\xd4\xfa\x4a\x32\x5f\xb0\x28\x09\x84\x2d\xd9\x23\xb8\xeb\x43\x29\x7f\xcc\x80\xc6\x04\x4b\x59\x14\x5b\x2d\x51\x74\x51\x7c\xc1\xd2\x88\x51\xfd\x20\xb1\x1c\x96\x45\xdd\xb3\x48\x09\x06\x01\x0b\xc3\xae\x74\x74\x61\x20\xba\x6a\xc6\x68\x11\x0c\x52\x64\x96\xe3\xf2\x11\xda\x85\x73\x8b\xd5\xbb\x9d\xde\xd6\x77\x16\x0c\x78\x48\xab\x18\xc5\x59\x5c\xd0\xc3\xc5\x13\x5d\x1f\x6d\x88\xd6\x0c\x75\xe8\xee\x76\x35\x79\x0a\x11\x9b\x60\xac\x9b\x7b\x37\x20\x7f\x3c\x2e\x9e\x16\x8f\x50\x9c\x7f\xbb\xb6\xff\x09\x26\xb8\x4f\x5c\x2c\x77\x8b\xe5\xee\x79\xb3\x67\xec\xb7\xae\x01\x1c\x6a\x3b\x3f\xc9\x1f\xe7\x53\xdd\xcd\x73\x26\x20\x8d\xfc\x01\x2a\x97\x02\xa5\x4b\xbc\x82\xb8\x13\x4c\xe8\x80\x46\xd5\x97\x76\x84\x43\x3d\x62\xd7\x10\x4c\x86\x91\x74\xd9\xed\xb7\x2c\x07\x85\xf9\xf1\x2d\x83\x9b\x69\xc0\xb9\xed\x09\x89\x05\xb3\x50\x20\x6d\xfe\xc3\xcb\xc8\x68\xec\xd1\x7a\xf5\xad\x6c\xf0\x11\xb2\x62\x5d\xe8\xf2\xe6\xbc\x2d\xe0\x58\xbf\x95\x96\x8e\x73\x72\x18\x84\x1c\xfa\xf2\xa3\x11\x5f\x85\xed\xa2\x82\x38\x56\x03\x63\xe1\x03\x2a\x45\xf2\x1f\xe3\x33\x29\x29\x09\xce\x2b\x5a\x27\xdf\xb0\x44\x0e\x87\x84\xd2\x46\xe4\x5d\xff\x3c\xde\x66\x17\xe4\x35\x93\x87\xc1\xd0\xf3\x46\xa6\xed\x5d\x55\x1e\x76\xe5\x7a\xb9\x78\x69\x77\x12\x62\xf8\xc2\xa1\x13\x30\xe5\x38\x18\xbd\x6a\x8c\x80\xea\x9a\xaa\x32\xc7\x7b\xa8\xaf\xa4\x71\x5d\xe7\x44\x13\x21\xf0\xb1\xac\x27\x84\x33\x82\xa1\xe4\x44\x30\x49\x33\xcb\xb1\x5d\x5c\x79\x92\xc9\x13\xe9\x20\x25\xab\xba\x38\x1d\xf6\x6f\xed\xa9\xf7\x95\xcb\x9a\xbb\x1e\x32\x90\xd6\x0d\xfa\x66\xa2\x84\x66\xde\x12\x51\xc7\xe8\x64\x3e\xf3\x20\xb1\x69\xa5\xdb\xea\xf4\x7a\xf9\x31\x7c\x16\x7a\x60\x91\x15\x5f\xb7\xb7\xf3\x03\xd4\x67\x2a\x0c\xad\xd6\x82\x51\x09\xf9\x58\xc2\x05\x2c\x41\xf8\x7e\x64\x6b\x41\xef\x17\xdb\x55\xb8\xb7\x15\x5b\x5d\x65\x91\xf0\xc3\x24\x15\x0e\xc0\xd7\xae\xb0\xf5\x73\xd1\x37\x19\x6c\x98\x79\x59\x8b\xe5\xfa\xca\xad\x44\x52\x50\x55\xc6\x5d\x83\xf2\x2d\xfb\x9f\x3b\x3c\x66\x01\x05\x2b\x0e\x04\xb2\x9d\xd3\xc3\x16\x7e\xcc\x53\xde\x71\x31\x66\x72\x80\x1c\x74\xd3\xdd\x4f\x34\x50\x9d\x4e\x51\x3e\x6b\xb2\x16\x16\x06\x1d\xdd\xfa\xee\x2e\x78\x5f\x76\x40\x2c\xe1\xa7\x1e\x50\x7c\x34\xab\x6f\x5a\xdb\xda\x54\xd2\x4f\xde\x30\xf7\x8c\x9a\x10\x28\x45\x24\x51\xf3\xcf\xc5\x43\x41\x38\xa7\x2f\xce\x5a\x75\x3a\x49\xb3\x83\xcf\xe7\x3c\x0e\xac\xdc\x09\x69\x18\x4f\x46\xea\x5c\x9c\x96\xf9\x76\x86\xf9\x10\xcb\xc4\xbe\xac\x1f\x84\x06\x74\xab\xa8\x0f\x52\x04\x13\x3e\xba\x81\x2f\xd8\xb6\x4b\x61\xc7\x93\x95\xff\x82\xd7\xee\x60\x19\xa5\x69\x57\x05\xf1\x8e\x45\x73\xaa\x70\x12\x90\xb0\x3d\x95\x1f\x99\xdc\xae\xc3\xaf\x2c\xdf\xa0\xca\x9a\xf3\x1d\x4e\x5f\x1e\x7a\x86\x66\xe1\x90\xbd\xb6\x3e\xed\xa0\x9a\x44\xf8\x98\x84\x84\x7f\x3f\xc0\xcf\x2d\xca\x53\x7b\x82\x2f\x27\xa8\x94\xd1\x53\x74\x9d\x30\x41\xde\x59\x04\x57\xe7\x60\x6f\xcf\xf9\x3a\x06\x02\x49\x93\x5e\xbc\xf9\x16\x63\xdc\xed\xe4\x53\xe8\x58\x52\x4a\xb6\x9d\xae\xed\xb3\x3a\x3b\xce\xd7\x12\x13\x2b\x37\xfd\x05\x2a\x85\xc5\x15\x0c\x86\x08\xbc\x48\x12\x17\xaa\x49\x41\xad\x0a\xf5\x05\x0e\xb8\x2c\x0b\x9d\x67\xb2\x19\xb1\x54\x99\x2f\xd9\xdf\xf7\xd0\x5f\xbf\xe4\xc2\x1d\x57\x76\x8d\x10\xd5\x74\x51\x7a\x33\x0a\xeb\xa6\x97\xfd\xfa\xcd\xb5\x72\x49\x51\x6d\x13\xc1\x74\x3f\x82\x20\xba\x42\x71\x12\x22\xc7\x6d\x59\x35\x5d\x8b\x96\x89\x41\x0e\xd7\xcd\x38\xf1\x6a\x3b\xb0\x24\x26\x36\x3c\x57\xae\x78\x89\x57\x13\x41\xbb\xb2\x01\x95\x95\xc2\xa1\x1c\x15\xe0\x88\x20\x64\x86\xb7\x11\x6c\x9c\x65\x84\xe6\x13\x41\x18\x87\x32\x70\xcd\x78\x8f\x55\xf9\x05\x8b\xf2\x30\x59\x02\x82\x50\x1b\x52\x8b\xc7\xf6\xd3\xda\x00\xc0\x42\xa9\xcb\xfc\xc1\xe4\x03\x45\x81\x4f\x0b\x97\x30\x0b\x8b\x0d\x90\x4d\x12\x48\x22\x88\x42\x8f\xb0\xab\xdb\xd6\xdd\x6e\x3f\x60\xdd\x54\x27\xd9\x94\xd5\x4d\x59\xe6\x04\x30\x19\x0c\xb4\x20\xe2\x29\x81\xc0\xf7\x35\x42\x7e\x0b\x0d\x6c\x9b\x0a\xe1\xaa\xa0\xe5\x25\x3d\xcf\xe8\x73\x46\x08\x26\x68\xd5\x94\xc7\x2f\xa7\x41\xde\x64\x74\x49\x8d\x64\x99\x19\x60\xfb\x4a\xf9\x51\xc4\xf8\x38\x7c\x37\x9c\xef\x41\x9c\xc6\x7e\xd2\x13\x18\x3d\xe7\xaa\x17\x85\x16\x41\x92\x40\xea\xe8\xf8\x4e\x87\x75\x21\xcb\xca\x24\x92\x6a\xe2\xf7\x47\xb5\xc1\xd6\x3f\x34\x18\xa9\xe9\x80\x48\x05\x90\xd1\xb3\x27\x34\xb0\x09\x02\xf6\x54\x53\x22\xe0\x01\x10\x48\xf1\x71\xf1\x74\xbf\xd8\xed\x16\x4f\x2f\x9b\xe7\x3f\xfe\x64\xdb\xdd\xe2\xdb\xaa\xeb\x13\x29\xb2\x1e\xf7\xa0\x48\x6b\x6c\xf5\xf3\x88\x55\x36\xda\xef\x07\x76\x64\xc0\x01\xc8\x66\xb5\xfa\x24\xab\xff\x9e\xb2\xe6\xec\x48\x9d\x5d\x1f\x19\x20\xeb\x71\x64\x0f\x25\x5c\xa9\x93\x64\xe3\x45\x64\xaa\xdf\xc6\xa6\x28\xba\xa1\xa1\x11\x70\xdd\xcb\xb2\xb8\x9a\xe2\x59\x8f\x26\x00\x5f\x6b\xe5\xcc\xf4\x33\xe4\xcd\xb9\xdd\xc4\x2d\x65\xe5\x2c\xac\x40\x04\xa0\x39\x15\x81\x5a\x75\xf9\x97\x09\x4a\xb8\x8f\xfb\xd9\xfe\xc2\x37\x44\xa7\x26\xa5\xe6\xfc\xa0\xab\x21\x97\x40\x08\xcf\xb7\x08\x84\x1d\x16\xd0\xad\xc8\x81\x90\x3e\xc5\xc9\x88\x49\xa2\x1a\xba\x95\x81\x54\x9e\xd9\x73\x4e\x79\x93\x39\x95\xb1\x29\xf1\xee\x64\x3b\x0e\x54\xc2\x12\x03\xd6\xc7\xf7\xfd\x07\xe2\x8f\xbd\x2b\x73\x12\x01\x72\xb3\xe2\xb4\x86\xf7\x64\xc5\x5c\x1f\x8e\xf9\xe5\xaa\x39\x5c\xee\xff\xde\xb2\xe9\xae\xa4\x0c\xc5\x20\x55\xb4\x38\x26\xf4\xe9\x70\xd6\x8c\x53\x14\xc0\xb2\x29\x12\x13\x12\xc9\xf0\xf6\x93\x4f\x63\xe0\x68\xce\xee\x21\xd7\xed\xca\xba\x68\x7e\xdc\x94\x93\x14\xa7\x08\xbd\xc4\xe8\xcd\xd9\x4d\xef\x1b\xb3\xb5\x94\xf5\x9c\xa3\x32\x7d\x69\xad\x3d\x17\x5a\x28\xcc\x0d\x14\x3f\x3e\x4b\xe7\x89\x90\x05\x26\xcf\x41\xab\x25\x0c\x57\xdc\xd0\x0f\x8d\x86\xf3\xfd\xfd\xed\x3c\xea\x6f\x38\xa2\x43\x5f\x19\xf2\xf1\x1b\xfc\xab\x2c\xb0\xfe\xff\x57\x2d\x2f\xc2\x40\xc6\x64\x24\x19\x0e\xef\x62\x10\x17\x0b\x43\x4f\x13\x1f\x55\x56\x64\x3d\xc5\xcb\xd5\x8d\x7c\xfc\x78\x61\x90\x12\xb6\xba\x3e\x66\xc5\x22\xcf\xdd\x29\x23\x34\x21\x38\xaa\x62\x5b\x2e\x5e\xdc\xef\x71\x28\xa8\x1c\x9c\x50\xac\xf5\x36\x2b\x24\xb6\x8e\x4c\x47\xd6\x2e\xc2\x38\xf2\x08\x3d\x77\x97\x41\x33\x46\x2e\x89\x30\x4e\x84\x25\x44\x7f\x2f\x7f\x0c\xe9\xa9\x45\x98\x84\x11\x35\x3d\x2c\x16\x9b\xd1\x4b\x4e\x3d\x83\x42\x6f\x7a\xe9\xf7\xdd\x5b\x85\x23\x65\x16\x11\xa6\x81\x49\xce\x34\x25\x65\x35\xba\x9f\x41\x7b\xc2\x71\x1f\x63\xdd\xf4\xfb\xd1\xe4\x35\xf0\x38\x04\x9b\x7c\xbe\x3d\x15\xaf\x58\x16\x4f\xf8\x71\x97\x97\xe5\x65\x1c\x6d\x3c\x12\x81\x19\x1a\xce\x6f\x59\x9d\x19\x3e\x91\x5b\xac\xb2\xf7\x6e\xb9\x0c\x41\x1a\x36\x4a\xa2\x3c\x3a\x40\x73\x8b\x32\x3b\x40\x3e\x1d\xd1\x22\x32\x25\xb6\x5f\xe0\x90\x35\xe7\xd1\x1b\x10\x22\x66\xda\x6a\x6d\xf5\x36\x25\xf3\x3c\xef\xe0\xba\xc8\xc4\xa7\x75\xbb\x83\xdf\x1b\x38\xc3\xf8\x19\x25\x30\x82\x69\xab\x72\x22\xbb\xf1\x99\x4e\x80\x08\xa5\x4e\x9d\x50\x84\x01\x23\x2e\xcb\xbc\xac\x76\xe7\xa3\x33\x6b\x43\x05\x31\xe1\x71\xd6\xb5\x35\x06\xdd\xef\x22\x26\x6b\x65\x57\x41\x53\xfe\xe8\x7e\xd5\x92\x10\x4f\xd2\x0e\x8e\xc7\xa1\xe8\xc8\x15\x0a\x88\xf1\x1d\xa1\x17\xb1\xa0\xe7\xc5\xa6\x97\xd5\x17\x7f\x88\x10\xb5\x22\x47\x7c\x53\x8a\xb2\xb9\xd9\x7d\x26\x0e\x28\x42\xcd\x7c\x1a\xd1\xa6\x04\x8c\xca\xa4\xc7\xed\x81\x0e\x54\xc7\x96\x3b\x69\x4b\x38\x65\x51\x37\xf8\x17\xfe\xc8\x7e\xcf\xba\x8d\x3f\xf2\x38\x32\xe5\x90\x6d\x94\x8a\xa7\xe8\x86\x6d\x65\x41\x4a\x2f\xec\x08\x55\x8d\x8e\x0e\x67\x30\x1b\x22\x16\x18\xcb\x93\x08\xc3\x3a\x5e\x1b\x11\x31\x9e\x72\x1b\xec\x1b\xd1\xd3\x0f\xef\x2a\xf2\x3d\x53\x84\xa2\x2b\xb4\xfc\xd2\xb7\x0e\x1b\xe6\x7a\xf8\x40\x60\x20\x8a\x9f\x5e\xe8\x36\xda\x4e\x21\x4f\x49\x41\xfa\x40\x38\xb8\xcb\xb2\x70\x11\x85\x52\x68\x47\xe1\xd6\x0e\x87\x41\x8c\x22\x8a\xbd\x94\x96\x4d\x8b\x9c\x24\x21\x34\xe3\x1e\x3e\x17\x57\xc2\x72\x51\x1c\x9b\x75\xec\x44\xa4\xf1\xa8\x96\x65\xde\xba\x3e\xd5\x74\x3b\x8e\x62\x15\x92\x5d\x08\x26\x15\xfc\xe4\xca\x82\x44\x14\x6b\x8f\x0a\xf2\x8d\x33\x63\xbc\xfe\xbb\xaa\x3c\xac\xfe\x78\xde\x0c\xa0\x7c\xb3\x6b\x61\x94\x04\x31\xf1\xeb\x61\xf3\xb6\x33\x90\x4a\x97\x0a\x7a\x3e\x35\xc7\xd3\xa5\xca\xcf\xe4\x70\x50\x14\x75\xa0\x83\x3e\xc0\x11\x41\x88\x28\x91\x06\x90\xb4\x7c\xfe\xb6\xda\x2c\x9f\xd7\x4f\x66\x7a\xcf\x11\x4c\x8f\x5f\x48\x1a\x70\x87\x79\x6d\x07\xa6\x25\x8a\x37\x56\xc3\xc8\xb6\x8d\xd2\x58\xd3\xe6\xba\xc7\x43\xd6\x7c\x2f\xab\x1f\x1b\xaa\x95\x99\x87\x38\x8b\x28\x55\x92\x9e\x74\x4b\x34\xd1\xbd\x58\xf6\x8a\xaa\xde\xdc\x44\x8a\xb8\x27\x09\xca\x3d\x28\xb2\x1a\xae\x4c\x11\x67\x8c\xd6\xe6\x1c\xaa\x57\xac\x9b\x17\x2c\x5c\x2a\x5a\x44\x3c\x8c\xd0\xfa\xba\x46\xde\x6f\xf3\x30\x3f\x5c\x79\xc2\x88\xc3\xa8\x2c\x2c\x15\xd1\x06\x41\xbe\x4d\x52\xca\x22\xe2\xa9\xaf\x2d\xe7\xca\xf3\xa9\xe9\x6a\xb6\x5d\x2b\x44\xd2\x04\x54\x4d\xec\x93\xb0\x72\xfd\xbd\x28\x4d\x15\xb7\x5d\x89\x94\xa9\xa8\x39\xf5\x65\x1b\x22\x02\xcf\x50\xf2\x58\x50\xe1\x9f\xe8\x44\x67\x44\x04\x22\xa0\x09\xa5\x0c\x96\xea\xb6\x0f\xf2\x46\xa0\x18\x45\xaf\x4d\xee\xae\xf5\x7a\xc8\x01\xa7\x18\x4d\x59\x4d\x4c\xd5\x08\x94\x29\x37\x7d\xed\x18\x1d\x3a\xc9\x15\x11\x09\xf0\xe8\x63\x13\x9c\xb1\xb6\x48\x44\xd7\x28\xfd\x80\xb8\xae\x5e\xf3\x52\xb4\x0b\x86\xc4\x99\x64\x56\x24\x03\x4d\x03\x6d\x4e\x65\x74\x7c\x27\x12\xcc\xfe\x6e\x72\x1f\x37\xed\x88\x72\x01\x81\x48\x31\x19\xb8\xbc\xff\x03\x6d\xb7\x50\x3c\x57\xab\xff\x9e\xa0\x5b\xc0\x54\xcc\x29\x26\x66\x1e\xfb\x11\x7e\xce\xa9\xbc\x8b\x48\xf1\x50\xdb\xdc\x28\xe5\x7b\xcc\x22\x72\xcd\x7b\x1b\x1f\x8b\xcc\x30\x98\x92\x70\x75\xeb\x11\x6f\xfb\x59\x8e\xbe\x4f\x10\x88\xfb\x53\xf1\xf3\x74\x0f\xc7\xe3\x68\xc3\x8c\x30\xe5\x86\xed\x4c\x96\x84\x62\xea\x3f\x17\xa2\xe7\xc5\x1d\x68\x96\xb6\x9f\x27\x38\x8c\x70\xdd\x22\xd2\x3e\x3a\x87\xc2\x52\x4d\x6c\xa6\xba\xd1\x22\xd2\x11\x3a\xf8\xed\xe2\x1d\x1a\x98\xab\xde\x15\x91\x06\xcd\x13\x67\x18\x7f\x77\x25\xd2\xdd\xac\xd5\x52\x53\xe1\x0f\xd2\xb4\x5b\x9c\x9a\xd2\x8d\xeb\x89\x79\x10\x7b\x91\xa6\xbd\xdb\x08\x94\xec\x4a\xef\xa7\x68\xe4\x7e\xda\x49\x02\x85\x8d\x2b\xc8\x6a\x24\x26\x48\xff\xeb\xd6\xb9\x03\x31\x63\x3e\xa1\x56\x33\x2c\x2d\x4b\xdd\x37\x68\xad\x00\xd7\x1c\xfa\xa4\xec\x23\x48\x42\xdc\xfd\xea\x7b\x22\x1d\xaa\xa0\x5f\x45\x7e\x8f\xef\x24\x48\x63\x2a\xbf\x24\xc8\x8d\x2d\x6e\x5f\x56\xe7\xba\x99\x29\x37\x9a\x5d\x4c\xe3\x40\x30\xc2\x70\xeb\xde\xd4\x9b\x74\xd0\x86\x20\xc3\x71\x91\x7d\xc2\x09\x28\xe2\xd0\x57\x06\x8d\x64\x18\x8d\x1f\xca\x9a\xc4\x06\xe6\x3b\x47\xcc\x4b\x0d\x11\x73\xd5\x85\xee\xe2\x28\xc4\xc4\xea\xc9\x64\xf5\x1b\xaa\x0d\x48\x1c\xba\x6f\x71\x1c\x60\x6c\x0b\x2e\x0e\xe5\xb8\x45\xfa\xc4\xba\x59\xcb\xb2\xc2\x1d\xc2\xa1\x1e\x47\xcb\x4c\x2d\x0f\xfd\x3d\x8d\xff\xf1\x7f\xc3\x24\x4f\xbb\x3b\xea\xc8\x39\x88\x35\x16\x6a\x36\x5b\x7b\xe9\xef\xc4\x89\xe7\x29\x07\x51\x28\x5f\x5d\xa2\x34\x4e\x52\x43\x22\x65\x12\x42\xed\x70\x59\x15\xea\xf6\x62\xa8\xc7\x09\x57\x24\xbf\xb4\x59\xfd\xf3\xeb\x6a\xbb\xdb\x2f\x17\x4f\xcb\xd5\xc3\xea\x76\x7f\xf3\xe7\x7e\xb9\x59\x2d\x76\xcf\x0e\x51\x10\xa7\x7e\x6c\x70\x3f\x70\x9e\xac\xd0\x71\xea\x4b\x53\xa1\x7d\x7a\x03\x91\x35\x5d\x6a\x30\x4e\x43\x65\x1c\x1b\x23\x53\xf6\x5c\x90\xb1\x30\xb9\x07\x1e\x85\x44\x1c\xfa\x48\xe4\x06\xd6\xdb\xfb\x14\x20\x24\x62\x9e\x04\xb1\x3f\xe1\xa5\xda\x9e\x44\x4f\x6c\xdf\x77\x15\xa9\x61\x32\xaa\xe1\x70\xcc\xd1\x54\x89\x3b\xa4\xb6\x88\x85\x45\x89\x1f\xa1\x6a\x0a\xac\xd8\xfe\x23\xeb\x6c\xb9\x58\x26\x51\x68\x56\x52\x87\xc6\x75\x0d\x1c\x28\x30\x6b\x8d\x94\x23\xaa\xa1\x2e\x8b\x88\x55\xe0\x11\x74\xa0\x1d\x90\x3a\x2f\x3f\xf6\xa7\xe3\xb1\x5b\xf0\x63\x95\xb0\xa8\x2f\xf2\xf8\xd2\x2f\x52\x57\x1e\x56\xa5\xca\x64\xd4\xa8\xff\xed\xe2\xf9\x17\x2f\x07\x3d\xa6\xba\x4a\xf3\xbd\xc0\x66\x0f\x4e\x3c\xc8\xdd\x02\x86\x06\x60\x65\x56\x27\x8b\x7d\xbc\x08\x55\xc7\x18\x1b\xe2\x1f\x59\x16\xef\x58\x35\xbb\x72\xf5\xb0\xfe\x63\xde\xc2\x8a\x51\x68\x92\xf5\xf8\xfd\xfb\xfd\x28\xa2\x63\x9b\xb5\x17\x05\x1d\xd8\xa1\xf9\x28\xd7\x05\x25\x34\x57\xff\xb5\xcc\x0c\xae\xcc\xcb\x75\xf7\x35\x15\x6d\xdc\x43\xfd\x36\x1c\x33\x73\x76\x7e\xac\xc3\x18\x95\x15\x8d\x24\x3b\x54\x4d\x9e\x43\x47\x82\xb6\xbd\xed\x5b\x95\x1d\x8e\x77\x50\xf5\x61\xdd\x58\xc7\x46\x99\x73\x09\xc5\x9f\x04\x49\x19\xee\x37\xb1\x96\xcc\x72\x05\x43\x76\x20\xc5\xa7\x6a\xfa\x60\x52\xb9\xcd\x6c\x55\xe8\xb2\x92\xb8\xc1\xf7\xac\xbe\x50\xc8\x14\x89\x27\x91\xe0\x8c\x37\xd8\xe8\x21\xfb\xa2\x48\x98\x85\x9a\x2c\x94\x1a\x40\x4d\x12\xa6\x35\x69\x01\x3e\xee\x6e\x97\xab\xcd\xd2\xf7\x5c\x83\x1f\x70\x2a\xef\x7f\xb7\x62\x47\x6e\xc3\xfb\x9e\x35\x6f\xcb\x72\x30\x7b\x86\xaf\x29\x09\x3c\x4d\xc8\x99\xf5\xf2\x99\x68\xcd\xca\xca\x77\x27\x0c\x58\x4c\x43\x6c\xd5\xbc\x89\x4b\x45\xe1\xcf\xb7\xf3\x24\x48\x0c\x64\xe3\x35\x7b\xc7\x45\x9e\xf7\x1c\xcc\x22\x09\xc0\xc0\xf2\x0e\xf5\x6b\xfd\x1d\xb2\xd6\xdb\x20\x8d\xd2\xf1\x09\x42\x2f\x09\x45\x07\x46\x82\x73\x79\xea\x4c\xa7\x24\x0c\x3c\x82\xab\x1a\x09\xc4\x3d\x55\x77\x75\x6d\x91\x11\x51\xa8\x91\x64\xc2\x4f\xc7\xf1\x67\x4f\xc2\x44\x11\x39\x88\xe1\x35\xd9\xf6\xb6\x5d\x12\xb6\xdb\xdf\x48\x2a\xa2\x1e\xf0\x90\xf4\x17\x47\x25\x1d\xc8\xf6\x2e\x2b\x20\x1f\x7e\x9d\x50\xc7\xbd\x84\x0a\x28\x7c\x81\x0a\x0e\xd8\x38\xa9\x9c\x61\x3c\xfd\x17\x15\x03\x93\xf7\x19\x79\x89\x43\x38\xed\xa0\xfe\xb1\x98\x51\xbe\x14\x49\xec\x07\x54\x28\x09\x82\xd0\x7e\xd6\x37\x4b\x12\x1e\x98\xf1\xfa\x86\xf2\xc7\xb7\xd2\x96\x39\x19\x6a\x72\x2a\x3b\x1b\x8f\xde\x24\xd1\xa6\xde\xc6\xc9\x44\xec\xde\xf0\x80\x6a\x7b\xb4\xdc\x20\x9f\xdf\x68\xca\x82\x34\xb2\xa5\x8e\xae\xcc\x66\x8c\x33\x4b\x52\xcd\xa5\x2d\xd8\xbd\x9e\x95\x4f\x40\x68\x8a\x1b\x98\xda\xbd\xa1\xda\xa5\x48\xa8\x46\xa9\x2f\x24\xc3\x29\x44\x23\x51\x4c\xa1\x0d\xf8\x96\xfa\x59\x6f\x1f\xbb\x43\x55\x1c\xd0\x57\x96\x1d\x37\xf2\x20\x83\x96\xa8\x84\x53\x5c\x29\x2f\x27\x72\xb7\x22\x51\x4a\x51\x5c\xa4\xc6\x66\x43\x06\xd7\x1c\x36\x24\xc1\x10\x09\x1f\x57\x9f\x44\x6d\xec\xcd\xcb\x52\x4e\x91\x20\x97\xa1\xd5\xc6\x28\xa7\x90\x9a\x04\x75\x4a\xa1\x31\xd9\x95\x54\xee\x4a\xf7\x26\xc7\xe7\x49\x3d\x9f\xc9\xd0\x95\xbe\x98\x2a\x62\x35\x67\x3d\xa5\x5e\x20\x46\xe2\xb8\x0e\x82\x32\x9b\x17\x4e\x3d\x11\x12\x61\x16\x51\x30\x42\xfb\x2e\x86\xeb\x5f\xea\xe9\x54\x99\xf8\xe3\xfb\xa1\xbc\xe2\x72\xa6\x8c\x49\x11\xf7\x05\xb3\x1d\xfd\xd7\x6c\xae\x26\x65\xb1\xe7\xa8\x55\x6d\xe5\xde\x65\x66\x3e\x65\xe8\xb3\x78\x40\x58\xde\xd1\x59\xf5\x21\xe5\xd4\x87\xc8\xea\xb5\x35\x6b\x59\xae\x0a\xd5\xd7\xa8\x8b\xd4\x57\x01\x2d\xf9\x3d\x33\x3c\x3d\xfd\x6d\xa6\x1d\x28\xc2\x76\x0c\xfc\x94\xc0\xfb\xa6\x24\xf8\xa2\x32\x65\x7c\x5b\x41\x98\xc6\xbd\xea\x81\xbb\xa9\xcf\xab\xb6\x44\x1a\x28\xa4\x71\xb8\xb8\x59\x8f\xb7\x84\x34\x64\x21\xad\x21\xd0\x0e\x4c\xf3\xa1\xe0\x0a\x50\x26\x0d\x43\x0f\xa5\xab\xca\xa7\x8f\xd4\xfa\x2e\x0f\xf8\x8e\x79\x0f\x91\x4b\x43\x29\x49\x3c\xc7\xa9\xba\x4e\x73\x91\x69\xc4\x38\x15\x82\x9c\x11\xaa\x70\xa8\xe1\x27\xd2\x28\x35\x80\xcf\xac\x5e\x2f\x17\x2f\xf3\xee\x65\x1a\xa5\xa9\x09\xc3\x60\x96\x3f\x94\xaf\xfe\x95\x31\x11\xf3\x94\xd2\x24\xcb\x89\xc4\xb3\x48\x93\x28\xf1\xcd\x98\xb7\x1c\x97\x03\x8d\xa3\x21\x1c\x5e\xa4\x49\xec\x93\x7c\x02\x05\x31\x58\x3a\x1a\x98\x89\xd4\x6c\x3c\xb7\x0d\xfc\xc0\x36\xa7\x68\x15\xa2\xb0\x36\x31\x8a\xf1\xba\x94\x72\x1f\x29\xd7\x2f\x31\x47\x31\x7d\x45\x90\x08\x6d\xc4\xcc\xb3\x42\x40\x8d\x43\x75\x12\x91\x8a\xc4\xa3\xdc\x9c\xd5\x94\xbd\xad\xca\x02\xa7\x98\x72\xd7\x15\x0c\x22\xff\x6b\x91\xe5\xa5\x01\xaf\xed\x20\x33\x8a\x57\xd3\xae\xc2\xc0\x4a\x3f\x50\x7c\xc9\x74\x63\xb8\x52\x87\x46\x65\xaa\x3c\xb3\x54\x1b\x39\x3c\xbf\xfb\x99\x2b\xde\xa3\xfe\xb6\xc7\xb2\x6a\xea\x1b\x6c\xe6\xb4\x98\x44\x8a\x69\x48\xe0\x47\x71\xaa\x8a\x3b\xc4\xbb\x8e\x45\x4c\xa4\x88\xc2\x00\xcd\xe1\x80\x5d\xe5\xb6\x48\x75\xeb\x3f\x1a\xda\x23\x13\x78\x19\xe2\x36\xcf\x7d\x2f\x24\x24\xd2\xc3\xfa\xfb\x57\x4b\x66\x24\xb8\xc7\x64\xea\x3b\x3b\x74\x83\x47\xc8\x14\xad\x32\x59\x17\x8f\xe0\xcc\x33\x46\xa3\x23\xd5\x7b\x5c\x3f\xed\xd7\x4f\xdf\x56\xdb\x5d\xd7\x03\x41\x1b\x90\x89\x53\x76\x9c\x18\x77\xdc\x8f\x91\xfc\x67\x32\x86\x5a\xf7\x17\xbf\x75\xd1\x0c\xee\x27\x31\xe5\x71\xca\x4a\xe1\xa5\x90\xcc\x2f\xf6\x65\x7b\x8e\x20\x30\xea\x3d\xf5\xc8\x09\xe0\x41\x0c\xb4\x69\xdd\x9e\xa0\xf8\x57\x36\x93\xd2\xe7\x81\xd0\x9e\x4b\x5f\xa2\xac\x4e\x59\x73\x8f\x55\x79\x81\xf3\xe0\x61\x1a\x53\x38\x56\x19\x71\xf5\x81\x7a\xfc\x98\xc0\xfe\xf3\xdb\x8c\x64\x4a\x66\x03\xbc\xbe\x66\xa7\xe2\x35\x7b\xac\x47\xb2\xa4\x82\xc7\x3e\x52\xc6\x7a\x91\x1f\xdf\x80\x8a\x19\x06\x49\x7a\xf7\x54\x71\xe8\x91\xcd\x69\x85\x79\x1e\xe1\x78\xcc\x8a\xd7\xed\x94\x16\x48\xf0\x38\x09\x3d\xd9\xe1\xfc\xac\x66\xdd\xb0\x52\xfe\xae\xac\x16\x79\xfe\xf2\x06\xf5\x74\x0d\xe2\x71\x12\xd1\x03\xbf\x97\x0d\x0e\x59\xc6\xe6\x5d\x0b\x1e\x27\x5a\xf9\x1d\xfa\x6e\x7f\x80\x61\x45\x56\xdf\x07\x93\x01\xac\x9b\xa5\xb6\x0e\xcc\xd2\x19\xb0\xd4\x75\xc4\xc4\xb7\xd9\xe7\x9b\xc5\xf6\x82\xa2\x72\xf4\xc6\x12\x5f\x53\x90\xeb\x03\xb3\x97\x0a\x97\xad\x8b\x24\xfb\x90\x13\x4f\x84\xa4\xd1\x4b\x76\x6b\xcf\x6a\x2b\x78\xa2\x25\x01\xfa\xbf\x63\xf6\x82\x95\x09\x06\xba\xb6\x94\x79\x84\xcc\x6f\x9f\x97\xe8\xcb\xdd\xef\x81\x27\xa0\x0b\x03\x19\xbe\xc1\x3e\xa5\xd5\x6f\x7b\x3c\x0d\x4d\x80\xee\xfb\xca\x7e\x43\x47\x15\xec\xda\x35\x4f\xac\xf1\x72\x49\x86\x23\x38\xf7\x7c\x32\xc9\x5d\x42\xfc\x05\x2b\x5d\x56\x53\x65\x67\xc1\xb9\x94\x24\x25\x98\xc9\xd2\x37\x9c\x57\xb6\x01\xc0\x23\x48\x6c\x56\x13\x90\x22\xbb\x56\xd6\xc0\x41\xa6\x91\xc5\xed\x2e\x4f\xd5\x3b\x7e\x2d\xea\x81\x6f\xe1\x5e\xfc\xe8\xa2\xa0\x24\x29\x03\x18\x56\x74\xeb\x1a\x8e\xf7\x4c\x2e\x3c\x13\xae\x79\xcb\x5e\x07\x2c\x6c\x82\x8b\x94\x05\xc3\x92\x3d\xda\xd0\xd5\xf5\x5a\x04\x2e\x78\x4c\x15\xf2\x5b\xc8\xb1\x36\x6b\xfc\xa7\x75\x1a\x5c\x68\x88\x0d\xeb\x78\xff\xd2\xe7\x7b\x4a\x40\x53\xfa\x9f\x15\xd8\x64\xff\x74\xb7\xa8\xa2\x34\x4c\x1c\xea\xd9\x96\xde\x8d\xdf\xba\xe2\x29\xf2\x41\x7d\xe4\x90\x03\x50\x70\xe4\x29\xf9\x89\x4b\x28\xa0\x3a\x7f\x4b\xee\xa0\x6e\x76\xa6\x3a\xa3\xeb\x02\x1d\xd3\x9d\x8d\x70\x6e\xbb\x2a\xd1\xb6\x95\x1b\x71\x44\x4b\x2b\x40\xc2\x87\xcb\x76\x7b\x9d\x50\xe9\x4c\xd6\x16\xcd\x90\x60\xb3\x1f\xc7\x37\x39\xdc\x86\xb9\xf6\x53\xb2\xd3\x8a\xf2\xe3\xe3\xe3\xa3\xff\x55\x42\x3c\x48\x91\xdd\x9c\x32\xa3\xd0\x3c\x5b\xb9\xe0\x0e\x8a\x99\x67\x88\x6e\xdf\xeb\xc3\xbc\x55\xc1\xb5\x4c\x29\x2d\x45\xee\x0d\x56\xad\x43\x3e\xb0\x08\xc1\x83\x80\x92\x76\x3b\xf8\x61\x64\x5d\x0c\xdb\xf8\xdf\x5a\x3f\x81\xf9\x32\x0d\xac\x5d\x92\x39\x06\xe7\xdf\x5c\x63\x92\xf8\x4e\xbf\xb8\x03\x89\x74\x73\x02\x98\x4e\x1c\xc7\xc4\xfa\x70\x04\x97\xc8\x19\x0e\x37\xf0\x83\xd0\x54\x36\x50\xb6\x71\xe3\x04\xd8\x5c\x6b\x68\xc8\x5d\xa5\x63\x6c\x9b\x1f\x59\xe0\x27\x09\xcd\x6e\x3d\xc1\x88\x81\x8f\x46\x77\x0e\x5a\x73\x79\xa4\xee\x20\x20\x8c\x63\x3f\x74\x4b\xc2\xa9\x68\xce\xc6\x11\xba\x5c\x5c\x20\x54\x3e\xa1\x58\xeb\x30\xb0\xeb\xa7\x6d\x88\x52\x4e\x3b\x7c\x51\x36\x78\xd3\x5e\xa3\xb9\xc5\x63\x4e\xd5\xe7\xa3\xe9\x09\xb1\xf2\x93\x5e\x56\x85\x78\xce\xe6\x07\x15\x24\x68\x6a\x21\x6d\x95\x5f\x3e\xb1\x9e\x20\xe5\x2c\xee\x19\x3c\x1f\x5b\xd7\x7a\xa0\xea\xec\x3a\xa9\x84\x52\x4c\x94\x1d\xba\x72\xa1\x14\x05\x3a\xda\xae\x4b\x17\x08\xb8\x9f\x26\x86\xd4\x23\xa7\xea\xf4\xec\x7f\x06\x5f\x84\x55\x93\xe9\x4c\xb6\x4b\xcc\xe8\x43\xf2\x88\x3b\xc6\xb5\x47\xf8\x39\x32\xd2\x00\xc0\x10\xe1\x75\xd4\x1d\xb4\x86\xfd\x76\x01\x2e\x03\x11\xaa\xd4\x7e\x12\xe2\x99\x75\x79\xd8\xed\x49\xd8\x3a\x47\x27\xa8\x36\x7e\x16\x91\x18\xe2\x59\xf3\x52\x96\xa7\xaa\xbe\xe8\x60\xf6\xac\x03\xd6\x75\x36\xdd\x1c\x40\x7a\x81\x21\x10\xa8\xce\x5f\x8b\x87\x52\xfe\x98\xf5\x0a\x41\xb2\x88\x6c\x89\x97\xaf\x37\x0f\xeb\x65\x6b\x9a\x75\x27\xf0\x0d\x42\xbb\x75\xe8\xad\xaf\x74\x57\x9e\xaa\x99\x1c\x32\xc8\x40\x5a\x4d\xef\x5b\x34\x2c\x17\xd3\xab\x70\xb3\x67\xdb\x1c\x68\x01\x07\xbc\x39\xcf\x04\x3b\x40\x05\x21\x09\x02\x9a\xe4\xde\x35\x0a\x8f\xff\xb7\x70\x0b\xa8\x30\x4c\x99\xe3\xf2\xdf\xe0\xeb\x60\x15\xfc\x37\x8b\xff\x73\xed\x68\xab\x20\x67\x92\xbb\xff\x66\x7e\x6a\x43\xf2\x80\x3e\x23\x58\x34\x68\x9d\xe5\x19\x34\xb8\xab\xb0\x5b\x47\x30\x30\x6c\xde\x16\x04\xde\xfd\x1c\xc6\xe4\x54\xfd\x5e\x1e\x32\x39\x42\x22\x81\xf6\x84\x74\x83\xb7\xb5\x31\x5a\x27\x77\x8a\xbd\x14\x5e\x98\x12\x67\x97\x2c\x0b\x09\xcd\x95\x31\x27\x3c\x4c\x7d\x9b\x43\xdc\x83\x52\xe7\x59\x48\x95\xed\xcb\x6c\x35\xc0\x97\x32\x57\x08\x97\x22\xbe\x42\xb0\x54\x81\xe3\x6d\x37\xc4\x31\xff\x28\xb3\xe2\x0a\xf5\x96\x10\x7e\x18\xd0\xc2\xb5\xde\xfd\xb1\x1f\x3e\xa0\xf0\x23\x03\xd8\x33\xaa\xd9\x63\x19\x42\xd7\x45\xaa\x58\x58\xb9\xc2\x45\xa1\xee\xa8\xe7\xec\xb2\xee\x72\xbe\x22\x00\x8f\x0c\xff\x53\xe1\x78\xe9\xa7\x9a\xf2\xdd\xa3\x86\x42\x80\xab\x73\xb4\x84\x17\x8e\x28\xe8\x5b\xd9\xf4\x98\x66\x11\x62\xac\xc3\xc1\xe6\xfc\x1d\x33\xd7\x14\x05\x31\xbd\x0c\x9d\xbd\xbe\x35\x8f\xd9\xcf\x2b\x2f\x21\x8a\x4d\xa8\x34\x2f\x5f\x47\xd2\xc0\xae\x19\x63\x72\x8d\x57\x5f\x9c\x13\x25\x12\xcf\x73\x24\x7d\xdb\x06\x9a\x49\x4c\x59\x24\x60\x68\x97\xff\xf5\x76\x7a\x3b\x8d\x06\x8e\x48\x05\x27\x54\xf0\xff\xb2\xa2\xd9\xdb\x08\xfe\xf8\x72\x3c\x0a\xa9\xb8\xa6\x63\x50\x2d\x3a\xcf\x63\x57\xde\x40\xf1\xa3\x2a\xbb\x64\x88\xe0\x88\xb4\xae\x1b\x3f\x73\x63\x16\xa7\xb2\x3a\xcf\xd4\xbf\x8b\xd6\x02\x20\x6c\xea\x76\xb9\x78\x1c\x46\xae\x05\x04\x86\x72\xd6\x6a\xd0\x34\xe7\xbb\x2c\x6f\xba\x60\xbc\x80\x38\xa6\x6d\xb6\xb4\x99\x22\xf7\x33\xf8\x89\xc1\xc6\xa0\xda\x96\xa7\x4a\xe2\x4d\xd7\xa4\x62\x96\xf6\xb3\x97\xe2\xf4\xae\x4d\x85\x46\x54\x51\xa1\xae\xca\xba\xb1\x1a\x1e\xed\x53\x3a\x55\xc2\xee\xd3\xaa\xc8\xa3\x1b\x7e\xc2\x0f\x72\xbd\x67\xd6\x33\xa1\x84\x21\x05\x7b\xc5\xe6\xe1\x24\x7f\x9c\x09\x28\xb7\x3d\x62\x31\xd9\x02\x05\x7a\x48\x25\x80\x5d\x04\x2e\xcf\x47\x42\x45\x93\x81\xdb\x0d\x44\x54\xbe\xa5\x18\x26\xaa\x15\xc8\xb1\x3c\x62\x91\x15\xaf\x83\xc0\x96\xd0\x7e\x42\x80\x87\xac\xd0\x15\x18\xef\x6d\x72\x9f\x3a\xf1\x08\x49\x44\x0e\xf1\x8c\xee\xa2\x10\x3a\xd5\x81\x7d\x69\x8f\x59\xd1\x23\xfc\x84\x56\xc2\x21\x3b\xbe\xd6\xb3\x51\x4f\xe9\x71\x49\xa9\x23\x27\x5e\xd0\x3e\x40\xfc\x1f\xf7\x0c\xd2\x93\x06\xd1\x66\x01\x15\x23\x12\xc7\xf1\x64\x90\xcc\x0f\xe2\x8e\x0b\xe4\x07\x16\xe3\xcb\x4d\x3b\xc7\x9a\x9c\xf0\x63\x85\x75\x0f\xb7\x92\x2c\x09\xc8\x6c\x02\xa5\x7a\x86\x80\x7a\x3a\xc5\xa5\xcf\x92\x6e\x5b\x86\xba\xb1\x82\xdf\xf3\x57\xf2\x03\xb3\x1e\x8d\xaa\xd2\xb1\xde\x5e\xcf\x8b\xb8\x03\x21\xa0\xcf\xb7\x7d\x2b\x3f\xb0\x1a\xd4\x04\xca\xc0\x03\xf0\x86\x6c\x69\xdf\xb3\xa2\x98\xb3\x87\x5d\x7f\xc6\xd0\xd2\xd3\x51\x71\xc2\xf8\xf3\xc9\xc0\x07\x8a\xb7\x92\xab\xb8\x2b\x89\x71\xeb\xe6\xbc\xfd\x21\xbb\x9d\xf1\x4a\x80\xc3\x1d\x1f\x08\x82\xd8\xda\xd6\x7f\x60\xf1\xa3\x47\xd4\xc8\x00\x7c\x1a\x60\xbf\x63\xfe\x3e\xce\x86\xc9\x10\x0d\xaf\x07\xe9\x84\xdc\x56\xe3\x58\xb1\x8c\x38\x10\xae\xbb\x35\x4c\x58\xf4\x54\xbe\xfb\x1e\x4b\xbb\x46\xe1\x13\xbd\x27\x41\x60\xf6\xfe\xde\xb8\xb9\xfb\x5a\x0e\x8a\xbb\x64\x84\x11\x33\x69\x49\x8a\xe5\xb6\x1f\x29\xe8\xda\xb4\x89\x08\xff\x78\x6d\x46\x57\x8d\xb9\xa1\x44\xb2\x55\xaf\xcb\xe7\xcb\x8d\x4f\xc6\x22\x21\xd7\x82\xe8\x0f\x6f\xb0\xd9\xad\xb6\xbb\xe7\xa7\x87\x3f\x27\x43\x3b\x16\x86\xab\x41\x41\x96\x9f\xdb\x89\xdd\x74\x17\x91\x26\x57\x60\x78\x0d\xb4\x9b\x8c\x32\x49\x62\x13\x04\x71\x51\xc8\x6d\xe7\x89\xc9\x24\x8d\xa8\xa8\x69\xb1\xdc\x8d\x6e\x38\xd1\x8a\x8a\x4b\x9a\x72\x77\xca\x26\xd6\x9b\x4c\x79\xea\xc8\x37\x6f\xfe\xe9\x12\x5d\x32\x15\xa1\xec\x09\x12\x5d\xd8\xfc\x6b\x56\x34\x8f\xd0\xcb\x0f\x8d\x32\xa4\xf6\x48\x1e\x85\xca\xce\x8f\xd5\xeb\xab\x85\x45\x4d\x4a\x79\x26\xa3\x83\x4b\xf3\x16\x5c\xad\xe3\x30\x2f\x2b\x81\x19\x99\x22\x82\x71\x57\x4a\x9e\x8e\xbb\xea\xd4\xb7\x86\x21\x4d\xd2\x1b\xa2\x37\xd9\x5d\x30\x84\x8e\x87\x31\x44\xdc\xeb\x72\xab\x8f\xa8\x1c\x72\x96\xb9\x3b\x01\xe1\xa7\xd0\xa9\x8a\x6c\x50\x62\xf6\x7e\xc1\xf2\x37\x6b\xf5\xcd\x0b\x29\x08\x29\x52\xf0\xbb\x02\xf2\x42\xdd\x66\xef\xc4\xb0\x3e\xf9\x08\x02\x14\x55\xb2\x7c\x7f\x78\xdc\x0d\x98\x6f\x84\x14\x42\x51\x32\xb2\x4b\x9c\x4a\x81\x01\x85\x6d\x73\xa8\x4d\xe1\xe8\x5e\x33\xde\x35\x6a\x24\xab\xce\xe5\x20\xf6\xab\xe6\x6d\x72\x29\xe5\xc5\x3c\xec\x4d\xe0\x65\xd6\x64\x13\x49\x72\x21\x55\x20\x5c\xa2\xd1\x58\x76\xee\xf7\x34\xa1\xb4\xb7\x82\xfa\x4d\x94\x50\xa9\x71\xa0\x5d\x62\xec\xd3\x2a\x42\x69\xf1\xf5\xf2\x99\xd2\x46\xf2\xf9\x88\x45\x3f\xe3\x30\x95\x4a\x0f\x68\x1a\x5b\xb7\xb6\xac\xd6\x53\x1e\x7f\x21\x51\x9b\x34\xdc\xaa\xa1\x05\x2c\xdc\x0e\xe9\x0c\xff\x96\x83\x2d\x35\x8f\x89\xfe\xf2\x15\x9b\xdb\x52\x9e\x88\xf9\x6d\x88\xa6\x51\x5e\x6a\x22\x5b\x13\x29\xfd\xcf\x10\xf4\xe3\x21\xa5\x18\x4b\x79\xe8\xd4\x6d\xb2\x5c\x5d\xe1\x78\x15\x8a\xf9\x8c\x52\x32\x8f\x8f\x4b\x67\x6a\x29\x96\x2a\xb2\x32\xb2\x8e\x98\x6e\xfc\x0e\x94\x1f\x07\x84\xf1\x73\x11\xa6\x97\xf5\xed\xb4\x07\x98\x2f\xbe\xda\x7c\x77\x67\x0d\xd2\x84\xc2\x65\x24\x55\x00\x85\x21\xd0\x76\x6d\x80\x14\x5c\x5f\x2d\x36\x0f\x7f\xee\x6f\xd6\x9b\x5b\xcb\x56\xda\x75\x90\x9a\xca\xf1\xda\xd5\x50\x94\x07\x57\x3e\xaf\xa2\x34\xe4\x81\x15\x14\x7d\x3c\x2f\x8e\xc7\x09\xd5\x8a\x50\x91\x30\x3d\x8e\x70\x7e\x29\xdb\xc5\x1a\x3e\x36\x78\x01\x91\x1f\x7f\x21\x15\x7b\x4c\xe9\x3e\xa1\xee\x52\x6a\x93\x4e\x0c\x89\xa3\x6b\xaf\xb3\x02\x72\x5b\x3e\x5f\x63\x55\xdf\xb5\xb6\xaf\xbb\xc3\xd8\x37\x48\xe5\x3b\x28\x1a\xa8\xcf\x26\x2f\x31\xb0\xe9\x54\x1c\x2a\x02\x2a\xdf\xd4\xd7\x20\xb3\x97\x5f\x2d\x86\xd0\xb3\xf7\x67\x19\x52\x46\x4b\x81\xeb\x25\x93\xd8\xc8\xef\xc1\x45\xc1\xe9\xe4\x81\x13\x11\x8b\xb4\xe7\xb6\x51\xfb\xd6\x8d\x21\x8c\x9d\xbb\xcd\x34\x62\x91\x35\x95\xbe\xae\x8b\x26\x35\x32\x5d\x43\xf0\x7a\xda\xf5\xe4\x9c\x48\x8b\xda\x21\xed\x94\xca\x84\x4a\x81\x51\xbc\xd5\x12\xd9\x13\x8c\x80\xb4\x17\xbb\xf6\x00\x85\x8d\x42\x0e\xe3\xac\x8a\x07\xa6\xaa\xef\xeb\xcb\xea\x8f\xe1\x8b\xe3\x41\x42\xc6\x9b\x89\x00\xd0\xfa\xd5\x7e\xa5\x2f\x30\xc9\x62\x2b\x2e\x0d\xb9\x75\xd5\x7e\x97\x30\x98\xb4\x82\x7d\xff\x46\x85\x65\x34\x0f\x41\xa4\x04\x54\xe9\x59\x21\xee\x9f\x96\x97\xbe\xe2\xe4\x5d\x4a\xcf\x0b\x98\xd3\xaa\xbc\x79\x78\x5e\xfe\xbe\x7b\x74\x67\x94\x09\x8f\x3a\x69\xa2\x9b\xd3\x90\x74\x60\x2c\xc3\x22\x94\xe4\x46\xf7\x74\xe9\xca\x63\x2d\xa1\xfa\xa7\x6b\x8b\x52\x22\xa5\xb5\x85\x92\xa3\x63\x76\x04\xa5\x94\x20\x92\x30\x22\xb7\x79\x3e\x7d\x4e\x3e\x25\x94\x42\x46\x78\x5c\x5b\xee\xf8\xac\x3b\xdb\x5b\x21\x53\xa6\x18\xca\x45\xac\x0c\xc9\xd6\xae\x1c\x15\x3a\xb8\xbf\xa3\xb3\xea\x40\x51\x44\xc5\xd4\xf8\x50\xf9\x42\x26\x87\xca\xad\x42\xe9\x28\x20\x3e\x34\x43\x5b\xbc\xb8\xbd\xdd\xac\xb6\x0e\xcb\x80\x5e\x18\xd1\x03\x1a\xb7\xf1\x16\x0f\x65\xd7\x92\x18\xba\xc4\x57\x39\xca\x9e\xa2\xa7\xe3\xc4\x28\x82\xbf\xfe\x36\x23\xb4\x25\xd0\x67\x08\x4e\xf4\x77\xb7\x7e\x5c\xed\x57\x7f\xbc\x3c\x3c\x6f\x5c\xa8\x07\xfd\x00\xa8\xfe\x65\x83\x90\x3f\x96\x05\x76\x67\xf6\xd3\x88\x0c\xbd\x83\x21\xde\xc7\xa9\xd6\xd4\x65\x38\x01\xc3\x34\x24\x28\x8e\x61\x0d\x83\xbc\x63\xcf\x17\x18\x85\x01\x4d\x6a\x4a\xa4\xf6\x36\xc3\xac\x8d\x8d\x51\xec\x09\xf2\xd3\xa0\x2a\x32\xf8\xba\xbd\xdd\x75\xa7\x91\xe0\x45\x7d\x7d\xe3\x50\x26\xdc\x38\x7e\x30\x17\xdf\x1e\x7f\x7b\x8c\x50\x53\xe0\xfa\x8c\x50\xf9\x44\x0a\x32\xda\x52\x31\x16\x40\x0e\x3a\xa1\xb0\x89\x31\x12\x95\xd3\x1d\x99\x5d\x52\x31\xf1\x7c\x9a\x66\xfb\xf7\xd0\x9d\x24\xf1\x05\x31\x45\x40\x9e\x3f\x6b\x8d\xed\x17\xf9\xe7\xa9\xec\x0a\x4c\x30\x89\x35\xf1\x02\x19\x9d\x2f\x2a\x06\x99\x9c\x33\x31\xda\x9e\x36\x7b\x3f\x7e\x43\x49\xa2\xa3\x78\xf8\xd9\xed\xef\xa9\xa7\x83\x2e\x32\xe9\xa8\xd4\xc6\xe7\x4d\xad\x2c\xba\x19\xde\xdf\xb2\x3a\x6b\x0c\xb9\xe3\x55\x20\xd0\xe7\x3b\x3e\xa6\x7e\x9a\x58\x0f\xef\x1f\x46\x55\x9e\x2c\x0b\xdb\xca\x59\xca\xad\x24\xcc\x87\xd3\x1d\x33\xb8\xe5\xf9\x57\xc9\xfd\x90\x6a\xcd\x9b\x0c\xab\x3d\x71\xcf\x76\xaf\x94\xc7\x86\xc9\x93\x86\xb2\x41\x8a\x0d\x82\x96\xc8\x35\xa7\xd4\xd0\x66\xf5\xf0\xeb\x72\x3c\x14\xdc\x33\x98\x17\x59\x0e\xc8\x65\x05\x0a\xe5\x69\xab\xdc\xe2\xaa\xd5\xca\x01\x97\xdb\xfc\x4d\xcb\xc0\xa7\x55\xf1\x0b\xe4\xf0\xf3\x3c\xa0\x90\x13\x28\x31\x34\xc2\x87\xd8\x50\x96\x94\xb2\x75\x9f\x56\x2c\xa2\x8a\x03\x02\x9e\xee\xb3\x7a\x8e\x6e\x01\x91\xc9\x80\x72\xc0\x0e\xf0\xb9\x5e\x3e\xef\x3f\x9c\xb5\x8a\x28\x3c\xb0\xd6\x9e\xd9\xc7\xa6\xc9\xb8\xf1\xd5\x50\x09\x82\x7a\x2f\x54\x49\xda\x39\x8e\x68\xdb\xc6\x3b\xa2\xf9\x5d\x1a\x35\xa6\xbe\xa1\x39\x57\x37\x24\x9f\xf2\x52\x65\x85\xcc\x8e\x16\x11\x34\xa9\x84\x41\xdd\xde\x96\x35\xa1\x2d\x5b\x48\xcf\x12\x29\xb4\x17\x49\xce\x69\x79\x00\xed\x18\x09\x66\x5f\xb5\xf6\x38\xa7\x69\x51\x1e\xb1\x18\x21\x81\xa7\xfd\xd0\x08\x8a\x1e\xce\x46\xd7\x73\x3c\x81\x34\x93\x49\x98\xb8\x08\xc6\x69\x90\xef\xd5\xbe\x8c\x5c\x3e\x7f\x79\xf7\x3c\xc7\x11\xa1\x7d\x34\x54\x6e\x26\x1e\x51\x97\xc5\x28\xe2\xa6\x03\x96\x12\x37\xad\xb6\x56\x40\x5f\xa0\xe5\x3a\x84\x86\xd0\x6d\x39\xaa\xc6\xd1\x41\x9c\x52\x71\xc3\x4d\xf6\x0e\x83\xc0\x82\x0e\x93\xd0\xcc\xd8\x71\x75\xae\x5b\x87\xff\x06\xb9\xbf\xd0\x91\x17\x44\xaa\x8b\x3a\xfd\x89\x50\xf5\xf0\x0f\x1d\x31\x1d\xf4\x25\x74\x9d\x35\xe8\xc2\xac\x3a\x0a\x62\x16\x0c\xb8\x99\x9e\x2e\xd5\x6c\xfa\x9e\x46\x1a\xcf\xa8\xb9\x4d\x0b\x68\x74\xcc\x34\x0d\xb6\x66\xbf\xcd\xe1\xdd\x2d\x86\x3a\x0e\x64\xec\xb9\x82\xde\x3a\x93\xcb\xd6\x6b\x30\xcc\xce\x58\x05\xde\x2d\x9c\x27\x2e\xb4\x8e\x53\x4e\xbb\xd3\xed\xcb\xf6\x97\x95\xbb\x3a\x56\x82\x0a\x42\xbe\x41\xd1\xd5\x66\x8e\xef\x2b\x89\x0c\x03\xd4\x7b\xd9\xe0\xf6\x74\xc4\xea\x9f\xa7\xb2\x3a\x1d\x66\x08\x06\x74\x12\x25\x54\x70\x7b\x5f\x1e\xb3\x91\x9a\xb1\xd0\x49\xc2\x53\xc3\x37\x21\x4e\xaf\x7b\x07\x2c\xda\xfd\xdc\xbe\xc1\x6f\x97\x94\xb2\x42\x27\x5a\x44\x83\xd4\x48\x27\x78\x3e\xb9\xb9\xd4\x4f\x99\xd7\xf9\xea\x2f\x06\xc4\x3e\x5b\x4b\xaf\xd3\x30\xa1\x7a\x95\xcd\x62\xb7\xda\xdf\x3d\x6f\xf6\xdf\x57\xab\xdf\x1d\xa3\x93\x4e\xe3\x84\x22\x0c\xff\xc2\x03\x14\xdd\xcb\xe7\x7e\x40\x60\x90\xdf\xb3\x3c\xef\x49\x17\x5d\xa3\x8c\x3c\xa7\xc3\xf3\x84\x3f\x9b\x27\x1a\x00\x53\xac\x87\xe6\xda\xa0\xd7\x3f\xa0\x7e\x81\x6c\x12\x2a\xd5\xc0\x18\x67\x3d\x2d\x0d\xda\xf2\x95\x0b\x8e\xce\xf1\x39\x15\x33\x39\x46\xcb\x3a\xbd\xaa\xa4\xef\x91\x11\x02\x72\xb0\x4e\xb9\x1b\x6d\xad\x7c\x7f\x30\x46\xb1\x36\x91\xc6\x45\x87\x8a\x9f\xad\x45\xd5\xa8\x8d\xd0\x98\x89\x2c\x8d\x54\x76\x5d\x2d\xab\x23\xb5\x18\x8e\x02\xed\x83\xb4\xd2\xc9\xc4\x8b\xe3\x6e\x43\x43\x2a\xc2\x01\x60\xe6\xd5\xec\x1b\xed\x8e\xb8\xc5\x66\x8a\x68\x91\x9e\x97\x44\xd0\x49\x8c\xe4\x79\xd9\x3c\x1f\xcd\xec\xee\xda\x53\x4c\x69\x53\xdb\xae\x36\xdf\x56\xb7\x6e\xe3\x5b\x3c\x7d\x71\x3b\x9f\xf4\x98\x9f\x92\x0f\xb0\x70\x14\xb4\xd2\x63\xc2\x07\x9c\x53\x17\xf8\xd4\x03\x9b\x28\x43\x49\xcf\x67\x11\x55\x4e\xdc\xc3\x3b\x45\xcc\xff\x5e\xb1\xbb\xf4\x7c\x9f\x53\x34\xe3\x2d\x7b\x7d\x6b\xd7\x13\xfa\x24\x03\xf1\x63\xe9\x05\xcc\x68\xef\x1b\xdc\xde\xe9\x42\xc6\xd2\x75\x0b\x0c\x33\x28\x55\x91\x35\x98\xff\x36\x69\xe6\x1c\xc2\x8e\xa7\xbe\xab\x90\x95\x5e\xa0\xfd\x10\x5c\x85\xee\xed\x24\xbb\xdb\x36\x77\xda\x3d\x4f\xa7\xc3\x0b\xd4\x75\x56\xbc\x4e\x24\x77\xc7\x57\x8a\x59\x44\xaa\x27\xf8\x0e\xf9\x69\x40\xbc\x3f\xb3\xe0\x48\x2f\x8e\x7d\x48\x7b\x9a\xb0\x01\x2d\x85\xeb\x20\x03\xc2\xdd\xbc\x67\xf8\x71\x5f\x9e\x6a\xbc\xc3\xee\xcd\xc4\x5a\x11\xbe\x61\xf1\x6d\xfd\xb4\xec\xd8\x05\xa5\x97\x68\x20\x9b\xcf\x0a\xda\xbb\x9f\xd3\x24\x21\x00\xde\x90\x3f\xb9\x6b\x12\x7d\x38\x96\x51\x29\x5d\xd7\x24\x74\x9a\x0e\x19\xf2\xbb\x06\x94\x54\xa8\x93\x1d\x5a\x67\x7e\x67\xcb\xd5\xb6\x99\x42\x2a\x30\xfd\x15\x75\x8b\x3d\x0b\xe7\x2c\x30\xfc\x88\x4b\xdf\x33\xf5\xdd\x20\x29\x91\x64\x3b\x40\x24\xc9\xfb\x34\x38\x89\xc5\x69\x50\xcc\x35\x9e\x20\x90\x00\xed\x28\xed\xdd\x77\xb3\x02\x94\xcf\x79\xbf\x22\xce\x70\xf2\x4a\x4f\xa4\xa6\x94\xc9\xd6\x83\x4e\x78\x5d\xa5\x27\x10\x22\x49\x61\xee\x02\x72\x53\x2c\xdc\xaf\xe5\xd2\x93\x2c\x20\x88\xcd\x7f\x4f\x58\x9d\xfd\xbd\x76\x52\xd6\xd2\x93\x0a\x09\xdb\xf5\xaf\xf5\xcd\xaf\xb6\x1e\xe9\x61\x64\xd0\x81\x1d\x0f\xd4\x97\x0a\x8e\x24\x81\x37\x67\xb6\x48\x0f\x63\x45\xe1\x3c\x83\x3d\xee\x85\xcb\x47\x85\xbd\xd2\x43\xed\x0b\xc3\x84\xdc\x5a\x51\x43\x54\xac\x64\x5e\x90\x06\x6e\x2f\x53\xf7\x50\xb5\x36\xf7\xf8\xdd\x30\xe6\x47\xc4\x13\xa6\x4f\xe3\x8a\x46\xc9\x18\x37\x02\x11\x15\x18\xd6\x3c\x77\x52\xa6\x90\x58\x02\x8f\x70\x9e\x9e\x4b\x07\x04\xb5\x3b\xb8\xdd\xcb\xca\x59\x8e\x9e\x8b\x05\x2c\xa6\x7c\xf9\xe6\xf6\x6e\xf8\x9a\x59\xe8\xa5\x5e\xe7\xd2\xf7\xc9\x72\xc9\x22\xc1\x63\x03\x9a\x86\xac\x58\x34\x0d\xf4\x3e\xd0\xf8\x95\xb1\x48\xc7\x94\xca\x39\x60\xde\x7c\x36\x85\x59\x1c\xa7\x81\xc9\x57\x3e\x8c\xee\x21\x4e\x53\x9d\x10\xfd\x41\x53\x75\x5b\xfa\xec\x68\x64\x89\xf2\x28\xb4\xac\x0c\xc7\x04\x75\x1d\x93\x64\xb4\x7d\x42\xdf\x91\x84\xe5\xc7\x37\x98\xbc\x89\x34\x30\xe0\x2f\x33\xc1\x6c\x85\x7b\x57\xd9\xde\xbf\xb8\x7f\xff\xe7\xff\xc6\x09\x2e\xc9\x52\x64\x94\xca\xb5\x41\x8b\x75\xb1\x3d\xa2\xcc\xb4\xc1\xa8\xcb\x37\x9c\x5c\x89\xfb\x91\x51\x0c\x6a\x5a\x07\x72\x7e\xe1\x1f\x0e\x56\xc6\x7d\x4d\xa6\xcd\xe6\x66\x39\x7a\x41\x3c\x52\x34\xdd\x08\xe3\x6b\xc7\x64\x57\x97\xe0\xfa\xc4\x90\x84\xfd\x42\x5d\x61\x7d\x59\x75\x2b\x19\xd7\xa9\x87\x0e\xda\x35\x2d\x71\xb6\x7d\x20\x15\xe4\xe3\x37\xe5\xf6\xa5\x2c\x27\x2b\x3e\x03\x6e\x90\x9d\x05\x76\x5a\xa0\x43\xce\x09\xdb\x4b\x04\x81\xf2\x1d\x28\xf7\x00\x54\x74\x38\x03\x3a\x90\x4c\xa0\x91\xef\x31\x2b\xc9\xd6\xd0\xfd\x5e\xf9\xf8\xd2\xe3\xf4\x88\x79\xd6\x90\x0a\xe3\xfa\x76\xf5\x33\x9b\x32\x23\x4a\x26\x03\x49\x95\xaf\x23\xf9\xd4\xf5\xed\x68\x03\x62\x92\x27\x04\x76\x31\xd5\x50\x34\xd9\x87\xa3\x5f\x02\x23\x9c\xa8\x4b\x2a\x50\x86\x75\xe5\x04\x18\x24\x93\x2a\x25\x38\x34\x16\xea\xe5\xbd\x19\x1e\xa9\x42\xa0\xc1\xfc\x50\x9a\xfd\x6c\x41\xe2\x9f\x57\xd0\x8e\x92\x29\x11\x05\x8e\xee\x6e\xbd\x47\x95\x35\x7b\x3f\x75\xe7\xc2\xc0\x58\xeb\xf5\x49\x1c\xb2\x6e\x17\x1b\xd8\x60\x17\x81\x96\xe1\x37\xc0\x40\x9b\xa5\xac\xc2\xf7\xac\x3c\xd5\xdb\xa6\xdf\x66\x18\x46\x8c\xaa\x10\x2c\xd1\xd4\xae\xdc\x36\x16\x08\xcd\xe2\x11\xfb\x54\x3a\x08\xbf\x4a\xa6\xe3\x84\xec\x91\x7e\x47\x35\xa3\x70\xa1\x1b\xac\x6e\x11\xd4\x43\x47\xf5\x27\x99\x06\x15\x59\xb3\x73\xdb\x61\x0a\x16\x93\xd1\xa6\x31\x14\x9d\x8a\xcf\xe0\xc9\x4c\xb3\xef\x85\xca\x29\x5d\xdc\x75\xbf\x25\x01\xb9\x96\x0f\x78\x28\x8b\x2d\xe6\xfa\xb6\x2a\x8f\xbe\x6b\x65\xe0\x53\x61\x79\x81\x3f\x9b\x76\x71\x7e\xcc\x8a\x9b\xbe\xfe\x42\xfa\x0c\x93\xc8\x26\xd7\x1e\x1e\xbe\x99\x57\xce\x47\x83\xc3\x0f\x12\x43\x07\x5f\x63\xf5\x6e\xab\x40\xea\x6e\xda\xb9\xf3\x04\x52\x87\x96\xd6\x72\x09\x95\xfa\x23\x9b\xf7\x84\xa5\x1f\x79\x8a\xc6\x4a\x5e\xbe\x7e\x2d\xec\x60\x18\x2d\xfa\x7e\x14\x49\x6e\x98\x42\x7e\xfa\x51\x7c\xed\x34\x32\x96\x43\x82\xde\xd6\x54\x1e\x66\x76\xa4\x1f\x83\x81\x89\x1e\xdf\x8f\x8f\xf0\x73\x5d\x48\x2c\xda\x7d\x69\x79\x1a\xf4\x90\x14\xa2\x21\xde\x92\x15\x54\xf9\x99\xa2\x0e\x1d\xfa\x46\xfa\x31\x86\x3e\xba\xba\x21\x62\x64\xbb\x87\xfa\xed\xae\xa4\x59\x44\x85\x79\x73\x66\xbc\xf4\x13\x4f\x87\x66\xd2\xc9\x1c\x61\x8a\x42\x93\x7e\x12\x24\xca\xa8\x88\xc8\x8a\x84\x72\xe8\xce\x67\xaa\xdf\x5c\xff\x38\x49\x9c\xb2\xd9\x06\x86\xf1\x41\xe9\xa7\xe8\x93\x3b\xf3\x52\x95\xfd\xa3\xf1\x50\x47\xbd\x18\x04\x9d\xbd\x3b\x80\x63\x94\xf6\x0c\x8d\x8f\xe7\xd5\x58\x24\xbe\xcb\x62\x3a\xa4\xd9\xe5\xed\x40\x98\xa2\x01\xc7\x43\x9e\x35\x67\x5a\x3e\xdd\xd9\x41\x04\x84\xfb\xdc\x2e\x9e\xba\x9f\x14\x47\x43\xe6\x47\x62\xe9\xa7\x0b\x95\x53\xe9\x0b\x16\x3a\x84\xc7\xb2\xac\x9b\xd3\x61\x1e\x29\x21\x7d\x11\x20\xf1\x53\xef\x88\xd5\xa3\xea\x93\x14\xd2\x17\xa1\x48\x23\x47\xff\x78\xc0\xeb\xba\xeb\xd2\x17\x71\x4c\x5a\x27\xdb\xdb\x8d\xef\x7f\x66\x31\xf9\x42\x06\x44\x82\x9e\x59\x70\x7c\xbf\x1d\x5e\x38\xe3\xd2\x97\x11\x28\x35\x2a\xad\x9b\x8d\xfd\xce\x67\x8a\xa5\x2f\x53\x46\xc9\x55\xa7\x32\x6d\x11\xb5\xc3\x10\xbb\xf4\xa5\x30\xa2\x3d\x35\x36\xb7\xad\x63\xff\xdb\xe0\xfa\x2a\x61\xb4\x7a\xa8\x52\x52\x51\x8a\x3b\x06\x43\x31\x62\xb0\x58\x74\xe3\x04\xa5\x17\x19\xcb\xcd\x71\x53\x94\xa7\x42\xdd\x11\x2b\x41\x07\xe6\x95\x3e\x2a\xc9\xac\x11\xe1\x40\xe4\xd6\x42\x98\x8f\x1a\x4a\x5f\xc7\x86\x1e\x9a\x50\x0a\xed\x8e\x60\xa8\x83\xd6\x85\x8b\x6d\xca\x80\x05\x1e\x47\xa7\x0d\x61\x02\xe8\x96\x6e\xa5\x6a\x17\xe7\xd3\x38\x9a\x20\x03\x16\x2b\x8a\x0c\xdc\xee\x9e\x2f\x83\x26\x32\x60\x5c\x51\x08\xfb\x26\x53\xd7\xcc\xa6\x59\x10\x8d\x0c\xfc\x28\x51\xbd\x6c\x16\xe5\xc4\x73\xa8\xaf\xd8\x6d\x81\x1f\x07\xb4\x6a\xec\xb3\x7a\xbd\x7c\x76\x0f\x13\x78\x21\xd5\x8d\x1d\xb2\xa2\x79\xec\x86\x7e\x10\x04\x11\x79\x49\xa3\x18\x73\x6f\x4b\xfd\xdf\xc5\x2f\x6e\x88\x06\xa1\x07\x86\xf3\xaf\x7c\xc7\xaa\x70\xc5\x32\x32\x08\x23\x53\x00\xbb\xc1\x02\xb6\xdd\x8f\x71\xe8\x0a\x56\xd7\x7d\x79\xcd\xfc\xd3\x86\x9c\x93\x27\xb2\x6f\x37\xa2\x1f\x59\x9e\x5f\x3c\xe8\xfc\xac\x0f\x42\x9d\x42\x34\x8a\x45\x63\xbd\x2b\x7b\x75\xfd\xa1\x22\x40\xf7\x18\x71\xa2\xc9\x70\xbe\x5d\xac\xfe\x98\xfb\x6a\x31\x28\x92\xe9\xca\x66\xa9\xe3\xaf\xb9\x77\xe3\x73\x24\xd6\x2b\x27\xd9\x41\x42\xf0\xcc\x1b\xde\xb3\x66\x66\x90\xc4\x88\xb6\xec\xf3\xe5\xbd\x19\x4b\x8d\xd8\x2e\x69\x62\x28\x3c\x5e\xb1\xd9\x43\x9e\xef\x8f\xc6\xc5\xdb\x67\x3d\x33\xe4\xf4\x08\xee\x09\x0b\x7b\xdd\xbd\xf5\x98\xcb\x89\x40\xf5\x68\xfa\x07\x3c\xf5\x28\xd7\xf0\x84\x3f\x1b\x93\x80\xbc\x87\xfc\xbd\x9f\x85\x01\xf0\x98\xf2\xc2\x8f\xbb\xaf\xdf\x98\xfb\x51\x04\x82\x78\x1e\xbf\x16\xd9\x5b\x59\x0d\x54\x52\x66\x56\xb3\x40\x24\x82\xc7\x66\x94\x3a\x5f\xda\x84\xbf\xdd\xd9\x64\x18\x79\xb6\x02\xc7\x88\xc8\xbe\x40\xb7\xd3\x04\x92\xfb\x2e\x92\x9c\xd5\x6f\x84\xc5\x81\x63\xd7\x88\x42\x83\xfb\x90\xbb\x72\x7e\x63\x0c\x54\xc4\xa2\x21\x5b\x1b\x2d\x47\x3d\xd4\x50\x06\x4a\xe8\x30\xe8\x91\x40\xc4\x64\xda\xb5\x69\xa0\x9b\xdb\x3e\x94\xd0\xc9\xeb\xc9\x00\x7d\xe5\xab\x01\x44\x96\xf0\xff\xa6\x86\xba\xeb\x12\xc8\x28\x75\x8a\x36\x06\x97\x8b\xd5\x43\x56\x77\xa7\xc6\xd0\x23\x8c\xd1\x97\x8a\x88\x58\xba\x4d\x25\xc0\x28\xa6\xc8\x0d\x64\x95\x55\xa5\x26\xe9\xef\xcb\xb4\xa3\xed\xaf\x3d\xc3\x31\x5b\xe0\x07\x65\x14\x46\xc0\x91\x09\x1d\xdd\xf4\x48\x09\xb2\x8f\xd2\xd8\xb4\xc3\xe8\xf3\x69\xa6\xc9\x96\xb7\x69\xf8\xe1\xbe\x10\xe8\x38\x14\xda\x22\xdf\xdf\x27\x93\x4c\xc7\x40\x72\x09\x36\xf8\x30\x34\x7d\x43\xcf\x47\x95\xf6\x71\xcd\x47\xa3\x17\x34\x1e\xce\xa1\x1f\xfa\xae\x72\xa0\x9b\xef\xe3\x35\x7a\xb0\x0d\x86\x81\x1f\x3b\xe8\xe1\x23\xfc\x55\x56\x8f\x59\x51\x56\x2f\x14\x97\x1c\x8d\xf8\x30\xf0\x4d\xcd\x9a\x84\x5c\xfe\x03\x14\x5a\xb8\xd5\x15\xd3\x31\x0c\x7c\xa3\x2f\xf2\x46\x1c\xd7\xed\x4b\x1a\xc0\x4b\x5c\x9f\x00\x95\x81\x18\x48\xcc\x8e\xcd\xd7\xfa\xd2\xd7\x98\x9e\x35\x01\x48\x9c\x22\x42\xd1\xbe\xd8\xb5\x31\x91\x27\xab\x40\x18\x0a\x08\xdd\x63\x9d\x0d\xa6\xb2\x77\x93\xc7\x77\x11\x05\x06\x91\x2a\x2d\x71\xd7\x5e\x0e\x2c\xd3\x30\x0a\x23\xb2\x3e\xf6\x1a\x07\xcf\x3a\x7e\x35\x11\xa6\x14\x12\xac\xca\xf2\x50\xf7\x51\xe3\xb1\xbf\xec\x56\xd9\x30\x0e\x19\xa5\x0f\x6f\xfe\x31\x72\x95\xc3\x58\x4b\x6e\x04\x38\x69\xe8\xb6\xaf\xac\x0f\xeb\x8f\x2f\x98\xc6\x40\x4b\x83\xe5\xe1\x75\x04\x48\xf3\x5f\x22\x8d\x25\xc1\x06\x96\x4f\x9b\xd1\xf5\x52\x40\x83\x47\x31\x7c\x79\x6a\x9b\x97\xd3\xaa\xe0\xcb\x9a\x06\x77\xac\x8c\x85\x1a\x58\xf4\x8f\x26\xd3\x9f\x61\xb5\x68\x26\x5f\x22\xc5\x88\x82\x8c\x66\x1e\x7c\xc3\x42\x5d\xdb\xed\x42\x9e\x78\x83\x52\xe5\x45\xf1\x6a\x83\xb6\xa9\x6b\x97\x1e\x81\xe8\x1f\xd7\x4f\xfb\xe5\xf3\xd3\x6e\xb3\xbe\xf9\xba\x5b\x3f\x3f\xed\x17\x8f\xcf\x5f\x9f\x76\xbf\x75\xdd\x02\x2a\xc3\xab\xe1\x7c\x9f\xb9\x1f\x21\x08\x08\x15\x43\xf2\x93\x17\xa8\x25\x19\x42\xc4\xa2\xbe\xba\x8b\x84\x65\x66\x32\xa8\x32\x84\xd4\x94\x53\x6f\x77\x8b\x2f\xab\x7d\xb0\xbf\x5b\x3f\xad\xb7\xf7\xdd\x55\x78\x4a\xd0\xa2\x5e\xeb\xa8\x0b\xf1\x8c\xbf\x20\x28\xa0\x4a\x3d\x09\x95\xaa\xf7\xaf\x65\xae\xa6\xd7\x41\x66\x59\xe0\x0b\x89\xf9\x54\xcd\x66\xfc\xde\x84\x06\xba\xa7\x1c\x75\xc3\x82\xc9\x89\x64\xe8\xa7\x91\x43\x64\xd6\xd3\x59\xad\x62\xc3\xac\x4f\x1e\xd5\x4d\x56\xa9\xba\x07\x20\x8d\xcf\xa3\x14\x53\x5d\x24\xa7\x07\x7f\xdb\x56\x94\x60\x92\x17\x66\x65\xb2\x79\xc6\xb9\xb4\xb1\x0c\x75\x1c\xb9\xc1\x43\xc1\x89\x11\x86\x42\x86\x3a\x35\x1a\xb8\x15\x12\xf1\xe0\xb8\xd6\x79\x6a\x87\x47\x9e\x60\xe4\x39\xde\xec\xee\x09\xe7\x6c\xcf\x12\x31\x8f\x45\x26\xd1\xfa\xd7\xa9\x6e\x76\x13\xf0\x93\x8c\x18\x4b\x98\x1a\x80\xcb\x49\x84\x70\x9a\xef\x76\x7d\x63\x9f\x2a\xff\x4c\x05\xca\xfd\x59\x54\x99\xb2\x45\x60\xd6\x8d\x1d\x9f\xdb\x0f\x19\x6d\xaf\x0f\xcf\x0f\xb1\xbb\x1f\x3f\x8a\x28\x25\x05\x55\x05\xe7\xad\xcd\x0f\xb2\x6e\x46\x45\x7e\x92\x7a\x46\xe3\xcb\xd4\x95\x9d\x6f\x6d\xb1\xf7\x78\xb5\x8a\x7c\x21\x0c\xa0\xfd\xa4\xb2\x76\xb5\xa2\x8d\x71\x7c\xf9\x30\xf1\x28\x93\xd7\x8e\x2a\x2c\xcc\xe2\x37\x50\x1b\x95\x51\xc8\x95\xb2\x85\x0a\xcb\xd5\x2e\xbe\x21\xbe\xf8\xc9\x75\x42\x69\xc8\xd0\x5f\x0c\x6b\xca\x26\x23\x0c\xa1\x6d\x8c\x02\x03\x5a\xa9\xb3\xe2\x35\x37\x5a\xe2\x4e\x9a\xf1\x8a\xf5\x3e\xdd\x7b\xa3\x28\xe6\x84\x22\xfe\xd9\x9d\x33\xe5\x04\xb5\xbb\xc5\x76\xfa\xd7\xd8\xc7\x69\x66\xca\x0c\x64\x14\xf1\x24\xb2\x3b\x01\x65\x41\x56\xea\x75\xc8\x42\x2a\xa3\x48\x71\x3f\x1a\x97\x0a\x8f\xb0\x79\x7d\x37\x18\x0c\xdc\x6d\x03\x3f\x7a\x2b\x2e\x8a\x74\x4a\xd5\x23\xcb\xdd\xd7\x31\xe0\x4a\x46\xb1\x27\x89\xea\xe3\xeb\xf6\x76\x72\x6b\xa9\x67\xaa\x74\x1a\x84\xc3\x43\x29\x7f\x38\x6f\x6a\x8b\x2e\x11\x10\xa5\x61\x4a\xd0\xe6\xed\x97\xdd\xe3\x14\xa2\x23\xa3\x54\x18\xbe\xb4\x55\xf3\xf6\x70\x8d\xeb\xed\xff\x26\x87\x58\x41\xd0\x7f\x91\x37\x94\xc9\x2f\x5d\x51\xaf\x8c\xb8\x30\x7e\xcd\x7b\x86\x1f\x44\xd1\xf0\x3b\x54\x07\xb8\x39\x6f\xcf\x07\x51\x8e\x68\x6d\x65\xc4\x65\x44\x16\xea\x12\xea\xb7\x5d\xd5\x05\xb3\x22\x88\x02\x62\x41\xa1\xea\xd1\x9b\xd3\x79\xf0\x8e\x80\x27\xae\x98\xd7\xb1\x0f\x3f\xc1\x74\x7d\x8d\xa4\x2f\x5d\xb6\x92\x2a\xf8\xa8\xcb\x20\xe6\x17\x49\x8c\x08\x90\x5a\x1e\x07\x0f\x3b\xe5\x1e\x1f\x9f\x53\x71\xc6\x95\x5b\x92\xea\xd3\x31\xef\x2c\xac\x08\x03\xcd\x4c\x28\xad\x6e\x50\x51\x3d\xc2\x23\x14\xe7\x5d\xb9\x2d\xaf\x85\x2b\x22\x14\x82\x6a\xa5\x4e\x35\x56\x77\x65\x25\x89\x7a\x6d\x65\x61\x22\x57\x69\xd2\xaf\x9c\x4b\x71\x82\xb7\x6e\x56\x37\xee\x96\x34\x37\xaa\xca\xd0\x65\x66\xee\x70\x3a\x1a\xb5\x0a\x99\xe5\x74\x7f\x1e\x31\x52\x5c\xfb\x7b\xe5\x05\x4d\xee\x46\xab\x50\xf8\xd6\xe1\x6d\x46\xa3\x69\xd4\x2f\xf6\x7c\x9f\xd2\x1c\x2e\x76\x6c\x33\x5f\x73\x35\xa0\x32\x66\x7e\x44\xe0\xad\xef\x50\x35\xf8\x3a\x34\x2d\x62\xdf\x0b\x79\x38\xc6\x41\xba\x65\x7c\xac\xef\xe9\xfa\x0b\x13\xfe\x3b\x64\x94\xab\x1a\x19\xcb\xb1\x2f\xb4\x10\xc4\xa7\x62\x81\x04\x7d\x51\xbf\x8c\x83\xd8\xa3\x80\x1a\xa8\xf2\xd8\x2c\x7e\x66\x97\x14\x52\xf3\x7e\x68\x1c\x5a\x44\x58\xeb\x26\x22\x05\xd5\x46\x76\x5f\x1c\x82\x51\x64\x3e\x56\x99\xc4\x3d\xfe\x3c\x96\x05\x8e\x5a\xb5\x65\x9c\x30\x19\x82\x4b\x8b\x22\x8e\x12\x83\x5b\x12\xa3\x42\x39\x19\x47\xa9\x4f\x9c\x4e\xbf\xf6\xe9\x2f\x70\x92\x32\x8e\xd0\xa7\x64\x98\x93\xb6\x26\x60\x18\x91\xa2\xbb\xd3\xc7\x3e\x27\xa7\x6c\x9f\x8f\x28\xcf\xe6\x47\x46\x1c\x83\xd2\x63\x3a\x00\x0a\x2a\x5d\x30\x2e\xc9\x38\x65\x3c\xec\x2a\x01\x4e\x55\x8d\x6b\xf5\xac\xb7\xcd\x49\x4d\x71\xf0\x32\x4e\x81\x91\x83\x66\x59\xec\x28\xa2\xdb\x67\x20\xe2\x54\x18\x85\xe1\xac\x26\x45\x9a\x0c\x8a\xe9\xf1\x9a\x5b\xe3\xa8\xb5\x7d\x1c\x06\xb2\xa3\x8d\x9a\x1f\xbb\x3c\x60\xcc\x09\x3f\x95\xcd\x15\x29\x21\x19\xf3\xd0\x73\xa5\x53\x8f\xb8\x2b\x17\x79\x6e\xe2\x8f\xae\x59\xb0\xb4\x03\x4c\x39\xda\x52\xdb\x06\x01\x23\x34\xbe\x05\x54\x4c\x36\x84\x18\x22\x41\xb1\xfd\x45\x85\x3f\xb3\x01\x00\xe8\x2a\xd4\x21\x86\xd8\xe8\xa7\x75\xb5\xda\xc3\xf2\x53\xdb\x47\x30\x13\xa2\x25\x0c\x05\x55\x71\xb8\xeb\x09\xad\x28\x12\xd6\x2e\x98\xbb\x37\xdc\x80\x10\x59\x73\x5f\x76\xbb\x74\x2c\x85\x26\x87\x22\x07\x72\x11\x9e\xbb\x88\x73\x2c\x55\x12\x74\xfe\xff\xf2\x57\xe8\x69\x19\x2b\x86\x5a\xf4\x4a\x27\x2b\x90\x6f\xa3\x14\x5e\xac\x94\xf4\x54\x0f\x47\xba\x90\x17\x76\xdd\x30\x72\x05\xc6\xbb\x92\x1c\x87\x9e\x74\x4f\xc6\x4a\x07\x91\x89\x88\xde\x94\x85\x32\x6c\x48\x13\xe4\xf0\x64\x12\xa3\x6f\x82\xd5\xf5\x49\xd4\x24\x9e\xbd\x2b\x29\xef\x67\x9b\xb5\xe4\xb4\xec\x59\x9e\x58\x62\x7d\x30\xcb\xea\xb5\x35\x62\x18\x27\xbe\xb6\xd6\xba\x93\x63\xec\xb2\x96\x1d\x96\x78\xc0\x71\x6b\x7a\x25\x9e\xc7\xc8\x74\x6c\x9d\xf0\x2f\x79\x29\x20\x5f\xb4\x86\x5b\x57\xdf\x72\x09\x13\x93\x89\xc7\x02\xe9\x28\x95\xa6\x0f\x3e\x08\x47\x4e\x96\x86\xc4\xd3\x5e\x34\x22\xeb\xdf\x90\x6c\xd4\x90\x70\xb6\xbf\x2f\x16\x33\x32\x23\x55\xf6\x5e\xeb\xb2\x82\x6e\x79\x4a\x58\xe2\x19\x0c\x7b\x99\x97\xa7\x6a\x7d\x3b\xd8\xfd\x46\x09\xb5\x84\x89\x90\xe4\x82\x6e\x76\xcb\x41\xf6\xab\x76\xa9\x38\xdb\xcb\x17\x06\x56\xbc\xa8\x9a\x5d\x79\xfa\x6b\xac\x84\x2b\x13\x5f\x23\xd9\x26\xfb\x23\x9c\x6f\x32\xb5\xb8\xbe\x37\x26\x41\x8c\x5e\xd8\x15\x24\xdc\x95\x15\x11\x3e\x59\x4c\xdb\xc4\xff\x4f\x02\x08\xb8\xdf\xf1\xde\x12\x3d\x91\x6d\x09\xbd\x24\xb0\x8a\x63\x2f\x99\x6c\x4e\xd5\xc8\x51\xef\x75\xac\xc6\x7f\xe6\x42\x82\xee\x84\x91\x4f\xd6\x5a\x6b\x5e\xbd\x60\x93\xb5\x77\x6f\x98\x40\x5b\x13\x76\x8a\xd7\x1d\xdf\x66\x28\x90\xb0\xf9\x04\xaf\xdf\x3d\xef\x1f\x17\xbf\xb7\x7f\x1f\x17\xbb\xe7\x95\x5b\x58\x92\x88\xc5\x84\x41\x2c\x4e\x87\x97\x76\xe1\xed\x7e\x0f\x05\x65\x34\x6f\x4e\x67\x07\xfd\x9a\x2e\xf6\xc3\xb5\xc7\x1d\xc5\x43\x06\x63\x1e\x6c\x57\xc3\x37\x7a\xac\x38\x60\xf1\x90\x20\xef\xa5\x74\xcb\x47\x12\x07\x9a\x82\x9f\xf5\x5b\x4f\xb6\xf0\x58\xbf\x6e\xb1\x98\x96\x12\xcb\x24\x81\xb8\xa7\xc1\xa6\x62\xd5\x3e\x65\x97\x24\x22\x0c\x2d\xd4\xec\x01\xd5\xeb\xb5\x79\x9e\x70\x2f\x20\xb7\xfa\x00\x3f\xed\xbd\x2e\xdf\x7a\x4c\x4f\xc2\x53\x49\x0c\x0d\xdb\xe5\xf2\x13\x04\x46\xc2\x41\x3b\xca\xbf\xca\x30\x5a\x8f\x3f\x06\xc7\xc0\x05\x97\x97\xd5\x59\x55\x16\x6b\x38\x79\x20\x90\x09\x15\xd7\x42\x25\x32\x43\x18\xb0\xfa\xd9\x54\xd0\x4b\x3f\xc9\x44\x44\x31\x99\x33\xad\x51\xb0\xa7\xa8\xe9\x7e\x02\xe4\x95\x89\x40\x2d\xac\xc2\xd3\x0f\x2c\x1e\xe0\x8c\x55\x4d\x98\x80\xc9\x4d\x49\x88\xa9\xe4\x75\x51\x55\x16\xb4\xb0\xae\xef\xaa\xf2\x7f\x58\x8c\x65\x4e\xbb\xee\xca\xd4\xfc\x99\xf2\xea\xc7\xee\x7a\x2a\x95\x94\x8a\xda\xbb\xc0\xc4\xbc\x73\x9e\x28\x8c\xc8\xa6\x46\x95\x4d\xb8\x98\x86\x4b\x14\x06\x26\x64\x4e\xeb\xbd\x22\xcc\xed\x5d\x55\x1e\xbe\x63\x36\xb9\x1f\x94\x10\x63\x47\xa8\x5e\x0f\x3d\xb4\x04\x75\x40\x86\xd0\xfd\xd7\x9b\xdd\x68\x51\xd0\x5e\x42\x07\x59\x16\xda\xf3\x66\x20\xf6\x51\x5f\xb0\xeb\xc8\x44\xfb\x09\x41\x1e\x96\xcf\x0e\xd7\x98\x7a\x5e\x28\x22\x93\x66\x30\x87\xed\xaf\x4c\x44\xf3\x6c\xa9\x3b\x4c\xc5\xb4\x23\xb7\x73\x79\xdf\xee\x9b\xfb\xca\xe8\xa5\xcc\x8e\xa8\x94\xb1\x90\x42\x79\x7b\x5d\x56\x1f\x50\xa9\xeb\x6c\x36\x32\x65\x81\x41\x01\x92\x2e\x14\x1c\x2e\x39\xfc\x65\xea\x7b\x9c\x86\xd6\x01\x8a\x13\xe4\xce\x01\x36\x54\x7f\xdd\x02\x9d\xfa\x01\x50\x89\x8b\x41\x01\x4d\xc0\x34\xa9\x2f\x38\x11\xf4\x7c\xb8\xd0\xef\x86\x82\xf3\x93\x8a\x77\x99\x06\x3e\x6a\x83\x0c\xae\x9b\xb2\xc2\x61\x7c\x20\x0d\xe2\x84\xb6\xfb\xfb\xc5\x83\x23\xd3\x95\x69\x90\x18\x31\x51\x95\xbd\x2f\x4f\xcd\x60\x9b\x4d\x43\x1e\x4b\xe9\x12\xef\xcd\xa9\x2a\x6e\xce\x2f\xd0\xa3\xf2\xa6\xae\x7f\x1a\x25\xc2\xa9\xca\x3c\x94\xef\xf8\xe0\xe4\x54\x5d\x82\x39\x8d\x04\xa3\x9d\x65\x8b\x1d\x33\xd4\x48\xf2\xe4\x57\xbb\xf7\xe4\x72\x1a\xc9\xe2\x3b\x40\x23\xdf\x8c\xf6\xf4\x5c\x5a\x3b\x8d\x99\x22\x54\xc4\x02\x7b\xbf\x37\x4d\x82\x88\xb4\x79\x6e\x16\x4f\xcb\xe7\xcd\x7e\xf9\xfc\xf4\x6d\xb5\xd9\xad\x36\xfb\xaf\x2f\x5f\x36\x8b\xdb\xd5\xa6\xeb\x18\x59\x4a\xb7\xa9\x0a\xfa\xe4\x6e\x38\x78\x14\x70\xeb\x65\xae\x2f\x28\x5a\x65\xca\x45\x42\xe4\x24\x96\x98\x98\xd0\x27\xee\x42\x1c\x35\xd5\xbf\xbd\x41\xbd\x2a\xca\xd3\xeb\xdb\x85\xb1\x35\x1f\x3b\x6f\x0f\x24\xa0\xfa\xcb\x1f\x8f\xcb\x39\xca\xec\x4b\x03\x35\x85\x98\x39\x15\x66\x57\x80\x53\xaf\x76\xf7\x93\xbb\x05\x19\xeb\xa1\x72\xf7\xa2\x38\x4f\x72\x7a\xf3\x37\x24\x7c\x4e\x40\xe3\xb7\x52\xe5\xbb\x2c\xcf\x87\x58\x97\x54\x84\x9c\x72\xf9\x1b\x50\x50\x6d\x8f\x88\x6a\x50\x1b\x23\x53\x01\x18\x49\x5b\xe0\x6a\x2e\x76\x57\x56\x37\x8d\xbc\xa6\xf5\x39\xb9\xb2\x32\x64\x03\x46\x03\xfb\x6f\x25\x9e\x53\xa1\x24\x05\xf5\xbe\x60\xf3\x52\xe6\x99\x3c\x7f\x06\xe3\x4d\xa5\x67\xec\x8f\x76\x06\x1a\x92\xb1\xbf\x37\x58\xa5\x97\x46\xbd\x4c\x88\x25\x34\xee\x26\xb7\xd2\x06\x50\x71\x80\x9f\x0f\x59\xf1\x03\x95\x93\xfd\xee\x1d\xd7\x14\x03\x46\x63\x07\x08\xbd\xb5\x68\xde\xb0\xc8\x80\x68\x39\x7b\x44\x47\x7f\x3d\xe4\x9c\x40\x6c\xdd\x72\xb1\x3f\xb6\x33\xfb\xf3\x0f\xa7\x59\x6c\xaa\x8e\x6d\x25\xd5\xf3\x83\x83\x14\xa7\x3a\x49\x9d\x2e\xd0\x17\xa8\xe7\x22\x77\xdc\x8b\xcd\x1a\xfb\x8a\xcd\xbf\x4a\x95\x81\x9c\xb6\x2b\x23\x33\xbb\x2a\x94\x43\x46\x71\x16\xc9\x24\xec\x1d\x90\x76\x92\x51\x88\x7e\x7e\x5d\xe6\x0c\x8c\xb8\xc6\xfa\xcb\xae\x53\xc1\x90\x9c\xa1\x61\x39\xfb\x4e\xe4\xd5\xbf\xcd\x14\x88\x4b\xce\xb4\x61\x3f\xac\x28\xa7\x7b\x57\x56\xdf\xcb\xea\xc7\x75\xe4\x72\xb7\x23\x72\x5f\xb0\xa4\x63\x9e\xbb\x39\x55\xc5\x68\x59\xe6\x81\x6f\x08\xff\xaa\xac\x39\x41\xde\x43\xb6\x79\x90\x4a\x43\x34\x4b\xa1\x92\xad\x71\x64\x8e\xce\x02\x1e\xbf\x99\x80\x03\x31\x59\xff\xfe\xe7\xe6\x79\x5d\xbc\x77\xa7\x90\x9c\x9e\xf6\x98\xc3\xd9\x54\x14\x5c\x8d\x1f\xf0\x38\xf2\x63\xe1\x9c\x84\x06\xbf\xd6\x6e\x13\xe5\xb1\x0c\xd1\x68\x80\x67\xaf\xaf\x58\x59\x08\x95\x6b\x4d\x7c\xb3\xfa\xd3\x9a\x0d\xc5\x08\xbd\xc5\x93\x28\x0c\x4d\x25\xe9\x07\x79\x6d\x83\x00\x0d\x4f\x84\x30\x92\x5f\xa7\xca\x54\x13\xb8\x86\xd4\x33\x40\x80\xa1\x36\x35\xe5\x7b\xe7\xf7\x4f\x9e\x32\x45\x69\x61\x02\x80\x51\xba\x76\xfc\xe5\xd2\x24\x22\x2c\x2f\x6d\x97\xa0\x75\x8e\x77\x15\xe2\xc3\xf3\xee\xca\xf9\xb8\xe7\x0d\xd4\xf0\xc7\x70\xec\x5f\x45\xd7\x46\x8e\x09\xe7\x2a\xf5\x6c\xd1\x9d\x11\x80\xee\x04\xc2\xad\x59\xc1\x21\x96\xfe\x90\xc5\xa1\xcc\x0a\x93\x2d\x37\x11\xe9\xd3\x48\xb6\xd6\x1e\x23\x3c\x46\x59\x2c\xfc\x79\x5c\x37\x78\x30\x28\x17\xd7\x16\x25\xf4\x52\xa9\xb0\xa5\xfb\x51\x18\x9c\x9a\xc2\xe2\xdc\xee\xc0\x75\xfd\x51\x56\x16\xaf\x97\x0e\xe1\x95\x5c\x48\x9f\x48\xd7\x3b\x64\xf9\x53\x59\x7c\xa3\x40\xe9\x18\x51\xf1\xf7\x36\x58\x2e\x30\x8c\x5d\xd9\x9b\x91\x2a\x9e\xab\x30\x92\x5c\x32\xe9\x4a\xe5\x17\x79\xd3\xda\x4a\x57\xfa\x09\x4d\x15\x0e\x16\xa0\xaf\x4e\x33\x54\x6e\xe3\x3b\x50\x60\x2a\x42\xde\xe5\xcf\x21\x17\xb3\xe4\x4a\x1a\xdf\x8c\x66\xe5\xaa\x79\x6b\x2f\x6a\x79\xf3\xc6\x59\x27\xae\x54\x90\x1a\x3d\xb7\x76\xe2\xbb\xb8\xc3\x75\xed\xdb\x2b\xef\x42\xc7\x26\x43\xff\xaf\x61\x4d\xbe\xe4\x3a\x4d\xe9\x8d\xff\x2b\x7b\x2d\xba\x80\x12\xd7\x3c\xf5\x0c\x0c\x60\xb9\x7d\x9e\xbc\x04\x2d\x51\xda\x72\xdc\x0b\xde\xef\xf9\x97\xa0\x55\x44\x4f\x60\x18\x6e\x89\x76\x65\xb0\x3e\x69\x8c\x88\x46\xe0\x65\xfd\xc7\xea\x61\xbf\x1c\xe4\x4b\xb9\xd6\x46\xec\xa0\x5d\xfe\xd7\x4f\x0e\xab\x0a\x1e\x47\xf2\x3c\xfe\x28\x4f\x6a\xf0\x2c\xc0\x78\xea\x00\x36\xc5\xe9\x30\xbe\x6d\x60\xb2\xd3\xe3\xa7\x70\x88\x21\x59\x75\x87\xfa\xc2\x50\xc2\x65\x84\x49\xfd\xe8\x89\x8c\x6f\x4f\xed\x5a\xdc\x43\xb4\xc0\xd7\x3e\xf9\xbc\x94\x58\xa6\x45\xa5\xf3\xa0\x1e\x7b\x2b\x01\x82\x28\x4e\x07\xe2\x3e\xe3\xf5\x12\x82\x48\xfa\x16\xca\xbd\x95\xe5\xe9\x58\x76\xa2\x6e\xcb\x72\xea\x68\x41\x10\xfb\x04\x7e\xc2\x9f\xd9\x24\x59\x0b\xa1\x97\xc6\xa6\xe2\xe4\x48\xd1\x51\xb7\x2d\x41\xc8\x02\xb0\xf3\xba\xf5\xc5\x36\xed\x12\x5e\x77\x8d\x41\x64\xf2\x22\x15\x88\x9b\xb2\xec\x6a\x6b\x20\xd4\x29\xa5\xa2\x6f\xa8\xd2\x7a\xc8\xbf\x28\x21\x12\x8a\xf2\xa8\x45\xf9\x0e\xed\x2e\xd2\xfd\xae\x13\x5f\x77\xfb\x52\x2f\x05\xd9\x49\x4a\xda\x7e\xb1\xcf\x60\x40\xfe\x70\xcc\xb3\x06\x0a\xb5\xea\xaa\x94\x25\xc4\xa0\xc9\x0f\x59\x35\x7a\xe8\x74\x41\xac\x02\x66\xb1\x8a\x4f\x70\xc0\x97\x8c\x42\x23\xa7\x19\x14\x16\x24\x3e\x1a\xe2\x6e\xac\x9b\x2f\xd8\x3c\xc0\xc7\x79\x24\x68\x2b\x21\x09\x78\x64\x6e\xb7\xf5\x07\xee\x06\x14\x55\xe3\x41\x0b\x49\xca\xa9\x2a\xc2\x86\x40\xcb\xa2\xc0\x11\x1c\xce\x86\x5f\x86\xf8\x56\x7b\x64\xaa\xcd\xf0\x14\xa7\xaa\x18\x28\xbe\x49\xe0\x2c\xa5\x54\x58\x26\x4b\x0b\xca\xdc\x98\x7a\x7f\x95\x99\x6c\x46\x3b\x9a\xd6\xc5\x54\xa2\x5d\x02\x4f\x0c\xdf\x10\x92\xfa\x53\x21\xc7\x85\x65\x17\x40\xd0\xcf\xe0\xa1\xc0\x53\x4e\x95\x3e\x32\x6b\xf0\x05\x8e\xd3\xb0\x08\x70\x2e\xe9\x3b\xbd\x19\xdd\xbb\x75\xd1\x71\x05\x4a\xe0\x92\x51\x54\xe4\xa5\x3a\xbf\x2f\xbb\xef\x03\xcc\x10\x82\x66\x04\x9f\xfe\x52\x41\x31\x0c\x72\x8f\xbe\x0f\x44\x46\xd7\xa4\xed\x78\x6b\x02\x01\xf3\x86\x12\x40\x1a\x7b\x51\xc7\x1e\xf8\x8a\x41\x57\xda\x2b\x01\xc0\xe0\x88\x6c\x74\x73\xd9\xee\xbb\x57\xd0\x3e\x00\x22\xa5\x80\x72\x6b\x3c\x0e\x15\xe5\x24\x08\x2f\x26\x5f\x2e\xab\xbf\x19\xc6\xf0\x0d\x09\xc0\x76\x57\x91\x51\x48\x01\x0b\x8a\x0f\x7d\x1e\xee\x05\x29\xb4\x6f\x81\xd2\xdb\x63\x59\xd4\x65\x55\xbf\x65\xc7\x7a\x4b\x6e\xf0\xcd\xd9\x5a\x9b\xf3\x03\x4d\xc9\x88\x44\xca\x2d\xba\xc6\x30\x5f\xdb\x36\x0c\xa4\xe8\x6c\x37\x7a\x0f\xcb\xb2\x50\xd9\x00\xcc\x0f\x28\x02\xc2\xde\x9e\x0c\xed\x6f\xbf\x6f\xf7\x57\x40\xf4\xc7\xba\xfd\x46\xa9\xe6\xf3\xd0\x3a\x68\x66\xe4\xa7\xbe\x54\x88\xc5\xaa\xc0\xea\xb5\x7b\x75\x9a\x2b\x0a\x9d\x92\xba\x0c\x64\xf9\xae\x2c\x1f\xa1\x38\x3f\x12\xed\x43\x77\xf3\x1a\x84\xb2\x19\x9c\x21\x19\x95\x04\x8d\x9a\x32\xec\xcb\xfc\xef\xd4\x5d\x0a\x2f\x4d\xd8\x40\x58\xf3\xf6\x5c\xc0\x21\x93\x57\x29\x3b\xda\x03\x90\x18\x47\xf6\xae\x58\xbd\x5f\xbe\x85\xc7\x03\xcf\x44\x7d\xcf\xf5\xa8\xd2\x59\x0a\x0f\x42\x72\xb3\x8d\xb4\xd4\xba\xe7\x52\x72\xed\x32\xa1\xc0\x04\x49\x25\x51\x58\xc2\xa8\xd3\x8c\x27\x90\x60\xdc\x90\x08\x98\x85\xe3\x69\xf1\x6d\xfc\x35\x04\x53\x3e\xa5\xc1\xd6\xcb\xdd\x67\x28\x4b\xc1\x54\x4c\x0b\xae\x2e\x4f\x55\xf3\xf6\x1d\xd1\xed\x2d\xc2\xe7\x31\xb9\xa7\x5f\xf0\x40\x18\x2c\xf7\xc6\x45\x10\x18\xc1\x49\x62\x47\xac\x6b\x54\x86\xe7\xdc\xc4\xad\xb7\x39\xd4\x6f\x73\x7e\x8f\x88\x74\x4c\x08\xa3\x02\x3f\x86\xb5\xc2\xb6\x35\xf6\x42\xba\xdf\x43\x56\x0c\xcc\x67\x11\x33\x95\xc0\x48\x90\x90\x46\xae\x5d\xbc\x26\x57\x88\x01\xa8\x7e\xe4\x07\x4e\x8a\xde\xa5\x88\x5b\x93\xb1\xe3\x8e\xb9\x5d\x2d\xd7\x8f\x5d\x68\x47\x24\x61\x00\x36\x58\xf6\x3c\x05\x22\x89\x24\x34\x41\xa9\xbb\x53\xbb\x21\x90\x6d\xbb\x84\xfc\x22\x0b\x67\x87\xd4\x24\x62\x38\xac\x5c\x1f\xfd\x65\x57\xe6\x83\x48\x78\x84\x76\x38\x3b\x19\xb9\xcb\x64\xa4\x48\x50\x84\x72\x54\xeb\x41\x09\xd8\xf1\x2b\x4d\x99\xaf\x1c\xa2\xa0\xf5\x18\xcb\x93\x2b\xdd\x38\x42\xd5\x53\xb3\xff\x3b\xec\xc7\x76\xd0\xe9\xf0\x85\x6e\x98\x73\xdf\x23\x92\xb9\x7f\x94\xd5\xeb\x10\x6d\x2a\x78\xa2\xa3\xa4\x8f\x52\xd6\x26\xfd\xe3\x1a\x15\x10\xd3\xdd\x06\x15\x1e\x8e\x73\x72\xf4\x93\xe7\xe6\x28\xe9\xfb\xef\xf0\x70\xc4\x0a\xda\x77\xfd\x88\x50\x9f\x4c\xc9\xc9\xcd\x74\x43\x1c\x46\xae\x04\x47\x0c\x45\x57\x40\x62\xc0\xa8\xcf\xe2\x2f\x94\xcd\x43\x3f\xef\x20\x4a\x69\xf8\xb5\x73\x29\xb7\x52\x05\x0e\x0b\xdd\x9d\x89\xd8\xb9\xed\x0a\x5b\xca\x0c\x72\x1b\x73\xae\x0d\xcf\x8b\x3b\x97\xf0\x34\x65\xb5\xb0\x68\xaa\xf3\x70\xe3\x17\x92\x4b\x4c\x6c\xee\x6a\x57\xee\xca\x06\x1f\xb2\xff\x9e\x32\x05\x4d\x59\x8d\x4c\x73\x81\x0c\xc9\x34\xff\xba\xbd\xbd\x7d\xfe\xfe\xf4\xf0\xbc\xb8\x7d\xd9\xac\x97\x2e\x82\x2b\xb4\x67\x6a\x33\x8b\xd3\xc1\xc6\xfc\xeb\xed\x4c\x05\x92\xd0\x51\x48\xd5\xb6\x96\x3f\x6b\xac\x77\x2c\x85\x4e\x18\xa5\x3b\x1e\xca\x57\xbb\x83\x75\x0d\x68\x94\xa7\xa8\x8c\xce\xd4\x34\xac\x65\xd9\x35\x23\x27\x16\x33\xb3\xbe\xd8\xf6\x2d\xe4\x14\x7b\x78\x2c\x8b\xe6\x2d\x3f\x1b\x51\x31\x47\x49\xfd\xb7\x1c\x04\xe9\x79\x82\x0c\x64\xe3\xff\xbd\xe4\x20\x2f\xea\x4e\x5c\xcf\x00\x69\xea\x1b\x69\xb9\x0b\x1a\x42\x29\xbd\x50\x44\x06\xe3\x7f\xc8\x8a\xaf\x1d\xe2\x70\x94\xc6\x91\x5e\xec\xbb\x3d\x93\x32\xb3\x36\x87\x30\x25\xf0\x93\x92\x79\x11\xed\x70\x37\xeb\xe1\x72\x2d\x7d\xcf\xa8\x2a\xef\xa0\x6e\x26\x0d\xe0\xd9\x29\x78\x5f\xe6\x6a\x05\x15\x31\x96\xae\x2d\xb5\xca\xfc\x33\x05\xa0\x68\x19\x7a\xc7\xaa\xb5\xc6\x56\x46\x10\x4a\x8d\x80\xc9\xd3\x43\x94\xa0\x04\xd2\x7e\xce\x51\xbf\xf6\x77\xfc\x68\x61\x10\xd0\xad\xbe\x67\x75\x67\x07\xcb\x50\x0b\x12\xcc\x35\x81\x17\xc3\xd3\x93\x5f\x53\xc2\x94\x32\x0e\x12\x8a\xd3\x50\xba\xc6\xd5\xd5\xb4\x2b\xf5\x63\xd6\x91\x90\x4a\x19\x73\xa0\xf9\x63\xbe\xee\x71\xf4\x75\xc7\xf7\x14\x73\x41\xc4\x90\x4f\xcf\xbf\xaf\x17\xee\xf0\xc4\x4b\x8d\x10\x31\x14\xad\xf1\xff\xb5\x21\x55\xf9\x2b\xef\x32\x09\x04\x95\xd8\x10\x95\xda\x76\xff\xb2\xda\xec\x37\xcf\x5f\xbb\xea\x7e\x99\x70\x48\x23\x27\x3c\xd8\xf1\xc6\x49\x99\xfa\x9c\xd2\x2e\x1f\xbf\xf8\xaf\xeb\x9f\x08\x53\x4f\x54\xe6\x6a\x5c\xb2\xe1\x3a\xa4\x46\x82\xef\x0d\xea\x31\xff\x8e\x6b\x97\xdc\xb1\x0a\x3d\x57\xa6\x84\xe1\x09\x7f\x36\x77\x88\xdf\xb3\x42\x95\xdd\x85\x38\x13\xc2\xba\xbc\x04\x47\x7d\x81\xca\x0a\xee\xf5\x75\x2b\x73\x03\x65\xf2\x5e\x78\x1c\x6b\xb0\x04\xc4\xd7\x02\x77\x73\xf9\x7e\x7b\xb8\x8c\x4d\x19\x61\xe7\x05\xdc\xe5\xf0\xba\x28\xd4\x7d\xa6\x14\x16\xcb\xae\x88\x42\xca\x38\xb5\xb8\x24\x7a\xa4\xfd\x21\xa3\x21\x74\xa1\x18\x33\x7f\x97\x32\x4d\xa9\xfc\xab\xfd\xce\xa7\xe3\x17\x38\xe0\x4d\x1f\x6e\x93\x52\x9b\x50\x89\x5d\xd4\x0c\x82\xd0\x35\x2a\xf4\xe8\xd0\xcc\x70\x91\x1b\xb4\xd4\xcb\x14\x47\x2b\x51\x06\x3c\xee\x42\xc9\x76\x9b\xec\x5a\x75\xe0\x39\x11\xe3\x0d\x16\xcd\x25\x7e\x49\xea\x08\xa8\x10\x6d\x7f\xac\xb2\xff\xe1\x08\xee\x2b\xb5\x52\x14\x03\x38\x96\x0d\x16\xed\x4d\xe4\xe7\x65\x56\x91\xd9\x9b\x15\xaf\x2f\xa5\x7b\x49\xca\x8b\x0c\xa7\xa7\xa8\x4a\x50\x12\xea\x11\xc3\xb8\x54\x9e\x0c\x0c\x72\x1e\xed\x7d\x74\x3b\xa8\x62\x29\xf3\xb5\xdd\x49\x28\xaf\xb6\x2b\xe7\x27\x82\xf2\xbd\x88\x3e\x44\x17\x21\xb8\xa0\x39\xfe\x45\x0c\xc7\x9d\x27\x45\x6e\x03\xd3\xb4\x86\x99\xc1\x7c\x09\xb0\x55\xbe\x08\x0c\x8c\xc5\x28\xe7\x59\x5f\xa4\x35\x67\xff\x51\x8a\x8b\x7d\x60\x34\x19\x54\xe0\x25\xa9\xc5\x41\xca\xf2\x70\x84\x62\x52\x56\xae\x02\x99\x50\x36\xa5\x75\x85\x9c\xfa\x8f\x54\x81\x06\x0a\xee\xed\x05\xd4\x18\x87\x0a\x65\xa9\x46\xf8\x49\x15\xda\xfc\x5c\x17\xd7\x51\x91\xef\x53\xb6\xc0\x38\xe1\x94\x87\xee\x43\x93\xfd\x05\xa3\x08\x08\xcc\x5b\xe0\xcf\xe6\xa9\xbc\x00\xed\xa8\x08\xc1\x6c\xf6\x0e\x22\x3e\xd9\x62\x55\x1c\x32\xe1\xbb\xa5\xf1\xae\xac\x96\xe5\x28\xa6\xa1\xe2\x10\x06\x25\x7b\xab\xe6\xed\x16\xb2\xfc\x6c\xa8\xd3\xc6\xb7\x12\x4b\x24\x27\xed\xa6\xcc\xd5\x01\xba\x0b\x24\xa1\x24\xbc\x32\x36\x6f\x38\xb6\x22\x54\xa2\x3c\x02\xe2\xb5\x6e\x6e\x8e\xd5\x6d\x79\x12\x79\xd9\x93\xe0\xa8\x34\x36\x52\xf4\x2e\x40\x34\x7e\xb4\x54\x29\xcf\x66\x2b\xfe\x78\x19\xa9\xd2\x8e\xfb\x71\xc0\x5e\xe7\xb3\xf5\xc4\xaa\x53\xdd\x7c\x7f\xc3\x62\xdb\x90\xba\xaf\xbb\x1a\xd7\x86\x77\x48\x9c\xce\xcc\xc5\x65\x15\xa4\xa9\xb4\x6c\x88\x7e\x14\xdf\x9c\xaf\xd6\x49\x2b\xa1\x03\xd5\xe9\x81\x19\x82\x83\xfa\x11\x8e\x97\xa5\x88\xce\x07\x53\x92\x1b\x0a\xdf\x76\xc3\xc0\x25\xc1\xe5\xa6\xc0\x7d\xa5\x42\x3f\x30\x25\xda\x13\x75\x4f\xa9\x94\x08\x89\xef\x63\xf9\x74\xbb\xb3\x26\x8e\x6b\x42\xab\xa2\x54\x97\xf9\x3b\xfe\x66\x6f\x77\xee\x8f\xeb\x1f\x7b\xe4\xf1\xfd\x6e\xab\xd5\x46\x1c\x8d\xe3\x1b\x42\x15\x91\x87\x77\x20\x8a\x23\x1c\xa4\x92\xd1\x4b\x21\xe4\x1d\xc6\x67\xce\x8d\x42\xe6\x49\x02\x6e\x9a\xd1\x44\x0e\xe2\xae\xfc\x17\x56\xce\x72\x43\xc6\xbc\xd0\x6e\x23\x37\xad\xbd\xee\x56\x83\xcf\x98\xf3\xda\xa3\xc0\xb2\x39\x90\x00\x34\x4c\x56\x53\x24\x1a\x93\x5e\x6c\xa6\x79\x5b\x35\x6f\x97\x2c\x15\xc8\x52\xd0\xc6\x5c\x12\x43\x6b\x09\x99\x0e\x09\x30\xd1\x94\x37\x4e\xb0\x6a\x9c\x4d\xb0\xfd\x02\x16\xd1\x66\x6b\x78\x30\x8d\xdc\xd4\x06\xf3\x51\xd9\xe2\xc8\x81\xc5\x20\xf5\x93\x4e\xd7\x3e\x2f\xab\x3f\x31\xcf\xbb\x3d\x15\x03\xc5\x0d\x5d\x0b\x36\xf2\xcd\x0c\x90\x1c\x95\xc9\x82\xdf\x95\xd5\x23\x56\xed\x7b\x74\xd3\x09\xc3\xd8\x78\x21\xb5\x7c\x43\x75\xca\x71\xe4\xe9\xd1\x7d\x86\x03\xa7\x6e\xc4\xb3\xd0\xba\x4f\xd1\x7f\xdc\x79\x24\xe7\x9e\xf5\x66\xf1\x1d\x8b\x13\xee\x4a\x5b\x92\xd7\x5d\x0a\x0d\x48\x54\x14\xe6\x4d\x8d\xe6\x35\x46\x3e\x12\x46\xa0\xc9\x0e\xb8\x2f\x8b\x7d\x53\x81\xc2\xc3\xb0\xc2\x10\x23\xf0\xb8\xf5\x14\xbf\x97\xd5\x90\xa1\x56\x62\x1c\xa6\xb1\x4d\x35\xbc\x20\xc5\x00\x47\x11\x9b\xf1\x1b\x8c\x85\xf2\x63\x97\x39\x5a\x42\x25\xba\xa5\x0d\x13\x16\x44\x56\x93\xc9\xc0\x4f\xaf\x8c\x69\x4c\xc3\x90\xdc\x05\xf3\x14\xdd\xe4\xc7\x34\x0a\xa9\x24\x71\xd5\xfa\x0b\xdd\xec\x42\xee\x21\x71\x80\xe5\xf8\x8e\xf9\xd7\x49\x6d\x0a\xf2\xd8\x48\x69\x98\xba\x4a\x3b\x10\xef\xaa\xf2\xf0\xcf\x13\x4e\xc3\x4e\x08\x71\x08\x36\x99\x93\x6f\xcb\x03\x3a\xd5\x9d\x6f\x19\x3c\x9f\x9a\xfe\x7d\x43\x62\xd8\x7e\x1d\x9e\xeb\x11\xaa\xd7\x89\xd6\xba\x44\x40\x41\xfa\x8f\x28\xcb\xfa\x5c\x37\x78\x30\xc6\x45\x47\x84\xe2\x4e\x26\x99\xd1\x54\x7c\xc5\xe6\x25\xfb\x89\xbd\xe4\x55\x57\xfb\x8c\x52\x27\x24\x47\xd9\xee\x9f\x59\xf1\xda\x8d\xbd\x09\x37\xa4\xed\xad\x22\x41\x5a\x6b\x1d\x5e\xc7\x24\xc5\xfc\xd4\xb5\x2b\x8f\x66\xfd\xfe\x15\x9b\x5b\x0a\x24\xd2\x94\x20\x51\x66\x9a\x1b\x97\x2a\x23\x12\x91\x25\x34\x88\x3a\x15\xf8\xa9\xfa\xbb\x44\xf4\x7d\x74\x31\xb6\x2d\x11\xa9\xb5\xf7\xb9\xc5\xa6\x1e\x81\xd0\x51\x27\x8a\x5e\xcc\xf7\x9b\xef\xbf\x8e\xa5\xa1\xb6\x6e\x00\x28\xe5\x0f\x1d\xbd\x4f\x5d\x43\xd4\x10\x2a\x43\x87\x54\xbc\x58\x1a\xdc\xde\xdc\x44\xad\x7d\x6f\xf8\xfd\xec\xbc\x1a\x3f\x8f\xf6\x98\x67\x88\x4b\xda\xdd\x7e\xa4\xf2\x25\xb5\x17\x58\xb4\x2c\x36\x37\xa7\xb3\x25\xc1\xa3\x6d\x98\x68\x77\xde\xa7\xe0\x55\xed\x85\x21\xf6\x2a\xf0\x7b\xfc\x79\xcc\xcb\xd1\xd6\xaf\x99\x32\x94\x04\x5d\xc1\x40\x9e\xef\xca\x4e\xba\x6e\x76\xaa\x68\xa6\xcc\x12\x59\xa1\xae\xb0\x9e\x59\x44\x35\x53\x8a\xf0\x5f\x06\xb1\xf0\xac\x77\x6f\x58\x1d\xca\xe3\x39\x87\xf9\x57\x98\x5e\x2d\x8f\x18\xad\xf1\xda\x6f\xbd\x83\x4b\xcd\xdf\x2b\xf7\x19\x28\xb3\x23\xac\x1e\x46\x75\x9a\x3a\x8c\x04\x45\xcb\xac\x80\x19\x49\x5d\x9c\x30\xf7\x27\x0f\x11\xc5\x9a\x1c\x46\x50\xea\x06\x89\x01\xc7\xec\xe9\x97\x94\xf3\x93\xbb\x8c\xb8\x94\x3d\x89\xf4\x56\x66\xad\x85\x5d\x37\x77\x65\xb5\xca\xf1\x7a\x9d\xa7\x8e\x55\x9a\xd8\xd4\xdb\x62\xb3\x2e\xde\x77\xbd\xa0\xbf\xd4\x09\x37\x02\xac\x2e\xdb\x7e\xe5\x1c\x89\x0e\x08\x36\x67\xae\x3d\x12\xb9\x19\x85\x9c\x74\xea\x7b\x48\x39\x43\x8a\x0b\x3d\xeb\x0d\xca\xb2\x9a\x4c\x2e\x9d\x06\x29\xe1\x15\x76\x58\x37\xfe\xd8\xa4\xd2\x69\x24\x29\x82\x57\x37\x44\x17\x56\xbb\xb0\xab\x4e\xe3\xd4\x10\x22\xdb\x40\xf4\x80\x62\x57\xea\x54\x48\xb0\x06\xdb\xba\xc1\x2e\x5f\x40\x4f\x7a\xe9\xcb\x69\x1e\x44\xd2\xd6\x04\xdc\xe2\x6b\x85\x38\xdc\x24\x34\x0f\x4c\x41\xce\x7a\xf9\xfc\x81\xf8\x83\xf5\xb9\x0f\xcd\x43\xb3\x7f\x51\x46\xe0\xf1\x76\x72\xef\x3c\x94\xca\x45\xfa\xd7\xc5\x7b\xd6\xd0\x9c\x98\xb3\x56\x34\x78\x01\x15\x90\x59\x57\x81\x52\x7a\xf3\xc3\x0d\x98\x22\x9d\x92\xaa\x50\x04\x28\xdd\xbb\x7b\x81\xd4\xf8\x61\xa6\x90\xad\xd3\x42\xbd\x39\x8f\x11\x30\xe3\xb3\x89\x20\x01\x63\xce\xbc\x23\xe4\xb6\x88\xef\x05\x2b\xdd\x7b\x00\x83\x4c\xd6\xe8\x2f\x8b\x3f\xff\x7f\x17\x79\xd3\x42\xc7\x32\xb6\xca\x63\x63\xa6\x48\xdb\xa1\xf5\x72\xa9\xca\x8d\x34\x0b\xf6\xcb\xc5\x8b\x6b\x51\x1e\x50\xbd\xc0\xfa\xe9\x76\xdd\xfd\xe6\x4b\x8a\x67\x6c\xa8\x00\x90\x42\xa6\xa7\x9c\xe2\xa0\x50\xd7\x8f\xa8\x32\x18\x44\x5f\x35\x2a\x9f\x52\xc9\x47\x38\xd5\x46\xad\x67\xf0\xdd\x75\xe8\x91\xfb\xbc\x00\xf9\x06\xd5\x79\xa8\x7b\xa5\x3c\x8f\xfb\x14\x50\x6a\xdd\xe7\x91\xfc\x90\x6d\x67\xcc\x4b\x6d\x91\xfd\x3b\x56\x8d\x3f\xa1\x83\x98\x74\x8e\xba\xd0\xeb\x5e\x19\x60\xc1\x43\x97\x9f\x56\x9e\x1f\xc4\x14\x6b\x69\xe0\x07\x6e\x31\xcf\x9f\x67\x65\x86\xe7\x3c\x45\xe5\xf9\xa1\x09\xb2\xde\x96\x1f\x85\x91\xf6\xfa\x3b\x70\x0c\xe5\xf9\xe8\x59\x68\x5c\xbb\xcc\xdb\xca\xff\xee\xe5\x28\x2f\xf0\x63\xa7\x71\xd2\xed\xeb\x4b\xe3\x8a\x8e\xf8\xa2\xba\x0f\xa9\xbc\xd0\xce\x14\x3a\xe4\x03\x2a\x55\x8f\x61\x8e\x83\x68\xc7\xf8\x19\xc2\x44\x9a\x28\x17\x7e\x58\xec\xf7\x67\x56\x78\xdb\x5f\x85\x76\x0d\xbb\x83\xfa\x2d\x2b\x8b\x7a\xd1\x34\xd5\x80\xd9\xce\x76\x8c\x98\x24\xd6\x58\xa2\x6c\xea\x1d\xff\xbc\x34\x99\x80\xca\xdd\x79\xe4\x9b\xf2\x83\xd7\xf6\x65\x54\x05\x01\x8c\xae\xe1\x29\xdc\x21\x91\x62\x68\x03\x0f\x37\x59\x3e\xde\x14\x95\x17\xc5\x09\xa5\x85\x72\x68\x6d\x86\x91\x97\xa0\xbc\x28\xd5\xb4\xc5\x9a\x90\xd0\xd4\x52\x18\x5f\x27\xf6\x79\xd4\xde\xda\xdd\x1f\x94\x94\xf9\xb4\x50\x4b\x79\x31\xf8\xe8\x64\x89\xb1\x40\x8d\x32\x83\xe9\xc8\x05\x66\x94\xa9\x0c\x53\xb3\x93\x33\xbb\xf8\x9a\x10\x0b\xed\x77\x3a\x26\x65\xb5\xa7\x97\xb8\x41\x6d\x92\xa2\x93\x73\x0a\x4d\x2f\xfa\x40\x29\x89\x1b\xa7\x79\x30\xe9\x25\x3c\x83\xcf\xcb\x4b\x50\x4f\x06\xfa\x74\x45\x07\x42\x11\xbb\x66\xec\x94\x0e\xe0\x54\xdd\xf6\x52\x71\x5d\x8f\xd4\xd8\x6d\x24\x8f\xbc\x69\x64\xd7\xa0\x05\xc5\x84\x04\xf8\x52\x94\x16\xc2\xde\x8d\x09\xe9\x49\xb2\x7d\x1e\xca\x57\xb2\x0b\x65\x76\xfc\x35\xa7\xbf\xf2\xa4\xef\x91\xf8\xd3\xee\xa3\x5c\x14\x6a\x71\x0f\xb9\x7e\x29\x8b\xff\x65\xbf\x75\xed\x92\xe8\x81\x1f\x9f\x77\xb7\x59\x3d\x28\x12\x54\x9e\x8c\x7c\x6e\x51\x71\x20\x9b\xa6\xce\xfb\x55\x46\xaa\x90\x56\x6d\xc8\x73\xe3\x13\xd8\x57\x37\x7d\xbf\xed\x78\x33\x04\xbc\x8f\x7f\x8e\x96\x29\x95\x28\x32\x56\x48\x6d\x64\xf5\x8e\x85\x93\x74\x57\xcc\x63\x09\xa9\x04\xae\x5a\xb3\x6d\x83\x45\x33\xa9\x2e\x50\xcc\xc3\xd4\xa0\xc0\x31\x1b\x06\xee\x14\x63\xcc\x04\x23\x44\x8f\x50\x9c\xdb\x40\x14\x63\x89\x62\xc6\x0a\x39\x15\x3f\xd8\xba\x5e\xa8\x2e\x84\xac\x18\x53\x8a\xaa\x84\x2d\x47\x89\x51\x77\xec\x10\xc2\x86\x8d\xd8\xf5\xf5\x59\x10\x0c\xd1\xc1\xcf\x94\xde\x2a\xab\x4d\x99\x8f\x23\x4d\x8a\x05\x91\x4f\xd4\x27\xc6\xcf\x5b\x74\xc0\x57\xc5\x02\x61\x02\x30\xed\x1a\xba\x90\x43\xea\x1c\xd7\x41\xa5\x84\xd3\x76\x57\x79\xcc\x8a\xcf\x18\x3d\x15\x0b\x10\x28\xbe\x71\xf3\xfc\xf4\x75\xbb\xf7\xf7\xb7\x8b\x3f\xb7\xee\x6a\x61\x64\x9e\x7d\x63\x33\x2a\xa8\x3e\xe1\x95\x57\x2c\x44\x45\x95\x91\x87\x4c\x11\x38\xe0\xf9\xd8\x7d\x45\x16\x25\x01\x4d\x9f\xbb\xb2\xfa\x91\x0d\xbf\x2f\x8b\xb4\x49\x85\x34\x46\xc6\xb9\xd3\x6d\x52\x2c\x16\x86\x7e\xb6\x9d\xea\xbb\xe5\x85\x7d\xac\x58\x2c\x85\x23\x77\x72\xa5\x3b\xd7\x0c\xe0\x81\x5b\xa2\x58\xe2\x03\xad\x0f\x23\xec\xf9\x20\xac\x3a\xff\x78\x49\x28\x9d\x38\xb0\x5b\xf5\xa7\x7b\x26\x4b\x40\xe2\x60\x40\xb8\x79\x32\xc5\xd8\x28\x96\x08\x49\xd1\xf5\xbd\xca\x6a\xe8\x03\x15\x8a\x25\x32\xa2\x30\xc6\x7e\x08\xd0\x98\x01\xc7\x2b\x96\xf2\x88\x32\xff\x5d\x70\x04\xa1\x1e\x98\xaa\x93\x52\x37\xc5\x78\x18\x13\xe2\xfe\x91\x64\xe1\x47\xdf\x00\x3c\x33\xb5\x6b\x6c\x5e\x40\xfe\xa0\x32\xb1\xf1\xc1\xe0\x29\x1a\x57\xe6\x4e\x1c\xe7\xd9\x55\xd9\xa0\xc9\xa5\x81\x1b\x8f\x6e\x8b\x55\x86\xb5\x15\x2f\x98\x5c\xa1\x75\x4b\x28\x54\x72\xaa\x25\x39\xa8\xf6\x77\x15\xa4\x60\xd4\xa6\xfa\xec\xf7\xc8\x00\x53\x4c\xa5\x8a\x80\x97\x79\x56\x53\x4d\x49\x37\x82\x94\x54\x89\x05\x35\x50\xbd\x95\xdd\xb4\x87\x60\x3c\xc5\x50\x01\xb1\xa0\x51\x60\x38\xed\x7e\x45\xcf\xb7\x22\x16\xce\xf0\x19\xdd\x2e\x6a\x95\x28\x97\x9f\x27\x85\x93\x66\x59\xaa\xee\xfb\xea\x20\xa4\xd0\x85\x31\x56\xad\x57\x30\xfe\x7e\x9a\x0b\x02\x14\x64\xf5\x8d\x91\x91\xea\x6f\x49\x4b\x0c\x1d\x13\xfb\xa8\x6a\x5a\xf9\x1e\xa4\x29\x77\x26\x88\x09\xd1\x15\xcd\x7a\x72\x6e\x9f\x05\x2a\x60\x7d\x68\xf1\x4a\xca\x40\xf9\x3e\x4b\x95\x29\x38\xcf\xf3\x21\xfb\x94\xf2\x7d\x2e\x28\x81\x4d\x75\xdf\x26\x30\xe5\x90\x59\xca\x0f\x03\x96\xb8\x28\x04\xa5\xfb\xef\x8f\xbf\x0c\x8d\x2a\x3f\x0c\x95\x0b\x46\x3d\x95\xcd\x06\x29\x1a\x39\xe4\x95\xb7\xfd\xa2\xc0\xf7\xe4\x48\x56\x69\x44\xb2\xa2\xfc\x28\xf6\x10\xdd\xbc\xef\x7e\x14\xb1\x76\xda\x7f\x65\xe1\x58\x63\x87\x69\x7d\xe5\xc7\x9e\x20\xfb\x6d\x4f\x69\x79\xcb\xf8\x3b\xcd\x53\x5d\x80\xdb\x27\x32\x89\xca\x8f\x65\xe7\x61\x76\xe4\x5d\xb4\xc3\x0e\xf3\x81\xca\x4f\x58\x42\x78\xd2\xeb\xc8\xee\xf9\x8f\x92\x84\xdc\x77\xb4\x24\x6f\x50\x14\x98\x5f\xf0\x48\x28\x3f\x49\x63\x5a\x6c\x4d\x90\xf9\x03\x8e\xcf\x5d\x4c\xb1\x6d\x04\x4a\x4b\xed\x50\xbe\x15\x65\x5e\xbe\x9e\x83\x2f\xfd\xde\xf8\x99\xdb\xad\xfc\xd4\x8b\x49\xa2\xdd\x20\x64\x08\x8a\xb0\xbf\x75\x27\x4e\x23\x45\x28\xb6\xd5\xee\x7e\xbf\x7b\xde\xff\x73\xbb\x33\x6c\xfa\xfb\xcd\x62\xb7\xea\x3a\xe9\x94\x26\x94\x29\xcc\x5a\xd7\x39\xf4\xca\xaf\x5d\xe4\x3e\xb8\x90\xdc\x68\xff\x69\xc5\xa1\x95\xcf\x3d\xdf\xf7\x7a\x2e\xd0\x76\xd6\xee\xce\xc7\xee\x63\x73\x4f\x19\x31\xb0\x11\xa8\x4a\xf9\x3c\x34\x1c\xd9\xf5\x31\xcf\x1a\xa3\x5a\xd2\x7d\x0e\x9e\x1a\x17\xf4\x0d\xe1\xb8\x2d\xab\xc6\x45\xd6\x9c\xdd\xe4\x03\x33\x88\x50\x52\x4f\xd6\x0d\x56\x6b\x59\x0e\x33\x8e\xad\xa7\x15\x52\x40\x86\x32\x3c\x0e\x96\xd3\x37\x9a\xf4\x1b\x65\x02\xbb\x52\x7a\xe5\x0b\xc5\x88\x23\xcd\xc4\x12\xee\x40\x8e\x72\x7f\xca\x17\xe8\x11\x81\x8a\x0b\xf9\x5d\x5d\x53\x7b\xdf\xc5\x97\x02\x99\x0d\x61\x35\x39\xde\x5c\x96\xd5\xb8\x7e\x32\x0a\x4d\xea\x4b\x64\x55\xf3\xb6\xf8\x99\xcd\x93\x7e\x28\x5f\x62\x60\xc2\xe7\x44\x54\xdc\xee\xc3\xb3\x44\x43\xca\x47\xcf\x14\x78\xbc\x22\x71\xf3\x56\xdd\x73\x62\xcf\xf7\x7a\x5f\x36\x98\x77\x0d\xda\xe7\x86\xf2\xc7\x68\x19\xff\x0f\xd5\xbe\xa2\x05\xf1\x0e\xb2\x1c\xd5\x73\xae\x4c\xf6\x62\x02\x7a\x74\x47\x73\xae\x7a\xe9\x8e\xe5\x5b\x76\x49\x4f\x34\xb9\x43\x2d\x7d\x8a\x63\x0f\x80\x12\x5f\xab\xec\xa2\x7e\xbb\xab\x7b\x1b\x46\x74\x54\xe0\xb1\xd8\xc4\x5d\x5e\xb1\x59\xbf\xdc\x6d\x89\x2c\x6a\x72\xc1\xae\xab\x24\xa9\x6e\x73\x6b\xed\xf4\xfe\x52\xe6\xea\x21\x9b\x90\xc5\xab\xc0\x03\x4d\x14\x18\xcb\xe7\xa7\xbb\xf5\x97\xfd\x6d\x3b\xa7\xb6\xeb\x5b\x57\xda\xac\x02\xe6\x99\xf4\xc4\x2d\x34\xb0\x2c\x8b\x86\xf4\x43\xfe\x4e\x30\x4f\x05\x2c\x4e\x28\x08\x73\x03\xd5\x01\x9a\xff\xed\x70\x84\x4f\x51\x81\x1f\x09\xdf\xa6\x81\x4c\x66\xcf\x79\x7d\xd3\x65\xa0\x1f\x5e\x81\xcf\x15\xd1\xaf\xac\x97\xcf\x64\x96\x0d\x63\xc0\x2a\x08\x42\x46\x64\xa2\x87\xbd\x84\x3c\x17\x20\x7f\x7c\x81\xba\x6b\x94\x1a\x3c\x4b\x25\x3f\x97\x44\x54\x41\xe8\x9b\xd8\x15\x9c\x9a\xb2\xfb\xe6\xae\x2d\x61\x24\x1d\x55\x9f\x0e\xf7\x16\x11\xbc\x7c\xa6\xf8\x4e\xd4\x75\xe1\x40\xa9\x3e\x0b\x48\x82\xec\x73\xae\x3c\x15\x44\x3a\xa6\x08\x5b\x83\x70\xb0\xbe\xa0\xba\xe2\xbf\x05\x71\x1c\x51\xdc\x6f\x9d\x97\xef\xf8\x67\x79\x72\x17\x8d\x53\x53\x8a\xa1\xd0\x68\xac\x4e\x0f\x93\x1e\xf1\xd5\xdf\x2c\x96\xbf\x7f\x7d\xd9\xef\xbe\x3f\xbb\x03\x93\x20\x11\x9e\x5b\x53\x5e\x3b\x78\xa7\x0a\x12\x90\x89\xc1\xd1\xbc\xbe\xe6\xe8\x22\xd4\x83\x6f\x90\x32\xa0\xbc\x81\x11\x00\xbe\x39\xcf\x84\x68\x82\x94\x49\xb0\x2a\x4a\xff\x28\xc5\x45\xba\x7f\xa0\xbe\xe2\x0e\x00\x8f\x8c\x6d\xd0\xda\x19\xf5\xee\x86\x52\x04\x22\xbf\xc5\xe6\xad\x72\x94\x86\xae\x49\x6b\xca\x72\x28\x2b\x9c\xd4\x03\x33\x55\xc0\x7d\x93\x93\x36\x9f\x63\x1e\xa0\xe2\xba\xa6\x66\x5f\x3f\x56\x16\xee\x3a\x90\xd3\x50\x01\xe7\x06\x20\xad\xc9\x54\xdb\x1e\xa0\x1a\x8f\x63\x88\x0c\xcd\xce\x1e\xba\x3a\xcf\x8b\x05\x72\x34\x3b\x41\x21\xc9\x19\x1a\xe6\xb3\x27\xfc\xd9\x0c\x39\xfe\x87\x1c\x0e\x2a\x10\x89\x89\x18\x74\x11\xf1\x61\x04\xc0\x6d\x10\x81\x64\x22\xb4\xfe\xc6\xc3\x9c\x1f\x34\x03\xac\x55\x81\x4c\x22\xc6\x47\xd6\xcc\xfe\x69\xb3\x73\x4f\x25\x45\xe8\xb9\x60\xb5\xfa\xeb\xa4\x32\xd9\xfa\x84\xe3\x68\x4a\x80\xa1\x47\x1c\x64\x22\x2b\xa0\x3a\xef\x6b\x84\xaa\x2f\x6e\x9b\x3c\xb5\x8e\x24\x8d\x60\x9d\x15\x6a\x99\x67\x2f\xad\xa1\xb3\x28\xd4\x16\x9b\x97\x4a\x5f\x48\xab\xbb\x83\x44\xc7\x7e\xe3\x28\xec\x9d\x21\x1c\x7a\x9e\x4f\x34\xfb\x7b\x71\xca\x72\xb5\x7d\xcb\x8e\xc3\x3a\x2d\x36\x61\x87\x76\x07\xa1\xb1\x2b\x6b\xa3\x06\x60\x25\x34\xac\x22\x94\xed\xc3\x98\xe1\xaf\xef\x70\xe2\x83\x42\xbf\x6b\x95\x66\xff\x1f\x67\x6f\xb6\xdd\x36\xae\x6d\x0d\xbf\x4e\x2e\xea\x82\x24\x40\x12\xbc\x94\x25\xd9\xd1\x2e\x77\xc7\x52\x92\xaa\x3a\xe3\x0c\x0d\x34\x0b\x16\xb7\x29\x52\x9b\x8d\x1d\xed\xa7\xff\x07\x17\x00\x76\xa2\x9c\x7c\xff\x4d\xb9\x22\x82\x1d\x88\x66\x35\x73\xcd\x39\x11\x11\x52\x34\x08\xa8\x67\x18\x5c\x70\xe8\xb5\x6b\x2f\xcc\x96\x53\x29\x1a\x84\x21\xc6\x99\x8a\x76\x22\x6d\x51\x21\xda\xb0\xe9\xe8\x09\xfe\x42\x51\xea\x6b\x1c\x8b\xb8\xf8\x3d\x72\xb9\xc9\xfb\xe4\xbc\xa2\x51\x68\x2a\x64\x78\x55\x41\x55\xdd\x42\xb7\xd5\xd3\x28\xa1\x86\x20\x2f\xe5\xf5\xae\x98\xb2\x00\x28\x1a\x69\xea\xb8\x79\x1c\x8b\xcf\x33\x6f\x1d\xc5\xf9\xbd\x96\x46\x9a\xe1\x74\x4d\xcb\xa6\x57\x33\x6b\x7f\x4e\x10\xcb\xf9\x76\x96\x86\x24\x2f\xed\xa6\x31\x8d\x03\x8d\x15\x27\x36\x6b\xb0\x17\x67\x7e\xb5\x98\x50\xd1\x38\x8a\x90\x8d\x0c\xb5\x48\x37\x8f\x77\xfb\xed\xd7\xcd\x6e\x79\xff\xf4\xe8\x8c\x39\xca\xbc\x24\xb1\x51\x52\xc7\x5a\x31\x43\x37\xac\x28\x23\x14\x5d\x96\xc7\xa7\xee\xcc\xc4\xc7\xc5\xa9\xc2\x5a\xaf\x55\x91\x43\x97\x1d\x9d\x92\xb5\x2a\xca\x78\x6c\x94\xaa\x32\x9e\x1e\x3f\xf5\x2a\xe7\x2b\x4d\x14\x65\xc0\xd0\x4e\x50\x85\x4b\x67\xd9\x03\x09\x35\x82\x97\x48\x7d\xed\xf4\x66\x15\x4d\x98\xb0\xe1\x4d\xb3\xce\x6c\x9f\x2d\x83\xc3\x28\xdb\xe3\x1a\x73\x0f\xa1\x1a\x5c\xa9\xff\xa7\x1c\xc2\xc5\x53\x72\x6a\xcc\xf6\x7d\x0e\x1f\x5f\x8b\xb2\x82\xed\xa1\xf8\x64\xd4\x77\xba\x59\xe3\xa1\xcc\xa3\x04\x47\xfd\x9f\xc5\x69\x14\x4c\xa1\x9c\x09\x84\x99\x7d\xe0\x47\xdf\x1b\xa2\xc6\xa9\xf0\xe6\x60\xfa\x08\x16\x78\x83\x18\xbf\x49\xfa\xaf\x8a\x2c\xe3\x57\x82\x3c\x54\x32\xdd\x87\x0a\xce\x45\x73\x3d\x1c\x6f\x4f\x50\x7e\xe8\x5b\x40\xff\xa5\xa2\xec\xf8\xb5\x14\x61\x48\xe4\xf2\xfc\xf4\x74\xbf\x5f\xaf\x36\x3b\x27\x5c\xa9\x28\x78\x04\x53\x68\xc6\x88\xde\xf1\xf2\x15\xea\x19\x0a\x35\x45\x81\x13\x8c\x59\x89\xe6\x7c\xcf\x73\xf5\x23\xad\x1d\x45\x93\xfb\x20\x2e\x82\xfe\xc7\x38\x94\x4e\x35\x37\xe3\x84\xcb\x03\xf4\xfb\x62\xe8\x05\x11\xd6\x9f\xee\xd6\x8b\x87\xfd\xf3\xfa\x65\xb9\x7e\xdc\xed\xef\xfe\x59\x77\xc7\x43\xa3\x44\x78\xb7\xfa\xcb\xfd\x14\x44\x9e\x05\x7f\xd7\x77\xbc\xb2\x36\xc7\x78\x44\x85\x41\x64\x34\xbc\xfb\x6d\x01\x33\x68\xbf\x50\xf1\x9d\xef\xe3\x90\x78\x01\x56\x62\xac\xd6\xdf\x97\xf7\x8b\xed\x76\xbf\xfe\x6b\xf7\xb2\x58\x22\x27\xec\xcd\x62\xdb\x3d\x2b\x21\x80\x2a\x34\x46\x10\x15\x83\xa9\xe3\xee\x0b\x89\xa0\x5e\x64\x71\x62\xa5\x5a\x57\xb2\x2c\x3e\x9e\xf2\x1b\xab\x8c\x31\xb1\x95\x43\x4a\x98\x19\x0c\xe9\xab\xa9\x76\x7a\x2e\x8b\xd7\x92\x1f\xd7\xab\x6f\x23\x93\x31\xa4\x92\x22\xc7\xae\x65\xa0\x5a\xe7\xea\xee\xc2\xa5\x0d\x43\x4f\xa0\x39\x7d\xb9\xc1\xcf\xee\x5a\x61\xc8\x35\x3a\x4e\x8b\xdb\x97\xcd\xd7\x6f\x37\xb2\x6c\x37\x2e\xb7\x16\x87\x51\x40\x11\x43\x77\x32\x50\xdd\xa1\xad\x11\x46\xb1\x26\x36\x12\x81\xbf\x8f\x54\x30\x6d\x9b\xd8\x8f\xa9\x1d\xe8\x77\x90\x43\x95\x5e\x48\x8e\x4e\xda\x73\x1a\xeb\xc1\x7a\x82\x29\xd6\xd6\x27\x78\x2e\x11\x4f\x3f\x6e\xcd\x02\xed\x1b\xe3\xc4\x38\x3f\x38\x4e\x0f\x25\x54\x87\x21\xfd\xea\xe4\x9c\x28\x82\xc0\xa9\x28\x9c\x4a\x30\x5a\x26\xe3\x3e\x49\x44\x18\xf5\x7a\x33\xbf\xd4\x99\x99\xdc\x21\x91\x86\x13\xea\x8e\xbf\x57\x69\x5e\xb8\xee\xe2\x3e\xc1\x18\xfe\x4d\x5a\x2b\xe0\x19\xa6\x1f\xc7\xb7\xe5\xa1\x44\x0d\x9c\xe5\xcb\xd3\x8f\xd5\x76\x71\xbf\xde\x3f\x3d\xaf\x1f\xdb\x0d\x65\xb7\x79\xe8\x86\x1f\x8f\x02\xdf\xd4\x97\xa5\x99\x72\xd6\xaa\x2b\x1b\x98\x1f\xd9\x02\x02\x65\x32\x1d\x59\x56\xd4\xf7\xc5\xeb\x95\xbe\x51\x91\x46\xe7\xf3\x26\xad\xd7\x67\x98\x22\x2f\x5c\x23\xd0\x58\xa6\x0a\x38\xac\xc7\x46\x56\xa8\xb4\x21\xf5\x47\xe5\xc9\xef\x3c\x73\x4b\x4f\x08\x3e\xd8\xda\x5a\x05\x70\x7c\x81\x53\x63\xf2\xdc\xb3\xc4\x41\x2a\x04\x6a\x08\x50\x2c\x2a\xf9\xb9\x75\x78\x7f\x40\x3a\x50\xee\x53\x21\xb0\x18\x3b\xb4\x35\x7d\x8c\x53\x86\xf1\xad\x9b\xf3\x3f\x3f\x96\x9f\x7b\x33\xa1\x66\xda\xb7\x6b\xcb\x5f\x3f\xae\x82\xfa\x5c\x63\x09\x58\xf9\xb3\xfc\xba\xf8\xd7\xe6\xf1\xce\xde\x3e\xf2\x42\x89\x51\x81\xc7\x6f\x0f\xfb\x4e\x15\x71\xf1\xd7\x66\xdd\x35\x60\x0c\x4b\xe6\x76\x07\x9e\xbf\xcd\xd3\x97\x8c\xec\xe7\xa8\x35\x12\x12\xb7\x2b\x94\xfc\x08\x73\xba\x30\xd7\xf2\xbc\xe3\x0e\x8c\x3c\x08\x06\xb1\x4b\x94\xa9\xc4\x52\xf4\xbe\xac\x48\x45\xbe\x47\x50\xe0\xaf\xc9\xab\x22\xb3\xd5\xfa\x37\xbc\xcb\x37\x47\x7e\xa4\x82\x21\x1e\x67\xe9\xc4\x4d\xfa\xf4\x5f\xe4\x73\xaa\x51\x98\xf1\xdb\x8e\xd0\xfd\xf7\xf5\x76\x87\x4c\x86\xdd\x61\x61\xec\x76\x30\xb5\x19\x1d\xeb\xe2\xe8\x73\x44\xbe\x54\x48\xaf\xdc\xee\x6e\x9b\xe5\x6a\x7e\x74\x46\x01\x01\xb4\xfb\x8a\x92\xcb\x0c\x06\x81\xac\x88\x00\x8b\x2d\xd4\xd5\x81\x8f\x2e\x20\xe8\x2a\x22\x5a\x21\xd5\x11\x4a\x31\x3e\x35\xf5\xa9\xa9\xb7\x48\x8f\xf1\x65\xb6\xb2\xcc\x9e\x45\x93\x10\xe9\xc9\xbe\xa7\xf0\xb1\x47\xe0\x40\x6d\x2b\xcd\xcd\x92\xb0\xb7\x39\xf1\xe9\x59\x3a\x71\xfc\x91\x69\xc5\x37\x0a\x72\x6b\x61\x7e\x9a\x3e\x8c\x42\x15\x22\x86\x78\xb7\x59\xbf\x10\xf7\x7a\x21\x10\xdc\x09\x37\xdb\xfd\x76\x73\xf7\xb8\xd8\x3d\xbd\xfc\x3d\x1e\xa3\x51\x44\x28\xb1\xf5\x33\xcf\xdc\x10\xf9\x5f\x72\x42\xa9\x28\x62\x1e\x8b\x2d\xc8\xa2\xd7\x5e\x68\x7f\x37\xcc\xc4\xca\x46\x4e\x7a\x19\x39\xd5\xda\xb6\x08\x7a\x5e\x9c\x52\x53\x36\xbf\x1d\x86\x3f\x7f\x31\x1a\xaf\x8c\xce\x38\x09\x71\x74\xb6\xe3\x0e\xd4\x68\x97\x8b\xe2\xc4\x48\x0c\x21\x71\xae\x2d\x06\xed\x8e\x29\x0f\xd7\xbe\xbb\x92\x2b\xb8\x29\x8a\x6e\xa8\x32\x65\x42\x99\x15\xd4\x37\xdf\xbe\x7d\x9b\x6a\x50\x5c\xe9\xed\x84\xfa\x18\xa1\xb1\x0f\xf7\x5c\xc2\x31\xcd\x61\x58\x72\xac\x22\x19\x45\x38\x49\x2a\xae\xa1\x6a\xc4\xfc\x0a\x1b\x29\xdf\x60\x9f\xad\xdc\x2a\x16\xd5\x3e\x0e\x68\x45\x46\xde\x6c\xa4\x7c\xc0\xfd\x65\x5d\xa6\xf2\xf7\x94\x4c\x55\xa4\x24\x17\xa4\xf3\x7a\x5a\xe3\x79\x5b\xf3\x37\x67\xe9\x8c\xbb\x17\x42\xca\xac\xbe\x0e\x86\x4b\xaa\xc7\xce\x61\x8c\x40\xfa\x91\xa1\x89\x78\x38\xa3\x08\xfe\x64\x88\xe8\x48\x1b\x14\x7b\x73\x3c\xee\x80\x77\xe7\xe9\x38\xc0\x0c\xd2\xea\xfe\xaf\xef\xfd\x6f\x86\x86\xf9\xc8\x7f\xbe\x76\xc1\xab\x48\x33\x8a\x30\x95\x63\x6a\x57\x64\x5b\xf3\xdd\x1f\x0f\xd1\xf3\x73\xcb\xca\x85\x87\x17\x69\x30\xee\xd7\x43\x51\xe4\x83\xaf\x1c\x7b\x10\x24\xa6\xfc\x7b\xd1\x45\x41\x77\xc5\xa7\x75\xde\xed\x49\x31\x90\x9e\xa4\x66\xfe\x03\xc6\x7e\x60\x0a\x44\xca\x42\x14\xf5\x7d\xca\x05\x16\x4b\xdd\xa7\xe2\x4b\xd7\x80\x29\x6b\xed\xdc\x15\x3c\x5b\xef\xbe\x7e\x99\x5c\x21\x0e\xec\x76\x94\x3f\xf0\x37\xf8\x96\x97\xa0\x9b\x8a\x8b\x0c\x90\x73\xb6\xbb\x0e\x37\xe9\x56\x7c\x9c\xa9\x8b\x14\x07\x09\x17\xd2\xd9\x54\xc5\x69\xc5\xcf\xd3\x06\x2a\x34\x7a\x75\x5c\xbe\x41\xcf\x79\x62\x8f\x12\x8f\xfb\x7d\x58\xaf\xc3\x63\xcf\x44\x54\x62\xc2\x0d\x96\x78\x2f\x4d\xf5\xe6\x2d\xcc\xa3\xbf\x54\x4c\xa4\xef\x81\xf3\xe3\x7f\x40\x6a\x52\x5c\x1d\xc9\x86\x03\x12\xc4\xa1\x9f\xa0\x3c\xb8\xdd\xb3\x8d\x3f\x68\xa6\xf6\x85\xd9\xd4\x39\x4f\x71\x48\x8d\xe8\x65\x05\xb0\xae\x0f\x83\x9a\x73\x15\x87\x2a\xc2\x61\xbc\x97\x3c\x5f\x15\x1f\x79\x56\x70\xf5\xe5\xd7\x7c\x09\x2a\x0e\x75\x84\x41\x8a\xf9\xf2\xd7\x45\x87\x1e\xfc\x03\xaf\xd1\xed\xc3\x7e\x34\xee\xa2\xd8\xa7\xb8\x12\x3d\xa7\xa0\x9e\xd3\x93\xd5\x1c\xfb\xe5\x54\x8d\x59\x18\x23\xf1\xb5\xe5\x97\x7a\xe0\x39\x7f\xed\x07\x00\x13\x12\x6d\x0f\x93\xd8\x59\x36\x55\x5d\x1c\x67\xb8\xb9\xc7\xdf\x20\x61\x01\x57\x76\xe1\x76\x42\x2d\xee\x50\x12\x93\xae\x80\x3c\xdf\xc2\x24\x0c\x13\xf3\xc4\xc3\x92\xd6\x23\xff\x89\xea\x83\x83\x04\x7a\xcc\x75\x1c\x44\xbd\x70\xda\x27\x24\x64\x2a\x16\x94\xcb\xa9\x5e\x60\x10\x7f\x19\xb7\x89\x12\xec\x31\x9d\x72\x5b\x61\x2e\xdd\x42\x1a\x0b\xc9\xa3\x61\x74\x70\xdb\xc8\xd6\x8b\xd1\x4d\x36\xce\x5c\xc6\x42\x87\x6e\x2f\xc3\xd8\x00\xe6\x0e\xe6\x67\xad\xf4\x4c\x20\xc0\xbe\x7b\xcd\x31\x00\xec\x42\x17\x93\xb6\xda\xa4\x0f\xd0\x96\x1c\x44\xa2\x62\x25\x8d\xee\xb8\x91\x81\xe1\xaf\x06\x16\x3b\xfd\x1e\x83\x21\x0b\xdc\x24\x06\x6f\x1b\xf5\x0a\xcb\x46\xbe\x75\xf3\x4f\xc7\xa0\xbb\x7c\xe2\xca\x4a\xfa\xa7\x1d\x72\x56\x31\x2f\x24\xd2\xa6\x77\x6e\xa0\x1e\xd6\x41\x2b\xe6\x45\x4a\x3b\xa3\x94\x37\x38\xd8\xa6\xf9\x7d\xe6\x09\x86\x08\xc1\x4e\x5c\x6d\xb0\x8b\x33\x4f\x18\x57\xae\xa3\x5f\x1b\x7d\x1c\xe6\x69\xa9\xc6\xce\xf2\x9c\x86\xba\x62\xbe\x67\x62\xc4\xc7\x4e\x86\xe5\x29\xff\xd1\xc5\xcd\x98\xcf\x0d\xa9\x7f\x67\x59\xae\x8a\xbc\x7b\x84\x20\x0a\xf0\x11\x4e\x1d\x93\xf8\x00\x71\xab\x58\x20\x05\xb1\x5d\xfd\x15\xd2\xf2\xcb\xa5\x2d\xdc\x3f\x06\xf1\x7c\x67\x42\x2d\x0f\xbc\xb5\x48\xa0\xbc\x28\xde\x57\x8c\xf8\x0a\x63\xbf\x96\x34\xd3\xe0\x38\x6e\x01\xaa\x9d\xf3\xbc\x18\x21\x9e\xab\xef\x6f\xbb\xac\xea\x7e\xe7\x24\x36\xf6\xaf\xf5\xa8\x41\xfd\x4f\x03\xe5\xf9\xc6\x0c\xc7\x69\xbf\x10\xa5\x18\xef\xbc\xfa\x47\xf8\x98\x75\x17\x58\x48\x23\x6a\x78\x37\x5f\x53\x87\x35\x63\x21\x18\x87\xe3\x9f\xe2\x28\x52\xf8\x58\x1a\x75\x20\x77\x34\x4a\x08\xd6\x23\x54\x37\x69\x3d\x08\x51\xb2\x28\xe1\x98\x95\x4a\x8f\xc7\xa2\xac\x3b\x62\x1e\xc5\x62\x12\x51\xea\xa8\xaf\x7f\xa7\x84\x79\x90\x78\x67\x31\x8f\x11\xc7\xfc\xe3\xfe\x66\x55\xf2\x8f\x6a\x75\xe3\x2e\xcb\x7c\x8a\x68\x44\xc9\x4b\xe3\x50\xf7\xb2\x87\xae\x45\xc0\x30\xbf\x71\xb3\x7b\xdc\x76\xa2\x10\x8a\x31\x2d\x2c\x9b\x32\xd2\x6c\xf1\xba\x86\x32\xff\x56\xb5\x1f\x6c\x58\xcc\x3e\x9a\xe7\x2c\x09\x01\x7c\x07\x2d\x2d\x07\x79\x99\xc1\x5c\x63\x22\x88\x3d\xab\x10\x8d\xe6\xf6\x6d\xd1\xfc\x92\x70\xdb\x9d\x1a\x6a\xee\x88\x85\xd0\xa8\x6d\x37\x3a\xc3\xf3\xbc\x1b\x80\x09\xdc\x3b\x88\xd8\xc3\x94\xe5\x6b\xc9\xf3\x7a\x81\x6b\xd3\x43\x7a\xb9\x10\xd8\xd6\xd2\xe7\x91\x29\x53\x2c\x5e\xb3\x91\xf0\x75\x7b\xcc\xac\xf0\x25\x70\xb5\xaf\x86\xc6\x2d\x93\x81\xa1\xcd\xdc\x67\x05\x32\x1c\xff\x00\x71\x97\xea\x1a\x73\x0b\xb9\xc2\x9a\xa1\xf9\x5d\x98\x49\x22\x83\x61\xa0\xbf\xf8\x85\x2b\xc1\xa4\x30\x42\xc8\x46\xd4\xf7\x61\x28\x3d\x6c\x5b\x40\x04\x81\x9d\x17\xdf\xa1\xac\x7a\xaf\x8e\xe9\x44\x9a\x4c\x5d\x8a\x06\xcc\x75\x1e\x64\xc5\xb4\x00\x07\x00\x5e\xa5\xaf\x29\x06\x6b\xbe\xa5\x97\x75\x05\x43\x4f\x97\x69\xc5\x30\x44\xb2\xfe\x09\x79\x3a\x46\x1f\x24\x9e\x9f\x80\x21\xc6\x5f\x6e\x9e\x37\x6b\x57\x81\xaa\x12\x2f\x48\x30\x67\x89\x50\xcf\x02\x29\x97\xdd\x11\x9a\x20\x6a\xc5\xe4\xaa\x8d\xb9\x35\xbd\xfd\xac\x7e\x96\x4a\x82\x38\x41\x3c\xda\x5f\xcf\x3d\x1e\x5c\x25\x81\x88\x92\x21\xb6\x6d\x05\x9a\x37\x99\x43\xa0\x55\x4f\xda\xa4\xde\xa6\xcb\x73\x12\x58\xde\xb7\x75\x6b\x51\x95\xa9\x34\x25\x56\xdd\x41\x85\x10\x86\xfb\x69\xd4\x70\xfe\x03\x26\x01\x10\x60\x2e\x9a\x3f\x66\xe6\x55\x09\xe1\x86\x35\xbb\x44\x02\xa4\x67\x28\x8f\x69\x55\xa1\xba\x46\x2d\x87\x64\xb9\xc3\x1d\x20\x09\x29\x41\xa6\x52\x4c\x41\xc2\x62\xb2\x72\x25\x61\x18\x18\x9e\x9d\x97\xdd\x8f\xa7\x97\x3f\xf7\x5d\x3e\x63\x40\xa5\xa1\x92\x50\x4a\xc7\x25\x67\x0b\xf8\x07\x09\xd7\x24\x22\x01\xb1\x02\x51\x77\x65\xf1\x51\x1f\x6e\x9a\xe3\x69\xd2\x4b\x31\x51\x4e\x5b\xb7\xdd\xbe\xaa\x9a\x1f\x4f\x5d\x64\x60\xb4\x46\x24\xb1\x26\x49\xd8\x85\x8d\xbe\xcc\xa8\x27\xaa\x84\x29\x29\x2c\x29\x85\x9b\xd7\xed\x83\x21\xbd\xc7\x08\x77\xf0\x5b\x30\xbb\x24\x69\x0d\x02\xf3\x06\x03\x3e\xfb\xc1\x2b\x26\x42\xa0\x43\xdc\xa5\xdc\xbe\x6d\x57\x3f\xd2\xfa\x60\xd2\x9d\x93\x8b\x81\xc2\x45\xe5\x64\x5c\xa0\x1f\x90\x0e\xf7\xc3\x24\xd1\x26\xf1\x56\x0d\x28\x71\x27\x1f\x45\x04\x31\xe2\x04\x6e\xd3\x12\xfe\x1a\x4d\x14\x11\xfb\x52\x76\xe1\xa2\xfa\xda\xca\x91\x28\x3f\x41\x26\x84\x7f\x23\x51\xe4\x80\xd1\x73\x32\x37\x5c\x73\x41\xb0\x96\xff\x3b\x94\x35\x54\xc3\x59\x01\x7e\x84\x90\xa4\x45\x76\x3a\x14\x79\xb7\xb9\x25\xc0\x0c\x16\xe1\x03\xa9\x50\xef\x79\x75\x05\x48\x93\x80\x0c\x30\x1b\xbf\x37\x3a\x28\x98\x94\xdf\x6f\x96\x4f\x2e\xd2\x91\xe8\x80\xf9\x96\x31\xe6\x5f\x85\x30\x7a\x26\x4b\x5e\xc3\x6b\x51\x4e\x1c\xa1\x44\x87\x1c\x4c\xcc\xe8\x27\x46\x96\x3f\x4f\xa0\x24\x3a\xd4\xe8\xbe\x16\xbc\x4a\xab\x55\x5a\x42\x17\xe0\x48\xb4\x14\xc8\xd4\xf6\xef\x06\x5e\x8b\x6d\x9a\x65\x7c\x59\xe4\x15\xe4\xd5\xb9\xf2\xfc\xf1\xd7\xe0\x1e\xf1\x0d\x7f\x08\xe6\x71\xbb\x7b\x8e\xff\x0c\x56\x3a\xee\x51\x8d\xbc\x7d\xdb\x63\x59\x0f\x3e\x1e\xf7\xe2\x00\x29\xdb\x72\xf8\xc0\xa0\x92\x89\x76\x5b\x4c\xe7\x84\x76\x78\xf8\x79\xb8\xef\x31\x34\x31\xff\x55\x60\xb0\xec\x09\x47\xdd\x08\xd9\xc7\x7d\x30\x2f\x64\x60\x93\x86\x6a\xe2\xb9\xa8\xd2\xae\xec\xd7\xe4\x6f\x22\xfa\xc7\x50\x5d\x41\xf1\x80\x52\xa4\xde\xc0\x5f\x1f\xe0\x58\x94\xe7\x45\x59\xf2\xf3\x80\x19\x40\xf1\x40\x9a\x7a\x6b\x53\x10\x82\xa3\x79\x5e\xbb\x5a\xf1\x00\x4c\xed\x8b\xa5\x39\x53\xd3\x30\x6b\xd7\x0c\x70\x67\x6b\xfd\xc6\x8e\x50\x7e\x2f\x27\x52\x77\xf3\x91\x24\x4e\x3c\x82\x23\xc6\x05\xab\x4b\xa3\xdb\x76\xad\x31\x45\x17\x00\x39\x94\x87\x73\x89\x3b\x48\x38\x1a\x54\x76\xc4\xa5\xe0\x5f\xbb\x0e\x44\x98\x77\x58\xd7\x87\x5b\x2e\x07\xc5\x06\x9c\xea\x04\x37\x0e\xb3\x13\xb5\x2f\x9c\xe6\x4d\xd1\x54\xdb\x21\x91\x44\xd7\x56\xa2\xa1\xd8\xe4\x0f\x4d\x0d\x3f\xdd\xcf\x61\xe2\xa9\x61\x69\xe6\x0a\xde\x07\xd9\x71\x1e\x6a\x86\xf0\x89\x26\xbf\xc9\xb8\x7c\x43\x4a\xe8\x71\x6a\xd2\x36\x8c\xfd\x04\x97\xa9\x22\x5f\xbf\x2c\x93\x84\x19\xea\xf6\xab\x38\x9f\xa1\x89\xc8\xe3\x48\xfb\x86\x2e\xb6\x35\xe4\x78\xb6\x02\x99\xa5\x39\xcc\xa3\x25\x38\xa3\x42\x1a\x79\xac\x8f\x4d\x5e\xc3\x6b\x99\xd6\xe7\x5b\xb8\x08\xf6\x8e\xc7\x31\x8b\x34\x06\x32\xfe\xf5\x6d\xbb\xeb\x40\x32\x9c\x09\x1e\x2a\x57\x2a\xf7\x02\xed\x6e\xdb\x93\xba\x4d\x96\x46\x9e\x84\x31\x7a\x94\x76\x7c\x8d\xbc\x1d\x9e\xc4\x86\x81\x2e\xb5\x44\x4f\x37\xe7\x45\xd6\x77\x72\x02\x86\x2a\x04\xe7\xe4\x46\x16\x13\x55\x7b\xc5\x39\x25\x18\x49\xb1\x18\xf4\xaa\xf5\x9a\x4f\x88\xdb\xf7\xbb\x26\x61\xec\xd9\x8d\xe2\xcb\x10\x59\x61\x0f\x8b\x08\x3c\x0b\x07\xe1\x86\x9f\xd4\x0d\x80\xc9\x26\xc1\x25\x51\x98\x50\x54\xc0\x55\xdb\xcd\xbb\x0f\xe7\xba\x70\x08\xb8\x11\x51\xde\x8d\xd6\x7e\xae\x03\x82\x29\x6a\xfe\x6a\xe5\xa2\x5c\x01\xdf\xf8\xca\x9a\xc4\x28\x42\x61\xdc\x9e\x2b\x40\x9b\x61\x04\xe3\x57\xa9\xd2\xc9\x0c\xd7\x31\x67\xae\x3a\xcc\x8d\x46\x8c\xc0\xe7\x83\x82\xa8\x41\x9f\xe8\x24\x42\x64\xda\xee\xc0\xd3\x1b\x7e\x30\x16\x63\x97\x90\xe0\x3a\x49\xb0\x02\xe6\x00\x65\x31\x9d\x2d\x5a\x86\xac\x1d\x2f\xcb\xe2\x78\x2a\x9a\x5c\xed\xf3\xe2\x63\xbf\x90\xb2\x6c\x40\xed\xd3\xf6\x9e\xe0\x44\x7d\x95\xf0\x82\x08\xb9\x5a\x11\xa5\x32\x28\xd3\x54\xc2\x23\x09\xd2\x5c\x59\x35\xa9\x67\xe7\xf8\x75\xc7\xa3\x00\xc3\x62\xff\xdd\xaf\xa0\x6e\xad\xaa\xdc\xaa\x4f\xda\xe3\xbe\x20\xc4\x86\xef\x1e\xe1\x67\xfd\xc0\x7f\xa6\xc7\xe6\x68\x2a\x3a\xba\x46\x41\x42\x24\x7a\xda\xa6\x18\x69\x05\x6f\x19\x9f\xc7\x59\x8d\xfb\x53\x10\x16\x20\xad\xda\x6a\x7d\xbb\xf8\x76\xbf\xdb\x2f\xef\x37\xb7\xb7\x5f\xba\x83\x1a\xb9\xd8\x6f\xd0\x21\x3e\x9e\xa6\xda\xd3\x4a\x10\x01\x18\xc9\x50\x20\x4d\xa8\xeb\xe9\x04\xf9\xc6\xf6\x4d\x6b\x98\x5b\x55\xe5\xf1\x59\x34\x91\x48\xcd\x39\xa3\x5c\xf9\xff\x34\x1a\x04\x15\x96\x9a\xa5\x35\x58\x57\x3d\xbc\x4d\x84\x4a\x60\x98\xe9\x03\xd2\x5d\x31\x82\xe0\x4d\xae\x10\xf1\x98\xe1\x78\x5d\xdc\xaf\xb7\xfb\xd5\x7a\xb1\xba\xdf\x74\x28\x1a\x11\x09\x9e\x08\x97\x5c\xbc\x43\x22\x22\xcb\xc7\xb0\x6d\x84\xb5\x7f\xbb\x6f\x10\xfb\x2a\xec\x8b\xe7\x2e\x71\xdb\x9f\xbf\x4a\x4c\x64\x1c\x20\x73\x2e\xbc\xf7\x78\x43\x11\x53\xce\xf9\x58\xc2\x60\x36\xd8\x24\xe2\x90\xa3\xcd\xf5\xad\x4a\xf3\xd7\xc5\xf7\xb4\xac\x1b\x9e\x6d\x31\x1c\xd4\x5d\x2b\xf1\x3c\x9b\xbc\xfe\x91\xe6\x50\x9e\x4d\x2d\x53\x6b\xc3\x9f\x5f\x50\xad\xb4\xf5\xf1\x66\xd5\xc3\x67\xe6\xea\x24\x76\x29\x98\x1f\xa2\x26\xfe\xc9\x16\x99\x2c\xd4\x34\x70\x39\x6a\x9e\x28\x86\xfb\x56\x2a\x8b\x75\x8e\x52\x6c\xfc\x15\x16\xee\x51\x79\x40\x3d\xcf\xed\x8e\x0f\xa9\xca\xd3\xd7\x43\x8d\x71\x34\xd7\x42\xc4\xa6\x12\xac\x3a\x14\x1f\xcf\x45\x91\x39\x5a\xd1\x71\xaf\x08\x69\x74\xa2\xa0\xbd\xc5\xcb\xd3\x76\xb9\x78\x81\xba\x4c\xe1\x1d\xb6\x4d\x79\xca\x9a\xee\xe3\x49\xa0\xc8\x5d\xd3\xe9\xde\xba\x3a\xe5\xb9\x50\xb6\x50\x61\x80\x11\xa9\xbc\x69\x6f\xfa\xa4\x6f\xb8\x7c\x1b\xcc\x46\x15\x82\x11\xf4\x81\x5c\xed\x51\xfa\xc3\x74\x98\x3b\xcc\x63\x4c\x78\x20\x95\xe1\x53\x7e\x0f\x5c\x59\x6d\xb4\x6a\x54\xf7\x20\x20\x8a\x51\xbf\x82\xbb\x0b\x03\x8f\x0c\xa8\xba\x10\x85\x2d\x5b\x1b\xef\x50\xa2\xf5\x5a\xac\x3d\xfb\x78\xbb\x13\x06\x9a\xbe\x99\x78\x8d\x42\xfb\x09\x2e\x17\xa6\x4c\xe0\x65\xb1\x5b\xef\xef\x17\x5b\xe7\xf7\x0a\x1d\x18\xe0\xc0\x3b\x1c\x52\x99\x81\xe3\x94\x19\xe1\x11\xae\x2a\x4a\xb5\xa7\x73\x62\x12\x3e\x8f\xf0\xd1\x53\x92\x2a\xa1\xc3\x00\xe3\x7c\xa6\x90\x67\x16\x35\x6f\x5a\x4a\x8f\x80\xc4\x04\xe4\xe3\xed\xfd\xe6\xfb\xaf\x23\xe0\xd2\x8b\x00\x99\x1c\x4e\x45\x55\xef\xfe\xfa\xdc\xcf\x95\x1e\xf3\xd1\x2b\xc5\xbd\xd8\x79\x70\xb8\x4a\x54\x87\xf4\x34\xee\x51\xe9\x7b\x56\xf7\xd2\xf2\x64\x8e\x6d\x49\xe9\xfb\xa1\x34\x50\xac\x34\xe7\xf9\xcf\x1a\x8e\xa7\xee\x50\xc4\xc3\xc8\x95\xef\x9f\x8a\x7a\xdd\x8b\xca\xb8\x16\x31\x15\x56\x44\x60\xa2\xa2\xaa\xa4\xcf\x7c\x44\x55\xb9\xf9\x64\x9c\x97\xfe\xbe\x09\xd1\x8e\x1e\xaf\x3e\x40\xf9\x32\x06\xff\x4a\x5f\x11\xa4\xf7\x4c\x2b\xac\x89\xe8\xc8\x01\x94\x0c\x02\x8a\x66\xda\xc9\x4a\x8f\xb5\x5f\x03\x23\x04\x83\x26\x11\x45\xf9\x0f\xc1\xf3\x37\xc7\xd5\xea\x0e\x01\x75\x90\x81\x9b\x7f\x7e\x5e\x88\x92\x7f\x9e\x86\x95\xc4\x23\x46\x4e\xcb\x10\x99\x2e\x4e\x27\x98\xe6\xe6\x25\x09\x62\xe4\x31\x3b\xf2\x9f\x66\x7e\x7d\xe9\x0e\x08\x5c\x22\xf1\x7d\xb7\x75\x71\xba\x2f\xfa\xef\x40\x22\x8d\x78\xd7\x2e\x48\x8c\x79\xc8\x7e\x1a\xdb\x66\xa1\xd0\xba\x0b\x67\x57\x8e\x0b\x70\xe4\xcd\xc8\x48\x70\xe8\x00\x4d\xb7\x88\xc5\xbb\x39\x9f\xf8\x34\xee\x2a\x23\x69\x44\x52\x9e\x9b\xba\x76\x90\x73\x19\x0b\x85\x6a\x0a\x35\x54\xa6\x64\xbb\xe9\xe2\xed\x92\x89\x10\x5d\xb0\xea\x50\x94\x35\xe4\x73\x08\x23\xc9\x34\xc5\xed\xfe\x79\xc8\xf1\x3a\x19\xbf\x49\xe4\xf9\x61\xaf\x15\xd9\xf5\x41\x22\x0d\x33\xbb\xa5\xde\xb0\xc1\xfa\x2b\xce\x92\x4c\x40\x68\xc0\xda\x4e\x57\x07\xd5\x7e\xcd\xbd\xbb\x18\x0f\x13\x69\x4a\xe1\x44\xd7\x33\x3c\x36\xf2\x00\xad\xdf\x9d\xe6\xaf\x46\xb6\x6d\xf2\x02\x5c\x11\x27\x5d\xbf\x4c\xeb\xf4\xbf\x90\xdf\xbb\x02\xee\x71\xf7\x71\x4d\xc0\x45\x4b\xf7\x15\xd4\xcd\x09\x13\x34\xd0\x17\xea\x4a\x41\x23\x24\xa2\xd9\x73\xa5\xec\xc6\x6b\x79\x5f\xec\x92\xe6\x3c\x02\x29\xc3\x04\xed\xce\xd5\xfa\xf6\xe5\x69\xbb\xdb\x6f\x1e\x37\xbb\xcd\xe2\xbe\x43\xfe\x3d\xfd\x78\x74\x62\x47\x4a\x4a\xc9\x71\x20\xb5\x7b\xc7\xed\x73\x3b\xf6\xeb\x3e\xa9\x21\xa5\x56\x40\x07\x52\x48\x06\x6a\x6c\xb4\xb1\x26\xa0\x03\x7b\x86\x8a\x63\x0c\x6b\x9a\x61\xb4\x9d\x09\xb4\x75\x0d\xb9\x91\x76\x87\x5c\xa1\x34\xc0\x36\x7d\x9d\x2f\x1e\xba\x5a\x4c\xd4\xfb\x4c\x52\x25\x31\x26\x1d\x9f\x9f\x67\x53\xfa\xa3\xf5\x51\x81\xc6\xa1\xd7\x7a\x14\x98\x25\x59\x61\x7d\xe0\x40\xf1\x71\xf2\xa8\xe0\x45\xf8\xf9\x5f\x0b\x9e\xe1\xee\x3c\x2d\xe3\x95\x20\x23\xd2\x53\x8a\xe1\xa4\x9c\xc1\xe0\x4a\x1d\x24\x96\x6b\x31\xcb\x50\x21\xae\x1a\x47\xdc\xa4\x26\x0c\xb3\xb8\x48\x45\xf3\xcc\xcf\xed\xae\x79\xa5\xa3\x35\x15\x4c\xbb\xc4\xf0\x0c\x38\x48\x79\xdc\x43\xf4\x1f\x22\x7c\x7b\x37\x40\x79\x52\x23\x90\x51\x3b\x16\x87\xc1\x12\xae\xfc\x40\xe1\xb4\x39\x16\xca\xd4\x76\x8f\x82\xf5\x9f\xa6\x49\x95\xaf\x7c\xd4\x8e\x59\x48\x43\x92\x7c\x1c\x92\x6c\xd9\x36\x41\xec\x23\xaa\x09\x6c\xc4\xc0\x74\xa6\x3b\xa8\x12\x1c\x12\xaa\x98\x40\x4f\xda\x23\x98\x35\x79\x29\x8a\x37\x59\x74\xcb\x93\x22\x9e\x91\x0b\x34\x5c\x6c\x9f\x18\xf7\x8a\x04\xb1\x99\xe1\xed\xd8\xfd\x13\x60\xca\xe3\xdf\xb6\x48\x10\xe1\xf4\x01\x99\x2c\x8e\xf0\x50\xbd\x76\x77\x01\x1f\x63\x9c\xcb\xc7\xdd\x54\xfd\x4f\x29\xa2\x15\x5a\x92\xa2\x39\x6f\x4f\xe9\x14\x54\xae\x42\x25\x30\x67\x63\xb9\x89\x71\x25\x72\x4e\xac\x0a\x21\x64\x86\x91\x01\xeb\x99\x7f\xbf\xab\x43\x00\x84\xe2\x8c\x4b\x79\xc6\x91\x01\x15\x91\x08\x74\x17\x2c\x72\xb5\x7e\x7d\x21\xb7\x2b\x56\x60\x5d\x7b\xc1\x49\x07\xe4\xc2\xe0\x93\xc9\x20\x4d\xf1\x3c\xa3\x47\x89\x38\x75\x05\x3c\x4f\xef\x50\x56\xad\x75\x3a\xe9\xd9\x08\xb8\xcb\x35\x19\xbd\xe1\x49\x1f\x31\x6a\x36\x0f\x54\x93\xf9\x85\x02\xda\xa4\x23\x98\x54\x58\xb1\x98\xe6\xa9\x2b\x26\x3e\x8f\x04\xe6\x66\xf7\x5e\x95\x10\x11\x46\x56\x32\x8f\x97\xb5\x15\xc7\x76\x9f\x85\x07\x9e\xf2\xad\x22\x99\x15\x0e\x5e\xc1\x91\xe7\x97\x98\xe6\x99\xe5\x45\x71\x12\xa2\x14\x8c\x6a\x8e\x27\x95\xbe\x77\x53\x8b\x87\x9e\xc9\xec\xa2\x24\xe0\x6d\x9a\xa7\x95\xdb\x0d\x95\xa4\x1c\x55\xb6\x7f\x7c\x7d\xba\x5f\x23\xf8\xd4\x08\x72\x75\xc7\x65\x88\xb1\xdb\x5d\xfb\xbc\x62\x14\xf4\x57\x52\x03\x02\x35\x30\x6a\x33\x9b\x15\x55\xca\x63\x01\x75\x4d\x30\x2a\x3f\x27\x80\xd1\xf7\x2a\x88\x88\x58\x0a\xb7\xe9\xc7\x77\x2d\x40\xd0\x8e\x43\xb9\x1d\xd3\xdf\x4e\x27\x28\x87\xe1\x75\x05\x3a\x34\x28\xd2\xea\x5b\xae\x51\xe6\x72\xf2\x54\xda\x13\x28\x0c\x63\x52\x4a\xaf\x5d\x47\x69\x4f\x52\xbf\x17\x12\xe9\xcc\x96\x4f\xf0\x11\x4a\xc7\x0c\x59\xf8\x54\xfa\x7e\x5b\x94\xb8\x00\xd7\x45\x0d\x2b\x78\x87\xac\x38\xb5\xde\xf8\x90\x94\x50\x81\x17\xc4\xbe\x81\x23\x9e\x8f\x48\x7b\x61\x2d\xc6\xd9\xe9\x06\x1e\xb5\x19\x29\xa8\x6a\x13\x26\x6e\x37\x44\x53\xf7\x72\x5b\x94\x90\xbe\xe6\xdd\x85\x85\x8f\x18\xa2\xd7\xf4\x1d\x6e\xd2\xb2\x3e\xdc\x9c\x51\x22\xc0\x1e\xf6\x35\xc5\xad\x64\x69\x43\x94\x0a\x7e\xb9\x5f\x41\x20\x02\xb4\x34\x8a\xd3\x20\x92\xec\x92\x4c\xbe\xdf\x97\x1e\xfb\xde\x80\xf3\xde\x56\x5e\x4c\x2b\xbf\x81\x84\x3e\xa2\x00\xd0\xd4\x78\xe7\x59\xaa\x5e\x9a\x0c\xac\x30\x83\x6b\x93\xc4\x04\xbd\x63\x59\x23\x93\xe8\x6d\xc6\xaf\x6c\xe3\x40\x84\x8f\xde\x69\x6b\x7c\xdd\x16\xe5\x3c\xc6\x14\xa8\xcf\x79\x37\x00\x37\xda\x8e\xd2\x4d\xd5\x15\xdb\x5d\x86\x46\xbb\x33\x01\x23\xae\xed\x2e\x76\x03\xaf\x4d\xbe\xa8\x07\xe2\x82\x0a\x42\x2a\x3d\x8b\x0c\xfb\x66\x22\x91\x7d\xb6\x79\x3c\xde\x20\xf2\x62\x69\x00\x73\x6f\x23\x75\xb6\xcd\x15\xcc\x2b\x44\x9c\xc7\x8e\xed\x3a\x47\xfb\x71\x59\x54\x75\x85\x05\x9b\xb6\x49\x42\x01\x23\x56\x5f\x0b\x95\x0d\x7c\x9a\xc9\x85\x92\x48\x61\xda\x00\x07\x45\x8f\xf1\x85\x44\x18\x76\x9c\x76\xa1\xe9\xca\xd2\x2e\x42\xbc\x90\x48\x2e\x8d\x43\xbe\xe4\x99\x4b\xfc\x00\x27\xa1\xc9\x6e\x61\xf8\xeb\x66\x1a\x59\x02\x4e\x18\x92\x33\x7c\x5f\x6f\x77\x13\x18\x3b\x48\x5f\x62\xde\xb8\x34\x16\xe4\x0a\x6a\x2e\x0f\xc7\xa9\x0c\x85\x02\x19\x2a\x24\x1e\xb7\xa8\xb2\xf4\xbf\x30\xdd\xff\x40\xf9\x09\xd2\x6a\x98\x42\x1d\x13\xc6\x7a\xd2\x4f\x39\x5c\x28\x63\x28\x50\xb1\xab\xbc\x91\x4e\x16\x7c\xdd\x9a\x92\xee\xb0\xd6\xc2\x30\x9c\x82\x5a\x58\xab\xf0\x94\x9d\xe7\xad\x32\x00\xe2\x05\x30\xa2\x40\x79\x01\x7d\xe5\x03\x00\x31\xd2\x34\xc6\x6f\x34\xb5\x14\xaf\xb0\x98\xbe\x2e\x10\x86\x01\xdf\x9c\x1f\x61\xdd\x5a\x54\x60\xd5\xf1\x86\x8b\xa0\x3f\xfd\x3c\x40\xb9\x36\x65\x5b\xbb\x43\x59\x7c\x4c\xae\xa9\x09\xc3\xc0\xa1\x5d\xcd\x0e\xbc\xcf\xc8\xfe\x6e\x84\xef\xff\xf7\xdf\x7e\x97\xd0\x1e\x65\xc8\xca\xb9\x8f\xf7\x65\x53\x55\x6f\xfc\xcc\xdb\x79\x5f\xbf\xb9\x80\x8a\xf6\xe2\x84\x79\xdd\xc7\xb9\x6f\x57\xce\x21\x20\x50\xb7\xab\x97\xdf\x85\x75\x71\xbd\xb8\x69\xce\x50\xea\x89\xb8\xa1\xd2\xbe\x47\x55\x6c\x9d\x53\x28\xf9\xc8\xaa\x77\x4d\x82\x90\xd8\x2d\x1f\xd3\x91\x1a\x33\x39\xd3\xeb\x30\x23\x80\x7b\x70\xd0\x5f\x3f\xb0\x58\x41\x4b\x26\xaa\xb4\x9f\x28\xe2\x96\x87\x66\x12\xae\xd0\x41\x10\x20\x5b\x87\xd9\x60\xb6\x3c\x7f\x6d\x8a\x61\x20\x5f\x07\x04\x90\xd3\xcc\x30\x8d\xa3\x1b\xbe\x3b\xa4\xd5\xf3\xa1\xe3\x6f\x57\x3a\x50\x12\xe9\xba\x9f\x94\xa5\x43\x76\x07\x08\x27\xf8\x74\x7b\x59\x64\xca\x09\x4c\xdb\x63\xd4\x27\xc8\x31\xba\x7c\x58\xee\xba\xdf\x02\x86\xc3\xe4\xae\xc8\x14\xe4\xb7\x19\x80\x1c\x2f\xfe\xb6\x5d\x14\x70\x5c\x7c\xef\xd3\x4c\xf0\xdc\xad\x15\x3a\x22\x01\x9a\xa7\xab\xa7\x87\xc5\xe6\x71\xbf\x5d\x3f\xaf\x5f\x16\xbb\x27\xe7\xc8\xe9\xd8\x8f\xbc\xc0\x71\xfb\xe4\x17\xe8\x73\x1d\x47\xc4\x10\x3d\xe1\xce\xb3\xc9\xdf\x8b\x54\xa6\xf9\xab\x33\x18\x66\x36\x1e\xcd\xa4\xf1\x8a\xd3\x6a\x99\x35\x83\x42\x6b\xcd\x80\x32\x6b\xd0\xf1\x0a\xa1\x08\x17\xbe\x8e\x4e\xfc\x18\xfd\x93\xfb\xf4\x08\xeb\x73\xe7\x98\xeb\x44\x85\xe6\xa3\x40\x5e\x97\xbc\x2b\x79\x75\x87\xb9\xef\xa3\xcb\xbc\x7f\x41\xe1\xc7\x55\x0f\x34\xd1\x3c\xf6\x11\x20\xd5\x7e\xad\x6a\x58\x89\xae\xb9\x62\xc8\x35\x77\x49\x57\xfd\xa9\x19\xa8\x85\x67\xf8\x03\x07\x1c\x99\x5b\x40\x3c\x6e\x6b\xc5\x06\x2b\xe0\xf5\x61\xf2\x5a\x22\x8a\x30\xde\xd0\x54\xbd\xee\xb6\x3b\xd4\x9a\x69\x48\xa4\x59\x1f\x78\x66\x52\xc3\xf5\xd7\xbe\x9e\x4b\xcb\x40\xe0\x3a\x5e\x94\xe9\x6b\xeb\xe0\x18\x3f\xda\x1d\x84\x20\xea\xc8\x9f\xdf\x8f\x7c\x3a\x63\x94\xc7\x70\x48\x6d\x96\x4f\x37\xf0\x9a\xe6\xd5\xa2\x7b\x7d\x45\x43\x9d\x74\x00\xb0\xaf\x90\x5d\x38\x37\x5a\xc5\x09\x82\xb7\x2d\xc1\x3d\xa8\xfb\x34\x7f\x1b\xe5\xec\xb4\x92\xc2\xb1\x4f\x5b\x7b\xd8\x8c\x23\xcb\x4b\x35\x34\x1b\xed\x19\x3a\x94\x18\x67\x17\x4e\x24\x00\x3c\xcf\x37\x52\x2c\xc2\xb1\x13\xb8\x4c\xd2\x2d\xc0\x60\xf6\x80\xe7\xfb\x01\x6e\x05\xc7\x42\xbe\x4d\x06\x01\x78\x3e\x95\xda\xe9\xf0\x4f\x99\x5d\x87\xef\x05\x5e\xc0\x3c\x8c\x02\x8b\xa2\x78\x7b\x29\x8a\x0e\xa4\xe2\x4c\xa2\xff\xbb\x88\x22\x0c\x5f\x01\xbc\x20\xf1\xd0\x30\xd9\x93\x7d\x51\xa6\xad\x5f\xd4\x3b\x02\xe0\x91\x58\x9a\xb7\x69\xb2\xb7\x59\xf1\x6d\xf0\x88\xee\x38\xbb\x3b\x60\xee\x08\x97\x0b\x1e\xe5\x31\xda\x6f\x69\x75\xc7\x8f\xd0\x93\xdc\x80\x17\xf2\x10\x89\x42\xab\xe6\x04\x65\x6b\x41\x2d\x5e\x4b\x18\xbb\xcc\xe0\x45\x94\xe0\xb0\x5f\xbf\x3b\x5a\xfb\xd9\x0d\x11\xbc\x08\x62\xf4\xf7\x1e\x6f\x9f\xe6\xb0\xd2\xa3\x67\x8a\x3d\x1f\xcb\x71\xd0\x0a\x2c\x72\x40\x60\xde\xfa\x3f\x5b\x6c\x83\x08\xb2\xd1\xa5\x63\xea\x1b\x01\x32\x2c\xb2\xad\xd2\xc2\x68\x10\x4c\x20\x58\xe0\xc5\x51\x88\x01\x0e\xc8\x52\x4c\xde\xc1\xf4\x38\x18\x35\x5f\x97\x5a\x78\xe4\x47\xf8\xab\xdd\x6d\xe7\xc0\x45\xe0\x71\xcf\x90\x5f\xbd\x42\x6d\xc3\x92\x93\xe3\x91\xee\x85\x6b\x1a\x97\x74\x00\x8f\x4b\x86\xa9\x8e\xff\xe9\x2b\x47\xc1\xe3\x5a\x30\x1b\x82\xfe\xf3\xef\xe5\x50\xe8\x6b\x16\x1a\x01\x9e\x20\xa6\x7c\x0a\xe9\xa7\x52\x28\xbf\xa6\xaf\x87\xfe\xdb\x09\x69\x48\xcf\x65\x71\x3c\x35\x46\x06\xe5\x0e\x72\x6f\xb0\x65\x82\x27\x89\x36\x32\xa9\xed\xf7\xdd\xd7\xd3\x52\x89\x71\xdf\x48\x16\xa0\xdb\xf3\xb0\xf8\x6b\xf3\xf0\xed\x61\x7f\xff\xf4\xf4\xbc\xbf\xe9\x65\x60\xc0\x53\x24\x44\xfc\xe2\xa1\x7d\x90\x8e\xb0\xd2\x14\xe7\x76\x98\x74\xf0\x54\x42\x51\x7a\x66\x79\x16\x50\x3e\xf3\xf3\x68\xde\x29\xa1\x30\xde\x67\xcc\x91\x5d\xb1\x85\x5c\xdd\x96\xc5\xd1\x6d\x60\xe3\xb1\x07\x41\xa4\xf8\x90\x60\x14\xc5\x8b\x86\x21\x62\xf0\x80\x72\x44\x42\xdd\x6f\x16\x8f\x77\x9f\x0e\x3a\x88\x89\x85\xdd\xfc\xac\xf7\x25\xe6\x91\x4f\xc3\xdc\x2d\x78\xba\x9d\x12\x7d\xc5\x1a\x16\x3b\x2c\xf9\x29\xad\x27\x1e\x05\x78\xda\xd7\x26\x2b\xd6\x71\x62\x2e\xba\x3a\xa2\x4e\xbd\x0e\x3c\x1d\x86\xb8\x3e\x98\x4a\x1d\xc3\xd9\x3a\x3f\x7b\x34\x48\xcc\x31\x2c\x4a\x91\xd6\xfd\x5e\x0e\xbe\xc7\x8c\xdb\xf0\x0a\xb5\xc9\xe0\x3e\xf0\x37\x28\x07\x6b\x37\xf8\x1e\x24\x18\xa6\xff\xce\x9b\x6c\x32\x46\x7d\x4f\x9b\x5d\xeb\xaf\xc0\xb5\xf6\xa9\x64\x2e\x6d\x80\x9b\x84\xd6\x69\x96\x5e\xab\x8e\x01\xdf\x8f\x02\x3a\x8a\xd3\xcf\xf2\x4f\x82\x4f\x22\x61\x68\x3a\xfa\xca\x5a\x77\x24\x26\x91\x45\x43\xdc\x14\x65\x59\x7c\x5c\x40\xb9\xc1\x27\x5c\x87\xae\xc8\xc1\xe1\x1d\x87\x3e\x33\xf8\x44\x74\xe2\x3f\x3d\x05\xff\xb0\x88\x12\x7c\x1a\x46\xb8\x60\x1e\xf9\x4f\x1b\xeb\x0a\x86\xa3\xcf\xa7\x89\x40\x0e\xc5\x97\x9b\x97\xf1\xef\xdc\x50\x37\x19\xd0\x94\x9b\x87\xe3\x8e\xa4\xda\x80\x07\x4a\xe0\xea\xbc\x2b\x44\x09\x03\x0d\xcb\x91\x88\x50\x67\xf6\x82\x1f\x12\x85\xe1\x37\xf3\xe5\xb0\x68\xeb\xb7\x6c\x03\xf0\xc3\x30\x42\x0c\x0a\xc6\x57\x2d\xeb\x9e\x7b\xdc\x30\x0a\xa5\x25\x6a\x5b\x66\x3c\x3d\x56\xa3\x05\xdf\x0f\x95\xfd\xc0\xe9\x7f\xe1\x49\xbb\x93\xa2\xc4\xc7\xcf\x33\x80\x38\x5f\xc0\xab\x46\x97\x61\xca\xf7\xa1\x67\xdd\xc2\x68\xed\xfc\x36\xe8\x33\xe0\xc4\x30\xcf\x14\x4e\xf7\x0c\xfc\x44\x70\x8c\x35\x3c\x3c\xdd\x6c\xee\x37\x8f\x7f\x76\xbf\xeb\xd8\x90\x5c\xf2\x37\xb0\x8c\xad\xd7\xca\xd4\x27\xb7\xe1\x5e\x80\x78\xaf\xb6\x83\x9f\xca\x17\x78\x87\xb2\xfe\x72\x21\xf4\xd5\xb6\x23\x88\xa9\xe9\x40\x9a\x2e\x7f\xc0\xb3\x19\x6a\x6d\xf0\x79\x02\x44\x4f\x90\x87\x8b\x12\xf8\xb4\x99\x64\x98\x03\x6e\x37\x16\xf9\x8b\x1d\xce\xe7\xed\xca\xd4\x0e\x35\x5e\x83\xa9\x4b\x18\xa5\x49\xc0\xe7\x3a\x74\x2c\x60\x5b\x59\x4c\x24\xd9\xc0\x17\x24\xc1\xec\xd8\x78\x0e\x48\xcf\x47\x54\x1d\x94\x65\x51\xee\x52\xf9\x06\x25\x56\x2d\xac\xdb\x7f\xcf\x6e\x62\xbe\x0c\x14\x8d\x7a\xb9\xd2\xf3\xf7\xad\x0d\x3a\xfd\x46\x35\x15\xf8\x32\xa2\x89\x3f\x20\xea\xbb\x81\xba\x36\x82\x1f\x68\xa3\x5e\x1d\x11\x92\x33\x5c\x49\x9f\x4a\x2e\xfb\x48\x3a\xf8\x52\xa9\x40\x75\x32\xb1\xb9\xe2\xa5\xc2\x48\x7d\x3e\x75\xfe\xc1\x97\x5a\x25\x1d\x4c\xab\x75\xc1\x66\xf7\x2d\x5f\x05\x20\x8d\x79\x83\xdd\xdc\x53\xd5\x83\xaf\x18\x43\x7d\x00\xae\xd4\x0e\xf2\x99\xb5\x77\x36\xbc\x0d\xbe\xe2\x11\x2e\xb9\x46\x49\x36\x3d\x42\xd1\x74\x5f\x00\x7c\xe5\xe9\x5e\x51\xa3\x2b\x45\xbc\xd2\x0f\x40\x12\xdf\x6c\xd3\x25\x0c\x01\xf8\xe0\x43\x18\x61\xc5\xcf\x2e\xfd\xe9\x7e\xd2\x91\x42\x60\xd7\x6a\x73\xb7\x1c\xc0\xb8\x3b\x63\xd2\x35\xe3\x01\xba\x36\xb2\xc8\x6b\x9e\xe6\x0f\x69\x8e\xeb\x61\xbb\x8d\x3e\x61\x11\xc1\x5c\xc6\x06\x7c\xad\x88\xdf\x33\xf2\x77\xa1\x2f\x5b\xc2\x7c\xf5\x76\x81\x07\x02\x93\x83\x65\xfb\xc1\x93\x68\xfc\x95\x02\x9f\xf8\x48\x8e\xf6\x0f\x16\x5a\x38\xbc\x30\x04\x7e\x94\x20\xa9\xc7\x0b\x4a\x46\xad\xeb\xc3\xae\xc0\xb0\xe8\xa1\xd3\xd7\x81\xc0\x8f\x4d\xa8\xba\x82\xfa\x76\x8a\x9f\x80\xc0\x4f\x88\x23\xdc\x76\x16\x12\x3a\x01\xc3\x69\x16\xf8\x3c\x42\x88\xed\x62\xb5\xda\xef\x36\xeb\x97\xed\x78\xd5\x0e\x7c\xc9\xd0\xea\xc2\xa4\xe3\xd6\x86\xb5\xf7\x8b\x87\x5e\xb5\x1c\x02\x5f\xc7\x8c\xba\x1b\xbd\x43\xb9\x39\x5e\x63\xc3\x6f\xdb\x4a\x2c\x28\xdd\x36\xaf\xaf\x30\x2e\xb2\x82\x20\x60\x11\x92\x05\x94\x2a\x7d\x9f\xdf\x4c\x83\x40\x19\x1a\x73\xcb\xca\x58\x1c\xdb\x99\xb8\x51\xd5\xcd\x79\x31\x31\x66\x03\xe2\x33\x44\x86\xb4\x9b\xf4\xf1\x36\xcd\x79\x2e\x5d\x65\xa5\xc3\xde\x5f\x1b\xce\xf3\xcf\x4e\xa8\x54\xd4\x65\xfc\x2f\x01\xeb\x10\x90\xd0\x13\x1c\xfd\xd8\x53\xfb\x29\xb7\xbd\x56\xb3\x6b\x90\x44\x48\xdb\xb9\x3d\x35\x75\x9e\xbe\x5d\x46\x56\x20\xa0\xa1\x8f\x70\x91\xfb\x34\x4b\x5d\xba\x1d\x02\x2a\xc3\x40\x0e\x0c\xef\xcf\xa0\x4d\xdd\x29\xcc\xb7\x6a\x34\xd2\xac\xda\x17\x38\xfb\xe1\xde\x1f\x84\x51\xa0\x1c\x0f\x98\xc1\xc4\x8e\xed\xe9\x20\x14\x46\x9c\x9e\x2b\x65\x90\x04\x93\x27\x8f\x48\x82\xc4\x2d\x7d\x40\xef\x06\xd9\xce\xae\x8c\x84\x48\x0b\x6a\x91\x45\x69\x73\x1c\xcd\xed\x20\x26\x01\x55\xbd\x56\xc3\x9f\x7f\x2f\x27\xf7\x8a\x29\x20\x6a\xfe\xd4\x64\xd9\xb0\xb6\x03\x82\x38\x14\x18\x4b\xe0\x65\xfd\x51\x94\x6f\x5b\x17\x1a\xea\x8e\x03\x51\xfd\xfa\xb3\x2c\xf2\xaa\x39\x4e\xdc\x6d\x08\x18\x21\x58\x11\x5f\xf2\x5c\x15\xc7\x4b\x43\x29\x60\xcc\x30\x66\x9a\xb2\xc7\xb3\x09\x85\xfe\xac\x4b\x7e\xb9\x0e\xb8\x33\x84\x61\xbc\x70\xd2\x60\xd6\x47\x1f\xd7\xb2\x7c\x96\x2c\x83\x20\xf1\x23\xf0\xfb\xa8\x6f\x3b\xb4\xd2\xfc\xd5\x12\xb4\x4e\x86\x62\xc2\x28\xe6\xc0\xcc\xed\x1c\x75\xce\xb5\xfb\x8c\x4f\x55\xda\x6a\xf5\xbb\xa2\x2a\x7b\x80\x7b\x06\x1f\xa4\x20\xe3\xe7\x27\xdd\x97\x2f\x43\xc0\x83\xd8\x59\x00\x5d\xc2\x07\x93\x8f\x98\x86\x1c\x96\x6a\x42\xc0\x93\x00\xcb\xfd\x4b\x3f\x1c\x81\xcd\x20\x10\x71\xe8\x8a\x32\x06\x99\x05\x03\x87\xdb\x9d\x4f\x30\x15\x1f\x80\x40\x6a\x70\xdc\x60\x43\x21\x66\x36\xe9\x39\xe5\x73\x44\xd4\x98\xba\xa3\x79\xea\x45\x08\x54\x10\xcb\x4e\x00\xfd\x1b\xf2\x7a\x0c\xe4\xec\x21\x50\x32\x31\x61\xaa\xcd\xfa\x65\x4f\xf6\x37\xdf\xfe\xde\x3c\xf6\xc7\x20\x42\x00\x43\xc6\xbb\x51\xac\x74\x82\x80\x47\x67\x3d\x5d\x20\x23\x46\xcf\x08\xd4\x33\xdd\x82\x03\xd3\x40\xb8\x50\xcb\xa3\x3c\x5a\x14\xed\xf8\x69\x81\x4a\xb0\xa5\xc9\xe9\xb1\x39\xde\x17\xf2\xed\x6f\xe0\x7d\x67\x82\x00\xcc\xc6\xdf\x41\xfd\x5c\x14\x59\xeb\x32\xd8\x2b\x4d\x2e\xa4\x3d\x8e\xbb\xc8\x07\xa4\x36\x8f\xe6\x2e\xa1\x43\xed\x68\x13\x10\x68\xd1\xfd\xce\x8c\xa8\x07\xea\xba\xdd\xfe\x8e\xaa\x1b\x04\x3a\xa1\xdc\x31\xb9\x17\x79\x35\x74\x1f\x88\x17\x51\x1c\x3d\xe6\x4b\x9b\xd8\xf4\x7c\x2e\x0f\x88\x27\x15\x8f\x07\x06\x15\x7e\xa1\xc5\x3b\x4f\xb3\x81\xe5\x42\xfc\x88\x8b\xbe\x33\x11\xc4\x3e\x99\xe3\x24\xe0\x86\x1b\x19\x01\x2c\xe8\x5e\x4c\x18\x2e\x27\x37\x26\x91\xf1\x58\x5b\xcb\x0b\x40\x55\xdb\x34\x97\x70\xcf\xab\xfa\xeb\xb0\x6a\xcc\x35\x06\x9f\x59\xb3\x6f\x7f\x2c\x54\x93\x15\xfb\x77\xf4\xb9\x86\x36\x63\xf7\xc7\x9e\x44\x99\x49\x2e\xae\x20\xbb\x4b\xf5\x78\x6f\x24\x54\x69\xc4\x1a\x14\x27\xc8\xd1\x70\x75\x2b\x1a\x09\xfd\x08\x59\xc3\xdc\xba\x6b\xd0\x75\xd7\x16\x22\x12\xb2\x04\xd7\xf9\xd5\x62\x73\xff\xf7\xfe\xf6\xdb\xe3\x6a\xbb\x7f\x59\xdf\xaf\xfb\x50\x0b\x89\x22\x89\xa9\xa9\xa2\xc1\x82\xa4\x7f\x71\xf9\x76\x2a\x5c\x58\xda\xb6\x61\x9e\x91\xeb\xe2\x4a\x39\x76\x9c\x6b\x18\x48\x20\x8c\xc5\x31\x75\xc1\x51\x33\x5a\x8a\x72\x73\x3c\x65\x93\x6e\x63\x89\x67\x28\x18\xf2\x77\x74\xc5\xc7\x57\x49\x84\x09\xa1\x3b\x2e\xf5\xbd\xef\x1e\x86\x7b\x14\x07\x85\x32\x90\x78\xc9\xab\xc3\x68\x80\xf1\x80\x28\xcb\xaa\x01\xed\x7a\x3d\xe9\x1c\xf6\xbf\xff\xe7\xcc\xf6\xe1\xff\xb9\x93\x93\x04\x13\xff\x86\x47\xdf\x20\x0d\x47\x98\x75\x20\x5c\x44\xbe\x72\x28\x91\xa1\x65\x61\x8f\x8b\xd8\xc3\x54\xf9\xb1\xc8\xeb\x03\x65\x93\x82\x09\x20\x42\x1a\x9d\x01\x14\x10\xbe\x5f\x74\x21\x23\x22\x80\x20\x39\xcf\x0e\x39\x5a\x1d\xc2\xa4\x43\x59\xdc\x16\x33\x75\xbf\x40\x24\xf3\x30\x5e\x70\x53\xd4\xa7\xf3\xaf\x12\xd4\x40\x64\x62\x38\x45\x4e\x56\x7a\xbb\xaa\x9a\x2b\xe6\x1b\x51\x41\x80\x59\x0a\x0d\x70\x9b\xfe\xec\x5f\x40\x09\x53\x44\x8a\x1d\xf0\xe8\xb4\x04\x80\x40\xc2\x31\xe4\x85\xe1\x96\x07\x43\x05\x3f\xb1\x53\x89\x8e\x09\x2e\xce\xbb\x03\x20\x8f\x82\xfb\x59\x31\xe7\xa4\x6f\x8b\x2c\x9d\x58\x77\xd4\x8b\x85\xb2\xaa\x98\x36\xda\xf1\xc0\x8d\xc9\x65\x2f\x40\x7d\x1a\x7a\xb6\xd8\x0a\xbd\xfc\x34\x7f\x35\x14\x6c\xe3\x0b\xf9\xb1\x67\xb5\xbb\xf1\xa1\xc2\xee\x74\x69\xf4\x72\xb9\x52\x5f\xd3\xaa\x1e\x14\xd1\x8d\x59\xa8\x6c\xf3\xc0\xd3\x8e\xac\x0d\xf7\xf4\x17\xa8\xda\x11\x3c\x88\x67\x5b\xea\xba\xee\x84\x04\xa4\xe1\xa2\x2d\xde\x53\x85\xb5\xd5\x4d\xf7\xec\x24\x0c\xd1\xd4\xc4\x04\xbf\x29\x93\x4a\xa7\x01\x23\x4a\x98\x67\x65\x9a\x50\xad\x77\x7a\x10\x60\xa8\xb8\xb7\x03\x3e\x2c\x15\x06\x4a\x54\x17\x17\xfb\x56\x01\x8a\x80\xdc\xa4\xf5\x91\x57\x6f\x93\x2b\xd1\x44\xea\x64\x30\xed\x46\xf6\x16\x8d\x68\x82\x43\xfb\xbe\xe8\xeb\x41\x46\x22\x76\x63\xc6\x3e\xa0\x51\x64\x12\xce\x23\x82\xe5\xa0\xbb\x1c\x0b\x10\x2f\x70\xca\x40\xa1\x42\xed\xe4\x6b\xc5\x24\x46\xe3\xe4\xbd\xc8\x9a\x23\xf2\x58\xd1\x2f\xdd\xa1\x04\x61\x5e\xfb\x12\x74\x93\x55\x87\x5b\x04\xad\x5c\xe8\xab\x03\x8d\x23\x70\xd2\xfa\x35\xe4\xa3\x65\x96\xc6\x89\x92\x4e\x76\xff\x50\x9c\xa6\x67\xca\x00\x61\x8a\xf0\x5e\x64\xef\x70\x73\x5e\xd4\xd6\x3a\x1c\x3c\xa0\x8c\x23\xc3\x85\xd3\xe1\x0c\x6d\x0f\xf4\x6d\x92\x48\x21\x6e\xe0\xfb\x66\xb9\x36\xe4\xf5\x9b\xe5\xd3\x7e\xb3\xdd\xdf\x2e\xfe\x74\x8b\x30\x4d\x18\xd1\xd6\xb9\xdb\x62\x4a\xd7\xa0\x9f\x27\xb7\xe3\x14\x0c\x67\x31\xc8\xc3\xf7\xa2\x86\xc7\xe6\x78\x5b\x94\xbf\x25\x4d\x06\x94\x83\xc2\x7d\xf7\x8c\x82\xc2\x66\x19\x9f\x0a\x85\x00\x15\x9e\xc0\xb0\x2f\x37\x5e\x41\x30\x76\x0b\xa8\xf0\x3d\xc4\x29\x60\xa0\x6d\xbd\xfb\x3a\x00\x11\x01\x15\x8c\x38\xad\x88\x75\x55\xff\x09\x67\x04\x7f\x3c\x4e\xdf\x42\x12\x8e\xc6\xc1\x53\xd9\x6e\xfd\x4e\xbf\x1a\x96\x07\xde\x39\xc4\x54\x85\x09\xc6\xdf\x9e\xbf\x2e\xb6\x6b\xdf\xd4\x57\x0f\x40\x11\x40\x15\x08\x84\xee\x6c\xbf\x6e\x9c\x6b\x4a\xc1\xf3\xd0\x8b\x4e\xab\x8d\x2c\x6e\xd3\xbc\x3a\x74\x6b\x16\x6d\xbf\x95\x70\xe6\x1e\xf6\x6d\xe2\x29\x7e\xee\x5e\x0c\x42\x85\xb6\xe5\x5e\xa4\x6a\xfd\xb2\x0c\xbc\xdf\x33\xd3\x43\xcf\xa3\x88\xdf\xdd\xb7\x9e\x17\xe6\xa2\xab\x67\xde\x97\x49\x41\xe8\xf9\x0c\x49\x67\x3a\x5d\xf3\x59\xde\x79\x08\xfd\xd0\x04\xfa\xc0\x70\x55\x1a\x8a\x48\x77\x4c\x7a\x9e\x93\xfd\xe4\x46\x95\x6c\xea\x8e\x86\x41\x90\x08\x6f\xc0\xf0\xf8\x65\x66\xdd\x0a\x83\x88\xa0\x46\xbb\xb2\x42\x31\x2e\x76\xfc\x0c\xa5\x65\x61\xb5\x0d\x49\x18\x81\xb4\x29\x27\x5c\xe1\xaa\xee\x48\xa4\xb1\xc6\xa2\xe4\x75\xaa\xcf\x0f\x43\xfe\x82\xd9\x71\x17\x92\x38\x42\x6e\xe6\xf7\xde\x5c\x0d\x09\xe7\x68\x4f\xc8\x22\xcf\x41\x5e\xd4\x72\x43\x48\x84\x61\x7f\x38\x95\x85\x6a\x24\xa8\x55\xca\x8f\x45\xde\xae\x1f\xdd\x35\xa8\xef\x23\xdc\x05\x95\xe8\xa6\x88\x1a\x08\x69\xa0\x2d\x8d\xa2\x6e\x72\x65\x10\xdf\xd3\xbb\x50\x62\x18\xbe\xda\x59\xc7\xf3\x9a\x2f\x33\xde\x5c\xb4\xe1\x8c\x59\xa0\xa5\xe1\x87\x68\x77\x9d\xd5\x45\xb6\x2c\xa4\x82\xc5\xc1\xc0\x69\x47\x44\xcd\x8c\x00\x19\x84\x54\xf9\xda\xec\x05\x4d\x0e\x98\xa3\x39\x14\x59\xbb\xd6\xce\x4f\xdc\x30\xa4\xc2\xf0\x69\x0d\xc5\x81\x67\x89\xf8\x46\xdf\x3a\x62\x89\x70\xe4\x40\xa9\x42\x62\xb3\xf9\xeb\x47\x3a\x34\xfa\x1f\x0d\x2f\x15\x2f\x57\x85\x6c\x8e\x90\xd7\xc5\x24\x42\x3a\x8e\x75\x86\x8c\x44\x89\x1e\x08\x37\x0f\x68\x36\xba\x16\xca\x60\x28\xd6\x8f\xde\x2c\x43\x02\x84\x2c\xe6\x4e\x5d\x6d\x6f\x0b\xff\xf7\xbc\x14\x69\x5d\xed\x4f\x50\xee\xe1\x2a\xcb\x07\x84\x4c\x79\xae\xa0\xb2\xaf\x7b\xbd\xe3\x35\x7c\xf0\xf3\xe4\x41\x92\x18\xd0\x08\x7e\x2e\x07\x88\xa8\x59\xc7\x25\xe4\x91\x44\xe0\xc5\x09\xc0\xa5\xc9\x43\xce\x39\x56\x6c\xa5\x79\x5a\x6f\x64\xf1\xd2\x74\x56\x47\xc8\xb9\xd6\x8e\x2f\x07\xb2\x2c\xcd\x5f\x37\x35\x1c\x6f\xce\x4f\xe2\xdf\x1b\x35\xac\x89\x82\x50\x7a\x26\x41\x70\x30\xdc\xe4\x93\x47\x94\x11\x47\x4c\xfa\xbe\xdb\xc1\x8b\x69\x0b\x10\x34\x1e\x06\x85\xa6\xa8\xd0\xe1\xce\x16\x2a\x2f\x31\xd5\xc1\x85\x82\x53\x91\x22\x13\xc7\x64\xc0\x2a\x2a\x30\xee\xef\x36\x93\xd6\xa2\x6a\xf7\xcf\xdb\x02\xb3\xdb\xd3\xaf\x09\x24\xc2\x10\xfb\x6e\xf9\xf5\x97\x65\x4d\x10\x02\x35\x99\x4b\x03\x60\x59\xe4\x6a\x6d\x92\x84\x33\x0c\xb1\xc3\x20\xea\xe4\x1b\x6b\x19\x63\x99\x3d\x57\xaa\x9d\x4e\xc3\x02\x42\xeb\x4e\x75\xdd\xab\x15\x57\xb4\x67\x12\xeb\x0c\xa0\xb1\xe2\x03\x84\x5a\x0b\x4c\xbe\x1c\x78\x75\x70\x54\x2e\x23\xf7\xcc\xfd\x99\xb1\x9d\x23\x4f\x01\xb2\xbe\x96\x69\xfe\x06\xe2\x6c\xc9\x18\x20\x0a\x3c\xa3\xcb\x66\x4a\x23\x3a\x8d\x16\x88\x02\xad\xc0\xa6\xb1\x17\xb5\xa5\x92\x6a\xcd\x98\xcd\x6a\xfc\x31\x22\x4a\x22\x04\x2e\x19\x72\x83\x4b\x32\x59\x88\x68\xcc\x70\x0f\xe8\x39\xa9\xfe\x5f\x6b\x4f\xff\x98\xdc\x52\x6b\xcf\x42\xf2\x14\x98\xc4\xc9\x27\xca\x6d\x10\x85\x21\x45\x14\x18\x57\xed\x7e\xd0\x94\xd0\x0e\xf5\x71\xed\x31\x44\x61\xbb\x8f\xa2\x60\xcf\xcd\x76\x26\xe0\x19\x45\x81\xd4\xde\xa5\xde\x74\xd4\x1d\xd6\x68\x7d\x16\x4a\xb5\xbb\x8e\x0d\xef\x4c\x2e\x11\x01\x06\x66\x9a\x0a\x4a\x5b\x97\x31\x6e\x10\x4b\xed\x62\x21\x3f\xf8\x2b\x94\xa0\x7e\x40\x3a\x8e\x74\x47\xb1\xa6\x08\x45\x77\xda\xc0\xbd\xe4\xdc\xfc\xc2\x10\x31\xca\xd0\x80\x3f\xf2\xaa\x7a\x2c\xea\x01\x90\xdf\xb9\x8e\x11\x8b\x7c\x03\xda\x32\x9c\xe1\xad\x85\xb4\x30\xac\xf8\x93\x8f\xcd\xe2\x10\xd5\x1f\xda\x4d\x49\xf2\xec\x11\x30\x78\x39\x79\x0b\x26\x03\xec\x29\x8d\xd8\xf3\xe7\x0b\x24\x3e\x44\x49\xcc\x50\x90\xed\x66\xb9\x73\x26\x50\x94\x30\x8a\x66\x4c\xa7\x01\x65\xcc\xf8\x4f\x3f\x6c\xc2\x12\x13\x12\x72\x62\xd2\xbb\xc7\xee\x72\xca\x8f\x84\x35\x03\x76\xc5\x36\x4b\x25\xdc\x10\x67\xbe\x47\x1c\x08\x2e\x09\x22\x55\x5f\x66\xeb\x6d\x6d\x3b\xe1\x71\x9b\x59\x3a\xf6\x0c\xc2\x5b\xa8\xeb\x34\x7f\xad\xdc\xec\x9b\x7f\x36\x11\x32\xc4\xbe\x5a\xb6\x50\xfe\xd3\x6d\xf4\xec\x7f\xfd\x30\x76\x3d\x2f\x24\xc1\x2f\xfe\xf4\x36\xc2\x2d\x45\xd2\xa3\x18\x09\x48\x65\xd1\x91\x5d\xfb\xdd\xc1\x50\x27\xfd\xa5\x5b\x3b\x77\xf2\x05\x24\x10\x9c\x71\x66\x0d\x7b\x84\x8f\x49\xff\x2b\x5f\x81\x35\x77\xef\x51\x94\x74\x44\x0d\x05\x91\x22\x1c\xcd\xe1\xa3\x61\x21\x1c\x54\xcf\x40\xa4\xb4\x54\x03\xb6\x9e\x4f\x53\x11\x11\xf8\x82\x58\xfd\xb1\x6d\x23\xfe\x0d\x72\x02\x5b\x88\x80\x6a\x6c\xd0\x9a\xdb\x26\x58\x61\x10\x0f\xe3\xf7\xd1\x81\xaf\x5d\xa8\x17\xc9\x8f\x60\x26\x91\xd5\xb5\x35\xa0\xae\x57\x7e\x84\x6e\x4f\xb2\x0f\x1f\x7b\x2c\xf0\x0c\x20\xb9\xf5\x21\x1c\xa7\x86\x3b\xc8\x85\x6f\xd7\xec\xb5\xcd\x40\xec\x8a\x9b\xe6\x92\xd9\x72\x74\xc3\xd8\xd3\xa6\x1e\x29\x3d\x1e\x0d\x73\xb0\xad\x12\xb6\x87\x7d\xc2\xb1\x4c\xb6\xb5\x12\x10\xfe\xc4\x6b\x30\xe0\x11\xa7\x0d\x38\x3f\xb8\x63\x9f\x9a\x18\x46\x89\x99\xb5\x61\xe9\x55\xb5\x2b\x76\x07\xb0\x18\x3b\x67\x55\xc6\x01\x61\xda\x77\xa2\x71\xe5\x91\x67\x2f\x45\x71\x7c\xe0\x3f\xc7\xdf\x3e\xa6\x3e\x27\x66\x61\xcf\xa1\xe4\x35\xb4\x3b\xe6\x16\x64\x09\xf5\x97\xb9\x29\x10\xd3\xd8\x93\x36\x93\x75\xdb\x64\xd9\x58\x05\xe4\x4a\x97\x84\xb1\x8f\xd9\x64\x6d\xeb\xab\x8c\x4b\x30\x93\x87\xa6\xdd\x09\x3c\x80\x5e\x54\x7f\x91\xab\xbb\x2e\x70\x18\xb3\xd0\xc3\x7c\xfc\xd2\x95\x72\x4d\x63\x23\x31\x8b\xa5\x34\xa4\xf9\xa0\xd2\xe9\x18\x8b\x93\x20\x24\x51\x17\x64\xbd\xcb\x0a\x81\x95\x6c\xad\xe9\xd7\x23\xd0\xba\x01\x3c\x97\x53\x8d\x13\xc2\x8c\x53\xd1\x33\xf8\xdc\x5a\xb2\x3a\xf7\x94\x49\x12\x39\x02\xc2\x9b\xa2\xc8\x6e\x53\xc8\x94\xdb\x66\x63\x1e\x28\x6a\x20\xae\x9b\x1c\x89\x69\x2e\xa4\xaf\x20\xe6\x49\x84\x5b\xf4\x7e\xc8\xdd\xd8\xe4\xf5\xf9\x12\xbd\x0b\xb1\x08\x13\x0c\x46\x7d\xe5\x99\x4b\xb3\xc6\x82\x01\xd6\xc1\x6e\x33\x48\x4f\x79\x5a\x76\xbf\x27\x1a\xe3\x91\x07\x5e\x21\x92\xfa\xbe\xa8\x6b\x28\x4d\x32\xe8\xc7\x34\xcc\x1e\x0b\xc5\x8d\xfe\xb8\x72\xc4\xb3\xed\xb3\xb6\x3b\xe6\x97\xa1\xbe\xc6\x85\x73\x39\xbe\x8a\xf4\x34\xf3\xba\x92\xb3\x65\x71\x3a\x63\x76\x4b\x15\x1f\x5d\x87\x49\xdf\xe8\xef\x38\x98\xea\x70\xfd\x8b\x65\xa8\x02\x31\x2a\x1f\x59\x1f\x4f\xf5\x79\xfd\x1f\xfc\x13\x84\x51\xd7\x10\x12\x84\xf4\x20\x5c\x7c\x2f\xda\x77\x1a\x98\x31\xb1\xa2\x09\xae\x84\x8e\x36\x60\x50\xbc\x0b\x31\x08\x89\xd8\x8d\x63\x9a\xb7\xce\xb3\xfb\x59\x07\x46\xd0\x71\x85\xb2\xe2\x15\x5c\x16\x8b\x8d\xbf\x85\x8e\xc3\xa8\x83\xf0\xe0\xd7\xfd\x96\x77\x70\x5c\x60\x9e\xaf\xf0\xbb\xd6\x26\x1a\x3e\x8c\x83\x8e\x2f\xc4\x3c\xc5\x10\xe8\x6a\x38\x02\xb6\x8b\x7b\xe7\x6d\x30\x3f\x32\xb4\x20\x27\x7e\xbe\x2d\xca\xbf\x8b\xa6\xbc\xcb\x78\xbb\xd8\x4c\xc0\xec\xc0\x88\x67\x6c\x8c\x0a\xea\x75\xfe\x9a\xe6\x13\x63\x8c\x91\x90\xe2\x3d\xcc\x20\x7e\x7a\xba\x9b\x7f\x29\x46\xb8\x46\x33\xc3\xa6\x36\x27\xca\x20\x57\xce\x51\x09\x7e\x34\x83\xb6\x7b\x6e\x9c\x16\x27\x30\xea\x05\x98\x7a\xbf\x7f\x58\x2d\xba\xdf\x98\xc4\x60\xf4\x23\x14\x37\xe9\x90\xa9\x09\x58\xe8\x05\xa6\xe2\xfd\xc2\x6f\xa4\x83\x22\x23\x60\x61\x14\x32\xe6\xb0\x35\xa6\xa9\xda\xa5\x47\x30\xfa\xf2\x53\xba\x24\x60\x21\x13\x2e\x1d\x7a\x53\xa6\xea\xd5\x2d\xc8\x45\x59\x5d\x8a\x86\x01\x8b\x62\x0f\x35\x6a\x2d\x10\x72\x88\xb9\x64\x91\x88\x08\xd8\xb4\x35\x16\x31\x04\x33\x99\x76\x16\x81\x44\x7b\x49\x15\x36\x45\x66\xb0\xde\xf6\x68\xec\x31\xe4\x26\x2d\x91\xd0\xf0\x9f\xfb\x5d\x77\x80\x1a\xcc\xd0\x3f\x69\x2e\xd7\x99\xe1\xaa\xb5\x87\x58\x2c\x1d\x54\xb2\x75\x2c\x1e\x8a\x1c\x26\x4e\x23\x63\xd6\xeb\x73\xec\x5a\xeb\x52\x06\xde\xa8\x7f\x99\xa4\x9c\x0e\xe4\x8a\x1f\xda\x71\x32\x21\x1c\x19\x5f\x33\x21\x14\xc9\xa2\x9a\x32\x9d\xbc\x62\x42\x09\x12\xb6\x54\x08\x7a\x73\x67\x0f\xbf\x12\xa7\xdc\xc5\x2a\x5d\x5d\xd9\x73\x99\xe6\x32\x3d\x4d\xa8\x00\x81\x09\x62\x04\x10\x5b\xc3\x63\xc7\x9d\x1f\xcb\x84\xf6\xd0\xe0\xb7\xd2\xbd\x4f\x7a\x2a\xd4\x33\x7e\x24\xe9\x49\x8c\xb9\xef\x8f\x69\x0e\x5c\x64\x63\x44\x0e\x93\x3c\xc6\x15\xce\x59\x9a\xcb\xc6\xaa\x27\xa4\xaf\x87\xa9\x49\xce\x14\xf7\xfc\xc4\xb1\xc1\xa4\x33\xfa\x27\xc0\x14\xd0\xb8\x63\xc7\x34\xd5\xaf\x9f\xa2\xc9\x19\x68\x0f\x13\x68\xd5\xb9\xaa\xe1\xf8\x94\x4f\x93\xff\x4c\x7b\x1c\x19\x11\x65\x71\x3c\x16\xf9\x58\x43\x1c\x12\x5f\x1b\xbd\x16\xb3\x9f\xdd\x70\x35\xe3\xae\x24\x01\x31\x18\x23\x23\x6f\x32\x22\x1d\x75\x2d\xe2\x04\xf5\x07\xcd\x26\x33\x22\xb0\x86\x24\x48\x22\xb4\x85\x50\x85\x15\x31\xe9\xd3\xc8\x7d\x12\x80\x88\x94\xad\x2a\x7b\x38\xcf\x48\x5d\x41\x42\x28\x45\xd3\xc8\xd8\xa1\xcf\x65\x71\x2c\x26\xba\xd8\xf3\x8c\x54\xf6\x74\xea\x69\x0c\x1f\x2d\xd7\xf7\xf7\xfb\xc5\x6a\xb5\xdf\x3e\x2f\xba\x08\x4c\x42\x59\x84\x05\xe6\x8b\xf2\x5f\x45\x73\x85\x8e\x10\x12\xca\x8d\x02\xee\xa9\x2c\x0a\x3d\x9c\x04\x49\x08\x7e\xe0\x18\x5c\xb1\x38\x68\x88\x10\xb7\x6d\x22\x3f\x30\x6b\xb7\x1d\x2a\x63\xf2\xd6\xd9\xd1\x97\x44\x09\x61\xc6\xdf\xaa\xe5\x01\xdd\xbc\x34\x7f\xbd\x49\x55\xf5\xa5\x2f\x95\x74\x03\x3e\x89\x03\x43\xc7\x97\x56\xdb\x13\xff\xc8\xd3\xfc\x75\x61\x78\xc4\xe6\xc1\x5d\x49\x1c\x6a\x1c\x6b\xa6\x72\x1f\x25\x57\xd7\xb9\x5a\x4d\xc0\x87\x97\xdd\x10\x33\xc3\x8f\xb3\x78\x2d\x53\x0c\x57\xbb\x58\xd9\xc4\x0d\x4e\x62\xa9\x95\x2d\xf7\x93\x30\x0b\x64\x9e\x5e\x19\x08\x82\xa1\xde\xad\x6d\xbb\x68\xea\x03\xe4\x75\x2a\x7f\xad\xa4\x0f\x49\xac\x79\x6c\xb9\x31\xd7\xbc\xcc\xce\x9d\x0a\x7f\x5e\x57\x17\x0a\x89\xff\x6b\x8a\x4d\xe7\xa2\x2e\xce\x93\x4d\x98\x66\xbe\xc1\x9e\x18\xf9\xca\xdd\x54\x94\x13\x92\x24\xd4\x48\xe3\x22\x55\xf7\x4b\x6c\xc0\x5e\x9b\xe7\x87\x01\xb4\x2d\x49\x04\x61\x8e\x56\xa3\x48\xf3\x11\x5c\x98\xba\x36\x3a\xc4\x30\x09\x06\xe7\x47\x5a\x88\xb6\x01\x4f\x4c\xe5\x38\x6a\xbb\xd5\x4d\x09\x53\xe2\xc7\xf1\x78\xe0\x3c\x70\x84\x72\xf6\x7e\xed\x0c\xfc\x89\x27\xda\x26\x22\x0a\x5c\x55\xd4\xb6\x11\x55\xaa\xce\x93\x59\x27\x85\xc0\x52\x79\xe7\x5f\x18\xf1\xd8\xb9\xa8\x7a\x22\xa5\xc0\x82\xf0\x9b\x42\x14\x07\x67\x48\x26\xca\x0b\x1c\xbe\xa5\x0b\xb2\xff\xb9\x1e\x42\x0e\x5d\xc3\x30\xe2\xc1\x00\xe4\xb0\xee\xf6\xb6\x04\x42\x8a\xf5\xbf\x56\x79\xa0\x63\x18\x9e\xa2\x59\x12\x90\x80\x8b\xf5\x11\x6f\xb0\xc9\x71\x1c\x75\x57\xd1\x09\xfa\x40\xff\x2e\xd2\x7c\xff\x5e\xd4\xfd\x02\xa5\x3d\xe6\x47\x33\xa8\xc1\xf1\x03\xea\x44\x33\x43\x10\xf8\x90\xe6\x69\xeb\x13\x01\x97\x7d\x6e\x25\xd1\xc2\x03\x9b\x9e\x30\x71\xf6\x2b\xca\x55\xd7\xc9\x41\xba\x6c\x76\xa2\x95\x8f\x51\xc9\x2c\x95\x90\x57\x70\x01\xb7\x37\xcd\xb8\xe7\x31\x44\x27\xa1\xa9\x2a\x79\x76\xea\xbe\x2c\xf7\x68\x18\x05\x3d\x70\xea\xa5\x47\x75\xf5\xa7\xfb\x41\x88\x98\x96\xd7\xb4\xcc\x36\xca\x31\xad\x4d\xdb\x44\xb6\x50\x6b\x10\xd0\x9f\xc3\x7e\x73\x3f\xe6\xa6\xac\x88\x6b\xd8\x1f\x9b\x79\x66\x12\xe0\xbe\xa6\x98\x4f\x5c\x7d\x5f\x0e\x97\x50\x1e\x04\x31\x5a\xca\xad\x4f\xb6\x2b\xf9\x3b\x64\xf7\x3c\xef\x5e\x87\xf8\x31\xb2\x8c\x6c\xbf\x3d\x2e\x9f\x3a\x08\x12\x27\xb1\x8c\x4c\xbc\xf3\x54\x54\x13\x4f\x8e\x53\x3f\x40\xc0\xdc\x7e\xb6\xdc\x0f\x38\x4d\x0c\x0d\xa5\x09\x7d\xcc\x65\x94\x79\xe8\xfb\x98\x7a\x55\xd6\x7c\x37\xa0\x19\xcb\xc6\xbe\x45\x19\xe8\x76\xe1\xbb\x05\xd8\xe4\x8b\xba\x2e\xa0\x3e\x3c\xe3\xca\x3e\xb9\x55\x08\x0a\xa9\xa8\x4f\xfc\xbc\x2b\x14\x3f\x8f\x55\x58\x26\x3d\x14\x45\x01\x36\x3e\x14\x4d\xf9\x5c\xb8\xd5\x94\xc7\x84\x08\x9b\xa6\x39\x9e\x47\xef\x33\x39\x3f\xe6\xbe\xd3\xbb\x5c\x1f\x4f\x59\x71\xbe\xa2\xd4\x01\x3c\x96\x0c\xd1\x5f\x3c\x2d\x57\x06\xea\x7d\xad\x21\x18\x35\xae\xd6\x85\x72\x86\xde\x22\x57\xa6\x22\xa9\x9b\x02\x9c\xf9\x26\x6d\xee\x54\xb8\x8a\x37\x38\x16\x26\x1d\xed\x5a\x40\xc8\x3b\xe7\x17\x5f\x62\x93\x5b\xee\x41\x9e\xed\x5d\xab\x04\xa8\x36\xa6\xee\xc6\x5c\xe9\x05\x4e\x45\xef\xa9\xdb\xc5\xdb\x36\xe6\xd2\x47\x0c\xa6\x59\x5e\x16\x4a\x5d\xc3\x51\x71\xae\x14\xd6\x3f\xed\xb9\x52\x63\x06\x79\xd7\x40\x53\xc9\x86\x82\xb4\x53\x08\x06\xe7\xda\x3c\x3f\x37\x50\xc6\x3d\x82\x3f\xf6\x3d\xff\x10\x70\x41\x0c\xf3\x4a\xdb\x07\x16\xf0\xf8\x4b\x4d\x2e\x77\x2a\x0f\x22\x6b\x8f\x1b\x31\x8c\xba\xf7\x29\x46\x78\x42\x2e\x14\x17\x7d\x18\x02\x01\xf3\xe0\x76\x93\xff\xfd\xbf\x3f\x26\x31\x59\x2e\x40\x6b\x70\xb8\x2f\x53\x1b\x39\x8b\xa6\xb5\xcd\x65\xc4\x1d\x0b\xdd\x32\x4b\x21\xaf\x17\xf5\x48\x2d\xce\x35\x8b\xb9\x37\xae\x66\x5f\xe4\x45\xbb\xf0\x0e\xa3\x88\x17\xab\xdd\xf8\x4e\x60\x2a\x95\xdb\xa1\xfa\x9f\x26\x3d\x8d\x23\xb4\xae\x91\x8e\x30\x77\x7c\xf3\xe7\x78\xc5\x50\xc4\xa0\xf8\x4f\xfc\x0c\xa6\x12\xf6\x19\xca\xe7\x4e\x70\x10\xb8\xe2\x14\x93\x73\x95\xd5\xf9\x40\x13\xa4\xba\x39\x3f\xf3\xeb\x53\x02\x02\xbb\xca\xb7\x9f\xef\x33\xcf\x80\x43\x4c\x0c\x1a\x07\x5f\x68\x57\xe0\x5b\x8f\xde\x0e\xc0\x20\x98\x91\xdb\xbc\x35\x43\x8c\x02\xe4\x97\xcb\x05\x9f\xeb\x84\x5a\x12\x71\x59\xe4\x6a\xd5\x40\x4f\x87\x09\x5c\x8b\xae\xa4\x6d\xc9\x4f\x9b\xfc\x07\xa4\xdd\x21\xeb\x2f\x0c\x8a\x57\x27\x32\x81\x20\xbc\x50\xa1\x1b\xff\x9e\xc2\xc7\xac\x54\x3a\x08\x8f\x1b\xd6\x69\x63\x5c\xaf\x40\x5c\xc5\xe7\xda\x13\x7c\x0a\x18\x53\x7e\x28\x72\xe5\x26\xb7\xf0\x43\x8d\x21\x74\x34\x60\xcc\x12\x87\xf8\xeb\xf6\xa5\x3b\x1e\xc5\x89\x47\x27\xfc\xc4\x28\x38\x9a\x55\xd8\xa6\x2e\x2f\xe3\xd0\x22\x60\x26\x24\x09\x97\x29\x34\xdb\x82\xd0\x18\xeb\xb0\x87\xe5\x60\xdd\x31\x1d\xa2\x83\x52\x7d\x00\x9c\x96\xc5\xd1\xb2\x7f\x8e\x47\xb4\x20\xba\x93\xdd\x5d\x94\xc0\xff\xa7\xe1\x59\x5a\x9f\x6f\xce\x4e\x56\x69\x82\x5e\x14\xd4\xa3\xc8\x53\xba\xc9\xe5\x73\x57\xab\x31\xbe\x24\xf5\x12\xb4\x2d\xd0\x22\xc9\x79\x53\x57\xa3\xba\x7b\x10\x94\x68\x53\x1d\x60\x90\xf3\xf2\xcd\xa1\xa4\x47\xf0\x8b\xc9\x45\x13\x53\xcc\x75\x6a\xaa\xc3\x32\x75\xda\x63\x20\xa8\x8c\x11\x64\x80\x9c\x25\x3b\xe0\x47\x33\xe0\xba\xce\x18\xf7\x28\x55\x26\x53\x53\x01\x12\x08\x36\xa7\xbd\xe2\x6f\x70\x68\x2e\x2d\x96\xf1\xdd\x43\xdf\xf3\x59\xa7\x2c\xa6\x1a\x59\x77\x4c\xa4\x53\x83\xf4\xca\x05\x02\x82\x8b\xe8\xf3\xcb\xe6\xfb\x62\xb7\xde\x6f\x77\x8b\xbb\xf5\xfe\x76\xf3\xb8\xd9\x7e\xfd\xd2\xb5\xa1\x98\xc9\x14\xed\x0b\xf8\xdd\xaf\xdc\x47\x40\xc4\x5f\xcb\xac\x68\xd4\x4b\x21\xdd\x81\x48\x87\x94\xe0\x9e\xa9\xb2\x76\x25\xaa\x79\x86\xe0\xb2\xe8\xc1\xb5\x60\x81\x44\x0e\x6e\x53\x45\xfa\xf5\x24\x1e\x0b\xd5\x2f\x02\x9f\xe9\x07\x83\x60\xca\x47\x6e\xd8\xc5\x66\x59\x94\x30\xb0\xeb\x05\x03\xcb\x17\xe8\x9c\xba\xdc\x70\x1d\x8d\x4f\xd7\x26\x61\x6a\x94\x69\xf2\x1c\xb2\xa1\x87\x2e\x12\x4a\x31\x0b\x82\x92\x51\xc3\x15\x4e\xf0\x48\x78\xd1\xe8\xc4\x21\xb4\x6b\xd4\xcb\xdd\xcd\x78\xac\xb1\x5a\x6a\x5b\x1c\xcd\x93\x5e\xe6\xa4\x26\x50\x71\x21\x3c\x45\x1c\xcc\xb7\x39\x1e\x79\x79\x36\x09\x41\xee\x22\xf4\xe3\x71\x23\xfc\x18\xe3\xc5\x3f\x36\xbb\xaf\xab\x97\xc5\x8f\xc5\xfd\x7e\xb5\xbe\x5f\xfc\xed\x9e\x5a\x40\x88\xa3\x50\xa3\x5f\x69\x00\x96\xf7\x23\x01\x41\x10\x42\x07\xf8\x35\x16\x4a\x3d\xf3\x66\x4a\xbb\x02\x42\xfa\x86\x72\xa1\x5d\xb3\xb0\x4b\x1e\x9d\x72\xad\x75\x37\x84\x92\xc6\x29\xd8\x20\x57\xba\xe9\x77\x67\x88\x08\xf0\x34\x66\x69\xbf\x72\x39\xea\x50\x20\xbe\x64\xce\xd2\x6f\xf2\x7a\x57\x76\xd4\x36\x20\x80\x72\xcc\x4e\xe0\x54\x7d\x28\x14\xea\x2f\x3e\x60\x70\xbf\x5b\xe2\xb4\x27\xb0\xcd\xed\xa2\x4f\x5e\x5f\x07\x00\x08\x4d\x4c\x29\x91\xa1\xf3\xb8\xe7\xb9\x3a\xf2\xf2\xad\x5b\x95\x74\xa8\x31\x6c\x60\xea\xa1\x71\x06\x05\xf3\x53\x5e\x7a\x91\x09\xd2\x9f\xca\xf4\xbf\xd0\xfb\x46\xd2\x8b\x19\x46\x4e\x6a\xd1\xfd\xc2\x44\xe0\x12\x72\x45\x71\x32\xd8\xb4\xd9\x89\x28\x3d\x2d\xc1\x8a\x6f\x0c\x30\x70\xbf\x65\xac\x48\x3f\x88\x30\x34\x61\xe5\xae\x47\xa9\xb6\xcf\xe7\xbf\xf4\x83\x18\xad\x49\x64\xe1\xce\xbb\xe4\x8c\xf4\x63\xa2\x06\xa9\x63\xa7\xcb\x3b\xcc\x8d\x4b\x5f\x78\x48\x8c\x6a\x69\xe4\xc6\xb0\x8f\x51\xe7\x4b\x5f\x02\x2e\xbd\xfb\xde\x9e\x7a\xe9\x77\x55\xe9\x43\x8c\xab\x90\x71\xb7\xcd\xfe\x39\x81\xc3\xdb\x96\x81\x24\x58\xc2\xd4\x5e\xe8\x5f\x7f\x3f\x2f\x67\xa2\xb3\x32\x90\xa1\x32\x4a\x99\xa9\x1b\x50\x92\x88\x80\xc6\x63\x41\xa1\x2d\xd4\xeb\x5c\x17\xa5\x84\x17\x78\x4f\x91\x80\xfa\xb1\xa8\xcd\x4d\xdd\x59\x3a\xc2\xfc\xd5\xe3\x66\xf7\xf2\xf4\xb8\xfe\xf6\x60\x76\x82\xc9\x60\x1b\xbd\x29\x65\x1c\x81\xb8\xff\x69\x78\x0d\xa5\x43\x87\x4a\xaa\x05\xaa\x85\xfc\xf8\xba\xd9\xad\xef\x37\xdb\xdd\xfe\x79\xfd\xb2\x79\x72\x48\x6b\x19\x06\x21\xb5\x7a\xae\x07\xc8\xf4\xc8\x78\x91\x61\x12\x79\x56\xe1\xc0\xc4\xd9\x76\x3f\x1d\x26\xf8\x37\x11\x17\xee\x42\x92\x22\x49\xbb\xf9\xaa\x58\xd5\x87\x73\xf2\x85\x77\xf4\xa3\x76\x4e\xcb\x28\x62\x56\xc5\xb7\x2e\xe1\x94\xaa\x2d\x96\xa3\xf4\x4b\xa5\x8c\x22\xa3\xbe\x83\xa5\xa0\x8d\x42\xcc\x31\xfa\xb7\x63\xfb\x58\x46\xc2\xc3\x0b\x61\x00\x60\x20\xa6\x3a\x7e\xb2\x98\xa9\xc4\xe2\xae\x7a\x22\x9e\x6b\xfc\x1b\xf6\x1c\x46\x89\x25\xda\xab\x1f\x9c\x5e\x25\x99\x89\xe4\x4a\x16\x06\x98\x67\xfe\x9f\xa6\xe4\x43\x16\x1e\x90\x2c\xd1\x98\xda\x68\x5d\xf3\xb4\x04\x85\xf2\xdd\x50\x55\x4f\xfa\xb9\x84\xf7\xb4\x68\xaa\x55\x93\xbf\x42\xd1\x9f\x20\x09\x8b\xc7\xf1\x89\x76\x20\x4f\xaa\xcd\x25\x83\x40\x50\x63\x93\xc1\xf9\x94\xf1\xbe\xdb\x38\x95\xc8\x56\x68\x96\xa1\xe7\x26\x7f\xab\x2c\xb3\xbb\x6b\x00\x31\x06\xde\x3e\x30\x6e\x3b\xaa\x4c\x1f\xfe\xbd\x52\xf1\x2b\x79\xeb\x9d\x76\xe6\xe3\x95\x15\x4c\x24\x44\x5a\x68\x26\x72\xff\x5f\x9a\xa1\x52\x70\x82\xf9\xf6\x9b\xa6\x4a\x73\xa8\xaa\x45\x53\x17\xa6\x7e\xe7\x5b\xde\x1b\x7a\x52\x79\x14\x47\x81\x02\x59\x1c\x4f\xed\xf9\x46\xc4\xa3\xb9\xc4\xff\x49\xc5\x7d\xdc\x68\xcc\x2a\xb5\xce\xd5\x85\xd0\x2f\x48\x25\x34\xda\x1a\x2b\xc0\xe2\xb2\x7e\x7b\x97\x4a\x25\x08\x47\x7d\x2d\x32\x75\x0b\xad\x51\xce\x6d\x6c\x74\xc4\xe9\x06\x12\x78\x82\xa6\x3e\x92\x0e\x3b\xaa\xf7\xc9\xdb\x69\x3f\xc1\xd5\xd6\xda\xea\xad\x69\x5c\x34\xb5\xa9\x2b\x54\x33\xf1\x3e\xe5\x09\xdf\x82\x0b\x1d\xef\x02\xca\x10\xce\xbc\xa6\xf2\x43\x85\x08\x11\xd5\x3a\xcc\x93\xcb\x04\xbe\xe7\x36\x04\xac\x73\x58\x54\x55\xfa\x9a\xc3\xbc\x3a\x07\xa8\x40\xcb\x24\x1c\xf0\x9d\xfe\xde\xa2\xae\x08\x8b\xa5\x2d\xff\x41\x52\xd1\xa5\xa9\x34\x9e\x50\x0e\x81\x22\x89\x87\xbc\x2c\xe8\x39\xe3\x4b\x2d\x8b\xe3\x89\xa7\xaf\x13\x63\x5c\x11\x15\x62\x76\xf1\x64\x80\xc4\x13\x9f\x56\x51\xcf\x10\xd4\x61\xe7\x2c\x4e\x27\xc8\xd5\x0a\x64\x3b\xc0\x41\x61\x84\x7c\x7c\x35\x1a\x25\x48\xd4\x76\x28\x9a\x0a\x69\x44\xed\xef\x21\xf5\x71\x8d\x34\x14\xf3\x96\x33\xa1\x77\xcc\x54\x98\x18\xfe\x70\x8b\xa8\x43\x29\xdd\x2f\x73\x60\x43\x15\xf2\x04\x49\xb0\xd2\xca\xd5\x3b\xba\x7b\x44\x3e\x45\x23\xf1\xc8\xdf\xe0\x39\xb5\x0e\xe0\xc4\x08\x53\x51\x98\x08\xbb\xb4\x75\xac\x3c\x3e\xeb\x2e\xc1\xb8\x53\x81\x7d\xce\x78\x0e\x66\xcb\x98\xe7\x86\x06\x15\x09\x1f\x53\x5f\xf7\x85\x29\xff\xe8\xd9\x45\x54\x6c\xc9\x07\x75\x93\xcb\xbd\xb7\x0c\x96\xdd\x01\xee\xe1\x7a\xf5\x5c\x42\x3b\xc0\x7f\x76\xbf\xcb\x04\x4b\xad\x6e\x79\x5e\x17\xa3\x72\x0a\xc5\x22\xed\x8d\x94\x67\xd2\xf7\xd4\xd9\x36\x2a\x11\x09\xe6\x1d\x45\x73\xde\xeb\xb2\x98\x62\xe4\x14\xd7\x14\x37\x1f\x74\x79\xcc\xb7\x7d\x99\x61\xaa\xb7\xad\xa5\x9f\x8c\x11\x50\xe9\xb1\x39\x7e\x2d\x54\xb6\xb2\x09\xb7\xc9\xe7\x96\x34\xc6\xca\xc2\xed\x7a\xed\xb6\x3b\x25\x43\xca\xcd\x10\xc8\x66\x1d\x22\xa5\x02\x83\x63\x3d\x41\xce\xb3\xce\xab\x52\x4a\x29\x83\x2b\xaa\xea\xdb\x26\x97\xd3\x82\x4c\x05\x9e\xd1\xe0\x4e\x65\x41\x1e\x78\xd7\x71\xad\x85\x6b\x56\x29\x5e\x1f\xda\x95\x63\xcf\xfd\xb8\x3b\x28\x3c\xac\xe4\xef\xa5\xd2\x31\xb4\x6d\xeb\x48\x3a\x65\x12\x50\x1a\x62\x70\x8a\x29\x46\xc2\xd7\xb2\x3b\x8c\x1e\x1d\xbc\x40\x25\x36\xf8\xfc\xa9\x84\x99\x01\x4c\xcf\x2e\xd0\xe0\xc5\x46\x64\x8f\xab\x7f\x37\x55\xbd\x4a\xb5\x4e\x65\xd3\xf6\xc3\xb8\x59\xe0\x2b\x65\x9f\xa8\x67\x8d\xfe\xb6\x5d\xfd\x58\x6f\xa6\x2d\x85\x67\x12\x1a\x9d\xbf\xbd\x2b\x7e\x8c\x51\x54\x10\x48\xe1\x82\x95\x23\x91\xcb\xf6\x08\x60\x74\xfa\xfb\x9f\x8f\xc8\x03\xe0\x7e\x27\xc4\x47\x62\x59\xbb\xf3\x8f\x10\x52\x40\x88\x41\x2e\x5b\x0d\xbc\x3d\xba\x8f\x55\x77\x34\x52\x42\x0e\x04\xf3\x5b\x5f\xfc\x34\x56\xa4\x03\x20\x92\xf8\xaa\xcf\x8a\x63\xe4\xeb\x29\x9f\xc9\x7a\x02\x0d\x8c\xbc\x34\xd2\xa3\xbc\x74\x59\xa2\xab\x35\x81\x40\x43\xaa\x1c\xae\xe7\xdb\xcd\x2c\x4f\x2d\x40\x18\x44\x88\x14\x00\x74\x69\x1e\xd2\x7c\x84\x67\x80\x50\x72\x5f\x77\x91\xa2\xea\x1e\xb4\x45\xe4\xbb\x06\x51\x20\xe3\xb8\xa3\xcb\x78\x85\xef\x58\x36\x34\x27\xdd\x0a\x10\x87\x1a\x91\x8d\xa6\x22\x67\xf7\x75\xf3\xb2\xda\xf7\xaa\x12\xee\x8a\x71\x62\x74\x95\x5f\xd6\x3f\x16\x2f\xab\xfd\xe3\xb7\x87\xfe\x88\xa9\x96\x95\x59\x51\x01\x3a\x8d\x90\xab\xe6\xd8\x75\x78\x2c\x19\x7e\x43\x01\xbc\x7e\xe0\x65\x9d\xf2\x6c\x68\xeb\x42\xac\x3d\x2c\x7d\x72\xf8\xe4\x2d\x64\x99\xa1\xc9\x9b\xef\x40\x16\x32\x57\x90\xba\xbc\x7d\x6a\x47\x7a\x9a\xbf\x5e\x6b\x0b\x04\x79\xc1\x5b\xeb\xfb\x96\xa7\xd9\x94\x05\xb7\xb2\x34\xb8\x8f\x45\xbd\xc9\xbf\x55\xe0\xb9\x87\x4a\x42\x90\xba\x97\xec\x31\xa1\xf6\xd1\x26\x06\xdc\xf7\x84\xcd\xba\x3f\xf7\x6f\x23\x22\x22\x92\x7e\xe4\xd8\xf0\x21\x7e\xbd\x4f\x93\xf8\x20\x54\x88\xb8\x87\xac\x78\xdd\x97\x20\x79\x75\xed\xfd\x85\x32\xba\xa9\x8b\x53\x99\x76\xb0\xda\xf9\x6b\x4a\x0e\x98\x0d\x1e\x4e\x36\x29\x03\xde\xc7\x40\x5e\xac\xfd\x89\x72\x50\x50\x7f\x00\xe4\xa8\xef\x3a\x19\x23\x52\x0a\xd6\x6b\xb5\x2e\x8c\x8e\xc6\x64\x26\x28\x19\x23\xfe\xea\x1d\x09\x8c\x3b\x9a\xda\xc9\x95\x94\x34\x65\xb8\x27\x7e\xee\x32\x5a\xfe\x1c\xfd\x33\x80\x56\x26\xef\x38\xd2\xf8\x78\x2e\x8b\x9f\x6e\x55\xd6\x7e\xc0\xf9\xa0\xb3\x7b\x46\x5c\x77\x9c\x8a\xc4\x45\x10\x30\xc3\x7d\x5f\xd4\x4f\x1a\x6b\x5b\x3a\xd4\x96\x0e\x42\x8d\xe4\x6f\xbb\x54\xee\xb8\xdc\x15\xf0\xd2\x64\xbf\x56\xc3\x18\x7f\x14\x1d\x44\xb1\x89\x3d\x01\x12\x89\xbb\x5f\x63\x0f\xa3\x3a\x4b\x87\x9b\x1d\x23\x44\x75\xa0\x62\xa4\xa6\xc2\xdc\xdd\xca\x2a\x79\xb9\x83\x94\x48\x61\x0a\x17\x10\xe9\x03\xe5\x63\xd1\xbc\x03\x6f\x9e\xcb\xe2\x54\xa6\x45\xd7\x8c\x19\x81\xc5\xd2\xf9\x92\xe3\x0e\xd7\xa1\x67\xf4\x79\x4f\x86\xfb\xe3\x2b\xcf\xfa\x02\x5c\x1d\x06\xd4\x15\xdb\x59\xb9\xd2\x61\x19\x93\x6b\xc4\x63\x18\x70\x96\xc1\xae\xe8\x6a\x47\x5c\x4a\xf8\x4a\xce\x48\x47\x1e\x50\x5b\x31\xff\xd2\x88\xa6\x32\x85\x6e\x9f\x56\xcc\xeb\x28\x66\xe8\xe9\xb8\xe9\xe2\x7e\x06\x91\x48\xe7\x00\x1d\x4f\x35\xec\x89\x83\x43\xea\xd8\x57\xe8\x9c\x9b\x4a\x5e\xa4\xd5\x99\x75\x52\x74\x1c\x30\x4c\xc1\xaf\x16\xab\xbf\x10\xb6\x60\xfc\x6a\x77\x34\x0a\xf0\x23\xba\x0d\x79\xbf\x28\xd3\x7c\xc2\xe6\xa4\x63\x29\x71\x21\x3c\x42\xcd\x15\xaf\xf9\xb4\x9a\x44\x33\x1a\x1a\xc4\x03\x72\x4a\x5f\xe1\xff\xfe\xb5\x38\xd3\x55\x67\x5a\x27\x11\x41\x16\x78\x44\x48\xdd\xce\x68\xfa\x0e\x7c\x55\xcd\xb5\xf4\xe6\x42\xcb\x57\x3e\x18\xd7\xca\xf3\x3b\x1b\xf3\x0c\xe5\x1d\x4f\xf3\xfb\xa2\xaa\x9e\xf2\x7b\x5e\xd5\xb7\x59\xea\x40\x54\x5a\x26\x46\x41\xe0\x98\x1a\x9a\x1e\x64\xbd\xeb\x0e\xea\x00\x1d\x08\xcb\x8c\x96\x9f\x67\xb5\x5a\x41\x2b\x2f\x31\x5e\x63\xd6\xb8\xe0\x95\x56\x81\xc4\xaa\xf0\x53\x51\x0d\xac\x56\x8d\xce\x80\x0b\x39\xb7\xcb\xf1\x27\x40\x7b\xad\x68\x82\x88\xf3\xbc\x39\x22\xe4\xa8\x9b\xed\x10\x6a\x64\x48\xb0\xa2\x8d\x7d\x42\x71\x64\xc8\x6b\x88\x8c\x5c\xbb\x55\x63\xfb\x3c\x1a\xae\xc1\x12\x44\x17\x08\x49\xdf\x1e\x0a\xb7\xba\x68\xcf\x53\x1a\x93\x24\x8f\x45\xde\x45\xc8\x79\xe6\x2c\x20\x87\x92\x1a\xce\x00\xed\x05\xb1\xc4\x08\xf7\xd1\x08\x62\x0d\xc3\x1a\xda\x23\x1e\xc3\x52\x03\x2b\x60\x78\x07\xc7\xee\x5e\x58\x36\x8f\x5f\xe4\x68\x61\xda\xe3\x22\x64\xed\x11\x30\x29\x26\x07\x5f\xb5\xeb\x51\x77\x05\xea\x4b\xe4\xe2\xfc\x33\xad\x6f\x9b\xba\x29\x87\x45\x04\xda\xa3\x84\xa0\x9a\xff\xfe\x15\xea\x55\x59\xe4\xb0\x10\x69\x96\x4e\x8c\x43\xed\x85\x9e\x92\xe0\xca\xed\x50\x9b\x7c\xc2\x8c\xf7\xc7\xd8\xe7\xfc\x63\x7c\x76\xe0\xe3\x88\x48\xd1\x81\x0e\x3c\x67\x2f\x6b\x2f\x4c\x12\x74\xe3\xad\x8a\xf2\xdc\x00\xd6\x5e\x14\xc5\x9e\xa9\xeb\x54\x3f\xd2\x7c\x34\xda\xb4\x97\x04\x12\x25\xd0\x1f\x36\xab\xbb\x97\xc5\x6a\xbd\xdf\xfd\xfd\xbc\x26\xee\xfa\x49\xe4\x23\x1f\x00\x2e\x0c\x67\xf7\xab\xe0\x71\xd4\xa7\x59\x97\x87\xa1\x84\xeb\xfc\x23\xc8\x20\xc6\x7d\xab\x35\x4d\x06\xd5\x34\x57\xb0\xae\x93\x93\x5b\xe7\x18\x6c\x00\x1a\x63\xef\xc7\xe2\x12\x8e\xa7\x3d\x4d\x74\x40\x07\x35\xae\x73\x3b\xa8\xf6\xbd\x08\xac\x63\x2b\x0b\x05\xcf\xad\xef\x50\x63\xe2\x6b\x3e\x18\xac\xfd\xc0\xd3\x38\x3e\x6a\xc7\xbb\xa0\x3a\x82\x4e\xed\x07\x81\x91\xbe\xd9\x63\x69\x36\x47\xe2\x91\x76\x5a\x43\xd9\x0f\x81\xd9\xe0\x90\xf6\x03\x12\xd2\x5e\x68\x06\xeb\x3f\x6e\x78\x05\xea\x69\x5c\x87\xd0\xdd\x49\x18\x6a\x84\x3b\x5e\x4a\x47\xa1\xa6\xfd\x40\x31\x8c\x0c\x61\xa4\x6d\x4c\x16\x7d\x0d\x57\xe3\xce\xd4\x1a\xc3\xbc\xa8\x25\x78\xfb\xf8\x6d\x3c\x60\x7d\x42\x05\x58\x55\x05\x17\x7d\xbb\xce\x88\xa2\x7d\x12\x52\x6d\xa4\x53\xca\x1c\x45\x4f\xe6\x6c\x78\xed\x93\x28\x0c\xba\x92\x7a\x5e\xc2\x48\xd6\xde\xb5\xe1\xda\x95\xd4\xda\xe8\xf4\x45\xee\x56\xfb\x44\x09\x65\xaa\x2e\x5f\x78\x7e\x19\x32\xd3\x3e\x0d\x7c\x03\x6e\x1f\x28\xb1\xcc\xbe\xc0\xe4\x09\x69\xa8\x70\xa1\x5d\xd7\x07\x01\xf3\xfa\xb7\xda\xa7\x89\xf2\xfa\xd0\xed\x4d\x53\xe6\x98\xac\x51\x93\x3e\xa4\x3c\x06\x13\x78\xb4\x0a\x3c\xd7\xa4\x63\x3b\x2f\x0b\xad\x33\xc7\x54\xd1\xda\x9f\xdb\x9a\x1f\x4f\xe3\x8a\xee\x39\xc4\x80\xf6\xc3\x30\x36\x58\xd4\x41\x98\x24\xf8\x32\x6e\xa2\xa9\x09\x34\x5a\x29\x08\x37\x86\xa2\xc8\x14\x47\xb6\x96\x4c\xe6\x7e\x64\xc4\x50\x5c\xb6\x96\xeb\x5e\x17\xe5\x5e\x3a\x1e\x81\xfd\x0a\xff\x7d\xdb\x91\x00\x69\x9f\x31\xb0\x9c\x27\x8d\x4a\x0b\x84\x6a\x4f\x3e\x07\xe3\x21\x31\x29\x0c\x38\xa2\xb2\x4b\x77\x2a\x97\xa3\x44\xe1\xd5\xef\x64\xdb\x27\x7e\x88\x93\x5c\xa7\x59\x36\x86\x4e\xf6\x3b\xbc\xf6\x13\x6d\xb2\x42\x58\xeb\xdf\xd3\x34\x6b\x9f\x47\x14\x57\x3b\x99\xa5\x5a\xf7\x89\x37\xed\x0b\x4d\x43\x1b\x66\xba\xe3\xd8\xef\xd3\x22\x7a\xed\x2b\x1d\xc6\x43\x09\xad\xf5\xee\xab\x3b\x1d\x88\x70\x1b\xf1\xd7\xa2\xa9\xe0\x99\x9f\x8b\x7e\x96\x02\x93\x01\x75\x0e\x7f\xbd\x03\x7e\x51\x6c\x3d\x01\x59\x6a\x1f\x94\x27\x2d\x19\xf5\xb8\x3b\x26\x4b\xa6\x6d\xae\x55\x84\x8f\xbf\xbe\x07\x5e\xe6\x36\x5a\xbb\x7e\xb1\x51\x2c\x1d\x78\x1e\xe5\xbe\x01\x21\x8e\xbf\x4c\xe0\xf9\x92\x47\x16\x2a\x56\xd6\x86\x15\xba\x1e\x23\x8d\xff\x98\x9c\x21\x12\x34\xe6\x3a\x12\xdb\x5e\x8f\x77\xdc\xd0\x0f\x39\x6e\xcb\x27\x7e\x6e\x1d\xd8\x2b\x7c\xbd\x3a\xf0\xb9\x87\xb4\x9a\x9d\x05\x50\xe4\x50\x1f\x38\x16\xd2\x7c\xab\xcd\x76\x6a\x9b\x06\x11\x27\x2e\x9a\x0a\xe5\x7b\x2a\x2d\x26\x77\x0e\x53\xe8\x56\xda\x20\x60\x1e\x8b\x47\x80\x9c\x61\x90\xab\xc7\x05\x75\xcd\x29\x42\x33\xb7\xae\x0c\x75\x7e\x15\x08\x02\x6e\xaa\xa8\x8d\x3d\x87\xf9\x98\x89\xba\xba\x0e\x08\x37\xd4\xd2\xed\xba\x88\x65\x2b\xc6\xe0\x99\x94\x94\xe8\x80\x08\x8f\xc6\xbd\x8d\xf9\x38\x50\x08\xd4\x01\x91\x02\xc9\xc3\x4a\x90\x67\xe9\xca\xcb\x75\x40\xa3\x18\x0d\xf7\x7f\xfe\x75\xdb\xfd\xa4\x2d\x2d\x5b\x31\xe5\x91\x98\x74\x79\xe8\x99\x73\x17\x23\xec\x90\x0e\x22\x12\x89\x8e\x53\xb4\x90\x6f\xed\x77\xc3\x69\x86\xe6\xe5\x64\x42\x04\x11\x05\xe4\x68\xd2\xbc\xf5\xc5\x6c\xe0\x69\x09\x65\x6d\xf8\xb8\x2f\x6b\x90\x3f\xb3\xf0\xed\x35\x13\x2f\xd4\x7d\x22\x73\xdb\xb3\x8f\xe8\x20\x01\x11\x1b\x50\xfe\x7b\xf1\xd6\x4e\xd1\xb7\x41\x94\xc3\xb6\x11\x32\xc4\xbc\xaf\x4e\x7f\x9a\x6a\x69\x9e\xc9\x9b\xc6\xed\xd7\x81\x4c\x08\xc6\xfc\xab\x53\x96\x5e\x59\xdd\x03\xc5\x7d\xb4\xd3\x31\x43\xbc\x85\xab\x85\x78\xf3\x3b\x48\xa0\xb8\x30\xa6\x7a\x93\xcb\xc3\x66\xec\x54\x38\xa3\x33\x80\x50\xa0\xdd\x70\x8f\x30\x14\xf7\x74\x3a\x11\x22\xee\x23\x2c\x03\xe2\xbb\x21\x28\xc3\x35\xe6\x06\xe2\x84\xe5\x5b\x3c\x43\x2e\xe5\xfd\xa9\x13\xb4\xd1\xc4\x4b\x02\x9c\x7e\x6b\x5e\x9d\xbf\x16\xc7\xce\xfe\x26\x9e\x34\x15\x20\x86\x65\x49\x64\xdd\x48\x23\x61\xd8\x29\x80\xdd\x14\x45\xf6\x7b\x55\x69\xfd\xee\x45\x22\x1d\x39\x8a\xdb\xf6\xcd\xc6\x7c\xa8\xb6\x4d\x0c\x71\x32\xc4\xfb\xa3\x07\x76\xe4\x6f\x53\x93\x9f\xc4\x5a\x19\x41\x1e\xf8\x09\xd9\xa0\xc0\xe6\x32\xd3\xab\x49\xe2\x07\x18\xa3\x85\xfa\xf0\xc2\x6b\xe8\xc2\xcd\x9a\x24\x32\xe2\xa2\xb3\x55\x91\xbb\xa0\x6a\xff\x3b\xb9\x19\xf7\x86\x61\x89\xe5\xd3\xcb\xfc\xc4\x21\xdc\x0b\x31\x9b\x01\x3f\xeb\x92\x5b\x8e\xbc\xd2\x32\x21\x4f\xae\xe8\x53\x3f\x70\xa0\xa9\x12\x41\xf6\xb3\x03\x86\x70\xe2\x23\x2e\x64\x7b\x3e\x8a\x22\xb3\xe5\xfd\xa3\xb7\xe3\x89\x8e\x7a\x3c\x42\x5a\x4c\x0c\x0d\xc2\x81\xfa\x96\xc2\x02\x43\x8d\x08\x0d\x35\xa4\x39\xf9\x15\xc6\x1f\x4d\xb8\x06\x8c\xa0\xb7\x43\x2b\xeb\x14\x1b\x34\x11\xc4\x0b\xa1\xa7\x93\x69\x2d\x64\xfe\x0a\x9b\xe9\x3d\x85\x22\x48\xf6\x54\x03\x3f\xfe\xab\xe9\x4f\x97\x49\x80\x96\x60\x47\x18\x7d\x7b\xbf\x5c\x16\xe5\xb5\xa7\x90\x82\xb9\xd0\xf3\x92\x97\xca\x0a\x3f\xa1\x09\x71\x15\x1e\x6a\x4f\x55\xb1\xc4\xfc\x83\x4d\x41\x0d\x8b\xab\x48\xf0\xbf\xe4\xff\xae\x33\xa2\x6a\xa2\x18\xf3\x1c\x13\x7c\x9a\x77\x55\xc2\xee\x28\x50\xe3\x29\xc3\x87\x0b\x0d\x0c\x1f\xc1\xcd\x62\x02\xb1\x87\xe6\xac\xcc\x80\x77\x9a\x7f\x88\xaf\x12\xe7\xc9\x68\x80\x84\x62\xd4\x55\x97\x45\x5e\xbf\x34\x3d\x7d\x9e\x26\x20\x62\x66\x59\xc7\xa6\x05\x62\xf3\x2f\xae\x3d\x40\x58\x03\x26\x55\x11\xd3\xf5\x90\xe6\xf5\x90\xca\x5f\x13\x1d\x12\xa3\x73\xca\x4f\xa7\xca\xa4\x13\x79\x26\xaf\x7c\x04\x2d\x42\x34\x97\xee\x8b\xd7\x2d\x46\xc7\x27\x04\xf6\xec\x8f\xb9\x94\xa8\x26\x5a\x06\x0e\x28\xb0\x34\xd5\x7b\x08\x7b\xb3\xc8\x94\xd1\xd3\xfb\x03\x62\x77\xe7\x16\xd0\xe1\x9f\x21\xa9\xaa\xa6\x5e\x98\xe0\xb7\xfd\x9e\xc2\xc7\xc3\xf9\xc6\x65\xe4\x35\xf5\x12\xc6\xba\xc2\xbb\xd6\x47\x2a\xca\x0a\x5d\x89\xae\x81\x8a\xa8\x89\xb2\x1c\xf9\x90\xa7\xda\x1e\xf6\x63\x93\xce\x6b\x5d\xad\xcd\xf2\xe9\x57\x49\xdc\xf9\x2f\x40\x7d\xc1\xa9\xe3\x36\xf8\xd4\x9f\xa0\x81\x67\xf2\xec\xfb\x6e\x3e\x5c\x40\x6e\x34\x0d\xb4\xd2\x66\x8d\x92\xc5\x3b\x94\xe7\xd6\x61\xd8\x95\xe9\xeb\x2b\x94\x03\x1b\x95\x92\xc4\xd7\x6e\x19\x68\xfd\x8d\x07\x2c\xfc\x1d\x0f\x34\x4a\x78\x84\x69\x8e\x77\x07\x91\x1e\x00\x45\x34\x25\xd2\x4f\x22\x57\x76\xd2\x94\x39\x3f\x42\xfe\x29\x5b\xa7\xa6\x21\x31\x80\x26\x03\x9e\xb4\x83\x7c\x94\x4c\x9b\x3a\x9a\x57\x0b\x39\x7a\x0b\x9d\x86\x92\x20\x81\xed\xd0\xee\x5f\xf4\x6c\x8c\xf3\x4e\x2b\x0d\xb5\x11\x4f\x7c\x85\x7a\xf7\x96\x3f\x69\x0d\xe5\xd4\x94\xa2\x51\x14\x3a\x6d\x79\xb4\x5c\x3e\x7d\xd4\x6b\xff\xfe\xc5\x2b\xd9\x5b\xc5\x7e\x14\x5a\x1d\x48\xfe\x0a\xe3\xb2\x3b\xd7\x84\x18\xaa\x9b\xfe\xfb\x77\xa5\x86\xcd\x05\x7d\x89\xa6\x31\x25\xe8\x47\x9c\xde\xeb\x7d\x9a\xbf\xef\x11\xd8\x60\x8f\x31\x5f\xa0\x65\x84\x62\xe0\x53\xf3\xee\xf3\x07\x65\xad\x51\x83\x88\x26\x4c\xfc\x6d\x4f\x46\x75\x78\xf2\xac\x2c\x00\xac\x1a\xb9\x4f\xdf\x60\x24\x3b\x33\x3f\x30\xb8\xd4\x86\x23\xf7\xc0\xcb\x5d\x71\x73\xae\x6d\x36\xc8\xb7\xc7\x85\x2f\xb5\x83\x79\xb7\xc3\x3a\x3f\xc2\x74\x93\xa4\x42\x28\x3d\xe4\xc5\x42\x9b\xff\x53\xb1\xfe\x71\xe8\xd8\x5e\x46\xea\x08\x81\x3c\x79\x73\xb4\x38\x7e\x67\xec\x50\xe5\x53\x48\xfa\xa8\xe5\xb4\x06\x45\x53\xa5\x63\x74\x9d\xb0\xda\x1b\x39\xa5\xfa\x73\xb5\x44\x91\x84\xcd\xf2\x09\x4d\x0f\x5b\x0c\x32\x2f\x60\xad\x29\x68\x66\x5d\xa9\x0f\x5e\xaa\x51\xb5\xa7\xa6\x9a\xf9\x98\x2e\x12\x3c\x97\x45\xe9\x04\x4e\xbb\xa3\x2a\x41\x9f\x23\x2b\x5e\xf7\x80\x3c\xd0\xa3\xf7\xd3\xed\xc8\x68\x47\x51\x71\x82\x1c\x09\xe0\x0c\xa5\xe4\xb5\xd5\x6a\x78\x72\xe8\xf9\x06\x8b\x5b\xf1\x77\xd8\xe4\xba\x58\x88\xa2\xa9\x1d\x16\xe7\x97\xd8\xc4\x81\x79\x17\x7a\x21\xf7\x0c\xc8\x8b\x67\x2b\x5e\xf3\x6d\x5d\xce\xf9\xb2\x53\x91\xd9\xd1\xa6\x11\xfa\x24\xd6\x89\xad\x69\xc5\x09\xda\x69\xa0\x8c\xdb\x05\x41\x84\x74\xff\xdb\x43\xa3\x75\xe6\x98\xfd\x75\x18\xc4\x01\x46\x48\xb6\xe9\xf1\x94\x0d\x40\xc7\x3a\x0c\x12\x81\xa5\x72\xab\xee\x07\x0b\xf4\xab\x80\x97\xf2\x70\x5b\x02\xe0\x9d\x2e\xb9\xd4\x7a\xf7\x7b\xf2\x7f\xec\x97\x2d\x2e\x99\xa9\x74\x48\x98\xaf\x9d\xc8\xe8\xb7\x0a\xca\x25\xcf\xb1\x9c\x87\x57\x60\x59\x60\x46\x0e\x5e\x48\x38\x8d\xbd\x0e\x39\xae\xd3\x6c\x62\x9d\x86\x44\xc4\x00\x36\x80\xd0\xe4\xa9\xe5\xab\x18\x8b\xf6\xb7\xad\x78\xe8\x1b\x3e\x81\x1f\xbc\x7a\xe0\x6a\x6c\x46\x86\x04\x02\x04\x7a\x3c\x5a\xec\xf0\xe4\x26\x61\x28\xd0\x0d\x7f\x48\x65\x59\x0c\xd8\xae\x75\x18\x79\xd2\x80\x38\x7b\x33\x31\x8c\x80\x22\x00\x68\x7b\x30\xf1\x6c\xf7\x7b\x4c\x05\xf2\xef\x56\x46\x96\x53\x8c\x41\x65\x3a\x8c\x63\x23\x45\xd1\xe7\xac\xfc\xa8\x3b\x57\x98\x44\xa8\xb1\xd5\xdb\x2d\xe1\xb9\x4c\xdf\xd3\x0c\x5e\x27\x4c\xb1\x3a\x8c\x41\xc4\x96\x3e\x47\x38\xb8\xbb\x0e\x99\xcf\xb1\xd6\x10\x2b\x11\x9b\xa3\x0d\xb5\xf7\x0c\x70\x9f\x15\xf0\xea\x90\x29\x23\x06\xf1\x81\x09\xcb\x27\x3d\xee\xbd\xc4\x93\xc6\xc5\x70\x54\x8d\xb7\xe9\xcf\xc9\x54\x9c\xb0\x7b\xea\x30\xe1\x91\xc9\xb5\xb7\x46\xda\x0f\x48\x4d\xa0\xb9\x4b\x36\xea\x30\x01\x81\xbe\x26\x52\x6b\x98\xa7\x7b\x32\x4b\xd0\x70\xfa\x7d\x36\x27\x13\xcd\x10\xef\xfd\x5a\xb8\x6b\xf2\x90\x46\x5d\xbd\xec\x8f\xb4\x3e\xbc\x40\x55\x64\xef\x57\xf4\x45\x74\xc8\x99\xc2\x2c\x62\xc9\xd3\x0a\x0c\xd1\x63\x85\x12\x35\x63\xdb\xc6\x8f\xbc\x3f\xcc\x1f\x77\x1e\x4f\x34\x71\x2a\x73\x46\xbb\x63\x5c\x8f\x3c\xb9\x8d\x4a\x90\x16\x3d\x2f\x14\xec\xd3\xcb\xc0\x6f\x28\x98\x87\x04\xc7\xb2\x51\x0a\x49\x14\xb9\x7b\x23\xc1\x45\x2c\x1d\xed\xb2\x5d\x57\xbb\xc1\x29\x99\xc4\x49\x6e\xe1\x83\xd5\xea\xc6\x1d\x81\x98\xd0\x0e\xd5\x6e\x27\xce\x4d\x6b\x34\xd7\x4b\xc8\xeb\x6a\xc0\x35\xa1\x43\xe0\x46\xfc\x16\xab\xd4\x67\x97\x07\xd6\xb5\x94\x1a\x2b\x57\x72\x35\x8c\x4e\x84\xa0\x12\xdc\x68\xa0\x92\x65\xf1\xe1\x4a\xcc\xc7\xaf\x08\xe0\xe3\x78\x68\x2a\x28\xb7\xe9\x6b\xde\x9c\x86\xd6\x59\xa8\x3d\x1f\x27\xf0\xdd\xcf\x5d\xeb\x05\x95\x95\xc9\xec\x8f\xaf\xa1\x7d\x03\xd6\x29\x5c\xea\xac\x1a\x65\xd0\x75\xa8\xa9\xc4\xaa\x8c\x26\x47\xf2\xcb\xa0\xfb\x9d\x85\x58\xc5\xf3\x00\x35\x6f\xbb\xe1\x13\xe8\xb4\x8e\x3c\xdf\xc8\x53\xb8\x02\xaa\x0b\xf8\xb7\x8e\x3c\x20\x76\xb6\x56\x58\x49\x6d\xb6\xc8\xfe\xb3\x45\xbe\x27\x5d\x99\x86\x63\x65\x52\xf7\x29\x17\xc3\x88\x5e\xe4\x07\x0c\xab\xe5\xf2\xa6\xfe\x2f\x96\x37\xd9\xdf\x83\x30\x0a\x4c\xca\x18\x5e\x73\x9e\xd7\x8f\x69\xfe\x6f\xee\x3e\x7a\x44\x02\x8d\xc0\xdc\x22\xc7\xe4\xfc\xec\x7e\x1c\x11\xc5\xa2\x61\x42\x68\x56\x99\x65\x1a\x79\x8d\xa8\x4f\x30\x08\x23\x78\x2d\x0f\x06\x13\xba\xad\x8b\xd3\xa9\x9b\xb4\x11\x65\x11\x66\x6e\xc6\xf1\xc4\x45\xae\x1c\x35\xc5\x15\x53\x3a\x0a\x03\x1f\xe5\x5f\x6e\x5f\x9e\xfe\x59\x3f\x8e\x84\xc1\x75\x14\xc5\x89\x6f\xcd\xa5\xaf\xbb\x87\xfb\xd1\xe2\x13\x45\x5c\x22\xa2\x61\x2d\x0b\xc3\x68\x81\xb8\x2b\x68\x8e\xee\xec\xd8\x53\xdc\x48\x13\x55\x75\x59\x9c\xef\x8b\xd7\x54\x8e\xa1\x85\x3a\x8a\x13\x23\x24\xf4\x49\x97\xc5\x9a\xe8\x78\xc4\x23\xb8\x2b\x56\xf0\x7e\xa5\x35\x23\x1a\x9f\x6a\x26\x2e\x33\x79\xf3\x44\x2a\x14\x29\xb4\x54\x37\xd5\x09\x46\x12\x58\xe3\xcb\x72\x3f\x46\x84\xe0\x25\x1d\xe7\xb8\x9d\x88\xe2\x30\x1a\x2a\x97\x6f\x2a\x9b\x87\x71\x0d\x04\xc1\xd4\x9d\x2a\x90\xf9\xc1\xd5\xaa\x4d\xac\xda\x61\x70\xcb\x9e\x28\xad\x70\x2b\x6a\x7a\xfc\xc4\x69\x1e\x2c\x3a\x79\xba\x67\xac\xa1\x37\x50\xe6\xf1\x13\x29\x62\x0a\xcd\xaa\xe6\x74\x2a\xca\xb1\x6a\x8a\x8e\x54\x64\x82\x54\x95\x05\x1c\xbb\xe1\x62\xab\x9e\x27\x97\x4a\x8c\xc6\xc0\xfa\x65\x31\x2a\x4f\xd0\x11\x50\xcf\xd4\x44\xd6\xbc\xac\xc7\xb4\x5f\x23\x0b\x2a\x02\x4e\xd1\x00\x7f\xd8\x6c\x97\xeb\xfb\xfb\xc5\xe3\xfa\xe9\x5b\xa7\xdb\xb3\xfd\xf6\xfc\x7c\xff\xb7\xbb\xa6\x0e\x75\x62\x41\x29\x8b\x5c\xdd\xda\xe0\xa9\x2d\x44\xfe\x01\xe9\xe4\xe1\x74\x6c\x2c\x09\xac\x84\x45\xe9\x91\xd6\x4f\x1d\xd0\x96\xeb\xd8\xf7\x22\xac\x32\xd9\xbd\x6c\x87\x11\xe6\xd8\xf7\x80\xf4\x98\xfb\xdb\x34\x87\x9f\xe3\xe3\xed\x46\x6b\x9d\xdc\xa7\xfb\xbf\xbf\x6d\xc7\x64\x98\x3a\x26\x81\x70\x60\xc1\x75\x8e\xc0\xe6\xb4\xc8\x17\xd9\x6b\x51\xa6\xf5\xe1\x38\x5c\x4f\x63\x22\xa8\xb6\x5c\x44\x88\xf7\x4d\xf3\xd7\xcb\x82\x77\x1d\x13\x15\xf8\x86\xbb\x52\xdd\x17\xaf\x93\x71\x3c\xea\xd2\x98\x72\x23\x4b\x22\x11\xca\xbc\x44\xaa\xcb\xb4\xc8\x2f\x78\xfe\x75\x4c\x21\xb4\x35\x4c\xf9\x31\x1d\x58\xa9\x31\x85\x88\x0d\x99\x03\x1e\xe1\xe3\xb9\x11\x7f\xc2\xf9\xb6\x28\x7b\x65\xd6\x60\x54\x31\xa5\xe3\xd0\x23\xd2\xac\xc7\x95\xa1\x67\x1b\x04\x06\xe2\x90\x79\xc8\x54\x7c\x57\xf2\xd3\x01\x72\x78\x2e\x3e\xa0\x9c\xc8\x7b\xeb\x38\x94\x2c\xb0\x81\xbd\x27\xf1\xef\x65\xc6\xab\x6a\xfd\xf3\x34\xe4\xa1\xd5\x71\x08\x46\x97\x2d\x45\xe2\xff\xf1\xbb\x47\x81\xc4\x6a\x69\x70\x45\xa2\xbf\x19\x3b\x71\xa7\xd3\x24\xe2\x1d\xd7\x9e\x59\x33\xc9\xe7\xd1\x93\x38\x12\x51\x68\xfc\x56\x5b\x2b\x0b\xa1\x7b\x9b\x48\xfa\x3e\x9d\x16\x85\xf7\xc3\x2f\x52\x80\xa4\x64\x19\xe8\x9a\x86\x93\x6f\x13\x69\xea\xa8\xc8\x5b\x07\xbb\xab\xa1\xeb\x5b\xc4\x34\x30\x80\xab\xa6\xbc\x5c\x2b\xff\x98\xb6\x4d\x88\xef\x08\x2c\x2d\x50\xfb\xdd\x66\x00\xe7\x59\x35\x75\x1c\x47\x5a\x20\xaa\xbc\xa9\x57\xe9\xfb\x78\x63\x8d\x63\xe9\xe3\xe6\x66\x89\x6d\x7b\x96\x96\x9b\x09\xda\x5f\xc7\x8c\x26\xd4\x02\x8e\x8c\x5c\xdb\xf8\x36\x2c\x0a\x30\x5a\xc6\x8d\x35\xb2\x2b\xda\xf7\x71\x5d\xc4\xe2\x50\x46\x6e\x1d\x11\x7d\xd5\x86\x8e\x99\xa2\x08\x86\xff\x57\xf3\x3e\x9a\x9b\x0c\x00\xed\xb0\x13\xbe\xdb\x7d\x5f\x42\xeb\x1a\x24\x52\xf3\xc0\x29\x81\x18\xee\xd4\xc9\x20\x4a\xc0\x47\xa9\x95\xbc\xbc\xe5\x69\xd6\x94\x9d\xa3\xde\x1e\x91\x3d\x91\x91\x21\xe6\x58\xc1\x3b\x64\xad\xa1\x33\xc7\x9b\xa8\x63\x4e\xc3\x04\xfd\xa6\x82\x67\x0b\x79\x48\xe1\xbd\x5b\xfb\x63\xce\x4c\x92\x43\x34\x69\x86\xc9\x8c\x07\x7e\x3a\xf5\xc8\x8d\x58\x28\x1f\xcb\xd4\x21\xaf\xa1\x34\x0a\xd5\x5f\xae\xf8\x73\xb1\xd0\x3a\xb6\x86\xcc\x57\x28\x8b\xd5\xcd\x3f\xed\x1f\xb7\xba\x8f\xdb\xca\xc4\x73\xd1\xdc\x5d\x81\x38\xab\x2f\x97\x69\xfe\x58\x26\x06\xcd\x81\x6a\xac\x03\x80\x34\x12\x01\x7e\xe7\xd9\x26\xef\x0b\x0f\x57\x20\xd3\x23\xcf\x26\x79\x94\x58\x45\x51\x6c\xa1\x39\x28\xfa\x64\x7f\x06\x3f\x42\xeb\xef\xc9\x46\x0a\xdc\xef\x3a\x89\x31\x35\x28\x79\x26\x1f\xe1\x63\xfb\x96\xe6\x8b\xd3\x09\x78\xd9\x91\x26\x0f\x24\xd9\xdd\x5f\x77\x2e\x8f\xd1\x16\x6b\x0d\x29\x97\xbf\x9c\x1d\xd7\xcc\x4b\x38\x42\xbb\x1c\xcb\xed\x1b\xe4\x33\xa6\x23\xf3\xb4\x44\xfc\x33\xfc\x9c\x91\x2b\xd4\xcc\xa7\x04\x4d\x6c\x95\x56\x92\x97\xea\x05\xfe\x8d\x35\x00\x1d\x5e\xce\x35\x4b\x34\xca\x1e\xa9\xb4\x42\xee\x9b\x26\x87\xa7\x4b\x7c\xad\x66\xbe\x0a\xd0\x0f\x80\x5c\x99\xf4\x89\x4b\x8b\xb3\x20\x10\x31\x73\x53\xf7\x73\x55\x5f\xcd\x82\xd0\x74\x78\x97\xef\x3d\x15\x23\xc5\x08\xcd\x02\x41\xb1\x9f\x9a\x79\x94\xf3\xe4\x0b\x32\x12\x08\x9c\x80\x35\x54\xf5\xa6\xba\xe7\x1f\xe7\x2e\x24\xc0\x88\xf6\x71\x4f\x5a\xf2\x0e\xe6\xbb\x3c\x00\x26\x0b\x47\xc9\x38\xc3\x77\xd5\x0d\x2c\x46\xdb\xfd\xd5\x85\x12\xa0\x82\x2c\xdb\x15\x7f\x42\x3e\x4a\x0e\xb0\x30\x0e\x07\x72\xa4\xfb\xd3\x64\x7d\x64\x91\x6f\x68\xbb\x78\xf9\x3a\x4f\x57\xd3\x36\x91\x08\x99\x36\x8e\xab\xf1\x34\xdc\xe5\x23\x6e\x08\x64\x8e\x85\x32\x29\xdc\x37\x28\x47\xe5\xb6\xae\x1d\x18\x69\x35\x05\x39\x1f\x2e\x23\x2c\xd2\x31\x52\x12\xc9\xe2\x78\xe2\x75\x2a\x32\x08\x02\x07\x49\x63\x31\xf7\xe8\xb0\xba\xc6\x9f\x5c\x95\x71\x8e\xdc\x4d\x70\x4c\xeb\x17\x90\x45\xa9\xa6\x60\xa4\xf9\x75\x9c\x31\xed\xf3\xb0\xa7\x53\x32\x9c\x6d\x9f\xaf\xfd\x2c\xd1\x1c\x03\xd2\x4f\xe5\x2b\xcf\xad\xff\xeb\xf0\x6d\xee\x81\x79\x1c\x63\x6f\x57\x6f\xfd\x4f\xcc\xe0\x79\xcb\x76\x09\xad\xb7\xb8\x08\x14\x4d\x29\x61\x96\xbf\x66\x72\x4f\x11\x7b\x32\x71\x2c\xa8\x13\x72\x31\xcd\x84\xe4\x4c\x0e\xca\x1c\x3c\x43\xe6\x6a\x8f\x4a\x8f\x42\x70\x51\x91\x78\x25\xa8\x75\x01\x53\xea\xe3\xf7\xed\x0e\x81\x80\x1e\x8c\x6c\x8c\x64\x0a\x5c\x83\x30\x61\xdc\x14\x23\xf2\x73\x3b\x77\x53\x09\x4f\x7a\x5b\xc8\x94\x67\xa6\xf2\x74\x80\x90\x1b\xbf\xa0\x92\x01\xc6\xcc\x97\x46\x8f\x7b\x21\x8b\x32\x1f\x3a\xeb\xac\x35\x6c\xed\x06\xb9\x2d\x8e\xf0\xa4\x1f\x78\x7e\xbe\x4f\x73\x98\x2b\x3d\x9f\xc6\x43\x19\x70\x1e\x53\xb7\x42\x5b\xf9\x47\x53\x2d\x73\x65\xb7\x66\xa0\x13\xdd\x89\x2e\x17\x15\x6e\x18\x69\x05\xbd\x74\x72\xdf\x54\x33\x61\xd0\x6b\xad\x87\xd3\xae\x4a\xf3\x0a\x73\x9a\x69\x29\x4c\x48\x17\x25\x0a\xea\x2f\x73\xc0\x4f\xa6\x15\x89\x88\xdb\x26\x4e\xd6\x1c\x5f\xd4\x75\x5f\xf7\xa3\x13\xcf\x0b\x59\xec\x72\xf6\x79\x53\x3d\x43\x39\x4c\x88\x25\x5e\x20\x64\xe0\xa4\xfa\x40\xed\x06\x09\x97\xcf\xb3\x2d\x89\x17\x0b\x9c\xe3\x9a\xa7\xd9\x92\x8f\x48\x5c\x74\xe2\x09\x13\x77\x52\x70\xca\x0a\x13\x8f\xec\x86\xe2\xf8\x32\x7e\x0c\x64\x98\xea\x69\x1d\xe5\x22\x47\xd0\xfc\xb5\xbc\x4c\x77\xa6\xc6\xfc\x62\xdd\x33\xcc\x75\xd4\xfd\x6e\xa0\x25\xbe\x34\x5e\x2d\x66\x90\x4f\xb3\x86\x42\xe2\x4b\x69\xe5\x12\x31\x55\xfc\x9d\xe7\x02\x7e\x5e\x5e\x2a\xd0\x84\xe9\x41\x35\x1d\x16\xe6\x4c\xde\x86\x78\x01\xee\xa3\xf7\xc5\xeb\xfa\x22\x50\x9f\x84\x24\x66\x46\xbe\xae\x6c\x2f\x52\x8f\x8b\xd2\xfe\x98\xb4\x15\x5d\x24\xf4\x28\xc7\xbe\x62\x12\x79\x11\xb5\x83\x14\x15\xab\x2e\xf0\x5f\x9f\x60\x68\x92\x48\x29\xe4\x76\x3d\x72\x07\x82\x39\xb9\xeb\xc6\x84\xe1\xb0\x7b\x48\xf3\xf4\xc1\x6c\xd0\x26\x90\x7e\xd5\x9a\x9f\x61\x71\x18\x6c\x38\x49\x4c\xc1\xd4\x47\xf2\xaa\x82\xf2\x66\x12\xad\x4a\xe2\x38\x8c\xfc\xbe\x1c\x65\xa8\x16\xa3\x93\x58\x07\x18\x27\x1f\xe5\xcf\x66\xd7\x84\x84\x71\x97\x20\x91\x6f\xf3\x7c\xf5\x57\x06\x31\x93\x09\x62\x94\xac\xdb\xfb\xbc\x7e\xd9\xaf\x77\x5f\xdb\xff\x2e\x5e\xee\xff\xee\x09\x80\x75\x92\x28\x4e\xf9\x68\x96\xcf\x28\x5c\xeb\x24\xd1\x5c\x74\xd9\xf7\x1f\x65\x7a\x45\xec\x5d\x27\x1c\x38\x86\x27\x32\x5e\xd5\x7b\x3b\xf2\xf6\xaa\x4f\xfb\x26\x82\x32\xf3\x68\xed\xfb\xdc\x5a\x1e\x6f\xd5\x1d\x0d\x8d\x1a\xf0\x91\xff\xdc\x42\x86\x78\x8e\x4d\xfe\x5c\x82\x4c\x7b\x1a\x79\x9d\x08\x16\x8b\x31\xd9\xd4\x0a\xaa\x3a\xcd\x4d\x24\x76\x64\x7b\x27\x82\x4b\xa4\x40\x59\xac\xbe\x6f\xb6\x4f\x2f\xdb\xfd\x62\xb5\x7a\x59\x6f\xb7\xdd\xb5\x04\x73\x1a\x8f\xd6\xa5\x6a\x3f\xd9\xff\x34\xa9\x7c\x43\xd0\xb5\xa9\xc5\xb6\x8d\x65\x12\x22\xf9\xd2\xdd\x6a\xb9\x90\xd2\xa3\xdd\xef\x40\xd1\xee\xc6\x00\x55\x70\xd7\x6d\xea\x09\xf8\x94\xaa\x61\xa9\xea\x43\x9a\x5f\xe9\x39\x20\x09\x52\xba\x1d\xd3\xfc\x26\x55\xa8\x9b\x71\xca\xd2\x6e\x47\x4d\x80\x06\x78\x6f\x23\x85\xf2\x36\xb8\x47\x28\x44\x4f\xca\x8f\xcb\xe0\x95\x35\x3d\xd1\x22\xc1\x85\xba\xfd\x3a\x37\x16\x6c\xbb\x76\x86\x21\xf7\x7c\xa3\xef\x79\x06\x5e\x3e\x69\x8b\x6b\xe8\xbb\x9d\x07\xc2\x88\xb2\xb9\xb2\xd4\x77\x32\x1f\xf2\xe3\x81\x8d\x41\xa2\x7f\xe5\x3a\x89\x53\x16\x31\x36\x04\xc9\x6c\x6a\x38\x6e\xd4\xf8\x7b\xf1\x90\x28\x61\xec\xdb\xf7\x54\x39\x37\x60\xc4\xa9\x30\x7e\x27\x1e\x79\x5e\x00\x36\xb5\xb6\x3c\xf0\x76\x2d\xb6\x13\xaa\xbb\x66\x04\x8c\x1a\x1a\x9c\xe6\x6f\xa4\xe7\xea\x7b\x8f\xc7\x3c\x4e\x98\x63\x6a\x84\xdc\xe2\xf9\x4c\x15\xe5\x9f\x70\x65\xb7\xe6\xb1\x88\x05\xe9\xd5\xf5\xb5\xc9\x1c\x8c\xdb\x30\x8f\xa0\xa5\xbe\x6d\xd7\xe8\x1a\x5e\x8b\xf2\xfc\x38\x21\x82\xd5\x9c\x85\x5c\x74\x35\xaa\x66\x8e\xdf\x16\x23\x62\x45\xd7\x30\x16\x46\x7d\x3b\x2b\x2a\x78\x38\xdf\x5d\xb8\xef\x9c\x09\x10\x64\x96\x32\x74\xf2\xf0\x4c\x87\x8e\xe2\xd2\xf1\x26\x4f\x57\x5a\xdb\x32\x09\x8d\x18\x11\x66\x88\x2d\x55\xc7\x7c\x9d\xb9\xe6\x89\x04\x35\x52\xf5\xba\x6d\x72\x28\x3b\xc7\x85\x27\x40\x59\x34\x08\x01\xcd\xf0\x11\x8d\xdf\x98\x07\x1c\x0b\xd6\x38\x2e\x48\x4f\xfa\x66\xbb\x73\x55\x8a\x93\xbe\xe1\x9c\x20\x0f\x4c\xbe\xe4\xb9\xf9\x88\x98\x8b\xc6\x7a\x24\x77\x7b\xe1\x69\x8c\xc4\x1c\x4d\x96\xec\x87\xc9\x92\x55\xdd\x61\x9f\xe2\xc7\xe2\xf8\xe8\x83\xba\x54\xcd\x05\x0d\x31\x55\xe4\x56\x9b\xed\x45\xc9\xf8\xa4\x27\x44\x1c\x92\x01\xc7\x42\x6b\x09\x99\x08\x5d\xe7\xb7\x4c\x3d\x18\x2e\x03\x0f\xf7\x6a\x05\xef\xbe\xd9\x3e\x83\xe7\xce\xbc\xe5\x92\x29\x19\x76\x55\x13\xd3\x58\x5d\x7b\xa9\xdf\xa0\xda\xd2\x5c\x26\x91\xe7\x66\x4a\x37\xd4\x7e\xf0\x77\xa8\x7e\x87\xaa\x4b\x73\x25\x42\xc7\xb7\xfd\xe3\x2b\x1f\x6d\xdd\x1c\x68\x80\xb8\x08\x4c\x25\x39\x79\x71\x7b\x4c\x07\x71\x1c\x1a\x64\xd9\x5d\x3f\x01\x7e\xb3\xd6\x6d\xfe\x59\x84\xc7\x19\x86\x8b\xcc\x2e\x8a\x0e\xba\x18\xec\xe7\x7d\xd7\x0a\x4f\x1a\x0e\x2c\xb3\x04\x1b\x72\xb3\x11\x51\x80\x8b\x03\x0a\x3f\xb0\x7c\x94\x63\xc8\xf4\x64\xab\x75\x61\x28\x11\x44\x1a\x4b\xfd\xab\x8f\xb4\x96\x07\x67\x62\xba\x1e\x11\x01\x18\x78\x86\x68\xce\x0f\xcb\x9d\x0d\x2d\x0f\x32\x5b\x57\x5e\x8c\x84\x06\x6f\xbf\x5d\xba\x75\x59\x10\x46\xa9\xa9\xb7\x31\xd0\x52\xfb\x33\xf5\x7d\x1c\xb2\xf0\x2e\xbb\x9f\x84\x17\x7b\x2e\x39\x50\x3d\xa4\x79\x0d\xea\xb6\x28\x07\x1f\x43\x50\x90\x06\xc8\x5e\x1c\x4f\x19\x4f\xf3\x2b\xf2\x3e\x5a\x84\x01\x35\x6c\xef\xbc\xaa\x11\x3b\xea\x7e\xa7\x1a\x6d\xe0\x31\x1f\xf3\x18\xf8\x21\xc2\x90\xa0\x12\xfc\xed\x7d\xf7\x16\x61\xa2\x31\xeb\x2b\x9a\xf3\x35\x8f\xa5\xe9\xc9\x9d\xb4\x08\x79\x84\x1c\x18\xca\x7d\x2b\xfb\x7b\x14\x1a\xd5\x09\x6e\xd3\xaf\x58\x15\x6f\x97\xed\xe9\xaa\x29\xa2\x28\x0c\x0d\x0a\xbe\xa9\xea\xde\x0f\xf8\xdc\x07\x10\x51\xa4\xb8\x03\x4a\x1a\x64\xcd\x93\xfe\x9e\x56\x13\x32\x15\x2d\xe2\x28\x8c\x4d\xe0\xb8\xcf\x93\x58\x70\xf3\xa4\x61\x12\x20\x99\xd5\xd3\xe3\x7a\xff\xf5\xdb\xe3\xea\x65\xbd\x6a\x8d\xb2\xe5\xcb\xfa\x71\xe7\x2c\x11\x11\xf3\xd0\x29\x63\x2d\x21\xaf\x9a\x12\xd4\xcd\xf9\xcb\xa8\x4f\x62\x29\x7c\xe5\xbc\xb8\x3f\xcf\x72\x58\x55\xe1\x9a\x40\xe4\x75\x4a\xb4\x6b\xb7\x16\xbb\x7b\x24\x24\x61\x7a\x44\xd7\x87\xe0\xa3\x49\x3c\x4f\x24\x8a\x21\xc6\x4b\x34\xe7\x11\xd9\xe7\x4c\xf1\x8e\x48\x94\xd1\xed\x79\x75\xa4\xce\x8b\x11\xc1\xd6\xf8\xc2\x9c\x18\x81\x80\x03\xb7\xc8\x17\x3f\x70\x47\xa8\x44\xb4\x16\x97\x12\x4e\x63\x07\x43\x70\xe6\x61\xe1\xd3\x29\x95\x6f\xe8\x7f\x4e\x60\x33\x82\x2b\xc3\x2a\x6f\x0b\x88\x6e\xcb\x8b\xdd\x51\x08\x22\x90\xdd\xa0\x3a\xa4\x75\x7d\xb6\x14\xc8\xee\x18\x48\x8c\xc9\x3c\x17\x15\xe2\x33\x32\xa8\xaf\x4e\x0b\xe9\x99\xa4\xa4\xc0\x48\xc9\x1e\x41\x06\xf3\xbb\xa7\x90\x9e\xd1\x5b\xb4\xba\x28\x06\xea\xec\xee\x09\x84\x10\xee\xa4\x92\xaa\xfa\x26\x55\xaa\x9f\x3e\x40\x80\x7a\x5d\xda\xa0\x3d\xde\x1d\x51\x09\xe6\x23\xd6\xb7\x8b\xdb\x9e\xfc\x58\x0b\x1d\x9b\x2c\x3a\x7e\xf6\xea\x47\xda\x6d\x7c\xd2\x23\x91\x89\xea\x17\xc5\x5b\xd1\xfd\x08\x09\xe6\xb2\xf6\x5c\x29\x57\x81\xd2\x13\x1e\xcf\x4f\x0b\xe9\x7b\x1e\x32\x5c\x2e\x17\xf7\xf7\xad\x2f\xf1\xd7\xf2\xeb\xe2\xf1\x6e\x48\x0f\xa1\xa5\x1f\x08\xdf\x14\x21\xdd\x59\x11\xfb\xfb\x1e\x3f\x23\x7d\xe1\x31\x5b\xb0\x65\xe2\x08\xd7\xd1\xca\xd2\x97\x0c\xf5\xff\xec\x86\x6d\x9d\xed\x8e\xac\xd3\xb6\x0a\xa8\x29\x6b\xfe\x87\x1b\x81\xa7\xa1\x6d\x27\x09\x31\xa5\x05\x59\x29\x47\x45\xe4\x5a\x12\x16\x45\x66\xe6\x6e\x0b\xdd\xba\xd0\x77\xc5\x84\xc3\xbb\x6d\xa3\x10\x53\xb9\x1c\xe5\xf2\x24\xe5\x3a\xb4\x34\x17\x39\x7c\x66\x11\x49\xaa\x03\xac\x06\xb6\xc5\x8e\x8d\x50\xe9\x7b\x75\x3b\xe1\x4b\xd0\x32\x0c\x15\x86\xca\x06\x6b\x81\x0c\x43\x93\x64\x16\x3d\xe9\xf0\xb8\x77\x22\xa2\xfc\x6e\xa5\x5f\xb8\xd3\xa2\x48\x23\x0e\xf8\xf9\x29\xa0\xdd\x6f\x89\x21\x1c\xba\x49\xd5\x73\xc6\xe5\x35\x20\x90\x8c\xc0\x10\x3f\x6e\x79\xdd\x65\xd8\x65\xec\x25\x8e\x14\x70\xe5\xb2\xe3\x53\x64\xf8\xd5\x4d\x5a\xc6\x81\x46\x75\xa2\x93\x85\x9a\x2f\x79\x96\x09\x2e\xdf\x46\xb3\x5b\xc6\xcc\xb0\xa8\x6d\x1d\x3f\xe3\xb8\x7b\x62\xe9\x3b\x68\xfe\xb7\xdc\xa6\xd2\x4d\x8a\x68\x57\x9c\xfc\xd0\x73\x8f\xca\x7c\x93\x22\x05\x95\xfe\x96\x02\xb5\x96\x2c\x94\xb8\x7c\x6f\x1e\x17\x7f\x0f\xe6\x92\x64\x9c\x8c\x14\xe3\x0c\x44\x69\xfa\xd9\x18\xd7\xae\x6a\xe8\xb6\x04\xd8\xe6\xfc\xad\x1b\x5e\x49\xc8\x30\xcf\x52\x1b\x45\xff\x6d\x91\x6d\xe6\x85\x17\xb4\xe4\x92\x86\x81\x5b\xd2\x5f\xf8\x1b\x0c\xd0\xaf\x92\x83\x4a\x0c\xdd\x06\xce\x6b\xbb\x90\xb8\xa3\x22\x4c\x98\xcd\x06\x9e\x06\x91\x42\x29\x18\xc1\xe8\xc4\x96\xe7\xb2\xf8\xf7\x38\x4a\xe5\x9a\x88\xd0\xb1\x93\x6c\x1d\x66\xad\xdc\x9d\x4f\xfd\x35\x84\x61\x37\xd8\x67\x45\xf1\xd6\x9c\xd0\x20\x76\x11\xcc\x4b\x05\x1c\x2d\xa5\x27\x31\x26\xac\xe0\x54\x82\xec\xfd\x7d\x29\x75\x80\xee\x99\xe0\xf9\xfe\x82\xdb\x53\x4b\xe5\x4b\xac\x54\x79\x4b\xb3\x6c\x93\x57\xf5\x55\x62\x14\x2d\x15\xf7\x63\xfb\xba\xbf\xcb\xa6\xa2\xa5\x52\xca\x8b\xfa\x12\x97\x97\xe5\xbc\xcd\x2e\xc1\x33\x84\xfd\x9d\x73\xaa\x9e\xf9\xf9\x08\x79\xdd\x69\x79\xbb\x86\x84\x62\x78\xee\x54\x9c\x9a\x8c\x97\x69\x7d\xb6\xb2\x7d\x33\x54\x6c\x5a\x02\x63\xf1\xb0\x22\xd7\x58\x07\x9f\x85\x21\x2f\xc1\x39\xca\x0b\xb4\x34\x5a\x1e\x88\x28\xfa\x96\x8b\x02\x91\xcc\xed\xc5\xe6\x5f\x47\x79\xdc\xe8\xce\xa3\xee\x45\x97\x6e\x54\x1e\x07\x5c\x35\xd2\xbc\x82\xf2\x0a\x1c\x46\x79\x40\x71\xf3\x69\xf2\xf4\x3f\x06\xaf\xdd\x3d\x89\x0f\xca\xf2\x0d\xd5\x0f\xbc\x7c\x4d\xf3\xdb\xa2\xfc\x9e\xca\xba\x28\xcf\x36\x75\x37\xa0\x70\xc4\xe6\x98\x69\xba\x7f\xba\xdb\x77\xa6\x48\xbf\xdd\x8c\xf5\x23\xdc\x39\x3a\xc1\x35\x03\x09\x63\x31\x0a\x38\xe0\xd6\xd3\x2a\x90\x80\xe8\x64\xdd\xe4\x72\x51\x96\xfc\xbc\xc9\x17\xe5\x2b\x2a\x8e\x54\xd3\x44\xb1\x22\x2a\xc6\x8c\xdb\x8f\x1f\x8b\x87\xe7\x32\x95\x28\x39\x58\xb6\xbe\xf8\x85\x5f\x3f\xe9\x03\x02\x80\x81\x92\xfd\xde\xc8\x11\x7e\xe6\xef\x29\xaa\x02\xf4\x6c\x6f\xb2\x06\xb6\x6f\xe7\x55\xc9\x5f\xbb\x0d\x4a\x85\x1e\xc3\x00\x1b\x96\x26\x3c\xa1\x24\xd9\xc4\xda\x52\x21\x65\x48\xb6\x70\x3c\x63\xf0\x66\xb8\xdb\xa8\x30\x32\x62\x7d\xf6\xce\xbb\xe2\xb1\x39\x2e\xd3\x7a\x2a\x86\xaf\x55\x18\x1b\xc1\xc3\x0a\xf8\x50\x50\x4a\xab\x90\x19\x24\x34\xfc\x3c\x61\x42\xd1\x14\xcc\x57\x43\xcc\x88\x8a\x02\x1d\xc6\x9d\x1c\xe5\x81\x97\xaf\xb0\x3f\x05\xdd\x51\x06\x28\x93\x9e\xc3\x87\xcd\x19\xbb\x03\x5a\x62\xc0\xa8\x9d\x23\x59\x96\xe2\xd3\xaf\xa5\x33\x32\x54\x4c\x7d\x44\xb5\xa4\xf9\xde\x0a\xf6\xa1\x85\xbc\x3f\x0d\xca\x8e\x54\x2c\x3c\x62\x48\x12\xe4\xdb\x2a\x7d\xef\x86\x2a\xe3\x86\xde\x02\xc1\x39\x45\x7e\x3e\x16\x4d\xb5\xe4\xa7\x49\xd7\x25\x2a\xc4\xa0\xd9\x03\xaf\x4b\xf8\x29\x87\xf8\xfd\x6b\x44\xbc\x5a\x71\x96\x78\x7d\x26\xf0\x0e\xf2\x97\xc7\x3b\xa7\x69\x35\xcb\x9f\xa0\x84\x2f\x71\xde\x7c\xa4\xf5\x61\xd5\x71\x28\x69\x25\x68\x84\xe6\xb4\x06\x18\xb9\x92\x4a\x92\xc8\x4b\xba\x5b\xac\xc6\xe4\x21\xae\x4d\x9c\x60\xa8\xd4\xe0\x3c\x16\xce\x27\xef\xe9\xc7\xb4\x02\x4f\x1b\xb2\xad\xa7\xfb\xf5\xfe\xfb\xfa\x71\xf5\xf4\xe2\x6e\x0d\x61\xc4\x2c\xae\x6a\x86\x3e\x6c\x98\xb6\x52\x9a\x87\x56\xaa\x08\x6e\x1a\x27\xd1\xab\xc1\x57\x1a\x6d\xc0\x8c\x57\x06\x51\x65\xf8\x45\xcc\x6e\x37\x10\x5b\xd7\xe0\xeb\xd0\x61\x4a\x4d\xf0\x7c\xb9\x58\x2d\x6c\x2c\xa6\xfa\xca\x4b\xd5\xc7\xda\x21\x20\x14\x54\xaf\xb8\x68\xa9\x6e\xfb\x72\x4b\x08\xb8\x40\x46\xad\x8e\x52\x72\x76\x5f\x84\x40\x86\x68\x15\xdc\xec\xb6\x0f\xc3\x19\x01\xc4\x0f\x71\x43\xe1\x86\xf1\x6a\xdd\x3f\x26\x91\x3e\xc2\x5f\x1e\x16\x8f\x5f\x17\xbb\xdd\xe2\xf1\xf9\xe5\xe9\xaf\xbf\xe9\xee\xeb\x76\xe7\x9a\x50\x5f\xa3\xb3\xc2\xe5\x7f\x9a\xd4\x84\xbe\xaa\x51\x3a\x04\x28\x21\xca\x94\x25\x39\x9a\xa3\xf1\x90\x03\x4a\x00\xd7\x40\x6d\x74\x64\x2b\x4b\x82\x55\xb5\x4b\x6d\x8e\x56\x49\x7b\xb9\xef\xbc\xb5\x3d\xdc\x29\xc0\x31\xb7\xd7\x6e\x72\x66\x75\x40\xb9\xb6\x6e\x53\xfe\x34\x22\x00\x71\x42\xd0\x0e\x35\x44\x03\x5f\x79\xae\xb2\x6b\xe9\x7a\x88\x65\x80\xa2\xa0\x2b\x8e\xa2\xdc\x95\x43\x0f\x74\xaf\x17\x2b\xc3\x9e\xf4\x00\xca\xe6\x96\x86\x7d\xcb\x88\xc0\xe0\xab\xe5\x88\x1a\xf7\x0c\x93\x31\xb3\x02\x8e\xc3\x72\xe7\xb9\xd8\x1d\x24\x91\x8f\xc1\xea\x21\xdd\x72\xdb\x5f\xad\xc3\xba\x2c\xba\x4b\x72\xeb\x40\x63\x18\x75\xfd\x53\x1e\xba\x03\xcc\xd7\xae\xc8\xae\x38\x62\xf0\x7f\x93\xf7\xd4\x03\xc0\x13\x81\xbe\xf2\xf2\x90\xe6\x87\xe5\x6f\x4d\x7b\xe0\x52\x52\x9b\x61\x3d\x16\xf9\x27\x45\xee\x20\x7c\x0f\xd9\xb0\xba\xa4\xf6\xe4\xe2\xa3\xcb\x0a\xdf\xe0\x44\x44\x83\x79\xba\xc9\x68\x11\x24\x46\xb7\x73\xf1\xf0\xf4\xed\x71\xb7\xef\x68\x8c\x34\x08\xc1\xd0\x39\x41\xa5\xfd\x0c\x8b\x54\xc6\x5c\xa0\x9f\x1b\xd7\x20\x79\x64\xf5\x72\x31\xc9\xe2\x86\x61\x17\xd8\xbb\x24\xf1\x76\x27\x82\xa6\x63\xca\xfe\x6a\x8e\xea\x5a\x83\x0a\x28\x06\xb8\xd4\x42\x5d\xb2\xd6\xf4\xab\x14\xa8\x50\x49\x8b\xa3\xdc\x42\xae\x10\x05\x3e\x58\xc5\x00\x48\x20\xdc\x52\x6e\x32\x0a\x23\x0a\x94\x49\xe7\x43\xc8\x69\x5f\x17\xf2\x9e\x2a\x14\xd2\xbb\x74\xb2\x47\x49\x63\xed\x71\xaa\x0c\x03\xec\x6d\xbf\x70\x69\x9f\x31\x39\x24\x41\x78\x4e\x7f\x42\x36\xac\xd4\xf4\x27\xcb\x8e\x0e\x28\xc5\x44\x97\x3b\xe3\xe6\xfc\x0b\xe5\x26\x77\x1e\x98\xf3\x38\x62\xa7\x97\xeb\xa7\x71\x5f\xea\xd6\x09\xb7\x15\xd9\x3c\xcd\xd3\xfc\xf5\x0e\x72\xa8\xd2\x6a\xc9\xbb\xcc\xa0\x26\x89\xb2\x45\x7c\x46\x41\xd7\x6e\x1b\xe3\x24\xa9\x26\x2a\x8c\xad\xf4\xb1\xa9\x85\x9c\xe1\x00\xc5\x56\xd0\xc9\x84\x54\x75\x06\x97\x68\x4d\x4d\x3d\xcf\x31\xa9\x59\xcf\x62\xa8\x28\xe0\x1a\x05\xc0\xed\xc7\x43\xbe\xdb\xa9\xb2\x89\xd6\x94\x48\x2c\x8a\xde\xdc\x2e\x1f\x6f\x86\xcb\x89\xa6\x32\xf1\x7b\x2c\xfc\x14\x36\xa0\xa9\x32\x6a\x9c\xc8\x8f\xd4\x54\x87\x7e\x72\x68\xaa\x7d\x2c\xb4\x29\x4a\x2e\xb3\xf4\xbf\xb0\xff\x4f\x03\xe5\x45\xdc\xd0\xfc\xf9\x5f\xdf\xda\x7b\x3a\x64\x1a\x87\xce\xb1\xc8\xeb\x43\x40\x6d\x50\xae\xf3\xe8\x75\x2c\x84\x67\x94\xf9\x74\x93\x2b\x23\x67\x33\xcb\x9e\xa1\x19\xe3\x4c\x75\x62\x0b\x13\xc4\xb3\x66\xcc\x70\x53\xbc\x14\x67\x9e\x8d\xe5\xf4\xb5\x66\x89\x44\x12\x1e\x93\xc0\x72\x2a\xc0\x73\x53\x58\x33\xa9\x93\xbe\x69\x3f\x6c\x93\x00\x2c\x5d\x6e\xd9\xee\x14\x57\x28\xae\x74\xc2\x39\x2e\x92\x26\xbe\xe0\xca\x7f\x8a\x09\xfb\xb8\xd6\xc2\x57\x18\x75\xf9\x70\x90\xca\xf1\xda\xd7\xcf\x54\x2d\x80\x22\xa1\x8e\xd5\x6c\x4a\xff\x0b\xff\x1f\x6d\x6f\xd2\xdd\x38\x8e\x6c\x8f\x7f\x9d\x5a\xf4\x02\x00\xe7\xa5\x2c\xcb\x4e\xbf\xb2\xd3\x6e\x4b\x59\x59\xdd\xef\xbc\xa3\x83\x21\x20\xb3\x2c\x91\x6a\x92\xb2\x53\xfd\xe9\xff\x87\x11\x00\x27\x51\x99\xf5\x5b\xfc\x17\xdd\xce\x12\xc1\x09\xc4\x10\xc3\x8d\x7b\xb1\xdc\xd4\xa3\xed\x4e\x0e\x28\xf7\xd3\x30\x91\x35\xca\xe0\x3a\x6b\x01\x7d\x59\xc2\x65\x74\x76\x49\x7f\x33\x1b\x03\x8b\x3b\x79\xdb\x0f\x99\x23\x91\xd4\xbd\xec\x49\x1b\xac\x55\x0a\xcb\x14\x9d\x2a\x97\x2c\xde\x5b\x13\x3e\xff\xef\x68\x24\x71\xc6\x18\xb7\x24\xbf\x03\x2e\x73\xd7\x8e\x76\x62\x75\xbd\x1a\xaa\xf0\x4f\xd2\x9e\x2e\x2c\x0e\xc4\xef\x65\xd5\xbc\xed\xa1\xae\x7d\xa1\xc1\x60\x03\xe4\x8c\xf1\x28\x40\xa1\x25\xe2\x91\x25\x25\x18\x7f\x48\x07\x59\x27\x65\x55\x3b\x39\x51\xb3\x29\x1f\x9c\x35\xcc\x19\x13\x49\x8a\xa2\x93\xe8\xc9\xbb\x0c\x89\xf0\x07\x83\x30\xb3\x98\x58\x2e\x4b\xb3\xbd\x39\xc3\xf6\x7b\x59\xed\x4d\x77\x34\x65\xa8\x00\x97\xd7\x2f\xa7\xe3\xf1\xbc\x3e\x96\x55\xd3\x3d\x55\x20\x35\x5a\xd9\xfa\x54\x37\xe5\xe1\xce\x87\x58\xa6\xcb\x55\x67\x10\xb6\xa7\x80\x30\xce\xa9\x98\x74\x64\x28\xc8\x41\xec\x96\x29\xd7\x9d\xbd\xd0\x21\x67\x2c\x8a\x23\x8f\x30\xdf\x9c\xaa\xa2\xfc\x18\x17\x9c\xb7\x2d\x32\x85\x4c\x91\xa6\x44\xff\xe9\x70\xec\x02\xf8\x9c\xb1\x58\x86\x68\x40\x39\xd9\x2c\x84\x6a\xcd\x16\x8f\x70\xc6\x12\x21\xb1\x34\x63\x0d\xcd\xe9\xe8\x9c\x8f\x4b\xf4\x47\xdb\xd0\x26\x18\x95\x83\xaa\xf5\x2d\xc6\xc7\x52\xa1\xac\xf5\x81\x83\xa6\xac\x6e\xf2\xfd\xfe\x4f\x03\x8d\xcc\xf7\x97\xdd\xd4\x8f\x8a\x34\x09\x12\x6f\xc9\x6e\xcb\x82\x34\x7d\x57\xff\xb9\xa1\xed\xc7\xbf\x4d\x2a\x85\x8c\x06\x52\x85\x8f\x54\x65\x8c\x0c\x22\xe3\x77\xc9\x62\x8d\xe1\x1a\x6f\xf8\x5e\x80\xa4\x26\xef\x9e\xa5\x92\x6c\x55\x3f\x35\x26\xd7\x93\x0c\x1c\xe1\x27\x12\x72\x50\x84\x63\xca\xea\xf8\x37\x60\xea\xed\xa5\x38\x0d\xb0\xf6\x25\x7a\x2d\xa5\x07\x53\x5f\x7d\x38\x19\x01\xa6\x24\x0f\x98\x63\x1a\xc3\xee\xdb\xc3\x3a\xe2\x8e\xdf\xff\xf5\x62\xa3\xff\xd9\x54\x94\x5a\x92\x4c\x46\xdb\x97\xdd\x56\x8e\x07\xc0\xba\x24\x58\x59\x39\xea\xf5\x7e\x1b\x6a\x1b\x58\x2f\xc1\x8f\xd0\x62\x6f\x2c\x72\xc6\x54\xca\x91\xb3\x68\x5f\x4a\xd3\x95\x6a\xb5\xbf\x6b\xc0\x0c\x5d\x53\x7e\x81\x1f\xe3\x8b\x29\x60\x99\x1b\xe2\x94\xdd\x9f\xe6\x32\x38\x63\x3a\xa6\x7d\x2f\x3f\x96\x2f\x7b\xd9\xd8\xb2\x3a\x0c\x6c\x2e\xdf\x28\x95\xc6\x09\x91\x2e\x17\x87\xd2\x9c\xf6\x27\x97\xbc\xf0\x0d\xb2\x14\x17\xf1\x76\x39\x70\x01\x11\x7f\xc4\x98\x8c\x7b\x1a\xa5\xbe\x72\x8d\xa2\x1b\x9c\x31\x93\x00\x06\x6c\xef\x4e\xfa\xfd\x4e\x6a\x50\x65\xf9\xde\xd5\x5c\x70\xc6\x80\xa7\x23\x8d\xd9\x2f\xe5\xfe\xba\x2a\x8b\x3f\x27\x24\xdd\x4e\xf8\x80\xea\xbc\x35\xf2\xbc\xcd\x0f\xdb\x9a\x8a\x91\xfb\x0b\x1b\x46\xd4\xe8\xbd\x8f\x84\xa4\xba\x54\x19\xf8\x13\x67\x86\x33\x66\x05\x31\xa8\x50\x2d\x49\x07\xf2\x5f\x18\x93\x4f\xc1\x3b\xd8\x1a\x12\x8a\x2a\x36\x50\x1d\xf2\xa2\x5d\x34\x65\x75\xbe\x24\x6c\x6f\xdb\x26\x11\x0a\x24\xac\x6e\xbf\x79\xc0\x53\x2f\x75\x8e\xc7\x65\x32\x2c\x41\x99\x87\xba\xfa\xc6\x86\x09\x97\xd9\x53\xe5\xc7\x74\x17\x1f\x0e\x95\x76\xb5\xc3\x38\xb0\xb3\xc3\x1d\xb2\x7d\x3c\x56\x38\x0b\x48\x3b\x12\x87\xb5\xcf\x3e\x3f\x14\xb7\xf2\xec\xd7\x71\xce\x93\x08\xd3\xb9\x37\xcf\x5f\xbf\xad\xb7\xb7\x8b\xcd\x6a\x3d\xb9\x08\xcf\x22\xd1\x55\x9e\xcd\x16\x69\xf8\x86\x32\x0e\xa2\x6e\xdb\xec\x93\x26\x77\x00\x97\xe3\x98\x07\xd2\xe0\xd2\xf9\xbb\xcc\xab\x72\x90\x40\xe1\x8c\x87\xc2\xb1\xb4\xa0\x55\x4b\x1f\x67\xbc\xa3\x70\xdf\x52\x12\x2b\x0a\x86\xed\xdc\x94\x29\xdd\xbc\xb9\x85\xa2\x3c\xe4\x45\xc7\xe7\xce\x19\x8f\x44\x16\xb5\x43\x08\x03\x7c\x3d\xd7\x09\x67\x3c\x4e\x12\xca\x19\x20\x68\x3d\x58\x75\x2b\x00\x8f\x25\x05\xc3\x6f\xe4\x3e\xff\xe8\x7e\x04\xc2\xde\xaf\x8e\xf9\x1e\x8e\xb5\xdf\xa3\x78\x12\x66\x18\x00\xbd\x2f\xbb\xf3\x13\x87\x12\xf9\x02\x79\x45\xa5\x91\x6f\xf9\x71\x49\xdc\xf0\xf3\xab\x1c\x4f\x79\xa2\x06\x49\xba\x95\xeb\xc7\xaf\x2e\x41\xd2\xb6\xb0\x22\x73\x41\x69\xca\x29\xf2\x78\xec\x5f\xb8\x76\x59\x1c\xe0\x1a\x44\x3d\xe9\xcb\x1f\x46\xdf\x2f\x9d\x7c\xc5\x2c\x76\xd4\x17\xb4\xa3\xbc\x82\xad\x27\x5f\x2e\x33\x3a\xca\x7a\x17\xf2\xc2\xa2\xe3\x8c\xcb\xc0\x7a\xc9\x80\x07\xfa\xb6\x83\x05\xfe\xf9\x08\xc5\x6f\xc3\xc6\x69\x8a\xf6\xe8\x63\xb9\xbb\x81\x02\x6c\xae\x73\x59\x9d\x5f\x64\x6e\xc6\x73\x8d\xcb\x8c\x27\xe0\x44\x2c\xb0\x6a\xf7\x76\xbc\x9b\x5e\x5b\xe8\xe7\x87\xab\xb4\x1c\x7d\x64\x8c\xe9\x57\x39\xd4\x23\xb3\x8b\xab\x98\x34\x3d\x5f\x91\x01\x6d\x45\x20\xea\x51\xf1\x9f\x6f\x98\x50\xa5\xce\x87\x6a\x46\xa3\x58\x65\xa4\x20\xda\x2e\xe6\x54\xe4\x7e\x5f\x95\xa7\xe3\x0c\x8e\xc6\x9d\xa0\x25\xc7\xec\xc8\xbf\xca\x52\xc9\x1b\x39\x40\x77\xf8\x4b\x9a\x88\x2c\x28\xe4\x87\x59\xb7\x3b\x92\xb9\xcb\xf7\x30\xc1\x77\xb5\x0d\x33\xaa\xec\x7b\xf3\x22\xb8\x93\x42\x13\xce\x38\x70\x2b\xb4\x33\xba\x7d\x86\xe7\x57\x60\x98\x51\xff\x41\x40\x8c\xf1\x15\x7c\xe4\x1f\x9d\x9e\x49\x7b\x20\x92\x58\x76\xd8\x8e\x8f\xd2\x36\x7a\x1c\x3e\x6d\x1b\xc4\x14\x4b\x3b\x56\xd0\xee\xde\xdf\x8a\x7d\x7e\xc8\x1b\x30\xe3\x62\xbb\xb6\x61\x9a\x61\x96\xca\x96\xd5\x50\xac\xd6\x1d\xb5\x3c\x40\x80\x3d\xd1\xd7\x0d\x64\x51\xe6\x58\x60\x39\x13\x2c\x8c\x71\xd2\x36\xe5\xe7\x00\xe3\xce\x99\xe0\x71\x3a\xc0\x22\x63\x21\xd1\x4c\x40\x96\x33\x21\x54\x80\xa1\x89\xa3\x8b\x6f\x8d\xa9\x41\x5c\xa3\xc0\x44\x88\x35\xc6\xe4\xd8\x2d\xe8\xd6\x34\x6c\x5f\x4a\x2c\xf4\xc0\x1e\x15\x61\x14\x11\x96\x5a\x16\x79\x73\xde\xe2\x27\xf5\xc7\x22\x37\x7d\x60\x0f\x7a\xa8\x69\x78\x2d\x6f\xdd\x9e\x92\x2a\xdc\xe1\x5c\xfe\xe8\x57\x73\xc2\x9d\x95\xf0\x20\x08\x7b\x63\xee\x61\xf9\x4c\xf0\xb4\x2b\xad\xd3\x08\x23\xf2\xbe\x1c\x84\x7c\xac\x71\x17\x25\xa9\xf2\x51\x19\x67\xb2\x8e\x52\xee\xe3\x2f\x92\x80\x08\xc5\x08\x06\xbc\x6e\x2a\xa2\x9b\x1e\xdf\x39\x15\x0a\xa1\xcd\x54\x0d\xd7\x97\xe0\xb7\x87\x62\x1a\x23\x47\x59\xd5\xf0\x3b\x9c\x3b\x90\x86\xb7\x58\x44\x9a\x6a\x64\x90\x42\x17\xa8\x75\x8d\x7e\x6a\x95\x8a\x14\x48\xa3\xa5\x79\x83\xe5\x59\x41\x45\xc9\x54\x22\xc7\xf4\x49\x2d\xce\x44\xc6\x00\xa1\x0f\x9a\x2a\x27\x9c\x4c\xe1\xcf\x2f\x2d\xb5\xc6\x94\x9a\xcd\x2b\xc0\x64\xf1\x63\xb9\xf3\x26\x7d\xfb\x86\x36\xe9\x64\xbd\x10\x2d\x08\xf9\x25\x2c\x9a\x33\xa1\x33\x81\x34\x0c\x72\xdf\x83\x40\xfd\x21\x88\xa3\x8e\xf1\x7e\x3f\x65\x7f\x77\x8d\x8c\xe3\xb2\x77\xf0\x60\xa2\x00\xa5\xd0\xf1\xf8\x63\x42\x94\x22\x80\xa8\xc9\x0f\x50\x9e\x9a\x45\xd7\xe9\x90\x2a\x67\xa8\xee\xf7\x45\xf9\xe9\x7f\xb6\x96\x21\x16\x94\xb0\x93\xc3\xd5\x30\x60\x59\x82\xa5\x42\x04\x17\x46\xc1\x87\xba\x91\x87\x63\x77\x5c\x92\x3c\xb5\xab\x93\x6a\x3d\xee\x6d\x31\x5d\xd7\x02\xa6\x09\xe3\x58\xa3\x54\x8b\xc9\x1b\x95\x4f\x9e\x39\x60\x20\xb0\xa0\x6a\x53\x95\xd7\x29\x45\xdb\x76\x56\x60\x5c\xd9\x19\x50\xc8\xc4\xe6\xbf\x45\xc0\x43\x0a\xd9\xdc\x3f\xff\x79\x3d\x0a\xdb\xb6\x8b\x89\xd8\x8f\x7c\xbc\xbc\x2c\xd0\xfb\x6f\xcd\x46\xca\x74\xdd\x9c\x2f\x54\x8b\xdb\xb3\xb2\x90\x27\x1d\xce\xe6\xcb\x44\x36\xbc\x6d\x00\x01\x5a\x23\x48\x13\x82\x79\xdb\x51\x5f\x72\x08\x62\x22\x8c\x3e\xd5\x23\x96\x6c\xce\x02\x91\x02\xd6\xdb\xb6\x26\xf9\x5b\x3e\x3a\x2d\x88\x32\xed\x25\x98\x87\x31\x82\x20\x64\x0c\xe9\x42\x30\x8c\x30\x04\x5c\x74\xa0\x80\xb6\x91\x30\x98\x12\x84\xc2\x20\x99\xbf\xac\x86\x14\x74\x7e\x4a\x07\x61\x22\x85\x2f\x1e\x18\x40\x8f\xda\x23\x69\x16\xf8\xa1\x29\x8b\xf7\xdb\x73\x21\x0f\xb9\x9e\xbc\x79\xcc\x95\x15\xa3\xcc\xf5\xee\xca\xf7\x8b\xb3\x08\xa3\x6e\xb9\x2e\x5f\xde\x64\x0d\x34\x53\xba\x2f\x18\x2b\x85\x9b\xc3\xd3\xe2\x4f\xc4\xbc\xad\xbe\x6e\xba\x43\xda\x10\xe8\xd6\x79\x11\x4b\x0c\x61\xcc\x27\x37\x38\x0b\x12\x91\x22\x2c\xaf\x75\x0b\xf3\x62\x77\x77\x42\x5d\xad\xd9\x09\x1e\x24\x11\x25\xc0\xb1\x88\xc8\xc5\x32\xe6\xdc\x86\x20\x49\x58\x4c\x8c\xe4\xad\x7b\xb8\xce\x77\x45\xbb\xfd\xb5\x23\xcb\xaf\x94\x43\x73\x57\xb0\x39\x1f\x20\x48\x24\x45\x44\xa8\x00\xf1\x63\xd2\x95\x69\x9a\x32\x37\x57\x7a\xf5\x92\x49\x45\x3e\x67\x41\xa6\x6d\xa0\x3d\x7f\xf3\x90\x7d\x83\xb3\x40\x82\x41\x82\xa1\xbc\xf6\x49\x23\xcf\x3e\x03\x93\xcd\x38\x50\x2c\x42\x73\xe9\x58\x41\x33\x0d\xcc\x04\x2a\x32\xd2\xf4\x6b\x25\xce\x89\x07\x33\x87\x5f\x6b\x1b\x5b\x86\x9e\x4d\xb3\x7e\xbc\x9d\x9d\xc0\x73\x1c\x69\x9c\x05\x5a\x29\xcc\xea\x40\xf3\x76\x3c\x57\xf2\x90\x77\xaf\xa1\xad\xc4\xdc\x1f\xf1\x20\x90\xc8\xe9\x9f\x93\xe7\x37\x22\x96\xda\x5b\xd4\x15\x16\x09\xd4\x73\xdd\x05\x29\x8f\xfc\xca\x87\x39\xa2\x9a\xa4\x01\xbb\xc8\x58\x00\x86\xe3\xc0\xdc\xee\xa0\x59\xbf\xe7\xfb\xfd\x6f\x43\x93\x3c\x00\x9b\x21\xe6\xba\x03\x92\xfa\x32\xdf\x9b\x33\xc2\x26\x86\xfe\xe8\xe4\x0d\x6d\x20\x53\xaf\x0d\x7d\xaa\xe4\xb2\xdc\x3b\x56\x0c\x4a\x00\xb7\x2d\x32\x11\x4d\xa9\xfe\xe6\xe7\x4f\xc8\x58\x18\xc6\x1d\xef\x06\xd6\x27\xef\x27\x96\x7e\xd8\xda\x4c\xac\xaf\xf1\x90\xb9\xd3\x08\x2b\xab\x7a\xe5\x3c\xe7\x99\xbc\x04\x9e\x18\xa0\xa5\x80\xe4\xa2\xdf\x8e\xb3\xde\xb9\xff\xe0\x21\x4b\x62\xe1\xc2\xa8\xab\x1f\x3e\xe6\xda\xc0\xc5\xc3\x18\xdd\x11\xda\x6f\x9e\xc9\xf4\xf7\x9d\x1e\x32\x70\xd6\xd4\x5b\xf9\x79\x23\xfd\x9a\x13\x0a\x41\x6c\xe0\x3e\x5b\x55\xec\x60\xff\x07\xe9\x37\xf8\x16\x31\x0b\xc9\xe5\xde\x54\x27\x12\xe1\x1a\x4d\xb2\x50\xa4\x49\xec\x62\xf2\xb7\x79\x7d\xdc\x4b\x2a\xa7\x18\xbf\xaf\xd0\xa4\x3e\xb9\x83\xe6\x3b\xc0\xfb\x83\xf9\xe1\xaf\x1f\x18\x02\x3e\xb7\x8e\xdc\x43\xfd\x34\x5b\xc0\xc4\x59\x18\x0a\xc9\x5b\x1b\xe5\xbe\xfd\x1a\xbd\xf9\xe9\x8f\x06\x52\x05\x5e\x26\x1b\x4d\x75\x5a\x54\x2e\x73\x30\x6d\xe3\x48\x92\xe6\xec\x5f\x65\x4e\x65\xe9\xb3\xeb\x5a\x18\x2a\x4a\x66\x9e\x10\x3c\x3c\x72\x7e\xc2\x48\x10\x56\xe1\xa6\x2c\x75\x1f\xdb\x09\xa3\x34\xc6\x58\xe2\xfd\xcd\x72\x39\xfc\xb9\xf5\xe0\x7c\xfd\x7f\x97\x5e\x9e\xd9\x2f\xc3\xc8\x00\xa6\xa4\xf3\x7a\x55\x18\x0c\xf2\xfb\x6b\xc4\x4a\xc7\xe9\xa0\xe2\xbb\x68\x06\x29\x6a\xdf\xc6\x30\x8c\xcb\xf8\xd1\xdd\x4e\x52\x1c\xe1\x57\x1c\xbd\xc9\x0b\xc7\x20\x30\xa7\x74\xb7\x2f\x4b\xb3\x5d\x37\xb2\x30\xb2\x32\x5b\x1f\x75\xdf\xce\x25\x74\xe7\xa2\xbe\x61\x12\x46\xb8\xff\x9e\x6a\xa8\xfe\x0e\xb6\xbb\x3d\xc5\x24\x14\xa8\xa8\x00\xfe\x3b\x70\x71\xc2\xd4\x61\x60\x76\x30\xe4\xa0\xf6\x34\x62\xdd\x07\x49\xa5\xc0\xc8\xc5\x47\x0e\x9f\xdb\x8a\x60\xc4\xf3\xf3\x3a\x0b\x82\xd0\xfa\xcd\xfc\x27\x28\xb5\xb6\xa9\x4d\xd0\xfc\xa6\x28\x97\x6c\x60\x85\x7c\x5a\x93\x5e\x97\x51\x86\x85\xb1\x8d\xac\x68\x0e\xa0\xf9\x8d\x56\x7d\xf6\x5b\xd7\x06\x92\x68\xba\x7a\x3e\x2e\x36\x33\x2b\x68\x28\x35\xb0\x21\x0f\xe5\x4f\x29\x28\xe7\x06\x91\x8a\x13\x24\x7a\xd7\x94\xe1\x1f\xd6\x00\xb4\x47\x93\x14\xb7\x0f\xb2\x41\xb1\x78\xd8\x8c\xe3\x7b\xa1\x52\x09\x72\x6e\xdc\x13\x01\xef\xc9\xa1\x92\xc6\x37\xd1\xd4\xe6\x51\x1e\x54\x2f\x38\x75\x61\xdf\x5f\xd9\x92\xbc\xef\x11\x2a\x1b\xf1\xbe\x08\xfc\x66\x31\x86\x45\xfe\x2d\x27\x2d\x54\xd6\x66\xa4\x24\x5e\x3b\x2f\xe9\xca\x8c\xd6\x99\x76\x7a\xa4\xb8\xda\x75\x14\x59\x18\x7e\x98\x2e\xa7\x1a\x38\x06\xdf\x1f\xe5\xa9\xd0\x6f\x7d\xff\x99\x88\x92\x5a\x5e\xe7\xa8\x57\x3c\x6b\x0f\x26\x0a\x73\xea\x8f\xa7\xff\x0e\x17\x00\x03\x91\xe4\x5d\xb6\xf6\x50\x36\x8e\x3a\xc1\x1d\x86\x94\xe3\x73\x6d\x1d\x8e\xf6\x17\x73\x05\xb2\x4c\x74\xe6\xe8\xc0\x04\x0d\xad\x30\xe9\xe8\x3a\x17\x11\xfd\x4b\x25\x94\xf6\x34\x90\x58\xc8\x82\x62\x1c\xd0\x8b\x87\xb5\x56\xa3\x18\xf7\x4a\xc4\x19\x68\xe7\x68\x5e\x55\x51\x6c\x9b\xa5\x12\x7a\xa6\xf3\xe7\xbd\xc1\x48\xf4\x78\xe2\x44\x3c\xb3\x68\x9e\x7d\x47\xed\xed\xae\xb7\x22\x6e\x14\x3a\xdd\x58\x0b\x8c\x10\xc2\xd5\xeb\x32\x11\xdc\x1f\x17\x81\xb4\x9e\x57\xa2\x7c\x87\x43\x59\x2c\x6f\x27\x8f\x29\x22\xe6\x81\xe4\x68\x3a\xde\x5c\xc8\x90\x8f\x1f\x45\x44\x71\xcc\x3c\xb0\xa5\xa8\x4f\x07\xb8\xc0\x3c\x73\x16\x85\x19\x15\x2c\x37\x4e\x1b\x1b\xba\x47\x0a\x4d\x1c\x11\x57\xd9\x07\xd4\x4d\x9f\xe4\x88\xa2\x90\x4b\xe8\x5c\x99\x97\x66\x2d\x2d\xac\x0f\x72\xef\xbf\x59\x14\xa7\x99\xa4\x9c\x5c\xbb\xcb\x98\xf2\xb3\xeb\x86\x84\x71\xdc\xa7\x0a\xf8\x1c\x05\xc6\x4e\x03\xda\xea\xce\x54\xf8\xe5\x9f\xd4\x5f\x55\x03\x51\x28\xe3\x84\x0b\x6e\xcb\xdd\x6e\x1a\xda\x8b\xb2\x10\x90\xc3\xfd\x7f\x5e\xee\x5f\xaa\xf2\x2f\xd0\x4d\x77\x44\x87\xa4\x52\xfd\xfa\xfc\xfd\x76\xbd\x78\x5c\x6d\xbf\x2f\x1e\x1f\x57\xde\x75\x88\xa4\xd3\x3e\xc3\xea\x00\xb9\x5f\x9f\xb4\x86\xba\xfe\xb6\xbe\xed\x1a\x40\xa0\x5c\xd2\x0f\x03\xd1\x0f\xed\x46\xe7\xdc\x05\xbf\xfe\x44\x4a\x10\x6f\xf6\xf2\x0d\x86\x0e\x5a\xa4\x62\xe2\x21\xbb\xab\x4e\xda\x57\x5c\x71\x16\x69\x41\x20\x8e\xd6\xa5\x22\x52\x95\xee\xbb\x98\x00\x18\xe9\x83\xb4\x96\xed\xae\x3b\xc5\x64\x24\xc5\x65\xf2\xba\x35\xb8\x07\x12\x5e\x9c\x45\xc0\x04\xa6\x2c\xfe\x67\xfd\xfc\xf5\x28\x9b\xb7\x6d\x3d\x72\x3c\x66\x96\xdc\x08\xe2\xd4\x3a\x0d\xbe\x1b\x59\xbc\xf7\x1b\x53\x04\x92\xdc\xb0\xae\x5e\xa2\xd7\x61\x6b\x8f\x1a\x93\x52\xc1\xea\xa6\x7d\xd7\x63\xf7\x3b\x64\xe8\x58\x40\x61\xee\x50\xb1\xf0\x7a\x6e\x2e\xb2\x9a\x6a\x24\x5f\x57\xff\xfc\xb6\x5a\x6f\xb6\x77\xcf\xdf\xbe\xde\x2e\x36\x0f\xcf\x5f\xb7\x04\x6f\xf2\x17\xb5\x96\x05\x94\x8a\x33\x00\x07\xc7\xf4\x36\x3b\x7f\x63\x96\x65\x54\xae\xd4\x3e\x00\x15\x70\xdc\x94\x55\x55\x7e\x76\xeb\x60\xcc\x74\x86\x42\x00\xff\x7e\x78\x7c\x7c\x78\xfe\xea\x7f\xe6\x2c\x43\x46\x90\x57\x59\xb4\x93\xe1\xe6\x6d\xf8\x05\x63\x9e\x26\x89\x33\xaa\x57\x9b\x2f\xdf\xd6\xb7\xa6\x9d\xbe\xe3\x69\x16\xf3\x2c\xc0\xcf\x8c\xf8\x4b\xc7\x27\x39\xda\xa0\x62\x11\x50\x0d\xaf\x34\x66\xb1\x6f\x9e\x2b\xa9\xa7\x69\xd8\x58\x44\x99\x76\x70\xaa\xaf\x25\x49\xc3\x4e\x40\x8f\x9c\xc5\x41\x06\x38\xf9\x28\xed\xf5\x94\xef\x06\x35\x6d\x9c\xc5\x91\x08\xd1\x68\x3e\x9c\xf6\x4d\xde\x76\xc5\xaa\x79\x9b\xe3\x29\x71\xcd\xe3\x20\xf3\x69\x89\xe7\x4f\x92\x58\xf1\xc3\x20\x8e\xb5\x41\x2f\xf2\xa3\x6c\x50\x13\x70\x8c\x72\xfa\xc7\x4c\xdc\x3c\x4e\x2c\x4b\x92\x0e\x6c\x77\x6c\x60\x1b\xf2\xd1\x1e\x1c\x27\x36\xc0\xa8\x1f\xa6\xaf\x28\x8b\x50\xae\xfb\x74\x6f\x9c\x32\xe5\x2b\x11\x7a\x08\xf3\xd8\x74\x8e\x53\x2e\xb4\xf3\x82\x5f\x1e\x3a\x49\xeb\xd1\x6d\xd2\x28\xd5\x6a\xe2\xb4\x3b\xa4\x44\x3d\x20\xf3\x69\x5b\x1a\x16\x39\x64\x91\x7b\x33\xe6\x0f\x49\x9e\x0a\xe5\x73\x36\x07\x55\x0e\x90\xce\x9c\xc5\x4a\x64\xdc\xf9\xa6\xdf\x6a\x43\xfc\x02\x4b\x18\x1c\x37\x54\x65\x4f\x08\x98\xce\x10\x3b\x8d\x88\x6e\xaf\x6a\x81\x8e\x47\x86\x82\xc0\xcb\x19\xb7\x9e\xca\x8d\x57\xb8\x19\xcf\x00\xcd\x64\x38\x60\xe0\x21\x88\xb8\xdc\xdf\x40\x43\x9a\x94\xe3\x6b\xea\x28\xe2\xfc\x52\x5d\xff\xd2\x48\x9e\x64\x93\x62\x1d\x93\xc4\x36\x6d\x94\xaf\x90\x17\xb6\xac\x34\x98\xce\xd6\xfd\x6d\x62\x31\xc5\x46\xa4\x3c\x18\x86\xf8\x5a\x17\x66\x36\x1c\x1f\x43\x2c\x32\x36\x88\x47\xcf\xa3\x4f\xba\x59\x65\x63\x89\x98\x6f\x52\x1a\xbe\x7b\x78\x5d\x6f\x66\xaa\xc9\xb0\xa1\xc5\x85\x84\x8a\xed\x68\xef\x18\x7d\x4e\x9b\x24\xb8\x7c\xe1\xc4\x79\x9a\xea\xfe\x5f\xd0\x9a\xb5\x67\x64\x22\x20\x6c\x67\xbb\x2a\x4d\xd3\x7f\x93\xb6\x5a\x25\x7d\x28\x14\xe7\xd9\x74\x77\x1f\xf6\xb8\x3f\xcb\x08\x13\xf5\x59\xb9\x9f\x08\x0d\xb4\x8d\xad\x32\x43\xa9\x51\xca\x36\xd1\x0c\xeb\xf8\x36\xa9\x6d\xd2\xfa\x66\x54\x63\x8d\x5b\xe5\xc4\x8e\x4c\x18\x28\xf4\x37\x7a\x7e\x05\xc7\xd3\x70\x7b\x82\xee\x12\x36\xc4\x21\xa9\xbd\xe4\x15\xa6\x06\x7c\x95\xc7\x28\xa5\x9b\x70\x9e\xe1\x50\xa3\x84\xf4\xe6\x61\xf5\xba\x8d\xb6\x8f\x0f\x4f\x0f\x7e\x9d\x4f\x78\x9c\x21\x08\x44\xee\xf7\x8f\x79\x01\xf5\xf7\xaa\xec\xe2\x9f\x09\x4f\x24\xf1\x32\x60\x79\xf4\x72\xc4\x6a\xd5\x6f\x2a\x09\x4f\xe3\x28\x1a\x6a\x5b\xc0\xa4\x42\x8e\xb3\x44\x68\x05\x72\x5a\x98\x3d\xff\xcd\x92\x80\xcb\x38\x1a\x11\x2a\x74\xb9\x5e\xff\x64\x41\xc4\x1c\x19\xa5\x34\x0d\xc8\xc3\x9f\xed\x95\x26\xb7\x0c\x74\x88\x8a\xc2\xf0\xe3\xb8\x2f\x2b\xb8\x69\x1d\x6a\x5f\xe4\xe3\x54\x3b\xfe\x97\x27\xf1\xff\xf9\xe6\x86\xdb\x41\x0c\x7b\x73\xac\x06\xd8\x95\x24\x8c\x6c\x02\x9d\xf0\xca\xc2\xc5\xe4\xbf\xa3\xb3\x34\x7e\xfa\x50\xc7\x68\x10\xd9\xfd\xa9\x7e\x5b\xf5\xbc\xfc\x9c\x25\x11\xa7\x9c\x0f\x0e\xf5\x17\x59\x35\xe7\x35\x14\xe6\xfa\x2e\x91\x44\x96\x63\x85\x80\xa5\x70\xe9\x4b\xb9\x5c\x15\x66\xe0\xf1\x26\x71\x28\xd0\xd3\xaf\xe5\xfe\x43\xee\x88\x83\xdb\xc1\x87\x87\x1a\xfd\xd7\x16\xbb\xf1\x93\xc7\xa9\x42\x6f\xe5\x70\xfe\x56\xe7\xc5\xae\xdd\x2a\x11\x40\xd8\xdd\x2c\x03\xa4\xd1\x7f\x79\x7e\x7e\xdc\xae\x6e\x1f\x36\x5b\xd1\x1d\xd2\x02\x99\xd6\x89\x59\xff\xcf\xe7\xa2\x53\x3f\xe6\x2c\x49\x78\x10\xc9\x01\x12\x74\x0d\xcd\x58\xf2\xd1\xb7\x8b\x63\x0a\x05\x14\x07\x2c\x6a\xf7\x3f\x5b\x86\x9a\x53\x07\xf9\x0e\xc4\x29\x34\x3e\x2d\x65\x9a\x34\x4a\x2b\x59\x34\x75\x97\xf7\x1c\x66\x44\x92\x34\x0a\x70\x2c\xac\x8f\x72\x10\x83\x49\xd2\xc4\x60\x86\x07\x13\x86\xb6\xca\x07\x5f\xc3\xb7\x90\x06\x05\xc7\xf0\xe6\xae\x3b\x5f\xa0\x3a\xc8\x02\x26\x5e\x6e\x92\x89\x08\xfd\xb9\x8f\x1c\x3e\xbb\x30\xf8\xb8\x45\xa0\x10\xda\x7f\xd8\xea\x81\x54\xe6\x97\xbc\x5d\x21\xbc\x5b\x98\x64\x31\xc1\xa7\xea\x46\x36\xb9\x5e\xb6\xe6\xff\x68\xe7\x1f\xee\xfb\x49\x96\x28\x52\x89\x3a\x15\x4d\x09\xd3\x54\x5f\x92\xa9\x14\xd1\x05\x58\xbb\x43\xcb\x25\x19\xbd\xbe\xd4\xcb\xb7\x03\xe3\x43\xed\xa8\x8a\x7a\x01\x99\x76\xed\xa4\xd0\x54\x54\x0e\x8d\x63\x44\x1a\xdf\x4f\xc6\x19\xda\x5a\xbe\x40\x6c\x22\xf7\x30\xeb\x52\x26\x32\x49\x30\x31\xe6\x0a\x8c\xe0\x0f\x24\x02\xda\xf5\xf5\xf8\xd3\x9b\xa4\x94\xaa\x3e\x56\xf9\x7f\xa1\x5e\xb4\x2f\xd5\x0f\x16\xc5\x2d\xba\x2c\x06\xd4\x69\xb7\x75\x62\x6c\x98\x5a\x1d\x21\x5f\x46\x7c\x71\x63\x4c\xcc\xf8\x66\xca\x06\x6c\xc8\xda\x87\xf2\xc8\x84\xb4\x1f\x37\x34\xdc\xe0\x22\x48\xd8\xd0\x91\xda\xd5\xe4\x92\x26\x54\x22\xc0\x6a\xde\x46\xcb\x6e\x28\x9a\x54\xe2\xfe\xbb\x7c\xbe\x59\xf8\xdf\x80\x4b\xe1\xec\x2d\x37\xef\x07\x19\x57\xdf\xa6\x7d\x65\x97\x23\xae\xca\xf7\x6b\xf1\x8c\x04\x52\x25\xc2\x81\x40\xe7\x4c\x00\xc6\xb5\xb4\x01\xd1\xac\x60\x08\x79\xa8\x28\x39\x52\x20\x6e\x1b\x46\x69\x42\x7d\xed\xa5\x39\xbb\x0a\xc1\x97\xaa\x6c\xb0\x54\xed\xa9\x34\xdd\x3a\x60\x93\x18\xf7\x1a\xb2\xa0\x49\x05\x73\x38\x24\xfc\x85\x53\x26\x92\xd0\x51\x48\x11\xb9\x56\x8f\xd6\x49\x99\x4a\x14\xf7\x7e\x75\x78\x9b\x7f\xd4\xcf\x9f\x13\x49\x98\xb6\x95\xa5\xd8\x3d\xd2\x3c\x3e\xdb\x47\x59\x98\xdf\x66\x70\x17\x29\x0f\x35\xfa\x76\xaa\xf4\x73\x21\xe5\x71\x12\x25\x23\x99\xc8\x9e\x29\xba\x6b\x63\x34\x92\x04\xfa\x92\xb3\x99\xc4\x64\x2a\x52\x85\xcc\x5f\x45\xf9\x3c\x16\x3f\xf1\xc7\x25\xc7\x72\xdb\xb5\xfc\x80\xd7\x5c\xbf\x2f\x0a\xf3\x54\x56\xcd\xb9\x3b\xae\x49\xfb\xa6\xab\x60\x99\xcd\x63\xa4\xc2\x10\x27\xe6\xf2\xf9\xe1\xeb\x6a\xfd\xe0\xc7\x4e\x1a\x18\x81\xa0\xc4\x06\xf4\x5b\x91\x6b\xb9\x1f\x59\xdf\x69\x60\x13\x74\x07\x64\x5d\xc3\x28\xb9\x9c\x86\x11\x91\x76\x90\x4d\xb7\xf8\xb6\x6c\xbd\xc3\xf5\xf6\xe9\xe1\xeb\xc3\xd3\xb7\xa7\xed\xeb\xe2\x61\xbd\xea\xda\xa6\xc6\x38\x0f\xfd\x56\x9e\xeb\x87\xe2\xa9\x2c\xa6\x8b\x50\x1a\x4a\x6e\xd5\x68\xeb\x9f\x38\x6a\xff\x98\xb4\x57\x1a\x67\x82\x95\xd5\x61\x9d\x17\xbb\xeb\x1c\x6f\xfe\x04\xad\x09\x3d\x20\x8b\xdb\xf2\xa4\xf6\x70\xdb\x47\x46\xd2\x28\x12\x71\xd6\x85\xd3\x7e\x9c\xd7\x4d\x59\x0d\x30\x8e\xae\x55\xcc\xa9\xec\xe0\x53\xd6\xb7\xb0\x87\xdd\xd0\x30\x9f\xbf\x69\x2c\xa8\x42\x1b\xb7\x0e\xc4\xcb\x3c\xdb\xef\x65\xf5\xfe\x73\xd4\x42\x1a\x27\x29\x3a\x6a\x20\x9b\x6f\x45\xae\xcb\xaa\x68\xd7\xca\xf2\xd4\x2c\xcb\xaa\x7b\xe6\x58\x66\x58\x9c\x30\x0d\xf1\x8d\x26\x49\x12\x46\x98\x1c\xae\xf3\x5d\x21\x9b\x53\x05\x3d\xe3\x51\x7b\x34\x92\x9a\x79\xfe\x13\x94\x1e\x7f\xcb\x8f\xab\x1f\xc7\xbc\x3a\xdf\xca\x66\xfa\xfa\x49\x0a\x34\xd6\x56\xf7\x0f\xeb\xcd\xeb\xbf\xb6\x0f\x5f\x37\xab\xd7\xbb\xc5\x72\xb5\x7d\x5d\xfd\xf3\xdb\xc3\xeb\xea\xa9\xcf\xf9\xa6\x69\x6a\x1d\xad\xee\x21\x2f\xb6\xf0\x63\x16\x93\x98\xa6\x59\x86\x90\xb0\x6d\x01\x9f\xcf\xa7\x66\x57\xb6\x73\xa8\x07\xae\xfd\x82\xb7\xcf\x5f\xc4\xb2\x60\xa2\xd9\xea\xb9\x3d\x5c\x8b\x2c\x22\x91\xd4\xdb\xdb\xff\xf9\xf3\xf5\xa5\xfb\x35\x0d\xd1\x85\x7e\x5e\xfc\x4e\x51\xe2\xab\x41\xe7\xd9\x9c\x5b\x9a\xa5\x12\x4b\x71\x5d\x58\x1c\x01\x0d\x53\x44\x55\x9a\x29\x1e\xbb\x0a\xb7\x97\x72\x02\x04\x74\x4d\x24\x67\x98\x8a\x7a\x93\xf5\xea\x70\x6c\xce\x2e\xd3\xb7\xde\x97\xd3\xbd\x33\x95\x59\x40\xfd\xd5\xfa\xad\x43\x6e\xb0\x29\x02\x6b\x7e\x1b\x4d\xa5\x55\x99\xf5\xf8\x9f\xe2\x54\x8f\xc5\x1d\x67\x61\x68\xde\x9b\x4b\x55\x42\x32\xe7\x14\x25\x26\x24\xd9\xba\xec\xaa\x17\x52\x1d\x50\x00\xff\x28\x4b\x97\x4d\x1a\x47\x06\x52\x9d\x4a\x08\x3d\x25\x11\x34\xb0\x91\xf5\xc5\x4c\xf0\x4d\xa5\x45\x10\xef\xb8\x94\xa5\xbb\x92\x61\x0e\x62\x5f\xc8\x76\x26\x83\x6d\x4d\xc1\x71\x77\x0c\x89\xb7\xda\x33\x42\x86\x86\xfb\xcb\xa9\xb9\xcf\xed\x24\x70\x9c\x9a\xd8\x22\xba\xc6\x05\x27\x47\x93\xc4\x64\x99\x57\x3f\x6e\x5f\x2b\x2f\x4e\x79\x33\xf4\xf0\xbb\xfe\x01\x1e\xe3\x67\xcc\x6b\xd2\x61\x59\x83\xdc\x4f\x02\x91\x29\x84\xca\x50\x9b\x19\x56\x9f\xf6\xb8\x94\x84\x43\xf1\xaa\x36\xe3\x6e\xb1\x31\x71\xb5\x92\xc9\xb2\x41\xba\xb6\xc7\x72\xa6\x68\x6d\x72\x9a\xe4\xb8\x8e\x17\xf0\xb9\x2a\x76\x7b\x59\x98\x9b\x3e\x92\x94\x5a\xa0\xf2\x6d\x69\x3e\xf2\x7a\xc2\x11\xc4\x59\xc6\x22\x86\x92\x2c\x7f\x49\xfd\x7e\x2c\x11\x1f\xfb\xcf\x93\xdc\xe7\x36\xef\xe6\x57\xc6\x9c\x14\x90\xc3\x17\x4e\x49\x56\x38\xcb\x84\x20\x20\x56\x03\xbd\xbe\xdb\xb2\xac\x9b\xee\x78\x42\xb8\x59\xaa\x6e\x98\x17\x1e\x4c\x67\xa7\x7f\x16\x24\x0a\x3d\x07\xe9\x60\x84\x4f\x65\x01\x7e\x83\xcc\x42\x41\xc8\xc7\x0a\x74\x59\xe8\x7c\x9f\xa3\xb1\x78\xeb\x89\x2b\xda\x16\x61\x02\x7d\xa4\x05\x45\x0a\xc8\xed\x8b\xfe\x6f\x1c\xce\xc8\xc2\x84\xc7\x7d\x95\xd2\xa4\xf6\xaf\x3d\x6e\x18\xe2\x3f\x1e\xcb\xcf\x7b\x39\x0e\x64\x65\x11\xa3\xc9\x81\x84\xb8\x1f\x65\xae\x61\x08\xb7\xfd\x79\x3e\x2a\x8b\x82\x54\x0f\xfd\xe2\x85\x81\x63\x33\xf1\x79\xc7\x8f\x12\x05\x1a\x71\xe8\x24\x92\xba\x7c\x93\xfb\x3d\x20\xd2\x92\x96\x96\x3b\x98\x2c\xc4\x59\xa4\x62\xf4\xcd\xbc\x09\xdb\xb6\xf8\xe9\xde\x96\x45\x56\x60\xd8\xe0\xe5\x54\xbf\xf9\x08\xc6\x54\xab\x9e\xb3\x2c\xe6\x19\x62\xd4\x6f\xf2\xb2\xc8\xb5\xef\x8e\x84\x59\xa5\x06\xf1\x09\xf7\x62\x95\x67\x8a\xdf\x94\x4f\xc5\xf9\x22\xcb\x3c\xff\x20\x09\x27\x35\x7f\xd5\x2e\x68\xb7\xf2\x3c\x76\x5b\xb2\x44\x50\xf2\xb2\xaf\x50\x46\x6f\xa0\x3b\x9c\x46\x38\xf5\x9d\x84\xde\xba\x3c\xed\x27\x5d\x93\xa8\x0c\x3c\x9d\x5e\x27\xb2\xd1\x2f\x2d\x59\xa2\x29\x7b\x06\xc7\xbc\x2e\x0d\x74\x7a\xab\x57\x9e\xd6\x44\xa1\x1c\x96\x75\x4e\xfa\x2b\x81\x08\x57\xbe\x55\xd1\x74\x6b\x50\x96\xb5\x4e\x06\xee\xf5\xa4\x04\x53\x9f\xae\x5d\x3e\x33\x01\xe1\xc0\xdb\xc9\x77\xda\xc3\x70\x33\xbd\xb6\xab\x0d\x7c\xc5\x2c\xb3\x31\x16\xa8\x39\xda\xf9\x97\xe7\xf5\x24\xac\x3f\x78\x71\x99\x91\x58\x93\x3a\xed\xf7\x30\xc7\xa8\xd0\xb6\xd1\x21\x72\x23\xd5\xd2\x82\x93\x5b\x9a\x74\xaf\x8a\x13\x34\x93\xf3\xc3\xa1\xac\x9a\x81\x14\xc0\xe4\xcd\xb4\x60\xc1\x80\x65\x6b\x68\x8e\x66\x26\x14\x5e\x54\x62\xe3\xf5\x72\x7e\x89\xad\x9e\x15\x1f\x1b\xdf\xd3\xd8\x18\x79\x19\xaa\xb2\xdd\xdb\x6f\xf2\x86\x32\xbb\x63\x37\xd1\xb5\x85\x88\xb8\x78\xd7\xfa\xed\x00\xfa\x7d\x0f\xfb\xd1\x23\xb6\xae\x15\x77\x32\x03\x7b\xf3\x24\xcf\x65\xbf\xd2\xce\x11\x93\xfb\xf0\x4e\x06\x59\x88\x58\x2a\x4d\x65\xac\xdd\xaf\xc6\x93\xc8\x3d\xc9\x1f\x37\xa7\xf3\xa4\x57\xc1\x8a\xc4\xe5\xfa\x6e\x4f\x8d\x7e\xc3\x51\xfb\x3a\xd5\xbe\xed\xda\x4b\x16\x28\x5c\x30\x5e\xbe\x2c\xd6\x2b\x3e\x14\xd0\x69\x0f\x1a\xa2\x32\x46\xb7\xf5\xd9\x4e\xab\xc0\x5a\xfb\xc5\x5b\xf8\xbf\xc3\x19\x4b\xaf\x66\x01\xe1\x52\x30\x85\x89\xe1\x76\x17\x78\xca\x8b\xe6\xfe\xe4\x17\x6a\x29\x6c\x82\x39\x01\x5a\x86\xc7\x52\x07\xa3\xf5\x5e\x06\x9c\x65\x7c\xa0\xa5\x61\xe4\x64\x9b\x94\x41\xa2\x85\xeb\x1c\x8a\x21\x8d\x0d\x11\x19\x80\x26\xc4\x06\xd4\xcd\xd6\xe6\x1f\x18\xf2\x6d\x57\xa1\x2e\x80\x2a\x43\x6b\x70\xbd\x7e\xd9\xcb\x76\xcb\xf7\x9e\xa5\x8c\x94\x1a\x68\x40\x2c\xdf\x64\x35\xcb\x6a\xef\x5a\xc7\x61\x86\x5f\x61\xf1\xfa\xe8\xa4\xe8\x4f\x73\x68\x17\xdf\xda\x1a\xdd\xf3\x88\x61\x54\xf0\x67\x17\x4f\x02\x8b\x71\x16\xb7\x31\x57\xfd\x9e\x26\x93\xd4\xe2\x22\x73\x44\xc7\x78\xf3\x59\xbe\xc2\x07\xc8\xfd\x95\xaf\x92\xc8\xc8\x49\xef\xea\xd2\xe9\xbe\x39\x9c\x93\x6b\x90\xb2\x20\xf3\x2c\xec\x27\xb3\xbb\xae\x1a\xef\xdb\x0b\x5a\xc3\x7a\x3e\xeb\xc9\x07\x48\x63\x96\xba\x5c\xda\x43\xd1\xdc\xe5\xb0\x37\x81\x3f\x96\x85\x42\x0d\x83\x29\xcb\x32\x2f\x4c\x55\x1e\x47\x15\x4b\xb2\x1d\xfe\xcc\x0b\xe1\x62\xb6\x6e\xfc\x08\x32\x30\x18\xe2\xf9\x23\xaf\xea\xf3\x61\x86\x83\x76\xd6\xa4\x97\x2a\x8b\xd1\x18\x78\xfc\xd7\xd7\xdb\x67\x7f\x2f\x65\x24\x66\x9a\xf6\x20\xcd\xc5\x58\x52\x86\x64\x38\x6f\x5b\x6b\xaf\xda\x7e\xc9\x9b\xe7\x0a\x91\x4e\x17\xa5\xd0\x9c\x49\x0d\x1a\xad\x9c\x6d\x2d\x3f\xae\x56\xd0\xfd\x63\x76\x8c\xfc\xdc\x44\x90\x46\x31\x0c\x9d\xd7\xb2\x78\x92\x3f\x46\xe9\x67\x69\x8c\x44\x6c\x99\x05\xa8\x17\xd3\x22\x53\x1a\x0b\xce\x5f\x94\x10\x12\xac\xce\x19\x72\x83\xf0\xda\xac\x41\xd6\x9d\xa5\x41\xf8\x2a\x4a\x47\x42\xef\x04\x9a\xc7\xdb\x81\xb4\x99\xc0\x8c\x66\x6b\x1c\x2e\x65\x61\xfc\xf4\x57\x4c\x86\x38\xfd\x1d\x87\x1e\x54\x1f\xb9\x86\x27\xf9\x83\x32\x52\xf5\x4b\x3b\x15\xca\x8f\xbc\x9e\x3e\xca\xd4\xc3\x51\x4c\x45\x26\x1a\xd7\x3c\xfb\xa5\x54\x71\x45\x15\x38\x8f\x65\xb1\x43\x8e\xbc\x2e\xaa\x2e\xfa\x15\x38\xfd\xbf\xf9\x2e\x56\x22\x20\xf6\xc8\xbc\x5e\x98\xbf\x64\x4f\x82\xf5\x8f\x8b\xff\x77\x27\x04\x26\xc2\x9c\xf7\xc3\xf2\x79\x8b\xc9\x15\x31\x4c\x7a\xa9\x30\xa4\xda\xd3\xc7\x72\xf7\xad\x86\xca\x87\x70\xae\x15\xa9\xa9\x98\x01\x66\x3c\x88\xd2\x1e\xcb\xb1\xfe\x9e\xfd\xa8\x92\x34\xc1\x0a\x62\xf8\x90\xfb\x93\x6c\x60\x7b\x28\x0d\x4c\xcc\x1c\x95\x64\x29\x2a\x1e\x62\xd4\xe5\x15\xec\xf8\xcb\xa9\xc4\x64\x88\x3b\x41\x3c\xdc\x0e\x9a\xed\x41\xe6\x45\x03\x45\xbb\xa3\x0f\xe2\x77\x2a\x55\x94\x7f\x7c\x69\x3f\xdc\x7b\x3d\x02\xc4\xab\x0c\x22\x12\x90\x78\x3b\x35\x83\xf8\x8b\xd2\x2c\x0c\x5d\x7c\xb2\xed\x8a\x47\x59\xec\x4e\xa8\x73\x7c\xe5\xfd\xba\x2f\xaa\x03\xed\x61\x70\xce\xb8\x7b\xca\x7b\xdf\x4d\x19\x66\x10\x04\xf8\x08\x3b\xe8\x48\x23\xaf\xf5\x59\x3f\x4f\x95\x89\x0d\xce\xf8\xed\xd6\x35\x12\xdb\x6d\x77\x4d\x1d\x63\xc8\xee\xaf\x32\x2f\x76\x48\x62\x30\xee\x47\x08\x52\x96\xf6\x15\x3e\xe6\x3b\xe4\xf3\x16\x8d\x02\xc7\xe2\x8b\x18\x3e\x6b\xf7\x18\x46\xf5\x0b\x8b\x02\x45\x82\xd5\xcf\x05\x78\x90\xee\xb0\x2f\x35\x8b\x13\x23\x7c\xcc\x2a\xd7\x70\x57\x56\x5d\x40\x95\x70\xd7\xb3\x0c\xf4\xed\x99\xd2\xca\x81\xa8\xe8\x5d\x59\x39\x1b\xcf\x1d\xe7\x3c\x45\xf6\xd9\x03\xc6\x84\x1e\xfa\xdf\x45\x86\x55\x14\x5d\xe2\xb1\xdd\x5c\xf3\x62\x77\xa5\x7a\x49\xf3\x2c\x50\x99\x47\x13\x6c\x31\x6c\xf0\x09\x79\x77\xb5\x2c\x14\x44\xb0\xda\xc5\xb4\x34\xcf\x22\x61\x3d\xec\x16\xf9\x75\xfd\x01\x15\xa2\x20\xda\xa1\xfc\x80\xeb\x1c\x6d\x6d\x43\x43\x48\xa3\x7b\xc7\xad\x62\xe6\x72\xf1\x9a\x5b\x2b\xf8\x30\x62\xe4\x70\x45\xfe\x76\x42\x06\x38\xd5\x5e\x2a\xf0\x64\x25\xed\xaf\x9a\x6b\x07\xba\x5b\x54\x2a\x1f\x12\x06\x8d\xe6\x8a\x0e\x62\x3a\x7d\xdd\xe3\xab\xab\x19\x03\x5a\x07\x8a\x47\xa3\x4c\xae\x4f\x19\xba\x55\xd4\xdf\x38\x8c\x04\x12\xc7\xf5\x31\xf4\x6d\x33\x2a\x42\xd1\x61\xcc\xb1\x4e\x0e\x7e\x1c\xcb\xaa\x81\x8a\x30\x43\xdd\xd1\x8c\x94\xa0\x96\xb2\xda\x97\xf5\x00\x19\xa7\x43\xc5\x33\xc7\x96\xfe\x24\xdf\xa1\xba\x81\x66\x90\xd0\xd4\x21\xa4\xca\xa1\x90\xfc\x4f\x91\xa2\x50\x69\x59\x19\xa8\x9e\x64\xa3\xdf\xd6\xb0\xbf\x10\x52\xfa\xb9\x5d\xad\x23\x15\x60\x58\xfb\x90\x17\xcd\x3c\xfb\xb6\x6b\x98\xb0\xd4\x89\x72\x23\x66\x9e\x8e\x4d\xa7\x9c\x4e\x42\xab\x1d\x08\xe8\x7e\x5f\x2a\x39\xab\xeb\xd4\xb6\x4b\x89\xc6\xad\x86\x7a\xa2\x53\xcd\x99\xce\x78\xe0\xf9\x47\x37\xf9\x01\x82\xf1\xfa\xa7\x33\xa9\x9c\xec\xc8\x3b\x39\x55\x57\x06\x60\xa6\x13\x57\x67\xd2\x6e\x64\x2f\xe5\x3b\xe8\x32\x2f\x16\x85\x41\x64\xa1\xac\xde\x3b\x4f\xe9\x72\x79\x73\x97\x90\x26\xe6\x8e\xba\x5b\x61\x60\xeb\x22\x9c\xd2\x36\xf1\x94\x3e\x37\x55\xae\xdf\x1f\xcc\x25\x01\x4a\x57\x95\xf7\x8b\x8f\xa1\xc2\x00\xb7\xa9\x5b\x1f\x65\x43\xff\xf2\x22\x31\x75\xf5\x6c\x13\x13\xe0\xff\x2f\xd0\x7e\x11\xa6\x84\x0c\x32\xe8\x8d\x4c\x4d\xad\xa2\x18\x3f\x7c\x8e\x34\x6a\xcf\x76\xf2\x21\x55\x16\xa1\x7f\x40\x2b\x4f\xbd\x3d\x9e\xea\xb7\x2b\x9d\xa4\x20\x44\x38\x8d\x3c\x1e\xf7\xe7\xa7\xa5\xef\x18\x1d\x03\xce\xec\x5b\x79\x3c\xd6\xbd\x07\xad\x75\x16\x63\xed\x6c\x7d\x3a\xa8\xbc\xb9\x2b\xab\x95\xaf\xf4\xf4\x0d\x9c\x61\x4f\x75\xa1\x7f\x94\x0d\x4c\x5c\x59\xad\x15\xc4\x6e\x94\x2d\xf6\xcd\x52\x1e\xf3\xa6\xe3\x3a\x9c\xbc\x07\x30\x52\x5e\xd0\xb2\x58\x7f\x4a\x9f\x60\xd6\x20\x6c\xe0\x28\xc4\x82\x41\x42\x7f\x26\xb5\x3f\xcc\xe2\x0e\xfd\x73\x0d\x31\xd1\xc8\xd6\xd0\x6c\x5d\xc8\x62\x6b\xa7\xd1\x1c\x6d\x23\x83\xe9\x61\xf9\x29\x73\x14\x06\xc5\x2a\x4e\xff\x18\x56\x6b\x5c\x23\xf7\x60\x1b\x9e\x8c\x4f\x35\x8c\x91\x0a\x02\xe1\x87\x90\x7a\x74\xd2\x20\x01\xac\x0a\xd9\xee\xc9\x11\x5f\x0e\xe4\x5d\xc7\xdf\xc8\xb0\x14\x10\x8f\x4b\x7d\xba\xfd\xa4\x7c\xbe\x3f\x68\x09\xf6\xdc\x2d\x7e\x1b\xc7\xa9\x43\xdb\xe6\xe4\xae\x22\x0e\xb0\x0a\x68\x87\x4e\x5f\xb5\x79\x93\xc5\xbc\x37\x63\x84\x15\x9e\xca\x78\xdb\x85\x8f\xb7\x14\x29\x1e\x82\xa4\x4d\xa0\x8c\x18\x46\xd5\x30\x6e\x48\xc1\xc3\xd9\xa9\x6d\x42\x11\x63\x36\x67\x4b\x7d\x33\x1e\x1e\x26\x4c\x35\xc6\x20\x30\x36\xeb\xd8\xf2\xdd\x4c\x7f\x9e\x00\x12\x4d\xc4\x19\xfa\x01\x25\xf2\x6d\xc0\xb5\x92\x86\x4b\xc5\xfe\xff\xfd\xbf\xc1\xb4\x9e\x94\xdd\x9a\x28\xa5\x8a\x30\x7c\xa1\x3b\x80\x65\xf7\xc9\x4d\x04\x14\x0e\x38\xc8\x1f\x8b\xa6\x81\xc3\xb1\x3b\x12\x4b\x8e\xfc\xe4\x9d\xce\xf0\x65\x26\xd3\x24\x82\xca\x16\x9c\x74\x3d\xb2\x97\x74\xf2\x8b\xed\x71\x95\x21\x25\xcb\xed\xc3\xe2\x71\xbd\x7e\xf9\xe6\xb1\x9b\x26\xcd\x4c\x40\xe5\x6c\x7e\x1f\x44\xc5\x13\x7f\xd4\x24\xa1\x19\x58\x30\xf3\xa9\x3e\x93\x09\x16\x13\x57\x11\x89\x82\xdc\xcb\x7a\x58\x4c\x6e\xb2\x24\xb3\x71\x5f\x4c\x39\x9b\xeb\x35\x32\xb3\x68\x28\xae\x1b\x79\xbe\xc9\x3b\x61\xb9\x3b\xa9\x07\xb0\x0a\xa3\x19\x04\x94\xac\x46\x39\x9a\x67\x3b\xba\x91\x91\x12\xb3\x48\xdb\x1a\xad\xcd\x8f\x19\x4d\xcd\xee\x5b\x18\x13\x13\x8d\x4d\x59\x20\x40\xff\xca\x90\x02\x65\x2c\xad\x87\x8b\x93\xc9\x9b\xbb\xbc\xc8\xeb\xb7\xe9\xe0\x07\x16\x1a\x74\x8e\x08\xa1\x15\x31\x8f\x81\x04\x06\x8a\xa4\x60\xe4\x7e\xbf\x6e\xca\xef\x79\xf3\x76\xd3\xe8\x5f\xa1\xf4\xaf\x47\xc4\x66\x72\x47\xce\x99\x01\xae\x23\x70\x96\xf6\xef\x15\x02\x87\x16\x8e\xa3\x7b\xfe\xd5\x80\x1b\x2a\xfe\xa7\x0a\xf2\x01\xbe\xb2\x6f\x22\x84\x09\xf9\xc4\x54\xf6\x87\x54\xc6\x3d\x12\xe1\xb2\x0c\x26\x9e\x5c\x28\x8a\x33\x74\x5b\xdf\xe1\x3c\xfc\x62\x10\x29\x6b\x3d\x63\x21\x59\x78\x53\x8f\x14\xe2\x8c\x07\x44\xae\x36\x48\x0a\x40\x2c\x05\xc2\x2f\x7c\xc5\xea\xfa\x54\x7d\xe4\x1f\x65\xd5\x59\xbc\x93\x8b\x28\x08\x7c\x35\x0e\x9a\xd2\x50\xfd\x36\x7a\xc0\xd8\x90\xc2\x71\x03\xf2\x40\xa4\x20\x43\x5c\x30\xc4\x26\xc1\xd2\xc0\xed\x61\xa8\x5e\x3e\x0c\x0e\x41\x0c\x04\x70\xfa\x28\x1b\x57\x34\x37\xee\x82\x24\x89\xc1\xb8\x98\xcb\xac\x2c\x5f\xdb\x46\x52\x3d\x32\x76\x24\x66\xe1\xbd\xc5\x0b\x09\xa4\x3e\x31\xd8\xae\xf9\x6e\x01\x40\x78\x94\xad\x4a\x1f\xfe\x82\x94\x19\xbc\x8b\xd4\xfa\x74\xc0\x55\x7b\xdb\x94\xdd\x41\x11\x60\x56\xce\x31\xb6\x22\xad\xc3\xb4\xa7\xd2\x8c\xe2\x8c\xb4\x94\x6c\x0d\x38\x63\xcd\x2f\xdf\x90\xc5\x2a\xe8\xcb\x09\x9e\xca\x0a\x1c\xc1\x82\x23\xa7\x9b\xd8\x7e\x20\x79\x60\x3a\x6a\x51\xca\x43\x1c\xfa\x38\x29\xc8\x98\x4a\x3f\x30\x34\x21\xcd\x73\xb1\x3f\x0f\xf6\x00\x90\x90\xa1\x15\xf1\x69\x7e\xea\x1b\xfa\xd6\x36\x61\xbe\x74\x0c\x45\x21\x4f\x35\x5c\x41\x41\x81\x0a\x88\x93\xe3\x7a\xda\x70\x04\x32\x01\x15\x91\xb4\xe5\x40\x48\x70\x29\xf7\xfb\xbb\xf5\xe6\x67\x14\x6f\xed\xfc\x47\x02\xc3\xc5\xfa\xee\x66\xe8\x1e\x82\xb2\x9c\x8d\x6b\x5a\x6e\x60\x52\xf5\x0e\x3a\x32\x18\x0f\xb1\xa4\xe0\xb4\x28\xcc\x4d\x5e\x35\x6f\x13\xb9\xc6\xf1\xfe\x0a\x5a\x52\x97\x21\x55\x5b\x2f\x5f\x76\x9d\x80\x6f\xd6\x6e\x04\x0d\x19\xda\xec\xba\xac\x2a\xf4\x59\xbf\x40\x55\x8e\xe8\xeb\x39\x03\x13\x19\xc4\xa7\x6c\xe1\x90\x63\xbd\xff\x07\x50\x46\x6b\xb8\x91\x03\xf0\x0c\xc1\xae\xf5\x49\x1d\x28\x2b\x4e\x20\x9a\x45\x61\x36\x55\xbe\xdb\x41\xe5\xec\x9f\xf1\x13\x40\xc4\x31\xab\x76\xff\xe7\x1f\xcb\x35\x14\xcd\xcd\x19\x43\xae\xd7\x6a\x1b\xfd\x59\x2a\x46\x8f\x49\xb6\x1e\x60\x35\x0c\xa8\x0f\x9e\xc8\x32\xa9\x5d\xb5\x05\x02\xb2\x3a\x1f\x12\x2c\xcf\xbc\xda\xf2\xea\x78\x98\x54\x0b\x52\x1b\xcb\x38\x60\x90\xec\xf8\x70\x8b\x2e\xcf\x76\x7a\x5c\x87\x88\x5d\x3f\xc8\x1f\xed\x2e\x75\x31\xe8\x2d\x0f\x68\x2c\xb5\x8b\x27\xfc\xb8\x82\x65\xf6\x6d\x1d\x1a\xcf\x15\xae\x0c\x90\x5c\xdd\x3b\x5b\x9e\x08\xf4\x69\xf2\xfa\xd6\x55\x69\x2d\x9c\x1f\x6a\xba\x5b\x4a\x91\x84\x1d\x97\xc6\x44\x54\x9f\x33\x2b\x44\x6c\x9c\xca\xb2\x63\x65\x99\x0c\xb2\x0b\xa7\x65\xf0\xaf\xae\x63\xad\x50\xc4\x7e\x8e\xea\x68\x43\x66\x45\x2b\x80\x73\x4d\x29\xfc\x03\x34\x6f\x70\xaa\xff\x9c\xf7\x1c\x6c\x20\x32\x94\x6b\xb9\x87\xe6\x9f\x27\x38\x8d\x6b\x75\x6c\x20\xa9\x80\xf9\x82\xc7\xfe\xab\x47\x24\xf9\x1c\xa5\x3f\x23\x64\x29\x26\x18\x65\x6b\x10\x3f\xc9\xbc\xe8\x28\x95\xa7\x50\x7b\x1b\xf2\x84\x47\x43\x26\xcf\xd6\x38\xc7\x7c\xc9\xec\x24\xb1\x61\x18\x62\x8d\xfc\xf2\x2d\x2f\x64\xff\x9d\x67\x53\x09\xa7\x09\x13\x32\x67\x36\xb2\xdc\x6b\x1e\x6e\x8f\xb2\x6a\x72\x9d\x1f\x65\xd1\x6c\x71\xec\xd6\xdb\xf7\xb3\xee\x2d\xe4\xc9\x18\x8b\x6c\x8c\x1c\x98\xb6\x02\xd8\xb6\x7b\xce\xd6\x96\xd5\x56\xcb\xc2\xe4\xed\xa3\x6f\x3d\x84\xcc\xc6\xb1\x46\xc3\x7c\x41\x8b\xfe\x73\x71\x25\x33\x69\x63\x10\x32\xf6\xd5\x27\xa7\xc2\x65\x66\x6e\xce\x14\x88\xfd\xe9\x62\x61\x63\x4b\x54\x18\xf7\xad\xeb\xb5\xef\xd2\xd9\x0f\xb7\xdd\x47\x48\xc2\x10\xc1\xa9\xef\x67\xdd\x07\x52\x97\x1e\x40\x5b\x56\x93\xe5\xd9\x26\xda\x06\x4e\x3e\xa9\x39\xd5\x63\xa1\x21\xce\x6c\x1a\x59\x54\x28\x5d\x2d\x16\x83\x70\x89\x4d\xd3\x08\xf7\x69\x03\x7a\x2f\x2b\x58\xbe\xc1\x54\x30\x84\x33\x9b\x71\xc0\x48\xc1\xa7\xdc\x43\x2d\x6f\xe5\xa7\xfc\xeb\xa9\xfc\x0b\xd6\x4d\xf9\x94\xef\xf3\xb2\x67\x6f\xb1\x59\x48\x42\x6b\x3e\xd5\xb1\x29\x5f\xca\x72\x3f\x03\x1c\xb5\x92\x71\x4c\xf7\xe5\xf5\x8d\x6c\x9a\x3d\x91\x40\x96\xd5\x0c\x29\x37\x47\xb1\x41\x5c\x5a\xbf\x9c\x55\x95\xbb\x8d\xed\x6a\x19\x83\x95\x2a\xd6\x89\x97\xb5\x27\x3b\xcc\x89\x61\xfd\x7c\x37\xb4\x12\x62\xf4\xee\xec\xa9\x39\x11\x1d\x73\x5e\xec\x28\x71\x34\xce\x91\x58\x15\x68\x2f\x1b\x7f\x4b\x42\xbd\xb3\xb2\x85\x93\xeb\xab\x48\x28\x3b\xe4\x42\xb8\x73\x4c\xec\x3f\x65\x42\xb0\x9a\x49\x04\x5c\xbd\xe6\xbb\x65\x25\x6d\xe3\x90\x4a\x2f\x52\xbf\xcb\x1d\x8c\x6b\x97\xad\x66\x24\x26\xdb\xc3\x0e\x71\x47\xab\xf3\x5d\xd7\x22\xe0\x1a\xfa\x60\x29\x32\x6e\x53\x54\x70\x72\x5b\xad\xb0\x60\xcf\x65\x4e\x6e\x4e\x55\xf1\x22\x4f\x75\xbf\x42\x6a\x23\x11\xfb\x7b\x7b\x7b\xf7\x77\xe7\xaf\x36\x80\xa1\x66\x0b\xfa\xed\x8f\xb2\x41\xee\xf0\xbb\xb2\x6a\xff\x79\x05\xc1\x6b\x21\x14\xca\xab\x39\x9b\x63\x5f\xa0\xf6\x05\xf6\xc7\xfe\xa4\xff\xe5\xbe\xa2\xc1\x42\x24\xd1\x0b\x6e\xb7\xb2\x95\xac\xf6\x67\xcc\xff\xf9\x6c\x9c\x85\x44\x23\x89\xf8\xb1\x9d\xa5\x17\x16\x84\x85\x4c\xc2\x50\x31\x60\xf2\xe1\x41\x31\xef\x8b\xbf\x94\x9f\x93\x82\x0e\xd7\xc6\x86\x44\xc4\xb0\xc7\x80\xef\x48\xea\x05\x5b\x70\xc6\xc2\x14\xe9\x2a\x64\xd3\x48\x47\x1d\xdf\xfe\x2a\x33\xe3\x84\xef\x47\xc8\xaf\xb9\x51\xc1\x19\x97\x8c\xf8\x28\xf7\x32\x3f\x74\x56\xfc\xc4\xe1\xf9\x59\x2c\xa6\xf3\xb3\x39\xe3\x20\xa5\x1d\xc8\x1d\x55\x83\x52\x25\xce\xb8\x95\xe8\x85\x7f\x7f\x6b\x9d\xe9\x37\xf9\x6b\xce\x7a\xce\x99\x88\xb9\x93\x6c\x6c\x9e\x30\x46\x88\xfd\x3d\x2d\xcd\x70\x8d\xc3\x98\x4c\xfd\x1a\xa5\x4c\x2b\xd9\xa0\xde\x09\xee\xdb\xdd\x56\xc9\x59\x98\xc5\x10\x79\x29\xdf\xcb\xe8\x33\x67\x21\xb0\x8c\x18\x49\x8d\xd9\xc3\xfa\xad\x44\x70\x49\x47\x2b\xc7\x59\xc4\x62\xdb\x93\x91\x8c\xe2\x3c\xc3\x51\x80\x35\xc7\xb8\xf9\x5b\x74\x5f\x6f\x17\xc7\xe3\x68\x39\xe5\x2c\x02\x8b\x09\xc2\x2d\xc2\xc5\x9b\x4a\xba\x95\x66\x22\x42\x3c\xf9\x66\x71\x00\x88\xe2\xa6\xdd\xf2\x1b\xca\x67\xdc\x4e\x31\xa4\x9c\x25\x5c\xe3\x2e\xb7\x6c\x87\x70\xed\xe1\x37\x73\x50\x4b\xce\x12\x1d\x20\xe5\x17\x46\xaf\x97\x65\x61\xf3\xea\xd0\xa3\xa6\x7d\x23\x48\x12\x3d\x28\xa1\x9b\x91\x1c\x6c\x5b\x59\x89\x45\xa5\xcd\x5b\x5e\x51\xd2\xbc\xdf\xcf\xbb\x2e\xcc\x24\x43\x6a\x33\xa2\x92\x26\xfe\xa6\x29\xc4\x0e\xd1\x1a\x99\x98\x90\xc8\xf4\x20\x8b\xb9\x89\xce\x99\x84\x84\x0a\x04\xdf\x40\xbf\xbf\x82\x85\xaa\xf2\x09\x7e\xff\xb2\x2a\xb2\x84\x3e\x40\x47\x5d\xee\x6f\xa1\xc8\xaf\x64\x17\x39\x53\xa9\x8c\x7b\xf9\x4c\x4f\x74\x7b\xb7\x97\x3b\xff\x2e\x3a\x4c\x90\x5e\xbc\x7d\x8e\x59\xa1\xde\xc9\x13\x6a\x80\x98\xd8\x3f\xf2\xdd\x5b\x83\x0b\xbf\xb3\xc3\xc7\x77\x36\x41\x84\x4b\x96\x3a\x9d\xa9\xf4\x6e\x7c\x19\x93\x01\x56\x2f\x39\x2d\xa3\x6b\xb1\x8c\xf9\xb7\x32\x3a\x41\xa3\xc3\xb8\x22\xbb\x6e\x01\x0c\xfc\x64\x36\xb6\xe3\xae\x77\x1e\xe6\xc3\xed\xe4\x09\x6c\x4a\xc3\xfb\xb3\x2b\x58\xb1\x5d\x8e\x84\x33\x6b\xe2\x88\x1c\xd0\x1b\x70\xe4\x17\x74\x84\x33\x26\x30\xcf\x46\xf3\x07\xd1\xae\xc3\x49\xcf\x99\x30\x18\xff\x32\xf0\xf1\x2a\x9b\xbc\xec\xce\x0b\x22\x24\x8a\xc0\xb5\x70\x4b\xa4\x2d\x73\x5b\xb1\x63\x38\x6a\x3f\x1e\xf7\x1a\x83\x6e\x69\xeb\xf4\x7e\x07\xbe\x35\xe7\x3c\x02\x84\x69\x6a\xda\x16\xfa\x10\x1f\xe7\x5c\x1b\xe1\x50\x72\x37\xa7\xf3\x2b\x92\x0b\x8c\xbb\x81\x8b\x28\xcc\xba\xf2\x61\x03\x53\xae\x38\xce\x85\xe2\xbe\x7a\xe4\xe6\xe4\x02\x31\xb3\x83\x97\x07\x71\x82\xf1\x69\x84\x31\x4f\x6e\x13\x80\x41\x75\x97\xdf\x57\xaf\x5f\x57\x8f\xdb\xc5\xcb\xcb\xf6\xe1\xd6\x3f\x66\x60\x05\xda\x41\x5b\x69\xb0\x76\x7a\x76\xe1\xe0\x61\xca\x11\x8a\x75\xb7\x58\x6e\x9e\x5f\xb7\xd9\x6f\xdd\xef\x11\xe6\xd1\xf2\x02\x99\xf8\x4f\x72\xbf\xd5\x3e\x3a\xcf\x79\x98\x11\x85\xf3\xce\x29\x20\x4c\x9e\x2b\xb4\x1a\xa8\xe0\x10\x64\xe5\x62\x1b\xee\x50\xac\x15\x16\x8e\x7d\xff\xfe\xb5\xb7\x16\x39\x8f\x6d\x1c\xb8\xe4\xd5\xdd\xa9\x20\x12\x74\xf8\x80\xe2\x92\xa3\x85\xf3\x44\x04\x60\x7c\x65\x75\x7e\xf4\x64\x4b\xb3\x33\x8b\xa7\x8c\xb2\x3f\x40\xb5\xbd\xbf\x9f\x35\x45\x84\xc6\xbd\x90\x06\x19\x09\x87\x9c\xea\x37\x54\xcb\xdc\x97\xe5\x68\xab\xe2\x69\x18\x64\x3d\x31\x0c\x95\xaa\xdf\x82\x34\x7d\x5d\x1e\xe7\x69\x92\x62\x74\x55\x1a\x67\xb4\x8d\x1f\x25\xe3\xdc\xcb\x13\x51\x5c\xab\x1d\x7c\xb3\x8a\x24\x6d\xe3\x98\x73\x37\x82\xda\x2d\x1b\x01\xf3\x77\xcb\xbb\xc1\xae\xc5\xb3\x58\x6b\x22\x50\x3e\x55\xed\x08\x2b\x2e\x62\xa2\x7e\x1b\xe6\x59\x96\x26\x9e\xf5\xd4\x97\x37\x2c\xdb\xd5\x70\xba\x54\xf3\x0c\x52\x5c\x05\xf2\xa2\x9d\x8a\x35\xcc\xe4\x84\x39\x97\xdc\x42\x36\x10\x69\xa8\x6f\x4e\x3d\x5d\x12\xe7\x32\x09\x85\x7b\xf6\xaf\xf0\xb9\x68\x5c\x11\x6b\x3d\xc3\xba\xc4\xb9\x0a\x98\x4c\xba\x2f\x6f\x64\x95\x4b\x47\xe6\x3c\x1b\x2d\xe2\x5c\xc5\x01\x96\xe8\xb5\xc3\xe7\x28\xab\xf7\x41\x28\x87\x73\x95\x08\x1d\x50\xd0\xad\xfd\x7a\x53\x88\xf4\xa5\x4e\x4a\x7b\x8e\x8e\x70\x0a\xfc\x91\x2b\x18\x8e\x49\x6d\x33\xcf\x51\xf7\x50\x34\xb0\x83\xea\x0f\x79\xda\x4f\x3f\x94\x49\x44\xc8\x47\x5f\xa1\x1b\xeb\x26\xe5\x28\x81\xbf\xc3\x7e\xe8\x7f\x96\x01\xbe\xf1\xb1\x3c\x22\x33\x0b\x06\x88\xab\x4a\x9e\x27\x3e\x30\xe7\x90\x04\xc8\x4d\xb3\x6e\x7d\xb9\x5c\xd6\xd3\x0a\x06\xdf\x4c\x2a\x64\x52\xa0\xcd\x9f\x70\xce\xd7\xf3\x23\xbf\xcc\x8e\x70\x6e\x95\x44\x1f\xf2\xeb\x6a\xf3\xe4\x9e\x5a\x30\x45\x65\x94\x8b\x63\xb9\xdf\x97\x6b\x38\x36\xd0\x6f\xbc\xab\x1f\x0d\x20\x95\xc8\xec\xd6\x22\x84\x48\x10\x10\xb3\x79\x58\xbd\x06\x84\xef\xf1\x97\x15\x81\x44\x18\x03\x0a\xa0\xf5\x42\x15\x7c\x7b\xd7\x85\x52\xb9\x08\xa4\x41\xeb\xc6\x55\x8f\x78\xee\x20\xaa\x0a\xfc\x5a\x76\xcd\xb4\x41\x58\x8e\x01\x9d\x1b\x58\x1f\xf7\x33\x9c\xa7\xc3\xb1\x27\x02\x88\x89\x47\xa9\xdc\x11\xff\xc4\x95\x45\x58\x04\x60\xbd\xa0\xef\xd7\xd3\x01\xf5\x38\xb0\x7a\xa5\xdb\xc0\x44\x60\x5d\xd1\x2c\x34\xab\xc3\x71\x5f\x9e\x01\x2e\x34\x21\x39\x17\x61\x22\xb0\x7a\xdf\x95\xcf\x57\x15\x02\x1e\xee\x00\x5e\x41\xe7\xc7\xa1\xf8\x8a\x3f\x41\xb3\xc8\xd3\x6d\x97\xbb\xc9\x92\x22\x42\xc8\xc0\x95\x16\xda\x52\x9f\x6a\x2d\x2b\x73\x1d\x2a\xef\x4e\x8a\x05\x67\x51\x77\xc9\x9f\x7a\x96\x5c\xc4\x0e\x3c\x5b\x93\xa4\xe7\x7f\xe1\xae\x5d\x18\x2b\x18\xea\x3a\x5d\xb9\x4f\xa2\x20\x4b\x5c\x3d\x01\x52\x2b\x3e\xca\xba\x59\x7c\x40\x25\x3b\xa1\x07\xdf\x7b\x69\x42\x1a\xcc\x79\x8d\x43\xaa\xe7\xd1\xe0\x22\x55\x51\xd6\x41\xd6\xd1\x76\x14\x38\x6b\x3a\xa5\x91\xb6\x09\xd1\x0b\xd3\x6e\x84\xe4\xc7\x7e\xe9\x18\x3f\x51\x16\x32\x9b\x39\xb9\x2e\x62\x1a\x9a\x2c\x7f\x22\xb3\x31\x06\x33\xd6\x9b\xc5\xef\xab\xed\x7a\xb3\x78\xdd\x6c\x37\x0f\x4f\x2b\x7f\x2b\xc9\x33\xf4\x67\x56\x05\x71\xa1\x4d\x4e\x57\x81\xc6\x94\xf3\xd3\xe9\xc7\x10\x81\xc4\x85\x0a\x43\x54\xfa\xde\xca\xe3\x11\x0a\xb3\x91\xbb\x1d\x98\xeb\xa4\x36\xed\x09\x54\xbb\xad\x1a\x5d\x0d\x2d\x25\xa1\x13\x86\xd9\xb9\x27\x59\x9c\x5a\x3b\x95\x64\xf4\xfc\x41\xcd\x30\x68\x86\xe2\x78\xcb\xd7\x67\xff\xbb\x71\xa1\x7d\x4c\xba\xd8\x1b\xb9\x5f\x43\x4f\xcc\xcb\x85\x49\x62\xae\x5d\xc4\x11\xb9\x83\x1c\x5a\x6f\x8c\x1e\xf4\x8d\x4d\x88\xbd\x8d\x62\x6f\xa4\x5e\x48\xbc\xcc\xee\x38\x04\xa4\xa3\xec\x61\xf5\x58\x71\x3d\xfe\x0e\x10\x32\xe5\x7c\xdd\x2e\xff\xb2\xda\x7c\xb9\x32\xf9\x40\x92\x66\x70\x47\x4a\xe9\x35\xb0\x26\x9d\x0f\x26\xb0\x91\x53\xbb\x68\xbe\x43\x3e\x17\x31\xe6\xc2\x46\x80\x26\xb4\xcb\xbc\x8c\xea\xc1\xe7\xef\x6f\x55\xa2\xb3\xce\x65\x73\x68\xa9\xbc\xd8\x0d\xf6\x62\x61\x15\x64\xc3\x9a\x4c\x47\x92\x3c\x28\x0d\xa1\x86\x01\x13\x29\x4f\x7d\x08\xc9\xce\xc6\x76\x7c\xcb\xd4\xc4\x3e\xac\xf8\x28\x8b\xa1\xf0\x88\x6b\x21\x2c\x15\x89\x6d\x4f\x4d\x49\x61\x51\xe7\xce\x04\x41\x14\xc8\xb4\x27\x51\x86\xe1\x1e\x3e\x6f\xfe\x07\x81\x4d\x33\xd3\x11\xf0\xde\x57\xe5\xe7\x40\x8d\xcf\xb5\x09\x99\x16\x6e\x43\x5b\xdd\x6f\x50\xdb\x65\x28\x83\xc3\x83\x50\x50\xc4\xdf\xd5\xaa\x60\x00\x28\x2f\xab\xbc\x19\x92\xb2\xce\xa0\x6c\x7e\x06\xef\x4d\x67\x19\xd3\x79\x10\x66\xe4\x85\xb9\x68\xfc\x16\x3a\x3f\x23\x08\x55\x82\xe6\x29\x1c\x8e\xcd\xf9\xa6\x34\x63\xc4\x3f\x0f\xa2\x28\x4a\xfd\xf8\x6b\xbd\xcd\xc7\xfc\x30\xb5\xad\x83\x48\x05\x18\x4f\xf6\x69\x4d\x64\x0e\x29\xe4\x9e\xa2\x76\x7e\xb4\x07\x71\x28\x7c\xae\xd7\xf9\xc8\x38\x25\x96\x17\xc4\x49\xad\x21\xaf\x04\x45\x44\xeb\xa6\x2a\xcf\x9d\xbd\x14\xc4\x52\x12\x2e\xa8\xd4\xef\xc8\x87\xfb\x01\xe4\x70\x8c\x9f\x28\x65\x0c\x67\xe9\x1e\x8a\xdd\x5b\x03\xc5\x5d\x55\xfe\x17\x0a\xb4\x0c\xe7\x8d\xdf\x20\xcb\x18\x8e\xf5\x97\xd7\x87\xe5\x6a\xfb\xf4\xed\x71\xf3\xf0\xf2\xf8\xb0\x7a\xf5\x37\xce\x64\x10\x0d\xf4\xf2\xee\xca\x6a\x4c\xea\xcf\x03\x99\x02\x6e\x7c\x77\xf9\xde\xef\xc6\x81\x12\x40\x8c\x79\x27\x84\xe2\xa2\x83\x37\x1e\x4b\x2a\xd2\x7d\x2d\xef\x68\x8c\xfb\x06\x2a\x25\x89\x8a\x0f\x28\x9a\x9f\xb2\x54\x76\xbd\xa7\x23\xca\xba\xae\x0f\xb2\x6a\x6e\xf2\xfd\x3e\x2f\xbb\x35\x27\xd0\x92\xa8\xcf\x9a\xbc\xed\xc1\x99\x08\x4e\xa0\x21\x44\x66\x0a\x02\xd6\xdc\xe4\x86\x98\xdf\xdd\x51\xc3\x33\x5c\x54\x7b\x32\xa7\xfa\xae\xac\xda\x6d\xe8\xf6\xd4\x2e\xca\x0f\xcb\xe7\xb0\x6b\x1b\x08\xa4\x57\xd8\x74\x06\x9f\xb7\x32\xc7\x9d\x6f\x1c\xa5\x74\xeb\x0d\xb4\xe3\xc0\x6b\x22\x8f\xc9\xe6\x2f\x0a\xb6\x86\xbb\x40\x00\x82\xc0\xff\x1f\x65\x97\xfd\xf0\x47\x22\x85\x82\xdc\x46\x9e\x37\xe5\x20\x8c\x12\x40\xac\x68\xd9\xc8\x8f\xf5\xc2\x98\x4d\xf9\x08\x66\xe7\xe3\x36\x82\x4d\x66\x3d\x64\x06\xd1\xc4\xb7\xf9\x2e\x6f\xe4\xfe\x77\x38\x0f\x2c\xe0\x00\x1c\x06\x59\xee\x73\x4d\x54\x21\xb5\xa7\xf0\x9f\x15\x57\xbd\x7c\x1d\xba\x50\xc8\x98\x49\x49\x54\x21\xff\xd8\x5a\x59\x37\xf7\x6e\xe6\x7d\x91\xf5\xdb\x76\x3b\x43\x25\xc0\x43\x6e\x12\xd3\x9e\xf3\xed\xf5\xc1\x3d\x4f\x28\x98\xc5\x4a\xf6\xa7\x7f\x3d\x7c\x7d\xd8\x3c\x2c\x1e\x87\xb5\x37\x3c\x14\x21\xe0\x94\xed\xb8\x0b\x71\xce\x5a\xa9\xc7\xce\x77\x28\x52\x8d\x91\xd8\xdb\xcd\x9f\x97\x51\x56\x1e\x0a\x13\x22\x57\x73\x7d\x6c\x5d\xaa\x53\x61\xfc\x30\x0b\x83\x34\x42\x43\x7b\xd1\x2e\xde\x9f\xc3\x20\xdf\x2c\x31\xe8\x68\x3c\x84\x81\x66\x34\xfd\xa9\x5c\xec\x61\xf9\xbc\xfe\x94\xc7\x47\x2f\xe4\xcc\x79\x18\xa6\x12\x47\x71\xad\x4f\x4d\xd3\x59\x40\xc8\x1f\xe0\xb2\x0e\x53\x31\x0d\x1e\x46\x52\x20\xc9\xde\x68\xb7\x1d\xd7\x2b\xcc\x62\x5a\xd2\xee\xfc\x30\xd3\x03\x45\xaf\x4d\x75\x72\x25\x3e\xfe\xf6\x31\x23\xb1\xf9\x1a\x9a\x76\x00\x6e\xc7\x80\x12\x1e\xc6\x3c\x46\xf8\xc9\xf1\x54\xbf\xbd\xca\x06\x5e\xf6\xf2\x22\x8c\xdb\xad\xe0\xdd\x84\x0c\xe3\x80\x61\xf9\xc8\xe2\xf6\x8f\x87\xf5\xf3\xeb\x7a\x8b\xcc\x57\xeb\xed\xf8\x93\xc6\x81\x64\xbc\x0b\x39\x1d\x8e\x1d\x10\x84\x87\x71\xcc\x31\x95\xfd\x52\x41\x53\x56\xb9\x9c\x17\xa2\xf0\x8d\x13\x33\xa1\xd6\xf8\x56\x5f\x49\x0c\xf0\x30\xe1\xc4\xe1\x84\x06\x72\xb1\xbb\xef\xe2\x1e\x61\xc2\x49\x6a\x9b\x34\xed\x5e\xa0\xc2\x34\xb8\xe8\x0e\x2b\x8e\xe0\xaf\x27\xa8\xb4\x6c\x4e\xf5\x2d\x78\x99\x59\xce\xc3\xd4\x64\x98\x8f\xed\x85\x04\xcd\xab\x6c\x72\x7b\xee\x1b\x38\x57\x08\x6d\x58\xf8\x5e\xe5\x4d\x33\xe0\x63\x1d\xbd\x4f\x96\x68\x84\x16\xbf\xec\xe5\x79\xf9\x26\x8f\x43\x63\x33\xcc\x14\x15\x29\xbd\x90\x4a\x8e\xcf\xe3\x8c\x47\x79\x66\x93\x80\x18\x96\x8f\x52\xbf\xf7\x71\x16\x1f\x29\x0b\x55\x68\x71\xbb\x79\x2b\x3f\x9f\x64\x71\xbe\x3f\xc9\x4a\x16\x0d\x74\x56\x63\xa8\x80\x88\x9f\x3b\x31\x36\x5a\x38\x6d\x97\xf5\x71\xed\x0c\x73\x18\x79\x59\xbd\x7f\x29\x4f\xd5\x45\x2e\x61\x3c\xef\x4d\x90\xe2\x24\x2b\xca\x66\xf5\x43\x03\xb4\xaf\x40\xa4\xfe\xc7\xc9\xc8\x33\x71\xa6\x5c\x54\x63\xf9\xfa\x28\xa7\x8c\x55\x3c\x34\xa9\x02\x57\x48\xf8\x15\x3e\x2f\xf4\x5c\xdb\x16\x32\x80\xc0\xa1\xab\xbf\xe7\xcd\x1b\x6e\x48\x57\x86\x85\x01\x16\x79\x95\x51\xc2\x72\xb4\x5e\x5b\x59\x99\x7a\x1a\x6f\x09\x21\x4c\xd1\x81\xd6\x65\xd1\xba\x95\xa7\xbd\x24\x59\x65\xf8\xd1\x4d\x2b\x88\x55\xe0\xe2\x1e\xb7\xd0\xfa\x04\x50\xe8\x7c\xa6\x8c\xe3\x17\x7f\xdd\xd5\x2c\x03\x64\x78\xa1\x2a\x36\xbf\x57\x85\x36\x23\x6a\xbc\xa3\x3c\x5f\xac\xd8\xa3\x45\x82\xda\x47\x2c\xce\xb0\xcc\x02\x99\xa0\xdd\xf7\x1c\x16\x67\xb7\x2d\x0c\xea\x95\xd8\xb2\xda\xe5\x1f\xb0\x79\xcb\x27\x7b\x7b\xc4\x03\x25\x9d\x71\xb5\xd9\x7c\x1f\xa5\xba\xc6\x0d\x23\x21\x90\x7e\xf8\x4b\x69\x2e\x44\x07\x7d\x13\xc3\x70\x42\xf5\x18\xaa\x3e\xe7\x12\x45\x36\xc6\xa5\x0f\x03\xec\x37\x48\x97\x5c\x35\x57\xd4\x0f\x78\x14\x07\x0a\xa1\x07\x2b\x7a\x22\xb2\xfe\xfd\xa5\xe2\xd8\x98\xa4\xe7\x05\x7b\x92\x3f\xba\x23\x89\xcd\x22\x47\x8c\xd6\xee\xf6\x7f\xca\xd9\x77\x49\xb2\xc0\x84\x54\x43\xba\x6c\xf7\xb5\x83\xec\x6a\x0a\x78\x94\xf2\x14\x63\xce\x79\xdd\x4e\x0c\x5d\x12\x3a\xa7\x3b\x9a\x09\xc4\x6c\x6e\x29\xf6\x4d\x94\xc6\xb3\x5f\x39\x4a\x6d\x9c\xc5\x3d\xe0\x4b\x56\x55\x2e\x77\x70\x31\x9d\xae\x60\x14\xdd\x45\xb2\x24\xd6\xa1\xe7\x00\xe0\xfe\x29\x32\x1b\x8c\x1c\x18\x97\x57\x39\x1d\xf3\x6b\xcb\x64\x94\x59\x12\x49\xcb\xeb\xc5\x7c\xf6\x2d\x92\x61\x00\x59\x07\x02\x6b\x3d\x01\x17\x9c\x9a\xcc\x97\x48\x25\xa4\xbb\x5e\x43\xf3\xfc\x01\x95\xf3\xdc\xd0\x2c\xff\x52\xee\xcd\x5c\x49\x08\x8f\x94\x09\x1c\xc1\xdc\x5f\xa0\x9b\x1e\xf2\xe1\x51\x28\x9e\x69\xbf\x6d\x69\x21\xe9\xe2\x47\xfa\xfc\x24\x8f\x93\x27\xd5\x10\x04\xc2\x15\xac\xe1\xef\xce\x67\x1a\xb7\x82\x20\xf3\xa4\x75\xe8\xfc\x68\x8f\xb3\xf3\xc7\xb3\xc0\x97\x58\x7d\xa3\x37\x7c\xea\x8c\xa9\x08\xb4\x46\x0b\xb4\x1d\x63\x8e\x34\xa7\x57\x44\xc7\xe3\x10\xea\x61\x7e\x78\x96\x6f\xc4\x35\xb6\x82\x14\x44\x48\xe1\xf4\xe6\x74\x86\x8a\x9c\x98\xf1\x03\x5b\x41\xcc\x32\xdd\x7e\xd5\xb1\x01\xf3\xc8\xc6\x09\x8e\x6c\x8d\xb9\xc0\x9e\x9d\x84\x47\xd6\x30\x8c\x16\x63\x1e\xda\x53\xd1\xff\xbd\x44\x3c\x8f\x99\x4c\x99\xb3\x56\xbe\xe7\xc5\x06\x0d\xf2\x2b\xc1\xf9\x98\xa9\x0c\xb5\x75\x3b\x5c\xfb\x8b\x3c\x57\xe5\x7e\xff\x7a\x2a\x3e\xe5\xd9\xb1\x1f\xf9\xde\x8d\x39\xd3\x22\x22\xb2\xb4\xee\xa7\x20\x04\x12\x5d\xab\xdf\xfb\xdf\x2c\xba\xeb\xbb\xd2\xdc\xc8\xa2\xff\x39\xe3\x88\xd2\xd9\xc9\x06\x3e\xbb\xd8\x51\xcc\x65\xa4\xd3\x2e\xae\xff\x74\xfe\x52\xd4\x73\x48\x11\x1e\x73\x23\xd0\x7c\xeb\xd1\x41\x0d\x3c\xd4\x28\xec\x3d\x35\xfd\x63\x21\x42\x1c\x27\x7b\x59\x37\x9b\xcf\x72\x71\x50\xb2\xae\xa5\x29\xab\x76\x74\x75\x1b\x68\x1c\x0a\x8e\x51\x99\x23\xe5\x3a\x57\x07\xa8\xe4\x50\x8f\x72\x7c\xd1\x10\x38\x77\x83\xcf\x27\x6e\x7d\x81\xed\x30\x53\x11\x47\x82\x63\xaa\xec\x6b\x89\xd5\x51\x97\xfc\x9f\x93\x17\x8b\x0c\x55\xa4\xb6\xe3\x0e\xe4\x01\x79\x29\xdc\xa1\x38\x09\x82\xc8\x2f\x15\xaf\xd0\x54\x39\x7c\x74\x99\x76\x74\x77\x77\x81\x6f\x9b\x80\xc6\xcd\x98\xa2\x24\x23\x0b\x20\x4e\x93\x44\xf7\x9a\x4e\x4e\xa6\xa5\x17\x9a\x74\xad\x64\x6c\x11\xb6\x3b\x20\xd7\x4c\x86\xe4\x9a\x3c\x96\xa9\x20\x62\x80\xbc\x5d\x9f\x8e\x9b\x4a\xea\x77\xa8\xb6\xfe\xb0\x8a\xa2\x58\xf9\xc8\x14\x54\xbc\xfb\x3d\x91\x32\xeb\x73\x29\xf7\xb9\x6d\x9e\x0b\x0d\x33\xf2\x55\x3c\xd6\x41\x88\xfc\xa6\xdb\x1e\x68\x44\x24\x1b\x93\x87\xd5\x31\x69\x80\x53\xcc\xd1\xe6\xcd\xa5\xde\x18\x8f\x75\x26\x54\xe2\x91\x7c\xfa\x62\x3a\xa7\xff\xb8\x4c\x45\xc5\x26\x25\xe5\x3f\x24\x12\x23\xd3\xed\x70\x11\x16\x8e\x21\x4d\x44\x3c\xac\xca\xbb\x95\x8e\x47\x9c\x40\x9f\x03\xad\x42\xdf\x0b\x20\x33\xd6\x43\x14\x56\x9b\x2f\x4b\x59\x19\xa7\x99\x92\x2b\x97\xd7\x18\xd6\xe6\xfe\x2a\x30\xd3\x77\x9a\x55\xc2\x2f\xdf\x9b\xce\x32\xde\x7c\x99\x74\xad\x05\xe2\x6e\x5a\xee\xf3\xe3\x11\xaa\x39\x45\x8b\xcb\xf5\x24\x61\xa1\x8d\x5c\xc2\xbf\xdd\x9a\x1f\xfb\x9d\x33\x61\x32\x41\x36\xc6\xcf\x6e\xc1\x5f\x96\xe5\x9e\xb2\x6a\xb9\x17\xb9\xe4\x09\x8f\x02\x4c\x5b\x2f\xcb\xea\x88\x37\x9d\x9d\x5f\x09\x8f\xb4\x97\xad\xc4\x90\x45\xeb\xcb\xdc\x95\x0e\x76\x71\x83\x30\x89\xc9\x09\x49\x84\xbe\xc9\xc3\xea\xee\xe6\x95\x87\x93\x60\x59\xc2\x33\xe3\x37\x8b\x2e\x4f\x52\xdf\x95\xd5\xd0\xf1\x70\x4d\x45\x0a\x9a\x96\xe9\xdf\xaf\x54\xd4\xf0\x24\x10\xa9\xca\x9c\x10\x65\x6e\x28\xeb\x7c\x85\xfc\x67\x70\x52\x62\x12\x37\x4a\xef\x2a\x80\x41\x16\x3b\x09\xd2\x04\xe7\xb6\x2a\x94\xdf\x30\x57\xae\xf0\xc7\xb7\xd0\x12\xc5\x9e\x97\xb2\x7e\xbb\x91\x7a\x94\x68\x4b\xc2\x18\x7c\x09\xe0\xfa\x28\x35\xd4\x6f\xf9\xd1\x69\x6e\x0d\x57\xa3\x24\xd4\x52\x74\x8a\xe6\x8f\x65\x5d\x0f\xe3\x2e\x49\x14\x12\x83\x61\xbb\x50\xbe\xc8\x0a\x0a\x8a\x0a\xf8\xc3\xb1\x60\x51\x07\xf5\xf9\xe1\xd0\x25\xff\x3c\x95\x3d\x08\xd4\x35\x4c\x44\x82\x0d\xff\x7d\x8d\x09\x77\xd2\x2f\x49\x10\x21\x5c\xe7\x2b\x7c\xfe\xb3\xbd\xe6\x9c\x02\x20\x4f\x92\x38\x8c\x54\x57\x40\xf6\x31\x6f\xe4\x24\x49\x9c\xa0\x21\x4f\x99\x0b\x14\xba\xfd\xc5\xcd\x13\x12\xf0\x26\xc9\xfd\xa1\x0d\x90\x24\x69\x26\x3c\xe7\x18\xd9\x40\x37\xe7\xc5\x8c\xbd\x99\x24\x46\xe3\xd6\x51\x9c\xf6\xfb\x3b\x39\x0d\x72\x27\x29\x23\xb7\xe6\xf9\xfb\xd7\x2e\xda\x97\xa4\x8c\x7c\x69\xa8\xb4\x60\x4d\xd7\xc9\x69\xa6\x90\x06\xa7\xf8\x4b\x8d\xbe\x70\x6a\x29\x2d\x7a\x52\xb9\x6c\x64\xd5\x7a\x9a\xa3\x67\xcd\x78\x10\xa7\x1d\xf4\xc7\x55\x33\x3e\xe8\x92\xf0\x2e\xbe\x51\x42\x40\x18\x8c\xf4\xd7\xf0\x52\xc1\x21\x3f\x1d\x26\x5f\x2f\xd3\x16\xf3\xa4\xfb\xf2\x13\xfd\x69\x9c\x7e\xa3\x71\x22\x99\x24\x8e\xa6\xb2\x3e\x94\xa3\xa7\x94\x61\x28\x9c\xb7\xf1\xf0\xb0\x5d\x4f\xae\x2c\x23\x85\x01\xa3\xcb\xe2\x73\x9e\x28\x9e\x61\x4c\xaa\x2e\xf7\x0e\xa5\x4c\x16\x94\x3f\x1c\x26\x8c\x0c\x7f\xfa\xe8\xe3\xa1\xa1\xe2\x48\x90\xc6\xc6\xa7\xac\x4c\x5e\x34\x50\x7d\x74\xf6\x66\xa2\x25\x60\x18\x1c\x4c\x4e\x5e\x09\xa2\x86\x7b\x94\xdc\xc4\xfc\x4d\x4c\x48\xd4\x95\xc8\xd0\x61\x5c\xa8\xde\xab\xa1\xf2\xc4\xa4\xc2\xc4\xce\xb9\xc3\xc9\xe5\x77\xb6\xc4\x64\xa1\xa3\x23\xe9\xa4\x02\x86\x74\x24\x3c\x31\x46\x62\xc6\xeb\x13\x72\x02\xdc\x3c\x14\xa3\xad\x39\x31\x20\x30\x9b\x73\x1c\xc1\x8d\x26\x23\xd6\x58\x0a\x43\xfa\x85\x76\x9c\x75\x4a\x20\x16\x3e\xff\x86\x29\x3e\xd2\x5b\xaf\x1d\xbe\xe6\x26\xef\x46\x83\x75\x12\x4d\x4e\xec\xfd\xdf\x3f\x2e\x75\x1d\x79\xca\x92\x94\xbe\x0b\xc8\x4a\xbf\x39\xdd\x39\x7f\xcc\xc4\xb8\xa6\xb6\xa7\xef\xef\xba\x04\x14\xee\xbd\x5f\x4f\x07\xd2\x2a\xeb\x1a\xdb\x34\xe8\xf9\x67\xee\x9e\x5e\x3c\xbb\xe8\xac\x3b\x9a\xf2\x40\x84\x3d\xad\x46\x35\x3d\x1a\x05\xe8\xac\x22\x29\x72\x6b\x27\x2d\xcc\x47\x5e\x97\xd5\x28\xff\x91\x72\x19\x12\x3f\x30\xfa\xcf\x88\x7c\xe9\xd0\x22\x93\xfd\x21\x15\x42\xa3\x71\xf0\x6d\xf3\xf2\xd8\xfd\x16\x98\x10\xe7\xed\x92\xa0\x8d\xfd\xef\x40\xb8\x79\xba\xe9\x80\x6b\xc4\x37\xd0\x49\x16\x77\x34\xbd\x79\xbd\x35\xdd\xc6\x9f\x06\x5c\xe0\x5a\xd1\x40\xdd\xdc\xc9\x7c\xff\x72\xda\xef\xbf\xbf\x41\x31\xd2\xd3\xe3\x69\x10\x0a\x1c\xb4\x34\x9f\xbb\xc2\xeb\xd6\x11\xec\x09\xf1\x27\x76\x81\x1f\xc1\x69\x18\x4a\xd9\x4b\x54\x8b\x4e\xa2\x9a\xa7\x11\x57\xb8\x34\xdf\x3c\x2f\x5e\x6f\xb7\x41\xf7\x73\x02\xe8\x71\xd7\x47\x28\xcc\xc2\x7c\x40\xd5\xe4\xb5\x67\x13\xbf\x58\x33\xd3\x48\xc6\xca\x79\x92\x37\x37\x77\xb2\x3a\x0c\xd3\x5d\x69\x1c\x86\x08\xbc\x79\xfe\x71\xd3\xe8\x5b\xb8\x54\xd7\xff\x5b\x66\x4c\x1a\x47\x24\x8a\xfc\x67\x5e\xfc\x99\xcb\xe2\x3a\xa5\x7a\xdb\x34\x66\x30\x80\xc9\xac\x9a\x37\x07\x68\x1b\xb7\x4b\x02\x40\xcf\x73\x0d\xcd\x7d\xbb\xd1\x5c\x04\x70\xd3\x24\x24\x9f\x92\x86\x9d\x1f\x24\x97\x59\x1d\xff\xae\x49\x1c\xe2\x8a\xda\x7e\xcd\x87\xa2\x6e\x64\x6f\xc2\x76\x48\xbd\x34\x49\x03\x84\x19\x3c\x50\xac\x71\x84\x6b\x9f\x7f\xa1\xc4\x50\xbe\xf9\xa3\x6c\xa0\x87\x54\xa4\x29\x4f\x31\xfb\x5e\x37\x65\x05\x6b\x2c\x17\x19\x4c\xc7\xd4\x4d\x99\x76\x09\x5d\x7e\x5f\xce\x57\x5f\xf9\x35\x33\x4d\x03\x1d\x1b\x47\x0b\xb0\x7d\xf3\xe4\x81\x3f\x01\x26\x5e\xf9\x4c\x69\xac\x30\xd6\xf2\x91\xc3\x67\x10\xfb\x67\xc9\x82\x10\x7d\x0c\x64\x28\xee\xf5\xdd\xfd\x61\xc9\x68\x80\x4a\x83\xd5\x53\xd3\xce\xf8\xf9\x1d\x65\x66\x14\x89\xb7\x7c\x40\x71\x02\x32\xf5\x27\x4d\x24\xa9\x4c\x75\x2a\x02\x48\x20\x36\xee\x00\xc5\x2c\xce\xe2\x5a\x8e\xf4\x67\x79\xaa\x22\x62\xa2\x7b\x2c\x77\xed\xd2\xe2\x5c\x8e\x9e\xe8\xef\xca\x20\xd4\x4a\x63\xad\x2b\x72\x5b\x7e\x6f\x57\xf8\x2e\x0d\x94\x6a\x90\xe8\xee\xb6\x96\xd5\xc2\xfc\x75\xea\x9c\xba\xd4\xc8\xd8\x3a\x9b\xb0\xf5\x86\x7a\x02\xd8\xf1\xc5\x8d\x49\xb1\x2a\x17\x71\x17\x50\x2f\x6c\x03\xd5\x72\x5f\xd6\xd3\x17\x07\x6e\x91\x35\x72\x87\x6c\x12\xb8\x7d\xad\xa1\xca\xbb\xcd\x30\x85\x80\xab\xc4\xdb\xd5\x55\x85\x12\x88\x57\x75\xdf\x78\xc6\x22\x8e\xa3\xe4\x9e\x34\x9a\xe7\xd7\x83\x8c\xc5\x61\x42\x7c\x7a\x67\xa8\x3c\xe1\xfb\xdf\xfa\x98\x19\x8f\x35\x4e\xc9\x76\x95\x7b\xd0\xe5\x84\x22\x65\xb6\xa7\xb3\x20\x00\x1c\xe8\xf8\x4d\x0e\xa7\xe6\x12\xe9\xf4\x8b\x9b\x06\x89\xd6\xc6\x7b\xd2\xdf\x88\xb8\xa9\x35\x0c\xbc\xfc\xc0\x95\xb3\x20\x48\x3d\x21\x2e\x01\x05\x83\xf9\xa1\x90\x85\x60\xb0\xda\xe6\x28\xcf\xa8\x53\xdd\x4f\xd2\x2c\x12\x01\xb1\x90\x14\xaf\x54\x8b\xef\x7e\x8f\x19\x89\x4b\x16\xf0\xb9\x3c\xeb\x7d\xff\xbb\x20\xab\xd7\x4b\xe0\xdd\x3e\x7c\xed\x0e\x85\x59\xe0\x42\x54\xff\x53\x2a\xbf\x56\xd5\x73\xeb\x54\x16\xc7\x19\x0e\xce\x7b\x2c\x44\xcc\x8f\xf7\x79\x63\xbb\xeb\x18\x30\xd2\x63\x0d\xba\x01\x7f\xe5\xd5\x62\xab\x62\x36\x52\xc3\xd8\x94\x2f\x08\x03\x29\xcb\xfd\x4f\x72\x3e\x59\x12\x64\xd6\xba\xa4\xa3\x6c\xb0\xd4\x64\xd5\x27\xf3\xb2\x2c\x31\x58\xfa\x73\xb3\x58\xaf\xb6\xb7\xdf\x5e\x51\xb5\xc9\x1f\x94\x2e\x2c\x84\x19\xec\x3b\xa7\xf0\x3e\x88\x94\x67\x4a\x08\x5a\x12\x5a\x23\xa4\xa3\x53\xe7\x99\xe6\x5a\x04\x3e\xe2\x86\xd1\xa1\x9f\x8c\x75\xad\x84\xb5\x3d\x4d\x70\xae\x9d\x2c\xde\xc4\x54\xcd\xb4\x02\x34\x00\xab\xc6\x29\x1d\xf4\x66\x44\xa6\x35\xf1\xc3\xd4\xd0\xf8\xa2\x9f\x19\xe5\x4d\x9e\x69\xc8\xd0\xfb\xfe\x70\xc5\x31\xb3\xf4\xe7\x3c\x33\x4c\x23\x34\xe7\xf6\x74\x50\x83\x54\x70\x66\xb2\x04\xc0\x55\x65\x87\xa3\xd2\x95\xf6\x98\xc2\xd2\xd3\xdf\x4f\xa6\xa4\x28\xc4\x88\x2b\x80\x67\xc6\x70\x35\x28\xf8\x41\x3b\x7b\xc4\xd2\xc2\x33\x60\x34\xea\xb0\xc3\x9f\x7a\xbe\xac\x81\xcb\x9a\x41\x44\x72\xa5\x18\xc1\x70\xca\xb6\xdd\x31\x45\xd2\xd2\x3b\xac\x9a\x40\xa4\xc6\xd2\x45\x7b\x5f\xaa\xd2\x95\xb3\xfb\xb6\x5a\x05\x51\x17\x15\x95\x48\x26\xb5\x83\xaf\xbe\xd8\x8c\x67\x00\x21\x06\x77\x94\x6c\x90\x7b\x4d\xc3\xde\x1b\xb5\xd3\xd0\x75\x06\x4e\xaf\xdc\xc8\xca\x27\x0d\x32\xdb\xae\x9f\xb4\x30\x6f\xca\xd6\x7d\xee\x0f\x00\x51\x22\xee\x65\x7e\xe8\xf8\x12\x4f\x3d\x0d\x39\xcf\xac\x70\x75\x73\x5e\xea\x1a\x56\x37\x9b\xe5\x14\x1a\x9a\x59\xa1\x11\x0e\xe1\xe3\xf5\xcb\x19\x3d\xb1\xc9\x44\xb2\x81\x30\xdd\x1a\xf4\x50\xdf\x82\xec\x7a\xdf\xa6\x04\x32\xaf\x4f\xc7\x63\xd9\xa5\x7e\x33\x6b\x80\xc8\xea\xde\xa4\x88\xe2\xd2\xae\x67\xb4\xd8\xa8\xa9\x64\x2c\x40\xcc\x2f\x49\xa4\xf6\x5e\x4c\x77\x7b\xc9\x32\x89\xeb\xae\xcc\xab\xdb\xcb\xe0\x9d\x64\x9a\x63\xf4\xcf\xd4\xff\x39\x0d\xb6\xd7\xf1\x3b\x48\xce\x22\xe2\x06\x46\x05\x9d\x4d\xf9\x15\x7e\xa0\xa2\xd0\x78\xb0\x4b\xce\xe2\xac\x6d\xb6\x7a\x5d\x0a\x11\xfc\xcd\xd0\xb5\xe4\x51\xe0\xb9\x39\x31\x0c\xf1\xf5\x74\x58\xe7\x85\x86\x87\x7e\x9c\x49\xae\x02\x4e\xbc\x00\x87\x83\x2c\xcc\xbd\x0b\x16\x0d\x86\xa9\x0c\x75\x82\x89\x69\x75\x3a\x5f\x41\x75\xca\x48\x26\x88\xde\x38\x76\xf0\xef\x4d\xf9\x7b\xee\x99\xa3\x78\xeb\xb6\x22\x5d\xec\x81\x50\xa9\x14\x14\x99\xb0\x31\xfe\x34\xaa\x2b\x93\x38\x11\xd9\x24\x9f\xf3\x50\xa0\x94\xd2\xb5\xbd\xce\x8f\x2d\x99\x32\xa2\xb1\x76\xc7\x27\xd4\x43\x5c\xa6\x29\x07\xbf\xe4\xc0\xf8\x4b\xf1\xe9\x07\x4b\x53\x40\x37\xfa\x58\x0d\x6b\x90\xb9\x4c\x6d\x88\x4a\x5a\xfb\x76\x65\x76\x72\x84\x7e\x38\xca\x2c\xe5\xd8\x3d\xab\xcd\x97\x41\xf9\x88\xcc\x74\xa0\x85\x63\x17\xbe\x7d\xde\x2c\x27\x01\x46\x99\x59\x8e\xfc\x92\xc5\x28\x44\x20\x65\x02\xc2\x41\x58\x7f\x87\x8f\x7c\x52\xab\x21\xa5\x4d\xd1\x29\xfd\xb2\x7c\x19\x9d\xa6\x38\x11\x88\x7b\xa2\xdc\x4d\x39\x04\xbc\x8d\xaf\xa1\x04\x11\xcc\x7d\x39\x9b\xaa\x6c\x97\x4d\x57\x49\xd9\x5d\x2b\xe0\x58\xb2\x40\xa9\x2a\x0f\x52\x1d\x9b\x87\x52\x0b\xa6\x7b\x41\x3c\xc7\xdd\x3b\xaa\x4a\x91\x46\x49\xe9\x3d\xed\xbc\x6e\x9e\x6d\xcf\x8f\xe5\x5a\x40\xc8\x30\x0c\xef\x1f\xe0\xda\x68\x19\x3f\x3f\xc4\x12\x57\x77\x22\xd5\xf8\x7b\xa7\x40\x40\x42\x3e\x98\x28\x1b\xc6\xfc\xa4\x65\x09\xf4\xba\xb2\x5b\xf8\x98\x48\xfb\x70\x69\x03\x27\xa8\x9c\x0f\x2b\x8d\xfc\xc1\x38\x8a\xc7\x2c\xd4\x63\x1a\x1b\x2e\xad\x95\x91\x2b\xda\x5f\xed\x76\x1b\xe9\xa3\xd7\xdc\xd3\xf0\xfb\xa1\xac\x58\x44\xd4\x09\xed\x7b\x21\x49\x73\x55\x1e\x5b\x57\x13\xae\x60\xe9\x95\x50\x02\x6b\x3c\xef\x5e\x7f\xf7\x69\x07\x15\x44\x54\xd8\xb9\xb8\x5f\x0f\xb6\x44\x15\x3a\x1a\xac\x9e\x99\x4d\xfc\xf6\xf3\xb0\xb9\x3b\x31\x0a\x63\x4b\x10\xad\xaa\x46\x49\xee\x4d\xb7\xff\xfb\x6b\xc7\x41\x46\x0c\x93\xd4\x01\x4e\x99\xb7\xef\x63\x15\x07\x12\x91\x28\xbd\x18\xa8\xc3\xcf\x7c\xfd\xf6\xe4\xc1\xf5\x2a\x61\x0c\xc1\xa6\xaa\x2c\xdf\x31\x76\x5e\x5f\x89\xf0\xa8\x24\x61\xf8\xda\x0f\x87\x76\xfd\xdf\x40\xdd\x2c\xba\x8b\x98\x30\x0d\xfa\xd5\xe0\x5e\xe6\x97\xe6\xb2\x6b\x9a\xda\x8c\x94\x58\xe5\x19\xfd\x85\x49\x81\x8c\xca\x92\x00\xab\x9e\x06\x29\xb4\x2e\x34\xbe\x86\x3d\x72\x5b\x4c\x77\x3a\x95\xa5\xc0\x29\x35\x3b\x22\x0c\x98\x73\xb7\x55\x66\x01\x57\xa6\xbb\xb2\x7a\xf7\xf5\x2d\xf3\xdf\x59\xc6\xc4\xd1\xb3\xad\xa1\xf9\x76\xdc\x55\xd2\x80\x54\xf9\x3e\x6f\xce\x33\x30\x11\x25\x25\xe0\x1a\xb1\x1c\xc8\x4c\xfd\x3d\x77\x43\x49\xc5\x42\x3f\x9a\x91\xa0\xf5\xee\x54\x98\xb1\x01\xa5\x94\x60\x68\x0f\x0f\x14\xef\x9a\x3d\x50\x04\x74\xfe\x7b\x29\xc5\x11\xb9\xb9\x2b\x1f\x3b\x7d\x39\xae\x94\xb1\x98\x91\x3f\xc8\x1f\xcf\x47\x28\x16\x4d\x23\xf5\x7b\x77\x17\xcd\x24\xc6\x81\x6e\x4e\xe7\xd1\xfe\xfc\xab\xe8\xc8\xe4\xd6\x3a\x0a\x10\x63\xde\x3e\x68\x87\x71\x50\xda\x44\x48\x2b\xb4\x06\x1c\x3d\x93\xfe\xd3\x26\x0d\x10\xb8\x97\x17\xe3\xd8\xa1\x32\x69\x84\x2b\x5a\xdb\xeb\x46\x74\xbf\x5a\xa2\xa6\x6c\x1d\xee\xaa\x99\xd6\x52\x73\x05\x21\x03\x36\xd8\xdd\xae\x79\x63\x97\xb1\x56\x05\x9a\x21\x9a\x7c\xf5\x47\x37\xbf\xc1\x04\x98\x62\x82\xfc\x28\xd8\xe2\x6f\xc8\x40\x73\x65\xe3\x14\x33\x36\xdb\x1c\x09\xe6\xaf\x81\x39\x47\x63\x6f\x88\xb4\x51\x16\x18\xce\x5f\x02\xec\x7c\xcf\x0b\x94\x25\x1f\x77\x9b\x66\x49\x1c\x66\x9e\xb9\x3c\x2f\x7c\x0e\x71\xf4\x28\x9a\x65\x9c\xf2\x7a\x3e\x89\xfe\xf5\x74\xf8\x0e\xf9\xa6\x24\xee\xfb\xd9\x8f\xa8\x99\x62\x38\x13\xb7\x88\xea\x3b\xec\x68\xb0\x09\x31\xbd\xb6\xcd\xb0\x2c\x4f\xe5\x85\x41\xe0\xed\x83\x81\xa2\xc9\x9b\xf3\x9c\x0d\xa8\xb9\x20\xca\x8e\xc7\xe5\x70\x23\xd5\x3c\x08\x11\x85\x55\x9f\x0e\xa3\xd8\xb3\xe6\x91\xc1\x90\x8d\x2f\x0e\x77\x81\x81\x69\x2f\xf0\x8c\xe4\x5b\xd7\xc7\xdc\x40\x85\xc1\x3f\x7f\xc4\x68\xa4\x27\x39\x94\x85\x7c\x2f\xff\xca\x0f\x92\x31\xde\x1f\xa4\x6a\x20\x69\xcc\x13\x18\xb9\xbf\xa1\x84\xd9\x69\x80\x71\xd3\x22\x05\xde\x4b\x9b\x3a\xe2\x55\x3f\x61\x74\x10\xc4\x98\x5b\xa8\xca\xb3\xdc\x37\xe7\xd6\x6b\xea\xe0\xdd\x23\x27\x4c\x07\x32\xc6\xbc\xcd\x3d\x34\x8f\x27\xfd\x7e\x26\x52\x9d\xfe\x42\x16\x30\xcd\x45\x40\xe1\xc7\x21\xe3\xf5\xf8\x55\x43\x13\x5a\x27\xfb\x72\x38\x15\x79\x83\x25\x70\xbf\x75\x07\x15\x1e\x94\xe4\x8a\xbc\xc2\xf1\xd4\x48\xfa\x57\x4f\x49\xcb\x75\x08\x5c\x90\x67\x5a\x36\x5f\x64\xfd\xf6\x6c\xc7\x76\x86\x8e\x04\x68\xd6\x65\xd5\x50\x72\x71\x4a\x42\xc3\x75\x94\x90\x6a\x57\x93\xff\x40\x52\xb6\xf1\xb4\xd5\x91\xa4\x98\xf2\xbe\xdc\x39\x15\xae\x0b\x73\x5a\xc7\x2c\xe4\x2e\x41\x84\x91\xf0\xc9\x67\x4d\x0c\x49\x77\xe2\x0c\xfa\x0a\x9f\x6b\xa8\xf2\xce\x8e\xd1\x29\x58\xc4\xf2\xee\x73\x0b\x8b\xc9\xb3\x65\x9c\xe3\x97\x3d\x15\x15\xd6\x51\x5e\x59\x24\x75\xc6\x89\x18\x2d\xaf\xbf\xb5\x7e\xf1\x0c\xca\x5f\x67\x81\x41\xea\xa7\x2e\x8f\xbe\x85\xe6\x6d\x5b\x0d\xab\x96\x75\x16\x06\xb8\x62\x2c\x9f\x9f\x9e\xbe\x7d\x7d\xd8\xfc\x6b\xfb\xba\x5a\xaf\x5e\xff\x58\x75\x0d\xd2\x84\xbb\xf4\xcd\x53\x8d\x28\xed\x1b\xb0\x65\x05\xdd\xf1\xcc\x62\x22\x02\x33\x34\xa3\xfc\x8c\xce\xb4\xb6\x71\xe7\x36\x75\x2a\x87\xe3\x9e\x92\x81\x8e\x91\x0a\x5a\x36\x65\xfd\x96\x8f\x2a\xa7\xb5\x62\x4a\x3b\xa7\xe5\xa5\xe7\xad\x21\xc9\xdc\xef\x79\xf3\x76\x29\xa5\xc6\xb5\xb6\x29\xa6\xd3\x94\x47\x09\x78\xc7\x43\x9b\x2c\x45\x43\xb5\x0b\x63\x2e\xf6\xfb\xde\xbe\x9a\x16\xd0\x69\x23\x43\x9c\xf1\x47\xe8\x76\x02\x6d\xac\x48\x9c\x6a\xc7\x1f\x50\x0d\x59\xc8\x5d\x03\x60\x22\x4e\x5c\x4c\x59\xee\x60\x3a\x97\x20\xa0\xf2\xea\x63\x59\x37\x4f\x65\x71\x57\x56\x4f\xae\x38\x7b\xac\x97\x47\x2d\xdb\x31\x72\xff\xcf\x2f\x7f\xd3\xc5\xd3\x10\x46\x08\xb1\x26\x99\xdd\xcd\xf3\x76\xf9\xba\x5a\x6c\x9e\x5f\xbb\x9b\x2b\x81\xa0\xd7\x7f\xe7\xbb\x7f\xcb\xdd\x28\xb9\xa3\x41\x93\xce\xf8\x0e\x6b\x34\x0c\xdc\x9c\xe7\xfa\xd6\x2a\x8e\x75\x34\x94\x02\x22\xd7\x61\x5a\xb9\x63\xb8\x08\x11\x1f\xda\xfa\x3e\x2b\x59\x9f\xc9\x23\xf0\x03\xc6\xf0\x88\x60\xc6\xed\x35\x5e\x01\x71\x0f\xf5\xf4\x0a\x09\x20\x4f\x31\xba\x86\x50\x6d\x5d\x51\x89\xbf\x82\xc8\x22\x24\x84\xd9\xba\x22\xe9\xaf\x72\x5a\x4e\x62\x82\x58\x75\xe5\x52\xd5\x07\x60\xd1\x1d\xb1\x7a\x75\x0d\xb4\x67\x1a\xbf\x29\xcb\xfd\x1d\xbf\x13\x77\xa4\x53\x3b\x91\x8c\xe2\x26\x64\x0c\x53\xcb\x78\x7e\x21\x4f\x4d\xfd\x87\xc7\x1e\xeb\xb7\xde\x00\x34\x21\x0f\xb1\x7c\x8e\x52\x72\x0f\xba\x1c\x70\x68\xa5\xbe\x8d\x0d\x3c\x9d\xe1\x4d\xbb\xdd\x0d\x40\xb1\x97\xdb\xb9\x89\x85\x41\x88\x21\x86\xfd\xd7\x03\x75\x9f\xf1\xca\x6a\xe2\x80\xe8\xa1\xbe\xc8\x43\xdd\x40\x35\x60\x0e\x19\xee\x55\x26\x51\xa4\xf2\x77\x2a\x86\x02\xe8\xee\x60\xca\x13\xeb\x90\x52\xdf\xea\x61\x8d\xed\x68\x7d\x35\x69\x1c\xe1\x04\xf0\xfa\x9b\x8b\xc2\x10\x99\xc3\x5d\x59\x7d\x29\x8f\x60\x4f\xbf\xe4\x80\xf6\x57\x4a\x74\xe8\x21\xe3\x7f\x47\xc1\xcc\x9f\x96\xd9\x40\xf6\x85\xe6\xb2\xd2\x6f\x8b\xc2\xdc\xc2\x07\xec\xcb\xe3\x25\x98\xc8\xc8\x98\x29\xd7\xe3\x7d\xd9\x81\x91\x59\x94\x39\xff\x57\x50\x77\x8d\x74\x00\x7e\xf1\xe8\x52\x52\x95\xcc\x5f\xc7\x41\x89\x7b\x77\x2c\x91\x5d\x56\x7e\x8e\x3d\xc9\xb7\xd3\x32\xe5\x8e\x3e\xfe\xa5\xec\x3e\x83\x04\x39\xa0\xdd\xed\x08\xdf\x5b\x9f\x85\xbe\xd7\x15\xf7\xc4\x48\x1b\xa1\x10\x67\x6b\x4b\xdd\x49\x55\x79\x8d\x25\x6e\x14\xe3\x09\x81\xe1\x1f\x4b\xfd\x4e\x85\xae\x93\xe9\xa2\x02\x85\xe1\xab\xbc\xf8\x28\xdf\xe1\x8f\x01\x73\xed\xd5\x8f\x39\x06\x95\xfc\xaf\xf0\x63\x56\xc5\x80\xc9\xc3\xf2\xb3\xa8\xd7\xe5\x69\x3f\x9d\xdb\x2a\x35\x18\xaa\x55\xad\xc5\x52\x4d\x9f\x43\x71\xa7\xd2\xd5\xbe\xfd\x4b\xb9\xcf\xf5\xf9\xf5\xb4\x77\x36\x68\x38\x55\xb5\x77\x67\x69\x91\xa0\xbc\xb8\xf3\x27\xe7\x2d\x2d\xa3\xc3\x48\x0f\x01\x55\x18\x66\xbf\x68\x93\xb0\xa0\xbb\x3f\x82\x99\xc6\x0f\xa8\xe3\xd4\xb3\x84\x74\xf1\x6f\xf4\xa9\x86\x88\x0e\xa3\x01\x5c\xb1\x43\xae\xb1\x68\x45\x49\xfd\x7e\x59\x55\xd4\x2f\x31\x46\xa4\x08\xb3\xd9\xba\x44\x69\x27\x24\xd8\x8f\x2b\x13\x64\x38\x8e\x29\x80\xe2\x0d\xf9\x71\x47\x98\xc8\x71\x8e\xd7\x50\xa1\x87\x38\x3d\x9e\xa6\x61\x47\x4f\xaa\xcb\xca\x8c\x02\x17\xc6\xd8\x98\xca\xae\x30\xcf\x4e\x23\x6f\xc6\x61\x34\x96\x67\x88\xf1\xd9\x1e\x5a\xd3\xf3\xb2\x52\xd2\xd8\x2c\x23\xf4\x6d\x1f\x50\x00\x66\x80\x52\xbb\x04\x9a\xe5\xec\xfd\x38\x88\x09\x00\x0f\x34\x62\x94\x09\x1f\xf9\xb0\x7c\xde\xae\x37\x8b\xfb\x15\xdf\xbe\xbc\xae\xb6\xeb\xc5\xe3\x2a\xec\x5a\x86\x0a\xc7\x08\xb8\x4a\x74\x6f\x55\x81\xe0\x82\x38\x3c\x21\x5f\x97\xb6\x59\x76\x95\x2d\x10\xc4\x11\x52\xb3\x50\xef\xba\xc4\xf2\x4c\x75\x14\x04\x69\x88\xa1\x1b\x5a\x12\x54\x29\x2b\xf3\x98\xa3\xc0\xb0\xcf\x24\xfe\x6a\x85\x18\xaf\x14\x10\x98\x98\xb9\x10\xcd\x36\xef\x40\xdc\xad\x1d\xe6\x9f\x2d\x4c\xb5\xe9\x51\xcc\x0e\xfc\xd0\x6e\xad\x4d\x67\xb8\x40\xa4\x32\x74\x88\xd1\xb3\xdd\xd6\xb0\xbf\x28\x29\x98\xdc\x36\x02\x49\x06\x2e\xc8\xc3\xd8\x28\x83\x38\xd1\x74\xa8\xbd\x81\xf7\x96\xbb\x3e\x8c\x1d\x3d\x16\x21\x3f\xb1\x10\x79\x42\x41\xe2\x1a\xa6\x61\x82\x29\xd8\x2f\x8b\xcd\xf2\xcb\xcd\x62\xf9\xfb\x6f\xdd\x01\x8d\x78\x27\xcc\x02\x4c\x18\x27\x5d\x93\x2c\x8a\x75\xea\x82\x1e\xed\x7e\xf5\xb5\x93\x0d\xe1\x90\xc5\x94\xda\x6d\x97\x2a\xa7\xf9\xf2\x8b\x77\xcd\x32\x92\xb8\x93\x55\x95\xf7\x30\x25\x50\xae\x96\xe3\xfe\xc7\xe2\xd4\xf7\xb6\x52\x16\xed\x2f\x8a\xde\x8d\x7b\x46\x27\x31\x26\xf5\x1e\xcb\x1d\x96\x03\x7e\x91\xfb\x8f\xbc\xd8\xad\x4f\xaa\xce\xcd\x05\x72\xf1\xca\xd3\xe8\x44\x85\x03\x4d\x8d\x17\x4a\xcf\x0d\x6a\xfe\xc1\xb4\x0e\x36\x3e\x6f\xf3\x59\x56\xef\x64\x66\xf9\x63\x89\xc2\x92\x10\xe4\x92\x6a\x9d\xe6\x81\xc2\x3e\x07\x60\xe0\x4b\xb7\xfe\x5d\x16\x93\x35\x1c\x6c\x4a\x2f\x6c\x9c\x24\x2d\x85\xee\x2f\x93\x8f\x69\xea\x4f\x50\x36\x76\xe5\x67\x77\x00\x17\x3b\x19\x58\xd0\x44\x95\xff\x26\x2b\xa0\x4a\x85\x9b\xf3\x1c\x65\x0a\x58\x6b\x51\xa8\x80\x0c\x0b\x5a\x5a\x16\xc6\x5c\xec\xe8\x3f\xa9\x20\xb4\x4c\xe8\x34\xe9\xe5\x17\x91\xb2\x70\x42\xaa\x3f\x3d\x23\x50\x18\xbb\xbb\xcf\x6d\xf3\x6b\xc9\xd6\xc9\xb9\x2a\x65\x6e\x1d\x47\x59\x34\x97\x01\xdb\x94\x48\x15\x38\x8e\x60\x59\x1e\x31\x0f\x76\x5d\xf4\x0a\xc8\xe3\x0b\xf2\x88\x22\xc6\xa4\xce\xf6\x3b\x9c\x1d\x6e\x7d\xd2\xca\xea\x6c\xb8\x07\x6d\x2a\x90\xf5\xa9\x9a\x44\xdc\xad\xe0\x89\x76\xa8\x82\x76\x6e\xcc\x42\xba\xac\xc8\x12\xaf\xf7\x5d\x9f\x0f\xaa\x4b\x17\xfb\xc3\x32\xc0\x35\x18\x0d\x35\x0f\x82\xf5\x6f\x24\x00\xcc\x00\xd0\x81\x3a\xe5\x4f\x03\x39\xaf\xd1\xd3\x04\x09\xe9\x1d\x21\x7b\xe8\x60\xcd\xb6\x01\x80\x36\x2e\x65\x31\x50\xef\x70\xe3\xcb\x86\x01\xc7\x95\xa6\x3c\x42\x41\x9c\x6c\xfe\xc4\x30\xb2\xe8\xc5\xab\xd3\xf9\x8f\x87\x9b\xd5\xa6\xfb\x3d\xe5\x58\xde\xfb\x50\x34\xd5\x28\xcd\x61\x43\xc7\x58\xfd\x3b\x54\x05\xec\x47\x65\x44\xbe\x85\x92\x98\x49\xcf\x31\xc8\x3b\xcf\x7c\xcd\x6d\x14\x46\x44\x5a\x7c\x90\x4d\xf5\xfc\xff\x26\xf4\xcb\x6d\x94\x42\xe6\xa4\xc6\xe9\x7d\x07\x85\x25\x36\xca\x52\xec\x8d\x76\xcd\x7a\x81\xaa\x2e\x0b\xb9\xff\x5a\x36\xf0\xdb\xec\x70\x8f\xe3\x10\x27\x57\xc7\xfb\x30\x25\x83\xb3\xb1\x24\xed\xa1\xbd\xac\x1d\x47\x6a\x97\x43\xb2\x89\x08\x11\x11\x87\x2a\xaa\xfe\xc7\x54\x90\x3c\xd9\x16\xa9\x9e\xf7\x79\xfd\xd6\xa9\x54\x8e\xaf\x2c\x03\x83\x4e\xc8\x23\xc0\xfb\xb2\xcc\x7f\xa2\x77\x3c\x6b\x6a\x5a\x19\x58\xf4\x9d\x3e\x21\xff\x56\x1b\x6f\xa3\x0e\x00\x3a\x56\x26\x46\x0a\xaf\xeb\xe6\x77\xbd\x1a\x33\xf3\x93\x4b\x69\xe9\x15\xc3\x3a\xa9\xb0\xb9\x89\xa3\x22\xca\xba\x60\xb7\x4f\x6a\x3e\x7b\xc7\xa9\x6b\x9c\xe2\x1a\xdc\xba\x8f\x5a\xb6\x2e\xf8\xf4\xb6\x4a\x9a\xd8\x29\x38\xfc\x05\xba\x2f\xd2\x9f\x5f\x2c\x8c\xb5\xbd\x30\x6e\x59\x21\x34\xc3\x1d\x02\x4e\x48\x89\xbc\x6e\x57\xbd\x0f\xb8\x04\xea\xf8\x86\x09\xd9\xa8\x07\x38\xe8\xe3\xf9\xe7\x8c\x79\xd6\x2a\x6e\xc2\x2e\x70\x32\x57\xad\x65\x2d\x10\x6f\x87\x73\xd7\x6e\x4b\x7d\xc9\xc8\x23\x18\x8b\x20\xa2\x1a\x77\xf8\x31\x98\x4f\x82\xb1\x98\x63\x19\xb8\x0b\xb7\x8d\x7a\x5b\x30\x96\x64\x44\xe0\x6e\x8c\x9b\x48\x9b\xf2\x7e\xea\x64\x0b\xc6\xc3\x4c\x72\x57\x3e\xb8\x3c\xa9\xb1\x35\x2a\x18\x4f\x43\x94\x10\xdd\x7d\x2c\xef\xfc\x7d\x85\x02\x82\x69\x37\x6f\xe2\xe0\x9d\x4f\xc1\x02\x01\x91\x1b\x2f\x6b\x14\x1f\x94\xd5\xf9\xd2\x42\x15\x2c\x88\xb4\xe7\x0e\xc6\x72\xed\x60\xf2\x44\x41\x4a\x28\x70\x34\x6e\x06\x3e\xe1\xdd\xa9\x30\x2b\x89\x21\x52\xdf\x32\xb3\x18\x0b\x3a\xe4\x45\x83\x11\xd4\xc9\x95\xc2\xc8\xa0\x44\xcb\x1f\xbf\x6f\xc6\xe1\x97\x71\x07\x87\x4a\x2a\x8a\xe7\x1c\xfb\xf0\xb5\x8b\xe1\x08\x16\x6a\x40\x85\xca\xdb\xd6\xa0\x9e\x55\xb5\x10\x2c\x34\x02\xc1\x5e\xad\xad\x4c\x82\x3b\x37\xa7\xaa\xfb\x4e\x51\x94\x44\x1d\x54\x67\x64\x8b\xfb\x64\x20\xe7\xff\xe7\xdb\xa6\x49\x1c\x8e\x99\xff\xef\xab\xf2\x74\x9c\x0d\x20\x0a\x16\x65\x36\x26\x7e\xa8\x0f\xf0\xb5\x5b\x97\x81\x6f\xc1\xe2\xc8\x02\x1b\xc1\xf6\xfd\xc3\xc5\x46\x47\x43\x98\xc6\x20\xee\x30\xaf\x47\x2c\x58\x12\xca\x30\xee\x87\x6d\x2f\x3f\x2d\x58\xa2\x14\xe2\xc1\xba\x68\xe5\x20\x67\x28\x58\x62\x19\x6a\x6e\x61\x40\x75\x33\x2f\xa3\x21\x58\x2a\x45\x14\xf7\xea\x05\x57\x5a\x65\x2c\xc1\x98\x3b\xb9\x03\x9d\xbb\x38\x69\x14\x33\x64\x68\x70\xe2\x3a\x0f\xbd\x93\x2e\x58\xa6\xb8\xed\x19\x39\x46\xcf\x99\xd9\x04\xc7\x55\xe7\x65\xee\xc1\xec\xba\xa3\xca\x50\x55\x8d\xd3\xea\x9f\x47\x85\xb5\xcd\x52\x87\x7c\x6f\x1c\xd7\xce\x0d\x90\xe0\xc5\xe4\x21\x75\xc4\x7d\x59\x8f\x2b\x76\x7a\x05\x12\xfe\x1a\x99\x30\x6d\x43\x52\x0e\xeb\xf2\x28\xb7\x70\x38\x55\xd5\x80\x9a\x6f\xf2\x08\x3a\x01\xe2\xc9\x85\xaa\xc9\x6d\xee\x03\x67\x82\x69\x9d\x65\xb4\xe2\xa1\x46\xfd\x40\x22\x5d\x30\x23\x81\x64\xfd\xdc\x73\xcb\xfd\x28\xa7\x38\xbe\x03\xc4\x1a\x5d\xe9\xad\x6d\x37\xb7\xf3\xa6\xf4\x71\xfa\x6e\x01\x81\xd4\x22\xbc\xa2\x7b\xe8\xa7\xbc\x68\x86\x15\xdb\x82\x59\x48\x30\x87\xb3\xa9\xca\xe3\xb9\x77\x37\xdb\x03\x69\xe6\x4b\xd8\xca\xbd\xaf\x62\x15\x9c\x73\xca\xd7\xac\x4f\x47\xa8\xa8\x80\x73\xae\x56\x6b\x38\x03\x38\x8f\x42\x5c\xff\xbb\x6f\x2a\xab\x26\x9f\xae\x18\x9c\xc7\x31\x75\xf1\x1e\x64\x45\xaa\x8c\x94\x19\x9b\x04\x2d\x2e\xf2\x67\x97\xb1\x67\xc1\x85\xe6\x18\x41\xa0\x45\x70\x44\x56\x2d\x78\x10\x67\x3c\xed\x72\x1c\xed\xe6\x65\x27\x09\x80\xd9\x7d\xa5\x3d\x11\xd0\x22\x5b\xbd\x2e\x93\x24\x59\xbd\x2e\x05\xbb\x91\x35\x5c\x63\x06\xbf\xc4\xc2\x0b\x1e\xc6\x02\xbd\xad\xb7\x7c\xf7\xb6\x76\x80\xaa\xd1\x14\xe7\xa1\x54\x98\xb7\x7a\xcc\x77\x6f\x4d\xd1\x61\x35\x05\x8f\xa2\x44\xb6\xa3\x63\xf1\x21\x1b\x59\xe5\x1e\x56\x28\x78\x14\x07\x08\x5f\x5e\xfc\xc8\xcb\x43\xdd\xff\xaa\x49\x66\xab\x28\x3f\xed\x5e\xbe\x8f\xd9\x3f\xe6\x9f\x76\x9a\x8a\x14\x3c\xb2\x29\x7e\x95\xaa\xd3\x23\x3d\x79\x52\x6b\xc1\x63\x48\xd0\x57\x85\x1f\xc7\xbc\xea\x5d\x0d\xbf\x7e\xf3\x24\x93\x48\x38\x7d\xa4\x78\x2f\xb2\xeb\xca\x49\x44\x4b\xf0\x44\xc5\x08\x74\x1c\x48\x6c\x7b\x46\x61\x73\x73\x7e\x02\x93\x63\xe1\xc6\xfc\x27\x49\x83\xcc\xd3\x6a\x0e\x29\x96\xd0\x25\x1e\x8d\x88\xd4\xc4\x8a\xb4\xff\x74\xe5\x69\x02\x04\xcf\x04\x25\x51\x71\xf3\x79\xb6\x83\x24\x49\xdd\x37\x51\x8c\x79\x5b\x0c\x33\x81\x5f\x5e\xc6\x19\x87\x7f\x8c\x5e\x3a\x53\x1a\xb1\xd1\x4f\xe5\x50\xb8\x5a\xf0\xcc\x10\x6a\x74\xf1\xf2\x84\x64\xac\x5f\x17\x9e\x39\x4e\x70\x19\x26\x18\x80\x2e\x4a\xd2\x91\x24\xae\xc3\xdf\xe1\xfc\xe7\x64\x92\xc8\x30\xc3\x02\xd0\xc7\xd3\x11\xf5\xf0\x66\xad\x25\xc1\xa5\x8a\x23\xef\x8a\xa3\x71\xb9\x3e\x96\x45\x0d\xb3\x9e\x90\xe0\xd2\x32\x5c\x76\x6e\xef\xd6\xbf\xb4\xe8\xdd\x29\x2a\x92\x62\xb4\xb4\x2c\xcb\xc3\x11\x8a\x7a\x50\x77\x22\xb8\x8a\x53\xdc\x73\x08\x68\xd7\x09\x92\xcd\xae\xd9\x5c\x0b\xc2\x5d\xaa\x53\x55\xbc\xfc\xf9\x48\x69\xcb\x97\x3f\x1f\x7f\x88\x8b\xc8\xc1\x2f\xfe\xdb\x5f\x30\x22\xe3\xe1\x78\x6a\x9e\x7f\x2a\x64\xee\xda\x9b\x38\x74\x48\xb0\xc2\x60\xd2\x73\xbc\x5b\x73\xa3\x74\xc0\x7b\xda\x34\xf9\x63\xf2\x69\x80\x19\x8c\xc7\xef\x4a\x83\x84\xf5\xfe\x3c\x88\x53\x8c\xcc\x59\x64\xe4\xba\x95\x67\xa4\xbe\x97\x55\xd3\x2f\xfc\x1c\x52\x8e\xab\xc2\xa9\xf8\x27\x31\xa9\xe4\xc5\x95\x6f\x05\x2a\x1b\xc0\xa7\xda\x05\xdd\x55\x3e\x5e\xf4\xd2\x68\xf4\x83\x15\x61\xd0\x9d\x86\x81\xd9\x19\xb7\x4a\x70\xcb\x24\x27\x8d\xb0\xba\xdc\x7f\x5c\x76\x99\x8f\x5a\xfb\xd0\xab\xe0\x56\x30\x8c\xc3\xb7\xae\x14\xa5\xb0\x5b\x67\xf9\xae\xac\x20\xdf\x15\x54\xb6\xe9\xde\x52\x30\x1d\x3b\xa0\x1b\x81\xc7\x2f\x63\xa3\x42\xf0\x24\xc0\xd4\x95\xaf\xbb\xbb\x88\x8e\x0a\xc1\x25\xa3\x08\xd9\x41\x37\xfa\xac\xa0\x3a\x94\x1f\xb9\xef\x6e\x21\xb4\x88\xa8\x52\xc9\x00\x1c\x46\x6b\x80\x10\x90\x20\x0e\x38\xaf\x7b\x32\x51\xd4\xfa\x42\x16\x32\xd7\x28\x88\x63\xdc\xb9\x5f\x16\xcb\xe5\xf3\xc3\xd7\x9f\xed\x6c\x22\x48\x78\x4c\x0a\x32\xed\xfb\x7c\x91\xfd\x45\xda\x6e\x19\x56\x1f\x9b\xc3\x4f\xc3\x70\x42\x84\x81\x8a\x7b\x8c\x2c\x09\x3f\x4e\xfa\x26\x4c\x28\x2a\xf9\x50\x68\x28\x9a\x65\x69\x2d\x0c\x13\x54\x42\x44\x81\x44\x98\x6c\xdd\x94\xc7\x71\xe6\x54\x88\x38\x60\x9e\x33\xf8\xa6\x2c\xf7\xa9\xf8\x6d\x9c\xa7\x6b\x5b\xc4\x8a\xfb\xe8\xf6\x41\xe6\x05\xb2\x8a\x9d\xeb\x4d\xb9\x79\xcb\x2b\xf3\xf2\xd6\x29\xa9\x0a\x11\x27\x12\x51\xa0\x44\x1e\x17\x77\x3f\x4b\x8b\x46\x5f\x71\x3a\xb8\x38\x75\x77\x44\x01\x12\x1c\x7d\x2d\x9b\xdc\x9e\x9f\xe6\xb3\x3a\x42\xc4\xda\x50\x5e\xc9\xc5\x71\x7d\xb1\xe3\xa4\xb3\x62\x1b\x21\xfc\xf2\x13\xf2\xed\x11\x2a\x82\x66\xf8\x5b\x25\x69\x8a\x6b\xd3\xfd\x24\xa1\x2f\x44\x62\x18\x82\x24\x76\xf2\x00\x04\x91\xf4\xe7\xa4\x2c\x33\xba\xb7\x56\x6b\x97\xe5\xef\xfc\x1d\x91\x46\x11\x26\x81\x6e\xcb\xa2\x97\xeb\x11\x22\x8d\x09\xd5\x42\x5a\xd2\x6b\xf9\x91\x17\x3b\x1f\x30\x1e\xdf\x3b\x4d\x62\x41\x3b\x4d\x51\x9f\xf6\x4d\xbb\xc3\xfc\x0e\xdd\x98\xce\xb2\x34\xa1\xd4\x3a\x5a\xa1\xc4\x1a\x80\x06\xc6\x64\x0c\x64\xd2\x22\xef\xf0\x5d\x05\xf5\xdb\xeb\xf3\xc3\xfc\xb6\x28\x24\xcf\x70\x5f\x43\x07\x66\xcb\xfd\x6d\x64\x92\x60\xe0\xe8\xde\x59\xdd\x9e\xaa\xc8\x1f\x57\x0c\x52\x17\x21\x1d\x26\xb1\x1e\x5b\x4f\xb0\x6b\x63\x28\xd3\xb0\x79\x83\xc3\xef\x6f\xa5\xfc\x52\xea\x29\xfa\x78\x96\xf0\x6c\x34\x71\x4c\x10\x1a\xc2\x70\x35\xa7\xaa\x18\x19\x50\xe3\x17\x31\x99\x44\xb4\xfc\x31\xf7\xd5\x30\xee\x00\xb0\x10\x69\x05\xbe\x3f\x6c\xbe\xdc\xbe\x2e\xbe\x6f\x17\xb7\xb7\xaf\xab\xf5\xba\x3b\x9e\x10\x5a\x66\x87\x74\x9f\x8f\x60\xbb\x99\x60\x21\x4e\xa3\x81\x36\xfb\xc8\xd2\x17\xd6\x26\x98\x1f\xc5\xe4\x78\x53\xa1\xa6\xd1\x2d\xfc\x68\xa0\xca\x9b\xf3\x1f\x28\x55\xda\xfc\x3c\xfe\x20\x02\x26\xb2\x80\xf8\xc0\x29\x67\xb1\xb0\x36\xdf\xe7\x5d\x7c\x47\x04\x9c\x67\xda\xf8\x8a\x9c\xee\xc7\x84\xf2\xfe\x0a\xad\xff\x91\x9d\x1e\xf0\x94\x49\xd1\x15\xf6\xa1\x15\xe2\xb6\xa7\x76\xfd\xfa\x0a\x9f\xbe\x61\x10\x28\xbc\x35\x16\x10\x5d\xc6\x1c\x82\x20\x4b\x91\x4b\xff\xaf\xf2\xad\x28\x86\x16\x7f\x10\xd8\x08\xb7\x88\xbe\xb6\x20\x8a\x9e\x26\x80\x4b\x11\x84\x42\x20\xdc\x95\x72\x0b\x7b\x80\x61\xb1\x9a\x08\x62\xc6\x23\x4e\x20\xcf\x97\xb2\x79\x44\xa1\x7f\x7f\x2c\x61\x02\xb7\xae\x23\x0e\xee\x71\xb7\x07\x49\xc0\x1d\xf1\x10\xfe\xec\x79\xf7\xaf\x78\x78\x41\xa2\x48\x04\x09\xb7\x87\xde\xb3\x0c\x52\x26\xd0\x3d\x41\x3e\x77\xa2\x9f\xa4\x6a\xc9\xee\x78\x82\x08\xe8\x83\xac\xde\x07\xc6\x1e\x21\xd7\x6c\x0e\x13\xb6\x4a\x11\xa4\x21\x47\x04\x4d\xbb\xd3\x82\xb9\xaf\xe0\x4a\xd5\xa7\x08\xd2\x38\x4c\x1c\x92\x6d\xf5\xe3\xf8\x6c\x6d\x0d\xcd\x98\xbb\x70\x4a\xb3\xed\x4e\xcc\x40\xa3\xca\x18\x16\x94\xfc\x1d\x09\x53\x77\x9e\x62\x31\xd2\x6f\xba\xb4\xad\x23\x74\x9b\x31\x61\x03\xc5\x0d\xd5\x37\x6a\x6f\xe7\x4e\xde\x52\x45\x90\x39\x8f\xa8\x63\x64\x5f\xe7\xbb\x29\x87\xc4\x05\xdb\xea\xf8\xef\xa4\x43\x94\x0c\xc8\x54\x21\x25\x8c\x2a\xff\x2f\xd1\x6e\xff\xbf\x29\xdc\x89\x40\x07\x12\xc3\xa5\x3e\x6a\x4c\xd6\xc0\xc3\xf2\x59\xfc\xd6\xb7\xf0\x8a\x03\x18\x8b\xc2\x40\xe9\xe4\x22\x9a\xa5\x2e\x50\xfa\x3f\x65\x5e\x80\xe9\x69\x37\x26\x7d\x61\xb2\x2c\x19\x94\x3a\xef\xf7\xe5\xe7\xb2\xa8\xa7\xfc\x0e\x17\xde\xe8\x28\x76\x17\x40\xc8\xb9\x4b\xaa\xc9\x33\x66\x45\x54\xfb\x61\x86\x12\x65\xdd\x77\xb4\x11\x0f\x3c\xcb\xe2\x2d\x48\xb3\x7c\x6b\xb7\xce\x62\xd9\xcd\xfe\x90\x25\x16\x3f\x4f\x53\xa2\xc5\x32\xc8\xba\x89\x90\x49\x83\x6e\x45\xbb\xe7\x1f\x2f\xcc\x77\xdf\x48\x05\x68\xa4\xbd\x40\x75\x90\x15\xbc\x8f\x26\x6d\xc8\x0c\x24\x3e\x1a\xfe\xad\x40\x67\x0e\xcc\xd8\xfa\x0d\x79\x40\xd9\x7f\xf8\x91\x3b\xba\x83\xf1\x37\xff\xc7\xd5\xdf\xfc\x05\x4c\xe2\xa9\xfc\x89\x4a\xc4\xc5\x27\x7b\x03\x24\xe4\x00\xb8\x09\xd2\x02\x31\x79\x05\xc1\x02\x44\x63\xfe\xfb\x4d\x96\xf7\xa7\x1e\x6a\x2f\x42\x11\x02\x86\x1a\x5d\x50\xa8\xfb\x39\xc9\xf0\x86\xc8\xe9\x48\xa3\xb9\x1a\x92\x21\x89\x50\x40\x36\x90\x18\x77\x30\x96\x81\x95\x13\x06\xc2\x62\xe5\x83\x96\xc5\x1a\x0a\xf3\x1d\xd4\x7d\x6e\x47\x0b\x73\x18\x86\x42\x41\x7f\xf3\x07\x57\xf2\x3d\xbf\x46\x84\x61\x1a\x73\x18\x94\x8d\x8c\x24\xeb\x66\xf6\xc9\x30\xd2\x31\x06\xa0\x3d\xb9\x7d\x47\x4b\x27\xc2\x08\x82\xd0\xe7\xa8\x67\xd4\xc2\x44\x18\xd9\xd0\xb3\xb0\xbc\x9e\x90\x6d\xa1\xab\x53\x73\x2d\x62\xe6\xa4\xa3\xc9\x73\x5e\x42\xbe\x6f\xdd\x74\x99\xd7\x93\x58\x74\x18\xa7\xda\xa7\x4e\xbf\xe7\x36\x7f\xf9\x1c\x07\x96\xc3\x24\x0c\xd1\x7b\x3b\x15\x8e\xdd\x00\xc5\x5b\xcd\x38\x7d\xea\xdb\x6a\x89\x3b\x33\x79\xa6\xae\x2e\xf1\xe9\xb4\x5f\xe7\xbb\x89\xcf\x33\xe9\xbd\x54\x71\xd6\xa5\xc6\x6f\xe5\x79\x32\x42\x32\x2e\xd1\xa6\x78\x85\x0f\xa8\x6a\xa0\x82\x56\x33\x47\xd8\x25\xc2\x4c\x90\x66\x13\xd9\x1f\xab\x1f\xfa\xc2\xd3\x0a\xb3\x90\x53\x42\xac\x76\x2c\x73\xfe\xf7\x48\xa2\xe6\xf4\x30\x34\x37\x2e\xaa\x9c\xcd\x7e\x89\x30\xd3\x51\xea\x4b\x42\xba\x8b\x99\x40\x51\x2a\x7f\xa5\xcb\x0e\xbc\xe0\x03\x2c\xa1\x54\x0a\x8b\x96\x48\xf8\xdb\x49\x99\xae\xa5\xbd\xaa\x74\x7d\xb1\x94\x0e\xa7\xa0\x62\x19\x8a\xb4\x49\x2c\xd7\x96\xfb\xfd\x8d\xf4\x74\x3a\x22\xd4\x22\x91\x0e\x11\x4d\xc8\x9e\x13\xd5\xcc\xfc\x9d\xb4\x7d\x7b\xb6\x41\xc3\x1f\x7e\x80\x3e\x35\x28\x70\xf6\x33\x8c\xbc\x08\x75\x20\x30\xf7\x01\x45\xd3\xeb\x46\xfd\x63\x20\xbb\x24\x42\x6d\xa9\x2e\x20\xaf\xbb\x9c\x06\xc9\x74\x4d\xb4\x87\xdb\x96\x6e\x07\xed\x89\xad\x26\x75\x69\x22\x34\x41\x80\x29\x3f\x17\xc8\xea\x90\xe6\x22\x04\x09\xa8\x62\xd0\xc1\xd7\xdd\xef\x96\xa9\x80\x77\x34\x2e\xb7\x24\x65\xed\xd2\xfc\x37\xe7\x0b\x0e\x6e\x11\x5a\x41\x98\x66\x72\xe1\x6e\xe8\x9d\x28\xec\x3c\x9e\x4d\x56\x27\x98\x12\xf0\x04\x11\xe3\xb2\xb1\xc9\xb0\xb1\x56\xf8\x48\xec\xe2\x2c\x71\x0d\xc8\x9b\x95\x2e\x8b\xf2\x90\xff\xe7\x04\xdb\x65\x79\x38\x36\xb0\x8d\xdc\x63\x47\x2c\xe4\x2c\xeb\x09\x57\x44\xf8\xb6\x26\xcb\x60\x54\x32\xe2\x1b\xa7\x20\x43\x57\x69\xd0\xc3\x0d\xba\x25\x39\x62\x5a\x06\xa6\xcf\x37\xbc\xc8\xb3\x92\xfa\xbd\x4f\x55\x8a\x88\x73\x8d\xc9\x50\x9f\xc4\xa0\xc5\xdd\x33\x4a\xfb\x46\xa1\x52\x43\x89\xf8\x71\xc7\x45\x22\x33\xc2\xa5\xaf\x5e\x65\xf1\xce\x99\xbf\xb8\x90\x92\xa8\xc0\xf3\xdd\x5b\x73\x93\x8f\xb6\xad\x48\x68\x8d\x3c\x16\x47\x2a\xe1\xdd\x8c\x1c\xce\x28\x48\x23\x4b\xc0\xec\xc7\xe7\xd7\xed\xfd\xeb\x6a\xf5\xb5\x3b\xa4\x52\xe1\xf2\x2e\x1f\xb0\x1f\xa6\x1f\xa2\x10\x62\xe4\xc7\xeb\xde\xa6\x79\x1b\x62\x39\xc7\x8f\x1d\x5a\x66\xc8\xdd\x96\x55\x33\xec\x93\x28\x32\x78\xef\xff\xca\xfa\x47\xfb\xbf\xff\xc8\xff\xfc\xc7\x1f\x8b\x53\xd2\x45\x55\x73\x09\x76\x11\x25\x3c\x36\x71\x2f\x77\xec\xe9\x3e\x26\x24\xe9\x6d\x3b\x19\x04\x7d\x11\xa8\x27\xa0\x9f\xb4\x4a\x85\xe6\x0e\xec\x89\x28\xfb\xa7\xd2\xc0\x60\xc7\x8d\x32\x41\x76\x41\x5e\xe8\xf2\x00\x53\xe6\x18\x11\x65\x19\x65\xf1\xee\x91\xbf\x61\x55\x40\xb5\x3b\x3b\x36\x70\x52\xe4\xf3\xed\x34\x43\xad\x29\xd4\xb9\x46\x44\x4e\x53\x9a\xbc\xc6\x18\x92\x99\x7c\x6c\x95\x5a\x46\x12\x9c\x0f\xc5\x57\xf8\xd1\x78\xcd\x84\xfe\xae\xca\x12\x4b\x39\xae\xf3\xbf\xd6\x93\x16\x91\x89\x0c\x99\xde\xc8\x9a\x70\x2c\xf5\x5b\x27\xba\xed\xaf\x09\x91\x40\x0c\xca\x00\xc4\x2c\x22\x1b\x27\x44\xc0\x72\x2a\xaa\xbc\x1e\xe8\xfb\x88\x98\xb1\x50\xf5\x73\xf9\xb5\xec\x7c\xe4\x98\x31\x89\x61\x78\x5d\x16\x5a\x36\x54\xf5\x3c\xa7\x5e\x24\x62\xa6\x39\x92\xe6\xd4\x6f\xe5\xe7\xc3\x88\x05\x4a\xc4\x9c\x29\x8c\xd0\xba\xd0\xb8\x93\xe2\x9c\xca\x38\x88\x98\x27\x59\x34\xcc\x87\xdd\x77\x31\xa6\x58\xc4\x02\x1f\x04\xb5\xbf\xae\xd4\x38\xfd\xff\xf5\xd7\x3f\x82\x89\xd1\xfa\xb1\x65\xd5\x14\xed\x1c\x45\x46\xa0\x76\xd9\xe9\x1e\x12\x14\x96\x7e\xfd\xe7\x04\xd5\xd9\x45\xb5\x86\x49\xaa\x38\x60\x0c\x2d\xe5\xc7\xd5\xf3\x70\x76\xc7\xa1\xc8\x88\x26\xab\x30\xae\x5c\x75\xe0\xfd\xc7\x51\x16\xe3\x97\x23\x64\x37\x34\x1e\x24\xda\x15\x83\x8e\x06\x48\x1c\xb3\x80\x75\x79\xcd\x5d\xd9\x75\x61\xdc\xc3\x27\x7a\xd3\xd9\x1f\x33\x91\xf5\xfc\xb4\x79\x53\x60\x21\xed\xd0\x7c\x8c\x13\x26\x10\xa9\x7c\xfb\xfc\x7d\xbb\xf9\xb6\xea\x7e\xe6\x16\x53\xda\x0e\xc1\xb6\x70\x15\xed\x73\xc3\xd8\x9f\x11\x25\x3c\xf0\x24\x9b\x75\xe3\x4a\x3e\x1f\xea\xfa\x84\x16\xf8\xec\x8e\x1b\x27\x59\x8c\x38\x60\xca\x45\xfd\x3f\xa6\xa1\xe2\x34\x26\xc6\x1b\xbf\xce\x3d\xa2\x68\xa8\x7f\x85\x54\x2b\x9c\x4f\x7f\xde\xbc\x8c\xbe\x49\x16\x44\xee\x9b\xb4\x6b\xfc\x0c\x93\x84\x88\x65\x42\x02\x9c\xa6\xa8\xab\xb1\x1e\xa4\x88\xa5\x25\x80\x3f\x41\x35\xfd\xf2\x36\x76\x34\x62\xc5\x85\x83\x52\xe7\x4d\xbf\x49\xc7\x2a\xa6\xaa\x07\x53\x7e\x16\x93\xa4\x48\xac\xd2\x08\x1c\x93\x26\x46\xaa\xfe\x39\x17\x0f\x77\x6d\x35\x0f\x34\xb9\x52\x7b\xf3\xaf\xf2\xb4\x2e\x27\xcf\xa8\x45\xe2\xd5\x67\x56\x9b\x2f\x08\x57\x9b\x2c\xbd\xb1\x11\xcc\xba\x38\xe9\x0d\xd4\x0d\x56\x40\x9d\x9a\x6e\x55\x89\x4d\x44\xb8\x3a\x4c\x9d\x96\x7b\xf2\x17\xba\x21\x67\xb2\x14\x1d\x51\x72\x3a\xda\xd1\x38\x28\x93\x77\x6d\x40\xea\x30\x18\x6c\x02\x57\x8a\x4a\x5d\x6b\x9b\x65\xa4\x3e\x5f\x56\xed\x86\xe2\x63\x9a\xb1\x55\x2a\xe8\x1d\x59\xd2\x2a\xf8\x5b\x1e\x77\xc2\xc2\x00\x85\xd2\x2c\x40\x3d\xd8\xd7\x12\x16\x13\x51\xcd\xd7\x87\xfb\x87\x7f\x77\x3f\x66\x44\xa3\xb7\x3e\x19\x03\xc5\x2d\x68\x79\xce\x8b\x1d\x31\x7d\x38\xb5\xbe\xae\xa9\x0c\x4d\x9f\xdf\x5e\x5f\xf8\xa9\x09\xe7\x12\xa9\x09\x3f\x1b\xd0\x6f\xde\xbd\x4f\x78\x94\x38\xdd\x36\x62\xe7\xbf\x85\x8f\x7c\xc2\x6a\x28\x12\xae\x88\x70\xfa\x44\xf5\xba\x13\x66\xfc\x7f\x4c\x1a\x5b\x46\xe2\xf3\x93\x7a\xce\x59\x0b\x2c\x69\xdd\x9f\xcc\x7b\x6d\x94\x95\x70\xd3\xe6\x36\xaf\x25\x91\xfc\x3e\x4e\xa5\xbf\x45\x12\x58\x5a\xa3\x6e\x1e\xee\xd7\xab\xc7\x47\xff\x36\x61\x0c\x59\x5f\xe6\xf2\x22\xab\x81\x56\xd6\xfc\xe7\x08\x75\x60\xf1\xfd\x8b\xa2\x3c\x15\x1a\x29\x5f\xbf\x74\xc4\x21\x22\x89\x79\x6c\xb3\xde\xb4\xc5\xa0\xee\xf7\xbc\x79\x23\xfc\x7b\x1f\x40\x1a\x3f\x5e\xc2\x43\x0f\x92\xbc\x39\x99\x5d\x17\x51\x48\x92\x14\x52\xe3\x54\xa6\x7d\x2c\x70\x58\xd6\x38\xb9\x8c\x62\x18\x18\xa0\xcc\xd2\x4d\x6e\xe6\x71\x3a\x49\xa2\x88\x3f\xcd\x8b\xe0\x16\xe6\x3c\x1b\xf1\x4d\x12\x10\x18\xee\x39\xca\xf3\x73\x81\x8b\x7e\x47\xeb\x2e\x92\x94\x13\xfb\x04\xce\x8c\xc3\x51\x16\xe7\xee\x48\x40\x6c\xd6\x7f\xac\xd6\x9b\x87\xaf\xf7\x28\xcc\xb5\xee\x0e\xa6\x16\xd5\xc6\x6e\xd8\x0f\xcf\x7d\xf0\xd3\x8d\x2d\x49\x35\x60\x38\x92\x80\x83\x2f\x32\x37\x63\xf2\xff\xe1\x3e\xdf\xee\xd0\x09\xe9\x18\x37\x6b\xf9\x01\xe8\xd4\x8f\x1a\x48\x46\xd5\xa6\x35\x34\xff\x73\x3e\xea\x4b\xfd\x47\x91\x48\x0b\xc8\x45\xf0\x24\xdf\xa1\x1a\xb0\x7b\x91\x92\xeb\xec\x5a\x96\x28\x96\xa1\x3f\x6c\x60\x2f\xcf\x8b\x53\x53\xba\x01\xe0\xdf\x5a\x85\x46\x3a\xa7\x9d\x16\xa1\xbb\xb2\x5a\xbe\xc9\x6a\x37\x35\xc0\x13\x1d\x18\x5f\xd8\xd0\x9a\xf9\x8f\xb9\xaa\x3a\x72\x60\x91\x68\x4d\xa9\xf3\xf9\x72\x05\x91\x68\xcb\x90\x7f\xef\xd0\x0e\xbc\x07\x2c\x81\x69\x87\x5f\xb0\xa8\xfa\xca\xb4\x7f\x8c\xe7\xe1\xbc\x42\xb4\xbb\x9e\x31\x09\x3a\x7e\xa6\x2c\x28\x99\xdf\x41\x1d\x12\x08\x33\x2c\xef\x41\x76\x84\x61\xda\x2e\x01\x2d\x03\xdb\x41\xd7\xbc\x08\x20\x09\xd2\x0c\x1a\x59\xe9\x6b\xa6\x73\x5f\x1a\x3b\xfa\x54\x60\x2d\x06\x88\x4b\xe7\x69\x8e\x63\x2a\x49\xeb\x13\x5a\xcf\xec\x34\xb4\x06\x12\xcb\x19\xc2\xc1\x8e\x39\x68\x18\xc0\x7c\x45\x62\x05\x55\x22\xd6\x6f\x58\xe5\x75\x2b\xf3\x49\xef\xdb\x20\x48\xc2\x61\x32\xbd\x86\xbd\x7d\x36\xa6\xbb\x40\xc6\x70\x68\xbb\x1e\x6b\x57\xf2\x57\x57\xdb\x4a\x2d\x52\xc6\x12\x0a\xbb\x43\x03\xd5\x21\x2f\x80\xc6\xed\xbc\xe9\x90\xb2\x98\x82\x4a\x84\x7f\x19\xee\x30\x18\xfd\x1a\xd7\x79\x8b\x94\x19\x32\xe1\xf0\x73\xc0\x3c\x82\xc4\x35\xe5\xcc\xa2\x96\xf8\x23\xd4\x75\x59\x6c\xe3\xf9\x81\x9b\xf2\x80\xa3\xe8\x87\x3a\x5d\xcd\xa4\x4c\xcf\x88\x39\x3a\xc1\x6b\x00\x47\xf1\x30\xc2\xa7\xcd\x4e\xe2\x94\xa7\x76\x84\x3b\xfa\x2a\xf5\xe4\xd5\x78\x96\xfa\xa4\xe8\x9f\xf2\x74\x57\x56\xf7\xb2\x5e\x9e\xaa\x99\x18\x43\xca\x0d\x8b\x7c\x90\x74\xdb\xbc\x55\x00\x08\xb8\x5d\xfd\xe7\xa6\x83\xb3\x8a\x54\x38\x3e\xcb\x1a\xf6\xfb\x0e\x3c\xec\x8f\x85\x31\xa5\xf8\xde\x40\xbf\x6f\xf2\xe3\x00\xeb\x2d\x52\x11\x5b\x17\xeb\x40\x07\x05\x4e\x87\x9b\xa1\xf6\xb6\x6f\xa5\xb5\x90\x9d\xd2\xe4\xf0\xc3\xd5\xb7\x0f\xb7\xf3\xe6\x41\x1a\xe8\x20\x49\x50\xa5\xeb\x07\x98\xa5\x3c\xae\xe5\xe1\xb8\x1f\xfa\x3a\x69\x00\xc4\x12\x86\x6c\x7e\x53\x0f\x24\x0d\x45\x48\x81\xdb\x01\x54\xc9\x4f\xd5\x34\xd4\x84\xb4\xf3\x76\xe4\x5a\x5a\xe8\x22\x28\x69\x6c\x32\xcf\x05\xf4\x5a\x7e\x2e\xcb\x7d\xe9\x50\xda\xdc\xab\xb7\xcd\x7f\xed\x18\x82\xac\x2f\x23\x7b\x91\x55\x33\x03\x15\x48\x93\x30\x4e\xd3\xce\x9a\x68\x77\x9e\xf1\x55\xd2\xc0\x60\x49\xee\x5e\xf7\x30\x73\x91\xa6\x59\x1c\x64\x5d\x3d\xe3\x1d\xc0\xcb\x49\x5d\x8d\xa2\xcd\x0f\xdf\x54\x87\xf8\x19\x5e\xaa\xbc\xf6\x2b\x53\x9a\x09\x95\xb8\x82\x58\xb5\x2f\x8e\x50\x41\x2f\xab\xec\x9b\x44\x02\x5c\x8e\x6b\x45\x1a\x54\x9d\xda\x4d\xd7\xa1\x92\x29\x5c\x2c\x9c\x65\x72\x37\xd0\x4f\x1b\xc6\xf2\x52\xc9\x75\xd2\x17\xe2\x10\x69\xe0\x6b\x5e\xbf\x5f\xd3\xfb\xf0\xa7\x05\x49\x1c\x0d\x40\x76\xf8\xd1\x1e\x8a\xfa\xb2\x98\x4b\xa4\x4a\x90\x20\xb7\x34\xe6\xa6\xca\xcd\x8e\xe6\x1d\xc9\x91\xa2\xe8\xfc\x64\x0f\x4b\x55\xa0\x90\x3b\xa0\xa3\xc7\x27\x9b\x73\xbe\x13\x95\x34\x68\x65\x3c\xdd\x79\xcb\x28\x55\x56\x4b\xf0\x6e\xfc\xba\x91\xef\x57\x7c\x9f\x54\x27\x29\x3e\xd9\xc3\x72\x81\x10\x0d\xff\xb3\x4d\x30\x48\xbd\x5e\x2d\xb7\x2f\xab\xd7\xed\x6a\xf3\xc5\x13\x5c\x8b\xd4\x24\x82\x47\x5e\x5b\xf1\x3f\x03\x5e\x6f\x7f\x3c\x13\x69\xa7\x03\xef\x7b\xa6\x33\x60\x7f\x1a\x7f\x48\x81\x85\x22\xf0\xf0\xeb\xa2\xaf\x07\x13\x29\xf0\x00\xb3\xfe\xa5\xb5\x50\x7d\x81\xfd\xf1\x5b\x9d\x17\xbb\x2b\x24\x97\xd3\xab\x72\x89\xe3\xb7\xeb\xcd\xaa\x3c\xbc\x94\x93\xbc\x48\x0a\x41\x82\x55\x48\xb8\x23\x6e\x40\xf6\xcb\x42\xd9\x15\x3c\x88\x14\x52\x8a\x38\xba\x2a\x39\x0c\x00\x4f\x1c\xde\x14\x54\xc8\x3a\x34\x1f\x18\x57\x72\x32\x1e\x13\x60\x39\xa1\x7d\x30\xd8\xf6\xe4\x45\xed\x45\x6a\x59\x48\x6e\x1b\x96\x8f\x38\x23\x6b\x5a\x49\x7a\xb9\xd7\xa7\x36\xf5\xe4\xc5\x87\xbc\xd8\x52\xae\x66\x7b\x94\x67\x0c\x22\x52\x9b\x8c\x71\x8b\xc8\x2c\x4f\x05\x32\xa8\x95\x99\x23\x86\xfd\xe9\xa6\x90\xb1\x04\x10\x99\xb3\x97\x35\x11\xb9\x6d\x6d\x8c\x42\x73\xee\x72\xdd\x4d\xa5\x40\x37\xbe\xca\x77\x6f\xa4\xdf\x80\xab\x79\xeb\x0e\x3d\xdb\x2e\xcd\xd3\x35\x06\x34\xf0\x16\xba\xac\x8a\x97\xb2\x19\xc9\x0b\xbb\x36\x3c\x33\x99\x67\xd6\x28\x0b\x38\xcf\x29\x6f\x89\x8c\x83\x32\x66\x50\x20\xeb\x72\x28\x8b\xe9\xd5\x84\x01\xa6\x3a\x45\x4e\xa7\x42\x31\xeb\xbe\x64\xa1\x4b\x61\x6f\x35\xde\xf7\xef\xed\xb8\x59\x98\x86\x58\x48\xe8\x08\xb2\x87\x22\xc4\xa3\xa4\xf6\xcf\xfe\xf8\x4b\x99\xd0\x38\xd5\x8a\x7c\x57\x20\x0a\xb4\x92\x17\xc2\xaa\xae\x71\xc4\xd2\xc4\x6d\xc9\xcf\xd5\x52\xea\x37\xda\x67\xf3\xe6\x7c\x53\x16\x93\x25\x3e\x8b\x52\x92\x21\x73\x76\x2b\x12\x19\xb8\x43\x71\x1a\xb0\x61\x24\xf7\xa5\xf2\x19\xed\x31\xaa\xf8\xe7\xbd\x10\x4b\x40\xd7\xab\xc9\x0f\x40\x95\x38\x0f\xc5\x53\x5e\x9c\x9a\xfe\x3e\x26\xc4\x6d\xbd\xc6\x8b\xbb\xba\x62\xf4\xce\x7e\x95\x9a\x99\xdc\x09\x20\x16\x83\xe7\x75\xc9\x9e\xf9\xd5\x33\x4b\x02\x69\x89\x1f\xe5\x6b\xd9\xdc\x9e\x8e\xfb\x5c\xcb\x06\x5c\x39\xdc\x24\xdd\x90\x25\xa1\xe0\x69\x37\xf9\x3b\x6c\x97\x13\xb1\xf4\x2f\x92\x44\x31\x16\x10\x1e\xc0\x38\x95\xf5\xda\xe5\x3c\xbe\x15\xf9\x34\x08\x92\xa5\x89\xce\x68\x1a\x55\x1d\x3c\x3f\x4b\xb3\x00\x03\xe2\xe8\xd4\xb6\xa6\x68\xee\x49\x2e\xae\x84\xa5\xc6\x2f\x95\x05\xc2\x10\xed\xd6\xb1\x29\x7f\x09\x12\x18\x3f\x4f\xa6\x53\xe4\x66\xb8\x07\x5f\xe8\xff\x50\x93\x06\xea\xcd\xf9\x16\xf1\xa9\xbd\xad\x9e\x65\x96\xd4\x72\x28\x06\xf3\x15\x7e\x34\xdf\xf3\xc2\x94\x9f\xc4\x85\xdc\x6e\xcc\xaf\xad\xe3\xf1\xdb\x45\x3e\x24\x93\x5c\x62\xa1\xf9\x6d\x17\xdc\x9e\xff\x3e\x32\x52\x59\xd6\xab\x4e\x43\xd5\x9c\x5d\x18\x7f\x8e\x59\x55\x64\x32\x35\x88\x59\x7b\x2c\x77\xbf\xff\x6b\x39\x44\x32\x4f\xfa\x5d\x66\x54\x42\x87\x79\x33\xf2\x49\xfd\x92\xca\x1d\x87\x80\xc8\x54\x9a\x20\xa7\x8c\x34\xe6\x8f\x72\x40\x93\x3c\xbe\x94\xd2\x44\x3e\x36\xa6\xb3\x18\x0f\x1d\x2d\x25\x0e\x9d\x37\xb9\x1f\x44\xe3\xb2\x76\xa7\x55\x44\xa5\x06\xf9\xae\x20\xf3\x60\x7a\x9b\x49\x5d\x99\xc8\xc0\x50\x49\xa5\x83\xa1\x0c\x2d\x78\xd7\xc2\xa6\xcc\xf6\xca\x09\x4e\x87\xed\xa9\xf5\xf2\xaf\xee\x20\x92\x31\x85\xba\x3f\x9d\xf7\xb4\x55\xb2\x86\xed\x01\xc7\xf8\xb6\x1a\x49\x71\xfa\x53\x42\x22\x72\xa9\xa5\x85\x5e\x10\x4c\x8c\x1f\x46\xb2\x58\x63\x4e\xfb\xeb\x9d\x2f\xbf\x92\x4c\x05\x68\x9d\xf9\x49\xfa\x0a\xed\x80\xd6\x0d\x98\x75\x33\x53\x2f\xf3\x8f\xc9\x6d\x55\x80\x59\xb0\x3f\x9e\x1f\x9f\x5f\x7e\x96\xf6\x97\x5c\x70\xe6\xea\xb4\x88\x1d\x64\x04\x3a\x90\x3c\x52\x08\x6d\xc6\xfd\x0b\xf5\x2d\xf7\x1b\xa8\x47\xd9\x31\xc9\xd3\x84\x56\xae\x72\xb7\xdb\xf7\xf9\xe2\x7e\x2c\x4b\xae\x85\x25\x41\xca\x41\x4e\x44\x0a\x46\xb1\xbf\x1d\x34\x77\x79\x21\xf7\x8b\xa2\xfe\x84\xea\xc1\x3e\xc9\x46\xbf\xc1\xa5\x3c\xe3\xf0\x95\xa7\xe6\xa6\x14\x09\xf1\x75\x4b\xdb\x8d\x67\x6f\x1a\xc9\x40\x04\x28\x69\xe6\x86\x9f\x63\xf9\x27\x3d\xa3\xf1\x55\x02\xf5\xff\x71\xf6\x26\xdb\x6d\x23\x59\xd7\xe8\xbb\xfc\xa3\x1c\x7c\x03\x44\x87\xe6\xce\x28\x89\x92\x59\xa9\x86\x25\xd2\x76\x56\xd5\xfa\x17\x57\x34\x27\x28\x94\x41\x80\x09\x80\xb6\xf5\x3d\xfd\x5d\x38\x11\x81\x8e\x90\x33\xef\x9d\xa4\x9c\x44\xa0\x0b\x44\x73\x9a\x7d\xf6\x56\x18\x37\x3e\x48\x63\x3e\x55\xf5\x1c\x9c\x20\x99\x76\xd5\x92\x8e\x4e\xe7\xe9\x61\x7e\xba\x75\x2a\x7d\x98\x49\xe8\xd9\x9e\xc3\x63\xf0\x2c\x42\x49\xb2\xf3\xa1\x09\xc5\x96\x55\x67\xf7\x19\x9f\xe9\x5d\x36\x41\x25\x57\x29\xce\x43\x47\xd6\xeb\x13\x14\x23\x82\x30\x2a\x63\x96\x61\x39\xd9\xab\x0b\xca\xa0\x41\xb3\xb8\x58\xc8\x84\x00\x78\xcb\xe0\x26\x37\x66\x00\x6a\xcc\xe1\x10\xd3\xf1\x99\x24\x46\x99\xa1\x58\x2b\xac\xb4\x1f\xdc\x43\x39\xba\xab\xa3\x83\xff\x86\x87\x4c\x59\xa2\xf8\xaf\xb8\xf2\x16\x70\x04\x32\xd5\x8e\xb0\xb4\x73\x85\x03\x66\xc1\x57\xca\x6f\xca\xd1\x96\x22\x33\x1f\x98\x3c\x22\x3d\xcc\x3b\xd4\x13\xe8\x92\x94\x54\x47\xa6\x8f\xc6\xdc\xf4\xc9\x31\x29\x05\x43\xe8\x85\x34\x66\x55\x9c\xdf\xe4\x6c\xf7\x98\x7e\x7d\x29\x75\xe2\xeb\x33\x7e\x87\xf7\xdf\xe6\x07\xad\x03\x01\xe1\xfc\x39\x9c\xf2\xa2\xfb\xbe\x65\xff\x84\x2a\xa1\xdc\x27\x80\x2e\xe7\x5d\x2b\xf5\xb7\x3b\x38\xb7\x6f\x8f\xb9\x9a\x2d\x06\x4a\x49\x1c\x83\x5f\xdf\xaa\x66\xd3\x3e\x54\x65\x29\x6f\xfa\xab\x68\x92\x62\x05\xcb\x4a\x55\x97\xfe\xed\x34\x97\xc8\xb3\x81\x5e\xb5\x1e\x5e\x4e\x0b\x25\x3d\x87\xfd\x44\xd0\xc1\x51\x49\x17\x60\x6e\xde\xf7\x50\xca\x61\xb6\xeb\x4c\x61\xcd\xdf\x01\x1a\x5d\x57\x3f\x3e\xf8\xc0\xa6\x73\x9f\x46\xe0\xfa\x1d\xe8\x1a\x66\xcb\x79\xe7\x72\xd1\x08\xd1\x9b\xef\xe7\xb6\x5a\xa3\xba\xd7\x68\x4a\x1a\xa3\x32\xa7\x41\x80\x6c\xe8\xbc\xff\x1d\x22\xf4\x9d\xaa\xd2\x8d\xf1\x4d\x79\x9f\xcb\xf6\x2b\xe4\xa1\x01\xd8\x54\xf7\xc4\xe6\xcd\xd4\xb0\x90\x56\xe9\x24\x08\xd8\xfc\x28\xc1\x6c\xab\xbc\x6c\x17\xaa\x6d\xa5\x05\xa7\x16\xe0\x82\x5b\x72\xd1\xf1\xfa\x0b\x63\x6a\xda\x29\x2a\x52\x4c\xcb\x19\xd1\xf1\xbe\xda\xdc\xae\xb6\x9d\x6d\x35\xe4\x52\x55\xa4\x62\xea\x14\x47\x8a\xbc\xdd\xb5\xf5\x52\x3e\x57\x45\x86\x45\x2e\xce\xee\x56\xfd\x49\x2a\x60\xfa\x2e\x8a\x68\xed\x05\x14\x91\x8e\x61\x24\x68\x11\x1a\xd8\x54\x66\x7d\x8c\x03\x69\xff\x16\x3f\xac\xa2\x89\x43\xce\xbb\x0d\x6d\x2c\x0f\x4a\x15\x05\x8d\x51\xe3\xbc\xcc\xdb\x83\xea\xba\xf4\xfd\x70\xae\xab\x63\x2d\x4f\xb3\xe7\x61\x19\x05\xe8\xfd\x2c\x8f\xb0\x0b\xc7\x24\x0f\xd1\xdf\xf5\xeb\x6d\x42\xc9\xb3\x6d\xaf\xdc\x2b\xdf\x96\xa7\x8e\x6f\x11\xbf\x5f\x3d\x12\x04\xa7\x8a\x67\x42\xfa\x94\x79\x90\x22\xa7\x8a\x2b\xe9\x4a\xc4\x4e\x1e\xbd\x81\x63\xdd\xc5\x2b\x66\xe1\x2d\x25\x52\x16\x18\x2d\x31\xca\x3c\xcd\x0c\xaa\x98\xca\x68\xc2\x8a\xf9\x09\xea\x6a\xee\xa1\xaa\x38\xa5\xb1\xaf\x74\x31\x79\x7b\x57\xcb\x63\xf5\xc1\x9a\xd8\x35\x4d\xbb\xde\xfb\x11\x14\x6c\x9e\xf2\x72\x5f\x7d\xfb\xe0\xcd\x63\xb0\xc8\x2b\xdc\x19\xc5\xcd\x98\x55\x63\x36\x34\xaf\x4d\x14\x95\x44\x31\xae\x42\xea\xf2\xbe\x75\x54\xd7\xb3\xc1\x90\x6a\x89\x71\xc3\x43\xde\xdc\xe5\xf2\x54\x95\xe6\xe5\xd2\x36\xf9\xac\x86\x4d\x65\xcc\x25\x09\x6e\xdf\xba\x75\xb4\x1c\xd1\xe3\xcd\x8c\x89\x0f\x1e\x2d\x5c\x26\x49\x1d\x38\xd5\x98\x17\x6b\x01\x69\xdb\x27\x31\xa6\xeb\x22\x4b\x7f\xa6\x04\x8e\x41\x1b\x44\x97\x0f\xc2\xf2\x54\xa9\x48\x58\x1b\xb6\x43\xb2\xf5\x60\xa6\x79\x85\xdc\x52\xbd\x9c\x52\xb1\xc0\x39\xfa\xb4\x7a\xfe\xb4\xda\xef\x57\xcf\xdb\xd7\x97\x3f\xfe\x95\xec\x3f\xad\x02\x89\x62\xd7\xc6\x20\x63\xd2\x63\x75\xf4\x85\x61\x39\xe6\xab\x3f\x88\xd3\xcd\x9e\x5a\x65\x86\xb9\x75\xc5\x5e\x4a\xd3\x6d\xc4\x7d\xec\xa3\xb3\xfe\x46\x7a\x30\xcb\x5f\x5e\x27\x1c\x51\x02\x3d\x03\x6f\x55\x06\x89\xf7\x59\x43\x9d\xba\x6a\xf3\x1e\xb8\xd2\x6c\xca\x9b\x4b\xf1\xed\x63\xf3\x55\x19\xaa\xc1\x43\x74\x36\x27\x79\xc4\xec\xd1\x6d\x51\x5d\xae\xa4\x8a\xa7\x6b\x91\xd1\x29\xa6\xff\x6d\x0d\x60\xbe\xe6\xe5\xb6\xaa\x8a\xfb\xaa\xc6\x4a\x9d\x11\xef\x15\x55\xc6\xe8\x6c\x90\xd7\x7c\xbd\x14\x9d\x0d\x37\xa1\xe9\x9b\x11\xf6\x51\x05\x49\x8a\xec\x26\x0e\xca\x79\x38\x77\xf6\xc2\xf8\xb0\x8c\x91\xcf\xe4\x5b\xae\xbf\xe1\x40\xe8\x1c\x83\xf9\x17\x98\x7c\x00\x6b\x13\x4c\x60\x98\x2a\xac\x96\x1f\xd4\xb7\xeb\x48\xda\xcc\x03\x35\x3a\xcf\xa5\x7e\x29\xc3\x26\xf5\x97\x31\xda\xd9\x85\x0c\xc1\x6e\x75\xaf\xfd\x78\xd1\xdf\x26\xb0\x13\x4d\xa2\x14\x81\x6d\x7d\xb5\xc3\x50\x68\xab\x29\x8b\x70\x1f\xba\xab\xf4\x05\x9d\x41\xbf\xa5\xc2\x5c\xd2\x3f\xb4\xf7\x0a\x6d\xf7\x55\x85\x8a\x6e\xf3\xc8\x9a\xa6\x89\x8e\x79\x50\x29\x39\xb3\x10\x95\xd3\x0c\x20\xc8\x7c\xef\x46\x7c\x97\x55\x51\x40\x7d\xbb\xac\x47\x36\x7b\x4d\x66\x13\xc1\x91\xe4\xd6\xf4\xd5\x3a\x43\xba\x14\x0f\x27\x5e\x83\x29\x87\xba\xc9\xe7\x0c\x22\x54\x73\x61\xf1\xd9\x4e\xf2\x67\x7e\xba\x9c\x46\x08\xfb\x70\x11\x21\x24\xe6\x5e\xaa\x33\x4c\x09\x9a\xa9\x16\x19\x0f\x21\xf8\x0f\x9e\xf3\xd7\xd1\x38\x1d\x13\x49\x23\xbf\x81\xc9\x41\x09\x57\xc9\x63\xd8\x9a\x75\x1c\x0b\xe2\xea\x69\x6b\xac\xbd\x59\x6d\xfa\x23\xd2\x55\xc0\xbf\x82\xae\x4a\x9d\x5f\xdb\xd7\xd3\x75\x40\x27\x94\xc1\x90\x82\x0e\xaf\x32\x9f\x66\x23\x4b\x57\x27\x09\x8d\x7c\x8e\xfc\xf1\xf1\xcb\xa1\xdb\x51\xfa\x62\x2a\x9d\x18\x9b\xb0\xde\x59\x1d\x11\xd8\x51\x9d\x46\x02\x07\xfc\x8f\x1e\xfb\xa0\x53\x9a\x66\x9e\xbd\xf7\x7c\x19\x58\x6d\x7e\x15\x10\xd1\x69\xb7\xa4\xf8\x20\xdf\x6b\xa5\x2e\x1f\xa1\x5a\x74\x2a\xa2\xac\x27\xa6\x0b\x2e\xe9\x15\xa5\x10\xd5\x69\x96\xc6\x7e\x87\xed\x36\x4f\xcf\x93\xb7\x80\x98\xd2\x59\x6c\x31\xc4\xfe\xef\xd5\xbf\x56\x63\xbf\x52\x67\x59\x84\xa4\x02\x18\xa4\xdf\xbe\xae\x87\xa8\x80\x96\x5a\x21\x76\xa6\x57\x38\x78\xea\x89\xc9\xa8\xd6\x51\x1a\xf8\x31\xb7\x52\x7f\x93\x47\xf0\x8e\x51\x67\x1b\x41\xf3\x81\x80\x45\x38\x99\xb8\x72\xc3\x06\xda\x03\x78\xbe\x9c\x43\xdd\xf9\xfa\x79\x79\xb8\x4a\xb4\x68\x9d\x19\xc4\x99\x5c\x9a\x5e\x37\x82\x6a\xad\x38\xf5\x72\xf7\xdb\x42\xb6\xb6\xaa\x4f\x9b\x52\x57\xa7\xbc\x3c\x4e\x2a\xcf\xfb\xcd\x60\x3a\x52\x0d\x75\xe0\xf3\x60\x4a\x2e\xc8\xab\xce\x72\x39\xda\x50\xee\xd0\x71\x88\x70\x9f\x5f\x4f\x38\x02\x9a\xbc\x3c\x5f\xda\x19\x8d\xcc\xd5\x1a\x37\x59\x6e\x8c\x66\x58\xa0\x82\xcc\x73\xfb\x51\x96\xc4\x1f\x87\xc4\x45\xe1\xb4\x2c\xba\x2d\x61\xf9\x31\x43\x5b\xcf\xc7\xdb\x20\xc2\x7a\xe2\x9e\x69\x1b\x01\x42\xa5\x54\xe0\x82\x5a\x5d\x23\xdc\x27\x37\xb6\xa9\xab\x70\x6f\x68\xec\xfc\x0e\xd2\x1f\x70\x55\xc5\x9d\x61\xf7\x7e\x86\xc9\x4a\x6c\xa2\x48\x53\x2f\xb5\x59\xf5\x3c\x5b\x93\x37\x32\x11\xc4\x62\x58\xcc\x47\xf2\xc5\x8b\x35\xd2\x86\x70\x11\x3b\xce\x82\x3f\x2f\x79\x0d\x66\xfd\xf3\x1c\x02\xf6\x4e\x7b\xe8\xb7\xd0\x30\x26\x98\xc8\xd3\x45\xd5\xe0\xd2\x3b\xcf\x0a\x19\xa2\x1c\x84\xf3\x5c\xe5\x4d\x53\xb9\x7a\x0d\x7f\x88\xea\x0c\xd1\x15\x79\xd3\x2b\x20\x82\x09\x01\x84\xd9\x13\x71\x26\x31\x3f\x7f\xac\xbe\x87\xd3\xe3\xc8\xa6\x4e\xe7\xa1\x28\x3e\x9f\x07\x31\xa8\x70\x98\xc7\xa9\xd3\xc3\x6b\xaf\x6a\xc2\xae\xad\x08\x13\x27\x8e\x4a\xc6\x83\xbe\xbb\xe7\x7c\xc4\xd2\xc5\xfe\x7a\x19\x4b\x3d\xf5\xd6\x67\xec\xfd\xfe\x80\x4e\x22\x1f\x18\xd8\x3f\x5d\x66\xa4\x1c\x26\xa1\x2e\xdc\x68\x20\xf8\x95\x5e\xc7\x77\xd6\x2e\x8b\xd3\xd4\x2f\x94\xaf\x55\x51\x20\xa5\x76\xb8\x83\x8c\x81\x7a\xe5\xed\xba\x7d\x1b\xa1\x38\x8d\x8e\x22\x2c\x9f\xae\xa5\x86\xfa\x90\x0f\x4c\x7e\xd4\x68\xc6\x11\x5c\x69\xf2\xa6\x33\xd8\x76\xd0\x93\x4c\x8d\x32\x43\x46\x0b\x2d\xa3\x20\xaf\xdb\x87\x60\x7e\x41\x72\x31\x64\x9c\x07\x83\xc6\xe8\x98\xa3\xdf\x81\xa9\x7d\xe7\x8f\x1d\xde\x7a\x01\x24\x6a\x74\xaa\x91\x19\x70\x2c\x98\x38\x30\x4d\xce\x7a\xa2\x1b\x15\x41\xa2\xbb\x6e\xbd\xa9\x35\xcc\x38\xa3\x55\x9c\xb8\x3a\x84\x93\xcc\x4b\xbf\x14\x86\x3b\x19\x9e\xa0\xf3\x72\xc0\x55\x66\xd3\xc2\xe9\xd7\x39\x42\x63\xd2\x04\xc9\x29\x6e\xe1\xbb\xd4\xf7\x3d\x2f\x39\x35\x26\x73\xae\xbc\x34\x66\xa1\x18\xc3\x37\x02\xe2\xd8\x2a\x07\x9e\x9c\xee\x12\x28\x06\x32\x67\x43\xa7\x06\x52\x19\xbc\x06\x4c\xe1\x40\xa9\xc1\xd5\xf7\x7f\xcd\x4b\x08\xb5\x19\x79\x55\xde\xbc\xbf\xc2\xf1\x52\x20\x86\x62\x79\x97\x9b\xfe\x3a\xb9\x8b\x25\x09\xf5\x8f\xb4\xd3\x0b\xa4\x0d\xa1\x19\xb5\xdc\x65\xf1\xeb\xef\xb9\x86\x5d\x3b\x06\x90\x1b\x9b\x29\xec\xc6\x15\x92\x82\xb4\x23\x85\xde\x69\x07\x00\x61\x42\x86\xc8\xdb\xe5\xfd\xda\x11\xf0\xcd\x28\x4d\x5d\xb6\xc5\xcf\xee\x29\x28\x08\x68\x1c\x27\x5e\x59\xe3\x69\x77\x1b\x7e\x65\xb1\x60\x51\x90\x18\xa8\xbf\x15\xb0\xaf\x01\x5e\xab\xaa\x9d\x86\x50\x7d\x6b\xce\x4c\xd6\xf5\xee\xea\xcb\x6a\xf3\xb8\xba\x79\x5c\x1f\xb6\xaf\x6b\x94\x6e\xd9\x7d\xde\x6e\x1f\xff\xf5\xdb\xd0\x0e\x57\x9d\x6f\xef\x3a\x90\xa4\x84\x89\x06\x82\x45\x58\xdb\xfb\x49\xea\x6f\x4d\x7e\x9c\xbd\x84\x88\x2d\x46\xb0\x5c\x8e\xb5\x5f\x53\xc2\xd1\xc4\xe2\xa6\xf1\xf4\xf2\xbc\xfe\xd7\xfe\x75\xbd\x46\x12\xf4\xfe\xa8\x4a\x90\x8a\xec\xc1\x85\x70\xea\x76\x94\x69\x83\x98\x13\x1e\xb4\xcc\xe5\xe9\x2c\xf3\x63\xd9\xfb\x87\x37\xef\x1b\x33\x8d\x41\x41\x22\x9c\x15\x86\x26\xeb\x7b\xf8\x3e\x4b\xc0\x3a\x48\x14\xc5\x80\xf9\x77\x59\xe6\xc5\xac\xd3\x53\xa0\xda\x83\x98\xc2\x76\x7e\x05\xa4\x85\x14\x94\x71\xc4\x9a\x67\x79\x69\x46\xb1\xfe\xe5\x09\x01\x59\x24\x94\x1b\x0f\x85\x9d\xdd\x2f\x33\x8a\xfa\x60\xe5\xc1\xb3\x04\x1c\xd4\x2c\x8f\x3f\xbd\xb9\x8c\x14\x42\xa1\x37\xcf\x5f\xc2\x45\x64\xe2\xe2\x6f\x37\xd5\x6e\x6c\x54\x81\xcc\x62\x44\xf9\xe7\x48\x7a\x5e\x8f\x85\xce\x29\x48\x05\x49\x5f\x62\x78\xf9\x0e\x57\x3b\x7a\x68\xa7\x2d\x2e\x53\x9d\xb9\xb1\x29\x9b\x4b\x3d\xda\x4f\x40\xc9\x24\x71\xb4\x53\x5e\x9b\xd8\x07\x6c\xef\xf3\xba\x69\xbd\x25\x66\xfa\xc6\xda\x91\x68\x77\xef\xea\x02\x46\xa8\xef\xeb\x8f\x6a\x29\x63\x3a\xe8\x18\x87\x9a\xe2\xe9\x96\x07\x36\x8b\x22\x15\xe4\x49\x7e\x3e\x56\xd2\x57\xb4\xfb\xac\xf6\xcd\xfb\x63\xdb\xdf\xcf\x66\x0c\x9f\xbc\xc4\xb8\xe4\x6d\x71\x51\x4e\x45\xf5\x6f\xf9\x10\x60\xc1\xa9\xc4\x9c\xf2\xf2\xce\x23\x06\x37\xe5\x10\x9c\x04\x6b\xb5\xaf\xc6\x5f\xe2\x2a\x74\x8d\x6c\x24\x5c\xed\x96\xf6\x23\xd8\x45\x63\xfb\x2e\xb1\x91\xcd\x06\x79\x41\x40\xee\xf9\xf7\x65\x44\xac\x25\x04\x8c\xcf\xa0\xdc\x41\xf9\x1e\x64\xcd\x27\xb3\xc0\xd2\x08\xe8\x58\xd5\xc7\x0b\x74\x3b\x9c\xd3\xf4\xd1\x68\x4c\xb8\x5f\xa4\x7a\x4b\xe3\x83\x5b\x53\x95\xb2\xb4\x4f\x6c\x7a\x90\xa0\x19\xfa\xc2\x32\xa2\xd0\x4e\xe8\xd1\x22\xa3\x29\x11\x9a\x18\x02\x7e\xe7\x45\x46\xc6\x57\x68\xaa\x4b\x7d\x45\xf0\x66\xb9\x56\x88\x79\xe8\x33\x8c\xde\xc9\xb0\x82\x65\x22\xea\x25\xec\x87\x2e\x14\xa9\x42\x54\xfb\xeb\x6a\xbf\x3e\xdc\x7e\x5a\x3d\x3f\xac\x0f\xfb\x4f\xaf\xeb\xdd\xa7\x97\xc7\xbb\xd0\x28\xa6\x0a\xeb\x9f\xdc\x1b\x7c\xa4\xc8\x15\x1a\x33\x83\xd1\x02\x94\x39\x30\x37\xef\xc8\x6b\xb3\x38\x48\x6c\xdc\x2d\x53\x9d\x13\xfb\x4d\x9e\xf2\x27\xf9\x73\xeb\xb1\x24\x87\x70\xe3\x44\x5b\x04\x54\x2d\x41\xc2\xd3\x71\xbd\xbe\x4d\xac\x42\xf3\xf2\xb5\x0a\xec\x67\x61\x91\xb0\xa9\x04\xd6\x53\xa8\x18\x80\xd3\xfa\x23\x97\xcd\xa6\x8a\x39\xb5\x47\x87\x87\xfe\xbb\xfc\xbb\x7f\xcf\xaf\xb6\x99\x50\xe8\x1a\x3f\x6c\xc2\x7e\x64\x65\x6c\x31\x6c\x03\xe3\x6f\x22\x93\x38\x73\x60\xeb\xdc\x4c\x72\x8c\x56\x09\xc7\x47\x33\x05\xdd\x6c\xca\xce\xdf\x5b\x0c\x93\x59\xcd\x09\x96\x74\x3e\xbd\xef\xf4\x1b\xf4\xfb\x83\xd5\x29\x47\x62\xc2\x43\x2d\x4b\x53\x9d\x1e\x2f\x7a\xa4\x5c\x43\xad\x96\x19\xde\x28\x68\x97\xc6\xd6\x83\xae\x82\x89\x6a\x4d\x9c\x28\x0f\x7b\xf4\x24\xa7\xa3\xa4\x85\x35\x36\xc1\xf3\xef\x2f\x0d\xc8\x67\x40\x52\xe8\x70\xcc\x52\x57\x12\x7c\x5b\x95\xcd\x18\xbe\x3d\x7d\x70\x1b\x8b\xb4\xeb\x84\xbb\x53\x3e\x0d\x69\x5b\xab\x44\xd6\x0b\x8f\x0e\x8a\x14\xe1\x28\x70\x5c\x13\x0e\xc8\x29\x26\x1b\x70\xe8\x0f\x59\xac\x8a\x62\x82\x7d\x5e\xea\x2f\x16\x45\x71\x82\x81\xcf\x20\xee\xfd\xc1\xac\x66\x51\x24\x63\x43\x3c\x08\x65\x20\x32\x61\x51\xa4\x35\x1f\xe2\x74\x61\x61\x1b\x6d\x2c\x2c\xc2\xec\x29\x46\xde\x9e\xe4\x79\x69\x93\x65\x11\xc9\x5c\xec\x19\x81\xa7\xfb\x3e\x37\xc8\x22\xa2\x52\xb4\x54\xd7\x27\x95\x1f\x8f\x50\x4e\x79\x3c\x97\x6d\xb9\x61\x9e\xb0\x88\x68\x8e\xe6\x88\x4b\x36\x95\xf9\xe5\x34\x74\x2d\x8b\x08\x40\x34\xc6\xbb\x74\xa7\xaf\x07\x2d\x53\xdf\x8a\x92\x34\xd5\x53\xbf\x66\xa8\x7c\x60\x11\x4d\x2d\xf7\x56\x6e\x37\xf7\x7d\x6c\x18\x33\xe6\xbf\x56\x6d\x66\x11\x35\x51\xd0\xc1\x18\x14\xec\x97\x9b\x32\x1e\xa3\x80\x63\xae\x2b\x8c\x7a\x84\xbb\xb3\xc4\x95\xad\xfe\xcc\xab\x32\x1f\xbf\x1b\x93\x3c\x0d\x4a\x4d\x39\xe2\x49\xc2\x11\x1e\x29\x4d\x86\x44\x99\x17\x01\x31\xfd\x61\xe1\x94\xdb\x9e\x5e\x9e\xf7\x9f\x1e\xff\x75\xd8\x3c\xef\xd7\xaf\xcf\xab\xc7\xc3\x97\xd5\xe7\xc7\xfd\xe1\x76\xb5\xed\x5b\x66\x8e\x31\x0e\x0b\x21\x30\x15\xf3\xd8\x6f\xd1\xac\xdb\xcc\x30\xe2\x7d\xd3\x6d\xbe\x21\x06\xc3\x22\x61\x28\x56\x69\x3b\x3f\x7a\x55\x14\xb7\x55\xe3\x78\x11\xe8\x02\x78\x63\xcc\xe8\x30\x27\x06\x64\x51\xcc\x48\xea\x40\xfa\xeb\x46\xcb\xa9\x53\xcf\x90\xf4\x14\xd1\x9d\x55\x09\x75\x75\x5b\xc8\xa6\x09\x82\x1a\x2c\x4a\xe2\x58\x8b\x80\x61\x79\x1c\x00\x44\x2c\x4a\x0c\x45\xe1\xff\xf5\xea\xf5\xf1\x5f\x87\xdb\x97\xe7\xfd\xeb\xe6\xe6\xf3\xfe\xe5\xf5\xb0\xdb\xaf\x7e\x5f\x87\x66\xa9\x76\x52\x81\x3e\xec\x78\x5f\xd5\xdb\x3a\xff\x9e\x17\x70\x84\xd9\xf8\x49\x21\x45\xab\xed\x91\x64\x87\xed\xea\x71\x32\x37\x52\xc8\x5c\xda\x1d\xe1\xa6\x3f\x00\xce\x0e\x73\xea\x0f\x67\xa9\x40\x9a\x82\x07\x68\x7b\x4a\xd5\x29\xa9\x16\x8b\x32\x29\xd0\xd1\xd8\x34\x48\xf9\xd6\x7f\xc7\xcc\x30\x4c\xcd\xbf\xae\xbe\x6c\x0e\xab\xc7\xc7\x97\xdb\x91\x80\x34\x8b\x24\xcb\x14\x19\xf0\xcd\x9e\xec\xfa\x0a\xd6\xee\x5b\x2b\x2d\x25\xbd\x6a\xdd\x35\xec\xe9\x9b\xfa\x8f\xe6\x4f\xd1\x11\xa4\xe9\xc0\xb8\xfc\xfe\xe5\xf3\xf6\x0e\x9a\x36\x2f\x47\x6e\x12\x8b\x4c\xc4\x4d\xe4\x43\x92\xb2\x7c\xff\x54\x15\x9d\xef\x47\xdf\xfb\xe3\x49\x16\xc5\xa3\x94\xf2\xf4\x13\x9b\x2c\xc3\x08\x7a\x91\x5b\x1f\x56\x39\xe4\x79\x1e\xce\x05\xc1\x71\x33\x38\xd7\xf9\xff\x42\xf3\x36\xa4\xad\xfd\x71\xab\x94\xf4\x9f\x70\x9b\xff\x84\x62\xb4\xb8\xf0\xe9\x9e\xe7\xf2\x44\x8c\x90\x88\x60\x28\xa2\xfd\x01\x65\xfb\x3e\x61\x83\xea\x0e\xa6\xb8\x7b\x7b\x25\x59\xb4\x6a\x71\x41\xeb\x55\x2c\x18\x21\x5c\x24\x63\xf0\xce\x24\x56\x30\x14\xa4\x2c\xaf\x17\x84\x70\x89\xd2\x4d\x58\x5f\x72\xdf\xcb\x66\x30\x42\x14\xf7\x98\xff\xf6\x41\x36\xf7\x55\x7d\xfb\xb4\xff\x6d\x76\xae\x4e\x11\xcf\xf0\xfb\x68\x91\x70\xe0\xf9\x6e\xdf\xfa\xfc\x7c\xb7\x79\x7e\xe8\x46\xf8\xeb\xde\x95\x2d\xed\x57\x4f\x61\xa2\x13\x96\x38\x86\x56\xa4\x2a\x7f\xab\xab\x1f\x8d\x4b\x9e\x3e\x3a\x6d\x5c\xf8\x8e\xc9\xc8\xe7\xaa\xc5\x9f\x87\xe0\x08\x23\x4c\x27\xcc\x07\x7b\x6f\x72\x73\x5f\xd5\x1e\x55\xd2\xf9\x64\x3f\x17\xfd\x6a\x46\x98\x8d\xf1\x6e\x21\xe5\x11\x84\x63\x66\xa8\x9f\xff\xa4\x7e\xa4\x11\x0e\x34\xf1\x51\x81\x5e\x6e\x76\x5f\x05\x9e\x86\x66\x3e\x32\x89\x20\x99\x03\x10\x57\xe1\x31\x85\xe0\xb8\xe6\x15\x70\x94\xfa\x7d\x3c\x43\x49\xcc\x5c\x4d\xdf\xed\xfe\xe5\xb0\xcb\x8f\xa5\x6c\x2f\x75\xff\x7a\x71\x26\x55\xd2\x87\xdf\x9f\x64\x79\x91\xcb\x68\x49\x46\x12\x92\x41\xe8\xc3\xb6\xea\x07\x44\xc2\x23\x2c\x33\x70\x89\xf3\x89\x9e\x13\x23\x89\x50\x68\x75\x1f\xe0\x94\x23\xb8\xd4\x91\x1b\x7e\xac\xed\x3f\x31\x18\x67\x54\x4f\x13\xf2\xa7\xbe\x2f\x92\xd4\x85\xde\x6e\xc7\xe2\xf5\xc3\x06\x4c\x12\x25\x44\xe6\xd2\xc6\xa8\x21\xd1\x0f\xb9\x54\xb9\x5d\xf1\x21\xe0\x6a\x0e\xa8\xe0\x7c\xf7\xdb\x08\x84\x95\x86\xb6\xda\xe0\x0a\xd8\x79\xec\x9b\xe1\xf5\x32\x96\x31\x34\x10\xd7\x4f\xeb\xd7\xd5\x74\x2a\x88\x28\x3c\x61\xc6\x63\x4c\x68\x3e\x55\x4d\x33\xa6\xf9\xf5\x87\x65\x14\xa7\x91\x17\x6b\x9b\xa4\xaa\x19\x91\x86\x04\xa2\xea\xaf\x55\xfd\xad\x99\xa2\x1f\x7d\x23\x15\xb9\xe5\x73\xbd\xd9\xaf\x5e\xef\xc2\xa3\xa9\x94\xc8\x09\x07\x03\x72\x8a\x54\x1f\xe4\x0c\x19\x51\x99\x0e\x11\xcc\xb5\xac\xcb\x2b\x3d\x34\x46\x94\x8a\xd0\xa9\x80\xf6\xad\x33\xb3\x46\xda\x30\x8c\x28\x60\xc8\x99\x78\x46\xf5\xc9\xda\x45\xae\x06\xfb\x92\x11\xcd\x19\x26\x3c\x76\xd5\xa5\x34\xba\xb3\xf6\x27\x91\x01\x46\x0c\x4d\xbd\x6b\x1d\xb6\x07\x07\x3c\xed\x8f\x83\x20\x49\x0f\x50\x72\xe2\xe1\xf5\xac\x27\x21\x72\xd0\xc0\xe0\x0e\xbe\x74\x6b\xd7\xfa\x6e\xfd\xc7\xec\x4d\x80\x38\xfd\x24\x54\xef\x6a\xf3\xba\x9a\x1d\xb7\x92\xa4\x6c\xe4\xa6\xce\x73\xd4\x8c\x46\x11\x45\x9c\xd0\xf7\xaa\xcd\xcb\xe3\xdd\x65\x4c\xbd\xc0\x68\x64\x63\xe2\x4b\xd1\x8a\x5d\xe7\x3c\x2e\xf2\x84\x76\xed\x9c\xa3\xe9\x82\x38\x87\xcd\xed\xcb\x00\x09\x98\xb6\x24\x86\x66\x8e\xe8\x45\xea\xf6\x50\xe4\x7f\x5e\xbc\x01\x7f\x38\xe2\x33\xd6\x07\xf8\x73\x61\xe6\xce\xee\x47\x40\x12\x5f\x62\x78\x25\x36\x30\x5b\x62\x28\x8d\xdc\x07\x1b\x65\x9b\x11\xe0\xf8\x17\x50\xa2\x70\x36\x35\x48\xb9\x73\x76\x56\xe4\x7a\xff\x69\xd6\x81\xb4\x5b\xf2\x11\x8b\x20\xcb\x9b\x90\x0a\x65\x94\x72\x8b\x46\x0d\x46\x10\x7d\xfd\x73\x73\x1f\xb4\xab\x42\x23\xc8\xdc\x8e\xdb\xf9\x13\xce\x4e\x7d\x05\x69\xde\x47\x1c\x75\x8c\x32\xa6\x9d\x36\xe9\xf9\x5c\xe5\x65\xbb\x3a\xce\x45\xd9\x18\xe5\x34\x61\x2c\x84\xdb\x2f\xa5\x79\xb1\xbb\xfc\x67\x0b\x50\x76\x2e\x7d\x33\xfb\x02\x42\x0b\xb4\xb4\x51\x96\x6a\x07\xed\x73\xf5\x63\xd6\x22\x89\x14\x92\x5d\xf4\x62\x1a\xe3\xd2\x46\x46\x13\x9a\x45\xc6\xc7\x8e\xf0\x29\x56\xbe\x10\x7b\x3e\xb6\x12\x9e\x26\x76\x28\xd4\xfe\x08\x51\xc1\x68\x62\x18\x0e\xd3\xb7\xb1\x4c\xcd\xfc\xb9\x13\xc3\x4c\x3a\xd3\xb6\x98\xdf\xd0\x2a\x10\x21\xa9\x58\x1a\x39\xbb\x42\xea\x15\x78\x8e\xd0\x3a\xd2\xec\xf9\x71\x6b\x52\x1b\x22\x35\x4e\xa5\x69\xbc\x88\xd1\x2c\x8b\xc3\xca\x32\x4e\x8d\x31\x2a\x35\xc1\x2a\x8d\xbc\x85\x53\x80\xbb\x4d\xba\x4c\x82\x40\xe5\xc1\xf2\x72\x0a\x29\xa1\xb0\x5e\x50\xcd\x54\x40\x7c\x84\x05\xe3\x3a\x03\xcb\xa8\x4e\x5d\xc4\xe2\x98\x7f\xef\xd7\x12\x6a\x22\xaf\x4c\x3d\xb0\x34\xfe\x43\xea\x6f\xe7\xaa\xbf\xb3\xb1\x71\xec\x88\xfe\xb7\x35\x04\xb4\x91\x3f\x06\xdc\x22\x78\xcb\xca\xbc\x98\xdd\x0d\x62\xb7\x00\x39\x42\xd7\xb4\x3f\x23\x55\x08\x1b\x43\x6e\xc2\x49\x76\x8e\xf4\xfb\x18\xb5\x56\xe0\xa2\xb1\xfb\xe7\xe7\xd5\xdd\x61\xb7\xf9\x77\x30\xd4\x59\x94\xc6\x18\xad\xde\x9d\xdf\xa0\xf6\xf5\x63\x68\x2a\xbe\xf7\x2d\x24\x25\x9e\x58\x1f\xc1\xdb\x03\xdd\x00\x63\x94\x70\xe6\x7d\x9c\x87\xaa\x30\xa3\x2c\xad\x27\xe2\x18\x7f\x2c\x46\x85\xa3\x84\x3c\xd6\xbd\x38\xd9\xe2\xe0\x63\x34\xb6\x18\x87\x9a\xd8\x81\xfb\xca\x55\x6e\x2d\x5b\x10\x8c\x1a\x83\x40\x80\x43\xde\x38\x01\xc0\x91\xb7\xc5\x18\x61\xb8\xc4\x39\x78\xd7\x46\x57\xfd\x01\xea\xc8\x26\x1a\x68\x1f\xe1\xfb\x75\x8d\x5d\xd7\x42\xe3\xee\x73\x7a\xff\x52\xb5\x30\xeb\x1b\x16\x3b\x7d\xfa\x07\x68\x5f\xf3\xe3\x98\x2b\xce\x37\xe0\x52\x20\x30\x09\x45\xf4\x7b\x9d\x3c\x17\xb1\xfa\xe5\x2a\xc7\x04\x65\x8c\xfb\x22\x7b\xdc\x56\xc3\x3d\x05\x8f\x11\x6d\xf1\xdf\x2a\x2f\x1f\xe4\xc9\xd1\x23\xfb\x30\xf7\x72\x77\x8a\xc4\x21\x8b\x6d\x5d\x9d\x66\xcf\x27\x94\x40\xb6\xf2\x07\xd9\xec\xa0\x28\x7e\x1b\x7e\xce\xd2\x20\x88\xd4\xea\x83\xbe\xc2\x82\x32\x26\xac\x45\xfb\xc4\x6d\x64\x58\xe8\xb0\x2a\x8d\xe3\xe8\xc3\x1a\xf9\xc5\x40\x59\x1a\x60\xe8\x4b\xbb\x89\x3b\x48\x66\x5b\x0b\x8b\x65\x82\x85\xbd\xe7\x1a\xbe\xe7\xd5\xa5\xd9\x42\x9d\x57\x66\x3c\x0e\x63\x6d\xad\x63\x2c\xf2\x36\xa2\xd7\x80\x9c\x3e\x71\xc2\x12\x4c\xe8\x9e\xab\x1f\x50\x2f\xeb\x27\x31\x96\x18\x47\x81\xdd\x40\x69\xee\x8b\xae\xe5\x15\xf2\x6e\x0c\x72\xbe\x7a\xd8\x94\x58\x65\x7b\x97\xac\x1b\xe9\xcd\x56\xe6\xb3\x75\x98\xa5\x3a\xc3\xd5\x67\xd7\x74\x2e\x6d\x69\x64\x6d\xfe\x9e\x06\x2e\x63\xa9\xe5\x5e\x9e\xe2\xb6\xe8\x45\x67\x19\xcb\x22\x8d\xe8\x8d\x2f\xab\xdd\x7e\xf1\x52\x93\x8b\x64\x94\x4a\x13\x56\x38\xf4\x2d\x3f\xbf\x6e\x7e\x9b\x35\x89\x5d\xb9\x53\x67\x8b\xb9\xcd\xf2\xc5\xee\xdf\x06\x1b\xaa\xbf\x33\x8b\xc4\x10\x78\x7f\xc5\x10\xe2\xbf\xab\x93\xca\xe1\xd0\x7d\x06\xf7\xcf\xbe\x71\x9a\x44\xbe\x0a\x08\xd1\x11\x37\x55\xf5\x6d\xa7\x3f\x24\x6d\x65\x2c\xcb\x0c\x22\x13\x36\xcf\xb7\xaf\xff\xda\xee\x7f\xfd\x56\x5a\x05\x51\xa6\x19\x3f\xb6\xe3\xa7\x1b\x51\x47\x32\x26\x79\x82\x11\x98\xa6\x00\x38\xf7\x3f\x02\xc3\x9c\x48\x3b\x94\x97\x9a\xd9\xae\xc7\xa4\x4d\x95\xdf\xda\x37\xda\xb1\x8d\x38\xfe\xc1\xa6\xf7\xaf\xc6\x3b\x0d\x53\x42\x21\x8e\xf8\xad\x2a\x3b\x0f\xbf\xdb\x8d\xfa\x63\x5a\x58\x1b\x08\x20\xcc\xa9\xd7\x88\xef\x27\xbb\x56\x10\x62\x60\xce\x9d\xdc\x57\xcf\x73\x4f\x9d\x19\x12\x21\x3d\xde\xa7\xed\x58\xb9\x9d\x31\x43\x13\x70\x78\x1a\xa4\xb2\x27\x07\x39\x31\x8b\x99\xa1\x12\x2b\xb2\x4e\xef\x56\x7e\x14\x5a\x63\x46\x38\xd2\xfc\x06\x5a\x0c\x66\x34\xf9\xb1\x5c\xe0\x15\x62\xcc\xa4\x02\xbd\xc4\x5e\xf9\x0d\xf7\x92\xba\x3a\xad\x0b\xfd\xc1\xb5\x81\xd9\xc4\x07\xe3\x5f\x0a\x73\xe8\xa7\xe4\xcc\x88\x60\x96\x73\x33\x48\xc6\x3a\xde\xeb\x0f\x90\x1c\x8c\x59\x11\x61\x97\xa2\x05\xd7\xb9\x85\xeb\x9f\x79\x33\xab\x8e\x63\xcc\xc6\x12\x2b\xa1\x41\xd6\xc5\xfb\xb5\xc0\x17\x63\x36\x95\xd4\x5b\x1e\x58\x39\xe4\x33\x70\x18\xd2\x58\x7e\x1b\x0b\x9e\x3f\xbc\x57\x5c\xb8\x5c\x33\xe9\xba\xb6\x3c\x8a\x22\xed\xf1\x36\x0f\x75\x1e\xa2\x52\x3c\x4a\x13\x37\x80\xe5\x09\x1e\xab\x63\x1f\x90\xe3\x91\x71\x74\x38\x79\x83\xd8\xfc\x0f\xae\x4a\x98\x43\xb7\xba\x2d\x10\x3b\xb3\x5e\x7d\x97\x79\x31\x29\x6d\x99\x74\x04\x27\x5c\xe2\xf7\x35\xd5\x5d\xde\x9c\x2f\x28\xc6\x55\xd5\xef\x5f\xeb\xbc\xbd\x16\x2c\x9e\xdd\x2e\x53\xc8\x05\xf4\x38\xc4\x97\xbe\x87\x07\x26\x8a\x31\xdd\x33\xde\x74\xf7\xff\x92\xc3\x8f\x97\x7a\x07\xe3\x72\xf9\x80\xf0\x60\x9c\x72\x85\xa5\xd4\x3e\x0f\x7c\xe0\xe1\x42\x34\x36\xa9\xa7\x8e\x5a\x9f\xf2\x76\x14\xf1\x98\xbe\x07\xcd\x5c\x62\xa7\x84\x1f\x13\x5b\x6d\xf6\xcc\x54\x47\x48\x78\xf0\xe5\xdf\xfb\xc3\xd7\xd5\xe3\x63\x90\xe6\x63\x9c\x49\x26\xac\x5f\xf8\x3b\xcf\x61\xf9\x2b\x73\x06\x26\x72\xa0\xa2\x5d\xe7\x53\xef\x60\x6a\xe4\x70\xc1\x52\x57\xd5\x85\xb1\x9f\x6e\xbc\x3e\xc8\x3e\xff\xc4\xb8\x88\x9d\x0d\xe4\xe8\xe8\xaf\x75\x16\x19\x8f\x99\x63\x0a\xd9\xbf\xd5\x55\x09\xa8\xd3\x09\x66\x52\x47\x18\x1a\xa6\x99\x93\x47\x1c\xd7\xb5\x3a\x51\xdc\xbf\x70\xa4\xae\xfe\x4e\x0a\x6e\xc3\xe5\x35\x8d\x3c\xb5\xee\xcd\xe5\x4a\x1c\xd4\x37\x4a\x38\x41\xd8\xb7\x7b\x1d\xa4\xc3\x5f\x7a\xa7\x44\x65\x89\x2f\xe2\xd9\xdc\xbe\x7c\x05\xf8\x46\xaf\x29\x76\xb0\x19\xd2\x0b\xdc\x56\xa7\x53\x55\x2e\x58\x63\x3c\x95\x6a\xd0\xc6\x76\xd8\x31\x17\x2b\x98\x5e\x28\xb5\x46\x0f\x90\x6a\x74\x7c\xdb\x39\x1b\x28\xe3\x99\xa6\x18\x16\xb8\x2d\x40\xd6\x6b\x57\x53\x8f\x86\x43\x5e\x1e\x27\x64\x42\xa1\xbd\x15\xd0\x5d\xf5\x70\x76\xc2\xb1\xb7\x6f\xb2\x5e\x4e\x62\x84\xf8\x09\x97\x11\x47\x4f\x42\xd5\x00\xa6\xdb\x8d\x6e\xc2\x40\x90\x82\x21\xf8\xc4\xe5\x96\xf0\x5d\xdd\xb8\x75\x72\x0a\xa1\x95\xb2\x71\x90\x3c\xf9\x82\xf1\xe1\xe3\xec\x25\x54\x9c\x22\x19\xd3\x4e\x5a\x78\xc8\x6d\x3b\x2b\xbd\x5f\xd8\x26\xb9\x8e\x28\xfa\xc7\x26\xff\x7e\x5f\xd5\x53\x9c\x09\xe3\x9a\x48\xc4\x4a\x3f\xd2\xdb\x85\x1a\xe9\xd0\x28\x23\xca\xef\x0a\xf7\x79\xf1\x11\x56\x76\xf1\xe6\xda\x60\x01\xe9\xe6\x66\xf3\xef\xd5\xed\x6a\xf7\x29\xdc\xd7\x68\x11\x4c\x12\x5f\x78\xff\x2b\x60\x35\xe3\xc0\xb2\xc0\x0c\xf3\x44\x67\x5f\xca\x92\x14\x6d\xa4\x63\x85\xc8\xa7\x70\x0b\x6b\x12\x74\xee\x0f\x5e\x15\x74\x50\xe4\x1a\xfa\xd3\xda\x2c\xe9\x29\x2e\x7a\x7a\xfe\x99\x48\x3b\x13\x91\xcc\x90\xaf\x6a\xa5\x35\x34\xcd\x43\x67\xe7\x4d\x9f\x41\x44\x52\x63\x86\x21\xa0\x84\x9e\x56\x7f\x1c\xd6\xfb\xf0\xba\x82\xd0\x54\xd3\x50\xa6\x03\x28\x37\xf3\x3e\xc1\x6e\x33\x41\x12\x0b\x4e\xbb\xe4\xe7\x6d\xd5\x0c\x3f\x6b\x8b\x0b\x44\x03\xed\xaa\x0f\x07\xcc\xfb\x6a\x58\x5a\x05\x25\x8e\x43\xd3\x83\x2d\x9b\x83\x81\x73\x80\x1d\x32\x41\xad\x04\x1d\x66\x14\x6e\x71\xd7\x21\x22\xc1\x20\x41\x93\x27\xa4\x9a\x9f\x60\x34\xe7\xa6\x4b\x82\x88\xb5\x40\xcf\xbb\x96\x1a\x59\x86\x47\xa1\x4e\x91\x70\x8d\x79\xba\x7e\x8b\xfc\xbd\xac\x7e\xa0\x7e\xdc\xcd\x35\xd1\x50\x38\x47\xa5\x68\x87\x86\xec\xf3\xae\x2a\x72\xb3\x1b\x98\x43\x99\x48\x80\xa0\x79\x80\x96\x6a\x67\x6c\xbf\x5c\xfa\xce\x4a\xa9\x8a\xbb\xcf\xf9\x69\x73\x77\xb7\x7e\x1e\xe5\xe7\x44\x2a\x32\x1d\x4d\xd4\x14\x36\xb7\x2f\x0b\x6a\xc2\xc3\x93\xa4\x19\x45\xd3\xbe\x33\x0a\x97\xea\xa3\xba\x16\x0c\xc3\x2b\xfb\xf5\xea\xe9\xf0\xe9\xe5\xf1\x2e\xb0\x9b\x30\x91\x45\x04\x23\xe5\x2e\x0c\xee\x98\xb5\xd7\xa5\x19\x77\xf6\xec\x76\x59\xca\xb9\x8b\x38\x96\x3e\x69\x7e\x0f\x70\x23\x1b\x6f\x03\x34\xfd\x95\x53\xc7\x05\xd9\xcb\x91\x05\x82\xa2\xbe\x81\x76\x8c\x35\x8e\x92\xcd\x03\xe8\x42\xa8\xa0\x9c\xe4\x8c\x44\x66\x75\xe6\x07\x57\x2f\x71\x75\x55\x51\x3c\xfb\xeb\x4f\x95\x94\x63\x86\xe7\xbf\xd5\x7b\x53\x4d\xa2\x31\x42\x49\xd3\xab\x5a\x5e\xca\x23\x54\xa5\x8f\x36\x2f\xbf\xb9\xb2\xdc\x81\x34\xe4\x09\xea\x4b\xb0\x67\x85\x8e\x92\xc8\xe9\x45\xd5\xc7\x80\x6a\x9a\x7d\x00\x23\x99\xa6\xbd\x94\xe3\x22\xa6\xb0\x6b\xe4\xf0\x08\x8f\x50\x96\xb2\x6e\x47\x29\x1f\x01\x99\xc4\x38\xb4\xbd\x14\xf7\x79\x51\xec\xff\x98\x4d\x04\xd0\x1c\x27\xf5\xca\xe0\x86\x8b\x3c\xec\x4b\x39\x7b\x01\x26\x51\x26\x08\xe4\x63\x04\x90\x84\x7b\xd8\x88\x18\xcf\xda\x13\xea\x57\x7e\x0b\xbe\xe4\xd8\xd0\xba\xd2\x72\x08\xe7\x4b\x88\xf9\x50\xad\x59\x6f\xeb\xea\x5c\xe7\xd0\xca\xfa\xfd\x3a\x02\x21\xac\x76\x68\xd6\xce\x57\xfc\x24\x4b\x53\xcc\x22\x28\x7e\x6a\xc6\x11\xa1\x18\x6f\x40\xb3\xf9\x15\x81\x58\x79\x55\x3a\x96\x85\xd0\x84\x27\x72\x10\xb8\x0f\xfb\xc6\x47\xec\xcb\x2c\x26\x94\x60\x48\xd8\xcf\xb0\x85\xfd\x3c\x26\x54\x60\xdd\xdd\x43\x55\x98\xfb\x5c\xb6\xf7\x30\xcd\x52\xc4\x24\x75\xbe\x7f\x0d\xd2\xb8\xdc\x68\x29\x4f\xf0\x47\x0b\x32\x0c\xef\x98\x92\x34\xf2\x7b\xd1\xa6\x85\xd3\xf3\x48\x52\x65\xda\x73\x31\xa5\x34\xe4\x20\xa5\xc3\x06\x8f\xb0\x41\x2c\xa6\xc6\xb0\x20\xe1\x92\x97\x3f\xc3\xcf\x9c\xd1\x58\x07\x05\xba\x2f\x55\x0b\x1f\x0c\xdb\x98\xb3\xd8\xa9\x39\xf6\x58\x67\x59\xf7\xac\x8d\xdd\xe1\xcc\x38\x49\x99\x4b\x33\x5b\x60\x63\x41\x08\x75\x6c\x86\x6e\x56\x7a\x36\xc0\xba\x3a\xdd\xc8\xb2\x67\x7e\x98\x9f\x43\xb1\x3e\xc1\x51\xcf\x63\x8e\xf6\xb5\x5b\x02\xe6\xcd\x98\xc2\x4b\xbf\xae\x6f\xef\x17\x6c\xb3\x58\x40\x8c\x24\xc5\xaf\xeb\x9b\xf5\xe3\xed\xcb\xe6\x79\x5c\x5b\xc4\xe2\x58\x65\x58\xbc\xed\x58\xd5\xfc\x37\x77\x72\x4e\x87\xb6\x3a\xe8\x69\x30\x20\x4e\x62\x4e\x60\x60\xba\xf4\x50\xc6\x71\xdd\x3d\x8b\x93\x8c\x73\x1f\xf4\xdd\x98\x9b\x77\xfc\x60\x93\x8f\x9e\x32\xc1\xfc\x2c\xf6\xaf\x7e\x2b\xcf\xb3\xc7\xce\x6c\x1c\x74\xfc\x7d\x91\x0c\x4e\x86\x1b\xac\xbb\x0c\xa8\x4a\x16\x4b\x99\xe0\xee\xf1\x0a\xa7\xce\x7b\xf8\x90\xae\x97\xc5\x52\x73\x5c\xdd\xbf\x76\xf3\x1e\xa9\xa9\x07\x54\x48\x2c\xad\x40\x4e\xd8\x12\x7e\x4e\xc5\x35\x7e\xf9\x5f\x7f\xb2\xe2\x6e\x1f\xc7\xd7\x69\xf3\xef\x70\x9f\x0f\xc5\xc6\xb3\xa7\x50\x5a\xe1\x1c\xfb\x9a\x97\xa6\xa8\xea\xe0\x19\xc6\x5a\x70\x31\x4d\x8d\x6f\xeb\xaa\x9b\xa4\x93\x85\x36\xd6\x69\x82\x70\x9b\xaf\x37\x63\xf8\x2a\x8b\xb5\x15\x9a\xf4\x64\xd9\xde\x92\xec\x86\x97\xaf\x6a\x9b\x4d\x4b\x43\x22\x91\x0c\x3c\x20\xde\x31\x1f\x47\x35\x62\x23\x24\xa6\x3e\x8f\xf9\x77\xf8\xfd\x62\xaa\x66\x91\x55\x94\xc5\x26\x96\x7d\x8e\xdb\x5d\xe6\x66\xb1\x28\x84\xc5\x46\xb9\x57\xaf\xe1\x3b\x94\x17\xb8\xaf\xe5\x88\x9a\x96\xc5\xe0\x05\xb3\xd4\xe5\xfd\x1e\xcb\x75\x76\x27\x59\xb7\x0b\xdc\x35\x7d\x7b\x8d\x35\xd3\xcd\xa5\x39\x43\x69\x1e\x7a\x3c\x34\x8b\xc1\x00\x32\x41\x7e\x87\x1a\x01\xce\xe7\x1c\x7c\x0a\x33\x9f\x51\xf3\xb0\x18\x2c\x49\xa5\xd7\x3b\xfb\x11\xd6\xbc\xab\xac\x79\x6c\x49\x84\x69\xbf\x37\xd9\xdc\xcc\x43\x23\xb1\x15\x0a\xab\x63\xaa\xda\x40\xdd\xdc\xca\x12\xa9\x3a\x0e\xfd\x45\x08\x1f\x52\xcf\xe1\xdf\xe9\x7f\xe2\x0f\x01\x3e\x0b\x63\xcc\x4a\x87\xcb\xa9\x65\x0b\x3b\x80\x71\x85\x29\x4b\x22\x42\x11\xdf\x67\x7b\x5d\x4d\x96\x10\x22\x19\x19\x34\xb6\x0e\x72\x46\x2d\xcf\x12\xe2\x95\xe4\x1f\x56\xfb\xf5\x63\xff\xa3\x48\x74\x34\x14\xfa\x20\x0a\x7a\xb0\x35\x13\x62\x24\x12\x8d\xf6\x05\xdb\xa3\xbe\xf2\x4d\x58\xe4\x12\x93\x08\x46\x2f\xbf\xcb\x66\x2b\xf3\xb2\x0d\x5c\x75\xa1\xdf\x13\xc6\x65\xe6\xd9\xfa\xd0\x07\xee\x09\x43\x1d\xe9\xc7\x48\xd7\x37\x9c\x90\x18\xe4\x05\xdd\xe7\x58\xe8\x37\x1e\xfe\x09\x8f\xb4\x75\x31\xd3\x7d\x9d\x1f\x7b\xa1\x59\x96\xf0\x54\x22\x86\x20\xac\xbb\x07\xda\x1f\x51\x94\x7a\xa9\x9b\x73\xd5\xc8\xc2\x47\x91\xa6\xf7\xe4\xe0\x80\xa6\x9e\xe0\xe3\xe6\x1d\x99\xf5\x97\xb7\xc3\x44\x10\x42\x06\x45\x13\x07\xb5\x0c\x77\x13\xdc\x62\x7c\xa7\xac\xda\xcf\x48\x8f\x2c\x55\x01\x9b\x12\x43\x0c\xa1\x4d\x2c\x5c\xc7\x99\x51\x59\xa4\xaf\xd1\x66\x49\x9c\x50\x4c\x84\x79\x32\x73\x87\x6d\x5d\xdd\xef\x7f\xef\xcf\xb6\x54\xc3\x8c\x48\x7d\x9a\x11\xee\xbb\x3e\x11\x0e\x49\x2d\x4f\x27\x28\x4d\x50\x05\x45\x02\x84\xc5\x45\x2b\x49\x62\x25\x43\x7a\xe5\x71\xb5\xbf\x95\xf5\x35\xa9\xe0\x72\xda\x38\x49\x3c\x08\x7d\x8b\xc9\xfd\x3b\x64\x14\xbe\x1d\x08\x61\x59\x92\x48\x40\x3e\xc4\xc3\x02\x78\xe0\x6f\x11\x77\xb1\x24\x4d\x63\x11\xc0\x25\x87\xaa\xec\x69\x41\xbb\xe9\xf3\x5c\x3d\x56\xc7\x70\xaf\x8c\x09\xa4\xb7\x42\x47\xe2\xc1\xe9\x7c\x02\x18\x2f\x3c\xdd\x83\xc7\x92\x4c\xc7\x41\x30\x7c\x73\xfb\x12\xac\x78\x7f\x50\x12\x8e\xe6\x59\x6e\xd7\x27\xa8\x8f\x50\xea\xf7\xdd\x00\x69\x49\x24\x73\x7c\x27\x3d\xeb\x99\x23\xc0\x5d\x4e\xdd\x24\x8a\x29\x6d\x02\x29\xcc\xa5\x6c\x6e\xde\x3d\x06\x78\xf9\x4d\x55\x12\x23\xe2\x6b\xd7\x39\x73\x48\x4f\xbc\x8c\xb6\x66\x89\x4a\x13\xea\x43\xaf\xfb\x1c\xea\x6b\x80\xe5\xe2\x6a\x9e\x28\x29\x11\x14\x7f\x93\x1f\x27\x13\x4c\x13\x07\x5d\x56\xae\x46\xa7\x2a\xf7\xfb\xa7\x9b\xf7\xce\xdd\x5d\x7e\x2f\x1d\xb3\xd4\x9b\x00\xeb\x9f\x6d\x2d\x7b\xa2\x0f\x96\x68\x88\x10\x19\x87\xd7\xf7\x00\x79\xa7\xed\x36\x9b\x7c\x1a\x52\x0c\x3f\x7e\x5a\xbd\xde\x75\x8e\xdd\xe1\xf3\x2e\x20\x54\x12\x93\x44\x48\x48\x28\x55\xbe\x2e\x75\xd5\x2b\x55\x4f\x02\x5d\x61\xf1\xee\x16\x8e\x91\x5c\xfa\x75\x5f\x5c\x3b\xd5\x09\xb0\xc4\x41\x00\xdc\x0e\xf9\x30\x5f\xf3\xd3\x88\x64\xa1\xe0\xf7\x53\x75\x06\x7b\x29\x36\x33\x6f\x31\x25\x19\x43\x55\x81\x97\xfd\x7e\xdc\x99\x29\x01\x8e\x25\x63\x1a\x2b\x1c\x26\x73\x33\xa5\x8c\xc5\x9e\xfd\xfe\xa5\xe7\x7a\xb9\x8a\x62\xa4\x34\x71\x08\xff\x23\x38\x66\xc4\x37\x4c\x50\xf4\xd1\xa7\x94\xca\x58\x50\xbf\x20\x5e\x9a\x16\xcc\xee\xad\x9a\xa1\x76\x52\x0a\x89\x80\x01\xba\xbb\x1c\x52\x9a\x8e\x8f\x94\x91\x38\xf3\xb9\x91\x47\xf8\x9e\xb7\xb2\xb3\x33\x3e\x97\xb9\xae\xea\x72\x6a\x21\x84\x95\x2b\xe5\x1c\xe2\x28\x4c\xba\x97\x2f\xb7\x03\x15\x2c\x4b\xb9\x30\xb4\x4f\x2d\x0d\x5b\x53\xca\x33\x81\x30\xd9\x71\x14\xf5\xaf\xcb\xb5\x59\xca\x8d\xc6\x0a\x39\x28\xcd\xfe\x0a\x60\x37\x6b\x2b\x22\x81\xf9\xa1\xfb\xe2\xfd\x56\xfa\xd4\xf8\x4e\x7e\x5c\xc2\xfe\x97\x7f\xc7\xe7\xc5\xfc\x3f\xe2\xff\x86\x1b\xc5\x14\x4b\x8b\xba\x41\xbe\xcf\x4f\xe0\x6a\x25\x96\x37\x91\x54\x24\x4e\x2f\xc6\x3a\x51\x2e\xa4\x9a\xf6\x20\xd3\x5e\xc2\x9e\xa5\x22\xb3\x8e\x90\xe8\x04\xad\x34\x57\x4e\x61\x2a\x0c\xe5\xba\xa7\x1e\xeb\x89\x0c\x46\xcc\x35\x2c\x8d\x63\x47\x18\xd2\xad\x9a\xff\x18\x5c\xe4\x34\xce\x18\x22\x5b\x5e\x01\x8b\xfd\x5d\xc0\x39\x1c\x93\x94\xf3\x40\xb3\xda\x76\xdf\x3e\x98\x7a\x63\xd3\x2c\x8d\x8d\xc6\xbd\xb5\xaa\x8f\x43\x99\x1a\x4b\x13\x12\x63\x6c\xbe\xae\xaa\xf6\x60\xaa\x93\x1c\x6e\x9a\x50\x9b\x06\x42\xab\x83\x3c\xca\xbc\x6c\xda\xfb\xaa\x7f\xdf\x24\x31\xb8\xfc\xdc\xdf\x3c\x0e\x25\x96\x2c\x4d\x74\xea\xb2\x79\xdd\x59\x79\xf9\xbd\x5b\xf7\x5f\x2f\x05\xb8\xe8\x4b\x68\x95\x72\x47\x34\x71\xf3\xb8\x79\x7e\xe8\x7f\x4c\x04\x56\xfb\x21\x63\x7a\x31\xd2\xde\x60\x69\x9a\x0a\x37\x05\x2f\xf5\xb9\x08\xb5\x06\x2c\x95\x49\x84\x90\xf2\x03\x3f\xa0\xe6\x49\xff\x7b\x9a\x62\x04\xaa\x7b\x88\x07\xef\x36\x3b\xcb\x36\x20\x5a\x46\x76\x5c\x2a\xb5\x42\xc0\xde\x97\x1c\x7e\x1c\x9c\xb2\x3a\x8c\x71\x15\x87\x2b\xe5\x44\x96\x2a\x26\x11\xac\x5c\x5e\x4e\xdb\xa2\xea\xb7\xce\x54\xa5\x11\x3a\xae\xd2\x84\x21\x02\x7d\x86\x12\xf6\xd5\xd5\x3a\x17\xd6\xc3\x54\x19\x8b\x01\xe2\xc6\x4d\x2f\x68\xe6\x8b\x9b\xd6\x19\x0f\x3b\xea\xba\xae\x87\x20\xf2\xbe\x72\xa1\x03\x1f\x98\x0c\x44\xd3\x2c\x05\xca\x30\x5a\x1b\x32\xa6\x4f\x57\x28\xea\x14\x52\x23\x49\x90\x71\xf7\xe5\x1a\xa1\xe8\xba\xe7\x06\xfd\xff\xcc\xdb\xc9\x52\xb0\x26\x72\x51\x5f\x4c\x50\xef\xab\xb9\xe4\xc4\xb4\x7d\x16\xd1\xc8\x38\x5f\x09\x4c\xb0\xe8\xe6\x2d\x9c\x40\x44\x5e\xe6\x8e\xe2\xde\x21\x12\xfe\x16\x6f\x2b\xcb\x22\x91\x45\x9e\xe7\x18\x3f\xc1\x23\xd6\xa5\xf7\x5f\x66\x53\xde\x74\xde\xc1\xfc\xa3\x64\x91\xaf\x65\x90\xaa\xce\xeb\xbb\x4a\xea\xaa\x87\x9b\x66\x91\xa2\xdc\x03\x18\x9f\xd5\x0e\x8a\x02\x73\xeb\xfd\x51\x63\x71\x1c\x54\x85\xf9\x63\xbb\xf2\x8a\x29\xfe\x18\x89\x33\x24\x47\xfd\x01\xf9\x24\x4a\x95\x91\xd8\x15\xfd\xab\xdc\xbc\x94\xb7\xb5\xb4\xed\x6a\x46\x81\x30\x7d\x2b\xa2\x9d\xe0\xf3\xba\x34\xdd\x26\xda\x93\x4e\xb0\x8c\x58\x87\xe6\xb1\xd0\xea\xb7\x2f\x55\x0b\xdd\x10\xbe\xaf\x6a\xa4\x8f\x99\x8e\x81\x8c\x6a\x8e\xbb\xa6\xdb\x89\x37\x2d\x9c\x5c\x52\x64\xd1\x1a\xc9\x58\xa4\xad\x0f\x2b\xfa\x18\xc0\x17\xa8\xb1\x3a\x78\xbc\xdc\x64\x8c\x32\x24\x71\x79\xcb\x8f\x58\xdc\x8e\x9f\xcc\x15\x50\xfb\x16\x9c\x45\x6e\x4d\xbb\x79\xb9\xed\x7f\xb3\x14\x3d\x3a\x94\xdb\x43\x57\x7b\x89\x0f\x98\x65\xb1\xe0\xe0\x48\xa0\x4b\x53\xfd\xa0\x68\x53\x8f\x80\xef\x59\x1c\x1b\x25\xbc\xa8\x60\x4f\xfc\xc2\xb2\xc4\x24\xd2\xdb\xe3\xdb\x8d\xe3\x2d\xa1\x7c\xfa\xdc\x89\xed\xe9\x03\x77\x0e\x5d\x3c\x31\xce\x7a\xcd\x5a\xdf\x3c\x25\xa9\xf4\xa1\x5b\x0f\x6f\x5d\x1e\xdf\xa9\x52\x36\x19\xb4\xdc\x7a\x5a\x1d\x96\xa5\x10\xf9\x58\x61\xdb\x42\x9d\xcf\x0a\x0a\x59\x96\xf1\x0c\x8b\x8c\x9b\xd5\x50\x3a\x1f\x0e\x69\x8d\x45\xf5\x9f\xbf\xf6\x1d\x28\xe3\x38\x71\xd2\x88\xb2\xd0\xcf\xf0\x73\x09\x43\x97\x29\x96\xa0\x21\x72\x40\xfc\x1a\x41\xca\x90\x70\x01\x9d\x44\xdc\x79\x8a\xa8\x3f\xe6\xb6\xe0\xa9\xfd\x1b\x5a\x6a\x43\xa0\x97\x55\x47\x6b\xbd\x47\xa3\xf7\x43\x5d\x9b\x0c\xab\x3e\x31\xea\xbd\x1c\xe8\x9f\xf5\x94\x31\x80\x00\x89\x2d\xfa\x80\xb0\xf5\xae\xe0\x47\x0c\xee\x1f\x5d\xc5\xd2\x28\xea\x09\xa3\x1d\x40\xaa\xc1\x65\xdc\x37\x00\xca\x94\x37\x15\x83\x97\x3b\x3e\x6c\x89\xf3\xfb\x9e\x2b\x1c\xb8\x6d\xde\x17\x94\x33\x19\x25\x91\xf2\xd9\x71\x57\x07\x3c\x1d\x9c\x32\xd2\x19\x52\x5a\xdf\x38\x32\xf9\xe0\x85\x48\x42\x22\xc5\x7b\x62\x47\xef\x4a\x86\x91\x24\x49\x06\xb8\xfe\xe7\x8e\x4e\xe1\xb6\x92\xfa\x2a\x5e\x35\x25\x6b\x08\x27\x1a\xe7\x4e\xb7\xc7\xda\xef\xff\x0d\xd2\x16\x74\xd7\x18\xa9\x24\xf9\xd6\x94\x4a\x24\x9f\x44\x41\x8d\xf6\xa0\x2e\xef\x87\x76\x98\x38\x98\x4e\xe8\x9e\xf1\xe6\x52\x97\x97\xf3\x83\x3c\x81\x4b\xb6\x79\x06\xa6\xbe\x59\x2a\x02\x1f\x81\x73\xc6\xae\x74\x1f\x99\x64\x51\x44\x86\x82\xd7\x59\xb6\x50\xb2\x2c\x36\x69\x80\x0d\xb9\xa4\x72\xc8\xc4\x8d\xb6\x66\xc9\x4c\x26\xc9\xa8\xd8\xa6\x0f\xde\x7f\xa8\xa2\xce\x24\x8f\xdd\xf7\x69\xab\x4b\x9d\x37\x63\x2b\x5f\xf2\x98\x53\xd1\x4b\x45\x28\xa8\x5f\xac\x47\x60\x98\x5d\x0b\xe7\x66\x5b\x57\x77\xd5\xc0\x85\xd2\x9d\x90\x22\x03\xa2\x1d\x2b\x0e\xfc\xad\x2d\x50\xf2\xce\x8f\xec\x3c\x8d\x00\xd0\xf7\x04\xfb\xd7\xc5\x12\xe1\x04\x6b\x58\xa0\xa5\xf2\x75\xa5\x3d\x68\x52\x0a\x92\x60\xa4\x14\xf2\xe3\x5b\xfb\xb6\x54\xa3\xcc\xa4\x90\x12\xb5\x8b\xce\xce\xbd\x75\x7c\x13\x3e\x0e\xbc\xad\x73\x67\x1b\x2c\x3f\xac\x30\x19\x8a\x30\x38\xfe\x8d\xe3\xf3\xfe\xf5\x5f\xe1\xaa\x71\x1c\x4b\x1f\x65\x7b\x05\xa9\xdf\xc0\xec\x2a\xdb\x0e\x15\x44\x32\x89\x92\xc8\x8e\x40\x48\x77\xf0\x1d\x8a\xea\x0c\xf5\x6d\x9f\x12\x94\xa9\x8c\xd0\xc4\x72\xfa\xbe\x70\xba\x62\x65\xff\x65\xe5\x2e\x93\x19\xd1\xda\x0f\x97\x2f\x85\xfb\xa6\xd3\x7a\x03\x99\xd1\x44\x27\xbd\x79\x8d\xc1\x3e\xdc\x16\xd6\x1f\x45\x50\x64\x46\x6d\xe4\x2a\xf6\xbb\x85\x3b\x80\x18\xab\xda\x81\x80\x66\xf7\x67\x2e\xdd\x79\xc4\x5a\xa6\x97\x5a\x6a\xac\x50\xfc\xe7\x05\x7a\x60\xaa\xcc\x44\x1a\xf8\x01\x76\xb2\xe8\x5f\x3d\xd3\x4e\xd2\xa1\x90\x4d\x7b\xb7\xde\xdf\xf6\x8b\xb5\x94\x3c\x75\x0a\x42\x79\x09\x5b\x38\x7f\x00\x25\x95\x32\x71\x01\xaf\xef\x39\xfc\xf8\x5c\x6a\x07\x4e\xf1\x93\x25\xac\x5d\x7d\x37\x28\x63\x12\xac\x22\xd4\x55\xf3\xde\xb4\x70\x9a\x64\x16\xa4\xa6\xca\x78\x0e\x6c\x9f\xdf\x7c\x82\x6e\x1e\x4c\x72\xd8\xe3\xff\x8c\xe3\xb2\x52\x8b\x54\xa9\x91\x42\xab\x93\xbb\x5f\x64\xa9\x4a\x67\x2f\xa1\x15\xc7\xbd\xaa\xdb\x97\xee\xaa\x8b\x2a\xe0\x26\x2f\x0d\x98\x9b\x22\x2f\xd1\xc0\x64\x73\x03\x71\x7a\xbe\xe1\x24\xac\x17\xbb\x6f\x79\x31\xf5\xd0\xa5\xc9\x34\xf4\x15\xe6\x67\xb7\xdc\xdf\xca\xf3\xa6\x5c\xb5\x6d\x05\x7d\xe2\x5d\x76\xae\x68\xb7\xfa\x3d\x6d\x1e\x82\xd7\x21\x81\x0b\x4a\x43\xf1\x29\x7b\x6a\x5a\x38\x0f\x19\xeb\xee\x68\xe2\x18\x87\xf2\x12\xaf\x38\x04\x3c\xa4\xe5\x11\x0b\x71\x81\x2b\x25\x16\x26\xad\x0c\x92\xe9\xd2\x43\x74\xcf\x85\xd4\x80\x04\x25\x81\xc8\x8d\x29\x22\x54\xa8\xda\x44\x63\xf0\x61\x9e\x75\x51\x24\x8d\x71\x81\x3f\x07\x0d\xfb\x0f\xb8\xcb\x99\xa2\x94\x86\x92\xf0\xa7\xf7\x6d\x55\xbd\xf5\x77\xa1\x71\xcc\x5c\xf7\x37\x6f\x87\xda\x47\x17\x27\x96\x8f\xa2\x69\x94\x84\x60\xa5\xa7\x7b\x58\x97\x8e\x96\x76\xcc\x57\xb2\xc0\x4f\xc3\x14\x85\x18\x73\x17\xbd\xd0\xf5\x52\xf2\x4c\xb1\x44\x06\x09\x40\x87\x58\xfd\x7c\xe9\x61\x78\x8a\x65\x2a\x1b\x49\xbc\x74\x8e\xf9\xb2\x2d\xa5\x98\x36\x98\x2e\xd7\xce\xe8\xb8\xaf\xea\xd7\xf5\x3f\xbb\x0d\xeb\x0a\xa8\xd3\x35\x45\x63\x15\x9d\xc3\xe6\xf1\xf3\x7e\x7e\xdc\x5a\x3b\x04\xa1\x3a\x17\xb5\x84\xc2\x9b\x9c\x57\xda\xf6\x93\xde\xe2\x8c\x04\xb5\x5c\x74\xc2\xfa\x78\x25\x16\x41\x2e\xfb\x3a\xe3\xe4\x81\xe2\x59\x86\xb1\xe1\xed\xeb\xfa\xb0\xb9\x7d\x39\xec\x37\xeb\xd7\xc3\xfd\xe6\x75\x17\xc0\x71\x4a\x30\x87\x5e\xc8\x1b\xcf\x3f\xd4\x1f\x48\xe2\x34\xf6\x7c\x2c\x87\x6e\x59\x39\xd4\xd0\x5c\xfa\x15\x47\x89\xce\x98\xf8\x3f\xff\xcf\xff\x79\xb8\xd9\x4e\xb6\x3f\x25\x0c\xa7\x51\x1f\x0d\xff\x0a\xaa\xc9\x5b\x18\xd8\xbb\x98\x8a\x99\x8d\x07\x80\xd4\xcd\x25\xc7\xda\x57\xe4\x07\xd7\x0b\x4a\xc8\x4c\xc5\x3a\x95\x01\xcb\x9f\xbb\x04\x17\xc0\x42\x70\x4c\xc5\x96\x62\xdc\x6d\x6c\x93\x84\x28\xf7\xdf\x0b\x5b\xab\x84\xd3\x80\x43\xeb\x3a\x04\x81\x00\x28\xd8\x3d\x97\x96\x63\x2a\xc9\x62\xdb\x9b\x5a\x9e\xdc\xba\x33\x51\x56\xa5\x83\xb0\x4f\x2f\x9c\xf2\xc8\x15\xb4\xc8\xd3\xc4\xde\x9d\x4e\xae\x2c\x96\xd8\xab\xe5\xe5\xf4\x62\x9d\x5c\x54\x3f\xbd\x24\x13\x58\x1e\xf5\xf5\x4d\x16\xd0\x1c\x8e\x75\x75\x39\xf7\xc7\xb4\xa3\xf8\x73\x7d\x1a\x72\x7f\x0b\x86\x8b\x92\x96\x40\xdc\x43\x6e\x3f\xe6\x2d\x67\x4a\x25\x0a\x6b\x8f\x5c\x04\xff\xd7\x8c\x0a\x4a\x49\xc8\x54\xef\x54\xfd\x5c\x94\x58\x61\x4a\x33\x47\x0a\xed\x79\x09\x3e\x55\x2d\x14\xfd\xfb\x69\xae\x8c\x1c\xe9\xbf\xed\x50\x5f\xe5\x43\x83\xe8\x2a\x55\xa6\x4c\x24\xd0\xbe\x68\xf2\xa2\x42\x48\x74\xb8\xb2\xe1\x40\x3d\xbe\x0f\xce\xb2\xee\xbe\xd0\x0e\x7a\x22\xd9\xd0\x48\x30\xec\x18\xd9\x6d\x65\xc1\xc8\xfd\xed\xb2\xa4\x95\xf5\xc1\xd8\x31\x19\xb8\x1a\x9f\x4b\x69\x50\x5b\x7f\x1c\xda\x54\x46\x29\x92\x85\xbc\x76\xd3\x56\xa7\x8f\x42\xf8\xca\x58\xa9\x3d\xc4\xa4\x4f\xcb\x2a\x60\x04\xdd\x4a\x5f\x66\x3d\x45\x94\x29\x2b\x1d\xca\x36\x6f\x42\xce\xbc\xde\xca\x26\x24\xd9\x5f\x41\xce\x59\x10\x99\xb2\xda\x69\xe3\x1d\xeb\xea\x47\xfb\x36\xc3\xfe\xeb\x88\x11\xcc\x02\x3b\xca\xc6\xf7\x91\xe2\xd4\xf4\xa5\x75\xc4\x13\xe4\xb5\x6c\x2e\xea\x94\xb7\x37\xb2\x28\xe6\x34\x5b\x61\x03\xd5\x24\x02\x47\x19\xd1\xb6\x52\x7f\x83\x7a\xfd\xf3\x3c\xc8\x7e\x84\x1b\x13\x66\xb0\x70\xc5\x8d\x64\xbf\xcb\x2e\x92\x73\x68\x12\x53\x5c\xcd\x0f\x47\x70\xb4\x4d\x18\xd2\x59\xb5\xff\x02\xb9\x5c\xa3\x32\x3c\x35\x01\x57\x5f\xff\x0a\x65\x2b\x47\x38\x21\x4d\x85\x72\x80\xa6\x8b\x6a\x97\x45\xfc\x98\xa6\x0a\x30\x80\xea\xd5\xcf\x07\x1b\xf9\xbe\xaa\x17\xd1\x4b\x9a\x51\x82\x0e\xef\xc1\x53\x90\xce\xe9\xb2\x98\x66\x19\xa5\x9e\xc7\xbe\xbe\x82\x9f\x69\x4e\x75\x88\xa0\x8d\xc2\x26\x24\x1c\xb5\x99\x08\x22\xc6\x63\x14\xfb\xf4\x1a\x82\x12\x42\x7a\x3e\xfe\x17\x3b\x81\x6e\x68\x91\x6a\xb4\xba\xf0\xe9\x9f\xab\xdb\x22\x1f\xe5\xea\x74\x1c\x27\x66\x22\xf4\xe1\x16\xaf\x9b\xea\x72\x7c\x6b\xc7\xb4\x34\xd3\x97\x8a\x53\x86\x1f\xfc\x0b\xd4\x7d\xd1\xb9\x4e\xa2\xcc\xf0\x09\xe0\x01\x33\xf8\xcb\x0f\x9d\x18\x85\x51\xf1\x22\x3f\xe5\xed\x8b\xbd\xa9\x65\xa9\x83\xa1\xa5\x53\xaa\xbc\x10\x53\xbb\xe9\x2c\xe6\x6f\x79\x79\x74\x03\x66\x60\xf7\x18\xb6\x11\x9d\x66\x32\x94\x1c\x06\x7d\xa7\xae\xb7\xa6\x63\x14\x65\xda\x70\x79\x44\x06\xa6\x79\x6e\x4a\xa7\x10\x47\x53\x74\xca\x1d\xa8\x99\x0d\xa2\x33\xe2\x48\xb5\x1a\x68\x75\x95\x97\xf6\xea\x6b\x87\x54\xe2\x11\xda\xbb\x4f\xb2\xdb\x2f\xca\x09\x49\x72\xd7\x22\x45\x92\x91\xaf\xb2\x85\xfa\x04\x45\x55\xe2\x08\x5f\x96\x64\x9f\xf6\x99\xe4\x4c\x3a\x60\x8f\x3c\x39\x10\x49\x88\xfd\x69\x4d\xa9\xa3\x66\x76\xcc\x47\x3d\xe3\xf1\x6c\xb8\x69\x2d\x1d\xb9\x53\xd7\xeb\xaa\x06\xf9\xed\xf0\xba\x7e\x5c\xaf\x76\xeb\xfe\x42\xa0\x42\x96\xd1\x95\xc8\x84\x49\xb0\x19\x98\x24\x99\x36\x82\x22\xc4\xe2\x94\x4b\x63\x7c\x2c\x62\x92\x23\xd2\x40\x04\x96\xd0\x14\x60\xdb\x38\x99\xf5\x12\xf0\x88\xa8\xb1\x86\xc5\x2b\x68\xcc\x41\xce\xa7\x07\xa8\x34\x14\x9b\xde\x56\x67\xe9\xc6\xc0\xd4\x75\xd3\x16\x9c\x52\xac\x4f\xb2\x37\x87\x4b\xd9\xe6\xc5\xe1\xbf\x93\x12\x4e\x13\x31\xe6\x50\x10\x45\x1e\xd4\x9c\x99\x89\x12\x86\xe8\xe2\x5d\x7e\xfc\x98\x27\x76\xba\x51\x8c\xb7\x5c\x43\x32\x97\xb3\x73\x3f\x36\x6b\x2c\xba\x5e\xd8\x9b\x0d\x91\x4e\xb7\xc2\x2e\xcf\x27\x43\x94\x83\x58\x23\xf6\xf0\xbe\xaa\x9f\xba\x99\x38\x51\x6f\xf1\x0d\x79\x04\x09\x59\xa6\x5d\xdf\x9c\xce\x57\x00\xdf\xc5\x4c\xd6\x70\x5b\xae\x34\x7a\x0f\xea\xf2\xee\xe1\xec\xd5\xcf\xf7\xe9\x27\x30\x5c\xc7\x68\x37\x1d\x02\x92\x18\xad\x94\xdb\x61\x7f\x35\x82\x69\xfc\xd4\x08\x6a\x9b\xc7\x7d\x97\x97\x69\x23\x78\x8c\xcc\x1f\x67\x0c\xc3\xbb\x52\xf7\x23\x24\xfd\x25\x45\x82\xd1\x8f\x60\x31\x38\x70\xc4\xcd\xfb\xb6\x73\x62\x70\xef\xfd\x80\x53\xff\xda\x78\x30\xc2\x53\x42\xe5\x8d\x2f\xb8\x30\xfb\xd5\x22\x9c\xc9\x88\xcc\xbd\x88\x97\xbb\x1e\x08\xb5\xb0\xa4\xca\xc2\x90\x97\x6a\xa0\x6e\x0f\x36\x2f\x4d\x37\x3b\x3e\xe5\x65\xfb\x0c\x3f\x7d\xed\xc8\xd0\x2d\x00\x8e\xfc\x4c\xeb\xad\x2b\xe7\xea\x8f\x58\x82\x17\x33\x9e\x28\xe0\xc5\x3a\x6c\xed\xa8\x9e\xd3\xc4\xc2\x15\xac\xe3\x0d\x19\x3f\x38\xea\xd3\x07\xd9\x7c\x6e\xba\x8e\x8a\x22\xe4\x21\x08\x93\xc0\x24\x4c\xa2\x02\xdf\xea\xe9\xe5\xf3\xf3\xfe\xeb\xea\x61\xfd\xba\xbe\xeb\x0f\xc6\x19\xe6\x5e\x3d\x23\x72\x20\xdd\xf8\xf5\x17\x4a\xd3\x18\x99\x5d\x4e\xf9\x10\x2f\x9b\xe5\x93\x2f\x57\xa5\x8e\x26\xd5\xa9\x0b\x27\xca\xbc\x7f\x95\x2c\xa2\x88\x1c\x70\x05\x7e\x07\x75\xa9\x67\x80\x46\xa3\x23\x82\x7b\xd4\xcd\xef\x37\x01\xfd\x62\x34\x44\x58\x25\xe1\x69\xf7\x2a\x64\x93\xdf\xd6\x81\x25\x75\x71\x9a\x69\xeb\x7b\x01\x37\x31\x5f\x88\xb3\x6c\x04\x1b\xa3\x62\xc4\xef\xdc\xbe\xbe\x7c\xbd\x73\xa4\xa0\xfb\xd5\x6b\x70\x9f\x8c\x31\x4c\x42\xd0\xcd\xf8\x06\x5b\xa8\x7b\xc6\x3f\x66\x0c\x68\x33\x2e\x9c\xdb\xdc\xbe\x4c\xc4\x83\x99\x01\xea\xf8\x3b\x4f\x2e\x96\xba\xbb\x60\x1c\xf4\xf3\xee\xee\xeb\x7a\xd3\xb7\x51\x36\x09\x56\x4e\x60\x20\xf2\xf2\x5c\x53\x17\x62\xba\x0d\x18\xb0\x8e\x24\x10\xfd\xf4\xdb\x5a\xaa\x7e\x14\x58\xea\xb8\x67\x7d\xda\x2c\x3f\x01\x2a\xde\x86\x32\x94\xe5\x8e\xb0\x4c\x18\x87\xd1\x56\x45\xae\xf7\x0f\xeb\x81\x2d\xb3\xbb\xc2\x18\xb7\x6f\x6c\x12\xa1\xf3\xdc\x0d\x8a\x55\x51\xfc\x36\xbe\x10\x44\x11\x43\xb4\xec\x6a\xb7\x6b\x3f\xc8\xef\x2f\x8b\xd3\x32\x88\x20\xc1\xcd\x17\x3d\x6d\xc7\x93\x53\xcf\x16\x22\x20\x86\x98\x3e\xbf\xeb\xa8\x24\xb1\xbe\xbb\xaa\x6f\x65\x69\x72\x33\xd2\x51\xbe\xe6\x85\x01\x62\x29\xb2\x90\xde\xad\xf6\x0b\xa8\x66\xa0\xb1\xc1\x3a\xbc\x53\x5e\x86\x80\xf2\x6f\xe1\x90\x96\x40\x3c\xc8\x51\x16\x63\x31\xf6\x0f\x1c\xa7\x2b\xd0\xfd\xf2\x3b\x53\x63\x3d\xc0\x73\x12\x8b\x9b\x4e\x0d\x60\x44\xe0\x56\xf9\xf4\xbe\xde\x6e\xc7\xee\x38\x30\x66\x9d\x98\x64\x30\xdd\x86\xfa\xac\x2c\x9c\xcd\x49\x96\x90\x20\xc5\xf4\x97\x34\x88\xff\x3f\xff\x86\x7b\xc5\x7d\x91\xed\x17\xe4\x41\xd9\x57\x2e\x6b\xef\x76\x95\xd0\x4a\x09\xe2\x75\xdd\x47\xa4\x73\x20\x22\x8d\xd4\x55\x8e\x09\x2a\x97\xed\x88\xfa\x9f\x81\x90\x0c\xd3\xe5\x3b\x68\x3f\x9f\x97\xa3\x57\x20\x4c\x8a\xdd\x11\xe8\x5e\x9b\x55\xdb\x9f\x0e\x34\x76\x30\x3e\x9d\xd7\xae\xaf\x1e\x25\xda\xea\xb3\x74\x19\xc4\x51\x84\x6b\xf6\x8b\x1b\x87\x6d\x5e\xc3\xa7\xca\xcc\x6a\xd5\x20\x61\x94\x05\x0e\xfa\xbc\x3c\xae\x7b\xf8\x02\x24\x82\x46\x71\xe0\xce\x40\x6f\xcd\xce\xcf\x95\x0e\xb4\xef\x80\xd2\xd0\x34\x55\xbd\x9c\x2a\x85\xc4\xb8\xd4\xde\x6e\xbf\x7e\x7d\xde\x7c\x7e\xfa\xf4\xf9\x61\xbd\x7e\x7c\xdc\x3c\xac\x9f\x6f\xd7\x83\x44\x2f\x83\x94\x38\xd0\x7e\xcf\x2a\x89\x60\x7f\xf4\x5e\x7a\x5d\xd0\x7e\x3a\xcc\x6e\x92\x32\x67\xf5\xea\xbe\xca\x04\x02\xa5\xd5\x6d\x75\x3a\x17\xd0\x23\x0d\xf1\xc4\xbe\xcc\x0d\x52\x10\x86\x0e\xfa\xe9\x54\xf6\x4f\x03\x89\x23\xf6\x86\x9f\xa0\x3f\x5d\x54\xff\xbb\x35\x68\xa1\xee\x7f\x3a\xe0\xae\xdf\x80\x82\x5d\x0c\xda\x2a\xcc\x54\xa2\x86\xec\xe5\xbd\xdf\x2d\xc1\x44\x29\x9f\x8c\xf3\xd7\x89\xfc\xe0\xec\x85\x8c\xb0\x81\x2d\x74\xa2\x40\xe0\x69\x9d\xc7\x58\x8c\x65\x2b\x1b\x80\x2b\x24\x9d\x39\xcb\xf7\xf9\x4c\xbf\x5e\x57\x6c\x14\x3b\x15\x05\x4f\x5b\xec\xd2\xb8\xd3\x54\x65\x68\x99\x64\x91\xee\x69\x0a\x77\x55\x81\xc6\xc3\x48\x6f\xbf\x6b\x62\x31\x56\xff\xa2\xfe\x0b\xbd\xc7\x6e\x23\xd0\x64\x9a\x21\xf9\x56\xc8\xdf\x16\xa2\x82\x96\x46\x26\x89\xfd\xc0\xbc\xcb\x8f\x79\x2b\x7d\xf2\x32\x5c\x8a\x32\x57\x6c\x03\xdd\xd0\xc0\xf0\xd9\x93\xcc\x47\xf2\x72\xcc\x52\x01\x38\x8d\x9e\xf3\xf2\xbf\x72\xd1\x29\x09\x0d\xb3\x24\x4e\x3d\xd6\xac\x6c\xaa\xc2\xac\x7a\x38\xb2\x83\x32\x4c\xdc\x2f\xcb\x19\x41\x40\xf3\x0e\xda\xdd\x45\x35\xba\xce\xcf\x5d\xd3\x51\x18\x68\xfc\x19\x2d\xe7\x8e\x43\xa0\xa7\xc7\x19\xe9\x01\xcc\xfa\x95\xc7\x4e\x89\x68\x77\xae\xca\x9b\x5f\x84\xbd\x2c\x4f\x2c\x5a\xbb\x0e\x1b\x74\x07\x05\x1c\x65\xdb\xd3\x0a\xcd\xaf\xaa\x38\x06\x51\xce\xf9\x4f\x28\x9a\x2d\xd4\xb7\x83\x71\x66\xb9\x4e\x90\x82\x65\xf3\xfc\x65\xbd\xdb\xbf\xbc\x1e\x1e\x5f\x6e\x7f\x3f\xdc\x7d\x7e\x1d\x33\x12\x5a\x0e\x19\xaa\xee\x9e\x26\x34\xf0\x0f\x55\x9f\x72\xb3\x82\x0a\x04\x31\x68\x79\xee\xbe\xd5\x23\x98\x01\xe8\x6c\x45\xec\xa4\x50\x1c\x6e\xfb\x29\x2f\x5d\xf5\xfc\x95\x96\x23\xb3\x02\x2c\xa6\xab\xbb\x6f\xf9\xdb\x98\xea\xc2\x1f\x8f\x05\xb5\xc1\x96\x81\x9f\xd3\xea\x67\x1b\x03\x60\x8c\x01\x1d\xa3\x29\x8f\x75\x78\x92\x84\x09\x2c\x28\x39\x61\x21\xdc\xfb\xca\x93\xd5\xd7\xb2\xd8\x76\xce\xdb\xaf\x49\x41\x6d\xc6\x25\x0f\x42\xde\xb9\x87\x04\x6c\xe6\x14\x0d\x36\xd3\x16\x87\xae\xd7\x26\xb8\xb9\x94\xa6\xe8\xbc\xfe\x6e\xb3\x6f\xaf\x6b\x60\xac\x8c\x32\x5f\xfb\xdd\x8e\x58\x18\x97\x68\x0e\xac\xd4\x14\x0b\x92\x7e\x42\x00\x6f\x5b\x09\x06\x43\x82\x7a\x28\xd2\xb4\x8a\x3a\x02\xcc\x75\xe9\x6b\xb7\xfd\xef\x5a\x48\x0c\xb5\xfb\x7d\xba\xf3\xce\xde\x77\x50\xcc\x16\x76\xab\x63\x19\xea\xd8\xf0\x74\x0c\x2b\x4f\xe7\x80\x96\x56\x84\xe0\x80\xbb\xd8\xb5\x62\x1f\xb3\x46\x2b\x2c\xef\x34\x21\x11\x7a\xb8\xad\xf2\xf2\x70\xfb\x26\x6b\xa9\xdb\x9e\x3c\x2c\xb4\x36\x4e\x52\x7b\x9f\x17\xf0\x73\x92\xad\xb3\x36\x8b\x11\xf9\x7b\x1e\x04\x3a\x67\x0d\x8c\x93\x37\x3c\xca\x93\xab\x14\x99\x53\xab\x58\x6b\x13\x64\xf0\x36\xd5\x4d\x58\x44\x78\x14\x11\xcb\x7d\xfd\xe9\x2e\xaf\x3f\x54\xd6\x0c\xad\xb9\x53\x7b\x46\xb3\xed\x34\xca\xcb\x5c\x2d\xa6\x3c\x8a\x12\x8d\xd2\xa6\x25\xfc\x6c\x47\xf4\x5d\x3c\x8a\x0c\x81\xbe\xd4\x6d\x5e\x7d\xc4\x23\x42\x05\x16\x9a\xe4\x4d\x58\xce\x06\x38\x0f\x8f\xa8\x30\x18\x75\x75\xe0\xdc\x1e\xd0\xc3\x23\xd4\x67\x76\x2f\x22\x17\x9f\x9d\x6a\x86\xab\xd0\xf3\xfa\xeb\xee\xe5\xf7\xcf\xc3\xa6\xcb\x23\x6a\x23\x47\x21\xe9\xaa\x13\x56\x18\xf9\x74\x95\xa2\x5e\xa8\xcd\x7f\xf6\xae\x69\x1a\x39\xb8\x43\x01\xba\xdd\xc3\xe9\x5c\xc8\x09\xbd\x37\x8f\x58\xc4\xd1\xca\xdb\xc2\x51\x36\x97\x71\xda\x85\x47\x2c\xb6\x58\x0f\xf5\x45\x55\xa1\xfa\x80\x47\x2c\x75\xd4\x07\x87\xbc\xf1\x65\xf0\x93\xe1\xc8\x23\x4e\x23\xe9\xba\xe4\x55\xb6\x0e\x3f\x3f\x6b\x21\x12\x81\xda\x05\x8f\xd5\x71\xa8\x65\xf7\x38\xcb\x85\x68\x07\x8f\xe2\x88\x6b\x1d\xd0\x7e\x08\x33\x71\xdf\x68\x7a\xd9\x98\xb8\xe2\xdf\x06\xb9\x56\x9e\x66\xfc\x86\x3c\x8a\x33\x85\x80\xde\xa7\x3f\x9e\xb6\x77\x4f\x93\x37\x8d\x55\x86\xb1\xa7\x61\xf6\xf1\x28\x36\x0c\xcb\xd6\x8b\xea\x07\x34\x6d\x60\x4f\xaa\x2e\xed\x3f\x2f\x55\x7d\xe9\xfb\x23\xe1\x04\x93\xa9\x26\x64\xb4\xb1\xae\xae\x99\x0d\x68\x1e\x25\xc2\x29\x44\xf6\x12\x28\x28\x75\xb1\x75\xec\x00\x33\xde\x20\x7f\x4a\x1a\x39\xd6\x99\x07\x59\x1e\x4b\x79\x9a\x3c\x71\x4a\xdc\xca\x28\x8d\x59\x9f\xf3\xa6\xea\xc5\x05\xff\x67\xfa\xd2\x29\x01\xe6\xa4\x35\xda\x35\x0a\x8e\xce\xe3\xc4\x3c\x4a\xa9\x2b\xb4\xb6\x79\x69\xbc\x1e\x0c\x26\x4e\xa7\xad\x32\x95\x86\x50\xa7\x1b\x6c\xcb\xa5\x59\x3c\x92\x71\x8a\xf1\xd5\xce\xb9\x0c\x10\xbb\x70\x28\x91\x3a\x1e\xa9\x11\xef\x74\x55\xc3\x6f\xb3\xa9\x28\x0d\x45\x58\x78\x73\xce\xdb\x72\x4c\x00\xce\x23\x09\xe0\xa0\xca\xd1\xcf\xbb\xea\x08\xba\xca\xcb\x49\xa7\x28\x92\xa0\x11\x7c\x92\x3f\x3f\x3d\x6e\x9f\xf6\x9d\x09\x12\x12\x5a\x3c\x52\x54\x1b\x33\x36\xe7\x9e\xde\x9d\x41\x77\xe7\x09\xbf\x97\x2d\x3b\x1e\x29\xce\x11\xc4\x0b\xce\x7c\xdc\x9d\x01\xf7\x53\x8f\x8b\x69\xc2\xf5\xb5\x16\x31\xf5\xcc\x91\x53\x58\xd9\x6d\x55\xd7\xa0\xaf\x6b\x04\x26\x96\xd4\xcc\x6d\x0b\x13\x54\x9b\x04\x27\x4b\xde\x34\x17\x58\x8e\xd5\xfe\xca\x3b\xe2\x91\x61\xe0\xb4\x4b\x9d\xf4\xbf\x2b\x9c\x5d\x4c\x7f\xf0\xc8\xc8\x58\x25\x81\x62\x08\x0f\xdc\xe7\x50\x04\xa0\x27\x8f\x8c\x06\x8d\x70\x9b\x6e\x8c\x53\x36\x1b\x22\x36\xe6\xb8\x23\x3c\x54\xef\x72\xfa\x61\x6c\x62\x83\xd2\xe4\x31\xf8\xb7\x9c\x44\xd4\x27\x84\x5c\x59\x99\x43\x59\x4e\x1e\x88\x44\xb1\xc2\xf5\xf5\x1f\x97\xa6\xcd\xed\x3b\x06\x56\xe6\x4d\x12\x47\x83\xa7\x3c\x2b\x80\xef\x38\x42\x88\xdb\xfd\xf3\x06\xd7\x20\x3f\xe1\x26\x1b\x23\x27\x44\x30\x8c\x06\xe2\x1e\x31\xe6\x9b\x19\xef\x11\xb3\x1a\x10\x4e\x48\xac\xf1\x96\x3b\x0c\x9f\xe4\x95\xd9\xd6\xb0\xd9\xbf\x1c\x9a\x1e\xcf\x39\xe9\x18\x42\x12\x4a\x3d\x08\xe4\xb9\x6a\xe1\x77\x78\x5f\xc2\x0a\x73\x42\x4c\x82\xc9\xe6\x22\xd7\x50\x36\xb0\xe9\x3e\xf9\x35\x44\x8d\x13\xca\x1d\xc3\x4f\x5f\x39\xb7\x83\xb6\x85\xa9\x90\x0d\x27\x34\xb1\xc4\x6b\xaa\xa0\x5d\x7c\x9f\x17\xc5\x61\xd1\xe5\xe3\x84\xa6\xcc\x7a\x77\xfd\x19\x7e\x38\x63\x66\x99\x4c\x83\x13\x46\x62\xe2\xdb\xde\xbe\xe5\x2a\xbf\xaf\xea\xfb\x4b\xf3\x11\xda\x97\x13\xc6\x64\x12\x76\x6d\x59\xc0\x35\x03\x26\x27\x2c\xcb\x30\x93\x6d\xf2\x6e\x9e\x54\xf5\x4d\x78\x07\xce\x1c\xc5\x00\x12\xb7\xec\xce\xa0\x73\xa4\x6b\xde\xcb\x6f\xd0\xbf\x27\x97\x02\x67\xbd\xed\x1c\xa1\x63\x3e\x1e\x78\x84\x83\x45\xb5\x62\x17\x97\xda\x94\xdf\xab\x39\xac\x94\x93\x98\x02\x0e\xce\x4d\x75\x79\xad\xaa\xb6\x19\x09\x16\x7f\x54\x2d\x12\xc6\x58\xcc\x1c\x32\x64\x5c\x28\xf7\x81\xd4\x63\x38\x23\x71\x59\xd5\xca\x43\xb1\x0e\x7f\x22\x14\x6b\x72\x8b\x7e\x9c\x25\xdc\xa2\x95\xde\xf9\x5f\x77\x73\x21\x35\x4e\x92\xc4\x28\x6f\x89\x3e\x86\x44\x4e\xb3\x7c\xdb\x24\x4b\x71\x09\x2b\xaa\x63\xd5\xcc\x2f\xa3\x32\x1e\x07\x31\xe1\x97\xa1\x1c\x81\x93\x44\xa7\x58\xd5\xf9\x54\xd5\x3d\xc7\x2e\x27\x69\x26\x11\x70\x53\x5d\xda\xa6\x95\xb8\x14\x8e\x62\x26\x9c\x64\x34\xb6\x83\x12\x42\xc8\x5e\x8e\x37\x74\x92\x31\x8e\xf6\x4f\x30\x9a\xd6\xb3\xe8\x13\x27\x59\x4c\x94\x1e\x29\xb8\xcc\x1f\x3a\xd3\x0c\x8d\xbb\x63\x2d\x4b\x73\xb0\x63\xaa\x45\x4e\x64\x6a\x10\x74\xe5\x31\x39\xfd\xfb\x28\x93\x51\xd9\xd7\x17\x17\x55\x7b\x55\x20\xc1\x91\x20\x38\xc6\xac\x69\x5d\x4d\x86\x92\xf6\xb5\x47\x3a\xc8\xf5\x2e\x86\x83\x38\xd1\x19\x47\x5c\x56\xe1\x70\x25\x43\xb9\x1f\x27\x5a\x52\xed\xd8\x55\x9c\x94\xcb\x46\x57\x33\x75\x51\xde\x2d\x01\x49\x67\x90\x05\x70\x39\x27\x46\x41\x1c\x4f\xc8\x47\x6e\xf6\xb7\x37\xf3\xbb\xf7\x83\x06\xa8\x63\xe9\xec\x76\x7c\x83\x29\x8b\x27\xf9\xb3\xeb\xe4\x19\xf2\x20\x34\x37\x12\xf3\xc0\x9d\x8b\xd5\x75\xe3\xe5\x63\xa5\x1e\x7f\x86\xa5\x04\x49\x25\x9b\x52\x9e\x9b\x37\x14\x49\xfd\x06\xb3\x52\xc3\x0f\xce\x8c\x53\x74\x17\x7d\xf8\xca\xab\x94\x39\xe6\x83\x4d\xf9\xb9\xe9\x77\x06\x6b\x98\xb6\x7e\xcf\x2a\xa1\x78\x45\x98\x50\xb7\x10\x56\x97\x49\x2d\x2b\xa7\x11\x77\x99\x93\x7f\xfe\xfb\x21\x8a\xc8\x48\xe6\x8a\xd3\x28\x71\x3a\x83\x79\x73\x73\x79\x7f\x9c\x14\x4a\xf9\x16\x84\xa4\x11\xf3\x85\xd8\x97\xf7\x11\x91\x34\xa7\x24\xb3\x88\x37\x6e\xfe\x9c\xde\x8f\x68\x82\xe1\xc2\xef\x55\x0b\x07\x5b\xd5\x07\x1d\x42\xc0\x87\x5b\xfc\xff\xa1\x6e\x9a\x53\x2a\x14\x26\x11\x1d\x03\x02\xa6\x5c\xc2\x56\x4a\x19\x21\x98\xdd\xb2\xc5\xe5\xe7\x3d\x8c\x6c\x8f\xa9\x7e\x2f\xa7\x4c\x64\x88\x09\xb2\x79\x28\xd5\xe8\x95\x29\x67\x1a\x95\x9c\xb2\x98\x3b\x85\x93\xca\xd7\x7c\xf9\xc4\xd3\xee\x47\xde\xea\x37\x6f\xb0\xcc\xcb\x36\xc3\xb9\x9a\x07\x6a\x8c\x9b\x8b\x39\x42\xfb\x62\x03\x9e\x6e\x79\xd3\xa0\x5c\x93\x94\xfa\xc4\x76\x6d\x66\x0a\xac\xbe\x8d\x60\x4e\x4a\x50\x43\xdd\x6d\xe0\xb3\x0f\x20\x0c\xb5\x72\x52\xf0\x3f\x9e\x72\x34\x66\x16\x03\x57\x77\xd2\xe4\xba\xef\xd5\x84\x47\x98\x76\x7d\xde\x3c\x63\x34\x72\xf2\xd1\x93\x38\x93\xd2\x13\x18\x41\xe3\xd1\xd2\x8b\x40\xad\x34\x9c\x91\x45\x69\x1c\x9c\x0b\xb4\xe2\x2f\xb2\xb8\xed\x47\x73\xdf\x3f\x89\x25\x18\x76\x2a\xaa\x23\xbd\xa9\xae\xb8\x1e\x39\x4d\x3d\xef\x32\xd6\xdf\x9a\xf7\xdb\xaa\xa8\x6a\xb7\x30\xce\xda\x25\x63\xe5\xf3\x6d\x9d\xff\xaf\x63\x6e\x0b\xaf\x90\x49\x16\xfb\xd4\xf3\x8b\xe7\xa9\xbf\x07\xf8\x8a\x25\x23\x37\xef\x2e\xac\xb6\x04\x5d\xe7\x34\x03\xc7\x3e\x82\x25\x98\xfe\x37\xc5\x04\x56\xac\x61\x3c\x23\x94\x5e\x8d\x78\xb0\xaf\x9d\x61\xaa\x34\xc5\x0c\x94\xc3\xda\x0f\x38\x3b\x4e\x0d\x65\x68\x78\x68\x59\x06\xc9\xa5\x59\xc2\x68\xfa\x40\x46\x67\x22\x94\xe2\x2d\x14\x63\x70\x0a\x91\x93\x74\x7b\xac\x8e\x41\x82\xf1\x97\x75\x16\x9c\x02\x61\xcc\x86\x78\xbd\x1f\x34\x77\xd5\x8f\x7e\xcc\x40\x0a\x54\x04\x35\x91\x53\xbe\x4c\x1b\xcc\x29\x64\x52\x79\x00\xe0\xbe\x96\x06\x7e\x1b\xcd\x38\xc8\x14\x92\xa5\xfc\x00\x79\xee\x6c\x80\x6b\x19\x2f\x4e\x2d\xf3\x34\x09\x97\xd2\xdc\xc9\x2a\xdc\xdd\x0a\x17\xe6\x6c\xb0\x2e\x63\x24\x30\x39\x1d\xf8\x2c\x4a\x05\xea\xdd\xf9\x1c\xa3\x2c\xbf\x39\x76\xf7\xc5\x77\x66\x51\x96\x21\x4c\x4f\xe5\xe6\x23\xbe\xf4\xd9\x19\x44\x39\xcc\xe1\x11\x46\xe1\x20\x7f\x8c\x12\x82\x61\x9e\x12\x7e\xdc\xc9\x0a\x35\xc4\xfb\x6a\x95\xbf\x9b\x80\xc1\x45\x6a\x7a\x4b\x2a\xb8\x93\x4b\x0f\xee\x95\x27\x4d\x1f\x11\x09\xcf\xcf\x88\x29\xf1\x0f\xb9\x05\xf9\x6d\x1c\x22\xe2\x8c\x51\x8d\x6e\xe0\x0e\xb1\x5a\x36\xaf\x4f\x08\x33\x1e\xe7\x04\xd2\xd1\x32\xc9\x44\xe4\x10\x05\x7d\xd0\xb2\xdb\x5a\x90\x5b\x78\x5b\x57\x6d\xa5\xab\xe2\xca\xf3\x65\x42\xb8\xe0\x4e\x9b\x9f\x60\xfd\xb3\x85\x72\xe4\xac\x32\x91\x46\x08\xd1\xd8\x3e\xdc\xad\xfa\xdf\x32\x8e\x5b\xf1\xf3\xcd\xfe\x4b\xff\x1b\xb0\xcc\x73\xcb\x0d\x81\xe8\x5f\xad\x38\x2c\x26\x16\xf3\x9e\x4d\x5e\x1e\x8b\x5e\xc6\xf0\x29\xef\x6f\x1d\x33\x08\x85\xdb\xd3\x6a\xc1\x30\x45\x59\x9c\xb8\x9a\x6c\x97\x1a\x44\xb7\xca\x57\xe4\x4e\xdf\x30\xb6\x0a\xdd\xff\x43\xde\xb8\xd4\xd8\xa2\x79\xc8\x12\xa2\xd1\xd0\x6c\xaa\x13\x3c\x41\xfb\x56\x19\xf1\xcb\x24\x3d\x67\x09\x4b\x49\xcf\x21\x52\x05\x15\x2b\xce\x12\x9b\x49\xff\xd9\x0e\xef\xd5\xa5\x3e\x1c\xe5\x09\x0e\xa5\x5b\x86\x31\x91\x13\xae\x20\x89\x23\x4d\x3d\xe7\xc5\x5c\xc0\x8f\x33\xa5\x1c\x72\x12\x13\x6a\xaf\x55\x51\xdc\x05\xbb\x3d\xac\xc7\x4c\x8b\x18\x6d\x04\x93\x37\x4e\xe3\x2d\xfc\x1e\x1b\x4c\xdf\x3b\x22\xf0\x1e\x11\xb6\xbc\x42\x31\x9d\x48\x5c\x4e\x5e\xb6\xab\x7f\x85\x2b\x80\x10\x58\xa5\x07\xb5\xec\x7f\x8a\x69\x94\x8d\x74\xfd\xb7\xb2\x6e\x9b\xdb\x2b\x76\x85\xfe\xe5\x6c\x9c\xea\x6c\x90\x8e\x3b\x61\xca\x21\x30\x6f\x87\x36\x99\x71\xd9\x15\x80\x6f\xdc\x61\xf0\xc2\x11\xc5\x63\x13\x78\xf6\x3c\x37\xb1\x9b\x4d\x0b\x61\x66\xce\xac\x56\x0a\xfa\x30\xe3\x4d\x55\x61\x9d\xde\x34\x1c\x34\x92\x30\xe9\xa3\x0d\xfd\xe4\xe1\x11\x07\xe4\x43\xa9\x51\x7e\x60\xb0\x98\x79\x24\x28\x26\x65\x6e\xb9\xee\x11\x8d\x9c\x47\xd6\x91\xdb\x6d\x5f\xd7\x07\x04\x30\x6c\xd7\xaf\xb7\xeb\xe7\x7d\x38\x4e\x58\xec\xab\x9f\xd0\x23\x9e\xdb\xb8\x9c\xb0\x14\xab\x62\x1c\x60\xf8\xa1\xa8\x14\x16\x7d\x35\x6d\x2d\xf3\xb2\xdd\x8e\x2c\xd0\xa5\xb5\x9b\x13\xe9\x10\x5e\x75\xc8\x31\x86\xdf\x35\x75\xfa\xf5\x6f\xd5\x8f\xcf\xe5\x59\xe6\x66\x53\xb6\x50\xcf\x4b\x92\x39\xa7\x8c\xa1\x6c\xcd\x03\x86\x9f\x4b\x9b\x1f\xc3\x25\x68\x9c\xc0\x50\xfc\xb5\x03\x7d\xc1\xe2\xa3\x5f\x6e\x49\x9c\x2a\x81\x50\xcc\x7f\xef\x77\x7d\x17\x30\x6a\x31\xf3\x7b\x85\x15\xff\xf5\xa5\x18\xe7\x2a\x84\xeb\x66\x42\xe8\x9c\x77\xdb\x0b\x62\x1f\xd7\xaf\xbb\xcd\xcb\xf3\xe1\x79\xf5\xb4\x0e\xf7\xe3\x09\xa0\x53\x8e\x71\xea\xee\xbd\x1a\x94\xa2\xb8\xaf\xea\xdd\x39\x2f\xcb\x1e\x85\xcf\x39\xcf\x74\xe6\xc3\x7d\x79\xf3\x86\x8b\x6a\x70\xb7\xb9\xc8\x58\x94\x05\x34\xd8\x41\x77\x9f\x44\x96\x2d\xed\x0f\xeb\x18\xe1\xd4\xa1\x8e\x66\xdb\x19\x7c\x0b\x98\xa8\xff\x24\x83\x51\x91\xba\x7f\x32\xfa\x1f\xfa\x7f\x47\xb5\x39\xe3\x40\x27\x17\xd6\xc5\x3d\xde\xe0\x67\xd3\xd6\xfb\x0a\xd9\x56\x26\x1e\x23\x8f\xa9\xc2\xed\x00\xa1\x4f\x6f\xb9\x7e\xbb\xdd\xdf\xcd\xbe\x6a\x9c\x3a\x4a\xb6\x12\x7e\xb6\x37\xb9\x71\xd1\x69\x44\x93\x8c\xc5\xb3\x39\x4f\x38\x23\xa1\x60\xe4\xf6\xd3\x52\x39\x2d\xe7\xa9\x72\xa8\xf2\x36\x30\x39\x4c\x63\x2b\x3c\x4b\x5c\x79\x8d\x2c\xcb\x4b\x71\x8b\xb6\x6d\x3e\x31\x5e\xa6\x8f\x96\x69\xe6\xe2\xcb\x39\xfc\x38\x1c\xa1\xc5\x55\x11\x63\xd8\xc3\x15\x75\x6c\x7c\x88\x6c\x81\xd1\x61\x36\x4c\x24\x75\x95\xb0\x47\x54\x3a\x5e\xc6\xec\xcc\x4f\x61\xd4\xb9\xaf\x68\x50\x76\x9b\x4e\x30\xd8\xff\xea\x3c\x8e\x74\xbc\x79\xf9\x84\xdc\x4b\xe5\x68\x09\xe3\x32\x4d\xe5\x50\x77\xe1\x10\x95\x03\xe9\xb4\xdf\xa6\xaf\xfe\x4c\xae\xaf\xa8\x4c\xc7\xca\x81\x0b\x75\x01\xa1\x25\x24\xa0\x82\xe5\x17\xca\x20\x6f\x07\x2c\x1a\xe7\x3a\x01\xc4\x80\x21\xfb\x3b\x7a\x05\x97\xbf\xc0\x8d\x71\xae\x95\x41\xe4\xd2\x73\xa5\x26\xce\x07\xb7\xd4\xa2\xe6\xb6\x83\x8d\x85\x1f\x65\x6c\xfc\x66\x7f\x0d\xe6\xe1\x22\x8a\x22\xa4\x25\x73\xba\x1b\x61\xde\x08\x2a\x14\x5a\xf4\x1e\x06\x37\x24\x82\xba\x23\xda\xa9\x0a\x6f\xf6\x9b\xd5\xe3\xe1\x66\xf5\xb8\x7a\xbe\x5d\xf7\x87\x63\x8b\xd2\x50\x37\x97\xf7\x8f\x6a\x73\x26\x7d\x24\x18\x97\x68\xb4\x3c\x56\x47\x3f\x2a\x31\x2c\x38\xf7\x7c\x05\xe3\x0a\x99\x85\x14\x86\x41\xd6\xa5\xae\xdf\x71\x8b\xda\x5e\xd4\x37\x08\x36\x98\x60\x71\x42\x4c\x6f\x53\xf5\x7c\x83\x4b\x26\x84\x60\xca\x22\x08\xe7\x7b\xde\xad\x09\x23\x22\x97\x70\xdc\xb8\x94\x17\xce\xfb\x98\xef\xab\x1d\xbe\xcf\x22\xae\x9f\x0b\xc1\x52\xc4\x6c\x9c\x3b\x17\x83\xcc\x55\x94\xb9\x88\x13\x22\x17\x44\x44\x17\x3d\x5b\x11\x27\x2a\xf5\xd8\xe9\x1d\x14\x76\xd5\xf4\xc5\x3c\xd5\x24\xa7\xc9\x45\x9c\x25\xdc\x47\xd4\x9e\xe5\x09\x5c\x91\xc3\xc6\x5c\x11\x1d\xcd\xae\x9f\x25\x81\x7e\xec\x19\x7e\x2c\xab\xdb\x70\x91\x50\x63\x6d\x58\x3c\x4f\x50\xb6\x9f\xcb\xfc\xcf\x0b\x94\xd0\x34\x23\x84\x33\x17\x49\x2c\x31\xe4\xfd\x0c\x3f\x76\xd5\xf9\x6d\x89\xdb\x9a\x8b\x24\xd1\x48\xa0\xef\x29\x85\x1e\xe1\x3b\x14\xf3\x2f\x92\x7a\x8d\xbb\x23\x04\x3a\x86\x29\xe3\xd8\xac\xb5\x75\xdf\xef\xcb\xeb\xfa\xc5\x6f\xea\x9f\x56\xbb\xf5\x81\x1c\xd6\xcf\x77\x28\x64\x17\x1e\x30\xe3\x22\x91\x43\xc5\x77\xfe\xbf\x7f\x29\xed\x3c\xbb\x55\xa6\x01\x23\x1a\x2a\x70\xf8\x3f\xe5\x65\x3f\x23\x32\xd0\x98\x62\x28\x64\xd3\xba\xc0\x42\x3e\xee\x1d\x19\x49\xe3\x83\xc9\x9d\x63\xf3\x98\x7b\x94\xfb\x3c\x67\x28\x64\x62\x71\x9b\x6b\x2a\x9d\x0f\x82\x54\xe1\xa0\x25\x5c\xf4\xb8\x7d\x5c\x43\x1e\x31\xcd\x37\x36\xc3\x84\xa2\x52\x39\xda\x65\x3d\x09\x05\x0a\x25\x53\xee\x8a\x7f\xe4\xfb\xea\x87\xac\xcd\x82\x87\x28\x74\xc4\xb0\x7e\x2a\x98\xa0\x9d\x23\xe4\xf5\x33\x36\xe5\x77\x28\x31\x60\xf9\x41\x26\x28\x5c\x42\x46\xf8\x4d\x3e\x97\x43\x7c\xf7\xea\x94\xc9\x5b\x6b\xc5\x31\xa5\xd2\x99\x40\xe3\x6d\x29\x1c\xb6\x91\x76\xe2\x51\x7e\x0c\x06\x4c\xc4\x64\x87\x14\x26\xa5\xc6\xa7\xa7\x7f\xcf\xcb\xa3\xa9\x4e\x5e\xcb\xe6\x75\x1b\x9a\x00\xc9\xb8\x07\x70\xff\x36\x66\x98\x08\x87\x63\x47\xbf\xbb\x6b\x01\x4e\x79\x3b\x10\xed\x70\x01\x29\xc1\x44\xe2\xcd\xea\xf1\xcb\xe6\xb9\x67\x3d\xee\x0e\x58\xe4\x90\xfa\xf4\xe5\xa6\xff\x49\x71\x14\x2c\xfa\x74\x91\xfb\xcb\xf4\x1b\x00\x44\xf8\x0d\x7c\x32\xee\x1e\x60\x54\x35\xd3\xaf\x3a\x96\x11\x4c\x02\xd5\x83\x22\x03\xe9\x8f\xa5\xbd\x02\x08\xd2\x0a\xce\xcb\x30\xb9\xb0\x32\xcd\xc6\x5a\xdd\x8f\x79\xd3\xf6\x1a\x6b\xb3\xa6\x26\x4d\x64\x40\xed\xb6\xb2\xf8\x24\x9b\xb7\x57\xd9\xce\x35\x63\xb8\xb0\x36\xd3\x8e\x67\xa8\x3e\xe5\x65\xe7\x3d\xbd\x55\x75\xdb\x5b\x52\xae\x55\x1c\x45\x8e\xaf\xec\x58\xe7\x1f\x04\x05\xe2\x28\x26\x91\x93\x90\x38\x93\xe9\x3d\xe2\x28\xb1\xee\x33\x3b\x8e\x00\x8c\x6d\xfc\xcf\xac\x49\x46\xec\x20\x5a\xda\x8d\xcd\xc1\x79\x7d\xcc\xe7\x16\x73\x1c\x29\x11\x79\x8f\xf4\x2b\x96\xf2\x37\x73\x97\x34\x8e\x20\xc6\x60\x6a\x79\x39\xdd\xc9\xfa\x5b\x59\x99\xde\xb8\x89\x09\xe5\x18\x4d\xc5\xad\xfb\xae\x8f\x63\x07\x94\x3b\x8f\x89\x10\x6a\xd0\x85\xf9\xdc\x40\x7d\xf3\xbe\x3e\xc9\xbc\x40\x01\x8f\x6b\x56\xe9\x69\x57\x90\x4c\x27\x76\xaa\xc1\xb5\x1a\x13\x5c\x2c\x84\x2b\x62\x9a\xa4\x08\x87\x7c\x78\xf9\xb2\x7e\x7d\x1e\x6d\xba\x31\x63\x11\xfa\xcc\x5f\x64\x99\xb7\xae\x3c\xe1\xf0\x9d\x85\xa3\x3c\x65\x36\x0b\x29\x1f\x7c\x58\xb7\xd1\x7d\x2c\x24\xc1\x63\xae\x1c\xbd\xe8\x0f\xf4\xde\xee\xa5\x06\x55\x55\xdf\xfa\x2b\x5a\x81\xe4\x31\xdf\xab\xb6\x6a\x70\xf0\x0c\x1d\x27\x98\xc5\xf0\xe9\xee\xd3\x66\xfb\x6b\x8f\x3c\x16\x71\x86\xb5\xcc\x5b\xd0\x97\x22\xbf\x4c\xe0\x02\xb1\x90\x12\x83\x14\x8e\xae\xf8\x38\x2d\xcd\xe3\x71\x9c\x50\xa4\x0f\x6f\x2e\x0a\xfb\x5e\xb6\x6d\x01\x2e\x76\x79\xb5\x42\xf5\x5e\x63\x9c\x44\xa9\xe8\xe9\x7e\x19\x9b\x55\x0a\xd0\x69\xa5\x00\x8f\x13\x66\x18\x09\x5e\x2d\x26\x40\x16\x2d\x89\x38\xe1\x91\x53\x29\xbb\x14\xdf\x56\xc6\x3c\xc9\x6f\x8b\xf0\xea\x79\xd8\x32\x4e\x32\xd7\x01\x0f\xdd\x9e\x3a\x46\x1f\xf2\x38\xf5\x10\xa9\xf3\xa5\x6c\xc7\xc2\xe8\x9d\xcf\xe0\xa6\xe3\xa3\x6c\xf3\x1e\xd4\x11\xa7\x56\x23\x25\xa0\xd7\x84\x78\x93\x35\x74\xfe\x04\x94\x8e\x66\x4a\x2f\xac\x00\x71\x16\x11\xe3\xad\x8c\x7b\x99\x17\x7d\x9a\x3b\xce\x22\x85\x9c\xfa\x23\x54\x28\xa2\xf2\xc1\x80\xd9\xdc\xae\xb6\x57\x85\x2b\x53\x4b\x2f\x5c\x25\x71\x4c\x12\xc8\xa3\xf0\x49\x16\xdf\xf3\xf2\xd8\xec\x2e\xaa\xc9\xcd\x9c\x7c\x87\xc7\x59\x9a\x62\xce\x7f\xd8\x02\x46\x6b\x8b\xe2\x19\xda\x0e\xaf\x9b\xdb\x4f\xa8\xc2\xb1\xcc\xd6\x17\x5a\x8b\xd4\xd8\x10\x1e\xef\x61\x80\xd3\x67\x53\x20\x31\x67\xd5\x79\x5e\x58\x29\xe9\x7f\xd7\x69\x42\xa2\x01\xaa\x3b\xac\x85\xb3\xa1\xab\xa5\xc0\x91\x81\xe1\x87\x70\xb2\xf1\x05\x8e\x38\x5c\xfe\x8e\x1d\x16\x1b\x43\x91\xf4\xe4\xe6\x71\x3f\x19\xfc\xc6\xa4\xe0\x88\x6d\xbc\x8c\x70\x38\x00\x4c\xf7\x64\x3a\x75\x95\x9b\x66\x33\x8c\x56\x48\xc0\xe9\xfa\x55\x97\x22\x88\x02\xf6\xc7\x32\x82\xe7\x35\xf9\xb1\xec\xa7\xd2\x5c\xf1\x6b\x98\x27\x90\x31\x27\xbe\x72\x39\x9d\xfe\x01\xe5\xb7\x9e\x46\x9c\xc7\x00\x22\x21\x43\xba\xe2\xbe\x06\xe8\x97\xc7\xd1\x27\x03\x4b\xd1\xdd\xf4\x16\x93\x17\x02\x0c\xfe\x45\x12\x31\xa1\xe4\x50\x3d\xea\xc8\xf8\x43\x80\x7e\x39\x00\x9e\x44\xdc\xb1\x11\x1c\xc7\x5e\x70\xdc\x5f\x31\x13\x8e\x4f\x07\x46\x94\xf7\x3c\x89\x8c\x95\x6e\x10\x56\x8d\xcf\x48\x8c\x31\x17\x49\x64\x35\xc2\x88\x7d\xe2\xd5\xf1\xbb\xbd\xd4\xc7\x45\xda\x9b\xa5\xe1\x96\x10\x0a\xd4\x17\xc2\xfe\x7c\xf7\xd9\xab\x8f\xac\xa4\xd9\x1b\x91\xd4\x39\x5f\x16\xa0\x09\x11\xdb\x84\xa6\xa9\x55\xbf\x28\x9f\x1a\x17\x92\xf0\x84\x1a\x11\x23\x81\x33\xae\x64\xeb\x3f\x89\xaf\x8a\xfd\x9f\x51\x71\x2c\x4f\x18\xe5\x0e\xcd\x82\xc5\xf4\xb3\xb5\x34\xe1\x0c\x30\x3d\xee\x65\x33\x61\x08\x5b\x0f\xf7\xe1\x2a\x49\x1d\x3f\x75\x5d\xfe\xb1\xfd\x85\x90\x04\x4f\x04\x38\x89\x1f\x8c\xa3\xb6\xa3\x61\x9d\xc4\xc0\x91\xbf\xc6\x97\xa5\x14\xc5\xc7\x29\x9d\x24\x55\x31\xa2\x88\xa4\xaa\x6a\xa7\x2d\x1d\x06\x73\x92\xd1\x2c\x82\xde\x12\xb8\xa9\x2e\xa5\x9e\x55\x6f\xf2\x24\x63\x91\x18\x60\x14\xdb\xb7\x0a\xca\xfc\x67\xbf\x4b\x25\x19\x4f\x90\x91\x26\xe0\xc4\xbf\xba\x88\xd3\x6c\x55\x4a\xa4\x70\x84\x20\x07\x67\x76\x07\xb5\xeb\xcd\xd9\x36\x9d\xb9\x04\x9e\xdd\x90\x46\xa1\xbd\x94\xd8\xcf\xc7\xdc\xb3\x0a\x34\x1f\x85\x71\x13\x65\x0d\x06\xe6\x1f\x2e\xb2\x36\x60\x6e\x00\x6a\x5d\xe5\x65\xcf\x2c\xc7\x13\x9d\x59\x8c\xa9\x7a\xde\xd6\x65\x84\xcb\x6c\x44\x19\x91\xa8\xc8\x67\x73\x0e\x4e\x57\xda\x7f\x82\xe5\xa7\x30\x99\xc8\x3c\xd3\xc3\xe7\xdd\xdd\x35\x85\x19\x4f\x8c\x64\x18\x17\x2e\xe1\xc7\xee\x2c\x35\x34\x6f\xf9\xd9\x63\xee\x7c\x74\xdc\x0d\x35\xba\xfc\x67\x7a\x31\x20\x5c\x3a\xf2\xa3\xb6\xce\x21\xf4\xd1\x5f\xbc\x13\x08\xe2\xd2\xc9\x48\x78\xb2\x7f\x83\xa7\x6a\x28\xf3\xe4\x69\x94\x44\x68\xaa\xd8\x22\x3f\xdf\xca\xb3\x4b\x1c\xef\xab\x51\x7a\x2c\x25\x91\x90\x9e\x97\xe1\x46\x96\xdf\xea\x2a\xc0\xd3\x79\x4a\x12\xae\xfb\x6a\xaa\x1d\xb4\xb7\xb2\xc9\xcb\xa9\xaa\x31\x4f\x89\x8e\x78\x30\x95\xff\xd8\x2d\x64\x48\x53\x62\x38\x5a\x60\x8e\x81\x1e\xe5\xba\xbb\x5d\x6f\x53\xde\x5c\x8a\x6f\x33\xb2\x43\x9e\x52\x4a\x5d\x22\xa0\x42\x73\xfa\x9b\xcf\xf9\x11\x3a\xe5\xf2\xe1\x29\x55\x06\xc7\x9f\xfb\x92\x3e\x1a\xff\x24\xcf\xb3\xe7\x63\x69\x8c\xa9\x8d\xbb\xf5\x97\xc3\xf6\xe5\x75\x00\xd6\x77\xa6\x9f\x4e\x3d\x4b\x26\x86\x23\xc6\x1a\x1a\xe3\x88\x66\xca\x09\xc1\x6a\x6c\xf8\xd9\xd6\xd2\xdf\x69\xcc\xbe\xcf\x53\x2e\x15\x7e\x87\x1e\xc3\xb5\x3a\x9f\x8b\x7c\xc9\xb2\x48\xb9\x36\x41\xe2\xa0\x9b\x59\x81\x38\x81\x4c\xb2\x4a\x29\x87\xcc\x69\x22\xb5\xb2\x6e\x43\x5d\x6b\xd8\x22\x52\x41\xe3\xc8\xbb\x74\x2b\xad\xab\x53\x77\x2f\xb8\x59\x86\x01\xa6\xc2\x5a\xed\x20\x07\xae\xe6\x7d\x7f\x17\x8c\xe3\x34\x89\xa4\x08\x4a\x4a\x55\xd9\xbe\x39\x5d\xc9\x6b\xe3\x30\x4d\x22\xc7\x05\x11\xd6\x84\x55\x51\x8c\x37\xe5\x34\x4d\xb4\xd7\x9f\x5b\x97\xed\x28\xc6\x1e\x0e\xdb\x0c\x91\x55\x8f\xd5\x71\xa8\xbc\x9f\x36\x91\x2a\xe2\x30\x6c\x8a\x87\x7e\x9b\xea\x8e\x20\xea\xeb\x69\xfd\xf5\xf0\xba\xde\xad\x5f\xbf\xac\x0f\xf7\x9f\x9f\xef\xc2\x71\x05\xd2\x65\xd8\xe5\x49\x15\x50\x23\xaf\xe9\xb4\xcb\xb5\xc9\x70\x04\x86\xa8\xe4\x0d\x68\x79\x69\xe0\xda\x82\x99\x49\x79\xfd\xcf\xec\x32\xe0\x66\x28\xee\x3e\x68\xb9\xa1\x2d\x79\xc8\x1b\x34\x06\x75\xd5\x33\x6f\xf2\xd4\x30\x40\x23\xea\xfe\x9f\xa3\x1d\x37\x35\x32\xb1\xa3\xea\x84\x91\x09\x16\x1a\x18\x82\x9e\x76\xfb\x96\xd7\xe6\x76\xc4\xb4\xef\x8f\x5b\x0a\x02\xfc\x1a\xf6\x15\xf2\x59\x1f\x5a\x99\x20\xbf\xd9\x7f\x2f\x4d\x4b\x22\x04\x40\xba\x23\x59\x14\xb1\x6c\x30\x81\x5f\xa5\x86\x2b\xc5\xf6\xe9\xf4\xca\x08\x4f\x03\xd3\xf9\x6d\xde\xbe\x6f\x0b\xe9\x81\xf9\xe1\x92\x24\x15\x29\x8c\x33\xc4\x3b\x68\x2f\x67\x4f\x9c\xf0\xb9\x6c\xf3\x61\x07\x23\xf1\xb4\x5e\xac\x3b\xd9\x45\x07\xce\x50\xdb\xaa\x3e\xf9\xe4\xfa\x9c\x4c\x8e\x67\x2c\x32\xb8\xfd\x86\x2f\xf7\x0a\x0d\x22\x3a\x6e\x74\x75\x39\x57\x1f\x6d\xb3\x19\x27\x90\xfa\x87\xef\x8c\xb0\x89\x93\x90\xf1\xd8\x79\x4f\xb7\x55\x0d\xbf\xd0\x4b\x1d\x4f\xc7\x8c\x83\xb6\x0e\x23\x5a\xb6\x55\x23\xff\x08\xd7\x12\x91\xc5\x95\xe1\x15\xbe\x57\xdf\x82\x07\xe4\xbe\xdb\x6c\x80\x67\x22\x4b\x90\x39\xb7\x5b\x00\x9f\xa0\x69\x46\xda\x1b\x13\xa3\x29\x8b\xa3\x04\xd9\x2a\xd1\xb8\xad\xa6\x13\x2d\x8b\x93\x0c\x53\x4a\x0f\x2f\xeb\xfe\x27\xab\x31\x76\xb2\x87\x62\x94\xd6\xcb\x12\xa1\x11\x9e\xf6\x26\x6b\x73\x2b\xcf\xe3\x58\x58\x96\xc6\x56\xa8\xe0\x62\x57\x85\xa9\x7e\x94\x41\x84\xe1\x3f\x24\x8a\xfe\x6f\x68\x96\x25\x91\xec\x0b\x4d\x8a\xea\x1d\x8c\xea\x46\x23\xae\x8d\x4f\xb2\xae\x73\x79\x1c\x06\x44\xc6\x13\x8c\xbd\x77\x06\xd9\xb8\x4c\x18\x5b\x3b\xa0\x5a\x1a\x96\xf9\x2c\xd3\x8e\x65\xb9\x09\x15\x8e\xb3\xde\x92\xda\xc9\x22\x18\x59\xa1\x63\x1e\xc8\x10\x79\xa6\xd2\xd8\x85\x71\x10\x60\xb0\x29\x6f\x7d\x2d\xe6\x60\x60\x67\x5a\x44\x68\x3f\x74\x1f\x42\xc3\x8b\xf5\x16\xcc\x74\x55\xc8\xb4\x26\x38\x19\x0f\x61\x61\xbc\x81\xf6\xc3\x9a\xdc\xd9\xa9\x26\xc2\x1c\xad\x2c\x5a\xf0\xa0\x9e\x2d\x38\x46\x81\x2b\x5c\x42\x66\xac\x45\x5f\xaf\xbc\x9c\x5c\xb9\x71\x01\x66\x86\x36\xcf\x20\x4e\x30\xd9\xd9\x7d\xf1\xdb\xa2\x33\x58\x27\xa2\x18\x5d\x83\x54\xf8\x4f\x71\x7f\x29\xcd\x35\xa4\x3f\x03\x90\x58\x4c\x7e\x92\x4d\x0b\xf5\x4c\x9e\x87\x67\x96\x5a\xef\xd0\x16\xc5\xb5\xea\x29\x97\x51\xe4\xea\xd8\x5d\xd9\xed\xb4\x3c\x88\xcb\x88\x41\xe2\x94\x90\x4a\x5d\x5c\x0c\xa0\xa8\xca\x38\xd0\x2d\xa3\xd8\x79\x87\x9e\xbc\x1f\x03\x74\xcb\xb3\x53\x46\x19\x71\x44\x0f\xd8\x71\x7d\x30\xf4\x53\xde\x2c\x45\x51\xfd\x49\x84\x32\xcc\xaf\x1f\x3b\x9b\x30\x97\x25\xed\x9e\x32\xdc\x9c\xc6\x69\xd8\x0f\xb7\x35\x7c\xae\x73\x32\x7d\x7c\x6a\x32\x8c\xe9\x5f\xab\xf5\x71\xc9\x38\x04\xae\xdd\x9e\xa5\x6b\x99\xcb\x88\x4b\x26\x44\xe2\xa8\x07\xdb\x1a\xce\xb9\xf9\x52\x5d\xf4\x1b\xd4\xbb\xaa\x18\xab\xf2\x73\xc9\x14\xc1\xce\xec\xd3\x60\x5d\x4f\x81\xb9\x2a\xb2\x98\xef\x3b\xfe\xf4\xce\x9f\xf3\x04\xc4\x07\xe5\xca\x0c\x7f\xa5\x88\xc8\x25\x97\x4e\xcf\xf2\x0c\x38\x92\x5d\xf5\xe4\xb9\x5f\x35\xa4\xa0\x8e\xfd\xeb\x93\x6c\x1e\x72\x3b\x85\xef\x4a\xc1\x33\xd2\x53\x0f\x1e\x64\x7f\x4e\x62\xb0\x7a\xe0\xb1\x3a\x6e\x1d\x2b\xd6\xb6\x86\x09\x99\xeb\xdf\xaa\x58\x90\x22\x83\x90\xb8\xc0\x6c\xa8\x13\x24\xf0\x28\x20\xe9\xaa\x6a\xaf\xa0\x64\x52\x68\x43\x3d\xe4\x02\x69\xab\x83\x02\xec\xb4\x55\x2c\x09\xa2\x63\x5f\xd7\xff\xfc\xbc\xde\xed\xd7\x77\x87\xdd\x7e\xb5\xff\xbc\x0b\xef\x90\x64\x5c\x38\xfc\x20\x8a\xa2\x14\x45\xb7\xeb\x19\xcf\x83\x3d\xbd\x54\xa2\x5d\x0e\xd8\x63\xac\x06\xef\x59\xa6\x1e\xce\x5e\x23\x70\xe5\xa3\x41\x9d\x2a\x83\xd5\x59\xeb\x3f\x6e\x3f\xad\x9e\x1f\xd6\x87\xd7\xd5\x7e\xdd\x5f\x42\x4b\xa4\xbc\xb3\x75\x75\xba\x96\xb1\x99\x5d\x49\x46\x80\xd9\x30\xb4\x30\x6e\xd0\xba\x1d\x6f\x01\x52\xd1\xd8\xbb\x78\xce\x51\x08\x05\xd6\x66\x5b\x57\x95\x9d\x96\x44\x48\x95\x45\x2c\x20\xe3\xf6\x8f\x4b\x3a\x0c\x5c\x2a\x19\xe1\xd2\xf0\x94\x97\xb0\xba\xfb\xe0\xfd\x34\x21\x91\x37\x5b\x0f\x18\xf8\x3d\xe4\x2d\x9c\x9a\x43\x5e\x1e\x1a\x2c\xdf\x9a\xde\xd7\x70\x97\xde\xdd\xfd\x90\xe7\xc9\xd3\x03\xa1\xd4\x47\x5c\xb1\xb6\xea\xbe\xaa\x7b\x5c\xc7\x12\x2e\x2d\x9c\x66\x14\x86\x11\x9d\xb6\xb4\xcb\x5f\x78\x92\x8b\x70\x65\x1b\x65\xc8\xda\xf1\x87\x91\x1a\x9b\x0d\x48\x95\xd9\x2b\x2d\x05\x1e\x67\xaf\x6b\x09\xe0\xfe\x84\xfa\x23\xf5\x83\xfc\x0e\xb7\x5f\x6f\x7f\x9d\x5c\x97\x96\x39\x18\xe0\xd3\xfb\x2f\x74\x29\x42\x5b\x93\x20\x8f\x1f\xfa\x56\xf3\xb4\x82\x8a\x04\xc1\x39\xb3\x2a\x9c\x48\xca\xa7\x30\x67\x16\xec\x7b\x15\xa5\x8a\x9b\x3e\xfd\xe5\x71\x00\x55\x3d\x1b\xe0\x2a\x02\x1a\xfb\x45\xe5\x66\x5e\xc4\xa7\x08\x71\x0e\xc5\xcd\xcb\xf3\xe7\x1d\x32\x41\xee\xf6\xab\x87\x75\x70\x38\xba\xe3\x41\x79\x74\x5b\x55\xc5\xaa\x34\xbf\x42\x8a\x2a\x42\x52\xe4\x7f\x75\x32\x5b\x3d\x1e\xf1\x23\xd4\xcc\x78\x39\x52\x04\x88\xed\x23\x85\x16\x6a\x11\xfd\x14\xd1\xec\x95\x29\x77\x00\x2e\x0c\x96\x3c\x5c\xba\x85\x71\x1a\x22\x51\x54\x1b\x0c\x8b\xa2\x34\x66\xf7\xc8\xe1\x4d\xa8\x89\x31\xe5\xe8\x0b\x89\x96\x54\x38\x67\x2f\xc3\x49\x16\xd0\x5f\xab\xa2\xe8\xcc\xb7\x59\x8c\x5b\xf1\x4c\xb3\xae\xf7\xb6\x55\xe7\x87\x1d\x44\xb8\x97\xa0\x11\x7a\x4d\x4d\x37\xdb\x0f\x77\x79\xa3\x47\x9b\x84\x12\x3c\xc6\x02\xab\xce\x42\x75\x41\xbe\x5e\x35\x81\x2b\x91\x24\xc1\x2d\xdf\x98\x55\x5d\xcb\xf7\x4d\x0b\xa7\xab\x1e\xfc\xc5\x10\x53\x09\x8d\x10\x9f\xdf\xfe\xbc\x07\x40\xd6\xd8\x9e\x7a\x86\xab\x24\x49\xb2\x14\xb9\x52\x9d\xea\xee\xfb\xdc\x11\x57\x49\x2a\x1d\xe1\x5b\x51\x95\x70\x05\x29\x1d\x97\x87\x7f\xcc\xd2\x34\x7f\xa2\x0c\x10\x38\x73\xf0\x35\xd0\x21\x99\x1a\x18\x7c\x3f\x38\x4b\xc7\x28\xaf\x71\xf7\x10\x5c\x3e\x95\x46\x3c\xa2\x5e\x8a\x5b\xb6\x70\x07\x4d\x5b\x5f\x06\x9d\x26\xae\x52\xa1\x89\xea\xc3\x60\x58\x2f\xe1\x2a\x95\xc2\xf1\xc4\x55\x97\x3a\x82\x0d\x47\x68\x3b\x3a\x0a\x99\xec\xcb\x84\xcf\x55\xee\x53\xf2\xe1\x70\x46\x9d\x82\x52\x51\x7d\x87\x60\xc9\x87\x43\x8c\x05\x0a\xe0\xaf\x90\x6f\xa1\xde\xc9\xb6\x6a\xde\xfa\x6e\x97\x42\x47\x59\xd8\x65\xfa\x8f\x2d\x2d\x48\x8f\x11\xf7\xd7\xeb\x27\x9e\xe2\x06\x49\x7a\xbe\xca\xef\xd0\xf4\x70\xe1\xd9\xe7\x9f\xf6\x97\x92\x3c\x80\xa1\xfb\x21\xf7\x17\xdf\xe7\xea\x0a\xa9\x1c\xc8\x42\xbd\xad\x1a\xea\x83\x43\x1b\xa0\x44\x4f\x7c\xea\x12\x6c\xae\x73\x39\x23\xdc\xe1\x4a\x33\x40\xdf\x09\x4a\x73\x53\xd5\x75\xf5\x63\x75\xac\x01\x16\xf8\xd3\x97\x1f\xc6\x44\x3a\x30\xc9\xf9\xaa\xbf\x60\x0b\x8d\x42\x34\xca\x30\x2f\x16\xaf\x35\x9c\xdb\x17\x6b\x67\x16\xac\x32\xa9\xe3\xcc\x3c\xc9\xc6\x13\x78\xc9\xe2\xb7\x71\x26\x71\x76\x5b\x10\x24\xce\x86\x5c\x73\x67\xa5\xae\x50\xd2\xab\xfb\x57\xff\x79\x20\x49\x32\x57\x96\xb8\x75\xd5\xf1\xa3\xc4\x82\x02\xc5\x10\x3d\xeb\x90\xf7\x5b\x59\xcb\x53\xd3\x1f\xb3\x3a\xf1\x74\xca\xdf\xf2\xf2\xf8\x62\xe7\x5b\x80\x35\xb1\x89\x42\x1d\xd7\x6c\x2d\xd7\x11\xb1\xb8\x74\x8c\x04\x40\x57\xaa\x9a\xe3\x85\x75\x24\x19\xa6\xb1\x71\x83\x76\x7d\x0f\xf5\x1d\x58\x79\x29\xe6\xa2\x5a\x5c\x47\x4a\x63\xbe\x05\xdd\xce\x9b\x00\xe6\x98\x3e\x95\x8e\xac\xc5\xd5\xb3\x73\xda\x2f\x85\x9c\x5d\x82\x08\x11\x67\x13\xf5\xce\x97\x4b\x7b\xbe\xb4\x3b\xa3\x9b\x62\x8c\x49\xd0\x24\xb6\xe8\x0c\x07\x3a\x5a\xe9\x00\x49\x2e\x20\xd2\x0f\x32\x4d\x59\x26\x9d\xd0\xa9\x3c\x9f\xc1\x4c\x19\x5b\x42\x1b\x91\xa1\xa5\x81\xa1\xb7\x43\xe0\x42\xeb\xaf\x90\x51\x84\xfe\x39\x7c\xe4\x66\xff\xd2\x1f\x30\x14\xe3\x1b\x6f\xa8\x8c\xfb\x0a\xd7\xb1\xa0\xc5\x71\xa1\x19\xd3\x81\x29\x7b\x87\xd4\xe6\xeb\xd2\xb3\x13\xcf\xc3\xc3\x9a\x09\x82\xfa\x04\xf8\x09\x77\xd0\xde\x03\x7c\x6e\xcc\x5d\x1e\xf0\x6e\xf3\xe6\x40\xd1\x49\x79\x7e\x79\x5e\x87\x72\x31\xcd\x09\xf1\x45\x66\x0e\xf2\x00\xbe\x72\xbc\xe9\x1b\x70\x88\xb2\x5e\x9b\xc0\xbd\xfc\x00\x49\xd3\x3c\x15\x61\xf3\x7a\xea\x16\x3a\x59\x3c\xe6\x4d\x3b\x88\x4c\x70\x2d\xd2\xd4\x04\x39\x92\xba\x3a\x55\x0f\x50\x46\xb3\x27\x13\x96\x84\x62\x80\xe2\xa9\x32\xb9\xcd\xc1\x5c\xad\x45\xd3\x53\x62\x11\xe3\x7c\x3c\x1c\x03\xc6\xc0\x85\x84\x96\x3b\x35\xa1\x80\xd6\xd0\x01\x6b\xc9\xeb\xee\x01\x47\xf5\xb4\xf3\xfc\x87\x4e\xb8\xcb\xf6\x37\xd0\x7e\x82\xfc\xa3\x47\x48\x12\xc7\x36\xfe\xb4\x79\xde\x6f\x9e\x1f\x0e\x8f\x9b\xa7\x4d\x40\xf4\xea\x24\x75\x5a\x56\x28\x3e\xf2\x0a\x4d\x55\x7c\x87\xd5\x9f\x17\x59\xe7\x97\xd3\x1c\x0c\xa1\x13\x65\x30\x6b\xea\x88\x4b\x1c\x67\x62\xb8\x50\x9a\xa6\x26\xf0\x41\x03\xf8\x49\x3e\x0a\xe8\x5e\xbf\x6c\x0a\xc2\xf2\x21\x4b\xf8\x49\x96\xc7\xbc\x3c\xce\x38\xf4\xb9\xce\x22\x86\x21\xb2\x3f\x2f\xb9\xfe\x76\xeb\x64\xeb\xbd\x7e\xc2\x38\x7c\x7a\x6d\xc1\x2e\xfe\x5d\x96\x94\xe6\x3a\x53\x29\x7a\x50\x98\x03\x5c\xcb\xba\x78\x9f\x7d\xfb\x0c\x00\xd7\xa1\xaa\x2c\xde\x9d\xce\x88\x3f\x20\x85\x13\x37\x79\x42\x40\xbb\x9b\x9a\x57\x83\x62\xf9\xcb\x48\xc1\xd0\xf8\x70\x94\xc0\xf7\x97\xa2\xf0\x72\xa2\x08\x3d\x5a\x32\xd2\xff\x8e\xf0\xee\xec\x1e\x31\x44\xde\x62\xbd\x29\x40\xea\xb7\xa5\x19\x2a\x53\xd7\x08\xf5\xc1\x1c\xe0\x95\x2e\x67\x58\xb5\x54\x06\x9d\xa4\xff\x56\x79\xe9\x1c\xad\xe9\xa5\x94\x8c\xd0\x24\x39\xd8\xaa\x1e\x77\xc5\x7d\x5d\x9d\x7a\x0a\x2d\x64\x1c\xfc\xb5\x15\x3c\xbb\xad\x52\x19\xba\x95\xef\x10\x1c\x73\xad\x4c\x16\x94\xf6\x5e\xbd\x20\x09\x98\xe9\xa2\xa0\x8c\x42\x6c\xf9\xba\x39\x8f\xc2\xcf\x5a\x33\x8d\x68\x97\xfb\x97\xcf\xcf\x77\xeb\xd7\x9d\xe3\x1b\xda\xae\x5f\x37\x2f\xc1\xb4\xd2\x26\x89\xb0\x54\xf7\x5e\x7e\x83\x6b\x3d\x01\xae\x8d\xb1\x38\x55\x7f\x04\x08\xd5\x53\x5e\x4e\xe2\xab\x1a\xa8\x8d\x09\x96\x03\x9f\xcf\xdd\xc0\xae\xca\x0f\x7c\x66\x0d\x3c\x42\x7c\x1b\x3a\x41\x07\x3b\xac\x5a\x96\x50\x8c\x65\x35\x4e\xe3\x63\xc4\xc2\xa2\x2d\xc9\x90\x84\x68\xbf\x59\xbf\x92\x03\x42\x73\xfb\x43\xc2\x91\x5a\x3c\xde\xac\xfa\x9f\xe2\x2c\x90\xfd\x07\x29\x63\x28\x66\xf8\x41\x6d\x55\x4f\xb0\x74\x9f\x97\x25\xbc\xa3\xdd\x56\xc0\x53\x55\xc3\xfe\x4d\xf6\xdd\x67\xad\x41\xb3\xa8\x79\x2f\xa1\x6e\x6b\x98\x20\x8c\x4d\xc4\x00\x89\xa1\xf7\x75\xfe\x3d\x14\x8a\xfd\xda\xc0\xb9\x02\x56\xfe\x72\xe7\x31\x11\x07\xf4\xd1\xee\xab\xaa\xfa\xdf\x6b\xdf\x76\xf2\x4e\x26\x8a\x63\xe3\xa5\xc6\x06\xd8\xc8\x1c\xc5\x6a\xa2\x44\x22\x27\x49\x01\xb6\xa5\xe9\x6f\xb3\xfb\x59\x82\x38\x84\x53\x65\x1c\x7b\xea\xcc\xed\x31\x24\xca\xa8\x43\x62\xb4\x4d\x5b\x83\xfc\x36\xe9\x0f\xc2\x23\x4c\xb7\xea\xea\x74\xba\x94\x79\xfb\x3e\xf2\xc2\x0c\x8d\x9c\xbf\x69\xe0\x7b\xb7\xa5\x6d\x6b\xd0\x83\x75\x6e\x28\xd3\x08\xf1\x7d\x92\x9d\x53\x54\x39\x46\xd3\x3e\xb7\x62\xe8\xc0\xab\xbf\xad\xe1\x94\x5f\x7a\xb3\xca\x50\x23\xd0\x71\x3e\x78\xcc\x02\xbe\x12\x8f\x66\x9d\xc3\x22\x86\x2c\x2f\xb2\x69\xf2\x63\xe9\x93\x0f\x77\xf2\xfd\xd7\xaa\x50\xdc\x30\x26\x99\x47\xc0\xf4\x5c\x91\x4b\x92\x6d\xdc\xb0\xd8\x3a\x36\xac\xce\x3e\x73\xa8\x37\x47\xd3\x17\x1e\x94\x19\x1b\x7b\x6e\x8e\xdd\x93\xc7\x0c\xb8\x69\xb4\x85\x7a\xdd\x59\x42\x2d\xd4\xa5\x2c\x66\xdf\x84\x27\xae\x98\x31\x28\x11\x0d\x56\x77\x0e\x73\x69\x6a\x6e\x38\x38\xf2\x57\x03\x36\x2f\xc1\xd3\x51\x2f\x2b\xd6\xf9\x33\x84\x49\x31\xec\xe1\xeb\xee\x50\x95\x25\x98\xdb\x8b\xeb\xa2\x89\x93\x34\x00\x7b\x30\x70\xfd\xc1\x85\x63\x4d\x91\x7a\xf1\x70\x92\x79\xd9\x1e\x9c\xdd\xb7\xb0\xbe\x98\x84\x12\x1c\x19\x25\xfc\xec\xd5\x91\xbe\xca\x23\xd4\xcd\xbe\xc2\xdc\x61\x28\x1c\x0f\xed\x85\x0b\x2f\x7a\x30\x83\xcf\xbe\xfb\x83\xa9\xce\xd2\x20\x2c\x38\x72\x9f\xfd\xd1\xcc\x50\x10\x81\x15\x1a\x55\x25\x3f\x9f\xb1\x7a\xf4\xd7\xf3\x50\x6a\x97\x3c\xf1\x49\x3c\xc4\x92\x7e\x6e\xa0\x46\xa0\xa5\x6f\xa3\x3c\x0f\xe8\x9b\x6c\xba\x43\x5b\xa8\x3d\x2d\xe2\x34\x2b\xc2\x43\xf3\x54\x87\xe0\xe3\x43\x21\x4d\xde\xcd\xb6\x6d\x67\xac\xcf\x9e\x58\x49\x86\x53\x32\x50\x78\x2e\x3f\xa0\x52\x02\x03\x61\x5e\xbc\x6e\xe2\x07\x19\x6d\x44\xea\x68\xae\xeb\xf3\x28\x5d\x64\xb4\x75\x01\x93\xef\x50\x9a\xaa\x9e\x64\xb7\x0d\x64\x5a\xf7\x11\xe2\x07\xaf\xc9\x66\xfa\xa3\x32\x45\x44\x5c\x55\xba\xf4\xc6\x15\x02\x6e\xfa\x0e\xa0\x22\xa9\x07\x18\xd9\x6a\x56\xc1\x3e\x7b\x17\x9b\xc5\x18\xf7\xcb\x1b\x44\xde\xe4\xe5\x11\x55\x27\xff\xe2\x13\x59\x69\xd0\x97\x39\x40\x10\x62\x7e\xac\xfa\x40\x21\x44\x94\xc7\xde\x64\x7b\xca\x4b\x24\xf6\x19\x99\x2c\xe3\x0b\x01\x56\x4f\xf7\xee\xc3\xd3\x12\xae\x18\x98\x95\x98\xaf\x43\x74\xc0\x41\x55\xe5\xa5\x39\xc8\xf1\x8e\x08\x5c\x26\x14\xcb\x28\xa5\x05\xb4\xb1\xc3\x01\xe1\x41\x4e\x8f\xd5\x71\x63\x00\x33\xe7\x81\x55\xf9\x6f\x81\xef\x21\x8e\x38\x56\xf4\xad\xff\xd8\x3e\xbe\x60\x19\xd9\xdd\xfa\xf9\xe5\x69\xf3\xbc\xda\xbf\x04\x28\x36\xc4\x32\x45\xb0\x8c\xa9\x50\xb2\xd5\x97\xbb\x4f\xec\x40\x48\xa3\x0c\x2b\x27\x35\xf2\xfa\x7f\x1d\xd2\xfc\xe1\x22\x69\x9a\xa0\x44\x6b\x3b\x66\xc3\xbc\x74\xab\x54\x68\x91\x45\x1c\x5b\x3c\x56\xc7\x9b\xdc\xf4\x51\xe9\x29\xa2\x62\x6e\x80\x82\x94\x1c\xad\xf4\x80\x2c\x58\x64\x5e\x9c\x44\x08\x41\x25\x02\x23\x53\x6e\xf9\x7e\xad\x06\x84\x2d\xa8\x24\x96\x83\x94\x4e\xb7\xb5\x2c\xa2\x52\x41\x49\xa7\x12\xed\x45\x4e\x40\x9e\xa6\x0a\x54\x7d\x33\xe1\xa8\x47\xac\xcd\x8b\x5c\x3a\x83\x27\xdc\xcb\x48\x86\xd1\xbd\xdb\x97\x7f\x07\x13\x04\x40\x46\xe8\x1f\x6f\x7a\x78\x02\x58\x69\xd3\x90\x8c\x3c\x82\xf1\xaa\xdf\x23\xb2\xc1\xe5\x1d\xdc\x46\xd6\x22\x4e\xe4\xfe\xf3\xb3\x27\xb3\xe6\x9d\x1b\x86\x23\xb7\x42\x62\xcf\x5e\xb2\x97\x5b\x62\xb4\xd4\x41\x01\x12\xa0\x33\xfa\x66\x31\x03\x4b\x7d\x5d\x0b\x8a\x40\x20\xb3\xeb\xac\x01\x8b\x81\x24\x03\x55\x75\xe9\x08\x8b\xc2\x1d\x98\xe5\x88\x30\x3c\xa3\xd8\xcb\x0c\x26\x67\x05\xd5\xc8\x82\x70\x53\x54\xc7\xd1\xaa\x62\xe3\x28\x0d\x0b\xf0\x3f\x2a\xe5\x44\x23\x66\xb7\x8d\xbb\xcd\xc1\x95\x9f\x0e\xf4\xd9\x87\xaf\xeb\xf5\xef\xa4\xbf\x4a\x2a\x10\xa8\x88\xa1\x89\xcb\x49\xf5\x21\x16\x1b\x6b\x47\xeb\x76\x84\x76\xbd\xff\x14\x7e\x4d\x28\x20\x94\x79\xdd\xf9\x9d\xbb\x56\x96\xa6\x33\xc8\x97\x52\xfd\x97\xab\x12\x32\x9b\x24\x2c\x88\x0a\x78\x30\xc3\x12\xd7\x81\x4d\x92\x14\xf7\x9d\x87\xd7\xd5\xed\x9b\xcc\x3f\x02\x11\x4c\x2f\x9d\xc5\x18\x8c\xf0\x40\x64\xac\xf3\x2e\x8d\x4f\x96\x8e\x9e\x3f\x8d\xa2\x40\x44\x84\x44\x0f\x4d\x7e\xfc\x22\x2f\xc5\x2c\xf0\x6f\xd3\x8c\x8c\x4b\x77\x5c\xc5\xbd\x47\x93\xf6\x97\x52\x9c\xf2\x00\xc6\xdd\xdc\xf5\x3f\x5b\x12\xbb\xe8\x47\x83\x9f\x79\xb9\xd6\xca\x66\x99\x27\x16\xc5\x07\xf6\xd2\xbe\x0d\x98\xe5\x4c\x84\xcd\x80\xe1\xce\x78\xac\x07\x8a\x41\x2b\x23\x85\x18\xb4\x67\x28\x65\xe3\xba\x2a\x1c\xa1\x09\x02\x17\x9e\xf2\xa3\x8b\x5b\x6c\x4a\x5b\xed\x60\xba\x61\x59\xa5\x29\x55\xfd\x06\xff\x09\xea\x2b\xe2\x5d\xdf\x50\xd3\x94\x78\x48\x81\x7f\xd2\x2b\x94\x91\xd5\x89\x72\x89\x95\x46\x2f\x14\x62\x59\xad\x32\x81\xcb\x87\xca\x65\x2b\xeb\xce\x23\x9c\xec\x84\xd6\x44\x9a\x20\xb5\x15\x48\x53\xe4\x25\xb8\x32\xfc\xfe\x28\xe5\x76\x28\xa0\x1c\xf1\x8f\xcc\xd4\xd4\xb8\x35\x46\x25\x64\xb0\x7f\xa7\xb5\xe4\xd6\x80\xd6\x81\x4a\xa1\xdb\x2e\xae\x51\x64\x16\xac\x0e\x92\xaf\x87\xb7\xf9\xd5\xad\x00\xc9\xc6\x33\xd9\x5c\x35\xb0\x59\xe6\x11\xf4\x73\xa6\x31\x6b\xd3\x4c\x07\x05\x93\xaa\x6c\x25\x12\x08\x5e\xf3\x9b\x59\xab\xa4\xd5\x01\xa2\xb6\x6e\xdf\x1e\x42\x37\x89\x28\xf2\xb4\xf5\x5a\x16\xda\xe7\x3b\x17\x6d\x15\x11\x45\x8c\x21\x0f\x4b\x58\xfe\xd7\x4f\x2f\xa1\xf2\x5c\x44\x91\xa6\x0e\x9e\x16\x98\xd8\xb6\x35\x84\x63\x44\x59\x2c\x50\x09\xf1\xe7\x7b\xdc\xd4\x7e\x15\x77\x10\x11\x8d\x74\xef\x92\xc8\xd2\xec\xab\xea\xdb\xea\x47\x08\xc3\x8b\x88\x66\x11\xee\x93\x2d\xd2\xd5\xc3\x39\xfc\xce\x62\x3b\x0a\x87\x1f\x02\x37\xe4\xdf\x0a\x18\x8a\x88\xf3\x18\x81\xbd\xe7\xea\xdb\x34\x49\x2a\x22\x2e\x04\xe6\x19\x3e\xbd\xec\x6f\x57\xbb\x4f\xbf\xf5\x3f\x6b\xc7\x14\x09\x65\x3e\xf6\x31\x45\xc4\xb5\x63\xff\x3b\xcb\xf7\xce\x04\x1e\xcd\x13\x11\x71\x93\xda\xa1\x24\x78\xe7\xe9\x9c\xfa\x33\x81\xa3\x14\x0e\x5a\x51\xeb\xd2\x7c\xa0\x67\x20\xa2\x98\x26\xb8\xb9\x7a\xb6\xe1\x51\xd2\x48\x44\x71\xa2\xf1\xb3\x9e\x0f\x41\x27\x70\xb1\x7e\x4a\x44\x49\xc4\xa3\x10\xb3\x7f\x3f\xa9\xe0\xf7\x89\x28\xa1\x89\xb5\x21\x98\xaf\xab\x32\xe0\x1a\x26\x13\x40\x44\x69\x62\x93\x81\x6a\xf5\x06\xda\x29\x9f\xd2\xf4\x66\x19\x03\x1c\x09\xfe\x89\xfd\xa2\x3d\x7a\xec\x4c\x73\x4f\x60\x1b\x7e\x91\x22\x46\x63\xf7\x98\x7f\x07\xc4\x91\x5c\x41\xbe\x44\x24\x63\x8e\x18\x32\xd9\x5d\xcf\xa5\x81\x27\xab\x85\x88\xa4\xb4\xc8\xf2\x7e\xf3\xe9\xe6\x2f\x21\x64\x22\x92\x86\xe2\x26\xe6\x82\x1d\x61\xd8\x3a\xc5\xf8\x31\x0e\xcf\x37\x57\x82\x9a\x21\x83\x15\xf8\x1b\xeb\xea\xe4\x45\x40\xfa\x12\xb6\xf9\x79\x71\x9a\x3a\xa7\xa6\x94\x75\x75\x07\xdf\xc3\x0e\x12\xde\x5d\x25\x12\x03\x55\x55\xb9\x7e\xbd\x4d\x28\xf9\x4b\x4e\x83\x21\xcd\x22\x22\xa5\x39\x72\xc4\x77\x0e\xfd\xd3\x7b\xfb\xf6\x80\xda\x60\xe1\xd2\x9a\x41\xea\xb7\xce\x8d\xf9\x89\x59\xcb\xd9\xc0\x30\x31\x4d\x92\xde\xf4\xbe\x41\x46\x94\xdd\x39\x9f\x8f\x1f\x93\x90\xd8\x95\x4a\x7a\x60\x33\xfa\xc7\x2f\xf6\xa5\x44\x4f\x6b\xf6\xca\xa0\xb8\xc9\xa6\x31\xf2\x31\x78\x4a\x44\x96\x38\xab\xb0\x69\xab\xf3\x19\xcc\xd6\x31\x54\xfa\xa7\x26\x91\x96\x09\xca\x71\xae\xfe\x38\x0c\x2a\x1e\x43\x8d\xac\x20\x84\xb8\x50\xc6\x28\x17\x04\x26\x0c\xd9\xc9\x93\x13\xaa\x9d\x1a\xc3\xe1\x5c\x83\xaf\x1d\xf6\x30\xcf\xe5\xf9\x46\x58\x6c\xb1\xfa\xe4\xf6\x2d\x47\xea\xa2\x30\x46\x09\xcb\x2c\x06\xf6\xd7\x3f\xe5\xc3\xcd\x36\xfc\xca\x29\xa0\x38\x56\xf3\x76\x69\xef\xaa\x1f\x65\xe0\x64\x9d\x5e\x94\x33\x83\x76\xa2\xba\xbc\xbf\xfc\xec\x4f\x8d\x09\x62\x29\xbf\xbb\xaa\xb1\xbb\x49\xa6\x44\x10\x9e\xc6\x3c\x9b\xaa\x5f\x61\xaf\x8f\x80\x4d\x82\x70\xe5\x0a\xac\x5e\x7f\xbf\x1d\x2f\x4c\x84\x2b\x8d\x51\x00\x47\x4a\x7f\x5f\xd5\x7d\xbd\xca\xf2\x5b\x73\x90\x81\xc2\xfa\xb1\x6a\x1a\x68\x10\x49\x3b\xfd\xae\x44\x70\x89\x8b\x45\x9f\xb5\x11\x44\xa4\x12\x51\x66\xa5\x8f\x0c\x84\x42\x82\xd5\x77\x99\x17\x54\x9c\xdd\x5e\x33\xcd\xb4\x0b\x22\x94\x46\x13\xe2\x4d\x36\x88\x70\x36\xe1\x40\x9c\x52\x8c\x7e\x7f\x5a\xed\x3e\x21\x60\xe7\xf0\xf4\xf9\x71\xbf\xd9\x3e\x6e\x42\x21\xab\x20\xb1\x52\xda\x27\x1b\xba\x91\x75\x6d\x88\x09\x12\x1b\x85\x9f\x4a\x3a\x80\xd1\x0c\x7a\xd1\x1d\x07\xd4\x5d\x77\xbc\xa4\xf9\x71\xb2\xe1\x0a\x92\x18\x12\x25\x3d\x15\x42\x55\xa3\x68\xb6\x17\xf2\x0c\x6d\x52\xe6\x2a\x69\xda\x1f\x88\x83\xba\xa9\xda\xd9\x45\x32\xa2\x31\xa6\xfe\x96\x2b\xa8\xcb\x39\x9f\xb2\x20\x19\x97\x99\xf5\xc6\xe2\x5f\xaf\x56\x44\x45\x0a\x02\x6a\xeb\x5c\x95\x4d\x85\x6b\x54\xbf\x4e\x2f\x7f\x55\x45\x19\xa7\x81\xeb\xcc\x31\x62\xde\xca\xa2\x50\x52\x7f\xeb\x53\x52\x82\x28\x4d\xe2\x24\x88\x70\xf6\x5b\x03\x51\x5a\x7b\xba\xdf\xa6\xe9\x35\xab\xe6\x09\x85\x99\xf0\x84\x20\x3a\x72\x55\x00\x3a\xc4\x43\x47\x25\x61\x82\x68\xe6\x48\xa2\x9b\xb6\xaa\x67\x36\x6e\x68\x11\x13\x15\xf7\x45\x1e\x13\x60\xe4\xf4\x46\x26\x71\xb0\x7d\x5b\x5c\x9a\xb7\x59\xb2\x46\x10\xa0\x32\x92\x21\xde\x77\x38\xb7\xfa\x50\x5e\x4e\xb3\x51\x02\xa0\x70\xd3\x09\x4b\xbf\x9f\x65\xb3\x56\x56\xc6\x0a\x7c\xb5\xc4\xb1\x5b\x3c\x9a\x3b\x70\x7e\xb4\x6b\x40\x69\xac\xc2\xd4\xf1\x85\x97\xb3\x8f\x12\xda\x59\x82\x53\xe5\x5c\x43\x0d\xc7\xef\x79\x31\xa3\x14\x10\x94\xa7\x0c\x41\x10\xea\xf2\xee\xeb\x61\xc2\x3d\x44\xca\x8c\x77\xab\x56\xad\x2f\xef\x6d\xfa\x83\x99\x93\xc0\xf9\xba\x7a\x7c\x5c\xef\x0f\xab\xc7\xc7\x97\xdb\x91\x60\x81\xa0\x42\x71\x2b\xbc\xba\x8f\x5b\x2b\xff\x86\xe6\xbe\xa0\xc2\xc4\x69\x90\x1f\xb8\x36\xce\x05\x15\xd6\x19\x05\x7e\x22\x2e\x90\x27\x09\x1a\x33\x37\xd3\xbe\x7c\xfa\x1a\x9e\x26\x89\x3c\xef\x7e\x5f\xa8\x3c\xdf\xe9\xae\x2a\xac\x04\x4d\x08\xc3\x5a\xfd\xe6\x72\x5a\x21\xa2\x00\xcc\x97\xbc\x6e\x2f\xbd\x9c\x7d\x7f\x75\xce\xb1\xb0\xf0\xa6\x72\xd2\xfd\x3d\x30\x37\x6c\x3e\x34\x31\x4e\x95\xd8\xc9\xdd\x7e\xaa\x7e\x3c\x5d\xf4\xdb\x53\x55\x77\x0e\xdf\x33\x96\x8d\x4e\x47\x1a\x4d\x69\x0c\x99\x57\x49\xae\x2e\xad\xec\xdd\x5d\x41\x53\x21\xd1\xb0\x47\x65\x80\x11\x8a\xeb\x7f\xa6\xbd\x90\x5a\xce\x3c\xc3\xfa\xf6\xe5\xe5\xd1\x95\x03\x92\x28\x5c\x25\xcb\x98\xf4\x92\x1b\xbd\x23\x77\x25\xf7\x20\x68\x26\x63\x16\xf4\x48\xab\xa2\x90\x2d\xd4\x3d\x47\x5f\xb8\x94\x64\x36\x70\x21\x8f\x97\x89\xe5\xf5\x81\x4a\x9b\x62\xfe\xc9\x81\x34\x06\x05\xd4\x7e\x96\xf7\xed\x24\xc2\x1b\xa4\xc9\x75\x5e\x95\xb2\x5e\x35\x4d\x8e\xe4\xdb\x72\x41\xaf\x4b\x50\x15\x3b\xb0\xf8\x9b\x6c\xee\x9e\x9f\x67\x43\x42\xdb\xcc\xa8\x01\xd8\xe9\x08\x6d\x7e\x65\xb1\x53\x48\xb9\x4c\xfa\xcd\x6c\x54\xe0\x1e\x9e\xcf\x2a\x82\xac\x84\xbb\xfc\x74\x2e\xe0\x29\xff\x39\x3c\xba\x55\xc2\x0e\x82\x74\x87\xf1\x36\xc4\x22\x96\x24\x03\xe8\xc1\xa9\x9d\x2c\xa9\x96\xf7\x4f\xc2\x48\x94\xc4\xfe\x43\xae\x8e\x55\x39\x58\x54\x53\x99\x44\xc1\x08\x55\x22\xea\x9f\x08\x67\xcf\xaf\xd4\xba\x04\x23\x82\x5b\x13\x56\x91\xce\x1f\x82\x72\xae\x00\x2b\x18\xd1\x14\x57\x6a\x9b\x9f\x9b\x90\x6a\x44\x73\xf2\x8a\xaf\x70\x34\x6e\x18\x31\x0e\x69\x0e\xed\x5b\x5b\x35\x7d\x11\x8a\x60\x34\x75\x1c\x07\x67\x04\xfc\x0f\xb2\x78\x82\x31\x2e\x70\x8e\x6a\x2f\xf4\xb4\x50\x7c\xff\x41\x0f\x31\xae\x82\x41\xf9\xe0\x58\x98\xea\x16\xea\xb0\x3e\x5f\x63\x6d\xfb\xd3\x2c\x7e\xe2\xdd\xcb\xed\xfe\x4a\x15\x44\x30\x16\xdb\x34\xea\x31\x11\x95\x9d\x78\x5a\x8c\xa5\x09\xc6\x54\x4e\x60\x72\xb9\x40\x08\x29\x18\x53\xd2\x05\xa0\x9e\x6e\x26\x76\x12\xe3\x24\x45\x67\xb0\xb7\xff\x97\xab\x61\x27\xc3\x9b\xf1\x84\xa5\x51\xe0\xf1\x42\x87\x6c\xe9\x99\xb9\x22\x56\x8f\xc5\x30\x83\x38\xbf\x6c\xe5\xec\xf1\xb8\x62\x99\xdf\xa7\x9f\x2f\x27\x5c\xa2\xeb\xf9\x2b\x70\x48\x07\x99\xb4\xd9\x58\x5a\x2e\xdc\x9f\x2f\xa2\x4c\xa4\x29\xba\x8b\x65\xd5\xca\x3a\xff\x5f\x40\xa1\xae\x89\x07\xcc\xe2\x24\x41\x90\xb9\xc1\xf2\x92\x97\x6e\xef\xfe\x60\xdc\xce\xbe\x7b\x2c\x63\x0c\xc4\xac\xcf\x6f\x30\x55\xba\x10\x2c\xd6\x12\xe9\x27\x7c\xee\x73\x42\x1e\x11\x9a\x58\x08\xda\x05\x07\x28\xcd\xa1\xed\x33\xcc\x82\x25\x91\xc8\xd2\x89\x82\xeb\x53\x65\x86\xa3\x2c\xc1\xcd\xed\xe5\xeb\xf3\x61\x58\x1a\x9c\x60\x77\x77\xa3\x83\x9b\x20\xd7\xe8\x8c\x1e\xcc\xdc\x5d\x03\x98\x73\x6f\x1b\x2c\xb6\xb8\xae\xb8\x13\x2c\x89\x13\xc4\xd7\xfd\xd9\x1a\xd8\x56\xdf\xe0\x54\x95\x8d\xcf\xa8\xcf\xde\x25\xa5\x02\xb3\xe8\x8f\xd5\xd1\x7f\xf2\xb9\x4b\xe7\x1b\x66\x84\x21\x0d\xc9\xe6\xf6\xe5\xf0\xd8\x07\x8f\x05\xcb\x52\x89\x29\x75\x5d\x9d\xba\xa9\xf9\x7c\x39\x41\x9d\x6b\xc7\xe8\xd4\x2c\x2d\xb8\x4c\x12\xcb\x02\xa9\xc3\xc7\x26\x5a\x3f\x10\x64\xac\x30\x43\x82\x85\x73\xdd\x8a\x80\xc1\x9a\x7d\x35\x8d\x22\x0b\x26\x13\x87\xb4\x55\x97\x77\x14\x5f\x59\x9a\x5a\x52\xba\x45\x14\x8d\x65\x17\xf2\x1c\x69\x5f\x09\xa6\x22\x13\xf8\xe0\x6e\x0a\xa9\xbf\x15\xf9\x98\x23\x79\xe8\x5f\xc5\x08\x2e\x80\x4d\x7e\x2c\x7f\xbd\x08\x6b\xed\x38\x77\x3b\xef\x21\x58\x99\x6e\x9d\xe9\x57\x36\xc3\x44\x42\xfb\x12\xd7\xad\xfc\x31\x9f\x9c\x06\x1c\x7c\x3d\x20\x2f\xc2\x89\x10\xc7\xc8\x8c\xa9\x2e\xef\xbf\x8e\x5d\x31\x88\x4d\x12\xf5\x2c\xa2\xdd\xaa\xe6\x34\xc2\xbe\xbe\x41\x89\xac\x45\x73\x3b\x82\x59\x69\x31\x3f\xe1\xef\x79\x70\xf6\x5a\xb8\xb3\x55\x2a\x0d\xbc\xff\xab\xed\x52\x96\x44\x30\x0b\x22\xa0\x27\x46\x01\x88\x5d\x7e\x9c\xa4\xf8\x96\xa1\x45\xdd\xd9\x31\xd6\x31\xb8\x92\x8c\x83\x27\x45\xf3\xf7\xe7\x51\x9a\x30\xb7\xc7\x3b\x4e\x90\x5f\x13\xa2\x8d\xbe\x1c\x8f\x32\x8d\x3c\x66\x9d\xbb\x9c\x97\xc7\x40\x49\x1f\x8e\x5a\x40\xc2\xf6\x1f\x90\x7b\xda\x58\xa7\x44\xe1\x0f\x13\x70\x1e\xc1\x3f\xaa\x4b\x5d\x06\xda\x37\x7f\x8c\x46\x2e\x28\x1b\xd6\xe6\x6d\x0d\x98\x1b\x34\xdd\xc2\x35\x5e\x92\xfe\x56\xe0\x8f\x53\xc5\x90\xf7\x15\x59\xcf\x0e\xfc\x50\x07\xf2\x4f\x57\x75\x1e\x46\x2c\x67\x84\x85\x4d\x3e\x54\xd9\x79\x02\xa7\xc9\xd7\xe0\xcc\x17\x31\xb9\x0c\x63\x28\xbb\x1c\x3c\x78\xce\xad\x8e\x93\xff\x97\xb3\x2f\xeb\x6e\x1c\x37\xbe\xff\x3a\xfd\x30\x0f\xdc\xb0\xf0\x51\x9b\xbb\x95\xb1\x2d\xc7\x52\x77\x4f\x92\x93\xa3\x83\xa5\x60\xf3\x67\x8a\x54\x48\xca\x6e\xe7\xd3\xff\x0f\x0b\x00\x37\xd1\x9e\xc9\xff\x25\x3d\x31\x41\x8a\x0b\x50\xa8\xe5\xd6\xbd\x7d\xe8\x50\x56\x56\x0e\x76\x72\x19\x92\x58\x81\x18\x0f\x21\xb8\x47\xda\xcc\x0a\xa6\x75\x3a\x37\x9c\x07\x0a\x53\x31\x36\xad\xe8\xc0\xa3\xab\x52\xc2\x4d\x95\x0d\x64\x26\x3f\xc4\xb6\xcc\xbf\x9b\x34\x00\xcc\x32\xf6\x7d\x9d\x88\xec\x9c\x9d\xfa\x49\x1a\xd9\xf4\x8b\xc9\xaa\xba\xd9\x9c\xce\x4d\xeb\x63\xfb\x63\xcc\x36\x26\xe7\xa5\x7a\x99\x7d\xdc\x54\x82\x97\x0d\xdb\xf5\x12\x07\xd3\x41\x2a\x04\xcc\xf0\xd6\x8e\xf6\x70\x34\x2f\x04\xd3\x38\x2f\xd6\x8b\xc3\xe6\x18\x87\xc7\xf5\x66\x75\x8c\x82\x30\xed\x8e\xeb\x18\x83\x8e\xd5\x00\x34\x71\x3f\x94\x2c\x9f\x31\xa1\x89\x30\x54\x86\xae\x93\x17\x93\x1f\x63\xe4\x04\x9f\xad\x9e\x93\x44\xc6\x56\x34\xcb\xab\xd7\xe0\xfc\xfc\x30\x13\x3d\xe3\x9e\x25\x9a\x50\x74\xcf\x94\xc8\xf3\x6f\x65\x03\xf9\x5c\x5c\x9c\x68\x0a\xa1\x8b\x0d\x1f\x84\xb2\xac\x6c\xf6\x9e\xbc\x76\x23\x49\x34\xb3\xac\x61\x05\xbc\xad\x44\xe5\x8b\x4b\x24\x81\xd8\x02\xc0\xa0\x40\x36\x81\x4f\xed\x5a\x02\x89\xcd\x81\x3b\x75\xb1\x7d\xeb\x13\xfb\x43\x3c\x24\x43\x22\x8a\x31\xe5\x2e\x49\x20\x25\x26\xec\xbc\xc6\xf6\x8d\xd7\x67\xdf\xd9\xfc\x65\x06\x4d\xd7\x9e\x21\x11\x15\xf5\x70\x39\x89\x07\xf1\x3e\xfa\xca\x86\x71\x2c\xdd\xde\x3c\x6e\x36\x48\x37\x79\xd8\xec\x0f\xf3\x55\x8b\xc4\x08\x43\xb4\x2f\xb0\x68\xf1\x3e\xe8\x84\x24\x24\x88\xf4\x40\x70\xcf\x36\x2c\x61\x16\x73\x7d\x95\x55\x20\x01\x95\xc6\xea\x70\x9f\xca\x57\x18\xb6\x22\xcc\x15\x85\x09\x09\x53\x61\xc7\x2f\xee\xbf\x6e\x6c\xa5\xd4\xd5\x4d\xfd\xaf\x87\x40\xb1\x17\xc5\xda\x98\xce\x13\x98\xf6\xb5\x7e\x9a\xec\x1d\xce\x84\x36\xde\xf7\xd4\x32\x77\xe2\xd7\xb8\xed\xc7\x0f\x61\x41\xe0\x34\x53\x1f\x5a\x63\xe7\xf3\x6f\xbd\xfb\x1d\xfb\xdb\x8b\x94\x0c\x12\x4f\x37\x51\x43\x27\xc7\x38\xc1\x2e\x11\xb4\x66\x48\xb8\x07\x02\x7a\x48\xee\xdc\x52\x22\x09\x0d\xb1\x35\x14\x6a\x25\xce\xf0\x0d\x01\x59\xfe\x90\x8a\x70\xf5\x1f\x6b\x68\x16\xe7\x49\x8e\x9d\x10\x88\x63\x97\x89\x72\xe0\xcc\x2b\x96\x3d\x42\x88\xb1\x0c\x30\x8f\x48\x5f\xd8\x46\xe3\x33\xa2\xe9\x93\xcf\x4a\x43\x5b\x47\xbc\x2d\xdf\x1e\xb3\xfa\x65\x29\x7c\xf6\x9d\xb0\x84\xc6\x03\xf0\xef\x61\x50\xbd\x3a\x94\xe8\xce\x64\x5d\x30\x49\x38\xb5\x34\x74\x9d\xca\xdf\xc8\x5d\x22\x3c\x65\x28\xa4\x66\x27\xda\x1a\xd6\xb3\x14\x5c\x84\x70\x21\x99\x27\x0d\xd8\x34\xcf\x4b\xbf\x9e\xfb\xfb\xe5\x02\xb0\x85\xcc\xb7\x9c\xfb\x5f\x48\x93\x54\xb9\x3c\xf2\xbe\x29\xbb\xe6\x7f\x42\x52\x1e\x63\x6e\xe0\x2b\x34\x3e\xd3\x8b\x98\xf2\xf1\x0f\x0b\xe5\xc4\x15\x91\x77\xa4\x68\x4d\xe2\x68\x73\x21\x52\x0b\x64\x9c\xdd\x6f\xbe\xde\x2c\xbe\xdf\x1e\x7a\x65\x3c\x42\x14\x24\x98\x70\x7b\x6c\xe3\x81\x06\x3b\x4e\x8f\xb6\x45\x38\xfb\xcf\x05\x8e\x03\xfe\xad\xe9\xf3\x6a\x25\x93\xf6\xb3\xfe\xf3\x6f\x37\xb8\xfa\x3c\x35\xae\x3f\xac\x09\xfa\x62\xde\xac\xdc\x5c\xa9\x3f\x10\x62\x02\x40\x14\x6c\xa7\x03\xd7\x53\xa6\x10\x62\x42\x8e\xf6\xcd\x35\x68\x16\x97\xba\x97\xb1\x27\x34\x08\x2d\x0c\x46\x68\x5f\xdc\x3a\x94\x1f\xd5\x6c\xc6\x66\x85\x86\x71\x82\xe5\x3d\x10\x55\xfe\xde\x7e\x26\xa8\xea\x61\xfd\xb9\x1d\xa1\x53\x27\xa5\x92\x15\x5b\x3d\x50\xea\x21\x34\xa4\x3a\x92\xa3\xb8\xc5\x2a\xad\xf8\xe3\x89\xb6\x7a\x6a\xed\x56\xb9\xf5\x66\x8f\x92\x54\xfb\x54\x1f\xa2\x76\xda\xd5\x3d\xfa\x48\x94\xc8\x00\x53\xa4\x96\x06\x77\xbb\xda\x25\xdd\xb9\x2a\xc6\xce\xf6\x46\xbc\x8c\xf2\xae\x94\x98\x30\xea\x09\x00\x31\xc4\xf9\xc8\x00\x8d\x0a\x7b\x1f\xb7\xb3\x11\xca\x98\x25\x71\xb6\xcc\xfc\x7b\x2c\xe5\x4c\x12\x16\x94\x69\x66\x33\x37\x9d\x07\xe7\xaa\xe7\x22\x9f\xec\xb1\xf3\x1f\x80\x8b\x50\x58\x66\xe7\x42\x65\x83\xad\x88\xa6\x21\x41\xaf\x72\x91\x37\x7b\xa4\x20\x75\x5e\xe7\xc3\xdb\x15\x99\xe1\xac\x33\x4c\x53\x6e\xc1\x09\xb6\x13\x79\xf3\xcb\x76\xd1\x4f\xde\xb4\x08\x88\xcf\xa6\xb9\xad\xae\xb6\xca\xa8\xe3\xbb\x14\x91\x41\x13\x2f\xb3\xf1\xce\xdf\xed\xcc\x54\x9a\x44\x39\x9b\xfd\x7b\xa3\xc6\x95\x02\xaa\x02\x5b\x42\xda\x2b\x51\x40\xa3\x7a\x44\x06\xa1\x2a\x02\x3e\xdc\x71\xbf\xfe\x9a\x8b\xc1\xa8\xa2\xd2\xa9\xd8\x61\x0e\x7b\x55\xd4\x53\x40\xc8\x07\x6f\x41\x09\xa5\x7a\x6a\x8b\x02\x3c\x47\x1f\xa1\x10\xa5\x48\xc6\x30\x54\xf6\x9c\xf7\x1d\x29\x10\xcb\xe8\x58\x0b\x03\x42\xcf\x23\x59\x09\x85\x94\x04\x0e\xd4\x0d\x87\x81\xba\x88\xff\x41\x93\x72\xa2\x7a\x42\x85\xda\x39\x8f\xf6\x28\x0b\x82\x18\x4b\x8a\x4d\x06\xd5\x4a\x9c\x27\xe6\x81\x05\x51\x82\xe9\xe1\x33\xc2\x4d\x01\x1d\xed\x61\x47\x9b\x1b\x16\x71\x81\x9e\xc0\xd7\x12\xfb\x1b\x86\x92\x18\x84\x25\x61\x44\x6d\x55\x1a\x9c\x68\xd6\x80\xe9\x85\xb0\x84\x47\x24\xe8\x98\x9d\xe6\xdd\x01\x46\x22\x81\x1a\xd3\x18\x12\x38\x10\xb1\x13\x5e\xf1\x53\x97\xd1\x24\xc6\x1d\xe7\xdb\xbb\xac\xb2\xee\xaf\x2c\xd0\xa9\x17\xb0\x1c\xf3\xb2\xb9\x01\x3c\x54\x3c\xf0\x15\x0d\x6f\xe3\xad\xfe\xe7\xa7\x9f\x87\x71\x4a\x90\x9f\x23\x2f\x9b\x06\x2a\xab\xc3\xb4\x11\x55\x4f\x5a\x4f\x18\x17\xa1\xc5\x43\x42\xa1\x8f\x77\xa0\xb3\xf6\x7e\x07\x06\x7d\xde\x3c\xb2\x14\x88\x1a\xf3\xfc\xba\x99\x0d\xf5\xce\x5c\x63\x89\x09\x13\x21\xc7\x3c\xf2\x62\x7d\xb7\x1b\xfa\x7a\x4c\x50\x4b\x83\xe8\x84\xe4\x10\x01\xf5\x81\x65\x18\x0a\x06\x8e\xdc\x0e\x26\x34\x41\x63\xa1\x44\xe1\xf1\x92\xcb\xf2\x1a\x16\xe2\x46\x4b\x29\x31\x6f\xf4\x96\x15\x7f\x13\xea\xe5\xa1\x6c\x3e\xeb\xe2\x24\x4c\x49\x1a\x8d\xd3\x79\x85\x98\xac\x43\xa6\x49\x8a\x2c\xdc\x59\xfd\xd5\xe2\xfe\xfe\x59\x9e\x64\x06\x6f\xd3\x61\xc2\x44\xd0\x55\x20\xc6\xd2\xac\x7e\x88\x8c\x31\x87\x24\x6c\x4b\x7d\x67\xc9\x99\xd6\x86\x9b\x7e\x86\x75\x39\x17\x7f\x1c\xa2\x00\xc3\xc3\xc5\xfe\xb0\x1c\xbd\x62\x13\xc7\xf8\xbc\x48\xdc\x66\xa5\x0f\x7b\x45\x2e\xc2\x0c\xa1\x58\x9d\xaa\x9f\xcb\xb7\xaf\xe2\x04\x9d\xf8\x3d\x61\x86\x5a\xa4\xa9\x37\x42\xc7\xd3\xfb\x38\x62\x66\x86\x1b\xec\x46\x37\x00\x0f\x22\xd3\x3e\x9b\x3f\xf7\x8f\x3f\x43\x6a\x24\x9f\x83\x53\xe6\xf4\xf2\x97\xf9\x48\x43\x6c\x6c\xa8\x78\x10\xa7\xa1\xc3\x53\x7e\x19\xec\x4c\xfe\x68\x62\x89\xf2\x6b\x68\x9a\x1c\x1e\x2e\xd7\xfd\xb5\xa3\x0f\xc0\x03\x92\x42\x8f\xaa\xb7\x98\x31\x54\xea\x99\xb7\x5d\x3c\x90\x80\x59\xd1\x6f\xbb\x87\xcd\x80\x24\x90\xf0\x90\xda\x0d\xb7\x86\xe6\x0e\x2a\x75\xc9\xa1\xb9\x6e\x6b\x22\x3c\x64\x16\x75\xe9\x32\x55\x4f\x36\x5d\xb5\x46\x81\x82\xc9\x48\x49\xb1\x89\xeb\x6d\xc2\x06\xef\x0e\xc7\x01\xc5\x0a\xa1\x45\xda\x8e\xf7\x82\xeb\x3c\x1f\x8f\xb5\x15\x1e\x91\x97\x3a\x2b\xa0\xae\x27\x57\x4b\xe2\x08\x91\x80\x0f\x50\x9e\x73\x18\xe5\x6c\x79\x92\x12\x6d\x7c\xd8\xe2\x65\xbd\xdd\x76\xc6\x69\x64\x81\x00\x79\x59\xbe\x5c\xce\xb3\xbd\x81\x7e\x64\x12\x1a\x6f\x22\xaa\x26\xab\x9b\xed\x64\x8f\xe5\x94\x53\xd9\x0b\xa8\x1e\xc5\x75\x72\x98\x33\xd2\xe9\x6b\xbb\x64\xb4\x17\xe8\x1a\x8f\xe3\x24\xc5\xb8\xdf\x35\x02\x78\x89\x1a\x7d\x35\x4e\xd9\x16\x4d\xec\xb1\xb3\x72\xbb\xef\xb6\x6b\xce\x3f\x7d\x4a\x22\x6c\x22\x6c\xb2\x33\xe2\x5b\xc6\xb7\x9c\xa6\x14\x53\x7f\x4d\x1b\x6a\xd6\xcb\x6c\xb4\x92\xb8\x08\x43\x6c\x8f\x6f\x57\x2d\xa6\x83\x3c\xf8\x7c\xfc\x66\x44\x92\x22\xc3\x90\x1e\xe7\xac\x3f\x28\xd5\x71\xc9\x01\xdf\xc1\xad\xa8\x3b\x0c\xa1\x3f\x04\x04\xe1\x70\x3f\x0f\x37\xfe\x4f\x3a\x34\xe8\x52\xf4\x55\xf8\x42\x83\x46\x5e\xdc\xba\x36\x97\xbc\xb3\x17\x5c\x83\x8a\x2c\x4b\xd1\xaf\xfd\x45\xba\xa6\x88\x6e\x86\x00\x4b\xb9\xe7\xa8\x40\x2d\x83\x45\xa1\x91\x8d\xa8\x35\xb0\x0f\x2f\xb3\xf2\x02\xed\x59\x56\x7a\xfe\x24\x7e\x3d\x54\xb0\x55\xe5\xb0\x1f\x8d\x70\x00\x2b\x5a\xd7\xf5\x02\xec\xa1\x99\xd9\x2d\x38\x98\x04\x5d\x34\x53\x56\x0a\x2c\xab\xe6\x54\x22\xbc\x1d\x94\x62\xe6\xbb\xa7\xcb\xef\xde\x8b\x61\x06\x3d\x0a\xaf\x07\x79\x63\x45\xfb\xdc\xe1\x34\x88\x84\x6b\xd4\x6d\x43\xfd\xdd\x19\x0a\xab\xe3\x5a\x95\xa7\x65\x59\xbe\x7c\x19\x79\x70\x69\x90\x06\xc8\x4a\xd4\xba\xd6\xfe\x0a\x61\x00\xc4\xe6\xba\x9e\xba\x0d\xd9\x15\xa0\xfe\x34\x35\x39\x7a\x63\x69\x48\x34\xca\x93\x58\x85\xd6\xbb\xcc\x51\xc7\x7f\x30\x19\xd2\x90\xd9\x06\x39\xbb\x66\xac\xd2\x41\xcf\x1f\x37\x49\x9e\xcf\x7a\x2a\x69\x98\x02\xe2\x49\x16\x15\x14\xa2\x7b\x20\x69\xed\x78\xbb\xc7\x5d\xe4\xef\xf0\xbe\xa8\x2a\x12\x5c\xf5\x8f\x4c\xcc\x4c\x1a\x6a\x85\x9e\x13\x0a\x41\x8a\x0f\x79\x88\xdc\xe8\x28\xb4\x85\xac\x1a\xf9\x87\x9e\xa0\xbe\x13\x85\x78\x9a\x7e\xfd\x34\x12\xc2\x6d\x92\x4f\x59\xdd\x7c\x2b\xea\xd9\x0c\x52\x1a\xa9\x80\x0f\x23\x8c\xc3\xa5\xd6\x0f\x55\xf9\xeb\xfd\x8a\x4f\xcf\x9d\x10\xb3\x94\x5a\xf8\x81\x7e\x44\x79\xaf\x69\x24\xe4\xc7\x09\x8e\x8d\xde\x50\xe8\x5b\xeb\x39\xf9\xb7\x14\x83\x42\x3e\x87\xdb\xdd\xd7\xe3\xd6\x69\xf5\x0c\x98\x03\xc7\x4f\x9b\x04\x14\x81\x28\x8e\x53\xba\x6f\xf4\x46\xa1\x07\x74\xcc\x8e\xf5\x70\x07\x4f\x93\x14\x34\xf3\xba\x6d\xbe\x4d\xc9\xf6\x31\x8f\xd3\xd0\xbf\xcd\x6e\x95\x69\x22\x9c\xfe\x19\x34\x43\xf8\xcc\xfe\x39\x33\xd3\x9b\x23\x26\x42\x9f\xfc\xf0\xfb\x61\xf2\x96\x68\x6a\x91\xa5\x0e\xc3\x89\x1f\x6a\x02\x50\x4b\xa9\xb4\x3a\x55\x3d\x11\xc4\x0d\xd8\x62\x55\x4f\x0f\x47\x52\x6a\x04\x22\xd4\xea\x91\x7a\x3f\x49\x19\xd3\xb8\xf9\xe4\xa0\x9f\xa6\x16\x36\x65\x00\x98\xc9\x84\x42\x95\xae\xff\x8b\x77\xd3\x8d\x07\x0c\xa3\x72\xeb\x89\xef\xcc\x20\x17\xea\x57\x2b\x0f\x29\x71\x0e\x81\xed\xad\x98\xd9\x95\x53\xde\x4e\x05\x57\x75\x85\x5f\x8d\x47\xe8\x0e\xbd\xfe\x94\x53\x5b\x6b\xc2\x54\xf7\xe1\xb9\xbc\xd4\xa2\xd0\x96\x72\xc6\x8f\xe0\x4c\x87\x43\xda\x45\x4b\x86\x34\xbf\x1f\xa6\x5c\x46\x9e\xc5\x71\x0f\xa2\xb1\xca\x94\xe3\x21\x69\xa4\x70\xef\xb9\x14\xd9\x7f\x5c\xe3\x7a\xf7\xe8\xa9\x08\x52\x1b\x95\xfd\xb2\xe5\x40\x5f\x06\xba\x14\x6a\x7e\x7d\x88\xd8\x6a\xcf\x2d\x7e\x2e\xfe\x18\x6e\xf0\xa9\xa0\x09\x23\x9d\x5a\xfc\x13\x54\xe7\x2a\xbb\x9a\xbd\xc2\x41\x80\x2c\x42\xe2\x52\xf7\xd6\x53\x26\x90\xfa\x74\xf9\x01\x4e\xe7\xbf\x82\x28\x4a\xa5\x8e\x50\x56\x18\x44\x55\x80\x2d\x3a\xfa\xeb\xa9\x90\x4b\xd5\x59\xe3\x2e\x0d\xb9\x3b\xbb\xd9\x34\x7e\x2a\x15\xd9\xb4\xcb\xf2\xf2\xfe\x3b\xbc\x7f\xe0\xb6\xa5\x8a\x06\xe8\xb8\xfe\x73\x7d\xd7\x77\x5d\x93\x54\x41\x40\x98\x87\x5a\x34\x9d\xfc\x10\x49\x75\x47\x25\x91\xe7\xff\x2c\x8b\x79\x3e\x30\x92\x6a\x12\x21\x0d\x77\xfb\xc5\x31\xd0\x1c\xd6\xd1\xff\x15\x06\xbd\x1f\x96\xf8\xef\xa6\xb9\x15\xaf\x07\x9d\xbd\x7e\x74\x55\xc1\x23\xdd\x31\xc1\x67\x0d\x2e\x35\x8c\xef\x5c\x83\xa8\x1f\x27\x2d\xa2\xea\x18\xfc\x5a\x67\xa2\x1a\xe5\xcc\x53\x0d\x01\x26\x28\xdb\x57\x2b\xaa\x4c\x60\x32\xac\x97\x07\x21\x29\x84\x60\xcb\xf4\x6d\xc0\x0f\x97\x93\x63\x49\xf1\x87\x0d\x8f\x3c\x66\x01\x21\x4d\x2e\x61\x35\x84\xb6\xa4\x46\x26\x28\xa8\xd0\x8c\xc8\x82\xae\x00\x90\x22\x88\xd3\xd8\x12\x10\xd6\xf5\xdd\xfb\xe0\x03\x88\x20\x0d\x54\xe0\x19\xfe\x5a\xb7\xeb\xa7\xa8\x10\xbd\xee\x68\x38\xfc\x30\x6d\x12\x5f\xa5\x3e\x3c\x57\xe5\x9b\x6d\xc5\xbb\x87\x37\xcf\x6d\x7d\x5f\x36\x03\x45\x6d\x22\x02\x10\xb4\x63\x6a\xbb\x01\x98\xc4\x67\x22\xa2\xd6\x41\xf4\xde\xf5\x14\x3d\x39\x19\x9d\x06\xb1\x5b\x21\x07\x51\xbf\x8c\x4d\x94\x88\xa4\x66\xd4\xc3\xd1\x77\xd5\x23\xb4\xcb\x4f\x35\x56\xdf\xd1\x8e\x4d\x06\x55\x52\x11\x73\x69\xd5\xdd\xea\x5d\xae\x3d\x4a\xd8\x1f\x53\x56\xf3\xfd\x6c\x1b\x44\x8f\x8e\x3b\x64\x02\xd6\x16\x09\x0f\xb0\x30\x69\x19\x61\x2e\x4d\xd3\x5f\x21\xd1\x31\x6a\xbc\xdd\x97\xaf\x62\xd0\xd3\x43\x04\x09\x84\xe9\x05\x06\xda\xe9\x84\x0b\xc6\x1f\x6d\x37\x01\x9b\xd4\x77\x0d\x77\x93\x18\x41\x90\x28\xf6\x34\x73\x5e\xe3\x7f\xfc\x96\x48\x94\x4a\xda\x25\x01\x90\xd9\xe9\x8a\x56\xd1\x0f\x25\x71\x32\x14\xe8\x1e\x72\x24\x10\x41\x74\x8a\xbd\x7d\x6a\xa0\xf0\xee\x8f\xd1\x40\xe2\xcb\x3e\x2a\x91\xdb\x32\xbb\xcb\xf7\xe1\xb4\x1a\xff\x0a\x25\xb1\x18\x42\x92\xdb\xf8\xb8\xac\x9a\xe9\xcf\x51\x4e\xd1\x16\x21\x59\xcf\xce\xfb\xea\xf5\x24\xa7\x2f\xa8\xb0\x72\xdc\x88\x9d\x04\xd3\xec\x5e\xa1\xfa\xe7\x6a\x77\x28\x47\x79\x60\x41\x45\x8c\xf1\xec\x23\xa6\x13\xef\x0e\xdf\x07\xf9\x69\x41\x0d\x51\x6e\x47\xbe\x45\xea\x21\xbc\x93\x07\xf1\xae\xc5\x35\xca\x60\xd6\xe3\x13\x8c\x18\x34\x78\xe7\x5c\xbc\xdf\xf4\xe6\x70\xbc\xf5\x8b\x54\x58\xe1\xa5\xe2\x72\xb2\x05\xdc\x1a\x71\xd8\x88\x58\x1c\xbf\x24\x21\x82\xd4\x4a\xa9\x6d\x56\x9e\xb9\x96\x08\x01\x06\xcb\x71\xc7\x3e\x5f\x9b\x9d\xca\x4a\x77\xf4\x09\x9f\xdf\xa4\x8c\x48\xa0\x3b\xf1\x96\x7a\x5a\xfa\x15\x92\xdb\xb9\x84\x6b\x7d\x31\x48\xe7\x0a\xa9\xc2\x81\x7c\x9e\xc7\xe9\xeb\x89\xa4\xf6\xbf\xe2\x7f\x5f\x65\x83\xc2\xf0\xdf\x73\x8d\x11\x42\x25\xca\x8b\x0b\xad\xc5\x3b\x36\xf0\x5b\xdc\xc1\xf8\x96\x15\x89\xb1\xd0\x82\xa1\xe0\x12\x9a\xbe\x7b\x8c\x08\x25\x02\x04\x9a\xdf\x96\xe3\x1e\x67\x7f\x58\x59\xea\x67\x51\x9d\x5d\x41\xa3\x0b\x3d\x84\x0e\x25\x22\x7b\x2e\x45\xe5\xec\xc2\xe4\x55\x40\x40\x3d\x9d\x66\xbf\x7b\x4c\x5e\x27\x84\x29\x8b\x3c\x5b\x5d\x4f\x0d\x4b\x04\xa8\x10\x55\x17\x5c\x72\x48\x68\xdd\x1f\x61\x58\x4a\x41\x1f\x06\xed\xc0\xaa\xbc\x54\x75\x7f\x26\x24\xd8\x89\x6e\x49\xbf\x6b\xdb\x99\xf8\xf9\x47\x35\x34\xc1\x6e\xf2\xbf\x2d\x46\xc8\x39\x61\x44\x8a\x74\xd3\x88\xfb\xd9\x34\xcf\x47\x77\x40\x06\x91\xc0\x8a\x38\x1e\xd8\xae\x76\x03\xbc\xac\x0c\x62\xe3\x8b\x1b\xee\xd7\x70\xd4\xf8\xcd\xca\x80\x19\x9a\x3a\xca\x81\xd1\xfd\xcb\x80\x47\x58\x59\x6c\x57\xe3\xfa\x71\x3f\x5c\xfd\xe3\xdb\x96\x51\x18\x38\xf5\x74\x9c\x42\xab\x4b\xdd\x94\x3a\x13\x3e\xdb\x36\xfa\x1a\x32\x8a\x01\x0d\xd3\xae\x18\x49\x91\x11\x19\xc9\x10\xb5\xba\xf7\x36\x71\xd3\x5c\xea\x2f\x73\xc9\x41\x19\x27\x31\x36\x4d\x6b\xf8\xf5\x7f\xa2\x1a\xa6\x88\x64\xcc\x78\xea\xf8\x35\x7f\x7f\x97\x50\xdd\x43\xf3\x56\x56\x2f\xb3\x16\x52\x26\x01\xe0\xce\xa8\x1d\xee\x64\xf2\x62\x12\xa9\xa2\xa8\xdb\x38\xa1\x72\x41\x85\xff\x29\x12\x4b\x64\xde\x3a\x94\x97\xaa\x10\x6d\x30\xd2\x8b\xcd\x12\x49\x08\xd5\x9d\xbb\x9e\xe7\xe8\x11\x2f\x4c\x03\xd5\x41\xfc\xea\xc6\x50\x99\x74\x44\x7b\x63\x76\x2f\xef\x83\x4a\x4a\x0d\x98\xa1\xc3\x8b\x4e\xac\xad\xc3\x22\xd1\x4e\x96\xe7\x56\x95\x63\x6e\x62\x79\x37\x42\xb2\x58\x20\x6a\x68\xbb\xda\x8d\x32\x98\x92\x09\x19\xf8\xb6\xd1\xa7\x2a\xc3\x59\xec\x68\x24\x06\xa9\x68\x37\x98\x07\x01\xbe\x78\x79\x79\xb7\xe4\xd2\x0e\xeb\xfd\x9b\xfb\x67\x4e\xd1\x8a\x48\xce\x65\x6c\x13\x5f\x42\x7d\x46\x39\xee\x86\xa7\x82\xcb\x6e\x67\x2a\xf3\x1c\xaa\x61\x0f\x8e\x14\x29\x88\x21\x80\x67\x6a\x9c\xff\x45\xfe\x3d\xf6\x2c\xa4\x54\x21\xc2\x15\x5c\xa6\xff\xee\x61\x42\x76\x30\x8c\x65\xa4\x4a\x13\xa4\x66\x53\x96\x72\xea\x50\xae\x37\x37\x93\x79\xa1\x59\x8c\x28\x84\xd2\x18\xa8\x6c\xc8\x77\xfe\x50\x30\x8b\x48\xcd\xa5\x8c\x7c\xe7\xf9\x09\xea\x46\x9c\xce\xcb\x77\xb4\x43\xa3\xe7\xd6\xda\x60\xeb\xc3\xf1\x68\x59\xc1\xc5\x09\x1a\xdf\x4c\xf3\x01\x9d\x04\x91\x10\x59\x66\x6a\x8b\x07\x14\x39\x0c\xe1\x5e\x12\x8c\xed\x65\x1d\xf2\x99\x0c\x33\x98\xfd\xae\x29\x4d\x24\x31\x19\x91\x8b\xba\xe9\xb0\xf2\xd2\x24\x31\xee\x31\x9e\x4b\xc3\xff\x99\x29\xcd\x06\x0b\xc7\xb5\x94\x4d\x76\x73\x69\x18\x68\xab\x54\x25\xf3\x4c\xdd\x58\x02\x8b\x07\xa8\xea\xb2\x40\x23\x36\xbc\x57\x15\x44\x24\x54\x1e\x6f\x9f\x15\x6e\xc3\x1f\xf0\x84\x10\x15\x46\x1a\xb7\x0f\x7c\xd8\x9f\x90\xfd\xec\x3c\x32\x15\x2a\x22\x6d\x8f\x3c\x54\x85\x68\x2f\x30\xb9\x19\x15\x01\xa0\xc3\xf3\x08\xd8\xba\xdc\xda\xe4\x42\x65\x22\xbf\x15\x72\xe0\x2d\xab\x38\xb0\x60\x8e\xa3\x6d\x32\x45\xde\xaa\x2b\x42\x2f\x3f\x36\x8a\xbc\x5a\xfa\x4a\x8c\x73\x9f\x83\x57\xab\x62\xa5\x51\x7c\x55\x89\x0e\xea\xff\x7d\x7f\xb0\x89\xf5\xc1\xb0\x24\x16\x58\x56\xf4\x1e\xd9\x20\x79\xa1\x08\x0d\x30\x3d\x22\xb4\xcd\x7e\x6e\x8b\xd7\x32\x53\x7f\x22\xad\x4b\x14\x51\x29\x06\xe6\x59\xfd\x60\xd5\x94\x40\x1f\x7e\x8d\x3d\x6b\x45\x65\x88\xbc\x07\xab\xc7\x87\xc5\x97\xee\x6f\x89\xed\xe7\xc9\xcb\x02\x6e\x00\x06\x40\x72\x37\x82\xc5\x02\xf1\xa3\x95\xe5\x8e\xdb\xf8\xe4\x62\x77\xdc\x18\x2c\xbb\x65\xf5\x83\xc8\xc6\x7a\x08\x6e\x04\x8f\x18\xb6\x1b\x63\x3e\xa6\xac\x9a\x1a\x39\x7f\x8c\x50\x30\xfe\xe8\x3c\xb6\xdc\x0e\x98\x37\x78\xdb\x36\x70\xba\xd6\xce\xf2\x43\x35\xc5\x02\x72\x81\x4d\x64\xcb\xcb\xfb\x68\x82\xa5\x61\x18\x22\x20\x51\xbe\x68\x13\x7d\xf9\x88\x3b\x8d\xa8\x94\x87\x9e\x61\x6c\x25\x4e\x67\x91\x3d\x15\x23\x12\x7e\xa2\x44\x12\x62\x21\x77\x04\xed\x9e\xcd\x35\x2a\x41\x09\xf6\x25\x9f\xa7\x0a\x56\x7f\x01\xac\xa6\x84\x4c\x95\x6b\x62\x3a\xa2\x04\x13\x0c\xa1\xda\x4a\x32\x02\x56\x10\xf2\x9c\x0b\x05\xab\xe7\xec\xfc\xfc\xf1\x9d\x48\xa3\xd1\x2f\xde\x3b\x95\x49\x57\x02\xc2\xc8\x73\xf2\x6d\x14\x44\x9e\xe5\xf1\xc6\xf3\x7c\x8d\x47\x68\x0e\xd8\x50\xbd\xdf\xac\x76\xf7\x6b\x27\xaf\x7a\xb7\xf8\xe3\xb8\x7f\x58\x78\x0c\x8b\x82\xc0\xaa\xb8\xbc\x59\x01\x82\xce\xfa\x75\xc7\x55\x8c\x2d\x61\x47\xa8\x55\x55\xbe\x8d\x26\x73\x12\xb8\x41\x26\x11\xa4\x2f\x56\x6e\x72\xb0\x1b\xd3\xd0\x74\x2a\x43\xba\xa8\xc8\x46\xad\x06\x9c\xa2\xd7\x18\x24\xa2\x0c\x13\xb8\x15\x19\x50\xcf\x3f\xca\x06\x6c\xc4\x7d\x53\x56\x3d\xa1\xd5\xfb\x38\x33\x35\xeb\xef\x28\x63\x48\x62\x4b\x8f\x5d\x2c\xe3\x2b\x6a\x76\x84\x0e\x03\x83\xcc\xe3\xa8\x4e\x2a\x6a\xd8\xae\x76\x6a\xc2\x83\x40\x74\xc4\xad\xd0\x39\x1a\xb4\x5b\xfb\x59\x46\xd9\x7b\x1d\x19\xc5\x45\x47\xed\xbf\x55\xe5\xa6\xd0\xf5\x62\xe2\x57\xeb\x58\x5a\xa2\x16\x2f\xd8\x39\xd0\xf5\xf3\x23\x94\xc1\x1a\x1c\x06\xb3\x2b\x51\x3f\x3f\x74\x8d\xff\x3a\x86\x40\x0c\xb9\x04\x0e\xe5\x5e\x18\xe8\x8e\x1a\xdb\x6a\xb0\x84\x26\xb9\x15\x5d\x6e\x43\x27\x51\x1c\x79\x15\xc6\xbb\x4b\x7e\x77\x4d\xaa\x35\x6f\x94\x74\x92\x44\x81\xdd\xc0\xdb\x77\x5f\xf7\x92\xc7\x03\xd2\x01\x9d\xa4\x89\xea\xc5\x66\x5a\xa7\x24\x3a\x86\x47\xaf\xd5\xde\xce\xa4\xe5\x3b\x09\x82\xa0\x1b\xaf\x08\xc6\x52\x67\x64\x6a\x86\xbb\x19\x1c\x85\x1f\x69\x22\x74\xcc\x8e\x99\xe3\x18\xfb\x33\xd6\xc6\xc9\xf9\x24\x64\x08\x7f\x3a\x5b\x50\x53\x74\x7c\xcb\x3a\xc4\x98\x26\x51\x98\x3a\x6f\xed\xb6\x14\xc5\xf8\x5b\x92\x58\x63\x07\xdf\x11\x7e\x65\x75\x63\x39\xaf\x7f\x87\x31\x5f\x30\xd1\x94\x58\xca\x52\xcc\xaa\x0c\x64\x4b\x88\xa6\xc2\x16\xa3\xdf\x50\x37\xa9\xe7\xe2\x21\x9a\x05\x0c\xb7\x8e\xdf\xd7\xc1\xd0\xa1\xd6\x2c\xe0\xc4\x3b\x8f\x8f\xa2\x78\xc1\x1c\xe0\x54\xa2\x83\x68\xc6\x43\x6c\x1a\x30\x59\xa1\xff\x61\xca\xea\x8f\xe9\x71\x19\xf9\x1e\x60\x57\x11\x9c\x2d\x22\x68\x26\x4d\x92\x0c\x5d\xb3\x29\x28\x68\x3c\x9c\x13\x4b\x93\xf0\x77\xd9\x7e\x52\x91\xfb\x34\xb0\xe6\x4c\xe3\xef\x59\x32\x2e\xa7\x9a\x3a\x39\x97\x5b\xa8\x93\xb2\x42\x0a\xae\xbc\x6e\x1f\x7e\xd6\x0b\xd5\x69\x2a\xb0\x8a\xb3\xca\x41\x14\xfb\x37\x10\xdd\x5c\x4b\x45\x0a\x30\x64\x95\x13\x15\xe6\xc1\xa7\x77\x3f\x21\xfd\x9e\xfc\xdf\x91\xb1\xd5\xa9\xd0\x76\xe7\xcd\xf3\xec\x3f\x97\x4c\x8f\xe1\x37\x3a\x6d\x63\x7f\x9b\x09\x1a\x7d\x30\x11\x74\xde\xf8\xca\x13\x07\x4e\x9e\x5c\x24\x11\x02\x75\x5d\x38\xba\xdf\x6c\xd6\xfb\xac\x18\xa8\x21\x4d\x9b\x84\xb5\xa0\x36\x45\x83\xaa\x4a\x58\x5b\xc0\x69\xe5\xda\xc7\x87\x14\x17\x5a\x50\x62\xf9\x50\x2d\x82\xee\xef\x6d\x30\x97\x95\x7d\xf5\x53\x0b\x25\x61\x28\xed\x71\x53\x95\xd7\xb4\xec\xf3\x0b\x4f\x40\x10\xbb\x68\xf4\xf0\x7e\xee\x5e\x85\x34\x80\x9b\xb6\xa9\xca\xd3\x23\x88\xfc\xcb\xb0\x10\xa8\x15\x0f\x28\x74\xf2\x19\x4f\x30\x6c\x76\xd1\xda\xc4\x89\xab\x54\x77\x29\xec\x31\x0a\xfe\x8a\xa1\x7d\xfc\x2e\x21\xa1\x81\xcb\x4d\xef\xde\x8a\x1b\x51\x3f\x5f\xe3\x29\x35\xf0\x20\x72\x83\x16\xff\xb9\xd8\xef\xb5\xb8\xe8\x15\x14\x4d\x3d\x5a\x9f\x20\x04\x92\x88\x6d\xef\x0f\x8b\x47\xdf\xb3\xaf\x4d\x68\x0b\x9f\xc7\xf6\x01\x67\x79\xeb\x26\xef\xc9\x18\xdb\x7c\xfb\x58\xe6\x70\x8b\x25\x7f\x77\x29\x08\x92\x08\x7d\xd3\xd9\xde\xa4\x31\x6e\xde\x9d\x11\x86\x09\x95\x03\xc2\x1e\xbb\x87\x1c\xde\xbc\x63\x09\xa1\xa2\xc4\xd1\xd1\x81\x3e\x36\xe5\xb1\x79\x86\xa3\x14\x85\x5f\x8b\x10\x71\x16\x04\xde\xf3\xc4\x3c\x5a\x56\x5d\xc1\x96\xc7\xaf\x15\xe2\x90\xa3\xa1\x13\xa7\xed\x47\xbc\xe8\x04\xe2\x38\xc5\xd5\xaf\xb3\x27\xa8\x9b\xb9\x94\x0c\xc4\x42\xc6\xed\x64\x2b\x94\x1a\xae\x12\x88\x75\xcc\xf4\x58\xf1\xbc\xdd\xc2\xb1\xba\xe3\x86\x10\x01\x68\xd2\x7e\xcf\x7a\xea\x4c\x02\x44\x51\x4b\xb4\x7c\xfe\x94\x9f\x01\x58\x60\xd5\x3e\x4e\xef\x07\x51\x65\xc6\x9f\xce\xc3\x48\x68\x0f\x50\xac\xa1\x6f\xea\x07\x1e\x01\xd6\x45\x6f\x2a\x80\xe3\x6b\xd9\xc0\xd1\x94\xd5\x51\x79\xa7\xe2\xb8\xec\x06\xc6\xa9\x4f\x4e\x7e\x83\xaa\x44\x79\xdf\xf9\xb8\x11\x52\x15\x21\xaa\xe0\xa1\x8d\xc8\xcb\xac\xf0\x72\x49\x04\x52\xa3\x22\x87\x83\x59\x0e\x88\xcc\xba\x08\xd8\xe5\x0e\x40\x24\x11\xd5\x3d\x0d\xe3\x4f\x47\x94\xc1\xa7\x65\xf1\xb1\xed\x02\x01\x06\x27\x4d\xe3\x10\x1d\x7f\xce\x69\x4c\x40\x18\xeb\x31\x3e\x41\xd3\x46\x90\x7f\x13\x1a\xfa\x2c\x82\xd3\xe8\x1c\x7f\x7f\x4d\x75\x40\xbd\xef\xb3\x2c\x0b\x3d\xca\x4b\x80\x4e\x19\xa2\xdd\x86\x4c\x22\x0b\xc4\xe1\x7c\xf0\xcd\x20\x8c\xd0\x99\x2c\x5f\xa1\xaa\x32\x0d\xab\x67\x51\x7d\xac\x63\x4d\x00\x62\x66\x65\x91\xd1\x61\xbc\x83\x5a\xcc\xb7\x93\x03\xa8\x8e\x23\x01\xe1\xa8\x76\xf5\xcd\x35\x06\x82\x89\x52\x8c\x0b\x70\x57\x7a\xba\x38\x81\x35\xc7\x8a\xfd\x09\xba\x17\x8c\xe2\x69\xdc\x6f\x67\xd8\x4a\x79\xf0\x79\x22\x30\x86\x63\xfa\x78\x9d\x89\x53\x59\xe8\x8f\xb8\x75\x27\x8b\xdf\x04\xd4\x36\xe6\xd8\xdc\xc0\x10\xc0\x6e\x02\x0a\x98\x19\xc4\xb8\x61\x79\x79\x47\x2c\xc6\x40\x06\x7d\x0a\x3a\x30\x81\x8a\x90\xec\xf6\x84\x52\xd4\xad\x9b\x3a\x75\x31\x4d\xc8\xd2\xa0\xe7\x89\x5a\x41\x0e\x72\x8e\x6f\xae\xbd\x6a\x2f\x88\xf7\x2f\xea\x7f\x21\x8a\x22\xda\x4b\xb7\x5a\x94\x5a\x79\x3d\xed\x66\x50\x83\xfd\x5e\x3c\xbf\x25\x0f\xf3\x3b\x26\xe2\x0a\x5d\x22\x2b\x5f\xee\xd7\xa5\x89\x20\xf4\xd5\xf5\x1b\xc4\xad\x8c\xa0\xe0\xa3\xaf\x6c\x22\x88\xf0\xbd\x22\x7d\xb4\xed\x42\x19\xd0\xe5\x98\x08\x24\x67\x5d\x7b\xf1\xc6\xb6\x4a\x7c\x15\xa7\xfe\xed\x47\x06\x12\x27\xf1\xbe\xc6\x66\x35\x5d\xae\x9d\x54\x72\x53\xce\xca\xc3\xfb\xbb\x8f\x43\x1a\x5a\xe8\x71\x3d\x23\x67\x3e\x4a\xc6\xf9\x33\xa2\x08\xc9\x10\xac\x0a\xf0\xb0\x76\x3a\x5e\xf5\x86\x30\xcb\xdd\x28\x2f\xd5\xa7\x04\x94\xc4\x90\x34\x88\xe3\xae\x3d\xfc\x0c\x55\xf3\x7e\x2b\x6a\xa7\xc4\x5b\xf5\xff\xe9\x79\xe0\x67\xd7\xab\x21\x20\x42\xe6\x58\x89\x8e\xc2\xa5\x1b\xdd\x31\x9a\x30\xe3\xf0\x87\xad\x1b\xed\x2c\xc9\x02\x23\x60\xac\x01\xfb\xa4\x58\x9f\x3e\x31\x94\x32\x04\xc8\x63\xbf\x61\x84\x6b\x64\x50\xf3\x30\x2c\x8e\x51\x96\x3b\xb3\x65\xb9\x39\x74\x93\x61\x5c\x05\xca\xb6\x75\x2c\xfb\x2d\xd0\xf0\x44\x23\x68\x2b\xab\xed\x1d\x74\x2a\x60\xd3\x42\xb9\x49\x03\x2b\x79\x51\x43\xd3\x5e\xfd\x5a\x0e\x96\x98\x34\x82\xd8\xb5\x29\x2c\x41\x4c\x02\x39\x23\x42\xea\xc3\x3d\x74\x7b\x9d\x86\x6a\x47\xc8\xe2\xf3\xb9\x46\x86\x02\xbb\x2b\xeb\xbc\x8d\xe5\x86\x5c\xb9\xf3\x98\x27\x23\xa3\x90\x93\x81\x1a\xc3\x4c\x5b\xb8\x91\x52\x60\x3d\x5b\x43\xee\x7a\xae\x5b\xf7\xee\x4e\x8c\xd2\xac\xe3\x1b\xd6\x86\x62\x29\xe9\xf4\x00\xd5\x1e\xf2\x1c\xdb\xed\xdd\x31\x88\x25\x16\x50\x9b\x41\xa7\x0f\xa6\xc0\xbd\x08\xaa\x1f\x68\xb8\xc1\x39\xea\xe5\x4d\x47\x42\xb5\x34\x08\x22\x83\x1a\xbb\x68\xc7\x16\x17\xd7\xf4\xe2\x0e\x86\xa1\x6d\x21\x13\x5a\x5b\x65\xf5\x39\x60\x06\x0d\x22\x11\xe2\xfe\xd4\xd1\x99\x75\x89\x7c\x1a\x44\xca\x92\x44\x7a\xa7\xe0\x11\xd4\x5f\x96\x8c\x71\x06\x92\x06\x71\x92\x40\xe4\xc9\xfa\x46\x10\x26\x8a\x8a\xe6\xc1\x20\x3c\xff\x51\xe6\x97\x13\x6c\x3c\x73\x18\x0d\x62\x2e\x11\x3a\x71\xca\x0a\x8c\xb0\x3e\xa5\x8c\xe9\xc8\x2f\xfc\x3f\x5d\x22\x71\xf2\xcc\xb1\x22\x28\x1d\x53\x9e\xa1\xa8\xcb\x4b\xa5\xa0\x35\x6d\x3e\x74\x73\x83\x92\x34\xf0\x7c\x9f\xad\x8d\x5a\xbe\x6f\xd7\x43\x02\x17\x1a\x24\x2a\x41\x62\xac\xe2\x72\x3a\x64\x39\xd4\xe8\x66\xf9\x3c\x07\x0d\x12\x93\x82\xe8\x2b\x3f\x03\x87\xb8\x3d\x26\x6c\xb9\xef\x19\xd4\xcb\xd6\xb8\x24\xf2\xa6\x8d\x7e\xc7\x04\xbc\x34\x20\xcc\x16\x33\xd1\xcd\xbc\x6e\x14\x1a\x3f\x18\x61\x1c\x5b\x7d\xea\x67\x11\x0e\x64\x70\x68\x40\xd2\x90\x59\xb5\x86\xfd\x45\x5a\x3a\x66\x98\x67\x89\xa1\x01\x11\x1c\x65\xcb\xd7\xc8\xbd\x0e\xd5\x37\xa1\x5e\x44\xf3\xec\x8d\x10\x0d\x88\xb4\xa4\xae\xfb\x1f\xd6\x48\x23\x42\x24\x08\x83\xf0\xcb\xe4\x42\x5a\xd3\x70\xd4\x26\xbe\x7c\x77\xb4\x7f\x03\xeb\x42\x03\x2a\xc2\x4e\x48\xeb\xa2\xb3\xe6\x11\xce\x65\xd5\x6c\x1f\x6e\xf6\xb3\xe9\x4c\x1a\x30\xad\x53\x3d\xc2\xac\xee\xcf\xa0\xb2\x81\x92\xd8\x70\x2d\xd2\x80\x27\x29\xc6\xc4\x67\xdf\x47\xd9\xc0\x76\xb5\xbb\x9f\x24\xd6\x06\xe3\xc1\x92\x1e\xeb\xa9\x93\x14\x76\x23\x4c\x68\xd9\xb2\x1d\xc4\xd7\x2d\xe2\x41\x3b\x18\x0d\xd2\xc0\x76\x6a\x3c\x41\x83\x02\x60\xef\x6b\x68\x44\x96\xd7\x1e\x94\x31\x7e\x59\xa9\x88\x31\x65\x7e\x29\x9e\x45\xde\xd4\x98\x33\xef\xd6\x72\x2a\x43\x6e\x7b\xde\xce\x17\x8b\xc8\x19\xb8\xfd\xed\x61\x89\x7b\xf4\x52\x54\xd9\xa9\xcf\xd9\xb7\x07\x34\xea\x3b\x6e\x36\x77\x43\x9c\x40\x7b\x00\xb0\xea\x55\xbf\x01\x4c\x31\x53\x93\xfb\x02\xcb\xc3\x9c\xc3\x2b\xe4\x88\x17\xbf\x9c\x27\xf9\x4a\x1a\x88\x84\xc4\x56\x93\x04\x1c\x12\xa8\xbb\x75\xc1\xd2\x88\x4c\x61\x84\xf5\x64\xa6\x08\xa9\x52\xed\xda\x6a\xc2\xbe\xc4\x4c\x03\x19\xd8\xc6\x2b\xf5\x9c\xe5\x76\xe9\x4f\x38\x47\x67\xf7\x50\x1a\xc8\x38\x8c\xdd\xaa\x59\xd4\x75\xa9\xb0\x93\xe4\x03\xc2\xfa\xc9\x03\x2b\x12\xc5\x16\x8f\x2b\xb4\x53\x34\x7c\xca\x4b\x29\xf2\x2e\x36\x6a\xff\xac\x45\x67\xc4\x34\x89\xac\xe0\x7d\x53\xde\x8b\xa2\xbc\xdf\xde\x7e\x19\xdf\x8c\xa6\x14\xab\xb7\x6d\xf8\x33\xfa\x6e\x5a\x59\xca\x73\x79\xb1\x2a\x6e\xd3\x1b\xfb\x90\x32\x98\x06\x10\x1b\x7c\xc0\x27\x54\x2e\x1d\xff\x1e\xa4\xa1\x4b\x6e\x15\x96\xa4\xca\x71\x4b\xfb\x9f\x35\x2a\x66\x49\xc7\xa2\x89\x1e\xee\x10\xda\xe0\x0d\xb8\xfb\xcf\x79\x1a\x07\x1a\x18\x08\xc0\xeb\x95\xfb\xe2\xfb\x00\x9d\x4f\xc3\x40\x92\xd4\x8a\xa2\x9a\xf2\x26\x83\x7c\xc2\x2d\x4e\xc3\x40\x59\xaa\x07\xec\x21\xc1\x8a\x84\x53\xc8\xa3\x61\x98\x58\x55\xae\x0a\x54\x1b\xb6\xcc\x74\x9b\xd1\x30\xe4\x21\x38\x36\x5c\xa4\xd9\x47\x50\xea\x6e\x86\x22\x8c\x86\x11\x28\xf4\x2b\x45\x1b\x48\xcd\x0d\x88\x49\x64\xc9\x58\x5b\x2b\x7d\xb8\x7d\x08\xfd\x8d\xc4\xa0\xd2\x0e\x0e\x97\xb5\x2e\xf0\xc0\x1f\xa3\x61\x92\xd8\x86\xa1\x65\x59\x4f\x20\x3b\x34\x4c\x48\x8c\x39\xec\xed\x7e\xb1\xf3\x7f\x23\xa9\x97\xfe\x2a\x74\x1b\x31\x1c\x4a\xab\x39\x36\x29\xb1\xd3\x90\x68\x0b\xfa\x72\xc9\x2c\xbb\x7a\xc9\x43\x7f\x75\x02\x21\xae\xe0\xf5\xe2\xf1\x77\xff\x37\x9a\x24\x8e\x97\xa9\x40\xcc\x4a\x56\x81\xde\x5f\x64\xad\xaa\x4c\x3a\xb1\xd9\xc9\x73\xd3\x44\xa2\xc7\x9a\xa9\xf2\x20\xaa\xa7\xce\x40\x84\x34\x01\xac\x09\xd5\x88\xd7\x82\xba\x29\xab\x21\x61\xd0\xa7\x99\x6c\x1a\x52\x4a\x41\x0e\x6b\xf3\xc3\xa5\xe7\xe7\x07\x35\x04\xbd\x97\x9b\xdd\xf7\xc7\xc3\xb7\xe3\x61\xbb\x79\x3c\x0e\x98\xbe\xfb\xc8\x81\x86\x2c\x36\xb6\xb5\x2f\x2b\xbe\x8c\x7e\x88\x09\x8d\x11\x87\xa5\xd5\xda\x1e\x76\x47\x27\x0d\xb3\x2d\xbe\xef\xd7\xfe\x74\x1e\x00\xb7\x11\x94\xe8\x83\xb3\xf1\x1d\xf3\x50\x20\x51\x65\x56\xb4\xd1\xc0\xa4\x05\xab\x1b\x23\xb1\xfd\xa6\x7e\x2e\x2b\xc4\x2e\xb8\xde\xd1\x31\xe9\xc9\xfc\x1b\xe1\x5c\x21\x99\x68\x56\x2f\x85\x9e\x9b\x81\x3c\x25\xf8\xca\xd0\x4d\x5a\x5e\xbc\x75\x09\xd3\x48\x23\x49\xad\xb0\x40\xb3\x6d\x61\x4a\x27\x8f\x3b\xb9\x40\x4a\x89\x76\xbb\xe8\xe3\x7d\x77\xb6\xb1\xbc\xd4\x59\x91\x75\xd4\x8b\xfe\x98\x24\x90\x0c\x01\x94\xa3\xde\x87\x79\xbb\x1a\x4a\x46\x64\xd4\xb5\x8c\x3d\x7a\xe6\x92\x91\xc9\x0f\x65\x6a\x45\xdc\x57\x1d\x4e\x61\xec\x5a\x85\x2a\xe6\xc8\xcb\x76\x0f\x6f\xdb\xd3\x94\x84\x8b\x86\x8a\x93\xd4\x65\xd5\x7f\x3f\x97\x67\x6c\x0d\x58\x0d\xd0\x78\x1f\xe9\x1d\xd3\x50\x47\xc2\xb6\xab\xd9\x45\x35\xec\xda\xff\xb0\x1d\xb7\xdb\xb0\x43\xad\x62\xcc\xe8\xb5\xce\xe6\x4d\x59\xed\xc5\xe9\x9c\xc3\x23\x3c\x65\xcd\x44\x7d\xba\xb3\x60\x46\x11\xcc\x48\xe2\xbe\x78\x0f\x6f\x88\x86\x99\x7c\x17\x63\x6c\xaf\xd4\xb9\x2a\x7f\xbd\xff\xef\xea\x4f\x93\xa4\xfa\xe8\xda\x51\x10\x5a\xa4\xb0\xcd\x2c\xb4\x01\xa6\x0d\xc4\xbe\x4c\x86\x11\x81\x58\x88\x47\x64\x6a\xc9\xb3\x57\xa8\xe0\xc3\xa2\x94\x3f\xc7\xd5\x99\x6a\x47\x86\xf3\xfd\x71\xfb\x65\x26\xe8\xa5\x51\x18\x40\xd4\x69\xba\xba\xb0\xcc\xea\xd2\xd6\x36\x52\xeb\x88\xc4\xef\xc4\x79\x72\x63\x61\x14\xd1\x4e\x65\x6c\x24\xdb\x4b\xa3\x90\x1a\xb7\x0f\xb7\x53\x2d\x8c\xfd\xdf\xa3\x20\xc4\x86\xa5\xc5\xac\x43\xec\x07\x45\xb6\xbe\xff\x54\xe6\x70\x72\xb2\xc0\xdd\x05\x08\x41\x2d\xce\xd3\xd1\x20\x84\xb3\xfb\xbb\x96\x90\x4c\x38\x97\x3e\x7f\x47\x71\x6c\x62\x33\xc0\xf1\xde\x95\x55\xf3\x24\x9e\xe6\x08\xaa\x68\x94\x44\x1c\xa1\x99\xd2\x4b\x28\x8e\x16\x4d\x94\xc4\x31\xf6\x6c\x8e\x59\xc7\x68\x94\x24\x69\xd0\xf7\xd8\x2c\x8a\xec\x24\xae\xd4\xf2\x66\x32\x22\x34\x4a\x0c\x45\x2a\xb3\xbe\x23\x69\x2e\x33\xe6\x06\xd3\x80\x85\x56\xaf\xd2\xc2\x5a\xe7\xa1\xb3\x34\xa2\x71\x88\x59\x71\xef\x0a\xdd\xc3\xdb\x27\xa4\xb1\xfd\x9b\xa2\x84\xe2\x92\xc6\x14\x03\x4e\xc3\x8b\xa7\xf6\xc7\xf2\x70\xf7\x1a\x28\x91\x89\xd5\x75\x69\xb7\x9b\xda\x4b\x99\x55\x13\xd2\x32\x1a\x51\x29\x18\xf4\x7a\xbd\xfb\xec\x09\x89\x20\x27\x0b\xdd\x0d\x66\x81\xa5\x08\x45\x52\x6d\xdc\x07\x97\xd9\x74\xca\x30\x92\x60\x8e\xa3\x28\x4f\x59\x61\xf1\xdd\xd7\xdd\x60\x34\x62\x2c\x25\x8e\x12\xa8\xba\x2d\x5f\x91\xf4\x79\xfa\x96\x58\x1a\x10\x9b\x17\x99\x15\x44\xa0\x11\x53\xb1\xb2\x29\xfe\xd7\x9b\xb2\x3a\x80\x38\x6d\x9a\xe7\x89\xff\x10\x31\x1d\xa3\xf3\x6e\xf3\xb0\x73\xb9\xcd\x39\x9b\xe1\xbf\x28\x0f\x93\x80\xd8\xd9\xfc\x47\x7b\xfc\xd3\x2c\x08\x8d\x38\xa1\xc6\x22\x0e\x4e\x6e\xa7\x00\xcb\x3d\xa3\x67\xc3\x95\x88\xa7\x4c\x05\xae\xef\xc2\x32\x56\xda\x36\xc7\xd2\x82\xef\x86\x29\x6b\x1a\xa5\x61\x10\xbb\xe2\xdd\xdf\x2f\x22\x47\x9d\x48\x47\x7d\xf1\x29\x4e\x87\x46\x69\xc4\x30\xc5\x3c\x94\xed\xfa\x84\x45\x6a\x72\x93\x82\x03\x31\x33\xbd\x8d\x98\x6b\xd9\xaa\x72\xf9\x3e\x80\xed\xd3\x48\xca\x18\xdb\xf2\x5d\x50\x67\x69\xd0\xbb\x83\x8a\xe3\xf4\xf8\x39\xd4\xa3\x19\xb7\xcd\xd2\x48\x9a\x10\x3c\x69\x06\xee\x8f\x18\xfa\x0f\xcc\xdf\xac\x05\x55\x12\x90\x67\x6f\xf1\x63\xb1\xbd\x5d\x2c\x6f\x37\xc7\xc5\xf6\x71\xfd\xb8\x7b\x38\xee\xbf\x3f\x3c\xdc\xfe\xc3\xdf\x82\x26\x34\xd6\x43\x16\x86\xfb\x5d\x77\x88\x69\xac\x73\xcb\xcb\xfb\xdf\xf7\x87\xee\xaf\x9a\xda\xf6\x51\xcf\xc3\xf1\x50\x95\x26\x6b\xba\xc5\x06\x91\xa1\x7d\x67\xa2\x95\x08\xad\xca\x93\x6f\xca\xf8\x93\x6f\x03\x89\xd1\x41\xd7\xb9\x23\xf2\xdd\xa5\x51\xe5\x09\x96\xef\x1b\x14\x2c\x1a\xbf\x9a\x38\x64\x29\x7a\x1b\x45\xd9\x64\xe6\xfd\x00\x75\x93\x9d\xca\x62\x10\xb3\x77\xe3\xc0\x91\xd2\x34\xb7\x58\x20\xb6\xe1\xee\x73\x05\xf5\x73\x99\xeb\x89\x6a\x84\x3f\x09\x64\x60\x83\xe7\xd6\x98\x7c\x42\x1a\x46\xe3\x28\x60\x81\xf2\x32\xe2\xed\xb8\x75\xf6\x9a\xd5\x13\x54\x35\x8d\x23\x1a\xa2\xdb\x75\xa8\x2e\x75\xb3\xf9\xee\xab\x96\x34\x8e\x78\xcc\xb8\x45\x1e\xa9\xa9\xd6\x9e\x1b\x12\x07\x8a\x38\xdf\xf9\x51\x98\x4d\x31\xf1\xed\xe3\x38\x64\x68\x99\xcd\xa5\xd0\x0b\x6d\x7f\xdd\x1f\x4a\x29\xd2\x20\x1d\x6f\xb6\x3f\x36\x87\x6f\xbb\xef\xfb\x85\x57\x0c\xa2\x31\x61\x21\x53\x3e\x16\xa9\x9b\xea\xd2\x06\x75\x75\x77\x14\x42\xcc\x15\xb6\xf6\x7e\x79\xc9\x72\x3d\x50\xa4\xfa\xb3\x64\xdd\xe4\x1d\x51\x66\xb9\xdd\x90\x6f\x66\x40\x3e\xd5\x97\x37\xfd\x40\x6e\xd5\xc8\xb5\xa5\x7f\xf3\x5d\x52\xf5\x12\x1d\x1d\xf5\x3c\xe6\xf5\xa1\x31\x05\x8d\x91\xe7\x93\x68\xe0\x4d\xbc\xef\xce\x50\x74\x09\xb3\x98\x25\x01\x76\xb0\x7d\x1b\x89\x5b\xd0\x98\x87\x31\x8f\x7c\x62\xb8\xf9\xee\x68\x7a\xf9\x6f\xbd\xb1\x8b\x39\x30\x4c\x92\xad\xb7\x9b\xc3\xfe\x0d\xa0\x7f\x2b\xdc\x58\xe4\x5b\x17\x89\x3c\x58\x89\x0c\xff\xe0\xa3\xe7\x4e\x63\xab\x27\xb4\xcc\x4b\xab\x59\x38\xc2\xa5\x8f\xdf\x91\x10\x01\xfe\x64\x2e\x6a\x37\x91\x36\xcd\x33\xee\x65\xc3\xee\xa1\x76\x1c\xb5\xe9\xf5\xda\xe9\x26\x8d\xdf\x88\x90\xc2\x53\x32\xff\xfd\x02\xd5\x7b\x57\x3a\xa5\xb1\x0a\x62\x04\x9e\xba\x36\x95\x4e\xbe\xa0\xbf\x07\x15\x32\xe4\x8a\x7b\x2a\x73\x7d\x33\xe6\x03\x99\xff\xb0\x2a\x01\xfc\xb5\x55\xf5\x7e\x6e\xca\xaf\x55\x76\xb6\x22\x87\xe8\x33\x7e\x34\x37\xc6\x93\x5b\x4b\x16\x4a\x9f\x73\xee\x88\x4e\x07\x89\xe7\x58\x4b\x91\x46\x9e\x69\x13\x77\xc7\xf1\x4d\x80\xd4\x58\xbc\xbe\x13\x59\xe1\x3b\x43\xef\xef\xfc\xd9\x60\x08\xf6\x69\x36\x4f\xd5\xde\xf6\x41\xd4\xed\x0c\x1c\xe1\x6c\x69\x6c\x28\xf5\xe4\x63\x1d\x11\xf9\x7c\xb2\x30\x36\xcc\x52\xf4\x64\x58\xea\xed\x95\x51\x27\x8b\xd6\xa4\x32\x19\xfa\x72\x22\x1f\xee\x0d\xb1\x11\x34\x71\xf5\x87\xfd\x4b\x96\xe7\x58\x77\x5e\x95\xf5\xd4\x12\x19\xc1\x85\xe3\x98\xed\x7b\x71\x1f\x84\x7a\x69\xc3\x9c\x39\xd7\x28\x09\x43\x6a\xb8\xd3\x38\xbe\x6e\x0f\xa5\x49\x18\x13\x8c\xc4\x1d\x03\xc2\xa1\xc4\x38\x7c\x32\x26\x15\x98\xe0\xac\xf3\x4c\x41\x48\x67\x30\x03\x34\x09\xa5\xc2\x4e\xeb\xff\xb3\x2c\x23\x5f\xc5\x09\x06\x24\xec\xf3\xb3\x3c\x89\x8c\x55\x1c\xda\xff\xf3\x4f\xb5\x01\x68\x12\x87\x0a\x65\x9e\x2c\xd2\x70\x71\x7f\xf7\xc1\x45\x93\x98\x23\xc0\xe1\x9f\xd9\x53\x96\x5f\x5c\x55\x84\x26\x09\x57\xa9\x53\x4b\x40\xa6\x9a\xf9\xb4\xe4\xf4\x5a\x32\x42\xb8\xe5\xf2\x39\x2b\x0a\x78\x11\x7f\xca\x13\x44\x93\x04\x74\x60\x57\xa4\x2d\x37\x3c\x82\x50\xcf\x9d\x19\x4a\x48\x10\xa4\x91\x9f\xe0\x2b\x0f\x86\xa2\x09\xe1\xd6\x76\xd5\xcf\xe5\xdb\xb1\x43\x45\x1e\x7f\x64\x6d\x70\x91\x95\x97\xfa\x98\x15\xc7\x0e\x85\xe9\x4f\x32\x01\xce\xe6\x63\x7b\x5f\x5e\xca\x6f\xb6\x87\xc9\x9d\x40\xb9\x85\x23\xb6\xe3\x37\x85\xfe\x07\x08\x3f\x05\x13\x96\x58\x9a\x9b\xb3\xc5\x94\x83\xe3\x9e\x70\x47\x79\xcc\x30\x1f\x24\x65\x39\x82\x54\xd1\x84\x4b\xa0\x81\xa7\xc2\x74\x4c\x72\x8b\x42\xb7\x1f\xff\xa1\xac\xb3\x0f\xa5\xe6\x68\xc2\x4d\x8c\x79\x13\x87\x30\x75\x6b\x75\xbc\x70\x92\x94\x0a\x9c\x9f\x65\x81\x0a\xfc\xc3\x7b\x4a\xa5\x45\x32\x9f\xc4\xaf\x35\xfc\xda\xf7\xb9\x87\x24\x55\x1a\xf3\x7b\x0d\xd4\xcd\x57\x2b\xc2\x89\x75\xf8\xee\xb8\x66\x58\xc8\x70\xa8\xc5\x7b\x78\xbb\x2f\x9b\x29\x54\x86\x26\x22\x08\x10\xb6\xf2\xf3\xdb\xf6\xb0\xb9\xdd\xee\x51\xcf\x7b\xfd\xfd\x71\x20\x3b\x40\x13\x29\xa2\x04\x7b\xcc\x6c\x16\xd4\xdb\xa9\x44\xa5\x12\x01\xc8\xb8\xc5\x77\x7f\x04\x86\xa2\x41\x97\x1a\xf2\x41\xae\xb8\x3b\x2a\x99\xaf\x57\x55\x42\xc3\xf2\xbd\x0b\xe0\x57\x03\x60\x9c\x1b\xad\x63\x83\x86\xce\x36\xe3\xcd\xfb\xee\x6e\x28\x50\x2b\xb6\xde\x71\xcf\x4d\x9b\x46\x69\x62\x78\xa8\x46\x48\x88\x99\xf8\x2c\x31\x22\x81\xa1\x15\xb3\x04\x39\xe3\xa7\x20\x01\x89\xe3\xce\x2d\x2e\xdf\x71\x5f\xaa\xae\xa9\xc3\x29\x09\x43\x41\x59\x87\x3c\xf8\x56\xea\x7c\x1a\x0e\x91\x30\xa2\x1e\x10\xbd\x78\xc2\x46\xe1\x4b\x8f\xdb\xf9\x17\xf9\xb7\x1f\x96\x04\x24\x1a\x57\xc6\xd7\x8b\xf3\xf9\x9a\x1e\xac\xcb\xc6\x90\xd0\x44\xa9\xe8\x98\xd1\x6e\xca\x6a\x91\xe7\x37\x1e\xbd\xec\x3f\x22\x89\x42\x11\x0d\xaa\x74\x7f\x13\xea\xe5\x5c\x4e\x8c\x32\x89\x44\xaa\xbb\x34\xcd\xbc\xce\xed\x6f\x93\x33\x1c\x47\xef\x1f\x50\x64\x5d\x35\x92\x44\x60\x59\xc9\xdb\x5d\xa7\xae\xe1\x9a\x42\x9d\x92\x38\x91\x58\xa0\xdf\xff\xfe\x38\x74\x62\x48\xcc\x04\xb7\xfc\x26\x2f\x50\xab\xe7\xb2\xcc\x47\x87\x93\x84\xe1\x1c\xb5\xca\xe7\x7b\xc8\x6d\x5a\x1e\xe9\x4d\xfc\x1a\xfd\x80\xfe\x62\x58\xec\x74\x57\x23\x51\x9c\x76\xdc\xbc\x65\xd5\x77\xb0\x52\x42\x44\x82\x4e\xc5\x43\xd9\x38\x4f\xc8\x1d\xa0\xda\x60\x67\xc3\x91\x1c\xc5\x6b\x53\x4e\xde\x20\xd7\x09\x36\xfc\x1f\xc4\x49\xd4\x83\x0a\x13\x49\x19\x43\x69\x17\x51\x14\xe5\xa5\x50\xed\xe7\x29\x1c\x31\x1d\xf7\x43\x04\x20\x1d\x65\x63\x05\x7a\xff\xb1\x29\xda\xe8\xca\xdb\x5b\x22\x02\x2b\xd3\xd5\x1a\x97\x02\xf2\x7a\xd0\x9a\x40\x89\x8c\x22\xd5\x51\x2a\xde\xff\x52\xfd\xdf\xa9\x07\x38\xba\xa6\xc7\xfb\xcf\x37\x0a\x22\x53\x81\xd1\xca\xdd\xee\x6e\x77\x44\xea\x6b\x34\x12\x23\xf6\x6b\x4a\x54\x22\xb0\xa9\x1c\xd9\xed\xcf\xbd\xe8\xfd\xe4\x62\x8a\xdb\x1e\xb6\xca\x76\xb7\xfe\xec\x7c\x86\x47\x50\xd9\x39\xeb\x6b\x2d\x44\x89\x04\x59\x78\xbe\xef\xd7\xeb\xec\x29\xeb\xf8\x79\x28\x51\xc6\x8a\xf1\x1d\x9e\x61\x7b\x3a\x95\x55\x23\xf2\x6e\x56\x6b\x99\x60\x18\xe0\xa2\x83\x7a\x51\xf8\x78\xb9\x46\xc5\xb1\x8f\x45\xb9\xc6\xf7\x09\x11\x80\xf3\x5a\x6e\x86\x9d\x70\xc3\xf0\x93\x18\xa6\x11\x90\x2f\x2f\xef\xdb\xa2\x29\xf7\xef\x85\x1e\x10\x9d\x52\x62\x8c\x0e\xad\xca\x15\xe6\xa6\x67\x51\x32\x94\x06\x31\x23\x0e\x7a\xd7\xfa\x59\x2b\xd1\xc0\x53\x59\x5d\x65\xd2\xdc\xe8\x90\x03\x96\x86\xb7\xab\xdd\x1b\xc0\x4b\xdc\xd1\x7c\x51\x1a\xf1\x20\x74\x16\x65\x99\x35\xaa\xcc\x8a\x2b\xd5\x1d\x4a\x23\x2d\xbc\x54\x6f\x17\x94\xf4\x82\x85\xa3\x25\x49\x63\x93\x60\x50\xbe\x3f\xe7\x59\xb3\xf9\xcf\x65\xd2\xe7\x49\x69\x12\x71\xcc\x65\x3c\x94\x65\x8e\xe4\x43\x4d\xf3\x81\x0c\x1e\xa5\x49\x9c\xc4\x81\x8f\xed\x1a\xd8\xb4\x11\x12\xe2\x6f\x93\xe9\x45\x65\xaa\xfa\xee\x8c\x21\x37\xc8\x2c\x56\xc1\x9d\x45\x92\x88\xba\x7e\x85\x11\x53\xf4\xf8\x89\x08\x50\x4c\x3b\xbb\xac\x08\x9a\x8a\x63\x57\xc2\x63\x7d\x09\x8f\xfd\xfb\xb7\xe9\x0f\xf3\x21\x95\xaf\xff\xdf\xce\x74\x50\x2a\x09\xbe\xfd\xc7\xec\x0c\x43\xa2\x0e\x4a\x59\x20\xd5\xa0\xb1\x69\x9d\xd5\xe7\x4b\xf3\xd7\xe4\x38\x28\x65\x61\x9a\xba\xd4\xfa\x4a\x9c\xef\x3a\x62\x00\x4a\x59\xc4\xd1\x43\x32\x00\xbd\x26\x08\xa5\x8c\x04\x98\x07\x74\x82\xbd\x59\xd3\x17\xd9\xbf\x7c\x5c\x16\xa5\x8c\xa4\x18\x95\x21\x7c\x34\xab\x6d\x60\xf6\x00\xd5\xb8\x65\x65\xfc\x36\x99\x66\xb4\xe7\x65\x7e\x84\xa7\x36\x4e\xec\x48\xd2\x07\x96\x8c\x72\xc2\xf1\x29\x9e\x2f\x08\x93\x19\x42\x3a\x28\xa7\x01\x6e\xaa\x0f\x37\x7f\x1c\xa0\x6e\x06\x36\x92\x72\x16\x63\x1f\xb1\x7a\x16\xd5\x13\x3c\x54\x65\x53\xaa\xb2\xdd\xcb\x3e\x37\x59\x34\x0d\x39\x9e\x27\xb4\x76\x0a\xb9\xf3\x0f\x90\x26\x5a\xdb\xda\x92\x45\x4e\x20\xf9\x7d\xaf\x02\x4c\xa9\x88\x6d\xce\xb2\xa7\x5d\x9d\x6c\xe3\x54\x9a\x50\xf6\x8d\xef\xab\x70\x32\x99\x55\x22\xb9\x25\xc9\x29\xc6\x3e\x0e\xd5\xb1\x85\x1e\x9c\xc5\xfb\xee\xd2\xfc\xad\x94\xf3\x51\x18\xd5\x84\x86\x58\xec\x13\x8d\xa5\x79\xf3\xf7\xa6\x53\xab\xb7\x30\x30\xc9\x0e\xed\xd4\x8d\x50\x49\xec\x32\x42\xb6\x8e\x84\x21\x55\x55\xfe\x7a\xf7\x60\xb7\xb9\x40\x95\x02\xb1\xf5\x30\x55\x9e\xda\x89\xba\x47\xc1\xa4\xd6\x9c\x0c\xda\x3c\xa6\xa7\xc8\x04\xe7\xe2\xc3\xa5\x99\xed\x95\xa0\x14\x20\x44\x3f\xad\x80\x37\xef\xcd\xdf\x86\x57\x98\xfa\x8f\xfe\x1d\x5d\x8b\x05\xd4\x2e\xb5\xbb\xf7\x75\xa6\x80\xf9\xda\x37\x0b\xb8\xc4\xf4\xd0\x09\x1a\xa1\x45\x23\x06\x7e\x33\x0b\x94\x44\xce\x97\x12\x33\xb4\x0b\xff\xe7\x30\x20\xd8\xc8\x0b\x8e\xa7\x79\x00\x2e\x1f\x76\xda\x50\x94\xaf\xb2\x1e\x9d\xe5\xff\x1e\x30\xc6\x51\x16\xb2\x10\x6b\xdd\x77\xdb\xfb\xed\xdd\xf7\xbb\x23\xc2\x38\x17\x77\xbb\xef\x5e\x79\x95\xb2\x38\x08\x63\x07\x2a\xfb\x76\x96\xf7\xa5\x86\x76\xef\x73\xc0\xdf\x59\xd8\x82\x3f\x91\x58\x18\x48\xed\x54\x04\x37\x95\x8a\x02\x8c\xb0\x2d\x3a\xbd\x37\x41\xac\x8d\xd8\xb9\x23\x8f\xb9\x02\x59\x77\xd9\xeb\xa9\xde\x27\x65\x89\x14\x1a\x3a\x0d\xc9\x59\x05\x52\xca\x48\x62\x73\x73\x76\xa2\x2f\x2a\xf0\xe1\x27\x23\x26\x21\x5d\x9c\xfd\xbd\xca\x26\x27\x52\x62\x9b\x34\xac\x41\x1a\x74\x21\xff\x49\xa9\x68\xde\x20\x32\x16\x25\x18\x65\x7e\x2b\x9e\x5a\x53\xb1\x1f\x70\x85\xcf\xbe\x3f\x16\x49\xdc\xf0\xf6\x38\xf7\xb3\xff\xc2\xa1\x74\xae\xd6\xff\xe7\xef\x27\x29\x1d\xe6\x92\x17\x8f\x87\xc9\x03\xf3\x58\x62\x4e\xc1\xe2\x63\x37\xff\x09\xb9\x5d\x13\xa1\xdb\x41\x42\x3e\x5e\xe2\x8c\x53\x01\xbd\x95\xc1\x52\xa8\xb8\x12\xfd\x77\x63\x53\x4a\xac\x44\x75\x8d\xd1\x17\xe8\xe5\xfb\xfc\x9a\x64\xc2\x51\x70\x59\x57\x0b\xb7\x68\x94\x84\x1c\x4e\x04\x37\x54\x47\x21\x46\x83\x8f\xbb\xdb\xcd\x1f\xfe\xb3\xea\x18\x52\x74\xc8\xe7\xc8\xfd\x28\xd3\xda\xf8\x36\x9a\x45\x85\x8c\x08\x93\xd7\x00\x2c\x8d\x42\x5f\x07\x6d\xac\x8c\xac\x9a\xa9\xbf\x33\x43\xa9\xad\x88\xb4\x4e\xd2\xce\xac\x27\x1a\xa7\x94\x19\x93\xd8\xb5\x7b\x76\x89\x45\xfb\x77\x1e\x84\xda\xeb\xab\x2f\x45\xd3\xe4\x23\xec\x2d\xe5\x81\x08\x3a\x81\x97\xbc\xc4\x98\xe3\xce\x7a\xa7\x30\x80\xa5\xcf\xed\x89\xbf\x8d\xaf\x63\x6c\x8e\xd4\x97\xfb\x1d\x0f\xef\x7c\x5d\xc8\x9d\x13\x86\x01\x92\xd3\xd8\x54\xcc\xf1\xa6\xac\x8e\xc3\x3b\x0f\x23\x4d\xac\x16\x6d\x53\xb5\xe6\x04\xcb\x00\x43\x72\x71\xca\x43\x12\xa2\xc1\x79\x28\x9f\x3e\x9d\xe0\x3c\x64\x96\x0b\x75\xb3\x5f\x2d\xaf\xd8\x74\x28\x8f\xc2\x18\xc1\x96\x9b\xc3\xb7\xe3\xe3\x66\xb5\xd9\xfe\xd8\xac\x8f\x77\x9e\x15\x9e\xf2\x28\xd5\xd0\xd3\x77\x6e\x9a\xe7\x99\x54\x1a\x8f\x8c\x85\x07\x7c\x45\xc9\x82\xec\x74\x39\x2d\xa1\x39\x0e\x18\xca\x29\x8f\x43\x8e\xcd\x70\xcb\xbb\xed\x6a\xb7\xf0\xf2\xfe\x0f\x55\xf9\x54\x89\xd3\xc9\x8f\x4a\x22\xc2\xfb\xa9\xee\x41\xad\xa3\xe7\x49\x78\x92\xc8\x89\x9c\x8a\x2d\xc4\x79\x2c\x7e\x37\x71\x79\xa2\x18\xa6\x50\x0e\xa2\x7e\x59\x95\xa7\x33\xea\x3a\xda\xf6\xe3\xf1\x03\x50\x42\xb1\x74\x8d\x33\xd9\x46\x1d\xf0\xb6\x79\x5c\x45\xc1\x27\x49\x3c\x4e\x39\x23\x4e\xb3\xc3\xb2\xd0\x39\xe4\xc1\xe4\x15\xb3\x20\xf2\x7c\x64\x87\x2c\x87\x35\xd4\xaa\xca\xce\x9d\x0d\x1d\x32\xdb\x51\xce\x68\xca\x1c\x23\x27\xd6\x2f\xfd\x9b\x61\xdc\x56\x62\x6c\x53\xb6\x07\x00\xd4\xdd\xe1\xd4\x36\xa6\xa9\xf2\x74\xca\x5c\x28\xee\x7c\x95\x91\x31\xe1\xcc\x84\x48\xba\x99\x83\x69\xc8\xc4\xb7\xe6\x69\x4c\x11\x36\x6c\xf1\x27\xfe\xda\x29\x48\x1b\xc7\x88\x46\x3d\xef\xa1\xd0\x7f\xc2\x4b\x4b\xb9\xe0\x01\xe6\x05\xac\x3c\xd3\x22\xcf\x0f\xe5\x39\x53\xdd\xcd\xca\x58\xa1\xff\xd5\xc3\x48\xb2\xb2\xf0\xaa\x9b\xf3\xba\x44\xfe\xcc\x44\x90\xde\xa5\x5c\x95\x79\x59\xa1\xe8\x54\x77\x65\x1a\xc5\x61\x4f\xe9\xb0\xd5\xfd\x6f\xa6\x21\xd2\xaf\x15\x97\xd3\xce\xac\x41\xe5\xa2\x02\x6d\x3b\x62\x77\xc6\x40\xfb\x9b\x0f\xb9\x28\xfa\xf1\x32\xb2\xb8\x22\xc4\x2d\x0d\x05\x7a\xb7\xae\x8b\x77\xf2\x95\x15\x0f\xb1\x5f\x65\xb5\xbb\xbb\xdb\xee\xf7\xad\xbf\xb5\xde\xfe\xf0\x97\x53\x9a\x09\xf0\x9b\xe0\xdf\x2f\xa5\xc7\xac\x53\xae\x59\x88\x0b\x6c\x20\x6e\xe7\xb0\xbc\xe3\xeb\x43\x12\x02\x9f\x32\x0a\x4d\xed\x3f\x07\x05\x98\xcb\xac\xe0\xb5\x7c\x01\x5f\x37\x5a\xda\x62\xd3\x28\xdb\x31\xbe\xba\x89\x23\x4b\xd0\xe4\xcb\x39\x77\x59\x81\x2b\xfd\xa6\xac\xee\xe1\x97\x15\x1f\x9f\x0f\xda\xb9\x61\xdc\xa1\xc0\x1e\xcb\x3c\xbf\x2b\x3f\x2e\x79\xf8\x13\x24\x43\x7f\x68\x20\xaa\xc2\xdc\xeb\x48\x03\xa6\xc2\xbe\xa7\xa7\xfd\x24\xd0\xdc\x66\xa2\x2e\x3f\x6c\x62\x1c\x99\xbb\x34\x4c\x58\x27\xc5\x69\x9b\x38\x26\x61\x6b\x1a\x12\x96\x38\x2e\xf9\xd2\xdc\x66\xbe\xeb\x82\xa6\x11\x81\x01\x6b\xb4\x53\xbb\xf2\x49\x95\xde\xaa\xa4\x11\x8f\x62\x07\x5d\xfc\x91\xc1\x1b\xe2\x29\x06\x84\x31\xed\x00\x91\xf4\xe8\x21\x57\x61\x19\x2e\xfb\x71\xd7\x90\x3b\x2b\x66\x9a\xf8\x95\x0f\x75\x7d\x57\x16\xf0\x3e\xce\x38\xa7\xb1\xe4\x96\x57\xa6\x9d\x8e\x0e\x23\xde\x1d\x4c\x38\x20\x2c\xd4\xde\xbe\xaf\xf1\xfc\xd5\x4a\xa5\xbb\x08\x09\x3a\x5e\x03\x0f\x6b\xd3\xdb\x42\x67\xaa\xc3\x4c\xa7\x84\xc4\xb1\x17\x72\xbb\x05\x51\xc3\x4c\x63\x1a\x4d\x89\xc3\xe5\x75\x2d\xce\x1f\xd0\x86\xfb\xe1\x3a\x65\x3d\x3d\xe4\xe3\x15\x63\x3a\x4d\x69\xc4\x93\xb4\x7b\x3c\xf7\x62\x1e\xe1\x9c\x43\x91\xd5\xcf\x6d\xe8\xb2\x6f\xca\x4a\x4c\xd3\xe8\x29\x8d\xa4\xef\x7f\xec\x5d\x0c\xa7\x4a\x3d\xfd\x05\xcd\xb0\x4f\xdf\xee\x3e\xbf\x67\xcd\xb4\xa4\x30\x7c\x67\xdd\x77\xa3\x31\x67\x91\x5f\xda\x0f\x56\x32\x12\x91\x41\xfe\x85\x51\x96\xf8\x9e\x5f\xec\x81\xc9\xea\x66\xc0\xa0\x4a\x53\x16\xf1\x58\x78\xbe\x4a\x04\x36\x40\x75\xdb\x71\x94\xd2\x94\x25\x11\x4a\x35\x40\x3b\x5f\x26\x33\x82\x13\xbb\x7d\xa3\xce\x96\xa8\xb4\xd5\x87\x1f\x20\xbd\x53\xce\x88\x05\x2d\xb7\xe1\xc0\x27\xbb\x59\xca\x53\xfb\x5d\x4f\xef\xfb\xa6\x2a\x8b\xa7\x6f\x1d\xf5\x02\x4d\xb9\x62\xc6\xf4\x5c\xca\x95\x9a\xbc\xe4\x34\xe6\x96\xe0\xb0\xf9\xf5\x0d\x44\x77\x5a\x4a\x2d\xfa\xe9\xe7\x1f\x5f\x87\x29\x8f\x54\x30\x85\x4f\x0c\xed\x56\xfc\x13\x64\x9d\xf5\xf7\x2b\x43\x62\x10\x20\x00\xea\xf9\x9f\xdf\xbb\xbf\xa6\x36\x43\xd0\x4e\xba\xe5\xfb\xd7\xaa\x2c\x4f\xdd\x21\x4d\xd0\xb2\xdf\x21\xf8\x61\x96\xed\xc9\x6e\xb3\xa3\xf9\x29\x4d\x14\x3b\x26\x93\xb2\x6a\xd6\xe5\x45\xe6\x80\x3c\x25\x1d\xd1\xe7\xbf\x27\xdd\xad\x34\x55\x61\x0c\x56\x6b\x16\x79\x33\x66\x04\x14\xdc\x40\x1d\x52\x83\xbd\x3f\x97\xe6\xb9\x6c\x83\x8a\xaa\x6b\x80\xa6\xa9\x56\x0c\x85\x06\xee\x96\x9b\x79\xd2\xbd\xf1\xb5\x20\xe4\x36\xdc\xb6\x0d\xf2\xdf\xb2\x66\x18\x5b\xa6\x10\x51\x7c\x0e\x9c\x7d\xe8\xbe\x2c\xf4\xa4\x04\x9b\x82\x88\xb0\x12\xaa\xab\xf2\xdc\x6e\x8b\x33\x5b\xb7\x1b\x69\xa8\xcd\xbf\x9e\xca\x02\x1a\x51\xbd\xef\x2f\x67\xa8\x86\x40\x8a\xd4\x08\x49\x31\x61\xbd\xfd\x63\x06\x6d\x9b\x1a\x13\x23\xeb\x2c\x9a\xf6\xcd\xfd\xfa\x18\xb9\x13\x45\x10\xa7\xb6\xa0\x88\xc2\xd7\xa3\xe8\x59\x04\x60\x8b\xf5\x96\x95\x04\x8b\xa7\x23\xa0\x93\x08\x43\x81\x9b\x64\x03\x75\x73\x23\xb2\xfc\xe1\x92\xe7\xad\xb3\x55\x5e\x9a\x61\x95\x49\x84\x91\xd5\x02\xaa\xa1\xe9\x78\x63\xfb\x3c\xc6\x5c\xda\xc0\x2f\x63\x11\x11\x65\x09\xc0\x9b\x7c\xec\x32\x89\x88\x05\xa1\xaf\x9f\xbe\xd9\x6e\x07\xff\x7b\x91\x08\x94\x03\xbd\xd8\xe7\xf2\x90\xc8\xd1\x5b\x11\xb1\x01\xac\xf6\x1e\x95\x28\xec\x9e\x3c\xb1\x52\x82\x04\x51\xe4\xfa\xb1\x30\x4f\x6f\x3d\x93\x9b\xac\xaa\x9b\x41\x60\x20\x48\x94\x06\x43\x98\xe0\x4f\x10\xe7\xb2\xf8\x53\x23\xef\xcf\x4e\x02\xee\x72\x05\xfb\x4c\xc3\x12\x9a\x0f\xf4\x7a\xdb\xa1\x21\xfe\xd0\xdf\xca\xec\x13\xbd\x3b\x3f\x98\x70\x2c\x01\x1c\x9f\xa0\xc0\x87\x7b\x14\x85\x2e\x4f\xcf\xa2\x7e\x76\x98\x8d\xf1\x78\x9a\x8a\xd4\x19\x3c\xaf\x5c\xb6\xef\xa9\x9e\xa8\x60\xdc\x36\x38\x20\xbb\x82\x23\x25\xbd\x8c\xda\x6e\x3f\x80\x52\x8c\x97\x8e\xe0\x10\x24\xae\x8f\xfa\xf6\xa2\x5e\x3a\xac\xd3\xe4\x76\xd2\xc8\x78\xdd\xed\x75\xa9\x7c\x1f\xcc\x1c\xa6\x40\x08\x4e\x90\x5f\xf1\xd8\xba\xcf\xe3\x29\x2a\xa4\xed\xe7\x35\x96\x74\xcc\x29\x18\x0c\xbb\x79\x84\x90\x76\x8a\x95\x45\xfe\xee\x2b\x10\x2b\x51\xac\xcb\xc3\x73\xe6\xb7\x57\x21\x23\x19\xc4\x9d\x3e\xd4\xbc\xad\x16\x32\x91\x21\xeb\xc4\x62\xca\x32\xaf\xfb\x44\xbf\x90\xba\xd3\x6d\x5f\x0e\xd3\xac\x42\x27\x96\x4d\xe0\x19\x51\xc4\x88\xee\x1d\x5f\x56\x0b\x82\x3c\x89\x03\x9c\xac\x80\x30\x40\x00\xe3\xf7\xfd\xfa\xb8\xdf\xdd\x1c\x8e\xab\xc5\x43\x77\x2c\x01\xc4\x32\xdf\x1c\x8e\xbb\x87\x8d\xad\x0e\x2f\x6e\x8f\x37\xdf\x3b\x6c\x95\x00\x62\x09\x2f\x7e\x17\x2f\x9f\x6c\x3e\x02\x9c\xb4\xa1\xed\xe3\x6d\xf7\xaf\xc5\xd3\x87\x89\x59\x01\xe0\x92\x5e\x22\x87\xf5\xa5\xfd\x4e\x9e\x9e\x17\x46\x6c\xca\x54\x98\x20\x40\x8e\xb7\xd6\xaf\x45\x26\x8f\xc5\xf4\x99\x0d\x67\xc2\x7d\xfd\xbd\x78\x05\x6d\xf9\xd7\xa6\xee\xbd\x30\xda\x38\x27\x37\x87\x21\x8d\xc3\xe7\x2b\xc3\x40\x14\x3a\x7b\x24\xaa\xa7\xe3\x24\xfd\x2b\x03\x16\xa3\x2e\xcf\x5b\x56\xb8\x14\x73\x57\xbe\x93\x41\xbb\x71\x5b\x8b\x50\x56\x1b\x9d\x35\xf5\xc0\xf0\xc8\x40\x59\x02\x9d\xcb\xf9\xa9\x42\xe6\x03\x30\xd9\xaf\x4e\x3f\x75\x0f\xaa\x74\xee\x3a\x1f\xe6\x1d\x64\xa0\x14\xee\x95\x9b\x5f\xcd\x8c\x96\xa8\x1f\xa4\x55\xe0\xb9\xad\xb2\x26\xfb\x2f\x14\xb7\xf0\x0a\x57\xba\x92\x7e\xb4\xb1\x89\x3f\xd7\x45\x3f\x6c\xf2\x1d\xed\xb8\x32\x4c\x00\xcd\xe8\x3e\x2b\x9e\x2e\xb9\xa8\xb2\x06\x37\xec\x38\xf1\xcf\x14\x92\xd0\xf3\x31\x6f\x90\x9e\x6b\xe8\x54\xcb\xd0\xd8\xda\xcc\xea\x71\xf7\x73\x8d\xed\x2c\x96\x02\x2c\xb4\x6d\x2d\x7e\x58\x14\x70\x6c\xf7\x38\xaa\x1c\x44\x65\x9b\x80\x44\xbe\x98\xc9\x78\xce\x4e\x44\x19\x85\xda\xb8\xba\x77\xbb\x11\x79\xb1\xdb\xf1\x33\x47\x4a\x5b\x2d\x5d\x8b\xac\x6f\x06\x1b\xb2\x8c\xa3\x14\x83\x1b\xa4\x5b\x6f\xd7\xd8\xce\x2c\xcb\xb2\x03\x62\xcb\x38\x06\x07\x77\xb9\x18\x93\xc3\xfd\x1a\xae\x90\x5c\x32\xd6\x09\x46\x8b\x47\xe1\x9b\x98\xe6\x6f\x36\x09\x6c\xd1\xd9\xab\x00\x14\x5a\x94\x93\x5b\x4d\x80\xa5\xca\x33\x06\x5a\x6a\x39\xf4\x51\x97\xef\xbd\x52\xcb\xe4\xaa\x84\x11\xe4\x8f\x79\xc9\xf2\xdc\xee\x6a\x93\xdb\xa3\x81\x15\x3a\x3e\x65\x45\x73\xb7\xf8\xc7\x27\xeb\x5a\xd2\x84\xa3\xb6\xf7\xd7\xcd\x7d\x70\x3c\xec\x0e\x8b\xdb\xe3\x6a\x90\xf7\x96\x94\x18\xec\xd4\x5b\x6e\x0f\x7f\xec\xfe\xd8\x75\x7f\xa6\x81\xe5\x20\xcf\xa0\x0a\xa7\x76\x54\x52\x1e\x25\x3d\xda\xee\xa7\xa8\xaa\xac\xac\x56\x3d\xca\x45\x52\xc5\x48\x1f\x0a\x59\x8b\xf0\x3f\x46\x42\xed\x35\xe4\x30\x91\xfb\xbd\xf0\xf8\x29\xdd\x1b\x9b\xb1\xb7\x39\x72\x1b\x24\xe3\x21\x42\xe9\x90\x8f\xad\x8d\x4f\x06\xbc\x70\x54\x32\xcd\x11\x84\xfe\x63\xfb\x70\x74\x75\x01\x7f\x88\x53\xcb\x1b\x69\x65\x65\x76\xe6\x0e\x44\xb3\x2d\xbe\x17\x99\x2a\x3d\x97\x3d\x95\x9c\xb1\x38\xf5\x5c\xcc\x0e\x2e\xeb\x13\x3e\x5d\xa8\x2a\xb9\x10\x48\xac\x52\xa3\x41\xb0\x2a\x0f\xa2\x81\x81\x7d\x97\x29\x35\x01\x19\x10\x3d\x76\x52\xfe\x96\x00\x66\xfc\x52\x04\x0b\xb1\x99\xf6\xe7\xf6\xf0\x6d\xfd\xb8\xf8\xe9\x2f\x22\x44\x8a\xd9\xc8\x85\xd6\x58\x47\x9f\x64\x83\xa5\x50\x31\xb6\x8d\x94\xaf\x50\x35\xcf\x55\xf9\x36\xca\xe9\x49\xa1\x18\xba\x77\x79\xa9\x5e\x96\x5d\xaf\x9c\x6c\xd7\xbc\xa3\x54\xaf\xb2\x27\xcc\x81\x96\x97\x42\x0f\xd9\x10\xfc\x48\xaa\x42\x47\x83\xb0\x14\xf5\x0c\x7f\x20\x95\x5a\x5a\xc4\x3b\xb2\x2d\xc7\xc7\xf3\xa0\xc6\x28\x4d\x4c\xf0\xf6\xad\xd4\x20\x0a\xa4\x6d\x0b\x55\x9e\xae\xf5\x46\xff\x6a\x35\x60\x62\x24\x4d\x42\x49\xcf\xd0\x31\x01\x4c\x49\x03\x11\x36\x7f\x74\x82\x39\x56\xf0\xd4\x1d\x56\x01\x11\xc2\x8a\x9d\x23\x20\x03\x13\x03\xdd\x31\xa1\xb0\x36\x63\x97\xc2\xbe\x11\x5d\x4a\x50\x85\x11\x4b\x7a\xe2\x76\x2b\x97\xd2\x1d\x4b\x99\x77\x79\xa6\x50\x35\x3f\x42\x1b\xdc\x04\x7e\x96\xd5\x0b\x54\xad\x8b\x31\x2d\x43\xfd\xa5\x27\x57\x51\x62\x7f\xa9\x3d\xba\x2d\x16\x55\xd5\xa7\xef\x7f\x1b\x9f\x38\x0d\x46\x54\xc4\x14\x42\x43\xbf\xdf\x6f\x0f\xfb\xec\x74\xce\xc1\xbd\xb8\xaf\x16\xe5\x3c\xb9\xe3\x38\x08\x50\x50\x06\xdd\xf4\x36\x46\xbe\x69\x8d\xc2\x5c\x9b\x88\x8a\xb9\x8c\x95\x27\xd8\xb9\xd4\xa3\xf4\x8e\x8a\xd3\x58\x50\x5f\x0a\xcc\xfe\x0b\xcb\x76\x55\xfb\x17\x97\x10\x85\xf5\x15\x51\x81\xe3\xc4\xb2\xc0\x87\x59\xec\x86\x4a\x8c\x42\xd5\xed\xa7\xd2\x17\x07\xc6\xeb\x49\x91\xd0\x12\xc1\x3d\x0b\x54\x0e\x2e\x2c\x50\x75\x10\x9f\xf9\x71\x2c\x8d\x86\x35\x86\xd5\xe5\x5a\x35\x83\x2a\x0a\x0a\x6b\x5f\x96\x03\xdb\xf5\x9d\xce\xe6\xfb\x14\x35\x09\x73\x24\x5b\xf7\xf0\xf6\x28\xfe\xfb\xd7\x42\x08\xc5\x22\x86\x55\x1b\xd3\x4e\x8b\x6e\x86\xb2\xc8\x0a\xb4\x16\xf0\xab\xb9\xa9\xca\xa2\xb1\x60\xb2\x85\xfe\xbf\x8b\x05\xea\x3e\x8a\x26\x2b\xbb\xd1\x86\x21\x65\xe1\x90\xa5\xc3\x72\x9c\xf9\x2f\xb7\x28\xb4\x55\xee\x18\x48\x88\x50\xc5\x09\x43\xbc\x8c\xbc\xbc\x5b\x86\x90\xa2\xd4\x7e\x09\xab\x54\x06\xd8\x05\xf6\x13\x8a\x9f\xa2\x18\xa0\x04\x94\x88\x25\xc2\x10\x3c\x95\xa3\xf7\x09\x3e\x2b\xd0\x28\xa1\xac\x3a\xd0\xcf\xe7\x71\xf9\x41\xc9\x34\xc4\x5e\xc6\xcd\xe1\xdb\xe6\xb1\xb5\xdc\xc7\xd5\xee\xfe\xf0\xb8\x5d\x7e\xe9\x06\x08\x44\xc1\xda\xf2\xde\x8d\xc8\x6b\x70\xc4\xbb\x83\xcb\x4b\x07\x9c\x43\xff\xdd\xca\x3d\x8c\xf2\x3a\x4a\x9a\x94\xb3\x09\x8f\xf2\xd7\xaa\xbc\xcc\x77\xba\x28\xc5\x68\xea\xe9\xe6\x51\xb2\xf7\xdd\xaa\x27\x4f\xa6\x9b\x4a\x03\x84\x6c\x1f\x0b\x78\x73\xbc\x05\xe3\x69\xa1\xb9\xd5\x31\x5d\xe4\xfd\xae\x82\x0a\xd3\xbb\xe2\xda\xe5\x9d\xf5\x07\x95\x36\x96\x11\xa3\xfd\x04\x7f\xcd\xe7\x52\xc0\x05\x75\x7b\xd9\x47\x0d\x16\xdd\x48\x85\xee\x84\x4b\x02\x66\x0d\x5c\x43\xc5\x15\x08\x91\x92\x01\x83\xdf\xd0\x8d\x54\x26\xa4\xc4\xa7\x03\x2b\x99\x8d\x2a\xcd\xd3\x55\x67\xb8\xb1\x32\x5c\x56\x8a\xbf\x2a\xb3\xe9\x0b\x35\x26\x40\xef\xca\xcd\x86\xc5\x1f\x7e\x36\x1c\x1f\x1e\xb7\x3f\x16\x87\x4d\xf7\xb3\x86\x84\x61\x07\x18\xc3\x9c\xd1\x4d\xf6\x0a\x33\xc5\x34\x1d\x90\x00\x91\x7f\xa6\xdd\xf0\x6e\xcb\x4e\x93\x87\xea\x80\x86\xc2\x3d\xd8\x60\x07\xd7\x81\x14\xa1\x25\xfc\x75\x95\xd8\x0f\x28\x08\x7f\x9b\x0a\x2b\x52\x1d\xa6\x01\x38\x25\xb7\x9f\xdd\x8a\xd1\x91\x54\x64\x24\x85\x89\xdb\xee\xb6\x30\x65\x47\xd6\x72\xf5\x69\x74\x9c\x06\xd2\x01\xf4\x67\x1b\x9e\xfd\x30\x61\x9b\x18\x6c\xb8\xe0\x27\xc8\xe3\x20\x23\xe2\x5f\xbf\x4e\x42\x41\x1c\x16\xed\xfe\xe6\xb0\x1a\x92\x54\x7f\x5c\x8e\xd5\x09\xa1\xa1\x4f\x15\x1d\x83\x23\x14\xf5\xa5\x82\xb5\xed\xa3\x41\x0d\xc8\x3d\x34\x87\xd2\xae\x4b\x7f\x8a\x62\x83\xe4\xb3\xa3\xd5\x45\x15\xa8\xf1\xf2\xd0\x89\x96\x18\xc2\x34\x20\x4e\xab\xf2\x74\x16\xc5\xfb\x20\x51\xab\x49\x92\x18\xdf\x58\xd2\x8c\x90\x42\x9a\xc6\xc6\x72\x4f\x65\x27\x4c\xea\xec\x64\x9e\x59\x82\x97\x21\x9d\x8c\xa6\x49\x88\xcc\x8f\x47\xec\xa2\xc2\xf6\x14\xd7\xf2\xdb\x5d\x48\x42\xe2\xa8\x2d\xb0\x6e\x05\xad\x57\xf7\x02\x1f\x34\x6e\x6b\xce\x62\x44\xcb\xf9\x17\xbd\xd3\xda\x96\x65\x67\x57\xa2\xe6\xd2\x4a\x0d\xb6\x21\x70\x79\xea\x76\xcf\x39\x9b\xa3\xb9\x09\xb1\xc9\xcd\x21\xc9\xa0\x68\xb0\xdd\xe5\xa7\xa5\x5e\xb6\x20\xd8\x61\x1f\xcb\xb0\x6a\xe5\x2e\x91\xc6\xa4\x47\xdd\x64\xff\x85\x23\xf2\x9c\x8c\xbf\xae\x17\x59\x6a\x47\x1b\x5f\x77\x71\x80\xc4\x45\x51\xbf\x41\xf5\x3b\x28\x25\x5e\x22\x42\x27\x0b\x29\xa5\x81\xec\x21\x29\x87\xe7\xd6\xac\xcc\x24\x77\x6d\x76\x98\xfb\x93\x52\x85\x80\xad\x7b\x78\xeb\xfc\xcc\x19\x85\xdc\xc9\x7b\x13\xa1\x25\x5f\xf5\xfb\xb3\xce\x6a\x04\xf3\xe9\x59\xb6\xd2\xc9\xb9\x4c\xa7\x76\xd6\x94\xd5\x93\x28\xb2\xff\x7e\x80\xa2\xd2\x42\x4a\xe3\x1c\x3a\x6b\xbc\xf7\x43\x3d\x13\xaa\x25\x09\x59\xd4\xd9\xbd\x97\x81\x21\x18\x5f\x47\xa5\x0c\x41\xb0\x5e\x40\xc7\xf2\x3f\xf9\x8f\xdd\xcd\x34\x4d\xb9\x0c\x7d\x1b\x62\x55\x37\x9e\x07\x6b\x53\xe8\x75\x5f\x5f\xd0\x5a\x01\xe6\x87\x7e\x66\x79\x3e\xd8\x76\x35\x04\x31\xae\x5e\xbb\xbb\xf9\xed\x51\x1b\x01\xde\xf5\xfa\x0a\x85\xa8\xca\x35\xbc\x22\xec\xa2\xce\x9e\xc6\xab\x0d\x82\x08\xb0\x55\x30\x2b\x5e\xa1\x68\xf7\xb4\xdb\x01\xdf\x35\x85\x30\xd0\x18\x1d\x6c\x57\x3b\xcf\xa4\x51\x8f\xd2\xca\x10\x46\x1c\xb1\x38\xcb\xcd\x08\x71\x09\x21\xe3\x58\xb7\x3f\x74\xfc\x21\x10\x0a\xab\xd1\x6d\x85\x10\x6c\xa9\xb4\xa7\x59\xa8\xa7\x6f\xd2\xdb\x28\x88\x92\xc8\x09\xf6\x57\xc5\x50\xad\x77\xf4\x89\x21\x62\xb6\x4a\xf3\x84\xec\xe6\x3d\x96\x79\xa6\x12\x06\x71\xa4\x11\x02\x71\x6c\x2f\x69\xcd\xaf\xad\x0a\x8f\xa6\xd2\xf8\xfa\x71\x6c\x23\x84\x27\x0b\x9d\x3f\x46\xbe\x9c\x0a\xb1\xb2\xe8\xec\x6f\x8b\x7f\x2c\x0e\x3b\xbb\x43\x2d\x1e\xbf\xee\xfa\xe3\x46\x79\x4e\x6d\x4b\xd8\xf8\xbd\xdf\x70\x20\x21\xcc\x04\x4e\x30\x6d\xe1\x39\xa7\x29\x24\x3c\x8a\x46\x2c\x24\x5e\x6e\x7a\x8a\xd7\xfb\x8b\x41\xd2\x6f\xd7\x5d\x0a\x90\x18\x8a\x7b\xaf\x4d\x08\x6e\x57\xbb\x59\x0c\x32\x10\x42\x23\xea\x73\xb7\x4f\x43\x68\xaf\x1f\xc0\x45\x68\x3b\x29\x1b\xa1\x9e\x87\xd2\x16\xde\x0a\x01\x8b\x19\x52\x1c\xda\xb6\xd8\x35\x9c\x4a\x55\x09\xf5\xde\x7f\xfe\x0f\x3d\x9f\xff\x29\xa3\x00\x2c\x31\x81\x9b\x05\x03\x34\xff\x00\x37\x01\x4c\xf1\x40\x7b\xa4\x08\xaa\x9c\x57\xcd\xa2\xd0\x6e\xc5\x7d\xc8\x31\xec\xce\xe6\x01\xc3\x6c\xac\xd0\x7a\x26\x73\x3c\x1d\x1c\x69\xdc\x18\xee\xee\xd0\x52\xf8\xbf\x12\x89\x31\x54\xad\xc4\x19\xbe\x89\x46\x3d\x77\x47\x8c\x65\xe4\x7e\x04\xd5\x88\xe2\xe9\x5a\x56\xc8\x8d\x4b\x63\x86\x9c\x9c\x42\x6b\x84\xaf\x7c\x40\xc8\x3d\x0e\x94\x20\x35\xc0\xbb\x9d\x73\x98\x27\x01\x11\x30\x2c\x8c\x58\xd2\xd6\x4b\x95\x81\x1e\x1d\x97\x94\x62\xba\xbc\xca\x9e\x9e\x1b\x12\x4c\x16\x9e\xd4\x14\x49\xda\x35\xbc\x3e\xc2\xa0\x9d\xa0\x3b\xdb\x30\x66\xb1\xd7\xaf\x20\xf2\x55\x59\xd4\xad\xbf\x70\xf5\xa2\xdd\x68\xa5\x28\x77\xf5\x84\xcb\xf9\xaf\x65\x80\x41\x41\xaa\xa5\x85\x46\x0d\xf7\x13\xf4\x62\x2e\x96\xad\xf2\x32\x20\x40\x03\x1d\x09\x24\xcb\xd8\xdd\x6f\x8e\x87\xdd\xef\x9b\xfb\xbd\xbf\x57\x1d\x53\xcc\x4c\x6e\xae\x3f\x0e\xa4\x89\xe5\x12\xcd\x5e\x01\x43\xec\xb7\xb2\xd2\xf5\x28\x70\x01\x10\x0c\x99\x98\x1e\x85\x31\x39\x0c\x84\xff\x3e\x8c\xdd\x01\xa4\xc6\x24\x73\x2e\x2e\x85\xea\xb1\x5c\x60\x62\x46\x5d\x8e\xf4\x61\xa8\x30\xe1\x0f\x1b\x8b\x52\xa8\xa1\x0d\xe3\xcc\xe5\x5a\xa2\x7d\xfe\x5d\x99\x20\x0c\x31\x6d\x77\x2e\x4b\xff\x85\x4c\x00\x51\x14\x76\x04\xb7\x87\xec\x04\x77\x5e\xce\x88\x9a\x88\x68\x4c\x13\xde\x66\x85\x16\xff\x7b\xae\xe6\x4f\x02\x9a\xb9\x46\x02\x13\xc7\x46\x45\x7d\x7e\xf8\x72\x5e\x41\x3e\xa9\x15\x98\x98\xda\x8e\x46\x9f\x3a\xc4\x2d\xf0\x5b\x89\x7d\xa1\xd3\xc2\x82\x89\xb9\x0d\x4f\x9f\xa1\x2a\xb1\xf9\xc9\x3f\x5c\xac\x24\xb1\xea\x3c\x2f\x1d\xdf\x3f\x35\x89\x50\xa6\x8f\x80\xac\x73\x38\xef\x2f\x98\x44\xdb\x68\xaf\xc9\xba\x4f\x67\x08\x8b\xc1\x81\x4c\x9a\x52\xe6\x42\xbd\xe4\x57\x24\x2f\x86\x06\x06\x21\x03\xfb\x87\xed\xef\x3e\x82\x31\x3c\xe5\x48\xa6\x70\x5b\x3e\x39\xd7\xd7\x6e\x4b\xde\xb3\xac\x3e\xca\x52\x1b\x0e\x56\x8b\xee\x6c\xb5\x28\xf7\x22\x07\x27\x0a\xe1\x33\xba\x26\x55\x80\x1b\xe4\xb1\xce\x4b\xe4\xa1\xcf\x9a\xfb\x89\xac\x3e\x35\x22\x32\xcc\xf4\xbc\x64\x05\x92\x47\x7e\xca\x5b\x64\x44\x9a\xca\x4e\xc4\x6c\x7f\x39\xe7\x1d\xbb\x9c\x51\xa1\xc0\x7a\xf4\x8d\xb8\x01\x47\xb4\xd4\x1f\x02\x9a\x78\x6b\x64\x9b\x6e\x11\x1b\x3b\x1e\x44\x6d\x7f\xc5\x43\xff\x54\xcb\xcb\x24\x27\x65\x94\x96\xd8\xa5\x74\xca\x8a\xe5\xe5\x7d\xd8\xd7\x60\x74\xcc\x43\xd1\x69\xda\x2f\x61\x12\xc5\x1a\x9d\x70\x64\xe8\x3b\x3c\x57\x00\x75\xf6\x34\xe2\x19\x34\x3a\xb5\x2d\x0c\xae\x49\xcb\x61\x8c\x2c\x0d\x85\x1f\x03\x3a\x86\xa8\xc7\xa4\x57\x23\xe5\x47\x6a\xc0\xa4\x18\x26\xd7\x97\x42\x97\x6f\xdd\x73\x99\x50\x31\xcf\x0c\x02\xc8\xef\x77\xe8\x80\x2d\xdd\x18\x32\x24\x1c\x76\x3f\xee\x2e\xcc\x82\x30\x0c\x30\xd6\x5d\x96\xe5\x0b\x62\x28\x37\xcd\xf3\x8f\xb0\x3b\x9a\x1a\x99\x38\x5b\x85\x39\xe6\xf9\x66\x83\xde\x17\x60\x41\x68\x40\xb4\xaf\xea\x6b\x29\xb3\xff\x0e\x3e\x02\x0b\x22\x30\x41\x8f\xf6\x3a\x97\xb5\xc8\x77\xd6\x89\x16\x43\xb0\x9b\x1b\x1d\x87\x26\xb5\xd4\xf3\xaf\x59\x0d\x55\x6d\x0b\x03\x4e\x74\xd9\x8f\xe1\xa1\x71\x60\xf7\xad\x2a\x3f\x60\xc7\xea\xc6\x2a\x24\xed\x42\xfa\x4b\x91\xdf\x94\xd5\x9b\xa8\x9c\xec\xed\xf0\x63\xb2\x20\x16\x01\xd6\x01\xff\x73\x29\xab\xcb\xa9\xfb\x2d\xc9\x8c\xeb\x2e\x48\xd6\xd9\x6b\xbd\x7b\x1b\x38\x51\x7e\x8c\x0a\xc3\x41\xa7\x59\xdf\xa8\x31\x9b\xda\x64\x41\xe2\x08\x87\xfc\x5e\x37\x91\x58\xfc\x6d\x7c\x5f\x89\x8a\x98\xf3\xf1\xf7\xcf\xd9\x79\x90\x29\x61\x01\x49\x13\xd5\xd1\xa5\xb7\x7b\xf9\xb0\xde\xcd\x02\x22\x62\xac\x8f\x9c\xb2\xa7\xa1\x6c\x34\x0b\x18\x49\x31\xc2\xcf\x05\xca\xba\x82\xb8\x7a\x1b\x0c\x02\x0c\x0d\xf2\x52\x78\x2a\x97\x9e\xbf\xe1\x5f\xfc\xdf\x83\xee\xa9\xc9\xfd\xf2\x94\xa0\xb1\xac\xc4\xa0\x7a\x79\xed\x45\xb3\x80\x0b\x16\xb9\x82\xc0\x63\x59\x7e\xca\x6e\xc6\x02\xae\x19\x96\x93\x2f\x85\x47\xab\xb5\xbe\xf6\x30\xe7\xed\x07\x1a\x6a\x11\xe5\xa2\xf6\xe0\xc8\x31\xf9\x1b\x0b\x84\xb4\xf4\x40\x88\xb1\xf8\x2f\x4c\x9e\x5c\x68\xd2\x03\x5d\xbe\x17\xca\x32\xdb\x0e\x09\xab\x58\x20\x03\xc6\xbd\x7e\xfa\x7b\xdd\xc0\xb4\x23\x79\x72\xf3\x32\x4d\x11\x1f\xd4\x54\xd9\x6b\x07\x3a\x63\x81\xd4\x32\xb6\x2c\x55\x1f\xb1\x83\xb2\x40\x45\x5c\x44\x2e\x78\xc9\x5f\xf3\x8f\xeb\x78\x2c\x80\x50\xa3\xb5\x93\x58\x0f\xfc\x21\x3a\x24\x3a\x0b\x20\xb2\x38\xfa\x4b\x61\x05\xbb\x5d\xc9\x74\x9a\xc4\x66\x01\x50\x9d\xb8\xc5\x7a\x7b\x51\x2f\xef\xc5\x80\xcf\x83\x05\x20\xa3\x84\x74\xa5\xaa\x76\xbe\x4d\xdd\x35\x16\x00\x48\xf4\x61\xb2\x8e\x01\xc2\xfa\x17\x13\xd2\x09\x16\x18\x13\x83\x6b\xa7\xc1\x52\x77\x3d\x2d\x70\xb0\x30\xa0\x01\x74\x8c\xdf\xea\x65\x92\xeb\x61\x61\x18\x02\x3a\x6e\x6b\x78\x7d\x2d\x1b\xac\xb0\x5f\x0a\xed\x80\x83\x6e\x4c\x14\x5a\x3e\xdb\x63\x65\x49\x21\x1d\xb3\xd1\xf8\x42\x51\x02\xf8\x81\xda\x8d\xb3\x12\x0d\x3c\x7c\xa0\x04\x31\x0c\x4a\x58\x18\xd1\x04\x37\xcd\x2a\x57\x47\x47\x54\xd2\xfd\x2a\x25\x9c\x76\x1a\x22\x50\x0d\x40\x3c\x93\x5f\x16\x2c\x32\x56\x4b\xaf\x34\x4e\x31\x6f\x68\x3e\xc3\x48\x25\x3c\xf5\x22\xaa\xcd\xb5\x2e\xc4\x78\x12\x84\x31\x91\x4c\x8e\x64\x9b\x5e\x60\xf0\xa1\x27\xa3\x93\x40\x2a\xcb\x1c\xef\xe0\x08\xd7\x64\x6a\x2c\x24\x49\x10\x24\x3d\x61\xb3\xfd\x9c\xbd\xa8\xed\xc8\x7e\x87\x84\x50\x6c\x33\xb0\x09\x9d\xa5\xd0\x4f\x53\xea\xb5\x81\xc7\xcb\x42\xc2\x2d\xa6\xaa\xce\x9e\x8a\xcb\x19\xf5\x28\xa6\x32\x22\x93\x9a\x13\x0b\xa9\xb4\x11\x6f\x5e\x16\x4f\x07\xa8\x4e\xcb\x8b\x7e\x1a\x02\x47\xfd\x9b\xa3\x26\x61\xae\xbd\x65\x75\xa9\xaa\x61\xde\x81\x85\x8c\x10\x9f\x39\xf9\xfb\xa5\x6c\xba\x0f\xc7\xa4\x44\x6c\xf3\x8f\xf2\x17\xe4\x0f\xb9\x98\xca\xe9\xf1\xeb\xff\x75\x67\xf2\x58\x09\x97\xa7\x5d\x89\x3c\xbf\x41\xee\xeb\x4e\xfc\x8e\x85\x9c\xda\xe3\x5f\xa1\xb9\x15\x35\xd2\xf9\x4c\xb3\x97\x2c\x4c\x43\x9b\xf7\xb1\x33\xf9\x9a\x97\x80\x85\x69\xcc\x49\x62\x7b\x7a\x16\xc5\x13\xa0\xd0\xc9\x5a\x34\x48\x12\x79\xb5\xd5\x84\xa9\x64\x36\x59\xf9\xe4\xa8\x0c\xdd\x5b\x98\x9f\x3c\xa9\xb6\xea\x17\x75\x53\x9e\x97\x22\xcf\xcb\xee\x75\xa9\x20\xb0\x69\xf6\xd6\xad\xac\x86\x2d\xbd\xfd\xd9\x9a\xc7\xb1\x67\x76\x3f\x36\x6f\x25\x72\xd3\x6d\xfe\x33\x72\x69\x58\xa8\xd3\x28\xe9\xda\x6a\x76\x66\xd3\xc6\x84\xfb\x2c\xef\x44\x52\x59\xa8\x45\x1c\x7a\xb2\x91\x07\x27\x7f\x86\x90\x15\x7f\x5c\x83\xa5\x70\x80\xd7\x7a\x64\x96\x43\x6d\x2c\x8f\x4d\x83\x65\xb5\xe3\x73\xd6\xdd\x3f\x98\x00\xdd\x00\x70\x3c\x1e\xc7\x4a\xf4\xdf\x1c\x8c\x8a\x2d\x72\xd6\x54\x50\x3f\xff\x14\x59\xf3\x20\xb2\x6a\x09\xcd\x76\x5d\x2f\xdf\x2d\x65\xf8\xd4\xfb\x63\xa1\x51\x61\x12\x8f\x24\x49\x87\xc9\xaf\xf6\xb8\x24\xa2\x0b\x5c\x1d\xca\x6e\xf4\x79\xa2\x20\xb6\x54\xd4\x27\xf1\x02\x43\xc7\x90\x45\x01\xe5\x58\x58\x7d\xf3\xcb\x01\x91\x51\xad\x69\x73\x9a\x79\xdd\x40\x05\xa1\xcb\xe9\x1f\x7e\x1d\xca\x47\x2f\x5b\xfe\x27\xf9\x1d\x77\x76\x18\x86\x68\x2e\xbe\x5b\x8c\x92\x90\x59\x9e\x35\xef\xb6\xc1\xd4\x0f\x49\x04\xaa\x0f\xb8\xb6\x62\x07\x9c\x76\x8e\xc6\xf8\x71\x42\x6a\x1b\xfe\x11\x63\x98\xa9\x3d\x14\xba\xfb\xac\x51\x98\x1a\xcc\x02\x6c\x9e\x4d\x56\xd5\xdd\x83\x86\x20\xa5\x40\x38\xeb\x0b\x14\xf7\xe2\x04\x8e\x09\x7e\x68\x26\xa2\x48\x70\xcc\xf8\xb6\x5f\x0d\x67\xfd\x5a\xbc\x77\x68\x3a\x16\xc5\x11\x51\xac\x5b\x35\x5d\xf7\xa3\x3f\x4a\x18\xc2\xdc\x0f\x97\xa6\xac\xfa\xed\x37\x8a\x53\xab\x3b\x5d\x43\xd3\x59\xb3\x99\xd4\x20\x8b\x92\x30\x45\x16\xd3\x7f\x42\xf5\xf2\xa5\xff\x9b\xe0\x5e\x0e\xf2\xbc\xb4\x7d\xf0\xd3\xf3\x94\xe1\x16\x1b\xb1\x5a\x7c\xc0\xbd\xc4\x22\x42\x02\xdc\x29\x30\xd0\xfb\x3f\xa1\x5e\xe6\xd7\x66\x44\x24\x47\xdc\x5f\xbb\xd1\x2d\x9e\x2a\xe8\x26\x00\xd1\x5c\x88\x7e\xab\xd1\xad\x93\xb8\x68\x46\x84\xc7\x93\x4b\x51\x25\x15\xef\x70\x72\xed\x63\x3b\xab\x30\xbe\x33\xaa\x23\x45\x3c\xe6\xdd\xb8\x1d\x6c\xe2\x27\x46\x2c\xb2\x5c\x88\xad\x27\xb9\x6a\x37\x08\x4b\x03\x56\xfa\xbb\x63\x89\x90\x1e\xe8\xd8\x58\xc1\xa6\x65\x79\x79\x7a\xfe\xdc\xdd\x8b\x18\x23\x60\xfc\x4c\x12\x0d\xf4\x8c\x20\xe2\x1d\x30\xa4\x1c\x62\xd8\x3e\x4a\xf3\x7c\xbc\xf1\x44\x3c\x0a\x10\x94\xf1\xbb\xc8\xb3\xe1\x7e\x1b\x71\xa1\x90\x85\x60\xff\x80\xa9\x9d\xee\xcf\x5a\xe3\x62\xff\x2a\x4e\x70\x93\x15\x59\xfd\x7c\xf5\x25\xb9\x91\x08\xe6\x78\xdc\xdd\x6e\xb0\x7f\xf8\xfb\x83\x3f\x3b\xa5\x81\x76\x32\xe6\xdd\xfe\x36\xc5\x80\xb3\x28\x4d\x55\xe0\x12\xdc\x8e\x61\x60\xaa\xca\xc7\x22\xc1\x62\xd2\x57\x74\xd6\xa5\x42\x22\xbc\x87\x32\x1f\x23\xa2\x59\x24\xd2\x04\x3b\xc2\x16\x55\x0d\x85\xc8\x5f\xeb\x3b\x51\xac\xb2\xa6\x5b\xd6\x42\xd2\x2e\x2c\x73\xf0\x92\xd6\xa3\xfe\x56\x8e\x6a\xbb\x7e\xb0\xb2\x74\xe3\xed\xf2\x47\x8d\xd9\xc9\x8f\xc9\xd8\x76\x4f\x7f\xdd\xed\x6e\x17\xc7\xef\xf7\xdb\x83\xff\x19\x99\x5a\xc2\xd9\xd6\x1e\x37\x3d\x18\xff\x28\xdf\x8f\x55\xf9\x36\xf9\x19\x45\x43\xe8\xc2\x99\x85\x2e\xcf\x0d\xe8\xc5\xaf\xcc\x39\x3d\x7c\x10\x6f\x46\x2a\x15\x01\xd8\xde\xaf\x73\x56\xcd\x13\xd5\xb1\x48\x19\x86\xc1\x00\x76\xd2\x91\xc9\xaf\x69\x2e\x3c\x9d\xc5\x3a\xab\x40\x35\xa5\x6d\xe9\x98\x5f\x7f\x10\x24\xc4\x25\x16\x8f\x67\x47\xe3\x73\x54\x6e\xd3\xfd\x0b\x13\x0e\x42\x20\x91\x67\x59\xff\x91\xc1\x9b\x7b\x43\x71\x10\xa5\x4e\x36\xb9\x6a\xc3\xed\xf9\x9a\xdc\x38\x0b\xcd\xe2\x80\x32\x11\xfb\xab\x61\x0e\xba\xbb\x1c\x44\xa1\xbb\xcf\xbd\x55\x1d\x51\x2f\x63\xda\x1f\x37\x30\x4a\x22\xcc\xe7\x9c\x73\xf1\x3e\x86\x80\x77\xbf\x12\x25\x04\x27\x7d\x81\xf6\x54\xe4\x59\x93\x41\xbd\x1b\xf7\x4e\xb2\x38\x0e\x92\xd8\xf4\xc2\x6b\xcf\x59\xae\xb7\x13\xbe\x7b\x16\xc7\x4a\x62\xa1\x6f\x65\x19\x9c\xf0\x82\xf7\x00\xba\x0f\x2a\xaf\x56\xef\x28\xc1\xeb\x2f\x63\x00\xbb\x1f\xf7\xbf\xff\xc3\x53\x7d\xb2\x38\x89\x38\xfa\x9c\xae\xf9\xb1\xf1\xe8\x11\xcb\x9b\x34\xf0\x23\xfb\xf9\x13\x27\x91\x8e\x3d\x43\xf0\x35\xb8\x60\x80\x77\x9a\xc1\xc9\xb2\x38\x49\x05\xe6\xac\xd1\x72\xac\x41\x65\x27\x91\x4f\x2c\x63\x4c\x68\x27\x14\xff\x23\xab\x2e\xf5\x28\x87\x11\x53\x66\x6d\xf0\x8f\xf5\xfd\x9f\x76\xc2\xb0\x98\x87\x16\x18\x87\x2e\xf8\x1e\x5a\x5f\x03\x2b\xcb\x93\x2f\xc1\x23\x4b\xfb\xe0\x5a\x80\xae\x5a\xbe\x59\xcc\x55\x3c\x68\x12\xfa\x81\x52\x9a\x08\x33\x1d\xdf\x7b\x1a\x1b\xb4\x44\x0f\xdf\x1f\x57\x88\xe0\x5d\x6f\x7f\x6c\xd7\x9b\x47\x7f\xf7\x29\x23\xc2\x76\xe4\x37\x9b\xfb\xaf\x9d\x28\xe5\xa7\x36\x3d\x16\x81\xad\xfa\xaf\x41\x74\xea\x7b\x2c\x16\x51\x38\x48\x96\xfe\x84\x01\x17\xf0\xe4\xf4\x48\x5a\xfa\x65\x97\x44\x1a\xf9\xf3\xb1\x48\xb8\x48\x46\x74\xb7\x37\xdf\xd7\xeb\xeb\x18\x62\xbc\xaa\x63\x91\x58\x52\xb3\x02\xde\x7c\x72\x6a\x1e\x73\x34\x96\xfb\x62\xb1\x60\x01\xe6\x5f\xd1\xa6\x9d\x32\xaf\x30\xe9\x8e\xaa\x54\xa3\xdb\x8d\x33\xb2\xe3\x3d\x2f\xab\x75\x86\x78\x00\x87\x33\xfd\xb8\x3d\x97\xc5\x4a\x32\x0d\x5d\xfa\xee\xd1\x22\xda\xeb\x9b\x12\x7b\xa9\xaf\xca\xf4\x2c\xd6\x11\xc3\x4c\x61\x53\x89\xac\x08\x27\x9f\x53\x53\x25\xa2\x4e\x62\x64\x48\xf9\xc7\x62\x2d\x35\x92\xcd\x7c\x2d\x2d\x3e\x51\x96\x8d\x15\x4a\xf7\x50\x5d\x16\x6b\xc5\x12\x17\xa9\xa3\x17\x7a\x28\x87\x91\xcb\xe7\x1e\x66\x0c\x49\x8a\xbc\x61\xcb\xb2\x3c\x21\x3d\x80\xa7\x5b\xfb\x20\xbc\x8b\x41\x44\xf1\x00\x3f\xd4\x28\xcb\xc8\x3c\x99\x0d\x20\xe2\x24\x74\x22\xe6\xd9\x6b\x96\xc3\x13\xcc\x26\x00\x63\x13\x45\x18\x2d\x56\xad\xc3\x70\xb1\x32\xa2\xbf\x5d\x06\x72\xa2\x2c\x36\x2a\x08\xad\x69\x76\xd8\x7c\x74\x64\xec\x0b\xe6\xff\x53\x41\x91\x8f\x8c\x95\x01\x89\x38\xf7\xd6\x0f\xa6\x69\x27\xa8\xca\x92\x40\x26\xe8\x91\x3e\x89\x13\x38\x79\x00\x1b\x7f\x0b\xcf\xd4\xce\x92\x90\x44\xd4\xf8\x36\x69\xbb\x20\x86\xa4\x65\xed\x00\x8b\x67\x38\xda\x0e\xee\x69\x12\x71\xf4\x16\x92\x28\x54\x5c\x0d\x29\x2f\x70\xf1\x7c\x92\x4d\x4a\xe2\x90\x22\x7e\x1e\xfb\x0a\xbe\x9f\xbf\xcc\x65\x40\x92\x98\x4a\xac\x3e\x21\xf8\x68\x77\xfe\x13\x15\x53\x96\x24\x51\x68\x01\x07\xdb\x87\x28\xf0\x0f\x92\x28\x83\xe5\xb4\xaf\x56\xd7\x0d\x0d\xe5\x73\xd3\xc3\x3d\x59\x92\x68\x2b\x40\xdb\x8b\xbd\xda\x92\xf3\x7c\x77\x04\x4b\x48\x1c\x23\x8b\x4a\x3b\x26\x08\x77\xaa\x89\x82\x90\xfb\x9f\x23\x49\x14\x29\x1f\x30\x5d\x4d\xe2\xe1\x22\x4f\x68\x90\xa2\x6d\xfa\x7e\xbf\xf2\x67\xd3\x88\x23\x12\x04\x3b\x93\x77\x66\xdf\xc7\x98\x09\x95\x7a\x28\x9a\xd5\x2b\xf5\xb3\x04\x2d\x66\x6b\x0f\x2a\x10\x2f\x3e\x3e\x59\x42\xf3\x06\x50\xb8\xa4\xcf\xa2\xd0\xdb\xd5\xae\x3b\x41\x18\xac\x32\xa3\x9f\x6b\x71\xc1\xcf\xd9\x79\xae\x8e\x33\xfe\xce\x4c\x26\x5c\x62\x09\xb8\x8d\x39\xc7\x66\x20\x61\xda\xa0\x17\xda\xcd\xa7\xae\xd4\xc2\x12\x9e\x48\x74\x07\x1f\xf7\xbb\xee\x59\xd3\x40\x63\x8c\x73\x2a\x75\x66\xde\x0f\x6d\xec\xb4\x76\x92\xb1\x93\x2b\xa7\x52\x1b\xdf\xd3\x9f\x8b\xba\x7e\x14\xc5\xcb\x97\xd1\x4c\x49\x55\x48\x6d\xa6\x69\x83\xb9\xc0\x41\x41\x95\x25\x29\x24\x34\x1a\x64\xcb\x6c\x58\x7f\x25\x6d\xc0\x12\x41\x23\xe6\x69\x1a\x7e\xad\x45\x23\x86\xa4\xc3\x73\x05\x61\x96\x08\x9e\x20\x52\x7f\x89\xe2\xc9\x48\x2f\xf1\x65\x98\xb5\xfe\x14\x1b\xcd\x12\x19\x04\x3d\x9d\xa0\xc7\xa8\x7d\x85\x22\xf8\x67\xa9\x33\xa1\xa6\x65\xbd\xcf\x8d\x61\x22\x53\x23\x92\x3e\x25\x05\x45\xb3\x16\xef\xae\x3e\x34\xe0\xfe\x63\x89\x8a\x82\xc0\xa7\x7d\x17\x85\x5e\x77\xbc\xd3\x2c\x51\x3a\x95\xb1\x8b\xb8\xf0\xf1\x8f\x22\x4c\xfd\x41\xad\xc0\x87\xa5\x0e\xad\xba\x28\xb4\xad\x40\x7e\x20\x1e\xe5\x4e\x04\xa6\x1d\x6d\xff\x23\x08\xfd\x7e\x28\x17\xea\x8a\x41\x88\x25\x60\x74\xe8\x18\x5a\x97\xd9\xb0\xc8\xcf\x12\x43\x42\x34\x76\x6f\x59\xb1\xd3\xba\xfb\xab\x48\xb0\x25\xab\xdf\x96\x97\x87\xd5\xd7\xe9\x3d\xf8\x5d\x8f\x04\x86\x60\x55\x6f\xb8\x1d\x7f\xe4\x1e\x5e\xae\x45\x6b\xdd\x55\x42\xad\xd2\x9e\xd0\xcb\x13\xc6\x3c\x3c\x97\x50\x64\xbf\x60\x56\xd0\x74\xba\xff\x92\x28\xb0\x74\x97\xc7\x0a\x84\x5e\xda\xa6\x87\x5e\xb4\x78\xee\x57\x23\xae\xb0\xf4\xf9\x38\x2e\xe5\xed\x27\x00\x5e\x46\xe2\x28\xc6\x6f\xa4\x3c\xd6\x00\x36\x87\x6f\x5f\xfc\x41\x41\x2d\x7f\x7a\x56\x3c\x2d\xdf\xa7\x67\x6a\x8a\x9d\x72\x4e\x2d\x64\x18\xb7\x92\x84\x52\x84\xa9\xa3\x61\xb2\xea\xe8\x37\x22\xeb\xb8\x26\x19\x49\xb8\xcd\x62\xec\x1f\x0e\xdb\xee\x6f\xa9\x71\xa9\xd4\x57\xc0\xa9\x84\xf1\xc4\xf1\x76\xf7\xa3\x1b\x21\x35\x7e\xc0\x53\x56\x20\xd8\x65\xc2\x46\xc8\x48\xa2\x01\xdb\x26\x6a\x28\x74\x1b\x66\x9d\xb0\xf5\x61\x76\x4f\x21\xc4\x18\x04\x0a\x9c\xcb\x32\x1f\xa7\x05\x09\x35\x46\x3b\xbe\xb7\xbb\xb2\xa8\x1b\xe4\xc6\xaa\xeb\xa5\xa8\x33\x35\x44\x04\x5d\x69\x0c\x7d\x94\x95\xbd\xce\xd0\x12\x1e\x30\xee\x72\xe3\x7d\x5e\x8a\xf0\x34\xc2\x62\xe7\xb9\x82\xd7\x2c\xcf\x9e\x50\x36\xea\x0a\x80\x3e\xff\x40\x29\xb3\xc5\x0e\x87\x34\x00\x6d\xf7\xd5\xa3\xea\xdb\x5f\x26\xfe\x08\x11\x41\x40\xad\xe4\x68\xdd\x08\x8f\x19\x60\x44\x70\x89\xed\xe8\x77\xbe\x54\x37\xea\xad\x74\x83\x64\x10\x61\x7e\x0d\x25\x63\x56\x96\x33\x74\xf2\x39\x24\x27\x18\x89\x2f\xb3\xe6\x2d\x2b\x14\x76\x92\xcf\x46\xa7\x7e\xbc\x10\x56\x29\x53\xa9\x6a\xc0\x0e\xf9\xdb\xe4\x87\x01\x84\xf6\x55\xd9\x72\x2c\x73\xc7\x88\xa2\x0c\x41\x53\x7e\x7b\x9a\xaa\xad\x77\x1b\x39\x51\x9c\xa2\x5c\xdc\x3f\x37\x9e\xa4\x8a\x11\x95\x72\xec\x78\x7e\xd8\xed\xf7\xab\x9d\x67\x35\x62\x44\x47\x0c\x2c\x69\xe9\xfd\xe1\xdb\x71\x7b\x7f\xdc\x6f\xfc\xce\x44\x40\x5a\x48\x1c\xe6\x08\xb2\xb2\x70\x30\x5b\x6b\x2b\xc8\xbc\x29\x27\x86\x6a\x2c\x2d\xff\xed\x52\x37\x8b\x02\x8d\xa1\xaf\x78\xd3\x20\xd2\xda\x6e\x4f\x37\x79\xf9\x06\xd5\x62\x28\x3d\xcb\x68\xe0\xbc\xfd\xda\x91\xdf\xce\x87\x28\x34\x14\x06\xc1\x8c\xae\xe3\xf3\xcf\xd0\xf8\xbf\x4d\xce\x06\x21\x9d\x06\xcf\x6d\xd9\x17\x99\xff\x15\xf5\xd6\x89\x4c\x64\xe9\xfe\x15\x3b\x7b\x45\xa3\x58\x39\x7f\xb8\xe3\xc1\x79\xe8\x15\x1f\xef\x4b\x9f\x6e\xa0\x51\x0c\x08\xe0\xb9\x14\x1d\xf3\x81\x57\xa8\x1a\xdf\x4e\x9c\x58\x8a\x3e\xb4\xa2\xad\xbb\x92\x77\x30\xea\xf6\x20\x28\xab\xcf\x3f\x57\x4e\x1c\x7c\x72\x9a\x84\x14\x3c\x13\x4b\xd9\x40\xed\xbc\x9e\xcf\x1d\x45\x9a\x44\x04\x19\x79\x51\x58\xe9\xdd\x57\x19\x3b\xa1\x9b\x0f\x75\x0c\xc7\xfb\xc1\xd0\x3e\xd3\x84\xc4\x21\xe9\x8a\xe1\x70\x3c\xf7\xda\x0e\x93\x27\x4f\xb4\x42\x10\xf3\xd7\xec\xd5\x01\x2b\xa0\xba\x46\x08\x8f\xdc\x0c\x4a\x62\x49\x1d\x26\x61\xf5\x2c\xb2\xe2\xb1\x2c\xa7\x97\x25\xc4\x2a\x8e\x74\x9a\x63\xcd\x33\x54\x08\xbe\xc0\x39\xf5\x41\x8d\x8e\x92\x54\x60\x8d\xe0\x7b\xa1\x3d\x9b\xcc\xfc\x40\x6a\xac\x62\xed\x05\x25\x69\xfa\x7a\xd8\x1a\x7a\x3f\x8f\x32\x97\xcb\x56\x22\x57\x08\x86\xb5\x30\xc7\x8e\x89\xa1\xbf\x5c\xeb\x29\x27\x1d\x41\xd4\xa6\x68\xc6\x2c\x5f\x8c\x32\x6a\x61\xee\xaf\xad\x1b\xd0\x6e\x73\x43\xca\x1c\x3f\x46\x0b\x6c\xc6\x6f\x43\x47\xeb\x8f\x5c\xd7\xe3\x29\x27\x89\xf1\x1c\x00\x4e\x26\x7e\x2f\x5e\x01\xab\x1c\xe3\x57\xc8\x53\xae\x52\x2f\x60\x62\x2e\xd8\x2e\xd9\x9a\x9a\xc1\x7c\xe3\x32\xc1\xc4\xce\xe6\xb0\xda\x5f\xaa\x57\xe8\x9e\x9c\x1b\xed\x03\xaa\x3b\xf1\x0b\x1b\x87\xd1\x58\xbb\xf5\xb2\x7c\xbf\x6d\xfc\x5e\x49\x53\x12\xe2\x46\x6b\x32\x6d\xf9\x9e\xc6\xbb\x15\x4d\x85\x89\xfa\x44\xcb\x4d\x55\x9e\xd0\x6f\xbd\xc2\x69\x31\x9a\x9a\x00\xb3\x6c\x06\xe0\x28\x87\xfd\x43\x8c\xca\x00\xb0\xaf\xf6\x49\x61\xa2\x6e\x50\xd4\xa1\x92\xc6\xc6\x66\x82\x41\xef\x51\xa4\x77\xd1\x1f\xb2\xa4\xd3\x08\xcf\xba\xc9\xb3\x73\x77\x80\x53\x7c\x3e\x91\x37\x50\x2d\x45\xf1\xe2\xdb\x95\xae\x96\x46\xff\xb2\x94\x4e\x70\x99\x3d\x7c\x5f\xde\x6e\x57\xc7\xdd\xcd\xcd\xe6\x71\x24\xbc\xc3\xa8\x0e\x18\x1f\x38\x53\x99\xaa\x4a\x07\x73\x9a\x5f\xb9\x40\x0c\xea\x1d\xb5\x91\xe6\x1a\x75\xc1\xba\x56\x48\xc6\x82\xc0\x04\xe1\x48\x3a\x56\x77\xe0\x78\xc6\x82\x10\x30\xfd\xeb\xa0\x10\xdd\x9f\xa9\x6d\x62\x68\x32\xa8\xe2\xdb\x9d\x4f\xfb\xb1\x30\x14\x9e\x3a\xc2\xea\x2f\x65\x27\x74\x62\xe6\xf8\x3d\x18\x0b\x25\xb3\x4a\xe6\x99\xae\x11\xb7\x0d\xfa\xa8\x06\x19\x24\x16\xea\xc4\xc3\xcb\x17\x79\xe6\xd0\x23\xe3\x35\xc1\x42\x50\x78\x87\x36\xfb\xfe\xad\xbc\xd4\x5d\x8a\xde\x39\x19\x2c\x62\x02\x9b\xcf\x7c\xa4\xbd\x12\xe7\x9e\xf9\x9a\xb1\x38\x8a\x91\x1a\xef\xa5\x56\x4b\xd1\xa8\xe7\xe5\xa5\x2a\x7e\x3e\x43\xf1\xbd\x86\x6d\xb1\xcf\x34\xa8\xd6\x7a\xcc\x25\x86\x46\xfb\x36\x8b\x63\x3b\x79\xde\xdb\x48\xab\x1f\x3d\x71\xa8\x59\xcc\x38\x3a\x78\x0d\xd4\x8d\x65\xf7\xad\x3a\x7d\x45\xc6\x62\xae\xb0\xca\x82\x82\xff\x9b\x76\xa3\x9d\x82\x92\x27\x35\x5e\x96\x84\x31\xaa\x2a\xc9\xbe\x6b\xd1\x1f\x89\x42\x74\x14\x57\x8f\x8b\xeb\xd6\x5e\xc6\x92\x38\xc6\xac\xce\x9d\x78\x01\xcb\x7a\x3a\x39\x9e\x5a\xf2\x71\x54\x22\x9f\x20\x52\x27\x23\xb5\x89\xc7\x21\xc5\xdd\xe2\xeb\xd7\xed\xe6\xcf\x72\x7d\x2c\x01\xea\xe7\xcb\xf7\xf6\xd1\x46\x9f\xcd\x2b\xc6\x39\x85\x81\x0e\x00\xf2\xc1\x3e\xe3\xce\x22\xb1\x42\x1b\xb9\xde\x7e\x3d\x3c\x76\x2e\x0d\x23\x69\x92\xda\x1a\x77\x23\xf2\x87\x72\xef\x72\x33\xde\x7c\x30\x4a\x39\x3e\xc2\xb9\x0d\xfe\x5e\x27\x6f\x82\xca\x24\xb6\xa5\x76\x94\xbc\x74\x5d\x13\x1e\x44\xb3\x2d\x7a\x0c\xad\x3b\x81\x51\x0a\x1e\x6b\x82\xde\x10\x6e\x40\x93\x99\x8b\xf6\x01\x59\x25\x9e\x33\x99\x35\xc3\xd0\x81\x71\x13\xa2\xf3\xb3\x5d\xed\xd0\x12\xf5\xad\x23\x8c\x89\x14\x52\xdd\x95\x56\x6f\x26\x5a\x51\x8c\xc9\x38\x70\x04\xe9\xb6\xbe\xe9\xb5\x6a\x66\x7c\x4d\x26\x53\x96\x42\xa7\xca\xd7\x80\x1a\x89\xbe\x31\x26\x35\xb7\x7b\xe8\x7b\xa1\x9c\x74\xeb\xb9\x19\x62\xa2\xba\x45\x70\x1d\xb0\x31\xc5\x08\xf2\x31\x94\xad\x2b\x88\xce\x1d\xe8\x87\x0c\x70\xc3\xd9\xcf\x20\x8e\xfd\x69\xc6\xb2\x7f\x7c\xbf\xdf\xfe\x71\x5c\x2f\xbc\xd9\x63\xca\xd8\x76\x8d\x06\xc4\xe9\xf0\x56\x3a\xb5\x53\x77\x50\x73\xc0\x8c\x15\x9c\x32\xab\x88\x33\x8c\xf2\x3e\x4f\x01\x30\xad\x52\x20\x3e\xaf\x77\x3a\x37\x70\x0c\x49\x77\x5d\xa5\x01\x21\xb6\x23\xf4\xce\x07\x8e\x01\x83\xc0\xb0\x70\x80\x8e\xd2\xd6\x2e\xbb\x5c\xb1\x9e\x71\xc6\x18\x50\x8b\x5c\xc7\x5e\xc8\x9b\xdb\xcd\x1f\xab\xa9\x8c\xd7\x64\x82\x83\xb0\xc4\x5d\xf2\xe2\x7c\x7e\x9b\x20\x1d\xe7\x5a\xe6\x52\xa0\x93\x3e\x6b\xc6\x83\xc0\xc2\xbd\x96\xab\x43\x79\x5e\x55\xc2\x34\x2b\x51\x14\x42\x7a\x56\x1d\xc6\x83\x28\xc4\x46\xc7\xf6\x76\x3a\x29\x28\xc6\x03\x90\xa1\xcb\x07\x57\x59\xf3\x7e\x73\x29\xac\x2c\xda\xc4\x5f\xe1\x61\xac\x71\xdd\x2c\xb3\xe6\x2b\x36\x39\xfd\x69\x59\x85\xc7\x89\x2b\x02\xd5\x2e\x29\xfe\x4d\x54\x7a\xd5\x4b\xd5\xf9\x61\x69\x82\x35\x6c\xfb\x96\x07\x8a\x7f\x57\x6e\xa8\x3b\x21\x09\x18\x76\x1c\x2d\xcb\x81\x16\x9b\x3f\x46\x02\xbc\xd8\x46\x96\x6d\x74\x36\x5c\x88\x9c\x24\x0c\xb3\xb4\xc7\x73\x05\x88\x9e\x99\x81\xa2\xf9\xa1\xc6\xa2\x14\x67\x28\x5d\xba\x11\x5c\x6b\x44\x96\xc1\xe1\x09\xd6\x76\xc7\xf5\xbf\x44\x63\x82\xb9\xca\x45\x9e\x4b\xa8\x9b\xac\x87\xd1\x76\x23\x20\x46\x47\xb1\xac\xb4\x9f\x87\xd3\xca\x1f\x67\x61\x68\x89\x4b\xce\x6d\xf0\x2f\xaa\xa7\xcf\x59\x25\x19\xe7\x81\xa4\x3e\x7f\x87\xcd\x22\x65\x55\x95\x6f\x59\xf1\xe4\x62\xfe\x6e\x2e\x70\x0e\xc6\x15\x7b\x5a\x73\x32\x8a\x37\x39\xd7\x80\x2e\x09\x20\xef\xa3\xdd\xfb\x3b\x11\x7a\x37\x26\x65\x06\x19\xfb\x1f\x41\x3f\x0a\x39\xb1\x78\x5c\x70\x85\x9d\xe8\x4e\x58\xb8\x9e\xad\x7a\x73\xc1\x0d\xa6\xc0\xf3\xb2\xd9\xea\x7a\x5e\x16\x94\x71\x91\x02\xf6\xe3\x34\xd9\xaf\xaf\x16\xad\xe0\xfb\xd2\x06\x6f\x53\xa4\x06\x1b\x43\xbe\x89\x4a\x96\xd5\xc7\x6d\x10\x1f\xd8\x10\x7f\x15\x49\x65\xa7\x93\x6c\xad\xf5\x13\xf0\xee\x37\x0c\x89\x93\xb1\x66\x66\xed\x08\xd8\x1e\x01\xab\x85\xdd\x40\xe9\x79\x49\x5a\xcb\x58\xdb\xb4\x4e\x6f\x26\xb8\xa4\x1a\x7a\x5a\x8a\x19\x45\x57\xc6\x25\x97\xc2\x78\x0a\x9d\xd5\x30\xcd\xe0\x07\xa4\x1a\x41\xd1\x98\xab\xb0\xd4\xbb\xfe\xf7\x55\x10\xa1\x99\x3b\x57\xe5\x09\x9a\x67\xb8\xd4\xfb\x32\xd7\x43\x60\x33\x57\xa1\xc5\xf8\x39\x9e\x47\x4b\x56\xe6\xf2\xbc\x73\x9d\x55\x8c\xab\x04\x30\xb5\x80\xf9\xaf\x63\x69\x8e\x67\xa4\x67\x3b\xbe\xc0\x7b\xd8\x5d\x15\x6c\xd3\x74\x0d\xcd\x72\xf1\xfd\xa3\xcc\xa2\x1b\x0c\x34\xc0\x22\xcd\xe2\xe1\xe1\xb8\x58\xaf\x1f\x8f\xf7\x8b\xbb\xcd\xfe\x61\xb1\xda\xf8\xcb\x81\x89\x91\x37\xcb\x37\x69\xe2\x8b\x1a\xf5\x02\xb3\x34\x48\x2c\x93\xa9\xcc\x9a\xb3\xc8\x50\x3a\xc1\x73\x60\xfa\x11\x44\x5a\xb5\x45\x71\xa9\xba\xbf\x49\x4b\x8b\x3d\xc8\x23\xd9\x2d\x6d\xf2\x96\xd3\x30\x08\x91\x08\x63\xbd\xe9\xfb\x3a\x59\x8a\x9a\x3b\xf8\xee\x41\x54\x43\x2c\xc1\x1a\x1a\x91\xe5\xdd\xb0\x34\xb1\x26\x39\x6b\x8a\xf2\x55\x74\x7f\x56\xd6\x49\x17\x55\xf5\x3f\xf1\xf1\xb0\x34\xd4\x12\xf3\x7b\x48\x74\x78\xd7\xe3\x8f\xd3\x48\x06\x52\x4d\x51\xa9\xdd\x3b\x8a\x94\xa2\xdd\x69\xae\x9a\x8e\xd0\xcb\x6e\x44\x1c\xda\x38\xa5\x86\x66\x37\xc1\xee\xa6\x31\x0f\xb5\xe3\xef\xda\xae\x76\xd7\x1d\x81\x7e\x98\x0c\x8c\x6b\x7a\x73\xbc\x0b\x73\x75\xdd\x34\x56\x16\x7c\x68\xf1\x4c\x62\x46\x9d\xda\x0d\x4c\x42\x6a\x1d\xf9\x2c\xcf\x27\x8e\x4c\x9a\x88\x64\xa0\xaa\xb1\x86\xd7\x2b\x49\x2b\x96\x26\x52\x76\x92\x95\x4e\xa2\xf8\xd3\x5c\x63\x4a\x38\x60\x0d\xa9\x3c\xc1\x93\x18\x5a\xb3\x94\x86\x3a\xb0\x2d\xda\xba\xfb\x13\x37\x18\x28\xeb\xf2\x23\x28\xb3\x1f\x28\x6d\x73\xec\xa5\x68\x8d\x78\x73\xac\x87\x0d\x04\x29\x4b\xe2\xb4\x27\x74\x9d\x50\x67\xff\x25\x21\x5a\x96\x32\x42\xb0\x13\xd5\xf1\x64\x89\xa2\x5e\x89\xfc\x33\x66\x0f\x96\x32\x1e\x62\x4d\x7a\xbb\x58\xef\x7e\x3e\x76\x37\x03\x0a\xe1\x74\x56\x9c\xae\x12\x12\x65\xc8\xba\x47\xe6\x54\xf3\xb8\xcb\x0d\x18\xa8\x44\x7e\x05\x9f\x4a\xd3\x18\x10\x6e\xbd\x7d\xec\x92\x89\x69\xca\x38\xeb\xda\x17\x11\x42\xe7\x8f\x08\x92\xe0\x46\x73\x42\x2a\x93\x0a\x6a\x44\x5e\x4c\xbf\xb6\x50\x96\x70\xa9\xee\xf9\x78\xaf\xb4\xbd\xc6\xaf\x44\x86\x16\x75\x70\x5b\x3e\x21\x6d\xfc\x55\x13\x42\x2a\x49\x88\xf0\x64\x4b\x54\x9f\x41\xfd\x65\x7c\x98\xd9\x30\xcc\xd2\x7f\x89\x4a\x77\xd5\x92\xf9\x6f\xa0\x48\xec\x85\x65\x5b\x8b\xef\x6f\xcf\x55\x9e\xdc\xbe\xe6\x08\xcb\x27\x0e\x4b\xaa\x63\x46\x7c\xbd\xf4\x1a\x8f\x9c\x6a\x6d\xf1\x46\x3d\x2b\xb5\xa8\x5e\xa0\x79\xc8\x7e\x41\x3e\x13\x42\xa7\xda\x48\x13\x77\x8a\xa6\xd6\x1e\x0e\xa0\x13\x29\xa4\xa1\xe9\x8c\x41\xed\xb2\xea\xcd\x30\x17\x34\xdb\x5a\xcb\x52\x30\x31\xf2\x8a\x17\xe2\x04\x03\xb4\xe5\xa7\x46\x3e\x35\x2a\x45\x9e\x1b\x18\xf0\xbb\x4c\xdd\x9c\xd4\x18\x60\x6e\x3b\xbc\x2b\x5f\xb3\xc9\x13\x89\x80\x5b\x56\x49\x24\x46\xe8\x89\xd0\xda\x41\x49\xe0\xc6\x44\x31\x60\x78\x89\x98\xc2\x63\xad\x44\x0e\xeb\xf2\xed\x2a\x0b\xea\x47\x0b\x81\x65\xc2\xbe\xbb\xe2\xa1\x82\x93\x95\xf8\x9e\x7d\x0e\x11\xa9\x20\xa2\x63\x0a\x39\xd7\x91\xfc\x21\x89\x1c\x13\xb1\x88\x31\x8b\xf5\xf5\x76\xe9\x43\x57\x91\x04\x90\xf6\xdc\xde\xb6\xd9\x71\xfa\xde\x1d\x30\x62\xb6\xac\xf0\xdb\x4c\xd6\xda\x35\x0b\x25\x3e\x56\x13\x49\x1c\x19\x17\x03\x2d\x54\x73\x11\x76\xa2\xec\xcc\x4a\x54\x7a\x57\x60\x70\xe0\x13\xf0\xe3\x3b\x26\x91\xd5\x0e\xbf\xd4\xb0\x2d\xea\x4b\x85\xf6\x79\x32\x44\x27\x96\x1e\xd7\x51\xdb\x58\xbc\xe1\x08\x2c\x24\x88\xe1\x48\x09\xeb\x9d\x0b\x4b\x62\x3e\x47\xf9\xcd\x04\x0d\x42\x04\xae\xdd\x2d\xfe\x38\xee\x0f\x8b\xd5\xef\xc7\xf5\xe6\x01\x85\x18\xfe\xfe\x7d\xfb\xb8\xb9\xdb\x78\xa2\x3c\x26\x28\xb1\x4c\xb3\x50\x34\x50\x1d\xeb\xff\x5c\x06\x5a\x1d\x7e\x08\x0d\x82\x8e\xe1\x6c\x29\x6a\xe8\x69\xa0\x99\xa0\x3c\xc5\xa5\x81\x8c\xbe\xfb\x97\xf7\xfb\xce\x65\x12\x4c\x59\x1d\xb2\x37\x80\x17\x64\x19\x58\xb9\xac\x7c\x37\x00\xa4\x4d\xc6\x96\x0d\x04\xd1\x7d\x39\xf4\xa6\x04\x33\x09\xde\x98\x01\xd0\xbb\x02\x49\xb3\x3f\x98\x79\xcc\x10\xcc\x4c\xe0\x07\xf9\xf6\xfb\x57\x4b\x53\xf5\xb9\x57\x2f\x98\x49\x11\x5c\xaf\x2c\x17\x9e\x33\x27\xdd\xee\x2d\x38\x93\x36\x85\x88\x17\x73\x00\xf2\x91\x6d\x98\x5c\x30\x25\x01\x26\xb7\x04\x4e\x8e\x0f\x96\xa5\x48\x69\x8a\x4d\x58\xe7\xcb\x2c\x07\x22\x13\x22\xe2\xb8\x7b\x35\xe5\x32\x8e\xbe\xcc\xc0\x09\x85\x10\x80\x3a\x2f\xed\x97\x18\xf2\x29\xfd\x69\xe5\xe6\x53\x04\xc1\xfc\x43\x09\x9d\x20\x80\x1b\xc5\x9e\x36\x8f\x7b\x2b\x31\x64\xa9\xf5\x0f\xdb\x3b\xef\x55\x0a\x49\x1d\x21\x59\xbb\x8f\xe9\x76\x49\x74\x2f\x52\x85\x29\xc2\x67\x34\xbc\x3a\xf7\x7e\xd0\x70\xca\x84\x4a\xc2\xc0\x4d\xfd\x06\x74\x33\xf4\xb1\x84\xe2\x29\x26\x51\xbf\xe6\xa5\x14\xf9\xf2\x52\x67\x05\xd4\xb5\x6d\x5e\x1b\x3a\x13\x42\x83\x64\x9e\x8c\x12\x85\xb7\x1e\xaa\xf2\x35\xd3\x50\x7d\xdf\xae\x3f\x30\x3e\xda\xd8\x24\xbf\xcb\x9d\xed\x0a\xe8\x73\x8c\x02\x42\x5b\xf5\x40\xd5\x0b\xcc\xeb\x86\x83\x43\x1e\x60\xbe\xad\x1d\x17\xcf\xf8\x13\x03\xd1\x9c\xa3\x77\xf2\x50\xc1\x56\x79\x3c\x8d\x30\x89\xe6\xa2\xa7\xa2\x2f\x73\x58\xe4\xf9\xa8\x3a\x21\x8c\xe0\xc2\xb9\x03\xc7\x0a\x85\x4a\xab\x39\xfd\x74\x26\x8c\x0e\x53\x31\xe4\x80\x5c\x0f\x1e\x74\xf6\x81\x65\x04\x96\x2a\xd1\x96\x46\x66\x9a\xf7\xa6\x79\x58\x19\x0b\x9b\xf6\x3d\x0a\xad\x9d\x78\x56\x36\xa8\x62\x8d\x59\xcc\x99\x4c\x54\x82\xdc\x63\x77\x9b\x83\x4f\xfc\x4b\x92\x5a\x11\x0a\x5b\xfc\xf5\x0e\xc6\x07\x36\xf9\x72\x45\xc5\xdc\x31\x6a\xe0\x3f\xbd\x04\xdf\xc8\xda\x49\x62\x18\x6e\x09\xc7\xd6\x34\x5b\x13\xbc\xd5\x3d\x23\xe0\xb8\xd3\x9e\x49\x4a\x04\x06\x8a\xcf\xa2\xde\x9c\xce\x79\xf9\x0e\xd5\x1d\x6a\x16\x0e\x99\x46\xe6\xdf\x21\x23\x12\xa8\x97\x3a\x7c\xc2\x60\xb6\x3c\x9f\x87\x34\x7f\x4c\x32\x15\x63\x77\xd8\xee\x0c\xc5\x43\x39\xe4\xae\x61\x92\xc7\x42\x50\xcf\x09\x7c\xe5\xd2\x60\x75\xe4\x4e\xfc\x1a\xcf\x27\xc9\xb9\x46\xac\xf5\xfd\x66\x35\xef\x9a\xc9\x94\xdb\xa6\xd4\xac\x5e\x5c\x2a\xb1\xff\xa8\xcc\x21\x53\x11\x59\x79\x60\x91\xab\x31\x53\xc8\xe7\x66\x40\xa6\xc0\x6d\xce\xe4\x72\x72\xd9\xa6\x76\x6a\xaf\x76\xb1\x7f\x30\x11\x52\x9c\x8f\xdf\xde\x65\x95\xe9\xcd\x1f\x9f\x80\xf4\xa4\xe0\x14\xa3\xf0\xf6\x05\xb5\x6f\x00\x0a\xd7\xf8\xe1\x8e\xcb\x80\x60\x31\x06\xf3\x43\xce\x2e\x5b\x93\x3e\xf1\xf2\xa4\x74\xe2\x6a\x05\xbc\xd9\x9c\xf3\x07\xbf\xa8\xc3\x08\xb9\xd9\x9a\x5f\xf5\x3c\x57\x37\x93\x3a\x8d\x98\xef\x03\x43\x8a\xa6\x4b\xbb\x1f\x22\x58\x68\x61\x1a\xa8\x16\x6b\xb0\x2c\x7f\xfe\x2e\x21\x36\xc2\x53\x8b\x7e\xf6\xb4\xc0\x89\x72\xae\xe3\xa6\x8d\x8b\xbb\x1d\x46\x02\x4f\x4d\x5f\xa4\xc2\xb8\xe0\xca\x05\x9f\x7e\x96\xc1\x3c\x33\x11\xc5\x4c\xea\xc3\x7a\x57\x74\x77\x65\xb8\x21\x81\x03\xb6\xe0\x5d\xb5\xdb\xee\xfa\xa3\xa6\x1a\x15\xc8\xc0\xa4\x96\xfa\xa3\x2a\xdf\xae\x7e\x75\xf4\xb6\x55\x48\x63\xcc\x80\x60\xab\xc8\xfe\xb0\x38\xd8\x86\x91\xe3\xc3\xe3\x6e\x88\xb3\x56\x51\x10\x8a\xd0\xef\x05\x27\x91\x15\x59\xf1\x74\x97\x15\x30\x6a\xf3\x56\x51\xc0\x11\x14\x8f\x93\xfe\x6b\x56\x79\x2d\x55\xa6\xa2\xc4\xa2\x15\x95\x43\xbe\x75\xba\x38\xfe\xb8\x4e\x11\x11\x73\xca\x8a\x7d\xf6\x5f\x70\x5f\xde\x1f\x34\x71\x1a\x74\x10\x64\xcc\x70\xec\x2f\x4a\x41\x5d\x9b\x4b\xbe\x6f\xe0\xdc\xfd\x4c\x1c\x86\xd8\x08\x7b\x00\x71\x5a\x14\xda\xf3\xa6\x77\x87\x23\x81\x70\xcc\x36\x3a\xa8\x2d\x1d\xc9\xfd\xb0\xaf\x58\xc5\x04\xd0\xcc\x6b\x00\x8d\xfc\x40\xe3\x57\x1b\xa7\x11\xa2\x2f\xa0\x50\xa5\x86\x65\x96\xe7\xed\x6b\x70\x0a\x81\x7f\x6d\xd9\xb5\xd7\xf0\x0d\xb9\x2b\xd1\xdf\x5a\xa2\x98\xdf\x6c\xf7\xcf\xd9\xb9\xa7\x5d\x1e\x9f\x9d\x98\x00\xdf\xb0\xb8\x34\xa5\xcb\xaf\xe3\x94\x68\x2d\xcf\xdf\xee\xba\x8b\x19\x25\x5d\x85\x79\xf3\xeb\x0c\xaa\x01\xfd\x55\x9c\xa0\xd7\x30\x64\x8a\x84\x01\x77\xef\xf4\xce\x71\x65\x21\x17\x81\xbf\x68\x5f\x03\x56\x24\xb2\x13\x6a\x05\x55\xd3\x64\xe6\x7d\x26\xf8\x52\x84\xc7\xb8\x0f\xd6\x4d\x79\xbe\xb3\xd9\xa5\xd1\x2e\xa8\x88\xb1\x3c\xc5\x1d\x6d\xed\x40\xae\xb7\xe7\xfb\x64\x8a\xc6\x61\xd2\x89\x32\x5d\x8a\xc6\xb6\xee\xad\xec\x2e\x35\x9e\xbb\x94\x58\xbd\x7d\x5f\x47\xaf\x6b\x5c\xd5\x87\x11\xe2\xc5\x7f\x84\xd1\x3f\xfe\x02\x00\xd8\xa5\xf9\x20\x32\xbd\xbb\x7c\x10\x23\x2b\x16\x68\x2c\x55\xb8\x62\x51\x56\x16\xc3\x97\xc3\x62\x8a\x40\xc4\x6d\x93\xbf\x0f\x76\x05\xc5\x62\x0b\x68\x1b\x28\x3c\x0d\x45\x8e\x99\xe2\xb1\x25\x11\x43\xea\xfe\x42\x7b\x92\xba\x19\x0a\x71\xa6\x44\x28\xa8\x83\xae\xac\xaa\xf7\xba\x11\x79\xbd\xbf\x9c\x4e\x53\x29\x76\xa6\x44\x04\x1d\x40\x7e\xca\xd7\x32\xb0\x33\x4a\x30\x43\x9d\x01\x6b\xbf\x96\x8d\x94\x91\xdc\xe9\x23\xbc\x99\x3f\x51\x29\xc4\x59\x1f\x25\x64\xc5\xd3\x8f\xed\xc3\xe4\x06\x24\x4d\xa2\xae\x71\x6a\xf2\x5e\xfd\x10\x48\x91\xbe\xc9\x9a\xff\x76\xb2\xef\x21\xcf\x2d\x49\xeb\x64\xa8\x4a\xc2\x98\xbb\x1c\xd8\xf7\xcd\x61\xf5\xd3\xa7\x4a\x94\xa2\x4c\x22\x9a\x21\xab\x6a\xab\x37\xe5\x6b\x86\xdd\x08\x63\xe5\xc9\x2a\xd1\x80\xaf\x6b\x29\x9d\x68\xcf\x12\x89\x36\xca\x29\xf0\x6c\x2e\x55\xb9\xba\x72\xc8\x94\xe6\x41\x64\x4b\x8e\x67\xcb\x25\xdc\x5d\x46\x72\xfc\xe8\x87\xcd\xe2\xee\xf8\x63\x63\x15\xef\x87\x1a\x9d\x4c\x41\x12\x49\xed\x48\x05\xae\x10\x2b\x0a\x52\x21\xc0\x3b\x9c\x16\x71\x8f\xd6\x68\xf9\x3e\x9c\x5b\x90\x6a\xaf\x43\x7c\x07\xf5\x33\x12\xa0\x2c\xdf\xd1\x2e\x8d\xae\x66\x74\xa0\xd1\xf9\x29\x2f\x35\x1c\x41\x77\x29\x5d\x65\x34\x20\x88\xb3\x2c\xf6\x17\xf9\x1d\x53\xc2\x57\x85\xe4\x7e\x5a\xe8\x20\x64\x98\x42\xe9\xb9\x2d\x1e\x44\x36\x4f\xce\xc9\x74\xc0\x18\x6e\xf9\xf7\xe2\x94\x8d\x28\x9f\x3f\x18\x2e\x04\x72\x8d\x1c\xfe\xd8\x35\xd7\x65\x79\x1d\x72\x85\xcf\x70\x54\xe2\xbc\x7b\xf3\xf0\x73\x1d\x71\x8a\x42\x69\x4d\xf9\xf4\xd4\x8b\x0f\xdf\x4c\xd8\x8c\x99\x8e\x20\x01\xdb\xae\x2e\xf2\x35\xbc\x5a\xc9\xe1\x9f\x90\x3d\x3d\xfb\x8f\xa6\x63\x62\x12\x36\xac\x52\x8e\xbf\xb6\x8e\x53\x82\xdd\x63\xcd\xa9\xcb\xbb\xe9\x84\x5b\x78\x1f\xae\x13\x8f\x87\x9c\x5b\xa2\x3a\x01\x4b\x33\xbf\xf9\xe3\x70\x5c\xed\xee\x1e\x16\xf7\xff\x68\xf7\xd3\xdf\x37\xc7\xc3\xb7\xc7\x8d\x8f\xa9\x34\x71\xca\x86\x0a\x5b\xb9\x6f\xaf\x00\xec\x9a\x10\x8d\xaf\xa9\xc9\x4e\x70\x0b\xa6\x39\x94\x03\x24\x84\x1f\x03\x89\x25\x2a\x82\xba\x59\x57\xd9\x87\xec\x62\x6e\x38\x0d\xe2\xb4\x7d\x37\xcb\x2a\x13\x45\x13\x0d\x83\x2c\x4d\x35\x84\x9e\x81\xa4\x10\xe7\xfa\xb9\xf4\x70\x6d\x04\x85\x7c\xdc\x17\xa4\x59\x60\xac\x73\x85\x32\x77\xdd\x1b\x63\x22\x24\x49\xbf\x8f\x61\x71\x6d\x23\xaa\xc2\xbd\x6e\xef\xdf\x6b\x26\x12\xe6\x79\xbf\x10\x7f\x36\xa8\x63\xf2\x0f\x1e\x84\x69\x60\x6a\xa0\xcb\xed\xfe\xcc\x93\xc0\x2f\xea\xef\x35\x54\xfe\xfb\xcc\xf1\x59\x32\xcd\xa9\xbd\x3f\xdf\x95\x38\x93\x19\xd4\xdc\x68\xcb\xdb\xad\x14\x9c\x1b\xd0\xcb\xb2\x7c\xc9\x8a\x27\xa3\x26\xe3\xd2\x88\xe3\x06\x84\x30\x92\xfb\x9b\xc3\xe7\xd9\x09\x9d\x26\x42\x5b\x8f\xde\xd2\xde\x3b\xbc\xd7\xe4\xe3\xa6\x42\x23\xde\x1b\x13\x33\xc7\xf8\x68\xa3\x67\x9b\xa9\xeb\xde\x72\x2a\x13\x21\x3b\x49\x97\xaa\x3c\x95\x23\x8b\xa0\x53\x69\x94\x1c\x76\xd9\x0c\x24\x2d\x66\x1d\x41\x9d\xaa\x00\x7d\xac\xac\x75\xcb\xab\xa7\xfe\xa7\x44\xc2\x89\xe9\xb6\x8a\xac\x78\x5a\x67\xc6\x64\xea\x92\x77\x1d\xbc\x5a\x92\xd4\xb6\xbc\xa1\x4d\x85\xcb\xc9\xa9\x9a\xde\xc3\xd5\x9e\x3a\xf9\x55\x29\x12\xac\x33\x7f\x7d\x5c\xac\xa2\xc1\xf6\xa9\xa5\x30\xa9\x05\x87\x22\x90\x6a\xd0\xa7\xaf\x25\x58\xe2\x5c\xa4\xbc\x14\x75\x7d\x2e\xab\xcf\xfa\x87\xb4\xe2\x54\x39\x6d\x94\x9f\x90\x8d\x78\x5a\xfd\x88\xd4\x66\x01\xd5\xa0\xc1\xd5\x1d\xd2\x01\x67\x96\x21\xe9\x53\x99\xdf\x51\x02\xd2\x9f\x9a\x28\x15\x7a\xba\x29\x78\xcd\xca\x8b\x43\x72\x8d\x02\xdd\x76\xfd\x21\xa2\xf9\x6b\x05\xdf\x84\x7a\x19\xbe\x04\x88\x4c\x68\xf9\x25\xb0\xd9\xc3\xb6\x51\xfa\x63\xca\x5a\x5f\x3d\x28\xaa\xdd\x64\xbf\xfa\xef\x66\x42\x86\x77\xde\x46\xb3\x7d\xc2\x42\x1b\x42\x53\x6a\x09\xa3\xb3\xfa\xf9\xa1\x42\x2e\xb2\xa4\x3b\xca\x12\x74\xf5\x84\xa7\x21\x98\xcd\x54\x68\x93\x0a\xbc\xb6\xc9\x8a\x59\xf6\xc8\xd1\x13\x42\x10\xaa\xd4\x76\x74\xd8\x3c\x8e\xe3\x4c\x1e\xcf\x7b\x08\x12\xbb\x55\x3d\x94\x7b\xd1\x94\xf5\xb3\xef\x51\x83\x40\x80\x74\x65\xb5\x07\xd7\xee\xdc\x1a\x94\xef\x45\x93\xe5\x43\x56\xc4\xee\xf6\x20\xd0\x06\xd3\x80\x52\xa8\x17\x4f\x40\x30\xbb\x24\x21\x8c\x53\x5c\xc1\xf6\x8e\x06\x65\x53\xff\xe3\xa1\xb4\x74\x74\xa7\xac\xc8\x4e\x97\x93\x0b\xea\xbf\x4c\xae\x22\x0d\x2e\x59\xa1\xf5\xb6\xa8\x9b\xac\x19\xb3\x00\x0f\x67\x05\x44\x11\xc5\xca\xe4\xff\x95\x59\xd1\xfa\xe4\xad\x1b\xbc\x2d\x5e\xb3\x06\xaa\x9e\x2d\xdb\x8f\x4d\x43\xac\x11\x39\x2c\x7f\x69\x8e\x8b\xdd\xea\x68\xca\xea\xb8\x2b\xe0\xd8\xf7\x6a\x40\x1c\x18\xe4\x58\x6c\x9d\x07\xc4\x5c\xcd\x0a\xdb\x8d\xf3\xe2\xfe\xd4\x94\x0b\xbb\x01\x64\xff\xf5\xe4\x52\xa3\x64\x1e\xc4\xc6\x6a\xec\x29\x91\xe7\x77\xa5\xc6\xca\x8c\x8f\x69\x47\x44\xf4\x0c\x92\x54\x2b\xa7\x0f\x1c\xc4\x3e\x8f\x00\x24\x60\x18\xfb\xb9\xf8\xc2\x6a\x9e\xff\x19\x48\x69\xf2\xa1\x48\x68\x1b\x36\xba\xc4\xe8\x0c\xe1\xea\xe4\x8c\x88\x20\xc6\x6b\x73\xf8\x86\x4c\xb6\xb7\xdb\xbb\x8e\x0c\x00\x68\x2c\xb1\xa4\x8e\x44\x12\x0f\x50\xdd\x95\x45\xd7\x11\xdd\x1e\x34\xc6\x33\x77\x6e\x57\xbb\x71\xd3\xfa\xe4\x67\xa8\x08\x90\xdd\xee\x24\xaa\x97\x1b\xab\xe6\xf5\xc1\x0d\x79\x35\x84\x1f\xb7\xc3\x1d\x18\x18\x0d\x30\xf0\x7b\x2d\xdb\xa0\xc9\xef\x09\xfe\xa0\xd6\xbe\x75\x7b\x59\x96\x39\x88\xc2\xb6\x3a\x8d\x17\x18\x67\x04\xf1\x4a\x68\xe2\xcf\xa2\x12\x3d\xd9\x0f\xa4\xc4\x48\xd5\x4b\x51\xf9\x88\xd8\x6f\x92\x7e\x14\xe7\xc8\x40\xb2\xfb\xea\xff\x22\x12\x61\xb9\x4a\xca\xf2\xe5\xaf\x01\xca\x40\x72\x7b\x1b\xbe\x2c\xb9\x2c\xa7\x74\xfb\x0c\xa4\xb0\x54\x27\x77\xdb\xfb\xe3\xc3\xe3\x76\xb5\x39\x6e\xef\x8f\xab\xcd\xfd\x61\xef\x7f\x58\xc7\x21\x22\x8e\x0f\xdb\xc5\xa0\x09\x03\xb4\x91\x58\xaf\xc0\x96\x99\xab\x8d\x76\xb4\xc4\xc0\x24\x4a\x77\x62\xe1\xc2\xc1\x46\x6e\xca\xca\xea\xe4\x0d\x31\x78\xee\x0c\x43\x99\xf2\x45\x2b\x77\xf3\x93\xe2\x3e\x18\x11\x63\xa5\x74\x7f\x12\x6e\xbb\x19\xcc\x40\x3b\xc6\x84\x89\x45\x96\xd9\xd2\xf5\xe6\xd7\xb9\x2c\xfa\xa0\xc1\x84\x29\x20\xf2\xe6\x9f\xa5\xa8\x86\x33\xc0\x84\x9a\x62\x23\xc4\xb3\xa8\xb7\xaa\xf4\x0a\x0a\x7d\x77\x62\x77\x9f\x26\x04\x40\xbe\xb8\xb3\x78\xdf\x83\xba\x54\x59\xf3\xfe\xd0\xd1\x9f\x32\x93\x50\x15\x12\xdf\xe1\x70\xe9\x49\x58\x99\x21\x1a\x52\x5f\x3b\xb2\x44\xb1\xc7\xfd\xee\x76\xfd\xff\x38\x7b\x97\xe5\xc6\x71\xec\x4f\xf8\x5d\x66\x55\x8b\x5e\x80\x77\xe0\xdb\xc9\xb2\x6c\xab\xcb\xb7\x96\x94\x99\x55\x33\xf1\x0f\xc5\x01\x70\x60\xb3\x2d\x91\x6a\x92\xb2\x53\xf5\xf4\x5f\xf0\x00\xa0\x48\x8a\xca\xea\x99\x4d\x65\x85\x09\x51\x14\x09\x02\xe7\xf2\xbb\x74\x87\x4d\x42\x16\x9b\x7f\xfc\xb9\xd9\x2c\x3a\x39\x03\x93\x86\x89\x95\x04\x5b\x2d\xac\x87\xd6\x62\xd5\x3e\xaa\xd9\xfd\x62\x1b\x77\x63\x54\x46\xa9\xd0\x8b\x24\x4d\xc9\x71\x8f\xff\x97\x30\x22\x93\x31\x6e\x64\x57\x3d\x3f\x0b\x6e\xf9\xc3\x90\x44\x16\x7b\x53\xee\x0f\xc7\x06\x9f\xf1\x67\x43\x8e\xf6\x3d\x7d\xc9\xcc\x70\x66\xed\x7c\xdc\x0c\xff\x67\x79\x1a\xdc\x5d\x1e\x26\x21\x0e\x3c\x2f\x07\x25\x1f\x23\x12\x8b\x5f\x76\xa8\x00\xd2\x6c\xab\x26\x72\x66\x23\x44\x48\x31\xd7\x7a\x31\x7f\x79\xbe\xdd\x7e\x7f\x79\xfc\xf6\xb4\xd8\x2e\xfe\xd8\xac\x66\xdb\x9b\x97\xe7\x6f\x7e\x06\x1b\x48\x53\x2a\x2b\xb4\x0b\x26\x56\xb7\x38\x12\x06\x34\x00\x16\x1f\xdf\xd1\x2f\x3c\xab\xb6\xdd\x0b\x46\x58\x79\xff\x11\x69\xcb\x3e\xf9\xd9\xcf\xc0\x1f\x51\xc8\xfb\xf2\xb1\xf3\xae\xbb\x31\x9a\x3b\xa0\x33\x02\xb2\x0d\x95\x00\x7e\xa1\x38\x7f\x19\xf3\x1b\x19\x5b\xc7\x8f\x8a\xfc\x56\xec\xb6\xd4\x26\xf9\x37\xa0\x3e\xd6\xe5\x1d\x8c\x30\xb9\x46\xc6\x9a\xfc\x3f\x6f\xb1\x6e\xaa\xf2\xd2\xe5\x7e\xf8\x23\x65\xaa\x08\x75\xeb\x9e\x84\xe7\x91\xf7\xcb\xa4\x83\x17\xdd\x28\x66\xfb\xdd\x8f\xf8\x86\x85\xae\x69\x6f\xf8\x95\x82\xb0\xff\x58\x64\x28\xd2\x80\xe2\x0d\x77\xf7\x65\x57\x84\x34\x4a\x58\x05\x88\xf7\x72\xa7\x07\x7d\x5a\xa3\x94\xa4\xdc\x11\x2b\xe5\x5c\xde\xeb\xb1\xda\xa7\x1b\x89\x51\x96\x74\x6c\xf9\xfd\xbe\x2f\x79\xe7\x47\x24\x76\xef\x81\x43\xb9\xdb\x95\xeb\x03\xaa\x1c\x76\x17\xe6\x27\xc3\x4b\xc6\x34\xe0\xb6\x30\xfd\x37\xdd\x0c\x83\x59\x68\x91\x79\xd8\x78\x37\xea\x89\xb9\x6c\x98\x22\xd9\x8c\x1f\x08\x84\x37\xe8\x75\x17\x7e\x19\xb0\x1b\x03\x9c\x5e\xc9\x26\xff\x79\x57\x1e\x8b\x1e\xc0\xcc\x18\x15\x85\x16\x80\x7d\xe9\x1e\xec\x87\xe8\x90\xb4\x33\xad\x5b\x72\x05\x79\x71\xc9\x9c\x1f\xff\xfb\x7f\x12\x3f\xfb\x0c\x06\x59\xe0\x82\xb5\xc9\x9a\x04\x67\x2c\xb6\x1a\x5e\xfe\xd5\xa2\x86\xd1\x99\xef\xe3\xc2\xdd\xab\x59\x2d\x67\x2c\xd1\x04\x98\xff\x67\x5e\x1c\x7b\xcb\x08\x67\x4c\x31\x92\x7a\xc5\x9f\x4d\x05\xe7\x22\x0d\x67\x0c\xd3\xae\xff\x42\xb0\x93\x3e\xa4\xac\x3d\xec\x68\xab\x96\xda\xb6\x85\xfe\x74\xe1\x2c\x48\xac\xef\x5b\x4f\x91\xe8\x7c\x4c\x4b\x42\xec\x2d\x7e\xc2\xfc\xe1\xae\xfb\xab\x61\xcc\x8c\x98\xc9\x53\xf3\xbc\x1d\x19\x39\x17\x4a\x82\x69\xfe\x36\x3e\x2a\xd1\xa5\x45\xcd\xb8\xfd\xd7\x0d\x31\x01\x3b\xeb\xe9\x38\x89\xa1\xe1\x98\x30\x06\xe5\xdb\xfd\x23\xf6\x10\x67\xa1\x11\x24\x3c\xfc\x5a\x7e\xe0\x1c\xdb\xf7\x65\xba\xae\xc8\x59\x94\x49\x82\x3e\xe5\x75\x7d\xc4\xea\x9f\xc7\x2a\xaf\x75\xde\x63\x3e\x72\x16\x89\x30\x62\x7d\x9f\x99\xfb\xb2\xd4\x17\xcc\x7c\xce\x62\x2e\x88\xe6\xd7\x13\x04\xbd\x8e\xf0\xe2\x2c\x09\xac\x6f\x98\x55\xea\xeb\xa4\x31\x38\x4b\xe2\x90\x50\x6e\xf8\x13\xd5\xb1\xc1\xf5\x21\x2f\xea\x61\x93\xd3\x0d\x4c\x59\x84\xb2\x23\x1e\xd8\x1a\xd1\x1d\xe2\xd6\x9f\x28\xe5\x19\x7d\x83\x75\xe8\xb3\xa5\xa7\x65\xf1\x1d\x6b\x6b\xb9\xee\x47\x49\xa4\x5a\x9f\x93\xcb\x76\x7e\x2e\x57\xee\x56\xaa\x64\xec\xca\x87\xf7\xb9\x69\xd6\xe5\x8e\xbc\x43\x36\xa7\x03\x8e\x9e\x72\x96\x45\xa4\xde\xf2\x34\xfb\x63\xf9\xf4\xed\xc9\x3b\x0e\x7d\xdb\x50\x41\xfa\x61\xb9\x59\x3c\x2e\xd7\x9b\x76\x67\x5f\xbe\xdc\x6e\xbf\xad\x6f\xfd\xf5\x70\x95\xca\xd4\x6b\x52\x59\x93\xbf\xba\x03\x70\x8e\xca\x6f\x9c\x71\xb4\x39\x9a\x33\xbb\x1e\xcd\x11\x11\x07\xce\x19\xa2\xcd\x84\xdd\x73\x25\x20\x59\x30\x08\xdd\x38\x13\x49\x4c\x28\x28\x07\xfa\x69\x27\xdd\xde\x46\x51\xdd\x8d\x12\x0a\xb5\xa7\x79\x5b\x77\x9a\xc1\x19\x20\xb2\xc2\x0c\xed\xe1\xdb\xbc\x57\x21\x1f\x3c\x33\x70\xa8\xf3\x36\xae\x3e\x35\xc4\x9b\x6b\xff\xe5\xbf\xf5\xba\xd7\xdc\x8f\x8d\x43\xea\xdf\x3f\xe6\x06\xd7\xd8\x6c\x19\x4b\xfd\xb5\x80\xab\xd5\xd0\x42\x68\x65\x13\x86\xb7\x1f\x8c\x75\x61\xb9\x85\x9f\x24\x62\x3e\x64\xcc\x70\x26\x99\x26\x38\x9c\x41\xbc\xc5\xa2\xdc\xe7\xc5\xd9\xeb\x9d\x33\x19\x5a\x3b\xdc\x1d\xd4\x9e\x4c\xe1\x0f\x29\xa6\xa9\xe9\x6c\x51\x14\xb3\xba\xc6\xa2\x19\xac\x57\x8a\x69\x63\xd7\x9d\x9f\x37\x8e\x32\xd1\xdf\xd2\x38\x53\x22\x22\xae\xf4\x3b\xd4\x13\xba\x36\x9c\x29\x08\xb8\xb5\xe6\x2a\xc9\x84\xda\x53\x50\xbb\xcf\xcb\x98\x54\x06\xee\x3d\x45\x9f\x33\x0d\x71\xe2\x7c\xe2\x36\xb9\xf5\x69\x9a\x15\x63\x82\xc2\xf4\x5a\xa5\x65\x20\x5d\xd9\x70\x51\x55\x45\xd9\x9d\x52\x45\xc4\xb9\x28\xad\x23\x61\xaf\x84\xc8\x19\x62\x44\xd2\x24\xa6\xac\xde\xda\x94\x72\xfe\x0e\x55\x3d\x7a\x00\xe8\x44\x1d\x41\xa9\xe3\x9e\x96\x67\x7d\x0f\x35\xa1\x60\xdd\x08\x13\xab\xd0\xb6\xc1\xe5\xde\xd9\xa5\xdf\x1c\x4f\x24\xf3\x77\x4d\xba\xd2\x7f\x92\x9b\xd8\x38\x23\x3b\x8a\x48\xc3\x17\x33\xfc\xfa\x20\xc8\x40\x9e\xbd\x45\x29\xd0\x9b\xb0\x52\xe3\x41\x98\x46\xa1\x8b\xdc\x49\x92\xfc\xa6\xdd\xe8\xfd\x31\x8e\x54\x83\x96\xc7\xd3\x53\x59\xf9\xaa\x1b\x0f\x42\xc1\x43\x8b\xa5\x52\xef\xb3\xdd\xee\xae\xac\xe6\x50\x68\xa2\x6a\x8c\xae\x22\xd4\x21\x80\x37\x1e\x27\xd9\xa4\x89\x6a\xd9\x3f\xc6\x9f\x11\x54\x27\xaa\x3d\xd3\x79\x12\xba\xc7\x83\x48\xa6\xdc\x89\x16\x2c\x55\x69\x93\x16\x77\x28\xe1\x48\x55\x89\x1b\x7d\xe8\xe5\x4a\xf6\x0d\xf3\x43\x84\xc5\x60\xb6\xdb\xe2\xfa\x7e\xfe\xad\xc6\x91\x4c\x01\x0f\x12\x85\x9d\x41\x35\xa8\x0f\xec\x5a\x65\xa3\x71\x29\xd3\xc4\x32\x69\x7a\xc6\x3a\xfe\x50\xc6\xd0\xb2\x6b\x66\xce\x22\xf7\xc5\xc6\x03\xd3\xcb\x6b\x90\x66\x31\xb5\x41\x4a\x43\x32\x1b\xbb\x7b\xd8\xe3\xb7\x6a\xd7\x9d\x0e\x33\x11\xfb\xbe\x63\x5e\xf4\xde\xe7\x20\xe3\x56\xef\xe7\x50\x7e\x9c\xff\xa6\x12\xb0\x9a\xa0\x9f\xe5\x07\xde\x57\x63\x9a\x37\x0f\x40\x04\xde\x22\x83\xe8\xcf\xbf\x7e\x32\x00\x01\x09\xc1\x37\xf0\x71\x66\x27\xf1\x40\x46\x92\xd4\x58\x8c\x73\x8c\xeb\x00\x04\x3c\x90\x89\x20\x06\xc4\xa1\x4d\xcd\xb6\xf1\x56\xb6\x93\xa0\x3b\x88\xcc\xdb\xc8\xd8\xda\x42\x6f\xed\x0b\x14\x47\xaa\x07\x12\x90\x70\xa4\x43\xe5\x86\x68\x9e\xd0\xf6\x97\xbb\x8e\xfe\x0a\x35\xe2\xb4\xf7\x10\x0f\x34\xd8\xa2\xe4\xa2\xac\x5f\xf3\xbf\xfe\x82\xf5\x2e\x57\x78\x5b\x5a\x59\xbf\x0a\xf2\xb1\x0e\x31\x0f\xb4\x92\x3e\x99\x7f\x82\x9f\x24\xda\x37\xed\xf7\xc7\x03\x64\x41\x18\x8f\x30\x0a\x14\x8d\x0c\x87\xb5\x69\x7a\x46\x7b\x95\x45\x4b\xc9\x1d\xf6\x62\x85\xf1\x58\x91\x26\x54\xe8\xdc\xed\xd6\xb8\xdb\xd1\xb2\xf0\x6a\x15\xfc\x77\x17\xd0\xc5\xd1\xf5\x98\xb8\x13\x6a\x74\x08\xa6\xf5\x65\x1c\xd6\x8e\xf2\x4a\x42\x36\x36\x58\x37\xd5\x51\x35\xe7\x58\xea\x57\xf1\x3e\x0f\x8c\xe6\xd6\xbd\x98\x1a\x4a\xfd\xe8\x76\x18\xcc\x05\xc6\x28\x4a\x4c\xee\x6d\xcc\xd0\x73\x92\xe3\x21\x13\x21\x09\xc1\xb8\x96\xec\x69\x2f\xcb\x01\x88\x8d\x87\x4c\x26\x14\x0d\x91\x4d\xcf\x38\x55\x18\x5c\x51\x18\x28\x1b\x42\xff\x1b\xd4\xc7\x6b\xd9\xf4\x5c\x39\x79\x18\xa0\x2d\xb4\xd8\xce\xca\x40\x39\xf0\xca\xd9\x42\xc9\x09\x2e\xd1\x03\xd4\xd8\x8f\x4d\x91\xfb\x78\x18\x2a\xe9\x8b\xfd\x6d\x78\xb5\xac\x07\x05\x35\x1e\x86\x86\x93\x50\xbb\x2d\x7f\xaf\xc1\x8c\xb6\xbd\x30\xca\x62\x0f\xb1\x76\x35\x32\xda\x12\x2e\x46\x21\x53\x1d\xf1\xeb\xe6\x78\x92\x3d\xbd\x5c\x37\x26\x8e\x04\x85\x5e\x94\x0d\x6d\x2d\xb6\x6a\x82\xc1\xc4\xc3\x38\x4e\x03\xed\x19\xc7\x6d\x88\xd5\x45\x00\x61\xcc\x4d\x08\x7d\xe8\xcf\x2f\x53\x68\x1e\xc6\x22\x22\x6e\xc9\x61\x07\x45\x83\x7a\x84\x54\x6d\x8f\x0b\x8a\x0a\x72\x55\x8e\x32\x91\x30\x86\x98\x16\xa1\xb2\x70\x12\xcc\xfe\x40\x12\x85\xc4\xe6\x6a\x88\x3a\x55\x9f\xf5\xd6\xfd\xf1\x2c\xb1\xc2\x2d\x5e\xc5\xe3\x6e\x57\x3a\x76\xee\xa8\xfb\xc6\xc3\x44\x33\x6c\x27\xda\xb6\x7d\x3e\xf3\x36\xdc\x9c\x7e\xea\x69\x6c\xa2\xc8\xf3\xcb\x9e\x86\xa6\x11\x3c\x4c\x8d\x24\xef\xf7\x6d\x97\x73\xad\xdf\x09\x9d\x3a\xf5\x1a\x86\x99\x02\xe3\x96\x05\x72\xa5\x1c\x3d\xa6\x0c\x35\x15\x48\x57\x08\x07\xac\x82\xc0\x7f\x09\x4f\xb0\xe7\x86\x4d\x0a\x65\x03\x4d\xfa\x31\xbb\x74\xf4\xad\x3c\x43\x13\x9e\xd3\x07\xcb\x87\xbe\xf2\x6b\xb9\x88\x09\x3f\xac\xac\x12\xd7\x52\x95\xb6\xe4\x3c\xe2\x40\xb7\x03\x39\xd5\xe9\xba\x5b\xad\x27\x76\xcc\x90\xcb\x30\x89\x5d\x5c\x62\xf9\x6e\xbd\x7a\x19\x0f\xb9\x96\xf4\x6d\x14\x52\x39\x25\xbf\xe1\x09\x44\xc4\x14\x5a\x83\x6e\xd4\x9b\x92\xea\x72\xfd\x4c\x6b\x44\xb3\xed\x6d\x18\xa1\x90\x19\x35\xd1\xe5\xb1\x3d\xef\x20\xe2\x0c\x21\x4b\x98\x5b\x0f\x9f\x6c\x3b\x65\x4c\x8b\xe1\x21\x60\x62\xc2\x9e\x48\xcb\x5d\x59\x2d\x1b\xdc\x8f\x47\x19\x91\xba\x94\xeb\xb8\x83\x6a\x51\x10\xbc\x69\x70\x79\x67\x8f\x98\xe9\x37\x45\x32\xc9\x98\xef\xa0\x3a\x0f\xe4\xd2\x35\x27\xfc\x05\xcb\x20\x8e\x95\x37\x03\xde\x63\xd1\x8c\x7a\xe2\x7e\x58\x6c\x21\xb5\x05\x5e\x33\x50\x19\x2d\x52\x3a\x0a\x53\x97\xbe\x11\x50\x6d\xf8\x22\xea\x8c\x11\xec\x92\x3a\xbe\x16\xc2\x30\x8a\x6a\x43\x2d\x6d\x31\xba\xcd\x58\xdf\xa1\x79\x80\xc3\x01\x8b\xf3\x22\x87\x4c\xc5\xe2\x6c\x1c\x52\x75\x0e\xf4\xb3\xba\x0d\xe7\x7a\x76\xe2\x3c\xc4\x2c\x89\xce\x2c\x18\xe7\xf4\x35\x9e\xda\xd3\x53\x1c\x39\xa4\x67\xdb\x61\x32\x1c\xb6\xd8\x69\xaf\x85\xe2\x3f\xed\xeb\x4e\x3c\x44\x01\x01\xf6\xf4\xf5\xbe\xe3\x7b\xae\x76\x68\xd9\x80\xe3\x79\x8c\xc8\x32\xd3\xa9\x50\x77\x5d\x4e\x37\x77\x46\xb7\x04\x4d\xc6\xfd\x3d\x7d\x3a\xfa\x58\x2d\x34\x4e\x9e\xd8\xb9\x62\xe8\x73\x82\x1f\x31\xa6\x28\x2a\x9a\xb7\x77\x8f\x9c\xe8\x3b\x12\xef\xf0\xdc\x11\xd3\x29\x49\x0f\x2c\xeb\xfb\xb2\x99\x12\x6d\xf3\xe3\x8c\x55\x5b\x78\xc3\xe6\x0c\xc5\xb6\xb7\x21\x76\x43\xc2\xd8\x22\x08\x3d\xbe\x66\xf8\xec\xa3\x28\x10\xdc\x38\x19\xfe\x27\xdc\xdb\x79\x19\x5e\x2d\x91\x0d\xae\x32\x92\x76\x6f\x75\x2e\xd0\x93\x24\x61\x1e\x45\x06\xe2\xb3\x6c\xf7\x14\x35\xfd\xef\x9a\x71\x3c\x8a\x43\x45\xc8\x61\x47\x9b\x3a\x2b\xb4\xf2\x28\x16\xcc\x4a\xa4\xbc\xe7\xd3\x15\x52\x1e\xc5\x68\xa8\x78\x61\x05\xd6\xf0\xb4\x19\x31\xbe\x79\x94\x60\x42\x21\xbf\x47\x56\xdd\x7e\x5b\xcd\xa8\x60\x11\xff\xe9\x87\xa4\x49\x60\x8d\x6c\x28\xb1\x75\x98\xb5\x36\x8c\x5b\x9f\xf3\x95\xb2\xdc\xfd\xd2\xad\x6d\xea\x87\x4e\x14\x78\xa2\x54\x80\xb3\x16\x25\xbe\xc8\xa0\xe7\xc9\xa3\x2c\xe0\xda\x03\x16\xdb\xb5\xa4\x3c\xf6\x4b\x60\x11\x8f\xb5\x5f\xd0\x3c\x50\x74\x9c\x25\x46\x5c\x03\x74\x44\x0b\xd8\xed\x2f\x3a\x54\x3c\x12\x10\x13\x0f\x77\x6b\xe3\xbc\x45\xf3\x7e\x29\xbb\xcc\x23\x21\x81\x0a\xe2\x7f\xdd\x5b\xe5\xcf\xd1\xa5\x42\x26\xa8\x8a\x7d\xa8\xf0\xad\x80\xa2\xf9\x3d\x6f\x9a\x0e\xbb\xcc\x23\x90\x48\xd5\x7a\x2b\xd1\xf2\x05\x95\x5e\xdf\x0c\xa2\xc0\x48\x46\x41\xe2\x4c\x29\x89\x90\x35\x3a\xbf\x74\xae\x17\x33\xad\x6f\xa0\xf8\x20\x0d\x0e\xe3\x6a\x22\x7c\x34\x87\x54\x22\x88\xdb\x7b\x9b\xbf\xe5\x0d\xec\xee\xcb\x9d\x5f\xbe\x22\x1d\x26\xe4\x65\xb7\xb6\xab\xdb\xe8\x4e\xe8\x58\x19\x02\xdd\x3c\x6f\x46\x21\x4c\xa4\x8d\xd5\xea\x27\xdf\x8f\xbc\xf8\x84\x5d\xae\xd7\xc7\x5c\xe5\x5d\x30\x13\x19\xe1\x7d\x66\xfe\x65\xdd\xb5\xfc\x62\x1e\xf9\x97\xd8\x18\x46\xa5\x76\x6b\x32\xe3\x63\x8e\x98\x05\xdc\x46\xae\xed\x7d\x79\xc8\xdf\xde\xd7\xea\x3c\xed\x63\x66\x18\x91\x57\x29\x60\xa4\x8d\x6b\x78\xd5\x71\xc0\xb9\xf1\x3e\x4d\x4d\x79\xb8\x28\xf7\x9f\xd7\xc8\x38\x8c\x18\x19\x02\xae\xdf\xcb\x2f\xec\x77\x0a\x79\x1c\x45\x92\xea\x4d\xb7\x15\x7c\xbd\x56\x48\x06\x28\xee\x50\x92\xb2\x98\xf4\xad\x8e\xaa\x71\x19\xfe\xf0\xbd\x8b\x53\x11\x53\xa9\x79\x07\xb5\xab\xa0\xbe\x42\xae\xcf\x47\x6d\xbd\x48\x81\xcd\x52\x9c\xee\xff\xb0\x92\x17\xa7\x3a\x08\x2d\x94\x83\x96\x7b\xe7\x90\x31\x1c\x93\xa5\x5a\x3a\xe9\x4c\xcb\x96\x3f\xa7\x95\x7f\x27\x2c\xc0\xe3\x2c\xcb\x84\x6d\x3b\x1f\xbd\x63\x25\x8f\x33\xc5\x68\xbb\xcf\xf5\x68\x35\x8b\xb9\xb0\xd0\xf8\xe6\x3d\x2f\xde\xe8\x6a\x7e\x1b\x32\x58\x78\x2c\xe2\x80\x38\x41\xba\xec\xab\x16\xf3\x58\x48\xeb\x08\xbc\xb0\x01\xda\xe6\x97\x3a\x79\xd3\x17\x2b\x9c\xaf\xca\x9b\x6b\x9f\x70\xe6\x0e\x80\x50\xd4\x08\x7e\x2c\xdf\xc2\xad\x29\xd4\x35\xc2\xe8\xa4\x4c\xff\x70\x2d\x0a\xae\x7c\x37\xe8\x84\x40\x0a\xdf\xff\x7d\x3c\x43\x86\x78\x2c\x03\xe1\x75\x51\xdb\x4d\x72\xfb\xd6\xb5\xb7\x78\x2c\x45\x42\x6f\xef\x94\xd2\xfc\x30\x3a\x8a\xa5\xb6\x90\x41\xbb\x97\xb4\xeb\xd1\xe4\x6e\x12\xab\x8c\x45\x56\x90\xe4\xad\x9d\xf5\x4b\xa7\xa7\xf3\xdf\xb2\xf5\x47\xbf\x49\x33\x0b\xb6\x69\x10\xf6\xcf\x24\x5c\xac\xf1\xe7\x60\x05\x8a\x75\x00\x94\x2d\xdb\x04\xf2\x26\xd7\x43\x5b\xe4\x09\x98\x37\x8f\x75\x2a\x68\x79\xcd\xeb\xae\xc3\xec\x5b\x63\x7e\x84\x8c\xa4\x71\x77\x66\x51\xa9\x90\xdd\x62\x4f\xef\x75\x3c\x73\xe9\xef\x21\xeb\xfe\x1d\xde\x12\xe4\x89\xb7\x6f\x7e\x5d\x6e\x51\xe7\xcd\x36\xf2\x49\x45\x6c\xa4\x45\x05\xb7\x61\x18\x05\x40\xf3\xbe\x09\x92\x1f\xa4\xd3\xa4\xdb\x20\xf7\x2b\xdc\x41\x33\x76\x24\xe3\xb1\x31\x9a\x62\x92\xd5\x6c\xb3\xd8\xce\x57\x2f\x3f\x6e\xa9\x45\xbf\x0e\xdd\x57\x25\x2c\xc8\xac\x6a\xe2\x0e\xa1\xfa\x27\xa8\x8f\x43\xd9\xbc\x9e\x95\x06\x2d\x56\xbe\x1f\x57\x75\x1f\x4c\x03\x6d\x89\xf8\xba\x5c\x36\xdd\x5f\xb3\x30\xb0\xfa\x5d\xfb\x03\xd1\x27\x5e\xcc\xa5\xac\x3f\x4f\x02\xc1\x8c\xb3\x0c\x9d\x1f\xeb\xa6\xdc\x63\xf5\x95\x37\xef\x8b\xcd\xc3\xaf\xab\x5a\x49\x80\x16\xae\xf3\xb2\x2f\x72\x5d\xee\x76\xe0\x73\xe0\x24\x64\xb6\x51\xb5\xf8\x6c\x23\xf0\x7c\x80\x23\x6d\x8f\x6a\xab\xd5\x83\xc5\xb4\x7f\xfa\xaf\xbf\x36\x44\x4e\x71\x44\x97\x49\xda\x8d\x6f\x3a\x51\x4b\x22\xcd\x22\xe7\x9c\x35\xab\x3f\x72\xe7\x04\x6a\x6d\x64\xfc\xe5\xc6\x61\x48\xe1\xfb\x6a\x71\xb7\x58\xad\x66\x8f\x16\x1b\xb0\x7d\x5c\x7c\x5f\x3c\xfa\x79\x90\x24\x68\x8d\xff\x5c\x57\xf0\xc5\x8c\x12\xf5\x24\x85\x94\xc8\xc3\xaa\x3c\x1e\x76\xb8\xdc\xc3\x1b\x2e\x5f\xef\xd6\xef\x50\xfb\x55\x31\x49\xa5\xa2\x46\xe0\xcd\xf1\xe4\x1c\x91\xc6\xe7\x50\x01\x09\xcd\xed\x21\x2f\xb6\xbd\x2a\x65\x92\x22\x0b\x5c\x8f\xf8\x7b\x69\x23\xb8\x49\xad\x0a\x9e\x64\x91\x34\xe7\xdb\xe3\x6f\xce\xf4\xad\xcc\x32\x43\x52\x36\x0a\x76\xed\x5a\x30\x3e\x93\x40\x85\x7e\x3a\xb6\x41\xc3\xf8\x6a\x79\x0c\x64\x04\xfc\x0e\xf5\x6c\x57\x21\xe8\x13\x6d\x52\x7a\x3c\x2c\xb3\x64\x14\x8d\x9f\xb8\x2b\x0f\x5d\x3d\xdd\x1f\x56\x92\xca\x61\x56\xae\x93\xbc\xec\x7e\xeb\x29\x70\x76\xd3\x46\x04\x19\xd5\x89\xce\xda\x6d\x9b\x92\x1a\xda\x57\x9e\xbc\x90\xa1\x76\x55\xba\x5b\x5b\xa0\xbb\x85\x06\xae\x0d\x56\x1c\xc3\xb3\xf7\xac\xd3\x9c\x19\x8e\x81\x24\xf5\x9a\x59\x3e\x18\x98\x5c\x62\x13\x48\xad\xd4\xae\xce\x6b\x8a\x2e\x28\x55\x69\xa7\x1e\x35\x2c\xc7\x83\x33\x4d\xa8\x50\x87\x44\x5b\x1d\x77\xe3\x48\x24\x91\x82\x51\xd6\xf6\xaf\x23\xe8\xde\xce\x91\xa8\x38\xcc\x6c\x3f\x88\xb8\x80\xe7\x8e\x73\xa2\x54\x96\x04\xce\x81\xf3\xca\x2f\xd6\x01\x78\xe1\xcc\x6f\x85\xca\x2b\xfb\x2e\x69\x5b\x86\x9f\x58\xe3\x12\x2d\xd0\x6a\xda\xbc\x3c\xfe\xad\x3c\x16\x4f\x90\x31\xe3\x6a\xd4\x2e\x2e\x21\xa5\xa0\x0d\xfe\x1c\x9f\x17\x63\x2b\x7a\xe8\x74\xcd\xe7\xe0\x25\xfc\xfc\x71\x61\x3b\xd2\x3d\x33\x03\x9f\x7c\x0e\x27\x88\x09\x23\xb2\x30\xdf\x42\x25\x73\xd7\xd5\xf5\x60\x58\x3b\x24\x0d\xa2\x24\xe9\x3b\x1c\xb6\x29\x64\x87\xe5\x19\x3e\x98\x34\x50\x32\x74\x54\x8e\xe7\xf2\xcb\x35\x7f\xa9\x5f\xeb\x07\x60\x42\x74\xcf\x36\x76\xa5\x93\xf4\x03\xbf\x34\x54\x01\xeb\xe3\xb9\x5d\xe0\x5d\x6f\xca\xc7\xf2\x2d\x57\xe7\x61\x80\xca\xb3\x62\x48\x93\xc9\x73\xb1\xdc\x80\x38\x48\x14\x3b\x63\xa5\xea\x72\xb7\xcb\x35\x6c\x10\xf6\x03\xd4\x42\x1a\x3b\x09\xb3\x8a\xfc\xbf\x7b\x82\xf0\x3c\x8d\xb5\xcc\x82\xb3\x6c\x1c\x36\xf9\xc0\xa2\xbc\x7b\x14\x69\x92\xda\x5c\xdf\x58\x9c\xc8\xa0\x16\x94\x26\x02\xb4\x17\x90\x92\x79\x33\x78\x89\xd3\x44\xd9\xfc\xef\x8d\x30\xfa\x5d\xf9\x2b\x4d\x59\xa0\x6c\x33\xaf\x21\x1b\x65\xdd\x1d\x08\x6c\x83\xa3\xdd\x6d\x6f\xdd\x7b\xf2\xeb\xe2\x7c\x9a\x0a\x46\x46\x6e\xb2\x2a\x41\x2b\xa8\x9b\x27\xac\x6b\x78\x1b\x30\x6b\x78\x9a\x82\x6d\x3e\xbd\xc2\x69\x55\xee\x76\x0f\x79\x7d\x21\xe8\xc9\xd3\xd4\x64\xa4\x1a\x34\x2f\x8b\xba\x81\xa2\x81\xc1\xa3\xcb\x02\x4d\x0f\x76\x76\xd4\x79\x73\xd9\x72\x1a\x46\x0f\x69\x26\x05\xdd\xf8\x2d\xcd\xc6\x4d\x79\x63\x27\x65\xbf\x5a\x9f\xf2\x50\x04\x0e\x62\xb4\x3c\x0c\xaf\x97\x27\x01\x11\xc5\x7e\x7f\x5a\x0c\x2e\x82\xab\x10\x3c\xfd\xb2\x7d\x7b\xd0\xe1\x6e\xd2\x78\xf4\xfd\x22\x51\x84\xcf\xbc\x5d\xdb\xcf\x4f\x56\x7e\x52\x01\x8c\xc7\xe7\x69\x64\xfb\x16\x57\x54\x5e\xdd\x47\x64\x6a\x68\xc7\xb3\x75\x87\x3b\xd8\xed\x24\xa8\x0f\x8f\xa7\xf6\x83\x32\x41\xf8\xe1\xbc\xf6\x5c\x7f\x1f\x51\x8e\xb6\x81\x54\x82\x2d\xae\x13\x33\x8c\x38\x02\x4f\x79\xe1\xf3\xdd\x5e\xfe\x9d\x4a\x29\x99\x57\xf8\x38\x1c\xe6\xa5\x1e\xa5\x34\xa9\x54\x40\xe0\x84\xb2\x68\xca\x5d\xf9\xe6\x9b\x86\xa9\x12\x32\x08\x3c\x22\x65\x5a\x64\x6f\x58\x07\xf5\xea\x22\x6d\xee\x31\xe2\xd1\xf3\x54\xe9\x4c\x5b\xb5\xe3\x4a\x6f\xc9\x61\x6f\xdb\x33\x1f\xe4\xa9\x16\x8a\x0a\xe3\xb0\xdb\x95\x5f\xb3\x4f\x68\xa0\x1a\x0a\x6b\xb4\x43\xbc\x04\x81\x6c\x7f\xef\xe4\x6e\x91\x6a\x19\xd2\xfc\x41\x55\xd6\x24\xa9\x70\x73\xcc\x49\x51\x6e\xf8\x7e\x63\x94\x11\x5d\x73\x3e\x7f\xd8\x2e\x6e\x97\x1b\x8f\xe7\xe4\x29\xc6\xa1\xc8\xce\x22\x87\xf3\x2e\x61\x4a\x31\x63\x54\x3d\x30\x65\xa5\x70\xa6\x3f\x7b\x99\x7f\x8a\x92\x53\x86\xa6\x8a\x66\x7b\xc0\x6a\x8b\x65\xf7\x55\x86\x45\x96\x70\x03\xc6\x0f\xcf\x18\xe3\x44\xac\xcb\x09\xf8\x3e\x6f\xc3\xbd\x06\x2b\x92\x1f\xaa\xba\x31\x71\x46\x72\x27\x8f\xe5\x1b\xb1\x7a\xf4\xd8\xb8\x97\x67\x0c\xb2\xa8\xd3\x61\x7a\xde\xdc\x76\x1f\x05\x1d\x78\x01\x5d\x77\x97\x86\xd8\xf7\x5e\xba\x9d\x31\x65\xb5\x2a\x74\x59\x58\xbc\x82\xf5\x70\xbf\xcf\x3f\x47\x68\xbc\xf3\xbb\x32\x9c\xda\x59\x10\x5b\x07\xad\x83\x03\xbf\xfe\xc8\x9b\xf7\xbb\x7c\x5c\xb8\xc8\x68\x49\xfc\x5f\xff\xdf\xff\xfa\x63\xf1\x3c\xef\xbf\x9c\x59\x14\xd9\x7a\xc7\x62\x5f\xfe\x3b\xef\xfe\x98\x21\x61\x3f\x6c\x3b\x15\x2f\x69\x7b\xd3\xd7\x92\x70\x2b\x14\xf5\x55\x56\x3b\x3d\xaa\xab\x65\x09\x80\xf5\xf8\x77\x1b\xd6\xb9\xb0\xef\x07\x28\x65\x9c\x54\x85\x05\x96\x10\xfc\xc6\x79\xf2\x8d\x6b\xf5\x59\xca\x90\x3a\xce\x2b\xf2\x33\xce\x8b\xb7\x99\x6b\x4b\xf4\xa7\x6d\x96\xc6\x31\xed\x17\xb3\xe7\xcd\xed\xe0\x67\xa7\x9a\x01\xe1\x20\xeb\xe6\xd8\xe0\x0e\x7c\x87\xcb\x1d\xce\x8c\x15\xd9\xfa\xcf\x31\x57\x1f\xeb\xb2\x3a\xdb\xf0\x86\xc1\xff\x4c\xe5\x79\x19\x0f\x53\x4a\xc7\x57\xe7\x3d\x3a\xe3\xda\x8a\x38\x2d\x36\x0f\x16\xf8\x4c\x0a\x7a\x8b\xf5\xda\x0f\x10\x09\x27\xf8\xef\xf7\x97\xe1\x43\x11\x59\x4c\x85\x88\xc5\xf3\x66\xb1\x5a\xdc\x6e\x9f\x66\xeb\xdf\xcf\xc7\x14\xf5\x9f\x70\x9f\xfb\x26\xe1\x5d\x55\xfe\x75\x85\x81\xc4\x33\xa1\x42\xca\xa8\x9e\xf1\x6b\xd0\xa0\x1d\x8d\xd2\xf6\xe6\x3f\x2d\x9f\xdd\xa5\x12\x40\xde\x7f\x29\xa4\x21\x39\xbd\x7d\x96\x0d\x2e\x2e\x49\xd4\xbf\xf5\xa6\x34\xa8\x58\xc9\xbe\xdb\xba\xd7\xd5\xf7\xc7\xb5\x21\x48\xb4\x69\xe3\x1e\x30\xb8\xad\x8f\xd2\x4e\x94\xc9\xbd\x32\x93\x81\xed\x42\x7e\x7f\xf9\xdf\x83\x7b\xa4\x24\xb8\x6a\x50\x7d\xc4\xe7\x72\x3f\xd6\x5e\x6c\x47\x68\x5a\xf6\xea\xa3\xb4\x5b\xbc\x5f\x16\x32\x1d\x46\x34\x2d\x1e\x5f\xee\xb7\x4f\xf0\xb3\x93\x17\xf6\xa2\x10\xc3\xf3\xe8\x48\x78\x56\x21\x91\xed\xa8\xeb\xda\xc1\x3a\x47\xcb\x82\xe6\x9c\xfc\x5d\xed\x56\xf3\x7b\x79\x86\x44\x4f\x51\x37\x79\x86\xca\x06\x3b\x64\x1b\xd5\xdb\x68\x33\x74\x32\xc0\xab\x97\xee\x29\x98\x8c\x91\x4d\xed\x4c\x7f\x62\xd5\xe4\x35\xb5\x85\xee\xf2\xe2\x02\xb3\xcd\x33\x03\x2a\x64\x3d\xa6\x21\xc5\x63\xc1\xe8\x87\x19\x6d\xb5\x1d\x9f\x96\xcf\xcb\xed\xfd\xec\x69\x41\x0a\x3c\xdb\xdb\xc5\xdd\xec\xdb\xa3\x03\xe2\x73\xce\x62\xc9\x1c\x08\xe2\x16\x3b\x35\xe2\x0b\xf3\x35\xce\x59\x2a\x42\x17\x1a\x58\xb2\xc3\xef\x78\xea\x09\x30\x71\x1e\xa4\x49\xea\xe0\x02\xeb\x03\x5e\x4b\x77\x78\x20\x19\x6d\x8a\x1f\x27\x65\x1d\x5c\x86\xbf\x8d\x07\x46\x70\x1b\x47\x82\xde\xe6\xa9\xdf\x3d\x78\x18\xc4\x14\x7e\xdb\xf9\xfb\x3c\xf3\x62\x42\x9c\x87\x3a\xa4\xb4\x63\x97\xff\xe7\x98\x6b\x27\x9f\x3b\xac\x50\xf2\x28\x15\x1e\x58\xb3\xa5\x8d\xf0\xaa\xea\x21\xe7\x91\x0e\x89\x73\xb8\xfc\xf6\xda\x9f\x93\x3c\x56\x49\x90\xf5\x1a\x2c\x3f\xca\xea\x03\xab\x99\x31\xa8\x9a\x41\x1d\x65\x74\xbe\x24\x4d\x85\x35\x19\x28\x4e\x03\x8c\x12\xcf\xc0\x90\x6c\x20\x45\xda\x37\x13\xe4\x06\x37\x8e\xa7\x29\xf9\xcf\xf8\x6d\xa0\x1f\x35\x73\x91\x30\xa6\x1c\x4d\x08\x1b\x92\x39\x1f\xbe\x94\x5c\xa4\x22\x0b\xe9\x65\xba\x39\x9e\xee\x8e\xde\x90\x85\x73\xc1\x63\xf2\xeb\x6c\x33\x78\xdf\xfb\xf2\x87\x44\x46\x36\xf8\x33\x63\xf2\x5d\xde\x49\xde\x5d\xe3\x20\x71\x2e\x8c\x22\xf9\xca\xbe\xae\xef\x18\x6a\x3a\xd9\x2f\xe5\x10\x74\x5c\xf4\x97\x63\x3b\xf7\x8f\x15\x6e\x35\xd6\x5b\x5d\x95\x79\xf7\x5a\x73\x99\x44\x59\xd8\xb3\xcb\xbd\x4e\xcc\xe4\x5c\xf2\x0e\xf3\x77\x0f\x7b\x5c\x14\xa3\xb7\x9e\xab\x34\xe5\x96\xbb\xa4\xca\x4a\xdf\x22\xec\x6c\x32\xb7\x42\xa8\xcf\xfc\x86\x7f\x8c\xda\xbe\xbd\x7f\x46\xd4\x20\xce\x15\x68\x92\x27\x20\x1d\xa6\xca\x53\x83\x9c\x43\x45\x97\x4f\x70\xcd\x2c\x3d\x5f\x1e\x4f\xe7\x80\xa0\x27\x07\x72\xe5\x1e\x69\x69\x3b\x8a\x75\x87\x1d\x59\xd6\xa3\x8d\xe1\xbc\x4a\x73\x54\x51\xe2\x90\x26\x67\xad\x3e\x77\xcc\x04\x86\x3c\x94\x8a\xb2\xc9\xcd\xe9\x45\xd2\x13\xaa\x2e\x54\x9d\x06\xfb\x1f\x37\x5a\xea\xa1\xc0\x55\xcf\x5c\x9c\x0b\x16\x73\xa3\x06\xc8\x16\x72\xd4\x1b\xbe\xd9\x82\x25\x21\xed\x87\xdb\x1a\x9b\xbb\x0a\xf1\xaf\xbc\x78\x73\x04\xb8\xfe\x6f\x18\x3e\x4a\x11\x04\x52\x5a\xb5\xb6\x52\xdf\xf5\xdf\x47\x11\x44\x3c\x70\x4b\xd7\xea\x65\xf9\xdb\xe8\x63\x2a\xa3\x26\x90\xed\x4b\xbb\xb4\xd7\x0b\xb7\x4f\xdd\x62\x11\x06\x56\x8c\x03\xb4\x3e\x77\xfa\x86\x75\xf3\x69\x37\x2d\xba\xea\xcb\x9e\xad\x08\x95\x35\x02\x34\x5f\xfa\xd5\x89\x3c\x0c\xbf\x31\x66\x36\xd7\xd9\xbe\xd1\xe2\xdb\xe4\x16\xac\xb6\xa9\xa0\x50\xef\xd8\xdf\x2f\x44\x1c\x02\x95\x07\x0b\xfc\xda\xda\x39\xfb\x6b\x70\x93\x88\x53\xa4\x76\x6f\xbb\xa7\xbf\x14\xaf\x50\xc1\x1e\x9b\x1e\xb6\x69\x30\x38\x89\x25\x29\xe2\xa9\x72\xb7\x43\xd5\x2c\xea\x26\xb7\xee\xb5\xbf\x0d\x87\x25\xd6\x09\xf1\x2b\xdf\xed\x36\xef\x95\xf7\xdb\xe1\x22\x49\x39\xe5\xb2\xb4\x5b\x3f\x5e\xad\xe5\x88\x84\x0b\xd7\x26\xd0\xf9\x67\xae\x8f\xb0\xb3\x36\x09\xfe\x30\xf2\x84\xbb\x8e\xfa\x30\x6f\x17\x69\x94\x7a\x71\x4f\xe2\xf8\xae\x47\x6a\xa2\x5c\xa4\x1c\x98\x23\x0e\x0f\xc4\x46\xa7\xb3\x61\x91\x9a\xcc\xab\xed\xae\xb0\x2e\xc9\x9b\x7f\x8a\xd6\xcf\x45\x96\x1a\x52\xc9\x27\x4d\xb2\xef\xd0\x29\xfe\x72\x91\x49\x1f\xd3\x3a\x01\xe9\xe9\x20\x47\x70\x08\x94\x23\xf1\x5a\x37\xda\x29\xfe\x2e\x17\x22\xb1\x89\xe7\xe2\x8f\xd7\xb9\xff\x0a\x61\x02\xd0\x9d\xe5\x4e\xf5\x76\x2e\xe5\x4d\xae\x13\x02\x12\xa0\x3d\xaa\x28\xf5\xb8\x0c\x2a\x00\x03\x52\xe3\x2d\x8e\xfb\x59\x25\xf3\xb3\x14\x39\x17\x60\x62\xda\xdc\x0f\xe5\x57\xbd\xbf\xf2\x2b\xc0\x98\x11\x42\x68\x00\x85\x6d\x73\x5a\x5a\x04\x66\x5a\x53\x11\x60\x84\x65\x11\x32\xb5\xfb\x54\x6d\x25\x16\xda\x10\xe3\xe6\xf4\xa3\xca\x9b\xcb\x3b\x3f\xac\xa8\x0a\x25\x62\xf0\xa2\x14\x3e\xbd\x5f\xb7\x5b\xae\x5a\xe7\xbe\xfe\x24\x14\x44\xde\x13\xfa\x7b\xd9\x38\x74\xcb\x68\x8e\xe8\xc0\xb6\x3f\xda\x59\x74\xac\x8a\xd5\x05\x9e\x59\x60\xca\x6d\xf6\xda\xce\x4b\xcf\x4e\xf8\x3b\xca\xe1\xe8\x46\x21\x22\xad\x58\x79\xfd\x84\x7b\x69\x6b\x76\x53\x82\x0c\x5c\x18\x66\x55\x75\x3b\xe2\x49\xfd\x9a\xab\x8f\x41\xdd\x45\x98\x58\x47\x71\x07\x6d\xfa\x36\x9f\x97\x79\xb1\x46\x92\x87\x1a\x74\x3f\xfd\x70\xc1\x48\xa6\x87\x50\x70\x65\x85\x23\x1f\x5a\x3b\x0a\x18\xd7\x94\x25\x6f\xde\xed\x00\x47\xf7\xe6\xc0\xd0\xa2\x68\x6d\xe1\x63\x80\x28\x1e\xfe\x4a\x20\x1d\x00\xe2\x1f\x34\x70\x7b\xec\xf6\x17\x08\x63\x99\x9c\xe5\x15\xfa\x0b\x36\x44\x4c\x07\xa9\x07\x23\xd4\x87\xb2\xe8\x48\x07\x10\x09\x45\x51\xf8\x01\x4e\x77\x65\x45\xad\x00\x7f\x04\x80\xe2\x7c\x17\x4b\xf4\xea\xca\x10\x07\x36\xbb\xed\x3a\x2c\x93\x7a\x9b\x17\x4d\xb6\xe1\xef\x88\x13\x6b\x2a\xd6\x2e\xab\x98\x7f\x22\x81\x4a\xbf\x1d\x36\xa3\x9a\x23\x24\x81\x65\xd7\x5b\x24\x85\x6e\xd3\x84\xc1\xfc\x87\x24\x46\x82\x13\xb7\x77\xde\x6a\xa9\x95\xd5\x6b\x45\xd5\xc4\x2e\x05\xb9\x72\x2f\xd3\x30\xa0\xf5\x53\x39\x5a\x9f\x6f\xe6\x40\x9a\x26\x24\xa6\x34\xfb\xd7\xb2\xfb\x13\x17\x00\x67\xa5\x92\xd7\x5c\xf5\x21\xf4\x7e\x90\x54\xa4\x89\x67\xd5\xc6\x7b\xdc\x1a\x7f\x5c\x27\xa4\x89\xe6\xf5\x8e\x37\x78\x95\xee\xde\x0e\xce\x08\xa9\x7c\x33\x7b\xfe\x7d\xf5\xf2\xf8\xe8\x64\xdc\x88\xd7\x73\x3e\x21\xaa\xa4\xa7\xad\x65\xa3\x9f\x9b\x53\x17\xda\x74\x97\x96\x49\xd0\xee\x3d\xbd\xb3\xc6\x6a\x17\xbe\x0e\x1c\xb8\x01\x5b\xad\x53\xa5\xbd\x77\xfd\xdd\x73\xfa\xb5\x03\x11\x33\x62\x71\x1d\x8e\xcd\xba\x29\x89\xf0\xda\xa8\x8b\xc9\x70\x85\x77\xf1\x6b\xb4\x8e\x07\x66\xfa\x6f\x12\x81\x71\x72\x3f\x6d\xba\x0c\x3b\x7d\x29\xf5\xc2\x41\x28\x15\xd8\xde\x30\x39\x49\x8f\x0e\x9a\x50\x38\x00\xda\x40\xe4\x2d\x08\x87\xfd\x09\x00\x80\x24\xe8\x25\x1d\xb6\xe3\x33\x4a\x86\x41\x72\x4e\x05\x3c\x27\x26\xb5\x2e\xab\x66\xd9\xbd\x41\x92\x2b\x4a\x42\x9b\x7c\x8f\x9b\x72\x0e\xbb\x7d\x77\x44\x5a\xd9\x6b\x8b\x80\x7e\xcc\x65\x05\xd5\xc9\xc9\xcc\x4e\x2a\x3b\x8c\x6e\xb9\x34\xda\xa8\x21\x31\xc2\xea\xf6\x0e\xb9\x48\xa0\x99\x95\x47\xaf\xc1\x74\x42\x4b\x37\xa7\xae\x86\x34\xb9\x95\x81\x0e\x39\x35\x9c\x72\x55\xfe\x80\xfa\xac\xca\xe7\x4f\x8a\x41\x42\xf1\xda\xed\xcd\xfc\xef\xfb\x3c\x80\x81\x50\xae\x71\x36\x5d\x79\x06\x0c\x03\xaa\x93\x3e\x1f\xcb\x3f\xf3\xc7\x1c\xfe\xde\x5c\x85\x83\x09\x53\x83\x5d\x14\xe1\xa0\x90\x53\x34\x1c\x30\x31\xa3\xa2\xcf\xeb\x6c\x35\x7b\x7c\x5c\x3c\x3e\x2f\x36\x3f\x5e\x56\xbe\xee\x03\x26\xc1\xcc\x05\x9f\x15\xe9\x0a\xbb\xf2\xf5\x78\xcb\x00\x93\x31\x5a\x86\xa8\x54\xba\xad\x06\x26\x52\x76\x88\x64\x91\x72\xac\xc1\x3d\xe4\x85\xc6\xca\x53\xe7\xfd\xeb\x2f\x99\xd4\xc6\x6b\x4f\x61\x51\xc3\xbf\x47\x73\x57\x32\x34\xd2\xd2\x5a\x16\xfb\x43\x73\xa1\x0b\xc6\x65\x10\x46\x54\x32\x7a\x87\xfa\x06\x3d\x4c\xee\x52\x7a\xc3\x8f\x4e\x90\xaa\x3c\x2f\xc5\x9b\xa7\x5f\xc9\x90\x31\xdf\xa5\x74\x36\xc1\x13\x2f\x91\x0c\xb3\x88\xb0\x08\x6f\xf9\x27\x2e\x9a\x77\x07\x36\x18\x26\xf7\x32\x0a\x8c\x88\x7b\xef\xc8\x23\x16\x6f\xcd\xfb\x9d\x63\xab\x4c\xcf\x64\xff\xd1\xd0\xe6\xfa\xb6\xa0\xb3\xcd\x6d\x9b\xa5\x3b\x31\xcf\x08\x12\x62\x8e\x7f\xe1\xcf\x81\xae\x05\x97\x11\x04\x81\x6f\xf7\xf9\xf9\xfe\x04\x3f\x57\x90\x77\xbb\x9a\x8c\xa4\x5d\x66\x1f\x60\xff\x17\x6c\xb7\xbd\xbd\x4b\x46\x2a\x23\x46\x09\x3d\xc7\x15\xaa\xf2\x13\xab\x73\xb5\xfa\xa5\xb8\xc1\x77\xd8\x99\x17\xb3\x42\x75\xac\x26\x54\x0f\x26\x63\x55\x19\x29\x4d\x59\xfb\x7f\xbe\x50\xf5\xbe\x2c\x66\x60\xf5\xc2\xe1\x67\x9b\xe3\xcf\x5d\x17\xf5\x5c\x4a\x95\x71\x94\xd1\xae\x32\x7f\x79\x7a\x5a\xac\xe6\xcb\xd9\xe3\xeb\xcb\xf2\x79\x33\x7f\x98\x2d\x9f\xd7\x7f\xae\x37\x8b\xa7\x6e\xa4\x90\x74\xc7\x66\x4f\xaf\xcb\xfe\xee\x2e\x63\xc8\xc8\xce\x79\xf1\xda\x53\xd7\x68\xff\x2c\xe8\x87\x7e\x21\x7e\x6c\xf7\xf0\xd3\xff\x3d\x8d\xb5\x8b\x13\x88\x26\x3c\xb5\xa4\xcb\x2c\x16\xca\x45\x05\x96\x8f\x39\x3a\x2c\x6d\x1f\x65\xd1\xbc\xaf\x4a\x5f\xde\x96\x99\x93\x83\xd4\xb8\xcb\x3f\xb1\x72\xd6\xe3\x43\x7a\xc4\x65\xb6\x26\x79\x98\x51\xb6\x06\x9a\x90\xef\xc3\xe9\x2e\x02\x71\xd6\x32\xed\xb8\xad\x0b\xbf\xfd\x49\x88\xad\xc3\x16\xcd\x10\xc2\x2f\x12\xa4\x64\xd4\xf9\x95\x90\x28\x4a\xa3\x09\x1f\x3f\xd3\x1e\x00\xbf\x9b\x00\xc0\xfb\x4f\xa4\x22\x8b\xba\x5e\x3e\x75\xe7\xef\xca\x6a\x7f\xdc\xc1\xa4\x3d\x2b\x97\x32\x44\xea\x7e\xee\xe1\xe7\xca\xb1\x86\xcf\x90\x6c\x29\x33\x45\x88\xb5\xad\x0b\xc2\x37\xe5\xa8\xd7\x33\x58\xde\xa4\x44\x4d\xfc\x86\x9b\x63\xbb\xa2\x9d\xe7\x93\xd2\x91\x66\x53\x32\x13\xe3\x40\x53\xea\x30\x20\x4c\xc5\xf6\x30\x36\x9b\x1b\xfe\x4e\x1d\x71\xd2\x45\xdb\xe1\x27\xee\xb6\xbe\x86\x52\x5b\xf7\xc2\xad\x3c\x75\x78\xcc\xe9\xdb\xa4\x13\x8b\xc4\xab\x9b\xf2\xd0\xbd\x8d\xbd\x5e\x9d\xd4\x99\xed\x72\x3f\xe3\xd7\x7d\x5e\x5d\xf2\xb6\x7f\x19\xd1\x4b\xcd\x35\x55\xbd\x8f\xa6\x2c\x75\x39\x98\xf5\x5a\x06\xd4\xec\xa5\x3a\x6c\xbb\x86\x74\x06\xf7\x5c\x6a\x95\x11\x5e\xe7\x00\x27\xba\x43\x2f\x45\x17\x2d\x4a\x6d\x8c\xec\xd0\x24\xf9\x18\xad\x2d\x11\x05\xe5\xbb\x54\x20\xea\xe2\x36\x69\x98\x55\x39\x20\x2b\x07\x8a\x54\x5f\x2e\xac\x4a\xfc\x50\xa3\x68\xca\x7e\x96\x0d\xd1\x0f\x08\x7d\x3f\xf8\x59\x8a\x21\x23\x50\xad\x7f\x36\xeb\x06\x3a\x6e\xa1\x0a\x18\xd0\x33\x76\x36\x96\x57\xa0\x39\x2a\xd0\x56\x17\x9f\x88\x7f\x83\x9c\x5d\x05\x46\x51\x5d\x4f\x1e\x4f\x2f\xc5\x75\xdd\x96\x5e\x99\x43\x85\xcc\x90\xd7\x20\x11\xfa\xab\xd9\x3f\x8f\xf8\x36\x8a\xc3\x55\x98\x46\xbc\xfd\x5d\xfb\xe3\xae\xc9\xdb\xd0\xf0\x29\x2f\x2e\x31\x87\x83\xf6\xe9\xa4\x5b\x1b\x57\xa1\x8e\x95\x38\x83\xaf\xd7\x79\xf1\x76\xe6\xeb\x3d\x8d\xdc\x05\xb9\x8a\x58\x4a\x00\x3b\x42\xef\x9e\x5d\x7a\xc3\x21\xa5\xe1\xc2\x94\x97\xab\x48\x59\x8b\xad\x45\xf3\x4e\x5b\x9c\x6f\x40\xfb\xfb\x14\x07\x60\x1d\x58\xda\x1f\x72\xae\xe2\xa9\x98\x23\xf1\x64\x65\xde\x78\xaf\x8f\x51\x4a\xaf\x92\x08\x14\x74\x4a\x89\x75\x47\x69\x1f\x0f\x93\x9a\xd6\x1d\xaf\xb6\xb3\x79\x58\xae\x6e\xb7\xb7\xb3\x3f\xad\x34\xbf\xbf\x90\x04\x23\x8a\xb8\x48\x6c\xcc\x47\xdd\x03\x25\x08\xff\x2b\xc3\x78\x34\x0d\x12\x4c\x68\xf1\xbf\xc7\x3e\x44\x5d\x71\xa9\x49\x02\xec\xb5\x2a\xd5\x19\x51\xac\x44\xc4\x6d\xe1\xab\xee\x6d\x9e\xd4\xc4\xe8\x53\x44\x95\x40\x43\xe9\x71\x7b\x63\x16\x9b\x07\x0b\x11\xbb\xb2\x04\x28\x00\x4e\x35\x72\xdc\xe7\xcd\x3f\x4b\x79\x93\xf7\x45\x8e\xce\x93\xed\x7c\x7b\x55\xac\x28\xad\x21\x22\xd8\xa2\x78\xcb\x8b\x0e\xaf\xae\x74\x92\x50\x65\x47\x41\xe1\x4a\xb4\x76\x19\x1d\xde\x56\x0d\x01\x7a\x89\x37\xaf\x3a\x3d\xea\x03\xf5\xbf\x10\x03\x20\xb8\xc6\x0d\xe4\xbb\x97\xe3\x80\x53\xaf\x10\x39\xb8\x2c\xff\x75\x07\x8d\x29\xab\xfd\xb9\xb7\x74\x59\xa7\x50\x26\x50\xa1\x55\x6d\x29\x3f\x8e\x07\x4f\x73\xbd\xf2\x8e\x1a\x9e\xe8\xc0\xb3\x00\xd7\xd8\xcc\xf3\xe6\x34\xc0\x98\xfd\xb7\x49\xd1\x7f\xb5\x5a\x2a\x03\x31\x99\x14\x39\x98\xfc\x35\x33\x67\xae\x19\xcb\xa8\xec\x48\x4f\xc0\x2a\x30\xed\xda\x3c\xb9\xa3\x17\x6b\x16\x84\x14\x38\x3a\xb3\x71\xf2\x8b\xef\x5b\xe9\x70\xcd\xa2\x2c\x75\xa5\xe7\x3b\xa8\x9b\x7b\x38\x74\x47\x20\x53\x8e\x62\x85\x45\x73\xd9\x13\xd2\x4c\x45\x61\xe7\x32\xfc\x08\x7b\x59\xd6\x3d\xbe\x89\x66\x28\x45\xbf\xa0\x38\x2b\xf4\x6d\x0f\xd2\x77\x7e\x78\x3a\x62\xd2\xc0\xd9\xdb\xf9\xa9\x74\xbe\xce\x94\xd0\xf9\x1f\x1b\x85\x01\xc1\xb4\xe6\x8f\xdf\x57\xe3\x04\x49\xc7\x91\xa1\x2e\xdc\xb1\xf6\x6a\xa5\x54\xdb\xb9\xa8\xca\xfb\xe1\x32\xa6\xf6\xf8\xfc\x65\x3e\x68\x2d\xeb\x18\x79\x14\x7b\x61\xc8\xfc\x33\xdf\xe1\x1b\xf6\x71\x4e\x3a\x0d\x25\x71\x0d\x5e\x1f\xfe\x38\xfb\x2a\x73\x9d\xa6\xf6\x2e\x92\x69\xc3\xc9\xa2\x10\x47\x39\xa6\x4e\x85\xa1\x10\x71\xdd\x94\x07\x77\x23\xfc\xc7\xb3\xd8\x66\x98\xd6\x2b\x82\x7c\x44\x87\xaf\x8a\xce\x52\x46\x35\xb1\xbe\x1b\xd4\xe4\xaa\xac\xb3\xd4\xca\xb5\xcc\xe7\x83\xf0\x52\x7b\xfe\xfb\x72\xfe\x32\x5f\x3c\x6f\x56\xb3\x47\x7f\x84\xb3\x20\xe5\x7e\x1a\x7d\x2b\xf2\x66\x45\xd0\xb2\xe9\x97\x41\x73\xa6\x49\x33\x85\x96\xf1\xed\xa1\xea\x84\xcb\xb9\xe6\x71\x92\x44\x83\x7a\x92\x85\xf5\x0f\x2f\x90\xa3\xb2\x38\x50\x37\xb9\xad\x7e\x67\x7d\x86\x22\x0e\x1b\x45\xe7\xcf\x19\x8b\x40\xc2\x4a\xa5\x59\xd6\xf4\x7f\x9b\x08\x2d\x40\x95\x6a\x4b\x14\xb4\xd1\xfb\x49\x30\x67\xdd\x66\xa2\x7e\x5c\xc2\xc8\xb8\x48\x97\x6d\x66\x67\x41\xd2\xfd\x80\x4d\x8b\x2c\x8b\x02\x2f\x87\x92\x2b\x5c\x37\x78\xc8\x46\xcf\x11\x18\x0b\xac\x2e\x10\x42\x7d\xac\x4e\x23\x28\x87\x86\x34\x61\x43\x95\x1b\x5a\xdb\xe6\xd5\xe9\xd0\x94\xe3\x73\x65\x49\xec\xe5\x1f\x8e\xa7\xa7\xbc\x98\x50\x2a\xd1\xa0\x03\x5b\x18\x6b\x77\xec\xbe\x3c\xd8\x70\x8e\xf7\x9d\x9d\xc7\xd1\xb9\x96\x2c\x24\xda\x03\x5a\x3d\xdf\xc7\xc5\xcb\xf3\xaa\x37\xad\x25\xcb\x88\xac\xa1\x7a\x12\xac\x0e\x51\xec\x47\xa4\xa1\xe9\x64\x6d\x27\x0a\xa7\x5a\x69\xe3\xaa\xb6\x2b\x6c\x72\x4b\xca\xf4\x55\xdb\xcb\xdd\x43\x6b\x91\x39\xe1\x19\x55\x92\x45\xfb\x1b\x76\x62\x80\xeb\xde\x9b\x8d\x0c\x3c\xbe\x74\xc8\x0c\xd0\x28\x19\x71\xa2\x88\x33\x71\xec\xf3\x98\xae\x55\x2e\xff\x4f\x38\x71\x8b\xba\xb3\xe9\xd0\xf5\x18\x6c\x14\xe6\x55\xdf\x2f\x54\x52\xa6\xd7\x62\x34\x16\xc6\x77\x5e\xe2\xf4\xbc\x42\x9d\x5b\xa7\x7f\x7f\xcd\x86\x85\x14\x48\x58\xde\xf4\xdf\x08\x08\x68\x13\x04\xd4\x6a\x5c\x3b\xed\x9e\x8b\x2a\xc1\x95\x8f\xa5\x56\x2f\xb8\xdd\xf6\x6d\x31\xaa\x99\xe0\xb6\x6b\xa3\x0c\xe1\x25\xb6\xb9\xab\xae\xf6\xd1\x08\xc8\x82\x80\xea\x2d\xf2\x58\x15\x43\x0d\xaa\x7e\x6c\x86\x2c\x94\x5a\xf4\xfc\xd5\x27\x88\x07\xc8\x74\xca\x3d\x8f\x75\xb6\x9c\xee\x12\x61\x10\x5a\x95\x70\xb7\x53\xbd\x82\xfa\x80\x37\x9c\x5b\xb7\xa8\xd1\x09\x83\x38\xa5\xa4\xa8\x17\x64\x95\xbb\x5c\x9d\x3c\x40\xe5\x3c\xcd\x30\xd4\x69\x66\x31\xe9\xb5\xaa\x72\x89\x9b\x7c\x87\xbf\x75\x1c\x64\xbf\xb6\x60\xe8\x64\xbb\x89\x88\x6e\xef\xc6\xf4\xd6\x81\x51\xa6\x48\xcb\x64\xb9\xb9\xef\x2f\xaf\x18\x49\x4b\x48\xa6\x82\xe4\xbe\xac\xa6\xcd\xb3\x38\x46\x5a\x08\xca\x74\xdb\x2d\xac\x9d\xe8\x8b\x42\xf7\x22\x3e\x8c\x93\x98\xe6\xe1\x97\x4f\x6c\x71\x8c\x15\xc3\x18\x2c\xc6\x89\x68\x9c\x26\xaf\xf6\xe3\x22\x17\xc6\x2a\xa2\xf0\xeb\xfe\xe9\xe5\xe5\xb9\xfb\x98\x0e\x29\xb3\xdd\xce\x96\x8b\x9f\x8e\x3d\xd4\x2f\xc0\x63\x12\xa5\xd2\x35\xa9\x6d\xdc\xd4\xc3\x9f\x61\x0a\x92\x88\xa5\x66\x5a\x48\x75\xf4\x2b\xb3\x04\x02\x65\x7d\x85\xdb\x6d\x7a\x71\xfb\x6d\xf8\x55\x19\x4a\xe2\x65\xbf\xae\x16\x5b\x8a\xa8\x83\x1f\x8b\xc5\xef\x7d\xad\x46\x8e\x3c\xc9\x88\x1b\xf4\x9f\x23\x56\xf9\x18\x76\x84\x02\xed\xd1\xf6\x16\xad\xf3\xfd\x61\x87\x6b\xac\x3e\x7d\x01\x6c\x68\x6b\xd4\x5f\x02\xfe\x67\xf4\x3c\x41\x49\x4a\x12\xee\x49\x4c\x6b\xf4\x8e\xa0\x54\x8a\x60\x0e\x6d\x62\x67\x75\x87\x46\xbf\xf7\xff\x24\xe7\xb5\x36\x3a\x63\x4b\x3d\x65\x11\x95\x4a\xbd\xc2\x01\x89\x55\x74\x82\x5d\x64\x8c\xe0\x43\x29\x54\x98\x46\x16\x8c\x75\xf0\x3e\x0f\x7f\xb3\x38\xa0\x36\x31\x85\x2a\x5b\x2b\x5e\xe3\xa6\xc2\x30\x8c\x1d\xfe\x18\x64\x4c\x5a\x1d\x7f\x7a\xf8\x97\x51\x31\x62\x20\xa9\xaa\xee\xb7\x2e\x5b\x34\xf2\x07\x85\xb6\x58\xc8\xf6\x8f\xcb\x42\x95\x6f\x45\xde\x94\xdd\x51\x34\x94\x84\xd9\xc5\xd3\x37\x60\xd0\x64\x16\x4c\xde\xa9\xfe\x59\x91\xdb\x5f\x78\x96\x73\xc3\xb4\x24\x7f\xa9\xca\x2b\xc5\x38\x32\xf3\xd8\x58\x9e\x9b\x20\xd0\xc4\xe6\xb8\x59\xaf\x7b\xb5\x41\x13\x86\x01\x15\x43\x16\xaf\x7f\xd0\xca\x37\x98\x7b\x26\x04\xab\xea\x6b\x75\xab\xba\x57\x68\xd3\x97\xf9\x1b\xdc\x38\x13\xb1\x88\xd6\xf6\x75\xbb\x3a\xd8\x34\xc5\x6d\xbd\xc7\x4b\xfa\xac\x89\xc0\xee\xff\xaa\xf4\xc5\x21\x4f\xfc\x32\x91\x01\x74\xe1\xc5\xcb\x27\x56\x35\xb5\x58\x87\xdf\x95\x06\xca\x7d\xba\x30\xf9\xdb\xea\xd8\x73\x34\xe1\x26\x0b\x05\xa1\x15\x1d\x6e\xff\xb1\x54\x1f\x97\xe8\x36\x93\xa5\x10\xba\x90\x7e\x3e\x7f\x70\x3c\xb7\xee\x14\xda\x6a\x9a\xef\xa0\xb6\x48\x80\xad\x09\xa2\x07\xa8\xdf\xb7\xee\x57\xf8\x81\x9c\x49\xb2\xf1\xb0\xbd\x8d\x6e\x0d\xea\x87\x4b\x86\x47\xc2\xfa\x94\xff\x3c\x60\x51\x9f\xe5\x19\x0c\xcf\x22\xcb\x91\x7a\xa7\x10\xa0\xe3\xd4\x9e\x57\x66\xc3\xb9\x6d\x28\x78\x47\x54\xbc\x87\x7a\xa2\x82\x6d\x44\x98\x5a\xda\x3a\xec\x3e\x46\xf5\x40\x23\x92\x98\x14\x68\xca\x03\x16\xaf\x76\x8f\x7c\x85\xaa\x99\xb7\x7b\xab\x7f\xb7\x8c\x48\x63\x6f\x5b\xb3\x7e\xcf\x0f\x9e\x53\x32\xfa\x96\xd4\x66\xbf\x8f\xf0\x17\x74\xde\x58\xdc\x08\xc9\x28\xe5\x04\xad\x5f\xe1\x84\x57\x12\x31\x23\xa4\xa6\x8d\x1a\x2c\x5a\x29\x2f\x0b\x02\x2c\x0e\x07\x41\x10\x80\xec\xc4\xa6\x9c\x1c\x45\x39\x4d\x2d\x32\x10\x86\x04\x16\xb8\xbf\x9f\xfb\xf2\x82\x91\x59\x42\x6b\x89\x82\xdd\x6e\x88\xce\x37\x2a\x4d\x82\xc8\x91\x08\xa0\x38\xf9\x86\x80\x05\x07\xb9\x31\x3a\x8a\xa9\x45\xf2\x70\xdc\x43\x91\xff\x67\x39\x7f\x99\xde\xe2\x8c\xe6\x82\x59\x61\x86\xbf\x55\x6c\xe5\x46\x2b\x90\xae\x9d\xba\x3e\xee\x2d\x93\xe4\xc5\x38\x2a\x10\x01\xc3\xea\xd7\xaa\xbc\x2d\xd5\xb9\x0a\x67\x30\x00\xa2\xa3\x49\x28\x2e\xa5\x48\xb9\x41\x9d\x30\x77\xca\x36\x1d\x8c\x89\x68\x31\x7a\xf2\x26\x88\x88\xd8\xb1\x87\xe2\x08\xbb\x36\x72\x6e\xfe\x86\x08\x30\xb8\x6a\x13\x05\x74\x05\xcd\x7b\xd9\x67\xf3\x08\xc6\x22\xae\x55\xa7\x13\x3d\xd3\xff\x3e\x92\xf7\x8d\x3f\x1a\x87\xa4\xa5\x38\x9f\xad\x66\xdd\xdf\x9c\xfe\xab\x75\xc0\xb2\x28\xb8\xcd\x85\x64\xa8\x60\x0c\xac\x00\xc0\xdc\x62\x84\xe6\xef\xf9\x61\x38\x09\x05\x0b\x18\x97\x9e\x10\x71\x82\xa2\xb9\xad\xca\xbc\x59\xa8\xb2\x28\xf7\xf9\x7f\x8e\xb8\x9d\x97\xfb\x43\x83\xfe\x5d\x16\x2c\x48\x02\x95\x9e\x0d\xd0\x9d\x78\xf2\xd4\x73\x12\x2c\xe0\x09\x4d\xf0\xf9\x00\x4c\x2d\x58\x18\x1a\x82\xc2\x6e\x36\x9b\xee\x4f\x28\x98\x75\xc1\x6e\x7f\xfd\xa2\x4d\x69\x77\x38\x68\x20\x4f\xbd\x05\x82\x45\x59\x06\xbe\x87\x0d\x0d\xbe\x95\x43\x6b\x1d\xc1\x22\x29\x91\x39\xbc\xd6\xbf\x8e\x58\xb5\x89\xf2\x95\xcb\x8d\x54\xc0\x5c\x63\xb0\xa3\xea\x0e\x4f\x16\xb3\x94\x72\x78\x45\x5c\xd6\x2e\xa2\x41\xd5\x37\xc0\x9d\xbe\xd0\x38\xb1\xe0\xe8\xca\xb6\x8d\x26\xa4\x43\x05\x4b\x12\x2b\x0e\x71\xb0\xba\xb4\x74\xcf\xfc\x97\x9c\x33\x27\xc1\x12\xf7\xb2\x3c\xe3\xd7\x2b\xd4\xb5\x47\xc8\x8d\x2f\x60\xd8\x43\xeb\xcf\x65\xc1\x12\xa7\x44\x59\x63\xf3\x8c\x5f\x13\xdd\x4f\xc1\xd2\x50\x72\xd7\xee\x6e\x9c\xd7\x0e\x5c\x7a\xdf\x0a\x96\xa6\x11\xba\x32\xd8\x7d\x85\x04\x58\x1b\xdc\xb4\xd4\x18\xc1\xcf\x1a\x3e\x3d\xf1\x21\xc1\xb2\x4c\x2b\xf0\xe8\xb1\x73\x47\xc2\x1d\xe5\x2a\xa6\x7b\xb6\xdf\xee\x10\xbf\xe0\xe4\xff\xde\x66\xcc\x0e\xd6\xbc\xdd\xfb\xf2\xd3\x36\x2f\x4c\x39\x0a\x46\xba\xf1\x9c\x94\x63\x9c\x60\x78\x33\x3e\xac\xad\xb5\xfa\xfd\xfc\xb5\x6a\x77\xc7\xc1\x5c\x85\x30\xa5\x2e\xbd\x7d\x0a\x74\xf1\xdd\x2b\xd4\x46\x5f\xe7\xda\xa7\x60\x90\x88\x4c\x9e\x15\x76\x2f\x5d\x5b\xff\xae\x26\x37\xb8\x6f\x90\x02\x74\xd9\xd0\x64\x01\x7e\x30\x79\x80\xa7\x41\xe4\x29\x85\x9a\xcc\x82\xe6\xef\xf9\x4e\xff\x36\x7c\xf0\xc0\x2d\x28\xaf\xc1\xba\x21\x3c\xe0\x73\xe9\x04\xec\xfa\x94\x20\xc1\xa4\x12\xe4\x47\xf6\xb5\xa5\xf0\xa9\xc3\x9d\x09\x26\x0d\xc4\x96\xb4\x5e\xbc\xed\xf0\xf6\xfb\xf2\xf5\x5f\xcd\xe9\x7c\x50\x69\x76\xae\xcf\xd3\x39\x6d\xe6\xde\x0d\x40\xe0\x0e\x7f\xd7\xa9\xef\x08\xa6\x1c\xbf\xd2\x97\x3b\x37\x3f\xef\x10\x5f\x21\xd7\xf7\x63\xdb\x3d\xc1\x54\x2a\x08\xdc\x77\x2c\xba\x4e\xdc\xb7\xb1\x52\xa0\x60\x5a\x84\x89\x67\x50\x3a\x6b\xdf\x61\x52\x23\x18\xc6\x8a\x5a\xc5\xc5\x71\xff\x62\x9c\x99\x48\x27\x80\x22\x18\xf2\x90\x92\xfd\x3d\x7c\xe0\x6b\x55\xea\x63\x17\x8a\x5c\xd1\xc7\xf1\x9f\x83\x6e\x7b\xba\x50\x71\x15\x0c\x8d\x95\x77\xab\x10\xf4\xac\x80\xdd\xa9\xc9\x55\xfd\x04\xdd\xa4\x37\xb1\x22\x7c\x86\x2e\xe7\xbe\xa4\x75\x15\x1d\x35\x7c\xb4\x06\xad\xf6\xfe\x81\x2a\x60\x8b\xcd\xc3\xf0\xbe\x05\x01\xd3\xc4\x7d\xbb\xdd\xcc\xe7\xdb\xe5\xe3\xcb\x8f\x2d\xff\xcd\x1f\x8a\xa4\x2b\xb0\xd1\x82\xd6\x40\x63\x17\xdf\xfe\x84\x0c\xc2\x48\x05\xb6\x23\xdd\x46\xe1\x47\xaf\xa2\x22\x82\xd0\x70\xea\x49\x51\x2a\x15\xf6\xad\x35\x44\x10\x05\x11\xe1\x00\x17\x85\x7e\x31\x0e\x52\x3b\x1d\x84\x8b\x20\x8a\x33\x6d\x3c\x45\x62\xb8\x8a\x04\x51\x66\xd1\x8e\xa4\x6d\xa5\xd7\xea\xdd\xc2\xe9\x1c\xa5\x98\x2e\xfb\x52\x54\xb6\x0b\xfd\x44\x10\xf1\x98\xea\xe9\x9f\x39\x7e\x79\x6e\xa7\x3b\x14\x07\x01\xb1\x14\x24\x14\x1f\xab\x72\xd7\xe6\x4b\x38\x72\xaa\x10\x41\x1c\x87\xb4\x86\x3c\x1d\x77\x4d\xbe\xce\xdf\xec\x92\xd9\x26\x2d\xb7\x90\xef\x4e\xb6\x86\x76\x51\xe8\x19\xfd\xc0\x24\x4e\x09\x4c\x77\xd7\x35\x70\x44\x90\xb2\x88\x70\x64\x5f\x79\xf3\xbe\xa2\x1e\xea\x78\x2a\x07\x69\x08\x5e\xeb\xfa\xcf\xe3\xfe\x87\x13\x50\x18\x9e\x3a\x4d\x12\x9e\x9d\x39\x98\xe3\x33\x18\x45\x4a\x31\xf7\xb0\x83\x9f\xa7\x80\x31\xff\xed\x59\x18\x91\x3c\x76\x1b\x95\x7b\xc6\xe6\xf4\xb5\x67\xc2\x3e\x9c\xbc\x5e\x37\xe5\xc1\x97\xc4\x44\x90\x81\x4c\x54\x8f\x85\x3b\x7c\x6c\x19\xa6\xae\x8d\xa1\x5d\x3c\x76\x99\x2a\x07\x23\xb4\xce\xaf\xfe\xeb\xcc\x7d\x86\x7e\xbf\xa2\xdd\x5f\xc9\xd0\x62\x9d\x5b\x55\x5f\x17\x8c\xde\x5e\x6a\x5a\xf9\x0f\x28\x93\x86\x36\x7a\x5e\x34\xef\x54\xfd\xf6\xef\x7d\x20\x8c\x97\x94\x26\x07\xdf\xcb\x04\x41\x04\xa0\x03\x2a\x77\xb5\x49\xc0\xd6\x54\xd8\xcd\x25\x30\xb1\x74\x82\x57\x95\xae\xda\x94\xe9\xd0\xdb\xef\x02\x99\xc4\x24\x4b\xf6\x7d\xf9\x7d\xd6\x6d\x0f\x94\x96\xff\x36\xe9\xdc\xdd\x9b\xc0\x92\x87\x29\x3b\x07\x5e\x6b\x85\xc5\x04\xd4\x7d\xfa\xc5\x92\x98\x49\x87\x1d\xa2\x18\xc8\x76\x96\x87\xf1\xad\x08\x74\x06\x94\xc2\x6e\xbe\xf7\x77\xc0\x40\x73\x45\xb7\xe3\x00\x75\x7d\x19\x3a\x8b\x00\x23\x21\x1d\xdc\xc1\x6a\x98\x1c\xa7\x89\x63\x22\xc0\x24\xb4\x0b\xc8\x85\xa8\x9a\x08\x90\x6b\xea\x54\xb4\x71\xda\x0a\x46\xdc\x0f\x11\x18\x96\xa2\x87\xef\x91\x91\xed\x1d\xb4\xb3\xe9\x34\x16\x15\x1b\x5c\x5a\xc8\x82\x98\xb2\x17\x79\x3c\xfd\x8e\xc4\x8e\x5b\xa1\x31\x83\x19\x1a\x32\x19\x92\x74\xf6\x4d\xde\xbc\x14\x37\x70\xfa\x95\x57\xd2\xe0\x9a\x42\x86\x3a\xb6\x22\xf5\xb6\x02\x79\x1c\x48\x5c\xfe\x63\x78\x29\xed\xe2\xe6\x5e\x84\xbb\xd5\x6c\x74\x9d\x41\x22\xe8\x1a\x1e\x73\x12\x02\xb0\xed\xcb\xbf\xb5\x42\x18\x7f\x43\x6a\xb9\xda\xd6\x60\x6c\xe9\x51\x98\xa5\x6f\x73\x74\xc3\x90\xd2\x10\x43\x40\xce\xbb\xb2\x3a\x5f\xfc\xc5\x13\x0b\x03\x8e\x1a\xba\x8a\xf9\xb5\x80\x34\x0c\x44\x44\x79\x7b\xf3\x2b\x1f\x91\xe1\x89\x55\x6c\xb1\xc3\xed\xdb\x61\x97\x6f\xaa\x0c\xf8\x33\x86\xed\x2e\xdf\xce\xc5\xd9\xef\x8f\xcb\xa7\xd9\xef\xb3\xe7\xee\x88\x88\x88\xd3\xee\xdb\xeb\x1d\x36\x11\x0b\x24\x7d\xe6\x5e\x77\x64\x78\x83\x42\x14\x9e\x60\xf4\xcf\x52\x7a\x95\xb8\x51\x42\x14\x86\xc6\x44\xc2\x01\x40\x8e\xe3\x53\x44\x51\x42\xec\xe0\xd9\xed\xf7\xe5\xfa\x65\xb5\x76\xee\x39\xfe\xda\xa2\xb4\x13\xe2\x5f\x03\x55\x51\x66\xbb\xfc\x73\xb4\x78\x84\x91\x10\x76\x2b\xb2\xb2\x0f\x53\x16\x2f\x22\x8c\x20\x86\xc8\xd3\x33\x9c\xd2\x04\x41\x42\xa6\xc8\x59\xfe\x33\x98\x50\xcc\x56\x94\x56\x78\xf1\x06\x76\xbb\xb2\x71\xaa\x5c\x6e\x4c\xcc\xd2\xb4\x13\x1a\x69\x13\x4d\x3d\xfa\xe2\x38\x09\xc8\x0e\x85\xc0\x31\xa8\xd7\x60\xd0\x02\xcb\x47\xbf\x22\x36\xd6\xc7\xe0\xf5\xfb\xeb\x76\xf9\xbc\x59\xac\xbe\xfb\xee\x9e\x08\x93\x30\x21\xe5\xa6\xf5\x7b\x55\x96\xfb\x3b\xa8\xf6\x5d\x3e\x1b\x26\x31\x86\x5d\xd9\xbb\x3e\x92\xf8\x8b\x6b\x0f\x0f\x2f\x24\x0d\x30\x75\xd1\xc0\x62\x35\x0f\x99\x2b\x51\x92\xaa\x1e\x99\x0a\x74\x6b\x63\x98\xca\x94\x74\xa7\x6a\xf8\xc4\xd7\xb2\x1e\x76\xff\x44\x98\x6a\xe4\xc2\x85\x5c\x4b\x5b\x70\x1a\x0e\xc8\x20\xa3\xd9\xa8\x2b\xc8\x8b\x5e\x01\xb2\x3d\xc2\x11\x5c\xc9\xf7\x2e\xdf\x5d\xc6\x18\x6e\x1c\xcf\x2c\xd1\x62\xa4\xc8\x31\xf3\xbc\x3d\x11\x72\x19\x29\xa7\xea\xf7\xea\x38\xd4\xa3\xab\x10\x81\xca\x3c\x01\xae\xdc\x69\x7b\x53\x1e\xa1\x6e\xe0\xa8\xf3\x26\x1f\x3f\x28\x88\xe3\x30\x74\x00\xdd\x73\xdf\xcf\xe9\x6a\x0c\xaf\x4e\x46\xb6\x07\xb9\xcf\x8b\x76\x6d\xe8\x08\x6e\x83\x90\x3f\x94\x51\x4a\x80\xac\x9b\xf2\xbc\xfc\x5e\x97\x24\x0b\x42\xfe\xeb\x7f\x7f\x65\x34\x27\x42\x99\xda\x47\xd6\xbe\x04\xfd\x5a\xa9\x08\x65\x96\x51\x38\x36\xcf\x9b\xea\x58\x5f\x26\x51\xc3\xf3\xe8\x34\x51\x0e\xd2\x49\xfb\xe8\xcd\x69\x35\x72\xc9\x16\x21\x26\x59\xa0\xfb\x94\x8d\x4b\xd7\x5c\x11\x62\x06\x2e\x79\xa3\x00\xca\xea\x54\x0f\xbf\x0b\x55\x47\x7a\xb4\x2d\xb7\x51\x6f\x55\x84\x26\x60\x59\xea\x3b\x2d\xb5\xed\xb4\x9c\x15\x7b\x45\xc4\x38\xf3\x93\xc0\xaa\x64\x4c\x2f\x55\x11\x33\x8a\x98\x70\x77\x50\x37\x96\x23\xfa\x8c\xcd\x57\x59\xf9\xf5\x31\x0a\x82\x44\x9e\x15\xd9\x1e\x72\xad\xa7\xfa\x60\xed\x38\x4e\x30\x87\xf9\xeb\x7c\x04\x60\x10\x51\x18\x65\xe4\x73\xb9\xcd\x6b\x22\x7f\x9e\x19\x74\x93\xc0\x55\xff\x29\x29\x89\xd5\x76\x2e\xe6\x42\x10\xfa\x53\x46\x99\x4e\x5d\x47\xea\x31\x2f\x06\xac\x18\x11\xc5\xcc\x7a\x11\x75\x0d\x98\x1e\xa1\x5d\x44\xb1\x4e\x08\xcb\x99\xd7\xaf\x58\xed\xa1\xc0\xa2\xd9\x9d\xae\x75\x1f\xdd\x67\x12\x06\xf4\x76\x16\xb0\xbf\x20\x7e\x8b\x28\x89\x33\x67\x94\xdf\x75\xe8\xad\x3c\xce\x68\x98\xe1\x44\x56\x59\x16\x75\x03\xaa\x54\x25\x5c\x99\xfc\xc3\x8f\xa5\xa1\xb0\x16\x84\xde\x42\xa5\xdd\x0e\xd6\x0f\xb3\x55\xf7\x8b\x52\xe0\xca\xeb\xd6\x20\xea\x9b\x93\x73\x0d\x1d\x4c\x99\x28\xd5\x9a\xca\x2c\x5f\x55\xde\xe0\x50\x75\x66\xfa\xe5\x1b\xdc\xd3\xd4\x35\x11\xc1\xf6\x38\xfc\x57\x67\x49\x4a\xe5\x34\xf5\xde\xa6\x29\xde\x6b\xa2\x3b\x9a\x05\xd4\x09\x53\xb6\x0f\x71\x8b\x87\x5d\x69\xb9\x8e\xe3\x42\xe6\x60\x81\x8a\x32\x99\xd1\x64\xba\x39\x56\x85\xe9\x6f\xf1\xc3\x5f\xc4\x21\x24\x9b\xee\xba\x34\x8d\x82\xc3\xb2\x18\x2c\x33\x91\xc8\x90\x4a\x04\x17\xa2\x97\xd7\xfe\xbd\x0c\x86\x23\xc1\x19\xe9\xe6\x6e\x5e\x5f\xe7\x21\x0b\xf8\x7f\x1d\xb4\x45\x42\x05\xa6\xef\xb6\x76\x99\xb3\xb9\x81\x10\x87\x24\xdc\xb7\xcf\x0b\x6f\xe4\xe8\x8f\xf0\x90\x76\xf9\x2d\x52\x24\x3a\x7a\x9e\xc0\xc1\x77\x9e\xbb\x4e\x48\xe8\x13\xed\x48\x05\xf6\xd6\xfb\xaf\xb7\xb7\x66\xc2\x6d\x7e\x74\x35\x8a\x6b\x8b\xe0\xfe\xc8\xfb\xfc\x2c\x11\x29\x21\xd1\xeb\x2f\xd9\xc4\xa0\xcd\x65\x2e\x65\x8b\x45\xa4\x94\x15\x20\xd0\xb6\x8c\x6f\x39\x44\x65\xbf\x72\x72\xe5\xbb\x75\x22\xbd\x25\xc1\x7d\x6e\xcc\x4d\x17\x0c\x74\x13\x43\x9b\x0c\xe1\x9a\xcf\xfc\xf0\xb5\x41\x96\x52\xa1\x67\x0e\x3b\x35\x22\x12\x0f\xbf\x15\x53\xdb\x45\x7f\x82\xea\x2d\x2f\x6e\xa0\x50\xfe\x27\x9b\x54\x80\x77\xd2\x25\x97\xf4\xb3\x7f\x85\x88\x8c\xca\x08\x29\xb3\x25\x05\xeb\xb7\xbc\x20\xd5\xc8\xdf\xf1\x34\xbc\x1b\x31\x8b\x55\x68\x95\x97\x0f\x3b\x38\xcd\x8a\x1a\xab\x1f\xfd\x0c\x7c\xdc\x73\xfd\x9f\xc1\x7b\x17\x33\x10\x51\xea\xa4\x89\xac\x7a\xee\xe8\xfc\x61\x1c\xd2\xee\xec\xdc\xeb\x66\x85\x9e\xc3\xee\x8a\xf7\x94\xbf\x8f\x71\xa8\x22\x52\xc5\xdb\x36\xbf\x72\x67\x16\x71\xc4\x32\x69\x95\x6d\x2b\xaa\x2e\x75\xd9\x78\x1c\x67\x48\xfd\xd6\x63\x8d\x95\x87\x84\x0d\x3f\x1b\x0b\x25\xc3\x6e\xe7\x98\x75\xc4\xd0\x39\x5c\x08\xfe\x89\x38\x96\x8a\x76\x69\x0a\xd3\x37\xef\x15\xd6\xef\xe5\x4e\x8f\x42\xe6\x38\x0d\xad\x0e\xfd\x1c\xaa\x55\xdf\xf5\x0a\xf2\xdd\xa8\x87\x2e\xe2\x34\x11\x16\xaf\x45\x5f\xbf\x1c\x19\x18\x8a\x38\x35\x16\xbe\xbe\x6b\x57\xea\xef\x58\xd5\x1d\xe1\x41\xc4\x59\x1a\x12\xd2\x38\x57\xe5\xf3\x71\x8f\x15\x34\x65\xdf\xfb\x51\xc4\x99\xd4\x5e\xef\xe2\x09\x0e\xa3\xdf\xc2\x99\x4d\xb2\x2c\x36\xb0\x26\xad\xf5\xbb\xe5\xdd\x6c\xa9\xeb\xb5\x07\x40\x8b\x98\x47\x8a\x82\x73\xc2\x1c\x3d\x74\xfa\x8a\x22\x16\x3c\x26\xad\x80\x9b\x97\x6f\xcf\x9b\x3f\xb7\xab\xc5\x8f\xd9\xea\x76\xb0\xe0\xc7\x90\x01\x35\x72\xe6\x2f\xcf\xcf\x8b\xf9\x66\x7a\x3d\x72\x63\x65\x62\xfd\x15\xb6\xa0\xf5\x0a\xd5\xe8\x2e\x49\x1e\xd8\x35\xf2\xfe\x67\xff\x6d\x8f\x55\xc6\xb5\xdb\xd2\x66\x87\xc3\x6f\x53\x2b\x5c\xac\xb8\xf5\x70\xff\x66\xe9\x31\x84\x16\xde\x2e\xe7\x2f\x24\x25\xb2\xde\xcc\x9e\x5e\x47\x5f\xa6\x99\xed\x68\xdb\xc2\x82\x85\x1c\x5c\xab\x58\x4f\xbe\xab\xb1\x0e\x45\x66\x9c\x8c\x08\x16\xfa\x82\x1a\x3c\x98\xed\xfe\x33\x88\x51\xd8\x43\xf1\x78\x0c\xd6\xf4\x8c\xc7\xc0\x7a\x10\x54\x47\x17\x35\x8f\xae\x00\x63\x50\xb6\xaa\xfa\x9f\x4f\x7c\xaf\xf0\xed\xb7\xe9\x2e\xc8\xd4\xa3\x40\xc9\x08\x38\x32\xcf\xf7\xb2\xdc\x9f\x9b\xfa\x22\x36\x71\x26\x5c\x77\x69\xd9\xe0\xbe\xb6\x24\xa5\xee\x28\xe7\x67\x03\x03\x27\xad\xf3\x50\x5e\x5b\xf9\x62\x23\x32\x09\xde\x55\x76\x57\x56\xf7\x15\x9e\x1f\xac\x41\xeb\x99\xde\x69\x31\xe5\xcd\x3b\xad\x6b\xf8\x6b\xff\x1f\x91\xb0\xc4\xfa\x6d\xe4\xb5\xdf\x50\xc9\x8d\x63\xf0\xdd\x09\xcb\x34\xb5\xe7\xc1\x82\xe3\x36\x65\xb7\xf9\xfa\x01\x22\xa5\xdd\x6e\xb9\x3f\x80\xea\xc2\xa5\xe9\xa5\x39\x61\xca\x31\x67\xda\x77\xe4\x82\x0d\xe3\x06\x05\x42\xf8\x0e\xd3\x2d\x82\xde\xe5\xc5\x28\x0f\x4e\x02\x23\x24\x38\xf4\x1e\x35\xa6\x5d\x3b\x7d\x74\xa2\x88\x19\x8a\xa9\x87\x50\x44\xf2\x36\xbf\xb2\x77\x27\x71\x16\xb3\xb8\xef\x93\x72\x59\x1a\x1e\x7e\x47\x6c\x22\xe1\xaa\xd4\xbd\x70\x3d\x49\x43\xcb\xee\xcf\x8b\xbc\x79\x5a\x6c\x86\xea\x25\xbf\x7e\x2c\x59\x1c\x51\x19\x9f\xec\x5e\xd6\x4f\x2b\x53\x56\x6d\x32\x38\x1c\xc4\x23\xab\x46\xb7\x2f\x75\x6e\x4e\xae\x4b\x3b\xdd\x9e\x17\x09\x4f\x43\xea\x7a\xdd\xe4\x8d\x2a\xf3\xe2\x75\x77\xac\xbb\x0b\xe5\x4a\x49\x8f\x21\x85\x0a\xf6\x13\xa4\x29\x37\x52\x64\x19\xad\x82\x38\xc6\x7c\x8a\x44\x00\xa3\xa0\xb1\xdd\x3b\x68\x61\x1e\x7e\x3f\x40\x44\x61\xc0\xfa\x50\x56\x4d\xdd\xf3\x15\xf7\xc7\xb5\xa0\x05\x12\x8e\xcd\x3b\x16\x4d\xae\xc6\x58\x1f\x91\xc8\x34\xa0\xf4\x60\x7b\x2c\x28\x4d\x5d\xc3\x1e\xd7\x6d\x1e\x44\xaf\xd7\x35\xc9\x99\xd1\x2f\xd0\x2c\x35\x8e\xf1\x70\x93\xbf\xbd\x56\xe5\xbe\xec\x47\x00\x89\x46\x4e\xe1\xc1\x1c\x0e\x2b\x04\xf5\x7e\x85\xe1\x28\x12\x8c\x38\xed\x84\x8b\x02\xab\xb7\xd3\x53\xa9\x1d\xbf\xce\xf7\x53\xfd\x30\x6e\x3b\x80\x2f\x75\x5e\xe5\xdd\xb7\xa0\x12\x88\x9d\x19\x66\x5f\x49\xd9\x8f\x30\x31\x67\x59\x0f\x86\x65\x81\xc9\xe7\xc3\x60\x9b\xb8\x16\x12\xf4\xec\x55\x7c\x44\x62\x74\x18\x76\x4a\x83\x7d\x99\x4c\x91\x32\x1e\x10\x34\xe4\x3b\x36\x55\x7e\x26\x0b\x8a\x94\x69\xab\x39\x39\x53\xaa\xdc\xef\x4b\x4d\xbf\xa3\xb7\x92\xa5\x41\x66\xa8\x49\xdb\x7e\xa8\x0d\xdf\x97\xaa\xec\x0e\x71\x70\x32\xdb\xb5\xf3\x76\xbc\xab\x6c\xa3\xd7\x6b\x85\x8b\x34\x10\x36\x8d\xa4\x96\x16\x85\x8f\x3f\x3a\x83\xe1\xb1\x82\x96\x48\x43\x6d\xf5\x0c\xd6\x70\x02\xdd\xb7\x5f\x6e\x0f\x19\x2a\x83\x6e\x0f\x58\x99\xb2\xda\x6f\x7a\xeb\x1d\xc5\x5e\x38\xa1\x19\x39\x99\x80\xa5\x11\x57\xd4\xfa\xb7\x20\xe7\x5d\x6e\x70\xf0\x4d\x11\x30\xda\xc8\x5f\x7e\x3c\x6f\x8d\x23\xad\x0f\x5e\xab\x5e\x3e\x91\x46\x90\x12\x6f\x60\x59\xb4\x9b\x60\x4d\x15\x92\xaf\xab\xf2\x95\x22\x8d\xb4\xa1\xd6\xa0\x6e\xee\xb1\xf9\x51\x56\x3b\x4d\xdc\x0c\x77\x34\x4e\x52\xba\xa3\xb3\x8f\x26\xef\x9e\x6b\x1a\x6b\x45\x41\xdb\x7a\x3e\x3f\x73\x2d\x45\x9a\xa4\x32\xb6\x36\x0b\x7f\xef\xc1\xec\x3f\x82\x01\x1f\x48\xc3\xf9\x02\x64\x9a\x46\x86\x36\xe2\x4e\x43\x78\xef\xd4\xe8\xf6\x37\x50\x7c\x74\x0e\x56\xbf\xd2\x23\x11\x69\x9a\x66\xb6\xa1\xdf\x40\xd5\x6c\x61\x30\x03\x53\xa5\x29\xdf\x3c\xe4\xea\xc3\xa5\xb3\x53\xcc\x6c\x91\x66\x59\x4a\x80\xd1\xcd\x62\xf6\x64\xb3\xfd\xa7\x6f\x8f\x9b\xe5\xeb\xe3\x72\xb1\xf2\x27\xcb\x44\x4a\xf8\x3d\xdc\x1f\x9a\xd3\xb2\xa0\x0e\xd2\x54\xea\x92\xf2\x50\x92\x39\xa5\xe7\xcc\x74\x44\xeb\xf8\xb6\x3c\xca\xdd\x35\x81\x2b\x91\x72\x81\xb4\x77\x90\x43\xfa\x3e\x27\x1a\xc3\x54\x16\x9e\x72\x69\xcd\x1b\xad\x57\x4b\xdd\xce\x7d\x62\xd6\xd9\xd2\x27\xea\x4e\x92\x69\x9a\xde\x21\x52\xae\x82\x94\x75\xa8\xad\x36\x99\xb6\xa0\xaf\x6b\x7c\x1d\xf7\x31\xa1\xc2\x00\x3a\xcb\xf3\xd7\xfc\x27\xee\xea\xf6\x71\x59\xe5\xae\x61\x81\x30\x95\x18\xdb\xdb\xf0\xb8\x59\xac\x37\x93\x39\xef\x71\xcc\x77\x17\xa9\x0a\x52\xaa\x39\x11\x2c\x91\xc2\xe5\x65\xb1\xe8\xa2\x98\x54\x09\x41\x27\xdd\x4a\xab\x21\xe0\xff\xac\x23\x6e\x9b\x1b\x2b\x1b\xa8\xd7\xb9\x46\xfa\xdf\xbf\x6b\x4b\xb8\x13\x60\xa2\xe2\xd4\x35\xfa\xd7\x88\x1e\x77\x2a\x52\x54\xba\x33\xb7\xfc\x2a\x50\x0f\x56\x90\xf1\x49\x50\xa8\xac\x0f\xcb\x9c\x43\xb7\x82\xa6\x26\xe1\x49\xd0\xc7\x79\xbe\x9d\x9d\x8c\x44\x6a\x04\x78\x64\xd0\x23\xea\x37\xf7\xc4\xb9\x3f\x0a\x19\x2d\xce\xf7\xb3\xa7\xc5\xd3\xec\x7e\x39\xa7\x12\xf3\xaf\x22\xf6\x2c\x08\xb4\xf5\x37\x82\xfd\x01\xf2\xb7\xe2\xf6\x68\x43\xbe\x5b\x38\xf9\x2f\xcd\xc2\x20\x73\xa2\x09\x4d\x4f\xef\x4d\x64\xa1\x6b\x0c\x6c\xde\xf1\xbe\x74\x1e\x27\xdd\x31\x19\xa7\xf1\x99\x04\x47\x46\x2e\xaf\x65\xdd\x4c\x88\x7c\xfe\xf2\x8e\x67\xa1\xb2\x38\xb2\xc5\xdb\x9b\xa9\xb0\xf8\xcb\x3f\xcb\x2c\x12\x41\x90\x5d\xb2\x20\xc7\x6f\x6e\x07\x26\xbe\x44\x97\x64\x91\x4a\xb4\x73\x8a\x7b\xad\xb0\xe7\xeb\xd9\x1e\x02\x6a\xcd\x75\xbe\xa7\xbd\x08\x2a\x8b\xd0\x46\xd0\x35\x2d\x93\x1f\x87\x32\x2f\xa8\xdc\x5b\x56\xcd\x9c\xac\x6b\x86\xef\x61\x16\x87\x09\x95\x07\x9a\xae\x2c\xfc\x62\xfc\xb9\x62\x60\xb4\x63\x6e\x69\x61\x72\x1e\x8a\xe7\x83\x49\xdc\xbe\x7f\x54\x04\xb6\x4e\x11\xee\x48\x02\x82\xae\xaf\xdc\x6a\x3c\xd6\x93\x0c\x26\x91\xa5\x9c\x51\x37\x63\xb3\xa1\x5d\x73\xf0\x6e\x67\x59\x2c\x09\xf2\x29\x8f\xbb\x73\xb8\x3b\xc6\xec\x3b\xda\x4b\x3b\x5a\x93\x4f\x77\xd9\x26\x52\x77\xf9\x6e\x57\x8f\xd7\x00\x3f\x30\xb1\xf7\x06\xfe\x73\x84\x2a\x3f\xee\xe7\x65\xdd\x4d\x98\x4c\xda\x52\xf3\x01\x0f\xf8\x5a\xe1\xfe\x22\x7a\xce\x32\x93\x10\x10\x6f\x56\x1c\x65\x17\x96\x64\x3c\xe4\x14\x08\xca\x63\x1b\x55\x3d\x94\xbb\xbe\xff\xf2\x70\xc9\xca\x78\x6a\x95\x0e\xda\x84\x04\x0e\xde\x4d\xf7\x82\xc8\x23\x32\x0e\x9c\x4a\xe3\xb6\xff\x47\x2f\x8a\x3b\x02\xed\xad\xb3\xa7\xb0\xf7\x63\xdc\x4e\xca\x20\xe4\xfd\xaa\x13\x54\x8f\x47\x55\x95\xdd\xe7\x45\x40\xa8\x85\xe7\x52\xe3\x6c\xf0\x3c\xa5\x70\x0d\x42\xb0\x92\xe5\x83\x26\x66\x26\x55\x44\xe5\x97\xf7\x72\xa7\xb1\x9a\x8d\x22\xd9\x4c\x31\x43\x65\x0b\x9b\xd1\xbe\x96\xe5\x85\xcf\xf8\xff\x13\x4d\x92\x84\x5e\x93\xa4\xeb\x24\x8c\x61\x01\x99\x8a\x03\xaa\xe5\x3e\x9d\x9c\x20\xb2\xcd\x3e\xb2\xbf\x5f\xa5\x33\x25\x13\x02\x0e\x48\xdb\x38\xb2\xdd\x81\x6f\xa3\x1a\x46\xa6\xc3\x18\xf4\xd9\xd4\xab\x0d\x59\xb1\x4f\x29\x9b\x8c\x94\x32\x04\x4b\x4c\xdf\xe7\x45\x33\x6b\xd7\xf1\x41\x41\x36\x33\x91\x22\xec\x7b\x51\x36\x8f\xf9\xc7\x28\x75\xcc\x0c\x07\xeb\x46\xd8\x26\x32\x2b\xfc\xc4\x4e\x27\x71\x7a\xcd\xce\x8c\x48\xac\x5e\xc1\x1b\x36\x8b\x9f\xea\xfd\xad\x8d\x36\xdc\x77\x71\x96\x5a\xff\xfb\x3a\x08\xec\xac\x0c\xdc\x81\x80\x19\x12\x3a\xf3\x0d\x34\x07\xc9\x18\x9c\x9a\x07\x81\xa1\x66\xcf\xe6\xf5\xe5\xe9\x7f\xfb\x53\x06\x3a\xa1\x78\xf9\xe0\x63\xf0\xa6\xcf\x48\x16\x3c\x4c\xec\x1c\x73\xf7\xcc\x67\x2d\xc3\x33\x87\x69\x4c\x42\x67\x5f\x04\xeb\x19\xb1\x7f\x04\x0f\x55\x4a\xb9\x8d\xbf\xba\x97\x4f\xac\x0e\x1d\x20\x91\x87\xa8\x93\xb3\x61\xea\x0a\x8f\x35\xce\xa1\x7e\x5f\x16\x0f\x50\x7d\x81\x37\x1f\xeb\xe1\x57\x02\xff\xbd\x51\x10\xf8\xd6\x14\x25\x09\x3d\x85\xe5\x01\xee\xc4\xbf\x8b\x3c\x32\xb1\xd7\xc4\xb9\xcd\x3f\xeb\x81\xe5\x96\xe0\x31\x30\xd2\x9e\x5a\x37\x50\x49\xa8\x71\x01\xd5\xee\xe4\xa5\x64\x66\x7b\x2c\xf4\xbe\x53\x43\x6e\x47\x0b\x2a\x60\x1c\x2a\x84\x41\x4b\x70\x90\x75\xf0\x58\xc7\x5e\x35\x85\x68\xf0\x75\x5e\x16\x23\xac\x90\x1b\x99\x40\x1c\x5b\x93\x70\xdb\xd5\xea\xea\x08\xdd\x71\x65\x3a\x97\xc5\x01\x64\xca\x0f\x30\x96\x9b\xf8\x86\xcd\x9a\xb8\x53\xd3\xd1\x16\x4f\x9d\xf3\xd5\x0a\x6f\x2b\xf8\xf2\xa7\x4f\x85\x7d\x3b\xf1\x13\xd4\x91\xd4\x46\x7b\xd2\x7f\x82\xa7\x52\x25\x89\x13\x9c\x20\xeb\x46\xab\x33\xd9\x1d\x36\x99\x2b\x1a\x34\x9b\x2a\x7f\x7b\x9b\xb2\xe3\x6a\x47\x69\x8f\xb2\x70\xe1\xf4\xb9\x00\x32\xbc\x19\x99\xe4\x3c\xeb\x15\xb8\x5e\xcb\xaa\x19\x17\x58\x79\xa6\xc1\x7d\x29\xd9\x8a\x5a\xe0\x6f\x6f\x03\xe5\x19\x26\x4c\xf9\x26\xd2\x6e\xd7\x89\x4e\x8c\xd4\x29\x87\xef\x20\xe7\x26\x25\x06\xa3\xce\xb5\x4f\xd4\x9c\xf9\xda\xb5\xd2\xdc\xf0\xf3\x02\x12\x2a\xcd\x28\x28\x6e\xcb\xc7\xb2\x3c\x5c\x0b\xfa\xfc\x78\x1d\x90\x1f\xf0\x9f\x8b\xd9\x6a\xbb\x79\x58\x2d\x16\xdb\xf5\xb7\xd7\xd7\xc7\x3f\xfd\xcf\x80\xd0\xda\xa8\xe5\xf5\xcc\xc1\x0e\xa6\x3b\x9f\x1c\x92\x98\x52\xdc\x83\x65\x71\xb9\xd6\xcb\x7d\x09\x3b\x9f\xcc\xfb\x81\x98\xd1\x19\x0f\x70\xda\x54\x45\xbd\x81\x9f\x57\xee\x85\x4c\x34\xb1\x5b\x9c\x58\xee\x6b\xb9\x6e\xfa\xcb\x1f\x57\x81\xf1\x82\x7e\xbf\xe3\xa9\x36\x55\xb9\xef\xc1\xeb\xae\xfc\x60\x95\xc4\x76\xef\xa4\x18\xc5\xae\x87\x6b\xf8\x3c\x5f\x9e\x36\x16\x12\xf3\x58\xbe\xe5\x05\x61\x16\x86\xc1\x3c\xc7\x50\x92\x6a\xa1\xdd\xa3\x7e\x9b\x88\x38\xb9\x01\xe1\x30\x20\x6d\xd0\x36\xc1\xc1\xfc\xa5\x03\xad\x3d\x89\x60\x81\xa1\x15\x86\xae\x71\x50\x61\x1d\xfc\xa2\x76\x5c\xc8\xba\x4c\x84\x60\x8e\x87\x1d\x3a\x36\xad\x9b\x74\x7d\xe2\xaf\xff\x58\x28\x63\xd6\xad\xae\x73\xa8\xf4\xac\x19\x21\xec\x83\x8e\xb1\xd6\xff\x3f\xff\x79\x21\xf4\xd9\x80\xd2\xbd\x52\x96\xfe\x7e\xbd\xff\x27\x18\x68\xaa\x9e\x1f\xac\x56\xdf\x56\xe3\x8e\x2c\x36\x9b\x06\xf5\xaa\x1c\xd7\xd9\x04\x33\x76\x8b\x70\x44\x42\xff\xe8\x45\x90\xa4\x18\xf7\xe4\x89\x1d\x75\xf0\xa1\x3c\x97\xd6\x44\xa0\x23\xbf\x24\x11\xbf\xbb\xdc\xed\x60\x3b\xbb\xd9\xb2\x70\xd0\xb8\x10\x81\x4e\x49\x29\xb7\xbd\x7b\x8e\x55\x5c\x95\x7b\x8b\xe3\xf7\x98\xa9\xd1\x65\x85\x81\x95\x49\x9c\x1d\x9b\x77\xeb\x05\xee\x0e\x44\x41\x46\xb6\x84\x7b\xca\x79\xb6\xc7\x42\xed\xb0\xef\x5b\x34\x7a\x74\x51\x68\x33\xbc\x5e\x4b\x3e\xbc\xa4\x57\x09\x11\x25\xdc\xf5\x7d\xdb\x7b\x4c\x2b\x8e\x23\xc2\xfb\x11\x31\xe8\xbe\x49\xcb\xe2\xed\x6d\x80\xcd\x10\x09\xb3\x3c\x7a\xbf\x0f\x7e\x2b\x0e\x55\xd9\xa0\x6a\x50\x0f\x00\x13\xbf\xe8\xdd\x8a\x24\x8a\x22\xe9\x70\xed\xf6\x43\xc3\x5f\x93\x48\x9e\x9e\x63\x9c\x35\x49\x1d\xdb\x09\x31\x1c\x97\x66\x29\xe5\x86\x56\x5c\x9c\x8c\xcf\x62\xb6\x7d\x5d\xac\xe6\x8b\xe7\x4d\x9f\xd6\x29\x44\x16\x85\x54\x1e\x03\x5a\xf0\xbb\xaa\x77\x1b\xd9\xc6\x16\x18\xf4\x6f\x6c\x77\x2b\xaa\x42\x7f\x2b\x0e\xd0\x7b\xfe\x3c\x09\x7b\x0e\xa9\xb4\x29\xdf\x94\x4d\x53\xee\x97\x45\x83\x6f\xe3\x42\x42\xbb\x80\x51\x02\xb3\x7a\x98\x77\x67\x00\x24\x1f\x4a\xe9\xed\x15\x85\x20\x62\x95\xf3\x45\x03\x97\x99\x32\x77\x4c\xa4\x9a\x60\x0b\xb7\x79\x51\xd6\x70\xac\x06\xf0\x29\x21\x94\x21\xd9\x86\xf9\xc3\xf2\x79\xb1\x5e\x6c\x17\x7f\xcc\x1f\x66\xcf\xf7\x8b\xed\xcd\xb7\x3f\xbb\xa2\x92\x10\xa8\x08\x65\x0f\x4d\xe3\x9d\xc8\x5d\x38\x24\x20\x0d\x19\x74\x96\x79\xcf\xf8\x56\x36\xb9\xa5\x8f\x5d\xc2\x47\x84\x04\x41\xfa\x7a\x12\xea\x5c\x79\x71\xb6\x15\x36\xc7\xca\x6f\x9b\x42\x71\x69\xfd\x29\x51\x7d\xb6\xbb\xed\x06\xbb\x2c\x46\x28\x69\x15\x42\x49\x6b\xf0\xbb\x4d\x0f\xdc\x21\x9d\x31\xd3\x69\xa9\xf9\x3d\x6a\x45\xcf\x61\x9c\x43\x08\x9d\xc5\xd4\x5f\xb4\x15\x0a\x5f\xdb\xea\x26\x2d\x6a\xeb\x5f\xf6\x45\xf2\xb1\x67\x3b\xd5\xd1\x5b\x62\x58\x46\x86\x97\x7e\xee\xce\x8b\x66\xfc\xf0\x4c\xcc\x48\x8a\xed\x19\xbf\x56\x79\xed\xc1\x36\xc0\x62\x2b\xe4\xbc\xc6\xe6\xb6\x02\xd3\xd8\x16\x99\x3f\xc8\x59\xc2\x7d\x9f\x63\x07\x43\x0e\xf6\x90\xa7\x29\x80\x61\x92\x59\xea\x82\x75\x24\xbb\xba\xae\x42\x90\xc5\x94\x00\x2e\x9e\xd7\xc3\xbb\x01\x81\x4c\xa8\x54\xf5\x63\xb1\x6c\x67\xfb\x76\xb1\x79\xe8\x4a\x6a\x10\xa8\x54\x38\x65\xd4\x3d\x81\xe5\xf2\xdd\xd5\x32\x82\xff\x88\x49\x08\x1c\x66\x8d\xe9\x66\x4f\x2f\xdf\x9e\x37\xeb\xe1\x8d\x81\x30\x0a\xd0\xe1\x96\x3a\xbd\x17\xc7\xb7\x1b\xa1\x88\x21\xcc\xb8\x14\x9e\x79\xef\xea\x8c\xfe\x90\x34\xda\x5a\xd6\x54\x08\xda\x61\x5d\x26\x0a\xc8\x10\x85\xb6\xbc\x5a\x63\x63\x25\x87\x3b\xf9\xa5\xf1\xce\x37\xfc\xee\x48\x5b\x9a\x6d\x7b\x99\xa7\x75\x53\xe5\x87\xc3\x79\x9e\x40\x84\x91\x62\x5d\xc9\xbe\x4d\x65\x8a\x8e\x97\x02\x09\x33\xb4\x14\x14\xc7\xfd\xb7\x1e\xdb\x05\x92\x20\xb1\x7e\x35\x6d\xec\x71\xdc\xe1\x33\xfe\xec\x4a\x0f\x93\xb1\x29\x24\x61\x44\xea\x62\xdf\xf3\x92\x5c\xcf\x7e\x9b\xca\xc9\x20\x51\x48\xc5\xab\xb2\x02\xb5\xcb\xff\xc2\x7b\xa8\x17\x3f\x9b\x0a\x66\x55\x1f\xe7\x05\x69\x1c\x50\x7c\xd8\xe6\x83\xc7\x43\xba\x1f\xdd\xa8\x54\x5a\xd1\x78\xbb\x38\xad\x9b\x76\x13\x7b\x3b\x3d\x82\x44\xe7\x57\x19\x24\x83\x90\x02\xb2\xd0\xd0\x5a\x74\x5b\x95\x05\x2e\xf6\x87\x5d\x79\x42\x5c\xbd\x74\x73\xec\x1f\xa3\xa9\x32\xfc\xba\x0c\x13\x52\x76\x84\xba\xc6\xaa\x59\xfc\x27\x76\x6e\xd6\xff\xe8\xff\xd3\x3d\x0d\x9e\xa5\x96\x6d\xdb\x94\x87\xd7\xa3\xb4\x96\xaa\xee\x98\x08\x02\x62\x7d\x1f\xaa\x72\x57\x16\x6f\xa8\x7d\x35\xad\x1b\x90\x62\x16\xfa\xe2\x44\x55\x95\x4d\xed\x42\x92\x7c\x58\xc9\x03\xa1\x42\x13\xf4\xf6\xf0\xa5\x1e\xec\xcb\x00\xc6\x50\xf1\x86\xf2\xd7\xd9\xee\xcc\x86\x1f\xdd\x4a\x19\x27\x91\x1a\xd9\xa1\xba\x43\x2a\xcc\xe8\x2e\x6f\x96\x8b\x55\x40\x3b\x8d\xbf\x4a\x95\xc5\xd2\x6b\x00\xcd\x5d\x5d\xf0\x4a\x5e\x0c\x8a\x5b\x83\xc6\x03\x9c\xe6\x5e\xed\xc0\x9f\x47\x6b\x4b\x9f\x36\x90\x57\x35\x71\x0e\x68\x57\x6d\x57\xe5\xbb\x3b\x3f\x08\xb9\xf5\xc3\x68\xb0\x6e\x82\xd1\x0b\x8a\x2a\xa6\x68\x12\xad\xb2\x83\xa3\x65\x76\x07\x53\x62\x92\x15\xf8\xb5\x79\x6f\x5f\x3d\x12\x3a\xfc\x6f\xe0\x52\x60\x02\xab\xb5\xf1\x03\x73\x52\xc9\xf4\xeb\x37\x98\xd4\xc4\xbc\x8f\x74\xb4\xf1\x65\xe7\xdb\x2c\xc0\x00\x0f\x5d\x3e\xe5\xc0\xfa\x44\x64\x37\x30\xc6\x3a\x83\xd1\xc6\x52\xd4\xdf\xcb\xaf\xae\x93\xee\x72\xd0\xc1\x48\xc9\x42\x61\x45\xeb\x0b\x53\x6e\x5d\x0e\x3a\x4e\xd6\x25\x4b\xec\xab\x6c\x77\xb8\xe1\x8d\x92\x4c\x18\xea\xcd\x1c\xc0\xc3\xf1\x86\x1f\x0e\x8c\x88\xe5\x99\x08\x4c\x36\x6d\xaf\x30\x6e\xc6\xca\x30\x4e\xf9\x59\x83\x94\xf8\xaa\xa7\x5f\xaf\xb3\x32\x4a\x6c\x51\xaa\xac\xde\xa0\xc8\x6b\xb0\x3e\x79\x1a\x7f\x8e\x4e\x1d\xa5\x01\x51\x53\x5c\xc0\x61\xdb\xb9\xff\x4f\xe5\x2a\x19\x19\x88\x65\x17\xd3\x2f\x28\x3e\x1e\xff\xe0\x84\x31\x5a\x11\x5c\x81\x6e\x9b\x3b\xb5\x81\xae\xf2\x10\x9e\x0b\x82\x83\xff\xbd\x7a\xe0\xbf\xfe\xdf\xd1\xd5\x26\x41\x46\xfe\x3a\x7b\x52\x60\x27\x47\x69\x2f\x3a\x3f\xbe\x66\x9e\x51\x19\xec\x70\x24\xd3\x41\x28\x4e\x2f\x05\x21\x5b\x27\x9b\x2c\x32\x0d\x14\x3b\xcb\x0a\xac\x41\xeb\xdd\xd9\x79\xe7\xd7\xac\x0a\x99\xc6\x8c\xd0\x34\xaa\x2c\x0a\x6a\xce\x0f\xf1\x04\x7e\x54\x9a\x39\x9e\x44\xe3\xa5\xb2\xa8\x1b\x31\xba\xee\x14\x41\x7a\x2d\x7b\xdb\x6d\x19\xac\x98\x32\x93\x8c\x50\xbd\x67\x3b\xe3\xf1\xc5\x8d\xc6\xeb\x4c\xba\x62\xc4\xcd\x51\x8f\xfd\x3f\x85\x14\x59\x12\x39\xb8\x50\x1b\x69\x43\x95\xc3\x6b\x59\xee\x26\xf1\x05\x52\xf0\x44\x5a\xed\xb4\x9f\xb0\xf7\x21\x9c\x04\x26\xd3\xa8\xa3\x9a\x4b\xac\x88\x29\xd9\x86\x69\x75\x37\x24\x49\x33\x65\x8b\x05\x0a\xdb\x93\x53\x24\xe9\xa2\xe9\x6e\x90\x0e\xa8\xd9\x6e\x6d\x8f\x9e\x16\x4b\x7f\x40\x46\x16\x62\xb6\x42\xad\xf3\x4b\x9b\xc6\x8b\x56\x84\x94\x60\xcb\xd6\x5b\xfb\x82\x2c\x8b\x76\x31\x2b\xab\x7c\x82\xff\xd7\xcf\x34\xa5\x36\x2a\xb3\x88\xbf\x36\x7c\x3d\xa7\x68\x0f\xe5\x4e\xbb\x9f\x34\xea\x8b\xba\x0f\x62\xc8\xc9\x46\xd3\x92\xca\xd4\x69\xfd\xd5\xb1\x35\x25\xa6\x09\x55\xb4\xee\xcf\xee\xf7\x93\x5b\xa7\x44\x85\x81\xcd\x7a\xac\x32\xd2\xf8\x3b\xd0\x0a\x25\x50\xa4\x4c\x59\x51\x4f\xd4\xc9\x7f\x99\x61\x01\x05\x30\x64\x15\xd8\x46\x04\x67\x9d\x0e\xa1\x58\x28\xad\x98\xd4\x40\xfc\x62\x72\x29\x52\x2c\x12\x54\x6c\x86\xbc\xba\xad\xca\xc3\x3f\xcb\x7c\xc4\x45\x50\x2c\x8b\x32\xab\xca\x52\xe0\x05\xd4\x43\x85\x90\x90\x68\x00\xd8\x40\x68\xbe\x2b\xbb\x7c\x49\x85\x32\x56\xd1\x79\x01\x75\xd3\xc0\x2b\x9b\xb7\xbb\x75\x48\xd0\xf6\xfb\xc5\x33\xdb\xce\xbe\xcd\x37\xcb\x97\xe7\xed\xed\xb7\xd5\xac\xfd\x1f\x3f\x28\x0a\x91\xa4\x5f\xdf\xf7\xa0\xea\x77\xe8\x18\x1b\xfd\x89\xa0\x22\xae\x9c\x18\x17\xe5\xfe\x76\x43\x1d\x04\x88\x8e\x1e\xa8\xe2\xd4\x50\xb0\xf5\x51\x2b\x2a\xfc\xdd\x1c\xab\xe2\xc7\x3b\x16\xa4\xfa\x57\x3e\x41\xbb\x11\x4c\xb0\x37\x47\xa0\x4f\x15\x67\x61\xe0\x08\x1a\x94\x66\x7b\x78\x62\xff\xa2\x62\x8c\x69\x97\xc7\xc2\x1a\x12\x6f\x4e\x87\x71\x19\x5b\x25\x71\x94\x9c\xd7\xa3\x5b\xaf\x23\x7f\xb1\x22\xaa\x24\x81\xc8\x8a\xc0\x40\xa5\xde\x6f\x4e\xf7\xbe\x80\xd7\x1d\x57\x08\xdd\x9b\xd7\xae\x17\xff\x37\xaa\x90\x17\x15\xa3\x7f\xf4\xe2\x2a\x95\x80\x95\x4b\x02\xad\x5d\x55\x66\x85\xa0\x2f\xc1\xc2\x7e\xb8\xab\x76\x92\xa6\xec\xba\x13\xe8\xa3\x03\x24\xe2\x74\x3b\x98\x41\x09\x1a\x7a\x1d\xca\x82\xf4\xee\x7a\x64\x32\x95\x06\x32\xb5\x1b\x12\xec\x88\x35\x3c\x10\x71\x11\x2a\x55\x29\x41\xfd\x36\x0f\xab\xdb\xee\x33\x88\xd2\x31\x33\x96\xaf\x77\xeb\x11\xf8\xcf\x0d\xca\x52\x4b\x2c\x39\x73\x74\x8a\x8f\xea\xa2\x58\xa4\x78\x62\xf9\xed\x2b\xf8\x38\xbe\x95\x67\xd6\xc4\x95\x7d\x62\xfc\xaf\xcf\xe0\x14\xcf\x0c\xb1\x1d\x9b\x72\x98\x06\x29\x2e\x13\xca\xd1\x6c\xb7\xc0\xaf\x2a\xb3\x76\xf9\x9b\x30\x56\x14\x4a\x64\x81\x77\xbb\x6b\xdf\x28\xeb\x26\xd0\x7f\xf5\x05\xc4\x24\xbd\x75\x70\x2a\xa4\xce\xc6\x6a\xf8\xad\x90\x1a\xb4\x80\xd3\xff\x37\x06\xb5\x02\x91\x52\x21\x64\x9b\xd7\x2f\x07\x0b\xbe\xbd\x2b\xab\x81\xf1\xd1\x35\xf6\xa3\x02\x8c\x29\xa6\xd1\xb9\x31\xb9\x3a\xee\x3a\x9c\x81\x92\x51\x92\x38\xe0\xe6\x31\xaf\x50\xf7\xf4\x8c\x85\x92\xc8\x28\x09\x50\xae\x56\xec\x8d\x64\xfe\x6b\x41\x85\xc9\x6d\x53\x29\x16\x12\xd7\x14\x88\xa3\x7b\x38\x93\x99\x95\x0a\x90\xaa\x37\x7b\xf8\x39\xef\xc9\x12\x0e\xfa\x21\x4a\x6b\x4d\x6f\xc6\x3b\xa8\x8f\x76\xe5\x9c\x28\xdd\x2a\x8c\x63\x42\xb7\xde\x3e\xbd\xbe\x1f\x4b\xe7\xb7\xea\x4f\x80\x32\x25\xac\x88\x7d\x92\xdb\x3e\x84\x59\x33\x93\xd0\xec\xa3\x65\xdc\x69\xcc\xfb\x9b\xa5\x83\x24\x24\x18\x96\x63\x0e\xf6\x4f\xaa\x03\x21\x88\xbd\x6b\x2b\xd2\x7d\xf4\x81\x0e\x64\xaa\xd2\x81\x54\x25\x05\x9f\xab\x0b\x29\x28\xa1\x03\x2d\x08\xe4\xf0\xf4\x32\xf3\xf5\x2b\x1d\x0a\x41\x92\xaf\x87\x77\xa8\x31\xf0\x89\xda\xb2\x78\x28\x8f\x5d\x9e\xac\x43\x83\xdc\x92\x89\xfc\x4b\xa9\xa3\x30\xca\x1c\x19\xe8\x5c\x39\x65\x2c\xd8\xb2\xae\x76\x3a\xb8\x69\x3a\xca\x3c\x94\xf5\x11\xe1\xed\x88\xab\xb2\x6e\xb0\x1a\xa9\x36\xe8\x48\x62\xec\xfb\x8b\xaf\x40\xa6\x19\xd7\xe8\xe3\xee\x13\x31\x93\xd4\x91\x04\xcf\x26\xf2\x7f\x0f\x2c\xc9\xb4\xb1\xcf\xa1\xcf\xd4\xd6\x71\x22\x9c\x99\xe5\x3f\x4b\xf9\x00\xf5\x5d\x85\x48\xfb\x7b\xd5\x5f\x81\x75\x9c\x00\x9d\x7a\x07\xc7\x42\xbd\x8f\x2f\x35\x4e\x2d\xda\x6d\x0f\x1f\xf8\x03\xf1\x63\x77\xb2\x5d\xf2\xe1\x0b\xae\x63\x15\x71\x17\xa6\xdd\x60\xdd\xdc\x1f\xb1\xae\x6d\x79\x96\x9a\xcc\x1b\x2c\x1a\x68\xf2\x4f\x52\x2d\x25\xb9\xa9\x53\x79\x6c\xba\xf8\x60\xca\xfa\x51\xe8\x24\x35\xdc\xca\xc0\x9f\xe6\xef\x04\xa6\x20\x2f\x8e\xd1\x37\x67\xcc\xee\xb3\x3e\x32\xde\xa1\xaf\x6d\x4c\x6e\x48\x3a\x13\xb6\x12\x57\xe1\x63\x09\xfa\x8f\x7c\x84\xee\xd7\x1c\x14\x15\x5a\x77\xb4\x4e\x0d\x5c\xec\x84\x16\x61\x40\xf3\x61\x9f\xeb\x0d\x56\x7b\x0f\x4e\xf0\x47\x15\x27\x7d\x81\xb5\x82\x1d\xbe\xc8\x2b\xa0\x09\x0d\x5c\x09\x57\x5e\x5a\xce\x5f\xfa\xba\xc2\x42\x83\x92\xa6\x7d\x18\x5e\xa8\xea\x97\xd0\x2b\x0d\xda\x9a\x63\xf7\x78\xeb\xaf\x58\x3d\xe5\xbb\xdd\x85\x82\x8c\x96\x10\x69\xd7\x75\xb5\x81\xfb\x44\x0f\x59\xab\x30\xa1\x29\x43\xa6\x63\xed\x82\x5a\xe0\x6e\xa1\xc6\x82\x3f\xd7\x77\xde\xde\x99\x78\x14\xf4\xd9\xa4\x0f\xf0\xf9\x79\x91\x74\x68\x2d\xe2\x24\x19\x9a\xd7\x5f\xdc\x73\xad\x13\x6a\x21\x6d\xe5\xf1\xf4\x47\x01\xfb\x8b\x14\x69\x74\x7b\x91\x85\x02\xfa\x19\x4a\x57\x97\x19\x7e\x37\xaa\x94\x44\x9e\x3d\xbd\xe5\xad\x42\xec\xb5\x96\x91\xc5\x31\x3d\x8a\xa7\xce\x4f\x6a\xf0\x79\x64\xa9\xed\x36\xed\xf3\xa2\x59\xd6\xf5\xd1\x1b\xdc\x4f\xc6\xab\xed\x2e\x40\x39\xaa\x2f\x73\xd1\x43\x3f\x6f\x4d\xc8\x80\x29\x33\xc0\x7b\xff\xc8\x9b\xf7\x36\x42\xfe\x45\x13\x09\x19\x4a\xd2\x7b\x52\x56\x2c\x82\x42\xba\x1e\xe3\x03\x83\x48\x11\x28\xf4\xcb\xbe\x76\x1b\x84\x3d\xd1\x46\xfd\xe1\xc4\xda\x51\x52\xb7\x60\x1b\x74\x7f\xd6\x9c\x48\xd8\x8f\x47\xf5\x41\xce\xdc\x75\x77\xc4\x28\xc2\xf8\x3b\x10\xbe\xff\x73\xc4\xed\xc2\x6d\xf9\x1a\xdf\x6a\xac\xa8\x10\xd8\x2e\x99\xe1\xf4\x4b\x80\x11\x04\xda\x32\x75\xcb\x3d\x81\xa1\xb0\xea\x49\xab\x5d\xca\x40\xf4\x7f\x75\x9c\xc4\xcc\x15\x38\x7a\x98\x50\x7f\x31\x49\x68\xf1\x88\x34\xd1\x8b\x63\x7d\x11\x8d\x60\x22\x2d\xd3\xd9\xf3\xef\xbb\x4f\x6a\xe6\x5c\x86\x8b\x66\x59\x58\x6a\xd7\xfc\x92\x8b\x8c\x69\x6a\xe1\x21\x7f\x0d\x74\x96\x30\x05\x49\x7d\xdf\x5c\x95\xde\xb2\x9f\xfc\x28\xbb\xfb\x9a\x62\x40\x75\x76\xdb\x4b\x28\x9b\x71\x54\x8d\x59\xcc\x7c\x79\xf7\x19\x7f\x36\xdf\xed\x1e\x39\x51\x61\xc1\x2c\x53\x51\x07\x70\x5d\xef\xca\x66\xd6\xfd\xfe\x4c\x08\x7a\xa8\x9f\xa5\xfd\xb0\x29\xbb\x23\x46\xaa\xd0\x7f\xff\xa2\x79\x7f\x2d\xbb\x07\xcb\x43\x6d\x4b\x8c\x26\xdf\x7e\x4d\xd3\x21\x90\x87\x96\xcd\x7e\x53\x95\x1f\x58\xb5\x77\xfe\x2a\xdc\x7d\xf4\xc1\x84\x63\x62\x2b\xa5\xed\x02\x7e\xf6\x9b\xf9\xbf\x86\x34\xf5\x26\x01\x4f\x99\x0a\x7a\xb0\x03\xea\xa2\x5a\xcc\xd1\x20\xd6\xc1\xf6\xb9\xa2\xe7\xa4\x97\x4e\x05\xa9\x97\x67\xb9\x61\x90\x06\x5a\x76\x6e\x7f\xf9\xce\xe7\x9f\xb7\xde\x88\xc2\x8f\xe3\x8c\xaa\x6f\x54\x64\x52\x04\xdc\xde\xaa\xb2\xf8\xc4\xea\x5a\x39\x72\xf4\x3d\x1c\x04\xf7\x3c\x07\xf5\x41\x1b\xd6\x08\xd5\x3d\xfa\x00\x46\xa9\xc3\xb8\x3d\xc1\x4f\x7a\xc5\x3d\x1c\x66\x59\xbc\x14\x78\x3f\x62\x70\x23\xa0\xf2\x0c\xed\xf6\xe9\xcf\x71\xb7\xb3\xb5\x77\xff\x13\x64\x0c\xc2\x4d\x33\x27\xc8\xe9\x0f\x24\x9a\xa2\xac\x01\xb5\x73\xdc\xd7\x41\x99\x0a\x7a\xc1\xd4\xb1\x6a\x5f\xf5\x2e\x2f\x46\xc9\xad\x9a\x88\x82\xa2\x9d\xdd\x57\x56\x42\x25\xa3\x80\x9d\x55\x1f\xd1\x86\x90\x57\x7e\xbc\x42\x4d\x3b\xdc\x7e\xfe\x6d\xb5\x5a\x3c\x6f\xb6\xeb\xcd\xb9\x76\x8d\x5a\x31\x8a\x82\xf7\x79\x91\xef\x61\xd7\xf3\x6c\xf3\x03\x90\x13\x23\xfb\xe1\xa4\xab\xf2\x0a\xbb\xd6\x0d\xc5\xc0\x04\xaa\xd3\xb0\xff\x8b\x60\x1b\xfe\x34\x98\x48\xd2\x78\xb3\xfb\x89\xb3\x39\x76\x15\x53\x3b\xc4\xb0\xd0\xba\x5f\xd5\x97\x3f\x65\xf8\xfb\x4d\xa0\x34\x7a\x4e\x75\x9b\x29\xe8\xa1\x0b\x9e\x1f\xa5\x33\x6a\xc1\xfc\x8e\x45\xf3\x71\x66\x41\x98\x50\x8a\x28\xe8\xea\xa1\xd5\xac\xae\x73\xc2\xc2\xc2\xa0\x65\x60\x22\x06\x74\x67\xde\xf3\xca\xae\x7e\x67\xaf\x7f\xff\x1c\x4d\x94\x44\xd2\x22\x10\x7c\xa5\xbe\x1f\xc6\x9b\x28\xb3\x5a\x91\xf9\x94\x64\x8e\x89\x50\x53\x45\x69\xeb\xc4\x06\xa6\x8d\x5a\x84\x89\x8d\x09\x9d\x04\xc6\x1d\xe2\xaa\xdd\x88\x87\xd3\xd5\x24\x59\x26\x5d\xea\xa7\xf0\xe6\x78\x1a\x08\x06\xbb\x31\x5c\x23\xb9\xca\xe4\xf5\xa2\x79\x27\xf5\xa8\xc2\xf2\x0d\x7d\x69\xcc\x88\x0c\xe2\xf4\x42\x77\xd5\x22\x1c\x27\x1e\xb7\x81\x24\x91\x0e\x52\x03\xf5\x6c\x27\xa1\xea\x92\x0d\x03\xdc\x50\xfb\xba\x2b\xf6\x2f\xf5\x76\xb1\x9a\x07\x69\xd2\x8d\x10\x86\xb2\xba\xdb\xe7\xe7\xfe\x16\x60\x40\x71\xe3\x7d\x53\xaf\xfb\x68\x08\x23\xa3\x34\x30\x83\x17\xed\x3a\xec\xe0\x1c\xaa\x1b\x99\x84\xce\x65\x29\x2f\x5e\xcb\x72\x67\xe3\x3d\xd5\x06\xd7\x9d\x16\x98\x51\x51\x4a\xf3\x8b\xa8\x15\xab\xd9\xf3\xfa\x6e\xb1\xb2\xc4\xc9\xd7\x4e\x82\xc6\xa8\x48\x0a\xed\xdb\x8c\xc3\x30\xd6\x50\x21\xc4\xbe\x55\x8b\xe6\x7d\xb0\x98\x1a\x95\x68\x4a\xdf\x1e\xcb\xb7\x9e\x5a\xcd\xfa\xda\xfb\x6b\x94\xc0\xc4\x8a\xaf\xd6\xef\xd7\x2d\x15\xfd\xe0\x76\x03\xa4\xc1\x07\xba\x7b\xfd\x57\xd9\x68\x11\x51\x66\x75\x2c\xbc\xdf\xda\xba\x1e\x61\x4b\x0d\x6a\xc8\xac\x94\x80\xf6\x8d\xc1\xff\x8e\xeb\x66\x4c\xa0\x09\x5e\xf3\x8e\xbb\x9d\xdf\x2f\x8d\xc9\x18\x89\x5c\xab\xb2\x6e\xb6\xa5\xe9\x28\xcd\x6e\xbd\x04\xc6\x58\xe2\x05\x0b\x1f\xcb\xa6\xe9\x64\xa9\x08\x07\x39\xb8\x36\x60\x2c\xe1\x26\xf1\x41\x4b\xa3\xde\x69\x63\xee\x5f\x04\x30\x96\x26\x84\x0e\x7f\x6f\x67\x64\x85\xa0\x4f\xe4\x07\xeb\xf7\x1e\x60\x4c\x84\xa9\x83\xa2\xcf\xaa\xea\xa6\x2c\x77\x77\x39\xee\x74\xf0\x9b\xb5\x82\x76\xa3\x82\x48\x90\xfc\xcf\x1b\xec\xd1\x49\xe0\xfc\x36\xad\xf6\xf7\x8f\xe1\xf7\x07\x99\x89\xfa\xb3\xb2\xf3\xf2\x98\xa6\x9f\x01\x0b\x53\x45\x37\xe8\xab\xaf\x5e\x0d\x2c\x04\x43\xcf\xd1\x82\xd4\x96\x85\x4b\xc8\xea\x17\x73\x09\xd0\x00\x16\x71\x4e\x5e\x63\x77\xab\xc5\xe2\x7f\x2f\x68\xa6\xfa\x13\xc5\x41\x9c\x5a\x49\xdd\xa6\x3a\xbd\xb8\x36\xf3\x9a\x30\x9c\xa5\x19\xdd\xbc\x58\x27\xaa\xf3\xd5\xc9\x8b\xb7\x3b\xc4\x01\xb2\x14\x58\x12\x65\xf4\xb4\x8e\x85\xec\x3c\x62\x87\x90\x9f\xe1\x19\x93\x34\x70\x3b\xbd\x29\x37\xb9\x0f\x13\x81\x25\xd2\xea\xf0\xf6\x44\x56\x83\x01\x92\x0a\x58\xca\x18\xf5\x32\xb5\xeb\xd4\x9e\x37\x13\x60\xa9\x50\xe7\x8a\x10\x55\xc7\x27\x8b\xfe\xd3\x60\x38\x60\x59\x98\x10\x8d\xf8\xab\xdd\x83\x7a\x2c\x81\xf6\x48\xaa\x1d\x01\xe8\x01\x9a\x4b\xb3\x09\x60\x9c\x59\x79\x34\xbb\xd4\xa2\xf7\x7f\x98\x32\x81\xf0\x9f\x08\x22\x6a\xbf\xe4\x75\x1b\xa8\x90\x3c\xb3\x3f\x02\x99\x13\xe6\x2d\x4c\xfe\xd6\x47\xbe\x03\xe3\x32\xe0\xce\xde\xe0\xce\xc2\xb0\xa6\xfa\x35\xc0\x44\xe0\x90\x73\xdd\x3b\xfd\xdb\xf0\xc7\x8a\x30\xf1\x22\xd4\xb7\x64\x45\x70\xe8\x7f\x8d\x48\x02\xc2\x01\xe5\xfd\x00\x79\x24\x55\x0f\x0c\xb8\x21\xf9\x46\x45\xbe\x12\xce\xca\x71\x1a\xfe\x3d\xfa\xf1\x20\x80\xe0\x59\xbf\x3f\xbf\xfc\xf1\xdd\x7f\x29\x48\xed\xbd\x6e\x9e\x4e\x2e\x4d\xef\xaf\x91\xc0\x64\x60\xb9\x16\xd4\x57\xee\x6d\xa9\xc0\x64\x9c\x26\x56\x24\xed\x93\xde\xcc\xba\xb7\x79\x00\x93\x2a\x11\x96\xe9\x55\xe8\xb2\x82\xee\xcf\x68\xa5\x62\x6f\xf3\xfa\xd0\x2e\x1c\x0f\x47\xe9\x0f\xa9\x28\x76\x36\x0d\x8e\xf3\xe7\x04\xc1\xa6\x35\x1a\xfe\x31\x98\xa2\x8a\x47\xc6\xd9\xa4\x61\xf5\x08\x75\xf3\x0a\xb9\x9e\x4d\xbb\xa2\x02\xd3\x59\x46\x90\x18\x5a\x90\x86\x3f\x57\x6b\xeb\xf8\x46\x1a\x35\x03\xab\xac\x69\xdf\x7a\xf7\x31\xcc\x42\xe2\x19\x3d\x96\x6f\xb7\xd6\x32\x71\xf1\xfd\xf9\xca\x9b\x68\x98\xec\xd6\x7e\x6f\x77\x6a\xb5\xab\x89\x18\x71\xec\x69\x36\x75\x3d\xb3\x90\xfb\x0f\x87\x26\x71\x69\xcb\xe0\x76\x9b\xc4\x8a\x59\xbb\x26\xb5\x55\x55\x1a\x35\xc0\xdc\x89\x87\xe7\xf7\x9f\x07\x54\x8e\xc4\xfb\x8c\x5f\x4f\xb8\x1f\x7b\x28\x5c\xe5\xeb\x03\x33\x92\xc7\x99\x75\xb9\x3b\x60\x55\xe3\xaf\x3c\xc6\x20\x60\xca\x50\x3f\xca\xfa\x1c\x6d\xb1\x68\x2e\x7d\x32\x46\x1f\x09\xe2\x80\x5c\x07\x5e\x57\xcb\xef\xb3\x8d\xb5\x5f\xbb\x99\xad\x9d\x60\xd1\x76\xf9\xbc\xfd\xe1\xfb\x97\x10\x84\x2c\xe6\xe4\x72\x53\xec\x3a\xeb\x0a\x08\x42\xcc\xc0\x3d\x57\x92\x65\xe9\x15\xf6\x9d\x68\x25\x04\x71\x2c\xec\x8e\x5d\x6a\xb4\x66\x70\xed\xab\xb8\x29\x07\x82\x7c\x7e\x6c\xa2\xfc\x8b\xf3\x7c\xdc\x2f\x9a\xf7\xcd\x17\xa2\x6f\xc1\x42\x10\xf3\x94\x94\x31\x0a\xfc\xba\x2d\xd5\xb1\xa7\xdd\x3a\xb8\x75\x41\x8c\x82\xc0\xac\xf2\x78\x9a\x51\xd4\x3f\xfe\x1a\x63\x0d\xaf\x08\x20\x62\xf5\x64\x66\x54\x37\x2c\xaf\x88\x01\xb4\x1f\x31\x99\xc7\xc7\xfa\xcb\x49\xe2\x10\x53\x8f\xf3\xbf\x87\x3d\x3a\x2b\x43\x7f\x58\x86\xcc\xb3\x77\x7e\x41\x25\x81\x20\x65\x86\xde\x0e\x3a\xcf\x44\x93\x6f\xf0\x9a\x05\x19\x03\xb0\xdc\xa7\x93\x77\x5c\x1e\x2c\x88\x41\x96\x45\x84\x39\x2c\x9b\x77\x6c\x73\xc0\xbc\xa8\x29\x9b\xaf\xb1\xbb\x34\x1e\x72\xea\x4e\x3a\x75\x73\xfc\x9a\x63\xd5\x90\xd9\x63\x37\x02\x2d\x73\xb0\x76\x4d\x40\x67\x59\x34\xbc\x70\x91\x25\x14\x05\xc2\x27\xe4\xbb\x36\x03\x1e\xa2\x59\xbc\x70\x74\xfb\x4a\xc7\xff\xe3\x3f\x23\x19\x61\x08\x9c\x2a\x93\x75\xb7\xc3\xea\x5f\xd4\x45\x1f\xfe\x52\x60\x9a\x42\x19\xdd\xf5\x88\xd7\xab\xe7\xcd\x15\xce\x3f\x0d\xcf\xce\x28\xb1\x4d\x79\xc8\x55\x7f\x43\x98\x00\x8a\x41\x00\xb1\x15\x41\x7d\x98\x3d\x7e\x5f\x3e\xdf\x6f\x6f\x17\x8f\xb3\x3f\xfd\x3d\x80\x4c\x50\x65\xac\x6a\x17\xdb\xfd\x70\x56\x03\xd7\x04\x3d\xfd\x81\xf2\xd5\x33\x64\x20\x00\xb0\x2c\x67\xeb\x30\xbf\x6d\xf2\xfd\xa8\x7e\x03\x01\x48\xb4\x22\x7e\xf9\x5f\xde\xe5\xc2\x1d\x91\x5c\x53\xc9\x68\x5e\xee\x0f\xed\x4b\xbc\x2c\xf2\xee\x81\xa9\x44\xa0\xc3\x89\xdd\xe4\x7a\x7d\x94\x6e\x8e\x50\x94\x53\xcf\xb4\x1e\xdd\x3a\x85\xd6\x7f\x56\xed\xca\x02\x07\x3e\x89\xbd\xdc\xf6\xef\xba\xa8\x5d\x25\x05\x02\xad\xc0\x4f\x87\xc7\x52\x7d\x0c\x42\xa2\x8b\x07\xa1\x4d\x44\x08\xae\x76\xbd\xfc\xad\x77\x12\x64\x01\x39\x33\x1f\x8e\xf5\x3b\x41\x13\xf7\x5d\xc7\x7d\x78\xf5\x88\x40\xf8\x27\x7f\xe1\xae\xbb\x4e\x3f\xbb\x69\x43\xd5\x6b\x57\x3e\x51\x4d\x81\xc0\xa0\xb5\x06\x69\x7e\x7a\x1f\x8c\x5e\xdb\x08\x42\xc6\x63\xbb\x71\xd0\xb4\xf1\xae\xa6\x83\x53\x84\x4c\x64\x99\xd5\x41\xfa\x6e\x4d\x51\xaf\x44\xbb\x61\x20\x25\xe9\x21\xbd\xae\x16\xdf\x97\xaf\xda\x2b\x82\xf8\xa3\x2a\x24\x0a\xda\x5b\x05\x0a\x6d\xed\xf0\x09\x7e\x6e\xa0\x7a\xeb\x5e\xcd\x30\x62\x82\xa0\x16\x9d\xe0\xda\xf2\xe5\x79\xfb\x34\xfb\xa3\x3b\x2e\x11\x23\x0b\x81\x7b\x31\xab\x97\xf5\x7c\xb6\xc2\xa6\xca\xf1\x13\xef\xd0\x57\x69\x20\x8c\xa5\xad\xbf\x78\xb7\xb5\x3b\xc4\xf3\x21\x74\x92\x1d\x08\xa4\x45\x63\x39\x68\x84\x69\x1b\xfe\x98\x24\xb6\x5e\x98\xf3\xd2\x18\xb4\xae\xcd\xa3\x1b\x7d\x1c\x33\xfc\x20\x4c\x9c\x45\x56\x0d\x5f\xde\x1d\x0e\xc2\x04\x6d\x12\xe4\x2d\xa8\xc6\x38\xd7\xe1\xdd\x4e\x03\x63\x61\x46\xaa\xac\x70\x44\x0e\x84\x30\x45\x4d\x45\x18\x6f\x72\xe7\xc4\x42\xf5\x8f\xbc\xd0\xe5\x17\xf5\xe4\x27\xf7\xbb\x10\x62\x20\x38\x87\x6f\x37\xdc\x22\xd8\xa0\x7b\x78\x7e\x48\x43\xea\xdf\x14\xf8\xb3\x21\x69\x63\xbb\x78\x52\xbf\xf1\xfe\x65\x33\x7f\xf0\x3f\x0a\x34\xb3\xe4\x6a\xb2\x09\x77\x8c\x5c\x5f\x49\x85\x50\x46\x31\x55\x61\x94\x7b\x9d\x6f\xca\x92\x04\x3d\x87\x17\x25\x23\xeb\x7f\x4d\x88\x7d\xdd\xb7\xa0\xeb\x03\xc2\xae\x8a\xc5\x4d\xff\x52\x19\x2b\x2a\x9c\x3b\xe0\x4b\x1b\x00\x6d\xbb\xcb\x4a\x43\xeb\x47\x07\xc5\xab\x15\xa7\xb8\xc6\xb7\x71\x1f\x50\x71\x44\x7b\xf2\x5d\x59\x35\xc7\x02\xef\x4b\x3d\xf1\xca\x86\x2a\x4b\xa8\x53\xd2\x60\x6d\x39\xe1\x5d\xb1\x00\x42\x1d\x49\x82\xd7\xef\xa1\x0d\xdf\x9f\x4b\x4d\xd2\x3d\xfe\x60\x66\xdd\xef\xb6\x70\xc8\xb7\xaf\x3e\xe9\x38\xaf\x1a\xa1\xe6\x69\xe8\x5a\x61\x79\xef\xf6\x62\x28\xbd\x15\xcf\x03\xd1\x63\xfb\x79\x4e\x88\x00\x54\x6a\xfb\x56\xf4\x04\x44\x20\x34\x41\x4a\xb1\x88\x55\x7b\xb0\xcd\x47\x77\x2c\x62\xcc\x16\x5d\xc9\xf9\xb5\x2c\x77\xba\xfc\x2a\xbc\x83\xd8\xe4\x6d\x8e\x58\x92\x59\x40\x82\xbd\x8f\xe4\x9a\x7d\x0e\x1e\x23\x86\x8a\x26\xfd\x62\xf3\xd0\x77\x1f\x86\x28\x08\x04\x81\xde\x69\x76\x75\xa6\xcc\x10\x05\x71\x48\xf5\x26\x87\x51\x9c\x15\x1d\xab\x6d\x38\x69\xa2\x20\x4e\x92\x90\x96\xa3\x6f\x35\x56\x05\xec\xd1\xa9\xdf\xf6\xdf\xc4\x28\x70\x8f\xc4\xde\xf6\xa2\xd4\xe3\xbd\x28\x0a\x30\x23\xc4\xbf\xeb\xb8\xd6\xbe\x94\x30\xb9\xb6\x45\x61\xa6\x89\x41\x26\xf3\x66\x0f\xf5\xc7\xb6\x9a\x56\x46\x84\x28\xe6\x8c\x5e\xb4\x0a\x1a\xbc\x45\xd5\x06\x60\x7e\x61\x8a\x62\x69\xb1\xd5\x2f\xff\x6e\x06\x37\x2b\x36\xc8\x6d\x0f\xf9\xe7\x40\x8b\x03\xa2\x24\xe2\xd6\xf0\x76\x57\xd6\x68\xc5\xd6\x48\xc3\x72\x67\x65\x6c\xfa\x77\xc9\x7d\x22\x65\x36\x9a\x5f\xfc\x78\xea\xfe\x14\xd9\xec\xe0\x2d\xff\xc4\xa7\x01\x31\x18\xa2\x34\x31\x56\xcd\xa0\x81\xfd\xe1\x7a\x70\x1a\xb5\xc9\x48\x68\x57\x6f\x32\x00\xf2\x61\x9a\x5d\x04\x07\xaf\x43\x94\xb5\x33\xd0\x16\xb0\x5f\xf3\x0a\x8a\x77\xa8\x2f\x8b\x39\x51\x16\x09\x54\xbe\x0a\x4f\xde\x0d\x2b\x3c\x58\xfe\xa4\x1b\xc1\x05\x52\x4e\x85\x3f\x0f\xbb\xb2\xc2\xbb\xf6\x51\x16\x8b\xa7\x97\xe7\xcd\x79\x45\x8f\xb8\x01\x0a\x34\xcf\x71\x92\x83\x5d\x4e\xe4\x58\xee\x23\x42\xa4\xce\xad\xa4\x20\x61\xff\xb5\xef\x90\xfc\x85\x5e\x44\x90\x77\x31\x5b\x24\x34\x47\xe3\x9b\x42\x83\xcc\x2e\x12\x18\xf8\x0c\x67\x66\x4c\xbe\xcb\x3b\x88\x13\x44\x90\x66\xb4\x0c\xfd\x75\x8f\x4d\x1b\x1e\x2f\x6f\xbb\x23\x98\xfa\x68\xfa\x75\x07\xcd\xb0\x08\x13\x49\x2e\x09\xf7\x3a\x9f\xdd\x94\x3f\x47\x7a\xae\x10\x29\x19\x9f\x8b\x64\x56\x7e\xb8\x87\x55\x80\x48\xe9\x44\xc0\xb9\xb5\x31\xba\xe5\x9a\x59\xd1\x1a\xdb\xdf\x3a\x56\xe5\xb7\xdd\xa1\x9b\x09\x5a\x58\xcd\xa5\xa5\xb6\x6e\xb3\xae\x8a\x3f\x8c\xaf\x23\xad\x22\xa1\x3c\xce\xa4\x8d\x8a\x5f\xcb\x66\x6d\x7d\xd4\xba\x13\x61\x42\xd9\xd8\xb6\x63\x4f\x43\x84\x71\xe8\x45\xed\xd6\xf9\x5b\xf1\xed\xf0\x52\xbc\x18\xd3\x5b\xe9\x22\x4c\x62\x32\x12\xa2\x9d\xed\x96\x1a\x7b\x70\xd1\x85\x82\x08\x45\xe0\xa9\x27\x9b\xbc\x39\xc3\x81\xed\xe1\x38\x0c\x02\x16\x75\x3c\xe6\x03\x56\xe7\x89\xf0\x8f\xd1\xc8\x34\xb1\x5b\x41\xfb\xda\xbb\x29\x33\xdc\xe0\xfd\x40\x01\xd4\x42\x5e\xcf\x9f\x6f\xb7\xf3\xd5\x8f\x5b\xca\x15\x09\xcb\xe8\x7e\x5d\x1c\x45\x9a\x0c\xba\xbf\xce\x3c\xdc\x43\x59\xa3\x1e\x14\x7d\xe2\x28\xcb\x08\x02\x42\xa2\x11\x2f\xc5\x5d\xfe\xf6\xde\x5c\x81\x62\x0c\xd7\x94\x38\x52\x11\xa9\xad\xb6\xbb\xe9\xb1\x9b\x62\x71\x9c\x45\x14\x0c\xd4\x4d\x9b\x9f\x93\x8b\xbf\x3b\x92\xc4\x48\x0a\x60\xf3\x97\xa7\xa7\xe5\x7a\xdd\x46\x51\x67\x4a\x03\xc4\x89\x01\x2f\xb9\x52\x7e\xe2\xa0\xe6\x38\xd9\xa1\x84\x38\x8d\x6c\x50\x6a\x57\xa7\x15\x2a\xcc\x3f\x47\xba\x8f\x10\xa7\xb1\x81\xc0\xdf\x52\xd7\x47\x3c\x1b\xfe\x0c\x6f\x7f\xc6\x64\x4a\xae\xc5\x5f\x88\x07\x37\x95\xfd\x54\x8c\xb3\xd4\xfa\x20\xe4\x85\xce\xc9\x20\xba\xd0\xeb\x52\xe5\xb0\x23\xae\xf7\xc0\xa3\x0c\x62\x1e\x44\xde\xca\xe1\x06\x6a\xab\x59\xff\xcb\xfa\x8a\x9d\x08\x41\x3c\xf8\xbf\xd1\x8d\xf7\x6b\x45\xcc\x39\xd0\xa5\xfc\x75\xf8\xeb\xbf\x13\xe3\x81\x98\x1b\x19\xf9\x68\xe0\x96\x2a\x12\x8f\xf0\x75\xea\x96\xb5\x58\x70\x16\xd9\xb2\xe9\x27\xd6\x24\xb2\x65\xa9\xbf\xe3\x2e\x67\xbf\x6a\x73\xa5\xd8\x19\x43\x00\xa4\xb6\x26\xb1\x40\x43\x0c\x8c\xa1\x5c\x00\xc4\x32\x8b\xa9\x29\x3d\x7f\x87\x0a\x54\x83\xd5\x90\xb0\x0f\xb1\x54\x8a\xea\x05\xf4\xe2\xd1\x6f\x9c\x52\xab\x87\x58\x62\x42\x0b\xda\xc3\x72\xd3\x73\x45\x6c\xff\x6e\xd7\x8d\x79\xd9\x6e\x4c\x45\x63\xeb\x9d\xbf\xf5\xf3\xa8\x5e\x32\x15\xab\x30\x26\x93\xd5\x43\xd7\xa2\x75\x5c\x84\x2b\xad\x72\xf7\x31\xef\xd7\x4b\xa8\x81\x1b\xef\xcc\xeb\x0f\x06\x48\xde\xd4\x4d\xde\x2d\x67\x31\x0a\xf0\x06\xe4\x67\x1d\xb3\xb3\x97\xe5\x28\x1a\x88\x4d\x22\x09\x14\x97\xd7\x77\x55\x59\x34\xab\x63\x51\x60\x65\xb3\x94\x97\xcf\xf3\xb3\x33\x32\x4d\xdc\xfa\x72\x7f\x8b\xfb\x52\x8d\x4f\x23\x11\x5d\xdc\x4b\xd9\x1a\xd6\xb3\xaa\x82\x13\x6d\xac\x84\x94\xe8\x4e\x95\x04\xb1\x8d\x28\x2a\x52\x45\xf9\x3c\x6f\x1d\x49\x00\x21\x57\xfd\x02\x78\x59\xd5\xb3\xce\x02\xd0\x8f\x0a\x53\x11\xc8\xce\x4e\xef\x6e\xa0\x3d\x38\x5c\x3f\x92\x28\x36\x56\xf0\x14\x76\x6a\x0e\xc5\x8c\xa8\x07\xc3\x72\xc5\x3f\xfa\xde\x24\xfe\x63\x59\x82\x81\x77\x05\xe9\xf9\xf5\xfa\xc3\x4a\x53\xb2\xe3\x68\xfc\xfe\x25\xb6\x10\x03\x7f\x95\x49\x22\x49\xdb\xe0\x19\xbf\xe6\x6d\x3a\x3e\x15\x3f\x27\x09\x68\x2a\x49\x6d\x2d\x63\xd2\x76\x2f\xfa\x79\xfa\x04\x25\x1a\x92\x44\x72\xd3\xde\xc0\x9b\xd9\xfc\xf7\x6f\xaf\xdb\x97\x67\xbf\xbe\x25\x3c\x14\xa9\x0d\x11\x9f\xac\xb2\xcc\x5d\x5e\xe4\xf5\xfb\xf9\xaa\x78\x14\xd3\x36\x69\xb0\x51\xef\xce\x8a\x83\xda\xaa\xf5\x5d\x59\xbd\x5a\xf9\xf8\x99\xde\xe7\xe3\x0b\xe5\x51\x4c\x91\x8d\x95\x4d\x7b\x3b\x0b\xcc\x0f\x56\x80\x44\x84\xd2\x42\x2f\x00\xea\x57\x38\x91\xfe\xb2\x3b\x04\x32\x22\x60\xb0\x0d\x8a\x33\xff\x67\x19\x70\x8a\x0c\x9f\xe7\xb3\xf5\x03\xb1\x9d\xbb\x23\x59\xa8\x5c\xca\x4b\xbc\x8a\xa8\x3b\xc0\x0d\x55\xc3\x9f\x66\x7f\x6c\xd7\xcb\xcd\x62\xdb\x45\x18\x89\xd4\x99\x51\x5e\x71\xe4\x48\x31\xf2\x08\xa3\x03\x89\x8e\x2c\x3d\xf9\x0d\x9b\x59\x5d\x63\xb3\xd4\x13\x61\x5f\xa2\x53\x26\x75\xb7\x53\xdc\x94\x50\x4d\xeb\xb4\x43\xa2\x25\x52\x50\x95\x9b\x1d\xfa\xd2\x7c\x82\xed\x7e\xdc\x35\xba\x5e\xb1\x5a\x34\xef\xfd\x82\x7f\x82\xa9\xc9\x5c\x9b\xf5\xa5\xa0\xe4\xc7\x1f\xc8\x38\x45\xf9\x1f\xb0\xcb\xfb\xfc\x74\x48\x50\x82\xd5\x4e\x1c\xc0\x2c\x87\x0f\xc0\x08\x6b\x94\x76\x8b\x9f\x4f\xc4\xaf\x77\xb1\x0a\x56\x8b\xcd\x43\xcf\x84\xa4\x1d\x29\xa9\x19\xec\x62\xcc\x6f\x75\x5e\xbc\x4d\x48\x43\xd8\xd1\x69\xc8\x80\x60\xb2\xb3\xb7\x2a\x27\xca\xc4\x13\x5c\xc2\x57\x21\x0d\x13\xeb\xb8\x44\xba\x8f\x3e\xad\x7d\x7d\xf8\x63\x3a\x65\x48\x43\x21\x09\xb4\xee\x73\xa8\x7a\x53\x3e\x11\x3f\xea\xda\x78\x25\xc2\x1e\xd6\xb5\xb7\x34\x4c\x3e\x9a\x34\x34\x29\xbd\x28\x56\xcb\xdc\x51\xbb\x7f\xd9\xd9\x49\x23\xb0\x00\x79\xc7\xdd\x1c\xce\x8a\x34\x16\x11\x89\x45\xa9\x1d\x42\x71\x3c\xcc\x24\x14\xba\x7d\xb7\xc9\xc8\x6d\xf8\xdd\x31\x68\x6a\x2e\x59\xe1\xa8\x5f\x55\x82\xd3\xc4\x49\x2a\xda\xe6\xdb\x04\x31\xea\xa2\x44\xd7\xdf\x0a\xd3\x44\x47\x04\xde\x5a\x17\xf0\x81\x7d\x42\x3d\xa4\x09\x86\x24\xa6\x28\x8f\x27\x5a\x84\xab\xd3\xe8\x07\xa5\x5c\xc5\xa1\xd5\x8d\xce\xeb\xf7\x99\xc5\x8c\xfb\x4f\x67\x71\x92\xe2\x90\x1e\x45\x4a\xc1\x37\xa7\xcd\xe9\x80\xb3\x42\x0f\xd4\x99\x86\x3f\x3f\xd3\x29\x21\xbb\x9e\x20\x27\x61\x0e\xa2\xd1\xf8\x65\x28\xe5\x32\x80\xc0\x77\x86\xbc\xb9\xbd\x8f\xbb\x87\x27\x12\x2c\xa3\xf7\xe1\xdb\xed\x7c\xee\x3f\x2e\x92\x90\x7a\x8f\x63\x9d\x7b\x7f\x58\x58\x3d\x96\xcf\x1c\xbf\xd2\xd8\x7f\x08\x22\x45\x11\xf2\xbd\x77\x59\xea\xd9\x06\x40\x0a\xc6\xba\x48\xa9\x63\x55\x9d\xe9\x07\x90\x4a\x86\x99\x33\xac\x9d\x55\x23\xbd\x71\x48\x65\x10\x61\xd8\x97\x5f\xca\xf7\xc7\xfd\x06\x3e\xb0\x7a\xad\xca\xa6\x54\xe5\x6e\x8c\x31\x84\x54\xa2\xd2\x69\xc7\xd4\x3e\x33\x76\xdd\x61\xc5\x84\x97\xd8\x5f\xbf\xe7\x87\x35\xba\xcd\xad\x7b\xdc\x2a\x45\x8a\x89\x9f\xe0\x2d\x57\xeb\xa6\xac\xc6\x33\x4f\x09\xeb\x78\xdc\xa9\x4d\x91\xfa\xc6\x45\x3c\x78\xe5\x05\xd0\x59\x92\xba\xc6\xaa\xd3\xa7\x69\xf3\xa9\x17\x63\xc3\xec\x5e\xf0\x91\x6a\x30\xe0\x7e\x88\xeb\x9d\x52\x35\x6c\xe0\xbf\x0e\x29\x86\x31\xc9\x0e\x38\x63\x25\xe7\xe0\x36\xfc\x4e\x84\x98\xea\xd6\x4f\xb3\xe7\x87\xd9\x66\x33\x7b\x7e\x5d\xbd\xfc\xf1\x67\xb2\x79\x98\x7d\xf7\x5b\x5b\x6a\x02\x41\x24\x32\x6d\x51\x77\xcf\xa5\xc6\x3e\xde\xbf\x1b\x96\xa4\xc0\xce\x52\x63\x6e\x53\x0e\xff\x1c\xdd\x23\x23\xa3\xd8\x61\x9e\xfd\x32\xd5\x87\x5b\x43\xc6\x18\xa3\x85\x34\xb7\x3e\x8c\x8f\xd7\x44\xff\xdb\x91\x40\x4a\x77\xff\xfa\xf1\x00\x87\xc3\xa9\x3b\x41\x90\x12\x2f\xf3\x61\x31\xbb\xed\xfe\x16\x71\xeb\x3a\x6a\x6d\x0c\x7e\x60\x3e\xbc\x11\x19\xd3\x96\x90\x89\x4e\x53\xa5\x1e\xd4\x2c\xb2\x20\x91\x94\x76\xef\xe0\x38\x29\xd7\xec\x87\x65\x11\xb1\xbd\x35\x5a\x0d\xfd\x5f\x2c\x94\x97\x45\x82\x2c\xd0\x11\x41\x89\x48\x57\xf6\x6c\xe1\xe4\x57\x80\xe1\x8d\xcc\x22\x16\x11\x86\x12\x87\x65\xb0\x2c\x0a\x45\x74\xee\xa1\x5e\xe8\x68\x0f\x27\x5d\x96\x30\x41\x93\xe4\xb3\x6c\x90\x45\x7f\x62\x5f\x10\x0f\xb2\x24\xb0\x45\xbf\x3d\x7c\xe0\x53\x59\x34\xef\x93\x54\x03\x68\x93\x27\x12\x43\xdc\xdb\xf7\xf0\x5c\x2b\xc9\x52\x8c\x28\x18\xb3\x32\x10\xb7\xb3\x3f\xc3\x11\x2b\x0f\xb2\x2c\x95\x74\xd3\x2a\xb4\xaa\xd6\xc7\xea\xb0\x3b\xd6\x8b\xe6\x7d\xf4\x83\x79\x26\x82\x0e\x4d\x32\x2f\x0b\x4b\x6c\x1a\x75\xe3\x32\xc1\x2c\xe7\x7d\x5b\x63\xf3\x5a\x7e\x61\xd5\xb5\xa3\xcf\x97\x2b\xe2\x34\xc6\x0e\x00\x77\x73\xac\x2e\x10\x30\x99\x10\x69\x90\x9d\x2d\xae\xc9\x4b\x6f\x74\x12\x29\xd1\x57\x62\xec\x47\x37\xa5\xdd\x9b\xc7\xa7\x72\x22\x97\xb5\xa5\x57\xd9\xba\xf9\xf4\x6e\x9f\x81\xe0\xe8\x75\xd8\xca\x3d\xe4\xa3\x00\x38\x03\x64\xa4\xa0\xe5\x9a\x27\x65\xdd\x7c\x5b\xdf\x5e\x8c\xd1\x54\x3d\xd8\x52\x7f\xf3\xe9\x34\x7b\x1b\xab\x9f\x43\x26\x83\x80\x8a\x3a\x78\x28\xd5\xfb\xd6\x9c\xa1\x30\x99\x14\xc6\x5b\xe2\xcd\xcb\xe3\x81\xa0\x72\x0e\x1f\xd8\xdd\x63\x95\xa2\x64\x1e\xd5\xb2\xfb\x6c\xa7\x6a\x0f\x92\x0e\x99\xca\x02\x12\x20\xdf\x6e\x77\x25\xe8\x20\xe4\xfd\x82\x51\xa6\xd0\x5a\x45\x38\x0a\x83\xbb\x79\x77\x55\xb9\x9f\x97\x25\x51\xc0\xf2\x4f\x5c\x93\x3d\xf0\xd9\x3b\x68\x94\xa2\x5d\xa0\x9b\x8f\x17\xd0\x3c\xc8\x94\x49\x49\x61\x8e\xea\xbe\x8c\x16\xe3\xde\xfa\x98\x21\x53\x09\xf3\xa5\xa9\x36\x8f\x7f\x84\x0a\xd7\xe5\x4e\x2f\x0b\xa7\x98\xe6\x47\x1a\x6e\xfb\xae\x4b\x6f\xca\x00\x99\x01\x45\x29\x68\xa5\x8a\xf3\x9f\x90\x00\x04\x87\xa3\xfc\xc0\x53\x1d\x0e\x1f\x0b\x67\x41\x48\xaa\x50\x79\xbd\xb5\x92\xc4\xbf\xf9\x03\x42\x5a\x81\x74\xab\x10\x64\x7d\xb7\xfd\xc1\x20\xb4\xe2\x4a\xf3\xf9\xc3\xf6\xee\x7e\xb5\xf0\x8c\x00\xe0\x01\x30\xc2\x2b\x5a\x7b\xfd\x2e\x1e\x1c\xdd\x98\x2b\xf5\x88\xab\x18\x10\x1e\xa8\x08\xdc\x0c\x6c\x93\x88\xb1\x9e\xda\x70\xbe\xf2\x00\x33\x6f\x7e\xb7\xf8\xd9\x60\xd1\x29\xd8\x00\x0f\x79\x1c\xbb\x8c\x60\xb1\x9a\x67\x61\x60\xb3\xbf\x57\xf8\x2a\xa6\x01\x2d\x3c\x44\xa4\x93\x95\xea\x40\x2b\xda\x28\xc6\xe5\x51\xa4\x3b\x2c\x9c\x7a\xc7\xce\xac\xa3\x3b\x9e\x0a\xda\x7e\x7f\x74\x4a\x27\xc0\xe3\x40\x06\x9d\x29\xd1\xdb\xb1\x42\x92\xcf\x6a\xca\xaa\x43\x67\x02\x8f\xa3\x10\xad\x63\xc0\xb7\xc2\xa1\xd5\x1d\x7d\x61\x78\x7d\x71\x1c\xd2\xb4\x5e\x43\x5e\x34\xf3\x32\x2f\x48\xa2\xdb\x9f\x25\x11\x9a\xc8\xa2\x95\xc5\x8d\xb8\x53\x8c\x92\x7e\x9e\x48\x4d\x35\xc7\xad\xc9\xc7\x2b\x0a\x4f\x94\x15\xdc\x5a\x51\xff\xbb\xe7\x81\xce\xfd\x00\x13\x53\xef\xe6\x5b\xb5\x7b\xc8\x8b\xe6\xb7\xe1\xa7\x4d\xa6\x9d\x35\xcc\xee\xe4\xea\xa3\xff\xd7\x0a\x0f\x7f\xf7\xaf\xfb\xae\x94\x69\x4a\x29\x67\x5a\x53\xa6\x39\x0c\x44\xc7\x83\x03\x1d\x5a\xc3\xe3\x9f\xfd\x46\x30\x4f\xe3\xc8\x12\x65\x60\xa7\x08\x9d\x49\x8d\x51\x9b\x36\x5d\x04\x6f\x3c\x4d\x22\x82\x8d\xdf\x63\xf3\xe3\xbd\x74\xe5\x2b\x4f\x95\xee\x67\x62\x3c\x05\x45\x4a\x46\xce\x2c\xda\xad\x2f\x9d\x19\x0b\xf0\x54\x27\x32\xed\x78\x3d\x2f\xcd\x3b\x56\xb4\x7e\x11\x76\x23\x98\x4a\xaf\x79\x16\xd8\x5d\xe5\x40\x90\xa4\xae\xb0\x35\x54\x65\x72\x63\xb9\xb4\x04\xf2\x7a\x57\x76\x5f\xc9\x95\x8a\xbc\x9f\x52\x07\x42\x1e\xcf\x0d\x6e\x22\x96\x8e\xfc\x2e\xff\xe6\xfd\x13\x51\x48\x42\x2a\x9d\xd0\x66\xf8\x27\x42\xf7\x42\x88\x38\xd2\x94\x14\x7e\x62\x65\x88\xf8\x59\xe7\x54\x30\xf3\x52\xfc\xbf\x2e\x02\x73\x91\x58\xab\xea\x63\x71\xe1\xbf\xe4\x46\x40\xa2\x6d\xf1\x29\x6f\xf2\xbf\xb0\xa8\xed\x3b\xee\x37\x02\xde\xce\xca\xc8\x23\x6d\xea\xe3\x7e\xfc\x69\x93\x01\x3f\x3b\x9b\x93\x89\xba\x3b\x24\x03\x4e\x41\x27\x92\xd5\x6d\xaf\x54\xc5\x55\x16\xc6\x3d\x29\xc7\xad\x4d\xa0\xfc\x51\xad\x22\x11\xfa\x6f\xf4\xfb\x32\xc2\x7e\xf3\x55\x8e\xbe\xdc\x70\x43\x89\xf5\xd3\x3f\xe7\xf3\x7e\x00\xc5\x8d\x12\x94\xc4\x2c\x9f\x97\x9b\xe5\xec\xd1\x69\xe1\x8f\x45\xb1\x40\xb0\x54\x28\xdf\x4a\x26\x6d\xcd\x41\x20\x22\x98\x61\x44\xfa\x2d\x8e\xfb\xcd\xb1\x6a\x33\xec\x15\x7e\x96\xbb\x6e\xdd\x17\x01\x97\xf4\x74\x40\xeb\x4d\xe5\x95\x92\xcf\xc8\xc0\xd1\xc2\x2c\x42\x4c\xa9\x4b\xff\x1d\xf1\xad\x1c\x88\x3d\x0c\x9f\x9a\x88\x52\xa6\xb5\xbf\x05\x67\xd1\x4f\x10\x91\x0e\xbc\x86\xc2\x3d\xd4\xfd\x77\x51\x9c\x25\x5d\xac\x8e\xcc\x5f\xb8\x3e\xca\x9e\x62\x15\x88\x38\x4c\x94\xb5\x17\x75\x80\x8c\xe1\x97\xc6\x3a\xa6\x4c\x9a\x00\x6d\x37\x8b\xcd\xf0\x56\x25\x09\xa3\xd4\xa6\xbd\x17\xfd\xe0\x7b\x74\xe5\x89\xb4\x2c\xcc\xfb\x0a\xa1\x79\x80\x6a\xdf\x65\x17\x22\x31\x81\xb5\x66\x5b\xce\x7f\x5f\x6c\xfa\x1e\x7f\x20\x52\xce\x88\x70\xbb\x77\x26\xda\xa3\x07\x91\xc5\x92\xda\xa3\xbf\xbf\xcc\x9f\x5e\x7c\x26\x2b\x32\x1d\x58\x0b\xc3\xc7\xd9\x7a\xfd\x67\x7f\x02\x08\xae\x19\x05\x6c\x1d\xe9\x0a\x75\xdf\x89\xa3\x6f\xd7\x03\x42\x04\x86\x36\x1d\x57\x19\x59\x1f\x68\x13\x74\x6d\xd8\x51\xc1\x73\xf8\x6b\x45\xc4\x6d\xcf\xd2\xd5\x62\xaf\x1a\x49\x80\x10\xb1\xb1\x6b\xbb\xd6\xdf\x73\x8d\xe5\x7d\xaf\x0c\x78\xe5\xe4\x12\xe9\x13\x8e\xaf\xb6\xee\x23\xfc\xff\x2b\x50\x83\x68\xc3\x8b\xb3\xca\xcf\x7d\x47\x51\x6c\x8f\x58\xcf\x2a\xd2\xa6\x53\x1d\xde\x8f\xfb\xc3\x90\x51\x05\x8e\x4a\x51\xae\xdb\x74\x29\xc7\x06\x02\x10\x08\x2a\x4c\xc0\xef\x81\x71\x10\x08\xc9\x24\x81\x42\xf2\xda\xc9\x29\xf9\xbf\x87\x29\x45\x27\x1a\x55\xa9\x71\xe8\xd9\x74\xe5\x77\xc8\x8c\x19\xfb\x91\xba\xa9\xca\x13\xad\xf4\x97\x36\x9c\x20\x24\x46\x7e\x89\xbe\x83\xba\x21\xb6\x64\xf7\xb5\xc6\xbe\xea\xf2\xcc\xd2\xed\x5e\x0c\x15\x27\xc4\xc6\x6e\x27\xca\xe2\xed\xad\x5e\xea\xf3\x21\x00\x79\x56\xe4\xb8\xc7\x82\x8d\xde\x1a\x9d\xc6\x8a\xdb\x90\x71\x97\x2b\x5a\xce\xdc\x45\xf9\x53\x68\x13\x50\xdd\x8b\x4a\xc5\xaf\x90\xff\xad\x7a\xbf\xfb\x1c\x46\x48\x66\x4a\xf4\x10\x6e\x8e\xa7\xf9\xb1\x7b\xd7\x4d\x90\xfd\xff\x9c\xbd\x5b\x77\xa3\x38\xba\x3f\xfc\x75\xea\x62\x5f\x00\x42\x42\x5c\x3a\x8e\x53\xe5\x7f\xe7\x34\xb6\xd3\xd5\x33\xb3\xf6\xf2\xd2\xe1\x91\xc3\x04\x83\x07\x70\x52\xe9\x4f\xff\x2e\x1e\x49\x9c\x8c\xd3\xbd\xdf\xab\xea\x0e\x32\xc6\x20\xa4\xe7\xf0\x3b\xe0\x8c\x95\xe7\xcf\xb5\xb2\xf8\xdb\xb0\x3b\xc6\xac\x8f\xde\xb6\xa9\xb2\x63\xbb\x6e\x76\x07\x84\xf0\x64\x72\xcb\x28\x9d\x45\x8f\x8b\x20\x8a\x10\x81\xfe\x22\xd4\xf0\x95\x12\x41\xa4\xa9\x03\xae\xee\xcd\x74\x6f\x17\x01\x15\x92\x79\x79\x7e\xc8\xf3\xdd\x47\x39\xba\xc7\x22\x4c\xa9\x6d\x95\x14\x0d\x54\xd5\xf9\x64\x35\x60\xca\x3e\x4e\x16\x11\xb3\x34\x4d\x5f\x7a\x59\xd4\xce\x0f\x60\x5a\x5f\x16\x84\xa6\x18\xb9\x17\xf0\x31\x8a\x32\x47\xc2\x16\xe8\x4a\x84\x58\x8d\xc5\x59\xb7\xa1\xde\xe8\xd7\x10\x11\x04\x76\xdf\x1a\x92\x55\x85\x88\x49\x90\x38\x96\xce\x20\xd1\x10\x71\x0c\xa6\xd7\x8d\x7f\x14\x47\xd0\x96\x66\xaf\x2e\xe8\x89\xfd\x3b\x2f\xe2\x34\xc2\x18\xeb\x3b\x34\x83\xaf\xa0\x09\x20\xa5\x02\xaf\xe7\x5e\xc8\xaf\x8b\xaa\x82\x72\xa9\xad\xd6\xef\x02\xda\x38\x67\xd9\xce\xfe\x91\xc7\x81\x10\x54\x52\xea\x7a\xba\x07\xd8\x7d\x94\x03\xcd\x58\x21\xa8\x4a\x02\x57\x89\xbc\x5d\xac\x27\xb7\x92\x41\x84\x72\x7b\xaf\xa2\x7e\x2a\xa0\x8d\x3c\x26\xd0\x10\x91\x30\x7b\x6e\x6b\x17\x37\x74\x95\x11\x22\x01\x8a\x09\x82\x3e\x17\x07\x28\x8b\xdb\x89\x88\x87\xc0\x90\xda\x69\x07\x5b\xa9\x6b\x91\x55\x97\xf5\x8c\xf1\x04\xe4\x8c\x24\x41\x97\x20\xff\xb1\x7e\xbe\xdb\x3e\xe3\xcb\xf5\x1b\x7c\x8e\xc2\x44\x21\x13\xbb\x2d\x74\xe6\x56\x3e\xe9\x1b\x3c\x03\x99\x0a\xfb\x03\x11\xf1\x34\x2c\x8d\x08\x29\x8c\x69\x6f\xcc\xcf\x57\xaf\x52\xe7\x8f\x28\xc2\xf1\xa5\x16\x5a\xf7\xa5\xbb\xfe\xa6\x29\x1d\x60\xb9\x03\xb7\xe7\x47\xf8\xb0\x28\xf7\xc9\x7b\xa4\xa9\xa5\x05\x5b\xdf\xfa\x6a\x20\x03\xe7\x07\x70\x69\xf5\xf3\x45\xae\xce\xb9\x68\xe0\x58\x56\x4d\x06\x35\x4c\x84\x67\x84\xd0\xc2\x5a\xe0\x0f\x64\x3a\x8a\xe6\x12\x87\x27\xb4\xb2\x58\x70\x47\x9c\xfd\x5e\xc1\xa7\xf5\x92\x3b\x4f\x94\x2f\x84\xd0\x5a\xdb\x84\xc9\x99\x55\x7c\xcf\xde\xfb\x9f\x0f\x24\x76\x9d\x74\x5b\x80\xb7\x7b\xe0\xb4\x7c\x25\x0c\xb1\xaf\x21\xde\x86\xbd\x27\xe5\x8c\x07\xc9\x80\x01\xb8\x67\x34\x1f\x32\xc8\x80\x5b\x69\x08\x91\xcb\x72\xac\x4d\x23\x64\x18\x44\x38\xf9\x1a\xef\x86\xba\x2e\x9c\x01\x8e\x1f\x10\x49\xdc\xa9\xac\x58\x4e\x73\x0b\xef\x7d\xe5\x4a\x46\x8c\xfb\x6a\xb1\x47\x08\x6f\xdb\xff\xac\x9b\x75\xb1\x68\x9a\x72\x28\xf7\x2d\x64\x94\x04\xf8\xab\x5f\x0a\xf1\x95\xb9\xb0\x90\x51\x4a\xf0\xa2\xfc\xc6\xec\x04\x40\x3d\xef\x7d\x46\x8e\xfb\xff\x94\x9a\x49\x12\x70\x2c\x5c\x1d\x5c\x84\x77\x57\x56\x9e\xa5\xe5\xaf\x95\x08\xa6\x9c\xac\xd1\xb3\x68\x7f\x78\x7d\xe7\x04\xe8\x26\x1e\xd7\x42\x12\x45\xb1\xe6\x26\xbd\x28\xa2\xcd\x8f\xc3\x49\x55\x57\x12\x1d\xa0\x68\x84\x0d\x16\xb0\x8f\x79\xf1\xa6\xfa\x48\x56\xc6\x4c\x63\xf9\xad\x42\x57\x54\x91\xa3\x24\xc0\xd2\x4f\xe4\x2b\x0f\x9a\x86\x02\xb1\x5b\xf2\xfc\xb9\x7a\x7e\xf1\x3f\x85\xa6\x2c\x74\x38\x6d\xd4\x14\xb7\x70\xe3\xf2\x63\xa8\xed\x24\x24\x55\x54\xba\x37\xf2\x5c\x5f\xb7\xa1\xf4\xa3\xb5\x85\x82\x0c\x88\xa0\xee\x08\xe3\x21\x02\x2b\xfd\x26\xb3\x6a\x5e\x2f\xb6\xe3\x51\xec\x29\x13\x42\x04\x19\xba\xb5\xa1\x5c\xfe\x64\xd7\x94\x89\xb6\x00\x3a\x61\xd3\xe9\xaf\x5a\x56\x92\x33\xab\xf5\xdb\xbd\xf8\x9b\xd2\x61\xe5\xa7\x50\xf2\xe9\x07\xa5\x42\x32\xc7\xbe\x1e\xa8\xed\x0e\x48\xae\x33\xa9\xac\xe4\xc6\x20\x6e\x64\x6f\xdd\x4d\xff\x1c\x16\xfc\x65\xca\x6c\x2b\xe9\x66\x7b\x7b\xd3\xfd\x2d\x09\x85\xec\x2a\xab\xa3\xaa\xa1\x94\x81\x14\xe9\xd0\x94\xc2\xbe\x75\xed\x9a\xeb\xb7\x71\x29\xc3\x00\xac\x07\x64\x76\xda\x9e\x60\x70\x20\x09\x31\xaf\xfb\xa7\x4f\xd6\xce\x7f\x05\x8a\x91\xca\x79\xf7\xec\xca\x53\x03\xca\x07\xec\x52\xc7\x41\xea\x84\xc0\x8f\xa7\xda\xf9\x83\x0e\x97\x76\x09\x9c\xd8\x04\xb0\x23\xc7\x0e\xd7\x77\x09\x12\x30\x6b\xbd\x2f\x0f\x5b\x68\x9c\xd5\x6d\x0f\xfa\xb2\xa3\x54\x18\x68\xec\xac\xb4\x31\x0d\xe6\x33\xaf\x50\xed\x5e\x45\xf1\x54\xad\xfe\x7b\xf6\x36\x4d\xed\x30\x2b\xe7\xd5\xee\x42\xd9\x2f\xc8\x2f\x88\xc9\x42\x85\x71\x84\x65\xcc\xf6\x4c\xab\x6e\xc5\x51\x11\x15\x88\xe0\xf4\x2b\xc7\x6d\x75\x3e\xf5\xe7\x8d\x28\xa4\x16\xc8\x88\xc1\x8d\x6b\x25\x20\xcc\xe1\xd2\x90\xdd\x3e\x26\x8b\xfe\x49\xa3\x61\x0d\x55\x11\x22\x07\x9e\x37\xbb\x4a\x4c\x1c\x07\x84\x22\xa9\x35\xcd\xf9\x0e\xb9\x68\xca\x01\x4c\x47\x11\xad\x61\x28\xeb\x7e\x07\x93\x86\x99\x8a\x59\x94\x06\x1e\x36\x6f\x31\xea\x43\x0c\xe1\xe8\x79\xaa\x38\xa1\x2e\x47\xd5\x00\xc7\x0b\x10\x4f\xff\xbe\xab\x38\x49\x91\xa3\x6a\x9c\xb4\xf8\x16\xfa\xfd\x49\x51\x9e\x4a\x27\x20\xfb\xff\x4a\xec\xd4\x5f\x14\x9b\x14\xe5\x1a\x99\x13\x6f\xd9\xb1\x76\x58\x8d\xee\xe3\x2a\x65\xc6\x3d\x8d\x7d\xbc\xaf\xcb\x23\xf4\xda\xe4\x42\xb1\x10\x10\x48\xd3\x1e\xbe\xc9\x4b\x69\x3f\xdd\x1d\xe5\x02\x97\x2b\xab\xbc\xf3\xbd\xcc\xf5\x08\x68\xa0\x12\x08\x11\xa9\xe4\x3c\x3b\x41\x2f\xf2\x1c\x69\x06\xb3\x6b\x81\xe2\x6d\x42\x64\x4d\xfe\x8e\x03\x84\x81\xe2\x42\xc4\xe0\xdb\x31\xe5\x47\x07\x8e\x50\x69\xc8\x31\x9a\xc3\xbd\x6b\x03\xd9\x4c\x2f\x47\xb5\x2b\xaa\xab\x5b\x3c\x99\x65\x79\xec\x93\x70\x95\x26\x14\x41\x06\x2f\xaa\x7d\xcc\xb8\xd6\x5a\x85\xb7\x79\xa5\x01\xa1\x52\x63\x53\x8d\xa3\x13\x59\x56\x03\xa4\x9c\x1b\x22\x82\x00\x83\xe3\x77\x51\x65\x88\x53\x1f\x9f\x41\x84\x11\xea\xca\x38\x23\x07\x64\x97\x6d\x4f\xa0\xb2\x01\xbd\x66\xf0\xe4\x65\x94\x78\x53\x99\x47\xf8\xe5\x65\x22\xe7\xb7\x62\x25\x93\x20\xf1\xad\x8e\x76\x17\x7c\xf6\xea\x1a\xe3\x4b\x90\x86\x81\x15\xc7\x30\x02\x6f\x5c\x1f\x24\x28\x15\x31\x94\xbc\x74\xbd\xd1\x61\x4d\x45\xa9\x38\xe1\xa2\x17\x52\x82\xa2\x79\x40\x83\xcd\x4b\x3b\x83\xf1\x0b\xa5\x68\x82\xbb\xd5\xe2\xfb\xea\x71\xf9\x4f\x1b\x34\xef\x97\x8b\x67\x7f\x5e\xcd\x23\xd4\xea\xbf\x5f\xfd\xf6\x6d\x56\x64\x79\xb8\x84\x2b\x08\x22\xdc\x81\x36\xe2\xd4\x94\x55\xfd\x5e\xff\xcc\xfe\x14\x95\xae\xe3\x88\xfa\x13\x42\xac\xb1\xae\x2d\xb3\xc3\x08\x6c\xac\x80\x73\x94\x16\xaa\x40\xe4\x58\xeb\xb6\xb1\xaa\x37\x56\x1e\xfc\x9f\x0b\x1c\xba\xdf\x60\x58\xcc\xa9\xd3\xdf\x73\x88\xc3\x76\x05\x10\xf9\x5d\x55\x1e\xed\x5d\x9a\x7d\xc7\x8d\x0e\x10\x43\xef\x6c\xc4\x87\x78\xa8\xf1\xc3\xd3\x01\xb3\xaa\x6e\xa7\x0a\x4e\x62\xa6\x41\x34\xfb\xc6\xe8\x30\xb4\xb0\xb4\x5d\x95\x8d\x82\x76\x1d\x09\x6d\x09\x3c\x4d\x79\x72\x7e\x1d\xfe\x10\x0d\x28\x72\x87\x6b\x61\x00\x3b\x8a\xf3\x93\x5d\x53\xc7\x24\x7a\x78\x59\x0f\x38\x10\x9a\x05\x56\xf3\xf4\x7e\xf5\xc7\x7a\xda\xd2\xd0\x2c\xb0\x0a\xbf\x7b\xb7\xf5\x2f\x07\x1b\xc9\xe4\xf4\x2c\xb4\x0a\xa8\x88\xdc\x40\x55\x43\xb7\xf5\x58\xcd\xe7\x41\xbc\xa3\x19\xb3\xca\x09\x30\xf4\x69\xaa\xef\x4b\xd1\xf9\xeb\x09\x9d\xf0\x10\x97\xc1\x67\x28\x8a\xcf\xef\x95\x90\xdd\x01\x15\xe2\xce\xa1\x44\x8e\x82\x48\xfe\xef\x3c\x89\xf1\x03\xae\xee\xfa\xd4\xfd\x40\x6e\x18\xba\x77\xf4\x70\xf8\xbd\x29\xab\xbd\x33\xfb\xa8\xfb\x61\xda\xb1\x37\xd1\x80\xe3\xf3\x28\xcb\x7c\xbc\x95\xe8\x94\x26\x18\xa2\x74\xe6\xe2\xfe\xb3\xa9\x09\xbd\x3a\x4e\x7b\x97\x7e\x94\x4d\xbb\x76\x7a\xd0\xe8\x70\x06\x69\x91\x04\xb8\x3b\xe7\x28\xaf\x33\xd6\x7f\x6f\x73\x21\x4b\x23\xc4\x4e\xb3\x8d\x65\xc7\xd1\x96\x1b\x27\x63\x1e\x47\x3d\xff\xee\x7c\xda\xff\x27\xab\x5f\xb3\xbf\x60\xa7\x6b\xc9\x48\x38\xbe\x15\xcf\xe7\xd3\xe9\xb3\x5d\x2d\x1f\x40\x67\x7d\x01\xdc\xc7\xc2\x5a\x6a\x83\x01\xd3\x36\x6b\x53\x0c\x4b\x16\x87\xa9\xce\xae\x1b\xab\x08\xc3\x72\x92\x2e\x01\x89\x28\x4f\x1f\xc5\x12\x72\xb8\xa8\x01\xb8\xe1\x9a\xc6\x38\x6f\x51\xe1\xbe\xfc\x28\x06\x2c\x20\xad\x99\xc5\x33\x60\x9f\xf9\x2c\x73\xf8\x0d\x94\x12\x6f\x11\x65\xdf\x26\x27\x11\xd6\x84\xbf\x0b\x37\xff\x0e\x4b\x5f\x9b\x48\x5a\x6d\x63\x54\x90\x1d\x18\x5b\xb4\x87\xec\x8b\x66\x05\x58\x67\x57\xc2\xd9\x0c\xe7\x82\xec\xad\x4d\x6c\x99\x4c\x18\x3c\x40\x3b\x5b\x06\xaf\x80\x61\x29\x6a\xdc\xec\xdd\x74\xfb\xef\x59\x54\xd0\x7b\x9f\x4d\xce\x05\x81\x73\xea\xdd\xa2\x03\x7e\xbb\x51\x15\x9d\xa9\x95\x7f\x56\x10\xc8\x18\xeb\x11\x96\xe0\x43\xdd\xee\xe9\x0f\xaa\x84\x27\x03\xd9\xbc\x32\x6f\x23\x99\x07\xf1\x0b\x63\xdd\xf5\xd1\x3b\xf0\xf5\x6c\x6e\x88\x48\x82\xc4\x06\xf8\xa5\xfa\xac\x15\x48\x64\x33\xfb\x76\x4b\x71\x6a\x9d\x90\xbd\x4f\x27\x03\x10\x61\x39\xd7\x1a\x93\xd6\x5e\xe9\x56\x00\xd1\xd6\xcd\xbf\xf3\xd0\xf9\x4a\x42\x5a\x40\xcc\x02\xb0\x92\x94\x6b\x14\xb0\xf1\xa7\x89\xb5\x91\xee\x07\x29\x51\xe9\x91\x6f\x9c\x1b\xc2\x88\x85\xc3\x22\xef\x96\xf9\x0f\x32\xc9\x00\x7a\xe1\x6e\x5b\x6c\xfa\xf9\x0a\xc5\xb3\x38\xd7\xd7\xd8\x4e\xc0\x54\x80\x37\x03\xd5\xfa\x1d\x8d\x7c\x8c\x2b\x07\xa6\x09\xe2\x47\x17\x59\xb5\xfd\x10\xa7\x2f\x7d\xd3\xdd\x47\x12\x12\x63\x78\xfd\x54\x40\x8e\x76\xad\xc3\x45\x1f\x92\x98\x88\x21\x5e\x6b\x8f\xdb\xfb\x5e\x14\x7a\x0f\x5d\x85\x1f\x12\x99\xe0\x3c\xfb\x8f\x85\x5a\x6d\x8f\x22\xcf\xfb\x63\x1c\xfb\x5f\x05\x7c\x8c\x27\xf4\x70\x4d\x82\x04\x0c\x56\xba\xff\xb1\xde\xfe\x58\x3d\x7e\xff\x42\xf3\x4a\x00\x8f\x53\x8c\xdd\x3c\x58\x7d\x57\x9e\x9c\x18\x7d\xef\x31\xda\x4d\x73\xe0\x89\x75\xd2\x71\x06\x83\x03\x5c\x1d\x70\x21\xb9\x43\xfa\x3d\x66\xea\x6d\xa8\xd2\xe8\x47\x18\x85\x53\x56\xe8\x0b\xdb\xb4\x8b\xe2\xc3\xe8\x1a\xd3\xc4\xda\x37\xd8\xa0\xec\xf1\xf2\xcc\xa9\x01\x66\xe5\xc8\x9a\x27\x63\x6e\x32\xdd\x01\x85\x41\xc4\x3a\x30\x9d\x74\xda\x16\xa6\x5d\x70\x10\x94\x62\xd8\x24\xce\x3a\x6b\x2c\x3f\xeb\xeb\xd5\x06\x64\x18\x08\x5f\x3e\x76\x2b\xa8\xff\x36\xa9\x24\xef\x4d\x06\x4d\xd6\x3c\x43\x85\x6d\x66\x3f\x40\x45\x0a\x23\xee\xed\x59\xd6\x23\x6b\x40\x7f\x1c\x02\xc4\x64\x3d\x6f\x56\xd6\x6f\x7a\xf5\x78\x3b\xd4\xc3\x01\x1d\x04\xe8\x6d\xb5\xb7\xae\x5a\x4f\x05\x6c\x21\x9f\x14\xbb\x40\x73\xc0\x41\xdf\xb3\xc3\xac\x23\xf0\x30\x7b\x9d\xd2\x17\x40\x83\xa5\xe7\x66\x85\xca\xcf\x1a\xea\xe9\xb9\x0d\xc5\xad\x0a\x2a\x65\x05\x47\xdb\xad\xcd\x5f\x1d\x10\x83\x45\xe4\xe7\x8d\xd5\x9b\xb8\x5f\x3f\xac\x77\xfe\xa0\x71\x1e\x43\xb7\xab\xe5\xfa\x61\x71\x7f\x61\xa5\x2d\xc0\x28\xc0\xfc\x1f\x37\x51\x0c\x06\xba\xc2\x82\x8b\x2f\x4d\x18\x26\x58\x9a\x5f\x8a\x73\xae\xab\xb2\xa8\x1f\xb2\x22\x3b\x88\xa3\x77\x3d\xf3\x02\x1c\xa3\x8b\x36\x51\x98\x08\xab\x9a\xf5\xcb\x96\x76\xdd\x6c\xff\x36\x19\xc6\x8c\x8a\xbc\x5c\xee\xea\xd7\x29\xab\x3c\x19\xdd\x0f\x50\x29\x66\x0f\x85\x47\xc9\xba\x8a\xa4\x5f\x4d\x0d\x09\x35\xf6\x4f\xbe\x43\xd3\x2e\x6e\xab\x02\xc1\x23\xc8\xcf\x1e\x4e\x69\x43\xa2\x28\x72\x85\x9a\x3d\xf6\x4c\xc6\x33\xda\x10\x26\xb0\xb4\x9f\x5b\xf5\xc8\x49\xe4\x3e\x9e\x90\x86\xa4\x29\x32\x95\xf7\x59\xf1\x50\x16\x70\x61\xe1\xe1\x86\xc5\x09\x13\xae\x8f\xb6\x3a\x1c\xac\x40\xd5\xcc\xe6\x64\xe2\x44\x29\xf7\x9e\x62\x77\x04\x77\x60\x9f\xda\xcc\xab\x48\xf9\x4f\x72\xc5\xa9\x2f\xb2\x3a\xcd\x89\x36\x07\x9b\x20\x0f\x0c\x0d\x14\x75\x10\xb5\xdb\xac\x96\xe7\xaa\x46\x5c\xb0\xcb\x06\x26\x63\x43\x86\x28\x1c\xcb\xdb\x39\x57\xc5\xb5\x25\xdd\xd0\x28\xc0\x52\xe7\x09\x39\x2d\x64\x8a\xd7\x31\x34\x62\x1e\x46\x86\x60\x5b\xff\x67\xad\x51\x60\xa8\xab\x39\xa2\xaf\xcd\x05\x2f\xcf\xb0\x88\x07\xae\x8c\x79\x9f\x29\x28\x6a\x18\xe2\xfc\x0d\x93\x2c\x70\xca\xbf\xc7\x2d\x38\x77\x59\x7f\x30\x09\x19\xe2\xe8\x86\x50\x8b\xbf\xb5\xf6\x99\x24\xe9\x22\xc3\x55\x4a\xa6\xcd\xa3\xf1\x15\xf2\xc8\x60\x37\xec\x3d\x83\x0f\x0f\x37\xf6\x54\x67\x7f\x25\x9c\x52\xd4\xfc\x71\x90\xdf\x2b\xb7\x92\x73\x4b\xef\x68\xa7\xb1\x68\x32\xb0\xee\xfb\x57\xbe\x55\x85\xb8\x80\xae\x8b\xcc\xd7\x7d\xda\xc1\x29\x0b\x81\xa6\x44\x12\x96\x46\x81\x48\x58\xa2\x85\x4e\xa8\x49\x8d\x16\x41\x92\x44\x24\x22\xa1\x4e\x65\x92\x5c\xb9\x82\x34\xe9\xc2\x81\x1b\x21\x3f\xbf\xbb\x34\x79\xec\x3c\x2b\x8c\x60\x76\x35\x5a\x64\xd5\xf2\x6f\x09\x18\x18\x21\x38\xde\x24\x94\x66\x32\xe7\x42\x3b\xf9\xbc\x27\x63\xdf\x08\x37\x4c\xd1\x38\x70\x0a\x5f\xfb\xfa\x52\xa0\xd3\x8f\x52\x29\x75\x3a\x9b\xcb\xe5\x0f\x2b\x04\x16\x85\xdd\x39\x94\x41\xf3\xf6\x4e\xa0\xe3\x0a\x03\xd1\x33\x80\xba\x35\xd8\xe8\x80\x0b\xef\x1b\x35\xa0\x74\x5d\x27\xab\x1b\x9d\x32\x3d\x74\x1e\xbe\x2b\xab\xdd\x6b\x05\x30\xc0\xe7\x18\x20\x10\xba\x17\xc0\x15\x43\xb1\x61\xd4\x4e\x95\xba\x7f\x4d\x80\x32\xab\xa8\x29\xaa\xb7\x0d\x88\xc9\x7e\x69\x0c\xb1\x70\x8f\x83\x25\xfd\x6e\x9b\xce\xcb\x5e\x18\x23\xb8\xb7\x96\xf0\xf5\xb5\xe7\x2a\x7b\x9f\x9e\x41\xe9\x04\x06\x3a\x8d\x58\x7b\xca\x06\xb5\x98\x2f\x7b\xcd\x32\x08\xa8\x40\x5c\xbc\xb0\xf9\xe8\x9f\x50\x3d\x79\x0d\x0e\x19\x04\xc6\x3a\x92\xb5\x9b\xf3\x8f\xcf\x53\xd9\xbc\x42\xed\x8d\xc5\x65\x10\x3a\x23\x28\xac\xa6\x65\x45\x0d\x55\x83\xc8\xb8\x9f\x59\xf3\xfa\xa3\x83\x03\xc9\x20\x4a\x64\xec\x3d\x32\xce\x9f\xcf\xce\xcb\x78\xd6\x98\x47\x06\x84\x84\xcc\xf8\x75\xa5\x97\x1c\x90\x41\x1c\x4b\x8f\x6d\x6d\x5f\xb7\xad\x7a\x85\x2b\xcf\x4f\x06\x31\x0f\x10\x1e\xe4\x4d\x02\x1e\x4a\x8d\x82\x3d\xa3\x1e\x93\x0c\x62\x11\x13\xd4\xcc\x71\x89\xa6\xfd\xc2\x7a\xad\x4a\x3f\x82\x32\x5b\xa4\x5b\x3f\x0f\x56\x20\x19\x50\x01\xd8\x7e\xfc\x99\x15\x0f\xa2\xa9\xb2\x5f\xdd\x01\x45\x53\x27\xba\x84\xa0\x8b\xf9\xcb\xa3\x20\xb0\xce\x88\x1e\xb0\xcf\xae\x06\xe2\x8e\xb1\x30\xe2\xde\x0a\xf3\x1e\x4c\x53\xbe\xc3\xd0\x5f\x88\xfb\x61\xa0\x88\xec\xe8\x10\x98\x73\x5a\x54\xd8\x5a\xd7\x37\x9f\x56\x4a\x75\x3d\xee\xc8\xc9\x20\x09\xad\xd6\xc0\xee\xe9\x5f\xa3\x9f\x93\x10\x85\x61\xc0\x1f\xdf\x57\xe3\xbf\xb3\x48\x3a\x14\xc9\x19\x9d\xd4\x06\x2e\xcf\xdd\x10\xc0\x37\x45\x8b\x46\x6c\xcb\x73\x35\x38\x62\x94\xb2\xd0\x8a\xe2\x6d\x7d\x3c\xb5\xf1\xe9\x60\xe9\x90\x01\x8f\x82\xc0\x45\x77\x1d\x6d\x7d\x72\x72\xce\x4d\x12\xf4\x3c\xe6\x7b\x10\x63\x91\x42\x19\x70\x6d\x0b\xba\x15\x74\xb3\x4d\x84\x41\xd4\xe9\xce\x82\xce\xae\x6b\xd7\xcb\x40\x50\xdb\xcc\x42\x14\xf1\xb3\xa8\x9a\x02\xaa\x61\x51\x57\x06\x82\x71\x07\x40\xb1\x8a\x70\x0f\x59\xd1\x5c\x53\x85\x73\x1f\x91\x69\xc0\x3a\xc7\x41\x2c\xb3\xe9\x19\xe3\x32\x19\x48\x11\x22\x67\xaa\xef\x54\x58\xc1\x06\xff\xd5\x2a\x89\xb4\x85\xd1\x6c\x40\x65\xa7\x76\xdf\x58\x58\xec\xf1\x5c\x2e\x28\x03\x25\xad\x06\x6a\xaf\x37\x3d\xb7\xcc\xca\x40\x93\x08\xf7\xd6\xbb\x2a\x83\x42\xd7\x7d\xd1\x5f\x06\x5a\x26\x06\xba\x59\x65\xb5\x8c\xb7\xe7\x63\xcf\x82\xe9\xc6\x59\x02\xfb\x51\x14\x67\x91\x3b\x51\x99\x2b\xb7\x43\xab\xd8\xe9\x6f\x2c\x66\xfc\x44\x65\x00\x11\x45\xd4\x7c\x59\x38\x59\x87\xec\xcf\xfe\x1e\x00\xb1\xd8\xb3\x9b\xe5\xcf\x2f\x12\x2f\x19\x80\x30\x18\xe1\xd5\x4d\x79\xda\x97\xd5\xbe\x82\xfa\x7c\x84\x7d\x97\x19\x75\xbb\x81\x0c\x0c\x25\x48\x3c\x59\xbe\x8a\xea\x00\x8f\x30\xf0\x56\x94\x81\x49\x6c\x9b\xeb\x54\x95\xbf\xc6\xb5\x3c\x3e\xe8\xac\xc8\xc0\x08\xdb\x65\x72\x21\xc8\x57\x11\x88\xff\x84\x0a\x11\x1f\x6a\x7d\xbc\x96\xaf\x6d\xce\x37\xb5\xff\x95\x61\x90\x98\xc4\xca\x6b\x94\x15\xbc\xa0\x30\xd6\xc8\x0b\xe8\x5a\x94\x33\x8c\x77\x65\x18\xf6\x2a\x8f\xcf\x56\xf6\x6c\x7b\x3e\xde\x7c\x8e\x88\x10\xe3\xc9\x13\x86\x3c\x45\xf9\x22\x5b\xb0\x5e\x2f\x9f\xc2\x61\xba\x21\xc3\xc8\x05\x64\x4a\x14\x37\xe7\xcf\x19\xc3\x33\x19\x92\xc0\x1a\xcd\xd7\xe0\xc4\x31\x2e\x32\xbf\xe1\x23\x0b\x49\x28\x91\x2a\xba\xaf\x4f\x79\xd6\x4c\xcf\xc5\x94\xdf\x05\x6c\xa1\x1a\xaf\xfd\xe2\x1b\x13\xca\x5c\x91\xfe\x2e\xab\xea\xe6\xa6\xac\xaa\xf2\xa3\x37\x1e\x98\x7d\x4f\xc2\x58\xd9\x8a\xb9\x25\x0f\xdf\x97\xea\xad\x6f\xaa\x4d\xb5\xb2\xfe\xaa\x9d\x3f\x62\xd9\xbb\xf3\x33\x46\x55\x4f\xf3\xc0\x7a\xf9\x33\x54\xc8\xc0\x99\xdf\xf3\x42\xc6\x19\x42\xa8\x9c\xeb\xc0\xaa\x71\xd2\xbe\xdd\x7b\x10\x26\x34\xa5\x66\x00\x5a\x1a\xf5\xf2\xe6\xaf\x66\xc2\xfd\x97\x21\x0f\x81\xba\x90\xfb\xa9\xdf\x54\xfc\xc1\x14\xb0\x4e\xb2\x7a\xd9\x0c\x45\x34\x65\xc8\x4d\x4a\x23\xb7\xc9\x07\x61\xff\x57\x83\xce\xd6\x03\xb5\xb7\xf6\x02\x46\xff\xb8\xa1\x29\x15\x89\xed\xfd\x67\xb9\xf6\x8e\x46\x93\x07\x99\x1a\x26\x48\x87\x40\xd8\x20\xb4\x60\x92\xc5\xc9\x50\x24\x02\xaf\xdf\x22\x45\xbd\xad\x83\xbf\x22\xc9\x2c\x8e\x34\x2b\xb2\x66\x25\xd4\xeb\xf3\xcb\xb6\x9b\xbc\x2a\xa4\xd8\x11\xb4\xa8\x8f\xbb\xb2\x9a\x64\x9a\x32\x54\x4c\xf8\x92\xea\x4b\x56\x34\xa8\x02\x4c\xba\x83\x4a\xc5\x2e\x7a\xbe\xdd\xee\x7a\xbf\x07\x19\x6a\x26\x30\xfe\xdf\x3f\xdf\xbf\xec\x9e\x46\xd7\xa3\x53\x6a\xfc\x0c\x2e\x3f\x26\xbf\x57\x8b\x50\x0c\xcc\x2b\x5e\x47\xe5\xcd\x8b\x6d\x2a\x04\xaa\x9d\x21\xd2\x7f\x40\x35\x0f\xa2\xf8\x9c\x94\xa2\x65\x08\x86\xa3\xf8\x66\x17\xc6\xe9\x1b\xcb\x23\x9f\x7f\x07\x4c\x64\xb0\x4d\x75\xaa\x60\xf7\xdd\x95\x43\x64\x14\x38\x11\x6b\x8b\xbf\x2e\x34\xb2\x4f\xed\xaa\xd1\x2f\xa0\x51\x40\x43\x63\x2b\x36\x47\x5b\xc6\xab\x9d\xee\xc1\xb8\x70\x22\xa3\x80\x27\x58\xc3\xd6\x90\xc3\x41\x34\xbd\x62\xd7\x5f\xa1\x64\xdc\xe7\xa3\x30\x42\x9e\x93\x29\x2b\x99\xe9\xdb\xac\x02\xd5\xdc\x82\xf4\x4d\x3a\x19\x11\x65\x91\xb5\x0b\x05\x07\xb7\x28\xf9\x43\x94\x5b\xc7\x6c\x1f\xc1\x4f\xcd\xa8\xfc\x30\x1d\x60\x5f\xe3\xf9\x69\x3b\xe8\x59\xc8\x88\x19\x81\x2b\x0b\xfa\xff\x6c\x1b\x38\xf9\x99\x1f\x25\x51\x12\x7b\x5b\x83\xe7\x73\x17\xb7\x45\x89\xe2\x8e\xf1\x8a\xf1\xbf\xa3\x20\xe2\xb2\xe4\xd8\x9b\x3d\xaa\x10\x47\x63\x58\xd1\x88\x37\xb8\xb9\xc0\xa5\xb6\xc7\x2d\x69\x1d\x57\x8d\xda\x56\xbf\xba\x63\x90\x58\x82\x96\x29\x2b\xa4\x5b\x5c\xae\x8c\x11\xa7\x29\x4a\xbd\x40\xad\xc4\x09\xae\x8b\x32\xcb\x88\xa7\x1c\xab\x07\x0f\xa5\x37\xb2\xf4\xdf\x93\xea\x04\x0b\x9f\x1f\x90\x0d\x69\x4d\x32\x12\x3c\x41\x5c\x51\x51\x36\xeb\xa2\x2f\xb4\x8f\x97\x9b\x48\x28\xc0\xc9\x94\x63\xa3\x66\xaa\x62\xe7\x07\x01\x4f\xd3\xee\xc5\x7f\x28\xf5\x39\x87\x0b\xcc\x5a\x3b\x2c\x65\xce\xb9\x68\xae\x71\xed\x46\x49\xcd\x03\x8b\x97\xac\xcf\xb0\x68\xda\x30\xfe\xeb\x09\x26\xc1\xa6\xef\xbe\x90\x50\x81\x5e\x34\x36\xfe\xb3\x6a\xcf\xe3\x8b\x95\x86\x60\x90\x71\x73\xff\xe0\x6f\x85\x8e\x18\xaa\x91\x3e\x7d\x3c\x61\x8f\x75\x74\x03\x35\xb5\xb0\xf7\x1a\x9a\xc5\x78\x2d\x8b\x74\x4a\x90\x6f\x9b\x97\x42\x8f\x25\x35\xae\x65\xb5\xb3\xef\x71\xa4\xa5\xcd\x24\xb0\x0b\xee\x54\x49\xfb\xb0\x7f\xb4\xe1\x46\x10\x07\x48\x55\xbb\x5f\xff\x6b\x61\xaf\xf3\xb2\x01\xcd\x27\x77\xc8\x84\x21\x06\xe9\x75\xe1\x1b\x23\xb9\x2f\x52\x4b\x12\x44\x22\x64\x7e\x59\x1d\x59\xe4\x4b\x12\x0a\xa9\x45\x9f\xd8\xde\x42\x23\xb2\x7c\x32\x4b\x49\xa8\x28\x56\x08\x37\xab\xed\x6a\xf3\xfb\xea\xd6\xb3\x35\x9e\x9e\x57\x96\x65\xba\xb8\xdf\xaf\xfe\x78\x5e\x3d\x6e\x57\x5b\x7f\xe2\x88\x87\x28\x7e\xf0\xde\x3e\xa0\x5d\x79\x03\xdb\x4e\xd3\x5e\x12\x12\xd2\x44\x8c\xe5\x5e\xbb\xd0\x75\x86\x65\x28\x09\x11\x31\x8a\xaa\xb4\x33\x00\xd1\x62\x3e\x96\xf5\xc7\x75\x8c\x98\x8f\x12\xfb\x03\xd7\x32\xea\xd9\x37\x8b\xc4\x4c\x60\x3c\xd4\xae\x14\x0f\xe5\x3b\x3a\xda\xef\xaa\x73\xdd\x5d\x6d\xec\x0c\x35\x6b\x68\x50\x21\xe7\x4a\x3d\x6a\xfc\xc8\x49\x9c\x08\x01\x4e\xc3\x3d\x83\xf7\x61\x27\x5c\x12\x1a\x0b\xa4\xf8\xbf\xd5\x6a\x5d\xfc\x85\x86\xf5\x70\x72\x10\x9a\x24\xd4\x81\x79\xee\xe1\x20\xd4\xe7\xe3\xdd\x6e\x36\x7d\x20\xd4\x50\x1f\x9a\xb9\xba\x47\xfe\xb9\x39\x5b\x17\xb2\x5e\x53\x4a\x12\x16\xa4\x78\xeb\x46\xde\x27\xc8\x14\x75\x89\x56\x3d\x27\x60\xd4\xdf\x3e\x96\x1a\x31\x90\x12\x69\x97\x91\x7b\xa4\x73\x4c\xae\x87\x29\x89\xe2\x25\xab\xe6\x15\xda\xb1\x45\x1b\x30\x5b\x37\xeb\xf1\xc0\x24\x10\xde\x09\xfe\xb9\x82\xf7\xac\x3c\xd7\x8f\x1d\x0f\xc1\x8f\x51\x12\x0b\x07\xbf\x3f\x2d\x47\xdb\x39\xe1\x91\x45\x0f\x62\x19\xb7\x68\x9c\x51\xfd\xd7\x31\x3f\xe1\xd4\x20\x2a\x57\x9e\x3f\x9f\x8e\x70\x10\xab\xc3\xa1\x3b\x5f\x62\xdd\x0b\x84\xd6\xbb\xd2\x79\x2b\x54\x16\x65\x28\xb2\xab\x30\x52\xf7\xe1\x34\xd4\xf8\x56\xa2\x8a\x13\xa8\x4c\x74\xaf\x64\x4a\x24\x0a\xd5\xc0\x11\xaa\x03\x14\xea\xd3\x2b\x07\xf8\xe3\xb1\x56\x8e\x5e\xfc\x76\x83\x42\xe5\xc7\xe6\xda\x03\x48\x13\x8d\x62\xe8\x4f\xe7\xb1\x37\xd1\xf8\xae\xa6\xc6\xca\x69\x61\x1b\xb1\xcb\xc2\x89\xe0\xd6\xdb\x48\xe3\xae\xdd\x91\x48\xe6\xe2\xc4\x51\xb8\x48\x44\x1a\x62\x64\xd9\xde\x98\x0c\xaa\x7a\x58\xa8\x9c\x23\xbd\x4a\x22\x84\x09\x5c\x25\x7e\x53\xdb\x88\x64\x7e\xe6\x4a\x9a\x60\x79\xf3\x59\x7c\x3a\xe5\x05\x7f\xb5\x2a\x89\x3c\xcc\xda\x7d\x14\x8d\xa6\xba\xc3\xc2\xfa\x56\x58\x00\xf2\xcd\xe0\x7e\x6a\xc2\x34\x5c\x74\xd8\x27\xcb\x5c\xbb\x2d\x75\x45\xf7\x0d\x1c\xda\x81\x65\xb5\x85\xea\xbd\xab\x78\x4b\x02\x61\x80\x25\xd2\xe7\xcd\xaa\x0d\x44\x86\x24\x29\x49\x20\xb2\x4b\xf7\x21\x33\xcd\xa6\x54\x6f\xf3\x49\x1c\x81\x24\x88\x7b\xbf\xc7\x81\xfd\x97\x3f\xce\x95\x6d\x46\xd5\xab\xe6\xf5\x59\x7c\xf6\xa0\x02\x49\x40\x27\x28\xc6\x7b\xec\x2d\xf5\xfd\x11\xa3\xad\xdd\x75\x2e\xb2\xa3\x55\x8f\x9a\x9c\xd7\x44\x46\x77\x4c\xc1\x85\xd7\xb7\x9e\xc1\x66\x48\x62\xb8\x60\x89\x9f\xf7\xdb\xcf\x42\xdd\x4f\x79\x89\x92\x18\x6d\xc9\xb8\xbe\xef\x85\xf2\x03\xfe\x6a\x8c\x49\xfd\xf2\x73\x57\x56\xa0\x44\xdd\x8c\x2c\xc5\xfe\xe7\x02\x58\x26\xe3\x80\xd8\x40\x32\x17\xb5\x15\xe8\xde\x9b\xe4\x87\xa8\x5f\xf7\x6e\xec\x37\x3f\x0e\x80\x5b\x2b\xa9\x3c\x5f\x54\xb6\x30\x30\x40\x46\xc9\x38\x0c\x8d\xe2\x5d\xb1\x75\xc0\x61\x91\x71\x48\x74\xe4\x92\x84\xfb\xb3\x47\xf3\xc9\x38\x8c\x13\xec\x73\xbc\x8a\xfa\x36\xab\x55\x5e\xd6\xe7\x6a\x60\x8d\x37\x9a\x28\x71\xa8\xec\x3c\xab\xd1\xc9\xa8\x6a\xea\x45\xf3\xb2\x5b\x5e\x0c\x0a\x71\x51\xf1\x6a\xa6\xb7\x25\xd4\x8f\x65\xf3\x20\x1a\xd5\xe7\x97\xa3\x68\x23\x8e\x98\xc6\xe4\xe0\xfe\xe9\xfb\x1e\x51\xa4\x77\x22\xcb\x87\xe9\xee\xe8\xfe\xc7\x91\xb4\xfd\x3d\x5f\xf3\xda\x8a\x1c\xea\x29\x0e\x61\x7c\x51\x91\x49\x83\xd8\xc2\x6a\xef\x2a\x80\x3f\xb1\xd4\x9a\x8d\xa4\x33\xc6\x1f\x20\x89\x0e\x94\x2b\xed\x89\x0a\xee\xdb\xc7\x28\xf2\x5c\x8b\x46\x0c\x17\xe4\x38\x16\x14\x2c\x4b\xa5\xd0\x39\x6c\xb3\xe2\x90\xc3\xba\x81\x0b\x35\xd5\x2f\x81\xf5\x32\x8e\x4d\x8c\xfe\xff\x28\xc2\xe4\x13\xbb\x98\x2a\x82\xca\xee\xa2\xc6\x86\xf6\xa5\x7e\xa5\x8c\x59\xcc\xa4\xf1\xc0\x2d\x03\x95\xc8\xeb\x87\xac\xb0\xf9\xe3\x08\x0a\xd7\x8d\x4f\x30\x52\xed\xa8\x4c\x36\x1d\xb8\x72\x17\x18\x07\xed\x76\x95\x1f\xf8\x03\xab\x5d\x79\x01\xbd\x77\x63\x13\x66\xc5\x3e\x34\xbc\xdb\x37\x6b\xad\x4a\x9f\x95\xc4\x49\xc2\x08\x19\x6a\x97\x38\x62\xca\x45\x70\xfe\xef\xff\xfd\x9f\xd1\x42\x3a\x2f\x14\x28\xe3\x44\x4b\xb4\xa5\xf7\xea\x9e\x4e\xca\x7b\x12\xbf\xc7\x3c\xb2\xc5\x3d\x54\xcd\x2b\x0a\xa8\x5e\xaa\x7c\x72\x47\x52\xcd\x51\x31\xf6\x3f\x6d\x84\x93\x9f\xe5\xe4\x0c\x22\x0a\xf0\x19\x1c\xb3\x62\x1c\x7b\xc5\x22\x25\xb8\x28\x6f\xa1\x39\x9f\xee\xce\x35\x08\x5f\xac\xbb\x0e\x9c\x8c\xae\x9b\x31\xbb\xb3\xca\x50\x19\xbb\x06\xae\x97\x4f\x36\x71\xf5\x5f\x28\xa9\x97\x3e\x2c\xcb\x1a\x16\xfe\xcf\x2a\x4c\x85\xea\xac\x01\xe7\x6c\x9f\xff\x56\xa7\x25\x56\x54\x60\xc3\xc8\x71\xdb\xee\x06\x8b\x87\xe2\xb1\xb6\x35\xd2\x5d\x25\x34\x0c\xd6\xe5\x58\xe9\x08\x77\x98\x76\x4f\x70\x44\xac\x0e\xc0\xd0\x1e\x8d\xc1\xf4\x2a\xc8\xcf\x8b\x3f\x76\x9b\xc9\xfd\xd7\x41\x84\x41\xb6\xb5\xd6\x5b\x1c\xfa\x70\x39\xd6\x21\xc7\x12\x7d\x25\x1a\x78\x32\x88\xcc\x35\x99\xf2\xf6\xcd\xe3\xd3\x98\x38\xe2\x2e\xe9\xcb\xcc\xe7\x23\x7c\x4c\x64\x16\x26\xb7\xd9\x30\x15\xf7\xe5\xce\x79\x55\x4f\x19\x1b\xc1\xd0\x59\x09\x9b\xf6\x56\x74\x6f\x0c\xb2\xc4\x21\x42\x7a\xc7\x1a\x23\xce\x79\xbb\x34\xaa\x37\x6c\x9d\xb8\x31\x34\x20\x02\xe3\xa1\xfb\xf2\xb0\x39\x0e\xab\x1e\xfe\xb8\xb0\xf1\x92\x2d\xb7\xcc\xda\x97\x4a\x1a\x26\x21\x22\x40\x6d\x3a\xfe\x5b\x96\xe7\x70\xa5\x58\x4a\xc3\x84\x61\x64\x7f\xcc\x0a\xab\x18\xff\x64\x4c\x1f\xfb\xd0\x28\x90\xcc\xc2\x0d\x9a\x57\x47\x90\x59\x34\x3f\xb2\xa6\xbe\x9f\x36\x00\x25\x8d\x84\xd4\xd0\xe1\xe2\x37\x58\x95\xba\xb2\xc8\x52\x12\x5a\x93\xe9\xda\xe9\x43\xec\x85\xee\x30\xa1\x92\x12\x2e\x95\x1a\xc5\xe5\x97\x8e\x98\x92\xc6\x91\x10\x09\xea\xa8\x96\xd2\x7f\x92\x4a\x81\x30\xc1\x01\x77\x50\x52\xaa\x42\xf4\x1e\xbc\xc9\xac\xe3\xb0\x9e\xb8\xd5\x5e\x54\xa0\xdb\xe4\x75\xb0\x57\x52\x0a\x2a\xa6\x9e\x31\xf2\x06\xc5\xae\xbc\x39\x57\x45\x77\x7a\x03\x9d\x8a\x4f\x79\xae\x9a\x57\x17\x77\xcd\x69\x89\x4a\xca\x42\xab\x6b\x83\x4d\xc1\x22\x2b\x27\x0a\x7a\x92\x32\x12\xe2\x6d\x7c\xc0\x86\x84\x2d\x0f\xe0\xcf\xb9\xbd\x46\x4a\x92\x34\x09\x03\x04\xc4\xef\xad\x0d\xcc\x22\xcf\x9f\x85\x7a\x03\xbd\x81\x77\x44\x2c\x74\xc6\xb9\x63\x95\x22\x49\x79\xc0\xa2\x60\xe0\x12\x1c\x4e\xae\x96\x2b\xab\x57\x55\xd9\xa7\x39\xd3\xf4\xa0\x5c\xa5\xb1\x43\xac\x3c\xde\x88\x3c\x2f\x7d\xdb\x57\x52\xc1\xb5\xd5\x07\xcb\xde\x61\xd5\xbc\x7a\x47\xfa\x71\xeb\x92\x0a\x15\x63\x2b\x4f\xc8\xfa\xdb\xe8\x57\x09\x88\x10\xd6\xa7\xc5\x67\xf0\x2b\x9c\x7f\x3b\xa9\x0a\xbb\x5d\xcd\x1a\x2a\x6c\xe0\x64\x83\xdb\xa5\x38\x59\x86\x1c\xf4\xf4\x28\xff\xa1\x54\x80\x47\xd9\x40\xa3\xf6\x72\xf6\x51\x69\x13\x53\xd2\xd3\xa1\x7e\xbe\x96\x08\x0f\xf9\xab\x42\xfa\xdf\xda\xc6\x29\xc4\x36\x90\x13\x8e\x96\xf8\x52\x64\x4d\xfd\x74\x6e\xea\x4c\x3b\xde\xda\x40\x3b\x5e\x52\x48\x28\x6e\x62\xf0\x8e\xdd\x3d\x71\xac\xaf\x79\xd2\x4f\xb1\x40\x3e\xb9\xa0\x00\x4c\x38\x36\x86\x23\x12\x7d\x95\xf3\x53\x13\x10\x2f\xee\xb6\x29\xcf\xcd\x08\xa7\x24\xa9\x61\x0a\xa9\x97\xcf\xe4\xb6\x71\x24\xe9\xfd\xf8\x26\xb3\x50\x84\x89\x93\x43\x90\xed\xc2\xf1\xcd\xff\xdd\x10\xe4\x43\x39\xc5\xc1\xdb\x4e\x6f\x50\xb2\x88\x47\xd0\x95\xbd\xaa\x5b\x57\x6c\xf5\x47\x63\x19\x3a\x77\xb4\x4b\x9c\xbd\x1b\x42\xc3\x38\xd6\xae\xe5\xbc\xf3\x25\xf2\x5e\x42\x49\x32\x1a\x59\xa1\xa0\xef\xa8\xfd\x39\x12\x1f\x1e\x5f\x3d\xa5\x01\xba\x13\xb6\x61\xdc\x78\xc2\x32\x16\x18\xcc\x22\x56\xcd\xab\x8f\x29\xc6\xaf\x15\x63\x24\x20\xba\xa7\x1d\xcc\xfa\x96\x70\x3f\x56\x59\x09\xcc\x6e\x02\x5f\xca\xc4\x4a\x96\x44\x21\x75\x64\xa1\x87\xd5\x62\xd1\x38\x54\xf7\x85\xae\x8e\x1f\x9e\x58\x4b\x78\x6c\x06\xef\xeb\xa2\xd9\xab\xa1\x5b\xa0\x64\x89\x90\x18\xc9\x6c\x9b\x0a\xc4\xd1\x05\x23\xc3\x2a\x01\xe3\x9c\xa2\x09\xcf\xf3\xcb\xcd\xfd\x7a\xb9\xef\xea\x5a\xcf\xab\xcd\x76\xf5\xb8\x5b\x74\xa5\x76\x96\x26\x52\x7a\x8f\x9a\x36\x0f\x9f\xcd\x58\x99\x10\x14\x89\xfb\xba\xcd\x46\xcb\x13\x54\xfb\x02\x3e\xbc\xca\x80\x05\xea\x5f\x88\x21\x48\x26\x34\x0b\xa6\xf8\xa8\x9f\x59\xf3\x6a\xe3\xab\x21\x4e\x69\x76\x12\x33\x01\xb6\x41\x86\xda\xfd\x0e\x56\x6b\xaa\xf2\xb8\x2f\x8d\x41\x99\x9d\x2f\x4b\x49\x4c\xc6\x16\x39\xf6\x52\xd8\x2c\xd0\xca\x07\x3f\x8b\xcf\x51\x4f\x0e\x9f\xee\xa4\xdc\xc8\x24\xd3\x08\xe4\xbb\x5f\x3f\xfe\xe6\xef\x94\xe4\xd6\xe3\x0d\xef\x54\x05\xe2\x7c\x0d\xf8\xe3\xc7\xcb\x84\x78\xa6\xe2\x6b\x05\x98\x5a\x4c\xfb\x3d\x4c\xaa\x98\xb8\x55\xca\x4a\xa7\x2e\x94\x9a\x04\xdc\x4c\x85\x81\x25\x62\xe1\xc2\x98\x15\x87\x5e\x0f\x10\x1f\xfa\x76\x40\x79\x9e\xfc\x0e\x25\x84\x76\x8a\x09\xcf\x50\xd5\x65\x21\x06\xb3\x6f\x90\xde\x30\x20\x09\xc2\xad\x9b\xd7\xac\xd2\x3f\x01\xde\x30\x5a\x58\x17\xed\x7f\xfa\x6b\x05\x66\x21\x44\x15\xd4\xea\x0c\xfe\xa7\xcc\x7f\x73\x12\x10\x0a\xbe\x92\x61\x03\xb4\xa1\x40\xa3\x4c\x82\xd4\xea\x54\xda\xde\xf2\x12\x2d\xfc\xae\x14\x80\x92\x40\x44\x88\x8f\xde\x41\x75\x1a\xa0\x04\x92\x28\x4c\x63\xd3\x13\x3a\x6e\xb3\xf7\x6b\x67\x88\xe2\x10\x09\x60\xab\x5c\xe8\x89\x37\x81\x4c\x22\x0e\x3a\x1e\x28\x0a\x6f\xc4\xc7\x03\xf4\xbd\x6e\x37\x2a\xe6\x04\x3b\x04\x3b\x10\xc7\xe1\x45\x50\xa2\x85\xf5\x9b\x6d\x5e\xab\x2c\xef\xfe\x9c\x10\xc4\xcf\x81\x65\x4c\x4c\xda\x64\x09\x0b\x2c\xc5\xac\x7b\xee\x93\x52\xf9\xe4\xfa\x59\x44\x70\x03\x39\x89\x4f\xa4\x2c\xc2\x15\x29\x46\x99\xb0\x34\xf2\x3e\x07\x16\xa4\xf1\x5d\x1c\xa1\xbb\xeb\x2c\x05\x14\x44\x6a\xa0\x6e\x27\x65\xf9\x51\x6f\xac\x6a\xd2\x63\x69\x15\x39\x06\x11\x7f\xc2\xb4\x4e\x3c\x2d\xcd\x01\xa2\xe7\xde\xb3\x24\x21\x1a\x49\x54\x5d\xaa\x99\xe7\xdf\x66\x7f\x45\x42\x19\xb1\x5e\x59\x4e\x1f\x3c\x2b\x8b\x4e\x92\x7f\xd4\x7c\x38\x5f\x75\xae\x94\x49\xc2\x2c\x62\x73\xef\xfc\xfd\xb2\x5f\x90\x3f\x88\xd3\x69\x06\xf7\xf8\x75\x9b\xdc\x2f\xf8\x09\x8f\x62\x0b\x44\xc9\x7e\x65\xdd\xaf\xe7\x40\x54\xdc\x7b\x9b\xff\x38\xa3\x20\xf7\xb5\x94\xab\x7b\xb0\x69\xec\x3c\xbf\xb0\xf4\xb5\xcf\x5c\xf1\xdb\xaf\xdd\x49\x2a\x22\x14\xb3\xca\x45\xdd\xa0\x2e\x76\xef\x8f\xe5\x47\xe8\x38\x70\x5b\xf7\xcf\xd7\xf2\x39\x13\x97\x6a\x2d\xff\xc7\x7f\xdd\x89\x85\xd0\xc8\x2b\x5a\x3c\x3c\xbd\x3c\x7a\x1d\x8d\xfd\xdd\xd3\x66\xbf\x5d\xdd\xdf\xfb\xaf\x97\x89\xc4\xfa\x5f\x2e\x9a\xec\x7c\x1c\x03\xa1\x12\x99\x28\xdc\x1a\x7d\xe5\xbc\xcd\xa4\xba\xa9\x3d\x79\x4e\x52\x02\x0a\xd1\x29\x0f\x31\x71\x76\x37\xe3\x7b\x2f\x21\x46\xd8\xe0\x76\xf7\x8f\x39\x53\x72\x99\xa8\x80\x72\x98\x01\xe8\x8e\x7f\x9b\x52\xf6\xc2\xf6\x1e\x98\x60\x69\x59\xce\x72\xa1\xbe\xe6\x3d\xe6\x3f\x0d\x0c\x1f\x8a\x23\x60\x8e\x51\x25\xfd\x95\x18\xdf\x23\x54\x1e\x02\x35\x95\xd4\x90\x89\xa6\x86\x5b\x1d\x52\xac\x77\x87\xfc\xe8\xef\x9d\xe6\x04\x5c\xa5\xdd\x25\x90\x4f\x27\x07\x65\x1e\xff\x16\xcd\x05\x36\xe5\x57\x85\xe6\xdd\x87\xa5\x0d\xbb\xea\xcf\xda\xf2\x19\xdd\xdf\x21\x48\x83\xa8\xe7\xd7\x5c\x4a\xa1\xcb\x04\x12\x6e\x7a\x87\x3d\x6c\x04\xdb\xbc\xc4\xea\x89\x8f\x07\x9b\xc0\x9a\xef\x7b\xe2\xc8\xcd\xb9\xd0\x5d\x27\x74\xf8\xd6\xf3\x20\x10\x78\xc7\x3f\x44\xa3\x5e\x9f\x51\x85\x01\xaa\x7a\x27\xea\xb7\x2b\x8b\x30\x0f\x63\x83\xd7\x8a\x38\x1b\xdb\x0a\x76\x47\xa2\x20\xc2\x64\xf0\x1e\x0e\x22\xf7\x29\x95\xaf\x83\xf9\x31\x14\xb8\xb5\x44\x6d\x84\x7a\x45\x3e\x7d\xdf\xc7\xe6\x91\x61\x98\xea\xbc\x65\xc5\x41\x97\xc7\x3b\xb4\x94\xf0\xe0\x39\x4e\x24\xc7\xed\xdc\xd6\x0c\x5c\x49\x6a\x7c\x71\x71\x68\x70\xbf\x2a\xe0\x57\x73\x0b\x28\x16\x97\xb9\x9e\xd6\xf0\x7b\x62\xce\xf0\xe5\x94\x5e\xca\x6e\x85\x8d\xed\x99\xa8\x8f\xc7\x90\x44\x38\x25\x6d\x91\xd6\x8a\x56\xff\x3d\xc4\x01\xa7\xa1\xc5\xf4\xa2\x87\xaa\x75\x0d\x99\xbf\xa7\x94\x06\x1e\xd2\x8a\xd6\x63\x57\x4e\x27\x04\x56\x1d\x1f\xd6\x8f\xfb\xf5\xe3\xef\xab\x0e\x91\xc2\x59\x14\x60\xb5\xb8\x16\xef\x93\x42\x0b\x67\x3c\x95\xcc\x5b\xf2\xd8\xbd\xde\xa1\x2c\x3a\x2e\xa8\xd5\x30\x1b\xff\xec\x84\x9b\x24\xf4\x1a\x4f\x68\x1c\x57\x4d\x47\xa4\x31\x76\xfa\xe5\xf9\xf3\xb9\x44\x31\xa6\x71\xb9\x38\xfc\x37\x73\x26\x46\x92\x27\x4a\x09\x18\xa9\xfd\xaf\x1b\x38\xee\x3e\x4f\xd3\xab\x4d\xb4\x25\xfc\x60\xb2\xf2\xd0\xbd\x20\x9c\x07\x69\xac\xbd\x70\x8d\x43\x2f\xf6\xc7\x2c\x7f\xf1\x37\x94\x73\xee\xc3\x67\x9e\x02\x90\xd0\xbb\x57\xdd\x54\x99\x3e\x74\x13\x00\xbd\x7e\x51\x1e\xf4\xe3\x36\x13\x65\x31\xe3\x0b\x21\xb9\x48\x03\xfc\xfc\x0d\x34\xae\x66\xf1\xb7\x2a\x73\x5c\x48\x86\x17\x8b\xdb\x73\xa9\x3d\xfa\x97\xcb\x90\x88\x64\x6c\x5e\xe4\x29\x76\x92\x4b\xc2\x02\x27\x6f\xe3\x9f\xd3\x65\x2f\x83\xcb\xd8\x32\x0b\x2d\xae\x6e\xbb\xb8\x5f\x45\xdd\x09\xd2\x28\xd4\x8e\xab\x3b\x0e\x8b\xfd\x00\x4d\x13\x5f\xd1\x11\x95\xee\xc4\x15\xfc\x22\xce\x25\x08\x84\x6b\xde\xdc\x3f\x2d\x7f\x9b\x48\x33\x4b\xae\x44\x14\x26\x23\x6f\xa3\x6c\x5a\x0e\xe2\x3a\x00\x16\x78\xac\xea\x8d\x28\xde\xfa\x17\x5f\xcb\x04\x63\x96\xfd\xd8\x98\x51\x72\x0d\x31\x57\x23\x9e\xec\x6e\xb9\xd8\xfe\x98\xee\x20\x1c\x58\xa8\x1c\x60\xdb\x89\x9b\x3f\x57\xb0\x56\xe5\xe4\x12\x20\x8d\x51\x89\xa4\x67\x41\x4a\x0e\x26\xf0\xad\x5a\x6b\x7c\x99\x15\x87\xa5\x38\x09\x75\xb1\xf0\x73\x13\x31\x7c\x65\xff\x7b\xce\xd4\x1b\x02\x96\xda\x55\xb6\x80\xfc\x2a\x96\xef\xda\xff\x0f\x9c\x43\xfc\xb9\x89\x4d\x47\xde\x2a\x81\xeb\x91\x1a\xdc\x1e\x43\x2d\xc0\x08\xfb\x65\xdd\x1f\x19\x43\xce\x3d\x2e\xce\xa0\x5f\x36\xf7\x33\x82\xa4\x92\x1b\x15\x99\x60\x20\x7c\x73\xe1\xe5\xd3\x8d\x63\xa8\x3a\x6c\x33\x10\x04\x15\x35\x13\x62\xa5\x4c\x83\x40\xe1\x52\x22\x0a\xf4\xb0\x75\x15\x29\x77\x30\x8a\x25\x6e\xf3\x36\x1c\xc6\x18\xd6\x08\x35\x95\x1f\xf4\x83\x99\x55\xda\xe9\x7c\xb8\x64\x1a\xa5\xd6\x8f\xf8\x74\xae\x5f\xd7\x45\x83\xe6\x34\xdd\x8d\x1d\x3e\x87\x34\x52\x80\xa8\xe7\x9f\x4f\xde\x70\x40\xa6\x44\x58\x63\x77\xd4\x2a\x52\x6f\x9d\x6a\xaf\x4c\x89\x61\x4c\xfb\x9e\x22\x68\xef\xa0\x30\xbe\x9e\x38\x8c\x71\x11\xca\x1a\x38\x0e\xfc\x1d\xba\xa3\xa9\x73\x8d\xcf\xf3\x36\x39\xc3\x2c\xb3\x0b\xe7\xd2\x38\x0e\x47\xde\xfb\xab\x01\xfa\x72\x76\x4d\x4f\xe3\xd4\x60\x85\x1b\x13\x23\xb7\x19\x0e\x48\x99\x32\xa5\x24\xc5\x32\x72\x87\xb1\xf3\x81\x84\xaf\x98\xcf\xb6\xd3\x52\x4a\x35\x5a\x0c\x7b\x29\x7f\xe3\x51\xb8\x7c\xae\xb4\x91\xb2\x48\x59\x23\x5f\x54\x49\xb4\xa5\x5c\x35\xa9\x95\xa4\x8c\xd8\x56\xf6\xe2\x03\x50\xc4\x64\xb0\x8a\xa6\x8c\x87\xcc\x42\xdf\xd0\x6d\xe2\xae\xea\x95\x5b\xae\xba\xd8\x8e\xaf\x98\xc9\x08\x79\x95\x96\x2b\x8d\xca\xae\xf3\xb7\x2c\x89\x23\xc4\x78\xad\x9a\xd7\x5d\xf9\x52\x6b\x8f\xcb\xfa\x72\xb9\x4d\x79\xa8\x11\xf7\x72\x12\x96\xc2\xdf\x3b\xf4\xde\x64\x13\xcd\x65\x99\xf2\x44\x21\x96\xd9\xc3\x5d\x56\xbf\xac\x74\xcc\x84\xca\x3e\xfe\x01\x5c\x51\x9f\xa1\x7a\xe0\xd9\xf2\x5c\xbd\xc3\x78\xe7\xfc\x9f\xd9\x89\xcc\x95\xc6\xea\xbd\x13\x2d\xe9\x7c\xfa\x86\xbf\xc9\x3f\x2b\x6e\x98\x50\x63\x09\x9c\x7a\xba\x0e\xa6\x69\x10\xe0\x6b\x75\xae\xa1\xda\x94\x79\x7e\x3b\xe5\x62\xcb\x34\xa5\xb6\x2a\x7f\x93\xa1\x5c\xd9\x50\x12\x63\x32\x90\x6b\xfc\x42\x7b\x71\x0f\x4b\x1f\xca\xa5\x22\x0d\x45\x3c\x51\xb7\x9a\x7f\x66\x32\x90\xb8\xa8\xfd\x56\x9d\x5f\x4d\x33\x02\xfb\xa6\xd2\xd8\x4e\xc0\xbe\xcc\x6d\x4c\x5b\x3f\x4d\x18\x17\xa9\x4a\x0c\xee\xb1\x3f\xa1\x92\xd0\x4b\x65\xc8\x54\x49\x8d\x08\xe2\x93\x6d\x88\x8c\xce\xab\x00\x4c\x38\xe2\x45\xa3\xb5\xb9\x15\xf7\x1b\x54\x1a\x53\x1d\x5a\x7b\x9d\xf6\x86\x3e\x3d\xdd\x5b\x0e\x58\xc8\x47\x65\xd4\x54\xc7\x8a\x83\xaf\x08\xe9\x03\x5c\x25\x3e\xfb\xf1\x32\x02\xd3\x49\xa6\x79\x29\xd8\x6f\xd3\x41\x4a\xd8\x48\xb6\x69\xa0\xa8\xd7\x75\x7d\xee\x17\x13\x08\x99\xd0\xa3\xaa\x4a\x6f\x5e\x2b\x53\x48\x05\xae\xc0\x9e\x82\x75\x3c\x95\x45\xef\xb6\xee\x06\x99\x94\x21\x88\x58\xa0\x77\xfa\xc3\xa7\xab\x54\x8f\xe7\xad\x01\xe5\x21\xda\x98\x25\xec\xca\x36\xba\xbc\x2b\x2b\x6b\x96\x3e\x79\x37\x44\xc8\x62\xde\x0b\xae\xd8\x37\x62\xb8\x62\x89\xd0\x84\x03\x01\x9e\x9d\xf8\xe5\xe8\x79\xe2\x70\xad\x0a\x2a\xa2\x28\x40\x22\x00\x28\xa1\xbb\x25\x77\x68\x4e\x4e\xfe\xd7\x8f\x24\x26\x84\xd1\x2e\x86\x62\x15\xef\xd7\x34\x7b\xa4\x20\x91\x15\x28\x55\x22\x57\x96\xc8\xfd\x65\xb9\x5f\x90\x54\xa0\xc8\x64\x3b\xbe\x3d\xf7\xa5\x68\x90\x14\x44\x58\xec\xc9\x01\xc5\x3e\x44\xde\xd1\xae\x42\x7f\x96\x98\x29\xa4\x19\x63\x97\x7f\x5c\x95\x16\x34\x4a\xac\x4e\xe0\xdb\xf4\x40\x6c\x61\x86\x7d\x90\xb3\x6a\x57\x8b\xbb\xb2\x5a\xdd\xfc\x73\xb7\x1a\x64\xdf\x5f\xae\x75\x82\x4a\x62\x35\xd1\x6c\x4b\x0e\x37\xf0\x91\x5f\x90\x14\x14\x2c\x27\xb7\xe9\xac\xb7\xfe\x71\x86\x33\x6c\x3b\xd1\xbf\x76\x08\xa0\x40\x6a\x9b\x25\xed\xfa\x2e\x9a\x60\x81\x41\xe1\xe6\xce\x53\xfe\xf6\xf0\xeb\xf1\xd0\x1d\x85\x50\x5a\xaf\x2a\xbb\x64\x4e\x79\xda\xff\xf3\xb7\xfa\xe8\xee\x64\x49\x10\x92\xb1\x3a\x8a\xf6\xc0\xe5\x8e\xe8\x29\x05\x27\x8a\x28\x4f\xae\xc9\x8a\xc3\x77\x31\x9d\xb3\x9c\x33\x66\xdd\xc1\x6f\xb2\xf2\x88\x9a\x4a\xb6\x66\xf0\x54\xe4\x9f\x33\xad\x32\xc1\xc1\x58\x3d\x9c\x1c\x54\x53\x95\x79\x76\x78\x6d\x76\x50\x37\x45\xd7\xe7\x11\x69\x18\xa3\xe3\xd2\x33\xb4\xfb\xd0\x8c\xc0\xdc\x5c\x59\x4c\xa4\xa1\xc2\x36\x1e\x6a\xdd\x60\x59\x17\xe7\x6f\x9d\x75\x37\x30\x4d\x53\xe4\xe2\x09\xfd\xde\x46\x5c\x43\xbc\x8f\x10\x20\x53\xc7\xb1\x99\xd0\x47\xe2\xc9\xf7\xc8\x20\xf5\x10\xa0\xdf\x45\x9e\x69\xec\x44\x8d\x16\x67\x16\xff\x8d\x7f\xfc\xd9\xb8\xed\xcb\x9a\x73\x6e\xb2\x3c\x6f\x37\x67\xcf\x26\x9f\xab\x12\x0a\x25\x8d\x6b\xb4\xaa\x73\xd5\x8b\xd3\x8c\x2f\x51\x19\x8d\x0f\x05\x55\x02\x66\x52\x11\xa1\x43\x1d\x61\x2d\xbc\x2c\xb2\xa6\xac\xe6\x16\x2f\xa1\x49\x8a\xf0\xeb\xba\x11\x6f\x08\x76\xf5\xb4\x58\x0b\xb2\x18\x7f\xa3\xa6\x94\x0e\xd5\x18\xc9\xf4\x64\x29\xf0\x41\x8d\xd9\x6d\x18\xa6\xbc\x52\xe4\x10\x5a\x10\x15\xf8\xd4\xf1\xb7\x7f\xfa\x10\x54\x68\xa9\xb1\x19\xe1\x0b\x82\x8b\xba\x3e\x57\xa2\x78\x07\xd7\x8f\xb8\x7a\x3e\x23\x85\x5b\xdc\x3a\x40\x8e\x6d\xd4\x8e\x2a\xa6\x6e\xb4\x09\x63\xa4\x7d\x8e\x6b\x69\x93\x53\x9a\x24\x44\x84\x9d\x3a\xd7\x4d\xa9\x3f\x47\x3e\x16\x52\x18\x1e\xe1\x2a\xf0\x08\x1f\x1e\xd9\x35\x0b\xe3\x16\x46\x11\x24\x1a\x28\x4b\x65\x7e\x84\x8f\x61\x05\xc2\x0f\x32\xd6\xed\x6a\x10\x0e\xa0\x16\xe6\xec\x95\xc9\x20\x88\x71\x6f\x5a\x22\x44\xa4\x28\x8f\x99\x12\x16\xf0\x33\xb4\x90\x94\x32\x88\x0c\x6e\xf1\x0f\x3f\x17\xbf\x77\x7f\x93\x09\x7a\x27\x2e\xa2\xc5\xcd\x70\xcf\x97\x81\x62\xcc\x92\x6e\x7e\xc0\xaf\x2d\xfe\x82\xf1\x33\x96\x61\x48\x51\x4d\x68\x55\x55\xa5\x9d\x91\x7e\x96\xcb\x50\x1a\x9c\x6f\x0d\x88\x63\xf8\x8f\x33\x74\x35\x25\x19\xa5\x51\xd8\xa1\x78\xcb\xff\xa0\x46\xce\xb3\xf8\x2c\xcf\xcd\x68\xd5\x97\xc4\x58\x83\xce\xd2\xc5\xe8\x48\x18\x9a\x8f\xd3\xff\x3a\x13\x94\x71\xc0\xac\x83\x1d\x32\x76\xcb\x32\xbf\x2d\x8b\x49\x10\x27\xe3\x20\xc5\xdd\x0d\x2f\xf7\x66\xd0\xbc\x95\x31\x0b\x10\x9a\xf1\x65\x01\x7e\x72\x32\xc7\x99\x16\xa7\x13\x14\xda\xe9\xcd\xae\xd0\x8a\xee\xcb\x0d\x47\x52\x12\xa3\x38\x82\xb1\x92\x04\xd3\xe2\x8b\xa4\x5c\xa2\xae\xe3\x66\xf5\x37\xb5\x38\xa5\xa4\x26\x10\xd1\x80\x7c\x76\x23\xaa\x5e\xc0\x3d\x9d\xac\xb1\x5f\xfc\xe3\x4e\xc7\x88\x85\xfe\x3d\x96\xef\xc2\x5f\x15\x53\xd2\x53\xac\x6c\x99\xd0\x57\x49\x64\x42\x04\x8a\xca\x49\xd1\x59\x6f\x5a\xe9\xb4\xdb\x4a\x7c\xa0\x4b\x8a\x1f\x98\x26\x0e\xdc\xba\x56\x25\x96\xf8\xbb\x23\xca\x3a\xfd\x59\xed\x73\x7d\x5b\x5a\xa7\xe8\xd9\x9c\x5b\x26\xca\xda\x18\xfc\xfc\xb1\xde\xad\xee\xd7\x5d\xc9\x4e\x72\xc2\xa8\x19\x42\x7d\x51\xc5\xec\xfc\x39\x1f\x47\xc9\x94\x69\xe4\x7f\x39\x09\x25\x04\xa3\x4c\x19\x2b\x52\xc6\x06\x81\x44\xf7\xe5\x01\xb5\x46\xb0\xcc\xe2\x4e\x37\x1e\xc8\x52\xe4\x23\xd5\x1f\xe2\xe4\x73\xd3\xe9\x95\xb7\x49\x40\xea\x73\x6a\x7c\xe1\x27\x7b\xaf\x54\xb1\x44\x93\x3c\x94\xb1\xe9\x8b\x01\xfe\x68\x92\x7a\x2c\x9f\xf7\xc2\x6e\x43\xf3\x9e\x98\xd6\xbd\x5b\x2a\x4d\x15\xeb\x6e\xa8\x17\xc7\xf0\xcd\x89\xcb\xce\x84\x4f\x85\xa4\x6a\x43\x65\x14\x2b\xd4\xdb\x66\xea\xba\x21\x25\x84\x3c\x1c\x0a\xee\x3a\xad\xc8\xee\x11\x43\x64\xb0\x5f\xb0\xeb\x73\x7a\xa8\x2c\x6b\xb8\xbd\xc7\x16\xf4\x7f\xad\x69\x33\xbe\x15\x90\x6a\xee\x60\xe6\x77\x28\x75\x37\xb9\x99\xa0\x62\x44\x1c\xa9\x32\xd7\x76\xb7\xeb\x66\x24\x18\xdb\x91\xcc\xea\xdf\xcb\xde\xc7\x5c\x4a\x23\x83\xc8\xf5\x16\x77\xbf\xfe\x8e\x1e\x89\x94\x46\x01\x4a\x7a\xca\x4c\x3f\x15\x37\x15\x40\xfb\xca\xba\x19\xb3\x3b\x37\x65\xe5\x95\x32\xe3\xc0\x7f\x42\xdb\x26\x45\x8d\xe1\xd0\x2a\x37\x83\x4a\x82\x7f\x3e\x2a\xa0\xdc\x12\x8f\x9a\xd2\xe2\xe1\x07\x29\x96\x0a\x38\x47\xfc\x70\xdd\xd4\xca\xff\x2d\x8c\xac\xd5\x8b\x45\x97\x38\x13\xdc\xed\xce\xd3\xe1\x54\xa4\x35\xfa\xf7\xe8\x12\x6a\x3f\xfd\xb0\xad\x34\x1f\xe8\x2b\x92\x5a\x59\x8b\x0a\xac\x75\xd3\x5c\x15\x4c\x11\xc5\x29\x1d\x6c\xb1\xf7\x59\xdd\xb4\x33\x33\x9a\xc4\x02\x2a\x0e\x23\x4c\x49\xce\x85\xca\x07\x62\x69\x52\xc5\x71\x84\x41\xfa\xad\xa8\x85\xcc\xf6\x59\x39\xdc\x80\xda\xa3\x38\x9b\x1e\x16\x7f\xec\x6f\xd6\xb7\xfb\xbb\xcd\x62\xb9\xbf\x79\xda\x75\xc7\x15\xc7\x9d\xe4\x1f\xe7\xec\xcf\x7f\xb4\x01\x54\xbf\xd3\xa9\x58\x69\x54\xeb\x73\xab\xf4\x50\x71\x7d\x3c\x91\x54\xac\x19\x02\x39\xfe\xf8\xe3\x8f\x3f\x46\x5f\x4f\x03\x89\xf5\x61\x25\x0a\xfb\x9e\x3c\xc2\x2f\xe4\x42\x3d\x97\xcd\x16\x29\xcf\x7e\x60\x2a\x10\x33\x64\xfd\x29\x16\xde\x0c\xa8\x3b\x0c\x10\x0e\xd1\x1c\x7b\x68\x5e\xf7\x4d\xb9\x57\x63\x08\x9c\xe2\x71\xec\x73\xc7\x85\xd6\x4f\x85\x83\x99\x8e\xde\x5c\x25\xc2\x04\x13\x86\x0d\x14\x6d\x00\x3f\xec\x44\xfd\x15\x8e\xd6\x9f\x81\x32\xec\x07\xbd\xa2\x0a\x6e\xed\xb7\xb1\x36\x31\x6a\xdf\xc6\xf1\x8a\xa3\x44\xa2\xb1\xce\xf7\x98\x1d\x20\x47\xd9\x8e\xb3\x6f\xcc\x29\x91\xf2\xd4\x5b\xeb\xf9\xf0\xee\x01\x53\x54\xbc\xae\xb1\xea\xde\x64\x25\x51\x42\x93\x44\x0c\xf5\xa8\xcb\x8e\x57\xa5\x24\x33\x56\xef\xa5\x10\xa7\xfa\xb5\x6c\x30\xea\x16\x08\xff\x18\x5f\x9d\x54\xe0\xa4\x09\x56\xa2\xf2\xee\x88\x9e\xbb\xb9\x11\x59\x3d\x5d\xb0\x95\x4a\x25\x3e\x8c\x5d\x75\xf6\x8e\x03\x57\x6e\xd7\xe4\xb6\x69\x9a\x60\x31\x7c\x18\x02\x0c\xf5\x5a\xa5\xd2\x92\x83\x35\x4c\xa8\x4f\x25\xae\x48\x5f\x76\xd3\xa9\x37\xa3\xf7\xff\xfb\x57\x8f\x71\x76\x9b\x52\x5a\x53\x34\x54\xfe\xa8\x32\x3b\x43\xd7\xd3\x9f\x0c\xcc\x2e\xba\x12\x0e\x5d\xb1\x47\x01\xd8\x82\x55\x65\x4d\x0b\xe6\x02\x55\x65\x62\xc6\xad\x7b\x5b\xdd\x8c\xeb\x41\xca\xd0\x28\x0e\xbd\x3b\xfb\x32\xcf\x6c\xfb\xb2\x3b\x98\x74\x3c\x75\xa5\xce\x27\xdf\xb5\xe0\xfe\x38\xa3\xa9\x2b\xc6\x3c\x64\xc5\x4e\xe4\x17\x44\x0a\x1d\xa8\x18\x8b\x54\xb6\xee\xb1\xda\xfd\x70\xe7\xd6\xa1\xc3\x4c\x7c\x47\x49\x84\xe3\x54\x3c\x5a\xea\x90\x69\x44\x46\x9e\xec\xd3\x1d\x4b\x90\x4a\x1d\xd1\x10\x9f\xbf\xd0\x1a\xa7\xcc\x02\xab\x39\x5f\x12\xf6\x74\x94\x44\xc8\xea\xd8\x5b\xf7\x70\x14\x56\xcc\x07\xfe\xe1\x0f\xd0\xa6\xe5\x53\xba\x9a\x8e\x24\x71\x2e\x3a\xd6\x98\x72\x03\xaa\x3a\x67\xa8\x13\xd2\x5d\x8d\x8a\x42\x6f\x6c\x76\x93\x1d\x0e\xfd\x9c\xf1\xef\x89\x8e\x74\xec\x51\xc1\xf8\x74\x0b\x0d\xbf\x86\x77\x53\x13\x4a\x91\xf1\xb6\x7b\xb5\x05\x24\x0f\x7b\xd7\x94\x30\xe2\x3e\x79\xf3\x2c\x46\xd5\x11\x4d\x75\x88\x15\xaf\x47\xf1\x9e\x0d\x1f\xac\x66\x81\x40\x3e\xac\x3c\x7f\xb6\x71\xe2\x0c\x40\x54\xb3\x10\x10\xf2\x64\x9f\xcd\x0f\x10\x55\x73\x03\xa2\xfb\x4d\xcc\x50\xbc\x5b\x55\x9b\xe7\x4f\x14\x4d\xdb\xa3\x12\x3d\x3d\x6c\xc9\xe0\x0b\x5e\xb3\x4e\x22\x5b\x6f\xb3\xfe\x91\x16\x24\xe8\xbf\x83\xcb\x20\xb6\xc2\x7a\xeb\xe5\x6a\xbf\x7e\x5c\x6e\x56\x8b\xed\x6a\xbf\x5d\x2e\xee\x57\xdd\x18\x93\x2a\x31\x84\x51\x74\xc2\xd1\x52\xa7\x34\xb4\x3b\x17\x4e\xf7\x5d\xf9\x92\x4d\xaa\x7d\x3a\xe5\x04\xcb\xb1\xd8\x86\xdc\x42\xee\x64\x54\x67\xdf\x41\x9d\x8a\x04\x63\x8d\xfb\xf2\xf0\x08\x1f\x5d\xba\xf9\x32\xe3\x76\xe0\x3f\xa1\x6c\xc1\xa3\x86\x66\x7d\x74\x46\x39\xee\x90\x60\x1a\xaf\xed\xd4\xd5\x56\xb7\x65\xae\x47\xec\x72\x2d\x78\x2c\x5d\x9c\x85\xc2\x97\xa8\x19\x34\xd3\x50\xd5\x82\x27\x28\x43\xb9\x13\xe5\xb9\xd7\xde\xb9\x9e\x2a\x68\x49\x0c\x26\x7d\xff\x2a\xcb\xe3\x68\x62\x48\x21\x5d\x44\x60\x73\x88\xe7\xaa\xd4\xe7\x81\x85\xce\x54\xba\x62\xfe\x4e\x49\x05\x71\x3a\xc9\xca\x2f\x22\xad\x3e\x2f\xd7\x2a\x0e\xc8\x10\xb3\x64\x0b\x60\x6d\x6c\xd3\x4c\x4b\xfa\xfd\x97\xe8\x30\xc5\x22\x38\xfa\x8a\xb7\x71\xfb\x90\x90\xee\x02\xad\xe9\x47\x94\xc1\xa2\xcc\x5e\xd4\x9f\x85\xba\x90\x39\x18\x0f\x86\x34\x4d\xb9\x07\x1a\xb9\x1f\xe1\x40\x7a\xd3\xc6\xc4\xf8\x69\x40\x6a\x75\xe4\x2a\x90\xa2\x81\xfc\x3d\x5f\xa9\x36\x59\xff\xfc\xf6\x77\x53\x2f\x08\x68\x84\x9b\xf7\xa4\x55\x0c\x41\x12\x62\x47\x66\x6f\xfd\x2f\xbb\x3f\x9b\xd0\x97\xbd\xb7\xa7\xac\x78\x3a\x37\xa7\xf3\x25\xd1\x6e\x36\x4e\x80\xc0\x24\x28\xca\xfb\xb2\xbd\x5d\x39\x5b\xe6\xf1\xe4\x82\x90\x05\x58\x2f\x5a\x14\xf5\x47\x37\x7f\x21\x94\x06\x2f\x65\x07\x75\x5d\xfd\xe1\xff\x1a\x05\x0a\x9b\xc4\xd6\xf4\xc9\xcb\xa9\x4b\x88\x22\x8a\xd6\xf6\x3b\x50\xaf\x45\xa6\x44\xbe\xc9\x3a\x72\x26\x90\x30\xa1\xb6\x68\x55\x35\x07\x31\xd5\xda\x01\x42\x65\xe0\x78\x3d\xcd\xb9\xb6\xbd\xbc\x7e\xa9\x87\x58\x08\x11\x0e\xf8\x0b\x6d\x78\xf2\x03\xaa\x6c\x88\xbd\x1c\xff\xa0\x58\x0b\xd4\xaf\x7b\x10\x0d\x54\x99\x78\xae\xb2\xa3\x4f\x70\x81\xc5\x29\x12\xcd\x6f\xce\xea\x0d\x1a\x6f\x4b\x30\x37\xdb\x7d\x0d\x04\x98\x02\x74\x1b\xf5\x34\xbc\x8e\x44\xe3\x9c\xaf\x2e\x14\xa5\x80\x69\x8d\xe4\xb3\x53\x99\x75\x3e\x8e\x12\x92\x80\x62\x87\xdc\x52\x71\x16\xba\x3c\xb5\x3f\xd3\x2a\xde\xda\xd8\xc1\x0f\x24\x10\x59\xc3\x90\xd7\xb1\xf2\xe5\xff\x29\xa4\x80\x44\x59\xca\x9e\x39\xe7\x58\xa2\xbc\xb3\x5a\xe2\xfe\x72\x38\x23\xb8\xc3\x3e\x9f\xeb\x57\xd4\x36\xf2\x7f\xe7\x0c\xe5\xee\xca\x02\x9a\xec\x08\xf7\xe2\x5c\xa8\x49\x59\x0b\xb8\x96\x58\xca\xd7\xf5\xc3\x39\x9f\x5f\x4d\x41\xc4\xc2\x3b\xb1\x3f\xc9\xff\xf4\x1b\x5e\x77\x5f\x05\xb3\x9e\xf5\x37\x77\xb7\xc3\x25\x0a\x04\x4b\x1d\x8e\x7e\x2c\x5d\x3f\x7a\x83\x04\x0f\x82\x4e\xf3\xe0\xc6\x8b\x5c\x5e\x99\x10\xc2\x08\x2c\x49\x3c\x6f\x9e\x1e\x56\xbb\x1f\xab\x97\xad\xa5\xf5\xee\x77\x3f\x36\xab\xed\x8f\xa7\xfb\x5b\xff\xdd\x32\x62\x21\xf5\x3e\x77\xe7\x29\x14\x19\x24\x49\x50\x00\x06\x65\xa9\x2c\x40\x0b\x25\x3e\x47\xbb\x32\xc8\x58\xe2\x7c\xc7\x38\x63\x61\x05\xe0\x6d\xe3\xe8\xe6\x73\xeb\x62\xe1\x19\xf0\x19\x48\x13\x12\xe5\x84\x9b\x70\x9f\x1a\xb1\xe7\xff\x2a\x2f\x98\xdc\x7e\x93\x06\x68\x16\xe7\x9d\xfc\x47\xb7\xd8\x28\x89\xd9\xab\x3c\x7f\x6e\x44\x05\xab\xc3\x61\xd2\x08\x1f\xff\x6c\xa3\x23\x5b\xf5\x80\xe6\x16\x6a\xac\xb2\x83\xb6\xaa\xc2\x50\xfd\x14\xf5\xb2\xac\x2a\x18\xa9\x7b\x99\x20\xe2\xb2\x7d\xfa\x4f\x5a\xdb\x39\x3c\x7b\x95\x26\x88\x53\x69\xaf\x72\xac\x10\xe7\x6a\xf7\xf1\xff\x0c\x4f\xc9\x08\x75\xb4\xab\xef\x65\xae\xef\x60\x56\xbe\x52\x9a\xb0\x5d\xa0\xdb\x10\xff\xe9\xe1\x61\xbd\xdd\xae\x9f\x1e\xf7\xcf\xab\xcd\x72\x84\xfb\x37\x51\xc0\xb0\xbb\x8c\x72\xc7\xed\x34\x1b\x9b\x27\x4a\x13\x85\x29\x32\x99\xee\xc4\x59\xc1\x45\x35\xc3\x0f\x12\xa9\x45\xf8\xa3\x60\x40\x59\x37\x6b\x55\x76\x99\x45\xd9\xee\xe7\xd3\x34\xd2\x10\x2e\x23\x47\x35\xb5\x41\xeb\xe5\x32\xe6\x76\xb8\x19\x44\x34\x89\x26\xbb\xca\xdc\x76\xed\x22\x4a\x13\x47\x56\x9e\xd5\xba\x69\xe6\x65\xd3\xf8\x4e\xa9\x89\x53\x8e\xd8\x36\x1b\x05\x58\x2e\xe2\xf8\x97\xd1\xc4\x60\x68\x56\x8b\x1c\xa6\x71\xb5\x1f\x22\x2d\xc4\xdb\xd9\x1a\x81\xaf\xe7\x4d\x87\x99\x04\xad\x6d\xda\x49\x6d\x6e\x3b\x48\x8b\x61\x34\xc4\xc2\xdc\x3f\x6f\x7e\xfc\xb3\xfb\x5b\xc2\x95\xe3\x43\xa1\xa3\xf0\x63\xbb\x9f\x90\xdb\xc9\x19\x99\x14\x08\xa6\xd9\x0f\x89\x15\xa3\x96\xd5\x64\x96\x31\x65\x6b\xd5\x2f\xdb\xdb\xee\x9b\xc0\xd2\xfc\x4d\x55\xfe\x09\xc5\x54\x32\xc9\x30\x48\x91\xbc\x20\x94\x1a\xe3\x30\x4d\x12\x10\xe9\x5c\x44\x97\xa2\x81\x43\x59\x7d\xce\x55\x55\x4c\xc2\xac\x7e\xa4\xc9\xaa\xba\xf9\x81\xd6\x77\xdd\x29\x74\x82\xd1\x93\x3a\x57\xef\x53\x24\x98\xe1\x24\x54\x03\xe3\x65\x0f\x6d\x99\xd1\xc1\x31\x5c\x05\x69\xdc\xf3\xdf\xf4\x6c\xd3\x63\x72\x2b\xda\x80\x98\x4d\x76\xd3\x2f\xf4\xf5\xa5\x49\x25\x89\xa8\x13\x8f\x6a\x23\x37\x6f\x03\x38\xbe\x94\x54\x12\xee\x30\x66\x6b\x55\x5e\xf8\x2f\x49\x93\x6a\x40\xa8\x95\x7f\xcd\x06\x40\x7b\x23\xa8\xc6\x89\xf4\x2a\xea\xd7\xbd\x35\x7e\xdf\x37\xa5\xfb\xaf\xf9\xdd\xc5\x88\x34\x90\xc6\xa3\x33\xad\x4e\x58\xd8\x9d\xcf\xd8\xb4\xc0\x9b\x67\x8c\xc8\x68\x46\x26\x11\xf2\x21\x9b\x2f\x7a\x44\x46\x0a\x8a\xe2\x84\xd8\xae\x3a\xfa\x86\x31\x82\x11\x86\x0e\x86\xd2\x28\x9a\x32\xd9\x1b\x7a\x58\x92\xa9\x3d\xe5\xb2\xcc\xf5\xb8\xb9\x64\x14\x97\x3a\xec\xed\x47\xa0\x6e\xd6\x7a\x57\x62\xbb\xb3\xfb\xff\x2b\x3f\x58\x01\x47\x3e\xdf\xd0\x0f\x70\x72\x8f\x75\xcc\x29\xf7\xf7\x51\xcb\x71\x51\xd7\x68\x66\x65\x6c\x77\x9b\xc5\xe3\xf6\x6e\xb5\x59\xdc\x74\x49\x96\x81\x80\x38\x2f\x4e\xd4\x7d\x2b\xf3\xf9\x9e\x97\x01\x42\x2d\x35\xab\xc2\x2c\x77\x03\xaa\x7c\x87\xea\xd3\xff\xe0\x99\xe8\xd2\x40\xc2\xb1\x04\xb0\xc8\xf3\x36\x59\x9c\x75\x74\xb7\xa3\x2c\x6f\xf4\xd7\x6d\x55\x9e\x36\xc3\xf0\xd7\x80\xe0\x18\x8a\xca\x09\xfa\xca\x98\xd8\x0a\x9b\xa1\x2b\xe7\x2d\xe4\x8d\x18\xc0\x41\x8c\x89\x25\x32\xcc\x51\x9d\x25\x53\x99\xa8\x3e\x77\x1f\x83\xa3\x0a\xe5\xc5\xef\xcf\x6f\xa2\xe7\xb3\xa8\x20\x08\x6d\xf7\xe8\x60\x6d\x0a\xef\x10\x55\xe6\xe4\x05\xb8\x1b\x13\xc6\x0a\x91\x5d\xaa\xcd\x61\xca\x11\x0e\x50\x05\x21\x27\x18\xbe\xec\x3e\x00\x1c\xc1\xce\x59\x46\x7e\xfa\x21\x51\x12\x20\x64\xee\x2d\xcb\xf3\x31\x83\x56\x05\x91\x60\x88\x2b\xdf\x42\xb3\x52\x65\xfd\x59\x37\x70\x9c\x8e\x89\x19\xc1\xbd\x29\xab\x1d\xc4\xd8\xe1\x3e\xfc\x71\x1a\x46\x78\x0e\x47\x18\xb0\xd3\x76\x3e\x3b\xf9\x2a\x79\x50\x01\x8d\x25\xce\x19\x44\x15\x6f\xda\xa7\x3b\x98\xfc\x2a\xa0\x49\x8c\xb9\x45\xd7\xdd\xdc\x2c\x93\x28\xbc\x5a\x89\x1b\x3e\x72\x15\x24\x26\xf0\xae\x7e\x6e\x52\xfc\x06\x9f\xe3\x79\xa1\x02\x1e\xc4\x41\xec\x05\x84\x2d\xda\x61\x5c\x95\x56\x01\x27\x0c\xdf\x40\x8c\x04\x9f\x97\xbb\x39\x35\x2d\x3f\x34\xb6\x6a\xa1\x98\xee\xbd\x8a\xce\x51\xe9\x1a\x93\x6d\x72\x37\x38\xb5\x62\x70\xb8\xdb\x63\x59\xf2\x27\x64\xfe\x5e\x70\xce\x31\xb1\x78\x58\x3f\xae\x36\xfb\xc5\xcb\xb2\xcd\xeb\x26\x58\x60\x15\x70\x15\x20\x64\x0a\x7b\x43\x37\xe5\xc4\xb7\xa1\x5d\xcf\x6d\x7f\xc9\xef\x6c\xed\x15\xce\x5b\xcd\x5d\x14\x22\xc7\xff\xe7\xcf\xa7\xc2\xd4\x13\x9e\xd6\xa8\x0c\xfd\x60\x75\x65\xc0\x25\xfe\xf5\xba\x68\xca\x65\xc7\x37\x57\x81\x50\x52\x53\xdf\x0a\xb9\x7d\xcb\xb7\x59\xd5\xf7\x42\x66\x33\x11\x7e\xc5\x70\x66\xf4\x57\x7f\x76\xcd\x10\x3e\xae\xca\x0a\x46\x51\xb3\x0a\x24\x23\xd8\x28\x76\x84\xa3\x81\x94\xf2\xb7\xb9\x33\x49\x09\xe8\x9f\x6d\xc1\x5e\x6e\x06\xdd\x95\xd5\x85\xec\x80\x0a\x14\xd1\xc4\xcb\x04\x2c\x7a\x5d\x46\xd1\xa8\xd7\xf6\xfe\xba\xf7\xf7\x7a\xbf\x4c\x05\x0a\x9c\x71\xfa\xcb\xcd\xca\x5f\xaf\x0e\xa3\xc4\xed\xbe\x43\x95\xf4\xc1\x7a\xa9\x02\x0d\xa1\x74\x7d\x45\x9b\x00\x4c\xc8\xfb\xd3\x06\xb7\x0a\x20\x88\x70\xbb\x3d\x66\x45\x17\x4f\xf9\x43\x89\xd5\x80\x13\x1a\xb1\xa4\x78\xd1\x17\x11\x4f\x0f\x84\x72\x9f\x32\x61\x64\x6d\xa1\x87\x22\xfd\x7f\xa7\x37\xa7\x02\x93\x32\x69\xf3\x68\x8c\x80\x9e\xdb\xa4\xc7\x16\xf0\x1e\x4a\xf5\xf6\x7b\x38\xb9\xcd\x26\xb5\x02\xa3\x8e\x37\xbc\x7a\xd9\xd8\x96\xe5\xf0\x8e\x84\x61\x2c\xb1\x12\xa4\x44\xb1\x01\xa1\xd7\xa8\x12\xf6\x24\xff\x03\xaa\x99\x56\x5d\xfc\xdd\x0f\x43\xa3\x20\xea\x4f\x7c\x7d\xdf\x56\x21\xa1\x9c\x77\x42\xe9\xa2\xd2\x4b\xe1\xe0\x5d\x2a\x8c\x83\x10\xab\x7b\x4f\x3f\xdb\x17\xd4\xef\x82\x23\x3b\xe5\x76\x90\x2d\x8f\x61\x74\x77\x3c\x89\xec\x30\x55\xe7\x9b\x18\xc6\x4f\xff\x1d\xfd\xd8\x38\x4c\x50\x05\xec\xbb\x78\x1f\x6c\x31\xed\x2d\xb0\x60\x6e\x51\xd7\x53\x01\xb3\xd1\xe7\x69\x94\x72\x17\x6b\xae\x74\xd6\x58\x7f\x9a\xa9\x3a\x9d\x23\xf0\x8e\x9e\x45\x48\xa5\x55\x09\x69\x17\xd7\xa3\xcc\xa0\x68\x7e\x9c\x8f\x99\xce\x9a\x4f\x27\x1f\x88\x9a\x39\x63\x32\x9a\x0a\x59\x9a\x78\xb6\xc9\xde\x05\x34\x7b\x51\xc9\xac\xa9\xf7\x27\xdb\xf0\x9a\xbe\x5b\x21\x4b\xa5\xa0\x1e\xef\xa3\xf7\xfe\x27\x32\x65\x4d\x81\x94\xc8\xd5\x22\xab\xda\x3d\x7d\x26\x64\x51\x61\x92\x50\xab\x85\x58\x1e\x9c\x64\xfe\xd0\x0e\x76\x3c\x36\x25\x54\xb9\xab\xfb\x91\xd5\x4d\x59\x65\xea\xd2\x4f\x49\x85\x29\xd3\x89\x6d\x89\x34\xe7\xaa\x70\x96\x34\x58\x6a\xb9\x85\xda\x72\x89\xc6\x1f\x90\x3c\x41\x66\xbe\xad\x4d\x4e\x7e\x9f\x54\x1c\xe9\x05\xb6\x72\xf6\x2c\x3e\xe1\x62\x84\x76\x71\xd5\xfa\x61\xf5\xf4\x32\x94\x85\x51\xa1\x8a\x6c\x9d\xef\x5c\x43\xd5\x06\xcd\xee\xcf\x3a\xa1\xa1\xad\x28\xe9\xb1\xf0\xb5\x0a\x0d\x13\xc4\x74\x91\x98\x35\x09\x1c\x8a\x5a\x8f\x2e\x3d\x0a\x24\x24\xee\x96\x38\x68\xca\x15\x9b\xaa\xf1\xf4\x88\x22\x16\x62\x81\x2a\xf3\xb1\xea\xef\x65\x73\xc5\x6c\x59\x45\x91\x50\x96\xab\x8b\xfa\x85\xb7\xf0\x5e\xe6\x67\x25\xca\x3e\xdb\x57\x51\x24\x43\x6c\x16\xf8\xe8\x7e\xb7\x59\x38\xe4\x97\x8a\x22\x93\x60\x29\xfa\xcf\xd7\xf2\xac\xc5\x67\xf6\xf7\xd0\x2e\x2a\x22\x91\xdd\xba\xac\xd2\x99\xef\xf2\x75\x07\x39\x76\x5c\xbe\xff\x6b\xfb\xb7\xcf\x47\x09\xb2\xa8\xb3\xba\x53\xe8\x1c\x3f\xc9\x88\x50\xeb\x20\x8c\x13\xec\x54\x37\x50\x1d\x5d\xc7\xe7\xbf\xdd\xf7\x72\x40\x6d\xf7\x76\x4f\x3e\x5f\x48\x8d\xfb\x41\x10\xa1\x5a\x40\xaf\x7e\x79\x77\x85\x27\xae\xa2\x38\x8d\x7d\x0e\xe7\xa1\x29\xfe\x88\x09\x10\x35\x2a\x4e\xa7\xfc\xf3\xae\xac\x7a\xe7\x99\x76\x4f\xf8\x5b\xc1\xdc\xfc\x6e\x7d\x01\x54\x50\x11\x25\x24\xd4\x9d\x9f\x54\x76\x3c\x1f\x1f\xcb\xde\x7b\x7a\xee\xcd\x8d\xa8\xb1\x8a\x53\x4d\x79\x3a\x9f\x9c\x56\xff\x78\x44\x02\xd6\x7b\xdf\x3e\x40\x5c\x00\xc7\xf7\x29\x31\x04\x51\xd1\xf7\x6d\x12\xe1\x7f\x36\x97\x29\x76\xa3\xdb\xf5\xa7\xee\x7a\x3d\x2a\x4a\x99\xb4\xce\xea\xd5\xe7\x09\x7d\x35\x6a\x17\x93\x4c\x82\xe3\x48\x28\xdb\x96\xac\xcb\x7a\x88\x43\xc0\x03\x88\xd9\xb7\xb0\xa4\x8e\x8b\xaf\x22\x19\x02\xea\x53\xa0\xbe\x9a\xdb\xec\x6c\x60\xdd\x67\xa9\x2a\x92\x52\x87\xdc\x1a\xcd\x59\x98\x37\x1c\x4f\x79\x07\x82\x50\x91\x66\x84\xb2\x01\xf3\x3c\x6b\x3e\x1f\x07\xd6\x13\x6e\x14\x44\x09\xbe\x29\xfe\xaa\x97\xed\x9a\x6e\xb7\xd6\xc9\xdd\x31\x91\x49\x8d\xc3\x6e\xbc\x43\xb5\x28\xf4\x16\xad\x38\x2a\x47\x75\x1c\x57\x80\xfc\x87\x08\x37\x96\xd2\xe1\x78\x3a\xae\xda\xaa\x48\x40\xe3\xd4\x95\x56\xf6\x95\x28\x34\xaa\x57\xcc\x4f\x4a\x12\x06\xa1\x76\xaa\x0c\x3d\x6e\x6d\x74\x75\x24\x8c\x22\x2c\x2e\xdd\x9c\x3f\x71\xde\x66\xc5\x61\x5b\xa0\xb4\xac\x1f\x60\x92\xd0\x71\xab\x6e\xfa\x04\x6c\x72\x96\x28\x34\x08\x5a\x84\x5f\xa0\xce\x0d\xdc\x97\x4d\xd3\x41\x0c\x15\x89\x92\x18\x7f\xcc\x73\x2e\x3e\xff\x08\x03\xff\x67\xc2\x59\x10\x5e\xfa\x1d\x63\x0d\xa0\xfe\x1a\x71\x3c\xdd\xbd\x07\xc9\x41\x7b\xda\x38\x1e\x27\x33\x51\xf0\x95\xeb\x9f\x22\x34\xd0\x98\x7a\xec\x36\xf7\xc3\x99\x46\xa8\x4c\x50\xc0\xec\xf7\xa7\xfb\x97\x07\xa7\x9b\xb8\x5f\x3e\x3d\xde\xae\x07\xb9\x00\xa1\x90\x48\xd1\x99\x37\xdc\xb9\x2a\xda\x00\xdc\xac\x08\x23\x80\x7b\xcb\x2d\x88\xe6\xd5\x92\x7a\xf7\xef\xfe\x20\x37\x1c\x51\x37\x0e\xd2\xde\x4e\xeb\x81\x65\x86\x22\x29\x0f\x12\xea\x88\x59\xcb\x3c\x3b\x22\x27\x22\x2b\xea\xc5\x41\x64\x45\xdd\x5c\xc2\x44\x14\x49\x25\xc5\xe4\x17\x2b\xa2\x6d\xca\xda\x57\x2e\x15\x49\x95\x75\x0e\x94\xe7\xcf\x97\x22\xeb\x3d\x22\x50\x81\x00\xeb\xd9\x33\x2a\xbf\xa3\xff\x9a\x04\x76\x44\x10\x86\x26\x8b\xe8\x9d\x77\xc4\x8e\xba\x1d\x32\x5a\xb9\x89\xa0\x89\x87\xa3\x79\xd3\xa1\x11\xfb\xc8\x55\x0b\xe6\x9a\x75\x8a\x08\xce\xd1\xf3\x5c\x59\x0d\xf5\x3e\xf8\xf5\xc7\x75\xec\xd9\x99\x37\x8b\xed\x95\x93\xc8\x20\xb5\xca\xa1\x28\xf7\x3f\x8a\x53\x67\xeb\x6c\x8a\x48\x62\x1b\xe4\xf0\xeb\x24\xd0\x8d\xc9\x43\xaf\xfd\x74\x93\xed\x2b\xe2\xeb\x83\x6e\x77\x5b\x15\xfa\x56\x34\x10\xfa\x3b\xae\x02\x1a\xd8\xd6\xff\x80\x84\xdd\xfe\xd9\x7a\xa7\xd7\xd0\xac\xf0\xc5\x99\x50\xe8\x15\x51\x51\x4a\x61\xd0\xe5\x5d\x17\x75\x93\x35\x16\xec\x52\xd7\xd0\x7c\xfb\x32\x98\xf5\x27\x91\x06\x2b\x24\x96\x04\x0e\x75\x13\x46\xa4\xbb\x04\x43\xb5\x7b\xbb\x57\x56\x5f\xf2\x59\xa8\x37\x0c\xc7\xbc\xde\xf1\xb8\xa3\xe0\x3e\xa7\x63\x83\x58\x7f\xc7\xc0\x9f\xd7\xb2\xfc\x92\xca\xa1\x88\x96\xa1\xe5\x2c\xda\x79\xbf\x39\xe7\x03\x61\x8a\x6e\x4c\x8a\xb7\xc8\x09\x77\xdc\xe5\x68\x39\x3c\xbf\xda\x69\x08\x92\x91\x3b\x6b\xfb\x96\xa0\x58\xd6\x78\x9c\x89\xac\xb4\x81\x06\x91\xd7\x8f\xe8\x95\xe7\x6f\x87\x49\x18\xba\x49\x67\xb5\xab\xc4\xfc\x58\x2f\xe7\x8a\xe6\x8a\x18\x88\x90\x15\xff\x5d\x64\x79\xde\x26\x28\x55\xf9\xa1\x07\x91\x4d\x1c\x48\x81\xd2\x5a\xab\x97\xcd\x13\xd2\x79\xdd\xdf\x43\x1d\xa2\x52\xd9\x6f\xcf\xbb\xd1\x62\x13\x87\x10\x69\x07\xc4\x5e\xe9\xf3\x10\x28\xae\xe2\x88\xd8\x37\x47\x68\xfd\x5c\x95\xc7\x72\x59\x6a\x98\x6c\x1c\xe3\xe0\xc0\x7f\x8e\x85\x96\x2a\x89\xc9\xf5\xf7\xcc\x34\xe3\x4c\x21\x8e\xd2\xd0\x82\xca\xab\xcf\x4d\x99\xe7\xf8\x5e\x7d\xf9\xd4\xe2\x28\xa5\x28\xcc\x72\xb4\xf1\x45\x9f\x98\xc5\x91\x16\xa8\x94\xf6\x91\x15\xa8\x3b\x33\x49\x03\xdd\x28\x42\x79\x12\x79\x9a\x37\x06\x65\xa6\x82\xfa\xf5\xbe\x54\x6f\x83\x48\x34\x26\x3c\x8c\x87\x06\x1d\x8b\x7a\x9b\x8b\xf7\x4e\x63\xdd\x8f\x92\x31\x56\xc1\xdb\x55\xcc\x3d\xa7\x45\x8d\x95\x91\x71\x1b\x61\xfc\x21\x6d\x5b\x5a\xab\x42\xdb\xc6\xdc\xe0\x6b\xe3\x28\xc1\x10\xe2\xe4\x79\x6d\xcd\x15\x44\xb9\x8a\x63\x1e\x61\x41\x74\x7b\x3b\x7a\x8c\xb1\x14\x08\x4c\xeb\xd9\x47\x37\xa2\x78\x5b\x9e\x7d\x5c\x13\x33\x4a\x31\x73\xbe\x2d\xa7\x68\xa9\xf6\x18\x78\xdf\xdc\x5d\x79\x7a\xea\xab\x91\x31\x4b\x34\x9a\x08\xff\x78\xba\xbd\xaf\xda\x49\xfd\x33\x2b\x26\x1f\x4e\x58\x14\xcb\x9e\xe2\xe1\x0a\x43\xf3\xe8\x66\x15\xf3\x40\xb9\xd6\x51\x9b\xa0\xcc\x80\xa4\x55\xcc\x9d\x9b\x65\x0d\x85\xb6\xfd\x15\x7f\x35\x3c\x4e\x90\xdf\x22\xf2\xf2\x55\xf4\x7f\x14\x18\xd9\x59\x6e\xf4\xf6\x7c\x82\xea\xb6\x12\x87\xa1\x1b\xb7\x8a\x39\xe7\x58\x17\x79\xf0\xfa\x6f\x3e\xd0\x88\xd3\x80\x23\x98\xfa\x01\x72\x24\xae\x62\xa7\x79\xbf\xaa\x54\x14\x91\xd1\x1d\x4e\x65\x88\x71\x43\x9b\xda\x3a\x28\x22\x5c\x50\xb1\xbe\x6a\xa9\xab\x38\xd5\x61\x6a\x3a\x7c\x2e\x6e\xd5\x3e\xcf\x89\x85\x8e\xf1\x95\x70\xb4\x92\x91\x04\x87\x8a\x65\xa0\xbd\x4d\xe5\x43\x56\x8c\xf1\xdc\xfd\xf9\x65\x68\x4c\xe2\x5b\x9c\xe5\x05\x2e\xc1\x8f\x4a\x92\x58\x0e\xe5\x10\xa6\x67\xe1\x8c\x3a\xe5\xad\x9b\x52\x54\xda\xaa\xf5\x6e\x4f\x42\x4d\xf5\xff\x87\x19\x81\xff\xb0\x92\x72\x4c\xb8\x43\xbb\xf6\x5d\xf9\x95\x4a\xbc\x8a\x25\x50\x2c\x4e\x99\xb2\x7a\xbb\x6a\x2f\x72\xe5\xa3\x46\x59\xf5\x84\xf2\xd7\xb8\x83\x30\x19\xa7\x12\x4b\xa2\x6c\x03\xec\x0a\x84\x45\x14\x8c\xde\x50\x4d\x99\x37\xb3\xb4\xb6\x74\x48\xf1\x82\x66\x00\x86\x1f\xef\x71\xb1\x4e\xe2\xd4\x39\x9b\xfa\x09\x8f\x90\x24\x67\xf0\xe5\x46\x01\x53\xb8\xdb\xb5\xf1\xfc\x06\x0e\xdd\x9f\x0d\x43\x3e\x03\x34\xaf\x6e\xe7\x5b\x9d\xab\x72\xd9\x01\x03\x55\x6c\xb4\x95\x9a\x6d\x2c\xf8\xdb\xf8\x33\xd2\x00\x38\x0f\xa6\xf6\xce\x6d\x58\x3f\xd5\x58\xf2\xf1\x3b\x0d\x85\x85\xa5\x7a\xf3\xc4\x83\xa3\xf2\x0c\x6f\x00\x25\x4e\x80\x75\x57\x9d\x4f\x5d\xea\x44\x89\xb1\xee\x38\x52\xa8\xb7\xed\xe1\xd0\x6e\x6f\x03\x76\xaa\xa2\x71\x68\xa5\x2a\xf7\xce\xdf\x6d\x79\x9e\x24\x7b\x34\x8e\x22\xec\x96\xaa\xbd\x82\xa2\xa9\x9f\x1d\x11\x6c\x68\x0c\xa8\x68\x4c\x83\xd8\xb2\xd5\x7f\x39\xdb\xda\xd5\xed\xcb\x28\x24\xa5\x31\x57\xe8\xdc\x61\xca\x0a\xb2\x43\x61\xa5\x45\x30\xf9\x19\x5f\x10\x58\xf9\x3e\x07\x96\x6c\x57\xa5\x75\xff\x35\x46\x7a\x21\xda\xed\x6b\x76\x72\xb8\x6a\x8f\x07\x9b\x7d\xcc\x94\x72\x89\xa2\x2c\x4f\x9b\xf5\xcb\xc3\xf2\x69\xed\x63\x70\xca\x02\x83\x30\x00\x0b\x04\xf2\x45\x86\xd9\xf9\x47\x19\xb1\x0a\xfb\x56\x4c\x2e\x2b\xb5\x63\xb1\x4f\x46\x31\x30\x6e\x9f\xea\xa0\x4c\x03\xd1\xb9\xd9\x7c\xc4\x7f\x94\xa7\x91\x53\x48\x7a\x06\x64\x0d\xb5\xbf\xfc\xbe\xcd\xc0\xab\x49\x84\x47\x13\x17\x8c\x1c\xa0\xb1\xfa\xc9\x8e\x4e\x3c\x8c\x31\x69\x42\xac\x89\xb8\xd0\x7a\xdf\xa6\x91\x95\x1e\x4f\x97\x84\x1a\x67\x7c\x51\xe8\xdb\xec\xbd\xde\x95\x5e\xe5\xd4\xdf\x9f\x44\x10\xec\xb0\x95\x95\x50\x6d\xb0\xbf\xff\x2f\x72\xc0\x86\x21\xc4\xbf\xc3\xff\x9d\xdc\x28\x1e\x46\x88\xb8\x6f\xb0\x56\x3c\xe3\xb9\xa7\x28\x57\xc4\x18\xdf\x4a\x79\xc8\x0a\x18\xcf\x13\xae\x03\xd4\x61\xde\x9f\x8b\x5a\x18\xb8\x45\x09\x06\xdb\xaf\x9e\x2c\x76\x34\x4d\x23\x3c\xd3\xbf\x44\xa1\x45\x37\x83\x52\xc1\x70\x0b\x72\x8a\x56\x37\x5e\xae\x68\x22\x0a\xa0\x68\xaa\x42\xac\x16\xde\x2d\x97\x43\x48\xb8\x3f\x8f\x20\x29\xea\x3b\xdc\x3c\x3f\x3f\xdd\x77\x7f\xa4\xc2\x03\xa3\x37\xe8\xbb\xf5\x78\xbe\x52\xa0\xa3\x82\x4a\xd5\x07\x52\xdd\x7c\x9d\x54\xaa\xae\x6e\x38\x54\xa4\x01\xde\xca\x76\x69\xd8\xe0\x8e\x3b\x6b\x2a\xd3\x0e\xd4\x18\x5e\x89\x76\xe1\xba\x28\x63\x52\x09\x76\xee\x3a\x02\xba\x57\xd4\xf5\xbf\x48\x09\x8a\x76\x25\xeb\x53\x55\x16\xcd\xa8\x6c\x42\x95\x10\x98\xe4\x6e\x44\x03\xa9\xff\xa3\x26\xb6\x03\x5a\xb7\x8b\xe5\xba\xfe\x29\xb2\x26\x2b\x0e\xa8\x69\x3f\x69\xe1\x51\x9d\x1a\x21\x26\x16\xea\xa3\x4b\xd7\x42\xe0\xb5\xed\x8f\x22\x2b\x9a\x7d\xe7\xf5\x5a\x95\x47\xd4\xf9\x19\x9f\x0e\x84\x88\x1c\x45\x46\xdf\x7c\x5a\xa7\xa2\x1d\xfc\x6a\xc6\xe7\x04\x43\x03\x7b\xd1\xf5\xa9\x5f\x57\x4c\xc4\x7d\x4d\xa2\x80\x8f\xf2\x82\xe4\xac\xa8\x21\x61\x82\xdb\x74\x79\x84\x07\x68\x5e\x4b\x1d\x7f\xc9\x8d\x57\xd4\x70\x96\x50\xaf\xdc\xb3\x3b\x9f\xba\x48\x9e\x1a\xb0\x52\x10\x3b\x10\xc7\x21\xc5\x40\xb1\x80\x69\xac\xaf\xd8\x5d\xc7\x22\xcd\x90\x38\x31\xfb\x15\x2c\x48\x4c\xe8\x6a\x84\xb7\x9f\x85\x38\x66\x0a\xf5\x5f\x90\x98\x3e\x19\x29\x42\x9c\x99\xbb\xd5\xe2\xc1\x76\x36\xf6\x56\xed\xae\xfb\x66\x43\xa4\x75\x35\xfd\x5c\x35\xaf\x4b\x51\xe9\x79\xfd\x01\xc5\x42\x29\x50\x72\x71\x09\x79\x9d\x9d\xeb\x4b\x3f\x8d\x76\x88\xc6\x88\xb4\x7e\x2d\x3f\x2c\x3e\xc5\x1f\x30\x91\x54\x88\x3c\x54\x6f\x59\x71\x40\x33\xf5\xe8\xdb\x45\xb3\x8b\x45\x44\x3b\x30\xf2\x28\x81\x3f\xcf\xe9\xe1\xcf\xba\x84\x2b\x16\xc5\x02\x27\xe2\x7f\x9b\x4f\x47\x40\xeb\xd4\x45\xdb\x83\x1a\x2b\xd7\xc7\xac\x68\x9e\x64\xf6\xa7\x2a\xb3\x62\xa2\x57\x32\x3e\x1b\x49\x52\x8c\xa3\xf7\x35\x34\x3d\x61\xb0\x39\x8f\x05\xf4\xb8\x1f\xcd\x49\xc2\xba\x42\x54\x1b\x34\xf7\x0b\xfd\xcd\x67\x67\x30\xf2\x17\x32\xf9\xc3\x79\xcb\x88\x62\x8a\xb8\x53\x5a\xd5\x6c\xf1\x17\x92\x8b\x8a\xc5\x01\x43\x50\xe2\xf1\x73\x5d\x98\x4a\x0c\xc5\xaf\x26\x3f\x2f\x76\xf2\x19\xa7\xb3\xc4\xea\x9f\xfb\x33\x4d\x02\x44\xb1\x8b\x36\x77\xb5\xe4\x9b\xf9\x70\x89\xd1\x44\x39\x6b\xc9\xc6\x71\xfe\x5e\xb6\xb7\x98\x8e\x15\x22\x1f\xbd\x81\x8c\x71\xcb\x2a\x3b\x40\xf3\x1d\x8a\xb2\x99\x4a\x96\x29\x96\xb4\x3b\x79\x6f\xe2\x81\x2b\xe9\x4d\xf9\xeb\xdb\x4c\x8d\x8e\xc5\xa3\x5f\x1f\x46\xfe\x11\x24\x22\x11\xc2\x37\x1e\x96\xe5\xf1\x94\x43\x5f\xb1\x62\x09\xa4\x3e\xe8\xb6\xf1\x8a\x7b\x96\x5d\x5a\xc1\x38\x4d\xb0\xf0\x8d\x00\x07\xec\x89\xf9\xe2\x0b\xe3\x8c\x2b\x0b\xd4\xfb\xcf\xb9\x6e\x10\xd8\x33\xb0\x46\x57\x8c\x1b\xc0\xe6\x5c\xbb\xad\x78\x9e\xa6\x3f\x96\x0a\x8d\xa5\x39\x87\xa7\xf2\xa5\x4b\x26\x02\x85\x91\xd8\xf7\xb3\x28\x0e\xcf\x50\x1c\xd0\x07\xa3\x3b\xca\x19\xb3\xf4\x64\xec\x84\xed\x85\x52\xd5\x19\xf4\x3e\x73\x92\xa7\x7b\x51\xe8\x0e\xf3\x76\xe5\x11\x4b\x96\x22\xa8\xb6\x12\x0d\x0c\x22\x51\x26\x13\x15\x6a\xef\xce\xf4\x57\xfe\x7f\xfe\x33\x6e\xf3\xb7\xfa\xcb\x2e\xd5\x98\x1f\xaa\x20\x45\x30\x87\x2b\xe4\x6e\xa1\xd0\x4b\x71\xca\x9a\x2b\xe6\xbc\x8a\x69\x12\x62\xcc\xf9\xeb\xd7\x2f\x7f\x89\x3a\xa6\xc9\x50\xa8\xbe\xb6\x8b\xa6\xab\xa8\xec\xca\x0e\xad\x31\x39\x13\x8b\x31\xff\x73\xa5\x1e\x27\x85\x3a\x75\x27\xf7\x83\x41\xe2\xfa\xf7\x52\x64\x65\x81\x37\x7f\x14\x78\x30\x20\x56\xe3\xb2\xbd\x06\x6b\xe1\x36\xfe\x32\x30\x24\x89\x5d\x51\xbe\xb2\xbc\x6e\x14\x84\x79\x32\x37\xd0\x4c\x5d\x5f\xbc\xb5\x47\xf7\xa6\x1a\x16\xa4\x96\x89\x65\xd9\xf0\xd9\x3b\xa0\x52\xda\xe8\x1e\xb9\x45\x26\x4c\xa3\x4b\x78\x00\x33\x8c\xa0\x8a\x04\xc6\x63\xb0\x6e\xfe\x31\x0c\xc7\x86\xef\x5f\x12\x10\x16\x39\x49\xa4\xad\xf5\x29\xb0\x36\xc2\xd7\x48\x14\x5f\xfd\x33\x1c\xee\x2e\x6f\xbc\x14\x26\x41\x6c\x99\xf5\x76\x29\xfc\xf5\xb9\x3c\x5f\x2a\x7b\xb6\xf9\x1b\x03\xf7\x3e\x3e\xe1\x0f\x58\x3c\xaf\x67\xcb\x64\x49\x94\x30\xac\x82\x39\xef\xd6\xf3\x84\x1e\xe9\xbf\x36\x02\x8b\x96\xb0\x2f\x45\x59\x1d\xb7\xd0\xce\x94\xaf\xca\x7d\x09\x09\x12\xe3\x00\x5e\xfb\xa6\x3c\xe5\x5e\xc6\x7b\x7e\xc9\x4b\x48\xa4\x71\x7a\x61\xe2\xb3\x2b\x7f\x42\xf6\x6d\x72\x3e\x6a\xed\x9e\xff\x53\xca\x7e\x01\xb2\x9c\xc0\xbf\xf4\xad\xf5\xa7\x60\x41\xe8\xda\xb8\x2f\x85\x2a\xab\x0a\x72\x44\x58\x3f\x4e\xbe\x2a\xd6\x14\x97\xa4\xed\xf9\x0a\x72\xd8\x8d\xa3\x2c\x46\xe9\xd9\xdb\x9f\x0f\x8e\xa1\xa1\x12\x2a\x99\x17\x3a\xbf\x85\xf7\x8b\x12\x52\x42\x4d\x60\x9d\x94\xdb\x68\x65\x84\xcc\x49\x58\x68\x11\x93\xf2\xfc\x79\xfb\xb4\x5b\xfe\x98\x7c\x92\x45\x56\x76\xa9\x0d\x03\xf6\xae\xa4\xbb\x2f\x4d\xbf\x6c\x49\x10\xed\xc4\xdc\xeb\xb1\x94\xa7\xfb\x78\x22\x62\xac\x50\xdd\xc3\xf1\xd8\x05\xde\x49\xd2\xe6\x08\x96\xf7\xdd\xae\x85\x58\x6a\x71\xf9\x96\x1b\x21\x02\x8e\xf4\x86\xac\x5e\xf8\x98\x77\x7c\x5d\x82\x58\x29\xe2\x7d\x5f\xca\xb0\x6b\xd8\xc5\xa3\xfe\x9f\xe9\x07\x55\xaa\x7d\x7d\xdd\x36\xfb\xae\x58\x02\x76\x1f\xd0\x03\x9a\x63\x9b\xb2\x22\x7c\x7f\xce\xf7\xf5\xa2\xc6\x3d\x3e\x93\x0c\x03\xdc\xcf\x8e\x50\xbd\xe5\xb0\xab\x00\x36\x65\x39\x41\x4b\xaa\x44\x52\x12\xd8\x90\x5a\xa1\x02\x67\x23\xf2\xd1\x32\x96\x48\x63\xed\xe5\x9a\xf6\xf6\xbf\x23\x3b\xfe\xe7\x2b\x14\xbe\xf1\xed\x37\xc8\x44\x53\x82\xa5\xb7\xdb\xa7\xcd\x65\x7f\x36\x31\x44\xa4\xae\xa3\xe9\x4c\x29\xda\x9d\xba\xac\xda\xf5\x24\x47\x54\xec\x1d\xa0\xea\x40\x3b\x13\xfd\x67\x68\x82\x58\xde\x36\xe4\x5a\x76\x7f\x64\x36\x8b\xea\x54\x25\xb0\x16\x55\xbf\x66\xa7\x87\x52\x43\x7e\xf3\x69\x6b\x39\xf3\x4f\xc3\xa4\x5c\x39\x86\xf1\xe6\x5c\xf4\x00\x4f\xc5\x83\xc0\xd2\x6c\x32\x04\xb6\xed\x5f\x21\x3f\x0d\xb8\x7d\x9d\x90\x76\x77\x2a\x1e\xd2\x08\x45\x68\x1e\xdb\x6c\x65\x98\xe4\xf0\x50\x2a\x63\x55\x95\xbc\x86\x42\xf3\xfa\x21\x3e\xeb\xee\x38\x58\xef\xb5\x4a\x64\x35\xcc\x75\xbb\x79\x94\x5a\xbd\xec\x39\x5f\xd4\x51\x25\x87\x47\x22\xc0\xa2\x3c\x72\x7f\xfa\xfa\x7f\x1f\x95\xf0\x38\x0e\xb1\x5c\x21\xc5\xdb\x9b\x18\x5d\x67\x9c\xa6\x60\x2d\x01\x00\x3a\xb2\xa1\xe2\x34\xb1\x18\x8b\xfa\x7c\x5c\xd9\x27\xe3\xfc\xfa\xa2\x6e\xf3\xe1\x54\xf3\x34\xb0\xf8\xba\x36\x54\x6d\xc3\xc4\xac\x38\x8c\xeb\xfa\x9c\x02\x50\x47\xda\xb9\x11\x75\xa6\xd6\x85\x2a\xbb\xc6\x13\x67\x49\x80\x16\x8f\x50\x58\xd6\x2d\xaa\x7b\xc4\xdd\x51\x4e\xb1\x42\xf5\xf3\x8f\xed\xfd\x17\xea\x4f\x6e\x74\x12\x50\x04\x5b\x8c\x28\xfd\xff\x3f\xff\xed\x7e\x63\x12\x58\x4e\x6b\xed\x4a\xd9\x50\x39\x41\xc3\x71\x53\xc1\x3f\x89\x84\xab\x34\xe9\xc5\xaa\x11\x9f\x8c\x6e\x8d\xed\x7f\xf9\x40\x90\x27\x69\x67\x3b\x6d\x5f\x83\x36\x19\x1f\xf9\x07\x28\x9e\x68\x00\xd5\x81\x8e\xf0\xd7\x3b\xe1\xe2\x31\xc3\x71\x7c\xb7\x53\x9a\x86\xbe\xce\x85\xfd\xa4\x27\xd3\xc9\x21\x8d\x67\x57\x6a\xc2\x24\x1e\xf6\xa8\xda\x9f\x77\x93\xf9\x17\x99\x8b\x10\xb0\xaf\x76\x44\x31\xfd\xf6\xcd\x1a\xaf\xe1\x5c\x10\x1e\x39\x18\x36\xf2\x51\x1c\x19\x6c\xc6\x1b\x50\x71\x91\x24\x08\x7e\x17\x95\x7a\xcd\xde\x2f\xb3\x6b\xae\x62\xea\x91\x88\xdb\xac\x8d\xf6\xae\x64\xae\x5c\x09\x8a\xad\xba\xba\x29\x4f\x5b\xab\x0f\x3a\x9c\xe7\x4a\x0a\xe2\x4b\x79\x67\xc4\x00\x62\xaa\xb8\x85\x66\x3b\x67\x5b\x3f\x39\x37\xd8\xf9\xac\xb3\x5a\x9e\xab\x7a\x52\xf1\xe0\x3a\xa2\x98\x83\x9e\x30\x10\x04\xbd\x1f\xc0\xc0\xfd\x4d\xd1\x34\x04\xd6\xd9\x19\x35\xa3\x24\x9d\x6b\x6a\xb3\x5b\xcc\x8a\x66\x31\x55\xe3\x87\xa9\xb5\xb6\x2a\x6f\x3a\x6b\x06\x1c\xa0\x2f\x60\xa5\xbc\x4d\x4f\x8c\x35\xdf\x3b\x66\xcd\x4f\x6f\x73\xd8\xff\x46\x10\x0a\x95\xf9\xa1\x40\x8e\x75\x27\x72\xa2\xb8\x49\x68\x12\xf4\x86\x63\xf7\xe5\x21\x53\x7f\xaf\x89\x91\x06\x90\x22\xc3\xa4\xdd\x1c\x2c\xa4\xd0\xc9\xac\xab\x34\x4c\xad\x7a\xd7\x4e\xbc\xc1\xd3\xb4\x0a\x9c\x86\x82\x21\x59\x0b\x1d\x13\x56\xbf\xb2\x09\x6b\xf8\x32\x5c\x4d\xa3\x10\xd0\x99\x18\x13\x88\x1f\x90\x55\xbd\x01\x99\x1f\x21\xad\xf1\xaf\xf2\xae\x14\x36\x8b\x1f\xef\x67\x69\xa4\x84\x25\xdd\x9c\x9b\xd2\x67\x40\xea\xa2\x98\x97\x92\x90\x84\x64\x9e\xa7\x76\x7b\x1e\x54\xbd\xc6\x3f\x8b\x84\xb1\x37\x2a\xb1\x74\xf6\x2f\x37\xfb\x94\x10\x88\x4c\x6f\xd0\xf9\x79\x0b\x2a\x3b\x8a\x1c\x23\x94\xe7\x0a\x54\x56\xcf\x8b\x86\xaa\x34\x66\x0c\xb7\xc1\x36\x30\xca\xf3\xac\xee\xb6\x97\x34\x4e\xa5\x36\x83\xbc\x7a\xe0\x33\x35\xfe\x72\x2a\xe3\xc8\x19\x61\x0c\x94\xad\x54\x4a\x15\x4f\x47\xb6\xf3\x77\xde\x44\x7c\x36\xce\x48\x99\x8c\xf0\x52\xa4\x67\x4e\x6e\x60\x9a\x2b\xa5\x0c\x0c\xf2\x82\x5d\x31\xff\x6b\x48\x61\x9a\x84\x04\xa7\x7f\x6f\x33\x2c\x91\x62\xfb\x54\x74\xc1\xd3\xe4\xfc\x09\x51\xd4\x9b\x89\x59\x81\xa1\xac\x71\x7e\xdf\xe3\xfb\xc6\xa3\x80\xd9\x96\x23\xb6\x7c\xbf\x8b\xe3\xc0\xc3\x5d\xa5\x9c\x10\x5c\x9f\x8f\xe2\xd7\x4d\xa6\x5d\x29\xbc\x3b\xc8\x78\xe0\x18\xd5\x1a\xe0\x78\xf3\xe9\xbc\x07\x9c\x04\xd9\xd5\x50\x70\x66\x32\xa7\x01\x4b\xac\x30\x88\xc8\xbd\xd6\xd2\xf4\xf9\xa4\x61\xc2\x3d\xd4\xfc\xa5\xc8\xfe\x7b\x76\x12\xfa\xe5\xa4\x6a\x3b\x99\x19\x69\x42\xe2\xbe\x4c\xdc\xae\xeb\x5f\x49\x24\xab\x34\xe5\x21\xd6\x11\x74\x59\x0c\x77\x97\xb9\x4d\x2e\x4d\x35\x71\xc2\xbd\xc7\xf2\x1d\x9e\x45\x35\x91\xee\x56\xa9\xa0\x5a\x9b\x6e\xf3\xba\x29\x7d\x46\x9e\x0a\x49\x3c\xef\x1c\xf1\x3d\xc3\x72\x94\x1f\xa2\x13\x9c\x78\x05\x7c\x4c\x01\xd3\xd7\x56\xa3\xf1\x1d\x93\x2c\xc4\x19\x9d\x3b\xfe\xda\x94\x31\xa9\x52\x45\xe3\x54\xbb\x9a\xe5\xe1\x30\xac\xc1\xa4\x4a\x80\x4b\xc7\xdb\xdf\xb6\x1d\x79\x6b\x8d\xaf\x53\x09\x63\xed\x91\x45\xf1\x6d\x7c\xc0\xd0\xd8\x35\x52\xb6\x4d\x1b\x00\x8c\xda\x15\x93\xb3\x40\x9a\xa6\xb6\xa0\x78\xa8\xd0\xc1\xb0\x38\xc0\x15\x56\xc4\xdf\x55\xf2\x51\xa9\x89\xb8\x4f\x37\x3a\x22\x01\x1b\x6d\xb8\xa9\x91\x32\x0c\xbb\xbe\xb3\x6b\x53\x79\x30\x4e\x6a\x80\xe2\x6f\xbb\xd9\x3c\x3d\xfe\x6b\xb5\xf7\xfe\x26\xcf\xbb\x7e\x80\x40\x90\x76\x56\x5b\xbc\x50\x77\x6f\x45\x10\x24\x58\x72\xc2\xc5\xac\x86\x42\x47\xd7\x5e\xf3\xcb\xed\x4b\x04\x44\x3a\xfd\xdf\x36\x94\xf8\x21\x6a\x24\x8e\x0d\x2f\x5c\x04\x22\x42\xa6\x13\x9e\xff\x5a\xd9\x69\xe6\xd4\x61\x0a\x98\xc0\xac\x6b\x71\x2b\x72\xf1\xe1\xc1\x02\x22\xd2\x0c\xeb\x5b\x96\xd3\xf7\x55\xbf\x58\x44\x90\xc6\xc2\xd7\x24\x70\x09\xb3\xbe\xe8\x83\x02\x82\x20\xcc\x66\x52\x36\x73\x9b\x95\x0c\x56\x82\xe8\x18\xbf\x33\x53\x25\x9e\x21\x5e\x75\x4d\x4f\x11\x93\x14\x4b\x3a\xb7\xab\xdf\xf7\x58\x75\xff\xf1\x74\x7f\xbb\xda\xf4\x87\x15\x26\xa9\x8b\x5b\x4f\x45\x1e\xc0\xc3\x45\xcc\x34\x52\xe4\x65\x76\x58\xbe\x66\xaa\x8f\xf3\x05\xd5\x76\xed\xc5\xfb\xe6\xa0\xdd\x83\x40\x62\xf2\x83\xe7\xe1\x76\xee\x54\x2c\x10\xe0\x68\xd3\x0f\x90\xb7\x27\x9a\x5f\x8f\x45\x42\x03\x63\x1d\x7f\x30\x9b\x6e\xa7\x98\x7d\x23\xb7\x65\xde\xfd\xde\x44\x2a\x07\x53\xb9\xb1\x2b\xd4\x80\x9c\xe3\x6f\x2a\x8f\x29\x42\xee\x36\x8b\xc9\x37\xf0\x18\x8c\xea\xf3\xd6\x9d\xf8\x35\x0a\xb9\x04\x97\x4c\x49\xdf\x15\xb4\x15\xdb\x61\x18\x20\x52\xa1\xe3\x5e\xe0\xb9\xdd\xac\x51\xf6\xe5\x0d\x8a\xdf\x05\xca\x32\xfb\x71\x46\xe2\x1b\xe5\x9f\xaa\xfb\xb9\x7f\xf1\x5a\xba\x0f\x8b\x40\xd9\x98\x55\xe4\xe0\xd3\xff\x8d\x68\x80\xfa\xb3\x0b\xaa\xf0\x2a\x6b\xeb\x6b\x79\x3a\xcd\xef\xb1\x42\x8a\x38\xb4\x9e\xb0\x18\x20\xa0\x47\xa2\x3f\x87\x54\x14\xf5\xb5\xcf\x35\x54\xbf\x97\xa8\x67\xfc\x75\xb8\x2b\xa4\x4a\x3c\xa3\xc3\xe6\xd0\xb7\x60\x60\xca\x1f\x13\x12\x08\xce\xb7\x13\x34\xaf\xcf\xab\xcd\xd4\x3c\x52\x09\x45\x42\xdf\xc4\x76\x96\xc8\xb6\xb5\x53\xcf\x48\xc9\x2a\xa1\x12\x89\x0d\x62\x24\xb5\xed\x16\xfe\xea\x35\x15\xf1\x20\xf8\x44\xa4\xec\xd7\x35\x15\xa1\x75\x8a\x04\xcf\xac\xc8\xdc\xf5\x77\xf7\x02\x12\x15\x99\x01\x79\x00\x41\xaa\x16\x9d\xea\x47\xa4\x71\x22\x7a\xac\x24\x4e\x4f\x1b\xaa\x8d\xe7\x8f\x09\x13\xc4\xa4\xb7\x67\x78\xcf\xf2\xbc\x5b\x35\x8c\x0a\x71\x7f\xc5\x4a\xd0\xf9\x70\xf0\xac\x3d\x19\x24\xd6\x3f\xa8\xdd\xaf\x1f\x06\x8e\xaf\xfe\x30\xe7\xc8\xdf\x78\x58\x6d\xd6\xb7\xeb\xc5\xa3\xfd\xa5\x33\xe9\xac\x0c\x74\x6c\x89\x47\x5d\xf8\x33\xd7\x66\xba\x7c\x3d\x65\x18\x05\xa8\x7c\xbd\x7a\xdc\x4e\x68\xa2\x32\x4c\x6c\x2d\xa5\x86\xe6\x7c\xfa\x3f\x6f\x32\x17\xed\xa2\x8b\xaf\x8e\x02\x83\xe9\xcf\x2d\xbc\xf7\x02\xf2\x4a\x46\x34\x32\xf6\x51\x75\x32\x6c\x9d\xb2\xb4\x92\x91\x96\x68\xa7\xb4\x01\xed\x38\x81\x5f\x6f\xf7\xee\x63\x44\x4a\xcc\x2c\xec\x2b\xf9\x3d\x2f\x65\xfb\x46\xa0\xb6\x7a\x36\x05\xc9\x4b\xa2\x53\xec\x3d\xa2\xf1\xe1\x4a\x67\x4d\x59\x6d\xb2\xc3\xeb\x14\x8b\x26\xa9\x34\xca\xb9\x9d\x0f\xcb\xef\x7f\x91\x06\x4d\xae\x8c\xc5\x96\xbb\x02\xcd\xeb\x16\x4d\x7f\xfd\xdf\x85\x45\xce\x35\x67\x79\x27\xa4\xff\x6b\xc2\x39\xfa\x82\xee\xb2\x26\x87\x5b\xa4\x47\x4c\xc4\xe9\x94\xe4\x91\x4e\xd2\x0e\x83\x58\x89\x6a\x08\x6e\x91\xa9\x08\xa2\x11\xdc\xf4\x8b\xb0\x45\xa6\x0a\xac\xc3\xb1\x78\x83\xe5\xbc\x3f\x8d\x92\x82\x19\xfc\xbe\x7d\x56\x5b\x06\xee\x74\x81\x9f\x0f\x6e\xfd\xa7\x05\x08\xb7\x22\xec\x4f\xb6\xfa\xb0\xd7\x13\x98\xd8\x68\xaa\x0b\x80\xc8\x2f\x90\x88\xfd\x1f\x04\xe3\x52\xb2\x04\x1f\xc9\x5d\x59\x5e\x32\x31\xa5\xa2\x02\x21\x94\x37\xe7\xaf\xe5\x73\x95\x54\xd2\x0a\x83\xdc\x40\x9e\x8b\x9b\xfc\x3c\xac\x82\xb5\x5b\x10\x32\x0d\xb1\xbc\x59\x9f\x33\x95\xe9\xee\x02\x74\x40\x43\xa7\xdc\xd0\x2e\x0d\xf7\xf0\x0e\x93\xc4\x46\x6a\x91\x22\x3d\xfa\xe4\xe4\xa8\xf6\xc7\x8d\x0d\x0f\xf2\xb2\xb9\x85\x77\x9f\x41\x8c\x2f\x08\x04\x27\xba\xab\x27\x88\x7c\x03\xa2\x9e\x78\x57\xb7\x83\x6c\x34\x70\x80\x69\xf2\xf8\xef\xff\xb5\x05\xc9\xbe\xfa\x21\x41\x00\x82\xb4\x3f\xd0\xb0\x7d\x72\x26\x23\xc1\xda\x14\xa0\xcf\xab\x5d\x4d\x9c\x52\xc0\x29\x87\xde\x47\xf3\x6a\x08\xa5\x02\xb0\x22\xb3\x6f\x99\x7a\x53\x59\xf3\x39\x54\x41\x50\x2a\x24\xba\x07\xe0\x9c\x46\x0b\xb2\x0a\x95\x41\x92\xae\x9b\x0d\xd8\xdf\x7d\xef\x56\x00\x15\x42\x82\x95\x15\x2b\x89\x8c\x5e\xcd\xcd\xb0\x18\xa6\x22\x1a\x60\x48\x2f\xec\x02\xd1\xab\x49\x28\x15\x73\xe3\x11\x7a\x1b\xa8\xcb\xfc\x1d\xaa\x45\x57\x5f\x99\x31\xc3\x51\x8a\xc6\x11\x32\xc0\xf1\x42\xbf\x43\x01\x75\x47\x5a\x83\xee\x8a\x59\x2a\x50\x91\xcb\xde\xad\x47\xf8\x78\x16\x95\x82\x7c\x8c\x4e\x9d\x9c\x98\x49\xd1\x79\x41\xfe\x5c\x3f\x77\xa7\x02\x81\x88\x9b\x53\x79\xb2\x6f\x27\x5e\x94\x33\xa9\xf4\x63\x4c\x48\x7c\xc4\x5e\x1e\x4f\x79\xd6\x5e\xfe\x16\xaa\xf7\xec\x1a\x55\x44\x25\x41\x4a\x5c\xd7\xe9\xb9\xcc\x33\x5b\x62\x04\x3d\x0f\xdc\x52\x49\xa4\xf0\x47\x2f\xbd\xcc\x75\x5f\x37\x99\xbd\x49\x09\x07\x04\xe5\x6e\x16\x8f\xdf\x57\xab\xc7\xdb\xbd\x2f\x5e\x2a\x1e\xa4\xb8\xb9\xde\x3d\xbd\x6c\x76\x3f\xf6\xbb\xf5\x6a\xb3\xbf\x5d\x6f\x97\x03\x50\x88\x12\x21\xd1\x56\x70\x69\xef\x0c\x93\xc6\x2f\x8c\x92\x91\x65\xdc\xdc\x95\xa5\xf6\x5d\xd8\xb1\x36\x51\xb7\x2c\x0d\x8a\xee\xf3\x6f\x76\x7b\x2b\x7c\x91\x06\x73\xb9\x45\xf3\xed\x5a\xc7\xb1\xff\x90\x8e\x12\x94\x7b\x5a\x8a\xe6\xb5\xbd\x7d\x03\x3a\xad\x82\x24\xf0\xfe\xa5\x3f\xca\x8f\x07\x51\x7c\xfe\xc4\x37\xaa\x9b\x1d\x86\xa5\x1e\x8a\x70\x03\xd3\xd2\xaa\x32\xdc\x02\x5d\x4e\xaf\xd9\xcf\xae\xff\xa4\x83\x10\x50\x7c\xce\xf5\x9f\xc6\x55\x05\x1d\x24\x1c\x2b\xa4\xb7\xc7\xfc\x0b\x36\xb2\x0e\xa4\x15\xae\xb8\x21\x64\x33\x5c\xc0\x74\x44\x12\xcc\xe7\x8a\xf2\xfc\x0e\xe2\x6c\xd7\xeb\x8b\xbb\x79\xf9\x52\x6b\x12\x84\x88\xb1\x3c\x89\x4f\x29\xd4\xdb\x06\xfe\x7b\xce\xaa\x2e\x9d\xd3\x24\x48\x50\x39\xcc\x47\x21\xdb\xb3\xfc\x3a\x2e\xd3\x24\xb0\x4e\x33\x15\xc2\x2f\xbe\x43\x31\x8f\x39\xd6\x44\x3a\x80\x7b\x05\xeb\xe5\x53\x1b\x2e\xd4\xf7\x60\x26\x8b\xa4\x8e\x69\x92\x38\xa6\x4e\x75\x9e\xd6\x95\x35\xe5\xdc\x11\x02\x91\xc7\xbd\x01\x0d\xc7\xd3\xac\xac\x40\xbf\x4a\x6a\x16\x08\xee\xd4\x89\xef\xb2\x5a\x89\x7c\xda\x65\xbf\xea\xa5\x34\xbe\xb4\x84\x44\xb8\x44\x38\xd6\xc8\xca\x61\x76\xbf\x75\x87\x79\xdc\x37\x9c\x9f\x2b\x38\x66\xe7\xe3\xd2\x6d\xd1\xd3\x46\xb6\x4e\x58\x8c\xd2\x81\xaa\x2a\xeb\xfa\xae\xac\xde\xee\x7a\xd2\x96\xe6\x32\xc5\x9c\xfa\x54\x96\xf9\x2d\xf2\x13\xfc\x01\xcd\x45\xea\xc5\xeb\x77\xd0\x9b\x4f\xb8\xe3\x29\xd5\x18\x19\xec\x4d\x05\x70\xa5\xfe\xed\x56\x08\x2d\x48\x82\x30\x53\xa8\x44\x0d\x1b\x44\x23\x4c\xd8\xdc\x5a\x68\x83\x6c\x6e\x57\xe3\x7b\x2c\x9b\xd5\x7f\xcf\x97\x80\x8c\xd1\xe6\xae\x65\x90\xf2\xd4\x37\x3b\x7e\xad\x8e\xa7\xea\x5c\x34\x43\x0b\x5f\x3f\x8e\x53\x6c\x51\xe5\x60\x9a\x68\x32\x0b\x14\x31\x18\xb7\x6e\x77\xff\x78\xc6\xe9\x32\xbf\x26\x6a\x45\x2d\x23\xdf\xcf\x07\xd1\x74\x2b\xba\x56\x60\x25\xa5\x6d\x81\xfa\xa9\xe8\x1e\x14\x04\xc6\x04\x03\x9a\xde\x56\x89\xe3\x4a\x54\x45\x2f\x41\xaf\x34\x10\x85\xfa\x28\x37\xb7\xeb\xd1\x6b\xd7\xee\xb8\xae\x07\xbe\xfd\x2c\xca\x53\x9d\xd5\xa3\x4c\x5f\x83\x21\x98\x96\x89\x43\x05\xf3\x2e\xed\x0a\x82\x40\xd1\x60\xc0\x30\xb1\x51\xac\xfb\x0a\x08\x03\xe1\x45\x71\xf7\xdb\x53\x59\xd4\x65\x05\x7a\x6f\xd3\x94\x7d\x56\xec\xff\x5f\x29\xf7\x37\x9f\xfb\x89\x6d\xfb\xe4\x2b\x42\x08\xd1\xa9\x0a\x19\xb8\xf3\x6b\x0b\x44\x0c\x94\x53\x2a\x18\x86\x97\x10\x31\x0b\xb7\x74\xbe\x03\xab\x42\xd7\x8b\xa6\x3b\xc8\x21\x89\xbc\x99\xec\x71\xda\x8a\x07\x12\xa4\x91\xab\xc8\x3e\xcd\xbe\x98\x6e\x5c\x9c\x24\x9a\x77\x79\x78\xa7\x02\xdf\x91\x62\xbe\x06\xfc\x03\x75\xb0\xac\x8b\xaf\x71\xc7\x59\x44\xb8\x05\x13\x9d\xd0\x56\xe2\x5b\xf7\xf7\x18\x53\x25\xb4\xc7\x00\xbd\xdf\x3c\x6f\xbb\x43\x49\x88\xf2\xc9\xcb\xf2\x7c\x2a\x8b\x89\x67\xe8\xbf\xa3\x7e\x21\xe5\x13\xb0\x32\x30\x61\x31\xa1\xbf\xdd\xfc\xf6\xff\x86\x93\x05\x12\x9d\x5a\x1f\x03\x55\xee\x6d\xdd\xad\x3b\x02\x4e\x89\xf9\xb3\x41\x60\xf2\x62\x7a\x1f\x79\x98\x20\x44\xfd\xb1\xb4\x3b\xd1\xc5\x2b\x37\xf3\xe6\x81\x0c\xa5\x97\xd0\x5a\x8a\xc2\xda\xe8\x7d\x61\xae\xa6\x40\x0a\xee\x83\xcd\x1f\xe4\x26\xd3\xba\x9f\x04\x4a\xa6\xc4\x16\xfc\xb6\xd9\xa1\x00\xfd\x58\xae\x0a\xe5\xb6\x59\x37\x44\x47\x0a\xd1\x56\xdb\x53\x95\x35\x7f\x0e\xf6\x53\xd0\x86\x7b\x61\x9e\x5b\x51\xbd\x15\xa5\x86\x4b\x3f\x20\x05\x20\x12\x6c\x5e\x7e\x87\xe6\xc1\x49\x76\xf7\x74\x6d\x30\x91\x44\xa0\x92\xd5\xc8\x74\x32\x9b\xf3\xd3\xc1\x10\x85\x01\xc1\xb6\x41\x08\xb7\x76\xa2\x07\xed\x12\x38\xfd\x4e\x93\x46\x32\x1c\x32\x5f\xc6\x7a\xad\x76\x94\x09\x78\x88\x29\xaa\xd3\x6c\xb0\xfd\xee\xac\x2c\x2e\x40\x2f\x26\x4c\x19\x56\xbe\x3d\xc8\xe3\xe8\xda\xc5\x73\x23\x2d\x48\xf9\xe1\x5c\x78\x5f\x52\x65\x42\x29\x93\xa8\xef\x1f\xeb\x39\xa8\xbb\x89\xa8\x56\xa9\x95\x12\x83\xa2\xc9\xde\xb3\x3a\x2b\x0e\xe3\xee\xac\x89\xb8\xc0\xfe\xbd\x65\x8b\x0e\xfe\x8a\x4a\x52\x7b\x44\x27\xb6\x59\x56\xd8\x1d\xd2\xd0\xd1\xa1\xa0\x72\x86\x1a\xf3\xf3\xc4\x10\x6d\xf9\x92\x28\x42\x73\x38\xe7\xa2\xb2\x32\x20\x26\xab\x8e\x23\xc1\x3e\x97\xa1\x0c\x37\x11\x13\x87\x02\xeb\x1a\x1a\x4e\x79\xf9\x39\x2d\xa5\xf9\x41\x44\x32\xfb\xc2\x3a\x47\x82\x53\x59\xb5\x93\x01\xdd\xa7\x60\x04\xdb\x31\x34\x32\x18\xa2\x38\xd8\x0e\xb8\xa2\xc7\x54\x77\x5b\x19\x9a\x18\x84\xf0\x9b\x73\x73\xae\x60\x8f\xfa\xd1\x7b\x0c\x3c\xfc\xa9\x58\x92\x44\x2e\xf0\x5b\x1f\x4f\xf9\xd2\xf9\x3a\xfe\x77\xbc\x0f\x9a\xc4\xcd\x2f\x2b\xb1\xf0\x76\x25\xd5\x36\x49\x6c\x4b\xce\xed\x8e\x36\xd1\xbb\x56\x26\x0d\x65\xc7\xea\x68\xdf\x85\x45\x53\x1e\xeb\xe5\xf5\x4e\x81\x49\x15\xe7\xc2\xcb\x3c\x0e\xca\x24\xee\xb0\x88\x23\x64\x14\x65\xf5\xc6\xce\x1d\xbb\x85\x5b\x2f\x87\xf1\x99\x84\x62\x58\x65\xbf\xc9\x9a\x2d\x9a\x4d\x3c\x94\x1a\x2a\xd1\xcf\x42\x19\x03\xaa\x1b\xae\x8b\xfa\x5c\x01\xfa\xb9\x75\xb7\x48\x26\x0a\x15\x68\x32\xe3\x25\xc2\xe6\xf2\x07\x23\x55\x82\x97\x83\x52\x8e\xce\x62\x17\x29\x2e\xab\xc2\x99\x13\xb8\x81\x8a\x93\xc8\xd5\x86\x3c\x83\xce\x03\x2d\xe7\xbc\xe5\x95\x51\x8a\xca\xce\xb0\xe7\xbb\x38\xc2\x36\xd3\x30\x16\x94\x98\xdc\x39\x05\x16\x75\xda\xd5\x47\x86\x9a\xe1\xca\xe8\x30\xd4\x2e\x98\x77\xed\x97\x09\xa7\xcd\x8f\x33\x69\xd0\xcb\x9b\xbb\x8c\x60\x90\x8a\x1a\x08\x62\xac\x7b\x28\x51\x3c\x7b\x55\x4a\x65\x80\x59\xf9\x89\x03\x34\xb8\x04\x65\xc5\x61\x7b\x3e\x1e\x45\xf5\x39\xd1\x88\x54\x06\x0c\xc3\xce\xd1\x76\xb5\xba\x5f\xed\x77\x4f\xbb\xc5\xfd\x7e\xfb\xf2\xfc\x7c\xff\x4f\x7f\x32\x13\x25\x78\xb7\x10\x19\xb7\x70\x68\xde\xb5\x83\xc5\x4d\xce\x66\x08\x20\xa6\xa2\x4d\x47\xed\x7a\x69\x6d\xae\x26\xf2\x16\xc6\x24\xa9\xd2\x3d\xd2\x76\xae\x20\x64\x0c\x4f\xb4\x45\xf9\x57\xc5\xc3\xe7\x3f\x5e\x16\x7e\x8b\x46\x11\x89\x42\xb7\x7f\x29\xb7\xe5\x11\x06\xe6\x49\xa3\x19\xa1\x83\x20\x90\xd8\x9a\xb8\xf1\x4e\xf9\xdf\xfc\x81\xc4\x8a\xa4\xd8\x25\xf3\x76\xf1\xf4\x6d\xfc\xc1\x30\xe0\xb8\x2d\x38\xc6\x8b\xc8\xc1\x01\xe9\x6d\xed\x74\xf2\x6d\x7f\x55\xab\xf3\x27\x8d\xac\xd3\xe4\x41\x1c\x61\x5d\x3f\x75\x72\x21\x3a\x08\x13\x2b\xa7\x5a\x43\xf3\x52\x94\x1f\xed\x5e\x77\x3e\x3e\x99\xd5\x2f\x4b\x62\xa9\x6d\x97\x7c\x78\x56\x37\x35\x75\x10\xa6\x11\x0a\xc2\x80\xce\x9a\x15\xea\xf4\x5d\x5f\x08\xdb\x7c\x10\x30\xb0\xbb\x79\xfe\x03\xc5\x90\x3a\x33\x03\x1d\x44\x81\xf5\xeb\x3d\x96\x45\xf3\x3a\x9e\x87\x3a\x88\x52\x66\xdb\xaf\x8e\xb7\x8a\x9d\x8a\xee\x93\x46\x62\x5a\x5b\x60\x48\x33\x08\x3f\x74\x40\x78\x8c\x89\x7b\x59\xc0\x73\x7e\x9e\x9e\x35\xe6\x21\x71\x48\xda\x1b\x51\xc3\xb6\x11\xc7\xac\x10\xd3\x41\x2a\xc5\xa5\xd6\x16\x6a\x7e\x03\xd7\x5c\x77\x2b\xc0\x68\x28\x95\x0a\x85\xca\x3c\xfe\xad\x1e\xc8\x50\xe8\x80\x2a\x6a\x05\x57\xbd\xb3\xa6\x84\xbb\x2a\x83\x02\x8b\x01\xc3\xfa\xed\x5f\x75\x3c\xaf\x3c\x5e\xaa\x43\xcd\x07\x4a\x31\x1d\x78\x66\xd5\x5f\x03\xa3\x5a\x8f\x44\x5f\xdb\xef\x9e\x60\xd2\xe7\x96\x62\x1d\x24\x94\x33\x17\xf4\x3a\xb9\x44\xbf\x66\xd5\xfe\xe4\x49\x6a\x2d\x08\xd7\xab\xdd\xa5\xfc\xbe\x0e\x12\x99\xa4\x89\x57\x85\x2e\x3f\x77\xaf\xf0\x52\x64\xef\x50\x79\x89\x73\x1d\xf0\x80\x09\xe8\x55\x5b\x07\xa9\xa5\x0e\x38\x27\x89\xec\x9f\xd5\x85\x38\xaa\x0e\x52\x29\x10\xab\x8d\x5e\x0b\x21\x9d\x1c\x15\x44\xe1\xf4\xaa\xcf\x35\x2a\xf9\xea\x0e\x23\xe6\x06\x48\x41\x90\xbf\xd1\xf7\x1e\x9c\x05\xd4\xe4\x67\x60\xe9\x6e\x20\x08\xbe\x9b\x42\x7d\x75\xa0\xc0\xba\x16\xac\xcb\x62\x58\x64\xd1\x81\x26\xd4\xd8\x88\x72\xf0\x78\x26\xe7\xd7\x34\xc5\xbe\x9f\xbf\x8e\x1b\x68\x3e\x00\x8a\x97\xba\xab\xc5\xe8\x00\xb8\x40\x8b\xf7\xac\xde\xbe\x4e\x8c\xa6\x75\x60\x22\xeb\xf9\x55\x43\xe3\x16\xfd\xd9\xf9\x12\x06\x24\x44\xc4\x8e\xea\x02\x36\x2c\x94\x7d\xf3\x87\x13\x86\xcd\x53\x2c\x19\x3a\x3c\xd1\x48\xa4\x53\x87\x61\xa8\xc3\xa1\x72\xe5\xcd\xe3\x8d\x3f\x14\x85\x1a\xdb\x1f\xed\xc9\xcf\x45\xd6\x7c\x7e\x6f\x83\x93\x7a\xd8\x69\xd2\x61\x44\x38\x56\xc4\x84\xd5\x36\x7b\xf4\x6e\x3a\x3a\x8c\x62\x03\x8e\xac\xf5\xd2\x64\x79\x1d\x8d\x7f\x63\x18\x71\x86\x61\xfe\xf1\xb3\xc3\x90\x3c\x96\xdd\x87\x25\xc5\x97\x7e\xf1\xdb\xd0\xc3\x4f\x87\x24\xe8\xe2\x79\x3f\x09\xfc\xa1\x98\x70\xb4\x3c\xc8\xac\xc8\xa7\xff\x2b\x50\x2c\xef\x2a\x0f\x2f\xbd\xb5\x48\x11\x77\x98\x12\x86\x91\xd3\x72\x7d\xf3\x78\x9f\xbd\x5b\x43\x72\xa4\x0e\xc2\xe8\x7b\x91\x0f\xd7\x6e\x71\x2f\x77\x77\xeb\xe5\x7a\xf5\xb8\xdb\x6f\x77\x8b\xdd\xcb\xd6\x0f\x60\x3a\x94\xb2\xaf\x84\x0e\x9b\xe7\xe3\x0d\x25\x64\x3a\x15\x81\x03\x0b\xf4\x6b\x67\xc8\x63\x2b\xeb\x90\x0b\x0c\x02\x75\xd9\xdd\x48\x0e\xc0\x5d\x1a\xe2\x0c\x2c\x7f\x88\x4a\x2b\xaf\x1b\xa1\xc3\x34\x4d\xf0\x8c\x39\xc6\x97\x5d\x79\x63\xda\xee\x1a\x66\x59\x3a\x4c\x1d\x22\x11\x11\x69\x77\x00\x1b\xf4\x70\x18\x03\xd9\xae\xd4\x96\x78\x77\x8a\x04\x37\x23\x0d\x9e\x6c\xf9\x03\xf4\x15\x14\x82\x0e\x53\x63\x90\xd1\x75\x46\x34\xd0\x5a\x4f\x56\xf2\x50\xb0\xd4\x5e\x50\x59\x34\xa2\x0d\x6e\x47\xdb\x4e\x28\x12\x45\x22\x7b\x58\x89\x66\xc8\xa1\x0b\x87\x10\xa5\xd0\x0f\x57\xcc\x2a\xb5\x67\x87\xe2\xe9\xdc\x4c\xe6\x9e\xd0\x02\x21\x93\x56\x71\x28\xff\x5c\x0c\x9a\x0b\x57\x2e\x5f\x09\x86\xa2\xeb\x37\x9b\xa7\xdf\x56\x9b\xfd\x66\xb5\x5d\x6d\x7e\x5f\xed\x17\xb7\xb7\x9b\xd5\xb6\x9b\x06\x4a\x31\xb4\xd4\x74\x0f\xea\xd6\x02\xee\x9d\xad\x34\xb6\xf0\xf7\xdd\x50\xe0\x68\x22\xf6\x7b\xd9\xd8\x84\xab\x99\xc9\x0c\x27\x17\x01\x5a\x50\x6f\x34\xdd\xee\xe7\x50\xdf\x95\x15\xc2\xf9\xbe\xd9\x1d\xdd\x3d\xed\x4e\x5a\x48\x87\x60\x8c\x35\x66\x47\xa6\xc4\x06\xde\xcb\x37\x98\xdc\x0d\x03\x21\xf6\x22\xda\x28\xc9\x37\x54\xbe\xba\x17\x51\x90\x32\x6c\x0d\x38\x09\xc5\xbc\x57\x07\xd3\x51\x20\x52\x95\xfa\xec\xbd\xd2\x4e\x3f\xa0\xab\x63\xea\x28\x0c\xb5\x6d\x37\xb8\x56\x4e\xaf\xf9\xa2\xa3\xd0\x44\xde\xf1\xaf\xbd\x90\xaa\x01\x6d\x77\x90\xd1\x05\x47\x24\x94\xb8\x4d\xec\x65\x2e\xd4\xdb\xbd\x6d\x3d\x8e\x87\xc4\x61\x8a\x8a\x41\xdf\xa1\xf9\x9e\x19\xeb\x8e\x3d\x9c\xff\x51\x4c\xc2\xc0\xb5\x2e\x7c\x50\xf8\x80\x1e\x92\xfd\x95\x52\x12\x1a\xd7\x0e\x10\x79\xa7\x82\xa0\x23\x2a\x28\x02\x49\x96\xdf\x87\x6b\x44\x44\xa5\x14\x4e\xa4\xb2\x0d\x29\x97\x3f\x97\xf5\x15\x83\x53\x1d\x51\x15\x0a\x17\xbc\xef\x2b\x38\x8a\xac\xc8\x8a\xc3\xfe\xbf\x67\x61\xc3\x2f\x37\x8a\x45\x89\x5f\x54\x56\x99\x2e\xcb\x19\x68\x82\x8e\x18\x91\xa8\x87\xad\x44\x9e\x5b\x1d\x82\x61\x9e\xd0\x1e\x77\xe9\x63\x9e\x9d\x86\xbf\x2e\x49\x58\x6a\xc6\x4a\x2d\xe3\x3b\xc4\x53\x6b\xf7\x51\x59\xfe\x66\x56\x16\xf5\x9d\xf5\xf8\xed\x16\xdd\x28\x0d\x53\x7c\x91\x06\xc0\xed\x0e\x8c\xad\xa3\x94\x50\xac\x5d\xb6\xd1\xea\xb3\xf8\x7c\x3a\x37\xe3\x32\x90\x1f\xc6\x80\xdb\x52\x61\x01\xf7\x42\x8e\x77\xe2\x28\xd5\xb6\xf3\xab\x72\x10\xd5\x22\xcf\x97\xa2\xd0\x98\x70\x75\x23\x04\xd3\xca\x74\x17\xb1\xa8\xd4\x6b\xbf\xcf\x46\x42\x50\x0c\xe8\xea\x37\x8f\xb5\x6d\xff\x26\x11\xb8\xf2\x90\xa9\xaa\xbc\xc9\x9a\x8e\x0e\xdb\x0d\x30\x56\xb3\xfe\x24\x3e\x03\x4a\xf3\xf2\x73\x82\x09\xd5\x91\x74\xa6\x21\xdf\xfd\x0f\xbf\xf2\xa0\x65\x62\x25\xd8\xfd\x0a\x69\xdd\x91\xba\x92\x80\xcd\x76\xa7\xe7\xe6\x1a\x1b\xf1\x0f\x59\xd1\xcc\x14\x8d\xa7\xdf\xa0\x04\x6e\x4d\x0f\x9f\x7f\x4f\x00\x52\x47\xd2\x50\x54\x50\xb2\xf6\x5f\x65\x56\x2c\x0e\xf3\xdd\x3a\x1d\xa9\x50\xa2\x82\x8a\x55\x3b\x98\x6e\x0e\x5f\xf2\x79\xdd\x19\x74\xac\x88\xef\x2e\xee\x45\x5d\x43\xd5\xcd\x4c\xcd\x63\x6b\x69\x0e\x39\x1c\xda\xfc\xb6\x7c\x84\x8f\x59\x4c\x56\x3b\x96\x69\xc7\xab\xc3\x10\xa7\x3e\x1f\xc7\x1b\x44\xa4\x53\x9b\x42\x20\x33\xc5\x96\x60\x47\xbf\x5a\x4b\x69\x97\x66\x54\x1a\xf1\x95\x3a\x7f\x2d\x10\x72\x65\x01\xfa\xe2\x00\x4f\x85\xed\xe7\x77\x07\x23\x85\xbd\xfc\x4e\x1f\x57\x47\x40\x6d\xbb\xa8\x86\x66\x4c\x5a\xd1\x11\x68\xcb\xc4\xbe\x5d\xbf\x8c\x26\x15\x40\x84\x9a\x1f\x8b\xe2\x00\xb9\xff\xa3\xd1\x11\x73\x95\xe6\xa5\xa8\xbc\x41\x35\xb6\x03\x07\x4a\xd3\xdd\x8f\x34\xa0\x11\x47\x6e\x93\x79\xdb\x28\xb0\x20\xd7\x39\xe8\x9b\xfd\x10\x09\x82\x18\x29\x0f\x8f\xe7\xea\x3c\x9e\x23\x93\xb9\x72\xa1\x14\xae\x49\xa0\x09\x66\xd0\x57\x99\xb2\x33\x30\x5e\x4d\x22\x12\xea\xae\x57\xdd\x6f\x6e\xfe\xa8\x48\x70\x6d\x3e\xdb\x24\xe4\x01\x17\xbf\xf9\x08\x97\x44\x42\x62\x24\x5c\x56\xd9\x61\xe0\x4d\x32\xfb\x2a\x90\xc8\x84\x38\x05\xca\x13\x14\xff\x2a\x0b\xd8\x41\x9e\x7b\x4f\xa1\xa8\x1b\x13\x61\x21\x68\x8b\xd0\x78\x54\xc4\x1d\xcd\x13\x42\x22\x86\x18\xab\x0a\xb7\x4a\x8c\x79\xc7\x91\x0a\x69\x87\x50\x0b\xa5\x3e\x96\xef\x80\x29\xab\x28\x9a\xbb\x4a\x1c\xae\x3b\x78\x6b\x42\xd2\x00\xfd\x9b\x94\x68\xd3\xbb\x7c\xeb\xd2\xc6\xbb\xec\x17\xe8\xef\xe2\xe2\x53\x93\x4f\xc7\x0e\x07\xe1\x9e\x3c\x26\x88\x57\xb3\xcd\xd1\x9b\x41\x62\x65\x58\xbf\x48\x63\x18\x92\xf5\x2b\x24\xa1\xa1\xc1\x0d\xc4\xdb\x3a\x75\x38\x84\xeb\x1d\x5d\x4d\x28\x03\x70\x6b\xae\x6b\x32\x20\x50\xed\xae\xac\xbc\x90\x6e\xaf\x83\xa0\x09\x23\x29\x58\x0e\x0a\xdc\x7e\xff\xd7\x14\x4c\xa9\x09\xa3\x8c\xa5\x83\x84\xe9\x36\xab\x00\x55\xa3\xc6\xd3\x75\xfe\x52\x18\x04\xd8\x66\x6c\xac\x8d\x87\x86\x5f\xbb\xd2\xd6\xe9\xa7\xe3\x2c\x07\x63\x73\xb3\xfc\x82\x90\xa5\x49\xc2\x44\xdc\x11\xd8\x2c\x3d\x77\x72\xa6\x24\xa5\xc0\x3d\xf0\xf1\xae\x02\xf8\xde\x6d\xb7\x24\x51\xdc\x53\xed\xbd\xa6\xd6\x65\xa2\x4b\x78\x18\xc5\x4e\xf0\xf1\x37\xf8\x9c\xb5\xdd\x1a\x0c\xe6\x0c\xfb\x1b\x6d\xa2\x98\x0d\xaa\x90\x9a\x70\x09\xd2\x26\x91\x2e\xbb\xf3\x25\xa6\x41\x62\x44\x38\xc4\xa8\xfa\x7e\x10\x6d\xb4\xb8\x5e\xdc\x76\x07\x8c\xc2\xc6\xce\xb8\xcb\xea\x23\x47\x22\xa8\x96\xe0\xba\x92\x59\xd5\x46\x62\x60\xb2\x5f\xfe\xc3\x32\x05\xec\x18\x34\x5d\xf4\x79\x79\xe1\x0a\x28\x1f\x08\x14\xb6\xfb\xd9\x20\x54\x24\x3a\x56\xa8\x4d\x72\x14\x6f\x80\xee\xb1\xed\xb2\x3f\x96\xc6\xd4\x44\xa7\x04\x97\x12\xbf\x81\xda\x25\x52\x8d\x05\x54\x35\x81\x48\x87\xb2\xab\xc6\xd9\xa2\xcc\xfc\x9e\x46\x20\x26\x48\x1e\xfe\x7d\xd9\x83\xfd\x34\x81\x34\xc0\x3e\x0d\xb2\xfd\xb6\xcf\xeb\xdf\x56\xfe\x88\x61\x26\x74\x51\x98\x23\x8b\x21\xfa\x68\x9b\x1d\xe6\xa8\x29\x9a\x18\xce\x50\x95\x4c\x39\x1a\xc0\x52\x9c\xda\x84\x66\x32\x03\x4c\x1a\x28\xe6\x05\x17\x06\x00\x40\x7b\x38\x0e\xa4\xc4\x98\x66\x2f\xb4\x76\x98\x9b\xd1\xb7\xc4\x61\xc8\xc2\xc8\xeb\x18\x14\xed\xee\x51\xbf\x8e\x23\xa7\x38\x22\x04\xa1\x63\x26\x3f\xd7\xaf\x2b\xdf\x79\xd0\x71\xa4\x0c\xa6\x9a\x45\xe9\x6c\xf0\xdc\xdf\x09\xd1\x18\x7d\xef\x0f\xd0\x38\xa3\x8b\xa6\x3f\x98\x24\x58\x5b\xa9\x26\x3d\x1b\x1d\x13\xc9\x70\xfd\xa8\xcf\xf2\x98\x35\x43\xbb\x82\xd9\xf7\x35\x26\x4a\x21\x66\x20\x73\xfa\x98\x43\xda\xee\x78\x64\x9c\xc6\x68\x8e\x6a\x2f\x73\x71\xca\x5e\xaa\x91\xb8\x86\x8e\x29\xa4\x60\xf1\x23\x2e\xe9\xbd\xd8\x03\xff\xfd\xbf\xa3\xb7\x3b\x66\xa1\x45\x83\x89\xac\xd2\x55\x79\x7a\xb8\xbd\xbf\x84\x8e\xb9\xa1\x89\x00\x0c\x5d\xfe\x89\xad\x04\xff\x73\x13\xc3\x95\x6b\xbd\x2d\x50\x69\x41\xe4\x57\x56\xfc\x98\x07\x1a\xc3\x48\x94\x0f\x36\x98\xb1\xd9\x62\x9d\xb9\xf6\x89\x14\x02\xec\x32\xad\xfe\x58\x2d\x5f\x76\xab\xfd\xea\x8f\xdd\x66\xb1\xff\xbe\xf0\x71\x47\x2c\x62\x8e\x10\x7c\x8c\x4f\x92\xee\xaf\x69\x14\xa4\x7d\xd5\x2d\xfb\x13\x7a\x97\xed\xbf\x59\x91\xf4\x67\x52\xd6\x25\xe1\x13\x44\xd5\x80\xf0\x45\x88\x58\x06\x56\xae\xd9\xe9\x26\xfd\xda\x36\xa2\xab\xbb\xc5\x32\x0c\xb1\xd4\x83\x42\x42\x4f\xe6\x5e\x14\xfa\x41\x14\x9f\x7d\x05\x62\x04\xde\xd1\xb1\x04\xa2\xdd\xe6\x81\x6f\xd4\x64\x42\x29\x0e\x54\x77\x64\x96\x0e\xe3\x76\x57\x95\x47\xbc\x87\x33\xfa\x55\x3a\x56\xa0\xbc\xba\x12\x26\x7b\xf3\xb1\xaa\x1b\xac\x59\x8a\x22\x20\x6d\x32\x73\xb1\xef\x5e\xab\xc8\x7f\x55\xa1\xbf\x50\xe9\xf1\x5f\xc4\x19\x6a\x61\x5b\x7e\x92\xf5\xdc\xf8\xd6\x1d\xe3\x98\x76\xb7\xaf\xdb\x1d\x80\x95\xf2\xff\x1c\xc5\x7b\x31\x08\x83\x11\x0d\x02\x72\xef\xb2\xfc\xb2\x40\xf3\xd7\x56\x9b\x33\x60\x57\x1d\x9b\xc8\x81\xfb\xa1\x79\xf8\x6c\x5e\x33\x25\xf2\xef\x95\x78\x17\x8d\xe8\xae\xcf\x10\xe0\xae\xad\xbe\x1c\x09\x52\xeb\xd8\xa4\x12\xb3\x9f\x47\xf8\xd8\xed\xee\x47\xdb\x97\x63\x77\x6b\x1a\x84\x2c\xf5\x26\x7e\x5f\x1a\x72\x8d\x5f\x01\x1a\x86\x16\x58\x2c\xcf\x76\xf7\xaf\x3d\xed\xce\x1d\x8f\x48\x80\x81\xd0\xf2\xe9\xe1\xe1\xe5\x71\xbd\xfb\xe7\xc8\xb9\xa2\x3d\x1e\xa2\x5a\xef\xf6\xe9\x6e\xb7\x5f\x2e\x9e\xf7\xeb\xc7\x51\xe3\x86\x46\x34\x21\x5e\x00\xdc\x5d\xd2\xfe\x66\x7e\xaf\xa0\x24\x12\x58\xf0\xf6\x6b\x15\x8a\x06\xd7\xbd\x7c\xc0\xf8\xd2\xe3\xc0\x8a\xf0\xbc\x42\x7e\xc2\xbc\x6a\x34\xaf\x69\x4c\x53\xd3\x87\x70\x77\x83\x89\x3f\xfe\xd2\x98\x6a\x7c\x9b\x3b\x2a\xe8\xaa\xd0\x83\xbd\x81\xc6\x42\x62\x05\x65\x8f\xba\x6b\x0d\xf4\x96\x92\xfd\xa5\x24\x41\x88\x54\xc1\x53\x05\xef\x59\x9e\x1d\xa0\xfd\x2e\xbf\x5e\x7d\x9d\x51\xd2\x44\x2a\xbc\x4e\x54\x31\xbb\xcf\x24\x16\x45\x8d\xe8\x8a\xc6\x34\x0d\x12\xc4\x3c\xed\x60\x08\x47\xd6\x34\xe5\x1a\x21\x24\x2e\xa5\xbe\xe9\x23\x40\x9a\x2a\x8d\x2d\xfc\x0a\x9a\x2a\x83\x77\xe8\x90\x4a\xe3\x9f\x2e\x52\x83\xcf\xa6\x44\x12\xf4\xbe\xf9\x3c\x4d\x7c\xe1\x34\x15\xca\xda\x69\xfe\x6b\xbd\xdb\x3c\x75\x0f\x55\x46\x0c\x01\x11\xce\xad\xc3\xf2\xd3\xbb\x83\x29\x60\x25\x1b\x7d\x6f\x4c\x03\xd5\xa0\xe6\x44\x55\x02\xc6\xf3\x49\x6c\x3f\x01\x25\x3e\xad\xc8\x1c\x76\xb6\x07\x3a\x7f\x5d\x96\x47\x35\x10\x14\x4a\x58\x2d\x9f\x46\xf7\x00\x08\x41\x54\x94\x0f\x65\x37\x50\x43\xf5\xee\x39\x7d\x93\xdf\x02\xc4\xd8\xb7\xf0\x7c\x7c\x32\x8f\x7f\x8b\x97\xa3\x29\x08\x82\x2f\x48\x01\x1f\x2f\xb5\xf3\xb1\x99\x64\x63\x33\x61\x2d\x35\x2c\x42\x16\xd8\xb9\x78\x16\x99\xbe\xf1\xec\xfc\xe9\x25\x19\xb0\x72\xf5\xde\xcc\xd0\xa5\xa4\xa8\x70\xe0\x7e\x23\x0b\xa2\x80\x5b\xb1\x29\xf8\xb3\xec\xa2\xa1\xa8\x34\xe4\x4b\x6e\xac\x66\x41\x9a\x12\xc7\x18\x7a\x83\xad\x12\xd3\xc8\x9a\x45\x82\x60\x54\xd3\xbc\x66\x95\xb7\xba\xb8\xed\xa3\x10\x16\x89\x18\x59\xac\xae\xe3\xbd\xf4\x5e\xd8\xfa\x5a\x8e\xf0\x97\xff\xfe\x25\x50\x57\xb3\x48\x51\x67\x10\x8b\x65\xdc\x3e\x6f\x61\x31\x65\x58\x18\xb8\x14\xa3\xfa\x32\x99\x63\x31\x95\xa1\xab\x73\x62\xa5\x62\xb8\x63\xf9\x21\x49\x02\x16\x23\x8a\x15\xfa\x36\x6e\xbe\xef\x20\x31\x9a\xc5\x69\x82\x62\x84\x3f\x6e\x96\x0f\xfe\x6f\x94\xd2\x50\x0f\x52\xc4\x62\xf5\xab\x57\x28\x99\xaf\xab\x30\x9a\x86\x18\xbc\x2d\x45\xf1\x24\xdb\x30\x75\xe9\xa5\x19\xfd\x1e\xc4\xa8\x66\x08\x20\x78\xde\xac\xf6\xeb\xe5\xd3\xfe\x61\xf1\xc7\xff\x47\xd9\x97\x2d\x37\x8e\x23\x5d\xbf\x4e\x5d\xf4\x05\x01\xee\x97\xb2\x2c\xbb\x3c\xe5\x6d\x24\xb9\xaa\x7b\xbe\x98\x50\x24\x80\x84\xc5\x29\x8a\xd4\x90\x54\xd9\x9a\xa7\xff\x83\x09\x80\x9b\x68\x57\xff\x7d\x51\xee\x10\xc0\x1d\x4b\x2e\x27\xcf\x19\x2f\xb9\x51\xc4\xbc\xd0\x92\xe9\x5d\x57\x50\xbc\x3a\xf4\xb0\x8a\x22\xad\x13\xec\x03\xba\xed\x0e\x37\x5f\x31\xac\xa2\x24\x88\xa8\x30\xca\xe4\xfc\x37\x3f\x9e\xe7\x4d\xa4\x28\x11\x41\xd0\xad\x8e\xc4\x1a\xd5\xbd\x94\x94\x45\x20\x86\x7a\x23\x1f\x04\x3a\x5c\x77\x3f\xa5\xa1\xfe\x9c\xe1\xff\x5a\x53\xb8\x73\x06\xa2\x54\x4a\x8a\x36\x59\x7e\x21\x7d\x22\xe9\xda\x29\x79\xc5\x78\xaf\x8f\x20\x11\xe4\x4e\x19\xfa\x66\x53\xee\x5c\x81\x9a\x04\xaf\x23\x11\x2a\xc7\x47\x75\x5d\xc0\x43\xf6\x8e\xd5\xec\x36\x10\x89\x24\x8a\x6d\x41\xee\x2d\x1c\xd0\x14\x8b\x4d\x46\x89\xf4\x94\xb6\x56\x8f\x89\xb4\x7f\xc5\x6a\x3a\x92\x24\x37\xba\xf9\xab\x1c\x65\x4f\xe9\xa9\x22\x09\x8c\xcc\x2c\xb7\xbf\x7e\x64\xff\xfc\xcd\x19\x65\xcf\xaa\x12\x45\xc1\x86\x43\xa9\x32\x7d\x7e\xc8\xf2\xf6\xa3\x17\x38\x89\x84\x0f\xa9\x96\x55\xa4\x43\x34\x05\xf6\x24\x74\xe9\x38\x63\x3e\x48\x41\xb9\x63\xe2\x90\x80\x8e\x6f\x13\x32\xb4\x79\x73\x6c\x72\x93\x1a\x19\xb1\xbb\xac\x9f\x36\xcb\xe6\x37\x0c\x2d\x2a\xf6\x82\x28\xb1\x99\xcc\xab\xac\x80\x42\x12\x31\xfe\x25\x6d\xb5\x8a\xbd\x28\x8e\x5d\x34\x6f\x56\x5b\x47\xc5\x5e\x9a\x52\x8d\xc1\x11\xce\xed\xca\xbd\xf8\x90\x54\x63\x76\xf4\xc7\x5e\x0a\xc2\xde\x4b\xb7\xe8\xec\x5e\x61\xb2\x8a\xc7\x2c\xe1\x89\x05\x12\x60\x55\xd9\x1a\xd2\x7a\xf1\x0b\xb2\x61\xb2\x26\x66\x29\x27\x2c\xc7\xc3\xdd\xe2\xe1\x6e\xe0\x0d\xc7\x0c\x98\xb4\xd5\xec\x96\xf9\x66\xf4\x46\x78\x00\x31\x0c\x0c\x78\xac\x66\xf0\x87\x2a\xf6\x99\x4f\x58\xf2\x0e\xc1\x34\x94\x9d\x98\x1f\x3f\xb1\xcf\x42\x43\xa0\xd6\x5a\xbc\xa3\xb2\x46\x15\xfb\xad\xed\x67\x13\x05\x95\xa5\x4a\x9c\x3c\xb8\xcf\x23\xda\x9a\x9e\xbf\x5e\xff\x8e\x7a\x47\xc5\xbe\xef\x93\x5a\x41\x97\x02\x29\x9a\xb5\x05\x33\x4f\x13\x4a\xb1\xaf\x05\x49\x3c\xc2\xa9\x29\x3f\x0f\x43\xc6\x41\xcc\xfc\x4e\xa8\xbd\x81\xdc\x98\x5d\x7d\xc4\x2d\x0e\x24\x83\xc4\x3a\xf7\xdb\xf2\x66\x18\xc9\xeb\x2d\x8c\x38\xd0\x3e\xe5\x88\xae\xef\xd6\x5b\x77\x64\x18\xa4\x2e\xec\x6c\x52\x29\xcf\x39\x48\xbc\x76\xbc\x5e\x1f\x21\x95\x55\x1c\x86\x32\x31\x3e\x95\x6c\xcd\xaf\xb9\xe5\xcc\xf5\x4c\x39\x91\xac\x1e\xb2\xe2\x21\x2b\xae\x4e\xe7\x3e\x49\x1d\x87\x10\x50\x44\xe1\x57\x86\x6f\xbd\x80\xa0\x6b\x8d\x7c\x8f\x10\xe9\x35\x41\x6d\xb7\x03\x9d\x3d\x83\x4a\xf8\xff\x5d\x58\xe6\x24\x48\x54\x1c\x07\x31\x49\xc7\x82\x52\xed\x2d\x5c\x9d\x87\x5a\x0e\xa3\xcf\x1b\xc7\x49\xd8\x49\xa3\xd7\x37\x65\xd5\x1a\x3d\xee\x66\xe3\x24\x22\x83\xb4\x38\x1d\xb6\xe5\xcf\x7a\xf3\x96\x51\xc1\xcf\x00\x52\x15\xc7\x2a\x4a\x1d\x55\x7d\x29\x7f\xbe\x98\xdb\xb2\xf1\xf6\xc9\xfb\x4d\xbc\x34\x32\x52\x76\xa7\x1a\x6f\x07\x72\x47\xc3\x2f\x9a\x58\xfa\xf4\xb7\x4c\xd9\xda\xa1\x4e\xaf\x75\x32\x8c\x93\x38\x22\x84\x4a\x87\x20\x81\x2e\xe8\x17\x27\x12\x28\x21\xe6\x64\x9f\xcc\x16\x38\x3f\x14\x53\xcf\x00\x49\x8e\x50\xd5\x48\xac\x15\x97\x12\x92\x2a\x4e\x59\x08\xca\x51\x24\xe2\xbc\xf0\xae\x8a\x53\x1f\x29\x72\x2e\xa0\x91\x7b\xb3\x48\xb7\xff\x16\x7d\x59\xe1\x5c\x0e\x62\x72\x12\x50\x8a\x00\x1c\xb6\x66\xae\x5d\x43\x9f\xcb\xcc\xf1\x3c\x45\x81\xf3\xe7\x63\x11\x18\x9a\x3e\xf3\xf1\x5c\x28\x55\x0d\x4a\x70\x55\x2c\x42\xa3\xde\x5e\x63\xd3\x7e\x9c\x2f\xf3\xae\xf1\xf8\x06\x44\xa4\x42\xcb\xbc\xfe\x73\x51\xa8\x35\xb1\xa1\x74\x27\x14\x46\x42\x64\x49\x7a\xb6\x03\xd8\x4f\x2c\xa4\xb1\x3a\x68\x65\xcf\x51\x4c\xbe\x97\x0c\x25\x0d\xca\x53\x8d\x95\xad\x7f\xab\x2d\xdc\x77\x3c\x7a\x65\x92\xa4\x81\x43\xa9\xdc\x96\xb9\xfa\x2c\xd1\x1e\x4b\xe0\x14\x82\xad\x4f\x2e\x2b\xba\x2d\xa9\x16\xe2\x7e\x26\x04\x12\x2b\xa6\x29\x13\x78\x75\xf3\xa7\xbb\x6d\x95\x28\x02\x5e\xd2\x40\xc3\xd3\x81\xde\xb5\x6b\x44\x66\x38\xdf\x5f\x0d\xe7\x3f\x16\xcd\x1a\x8a\x9f\x1f\xdc\x8a\xe6\x48\x49\x1b\x93\x62\x7e\x2c\xd5\x54\xaa\x71\x3c\xf7\x74\xe2\xf9\x96\x71\x18\x29\x16\x34\x89\xeb\xc6\x5a\x44\xdc\xc9\x7b\xd3\x6a\x34\xba\x5c\xe2\x79\x1e\x0d\xb6\xaa\x2c\x8d\xca\x97\xfb\x1d\x23\x53\x34\x6c\xa4\xc7\xec\xf4\xa8\x9f\xdb\x69\x37\xd9\x0b\x12\x16\x04\x89\x25\x7a\x6b\x4d\xce\xd6\xc8\x5e\x96\xa7\xaa\xc6\x2b\xa8\xf1\xa9\xb8\x53\x9b\xe6\xa4\xa6\x05\xae\x2a\x61\x61\x44\xc8\xac\x43\x56\x9c\x1a\xac\xef\x0a\x2b\x5a\xe4\x9a\x53\x23\xe0\xdd\x60\x6d\x62\x8e\x59\x43\xba\xcf\xae\x9d\x63\x4a\xc4\x10\xd3\xd0\x5d\xe2\xfb\x40\xd0\x38\x55\x95\x17\x4c\x09\xd3\xd8\x63\xe2\x07\x81\x41\xc1\xb6\xe3\x9d\x48\x14\xeb\xee\x3c\x01\x50\x3c\xda\xb0\xfd\xcd\x4f\xd6\xc4\x8f\x00\xdb\xe3\x57\xff\x7c\xb9\x5b\xfd\xd9\x1d\x8a\x3e\x15\x5e\x39\xa3\x69\x37\x1e\x9d\x49\x10\x69\xe2\x05\xb4\x01\x7b\x93\x2a\x35\xb9\x7f\xcb\xef\xea\xce\x14\xa4\x9c\x7b\x03\x8e\x5a\x22\xc9\xe8\x63\x14\x49\xa0\x7d\x32\xe9\x56\xdb\xe7\xa5\xfb\x2d\x0c\xe3\x01\xf7\xba\xe1\x83\xb3\x4d\x11\x37\xe8\x7a\xaa\x0a\x3d\x4e\x3e\x48\x1c\x31\xf2\x5c\x9f\x9e\x49\x4a\xf8\xf9\xe9\xe9\x7e\xf7\xbc\x5a\xdf\x3d\xb9\x4c\x46\x12\x43\x64\xee\xdb\xe2\x85\x5b\xa7\x47\x94\x4e\x10\xc4\x9a\x99\x49\x22\x8d\x9b\x52\x3b\xd6\xd0\x71\x7c\x26\x49\x13\x4d\xf1\xef\xbb\x87\xee\x17\x25\x08\xcc\x62\xee\x78\x48\x82\x31\x60\x8f\xbd\x7c\xf9\x90\x28\xda\x26\xb1\xd9\x93\x3a\xf2\x24\xc0\x99\x00\x84\x38\x78\xcd\xbd\x93\x66\x78\x59\x5c\x2f\x69\xf2\x0e\xa4\x5e\x52\xe6\x96\xb5\x76\xb4\x59\x27\xa0\x44\x0c\x9d\x5e\x21\x51\xfd\x99\x18\xc6\xe4\x15\x02\x46\x24\x12\xbc\x41\x79\xaa\xb2\x66\x8e\x29\x57\x25\x82\xf9\x5d\xea\x0a\xab\xba\x2c\xa6\xa8\x87\x44\x04\x8a\x96\x39\x07\x7f\x2d\x6c\x99\x43\x79\xcc\xa1\xe8\xd5\xb4\x86\x6f\x65\xbc\x0e\x77\xa4\xe6\xe3\x0b\xc7\x1e\x79\x4e\x65\x3b\xce\x77\x15\x4a\xcc\x7e\xe1\x48\xa2\x41\x25\x02\x04\xd5\x4c\xae\xaf\x5d\xcc\x27\x91\x11\x93\x96\xc5\x7e\xfb\xb0\xfa\x73\xd6\x8b\x4a\x64\x6c\x10\xad\x99\x25\xe7\xde\x60\x9e\x77\x6a\xa2\x24\xef\x76\x11\x97\xbc\x20\xcc\x54\x89\x44\x41\x39\x41\x5b\xd8\xd1\xee\xb9\x59\xf1\x3a\x2f\x48\x3d\xe5\x2d\x36\xa7\x48\x3d\xae\x69\x46\xda\x8f\x7e\x35\x49\xb0\xa4\x5e\x10\xc9\x21\x78\x75\xd3\x3b\xe2\xa3\xaa\x62\xd7\x3d\xe9\xc4\x8a\x1e\xc8\x19\x71\x54\x35\xcb\xf2\x70\x84\xe2\x7c\x75\x3a\x77\x67\x96\x86\xa5\x50\x02\xc5\x54\x3a\x67\xcf\x96\x40\xa9\x94\x09\x45\x50\x20\x77\x69\x3b\x86\x66\x5f\x68\xca\x63\xcd\xdd\x56\x77\x3d\x65\xa1\x56\xa9\xaf\x12\x95\x12\x2f\x91\x18\xca\x27\xa8\x34\xf0\x3c\x12\x89\xf9\x40\x44\xd9\x9f\x5c\x26\x4a\x3c\xaa\x4a\x28\x73\xf5\xa3\xca\x1a\x74\xfa\xc0\xc3\x41\x91\x46\x2a\xa0\xf9\xf9\xfd\x6e\xbd\x72\xeb\x6c\x1a\x47\xe8\x85\x83\xa7\x71\x5c\x01\x97\x1c\x24\xee\x80\x44\x53\xa9\xc3\x50\xf7\x62\xe0\x07\x7c\xc6\x40\xa6\xd2\x84\xc5\x64\x4f\xec\x76\xb5\x1b\x0d\x77\x35\xa9\x2a\xed\x76\x17\x01\x83\x4f\x52\x05\x69\x12\xfa\xb4\x21\x3a\xf1\x99\x6d\xa7\x7f\x35\x95\xa1\x51\x69\xa2\x7d\x49\xb5\xc0\xa0\xbb\x3d\x70\xb9\xcf\xf2\xcb\x30\xd8\xfc\x4d\xa7\x4c\x6b\xc3\x2a\x75\x55\x66\x39\x56\x74\xbf\xf3\x1b\x7f\xda\xbe\xcf\x94\x68\x89\xd5\x2b\x56\x86\x9d\x9e\x22\xc3\xdf\xb1\x32\x0e\xae\xed\x28\x3c\x43\xf9\x36\xf2\xc8\x19\x1f\x2b\x32\xab\x54\xb4\xfe\x77\x7b\xef\xad\xb9\x7d\xba\x4c\x50\xf5\xdd\xa8\xdc\x79\x8d\x7d\x49\xb1\x4a\x85\xe2\xa2\xdb\x16\x37\x65\xae\x9e\x8a\xbb\xe5\x53\xd7\x8a\x92\x42\xb9\x4b\x68\x16\xaa\x3c\x76\xfc\xd3\xe1\x47\xb9\x1d\x7b\x9c\x04\x88\x52\x9b\xaa\x98\xd7\xa1\x9e\xb5\x25\x53\xa9\x95\x4b\xa2\x0c\x22\xca\xa9\x62\x82\xa2\x47\xe2\x74\xa6\x00\x90\x29\x31\x73\xad\x18\x19\x40\x54\xfb\x99\xcb\x7a\x4a\xf6\x70\x31\x38\xb5\x2f\x45\xd8\x19\x3c\x1b\x50\x2a\xc7\xcd\xbe\x3c\x8e\xc2\x0f\x93\xfb\xd2\x51\x02\x7d\x20\xf0\x01\xde\xaf\x4c\xdd\x1c\x49\xf0\x8e\x87\x12\x78\x21\x23\x0f\x61\x0f\x7d\x78\x60\xd9\xee\x9c\xae\x3d\x55\xae\xcc\xa8\xdd\x5e\x4c\x0d\xd7\x53\xb1\xa1\x5c\x95\x81\xdc\x4e\x3c\x34\xf0\xb4\xa0\x8d\xcb\xee\xf3\x86\x74\xfd\x02\x23\xf0\x69\x44\xd6\x9e\x89\x45\x26\x05\x75\x93\x55\x75\xb3\x81\x93\xca\x86\x4b\x0a\xf0\x08\x12\x31\x90\x35\x98\x4f\xe2\x00\x57\xa6\xfc\xe3\xee\xba\x73\xa4\xc1\xd7\x26\x02\x64\xf3\x05\xdf\xcb\xfc\x74\xc0\x51\x8d\x8c\xed\x18\xa0\xd9\x61\x77\x86\xab\xcb\x64\xea\x17\x87\x61\x5c\x02\x02\x54\xae\x34\xdf\xd6\x8c\x4d\xe5\x5a\x14\x84\xa1\xd1\xc1\xfc\x0b\x6d\x2e\x60\xbe\xde\x08\x42\x9d\x92\xf5\x09\x54\xf7\xda\x7e\x8d\xb1\xf1\x00\x51\xc2\xb9\xe3\x7c\xd9\xee\xab\xf2\xad\xee\xea\x8e\x29\xf0\xf8\x58\x76\x80\xd6\x41\xa8\x07\xe2\x00\x29\x34\xf5\x36\xaa\xae\x81\xd8\x82\x92\xea\x7d\xf9\xb6\x2d\x8f\x23\xc2\x08\x05\x89\x1f\x86\xde\x30\xdc\xf0\xf7\x72\x78\x90\xf8\x08\x06\x02\x51\x5c\xa3\xae\xca\xba\xb1\x69\x90\x45\xa1\xb6\x7d\x56\x19\x92\x44\x0a\x74\xfa\x56\x6f\xf3\x01\x09\x48\xfd\x84\xb8\x14\x04\x61\x05\x7e\x62\x31\x2c\x2a\x81\x34\x0e\x69\x67\x5e\x6d\xbf\x36\xe5\xbf\x7e\x60\x56\xf5\x7b\x2a\xa4\xb1\xa6\xea\xa0\xaf\xa7\x76\xf7\x1f\xf8\x73\xd0\x2e\xb7\x49\xa7\xbb\xb4\x5a\x6c\xcb\xa2\x26\xce\xdd\x2e\x9c\x01\x29\x02\x79\x3c\x7b\x23\x9f\x7f\x57\x0c\xe5\xf6\x14\x00\xfa\x56\x8c\xa6\x1d\x17\x94\x1f\x31\x88\x21\x6d\xf4\x99\x8a\x1f\x98\xb9\xbe\x82\xf3\xd8\x2a\xf5\x6e\x4e\xaf\xaf\x58\x37\xad\x4d\xf8\xc9\x14\x06\x09\x8a\xe2\x58\x4b\x6c\x6d\x2c\x92\x97\xb5\x50\xa4\xcb\x3a\x37\x05\x52\x25\xda\x32\x43\x5e\x67\xb5\xa4\xdd\xee\xf3\x2f\xa4\xb8\x47\xbb\x8d\x6c\xfe\x17\x05\xd6\xf7\x76\x4d\x61\x4c\x31\xe5\xa2\x6c\x32\x7d\x5e\x96\xad\x03\x80\x15\xe4\x8f\x65\xb3\x26\x62\xcc\xa9\xa3\x05\x2a\xf2\x29\xff\x4f\x95\x6d\xae\x7a\x79\x1a\x79\x1b\x4c\x6b\xc4\xc4\x10\x27\xd1\xab\xbb\xef\xc9\x26\x6d\xbb\x8e\x63\x9a\x2b\x9b\xeb\x23\x9c\x7f\x0f\x68\x15\x1e\x37\x86\xe0\xa1\x35\xf2\x48\x60\xdb\x7d\x25\xe1\x05\x46\xe9\xe5\xa9\x18\x15\x74\x08\x2f\x04\xaa\x25\xba\xf9\xf3\xf1\xe9\x47\xf7\xa3\x2d\x17\x24\xd5\x1b\xc3\xbe\xf9\x21\x8c\x45\x78\xa0\xc2\x8e\x8b\xed\x02\xc0\x23\x3c\x6d\xcc\xbd\xd5\xf2\xeb\x62\x7d\xeb\xc0\x44\x82\xa5\x29\x01\x6a\xd7\x8b\xed\x6a\xb7\x59\xdc\xaf\x36\xdb\xc5\xed\xea\x7e\xb1\xd9\x76\x3d\x64\xe2\x85\x8e\xbb\x97\x28\x5a\xd7\x78\x3c\x35\x74\x2b\x37\x65\xf5\x00\xc5\x49\x83\x6c\xed\x8c\x6a\xb6\xd4\x54\x09\x1e\x46\xf4\x39\x7e\x2c\x97\xbd\xc4\x9b\x12\x3c\x05\xe7\xb2\x3d\xe7\xe5\x4c\xce\x49\x70\x04\x5a\x23\x76\x29\xdb\x3d\xac\xdd\x71\x7e\xa2\x08\xd7\x4e\xd3\xa3\xe3\xcd\x9c\x0e\xaf\xd1\x2a\x26\x02\x8f\x71\x1b\x3f\x7e\xae\xca\xff\xa0\x9c\x2a\xed\x9a\xaf\xd8\x7b\xbf\x93\xc3\x85\x47\x7c\x31\xae\x56\xd0\xdd\x4a\xa0\x62\xe0\x3d\x41\xeb\x58\x35\x77\x86\xdd\xa0\xb3\xb5\xfe\x8f\xdb\xfd\x54\x84\x89\x47\xa3\x5b\x9b\xb8\x75\x3d\xf8\xce\xae\x87\x34\x64\xdc\x02\x65\x79\xc0\xc5\x2b\x7e\x50\xa1\xab\x44\xa8\x53\x4a\xc4\xef\xb3\xd7\xfd\x80\x85\x58\x89\x88\x87\x54\xeb\x42\xe1\xf3\x5f\x58\x37\x7d\x45\xfd\xe4\x95\xc7\x4c\x1b\xbe\xfd\xf2\xbe\x2c\x8f\x93\xcd\x47\x24\x7e\x40\xb1\x86\x47\x7c\x6f\xae\xcb\x93\xf8\x40\x92\x4f\x89\x24\x16\x68\xe2\xfd\xad\xef\x34\xad\xab\x57\x22\x49\x3d\xc7\x34\xb1\x84\xba\xc6\xa6\xc1\x4d\xf6\x3f\xdc\xf5\xed\x81\x21\xa4\xa4\x32\x18\x1b\xb0\x36\x94\x05\xa6\xc6\xa3\x97\x1b\x50\x22\xf5\x53\x8a\x1b\x75\xee\x82\x13\xfd\x39\x8d\xa4\x07\x5d\x6f\x94\xb4\x5f\xad\x1e\xaf\xaf\x17\xdb\x6e\x22\x40\xca\xc1\xee\xdd\xdf\xf0\xfc\x41\x00\x4c\x08\x4f\x50\xf9\x96\x38\x9d\x0d\xf0\xf1\xa3\x18\xf1\xa7\xc9\x22\x21\xd2\x84\x50\xd6\x86\x39\xb7\x63\x67\x50\x42\x28\x53\x85\x47\xdd\xb7\x25\x45\x11\x0d\x5c\xd8\xb3\x3d\xa4\x17\x80\x2d\xb9\xb1\xf4\xa3\x33\x85\x91\x42\x4a\x13\x41\x5d\x67\x58\xdf\x56\xb0\xef\xb6\x38\xa1\x38\xa3\xa1\x70\x0d\x14\x80\xeb\x7e\x56\x11\xc5\xea\xee\xef\xee\xef\xb6\x5f\x87\xd3\x54\xa9\x98\x8a\x07\x1f\xee\xae\x6f\xd7\x8b\xeb\xd5\x6e\xfb\xd7\xf3\x6a\x37\xe0\xa9\x52\x42\x61\x24\x2d\xd1\xf3\x80\x1c\xf4\x6e\xf9\xb4\x7a\x74\x21\x11\x81\x7e\x40\x33\x70\xbb\x1e\xfc\x16\x85\xa6\xd0\xa7\x14\x34\x99\x6b\xc7\x0f\xf2\x11\x73\xd0\xd4\x8b\x18\xec\x39\x42\xfb\x82\x6e\x82\xca\xf0\x26\xe3\x56\xc7\x46\x05\xc9\x98\x9c\x86\xe4\xd0\x28\x3c\x7d\x92\x8e\x91\x5e\x68\xe2\x97\xf5\x49\x5c\x92\x2b\x28\xe9\x25\x8c\xdc\xb4\x5d\x56\x5f\x55\x88\x2a\x2b\x5e\x49\xd7\xa0\x71\xcb\x51\xe0\xfd\x61\xfe\xd8\x03\x18\x8b\xc8\xd3\xd8\x97\x55\x8d\x94\xb6\x1f\x9f\x90\xc5\x92\x3c\xee\xef\x8b\xfb\x97\xd5\xee\xfa\x6e\xb3\x5d\xdf\x5d\xbd\x50\x8c\xe9\xdb\xea\xaf\xdd\xd3\x8f\xc7\xd5\xda\x79\x95\x92\x25\x92\x72\x59\xa8\xb2\x86\xa2\x9f\xd3\x77\x34\xe2\x7b\xb1\x8b\x4f\xb7\xe5\x49\x96\x68\x32\x23\xf7\x50\xef\x3f\xa9\xfa\x57\x92\xc9\x10\x6d\x7e\xf0\xa1\x2c\xd0\x39\xf1\xd2\xf7\x84\xb2\x25\x29\xff\x00\xf9\xf3\x58\x36\x61\xd7\x04\x92\x0f\x39\x19\x1e\x33\xf9\xf3\x11\x0e\x53\x1f\xc6\xf6\x0e\xfc\x48\x5a\x62\x9e\xbb\x6b\x72\x1a\xd7\x68\xcb\x7b\xf6\xd9\x91\x00\x2f\x9d\x5e\xe7\x33\x98\x72\x04\x22\x0e\x79\x6e\x87\x0a\xb9\xc6\x1a\x2b\x2c\x24\x5e\x65\x86\x89\xff\x6f\xf0\x5e\x2a\x19\x84\x3c\xb0\xc1\xe6\x07\x07\xac\xf9\xd2\xb5\x59\x30\x1a\x55\x74\x56\xd7\x0e\x88\x3e\x85\x2b\x8d\xcf\x18\x86\xd2\x28\x88\x63\x73\x81\x29\x98\x74\x8d\x98\xd1\x40\x20\xf2\x85\x3b\xbd\xc8\xf3\xc5\x7a\xdb\x65\xcd\x3a\x93\x4f\xc6\x11\xc6\xa6\x12\xee\x6c\xb9\x65\xa1\x01\x5b\xa3\xf3\xa9\x3d\x25\x63\xcd\x84\xa5\xe0\xb0\xb7\x40\xfa\x8e\xb6\x35\xe1\x9c\x1c\x84\x32\x57\xe3\xfa\x5b\x99\x80\xd1\x21\xbc\x62\x23\x91\x66\x25\x53\x96\x44\x3d\x21\xf3\x0f\xcc\xcc\xa8\x19\x42\x51\x65\x0a\x06\xe0\xdb\xc1\xe6\xcb\x03\x58\x49\x5b\xa2\xc8\x9b\x4d\xa0\xc9\x54\x08\xfa\x12\x7b\xa8\xfb\xf7\x66\xdb\x84\xa7\xc8\x60\x7e\x2d\xaf\x40\xfe\xdc\x96\x4e\x08\xd6\x35\xfb\x1e\x05\x9d\x74\x76\xac\x6f\x6d\x12\xb6\x6b\x8b\x22\x53\x69\x5b\x92\x20\x18\x34\x58\x3f\xe9\xc9\x8c\x53\x9e\x6f\x42\x33\xe5\xa6\xa9\xc6\xa1\x4c\xa9\x42\x03\xfd\x69\x27\xd8\x5c\xb0\x47\xaa\x54\x84\x46\xdb\x45\xd4\x43\xc9\xdf\x0f\xbe\x88\xd2\xdc\x69\x8a\x98\xa8\x7f\x3d\x1a\x73\xe8\x89\xd0\xa2\x2b\x1e\xcb\x06\xdb\x3d\x68\xdc\x1e\xc7\x64\x20\xde\x67\xc5\xcf\x03\x85\xac\x0e\x38\x6c\x35\xd2\x11\xa2\xdd\x94\x08\x3a\xe2\x82\xc3\xdd\x38\x19\x6f\x50\xee\x38\x08\x88\x58\x0a\x2b\xc9\xbd\x66\xf0\xbd\x95\x27\x63\x72\x9a\x0f\x67\x2b\x79\xeb\x02\xb9\xb6\x9d\xf9\x81\xe3\xd3\x6a\xe7\x36\xe5\x44\x46\xe7\x56\x2c\x30\x35\xca\x46\x7a\xac\x29\x65\x99\x7f\xc7\xea\x52\xf4\x65\x70\x80\x91\x35\x6a\x7a\x00\xf6\x33\x64\x79\xde\xc7\x74\x14\x0b\x35\x69\x0e\xd9\xda\x8a\x8b\xdc\x93\xeb\x16\x29\x42\x0d\x93\xe4\xf7\x61\x68\x0a\x29\x16\x63\xac\x3a\xf2\x71\xd2\xfb\xee\xb5\xa8\xff\x66\x48\xc0\x9e\xca\xf7\x3c\x43\x4c\x03\x75\xe3\xd8\x17\xbb\x64\xa0\x0a\x22\xe9\xb4\xc3\xb6\xef\xc3\x4f\xa9\x82\x94\xd1\xa8\x75\x81\x29\x4a\x86\x3d\x55\xe4\x3c\x8f\x07\xa8\x0a\x52\xee\x68\x39\x6f\x66\x32\xa1\x7f\x4c\x7b\x4b\x30\x15\x12\x07\x7a\x33\x73\xc0\x64\x15\xfa\x1e\x23\x44\xc2\xfa\x6e\xb9\xda\x3d\xaf\x57\x57\x2f\x7f\xb9\x3b\x0b\x63\x4e\x95\xdb\xba\xac\x9a\x53\x81\xbb\x1a\xf3\xfc\x37\xd7\x8c\x7c\x43\x39\x86\x07\xac\x48\xa2\xa7\xfd\xd6\xc4\x0e\x46\xe5\xab\xae\x97\x4e\xc2\x1e\x4c\x75\xff\xf4\x6d\x7e\x61\x54\x31\x0f\x88\xcd\xb0\x2b\x81\xa5\x82\xe8\x0f\x51\x6c\xc3\xf9\xa8\x62\xdf\xa7\x19\x04\x56\xa7\xa0\x5b\x4c\xb6\xa5\x0b\x23\x4c\xf6\xc8\x0b\x1e\x47\xa5\x62\x69\x10\x90\xaf\xd8\x7c\x3d\x1d\xa0\xb8\xf4\x4a\x54\xe2\x85\x49\x34\x2b\x9a\x65\x12\x3d\xc4\x65\x44\x98\xc6\xf3\x44\xa6\x50\xa9\x24\x34\x24\x03\xa0\x0e\x59\xb1\xc1\x66\x55\xfc\xca\xaa\xf2\x32\x41\xa2\x12\xed\x85\x56\xaf\xc2\x4a\x98\xff\xc0\xec\xa6\xac\xee\xa4\x33\x7b\x55\x1a\x02\xd5\x2d\x2c\xee\xd6\xd7\xeb\xa7\xe7\xcd\xc8\x26\x53\x29\xf8\xa6\x60\x83\xea\xfa\x6d\xba\x75\x72\x11\x08\x25\xcd\x85\x06\xeb\xe6\x06\xb2\x7c\x73\x12\x76\x3b\xb8\xc2\xbc\x7c\xfb\x17\x56\xdd\xc5\x40\x18\x7b\x41\x53\x25\xcb\x24\x06\xaf\x44\xca\x3c\xcb\x2d\xa3\xb2\xc6\x30\xa9\x4c\xed\x91\xf1\xa5\xa5\x67\xb2\x96\x70\x52\x59\x37\x31\x94\xef\x39\xfa\xd6\xef\xbb\xb5\x3f\xb9\x5b\xe5\xa7\x84\xc4\x01\xa5\x88\x6d\x2a\x27\xa2\x3c\xd7\x28\x34\xa1\xac\xa5\xa1\xcf\xea\x56\xbf\xf9\xab\x2b\x8c\xa9\xf4\x0a\x2c\xd3\xfa\xc2\x70\x12\xbb\x93\x69\x16\x90\xbb\x67\x58\x6b\x51\x91\xab\x53\x8d\x09\x7f\x94\xd2\x69\xcc\x53\xa2\x77\x6a\xfd\xb2\x2d\xbc\x2f\x21\x97\x5d\xa3\x32\xae\x7b\x7d\x3a\x1e\xcb\xaa\xa9\xb7\x15\x98\x45\x34\xbb\xc4\x64\x8e\x56\x41\xf4\x18\x97\xc6\x50\x7e\xe9\x9c\x70\xf4\x7c\x0e\xd6\x09\xbf\xab\x37\xcd\x49\x65\xe5\xe5\x69\x3a\xeb\x0e\x3d\x4c\xc8\x71\x76\x1a\x4b\xae\x30\x1e\x2b\xa7\x5f\x5e\x34\x99\x5b\xa9\x90\x05\x2c\xee\x3c\xfc\x1c\x5f\x41\x95\xd7\xb8\xaa\xe5\x09\x73\xa0\xa0\xfa\x79\xbc\xb2\x23\x0b\x0c\x81\x7e\x57\x29\xbe\x7a\xfe\x73\x28\x08\xa0\x90\x21\xc6\xb6\xd2\xc4\xa0\x54\x87\x55\x65\xa3\xb1\x83\x9c\x09\x12\xeb\x7d\x66\xee\x60\xce\x8d\x77\x74\x85\x60\xdc\xed\x0e\x6d\xf1\xf7\xe0\xac\xc8\x43\x4f\x98\xdd\xb0\x75\x39\xe7\x42\xe5\xc8\x23\x53\x7c\xa7\xe6\x3d\x0e\xd7\x2b\x36\x4a\xd1\x12\x8e\xbb\xe6\xf0\xde\xdd\x60\x92\x74\x02\x39\xad\xfd\x33\xb6\xa1\xd0\x4f\x3c\x8a\xe5\x1d\xe0\x27\x56\x84\x62\x1b\x9f\xd5\x57\x06\xb5\x64\x19\xc6\x28\x80\x3b\x97\xda\xc2\xc0\xf7\x03\x70\x8a\x98\xd9\x01\x77\x39\x71\x13\x53\x6d\xda\xa5\x43\x82\x41\x04\x71\xe2\x16\x17\xdf\xdd\x4d\x10\xfb\x68\x53\xb2\xcb\xe0\xc6\x0d\xe2\x31\x3e\x6e\x88\x7e\xc4\x30\xd0\x34\x00\x4f\x85\xb9\xdc\x63\xf9\x76\xe5\xd4\x88\x26\x37\x18\x6b\x1f\x7d\xc7\xa0\x63\x04\xea\x8f\x63\xe2\xe4\xfe\xee\xd2\xd0\xf0\x2c\x2c\xd6\xab\x9b\x21\xe5\xb5\xc2\x34\x51\xa9\x6f\xeb\xae\xad\x80\xda\x79\x75\x80\x2c\x9f\x0c\x3b\xf0\x3a\x5d\xa2\x35\x42\x7e\x85\xd3\x17\x00\x2c\x8c\xb5\x83\xce\x67\x45\xeb\x1c\x2f\xaa\x66\xca\xdc\xa6\x10\x7c\xed\xc9\x4e\x2c\xf6\x49\x6b\xb2\x98\xdc\x28\xfb\x30\xa6\x3c\xdc\x6d\x10\x54\x42\x96\xd3\xce\x3e\x70\xeb\xcf\xdd\x0d\x92\x3f\x28\x3c\x48\x7a\x3e\x2e\x83\x2e\x18\x4c\x51\xc1\x98\xa1\xdb\x1b\xca\x6a\x99\xb9\x62\xb9\x59\x5d\xc7\x54\x90\x9b\x49\xc0\xec\xab\x49\x5a\xac\x7b\x37\x42\x18\xf1\x2b\x50\x6a\xf5\x7e\x9c\xe5\xd5\x42\x99\x84\x4e\xa9\x62\x88\xa2\xbf\x3a\x0f\xe2\x84\xa8\xb8\xa2\x1d\x6a\xa6\x6e\xee\xff\xf8\xbf\xff\x18\xc1\xb5\x06\xd1\xac\x6e\x23\xf5\xff\xdd\xfd\xea\xfe\x77\xe8\xa6\xa3\xf2\x99\xd1\x25\xb2\xf4\x0c\x2e\xc8\x3d\x1e\x58\x2a\x4c\x08\x6b\xfc\xb5\x6c\xf2\x8e\x1a\x4e\xa1\x92\x91\xb6\xab\x7c\x7d\xea\xef\x59\x07\x46\x17\x74\xdb\xf1\x2c\x5d\x6d\x97\xe5\x6a\xf2\xd5\x75\xe8\x51\xdd\x69\x03\xf5\x4f\xd2\x69\xb7\x87\x6b\x8f\x25\xb4\x58\x5d\x3d\x3d\xbe\x6c\xac\x4a\xcf\x66\x47\x5e\xf8\x66\x7c\x0e\xed\xf1\x50\xf5\x65\x67\xb7\x25\xe4\x43\x82\x23\xed\xa1\x1f\xa6\x1d\x1e\xe1\xa6\xac\x50\x82\x91\x88\xf9\xd4\x88\xd2\xcc\xd7\x44\x96\x76\xb7\x7c\x32\x7a\xd6\x66\x4c\xf1\x37\xc4\xee\xdc\x2c\xe5\x74\xee\x6f\x7b\x10\x70\x86\xa2\xfb\x1d\x65\xe2\x34\x3c\x0d\xb0\xa8\x9a\xa9\x36\xd6\x9c\x07\x92\xf5\x22\x32\x43\xdf\x4e\x73\x21\x85\x1c\x09\xf2\xb4\xcb\xc4\xf8\x93\x68\x3f\x32\xbc\x17\x0a\x73\x07\x9d\x9f\xf6\x40\x43\xa3\x7c\x7b\x82\x4a\x41\x7b\x33\xf0\xe5\x93\x3a\x30\x7b\x54\xc0\x98\x43\x79\x3c\xe9\xf6\xe3\x4d\x65\x27\x94\x0e\xb8\xd9\x6f\xda\x49\x74\xc9\xa4\xa0\x83\xd8\xa7\xdb\x2f\x06\x6c\x0d\x83\x21\xa7\x83\x18\x4c\x30\x0c\x8f\x39\x38\xfb\xb4\x0f\xb0\xea\x40\x4a\x2d\x9d\xdf\xd1\x07\xe3\x74\xa0\x8d\x38\x89\x13\x94\xfb\x32\xba\xa9\x10\x12\x52\xe5\x31\xd1\xa4\xab\xad\x83\x15\xe9\x10\x63\xf2\x0b\xc9\xe8\x1a\x32\x27\xe9\x28\x61\x24\x6a\x62\x29\xf8\x30\x37\x48\xaa\xf9\xc8\x8b\x8e\x54\x42\x15\xae\x3b\x71\x3a\xdf\x23\x7c\xdc\x31\xf6\xb5\xd3\x06\xbd\xa9\x10\x37\x47\xac\xba\x4b\x26\xb1\xa4\x67\x27\x16\x8a\xab\xd3\x99\x2e\x68\x71\x54\x1f\xd3\xfb\x7c\xf8\x97\x02\xaa\x9e\x3b\x37\x02\x45\xbf\xeb\x7d\xd9\xa3\x6f\xab\xed\x5b\x39\xca\x9e\xe8\xd4\x0f\x0d\xc2\xd1\x10\x1f\x4f\x94\x29\x94\x4e\xc3\x98\xec\x69\x2c\x7e\x61\x5e\x5e\x14\x58\x69\xf0\x24\xb1\xc6\x5a\x66\xd4\xeb\xac\xa6\x3c\xb5\x6b\xf5\x25\x61\x97\x4d\x85\x0e\x54\x8d\x25\xd2\xf8\x84\xf9\x40\x0b\xcd\x79\x6c\x37\xe8\xbe\xf7\x34\xc5\x3e\xff\xb2\x65\x6a\xa8\x24\x6c\xe6\xcf\xe8\x53\xfc\x66\xe7\xb0\x87\x2a\xcf\xec\xfb\xe2\x74\x5e\x1d\x8e\xcd\xf9\x39\x7b\xc7\x49\x5a\x56\xab\xd6\x3a\x25\x37\xbf\x6e\x1e\xcb\xe6\x3b\xe4\x9b\xac\x98\xe2\xfa\xb5\xc2\x00\x42\x47\x62\x62\x55\x76\x75\x66\xf8\x1b\xbe\x66\x45\x3b\x8b\x7f\x2d\xba\x00\x99\x7b\x55\x1a\x7c\xc2\x01\x48\xfa\xfc\xff\x28\x27\xa0\x51\xad\x95\xe7\xaa\x80\xda\x4d\xd8\x02\x63\xba\xa3\x95\x20\x51\x9a\x86\x6a\x48\x3e\x79\x47\xe8\x79\x2c\xa1\x55\xd2\x09\xd5\x7c\xb1\xbf\x33\xaf\x13\x74\x74\x26\xd3\xf8\x40\x96\xc6\x68\x40\xb6\x0e\x6b\xd2\x1d\x0a\x1e\x9a\xc2\xd5\x09\x39\x76\xdb\xc4\xa8\x7c\x9c\x20\xac\x8e\x43\x63\x9a\xd9\x40\x8f\x33\xc1\x2d\x40\xc9\x2a\xed\xd6\xc6\x06\x72\xed\x42\x13\x1b\x21\xc5\xe4\x9e\x4e\x6d\x2b\x8d\xd7\x7f\x9e\xb0\xca\xb0\xef\xa6\x4d\x3a\xac\x4b\xa5\x8c\x86\xce\xf8\x92\x3e\x03\x22\x94\xf9\xe7\x29\x93\x3f\x6f\x72\x47\xf8\x83\x5e\xc0\x52\x1a\x44\x54\xd4\x66\x33\xd9\xae\x09\x0d\x48\x5c\x75\x2c\x16\xb3\x28\x82\xb6\x23\x62\xea\x04\x9d\xf7\xd9\xf1\xa5\xa8\x41\x63\x7e\xc1\x8a\x63\xbb\x87\x09\xa7\xee\x3b\x05\x67\x2a\x5d\xbe\x1e\xd2\xab\xcd\x7f\xc7\x10\x3d\x99\x38\x4e\x80\x9e\xdb\x6b\x10\xcc\x40\x2f\x62\x9e\x8e\x7a\xa3\xac\xb9\xd0\x8f\x71\xfd\x7c\x45\xde\xea\xc3\xfa\x7a\xb3\xdd\x2c\xc7\x0c\x47\xe8\x45\xd2\x2c\xf1\x9d\x76\xcd\x4b\x91\xbd\xf7\xab\x04\x7a\x11\x72\x8a\x20\xfc\xab\x2c\x63\xce\x26\x43\x20\x0e\x41\x74\x50\x70\x93\xfb\xfc\x4e\x49\xed\x31\x9a\xd9\x7a\xf9\xe8\x25\x5e\x10\x5a\x2f\xbf\xdd\x2b\xd5\x16\x8a\x9f\xf5\xe4\x9c\x49\x60\x96\xad\x3c\x93\x58\xd4\x78\x11\x08\x40\x2f\x0d\x91\xa8\x9c\x6e\xbf\x3e\x8f\x9e\x25\x8d\x23\xed\x77\xc9\x2f\x34\xb8\x24\x9b\xd3\xfb\x68\x61\xed\x2c\x43\xf4\x52\x8c\xc8\x1c\x59\x43\xdd\xec\xfb\xb3\x82\x67\x58\x53\xb2\x42\x97\xbb\x25\x14\x57\xe8\x4c\xa7\xf1\x5d\x01\x0f\x84\x29\xd4\xfb\x85\x55\x73\xa7\x4d\x8e\xfc\x1e\xeb\x7a\xbb\x87\xe2\x21\xeb\x4e\x28\xe2\x88\xac\x60\xb3\x1b\x7c\x58\x76\xfe\xd1\x1d\x4f\x52\x0b\x33\x79\x2e\xf4\x44\x22\xc9\x98\xdc\x43\xbd\xf9\x99\xe5\x97\xc4\x04\x1f\x0c\x3c\x19\x79\xb4\x0e\x6c\x6e\x1d\x16\x1e\x3d\x19\xa3\x0a\x1c\xa3\x61\xa1\xb3\xd7\xab\xb2\x1c\x90\x1b\xf7\xef\x0f\x99\x49\xca\x52\x9d\xe2\x43\x46\xb5\x9d\x5f\xc6\xf7\x85\x7e\x4a\x2c\xdd\xc5\x40\x96\xdb\x35\x69\xa0\x3a\x47\x3a\x7a\xa7\xd0\xc4\x90\x5c\xab\x8e\x90\xa2\x5d\x1d\xc6\xf8\x86\x08\xe8\x3f\x8e\xcc\x4d\x1e\x4c\xa7\x46\xc1\xd9\x00\x4c\x6e\xb2\xf1\x12\x8c\x8c\xc5\x11\xb1\x7e\xdc\xc2\xe1\xe3\x53\x4f\xd6\xde\xd1\xb0\x65\xdc\x43\x4a\xe0\xb6\x9b\xf2\x4a\x9d\xcc\xb0\x9b\x63\x62\x46\x16\x78\x46\xac\x94\xa6\x6e\x3b\x48\x3e\xad\xc3\x46\x16\x30\x21\xbc\x9e\x55\xbd\x9d\x9d\x56\x63\x1c\x59\xa0\x12\xee\x1b\xff\xc3\xd4\x3a\x1f\x73\x90\xf3\x02\xb3\xc8\xa2\x90\x53\x6c\x59\x1b\xfa\xb6\xab\x53\x55\xac\x8d\xd4\xc4\x97\x19\x5f\x0b\x59\x94\x26\x9e\x74\x5c\xc2\xa2\xdd\x1a\x44\x8e\x33\xe4\x73\xc8\x62\xa6\x62\x83\x91\xa9\x6f\x4e\x3d\xe9\x0c\xb2\x98\x23\x11\xc3\x39\x17\xe1\x2b\x15\x7c\x0c\x5e\xee\x14\x55\x39\x39\x6f\xc2\xa8\xb2\xe3\x54\x18\x72\x1a\x17\x30\xba\x88\xbd\x20\x8b\x53\xc0\x21\x12\x7d\x36\xb4\x80\x2c\xd6\x3c\xb5\x9b\xed\xe2\x79\xbd\x7d\x9f\x7c\x9b\x24\x14\x54\x57\x70\xb5\x5d\xf5\x75\x70\xc8\x92\x08\x89\xda\x7a\x8b\xb5\x55\xf7\x73\x0d\x32\xa0\x52\xb4\xfd\xa9\x2a\xa5\xfb\x31\x65\x46\xa5\xfa\xb5\x84\xbc\x4f\x9b\x20\x83\x20\x91\x43\x7c\xed\x03\x36\xfb\x52\xdd\xa9\xbe\xdd\x90\x29\xd5\x36\xbe\x41\xcf\x31\x17\xa2\x40\x06\x36\x91\x5f\x16\xcf\x70\x2e\x4f\x1f\xec\x84\x0c\x54\xc8\x6c\x76\xc3\xea\x65\xef\x9e\x26\xf9\x4f\x64\x82\x19\x91\x6b\x69\x29\xe0\xdc\xcf\x1c\x3d\xed\x64\xa0\x89\xf6\xe1\xb9\x35\x34\x5d\x3d\xcb\xf8\x1c\x32\xe6\x3a\xe8\xa5\x4b\x6e\x66\xbf\xd6\x68\x70\xc9\xc4\x08\x97\x2e\x97\x0e\x19\x62\x1b\x14\xf7\x63\x1b\xc0\xdf\x94\x55\x83\xca\x38\x8d\xe3\x88\x31\x32\x15\xa5\x51\x5f\x01\x72\x9f\x89\xf9\x17\xa5\x14\x98\x3a\x42\xeb\x5d\x99\x70\x9c\xbb\x16\x7a\x86\x48\x53\x95\x94\x48\x19\x23\xd4\x2f\xbd\x26\x64\xe8\x9b\x97\xf2\x0b\x4e\x79\x67\x4c\x0d\x7b\x70\xcf\x8f\x5c\x69\x1e\x7d\xbf\x07\x6c\x40\x41\x03\x57\x50\xe3\xcb\xfa\x6e\xd2\x39\x00\x1a\x11\x5f\x9f\xae\xef\xab\x4d\x99\xab\x1f\x33\x38\xf4\xd9\x25\x8d\x7b\xc2\x58\xb5\x2e\xec\xbe\xc8\xf3\x97\xa2\xbe\xa8\x24\xb2\xbd\x59\xa8\x49\xab\xf9\x55\x34\x23\x48\x08\x72\x16\x0b\x9d\xf4\xab\xcb\x4b\x21\xcd\xf6\xd6\x8e\x97\xae\x13\xf7\x59\x60\xb9\x67\x09\x83\xd9\xfd\x1e\x05\x4e\x91\x71\x53\xc0\xb1\xde\x97\xcd\x04\x8d\x33\xb9\x6b\x1e\xfb\x60\x23\x09\xed\x36\xc9\xc3\x68\x5b\x92\xd4\xf6\xa4\x9b\xd6\x64\x68\x2f\xf3\x4c\xfe\x5c\xbf\x5c\x7d\x82\x17\x40\xee\xfb\x1e\xf1\x47\x19\xf7\xee\x3a\x83\x43\x59\x4c\x79\xfd\xff\x06\x3f\x8a\x3d\x5b\x10\x45\x44\xc8\x74\xb7\x7c\xda\x62\x75\xa0\x0c\xa6\x9b\xa1\x3c\x40\x8f\xf7\x81\x06\xbb\x78\x2e\xea\x67\x2a\xc9\xee\xb3\x1b\x6e\xa8\x7e\xaa\x4b\x3b\xba\x6a\xa8\x24\x25\x60\x68\x69\xe8\x7c\x61\xe4\x11\x37\xc4\x46\x26\x5c\xd5\xe0\x03\x09\x2d\x0f\x73\x79\xb3\x0b\x27\x8f\xb4\xf2\x5d\x84\x90\xf6\xeb\x6e\xa1\xe4\xb1\x1f\x75\x25\x6c\xed\xf4\x6c\x9d\x37\xaa\x79\xed\xbe\x76\x1c\x2a\xa2\xb4\x3f\x94\xf2\xe7\xae\xf5\x4a\xee\x2e\x95\xcd\x5c\xd7\x14\x7c\x1b\x1b\xdc\x89\xf1\x97\x77\x3d\x20\x25\x96\xbc\x7f\x9c\xf2\x1c\xaa\xa5\xe3\x32\xe9\xae\x05\x18\x28\xb7\x19\xca\xb2\x52\x5f\xcb\x5c\x4d\xa2\x28\xc8\x13\x30\x35\xb0\xd0\x34\x20\xf7\xfd\x49\xe6\x6f\x2a\x11\x06\xe1\xf6\x17\x96\xff\x19\xdb\xbb\x3c\xd1\x3c\x1d\x84\xff\xb6\x3d\x01\x1e\x72\x48\x55\x60\xe2\x11\xc7\xd3\x45\x65\xd6\x64\x1c\x03\x0a\x9d\x1a\xb8\xe9\x6a\xbd\x5c\xaf\xae\xef\xb6\xee\x34\x22\x52\xc2\xee\x30\x57\xea\xb8\x2a\x9a\xea\x6c\xca\xed\xdc\xf8\x60\xd1\xbf\x5d\x57\xa5\x9d\xcc\xfd\x42\xfd\xba\xac\x24\x47\x2e\xb9\x2f\x0c\x75\xf7\x6a\xba\xe6\x72\x19\x07\xe4\x02\xb4\x16\xde\xf0\x03\x4b\xf0\xc8\x0e\x36\xc1\xb2\x7b\xd4\x6e\xfd\x9e\x7c\x19\x15\x46\x14\xbf\xb0\xec\x8c\x54\xf4\xe0\x1e\x42\x81\x4f\x6e\xcb\x33\xbc\xd5\x3d\x5e\x16\xb9\x42\x6d\x56\x37\xf2\x17\xca\x23\x39\x26\x0d\x1c\x9c\x8b\xc5\xd1\x0f\xc1\x98\x8b\x79\xfe\x5c\x96\xfb\xba\x6f\x80\xc8\xfa\x81\x2e\x4b\xd4\xb7\xc5\x60\x38\x3b\xad\xf6\x49\x3b\xc0\x07\x4e\x08\x47\xc5\xa8\x22\x6b\xb5\x7c\xda\x6d\xfe\xda\x6c\x57\x0f\x3b\x0a\x1a\xba\x76\x1d\x24\x54\x38\x64\x78\x45\x0d\xf0\x61\x51\xb5\xeb\x7d\x9d\xd5\x4d\xef\xce\x72\x2d\x03\x0a\x64\x92\x03\x7f\xc8\x06\x0d\x88\x54\x8f\xb9\x84\xe6\x9a\xe0\x5d\x1d\xfd\x2e\x72\xad\xd3\x40\xf7\x15\x3b\x17\x8f\xac\xb5\xd1\xb4\xde\x90\xaa\x45\x9e\xef\x6c\xe9\x8d\x6d\xf7\x3d\x3f\xa5\xf0\x78\x66\xea\x41\x08\x92\x33\x9c\xfc\xbe\x27\x42\xc2\xde\x3f\x57\xa5\xc4\xba\x6e\xad\x2c\xf7\x6a\x7c\xc6\x4d\x15\xe2\xee\x68\x24\xd8\x4c\xa9\x2c\x56\xbe\x77\x0d\xe7\xae\x97\xef\xa7\x94\xd6\x7b\xd8\x6e\xbb\x9f\xc2\x34\xea\x0a\x67\x77\x36\x96\xd6\xa5\xf4\xd1\xf7\x21\x52\x36\xfb\x74\x0b\xf5\x0b\xe1\x2c\x2c\x85\x68\xd8\x2f\x53\xa1\x1d\xaa\x7e\x20\x43\x87\x6d\x37\x6e\xc0\x6c\x50\x0c\xfd\x10\x43\x43\x33\x8c\x8d\xdc\x53\xd4\xeb\xea\x7c\x47\x01\x92\x07\xac\xda\xcf\xde\x8c\x9f\x3d\x52\x26\x6a\xd7\xd1\x43\x39\xd2\x46\xdb\x1e\x73\x45\x3c\x09\x0b\xf5\xab\x5d\x5c\xd4\x6e\x51\xe0\xa1\xcc\x3e\xdb\x10\xfc\xd6\x2d\x4d\x9d\x2f\xb1\xb6\xd4\x07\x03\x34\x02\xfa\x89\x17\x44\x36\xa7\xd9\x4e\x08\xbf\xfb\x1d\x3c\x66\x01\xda\xeb\xf2\xd4\xe0\xcc\x94\xf4\x53\x16\x9b\x34\x53\x56\x64\x87\xd3\xe1\xb6\x84\x7c\x00\xf2\x46\x3f\x0d\x52\x23\x5f\x6f\x0b\x5b\x2e\x65\x6a\x27\xaf\x0c\xc2\x84\x78\x02\x96\x8e\xe0\x65\x3c\x4f\x7d\x91\x72\x87\x29\xba\x85\x1c\xde\xcf\x93\x1b\x12\xa9\x42\x97\x5f\xa0\x53\x4c\x62\xc8\xe8\x0b\x60\x94\x75\xdb\xb9\xb4\xe8\x22\xcf\x3b\x36\xa7\x7a\x7c\x73\xae\xf4\xba\x3d\x2a\x25\xa5\x8e\x4d\x83\xef\x5b\xc8\x7f\xba\x07\x94\xb1\x4f\x6c\x93\x57\xca\x54\x9f\x6c\x9a\xb2\xea\x46\x4f\xe2\x3a\xa5\xbe\xa1\xf0\x1e\x2a\x19\x75\xa7\x56\xa9\xd1\xf3\x34\xd4\x6e\xf7\xd9\xa0\xdc\xb8\x8f\x20\xa3\x8f\x91\x4f\x05\x39\x24\xa9\xb5\x29\xc0\xe5\x4e\xd1\x47\x08\xa9\x65\x83\xc5\x54\x14\xec\x53\xb3\xc9\xd7\x8c\x21\x0e\x51\x04\x06\xbf\x94\x2f\x9a\xa6\xb2\xf8\xf7\x41\x56\x0e\x7d\x0d\x9a\x40\x75\x96\x27\xf0\xf1\x74\xb0\xf9\x52\x0c\x3c\x3f\xa6\x6d\xb2\x5d\x7f\x07\xbc\x26\x23\x97\x37\xf0\x52\x4e\x1f\xe7\xe6\xe9\xe5\xf1\x7a\xb5\xb6\x69\x0e\x77\x0a\x16\x44\xc2\x1b\x30\x59\x2c\xcb\x83\x68\x2d\x8e\xac\x2c\xbe\xa1\xf9\xce\xc9\xff\x05\xff\x76\xbd\xc3\x84\x10\xc9\x96\x0b\xc8\xba\xd0\xdd\xb9\x04\x52\xe0\xc4\xa4\xf3\x16\xc7\x63\xee\x82\x1f\x53\xe4\x3d\x06\x4c\x1b\x92\x1d\x22\x70\xc8\x47\x64\x8a\x18\xf0\x28\x75\xe5\x34\x1b\x59\xc1\xd1\x12\x0c\x5c\x9f\x2a\xb8\x8c\xef\x05\x81\x87\x14\x5c\xdf\x7e\x5b\x5e\x8f\x14\xcb\x7e\x0b\xd8\xc7\x20\xe0\x29\xb3\xa6\xc8\xc2\xd6\xe2\x92\x0e\xac\xcd\x92\x9e\xfa\x72\x04\x0c\x02\xdf\x97\x76\x16\x7c\x87\x6a\x7c\xc7\x81\x30\xe7\xf9\xb6\x78\x5e\xfc\x35\xcc\xfc\xce\x2d\x0f\x41\x20\x19\xc5\x5b\x75\x56\xa8\x5d\xdb\x62\x25\xb0\xec\x97\xb7\x2e\x63\xf7\x05\x03\x8c\x1c\xbb\xc0\xf3\xdd\x0e\x55\xd6\xec\x98\x37\xbe\x7e\xe8\x73\x22\xa8\xb4\x16\x50\x6d\x04\xca\xc6\x93\x30\x08\x15\x12\x61\xd9\xad\x29\xa2\x99\x82\xb3\x31\x88\xb8\x8f\x66\xf1\x21\xfe\xe0\xa9\x47\x72\x11\x5b\x0c\xa2\x20\xa0\xd0\xd4\xa2\x96\x58\xa8\x5b\x57\x9b\x8e\x41\x14\x21\x9a\x1a\xd2\xec\xf5\x15\xab\xef\x65\x2e\xa1\x28\x57\xd5\xe9\xd8\xc7\xa5\x31\x48\x55\x08\xa2\x8f\x3b\xdf\x15\xba\x5c\x90\xda\x4c\xbb\xba\x8f\xef\x1d\x18\xa7\x9c\xc8\x15\xea\xb2\xc2\xe5\x3e\x3b\x1a\x96\xa8\x2f\xa3\x37\x05\xca\x10\xc6\xbd\x61\x66\xe4\x35\xd4\xe4\x34\x22\x8c\x9c\xde\xe4\xb7\xc7\xe5\x05\x1f\x2e\x06\x02\x02\x13\x6c\x7a\x83\xe3\xef\x6a\x18\x3f\x9f\xe8\x81\x10\x26\xed\xf8\x75\xc2\xea\x8e\x81\x50\x01\x21\xd1\x69\x12\x2d\x6c\x19\x70\xdd\xb7\x6a\x1e\x0f\x22\x16\x56\xb9\xc0\xb5\x6a\x6d\x54\x77\x48\x3b\xf7\x35\x2b\xbe\x8c\x2e\x2a\x23\x34\xbe\x2b\x34\x59\x53\x7e\xe9\x7e\xd5\x14\x1d\x11\x50\xe3\xce\xec\xc7\x35\xa2\xda\xc1\x20\x5f\x83\x81\x8c\x63\x3f\x1a\x54\xeb\x15\xe7\x7b\x28\x14\x91\x75\x74\x3e\xc3\xac\xf3\x10\x48\xa9\xa4\x59\x4d\xeb\x53\xde\x50\x31\xae\x6d\x51\x2c\x96\x4e\x2c\xf6\x54\x28\xca\x46\xcd\xd2\x4c\x61\xa0\xb4\x4f\x38\xc9\xaf\x6b\x42\x68\x0f\xa3\x1c\x81\xd2\xa9\x3f\xa4\x11\xa2\xba\x36\xdb\xa6\xd3\x90\xf0\xdf\xc7\xec\x88\x03\xa4\x32\x86\x5e\x20\x2d\xf1\x63\xc7\xa6\x33\xb3\x9d\x86\x2c\xf0\x94\x11\x20\x29\x6b\xdc\x5a\x35\x22\x9d\xe5\x38\xd4\xf6\x70\x43\x2c\x64\x91\x91\xff\x78\x7a\xb8\xfb\x7e\xb7\xd8\xae\x1c\x54\x07\x43\x96\xca\x40\x8e\xb2\xec\x0f\xa5\x1a\x14\xa6\x62\xc8\x20\xf5\x1c\x7c\xc4\x70\x73\xb4\xa6\x58\x3d\xc5\xc7\x4c\xaa\x50\x30\x64\x52\x10\x3f\xd8\xee\x21\x2b\xb0\x8b\xd6\x84\x3c\xf4\xc9\xd2\x75\x0f\x47\x21\x9b\xbd\xf1\x5e\xc6\x27\xe0\x69\xe4\x48\xb2\x1f\xce\x5d\xfa\xb1\xbe\xca\x41\xfe\x34\x51\x3b\x52\xcd\x46\x07\xa2\xc5\x90\x03\x98\x89\xd2\x40\xd5\x5c\xb5\x2f\xb0\xbf\xac\x04\x62\x4e\x59\x3f\xdd\xaf\x76\x9b\x97\xe7\xd5\xba\x6b\xd1\xb1\x08\x9d\xd2\x7b\xb3\x2d\x9f\xe1\x7c\xa9\xf6\x8e\xa1\xef\x7b\x12\x5c\xc2\x85\xce\x5d\x3b\xdc\x58\x32\xc5\x46\x4d\xde\xbe\x9f\x1a\x70\x5b\xdd\x43\xad\x17\x85\x32\x92\x0e\x5f\x66\xd6\xce\xd0\x07\x9f\x80\x8d\x1b\xec\x88\xe7\xe6\xd5\x3b\x31\xf4\x51\xbb\xf8\x1d\x99\x6a\x63\x74\xbc\xed\x14\x70\x4d\xeb\xc3\x42\x51\xb9\xd8\xdf\xcd\xa3\xda\xa3\x43\x4f\x9a\x08\x35\x54\x5b\x78\xcf\x46\xe1\x35\xd7\x85\x23\xe5\xa4\x1f\xa0\x2a\x32\x1c\x78\x3e\x61\x18\x33\x61\xc7\xd7\x16\x8a\x9f\x1b\x07\xd1\xec\x9e\x35\x62\x8a\x62\x49\x7d\x96\x39\x2b\x5e\x8d\xb2\x56\x36\x57\x3f\xf6\xc1\x4d\x46\x91\x22\x30\xe9\xee\xe0\x4a\x6f\x3e\x44\x5f\x99\x09\x72\x19\x0b\x0d\xa3\x38\x34\xd8\x84\x77\x17\x93\x0c\x63\x34\x00\x73\xca\x8e\xaf\x1d\xb5\xc2\xac\x73\x1b\x26\x5e\x64\x24\xeb\xa0\xde\xdf\x75\x2f\x20\x49\x3d\x5a\x65\x6a\xf8\x85\x83\x31\xd3\x1f\x96\x8a\x90\x48\x3b\x1f\x50\x41\x9e\xf7\x1b\x4d\x98\xca\x90\xa2\x26\x4e\x21\x78\x4e\x10\x09\x43\x88\x42\x4a\x14\x3e\x5c\xdf\x2d\x9f\x08\x21\xc3\x7e\x87\x3b\xfb\xe0\x15\x8a\xc0\x27\x3b\x89\x4a\x63\x5d\x59\xbc\x89\xfd\xb9\x5b\x12\xca\x70\x89\x98\xc5\x69\xac\x69\x3d\x7c\x93\x32\x62\x84\x92\xbb\xca\x9a\xe5\xbe\xac\xd4\x6f\x42\x0f\xa1\x62\x40\xab\xd0\xaa\x18\xf1\x56\x60\xa8\x38\x06\xcc\x5a\x7a\xcb\xb2\xfa\x4d\x0a\xb0\xed\x4e\x98\xb2\x9d\xd5\xdf\x2e\x4b\x9b\x46\x48\x26\x1d\x31\x8a\x08\xee\x44\xfe\x56\xbb\x59\x3c\x40\x3f\x66\x31\x01\x48\x3b\x1f\xb0\x47\xe9\x63\xa8\xfd\xc0\x18\x35\x27\x31\x38\x6d\xd2\xb5\x1a\xeb\xda\x0c\xe5\xd5\xdd\xf3\x40\xa8\xf0\x43\x6b\xae\x3d\x8a\xe2\x0e\xcf\xc4\x72\xd6\x5d\x29\x65\x2e\xdc\x64\x33\xae\xe3\x35\x45\xcb\x84\x28\xae\x8c\xa6\xeb\x3e\xab\xd4\x8f\x0e\x7d\x83\xa1\xd6\x01\xa1\xa6\x9b\x0c\x2b\x5b\xe8\x82\x91\x67\x29\x24\x16\x5a\x67\x79\x46\x81\xb8\xc9\x78\xbe\xfc\x92\x91\x97\x7a\x3a\xe8\x05\xdb\x40\x36\xd7\x78\xac\x50\x0e\xc2\x7b\x91\x07\x82\x18\xfe\x9e\x21\x07\xd9\x0e\xf2\x76\x89\x73\x00\x43\x8c\x78\x68\x54\xc7\x36\x98\xeb\x67\x38\xbb\xa2\x88\xbf\x0b\xe2\x18\x8d\x94\x88\x47\x41\xcf\x4a\x76\x03\x79\x2e\x40\xfe\xa4\xdd\xde\x75\x48\x12\xc3\xe9\xe8\x62\xba\x03\x29\x05\x8c\x78\x0a\x46\xae\xb8\xdd\x21\x1e\xf1\x7d\xc8\xcc\x8a\x11\x87\x90\xfc\x58\xf9\xf5\xc7\xd2\x84\x8e\xba\x86\x94\x59\x83\x60\x37\xa0\xbb\xdb\x35\xe5\x31\x77\x2c\xc8\xf3\xab\x42\xc4\x85\x91\xd8\xbd\x32\x9f\xef\x99\x82\x2d\xee\xbc\x7e\x1a\xa7\xc6\x42\xa8\xf1\x22\x56\xf8\xbb\xbf\xee\x1c\xc2\x57\xa6\xc0\xbb\x90\x65\x3b\x61\x49\xf9\x69\xcc\xce\x83\x51\x98\x58\xd6\x63\xe2\xd8\xca\x5e\x8b\x97\xe3\xec\x7a\x12\x85\x29\xa3\xaf\xf5\xfc\x7d\xa8\x1d\x87\x51\xa8\x24\x71\x22\xd2\x4a\xf8\x80\x87\x2e\xd6\x12\xc5\x5e\x40\x8e\xed\x01\xb2\xa2\x41\x62\x78\xdc\x90\x67\xd2\xee\x44\xf5\x0c\xd7\x16\x46\x49\x22\xa9\xfa\xdb\xa5\xd4\xda\x9e\xd3\x52\x65\xdb\x55\x78\x18\x58\xf0\x81\xc2\xaa\x8f\xf1\x46\xa2\x35\x10\x07\x7a\xbc\x96\x67\x6a\xfc\xf6\x85\x0a\x9c\x68\xe3\x22\xcf\x6f\x61\x82\x07\x88\xa4\xaf\x88\x9d\xf5\xea\x7e\xb1\xfc\xb6\x7c\xba\xdb\x74\x0d\x61\xea\x77\x35\x4f\x14\x1f\x98\x21\xfd\xc1\x48\x05\x8c\x48\xb2\x48\xf8\x66\x18\x2b\x89\x54\x98\x50\xb9\xc5\xe2\xeb\x62\x37\x7a\x91\xa8\x65\xe2\xbb\x35\x94\x2c\x15\xe2\x27\x1d\xdd\xfd\xf8\x22\xda\x63\x10\x8f\x5d\x29\xee\x7f\x19\x77\x49\x4d\xf9\x06\xa8\xff\x9c\xea\x66\xe7\x96\xef\x9d\x22\xd2\xba\x6e\x3a\xc7\x1e\x8b\xe9\x7e\x1f\xee\x96\xeb\xa7\x81\xea\xea\xdf\x9b\x7d\xb1\x07\xdc\x41\x62\xda\xd7\x99\xe9\x66\x8b\x87\x63\x0e\x0d\x29\xd2\xd9\x4e\x8c\x21\x25\xc6\x8e\x39\x14\x3b\xa3\x06\x48\x78\x60\xd7\xce\x7d\x8f\xac\x6b\x81\xc5\x1a\x41\x9d\xfb\xdf\x19\x95\xc1\xa8\x8c\x62\x79\xcf\x7b\x2c\xca\x03\x16\x65\x31\x5e\xfa\x62\x1e\x04\x44\x61\x9e\xc9\x72\x9b\xe5\x79\x77\x78\x18\x26\xee\xde\xcc\x4d\x1b\xd2\xfb\xd6\x49\x2b\xc8\x62\x35\x6f\xcc\x0d\xc2\x98\x43\xac\xe5\x90\x5f\xf3\x3b\x54\x59\xef\xab\x5b\xbf\x36\x0a\xfe\x18\xf8\xd3\x31\x57\x11\x09\xc2\x5d\xe1\xff\x60\x54\x5e\x8d\xb1\x1f\xc7\x5e\xea\x32\x70\xa7\x4a\xa2\x59\x79\x3e\xdd\xb1\x62\x5f\xf8\x34\x40\x5d\x75\x4d\xc7\x0a\xd5\x4e\xb3\xf1\x60\x8e\x03\x8f\x11\x39\xd0\xa2\x92\x65\x01\xf3\x5a\x44\xff\x9f\x6b\xc8\xe4\xfb\x06\xa1\x71\xb6\x7b\x86\x2a\xac\xa7\xbc\x54\xae\x2b\x70\xe5\x77\x0c\x4a\xd9\xe1\x74\x58\x15\xaa\x7c\x1b\x84\x56\xe2\x40\x06\x34\xcb\x7f\x40\xbd\xef\x4a\x1c\x6c\x5b\xc8\x63\xe1\x0d\xaa\x2e\x9d\x1d\x3c\x3b\xec\x42\x69\xea\xe1\x57\xdb\xfb\x21\x90\x6d\x6c\xa1\xc7\x71\x94\x2a\xe3\xbe\x9f\x6f\xca\x4a\xa2\x81\x27\x0f\xb9\x9a\x30\x8e\x53\x9f\x22\x38\xe3\x7a\x0b\xd7\x28\x38\xd9\xd2\xbd\x3c\xd4\xfc\xa3\x27\x52\x53\xc4\xc1\x86\x32\x6d\x2a\xd9\x36\xa6\xa9\xef\xeb\x2e\x46\xb7\x85\xd7\xab\xf3\x43\xa9\x4e\x39\x6e\xcf\x47\xc7\x7b\x36\x66\xf3\xc3\x18\x42\x2f\xd4\x43\x4b\x6f\x36\x28\x16\x43\x28\xba\x30\xfc\x43\x56\x34\x8b\x53\xb7\x43\xc5\x80\x31\x21\x92\x48\x44\x82\x4d\x4a\x07\x31\x16\xc8\xc9\x19\x7b\x73\x85\x56\x13\x3f\x36\x16\xa8\x23\x57\xb2\x51\xc8\x93\x68\x2d\xbb\x79\x3c\x44\x2c\xb9\x07\xce\x65\x2c\x0f\xc7\x06\x77\xdc\x01\x2b\x62\xc9\x63\xd2\x86\x5b\x5c\x3f\xdc\x3d\xee\x96\x4f\x8f\xdb\xf5\x62\xb9\xed\x5a\x03\x8f\x3b\x0b\x93\x90\xe8\x4f\x9a\x77\x6d\xa8\x28\xb1\xbd\xfd\xb6\x1d\xcd\x2a\x95\x04\x72\x08\x84\x3b\x4d\x0a\x09\x30\x56\x98\xc8\x4e\xdc\x2c\x13\xd9\xed\xea\xd1\x9b\x71\x99\x63\xe4\x5e\x14\xd8\x2a\x0f\xc4\xea\x02\x67\x15\x63\x20\x42\x4b\xd5\x7d\xb7\xd9\xbc\xac\xae\xc7\x61\xc7\x18\x21\x71\x64\x3e\x37\x15\x22\x05\xad\xaa\x25\x34\xf8\x5a\x12\xe6\x6e\x76\x4e\x25\x1e\x93\x89\xb9\x3d\xc8\x6f\xca\x6a\x69\x73\x38\xa3\x7b\x4b\x98\x97\x38\x2e\x24\xa3\xde\x44\xdf\xf7\x75\x08\xd6\x1b\xf7\x0f\x4d\xd5\x43\x56\x5f\x9d\xce\x4f\xc7\xee\x75\x25\x4c\x4a\x4a\xa3\x1d\x89\x34\xc8\xfe\xc8\x3d\x9f\x6c\x10\xc7\x4a\x3f\x50\x65\xc6\x84\x73\x16\x78\x23\xd9\xdf\x7b\x2a\xa4\xf8\x34\x23\x9d\xf0\x94\xfb\x5e\xb7\x52\x18\x9d\xaf\xd1\x68\x4d\x78\x1a\xd1\xdb\xbc\x5e\x6e\x9d\xaf\x9d\xf8\x81\xe1\xa5\xa4\x18\xd2\x78\x58\x25\xbe\x00\x1a\x00\x75\x56\xbc\xe6\x78\x57\xfc\x2a\x7f\xe2\x8f\xac\xd9\xf3\x45\xd5\x0b\x1d\xfc\x31\x5f\x2d\xed\x4e\x21\x15\x85\xe6\x2c\xcf\x5c\x77\x55\x89\x54\xda\xb9\x2f\x4f\x35\xde\x20\x6e\xf7\x15\xd6\xfb\x8e\x88\x1e\x13\x1f\xa3\x34\x1e\x80\x0f\x9e\x28\xe0\x57\x7f\x31\xfa\xdd\xee\x1f\xdb\x39\x60\x1d\x1b\xcd\x16\xeb\xa6\xb5\x48\xc6\x77\x11\xc8\x98\xde\x76\x57\x63\xf8\xa1\xfa\xdb\xf8\xb8\x90\x79\x26\xde\x35\xc0\xd4\xc3\xe5\x50\x09\x43\x46\x55\x2c\xbf\xca\xd6\x82\xb7\x1a\xfb\x2f\x45\xd6\x4c\xfb\x61\x42\xc9\xad\xed\xbd\x55\xf0\xd8\x6d\xfe\x7a\xb8\x7a\xba\x77\x0f\x1d\x79\x2a\xb0\x76\xc8\xa3\x43\x87\x96\x55\x7d\x51\x9f\x8a\x49\x24\x0d\x31\x58\xbb\x56\x53\x6d\x7b\xbb\x34\xcc\x32\x72\x60\x12\x33\xdf\x33\x4e\x6b\x7b\x67\xf5\x2e\x53\xd3\x0e\x5c\xdb\xcc\x95\xcd\x24\xdc\x43\xdd\xbc\x18\x5d\x9c\xec\x30\x59\x92\x93\x38\x31\x14\x75\x1b\x10\x55\xe6\xf6\x3c\xd7\xa6\x91\x39\xfe\xb0\x03\xe4\xf9\x12\x8e\x5d\x1d\xe9\x73\x6f\xa4\x7f\x30\x80\x13\xc6\xc9\xed\x22\xa3\xad\xf7\x4f\xc7\x9d\x52\x26\x3d\x87\x4a\xc9\x0e\x38\xe4\xd0\x70\x3d\xb8\xe4\xac\xe3\x54\xb9\x29\xab\x35\x2a\x3c\x1c\x3f\x43\x4f\xba\x23\xfd\x80\x30\x00\x64\x3a\x12\x0d\xb1\x7b\xb0\x34\x8d\x89\xe0\xf2\xf9\xe5\x71\x39\x7a\xe2\x54\xba\x4c\x06\xa8\xdd\xdb\x1e\x2b\xdc\xbd\x82\x7a\xc5\xe9\xa7\x4f\x55\x48\x6c\x0b\x94\xbe\x9c\x8e\xbe\x8b\x32\x52\x4c\x20\x35\x08\xab\x97\xe7\x1d\x65\xb5\xaf\xb0\x43\x35\x24\xc2\x53\x86\x8a\x94\x0a\x7a\xa0\xf8\x59\x9d\x8e\xdd\xcc\x12\xda\xf3\xa2\xa1\x80\x29\x59\x5c\x9b\x51\x7d\xf9\x60\x0b\x75\xdb\x70\x22\x34\xd3\xa9\x7d\x90\x3b\xba\x97\x7a\x42\x71\x8b\x89\x8c\x4d\xfe\x2e\x2b\x64\x45\xdc\x69\xbf\x20\xcb\xaf\x2e\xf9\x0c\x86\x73\x53\xb1\x90\xb6\xb9\x6f\x78\xbe\x99\x51\xf8\xeb\x7b\x11\x76\xe7\x1e\xea\xef\xf8\x0a\xdd\xa3\x6a\xc6\x1c\xef\x96\xca\x71\x59\x76\x80\x9d\x44\x0b\xa0\x20\xb3\x2e\x2b\x62\x75\x1a\x2e\x5f\xf6\xc9\xc6\xd7\x48\xbd\x34\xb1\x81\x8b\x66\x75\x38\xe6\xe5\x19\xab\xdf\x84\xf2\x52\xc6\x7d\xa2\xb6\x3b\xc0\xfb\x75\x59\x94\x1d\xc2\x22\xe5\xbe\xb6\xc5\xed\xad\x61\xbb\x6b\x3a\xe1\x4d\x4c\x79\x60\x60\x48\x86\xe7\xd9\x96\xe8\xb5\x0b\xc2\x90\x75\x17\x53\x6e\x19\x5e\x1b\x84\x83\x89\x10\x76\x27\xf7\x43\xb0\x00\x5c\x42\xe5\x10\x15\x70\xd7\x26\x8d\x30\xd6\xb1\x7c\xc3\x6a\x10\xbd\x4e\x7d\xe5\x53\xd2\x8c\x06\x18\x79\x5f\xff\x5f\xc5\xe8\x98\x06\x41\x4c\xb3\x6f\x0f\xf5\xf5\xc9\xa4\xdc\xc6\xd9\xfd\x34\x48\x7d\xc2\xae\xae\xb6\x5f\x49\x33\xe3\xf6\x69\xe1\x96\xae\x34\xe2\x48\x46\xf3\x8d\xe7\x79\x7c\x38\x43\xd2\x48\x68\xcf\xf0\xcd\x1c\x81\x02\x37\xb3\x93\x3f\x4d\x78\x80\x96\x96\x66\x48\x4b\x5b\x5f\x06\x75\xd2\x84\x0b\xda\x1e\xdb\xd5\xe1\xe9\x17\x56\x77\x43\x88\x45\x9a\x28\xf3\xcd\xb2\x22\x6b\xd6\x60\x4d\x8e\x3e\xf7\x98\x26\x2a\xa4\x80\x19\x28\x65\x79\x5c\xca\xa2\x6e\x2a\xc8\x2e\x36\xf6\x59\xbe\x76\x4c\xc1\x0b\xac\xef\x27\xcb\x42\xd1\xc6\x6d\xe2\x7c\x55\x37\x06\x20\xe2\x54\x51\x50\x16\xd7\x98\x67\xbf\x3a\xa1\xa9\xb6\x25\x0d\x0d\x04\x96\x68\xba\xe7\xdf\x85\x60\x86\x39\x02\x8c\xc3\x3e\x8e\x1b\xa4\x22\x65\x54\x19\xfc\x3d\x93\x4d\x6b\xe5\x9c\x0e\xed\x66\xb1\x7c\x1a\xbf\x76\x81\x11\x18\x56\x53\xb5\x6a\xf6\x03\x86\x39\x4c\x85\x36\xec\xb4\x2a\xab\xcb\xb7\xee\x00\x89\x1a\x7a\xb0\x8d\x9d\x21\x0e\x24\x3b\xeb\x7b\xa6\x8a\x2b\xaa\x3a\x7b\xc4\xb7\x31\x43\xfc\x07\x1c\x46\xf3\x4f\xab\x7c\xc3\x49\x7c\xff\xaf\x3f\x47\x4f\xa0\x2c\xc8\x94\xfc\xfd\x76\xb9\xf9\x32\xb9\x7a\xc2\x29\x83\xb2\xdd\x1b\x7e\xfa\x49\x2b\x30\x42\x55\x16\x3b\x45\x24\x22\xdd\xeb\x53\x2a\xa5\xb4\xd8\xcf\xb3\xb4\xb5\xc9\x97\x31\xb6\x14\xc3\x80\xe0\xa6\xdb\xd5\xe2\xc1\x6a\xc3\x38\xb3\x38\xc5\x28\xa5\x38\xa0\xc9\xa7\x39\x71\x8f\xb9\x93\xa4\x9c\xb4\x62\x6e\xaf\x9e\x87\x11\xaf\x14\xc1\x48\xb9\xdb\x24\x2b\xf9\x95\xcc\x33\xff\x8d\xb7\x8d\x14\x45\x48\x68\x3a\x85\xd0\x50\x50\x74\xf7\x8b\x39\xcb\x3e\xd5\xbe\xe4\x96\x29\x30\x49\x92\x6e\xc3\xdc\x4c\x8a\x1b\x52\x1d\x29\xb2\xd7\x1b\xc3\x97\x79\x03\x12\xb7\x65\xfb\x6f\xaf\xfc\x83\xa9\x96\x92\x2a\xbe\x9d\x2c\xe5\x87\x3a\x1e\xa6\x3f\x78\x91\xa9\x2a\xdd\x41\xdb\xd1\xd0\x2c\x98\xfc\xa3\xe5\x51\xe9\xc3\xe6\xe0\x29\x8f\xdc\x40\x2c\xd4\xba\x53\xdd\x42\x60\x9e\x4f\xea\x01\x6b\x0b\x96\xea\x7e\xf7\x0d\x20\xf4\x19\xe5\x29\xcf\x4e\x87\xa7\xee\x2e\x81\xf9\x06\xc8\xdd\x3a\xf4\xb2\xac\xba\x88\x17\x30\x0c\x79\x87\xd9\xbf\x71\xbf\xfa\xbe\x29\x5d\xde\x39\x58\xc2\xf5\xa9\x91\xfb\xa1\x10\xf1\xc5\x3a\x08\xbe\x34\x44\xe3\xf6\x71\xb7\xa5\x0d\x9b\x3d\x80\xc3\x49\x41\x90\x24\x84\x41\xcd\x0c\x46\x7c\x32\x30\x21\x04\x83\xcc\xc6\x42\x95\x55\x3d\x4f\x88\x88\x10\xa2\xa6\x2c\xc4\x11\xaa\xa6\x75\x10\x77\xad\xf5\xa8\x6c\x98\x7c\x77\x80\xaa\xca\xe0\x15\x77\xa3\x1a\x23\x88\x40\x27\xbc\xb3\xe5\x52\xf7\x73\x2c\x3c\xda\xbc\xaf\xb2\x3c\x13\x8e\xd3\x00\x21\xe1\x51\x18\x0e\x40\x19\xcf\xe6\x52\x33\x32\x59\x08\x89\xf0\x08\xba\x85\x05\xe1\xef\xdd\x29\x52\x2f\xa2\x54\x5c\x8e\xba\x19\xa5\x97\x21\xf5\x80\xfc\x9d\x1e\x1f\x55\xdf\x94\x95\x01\x90\xba\x2e\x3c\xe1\xd1\x10\x6f\xd6\xae\xd5\x0a\xdf\x5d\x3b\x44\xd2\xb2\xef\x54\xb5\x39\xfb\x88\x91\xdc\xf6\x12\x1e\xa4\xae\x56\x2d\x2b\x5e\xfb\x3d\xdb\xb5\x4b\x83\x09\x12\xa7\xf3\x28\xb2\x00\x02\x35\xc1\x91\xfe\xfa\x36\x5c\x57\x40\x41\x1c\x75\x3c\x3a\x85\xca\x8c\x63\x31\x7e\x1b\x18\x6a\xed\x62\xfd\x90\x51\x51\x2b\xf6\x32\xf1\x08\x98\x84\x34\xa5\x8e\x86\x20\xf3\xb3\x52\xa8\xc9\x67\x47\x19\x53\x8c\xf4\x66\xf5\x78\xf7\xe7\xe4\xaa\x1a\x3d\x1a\xdd\x59\xbd\x38\x60\xa1\x50\xad\xa0\xca\xcf\x5d\x71\xe0\xa8\xb3\xf0\xb8\x17\xdb\xe2\x8b\x97\xbb\xa2\xd9\x9e\x8f\x2e\x90\x6a\x36\x3c\xbb\xdf\x09\xce\x12\x8a\xaf\x03\x15\xb2\x3f\x40\x91\xe9\xd6\xad\xb8\x99\xca\x54\xa2\xe0\x5c\x04\xa1\x45\x3c\x1a\xa6\x28\x31\x53\x93\xe8\x3a\x87\x8a\xf9\x44\x5e\x31\x28\x3f\xef\xce\x14\x22\x19\xe9\x44\xa6\xf1\x7a\xaa\xa6\xf7\xee\xa7\x61\x2c\x7a\x0b\xe7\xda\xea\xa5\xab\xa1\xf4\x9b\xed\x1a\xf0\x90\xf7\xdb\xd2\xe7\x60\x61\x11\x28\x90\xa6\x12\x54\x19\x59\x87\x1f\x88\x3f\xbb\x52\xf8\x76\x31\x95\x04\x14\x5d\xae\xee\xba\x9f\xa4\x88\x22\x0b\x39\x98\xc0\x19\x45\xa8\x0c\x96\xd2\x96\x3c\xcf\x0c\x4e\x11\x22\x70\xec\x9d\x8d\x01\xd4\x5c\xc4\xdc\xc0\x6d\x1c\xd9\x82\x7b\xdb\xa3\x4b\xc4\xa9\x89\xa5\x1b\x2d\xe3\x5b\xe7\x96\x8b\x44\xd8\x2a\x1c\x72\x05\x1f\x50\x65\x30\xad\x97\x46\x91\x72\x3f\x8a\x5c\xdc\x5a\x96\x07\x1a\x34\x86\x1e\xfc\xcb\x05\x06\xa0\x1b\x10\x69\x04\x61\x5f\xc5\xd9\x91\x6b\x51\xed\xf4\x97\xae\x8f\x01\x7a\x3c\xc0\x1e\xf2\x91\x8f\x27\x20\x96\x8e\xa1\xdf\xd2\x79\x0e\x63\xf1\xb6\x93\xe0\x01\xe5\x98\x77\xc7\xb2\xcf\x5c\x7e\x2d\xcb\x4b\xcd\x9c\xf1\xc0\x10\x32\xa4\xac\xce\x03\xfc\xc4\xca\x50\x22\xe1\x1b\x69\x54\x4e\x46\x90\xc0\xc8\xe9\x2b\x58\x0c\xd2\x05\x59\x0e\x0a\x29\x24\xf1\x42\xb8\x38\x0a\xb1\xe3\x13\x0d\xfd\xf8\x3d\x4a\x25\x20\x70\xb3\xdd\xa0\x64\x06\xf6\xa6\x90\x9a\xeb\x01\x5a\xed\x19\xaa\x1a\xe5\x92\x98\x6a\xdc\x4b\x51\x09\x8f\xac\xe7\x6e\x43\xaf\x57\xa7\xf3\x5c\xe2\x5f\xa8\x04\x29\xac\xf4\xe7\xea\xfb\xea\xf1\x65\xd5\x9d\x00\x74\xe2\xe2\x70\x8f\xf8\x66\xf7\x9c\xaf\x50\xff\x0b\xab\x72\x44\x0f\x82\x42\x29\x3f\x05\xf7\xec\x8e\x35\x8a\x12\x6e\x93\x4b\x61\xec\xf4\x4e\xcd\x6c\xa8\x5b\x3b\xd9\x86\x92\xce\x23\x97\xd0\x1e\x81\xcc\x70\x52\xac\x9a\xfd\x7d\x59\xbc\xae\xde\xb1\x92\xd9\x80\x36\xe5\x37\x8c\xa4\xf3\x4b\x9e\xc0\xd0\x0b\x99\xcd\xf0\xfd\x6f\x34\x96\x30\x34\xf5\x45\xb5\x95\x8e\x5f\xe4\xf9\xd3\xa9\xba\x85\x7a\xf5\x2e\xf1\x78\x11\x27\x98\x9e\x37\x61\x96\x7c\xcd\x71\x28\xbf\x6c\xae\x7f\xf4\x53\x1b\x45\xe2\x0d\xf4\x26\xea\xfe\x77\x41\xd0\xf9\x1d\x59\x96\x8b\x42\x6d\x4e\x62\x96\x79\x16\x05\x2a\x85\x36\xa0\xb1\xc8\xf3\xde\x21\xf9\x70\x7d\x17\x68\xd9\x14\x76\x2e\x7d\xf0\xb8\x58\x7e\xb0\x84\x6a\x4f\x59\x8c\x6e\x9e\x2f\xf2\xdc\x0e\x97\x8f\x90\x02\x1f\x9c\x83\x69\x92\x00\xd9\x43\xbd\xa1\x65\xfb\xf6\x04\x15\x14\x4d\x97\x94\x13\x3a\x30\xb8\x4d\x03\x12\xb9\xb9\xff\x7d\xfe\x5b\x68\xe0\x4e\xce\xf8\x3a\xab\x4d\xd2\x70\x58\x92\xdf\xf6\x30\xde\x26\xc5\x88\xca\x1e\x48\x3e\x70\xbc\x47\x3e\x9b\xd0\x4a\x82\x49\x2e\x8c\xb4\x84\x4c\xab\xe4\x29\x84\x8e\x77\xc5\x51\xf5\x8c\x2e\x28\x7d\xae\x0c\x92\xc3\x20\xd2\x87\xfc\x2f\x28\x03\xc6\x68\xf6\x19\x1e\xb5\xa2\x98\xa6\x5a\x65\xc0\x15\x79\x5d\x3b\x13\x1b\xfd\xd1\x1a\x57\x65\xf5\x11\xc3\xd4\xe7\x3b\xb8\x8c\x12\x41\xe6\x5d\x0d\xbf\xf0\x01\x1b\xa0\x99\x37\x86\x45\x7f\x4a\xe2\x3a\xc4\x66\x5e\x30\xbf\x4e\xaf\x25\x22\x13\xed\x6a\xbd\xcb\xef\x25\x31\x81\xb8\x26\x25\xa8\x70\x6e\x93\x1d\x8e\x39\xe5\xef\x87\x53\x4b\xc6\xa1\x47\x21\x4f\x85\x86\x14\xa1\x72\x4b\x45\xd7\x21\xe2\xb6\xbe\xa1\xc9\x7f\xe5\x3f\x50\xd4\xd9\xc4\xe1\x97\xb1\x54\x60\xc3\xf3\x96\x02\xdc\x48\x8e\x7c\xbe\x88\xcb\x18\x8d\x4a\x5e\x33\xcd\xf5\xcb\x24\x16\x8e\xf9\x6c\x5b\xc1\x2f\xcc\x67\x92\x02\x32\x01\x0b\x06\x55\x99\x3e\x8f\x9e\x29\x11\x82\xe2\xf6\xaa\x23\xba\x34\xd1\xd6\xf9\xf9\x25\x13\x15\xea\xb8\x2f\x91\xb1\xa1\x98\xeb\xb2\xe8\xef\x47\xa7\x54\xf6\x7d\xb4\x83\x6e\xa2\x28\xe0\xb6\x4c\x99\x4a\x4e\xf9\xd3\xcd\x49\xcc\x5b\xf3\x32\xb5\x90\xb5\xbc\x2c\x5e\xdd\x2a\xfb\xa5\x6b\x93\x04\xc6\x38\x1a\xea\xac\x1b\xc4\xba\x5f\xb7\x27\x59\x1f\x09\x69\x32\x52\x4d\xd9\x96\x0b\xcb\x31\xf6\xc1\x53\x0a\x3f\xa1\x24\xeb\xea\x54\x95\x24\x52\xec\x2e\x2b\x82\x90\x02\x2f\xd7\xf8\xeb\xe8\x36\x76\x29\xbd\x50\x73\x2a\xfb\xcb\x33\xe5\xec\xae\x0f\x42\xf9\xee\x90\x30\xa2\x43\xda\xd7\xd8\x3e\xda\x34\x93\x25\x65\x14\x50\x59\xc9\x2f\xac\x47\xe0\x0d\x29\xc1\x27\xcb\xbc\xc0\x77\x4a\xcf\x6c\x7b\x0c\xa3\x54\x36\x88\xf9\x5c\x6e\x9e\xb1\x5a\xf6\x39\x4a\xa9\x7c\x4d\x79\x0c\x1a\x3e\x4e\x6d\x38\xe8\x5a\x53\xa3\xd6\xd2\xa5\x88\xaf\xab\xd3\xeb\xd5\xe9\xfc\xc1\x77\x51\x5a\x71\x0b\x49\xb8\x5b\xdd\xcd\x02\x46\xa5\x56\x81\x34\xbc\x3e\x3f\xc7\x73\x48\xa3\x2d\x59\xf9\xcf\xcc\x87\x9f\x5f\x1d\x94\xc7\x34\xe5\x6b\x0f\xf0\xfe\x03\x5e\xb1\xea\xeb\x29\x94\x27\x39\x65\xc5\xee\x33\x8d\x1b\x6c\x76\x9e\x17\x74\x4d\xe8\x51\xbc\x21\x6f\x14\xb1\x49\xba\x95\x4b\x31\xe6\x83\xab\x21\xed\xc4\x79\x06\x95\x05\x8a\x29\x8f\x06\xf9\xb7\xea\x7c\x6c\xca\xdb\x4c\x37\xb5\x25\x1b\xed\xcf\xa1\x19\xd1\x62\x1e\xc7\xec\x5b\xa8\xb8\xe7\x53\xda\x5e\x3a\x2a\x6c\x54\x3c\x60\xae\xbe\x7c\x14\xaf\x54\x3c\xf6\x8d\x49\x4f\x2b\xe8\x5d\xf1\xab\x1c\x72\xfd\xcf\x9a\xe3\xca\x0f\x13\x34\xb6\xb5\x3c\xcb\x1c\x17\xc7\x23\xb6\x9b\x93\x3d\x8e\xf1\x64\x50\xa0\xf3\x87\xfd\xc9\x1d\x1a\x27\x60\xed\xbb\xaf\x67\x51\x65\x2a\xfb\x9f\x21\xf0\xbd\x5c\x30\x54\x10\x1a\x32\x93\x03\x1e\x04\x56\x33\x48\x51\x15\xfa\x3e\x95\x6c\x19\xfb\xdd\x99\x35\xc7\xe1\xb9\xe6\xa4\xfe\xdc\xfc\x57\xa1\x02\x1a\x45\x7d\xdd\xed\xce\x0e\x25\x57\x43\xa1\xa2\x40\x93\x4b\x93\xd5\xbb\x9f\x59\xf1\xba\xd3\x65\xb5\x1b\x94\x07\xaa\x28\x35\x4b\x48\x27\x43\x5d\x95\x6f\xca\x32\xda\x74\x7d\xc0\xc8\xfd\xe2\x21\x6b\x6e\xd0\xaa\xeb\x67\xcd\xd9\xe4\x62\x26\x18\x74\x15\xe9\x80\x3c\x23\xf3\x50\x43\xde\x92\xf1\x74\xb6\xdd\xe3\x58\x11\x17\x87\x15\x08\x19\xed\xa0\x2a\x4e\x7c\x5a\x2b\x6c\x30\x62\xdc\x98\xf8\xda\x11\x27\x0c\xa0\xfc\xae\x51\x7b\x74\x17\xc4\x66\x4e\x5a\x2b\x23\x96\x43\x54\x69\x84\x14\xa6\xb3\x18\x12\x72\x06\x3a\xde\x45\x54\x10\xa4\xa4\x98\xb1\xd8\xa3\xd9\xdf\xae\x2a\xc8\x0a\x5d\x96\x8a\x77\x5d\x22\xc3\x98\x33\x20\x63\xc5\xc9\x1c\x56\xc2\x43\xd2\xd4\xb8\xbd\xbb\x1f\x4e\x61\x25\x83\x80\x0c\xb8\x5b\x38\xe0\x94\x33\x44\xc9\x50\x12\xba\x60\xf3\xf2\xfc\x7c\xff\xd7\xee\xe6\x69\xbd\x7b\x58\xac\xbf\xad\xb6\x77\x8f\xb7\x5d\x9f\x44\x7b\x43\x11\x20\xc8\x2f\xea\x17\xdb\x3e\x24\xe5\x55\x1e\xb1\x98\x04\x97\x6c\x0f\xc5\x4c\xf5\xab\xc8\xd4\xea\xfd\x98\x55\x48\xaf\x6b\x64\x04\x29\xed\x19\xc0\x10\xd1\xf9\x15\x8a\xd0\xef\x53\x14\xf3\xf8\xac\xda\x93\x44\x77\xb9\x5d\x6d\xb6\x14\xa4\xec\x4e\x15\xa4\x44\x5d\x7c\x38\xdf\x74\xa1\x95\xae\x4d\x19\xb6\x64\x50\xea\x3f\x65\x56\xe4\x59\xdd\xec\x4a\xf5\xc1\x1e\x8a\x5e\x00\xe6\x12\xf7\xdb\xc9\x87\x45\xe6\x2b\xb7\x22\xa8\xac\xb9\x86\xb2\x6b\x88\x22\x22\x47\xf9\xb1\x78\x18\x5e\x19\x59\x0c\x24\xea\xb1\xdd\x67\xa8\xbb\x1f\x13\x43\x34\x5f\x95\x39\x1a\x89\xfa\xd9\xe1\x8b\x3c\xb1\xac\x24\xa5\xfc\x69\x7c\xd6\x0f\xee\x98\xa3\x81\x76\x9f\x8a\x1a\x1b\x42\xa6\xe7\x17\xf9\x53\xe4\x1a\x29\x04\xab\xd0\xd0\x31\x7c\x70\x2e\x3f\xe5\xd2\xda\x2b\x0f\xf0\x4e\x70\xfe\x66\xe1\x12\xc1\x4f\xfa\x6b\xd9\x67\x66\x30\xe0\x11\x7d\xe2\x55\xb3\xe7\xc7\x0a\x1f\x37\xcf\xe3\x31\x80\x41\x60\x4a\xf4\xdb\xdb\x59\xe3\x7f\x4f\x59\xf5\x11\x0b\xd2\xe4\x2e\x82\x50\x59\xdb\x39\xcf\x57\x85\x1a\x24\x3b\x30\xf4\x91\xb0\x97\x76\x52\xaf\x07\x9b\xb9\xeb\x11\x7a\x89\xe7\x68\xca\x9b\x3d\x56\x7d\x8c\xc8\x79\x39\x18\xea\x94\x72\x69\x75\x53\x1e\xb7\x08\x07\x27\xf5\x6d\x92\x94\xb6\x53\x2c\x8d\x4b\x7f\x5f\xbe\x3e\x52\xad\xd5\x9c\x9a\xc8\xbc\x80\x60\x7b\xb0\x34\xb5\x15\x15\xde\xc9\xb2\xcb\x6c\x77\xa8\xb0\xc9\xab\x4a\xb5\xa9\x4e\x7f\x5e\xaf\xee\x96\x4f\xbb\xaf\x8b\xf5\xf5\x72\xf1\xec\xee\x04\x52\x4e\x4c\x74\x79\xbb\xd2\xaf\xde\x8f\x0b\x42\xd8\x0d\x60\x4e\x08\xe0\x93\x4d\xd4\x4e\x25\x1b\x99\xea\xe3\xf2\x08\x32\x24\xd0\x08\xd5\x68\xb4\x6b\xf1\x08\xb7\x65\x3b\x49\x89\x34\x2e\x4d\x1a\x6f\x91\x57\x08\xea\xfc\x40\x7a\x2c\xee\x2a\xca\x6e\x9f\xd0\x57\xa8\x39\x26\xeb\x2d\x0c\x89\x3b\x06\xd7\x56\x9e\x29\xca\x21\xa6\x3c\xe3\xb1\x4e\x2e\xac\x18\x23\xf7\xa2\xc0\x37\x4a\x7a\x8c\x66\x81\x0a\xd0\x01\xda\xbe\x97\x0d\x5e\x4d\x2a\xa1\x11\x53\x23\xa7\x0c\x4a\x19\xf9\xb4\x71\xb3\x4e\x0d\x2e\xb4\x75\x67\x5b\xc3\x19\xd5\x8b\xe5\x23\x31\x9b\xbd\x0d\x13\x4c\xee\x48\x2b\x45\x53\xef\xb5\xea\x83\xf7\xda\x8b\x38\x39\x9e\x47\x42\x0c\xec\xf8\xf8\x18\xed\x25\xa1\xea\x02\xa4\xbe\x85\x42\x4f\xba\xa4\x92\x26\x2a\x1a\x05\x16\x67\x8c\x8e\xaa\x4c\x47\xbe\x91\x3d\x8e\xc5\x29\x25\xd7\x4c\xe6\xc5\x40\xd5\x66\x33\x75\x9a\xcb\xc8\xa8\x3b\x52\x45\xce\xa9\x2a\xae\xce\x5f\xa7\x0a\xdb\xa8\x7d\x26\x3c\x45\x14\xe6\x65\x93\xbd\xf7\xe2\x6c\xa8\xfd\x38\x0c\x8d\xc6\x74\x3d\xc8\xee\xe9\x80\x19\x72\x21\x12\x6c\x56\x3d\xca\x63\xf0\x9d\x75\x28\x52\x4f\xf7\x64\x14\xbb\xe9\x13\x5d\x1a\x19\x3a\xf2\x02\x2a\x4c\x36\xa1\x44\x07\xd6\x75\x17\x8d\x03\x46\x8b\x27\xc9\x3e\x62\x6d\xad\xb3\x5d\xd7\x1c\x7a\x49\xd0\x23\xc0\xca\x53\xa1\x9e\x73\x98\x0c\x6a\x1d\x87\x82\x40\xe8\xb7\xb7\xe3\x7a\x8c\x59\x4d\xb8\x3f\x26\xc7\x0a\x23\x44\xee\x7c\x25\x82\xaa\x1f\x1b\x0a\xbb\x8d\x82\x26\x3a\x4d\x62\x69\x6d\x37\x33\xd3\x3b\x67\x7e\xfc\x79\x40\x45\x04\xdb\xc9\x6a\x0b\x40\x1f\x62\x4f\xb5\xf0\x22\xda\x9c\xcd\x7a\xf3\x59\x1e\x52\x0b\x16\x63\x0f\x21\xa4\x55\x79\xd6\xd2\xd7\x02\x22\x69\x0a\x26\xdf\x51\x0d\x73\xa2\x5a\xa1\x20\x90\xd6\xbe\x54\x39\x56\x23\x44\xb2\x46\x1f\x84\xee\x20\x15\x5b\xa8\x7f\x76\x5f\x45\x73\x61\x59\x53\xc9\x47\xbb\xab\xeb\x13\x5a\x55\x95\xf9\x2d\x45\x6b\xe9\x51\x12\xdd\xd8\xd1\xcf\x58\x0d\x90\x5f\xda\xf3\x64\x48\xb3\xca\xa4\x1c\x77\xdd\xa2\xa7\x3d\x1e\x47\x04\x8d\xdd\xbd\x92\xbe\xcc\x2c\x29\x90\xf6\x7c\x21\x59\x1f\x36\x26\x26\x5c\x02\xd3\x40\xa5\xda\xd5\x8e\x6a\xb2\xbb\x51\xaa\xbd\x20\x85\xa0\x2b\xab\xa8\xaf\xa0\xf8\xe9\x2e\x17\x88\x30\x70\xa2\x6c\xbb\x65\x59\xd4\x58\xd4\xe7\x7a\x8d\x20\xf7\xa8\xfa\x4e\x48\x0e\xcd\xf1\x68\xa8\xa6\xfa\x9d\x49\x7b\xa1\xd6\xb4\x84\xeb\xaa\x3c\xfc\xc0\x6c\x5b\xde\x8c\x55\x70\xb5\x17\x85\x9a\xf6\xae\x6f\x50\xbc\xde\x9e\x4a\x77\x60\x24\x13\xa2\x29\x3d\x56\xe5\x21\x9b\x6e\x0d\xda\x8b\x13\xc3\x06\x50\x63\x73\x93\x97\x6f\x38\x0f\x89\x6c\xfb\x99\xb3\xbf\x65\xc5\x38\xdf\xf5\xc7\xb8\x5f\xc2\x42\xe3\x6f\x97\xaf\xaf\x39\x3e\x57\xe5\xa1\x1c\xbe\xa1\x54\x78\xc0\xbb\x50\x58\xbb\xd8\xdd\x62\x31\xe2\x27\xb7\x1d\x81\x33\x27\x39\x4e\x0e\xfb\x08\xcd\x38\x99\xeb\xda\x13\x3c\x8c\xd8\xa8\xc6\xef\x6a\x0c\x31\x73\x6f\x43\x84\x61\xd8\x11\x24\x9b\x9a\xdc\xae\x09\x22\x99\x76\x7c\x8a\xf6\x47\xe9\xf9\x54\x1c\xa2\xcb\xaa\x5d\xe0\x9d\xb9\x30\xbe\x57\xc9\xd0\x65\x51\x09\x43\x34\xaa\x1f\x9b\x1f\x58\x32\xd4\x94\xca\x5b\x42\xbd\x7f\x28\x7f\x5d\xe6\xfa\xe7\x3c\x40\xed\x29\xe0\x69\x32\x8a\x66\xd0\x6e\x6a\x09\xe5\x4d\x6c\xe8\x37\xa5\x51\xee\x4c\xc8\x99\x23\x3a\x38\x15\x07\xaa\xcf\xfc\xfc\x08\xcd\x25\xa9\x86\x39\xcb\x9d\x72\x94\x6b\xd4\xa7\xc9\x0e\xa0\x3d\x1d\x33\x42\xea\xaa\xac\x96\x65\xd1\x64\xc5\xa9\x7b\x9f\x5a\x31\x32\xed\x69\x1e\x34\xfb\x0a\x91\xa8\x2f\x56\xff\x7d\xe9\x38\x37\xda\x4e\xa9\x67\x9d\x66\xca\x55\xdc\xa9\x25\x54\xaf\xe5\xd0\xc8\xd2\xcc\x63\x21\xf7\x3a\x13\xa8\xa3\xd1\xd3\xcc\x8b\x23\x2a\xef\x20\x9c\xf0\xa6\x1d\x3e\x03\x0d\x5f\x37\x62\x18\x0b\x02\xe2\xde\xfc\x9e\xe1\x9b\x49\xd5\x8c\xec\x2e\xd7\x4b\x85\xe4\xad\xb4\xee\xce\x26\x93\x57\xe5\xdf\xb1\x30\x35\xe3\x81\x49\xa1\x82\xd1\xc9\xb2\x0a\x97\xc6\xed\xbc\xdc\xdd\x34\xe3\x0a\x1c\xc8\xcc\x69\x65\x59\xc1\xde\x87\x52\x61\x0f\x1f\x5c\x41\x55\x18\xa6\xf8\x41\x62\x56\x33\xdf\x8b\x23\xd6\x2d\x3b\x9b\xce\x70\x6b\x5b\x14\xd3\x9d\x14\xf8\xdc\x22\xae\x99\x2f\x42\x0a\x89\x3c\x96\x3f\x4f\x0f\x50\x37\x76\x54\xcd\x06\x80\x34\xf3\x15\xa6\x26\x7a\x75\x89\xdf\xd7\xcc\xd7\x8c\x72\xc1\x8f\x28\xab\xf2\x80\xa7\xa1\x7f\xa8\x59\xa0\x34\x55\x8f\xb9\x6a\xf8\x59\x10\xb8\x66\xa1\xe7\x13\xf6\xe0\xbe\x7c\x6d\x57\xdc\x97\xa2\xea\xb5\x76\x67\xa7\x05\x0b\xed\x32\xdd\xfa\xc4\x79\x5e\xbe\x75\xb2\xef\x3d\xfb\x82\xeb\x89\x26\xb4\x7d\x0f\xa7\x42\xee\xd7\xa5\xfc\x89\x93\x02\xd5\xcf\xfe\xd8\x93\x44\x2c\xa4\x0a\xf2\x3e\x6e\xfa\xe7\x5f\xff\xba\x5c\x9d\x5c\xef\x38\xa1\x95\xbb\xc0\xf7\x41\x09\xb6\x66\x91\x4c\x84\xb5\x3d\x57\x54\xce\x8d\x4f\x7a\x09\x87\x23\x64\xaf\xe3\x7a\x10\xcd\x22\x6d\x02\xc7\x1f\xa1\x1d\x2f\x8c\x21\x7b\x5c\xe2\x47\x54\x29\x46\x16\xc1\x88\x18\xd7\x75\x48\x8c\x12\x20\xbe\x37\x58\xa8\xcd\x14\x1e\xaa\x59\x82\x61\x84\x1d\xd6\xdf\x38\x8a\x44\x6a\x4b\x18\x95\xf3\x87\x0f\x9d\x06\x46\xcd\xd4\x02\xc9\xbf\x65\xb9\xdb\x90\x58\x1a\xfa\xb4\xb2\x83\x52\xcf\xe5\x4f\x3c\x94\xc5\xb6\x34\xe3\x6e\x76\x8b\xd7\x0c\x10\xe8\x1e\xb2\x22\x23\x19\x5d\xff\x6f\x17\xd6\xcd\x0f\x61\xc1\x98\xb4\xf2\xbb\x0f\x59\x81\x15\x01\x3a\x2f\x1f\x5d\x28\xcf\xad\x42\xeb\x52\x2e\xcb\x6a\x2c\xb4\xda\x76\x88\x68\x2a\x34\xf8\xde\x4d\x38\x99\xf0\x58\xbb\xea\xbb\xdb\x9e\xd0\x67\xe8\x7c\xb7\xbd\x02\x02\x82\x2b\x2b\x64\x45\x78\x88\xe6\x02\x44\x3d\xbe\x1f\x29\x22\x2a\x2d\x38\xe2\xab\xbb\x9a\x92\x11\x13\x0e\xd2\xf5\x0c\xe7\xfb\x12\xba\xc9\xa6\xd0\x94\x11\x56\xf8\xfa\xd8\x29\x4d\x69\x86\x8c\x53\x40\x32\xab\xad\x88\xdf\xe4\xa9\x91\x4b\x1a\x32\x12\x72\xf9\x52\x3c\x40\xfd\x93\x60\x13\x05\x81\xed\xe7\x6f\x0c\x23\x19\xe0\xa0\xa4\x26\xcf\x51\x36\x99\x98\x29\x80\x1c\xcf\x45\x04\x03\xc6\xfa\x5a\xe6\xb0\x2f\x8f\xa3\xa5\x02\xa5\xf1\x58\x0d\x4c\xe1\x1b\x9e\x2f\x03\x95\xba\x75\xa5\x1c\x73\xd4\x50\x9a\xbb\x75\x18\xaf\xce\x06\x19\x33\x3e\x40\x87\x18\x1b\x99\x11\x45\x7b\xe5\xb6\x1c\x1e\x37\xed\x9c\x70\x82\x45\xee\x8e\x50\xd5\x78\x57\x34\x1b\x99\x61\xd1\x64\x3a\x93\x43\x27\x52\x73\x8f\x29\xe2\x76\x20\xff\x79\xf7\x9f\x93\x7a\x1d\x51\x10\x8f\x1e\x9a\x7b\x0c\x7d\x2b\xfd\x6f\xc9\xc8\x57\xef\x28\xdb\x29\x75\x0b\xf5\x3d\x29\xa8\x4c\xb3\x5c\xb3\xa3\x98\x7b\x3a\x26\xc3\xcd\x28\xcd\x4f\x92\x9d\xe3\xae\x8c\x33\x2f\x72\x59\x2f\x57\x43\x1d\x7f\x71\xad\x89\x24\x8e\x92\xbb\xe5\xd3\xee\x79\xb5\xbe\x7b\xba\xee\x5a\x74\x4a\x88\x8b\x03\x51\x11\x10\x86\xc0\x35\x71\x4f\x98\x42\x22\xe2\xf6\xed\x88\x64\xe6\x8d\x97\xc9\xed\x70\x66\xe8\xd4\x6c\x05\x33\xd5\x30\x65\xcd\xf9\xb3\x6a\x0c\xcd\x79\xac\x29\xdc\x9a\x1d\x8e\x65\x65\xa1\x53\x34\x71\xa9\x0e\xed\x52\x72\x51\x73\x1f\x52\x57\x97\xbf\x20\xad\x64\x54\x8b\x42\xad\xf1\x3f\x24\x86\xd4\xba\xfb\x17\xb9\x67\x77\xa4\xe4\x8e\x99\xfa\xe9\x88\xc5\x55\xa6\xea\xf1\x82\xcc\x43\xa9\xa1\xd7\x92\xb8\x2a\x27\xd6\x32\x8f\x58\x4a\x5f\xf9\x08\xe7\xab\x4c\xcd\xdb\x80\x3c\x4a\x13\xa3\x70\xd9\x7e\x96\xce\x0b\xe0\x71\x18\x13\x12\xe8\x58\x21\xf9\x55\x93\x4b\xc7\x89\xa2\xf8\xef\xc3\x19\xaa\xc6\xf0\xc7\xb9\x16\x48\x84\x2b\xe1\x75\x06\x62\x35\x71\x51\x78\x22\x13\xde\xdb\x0a\xcf\x15\x0e\x63\x30\x9a\xa7\x51\x44\x0c\xd9\xa2\xca\xe4\xcf\xd5\xf6\xeb\xc0\xa9\xd3\x3c\x4d\x25\xeb\x25\xe7\x2c\xcc\x70\x5e\x46\x46\xf3\x54\x28\x47\x09\xb1\xd8\x34\x65\x75\x21\x64\x3e\xee\x0e\x3e\x9a\x31\x2a\xb3\xba\xee\x90\xe1\x9a\xcb\xc8\x54\xd8\xf5\x35\x8f\x57\xd0\xc8\xfd\xd5\xd9\x15\x3d\x3a\x39\x4e\xb7\xe9\x71\x15\x71\xf3\xdd\x5b\x9b\xcd\xbc\xda\x45\x63\xc4\x41\x5d\x8f\x44\x45\x23\x4c\x7f\x3b\x18\xc6\xb3\x9f\x2b\x19\xa2\xb1\x61\xc9\x13\x75\x87\x62\x18\x90\xa9\x75\xff\xf4\x72\xbd\xfa\xb3\xfb\x35\x49\x22\xe7\xdd\xf5\x39\x8d\x4e\xfd\xc2\x90\xed\xd4\x46\x29\xc1\x1d\x92\xc6\x34\x9e\xeb\x1c\x7e\xd9\xe4\x81\xf5\x56\x2c\x02\x2c\xfb\x5f\xff\x55\xda\x0d\xd0\x33\xb0\xd5\xdc\x4a\xf7\x8d\xdf\x1e\xca\x54\xa6\x36\xa5\x50\xe6\x6a\x7e\x35\x98\x0c\x3f\xd4\x40\x55\xba\x8e\x27\xf4\xae\x68\xca\xf6\xe0\x19\x5f\x7b\x72\xa4\x8e\xb5\xb4\xf6\xcf\xf1\x74\x89\xd4\x33\xbd\x7c\x2f\x44\x8a\x51\x1a\xd3\xa1\x9d\xab\xdf\xce\x92\xc4\xbd\x47\xf7\xee\x7b\xa8\xa8\xdf\x72\xfb\xd4\xa7\xe4\x6c\x1b\xe3\x7e\x1c\x0e\xf8\x65\xc8\xab\xeb\xf1\x62\xda\xe7\x71\x94\xb8\x7c\xde\x49\xf4\x29\x9b\xd1\x9c\xf1\xb9\x64\x89\x03\x60\x54\x59\x31\x8e\x9c\x69\x3f\x08\xc3\x01\x63\xec\x03\xbc\xdb\x34\xf8\xb4\x57\xe4\xcb\x8b\x40\xe2\x68\x63\xf7\x03\xc5\x94\x3f\x28\x73\x5c\x1c\x8f\x4e\x62\xef\x23\xf0\xb6\xe3\x56\x9b\xe0\xca\xb4\x1f\x0a\x19\xd8\xfa\xd1\x0e\x8b\x3c\x6b\xc1\xfb\x91\x6f\x92\x32\xed\x93\x8d\x1f\x3c\x4a\x34\x81\x1a\x56\xef\x4d\x05\x22\x1b\x66\x2e\xb4\x1f\x27\x82\x22\x50\x15\xf9\x70\xc6\x9c\x1f\x9f\x38\xf1\xfc\x40\x76\x9f\x90\x24\x80\x66\x50\x77\xda\x4f\xa4\x81\xaf\x74\x43\xc9\xc6\x3c\xbb\xfb\x48\xbd\x94\xbe\xe3\xc3\xe2\xcf\xdd\xf6\x69\xbb\xb8\x37\x85\x93\x56\x4d\x75\xe3\xee\x28\x0d\x7c\x02\xca\x6c\x5e\xd6\xdb\xc9\xdb\x4f\x63\x66\x88\xf9\x5e\x5f\x2b\x8a\x6b\x0e\xd4\x86\x26\x03\x2f\x05\xe6\x0a\x53\x8c\x27\x3e\x96\x53\x1d\x3f\x22\xf8\xe0\x74\xdd\x9a\x2f\xb3\xa7\x83\xc0\x54\xf2\x83\x52\xc4\x5e\x3c\x94\xdc\x9f\x9c\x2b\x96\x04\x90\xba\x79\x7a\x59\xef\xfe\x5a\x2d\xd6\xbb\x6f\xab\xd5\x73\x97\xfc\xd2\x3e\xa4\x89\x62\x8e\xd3\xd4\x8c\x68\x83\x81\xb2\xed\xc2\x67\x94\x4b\xc2\x42\xad\x8e\xa5\xdc\x4f\x18\x25\xb5\x2f\x50\xfa\xa2\xab\x95\x80\xea\x6c\xc2\x7c\x94\xd3\x1f\x26\x19\xb5\x2f\xd3\x94\xe6\x68\x5e\xbe\x76\xa5\xbb\xda\x97\x68\xf8\x9a\xb2\xa2\x37\x3c\x21\xc7\xd9\xb0\x86\x2f\x51\x38\x19\x93\xd6\x92\xbd\x88\x4c\x6a\x5f\xf9\x9c\x56\xc3\x7f\x9c\xea\xe6\xc6\x44\x48\x26\xe7\x50\x52\x26\x86\x39\xe1\xfd\x16\x6a\xcb\x51\x59\x90\x2c\x81\xed\x81\xcc\xf4\xb8\x2f\x8d\x70\x72\x7d\x29\x2e\xf6\xa9\x39\xef\x63\x68\x04\x0f\x5c\x5c\xe2\x6a\xb9\x7a\xea\x4e\x1e\x05\xe8\x00\x32\x7f\xb6\x1d\x96\xa5\xc2\xc9\x57\x43\xe4\xcc\x6e\x54\x2f\x54\xdc\x31\x2a\x6a\xb7\x9d\xb4\x0a\x89\x1b\xe9\xf9\x6e\xb7\xba\xbe\xdb\xee\x98\xbb\x82\x46\xf3\x49\x5b\xeb\x89\xa8\x47\xd9\x6e\x73\x7f\xfb\xb8\xbb\x5f\x6d\x36\x7d\x1f\x45\xcb\x8f\xd9\x73\x49\xa3\xbd\x35\xa8\xba\x4c\xb5\x0e\x3c\x2f\x88\x0d\xb4\xe6\xde\x80\x5a\x7a\xad\x46\x1d\x78\xdc\x27\x4b\xbe\x35\xc3\x5c\x74\x6e\x51\xb7\xdb\x44\xb7\x43\x04\x2c\x36\xda\x9e\x66\x10\x18\x0c\xd3\x34\xe6\x11\x70\xe6\xd1\x0a\xb6\x78\x2b\xab\x9f\x13\x37\xdf\x76\xf1\xad\x34\x3c\xda\xda\xc7\x01\x02\x57\x07\xbe\xf6\xd3\x0b\x3b\x32\x74\xad\x01\x37\x2c\x2f\x96\x4f\xa2\x34\x84\xf4\x55\xd7\x0c\x01\x45\xf0\x21\xab\xae\xab\xf2\xb8\x19\xea\x0f\x7f\xe0\x45\x06\x81\x60\x54\xe8\xf0\x1d\xf2\xac\xd9\x0f\x17\xaf\x20\xf4\xbc\xa8\x63\xaf\x58\x35\xfb\x35\x10\xb0\xd2\xb5\x86\x29\xe7\x7d\x89\x3a\x1d\x38\x5c\xb1\x82\x10\x14\x81\x76\x0f\xa5\xca\xf4\x99\x68\x00\x0a\x4b\x35\x38\x4a\x33\x4d\x6e\x28\x62\x9a\x72\x1b\x5d\xf6\xba\x5d\x0b\x68\x79\xb9\x99\xa0\x89\x75\x10\x25\x3c\x08\x87\xc8\x1a\xc3\x8c\x87\xea\xaa\xa7\xad\x76\x5d\x51\x50\x58\x0f\x5e\xb1\x68\x48\xb3\xba\x1e\xca\xb2\xda\x5e\xb1\x27\x68\x21\x6a\x4d\x99\x97\xa3\xb9\xec\x44\x01\x4e\x07\x31\x03\x65\xc2\x62\xe5\x3b\xe5\xd7\xe6\xed\xe9\x20\x16\x21\x3d\x49\xeb\x01\x13\x17\xc5\xd3\x8f\x9e\xd4\xaa\x6d\x06\xf2\xbf\x6a\xd0\xb8\x2d\x1f\x4e\xb9\x5b\x1b\x47\x27\x49\x82\xc4\xf1\xd2\x6f\xe1\x27\x4e\x0b\x85\x75\x90\x80\xf6\x86\x22\xc5\x70\x2c\x3f\xa0\x60\x1c\xed\xa3\x41\xa2\x0d\x5e\xba\x5d\x95\x1f\x7a\xef\xa3\x13\x7c\xb6\xdd\x52\xd0\x14\x9d\x5d\x2c\xef\xff\xba\x96\x59\xf7\xf9\x53\x09\x60\x21\xd9\x2f\xf5\x00\x3b\xa6\x03\x08\x0d\x4d\x9c\x95\xa5\x1c\x88\xaa\x2d\x74\x83\x15\x81\x09\xce\x93\x87\x80\xc8\x58\xdc\x76\x17\x74\x08\x03\x1d\x80\x08\x58\xef\xf8\x92\x51\xf0\x81\xef\xe6\x0e\xc0\x20\x4a\xba\x94\xd4\x6a\xfb\x55\x97\xd5\x63\x59\x1d\x20\xbf\x3a\x9d\x3b\xc2\x69\x1d\x88\xc4\x71\x42\x35\x7d\xf0\xef\xae\x7b\x3c\x09\x3c\x31\xbc\xc1\x0e\xcb\xb6\xb5\x91\x3f\xaa\xa0\xb3\x25\x92\xae\xb7\x8a\x91\x0a\x63\x0a\x7c\xeb\x94\x75\xb3\xff\x19\x00\xe3\x6f\xf9\x38\xa7\x21\xa5\x40\x09\x20\x83\xeb\xe9\x79\x3b\x42\x7f\xe8\x40\x29\xa4\x90\xcf\x3f\xfa\xf0\x79\x80\x96\xcf\x03\x44\x5d\xe6\xa7\xa6\xdd\x68\x86\x96\x78\x80\x2c\x24\xba\xd7\xd3\xf1\xb5\x02\x35\xc1\xba\xe8\x00\xd3\xd4\xe1\x8c\xf2\x1c\x8b\xd7\xa1\x27\x13\xe8\x38\xa6\x14\x53\xe3\x36\xc9\xbf\x25\xa2\xa3\x03\x9d\x9a\x72\xd0\xfa\x74\xc4\x8a\x5e\xdf\xd0\xfc\xff\x63\x78\x05\xc9\x53\x63\xfe\xe8\x81\xac\xb6\x0e\x3d\x0e\xcc\xd4\xa7\xe7\xa7\x03\x76\x90\xde\x39\x6a\x1b\x1d\x32\x3f\x22\xf8\xa5\x6c\xca\x71\xfc\x28\xe4\x3c\xa4\x50\x8c\x2a\x0d\xb1\xeb\x30\x4b\xa6\x43\x1e\xa5\xe4\x84\x92\xa0\xc0\x80\xf9\x58\x87\x5c\x4a\x3f\xec\x17\xb7\xea\x54\x37\x56\x51\x74\x58\x7a\xeb\xbe\x58\xe8\x73\xe1\x18\x6d\x9c\x90\xfb\x78\xcd\x08\xfd\x20\x26\x30\xb0\x21\x1b\x7c\xa7\x4c\xf7\xdf\x4d\x68\x1a\x11\xfb\x3f\x2e\x5e\x5e\xe8\x87\x89\xef\x0f\x4c\xf7\x76\xe7\x5d\x7c\xb0\x1a\x85\x3e\x48\x8f\xbb\x22\x88\x5f\x33\x4a\x22\x3a\x0c\x54\x42\x0b\xd6\x2f\x2a\x32\x5c\x12\x76\xe9\x92\x47\x64\x34\xf1\x92\x99\x25\x3c\x8c\xb8\x4f\xdb\xd4\xbf\x50\x64\xc3\xf1\x1b\xc6\xdc\x8c\xc5\x7f\x90\xb0\xf9\xb8\x21\x1a\xaa\x73\x4c\x01\x4b\x3a\x4c\x7c\x8f\x64\x75\x48\x95\xe0\x16\x0d\xe0\xc3\x10\x65\xce\x2e\x76\xf6\xb0\x34\x0a\x7d\x4b\xeb\x41\x79\xfd\x0f\xe2\x11\x61\xaa\x0c\x9a\xcc\x04\x5b\x3e\x8f\xc6\x85\xe0\x09\x81\x4e\x78\x12\xe5\x69\x5a\xe6\xa2\x43\x60\x71\x3c\xe4\x62\xb1\x09\xd6\x8d\xa5\xa5\x6e\xd7\x85\x41\xe2\xec\x83\x0a\xa1\xff\xbf\x98\x6b\x08\xdc\xf0\x56\xb6\x1e\x18\x1c\xe0\x15\x67\x8c\xac\x50\x88\x94\x4a\xbd\x4d\x52\x69\x47\x23\x3b\xc7\xba\x1e\x4a\x5f\x4e\x8e\x50\x3a\x34\x24\x21\xeb\x2e\x47\x70\x51\xda\xaa\x43\xe9\x03\xbd\x68\x9b\x8f\x79\x30\x9c\xe7\x17\xa1\xa6\x6e\xca\xc8\x48\x47\x71\x1f\x00\xca\x0c\x06\xf9\xea\xbc\xb9\x90\x51\xd5\xa1\xf2\x44\x30\x60\x0c\xff\x14\xcb\xad\x43\xa5\x0c\x7f\xc7\x8f\x21\x19\xd2\x6c\xfc\x31\x54\x5a\x12\xac\x26\x87\xda\x84\x2f\x76\xe0\x62\x76\x21\x26\x09\xd9\xac\x3b\x71\x3a\xcf\xc8\x7a\xb4\x1d\x74\x20\xed\x8b\x69\xc7\x9c\xec\x6d\xc5\x10\x53\x20\x29\x9b\xe5\x59\x60\xf5\x90\xe5\x58\x8f\x86\x3b\xa2\x60\xbe\xb3\x56\x37\x58\xa8\x1b\xc8\xf2\x53\x35\xa2\x15\xd3\x91\xe7\x07\x5a\x39\x50\x42\x93\xb4\x6b\xef\xd5\xb9\xb1\xd1\x18\x16\x8c\x91\x26\xcc\x1d\xa4\x52\x23\x17\x3a\x00\x6b\xee\xa0\x87\x3e\xd9\x6e\x2c\x86\xc8\xeb\xea\xb0\x30\xfb\x35\xe4\x3e\x1f\xac\x31\x11\x8f\x43\x21\x9c\xd2\x9c\xf1\xf5\x0a\xd5\x85\xd1\x3f\x8d\x3e\x47\x3e\xf8\xa1\xbd\x48\x93\xe3\xec\xc6\x3d\xaf\xa2\xa5\xa3\x40\x32\xcd\x87\x80\x8c\x92\x38\x92\xab\x7e\x4c\xbb\xd4\x5c\x14\x85\x3e\xb3\xaf\x69\x55\xbf\x96\xdb\x71\x89\xa2\x8e\x62\x9e\x92\xf7\x73\x0d\xff\x75\x4f\x1f\xc7\x8a\x7e\x2a\x5d\x25\xd9\x10\xd6\xa8\xa3\x44\x73\x0f\x2c\x67\xf0\x20\x12\x12\xa5\x61\xe4\x6a\x3e\x6c\x71\x81\x9e\x24\xbf\xa2\x14\x20\x64\xb6\xf8\x34\x8e\x27\x77\x92\x2a\x43\x77\x53\x63\x43\xf3\xe3\x1e\xd5\xab\x4b\x29\xcf\x47\xee\xfe\x98\x9c\x40\xa7\x64\x32\x36\x08\x87\xef\xae\xb6\xf4\x54\x34\xdd\xc6\x15\x01\x33\xec\x4e\xed\x88\xbe\xce\xb4\xce\xe4\x29\x6f\xce\x3d\xdc\xcc\xa9\xa2\x0f\x4d\x84\x08\x18\x52\x9a\xcc\xc2\x9a\xbe\x4c\x15\x6c\x75\x04\x7e\x4a\x34\x2f\x99\x2c\xaf\x40\xfe\xec\xd4\xc1\x74\x24\x3c\x48\x3b\x0d\x11\xb2\x8a\x5a\x5b\x50\x67\xf9\x40\x70\x67\x3e\xdf\x37\xb3\x5c\x47\x82\x27\xc2\x48\xfc\xe4\x27\x7c\xd2\x5f\xc6\x8d\xa1\x88\x95\x1b\xb3\xed\xd0\x36\x02\xc3\xae\x35\x15\x44\xbf\x43\x22\x5c\x2e\x72\x91\xfc\xd1\x97\xf5\x4c\xde\xa5\xf4\x80\x4a\xaa\x06\x77\xfd\x21\x5d\xd1\xf4\xd0\x38\xb2\x82\x4b\x14\x15\xb8\x76\xf5\x2a\xf3\x64\xf8\xee\x20\x34\x71\xab\x76\xff\x05\x62\x22\x9e\x04\x4d\xc6\xdd\x15\xf7\x92\xc8\x69\x3e\x94\xb9\x2a\xdf\x8a\x99\x74\x4b\xa4\x7c\x53\xd3\xda\xda\x3d\xf6\x3e\x6e\xab\xf2\xe4\xa2\x19\x91\x92\xc6\x87\xdb\x20\xe5\xf5\x36\x0d\x1e\xa7\x67\xc0\x90\x28\x19\x9f\x33\x54\xcf\xd9\x11\xab\x47\x6c\x5a\xe7\x75\xe0\xaa\x44\x18\x32\x66\x17\xeb\xa5\x65\xcb\x1c\x1b\x5a\x11\x46\x46\x9b\xe4\x3a\x7b\xcd\x1a\xc8\xb7\xfb\x72\xec\x4c\x46\x28\x22\xa2\x1a\xc5\x5a\xc2\x11\xbf\x42\x23\xf7\xed\xa9\xfa\x91\x8b\x18\xbb\x22\x4d\x1b\x9e\x1d\x56\x29\x75\x9d\x04\x59\xf7\x92\x54\xfd\x9a\xab\x53\xd5\x5d\x40\xfb\xd2\x49\x66\x6d\xf6\xd9\xf1\xd9\xe8\x5d\x9a\x77\x4c\xec\x69\x38\x4e\xe9\xc7\x5e\x24\x89\xc9\xcb\x46\x66\x1c\x62\xdd\xb6\x32\xcd\xc3\x9e\xc6\x6d\x5b\x1e\x33\x39\x82\x9b\xb0\x70\xbc\xd8\xc5\xdc\xc3\xd8\xc1\x2e\xb6\xfb\xca\x64\xc8\x09\x3f\x52\x3e\x40\x71\x1e\x56\xa2\xeb\x98\x47\x11\x26\x6e\x01\xea\x88\x16\xdb\x15\x7e\x7b\x29\x72\x3f\xfa\x5e\x31\xa5\x08\x8c\xf7\xd9\xba\xd2\xc4\x85\xfc\xe9\x70\x8d\xb9\x8a\xd5\x30\x22\xb5\x84\xe3\x97\x51\x07\xdf\x0f\x08\x1d\xd8\xdd\x07\xa1\x94\x7e\x73\x1f\x81\x42\x17\xba\x22\x48\xe1\xd3\xa9\x91\xe5\x20\xe0\x30\x5a\xcf\xe3\x98\x03\x51\x9c\x58\x06\xf6\xf3\x41\x38\x1e\x18\x1d\xc7\x00\x54\x67\xf0\xdf\x13\x56\x94\x73\x98\xe2\xa3\x26\x57\x4e\x3d\xa0\x1a\xe7\x2b\x28\xa0\x80\xdb\x3e\xf3\x1a\xa7\x41\xe0\xdb\x58\x14\x2d\x70\x5f\x8d\x84\xf0\xe8\x68\x08\x18\xe5\xe2\x2a\x78\x7b\x84\xc3\x40\xdf\x7d\xf2\x3d\x21\xe6\xda\x70\xe3\x0a\xaa\x16\xae\xaf\xe7\x65\xf3\x3f\x87\x13\xc5\x20\x58\x68\x17\x2d\x85\x32\x3b\xc0\x44\x92\x50\xc7\xa0\x19\x45\x64\x25\x14\x96\x4b\xb7\x1d\xda\x44\x42\x75\xdf\xe9\x80\xeb\x58\x04\xa6\xc6\xa8\x2a\xf3\x7c\x72\x06\x11\xfa\x2c\x19\x3c\xb6\xe1\x94\x1b\x4e\xbf\x58\x58\x07\x3b\x1f\x6e\x74\xb1\x48\x22\xce\x3b\x6c\x6e\x56\xbc\x5e\x23\xa8\x3c\x2b\xba\x17\x2a\x03\x41\x96\xbc\x09\xdb\x8c\x78\x9c\x75\x2c\xa5\x24\x64\x6f\x56\x64\x06\x44\x74\x93\xe5\xf8\x99\xfa\xf5\xdc\x92\x1f\x4b\xa5\x68\x1d\x3e\x15\x99\x2c\xab\xa2\xbe\xcd\xf4\x60\x1a\x2a\x66\xd4\xcf\x0f\x24\xcc\xdb\xee\x60\xc6\x73\x19\x2f\x3f\xb1\xd2\x69\xd4\xdb\xdb\xf7\xe5\xeb\xe5\x2c\x1a\x5d\x14\x7d\x8c\xb9\xc3\x48\x95\x85\x43\x48\x99\x02\xe3\x01\x4e\x2a\xc6\x20\x25\x74\x63\x7d\xae\x1b\x3c\x0c\x29\x03\x74\xac\x6d\xb1\xb2\xc5\xda\x2c\x3a\x19\x36\xdb\x21\xf1\x3c\x4c\xb0\x47\xd4\x1a\x79\xd6\xae\xd1\x07\x69\xa9\x2f\x8d\x7a\xeb\x54\xb9\xd5\xf5\xb3\xd2\x04\x2e\x1e\x76\x53\x21\xda\x8a\x8d\x09\xbc\x2e\x61\x61\xc2\x65\x17\xfb\xe8\x7f\x8e\x24\xd5\x6f\x1b\xa0\xa8\x4d\xbc\xd8\x36\xee\x69\x72\x1a\x0e\xa4\x6d\x86\xab\x53\x55\x1a\xf2\x3a\xf2\x86\x67\xe7\x5f\xe2\x0b\xa9\xe2\xc1\x1d\xe5\x93\x51\x93\xf8\x8a\x31\x0b\xe9\x26\xdb\xb7\x29\x0b\xac\x17\x85\xda\x0c\xc4\xe6\xe6\x8b\x97\xa6\x6e\x42\xe2\xab\x98\x2a\x10\x6c\x22\xdb\xa8\x13\x38\x69\xcf\xe1\x27\x4d\x7c\x1d\x04\xb6\x6a\xe0\x19\xce\xed\x48\xb9\x3a\xcf\xe6\x10\x92\x08\x4c\xd0\xdd\x06\xa8\x1c\x9a\xa2\x33\x8e\x93\x48\x6b\x62\x1b\x32\x5b\xc2\x55\xf6\x61\x98\xdc\xf6\x8f\x19\x87\x81\xc8\xd4\x54\x1a\xbb\xeb\x15\xf3\xc8\x6d\xa2\x44\xf7\x78\xfe\xd1\xee\xb3\xed\xb7\x6f\x37\xa0\x35\x8e\xab\x14\x75\x12\xa7\x81\x13\x92\xdb\x94\xf9\xaf\xa9\xcf\x95\x24\x2c\x20\x98\xcf\x2a\x3f\xcf\x7a\xc2\xa3\x28\xd3\x98\x81\x50\x27\x49\x14\x80\x74\xcc\xc7\x24\x22\x34\xfa\xe6\xae\x57\xac\x28\x30\xbe\xa4\x5a\xbd\x0d\xbc\xc2\xf5\xa9\x78\xc5\xb2\xf8\x8e\xd5\x25\x45\xfc\x67\x8e\xec\x4c\xf9\xf0\xcc\xcf\x53\x2b\xf1\xff\x82\x7f\x0f\x6f\x3a\x0d\x0c\x4e\xdb\x72\x33\xbe\x0c\x32\x4a\xa3\x5a\xe4\xc9\x07\x4a\x31\x65\x6c\x00\x35\x37\xa2\x00\x33\x78\x97\x04\x64\xe4\x59\x18\x98\xe7\x86\x03\xa0\xaf\x6d\xbc\xb7\xd4\xad\xa7\x86\x6a\x10\x24\x4b\xa4\x67\x49\x68\x1b\xa8\x9a\xe7\x21\xed\xc9\x07\x77\xa3\x98\x72\x6e\xd1\xb6\x6c\x26\xfa\x8b\x3a\x51\x69\x4a\xc4\xf1\x40\xb8\xcc\x81\xd7\x3d\xf9\x34\x4a\x73\x69\x77\x96\x5b\x2c\xd0\x42\x67\xea\x19\x81\x56\x9d\x60\xa4\xc5\x90\x56\x62\x03\x97\xae\xf9\x07\x77\x8b\x31\x4f\xe4\x64\x32\x7f\x19\x19\xd4\x76\xda\x26\xdd\xa4\xc5\xd4\x28\x56\x1a\x4c\x48\xfd\xed\xfa\x6e\x72\xeb\x08\x21\x1a\x1a\x70\x2a\xce\x26\xd1\x93\xe1\x76\x95\x20\x48\xaa\x53\xa9\x8f\x34\x8f\x29\xa5\x6d\x9b\x34\x53\x84\xae\x68\xef\x87\xaa\x27\x2f\x2a\x3a\x47\x96\x47\xa2\xa3\x94\x98\x2e\x35\xca\xfd\x22\xcf\xbf\x13\xe1\x65\x7d\xca\x9b\x9b\xb2\xb2\x40\xe6\xee\xd4\x09\x23\x64\xc6\xb6\x3e\x76\x65\x23\x3a\xd1\x52\x52\x92\xe1\x3b\x14\x0d\xa8\x69\xa8\x27\xf5\x7c\xcf\xa9\x30\x5a\x76\xf6\x2f\x5d\x8b\xa0\xad\xff\x68\x4a\x05\x36\x47\xe2\x3a\xd9\xbe\xcf\x29\x13\xeb\xd4\x13\x9c\x4a\x42\x6b\xa7\xe5\x39\xf0\xd0\x52\x4f\x1b\x68\xce\x42\x29\xbb\x07\x8d\x0f\x66\x51\x44\x4b\x7c\x81\x6f\x4f\xd5\x2b\x14\x59\x3d\x52\x9f\xba\x8c\x2d\x26\x83\xd1\x91\x32\xf4\x5d\x89\xce\xd5\xe9\xdc\x3a\x78\x33\x53\x23\xe5\x5c\x11\x7c\x44\x75\x54\x7b\xae\x41\x1b\x35\xd9\x1a\x9b\xab\x46\xbe\xd4\xea\x42\x5c\x48\xa7\x7e\xc0\x89\xab\x49\x42\x2e\x97\x66\xdd\xad\x1f\x11\xd5\xa5\xd4\xb3\x3d\x20\xf2\x42\x32\xa7\x8f\x99\x2c\x8f\xf5\x6e\x8a\x67\x75\xbd\x7c\xed\x4a\xc5\xd6\x78\x2c\xab\xd6\x86\xf9\x91\x15\xaa\x7c\x9b\x30\xab\xe8\x34\x4a\x7d\xf2\xf9\x95\xa1\xb7\x9b\x9b\x01\xae\x27\x28\x2a\xde\x5c\xee\xab\xb2\x28\x47\x09\x9e\x59\x1b\x2f\x8d\x03\x4d\x19\xbd\xc7\xd5\xfb\xd6\xbd\x94\x38\x45\x2a\x32\xbd\xc5\x66\x9d\xbd\x76\x54\x27\x89\x6b\x06\x6e\x55\x7d\xfe\x83\xb2\x59\x62\xd5\x18\xbd\xf4\xe9\x7b\x8b\xa5\xe7\xa1\xb3\x9b\x97\x15\xd2\x67\x7d\x80\xf7\xee\x32\x08\x34\xc6\x56\xd7\x2f\xbb\xe7\xd5\x7a\xb7\xda\x7e\xdd\x3d\xaf\x57\xbb\xcd\xe2\x7e\xd5\xf5\xd1\x1c\xb5\x0b\xe1\x58\x23\xe3\xc6\xb0\xaf\x42\xe7\xc8\xa7\x89\x9f\x52\xe5\xb8\x80\x3a\x93\x23\x23\x21\x4d\x03\xe6\x1b\x53\xb8\xcc\x11\x8a\x91\xe6\x9c\x9b\x67\x69\x1a\x22\xd9\xd5\x5f\xaf\x97\x5b\x1c\x15\x70\xea\x34\x4d\x12\x87\xfb\x1f\x60\xea\xa7\xa8\xa6\xc9\x67\x48\x65\x60\xc5\xe8\xeb\x86\xc4\x82\xee\x07\x27\x54\x49\xd4\xd9\x6f\x07\x92\x72\xde\x39\xf7\xc6\xc4\x11\x7d\xa2\xa6\xb3\xdd\xc1\x4b\xa4\x81\x61\x60\x7e\x57\x0c\x29\x3f\xd8\x05\xf5\x9f\x3b\xc4\x4f\x99\xe3\x83\x06\xf3\xe6\x0d\x41\x71\x3d\xb3\xbe\xa6\x20\x18\xd1\xf6\x50\xf0\x61\xf4\xa1\x65\x18\xd2\x08\x5d\x3c\xdc\x6d\x26\x83\x57\x86\x11\x91\x10\x54\x27\x71\xaa\x9f\x2a\x28\x5e\x27\xf0\xd7\x54\x46\x01\xe5\x7b\xbe\x92\x18\x0c\x11\x20\x90\x8f\xea\x6e\xf9\x93\xea\x27\x9d\xaa\x18\x44\x32\xa0\xc2\x98\x4f\x9e\xa4\x08\x9c\x46\xd0\x8e\x12\x03\xb4\x37\x4e\xb4\xa3\x5d\x47\x01\x14\x04\x10\x59\x23\xcb\xac\x30\x61\xb9\xcf\x2d\xa3\x14\xa5\x49\x04\x6d\x5b\x87\xf2\xee\x00\xaf\x38\x50\x34\xd5\x29\xea\x58\x43\x67\xb3\x95\xa7\xe6\xf1\x74\x30\xd4\xc0\xa3\x77\xa8\x99\x41\x20\xd5\x46\x6f\xe3\xcd\xd4\x1f\x8d\xef\x4e\xa3\xa2\x11\x41\xc9\x6a\xa3\xf4\x84\xd5\xa8\xea\xc0\x74\x04\xcf\x07\x2e\x86\xe8\x5c\x35\xc8\x2b\xff\x31\xe9\x9b\x18\x81\x4c\x9b\x3b\xbb\xc6\xf7\x06\xab\xac\x99\xac\xbe\xe0\x25\x60\x58\x46\x1b\xb9\x9f\xc3\x35\x81\x97\x32\x82\xef\x8a\xd3\x79\xd3\xc0\xe1\xe8\x3e\x30\x78\x69\x44\xe0\x89\xac\x6e\x5f\x67\x55\x4f\x77\x17\xf0\x94\x8c\xbd\x4e\xf8\xa7\x35\xeb\x37\xd0\x94\xf5\x3e\x9b\x5f\xbb\x80\xf9\x40\x70\x11\x22\xf5\xc0\xea\x30\x0a\x3b\x00\x0f\x00\x8c\x37\x45\x4a\x17\xad\x53\x55\x34\xf9\xb9\xab\xb3\x1a\xbc\x74\xf0\x3d\xc3\x62\xa6\xca\x8f\x53\xdc\xe0\x4b\x3f\xe6\x1d\x37\xe8\x78\x5a\x77\x5d\x34\x50\x30\xf5\x20\x3f\x0f\x17\x43\xe0\xc5\x9e\x13\x7a\x6f\x47\xc9\xf7\x47\x77\xdf\x01\xe7\x54\xd2\x84\x50\xe5\x19\xd1\x4d\xbd\x37\x1b\x0a\x2a\x1f\x2e\x45\x61\x35\x04\x21\xa7\x0a\x18\xa8\x2a\x38\x3f\xe9\x65\xde\xfa\x1f\x93\x17\x1b\x58\xd2\x92\x83\x61\x9e\x68\x4a\x55\xfe\xca\xb0\x3b\x83\x0c\x28\xfa\x66\x90\xb3\x6b\xac\x8d\xf9\xed\x5a\x95\xd1\x08\x90\x56\x39\x4c\x2d\x94\xca\x8a\x57\x62\xd9\xca\xbb\x97\x1d\x20\x38\x9a\x36\xac\x7e\xd1\xc2\x3d\x9e\xde\x10\x62\x40\x50\x23\x53\xcf\xea\x82\x8f\x53\xbc\x01\x44\x5c\xbb\xfd\x95\xa2\xbd\xd5\x79\x93\x97\xaf\x30\x4d\x2a\xbb\xde\x9a\xa5\x62\x84\xe6\xbc\x29\xab\x7f\x9e\xb0\x47\x91\xda\x8e\x69\x24\xd2\x01\xd5\xa1\x51\xcb\x82\xdc\x18\x47\x13\xeb\x04\xd2\x24\xa0\xcd\x5f\x9f\x0a\x45\x1a\x04\xee\x77\x65\x90\x3d\xd7\x8b\xcd\xe2\xea\x6e\x77\xf7\xb4\x9b\x24\x98\x01\x30\x11\xd6\xcf\x6d\x0f\x9c\x49\x4a\x81\xf0\x78\x14\xda\x6f\x91\x5d\xe3\x2f\x77\xa8\xe8\x59\x1c\x4c\xb5\x1e\xaa\xed\xfb\xe4\xe5\x08\x61\x62\x1f\x0f\x8b\x3f\x77\x8b\xfb\xfb\xa7\x1f\xab\xeb\xdd\xd5\x5f\xbb\xcd\x76\x71\xbb\xea\x20\x44\x20\x30\x92\xda\x01\x95\x9b\x13\xe4\x56\xf4\x2d\x2b\x0b\x4a\x67\x9b\x90\xde\x6f\xe5\x0e\xed\xd9\x54\xa0\x82\xa8\x0f\x35\x0e\xa5\x27\xba\x1e\x18\x1b\xb0\xe8\x2f\x2c\x0c\xbf\xd3\x98\xcc\x48\x03\xc6\x21\xb6\xdf\xe9\x4f\x28\x94\x23\x12\xd5\x80\xa9\x6f\xb4\x33\x08\x27\x49\x23\x7b\x60\x6c\xbb\xb9\x89\x92\x25\x4e\xe6\xba\x8b\x74\x8f\xef\x51\x33\xa4\x77\x67\x12\x9a\xdb\xac\x9b\x1c\x3a\x49\x53\x43\xe3\x6f\xb5\xf0\x3e\x62\x6c\x18\x6f\x88\xa0\x25\x27\x13\xd4\x78\xe2\x57\xa7\x3a\x2b\xb0\xae\x2d\x30\x6e\xd6\xd1\x16\x9e\x27\xa9\x00\x2c\xa3\xad\xa2\x7d\x01\xd6\x2a\x73\xa4\x29\x5a\xb0\xd0\x08\x9b\xed\x04\x34\x72\xcf\x76\x99\x2c\x07\x68\xb9\xe1\xac\x16\x2c\x34\x4a\x7e\x28\x0f\xa7\x3e\x8c\xe0\x4f\x00\x4d\x82\x45\xc9\xc0\xaf\x3d\x5a\x39\xd3\x7e\xaf\x16\x4c\x33\xc7\x31\x67\x79\xf8\x3e\x08\xd9\x0b\x1e\x6a\x27\x5a\xd8\x5b\x68\x17\xd0\x57\xc1\x53\x26\xc5\x20\xd9\x7b\x37\xaf\xb7\xa0\x05\x57\xc8\xe5\x50\x6f\xb9\xde\x96\xdb\xb7\xdf\x04\x7c\x05\xd7\x9c\xb8\x14\x5a\x5b\xc7\x44\x24\xee\xa1\xfd\xff\x35\xfe\xca\xea\x3e\x6a\x21\x7c\xab\x71\x61\x28\x29\x4c\xdd\xd5\x4d\x49\x86\xae\x81\x45\x8f\xbd\x71\x7b\x54\x10\x6b\x72\xc5\x96\xa7\xbc\x39\x55\xf8\xbc\xcf\xf2\xb2\x2e\x8f\xfb\xf3\x0d\x64\xcd\x9e\x3c\x33\x77\x81\x40\x48\xca\x1d\x9b\x5c\x42\xf3\x0c\x75\xfd\x56\x56\x6a\x96\x87\x4e\x8b\x40\x31\x0a\xf8\x6f\xf7\xf8\x70\xa2\x29\x47\xeb\x8c\x74\xe1\x33\x11\xa6\xda\x68\x35\xbf\xc1\xf1\xb9\x2a\xdf\xc7\x21\x72\x11\xa1\x91\x72\x3e\x9a\x60\xce\xc0\x59\xb0\x32\x3a\x5a\x24\x5c\x71\x4b\x02\x51\xe1\x73\xeb\x9d\x8f\x42\x42\x22\x49\x62\x5b\x0c\x6f\xf0\x11\x83\xb2\x3d\x91\x48\x0f\x55\x1f\x9b\x5b\xfd\xf3\xe5\xee\x47\xb6\x6f\xca\x53\xf3\xed\xaf\x65\xd7\x49\x85\xb4\xd0\x13\x40\xc4\x45\xe9\x5c\x63\x1a\x4b\x3f\xe8\x26\x04\xb1\x96\xd8\x8c\xce\xa7\x08\x25\x01\x22\x48\x3b\x10\x9f\x71\xb4\xa6\x03\x60\x88\xa9\x98\x1c\x2d\x02\x8f\x10\xc5\x6b\x90\x59\xf1\x3a\xb4\xb2\x85\x08\x14\x4d\x90\x65\xc7\x33\x65\x74\x22\xa7\x8b\xb9\x10\x3a\x10\xb6\xe4\xfa\x5b\x46\x52\x89\xb7\x30\x49\x0b\x09\xa9\x0d\x63\xc5\x2e\x37\xfa\xf5\xa3\xd0\xa7\x50\x7e\x18\x05\x7d\x59\x50\x7b\x8d\x07\x8a\xd0\x56\x5d\x8f\x38\x26\xff\x4d\x65\x6a\x53\xea\x66\x09\xc7\x71\x25\xb6\x50\x29\x10\x92\x77\xbd\xba\x79\x79\xbc\xde\x2c\x96\xdb\xbb\xef\xab\xae\x11\x62\x82\x5f\xdd\x67\xa2\x82\xea\x3c\x7a\x4c\x64\x69\x6c\x68\xff\x6b\xd9\x55\xbd\x0a\x0c\x12\xc3\xd9\xbe\xcf\x8e\xdb\xf2\x61\x56\x74\x47\x0b\x8c\x83\xd8\x6a\x98\xa8\x55\xa1\x8e\x65\x36\x13\x26\x1c\x9b\x25\x02\xc1\x80\xf8\x8d\x2d\x40\xa5\x11\x9f\x97\x91\x09\xc4\x88\xc6\xd6\xf2\xf1\x2f\xa3\x34\x94\x9f\xa6\xc6\xf7\x28\x36\x67\x0f\xd3\xb1\xf4\x71\x90\xa7\xb1\x6b\xeb\xe4\xc3\x68\x8c\x28\x24\x0f\x27\x95\x59\xa7\x77\xe4\x91\xcc\xfb\x33\xd2\xf3\x01\xbc\x7e\x1b\xbe\x3a\x9b\xb2\x8c\xf1\xc9\xa5\x17\x6a\xb2\x7b\x48\x94\x08\xf2\x8e\x09\x4c\x4b\x2f\x32\xb0\xcc\x22\x93\x78\x7b\x3a\xd7\xd3\x03\x13\x43\x61\xf3\x74\xaa\xae\x1c\x53\x92\x96\x1e\x86\x44\x4c\x4d\x35\x22\x26\x2a\xeb\xe6\xb7\x64\xc8\x29\x99\xde\xba\x77\x33\xb5\x45\x92\x07\x9c\x92\xd2\x65\x41\xd8\xb1\xb9\x05\x55\xf2\x40\xc2\xa8\xaa\x60\x00\x63\x99\xde\x21\x8f\xd1\x70\xc2\xd5\x77\xb2\x1c\x0a\x0b\x6b\xc9\xd1\x23\xb6\xd4\x87\xac\x40\xb5\xdd\x67\xf5\x5f\x08\x6e\x20\x4b\x1f\x42\xd2\xb7\x6e\x8d\x3d\xa2\xef\x6b\x8d\xf0\xc9\xb9\x43\x61\x94\x00\x5c\x94\x62\x52\x1a\x37\x1e\x50\x32\x94\xa9\xb3\xe7\x5a\x43\x76\x22\xda\x36\x3e\x73\xc4\x35\x99\xa9\xdb\x2a\x23\x59\x4f\x4a\xde\xcf\x0f\x54\x19\x21\xf3\xc1\x55\x53\x9e\x0a\x35\x5f\xd2\x27\xe3\xd0\x20\x1f\x6d\x58\x6a\x84\x69\x97\xb1\x8a\xc8\xe9\x3e\x4e\x62\xd8\xff\xc7\xa2\xc9\x46\x2b\x13\x8e\xa3\xe2\x96\x97\x82\xb8\x66\x51\xdd\x60\x97\x92\x90\x49\x14\xfa\x96\x58\x9c\x02\x5a\x54\x5d\xc2\xbb\xd6\x38\x4c\xec\x06\xbb\x23\xd3\xd6\xf0\x15\x8d\xc0\x32\x32\xe5\x09\x15\x4f\x37\xf0\x3e\xfe\x3d\x46\x5a\x7f\x6f\xb1\xc8\x4e\xdd\x05\xd3\xc4\xa7\x6f\xb9\xdc\x63\x5e\x23\xfc\xaa\x17\x55\x8d\x45\x87\x67\x95\x10\x72\xe2\xa0\xde\x67\xaf\x7b\xe2\x63\xef\x1b\x4c\xd0\xff\xae\x5e\xc3\xff\xd6\x27\x32\x0c\x26\x6f\x0e\xb4\x01\x99\xdf\x94\x07\x5b\x4e\x3b\x70\x66\xa5\xe0\x29\x57\x03\x74\xc8\xcd\xa9\xe8\xf1\x54\x89\xeb\x24\xd0\x08\x4b\xb6\x2f\xa4\x2c\x9b\x0b\x46\x00\xdb\x4f\x7a\x1c\x3b\xa1\x44\x3c\x1d\xa6\x21\x15\x29\xb9\xa1\x1d\x36\x94\x32\xcb\xaa\xbc\x0c\xde\x4b\x29\x19\x7d\xcc\xc6\xd5\x3c\xaf\xba\x70\x8f\x54\x9e\x11\xf6\x59\x00\xa8\x3d\x54\xd7\x78\x28\xbb\xa6\x18\xc1\x95\xca\x3f\x3d\xdd\x1b\xad\x40\xdf\xef\x9a\x35\x12\x46\x3a\x93\xe5\xb0\xf6\xc3\xb6\x6a\x1e\x0a\xec\xf8\x32\xdd\x64\xdc\x9c\xc6\xb8\xef\xf1\xc3\xea\x30\x24\xee\x2f\x97\x50\x1a\xea\xe7\x9b\x2e\xca\x63\x1e\x31\xcd\xec\x6a\xcc\x73\xa7\xdc\x36\x3a\x8b\xf2\x98\x22\x36\x2b\xc3\x91\xfb\x54\xac\xd6\xcb\x98\xb3\x0f\xe5\x49\x47\x56\xae\x3b\x05\xf7\x09\x3a\x76\x73\x63\xf2\x1d\x13\xfa\x35\xad\x9c\xcc\x15\x0d\xd6\x65\x79\xaa\xea\x6e\xa8\x2b\x1e\x19\x9a\xf4\xff\x80\xfc\xf9\x5c\xba\x52\xb3\xbe\x19\x8d\xca\x8d\x59\xab\x96\x39\xd4\xf5\x00\xcc\x3d\x7e\x23\xca\x57\x8a\xc0\x2c\x4f\x85\xd1\x5a\x58\xfd\xf7\x04\x79\x7d\x57\xf4\x0b\xb2\x0a\x98\xd1\x74\xa8\x89\xe8\xcb\xb1\xd6\x98\xf2\xd6\xf1\xc9\x82\x38\x22\x0a\xa5\xc5\xa9\x29\x8b\xf2\x50\x9e\xea\x76\x47\x7e\x83\x0a\x9f\xaa\xd7\x2f\x63\x34\xd6\x69\x88\xc9\x72\xc7\x8b\x80\xfc\x72\x32\xcc\x89\x8f\xcb\xe9\x0a\x68\x15\x86\x90\x80\x83\x9b\x91\xba\xc9\x11\x8b\x6e\x93\x57\xb1\x48\x08\x74\x4a\x72\xe0\x54\x0a\x3e\x02\x01\xff\x31\xb7\x49\xab\x58\x07\xbe\xd5\xc6\x5a\x2e\xbf\x9a\xe1\x17\x8f\x2c\x3b\x95\x78\x89\xa9\x79\xc9\x0a\xf3\xc4\xee\x77\x9e\x52\xe6\x11\x0b\x65\xf9\xc5\xba\x96\x08\xa8\x00\xed\xc6\x68\x9f\x4c\x5e\x51\x1a\x09\xa2\x4d\x30\x46\x8c\x9a\x04\xc0\x06\x91\x3e\x95\xc6\x92\x84\x4e\x96\x8f\x65\x83\x75\x47\xd4\xae\x55\x9a\x98\xf8\xbd\x35\x28\x6f\xca\x8a\xa8\xf0\x1d\x7a\x6d\x7e\x9e\xab\x54\x18\x4a\x5b\x83\x6f\xff\xee\x22\x7c\x6b\xc3\x32\xdf\xad\xbe\xfe\x25\x01\x01\x1b\x90\x57\x0f\xc7\x70\xaa\x19\xad\xa9\x12\x9a\xc7\xf2\xbe\x2c\x5e\xb1\xb2\x5e\xc0\xe4\x99\x21\x30\x12\x64\x0f\x99\xf5\x46\xdc\x93\x40\x68\x48\xf5\x2b\x33\x75\x8c\xc0\x16\x61\xdd\x3e\xcd\xb4\x28\x48\xcc\xd2\x6a\x40\x97\x20\xf7\x17\xfd\x47\xcb\x93\x02\x54\xb4\x23\x5f\x95\xe5\xc1\x14\xe8\x56\x13\x4d\xc6\x01\xef\xc2\xcc\xa7\x00\xed\xd3\xf1\x56\x50\x7e\xf1\x5a\x21\xc5\x83\x66\x34\xa3\x2e\x48\xde\xa6\x21\xa8\x79\xdf\x4b\x89\xd0\x04\x0b\x41\x29\xf3\x21\x0f\x14\x29\xc1\x3b\x59\x7e\xf0\x41\x05\x24\x54\x5f\x76\x95\xa1\x71\xf0\x06\x2f\x56\xea\x90\xc2\x6f\x04\x31\x6e\xf6\x9f\x56\x63\x2b\x15\x47\x8e\xd6\x54\x9c\xce\xc7\xcb\x8d\x5c\x29\x61\x38\xe0\x49\x6d\xeb\xfb\x8b\xe3\x5d\x52\x18\x44\x9e\x8b\x17\x39\xa2\xc3\x9b\x8b\x88\xa9\xc2\x24\x88\xd2\x4b\xf9\xa2\x51\x20\x43\x69\x2f\x66\x43\x58\xef\x85\xa0\xe0\xe0\x7b\xe8\xc8\x70\xf4\x1c\xab\xb2\x41\xd9\x7c\xcb\x8a\x57\x55\xba\xbc\x9d\xd2\x10\x90\x01\x49\x21\xfb\x1a\x9b\xd3\xf1\xaa\x84\x4a\xad\xcb\xf2\xb0\x28\xd4\xa2\xae\xb1\xea\xa6\xb1\x46\x03\xbf\xef\xea\x7a\x28\x4f\x7a\x7d\xa9\x83\x6a\xfa\xa3\xe7\x01\x6d\x86\x59\xa1\x5a\x97\xe7\x04\xf9\x03\xbc\x2f\xe1\x38\xf2\x28\xd1\x8b\x39\xa9\x17\x6f\xae\x57\xb3\x45\x19\xc3\x15\x06\xbd\x04\x49\x28\x68\x5f\xbe\xed\x0e\x50\x9c\x77\x50\x89\xac\xa9\x77\xaa\xdc\x65\xbb\x3d\x74\xc6\x23\x7a\x5a\xd3\x26\xab\x29\x42\x65\x42\xd3\xe3\xbb\x63\x21\xb3\xb2\x8c\xed\x44\xdb\x22\x1c\x56\xcd\x7e\x12\x26\x43\x16\x2a\x61\x64\x04\xaa\x9f\xd8\x88\xf6\xd5\xdc\x67\x16\xe1\x69\xa2\x8c\x7f\x2f\x5f\x8b\x4c\x70\x2f\x71\xa3\x02\x7e\x39\xc3\x07\x79\x84\xe4\x4f\xb7\x76\x6c\x59\x60\xd1\x0c\xb1\xc6\xc8\xc1\x30\x26\x1b\x67\xf6\x1f\xa7\x57\x50\x30\x53\xaf\x81\x5c\xa6\x04\x49\x78\x31\x11\xf1\xab\xb3\x19\x61\x1f\xc0\xea\x91\x2b\x8f\x22\x65\x50\xd7\xd9\x6b\xb1\x06\xad\x73\x7c\xae\xb2\xff\x4d\xb0\x11\xc8\x91\xf3\xd4\xd9\x4e\x0d\xe4\x84\x4b\x9f\xf4\xf1\xc1\x14\x3b\x2f\x6f\x97\xb7\xc3\x69\x85\x01\x62\xac\x7b\x86\xc1\xbb\x06\x0f\xb3\x29\x56\x0c\x99\x91\xa2\x39\x62\x55\x67\x75\x33\xdc\x39\x30\x0c\x93\xc8\x94\x52\xbb\x08\x1d\x46\x2c\x21\xbd\xa0\xe7\xc5\x7a\xfb\xb8\x5a\x6f\x76\x8b\xeb\xeb\x75\x5f\x73\x88\x51\xa0\x99\xd9\x34\xde\xb3\xc3\xe9\xf0\xb5\x54\xf9\xf5\xc9\xc8\x08\x39\x89\xa5\xf9\xb7\x12\x07\x09\x4d\x6d\xda\x4c\xe5\x3e\x93\x3f\xbb\x31\x1a\x8b\x88\x07\x9d\xb6\xc7\x43\x8f\x44\xc2\x58\x6b\x0a\x1e\x6d\x8e\x55\xd6\xe0\xe8\x05\x24\x2c\x48\xfb\x22\x29\x6a\xba\x3a\x7f\xfd\x31\x4f\xe2\xaf\x31\x09\x3d\x2b\x6f\xd6\xb4\xef\xaa\x23\x19\x18\xbf\xee\x24\xe2\x46\xb2\x21\xeb\xd1\xfc\x6d\xf7\x7a\x51\xa8\x6b\xac\x9b\xaa\x3c\x8f\x7e\xfe\x2d\x5d\xa0\xc6\xd4\x8f\xe3\x6e\xc1\xc2\x9b\x0a\x6a\x67\xcd\x60\x1a\x23\xed\x39\x6f\xfb\xf2\xae\x5e\x96\x85\xc4\xaa\x98\x22\x1e\x30\x45\x10\xb2\x33\x79\x26\x1f\x17\xd2\x48\xaa\xae\x64\xe7\xa5\x36\x70\x4a\x62\x53\x9d\x51\x0f\xd7\x08\x32\x0e\x85\x8b\xaa\x3b\x1d\xca\x8f\xc6\x31\x20\x3a\x00\xec\xa6\x5d\xba\xba\x2a\xaf\xa9\xab\x67\xfb\x0b\x4f\x52\x6a\xaf\xdd\x2a\x96\x4f\x14\xdd\xa2\xf2\xb3\xcf\xd3\x65\x28\x58\xaa\xa2\x9e\xfe\xbd\x9d\x27\x33\x6f\xf3\x62\xef\xfa\x74\x9b\x45\xe1\x87\xd1\x45\xf2\x75\xd7\x94\x9f\x6e\x3f\x28\x3d\xa4\xec\xc0\x7d\xf9\xea\xbc\x87\x85\x1a\xa6\xeb\x67\xb0\x3d\x69\x97\x53\x3d\x5d\xaa\x19\x6a\x94\x21\x10\x0a\xa7\xb5\xaa\x63\x57\x67\x81\x32\x52\xb2\x1f\xbc\x16\xd5\x6e\x7d\xe2\xdf\x15\xc2\xcc\x3f\xb0\x12\xd2\xf3\x5d\x78\x1e\x2a\x74\x1c\x75\x37\xa5\x13\x34\x9c\x75\x43\x50\xa9\x98\x22\x52\x75\x91\x1d\x8d\xe5\x6f\x6c\xef\x0b\x0d\x1d\x8d\xe8\x1b\x6a\x89\x76\x45\xd8\x6d\xbf\xdd\xee\x1e\x9f\xae\x57\x5d\xa3\x95\xec\xa9\xb1\xd9\x1d\xb2\x62\x77\x80\xf7\xdd\x4d\x56\x14\x78\x7e\xc6\x91\x21\x36\xb9\x3e\x6a\xcf\x11\x2d\xcc\xe0\x82\x34\xf3\x2d\x22\xbc\x1d\x16\xe3\x96\xc0\x67\xcc\xcd\x2b\x8b\xc3\x75\x02\x8d\xe3\x8e\xe0\x93\x85\x76\x80\xf7\xf6\x3e\x6a\x52\x4c\xeb\xac\x75\xcd\x2d\x29\x0b\x69\x20\x43\x95\x35\xe7\x4b\xb3\x41\x07\xdc\xd0\xad\x5b\xdd\xea\x9d\x84\x7a\xbf\x23\x68\xd4\x0e\x86\x9e\xa0\x0e\x59\xac\xb5\xbb\xab\x6b\x14\x93\xf5\x5c\x87\x51\x64\xa4\x11\x4c\xd2\xf9\xa6\xac\x6c\xbc\xb2\xab\x86\xd6\x21\x32\xaa\x51\xdd\x65\x0d\x1e\x6c\x8d\xc6\xf8\xa5\x44\xa1\x1f\xc9\x01\x83\x83\x01\xb9\x43\xd5\x4c\xfb\x41\x18\x88\x4e\x41\xe8\x06\x7e\x75\x7c\x23\x3a\x02\x15\x86\xc3\xd2\xf1\x71\x40\xc6\xf5\x92\x3c\x30\xa0\x41\x42\x0b\xa2\x7a\xd9\x38\x12\x1f\x1d\x87\x09\x7d\x70\xb3\x79\xde\x2d\x9f\xe6\x4a\x24\x5d\xdf\xc8\x44\xd8\xd6\x4f\x57\x2e\x77\x32\x2d\xce\xd1\x31\x18\x43\x9a\x7c\xfa\x47\x7c\x1d\x99\x31\x3a\x09\x13\x2a\x3f\x76\xb2\x77\x94\x0c\x1d\x10\x30\xea\x04\x64\x62\xe3\x40\x37\x59\x01\x79\x5f\xcd\xab\x13\x15\x92\x69\x68\xa8\x23\x37\x6f\x9d\x23\xa7\xd3\x48\xc6\x36\xa2\xfb\xb5\x2c\xca\xd3\x24\x32\xa8\x81\xc7\x24\x2f\xb6\x87\xba\xaf\x9e\x9e\x24\x7c\x34\x04\xa1\x05\x4d\x90\x45\xfe\xb7\x24\x8b\xb5\x16\x91\xa4\x78\x83\x4d\x55\x7d\x1a\x5b\xd5\x42\x18\xfd\xed\xac\x1e\xd9\xa1\xae\x55\xfb\x34\x82\x1f\x5e\x36\xcf\xeb\x85\x7b\x36\x99\xc6\x14\x18\xfb\x8a\xea\x15\x97\x50\xef\xbb\x06\xc1\x68\x08\x16\xa7\xc3\x3f\x5b\x7f\x8b\x1e\xc9\xb6\x29\x1f\x28\x9a\x9e\x97\xaf\xcc\xbb\xc9\xcb\x72\x8c\x23\xd7\x2a\xe0\x20\x86\xd8\xe9\x0d\x31\xa3\x2c\x3e\x16\xea\xd3\x5a\xa5\x29\x15\x8e\xb4\x3e\x4e\x37\xfe\xd0\x97\x94\xb0\x7d\x59\x2d\xc7\x15\xa1\xe3\x63\x31\x90\xb2\xd3\x55\x19\xa0\x6d\xb5\xe6\xca\xb0\xdc\xc2\x79\x5b\xce\x89\xda\x6b\xad\x43\x49\x9c\xaf\x22\xb3\x24\x24\x78\x3a\x4c\x83\xde\x23\x5f\xae\x1d\x83\x14\x80\x18\xc2\x25\x07\xb3\xea\x8f\xc9\xf9\x05\xc6\x76\xc4\xfd\xa3\x14\x9b\x63\x59\xd4\x25\xd5\x55\x8d\x2c\x30\xee\x79\xcc\x37\x84\x7c\x34\x57\xb7\x86\x12\xd3\x36\x71\x0f\xfc\x5e\xad\xc1\x08\x68\x8d\x31\x9d\x83\xb2\xa4\xe1\xf5\xdb\x63\x63\x4e\x61\xfd\xda\xcd\xfe\x1e\x3c\xd7\xb6\x4a\x4e\xec\x15\x35\x65\xcd\xeb\x41\x0e\x89\x7b\x9e\xef\x1b\x7f\xed\x01\x5e\xb3\xf7\x35\xca\xb2\x52\x3d\x44\xa5\x6d\x0f\x91\xe0\xd7\x99\x2c\x5d\x59\x7a\xfb\x6b\xec\x13\xa0\x49\x23\xd6\x3b\xf7\x63\x20\x22\x1a\xc7\xdb\x3d\xfe\xd8\x43\x8e\x3f\x9c\x84\x67\xdb\xa6\x34\xdd\xc3\x15\xd4\x99\xec\x7f\x6d\x87\x84\xad\xc1\xef\x2d\x3a\xee\x79\xa1\x9f\x10\x8b\xfb\xf5\x76\xd5\xfd\x14\x1b\x59\xc3\xad\x1c\xa3\x25\xdb\x26\x25\x22\xd5\xf1\x74\xfe\x8e\xba\x6f\x6a\x98\x71\xcf\x8b\x83\x98\xf0\x29\xcd\x1e\xd7\x48\xee\xfe\x97\xf1\x0b\x8e\xa3\x88\x18\x6e\x17\xad\x13\x64\x00\x3a\xb6\x25\x91\x5c\x1a\x5a\xfa\xda\x85\xbc\x26\xc7\xa6\xe0\x85\xd6\xcf\xbc\x87\x42\xd9\xc2\x9c\xac\x2c\xac\xf9\x98\x5d\x5c\x0d\x78\x48\xd5\x93\xcf\x7b\x18\x3f\x28\xd8\x58\x3c\x28\xe5\xaa\x93\xdf\xba\x12\xfb\x0f\xac\xa1\xee\x50\x49\x50\x2a\x71\xaa\x8a\xc5\xbf\xee\xb7\xab\xcd\x76\x32\x36\x85\x67\x88\x7c\x5a\xe3\xab\x2b\x57\x4f\x5c\x63\x62\xd0\x71\x40\x7e\xea\xea\xbf\x63\xae\x86\xe1\xe4\x31\x9d\x69\x3f\xd8\xf5\xec\x95\x7f\xc7\x79\xe3\x9e\x27\x99\x71\x29\x8e\x15\x1e\xb2\xd3\xe1\x19\x9c\x6b\xd0\xb6\xc5\x86\x56\xf0\xcd\xc9\x93\x4f\x67\xf0\xe4\x54\x71\x4c\xc8\x21\xd1\xee\xc9\x67\xe7\x98\x74\x27\x53\x9a\x6c\x0d\x81\xad\xb1\xf0\x9c\xc9\x9f\x39\xae\xb3\x7e\xce\x28\xe6\x51\xea\xfe\xa9\x3a\xee\xf1\x54\x1b\x50\xa9\xac\xef\xa1\xec\xee\x47\x71\x54\xdc\x2c\x48\x4e\xee\xb3\xfd\x15\x05\x65\xd7\xad\xa2\xcb\xe6\x32\x1e\x73\x19\xf3\xe3\x9e\x87\xc2\x04\xf3\x3b\xb0\xda\xb6\xbc\xcd\x7e\xe1\x64\x60\xa0\x4e\x63\xa3\xf9\x71\x7e\xdc\x6e\xdc\x25\x35\x37\x08\x5f\xcb\x68\xed\x82\x77\xae\x55\x48\x6d\x13\x5f\x37\xa7\x3c\x3f\x7f\x9f\x61\xf7\x1e\x8f\x15\xd6\x4e\x7a\x1b\xc9\xbf\x3d\x15\xf5\x9d\x72\x4f\xc7\xbc\x40\x49\x13\x5f\x6c\xdd\xf2\xc3\xa9\xc8\x9a\xf3\x10\xd4\xd3\x76\x11\xc6\x9e\x35\x7e\xc8\xa6\x63\x40\xf8\xe0\x5a\xdc\x33\xdd\x17\xd7\x0f\x77\x8f\xbb\xcd\x6a\xbb\x6b\x87\xe6\x6e\xbd\x78\xbc\x7e\x7a\x18\x04\x3d\xb9\xc7\x7c\x2f\x26\x1e\xa5\xae\xc2\x6c\x83\xcd\x63\xd9\xac\x91\x02\x09\x20\x72\x7c\x2c\x07\x34\x06\xdc\x63\x41\xe8\x53\x10\xc3\xe6\xc7\x30\x2f\x8b\x63\x39\x4b\x52\xdb\x76\xb6\x42\x86\xcd\x6b\x45\x69\x29\xa8\xba\xd2\xdb\xee\x7c\x2a\x26\xcb\xda\x46\x83\x16\x79\xbe\xa8\x2e\xd1\x13\x93\x27\x0c\x90\x51\x46\xe6\x87\xf7\x13\x17\x37\x17\x22\xf9\x1f\x46\xe2\x46\x0e\x1b\x9d\x27\x54\x86\x7b\xdd\x65\x67\x6c\x43\xe8\x21\x67\x36\xbe\xd2\x9b\x90\xa3\xf1\xc5\x42\x5f\x11\xde\x96\x62\xb2\x0b\x55\x1e\x5b\xdf\x6d\x90\xb9\x68\xbb\x04\x48\x56\xd7\xa9\x38\xc2\xa9\xc6\xe7\xef\xcf\x5d\x4b\x22\x49\xf1\x52\x67\x79\x3e\x82\xb7\x71\x8f\xc5\x81\x51\x66\xb0\xca\xd4\x33\x44\x7d\x6d\x27\x30\x0a\x4b\xff\x8f\xb3\x7f\xd9\x6e\x1c\xc7\xb6\x85\xe1\x77\x39\xad\x6c\x9c\x06\x00\x92\x20\xf9\xf7\x64\x59\x76\x28\xd3\xb6\x54\x96\x1c\x51\x59\x7b\x9c\xa1\x81\xcb\x82\xcc\x32\x45\xaa\x48\x2a\x6c\xd7\xd3\xff\x83\x0b\x00\x6f\xa2\x23\x73\x7f\xbb\xb1\x23\xcb\x00\x29\x12\xc4\x65\x5d\xe6\x9a\xd3\xf9\x75\x76\x86\x7f\x2b\x73\xdd\x7f\xaa\x18\x00\x87\x16\x29\x6c\x41\xe4\xbd\xea\x2c\x23\x34\x09\x52\x04\x3a\xac\x8a\xa3\xab\x82\x1a\x6e\x8b\x34\x89\x04\xc2\xe3\xf2\xec\x3f\x97\x4c\x67\xcd\x67\x87\x35\x1a\x0f\x42\x92\xe8\xd0\xa3\xa0\xb0\x22\xd8\x71\x5a\xf8\xe2\xf8\xf1\x43\xa7\x44\xd9\xfa\x82\xf6\x40\x5d\x66\x15\x46\xe2\xfa\x2d\x84\x4a\x61\xc0\xa6\x26\xcb\x02\xaa\xec\x32\xac\x8e\x62\x84\x6a\xa5\xd1\x26\x28\xe0\x7d\xd9\x71\x8b\xcc\xee\x7a\x54\x03\x47\x96\xd2\x53\x01\xa7\xb2\xdd\x66\x96\xc3\xef\x02\x89\x55\x63\xb7\x93\xf8\x87\xdf\xfd\x96\x65\x55\x40\x85\xe5\x08\x16\xe3\x03\x43\xf6\x72\x1f\xb2\x6a\xaf\x4f\xad\x5b\x25\x5b\x9b\x60\xb2\x0f\x22\x15\x32\x1f\xe4\xd9\x56\x0e\x8a\xd5\x36\x71\xc0\xdc\x45\x99\xeb\xc5\xf9\x5c\x81\xca\xf0\xca\x67\x64\xd9\xc9\xba\x5e\x29\x87\xc8\x17\x25\x9f\x6d\xf4\x6e\x29\xce\xeb\x62\xd1\x34\x25\x8c\xfd\x15\x46\x18\x61\x29\x42\xdd\x00\x25\x75\x9c\x27\x4a\x99\x6f\x0d\x2d\xd2\x0f\xd5\x8f\x33\x35\xd2\x95\x98\xb1\x7b\x18\x81\x14\xc5\xa2\x65\xa6\xc7\xa0\x66\xd7\x4e\xb5\x41\x48\x10\xb2\x66\x1d\x6e\x5f\x9e\x17\xfb\xf5\xe6\xe9\x10\xb8\x87\x67\x8c\xdb\xb0\x86\x2d\xb7\x2e\x46\x31\xc9\xb6\x39\x0d\x30\xa3\xe5\x22\x05\x56\x34\x75\xfc\x04\x01\x4b\x95\xb3\x82\x0f\x22\xcf\x0f\xe8\x94\x64\xcd\x67\x31\x79\xef\x90\xd3\x18\xc6\x91\x8d\x79\xc2\x93\xbf\x72\xf9\xff\x3f\xfe\xeb\x1e\x23\x22\x8c\x87\xbe\x08\xbb\x11\x87\x68\xf2\x98\x51\xc2\x51\x12\xeb\x3f\x17\x91\x67\x26\x83\x7a\x51\x77\xfb\xfc\x8d\xc8\xf3\xb2\xf9\x6d\x34\xc0\x11\x44\x18\x94\xb3\x46\x6b\xa7\x68\x58\x5b\xba\x7d\xd7\x89\x13\x9e\xc6\x5d\xa7\x79\x59\x88\x76\xca\x0e\xf7\x15\xc6\x03\x48\x2c\x5d\x59\x6b\x52\x65\x8e\x61\x6b\x7c\xd6\x30\x2e\x08\x26\x14\xec\xd2\x40\xf1\xae\x83\x98\x58\x05\xc3\x23\x84\xc5\x31\x60\xe9\xde\xfd\x8f\xfb\xbb\xed\xc3\xcb\xee\xeb\x10\x78\xdb\x59\x5b\x29\xa1\xd5\xfe\xdb\x83\x05\x01\xfd\xdd\x80\x4c\x77\x83\xd8\xe3\x24\xbd\xb9\x36\x5c\xd9\x2c\x76\x25\xf1\xcb\x8d\x4b\xa3\x31\xc2\x12\x9a\xa6\x04\x23\x67\x16\x8e\x8a\x41\x27\x8b\x5f\xfb\x6a\x8a\x8c\x1e\x3a\x09\xb4\xb0\xd1\x2e\xdc\xdf\xfc\x4e\xb8\xda\x7f\x9b\xb7\x93\x58\xca\x08\xfa\x79\x77\xbb\xbd\x7f\x86\x14\xa2\xd4\x9b\x99\xa5\x9e\xe1\x97\x66\x84\x89\xd0\x22\x4a\xf3\xec\x94\x59\x56\x05\x7f\xb5\xe0\x56\xa2\xeb\xe9\xee\x9f\x03\x47\x82\x09\x15\x60\xf0\xd2\x27\xb9\x87\x2c\x0b\x93\x6f\x2f\x93\x18\x73\x95\x1e\x59\xb1\x2f\x3b\x36\xbb\x76\x8f\x2d\xab\x2f\x88\xbc\xdb\x4b\x65\x80\xae\xc0\xef\x7b\x74\x81\x54\x87\xdf\x6b\xdb\x54\x0c\x71\xc7\x27\x02\xd5\x4f\x91\x2f\x4b\x30\x26\xc3\xca\xb1\x81\x35\xfe\xf7\xd6\x92\x0a\x69\xe0\xea\xcf\x9e\x32\xf5\x86\x44\xb1\x97\x39\x7b\x98\x29\x41\x3a\x05\x21\xf1\x59\x95\x79\x3e\x6b\x81\x30\x1d\x51\x84\x9c\xef\xf6\xcf\xfb\xfd\xc0\xdd\x62\x9a\x83\x30\xc3\x34\x5c\x59\xd5\x57\x40\x62\x46\x18\x04\x29\x0b\x3b\x52\x19\xb7\xd3\x4f\xba\x28\x88\xc3\x2e\x19\x63\xa1\xb9\xe3\x35\x6d\x40\x22\x51\x20\x26\xaa\xd8\xc1\x5a\xfc\xf7\xa2\x7e\x69\xed\x59\x4a\x08\xa6\xad\xfc\x12\x0c\x48\xcc\xad\xaf\x52\x96\xf9\xba\x9b\xc6\x01\x31\x31\xda\x24\xc5\xe5\x74\x28\xe5\xbf\xc1\x8b\xbf\x33\x12\xb0\x20\xe6\x81\x23\x67\x87\xca\x94\xd5\x09\xc3\xb0\xd7\x54\x19\xc9\xd5\xff\xa7\x7c\x70\xb0\x05\x8c\x3b\x92\xa1\xf2\x52\xe8\xcd\xb9\xb3\x07\x82\x20\xe4\xc8\x92\x60\x79\x9c\xbe\xfa\x9c\xff\x73\x25\x7e\xfc\xb5\x87\x18\x04\x69\x92\xba\xaa\xbb\xfb\x2a\xf3\x95\x77\xa3\xcf\x17\x04\x3a\x45\xa0\x4e\xfd\x9e\x35\xea\x75\x5f\xde\x7a\xef\xa7\xf5\xf5\xda\x75\x34\xfa\x12\x41\xa0\x21\x0c\x3a\xe1\x17\x24\xe9\xb4\xbb\xc4\x5f\xcd\xbf\xf9\xf9\x18\x44\xcc\x72\xd8\x23\xb7\x96\x2f\xd6\xf7\x6d\x9a\x4b\xe7\x5e\x38\xf7\x00\x2b\xb2\x86\x9c\xda\xae\x27\x0f\x03\xc2\xbb\x1c\xc3\x43\x56\xbc\x81\xb6\x5b\xf6\x40\xa9\xde\xf7\x05\x4b\x11\xd0\x4b\xa2\x5c\x25\x52\xfb\xc7\x8b\x23\x9e\x7a\x4d\x52\xaf\xb7\xe3\x9b\x8c\x92\x43\xfc\x4b\x9f\x6a\x9e\xdc\x23\xd1\xd4\x1b\x1b\x78\x1c\x3c\x66\x05\xaa\x2e\xca\x5f\x72\x22\xb5\x17\x02\xc3\x3a\x93\x8e\xc8\xed\x41\xd4\xdd\xe0\x24\x90\x20\xdd\xcd\x29\xfb\xb8\x2b\xab\xd3\x25\xf7\x26\x50\x90\x32\xca\x89\x9f\x61\x74\x57\xe6\xba\x6b\xe1\x4e\xe4\x45\x18\x98\xa5\x2e\xc4\x3e\xb1\xb0\x81\xd5\xdb\x0c\xc6\x66\x73\x90\x26\x91\x76\x47\xc3\x0f\x80\xb7\xfc\xd3\xeb\xd8\x8e\xa7\x54\x9a\xa4\x88\x51\x10\x32\x1b\x6b\xb8\x62\x9b\x4c\x02\xb7\x92\xb7\x15\x9c\x45\xa6\x57\xcd\xeb\xfe\x1d\x06\xa7\xeb\x9c\xaf\x19\xa4\x32\x48\x6c\xd1\xcd\x37\x51\xbf\xee\xb2\x63\x01\x7a\x7a\x6f\x9d\x1a\xdd\xc7\xa6\xb1\xba\xfa\xcb\xe0\x1c\x23\x81\x08\x2c\xfb\x71\xa6\xca\x03\xda\xcb\xda\x27\x0b\xda\xc6\x38\x35\xb6\xd0\xa2\x29\x8d\x19\xe3\xda\xdb\x66\x99\x20\x01\x8b\x8b\x2c\x6f\xaa\xec\x98\x15\x22\xbf\x81\xee\x03\x49\x16\x60\x91\xbe\x43\x36\x59\xba\xac\x89\x87\x13\x28\x12\x20\xb2\xac\x3d\x73\x4c\x9e\x75\xb7\x57\x12\x90\xdc\x03\x83\xc9\xdb\x2f\x24\x10\x7c\x38\x2c\xd0\x81\x95\x61\x6c\x77\xd0\x4a\x43\x75\x33\x23\x80\xef\xbb\x0a\x85\xb1\x3c\x27\xa3\xe2\x04\xb1\xfc\xcf\x02\xd1\x18\x21\xdb\x5d\xce\x72\xe8\xac\x04\x10\x30\xac\xb0\x3e\x96\xb9\x5e\x9b\xbb\x91\x96\xa1\xeb\x62\x84\xb0\x5a\x78\x02\xd5\x79\x9b\xab\x76\x19\xf9\x12\xe0\x21\x6f\xd9\x2c\xb2\x6b\xf2\xa1\x0c\x28\x3c\x62\x1e\xca\xe3\x5f\x45\xa7\x47\xe7\x7d\x48\x48\x8a\xd1\x0e\x9f\x45\xbb\x2b\x2b\x3c\x31\x7b\x3d\xc0\xde\x92\x9b\x6c\x9e\x21\x49\x25\x56\x33\xdb\xfc\x80\x03\x4c\xcf\x00\x94\x19\x09\x69\x44\x11\xd8\xd4\x21\x1f\xb6\x13\xc5\xd7\xd1\x48\x84\x54\xa6\x69\xec\x73\x17\xd9\x7f\xc1\x4b\xdb\xfc\x76\x2d\x8b\xcc\x48\xc8\x98\x0d\x37\xd6\xd0\x2c\x2e\x8d\xd3\x34\xbc\xf9\x1c\xa9\xf7\x0c\x0e\x98\x90\x85\xb6\xb0\x21\x07\xf1\x13\xb0\x06\x7b\xfc\xb0\xcc\x91\x63\xd8\x3d\xef\x65\xc8\x27\x3c\xee\x07\x91\xea\xd9\x3d\x7b\x66\x93\xf1\xd3\x05\x2c\x89\xb4\x57\xae\xec\xf8\x48\xfd\xb1\x19\x86\x92\xa1\x10\x07\x7c\x28\x00\x5d\xb7\x73\x6d\x39\x46\xad\x33\x12\x46\x2c\xc2\x7d\xee\x74\xc9\x59\xc4\xfd\xa5\x9c\x58\xc1\xce\xe2\x58\xfd\xd7\xa3\x16\x7d\x5b\x0c\x21\x9a\x16\x9e\xe7\x07\x49\x3e\x9b\x2f\xf2\x37\x8c\x84\x89\xb2\xa0\x9b\xac\xb0\x3c\x4b\xe3\x77\x48\xc0\xea\x77\x6f\xc5\x67\x6b\x12\x8e\x7e\x29\x8d\x42\x6f\x05\xdd\x54\x00\x3a\x2b\x8e\x8e\xc7\xe3\x17\xf8\x73\x46\x42\x91\x24\x2a\xb2\x99\x97\x1e\xe2\x34\xda\x4d\xdb\xa1\xc1\xd0\xc8\xe2\xfb\x62\xfd\xb0\xb8\x79\x58\x59\x9e\xe4\xe0\x60\x65\x62\xfd\x13\x48\x6e\xed\xca\xe2\xe2\xd9\xc3\x56\xad\xf7\x0f\x93\x5d\x37\xd4\x81\xe6\x91\x47\xf7\x5f\x8a\xc6\x22\xc0\xea\x8d\x99\x99\x03\xc0\xe3\xd0\xa2\xf1\xdf\x45\xa5\xe7\x23\xb1\xa3\x2b\x22\xa2\x18\x9e\xd3\x0e\x7f\x7c\x57\x5e\xaa\xe6\xd5\x43\x0a\x19\x89\x68\x48\x54\xec\xf3\x86\xe8\x73\xa2\x08\x6f\x9f\x03\xc3\x3e\x56\xdf\xae\x79\xc3\x5e\xfe\xcf\x8c\x39\x75\x68\x2b\x9a\x6c\x25\x7f\xe6\x3f\x64\xc4\x02\x8d\x78\x24\x54\x5a\xec\x06\x16\x19\x5b\xb3\x13\x94\x97\x61\xf6\x21\xf9\x1f\xd6\xf9\x67\xe3\xff\xf4\x37\xd3\x40\x79\x47\xcc\x6c\x05\xb9\xca\x4b\xc7\xb3\x3d\x1e\xb3\x28\x70\xb5\x0a\x36\x57\xf4\x98\xb5\xdb\xf9\x36\x17\xe3\x0a\x1d\x3a\xf1\xa6\xa2\x80\x13\xe8\x28\xfb\xba\x22\x53\x1e\x4e\xde\x2b\x00\x8e\x0e\x54\x73\xa9\x8a\x8d\x31\x9b\x4a\x28\x74\xb7\x5d\x73\x18\x12\x4a\xc6\xd5\x4f\x77\x65\x65\x13\x1f\x7d\xcd\xfc\x98\x2d\xa4\xbd\x2c\x16\x21\x1b\xd4\x26\xdc\x8a\x0c\xeb\x46\xfd\xe6\xfb\x1d\x79\x5a\x2d\xd8\x76\x02\x9c\x6e\xaf\x96\xd6\x93\xb4\xb6\xf4\xfc\x3c\x8f\x22\xc5\xf0\xe8\xd9\x41\xa5\x5e\x5f\x6a\xa8\xa6\x3c\x2a\x93\xfe\x9c\x0b\x48\x9c\x41\xf5\x58\x16\x08\xc7\xce\x45\x5d\xef\xb2\x06\x76\xdd\xe1\x19\x71\x21\x31\x81\xf3\x04\xef\x4f\xa5\xb6\xfb\x29\x1a\x1b\xd5\x28\xba\x1a\xc5\xcc\x52\xdc\x59\x7b\xc0\x85\xaf\x71\xf4\xe0\xb7\xbf\x64\x2c\x6c\xaf\x0f\x08\x9a\x0c\xbb\xd5\xc3\x83\xff\xed\x38\x64\x88\x28\xf0\x86\xdd\x48\x85\x6f\xf2\x3a\x49\x40\x70\xe7\x6f\x1d\x78\xbf\x8d\x5b\x1f\x67\x36\xa6\x18\xa5\x8c\xa0\xd0\xce\x37\xf8\x1c\x6e\x33\x51\xaa\x22\x4b\x70\xef\x24\xc3\x37\xa8\xd6\x50\x8f\x38\x7a\x18\x89\x24\x4d\xd1\x37\x7f\x15\x75\x17\x03\x1c\x03\x6e\xda\x4e\x69\x40\x1d\xd1\xa9\x1d\x89\x09\xf5\x6d\xdb\x45\x50\x34\xa6\x6e\x77\xbf\x77\xaf\xad\x58\x82\x91\x54\xff\xda\xfb\x59\xb0\x64\xdb\x31\x56\x26\xf2\xcc\x04\x4b\x28\x9a\x4b\x75\x15\x87\x8c\x54\x6a\x85\x78\xdf\xfd\xed\x35\x21\xdc\x32\x7a\xc0\x5e\xbc\xc1\xea\xc3\x79\xc4\xbe\x99\x2b\x7c\x22\x5f\xc2\xb0\x3a\x1e\x87\x2b\xc5\xfb\x79\x91\x56\x04\xe3\x97\xe7\xb2\xf4\xfe\xe8\x52\x9c\xf7\x19\x54\xd4\xdf\x0a\x08\x30\xee\x33\x0b\x50\xd5\xcb\x3c\x33\xc6\x37\x9a\x40\x46\xc9\x88\x7c\xbc\xb5\xb0\x96\x97\x89\xd1\xce\x89\xa0\x91\xa3\x8f\x39\xfb\x0d\x8c\x53\x12\x63\x11\x93\x06\xd1\xbc\x62\x28\x4a\xb0\xae\x2d\x8c\x10\x60\xff\xed\xdb\xed\xf0\xcb\x72\x46\x0c\xd2\x30\x94\x5e\xb1\x7b\x55\xe8\xd1\x1c\xe6\x2c\x49\x30\xa0\xa2\xe1\x9c\x97\x9f\x18\x01\x70\x65\x3e\xbe\x03\x84\x91\x3b\x83\x6e\xb3\x0a\x94\xa7\x4a\xda\xbf\x56\x50\xbf\xb6\xf6\xfd\xf8\xd9\x03\x6a\x75\xb1\x2f\xc5\xc0\x93\xbe\xb6\x70\x78\xc0\x53\x34\x3e\x17\xcd\x6b\x0e\x43\x74\x1a\x23\x3c\xe4\xf6\x4c\x3c\xa0\x40\x3f\x12\x92\x0e\x93\x14\x3c\x8c\x01\x83\x9e\x58\x5c\x5f\x88\xdc\x71\xa1\xfa\xe6\x88\xea\xc8\xf2\x52\x0c\x0a\xaf\xc6\xe7\xcc\x97\x96\x17\x6f\x8f\xdc\x18\xf3\x96\x0d\x66\x75\xbf\xd3\xee\xb6\xa1\xb5\x49\x6e\xd7\x8b\xc7\xcd\xd3\xad\xff\x33\x27\xf1\x00\x07\xb9\x14\xc5\x1d\x34\xea\xf5\xb7\x7e\x27\xe4\x71\x64\x39\x8c\x5f\x3f\xcf\x58\xea\x09\x95\xf1\x64\x31\x6d\xab\x4a\x90\xf4\x7e\xcc\x74\x71\x57\x95\xa7\x2e\x84\xf3\xcb\xb4\x1d\x4f\x92\x08\x31\x8a\xb5\xc8\x61\x3d\xc9\x74\xf0\x24\xb5\x0a\xa5\xee\xe8\x74\x40\x15\xd7\x98\x06\x09\x62\xdf\x51\xc1\xce\xe1\x00\x86\xa5\xfb\x33\xc3\x93\x86\x1a\xa9\x8b\x84\xd6\xa8\x03\x3b\xf1\xe8\x79\xaa\x01\x99\xf6\xf6\x65\x21\xf2\x7f\x5c\x44\xd1\x5c\x4e\xdd\xcf\x19\xce\xd5\x50\xf8\xae\x7e\x2a\x9b\x55\xa1\x41\xaf\x8b\x85\xfe\x89\x31\x8d\xae\xab\xc2\xbd\x06\x3e\x54\x7e\xd1\xb0\x38\x49\x51\xd7\x42\x97\xd5\xac\xc2\x29\x23\x5c\x84\xa1\x09\x3a\xf5\xa0\xdf\x66\x0c\x79\x2e\x79\x28\x43\x1f\x2a\x17\x0d\x3c\x75\x3a\x45\xf4\x8b\x00\x01\x57\x46\x63\x74\x48\xe5\x20\x0a\x5f\x50\xde\xc5\x89\x26\xfe\x14\xd7\x84\xb2\xc8\x1f\x94\x76\x1f\x2b\x10\x51\xd8\xce\xc3\xd1\xc7\x4b\xfc\x15\xd4\x68\x87\xab\x7c\x84\xa3\x98\x8d\x71\x71\x1d\xf2\xc4\x22\x03\x33\xe5\x8e\x97\x7e\x12\xcd\x1e\x74\x1c\x54\x2c\xa8\xff\xb0\xad\xb7\x7b\x55\xb1\xfd\xe5\x17\x8e\x09\x4d\x11\xd6\xea\xb8\xce\x5a\x2b\xc3\x94\xd5\xc9\xbf\x51\x67\x3a\xc5\x24\x0e\x11\x0a\xf3\x4f\xa8\xca\x1b\xe8\x82\x03\x31\x49\x25\x42\xb1\xff\x2d\xd4\xdb\xb9\x6c\xb6\xe2\xe2\x79\xef\xdb\x46\xc9\xf1\x8d\x3d\xbd\xfa\xb6\x13\x3e\x64\x24\xa6\xa1\x41\xbf\xb6\x86\x66\x07\xb9\x41\xcc\xe8\x45\x35\x37\x50\x80\xc9\x54\x26\xc6\x88\x53\x46\x62\x16\x84\x58\xff\xf8\x08\xe5\xfb\x70\x07\x89\x59\xc2\x03\x8f\x4b\x7b\xdc\x4c\xaf\x4a\x6d\x18\xa0\x8b\x36\xc1\xcd\xa5\x69\xca\x62\x5d\x20\x1d\xa5\xef\xa5\x34\x7a\xc1\x4f\xf0\x5e\x77\x08\x20\x46\xe2\x80\x27\xa8\x51\x8c\x4e\xfb\x0e\xb0\x18\x76\xde\x60\x8c\xc3\x88\x23\x8e\x72\x69\xab\xdc\x7a\x21\xa5\xb9\x48\x7b\x1c\x2a\x7b\x0a\x3d\x66\x6f\xe3\x2a\x22\x46\xe2\x88\x25\x08\x93\x6a\xb7\x84\xb2\xfb\x23\x00\xda\x48\xe8\xca\xe1\x5a\xcb\x9a\x0c\xfc\x81\x11\xf3\x04\x20\xe9\xf5\x4b\xcb\x5a\xe4\x6b\xbf\x6b\xc5\x31\x51\xe8\xc4\xdc\x3f\xbf\x0c\x42\xce\x71\x1a\x12\xf4\xcf\x6c\x9e\x73\x10\x90\xeb\x86\x25\x4d\x39\xb1\xb1\x87\xe2\x27\x54\xcd\xad\x65\xa8\x1c\xaf\x84\x38\x35\x12\x91\xc0\x75\x6b\x19\x55\x93\x75\x12\x0b\xae\x10\x11\xde\x1d\x83\x2e\x14\xf6\x3d\xab\x2e\x93\xc9\x1f\x0b\xae\x91\x0c\x67\x7f\x79\xbb\xb9\x78\xac\x41\x2c\xa4\xc0\x75\xf9\x68\x39\x08\xbb\x3f\x2b\x89\x21\xa6\x43\x77\xe7\x67\xf8\xcf\x25\xab\x1c\x85\x91\x87\xaf\xce\x7f\x2c\x99\xa4\xf8\xbd\xbd\x11\xf0\xe0\x99\x8e\xda\x36\x6d\x2b\xcb\xd1\xad\xf0\x41\x00\xdf\x06\x32\xf2\x4c\xfe\xa2\x81\xb5\x2a\xdb\xa5\x82\x55\x8b\xbe\x8b\xe2\xa1\xb1\xaa\x01\xb6\x58\x67\xf2\x8e\x4a\xc6\xd6\xc0\xae\x44\xd1\x25\xd0\xaf\x99\x1d\x19\x89\x81\x87\xb8\x36\xcf\x19\xdc\xcc\xd0\x5b\x31\x12\x9b\xd0\x04\xee\xf3\xfc\x52\xba\x92\x91\x84\xe8\x04\x01\x1b\xab\xef\xfb\xe5\xfe\xe1\x17\xb1\xaa\x84\x06\x14\xb3\xad\x1a\x3c\x61\xc1\xd8\x9b\x4c\xa8\x63\xcb\xeb\x8d\xe8\x24\xa0\x09\x96\x90\x21\x2e\xf5\x30\xca\x9b\x27\x01\x63\xd4\x45\x15\x36\xe7\x6b\x76\x24\xec\x61\x85\x50\x16\x4d\x95\x89\xea\xed\xaf\x4a\xa1\xdb\x2b\x42\x40\x8c\xe3\x42\x6b\xe7\x7c\xce\xef\x8d\x49\x10\x41\xa2\x7a\x26\x0c\xff\x57\x15\x23\x57\xea\xe1\xb5\xdd\xac\x57\xc7\xe3\x64\x60\x93\x40\x49\xed\x8c\x64\xb5\xb0\x6a\x39\x7f\x6d\x4d\x20\xc5\xa4\x71\x71\xa9\x3b\xc8\xfd\xde\x99\x44\x0e\x99\x53\x43\xb3\xaa\x94\x8b\x14\xd6\x73\x2a\xdf\x6d\x67\x63\x25\x39\x3d\x86\xa2\xd0\xa3\x34\xef\xe0\x40\x49\xb8\xd0\x18\x7e\x7d\xcc\xe0\xfd\xbe\x0f\xbe\x26\x31\xb5\xea\xbd\x77\x65\x05\x4a\xa0\x23\x7f\x27\x54\x53\x4e\x77\xd4\x24\x09\x12\x95\xf8\x3d\x65\x0b\xd5\x0f\xe1\xf3\xd6\x49\x12\x69\x5b\xdc\x70\xbf\x22\x6c\xf9\xcd\xff\x39\x25\x21\x1a\xdb\xb8\x1f\xb6\xc7\x5d\xd7\x10\x33\x3c\x6f\xb7\xa2\x6a\x32\x91\x3b\xbb\xf1\xab\x0a\xaf\xc9\x94\x4b\x35\xb1\xc1\xc0\x77\xa1\x5e\x5f\x55\x99\x4d\x6c\xfc\x44\x90\x34\xed\xf3\xa8\x7f\x64\x4d\xf3\x65\xda\x62\x3e\xd7\x98\x88\x14\xd0\x38\x6e\xde\x41\xbc\xf5\xf4\xe0\xdd\xb2\x4d\x84\x21\xa9\x13\xd2\x59\xb7\x2e\xef\x5b\xbb\xd3\x0f\x26\xa9\x24\x09\xe9\xf5\x26\xad\x4a\xcd\x55\x35\x65\xdb\x2f\xb0\xc2\xd3\x05\x7c\xcc\x72\x77\xb7\x5d\x62\x1b\xe9\x59\x1c\xab\x0c\x19\x34\x30\xe4\xf7\xd1\x4d\x4f\x45\x09\xae\x98\x9b\x87\xcd\xf2\x8f\xc3\xcd\x62\xb7\x5e\x1e\xb6\xcf\xeb\xe5\xaa\xeb\x90\xd8\x5c\x01\x2a\xa6\x7d\x09\x82\xf4\x9d\x45\x8c\x77\x6b\x4f\xaf\xf5\xf6\x7e\xf2\xb8\xda\x74\x9c\xf5\xe8\x4d\xce\x15\xfe\x33\x92\x00\x55\xc8\x46\xfb\x5e\x65\x18\xa1\xd4\xd9\xc8\x26\x1a\xaf\x4e\x48\x52\x2b\xd7\xd6\xdc\x5d\x8a\x49\xaa\x25\x01\x29\xd0\x3e\x3e\x74\x89\xce\x5f\xc2\x83\x12\x90\x06\xc7\x33\x3f\xdf\x64\xda\x86\x11\xdc\xad\x52\x12\x6b\x3c\x78\xd0\x91\x59\xe6\x5e\x64\xad\x6d\x49\x43\x8b\xd9\xb6\xba\x8f\x93\x25\x3c\x16\xb9\xc2\xee\x06\xc9\x0f\x94\xcf\xe5\x8f\xb8\x48\xda\x0e\x92\x08\x04\xc6\xa3\x54\xc2\xfb\xb6\xca\x7e\x66\x39\x1c\x3b\x4b\x27\x25\xca\x20\xac\x4d\x95\x45\x7d\xc9\x9b\x49\xed\x84\xef\xa4\x2d\xdd\x41\x5e\x96\x6f\x97\xf3\xcd\xe7\xb6\x2a\xff\x0d\x6a\x32\x81\x52\xa2\x13\xc4\x19\xb6\x9b\xc3\xdb\x46\xeb\x69\xb3\x09\x10\xcd\x96\x43\xf3\xea\xd4\x18\x17\xcd\xb7\xac\xa9\x1f\x40\x74\x8f\x43\x79\x88\xa8\xa3\x83\x63\x01\xbf\x0a\x95\xcc\x4e\xcc\x94\xc6\x29\x42\x5a\x8e\x79\x29\x45\x0e\x83\xac\x75\x4a\x0d\xc3\xd8\xf0\x7a\xb9\x29\x7f\x42\xb5\xcf\x50\xd9\xb3\xcb\x52\xa4\x2c\x8d\x49\xa7\xba\xec\x0c\x09\xdf\x16\x12\x2b\x67\x21\x1b\x35\x08\x09\x39\x3b\x69\xf2\x7a\x21\xa4\xb8\xf3\x16\xf0\xfe\x7b\x29\xe7\xb8\x63\x18\x49\x23\x1e\x20\xd8\xbe\xce\x33\x05\x6c\xce\xfe\x4f\x23\xc3\x90\xdf\x08\x0a\xdd\x43\xca\x5c\x1b\x8f\x58\x14\x0d\xe6\x7c\xf7\xf7\x44\x3b\xb9\xcc\x77\x51\xe9\x6f\x59\x7b\x32\x7f\xda\xb2\x82\x31\xe9\x56\xdb\x57\xc6\x3c\xf1\x31\xd0\xb1\x2e\x75\xdb\xaa\x52\xf4\xfd\xef\x57\xff\x9c\xcc\x3d\xdf\xc1\xd8\x60\x56\x2f\x9b\x51\x77\x92\x28\x5f\xba\xd1\x69\xac\x35\x09\xbd\x28\x55\x03\x75\xb3\xb8\x34\xaf\x65\x95\xfd\x17\x29\xc6\x5c\x9e\x61\x3c\x0e\x31\x44\x08\x6f\xc4\xd0\x92\x14\xc5\xdb\xd0\xd2\x4c\x93\xd8\xe2\xad\xdb\x05\xe4\x84\x0e\x50\x85\xb0\x6b\x06\x1e\x4e\xcb\x5b\xe7\xcd\x86\x34\x81\x00\xf1\x5c\x0f\xe5\xf1\xa6\x2c\x8b\x4e\x02\xeb\x6f\x01\x5b\xd3\x34\x0d\x31\xe4\x89\x54\x67\x9b\x2e\x0c\x95\x8a\xc8\x0a\x64\x22\x14\x7c\x77\x39\x2d\x06\xbc\x6e\x57\xb7\x9e\xbd\xb3\x90\x31\x5a\x2b\xde\x98\xf1\xaa\x8f\x93\x0f\x22\x63\x82\xc6\xd6\x72\xf1\xf0\x70\xff\x17\xe5\x9f\x6d\xf7\x84\x28\x17\xa4\xfe\x99\x95\x97\xba\x6e\xc4\x11\xf2\xb2\xee\x17\x8c\x94\x56\xe6\x7e\xd5\xbc\xc2\xc7\x97\x39\xa4\xf1\xb3\x2a\x65\x99\xb3\xdb\x33\xa6\x80\xbc\x53\xf0\xb3\xf9\xc0\x61\x22\x2e\x05\xa9\xd0\x32\xcf\xea\xad\xc8\xba\x75\x6f\x02\x85\xe7\xe4\xe3\xfa\x69\xfd\xb8\x78\x38\x6c\x17\xcf\xfb\xf5\x72\xbd\x45\x5c\x97\xeb\x24\x08\x09\xa3\x76\x4c\x77\x8b\x87\xd5\x61\xf5\x74\x7b\xd8\xaf\x1f\x57\x5d\x23\x65\x88\x86\x5b\x2f\x37\x3e\x3e\xee\x5b\x52\x0d\x0a\xd1\x38\x8f\x8f\xe3\xc4\x81\xa0\x3c\x91\xb6\xf8\x25\x2b\xea\xad\x95\x67\xf2\x4d\xb1\x64\xd6\x9a\xfc\x18\x30\x89\x30\x22\x98\xa4\xe8\x38\x9a\xb2\x7a\xdb\xbf\x66\x7e\xe9\x88\x20\x8d\x6c\x89\xc6\xe7\x1e\x6a\x54\xbd\x1c\xce\x58\x11\x42\x82\x24\x53\x87\xd6\x4b\xaf\x3c\xa3\xfa\x2d\xe4\x70\x14\xcd\x97\x11\x03\xc1\x89\xb0\x3c\x29\xe8\x1a\x5c\xaa\x3e\xbe\x24\xe2\xc0\x2a\x9e\x62\xda\xdf\x21\x2e\xfa\xbc\x92\x88\x25\xc3\x6f\x72\x68\xdd\x76\x9b\x4f\x6f\x1d\xac\xf1\x32\x13\xb1\x8e\xac\xd6\x27\x14\x7a\x8c\x72\x19\x17\xc3\xbb\xee\x69\x2a\xb5\xe5\xec\x3a\x9d\x73\x94\x1f\x1d\x3f\xae\x50\x16\x59\x77\x84\xa6\x6e\xca\xf3\x75\xa4\x4e\x48\x41\xf0\xc0\xa9\x5e\xcb\xee\x4f\x26\xa4\xce\x36\x3b\x62\xda\xa4\x4f\x9a\x08\x25\x15\x7a\xc1\x7d\xc8\xd5\xc7\x9d\x5a\xff\xe5\xda\x57\xfd\x8b\xf9\x7a\xf5\xef\xf0\xe5\x74\x90\x20\x84\xe6\xa7\xcd\x21\xe1\x11\xd5\xa3\x87\xb6\x15\xa8\x9e\x97\xac\xed\x9e\x88\xc4\x95\xc3\xed\x41\x38\x92\x48\x5f\x2a\x30\x1e\x65\x60\x5d\xa9\x80\x2b\xaa\x1d\x48\xd0\xba\x3e\x86\x24\x78\x36\x1c\xce\xe2\x73\x2b\x3e\xe1\x2a\x3e\xfe\x7f\x27\xfd\x19\x09\xd9\x80\x3d\x71\x0b\xd5\x54\x05\x85\x11\x49\x58\x80\x96\xb2\xce\x6a\xf1\xb3\xf4\xa1\x66\x49\xa2\x28\x74\x80\xf3\xf2\xd2\x9d\xfa\xbe\x31\x0e\x11\x7f\x83\xb6\x32\xad\x2d\xe9\x4e\xd7\x98\x72\xf4\xf1\xcf\xab\xbf\x07\xa7\x92\x04\x04\xba\x95\xdb\xf2\xc7\xb7\xf0\xb6\xbb\x8d\xf1\x94\x71\xcd\x3d\x1e\xda\x58\x79\x7a\x55\xa6\xfa\xbf\xfa\xd7\x1f\xb3\x92\x4a\xe2\x4b\x98\x76\xcd\x45\x59\xc9\x97\xd9\x51\x94\x54\x13\xf4\x5a\xf6\x8b\xc5\xee\xf0\x7d\xf1\xf2\xe0\xc1\x72\x92\xc5\x96\x6c\xb3\x76\xd5\x66\x28\xaa\xdd\xdb\xd5\x92\x25\x42\xbb\xaa\xc6\xf5\xf6\x6e\xf7\xad\x0f\xbe\x48\x26\xac\xf8\x80\x3d\xe5\xba\xbf\xea\x14\x31\x98\x0f\x88\x66\xbe\x85\x53\xa9\x2a\xa1\x3e\x9f\x2f\x83\xf4\xc3\xbc\x9c\x29\x23\x32\x70\x2a\xdd\xeb\xc2\x64\x45\xf6\x31\x82\x24\xcb\x30\xa0\x48\x17\xa5\x1d\x48\xfc\x76\x20\x3c\xde\x36\x87\x92\xf9\xc3\xb2\xf3\xb6\x07\x6f\x12\x46\x31\x62\x58\x8b\xcb\x09\xe7\x7c\x17\x9c\x91\x28\x63\xe8\x52\xbb\xf2\x5a\xbe\x99\x11\x19\xd1\xd4\x53\xae\xdd\x88\xaa\xca\xa0\x5a\xd4\x08\xd9\x1a\xdc\x9f\x47\x4c\x3a\x36\xab\xac\x00\xed\xf9\x83\xba\x5f\x89\xc3\x04\xab\xc7\x9e\x57\xf7\x2f\x0f\x8b\xe7\xc3\xfe\xcf\xed\x2a\xe8\x1a\x15\x20\xdb\xef\x33\xfb\x67\x33\xd8\x4f\xa5\x88\x24\xfa\x90\x59\x81\xa9\xb7\x2b\xf7\x41\x0a\x65\xd0\xb5\x17\x5a\xdf\x96\x6a\xfc\xd4\x92\x00\x22\x57\x4a\x87\x49\xc1\x8f\x37\x1e\x70\xc9\x12\x4c\x71\xc9\xcb\x67\x74\x4d\xdb\x31\x2a\x5b\xbe\x02\x3c\x5e\x3b\x33\x52\x32\xa1\xbd\xa4\xbd\x2d\x4e\x1d\x8a\xe3\xcc\x04\x17\xa4\x0a\x43\x1f\xa7\xfd\x56\x76\x71\x4b\xa9\x24\x20\x54\x0a\x01\xff\xb8\xe7\x8c\x18\xbf\x47\xdb\xb1\xd4\x24\x74\x1a\xe8\x35\x34\x0e\xeb\x3a\x59\xec\x3a\xb4\x24\xe7\xb8\xb9\x42\xeb\x03\x57\x9f\x0b\x0b\x1f\x9c\x98\x64\xd2\x10\x85\xd3\xfa\x16\x2a\x64\x1e\x9a\xb4\x32\x13\xfa\xf3\xe6\x0a\x3c\x32\x57\xd1\xdc\x5e\x93\xda\x22\xab\x32\xd7\x3b\x80\x7c\x74\x62\x4a\x23\x52\x4c\x39\xc8\xb2\x7c\xb3\xd1\x04\xf5\x0c\x27\x61\xb3\xca\xb6\x8e\xa8\xeb\xaa\x01\x0f\x95\x9a\x85\xbf\xf5\xaa\x71\x6d\x03\x58\x9a\xe1\x1f\xa2\x51\xaf\x1d\x7f\x17\x23\x8a\x38\xb2\xc2\x23\x34\x3f\xda\x79\x5b\x56\xcb\x57\xa8\x1b\x8b\x4a\x71\x7d\x28\xb3\x1e\xdc\x19\xec\xf2\x5f\x17\x88\x02\x87\xdf\x2f\x43\x6c\xc1\xb5\xb9\xab\x18\x95\xc2\x91\x3a\xf5\xdc\xb0\xc1\x78\xbc\x14\x4b\x24\x32\x3f\xd5\xea\xd5\x85\x67\x47\x63\xa3\x98\x8e\x90\x7c\xbd\x23\x8f\x32\x26\xcb\x33\xd1\xc0\xb6\x6c\xa6\x5d\x4d\x88\x73\x55\x97\x1d\x45\xe2\x3c\x62\x55\x05\x09\xc5\x80\xaa\xca\x9a\xcf\x6d\x59\xe6\xfb\x01\xca\x40\x05\x12\xec\x17\xb4\xd1\x8a\x7f\x95\x27\x99\xcd\xf1\x0d\x32\xa2\xa2\x90\xa5\x96\x1a\xf4\x67\xf9\x36\x81\x01\xa8\x28\xb4\x24\x87\xcf\xcd\xcd\x20\x6a\xab\x3c\xa5\x92\x73\x2c\x16\x77\xfb\x3f\xa2\x47\xf1\xd9\x35\x27\x31\xe6\x64\xb6\xdf\x9e\xba\x3f\xc9\x30\xb5\x7e\x8d\x6a\x7d\x37\x4f\xfb\x8b\xc9\x0a\x9c\xc4\x96\x1b\xf3\x0b\x5a\xca\x71\x3e\xdb\xdf\x12\x2c\xfb\xc3\xaf\xf3\xfd\x3b\x9b\xce\x9b\xbc\x57\xcc\x2c\xd8\xf2\x67\x06\xef\xad\x83\xaa\x2f\x53\x1f\x58\x25\x51\xe2\xc5\xba\xdc\x23\x4e\x29\x51\xda\x4e\x3c\x42\xc4\xcf\xc9\xe9\x1e\xbb\x3f\xa7\x84\xa2\x25\xdf\x17\xd7\x2d\x6f\x6f\xaf\x67\xd9\xe4\x4b\xa4\x81\xe2\xcc\x7b\xdd\x13\x15\xe5\xb6\x59\xc7\x28\x5f\x89\x41\x5d\xc7\xb2\xbc\xd6\xd3\x4e\x26\x88\x1d\x2b\xd7\xcb\xf9\x8a\xb3\x90\x11\x25\x48\xe8\x85\x98\x56\xb5\xaa\xca\xf7\x9b\xeb\x9b\x08\x96\x32\x04\x7f\xbc\xdc\xdd\x0c\xd7\xb1\x12\x9a\xa3\x17\x9d\xd5\xdf\xa1\x6a\x0d\xa8\x87\xf2\x98\xa9\xb9\xfa\xdc\xb6\x33\x08\x54\x9c\xad\x2f\xd5\xb9\xca\x6a\xd8\x8a\x42\x7b\xd8\xa6\x92\x2c\x36\x76\xd6\x61\xbc\xbc\x2b\x99\x69\x8d\x35\x30\x65\x05\xe3\x90\x8d\x92\xb1\x54\x96\x61\xcf\x0e\xf4\x2f\x83\x79\x4a\xf1\x24\x71\x21\xf2\xc5\x4f\xd1\x88\xea\xe6\xb3\xc3\x7f\x0f\x4f\x0f\xa5\x62\x19\xf6\x85\x3b\xb3\x29\x5b\xd7\x53\x33\x1a\xd2\xbe\x82\xef\x01\xd5\xb7\xbb\x4a\x06\xd7\x09\x42\xc5\xf9\x00\xbe\x2e\x7a\x0e\xc7\xb6\x55\x52\x3c\x60\x77\x80\xdc\xe1\x9e\x8d\x74\xfc\x3b\x20\x23\xab\x0f\x56\x89\xa2\xd9\x97\x3b\x68\x5e\x6c\xb1\x97\x1e\xeb\xe1\x0e\xce\x17\x65\x02\x40\x86\xeb\x76\x47\x6d\xa0\x68\xe7\xea\xe1\xe4\xa5\xe3\x19\xd1\x84\x10\xfc\xe6\x2e\x41\x36\x70\xaf\x35\xa1\x02\x0d\x44\x0c\xff\xd5\x0d\xba\x7b\x57\x04\x1a\xc3\xc3\xd2\x5f\xa7\x68\xa0\xbc\x5d\x26\x9a\x4b\xfd\x58\x6a\x47\x8b\x3f\x7a\x1f\x4d\x53\x8a\xa6\x75\xc7\xbe\x86\xf9\xd7\x61\xf1\xb3\x0e\x04\x91\x3d\x0f\xf4\x28\x63\xac\x03\xa3\x18\xf1\x48\xab\x1d\x80\xee\x69\x04\x18\xd1\x9c\xda\x0c\x39\x3e\xba\x55\xfe\xf2\x67\xf1\x6d\x56\xbb\x72\xc3\x55\xd1\xfe\x47\x77\xc7\x98\x6a\x44\xda\x1d\x2a\x38\x97\xe7\x5f\x81\x33\x47\x73\x4a\xc7\x9c\x52\x8b\x89\x3f\x65\xc5\xa1\xf1\x4e\xdc\x6f\x93\x5e\x89\x2d\x81\xee\xa4\xe1\xf3\xa1\xfa\x65\xdb\x41\x07\xb8\x35\x60\x10\xcf\xf3\xda\x58\xce\xe4\xbe\x4b\x82\xf6\x90\x78\x3d\x09\x7d\x25\xcf\xcf\x88\x4e\xe2\x10\xbf\xf7\x1d\xf4\xaf\x95\x68\xab\xf8\x8e\xf0\xae\x6e\x39\x4d\xe1\x32\x3a\x8d\x0c\x42\xaf\x2c\xce\x71\x8d\x77\x1d\xe7\x56\x74\x9a\x30\xe6\x72\xc4\x8b\xe2\xb3\x2c\x60\x29\x8a\x51\xfc\x7f\xa0\xd6\xe4\x2f\x11\x36\x95\x75\x44\x56\x0e\x5b\x48\x87\x14\xec\x73\xf0\x2f\x2d\x89\x42\x23\xf5\x86\xd1\xd9\x15\xf7\xd5\xbf\xfe\xf2\x80\x6a\xee\xa7\xc4\x5d\x59\x35\x97\xa2\x33\x06\xb4\x4c\x29\x3e\x89\x3d\xf7\xb6\xa2\x6a\x66\x44\xc2\xbe\xf8\xc2\x2a\xb0\xea\x31\xf2\x6c\x57\xf7\x64\xe8\x54\x48\x62\x57\xfd\xaf\xb3\x51\x11\xab\x56\x21\xc7\x5d\xf7\x94\x15\x96\x82\xd7\xe1\x95\x46\x59\x28\xad\x14\x60\xcd\xce\xf6\x79\x75\x58\x3e\x6f\x7e\xdc\x62\xf4\x63\xb9\xd8\x76\x1d\x20\x8d\x93\x31\xdd\xd9\x17\x35\xb9\x5a\x73\x62\x7c\x3e\xa7\xb0\xda\x9e\xdd\x80\x0f\xcb\x24\x3c\xfc\x4f\x9b\xd8\x60\xac\xe3\x76\xb1\x5f\x1d\xf6\x9b\x3f\x56\x4f\xbb\xc3\xcb\xd3\xc3\x66\xf9\xc7\xca\x7b\x72\xda\x28\x8d\x49\x01\x9f\x91\x74\x87\xcc\x64\xf6\x19\x23\x2d\x7b\x57\xbb\xe8\x90\xab\x64\x07\x9e\xa7\xdd\x76\x01\x12\x5b\xba\x2b\x47\x24\x29\x2a\xbd\x6c\xed\xde\xd1\x7d\x10\x7d\x8d\xb6\xc5\x1e\x4d\x8b\x19\x46\x3c\xd7\x91\x12\x1e\x58\x81\x19\x70\xf4\x27\x37\xfb\xa5\x28\xf4\x30\xe5\x09\x94\x09\xc4\xc6\xd9\x0f\x6f\xfd\xdc\xd9\xc8\x2d\xb0\xc8\xd6\x37\x76\x85\x06\x2e\x4e\xe8\xef\x14\x04\x36\x54\x7c\x5f\x96\xfa\xa6\x3b\x81\x20\xd0\xd2\x33\xfd\xa3\x3a\xd0\xc4\xc8\x83\x28\x88\x31\x72\x9b\x0d\x85\xaa\x17\x79\x05\x42\x7f\xda\x80\xe1\x15\x28\xc2\x5f\xc9\x29\x42\x49\x6e\x6c\xa1\xfb\xab\xa8\x44\x39\xf1\x61\x20\x8a\x03\xac\x32\x40\x88\xfc\xb0\x74\x0f\xa2\xd4\x26\x7b\x6c\x0d\xec\xab\x38\x9d\xb3\xb2\xe8\x14\x27\x19\x01\xce\x24\x56\x75\xed\x9a\x0a\xc4\x29\x6b\x3e\xed\xb9\xdf\x35\x87\x31\x50\xbf\x71\xdc\xb4\x2f\x97\x7b\x6d\x93\x29\x89\xe2\xe4\xb9\x79\x64\x01\x97\x35\x1e\xca\x65\xb5\xc8\x2a\x3d\xcc\x52\xce\x04\x66\x80\x0b\xa6\x3a\x7f\xbe\xba\xcb\x20\xd7\xb4\x7b\x12\x48\x11\x33\xdf\xcc\xa5\x91\xfd\x64\x88\xb9\x46\xe6\xcd\x03\xea\x5d\xdc\x0f\x2b\xba\x66\x57\x35\x24\x31\xf1\xee\xc1\xed\x6e\xbf\x43\x59\x4f\x54\xc1\xf2\x3f\x9b\xa4\xb1\x2d\xe7\xdb\xfc\x78\xf6\x7f\x4b\xe3\x14\xa3\x89\x96\x14\xee\x46\x14\x6f\x93\xaf\x9d\x26\xd2\x84\x7d\x65\xd9\xc8\xaa\x80\x54\x58\xdd\xc4\x33\xe6\x85\xfb\xe8\xe9\xf8\x16\x82\x45\x81\x65\xc9\x76\x01\x74\x9f\xb0\x1c\x96\xfc\x5c\xc7\x8c\x26\xaf\x27\x02\x8a\xc1\xc8\x23\xd6\x5f\xce\x87\x1e\x41\x24\x3a\xe1\x9d\x8d\xef\xc4\xad\x66\x4a\xcf\x40\x32\x91\x74\x3a\x1e\x13\x85\xd3\xbf\xb5\x3b\x83\xe4\x36\x44\x6b\xaa\xf2\xbf\x50\x78\x39\xce\x5f\xbf\x83\x14\x96\x25\xf3\xe8\x24\x94\x8e\x5d\xec\x16\x14\x31\x84\x8e\xe4\xcf\x7f\x52\xd6\xfa\xf8\x07\x77\x8b\xae\x63\x6c\x4d\x81\x1a\x44\xa5\x5e\x31\x05\x34\xac\x4f\x07\x4d\xad\xf4\xbc\x14\x7a\x46\xce\x7e\x38\xc3\x74\x1a\x76\xdc\x58\xd6\x80\x3b\xa8\xb1\xd9\x0f\x5a\x40\xd4\x13\xc1\x5c\xd7\x8e\xcf\x39\x5a\x00\x44\xa5\x6e\xca\xbc\x54\xf9\xf8\xd0\x05\x88\x42\x24\x97\x43\x72\x89\x41\x6e\x6f\x3c\xb8\x20\x38\x06\x01\x56\xbb\xcd\x16\x85\x83\xbe\x20\x0d\xee\xb4\x09\xfd\x75\x52\xa0\xc1\xe0\xec\x24\x8b\x72\x2a\xab\x97\x3a\x2b\x8e\x4f\xf0\x3e\xf1\x6a\xc0\x44\x31\x92\x4b\xc8\xcb\xe9\xec\xcd\x97\xd1\xbb\x18\xc2\x63\x4c\x46\x6e\x9f\x57\xfb\xdb\xd5\x28\x84\x65\x08\xb7\x64\x41\xb8\x21\x1d\xda\x13\xe6\x65\x3b\xbd\x3c\x8e\x50\x0f\x1d\x01\xe0\x13\x0f\xc5\xb4\xfe\xb4\x41\xe8\x51\xd6\x97\x7b\x7f\xa1\x3d\x3e\x5c\x76\x06\x4f\xff\xff\xf3\xff\xfb\x3f\xdf\xa1\xca\xcc\x12\x1c\x15\x50\xbb\x6d\x75\x9c\xf3\xc3\xbd\xc8\x50\x22\xc0\x86\x39\x6c\xc5\x6a\xbd\x7a\x5e\x52\x1e\x5d\x63\xdd\xf0\xa2\xb0\xbb\xca\x68\xdd\x09\xe3\xe3\x9b\xf7\x2c\x8d\x6d\x7b\x62\x63\x1d\x06\xd4\xeb\xf7\xb2\x81\xdd\xe5\xf4\x74\x39\xdd\x95\x55\x7b\x64\xcd\xa0\x71\x0c\xd5\x49\x24\x3b\x93\xcc\x2b\x3e\xcd\x42\xf3\x4c\x40\xad\xdb\x64\x1d\x4b\xd5\x2d\xd2\x71\xee\xcf\x04\xad\x85\xee\x42\x79\xed\x21\xb9\xfa\x68\x2a\x31\x1f\x36\x35\x01\xa7\x28\x7e\x53\x22\x08\x7b\xe5\x20\xd9\x93\x0f\x16\xe8\x90\x7a\x85\x1c\x51\x79\x11\xdf\x51\x3a\xc0\x84\x84\x86\x18\x14\x38\x97\xf9\x98\x0b\xbc\x6d\x4c\x6d\xa3\xa3\xf9\xf8\xb4\x32\xb6\xa3\x6d\xd3\x84\x3a\x16\xa2\x53\x6a\xb2\x6a\x5b\xfe\xfa\x28\xa4\x88\xde\xf5\xa6\xc9\xa2\xfe\x87\xab\x7f\xd7\xde\xc8\xf3\x3d\x05\x91\xb6\xda\x43\xe8\x3d\x88\xd3\x0c\xfb\x21\xf6\x32\x18\xc4\xdb\x78\x79\x7d\xef\x37\x58\x61\xef\x2b\xc3\xd9\x44\x90\x68\xed\xe3\x6f\xe3\xc0\x9b\xe1\x51\x42\x79\x2f\xf9\xf9\x0b\x37\xd2\xc4\xd4\xba\x62\x8b\xff\xf8\x9c\x89\x89\x59\x8c\x26\xab\xd3\x1a\x9f\xf4\x8f\x2c\x31\x76\xeb\xc9\x56\xa7\xcf\x5d\x99\xeb\x0c\xaa\x7a\x39\x94\x65\x77\x5d\x13\x42\xd1\x40\xb1\x89\x80\x5f\x7b\xc8\x26\xe1\x80\xc6\xd7\x21\xab\x6d\xfe\xfe\xa7\xc8\x72\x14\xd8\x72\x1d\x04\xb7\x85\x58\xd0\xbc\xee\xa0\xd0\x3b\x71\x72\xba\x48\x5f\x84\xb5\x8d\x88\x89\x24\x9d\xcf\x6d\x6f\xd6\x61\x38\x65\x6e\x8d\xc9\x2f\xe6\xa0\x64\x12\x37\x6f\x8c\xa7\x62\x52\xfe\x66\xbf\x1c\xc4\x9d\x8d\x0c\x38\x06\xbb\xda\x79\x95\xfc\xee\x9f\x51\xa6\x12\x5d\xb9\x87\xf2\xb8\x2b\xab\x06\xb4\x15\x53\x1b\xdf\x5b\x85\x49\xe2\x85\x55\x5b\x13\x07\x05\x35\xa6\x7d\x0c\xc3\x48\xec\x52\x0c\xa8\x64\x8c\x4e\x12\x2b\x74\xe4\x88\x01\x46\xc9\x43\x03\x22\xf2\x7a\x4d\x2f\x35\x54\x7b\x51\xbf\x2d\x9a\xb9\xa9\x06\x90\xa0\xea\xe0\xa1\x35\x38\xb7\x7e\xa2\x52\x42\xa4\x41\x7f\x22\x2f\x73\x31\x58\x2b\x94\x50\x47\x89\x73\x84\xe6\xe1\xe1\xbb\x25\x17\x67\x89\x6f\x65\x71\x80\x69\x0e\x79\xf9\x84\xca\x01\x04\x7e\x79\xbe\x52\xc2\x52\xe3\x6a\x8e\x32\xf5\x06\xc5\xb7\xce\x27\xa1\x84\x69\x63\xcd\x29\x4b\x81\xe8\x40\xb2\xb5\x6f\x0e\x15\xc3\x90\x05\x6a\x6a\x81\x38\xad\x8b\xba\x11\xfd\xd5\xa1\xd2\xb6\xe2\xb0\xbd\xd8\xee\x06\x1b\xb3\x53\xe2\xd4\x67\x2f\x29\x09\x75\x82\xfa\x0a\x0b\xad\xbf\x41\x0e\x45\x36\x50\x87\x18\x3f\x67\x08\xd2\x50\x07\x79\xbb\x34\x30\x4b\x11\x43\x49\x68\xac\x2a\x4b\xfd\x96\x15\x6b\xbd\x2f\x7b\x6d\xab\xbe\x4f\x94\x02\xef\xbd\x81\x8e\xa8\xa1\xd0\xe8\x9e\xd5\xaf\x13\x79\x42\x7f\x95\x22\x9e\xaf\x7e\xb9\x1b\x83\x78\x29\xe1\x91\x41\xd0\xe4\x29\x2b\x6c\x70\xa7\xe8\x13\xf8\xb3\x8b\x8c\x12\x1e\xcb\xa0\xcb\xbe\xa1\x4b\xd2\xbe\x12\xca\xf0\x0c\x92\x86\xf3\x89\x4c\x77\x76\x53\x12\xa7\x04\xd3\x7e\xad\x21\xfa\xe3\xb5\xcc\xad\xf9\x76\x1c\x91\xc4\x50\x12\x8b\xd8\x2a\xa5\x59\x15\xc8\x3e\xd0\xf5\x85\x00\xe3\x2f\xc5\xcf\x07\xbc\xf7\xee\xf6\x89\x8b\x08\xb6\x2f\x7f\xf8\xe2\xeb\x25\x21\xc7\xda\xfa\xac\x3e\xbc\x7d\xaa\xc9\x06\x4a\x49\x4a\xa4\x9d\x69\x1a\x54\x85\xe0\x89\x75\xf1\x13\x0a\x9c\xbe\xf3\xd3\x36\x8d\x89\x8a\xba\x42\x87\x83\xba\xda\xf3\x28\x49\x65\x88\xbe\xa8\xcc\x9a\xfa\x51\xd4\x6f\x7e\x38\x52\x65\x45\x57\x7d\x71\x74\xf3\xfa\x0b\xaf\x84\x12\xc1\x01\xbc\xea\x95\xc7\xc0\x4c\x0e\xe0\xab\xdc\x00\x25\x22\xb1\x84\x9d\x96\xd3\x0e\x97\xb0\x25\x4c\xaa\xe7\x91\x30\xed\x15\x7a\xc0\x13\x74\x5f\x89\xe2\x92\x8b\xa9\x5a\x63\xdb\x4f\xda\xed\xae\xb8\x9c\x36\xe6\xf7\xac\x38\xe6\xd0\x2d\x27\x01\x16\x57\x55\xf7\x75\xd2\x2e\xd6\x35\x2e\x8d\x73\xdd\x65\x0c\xb8\x5a\xd0\x5c\x19\xf0\x78\xce\x7f\x43\x29\x52\xdc\xf2\x34\x9c\x2e\x55\xfb\xfd\xef\x00\x06\x91\x0e\x4a\xa4\x0a\xe3\xae\x54\xdb\x81\x86\xb2\xc2\x6b\xc6\xb7\x1d\xb4\x25\x27\xe8\x09\x07\xbe\xa1\x01\xf9\x90\x29\xc0\x30\x7f\x97\x95\xa1\x44\x51\x5b\x2b\x82\xf5\x8d\xc8\x59\x31\x19\x07\x15\x09\x94\xf6\x3e\x58\xdb\x08\x7f\xa9\x9a\xcc\x2b\x15\x59\xda\xc2\x89\x51\x32\xfc\xbc\x9a\x86\x98\x78\x94\x97\xaa\xd8\x3e\xaf\xd6\xcb\xcd\xb0\x54\x93\x12\xcd\x24\x66\x35\x11\xe0\x78\x78\x7c\x79\xd8\xaf\xb7\x0f\xeb\xd5\xf3\xc1\x76\x66\x5d\x3f\x00\xe6\x32\x7f\x0e\x08\xbe\xb9\x34\xbf\x0d\x06\x1b\x58\x98\x38\xdd\x91\xdb\xac\xf6\x68\x0e\x05\x45\x23\x8e\xf0\x00\x3f\x21\x0f\xfc\xbd\x20\x0e\x42\x5b\x9b\x72\x53\x7e\xac\x1b\x38\xad\xa7\x2f\x0f\xa9\x08\x1c\xd2\xca\xd5\x24\x21\x6e\x48\xe4\xf5\x64\x04\x4c\xa4\xb5\x18\x73\x6b\xff\x4a\x5f\xc0\x5f\xa5\xa4\xe1\xc3\x2d\xf2\x54\x2e\x2f\x4d\x06\xb3\x2e\x64\x6b\xf4\x5a\x29\x86\x3a\xfb\x2f\x0c\xec\x5d\x4a\x0c\xa4\x81\xa5\xad\xb5\xa7\xdf\xbe\xf4\x2b\x67\xf4\x7b\x78\x70\x69\xef\xe1\x20\xe9\xb1\x5b\x2c\x56\x50\x67\x86\xc1\x86\x52\x12\xe9\xc0\x79\x45\x95\x55\x89\x7c\x2a\x8b\xa1\x7a\x6d\xdb\x87\x53\x54\x86\x36\x59\x21\xf2\x8e\x00\xb9\x6d\x10\x11\x32\xf3\xb6\xa7\xf3\x6c\xe4\x85\x52\x4a\x08\x62\x5c\xec\x18\x5c\xed\xe6\xfd\x97\xa5\x34\x4c\x11\xf6\x26\xbd\x00\xa6\xe5\xd3\x19\x8d\x11\xa5\x89\x55\x22\xb0\x6c\x0f\xeb\xe5\x06\x83\xd5\x7e\xfa\x50\xaa\x08\xf2\xd3\x5a\x2d\xcd\x5b\x2b\xf2\xfc\x78\x69\xb2\xaf\x33\x43\xf3\x07\x3a\xa5\xda\x46\x39\x37\x85\x8d\x1c\xbb\x52\x50\xff\x43\x2c\xb5\x62\xc8\xb5\xc8\xa1\xfc\xd9\x2d\x5e\xca\x20\x36\x0e\xe7\xf0\x90\x59\x60\x93\x5f\x03\x34\x08\x42\xa6\x3b\x2a\x64\x87\x3e\xd8\xb6\xb6\x52\xdf\x45\x08\x8c\xd3\xdf\xec\x1f\x0e\xeb\xc7\xc7\xcd\xf3\x7e\xf1\xe0\xdb\x42\xaa\x82\x5e\x7a\xd1\xd7\x14\xdc\x5d\x06\x34\x77\x53\x70\xad\x2d\x75\x64\x49\x77\x07\x8d\xb5\xc3\x56\xbd\x6a\xd5\xbc\x3a\x6e\xeb\xb2\xfb\x09\xa3\x31\x21\xb7\x40\x5e\xb2\xa1\xc5\x44\x23\xdd\x59\x4c\x3b\x38\x65\x56\x1f\x74\x32\xff\x22\x63\x39\x94\x9f\x41\x65\xf0\x13\xf4\xe8\x03\x4e\xc6\x97\xf3\x10\x0b\x57\x17\xcf\x4b\xff\x13\x5c\x46\x88\xd7\xb7\xb4\xf9\xb8\x27\xb2\xc9\xe7\x4f\x08\x0d\x2c\x1e\x6e\xb9\x98\x35\xff\xdb\x2e\x31\xf3\x0c\x2b\xbf\x8d\x7e\x32\x89\x29\x6e\xac\xf7\x53\x07\x91\xd2\x24\x21\x08\x1f\x3c\x89\x0f\x2c\x81\x43\x2b\xc2\x86\x96\x6f\x44\x0d\xc3\x38\x28\xa5\x29\xb3\x7a\xcc\xb6\x2e\x6d\xac\xaa\xec\xbb\x84\x52\xd9\xc3\xf1\xe7\xf2\x32\xd8\xa0\xfc\x2d\x04\x09\x3b\x72\x66\x51\x37\x50\x37\xbb\xb3\x50\xd0\x7a\x49\x83\x2e\x5a\xfa\xd9\x72\x5d\xb5\xd3\x76\x30\x98\xfc\xeb\x69\x49\x3a\x8d\x88\xf1\xc3\x08\x2a\x45\x32\xce\xc0\xb9\xa0\x51\xde\x4f\x5c\xc9\xe2\xa8\xef\x74\x63\x45\x0e\xf7\xd9\x09\xee\xca\xca\xcb\x0a\xcd\xbe\xaa\x0c\x0d\x1a\xcb\x68\x81\xb9\x2c\xcb\xa4\x47\xcc\x04\x52\xb4\x5c\x24\x9d\xb7\x43\xa8\x96\xb6\x36\x04\x53\x36\x4f\xf0\xbe\x6b\xc4\x5b\xbf\x70\x80\x25\xd2\xb1\xf1\x3c\x58\xf1\xc5\xc1\xb6\x01\x9a\xa3\x44\x61\xbb\xe4\xc7\x75\x3c\x94\x1a\x22\x7d\x60\xd2\x6a\x77\x3f\xc3\xf9\xd2\xe0\xe9\x8c\xef\xf2\x52\xb4\xfb\x43\x0d\x7d\x7f\xc0\xed\x63\x27\x72\xd8\x98\xe5\xab\x38\x41\xf3\xdf\xae\x31\x48\xd1\xb2\x58\x2d\x37\x87\xdd\x9f\xbb\xfd\xea\xf1\xf0\x6d\xf3\x70\xbb\x7a\xee\x3a\x00\xa8\xa8\xb7\xad\x71\xf6\xdf\x42\xde\x88\x1d\xe4\xf9\x97\xbc\x65\xbf\x5a\xba\x57\x55\xe6\x73\x62\x92\xed\x2f\x9b\x94\x58\x55\x88\x4c\x41\xf7\x6d\x27\xe6\x21\x23\x10\x31\x87\x1c\x7c\xf3\x88\xbd\x5f\x46\x76\x29\xa3\x31\xf7\xf8\xe7\xdb\x4a\xbc\x0f\x4e\xff\x9b\xcf\x01\x6b\xd6\xe0\x02\xad\xe2\xa8\x0f\xd1\xb7\x87\x69\xe7\xf1\x52\xc6\xa2\x58\xc3\x20\x69\x71\xfe\x8b\x9f\x0f\x08\x8d\xc0\x93\x70\x59\xec\xd2\xc1\x64\xd6\xc6\xff\x96\x15\x28\x9c\xb7\x76\xd8\x04\x6f\x1e\xb1\x20\x8c\x79\x17\x1c\xc3\x50\x5c\xd6\x20\xfb\xd4\xb6\xcc\xf3\xc9\x90\x04\x11\x49\x82\x8e\x10\x7e\x77\x91\x35\xd2\x77\x4f\xa3\xb6\x94\x85\x14\xc2\xb0\x3f\x26\x37\xc6\xce\x9f\x1a\xf4\xa2\xb6\x3c\x0c\xde\xec\x60\x91\xe4\x18\x6c\xea\x62\xec\x2e\x44\x36\xfa\xf0\x2c\x74\xbd\xb9\x48\x91\x8a\xa6\x02\x3b\x13\x67\x77\x4b\x16\xab\x80\x08\x17\x6d\x6a\xbf\x01\x42\xb0\x46\x07\x2d\x8b\x0d\xa4\xae\x8a\x77\x53\xd8\x14\xee\xfc\xbd\x92\x24\x24\xc4\xc5\x7b\x7d\xc5\xc0\xbe\x23\xfd\xa5\x2c\x49\x2d\x19\xe6\x63\xa6\x5e\x05\xe4\x3d\x28\x85\xb2\x44\x58\x19\x7b\xdc\x93\x0e\x28\xf4\x77\x50\xa5\xee\x56\x2a\x4b\xa3\x50\x3b\xa0\xe2\x42\xeb\xd9\x19\xe6\x7b\x02\xc3\xf8\x2e\xda\x14\xa3\x60\x0f\x65\x82\x1b\xcb\x08\xd8\x1a\xad\x2b\xcc\x8f\xf9\x96\x24\xb2\x22\x64\xaf\xe5\xfb\xe3\xe7\x30\x38\x46\x99\x50\x21\xe6\x85\x5f\x8a\x4c\x95\x55\xd1\x8b\xd6\x62\x5b\x8c\xd4\x28\x27\x9c\x34\xef\xbb\xf3\x68\xee\x7e\x31\xfb\xa4\x09\x28\xf7\xe2\xff\xe7\xaf\x5e\x44\x05\xc6\x31\xfd\xb6\x87\xaa\xa7\x2d\x76\x89\x9a\xf3\xd4\x80\x61\x2a\x32\x48\xd6\x89\x06\xf9\x60\x1f\x63\x2a\xa1\x91\x03\xb4\xe0\x2e\xe8\xd7\x4f\x37\xb6\x9a\xc7\x38\x53\xce\xe2\xf3\xb9\xfc\x14\x79\xd3\x8d\x0a\xe6\xdb\xf0\x41\x5d\x92\x70\x00\x54\xa2\x0c\xa4\xd4\x7c\x40\xaa\xdc\x6e\xa1\xbf\x8e\x66\x30\xc3\x09\x82\x2c\x00\xf3\xfa\xd7\x45\x01\xde\x3f\x0b\x48\x2a\xc0\xb1\xb7\xb5\x67\x85\x07\x44\x76\x6e\xdc\xd4\xa1\x0b\xa8\x72\x72\x0f\xa2\x1c\x05\x54\x69\xc0\x38\x43\x43\xd1\x39\x22\x73\x31\xc5\xb6\x93\xad\xc7\xb0\x32\x4b\xf7\x5d\xb5\xb7\x5f\x05\x01\x4b\x43\xa4\xab\xed\xb0\x10\xdf\x44\x8d\x70\x88\xee\x67\x14\xe0\x4a\xba\x59\xec\x56\x87\xc5\xe3\xe6\xb0\xdf\x1c\x56\xfb\x6f\x87\xe7\x85\x27\x59\xa7\x01\x03\x89\x23\xbd\x6f\x37\x96\x4b\x35\x62\xf0\xa1\x41\x10\x09\xed\xa0\x86\x0e\x41\xb3\x38\x1e\x2b\x38\x8a\x6b\x7e\x6f\x7f\x45\xa2\xa9\xec\x2a\x4e\xea\xbe\xec\xda\x46\x4d\xfa\x87\x0b\xb4\x06\x87\x0f\x6d\x72\xb8\x81\xe6\xfb\xf8\xc0\x4c\x7c\x3f\x08\x30\x00\xdb\xf3\x43\xf5\x16\xc6\xec\x17\x0d\x42\x92\x68\xaf\x38\x89\x47\x61\x59\x39\xfa\x18\xdf\x81\xd1\x50\xfa\xca\x62\x28\xdb\x59\x54\x4f\xc6\x36\xe4\x80\xf1\xd9\x5a\xfc\xec\x64\xea\x47\x23\x13\xa6\x2c\xf6\xb0\x06\xcb\x4d\xb1\x15\xd5\xd7\x30\x65\x77\x55\x14\x25\xdc\x23\x89\xec\x55\xed\x54\x42\x07\x68\xfa\x04\x51\x42\xad\x73\x7f\xa9\x9c\x36\xde\xba\x7b\x81\x48\x33\x44\x00\xb6\xdb\x1a\x7a\xe2\x03\xfe\x6f\x1a\xf0\x98\x4a\x8f\xdf\x69\x4f\xf7\x83\x35\x83\x3c\x74\x9e\x06\x3c\xa1\xca\x45\x81\x2d\x0d\xce\xe4\xa7\x63\x92\x86\x3d\x25\xc4\xaa\x79\xbd\x12\x55\x6d\x3b\x71\x6d\x35\xd7\xd4\x2b\xe8\x4b\x0e\x7a\x18\x61\xa7\x41\xaa\x98\x70\xbb\xf8\x3b\x6e\x40\x7d\x65\xa1\xff\xb2\x82\x71\xb4\x5e\x4b\x63\xa0\x5a\xd4\x3b\xa1\xaa\xcc\x64\x0a\xee\xaa\xf2\x34\xc8\x49\xd3\x40\xc4\x0c\x49\x5f\x1f\xb2\xe3\x6b\x53\x9a\x7b\x91\x8b\x8f\xcf\xae\x51\xa5\x18\x0f\x14\x5a\x8f\x5c\xb3\xd1\x5c\x9a\x4d\x39\xd3\x40\xe8\x10\xcb\x58\xdb\x8f\xf0\x03\xe0\x6d\xff\x5e\x76\xb7\x85\x14\x63\x38\x05\xbc\xdf\x5f\xf1\x7c\x5e\x8b\xeb\x0d\xfd\xcc\x40\x80\x96\xce\x92\x58\xe4\xb9\xf5\x8b\xbe\x12\xb8\x66\x34\x90\xa9\x05\x32\x3b\x78\xec\x1c\x93\x19\x0d\x54\x10\xc4\x4e\x20\x2e\xb7\xa4\x91\x56\x72\x55\xe4\xb9\x14\xea\x8a\xb1\x6e\x1a\x98\x1b\xc4\x2f\x02\xcd\xad\x50\x35\xd8\x92\x47\xe4\x85\x1c\x3f\x91\x4e\x4c\xe8\x3e\x9e\x8b\xba\xd8\x05\xf4\x74\x39\x4d\x7b\x4a\x86\x7c\x31\xed\x36\x36\x9f\x06\x9d\xbc\x2c\x70\xe2\x1d\x8a\xfd\x5b\x81\x11\x76\x07\x6b\x99\xf4\x4b\x42\x3c\x17\xbd\x97\x62\xb7\xf3\x41\xa4\x20\x00\xc1\xa5\x1c\x50\x31\x38\xdd\x53\x7f\x46\x06\x26\x0c\x3d\xd6\xbf\x9d\x18\x6e\x0b\x46\x1a\x36\xdf\x23\x15\x7a\xc8\xa8\x31\x07\x6e\xa6\x81\x01\x12\x86\x1e\x85\x57\x37\xed\x4e\x30\x97\x4d\x6b\x3b\x32\x19\xf7\x12\xe1\x95\x50\x13\x76\x47\x1a\x32\x22\x30\x6a\x71\x70\x91\xc4\x71\x95\xfc\x78\xa8\x42\x16\x42\xac\x2d\x1b\x71\xa7\xc1\xf3\x9b\x6f\x13\x96\x6c\xd0\xeb\x40\x57\xc7\x6c\x62\xc6\x85\x41\x04\x5e\x14\xd1\xfe\xcc\x18\xf1\xe7\x7b\x69\x81\x59\xce\x76\x96\x6e\xcc\xfe\xb5\x2a\x3b\xf8\x13\x0d\x43\x12\x21\x57\x04\x1e\xa7\x1d\x0a\xec\x8b\xc7\x0d\xb9\xc2\x70\xc0\xa5\xc8\x9a\x5b\x30\x50\x4c\xd2\x7e\x34\x8c\x42\x6e\xcb\xb4\x36\x2f\x4f\xb7\x37\x9b\x3f\xfd\xcf\x44\x22\xf4\xd5\x8b\xcf\xd0\xce\xe6\x41\xdc\x25\x8c\xc0\xea\x1d\xb5\x76\xf1\x4d\xd6\xec\x5a\x2f\x32\xb3\x64\xf1\x9b\xcd\x8d\xef\xc5\x19\xc5\xd7\x90\x99\x0e\xc6\x40\x0f\x77\x30\x27\xfe\x58\x0e\x79\x08\xb1\xa5\xa6\xdf\x14\xd0\xe9\x5e\x33\x1a\xc6\x71\x62\xe3\xeb\xa7\x6c\x98\x6d\xa4\x61\x9c\x32\xde\x65\xd3\xaf\xf4\xd5\xc6\x0b\x35\x4c\xc2\x18\xc1\x11\x45\xd9\xb4\xbb\x19\x4e\xcd\x0e\xcb\x4b\xc3\x84\x27\x81\x9b\xd7\x76\x4d\xbd\x14\x59\x33\xcd\x97\xd1\x30\xa5\x60\x49\x71\x40\x95\x85\x76\x8b\x70\x88\xff\xa2\x61\x1a\x25\x18\x66\xc4\x9a\xea\xe5\xcb\xf3\x73\x47\xc6\x4b\xc3\x94\x33\xab\x1c\xa0\xa1\x68\x1f\x03\x2a\xb4\xa2\x87\xbb\x54\x98\xa6\x71\xe0\xe6\xc7\x5a\x95\x6c\xce\xe1\x0d\x53\xc5\xb1\xd2\xda\xb8\xca\x8c\xfd\x6b\x75\xad\xe0\x3b\xbf\xad\x85\xc2\x70\x3c\xb8\x85\x52\x70\x6e\xfa\xf2\xac\x76\x31\x7e\x35\xe5\x25\x0d\xb9\x4d\x71\x94\x95\x25\xb8\x99\xdb\x60\x43\x29\x39\xc6\x6e\xd0\xa0\xce\x7a\xa3\x22\x54\x4c\xf8\x93\xdd\x69\xa4\xbe\x3c\xaf\x27\x33\x5e\xa5\x1a\xd9\xa9\x7e\x54\x59\x03\xad\x6d\x32\xac\x9a\xa7\xa1\xd2\x32\x21\x83\xea\xca\x3e\x7f\x3f\xc8\xdb\xd3\x50\x6b\x91\x58\xd9\xc2\xe3\x25\x17\xd5\x80\x07\x86\x86\x10\xd9\xe2\x05\xef\x15\x79\xd1\xb1\xf9\x09\x03\x91\x09\xdc\x66\x7b\x57\x56\x38\x25\xf0\xdc\xbd\x03\xa8\x7b\x1e\x31\xdf\x39\x11\xa1\x97\xe5\xc3\x40\x3e\x06\x09\x26\x86\x77\x68\x62\x6a\xc0\x47\xe9\xef\x2e\xb9\xc9\xf2\xbc\xb5\x69\x3d\x0a\xda\x9b\xb6\xec\x2a\x42\xf8\x3f\xf1\xff\x1b\x9f\x98\x1e\xf2\x47\x23\x42\x52\x44\xe1\x35\xd9\xc9\x89\xe3\xfa\x06\x15\x79\x0c\xf8\x1f\xf0\x59\xf7\x7f\x8e\x91\xc6\xaa\x80\xf7\x75\x03\xa7\x5f\xa1\x59\xda\xce\x3a\x72\xfe\x47\xbb\xf8\x47\x04\x9d\xae\x0b\x35\x29\x96\xb4\xef\x97\xfb\xd1\x44\x8e\x18\x51\x58\xf0\xdf\x5b\x88\xd6\x12\x71\xef\x31\x38\x78\xfd\x05\x32\x44\x4f\x78\xf3\xe3\xe9\xb0\x3b\x59\xcf\x19\xb7\xeb\xc3\xf4\x4b\xf5\x3e\x4b\xc4\x14\xc7\x6c\xde\xc3\xe6\xfb\xea\xcf\xcd\xcb\x70\x83\x88\x58\xbb\x6b\x0d\x76\x7e\x47\x01\x3d\x77\xb0\x45\x41\x6c\x99\x6b\x90\xd4\xd0\xb2\xbb\xa0\x9b\xfb\x8f\x0b\x5c\x6c\xa9\xf2\xa4\x7f\x22\x10\xe2\xe6\xd8\x33\x96\xa2\xb5\x28\xba\x41\x0e\xa4\xad\x35\xfb\xd7\xef\xff\xfa\x7d\xf4\x48\x81\x34\x68\xd7\x7f\x04\xa3\x3f\x87\x2c\xb6\xf2\xd4\xe2\xad\xb5\xb9\xe7\x97\x61\x14\x46\x09\x26\xdf\x6b\x91\xff\x14\x47\x78\x2a\xbb\xd2\x24\xcb\x16\x8a\x72\x1c\x57\x88\xae\xc9\x3d\xb4\xc2\x90\xdd\x49\x7c\x3c\x66\x45\x33\xd8\xdc\xa2\xc8\x69\xca\xdc\x77\xe6\x05\x3a\x53\xe8\xc8\x8f\x98\x6e\x7c\x7f\x61\x30\x51\xe2\x82\x4d\xf3\xb9\x37\xea\x37\xf8\x88\x8b\x94\xab\x81\xaa\x20\x0a\xff\xf9\x7b\xc5\x01\x43\xb3\xfa\x67\xd9\xf4\xa8\x18\xdf\x16\x59\x9c\xbf\x1e\xd0\x78\x0f\xc1\x48\x34\x8a\x85\xad\xfd\xbd\x87\xe6\x46\x14\x6f\x50\xf5\xea\xb7\xce\xaa\x8d\x52\x66\x05\x94\xff\x14\xe5\xa3\x40\x3d\xf5\xbf\x64\x7f\xa1\x51\x1a\x52\xcc\x06\x77\xd9\x13\x27\x18\xd5\x1e\x0e\xf4\x06\x1a\xe1\x1f\x40\x04\x52\xb9\xa0\x83\xdb\xb6\x46\x16\x6d\x24\xc2\x04\x8b\x3e\x20\xcf\x8e\x99\xcc\xe1\xae\xac\xc6\x91\x89\xf1\x9a\x12\x5c\x41\x2f\xc6\xed\xb3\xc8\x13\x88\x35\x8d\x84\x0a\x51\xe2\xbe\xdd\x47\xc6\xe8\x2e\x1a\x09\xe0\xdc\x09\x93\xb7\xfb\xd7\x0f\x90\x75\xd6\xfc\xa2\x08\x8a\x46\xc2\xd8\xf5\xea\xa2\xbd\x6f\x50\x0c\x79\xd3\xfd\x7d\x65\x00\x68\xd7\x9b\xaa\x3c\x59\x80\xe5\xc0\x86\x8d\x64\x14\x62\x10\xbb\xc3\x16\x3b\x3b\x78\x53\x2c\xf0\xb8\x99\xa9\x39\x98\x3e\x86\x14\x1a\x7f\x60\xbf\xdd\x4f\x62\xa9\x91\xd4\x01\xe9\xf3\xfd\x3f\xca\xea\x0d\xaa\x6d\x59\xe6\xbf\x7d\x91\xfd\x9e\x1f\x5c\x69\x38\x71\x71\xb4\xbb\x0a\x00\xa7\x74\x75\x07\xa0\x47\x06\xfb\x34\x16\x7a\x85\x58\xa6\x91\x92\x89\xee\xf3\x4a\xeb\xdc\xaa\xde\x7c\xcd\x78\x44\x23\xa5\x48\x40\xc7\x15\x2b\xb3\x36\x6b\xa4\xb9\xe4\xae\xe3\x3e\x83\x6a\x63\x66\x78\xee\x69\xa4\x53\x82\x35\xb9\x0e\x91\xe4\xd0\x56\x03\xb6\xd8\xc9\xcf\x6b\xe8\x42\xfe\x5b\x51\x75\xca\xcb\xe3\xa9\xaa\x21\x4e\xfd\x4f\x8b\xe2\xad\x3b\xed\xbb\x0e\xc0\x22\x0c\x1f\x5d\xac\xf2\xb2\xa5\x39\xe8\x3f\x92\xa1\x0a\x6d\x9c\xd2\xf1\xbd\xee\x2c\xbf\xeb\x75\xa8\xcb\xf7\x4f\x78\x04\x1e\x72\x85\x75\x66\xb3\x23\x62\x14\x60\x1c\xdd\xb3\xe2\x7c\x41\x6f\x4f\x39\x49\x03\xe1\x5e\x72\x5d\xef\x5f\xb3\x4a\x0f\x8d\x00\x4e\x43\x83\x2b\xb1\x12\x85\x2e\x4f\xbb\xb7\xac\x58\x9c\xcf\x20\xaa\xc1\xc6\xc6\xa9\x26\x48\x9f\xd2\xb8\x48\xda\x36\xb8\x3d\x4c\x7e\x85\xc5\xb6\xbe\xa4\x3d\x5a\x44\xe5\x57\x1d\x0f\x74\x98\x0a\x57\xb9\x0b\x7a\x59\x56\xdd\x3d\x03\x30\x48\x8a\x78\x2f\x8a\x63\xe1\x8a\xcf\xe7\xab\x40\x29\x0f\x13\x5b\xfb\x90\xa9\x72\x8c\x49\xa5\x3c\x22\x34\xb4\xf9\xad\x9f\xe5\x38\x0b\xc1\x23\xb0\x45\xc5\xbe\x28\xa5\xab\xbd\x74\xdb\xf6\x5d\x59\x3d\x8a\xe2\x22\xf2\x67\x5b\x9d\xf7\xd9\xdd\xd3\xd8\x94\x83\x57\xf9\xd8\x35\xad\xd7\x75\xcc\xd4\x28\x7f\xce\x79\x9c\x86\x64\xc4\x24\xb2\x28\xb4\x03\x32\xce\xef\x63\x3c\x26\x86\xb1\x2e\xea\x34\xbf\x28\x78\x4c\x2d\x0c\x62\xf5\x51\x3e\x66\x45\xe6\xd2\x59\x5f\x0c\x4d\x12\x87\xe8\xf5\x15\xf0\x7e\xbb\x98\x80\x77\x78\xa2\x52\x24\xfa\xeb\x39\x2f\x3d\x84\xe7\x01\xf4\x71\x30\x03\x47\x33\x9e\x27\x4a\x60\xb4\xb9\x70\xd0\xa6\x01\xa2\x98\xf2\x94\x04\x38\x38\x8e\xb7\x70\xff\x31\x5e\x2e\x3c\x8d\x43\xdc\xf9\x2b\x64\x7a\x7a\x2a\x6d\x06\x2c\x13\x13\xf5\x41\xca\xd3\x84\xe3\xe1\x0d\xed\x07\xd5\x02\x95\xcd\xcb\x49\xee\x82\x8b\x28\x0a\x83\x2e\x44\x71\x57\x56\x4e\x46\xb6\x37\x84\xb9\x10\x04\xfd\x8b\xb3\x83\x3b\x0d\x8a\xac\x28\x97\x60\xeb\xb0\x5e\x4b\x9d\x4f\x9c\x06\xae\x28\xc7\xd7\xb4\x41\xf3\xd5\x87\x13\x75\x1f\xe0\x31\x26\x63\xad\x40\x7b\x5d\x8c\x2d\x14\x22\x6f\x3e\x6f\xb3\x5a\x5e\xaa\x7a\xc2\x69\x42\xb9\x4e\x03\x9c\xb0\xe7\x2a\x53\x57\x9e\x3a\xd7\x40\x63\xe1\x5b\xd1\x9a\xa0\xfe\x79\x81\x89\xb4\xa3\xd8\x1e\x14\x97\x50\x0e\x41\x18\xa6\x93\x9a\xbd\x19\xf0\x00\x07\xc1\x02\xa7\x5c\x89\xd8\x09\x2c\x18\x98\xdf\x6a\x38\x88\x08\xec\xb7\x6a\x57\x86\xfe\x6a\x4b\xe2\xa0\x78\x2a\xbd\xdd\x98\x97\x97\xfe\xa1\x94\xc1\x88\xd7\x5e\x8a\x32\xef\xfe\x68\xec\xba\x38\x57\xe5\xc7\xa7\x93\xa3\xbf\x06\x19\xf4\x87\x64\x4c\x40\x22\x0f\xed\x49\xbc\x41\xd5\xe9\x02\x61\xa2\x7a\xf4\x1c\x71\xeb\x9a\x0b\xaf\x9c\x98\x41\xfd\x07\x7c\x4e\x7b\x44\xcc\x49\x8d\xc0\xbb\x14\x6f\xde\x1e\x89\x69\x0c\x18\x6b\xac\xb3\xaa\x67\x77\xef\x1a\xb5\x8a\x03\x8b\x2d\xfc\x67\xfb\x7c\x7f\x11\xa4\x72\x57\x31\xa1\x30\x4a\x70\xa8\x6c\xd8\x13\x27\x50\xfd\x3c\xc9\x19\x8d\xe6\x45\x1c\x50\xea\x0d\xf0\x1f\x65\xa5\x47\x8a\xa7\x34\x0e\x02\xc3\x7d\x40\xf8\xf6\xe7\xc8\x79\x88\x03\x41\xd1\x95\x5c\x3f\xad\xf7\xeb\xc5\xc3\x61\xbb\x79\x78\x38\x3c\x6d\x9e\x3c\x35\x19\x8d\xc3\x48\xa1\x4a\xa0\x5f\xb5\x43\x73\x32\x0e\xe3\x18\x61\x2f\xeb\xe5\xe6\xb0\x5d\x3d\x2f\x57\x4f\xfb\xc5\xfd\xca\xeb\x8d\xd1\x38\x94\x09\xa2\xcf\xfd\x4e\x61\xad\xc6\xf1\xac\x8e\x43\xad\x2c\x0f\x0d\x42\xf1\x10\x3b\x33\xc5\xc8\xd3\x38\xa2\x1a\xf7\x87\x9b\xcb\xf1\x06\x05\x2e\x3b\x4e\x21\x1a\x47\x2c\x45\x7e\x12\x55\x9e\xce\x55\x79\xca\x6a\x98\x58\x69\x31\x8f\x22\x4f\x82\x6e\xd3\xca\x7d\xc4\x61\x06\xfc\xde\xf6\xd7\xcc\x49\xf6\x3c\x74\xe9\xf1\xbf\x55\xf8\x46\xe3\x98\x11\xed\x7c\xd4\x6f\x90\xeb\x11\xc7\xc6\xf8\xc5\xe3\xd0\xa0\xbb\xbe\x7c\xd9\xed\x37\x8f\xab\xe7\xc1\x10\xfa\x07\x8f\x13\xab\x91\x90\xd5\x1b\x4f\x02\x8d\x03\x13\x12\xdf\x41\x74\xc4\x32\x96\xed\x04\x2b\xbf\x5d\x63\x42\x03\x4b\x7c\x89\x46\xe1\x42\xd6\x3d\xa2\x7a\x72\xd0\xc6\x69\xc4\x11\x1c\xb4\xdf\xec\x37\xd3\xd2\xa3\xf1\x53\xa7\x49\x2c\xac\x54\x4a\x7e\x15\x0c\xf2\x5d\x0c\xc1\x95\xb7\x9a\x68\x22\xd0\x58\x08\x89\x59\x9d\x83\x97\xc6\xf0\x42\xfc\x93\xc7\x11\x3a\x88\x84\x17\x1d\x17\xf9\x40\x6f\x8b\xc6\xc2\x50\x34\x2d\x3a\x5d\xd4\x3f\x3e\x65\x17\xe0\x9c\x3c\x89\x4c\x63\xb4\xf0\x91\x17\xf2\x51\x7c\xf4\xd5\xba\x34\x96\x9a\x20\x4b\x71\x3b\x6d\x2e\x0d\xb4\x16\xee\x28\xc4\x14\x2b\x21\xd1\x97\xb9\x87\xa6\x8f\xfe\x8d\x9f\x53\xa7\x12\x5d\x03\x0f\x8d\xfc\xe8\xe9\x03\x47\x7b\x91\x96\x09\x58\x62\xc6\x9b\x81\x3c\xc0\xd8\x85\x73\xf6\x6e\x6c\x98\x9d\x7c\xcb\xe7\xef\xa3\xb1\x33\xc0\x95\x63\x70\x7f\x2e\xbf\x98\xb9\x09\x8d\x04\x15\x5d\xf2\xc2\x82\xc2\x10\x1f\x86\x21\x8b\xd1\xc3\x27\x34\x05\x2c\xae\x70\x03\xb0\xa8\x9a\xac\x6e\xf6\x1f\x77\x00\x73\x82\xf9\xed\x05\x8a\x62\xe5\x0b\x52\x73\x3f\xc1\xbb\x9b\x91\x76\xbf\xa1\x2c\x19\xb1\x7f\x4c\x1c\x8e\x84\x01\xd7\x16\x37\xf8\x79\xc8\xcb\x9f\x80\xe7\xe9\x18\x39\xfc\x0b\xc5\xd8\xf6\x7a\x89\x7b\xed\xe5\x6b\xd6\xbb\x2f\xff\x1d\x0d\x11\x33\x31\x22\xaf\x90\x53\xeb\xe5\xf1\xb0\x7d\x79\x5e\x7e\x5b\xec\xfc\x9a\x4b\x98\x31\x2e\xb7\x95\xe7\x8f\x4f\xcb\xc9\xa0\x05\x91\xc0\x2d\xef\x70\xd0\xd9\x71\xda\x06\x41\x4a\x7c\xcc\xb9\xc9\x27\xd0\xa3\x24\x64\x12\x53\xa8\x63\xdd\x73\xbf\x99\x26\xa1\x8b\xd8\xef\xa1\x6e\x58\xff\x47\x5b\x1f\xaa\xab\x1f\x59\xb1\x7c\xb5\xa4\xb1\xe3\x5f\x0d\x13\x9b\xaa\xef\xab\xba\x04\x0d\xbb\xeb\x4d\x8a\xc5\xb4\xfb\xe7\xc5\xd3\x6e\x8d\x6a\x90\x3f\xd6\x4f\xb7\x9b\x1f\x7d\x07\x4b\x38\xd4\x19\x73\xa0\x5e\x9d\xe8\xdc\xe4\xf1\x23\x12\x33\xa7\xd7\x70\x86\x62\x07\xc7\x53\xe7\xda\xf8\x1e\x01\x41\xf4\xe0\x59\x54\x4d\xa6\xb2\xb3\x28\x2c\x50\xdb\x86\x7a\xbf\x28\xaf\xea\x5f\x24\xe2\x56\xb9\x01\x81\xa9\x50\x37\x9b\xf7\x2e\xb4\x99\x44\x09\x45\xe4\xed\x6c\xc2\x3c\x89\x12\x2b\x10\xd4\x38\x51\x29\xf7\x67\x4e\x04\xc1\xc8\xf5\x78\x43\xf3\xad\x54\x59\x25\xde\x97\xdb\xf5\x7e\x75\x7b\x58\x3c\xdd\x1e\x16\xdb\xed\xf3\xe6\xbb\x2f\xe2\xa5\x49\x2c\x6c\xbc\xba\x86\xe6\xbe\x02\x18\xd2\x3a\xd3\x24\x96\x36\x90\x63\xad\xc8\x81\xe2\xa0\x6b\x4f\x62\x85\xe9\x8e\x57\x31\xd9\x96\x92\x34\x22\x18\x25\x7f\x7e\x98\x27\xa5\x1b\x44\xde\x12\x11\x51\xdc\x3a\x5e\x8a\x3b\xac\x02\xc4\x47\xb0\x02\x89\xf3\xc3\x28\x62\x6e\x8b\xe2\x31\x5e\x3f\x21\x1a\x9e\xf6\x4d\x79\x48\x7a\xae\x2e\x1f\x54\xb9\x0a\x1a\x26\x52\x59\x9b\xce\x85\x4a\xb2\x2b\x63\xf6\x2b\xdc\xd2\xf4\x3e\x3a\xc2\xf9\x08\xed\x37\xee\x0b\x6b\x69\xa2\xb4\x25\x3d\xdf\x6e\x36\xdb\x8d\x8f\xe4\x27\x3a\xe2\x81\x65\x3a\x11\xb9\x8d\x45\xfd\x80\xec\xf8\xda\xcd\x38\xcd\x15\x2a\xe1\x2a\x91\xab\xa9\xf8\xca\xe4\x97\x75\x9a\x84\xb2\x8b\x6c\x57\x9f\xdb\xd6\x8e\xec\xee\xa3\x03\x4c\x78\x63\xdd\xee\x1a\xd3\x06\xcd\xe7\xd8\x05\x49\x20\x8c\x78\x9f\x17\xbe\xf1\xd8\xd5\xc9\x6a\x84\x50\xd0\x4e\x4b\xa7\xcc\x75\xf9\xde\xcd\x17\xe0\x49\xec\xc5\x18\x2c\xbf\xdd\x10\x16\x92\x40\xcc\x63\xed\x29\xed\x26\xfc\xbe\xe3\x33\x38\x01\xb0\xf9\x11\xa1\xf5\x42\x7b\xd4\x91\xfb\xe7\x57\x7b\xa8\x91\xb6\x9e\x54\x89\x3c\xff\x31\xa1\x6b\xf5\x5d\x34\x55\x21\x5a\x63\xa7\xb3\x28\x3e\x9f\x06\x9f\xc8\x40\x18\xa7\x83\x84\xe1\x33\x14\x83\xb7\x33\x46\x22\x06\xfb\xee\xf2\x35\x61\xfd\x97\x10\xb8\x2f\xfe\xbd\xe2\xca\xa0\x29\xa1\x06\x21\x8e\xfe\xf1\x2d\x2a\x76\x76\x76\xa7\x24\x8c\xd1\x0e\x79\x14\x75\xeb\x9f\x96\x1a\xec\x4e\xb4\x1b\x90\xfa\xb9\xae\x94\x59\x3e\x82\x76\x21\x2c\x36\x6e\xf4\x67\x6d\x8a\x94\x86\x80\x40\x7b\x2d\x3e\x19\x96\xc6\xfe\xe6\x1b\x4c\x88\x52\xa4\x75\x53\x56\xff\x1e\x62\xf3\x53\x96\x44\x58\xda\x73\xb6\xca\x09\x96\x18\xc4\x46\x09\xba\xe8\x6a\xca\xa4\xa5\x29\x3f\x65\x45\x1f\x47\x2f\xab\xa9\x04\x0b\x4d\x83\x88\x63\x0d\xfa\xfd\x07\x62\xde\x44\x8f\x2a\x4e\x83\x98\x22\x91\xb0\x71\x6a\x07\xad\x61\x99\x15\xbd\xf6\x20\x4d\x83\x84\x53\xb7\xe2\xc9\x87\x8f\xef\x4c\xde\x30\x50\x5a\x7a\x8f\xe1\x20\x3c\xef\x35\x4d\x43\x13\xe0\x6a\x6b\x5d\xf0\x7a\x58\xc0\x45\xd3\x88\x13\xdc\xbb\x31\xa1\xf0\x5c\x5e\x72\x68\x1a\xf0\xc8\xe7\xae\x53\x12\x46\x43\xdd\xc3\x45\xde\x28\xcf\x95\x3f\x1d\xe5\x28\x11\x91\x63\x04\x6f\xff\xba\x83\x2b\xdd\x2a\x9a\x72\x01\x88\x25\x7d\xcd\xfa\xf0\xda\x28\xe5\xcf\x88\xef\x69\x40\xf4\xdb\x97\x95\xe6\xc0\xb4\x8c\x57\x90\x70\xff\x7a\xd6\x32\x3a\x63\xc1\xa4\x31\xb1\x8a\x64\xe8\x81\x7e\x2f\xd1\xad\x1f\x3b\x1a\x69\x4c\x14\xa2\xd6\xce\xe2\xf3\x50\x8d\xa0\x5b\x69\x1c\x0a\xf4\x52\xd0\x96\x7d\x82\xe6\xbd\xac\xde\x1c\xf7\x81\xef\x91\x00\x02\x73\x1d\x2e\x6a\x37\x10\x4d\xf7\x3d\x24\xc3\x51\xbe\x2f\x73\xfd\xef\x4b\xd1\xa1\x8c\xd3\x84\x5a\x09\x19\x74\xf0\x5f\x0a\x65\xa9\x78\x6f\x32\x3d\xd2\x3c\xa7\x69\xc2\x19\xd6\xb2\x9e\x70\x04\xfe\x00\x29\x64\x37\x77\x12\x88\x13\xe2\x89\xe1\xf2\x5c\x54\x13\xcd\x7c\xd4\xd2\xf1\x03\x9a\x26\x56\x15\x05\x6b\xdb\x4f\xe7\x06\x0e\xf1\xc8\xb3\x4c\x53\x1d\x29\x3d\x48\x24\x0e\xd1\x29\xae\x8b\xe0\x80\x9e\xc4\xe3\x7a\xf9\xbc\x39\xdc\x6e\x1e\x1e\x16\xcf\xbb\xd6\x09\x3a\xdc\x3c\xed\xff\x3c\x6c\x9f\x57\xbb\xc5\x83\x37\xcb\x52\xc1\x8d\xe7\xca\xbd\x6b\x8d\x0a\xa8\x5c\xb0\x76\x3c\x44\x52\xc5\x98\xfe\x50\x0e\xb9\xd1\x76\x5d\x77\x22\xd4\xdd\x54\x54\xb1\xd0\x2e\xfc\xfa\x6e\x65\xb1\xdc\xb3\x51\xd2\x75\x11\x42\xd8\xda\x57\x1c\x4e\x94\x19\xed\x2a\x5c\x27\xaf\xa2\x09\x58\x46\x25\x9f\xf3\xd4\xa7\xac\x68\xfb\xb1\x69\x47\x11\xe2\x44\x7c\x86\xfa\x72\x1a\x20\xb4\x07\x73\x48\x0b\x09\x72\x30\x72\x93\xb4\xe5\x64\x8f\xd3\x8a\xdb\x60\x1c\xa8\xd7\x22\x53\x22\xf7\x4c\x9b\xbe\xdd\xc4\xa8\x7a\xf4\xaf\xfd\xb7\xfd\x1f\x4f\xfe\xaf\x26\x22\x51\x7f\x96\x6d\xcb\x37\xb7\x26\xe6\x77\x3c\x13\x33\x95\x7a\x9c\xad\xaf\xc4\x08\xba\x7b\x69\xab\x30\x26\x94\x25\x73\xe9\x06\x59\xd0\x54\x32\x9b\x03\xfd\x09\x95\xce\x00\xa5\xb6\xbc\x1f\x27\x98\xd0\x81\x70\xc4\xea\xbb\x5c\xd4\xaf\x83\x26\x15\xe3\x85\x37\x19\x6e\x10\xb7\x48\x03\xd3\xa3\x22\x44\xc0\xac\xe7\xf2\x5d\x20\xb9\x77\xc7\x07\xfd\xcb\x8c\x84\x08\x82\x18\x03\x6d\xb7\x55\x99\xe9\xd5\x7a\xeb\x25\x3e\x47\x03\x2a\x82\x00\x10\x34\x7b\x14\xf5\x33\xfc\xa7\xfb\xc5\x24\xc5\xf8\xe3\xf6\x79\x75\x40\xa6\x99\xe0\xc7\x6a\xf5\x87\x95\xdd\xeb\xfa\x18\xcb\x5c\x27\xb4\xfe\x6e\xb5\x22\xca\x6a\x26\x97\x2a\xc2\x14\xb0\x40\xf7\x61\x00\xb8\x15\xa1\x88\x10\xcf\x03\x96\xa4\xd7\x06\x5a\x70\xa0\x7b\xe9\x56\x2a\x42\xc5\x95\xad\x2f\x87\xc2\x7e\xb1\xf1\xa7\x12\xa1\xd2\x18\xe5\xfd\x76\xbb\x1c\xda\xaa\x22\x22\x3e\xfc\xdf\x5c\xaa\x62\x20\xb0\x37\xbe\x3c\x52\x54\xb9\x98\x55\xbb\x3d\xb2\xee\x72\x6d\xd1\x2d\x28\x49\x83\x2a\x92\x97\xab\x3a\x59\xd7\x95\x07\x09\xfa\x79\xad\xf9\x09\xd5\x29\x1b\x56\x76\xce\x7f\x17\xee\x72\xcb\xe7\x4e\x58\xb4\xfd\x98\xa3\xf3\x45\x70\x65\xcb\xd9\x4f\x70\x14\xb2\xac\xeb\xb9\x5a\x0b\x11\x27\x06\xa3\x0b\x15\x98\xee\x4f\x9a\xe3\x44\x5f\xfd\xe3\x65\xbd\x7d\x5c\x3d\xed\x0f\xcf\xab\x1f\x8b\xe7\x5b\xcf\xda\xf3\xf4\xf2\xd8\x7d\xbf\x84\x84\xc6\x62\xeb\x5f\x61\x5c\x13\x23\x92\x20\x0e\x7a\x74\xfc\xb1\x2c\xf0\x78\x7f\x9a\x78\xd4\x22\x11\x16\x5b\x56\x43\xb3\x2d\xab\x91\x76\x3c\x15\x29\xd5\x18\x4e\xd8\x56\xaa\x68\x06\x18\x1f\x91\x2a\x13\x84\x5d\x11\xa2\x9e\xc7\x57\x09\x41\x63\xd2\x51\xd3\xb8\x31\x6a\xbb\xf7\x67\xbb\x10\x0a\x3c\xf5\xad\x35\x22\xcb\x6a\xb7\x9d\x3c\xa2\xa4\x81\xb0\x24\x7b\x1f\x53\xae\x5d\x2a\x64\x40\xf0\x8c\xf2\xdb\x58\xb7\xdd\x6d\xcc\xae\x29\x2b\x31\xb5\x14\x84\x8c\x38\xb5\x5b\xf8\xd3\xe1\x66\x7d\x7b\xb8\x7b\x5e\x2c\x0f\x37\x9b\xbd\x7f\x22\x19\x1b\xf4\xb5\xed\x79\x73\xce\x85\x82\x83\xe5\xfc\x52\xd3\xba\x14\x21\x53\x8a\xe6\xb1\xc9\x3e\xac\x06\xc8\x7d\x25\xce\xaf\x99\x9a\x05\xc1\x08\x69\x22\xa4\xb6\x34\x00\xb5\xc7\x41\x09\x45\x28\xce\x3d\x47\x45\x3f\x8f\x2f\x9b\xf7\x4c\x84\x8a\x84\x65\x63\xcd\x9a\x4f\x57\x7b\x37\x53\x0c\x2d\x14\xb7\xfa\xa1\xba\x3d\x15\x2a\x78\x5e\x7e\x1f\x9d\x7b\x42\x25\x56\x80\x09\xb5\xcf\x1b\x40\x7e\xe9\xf1\x2d\x24\x75\x30\x1d\x64\xbc\x1e\x72\xa6\xf9\xf6\x20\x40\xc6\x10\x94\x2e\x6d\xc4\x38\x2a\x25\x29\x44\x26\x71\xc6\xd9\x95\xcf\x29\x59\x62\x57\x1f\x14\x7a\x87\xe0\xa9\x61\x3d\x93\x0c\xb8\x20\x0e\x6b\xe9\x1f\x6b\x9a\xed\x96\x61\x10\xc7\x71\xcf\xcd\x37\x74\xf0\x65\x98\x10\x92\x78\x30\xa0\xd3\x65\x1f\x2a\xed\x8f\x9f\x25\x94\x01\x96\x08\xf8\x14\x4a\xbd\xec\xef\x14\x45\x2a\x1c\x90\xcd\x29\xd1\xb7\x48\xcb\x0d\x81\xd9\xd6\x31\x14\x42\xf2\xc4\x2e\xa1\xdb\xcf\x63\x56\x94\x23\xdd\x39\x2a\xb9\xb0\x8c\x8f\x79\xa9\xde\xee\xfb\xe5\x25\xb9\x0a\x30\x38\xd0\xce\x60\x0f\x2e\x18\xb3\x59\x51\xdf\xd3\xe9\x72\xb7\xfe\xc1\xdd\x65\x4a\xfc\xed\x1d\x41\x99\x90\xd4\x73\xba\xf5\x00\xef\xd9\x45\x2b\x5b\xbb\x0c\x25\xae\xb2\x8f\x6e\xa2\xcb\x44\x52\xfc\xe3\x01\x3d\xf4\x5b\x90\xcd\xf3\x48\x98\x67\xfa\x45\x12\x9d\xc6\x41\xb7\x77\x23\x94\xed\x1a\xc2\xf4\x3f\x89\x33\x53\x65\xca\x08\xda\x0f\x2e\x71\xbc\x17\xc5\xdb\xd0\x45\x74\x61\x46\x29\x94\xf1\x65\x7e\xb7\x60\xc4\x25\x6f\x7a\x9c\x9e\x94\x71\x8a\xfb\x7d\x7e\x51\x6f\x9f\xb7\xe5\x71\x00\x78\x92\x32\xe1\x42\x8e\x89\xd5\xfe\x1e\x26\x4e\xaa\x24\x34\x56\xec\x18\xd3\x77\x65\x3d\x65\x51\xed\xfd\xbd\xe9\x95\xa9\x40\x8c\xa4\xbc\x7c\x4e\x16\xf5\x78\xbc\x95\x8a\x90\x7b\x02\xcf\xa9\x9b\xa1\x82\x20\xd2\x09\x5f\xfd\xcc\xb5\x83\x29\xb5\xb4\xb9\x9e\x93\xf8\x70\xbb\xec\x08\x04\x23\x35\x68\x6a\x43\x0e\xe7\xac\x11\xf9\x56\x35\x37\xd9\xb9\x5b\x61\xc0\x18\x26\x4e\xbd\x48\x76\xbb\xe3\x8d\xb4\x0d\xfe\xe2\xdf\xee\x36\x1c\x6c\x90\xbd\x23\xb4\xf2\x66\xe2\x15\xc5\x28\x95\x20\x45\xea\x01\xf1\xfb\x0f\x5f\xba\xd5\x3d\x12\x68\x64\xd7\xc2\xbf\x5b\x18\xc6\x70\xdd\x28\x42\x13\x64\x84\x53\x98\x32\xcd\x2d\xf8\xcc\xb7\x31\x5b\xa1\xee\xb3\x3f\x98\xf8\xbb\x0c\x59\x2d\x14\x09\x6c\x6e\xd1\x9d\x5e\x59\x71\x1c\xf3\x5c\x53\x45\x64\x80\x6b\x1d\xcd\xe8\xf9\x0f\xa7\x08\xa4\x98\xe8\x40\x92\x9d\x4b\x61\x59\x78\xc7\x8b\x49\xd1\x58\x20\x52\xfc\x52\xd8\x1d\x05\x1e\xb3\xbc\xdd\x83\x7a\xc8\xae\x62\x21\xc1\xc4\xec\xfd\xed\xf2\xaf\x71\x47\x8a\x71\x8a\x00\x78\x9d\xd5\xcd\x17\x7c\x6b\xae\x67\xa8\xb9\xd3\xf4\xcc\x30\xc3\x7f\x23\x6a\xe4\x43\xf4\xbf\x1b\x19\x89\xcc\x9a\xce\x56\x3f\xe8\xf2\x22\x73\x38\xd4\x97\xd3\xe1\x2c\x32\x7d\x30\x55\x79\x3a\x34\xaf\x70\x90\x63\x15\x33\x77\x39\x27\x02\x43\xfb\x3a\xfb\xf9\x5b\x8f\x28\x49\xba\x56\x15\xf7\x30\xa5\xc7\x52\xe2\x56\xf1\x17\x60\x9c\xd1\x8b\xf2\xa0\xc3\x4d\x5a\xdd\xfd\xe1\xae\xae\xb8\x4c\x91\xa3\xeb\x06\x05\x62\x96\xd5\xe7\xb9\x29\xd5\x48\x30\x87\x2a\xae\x63\x2c\xcc\xbc\xc9\x1a\x29\xe4\x68\xe3\x55\x49\xcc\x99\xbb\xfb\x4b\x61\x21\x19\x57\xb6\x99\x4a\x62\xab\x67\x67\xa9\xfe\xb1\x7c\x7f\x08\x1c\x53\x49\xc2\xc0\xb3\x6a\xdd\x43\xb3\x14\x35\x2c\x86\xa4\x63\x6d\x8f\x00\xdd\x63\x51\xd8\x3d\x60\xa0\x69\x38\xff\xd1\x52\xc1\x91\x77\x2e\x2f\x95\xc8\x91\xae\x66\x3a\x27\xa6\x31\xcb\xf1\x9f\xdd\x6d\x24\x8d\x9c\x55\x69\x37\xe9\x45\x85\xbe\xfb\x55\x8c\x6b\x3e\x92\x7b\x15\x26\x1d\x09\x2d\xb7\x77\x4f\xd0\x4f\xb6\xe4\x78\xdf\x61\x48\x33\x3a\xfa\xa8\xee\xa0\xee\xff\x19\xde\x04\x6c\x69\x3f\x4a\xb2\x39\x7d\xcb\x45\xe3\xaa\x88\xeb\x9b\xcf\x67\x84\xe9\xb6\xee\xc8\xfc\xc3\x8d\x26\x8b\x16\x96\xc2\xcf\xc2\x72\x5a\x1b\x68\x52\x5e\xaa\xb4\x24\x81\xab\xcd\x3b\xef\x5e\x33\xf0\x4a\x65\x54\x69\x48\x10\x21\x68\xb2\xe3\x2b\xa2\x87\xd1\x8e\xba\x92\x11\xa7\x0a\xa8\x8d\x95\x65\xc5\xbf\x41\xfd\xb2\x10\x40\x81\x01\xd5\x3d\xcf\xcd\xe5\x73\x60\x3a\x2b\x13\xd8\xb8\x87\xc7\x3c\x8c\x35\x52\xa9\x32\x11\x0d\x98\x9f\x75\xc5\xc5\xe9\x2b\xcd\x50\x7b\x28\x93\x5a\x0c\xcd\xe5\xac\x71\xeb\xb9\xc6\x75\x69\x1a\x26\x78\xf0\xbd\x43\x76\x57\x56\xff\x14\x97\xdf\x7c\x83\x70\x80\xb9\x76\x8e\x59\x3c\xd0\x84\x06\x9e\x6a\x2a\x63\xd4\x91\xdf\xff\xee\x9d\x2a\xcd\x78\x8a\xf6\x91\x11\x75\x3b\xdf\x5f\x91\x19\xd1\xb7\x69\x81\x70\xdf\x4b\x71\x87\x04\x07\x33\x9e\xaa\x0e\x22\x66\x39\xac\xd1\x12\xfa\x26\xaa\xd6\x22\xbb\xeb\x34\x29\xa8\x0e\x78\x84\x91\x4a\x03\x33\x65\x63\x7d\x1f\xb4\x67\xbd\xb2\x94\x13\x8a\x9f\x55\x5f\xf0\x97\xc4\x5c\x41\x3f\x41\x8c\x35\x93\x47\x8b\x46\x07\x9a\x81\xe5\xaf\xb1\xe4\x1e\x59\xd9\x29\xb0\xfa\xa7\x0b\xa9\xe5\xa9\x5a\x3f\x97\xb2\xec\xfe\x18\x49\x50\xbe\x18\x02\x31\x0f\x43\x82\xea\xf1\xa3\x87\x92\x60\x85\x61\x71\x39\xb5\xbb\x5a\xbd\xcf\xf2\xdc\xa5\x24\x6d\x5c\x76\xdc\x3d\x22\x2c\x0e\x46\x6c\xb6\x7e\x77\xd3\x51\x60\x10\xac\xef\x03\x93\x0f\xa5\x7a\xbb\x9c\x47\xb8\x2c\x1d\x29\x82\x89\x3f\xe3\x44\x2f\x16\xc7\x3e\xca\xa2\x23\x25\x71\x0b\xfd\x09\x15\xd2\xa8\x61\xb4\x6b\x3c\x22\x3c\xb2\x5a\x98\x12\x79\x99\xfd\xe3\x4d\x57\xb5\xef\x1c\x6b\x21\x7c\x2a\xac\x10\xb9\x1d\xbb\x71\x28\x57\x73\xa5\xa5\x55\xa6\x7b\x77\xb3\x7e\xfc\xc2\x71\x90\x22\x03\x94\x7d\x0f\xcb\x76\xf0\xc5\x50\xc6\x52\x1b\xd3\x57\x52\x5f\x8a\xe6\xb6\x0f\xed\xeb\x84\x10\x07\xe8\x69\xfd\x32\xaf\x95\x3e\x01\xdf\xea\x84\x50\x4a\x3d\xf0\xa1\x9a\xb8\xc6\x3a\x11\x3a\x54\xe3\xf2\xa0\x61\x85\x83\xeb\x95\xea\x08\x9d\xb0\xf6\x14\x78\xc6\x28\xa8\xa3\x01\x70\xed\x82\x5a\xed\xbb\xec\x74\xce\x0f\x36\x8f\x1a\x2e\xb3\xca\x71\xfb\xcf\xbf\x9b\x48\x43\xf0\x45\x03\xab\x9d\xea\xc1\x82\x5a\x08\xf0\xa4\x30\xff\xb8\xe0\x22\x6a\xcf\x75\xcb\x99\x31\x79\x30\x61\x08\x7a\x5d\xbd\x20\x75\x07\xc8\xfc\x0a\xd6\x33\x6b\x03\x6b\x49\x6c\xf0\xfe\xbd\xcc\x4d\x38\x76\x6f\xb4\x24\x49\xec\x29\x45\xda\x03\x72\x99\x35\xd9\x7f\xa1\x18\x5a\x7c\x57\x77\x33\xc4\xe1\x23\xd7\xa7\x53\x59\x35\x22\xaf\x37\xc5\xfe\x15\x6e\x44\xd3\xe4\x60\x70\x6f\x1e\xaf\x5e\xc9\xec\xce\x82\x24\x78\xf6\x24\xbb\x0c\x70\xa7\x5a\x91\x10\xcd\xc5\xef\x99\xac\x44\xd1\x89\x49\x50\xad\x22\xca\x6c\x08\x09\xfd\xf8\xdd\x6e\xeb\x19\xb7\x27\xbf\xa0\xe2\x10\xe9\x05\x85\xd6\x88\x9b\x78\xb0\xbe\xcd\xfc\x66\xa2\xa4\x44\xa2\xab\x6f\xd9\xf1\xf5\x77\x4b\xa9\x6e\x51\x0b\xfe\x67\x81\x4b\xe2\x62\x2a\x7f\x34\x6a\x2a\xa6\xdd\xef\xe0\xda\x10\x2d\xbc\x91\x33\x30\x4f\xb4\x61\x20\x5c\x46\xee\x09\xde\x7d\x11\xdb\xe4\x99\x4d\x22\x11\x8b\x86\x2e\x59\x83\xe7\x84\xb6\x14\x7d\xb3\x03\x0f\x84\xda\x42\xec\xbc\x3c\x22\x9d\xf7\x2f\x3f\x3a\x10\xc3\x98\x15\xc8\xc7\x50\xb3\xad\x66\xf7\x3b\x0b\xb0\x34\xf0\x25\x30\x37\xa2\xce\x94\x55\x32\xbe\xd6\xa2\xa4\x10\x24\x90\x74\xc4\xc5\xd6\xa2\xf1\x2d\x4a\x63\x60\xbf\x3d\x0b\x6e\x27\x93\x17\xa2\x20\x09\xdc\x07\x99\x08\x19\xfe\xdf\x69\x47\x8d\xbe\xff\xe1\x2f\xfc\x2c\x88\x34\x41\x5c\x8d\x8b\xd1\x1f\x76\xfb\xc5\xf3\xfe\xf0\x63\xb5\xfa\xc3\x9f\x6e\x10\x01\xc3\x44\x62\xfd\x2a\x2a\x98\xc8\xed\x51\xe0\xa9\x44\x9f\x40\x8b\x46\x3c\x42\xf5\x96\x77\x98\x93\x2f\x14\x1d\x28\x70\x19\x61\x3a\x7d\x24\xb5\xfe\x45\x40\x1e\x62\x9e\x60\x65\xe6\xbd\x38\xc9\xdc\xcf\x25\x48\x38\x97\xe0\x37\x21\xcc\x6f\x62\x85\x74\x56\x16\xcb\x4e\x4a\x86\x42\xd2\xfe\x9f\xcf\x6d\xe4\x65\x95\xcc\x55\x66\x43\xca\x34\x46\x2d\x3b\x6c\xdb\xa7\x3d\x07\xe7\x47\x36\xe5\xd2\xdf\x13\x13\xcf\x56\xaf\x00\x11\x14\x97\x6b\xa6\x7f\x0a\xa9\x64\x38\xbf\x56\x16\x73\x7e\x15\xcb\x9a\xff\x15\xc1\x64\xe2\xb0\x59\xe2\x73\x63\xd6\xcb\xcd\xca\x4b\xdd\x53\x50\x84\xa2\x35\xf0\x6d\xf1\xf2\xaf\xee\x6f\x51\x8a\x13\xea\x77\x78\xfb\xcc\xf3\xc3\xba\xce\x45\xa1\x0f\xeb\x42\xf9\x0e\x9a\x18\x1e\x76\x7c\xaa\xab\xd3\x39\x2f\x3f\xa7\x01\x2d\xd0\x21\xc7\x44\x8e\x4d\x1b\x75\xf3\x5a\x87\x31\x92\xa1\x8a\xa2\xb5\xbc\xb6\x65\xdf\x20\x81\x75\x56\x5b\xbd\x28\xb4\x27\xaf\xcb\xa0\xde\x98\xdb\xa1\x4c\xcb\xe4\xdf\x09\x51\x26\x05\xa0\x84\xf5\x7c\xaf\xab\x8f\x06\x8a\x7a\xc0\xc8\xe6\x7b\xf1\x30\x72\x3e\xea\xa1\xf5\xe8\x0f\xa2\x92\x59\x53\x5b\x9e\xc6\xc9\xcb\x80\x4c\x6d\xb9\x75\x79\xdc\x89\x1c\x96\xe2\xfc\x0c\x42\xbd\xc2\x17\x5b\x30\x18\x4a\x0c\xe9\xe8\xa0\x77\x90\xfb\xd8\x33\x98\x24\x40\xc7\xe1\x56\x34\xc2\x16\x0d\x2d\x8a\x12\x5d\xac\xaf\xd8\xa0\x07\x90\x31\x30\x26\x36\x33\x55\x55\xe3\x37\x33\x24\x60\x58\x28\x7c\x93\x35\xb7\x8b\xcd\x70\xdf\x33\x44\xc4\xe8\x96\x15\xa5\x86\x43\xd5\x1a\xe4\x07\xf5\x9a\xe5\x13\x2b\xc1\x10\x19\x20\x96\xe0\x52\x48\x2b\xbb\x9a\xc1\x14\x54\x6d\x28\xb5\x12\xa6\x0e\xfd\xf1\xb9\xdc\x6c\xbe\xf0\x3f\xfd\x05\x82\xa2\x69\x26\xf1\x18\xb2\x27\xf9\xe4\x77\xa9\xb4\x34\xff\x36\x05\x35\x2c\xfd\x9a\xdc\x8b\x31\xa6\x5d\x5e\xfc\x07\x64\xa3\x60\xa8\x61\x22\x45\x37\xe2\x30\xf0\x3d\x47\x82\x73\xbd\x07\x6a\x98\x12\xc8\xad\x76\x29\xbe\xce\x49\x1a\x06\x1a\x0f\xb9\x5e\x32\xac\xaf\xcd\x59\x15\x7a\x80\x1f\x34\x41\xc4\x11\xed\xb4\x5c\xec\x0f\x77\xeb\xe7\xdd\xbe\x6b\x48\x14\x46\x90\xe4\xa5\xd0\x79\x56\x1c\x47\x9a\x19\xd4\x04\x26\xc0\x5c\x82\x0f\x8b\x2e\xa1\xa8\x4b\xdc\xc3\xfa\x00\x9c\x09\x8c\x09\x1d\x4d\x15\x72\x28\x3e\x97\x79\xee\xd7\x8f\x09\x49\x82\xdb\x58\xf3\xd6\xfd\x25\xa5\xd4\xed\xf0\x77\xd9\x4f\x34\x6e\x1d\x00\xeb\x4b\xa9\xa9\xf9\xc8\x93\x09\x35\xf3\x15\xea\xad\x1f\xe4\x39\x51\xc7\x9f\x84\x53\x82\xb3\x0e\x0a\x8d\x7a\x5b\xa3\x84\xa0\xe1\x32\x42\x7e\xe3\x6b\x66\x94\xc9\x97\x8d\x99\xc6\xa9\xf7\xe7\x66\x9c\xad\x32\xb1\x50\x68\xd6\xa8\x52\xc3\xea\xe3\x5c\xb6\x36\x69\xb7\x3f\x9b\x44\xc4\xcc\x97\xf7\x38\x73\x60\x64\x89\x9a\x44\x0b\x34\x8c\xf7\xdf\x9e\x57\xbb\x6f\x9b\x87\x5b\x0f\x87\x33\xa9\x48\x50\x14\xe2\x09\xde\xbf\x89\xfa\xb5\x5d\x1a\x7b\x8c\x40\x77\x21\x2f\x93\x2a\x01\xa6\x23\x0a\xb2\x60\xf9\x2f\xf2\x57\xbf\xc4\x1d\x5e\x33\x3a\x8d\x07\x5a\x50\xab\x59\x7e\x23\xf2\xbc\x9c\x30\xf6\x7d\x11\x3c\xf8\x15\xbe\xd2\x08\x13\x92\x60\x28\x22\xf3\x50\x1e\x87\x61\x1e\x23\x83\x14\xeb\xfd\x3b\x28\xfc\xcf\xb9\xb8\xe4\xd7\x4c\x0d\x46\xa6\x3d\x7d\x87\x3e\x65\xc5\x43\x39\x01\x40\x1a\xc5\x6c\x51\xd2\x53\x79\x19\x41\xe5\x8c\x16\x89\x43\x06\x7e\xce\x46\x43\xe7\x12\x83\x8c\x90\x94\xe2\x5c\x14\x5a\x3b\x89\xa4\x39\x76\x88\xb6\x9f\xc5\x64\x22\xd3\x8b\xcd\xef\xfd\xe6\x9b\x94\x63\xd0\x47\x07\x6a\xfb\x7d\x35\x7a\x62\x46\x68\x6c\xab\xf1\x6e\x77\xae\xf4\x72\x52\xb6\xcf\x08\xd3\x0a\x0f\xb7\xbb\xc5\x72\xbf\x79\x3e\xc4\xfe\xce\x41\x6a\xb0\x5c\x32\xab\x5d\xad\xf5\xac\xfe\x3b\x23\x81\x90\x58\xdb\xbb\xb8\x59\xcf\xc2\x6a\x19\x09\xc1\xf8\xb2\xed\x47\x98\x29\x44\x67\x24\x0a\x0d\xd2\xf9\x5d\xce\xda\xe7\x5d\xfc\xa6\x72\x65\x08\x33\x12\xc5\x52\xc5\x1d\x2e\xf1\x19\x7e\xa2\x3c\xe7\x80\xd1\xcb\xad\x17\x87\x8e\x61\x84\x43\x82\x28\xbb\x4b\xa1\xb3\x5a\x8c\x4b\x8d\x5c\x97\x38\x66\xc2\x43\x00\x5e\xce\xff\x1a\xf8\x77\xb3\x93\x85\x91\x58\xa4\x68\x73\x62\x4c\x71\x5d\xbc\xec\xba\x4f\x92\x50\x45\x2d\x18\xca\x4a\x59\xbb\x29\xe1\x5b\x99\x8a\x9d\xfa\xcd\x6d\x59\xe0\x79\x8a\xd5\x6a\x23\x2c\x8a\xef\x0b\x40\x9d\xfa\xd0\x44\xea\x98\x91\x14\x52\x27\x53\x59\xe8\xaf\x4a\x7d\x19\x11\x04\x10\x50\xf3\x50\x1e\x8f\xa0\x91\x5f\xef\x57\x71\xe3\x49\xf4\x8e\x11\xc1\x98\x0d\xac\xb6\x9b\x2e\x54\x1e\xcc\x3e\x03\xcd\x66\x44\x86\x02\xe3\x0f\xfb\xe5\x76\xe9\x9f\x52\x51\x8e\x68\x15\xc4\xa7\x67\xc5\x71\x77\xee\x54\x88\x18\x51\x71\x1c\x88\x21\xcb\xc5\x1b\x60\x68\x06\x54\x76\xbe\x3a\xa4\x19\xd1\x91\x46\xe3\xef\xcf\xac\xec\xf7\x33\x46\x74\x6c\x45\xa9\x9e\xba\x7c\xd9\x78\x08\x74\x12\x23\x51\x06\x42\x19\x0e\xb7\x8b\x3f\x83\xc3\xed\xcb\xf3\x40\x60\x98\x11\x9d\xa6\x98\xd4\x78\x14\x59\xfe\xed\x52\x37\x39\x4c\x24\xb8\x19\x81\x30\x44\xff\xa3\xf5\x1c\x7e\x09\xc3\x60\xa4\x75\x1e\xda\x31\xff\x4f\xfd\xaa\x67\x45\xdc\xdd\x96\xc6\x08\xf0\x14\x29\x29\x16\x0f\x0f\x9b\xe5\x61\x71\xfb\x7d\xbd\xdb\x3c\xef\xba\x9f\x94\x29\xee\xf2\xd5\xa5\x98\xc1\xdc\x33\x02\x8e\xc3\xc6\x17\xc9\x1e\xf4\x95\x30\x2f\xaa\x40\x58\x1a\xce\xb2\xb8\x9c\xb6\xd5\x08\x74\xf5\x25\x4a\x71\x3c\x80\x86\x32\x62\xf3\x8e\xef\x50\x37\x8b\xfa\x6d\x54\x57\xdd\xb6\x0b\x0c\x85\x59\xe3\xc9\xe2\xc6\xbe\x88\xc3\xce\x9d\x14\x8c\x98\x88\x21\xdb\xe0\xfb\x6b\xb9\xae\xf7\xaf\x43\x0e\x61\x46\x4c\xaa\x8d\x8b\x00\xdc\xf9\xa0\xab\x43\xfa\x8f\x85\x2b\x18\x31\x1a\x7c\xde\x72\x07\x79\xde\xd3\x1a\xd1\xc9\xe2\xa5\x84\x5b\x30\xee\xef\x2f\x0f\xeb\xc5\xd3\x01\xc7\x7f\x38\x23\x28\x49\x6c\x31\x21\xf2\xa6\x0f\x52\xcc\x8c\x12\x1d\x79\x79\xce\x67\x31\xd1\x51\x67\x94\x00\xf1\x88\xcc\x76\xe1\xfb\x3f\x53\x46\xad\x04\xe2\xf3\x63\x03\xfe\xa0\x47\x72\x4d\x2b\x82\x80\xc2\x21\x83\xc4\x14\xa3\x54\x05\xe8\x5b\x40\x25\x5c\xb9\xcf\x9c\x7d\xcc\x28\x63\x0a\xfb\xa1\x6d\x6b\x41\x11\x5f\x02\x46\x19\x65\x5a\x2a\x77\x86\x1e\x3a\x45\x23\xff\x93\x01\x8b\xd2\xc4\x86\x1b\x5d\xe0\xa4\x7b\xad\x20\x0a\x94\x18\xc4\x06\x6f\x3e\x47\x0f\x1b\xc4\x29\x86\xe7\x9d\x36\x62\x6d\x4d\x9a\x6e\xa1\xd3\x40\xc5\xba\xa3\x95\x76\x93\xb0\x8f\x72\x33\x1a\x1a\x1e\x59\x3a\xd9\x1f\x90\xfd\xd2\x05\x44\xc6\x04\x9b\xed\xbb\x54\xc5\xe5\xfc\xad\xcc\x35\xc2\x14\xaf\xa5\xa0\x7d\x7f\x2e\x65\x3b\x7b\x7f\x40\x6b\xe9\xfc\xad\x82\x7d\x46\xa3\x54\xe3\xd9\xe7\xf0\xf6\x36\x47\x30\x79\x0e\xa3\x12\xb7\x8f\x6f\x9e\x56\xfb\xf5\xe3\x6a\xb7\x79\xf0\x67\x00\xe5\x91\xe5\x2f\xf6\xf1\x4d\x4f\xed\x78\x5f\xe6\xfa\x0f\xf8\x9c\xd3\x49\x61\x94\xa7\x02\xbf\xa5\x0d\x36\xf8\xd0\x03\xde\x7a\xbf\x78\xdc\xfa\x7b\xc7\xa1\x2d\xca\xb3\x22\xb0\x37\xfb\xee\xef\xd2\xc4\x89\x0f\x2d\x7b\x72\x50\x0b\x08\xbe\x36\x92\x87\x06\x25\xa3\xa9\x48\x91\xe8\xf1\xf6\xc7\xcd\xde\x92\x11\xff\xdd\xa8\xdf\xe4\xeb\x08\xce\x75\xda\x03\x81\x3b\x83\x9f\x51\x21\x13\x60\x03\xde\xc7\x01\xed\xee\x20\xe5\x33\x7a\x2a\x49\x15\x2e\x8f\xc3\xd3\xe5\xb4\x31\xbb\xe6\xa2\xa1\x68\xea\xad\xe8\x97\x9b\x0c\x08\x96\xce\xcb\xa6\x47\xc7\xcf\x4f\x1b\x19\x81\x62\x03\x7a\x3f\x98\x32\x2a\xb5\x5d\xcc\xa0\x16\x5b\xd7\x03\xe3\x92\x51\xe9\xe8\x1a\xed\x59\x85\x41\xb6\x3c\x87\xca\xaa\x63\x4d\x83\x76\x73\x46\x1c\xd5\xa1\x0d\x41\x3b\xfa\xe8\xd9\x0c\xd5\x35\x3d\x00\xc6\xa2\xd0\x32\xb9\xef\x03\xcb\xad\xfd\x0b\x56\x08\xd8\x22\xd0\x1a\xd0\x37\x9f\x7b\x28\x44\xff\xc0\x90\x06\x31\x71\x1a\xaa\x95\x06\xac\xd3\xb3\x89\xfe\xbb\x72\xc0\x6b\xd1\xbf\x3e\xe8\x40\x59\xb9\xfc\xa7\xdd\x7e\xf5\xf0\x30\xda\x0f\x41\xc7\x61\xe2\x83\x5d\xcb\x4f\xd5\x1d\x8c\x14\x4c\x1a\x6a\x5b\xb6\x54\x75\xa9\x90\xf1\xad\x19\x25\x54\xd3\x5e\x60\xfd\x51\x9c\xcf\xad\x2d\x90\xfd\xd7\xdf\x85\x51\x4e\x94\x2d\x0a\xf7\xf2\x0b\x2b\x64\x03\xc1\x12\xc6\x69\x02\xf2\x3a\x9a\xc0\xd0\xfc\x07\x5b\x8b\x62\x77\xd3\x1b\x8f\xad\x63\x2c\x20\x46\x85\x5e\x30\xff\x2e\xab\x5f\x17\x48\x85\xdc\x35\xa7\x90\x20\x16\xa4\x14\x05\x5e\x3b\xd0\x4a\x60\x2c\x10\x91\x16\x8e\x57\xa0\xfa\x09\x1d\xcf\x1e\x63\x21\x09\x43\x57\x6c\xa0\x7e\x60\xca\xcc\xda\xb6\x33\xbc\x30\x8c\x85\xcc\x46\x21\x30\x85\x86\x27\xd3\x7c\xb7\x48\x62\x38\xea\x71\xf1\xcf\xe5\x62\xeb\x41\x7c\x1d\xf5\x13\x63\x21\x67\xc4\xd2\x31\xe7\xd0\xc0\x2a\xc7\x10\x5b\xeb\xf1\x8c\x82\xb9\xae\x73\x44\xac\x57\x82\x6c\xf9\x0e\x33\xf6\x6b\xe3\x85\x45\x69\x88\x67\xb1\xc9\x0a\xfd\x58\xea\x4b\x8e\x3c\x4d\xf3\xfc\x12\x8c\xf1\x28\x4c\x2d\x73\xc8\x07\xe8\x87\xf2\xc8\x26\x0f\x90\x84\x09\x1a\xbb\x4e\x44\x6e\x7c\x71\x12\xa7\xd4\xf1\xdf\x0f\xb1\x90\x8c\xa5\x3a\xc0\xc9\x26\x9a\x46\xa8\xb7\xc7\xb2\xa8\xaf\xf6\x4a\x26\xa2\x00\xb1\xae\x37\x9b\x1f\x7b\x6b\xd6\xfa\x86\x34\x42\x6b\xe4\x41\xd4\xcd\x63\x7d\xec\xfe\x6c\x9c\xb9\x8c\x0b\x6c\x5f\xbe\x64\x85\xe7\xd4\x1e\x6d\xfd\x4c\x12\x8d\x55\x2a\x27\x51\xd7\x96\x1d\x61\x52\x9f\xc0\x98\x4c\x52\x34\x8a\xc7\x2c\x6f\xb3\xbe\x0f\x53\xd4\x96\xcc\x9d\xc4\x87\x15\x7b\xec\x60\xaf\xfe\xc9\x94\x01\x04\xb7\x9c\x3e\x11\x39\x7f\x53\x95\xf5\xf2\xda\x17\x60\x3a\x8e\xe3\x9e\xb7\xdf\xfa\xb6\x33\x21\xaa\x6b\xee\xc2\x41\xde\xad\xbd\x8b\xcd\x08\x0d\xd1\xe3\x83\x1a\x0f\xc6\x4c\x44\xc1\xf9\xc0\x28\x91\xdc\xcb\xdb\xb7\x6d\x12\xbd\xb4\xa6\x53\x3f\xfa\x1b\xc2\x26\x2c\x20\x91\x41\xe2\xbc\xdd\x6b\xf9\xee\xaa\xea\x66\x55\x25\x26\x97\xd1\x30\x0a\x4d\x17\x3f\x5b\x8a\xd3\x59\x64\x47\xaf\x83\x7b\x15\x61\x1c\x7e\xc3\x80\x72\x86\x19\x31\x1f\x09\xc0\x02\x51\xbd\xfa\x38\x23\x6b\xdd\x5f\x9c\x6c\xfe\x1e\x26\x66\x8e\x8a\xa7\xec\x62\xf0\x03\x63\x92\xfa\x8e\x8c\x24\x68\x2a\xbe\xe3\x1c\xc6\x9c\xdf\xe8\xcb\x05\x8c\x47\xc8\x25\xf6\xe3\xc6\x61\xfd\x59\x10\x68\x89\x50\x3e\xef\xec\x76\x89\xa6\xbe\x1d\x8d\x9c\x77\x81\x24\xbf\x33\x52\x16\x2c\x08\x63\x8d\x67\xb6\x67\x94\x98\xe5\x0b\xf8\x5f\x05\x70\xdc\x8d\x23\x2a\x91\x75\xfa\x7b\x36\xc2\xc1\xb0\x80\xf3\x04\xdd\xa4\xac\xf6\x78\xbe\xce\xc4\x0b\x78\x9a\x22\x77\xf9\xa5\xc8\x9a\x3a\x20\x67\x1b\x9d\xb4\x52\x62\xae\x4b\xcc\x62\x44\x23\x7d\x5b\xef\xbb\x3f\xe9\x28\x72\x83\x6c\x95\xc2\xbc\x10\x06\xee\x66\x74\xbc\xe6\x83\x24\x4c\x91\xb4\xc4\xed\xa1\x68\x61\x8c\x32\x8c\x2c\x48\x03\x30\xa1\x0f\x4d\x02\x8a\xe7\xfc\x1a\x24\xeb\x17\x75\x90\xf2\x10\xf3\x96\xff\xb9\x40\xf5\xb9\x50\xf8\x14\x93\xed\x2e\x48\x95\x25\xbe\x71\x04\xf1\x96\xa2\xc1\xb7\xe9\xd0\x46\x5f\xb3\xa2\x79\xb4\x55\xdd\x78\xc0\x8d\x5f\x21\x05\x5b\xcd\x70\x44\x59\xbf\xbb\xaa\x3c\xfd\x01\xe3\x3a\x3c\x16\x08\x1e\xa0\xf2\x6b\x01\xef\x8b\xba\x2e\x55\x36\x25\xf9\x67\x81\x90\x69\x38\x14\xbf\xbc\x2b\xab\x6d\x55\x22\xd2\x04\xc4\xbc\x60\x12\x0b\x24\xa1\x68\x85\x6b\x50\xed\xd3\xd5\xab\xfd\xb7\x7d\xd9\xc7\x2d\x02\x19\x05\xc8\x9d\x25\x8a\x26\xfb\xcf\xc5\x63\xce\x58\xa0\x5a\xd3\x72\x00\x1e\xc0\x01\xed\xa9\xeb\xbe\x58\xf5\x2a\x4a\x91\x50\xe3\xa5\xc8\xf2\xd2\x32\x80\xed\x45\x96\x5f\xab\x8c\xb3\x40\x69\x4b\xda\x55\xf7\x3a\x1f\x5f\x1c\x38\x81\x16\x3a\x26\x5e\x7b\xa7\x3e\xee\x8a\x6b\xda\x09\xdf\x53\x06\x58\xa7\x88\x05\xb5\x07\x4b\xab\xd2\xbd\x92\x56\x16\x71\x96\x83\x69\x68\x38\xf9\x46\x10\x09\xac\x53\x3b\xe7\x5d\x7f\x48\x63\x09\x1e\xf4\xdc\x6e\x9c\xb3\xa1\xfc\xb6\x9f\xa1\xb1\x0d\xd8\x68\x80\xd3\x4e\x9c\x60\x99\x8b\xba\x5e\xe8\xf2\xdc\x80\x5e\x7c\x64\x93\x4a\xd5\x64\x72\x03\xa3\x24\x56\xa2\x1c\xf2\x01\x2c\x80\x05\xc6\x58\x76\x98\x23\x34\xbb\xd7\xec\x5c\xaf\xbb\x57\x09\x49\xcc\xad\x90\x1b\x1c\xd7\xf5\x0e\x9a\xcb\xb9\x6b\x49\x42\x4c\x2c\x2f\xaa\x06\xbd\xfe\xff\xa5\x45\x3f\xf7\x7c\x21\x91\x1c\x97\x60\x6b\x8c\x62\x22\x65\x29\x1a\x38\x96\x93\x14\x39\x0b\x29\xd3\x88\xef\x7c\xfc\x74\x80\xe4\x2f\x3c\xd2\x90\x8a\x18\x0b\x90\xef\x37\x0f\xb7\x87\xc5\xe3\xe6\xe5\x69\x7f\xf8\xe7\xd6\x2b\x11\xb0\x90\x45\x06\x61\x45\x16\xe2\x93\x95\xfa\x76\xa4\x65\xc5\x42\x16\x13\x3c\x8c\x07\xac\x80\xfd\xdd\x59\x4a\x92\x5e\x14\xea\x0e\xe0\xd7\x0c\xce\x2c\x64\xca\xc4\x1d\xdd\x44\x71\xe3\xa9\xc7\x59\x18\x84\x49\xc0\x7b\xff\x61\x9e\x42\x9d\x85\x81\x91\xbe\x3a\xb6\x3d\x39\x2b\x4b\x68\x7d\x2b\xa6\xe3\x13\x72\xab\x33\x0b\x3a\x6b\xb6\x50\xd5\xe5\xb5\xae\xf5\x4c\x81\x2b\x0b\x23\x1e\x47\xc6\x53\xf7\x5a\xa1\xb9\x5d\x76\x2c\x44\x73\xa9\xbe\xf0\x7c\xc2\x98\x02\x72\xbf\x67\xae\xea\xd7\x6b\x46\x4e\x9e\x28\x0e\x58\xe2\xc1\x56\x84\xfe\x09\x23\xf7\x27\x4c\x42\xae\xa1\x33\x3b\x5d\x48\xb3\x3b\x84\x07\xee\x4a\x98\x44\x21\x46\x40\xf6\x55\xe6\xf7\xc6\x30\x4d\x83\x91\xf3\x85\xd4\x08\xe3\xa7\x14\x34\x46\x02\xe4\xbf\xc8\x36\x4f\xde\x4d\x70\xab\x9d\x5b\xc0\x47\xb3\xf5\xa7\x6b\x28\x12\x8a\xab\x7b\xbf\xda\xed\xfb\x99\x24\x52\x8e\x0a\x3f\xcb\xfd\x6e\x10\x3e\x0c\x65\x28\x31\xbe\xb4\xff\x73\xb9\xd9\x3c\xcd\xc5\x07\x86\xa6\x45\x28\x23\x1b\xbe\x55\x65\x51\x5f\xae\x39\x53\x7c\x2f\xb0\xec\xd9\xbd\xa5\xa4\xe1\xe3\x0b\x70\x12\x0b\x15\x55\x9e\x27\xe8\xa9\x74\x10\xc9\xbe\xfc\x7a\xfc\x99\x54\xc8\x31\xd3\x6b\xcd\xc0\x51\xf6\xe6\x7f\x82\x3e\xc2\x18\xfc\x3f\xdf\x5f\x29\xcf\x7f\x94\x15\x68\x13\x5b\x70\xd3\x95\xec\x02\x0b\x75\xa4\x51\xfe\xe4\xfd\x33\x2f\x2f\xc3\x83\x3f\xd4\x8a\x61\x64\x41\x67\xdd\xb6\x03\x11\xe0\xb0\xdd\x3e\x2d\xbe\x64\x80\x61\x21\xc4\xa1\x65\x49\xc3\x04\xa9\xbd\xe7\xf8\x47\x0d\x65\xb1\x53\x65\x7c\x82\xf7\x81\x14\xfd\xd4\xa7\x1e\xed\x9a\xdd\xc5\xa1\x07\x96\x74\x81\xf1\x88\x10\x81\xf9\xea\x2b\xb1\xce\xf9\x67\x8c\x68\x22\x62\xb7\x64\xbf\x97\x0d\x54\x75\x27\xbd\xda\xfe\x4f\x7f\x57\x2a\x12\xe1\xb2\x21\x56\x5a\x43\xce\xd0\x3d\x0c\x67\x4a\xc4\xb8\x65\x9c\x39\x8b\xcf\xcd\x65\x7c\x60\x4c\x76\xd5\x88\xa5\xc6\x18\x1f\xb9\x31\x50\x55\xd7\x36\xb5\xef\xa9\x23\xe5\x44\x0f\x4f\xe7\xe6\x11\xc9\xd4\x71\x5b\x73\xed\x41\xc2\xb1\xae\x61\x97\x9d\xce\x39\x0c\x1d\xa3\x28\x30\xc6\x50\xa7\x26\x94\x89\x7c\x59\x16\xc7\xeb\x03\x36\x0a\x99\x91\x96\x34\x06\x29\xa9\xf1\x93\x21\xf1\x1d\x7a\x09\x83\x04\x44\x14\x06\x91\x13\x06\x6a\x84\x7a\xed\xfe\x1a\xa7\x48\x4d\xe8\x53\xd0\x1d\x5c\x77\xae\xca\x89\x45\x11\xb5\x98\x26\x8b\x27\x9f\x85\x1c\x4f\x07\x2b\x0a\x8d\x07\xb5\x79\x3b\x32\x8a\x22\x89\x5c\x82\x2f\x4f\xeb\xfd\x4f\x36\x79\xa5\x88\x4b\x1d\x4f\xc4\xde\xc7\x40\xe8\x09\xea\x82\x45\x91\xd0\xd4\xca\x4b\x99\xcb\x11\x06\xdb\x45\xc4\x43\xe2\x69\xc7\x37\xd5\xd2\xf1\x79\xc2\xcf\xac\xbc\xd4\x77\x00\x3f\xb2\x42\x7b\xb1\x74\x16\xf1\xc4\xd2\x34\xa3\xe6\x8b\x67\xe0\x1b\x1b\xac\x51\x1c\x12\x0e\x3e\x37\x76\x9a\x66\xa2\x51\x65\xc6\x88\x6e\x05\xf9\x3d\xbf\xfd\xec\x37\x0f\x5f\xcc\x91\x34\xa0\xd1\x94\x67\x61\xe9\x23\x39\x51\x1a\x04\x18\x40\xd8\x9d\xc4\x44\x43\x86\x45\xa9\x66\x98\x78\x7e\xc8\x0c\xec\xa0\x39\x10\x12\xf9\xcb\x04\xd5\x48\x26\xb4\xdd\xdc\x7e\xeb\xfe\x96\x12\x3c\x8c\x9e\xe0\x7d\xa4\x37\xf3\xb7\x1c\xac\x48\xf2\x28\xb6\xd4\x45\xf5\xcd\x34\x6e\xe7\xfd\xd5\x48\x85\x56\xcd\x4a\x7d\x4a\xa8\xac\x7e\xca\xf8\x91\x55\x14\x61\x39\x5a\x87\x6c\x05\xd3\x0c\x71\xad\x2c\x52\x40\x90\x02\xec\x60\xbf\xff\x90\x65\xea\x6a\x3a\x2a\x93\x7a\x82\x9b\xc5\xb1\xca\x50\x78\xa5\x3d\xe5\xe0\xa3\x99\xfe\xae\xd1\x51\x6a\x53\xb7\xdb\xaa\x3c\x65\xf9\x75\x5a\xc5\xf5\xd4\x22\x86\xe1\xc9\xe6\x3c\x58\x4f\x80\xe1\x7a\x99\x90\x20\x89\x99\xbc\x7c\xae\x8b\x5d\x7b\x9e\x6b\xd1\x37\xa6\x36\x26\x51\x37\xe5\x79\xdd\x74\x7f\x55\x90\xb8\x78\xe5\x3d\xc6\x68\x6c\x55\xe1\xf8\x41\x5b\x3b\xc3\xa2\x82\x3d\x7d\x32\x46\x19\xe0\x72\x72\x84\xfa\x93\x30\x20\x27\x32\xb5\x75\x87\x2e\xd4\xef\xf2\x39\xae\x95\x26\x31\x42\xba\x6d\xf1\x90\xd7\x46\x1c\x62\x56\x18\xa7\xca\xc6\x80\x1d\xa9\xb0\xdb\xc8\x17\x5a\x4f\x6d\x0e\xce\x94\xc6\xd0\xc7\x7b\x55\x96\x27\x7f\x79\xc0\x81\x47\x63\x55\xf9\x91\x96\xf0\xac\x61\xc4\x03\x01\x58\x3d\xbf\xdd\x7c\xbb\x0d\x68\x77\x2f\x48\x30\xf4\x50\x95\x17\xcb\x66\xa0\x27\xec\x42\x8c\x07\xc6\x26\x9f\x06\x7a\x88\x75\x77\x7d\xe8\xea\x4a\x7e\x2f\xdf\x5c\xee\xc0\x37\x44\xa1\x72\x10\x8d\xfb\x32\xd7\xb7\xa2\x11\xb7\xa5\xba\xf4\xb1\x0d\xd7\x2f\x8a\x39\x16\x0f\xf9\xba\x9a\xdd\x15\x42\x9d\xf1\x76\xc1\x5e\xe1\xfe\x66\x0d\x9f\xc4\x5f\x21\x52\x4c\xa8\x7f\x17\xf9\xe7\xa5\x11\x63\x84\x07\xe3\x3c\xb2\x4e\x44\x0d\xcd\x30\x92\x3f\xfe\x55\xce\x35\x42\x9e\x4e\xe2\x0d\xee\x2f\x53\x05\x46\xc6\x79\x62\xe3\x68\xdf\xb3\x3a\xeb\x3e\x6d\x1c\x10\xc4\x74\xf4\x98\xc8\xae\x45\x32\xe4\x7e\xfa\x09\x15\xe8\x4c\x35\x97\x53\xdf\x12\x10\xdd\xed\x60\x8e\xda\x60\x32\x11\x12\xce\xb0\xfc\x28\xc3\x7a\x98\xb9\x65\xc4\x13\x11\x0c\x54\xdd\x10\x33\x54\x67\xc7\xc9\x7d\xd2\x90\x01\xf2\x0e\x95\x79\x3e\x4b\x21\xf4\xeb\xf4\x05\x4f\x35\x03\xa7\x88\xf0\x04\xef\xdb\xb2\x11\x0d\xe6\x9a\x6b\x47\xa1\x39\x19\xa3\xd4\x50\x1c\xe8\xd6\x66\x5e\x4c\xda\x84\xab\xca\x74\xf0\xaf\xf6\x9b\x3e\x7f\x85\xe1\x66\x5c\x1a\x4b\x53\xd9\x6e\x27\x42\xbd\xb5\x93\x64\x2e\x89\xc0\x35\x33\x48\xac\xf4\x06\x9f\x1e\xab\x38\x90\x69\xf5\x9d\x74\x8c\x38\x96\xd7\xf2\xfd\x51\x14\x36\xac\xb8\x2e\x7e\x40\xb6\x2f\xad\x20\xe1\xee\xf3\x24\xcb\xbc\xa7\xbe\x61\x1c\x98\x4c\x7d\x61\xb7\xf8\x54\xa2\x2a\xb2\x89\x6c\x48\xdb\xc7\x1e\x8a\x27\x2c\x34\xe9\xae\x84\x30\x76\x21\x9c\xc3\xcf\x29\x2b\x80\xed\x13\xd3\x24\x42\x5e\xcf\x1d\x14\x9a\xde\x83\x67\xff\x62\x31\x93\x04\x63\x67\xaa\x1e\x6b\x28\xb1\x98\x69\xc3\xe3\xee\x73\xbb\x59\x33\x1b\x13\x88\x99\x49\x90\xb6\xc7\x06\xe0\xac\x86\x81\x6b\x0a\x98\xad\x90\xf2\x50\xb4\xad\xa8\x3b\x39\x01\x16\x07\xa1\x25\x33\x71\x86\x81\x78\xff\x82\x89\x62\x7e\xb2\xc4\x61\x6b\x0d\x60\xc4\x28\x53\x6f\xcb\xb2\xf8\x09\x55\xb3\xad\xb2\xb2\x42\x54\xbb\xbe\xce\xfb\xff\x6f\xa2\x70\x71\x18\x84\x18\x85\xfb\x29\x2e\x79\x33\xa6\xd0\x60\x71\x94\x08\xcc\x8c\x75\x14\x81\x5d\xbe\x3c\xe6\xc4\x92\x30\x0d\x24\x75\xa1\xb2\x95\xde\xdd\xe0\xb6\xbb\x25\xf5\xe7\x49\xb1\x3a\x41\x75\xec\x6b\xe1\x58\xcc\x39\x47\x6c\xae\xcc\xf4\x6a\x9a\x26\x8a\x79\x1c\x87\x6a\x70\x3e\x3c\x7b\x12\xd4\xee\xee\x71\xc8\xed\x93\x23\x20\x03\xb9\x80\xba\x26\x1e\xfa\x14\xa5\x05\x1e\xaa\x89\xc7\x1e\xa7\xcc\xd6\x49\x22\x8d\xf3\xf6\xb5\x84\x22\xfb\xe8\xcc\xdb\x38\x4d\x14\x4e\xc1\xc7\xc5\xd3\xb7\xc5\x7e\xbf\x78\xda\x3e\x6f\xfe\xf9\xe7\x62\xb9\xbd\x79\xf8\x7e\xdb\x75\x32\x22\x74\x65\x33\xce\x51\xed\xae\x17\x71\x8a\xe6\x04\x82\x76\x90\xe5\xbd\x7f\x36\xa1\x08\x4a\xb4\xdf\x43\xeb\x91\xef\x20\xcf\x3b\xa0\x81\x8f\xf5\xc6\x42\x0b\x04\x12\x61\x81\xc0\xaf\x54\xb9\xa7\x80\x87\x91\x41\xeb\x6e\x26\x0d\xc7\x72\x4f\x68\x5e\xcb\xaa\x86\x4d\x25\xd4\x8c\x09\x3c\x25\x4c\x63\xb1\x8a\x43\xe1\x31\x39\x2b\x4b\xe4\x35\x9b\xcb\x89\x95\xd0\xb6\x58\x58\x7c\x64\xa7\xcb\xa9\xcf\x88\xc5\x9a\xda\x0a\xed\x7b\x70\xfc\xab\x4b\x51\xe9\x5e\x3b\x87\xc5\x3a\xb0\xbc\x06\x18\x6a\xdd\x7f\x58\xd6\xcd\x9e\x11\xbc\x7b\xb5\x61\x0e\x2e\xd6\x51\x80\xf6\xe0\x8f\x32\x7f\xeb\x6e\xa4\xe3\xc4\xca\x9c\xde\x21\x53\x46\x67\x71\xbb\x76\xa0\x21\xe6\x1b\x5c\x42\xe2\xd6\x43\x65\x7d\x33\xe3\x98\xba\xb3\x71\x87\xe5\x15\xbc\x97\xc5\x26\x4a\x31\x4e\xbf\x5f\xff\xf3\xde\xf2\x76\xcd\x99\xa0\x5f\xfd\x3b\xbf\xb2\x4d\xca\x03\x47\x8f\xba\xb1\x26\xed\x78\x33\x9e\x76\x97\x01\x72\xf7\x3d\x96\xb5\xc8\xda\xe3\x62\xba\x5c\x8d\x16\x88\x54\x76\x74\x2f\x3b\x71\x12\x55\xd6\x08\xbf\x61\x27\x34\xa4\x54\x0e\x98\xb3\x17\x85\xb6\x55\x71\xf3\xa7\x45\x42\xe3\x00\x8d\xcf\xc3\xc8\x64\xf0\x7c\x0e\xae\x13\x0b\xa5\xec\x28\xdf\xee\xb2\x62\x5e\xa0\x84\x25\x4c\xa7\x86\x0d\x63\x15\xf5\x08\xcf\xcb\x92\x30\x11\xb8\x4d\xee\x97\xfb\x11\xbe\x6a\x2e\x3e\x92\x84\x82\x1b\x31\xe0\x38\x74\xe5\xbe\x1d\xea\x32\xf1\xfd\x24\xc1\x82\xb2\xa3\x38\xc1\xb3\x28\x74\x59\xd0\xee\xf7\x20\x41\x1f\xf6\x7c\xa9\x5f\x0f\x65\xe5\xa8\x54\x0f\x6f\x13\xd6\x62\x96\x44\x91\x34\x56\x65\x17\xd4\xdb\x0d\xd4\x57\xb2\x00\x93\x37\x8d\x22\x4b\x50\xee\x7d\xd3\xaf\x02\x03\x93\xd1\xe6\xb1\x8e\x6d\x7d\xec\x59\xcc\x93\xc2\xb0\x84\x4b\x2b\x07\x6a\x41\x66\xeb\xe5\xa6\xb5\x8e\xee\x57\xf4\xe0\xf9\x74\xfc\x91\x97\xc4\xce\xc4\xd0\x65\x01\x22\xaf\x40\xe8\xab\xe5\x3b\x58\xec\x49\xac\x85\x66\xc3\xca\xe6\x9b\x4f\x1b\x21\x5f\x8f\x65\xdd\x58\x12\x43\xca\x87\xbc\xed\x93\xaf\x98\x50\xab\xbc\xdd\xb8\x1a\xca\x85\xcf\xa8\x75\x1d\x12\x83\xf1\x0a\x97\xd5\xdc\x56\x70\xca\x2e\xa7\x39\x26\x86\xaf\x44\x64\x58\x92\x18\x81\x07\x3d\x88\x2a\xff\xf4\x88\x8c\x89\x65\x99\xa4\x94\xda\xc4\x95\xf5\x9e\x73\x51\xc0\x34\x95\xe9\x7a\x0a\x65\x95\x41\x10\x37\x84\x99\x0d\xd7\x20\x63\x8b\xcf\xf6\x5f\xb2\x35\xd6\x2e\xf2\x0f\xf8\xbc\x2b\x87\x52\x48\xe3\xa9\x29\x63\x89\x25\x6e\xdf\x45\x2d\x54\x6f\x2e\x27\x52\x9a\xd0\x05\x80\xd6\x0d\x9c\xa6\xb6\xde\xe4\x99\xa4\x31\x91\x8d\x39\xa9\x7d\x79\x2b\x3e\xa7\x6f\xa7\x98\x36\x9e\x3a\xfd\xef\x19\x12\x89\x8a\xad\xe6\xed\xf3\x45\x7f\xd6\xc3\xc0\x5b\xa2\xa4\x8d\x8e\x57\x03\x81\x43\x96\x28\x27\xbe\x77\x12\x1f\xff\xb8\x88\x02\xbd\xa3\xba\x6b\x04\xea\xf5\xcc\xfe\xc8\x8a\xa3\x2e\x4f\xfb\xcf\x33\xfc\x36\x1a\x09\xcd\x12\xac\xe6\xd7\x59\xdd\xce\x11\x6b\xbb\xd4\x48\x7a\x30\x98\x7a\x3a\x8c\x63\x37\xfa\x7b\xf1\x36\xe0\x63\x9f\x2c\x2b\x6d\x0c\xed\xf8\xdd\xcf\x63\x5d\xa7\xf1\x14\x85\x90\x4a\xe7\xb1\x6a\x38\x37\x6a\x08\x80\x98\xdc\x14\x22\xcb\x59\xee\x32\x37\x37\x65\x31\x4f\x2f\xcf\x12\x48\x2c\x5b\x49\xa6\x4a\xf4\xae\xa6\x1f\x04\x52\x86\xe7\xfa\x9f\x17\x51\x3c\x64\x62\x88\xdb\x66\x29\xe1\x01\x16\xa1\xe8\xac\xb6\x62\x06\x1d\xa7\xe5\xe8\x26\x29\xd1\x1c\xd1\x4b\x50\x34\xd5\xe7\x1d\xc0\xa1\xbb\x81\x96\xe8\xb9\xc8\xcb\xe7\xaa\x80\xea\x78\xc5\x68\xf9\x7f\x27\x37\x02\x8a\xe0\xd0\x53\x56\x34\x37\x97\xcf\x2f\xbc\x3d\xd7\x99\x05\x94\x93\xce\x87\xe8\xf9\x00\xbe\x2c\x93\xba\xba\x3e\xc0\x60\xde\xdd\xe6\xf9\x70\xb7\x79\x79\xea\x14\x9e\x59\xca\x12\x19\x5a\xe2\xed\xf5\xb9\xb4\x99\x95\x4d\xa7\xae\xd7\x36\x6b\xde\x97\x1d\x8d\x94\x17\x47\xa3\x9f\x06\x91\xf2\x42\x90\x8e\x85\xae\xf7\x47\x6c\xc1\xca\x6f\x93\x0b\x62\x70\xac\x73\xcd\xa5\x2a\xd6\xf8\xb8\xbf\x8d\x9e\x3a\xe4\x04\xb3\xf7\x96\x63\xae\xa9\xac\xc2\xe7\xe9\x3a\x67\x91\x86\xb1\x35\x16\x35\x5c\x6a\x68\x7c\x0c\x32\x0d\x53\x83\x56\xbf\xdb\x30\xcb\xcb\xf1\xb5\x99\x5e\xe9\x32\xb9\x59\x91\x35\x56\xb1\xcc\x35\x44\x6e\x73\x42\x12\xa7\x29\x85\xe8\x2f\xeb\x23\xae\xeb\x21\xc6\x1f\x23\x02\x88\xe4\xd8\x21\x6c\xcd\xcf\x97\xe7\xf5\x68\x71\xa6\x3c\x49\x12\xb7\x1d\x75\x49\x80\x89\x41\x91\xf2\xd4\xd1\x3d\xa2\x77\xb4\xb8\x34\xaf\x93\xf7\x8b\x13\x88\xe2\x8e\x8a\x19\xf4\xc2\xf4\x2e\x42\x9a\xb0\xd0\xe2\xa1\x7c\x48\xc8\x62\x07\x7e\xb9\x49\xa5\x89\x4c\x95\x5b\x66\xed\x44\xf1\xa7\x75\x9a\x12\x8e\xa0\x45\xfb\x5a\x56\x3b\x66\x07\x0d\x06\x8d\x26\x86\xc2\x24\x80\x33\x7a\xeb\x94\x51\x4c\xba\x3a\xee\x68\x38\x9d\xcb\x4a\x54\x5d\x6a\x7c\x0e\xf3\x95\x8a\x20\xc0\x49\x7a\x53\xea\xcf\x47\x51\xd7\x03\x36\x0d\x96\x8a\x30\xc5\x53\x5b\x8a\x01\x65\x00\x4b\x25\x09\x11\x3c\x79\x16\x97\x1a\x1e\xcb\x2e\x7f\x9f\xca\x88\x21\x2b\xf9\x3b\x64\x3b\xd5\x03\xbf\x53\x99\x4a\x65\x99\x79\x32\x84\x9a\xee\xcb\x97\x22\x73\xfc\x22\xe3\x11\x52\x46\x05\x6c\x38\xac\xdf\xb3\x4a\xe4\x1e\x80\x39\xee\xab\xb5\x46\x81\x17\x53\x56\x90\x1d\x8b\x19\xb6\xb9\xf1\xf0\x68\x13\x21\x81\x0a\x0a\xc3\x1d\x7f\x1b\x8e\x02\x48\x4a\x5c\x9e\x41\x8c\x29\x08\x58\x6a\x02\x4b\xe5\xea\xe0\x98\xab\x7e\x1c\x4c\x68\x75\xca\x4e\x59\x71\x03\xcd\x80\xcc\x95\x09\x12\x70\xed\xe8\xb9\xd8\x10\xfa\x2c\x68\x94\x20\x2e\x4b\x36\xca\x39\x2b\xbe\x01\x54\xe2\xb2\x92\xbb\xf2\x04\xcd\x6b\xfb\xf1\x27\xa8\x29\xc1\x62\x13\x48\xcf\xc7\xf4\x13\xf2\xf2\xdc\x3b\xf4\xae\x4b\x00\x02\x75\xaf\xbd\x09\x53\x78\x3a\x99\x71\x01\x14\x13\x61\x90\x60\xc8\xcc\x54\x4e\x28\xf5\xd6\x61\x1a\xc6\xc3\x2c\xc2\x98\x22\x4a\xcc\x86\xf5\x66\x92\xe0\xbe\x5f\x9a\x06\x6a\x90\x80\x01\x3d\x03\xc1\x12\x3c\x88\x70\xdd\x7c\x1b\x1c\xed\xae\x29\xa6\x14\x63\xb1\x5d\x5d\xf1\x5d\xaf\xc9\x72\xb5\x5b\xf4\x67\xac\x88\xa3\x20\xb0\x98\x0c\xd1\xbc\xde\x8a\x46\x1c\x04\x4d\xfd\x70\xc4\x29\xf1\xda\x07\x88\x40\xde\x96\x59\xd1\x78\xd2\x98\xd9\x13\x43\xc4\x42\x61\x72\xa4\x12\x6f\xdd\xd7\x89\xa5\x95\x2c\xc3\x62\x50\x0b\x01\x9d\x96\x37\x88\xc4\x48\x14\xf9\x33\xe8\x76\xe4\x3f\x73\x87\x80\x99\x29\xbf\x11\x29\x21\x4e\xbc\xb2\x41\x04\xd8\xcf\x49\x89\x29\x13\x29\x53\x61\xe4\x50\x1a\x5e\x46\xbc\xb5\x5a\xfd\xaf\xb5\xa3\xed\x88\xc5\xff\xb8\xf8\xb3\x58\x88\x98\x62\xd8\xc1\x9e\xf8\x87\x77\xcc\xa5\x1c\xa0\xd0\x07\xd9\x6b\xd3\x30\x21\x64\x14\x58\x0a\x85\x13\xe6\x96\x2e\x55\xeb\x40\x74\x78\x3a\x21\x94\x15\xb5\xce\x0a\xe5\x61\xd6\xbe\x05\x84\x0f\x72\x79\xc9\x4d\x9b\x0c\x98\x10\x4e\x31\x21\xd3\x30\x08\x3a\x09\x69\xa7\x1f\xa0\x57\xfb\x72\xff\x0a\xdf\x44\x6e\xf0\x3f\xa6\xd7\x48\x8a\xb1\xe2\x9e\x42\x6a\x14\xf2\x9e\x47\xfa\xba\x6b\x55\x64\x90\xa6\xdc\x58\x31\x47\x07\x97\x74\x8d\x3a\x90\xb1\x25\xe6\x10\x3d\x85\x19\x13\xc0\x83\xd0\x0c\xb9\xea\x4e\x30\xdd\x92\x04\x18\x1a\x58\x62\x0b\xd4\x5a\xb1\xd1\x3f\xa7\x4b\x38\xec\x3e\x7e\x1a\x43\x08\xfa\x70\x12\x9a\xe9\x82\x32\x54\xa2\x27\xfb\x52\x9c\x85\x7a\x5b\x28\x05\x75\x7d\x6b\xf5\xe9\x07\x7b\x92\x30\x61\x8c\xd1\xe0\x66\xc0\xcc\xb1\xc8\xfc\x87\x90\x84\x5a\xf0\x66\xd6\xf1\xd6\x2e\xea\x1a\x9a\xba\x1d\xd6\xac\x5e\x9c\xcf\x79\x36\x8a\x68\x4a\x12\x81\xf7\x82\x1c\x85\xfb\xf0\x81\x25\x49\x28\x52\x8f\xf8\x4a\x98\xef\x99\x86\xf2\x7e\xca\xbe\xc1\x24\x81\x14\x77\xdd\xd5\xe2\x79\xff\x6d\x68\x07\x4a\x62\x38\xc0\xf0\x07\x36\x66\x0e\x50\x22\x29\xa5\xdc\x85\xd6\x2d\x66\x15\x5d\xee\x2f\x72\xd5\xfe\x9a\x88\x89\xf6\x6d\xad\xae\x9b\x68\xe0\xa1\xac\xfb\x94\x8a\xa4\xa9\xa5\xb4\xce\x4e\x8b\x3c\xfb\x09\xdd\x9f\x85\x95\x5e\xf6\x7b\xa1\x0f\x65\x39\xa8\xa0\x98\xaf\x39\x65\x92\x9a\x20\x1d\xf0\x03\xaf\x8b\x9f\x65\xbf\xb7\x4b\xc6\x03\xac\x86\x40\xc0\x04\xa6\x8b\xd6\xb7\x7d\x5b\x8c\x36\x11\x26\xe4\xf2\x2b\x0e\x09\x26\x59\x22\x44\xe8\x63\x73\xbf\x40\xc1\x48\x06\xc2\xe9\x75\x59\xf7\xec\xdb\x8f\xe5\x2d\x9c\xc7\xdf\x8c\x19\x8a\xe7\x33\x2a\xa0\x5c\x4e\xb7\x99\x31\x99\xba\xe4\xcd\xe7\xfe\xb5\x82\xfa\xb5\xcc\xf5\x0f\xc8\xfc\xa3\x05\x5c\x5b\x76\x81\xa6\x3c\xef\xf5\x80\x55\x9e\xc9\x30\xd2\x98\x91\x42\x38\xfc\x8d\x50\x6f\xbf\x26\x14\x66\x32\x4c\x52\x6a\x49\xfa\xce\x3d\xae\x5a\x46\x2c\x34\x6e\x02\xf4\x6a\x7e\x5f\xdc\x21\x0a\xec\x17\x13\xd5\x98\x03\xa7\x6d\x91\x98\x98\x11\x4a\x55\x17\xd0\x0f\xd9\x7f\x26\x43\xc8\x0d\xa4\xee\x67\x16\xc7\x0a\x70\x11\xee\x46\x74\x65\x6d\x1f\x83\xbb\x63\x56\x23\x9f\xb0\x7e\x39\x4f\x6e\x12\xa7\x9c\x05\xfe\x3b\xac\xce\xa5\xea\xdd\x74\xd7\x23\x89\x39\xa1\x23\x9a\x99\x2d\x14\x7a\x30\xe9\xd2\xc0\xd6\x29\x7d\x5f\xed\xf6\xeb\xa7\xfb\x03\x3d\xdc\x2e\xf6\xab\xae\x35\x0a\xd1\x53\x3e\x97\x65\x7e\x07\xc3\x52\x1d\x99\x72\xc9\xdd\xce\xb8\xde\xde\xed\x86\x64\x8d\x63\x67\x4f\xa6\x32\xc6\x32\xc8\x9b\xd5\x1e\x7f\x62\xb3\x5d\x3d\xed\xba\xdb\x48\x4b\xe8\x25\xf4\xbf\x2f\x75\x6b\x7e\xfc\xd7\xea\xd3\xb4\x66\xea\x8f\x01\x04\x67\x3c\xf0\x42\x59\xa6\xb2\x63\x25\x8a\x66\xa1\xad\xc0\xb9\xc8\x11\xde\xfb\x05\xc0\x4c\x0a\x08\x52\x5f\x77\x02\x05\xa8\xcc\x64\x62\x9a\x45\x96\x92\x58\xed\x16\x4b\xe3\x3a\x48\x78\x4a\x19\x9a\xc8\x71\x53\x42\xd1\xfe\xdc\xa3\xf8\xe8\xda\x84\xc6\xb8\x1f\x7a\x29\x17\x1b\x68\x1e\xff\xb8\x22\x1a\xcb\x1f\xc5\xf9\x0c\x85\x5e\x15\xaa\xfa\x3c\x37\xc8\x5b\x3e\x0f\x17\x97\x2a\x90\x89\x9f\x1f\xd5\xf1\x72\xbd\xa5\x4b\x95\x26\xe8\xdc\x48\x51\x67\xca\x81\x60\x87\x1f\x48\x09\x89\x7c\x6b\xae\x74\x60\xb1\x5c\xae\x1e\x56\xcf\x8b\xfd\xc6\xbb\x7e\x52\x73\x8d\x55\x87\xaf\x59\x8f\xdf\x95\xda\x30\x04\xa4\xe1\xd0\x5a\x08\xd2\xea\x76\xf5\xcf\x2f\x06\x15\x52\xcb\x78\x58\xcd\xeb\xa4\x0d\xac\x05\x09\x32\x45\xea\xa9\x5a\xbd\x82\xbe\xe4\x70\x5b\xae\xa7\xaf\x64\xa8\x60\xae\xb8\xbf\x7a\x28\xd5\xdb\x8b\x87\x30\x4a\xc3\x2c\x91\xc6\xf3\xc6\xe6\x1b\xef\xee\xba\x96\x54\xdb\xb4\x53\x2e\x6a\xcb\x81\xa9\x4a\xfd\xd7\x64\x45\xfe\x6a\x29\x30\x80\x8a\xfa\x86\xa8\xe0\xd8\x1a\xf5\x4e\x5f\xd2\xf7\xd1\x0a\x09\xab\x9f\x85\x31\x39\x8a\x19\x16\x47\x78\x28\xcb\xf3\x78\xcd\x2b\x12\x0b\x6d\x0f\x33\x7d\x77\x69\xad\x11\xbf\xfd\xb8\x76\xaa\x09\x9e\x5d\x87\x4e\x15\x60\x4c\x3b\x3f\x7a\x32\xc5\x28\xe0\x8c\xf9\xd7\xb7\xf5\xb7\x97\xf5\xfd\x8b\xdf\xa0\x14\x8b\x54\xa7\x17\x10\xf7\x7f\xd4\xde\xf0\x3e\x38\x1b\x7f\x4c\xfd\x31\xff\x23\x01\xb1\x20\x9d\xce\x53\xd9\x35\x70\x1e\x7f\x14\x15\xea\x14\x6f\xfd\x2a\x6a\x4c\xe4\xb7\x1b\xe2\xbe\x7c\x06\x95\xc1\xcf\x39\x6e\x6d\xa6\x42\x43\x79\xd2\x11\x65\x5a\x5c\x32\xc0\xb6\x2a\xa7\xb7\x8e\x28\x8f\x5c\x8d\xc1\x00\xf0\xf5\xaf\xb2\x98\x1c\x38\x2a\x92\x2c\x76\x59\xd1\x87\x21\xb4\x61\x9a\x5e\x71\xdd\x39\x85\x01\x01\x9a\xf7\x99\xb7\x65\x39\x3a\x79\x14\xe7\x02\xe2\x1e\x07\xdd\x0e\x9c\xb2\x75\xcd\x07\x9d\x99\xd6\xfa\x2f\x14\x1c\x0c\xe2\x33\xfc\x40\xf3\xd4\xe2\x3a\x9b\xd6\x53\xbe\x5d\xac\xe7\x37\x28\xc5\x85\xb0\xe5\x6f\xd9\x51\xfd\x05\x92\x50\x71\x01\xd4\x51\xb9\x8e\xab\xe0\x5c\x7b\x12\x30\x8b\x76\xcf\x41\x54\xa8\x44\x36\xb1\xc9\x5d\xbf\x34\x64\xb1\xa5\xad\x52\x9f\x2a\xef\x35\x29\xc6\x4f\x26\x94\x0d\xe8\xd4\xd0\xbc\xec\x6e\x6f\x1a\x35\x69\x97\xad\x0f\x87\x27\x86\x13\x15\xad\xb1\xe8\xc0\xef\x0f\x4a\x69\x82\xb0\x21\xc4\x6e\x8e\xb8\xe8\xbf\xac\xa2\x54\x3a\x02\x94\x32\x41\x5e\xd4\x1b\x68\x26\x0b\x07\xa8\xc1\x19\xf6\x3d\xfb\x50\xa5\xe3\x23\x67\xbf\x1c\x32\xe0\x14\xad\x97\x63\x5e\x4a\x91\x3f\x42\x33\x64\xae\x65\x0a\x52\xab\xd3\xed\xc9\x5c\xbf\x97\x0d\xd4\xcb\x8e\x5d\x9e\x29\xd0\x04\xe3\x8f\x37\xfb\xea\x52\x0f\x49\xb4\x98\x32\x34\xc6\xd1\x7e\xd9\xed\xc7\x11\xb9\x2f\x0b\xf3\x94\x89\x2c\x36\xe9\x5c\x65\x3f\xb3\x1c\x8e\xa0\xaf\x12\x0a\xa3\x79\xea\x2f\x4b\xad\xef\xda\x71\xbc\x16\x4e\xb3\xef\x8b\xc5\x6a\x84\x46\xb6\x83\xac\xbe\xbb\xe0\x19\xfe\xd4\xb9\x06\x9a\xe8\x00\x05\xcb\x36\xb7\x74\x88\x5c\x75\xad\x94\x59\x4e\x83\xc7\xcf\x3d\xd4\xce\x5e\xf5\x5b\x87\xa6\xd2\xea\x23\x3b\x3b\x31\xff\xb4\x65\x73\x03\xd3\x4a\xb7\xbf\xad\x3c\xb1\xd8\x47\xe3\x8a\xcd\x26\x3f\x12\x50\x62\x52\xcf\x40\xd9\x9e\x9e\x13\xf8\x9d\x0e\x42\x46\x9d\xed\x7e\xe8\x83\x74\x3a\x24\x12\xbd\x3d\x0d\x46\x75\x86\xbe\x0e\x81\x20\xac\xf4\x2c\x3e\xd9\x57\x51\x37\xd7\x95\x13\x4d\xe3\xce\xc7\xd8\x42\xd5\xdb\x8b\x9a\x83\x4c\x62\xef\x1b\xfd\xff\x69\x7b\xb3\xe6\xc6\x71\xa4\x6d\xf4\xef\xf4\xc5\x5c\x10\x04\xc0\xe5\x52\x92\xe5\xb2\xa6\x6c\x4b\x63\xc9\x55\x3d\xdf\xc4\x1b\x0a\x2c\x09\x9b\xaf\x29\x52\x43\x52\x55\xa5\xfe\xf5\x27\x98\x00\xb8\x49\x72\xf5\x77\xe2\x9c\x9b\xa9\x1e\x13\xa4\xb8\x00\x89\x5c\x9e\x7c\x1e\x53\x86\x9f\x27\x65\x75\x1c\xb1\xd0\x7b\xff\x0a\x8a\x49\xd8\xa0\x13\x4e\xa9\xed\x7b\x41\xd9\x83\x79\xd6\xae\x6d\xe7\xf3\x6f\x2a\x30\xd9\xaf\x61\xf0\xa3\x13\x95\xe0\xb4\x9f\x69\xfd\x24\x1a\xa8\xb2\x2b\x02\x01\x93\x1f\x50\x06\x53\x83\x58\xc8\x7a\xad\xa1\x42\xe4\xe9\x69\x42\x94\x1b\xea\xd4\x10\xcb\x64\x8c\x71\xdc\xe2\x75\x7b\x37\x79\xd7\x82\x04\x28\x0e\x6b\x3b\x64\x3a\xbe\x86\x7a\x3a\x8c\x5a\xe2\xa6\x55\xf9\xb4\x1b\xae\x02\x2d\xb8\x0e\x98\x7f\xa7\x9e\x3a\xec\xc9\x63\xbd\xfc\x28\x19\x9a\x58\xf6\x04\x17\x6b\x63\x10\x5d\xbc\x99\x70\x9f\x8c\x9f\x51\x32\xe2\x1a\xf6\x9e\x5f\xb7\xfb\x8e\xb9\xa6\xbb\x66\x44\x3c\xe9\xf6\xa9\xc8\x9a\x3b\x30\x50\xd4\x16\xe6\x73\xcc\xb3\xbf\xc1\x42\x38\x98\xb7\x52\x18\x8b\x25\x87\xba\xd9\x97\x05\xac\x0a\x04\xa6\x2c\xff\x3b\xb7\xf6\xa7\xfb\x4d\x47\xf2\x76\x14\xe7\x45\x79\x40\x12\x91\xed\xb1\x2c\xea\x29\x7e\x45\x4b\x13\xe9\xb0\xef\x01\xbd\x07\xd8\xf9\x96\xc5\xab\x21\x9f\x56\xd4\x96\x0b\xdc\x1b\x72\x20\x3b\x6f\xda\xb5\xe2\x02\x53\xbc\x88\xcf\x15\xa3\x1c\x98\x56\x09\x78\x89\x85\xd5\xb7\xfd\xcb\xa4\x07\x4a\x2b\x48\xbc\xfa\xfd\xb2\x56\x27\xc8\x45\x77\x66\xeb\x67\x60\x9d\x76\x39\x7b\xda\x7f\x5d\x2e\x37\xab\xe7\x2f\xdd\xb1\x54\x22\xba\xbf\x81\xc3\x11\x37\xfc\xa1\xe1\xd4\x5a\xdb\xd4\xf4\x1b\x34\x8f\x2f\x8b\x6b\x54\x24\x5a\x03\x53\xda\x97\xbd\x5a\x6b\xf0\x84\x42\xb9\x5d\x02\xc8\x0d\x83\xd0\x12\x91\x29\x6c\x0e\xf9\x06\x55\x66\xce\x5f\xe1\x3c\x44\x9b\x5f\xa4\xc9\x47\xbb\x82\x36\xc4\x26\x26\xd1\x11\xf5\x32\x10\x23\x77\xe3\x92\x48\x03\x02\x42\xbc\x93\x6f\x53\x99\xd7\xca\x89\x10\x84\x12\xc3\x52\xec\x84\x5d\x76\xa6\x08\x08\xa1\x18\xa0\x9b\x9e\x89\x76\x4c\xc0\x38\xb9\x0e\x09\xe3\xd0\xa2\x50\xfe\xdc\xb7\x73\x78\xd9\x71\x76\x40\xc8\xed\x87\x6f\xad\x03\xef\xfe\x28\xad\x95\xb6\xb9\xed\xcf\xdc\x3f\xa0\x31\xb1\xc4\x03\x1f\x79\x59\xd7\x5d\x55\x0f\x68\x9a\x60\x8b\xc0\xe1\x94\x37\xcf\xa7\x03\x58\x4a\x3d\x77\x90\x91\x10\x53\xf3\xed\x43\x7f\xc0\xe6\xd4\x74\x07\x22\x8b\xe1\x6b\xca\x1c\xda\xd7\xb9\x3d\xc9\xeb\x8e\x0b\xf0\x84\xf3\xb8\x0f\x7f\x97\x6f\x6f\xdd\x4f\x73\x21\x6c\xbe\xad\x75\x28\xb1\x3b\xbb\x1a\xa4\x66\x20\x0a\x03\x6a\x37\xf9\xb2\x86\xbd\xec\x28\x7e\x43\x88\x28\xe5\xae\x65\x06\x4b\x94\x96\x50\x76\x34\xad\x20\x8a\xed\x6c\x3f\x0c\xa5\x4b\x43\x88\x0c\x41\xb6\x95\xb7\xec\x07\x52\x26\x40\x61\x6b\x39\x93\xb3\xe3\xd8\x18\x8a\x70\x9c\xbf\xa6\x47\x12\x96\x04\x63\x7c\xe6\xf6\xe3\xe4\x2f\x9f\x04\xb6\x1f\xa5\x6b\x36\x41\x46\xf6\xee\x28\x8b\x30\xbf\xe9\xcc\xfd\x40\xaa\xec\xd3\x3c\x0f\x24\x3c\xc6\x8d\x3d\x87\x37\x91\xd7\xe3\xd4\x36\x24\x2a\x89\x5d\xe9\xb3\x35\xf0\xed\x0d\x0d\x0e\x59\x22\x3c\x71\x90\xb7\xca\xce\x90\x68\x83\x31\xff\x6a\xb1\xde\x7b\x61\xcf\xc5\xfa\x79\xf7\xb2\x9a\xbf\x0e\x1a\xf5\x21\x25\x21\x4b\x3c\xc5\xaa\x18\x8b\xf7\x85\x90\x72\x13\x39\xf9\xae\xf2\xd4\xec\x8b\xb2\x3a\x60\xfa\xad\x9b\x4a\xa9\xb0\xb9\x07\x55\x1a\x0b\xb9\xab\xad\xa5\x70\xac\xc9\xad\x83\xa3\xde\xfb\x69\x29\xc2\x10\x03\x09\x9f\x78\xfb\x84\xe7\xba\x1d\xac\x53\x57\xc3\x98\x97\xe5\x47\x2f\xb9\x10\x82\x0c\x15\x52\xcc\xfc\xc8\xe0\xa7\xe7\x07\x71\x1d\x7b\xe3\x77\x2c\x25\x45\x97\xe4\x2e\x83\x1a\x2c\xc3\xcb\x06\xde\xba\xcb\x28\x86\xd4\xaf\xe6\x28\xaa\xc6\x26\x4f\x46\xa5\x45\x50\xc4\xaa\x17\xd4\xef\x62\x18\x83\x7f\x1a\x56\x80\x8e\x68\xe0\x8c\x4b\x9f\x37\xbf\xfe\x88\x3a\x8d\x3c\xf7\x6c\xa7\x1f\xd2\xa7\x6c\x01\x88\x46\x54\xd5\x09\x59\x6b\x66\x8d\x67\xb1\x19\x01\xab\xfc\x58\x16\x69\x8b\xf1\x3d\x8e\xba\x70\xc1\x24\x14\xf9\xdb\x66\xa7\xe6\x7d\x55\x64\xd3\x35\x61\x00\x42\x37\xd1\xf6\x03\x9d\xd2\x7d\x71\x3a\xec\x4b\xb3\x3f\x56\xe5\xbe\x12\x8d\xd8\x5b\xb7\x69\x8f\xe4\x6c\xd3\xc2\xaa\x09\x20\x42\xd2\xda\x8e\x93\xe9\x09\x9a\xf7\x52\x8f\xe7\xb4\x09\x4c\x88\xae\x9f\xb5\x6b\x93\x1a\xa5\x21\x91\x4a\x3a\xfc\x91\x8f\x4a\x26\xdf\xd3\x84\x3c\x32\x4e\x34\x77\xb5\xf6\xce\x80\x09\x4d\x82\x79\x5a\x91\xe7\x5d\xff\xc8\xa8\x1f\xcd\x50\x08\xb5\x75\xc9\x9c\xdb\xea\xfe\xce\xa8\x94\xb6\xf2\x00\xba\x57\xdf\x0c\x0d\xe3\x29\x96\x52\xf6\x07\xf1\x6b\xb4\xf7\x19\x96\x58\x72\xff\xed\x6a\xb6\x98\x6d\x1f\x16\xeb\xd5\x73\x77\x48\x18\xbc\x18\xd2\x42\x7f\xbd\x50\xc3\x0b\x0d\x83\x14\x5b\xeb\xbe\xe8\x63\xf5\xf7\x44\xba\x42\x13\x05\x56\x52\x7c\x94\xe3\x37\x91\x30\xd8\x06\x62\x17\xd0\xb8\x64\xfd\x39\x7a\xc4\x44\x46\x58\x62\x00\x77\x73\x65\x87\x6b\xda\xcf\x55\x79\x3a\x5e\x36\xda\xbb\x13\xe3\x20\xd5\x6e\xa6\x58\xfd\xe9\xab\x66\xcd\xc4\xb1\xc6\xec\x8c\x5d\x90\x48\xc8\xe1\x8f\x48\x48\x1c\x52\xff\x3e\x47\xd5\xd2\xd3\xb0\x3f\xfe\xc6\xfd\xc6\x9a\xe0\x27\xb7\xc6\xe7\xfe\xe4\xb9\x58\x43\x93\x70\x10\xae\x07\xc2\x36\xb6\x8d\x4f\x4c\xe2\x10\x71\x8f\x1e\x25\x37\xb2\xda\x26\x11\xa1\xf4\xd0\x52\x71\x5e\x9b\xef\x00\x93\x1e\x43\x93\x06\x56\xe3\xf5\x0b\x76\xf1\xb6\xfb\xe8\xb0\x73\xd1\xa4\xd4\xe0\xd7\xc4\x4a\x76\x56\xbc\x7d\xcb\x84\x2b\x73\x0e\x83\x50\x23\x88\x31\x8e\xa2\x63\xbf\x79\x59\x3f\xad\xf7\x5f\x56\x2f\x8f\xde\x03\x30\x22\xe1\xca\x33\x7c\xdf\x8b\x2c\xf7\xad\xf2\x7e\xee\xcc\xde\x44\x07\x3d\x32\x42\x70\x3d\x80\x59\xbc\x3c\x5e\x75\x5c\x8c\x30\x01\xed\x40\x16\x75\x53\x9d\xd4\x40\xea\x60\x3c\x54\x72\x4b\xd5\xdf\x41\x03\xef\xab\xf2\xf0\x3d\x6b\xde\x6d\x5d\x73\x48\x8d\x7c\xa3\x30\x35\xfe\xfa\x32\x26\x66\xd0\xe8\x60\x8b\x23\xdf\xa0\xd0\x65\x85\x5c\xf0\x93\x4c\xaa\x91\xb1\xc5\x42\x5a\x85\xc6\x6a\x6d\x76\x3f\xb3\xa6\x41\xb8\xda\xe4\x46\x35\xa0\xdf\xf0\xdf\x46\xa3\x3e\xdf\xe1\x22\x4c\x31\xd2\x58\x65\x60\xa1\x75\x57\x31\x9e\x0c\x51\x94\x30\x5f\x8f\xf1\xa9\xa4\xae\x80\xe0\xaa\x18\x1d\x4d\xc5\xf8\x06\x40\x71\xb0\x29\xf0\xa1\x79\x35\x60\x00\xb7\x34\x0d\x3f\x4e\x90\xff\x80\xcd\xa9\x68\x4e\x42\x65\xa8\xc2\x32\xda\x18\x8c\x21\x04\xd1\xc8\x0b\x64\xd2\xdc\x42\xee\xd8\x34\xff\xa6\x28\xac\xbf\x4a\x9c\x62\xee\xf9\x75\x3b\xb3\xf7\x40\x03\x12\x5b\x97\xcb\xc2\xbe\xbe\x5d\x22\xc0\x69\x40\x20\x96\x36\x2b\xb0\xf2\x8c\x5a\xc8\x0a\xe4\x8f\x87\x81\x44\xec\xef\x16\x1a\x83\x2c\x08\x3b\xf1\x6b\xf4\x02\x68\x10\x52\x5b\xce\xd9\xeb\x72\x21\x1a\xf5\x7e\x9f\xd5\xef\x93\x15\x3c\x7c\x5e\x1a\x84\x8c\xa1\x3a\x96\x19\x28\xe0\xfa\x43\x2a\x45\xb7\x03\x0d\xc9\x5d\xe7\x04\xd2\x80\x06\x56\x95\xf8\x5d\xd4\xbd\xaa\xf5\xf8\x5c\x1a\x0b\x6f\x46\xda\xc0\xa2\xa7\x6d\xeb\x6f\x95\x05\x14\x8d\x74\xd9\xae\xc7\xec\x2f\xd8\x23\x4b\xc3\xa8\x8b\xef\x3f\xec\x7f\xfc\x60\xca\x30\x5a\xdb\x81\x7a\x2f\xca\xbc\x7c\x3b\xf3\x2f\x97\xd6\xf9\x9a\xb1\xa3\x01\x03\x8d\x21\xe1\xcc\xf1\x65\x5e\xb5\x89\x34\x88\x08\x33\xd2\x0b\xc5\xef\xae\xf5\xed\xfc\xc7\xdf\x4d\x44\x35\x6a\xca\x3e\x40\x9e\x67\x85\xf0\xef\x25\x8a\x42\xd3\xb7\xb3\xb4\x9f\xcf\xf5\x85\xdd\xf8\xc5\x24\x56\x18\x99\xef\xb3\xda\xa6\xa9\xfb\xce\xe0\x1b\x8f\x92\xa4\xb6\x88\xd3\x61\x84\xb3\x1c\xdb\x45\x7b\xd1\x37\x12\x4d\x4f\x11\x8c\x60\xb9\x02\x43\x94\x17\x91\xd5\xa0\xe7\xe7\xc9\xb7\x48\x13\x91\x5a\x2b\x5d\x15\xb3\x36\x46\x99\xc6\xcb\x34\x10\xc4\xca\xec\x21\x9c\xe2\x2d\x2b\x0b\x57\x6e\x5f\x1d\xc4\x1b\x4c\x2c\x41\x3b\x9a\x61\x23\xe9\xcb\x6a\xfb\x75\xff\xb8\xfc\xb6\x7c\xf4\x2f\x49\x50\x85\xd0\x16\x55\x3a\xab\xf7\x1d\xc4\xb1\xb4\x08\xbe\x4b\xc9\x80\x7f\x4c\x2e\x9b\x04\x61\x30\x62\xd1\xbd\xa4\x48\xa2\x81\x24\x80\x7b\x3c\x46\x37\x2f\x36\xbe\xb7\x98\x85\x69\x5f\x0d\x0d\x64\x6a\x85\xc7\x11\x15\x50\xb6\x0e\x0d\x72\x11\xde\x67\x90\x4f\x00\x3e\xed\x58\x8d\x31\xe5\x11\xe9\x22\xa6\xab\x57\xea\xd0\x75\x39\x60\x5d\x7e\xb8\x93\xd1\x40\xf1\x00\x4b\x91\x33\xaf\x8c\xd5\x75\x31\x74\x39\x0e\x1a\xa8\x34\xc2\xb2\xca\xdc\x03\x4e\x5a\x1b\x3f\x33\x26\xcb\x2f\xe8\x42\x68\xa0\x0c\x23\x5e\x8c\xae\x7b\x6b\xd7\x5f\xde\xe4\x25\x6a\xca\xb0\xde\xad\x44\xe1\xb5\xd0\x3a\xe5\x2d\x1a\xe8\x08\xbc\x14\x66\xd7\x34\xfd\xc7\xd8\x66\x68\x63\xa2\x76\x53\x6d\xde\x41\xe5\x27\xe9\xcf\x34\x2c\xc5\x44\xb9\x3c\x9d\xad\x27\x7a\xb1\x6e\x4c\x04\x89\x2b\x34\x2e\xaa\xb3\xae\xbe\x65\xf0\x73\xdb\x88\x42\x8b\x4a\x3f\x8b\x03\xf4\xc4\x44\x94\x04\x92\x26\x6c\xd0\x93\xb2\x6d\x3a\xf8\x0b\x25\x84\xdb\xe4\xde\x76\xbb\xae\xde\xec\x1a\xbd\x2d\x21\x4e\x09\x0a\xa4\xd9\x74\x6b\x59\xb5\xf1\x67\x31\xdc\xfe\x29\x21\xda\xd6\xd7\x75\xd9\x74\xbf\xa0\x15\xee\x79\xc7\xb2\x6e\xae\xea\xef\x8d\x75\xf8\x28\x21\x40\x31\xd9\xdc\x2e\xfb\x7b\x77\xcf\xd7\xd3\xbf\x94\xd0\xf6\x09\x06\xc4\x73\x96\x47\xf0\xa2\x60\x43\x09\x23\x46\x7b\x6a\x94\xcd\x8d\x8b\x31\xae\x6c\x80\x54\x56\x0a\x06\xfa\x0a\x94\xb0\x48\xf9\xd5\x82\xb0\x54\x9f\xde\xfc\x24\xa7\x47\x09\x13\x5c\x0d\x19\x07\xc7\xd3\x8e\x30\x61\xd1\xe0\x28\xa4\xe7\x88\xeb\x27\xc6\x9f\x70\xce\x2d\xe9\x8c\xbe\xd2\x30\xe5\x27\x03\xe1\x89\x12\x6e\xd4\x95\xae\x1b\x37\x28\xe2\x12\xd3\x7e\x42\x29\x38\x36\xf3\x4c\xdf\x97\xd5\xe6\x54\x7c\xdc\x1a\x9e\x02\xa2\xb9\x0e\xa0\xc5\xa0\x17\xae\x3d\x60\x63\xe0\xe5\xdd\x2b\x8a\x35\x2f\x77\x0f\xfb\xe5\xec\xe5\xf1\xdf\x1d\x98\xbf\x1b\xa9\x03\xa5\x27\xe8\xad\xc8\x1f\x8c\x93\x24\x18\x60\x6f\x66\x95\xcc\x1a\xd7\x9d\x32\x5a\x22\x24\x56\x21\xd6\x7c\x0f\xa0\x33\x61\x6d\x1b\x22\xbc\xc6\xb7\x1b\x2b\xcb\xce\xb0\x87\x42\xdb\x1e\x76\x7f\x00\x6c\xa7\x9c\xf5\x21\x11\x48\x73\xe3\x73\xc5\x26\x35\x0e\xa8\xbd\x15\xc5\x93\xf8\x75\x85\x82\x8e\x92\xc4\x18\xe5\xb4\x04\x5e\xca\x8f\xcf\xf4\x34\x28\x49\x89\x44\xef\x70\xc0\x0b\xea\x1e\xb3\xac\xa6\x4b\xc0\x9f\xc2\x18\x66\xc8\xd0\xe1\x2d\xb2\xe6\x26\x23\x4b\xf7\xf1\xd3\x44\xa6\xc9\x40\xf5\xd5\xf6\x3f\xec\xaa\x4c\x9e\x06\xe4\x63\x6e\xb0\x08\x02\xd5\x23\x63\x11\xbe\xf8\x32\xd0\x5b\xf0\xa3\x42\x89\xf8\x24\x07\x3e\x19\xf2\xab\x22\xd9\x41\xf7\x11\x05\xa3\x29\x78\xd6\x4a\xa1\x3e\x5a\xff\xf2\x0e\xea\xa6\x2a\xa7\x9d\xd6\x94\x08\x05\x98\x55\xb7\x99\x51\x8b\xfb\xdc\x40\xb5\xdc\x3d\xcc\x7b\xfc\x1a\x25\x32\x08\x71\x18\xba\x65\xe3\x23\x2c\xf1\x58\xea\x36\xfe\xa8\xb7\xd0\x7c\x87\x6c\x03\xd5\x93\xd3\x90\x9f\x3c\x85\x22\x0a\xac\x5e\xe0\xa9\x06\x6d\x43\xf4\xc9\x3d\x29\xa2\x99\xb5\xa2\xd8\x1a\x35\xad\xda\xf9\x51\xd2\x2a\x5e\x2e\x9f\xb7\xfb\xed\xeb\x7c\x3f\xdb\x6c\xf6\xcf\xb3\xa7\x6e\x9e\xeb\x24\xc6\x7e\x41\x55\x1e\x8e\xd0\x64\x6d\x88\x39\x55\x3c\xa3\x44\x0b\xee\x99\x0c\xb6\x50\x68\xa8\xec\x76\xeb\x8e\x42\x10\xf3\x60\x00\x09\xfa\x5b\xd9\x60\x4a\x80\x58\xda\x8d\xe3\xa9\x82\x3e\x54\xa4\xc4\x88\x04\x3d\x83\x55\xbd\xb0\x3a\xbb\x17\x84\x21\x76\x60\x48\x02\x85\xc2\x01\xdb\xc6\x0c\x39\x4d\x68\x48\x98\xf1\x3a\xc1\x9b\xaa\x34\x59\x33\xf3\x92\x0a\x6b\xf3\x50\x9e\x7c\x5f\x20\x0d\x09\x44\x48\xf8\x7b\xec\xe9\xfb\xa0\x50\xed\x57\xe9\x52\xc8\x34\x0c\x89\x21\xee\xe1\x9f\xe5\x37\xdf\x4c\x71\x59\xc3\xa4\x98\x71\x40\x86\x32\x87\x6c\xfd\xd7\x49\xd8\x1e\x3e\x77\x9c\xa6\x31\xae\x0f\xa1\xb5\xaf\xf7\x0e\x17\x46\xef\x94\x8f\x97\x62\x48\x45\x80\x86\xf4\xbb\x78\x13\xa3\x07\x65\x81\x4e\xc8\x80\xd1\x6f\x20\xc8\xfb\xad\xcc\x4f\x07\xb0\x44\x00\x1d\xe6\x85\x86\x8c\x87\x24\xea\x2c\x4a\x17\x57\x4d\xb7\xe8\x90\x29\xcb\xa8\x63\x79\xd8\x3b\x1e\xa2\x76\x67\xf6\xb1\x12\x73\x43\x79\x48\x71\xaa\xe2\xc6\x73\x87\x0a\xdb\x6b\x33\xcb\xf3\x2e\x4b\xe6\x7f\x3b\x0a\x44\x22\x3b\xe4\x25\xf2\x6a\xd8\x80\xc0\x6e\xa0\x81\x1f\x16\x46\x76\x57\x6c\xc3\x4c\x0c\x90\x7a\xa1\x1c\x3f\x24\xd2\x1e\xd1\xb5\xae\xde\x44\x91\xfd\x05\x95\xcf\xca\x42\xff\x7b\xda\x20\xee\xa5\xce\x1a\xd8\x9f\xaa\xbc\xfb\x3b\x58\xb9\x3c\x4b\xf1\x71\xf7\xb4\xbd\x60\x1c\x1c\x7e\x06\x3f\x5f\xc3\xc8\x08\x93\xfa\x1d\xb1\x06\x51\xa9\xf7\x2b\xfc\x4f\x34\x4c\xb8\xcd\x4f\xdb\xa4\xca\x67\x80\x35\x1a\xa6\xd2\x32\x2a\xa1\x70\xe5\x5d\xef\xf6\x84\x22\x54\xc4\x2a\x09\x83\x3a\x35\xd0\x7d\x00\x6b\x52\x93\xff\xfc\xcf\x80\xdf\x64\xf2\x5f\xfe\x0a\x34\x88\x1c\xdf\xc5\xfd\xa9\xd0\x93\x10\xc4\x0f\x8a\x24\x42\xf3\x6b\x9b\x50\x75\x7f\x55\x4c\x23\x34\xa7\x3e\xc9\xbd\x59\x94\xfa\x6a\xcd\x85\x86\x2a\x92\xc2\x02\x9c\xf3\x55\x81\xa2\x23\x27\x91\x2f\xa0\x6a\x32\x63\x15\xef\xaf\x48\x52\xd2\x50\x09\x40\x8f\x2a\x17\x75\xb3\x2f\x8d\x81\x6a\x9f\x75\xbf\xac\x65\x80\xe5\x58\x21\xcb\xaa\x71\x35\x71\x7f\x0c\x78\x8c\xbc\x0c\x25\xb6\x6d\x0e\x33\x7d\x34\x84\x18\x52\xb7\x10\x1c\x51\xf5\x75\xcf\x20\x84\xd4\xf5\x26\x9e\x8a\xba\xef\x1d\xa0\xa1\xd1\x76\x5d\x38\xe9\x90\xbb\x72\x52\x29\xa6\x6d\x4c\xad\xdd\x76\xe1\x9e\xd1\xd1\x95\x8f\xaa\x49\x43\x7b\x40\x83\x08\xb4\xbb\xe8\x93\xdd\x8d\xb0\xd7\xc9\x1f\x35\x96\x7f\x3f\xab\x5d\x34\xd0\x4c\x66\x12\x25\x01\xf3\x4e\xd6\xa6\x82\x1a\x59\xbe\xe0\x0e\x9e\xa0\x16\x63\x3f\x83\x92\x30\x10\x0e\x75\x8d\x88\xdd\xf3\xeb\x8b\x8f\xb4\x28\x11\x26\x1a\x12\x0a\x0e\xb3\xaa\x94\xd2\xc4\x8a\x3b\x69\xc8\xaf\x50\x51\x52\xca\xa8\xf0\x8e\xc5\xa2\x2c\x4c\xf6\xf6\x59\xa1\x84\x52\x16\x85\xd4\xf8\x98\x6b\xb9\x7b\xf2\x3f\xc3\x03\x60\x36\xed\xf1\x26\xb2\xc2\xe6\x24\xfd\x21\x1e\x63\x9e\x67\xf5\x51\x7e\x94\x43\xf3\x46\xb9\xa6\x48\xb5\xb5\xba\xdf\xba\x9b\xfe\xac\xd6\x4e\x69\xac\xad\x68\x20\x14\x7a\xdd\x4e\xac\xac\x78\x5b\x1d\x8e\x7e\xdd\xd3\x84\x07\x58\x80\x83\x43\xd6\x38\xa6\xb4\x4f\xc1\x03\x94\x26\xa9\xc2\x86\x40\x5d\xaa\x49\x10\x48\x13\x15\x60\xe5\x60\x2f\xda\x79\x88\x30\xc5\xdf\x5c\x2c\x0d\x62\x41\xbb\xb5\xe6\x6e\x60\x56\xe8\x85\x40\x03\xeb\xef\x32\x65\x80\x6c\x3c\xbb\x2a\x3b\xce\xf2\x6e\x8a\xd3\x54\xdb\xed\xfe\x41\x99\xab\x9c\x7f\x6e\x98\x08\x18\x38\xce\x86\xa5\x05\x51\xb6\x83\xeb\x01\xe2\xa0\xbf\x23\x11\x33\x35\x68\xd0\xb6\xdd\x16\x03\xd1\x20\xff\xd3\x42\x28\xb4\x7c\xb3\xa2\x28\x4f\x85\x82\xfd\x4f\x8b\xa6\xfb\xfc\x79\x85\x24\x81\xee\xa4\xe1\x60\xd9\xbc\x2f\xc4\x71\xd3\x23\xaa\xc7\xa3\x25\x4d\x2d\x3b\x62\x56\x64\xc8\xd1\x7d\x07\x8d\xc8\xf2\xeb\x37\x2e\x63\x86\xab\xb8\xb5\x21\x18\x10\xb6\xf1\xc0\x64\xe2\x4a\x13\xe3\xb6\x7d\xbf\x5e\x8c\x26\x95\x0e\x23\xd6\x11\x7d\x62\xe9\xb1\x9b\x89\x1a\x08\xe2\xb2\x4b\xed\x39\x18\xdb\xbf\xd9\x9e\x4f\xf1\x03\x2a\xf1\x66\xf9\xed\xfa\x72\x26\xa5\xe0\x38\x19\xa6\x1c\xe5\xfe\x30\x0d\x43\xeb\x1b\xd9\x57\xb7\x3d\x1d\x5b\xb3\x61\x77\xc6\xee\x1a\x5c\x23\x00\xeb\x7b\x59\x61\x1a\xf6\xad\xbb\xba\x31\x0c\x23\xd6\xbd\x99\x92\x7a\x53\x16\x04\xca\x38\xeb\xf2\xb8\x5e\x0c\x4a\x28\x94\x05\x69\x80\x14\xf5\xcb\xe5\xff\x51\x03\x06\x37\x77\x94\x84\x80\x96\x6c\xdb\x94\xed\x23\xf9\x66\xe2\x3e\x03\xc1\x88\x20\x58\xa8\xaf\x2c\x8f\x90\x43\x93\x7b\xca\x84\x0b\x9e\xee\x01\x7f\x77\x9f\x74\xa7\x8c\xe8\xd8\x32\x42\x64\x3f\x60\x97\xfd\xba\xda\xe3\x49\x59\x18\xa6\x54\xf7\xac\x64\x59\x59\xf4\xa4\x67\x94\xd1\x58\xf3\xc0\x37\x71\x9e\x8a\xa6\x83\xaa\x50\xc6\xe2\x34\x09\x7b\x4d\xc7\xab\x1b\x1c\x63\x42\xe9\xae\x27\x6c\x6d\x4c\x0d\xdd\x4b\x62\x32\xc0\x34\xea\xa9\xca\xf7\x48\xb6\xb1\x3f\x8a\x63\x37\x19\x18\x03\xe6\xd5\x5c\x1f\xb2\x69\x24\xc5\x78\x28\x2d\x14\xdf\x2a\x2d\x5d\xf0\xd1\xf9\x61\xc6\x8a\x1e\xfe\x3a\x8e\x84\xcb\x29\x8b\x68\x82\xf7\x65\xd1\x37\x0f\xa2\xd2\xca\xb3\x8f\x53\x16\x13\x4d\x5c\x54\x84\xb3\xfb\xaa\xfb\xcb\x92\x90\x5a\xdc\x87\xfb\xcd\x4d\x95\x1d\xa6\xf0\x67\xca\x12\x0a\xcc\xb6\x7e\xe7\x2f\x65\x0d\x45\xbb\x77\x59\x81\x87\xc9\x38\x43\xc0\x32\xa5\xab\x8f\x59\xd3\xc0\xa1\xbb\x9b\x94\xc4\x9a\x79\xee\xfc\x3c\xb7\x64\xbe\x36\xb8\x19\x6d\x42\x2c\x8d\x19\x56\x05\x9f\xa0\x28\xab\x72\x21\xea\xf7\xd1\x26\xcd\x52\xb0\x02\xa8\x0e\x39\xb3\x6d\xe0\x58\xcf\xcf\xc3\x74\xc7\x78\x99\x33\x11\x00\xa6\xf1\xc5\xf1\xf8\xd0\xe5\x97\x98\x70\x99\xa9\xbe\xc3\xe4\x92\x78\x96\x32\x01\x04\xd3\x21\xdf\x45\x9e\xdf\x65\x15\x0c\x18\xb9\x28\x93\xa1\xc2\x62\x6d\xc7\xb1\x32\xec\x4b\x19\x6e\xe1\x4c\x05\x02\x6c\x9a\xf2\x20\xb3\xde\x27\x98\xb0\xca\x51\xa6\x98\xc4\xa4\x97\x86\x63\x5e\xe2\x33\x0d\xc8\x6a\x28\x83\x20\x40\xbc\xc4\x62\xbd\x7a\xde\x6f\x5f\x37\x9b\xc7\x7f\x23\x93\xc0\xe6\x61\xb6\x5d\xee\x49\x37\x8c\x5b\x99\xdf\x26\x6b\x9a\xf3\x24\xb1\xc8\x80\xdb\x1a\xd6\x6e\xf5\xb4\x9c\x60\xac\x28\x03\x41\x70\x3e\xa2\xfc\x42\x5f\x2b\x60\x86\x00\xb6\x09\xff\xf3\xdb\xd5\x9c\xf7\x75\xd3\xcd\x4c\x6a\x13\x65\x7d\x9f\xea\x4a\xb9\x82\x3e\xe5\x41\x98\xe2\x4c\xd9\xfe\x6b\xd7\xfd\x29\x05\x4c\x25\xea\xb2\xf8\x80\x73\xbd\xcc\xb3\xb7\x4c\xe6\x70\x5f\x56\x83\xb5\xcc\x03\x88\x91\x31\x72\x50\xba\xf6\x5d\xb8\x2b\xe3\x1c\xa4\x0e\x07\xd9\x4c\x94\x0b\xdd\x35\x48\x68\xdb\x7c\x86\x94\x5e\x9e\x1c\x63\x32\x52\x0a\xab\x6b\x02\xea\xfd\x5b\xd9\x60\x6e\x73\x34\x45\x38\x51\x36\x4f\x8f\x8a\x29\x48\xe2\x34\x68\xc5\xa7\x3c\xe4\x1c\xa1\x3d\x52\xf6\xec\xee\x43\x32\xfb\x76\x84\x15\xea\x3c\x88\x5f\xcf\xa7\x83\xdc\x40\x65\xb9\xf2\xba\xe3\x91\x40\x6f\xb6\x39\x55\xc5\xda\x98\x6d\xd7\x94\x47\x39\x0d\xac\x61\xb7\xad\xb5\xcf\xf0\x0b\x79\xde\x56\x45\xd6\x88\xd6\x0f\x9b\x43\x73\xc1\x30\x4d\x39\xa5\x84\x26\xae\x02\x6e\xcb\xf7\xd7\x17\x0e\xa7\x71\x82\x21\xc8\x0e\xea\x66\xf4\xab\xa9\xc2\xa5\x7c\xc8\x8a\x36\x86\x29\x4f\xd5\x75\x15\x1d\xca\x59\x18\x62\x15\x64\x8f\x29\xb4\x57\xa7\xe4\xed\xaf\xc3\x12\x99\xb8\x00\xbb\x13\x4d\xa0\x9c\x49\x0a\x83\xcc\xf7\x56\x34\xf5\x10\xb1\xd5\x8d\xb2\xb4\x90\xe2\xa4\xb3\x66\xc4\x4e\x36\x86\x1b\x8f\x76\x94\xe9\xdd\x81\xc2\xb0\x49\xfa\x26\xea\x75\xf1\x7a\xb4\x19\xea\x6e\x13\xe3\x9c\x5a\x72\xc0\x53\x51\x1f\xa1\x68\x16\x15\xe8\xac\xa9\xfd\x8c\xf3\x96\x98\x73\x15\xa1\x23\x87\x65\xa7\x5d\x79\x4d\x95\x8f\xf2\xc8\x30\x24\xe0\xf8\x5a\x16\x4d\xde\xad\x84\x98\x08\x47\xc6\x06\xc5\x03\x54\x13\x9e\x30\xca\x63\xa5\xa9\x6d\x22\xf9\x21\xf4\x58\x4e\x88\xf2\x84\x89\xd0\x73\x76\x6e\x1b\xd1\xd4\x9f\x11\xd1\x50\x9e\x44\x51\xc2\x3b\xcd\x8f\x9b\x24\x16\x94\x27\xb1\xe5\x95\xb8\x5b\x7e\x5b\x3e\xae\x37\xcb\x97\x3d\xc2\x32\xfd\xcf\xa6\x84\x44\xf6\x23\x99\x2c\xbf\x04\xaf\x8e\x3e\x55\xca\xe2\x34\xbe\x00\xdd\xdb\xb2\xcf\xf8\xa3\xa6\x71\x8c\x8b\x6d\x23\x2a\xa1\x33\x07\x16\xda\x5e\x01\xd3\xfc\xed\x7f\xaf\x7a\xb7\x3c\x95\x3a\xb0\x7c\x2d\x19\xfa\x50\x57\x9a\x15\x28\x97\x04\xa4\xab\xe5\xac\x7f\x40\xd5\xe5\x08\x13\x7f\x5c\x27\x48\x56\xbf\x77\xec\x8a\xad\x63\xb3\x11\x55\x43\xae\x07\xe9\xbc\xf5\xf4\x87\x24\x7e\xeb\x6b\x88\x8a\xe9\x39\x61\xec\xe5\xff\x96\x07\xac\x92\x4f\x6e\x52\xa5\x91\x97\x3c\x6c\x57\x7f\xdf\xe6\xb2\x2a\x50\xc3\x7f\x3c\x1a\xb8\x76\xb1\x22\xe6\x87\x3d\x75\x97\x9f\x9f\x51\x60\xb8\xb0\xb1\xb1\x7d\xed\xa3\x8d\x37\x0a\x89\xc5\xdc\x68\x30\xe2\x94\x37\xbe\xda\x33\xd8\x27\xa2\x90\x09\xac\x77\xa3\x1d\xbc\x9f\xa8\xe4\xd2\x28\x8c\x02\x4c\x44\x37\xef\x59\xa5\xb1\xb8\x70\x2c\xb3\x62\xd8\x5b\xde\x8e\xd1\x26\x1e\x93\x3b\x7e\x1a\x2b\x46\xa1\x0c\x71\x2a\xce\x2e\xbb\xe8\x69\x44\x63\x88\xbc\x28\xf4\xa8\x6c\xdc\xa3\x81\x69\xc4\x62\x9a\x26\xae\xf8\xb5\x7b\xaf\xca\x9f\x2f\x60\xd5\xd9\xcb\x66\xc0\x97\x44\x23\xce\x35\xa2\x9a\xef\x45\xd1\x78\x36\x4a\x1a\xf1\x98\x60\x3a\x4e\x43\x83\x52\x3b\x60\xab\xaf\xcb\x69\x5d\x28\xe2\x0a\xac\x78\x13\x34\xdf\x5b\x1f\x13\x11\x7e\xe3\xea\x0f\x77\x43\x63\x20\xa2\x93\x41\x2f\xde\x9a\xf7\xb5\x79\x12\x4d\x8f\xab\xa3\x51\x6c\x28\xd6\x07\x95\x2f\x5b\x2f\x0b\xdd\xa5\x5e\xa2\x84\x4b\x5c\x72\xf2\x38\x74\x17\xa3\x44\x87\xbe\xa1\xa4\xc9\x8e\x79\x6b\x4b\x76\xe5\xcd\xec\x5d\x24\x48\x84\x09\x43\x07\x73\x5c\xd5\xf5\x09\x33\xfd\xbf\x59\x74\xfe\xec\x44\xa7\x7a\xc8\xc0\x53\x5e\x32\x48\xf8\xa1\x10\x60\x02\x55\x0f\xa2\xc6\x0e\xa3\xe1\x6f\x5e\x02\xc5\xf7\x8c\x3e\xa3\xca\xcb\x93\x1e\x3d\x9b\xd6\x01\xe6\x0f\x8f\x22\xd3\xf3\x4c\xf7\xb5\xd9\x76\x1a\x8e\xcc\x70\x04\x41\x84\x21\x0f\xb8\x19\xfc\x79\x3e\x20\x02\x22\xf0\xad\x6d\xaa\xf2\x50\x5a\xa5\xec\xac\x78\xca\x8a\x66\xcc\xa5\x40\x23\x70\x42\xee\x35\x34\xb3\x76\x5b\x6a\x9f\xf8\x0a\x56\x21\x02\xcd\x45\x34\xe0\x93\xf6\x82\x46\x57\x54\x5d\xda\xc1\x09\x66\x4e\x10\x3d\x3b\xa1\xa6\x75\x43\x4c\x12\x09\xcb\xa8\x7c\x10\x58\x59\xb8\x66\xcf\x22\x63\x84\x05\xc4\x15\x99\x25\x0b\x18\x1f\x8f\x03\x1a\x6a\xdb\x54\x6a\x7b\x64\xff\xf0\x7f\x4f\x42\x4f\xc9\xe3\x33\x56\xfa\xae\x54\x57\xee\x35\x26\xd2\x36\xb7\x6e\xa1\xb1\x32\x9b\x43\x50\x3b\x8d\x43\x66\x2c\x91\xfa\x98\xe7\xf6\x2a\xdd\x3c\x8d\xc3\x34\x46\xf0\x09\x26\x70\x87\x8d\x77\xed\x21\x4b\x64\xb5\x78\xdd\xee\xd6\x4f\x7b\x04\xc9\xef\x17\x2f\xcb\xd9\x6e\xb9\xdf\x2e\x5f\xbe\xad\x16\xcb\x61\x75\x22\xa6\xa1\x40\x5f\x7f\xbd\xdd\xc1\xa8\xab\x87\xc6\xd4\x04\x98\xf2\xdb\xd7\x98\x5d\xbb\xb0\xb0\x31\x4b\x8d\x77\x4a\x2d\xca\x10\x17\xda\x20\x76\x8f\x39\x81\xd4\x76\xaa\xea\x17\xd0\xf2\x94\xe7\xff\x6a\x1d\x97\xc9\x75\x38\x4b\x8c\x2d\xdd\x54\x19\xd4\x23\x6e\x5f\x1a\xf3\x38\xc2\x07\x3a\x15\x79\xbb\xcc\x27\x3e\x7b\xcc\xb5\x48\x68\xc7\xa7\x30\xab\x2e\x88\x23\xdc\xb8\xc8\x00\x6a\x5f\x38\x01\x53\x94\x59\xff\x7c\x87\x89\x63\x6a\x12\xdf\xe8\xb7\x13\xc7\x21\x4f\x2f\x8d\x13\x63\x91\xa2\xf7\xb3\xcd\x7d\x9f\x84\x0e\xfd\xe1\x34\x06\xed\xd5\x70\x8f\xc7\xf9\xf9\x4a\x51\x32\x16\x94\x4b\xd7\xe7\x60\x00\x5b\x4d\x46\xa5\xd4\x58\x30\xab\xcd\xe9\xbc\xbd\x75\x01\xaf\xaf\xab\xbb\xeb\x5b\x68\x2c\x39\x20\x3e\xd8\x8a\x78\xbb\x3f\x2a\x87\xd9\x7f\x5a\xec\x6e\x23\x2c\xc7\xd7\xd1\x61\x14\x5a\xca\xc1\xfa\x74\x03\x91\x3c\x4c\x41\xc4\x90\x32\x6c\x1e\x70\x69\x74\xbf\x5e\xc7\x1c\x56\x6e\xac\x21\x0c\xc1\x90\x56\x12\xe8\xb1\x9f\x69\x86\x58\x4f\xed\x5d\xd4\x2b\x27\xb4\x30\x9e\x22\x49\x10\x6b\x91\x74\xd8\xe0\x32\x53\x59\xe1\xf3\xa4\x76\xb5\x0d\xb7\x93\x24\x50\x14\xed\xab\x14\xea\xe3\x15\x59\x03\x87\x9b\x55\x12\x72\x8a\x09\xaa\xed\xee\xc5\xff\x89\xca\x0e\x74\xb3\x3d\x55\xc7\xdc\xf3\xb6\xd0\x84\x71\xf0\xfa\xbb\xad\xdb\xd0\xeb\xae\xd1\x84\xa9\x00\x59\x75\x85\x2d\x35\x51\xff\x77\xce\x15\x66\x17\x6c\xe8\xe1\xeb\x13\xb7\x84\xd8\x6e\xfd\xff\x29\x45\x24\x5e\x57\x53\x9f\xef\x43\xbf\xfc\xbe\xb4\x32\xe5\x57\xab\x5a\x09\x4f\x28\x6a\x84\xd5\xd9\x5f\xb0\x36\x1e\x75\xd3\x3d\x59\x14\x30\x64\x00\xc4\x8c\xd9\x64\x5d\x25\x51\xc4\x30\x12\xfa\xdf\x32\x2b\x16\xef\xa2\x28\x20\x9f\xfe\x8a\x67\xae\xa3\x49\x14\xa7\xb1\x9b\xed\x0f\x20\xf2\x11\x4b\x3b\x4d\x22\x4d\xb1\xf1\x6a\xdf\x40\x71\x2a\x4f\x43\x92\x36\x9a\xc4\x0e\xda\xef\xeb\xd3\xf5\xb6\x9c\xb0\x54\xd2\x24\x86\x98\x03\xd6\x7b\x2c\xe0\xc7\x12\x41\xb6\x5b\x88\xdd\x7d\xaf\xb2\x56\xba\x73\xd3\xc4\x46\x74\x4f\x65\x01\xe7\x9e\xe7\x99\x26\xa9\x08\x91\xad\xbc\x7d\xc0\x2f\x53\xdd\x29\x9a\x08\x6a\x60\x98\xd3\x1f\x65\x6d\xaf\x2e\xc1\x44\xa8\x94\x76\xe9\xe7\x6e\xb2\x49\x43\x11\x58\xb1\x79\x59\x3f\x2d\x77\x0f\xcb\xd7\xed\xde\x82\x5f\x57\x8b\x65\x3f\x46\x8a\xb0\x2b\x2e\xb4\xef\xba\x0d\xa2\x26\x77\xa4\xb8\x44\xf2\xb3\x4c\x95\x5e\xe8\xa9\x97\xb1\x7f\x84\x1f\x90\xfb\x2c\x47\xa2\x29\x4f\x1d\x1e\x65\x57\x36\x22\xdf\xbd\x43\x59\x41\x93\x29\x4f\x61\xd3\x0d\x14\x56\x3a\x1a\x86\x74\x87\x34\x01\x2e\x09\xf3\x28\xb5\xcb\x86\x26\x9a\x40\xaa\x31\x6f\xb4\x6d\xca\xe3\xfd\xa9\x06\xf1\x0c\xa8\x79\x7a\x25\xb7\x9d\x98\x38\xc6\xb4\xba\x05\xba\x6f\x41\x95\x9e\xd7\xa6\x1b\xa1\x2c\xb7\xe0\xdd\x6a\xbb\x40\x0d\x1b\x6c\xbf\xf7\x82\x36\x3b\x6f\x54\xd3\x80\x07\xe8\x64\x2e\xd6\x4f\x4f\xaf\xcf\xab\xdd\xbf\xad\xea\xef\xf2\x65\xbb\xdf\xee\x66\x5f\xfd\xeb\x4c\x09\xb5\xc9\xd5\xe7\xe5\x9f\x5d\x58\x96\x12\xad\xd1\x59\x78\x17\x85\xce\xe1\xf1\xa4\x3e\xce\x9e\xd6\x61\xf4\x19\x53\x62\x02\xf4\x45\x51\x4d\xb1\x01\x35\x5e\xb9\xce\xee\xa5\x21\x53\xa8\x3a\xb1\x03\x71\x78\x2c\xd5\x47\x56\xbc\x59\x22\xb8\xe8\xa9\x2c\x9a\x77\xff\x6c\x69\x18\xc5\xd8\x29\x9a\x99\x3b\xb0\x62\xf9\xa3\x37\x99\xb2\xd4\x8a\xa2\xd7\xd0\x3c\xdf\xef\x6e\xb8\xf5\x7e\xac\xb0\xd1\xe2\x41\x7c\xc0\xc3\x59\x56\x99\xce\xfe\x1a\xcb\x43\x8c\x9f\x84\x29\xc5\xae\x49\xce\xe5\xbf\xd9\xf9\x52\x0e\x56\x3c\xb9\x3e\x82\x72\xa4\x74\x3f\xa7\x4e\x48\xea\x99\x3d\x91\x1b\x0f\xf5\x2e\x5d\x3f\x97\x7f\xf4\x18\x98\xb6\xe1\x4a\x9e\x5f\x41\x60\xa4\xb1\x49\x91\x5a\xe9\xeb\xf3\xdd\xd0\x24\xa4\x09\x8f\x91\x1f\x61\xbb\x9b\x3d\x8f\x0f\xc4\x51\x1a\x0c\xc9\x02\xba\x03\x22\x12\x91\x47\x6f\x55\x17\x69\x9d\x34\x91\xb6\x49\x68\xbb\x78\x58\x3e\xcd\xf6\x0f\xb3\xed\x83\x3f\x35\x15\xdc\x6a\x15\x5b\x9b\x35\xd3\x97\xc2\x24\xe3\x6b\xa5\x40\x4c\xd8\x6b\x17\x94\x96\x45\x63\x51\x1e\x8e\xa2\x38\x5f\x13\x15\xbc\xfc\x2e\xa9\x49\xe2\x9e\x99\xf0\x3e\xcf\x8e\xb3\x42\x3f\xdd\xed\x6e\xf5\xec\x4e\x4e\x17\x21\x67\x1d\xea\xf2\x39\x7b\x7b\x6f\xba\xd9\x26\x64\x18\xd8\xf6\x80\x26\x33\x67\x0f\x30\xbd\xce\x34\x43\x53\x01\x10\x44\xfd\xde\xfd\xf7\x52\x97\xa9\x8c\x34\xce\xd8\x7f\xbd\xae\x9e\x3f\xa1\xb4\x9d\x9e\x25\x3b\xc7\x7e\x51\x76\x30\x7c\xcb\x78\xe7\xef\x5e\x05\xa1\x6c\xf7\xe5\xf5\x66\x3b\xfa\xee\x9a\xd2\x54\x0e\x58\xf2\xc4\x1b\xcc\xcf\x03\x37\x33\xd5\x82\x60\xe1\x6f\x7b\x2c\xab\x66\xdb\x88\xea\x49\xf4\xac\xde\xed\x61\xcb\x2f\x8b\xe0\x1a\x54\xe3\xbf\x07\xb8\x83\xa2\x44\xf5\xd7\xae\x4a\x94\x42\x9c\xa0\xc3\xf7\x65\x39\x5f\x2e\xba\x3f\x26\x14\xeb\x08\x6f\x27\x51\x69\xd0\xb3\xaa\x12\xe7\x17\x5b\x10\xf9\x63\xb0\x45\x0f\x37\xea\xd4\x84\x96\x10\x69\x0e\x4e\x2e\xa2\x75\xc3\x43\xef\x1f\xa4\x26\xb4\xbd\x23\x36\x8e\xaf\xa1\xa8\x4f\x1e\x3e\x33\x99\xb8\x46\x19\xcc\xb0\x5d\xa3\x14\xa2\xa9\xd1\x51\x62\x46\x94\x5c\xae\xa7\x0b\xbb\xb9\x47\x57\x12\x41\xa2\xd3\xb8\x6f\x44\x84\xd5\x62\x2d\x7e\x88\x2c\xcf\xba\x96\x14\x2a\x88\x24\x48\x2d\xe1\xfa\x09\x11\xff\xe5\xef\xab\x1b\x62\x39\x33\xee\x44\xd1\xb3\xc0\x52\x41\x54\xe8\xfb\x6e\x37\x65\xf1\xf6\x43\xe4\x7f\xf4\xb6\x52\x10\xb0\xe8\x9a\xf2\x08\xc5\x23\x08\x0d\x95\x2c\x45\xa5\x5d\xe1\x71\xe8\xb9\x89\x90\x09\xea\x5d\x9c\xd9\xec\xa2\x19\x60\xf4\xfc\x22\x8c\x43\x2c\x1e\x3f\xc2\x96\x0e\xef\x86\x12\x16\xd1\x81\x5a\xf2\x23\x56\x52\xba\xa4\x86\xa0\x94\xa2\x70\xe2\xfc\x74\x32\x87\x11\xa7\x29\x15\x34\xd2\x68\x94\x0e\x99\x2b\xd7\x7e\x1e\x01\x0b\x1a\xab\xc0\xb1\x6c\xbc\x3c\xef\xe6\xd7\xc4\xc6\xa7\x67\x08\x1d\x77\x62\xb6\x2f\xe5\x24\x83\xe7\xdf\x19\x0f\x62\x04\xed\x43\xa1\x47\xb2\x17\x93\x8b\xf1\x30\x42\xbf\x15\x7e\x1d\x45\xa1\xff\xf4\x4f\xc1\x13\x8e\xac\x67\x7f\x41\x55\xce\xcb\xd2\x17\xe8\x45\x24\x13\xdb\xa1\x68\xa7\xcb\x1c\x0a\x30\x99\xca\x44\x75\xee\xb3\xcc\x22\x89\x2d\x27\xac\x25\x3c\xb3\x22\x46\x97\xa1\xba\x48\x40\x23\xf8\xfb\xb1\x54\x19\x86\xc5\x1d\xf0\x42\xa4\x01\x70\xf0\x34\xfa\x56\x74\x67\x87\x53\x0a\x25\xd3\x1d\x2c\xf6\x69\xf1\xfd\x2a\xf9\x11\x15\xa9\x20\x58\xcb\xd9\x3e\x7b\x88\x85\x10\x91\x20\xf1\x28\x2c\x99\x15\xbe\xc2\xff\x69\xcf\x18\x15\x22\x06\x12\xfa\x16\xaf\x32\xcf\xa1\xba\x83\x1c\xde\xfa\xd4\x9c\x90\x82\x20\x19\x5c\xb6\x10\xa3\xa4\x90\x90\x20\x98\x67\xb2\xc3\x0a\xed\x57\x38\xdf\x30\xa6\x42\x51\xe3\x8b\x78\x9b\xf5\xfa\x71\x0f\x3a\x6b\xf6\xbe\x5d\x9e\x0a\xc5\x64\xe0\x58\xd1\xff\x75\xca\xd4\x07\xee\x1d\x96\x20\x72\x72\x9d\x54\x60\x2e\x67\xa1\x3c\x60\xfb\xaa\x91\xbd\xb2\x76\xb4\x8e\x51\x65\x0f\xb3\x02\x57\xc3\xbc\xe4\xd2\x56\x09\x0d\x12\xc1\x80\xeb\x02\xda\x0f\x7e\xa5\xc5\x69\xfc\x3a\x81\xd9\xc0\xe0\x0d\x9a\x47\x51\x5b\x11\xdc\x61\xe1\xda\x0f\x13\x51\x6a\x29\x72\x9f\xe1\x57\x33\x3f\x69\xfb\x0e\x8b\xa7\x4e\xf5\x93\x0a\xd0\x61\x98\x38\x07\xa1\xdf\x06\x04\x68\x85\x55\x2c\xc4\x0f\x0c\xf3\xf0\x43\x6c\xf3\x8d\xe5\x68\xa4\x40\x89\x8f\x47\x4b\x41\x66\xff\x2a\x03\x21\x01\xf9\x11\xde\xcb\x9f\x08\x51\xbd\xbc\x61\x19\x48\xab\x82\x85\x18\xee\x3c\xaf\x0f\xb8\x85\xbc\xc0\x7f\xbb\x8b\x68\xe9\x84\x8b\xed\xec\xd9\x87\x17\x3c\x92\xff\xf9\x9f\x7f\xf4\x30\xec\x31\x59\x3f\x95\x84\x50\xec\x0f\xb1\x7e\xf0\x9d\x68\xc0\x4f\x0e\x49\x88\x94\xa4\xeb\x8d\x38\x42\xd5\x9c\xdb\x77\xeb\x2a\x2e\xa7\x5e\x44\xa1\x1d\xaa\xb1\x04\x6c\xdd\x8f\x5f\x13\x77\x52\x92\x38\xc6\x84\x9c\x73\x20\xef\xa0\x13\x96\x1a\xf3\x29\x0e\x27\x8e\x24\x60\xd1\xd1\x7e\x6f\x16\x45\x33\xc8\x43\x48\x62\x12\x6c\xeb\xc9\x45\x6d\x37\x18\x7b\x5f\xdd\x7a\xf6\xe3\x42\xc9\x12\x97\x91\x6f\x7f\x63\x57\x3a\x08\xe6\x93\x38\x4e\xee\x92\x46\xcc\xeb\x80\xcd\xda\x4d\xa8\x0d\x3e\x6c\x8f\xfa\x10\x64\x21\x69\x2c\xad\x1b\xfa\xdf\xaa\x19\xa5\xcb\x24\x15\x26\x71\x56\xd7\x02\x9a\xaf\x47\x7f\x92\xca\x38\x18\x91\xf5\xbe\x16\x8d\xf8\x05\xfa\x53\x19\x27\x2a\xa9\x8a\x63\xd2\x37\xf4\x6f\xdf\xab\xac\x7f\x4c\xc6\x14\x3a\x93\xa2\x6e\x03\xbd\x67\xf8\xb9\x11\x95\x82\xdc\x0b\xef\x4c\x5c\xb7\xd1\x8b\x66\x29\xf5\xa8\xca\x36\x6c\xbf\xcf\x44\xa7\x68\x36\x1a\xc7\x85\xc0\x8f\xbc\xdd\xcd\x7c\x05\x58\x72\x19\xf2\x8e\xb1\xe5\x41\xd4\xed\x8d\xed\x46\xf4\x28\xe3\x47\x8f\x42\x0b\xe8\x3f\x88\xac\x18\x15\x55\x65\xa4\x00\xa9\x77\xe4\xe9\xdc\x06\x92\xd9\x31\x87\x55\x03\xd7\x2d\xc6\xc5\x0a\x93\x91\x51\x58\x99\xb4\x0d\x8c\xaf\x1d\xe8\x53\xc6\x84\xab\x81\x97\x36\xc4\x6b\xf5\xeb\xe2\x72\x01\xfb\xb3\x25\x61\x1e\x4c\x59\x01\xfc\x85\xee\xdd\x64\x08\x28\x2c\xf6\x61\xfa\x68\x6d\x46\xf5\x19\x19\x1b\x95\x44\x5e\xa6\xde\x16\x9b\xf7\xef\x38\x35\xbc\x73\x2c\x93\x20\xc5\x64\x64\x2d\x72\xe8\xe9\xba\xa9\x4c\xe2\x50\x0f\xab\x4f\xf7\x55\x79\xf8\x3c\x08\x90\x89\x01\xa4\x8a\xa9\x85\x81\xa7\x53\xbe\xd7\xa0\xae\x6f\x0b\x32\x4d\x4c\x1a\x4e\xb7\x05\x8f\x90\x97\x82\x32\x04\x2f\x35\xfb\xa7\x4c\xbd\x8b\xac\x7b\x99\x82\x45\xb1\xcd\x38\x77\x46\xd6\x1f\x92\xc4\x66\x5d\x8f\x15\x1c\x45\x05\xbb\x72\xab\xca\x0a\xc6\x6f\x43\x26\x41\x18\x8e\x74\x6c\x5e\x44\xd3\x3a\xcd\x58\x35\xec\x2b\x07\x52\x26\xb6\x9a\xe2\x9f\xbd\x3d\x76\x1d\xc7\x30\x7e\x2c\x29\x18\x8a\x8f\xf9\x52\x54\x26\x6d\xf4\xfb\xbb\x49\x34\xb9\x8c\x0a\x53\xc4\x90\xd4\xe7\xba\x81\xc3\x12\xc3\xf1\x61\xc9\x4b\x2a\x21\xc0\xc9\x39\x6f\xca\x7a\x9c\xe6\x93\x9a\x69\x7c\x49\xa5\x45\x28\x0f\xdb\xcd\xa4\x4e\xad\x3e\xfe\xbe\x5d\xfa\x23\xd8\x81\xd4\x22\x40\xef\xfc\xe9\x6c\xdf\x8d\xd7\xee\xa1\x12\x18\xb7\xed\x15\xa2\x51\xef\xd8\x8e\x5a\xff\x71\xb1\x63\x4a\x30\x5c\x3b\x41\xb9\x0a\xbe\x43\x6e\x86\xc8\xc4\xd1\x0d\x9a\x80\x61\xf1\xc6\x88\xba\x59\xf6\x5f\xd0\x84\xa9\x05\xa1\xbc\x81\x23\xfb\xae\x37\xa2\x6a\x9c\x4e\x53\x37\x5f\x8d\x8a\xe3\x5e\xc5\x09\xe7\xc0\x1d\xe4\x62\xd2\x52\xa8\x82\xc4\xd6\x1e\xb3\x22\x6b\x9e\xb2\x62\x48\x8f\x41\x15\x09\x38\x66\x96\x20\xcf\x30\xd8\x81\xd1\xe4\x1e\x5f\x88\x84\x34\xf2\xbd\x89\xa8\x91\x38\x95\x91\xbe\xee\x60\xa9\x90\x45\x56\xa3\xac\xdf\xac\x26\x57\x0e\x25\xc3\xbd\xd5\x60\x55\x68\xf3\xb2\xec\x41\x66\x2a\xd4\xc0\xb9\x95\x54\xac\xba\xb2\xe6\x42\xd4\x59\xe1\x51\x00\x8a\x86\x1a\x9d\x5c\x55\x37\xbb\xf2\x29\x53\x55\x7f\x44\x5b\x36\xba\x67\xf8\x69\xd9\x35\x26\xef\x86\x25\x8c\x58\x66\x80\xb7\xb7\x1c\x2c\xc4\x62\x7e\x3a\xf7\xce\x86\x62\x29\x4b\x1c\x08\xed\xae\x2c\x2e\xe4\xb7\xa8\xe2\x22\x48\xfa\x64\xee\xa2\xac\x27\x31\x9a\xe2\x8a\x73\x2f\x3e\x78\x10\x6f\xb0\xa9\xb2\x1f\xd3\x21\x90\x62\x71\xf7\x70\xca\x43\xac\xa2\x4e\x8e\x47\x34\xf5\xfb\x82\x14\xea\x46\xcf\x95\x8a\x52\xcb\x25\xe0\xd5\x7e\x3c\x57\x9d\x3f\x2c\x15\x4d\x07\xdb\xef\xa4\x48\xa8\x22\x65\xb5\x09\x05\x02\x7d\xd1\x3e\x3b\x03\x89\x31\xed\xe4\x96\x62\x4a\x0c\x12\x41\xd7\x0b\x51\xf4\xe2\x46\x54\xc5\xa9\xc0\xf4\xd8\xa2\xcc\x8a\xfb\x53\x97\xc4\x53\x09\x0f\x5c\x37\xbe\xad\x69\x7e\x19\xfc\x74\x12\x05\x98\xbd\x5f\x3d\xef\x5e\x96\x9b\xd5\xdd\x7e\xfb\xb0\xda\x8c\x52\xa0\x2a\x49\x45\x10\x0c\xa0\x2d\x9d\x2e\xb3\x77\xa3\x92\x11\xf8\x5e\xa5\x8c\x22\xb5\xe8\x10\x59\x3b\xce\x3b\xab\x34\xb5\xe0\x21\xd4\xcb\x52\xcd\x3f\x4b\x39\x9a\xc8\xde\x58\x2a\xa1\x35\x82\x88\x0e\x03\xb8\xb2\x3f\x64\x14\x42\x27\x7f\x94\x0d\x3c\x97\x6d\x1c\xd9\x2e\x8a\x43\x56\xcc\x5b\x0b\x71\xb9\xbd\x5d\x76\xdf\xa9\x76\x67\x73\xb0\x5b\x93\x9f\xa0\x50\x30\xcb\xdf\xca\x2a\x6b\xde\x0f\xd7\x90\xb7\x4a\x0a\x8e\x64\x1b\x12\xa3\xef\xaa\x7c\xab\xc4\x61\x58\xc0\x56\x8a\x44\x28\xa7\x2e\x51\x01\xc2\xe2\x5c\x27\x85\x9a\xf1\x43\x28\xca\xb0\x34\xb4\xaf\xa1\x79\x39\x15\x60\x5b\x79\x09\x99\x7c\x71\x15\x73\x91\x0c\xda\xd1\x06\x6b\x54\xc5\xb6\x61\xe4\x54\x43\xb5\xd2\x03\xa5\x00\xaa\x54\x2a\x30\x27\x87\xda\x7b\x1d\xea\xec\xf3\x18\x42\x69\x1e\xa4\xc3\x7e\xa6\x5d\xe9\x8b\x13\x93\xf7\xaf\x63\x85\x74\xe4\x4f\xa5\x06\xbf\x37\x2a\xad\x13\x2c\x67\xe7\xe5\xdb\xa8\x01\xc2\x1d\x06\xe9\xe8\x68\x7d\x04\xef\xc8\x42\xae\x1a\x3d\x1d\x44\x01\x71\x25\x5c\xe7\xae\xae\x74\x6b\xfc\x2e\x26\xe0\xf0\x37\x34\x89\x05\x73\x4f\x5d\xcd\x5f\xfe\xdc\x78\xb5\x51\xaa\x89\x90\x56\x08\xc8\xd5\x44\x9d\x87\x59\x3d\x0e\x24\xe9\xa9\x26\x32\xc1\x80\x04\xf3\x43\x8e\x2b\xdb\x1f\x52\x29\x87\xce\xc1\xb7\xc5\xb4\x2b\xad\x50\x9a\x18\xb0\x04\x51\x61\xf8\xc7\xb0\x3f\x56\x87\xcc\x60\x6f\xc9\x63\xf9\x66\x9f\x7c\xd9\x4c\xcc\xa2\x0e\xa3\xd4\x4a\x66\x69\x8d\xd5\x78\x57\x58\x99\x6c\x62\x93\x37\x15\xc6\x56\xd7\x0b\x7d\xe7\xc7\xac\x0b\x9f\x75\x28\x29\xb6\x46\x3c\x88\x72\x50\x60\xd1\x34\xd4\x91\x18\x74\xcf\x69\x24\x90\xeb\x8e\x32\x93\x38\x07\x02\x21\x6a\xb3\xa2\xfe\x09\xd5\x68\x7f\xd7\x8c\x69\xdc\xa8\x1d\x70\x19\xf4\xa0\x49\x67\x34\x4f\x34\xa7\x14\x7b\x69\x97\xf3\xc5\x7c\x18\xc1\x6b\x2e\xa2\xc4\x4b\x3f\x1c\x85\x82\xfa\x3d\x3b\xbe\x1e\xdf\x2a\xa1\x61\x18\x6a\xe8\x28\x4a\xb5\xec\xe8\xb6\x5c\x49\x09\xd5\xf7\x26\xb1\x81\x8e\x64\x80\x29\x56\xeb\xfe\x83\xb6\xf5\x11\xe4\xb4\xc7\x0d\x7c\xe8\x85\xe8\x48\xa5\xa1\xe9\xbd\x5a\x4b\x8c\xbd\x11\x95\x38\x4c\xc2\x7e\x1d\x13\x69\x91\x8e\x4d\xe5\xa4\x87\xf3\x7c\x2e\x7a\x01\x98\xc9\xc7\x88\xa9\x12\x1d\x4b\x5f\xe6\x28\xfa\x0e\xc7\xe6\xfc\x5c\x36\xeb\xa2\xfb\x34\xb1\x12\x36\x11\x69\x5d\x83\xd1\xab\x89\xc1\x36\x6b\x60\x61\xb3\xc1\x8d\xcd\x1d\x49\x82\x44\xbb\x50\x18\xa1\x35\x43\x6c\x97\x4e\x02\x8d\xf4\x1a\x2b\x33\x84\xab\x4d\x6b\xfa\x3a\x89\x42\xd0\x23\x02\x01\xbb\x02\x2c\x66\xe7\xba\xa5\xd2\x49\x62\x75\xd1\x8f\x15\xac\x94\xed\x54\x19\xd5\xab\x74\x0a\xc2\x33\x93\x61\xff\x09\xfa\x8a\x0b\x51\xe8\xc9\xf6\xa5\x45\xaa\xb0\x6a\x8b\x08\x9e\x76\xfb\xb2\x6c\xfb\xfe\x3a\x92\x02\x82\xde\xf7\x98\x84\x9b\x55\x20\xb0\x4d\xa4\x81\xb7\x81\x88\xf4\x75\x9f\x55\x4b\x93\x5c\x20\x72\x16\xe5\xe1\x98\x43\xbf\x24\x14\xb1\x95\x57\x23\xb2\x7c\x2b\x0c\x3c\x66\x87\xac\xe9\x0f\x5a\xca\x86\x99\x9e\x0d\x94\x23\xa9\x56\x21\xc1\x64\x6f\xaf\x4b\xf7\x99\x8c\x7b\x7f\x43\x8a\x52\x99\x76\x84\x27\x51\x77\x39\x6a\x30\xcf\x68\x9f\xf1\x4b\x95\xfd\x86\xf3\x41\x2b\x16\xa2\x33\x85\x38\x4d\xf2\x09\x97\x2c\xd5\x4a\x30\xbc\xd5\xed\x49\xb6\x0f\x36\x2a\x59\xbb\x42\x19\xe9\x2e\xab\x24\xf6\x58\x3d\x96\x6f\xf7\x65\x9e\xf7\xce\xcf\x8d\xc7\xd1\x01\x55\x2e\xe9\xf6\xf8\xf8\xcd\x06\x4c\x5d\xee\x5c\x6b\x1e\x52\x2b\x75\xe3\x37\x8f\x27\xe8\xe0\x34\x83\x8b\xc4\x69\xec\xd6\xf3\x72\xbb\xde\xdc\x98\x6f\x5a\x0b\x2c\x38\xd4\x28\xf8\x6e\xc5\x9a\xef\xc4\xf1\x38\x11\x5a\xa4\x1a\x48\x8a\x1b\x60\xeb\x67\x8e\xb8\xf4\x06\x58\x39\x0d\x51\x84\x3d\x33\x70\xc8\x9a\xbf\xa5\x8e\x47\x35\xb4\x3e\xbe\xbd\xcd\x07\xc8\x26\xbb\x9f\x36\xa9\x46\x1f\xcc\xc9\x78\x4d\x1e\xd1\x80\xcd\xe8\xb7\x3f\xe7\xa7\xee\xf2\x87\xc8\x4f\xa2\xb9\xa2\xae\x7f\xba\x80\xfc\x76\x57\x02\xa2\x29\x77\x09\x81\xaf\x70\x7e\xad\xc1\x3b\x52\xd3\x61\x09\x72\x24\xb4\x93\xda\xc2\x7c\x30\xfd\xe3\x56\xb4\x1f\x64\x6c\x0d\xc5\xd5\x56\x2f\xfb\x36\xae\x7e\x09\x08\xb9\x71\x30\x80\x42\x3b\x22\x91\x4f\x9b\xe7\x51\xda\xb2\x9d\x25\xad\x53\x8e\x89\x42\x7f\x03\x34\xb6\xd1\xd9\xde\x09\x8f\x8c\xa1\x8d\x9f\xae\x00\xa0\x3a\xc6\x86\x69\x0f\xdc\x70\xc9\xb3\x1f\x98\x2f\xac\x0e\x63\x9c\xc1\xb8\xda\x35\xfe\x07\xe7\x4f\x18\xf8\xcb\x1a\xa9\x07\xe2\x80\x3d\xf9\x8c\x3b\xce\x48\x6c\xe1\xaf\x50\x0f\x76\x9f\xb5\xb9\x03\xcb\x57\xe1\x1f\x8d\x31\x2b\x21\x74\xb7\x19\x1a\x72\x60\xed\xee\x35\xcc\x52\x6f\xca\xaa\x31\x65\x9e\xf9\x30\x09\x38\x95\xa1\x43\xdf\x6d\xb3\xf6\x06\x1d\x58\xee\x53\xf4\x28\xf0\xd4\xc2\x75\xda\xc0\xd2\x66\x90\x2e\x2d\xd1\x8d\x33\xb5\x55\x4e\xd1\xa0\x72\x51\x39\xd4\xe7\x95\x25\x03\x1c\x12\xcc\x53\xf4\xd5\x96\xcf\xc1\x31\xfe\x34\x43\x50\x56\xea\xbd\x3c\xf9\x2c\x0e\xc4\x69\x02\xde\xdb\x77\x62\xe2\x2b\xfd\x3d\x6b\xde\x31\x95\x39\xb4\x5e\x10\x8b\x34\x70\xb9\xa6\x95\x2a\xa7\x2a\xbd\x14\x62\x9d\x22\x30\xcb\xa2\xb2\xbd\x08\xc8\x2d\x62\xaa\xd1\xa5\x13\x05\x98\x1c\x84\x42\x95\x1a\x56\x66\x99\xd7\xbf\x41\x5c\x41\xca\x63\xcc\x72\xf6\x7c\xf2\x98\xcf\x19\x3f\x71\x1a\xd1\xb8\x13\x89\x32\xcd\x42\x1c\x57\xc5\xe2\x42\x33\x81\x42\xaa\x6c\x97\x6d\x0d\x9e\x17\xe7\x33\x9f\x0e\x84\x62\x72\x88\xbe\x19\xb5\x79\x4c\x5e\xba\x0c\x48\xea\x95\x73\xad\xcd\xed\xa8\xed\x6f\xac\x51\x49\x13\x64\x03\xf3\x9d\x7b\x0b\x71\xb4\x35\xa5\xe9\x0b\x97\x49\xe4\x52\xe3\xc8\x85\x0c\xda\x2b\x94\x3b\x32\x80\x27\xf1\xbf\x5d\x95\x16\x14\x4f\xe9\x50\x03\xcf\x46\x40\xe2\x36\x31\x2c\x05\x95\x18\xac\x28\x60\xe6\xd0\x0a\xeb\x0d\x5a\x93\x41\xc9\xc8\x4b\x45\xf9\xb6\xf9\xbb\x0b\x32\x1e\x50\x8a\x21\x94\x14\xcb\x2b\xd6\xeb\xdb\x76\x49\x55\x50\x86\xa0\x5b\xf8\xd4\x06\x41\xc5\xd7\x51\x9b\x2d\xe8\x40\x84\x30\x88\x77\xbe\x97\xd5\xc7\xe0\x3d\x4f\xb7\xcf\xf1\xef\x6a\x16\x47\xd6\x2d\x00\x51\x9f\xaa\xf3\xb6\x2f\xc7\x82\x36\x32\x49\xbb\x26\x39\xec\x9f\x79\x87\x62\x23\x4e\x17\x7e\x2b\x98\x10\xb0\xc8\x55\x37\xe5\x71\x83\xfe\xd5\x53\xd6\x5f\xc8\x84\xe0\xe9\x66\xe7\xb3\xd5\xc5\x5c\x1f\x5f\x29\x0a\x98\xe9\x18\x0e\x10\x2f\xfb\x5c\x5e\x8a\xb3\x8f\xbf\x81\x09\x42\x83\xbf\x80\xa8\xec\x61\x7b\xb2\x09\x64\x28\xa3\xae\xfa\x61\xb2\xfc\x7a\x36\xcd\x10\x06\x49\xe4\x31\xc4\xcd\x2d\xe7\xc8\x0f\xd6\x12\x91\x4d\x6d\xac\x9e\xe9\x1e\x28\xe5\x7f\x34\x54\xd2\x66\x70\x2d\x67\xf5\x17\xcf\x04\x4d\x0d\x15\x1a\x2b\x75\x1b\x51\x1d\x50\x9b\x7b\xf8\x29\x0d\x53\x16\x8f\xbd\x78\x87\xaa\xea\x2c\xac\xe1\x2a\xf2\x7a\x52\x7b\x2d\x1a\xb1\xc7\xa9\x76\x61\x2e\x47\xcf\x13\x11\x86\x3b\xd5\x2e\x2b\xce\x96\x2b\xf1\xb1\x2c\x3f\x4e\xbe\xd0\x60\x22\x66\x3b\xe9\x6b\x68\x90\x74\xd9\xde\x47\x6f\x3d\x4d\xc4\x6c\xce\xdc\xed\x2b\x96\x22\xf8\x86\xb1\xb9\x56\x3b\xf3\x97\x49\xb8\xa7\xb2\x7c\x2d\x2c\xf5\xa0\x7e\x10\xf9\x8f\xac\x78\xdb\x9e\x64\x9d\x4d\x9d\x6b\x13\x81\x25\x70\xf3\xec\x8c\x37\xdc\x8d\x9b\x26\xcf\xc4\x5a\x21\xaf\xd5\xbb\xa8\x5f\x10\x0f\x80\xd4\x13\x57\xd7\xae\x49\x82\x48\x76\x75\x8f\x99\xfe\x91\xd5\x65\x75\xb6\xb6\xad\x17\xb5\x6d\x87\xa5\xae\x57\xd7\x46\x9b\x33\xed\x39\x4d\xb6\xea\x1d\x0e\xe2\xa6\xd6\x0e\x35\x69\x10\x23\x56\xf7\x69\xf6\x27\x32\x03\x2f\x77\x0f\xcb\x97\xfd\x76\xb3\x7c\xf6\xcd\x7f\x26\xa5\x09\x58\xb8\xbf\xf7\x63\x1e\x07\xe2\x9c\x93\xa9\x27\x68\x6c\xdb\xb2\x4f\xf5\x11\x0a\x0d\xfa\xb5\x68\xba\xcc\xbe\x11\x2c\x75\x12\xb8\xcd\x7d\x6e\x35\xc9\xc6\x0f\xac\xb4\xf4\x64\x52\x4e\x6c\xac\x8d\x7b\xbb\xe9\xa9\x03\x12\x5b\xea\x7f\x24\xd2\x71\x4d\x57\x93\x6b\x68\xc6\x31\x07\xb0\x7e\xf2\xf5\x23\x03\x41\x8c\x28\xcc\xb9\x28\x54\x59\xfd\x6b\x20\xbb\xdf\xaf\x44\x20\x5a\x0c\x19\x89\xdb\xed\x73\xb9\x7b\x18\xef\x45\x06\xb8\xc4\xec\xcd\xbb\xa8\xf4\x42\x1c\x5d\x43\xe1\x97\x52\xe4\x7e\x4f\xf2\x03\x23\x82\x8d\xf6\xc7\x53\xfd\x8e\x32\x66\x55\x3d\x6d\xa4\x30\xa0\x03\xe4\x08\x7a\x17\xf5\xb2\x28\x4f\x6f\xef\x03\xc3\x6c\x4c\x28\x8c\xdb\xa8\x67\x4d\x73\x89\x63\xfa\xff\xfa\x5f\xff\xb3\x4a\xe1\xab\xda\x40\xbb\x1f\x0d\x5a\xa2\x59\x10\x48\x8e\x2d\xd1\x7b\x04\x22\xdc\x9c\xf6\xd3\xa2\x01\x0b\x88\x96\xc4\x13\x8c\x79\xda\x8d\x6b\x13\x9e\x05\x21\x21\x88\xfc\xd8\xd7\xd0\xac\xab\xec\x2d\x2b\xba\x5e\x8d\xc9\x40\x9e\x62\xea\x7a\xfe\x3c\x84\x4b\xb1\x20\x8c\xa4\x91\x3e\x7c\xaf\x3e\xda\xab\x20\xe5\xd3\x69\x92\xba\x66\x41\x28\xac\xd0\xe9\xbf\x4f\x3a\xfb\xab\xcf\xdd\xb0\x80\x86\x49\x14\x79\x8c\xca\x12\xe1\x61\xad\xbb\xe8\x38\xf5\xc4\x4d\x74\x0b\x0b\x68\x42\x69\xef\x42\xa3\xf3\x3d\x2b\xf4\x10\x6c\x75\xed\x9d\xb7\xe7\xe9\x10\x06\x53\x6f\x56\x1d\xce\x93\xbb\x65\x51\x90\x98\x4e\xc6\xd3\x27\x82\x06\x26\x95\x05\x9c\xc7\x32\x71\xb2\x2f\x16\xd7\x53\x7f\xc2\x18\xcf\x02\x2e\x1d\x70\xec\x67\x56\xd7\xf3\x6c\xfa\x7e\xb8\x0e\x28\x74\xa2\x8a\xf6\x7a\x53\x1a\x82\xe9\x15\x81\xa2\xd6\xa8\xeb\x9d\xde\xd7\x83\xfc\x05\x0b\x22\x16\x11\xd7\x38\xf7\x54\x8e\xbb\x65\x59\x10\x29\xf0\x39\xa8\x8d\x50\x1f\xe2\x0d\xac\x3b\x36\xd9\x8c\xfd\x68\x88\xc2\xa8\x17\x02\x1f\x74\xb4\xfd\xbf\x9a\xf5\xed\x05\x53\xec\xc2\x38\xe6\xe2\x6c\x65\x9d\x26\xf7\x17\x07\x1c\x93\x96\x5e\x8a\xa9\xb5\x0e\xed\xac\xfc\x6c\xdf\x6f\xcf\x32\x78\xd6\xde\xde\xe8\x1f\x97\x01\x69\xe2\x46\x26\x51\x60\xdc\x7e\xf7\x20\xea\x45\x79\x70\x02\x1c\x50\x0d\x7b\x7b\x9c\xd9\x66\x41\x12\x5b\xfa\x89\x1f\x36\x62\x82\x5e\xc7\xf1\x4b\x55\x9e\x8e\x53\x53\xc3\x82\x34\x22\xba\x43\x81\x94\x65\x7e\xd9\xd3\xcc\x82\x54\x1b\xac\x97\xb5\xcf\x87\xa5\x18\xf7\x77\xa1\x13\x74\x94\x91\x8b\x64\x56\x77\xe9\xea\x4f\x82\x40\x77\xa6\xd4\x29\xc6\x25\x77\xaa\xac\x8e\x08\xd9\xb0\xac\x48\x17\x7b\xa6\x1b\xaf\xc2\x18\x01\x65\x4d\xe9\x09\x35\x6f\xcc\x34\x65\x08\x7e\x2f\x5b\x1e\xc4\x87\x71\xac\xed\xe3\x57\x3c\xe5\x08\x1b\xff\x9c\x36\x3a\x02\xe7\x16\x2e\x8b\xaa\xcc\xf3\x43\xe7\x5f\xb2\x00\x82\x18\xbd\xa8\xec\x70\xcc\x2d\x0f\x0b\x7b\x01\x0d\x70\xbd\x84\xd8\x8e\xb7\x81\xe6\x3f\xb3\xe2\xeb\x49\x14\x6f\x8f\x99\xe8\x6c\x0a\x38\x69\x51\x9f\xde\xfa\x96\x89\xdf\x77\xe1\x30\x12\x24\x0c\x71\x0c\x3f\xca\xeb\x04\x6c\x8c\x10\x25\xac\xac\x64\x23\xaa\x66\x53\x65\x3f\x44\x83\xc2\x17\x77\x1d\xc4\x8b\x11\x02\x11\x2e\xf4\xe7\xb2\x58\xe2\xb4\xfa\x01\x57\x95\x8a\x4e\x03\x58\xd5\xb5\x90\x89\x91\x50\x6a\x34\x31\xd3\x0e\x39\x77\x98\x52\x1b\xcb\xef\xa0\x6e\x96\xbb\xc5\xc0\xa8\x12\x46\x0c\x26\x05\x17\x2f\xff\xde\xec\xd6\x0f\xcb\xbb\x2f\xcb\xc5\xe7\x3a\x57\x8c\x30\x19\xa1\x05\xb2\x05\xd1\xb9\x18\x10\x32\x8e\x7f\x97\x01\xc1\x22\xd6\xf3\xf2\xfb\xa2\xdd\xaf\xc6\x47\x39\x95\xb1\x95\xf2\xad\xdf\x7f\x8b\x24\x63\x24\x8a\x2d\xe1\x98\x5f\xe9\xf8\xaa\x76\xe5\xb8\x40\xdd\x0e\xb3\xb2\x4f\xdb\x77\x71\x80\x1c\xea\xfa\x75\xb9\x7b\xc9\x8e\xa5\x31\x7e\x44\x6c\x28\x56\x57\x90\x27\x6e\xa8\x46\xe2\x8e\xa7\x21\x41\xf9\xad\x06\xc4\xa1\x67\x17\x1b\xbf\xf0\x14\x0c\x8a\xad\x2f\x4a\x4b\x10\xe3\xcf\x15\x21\x45\xe0\x1a\xc6\x8a\xb7\xd2\x4b\x17\x05\x39\x46\x64\x1c\x20\xeb\x40\x79\x84\x62\xe3\x79\x48\x19\x91\x49\x22\x2d\xd7\x6a\x05\xf0\x94\xe5\x79\x56\x16\xbb\x9f\xe5\xc3\xa9\xd0\x15\xe8\xdd\x7b\x79\xaa\x85\xf7\x4c\x18\xd1\xc4\x86\x7b\x05\xfc\x6a\xee\x00\xe7\x5c\x37\xa5\xfc\x90\x50\xc5\x1d\xe2\x79\xb8\x05\x8d\x5e\xb5\x8e\x05\x96\xc6\xe7\x20\x4e\x0d\x36\xa8\x8c\x2f\x02\x29\x38\x46\x8f\xdb\x2b\x65\x32\x43\x21\x30\xa2\x87\x97\xcf\x6d\x2a\x2a\x2b\x6c\xf9\x65\xa4\x96\x30\xca\x53\x31\x02\x22\xc0\xb4\xcd\xa6\x82\xb7\x42\x5c\x6e\x9a\x37\x7e\xcf\x44\x31\xf6\xdb\x2e\x9e\xd6\xfb\xed\xc3\xec\xc5\xd5\x74\x59\x18\x44\x0a\xad\xc1\x40\xb4\xfd\xb3\xa0\x8d\x85\x41\x6c\xf7\x5b\x6f\x22\xbc\xce\x42\xf3\x5e\xb5\xae\xe1\x1e\xdf\xc2\xbe\x29\xf7\x6a\xca\x27\x77\xd5\x76\x84\x84\xd8\x4f\x6d\x53\x05\xd7\x9a\x2a\x58\x18\x86\x21\x03\xd7\xb5\xe3\x5c\x8a\x61\x78\xc0\xc2\x90\x0a\x7c\x2b\xc2\x67\x3b\x3e\x05\x4b\x4d\x2e\xae\x53\xcf\x9a\x36\xbb\x7b\xf1\xef\x85\x3a\x48\xc1\xeb\xf3\xd7\xe7\xf5\xf7\xe7\xfd\xee\xdf\x9b\xee\x9d\x31\x02\xd2\x51\x70\xe6\x39\x14\x6f\xe8\x83\x6f\x44\x6d\x81\xb4\xfa\x52\xe9\xbc\xe7\xa6\xeb\xe3\xbb\x71\xfa\x9a\x85\x2c\x8c\x51\xb9\xc4\x6a\xf4\xe0\x82\x71\xc5\xce\xa1\x2e\x50\x17\x59\xb2\x90\x25\x56\x8d\xf0\x0d\x9a\x79\x25\xd4\x07\x34\x36\x29\x85\x17\x76\x5b\x8a\xdd\xbc\x1d\x24\x8f\x85\x3c\x48\x78\x9f\xca\xb3\x84\x1e\x57\xa7\x7c\xc8\x15\x50\x3b\x2d\xb0\x0e\xb7\x13\x13\x96\x59\xe7\x0f\x84\x11\x35\x98\x1c\x6f\xaf\xb8\x5a\xac\x3f\x91\x47\x61\x61\xc4\xad\xc2\x9e\x12\xc5\xc2\x56\x0b\x87\x48\x14\x32\xb9\x30\xb7\x54\xec\xf7\xe2\xa4\x5a\x1f\xf9\x2a\x75\x78\xf7\xf2\x22\xce\xc4\x50\xef\xc6\xb2\x39\xfd\xd1\x1d\xe5\x08\xfb\x3d\xa2\x94\x19\xe8\x25\x26\xfe\x26\x73\x2c\x0e\xb4\x27\xb8\xf4\x0a\x93\x07\xf1\xcb\xce\xe2\x09\x58\xdc\x9f\x11\x32\xec\xa8\xdb\x5b\xc8\xcc\x80\xb7\xd7\x0d\x48\x02\x85\x04\xbc\xce\xfd\x3b\x1d\x8f\xe7\xad\xc8\xa7\x5d\xd0\x9f\xaf\xdc\x30\xe1\x02\x1b\x23\x66\xf9\x31\x2b\xe0\x09\xde\x44\x9e\x35\x7f\x63\x83\x08\x53\x26\x89\xf1\x5b\xee\x7d\x56\x8d\x20\x6a\x2c\x4c\x65\xcc\xb9\x6b\xa1\xc2\xed\x18\x35\x69\x4e\x45\xd1\x01\x6f\x58\x98\x02\x84\xae\xa7\x1a\x83\xf9\x8d\x38\x0f\x88\xb9\x58\x28\xa2\x60\x24\x67\x6f\x09\x51\x07\x73\x54\xc4\x0c\x6b\x78\xde\xff\xdb\xc1\xc8\x66\x5d\x6b\x89\x64\xa1\x10\x0c\x49\x0f\x9c\xde\x67\xcf\xa0\x39\x7e\xfd\x02\x04\x32\x21\x62\xa3\xdd\x0f\xa8\x06\xdb\x78\x28\x03\x11\xd3\xae\xdc\xb6\x11\x67\xd0\x93\x8c\x3e\x0b\x25\x04\x48\x9c\xda\xc6\x70\xb3\xe3\x71\x65\x9e\xe1\xe7\x05\x69\xeb\xf8\x14\x15\x87\x04\x5c\x11\x60\xeb\x59\x37\x6b\xa8\x5e\xeb\xac\x78\xbb\x43\xd2\x23\xd0\xe3\x2e\x4d\x16\xaa\x54\xe1\xf6\xb0\xf7\x98\xad\xdf\x18\x44\x05\xb6\x83\xce\x54\xe5\x5f\xc8\xeb\xd3\x4c\x38\x80\x59\xa8\x49\x88\x4d\x20\xdf\x21\xfb\x0e\xd9\xd5\x16\x08\x3f\x32\xd6\xb2\xd3\xb6\x9a\x0d\x58\xef\xfd\xdd\x69\xd7\x1f\x8e\x24\xa2\x56\x7b\xc0\x96\x02\xbe\x88\x5e\xd8\x87\x85\x5a\x76\x7a\xf1\x36\x5e\xf5\xcd\xef\xce\x5e\xfb\x61\xda\x50\x87\xf5\x9a\x97\xe5\xc7\xad\x7c\xbc\x1f\x0d\x04\x7d\x93\xdd\x50\x8c\x6f\xfa\xfa\x40\x47\xa9\xcb\xaa\x5b\xfa\xc3\x9e\x24\xa4\xfb\x59\xa3\x28\x3a\xc8\x4a\xd4\xef\x83\x88\x80\x06\x3c\xc2\xb2\xe6\xcf\x2a\x6b\xe0\x09\xda\xa0\xb0\xd0\xd9\xc0\x7d\x19\xad\x18\x1a\xc4\x56\xc6\xcc\x66\x6a\x5f\x40\x9d\xaa\xf6\xe8\x3c\x43\xe8\xfb\x55\x95\x0d\x46\x03\x9d\x78\xf6\xd9\x47\x51\xe3\x3d\x4e\x2d\x05\x25\x51\xec\x35\xed\xf0\x73\x7e\xcf\x46\x6a\x3f\x8c\x92\x44\xf2\xa1\xb0\xe7\x43\x89\x6a\x54\xd3\xcb\x18\x12\xb1\x9e\x3a\x6c\x7f\x74\xdc\xe5\xee\x70\x18\x86\x2a\xe8\x0f\xdf\x63\x09\x10\x15\xea\x3c\xa9\xd7\x68\xd3\xa4\x61\x98\x78\x21\xa5\xc7\xb2\xb5\xc9\xa7\xa2\xb9\xbf\xd0\x00\xf3\x83\xa9\x95\x02\x79\x52\xf7\xf9\x19\x1b\xd5\x6f\xb5\x74\xfc\xff\xfd\xaf\xbf\x21\x90\xa8\x17\x36\x65\x3d\x79\x14\x56\x13\xfc\x07\xca\x1d\x3e\x97\x16\xa1\x3f\xd8\x0e\x28\x55\x69\xec\x88\xe5\x4e\x47\x5b\xfc\x9c\xc6\xa1\x94\x9a\x2e\x09\xb0\x5a\x6d\xf0\xa3\x0d\x51\x0e\x8c\xb2\x94\x73\xe2\x3a\x0d\x7a\x56\xa0\xf1\x1e\x79\x9d\x9f\xd6\x5f\x40\x19\x7c\xa1\xaf\x35\xcc\xcf\xdb\xd2\x34\x3f\xc5\xa4\xa2\xc4\x28\x03\x9b\xe4\x72\x35\xba\xc7\xb2\xbe\xb0\x9d\x6e\x24\x0f\x63\xe1\x3a\x1e\x07\xf4\x03\x93\x31\x1c\xb0\xbd\x2f\xab\x67\x93\xdf\xe1\x69\x82\x3b\x19\x26\xc4\x67\x93\x6d\x8c\x46\x44\x21\x07\xe0\x31\x53\xe5\xb1\xde\xcb\x9e\xd1\x9b\xd1\x28\x24\x4e\x2c\xe0\x24\x73\x58\x16\x4d\x75\x1e\x60\x83\x19\x8d\xa2\x54\x68\x6f\x7f\xdc\xbb\xf6\x87\x24\x41\x15\x93\x67\x14\x7a\x7b\x7d\xde\xbd\xac\x96\xdb\xee\xa0\x66\xc8\x5f\xbe\xfb\x59\xfe\xdf\xb5\xd8\xb4\xa7\x72\xec\x54\x76\xc4\x8e\xf3\x29\x1d\x25\xa3\x31\x89\x10\x19\xb1\xbb\xc7\x26\x66\xff\x9b\x71\x68\x6c\xa2\x29\x7b\xf3\x7a\x1e\xae\xb6\x35\x4a\x60\xd1\x38\x61\x98\x5f\x94\xc5\xda\x5c\xe5\x80\x67\x34\x06\xa2\xc2\x9e\xb3\x56\xe4\x30\x06\x14\x39\x70\xe3\xf0\x9f\x9b\x1e\x00\x4d\x22\x49\xfd\xae\x83\x7e\xa1\xf7\x72\xa8\xbf\xf3\x24\xb6\xb2\xbf\x8e\xa2\xca\x51\x01\x0c\xeb\xdc\xb7\x16\xd3\xc8\x25\x1d\x5a\xe9\xc1\x4c\x4d\xa4\xed\x5f\xfb\x99\x15\xba\xfc\x19\x5a\xbc\xde\x05\x7b\x12\xa3\x89\x96\xdc\x49\x15\xb9\x16\xce\x1b\x31\x04\x15\xa1\x85\xd6\x59\x9f\x1f\xf4\x77\xc8\xae\xef\x5f\x54\x18\x6b\xa3\x6a\x6c\x28\x3d\x9d\xa7\x66\x49\x86\xa1\x72\xbb\xc3\x17\x71\x80\x17\xa8\x4f\xf9\x74\xfe\xca\x50\x60\xba\xd3\xbe\x9d\xbb\xac\x3e\x9e\x9a\xcb\x52\xf1\xf5\x35\xa3\x28\xc5\x6c\x7b\xfb\xee\x6d\x4e\x68\xfb\x5e\x56\xcd\xca\xef\x9f\x54\x87\x14\x45\x10\x6c\xf4\xd4\xfd\x95\x26\x61\xec\xeb\x03\xad\x0b\x72\xd1\xcc\xc4\xa8\xe6\x04\xe9\x17\x25\x34\x77\xdd\x79\xaa\x43\x75\xdd\x97\xdd\xd5\x20\x4c\xac\xfc\x46\xeb\xb0\xd7\xef\xe3\xd9\x08\x32\xc1\xfd\x11\x0a\xbd\x52\xe5\x93\xc8\x8a\x9e\xeb\x8e\x51\x13\x49\x9e\x74\x75\xc0\xaf\xff\x5e\x4c\xde\x9f\x89\x20\xe8\xd5\x04\xf6\x16\x77\x3c\xb9\x51\x03\xb6\x91\x62\x76\x77\xf7\xb2\xdf\x7d\xfd\xb2\x9f\x6d\xb7\xeb\xc5\x6a\xd6\xab\x32\x32\x46\x78\x8a\x50\xdf\x1c\x81\x26\xcb\xff\x9e\x84\x6f\xb6\x19\xb4\x81\x0d\xef\xbb\x3d\x43\x74\x05\xdd\x4c\xc1\x7a\x04\x7d\x63\x98\x97\x48\x7d\x68\x5e\xb7\x1b\xd3\x03\x88\xbc\x19\x02\xdd\x58\x1b\xa7\x48\x5c\xc9\xcb\xed\xee\x8a\x5a\x24\x6b\x5d\x58\x4c\xb9\xac\xf3\xec\x07\x7c\x11\x95\x86\xa2\x7e\x81\xba\xf4\x58\x14\xc6\x42\x65\xac\x75\x3b\x35\xf3\xa6\x6c\x23\xb9\x6d\x73\xd1\x28\x72\x95\xe1\xf5\xda\xbf\x53\xff\x71\x74\xb3\x40\x94\xcf\xf9\x67\x79\xeb\xd3\x4e\xe8\xb5\x19\xa3\xcc\x06\x68\xf2\x74\x5e\x17\x73\x78\x17\xb9\x69\xef\xc8\x37\x68\xae\xc6\x79\x43\x12\xfa\x4b\x53\x41\x83\xbe\x1d\x74\x55\xd4\xa7\x0a\xaa\x4e\x59\x70\xf9\xe3\x96\xc2\x09\x63\xd4\x04\xc2\x6e\x31\x55\xf6\x03\x2c\xcc\x75\xc8\x10\x81\x35\xb9\x41\xd4\xda\xf9\xf6\x8c\x31\xcb\x58\xdd\xda\xef\xcd\x7a\x37\xdb\xad\x3b\xf3\xcd\x98\xa6\x3c\x9c\xa8\x96\xad\xbb\x94\x13\xe3\xa1\x41\x95\xca\xa6\x3a\xcf\x4f\x17\x58\x3e\x3f\x88\x76\xbc\xe1\x7d\x83\xaa\x75\x61\x6f\xb5\xa5\x32\xc6\x99\x51\xae\x4d\xae\xf7\x13\x97\xa2\x2a\xb0\x81\xa3\x2c\xf3\xfb\xb2\xb2\x61\xd0\xf5\xd7\xc1\x39\xc4\xbd\x25\x75\x8c\x19\xd7\xe5\x74\x3e\xfd\xd7\x7f\x18\x1e\x07\xd4\x02\xeb\xd4\x07\x72\x92\x0f\x88\x88\xba\xb7\xa1\x04\xe6\xd4\x91\x07\xea\x77\xdd\xfa\xfe\xc2\x11\x55\x88\x30\xf7\x4d\x84\x22\xcb\xcf\xae\x85\x66\xb4\xc2\x59\x04\x04\xe3\xc7\x4c\x95\x88\x95\xf5\xbf\x1a\x1b\x20\x81\x2b\x82\xcc\xab\x4c\x77\x51\x1d\x4b\x0c\x84\x36\x23\xa3\x77\x20\x0e\x23\xbf\x87\xa5\x51\x10\xf6\xd2\x09\xff\x3a\x95\x53\xca\xa9\x76\x48\x8c\xdd\x07\x18\x78\xee\xdf\xba\x2e\x45\xc6\xd2\x38\x09\x53\x0b\xa9\x6e\xdf\xc3\x38\x78\x60\xa9\xd6\x9c\xbb\xf2\x5b\x5f\x59\xf0\x47\x65\xc8\x31\x16\xdd\x8a\x76\xcf\x18\x99\x0a\x49\x19\x42\x8d\x30\x36\x0d\xef\x40\xe8\x3c\x2b\xba\x1f\x95\x46\x44\xd2\xae\xa9\x05\xe4\x20\x91\x62\x7e\xfc\xd5\x55\x48\xa1\x13\xa7\xfc\xbd\x8b\xc1\x54\xcc\x63\x31\x6a\xdd\x5a\xa9\xd2\x51\x86\xf9\x21\x29\xd1\xcc\xab\xc6\xff\xf2\x95\xd5\xc9\xcf\xa6\x96\xf8\x4c\x95\x87\xa3\xa8\xc0\x35\x33\xb9\x95\xfd\x8f\x1b\xff\xfa\x73\x65\x8a\xd5\x63\x9b\xe9\xd8\xba\xee\xdc\xc9\xf5\x01\x90\x5a\xf0\x1d\xf2\xbc\x44\x5a\xed\xef\x20\xfd\x0d\xea\x80\x21\x70\xd1\xb7\x12\xd8\xd4\x4d\xbf\x75\x30\x2d\x74\xd0\x6f\x9b\x7a\xc8\x61\xe4\x47\x80\xed\xed\x5a\xf4\xd5\x8d\x21\x48\xc0\x8d\x82\x40\x25\x43\x9a\xd2\xfb\xe9\x71\x21\x53\xcb\xb9\xfc\x03\x5a\xd7\x72\x7f\x1c\x38\x90\x0c\xa4\xc0\x49\x61\xa3\xe1\x3b\x71\xae\xef\xcb\x91\x9c\x31\x63\x86\x25\xa9\x5b\xf3\x9e\xd7\x14\xa6\xab\xc0\x24\x61\x22\x2c\xb5\xdb\x83\xaf\xd2\x12\xff\x9e\x8c\xb2\x68\x12\x3b\xa7\x5f\x20\x47\x40\x9f\x37\xe1\xc3\x2f\xcf\x83\x00\x02\x3e\x41\x3a\x6c\x44\xd5\x0c\x1c\x5b\x1e\x50\x21\x5d\x45\xfc\xce\x72\x4d\xfa\xcc\xf7\x17\x31\x99\x02\x3c\x88\x6c\x86\xe5\x6b\x29\x72\x81\x06\xc2\x5f\x85\x44\x36\x5b\x36\x6a\x4a\x0c\xa3\xee\x70\x2a\x10\xb9\xdf\x88\x0f\x18\x16\xf8\x3e\x4d\x3b\x73\x22\x92\x34\xc5\x10\x60\x7b\xb2\x60\xeb\xc9\x71\x49\xb5\x63\xcb\x42\xe9\x7f\x57\x41\x73\x47\xc3\x84\xe1\xd9\x7b\x24\xe9\xc0\xa6\xb8\x6f\xa2\xca\xda\x09\xd8\x3d\x3c\x65\x56\xa8\x5c\x68\xfd\x74\x6a\xd7\x63\x71\xdf\x09\xa7\x5e\xde\x0f\x35\x06\xfb\x59\xca\x76\xea\x0f\x23\x62\xce\x88\x89\x93\x81\x21\x47\x20\x79\xf9\xeb\x3c\xaa\x2f\x72\xc6\x0d\xba\xe2\x8f\xaf\x8f\xaf\x43\x93\xc0\x99\x26\xc6\x5a\x37\x85\xbf\xff\x3d\x2b\x26\x8f\x1a\x85\x31\xeb\x30\x2b\xb5\x95\x31\xf2\x67\x47\x71\x82\x5b\xcf\xd3\xea\x79\xbe\xdc\xf9\xbf\xc6\x24\x46\x1a\xbb\xe7\xe5\x76\x77\xdf\xd1\xf3\x31\x1e\xeb\x38\x42\xb8\xd1\xc3\x76\xe1\xff\x96\x68\x16\x8f\x9b\x3b\x47\x0c\x11\xdd\xa8\x28\xf8\x94\xc9\xf1\x5a\x75\x8b\x27\x26\xc4\x97\x56\xff\x14\xd5\x61\x57\x4d\x31\x07\x3c\x31\x11\x46\x73\x59\x51\x63\xb3\xde\xb0\xb3\x98\x71\x11\x50\x2b\x8d\xa0\xde\x41\x9f\x5a\xd3\xd1\xac\x6e\x7d\x9e\xd6\xab\x70\x32\x0a\x77\xa2\x11\x3e\x71\x39\x5a\x5a\x5c\x50\x2b\x92\xe3\x44\x67\x6f\x74\x17\xf9\xc1\x91\x89\x99\x27\x6e\xfa\x75\x7e\x84\xb7\x89\xbe\x33\xe3\x22\x21\x81\x6b\x7c\x79\x82\x46\x5c\xd2\x8c\x5e\xfe\x7b\x19\x5e\x73\x01\x56\x29\xbb\xce\x45\xfd\xde\xda\xae\xa2\xdd\x87\x2e\x75\xa8\x19\x97\x3c\xe2\x96\x88\x2e\xcf\xcb\x66\x59\xa8\xea\x6c\xb5\x55\x40\x7d\x80\x37\x32\x5c\x0a\x4e\x5c\xe7\x9e\x4d\xa9\xdc\x80\x49\x33\xae\x94\x96\x0e\x2f\x7e\x0f\x57\x08\x34\x19\xd7\xc4\x73\xbe\xbd\x15\xed\xad\x2d\xae\x14\x29\xb9\xe6\x1c\xb1\x78\x7b\x9b\x61\xc0\xd0\x7a\x6c\x7f\x39\x84\xa1\x86\x11\xff\x59\x05\xaa\xf9\x0d\x73\x14\xe3\x10\x07\x26\x70\xe8\xeb\x43\xd6\xcc\xf1\xb9\x6f\xbe\xe2\xe1\x35\x7c\x21\x81\x1b\x6e\x41\xd8\xa2\x3e\x17\x6a\x0b\x85\xde\x66\x39\x14\xc3\x9f\x1e\xff\xa4\x11\x21\x92\x09\x14\xf0\x73\x2e\x8a\x8f\x6b\x2a\x05\x2c\x0a\x02\x82\x48\x97\xc5\xeb\xbc\xf3\x24\xa3\x20\xe0\x18\xfc\x3e\x22\xdf\xf2\x27\xde\x51\x37\xde\x60\x67\x82\x4f\x49\xdf\xa3\xc6\xba\x3f\x68\x02\x24\xbc\xb0\x29\xcc\x2e\x69\x33\xa1\x9c\x9e\x3c\xc2\x7f\xb8\x9b\x53\x11\x09\x25\xce\x94\x2f\x50\x48\x79\x1e\xda\x9b\x88\xa4\x96\xcf\xfb\x05\xd4\xbb\xa8\xde\xa0\x8d\xc3\x26\x8f\x17\xc6\x1c\x0d\xce\x0f\xab\x34\x8f\x62\x5f\x7f\xc7\x95\xbc\x58\x96\x51\x28\x02\xac\xd2\x9b\x53\xa1\xee\xab\xf2\xb0\x20\xfe\x36\x42\x13\x79\x78\xc6\xbd\xd0\x50\x9e\x90\x69\xa9\xa9\xaf\x35\x55\xb2\x88\x6a\xe0\xce\x8d\xd9\x88\xba\xb1\x79\xdf\xae\x67\xa0\x7b\x6b\x2c\xe4\xc4\x76\x02\x76\x05\xaf\x4d\x59\xd7\x3d\x2b\x11\x8b\x18\x0f\x3d\x3b\xc5\xb0\x2f\x21\x19\x2f\x8d\x88\x71\xab\x24\x83\xd9\xa0\x9e\x1d\xdb\x1f\x8d\x14\xb0\x4e\xa1\xb1\x75\x69\xb6\x5e\x89\x93\x45\x4c\xd8\x34\x70\xd7\x32\x60\x63\x61\xa8\x16\xa7\xe6\x8f\x91\x6b\x14\xf1\xd0\x32\xf5\x6d\x00\xaa\xf9\x49\xd7\xa3\x0f\x15\x31\x82\x26\xd7\x92\xbf\x1f\x6f\x60\xd9\xfd\xe0\x98\x63\x89\x6d\xfd\xf2\x65\xf6\xbc\x5a\xfc\xde\x33\x8c\x62\x4e\x10\xdb\xbd\xf9\xea\x5e\xc0\x68\xc5\x46\x71\x24\x30\xad\xb5\x3d\xfc\xa5\x0f\xa3\xfb\x4a\x93\xd0\x07\x2e\x1b\xa8\xea\x09\x49\x2e\x8b\x52\x91\x20\x4e\xcf\x92\x34\x8b\x06\x30\x07\x3b\x7c\x7d\xa9\x22\x0c\x3a\xbd\x8c\x4b\xac\xaf\x1b\x26\x68\x48\x59\x27\x8a\xbe\x78\x37\xc3\x7c\x5d\x24\x98\xd5\xd4\xcd\xea\x67\x00\x8d\x01\x83\xdb\xbf\x7a\xb1\x79\x16\xa9\x80\x28\xcb\xc6\x70\x76\x8d\x7a\x7f\x0c\x32\x59\x49\x37\x2a\x84\x0e\xa0\xb6\xd7\x70\x6c\xde\x47\x7e\x57\xa4\xa4\x40\x29\x43\x6c\x90\x6b\x7e\x96\x2b\xd7\x23\xf7\xdf\x71\x60\x10\x69\x16\x20\xc1\x75\x79\x84\x02\x9b\xf8\x5c\xe5\xb2\x3b\x4c\x84\xdd\xef\x54\x05\x07\x6c\x34\x6e\x44\x8e\xd4\xc4\xdd\x25\x40\xa6\x51\xd2\xa5\x6b\x5f\xab\x6c\xf2\x7a\x4d\x10\x4a\x89\x9a\x13\xea\x03\x9a\x7a\x2f\xad\x40\xfd\xb5\xfd\x37\x32\x81\x42\x66\xdf\xaf\x27\x91\x7d\x15\xd7\x6d\xd2\x95\xa9\x61\x08\x90\x9e\x47\x7e\xcc\xf9\x7f\xf5\xec\x1b\x46\x60\x94\x55\x1e\xbe\x6f\x93\xc8\x34\x1a\x61\xbe\xbd\xe7\x16\x93\x90\xe0\xbc\x7b\x42\x1d\x95\x43\x56\xb4\x11\xfe\x45\x23\x3d\x8b\x89\x11\x08\xf2\xdf\xcb\x53\x96\x5f\xf0\x2e\xb2\x38\x64\x92\xcb\x2e\x5d\x34\x3b\x64\xb5\x73\x2e\xc6\x97\x61\x54\x23\xe8\xd9\x90\xf1\x8e\x15\xb3\xd4\xa6\x08\xe5\x05\xa9\x12\x8b\x99\x08\xf1\xb7\xbb\x4e\xd2\x01\x00\x9d\xc5\x0c\x42\x0c\xa4\x31\x63\x8b\xf4\x9c\x88\x03\xb6\x2a\x22\x7e\x10\xa7\x0c\xb3\x81\xdf\x2b\x71\x3c\x4e\xf0\xbf\xd7\x63\xf8\x2e\x8b\xd0\xe5\x35\x62\x2e\x52\x0c\x5f\x5f\x77\x7f\xae\x2d\x90\x0a\xf4\x98\x5e\xf2\x1a\x84\xf4\x73\x20\xd7\x78\x06\xc5\x49\xc2\xc2\xb4\xfb\x52\x16\xbb\x79\xf1\x2d\x92\xc4\xd2\x13\xe7\xa0\xdf\x06\xea\xfa\x5a\x77\xef\x24\xe5\xd6\xda\xfb\xbd\x0e\x5f\xd8\xea\xa2\xef\xfd\x34\x06\xd7\xc4\x69\xac\x89\x55\xac\xb3\xad\x4b\x3d\x0b\xc1\xf8\x2e\x85\xb4\xd2\x1f\x07\x51\x7d\x20\x9c\xae\x8d\x09\xe0\x62\x14\x48\xbb\x72\xd0\x8f\x3e\x1d\x27\x87\x25\x09\x31\xa1\xf2\x94\xad\xfe\xe6\x42\x89\x25\x49\x90\x04\x21\x53\xe5\x65\xe1\x25\x96\xd4\xb6\x2a\xce\xb3\x66\x51\xe1\x34\xf2\x07\x84\x40\x4f\x61\xf6\xf8\x10\x76\x7f\x93\x56\xcb\xf8\x68\x4b\xdc\x5e\x0f\xad\x23\x52\x6b\x47\x30\xea\x95\xa3\xf7\x42\xeb\x59\xa1\x5f\xf0\xab\x6c\x5a\x43\x5b\x5b\x99\x4b\x37\x56\x45\x2a\xb6\x05\xb6\x4c\xc1\xe3\xa2\xfb\xb3\x21\xd8\x5b\x6d\x73\x9f\xcf\x65\x63\xd3\x9f\x17\xa0\x8f\xf1\x53\x2a\x63\xb0\x39\x0e\xf1\x1e\x59\xf1\xe6\x7d\x22\x77\x18\x94\xc0\xd2\x3a\xae\x94\xbb\xaa\xbc\x0e\xbd\x67\x49\xc0\x14\x20\xd9\x1f\x74\x35\xdd\x24\x88\x34\xf3\x34\x59\xe5\xa9\xa8\x57\x85\x4d\x79\x4d\xce\x74\xa0\xc7\x36\xe6\x9f\x65\x95\xbe\xfd\x1b\x84\x5a\x0e\xbf\xe5\xaf\xa6\x35\xb0\x83\x42\x7b\x42\x12\x4e\xc4\x20\x8b\xf0\x3c\x60\xe9\x1d\x3d\x6f\x42\x52\x2b\x61\x2d\x9b\xb3\x12\x5a\x1f\xca\x02\x6e\x78\x8b\x09\x31\x69\xa8\x7c\x53\x45\xa9\x3e\x26\x71\xc7\x64\x34\x8d\x23\xab\x50\x73\x3a\x93\x0f\x67\xbf\xfd\xed\x31\x22\xb1\x30\x82\xcc\xe8\x46\x28\x98\xfb\xdc\xd1\x0d\x90\x4a\xc2\x38\xc1\x7e\xa8\x63\x55\x62\x9b\xc5\x1d\x08\xdf\x38\xc9\x12\x26\x02\xac\x39\x5a\x5e\xa5\x1d\x32\x03\x74\xfc\x34\xd7\x63\x37\x77\x26\x0f\xc0\xf9\x50\x98\x5c\xb0\x5e\x69\x6f\x74\x12\x4e\x2c\x15\x4e\x56\x63\xc3\xc4\xc8\x12\x24\x9c\x25\x88\xae\x53\x39\x88\xea\x0b\x14\x28\x07\x3a\x2b\xf4\x93\xa8\x2f\x7a\xcf\xaf\xbb\x8c\x09\x67\x52\xf7\x0c\x29\xbb\xf7\xac\xd2\xcb\x5f\x7d\x05\x67\x32\x38\x09\x65\x30\x10\x3e\xb3\x65\xe6\xfb\xb2\xfa\x52\x96\x1a\xc9\x9f\x97\xa2\xea\x56\x64\x12\x05\x0c\x67\x72\x53\x5a\x1c\xdb\x1f\x53\xb3\xd8\x5f\x39\xa2\x14\xfd\x44\x4f\xef\x84\xf2\x46\x4f\xe2\x57\x1f\x7b\x27\x71\xc4\xac\xf8\xa5\xd6\xe8\x99\xec\xb2\x29\x00\x38\x49\x98\x51\x1d\xf9\xdc\x06\x7a\x96\x51\x96\x24\xb1\x42\x32\xb1\x6d\x06\xc3\x6c\x4a\x92\x24\x04\x7f\xd8\xa7\x9b\x7d\x24\x93\x24\x89\x64\x16\xe2\x82\x0e\x83\xa3\x80\x18\xbf\xff\x24\x05\x3a\x10\xa0\x3e\x8c\x0b\xe5\x3d\x9a\x60\xc8\x31\xe2\x4f\x35\x36\xa7\x69\xa9\xa0\xb1\xf3\xb3\x5e\x15\x9b\xb2\xce\x7a\x0a\x02\x96\xa4\x91\xc0\xd0\xa0\x0d\x08\x37\xb3\x51\x8a\x23\x91\x81\x47\x70\xe0\xdb\x25\xd1\x27\xaf\x57\x0a\x81\xd3\xfd\xfe\xf5\xf9\x6e\x3f\xbb\xeb\xd0\x6c\x89\x62\x8c\xa6\x9d\x0c\x2a\xae\xa6\x75\x71\x2d\x36\x4d\x54\x44\xb1\x7b\xdf\xc2\xfa\xda\x60\xad\x2a\xf3\x7c\x7e\x3a\xaf\x8a\x61\xe5\x25\xd1\x84\x61\x09\x0f\x11\x77\x03\xc6\x39\xff\x8b\x40\x78\xe0\x2b\x59\x59\x55\x37\x6e\x0d\xd7\xa8\x93\xae\x31\x67\xd9\x7e\xbd\xbb\xd1\x29\x69\xea\x28\x41\x9f\xb2\xc2\x2a\xac\x4d\xee\x0e\x98\xb6\x48\x2e\x51\x7c\x10\xda\x9d\x98\x44\x68\xc9\x36\x55\xf9\xbf\xa0\x9a\xbf\xb9\xcf\x24\xa0\x28\xa6\xb2\xef\x66\xab\xc7\x7f\xef\x1f\x57\x4f\x2b\x9f\xea\x49\x8c\x52\xe8\x99\x2e\x5e\xb6\x5e\xa3\xd8\x1e\x49\x83\x40\x63\xb6\xa3\xd7\x5d\xeb\xa7\xc1\xff\x15\x80\x21\x0d\x42\xb0\x1c\x20\xeb\x2f\xe1\x7e\xd9\x5d\x5f\xda\xbf\xfa\x94\xd0\xf2\x54\xed\xca\x29\x3b\x08\x4b\x03\x20\xa8\x30\x0a\x3a\x6b\x36\x19\x28\xc0\x34\xc9\x27\x81\x71\x7b\x86\x57\xaf\xb6\x79\x82\x39\xba\xb8\x23\xac\x6f\x1a\x32\x69\x62\x87\x05\xee\x73\x39\xfd\xe1\x34\x44\x16\x83\x76\xb3\xb4\x2d\x9a\xa0\xef\x3c\xaf\x0a\x4b\x69\x60\x1b\xfa\xfd\x66\x80\x3a\xe2\xce\x76\xfb\x21\x21\xc1\xfe\x40\x68\x0d\x32\x26\xbc\xc7\xc1\x5b\x4a\x63\x82\xcf\x6f\xa0\x51\xef\x1b\x91\x69\x9b\x15\xbf\x2f\x2b\x87\xdf\xe9\xbe\x04\x15\xa1\x09\x7d\x1b\x6d\xe1\x28\xeb\x5b\x6b\x86\x3c\xeb\xeb\x69\x6d\x2d\xa5\x3a\xc0\xc8\xaf\x8d\x22\xbe\x03\x7c\x74\xd7\x71\xad\xd9\x5d\xa7\xec\x97\x4a\x14\xcd\x2d\x48\x7f\xca\x08\xc1\xb5\x6a\x41\x42\x6e\xca\x4d\x7e\x8a\x51\x15\x5b\xed\x98\xba\xcc\x7f\x8c\x4b\xce\xe4\x12\x28\x33\x34\xd9\x24\xba\xe1\x49\x0e\x16\x5f\xca\x04\xa0\x14\xe9\x88\x83\x7d\xb5\x58\xef\xb7\xbb\xd9\x97\x25\xe9\x64\xfc\xbd\x1f\x94\x32\x08\x91\xdc\x6a\xf1\xe7\xe3\x95\xca\x7d\xca\x29\x08\xd1\x1b\x38\x3f\xa1\xef\xab\xf2\x70\x4b\x5e\x87\xa5\x9c\x5b\x68\x87\x0b\xc8\x5b\xf3\xb9\x3e\x35\xaa\x3c\x4c\x5f\x3c\x4f\x22\xfc\x50\x38\x57\xb1\xc0\xe8\x92\xc7\x03\x6e\x25\xd2\x0d\x56\x81\xf2\xbd\x0e\xed\x25\xfd\x2d\x46\x89\x88\x5d\x3a\xfc\xa1\x3c\xc0\x66\xca\xf1\xc5\x5a\x1b\x8a\x3b\x77\x55\xca\x8d\xc0\x6c\xd9\xf5\x0f\x18\xc9\x38\x8d\x1c\xa3\xe9\x93\xcd\xe2\xd4\xcb\x3c\xfb\x95\x79\xdf\x2b\x4d\x68\xa0\x1d\x40\xa8\x6b\xb6\xdc\xe4\x65\x73\xc5\x5e\xa6\x69\x18\xa1\xbd\xdc\x42\x6e\xbe\xc2\x79\x2c\xe1\x11\xb1\x7f\x0c\xfe\x19\x9c\x94\x2a\x74\x4b\xd1\xb9\xc3\x3e\xa9\x7c\xa0\x25\xcf\xd2\x54\x70\x44\xdb\x7d\xde\xc7\x94\x0a\x42\xb0\x0b\x31\xcf\x14\x14\x35\xec\xa0\x3a\xd4\x4f\xe2\xd7\xa2\xac\x9b\x0d\x54\x5b\x50\xd7\xd1\x29\xa9\x10\x61\x1a\x76\x14\x2e\xc3\xf8\x3f\x95\x4c\x07\xb2\x9b\x09\xd8\x8f\x06\xda\x56\xaf\xc6\x15\xd7\x7e\x3c\x1b\xf2\xa1\xf8\x30\x05\xab\x45\x63\x7b\x27\x63\xe5\x84\x2f\xc1\x09\x3e\x0d\x36\xee\x54\xaa\x30\x1d\x6a\x39\x3c\x65\x45\xe3\x18\xc2\xc7\x97\x51\x92\xda\x96\x1a\x51\xac\x0e\xc7\x1c\x03\xfe\x95\x77\xef\x06\xf0\xb5\xab\x08\xce\x14\x04\x30\x47\xcd\x7a\x81\x2b\xbd\x0c\x95\x52\x43\xac\x48\x7a\x56\xd4\x50\xa1\x20\xd2\xb6\xac\x9a\x3e\x06\x9a\x5c\xdd\xc4\x31\x3a\xe3\x0b\xdb\xea\x8d\x8c\x25\x18\x73\x4c\x26\x8d\x89\x05\x26\xa7\x61\xb0\x16\x6d\x12\xb8\x9e\x0f\xd0\x55\xa9\x31\x89\xe7\xf1\x75\x8f\x35\x3f\xb7\x1e\x76\x3d\x21\x3f\x61\x22\xa0\xa9\xc2\x05\x3e\xff\x04\x0d\x2a\x82\x84\x69\xe3\x2a\xac\x76\xc2\x5d\x1f\x47\x42\xd0\x0e\x9b\xe1\xf6\xed\x95\x76\x32\x26\xb3\x42\xaf\xf4\x05\xa9\xae\x3f\x2f\xb1\xed\x5e\x8f\xeb\x47\x6f\x7a\x04\x51\x04\x1c\x0d\xd7\x40\x15\x7d\x56\xe8\x79\x56\xe8\x70\x9c\x3e\xb8\x05\xa3\xe8\x2e\x65\x21\xda\x8e\x4f\x6e\x51\x82\x31\x99\xca\x7a\x08\xa4\x08\x03\x61\xc9\x1c\x01\x34\x09\xc6\x6f\x5d\x84\x94\x46\x0e\xa9\xd9\x3a\xd9\xb3\xc6\x82\x1c\x60\x60\x86\x86\xff\x4b\xc3\xff\x10\xe2\xdf\x6f\x18\x4b\x04\xab\xd9\x28\x17\xa7\x99\xed\x72\xf6\xbf\x4c\x03\x2b\x58\x7d\xd8\xa3\xc1\xc8\x8a\xb7\x55\x3d\xd4\x18\x67\x82\x26\x14\xcb\x47\x9d\x45\x05\xbd\x3d\x88\x3c\x5f\x88\x1b\x71\x97\xa0\x32\x20\xc8\x47\xdd\x34\x42\xbd\xef\xca\x4b\x85\x57\x26\x18\xb5\x7e\x58\xbb\xab\x2d\x44\x55\x9e\x6a\x4f\xc2\xd6\x1e\x53\x9c\xf4\x41\xc7\x93\x93\x4d\x9b\x5a\x72\xc1\x18\xc1\x0e\xa0\x3b\x40\xb8\xc4\x0e\x86\xcb\xee\xa6\x37\x33\xbe\x57\x4c\x04\xb4\xcf\x0f\xd5\xb4\xcc\x25\x98\x30\xd8\xf7\x2d\xb4\x18\xc4\x8e\x22\x4a\x18\xb8\xef\xb1\x3f\xb6\xb6\x6b\x9c\x2c\x12\x91\x53\xa9\x47\x17\x13\xbb\xeb\x27\xcf\x1e\x09\x86\x15\xea\xa7\xd5\xf3\xee\xdf\xdd\x55\x85\x0c\x7c\x1f\xc5\x28\x73\x20\x62\x0a\xdc\x0c\xf2\x1e\x37\xa9\x31\x06\xd9\x20\x11\xc7\xa9\xd5\x74\x5c\x3e\xae\x2d\xa3\xc6\x94\x2a\x99\x89\x58\x87\x71\x3c\xdd\x3e\x91\x9d\x33\x17\xea\x63\xb8\x79\x8e\xed\x85\x48\x02\x89\x5b\xd6\xfc\x54\x67\x05\xd4\xf5\x6b\x31\xec\x0b\xb8\xe9\xb9\x8a\x84\x87\xd8\xc0\x7a\x2a\x6a\x70\x95\x1b\x7f\x04\xec\xa7\xec\xe4\xf4\xff\xba\xd2\xf8\x3f\x7e\xcd\xa9\xa6\xda\xf2\x53\xe4\x39\x66\x3f\x10\x44\xf2\x49\x7b\x9d\x48\x75\x82\x60\x2f\x03\x30\xef\xca\x04\x42\x44\xa1\x71\xf9\xe7\xb5\xfc\x5f\x2b\x62\x7d\x4d\x31\xa1\x1d\x69\xd5\x29\xb0\x04\x68\xf3\x1e\x07\x5c\xcf\x23\xe4\xb7\x10\xa9\xe5\xcc\x7a\x83\xe6\x5b\x3b\x25\xb5\x5b\x73\x23\x97\x55\x48\xa3\x82\xd0\x63\xab\x4f\x58\xe6\x2b\x9a\x2e\xa5\xd5\x43\xd8\x85\x62\x56\xc3\xdc\x3a\x6e\xcf\xf0\xd3\x02\x16\xb0\xea\xec\xc9\xf5\xba\xa1\x80\x15\x5d\x27\x46\x01\x68\xf9\x1c\xbe\x63\xfc\x05\x95\xb2\x98\x51\xdb\x7d\x8c\x02\x46\x93\x87\x55\xa0\x50\xac\x60\x23\xce\x00\x9d\xd2\x6f\xbb\x61\x0d\xd9\xfc\xae\x46\xed\x42\x53\x8e\x2b\x64\x93\xd5\xa2\x78\x1b\x06\xb4\x42\x6b\x83\x60\xef\xfa\xa7\x38\x3e\x75\xcf\x08\x09\xc3\xb8\xa5\x13\x17\x76\x75\x82\x61\x1f\xc5\xe4\x09\x00\xac\x22\xd2\xa9\x86\x4d\xf9\x73\xc2\x78\x72\x69\x15\x93\xff\x90\x38\xf2\x86\xc3\x30\xe5\xbb\xa1\x9f\xe1\x67\xfb\x92\x6c\xe5\x61\x84\x3c\x1d\xcd\x5c\x63\x62\x66\x4d\x8d\xcc\x6e\xac\x0a\x19\xb0\x14\x31\x16\x6f\x99\xf1\x5f\x44\x06\x91\x48\x1d\x18\x6c\x96\xe7\x4b\xa7\x91\x5e\xaf\x4d\xd7\x83\x71\xeb\x62\x31\xf1\x9f\x72\x7f\x74\xbc\xed\x7b\x23\x54\x96\x5f\xc0\x80\x64\x60\xac\x92\x87\xd3\x9f\xb3\xf3\xac\x5d\xc7\x5f\xb3\xe2\x0d\x91\x81\x1d\xe1\xe4\x6f\x8c\xe2\xe7\xf8\x40\xf7\x73\x24\x0d\xb8\xf4\x74\x03\x6d\x8c\xfc\x9b\xc4\xad\x24\xa9\x16\x5d\xbf\xc4\x35\xb1\x2b\x3f\x4e\x84\xe8\x22\xe9\xac\x6e\x03\xed\x59\x25\xb3\x0b\x3f\x4a\x12\x29\x10\x3a\x89\xdb\x95\x47\xc8\x4d\x5e\x08\x91\x46\x5b\x24\x98\x27\x1f\xf2\xdf\x23\x8c\x0d\x92\x39\x2e\xca\xff\x9e\xb2\xf1\x11\x15\xa2\xb1\xff\xf2\xef\x11\x22\x43\x52\x6a\xb0\x78\xba\x17\x93\xf6\xa7\xf1\x6d\x51\x0e\x66\xc4\x36\x75\x43\xda\x6e\x6c\xc4\x24\x4d\x19\xa6\x1b\x6a\x71\xfe\x52\x96\x7a\x7e\xf6\x4b\x42\xb2\x34\x44\x85\xa3\x2d\x34\xab\x22\x6b\x46\x71\xf2\xdf\x2a\xb7\x4a\xa6\x00\x3d\x98\x76\x8b\x9d\x77\x5c\x8b\x83\xe3\x60\x09\x68\xe5\xe9\xbc\xfe\x79\xc3\xf5\x92\xcc\xa8\x04\xbc\x0e\xe6\x40\x40\xac\x3c\x35\x48\x3f\x7a\xec\xa6\x3a\x0f\x12\x34\x29\xed\xbe\x31\x3f\x63\x9f\xfc\x08\xf1\x2b\x79\x00\x5e\xf1\xe2\xa9\x7e\x1b\x92\xa6\xf8\x01\x84\x62\x44\xdb\xbc\x55\xb7\xb9\xab\x99\xe4\x71\x20\xd2\x4e\x6e\xa6\xec\x6f\x40\xd9\x36\xe5\xe2\x74\x58\x64\x4d\x06\xfd\x09\x60\xb0\x81\xc0\x6e\x11\x0b\x1b\x18\x7d\xca\x14\xc8\x64\x24\x13\xb4\x53\xfb\x5a\x18\xf8\x1d\xe3\xde\x68\x79\x44\x26\x46\x25\xbd\xd6\x1d\x99\x8b\xe6\x7d\xf7\x6b\x62\x9a\xae\x64\x39\x64\x1c\x46\x18\xe8\xca\xd3\x19\xb3\xf4\xdd\xbd\xc7\xb1\x41\xa3\x22\x94\x82\xa3\x6d\xf6\x45\x6b\xd5\xeb\xf7\x4f\x66\x54\x9c\xda\x52\x58\x27\x50\x4f\xad\x84\xf4\x7e\xb3\x7c\x59\x2c\x9f\xdb\x40\xdb\x5f\x3b\x09\x05\x76\x11\xff\x28\x51\x8d\x62\x08\xc2\xbc\xde\xe2\x26\x93\xd4\x20\x5c\xc0\xe9\xad\x35\x70\x7c\x2c\xbb\xb6\x3b\x99\x18\x69\xa2\x01\x15\xd5\xb5\xc8\x4b\xa6\x4c\xa0\x0f\x20\x9a\xc6\x03\xc5\xa5\x20\x82\xd9\x0e\x8f\xed\x51\xfc\x2c\x86\x80\xa9\xc9\x32\x13\x3c\x88\x5c\xef\xcf\xb3\xeb\x39\xc2\x8f\x23\xac\x5d\xed\x2e\x08\x92\x84\x2e\xdb\xd5\x6d\x24\x8e\xe3\xe8\x4a\x7e\xa2\x7f\x40\xc9\x52\xac\xd2\x38\xd0\xdf\x53\x56\x9c\xea\x7b\x80\x7a\x7d\x6a\xea\x46\x58\x6a\x15\x3f\x34\x8e\x2d\xb5\xb3\x83\xae\xdf\x9d\xaa\x01\x3f\x6b\x7b\x5c\x61\x9a\xee\x88\x8c\x59\xa3\xd2\xaf\x94\x3a\x40\x0c\x72\x6b\x2d\xd6\xc7\xde\xd8\x28\x06\x18\xe1\xfe\xeb\x04\x50\xfc\x39\xdc\x38\xa5\xd2\x46\x3a\x25\x01\x0d\xbd\x7b\x20\x15\x44\x41\xdf\x7f\x7b\x63\x15\x6b\x61\xac\x56\xaa\x2c\x4f\x13\xaf\x46\x6a\x93\x3a\x2e\x5d\x8c\x7e\x5f\xc0\x5c\x53\x84\x62\x2a\xa0\x0c\xbf\xfd\xf2\x65\x11\x87\xe4\x2a\xa6\x4a\x05\x5c\x21\x7c\xcc\x31\x6d\x3f\x96\xa2\x98\xd8\x66\x15\x68\x89\xf5\x94\x4c\x95\xc4\x25\xea\xb5\xed\x15\x74\x03\x48\x68\x67\x11\xf6\xba\xfa\xbf\x19\x1b\x26\x62\x3b\xc5\x9e\xee\x85\xf6\x45\x23\x85\x52\xd4\x0e\x26\x5b\x9d\xb7\x65\x6e\x9d\xb8\xc9\xaf\xd2\x80\x24\x56\xc5\x18\x40\xdf\x97\x07\x3f\xf5\x14\x25\x29\x52\x40\x60\x11\x5e\xd4\xf0\x4f\xa1\x3e\x8e\xe5\x4d\xaa\x2b\x7f\x16\xd5\xe8\x7c\x54\xad\x69\xda\x4f\x7f\x2b\xe6\x81\x27\x62\xc9\x8a\x79\x07\x61\x53\x4c\xa5\x1e\x28\xe2\x35\xb5\x5e\x96\xbb\xbb\xe5\x7c\x50\x0e\x54\x0c\x3a\xef\x71\x23\x9a\x36\x48\xb4\xfd\x03\xb8\x01\x8c\xdf\x36\xe7\x36\xe7\x6d\x69\x43\xbb\xa4\xcb\xa7\x86\x4d\x45\x3c\x0d\xe3\x01\x52\xfc\xa7\xff\x92\xd7\x5c\x66\x15\x71\x83\x94\xd3\xb6\xfe\xf2\x82\xde\x62\xc7\x67\xc6\x54\x04\x06\x5b\x5e\xb7\xad\x91\x44\x22\x07\x6f\x29\xdd\x80\x98\x29\xf4\xeb\x1f\xcb\xb7\x51\x24\xf4\xf9\xd6\xd5\x9e\x86\x28\x4a\x85\x91\xf7\x04\x3f\xa6\x52\xa2\xb0\x10\x9c\xd5\xed\x4b\x79\x01\xe4\x59\x03\x64\xb7\xbc\xe9\xe0\x5c\x90\x79\x33\x95\x52\x8a\xfb\x11\x54\x55\x39\x62\x87\x66\x2a\x95\x06\x89\xb2\x51\xf0\xaf\x7b\x5a\x11\xc7\xc0\x1d\xa3\xc4\x73\x07\xf1\x51\x22\x4d\x98\x63\xd5\x7e\x29\x4f\x17\x1e\x8b\x12\xc6\x7a\xc3\xad\x0d\xda\x8b\x11\x44\x44\xc9\x80\x60\x89\x72\xbf\x7e\x5e\x76\x7f\xe3\xb1\x6e\x57\xf4\x4f\x1f\x70\x2f\x8b\xa6\xca\xe0\xba\x38\x14\x53\x8a\x5a\xf5\xbb\xbd\xab\xc1\xb9\x3f\xeb\x50\x80\x6d\xd3\xe9\x74\xb8\x5e\x91\x62\x7d\xba\x20\x21\xe4\x48\x60\x68\x3f\xf1\x17\x71\x80\xed\x11\x54\x66\x32\xf5\x5b\x4e\xac\xee\x0a\xe9\x00\x21\x72\xf3\x13\x5f\x75\x74\x15\xa4\x3a\xf4\x4a\x8e\x36\xb1\xfe\x69\x6c\xa1\x00\x28\x5a\xe8\x31\xf8\xf0\x77\x0e\xad\x3d\x59\x07\x4a\x05\xbe\x79\x07\x33\xba\x93\xbe\x2c\x4d\x22\xc1\xb4\x93\xc1\x7c\x6d\xbd\x8e\x3c\xbb\x64\x49\xfa\xc7\xe8\x9a\x44\x85\x49\x8f\x2d\xf9\x56\x36\xf0\x72\xca\xa7\x4c\x23\x3a\x4c\x15\x12\x67\xed\x6d\xb0\xbd\xb5\x3a\xae\xe3\x1f\xa7\x01\x43\x69\x1e\x17\xe9\xb5\xf6\x6f\x38\x2b\x35\x0d\xac\x96\x92\x55\x54\x7d\xc2\x8c\x45\x1f\xf2\x6b\x0a\x02\x55\x48\x31\x3b\xeb\xd2\x94\x94\xfa\x6a\x93\x66\xa1\xc5\x3e\x1e\xab\x6c\xa2\xb9\xca\x34\x83\x14\xdd\xd0\x7c\x02\xdf\xd2\x9c\x5a\xdd\x0e\x0d\x99\x3a\x88\xdc\xcf\x5b\x1d\x91\x08\x33\xc1\x58\xca\x7c\x2c\xd5\x87\x93\x68\xf1\x87\x75\x14\x10\xe7\x59\xdc\x97\x17\x9f\xd4\x8d\x8a\x03\x8d\xfc\x24\xc8\xcf\x36\xe2\xfa\xf3\x03\x68\x8c\xe8\xf7\xc3\xbe\x47\xde\x75\xb7\x10\x27\x01\x36\x27\x67\x35\x22\x83\x26\xa7\x26\x91\x09\x82\x41\xd2\x64\xdb\x88\x8f\xeb\x42\x77\x4c\x27\x29\x41\x49\x26\xfb\x05\x9f\xdb\x1d\x22\xc3\x12\xd3\x4c\x5f\x74\xe5\xe9\x34\x16\x58\x78\xfd\xc8\xf2\xbc\x4b\x03\x6b\xc1\xac\xf3\x6b\x17\xd1\x93\xf8\xd5\x0b\xe1\x4f\xce\x17\x3c\x42\x49\x95\xd9\x97\x61\x98\xa1\x85\xd6\xca\x36\x91\x34\x2f\xd0\x7e\x75\xd5\x80\x1e\x7e\x5d\x49\x0c\x52\x12\x1c\xac\x3c\xd3\x5f\xa0\xc7\x61\xc6\x35\x12\x46\x1f\x81\x69\x29\x53\x34\xc3\x3e\x61\xb3\x18\xa4\x4a\x26\x69\x9b\xf1\x6b\x54\x71\x4a\xdd\x82\xf9\x7a\x9e\x90\x35\x32\xad\x74\x00\xc3\x2c\x7a\xe7\xa9\x5f\xff\xde\x3a\x64\xc8\xdb\x8e\x89\xb1\xac\xb0\x3b\xc2\x7c\xe7\x01\x29\x5a\x4b\x8e\xa4\x73\x47\xa8\x4c\x59\x1d\x5a\xf7\x72\xd4\x06\x7e\xba\x02\x5f\x1a\x18\x74\x0d\xd4\x92\x7c\x75\xec\xe9\x80\xf5\x7e\xab\xab\xff\x19\x7a\x42\x03\x55\xd8\x87\xf6\xf6\x13\x32\x7f\x37\x90\x06\xb8\x1a\x7f\x66\xfd\x9c\x33\xa1\xc6\xd0\xf7\x3e\xcb\x0f\x47\x51\xf7\x7f\x8f\x39\xe6\xa2\x3a\xf4\x6e\x55\x1e\x70\x57\x9e\x64\xd0\xb5\x51\xa9\x76\xbe\xc1\xdc\x1a\x95\xf1\x00\x08\x58\x82\x73\xf1\xbd\xac\xea\x76\xe9\x6c\xaf\xc8\xaa\xfb\xa1\x12\x90\x02\x67\xf9\x0d\x46\x7d\x45\x40\x14\x45\x43\xb0\x79\x59\xec\xf6\xcb\xdd\xc3\x7e\xbd\xe9\x0e\x19\x81\x0c\xfb\xf7\xab\x97\xed\x6e\xff\x7d\xb5\x7b\xb8\x7b\x99\x7d\xdf\xbf\xcc\x76\x7e\xfb\x81\x90\x28\x0d\x2e\xbc\xdf\xb5\xce\xa6\xad\x04\x4c\xd1\xc5\x17\x93\x0c\x42\x25\xd0\x79\xf5\x2f\x01\x65\x60\xf4\xf2\xd7\x11\x8a\x4b\xaf\xa4\x3b\xc7\xe2\x8f\xdb\x60\x09\xad\x7f\xf8\xc7\x64\x80\x96\xda\x46\x95\xc5\xc7\x0b\xa8\xec\xd8\x7a\x44\xcf\x1d\x26\xde\xfb\x04\x40\x19\xc3\x58\xe6\x70\xde\x36\x65\x05\xda\x2b\xd8\xf8\x4f\x04\x9c\x72\xdc\xd2\xff\x09\x55\x35\xc2\x40\x03\x4f\x88\x1c\xc2\xd1\x67\x79\xbe\x2b\x87\x30\x44\xe0\x52\x7b\x9f\x0c\x7b\x12\x2f\x75\xe1\x19\x70\xb0\xb5\xc8\x3a\x2f\xdf\x3a\x62\x32\x88\x38\x20\x3e\x66\xa6\x75\xe5\x7b\x60\x20\x16\x34\x71\x34\x9d\x5f\xa0\x80\xad\xca\xc0\xca\x03\x57\x17\xfc\x05\x10\xab\x04\xeb\xca\x6e\x4d\x78\xff\xea\x93\xe2\x0f\x24\x2c\x42\x67\x59\x95\x85\xc9\xaa\x03\x20\xda\x76\x08\x4a\x84\x44\xda\x5e\x8a\x37\xc7\xfe\xda\x6e\x27\x36\xfe\x9b\xe4\xb2\x21\x4d\x13\xd5\x09\x73\xd4\xef\x7d\x66\x0b\x52\x2d\xb0\xd8\x88\x01\xf2\x42\xe4\x17\x14\x81\x6e\x9c\x48\x34\x22\xad\xee\xcb\xaa\x29\xb2\x06\x7a\x31\x55\x06\xc2\x10\xb0\xdd\x4d\x85\x9e\x0b\x7d\x65\x3b\x1f\x5f\x4b\x45\xc6\x52\x47\xe2\x06\xb9\x28\x8b\x06\x5c\x39\xb5\xbb\x61\x15\x5b\x79\xf2\x43\x56\xf4\x41\x12\x68\xc2\xbc\x54\x87\xdd\xa8\x66\x79\x26\xea\xfb\xf2\x3a\x1f\x35\x03\x1d\x6a\x0b\xe5\x2b\xb2\xe6\xa2\x3f\x6c\x3a\x96\x6a\xcc\x14\x6c\xca\xfc\x3c\x2b\x44\x7e\x6e\xb2\x5f\x23\x44\x47\x37\x0e\xd0\xa7\x9d\xcf\x16\x5f\x5f\x37\xfb\xdd\xc3\xcb\xb2\x5b\x73\x5a\xc4\x84\x3a\xcf\x72\xf7\xb3\xfc\xde\xbf\x22\xad\x42\xec\xb5\xfb\xbe\x7a\xf6\x28\x0f\x80\x20\xb0\x5a\xdd\xe7\x27\x68\xde\x07\xc2\x68\xa3\x09\x09\x51\x08\x76\x1d\xab\xb2\xd0\xdf\xc5\x0f\x18\x56\x4c\x01\x52\xe9\x83\x91\x6f\x59\xd5\x9c\x7a\x69\xfd\xeb\x8f\x09\x52\x21\x7e\x60\xfb\x7d\xb6\x59\xac\x57\xcf\xff\xc7\x5f\xc8\x00\xc3\x29\xd2\xba\xb6\xbb\x12\xe7\xd3\x63\x76\x99\x22\xb6\xa3\x4d\x10\x53\x6e\x03\xec\x46\xbd\xaf\x5c\xd0\x65\xc5\x56\x7b\xba\x98\xcb\x49\xdd\x9e\x27\x5c\xe0\xdf\xfa\x35\x6b\xf3\x28\xea\x66\x9e\x79\x8f\xc3\x90\xd0\x10\xeb\xb1\x97\x26\x6b\x5a\xd3\x93\x15\x6f\x4f\x03\x20\xad\x1f\xc7\x53\xc4\x60\xc1\xaf\x06\x8a\x21\x4a\xd2\x10\x50\xd4\x09\x69\x21\x85\x15\xd4\x75\x67\x70\xfc\x98\x50\xd9\xa4\xbd\xad\x40\x0f\x94\x37\x98\xa1\xa1\x6d\xe9\xb2\x4e\xc4\x83\xe5\xaf\x1d\x1b\x77\x43\x39\x67\xa9\x67\xf0\xf8\x63\xfa\x88\xa8\xd5\x65\x23\xd9\xf6\x85\x40\xd1\x64\x0a\x16\xef\x30\x45\x0c\x18\x96\x10\x65\xbb\xcf\x84\xca\x61\xd5\xfc\xeb\x04\xd5\xf9\x3a\x5d\xe4\xd5\x9d\xc3\xb0\x44\x7a\x67\xe3\x7b\xfb\x1d\xa6\x9e\xa8\xe1\x8c\xe1\x3e\xd7\x6d\xec\x48\x51\x3a\x86\x14\x19\xce\x01\xd1\xc0\xef\x48\xa8\x39\x90\x28\x77\xc7\x23\x62\x59\xef\xbe\x40\x73\xb7\xde\xbd\xc0\x8f\xf2\xa3\x35\x34\x98\xf8\x1b\x66\x5f\xfc\xda\x35\x11\x07\x88\x7d\x49\xe4\x03\x8a\x3b\x50\xd9\xc0\xe9\x34\x51\x1a\x08\x44\x5a\x57\xe7\x63\x53\xfe\x14\xd5\xe0\x48\x64\x5c\x98\x89\xb7\xfa\xbb\x7c\xdd\x00\x94\x62\x62\x4a\xb0\x2b\x65\x93\x0b\x05\x03\x32\xac\xa1\x6b\x61\x62\x46\x75\x57\x9d\x3b\x0a\x05\x53\x5a\x26\x13\xb3\x28\x8d\x5d\x39\x4a\x0a\xf5\xf1\x45\xd4\xa3\xf9\x11\x8b\x14\x83\xf5\xef\x22\xb3\xcd\x2d\x53\x44\xb2\x49\x42\x6e\x59\x57\xf3\xb2\x86\x41\x5e\xcd\x24\x06\xd0\xd9\x5e\xea\x37\xa4\x42\x74\x0a\x76\x7f\x2b\xe4\x31\x29\xd1\x58\xbe\x6d\x4d\xd9\x6f\xa2\x63\x7f\x46\x1c\xa0\x5f\x21\xac\x0b\x0b\x28\xe1\xb6\x36\xce\x81\x9a\x18\xcc\x6e\xf6\xa6\xa9\xc4\xee\x82\xc5\x7b\x66\xdb\x94\xfc\xdd\x8b\xc8\x50\xe9\x72\x42\x59\x05\x1a\x91\x02\xf5\x32\x17\xc7\x1a\xf4\x7d\x59\x7d\xcb\x54\xd3\x17\xa4\x8d\x90\x32\x71\x6d\x68\x28\x79\x77\x5b\x36\x80\x19\xa1\x23\x2c\x92\xb8\x80\x08\x61\x17\xfd\x0e\xe9\x06\x49\x1e\xa1\x0b\x6b\x51\x8c\x3b\x07\xb4\xfd\xfc\xa5\xa9\xd0\x76\x6f\x41\x25\x06\x8a\x64\xcc\xa8\x88\x7b\xe5\xa1\xd5\x05\x91\x90\x1f\x13\x07\xc6\x0c\xf0\x5d\xeb\x01\xaf\x3a\x33\x4a\x26\x81\xab\x74\xd5\x30\xc1\x7c\x74\x43\x14\x66\x70\xad\x1f\x55\xfe\x5c\x56\x2a\x0c\x3e\xdf\x19\x8d\x0e\x04\x77\xc1\x90\x17\xbd\xbd\x2f\xbb\x77\x31\x82\x8e\x1a\x1d\x4a\xcc\x47\x3c\xa3\x57\x2d\xf2\x41\x6d\xdb\x68\xce\x13\xdb\x5d\xfd\x0b\x5d\xb7\x6b\xe4\x79\x46\x47\xa0\xd2\x4e\x01\xbc\xcf\x5d\x19\x88\x43\xa7\x45\x80\xe9\xbf\xd7\x02\x73\x9f\xfd\x51\xab\x50\x9b\xd5\x2f\xf0\x76\xca\x45\xb5\xae\xe6\xa5\xa8\xb4\x13\xd9\x19\x7f\x5a\x48\x00\x1b\x5f\x1c\xd2\xe9\x56\xc7\xc9\xa7\x66\x0e\x4c\x84\x53\xbf\xdb\xc1\x27\x08\x39\x37\xcc\x28\x81\x2e\xf7\x8f\xac\xce\x9a\x4e\x84\xd1\x3f\xac\x01\x81\xfe\xcb\x71\xc0\x31\x6a\x9f\x88\x07\x01\x67\x69\x8f\x4e\x5e\x16\x4d\xd6\x9c\x9f\xa1\x17\x21\xea\xbe\x3b\x0f\x02\x50\x1e\xdb\x7e\xf7\x20\x1c\xa8\xdd\x7d\x72\x1e\x90\x20\x21\xce\x3f\xd9\x5b\x38\xfe\xd5\xc9\xc5\x03\x12\x46\xd8\xca\xfc\x75\xf9\xf2\xbc\x7c\xdc\xcf\x36\x1b\x7f\x2f\x24\xb6\x48\xed\x4e\x6d\xf5\x24\x3b\x7d\xe6\xab\xa0\x22\x1e\x10\x23\xac\xd0\x57\x95\xbd\xbd\x41\xf5\x02\xc8\x47\xe7\x95\x39\x6d\x82\xe5\x96\x8f\xc4\x83\x50\x59\x0a\xa5\x36\x62\x9d\x0f\x44\x6c\xd0\xff\xbe\xe6\xcc\xf2\x80\x92\x10\x41\x72\x32\x07\xa1\xde\x67\xc7\x23\x88\xaa\x6b\xba\x9b\x72\x05\xf0\x80\x6a\x05\xfd\xeb\xed\x3a\xe7\xa6\xbc\xd0\x64\x7a\x67\x3c\xd4\xbe\xb4\xee\x81\x72\x2f\xc8\xd8\x53\xfb\x97\xc5\x69\x8c\x52\x2a\x8e\x38\xda\xd1\x3a\x62\x67\xe0\xf5\x57\xc5\x59\xa0\x8c\x13\x52\x79\x12\xbf\x7c\x3d\x7c\xf2\x7c\x3c\x0d\x90\x3e\x64\x00\x95\x79\x14\xd5\x1b\xdc\x82\xca\xf0\x80\x2b\xc6\x86\x6c\x06\x7a\x79\x85\x62\x82\x07\xdc\x50\xef\x38\xe0\xf3\x3c\x61\x63\xc0\x8d\x0f\x13\x85\x21\x5a\x50\xab\x13\x71\xd7\xe9\x6b\xf2\x20\x4a\x04\x8a\xa2\xdb\x5a\xc1\x05\x8e\xc4\x8f\x92\x06\xb7\x61\x4f\x7e\x38\x3f\x6f\xcf\x07\x59\xe6\xc3\xdd\x9d\x07\x31\xd3\x48\x55\x38\x10\x6a\xb8\xd1\xa3\x34\x3a\x2d\x61\x32\xb0\x55\x93\xe2\x24\xf2\xf5\x0f\xa8\xaa\x4c\xc3\x52\x23\xae\xfc\x21\x7b\x6b\xdd\x9d\x79\xa6\xf5\xcd\xa7\x4b\x23\x83\xcf\xf0\x15\x9d\x80\xa3\xfd\xbe\x4f\x1d\xf8\x8c\x07\xa9\x21\x18\xac\x6d\x1f\xbb\xb5\x21\x88\xcd\x42\x3b\x01\x24\xb8\xee\x2b\x0d\x56\xab\x48\x34\x7a\x89\x59\xed\x7c\x9e\xeb\xf3\x59\xa4\x14\x99\x71\x36\xeb\xe5\x9f\x57\x95\x8d\xfd\x38\x15\x20\x0a\x60\x7e\x3a\xbf\x94\xf5\xa0\x11\x85\x07\x92\x58\x80\x7f\xe3\x51\xc0\xb4\x3b\x42\x39\xce\xfe\x79\xa6\xb7\xe2\x87\xef\x92\xe1\x81\x54\x1c\xdf\xe0\xec\x20\x45\x5d\x0b\xed\xd5\x6b\x78\xa0\x52\xee\x91\x2c\x4f\xe2\xd7\x2d\x86\x1a\x1e\x28\xd5\x35\xac\xae\x4f\xcd\xb6\xa9\x40\x1c\x26\xfe\x0c\x0f\x34\x97\xe8\x64\x3e\x7a\x6d\xbf\xee\xc6\x34\x84\x68\xf5\x96\xcd\x3b\x06\x0c\x5b\x10\x95\x7a\xff\x67\x29\xa7\xaf\x47\x83\xb0\x3d\xab\xa5\xce\xcc\xf9\x33\xcd\x2d\x1e\x40\xac\x11\xe4\xb6\x78\x59\x7f\xbf\xdb\xce\x1e\x97\xfb\xc5\xe3\x7a\xbb\x7a\xfe\xb2\xdf\xad\x3c\x65\x01\x0f\x20\x21\x91\x1c\xc6\x71\x5b\x10\x39\x68\x5f\xfa\xc0\x0c\xc2\x6d\x8b\x05\x49\x8c\xfb\xd6\xf1\x5c\x89\x43\xd6\xbd\x50\x30\x69\x44\x7c\xbf\xe7\xa2\xac\x2a\x50\x7d\x31\xc5\x8d\x31\x40\x98\xa3\x45\xf1\x9a\x4d\x43\x23\xff\x99\x60\x97\xbd\x02\x09\x02\x89\x99\xe5\xa3\x77\x33\xaf\xf0\x74\x70\x12\x84\x06\xb3\xe1\x9b\x97\x25\xbe\x84\xed\x6e\xf6\xb2\x1b\xbe\x02\x12\xc4\xb6\xe7\x62\x50\xf6\xb4\x65\x19\xd0\x33\xd3\x40\xb5\xac\x95\xc8\x2f\x13\x8f\x9c\x90\x30\xc0\x79\xf3\xe7\xe2\x79\x37\xdc\xc5\x08\x09\x63\x5f\x97\xdf\x8a\xbc\xe3\x04\x44\x27\xd5\xc2\x3a\x47\xaf\x91\x10\x6a\xe5\x50\x2c\x49\xdc\x8f\xc5\x84\x2f\xd9\x8f\x4a\x25\xa2\xd6\x94\xc5\x0c\xb8\x36\x31\x27\x13\x3e\x1d\x2b\x6d\x75\xee\x90\x15\xf3\xd3\x19\xb1\x1f\x87\x3e\xd2\xe0\x24\x4c\x24\x1a\xf4\x85\x38\x1c\x45\xf6\x56\xbc\x40\x7d\x3a\x4c\xfc\x67\x4e\x68\x6c\x98\xbb\xaf\xf6\x39\xea\x4d\x76\xbc\x8d\x95\x73\xe7\xf8\x50\xaa\x81\xba\xb1\x30\xc2\xce\x67\xea\xdd\x7f\x4e\x98\x88\x24\x1b\xa4\xb6\xfa\xec\xd2\xf8\x72\x3c\x88\x8c\x4f\x68\xdc\x8b\x6a\x94\x22\xe2\x24\x22\x80\x58\xf0\x87\xaf\x77\x0f\xbf\x63\x04\xe0\x24\x12\x24\x31\x5d\x5b\x09\x32\x41\x5e\x7b\x77\x91\x70\x71\x27\xee\x64\x8f\x65\xd3\x40\x4f\xb8\x70\xd5\x31\xe2\x24\x52\x91\x72\xcd\xe4\x8e\x06\xdb\xbf\xe9\x48\xc7\xd4\x42\xc8\xd5\x09\x77\x71\xbb\xa4\xb0\xed\xab\xab\xe6\xb7\x13\xfe\xea\x8e\x4d\x62\x66\x02\xd7\xac\x81\x4e\x97\x75\x9e\xc7\x37\x9c\x84\x10\xdb\x5c\x69\x61\xbf\x32\xf3\x3f\x9e\x70\x8d\x5e\x77\xbb\x3d\x8d\xf4\x96\x39\x49\x43\xa3\x6c\xbb\x53\x7d\x6a\xff\x7e\x57\x09\x33\x9d\x71\xa9\xa0\xf1\x50\x64\xf8\x05\x70\xad\xed\xaa\x13\xbc\x6e\xef\xfc\x95\x44\x62\x6d\x31\x56\x14\xf6\x3f\xb3\xa2\xde\x77\x49\x5f\x4e\x84\x30\x88\xc3\xd0\xfe\x03\x6f\x04\x2a\x3c\x61\x2e\xd3\x0f\x92\xdc\x24\x9e\x59\x7e\x6f\x3a\x6e\x62\x4e\x14\x11\xb6\x0a\x80\xf0\x88\x1e\x26\xce\x89\x8a\xed\x0c\xaf\x01\xf4\xfe\x60\x01\xad\x99\x4f\xc8\x71\xa2\x29\x4f\xdc\xfe\xfe\x5a\xc3\x72\xb5\x89\x49\xd8\x47\x0d\x9c\xe8\xc4\x18\x0f\x58\x13\x3f\x26\x93\x0e\xa8\x76\x5d\x1b\x23\xd1\xca\x11\xf8\x62\x32\x01\x40\xa7\x88\x07\xf8\x89\x30\xe6\x2d\x34\x57\xda\xa1\x39\x31\x82\x4a\x4f\x22\x78\x2f\xb2\xfc\x16\x53\xe9\x20\x57\xca\x89\x91\xb6\xe9\xac\x75\x65\x9b\x4a\x64\x45\x56\xbc\xed\xb3\x3e\x88\xe2\x61\x10\xc4\x24\xe9\xa3\x04\x54\x09\xbe\x56\x7d\xe6\x61\x90\x86\x58\x5e\xde\x54\x70\x14\x15\xbc\x94\xf9\x98\xc5\x96\x87\x81\x34\x68\xd4\xea\xf7\x93\x31\x9e\x53\x80\x87\x81\x0e\xc1\x22\x88\x85\x46\x37\xa6\x2a\xf3\xbc\xfe\xb3\x7d\xbc\xf1\x33\x86\x21\x11\xd8\x08\x80\xc9\xab\x0e\xf7\x8a\x90\xe3\x09\xde\x98\x87\x21\x95\xd8\xc5\xa5\xcb\xa2\xdb\x74\x43\x4a\x63\x6b\xbb\xc4\x5b\xa6\x8a\xd3\xa1\xce\xde\xba\x43\x2c\xc1\xa4\x41\xd5\x7a\xaf\x50\x2d\x7d\x43\x26\x0f\x19\x4d\x02\xd7\xfb\xb9\x5f\xfe\x52\xef\x6f\xfb\xf9\xc7\xdb\xe2\xfd\x76\x57\xe4\x55\xeb\x15\x32\x6e\x85\x7d\x6b\x28\x5a\xc7\xf1\x66\xfa\x8c\x63\x73\x64\x8c\x59\x00\x0d\xbf\x7e\x64\x30\xf1\x5c\x43\x96\x26\xc2\x35\x25\xbd\x56\x63\x4f\xaf\x75\x3f\x3d\x85\xcc\x97\xbc\x94\x22\x1f\xd5\xdb\xc6\x7b\x6c\xc8\x85\x88\xbd\x42\x36\xee\x20\xdc\x3f\x33\x37\x5c\xf5\x38\xd6\x79\x76\x81\x35\x72\xe3\xa2\xc8\xa4\x91\xa3\x72\xf8\x69\x83\x76\xec\x0d\x6f\x72\xf8\xe3\x4a\x8d\x8a\x87\x91\x4e\x71\x96\xa8\x7c\xa8\xab\xc2\xc3\x98\x52\x22\x47\x9a\xb7\xb6\xb3\xc1\x91\x7c\x4e\xb8\x45\x3e\xad\x71\xe3\xc5\x4c\x2f\x2b\xde\xc6\x91\x68\x1a\xba\xdf\x4a\x22\x74\xa9\x30\x9d\x86\x9b\xe6\x36\xfb\x0b\x56\xc5\x20\xed\xce\xc3\x24\x20\x91\x75\x99\x51\xa6\x69\xdc\x73\xf3\x09\xe1\xff\xe4\x56\x92\xd8\x16\xab\xb0\xce\x0b\xf5\x97\xec\x47\xb7\x97\x87\xa9\x4c\x83\xd8\x6b\x4d\x9f\xf2\xc6\x53\xf6\x8d\xaf\x90\x6a\x2b\x4d\x64\x4e\x1d\xa3\x36\x0f\xa5\x88\xad\xb4\x43\x0d\x95\xe5\x04\x1f\x49\x4b\xf8\x51\x32\xc5\x6c\xef\xe6\x61\xbd\x7c\x5e\xfd\xb9\x5f\xac\x5f\xb6\xb3\xd5\xcb\x7e\xf9\xe7\xee\x65\xb6\xd8\xad\xd6\xcf\xfb\xf9\x6c\xeb\xbd\x95\x50\x49\x66\x86\xea\x84\x9d\xec\xf8\xe4\x51\xbb\x89\xaa\x94\xf0\x0a\xbd\x88\x0a\xb2\xbd\x08\xf3\xae\x37\x9a\x87\x0a\xb4\xa2\x7e\xd2\x23\xf5\xe0\x4f\x18\x64\xed\xae\x6c\xa5\xa1\x26\x1c\x27\xe5\x30\x07\x36\xe8\x6f\xff\xfc\xcb\xeb\x18\x24\x1d\xa3\x76\x10\x3a\xb0\x1a\xda\x34\x2d\x15\x8d\x06\x01\xda\xa6\x2c\x73\x87\xa8\x1b\x5f\x0d\x58\x20\x49\x97\x95\xaf\x37\x50\xfd\x1b\x44\x37\x43\x40\xcb\xd8\x5d\xe6\x75\x55\x34\xc9\x55\xb4\x9a\xdb\x6c\x43\x43\x18\x76\xd8\x62\xfb\xff\x15\xac\x2c\x0f\x8d\x83\x6c\xe5\x65\x0d\x55\x27\xdd\xcd\x43\xc3\x52\x04\xfe\x3b\x9d\x37\x1b\x22\xaf\x8a\x79\xd1\xd8\xff\x9e\xba\x74\x93\x37\x62\x24\xc5\xca\xa8\xbb\x29\xfb\xaa\x47\x49\x2c\x4e\x83\x24\x45\x1e\x80\xfa\xf0\x6b\xd7\x0b\xb0\xfc\xe1\x8f\x2a\x0b\x95\xae\xc4\xa4\xbd\x9f\x53\x12\x19\xe3\x80\xcf\x73\x68\x5e\x33\x87\xc2\x4f\xfe\xd1\x3f\x39\x25\x82\x7a\xc8\xda\x1d\x58\x71\x0d\xd0\x2f\x70\x2c\xab\xc6\xf5\x2c\xde\x9d\xa0\x23\x04\xf2\x3f\x1a\xc6\x12\xa1\x5e\x39\xee\x5f\x98\x55\xdb\xfd\x1a\x21\xe8\x39\xa5\x52\x22\xd3\x92\x16\x8d\x58\x40\xd1\xd8\x4c\x46\x77\xd4\x98\xd4\xc9\xdf\x5b\xb2\x1b\xd7\x3b\x7c\xcb\x6a\x0f\x27\x21\x65\x41\xec\xc8\xde\x2d\x4b\x7b\x47\x76\x32\xb9\x05\xc6\x53\x70\x5d\x0a\xf5\x16\x90\x0b\x15\xb0\x29\xc3\x7a\x44\x58\x2b\xf9\x95\x1d\x44\x03\xbe\x45\x84\x53\x4e\xb8\x76\x28\xd1\xea\x04\x7a\x7e\x42\xd5\xff\xd1\x64\xa0\x5c\x12\x04\x10\xd8\xec\xf9\x3f\xb3\xe2\xad\xa3\xbf\xe3\x94\x6b\xcd\xdd\x24\xef\x12\x88\x3d\xe8\xdf\x8b\x5f\x21\x87\x61\x8f\x27\xea\x4e\x36\x71\x34\x54\xb1\x68\x4f\x1c\xc2\xd5\xae\xc0\x64\x39\x8d\x48\x10\x75\x52\x84\x06\xaa\x4a\xe4\xdb\x46\x34\xa7\x49\x10\x49\x23\x1d\x63\x51\x1f\x0a\xbd\x36\xbd\xc9\x74\x47\x13\x16\xc7\x81\x43\x7a\x57\x3f\xc0\xa1\x2e\x3a\xa3\x46\x93\x18\x30\x61\xdb\x88\x3c\x3f\xef\xde\x11\x9e\xd3\x3d\xb4\x90\x86\x89\x9e\x78\x1e\x83\x86\xfb\xb2\x9a\x61\xdf\xf8\x94\xf6\x92\x53\xa9\x38\x3a\xae\xca\x16\x3b\x3c\x8e\xd8\x1f\xd5\x31\xd2\xa7\x61\x14\x79\x7d\x6b\xa3\x2a\xb1\x0e\x84\x63\x2d\x1e\xe9\x78\xfa\x21\xc2\x4e\xb1\xd6\x90\x88\xfa\xa3\xbe\x9a\x78\xa0\x3a\x21\xe8\xbf\x6d\xc5\x8f\xac\x78\xab\x51\xbb\xc9\x1d\xc2\x4a\xf8\x80\x92\x7f\x7b\xac\xb2\x06\x6a\x94\x52\x9d\x9f\x2f\xfa\x1b\x39\x85\xd8\x82\xe5\x25\xa8\xf2\x00\x1b\xa1\x32\x93\xd5\xcd\xc1\xf6\x30\xfa\x31\x52\xa7\x36\x1f\xb2\xcb\xa0\xfa\x67\x99\x15\x93\x2c\x2a\xa7\x26\x08\xd3\x01\x78\xc3\xae\x8c\xcd\xe2\x8f\xee\x30\xe7\x2e\x72\xb7\x74\xa7\xcb\xce\x6d\xa6\x26\x4c\xb0\x1f\xaa\x34\xd8\x89\xd9\xe5\xe2\x6e\xc0\x1f\xfe\x71\xcd\x4c\x53\xc3\x15\x46\x2e\x42\xeb\xa6\x7c\x44\xe5\x4f\x59\x7a\xfb\x3b\x6e\x68\x75\x99\x70\x4e\x4d\x92\x4a\x57\x2c\x5e\x0c\xf4\x52\x5e\xb7\x77\x0e\xa9\xcb\x59\x10\x08\xd4\xcc\x91\xa7\xf3\xe6\xf4\xd7\x5f\xee\x6e\x12\x7f\x34\x04\xc4\x20\xfd\x50\xbf\x06\x2c\x90\x9c\x05\x2c\x64\x0e\xa1\x08\x06\x37\x8a\x55\xf1\x82\x78\xb5\xd1\xd9\x11\x4b\x02\x5f\x8b\xd4\x0e\x41\x35\x7a\x2a\x16\x28\x86\xad\xb2\x47\x4c\x6f\x14\x83\xee\x67\xce\x08\x68\x6c\x9a\x29\x0d\x54\x8d\xf0\x7f\xa5\x3c\x46\x8f\x78\x20\x8c\xe4\xda\xc9\xc6\x57\x66\x34\x35\xe0\x1d\xdf\x0f\x28\x2e\x6a\xb6\x7e\xd6\x32\x96\x2a\x4c\x51\xcd\xaa\x06\x4e\x43\xf6\x2f\xce\x78\x94\x44\xb6\x6d\x6b\x5f\xe7\x65\xb3\xcf\x8a\xbd\xcc\xf4\x65\x63\xa2\x1f\x2e\x02\x24\x5e\x7d\x5a\x2f\x47\x97\x89\x08\xc5\x9c\xde\xd3\x76\x73\x51\xb2\xe5\x2c\x62\x29\x46\xff\xb3\xd7\xc5\xa2\x3b\x83\x73\x9c\x6d\x77\xe0\xa1\xbc\x9c\x45\xda\x66\xc0\x7f\xfc\xae\x41\x89\xb3\x98\xc5\x98\xf9\xc6\xc5\xda\x19\xbc\x4f\xe4\x1c\x39\x8b\x23\xf0\xcd\xd5\x4d\x0e\xb3\x42\x7b\xf3\xb8\x30\x7a\xc4\x05\xc0\x59\x12\x04\xb8\xcc\x1d\x63\xde\xb6\x97\x90\xe7\x2c\x91\x96\xd9\xc5\x9f\x2d\x72\x27\xd9\x67\xc9\xae\xa7\x53\x7d\x60\x31\x59\xca\xd3\x34\xe9\x70\xc5\xd9\xe1\x74\x58\x94\x45\x7d\x3a\xa0\xbb\xd6\x13\x33\x73\x96\x26\xc4\xb3\x58\xcf\x4f\x67\x9f\xab\xe8\x75\x8a\x3d\x91\xec\x75\xcd\x7e\xce\x52\xa1\x31\xf3\xf0\x34\x7b\x7e\x98\xed\x76\xb3\xe7\xcd\xcb\xfa\xcf\x7f\x2f\x9e\xbf\x3d\xef\x66\xdf\x96\xdd\xaf\x80\xf5\x64\x50\x86\x43\x7d\x80\x1e\x87\xec\x4c\xb0\xc8\xa0\xb1\x3b\xab\x1c\x9e\xda\x70\x60\xd0\xd5\xc8\x99\xa4\x41\x68\xa3\xd6\x1f\xe5\x47\x6b\xb8\x9f\xce\x9e\x9d\x9e\x33\xa9\x2d\xc5\x85\xc3\xa4\xe3\x1e\x3c\xbe\x47\x15\xdb\x5a\x70\x27\x4c\xdf\x35\xc8\x74\xf3\x56\xa5\x44\x7a\xa5\x8d\x79\xd6\x3c\x97\x6d\xa0\xeb\xf9\x63\xdd\x98\x36\x4e\x0c\x5d\x8d\x1a\x0e\x65\x9e\xd5\xef\x8b\x41\x8b\xfe\xe4\xc5\x68\xa1\xd0\xe3\xba\xcd\xc6\x33\xda\xf2\x99\x56\x06\x42\xf4\x38\xea\xa1\x08\x8c\xb8\x84\xce\x73\x66\xb4\x15\xbc\xf3\x9b\xe8\xeb\x62\xb6\x7d\xb8\x3e\x17\x79\x40\x22\xcc\x5a\xe1\xf4\x5d\x99\xe5\xaf\x63\x5e\xea\x6e\x2b\xe2\x41\xcc\x84\x0b\xd8\x9e\x30\xcd\xde\x19\xb7\x1b\x50\x4c\xce\x03\xc5\x10\xe7\x6d\xf5\x03\xf7\x7d\xbe\x84\x93\x84\x27\x2e\xa5\x73\x9f\x8b\xb7\x71\xb1\x92\xf3\x90\x12\xe4\x15\x69\x1f\x11\xe3\x9e\x21\x9d\x34\xe7\x94\x09\x84\x65\xd4\x1e\x82\xf4\xe2\x20\xff\xdd\x80\xd8\x4a\x16\xcf\x2a\xf1\x56\x16\xa3\x29\xc2\xa9\x50\x81\x1e\x7c\x63\x7d\x51\x7d\xf6\x03\x21\xc0\x3c\x3c\x6e\x72\x4f\x65\xd5\x75\x13\x70\xce\x04\x45\x21\x81\xff\x9e\xa0\x3a\x3b\xff\x7d\x57\x09\x64\x72\x19\xe0\x61\x38\x67\xd2\xd2\xa7\x7d\x7c\x7c\xf4\x0c\x8f\xd7\x7f\x8e\x47\x04\x4b\x82\xb3\xf5\xd7\xcd\xec\xdf\xfe\x02\x51\x62\x10\xda\xb7\xdf\xb7\xeb\xae\xf7\x92\xee\xcb\xea\x4e\x58\x96\x8f\xfa\x0a\x63\x2a\xe7\x91\x04\x4c\x1a\x1a\x00\xdc\xc8\xc7\x47\xe3\x20\x42\x7f\xd8\xb2\x92\xd7\x36\x76\x0d\x6f\xdc\x59\xcc\x45\x60\xd1\x62\xe3\xc5\xc8\xe3\x34\x46\x1b\xaa\x44\xae\x4e\xad\x03\x7c\x57\x9d\xde\xe6\xa7\xb3\x8d\x88\xc7\x6b\x8b\x27\x41\x84\x18\x9d\xd6\x09\xde\x96\xa7\x4a\xc1\x17\xb0\x22\x5c\x6b\xb3\xcd\x7e\x35\x00\xc5\x15\xc1\x0a\xce\x13\x6a\xb1\x57\x7b\xeb\xe2\x4e\xf4\xc2\xfc\x20\x0e\x58\xd6\xd0\x99\x38\x94\x85\xc6\xcd\x71\x57\x5a\x04\xd0\x34\xa5\xcb\x93\x84\x59\x96\x7f\xa7\x95\x75\xbe\xa4\xb2\xe0\x3c\x85\x00\x35\xc6\x2b\x14\x6a\xf5\xe0\xf5\x0b\xfe\x25\xce\xa5\x4e\x91\x2f\xbb\x8d\x18\xe6\xe7\x79\x95\xe9\xee\xfd\xa8\x24\xc4\xfc\xbe\x18\x48\x4d\x6d\x2a\xe8\x79\x2a\xdb\x21\xc6\x92\xad\x43\xdd\x9c\x77\xbd\xc3\xce\x21\x34\xa8\xa4\x24\xf4\xff\x9e\xea\xe6\xae\xcc\x73\x61\xb9\x6f\xa0\x7a\x11\x4d\x56\x4e\xee\x02\x18\xb3\x7c\x97\xc8\x00\x90\xd5\x5d\x64\xcb\x81\x45\x58\x7c\xef\x72\x27\xdd\x01\xa1\xac\xcc\x12\xfc\x7c\x71\xf9\x87\x9b\xc4\x62\x9c\x9b\x24\x04\x6b\xfe\x45\x3e\xe8\x73\x1b\xad\xdb\x28\xe0\x0a\x43\x28\xcf\x6e\x6e\x3c\x07\x34\x8f\x02\x61\x5b\xdf\xde\xcb\x53\x0d\xd0\x11\xec\xf3\x28\x90\xb6\x57\xbe\x9b\x44\x1b\x71\xb6\x2c\x4b\x55\x51\xf5\x8e\x49\x44\xa2\xc0\x37\xc0\x3c\x8a\x42\x1f\xd1\x3e\x63\xa7\xe8\x1d\x18\x28\x34\x54\xab\xbb\xc1\x06\xd4\xdd\x13\x49\x94\x70\x5b\xac\xcd\xf7\x0c\xc9\x03\x6f\x29\x3b\xf2\x88\x00\xa0\xed\x6a\x77\xdb\x36\x2c\x9a\x9f\xce\x3d\x43\xcf\xb8\x0c\x1f\xb5\x4f\x81\xf2\x7c\xed\x6c\xb6\xc4\xb1\xd7\xdf\x62\x14\x4a\x16\xc6\x4e\xc3\x28\x2b\xe0\xeb\x59\x8d\x17\x66\xd4\x06\xb1\xed\x2e\x69\x7e\x76\x5b\xf9\xf8\x4b\x47\x94\xcb\xa8\xaf\x5f\xcf\x45\x8d\xbd\xcc\x05\xa2\x5d\xae\xe5\x1c\x88\x3f\x91\x01\x41\x52\x55\xc7\x60\xe6\x3b\xf3\xc5\x00\x28\xc3\xa3\xd6\x39\xc4\xd0\xe6\x54\x15\xed\xda\xf0\x7f\x8f\xd2\x18\xfd\xf9\x4c\xaa\xae\xd7\xb6\xb3\xb7\x51\x1c\x02\x72\x4e\xad\x8f\x50\xcc\x33\x7d\xb9\x81\xfd\x1d\x54\x11\x8f\x62\x9a\x60\x2b\xfc\xec\xcb\xce\x5f\x39\x89\x80\xf0\xa1\xd4\x5a\xfd\x52\xaa\xd5\x64\x45\x47\x49\x0c\xe8\xea\x35\xa7\x02\x1e\x45\x6d\x83\x01\x9c\xec\x13\xfd\x26\x1e\xa5\x24\xc5\x2a\x85\xc9\x7e\x0d\xd6\x61\x94\xfe\x3f\xa4\xbd\x6b\x73\xa3\x48\xd6\x2e\xfa\x77\xfa\xc3\xfb\x01\x48\xc8\xcb\x47\x59\x96\xab\x34\xed\xdb\xb6\x54\xd5\x3d\xef\xc4\x84\x22\x2f\x2b\x6d\xb6\x11\x68\x00\xb9\xec\xf9\xf5\x27\x58\x99\xc9\x4d\xd8\xdd\xe7\x9c\x1d\xb1\xdf\xea\x31\x09\x82\x24\x59\xb9\x2e\xcf\x7a\x1e\x4a\xf0\x15\xf6\x3b\xce\x41\xc6\xd1\x77\xd9\xbc\x1c\xfc\xe9\xfd\x40\x46\x42\x26\xfa\x36\x6f\x5b\xcc\x5a\x8e\xbd\x74\x2a\xb8\xe1\x8e\x55\x3e\x94\x4d\xc2\x01\x6d\xd0\xad\x97\x4d\x93\x37\xad\x1c\xce\x90\xc2\x7d\xea\xce\x63\x87\x11\x13\x4c\x46\x15\x37\xe8\x50\xef\x6b\xf9\x06\x85\x96\xcd\x4b\x7f\x44\x3b\xda\x14\x74\xb5\x43\x83\x59\x38\x66\xa4\xf4\xf1\x5e\xb0\x18\x13\x96\xff\x8c\xea\x48\xa0\x2f\xf4\x54\x61\x97\x57\x55\x15\x43\x14\x3c\x5d\x91\x3a\x8e\x10\x2b\x7a\xc4\xe9\x4f\xa2\x24\x1e\x14\xea\x86\x15\xa0\x49\x42\x92\x20\x60\x03\xdb\xf5\x03\x42\x78\xbc\xef\xbb\xfc\xb6\x75\x66\xb5\x53\x03\xa9\xf2\xe6\xef\xd1\x94\x65\xd4\xd8\x14\xad\x00\x32\x54\x36\x27\x79\x74\x6d\x0b\xe1\x36\xac\x10\xd8\xb7\x57\x61\x23\xfc\x7f\xa1\x6e\x0e\x27\xcf\xba\x10\x46\xc8\x24\x9d\xc2\xf9\x3f\xeb\x78\x08\x27\x80\xe6\x61\x65\xec\xd0\xce\xf8\x4b\xb1\x48\xc7\xd8\xea\xfc\xed\x6a\x54\x7b\x67\x11\x90\x20\x9d\xb9\x0c\x6e\xf3\xe3\x62\x99\x22\x0b\xf8\x9d\x7c\xbf\x82\xd6\xcd\x94\xdb\xc9\x67\xab\x9b\x91\x18\x10\x04\xf8\x9f\x73\xde\x76\x7b\xf9\x70\x07\x24\x8d\xd1\xb6\xf9\x98\x00\xd7\xe1\xbc\xe6\xce\x88\x94\x58\xc9\x29\xc1\x81\xe7\xe7\x87\x35\x24\x63\x60\x46\xe7\x1a\x5f\x7d\x8c\xf1\x94\x7e\x60\x4a\x93\xcc\xa7\xda\x7f\x56\x33\x9a\xc4\x8c\x65\x91\x2b\xfe\x38\xb3\xb4\x7e\xb1\x6b\x28\xdb\xc6\x17\x28\x66\x43\xa9\x11\x3e\x49\xf3\x07\xc8\x53\x55\x3e\xc9\x3a\x6f\x3f\xb0\xbd\xa1\x9b\xb1\xf9\xe7\xcd\x32\x93\xa2\xe8\xf2\xe6\x98\xb7\x1e\x3a\xb1\x7e\x91\x75\x7b\x0d\xad\xcc\x8b\x4f\x61\x77\xd3\x17\xc9\xa8\x64\x6c\x10\xfa\xf7\xf9\xfa\x2e\x6a\x59\x6a\xda\xcd\x18\x8b\x53\xa3\xa6\x9a\x0b\x4f\xa3\xb4\x5c\x18\xc5\x63\x60\x3d\x95\xf2\xf6\xf1\x66\xb7\x30\x73\x4c\x24\x42\xf5\x51\xde\x5c\x1e\xaf\x1f\x44\x6c\x2f\xf1\x54\x3a\xae\xb8\xaa\xde\x57\x67\xfd\xd2\x27\x97\x18\x8f\x63\x16\xa0\x0a\x55\xbb\x6a\x6e\xf2\x77\x30\x8f\x55\xee\x08\x29\xe5\x11\x2e\xe6\x8e\x33\xa7\xec\x90\xeb\x6a\xda\x4b\x9c\x31\x0e\x02\x4b\xf4\x4f\xdf\xff\x79\xff\x10\x5a\x35\x32\x26\x84\x8a\x7d\x44\xf8\xa3\xf4\xec\x0f\x66\x55\x8f\x9d\x0a\x26\x8c\x41\x89\xe1\xa1\x70\xb1\xaf\xbe\x57\x27\xb0\xe7\x62\x6b\x66\x79\x25\xa6\xb4\xa1\x72\x0c\x52\x98\x39\x0f\x53\x27\x82\x69\x42\x83\x83\xee\x5d\x6b\xef\x76\xde\x54\x75\xa8\xd5\xcf\x26\x58\x73\x8e\x79\x61\x7d\xae\xff\xcf\x59\x0e\x29\x26\x66\x88\x51\x1e\x93\x7c\x7f\x3e\xba\x28\x62\x96\x81\x63\x26\x1b\xaf\xdc\x1d\xa6\x30\x5d\x32\x7e\x79\x13\x67\x86\xa7\xb8\x47\xff\x2f\x3c\xcb\x7a\x99\x60\x71\xa1\x5e\xc0\x8c\x50\xa8\xc3\x7e\xb7\xbd\x47\xb6\x66\xc7\x54\x17\xee\x14\xa2\x0c\xd9\x54\xa5\x31\x2e\xf0\xed\xae\x7b\x3d\x9b\x49\x88\x2d\xf7\xf2\x66\x81\x6a\x3c\x1c\xc9\x34\xb2\x1c\x1c\x65\xab\x5f\x5c\x5b\x5a\x38\x62\x33\x64\xed\xf2\x6f\xd2\xa9\xc5\xcc\xb1\xcc\xfd\x58\x16\x39\xce\xc2\xa2\xd8\x5d\xb4\x4e\x7e\xb9\x79\x33\x2b\x1c\x85\x86\x6b\x45\xec\x3e\xe6\x71\xf2\x27\x0c\xd2\xdc\x23\x01\xda\x27\x47\x07\x88\xcc\x5b\x3d\xac\x79\x72\x49\x1e\xb1\x04\x5b\x63\x4d\xde\x74\xee\xde\x61\xe4\x0e\xf2\x48\x03\x4f\x7b\x2d\x57\xe4\x29\x96\x79\xf9\x60\x97\xad\x2d\x8f\x23\xc7\xa7\x6d\x5c\x52\x63\xdd\xf9\xd3\x2d\xd4\xb2\x08\xca\x62\x0f\x16\x25\x4e\x9b\xcb\x6e\x91\x45\xf3\xc0\xe3\xc8\x89\xd3\x35\x85\x7c\x03\x57\xe8\x7e\x9c\xec\x34\x3c\xe6\x2c\x0b\x85\xee\x43\x55\xba\x56\xe2\xcd\x7f\x7e\x74\xce\x69\x3f\x46\x3b\x35\x41\x9f\x4d\x68\x1e\xea\x1b\x99\x17\x18\xbe\x3c\x3c\x5c\xf5\xa3\x6c\x86\xdb\xf9\xb0\x67\x05\x8a\xe2\xf3\x1c\x37\x3d\x2f\x7d\xf1\x44\x59\xd4\xd4\x71\xab\xfb\x1a\x0a\x78\x96\x2d\xfc\x3e\xd0\x0d\xfb\x71\x24\xce\x30\x52\x5d\xed\xff\x9a\xd9\x3f\xe3\x84\x30\xfc\xfe\x47\x77\x54\x1a\x47\x82\x39\xee\xa7\xcc\x38\x91\x31\xf6\xb0\x55\x5e\x4e\x17\xbb\x0a\xfa\x94\x0c\x27\x2a\x81\xfe\x2d\xfe\x31\x16\xef\x5f\x15\x21\xda\xe6\x69\x22\xb0\xc9\xea\xdc\x40\x8d\x20\xc8\x6e\x61\x05\x2b\xfa\x89\xff\xce\x19\xa8\x20\x00\x80\x66\x7b\xf2\xf2\xb8\x15\x98\xa9\xf3\xea\x46\xab\x67\x28\xdb\xdd\x1c\xa9\xc0\x45\x62\x31\x3f\x1d\xc2\xc8\xab\x8f\x4f\x16\x97\x90\x36\xc0\x70\x7d\x8f\xce\xef\x67\x53\x35\x2e\x31\x7e\x41\xbe\xd7\xbf\x1a\x49\x63\xe3\x38\x09\xaa\xda\xa0\x8c\xc1\xbe\xda\x9a\x2e\x7c\xb3\xf9\x8c\x7a\x68\xb8\x75\x49\xb5\xa4\x21\xe5\x5d\xd5\x1f\x9b\xf7\x53\x1e\xa0\x39\x71\x12\x06\x41\x86\xf0\x01\x47\xcd\x3c\xad\xf7\xf9\x21\x2a\x93\x24\x1b\xcb\xb6\xef\x70\x73\x1a\x89\xc2\xf0\x7f\x25\x03\xb9\xfe\xe4\x3f\xfb\x4b\xe8\x88\x8e\xa0\x31\x7f\x59\x7a\xee\xcf\x33\xd2\x31\x7a\x60\xf8\xfd\x47\xcf\x77\x9c\x71\xc5\x33\x9f\xe4\xec\x6e\x1c\xb7\xd2\x05\x53\xca\x75\xe4\x1c\x02\x97\xf7\x6f\xcf\x0d\xe6\x39\x51\xa0\xc1\x04\x62\xd1\x7e\xa8\x6b\xe1\xf1\xd2\xb4\xdd\xc3\xce\xac\x1e\xd7\x89\xc4\xa4\x61\xe7\x53\xe4\x41\x49\x2b\xe3\x3a\xb5\x58\x58\xff\x12\x6b\x36\x5b\x09\x3a\x33\x98\x35\x68\x2a\xdb\xcb\x6f\x85\xeb\x19\x62\xb0\x54\xf7\x58\xc8\x8f\xef\xb2\x28\xc6\xc9\x6a\x6e\x64\xaa\x52\x0f\xe5\x09\x8d\x1c\xe1\x90\xc9\x30\x8b\x10\x22\xd1\xc1\x30\x5f\x86\xa2\x1c\x68\x84\xed\x31\x98\xd8\x99\x20\x2e\xb8\xa5\x0a\x37\x8f\x6f\xf9\x1b\x84\xe2\x98\x73\xff\x7d\x68\x30\x7b\x16\x6b\x52\x6c\xf8\xc4\x60\x2a\x1e\xb5\x1e\xbb\xe3\x22\x8e\x58\xe6\x77\xac\x75\x85\x96\x73\x86\x7c\x1d\x6f\xd1\x22\x4e\x49\xe2\xdb\xd0\x87\x22\x9f\xe8\x0c\x39\xed\x99\x04\xfb\x42\x5b\xb7\xd3\x7f\xca\x20\x1c\x4e\x05\x91\xc4\xfd\x52\xf1\x8a\xb2\xfe\x18\x01\x93\x78\xe5\x97\xed\xfa\x21\x7e\x1c\x81\x2e\x45\xaa\x1c\x41\x83\x43\x29\xed\x7f\x85\x4c\xbf\xa0\x19\x51\x7c\x6c\xd3\xf2\xaa\xf4\x4b\x2a\x8c\xd0\x02\x9b\x4e\x1c\xcc\xd8\x45\x38\x23\x56\xc3\x4c\x50\xa0\x89\xbe\x34\xf9\xd8\x94\x8b\x45\x67\x3f\x8e\x11\x40\x66\xe1\xf5\xf6\xe6\x69\xfd\xb0\xbd\x1f\x29\xef\x66\x82\x09\xc1\x03\x14\x61\x5f\xad\xe6\xe8\x24\xc1\xe3\xcc\xc9\x46\x14\x67\x0d\x7b\xe8\x4c\x61\xfe\x25\xe8\x4f\xf0\x24\xc3\x46\xc5\x20\x8f\x38\x94\x37\x04\xcf\x12\x3b\x64\x13\x02\x9d\xfa\xfc\x17\xa5\xab\x5f\x7b\xe9\xfe\xba\x3a\x56\x3b\x00\x33\x4e\xc5\x8d\x0b\x33\x7f\x83\x4c\x6a\x6a\x11\x84\x88\x0c\xc2\x58\xf1\x93\xb8\x39\x17\x16\xdb\xe0\x87\xaa\x49\x67\x7e\xc2\xc6\xc6\xff\x3d\x3f\x59\xd3\xc0\x64\xf9\x2c\x8f\xa0\x65\x8d\x46\x08\x39\xf5\x43\xf0\x3e\x3d\x43\x26\x1c\x71\xf7\x3f\xee\x6f\x1f\xd6\xbf\x1f\x1e\x37\x4f\xdb\x87\x90\x9a\x16\x2a\xd1\x48\x70\xd5\x13\x65\x3c\x0d\xe0\x9c\xa9\xe1\x10\x2a\x8b\x31\x70\x3f\x60\xdf\x61\x32\xf6\x4f\x84\xca\x28\x82\x11\x1e\xf7\xb7\xfd\x9f\x34\x0d\x20\x04\xdc\xc6\xdc\xee\xe0\x0f\xea\x28\xc3\x83\xd7\x9b\x9f\x87\xfd\xea\xcf\xc3\xf5\xf6\xe7\x76\xf7\xf0\xd4\x1f\x4e\x04\x38\x78\x1b\x7a\xd1\xa8\xbb\xdb\xbb\xb9\x42\x8b\x0c\x53\x3b\x87\x6e\xcd\xfc\x01\xea\x5b\x6e\xdb\xcf\xa9\x4f\x33\xa1\x01\xc0\x11\xb1\xbb\x4d\xd4\xed\xd9\x23\xc2\x9c\x4c\x98\x58\xa3\x41\x82\xf6\xe5\x60\x5c\xcb\xdc\xa1\x0c\xf4\x24\x99\x30\x84\xe8\x38\x70\xd5\x74\x36\x78\xe6\x55\x0b\x50\x22\xf3\xc4\x10\x6f\x79\x01\xcf\x70\xd9\x3f\x37\x09\x03\xa6\x2b\xd6\x1a\x83\x7a\xb8\x4d\xe7\xc9\xae\xab\xe3\xf1\x5c\xe6\x1e\x46\xd2\xcf\x98\x05\x8b\xf9\xf9\x2e\x64\x2e\xa6\x50\x10\x19\x47\x3d\x41\xf2\xfa\x25\x2f\x66\x65\x65\x19\x8b\x48\x3b\x91\x9c\x5c\x23\x6f\xb9\x74\xdb\x08\x2a\x39\xbd\x41\xde\x5f\x27\x49\x62\x74\xf5\x4f\xdd\x9a\x47\x32\xa8\x1f\x83\x3d\x90\x24\x72\x92\xfd\x27\x97\xd3\x1d\xe5\x6d\x24\x89\x63\xdc\x5e\xaf\x1d\xeb\x5c\xff\xe7\x54\x6a\xd9\x6b\x3d\xdf\xc9\xfa\xb9\x4f\x1c\x48\xa2\x64\x1a\x02\x40\xa8\xdb\xce\x45\x1b\xcf\x89\x4c\x93\x88\xc7\x01\x21\x9d\x6b\xd8\xb5\x70\x22\xd3\x59\x97\x29\x01\xe9\xe3\x9d\xb6\x19\x38\x5f\xa7\xa6\x53\x66\x11\x25\xd4\x63\x0e\xba\x5d\xd1\xc5\x04\x17\xd4\xed\xc1\x51\x91\x59\x62\xdc\xf7\x7f\xee\xa2\x31\x9f\xe0\x0c\xc7\x38\x41\xd4\xd7\xa1\x86\x95\x4b\x55\xe7\xd6\xe6\xfa\x5c\xcc\x08\x05\x33\x49\x75\x96\xba\xe5\x5f\x76\x8e\x37\x8a\x40\xfb\x43\x8c\x3a\x7e\x7c\x05\xcf\x79\x89\xda\x4a\xd3\x53\x19\x8f\x50\x0c\xed\x1a\xd6\xc5\x59\xfd\x25\xca\x59\x72\x6a\xb0\xd6\xb0\xd9\x7f\x3f\xfc\xd8\x5d\x1f\x36\x7f\xae\xbf\xaf\xee\xbf\x6d\x0e\xeb\xcd\xfd\x7e\x17\x7e\x95\x03\xb5\xbe\xa2\x75\x0f\xbf\x36\x26\x9f\xf3\x41\x66\x52\x98\x34\x0b\xeb\xa8\xc8\x87\x50\x34\x5c\x42\x25\x4e\x2c\x13\xf1\x26\xdd\x2b\xdd\xe5\xff\x9d\xdf\xbc\xca\x12\x2c\x67\xdf\x6d\xf7\x17\x14\xd6\x5f\x86\x54\x52\x09\xa7\x8a\x22\x8d\xb9\x46\x49\xf9\xf5\x4b\xf7\xe3\xb7\xf9\x40\xe7\xbe\xc4\x49\x9a\x49\xa5\x49\x3c\xb4\x0d\x6f\xd7\x0f\x0b\x15\x0e\xa9\x13\xe1\xe5\xb5\x4b\x84\x03\x0d\x10\xcd\xd9\xd5\x34\x24\xb2\x07\xa1\xa0\xbf\x39\x7c\x02\x86\x59\x6c\xce\x7b\x28\x71\x3d\xf6\x7f\x16\x31\xf6\x64\xb9\x1d\x03\xf1\x21\xe1\x88\xd5\xe8\x85\xec\xb0\x9d\xe4\x2e\x2f\xa1\x6e\xfe\x74\x2a\xfa\xd3\x5f\x05\x95\x06\x11\x7f\x9f\xb1\x9e\x3f\xf3\x85\xf7\x23\xc1\x32\x74\x95\x30\xa8\xc4\xd6\xdb\x4b\xee\xa6\xc9\xaf\xa8\x28\x73\xd9\x3d\x57\x4e\xf0\x19\x94\xc9\x1a\x50\x71\xe4\x58\xfa\xb7\xf7\xdb\xfd\x76\x75\x7b\x78\x7c\xda\xae\x37\x87\xed\xfd\xfa\x69\x73\xb7\xe9\x03\x78\x15\x0b\x27\xe3\x9e\x97\x97\x71\xaf\x8a\x65\xc4\x7c\xf1\xfc\xdb\xc3\x23\xe6\x4e\xe7\x6b\x4d\x25\xc2\xf0\x41\x8b\x0c\xea\x11\x09\x7a\xa6\x12\xa9\x11\x5c\x37\xd3\xee\x19\xab\x59\x66\x8a\xc4\x12\x13\x85\xa7\xd9\x32\x0b\x87\x55\x86\xd9\x42\xc7\x7b\xd3\x4d\xbd\x99\x94\x46\x15\x51\x16\x3d\xa0\xbe\x41\xbb\xae\x8e\x5f\xf7\x88\x66\x8a\x80\x31\x43\x56\x6d\x5f\xcb\x7c\xbe\x15\xa8\x2c\x76\x64\x72\xce\x1b\x5b\x58\x8a\x2a\xa3\x6c\x44\x1f\xe6\x98\xfa\x16\xbd\x3e\x95\x51\xa7\x79\x21\xdf\xa0\x96\xcf\xb0\xd3\xb5\x3c\x8d\x2b\xae\x8a\x92\x14\xeb\x4c\x3e\xdd\x71\x9d\x37\xaa\xf3\x4d\x8f\x43\x60\xae\x68\xaa\xb0\xe0\xde\x20\x5d\x52\x80\x3b\xdc\x57\x9f\xd1\x14\x64\x8a\x4a\xe0\x5e\x40\x75\xb7\xba\xdd\xec\xf6\x3d\xb3\x49\xa6\x58\x92\x60\xcb\xda\xee\xdb\x7e\x36\xdf\x2c\x53\xcc\x49\x4b\xd5\xa3\xfa\xda\x20\xf2\x91\x29\xde\x7d\xab\x2e\x35\x7b\x07\x26\x97\x97\x5d\xa9\x4b\xc4\x8e\x99\xe2\x9c\xba\x9a\xd9\x90\x28\x6c\xfa\x6b\x0a\x8d\x38\x8d\x55\x5e\x5f\xd7\xd5\x69\x1c\x65\x28\x11\xb9\xc6\x14\xd7\xdb\x53\xe4\x25\xe4\x83\x15\x56\x32\x72\xac\x20\xcf\x9d\xaf\xe3\xda\x5b\x67\x4f\x24\x23\x8b\x29\x0d\x64\x40\x9c\xc3\x39\x67\x43\x13\x83\x86\xe1\x98\x97\x9d\xef\x30\x79\x47\x12\x62\xcc\x30\x82\xac\x8b\x8f\x60\x13\x9d\xab\xbd\xea\xdf\x92\xe2\x80\x02\x28\x07\x25\xcd\x33\xfc\x28\x7d\xa2\x7f\xba\x70\xb4\x86\x80\x30\xbf\x99\x50\x15\xfa\xe3\x26\x75\xec\x07\x27\x67\x41\xfa\xc4\x83\x32\xcc\x49\x86\xf4\x14\xe6\x8f\x85\x6c\x6d\x55\x1f\xfb\x01\xca\xe9\xca\xfa\xfe\x25\x47\xe5\xdb\x1f\x63\x8e\xe3\x14\xeb\xf1\x21\xef\xd3\xbf\x01\xa3\x63\x84\x0c\xf9\x0c\xd7\x6f\x7d\x6b\xcb\x70\xdf\xc6\x68\x9c\x81\xeb\x6f\x7f\x5e\xd4\x5d\x66\x13\x09\x71\x82\x89\x0c\xbc\xd3\x24\xfc\x06\x64\x04\xf3\xce\xaf\xb9\x7e\xc5\x78\x71\xbb\x7e\x58\x76\xf6\x74\x44\x33\x84\xd4\x1c\xf3\x72\xd7\xca\xd7\xbc\x7c\x9e\xf4\x41\xe9\x38\x4a\x52\xcf\x12\xba\xed\xa1\x75\x3a\x89\x32\xd4\x3d\x2f\x64\xd3\x1e\x6a\x59\x9a\xea\xd8\x1f\x4a\x15\x62\xa5\x6d\x55\xe4\xd5\x78\x7d\x69\x12\x8d\xd2\x39\xd7\x55\x39\x2c\x4b\x9d\x72\x4b\xba\x49\xb9\xfb\xe7\xf5\x66\xbd\xbd\x5b\x05\xaf\x58\x67\x91\x45\xa3\xe5\xda\xed\x1f\x5f\xa0\xac\x8e\x50\x56\xb3\x14\xaf\xce\xd2\x34\x73\xea\xc0\x79\xd3\x36\xcb\xed\x61\x3a\xd3\x10\x39\xeb\xe0\xc1\x57\x0f\xa5\x53\x1a\x0e\xc7\x4d\x8a\xd6\xa3\xcd\x0b\x18\xcb\x88\x05\x4f\x47\xd3\xc4\x20\x70\xe4\x6e\xf5\xe7\xc1\x8b\xeb\xad\xb6\x4f\xd7\x4f\x0f\x8f\xbb\xc3\xd5\xc3\x8f\xfb\xfd\x36\x88\xb1\x66\x9a\x45\x12\x37\x1b\xd4\x86\xa8\x56\x35\xc8\x49\x89\x4d\x33\xee\xb8\x76\xa5\x31\x78\x13\x9f\x14\xd8\x34\xd3\x26\x66\x93\x7c\xb7\x03\x1a\xfa\x2f\xd0\x8f\xe2\xa9\x63\x70\xd4\xd5\xf1\x38\x5a\x6c\x5a\x90\x08\xab\x3b\x58\xb8\x84\x05\xb4\x8c\x16\xc4\x58\xc7\xca\xfd\x4b\xd6\x0e\x96\x37\xad\xcb\x85\x71\x59\x46\xb8\xef\xa4\x3f\xb9\xe2\xde\xd8\xe8\x68\xc1\x12\xa4\x20\xf8\x47\xe5\x7c\xb4\x55\xe3\x8b\x51\x93\xc8\xcf\x0f\x96\x99\xd6\x9e\x54\xc7\x60\x59\x69\x9f\x17\xc5\x66\xff\x7d\xd5\x34\x03\xea\x5e\x4b\x91\x11\x13\x28\x95\xbd\xc1\x5a\xce\x7b\x69\x29\x13\x9a\xf4\xa2\xaa\xfd\x05\xa4\x0c\xd5\xd8\xbb\x8f\xf5\x4b\xae\x47\x8b\x51\x25\x4a\xfb\x4c\xd9\x55\x5d\xbd\x42\x2f\x86\xb1\xfc\x03\x8a\x50\x6a\xfa\xe0\xfe\x2e\x7f\xae\x2f\xaa\x3d\x5a\xa5\x36\x71\x0a\x7a\x95\x75\x16\x50\x76\x0e\xcc\x34\xf8\xd0\x2a\x53\xda\x3b\x8d\x2e\x3b\x37\x0a\x0c\xb4\xa2\x04\x3d\xc6\xbc\xd9\xb6\x5b\x5d\xf5\x7f\x16\x1c\xb1\xd6\x2e\x7b\xee\x45\x95\xcd\x25\xb0\x56\x2b\x43\x11\x39\x65\x73\xdb\xbe\xec\x41\x1e\x07\xcc\x5f\x7f\x2d\x70\xb0\x9c\x36\xc0\x34\xab\xba\x1d\xb1\x86\x74\x03\x14\xba\xdb\xd7\x5b\xfc\x12\x77\xa3\xbf\xb3\xde\x6b\xab\xea\x66\xf6\x5c\x9a\xa4\xe8\xba\xb9\xb6\xc6\x53\x51\x7d\x80\x13\xce\x18\x46\x18\x95\xea\x41\x93\xa2\x39\x9d\xcd\x68\x83\xd1\xda\x12\x8c\x60\xdc\x36\x7f\xb0\x55\xdd\xad\xc8\x61\xa5\x6a\x4b\xd1\x19\xfb\x7d\xf3\x10\xfe\x64\xb4\xc4\xae\x80\x2e\x06\xac\xca\x41\x7f\x27\x1c\x86\x14\x5f\x88\x73\x12\x91\x67\x76\xe8\x73\x5f\xe9\x09\x4d\xc1\x28\xfb\xa9\x81\xb9\xb6\x14\x03\x6f\x67\x28\xde\x60\x53\xea\x33\x34\xad\x34\xd5\x0c\x8a\xa6\x41\xa5\x0a\x77\x98\xb3\x3a\xe6\xed\x48\x90\x24\xd3\x36\x8b\x31\xa5\xd5\xf4\xb4\x6b\xce\x65\x5b\x2c\x6b\x69\x2b\x38\xc6\xdc\x1b\x73\x5e\x17\xd5\xd9\xf4\x57\x91\x19\xd2\x4f\xa1\x15\xcf\xcb\xe7\xf1\x4e\x69\xa2\x28\x4a\xe3\x49\x9d\x6d\xdc\x20\x62\xa2\x34\x42\xb6\xe0\xdf\xf7\x11\x5b\xca\x02\x5d\x66\xee\x4d\xa4\x52\x64\xd7\x3b\xe6\xe5\xcd\x19\xa9\x87\xbf\x55\xfd\xd2\x31\x71\xe4\x0c\xa4\x8b\x4f\x7f\x7a\xa8\xa9\x17\x47\xef\x07\x19\xc9\xd3\x31\xc8\x72\x99\xde\xc0\x90\xc8\x38\x96\xef\x12\x25\x2d\x0e\xbf\x43\x15\x56\x8a\x21\xd2\x89\x4f\xbb\x94\xb9\xeb\xde\x99\xdc\x27\x51\x4e\xd5\xc1\xe9\xe5\xca\xba\x96\x1f\x48\xd0\x3b\xfb\x09\xa5\x4d\x60\x41\xfd\x2e\x6b\xa3\x83\x96\x65\x66\x88\x89\xb0\xe3\x21\x38\xc3\xf3\xce\x0d\x93\x2a\x83\x4e\xd4\x6d\x55\xbd\xae\xda\x75\x10\x5a\xbd\x81\x7e\x3d\x9b\x4c\x30\x54\x53\xec\xc9\xe7\xc6\x7c\x8f\x61\x0c\x48\xdb\xcb\x38\x1f\x4e\x55\x3e\x18\x67\xc3\x28\x50\xbf\x42\xd6\xd5\xf1\xd4\xc2\x21\x61\xd3\xc7\x64\xdc\x60\x4a\x71\xab\x2b\xcc\x52\x0e\x02\x10\xb3\x27\xe5\x44\x61\x7d\x46\xf6\x4a\x16\x87\xee\xaa\xb2\x36\x8f\x50\xbf\xee\xe1\x7d\x1e\x1e\x85\xf3\x32\x87\x45\xf5\xbc\xe6\xa7\x73\x31\x4e\xe2\x1a\x2e\xdd\xf2\xde\x9d\x72\x3d\xa1\x21\x31\xdc\x68\xe4\x9e\x57\xd0\xae\x4a\x73\x53\xe4\xfd\xc4\x71\x4b\x65\x36\x6a\x67\xbd\xa9\xea\xef\x79\x33\x42\x11\x19\x11\xc7\xa8\x3c\x83\x0e\x5e\xff\xd1\x5e\x75\xd1\xfd\xc8\x16\x1a\x91\x00\x0c\x24\xb1\x37\x00\x33\x01\x9c\xe9\x0c\x08\xce\x95\xe7\x64\x76\xfd\xc5\x9f\x37\x5d\x85\x33\x84\x3b\xa3\x77\x07\xae\x02\x2e\x6d\x36\xb9\xc2\x64\xb8\x89\xbe\xe4\xcf\x2f\x21\x17\xb6\x83\xa2\x18\x7f\x1a\x02\x34\x27\x43\x83\xe9\xd5\xf9\xa3\x5b\x15\x9b\xfd\xf7\xd9\xb5\xa4\xce\x70\xdd\x5d\x57\xfa\xdc\xbd\x47\xc7\x1c\xb8\xbc\xe9\x18\x95\x1a\xd3\xd9\xa1\xff\xeb\xf0\x3b\x57\xe3\xe4\x82\x51\xd4\xd1\xb2\x8c\x98\xeb\x1d\xcd\xd1\x23\x92\xb5\x3f\x0f\x03\x21\xca\x3c\xdc\xe7\xba\x2a\xf1\xfd\xfa\x5a\x5c\x33\x01\x2f\x1b\xad\x25\x66\x3c\x4e\x55\xd3\xde\x41\xd3\xc8\xe7\xcb\x36\xa3\xc9\xea\x31\x11\x0c\xaa\xd5\x98\x1f\x1c\x2b\x9a\x8f\xea\x8c\xc6\xa4\x0e\x72\xfb\x04\x08\xcd\x0e\xb7\x66\x8c\x63\x83\x77\x99\x88\xbb\xfc\x7d\x83\x6e\xde\xa8\x0d\xd9\x58\x65\x31\x1c\x43\x8d\xcb\xca\x9c\x07\x0d\xfa\xaf\xc8\xc7\xc2\xc9\xda\xf2\xa0\xa1\x39\xef\xd3\x81\x28\x21\x6a\xe8\x9c\x46\x7f\x6a\x9a\xbf\x81\x88\xba\x0f\x5c\xd6\xf0\xe4\x9a\x7d\x3c\x01\xea\x25\xc8\x0d\x22\xcd\x5d\x1b\x5d\xd5\xfc\x15\x15\x98\x3f\x23\x8e\x79\xec\x30\x9c\x26\x08\x4d\xce\x22\x2a\x88\x49\x86\x3d\xbb\x4e\x53\xeb\xd0\xbb\x4b\xbf\x2d\x58\xf0\xc9\xab\x81\x98\x46\x94\x4c\xf5\x8e\xe7\xd7\x56\x19\x7a\xe3\xc8\xfd\xff\x08\x75\x78\xe3\xe1\xb0\xa6\x58\x84\xc0\xe4\x75\x78\xa2\x87\xa7\xdd\x67\x48\x28\x20\x31\x43\x70\x95\xc3\xbc\x15\x32\x3f\xfa\x32\xf4\xa5\x96\xd2\xfc\x4c\x12\x39\x9e\xe2\x40\x88\xee\x10\x3f\xcb\x28\x52\x20\x4c\x25\x2e\x6e\x2e\x06\x11\x9b\xd9\xb3\x11\x43\x70\xd1\x60\xe6\x68\x84\x1b\x5e\xee\xc9\x01\x62\x18\x66\xb3\x65\xd3\x05\xfd\x8e\x43\xf4\x92\x82\x71\x7a\xd3\x69\x6c\xa4\xaf\x2b\x3c\x61\xfc\xe3\x76\xf7\xe9\xa0\x2c\x49\x91\x49\xb4\xce\x9f\x5f\x5a\x3e\x3b\x48\x13\x81\x26\xb4\xf3\x49\x6a\x99\x37\x79\xf9\x7c\x0d\x45\xdf\x55\x03\x34\xcb\x42\xc6\xc7\xb5\x1b\x5c\x55\x4d\xf3\x87\x2c\x4b\xb9\xae\x3f\x2e\xa8\xd9\x33\xa0\x9a\x44\x7d\x78\x35\x66\x11\xcf\x80\xda\x2c\xee\x0b\x69\xd7\x30\x90\x34\xf9\xe3\x2c\x8b\x53\x2f\x65\x27\x03\x45\x42\x7f\x4c\x8b\x9e\x05\x11\xd1\x14\x47\x87\x23\x43\x70\xed\x20\x0c\x37\x7d\x36\x06\x44\xdb\xa1\x88\xbb\x2a\x8a\xa1\x13\x1d\xb8\x48\xd0\x56\x06\x15\x83\x49\x95\x0c\xb8\x25\xc8\xc8\x5b\x54\xcf\x3f\xb6\x8b\x29\x47\x90\x09\x15\x9d\xeb\xb0\xd3\x79\xd3\x0c\x51\x24\x48\xab\x30\x87\xbc\xca\x5f\x75\x95\x4f\x91\xfd\x60\xc0\x89\x51\x7a\x8c\xc7\x0e\x74\x0d\xc8\xe6\xb8\xe0\x01\x02\x70\x89\x7b\xc3\xaf\xbc\x2c\xf3\xf2\xb9\xf3\xa4\x77\x7d\x26\x0d\x00\xb4\xd2\x7e\x8b\x6b\xf2\xaa\xbc\xfa\xf8\x5f\xa8\x83\x1f\x0b\x56\xb8\x2d\xff\xf6\xe1\xdb\xa1\x84\x5f\xbb\x53\x5e\x36\x7d\x30\x70\xc1\xeb\xbd\x68\xf9\x6d\xc4\x2d\x96\x6c\x0c\x68\xf9\x01\x4e\xdd\xf7\xc1\xee\x7f\xe5\x6d\x0b\xf5\x1c\xc5\x65\x23\x9b\x22\x83\x44\x9f\x65\x73\xf9\x39\x80\xa7\x85\x4e\xd1\xfe\x1c\x93\xf8\xcc\x7c\xe7\xa7\x2d\x3b\x69\x36\xa1\x09\xf2\xba\x8e\x89\xa7\x82\x51\xb7\x09\x8f\xd5\xd0\x5a\xe8\xaa\x0e\xd0\x5e\xb4\x04\x5b\x22\x24\xda\x22\x93\xbf\xfd\xe6\x29\x3c\xc6\xbd\x4b\x96\x18\x99\xf9\x86\x98\x2e\x66\xf4\x18\xbe\x49\x98\x6a\x89\x4d\xd0\x31\xfd\xbf\x15\xf2\xb5\x84\xfe\xd5\xe9\x33\xa5\x04\x8c\xaf\x6f\xdc\xc1\xb1\xb9\x48\xb6\xdb\x54\xb3\xc8\xcb\xe6\x06\xde\xe8\x25\xd9\xad\xcc\x66\x5a\x05\x98\x26\xd2\xb9\x60\xd1\x79\xdf\x37\xf5\x8f\x21\xa1\xe1\x0c\xd0\xbe\x7e\xd1\xae\x5f\x40\x9e\xa0\x41\xf7\xeb\x0f\x14\x2a\x9f\x0e\xa5\x8c\x60\x31\xef\xb6\x7a\xfb\x9a\x7d\x36\xb3\x8c\x78\xae\x98\x60\x80\x83\x55\xba\x1a\x48\x07\x2c\xe7\x19\xba\x09\x6b\xd9\xbc\x3c\x9c\xc7\x22\x67\x99\x15\x54\x61\xfe\x11\xfb\x3e\x27\x1f\x84\x15\xca\x3a\x05\xc6\x87\x7b\xec\xa3\x3f\x3c\x6d\xbe\x6d\x77\xfb\xa7\x7f\xf6\x03\x6c\x8c\xdb\xfb\xc5\xf6\xb8\xbc\x66\x65\xe4\xe4\xc0\xf3\x06\xbf\x86\xf0\x40\xe3\x6d\xc9\xca\x4c\xc2\x10\xe3\xed\x5e\xe4\x09\x76\x2f\xb9\x6d\x47\x3d\x4a\x28\x57\xba\xb0\xa5\x59\xc9\x1d\x6d\xc6\xc1\x76\x96\x27\x60\x41\xa7\x53\x2b\x4d\x84\x60\x42\x94\xff\xee\xee\x35\xd8\x06\xab\x52\x27\x6f\xff\xf8\xf0\x47\xe0\xa7\xcf\xac\xa2\x34\x90\x2c\x7f\x87\xba\xda\xb6\x70\x9c\x59\x32\xab\x33\x96\xc9\x51\x9a\xd6\xbf\xfe\x89\xe7\x64\x75\x66\x31\xa6\xfe\xbe\x7d\xfc\x1e\x88\xaf\x33\xab\x99\x88\x5c\x44\xdc\xff\xc5\x13\x18\x63\x69\x4d\xce\x39\xf1\x33\xab\xc1\x44\xb1\x17\x26\x70\xab\xec\x11\x59\x5f\xc3\xf9\x26\x76\xf4\xa7\x4f\x1b\x94\xad\xde\x6f\xef\x36\x87\x9b\xa7\x55\xcf\xd4\x64\x8d\x8c\xd1\x0b\x29\x2b\xd4\xb0\x58\x5e\x54\x46\x31\xf4\xbf\xef\xb6\xf7\x07\x7c\xf9\xdb\xab\x1f\xc8\xa2\x30\x40\x6d\x2c\x28\x47\xc0\xe1\x12\x09\x83\x57\x6e\x2d\xe5\x88\x61\xd9\xf6\xa2\xce\xcb\xea\xbf\x99\xb5\x4a\x5e\x74\x85\xba\x6e\x6b\x1c\x40\xa3\x28\x52\x32\x19\xf5\x2a\x38\xef\x3b\x04\x9e\x93\xf7\x40\xa3\xd8\xc4\x68\x73\xd1\xd7\x44\xc5\x88\x21\xe7\x4a\xa3\x44\xb9\xba\xd1\xa1\x1d\xd3\x4f\x7e\xaa\x2a\xd6\x53\x60\xfd\xcf\xf4\x47\x48\x24\x89\x8b\x5d\x4f\x55\xdd\x4e\x62\x7d\x1a\x11\xa9\xc1\x29\x09\x3e\xc1\xf3\x58\xbd\x6a\x81\x21\x84\x46\xc4\x32\x2c\x6b\x38\x42\x3c\xd0\x05\x3a\x91\xdd\x5e\x7f\x93\x97\x79\x00\xea\xd3\x28\x4d\x2d\xc6\x99\x28\xe2\x6c\xf2\xb7\x7e\x76\x52\xea\x28\xb2\x64\xd3\x78\x66\x23\xd7\xbf\x6f\x2e\xb6\x90\xe9\x0f\xa7\x8a\x51\x9f\xf4\xda\x3c\x3f\x37\xbb\xbc\xd4\xd8\xf5\xf0\x7d\xac\x98\x36\x3f\xc7\xa6\x98\xdb\xbf\xf9\xb1\xff\xf1\xb4\x39\x5c\x77\x66\xa0\x5b\x14\x9b\xb1\xd4\x37\x8d\xb2\x04\x2c\x9d\xe4\x22\x77\x55\xf1\x36\xb3\x6f\x34\xca\x14\xc1\x4d\xe3\x34\xc8\x62\xcf\x46\x50\x2a\xd1\x50\x57\x63\xc1\xd7\x29\x6b\xd0\x68\x3b\xa6\x11\x95\xb1\x97\xda\xc5\xf7\xe2\xff\xca\x22\x86\xf0\xc8\x4b\x8a\x2a\x1a\x31\x12\xa1\xa5\xd7\x55\xf9\x5c\xcb\xd6\xc7\xb5\x37\x75\x75\xbc\xaf\x82\xea\x27\x8d\x38\xd5\x2c\x1a\xd8\x28\x7f\x42\xdd\xcc\xbb\x24\x69\x24\x22\xc2\xf4\x88\x3b\xa8\x56\xf9\xbc\x19\x6a\xba\x50\x44\xac\x91\xdc\xdd\x19\xeb\xab\x8f\xce\x03\x28\x3f\x81\xec\xd1\x48\x10\x85\x0b\xbb\x91\x16\x90\x9c\xfa\xb8\xd0\x94\x1b\xc6\xa6\x1a\x09\x0c\x50\x6d\xb9\xa9\x0a\x1f\x8e\x2c\x30\x29\xd1\x48\x64\x5c\x66\x53\x84\xfa\x6c\x41\x0b\x8f\x29\x0f\x86\x6d\x97\x5f\x68\x08\xd3\x48\x66\x49\xe2\xf3\xff\x01\x0c\x1b\xe4\xfd\xc0\xcc\x9b\xa4\xce\x23\x86\xae\x0b\x59\xee\xfe\x82\xce\x27\xee\x16\xd1\xea\x93\xf5\x28\x79\x8c\xb9\xa1\x73\xd9\xeb\x7a\xe1\x45\x78\x38\xae\x2c\x3e\xdb\xc6\xab\x92\x5c\x90\xb9\xd2\x48\x45\x8e\x4b\xf0\x24\x3f\xf6\xd5\x03\xb2\x56\x7f\x32\xa9\x8a\x5b\x44\xde\x7d\x83\x76\xf3\x26\x8b\xf3\xdc\x67\x0a\x3f\xaa\x2c\xcf\x06\xac\xac\x73\x83\xf7\xd5\x5e\xbe\xc2\xaa\x79\x9a\x67\x7e\x68\xa4\x93\x24\x4e\x03\x2d\x4e\x91\x9b\x4b\x3c\x1e\x8d\x34\x91\x48\x34\xb1\xd5\xf2\x34\x7f\x49\x5f\x22\x8c\x69\x64\x08\xc7\xf2\xa1\x0a\xfc\x51\x3f\x1a\xe4\x21\xbc\x60\xeb\xf7\xe3\x81\x72\x6c\xf4\xbb\x92\xff\xad\x51\x5a\x76\x94\xce\xa1\x11\x08\x9a\x46\x7e\xab\xff\xd4\x74\x4e\x6f\x00\x24\x45\x94\xcc\xb1\xef\xf6\x9e\x44\xcf\x34\x02\x23\x9d\x3a\xc1\xb9\x3e\x15\x5e\x73\xbe\xb7\x6e\x96\x13\xd7\xc5\x5f\xb6\x50\x3b\x7a\x90\xc3\x33\x38\x75\xea\x35\xfe\xcf\x51\xa6\x93\xc6\x91\x70\xc9\x0e\x97\xce\x86\x5f\xe1\xef\x71\x2c\x55\x12\xda\x9c\x76\xf0\xc9\x77\x13\xc7\x24\x45\x5a\x26\x97\xa6\x5d\x9d\x4e\x45\xd0\xf7\x98\x4c\x52\x1c\x0b\x19\x0d\xba\x3a\x37\x00\xdd\x8e\x38\xbd\x54\x12\x5b\x24\x65\xb2\xe1\x16\x48\x4a\x48\x7a\x09\xef\x9d\x7e\x6b\x31\x51\x12\x25\x58\x42\x21\x31\xb4\xcf\x2f\xae\xff\x38\x8d\x45\xe6\x25\x50\xee\xe5\x71\x90\x5e\xa3\x71\x6a\x52\xd7\xbb\x75\x82\xd2\xac\x6b\x30\xf9\x25\xb1\x74\x18\x6a\x9d\x94\xb0\x23\xf7\x7d\xb0\x2e\x49\xfe\x58\x83\xcd\xdf\x17\xb3\xd0\x34\xa6\x31\x45\x7b\x68\xaa\xf2\x15\x3e\x9e\x64\xf9\x7a\xb1\x11\xc7\x34\x8b\x90\xd8\xd4\x80\x95\xe7\xa2\x1d\xd8\x21\x68\x4c\xa9\xc0\xb0\xbb\xf3\xa5\xa0\x19\x2f\xb0\x98\x72\x08\x2c\xd6\x7b\x84\xaa\x56\x65\x3e\x6b\x5e\xa4\x31\x63\x19\xde\xf1\x55\x51\xbd\x7e\xab\xcf\xa7\x70\x32\xb3\x3a\x26\xa1\x10\xa4\x65\x6d\x26\x6b\x83\x47\x09\x6e\x5e\x25\xfc\x5a\x07\xb8\xf2\x6f\x97\x61\x3e\x8d\x39\x13\xe0\x05\xcd\x7f\xcf\xdb\x76\xb9\x21\x32\xc9\xe8\xbf\xb2\x7f\x87\x33\x78\x8a\x05\x24\xc7\x94\xea\x53\x40\x9f\x4c\x37\x97\x19\x52\x3a\x5f\x6f\x7e\x6e\x6e\x1f\x1e\xef\x36\xf7\xfb\xc3\x7e\xb3\xba\x3b\xac\x57\x8f\xe1\x56\x45\x26\xd0\xbf\x2b\xcf\xc7\x55\x39\xe2\x99\xa7\xb1\x50\x92\x59\x87\x49\x1a\xbd\x6d\x49\x12\xc7\x09\x8e\x65\xcd\x71\x6e\x98\xc6\x52\xc6\x48\xa8\x2f\x8d\x23\xb2\xf5\x90\xd3\x49\x9b\x01\x8d\xa5\x4e\x98\xf7\x70\x57\xa7\xfc\xea\x63\x6b\xbc\x92\xe6\xf5\x47\x29\x8f\x23\xbd\x2d\x3f\x5e\x25\x1a\xd1\xf4\x0d\x0a\xe1\x60\x82\x7f\xda\x18\x44\x63\x95\x26\x88\x5d\x84\xff\x9c\x65\x81\xa5\x8d\x7d\x85\xff\xfc\x36\x97\xc7\xa1\xb1\x32\x4e\x1e\xe7\xea\xc7\x3f\x0f\x57\xab\xf5\xef\x4e\x17\x32\x5c\x49\x47\x3c\x1b\x33\x75\x0d\xaf\x6f\xd1\xe6\xc5\x3a\x4d\x8c\xe9\xa3\xb2\xc0\x06\xd8\xa7\xee\xfd\x0d\x24\x51\x18\xae\x22\xd4\x3c\x51\xe7\xba\x7c\x44\x45\xc4\xc1\x91\xa5\xb1\x01\x86\x21\x36\xe6\x66\x08\x99\xcd\x03\x08\x8a\xf8\x02\xdf\xab\xdc\xa4\xf3\xe3\xd2\x89\xba\x22\xdf\x81\x8b\x0a\xe6\xfe\xe0\x65\x62\x72\x41\x22\xf8\xe2\xff\x4e\x05\x0a\x68\x0c\x26\xc6\x90\xc1\xca\x3a\x48\x8c\x4e\xee\x24\x89\x22\x0a\xfe\x0d\xbb\x7e\x67\x9f\x59\xde\x9a\x2b\x68\x7f\x01\x20\xa4\xa4\xc1\x2d\xa8\x73\x7f\x96\x2d\x64\x12\x45\x2c\x54\x25\xaf\x5c\x0c\x1f\x0e\x30\x65\x1c\xa8\xc3\xa0\x46\xe8\x28\x72\xa7\x49\xc4\x33\x11\xbb\x4d\xb6\xa7\x27\x1d\x26\x22\x0c\xb2\x34\x76\xba\x5d\x55\x0d\x4e\x91\xef\x3c\x41\x94\xcf\x6f\xc5\xba\x04\x5f\x67\xfc\xe0\x1d\xa5\x37\x2e\xae\x68\x52\x19\x34\x2d\xb6\xeb\x87\xbf\xb7\x63\x25\xb1\x70\x3c\x72\xce\xba\xa3\x79\x1a\xd1\x48\xd2\x24\x56\xd4\xb1\x60\xe5\x25\x12\x43\x3d\x7b\x87\x3d\x1c\x27\x89\xc0\x02\xe8\x7f\xdb\xe1\x2f\x12\x61\x2c\x27\x6f\xd5\x87\x4f\x37\x21\x96\x72\x16\xb0\x7f\x6f\x50\xce\x72\x83\x34\x49\x33\xc1\x74\x1f\x0a\xef\x03\xd2\xc4\x71\xb2\x7c\xd6\xb3\x38\xb6\x00\x49\xaa\x12\x04\x57\x39\xee\xce\xc3\xf5\xc3\xdd\x6a\x7b\x7f\xd8\x6d\x1e\x57\x4f\xab\xfd\xc3\xd3\x61\xb7\xfe\xbe\xb9\x5b\x1d\xbe\xaf\x76\xdf\xc3\x5d\xa5\xda\x49\xe0\x23\x84\x0c\x8e\x55\xb9\x29\xa1\x7e\xfe\x98\xcd\x6f\x06\x8e\xca\xf2\x54\x5d\xca\xb1\x4f\x77\x8c\x84\x71\xcb\xa9\xf7\xd4\x7a\x09\xb1\x70\x4c\x08\x4c\x21\x3f\xca\xff\x9c\x65\x9d\x7b\x1e\x9f\xce\xfc\x27\x7f\x59\x8a\xa4\x09\x27\xa9\x09\x54\x73\x0f\x48\x49\x36\xc3\xc4\xd1\x84\xf3\x88\xb8\x6a\x25\x96\xe3\x9f\x36\xc1\xd0\x26\x82\x38\x96\xec\xda\x0b\x35\x76\x2b\xff\x8f\xdd\x32\xb6\xb8\x7f\x16\x91\xa9\x6c\xa0\xb5\xfd\x26\x0b\xe9\x25\x61\xf9\x74\x7b\x4e\xa4\x14\x48\xe5\x7e\xfd\xf0\x6d\x82\xc9\x0a\x87\x2d\x41\xa5\x4e\xf7\xd3\x30\xa9\x93\xe3\xd1\x60\xc4\xd6\x85\x6c\x9a\x9f\x39\xfc\xba\xcc\x1d\xd3\x44\x09\x8b\x79\x50\x8b\xe1\x22\x52\x61\xac\xc2\x35\x94\x76\x5d\xfe\xc7\xbc\x6c\xaf\xaa\x6a\x22\x7c\x3b\x32\x22\x0b\x76\x25\xf1\x9b\x61\xa2\x23\xc5\x92\xb1\x2c\xa1\x43\x48\x8d\x35\xf5\x68\xa2\x09\xc5\xea\xb3\xaf\xc5\x07\xb3\xec\x33\xf8\x9f\x78\xf8\x89\x91\x14\xd9\x00\xf6\xf3\xa4\x95\x7b\x8d\x79\x55\x2e\x2e\x72\x7f\xb6\xf5\xb4\x18\xdf\xbf\xed\x1e\xd6\xdb\xd5\xed\x17\x50\xde\x6e\xb0\xe3\xa5\xec\xfc\xbf\xfc\x08\x63\xe6\xe8\xf9\x65\x21\x4b\x43\x6b\xf8\xfa\x05\xf4\xeb\x4e\xbe\x81\xde\xb4\x2f\x53\xaf\x95\x44\x09\x8b\x7d\x51\xb6\xbb\x9a\x9c\x45\x38\x83\xf3\x4e\x22\x1d\x27\x36\x14\x50\x7c\x84\x11\x0e\x19\xc1\xfc\x45\x56\x6d\x75\xbc\x85\xb7\x29\x6c\x2f\x0c\x03\x10\x2e\x4b\xfe\x06\xb2\x18\xe7\xa2\xe7\x0b\xf5\x93\x66\x97\x65\x43\x47\x22\xb0\x81\x19\xf2\xfe\x7c\x7c\xb0\xb8\x43\xee\x5a\xf0\x0e\x57\xf8\xf9\x98\xa6\x21\xfb\xb5\x93\x85\xf4\x12\x65\x0e\xe8\x3f\x22\x2d\xe8\x06\x42\xc6\x03\x2d\xf4\xb3\x7b\x85\x6e\xd7\x9b\x7e\x90\x24\x49\xc1\x7a\x40\xbc\x39\xeb\x8b\x20\x84\x24\x99\x53\x56\x43\x35\xbe\xcd\x1b\xd4\x1f\x55\xd9\x4f\x5a\x22\x12\x6c\xf3\x28\xc0\xb6\x24\x9a\x7e\x0d\x24\x51\x16\x49\xc9\xce\x25\xd6\x74\xee\x86\xb3\xac\xc6\x5e\xc3\xbb\x5c\xbf\xe4\xcf\xb2\x7c\x6b\x6e\xab\x8f\xaa\x90\xe1\x78\x9a\x09\xec\x70\x2c\xaa\x67\xc7\xd6\xd8\x78\xba\x46\x83\xdd\x5e\x66\x18\x67\xb0\xda\xfc\x13\x30\xfb\x74\x27\xf5\x4b\x3e\xdc\x5b\xca\x49\xe2\xa8\x25\x65\xed\x90\x3d\xba\x0d\x54\x71\x7e\x48\xc6\x22\x1d\x05\x40\x57\x55\xcb\xe7\x45\xea\x58\x4a\x32\x9b\x9a\xb1\xd3\x73\x9b\xab\x5a\x86\x1e\xbd\x8b\xb1\x19\x2e\x10\x0c\x8b\xac\x9c\xd4\xe0\x29\xa1\xc4\xe5\xdf\xe1\x5c\x57\xd8\x4f\x9f\xfc\x82\x7c\x36\x6f\x4c\xa9\xc4\x09\xa0\x84\xaf\x71\xa2\x74\xbd\xd0\x00\x40\x09\x8f\x15\x3a\x78\x5a\x96\x9e\x3a\x69\x12\xbb\x75\x81\x27\xb2\x2c\xdc\x54\x75\x7b\x1e\xe6\x88\xab\x24\xd3\xbe\x49\xcd\x4b\x81\x86\x43\x92\x1a\xe6\x3b\x2a\xda\x3c\x94\x28\xa6\x94\x54\x4b\x79\x1f\xa2\xa8\xc0\x8d\xfe\x6e\x7b\x87\x4d\xd1\x93\x6c\xa5\xeb\x90\x3e\x74\xfb\xbf\x1f\xae\x23\x07\x07\x3a\x34\xd0\xde\xca\x67\xdf\xf5\x35\xda\x62\xe2\xe9\xf7\xa7\x53\x81\xca\x84\x0e\x5c\x78\xf0\x95\xa1\xe6\xb7\xd1\x47\xae\x29\x68\xc7\x50\x6b\xf6\xd5\x8c\xb1\x61\x72\x29\xa0\x32\xb0\x16\xb8\x9a\xd1\x63\x17\x9c\x5d\xb2\x6e\x51\x62\x52\xce\xf8\x58\x02\x65\xe4\x63\x10\x93\x49\xcc\xe5\xbf\x75\xb1\xd5\x40\x9f\xd6\x1f\xb6\xae\x1a\x7e\xa8\x5d\x6f\xea\x4f\x24\x00\xb8\x54\xbf\x1c\x73\xbb\x50\x02\xc4\x64\x48\xdb\x02\xf5\x11\x3b\x49\x17\x49\x06\x28\x01\x6a\xb0\xb7\x7e\x7b\x7f\xfd\xd0\xb3\x4c\x51\x02\x2c\x85\xd0\x10\x72\x6e\xc1\xc9\xef\x4c\x7f\x80\x39\xe6\x55\x69\x7c\x4c\xba\xd3\x55\x3d\xef\x42\x08\x63\x55\x86\x3d\x88\xb2\x69\xa0\x6e\x37\xff\xf1\x84\xb3\x7e\x33\x09\xf3\x09\xd6\x89\x9f\x94\x00\xe6\x09\x6c\xb7\xfb\x8d\xc0\x14\x33\x7b\x67\xa9\x4c\x13\xcf\xc6\x74\x03\xd0\xdc\x9f\x8f\xde\x5f\x08\x03\x64\x8c\x35\xcc\x3f\xff\xf9\xbf\x93\x2f\xc8\x2a\xd3\x17\x6d\xfc\x94\x38\x12\x49\x5c\xbd\x5d\xb4\x34\x0d\xe3\x89\x55\x80\x35\x5b\x07\x00\xd0\x6d\xf4\x7e\x0f\xed\xaf\xaa\x7e\xfd\xbc\xed\x93\x12\x6b\xb9\x72\x22\x6b\xb9\xcf\xd8\x5d\x0a\x39\x4d\x9f\x28\x8d\x18\xb8\x1e\x9c\x40\x7b\x84\x45\xe9\x66\x5b\xee\x5f\x60\xe6\x4e\xce\xcf\x14\x11\xee\x73\x57\xd7\xab\x81\x77\x84\xa6\x91\x4a\x31\xf2\xdc\xf9\x86\xe7\xd9\x49\xd6\x75\x26\x06\x56\x12\xa4\x92\x7a\x38\xb7\xa7\x73\x7b\x09\xc8\xa7\x69\x4c\x18\x75\x0c\xa8\x9d\x95\x77\xc5\xe9\xe6\x5b\x55\x79\x80\xc6\x67\x34\x51\x34\x8d\x8d\x83\xf8\x61\x89\xda\x15\xf8\x5c\x5d\xa0\x2a\xc2\x17\x90\x26\x24\xc1\xd6\xb0\xb7\x1c\x7e\xad\xfb\x2a\xee\xaa\x34\xa1\x2e\x30\x7c\x9d\x69\x92\x51\x07\x49\xac\xf2\xf2\xa2\x22\x4e\xd3\x84\x27\x36\xf1\xe4\x34\x5f\x68\xb1\x76\x03\x53\x84\x1f\x1f\x3c\x51\x47\x39\xcb\xfd\xa7\xc4\x67\x20\x9a\x13\xd4\xc7\xa2\xaa\xcd\x13\xfc\x27\xdc\x70\x6a\x85\xf5\x58\x70\x87\x5f\xf5\xd0\xdc\xe9\x4f\x64\x49\x84\x6f\x74\x8b\xe0\xf8\x73\xd9\x5e\x12\x32\x85\x91\x24\x75\xe9\xe3\xbb\x8b\x5e\xfb\xf1\x87\x94\x66\x5c\xb9\xca\x41\x17\xf5\x79\xe2\xb0\xa1\x7d\x80\xa6\x94\x65\xae\x6d\x12\x7c\xb5\x6c\xd5\x1f\x51\xae\x4a\x84\xbe\x5f\xee\x60\x48\x63\x1a\xdc\xd9\x0d\x51\xe5\x0a\x1f\xb7\xd5\xf3\x1f\x43\x26\x9b\xf7\x47\x5d\xa3\xdd\x49\x4e\x1f\x28\x4e\xf8\x34\x66\xf0\xe3\x59\x24\x83\x12\x0c\x5a\x12\x47\x31\x35\x9b\x2d\x46\x13\xc7\xb1\x8f\x90\xba\xe9\x5b\xe5\x44\x39\x12\x2a\x54\xe1\x39\x17\x6d\xbe\xc8\x57\x41\x53\x9e\x3a\x08\x36\x76\x3b\x93\x3f\x47\x7d\xbe\x34\xe5\x2c\xa1\xe3\x1e\xc7\xcd\x3b\xe8\x01\xce\x43\x53\xce\x33\x2c\x66\x2a\x59\xce\xb4\x0d\x26\xef\x80\x4b\x86\x5e\x83\xe7\x19\x34\x00\xc7\x95\xd6\x70\x6a\x3f\x4b\x13\x75\x3b\x0e\xf5\x12\x1b\x01\x91\x84\x04\x03\x0b\x1e\x66\x2a\xa8\x76\x24\x40\x79\x01\x4d\x5b\x95\x70\xd8\xea\xca\xb3\x49\xda\xf3\x04\x12\x49\x53\xa1\x15\xf6\x15\x9c\xee\x3d\x0b\xef\x40\x14\x32\x2b\x56\xd3\x54\x18\xea\xda\x2f\xba\xd9\xbb\xcb\x3f\xf3\xc5\x53\x49\xc0\xf8\xde\x9c\xc7\xaa\x28\x96\xd9\x14\x68\x2a\xa9\x89\xfd\xe6\x77\x28\xe1\xbd\x3d\x60\xcd\xea\x60\x7c\x26\xe2\x60\xeb\xea\xd8\xff\xaf\xe5\xd4\x63\x2a\x41\x60\xcf\x43\x00\x2c\xad\x5d\x5f\xfd\x27\x37\xa6\x12\xc5\xa1\x47\xa2\xce\x64\x7e\xfc\x18\x9d\x24\xca\xe7\x11\x02\x66\xe5\x1b\x94\x73\x5b\xa6\x13\x6d\xf4\xa8\xcf\xcd\x81\x79\x3c\xf8\x60\xa1\x0c\x90\x6a\x0e\x98\xc9\xfd\xf5\x22\xdb\x3f\x64\xb3\x7f\x81\x9f\x01\x06\x48\x53\x2d\x2d\x26\xfd\xa5\x31\x3f\x11\x18\xf3\xb7\xd8\x87\x68\x6a\x12\x8a\x11\xf7\x76\xfd\x70\x58\xaf\x1e\xe3\x70\x3d\xc3\x98\xe8\x13\x90\xcd\x55\x75\x7e\x7e\x99\xd5\x79\x52\x23\x9d\xbe\x3c\x94\xe6\xaa\xaa\xeb\xea\xd7\xea\xb9\x06\x57\x44\xfa\x42\xa9\x8e\xa6\x40\xa2\x98\x87\xa5\x8b\xc0\xa3\xef\xb2\x34\x73\xfe\x03\x9a\xda\x84\xdb\xb1\xbe\xca\x84\xf8\x95\xa6\x36\xf3\xca\x1a\x55\x69\xe4\x2e\x2f\x7a\xcf\x3b\xb5\x5d\x1c\x84\x50\x47\x07\x3a\xec\x69\x38\x97\x5f\xa9\x95\xa0\x78\x48\x98\xa0\xa3\x8e\x66\x72\xc6\xa8\x48\xb3\x28\xd2\x08\x8b\xf2\xfd\x33\x35\x6a\xd6\x87\x63\x09\xd7\x1e\x49\xe2\xd4\xa8\xb6\x65\x7f\x48\xa6\x4c\x4f\x01\x71\x9f\x95\xe4\xb2\x44\x70\xb4\xd5\xab\xeb\x9f\xdb\xdd\xe6\xe9\xb0\xdb\xaf\x7e\xdf\x84\x0b\x25\x2a\xc5\xda\xd3\x8f\xeb\x55\xff\x27\x1d\x21\xed\xec\x8b\x6c\x02\x36\x7f\xd5\x7a\x80\xa0\x0b\xed\x17\x1f\x39\x4b\x34\xc3\xc6\x55\x8f\x1e\xaf\x25\xd2\x2d\x4c\xbe\x8b\x8c\x24\x06\x77\x97\xe6\xac\x10\x56\xb1\x7c\xc7\x44\xaa\xd8\x87\x72\xc3\xae\xe1\x8f\xa5\x40\x13\x3f\x61\xe7\x23\x84\x6e\x49\x7f\x30\xe3\x91\xed\x35\xe0\x11\x45\xfe\xd1\x99\xc2\xed\xf5\xec\x36\x32\x63\xb0\x32\x82\x49\xbc\xed\xd7\x7d\x93\x34\xa3\x44\xa5\x93\x2e\x79\x4f\x8f\x11\x7e\x95\xa6\x99\x13\x6a\x2a\x64\x7e\xdc\xb4\x2f\x37\xf3\xd4\x4e\x46\x15\x63\xa6\xd7\x48\x71\x4a\x1c\xe3\x64\x7e\xc6\x62\x82\xdd\x00\xef\x27\xb9\x79\x77\x19\xbd\x70\x75\x11\x3b\xb5\x9f\xab\x87\xfb\xd0\x8f\x43\x33\x61\x38\x78\xbb\x1b\xc6\xdf\x54\xf5\xf1\x5c\xcc\x9c\x86\x4c\x12\x69\xc7\xd2\x36\x57\xdd\xae\x31\x9d\x0c\xc9\x5d\x87\xf4\xe1\x98\x97\xed\x4d\xde\xbc\xfc\x55\xf2\xc5\x3b\xb7\xc1\x5f\xce\xa4\xa5\x98\x54\xed\xb5\xdb\xcf\xa5\x69\x56\xa5\x79\x94\x1f\x4f\xd5\x87\x2c\x2e\xd3\xbc\x99\x22\x8e\xf6\xbb\xf7\x08\xb7\x4d\x73\x86\x6f\x55\x61\x02\xb5\xf2\x04\xe5\xd0\x6f\x22\x99\xca\x8c\x20\x81\x23\xf1\xbd\xdb\x14\xbe\xe0\xdd\xa3\x99\x16\x49\x34\x96\x12\xf5\x41\xd4\x5f\x64\x58\xff\xea\xdf\x70\x71\x63\xf0\xa5\x5d\x8d\x60\xdc\x4b\x40\x8c\x4c\x5b\x57\x14\xdf\x1c\xf3\x51\x32\x3a\x33\x22\xc2\x55\xf8\xab\x05\xfd\xd2\xff\x51\xbb\xa4\xc2\xae\x95\xa5\x09\x3d\x4c\x7f\xd4\xf2\x74\x9a\xdb\xb2\xcc\x46\x04\xe7\x22\x08\xf9\xfd\xb5\x1c\xca\xfc\xdf\xd9\xf5\x2c\x60\xaa\x1a\xda\x97\xbb\xde\xd7\xa6\x51\x92\x62\x15\xed\x45\x36\x2f\x2e\x37\x1b\xb0\xb5\x93\x65\x44\x23\x12\x53\x97\x3d\xfe\xa8\xef\xe5\x11\x9a\xc3\x22\xe4\x95\xd2\x28\x63\x98\xab\xab\xa1\x94\x47\xd8\x9f\x8b\xfc\xf4\xd9\x48\x95\x51\xbf\x61\x77\xfe\xf0\x21\x99\xf8\x08\x34\x66\x3a\xe1\x3e\x40\x76\x15\x91\x91\x37\x4d\x93\x0c\x52\x9f\xed\x3b\xca\xb6\x57\x42\x9e\xbc\x19\x9a\x30\x83\xcd\xae\xed\x4b\x5e\x9b\x43\xff\x81\xa3\x97\xde\xab\x4b\x51\x4a\x68\x1c\xd8\x2c\x6e\xab\xb6\xad\x7a\xaa\x6c\x1e\x06\x30\xa7\x6c\x70\x70\x3d\x4d\x2e\x88\x58\x5e\x93\x94\x70\xe9\x78\xc1\x4e\x79\xf9\xdb\xf4\x88\x4c\x21\xc8\x82\xec\xab\xdb\xea\x57\xa8\x9f\xc7\x7e\x40\x96\x1a\x34\xb1\x35\x46\xd9\x8f\x97\x88\x94\xbf\xb7\x72\x69\xc6\x38\xc6\xe5\x87\xbc\xe9\xe2\xa7\x95\x6e\xcf\xf3\xf2\x25\xcd\x98\xeb\xc2\xfe\x52\xf2\xd1\x8f\xa5\x24\x89\xc6\xf8\xec\x9b\xba\x3a\x6e\x1a\x5d\x57\xbf\x96\x41\x25\x94\xc5\x11\x72\x43\xb8\x06\xb4\x1f\x63\xc8\x54\x73\xa8\xca\xe2\xe3\x70\x0d\x6f\xbf\xf5\x83\x29\x16\x52\xbf\xed\x77\xe3\x78\x97\x32\xcf\x8f\x79\x38\x9c\x26\x5d\xd4\x23\xff\x9c\x72\x96\x62\x12\x45\x62\xd8\x75\x46\xde\x83\x06\x33\xa6\x33\xe5\x91\xf1\x04\x06\xb3\x4c\x45\x42\x51\xc5\xfe\xe6\xc7\x97\xc1\x0b\x15\x9c\xa1\x39\x3e\x25\x27\xf4\x53\x67\x5f\x2a\x15\x22\xc3\x10\xe5\x54\xc8\x8f\xdd\x47\xd3\xc2\x71\x91\xad\x82\x52\x15\x65\xc2\x33\x79\xed\xa0\x34\x0b\xbd\x8b\x94\xaa\x04\x30\x3d\xb1\xae\x4a\x2c\xe1\x86\xe9\x50\x86\xa0\x3a\xcb\xdd\xc7\x63\xfe\xdf\xff\xca\xc7\x7c\x92\x5f\xa3\x3a\x89\x91\xb5\xf4\x70\x42\xcd\x98\xf0\x57\x1d\xe3\xd7\xfd\xcf\xe4\x1f\xfd\x9f\x20\x49\xf9\xd0\xa0\x3e\x2c\xe5\x60\xf0\xa9\xb6\x71\x24\x3c\x1e\xba\xee\x2f\x65\x98\x32\xd2\xa3\x2e\xce\xa7\x69\xce\x8c\x1a\x9e\x20\xe4\xe1\xba\xce\xdf\xe0\xa5\x2a\x72\x3d\xb9\x39\xab\x53\xdc\x83\x7c\xaa\xd5\xec\xf2\xce\x19\x5a\xcb\x53\x33\x8c\x70\x02\x2d\xad\xcb\xe7\xf6\x74\xec\x8d\xd3\xab\xf7\xc3\x58\xa4\x8c\xf5\x98\xa2\xcd\xd3\x9a\x31\x36\x7d\x13\x2c\xd2\x1a\x5d\x5a\x8f\xac\x7b\x55\x55\xf1\x58\x9c\xdb\x4a\xd7\x72\xe6\x8a\xb2\x38\x61\x30\x4e\x23\x84\xbe\x94\xf0\x53\x31\x63\xa0\x3c\x77\x91\xe7\x50\x5c\x2c\xf4\xb2\x58\x51\x4c\xc2\x23\x91\xc1\x53\x75\x6e\x47\x62\x3f\x73\x3c\xcc\x78\xf1\xb2\x18\x92\xac\x47\x0a\xec\xeb\x6e\x36\xa6\x57\x4e\xb8\x8a\xd3\xbe\xdd\xf5\xf1\xcf\xdb\x65\xd7\x8c\x25\x8a\x80\xeb\x7c\x2a\x70\x07\xda\xb4\x1a\x93\x22\xe1\x51\x12\x2d\xb2\x5e\x5c\x4f\x57\x79\x9f\x1d\x65\xc4\xf3\x9e\xed\x1f\xf6\xab\xdb\xc3\xe3\xc3\xc3\xed\x61\xfd\x70\x77\xb7\xdd\xed\xb6\x0f\xf7\xfd\x20\x4a\x10\x12\xbd\x7a\x7c\xda\x96\xd6\x81\xd3\x16\x4a\x49\x2c\x8d\x1d\x01\xc5\x56\x57\x93\xfe\x0c\xca\xd2\x34\x42\xb8\xc1\x1f\xb7\xa3\x34\x0f\x4b\x33\x81\xeb\xec\xf1\xe9\xfe\xdb\x61\x28\xa7\x87\xa3\xd4\xa2\xdb\xd5\xd3\x39\xf9\x72\xcc\x84\x32\x7c\xfa\x7d\xb1\x94\x73\x8c\xc4\xb1\xb7\xe8\x71\xd4\xbf\xd6\x1d\x12\x42\x0d\x4d\xf0\xdf\xab\x73\x3d\xbf\x7d\x11\x21\x04\xa8\x0b\xd2\x1e\xca\x47\x27\x67\xdd\x9f\x2e\xa4\xeb\x80\xf6\x04\x7a\x17\x9c\x7d\x7e\x5c\x16\x25\xda\x0b\x15\xae\x7c\x21\x71\x3e\x42\xc7\x88\x65\x47\x92\x80\x3e\xb7\xe9\x0f\xd2\xc8\x84\x82\xce\x9d\x7c\xdf\x1f\xe7\x2b\x82\x32\x27\x2d\xfb\x94\x1f\xcf\xd5\x5b\x8e\x9c\x23\xb3\xeb\x53\xa6\x9d\xc8\xed\x8b\xac\xc1\x7d\x3d\xfd\x24\x50\xae\xb0\x99\xe1\x00\xc7\xbc\xbd\x06\x47\xb8\x30\xa0\x25\x18\x03\x8b\xd0\xa3\x43\x03\xb2\xf8\xda\x6d\x66\x3c\x71\xbd\xf6\x27\x57\x83\x70\x9a\x77\xc3\x31\xa4\x54\xea\xe9\xf4\xd0\x85\xbd\xea\xa2\xdf\x0a\xa5\x32\xc3\x38\xe2\xd8\x20\xfd\xbe\xda\x0d\xb8\x78\x1e\xc1\x53\x14\xfc\xd9\x9c\x1b\xf3\x19\x51\xc3\x67\x25\xa6\xd9\x2d\x0b\x4e\x9d\x3b\x50\x3d\x75\xcf\xd7\x1d\x0b\x46\x8f\x49\x4f\x69\xfd\xec\x29\x89\x9a\x47\xa8\xb1\x92\xf1\x36\x2d\x44\x31\x45\x05\x92\x90\x42\x67\xa3\x60\x06\x9d\x62\x3a\x75\x09\x23\x0f\x82\x09\x7f\xe5\x19\x6e\x65\x7d\xc7\x63\x08\x31\xa6\x8f\x6a\x93\x08\x31\xc6\x87\x41\x91\xef\x93\x2f\xde\x5a\x86\xf5\x56\xbf\x1c\x9f\x16\xf4\xe4\x29\x8f\x63\x8d\xdf\xd7\xfd\xcf\xab\xb1\x35\xe6\x71\x66\x10\x3a\xe0\xbf\xac\xaa\x98\x40\x94\x38\x66\x09\xbb\xcf\xf2\xc7\xd3\xfa\xfb\x6a\xb7\x59\xbe\x05\x9e\x50\x65\x7d\x9d\x6d\x7b\xec\xfd\xc5\x70\x50\x3a\xf5\x91\xde\x67\xc5\x1b\xd8\xbc\xcf\xfb\xe1\x96\x42\x81\xd9\xef\x90\x54\xa0\x55\x29\xcf\xc8\xc2\xda\x67\xbd\x38\x11\x10\x24\xb9\x7e\xe4\x65\xeb\xdb\xb7\x27\xaf\x83\x13\x61\xe3\x51\x1f\xcd\x24\x8e\xf6\x43\x52\xe2\xb8\xa0\xbd\x7e\x7d\x7c\xc0\x0c\x9c\x19\x72\x93\x3c\xcd\x62\x7c\x2d\x41\xe6\xb3\x73\x48\x0f\x58\x48\x3d\x9c\xcb\xee\x95\xf6\x03\xb9\xe4\x41\xf8\x37\xd7\xed\xb9\x86\x89\x47\xcb\x53\xee\x2a\xe1\x4e\x48\x39\x4c\xcd\xb4\xa6\xcb\x29\x8d\x3d\x6c\x16\x05\xf0\x3c\x2e\xe6\x09\xa4\x19\xed\x4e\x9c\x69\x9a\xf6\x29\x41\x8c\xdd\x71\xb1\x96\xf2\x93\x24\x14\xe7\x71\x16\xf3\x00\x43\x19\x29\xc4\x87\xc3\x69\x86\xc5\xab\x1f\xe1\x07\x78\xe6\x3e\xcd\x47\x59\x37\xa0\x3f\x65\xf6\xf8\x9f\xd9\x65\x98\xa3\x04\xd8\x57\xe7\x7a\x2d\x9b\x97\x49\x98\xf3\xd7\x38\x0a\x2e\x32\x01\x03\x77\xc0\xe7\x3a\x9a\x94\xcb\xd4\x51\x07\xea\xea\x78\x82\x36\x77\xc2\xfa\x23\xc0\x3e\x57\x51\x9a\x89\x90\xa2\xe9\x1c\x99\xc5\xc4\x1b\x57\x19\xc1\xbc\xeb\x63\x21\x4b\x68\x1f\xec\xc3\x85\xe6\x18\xe5\x4a\xa4\x68\x1b\xda\xaa\x5b\x68\x7c\xff\xd2\x79\xbe\xe1\x98\x62\x98\xdc\x3b\x61\xeb\x37\x4c\xbd\xd4\x65\x3b\xc4\x95\xa6\x58\xe2\x72\xca\x7c\xe7\x1a\x09\x3c\x42\xe7\xe1\x54\x64\xe9\x82\x06\x97\x72\x2d\x28\xe6\xf4\xe0\x08\xf5\x33\x94\xfa\xe3\xba\x96\xbf\xf2\xf2\xf9\xa9\x73\x23\xc2\x6d\x69\x95\x59\xd6\xcb\xba\x8c\xa0\x31\xfd\x65\x4c\x16\xe1\x3e\xe1\x9a\x6d\xa0\xfd\x5e\x9d\x1b\xd8\x98\xe7\x59\xce\x91\x1b\x19\x79\xe1\xf1\x9b\x76\x6c\x45\x80\x45\xcc\x79\x6c\x88\xa7\x4b\x26\xdf\x3f\x48\x86\x3e\xfd\x13\xb8\xa6\xbb\xd9\x35\x41\x45\x99\x4f\xe4\x8c\x1b\xfc\x9c\x73\xfe\x3f\x93\x0b\x59\x86\x64\x81\x2f\x55\x11\x00\xdc\x71\x7f\x07\xd6\x31\xeb\xed\x5a\xb3\xed\x4e\xfc\x6d\xe4\xdb\x73\x1b\xc7\xd9\x80\x9f\x72\xfd\x17\x23\x33\xce\x2d\xa4\x89\xd3\x70\xc9\x8b\x8f\xf1\xd4\x89\xc8\x46\xe8\x8a\x62\x1d\x0f\x5d\x8e\xdb\x9e\x29\x81\x8a\xd8\x23\xd8\x8c\xfc\x58\x0f\xdd\xc1\xdd\x9e\xc0\x63\x33\x00\xef\x2f\x76\xbc\xc5\x95\x20\x12\x03\x49\xe2\x9d\xcc\x55\x51\x4c\x74\xa4\xfd\x10\xa2\xe3\xc0\xdb\xe6\x8b\x57\xfb\x5c\xbf\xc2\xdc\xf3\x10\x04\x74\xe0\x81\xd8\xdd\xec\xaf\x11\x0e\x39\x86\x42\x0a\x02\x46\x04\x75\x92\xa1\x90\x35\xbd\x1f\x02\x8e\x1d\x0a\xa5\x53\x1f\xab\x2a\xe4\x8a\x45\x9a\x66\x48\x21\x8f\x3a\x6b\x07\x3a\xe2\x87\xa4\x22\x15\x09\xc2\x1d\x42\x78\xf8\x47\x55\xae\xab\xa6\x0b\x12\xc7\xfc\x77\xcb\xdf\x82\x48\x2d\x55\x8e\xba\xe0\x39\x3e\xd8\x52\xcf\x23\xca\xff\x59\x0c\xcc\xa6\xfe\x74\xfc\xc9\xb5\x69\xac\x70\x97\xc4\xa7\x15\x42\xbf\xc8\xbf\xc1\x2b\x41\x05\xcd\x8c\x74\xa0\xe1\x53\x51\x7d\xec\x5a\x38\xf5\xd2\xa0\x54\x50\x91\xb9\x0c\x73\x5d\x55\xc7\x9f\xbd\x1d\x10\x2c\x4e\x8d\xe3\x5c\x79\xcf\x8f\xe7\xe3\x5e\xd6\xcf\xc3\x92\x62\x89\x63\xaa\x08\x65\x64\xea\x3e\x16\x7f\xfb\xe1\x76\x19\x05\xe2\x3c\x5e\xe4\x43\x37\x53\x2c\x96\xe0\x4c\x39\x19\x5f\xd7\xcd\x32\x62\xcf\xa0\x42\x30\xd7\x55\xd7\x4d\x78\x90\x12\x98\xce\x85\x90\x0c\xbc\xf0\x2d\xba\xf9\x60\xf2\xf6\x40\xe2\xc9\x06\x25\x84\xe6\x91\xef\xe0\x33\xf0\x70\x1a\x17\x47\xff\x45\x06\x4b\x34\xfa\xcf\xe4\xdf\x93\x3d\x7b\x94\xcb\x13\x92\x69\xe2\x35\x9c\x57\xe5\x25\x65\xe6\x74\xf5\x4a\xa9\xb5\x4f\xa8\xf7\x7a\x6c\x2e\xe8\xfa\x7a\xf9\xa8\x88\x21\xe8\xf9\x5a\x56\x6b\xd9\xe4\xe5\x98\xc4\x89\x0a\x9d\x2a\xcc\x43\xbc\xe5\xf0\x2b\xf4\x50\x4e\xe0\x21\x42\x53\x40\x76\xbf\xc2\xd5\x9f\x7e\x55\xdf\x65\xd3\x2b\x2f\x52\xa1\x8d\x94\xe3\x44\xfc\xa4\x4c\xe5\xc7\x18\xc8\xf0\xc3\xdb\x9c\x72\x3d\xcb\xee\x0a\x48\xad\x17\x17\xb0\xe7\xd2\xfc\x11\x74\xd4\xa9\x00\x95\x71\x9f\xfb\xba\x01\x44\xfc\x21\xe9\x4b\x7f\x58\x6b\xec\x38\x50\x52\xbf\x42\xcf\x5e\x33\xcf\xb3\x0a\xd0\x36\xe1\x43\x4e\xde\xeb\xfa\xfc\x91\xb7\x2f\x8f\x9d\xbb\x33\xa6\x8c\x59\x9a\xc6\xce\xd6\x0e\xef\xcb\xa6\x14\xc3\x3c\xef\x53\xde\xe5\x65\xfb\x55\x1d\x5a\x58\xe1\x7a\x2a\xbc\xe3\xb4\xeb\x3b\x7c\xc2\x43\x58\xe0\x09\x78\x83\xd3\x59\x42\xb7\xb3\x75\xcf\x7a\x03\xc1\xd7\x9f\x5c\x52\x46\x82\x08\xdf\x21\xb1\x43\xf7\x47\xd6\x1f\x5f\x69\x1b\x51\x19\x67\x09\x66\x54\xa4\x2f\x9a\x21\xad\x89\xe3\xaf\x04\xf3\x50\xae\x51\x68\xcb\xf3\x84\x4c\x7f\x2b\xe6\x2e\x9f\xd2\xf4\x8a\xae\x79\x91\xb7\x1f\xa3\x1c\xa3\x4c\xe2\xcc\x6f\x71\xaf\x50\x3a\xcd\xab\xdf\xc2\x21\x6a\x31\xa2\xdd\x3f\xc3\x1e\xe4\xd1\xb1\xaf\x8f\x08\x66\x66\x81\x9d\x24\xca\x38\x0e\xf7\xb3\xc2\xbf\xcf\x9c\x91\xe5\x18\x4b\x12\x9b\x66\xc6\x43\x91\xd0\x31\x89\xa7\x46\x5f\xa6\xdc\xc1\x95\xd7\x4f\x0f\x7f\x5c\xdf\xfc\xb8\xbf\xde\xde\x7f\x9b\x90\x00\x53\x99\x0a\xa7\x37\x7f\xba\xc4\x46\xc8\x54\x73\x8c\xe1\x8e\xf2\xfd\xd6\x85\x71\xdb\x16\x8e\xfd\x99\xc0\x4d\x32\xd2\x6c\x5e\x92\x5a\xa5\x32\x4b\x22\xa7\x7e\xfe\x0c\x65\x7b\x27\x5f\xe1\x6f\x29\x2d\xcc\x5e\x23\xcd\x74\x1c\xf5\x49\xa9\xeb\xfc\x39\x6f\x65\xb1\xaa\xdb\x01\xa3\x2c\xa9\xb1\x4e\xa9\xb6\xaa\x9e\x0b\x18\x3a\x87\xfc\x61\x26\x5c\xc3\x93\xab\x1c\xa0\xf8\xa3\x2c\x8a\x6f\xb2\x1f\xc0\x13\xc0\x64\x9f\x3c\xb7\x95\x07\x20\x04\xad\xc3\xe5\xc9\xe7\x26\x46\x5f\xf4\xe0\x09\x3f\x5c\xc8\xb6\x3d\x9e\x8a\xd9\x0c\x08\x92\x5a\x2f\x4b\xf6\x84\x9f\xc2\x05\x14\x4a\x8a\x34\xe2\xba\x2f\x01\x7b\xfc\x74\x5d\x1d\xbf\x57\x85\x99\x50\xd6\xce\x5e\x50\x67\x5c\x48\x60\x06\xcf\x07\xe2\x61\x04\xc7\x7f\xbd\x76\x64\x1c\x21\x1f\x88\x17\x24\x7a\xf2\x15\xa2\x99\x2e\x2d\x95\x92\xe9\xcc\x37\x07\xa0\xaa\xef\x27\xb3\xa1\x08\x73\xd3\x67\xcc\x5d\x55\x4d\xf8\xd4\xa8\x54\x5a\x60\xed\x7f\x7d\xd4\x98\x5d\x99\xfd\x84\xb2\x10\x09\xdf\xdb\xf0\xa3\x34\x73\x3e\x12\x2a\x0d\x71\x22\xb2\x18\x7a\xed\x73\xec\x97\x7d\x06\xd2\x1f\x66\xae\x42\x77\x30\x15\x34\x88\xc4\xc4\x47\xfa\x2e\xdf\xe0\x16\xb3\x91\x13\x20\xb0\x34\xdc\xc4\xbd\xb2\x4c\x13\x42\x03\x77\x61\x47\x9b\x34\x09\x12\x25\x24\xcc\xb8\xd6\xf1\xf2\x08\x47\xf9\x11\xae\x03\x4a\x62\xc3\xc0\x8d\xac\xff\x9b\x0f\x9a\x87\xfd\x51\x2b\x9d\x0c\x47\xf1\x28\x7d\x23\x1a\x0f\x60\x12\x3f\xc6\x82\x40\x77\x0a\xbd\xf0\x09\xea\x56\x25\x84\x63\xab\x84\xa9\x02\x1b\x21\x55\x24\x11\xb8\x63\x9a\x59\xbf\xd5\x62\xf9\x44\x11\xce\xd0\x73\xf2\x09\x18\x67\xf4\x66\x5f\xa7\x22\x92\x62\x94\xbe\x83\xc2\xfe\x0e\x1f\x0b\x69\x3b\x95\xc6\x14\xe1\x42\x5e\xe5\x39\x20\x97\xfe\x16\x7a\x57\xa5\x99\x72\xb9\x62\xe4\xc5\x83\x3a\x0d\xcf\x92\x6a\xc0\x1e\xa1\xfb\xc7\xaf\x52\xeb\x2a\x8b\x75\x00\x8e\xcb\x62\x44\x49\x46\x55\x96\x58\xf4\xee\x11\x31\x14\x98\xe1\xc6\x6c\x1f\x54\x51\xaa\x51\x52\x5a\x1e\x51\x6c\x6c\x33\xe6\xe0\x6c\xfa\x41\x3a\xf2\x72\x04\x2e\xbf\xbb\xfb\x95\x8f\x48\x62\x56\x23\xb5\x53\xaa\x98\xe1\xd1\x58\x5c\xff\xea\xfc\x31\xc6\x16\x2b\x66\x9d\x92\xde\x37\x99\x97\xbb\xf6\x6c\xed\x52\x2d\x75\x98\x1c\x9e\x01\x02\x25\x8e\x1f\x53\x57\x4e\xf1\xcc\x22\xda\xe0\x98\x97\x79\x89\x32\xb5\xfe\x8b\xe8\x75\x45\xa9\x12\x31\xc5\xfb\xde\x41\x7b\xc0\xd8\x1e\x9a\xf6\x70\x09\x87\x53\x22\x91\x88\x2a\xdf\x55\xc7\x32\x9f\xc8\x0f\x53\x25\x88\x40\xce\xd0\x7f\x54\xaf\x50\xeb\x21\xf5\xaa\x84\x86\xd8\x73\x4b\xf4\x96\xd4\xf5\xa7\x8e\x8b\x6c\x4a\xc6\x3a\xf6\xb4\xd2\x57\xf2\x79\x55\x9a\x6f\xb9\x6d\x57\xae\xcb\x65\x66\xc8\x67\x8f\x2e\x13\x70\xd9\x41\x99\x9b\x39\xb1\x14\x55\x32\x25\xb1\xcf\x92\x5e\xe7\x35\xe8\x8b\x6e\x09\x25\xb5\x8c\xf5\x20\x8b\xd1\x24\xe1\xce\xb5\x8c\x02\x80\xed\x70\xfc\x38\x0c\x9c\x7c\x54\x69\x50\x18\xf1\x1f\xcf\xc5\x88\x28\x7f\x76\x63\x26\x35\x02\x11\x9d\x2e\xe9\xd5\xf3\xfd\x84\xc3\xcc\xc1\x1f\x6f\xab\xe7\xa9\xe0\xf0\x24\x2c\x49\xbf\x0a\xef\x95\x31\x49\x14\x7a\x82\x2a\x87\x61\x35\xc8\x89\x3b\x80\x3c\x95\x31\xdc\xa7\xf6\xb1\xd4\x37\x49\x36\x2b\x1b\x25\xda\x06\x82\xc8\x06\x6e\xe1\x0d\x8a\x1f\xa7\x61\x2f\x54\x36\x89\x30\x67\xf5\x7b\xae\x5f\xd7\xd5\x11\xeb\xce\x28\xdd\x3e\xed\x55\x98\x4e\xa9\xd5\x06\xd5\x00\xbe\xdd\xad\x27\x8b\xc4\x1a\x92\xe9\xbe\xca\xb0\x0a\x0b\x50\x47\x91\x70\x58\x39\xc7\xd3\xbc\xd5\xd5\x08\xf9\xa8\xa3\xce\x68\x07\x74\xbc\x83\x05\x4f\xf1\x8e\x3a\x16\xa0\x1c\x41\xbc\x34\x53\x36\xc1\x51\x1c\xae\x63\x60\x18\xde\x9e\x30\xff\x32\xdb\xff\x74\x12\xb3\xc4\x37\x7e\x4c\xb0\x30\xfb\xca\x7f\x51\x23\x66\x69\xaa\x13\xa5\x3d\xc7\x0b\xe8\x57\xa7\x30\x3b\xab\xfa\x68\x12\x29\xfc\xb9\xab\xed\x7e\xf7\xd7\xa1\xa0\x26\x89\xc5\xad\xdd\xc0\x31\xff\xca\x8e\x69\xc2\x99\xa3\xce\x0b\x39\xc2\x63\x5e\xb6\x87\x5f\xae\x7d\xf1\x20\x8d\x39\xf8\xdc\x6f\xfb\x71\x68\xab\x03\xa6\xed\x2a\x14\x70\x99\x3c\x2f\x31\xb4\x5f\xdd\x7e\x17\x38\xb4\x50\x1f\x97\x37\x65\x9d\x92\x0c\x85\x8c\xb1\x6a\xf6\xa3\xe9\x51\xa7\xfd\x61\xa7\x53\xfd\x52\x99\xa2\x9b\xb3\x59\xab\x84\x4e\x99\x2b\xc0\xec\xfe\x9c\xac\x08\x9d\x2a\x8e\x91\xc0\x9f\xdb\x87\xe9\xdf\xad\x24\xbe\x3a\xf1\x60\x51\xbd\xb7\xe8\x02\xce\x81\x6d\xdd\x8f\xcb\x74\x8c\x24\x6e\x70\x44\x66\xcd\x59\x53\x91\xa6\x86\x50\xb7\xaf\x96\xa3\x72\x90\x66\x60\xb0\xfe\x62\x8b\xfc\x94\x8e\xb3\x49\x9a\xc7\x04\x13\x0c\x85\x6c\x50\x17\xe3\xd7\x88\xb6\x9f\x6a\x41\x08\x17\x23\xb5\x2e\x80\xff\xa2\x58\xf9\x92\xb7\xaa\x05\x17\xc6\xfa\x7c\xd2\x34\xf1\xaa\x85\x70\xfd\x0b\xb7\xd5\xdb\xa4\xb4\xaa\x85\xd2\xe9\xd8\x0f\xde\x96\x0e\x74\xd0\xc5\x14\x9f\x13\xba\x51\x2d\x7c\x17\x8f\x82\xa6\xad\x7e\x5d\x44\x62\xd3\x1b\x53\x49\x82\xb5\xff\xea\x3c\xee\x52\xd6\x8a\x3b\xae\xdc\x90\x29\x73\x52\x2e\xcb\xb2\xaf\xe1\x14\xc5\xad\xe3\x61\x7b\xcb\x5b\xa8\x83\xe3\xd7\x5f\x11\x7a\xe9\x8e\xef\x50\x57\x83\xb8\xfb\x2c\x49\xa7\x75\x92\x20\x4d\xb1\xe7\x25\x43\xe3\x30\xde\x7e\xb5\x36\x0c\xd5\xea\x07\x4a\xc9\xb3\x7e\x75\x29\xf6\xe9\x1d\x01\x31\x18\x21\x6b\x47\x4c\x39\x69\x22\xd0\x00\x44\xb2\x71\x7e\x6b\x6b\x2e\xaa\xa7\xd3\xcb\xd9\xcc\xcd\xc9\xd5\xfe\xb6\x8b\x75\x76\xdb\x55\x28\x55\x6a\x4b\x9d\xe0\x5e\x5b\x9f\x9b\x16\x0c\x86\x22\xaa\xaa\x5e\xfb\xe3\x22\x46\x24\xed\x29\x7f\x87\xe2\xb9\xce\xfb\xbb\xb0\x9a\x51\xd7\x06\x96\x3f\xe6\xe3\x65\x69\x22\xc3\x3c\x1b\x60\x53\x15\x38\xfd\x81\xe5\x73\x66\xac\x4c\x1c\x3b\x18\x49\x59\xf5\xef\xcf\x24\xc2\x49\xb0\x38\x3b\x7f\x95\xcf\x12\x6e\x26\x51\x3c\xf5\x8d\x38\xd7\xd2\x3c\x41\xb1\xd0\xe9\x6f\x12\xad\xe4\x20\xeb\x77\x07\xad\x44\x84\xca\x7c\x96\x16\x6b\xcd\x73\xec\xaa\x49\x40\x21\x93\x5f\xd3\x56\xa7\xc7\xaa\x69\xb7\xba\x5a\x95\xa6\x0b\xc7\xc3\x3d\x93\x38\xb1\xcc\x27\x25\xff\x52\x81\x85\x1a\x42\x92\xcc\xf4\x1c\xc1\x48\x3c\x3a\x53\x39\x08\x03\x95\xc1\x80\x0a\xde\x41\xaf\x7f\xec\x36\x0f\x23\x5a\x37\x6a\x88\xb1\x68\x15\x0c\x80\x69\x66\xb4\x96\xd4\x10\x70\x79\x60\x6c\xca\x69\x65\x31\x66\x87\xea\x8e\x72\x34\x01\xd8\x2f\x87\x21\x24\xe6\x40\x24\x32\xf7\xde\x54\x35\xe4\xcf\x81\x6f\xbc\x1b\x6c\x90\x32\x38\x6f\x76\x27\x28\xdb\xf5\xb9\x69\xab\x23\xd4\xfb\x77\x7f\xd7\x37\x55\x7d\xb7\xfe\x63\x19\xd9\x62\xb2\x34\x56\x51\xcf\x5b\x87\xeb\x75\x6c\x52\x0d\x4d\x2d\x51\x7e\xd3\xdb\x83\x3c\x4e\x43\x0d\x43\x41\x4b\x57\xf2\x6f\xeb\x1c\xde\xc0\x7d\x56\xb3\x79\x62\x8a\xe0\x36\x76\x2e\x67\xdf\xae\xe1\xc4\x20\xec\xb4\x33\x51\xff\xfc\x9b\x35\x15\x23\x39\x60\x0d\x0c\x13\xfd\x0e\x16\xb3\xae\x9a\x76\x5f\x75\x01\xf2\x83\x17\xb3\x9b\xdd\x82\x22\x3a\x92\x21\xf3\x81\xe0\xbd\x4f\x5e\xbe\x62\x14\xd1\x24\xbe\xfc\x61\x02\x2b\x8d\x3f\xac\x95\xb6\x0e\x08\xd8\xfa\xd9\xf5\xe4\xb4\xbd\x27\x64\x4c\x9c\x39\x28\x78\xf7\x49\xa2\xad\x19\x75\x71\xa4\xff\xb3\xf4\x4f\x38\x93\x53\xbc\xc9\x6e\xab\xfd\x51\xe6\xff\x39\x83\xef\x07\xb9\x08\x9c\x26\xf3\x61\x24\xa8\x71\xa5\xb7\x5b\x2a\xae\x4d\xc8\x0f\x00\x9d\x66\x1e\x44\xfc\xa3\x81\xba\xfb\xff\xa5\x9c\xf7\x75\x1b\xb0\x92\x79\x45\x93\x55\xd8\xda\x67\x43\x2c\x8d\xb1\x0a\x72\x82\x1a\x5d\xb4\x01\x35\x30\x59\x33\x56\x39\x4f\x5f\x9a\xb7\x16\xe4\x71\x94\x76\x37\x16\x32\x2c\xd8\x23\x3b\x91\x2c\xae\xf3\xcb\x62\x0a\x44\x71\xa4\x7d\x7f\xad\xe7\xb9\x72\x62\x3c\x13\x63\x0d\x31\x61\xda\x7b\x52\x7d\x83\xde\xf6\x78\x2a\x10\x7c\x2d\x47\xe5\xb3\xa9\xa3\xeb\xcf\x4e\x48\xca\xb3\x00\xea\x43\x79\xde\x06\x15\x71\xd7\x2f\x32\xbc\x48\x20\xc4\xf1\x71\xdc\xc3\xaf\xff\x73\xce\xff\xfb\xdb\x82\x76\x1a\x85\x34\x96\x48\x12\x21\x1d\xdd\xa6\x4f\x18\x5e\xc8\x0a\x4e\x57\x19\xa4\x5e\xfb\x34\xc4\x2a\x3b\x28\x3e\x85\x27\x4c\x5e\x36\x64\x91\x93\x15\xbe\xca\xdb\xaa\x2c\xf2\x12\x90\xc3\x36\xdc\x72\x46\x35\x36\x0f\x76\x71\xfd\x5a\x9e\x9e\x40\xea\x97\x3e\x2b\x01\x99\x54\x84\x0f\x84\xaf\xf2\xbd\x97\xc1\x9b\xde\x5d\x26\x2d\xfa\x14\xff\xcc\x4b\x8b\xf6\xa9\xbf\x80\x8a\x14\x78\x53\x8b\x81\x46\x38\x40\xa3\x2c\xf2\x8e\x94\x83\xac\x6e\x75\x35\x72\x9d\x81\x46\x0c\x29\x2e\x6d\x5d\xfd\x17\xca\xa9\x9f\x02\x94\x13\x64\x20\xbd\xaf\xda\xee\x6d\x8f\x5d\x15\x60\x89\x21\x71\x80\x14\x79\xda\x2b\xec\xc6\xee\x9e\xb0\xe9\x47\xb1\x08\x6b\x58\x63\x47\xa6\x3f\x14\x23\xd2\xd1\x7f\xad\x83\x63\xff\x49\xb8\x37\x9d\x6d\x1e\x51\xf4\xae\xcf\x27\x67\x1a\xf1\xa7\xff\x2e\x78\x71\x39\x9a\x02\x2e\x28\xda\x76\x84\xf8\xdd\x54\xf5\x1a\xea\x36\xb7\xf9\xa4\x71\x6b\x56\x14\x9a\xd7\x88\x86\x89\xe5\xda\x11\x49\xaa\x4a\xdd\xc9\x57\x68\x36\xed\x4b\x68\x11\x58\x64\x32\x4a\xa2\xfe\xdf\x31\x72\x10\x44\xc4\x58\x36\x51\xfa\xaf\x47\x46\xf4\x93\x27\x11\xcc\x62\xad\x01\x43\xa6\xcf\x1b\x59\x40\x58\x23\xa0\x77\x68\xa7\x3c\x21\x20\x29\x45\x6d\xda\xbb\xaa\x6e\xe5\x2c\x13\x09\x92\xa5\x30\x12\xc8\x35\x3d\xcf\xc5\x7c\x3f\x05\xc9\xa4\x1a\xd6\xb6\x1c\x17\xda\xc3\x08\x91\x20\x58\xe1\x66\xb3\x39\xec\x36\xb7\x9b\xf5\xfe\x70\xb7\xfa\xf3\xf0\x73\x75\xfb\x23\xb4\x17\x80\x04\xc0\x7c\xbd\x81\x37\xbf\x93\xf9\x03\x4a\x73\x4c\xde\x74\xb6\x73\xd5\xd3\x7c\xdf\x54\xf5\x62\xeb\xe1\xd4\xbf\x03\x05\x91\xb2\x3d\x16\xb0\xdb\xc2\xbf\x49\xa4\x80\xe8\x2f\xaf\x25\xc3\xfe\x88\xef\x50\x14\xd5\xb7\xaa\x30\xb8\xd0\x62\x44\x7c\x65\x61\x90\x49\x58\xea\xe4\x32\x1d\x51\x2f\x96\x20\x70\x62\x3e\x03\x49\x80\x61\x02\xbf\xbb\x63\xa5\xf2\x22\x2f\x5f\xbb\x1d\x7c\x1a\xbc\x80\x91\x31\xa6\xfd\x4e\xe7\x9e\x76\x7a\xf2\x09\x58\xae\x90\x6a\xf7\x74\x6e\x07\x04\x9e\x8d\xb8\x04\x5f\xee\xa9\xba\x47\xc1\x52\x64\x83\x0f\xd8\x38\x4f\x66\x72\x23\x36\x12\x51\x1a\x20\x27\x08\x37\xb8\xaf\xba\xc0\x66\x52\x5f\xb1\x71\x44\x31\x60\xf1\x6f\x3b\x24\x11\x26\x93\x69\x93\x38\xc2\x14\xa4\x74\xcc\xa0\xfb\xaa\x27\x3a\xb0\xf3\x91\x69\xc6\x9d\xa3\x8b\x15\xec\xc7\xe5\xde\x27\x4b\x32\x8b\x7d\x8a\x12\x89\x70\x4b\x68\x9a\xa0\xdf\xbc\xb8\xea\x2d\xd1\x80\x4b\x61\x8a\xee\xb5\x29\x23\xb8\xc8\x6f\xab\xe7\xab\xf3\xc7\x72\xa1\x69\x76\xa5\x94\x0b\xdc\x4e\x0f\x5e\x98\xfd\x2f\x08\xe3\xa9\x4d\x15\x31\x41\x6d\x77\xff\xff\xad\x32\x61\x33\x11\x59\x1a\xd8\x11\x7c\x96\x6e\x49\x1d\xb4\x1f\xae\x30\x4d\xfe\x58\x57\xdb\xf5\xc3\x84\xc7\x9f\x5a\x0a\x9a\xf8\xc4\xd0\x94\x1d\x27\x80\x32\x2c\x4b\x89\x19\xea\x20\xdf\xce\x0b\x1a\x1f\x9f\x4c\x0e\xe3\x1c\x53\x93\x7f\xfe\xf9\xe7\x1a\xeb\xdc\xfe\xef\x9c\x32\x4c\x62\x1f\x72\x54\x62\xb6\x5f\x45\xac\x96\x4b\x15\x84\xdb\x9f\x64\xf9\xfa\x50\x06\x7c\xf0\x74\x4e\xa4\x88\x50\x93\x77\x53\x9e\x8f\xf9\x5b\xc8\xbf\x59\x29\x21\xf5\xd5\xbb\x89\x52\xe1\x72\x20\x62\xa5\x36\x28\xe6\xd3\x7d\x64\xf8\xfe\xaf\x47\x6a\xa5\xf3\x5f\x84\xc8\x90\x80\x8b\xbc\xe4\x72\xb0\xd2\xc6\xb8\xa3\xed\x7e\xde\xe6\xcf\x2f\x93\xda\xb8\x95\x56\xa0\xe7\xb3\x91\xed\x1d\x60\x64\x37\x3d\x57\xa7\x9a\xd9\x59\x6d\x66\xd9\x3e\x58\xc3\x53\x4c\x47\xf5\x66\x7f\xf3\xdc\xad\xde\x4f\x56\xbe\x51\x29\x36\x7f\xf5\x94\x22\x4f\xc8\x5e\x7c\xd1\x8f\xe4\x87\x43\xcc\x21\x09\xc4\x15\x65\x9b\x97\xcf\xbe\x62\xf0\xc9\xf0\x24\x0a\x4c\x62\x4f\x03\x7e\x3f\x1c\x64\x4e\xf1\xc0\x53\xd7\xb6\x72\x2c\x6d\x13\x2f\xa6\xb0\x2c\x08\x91\xc5\x5e\x5e\xf8\x19\xa5\x6b\xeb\xbe\x34\x61\x41\x49\xa4\xaf\xbc\x93\x55\xdd\x0b\xb5\x86\x63\xc6\x21\xf4\xba\xf7\xee\xea\xad\x5d\xe4\x7d\x93\x23\x63\xc5\x22\x66\xda\x5a\x19\x73\x9f\xd6\x70\x69\xe7\x5e\x0c\x7b\x70\x83\x58\x14\xd1\x18\x33\x93\x87\x67\x68\x77\x2f\xf9\x09\x75\x16\xc7\x17\x62\x51\xcc\xa9\xe3\xf1\xd5\xd5\xc8\x87\x67\x51\x6c\x52\xec\x0c\x9a\xf0\x5e\xb0\x28\x06\x85\x55\x97\xfb\xeb\x3d\x09\x7f\x4b\xb8\x94\x9d\x95\x78\xab\x5a\x78\x28\x5d\x35\xee\xb7\xf3\x88\x1c\x72\xe2\x43\xb0\x28\x11\x80\x3e\xf9\x55\x58\x2d\x93\xf5\xc4\x22\x92\x45\x98\x4a\x58\x57\xe7\x53\x55\xce\xb8\xf3\x16\xe4\x5f\xf9\x58\x99\x7a\xfa\x74\x04\x32\xaf\xca\x89\x5c\x7d\xdd\xf3\x3f\x9e\x55\x91\xeb\xd9\x4f\xa6\x24\xf3\x6c\x16\xed\xb7\xce\x24\xe7\x8d\x53\x87\x5e\x4a\x10\xb1\x28\x05\x0e\x3e\xab\x8f\x2c\xad\xdd\xfc\x6f\xcd\xaa\xae\xe5\x07\x96\x7f\x67\x6b\xff\x5f\xff\x5e\x26\x09\x9b\x5f\x54\xa2\xdc\xca\x21\x77\xf4\x5d\xbb\xd7\xfc\x92\x2e\x63\xfa\x74\x19\x49\x31\x30\xf5\xf6\x7c\x07\x61\x83\xef\x0e\x39\x86\x2f\x4f\x89\x0f\x75\x4f\xeb\x31\xfd\xd5\x4c\x03\xf5\xe4\x5a\xbe\xfb\x23\xc8\xc2\xcf\x06\x52\x0a\xa1\xbf\xb6\xfb\x1c\x3d\x52\x61\x6b\xe6\x17\x64\xb1\xc5\x0b\x3a\x59\x0e\x0f\x07\xbc\xfa\x70\x06\x65\xc9\x28\xb0\x88\x13\x87\xbd\x91\xbe\x43\xfa\x2a\x37\xa9\x9c\xc4\xfd\x2c\xe2\x92\x61\x90\xdb\x7d\xd8\xdf\xa1\x38\x2d\x6c\x43\xd3\xfb\xe0\xc6\x51\x61\x7b\x38\xd9\x2d\xc8\xb7\x45\x8a\x0a\x16\x49\xc2\xb3\x5e\x26\xfb\xba\x17\x14\x62\x91\xcc\x52\xcc\x9a\xaa\xf3\xc7\xcd\x6e\xdf\xff\x95\x3b\xbd\x66\x04\x28\x23\x77\x4c\xfd\x0a\xed\x44\x84\x3b\x8c\x54\x8e\x98\xc7\x09\xcf\xea\x41\x6b\xcb\x1f\x57\x92\x44\x3d\xc0\xd2\x75\x63\x5e\xcb\x56\x8e\xb9\x96\xc3\x48\xc5\xa5\x09\x50\xe1\x63\x20\xe5\x99\xcd\xbc\xb2\x1a\x31\xd2\x3e\xe0\xf0\xc4\xea\xe1\x12\xda\x26\xd8\xa8\xb0\xb9\xdf\x3d\xc1\x1b\xd4\x0d\xf4\xb9\x91\x69\x10\xd0\x8f\x77\xa5\xb7\xd0\xdd\x31\xbb\x9c\x89\x5d\x0c\x95\x37\x9d\x21\xdb\x1a\x97\x3e\x18\xb7\xc1\xb0\xc8\x68\x81\xbd\x95\xce\x45\xbe\x97\x47\x58\x22\xf8\x67\x11\xa4\xda\xfa\x79\xee\xbf\xb8\xfd\x9c\xd9\x79\xf9\x2d\x83\x25\x18\x56\xaf\x6f\x57\xdb\x3b\xcf\x11\x13\x6e\xd1\xd2\x38\xb6\xbe\x68\x1e\x7a\xa7\xfa\x63\x2c\x09\x1d\xb4\xff\x28\x1d\x1b\x88\x2b\x26\x84\xe3\x82\x60\x25\x6c\xf3\x7e\x2a\xaa\x59\x0d\x84\x45\xd6\x98\xb8\x5b\xe3\xdf\xea\x5c\x0f\x76\x9c\xc5\x49\x64\xd0\x2e\x94\xbe\x27\xbf\xdb\x36\x9a\x9e\x48\x32\x0c\xea\xbc\xce\x99\x1e\xff\xd8\x8c\x8d\xbc\xa1\x6e\xb0\x72\x92\x29\x85\xcc\x8f\xd7\x32\x2f\x3e\x6e\xab\x6a\x9a\xbf\x60\x71\x62\x44\xec\x3d\xac\x9d\x2c\xf7\xfb\x3d\xc2\x55\xa7\x63\x48\xa2\xa0\x27\x73\x6e\xda\xea\x88\x50\x85\x3b\x79\x3a\x61\x32\xe2\x3c\x23\x6d\x66\x31\xa1\xae\x3d\xd0\xd3\xe7\x0d\x14\x3e\x3b\xa8\xdf\xf2\x19\x0a\x98\xc5\x44\x3a\x76\x22\x9f\xf2\x09\x81\xfe\x62\xb3\x3e\x8b\xb3\xc8\x46\x6e\xa7\x7c\xbb\x01\x40\x9d\xdc\x70\x24\xce\x10\x55\x5a\xc2\x3b\xca\x35\x84\x3f\x73\x27\x9f\x79\x77\x33\xf2\x81\x59\x4c\x63\x81\xab\xd0\xa5\x2c\x7b\xc8\x90\x5f\x32\x9f\xb8\x7d\xb3\x05\x35\x8b\x75\x17\x23\xe0\xf0\x73\xa9\x8d\x7d\xe6\x3f\x40\xc5\x9a\x41\xba\x98\xc5\x94\x71\x2c\xef\x0c\x00\x8d\xcd\xd3\xb7\x4b\x20\xf2\xfc\xaa\x4a\xca\xde\xfe\xe0\x33\x9c\x9d\x93\xec\x8f\x33\x1a\xa3\x29\xc7\xd2\xe4\xc0\x07\xb1\xaf\x65\x5e\x86\xc4\xc2\xa2\xd4\x09\x8b\x19\x8f\x83\x9a\xc7\x13\x34\xed\xee\x7c\x44\x5c\x48\x4f\xa2\xc4\x62\xa6\x35\x06\x82\x7d\xaf\x64\x0b\x66\x5b\xfe\xac\xda\x25\x04\xc3\x92\x2b\xc2\x62\x1e\x39\xaf\xf5\x97\x2c\xdb\x6d\x7b\x57\xd5\xb0\x7f\x91\xe5\x3f\xab\xf3\x6c\x09\x72\x26\x84\xd7\xac\xc6\x1a\xc7\x25\xd7\x0c\x8b\x65\x16\x19\xe5\xb7\xa3\xe7\xaa\xbc\xc9\xe7\x0c\x08\x2c\x96\x96\xeb\x38\x64\x56\x67\xc9\x50\x16\x2b\x02\x18\x83\x35\xa5\x7c\x85\x23\x7a\xba\x3d\x79\x0b\x8b\x55\x46\x62\x6f\xd4\x42\xdb\xe6\x2e\x40\xc8\xe7\x30\xb9\x85\x06\x8b\x65\x0a\x3c\x16\x2b\xa9\x03\x43\xa5\xeb\xa2\x46\xee\x91\xc1\xe3\x89\x35\x49\x8d\xeb\xa2\x28\x3f\x7a\x89\xb3\xe9\x93\x6b\xa9\x31\x66\x47\x05\x9e\x95\x31\xfb\x6a\x10\xb8\x9b\xd9\x40\x1f\xec\xb0\x58\x1b\xc7\xcc\x83\xcc\x2e\xfa\x55\x3e\xc3\xb5\x0a\x8f\x6a\x44\x24\x22\x8c\xf0\x4b\x8f\xf6\xe9\x8f\x98\x38\x53\x3d\x79\x95\xe3\xbe\xf8\x4a\x0e\x91\xc5\x06\x34\x66\xa5\x1c\x14\x7d\x24\x60\xf5\xa5\x7b\x12\x1b\x4b\xc1\x33\x8b\xdd\x56\x6d\x0b\xf5\x47\x17\x82\x87\xdb\xb0\x9c\x07\x58\xc9\x42\x1b\x27\x8b\x2d\x70\xcc\xfd\xa9\xf3\xc7\x7d\x55\x1f\x67\xa9\x1a\x96\x44\x90\x62\x5c\x79\xeb\x65\x4a\x59\x12\x13\x92\xf6\x2d\x90\xae\xbe\x31\x7e\xf0\x24\x96\x31\x42\x06\x10\x4c\xe4\xb9\x6d\xc6\x7b\x5e\x92\x50\x81\xc4\x48\xa8\x9f\xd9\x79\x4e\xbd\x0a\x0c\x4b\x12\x1d\x21\x41\x7f\x2d\xf3\xc6\xa1\x04\xb6\xb6\x73\x46\x3e\x61\xb8\x60\x09\x49\x41\x63\xcf\x83\x7c\x85\xbf\x00\x2b\x4e\x37\xb5\x84\x50\x12\x3a\xed\x1e\xf3\x77\x28\x56\x35\xc8\x75\x55\x54\x9f\xcb\x1c\x4c\x7f\x39\x25\x31\x92\xe0\xdd\xe5\xba\xae\xbc\xda\xed\x6c\xf2\x52\xe2\x7a\x64\x54\x55\xbd\x1e\x65\xfd\x3a\x9d\x87\x14\x22\x92\xf4\xdd\xc7\x9b\xd2\x5c\x07\x4c\x17\x4b\x32\xae\x30\x82\xcb\x9b\x11\x20\x6e\xf2\x39\x24\x34\x8d\x48\x28\xe5\xaf\x65\xb9\xc7\xdc\xc6\xe2\xfe\x9d\x50\x99\x11\xbf\x82\xbf\x57\xa6\xf8\x2e\x9b\x2b\x80\xb2\xdf\x3d\xa6\x4b\x22\xa1\x2a\x8b\xfc\x26\x36\x67\xd4\x9e\x0d\xb4\xae\xe5\x42\x23\xb4\xe3\x67\xd5\x8e\x85\xec\xff\x67\xe0\xb5\x5c\xf8\x2f\x7f\x05\x16\x65\xb8\xe4\x9b\x5f\xf2\xb4\x9a\x88\x94\xb1\x84\x65\x12\x33\x05\xbb\x73\x0d\xed\x6c\x8d\x31\xe3\x78\x56\x1e\x8b\x73\xf3\x28\x3f\x6e\xf3\xde\x8e\x27\x9c\xb9\x96\xae\x93\x3c\x37\x72\x76\x49\x91\x19\x34\xc3\xbe\x40\x29\xdf\xd1\x84\x24\xb3\xe7\x17\x36\x4d\x03\xff\xe5\xfb\xbe\x0a\x4e\xe3\xa7\xbd\xb2\xcb\xcb\x43\x12\x82\x95\xc0\x91\xbb\x9d\xcc\xde\xa0\x24\x80\x1e\x85\x4b\x5e\xfc\x51\xcd\x5f\x84\xe4\x29\x46\xfc\xdf\x57\xdb\xbf\x26\x55\xf8\xd2\x48\x24\x12\x22\x95\xfd\x05\xe9\xdf\xe3\xd3\x66\xd8\xb2\x12\x2d\x2d\x3a\x50\xc8\x16\x35\xaf\xe4\x87\x31\x46\x72\x47\x77\x83\x2d\x5d\xd7\x57\xe1\x80\x49\x22\x60\x3d\xdc\xf9\x60\x10\x3c\x15\x0e\x42\x12\x21\x06\xe5\x70\x90\xaa\xaa\xdb\xc3\xa1\x3f\x60\x40\x8e\xb4\x4c\xef\xf2\x12\xc6\xda\xb9\x6e\x14\x89\x62\x41\xd3\x51\x39\xff\x1a\xde\xbe\x48\x86\x30\x12\x81\x53\xb5\x47\x45\x4b\x2c\x90\x74\x9f\x53\x59\x19\xb8\x29\x42\x5f\x04\x23\x71\x42\x94\xdb\x3b\x8a\xab\x6a\xf6\x1d\x93\x38\x53\x99\x57\xd0\x6f\x8b\x89\x54\xe4\x27\x75\x86\x89\x93\x4f\x12\x41\x78\xd4\xb7\x78\x41\x19\x1a\x64\xd6\xe3\xc7\x4a\x84\x23\x88\x74\xbc\x89\x97\xf7\x40\x12\xc7\x38\x73\x28\x9c\x91\xff\xda\x65\x27\x69\xac\xb9\xab\x1e\x6f\x8e\xa7\xf6\x63\x62\x79\x48\x9a\xa4\x48\xb1\x71\x75\x2e\xcb\xc9\x87\x45\xa8\xa0\xc8\x03\xb6\xeb\x42\xa0\x71\xd5\x6d\xd9\xb2\x10\x2a\x33\x44\xe5\xfa\xc6\x58\xa9\x5f\x4d\xd5\xbb\x09\x84\x5a\x6a\xc4\x18\x99\x5d\x9a\x31\x32\x70\xf6\xa2\x58\x44\x88\xed\x09\x2d\xb1\xda\xfb\xff\xb6\x24\xb3\x7c\x93\x2c\x8d\xd0\xa1\xb4\x5e\x11\xf0\xa6\x57\x46\x63\x84\x71\xca\x7b\xc5\xbe\x34\xfc\x95\x47\x3a\x19\x0c\xc5\xaa\x7c\x86\x62\x2d\x6b\xb3\x83\x3a\x64\x43\xf9\x92\x27\x48\x78\x9c\xa1\xe9\x40\x64\xd7\x53\xf5\xea\xb3\x34\xe1\xa8\xb2\xa9\xe7\xdf\x71\x7a\xd3\xaa\x92\xb5\xf9\x22\xd3\xc9\x08\x07\x83\x1c\xa9\x6e\xc5\x1c\xae\x42\xf3\xff\xf2\x0c\x0a\x42\x44\x34\x9a\xef\xc6\xc3\x06\xf3\x79\xd0\x4c\x64\x94\x22\x6e\xf1\xd0\x40\x61\xc3\xfd\xc9\x8c\xa1\x12\x12\x14\xf9\x73\xae\x8a\x49\x1a\x9f\x11\x69\x01\x67\xf1\x51\xd6\x79\x33\x59\x34\x2a\x36\x98\xf5\x7c\x02\x59\xdc\x49\x53\xe7\xe6\xad\xb9\xcd\xdf\xa0\x3e\xf5\x25\xe2\x6e\x90\x45\x65\x48\x05\xad\x3a\xeb\x2e\x96\x2f\xfb\x97\xa0\x52\x8a\xbe\x52\x80\x8f\xaf\x9e\xe1\xe1\xed\x13\x88\x37\x23\x4a\xba\x56\xac\xc1\x58\x11\xa5\x89\x1e\x87\x84\xfb\x97\xba\x2a\xfb\x38\x94\x68\xc9\x03\x4a\xf3\x0e\x9e\xe5\xa4\x50\xc9\x88\x56\x99\x70\xfa\xd0\xce\x34\x3c\xd8\xb5\xe3\xf1\xfe\xf0\xe2\x40\x8f\x30\x82\xab\x75\xe3\x65\xa0\x25\xc5\x69\xb8\x1d\x92\x19\x44\xeb\xc4\x09\xb5\xba\x8d\xf3\xe1\x34\xcc\x92\x31\x19\x06\xca\x87\x21\x6e\xf9\x5e\xd5\x4d\x7f\x1b\x90\x68\xa4\x30\xbd\x49\x7e\x3c\xf6\x8e\x00\x01\x49\xb0\x09\x3a\x0f\x2a\x36\x63\x09\x37\x46\x6c\x6c\xc0\xe1\x57\x3f\x76\xd0\x85\xd6\x37\x70\x21\x3b\x37\x9b\x3e\x9b\x8a\xd4\x2f\x92\xc5\xac\x27\x23\x56\x48\xed\x81\x05\xee\xd7\x9a\xdf\x66\x1b\x37\xb1\x42\x41\x68\x0d\x9d\xc2\xfd\x91\xd5\xe4\xd3\xc6\xf7\xbf\xfa\xa0\x2f\x09\x7b\x19\xb1\x26\xc3\x04\xd1\xa6\x7d\xc1\xf7\x76\x03\x60\x94\x1c\x7e\xc4\x0d\x4b\xa3\xcc\xe9\x1b\x9f\x6b\x95\xb7\x7d\xb2\xbe\xf9\x29\xcf\x45\x78\x3d\x69\x04\x34\x55\x01\x5d\x10\xac\x8c\xc3\xdf\xb8\x36\xae\x71\x6e\xff\xbb\x6c\x5e\x46\xb8\x4d\x96\xc6\xc4\x29\x57\x3c\xd7\xb2\x0c\x5a\x77\xe3\x0f\x21\x8d\x39\xa3\x72\x50\x8b\x74\xad\x50\xfe\x58\x62\xb2\xd8\xc7\x65\x7d\xc8\x01\x66\x06\x66\x58\x7c\x63\x29\xa1\x2a\xb4\x08\xaf\xe5\x18\xc7\xc3\xd2\xee\xc3\x49\xdd\xfb\xbf\xa9\xea\xbb\x0f\xfc\x9c\xcf\x23\x70\x3f\x4b\x33\xa6\x42\x35\xe7\xee\xa3\x8b\x2d\xca\x41\x37\x98\xa5\x19\xa7\xb8\x9b\xba\x6d\x07\x9f\xc6\x67\xf5\xc3\x08\x96\x72\xf0\x79\x8f\x6d\x89\xd5\xb4\xbc\xfd\x70\x8d\x44\x9e\xd9\xfc\xa2\x5e\x7a\xd1\x1e\xcf\x52\x9e\x39\x5a\x79\xd7\x70\x6a\x26\xed\xcb\xd3\xf7\x9d\x72\x2a\x1d\x89\x7f\x75\x54\x79\x89\xf5\xb3\x79\x05\x8a\xa5\xdc\x30\x24\x30\xc0\x94\xcd\x63\x51\x21\xf4\xbe\x27\x44\xba\x6c\xc4\x5c\xd8\x97\x53\xa1\x0c\x0f\xc9\xb7\xbe\xe7\x62\xf9\x15\xc8\xd8\x26\x7e\x27\xbb\x87\xf7\xd6\x07\x5a\xfb\xfd\x9d\xa7\x9e\x4d\xc7\x44\x6a\x2c\x95\x42\xc5\x5e\x24\x1d\xd3\x6c\x15\x86\xe2\x03\x7e\xde\xcc\xd6\xae\xd4\x8a\x78\xae\x5f\xbc\x90\x70\x5f\x84\x08\x3f\xaf\x62\x8a\xb6\xf7\x15\x3e\x7c\x44\x7d\x21\x6c\xcb\x52\x45\x8c\x4d\x07\xdb\x73\x80\x50\xd7\x65\xa9\x12\x0a\x75\x4d\x36\xfb\xef\xef\x49\xff\x47\x1d\x47\x81\xbd\xfd\xd0\xbe\xd4\x00\x78\xed\xcd\x7f\x9c\xf0\x88\x1f\xa5\x49\x8a\x61\xc6\xf7\xfd\x7a\x3d\x59\xec\x9a\x39\x82\x89\x53\x9d\xbf\xe5\x05\x3c\x0f\x8d\xa0\xd3\xa9\x33\x2a\xc5\xb6\x15\x4f\x45\xd0\x56\xaf\x65\xe7\x6a\x86\xcb\x80\x49\xd0\x87\x34\xa0\xda\x0b\xb1\xe8\x31\xba\x87\xa5\x56\xb0\x20\x47\xfd\x04\xa3\x62\xf4\xec\x5d\x59\x29\x85\xd7\x5b\xef\x67\x1c\xf5\x99\x7b\x86\x91\x6e\x8c\xc1\xb0\x36\xa4\xf4\x31\xd9\x36\xee\xf1\x9e\x35\x4c\x4c\xd6\x8d\xb5\x4c\x83\x4f\x79\x8e\xe5\x3f\xdc\xe1\x2c\xa2\x91\x08\x9f\x6b\xf7\xad\x7a\x6f\x2f\xf4\xec\x2f\x46\xa3\x59\xd4\x7d\x8a\xb8\x09\x75\x3b\xe7\xfc\x8a\xd6\x6d\x0d\xdd\x27\xd8\x78\x65\xd7\x21\xac\xc9\xe2\x88\x60\x06\xf8\x65\x64\xea\xb2\x24\x66\x28\x9f\x78\xcc\xcb\x3e\x55\x37\xb7\xbe\xa3\x6b\x24\xdc\xe9\xba\xac\x57\x8f\x43\x03\x06\xcb\x08\x07\x11\x05\xd3\x73\xf2\xbd\x87\x4f\x55\x01\x8b\x00\x2c\x96\x11\xc3\x5c\xd5\xbd\x46\x06\x67\x4f\x44\xfb\xd1\x5f\xce\x26\x88\xb8\xee\x8e\x81\xd9\x57\x46\x7e\x6c\x4b\xd7\x42\x19\x5e\x4d\x96\x5a\x17\x78\xe0\xb2\x4c\x0e\x50\x36\x67\x24\x88\xc1\x74\x8e\xa3\x94\xcd\xab\xb2\xd7\x35\x76\xfa\xdc\x57\x1f\x71\x14\x85\x2b\x64\x32\x46\x8b\x67\xab\x5a\x03\xf2\xd7\xcc\xe6\x33\xd3\x26\x41\xf8\x6d\x50\x58\x67\x19\x8d\xe2\x20\xc3\xb7\x2a\x8a\xc7\xba\x7a\xcb\x0d\xd4\x9e\xa8\x6f\xfa\xaa\x28\x55\x8e\x9e\xc5\xef\x7a\xbd\x8e\xfd\x25\xa6\x98\x65\x94\x51\xec\x91\x40\x59\x8a\x5c\xff\xac\x8a\xd7\xe6\x97\x7c\xee\x3f\xa3\x8c\x32\x9d\xea\xf0\x6e\x1f\xab\xea\x34\x71\xd5\x33\x6a\x08\xbe\x97\x6d\x55\x8e\xea\xe5\x2c\x63\x71\x14\xa4\x50\x5c\x41\xf1\xb2\x69\x81\x65\x4c\x46\x68\x49\x77\xbb\xeb\xeb\xfd\xfe\x8b\xc6\x00\x96\x31\x10\x98\x02\x0f\x0f\x55\x83\x19\x55\xa7\x59\xc6\x59\x8a\x1d\xc2\xb7\xab\xfd\xf6\x7e\x0c\xb7\x67\x19\x17\x4e\x2b\xea\x88\x2a\xb2\xd8\xe2\x85\xc5\xa0\x9e\x96\xa6\x1f\x47\xb0\x0b\x20\x44\xdf\x79\xd9\x42\xd9\x7d\xef\x8b\xe5\xbf\x4c\x10\x00\x18\x76\x8c\xfb\x11\xb4\x71\x7a\xeb\x82\x59\xc4\x57\xea\xaa\x69\x6f\xaa\xda\x13\x66\x23\xeb\xc1\x27\x8e\x72\x26\x40\xa6\x8e\x24\xac\x7a\x3d\x9f\x76\xa7\x3a\x6f\xe7\x6b\x44\xc6\x4e\x82\x4c\x9d\xd1\xb3\x72\x64\x3b\xe1\x51\x24\x49\x90\xdb\xe2\x6a\xbd\xda\x2d\xe2\x5b\x27\x37\x28\x85\xeb\x93\xc1\x91\xa1\xf1\xeb\x22\x90\xff\x0b\x17\x29\x5c\x4b\x2b\xf4\x07\x8b\xf2\x4b\x14\x17\xcb\x14\x05\x44\x00\x0f\x6c\xe7\x00\x06\x01\x89\xb3\x71\x52\x01\x04\x2c\x45\x0d\x97\xb5\xeb\x4c\x41\x84\xc1\xd0\xdd\xd3\xd5\xed\xe4\xc5\x2b\x9b\x10\x0f\x0a\x0f\xf5\xa4\x2a\x14\xb0\x16\xb7\xf6\x4c\xf3\x04\x1b\xdd\xbf\xc9\xe6\x47\x03\x66\xf6\x43\x5a\x39\x79\x1f\xbf\xc9\x3e\x56\x55\x31\x6a\x51\x9d\x8d\xd5\x2a\x26\x03\x7f\xfe\x2d\x48\x3b\xf8\x08\xb3\xa9\x30\x34\x0a\x48\x5a\xd7\x7d\xb8\xbc\xe0\x20\x31\xe8\xa2\x34\x6d\xaa\x5f\xc7\x5e\x56\x06\x89\x13\xe4\xb9\x7b\x78\xc2\x42\xd4\x5f\x84\x9f\xe1\xac\xcc\x48\x5f\x15\x57\xb3\xd2\x4c\x66\x89\x41\x44\xda\x5b\x0e\xbf\x0e\x35\x48\xf3\x31\x96\x64\x9a\x5e\x88\x46\x5c\x27\x0e\x68\xdd\xcb\x53\xfe\x16\x0e\xe9\x0c\xc9\xda\x0b\xd9\xb4\x8f\x83\xd3\x46\x63\x9e\x22\x58\x00\x6a\x9d\x44\xd3\xac\x0d\x4d\x52\x8e\x8b\x7f\x77\xb5\x9d\x5c\x2b\xd1\xd6\x35\x37\xfb\x64\xcf\x85\xee\xab\x1f\x47\x0c\xc7\x72\xd0\x8d\x54\xa3\xb2\x1c\xcd\xac\xc3\x27\x60\x5b\xb3\x2c\x5c\x16\xbb\x8b\x58\xba\x27\xdb\xd7\xd0\xbc\x54\x85\xf1\x1f\xf3\xec\x8a\x34\xca\xd4\x10\x6e\xfb\xee\x20\xec\x85\xbd\x1a\x8b\x27\x86\xd1\x82\xa1\xdb\x06\xc7\xbc\x1d\x2f\xd7\xbf\x97\x0a\xa3\x8c\x1b\xed\x3b\xb0\xbf\xff\xb1\xf6\x73\x33\x7e\xdd\x94\x33\x43\x3c\xd0\x39\x6f\x02\x15\x43\x2f\x85\xe3\x07\x89\x84\xe9\xcc\xcb\x0a\xef\x4e\x52\x03\xea\xda\x2f\xff\xa4\x50\x82\xaa\xfe\xf9\xb6\x2d\x1c\x27\x55\x99\xf9\x68\xcd\x85\xaf\x73\x78\x4d\xde\x7a\xd2\xca\xe8\x87\xc9\x84\x4b\x32\x34\x4e\x3b\xca\x87\xd9\x18\x25\x52\x27\x0d\x5d\x9d\x3e\x4e\x5d\x70\x1b\xee\x5e\x59\x8a\xa1\x4c\xde\x74\x57\x36\x7f\x45\x60\xc1\xa8\x16\xae\x1b\x41\x05\x17\xed\xa1\x98\x39\xb1\x54\x9b\x04\x33\x9e\x57\xfb\xfd\xe3\xe6\xa9\xd7\x3d\x66\x14\x88\x40\x88\xa6\xca\xdb\x4f\x61\x62\x61\x28\x4d\x59\xe2\xc1\x3d\xad\x13\x8b\x18\x9b\x52\x0a\x4a\x63\x84\xb5\x7e\x91\xf5\x33\xec\xa1\x8f\xbc\x59\x24\x53\x3e\x56\xf5\xee\xe2\x81\x45\x38\xc4\xf4\x17\xbb\x7d\x94\x78\x6e\xde\xdd\xa9\xfb\x12\x97\xc4\xcb\x19\x4b\x04\x60\x92\xa0\x3a\x41\x28\xb3\x8c\x78\x7a\x18\x4b\x8c\x45\x1f\xec\xad\xea\x45\xfb\xc2\x21\x12\x03\xf3\x66\x6d\xbd\xfe\xee\x18\x4d\xc4\xe4\xb1\x18\x49\x93\xa4\xd7\xcc\xf0\x7d\x92\xcd\x24\xd2\x67\xa9\x89\xb2\xe0\xcf\x75\xa1\xe5\x18\x5a\x3e\xb9\x56\xc6\x28\xae\xef\xf6\x05\xf6\x7d\xb7\x4c\xf7\x67\x9d\xa2\x5c\x4c\xf3\x53\xd6\xf9\x08\x4c\xcd\x18\x95\xbc\xe7\xa8\x3a\xb7\xf0\xe4\xf5\xbd\x9c\x5f\xf6\x5d\x86\x88\x32\x4c\x05\x55\x31\xf5\x20\x37\x64\xae\x36\x72\xc9\x9c\x32\x46\x9c\x12\x75\xf7\xd7\x55\x5e\x5f\xd7\x55\x70\xb6\x18\x4f\x5c\x2d\xb3\x06\xdb\xd9\x05\xe7\xd1\xa2\x1a\x47\x67\x23\xa0\x6e\x10\xe4\xd3\x8f\x26\x51\x60\x16\xda\x94\x6d\xfd\xd1\xc5\xe5\x5f\xf6\x9c\x33\x26\x88\xe5\xbe\x4b\x4d\x57\x81\xfe\x93\x31\x91\x26\x58\xf7\x3c\xca\xba\xce\xe5\x33\xdc\xe6\x1a\x4a\x0d\xc8\x0b\xb7\x7d\xbc\xd9\xbd\xc8\xa0\x21\xcd\x98\xa0\x11\x5a\xe8\x36\x6d\xc7\x56\x92\x09\x90\xbe\x31\xd7\x3c\x56\x4d\xfb\x50\x5e\x61\x12\xef\x4b\x98\x0c\x13\xa0\x3c\xb3\x25\xd6\xed\x9f\x64\x39\xcb\x5e\x30\x49\x5d\x6b\xd0\x40\x45\xed\x7b\xa9\x7f\x3b\x5f\xb6\x6c\x33\x26\x8d\x73\x57\x5d\x82\xbd\xdb\xd6\x6f\xaa\xfa\xa1\x84\x1e\xcb\xdb\x0d\xc9\x0c\xef\x09\xda\x10\x79\x7c\x27\x3f\xae\xf3\x66\x8c\x30\x61\xd2\x50\xc4\x43\x79\xaa\x09\xc7\x67\x1e\x00\x01\x4c\x25\x46\xd1\x71\xd3\x1b\x66\x53\x9a\xfe\x30\xcd\x50\xc7\xb8\x45\x16\xa1\xa1\x46\x11\x0e\x73\x6b\x75\xd0\x3f\x2c\xc1\x75\x62\x4e\x37\x23\xa6\xb5\x44\xba\xd6\x73\x59\xe4\x4d\xbb\xaf\xab\xd3\xcb\xc7\xec\xd3\xd3\xda\xa9\x48\x75\x06\xfb\xf7\x6f\x23\x0e\x40\xc6\x4c\xca\xc2\x77\xe3\xd4\xf7\x26\x8d\xe5\x8c\x41\xac\x62\x3a\x6e\x8d\x08\xbc\xf9\xb7\xf9\x31\x9f\x7f\xe2\xe0\x73\x69\xed\xa4\xe7\xbe\x8b\x5e\x96\x5c\xb3\x10\xeb\x33\x48\x28\x32\xab\x4d\x68\xf7\x0a\xa9\xa0\x98\xd0\xee\x31\x06\xd2\xe1\x16\x50\x3c\xfa\xdc\xb4\x41\xb6\x36\x1c\xb7\x94\x20\x46\x70\xb3\xff\xf9\x34\x79\x0a\xab\xa3\xa0\x46\xd9\xd7\xd1\x67\xcb\xc7\xea\x18\xa9\xdd\x8d\xfc\x68\xf6\x55\x88\xa8\xa6\xcf\x67\xc1\x62\x5c\x1a\x9e\x0f\x61\xe8\x61\x79\xcd\xb6\xce\x21\x32\xe4\x11\x95\x38\x87\xd7\xd5\xfb\x68\xbb\xe7\x91\x49\x82\xa2\xa4\xd3\x2f\x03\x07\xd1\xda\x3a\x41\xf0\x5c\x15\x79\xf9\x3c\x96\x03\x63\x3c\x8e\x14\x0d\x71\x73\x6f\xd8\x78\x9c\x71\x47\xf6\xd9\x40\xfb\x5d\xe6\x35\xa6\xdc\xe8\xf4\xde\x79\x4c\x13\x4c\x90\x54\xc8\x6d\xb1\x29\xcd\xe8\xaa\x54\x60\x19\x75\x65\xe4\xa9\xed\x93\x58\xcb\x7b\x2b\x8f\x35\x41\x92\xf8\xc0\x26\x67\x72\x0d\x4f\x55\x51\x2c\x7a\x84\x9d\xb3\x8a\xb4\xcd\x77\xdb\x7b\xac\x9a\x05\xaa\xc9\xc3\xf6\xfe\xd0\x53\x20\x30\x4e\xa8\x0d\x06\x1e\x4d\xc9\x38\x0d\xe5\x87\xa4\xd2\x38\x36\x63\x67\x62\x67\x8d\x87\xb3\x9b\x4c\x0d\xa7\x3c\x4c\x6d\x99\x77\x7e\xf0\xa6\xdb\x34\x42\xe6\x86\xa7\x40\x2c\xe9\xbb\x35\x1d\x8c\x64\x56\x03\x9b\x3e\x48\x96\xa6\x68\x7f\xe4\x58\x1d\x65\xfe\xb4\x19\x98\x24\x76\x50\x77\xdf\xbc\xe2\xf4\x9c\x83\xf8\xe9\xca\x18\xb8\x00\x4b\x87\x73\xad\x12\x7c\x24\xfa\xe4\x73\x2e\x73\x4a\x05\xc6\x69\x94\xa1\x65\xde\xff\x39\x5e\xe2\x9c\x0a\x8d\x6d\xc5\xcf\xc5\xb9\xdf\x97\x38\xb3\x12\x11\xd1\xb7\x55\x6d\xba\xa5\xf7\x58\x23\xa6\xe6\xef\xe6\x92\xa7\x93\xca\x23\xc0\xf4\xfb\xef\x1f\x0a\x6a\x2f\x30\x35\xbb\x37\x6e\x53\x9c\xd6\xd0\x6c\xd8\xad\x5e\x4c\x34\x87\xd8\x7a\xbc\xcf\x72\x11\x8b\xc4\x7a\x6c\x5e\x69\xf3\xfa\xd8\x85\x57\xae\x3c\xe3\x03\xe0\xd9\x1a\x10\x99\xc5\x90\xe5\x20\xcd\x5b\xe7\x43\xad\xd1\x9d\x5c\x4c\xc1\x73\x21\x34\x84\x17\xf6\xeb\x1e\x7e\x79\x9d\x8f\x59\x76\x81\x0b\xe1\xb8\xf2\x6e\xbf\x4d\x42\x72\x2e\x89\xab\x6a\xa1\x07\x5b\xd5\x93\x02\x2a\x97\xa9\x4e\xed\x18\xa4\xbe\xaf\x9e\xa0\x0b\xf9\x2f\xb9\x74\xc3\x19\x19\xb8\x8c\x2c\xc2\xa6\x77\x98\x24\x9b\xdd\x89\x54\x14\xb7\xcb\x00\xef\xec\x56\xf9\x7c\x88\x65\x18\x47\xe6\x0d\xf6\xb1\x75\x4f\xbf\x72\xbc\xbe\x41\xdb\xcf\x0f\x54\x5e\x80\xd2\xfd\xdc\xb4\x1b\xe2\x2f\x7c\xfc\xbf\x03\x24\xe2\x4a\xb9\x8a\x70\xb7\x65\xc8\xe2\x2b\xd5\x70\xc6\x95\x6f\x1d\x3a\xd4\xee\x0d\xdc\xc9\x57\x78\x2c\xbe\xe0\xba\xf7\xe7\xe9\x84\xa7\x97\xcc\xb2\x5f\xd0\xca\xf2\x70\x22\x89\x30\xa8\x76\x0c\x86\xc9\x61\xa0\x2f\x67\x5c\x53\xce\x21\x10\x6e\xe8\xd7\x4b\x96\x1c\xc6\xb5\x66\x71\x8f\x10\xec\xac\xa1\xdb\xb7\x6f\x72\xb5\x80\x4b\xe6\x86\x02\x16\xde\xec\xb9\xd4\x0e\x58\x5d\xae\xea\x67\xfc\xda\xc7\x50\x8e\x19\x22\x8a\x1b\x1e\x07\x56\xb8\x3b\xf9\xee\x25\xcd\x77\xa7\xca\xbb\xf7\xe1\x51\x8c\x70\x41\x46\xd1\x6d\xb6\x3d\xd4\xd4\x1f\x84\xc8\x25\x51\x1b\x58\x12\xca\x0a\x97\x00\x96\x38\xc1\x5a\x03\x4d\x5b\x57\x33\xd7\x80\x83\x30\x48\x84\xd3\xed\xbd\x77\x70\xac\xea\x8f\xce\x6d\x7a\xae\xf3\xf6\x03\xeb\x50\x84\x8c\x73\xd9\x1c\xb4\x81\xb8\xb7\x9b\xb3\x6b\xd9\x28\x43\x1e\x90\x5d\x55\x54\x47\x78\xc7\x17\x37\xc2\xe4\x73\x9b\xb8\x56\x34\x33\x6b\xc4\x5b\x7e\xff\x36\x15\xd8\xfc\xbf\x83\xf6\x7c\x7a\x92\xd6\x16\xb3\x76\x9c\x30\x4e\x5b\x04\x43\x48\x97\x37\x69\x6e\x65\xd3\xae\x0b\x90\xf5\x85\x44\x33\xe3\xd6\x4a\x9f\xf3\x40\x7b\xb3\xaf\x4e\x3f\x4e\x0b\x8e\x8c\x88\x12\xa1\xdc\xf6\x70\x74\xe0\xc5\xd5\xd3\x9f\xe3\x46\x74\x26\xa2\x14\x20\x20\x12\xa4\x52\x79\x7b\x87\xed\x5e\xbb\xf3\xf1\xe8\x1d\x02\x3f\x30\xd6\x2a\x0e\xb1\x4b\x91\x43\xd9\x76\xf7\xe7\xae\xb5\xbd\x5e\xae\x95\x88\x44\xa4\x58\x88\xbb\xda\x07\xcc\x98\x48\x80\x21\x9f\x41\x9f\x32\xad\xab\xf3\x29\x9f\x9b\x33\x41\x04\x48\x87\x7a\x6a\xce\x50\x07\x48\xaf\xe7\x49\x9b\xb3\x95\x31\x91\x11\xa7\xaa\xf0\x7b\x17\x2f\x95\x3b\x28\x6c\x17\x64\x24\xfd\x61\x4e\xd1\x9c\xaf\x8a\xf6\xea\xfc\xf1\x55\xb3\x75\xe7\xec\x6b\x44\x78\xbc\x79\xbc\xe2\xa6\x34\xd5\xaf\xa5\x2d\xfa\xef\xfe\x1b\xae\x1b\x53\xa4\xe1\x0c\xab\xff\x3a\x6f\x50\x61\xe9\x6b\xb1\x1f\x26\x68\x62\x07\xf8\x65\xb3\x84\xdc\x13\x2c\x02\xec\xe0\x73\x49\x05\xdf\xc8\x0a\xba\x3a\x1e\xc1\xe9\xfa\x7d\x6d\xa1\x04\x4b\x32\xdc\x23\xee\xf2\x12\x61\xab\xb2\xee\x99\xce\xba\x83\x0a\x7d\x45\x4c\x3e\x4c\xab\x9c\x82\x25\x80\x74\x2d\xdf\x9e\x7e\x4e\xff\x2e\x5c\x11\xeb\x19\x4a\xa4\x02\xda\xbc\x9f\xbe\x0d\x19\x6b\xc1\x20\xd2\x64\xa8\xbd\x62\x66\xe7\xfe\x1c\xbc\x5f\xc1\x59\x86\x02\xcf\x06\x6c\x17\x63\x04\x25\xaa\x90\x30\x5a\xb4\xce\x82\x6b\xd0\x23\x36\xdb\xb1\x5c\xe1\x72\x69\x79\xde\x38\x9b\x4e\xb7\x88\x70\x59\x13\x2b\x8c\xb5\x3f\x5c\x7f\xc5\x41\x4d\x10\x03\x42\x24\x8c\x9a\x50\xe7\xdd\xb6\x70\x0c\x16\x46\x48\x92\xa2\x36\x7f\x83\xec\x5d\x48\xde\x37\x5e\xb1\x32\x65\xb8\xcc\xf6\xff\xf8\x7b\xac\x08\x4c\x48\xe9\xe8\xf1\x90\x2f\xb0\x3c\x0f\xf1\xd3\xf4\x65\xaa\x14\x1c\x82\x1d\x21\xda\x7e\x5b\x5d\x5c\xbb\x1e\xb2\x32\x3a\x55\x64\x34\xf1\xb0\x9b\x90\xb2\xef\x9f\x47\x09\x8d\x88\xf0\xef\xff\x98\xbc\x6a\x25\x0d\xc6\x04\xf6\x0c\x21\xbd\x2f\x34\x4b\x43\x2c\xe6\x7c\xd1\x87\x5f\x33\xd4\x66\xc8\x20\x08\x2d\x52\x2f\xeb\x7b\xcc\xcb\x83\x34\xb3\x4c\x92\xd0\xe0\xa0\x7f\xf0\x0e\xda\x7b\x1b\x23\xd0\xfe\x7c\x3b\x12\xc6\x68\xea\x29\xc8\xae\x64\xf9\x0a\xf5\x5a\x96\xc6\xa9\xc5\x9c\x2f\x94\xc6\x99\x80\x28\x09\xf8\x0d\x27\x43\xd8\xb7\x1f\x4f\x39\xad\xfb\xe1\x22\xf6\xe1\xe7\x75\xf5\xab\x2c\x2a\x39\xe6\xa1\x67\x02\x62\x8d\x90\xd5\x83\xf6\xf0\x78\xac\x06\xe5\xea\x12\xab\x17\x4e\xf0\xc2\xae\xff\x0b\x2a\xef\xdc\xda\xff\x9f\xd8\x3e\x61\x33\xd7\x4c\x7f\xaa\x4e\x71\xb8\x29\x6b\x2c\x1d\x11\xcc\x8c\x41\x10\xdd\x31\x11\xe8\xdf\x5d\x2f\xae\x8b\xdc\xbe\x62\x30\x65\xc2\x82\xa0\x9e\x83\x73\xd3\xbe\xac\xe5\x69\x07\x45\xb1\x2d\x6f\x42\x52\x47\x46\x24\x02\xd5\x37\x65\x9a\xea\x18\x8a\xe4\x48\x03\xdd\x8f\xa2\x8c\xf8\xe4\xd1\xef\x1f\xba\x73\x94\xf3\x7a\x8a\xa8\x1b\x42\x4f\x19\x09\x61\x7c\x54\x11\xd4\xea\x9b\xfe\x42\x86\x52\x1f\x14\xcf\x90\x6a\x0b\xdb\xac\x8c\x65\xea\x34\x04\x5d\x7b\xf1\x6d\xa5\x5f\x67\x9f\x90\x8c\x8d\x48\x1d\xd3\xe1\x59\x15\xd0\xbd\xea\xf9\x00\x4b\x32\x9f\x97\x7d\x38\x81\xe7\xa1\xd8\x3c\x0f\x9c\x03\xa3\x3b\x4f\x62\x07\x8d\x6d\x2b\xc7\xd3\x7f\xc8\x75\xe8\x5f\x90\x89\x04\xf4\xed\x31\xd3\xd7\x0c\x34\x24\x4c\x92\xd8\x91\x73\x63\xa5\x3c\xe9\xff\x6a\x21\x8d\xfb\x70\xb0\x75\x3b\xfe\xe4\xe5\xc8\x54\x68\x44\x71\x77\xcb\xbf\xae\x8a\xc2\xb3\xa4\x2e\xbf\x4a\x99\xa5\x09\xf7\xf0\x7f\x34\xd4\xb3\xe7\xcc\x14\xc1\x6c\x3c\x6e\xd6\x79\x9b\xbf\xc1\xa3\x6c\x5f\x3e\xa3\xf1\x09\x27\x69\xa6\xa9\xcf\x7f\x5e\x83\x2e\xf2\x99\x28\x24\x93\x19\x38\x75\x97\xce\x57\x0b\x3a\x58\x3f\x9a\xbc\x7c\xbe\x46\xfe\xea\x81\x75\x24\x3c\x37\x15\x34\xed\x69\xd2\xfa\x0d\x34\x74\x7d\xfe\xed\x30\x70\x64\xd8\x25\x95\x0c\x3b\xad\x4b\xf8\xd5\x45\xd6\x47\x59\x60\xda\x68\xbe\x14\x58\x96\x62\x17\x69\x23\x8b\x37\xf9\x0c\xf7\x15\xca\x8a\xfe\x0a\xed\x78\x3b\x28\xdb\x7d\xf5\xa9\xc8\xc7\xec\x5a\x8a\x63\x8e\xcc\x6d\xd3\x9b\xd0\xce\x06\x17\x5a\x98\xa3\x53\xb4\xcb\x88\x8c\x53\xd9\x9b\xf7\xb6\xbe\xdc\xdb\x96\xdf\x05\x4f\x12\x24\xfa\x40\x61\xf5\xdf\xfa\x3f\x72\xe2\xd2\x2c\xe7\x13\x2a\x41\xf6\xf4\x2a\x8b\x95\x7c\xc9\xb9\xc0\x20\x2c\xc0\x6c\xbb\xf7\x73\x3e\x1e\xcf\x65\xe7\x5b\x7b\x11\x49\x3f\x54\xc4\x11\xca\x7d\x62\x52\x25\xa0\xca\x87\xfc\xbf\x14\x84\x62\x5f\x06\x6e\xf9\x48\x29\xe0\xc4\x07\x9f\xeb\xaa\x27\xd8\xea\x46\x69\x0d\x5e\x9d\x0a\xea\x6f\xd0\x7a\xd8\xdd\xfe\xfd\xea\x4b\x72\x65\x26\x05\x38\xb5\xce\xed\xf5\x60\x96\xa5\x12\x4e\xdc\x5e\x55\xae\xcd\x7a\x5f\x4d\xe0\x17\x7e\x94\x26\x54\xa7\x9e\x88\xa4\x9e\x6a\xb2\x33\xa9\x53\xc5\xfc\x46\x81\x52\x72\x27\x39\x5c\x5e\x33\x41\xd2\x71\x32\x6d\xb5\xc5\x18\xfd\xd4\xf6\x6d\xd4\xb3\x6f\x54\x0b\xc0\xbd\xff\x84\x98\xa9\xfb\x1e\x7a\x2c\xb5\xb5\xd8\xcd\xae\xa4\x79\x76\xbc\x70\x9f\x02\x5f\xfd\x19\xc6\xb8\x86\xac\x9f\xd5\x3b\x14\x4f\x70\x92\xae\x43\xe2\x7c\xa1\x90\x38\x0a\xa5\x24\x64\x1c\x83\xf8\xbb\xd5\x9f\x87\xfd\xc3\xef\x9b\xfb\xc3\xd3\xe6\x8f\xd5\xd3\xf5\x2e\xdc\x07\x88\x54\xd8\xbe\x11\x33\x9a\xdd\x3e\x48\x8b\x00\x69\xdf\xbf\xfa\xa3\xac\x97\x99\x7a\x99\x04\xe3\x94\x6b\x03\x93\x79\x7f\x7d\x90\xc8\x71\xb3\x7a\xcf\x03\x09\xc4\xe6\xbd\x85\x51\x2e\x4f\xda\xd8\x60\x1a\xc9\x04\x84\xe9\xf4\xca\x96\x19\xa1\x47\xfc\xf4\xde\x8c\x7c\x5d\x53\x92\x56\x80\x57\xba\x1b\xde\x9f\x8a\x22\x45\x7c\xf8\xe9\xb8\xa6\x9c\xf4\xc2\x60\xc2\x55\x94\x24\x48\x08\xe1\x3e\xd5\xee\x85\xce\x7d\xd1\xf1\x60\x96\x21\x3b\xdc\x4d\x31\x01\x49\xa9\x48\x53\xb4\x24\xfe\xeb\xef\x8c\xcd\x14\x7d\xaa\x08\x23\xd4\x21\x38\xeb\x06\x6e\x2b\x59\xa2\x3e\xd7\xc8\x78\xff\x4b\x0c\xad\xd8\xec\xdf\x1e\x90\xf4\xaf\xf4\xdf\x63\xc3\xa6\x08\x8f\xec\x58\xfa\x4e\x16\x3e\x07\x35\x8b\xf8\x15\x91\x1c\x71\x1c\xea\xfc\xb1\xf2\xfc\x03\x93\xd9\x52\x44\x59\xc4\x29\x22\xb0\x6e\x94\x7c\x50\x69\x2a\x51\x5d\xc4\xf3\xf8\xfe\x01\xf9\x24\xad\xa4\x52\x4a\x10\xfb\x8c\x5f\xc4\xf1\xdc\xc2\x05\x95\xfe\xdc\x9d\x59\xd8\xa8\x55\x0a\x49\xc2\x83\x3a\x72\x55\xdc\x00\x5c\x70\xc9\x32\x95\x65\x29\x73\x34\x4f\x6f\x39\xfc\xea\x19\x9c\x86\xd7\x91\x75\xab\xcd\x95\x88\x71\x83\x5d\xee\x5f\x50\x99\xe0\x99\x0a\x82\xa8\x9b\x77\x0d\xa7\xcb\x86\x5f\x95\x49\x89\x5c\x97\x4f\x9b\xdd\xe6\xe9\xe7\xc6\x7f\x3b\x93\x26\x58\x95\x19\x85\x28\x1d\x69\x8c\x67\xa2\xf0\x07\x58\x96\x60\xd2\xa0\x79\x91\xe4\x3b\xbc\x2f\xa6\x99\x15\x93\x89\x23\xe4\x93\x47\x08\xdd\x26\xb3\x3b\x65\xda\x62\x07\x6e\x51\x3d\x4f\x9b\x48\x14\x33\x11\xf6\x35\x6e\x4c\xde\x5e\x57\x5d\xc0\xbf\xe4\x00\x29\x41\x8d\x65\xbe\x2d\x66\xaa\x57\xcb\x94\x60\x49\xa0\xd3\xe8\xec\x9c\xb3\x93\xd3\xb3\xb5\x63\x7d\x44\x45\x5b\x47\xbb\xe2\x58\x98\xe7\x15\x67\xa5\xa2\x24\x72\x7c\xab\xad\xac\xd7\xe7\xfe\x37\x54\x6c\xd0\x7c\xec\x1e\x1e\xbf\xc8\x84\x85\xc1\x89\x41\xe2\x8e\x03\x6e\xfd\xd8\x9d\xb5\x35\x1b\x27\x55\x35\x1b\x49\x8c\x13\x6a\x6e\x5f\x1c\xbe\xb0\xff\x3d\x6a\xb8\xef\x6b\xab\xce\xed\x65\xab\xae\x52\x20\x89\x1c\xe1\x71\x6f\xf3\x66\x91\xa8\x92\x29\x4d\x04\x46\x2b\x4e\xbd\x60\x2d\xcb\xaa\xcc\xb5\x2c\x86\x20\x63\x1c\x9b\x5c\x34\x17\x2b\xad\x05\xd6\x63\x7b\x91\xb1\xaa\xb4\x79\x00\x6a\x28\x0d\x02\x49\xc0\x15\xb4\xdb\x60\x06\x95\xc9\x42\xdf\x44\x69\x7c\x2c\xf7\x7f\xce\xf0\x89\xb8\x3d\x53\x10\xbb\xc0\xfb\x54\x57\xc7\x6a\xdd\x4b\x37\x33\x65\x69\x86\x85\x84\x9e\xd3\x75\x66\x7b\x2c\xc8\x20\x54\xfc\x6d\x86\x49\x70\x23\x74\x4c\x69\x14\x7a\x71\x73\x73\xf5\xe1\xc0\x55\x50\xaf\x5c\xb7\xda\x14\x25\x19\xce\xb1\x69\xe2\x88\xba\xe1\xea\xfc\x11\x42\x12\x4d\xa8\x44\x9a\xd1\xe6\x04\x58\x07\xec\x3c\xaa\xa5\x76\xbd\x30\x5c\xb0\xb4\x87\x01\x56\xe5\x04\x9b\xfa\x63\xc0\x34\xfa\xd1\x69\xe2\x6a\xc4\xea\x9c\x17\x66\x6b\xa0\x6c\x73\x9b\x7f\xce\x5e\x30\xe9\xe1\x0a\xfc\x19\x63\x1e\x8d\x51\xd1\x75\x68\xfa\x1d\x7f\x12\x3a\x95\x09\x6a\x90\x7c\xdb\x8d\xaa\x62\x3a\x55\x06\x78\x2f\xd3\xe4\x2a\x92\x9f\x3c\x60\xa6\x0d\x84\xfe\xbd\xa4\x37\xf6\xd9\x60\xec\xb3\x7f\x87\x91\x90\x11\x07\xb0\x7b\xbf\xbe\xff\xfd\xeb\xdd\x4e\xa3\x8a\xa1\xef\x3b\xc5\x8e\xa7\xbe\xf9\x67\x91\x10\x43\x53\xcd\xd0\x4f\xf2\xf4\xc9\x7f\xc8\xa2\xe8\xa3\x35\xcd\x92\x0c\x13\xa6\x48\x6a\x66\xab\x7a\x0d\x43\x59\x68\x51\x89\x75\xf9\x9f\xc1\x32\x6b\xc6\xb5\x2f\xfd\xbb\x12\xc9\xf4\x66\x98\x75\xe4\x9a\x65\x85\x68\x80\x60\xfe\x34\x8f\x9d\x8e\xf9\xbe\x8b\x1d\x9e\xee\x7e\xef\xff\x4e\x22\x84\x14\xf6\x1a\x53\x5e\x80\x37\x1c\x36\x12\xb2\xa9\x5a\xfd\x6d\x5e\xbe\x42\x3d\x22\xc3\xf1\x43\x05\x4d\x10\x0c\xed\x1a\x56\x57\x65\x59\x9d\x4b\x1d\x7c\xaa\x30\x86\x59\xdf\xdc\xd1\x0b\xe4\xcd\xee\x5f\x1a\x13\x93\x50\xa9\x35\x9f\xc1\x0f\xb5\x8e\x2d\xc6\xb5\x27\x59\xb7\x1f\x87\xd0\x4c\xac\xb5\x8c\x31\x02\x2d\x30\x07\x2c\xf3\x23\x98\x11\xd5\x3c\xd3\xda\x28\x0f\x39\x6a\xdd\x6b\x9a\x87\x20\xfd\x38\x87\xd5\xf1\x9a\x52\x0e\xdc\xec\xbd\xd3\x71\xfa\x68\xc6\x58\xcb\xb4\x89\x1c\xe9\x38\x0a\x0c\xeb\x57\xf0\x44\xba\x87\x26\x3f\x9e\x67\x56\x51\x1b\x41\xc8\x88\x86\x6b\x91\xd1\x7b\x6a\x17\x8c\x14\x28\x58\xb5\xd2\xdd\x46\xdb\xa0\x33\x54\x9d\xaa\xe2\x63\x7e\x65\xa9\xb0\xff\xd4\xc2\x54\xdc\x99\x69\xc8\x9c\x50\x52\xdf\x98\xf2\x60\x1f\x1c\xc2\xa3\x5f\x29\x40\xad\x03\x99\x96\x4e\x00\x76\x76\x6d\xb0\x3c\xf1\x32\xd2\x37\x55\xfd\x9c\xbf\x81\x41\x6e\xc8\xc9\xa7\x6d\xc1\x51\x95\x5c\xaf\xfe\xe9\x2f\x6b\xe2\xc4\xa9\x90\x39\x3f\x6e\x42\x9b\x31\x24\xd4\x2e\x18\x6e\x47\xdb\x80\x89\x45\x1c\x1c\x2f\x4c\x50\x69\x1f\x77\xc7\x9f\x74\xad\x99\x58\x13\x39\x46\xe4\xae\x5f\xc6\xed\x09\x8b\x91\xa3\x89\xad\x63\x2b\x73\x2d\xf9\x21\xdd\x6f\x92\x98\x22\x16\x1c\xad\x63\x5e\x3e\x37\x07\xcc\x5c\xf6\x87\x89\x42\x78\xa3\x2f\x71\x2d\x47\x99\x61\x2c\x35\x14\x86\xae\xe3\xb2\x6a\x9f\xc0\x09\x50\xad\x7a\x77\xc8\x24\x2c\xd1\xfe\xbb\xbb\xc9\xeb\xa6\x45\x16\x8c\xa6\x27\x86\x67\x86\x48\xc7\xb4\x72\x5b\x3d\x3b\xef\xdb\xac\xab\xe3\xa9\xc8\xbb\x69\x79\xac\xab\xca\x2e\x92\xba\x31\x93\x26\x56\x47\xc1\x0f\x71\xd5\x01\x6f\xb0\xa6\x73\x97\xc5\x31\x62\x11\xb1\x5d\x05\x93\x72\x3e\x72\xbd\x19\x02\x4e\x93\xc5\x82\x89\x51\xc2\x72\x60\xed\x6c\xc7\x70\x40\x43\x95\x4c\xe2\xa0\xf9\xd4\x6b\x82\x8c\xdd\x7c\x43\xb5\x6b\xe5\x3e\xf7\x51\xd1\x6f\xe3\x49\xeb\xe6\x2c\x0a\x01\xf2\x65\x68\x68\xa8\xb1\xc8\x4a\x70\xb5\xdd\x0f\x93\xc8\xd2\x18\xa3\xf8\xdd\xea\x76\x73\xd8\xdc\x5f\x1f\xae\x57\xfb\x4d\x7f\x90\xb3\x80\x1a\x5f\x6f\x1e\x66\x97\x63\x22\xc3\x78\xdb\x65\x9e\x06\x89\x48\x66\x78\xda\x13\x30\xdd\xc9\xbc\xf4\xf9\xe9\xba\x5d\x95\x26\x28\x25\x2f\x5a\x2c\xc3\x99\x48\xd2\x91\x80\x7f\xe7\x27\xfe\xd9\xfd\xea\x6f\x4b\x9b\x8a\xe1\xd2\xe9\x23\xae\x2b\x54\xa7\xcb\xdb\xed\xfa\xe1\x33\x98\x66\x38\xc5\x2a\xc1\xfa\x4e\xd2\x5b\x79\xae\x41\xb6\xd5\xe4\xc3\x34\x82\x48\xe6\x01\xc7\xc8\x59\xf1\x59\x0b\x91\x11\x69\x8c\x0e\x64\x17\xeb\x3e\x3e\x6d\x7f\x8e\x66\x4e\x64\x3a\xd8\x90\xce\x7c\xca\x87\xf3\x5b\x6e\xaa\x3a\x9f\x21\x36\x8c\x90\x1a\xe3\xb2\x7b\xf8\xe5\xd2\xa3\x77\xf2\xf5\x13\x16\x1f\x23\xa3\x08\xfb\x33\x76\xa7\xbc\x34\x05\x4c\x96\x86\xcc\x34\x6e\x1a\x4a\xb6\x45\x55\x9b\x81\x26\xc3\x48\xe3\xa4\xfd\xf2\x32\xbf\x50\xee\x9f\x14\x04\xc6\xf9\xc5\xd1\x5e\x6a\x94\x00\xee\xf6\x52\x78\x93\xc5\xb9\x0b\x30\xf7\xdf\x17\xbc\x38\xa3\x64\xcc\x49\xa0\x12\x46\xbf\x5d\xaa\x02\x9a\x11\x23\x8c\x51\x92\xe3\xfe\xa7\xce\x1f\x03\xd1\xf0\x74\x52\x75\x22\x10\x6b\x7c\x38\xe8\xaf\x80\x11\xc6\xc4\x8e\x90\xc2\x73\x22\xac\xf4\x92\xc0\xd7\x85\x60\x24\x33\x86\x70\xe4\x92\x3a\x15\xb2\xec\x3e\xb0\x21\xf6\x34\xdd\x0b\x85\xde\xaa\x5f\xcb\x76\x26\x31\xc6\x8c\x51\x0e\xe9\x75\x2c\x3f\x6e\xc1\xb6\xdb\xd2\xb3\xca\x86\x2b\x40\x2c\x53\x2f\x65\xd2\xf6\xaa\x0c\xd0\xac\x82\xba\x79\x73\x49\x20\xd3\xdf\x18\xc4\x16\xbb\x4b\x6d\xfe\x3e\xa2\xd2\xae\x3f\x76\xf8\xd4\x8b\x74\x57\x06\x12\x27\xeb\xf9\xfd\x5c\x3e\x77\x27\xf4\x2e\xa2\x81\xc4\xd5\x42\x57\x98\xc4\x18\x65\x1c\x0c\x08\xf0\x56\x44\x55\xf3\xf2\xb4\x01\x2b\xb1\x10\x54\x95\xc5\xc7\xea\xa8\x64\xd3\x48\x33\xa4\xc3\x8d\xa5\xae\xb3\xf1\x98\x97\x8f\xb5\xb7\x79\x03\x0e\xa7\x1f\x65\xd5\x40\x82\xf3\x04\xcf\xe7\x42\xd6\x8e\x46\xc5\x0d\x80\x28\xa3\xd2\x37\xa2\x21\xed\x46\xfd\xdb\xd2\xc7\x0a\x11\xa3\xa9\x8f\x07\x3d\x5a\xfb\xe6\x0c\xc5\x3c\x18\x84\xc8\x3a\x4e\xcd\x43\xc0\x1d\x4d\xf2\x6b\x10\x47\x89\xc8\x1c\xef\x70\x0d\xc6\x2b\xa8\x4f\x7f\x28\xce\x12\xe5\x10\x9b\x08\x3e\x73\x4e\x55\x38\x66\x99\xb1\x3d\x56\x78\x75\xc1\x0d\xcb\x20\x21\x19\x36\x4b\xa8\xc0\x4b\x35\x3b\x6c\x1c\x28\xab\xaf\x58\x20\xb5\xdb\xf8\x35\x42\x9a\x46\xf8\x1a\x7f\x3e\x01\xb4\x3f\x42\xad\x03\x32\x9e\x22\x6a\xd2\xeb\x91\xaf\x9e\x76\x9b\xf5\x61\xfd\xb4\xb9\xde\xee\x0f\xbb\x1f\x8f\x8f\xb7\xc1\x71\x00\x9a\x45\xf8\x5d\x1d\xf3\xf2\x90\xf7\x90\xf8\x83\x17\xa3\x1b\xf5\xe8\x01\x4b\x38\x72\xaf\xba\x4e\xcc\x2e\x8c\xdb\xbc\x9f\xaa\x7a\x3e\x23\x2c\x71\xd5\x00\x5f\x27\xbd\x86\xa2\x47\xca\x02\xd3\x51\x42\x7c\xdc\xe8\xa6\x7a\x5f\xcd\xb2\x70\xc0\x20\x89\x3d\xb3\x75\xff\x27\x0b\x58\xd8\x78\xb8\xdf\x3c\x6e\x9e\xd6\x9b\xfb\xbd\x4b\x72\xec\x0e\x8f\x9b\xa7\xc3\x90\xc8\x05\xae\x13\xf4\x5b\x9d\x40\x56\xae\xab\xba\x9c\xf8\xe9\x20\x22\x89\x26\xa2\xb2\x16\xea\xab\xaa\xae\xab\x5f\x41\xac\xed\xcb\xa8\x05\x44\xe6\x00\xbb\xa7\xb3\x7a\x85\x8f\x20\xa3\xc3\x40\xc8\x08\x01\xa8\x36\x2f\xa0\x59\xc6\x4a\x81\x50\x71\xa8\xe7\xad\xea\xfa\x16\xca\xe7\x61\x52\x85\x4d\x84\x03\x42\x19\xbc\x8b\xc9\xcb\x95\x11\x55\x7c\xdc\x35\x8e\x53\xd6\x99\x8f\x70\xba\xa4\x36\x09\x95\x92\x4b\xa0\x05\x48\x2d\xb0\xaa\xe4\x80\x4a\xe3\xaa\x6b\xf0\x58\x40\x89\x4c\xbb\x45\x2a\x5d\x7f\xea\xe1\x2d\x0e\x94\x8e\xa0\xb4\x8d\x7a\x0d\xf4\x66\x22\x5e\x17\x46\x40\xea\x5c\xf9\xbf\xac\xeb\x7e\xba\xb3\x82\x4e\x74\x50\x8b\x5a\xbd\x3d\x3f\x9e\xfa\x8b\x1b\x12\xa3\x02\x47\xf7\x6d\x16\x98\xd6\xef\x53\x07\x60\x78\x1c\x0d\x0a\xef\x18\x86\x5c\xd7\xb9\x9d\xcf\x80\xb1\x91\x60\x7e\x45\x3c\x42\x3d\x22\x30\x0b\x17\x02\x29\xb0\x44\xbf\xee\xfe\xdf\x42\x52\x17\x00\x2c\xda\x24\xbf\x5d\x3c\x94\x97\xbd\x0e\x60\xb9\xc0\x92\xd4\xf5\xe6\xe7\x61\xbf\x59\xdd\x1d\x1e\x1f\x9e\xf6\xbd\xf4\x3f\x03\x2b\x38\x96\x3b\x37\xef\x8e\x89\x64\xe9\x77\xac\x8e\xd0\xcb\xc5\x6f\xd6\x9f\x68\xa3\xc4\x62\x7e\x56\x57\xf5\xd7\xb4\xd8\xcc\x46\x19\x60\x58\x32\xb4\xef\xbb\xf5\xf2\x58\xc3\x56\xcf\x7a\xa6\x6c\x44\x25\xba\xc9\x8e\x52\x1f\x69\x66\xe7\xc1\x5a\xd8\x5e\x6c\x44\xad\xb5\x43\x48\x7c\x93\x17\xc5\x8f\xd3\xec\x7a\x71\xa2\x39\x8c\xfc\xaf\x55\xb3\x3d\x76\xc6\x21\x2f\x9f\x97\x59\xfd\x99\x8d\x95\x42\xf6\x98\x53\x0d\x36\x7f\x07\xf3\x5d\x36\x2f\xc9\x7c\x8c\xcd\xd0\xb5\xfd\xfd\x5c\xc3\xa8\xed\xd3\x26\x69\x84\xeb\x5e\x62\xa8\xb6\x93\xba\xee\xc2\xfe\xd9\x5b\xb1\x89\x51\xb8\x5f\x4d\xe5\xf3\x51\xda\x32\xd8\x16\x4b\x04\xc3\x78\x4c\xa1\x31\x80\xda\x35\x60\xdd\xe4\xb2\x9d\x64\x8f\x2d\x11\xd2\x93\x69\xbf\x42\x89\x19\xc8\x49\x26\xc2\x12\xc9\x12\xd7\xd5\x90\x37\xd3\x2c\x96\x25\x56\x51\x11\x96\xaa\x7e\xc9\x4b\xf8\xbb\x54\x3d\xb3\x37\x9c\x0a\x8e\xfb\xbc\x27\xe3\x43\x25\x3d\x28\xcd\x1c\xa6\x64\x53\x15\x65\x3d\x41\xd2\xb1\xd2\xd8\x84\x34\x09\x54\x6c\x16\xc9\xc4\x04\xd0\x80\x9e\x02\xea\xc2\x10\x46\x11\x8a\x1c\x52\xf6\x37\x75\x75\xf4\x41\xcd\x72\x5d\xd0\x52\xa1\x11\x4f\x87\x65\x33\xd7\x5f\x55\xd5\xdd\x8f\x07\xe2\xcf\x51\xd6\xaa\xff\x27\x9c\x0b\x94\xf9\xb6\x85\x95\x67\x5d\xff\x36\x17\x8b\x60\x96\x29\x10\xee\x6d\x55\xdd\x2a\x9b\x55\x64\x2d\xcf\x74\x90\x63\xfb\xd1\x98\x4d\xfb\x32\x5b\x10\x5c\xbb\x4a\xcb\xb3\x3c\xc2\xe3\x20\xf1\xcf\x2c\x37\x4c\xc9\xc0\xa3\x6b\x3c\x8e\x77\x7a\xae\x20\xe0\x9a\x50\x26\x24\x83\x77\x70\x5c\xe6\x13\xb5\x92\x64\x01\x4e\xe4\xfc\xf3\x49\x0f\x97\x55\xb1\xc1\x82\xcc\x76\xfd\x30\xaf\xec\x58\xa5\x65\x08\x4f\xbb\x25\x5b\x42\x71\x03\x97\x04\x63\xb3\xc9\xd7\x89\x43\x10\xd8\xaa\x28\xaa\x5f\x4b\x60\x45\x6b\x80\xa3\x85\xc0\xa6\xbb\x6f\xbb\xfd\x38\x79\x64\x21\x72\x55\x31\x2f\xbc\xfc\xc7\x66\x1b\x6e\x15\x58\x86\x5c\x1a\x9d\x8d\x1d\x5a\xb9\xfa\x2f\xc8\xc6\x04\x4d\x14\xea\x62\x79\xb0\x6a\x9f\xe2\xb2\x56\x31\x6c\xf3\x3c\xf9\xb6\xd2\xa7\xa1\xa4\xca\xa3\x88\x2a\x44\x86\x1c\xe5\x2b\xdc\xe6\xff\x39\xe7\xe6\xb1\xce\xc3\xc1\x38\xa1\xd1\xdf\x83\x0c\x7d\x01\x45\x09\xd7\xa2\x31\xf3\xd5\xb4\xc9\x8a\xe2\x51\x0c\x8e\x3e\xa0\xcf\x98\x99\xdb\xea\xf9\xb9\xf3\x47\xa6\xe3\x12\xea\x38\x47\x3c\xba\xb2\xf3\xcb\xdd\x32\x5d\xfc\x16\x78\x94\x68\xa9\xf5\x14\x23\x7c\xf5\x81\x3e\xa0\x93\xd4\xf9\x80\xc5\xd0\x94\x47\x84\x51\x04\x47\xae\xf3\x9e\xbe\x63\x40\x79\xf2\x88\x18\x0e\x8e\x28\xeb\xde\x57\x7a\x7e\xdc\x6f\xf7\xe1\x68\x9a\x12\xac\x83\x8c\x40\x3e\xf8\xe5\xc5\xfd\x00\x9a\xe2\xbb\xb4\xe7\xd2\x34\xfb\xca\xfb\xbb\xd3\x5b\x4f\xa9\x25\x2e\x07\xd5\x05\x8b\xb8\xb5\x7a\x8b\x76\x0b\xe6\x79\xa1\x5e\x36\x3b\x5d\x25\xda\xe9\x6b\x3b\x41\xa0\xf0\xd3\x0c\x9c\x44\x74\x58\x09\xf7\x55\x38\xc2\x13\x17\x3d\xbd\x55\x3d\x22\xaa\xff\x1a\x78\xc4\xa9\x8d\x5d\x77\x9e\xd9\xec\xbf\xdf\x85\x4d\x80\x47\x5c\xbb\x24\x4d\x67\x72\xc3\xf7\x38\x31\xbd\x3c\x12\x91\x44\xf7\xbc\xa8\x9e\x77\xbf\x00\x2e\xd3\x53\xcb\x2f\x4f\x68\x97\x56\xce\x1b\x2f\x2a\xeb\xc3\x83\x7e\xe1\x0a\xcd\x70\x80\x5f\x95\x3d\x5d\xf7\x6c\x26\x85\xb1\x18\xf4\xdd\x41\x2b\x7d\x1e\x69\xa1\xf8\xc5\x23\x49\x08\x06\xca\xdd\x5b\x91\xb5\xd7\x22\xb9\x3a\x4f\x8b\x6c\x3c\x92\x96\x05\xf6\x76\x44\x12\x7e\x4a\x1d\xc2\x23\xc5\x39\xf2\xb6\x7e\x56\xcb\xe2\x7e\x9c\x4e\x68\x84\xd0\xb4\xf5\xea\x7a\x75\xa8\x1d\xdc\xa9\x39\xbc\xc8\xda\x1c\x7a\xc6\x7d\x1e\x69\x49\xe9\xc0\x3e\xb0\x71\x68\xa6\xfe\xbe\xb4\x89\x02\xab\xec\x15\xb4\x5d\xd4\xbe\x72\x6a\x29\xb3\xe9\x30\x92\xfe\x3f\xac\xbd\x59\x73\xe3\xb8\x92\x3d\xfe\x75\xfa\x61\x1e\x08\xae\xc0\xa3\x6c\xcb\x65\xdd\xf6\xa2\x6b\xc9\x5d\xdd\x33\x31\xa1\x48\x00\x09\x9b\x6d\x8a\xd4\x90\x54\xb9\x7c\x3f\xfd\x3f\x98\x00\xb8\x49\x72\xf5\x2f\xe2\xff\xa4\x08\x11\xdc\x40\x2c\xb9\x9c\x3c\xc7\x8c\x85\xce\x16\x45\x31\x76\xb8\x78\xa0\x75\x9c\xda\xf8\xc9\xdf\xc7\xa6\xbd\x45\xbc\x50\x5e\xcd\x03\x0c\x2c\x33\x2f\x09\xec\x13\x48\x28\xf0\x17\xc1\x94\x13\x8c\xbf\xf3\xa4\xc7\x2a\xc3\xb3\x6f\x6c\x44\xc2\x71\x14\xbe\xb4\x01\xe5\xaf\x04\x81\xe7\xbf\xce\x40\xe2\x2c\x08\x33\x69\x4b\x17\xd7\x75\xbe\x87\xfa\xd3\x83\xc1\xa6\x6b\x08\x0b\x42\x24\x76\x09\x5b\x14\xf7\xdd\xdb\xa0\x9d\x25\xab\xa9\xe2\x79\x0d\xb5\xc2\xe2\xcf\x89\x75\x38\xab\x16\xe7\x2c\x40\xa6\x6d\x34\x94\x10\xa8\xfe\x1a\x8c\x09\xee\x88\x34\x57\xaa\xb2\x7b\xca\xe8\x4b\x33\x16\xc5\x64\xa2\x96\x15\xbc\x8d\x02\x40\x9c\x31\x1d\x63\xe0\x9c\x32\x5b\x98\x75\x05\xad\x7a\xbb\x18\x6f\xe0\x2c\x14\x9c\x00\xb6\x95\xfc\xbb\xa7\xcd\xe3\x2c\x34\x9c\xbc\x95\xdb\x63\x7b\xac\xa9\x36\xe5\xec\x42\xc1\xfe\x99\x06\xe8\xec\xa5\x23\xc6\x95\x63\x2b\xdc\x1d\x4b\x63\x41\x28\xfe\x58\x64\x75\x9f\xda\xce\x96\x2d\xa1\xc5\xa5\xd3\x4b\x9c\x93\xa4\x9c\xfe\xf8\xce\x89\x40\x91\x65\x45\xe2\x0e\x13\x8e\x6b\xce\x22\x6d\x75\xbf\xda\xea\x75\x24\x98\x4d\xa5\x0b\x63\xde\x2d\xce\x62\xae\x03\x8f\x45\x87\x16\x5f\xab\xfa\xf3\x0f\xcb\xee\x3c\x7d\x97\x18\x22\xd2\x3c\xb7\x1b\xdb\x93\x59\xb4\x6f\x05\x5a\x1d\x8e\xb1\xff\xc7\x59\xac\x21\x52\xa3\x21\xea\x2b\x41\xa6\x97\x4b\x92\x2c\xcc\xdc\x26\x3a\xa0\x9b\x88\xea\xc3\xb7\xc8\x2c\x99\xda\xa6\xaa\xfb\xb7\x4a\x04\x9a\xb4\x0f\x67\xae\x54\x35\xb5\xa5\x38\x4b\x94\x8a\x1c\xd4\x45\x55\x3f\xb0\x7e\xc4\x0f\x9b\x34\x3c\xd9\x82\x87\xb5\x9a\x25\x26\x48\xdc\x20\xdc\x12\x74\xf4\xbc\xc2\xe2\x74\xcb\x63\x89\x49\x28\x49\x0e\x5a\x3f\x40\xf9\xb9\xad\xae\x0a\x50\xef\xc4\x79\x3b\xf5\x45\x38\x4b\x05\x5a\xdc\xb9\x4d\xf1\xff\xc8\x35\x5a\x51\x54\xbf\x86\x30\xd2\x9e\xb5\x84\x64\x58\xb6\xf9\x0f\xbc\xad\xea\x3b\xaa\xda\xf5\x2d\x32\xc6\x69\xb5\xb5\x1b\x14\xc9\x9e\xb8\x23\x3c\xb0\xf1\x09\x55\x54\x4d\x5e\xbe\x8e\x92\x5b\x9c\x89\x44\x70\xdd\x77\x58\xf7\x9c\xdd\x5a\xe1\x76\x06\xaa\xd8\x3c\xf3\xb8\x22\xd1\xb4\x16\x7d\xbb\x79\xfa\x82\x81\x83\x33\x91\x59\x2c\x8f\xd5\xfe\x2b\xaa\x1a\xeb\x81\xb5\x8d\x33\xc1\x91\x74\xc1\x9f\xef\xaf\x2d\xb6\xaf\x2f\x5d\xe0\x0c\x02\x63\x6c\x5c\xfa\x47\xf5\x8e\x73\xda\xfe\x39\x96\x65\xda\xf1\x80\x96\x1d\x71\xb9\xbd\x73\xc6\xc4\xf2\xcf\xeb\xbb\xc5\xe3\xb7\xe5\xee\x79\xb1\x5d\x3d\xf9\x7b\x48\x6d\x21\x26\x1f\x48\x51\x6d\x3d\xd0\xf6\x9d\x40\xdf\xdc\x19\x2a\x70\x7b\x73\x67\x14\x76\xbb\x64\x35\xe6\x05\xe3\x4c\x41\x46\xf0\xa6\x8f\x31\xb3\x89\xcf\x63\x8f\xaa\xd3\x39\xd3\x46\xca\xd4\x2d\x4f\xbe\x22\x75\xcc\xea\x3b\xbd\x2f\x32\x9b\x1a\xd3\xd8\xcb\x25\x4d\xe7\x14\x46\x82\x20\x5a\xbf\x02\x79\x70\x66\x20\xa3\xca\xaa\xd7\xfc\x07\x96\x23\x51\x0c\xce\x0c\xf2\x50\xf8\x30\x7f\x9f\x3e\xba\xbc\x60\x86\x81\xb6\x51\xcb\x9e\x77\x0d\x0a\x1c\x5f\x31\x0c\x4c\xec\xe7\xcd\x23\x7e\xf4\xc5\xc8\xf5\xd4\x67\xe6\x61\xd7\x6f\xcc\xf1\xa2\x9f\x06\xd2\x79\x18\x9a\x94\xdc\x3a\x72\xa8\xef\xab\xf9\xb6\x19\x46\x41\x44\xd0\xee\x9d\x9c\x25\x98\x79\x18\xa9\x90\x02\xd0\x6f\xd5\x87\x9d\x84\xa7\x96\x61\x18\x21\xb7\x2b\x17\xf4\xc9\xa8\x13\x32\xbf\xb3\xc9\xb9\x51\x8a\x8e\x87\x91\x91\x64\xc2\x7e\x90\x03\xdd\xed\xbb\x57\x55\xfb\x76\x5b\xd5\x38\x2f\x20\xe4\x61\x1c\x6a\xed\x3a\xe6\xfe\xfe\x0f\xcb\x4d\x10\x26\x93\x4f\x1a\xc6\x71\x40\x36\x2d\x61\xa7\xbf\x57\xf5\xbb\x0f\x7a\x3b\xe7\x92\x87\xb1\x48\xb2\x6c\x54\xfd\x09\xaa\xa5\x58\xd2\xf4\x5e\x49\xa0\x09\x28\xdf\xcd\x86\x7f\x7b\xee\x46\x1e\x26\xa1\x54\x0e\x6c\x8b\xab\xe6\x5b\x35\xac\xf8\x61\xca\xb8\xaf\xfc\xb7\xd1\x61\x17\x02\xf4\xfd\x95\x86\x9a\x5c\x68\x3b\xb7\xee\x9e\x6e\xee\x77\xe2\xa1\x3f\x39\x61\x06\x7b\x02\xee\x13\x22\x59\x1e\x66\x29\xd2\x46\x4f\xa3\x66\xcb\x97\x7f\x6e\xaa\x42\xef\xbe\x2d\x1f\x97\xcf\x3e\x40\xc4\xc3\x8c\xdb\x5c\x3a\xad\xfe\xb9\x7a\x8b\xcf\x9b\x3b\x61\xa6\x63\x42\xf9\x0c\x0e\xc5\xf4\x38\x37\x2a\x12\xbd\x85\xf7\x8c\x87\xaa\x6e\xb1\x3e\xf5\x5c\x79\x28\x58\x40\x91\xfc\x65\xe7\x61\xd4\xb9\x7a\x29\x73\x12\x92\xe8\x8f\x87\x60\x35\x73\xde\x1c\xab\xc2\xad\x67\x8d\x1b\xee\x26\x83\xd4\x43\xd5\x97\x7b\xc8\x8b\xe9\x07\x95\x89\x24\x59\x86\x55\x63\xd1\xa6\x7a\x46\xda\xe3\x9b\x01\x23\x83\xe3\x1b\xd5\x09\x8c\x9c\xa4\x50\x45\x8a\xc2\xff\x37\xcb\xdb\xc5\xcb\xbd\x15\x5c\xbb\x7f\xba\xfe\x7d\x77\xf3\x42\xeb\xda\xe3\xa8\x21\x2d\x9e\x16\x73\xba\x5d\xdc\xbb\x65\x70\x1c\x23\xe7\xa1\xe2\x16\xea\xe3\x65\x06\xb1\x1d\x41\xb2\xff\x9f\x0a\xae\x78\xa8\x23\x2b\x72\x48\x5b\xcb\xf9\x4f\xa5\xd3\x80\x9c\x16\xbc\x3a\xb6\x6d\x6f\x24\x86\x1a\x6d\x34\x98\x60\x64\xd7\x23\xfb\x3b\xc4\xc0\x60\x30\xd0\xb7\x90\x40\x55\xdd\x73\x3f\x5e\xf0\x8c\x2f\x3c\x1f\x9a\x20\x51\x83\xc6\x70\x35\x61\x01\xe6\x11\x0b\x2c\x07\xcf\xa1\x37\xcc\x9f\x51\xe5\x87\x1c\xcb\x96\xf5\x6d\x50\xd3\xc7\xfd\xeb\xe9\xe5\xdf\xab\xc5\xe3\xd5\xea\xab\xad\x2f\x0a\x65\xa2\x3c\xbf\x58\xd9\xb4\x50\xb6\x44\x11\xda\xdb\x14\x51\x88\x71\xec\x40\x90\xeb\x1a\x75\x7e\x36\x5d\x77\xf6\x97\x9f\x44\x05\x26\x03\x28\x8a\x18\x4b\x5c\xe5\x8c\xa5\xf8\x68\x4e\x3a\x6b\x76\x42\x8c\x54\xc8\xd3\x1c\xe5\x4c\x71\x73\xd2\x89\x51\x94\x59\x62\x6c\x8f\x0d\xdb\xd6\x47\xbc\x85\xa2\x9f\x23\x51\x24\x58\xe6\x23\x3c\x56\x5a\x8a\x22\xec\x16\xd9\xd8\xb7\xb1\x6a\xdd\x36\x7d\xf4\x8c\xaf\x23\xe8\xe7\xff\xb0\x74\xe6\x16\x90\x5a\x92\x23\x1f\xdc\xfc\xdf\x14\x46\xce\xa3\x24\xc9\x40\xcd\xca\xdf\x1d\x29\xe6\x6c\xe7\x8e\x12\x19\x27\xae\xe9\x72\x7b\x37\xbb\x4e\x9a\xc4\x14\xd4\x6a\xda\xaa\xfe\x7b\xea\x6b\x47\x29\x47\xb2\xe2\x9e\x0e\x87\xb1\x7f\x11\x65\xa9\x21\x88\xde\x20\x2a\x3c\x44\x84\x7d\x13\xc1\xa8\x22\x33\xdf\x1f\x48\xf1\x3d\x2f\x5f\x77\xc7\x72\xac\xd9\x35\x06\x2f\x4e\x1f\x89\x8b\x00\x8d\xaf\xc2\xf8\x86\x6d\xb7\x64\xfc\xfb\x04\xba\xc5\x23\x11\x46\xcc\xf3\x21\xfd\x13\x80\x0b\x8f\x04\x0a\x82\xfa\x82\x7a\xc7\x7a\x0f\xe5\x79\xce\x06\x1e\x09\xa3\x2c\x2d\xf1\x4f\x1b\x98\x9d\xed\x9a\x11\xc4\x49\x66\x7d\xf1\x3d\xbe\x83\x7f\x67\x48\x91\xf8\x80\xf6\xaf\xfb\xf6\xaa\xd2\x9f\x36\x9c\x3c\xf5\xf8\x23\x50\xd2\x0c\x39\x37\x27\xf8\x3d\x7d\x4a\xc9\x84\x34\x5e\x85\x6a\xac\x82\x7c\x36\xdb\xc2\x23\x19\x31\x70\x81\xd6\x6e\xaf\x6c\xce\xc6\xa2\xf9\xf9\xd5\x21\x92\x89\x11\x6e\xdc\xbe\x94\x43\xa2\x41\xf7\xc4\x98\xbb\xf3\x6b\x5a\x24\x21\x25\x4e\xac\x9e\xbb\x64\xa2\x5b\x7b\xd1\x72\x8a\xa4\xb2\x3c\xbe\x2e\x0e\xba\xad\x0e\x07\xd4\x2f\xe7\x61\x46\x1e\x2e\x29\xdc\xb6\x1f\x29\xd4\x34\xac\x6e\x9f\x5e\x1e\x6f\x68\xdd\xdf\x5d\x2f\xd6\xeb\xe5\xcd\x58\x7d\xb3\x6b\x66\xeb\x9d\x54\xfd\x79\x68\xe1\x58\x4f\x46\xaf\x56\x82\xf0\x80\x9e\x81\xe0\x3b\x5e\xd6\xf0\xe6\x91\xc9\x2c\x7c\xcb\xe2\x97\x7a\x40\x11\x8f\x03\x13\x0a\x87\x0c\xd9\xe6\x58\xb3\x69\x7d\x8d\x6b\xc4\x22\xa6\x1c\xc6\x61\x71\x38\xf4\xdb\x59\xcc\x78\xe0\x79\x6a\x36\xa8\xea\x79\x0c\x33\x0e\x23\xcb\x35\x2b\xf3\x76\xff\xcb\x92\x4d\x1e\x87\x1c\xe8\x95\x72\xca\xd0\xf4\x9a\x48\x67\x87\x4b\x1c\x45\x2c\x46\xbf\x46\xd2\x2e\x3c\x72\x4c\xe2\x48\x88\xd4\x91\x06\x6f\xf3\xbd\xa3\xdb\xfd\x67\x52\x8b\x3c\x8e\xa3\x90\xc2\x08\x16\xb7\xfc\x47\x35\x83\xd1\xf3\x38\x8e\x23\xee\xae\xfe\x0f\xaf\x7c\xe1\x4e\x49\xc0\x28\x5a\xe4\x15\xd2\x4a\x38\x34\x6f\xd5\xbc\x1b\x13\x61\xad\xdb\xa7\x1a\x9f\x6a\x9c\x10\xe9\x5d\x0c\xa0\xc5\x89\xe2\x4a\x8f\x4c\xfb\x59\x49\x2d\x8f\x53\xa1\x48\xfe\xab\xc8\xdb\x16\x4c\x3e\x0d\x2e\xc4\x29\x44\x89\xc5\x0f\xe4\x9e\x39\x66\xc0\x95\xf0\x38\x0b\x24\x81\x65\x77\xf0\x33\xc7\x66\xb0\xf8\xf9\xec\x05\xb3\x50\x51\xed\x03\x15\x45\x5c\x13\x87\x0b\x0c\xdb\xe4\xd8\xfa\x8e\x33\xc8\xc8\xd5\x2c\xf1\xc3\x67\x7e\x26\xb9\x21\x1e\x0b\x16\xf4\xf9\xd8\xa2\xd8\x1e\xeb\xb2\xf3\xff\x7f\xeb\x8f\xca\xc8\x69\x0d\x38\x4f\xc6\x5a\xad\x94\x7f\x3e\x0f\x28\xe5\xb1\x64\xe8\x88\x21\x4a\xac\xa1\x5b\x30\x3e\xdb\xfe\x25\x95\xb4\xc2\x55\x58\x6a\x47\xed\x3c\xee\x02\x65\xd0\x72\x62\xed\x0e\x75\x55\x19\xbf\x34\xc6\x3a\x34\xda\xb1\x7a\xb6\x7f\x7c\xa9\x47\xe3\x4f\x70\x5c\x73\xc4\xeb\xd1\x74\x96\x67\xa3\xea\xea\xe3\xc4\x92\x98\x0e\x0a\x64\x09\xc1\xac\xba\x7f\x6f\xbf\xdf\xf8\xbb\x63\x6c\x37\x70\xbb\xe2\x7f\xbb\xda\x9e\x75\x83\x63\x4c\x13\xb2\xce\x7f\x40\x29\xf1\xe7\x16\x61\xdf\x3d\x6a\x5e\xbe\xda\xf1\xec\xaf\x66\x02\x4e\x49\x88\x83\x05\x3f\xfd\x0b\xd4\xfb\xa1\x6a\xe7\x54\x36\xb3\xf7\x31\x32\x4a\x6d\x41\xfa\xa1\xa8\xa6\xd0\xfb\xd3\xb6\x3a\x26\x2e\x98\x57\x68\x96\x87\x4a\x39\xf8\x01\x4f\x02\x65\xb3\x96\x1a\xe5\xf1\x75\x87\x54\xed\xd4\x0d\x7c\x09\x0d\x6e\x7f\x3e\x1d\xdb\xc3\x29\xf1\x9e\x3f\x55\xc7\x14\xf4\xfd\xfd\xf1\xe9\xfb\x78\xc5\x4c\x58\x20\x74\x2f\x19\xd7\x42\x31\x48\x63\xf1\x84\x45\x19\xc5\xd9\x4e\x60\x7a\xb7\x75\xb5\xbf\x81\xc3\xe1\xe4\x9d\x07\x43\x30\x61\x26\xcc\xac\x26\x2c\x91\xa2\xe7\xfa\x9c\x8e\x1c\x4f\x42\x99\x59\x6e\x6b\xca\x0d\xff\xd6\xff\xab\xc9\x2b\xf9\x98\xc8\x29\xf1\x13\xf2\x10\x9e\x84\x0a\x7a\xd6\xed\xcf\x03\x76\x4f\xb6\xd4\xf9\x30\x9b\x98\xbf\x51\x04\x81\x2d\x1b\x7c\xfe\x73\xd2\x01\x91\x11\x54\x68\xee\xe3\x94\x84\x70\xe9\x46\x35\xc2\x7e\x6a\x33\x25\xb1\x93\x6e\xb4\x41\x25\x32\xda\x3d\x0d\xf3\xd9\x41\x9c\xc4\x12\x32\x3d\x36\x1c\xf5\x79\x5e\xf8\xfe\x06\x52\xf9\xc4\x17\x3d\xe3\x35\x4c\x33\xf7\x3c\x49\x53\x81\xc2\x43\x56\x3b\x1b\xf3\x11\x7f\x5a\x9a\xa8\xd5\x89\x29\xe1\x4e\xc9\x04\x8b\x86\xa7\xb6\x1d\x19\xf8\x63\x52\xa5\x96\x7c\x38\x7f\x7d\xc5\x7a\xd3\x92\xe6\x42\x79\x84\xa2\xf8\x8c\xce\x7f\xb0\x6e\x93\xf5\xf4\xa7\x5d\x57\x4d\xaa\x37\x79\xc2\x93\x20\xb3\xd5\x93\x37\xfd\x5f\x2a\x4b\xfb\xca\x5b\xc7\xce\x32\xbd\x26\xc4\x29\xb9\xb3\xcf\x54\xe3\xad\x61\xef\x4f\x05\x61\x31\x01\x07\xea\x36\x53\xd5\xda\x15\xd7\x5f\xe8\x70\x99\x68\xaa\xc8\x25\x41\x33\xab\x59\x31\x14\x33\xce\x92\xbe\x3c\x91\x26\xa6\x1d\xfc\xba\x33\x25\xaa\xeb\xea\xf0\x39\x19\x19\x2a\x0c\x49\xaa\x17\xb4\x7e\xaa\xf3\xd7\xbc\x9c\xae\xbc\x89\x4a\x98\xcf\x19\x3f\x7b\x6e\x14\x5b\x00\x7c\x5b\xd5\x63\x19\xfa\xfe\x82\x99\x89\xdc\xea\x74\x41\x3d\xfa\xff\x6d\xa7\x4c\x74\x16\xf8\x78\x4b\xf7\x9e\x53\x81\x22\x9e\x68\x48\x08\x2d\xa1\x30\x2f\xce\x45\x88\x12\x6d\x14\x4d\xbe\xc5\x3e\x7f\xad\x06\x54\x21\x4f\x90\xc5\xc1\xc0\x74\x77\x8b\x67\x49\x95\x79\x82\x3c\x61\xe9\x40\x0c\x15\x6e\x8e\xfd\x97\x33\x61\x14\xbb\x2c\xd3\x63\xd5\x7a\x90\x80\x27\xde\x6e\xfa\x66\x29\x24\x04\x5f\xbc\xb9\x79\xde\x5d\x3d\xbd\x3c\x6e\xff\xf2\x68\xb1\xc5\xf5\xf5\x50\x14\xc7\x13\xa3\x04\x0d\x2c\xd2\xe1\x1d\xb8\xab\x79\x62\xd0\x02\x5f\xe5\x10\xec\x3e\x35\x4d\xd3\x80\x85\x32\xf0\x28\x0b\x2a\xb7\x52\x58\x3c\xf7\x60\x66\x9e\x86\x22\xb6\x8a\x22\xc7\xcf\xab\xcf\x6d\xb5\xaf\xce\x0f\xb1\x34\x4a\x43\x8a\xae\x52\xc5\x91\x8f\xab\x79\xa4\xd0\x6f\x7d\xa3\xc4\x53\xac\x53\xf4\xd5\x95\x35\xb8\x9f\xea\x3c\x6d\x3b\x4f\x23\xa5\x69\xfe\x93\x9e\x5c\xf7\x45\x7b\x19\x82\x33\x36\xf7\xd8\x4e\x48\x23\x23\xa8\x62\xb3\x2f\x5d\xd9\xb4\xd5\x61\x14\x64\x49\xe3\xc0\xe2\xbf\xf3\x66\x47\x66\xc7\xce\x16\x0e\x4f\x07\x44\x1a\x07\x09\x21\x36\x0c\xb6\xea\xcd\x2d\x59\x56\x32\xf1\xb6\xaa\x1f\x48\xc1\xbd\xb7\x86\xd2\x58\x6b\x57\xfe\xee\xc2\x9b\x4f\xc6\xe5\x1a\x67\x57\x4d\x32\x70\xa0\xe5\xf2\x7d\xba\xa4\xa6\x89\x56\x21\x0e\x12\x94\xd6\x27\xb2\x8b\xe4\x6c\xb0\xa5\xa9\x04\xb2\x08\xee\xa0\xae\x3f\x47\x83\x35\xcd\x82\x0c\xec\x16\x50\x6e\x2b\xaa\x6c\xef\x16\x99\x0b\xc6\x4d\x9a\x25\x91\xd5\xc0\x71\xec\x7b\xcf\xbb\x21\x39\x7f\xbd\x58\xf7\x17\x4d\x78\x8a\x3e\xd0\xf1\xe3\x6c\x69\x0c\x4f\x33\x6e\x5d\x80\xe6\xd8\x1c\x70\xee\xeb\xa5\x99\x54\x62\xc4\x4b\xfa\x0d\xfa\xc2\x12\x9e\xf2\x40\x51\x12\x9d\x32\xa2\x2f\x84\x43\x5e\xf4\x1d\xcb\x33\xb4\x4a\x68\x54\xaf\x48\x01\xa4\x11\xf3\x21\x4f\x39\x6a\xe2\xea\xb5\x84\x27\x3e\x3f\x7b\xe1\x7d\x81\x0b\x61\x09\x45\x0a\x84\xfa\xaa\xce\xf5\x2b\x3e\x02\xa5\x5a\x70\x66\xc2\xa7\x32\xe1\x44\x75\x4f\x80\xcb\x6b\x28\x7f\x50\x5d\x4b\x1f\x7f\x9c\x1b\x2a\xa9\x62\x40\x84\x71\x8e\x42\xea\x5f\x55\x5e\x3a\x57\xf1\x8c\x4f\x9f\xaa\x30\x26\x05\xd6\xda\xaa\x7d\x74\x66\xe3\x4c\x8e\x9f\xa7\x3a\x44\x5f\x47\x39\xce\x46\xcd\x5b\xe9\xc8\x24\xfd\x96\xe6\xd6\xa6\x6e\xeb\x1f\xe4\x17\xe7\x27\xd8\x3a\xe5\x63\x49\x40\xa2\x19\xb7\x28\x4f\x11\xa4\x17\x09\xdd\x94\x90\x17\x33\x11\x4a\x9e\xa2\x8a\xc9\x4c\x22\x30\xce\x4e\x4d\xb3\x6f\x59\x90\x99\x48\x7b\x0d\x78\xe8\x8e\xb8\x6a\x1e\xef\xe4\xba\x0e\xcb\x58\xa4\x03\xca\xed\x1d\xfb\x64\xdb\x99\xbc\x48\xc6\x12\x4e\x76\x03\x15\x1c\x2c\xfe\x7a\x7a\xd9\xee\x6e\x9f\x17\xd7\xbb\xab\x27\xbf\x1c\x66\x4c\x32\xe9\x0d\x01\x68\x91\xa5\x69\xda\x1f\x32\x16\xd2\x41\x12\x2d\x9b\xff\x3b\xe6\x75\xed\x79\x75\x78\x16\x06\x3c\x1e\x94\x6c\x6d\xe4\xd8\x07\x56\x9c\x89\x65\x1f\xdc\xaf\x9c\x59\x08\x9c\x88\x4c\xdf\xdf\x7d\x76\x2d\x8b\x02\x46\x79\xbd\xeb\xa7\x87\x87\x97\xc7\xd5\xf6\xaf\x9d\x43\xfa\x2e\xbe\x79\x3f\x3d\x8b\x99\x3d\xed\xff\x4e\x4a\x4d\xfb\xde\x48\x22\x4d\x8c\x8c\x7e\x77\xb8\x3d\x96\xba\x39\xad\x87\xe7\x59\xca\x10\x12\x47\x67\xeb\xe9\x75\xfc\x7d\x52\x37\x62\x6a\x7d\x53\x4d\x94\xa4\x78\x96\xc6\x92\x28\x3f\xea\x72\x9c\x1b\xcc\x32\xb0\x51\xd1\xcd\x76\xf1\x3c\x69\x9f\xa9\xcc\xd2\x6a\x76\x0b\xa4\xe5\xc1\xec\x85\x3f\x5d\x13\xae\x23\xf0\xb9\x89\xe2\x88\x91\xff\x5f\x64\x99\x1e\x29\x80\xf4\x00\x50\x3e\x75\x07\x62\xd7\x1c\x74\x44\xe4\x08\x47\x6b\x06\x8c\x18\x80\xe8\x18\x5a\xe9\x36\xbd\xc6\x91\x6f\x95\xc9\x20\x0c\xac\x10\x05\x61\xb0\x1d\x93\x40\x7f\x34\x53\x8a\xf5\x0c\x78\xaf\x78\x8a\x30\xe6\x99\xe4\x9c\xc8\x99\x9a\x28\x71\xd6\x71\x7f\x40\x24\x9e\xcd\xe1\xe9\xea\x79\xb4\x10\x66\x52\x5b\x0d\xea\xee\xd0\xe2\xfe\xfe\xe9\x9a\x42\x33\x9b\xdd\x78\x73\xce\x94\xb2\x94\xe4\xde\x8b\x58\xb6\x6f\xd3\x85\x3e\xd3\x9a\xeb\xee\xd6\x77\x2b\xf5\x2b\x89\x03\x9e\x21\x4f\x3c\x45\x6d\xd7\x01\xd5\xd1\x31\xb7\x4f\xec\xaf\x0c\x85\x91\x6a\x60\x36\x5f\xe9\xeb\xb2\x9d\x85\x52\x33\xd4\x20\x42\xbf\x8c\x5b\x36\x2a\xaa\x53\x99\xb5\x32\xd2\x17\xa4\x3f\xe4\x3f\x6f\xab\x7a\x7f\x2c\xe0\xac\xc9\x93\x19\x17\xe3\x5b\x2f\xd7\xcb\xc6\x7b\x4a\x3c\x08\x0d\x73\xf2\x86\xa7\xc8\x5f\xdf\x26\x89\x83\xac\xa7\x0b\xb4\x9d\xf0\x8b\x74\x9c\x3f\x13\x25\x4d\x25\xfa\xec\xba\x7a\xb5\xfb\xe3\x03\xd4\xef\x47\x8f\xf9\xe1\x8c\x19\x0a\x9a\xdc\xf6\x7f\xa4\x56\xc8\x7b\x67\x6d\xb8\xb3\x6f\xc3\x43\x2e\x69\x1b\xa2\x11\xef\xf2\xc4\xb8\x28\xb5\x07\x26\xf8\x8f\x38\x68\x6e\xce\xcc\x0f\xfa\xef\xa2\x71\x32\xac\x22\x3c\x04\x49\x73\xeb\xea\x58\x97\xdf\xc0\x8f\x5a\x1e\x31\xe6\x45\x1a\xae\xab\xfd\x01\xca\xcf\x33\x15\x78\x9c\x47\x71\x44\x31\x33\x2a\x2f\xbb\xc8\xc9\xf6\xa5\xb1\xcc\xa3\xd4\x92\x6a\xd0\xf4\xa1\x78\xcb\xee\x87\x75\xef\xe7\xeb\x39\x8f\x15\xa3\xed\x60\x67\xf2\x32\x6f\xde\x7a\x69\x38\xde\x79\xa6\xb4\x35\x43\x51\x78\x66\x8d\x39\x93\x20\xef\xdc\x10\xda\x72\xf1\xa7\x45\x9d\xd2\x66\xf2\x3b\x5a\x58\xed\xb8\xa2\x80\xf3\x94\xe9\xd0\xaa\xb6\xd6\xef\x38\x9b\xae\x3c\x95\x71\x46\x40\xa3\xe5\xf3\xb5\xb7\x8a\xb7\x4f\xbb\xe7\xe5\xfd\x72\xb1\x59\xf6\x97\xd0\x59\x6a\x7c\x17\x16\x55\xbd\xc5\x7e\xb9\xe2\x19\x8b\x25\xfa\x94\x27\xfe\xc8\xab\x63\xe3\x34\x74\x7d\x83\x88\x51\x54\xef\x79\xb1\x5d\xee\x96\xdb\xbb\xdd\xf7\x3f\xbf\xf7\xc7\x1c\x1d\xde\xbf\xff\xda\xda\x7e\x1a\x2f\x96\xdd\x88\x53\xd2\xcb\x97\x2d\xac\x03\x30\x6d\x20\xdc\x62\xe3\xeb\x61\x6c\xb5\xd3\x97\xe0\x12\xce\x55\x16\x30\xcf\x10\x89\x40\xfd\x4b\x8b\xe3\xd9\xa8\x0a\xe7\x46\xe8\x60\x2c\xc1\x7a\x85\xfd\x47\x14\x69\x90\x8e\x2b\x5e\x77\xd5\xd8\x53\xf7\x8d\x90\x87\x96\x46\x0a\xf6\xd1\x34\x9c\xcf\x21\x4d\x88\x08\x61\xd7\xf5\xde\x91\x32\x20\x6e\xa3\x1c\xef\x62\x1c\x20\x25\x23\xe8\x8f\xbc\x3e\x36\x84\x82\x76\x07\x64\x06\x54\xdf\xf2\x56\xed\x49\x1d\x16\xeb\xed\xcf\xfe\x98\x32\x32\xf1\xf4\x85\x2d\xbe\x5a\x2e\xf4\xe1\x54\xcd\x8d\xaf\x2f\x7b\x9e\x90\x09\x4d\xdf\x5f\xc5\xb6\x14\xf7\xfb\xf3\x76\x56\x0e\x31\xeb\x28\x95\xa2\x0e\x7d\x50\x1a\xf5\x09\x83\x05\xe7\x4a\x2b\x52\xfa\x36\x39\x99\x9a\x93\xa5\x96\x6b\x05\x04\x32\x6d\x2a\xd3\x5e\xc3\xc1\x55\x69\x7d\xab\xa0\x58\x95\xe3\xe4\x26\xd7\xda\xb2\x8e\xfb\x8d\xe0\x2a\xd7\x3d\x21\x4f\x77\x14\x95\x43\xbf\x60\xdd\xe0\x4c\x1b\x61\xf6\xc8\x06\xb2\xc8\x4b\x0c\x14\xb9\x1e\x47\x9c\xa7\x83\x46\x04\x68\x43\x3b\xf2\x58\x97\x8f\xb7\xdb\xe9\x8b\x09\x16\x06\x54\x33\xf3\x5a\x6d\xab\x47\xfc\xd9\x5a\xb0\x9d\x3f\x98\x32\xc2\xe1\x59\x74\x97\x13\xfb\x19\x53\xc0\x9c\x0f\x34\x0a\xc6\x43\xaa\x6d\xb7\x66\xd4\xd5\xd5\xd3\x3c\x3a\x3b\xf6\xce\x04\x13\x92\x32\xdc\x12\x9b\x76\xf7\x0a\x03\xcc\x56\x30\x0d\xf4\x01\x2d\x33\xe7\x34\x96\x22\x42\x11\x64\x61\x5f\x35\xb3\x68\xac\x3c\x62\x4f\xc5\x33\x7d\xcd\x88\xc5\xf4\x26\x9b\x3d\xd4\xed\x7d\x5e\xbe\xff\x72\x9b\x15\x91\x4a\xc8\x27\x26\x51\xaf\xf1\xb8\x71\x6c\xf4\x5c\xc4\x19\xd3\x6e\x98\x3e\x95\x93\xb2\xe6\xce\xda\x1e\xc9\x19\x72\x11\x2b\x24\x6e\xdd\xc3\x51\x16\x79\xf3\xd6\x59\xcf\x4e\xe9\xd8\x35\x48\x43\x49\xc5\x53\x37\x1b\x36\x5e\x27\x44\xca\x79\xe6\xa4\x28\x8e\x16\x42\xe0\x63\xca\xd3\x17\xcc\x52\x4e\x9c\x2f\x96\xc6\xe5\xb6\xaa\xff\x35\x8e\xf9\x9f\x1d\xf6\x22\xcb\x52\x82\x81\xd1\x22\x45\xee\x49\xe7\x4c\xcc\xda\x08\x21\xdd\x16\xf4\x52\xe6\xa7\xda\x28\x5c\xf0\x98\x91\xe1\x45\x59\x03\x1b\x50\x9a\xbc\x01\x4f\x94\x8b\x0b\xb6\xc7\xba\x6c\xb6\x1f\xd5\x4b\x59\xc2\x1e\x2f\x44\xe4\x84\x60\x21\x85\xd0\xae\xef\xff\x1c\x00\x1e\x67\xd7\x43\x21\x32\x5b\xc4\xd9\xfe\xf2\x63\x0a\xe0\x54\xcd\x4c\x5b\xf9\xa2\x28\x7c\x45\x87\x5d\x37\xae\x3e\x9f\x4e\x57\x3f\x01\x60\x35\xe2\xbb\xd5\xcf\x6f\xf9\x63\x6a\x5f\x2e\x00\x6d\x88\xcc\x2d\x8d\x17\xfc\x2b\x21\x23\x20\xc8\xdb\xa2\xce\xfb\xbd\x4d\xc8\x38\xa1\x1c\x77\x73\x94\xd6\x91\xbb\x50\xba\xeb\x9b\x27\xd2\xa5\x7c\x29\x92\x4b\x0a\x5d\xc7\x13\xbd\x3c\x2e\x94\x74\xc9\x49\x6c\xda\x21\xad\xe1\x6f\xaa\xb4\xf0\x74\xe4\xdf\xdf\x70\xa6\x6c\xc0\x85\x32\x8c\xb2\x87\xeb\xe7\xe5\xe6\xe9\xfe\xc6\xed\xaa\xfe\x64\x8d\x29\x1b\x93\x8e\xde\x60\x0b\xb9\xdf\x4c\x05\x06\x86\x90\x88\x9b\xce\xcd\xd9\xb1\x1d\xf9\x0f\xfd\x41\x88\x68\x8c\x38\x50\xf6\x63\xd5\xfe\x37\xd6\xd5\x6c\x20\x19\xcd\x69\x49\x3b\x8c\x40\x65\xdb\x1c\x6b\xef\x46\x40\x10\xa4\xe0\x08\x88\x2e\xc8\xcf\xfb\x86\x59\x40\x51\x8c\x82\xea\x30\x86\x05\x0d\x98\xb2\xbc\xd2\x0d\xb6\x7f\xe4\x0a\xbb\x3b\x75\xee\x52\x8b\x37\xf8\x80\x0d\xfc\x12\x89\x31\x59\xf7\x21\x0c\x80\x32\x11\x7e\x0f\xfd\x73\xbd\xa0\x64\xcc\xa2\x9c\x15\xd8\xce\x71\xcf\x10\xc6\xb6\x2c\xa1\xc1\x76\x27\xa1\x41\x47\x7d\x0b\xcd\xae\x41\x1c\xb6\x04\x88\xb4\xc5\x5c\xee\x6a\xd4\x88\x53\xf1\x43\x0e\x71\x88\xc2\x05\xd0\x5d\xc4\xf4\x44\x51\x8c\x43\x9c\x04\x84\x7d\xed\x06\xc4\xb6\xfe\x5c\xd7\xd5\xcf\x4f\x02\x34\xfb\xe3\x82\x67\x8e\x6d\x60\xec\x68\x41\x12\xea\xc8\xd2\x5b\xfc\xbc\xcb\xbb\xa9\xf2\xf9\x8c\xaa\xaa\xf5\xea\xa6\x6f\x21\xd1\x4b\xa5\x2e\x1d\x5c\xa0\x73\xb6\x17\x67\x16\x09\x48\x94\xf5\x59\x5c\x87\xec\xda\xca\xbe\x72\xb3\x3b\xd4\xf8\x63\xf7\x81\xf8\x3e\x25\xc1\xe3\x90\x60\x6a\x02\xfb\x60\xc7\x02\xea\x41\xde\x97\x43\x16\x33\xca\xa3\xd1\x6a\xaa\x1c\xd5\x44\xd3\x1f\x4d\x83\xd8\x4d\x95\x45\xe3\x2a\xab\x4f\xdd\x66\xc8\x52\x5b\xcd\x43\xec\x2f\x2e\x30\xe3\x8d\xfc\x8b\x1f\x2e\x33\x61\xa2\x47\x9f\xfc\x5f\xd5\x3b\xd6\xe7\x59\x08\x39\xf0\xc4\x4a\xe0\x6c\x9e\x6e\xb7\xd7\x8b\xf5\xee\x7e\xf5\xd0\x97\xb7\x00\x47\x24\xbe\xa8\x7d\x5e\xe6\xfb\xe3\x7e\x0b\xef\x58\xaf\xeb\xaa\xad\x54\x35\x4a\xb6\x83\x08\xd1\x41\x62\x5d\x8c\xd4\xc6\x74\x46\xf5\xd7\x93\xf9\x0f\xc0\x80\x4c\xb6\x55\x71\xdc\xff\x39\xc9\xe5\x00\xc4\x9c\xb0\xe5\x6f\x58\x57\xdd\x1a\xb2\xad\xee\xb0\xae\xba\xe5\xb5\xf9\x6d\x6c\xb3\x01\x24\x96\x81\x6c\x46\xc0\x32\xda\xb3\x3b\xab\x8e\xcc\x06\x2c\xf5\xae\x86\x61\xd4\xc8\xd8\x64\x43\x68\xdc\xad\x96\xfd\xec\x19\x3a\x5f\x66\x11\xe5\x1c\x0f\x2e\x8d\xed\x46\x83\x8d\x70\x36\x8b\x1f\x90\x17\x20\xe7\xc0\x3e\x90\x1a\x12\xe6\x18\x24\xdb\x97\xba\x68\x7e\x9b\xd2\x34\x70\x50\x32\x20\x8b\xc1\x41\xbe\x6e\xd1\xbf\x9b\x93\xe8\xed\x5a\x58\x85\x63\x4b\x5c\xd5\x7e\x3e\x40\x09\xaf\x23\xa9\xd0\xb3\x9b\x12\x20\x47\xb0\x34\xef\xe3\x79\x78\x86\x7c\x86\x03\x42\x16\x4d\xf0\x50\xfa\x66\xb4\x02\x99\x4c\xd0\x8c\xee\xbc\xdc\xab\xed\xf5\x79\x83\x14\x8c\x88\x6d\x89\x80\xd6\x14\xe0\x9e\xac\x3b\x32\xc8\x02\x1c\x8b\xc7\x8d\xc4\x23\xb9\x0c\x30\x13\x96\x55\xe0\xc7\xd8\x39\x1d\xe7\x52\x07\x96\xad\x13\x59\x75\x2e\x99\x0c\xa8\x8f\xd1\x05\xed\x89\x80\xe2\xfc\x63\xca\x90\x59\x80\x1d\x96\x9a\x82\x86\x66\x48\xe7\xc8\x30\x4a\x69\x71\x24\x64\xba\xce\xa1\x9c\x59\x3c\x32\x44\x2b\x2d\xb7\xcf\xcb\x11\x9b\x1c\x97\x51\x8c\x23\xb9\xd8\x7b\x28\xf5\x44\x6a\xf8\x5c\xae\x4a\x46\x26\x02\xec\xab\x76\x46\x14\xee\xee\xab\xcb\x38\x96\x5e\x8c\xba\xc7\xf7\x9c\x0f\x5b\xcb\x18\x53\xca\x23\x97\x4e\xdf\x68\x8d\x75\xaf\xf4\xc4\x65\x12\x85\x64\xac\xee\x3a\x73\xfa\x1a\x6a\x59\x95\x37\x55\x51\xc0\x29\xfd\xd9\xb4\xab\x12\x91\xd1\xf6\x68\xa5\xb0\xdb\x0b\xa5\x76\x32\x01\x2b\x00\x6d\x50\xbd\xad\x6b\x5c\x90\xd6\xd4\xc0\x7e\xe7\x5b\x69\xcb\x7c\xd6\x60\xbb\x5e\x9d\x11\x39\xe3\x32\x41\x41\xc4\x17\x50\xb7\x63\xa5\x5d\x77\x34\x0d\x82\xa8\x57\xe6\x99\x89\xd9\x4c\x9f\x27\x55\x29\xa1\xea\xf7\xf0\x73\xf1\x5a\x95\x63\xfc\xa4\xcc\x24\x6a\x1c\xd9\x03\xb3\xaa\x0b\x99\xa1\x65\x42\xb1\x80\xaf\x85\x31\x79\x91\x8f\x5e\x82\x4b\x46\xa4\x6e\x3e\x42\xbf\x69\xab\x1a\xa7\x71\x31\xc9\xd1\x2e\x33\xf2\xf8\xb9\x6b\xdf\xfc\x2a\xe1\x8f\x8a\x38\xe4\xbe\x56\x09\x57\xd7\x4f\x9e\x8c\xa3\xa8\x7a\x5e\x32\x2e\x21\xcd\xac\x14\xbc\x57\x6f\x3d\xe7\x2a\x4a\x30\x11\xb1\x41\x5b\x1c\x85\xa5\xf0\x3e\x6b\x5b\x48\x99\x1a\x62\xe7\xf9\x40\xf9\x2d\x37\xd6\x8f\x9b\x60\x9d\xa5\x4a\x6c\x0e\x98\x28\x02\xbb\x6e\x77\x9c\xb8\x77\x27\x6e\xa5\x54\x09\x5a\xb4\x13\xbe\xe6\x25\xf9\x70\xfe\x00\x07\xaa\x65\x03\xbb\x2f\x6d\x0e\x38\xba\xbe\x16\xc4\x4f\xe9\xc8\x76\x76\xeb\xbb\x21\xde\x21\xb5\xb4\x8a\x8b\x07\xeb\xac\x39\x2d\xe6\x95\x7e\xee\xd6\x63\xdf\x08\xd3\xcc\x93\x50\xee\x6c\x01\x57\xd7\x3b\xbb\x66\xae\x58\xca\xa5\x09\x63\x0a\x4c\x81\x5f\x91\x6f\xab\xbe\x2e\x07\x8a\xc5\xfc\x7d\x4c\x1c\x64\xc2\xd1\xec\x6c\xc6\xa5\x6e\xb3\x61\x65\x32\x11\x3b\xc6\x03\x47\x25\x39\x3b\xae\xad\x1e\xed\x00\xcb\x5b\x95\xcd\xb1\x1e\x0d\x0d\x15\x24\x9a\x6c\xff\xe6\xad\xaa\xdb\x5e\x6b\xf5\x02\xd8\x4f\x05\x5c\x10\x0d\xf7\x7f\x2f\x9e\x77\x4f\xfb\x32\xd7\x76\xce\xfa\xa3\xd2\xe2\x2e\x77\x07\xa8\xdb\x1c\x0a\x02\x64\x4c\x3e\xbb\x62\xcc\x50\x08\x7b\x83\xed\x6a\xfd\x7c\x9e\xe5\xef\x0c\xb4\xea\x14\x70\x35\x9e\xa6\x2a\x8c\x20\xb6\xa9\x1a\xcb\x81\x37\x06\xcd\xaa\x28\x94\x98\xf6\x21\x51\x8b\xb2\xb1\x21\x3e\xdf\x40\xa7\x9e\xa8\x74\x5d\xc0\xe7\x88\xc7\xd6\x35\x88\xa5\x2d\x44\xdf\xc3\xcf\x35\x7c\x36\xeb\xe1\xda\x31\x86\xc4\x69\x55\x63\x5b\xe7\xf8\xe3\xb4\xc6\x66\xda\x7d\x89\xb2\xb2\xbf\x23\x5e\xcd\xf1\x54\x57\xa9\x40\x12\x71\x78\x83\x86\x28\x09\xce\xcf\x1d\x95\x2a\x4d\xf0\x59\xab\x5e\x3c\xa9\x97\x54\xa9\xe6\x38\x30\x59\x62\xdd\xdc\xe4\xcd\x01\xcb\xa6\xf3\x26\x7d\x9b\x2c\x8e\xa8\x47\xbe\x63\x61\xc0\x61\x18\x06\x96\x31\xae\x32\x1e\x52\xf9\x58\x75\xc0\xf2\xaa\x72\x04\x42\xe7\x87\xa0\xea\x76\xaf\xcc\xd2\x2d\xd6\xd5\x0f\x5c\xd7\x15\x15\x00\x9e\x7f\x7f\x8e\x3d\x57\x32\xad\x65\xc7\xb6\xea\x85\x0c\xfc\xcd\xb9\x89\xa8\xee\x1e\x6c\xa5\x80\xb7\x2b\xdc\x51\xa1\x80\x40\x93\x9e\xa8\xf2\x3b\xe6\xfd\x21\xc3\x48\x83\xd4\x63\x6e\x3b\xf7\x01\x7a\xab\xe9\x7f\x58\x30\xc4\x90\x47\x8c\x95\xf1\x10\x45\x8e\x9d\x93\xa8\x20\x0a\xd2\x70\x42\x18\x37\xb8\x80\xb6\xb7\x17\xa6\xc5\x7a\x61\x99\xda\x86\x0d\x41\x41\x02\x04\x75\x18\x84\x64\xa7\x1c\x83\xe7\xbb\x10\x64\xa0\xfb\xc2\xdc\xab\xea\xf8\xfa\xf6\xab\x33\x24\x0a\xc2\x6e\x1f\x1b\xfc\xbd\xac\x3e\x0a\xd4\xaf\x33\x1f\x54\xa9\x98\x45\xd0\xd7\xa1\x54\xe6\x6b\xc3\xac\x6b\x6e\x9d\x74\x1f\x2a\x18\xa1\x16\x94\x32\x86\x52\x03\xd4\xe9\xb6\xc4\xad\x1d\x66\x3d\x86\xcc\xd3\x52\x0f\x62\xf8\xd3\xab\x63\xa2\xc8\x82\xf7\x7b\xd4\x43\x5e\x62\x3d\x58\xe7\x0a\x39\x8f\x13\x4f\x6a\x4c\x5b\xc1\xd4\xe4\x75\xcd\x0c\x97\x14\x84\x5e\x3e\x5f\x87\x61\x34\x36\xca\x95\x31\x8a\xc2\xa0\x7f\xdd\x7a\xcf\x40\x07\x81\xf5\x95\x4c\x5e\x37\xed\x76\x0b\x3f\x27\xdb\x8b\x0e\x38\x8b\x5d\xb0\xd2\xc1\x68\xee\xf2\xd7\xb7\x46\x55\x35\xbe\x34\xfd\x80\xd3\x81\x0e\xc3\x31\x4b\xb5\x5b\xe8\xfd\x61\xc6\xb3\x38\x19\x74\xef\xc6\xd4\x26\xae\x45\x08\xc2\xe5\xd9\xdf\xaf\xc6\x59\xa1\xe9\x07\xd0\x11\x58\x25\xe7\xee\x7b\x55\xb3\xfd\x40\x47\x18\xa1\xb3\xf1\x76\xaf\x15\x14\xb3\x87\x88\xc3\x88\x3e\x1e\x96\x7a\xa5\x2a\xd6\xff\x1d\x27\x64\x01\xee\xc0\xe4\x73\xdc\x80\x8e\x95\x15\x68\xfe\xc8\x4b\x5d\x7d\x84\xd6\xf2\xe8\xec\x6c\xaa\x5d\xf7\x19\x1f\x9d\x20\xa3\xe9\xed\xf9\x86\xd6\x55\xd3\xe4\xb2\xc0\xeb\xb7\x6a\x10\x17\xe7\x3a\x55\x48\xb9\x69\x22\xe9\xda\x7c\xa5\x0b\xf2\xff\x94\x4e\xd1\x59\x1a\x13\xee\x54\x43\x0b\xb7\x55\xbd\xc1\x4b\x36\xb4\xe6\xb1\xa2\x00\xb9\xc6\x62\x51\xb4\x24\x87\x37\x9b\x12\x9a\x67\x82\xac\x04\xc7\xd7\x70\xca\x6c\xce\x35\x37\x8c\xfc\x9e\xc5\xd5\xd3\x9f\xfe\x3f\x11\x24\x3d\x23\x6b\xd3\x60\xbb\xd2\xdb\x3a\x3f\x10\xf9\x23\x7a\xce\xb7\xe9\xb3\x88\x40\x12\x0c\xf3\xda\x03\x9b\xc6\x36\xb4\x16\x91\xd5\x57\x2a\x8f\x7b\xc2\xd4\xf5\x9d\x28\x52\x01\x89\x77\xcb\xc6\xce\x48\x77\x04\xbd\xde\x4d\x0e\xc5\xe2\xf9\x4f\x3b\x4f\xc7\x51\x34\x2d\xb4\xd2\x43\x94\x79\x59\xab\x30\xf8\x65\x45\xa3\x86\x54\x92\x43\xe6\x60\xca\xfe\xad\x66\x3d\x07\x59\x4c\x75\x1c\x76\x2a\xe5\x7b\xbc\xcf\xcb\xbe\xcf\x20\x4b\x0c\xcc\x24\xd5\x09\x4a\x52\xcf\xaf\xc2\x93\xc0\x95\xa3\x2c\x8a\xa2\x67\x41\x9d\x3e\x90\x4c\xe2\xac\xaf\x9f\x23\x3b\xf4\x71\xc8\x76\x68\x29\x02\x88\x49\x34\x44\xbf\xe2\x08\x9e\xa3\x55\x64\x0d\xfe\x5e\x8b\xd6\x5a\x57\x5e\xb1\x80\x6b\x65\xb4\x2f\x77\xd9\xe4\xaf\x2e\x0a\x3e\xbb\x37\xb2\x84\xb6\xdf\x07\xf8\x9b\xa6\xf0\x08\xd6\xae\x31\xb6\x00\xb0\xc6\x96\x27\x1e\x0f\xce\x90\x38\x23\x5b\xca\x35\x66\x9c\x32\x46\xdf\xa1\xd4\x16\x47\xd6\x8e\xb4\x15\x2f\xe3\xf0\x35\x22\xa3\x0c\x8a\x8f\x8b\xd0\x18\x7d\x3a\x5e\xd8\x4f\xb5\x61\x22\xd4\x03\xd8\x65\x23\xc7\xba\xbf\x5c\x9b\x28\xa3\x64\xf0\x1d\x7c\xbc\x5f\x56\x18\xe5\xda\x64\x19\xe1\xe3\xb6\x35\xfc\xc0\xa2\xc8\xcb\xd7\xdb\x1a\xf1\x9f\xc9\x3d\x71\x0c\xb2\x30\x76\xf2\x7d\x83\x78\x33\xc7\x80\x33\xe2\xae\x22\xe7\x68\x31\x25\xd3\xfb\x72\x77\xc3\x40\x26\x81\x57\x2f\x22\x87\xe6\x14\xcc\x89\x81\x04\xda\xec\xc1\x98\x06\xcb\xd3\x02\x97\x2f\x97\x15\x64\x89\xfd\x3e\xf4\x38\x0e\x7e\xfd\x2b\x6d\x94\xcb\xc1\xcc\x3e\x6c\x82\x0c\x2c\x75\xc6\xd5\xb1\x2e\x27\xb4\x11\xd3\xdb\x47\xa9\x0d\x9f\xee\xec\x20\xbf\xa0\xaa\xce\x31\xe2\x31\x59\x97\x16\x84\xb1\xb3\xb9\x19\x4f\x92\xe7\x2d\x2d\x77\xe6\xf4\x44\x15\x13\x7c\x90\x92\x18\xf7\xe3\xb2\xc2\xc9\x8c\xc4\x38\x89\xd1\x6d\xdd\x37\x47\xea\x05\xff\xf5\xe2\x2c\x20\x93\xd7\x2b\x04\xdb\x10\x8c\xe5\xa9\xe9\xf6\xca\xc6\xfe\x6c\x60\x4f\xda\xf0\x2b\xed\xb9\x36\x30\x89\x24\x4d\x22\x67\x10\xfe\xfe\xd7\xf5\xa2\xd4\x9e\xa6\x60\x66\xe8\x7f\x15\x8c\xc0\xc4\x11\xf4\x7c\x20\xbe\x17\xe3\x7c\x36\x26\x98\x58\xd2\x93\xb2\xfa\x30\x05\xbc\x4f\x99\x25\x2e\xdc\xe3\xa4\xec\x01\xd3\x34\x41\x33\x82\x8a\x91\x19\x5c\xd5\x53\xd5\x47\x8e\x29\x47\x9f\xde\xbe\x87\x86\xc8\x23\x3d\xed\x3d\xc7\x54\x58\x0e\xcf\xc1\xf8\xb9\x10\x02\xc0\x2c\x50\xbe\x6a\x66\xdd\xf5\xc5\x39\xe6\xa2\xe9\xd7\xe1\x59\x96\xfa\x3a\x9b\x4f\x28\xdb\x9b\xba\xca\xdb\xa5\xaa\xca\x6a\x9f\xff\xdf\x11\x77\xdd\x62\xdd\xe2\x4e\xf8\x67\xe1\x52\x91\xa5\xd1\x33\x29\x0e\x19\x0b\xe4\xa8\x99\xf4\x7b\x4b\xaf\x13\x09\x5f\xa5\xc9\x51\xa4\x4a\xba\xe8\xfa\x8d\x65\x6e\x5c\x0c\x52\x54\xb3\xf9\x28\xa4\x31\x7c\x48\x3a\x0c\x1c\x08\x7e\x77\x43\x08\x8c\x1a\x2b\x04\x5d\xf7\xd5\xa4\x27\x11\x5f\x84\xd4\x66\x7a\xc8\x1e\x24\xe6\x07\x5a\x8a\xcf\x11\x16\x20\x88\x90\x4c\x84\xdd\x6e\xd7\x60\xbb\x25\x59\xef\xf9\xe5\x20\xa2\xb5\x7b\x57\x56\xdb\xb7\xba\xfa\x98\x0c\x97\xf1\x88\x50\x31\x23\x3a\x57\x47\x14\x39\x20\xf8\xe6\x6b\xc2\xf9\x0e\x53\x32\xa3\x4f\xfc\x6d\xd8\x77\x50\x27\x8a\x48\x09\x1f\xae\x3d\x3d\x03\x9a\x30\xa5\xc0\xc6\xbf\x96\x93\xc0\x32\x9a\x38\xb4\x6c\x48\x14\x85\xd9\x7c\xc0\x61\x64\x84\xa3\x49\x0d\xd5\xfd\x74\x4e\xd9\x1c\x5a\x88\x06\x2c\xf1\xb6\xab\x16\x79\x46\x62\x63\x3d\x3f\x10\x8d\x41\x2a\x5f\x79\x25\xdc\xe5\xfa\x6a\xeb\x2d\x66\x13\x44\x49\x62\x85\xd5\xe9\x2a\x33\x10\x9c\x09\x74\x4c\xc5\x16\x2d\xa9\xa3\xf9\x69\xd2\x4c\xcc\x6a\x13\x86\x16\x21\x66\xf1\xea\xd5\x0f\xd4\x8e\xcc\xbd\xbb\xd9\xe2\x70\x28\x3c\x15\xff\xa4\xeb\x4c\xc8\x13\x2a\x98\x34\x0d\xe5\x47\x69\x55\x7c\x3c\xee\x1d\x67\x8e\x6f\xa4\x63\xca\xfe\xe6\xbd\x58\xc2\x6c\x5b\x30\x91\x23\x01\x74\x69\x94\x63\x67\x91\xcf\xb8\xd4\xb8\x89\x32\x06\x74\x99\xc6\x63\x02\xfd\x0d\x22\x94\xe4\x89\x5d\xd1\x13\xf4\x74\x32\x26\x56\x99\x0f\xd1\x39\x65\x4f\x8b\x69\xec\x76\x4a\xc4\xae\x9f\x9a\xe1\x29\x63\x6d\xd9\x29\xda\xb7\x1a\x9b\xb7\xaa\xd0\xd3\x0e\x4a\x54\x46\x10\x70\xca\xf3\x2e\xb7\x77\xcf\x90\x0f\x61\x36\x93\xa6\xd2\xd3\x12\x2c\x8a\xe2\x0e\x61\x38\xc2\xb5\xaf\xc6\x9f\x14\x0c\x35\xbd\x25\x7a\x7e\x17\x31\x29\xc4\x1c\x7a\x3d\x8c\x71\xe8\xd1\x64\x86\x11\x14\x77\xa1\xa0\xd4\x9f\xbf\xde\xeb\x0d\x8f\x22\x4a\x63\x7b\xca\xb3\x09\x96\xc5\x88\x00\x2d\x0d\x40\x67\xb5\xc0\x3e\xd7\x61\x7f\x04\x12\xb2\x88\xf7\xf0\x73\x5d\x5b\x64\xec\xb0\x44\xac\xb1\xf6\x79\x64\xdf\x1e\x58\x46\x7d\x88\x4d\xf7\xf1\x4e\xc4\xc9\xb9\x91\xa1\x20\x34\xc6\xae\xb7\x94\x2e\x92\xf9\x8f\x4e\xd2\x82\xa2\xb0\xbe\xd4\xa8\xdf\xf2\x2f\x21\xe4\xe8\xff\x30\x98\xe6\x2b\x8d\x34\x21\x07\x07\x30\x81\xc2\x7e\x05\x5b\x2c\x3e\x4d\x30\x18\x85\x96\xa1\xe8\xbf\x97\x2f\x23\xc5\x0d\x6e\x74\x16\x92\x39\x6f\x43\xf3\xcf\xa5\x26\x12\x5f\x7f\x50\x59\xd5\x9b\x06\x0c\x5a\x7d\xe0\xeb\x02\x61\x88\x67\x19\x4c\x62\x32\x7d\x36\xdb\xc5\x76\xb9\xbb\x5a\x6e\x77\xcb\xc7\xc5\xd5\xfd\xf2\xa6\x6f\x20\x80\x8a\x18\x1c\x84\x93\xcd\xbe\x12\x2a\x4b\x21\x5c\x63\x5e\x36\x23\x98\x8a\x31\xb1\xe0\x30\xac\xe1\x96\xd7\x8f\x00\x9e\xbe\x01\xa6\xf4\x3e\x7f\x57\xf9\x7c\xfe\x1a\xc3\x69\xe6\x3c\x56\xef\xc7\xeb\xaa\x6c\x8e\x7b\x8a\x94\xaf\x0b\x28\xcf\xee\x2e\x22\x08\x23\xab\xba\x63\xa9\x2c\x9c\x51\xb3\xe9\x97\x1b\x11\x84\x32\x10\x16\x80\xae\x4b\xfc\x38\x45\x16\x88\x20\xd4\x56\x7a\xc3\x22\xb4\x77\x6f\x58\x1c\x66\x6a\x69\x22\x88\x22\x16\x59\xfe\x1e\x04\xab\xd3\x4f\xd1\x6b\xef\x75\x89\x20\xe2\xa1\xee\x16\xe8\x9b\xdb\xb1\x0c\x96\x08\x92\x04\xe9\x7f\xeb\x4e\x3d\xe2\x09\xf4\xfd\xac\x21\x78\xf1\xe0\xf9\x4e\x48\x24\xd2\xb7\x5c\xd5\x55\x79\x07\x23\x47\x62\xd6\x2e\x0d\x75\xd6\x93\x60\x8f\x49\x30\x67\x99\x55\x11\x64\x22\x24\x84\xd5\xf3\x1f\xcf\xc3\x90\x13\x41\x86\xd6\x4e\x39\x89\x3c\x4e\xcf\xe6\x71\x08\x6c\x9a\x11\x61\xe3\x8c\x88\x08\xb8\x91\x96\xc9\x81\xed\x9c\xdd\xe4\x6f\x21\x82\x30\xb0\x65\xd1\x56\x06\x77\xf6\xb1\x44\xa8\x03\x1c\x2a\xc4\x66\x07\x41\xa1\x2d\x1c\xd9\x1c\xe0\xa3\xa4\xec\xba\xc7\x65\x9c\xed\x10\xa1\x14\x25\x90\x0b\x34\x2d\x4b\x67\x6f\x21\x4c\x1a\xf1\x11\x29\xde\x57\xce\x80\x08\x40\x18\x08\x7a\x08\xe1\x2b\x76\xdd\xbb\x68\xdb\xaf\x53\x99\x22\x90\xcc\x6a\xe3\x75\x3e\xb9\x8d\xdc\x41\xf9\xee\xfb\x42\x66\xda\x38\x48\xc1\x88\x5f\xd8\xa1\x32\xc7\x8b\x84\x08\x54\x68\x7d\xb8\x43\x8d\x0f\x73\x88\xd4\x70\x37\x15\x09\x6e\x3c\xff\x67\x7e\x58\xe9\x66\xd8\xd1\x44\xa0\x38\x52\x11\x99\xae\x1e\x06\x99\xa1\xb3\x8b\xa0\x08\x94\xb4\x84\x7a\x0f\x79\xfb\x8e\x9f\xe3\x31\xa2\xa4\x5d\x37\x3a\x43\xb7\x0f\x1b\xf8\x63\x26\x26\x98\xcd\x01\x3e\x5d\xf6\xe7\x1c\xd6\x57\x04\x3a\x8c\x09\x7f\x45\x03\xf5\xea\x68\x7a\x3b\xba\x3b\x94\x90\x39\xeb\x41\x0e\x03\x7c\xcc\x35\x40\xa6\x28\xa5\xbc\x38\xb6\xd5\xad\x87\x38\x4f\x81\x90\x22\xe8\xec\x58\x1c\xa4\xcd\x6e\x76\x0f\x8b\xe7\xdf\x97\xdb\xd5\xe3\xb7\xdd\xb7\xe7\xa7\x97\xb5\xbf\x98\x41\x2b\x28\xf9\xea\x8b\x7a\xcf\x89\x10\x0b\x16\x64\x09\xb9\xbe\x4d\x55\xe8\xab\x4f\x47\x29\xe0\xd7\x06\x16\x70\x6b\x35\xfb\x4d\xa6\x47\x49\x3e\xf4\xa5\x61\x82\x05\x10\x79\xc2\x6d\x4f\xd2\x78\xa2\xff\x26\x58\x60\x6c\xbd\xf9\x7d\xf5\x7a\x95\xeb\x07\xd0\x5f\x0b\x26\x0a\xc6\x22\xa9\x2c\xb0\xb3\x1d\xd3\x0a\x0b\xc6\x62\x4d\x39\xc9\x0f\xc2\xd8\xae\xab\xaa\xd8\x0e\xca\x28\x82\x31\x11\x93\xff\xf5\xf8\xb4\xdd\x2d\x5e\x6e\x56\x5b\xbf\x31\x74\x87\x78\x88\x03\xb7\xfc\x93\x71\x91\xfd\xc9\x27\x64\x4c\x09\x8a\xf6\x6a\x68\xde\xbc\xa3\x23\x58\x1c\x49\x5a\x0e\xab\xf2\x03\x6b\xe3\x43\xb7\x82\xc5\x59\xe2\x21\x38\x84\xa0\xfc\xfd\xaf\xeb\xd9\xf5\x62\xae\xa8\x1c\xc5\x7e\x75\x5a\xc7\xaf\xaa\xea\xfd\xfc\x4a\xc7\x62\x63\x45\x0e\x0f\x55\xad\xaa\x19\x8c\x4e\xb0\x24\x0a\x29\xd2\x39\x68\x06\xde\xe7\xcd\xb8\x22\x6f\x7a\xb1\x04\x04\xb3\xea\x47\x96\x08\x10\xad\x04\x8f\x7f\xf6\xc4\x68\x1b\xb5\x3c\xca\x6d\x35\x46\x52\xcd\x3e\x45\xca\x2c\x85\xc3\x55\xb7\xda\xcd\x0e\x45\x36\x56\x01\x5a\xf7\xb0\x35\xd4\x73\x19\x41\x07\x3f\x13\x2c\xcd\x12\xe3\x9a\xef\xa0\x24\x01\xfb\x33\x88\x61\xc1\x52\xce\x08\xb9\xdb\x39\xfc\xc7\xc3\x4b\x83\xf5\x09\x28\x6e\xb8\xa6\x09\x5c\xdd\x39\xaa\xf7\x5d\x5e\x3a\x3d\xf8\x6a\xde\x77\x99\x61\xa9\x0f\x78\x57\x55\xa1\xab\x8f\x72\xa0\x60\x8e\x83\xbe\x55\x4a\x45\x16\x43\xca\x70\x46\xc9\x29\x18\x8f\x23\x5a\xf9\xcc\xb1\xdc\x35\x50\x6a\x59\xfd\x9c\x3d\x3e\x17\x8a\x34\x7d\x16\xdb\xed\x78\x86\x33\x11\x73\xa2\x0d\x27\xa8\x4a\xae\xaa\xdd\xb0\xdd\x33\x11\x8b\x34\xee\x89\x9a\xe7\x45\xc9\x82\x09\xa3\x08\x28\xfe\x0d\xaa\xd7\x23\xcc\x38\x6a\x04\x93\x2a\x25\xb0\xcd\xba\x46\x8d\x9d\xf7\x52\xf5\x9f\x59\x6a\xe6\xf8\x8b\xa8\x80\xcc\xbb\x91\x93\xab\xab\x40\x4b\x37\x89\xc9\x7a\xc5\x7d\x55\x9e\x5d\xe1\x98\x42\xe3\x14\x20\xa0\x6e\x37\x05\xec\xf7\x58\x53\x0c\x78\x36\x9d\xff\x27\xf9\xdf\xf9\x0a\xec\xe5\xd1\x04\xd3\x8c\x51\xca\xd1\x5a\x80\x2e\xff\x40\x0b\xeb\x98\x05\x40\x30\x1d\x1b\x4a\x98\xf9\x05\x08\xf5\x58\x06\x49\x30\x9d\x65\xa4\x0c\x63\x2b\x4d\x37\x58\x58\x5a\xe1\x13\x83\xf6\xfc\x5c\xc3\x34\xcb\x32\xc7\xa3\x37\x41\x3e\x4f\x7b\x1e\x21\x21\xf7\x59\x55\x65\xd3\xd6\x36\x1b\xbe\x1c\x3e\x9c\x09\x42\x82\xbf\xf6\xa1\xd7\xe7\xaa\xba\xa8\x9d\x30\x31\xa5\x05\x33\x51\x9a\x26\xe3\x15\xe9\x76\xce\x66\xd3\xb5\xc9\x28\xe6\x7b\x7d\xb7\xdc\x6c\x26\xc3\xc9\x24\x56\x5f\xe4\xe9\x79\xf5\x6d\xf5\xb8\xb8\xdf\xad\xd6\xb7\x9b\xdd\xdd\x62\x73\xd7\xb7\x50\x48\x0e\xfd\x76\x5f\x95\xf8\xb9\x25\xd9\x3a\x7f\x48\xdb\xa2\x84\xbc\x69\x8e\x78\x8d\xb5\x53\x89\xc3\x2f\xc2\xe5\x22\x0c\x82\x04\xc2\x9e\xbd\xcd\x52\x82\x8d\xf1\x68\x22\x64\x91\x05\x33\xba\xf0\xd7\x19\x52\x17\x11\xb2\xd8\x92\x1b\xef\x3f\x3b\x2f\x24\x3f\x92\x8c\x61\x1f\x7c\x13\x21\x4b\x75\x18\x0c\xb1\xe6\xa1\x3c\x4b\x84\x4c\x22\xc1\x8a\xa8\x48\x6a\x47\x3a\x4b\x8e\xfd\x6d\xc7\xfa\x36\x98\x52\xf5\xd0\xca\x3c\x54\xfa\x58\x38\x7d\xce\x33\x2c\xc3\x22\x0c\x23\xa9\xe5\x5c\x76\xcd\xd2\x12\x7f\xa1\xba\x26\xc2\xc8\x30\xaa\xa0\xd8\x60\xbb\xc3\xf6\x6d\xf7\x9a\x9b\x29\x65\x88\x08\xe3\x98\x51\xb2\xce\x2d\x47\xb8\x28\xf5\x37\x24\xe5\x2d\xdc\xdf\xe2\xd7\x99\x72\x11\xc6\x89\xa5\xc9\xa3\x59\x46\xf1\x9a\xd9\x71\x0c\x93\x78\x28\x6d\xa8\xd1\xe6\x25\x9a\x16\xf6\x87\x79\x53\x63\xa5\x9e\x77\x45\xa5\xde\x5d\xd4\x74\x3c\x8c\xc2\x84\x87\x99\x05\x9a\x20\x4c\x59\x9d\x45\x98\x18\x43\xd5\x83\xfb\x4a\xe7\xe6\xb3\xd7\xe4\xda\xc2\xcf\x53\xa5\xbc\xf3\x1b\x79\x98\x06\x96\xca\xf4\x70\x94\xc3\xac\x09\xd3\x28\xa5\x7d\xd3\xa5\x74\xf2\x06\x4f\x02\xd0\x5f\x5f\x36\x8b\x0d\xe5\x04\xe5\xf1\xf3\xea\x69\xfb\xf3\x02\x2f\xcd\xf9\xde\xe5\x3c\x21\xc6\xcb\xfa\x58\x36\x4f\xc7\xf6\xc9\xf4\xc5\x52\x9d\xf7\xd0\xf3\xb5\x5e\x0c\x89\x4f\x07\x83\x00\x0b\xb0\x18\xb6\x8c\x8b\xec\x4d\x22\x14\x5a\x05\x82\x44\x0b\x7b\xc2\x67\x67\x55\xf5\x4f\x00\x21\xcf\xc4\xa0\xd4\x33\x63\xfa\x9b\xdd\x1c\xb2\x38\x10\x43\xe4\xeb\xea\xf8\x79\x3d\x26\xbc\x9a\x35\x16\x56\xae\x09\xda\x16\xba\x79\x45\x38\x9c\x47\xfc\xa0\x84\xaf\xb3\x36\x27\x58\xc4\x13\x79\xbc\xe9\xf5\x64\x26\xa8\x3e\xf6\x0e\x9a\xb7\x67\xeb\x0d\xe9\xb3\x45\x44\x22\x54\x1c\xc0\xe7\xe3\xe1\xf3\xe9\x38\xd1\x92\x10\xa1\x82\x90\x92\x82\xff\xc2\xea\x00\xb5\xfe\xec\xff\x97\x92\xd0\x10\x37\x8b\xbf\x36\xcb\xeb\xa7\x47\x2f\x7d\x2d\x42\xa5\xad\xb2\xe3\x2b\xb6\xb7\x55\xdd\xbe\x11\x09\xc4\xf3\x50\xf5\xec\xdb\xe9\xd4\x72\x39\xfb\x2d\xe4\xae\x6a\xb1\xb8\xd0\x99\x5a\x58\xe6\x22\x28\x8a\x4d\x6f\x70\x86\x28\x33\xf2\xb5\xaa\x03\x96\x13\xae\x22\x11\x9a\xd8\x6a\x86\x4c\xab\x82\xa6\x17\x35\xa8\x28\x29\x92\x37\x04\x11\x26\x3c\xea\xa4\x45\x14\x28\xe3\x94\xda\xfc\xf4\x88\x02\x03\x54\x41\xbc\xbe\x5f\x6c\x6f\x9f\x9e\x1f\x76\xb7\x4b\x22\xa0\x5d\xfa\x06\x2c\xb0\x32\x9a\x7b\x2c\x10\x1d\x23\xc0\xd5\xe7\xe6\x28\xdb\xcf\x03\x9e\x8a\x44\xd3\x09\x96\x26\xb8\x3a\xd6\x25\x10\x59\xb9\x97\xae\xf0\x2d\x50\x52\x64\x8e\x60\xc1\xcd\x5b\x7e\xf0\x66\x5c\x7d\x2a\xdd\xef\x4e\x09\x43\x0c\x92\x89\x7a\xd1\xf9\x91\x17\x85\x51\x60\x11\xf3\xdd\x7a\xb6\xad\x61\x20\x89\x16\x51\x98\xa0\xec\xfa\xf7\x3f\x58\x57\x2f\xab\xbe\x73\xa3\x10\x2d\xd6\x85\x22\x10\xdd\x10\x5d\x3b\x9a\xfc\x73\x4b\x79\x14\x65\xd2\x96\xc6\x60\xdd\x54\x9d\x93\xdf\xd8\x5c\x7e\xd5\xf4\x17\x8c\x94\xe5\xc0\xec\x16\x4d\x8d\x70\x73\xe2\xa5\x44\x11\x5a\x06\x3a\x42\xb4\xd9\x4f\xbd\x9b\x61\xb8\x44\x94\x84\x56\x73\xe4\xdb\xd3\xbd\xbf\x72\x2a\x38\x73\x55\xb2\x8f\xc7\xbd\x83\x1f\xbf\x34\xa8\x6f\xab\x7a\xe6\x78\xcd\x3a\x26\x55\x61\x06\x7e\x18\x5b\xd9\xa7\x89\xb5\x19\xa5\x0a\x53\x4b\xc5\xe6\x92\x16\x4f\xe5\x6b\x35\xea\xbd\x54\x47\x89\xe5\x76\x2f\x8a\x7b\x54\x55\xd9\x8e\xb0\x2b\x22\xca\x42\xd0\x23\x6d\xd9\x7c\x6e\x16\x47\x59\xa8\x43\x5f\xe9\x71\x5f\xf5\x97\xcd\x32\xed\x62\x4b\x24\x30\x69\x91\xf1\x43\x1a\x5f\x44\x3c\x16\xc6\xc9\x34\x51\x90\x0c\xc6\x19\x1d\xdf\x26\xcb\x6c\xcd\x58\xfb\xd6\x5d\xc0\x67\xc1\xfc\x51\x6e\xb8\x43\xef\x2d\x6a\x99\xb7\xf5\x69\x60\x5c\x44\x22\x88\x32\x67\x0b\x50\x50\x7c\x66\x4b\x44\x20\x58\xea\xc2\xc2\x14\x3a\x19\xf2\xda\x7e\x27\x8e\x24\x63\x94\x21\xb9\xca\xdb\x22\x7f\xef\x7b\x46\xa6\x9c\x2c\x15\xb3\x39\xca\xf3\x96\x5f\x24\x31\x4e\x52\x4f\x04\x34\x26\x12\x74\xc7\x55\x68\x03\xaa\x9e\xa6\x67\x54\xf5\x46\x07\x29\x68\xde\x7c\xc0\xe1\xae\x6a\xaf\xab\xa2\x9f\xdd\x2a\xb2\x9c\xc3\x83\xc2\x06\xf5\xef\x80\x57\xf7\xed\x52\x2b\x78\x4d\xb5\x63\x67\x97\xe0\x48\x27\x41\xcf\xb7\x4b\xde\xec\xa3\xa7\x87\x11\x91\xce\xd2\x34\xea\x91\x7f\xcb\xba\xbe\xae\xf6\x12\x66\x31\xaf\x08\x51\x58\x64\xab\xc9\xbd\xf9\x7c\x3c\x01\x74\x8b\xc8\x84\x40\xdf\xb2\x45\xb0\x80\xe6\x66\xd5\x59\x8e\x37\xa3\x37\x36\x91\x15\x72\xa5\x64\x60\xbb\x87\xf9\xb7\x34\x31\xa7\x7a\x1a\x93\xbb\xe0\x46\x1a\xcf\xa8\xa6\x44\x64\x12\x4c\xdd\x7c\xd8\x11\xdc\x62\x77\x6c\xb0\xde\xd5\xa8\xa0\x99\x99\x58\x91\x11\x40\xdb\x78\xf3\x56\x7d\xdc\xe0\xfe\x58\xd7\xf0\xea\xb4\xba\xfb\xe9\x63\x84\x89\x6d\x92\x53\x55\xb5\xb6\xda\x15\x13\x0b\x63\x24\x21\xed\x4f\x31\x0a\xa2\xa1\x1c\xeb\x19\xfd\xa4\x88\x03\x63\x6c\x25\x37\xb9\x1b\x57\x38\x7b\xa0\x98\x25\x29\xf9\x70\xf2\xf8\x49\x18\x50\x8f\x8a\xed\x1e\xf0\xfc\xbe\x18\x87\x71\x46\xfb\x22\x65\xf9\xfe\xa6\x5d\xf9\xf0\x2f\x0f\x2e\x13\x71\x14\xa2\xd7\xf4\x72\x0f\xdd\xad\xdd\x93\xd8\x54\x1c\xc5\x48\x21\xde\xbc\x6c\xb0\xa6\x85\xf2\x4b\x9a\x34\x11\x47\x89\xa2\x91\xb9\x05\x0d\x03\x9b\xc7\x9a\xaa\x60\x06\x3a\x1b\x11\x47\x46\x27\xfd\xee\x66\x3f\xb7\x05\xe8\x7f\x1d\xba\xe9\x2c\x5f\xaa\x05\xba\x79\xfa\xbe\xdb\xbc\x3c\xfa\xcb\xc5\x51\x1a\x99\xde\xe9\x5b\x14\xc5\x0d\x1e\xb0\xd4\x58\xaa\xbc\x37\x7e\xe2\x18\x33\x4a\xf3\x59\x8b\xdc\xd6\x3f\x91\xe8\x67\x5e\x9e\x94\x35\xbb\x53\x92\x2c\xe6\xd1\x28\xad\xd1\x87\x43\xc2\x09\xcc\x71\xf8\xd7\x9f\x07\x49\x66\x99\xc1\x4b\x4d\x5b\xf3\xb4\x12\x6e\xb2\xbd\xc4\x29\x20\x19\x01\xee\xb9\xe0\xd8\x50\x45\x8b\xe9\x7a\x7b\x88\x44\xc6\x82\xc5\xe4\xac\xfd\x1d\x3a\x4e\x85\xdf\xfa\x03\x82\x22\xcb\xf5\x19\xd0\xfe\xd4\x39\xf4\x27\x48\x46\x50\xf2\xfd\xb1\xcd\x37\x58\xea\xe5\xf6\x8e\x88\x8a\x72\xd3\xf9\xc1\x65\x6b\xeb\x42\x2f\x1a\x9a\x31\xa4\x09\xeb\xf9\x6d\x2c\x4d\x2a\xc9\xf1\x77\x43\xf7\x5c\xa1\xa2\x88\xc1\x48\x13\xba\xcd\xfc\x2a\x7f\x5d\xd7\xd5\xbe\x1a\x51\xb2\x8b\x58\x4a\x6b\xbb\xbe\xbe\xaa\xd9\x9e\x18\x2b\x1d\x52\x29\xc1\xd5\xe2\x7a\xf1\x5b\xff\x9f\x09\x74\xaf\x0f\x66\xce\xdd\x52\xa1\x96\x7c\x10\xee\xa0\x6a\xff\x49\x9d\xcf\x7f\x8d\xfa\x56\x19\xc1\x5c\x00\xe7\xca\x8a\x5d\x9d\xf2\xbd\x8b\x18\xe3\x8c\x00\xc0\xb7\x45\x3e\x26\xdd\x15\xb1\x89\xb4\x07\x8b\xbf\x1c\x4e\x89\x3b\x44\x6c\x62\x5b\xee\x77\xb0\x1a\x16\xfd\xc4\xa0\x3c\x6e\x1f\x73\x88\x0d\xc4\xa1\x97\x1b\xba\x7a\xf9\x6b\xf5\x38\xa6\x4e\x15\x49\xc0\x40\x0f\xa5\x4b\x0e\xbe\xfb\x55\x3d\xbe\x48\x98\x93\xd9\x5f\x57\xdf\x1f\xee\x89\x9d\xcd\xdb\xbf\x09\x4b\x25\x64\x23\x85\x20\x67\x65\xd9\xa4\xe9\xcd\xd1\x96\xee\x8f\x6a\x33\xbb\x33\x14\x89\x4d\x4a\x6c\x1f\x48\xb4\xe4\xd8\xe3\xd9\xb9\x6f\x22\x14\xad\x9b\xf7\x8b\xdb\xd5\xe3\xe2\x3e\xf3\xa7\x86\x71\x34\xd1\x7f\x99\xc3\x55\xce\x3a\x53\x49\xc4\x02\xe9\x8a\x41\xbd\xc1\xf8\x0c\x13\x1f\x68\x14\xbf\x4e\x22\x08\xb9\xdb\x52\xbf\x61\x89\x8d\x67\x93\x99\xf6\x48\x84\x48\xce\xf3\xca\x46\xf3\xd6\xc7\xce\x4b\xb2\xea\xf3\xb3\x9b\x1b\x26\x5c\x85\xd3\x92\xea\xb0\x26\x4b\x63\x12\xa7\x19\x8b\x7c\xbd\x6e\xb7\xb3\xde\x41\xf1\x23\x2f\xfb\xed\x21\x49\x74\xac\xd0\xef\xf0\xbd\xd1\x38\xbb\x49\x1a\x08\xee\xf6\xd8\x6b\x38\xe4\x2d\x14\xf3\x06\x61\x4a\x21\x70\x2b\x16\x4d\xd0\xf5\xc5\x50\x92\x2f\x92\x54\x20\x5d\xc0\x99\x94\xeb\xa3\x5c\x5d\x3f\x8d\x56\xda\x24\x4b\x0c\xed\x7a\xcd\xf1\xd0\x0d\x96\x7d\x1f\x5d\x4f\xb2\x54\xf1\xb0\xa7\x09\x2d\x96\x3f\x0f\x13\x5b\xc5\x7f\xd2\x2c\xcb\x24\x0e\x58\x1e\x32\x27\x1e\xab\x91\xf2\xff\xf4\x81\x33\x1e\xe0\x48\x09\xbe\xaf\xf7\x74\x9b\x3e\xbf\x14\x38\x3b\x51\xe7\x9b\x32\x90\x88\x24\x53\x40\x7b\xd1\xd5\xd3\xe3\xcb\x66\xfb\xfd\x69\xa4\x80\x2d\x92\x4c\x73\xca\xbc\x12\xf3\x5a\x3f\xbd\x7a\x61\xdf\x79\x64\x37\xc9\x34\x10\xf6\x98\xba\xf5\x06\x9b\xb6\xae\xfa\x89\x91\x19\x34\x71\x5f\x49\x37\x00\xaf\xa7\xe3\x88\x87\x29\x19\x50\x05\x34\xed\xd5\x51\xbd\xf7\x4e\x5d\xc2\x85\xcd\x9d\xb6\x35\x68\xc2\x75\xdd\x9d\x49\x3e\x5d\x54\x70\x38\xdb\x2d\xee\xca\x22\xb4\xee\x62\x5e\x76\x8e\x4b\x83\x8e\x72\x85\x0c\xd3\xab\xcf\xa7\xb2\xff\xe8\xdd\x5a\x65\x6c\xb5\xc3\xdb\xa5\x88\xa5\x6f\x9a\x32\xd9\x2f\xe6\x84\x1e\x3f\xe5\xfe\x12\x09\x30\xa5\x42\x4f\x07\xf8\x31\xce\x8a\x24\x10\x0b\xaa\xe7\x79\x29\xd5\xa8\xac\x49\x24\x90\x84\xcc\xc5\x77\xfa\xe7\x02\x2e\xa3\xb8\xdf\xa7\x4f\xa2\x3c\x73\x20\x99\x48\x64\x14\x12\xa1\x9d\x65\x2d\xde\x56\x87\xb3\xeb\x6b\x22\x63\xab\x1a\x74\x80\xbc\xbf\xbf\x0a\x99\x50\x63\x49\x40\x92\xec\xfe\x7a\xb9\x54\x61\xa2\x1d\x5a\x7e\x50\x55\x9e\x75\x85\x8a\x84\x8f\x0e\x3c\x1e\xf7\x4e\xb3\xa1\xbf\x69\x8a\x7e\x27\xb8\xb2\xdd\xbe\x29\x7a\xfa\x93\xf3\x91\xda\x44\x07\xd8\xcb\x84\x2c\x4a\x6d\xf1\x80\x53\x88\xe8\x38\xff\xed\xcf\x0a\x35\x79\x27\x57\x55\x6b\x77\x82\x53\xef\x3f\xd1\x71\x46\x4e\x86\x95\x24\xde\x38\xd1\x85\xc5\xc3\x40\xfd\x24\x12\x0d\xce\x12\xab\xf3\x09\x2d\x82\x48\x30\x48\x82\x01\x56\x56\xe3\x57\x6a\x5d\xfe\x14\x16\x7b\x71\x7c\xf2\x27\x3b\x93\x7f\x43\x14\xf0\xb3\x0f\x86\x51\xd4\x67\x4c\x8e\x6d\x65\xcc\x09\xd6\x5b\x24\x26\x55\x94\x2d\x2b\xe0\x58\xaa\xb7\x81\x99\x45\x24\x06\x53\x32\x40\x7e\x74\x86\xca\xc2\x4f\xf3\xfb\x97\x29\x75\x88\x48\x03\x16\x50\xf9\x39\x55\x57\x3c\x5b\x77\xd3\x99\x99\xbe\x45\x14\x1a\x4b\x50\x7a\x6c\xa6\x1a\xd9\x83\x75\x90\x06\x09\x52\x30\xdf\x6f\x5e\x67\x05\xc7\x44\xca\x82\x30\x71\x64\xa7\x7d\x01\x86\x48\x59\x14\x06\xe3\x3a\xa6\x2f\xe2\x39\x69\xc4\x6d\x45\xc4\x6b\x8d\xde\x01\xe8\x8f\xd8\x72\xb3\x6f\xd8\x6e\xdf\xf0\xfb\x5b\xe5\x2f\x1f\x43\x4a\x32\x2a\x96\x6b\x10\xea\xf6\xc4\x12\x4a\x63\xb4\xdc\xc1\x56\x1d\xc8\xee\x13\xfd\x34\x4d\x93\x98\xdb\xfd\x01\x8c\x7d\xb6\xa1\x78\xae\xfb\xe0\x97\x81\x7a\xd3\xae\x4e\x92\xc4\x67\xd1\x37\xf9\x6b\x89\xf5\x08\x65\x2f\xd2\xc4\x00\x45\x3e\xe9\x43\x34\x3b\x57\xfb\x3c\x3c\x44\xaa\x2d\x1b\xde\xb1\x9c\x6b\x46\x8a\x34\x45\x41\xd8\xb8\xf7\x46\x5d\x10\x81\x9c\x98\xd3\x69\xc6\x21\x71\xc2\xf1\x9f\xdd\x63\xdc\xd4\xf0\xe1\xef\xc3\x63\x11\xb8\x9a\x0b\xac\x21\xef\xff\x16\x40\xb9\x1e\xac\x5f\xfb\x8e\xe5\x3a\x25\xd8\xdc\x5f\xf7\xd7\xff\x0c\xae\x2d\x52\x8e\x29\x39\x18\xf6\xce\x5b\x78\xef\xac\xce\xd9\x90\x14\x02\x28\x0c\xf4\x23\xc7\x8f\x8d\xcf\x4c\xf5\x3e\x4a\x2a\x64\x68\xc9\x50\xbb\x7d\xac\x67\x27\xdd\xde\x6d\x2e\x9b\xe3\xa9\xd0\x16\x1d\xf2\x81\xf9\xa4\xe6\x42\xa4\x92\x31\xe9\x66\xd9\x77\x27\x26\x65\xa9\x9c\x28\x28\xe2\x03\xb3\xae\xf0\x5c\xa4\x32\x4b\x29\x53\xd7\x7d\xfd\xf5\x5b\x55\x0e\xd7\x01\x2b\x67\x73\x5f\xbd\x5a\xdf\x60\xb2\x80\xa5\xca\xc1\xe0\x3e\x30\xa7\xc5\x79\x3d\x2c\xb3\x7d\x0b\x99\x24\x3e\xd4\x42\x36\x25\x95\x09\x9e\x4e\xfa\x54\xa9\x98\xd2\x1f\xa4\x6a\x3b\xa2\x7b\x10\xa9\xe6\xb1\x4e\x5c\x94\xc0\xf1\x55\x35\x13\x6e\xa5\xd9\x3d\xb5\x34\x11\x73\x3e\x47\xb7\x78\x7c\xcb\x4d\x1b\x9e\xc7\x80\xa4\x18\xa5\x23\xb8\xd3\xaf\x3c\xb6\x14\xb5\x95\xe4\xeb\x21\xdc\xdd\xc2\xd1\x8d\xe9\x7a\x55\x36\x47\x63\x72\x95\x63\x49\x11\xf6\x66\xcc\xb7\xe3\x9f\xcc\x30\x85\x6e\x95\xbc\xa3\x72\xc4\xba\xc5\x49\x80\x27\x35\x71\x10\x78\x35\x92\xd7\xce\xa3\xbd\x30\xf0\x27\x33\x25\x0b\x82\x94\x46\x3e\xf1\xd3\x4d\xa0\xd6\x22\x0b\x32\x0b\x3f\x52\x8f\xb9\xc2\x6f\xc7\xcf\x95\xfe\xd9\x1f\x52\x42\x51\x91\xdc\x72\xf1\xe0\x69\xca\x3c\x06\xc4\xb7\x61\x41\x44\xc3\x36\x6f\x2c\x80\x68\x7a\x63\x16\xa2\x55\xc5\xb0\x8b\x8b\x1b\x85\x6b\xcb\x24\x74\x3e\xeb\x77\xbe\x12\xd5\x5f\x2f\xb2\x85\xf7\x77\xc7\x3d\x94\x5f\x2c\x98\x19\x8b\x0c\xb7\x1e\x11\xc2\xc1\xda\x6b\x3f\xf2\xa2\xe8\xb9\xdc\x44\x16\x46\xa0\x9d\x15\xfe\x80\xda\x25\x04\x67\x83\x2e\x0b\x63\x4d\xcb\x13\xf1\xa6\x3e\x95\xf3\xa3\x32\x20\x9a\x8f\xbc\xe9\x55\xce\xce\x03\x80\x45\x16\x05\x08\x2e\x4a\xb3\xd2\xd8\x67\x7e\xb2\x48\x70\xda\xe2\xdf\xaa\x63\x5d\x7c\xae\xfb\xca\xe7\xfe\x38\x46\xc4\xa1\x94\x37\x8b\xe2\xf0\x06\x2f\x87\x83\xcf\x34\x33\xd7\x22\x4e\x22\xa2\x71\x6c\x5f\xeb\x0d\xb6\xf7\x79\x1f\x5b\xcf\x62\xb0\x14\x68\xd7\x27\x34\x06\xd3\xbe\x4a\x02\xe4\xc9\xa8\x46\xcb\x69\x1f\xcc\x1a\xa5\x09\xed\x98\x3d\xac\xc3\x95\x88\xf8\xc3\x2a\xa5\xb8\xf9\xc6\x29\xe0\x8f\x3a\x62\xd8\x2f\xb3\x34\x48\x3d\x1d\x63\x37\xb8\x6f\x5c\x68\x60\xe4\x2e\x7a\x9f\x2d\xcb\xa4\xb5\x3e\xbb\x99\x44\x10\xf8\xae\x21\xcd\x88\x66\x61\x19\x78\x5c\x43\x1e\x00\x01\xc0\xf1\x07\x96\xed\x1c\x04\x72\x7e\x4f\xca\x38\x43\xcf\x51\xb1\xfc\x89\xfb\x43\x7b\x5e\xdb\x4a\x64\x3c\xd6\xf4\x5a\x54\xa9\x8d\xe5\x56\xcf\x07\x08\xe7\x21\xad\x3d\x16\xb1\x68\xe9\xdf\x55\xfb\xb4\x2f\xf3\xb1\x0f\xfc\x5f\x27\xfe\x70\xc6\x25\xa7\xf5\x1c\xa8\xc0\xe4\xb9\x7b\xfa\xe3\xfc\xe2\xc0\x4c\x62\x0b\xac\xc6\xaa\x7d\x22\x03\xa1\x49\x0a\xcd\x62\x94\xba\xd5\xe4\xe2\xb8\x93\x89\x76\xf8\x76\xaa\xeb\xda\x35\xd8\xee\xf3\xf2\xb9\x9a\x27\x77\x33\x15\x33\x32\x17\xd6\x2f\x57\xf7\xab\x6b\x4b\x81\xb4\xdb\xae\x1e\xbc\x23\x95\x29\xa1\xb4\xd3\x0c\xd8\xb4\xd5\x61\x94\xee\xca\x94\x14\x14\x7b\xbb\x2d\xba\xad\xe4\x06\x0b\xf8\x5c\x28\x85\x4d\x33\x2c\x7f\xb3\x7e\xd5\x0c\xa2\xb8\x27\xd6\x1a\x48\x68\xfc\xe1\xcc\xe2\x52\x72\x07\x51\x6e\x28\x8f\x8c\xb3\x00\x50\x66\x98\xd5\x2b\xf2\xe6\xd7\xb6\x1a\xbb\xb1\x99\x89\x83\xcc\x55\x34\x38\x6e\xc4\xd9\xe9\x02\x68\xfa\xee\x2d\xdf\xea\xb8\x8b\x79\x10\x49\xb2\x57\x09\x76\x7b\x66\xa5\xe7\x01\x58\xb4\x74\x73\x40\x95\x13\xb7\x3e\xbc\xd2\x12\x31\xb9\x07\x67\x2c\x49\x6c\x41\x4d\xbe\xc6\xfa\x66\xeb\x51\x12\x9c\xa5\x82\x82\x08\x75\xd7\x65\x69\x34\xfd\x1a\x9c\x29\x85\xdd\xa3\xef\xf6\x79\xd9\x92\x28\x83\x4b\x63\x9c\xfd\xca\x3c\x0c\x33\xea\xce\xef\xfd\xcb\xf3\x10\x34\x85\xce\xcb\xca\x87\x32\x67\x21\x4c\x1e\x85\x2a\x70\xae\x20\x19\x66\xfa\x7c\xb4\x9f\x47\x3a\x4b\xc2\x81\x0b\xde\x7b\xc3\x3c\x0e\x35\x01\xbd\x6c\x19\x6b\xb7\x33\x9e\xa6\xec\xce\x07\x6b\x79\x9c\x02\x65\x5e\xad\x30\xc3\x3c\xd9\x3c\x6b\x0b\x81\x03\xcc\xb4\xb7\xb8\xef\x15\x1b\x67\x7e\x3b\x8f\xa5\x8a\x1d\xfa\x73\x51\x23\x50\x74\xe1\xc2\x05\x4d\xec\xa3\x41\x57\x2f\xe7\x23\xe4\x3c\x36\x82\xbc\x4b\xb2\x8c\xef\xbd\xe0\xfa\x00\x9f\xf7\x7d\x90\x04\x91\x1e\xa9\xd1\x3b\xb9\xd9\xaf\xe0\x2c\x3c\x49\x85\x71\x2b\xa5\x2b\xcd\x28\xdb\xb1\x20\xc3\x60\x59\x9c\xb1\x61\x79\x02\xa0\xbc\x35\x7d\xa8\xca\xce\xd4\x79\x9c\x8d\x9d\x34\x4e\x28\xb2\x67\x10\xc7\xa6\x36\x4f\x55\x40\x35\xb5\xf9\xf8\xcf\x0c\x94\x2f\xb4\xbd\x86\x43\x73\x2c\x4e\x79\xb8\x04\xcf\x14\x27\x78\xbc\xa3\x2d\xb7\x54\x8a\x13\x4b\x8f\x73\x8c\x08\xc2\xb6\xcf\x5f\x6b\x68\x71\xc6\x71\xe6\x1a\x89\x48\xab\x5e\x23\xec\xf7\x71\x7a\x6e\x6a\xa1\x71\x21\x62\xe5\x34\x06\xae\x97\xdb\xb4\x7b\xa4\xab\x4f\xa7\x83\xd1\xdf\x52\x80\xa2\xed\xad\x5b\x60\x6e\xf2\xf9\xbd\x20\x16\x94\x9a\xdd\x05\x3f\x6f\xaa\x57\x54\x03\xe6\x96\x03\xa4\x34\x5b\x4a\xfc\x39\x95\x61\x7b\xa6\xd5\xa8\x6f\xa6\x52\xab\xa1\x40\xb4\xfb\x0e\x0f\x3a\xf9\x18\xa0\x13\xf2\xb4\xaf\x6f\x9f\x66\x2f\xa0\x82\x2c\x8a\x9c\x89\x79\x32\x54\x15\x4b\x68\xc7\xa2\x2c\xa6\xad\x00\xfc\x6a\xc0\x28\x86\x8c\xb0\x58\x4f\xab\xc7\xdd\x7a\xf9\xbc\x5b\x6e\xef\x96\xcf\x04\x84\x7a\xf2\x34\x75\x82\xab\xc8\xee\x09\xa0\xf5\xa6\xad\xf3\x69\xc4\x8e\xa5\x93\x7d\xe8\x1c\xab\xc7\x65\xaa\x8f\xee\xda\x46\xb1\x41\x34\xa2\xae\xfe\x83\xe5\x9c\xc5\x6e\xf6\xcc\x29\xa3\x80\xb8\x13\x73\x7c\xb9\x5f\xad\x27\x62\x8e\x82\xeb\x20\x23\x40\x23\x05\xea\xd7\x55\x55\xcc\x7a\x50\x47\x56\xf0\xc7\x19\x25\x57\x57\x4f\xfd\x91\xc4\x44\x4e\x9d\x63\xc0\xcb\xbb\x63\x18\x1b\x82\xb1\xb8\xb3\x2e\x94\xbe\x4e\x47\x0a\xa6\x3c\xf1\xd9\x70\x7a\xb5\xd9\x48\x32\x32\xd0\x8e\xac\x73\xf9\x03\xcb\x6e\x8f\xdf\x52\x99\xd1\x6c\x96\x18\x69\x68\xbc\xd0\x52\x78\xb5\xbd\x9e\x8e\x15\x83\x56\x41\xad\xad\x3e\x4a\x55\xe7\x58\x5f\x43\x51\x48\x70\x45\x7d\x03\xad\xd5\x64\x5a\x89\x80\x89\xd8\xb1\xe6\xaf\xae\x9f\x36\x27\x0a\xec\x42\xb0\xc8\x92\x48\xd8\x15\x68\x4b\x65\x62\xe7\x3f\x8a\x60\x99\xb0\xbe\xf6\xcf\xbc\xed\x7a\xfc\x37\xff\x3f\xb7\xd8\x52\xc7\x6a\xfc\xb5\xed\x24\x98\x48\xa9\x40\xb6\xf3\x9c\xee\xab\xaa\x39\x9f\x59\x3a\x35\x7c\x4e\x76\x01\x82\x44\x11\x6a\xba\x6a\xd1\x96\xed\x4f\x84\xb7\x85\x88\x50\x87\xba\x4f\x7d\x0e\x48\xcb\xf3\x0f\x16\x27\x11\xf9\xa2\x4a\x06\x26\x41\xe3\x33\x0c\x22\x49\x02\xed\x51\xe0\xd6\xee\x9c\x05\x09\x45\x22\x84\x63\x3d\xc2\xd5\xf5\xd3\x3f\xdb\xc3\x44\x9a\x00\xd3\x23\x02\x72\x03\x0a\x57\xfb\x83\x45\xc5\x9c\x49\x87\x4e\x06\x95\x48\x8d\xc8\x7a\xfa\xcf\xab\x63\xdd\xd7\x1a\x09\x91\xa5\x82\x96\xa7\x07\x82\xbf\xd9\x0c\xe9\xef\xf8\xd9\xf3\x58\x70\xdf\x0e\x15\xf7\x28\x84\xf6\xa8\xb1\x6c\x57\x37\xa4\xa2\x3d\x5e\x25\x05\x67\x5a\x3a\x68\xd9\x42\xff\x20\xa0\xdd\x79\x97\x49\x70\x6d\x28\xe2\xb5\x39\x1e\xb0\x7e\x29\xda\x1a\xd6\xd5\x07\xd6\xa3\x6a\x05\x21\x18\x24\x72\x08\x09\x17\x9d\x71\x56\xe2\x65\xe1\x40\x21\x44\x62\x6c\x39\x75\x55\x95\x9b\x76\x88\x1c\x08\xa1\x32\xda\x30\xf2\x32\x6f\x1f\x61\x8f\x9b\xcf\xbd\xac\x8a\x73\xa6\x96\x80\x80\x65\x6a\xc2\x1a\xd2\xdf\xda\x5f\x0d\x32\xe9\xd5\x4b\xa7\xb2\x4d\xd3\x57\x04\x93\xc6\xf2\x02\xce\xee\x44\xe9\x4a\x08\xc9\x53\x9b\x7a\xa7\xc1\xf9\x52\xe6\x6d\xe3\x18\xd5\xa6\x43\x41\x25\x09\xed\x8f\x16\xa1\x6a\xc5\x6e\xfc\x93\x29\x95\x84\x43\x60\x7b\x09\x75\xf1\xb9\x2a\x55\x75\x8a\x5d\xf6\xed\xb5\x12\x43\xce\x97\x70\xd1\x27\x9c\xce\x42\x68\x13\x19\x36\x42\xf4\xf5\x8c\x3e\x0b\xd2\x6d\x3a\xf4\x35\xc0\x42\x60\x2a\x29\xb2\x75\x86\x7e\x5d\x08\xcc\x22\x36\xca\x85\x5a\x69\x84\xfe\xcc\x0c\x28\xea\x33\xe2\x77\xe8\xac\xe8\x66\x3a\xc0\x50\x24\xa1\xe3\x39\xfb\x1d\x3f\x9b\xf9\x0d\x74\x44\x50\xa3\x5e\xbe\x66\xe0\xef\x14\x02\x91\xd3\xce\x46\xcc\x21\xf9\x7f\xb0\xe7\xf8\x16\xc2\x24\x86\x24\x45\xd4\x71\xbf\x28\x72\x2c\x9d\x9d\xd0\xbf\x95\xc9\x42\x8a\x83\xc8\x89\xfb\x30\xbd\xb7\x31\x8a\x64\x04\xba\x47\x6f\xda\x53\x98\x1e\x04\x81\xa0\x81\x45\x3c\x9b\x25\x14\x9b\x4b\xfa\x53\x5d\x53\xa4\xa6\x7d\x5f\x78\x5c\x98\xb3\x19\xe6\x09\x8b\xe3\xa9\xaa\x8a\x80\x20\xd2\x04\x3e\xd2\x23\x95\xb0\x99\x58\xa8\x27\xa8\x1e\xef\x02\x10\xa4\x89\x74\xb6\xed\xfd\xd3\xeb\x74\x28\x00\x13\x82\x7b\x8c\x8c\x2b\x52\x8d\xff\x42\xf0\xfa\x11\x02\xc2\x34\xec\x11\x2b\x84\x18\x1a\xd0\x3a\x10\x02\xd0\x0a\xdb\xbe\x41\xf9\xfe\x57\x75\x9c\xf6\x20\x84\xca\x4a\xbd\x59\xb6\xfc\x7b\x68\xda\xb1\x93\x04\xa1\x8e\xa8\x3c\x56\xbd\xbd\x97\x95\x46\xcb\x57\x33\x7b\xbc\xc8\x80\x14\xee\x12\x45\x5f\xde\x2b\x20\x0e\x2c\xcb\x8c\xcd\xdf\x38\x7e\xec\x4d\x0b\x83\x18\xc4\x2f\x49\x20\xa6\x37\x4a\x42\x2d\xd3\xc9\x2a\xf1\xd2\x60\x7d\x5f\x29\x57\xe9\x38\x8d\x80\x42\xa2\x02\x13\x4f\x31\xb1\xcb\xde\x3b\xeb\x0c\xc4\x18\xfa\xb0\xdf\xe6\x78\xb0\x3a\xdc\xb3\xee\x49\xe3\x31\x60\xda\xc7\xc3\xd7\xdd\xb0\x08\x47\x18\x25\x48\x33\x1b\x87\x7d\xb9\x7b\xf9\xb6\x7a\xec\xff\x35\x11\x15\x3a\x55\x6e\xf4\xef\xa6\x82\x2a\x93\x95\x70\x04\x2b\x71\x67\x67\x71\x48\x18\x9e\x3b\x38\x1c\x3e\xef\x73\x33\x62\x66\x11\x90\xe9\x44\x79\xef\xd5\xd1\xc3\xfa\x43\x9c\x85\xa1\x8b\xfc\xd2\xbc\xe9\xd9\x98\xb9\x6f\x10\x45\xe8\xea\xae\x37\xc7\xfd\x09\x85\xa7\x00\x9e\x6a\x5f\x98\xdd\xd9\x00\xdf\xf3\x59\x58\x0c\xb8\xd2\x94\x07\x5b\x57\x05\xd4\x67\x73\xed\xc0\x8d\x22\x9b\x6a\x12\x33\xfc\x47\xd2\xd8\x02\x84\x12\x7e\xe3\x75\x1f\x7a\x7d\xaa\x78\x25\x00\x58\x1c\xf0\x11\x61\xfd\x6d\x91\x1f\xfa\x39\x01\x19\xaa\x41\x67\xa8\x73\x7f\xa1\x3d\xd6\x53\x8c\x13\x80\x50\x94\xdf\xde\xe7\xe5\x19\xc6\x0f\x01\x20\x03\xa2\xc1\x5d\x9f\xbc\x1e\x28\x4d\x42\x34\xab\x32\x6f\xa1\x58\x57\xfd\x7d\x65\xa0\x08\x5a\x41\xd9\xe5\x0d\xb6\xbe\x6e\x73\x24\x35\x31\x7d\x0b\xa9\x11\xbd\x00\x51\x95\x7f\x6d\x75\x83\x0e\x2d\xf4\x71\x0f\x3f\x6f\xe0\xb3\xbf\xa9\x8e\x6d\xb0\xa5\xaf\xdb\x7e\xa8\x4a\xfc\x7c\xa0\x4a\xa8\xdf\xce\x2e\x54\x18\xab\xcc\x06\x36\xbb\x25\x11\xeb\xa5\x5f\xbd\x89\x64\xb8\xc9\xfd\x16\x01\x28\xad\xa8\xb4\x43\xd4\x3f\x54\x9f\x63\x7e\x24\x01\xa8\x2c\xb9\x43\x81\x3f\xb0\x78\x39\xeb\x94\x7c\xfd\x63\xaf\x23\x83\x48\xf9\xda\xce\xab\xfc\x02\xdc\x5b\x06\x1a\x69\xbb\xa6\x5c\x91\xe7\xb0\x9b\x7c\x18\x19\x18\x83\x30\xa6\xd6\x72\xda\x19\xcb\xce\x0b\xec\x93\x2d\x92\x29\x9b\xac\x9d\x56\x98\x75\xeb\xc9\x89\x66\x95\x90\xcc\x25\x77\x08\xef\xe1\x15\xfb\xdd\xb2\x3e\x6d\x19\x06\x96\xa5\xa0\x3c\xee\x7b\x35\xa9\xe6\xcf\xed\xe7\x61\x32\x03\x65\x98\x4a\xeb\x6e\x15\x08\xf5\xd6\xca\x08\xa1\x0d\xd1\xdc\x41\xf3\x36\xe2\x4a\x3c\x81\x48\xcc\x67\xd0\x99\x10\x82\x8c\x23\xa0\x61\xeb\x42\x96\x13\x07\xfc\x76\x9e\xbb\x94\xb1\xb0\xf8\xc9\xc5\xcd\x1f\xab\xcd\xd3\xf3\x6e\xfd\xf4\x74\xbf\x5b\x3d\xf6\xc5\x37\x32\xd6\x8c\x52\xae\xc4\x85\xb9\x6b\x06\x92\x47\x21\xd3\x04\xa8\xf6\x71\xfd\x74\xfd\x57\xff\x9f\xd2\x14\x30\xa5\x70\xf6\xc8\x2b\x97\x59\x94\x11\x0f\xee\x3d\x8e\xd5\x46\x84\xe4\xb1\x05\x0e\xf5\xa4\x03\xae\x94\x75\x3a\x51\x24\x57\x60\x8c\x8f\xd8\x78\x6a\x83\xfe\x83\x72\x0d\x64\x05\x2b\x57\xf5\x95\xeb\x49\x55\xa2\x14\x9c\x91\xa9\x53\x51\x02\x37\xaf\xca\xc5\xd8\x19\x95\xc2\x44\xbd\xfa\x2c\x36\x4d\xb7\x28\xae\xeb\xaa\x33\xb9\x86\x5b\x00\x53\xde\xd0\x5e\xd7\xf9\x0f\x2c\xf0\x15\xf5\xd4\xe8\x9a\x5a\xa3\x12\x42\x24\xcb\x6c\xeb\x5d\xe0\xe5\xcf\x37\x70\x94\x40\xd3\x97\x83\x2c\x4c\x60\x0c\x77\xaa\xea\xbd\x65\x5d\xd9\xed\xf3\x4b\x2a\xa5\xdd\x69\x96\x16\xc8\xcd\xce\x11\x43\xa7\x90\xc0\x33\x82\x07\xe1\x4f\x54\x47\xc7\x94\x6d\x2b\xa6\xcf\x83\xc6\x25\x70\xed\xe5\x88\x1f\x6c\x90\xc7\x22\x1c\x56\xc4\xba\xb4\xc9\x65\x91\x97\xaf\x63\x39\x3b\x21\x65\xec\xc0\x7d\x6f\xd5\xc7\x40\x3d\xd3\x73\xf6\xb8\x56\x2a\x92\x94\x7e\xc8\x9b\x05\x49\xc5\xe2\x6c\x25\x97\x2a\xd1\x8e\x09\xad\x84\xe2\x73\xce\xe0\x29\xa4\x92\x96\xf5\x6a\x08\x03\x8f\xa2\x3a\x17\xba\x46\x07\x96\x4f\x82\xc6\xeb\x4a\x55\x96\x85\x37\x2c\xf5\x48\xd7\x53\x48\x9d\x58\xda\xf1\x1a\x7f\x54\xef\x5f\x28\x8e\x0b\x89\x3a\xa2\x44\xd7\xd2\x71\x64\x3e\x57\xc7\x02\xdb\xde\x04\x90\x88\x11\x31\x1f\x7e\xc3\x76\xd7\xd9\x51\xbb\x91\xc4\x86\x90\x26\x49\xad\x9e\xbf\x55\xaa\x58\x50\xa9\xcc\xca\x61\x79\x4e\x20\x29\xa7\x10\xce\xde\x65\x91\x46\xa4\x01\x78\x2a\x98\xe6\x58\xb4\xdb\x31\x17\xf9\xf4\xa1\x55\xc0\x25\x38\x5c\xc2\xba\xc6\x7d\xde\xdb\x85\x8a\x05\x48\x82\xa6\x26\x2f\xda\x1e\x93\xe7\x8f\x89\x28\x88\xbd\xe3\x4b\x03\xeb\x0f\xa8\x73\x59\x9c\x29\xce\x9a\x3f\xf8\x64\x44\x29\xa6\xac\x7b\x65\xeb\xbc\xd6\xd5\xc7\x65\x5e\x2e\xa1\x18\x5a\x50\xb2\x4b\x43\xc2\x24\x5a\xa4\xa2\xc8\x92\xe5\x79\x15\xd9\x66\xd7\xbc\x41\x8d\xfd\xe1\x54\x52\x96\xcd\x20\xea\x69\x9c\x49\xc5\x81\xa6\xe0\xc7\x35\x69\xd8\x56\x79\x71\x77\xdc\xeb\xf6\x73\xf9\xb3\x1b\x8a\x73\x55\x0b\x6f\x03\xa9\x24\xd0\xc6\x95\xc2\x2d\x57\x8f\xe7\xe7\xb7\x4a\x58\x20\xd3\x9e\xb3\xe4\x44\xe0\x7f\xda\x38\x4d\x63\x9f\xac\xb8\x5e\x6e\xd3\x59\x92\x79\xb4\x4b\xcf\x7f\xdc\xf9\x19\x53\x64\x4d\xda\xce\xbc\x45\xdc\xbc\x8d\x14\xcb\x7c\x23\x8e\x81\x23\x8b\xe9\xc5\x89\x85\xe2\x3c\xa5\xb1\xeb\x94\x89\xf7\x07\xc8\x5f\x4f\xf2\xaa\xff\x7f\xfd\xfa\x7b\xea\x88\xf2\x52\x60\xf9\x5c\xcf\x89\x20\x75\x8d\x80\x70\x3e\x76\xa7\x0a\xd9\x3a\xff\xcf\x7f\x60\x5a\xaa\xa2\x3c\xef\x63\x55\x6e\xe1\xb0\xae\x8a\xe2\x96\x7c\x95\xdf\x4e\x81\x51\x4a\x84\xb1\x32\x43\x8d\x9b\xd3\x39\xfa\xed\x74\x16\x29\x10\x96\x89\xda\x91\xc5\x60\x01\xb3\x9c\xa9\x02\x13\xa8\x3e\xf8\xd2\x7d\x22\x4b\x73\xd2\xb9\xc0\xe7\x62\x18\x4a\x8a\xd0\xa7\x27\x9c\xd1\x3a\x72\x44\x95\xd4\x8a\x56\x30\x79\xfc\xcc\x2f\xac\x30\x4a\x41\xcf\x13\xff\x57\x75\xdc\x1e\x25\xce\xb4\x2c\x85\x52\x32\xf6\xfc\x0b\x8e\xa7\x8c\xf9\xc8\xa8\xd2\x41\x60\x46\x9c\xc1\xfd\x4d\x26\x4f\xa9\x13\x5b\x9c\xbc\x6b\xeb\xcf\x65\x0d\x0d\x6e\xf2\xf2\xb5\xc0\xc7\x4a\xcf\x90\x1d\x4a\xa7\x21\xba\x1d\x69\x7d\x94\xef\xf8\x79\x32\xbc\x67\xed\xb3\x8c\x76\xd0\x5d\x8f\x2f\x53\x5a\x84\xf4\x39\x34\x16\xd8\xe2\x9d\x25\x92\x99\x9d\xe5\xc0\x98\x25\x7e\xfc\x81\x75\x33\x24\x5e\x14\x06\x82\x5c\x4f\x8f\x78\x3f\xbf\x68\x20\xb3\x66\x3e\x68\x7d\x0b\xdd\xe6\x33\xff\x8c\x18\xc9\x54\x8c\x70\x93\x16\x4e\x01\xc5\xa2\x28\x16\xf5\xeb\x2f\x22\xc7\x0a\x33\xe3\x79\xb7\x16\x45\xf1\x9c\xbf\xbe\xb5\x77\xd0\xef\x1e\x0a\x31\xa1\x8a\x7c\xeb\x3d\x8f\xd1\x65\xca\x88\xc0\xd8\x05\xbf\x28\x1c\xf1\xd9\xd7\xd4\x27\x3a\x08\x34\xa5\x44\x9f\xb1\xa8\x40\x53\xa4\xe5\x42\x43\x96\xd1\x5a\xb7\xc5\x86\x54\x86\xaf\x7d\x05\xf9\xe9\x5e\xe8\xa3\x74\x3a\xc8\x54\x38\xae\x66\xb8\xad\xea\x49\x28\x48\x07\xbc\x4f\xa5\x56\xe5\x85\x25\x5a\x77\xcb\x9d\xcb\x6b\x50\x0c\xd1\x32\x74\x4d\xba\x4c\x33\x66\x75\xbf\x65\xfb\xa9\xe4\x79\x00\xad\x0e\x63\xeb\x77\x4d\x0a\xbe\x37\xcb\xe5\xcd\xa4\xea\x5b\x87\x3c\x43\x8a\xde\x34\x76\xca\xdf\xd0\x54\x05\xf5\xd6\x1b\x20\x3a\xe4\x00\xdd\xac\xbb\xaa\xab\xf7\xb9\x2f\xa0\xa3\xd4\xb2\x76\xab\x63\xfd\x00\x3e\x21\xa6\xe3\x90\x2b\x18\xe4\x7e\x2c\xf0\x71\x52\x37\xaa\x93\x20\xe5\x2e\x21\x70\x3c\xac\x8b\xaa\x1d\x02\x50\x53\xbb\xdb\xc2\xd0\xc7\x1d\x9d\xa4\x11\xe1\x57\xdc\xab\xef\x0c\x8d\xca\xe9\xb2\xa7\x13\x11\x5a\xd0\x4c\xad\xaa\x12\xc6\xc6\xb0\x4e\x51\x89\x64\x28\x06\x3a\x7e\xfe\xb3\x7a\x68\x9d\x1a\x4e\xf9\xcc\x2b\x6c\x9f\xca\xab\xc1\xf2\xd0\x59\x68\x59\xad\x2d\xbf\x9c\xdf\x56\x67\x0c\xb1\x42\x67\x59\x4c\xa2\xdf\xbd\x37\xb4\x99\x87\x12\xb5\x60\x2c\xb5\x4c\xbf\x05\xb5\xba\x1f\xf1\x66\xfc\xd7\xac\x29\x87\x6c\xa8\x80\xdf\xe5\x25\x6d\xdb\x47\x12\xec\x98\x55\x92\x6b\x08\x0d\xe5\xf1\x6c\x81\xfc\xa4\x33\x20\x92\xb1\xee\x9d\xf8\xab\xaa\xae\xab\x8f\xbc\x7c\x5d\xb5\x33\xb5\x21\xa1\x21\xc9\x88\x9c\xc8\x1a\xb8\xe3\x18\x96\x06\x80\xc4\x31\x03\xdb\x25\x62\x70\x03\x35\x28\x99\x3a\x0c\xfe\xb2\x7d\x1b\x93\xc6\x09\x0d\xc6\x6e\x60\x76\x6f\xfa\x47\x7a\x9f\x42\x4b\x66\xcb\xde\xdc\x22\x7c\x5b\xd5\x8b\x39\x10\x43\x4b\x06\xb1\x71\x91\xcd\xdb\xaa\x1e\xc4\x03\x66\xcd\xa2\x30\x71\xe1\x2e\x8b\xdc\xbb\xaa\x7e\x4e\xec\x34\x2d\x39\x2a\x67\xa3\xb8\x0c\xfb\xc6\x55\x99\xf4\xa2\xf6\xb3\x4f\x28\xb5\xce\x06\xf1\x1c\xab\x91\xd5\x4c\x97\x64\xad\x64\xe0\x56\x6d\xd0\x45\xcf\x48\x2c\xb4\x0e\x32\x42\x2c\xfc\x0e\x75\x31\x51\xeb\xed\x0e\x49\xda\xdd\x0a\x68\x08\xfc\x3b\x0a\x8d\x69\x1d\xe8\x4c\x0f\x1a\x41\x57\x45\x65\x53\xed\xfd\x94\x9a\x23\x7a\xfc\x79\x5c\x12\x7c\x66\xf9\x6d\xc2\x76\xa2\x51\x58\x79\xa5\x06\xdb\x87\xe6\xf5\xfc\x56\xaa\x0d\xb7\xc9\x97\xc7\xbc\xa8\xf6\xd8\xeb\xf2\x09\x6d\xb4\xf6\xd1\x96\x47\xfc\xb8\xa9\xca\x6e\x63\x9b\xdc\x18\x59\xa0\x98\x73\x83\x16\xe7\xd9\xff\x04\x32\x6d\x2b\x8c\x4c\x8d\x78\x5f\xb5\x6d\x45\x39\x75\x77\x30\x0c\x52\x0a\xe6\x9a\xaa\x56\x78\x93\xff\xb0\xf8\xa6\x11\xaa\x18\x43\xa6\xa8\xc5\xcb\xea\x7b\x67\xc9\x4c\xef\x1f\xf2\x94\x52\xe3\x92\x38\xeb\xbb\x05\xbe\x3a\xb6\x03\x51\x8d\x6f\x25\xe3\x8c\xcf\xf8\xa1\x4f\xd8\x6c\xce\x0f\x52\x8c\x02\xc1\x02\xaf\xba\x45\xd4\x9d\x96\xdc\xfa\xa7\xcd\x55\x3f\x56\x43\x14\x15\xa3\x98\x51\x1e\x82\x04\xcb\x17\x5a\x3f\x57\xc5\x89\x96\xe3\xfc\xf2\x60\x69\xcb\x7f\xe4\x75\x7b\x84\x82\xe2\x1b\xcd\xe6\xb8\xdf\xa3\xe3\x49\x9c\x8c\x37\x8c\x53\xcb\xd1\x5e\x1d\xb0\x74\xf2\x81\x36\xdc\x37\x14\x35\x60\xa2\x81\x18\x12\xaf\x3e\xdb\x6a\xff\xad\x2a\x26\x68\x75\x4c\x99\x25\xdc\x05\xad\x6f\x86\x40\x28\x92\x26\xbf\xfd\x7b\xb5\xdf\x1f\xdb\xce\x4f\xea\x3d\xcb\x33\xac\xa7\x02\xd3\xcc\xd0\x94\x7f\xee\x8c\xd1\xfe\x32\x32\xa1\xcd\xea\x8f\xf5\x76\x7a\x57\x13\x99\x99\xce\x4d\x3a\x99\x9f\xc8\x03\x20\x0f\x7c\x97\x7f\x87\xb2\xfd\x73\xbc\xa5\xfb\x16\x4c\x59\x49\x92\xe6\x5f\x95\xb4\x74\x33\xd3\x74\x95\x6f\x17\xa7\x7a\xe2\xfd\x4c\xc6\x3d\xf7\xad\xa4\xf2\xae\x21\xf9\x06\x03\x78\xd9\xb7\x10\xb1\xc5\xf5\x3b\x5b\x0b\xf5\x55\x51\xc9\xdf\xfa\x83\x56\xdb\xc8\x8a\x1b\xfc\x4d\x28\xed\x7f\x81\x7a\x3f\x54\xfd\xa8\x13\xc2\x04\x99\x1b\x39\xb3\x57\x11\x10\x49\xd1\xcb\x61\x7a\xc4\xfd\x2f\x46\xa2\x00\x43\x46\xf6\xb2\x24\xe2\x48\x8d\x93\xcc\x13\x02\x63\x04\xa0\xdf\xc3\xcf\x6b\x38\x4c\xf4\x4a\x05\x02\x06\x89\x73\xa9\x1d\xc5\xca\xf9\xcd\x08\x01\x43\xda\xb7\x96\x55\x43\xac\xe1\xc3\x05\x32\x41\xa1\xda\x42\x8f\x60\x6c\xee\xa0\x0a\x6c\xc6\xf8\x1b\x25\x12\x4d\x5e\xef\x6d\xdc\xe0\x5c\xbf\x2b\xcd\x88\x0c\xc2\xea\xfd\x4f\xf2\xdc\xb3\xf7\xd5\x81\x09\x1c\x15\xaa\xaa\xf2\xf2\x1e\x5f\x3d\xc5\x81\xbf\xaf\x66\xa1\x70\x60\x28\xda\xe6\xe6\xfd\x77\x16\xcb\x31\x5a\x5a\x34\xb7\x60\xdf\x57\xa2\x17\x2e\x06\xa2\x57\x81\x5a\x00\xc1\xfd\x3d\x0a\xf4\xf9\x3a\x0b\xd9\xd7\x06\x30\x6a\x9d\x64\x0e\xd5\x7a\x5d\x1d\x0e\x17\xa4\xc8\xf8\x79\x9f\x00\xb5\x91\xb4\x4c\x7e\x1b\x23\xa1\xa6\x37\xc0\x20\xa6\x39\x72\x5b\x40\xeb\x08\x7b\x96\x3f\xe7\x63\x0b\x59\xc2\x5d\xb9\xfe\xc3\xe7\x17\x31\x04\x34\x4c\x90\x98\xb7\xce\x1b\x5b\x13\xe7\x64\x6a\xfd\xe1\x24\x49\x7a\xbb\xee\xbf\xab\x6a\x7f\xff\xc3\x2b\xf3\x4c\xc3\xa9\xb3\xab\x26\xa9\xf4\x5e\x40\xf3\x4e\x08\x85\xab\xaa\x7a\xdf\xb4\xd0\x8f\x46\x13\x40\x1c\x5a\x96\xfb\x77\x3c\xc1\xa8\x4e\x2e\x67\x18\x53\x94\x24\xec\x96\x8c\xf3\xc9\x20\xdf\x50\x1a\x13\x8f\x78\xd9\xa8\x28\xe3\x2d\x2f\xf4\xcd\xe2\x69\xda\x43\x26\x0c\x52\x36\x84\x7c\xef\xf3\x92\x08\xc4\x67\x83\xf0\xd2\xaf\x37\x5e\x4d\x98\x25\x64\x1e\xf8\xe8\xea\x98\x06\xce\x35\x89\x42\x86\xbe\x18\xdd\x2a\x51\xf5\xde\x75\xf7\xe9\xb9\x6f\x96\x44\x91\x1a\x11\x2c\x6c\x5a\x28\xf0\x5c\x16\xc7\xc4\x41\x46\x61\x0d\x07\x5d\xa6\xd8\xac\x45\x1e\xfb\x99\x34\x86\x19\xcf\xba\x32\x4e\x63\xaa\xd4\xf8\xbe\xf2\x28\x56\x93\x18\x49\xd1\xe4\x5c\x55\xbd\x42\x6b\xff\x95\xd2\xd0\x50\xda\xa3\xa8\x5e\xa9\xfa\xf9\xc7\x30\x38\x4c\x2a\x62\xab\xcf\x13\x4e\x03\x48\x26\xd5\x42\xf5\x64\xa7\xd6\x5b\x70\x4e\xe4\xc9\xe4\x19\x26\xa2\xc9\x12\x4d\x65\x73\x0d\xec\x71\x5d\x55\xc5\xe0\x6b\x99\x4c\x08\xd2\xdf\xde\xb4\x47\x9d\x57\xfd\xbf\x52\x4f\x04\x3b\x47\x41\xce\xbc\xa2\xe8\xf1\xac\xe7\x44\xc2\x89\x82\xc9\xc9\xf6\x4e\x89\x1d\xed\xe7\x88\xa7\xe9\x66\x77\x22\x64\x61\xea\xf0\x91\xe4\xc6\x9d\xa9\xa1\x36\x32\x11\x54\xb5\x2b\x89\xdb\xe0\x17\x23\x5a\x65\x92\x74\x62\xd6\xcb\xe7\xeb\xe5\xe3\x76\x77\xb3\xfa\x63\x75\xb3\x7c\xf6\x6f\xa6\x0c\x52\x21\xab\x4b\x5e\x6f\x3a\x07\xee\x58\xa0\x5b\x57\x7f\x8d\x29\xfd\xda\xf5\xe9\x2e\x4f\x8c\xea\x8b\x97\xeb\xed\xea\xe9\xd1\x22\x9b\xfb\xfa\x05\xa3\x83\x94\xec\xd9\x7f\xd7\xf9\xe1\x50\xf4\xc0\x48\xa3\x93\x80\xec\xd9\x22\x97\xb3\x0f\xae\x79\xe8\x95\xcc\x9f\xf1\x70\x6c\x5d\xbe\xc0\xb6\x99\x76\x13\xaa\x80\x08\xa7\x1e\x16\x7f\xee\x6e\x16\xab\xfb\xbf\x76\xce\xa7\x7d\xba\x7f\xda\x6d\xd6\xcb\xc7\xfe\x31\x4c\x1c\x22\xeb\x63\x85\x77\xb9\xd6\x58\x4e\x28\xeb\x2d\x29\x6b\x1a\x0f\x0a\xfc\x13\xc4\xd8\x9c\x44\xc9\x2f\xb2\xc6\xc4\xc6\xef\x83\x0e\x01\xb1\x78\xc5\xf9\x3a\x6b\x4c\xa6\x83\xd8\xeb\x77\x3b\x61\xf2\x09\x33\xca\x64\xe1\x87\x20\x88\xa5\x0e\xfa\xd8\x8d\xa3\xf0\xfc\xa7\x21\x43\x7f\x0d\x1d\x72\x7b\xcf\x0f\xa8\xf5\x33\x12\xe9\xcf\x45\xe4\xfe\xe4\xab\x42\x10\x18\x93\x3a\x11\xcf\x1c\xca\xeb\xaa\xec\x9e\x3b\x4c\x52\x39\xab\x00\x85\x80\x45\x22\x4c\x26\x51\xbf\x39\xcf\x21\x04\x21\x8b\xc8\xb6\xb9\x45\x7c\x1a\xa3\x7c\xcf\xdf\x3b\x0c\x0d\x2d\xe6\x67\xf8\xe0\x9c\x59\x08\x41\x94\xc8\xd4\xc9\x4b\x8e\xa9\x83\xfd\x51\x19\x93\xa4\x5b\x1f\x6c\xbd\x34\x94\xcf\xf7\x5c\x64\x2c\x0d\xd5\x75\xfd\x79\x68\xab\x6f\x4f\x23\x13\x01\x82\x38\x60\x26\x18\x98\x17\xa7\xdc\x84\xe3\xb1\xd1\x35\x55\x44\x50\xbc\xc5\xbd\xac\x06\xfc\x00\x04\x31\x72\xca\x8e\x60\xe7\xf5\xb6\xb8\x2a\x5f\x1a\x3d\xb2\xae\x20\xc8\x52\xeb\xfd\xba\xd7\xeb\xe6\x6a\x91\x3b\x66\xe3\x13\xb8\xdf\x7f\xcd\xd3\x15\x67\x1f\x46\x24\x8a\xc5\x93\xe0\x65\xf4\x5b\x7f\xc8\x48\x9b\xd8\x2d\xf2\xf2\x7d\xb9\xba\xf9\x6d\x54\x0f\x3c\xeb\x1b\x91\x46\x64\x21\xed\x3f\x27\xcc\x3f\x10\x40\x24\x69\x22\x3c\xe2\x07\xa1\xe4\x4e\xb7\x54\x08\x20\x31\x04\xa6\xbc\xca\xb5\x35\xb7\x2f\x10\xbc\x43\x00\x4a\x91\xb5\xb4\xb8\x79\xf0\x88\x0e\x08\x64\x98\xb2\x6c\xe2\x71\x7b\x1f\x7a\x7a\xb2\x14\x4a\x0e\xec\xa1\x9e\x90\xe7\xab\xf9\x26\x65\x46\xe1\xd6\xfd\xb1\x58\x35\x1b\x30\xe7\x2d\x9c\xae\x1d\x10\xe1\xf3\x6a\x7f\xc0\x7a\xf2\x49\x55\x12\x86\x36\xf2\xd4\xb6\x17\x12\x42\x10\xe8\x20\x45\x35\xc2\x4c\xac\x55\xfb\x93\x05\xfe\x12\x3a\xce\x04\xe5\x09\x8e\x6d\x55\xe7\x0e\x56\xd3\x1f\xcc\x04\xf6\xf9\x57\x07\x02\x18\x7c\x14\x08\x34\xda\x0c\xec\xab\xe5\x87\x5e\x94\x9a\xf6\x95\xe8\x1f\x05\xb0\x20\x30\x8c\x0b\x17\x6f\xbe\x86\xa2\x58\xb7\xf5\xac\x4f\x4d\xa4\x22\x27\x47\x48\xae\xdc\xa6\x33\xe2\xbe\x8c\xa9\x02\x0b\x40\xd2\xd6\x4d\xf3\x08\x8b\x6a\xf9\x7c\x1d\x06\x93\xd5\x1e\x58\x60\x4c\x18\x0d\xa2\x94\x7e\x82\x33\x26\x45\x32\x16\xb2\x25\x63\x61\xf6\xa1\x19\x53\x48\xcb\xe4\x5b\x55\xe8\xb9\x70\x02\xb0\x50\x26\x14\xbf\xda\x0d\x7b\xfa\x44\x37\xe6\xfc\x43\x47\x9d\xf1\xe0\x58\xda\x46\xe2\xb3\xc0\xe2\x88\x59\x81\x74\x68\x2b\xbc\xb7\xf5\x32\xfe\x90\xe4\xe4\xfa\x91\x46\xe4\x50\xbf\x00\x2c\x61\x81\xa5\x3b\x83\x72\x8d\xb5\xa9\xea\x53\x97\xe2\xbc\xaa\x3b\xb0\x14\x04\xb9\xd5\xb8\xcf\x5b\x5f\xf8\xb0\xc1\x93\x48\xfc\x74\x96\xb3\x54\x29\x88\xa7\x3a\x10\xe7\x8c\x06\x60\x59\x98\x0d\x72\x3a\x14\x7b\x38\xb7\xc5\x02\xcb\xe2\x8c\xb9\x18\x9d\x4d\x9b\xde\x56\x03\x60\xb2\xbf\x6d\x86\x6e\x55\x38\x16\x6d\xee\xcd\x95\x6d\xfe\xfa\xd6\x16\x9f\x6b\xa0\xae\x9a\xb2\x4a\x00\xe3\x21\x27\xf6\x6d\x68\xdb\xb9\xff\x07\x8c\x2b\xa0\x95\xd3\xe1\x09\x3a\x2b\x72\xc4\xda\x0f\x4c\xa4\x71\xe8\x0c\xdc\x53\x72\xf5\xe9\x0b\x40\x14\xf9\xbc\xfa\xa3\x43\xa5\x58\xa8\xd2\xac\x19\xd7\xf1\x90\x92\x5a\xa9\x6a\x5c\x7f\x07\x0c\x64\x92\xe1\x98\x8f\xe8\x12\x24\x17\x98\x94\x2a\x8a\x7b\x76\x8f\xb6\x1f\x3f\x12\x33\xaa\x1b\xe9\xfe\xbb\xcd\xeb\xa6\xfd\x8e\xf8\xde\xb3\x67\x02\x53\x59\x80\xd6\xfc\xd7\xb8\x2f\x1d\x6b\x89\x87\xde\x03\x53\xda\x58\xa4\x27\x49\xe6\x5a\x58\xe4\xa4\x6e\xde\xb5\xc3\xc8\xea\x7a\x40\xbd\x77\xfc\x14\xb4\x22\x35\xf7\x73\x94\x2b\x30\x04\x43\xc8\xed\x96\xa0\x0e\x63\x64\x11\x30\x94\x19\x79\xe0\x0f\x79\xd9\x6e\x2b\x6b\xa3\xce\xce\x36\x01\x45\xf2\xa9\x2c\x78\xd8\xd3\xa7\xdd\x6a\x52\x1b\xa6\xb1\x42\x82\x16\xb5\xb3\xf9\x95\xaa\x05\x30\xa3\xe2\xc4\x56\x43\xba\xbc\x51\x5d\xc3\xe7\x93\xb9\xc2\x12\x4d\xae\x72\xa8\x73\x6c\xe6\xda\x44\xa7\x9f\x22\x64\x49\x4a\x56\xcc\x6b\x0d\x65\xaf\x50\x34\x64\x13\x2e\x04\x95\xfd\xc9\x10\x81\x25\xd3\x7d\xac\xea\x3d\x14\x63\x12\x2e\xd7\x24\x64\x22\x75\x59\xc7\x3f\xaa\xa3\x7a\xc3\x7a\xb6\x21\x4d\x5f\x2b\x0c\x23\x4b\x95\xfd\x91\xbb\x94\x87\x5f\xfb\xc3\x30\xe5\x54\xb9\xb9\x28\x24\xd4\xae\xb0\xe2\x8f\xf8\xb7\xf3\x71\x87\x0b\x17\xe7\x96\xd6\xd5\xb1\x86\x0e\x6c\x02\x7e\x10\x87\x51\x6c\x6b\x42\x64\x51\xa9\xf7\x13\x7e\x01\xdf\x08\x14\x81\x29\xd1\x45\x49\x54\x9f\xc9\x86\x30\x96\x9c\xac\xe8\xdc\xa5\xbc\x76\x71\x7f\xc4\xc4\x64\x8f\xc1\x8c\x4a\x19\xc2\x84\xc5\x04\x82\x58\x28\x62\xb0\x19\x6f\x6a\x61\xc2\x39\xa1\x36\x96\xdb\xbb\xa7\x8d\xff\x33\x0d\x62\x62\x65\x97\xb9\xb6\x14\x57\x17\x3a\x33\x0b\x6d\x55\x64\x3b\x62\x32\xbb\xad\x6a\x2a\x5f\x23\xd1\x83\xed\x47\xe5\xaf\x99\x19\x3b\xbb\x4d\x55\x3b\x86\x22\x7f\x84\xa7\xc0\x44\x6f\x25\x6f\x0e\x45\x3e\x0d\x5b\x74\x2d\x50\x8f\x64\x93\x9d\xe5\x31\xdb\x6c\x42\x9e\x09\xd2\xef\xb2\x21\x00\xe2\xd9\xba\x1e\x29\x7f\x9f\x89\x47\x41\xc8\x79\x18\x8e\x72\x1c\xbe\xed\x99\x50\x10\xb5\xcd\x42\xcf\x74\xf5\x4a\x41\xdd\x6e\x20\x5f\x58\xde\x43\xae\x52\x5a\xb6\xdd\xbf\xbb\xb6\xda\xd1\x68\x9f\x3d\xb5\x08\x15\xd9\x99\xbd\x00\xd3\x58\xe7\xd2\xb7\x89\x58\x08\x8e\x6d\xef\x47\x4f\x30\x60\x41\x49\xaf\x25\xea\x07\x6c\x1a\x78\xc5\xdf\xe6\x1c\x32\x10\x76\x26\xa7\xc5\x7e\x40\x5e\x3e\x54\x65\xb7\x70\x36\xd7\x95\xc7\x8d\x00\x55\xce\x7b\xc4\x40\x55\x2b\x5c\x5a\xb0\xd4\xa0\xbf\x3e\x52\x84\x80\x50\x08\x0e\x76\xb7\x3f\x36\x78\x8b\xf8\x87\xa7\xc2\x01\xc2\x32\x38\xb8\xc0\x7d\x05\x65\x63\x55\x29\xae\x3e\xaf\x8b\x7c\xf4\x25\x85\x66\xc1\xf0\xad\x2f\x14\xcf\x42\x08\x69\x68\xd2\x3e\xef\x75\x09\x6c\xd6\x37\x8e\x5d\xa5\xad\xdb\x18\x2e\xc0\x50\x4e\x58\x77\xc7\x86\x71\x08\xda\x22\x0b\x96\x3f\x0f\x79\xf7\xb7\xa5\xd8\x1e\x4a\x76\x21\x94\x31\x37\x24\xe8\xdc\xad\xd5\x4d\xfb\x8c\x6d\xdd\x8f\x6e\x29\xb3\xb0\x5b\x64\x97\x05\x1e\xde\x80\x84\xec\x3e\xf7\x58\xb6\x23\xfb\x34\xd4\x19\x27\x37\xfd\x06\x6f\x2e\xb2\x32\xfb\xa6\xda\x16\x70\xee\x54\xb5\x3f\x1c\x5b\x5c\x1c\xeb\x13\xbd\x11\xd7\x14\x83\x80\x3c\x87\x6e\x97\xe8\x3c\x3f\xcb\x43\x34\xfa\x66\xc8\xa2\xd0\x22\x5d\x3b\x03\x6e\x36\xb2\x30\x34\x81\x23\xb1\xef\xdc\xcb\x95\x2b\x13\xf8\x67\x2e\x6a\x88\x69\x94\xb8\x0c\xc0\x43\x5e\x3e\xa3\x7a\xeb\xba\x66\x7e\x8b\x14\xad\x86\x66\x37\x67\xfb\x25\xaf\xb9\xad\xea\x33\xcb\x39\x6a\xed\x29\x0b\x5c\xb0\xe4\x92\xad\x78\xe1\x91\x4c\x94\xa6\x6a\x4c\xdc\x69\x1d\xb6\xff\x61\x59\xfa\xbf\xe3\x82\x2d\xdf\xdc\xd1\xdb\x6a\xf8\x6c\x86\x9c\xa1\x3f\x28\x75\x2c\x9d\x3e\xae\x4f\x96\x4f\x34\x72\x21\x34\xc8\x98\xed\xdc\xeb\xaa\x21\xee\x97\x9e\xe1\x18\xa2\x20\x16\x81\x33\xdc\xee\x8e\xe5\x18\xf4\x38\x7d\xe8\x28\x48\x52\x36\x16\xb1\xb3\x91\xac\xc4\x5a\xa4\xfe\x77\xd4\x9c\x4b\xa2\xdf\x6a\xbf\xa2\x02\x70\x0c\xa3\x10\x05\xd2\x72\x04\x83\xd6\x8b\xe7\xc5\xb4\xbf\x23\x96\x46\xe4\x32\xfe\xeb\x81\xc2\x36\x5f\x44\x63\x21\x62\x2a\xb1\xfa\x92\xa0\x35\x2d\xf1\x4f\x66\x5b\x1d\xce\x8f\xe0\x28\x0a\x65\x08\x9e\x6c\x9e\xb8\xf7\xce\x1a\xb7\x51\x94\x28\xef\x50\x5a\x85\x66\x28\xa0\xfe\xbc\x3a\x96\xe5\xe7\xc4\xbe\x8d\xa2\x4c\x5b\x45\x10\xaa\xa6\xb0\x1c\x7c\x67\xdd\xec\x28\xe2\x29\x15\xfc\xaa\xea\xc7\x7e\xca\x13\xe8\x1b\x18\x54\xbd\xac\x5d\xef\x42\x44\x49\x18\x20\x73\x59\x34\x68\x61\x55\x3a\xea\x06\x7f\x58\x04\x94\xdf\xd9\xe7\x7b\x6c\x3f\x0f\xc3\xff\x3a\x24\xee\xfc\x1d\x09\x10\x7d\x19\xd6\x88\xd2\x20\x24\xb8\xea\x0d\x7c\x92\x31\xfd\x30\x97\x3c\x84\x28\x15\xa9\x67\x53\x5e\x96\xfa\x50\xe5\x65\xbb\x86\x1a\xf6\xcd\x49\x19\xd7\xf4\x34\x99\x11\xca\x81\x3a\x71\x60\x2a\x86\x28\xd3\x09\x61\xb7\x69\xe6\x8d\xb7\xfe\x28\x43\x20\x8f\x5b\x1e\x3f\x89\xa9\x0d\x86\x4c\xec\x29\xfe\x72\xd2\xc3\x3c\xb3\xaa\x2d\xb2\xb9\x40\x10\xef\xdb\x71\x49\xbb\x8f\xc5\x72\xf8\x68\xc5\x85\xe2\x17\x7f\x8e\x30\x14\xd4\x5d\xd7\xf0\x19\xaf\x6b\xfc\xf4\x44\x3d\xce\xb8\xe4\xde\xb4\x8c\xb8\x8e\x79\xdc\xbb\x15\x1e\xdf\x3e\xbd\x9a\x48\x53\xe3\xb6\x37\xab\xa5\x66\x7d\x8a\xe5\xeb\xeb\x29\x28\xae\x6b\x6d\x49\x06\xe4\xb1\x2e\xd7\x7f\xde\x5b\x5b\x79\xfd\xe7\xfd\xa5\x1c\xd1\xec\xd1\x05\x04\xa9\x1d\x21\xe5\x20\xd5\xbe\x2a\x7b\x31\x79\x88\x84\x62\xd4\xe5\x15\xf1\xe4\x40\xf1\x52\xfb\xfd\x33\x82\x30\x4a\xdd\x93\x3e\xc0\x44\x46\x6e\x3a\x84\x24\x0b\x69\xa7\x79\xae\x64\xd5\x96\xf9\xfb\x69\xed\x09\x44\x2a\x54\x1e\x39\x61\xe3\x86\x4d\x5e\x95\xb7\x88\x0e\xe4\x33\x7d\x6a\x1d\x24\x6a\x24\x61\x8c\x7a\x54\x52\x0f\x91\x8e\x02\x32\x69\x3b\x3b\x74\x04\xe8\x85\x48\xab\x8c\x9c\x3a\x0f\x20\xec\xba\xea\x1e\xf5\xeb\x69\x8c\x7c\xd6\x4b\x1a\x45\x68\x26\x38\x41\xab\x50\xa2\xfa\x75\x13\x53\x49\x29\x3c\x1b\x49\xb6\x94\x6d\xbb\xd5\xf5\xd3\x6e\xb3\x5d\x7c\x5b\xb2\xdd\xfa\x79\x49\x31\xc9\xa4\x3f\x41\xc5\x16\x19\x0f\xef\xb8\xba\x7e\x1a\x3a\xbf\x71\xd5\x85\xfb\x7d\xde\x34\x17\x63\x4f\x11\x9a\x84\xf2\x01\xcb\x46\xc1\x01\x1d\xc2\x7b\xf2\xd4\x31\x0b\x6c\x25\x8c\x7d\x5d\xca\x2e\xfb\xf5\x24\x66\x51\x1a\xe8\xc1\xec\x7f\x32\xa6\xc8\xcb\xbe\x7c\xee\xa4\x3b\xa6\xd7\xd5\x8c\x1e\x7d\x51\xd7\xce\xac\x5d\x35\x8f\x95\x2f\xd3\x9e\x3e\x43\x88\x9c\x9c\x87\x87\xfc\xaa\xaa\x74\x81\x67\xc5\x97\xbf\xde\x1f\xe3\x28\x0b\x69\x8c\x3e\x5f\x5f\x8f\x85\xe9\x20\x8e\x24\xa7\x75\x67\xbb\x5c\x5c\xdf\x4d\x8f\x68\xbb\xdd\x10\x48\xe2\xd8\x9b\x8e\x71\xd2\x8d\x78\x2a\x82\x9a\x51\x26\x42\x9c\x26\x31\x29\xad\xbe\x62\xbb\x28\xf3\x3d\xaa\x39\xc9\x37\xc4\xa9\x0e\x28\xf3\xff\xb0\xd8\xee\x5e\xfa\x62\x0b\x88\xb3\x10\xb0\x8f\x8a\xac\x8c\xfb\x18\x93\xf5\x27\xce\x22\x5b\xfc\xb5\xfc\xf3\xa9\x4f\x71\x5d\x0a\xcd\xfb\x53\x30\xe0\xf6\x61\x5b\x68\xbd\xd9\x16\xf3\x20\xa4\xfa\xc9\x7f\xad\x1e\x37\xfd\x7f\x71\x44\x05\x4c\x96\xb9\xe3\x8e\xb8\xc3\xfa\x63\x29\xd0\xe4\xab\x09\x28\xd5\x57\xd3\x41\xcc\x95\x2d\x24\x6d\xb1\x69\x37\x1f\x70\xd8\x7a\x14\x06\xc4\x82\xf1\x2c\x73\xd8\xa0\x6d\xbe\x9f\x83\x01\x21\x16\x61\x48\xd9\xa1\xbc\xe9\x0c\xa2\x12\xf6\xb8\x85\xae\xfb\xa7\xef\x0c\x0c\x84\xc3\x27\x5a\xd6\xf8\xe9\x45\x80\x49\x2a\x43\xfa\x51\x5d\x26\x42\xf6\x4d\xb9\xb6\x45\x5d\xcf\x4b\x8a\xec\x7f\x5f\xae\x76\xdf\x57\xdb\xbb\x1d\xb1\x8b\xfe\xd6\xb7\x42\x72\x42\x9b\x6e\x52\x79\xb1\xd1\xf3\x7d\xab\x32\x95\xea\xbe\x08\xa3\x75\x1c\x62\xd3\xc7\x57\x60\x52\x97\xd6\xbf\xe9\xac\xf4\xb2\xc1\xb3\x06\x41\xac\x19\x10\x75\xe6\x35\xd4\x96\x59\x79\x52\x8c\x0b\xb1\x56\x29\x15\x83\x2a\x28\x8a\xfb\x5c\x86\xb3\x61\x85\x81\x4e\x92\x91\x44\x9e\xaa\xb4\x55\x33\xdb\xf4\x95\x99\x10\x63\x0c\xb4\x73\x98\xaa\xfe\xd9\xff\x67\x42\xa2\x27\xff\x38\xfc\xdc\x12\xcb\xda\xd8\x64\x88\x0d\x33\x14\x5b\x5e\x5c\xdf\xff\x75\x63\x4d\x25\x7f\x24\xca\x6c\xe9\x46\x55\x6f\x71\x24\x76\x0d\xb1\x31\x8c\x3c\xde\x3f\x8a\xea\x55\x11\xee\xe2\xec\xf7\x48\x82\xc0\x92\xfc\xf5\x26\xeb\x15\xb6\xe7\x75\x0d\x20\x09\x18\xc4\x91\x0f\xa7\xd0\xba\x79\x53\x57\x87\xf3\xe2\xd0\x90\x04\x3a\x63\x63\xf6\xa0\x6e\x9b\xff\x2a\xfe\x3a\x3b\x9d\x45\xda\x52\xbf\x58\xce\xe5\xbc\xcc\xf7\xc7\x29\xee\x10\x12\x96\x08\x52\xd4\xd8\x59\xf1\x93\x7f\x16\xeb\x4e\xc2\x08\xa9\xb0\x7f\x0f\x3f\x7d\x56\x6c\x8c\x79\x87\x24\x44\x4c\x07\xce\x07\xc7\x3d\xd6\xfa\xd0\x58\x12\xf3\x90\x84\x2b\x17\x9a\xb8\xe3\x72\x65\x19\xcd\x27\xef\xc5\xe6\x37\x8d\x75\x44\x56\xf6\x01\x4e\xeb\x31\xff\x59\x87\x24\x49\x4a\x11\xf1\xbb\xaa\xc4\xcf\xcd\x51\xbd\x17\x54\x6c\xdd\x3f\x75\xa2\x62\x82\xfa\x6d\xeb\xe3\xfe\x70\x0b\xf5\xbe\x0f\xa7\x26\x89\x02\xaa\x94\x78\x29\xf3\xce\x27\x1c\x8d\xc6\x24\x31\xe8\x50\xbe\x57\xc7\xb9\x6e\x1e\x24\x19\x93\xcc\x0a\x83\xd5\xf9\x7b\xe7\xbc\x77\xeb\xe2\x00\x84\x83\x84\x47\x52\x8c\xc5\xeb\x9e\xe1\xbd\xbf\x34\x4f\x62\xef\x94\xdf\xd6\x88\x9b\xce\x87\xa9\xb1\xe8\x0f\xcb\x88\x6c\xea\x12\x7f\xb6\x94\x45\xf3\xc2\x7c\x90\x88\x44\x53\xf9\xea\xb7\x3a\xd7\xea\x28\xc7\xb0\x54\x48\x64\x18\x58\xce\x8e\xa3\xfc\x55\xc9\x26\x24\x32\x61\x94\x82\x70\x74\xf7\xb3\x4d\x2d\x91\x29\xa7\xba\x47\x2f\xe8\x34\x72\x5d\x13\x69\x54\x66\x57\xc6\xdb\x63\x49\x51\xad\x11\x0b\xdd\x64\x7d\x49\x94\xab\x5e\xbf\xab\xf6\x78\x55\xe7\xfa\xf5\xc4\x14\x1f\x82\x93\x17\xbe\xae\x0a\x81\x60\x52\xab\xed\xb7\xc9\xd6\x98\xa8\x38\xcd\x12\xa7\x72\xee\x93\xc6\xfe\x50\x9a\x10\x1a\xa4\xa8\xaa\xf7\xe3\xc1\x6b\x46\x5d\x98\xe8\x2a\x13\x21\xf4\x60\xfa\xe9\x80\x57\x3a\x4e\xbc\x16\x34\xc9\x6b\xad\x6e\xae\x3e\x1f\x67\xa2\x04\x90\x68\xc8\x48\x4a\xa7\xdb\x55\xa1\xcd\x7f\x4e\x9e\x13\x53\x41\xd7\x20\x65\xdf\xfe\x4f\x19\x52\x1a\xef\x6a\xb5\xbd\x7e\x5a\x3d\x7e\x5b\x78\xbe\x33\x48\x50\xa7\x04\xa1\x74\x21\xfe\x71\x28\x7b\x1c\xea\x4f\x4c\x1a\x46\xc2\x39\x7e\x97\x92\xd8\x7d\x53\xf0\xe1\xa4\x3f\xa0\xce\xad\x56\xcc\xa7\x9a\x47\xb4\xd2\x20\x13\xc4\x81\xbb\xcf\xcb\xeb\x63\x3b\x36\x2c\xd3\xc0\x09\x3b\xfe\x91\xab\x6a\x54\xcf\x07\x69\xa0\x2c\xf6\xee\xf6\x65\xfb\xf2\xbc\xdc\xdd\x2c\xff\x58\xde\x3f\xad\x1f\x96\x8f\xdb\xdd\xed\x8b\xc7\x19\x40\xca\x00\x99\x25\x43\x51\xef\xe7\x48\x9a\x20\x65\x4e\x71\xdc\x56\x90\x55\xc7\x5a\xe1\x06\xc7\x75\xff\x90\x86\x59\x44\xe9\xeb\x5c\x55\xcb\x52\x0f\x70\x5e\x48\x43\x99\x19\xd2\xd6\x55\xd5\xb4\x4a\x0f\xd2\x28\xb4\x64\xc6\x56\x6b\xd0\xd6\x3c\x9e\x30\x2e\x42\x1a\x71\x41\x1e\xce\x6a\x42\x90\xf9\xe4\x40\x78\xa0\xda\x9b\x9e\xf6\x03\xd2\x58\xe8\x14\x7a\x1a\xb9\xdb\xfc\x67\xef\xaf\xa6\x31\xa6\x91\x55\x73\xdc\x1f\x8a\xc9\x04\x4d\x63\x63\x4b\x86\x1c\x17\xf1\x4d\x8f\xdf\x76\xc7\xd3\x28\xa5\xf8\x92\x39\x40\xed\xac\xfe\xdf\x46\x74\xa8\x90\xa6\x29\x12\x02\x64\x67\xc8\xfc\x39\x9e\x94\x63\x41\x9a\xa2\xb6\xbc\x5a\xf9\x0f\x7c\xc0\xc1\x16\x4a\xb3\xcc\x48\xe1\x5d\xfa\x6e\x8c\xdf\x56\x56\x22\x79\xd6\x0f\x3c\xb1\x45\x00\xbf\x3f\xfd\xfe\x34\x8a\x93\xa5\x3c\x4d\xa8\x6a\x61\x9d\x4b\x39\x7b\x2f\xe1\xe2\x62\x76\x47\xba\xae\xa1\x27\x69\x1c\x56\x8d\x54\x20\x23\xf7\xbe\x2a\x8b\xcf\x51\x6d\xf3\x35\x94\x37\x55\x7f\x21\xcc\x6c\xde\xe5\x1c\xae\x27\xf6\xbd\x00\x49\x44\xb2\xb3\xae\x6c\xec\x70\x70\x0c\xca\xcd\x49\x88\x36\x95\x2c\xc9\xc0\xbb\xd9\xdd\x71\x17\x88\x9b\x8e\xbc\xce\x67\x22\xac\xd7\x82\xa4\x65\x97\x7f\xae\x17\x8f\x37\xbb\xd5\xe3\x76\xf9\xfc\xc7\xe2\xfe\xb7\xbe\x55\x46\x99\x88\xf7\xbf\xdf\xd4\xa8\x5f\x94\x12\xd4\x5f\xff\x7e\x7e\xc6\x3e\xee\x9a\xea\x38\xa3\x14\xeb\xb1\xd1\x96\xb9\xe5\x61\x38\x43\xa7\x8a\x08\x02\x2c\x2c\x06\x64\x81\x33\x3b\x6e\xfa\x0e\x5a\xc7\x7c\x84\xdd\xd7\xb7\xb3\xba\x8d\xae\x05\xf7\x35\x61\xd3\x10\x7d\xaa\xb5\x85\x74\x91\x72\x9e\xa9\x16\xb3\x13\x31\xe2\x3e\x05\xb8\xa9\x0a\xbd\xa8\x11\x9a\xc9\x84\xc3\x08\x69\xed\x52\x55\x5d\xa3\x6a\x77\x16\x38\xb0\xef\xa5\x16\xc2\x24\xfd\x9f\x48\xfc\xaf\x6f\x6d\xac\x70\x35\x68\x4d\x09\x25\x28\x9c\x38\x94\xbf\x9c\x89\x04\xea\x1e\xbd\xb3\x28\x8a\x35\xd4\x23\x74\x47\x16\x84\xd6\x36\xdb\x7e\xbf\xd9\x3d\xed\xcb\x5c\x57\x45\xe1\xe5\x61\x20\x0b\x32\x4d\xb9\x4d\x2f\x7a\xb5\xf3\x7b\xeb\x39\x50\x2b\x64\x81\x90\xac\x4f\x83\xf8\xaa\x7c\x7f\x4c\x33\x4a\x29\xfa\xe0\xf4\xaa\xcc\x67\xce\x52\xc6\x98\xc5\x0d\x74\xa6\x7b\x67\x7a\x8e\xc6\x72\xc6\xe2\x20\xb3\x4a\x9d\xf9\xeb\x2b\xd6\xdd\xf6\xe7\xaf\xcc\x30\x23\xe8\xdf\xe3\xe2\xdb\xa2\x5b\xd9\xfd\xff\x61\x6c\x7c\xb2\xa0\xb3\xc3\x17\x45\xb1\x28\xf5\xd5\xb1\x9e\x05\x09\xb2\x50\x04\xc4\xfb\xbb\xba\xf9\x73\x3c\xc7\xb2\x50\x84\x7a\x44\xb7\x35\xf1\x31\xcf\x8e\x9b\x2c\x62\x1c\xd4\x48\x5c\x86\x48\x8e\xfd\xb2\x39\x6b\xaa\x65\x32\xa0\x8a\x7d\x05\x73\x37\x62\xea\xfd\x99\xe4\x65\x16\xb3\x88\x2a\xa7\x49\x4b\x77\x22\x84\x36\xde\x16\xb3\x38\x11\x19\x23\xb9\x9f\x4a\xbd\xff\x3e\xd8\xe0\x59\x9c\x00\x05\x9f\x4d\x51\x7d\x60\x4d\x2c\xab\x17\x54\xd7\x20\x8b\x79\x14\xb9\x54\x62\xe7\x88\x39\x4a\x94\x55\xb9\xed\xa5\xdd\x66\x2f\x93\x64\x89\x85\xdd\x7b\x81\xa9\x13\xbd\x84\xd9\x1d\x12\x08\xa9\xa3\xdc\xbf\x24\x43\xa8\xf7\x79\xd9\xe3\x3e\xfd\x63\x27\x4a\x66\x03\x27\x33\xed\x82\x4e\x53\x22\x9c\x75\x50\x1a\xc7\x04\xa8\xb6\x15\x0c\xf7\xcf\xeb\xf3\x73\x3b\x4b\xc1\x0a\x7a\x59\xaf\x96\x48\x2e\x0e\x05\xf6\x99\xb4\xc1\x46\xea\x06\x9f\x0f\xb1\x65\xa9\x31\x54\x91\xe9\x11\xd3\xed\x1b\x55\xce\xb9\xa4\xa0\x6b\x94\xc5\x8a\x70\xa3\x6d\xd5\xce\xe9\x23\x21\xcb\x52\x5b\x0b\xd1\x60\xfb\xfb\x5f\xd7\x33\xe2\xdc\xfe\x3e\x19\x67\x96\x9e\xac\x6a\xac\xb6\xfa\x2c\x69\x37\xb1\xf5\xb2\x4c\xc6\x94\x16\xbe\x5d\x2e\x77\x0f\x2f\xf7\xfd\xad\x4c\x48\x35\x12\xfb\xbc\x7c\x80\x9f\x57\xc7\xcf\x61\x4f\xca\x78\x90\x92\x9d\x56\x5a\x4c\xec\x04\x3b\x92\x71\x16\x11\x62\xc3\xa5\x5b\x49\x33\x6a\x8d\xd0\xc7\xe6\x32\xce\x4c\xe6\x88\x56\x7e\xff\xeb\xda\x0d\xf0\x35\x7c\x16\x15\xe8\xf1\xbe\x9a\xf1\x90\x07\xa1\x9f\x3b\x55\x3d\xcf\x8f\xbb\x56\x22\x34\xb4\xbe\xcb\xe3\xe7\xe2\x77\xa4\xe0\xeb\x34\x32\x77\x61\x9e\x89\x44\x53\xc8\xc4\x42\x52\x77\x70\xd2\xd9\xc2\x58\x6c\xd4\x16\xde\x71\x5d\x7b\x36\xb5\xe1\x02\x90\x04\x84\xaa\x5b\x95\x6d\x5d\xfd\xf6\x2b\x56\x44\xc8\x80\x07\xd4\x31\xa4\xe6\x71\x31\x27\xf4\x2b\x1f\xea\xb4\x9e\x03\x32\x19\x30\xca\xa5\xea\xaa\x6c\x37\x58\x14\xcf\x27\x81\xf0\x4c\x86\x4a\x10\xac\xf3\x50\xe4\x13\x56\x4a\xc8\xa4\xd3\x1c\xaa\xb1\x39\xee\x71\x56\x1a\x04\x99\x0a\x63\x2a\xd9\x39\x74\x73\xfe\x0c\xaf\x0d\x64\x0a\x18\x73\x31\xc8\x07\xdc\xe3\x58\xce\xbf\x6f\x01\xe4\x94\xdd\x3e\xbd\x3c\xde\x2c\x08\x56\xfb\x7d\x71\x7f\xbf\xf4\x71\xaa\x0c\x03\xa5\x86\x65\x92\x96\xfe\xaf\x7a\xf4\x6c\xfa\x39\xc3\x24\x20\xd4\x7a\x9b\xef\xd1\x82\xc9\xa7\x23\x05\x53\x5b\x5f\x4f\xd0\xd6\x1f\x08\x85\xb3\x2a\x66\x57\x31\x01\xcd\x9e\xd5\xcd\x72\xe1\x1f\xcf\x84\x29\x95\xc6\x7d\x23\x5f\xc3\x06\x5a\xd5\xe7\xea\xc6\xef\x80\x3c\x60\x96\xd7\x1e\xad\x8c\xfd\x17\x76\x01\x0f\x62\x1e\x25\x9e\x53\xce\x4a\x7c\x2f\x4b\x4d\x6b\xed\xc4\xd3\xf1\x29\x27\x1e\x24\x36\x10\x7e\x6e\x0b\x99\x5d\x9a\xdb\xaa\xcd\xce\x2e\x78\xcf\x8b\xe2\xfa\x84\xa1\x1a\x78\x20\xac\xe6\x7e\xde\xb8\x1c\xa7\x7f\x05\x16\x8a\x98\x79\x9b\xc3\xea\xdd\xfe\x07\x6f\xb0\x21\xae\x23\xd4\x9e\xa8\xc6\x85\x72\xc6\x4e\x06\x67\x29\x92\x42\xb4\xad\x4e\xfd\x3e\x0e\xf2\xf1\x90\x09\x0c\x27\x70\xda\xd3\x57\x3d\x7d\x93\x30\x33\x62\x6c\xf5\xba\x45\x9b\x38\x72\x7c\x13\xa3\xa9\xea\xcd\xd9\x57\x0b\x7d\x22\x28\x3b\x4a\x46\xf0\x28\xd1\x69\x36\xde\x55\x2d\x22\xea\x8c\x72\x00\xf0\x48\x69\x82\xf5\x3f\xd4\xcf\x08\x87\x09\xbd\x0c\xf0\x38\x91\x04\x6a\x5c\xdc\xac\xc1\x47\x50\x78\x92\x26\x64\x74\x7c\x5b\x5c\x6f\x87\xff\x8c\x2b\x7c\x94\x43\x9a\x66\x8c\xe9\x71\x5f\x79\xc8\xc4\x0c\x42\x45\x33\xc9\x22\xe0\x09\x67\x54\xbe\x48\x65\xb7\x75\xcf\xcb\xde\x1f\xcd\x8c\x15\xbd\x38\xc3\x2b\x3f\xfd\xfc\x09\x58\x20\x12\xd1\x48\x47\x7c\xf6\xe6\x89\xcc\xb4\xa7\x4d\x02\xf5\xee\x77\xa8\xd9\x10\x4a\x43\xcb\xb5\x57\x56\xed\x3d\x36\xcd\xf6\xad\xf7\x8f\x79\x8a\x48\x75\xea\x16\xcc\xea\xca\x66\x66\x37\xc9\x62\x43\x79\x21\x57\xe6\xee\x21\xcd\x93\x5d\x89\x67\xc0\x6d\x02\xe7\x2d\x37\xa7\x92\x47\xa3\x0f\xcb\x43\x4d\x51\x39\xfa\x48\x77\x84\x9b\xdc\x94\x70\x68\xde\x28\x4f\x7a\xa1\x17\x78\x66\xc5\x80\x64\xae\x77\x2d\x71\xb3\xf6\xc2\x97\xc0\x85\x66\x14\xc6\xee\xfc\x49\xf5\x56\xd5\xe7\x13\x03\xe7\x2f\x2c\x74\x6a\xf4\xb4\x30\xfe\x5b\x37\x84\x5f\x49\xaf\x64\xd6\x8f\xc0\x25\xb3\x3b\x50\x79\x6c\xee\x87\x25\x97\x03\x47\x8a\x7f\x1f\xcb\xbc\x25\xa1\xae\xfe\x80\xcc\x22\xd5\xd7\xd4\xe9\xa3\xb2\x81\xa6\x75\x9f\x9a\x1f\x7a\x19\x34\x52\x9e\x81\x52\x98\xd7\x70\x00\x35\x44\xfc\xb8\x66\x8a\xac\xd5\x3d\xfc\x7c\x80\xe6\xbd\xff\x3b\x93\xc4\x11\x47\xa6\xae\x93\x84\x9a\xe8\xef\x02\xd7\x68\x41\x72\x37\x35\x94\x0f\xfd\xbf\x18\x26\xb4\x03\xb8\x3d\xff\x71\x9c\xd9\xe0\x18\x59\xfe\xb5\x27\xcf\x95\x44\xa6\x5a\x7f\x54\x0a\x8a\x14\x43\x7d\x98\xcc\x33\x54\x9c\x96\xe1\x9e\x79\xab\x40\xfd\xda\x07\x07\xb9\x89\x52\x0a\x29\x78\x79\x89\xdd\xf5\xd3\xc3\x7a\xf1\xf8\xd7\xee\xdb\xf3\xd3\xcb\xba\x6f\x95\x02\xf0\x81\x04\xe6\xf6\xe9\x79\xf7\xb4\x5e\x3e\xd3\x0e\xb4\xe9\x1b\x81\x11\x76\x41\x56\x55\xa9\xa1\xfe\xfc\x06\xcd\x38\x62\xc3\x8d\xb6\x62\x3a\xb7\x05\xbc\xce\x2b\x88\x6c\x13\x11\xc4\x11\xc6\x8e\x9f\x61\xbc\x34\x8a\x20\x4e\xa9\x96\x45\xe7\xe4\x31\x7e\xb3\x18\xca\xc1\xca\x10\x41\x62\x19\x35\x5d\xa1\xc7\x5f\x0f\x57\x5e\xb1\xb7\x3b\xa6\x7c\x32\x91\x2c\xdb\x5e\x0c\x08\x44\x90\x71\x52\xf0\x7b\xfa\xfe\xb8\x7c\xde\xf4\xff\x8a\x90\x6c\x21\xb2\x48\x2f\xb8\xd8\x67\xf5\x36\x41\xb0\x90\xa9\xcc\x0b\xeb\xe0\x71\xbf\xb5\xb6\x5d\xb3\xfb\x6d\xd6\x0e\x24\x21\x59\x75\xb5\xc8\x6b\xaa\x8f\x1d\xac\xdd\xd9\x34\xfd\x9f\xff\x9d\xdd\x23\x0c\xad\x3a\x46\xaf\xda\x33\xc8\xaa\xcd\x1a\x46\x69\xe8\xc7\x39\xe4\x7a\x7e\x34\xe3\xc4\xd2\x51\x1d\x7c\x29\x93\x65\x5c\xef\xa5\xc4\x40\x84\x52\x12\x10\xe2\x69\xfd\xbc\xb8\x1b\xfe\x34\xc6\xa1\x28\x96\xd6\xd3\x5d\x77\xb6\x69\x1f\x54\xe2\xb3\xc7\x8d\x64\x42\xd3\x90\x24\x9d\xec\x96\xe1\x2f\x15\x47\x92\xd0\x0d\xf7\xab\xe7\xc5\x9f\x5f\xea\x92\xb8\x13\x92\x50\x86\xa3\xac\xe6\x74\xb5\xeb\x8e\x7a\x9e\x59\xef\x5a\x7f\xb9\x3f\x8a\x2c\x08\xe2\x01\x9d\xf7\x8b\xc2\x3c\x77\x0e\x47\x6b\x4e\x37\x14\x6e\x20\x1f\xb1\x54\x8e\x1d\x7f\xda\x12\x78\x6a\x09\xe5\xe8\xea\x4e\x93\x6e\xb6\x25\x09\x19\x8b\x5e\x93\xf9\x1c\x79\x1e\x08\x99\x0a\x8a\xf4\x52\x55\xd8\x23\x94\xe3\xfa\x02\x21\x53\x4d\xee\xde\x01\x9a\xf6\x36\xff\x81\x0f\x79\x79\x6c\xfb\xf9\x2d\x24\x04\x22\xb4\x46\x69\xfe\x1f\x24\x30\x64\xdd\x10\x6a\x76\xf6\xac\x3a\x88\xa9\x7c\xc5\xce\x9f\xf5\xf3\xea\x8f\xc5\xd6\x26\xb4\x77\xd7\x0b\xbf\x10\x08\x14\x99\xb1\x0b\x5e\xb7\x32\xe9\x1d\x21\x46\x77\xe5\x88\xd3\x0d\x04\x6a\x5b\x22\xe4\xb9\x16\x69\xe5\xbd\x60\x23\x08\x13\x18\x2f\x88\x44\x03\xa8\x73\x3b\x7c\xc0\x7a\xde\x9d\x86\x01\x79\x1a\x40\x74\x65\x0e\xcb\x36\xeb\x2b\x03\x92\x32\x04\x13\x45\xcc\xd3\x6f\x68\xa4\x20\x2e\xf3\xce\x76\x73\xe0\xc2\x53\xb3\xe7\xe4\x14\x7a\xd2\x63\x83\xf5\x54\xcb\x07\x20\x88\x43\x8f\xef\x5a\x14\x05\x19\x66\xcd\x39\xdd\x55\x80\x20\x49\x29\x54\x4e\x34\x59\xcd\xce\x15\x28\xec\x46\x42\xf3\x00\x41\x16\xd1\xbc\xcc\x55\x65\xe1\x21\xfd\x01\x6d\xb5\x43\x0f\xf6\xd5\x37\xd8\xb6\xa4\x6f\x39\x9e\x21\xc0\xd0\x0a\x2f\xf6\x89\xbb\x85\x31\xdb\x59\x42\x12\x42\x69\x59\x23\xb6\xfc\xfa\x32\xbb\x1a\x40\x68\x32\x88\x7b\xd2\x52\x5b\x62\xfb\x79\x2a\x38\x0f\x10\xb1\x2c\xb3\x4b\x42\x61\x76\x4d\x3b\x40\x39\x21\xca\x80\xcc\xe1\xe6\x28\x1b\x8a\x23\x7f\x99\x97\x81\x58\x58\xf9\x8c\x75\xfe\x33\x3f\xfa\x6b\xc4\x2a\x48\x5c\xe5\x5f\x6e\xaa\x4a\xdf\xe0\x8f\xb3\x69\x5a\x48\x22\xe6\x33\x4b\xf6\xdd\xc7\x6e\xbb\x6f\x13\x5b\x2f\xeb\x6f\xd0\xf8\x8c\xea\xfc\x00\xa1\x34\x04\x1b\x61\xa2\x66\xef\x9b\x1a\x41\xdb\x66\x31\x51\xe8\x03\xc8\x18\x86\xb1\x4b\x3a\x9f\x95\xf5\x00\xe0\x49\x28\xa3\x3e\x8a\x72\x4f\x69\xe7\x4b\x06\x16\x70\x89\x54\x94\xec\xd0\xc3\x58\x5f\x80\x8c\xf8\xba\xd2\xe9\xd9\x22\x4e\x89\xeb\xdb\xc2\x43\x1e\x3e\xbf\x57\xf5\x7b\x73\x91\x32\xe5\x4b\x04\x14\x40\x14\x70\xf4\x64\x80\x9d\x13\x7f\x29\x59\x39\x7d\x04\x88\x85\xb1\x3a\xbb\x9e\x68\xf5\xdf\x47\xe8\xfc\x1f\x5f\x64\x06\x20\x34\x6d\x01\x8b\x22\x57\x93\xbe\x94\x2c\x4a\xc6\xaa\xf4\x3d\xb0\x78\x8a\x39\x9b\x3c\xef\xf9\x92\x77\x00\x19\x86\x04\x68\xb1\x20\x70\x97\x2d\xba\x10\x35\x07\xc9\x03\xb2\xde\x87\x7d\xb1\x7f\x24\x19\x53\x27\x4c\x14\x2c\xf2\xaa\xbc\x86\x43\xdf\xc4\x18\xc7\x09\x41\x86\xca\x06\x8a\x33\x85\x9f\x00\x2a\x15\x96\xbd\xb3\xaa\x8a\x2b\xca\x7e\xfb\x03\x1c\xb4\x9b\x72\x54\x0c\xb2\x28\xf5\x86\x0c\x2a\xaa\x1c\x77\x8d\x74\x28\x42\x07\x48\x75\xd6\x60\xf9\xfa\x64\xcc\x89\x64\x3e\x80\x06\x83\xbc\x97\x85\x5f\xe8\x1f\x58\xb7\x79\x73\xa1\x64\x18\x00\x3b\x17\x9d\x80\x3f\xaa\x3d\xd6\x7d\x99\x0b\x20\xe7\x23\xe8\x73\xf7\x29\x46\x16\xd8\x59\x50\x00\x20\x32\x0a\xeb\xdc\xd4\xf0\x31\xac\x94\x68\xac\xf8\x62\x93\xff\x6c\xdf\xfa\x08\xf6\x4c\x64\xb7\x6b\x06\xe4\x1d\x2a\x82\x4b\x39\xe6\xd1\x11\x80\x10\x0c\x4b\x79\xe2\x76\x4d\x07\xd8\xb6\xc1\xc6\x6e\x03\xb1\x7b\xff\x06\xf6\x54\x6e\xdf\xa7\x8f\xc1\x48\x93\xb9\x38\xaf\xf5\x23\xfc\xff\x28\x28\x1c\xbe\x77\x5e\xb2\xfb\x5f\x06\x61\x12\x3a\x37\xce\xd2\x32\x74\xab\xce\x1a\x3e\x66\xd9\x62\x19\xf0\x48\x90\x11\x49\x15\x24\x37\xb2\x3f\x5f\x5a\x99\xca\xce\xfb\x26\x9e\xa7\x9e\x4b\x63\x74\xae\x34\xd1\x69\xec\x79\x12\x6e\x9c\x9e\xc0\xa2\x80\x28\x22\x7f\x54\x2d\x36\x8f\xde\x92\x92\x4c\x00\x15\x22\x7d\xab\xa0\x78\x80\x9f\xf9\xfe\xb8\xf7\xa4\x5c\x5f\x02\x6f\x64\xc8\x32\x52\x45\x69\x8e\xf2\xa9\x7c\xa2\xd4\xd5\xeb\x2f\xc0\x3a\x32\x0c\x13\xb2\x2a\xec\xc2\x62\xe9\xe9\x89\x1f\x98\x54\xbc\x4f\x95\x55\x4f\x74\x64\x41\x86\x31\x52\xd2\x49\x55\xfb\x7d\xde\xfe\x31\x06\x08\x7d\xc5\x68\x07\x32\x4c\x79\xc4\x3c\x01\x53\x3b\x32\x26\x65\xc8\x95\x27\x41\xd8\xd6\x78\x92\x6a\xf7\xad\x44\x60\x54\xff\xec\x7f\xe7\xe5\xeb\x7f\xde\xf2\x39\x60\x74\xfa\xba\x51\x0c\x82\x79\x7f\x6e\x59\x62\xfd\xea\x3d\xc0\xff\x8f\xb6\x37\xeb\x4e\x1d\xc9\xd2\x40\xff\x4e\x3e\xf4\x83\x86\xd0\xf4\x08\x18\xdb\x54\xda\x86\x02\x7c\x4e\x56\xd7\xea\xc5\x8a\x61\x07\xa8\x2d\x24\x4a\x83\x7d\xc8\x5f\x7f\x97\x76\x0c\x1a\x10\xce\xec\x7b\xd7\x7d\x39\xce\x24\x42\x73\x0c\x7b\xf8\xf6\xf7\x31\x12\x46\x98\xd7\x98\xb7\xc6\x86\x1a\x81\x38\xe5\x3f\x8f\x83\x24\xeb\xfd\x34\xbf\x8e\x5e\x8c\x6e\x92\x08\x07\x29\x31\xce\xf4\xd7\xbe\x57\xd8\x69\x5a\x81\xa1\x01\x3e\x13\x62\x8a\x8d\x44\xf7\x0a\x69\xe0\x28\xcb\xf0\x5a\x34\xf5\x3c\x3d\x0e\x04\x9c\x4c\x27\xe9\xa3\xd9\x37\xaf\x81\x9e\xfb\x10\x1f\xdb\x1e\x23\xaf\x53\x09\x79\xd1\xe4\x1c\xac\xd2\xaa\x6e\x8f\xdc\x08\x3f\x63\x6b\xf2\x34\x17\x45\x43\x2c\xba\x79\xca\x22\x4f\xd1\x27\xd0\xaa\x82\x7a\x25\xd6\x72\x10\x05\x30\x9d\x42\x1f\xe7\x89\xca\x6b\x23\x78\xa5\xa6\xe7\x0b\x8e\x44\xdf\x9e\x29\x51\xac\xa5\xf4\x01\xb3\x67\xa6\xba\x64\xf4\xe1\xfa\xa6\x10\x8b\x84\x8b\xd5\xf5\x07\x4d\x14\x08\x9f\x69\xbb\x79\xae\x2e\xb2\x7a\xa6\xd5\x09\x46\xee\x03\x8b\x05\x20\x9a\xed\x44\xab\xd3\xa1\x4c\x2f\x70\x16\x6e\xe8\x4c\xa6\xd7\x58\x2c\xb9\x27\x2c\xfc\x02\xaa\x8d\x8e\x6f\xed\x4a\x7e\x67\xe2\x26\x8e\x40\x3c\x27\xda\xc5\xad\x7d\x6b\x19\x9b\x29\xb2\x54\xb6\xdf\xfb\x79\xdb\xb3\xed\x19\xa5\x8a\xec\xf2\x92\xf2\xa2\xea\xf6\x18\x46\xb9\xa2\x67\xc4\xb2\x52\x9e\x5e\x68\x0d\x87\x34\x3f\xd0\x92\xa5\x75\x75\xb8\xa8\x4c\xc0\x41\xa6\xf4\x4e\xec\x94\x89\x48\xa2\x0e\x9f\x59\x7f\x1f\xa8\x9d\x44\x82\x81\xe2\xd0\x2a\x4a\x0e\xeb\x4f\xd4\x06\x38\xda\xcf\x29\xa4\x8b\xd5\xc6\x07\xad\x17\x3d\x2d\x21\xf9\xad\xff\xc4\x80\x48\xc3\xee\xb6\xca\x55\x58\x66\xd4\x21\xa0\x66\xd9\x5d\xd0\x5c\xa4\x56\x99\xda\x7e\x28\xd9\x6e\x11\x6a\x68\xbf\xd2\x5f\x33\x5d\x5b\xd6\x5b\xd2\x99\xa4\x8a\xa3\x4e\x14\x39\x1d\x71\xcf\xb5\x8d\xd2\x35\xe5\x45\x25\x74\xc4\x30\x5d\x20\x82\x49\x26\x10\x53\x79\x4e\xf3\x7a\x51\x9c\xcf\x4d\x9e\xd6\xd7\x61\x3a\x97\x3b\x6e\x48\x35\x6b\xd9\x9c\xf2\x8f\x9e\x88\x85\xe9\xe0\x05\x94\xd9\x5d\xb3\x57\x20\x85\x74\x5d\xc3\x6c\x92\x39\x24\x8e\xfc\x64\x80\x43\x7e\x68\x3e\x86\x70\x1b\xee\xba\x8e\xf1\x0f\x94\xe6\xc1\xae\x37\x94\xb8\xeb\x85\xc8\x92\xa0\xe0\xed\x37\x30\x55\xee\x26\x11\xc6\xe0\x57\x9b\xd7\x5e\x82\x96\xbb\x34\xc1\xe8\xcd\x73\x3a\xdf\x0f\x80\x46\xdc\x15\xcc\xe8\x34\x2d\xeb\x93\x8e\x67\x28\x5a\x40\xf4\x08\x50\x4c\xbd\x87\xc5\x70\xbd\xd8\xfc\xd5\x67\xf0\x1c\x40\x9b\x46\x59\xb1\x3a\x2a\x8e\x4c\xf9\x83\x0f\xcf\x3d\xaa\x38\x33\xd4\xe0\xc2\x02\x03\xa8\xa1\x1c\x4d\x53\xee\x3b\x21\x53\x6c\x01\xfd\x4a\x26\xee\x87\x04\x83\xc7\x1b\x9a\xd1\xcf\x92\x0e\x9a\x12\x82\x7e\x8c\x68\x94\xc9\x32\x87\xfa\x0b\x40\x6b\x80\xb4\x3e\xa0\xfd\xa6\x24\x56\xb2\x31\x16\x26\x32\x11\xfb\xe7\x84\x06\x2a\x12\xf7\x63\xf6\x62\x8c\x93\xc1\x2b\x0b\x1c\x81\x6e\x72\x6d\xd1\x36\x28\xb5\x62\xa6\x11\x0f\x63\xa6\x68\xe2\xa6\x3c\xd9\xe1\x74\x69\x0d\x45\x8c\xb8\xef\xea\x82\x7f\xbc\x98\xdc\xda\x60\x40\x84\xd2\xd5\x42\x52\x36\x2c\xff\xf0\xf4\xdf\x03\x28\x17\xf2\x14\x87\x6a\x47\x79\xdf\x3d\xd8\x5f\x65\x8c\x75\x7e\xb6\xc6\x6f\xc4\xee\xa3\xbb\xc5\x01\x20\x0d\x65\x5a\xfd\xa0\x59\x2a\xde\x6e\xcc\x18\x1e\x47\xae\xab\x2b\x36\xfb\x7c\x8d\x94\x27\x4c\x3a\x3a\x44\xfc\x7d\x2c\x86\x53\x4f\x45\xc4\x90\xdf\xfa\x13\xaa\xfa\xd7\x26\xa3\x75\xbf\x36\xde\x74\x14\xd4\x4a\x0e\x66\xd9\xac\xdd\x59\xec\x63\x72\xcf\x41\xdd\xa3\x8f\x34\xcb\x5e\xa1\x3a\x6d\x8a\x76\x74\xde\xc9\x09\x4e\xb0\xcd\x51\xce\xa5\x87\x84\xbd\x98\xe1\x1b\x80\x9a\x47\x1d\x85\x4b\x55\xbc\x33\xbb\x55\x92\xfb\x26\xbd\xc6\x85\xa7\xa4\x84\x8d\x2d\x0d\xf0\xe7\xd8\x6c\xe7\x22\x02\xf4\x9a\xad\xc0\x79\xbb\x67\xec\x8b\x3d\xd8\xe0\x36\x07\x29\x0c\xa8\x6d\x91\xd6\xd7\x5d\x56\x1c\xe9\x58\x13\x5b\x77\x95\x7e\x82\x88\x9b\x5d\x0d\x34\xab\x4f\x4f\x65\x2a\x26\x15\xb4\x87\x07\xc5\x01\xba\x5f\x97\x8c\x5e\x5f\xa1\x67\x8e\x4e\x0e\x53\xe1\x78\x2a\x77\xfa\x3a\xfb\xe3\xb0\xd9\x2e\xb1\x30\xa2\x27\x3c\x47\x85\x43\x09\x24\x26\x0a\xf8\x56\xd4\x1d\x83\x82\x70\x5d\x96\x18\x98\x61\xda\xba\x15\xb6\x34\x59\xb8\x5e\x82\xd6\xee\xfa\x0b\xcb\xdb\xfb\xb3\x4c\xb8\x8c\xe3\xd0\xaa\xda\xc7\xd2\x48\xb1\xc9\x6f\x2a\x3c\x9a\xc8\xb8\x0f\xac\x1a\xfb\xba\xe3\xee\xa0\xea\x6f\x55\x7c\x15\xb5\x6c\xe6\x98\xde\xee\xb3\x39\x75\xcf\xee\x7b\x11\x32\x40\xe8\x02\xdc\x1d\x3f\xc1\xd9\x3e\x9c\x1f\x38\x68\x54\x2c\x7f\xf1\x12\x6a\x8c\x08\xf7\x9e\xc1\x8f\x13\x45\x86\x6b\xd8\x82\x5b\xc3\x64\x5b\xb9\xdb\xca\xbb\x2d\x9c\x15\x3e\xc4\x98\x52\x79\x2a\x01\xf2\x1e\x6b\x5e\xdb\xa2\x28\xb4\x4a\x9a\x8b\x11\x02\x50\x90\xc0\xc7\xb9\xf9\x73\xb9\x3a\xbc\xae\xde\x56\xaf\xef\xaf\x87\xcd\xfb\x76\xf1\x3c\xdb\x2d\x6d\x1f\x11\x63\xf8\xbc\xa9\x5a\xbf\xb8\x1f\x0c\xed\x0f\x0a\x11\x12\x35\xf5\x5e\x67\x7f\x2c\x66\x1b\xa3\x4d\xbd\xd9\x2e\x0f\xab\xc5\xda\x9c\x2b\x76\xdc\xb0\x93\xef\x1a\x67\xaf\xa6\x67\xbf\x88\x29\xa5\xa1\x49\xe2\xcc\xce\x13\x35\x41\x22\x16\x71\x14\x98\x68\xf6\x15\x60\xf9\xeb\xa2\xa2\xdf\xe7\x3e\x7f\x65\xbf\x92\x52\xc4\x52\x85\x03\x5f\xa1\x2c\x53\x93\x81\xfc\xb6\x68\xbe\x97\x8d\x10\x89\x17\x61\x95\x9a\xaa\x24\x37\xa5\x33\xa3\xc5\x51\x24\x81\x87\x9e\xd7\xe9\x70\x31\x44\xd3\xed\x8f\x11\x62\x02\xbf\x6e\x05\x70\xa9\x48\x42\x17\xd5\xed\x87\xfa\x45\x7f\x85\x52\xbf\xe5\x31\x10\x89\x16\x09\x31\xf2\x6b\x8b\xa6\xbe\xa3\x68\x43\x45\x02\x12\xa1\x01\xef\x8c\x5e\xbf\x89\xf9\x09\xea\x05\x49\x68\x51\x08\xec\xe6\xe6\x19\x8b\x71\x08\x14\x39\x2e\x5d\x5d\xe6\x5b\x30\xae\xdc\xe0\x79\x53\xe2\x64\xb5\x4f\xf6\x7f\x7c\xed\xdc\x53\x22\x45\x23\xe1\xcd\xd9\x62\xbf\xfa\x61\x07\x2c\x8f\x04\xd5\xfc\x5a\x0b\x68\xc7\x7b\x36\xa7\xf9\x98\x6c\x9a\x0a\x11\x50\x4d\x17\x23\x8b\x26\xbf\x25\x83\x11\x22\x8a\x99\x62\x7d\xa3\x65\xfd\xcf\xc9\x41\x2f\x80\x1a\x85\xab\x1d\xaa\x06\x8d\x4e\x01\x21\xf7\x75\x7b\xbb\x33\x9a\xd0\xe4\xc0\x68\x11\x32\x54\xd7\x79\xdf\x6f\x5e\x06\x2b\x80\x8c\x34\xc1\x1c\xe4\x9d\xbc\x36\x05\xd7\x0d\x30\xf2\xf7\x89\x7c\xe0\x0a\x0b\xd0\x83\x70\x7d\x3b\x99\xc0\x0b\x05\xc6\xa9\x6a\xc8\x1f\x80\xa7\x67\x9a\x6d\x32\x6a\xa5\x3f\x28\xf8\x81\x92\xb7\x3c\xd9\xe4\x1c\x10\x37\x36\xa1\xde\x8d\xd2\xac\xde\x94\xe8\xca\x0e\x44\xbc\x06\x2f\x17\x08\xd3\xa5\x5f\xb3\x3f\x0e\xcf\xeb\xdd\xfe\xa0\x99\xe6\xcc\x39\x03\x8f\x70\x8d\xa7\xae\xb7\x69\xf5\x31\x2d\x0b\xaa\x3b\x87\x9e\x1b\x9b\x9c\x79\x53\x6a\x8c\xb2\x69\x8b\x02\x44\x0e\x3f\xd1\x33\xec\x52\x3e\x2f\xfe\x8a\x42\x71\x78\x9f\x91\x17\x10\xc4\xc3\x63\xf5\xff\x6f\x83\xcb\x46\x5c\xe1\x38\xd0\x7b\xc8\x53\xeb\xb9\x42\xc4\x55\x61\xc6\x2a\x57\x9c\xab\xdf\x87\x44\x20\xf6\x62\x7c\xa5\x87\x1c\xbe\x9e\xe8\x38\xcf\x01\x71\xe8\x63\x35\x92\xf1\xb8\x36\xdb\xdd\xf0\x6d\x98\x7e\x11\x8d\x1c\x5b\x3e\xda\xae\xe4\xd0\x43\xc2\x8d\xaf\x49\x3d\xad\x90\x9a\x0f\xcb\xaf\xee\xdd\x23\x8d\xd4\x66\x73\x02\xfe\x31\xf0\x41\x06\x63\x15\x62\x46\x54\x2e\x99\xd7\x0d\xcd\x9e\x8a\x7a\xb9\x7f\x1e\xdd\x67\x12\xc5\x98\x59\x7c\x9d\x6d\xb7\x6b\xe3\x44\x40\xc2\x43\x34\x6d\x2e\x65\x51\x17\xbc\xc8\x06\xe2\x01\x14\x28\x11\x9e\x8a\xe3\xd3\x8e\xd3\x07\x28\xf5\x54\x74\x05\xef\x6a\xe0\x62\x41\xeb\x88\x69\x48\xd4\x4b\xfa\x9f\x26\x15\x69\x7d\x9d\xe5\xc2\x50\xb6\xdc\x04\xb3\xcd\x61\x5c\xd1\x7a\x40\xdf\x38\x47\xcf\x6b\xad\x4a\x2f\xf3\xbf\x56\x5c\xa5\xc0\xb8\x92\x8d\x52\x00\x0b\x0c\x51\xe9\x16\xee\x53\x44\x42\x6e\xca\xa2\x90\x6b\xf9\xdc\x9c\x69\xeb\x1f\xce\x84\x58\xdb\x87\xe5\x09\x41\x77\x5f\x13\x07\xf5\xd4\x9d\xef\x7c\x1d\xe1\xfa\x58\x32\xf3\x71\x65\xbd\x5b\xb4\x8d\x89\x13\x98\x42\xdc\x9a\x9f\xd2\xfc\xb8\xc4\x45\xb6\xcf\xaa\x00\xc2\x0b\x70\xe7\x4d\x73\x45\x74\x52\x3c\xa4\x15\x9c\x19\x2d\x3f\x46\x34\x94\xc3\xd7\x25\x22\x89\x5c\xcf\x1a\x9c\x3b\x5d\xe3\x0b\xe0\x26\xdc\xb0\x0c\x77\xb1\xd6\x1e\x2d\x35\x05\xe9\xc7\x28\xae\xbe\x30\xb5\x59\x18\x0b\x9b\xd8\xcb\x41\x86\x52\x2a\x63\x1f\x39\x82\xf7\x25\x35\x25\x07\x0f\x69\x75\x93\x3a\x19\xbd\x29\xc9\x22\x74\x80\x65\x3b\xe6\x0f\x5c\x4b\xa0\xab\x46\xe9\x38\x04\x22\x83\x4e\x93\x50\x96\x34\x1b\x25\x8b\x86\x4f\x2f\x9d\x80\x63\x00\x34\xa3\x55\xad\xb1\x5c\x9d\x46\x48\xdb\x2c\xb0\xc0\xa3\xc9\x91\x1d\x47\x39\xe5\x33\x03\xae\x55\xd3\xce\x74\x6d\xdd\x2c\xed\x98\xe0\x43\x23\xaa\x5c\xd6\x50\xa2\xa2\xeb\x83\x05\x3a\x49\xd7\xf3\x99\x82\x33\x48\xf9\x5c\x34\xe5\x1d\x62\x20\xe9\x86\x2e\x2e\x1b\xaf\x2a\xed\x33\x69\xb5\x37\x3d\x6d\x69\x73\x18\x0b\xa8\xa6\xfc\xa9\x71\xf1\x7a\xc7\x9b\xbf\x59\x1e\x86\x07\x71\x8f\x68\xa4\x6a\x3d\xb5\xbe\x8e\xae\xe1\x79\x2a\x80\x7b\x84\xfa\x1f\x05\xbb\xb3\x44\x49\x3f\x62\xc8\xcd\xf2\x50\xe4\x9d\x4d\x69\xda\x62\xc0\xf0\x08\x52\xd7\xcd\xab\x4b\x5f\xed\x81\x4a\x3f\x61\xd8\x8a\xfe\x1d\xc6\x57\x84\x5e\x31\x07\xcf\x3d\xfc\x96\x3e\x53\xec\x65\xba\x20\xba\xee\x4b\x04\xfc\x45\x44\x5a\x12\xee\xf7\x54\x67\xa7\xc5\x4d\xa9\x0c\x3c\x65\x4c\xef\xb7\xb3\x89\x22\x77\x19\xf8\x41\x68\xa1\x3f\x7b\xa0\xe7\x81\x17\x2e\x03\x2e\x85\x30\xa2\x6d\x6b\xb9\xac\x4f\xeb\x7c\xf9\xbe\xb5\xcd\x10\x32\xaf\xc7\xcf\xbb\xb4\x52\x81\xdd\x1b\x0d\x25\x43\x72\x0f\x24\xcd\xc3\xb3\xaf\xce\x17\x93\xa1\x92\x11\x55\x64\xe3\x65\xdd\x8c\x8e\x8b\x38\xc1\xcc\xea\x02\xca\x3a\x95\xa9\x55\x50\x6b\x5b\x40\x15\xaa\x43\x55\x4f\x94\x06\xc9\x08\x38\xd7\x8c\xed\xdb\xa2\x82\xbc\x3d\x03\xe2\x68\x46\xcf\x1e\x53\x89\x98\x26\x71\xb4\x1f\x31\x66\x21\x51\x45\x6a\x48\x81\x3a\xcd\x8d\x21\x63\x29\xb0\xa2\x65\xb5\x3b\xb7\x06\x31\xd8\x60\x96\xa4\x9c\x7a\x4a\x6e\xf6\xfa\x7d\x7a\x5e\x32\x4f\xa1\xcd\x54\xe8\xc0\x90\x5c\x99\xf3\xb0\x44\x22\x57\x74\x5a\x2d\x68\x29\x90\xfb\xde\xea\x73\x19\x80\xa8\x64\x8c\x72\xa5\xbb\xab\xc3\x92\x77\xae\xc4\x7d\x2c\x48\x99\xe5\x39\xfc\x82\xc3\x6e\x7d\x78\x58\xfd\x98\x1d\x76\xb3\x9d\xbd\x1a\x28\x7d\xd6\x7f\xfe\xf3\x9f\x7d\x53\x4f\x72\x21\xf1\x1e\x55\x1c\xec\x09\x72\x47\x87\x2e\xff\x6f\xe5\xf2\x92\x4b\x82\xe8\x05\xfc\x58\xfb\xaf\x42\xed\x04\xbf\x75\xad\x48\xcb\x9d\xe2\x9b\x18\x7d\x4b\xe1\xd2\x48\x98\x2a\xb3\xe9\xfa\x1b\xdd\x13\x08\xf7\x23\xeb\xfc\x64\x20\xed\x47\x81\x44\xe2\x44\xd9\x43\xa5\x82\x64\xa3\xcd\x4a\x82\x08\xd1\x23\x52\xac\x34\xed\x12\xa9\xbd\x67\xdd\x2e\x5d\x07\x15\xdb\x5f\xd2\x1c\x68\xf9\x00\x9c\x5e\xdb\x45\xb7\x3d\x95\x29\xa9\xb4\x5d\xbd\x98\xf8\x7a\x9f\x68\x2a\xc4\x63\xed\x8c\x0c\x26\x95\x92\x24\x42\xaf\xf5\xbb\xf4\x4f\x98\xe5\x62\xdb\xab\xee\x18\xbc\x35\xe6\x38\x8e\x74\x9c\xbe\x94\xf0\x21\x87\x5f\xf5\x01\xb4\x17\x79\xf8\x82\xf4\x6f\x15\x0a\x33\xc7\xe1\x0a\x9d\xa8\xbe\xe3\x73\x51\x56\xb0\x3b\x15\xe0\xde\x03\x37\xea\xc3\xdc\x24\xc4\xac\xd9\xf6\x5f\x6f\xd6\x96\x60\x8e\xcb\x64\xe0\x76\xb1\xb5\x09\x9f\x8b\x39\x5e\xcc\xd0\x79\x78\xf9\x7d\x71\x9b\x0c\x65\x8e\x27\x12\x2c\x3d\x78\x5b\xbd\xce\x4d\xad\x3c\x73\x7c\x16\x63\xd4\x75\xf5\xfa\xb0\xfc\x43\xf4\x49\x59\x99\xe3\x8b\xc8\x51\xcc\xae\x22\xad\x2e\x4d\x0d\x8f\xf4\xd3\x24\x75\x98\x43\x48\x80\xc0\x54\x5c\x98\x97\xbf\xea\x92\xae\x2f\xca\xdc\x32\x1d\x62\x69\x12\x9b\xaf\xd7\x07\xb8\x64\xc5\x75\x36\x55\x8f\xc7\x1c\xa2\x05\x31\x54\xb0\xeb\xbd\x82\x12\xcd\xb0\xa7\xb2\x68\x6e\x78\xf6\xb4\x5b\xcb\x1c\x22\x62\x0c\xc1\xb5\x93\x70\x2d\x65\x8f\xde\x7e\xf8\x5a\x08\xc4\xc4\x31\x30\xdb\xfb\xa8\x12\xe6\x04\xc2\xc7\xf8\xe5\x82\x66\x99\xe1\xb9\x16\xa3\x77\x1c\x26\xb1\x1b\xda\xfd\xec\xb6\x34\x90\x39\x91\x0b\x44\x45\x06\x4b\xa0\xe2\x2e\xbd\x20\x73\xa2\x30\xc6\xa4\xa0\x65\x88\xd7\xae\x67\x7f\x2f\x60\x4e\x1c\xb2\xc4\xeb\x58\xae\xf6\xc5\xfe\x75\xf9\xc7\x9d\x27\x8d\x25\x48\x5d\x9c\x71\xa8\xfb\xdb\xce\x08\x1b\xc8\x9c\xc4\x97\x18\x66\x53\x38\xae\xd7\xf7\x97\xfd\x6a\xf3\xb2\x32\xac\xdf\xcc\x49\x92\x04\x91\xc5\x5a\x9b\xf2\x5f\x40\xed\x67\x4f\x20\x42\x4b\x47\x4d\xdb\xe7\xf4\x13\xec\xbd\x52\xea\x62\xe5\x9a\x56\x53\xaf\x4f\x8f\x30\x7e\x3b\x94\xab\xbc\xc2\xe1\x1b\x7c\xfd\xdf\xf2\xd7\x98\xc3\x99\x8b\xfb\x01\xfa\x8d\xf4\xeb\x1b\xb7\x91\x39\xc2\x71\x71\xb5\xcb\x1a\xfe\x71\x9d\x37\xd7\xdf\xec\xef\x8a\x28\x98\xb6\xe6\x17\x22\x29\x54\x7d\x10\xea\x45\xa0\xd5\xa6\x69\xb9\xdf\x9a\x73\x3f\xa5\xc9\x1c\x70\x95\x2c\x9f\x61\xa2\x98\xcf\x5e\x66\x6f\x8b\xa5\x9d\x57\x10\x12\x04\xf0\x08\xa8\xa1\x3c\xa7\x39\x74\x4c\x2e\xf6\x7d\x01\x53\x5f\xc1\xc8\xec\x89\x7f\x34\xe5\x75\xc2\xe1\x63\x8e\x64\x32\xf2\x4c\x89\x35\x43\xa6\xb8\xe1\x03\x4a\x11\x63\x70\x74\xb6\xed\xca\x2e\xdb\x5f\x99\x0a\xb7\xea\x78\xde\xeb\xec\xed\x7d\xf6\x72\xd8\xad\x9e\x30\x64\xb2\x5a\x3f\xd8\x9e\xd2\xc1\x6c\x5a\x96\x56\xf5\xc2\x30\x9e\x84\x64\x9c\xaa\x51\xaf\x55\x6d\x85\xcc\x75\x1c\xea\x6b\xc4\x15\xea\x29\xec\x9a\xf3\x7d\x33\x95\xb9\x4e\xe4\x62\xa2\x12\xa5\x6b\x2c\xa9\xee\x5b\x93\x65\x23\x92\x04\xe6\xba\x1e\x10\x93\xe0\x4a\x4b\x5c\x88\xd3\xfc\xd8\xcf\x6f\x33\xd7\x85\x08\x9d\x83\xdd\xea\xe5\xc7\x72\x6b\xb8\x76\x76\xbf\xbf\x98\x0e\x1e\xf1\x48\xa0\xe1\x66\x5b\x0d\x11\x7f\x58\xbd\x21\xb7\xa5\x91\x76\x9e\x1e\x2f\xae\x17\x04\x68\xb6\x62\x35\xe0\xed\x5a\xea\xfa\x22\x4a\x14\x17\xa0\x00\x38\x83\xb8\x11\x5b\x60\x2e\x09\x7c\xa1\xf3\x7e\xbb\x2f\x7a\xe9\x1b\xb5\xcc\x25\x21\xc1\x49\xa4\x83\x28\x48\x02\x63\x9a\x58\x84\xa6\x23\x15\x42\xf3\x0f\x7e\xe7\x7f\x32\x97\x70\x1a\x84\x1a\x0c\x6d\x21\xcb\x0c\xb9\x83\x43\x15\x98\xe7\x78\xfe\x1e\xd5\xb8\xc6\x3f\xdd\x52\x81\x0f\xcf\x1c\x00\xc3\x98\xf4\xbe\x68\xb7\xdd\x9b\xec\xc5\xb0\x73\xc8\x94\x49\x8b\x79\x99\x1e\xf4\x6f\xdc\x4d\xa7\x86\xdb\x4d\x75\x53\x14\x59\x2f\x10\xa9\x7b\x44\x7e\x80\xd5\xb4\x5a\x84\xad\xd2\xaf\x68\x38\x21\xdc\x88\x85\x14\x13\x46\x39\xeb\x19\x4f\xcc\x8d\x89\x8b\xc1\x0e\xa4\xa4\x14\x77\x29\xa6\x87\x4b\x89\x1b\x07\x11\xa2\x90\x8c\x44\xcf\x86\xd6\xa7\x2f\x7a\xbd\xb3\x9a\xb8\x89\x23\xdd\xb8\xa3\xa6\x18\x2c\xd8\x6e\xe2\x53\x95\x39\x7d\x5b\xed\x57\xb3\x97\xc3\x6c\x31\x48\x71\x30\x37\x89\xfd\x50\x17\x00\x5b\x2b\x7b\xf4\x74\x49\x1c\x63\x2a\x66\x9e\x15\x9c\xd3\xd6\x70\x2a\x6e\x71\xf0\xcc\xe5\x81\x2d\x05\xd3\xae\x66\x9a\xb5\x93\x68\x78\x32\x1e\x26\x28\x88\x87\xd3\x0e\xce\x17\xcf\xdc\x88\x10\xb1\xa0\x16\xf5\xf5\x08\x76\x21\x77\xc1\xd3\x00\x5e\x25\x25\xfc\x50\x9c\xfb\x14\x30\x7d\xb3\x9c\xb9\x10\x38\x6e\xd8\x19\xef\xfb\x13\x3c\x17\x22\xb3\x67\x12\x0e\x1a\x09\x5f\xb4\x04\x64\xde\xb4\xd7\x90\x51\x88\x09\xfe\xcd\xf6\xbf\xf7\x7f\xcf\x63\x65\xae\xe4\x5c\x51\x16\x9e\x2f\xd9\x41\xa5\xae\xd5\xb0\xbe\x5b\xb2\xc2\x5c\x29\x02\x64\x4f\x52\x59\xd4\xf9\x08\xdf\xce\x3c\x47\x93\x4f\x97\x5a\xc3\xc4\xac\xf0\x9e\x4b\x94\x2c\x4b\xbb\x24\xce\xb2\x6c\xde\x5c\xef\x98\x0f\xc3\xd1\xe1\xb9\x81\xe3\x59\xae\xf5\x65\x7d\xda\xf2\x4f\x61\xcf\x29\x1c\x14\x4c\x69\xdf\xea\x7c\xbf\xf8\x65\xcb\x3c\x99\xe7\xf9\x4a\xe9\xc8\x54\x72\x96\x56\xab\x92\x79\xc8\x69\xdd\x3e\x83\x2a\x9b\x84\x58\x6b\x3c\xf5\x87\xbe\xe7\x7b\x11\x66\x03\x2f\x4d\x96\xa1\xda\x8c\x59\x38\x8b\xbe\x8e\x14\xf3\x08\xf1\x85\x76\x60\x30\x09\xfb\x5e\x8d\x25\xad\xdb\x3e\x09\xb3\x81\xa4\x5f\x8b\xd9\x66\xdc\x4e\x29\x86\x90\xda\xe7\x98\x99\x1b\x08\x3c\x81\x65\x00\x87\x12\x25\xef\x7a\x35\x9c\xa3\x37\x14\xf8\x8a\x4a\xe0\x7d\xf7\xb0\x7f\x9f\x2f\xed\xf1\x34\x42\x64\xd6\x31\xfd\x84\xdf\x1b\x51\xdc\x99\x7e\x5e\x2c\x54\x95\x37\xbe\x60\xc5\x36\x66\x8a\x81\x5f\xe9\xe5\x62\x73\x0d\xcc\x4b\x5c\x50\xcc\x35\x4a\x1b\x5e\xc1\xeb\x7a\x55\xaf\xcc\x4b\x02\x1f\x09\xac\x44\xfb\xed\x53\xd6\xd4\xf0\xb2\x98\xed\x9e\x6f\x0d\xa7\xd1\x3d\x24\x91\x4c\xfa\x8c\xde\x0f\xb4\x18\x4e\x3b\x2f\x49\x1c\x8c\x54\xcf\x9f\xe6\x43\x3d\x64\xe6\x25\x52\x21\xb3\xda\x19\xf9\x48\xd3\xec\xf0\x59\xd4\x50\xbe\x15\xb5\x59\x0f\xec\x87\x67\x5e\x1c\x9b\xd8\xf8\x4a\x8b\xe2\x98\x02\xe8\xfb\xa6\xa5\xc7\xa8\x60\x46\x06\xaf\x11\x69\x3d\x2a\x2a\x63\x1e\x8f\x5c\xf4\x05\x44\x81\x5e\x6e\x21\x17\x45\xd6\x3a\x3b\xe5\x5f\xf3\xa7\xde\x79\x21\x3c\x71\x59\xd2\x41\x48\x47\x3a\xb6\xc3\xbe\x82\xbb\x98\x39\xdd\x2e\x17\xcb\x55\xbb\x77\x6f\x66\xff\x5a\xbf\xef\x0f\xfb\xe7\xed\x72\xf7\xbc\x7e\x31\x56\x89\x07\x91\x1b\xa0\xc5\x70\xbd\xc0\xbc\xfb\x31\x44\xdb\xf4\x65\x76\xf8\x52\x9c\xba\xba\x41\x12\x11\x93\x01\x01\xab\x66\x9f\xfc\xfe\xce\x65\x1c\x63\xd9\xd2\x7f\x1a\x9a\xd7\xa9\xa0\x02\x1e\x60\x86\x22\x0a\x7f\x52\x5e\x8c\x2a\xa0\x99\x27\x99\xa2\x20\x3b\xa7\xb9\x1a\x4f\xcb\xc6\x2c\x19\xbe\xe3\x29\x49\x4a\x49\xd3\xf2\x3a\x12\x00\x66\xbe\x43\x63\x0c\x21\x96\x45\x96\xed\xbf\x8a\xc1\xcb\xe9\x53\xbb\x32\xdf\x11\x1e\x06\xfe\xd2\xfc\xb3\x18\x01\x9f\x98\xef\xc6\x01\xde\xc0\x4c\x88\x87\x6b\x4e\xcf\x93\x0c\x52\xa3\x8a\x23\xe6\x7b\x6e\x88\xd1\x00\x8c\xcb\x66\x45\x65\x65\x61\x4c\x7b\xa2\xaa\x1a\xab\x2f\x8a\x52\x61\xfa\x67\x3f\x72\x11\x62\x88\x73\x2d\xad\x2a\x53\x6b\xc5\x7c\xe2\xbb\x8e\x22\x60\xfa\x52\x28\xfa\xce\xf8\xf0\x83\x04\x10\x52\x2e\x55\x0d\xea\x60\x83\xf4\x03\xa1\xe8\xec\x0c\x41\xf0\x6d\x30\x89\xf9\xa1\xaf\x92\xc3\x36\x42\x77\x84\xb1\x2e\x0c\xf3\x43\x1a\x62\xfd\xd5\x05\x1f\xdf\x9e\x3f\x4a\x3c\xb5\x3b\x67\x05\xa3\xd9\x03\x4d\xb3\xeb\xc0\x70\xf4\x23\x4d\xa6\x55\x0b\x5d\xea\x62\x1a\x62\x00\x34\xa5\xe0\x57\x5a\x3f\x02\x1c\xcc\xef\x94\x50\xcc\x88\x50\xf1\xbf\x4d\xd5\xb6\x2c\xf3\x3a\xad\x33\xb8\x8b\xc7\x61\x3e\x8b\xe3\x40\xcd\xfe\x7f\x2c\xbe\x01\x50\x30\x9f\x47\x01\xb2\x09\xd5\x29\x94\xfb\x53\x09\x1d\xf7\xa2\xee\x20\x68\x84\xab\xea\x7c\x3d\x5f\xa3\xbb\x66\xf6\x6f\x1f\x28\xa0\x63\x8b\xa1\x7e\x35\xda\xf6\xf4\x03\x8a\xcf\xfb\x3a\x3d\xe6\x48\x16\x29\xbe\xf5\x2f\x5a\xea\xc4\xf8\xa6\xb4\xd1\x6c\xe6\x83\x08\x3c\x0d\xb2\x79\x4c\x69\x3d\x19\xea\x6f\x7b\x01\x06\x68\x4c\x18\x6d\x96\x65\xa3\x1e\x32\x91\x8a\x8a\x07\x95\x16\x20\x17\x36\x22\x3e\xfa\x94\x92\xa9\xd0\x45\x05\xf5\x26\xfd\x05\xd9\xa2\xc8\x34\x81\x4b\x97\x8d\xe8\xbb\x1e\xbe\x94\x09\xba\x4e\x0f\x2f\x3f\x34\xa2\x80\x11\x97\xf8\x58\xa3\x3c\xa7\xd5\x07\xd4\xc3\xb2\x5d\x46\xdc\x20\xc6\xb8\x1d\x6b\xae\xad\xd1\x86\x97\xb9\xbb\x34\x0c\xdf\x17\x71\x69\x82\xcf\x71\x6c\x77\x36\x84\xda\x6a\xb6\x08\xbb\x52\x13\xcf\x67\x4e\x60\xe3\xc2\x5b\x4d\xb9\xfc\x9a\xe6\x1d\x11\xcd\x7f\x75\xc0\x67\x73\x10\xb5\xba\x29\x96\x09\x60\x9d\x67\xd7\x5e\x09\x47\x67\xc9\x10\x4f\x12\x8c\xfb\x6a\xc8\x19\x3a\xd0\xdf\x27\x1c\x19\xf1\x03\x65\x6c\xca\xbe\xfe\x61\xef\x9c\x7e\xe0\xa3\xa6\x80\x82\xff\xf6\x5c\x1c\x42\x84\x83\x69\xdb\x97\xd5\x6e\x66\x7f\x03\x25\xa7\xd9\xed\x96\x78\x2f\xfb\xe2\x4e\xee\x64\x7a\xf8\x11\x22\x05\x0a\xfe\x0a\x5d\x36\x63\x26\x1a\x09\x02\x8a\xf4\x47\x69\x5e\x41\x59\xbf\xa6\x19\x54\xb5\x51\xb4\xfe\x0b\x6f\x85\x04\x09\xa0\x78\xf3\xee\x02\xe5\xf9\x85\xb2\x6a\x0b\xac\x28\x73\x7b\x6a\xc6\xa5\x26\xb8\x4d\xcf\xcd\xf9\xf9\x2a\xca\x02\xe3\xb7\xc8\xe4\xad\x3b\x85\x41\xc8\xe3\x2e\xec\xf1\x5d\x01\xcb\xdf\x1b\x38\x21\xa8\x4c\xc3\xee\xe5\x7d\xff\xdf\x7d\x6b\x8d\x44\x41\xe4\x52\x8d\x0c\xb6\x81\xe8\x7d\x7a\x1e\x7b\xf6\x24\xe2\xaa\xb8\x72\x5f\x5c\x06\x27\x48\x78\xc2\x3b\x74\xfd\x9c\xe6\xff\x69\x26\x69\x29\x19\x49\x04\x41\xfc\x87\xe6\x4a\xdb\x94\xc5\xa5\xa8\x4c\xf5\x66\xdb\x9c\x80\x91\xe0\x4a\x8f\xa7\xda\xa0\x1f\x6c\x90\x6e\x6c\x5e\x10\xea\x45\x38\x95\x24\xf0\xd3\xa6\x84\x59\x96\xed\x9a\xf3\x5b\x73\x7e\x2c\xca\x0e\x8a\x6b\xfb\x0a\xa3\x6b\xba\xca\x65\x81\x86\xa9\x26\x46\x54\x21\xdc\xfe\x7c\xa0\x3e\xc3\x80\x02\x9a\x25\x96\x5e\xec\xfb\xc5\x8c\xd0\x24\xc4\x72\xce\x1c\xea\xaf\xa2\xfc\x78\x2a\x8b\x2f\x4b\x4a\xa2\xbb\x30\x21\x23\x1d\xb5\x9b\x8b\xcb\x2d\x75\xff\xbf\xdd\xd0\x3c\x1b\xa7\x2e\xb2\x3d\xed\xff\xf8\xe7\x7d\xfc\x0b\x23\x9c\x71\xee\x5b\x3d\x2c\x46\x47\xde\x3f\x11\x0e\x51\x5a\x55\xad\x4b\x74\x0b\x6c\x31\xbd\x22\xee\x6b\x48\x9b\x49\x56\xbf\x40\x2e\x46\x4a\xfb\x8c\x40\x4c\x70\xc7\x6a\x2a\x28\xdf\x7a\x65\x94\x8c\xc8\x28\x41\x4b\x8f\x35\xd7\x81\x92\x42\x2f\x93\xd5\xbf\x62\xe0\x7a\xaa\xd2\xea\x67\x6b\xec\xbd\x42\x0d\xe5\x0c\xe5\xed\x07\xb0\xa8\xef\x07\x75\xe0\xfa\x01\x06\x67\xce\xed\x73\xbd\xd1\x33\xcc\xd5\xc1\xbf\x8d\xba\x91\xc8\xc4\x70\xf6\x40\xcf\xa3\x4a\x07\xd3\x29\x26\x54\x3b\xc3\xbb\x4b\x91\x57\xc5\x20\x9b\x36\xfd\xc5\x03\x37\x8e\x30\xb2\xbe\xdb\x2f\x16\xfa\x45\x04\x9e\x4b\xd0\x0d\x95\x8a\xe8\xd7\x58\x03\x01\x49\x58\xec\xf5\xd8\x38\xff\x4f\x99\x94\xe9\x70\x41\x40\xb8\xd2\x57\xa3\x62\x12\x21\xa9\x7b\x05\xc4\x25\x9e\x8d\x11\xbd\xd2\xfc\x7a\xdf\x62\x0f\x82\x30\x56\x36\xc9\x57\x5a\xb7\xee\x44\x59\x5c\x2c\xd1\xd1\x20\xef\x32\x75\x6c\xe4\x20\xc2\x7c\x43\xeb\x14\xf2\x5a\x09\xa5\x9b\x7d\x2f\x08\x35\x0b\xb6\x48\xab\x4b\x46\xaf\x9f\x70\x4a\x79\x06\x42\x2b\xcd\x4c\xbf\xe0\xc8\x53\x85\x8b\x4a\x0e\x6c\xb4\x59\x07\x51\xa4\xa4\xcb\x37\xdb\xe5\xeb\xea\x6d\x79\xd8\x2e\x5f\x96\xb3\xdd\xf2\xfb\x9d\x28\x88\x9d\xc8\x70\x67\x3f\xd0\x9a\x56\x50\x4f\xa0\xa6\x59\x10\xbb\x81\xc3\x06\xe4\xfb\x0f\xcd\xb0\x82\xcc\x74\x8c\x02\x64\xcb\xbd\xa8\xf8\xd0\xb7\x2a\x97\x2c\x88\xc1\x73\x3c\x9b\xa7\x5a\x4b\x4c\xdc\xb6\x8b\x8b\x0a\x56\x7d\x7f\xeb\x89\x4b\x24\x18\x72\x44\x28\xc7\xd4\x96\x2c\x48\x42\x55\x6a\xc1\x0c\x89\x56\x9f\x64\x9b\x05\x49\x04\xa4\x8b\x8b\xcf\x8b\x22\xeb\x52\x9c\x76\x2b\x0e\x12\xe1\x62\xc9\x11\x2b\xca\x2e\x0a\x11\x50\xe1\x51\x61\xf9\x12\xd4\x06\x61\x9a\xa4\x83\x85\x2b\xad\xc1\x9e\x8b\x07\xe0\x28\x94\x26\xe6\xf7\x31\xd4\xff\x27\xce\x58\x16\xb0\x30\xc6\xf0\xf1\x6c\xb5\x7d\xd8\xae\x37\x3a\xc4\x6a\x2e\x2f\x68\x82\xec\xae\xed\x7e\x02\x65\x7d\xfd\x1e\xba\x67\x0f\xa2\x88\x78\xcc\xe1\x4b\x71\x85\x8e\xc4\xbc\xb5\x8d\xd4\xbd\x15\xe9\x29\xdc\x24\xe4\xbc\x10\x6a\xa5\xf9\xad\xab\x1d\x8b\x4d\x2f\x0a\x68\xfa\x1d\x38\xcd\xf8\x88\x6d\x6d\x78\x03\x92\x13\x25\x13\xbe\x7b\x7f\xeb\xef\xa7\xa1\xe3\x2b\x58\x06\xcd\xb2\xe2\xeb\x96\xfa\x8a\x85\xae\xef\x4b\xab\x0b\xb8\x4f\xa1\x34\x1e\xc9\x90\xc9\x80\x85\x5e\x10\xa3\xb4\x50\x67\x25\x6d\x60\x48\x12\xcc\x42\x0f\x14\xd3\x9d\x12\x89\x34\x1c\x47\x83\x1b\xf2\x7d\x95\x3e\x63\xed\x1d\xd5\x4a\xf1\xb0\x75\xa6\x86\x0c\x2a\x2c\x24\x84\xa2\xd1\xd2\x1a\xd9\xb3\x4f\x5a\xd3\x72\x25\xdf\x0a\xfd\x5f\xd5\x0e\xee\xb8\x28\x61\x20\xdc\x58\xe5\x9f\xca\xbe\x3c\x1a\x0b\x03\x70\xd0\xaf\xc0\x12\xa4\xae\xb0\x95\x85\x21\x11\x31\xed\x58\xe6\xaa\xf9\xf5\xa1\xe0\xa8\xbd\x30\xd8\xae\xc2\xd8\x49\x7c\x1c\x37\x6f\x6f\xeb\xf7\xb7\xc5\xf2\xf0\x73\xf5\xf6\xb6\xdc\x1e\x1e\x96\xb3\x87\x97\xd5\x9b\x09\xf8\x84\x31\x4b\xd0\xdc\x13\xa0\x50\xcd\xdd\xef\x8a\xbe\x41\x45\xf8\x86\x79\x63\x16\xc6\x92\x23\x3e\xec\xd8\x60\x01\x27\x80\xd8\xd0\x2b\xa3\xed\x37\xb1\x1e\x4c\x98\x48\xe2\xa8\x35\x51\x17\xc1\x97\x9f\x7f\xab\x16\x99\x85\x34\x66\xc4\xee\x48\xf4\x56\xad\x7a\xa2\x9e\x78\xea\xef\x37\xb1\xf2\x90\xd2\x30\x11\x4a\xec\x72\x12\x90\x67\xba\x09\x8a\xb0\x1e\xa5\x1c\xd4\xda\x88\xe8\xcc\xaa\x6f\xf5\x17\x01\xaa\x90\x45\x1c\x79\xac\x68\x5a\x8a\xb2\xb8\xac\x72\x8c\x6d\x37\x5d\x7c\xe7\x86\x1c\x69\xe2\x1c\x8c\xfb\x86\x74\x22\xcd\x8f\xad\x67\x62\xde\x2f\xe3\x09\x42\x2e\x68\x5e\x7d\x59\x82\x3f\xdb\x28\x5c\xc5\xba\x7f\xa2\x69\x8e\x98\x36\xdd\xc0\xa3\x00\xab\x11\xb2\xa2\x02\xbd\xdd\x1b\x53\x73\x70\x61\x11\x45\xc8\x0c\xd8\x49\x2f\xb6\x73\xe7\x95\xe6\x0d\xcd\xb2\xeb\xbe\xb8\xb7\x99\x8e\xee\x5f\x44\x14\x9d\x9f\x13\xad\x14\x45\xc2\x86\x8e\x8d\xe3\xc8\x89\x95\x8a\x7d\xd3\xda\x4e\x8f\x70\x63\x3e\x99\x6e\x92\x62\x44\xfc\x48\xcf\x70\xc0\xe2\x04\x33\xff\x22\xd7\x55\xbc\x03\xa9\x16\xde\xee\x93\x83\xb2\xc8\xf5\x85\xa2\x43\xa4\xf9\x47\xe7\x27\x0d\x4f\xee\x32\x07\x34\x64\x7d\x57\x53\x7b\xa8\xe7\x2a\x31\x18\xac\x4e\x83\x7d\x71\x4f\x8f\xd6\x74\x0f\x23\x54\x34\x5a\xee\x57\x0b\x7b\x0a\x1e\xe0\x9e\xf2\x38\x7b\x5b\xfc\xeb\xbb\x38\x44\xe4\xd3\x18\x63\xb2\x8b\xf9\x6e\x62\x21\xbf\x6b\x12\x8e\xd7\xeb\x88\xb8\x80\x54\x39\x1a\x6f\x87\x59\x85\x49\x2b\x2a\x22\x9e\x8f\xd0\x2d\xfa\x09\x65\xbf\x46\x73\xf8\x54\x24\xa2\x48\x15\x8a\x39\xed\x94\x7f\xc0\x28\xbd\xd1\x8e\x28\x2c\xab\x78\x58\xfd\x58\xed\xd6\xdb\xc3\x66\xbb\x5a\x98\x15\x26\x0a\xbc\x18\x53\x58\x98\x05\x9b\x43\x5f\x02\xd7\xfc\x3b\xb8\x5a\x10\x2a\x25\x30\x2a\xce\x69\x6e\x0b\xcf\x0f\x74\x1c\xd9\x88\x82\xd8\xe3\x8e\x06\xd5\x2e\xeb\x13\x12\x4b\x76\x7c\x69\x2c\x0a\x63\x0f\x0b\xb6\x57\x8b\xf5\x80\x19\xfd\xef\xed\xbc\x51\xe4\x80\x0a\x6f\x88\xff\xad\x29\xfb\xf6\xc3\x45\x44\xe0\x7a\xf5\x47\x9f\xe3\x8f\x45\xb1\x9b\xe0\x6b\x79\x9a\xed\x0e\xdb\x65\x47\x32\xcd\xa2\xd8\x57\xd4\x12\xf8\x8c\x83\xb1\x1a\xfb\x8c\x6b\xb9\xa5\x45\x6b\xb5\xe6\xad\x13\x5c\x4d\xd8\x2a\x51\x1c\x24\x18\xe8\x6c\x57\x86\x79\x8a\xf4\x03\x0d\xe7\x5d\x88\x3b\x8a\x63\x50\xd4\x29\xb3\x3f\x0e\xf3\xd6\x6a\xf8\x97\xae\x02\x19\xd8\x10\x51\xe2\x00\x86\xfc\xdb\x6d\x5b\x45\x31\x5b\x9b\x0c\x23\x2c\x3f\xef\x28\x3c\xb3\x28\x71\x9d\xc0\x37\x96\xa4\x59\x10\x47\x0a\x58\x6d\x2f\x81\x21\x44\xe4\x19\x11\x0f\x3a\xb3\x57\x8d\x24\x2c\x58\x94\x88\x88\xf5\x83\xf1\xaf\xc5\x27\x42\x56\x8b\xa6\xde\x97\x8d\x5d\xd4\x22\xca\x7d\x0c\x3b\x7f\x42\xa9\x52\x76\xfa\x77\xe6\xd3\x90\xf7\xe8\x7b\xd2\x4c\xa4\xf9\xb1\xef\x68\x0c\xdc\xaa\xa9\x7f\x7b\x2f\x96\x41\x8c\xce\x2c\xe2\x41\x77\xfc\x54\x14\xd9\xa8\x40\x42\x77\xe4\xbe\x8b\x31\x94\xd7\xd9\xdb\x52\xd1\x75\xd3\xb2\xce\x27\xe8\x2a\xee\xda\x7e\xdf\x6e\x83\x11\x87\x84\x77\x36\x2b\x1a\x1d\xad\xcd\x31\xfc\x12\xc2\xf5\x91\x32\xcb\xf2\xf7\x9b\x8f\x30\x49\xbd\x6b\x0f\x8a\x34\x33\x3e\xf2\xe6\xaf\xcb\xe3\x24\xe4\x96\x45\x42\x90\x38\x36\xb1\xe7\x97\xf9\xae\xc8\x84\x95\xf2\xf6\xcd\x7b\x00\x27\x44\x17\xfa\x09\xf2\x75\x53\x2f\x4e\xe9\xa5\x7a\xeb\x94\x1e\xee\x4c\x2f\xf0\x14\xa3\xac\x55\xee\x82\x2c\x1b\x3d\x1a\x10\x0f\xeb\xf6\xd2\xfc\x93\x0a\xd8\x64\x34\x87\x5b\x9e\xa8\x5b\x67\x2c\x02\x1e\x49\x30\x5a\x82\xba\x44\xf1\x96\x35\x48\x75\x8e\x5d\xa6\xca\x29\x68\x56\x02\x15\x57\x03\x52\xe8\x54\x11\x75\x3f\x2f\x52\xe2\xc1\x02\xb2\xf4\x13\xca\x59\x7e\x84\xac\xda\x2e\x1f\x26\x38\x70\x47\xf7\x13\x7b\x31\x20\xc8\xbd\xf5\x55\x7f\x0d\x91\x95\x64\x74\x37\x1e\x55\x4b\x77\xa5\x2a\xa7\x90\x7c\xf2\xb7\x51\x17\xae\x6a\xa2\x9b\x1c\xf3\x6e\xd3\x86\x4b\x4c\x28\xc5\x30\x61\x8d\xf3\xa7\x67\xa7\xc7\x44\x42\xec\x77\xf5\xf0\x8f\x00\xfb\xe2\x86\xdf\x99\xc5\x01\x88\x04\x39\x75\x75\x2c\xbc\xbf\x4a\xc5\xa1\x03\xa1\x18\x18\x07\xfb\x53\x59\x34\xc7\x13\xb2\xf6\xb3\xec\xde\x5d\x85\x6e\xe8\x25\x66\x41\x40\xf6\xa5\x67\xa0\x36\xd6\x62\x3a\x05\x02\x55\xae\xb4\xd9\x84\xe3\xf8\xc1\xd8\xf1\x69\xa1\x92\x6f\xdf\xbc\xee\x50\x10\x34\x91\x5f\x1f\x7e\xbf\x05\xfe\xb2\x38\x0a\x23\x4c\x51\xfd\xf7\xf3\xfa\xbd\x3f\x9d\xe3\x28\x12\x52\xe8\xfd\x04\x6b\x92\xf5\x17\x1a\xb3\x5c\x0c\x1f\x29\x8a\x39\x52\x95\xfc\xfe\xaf\x05\xc2\x02\x47\x57\x8b\x39\x41\x3b\x9a\x35\xd7\x55\x0d\x67\xf7\x37\xfb\x3b\x33\xf5\x12\xcb\x5f\x3c\x6b\xc4\x88\x12\x8e\xc5\xd4\xe5\x98\xdc\xa9\x3d\x74\x98\x27\x20\x30\x6d\x97\x40\xc7\xae\x9f\x1a\x5a\x8a\x94\xe6\x13\x01\xe6\x98\xfa\x21\x38\x96\xbc\xb9\x13\x77\x3e\x77\x27\x8a\xd4\x1e\xad\xca\x01\x9e\xe8\x19\x9e\x53\x21\x6e\x5e\x1d\x95\x61\xc0\x10\x57\xb1\x5f\x6e\x1f\x67\x8b\x25\xc2\x98\x66\xa8\xa7\xb0\xdc\x2e\xdc\x30\x30\x27\x64\x4e\x82\x90\xc6\xed\xf2\xe1\x69\xf5\x62\x7f\x75\x19\x27\xbd\x61\x33\xcb\xc5\x63\x59\x68\x6c\xea\xf7\x35\x31\x2c\x66\x61\x88\xe5\xd5\x02\x6e\x25\x9c\x4d\x17\xc6\x40\x6f\x9e\x77\x66\x3b\x8f\x15\x4c\x79\x20\xf9\xf4\x17\xfe\xc3\xf0\x36\x38\x57\x08\x45\x85\x65\x30\x56\xf7\xe8\x2a\x42\x55\x26\x9b\x35\xf9\x3d\x57\xe4\x29\xb5\x45\xc6\x8f\xce\x29\x02\x1e\x76\xca\xfe\x45\xde\xba\x4b\x8a\x3f\x5c\x27\x60\x74\x47\xe1\x70\x03\xa3\x5d\xf1\x42\x11\x53\xf4\x3e\x34\x10\x55\xcd\x8e\x70\xe2\xde\xef\xd2\x73\x88\xd7\xbb\x9f\x83\xec\x8a\x21\x58\x2c\x23\x8a\x41\x42\x8d\x3c\x7d\x2d\x72\xb8\x0e\x62\x2b\xb1\x8c\x13\xcc\xb4\xaf\xff\x2c\xf2\xc1\x16\x98\x38\x2e\x35\xa1\x65\x0c\xe7\x68\xd1\x91\x81\x2f\x9a\x38\x41\x80\x53\xe4\x9c\xe6\x56\xde\xb2\xfd\x95\x21\x76\x6c\xbf\x9c\xbd\x0e\xc8\x91\x59\xe2\x30\x25\x19\xd6\x79\xef\x4f\xc5\x68\x8c\x0c\x5e\x78\xe2\x7a\xaa\x36\x0c\xf9\x7b\xce\xb0\x4f\xb3\xcc\x0a\x18\xb3\xc4\xf5\x5d\xcd\x4a\xc6\x8b\x5c\x2c\xe8\x65\xd9\xa3\xe5\x35\x7d\x12\x55\xd5\x8a\xfb\xa1\xc9\xff\x75\x32\x3b\x2c\xf1\x1c\x8a\xf9\x54\xe3\x01\xe8\x75\xdf\x44\xfa\x86\xf7\xe3\x05\x0c\xc3\xfd\x3a\xd3\xd1\x29\xca\xd9\xb3\xb1\x18\xfd\x8a\x13\xad\x4e\x3d\xfa\x4c\x96\x78\x3c\xc2\x30\xb9\xf2\xbb\xe7\xcd\x75\x1a\x5c\xf3\xed\xde\x9a\x04\xbe\x23\xe2\x1b\xdf\x6d\x7c\x12\x33\x6d\x92\x20\x94\x32\xea\x62\x0a\xab\xd1\x1a\x96\x84\x71\x12\x28\x68\xf0\x67\xf1\xd1\xab\xb7\x30\xcd\xd4\xa1\xba\x98\xa6\x5d\x39\x2a\xac\x41\x1f\x5f\x23\xe4\x0e\xe2\x98\x29\x2b\x4a\xec\x36\xbd\x43\x24\x11\x57\x4c\xeb\x8b\x34\x2b\x7e\x99\x2b\xc4\x9e\x92\x59\xc6\x04\x46\x55\xa7\x35\xee\x03\xf3\x49\x4d\x50\x96\xc4\x41\x82\xa3\xfd\x25\xad\xeb\x0c\x76\xed\x56\xd3\x95\x60\xd8\x53\x06\x8a\x61\xaa\x35\x39\xdf\xe0\x48\x6b\x04\xd1\x0e\x6e\x25\x4e\x22\xd4\xb7\xaf\xce\x34\xcb\x16\xf4\x82\x36\xee\xd8\x76\x4d\x12\x37\x52\xeb\x81\x82\x5b\xf4\xc8\x83\xa7\x23\xe7\x49\x42\x9d\x58\xbf\xed\x97\xcb\xaa\xfa\x59\x94\x1f\xad\xc9\x3c\xec\x23\x58\x48\x6d\xa8\x54\x23\x39\xec\x78\x4e\xa4\x8f\x90\x0c\x4e\xcb\xb5\x34\x34\x7f\x77\x2e\x26\x7d\xd0\xf0\xd0\x55\xb5\x6f\xca\xfc\x81\xd6\x74\x47\x3f\xfb\xd5\x68\x2c\xa1\x81\x12\xbc\x3f\xe0\xfc\xc9\x60\x86\x44\x0c\x2a\x22\x60\x67\x31\x8d\x14\x99\xbf\x66\x94\x51\x80\x83\xf5\x27\x94\x65\x2a\x60\x35\xad\xf1\xcd\x12\x16\x05\x91\x71\x42\xf6\xdb\xd9\xdb\xee\xd1\xb2\xb7\xb2\x84\x81\x62\x47\x7b\xa2\x39\xc5\xaf\x33\x53\x5b\xfe\x65\x8c\xc6\x4b\x38\x23\xaa\x5c\x28\x4f\xff\xa3\x71\xb1\x76\x68\x71\xe1\x60\xa4\x5c\x49\xbb\xce\x84\x50\x1c\x0c\xed\xd8\xa7\xfc\x46\x14\x82\x25\x1c\x1c\x55\x3e\xa4\x72\x71\x06\xd3\xd3\xab\x63\x65\x09\x38\x81\x40\x45\x08\xa8\xdb\x55\xf8\xbe\xfe\x1a\x4b\x20\x70\xd0\x44\x96\x69\x56\x0f\x2e\x5b\xf5\x5f\x31\x24\x31\x73\x6d\x6e\x5a\x13\x83\x77\xc8\xcb\xdb\x2c\xf8\xf0\x9e\x41\x28\x67\xb4\x2a\x64\xbd\xa0\x17\x43\x18\xa6\x5b\xa5\x20\x9a\xf5\xe3\x99\xd6\xfc\xb4\xce\x0d\xcf\xba\xee\x40\x1d\xc7\x4d\xb4\xd2\xf2\xbc\xb5\xe5\xc6\x38\x0e\xea\x50\xc5\x73\xb2\xbc\x0e\xd6\x77\xea\x30\x47\x91\x7f\x0b\xf1\x06\x5f\x0b\x5a\xc3\xb1\x5d\xed\xb4\x65\xd4\x77\xa0\x06\xf7\x4b\x5d\x57\xc7\x56\xd7\x6f\x3f\x96\xdb\xdd\x6a\xfd\x76\x78\x58\x2e\x56\xaf\xb3\x97\xc3\xe3\x6c\xb1\x5f\x1b\x94\x3b\x75\x81\xf8\x1d\xd7\x3b\x92\xaf\xa4\x7f\xa2\x86\x26\xa3\xfc\x63\x52\xec\x75\x14\xeb\xa5\x9e\xce\xaf\x23\x40\x2b\x47\x7e\x2f\xf8\xc6\x1c\xa7\x5e\xe2\xb9\x4a\x02\x30\xd7\x8c\xa2\xd3\x5f\x96\x7a\x22\x42\x61\x96\x97\xa2\x14\x7f\xf4\x48\x1c\x18\xf5\x40\x98\xf7\xf9\x4a\x8f\x29\xd7\x09\xc1\xe1\xe1\x81\x9f\x38\x8a\x78\x1e\x51\xed\xad\x73\xa8\x91\xec\xe6\xc3\xd1\x80\x25\x8e\x2e\xf2\xd1\xdc\xac\x87\x42\x1e\x1e\xe6\x66\x6f\xa6\x61\x18\x98\xb0\xd4\x43\xc1\x47\x17\x08\x45\x8c\x7e\x4e\x5f\x89\xd1\x52\xc0\x32\x1a\xf9\xdc\x35\xbc\xfb\xeb\xf5\x70\x12\xd0\xd6\x83\xd7\x9a\xf8\xad\x57\x5e\xba\xf6\x28\xc9\x71\x79\xaa\x8f\x43\x64\x0e\x8d\x99\x86\x06\x22\xf7\x47\xbb\xad\x69\x07\x7b\x02\x3c\x44\x63\xa9\xd0\x2b\x58\x14\xb2\x2f\xac\x75\x3a\xfd\xa2\x93\x90\x20\x00\xa7\x52\x36\x4f\xa5\x6c\x49\x64\x97\x95\x94\x8f\x8a\x9f\x89\x39\x28\x09\x69\x60\x2a\x8e\xab\xce\xb4\xd2\xcd\xd4\xe3\x81\xe6\xa1\xfe\x4f\x43\xb3\x54\x5e\xe7\xe9\x14\xfc\x82\x52\x96\xa0\x3c\xc1\x63\x53\xa9\x69\x3e\xb9\x92\x52\xca\x18\x6e\x92\x48\xab\x39\x00\x33\x51\x26\x1c\xd7\x70\x61\x2b\x0a\xc8\xd1\xdb\xe0\x0e\xc3\xc0\xde\x27\xe0\xb4\x57\xc9\xf7\x85\xe2\x2c\x49\xd9\xfd\x38\x81\x39\xdc\x8b\xd0\xf4\x60\x54\x1c\xff\x22\xc9\x46\x81\x03\x53\x56\x32\x2f\xa1\x67\x71\x50\xe9\xa9\x9a\xb9\x76\x96\xec\x8b\xef\x6d\x6d\x2a\x89\x44\x6a\xaa\x43\x45\x25\x3c\xd2\xcc\x42\xa1\xa8\xe4\x31\x4e\x9e\xe5\x25\x45\x66\xc6\xfe\x6a\xc1\x1c\x9f\x22\x00\x11\x68\x99\x5d\x8d\x90\xcf\xc3\xfb\xe0\x6d\x31\xc7\x97\xe8\x3b\xfe\xd0\x8a\x7d\xc8\x89\xa3\x09\xec\xa7\x1f\x8a\x39\xe0\xea\x84\x24\xd6\x20\x6b\xd3\xcb\x9c\xd0\x25\x8a\x3c\xee\x7c\x45\x32\x46\xfd\xab\xe7\x48\x25\x32\x58\x34\x59\xb5\xeb\x72\x35\xcc\xf3\x54\xd5\x9d\xad\x2e\x7b\x28\x9b\xe3\x6d\xf4\x81\xf9\x82\x73\x1b\xfa\x58\xe5\x9f\x9a\xd0\xc9\x0c\x30\x46\x78\x24\x90\xec\x79\x5f\xa6\x03\x81\x43\xc6\x02\x97\x22\x10\x69\xf9\xb0\xfc\xe3\x6f\x11\x41\x30\x16\xc6\x01\x33\x74\x48\x06\x5d\xc6\x42\xce\xd1\x9e\x17\x90\x21\x86\xf4\xbb\xf2\x68\xc6\x22\x07\x02\xa2\x19\xfe\x94\x06\xb4\x19\x2b\xf6\x9e\xa3\x30\x46\x12\x41\x8c\x3b\x3e\x29\x3e\xa2\x1b\xe6\x5d\xc6\x62\x37\x20\xc6\x1f\x41\x31\xd6\xbe\x37\xd0\x6e\xc6\xae\x76\x69\xff\x98\xc8\x73\x0e\x6c\x7f\x96\x48\x89\xc5\x06\xe8\xab\x18\xf0\xb6\x6e\xa3\x9e\xc0\x91\xa0\xf6\xc4\x55\xfe\x99\xa2\xec\xc6\xd7\x58\xed\x97\x31\x46\x88\x16\xa1\x3f\xa7\x39\x4e\x9f\xd1\x1d\xf3\xc0\x61\x41\x2f\x9a\x64\x82\x3e\x1d\x30\x94\xf1\x44\x91\x9e\x5c\xa0\x4c\x0b\xb1\x5a\xac\x11\xd2\x68\xdf\xb5\xf0\x95\x5e\xcc\x6c\xbb\x3f\x2c\xd6\x6f\xfb\xed\x6c\xb1\x3f\xcc\x1e\x1e\xb6\xcb\xdd\xce\xf6\x09\x12\xac\x9b\x3d\xab\xd0\xd0\x90\x39\x84\x31\x11\x13\xb0\x23\xc6\xf8\x10\x68\xdd\xf7\x54\xbc\xdb\x6e\xb1\x02\xcf\xae\xe7\x6b\xfb\x5b\x6b\xb3\xa3\x7d\x63\x9c\xdb\x29\x72\x12\xc6\x04\x53\x09\xc3\x13\xad\x96\x79\xd1\x1c\x4f\xca\x36\xec\x68\x59\x47\xc3\x0a\x42\x4f\xa5\x02\x14\xe1\x25\xd4\xcd\x8d\xe2\xfe\x30\x8d\x30\x3d\x01\x81\x72\x64\x7e\xc8\x90\x76\xde\xea\x4e\x98\xbb\x97\x81\x8f\xbb\x7d\x5a\xa9\xf2\xf5\x71\xc9\x1e\x93\x81\x7a\x33\xa8\x51\xba\xab\x5b\x0b\xcf\xcc\x47\xee\x84\x34\xd1\x34\x78\xbb\x31\x33\x1f\xe3\x8e\x04\x5f\xf1\x34\xcb\xe2\x55\x05\x97\x87\x1d\x3c\x22\x10\x1d\xbb\xfa\x63\xaf\x13\x8d\xd3\x50\x49\xee\xbb\x5c\x51\xcb\xc1\x27\x64\xc5\xa5\x9b\x15\xdc\xf7\x5c\x2c\xb5\x95\x45\xc9\xd2\x1b\x1d\x91\xe1\x80\xe6\x7e\x18\x60\xac\x99\x35\xba\x4c\x4c\xb3\xaf\x4c\x2f\x5d\xdc\x8f\x03\x53\x9f\xd5\x0c\x0b\x90\xb8\x4f\x7d\xf4\xbb\x9f\x7e\xee\xbb\x88\xb1\x6e\x23\x8e\x87\xf0\xf4\xfd\x7a\x3f\x7b\x39\x6c\xb6\xcb\xd9\xcb\xcb\x7a\x81\x32\x0e\x5d\x17\x69\x80\x8b\x7a\xac\xbc\xaf\xf2\x3a\x1e\x57\x6e\x0f\xbe\x68\x6c\x8e\xf5\xa5\x92\xe6\xc5\xd9\xfd\xed\x5e\xc0\x49\x28\x3d\xed\xaf\xfc\xb3\x81\xaa\x5d\x03\x6f\x89\xc5\x19\x27\x94\x22\x98\xae\x3a\x15\x5f\x6a\xf6\xdd\xd6\xc4\x33\x1e\xf8\x1e\xae\x51\x58\x56\xff\xc8\xcd\x9c\xe0\x01\xf1\xa8\x11\xb1\xdb\x34\x2c\x4b\xf9\xc4\x56\xcd\x83\x48\xa0\x33\x71\xf8\x7b\xe0\x34\x9d\x26\x9e\x3a\x51\x1c\x03\xf4\xaa\xdd\xef\xc6\x92\x79\xc0\x29\xf2\xa5\xcb\x26\xcb\x50\x89\xb4\xdd\x29\xe6\x45\x2e\xaa\xf1\x93\x49\xa5\x60\xa8\x05\xed\x91\x49\xa4\x9b\xf4\x3c\x0c\x12\xf4\x37\x75\x90\xa5\xda\xa7\x59\xf6\x56\x7c\xd9\xe6\x88\x09\x50\x55\x82\x87\xfd\x6c\xf7\xfb\xe1\xc7\xec\xe5\xdd\xa4\xd0\x78\xec\x48\x25\x6d\x62\x7f\x08\x44\xd0\xcb\x0c\x58\xf7\x65\xa3\xad\xb9\xd1\xd0\x8f\x43\x81\x99\xb2\x99\x10\x8a\x7b\x09\x6b\x2b\xfb\x51\x61\x1e\x27\x8a\xe6\x63\xbb\xfc\x61\x2f\xd2\x9a\xb0\xb8\x83\x66\x29\x4f\x6b\xba\xa1\x47\x94\xb1\x2b\x46\x4f\xce\x62\x92\x74\x3c\xbd\x8f\x70\xef\x2e\x98\x90\x11\x6e\x05\x5e\xa2\x06\xa9\x6b\x1a\xc0\x35\x8b\xf7\x02\x32\x60\x58\x85\x38\xbc\x06\x8f\x12\x54\x55\x7f\x2d\xf8\xc7\x03\x8c\xd7\x17\xce\xa5\x83\xb0\x7e\x6e\x79\x7d\x8d\x3d\xcb\x21\x81\x88\x0d\x5f\xd5\x9d\xa9\x0a\xd2\x53\xa4\x37\xe9\x31\x5f\xe7\x76\x2a\x4a\x5f\x45\x2e\x5e\xbe\x05\x91\x73\x19\x44\xa1\xd3\x07\xa4\xfd\xbf\x42\xab\x72\x19\x27\x48\xd7\x23\xd2\x4f\x8d\xe6\x1b\x15\x6a\x73\xc9\x85\x91\x9f\x9d\x2b\x0a\xb6\x9e\x31\xc4\x25\x38\x18\xc7\x7a\x4c\x07\x95\x49\xc2\x71\x42\x2c\xdb\x32\xea\x32\x38\x96\x95\x0f\x5f\xd9\x3e\x4c\xe1\xa7\x71\xff\xda\x5d\x20\xaf\x37\x8a\x0b\x65\x70\x8b\xc2\xe1\x80\x7e\x8d\x0d\x51\x29\xc1\x2a\x8c\x53\x35\x1d\x4d\x03\x13\x6e\xe0\xa1\xb5\x71\xc0\xb8\xa6\xb5\x76\x1f\x34\xee\x6d\x78\x56\x37\x56\x9e\x8e\x42\x52\xf5\x36\x99\x51\x78\x47\x78\x6e\x84\x59\xb7\xc5\x6c\xf5\xd0\xad\x9b\x93\x26\x91\xf0\x02\xcf\x57\xfc\x80\xc5\x4c\x88\x2d\x7c\xa6\xf0\x35\x1e\x97\xc2\xa3\x49\x18\xe8\x7a\xc5\x37\xf8\x85\x92\xb7\xc3\x42\x3b\x8f\xfc\xd7\x9d\xff\xd7\xa7\xf0\x1d\x4e\x15\x39\x60\x55\x8f\xb0\x32\x82\x50\x4a\x6c\xa9\xd4\x41\x95\x6c\xdf\x61\xc5\xd2\x47\x04\xc4\xe7\x5a\xa3\x9e\xef\xd3\x33\x88\x7f\x36\x45\x17\x52\xfb\x7e\x00\x89\x20\x48\xb0\xf4\x82\x17\xb9\x4c\xcb\xb3\x2a\x42\x3f\x0c\x59\x05\x44\x3b\x56\x89\x59\xff\x37\x59\x51\xdb\x82\xa6\x9b\x95\xd0\x1e\x91\x20\x8a\x21\xe5\x77\xd9\x91\xc6\x7f\x6f\x57\x53\x11\x50\x82\x05\x59\x8a\xa8\xc9\x70\xf8\xdc\x10\x4d\x33\x11\x80\x8f\x6b\xcf\xa5\x35\xa1\x7c\x0b\x3f\xd4\xad\x91\xab\xf8\x05\x4f\xb4\x7a\x4d\xab\x0a\x04\xaa\x9a\x5f\x8a\x34\xaf\x77\x0d\x33\xb0\x7d\xd3\x39\xe0\x08\x03\xa8\x20\x17\xaf\xb4\xfc\x80\xf6\x9a\xb3\x5c\x6c\xdf\xb6\xb6\x0b\x57\x55\x73\xad\xf1\x3d\x98\x35\x89\x17\xab\xdc\x78\x71\x3e\x17\xf9\x83\x7e\x89\x93\xcb\x07\x5a\x70\x48\x65\x25\xd2\xfa\x89\xde\xc1\xbe\x89\x24\xe2\xa1\x30\x89\xf3\x2f\xf8\xb5\x43\xb5\xb9\xa6\x1c\xa2\x19\x05\x75\x08\x12\x27\xd1\xa6\x2e\x14\xf1\xa8\xb9\x25\xea\x52\xc4\x5c\x4a\x2c\xba\xd3\x62\x55\x7b\xa0\xe7\x2d\xf0\xf4\x92\x76\x1e\x9f\xa0\x9e\x8a\xeb\xcf\x9f\x57\xaf\x83\xa7\xa2\x04\x40\x87\x53\x95\xd6\xb9\x76\xc5\x8a\xb2\xb2\x3e\x77\x35\x60\x04\x63\x82\x8a\xb0\x47\x32\x32\xf0\xe8\x04\x73\x44\xa2\x2b\xe3\x11\x74\x39\xb8\x18\xf3\x7d\x83\xd2\x7e\xd3\x6b\xcf\x83\x62\xb2\x10\x0f\x40\xb3\x6a\x53\x16\x1a\x34\x6b\x8f\x88\x9c\xc4\xf0\x42\xf5\xaa\x8e\x47\x2f\x92\x71\x47\x11\xe2\xea\xe9\xa6\x8c\xb1\x2d\x18\x92\xa9\x61\x6f\xee\x04\xea\x7d\x56\x15\x94\xf5\xf2\x3f\x5e\xa8\xb6\x20\xcf\xcc\xe8\x91\xdf\x22\xb8\x50\x91\x19\xc5\xb3\x75\x4a\x2f\x93\x00\x63\x21\x3c\x2f\x71\x74\x60\xad\xb5\x7c\x7b\x79\x6f\xd3\x23\xf0\xd1\x77\x55\x02\x32\x48\x74\x45\x07\xe2\xed\x6d\x17\x15\x5f\xbf\xe1\xad\xfc\x8b\xa9\x2e\x98\xaa\x10\xe5\x34\x37\xe6\xd0\x4a\xbe\x4c\xd8\xdf\x42\xb4\xd6\x2f\x8e\x63\x8a\x65\xfe\xe6\xca\x40\x5c\x70\x6d\xe8\x74\xdb\xb3\xae\xff\xed\xff\xcf\x84\xbe\x55\xf4\x3f\x23\xa0\x5a\xfc\x6f\xd7\xfc\x14\x6b\xed\x57\xfd\xfb\xa4\xb8\xdf\xe0\x58\x93\xd5\x12\x10\x83\x21\xb2\x7c\xda\xec\x4e\xb4\x3a\x6d\xb1\x7a\xb5\x9f\x18\x11\x32\x0c\x95\xbb\x7d\xa6\x65\x7d\x8f\xa7\x32\x36\x9d\x99\xc0\xa8\xa2\xd2\x40\xa9\x60\x6c\x5f\x83\x93\x04\xa8\x1a\x83\x6e\x69\xbb\x0e\x99\x06\xd7\xf1\x31\x3b\x7c\x50\x3c\x28\xbf\x8f\xb1\x4e\xe0\x25\x0a\x4c\xa6\x7f\xd5\x90\x8f\xea\x94\x5e\xcc\xf7\x04\x8f\x0a\x5c\x71\xb2\xe2\xf8\x9e\xa7\x9f\x50\x56\xf0\x58\x94\x1f\x20\x16\x14\x69\xbe\x4d\x37\xa1\xf4\xf6\xd5\x96\xb0\x96\x5d\x96\xa8\x3b\x93\x74\x62\x63\x19\x15\x55\xfd\x58\x94\x5b\x03\x87\xd4\x8f\x0a\xbe\x27\x98\x2a\x25\x56\xb1\xd9\x7e\x9e\x1e\x7c\xa1\xe8\x1e\xda\x1d\xf8\xa1\x2c\x72\x78\x00\x49\x9b\xac\x9e\xe9\x2a\xf5\xc1\x78\x02\x42\x13\xc7\x1f\x52\xc0\x8c\x53\xac\x40\xa4\x42\xe0\xb2\x82\x96\xa2\xbd\xa7\xdf\x6c\x83\xc2\x0b\x20\x5f\xd1\x99\xa6\xf9\x2b\xcd\x1b\xfb\x20\x81\xab\x2a\xcd\xcd\x96\x66\x7f\xf7\x5c\xac\xa7\x4a\xf3\xd6\x74\xab\x60\x5c\xde\x3d\x39\xf7\x21\xf0\xbc\x44\x53\x8a\x9a\xb4\xb8\xa6\xed\x1e\x7e\xab\x20\x09\x41\x91\xe7\x20\x5c\x10\x17\xb7\xdc\x56\xdd\x40\x00\x89\xdf\x39\x59\x8a\x21\xe0\xf0\xbe\xd9\x2c\xb7\x88\x97\x32\x68\x2d\x08\x89\x22\xfe\xe9\xb0\x21\x16\x06\x38\x9e\xa8\xc3\xeb\x87\x01\x78\xb4\x23\x29\xf8\xad\xfb\x99\xd8\xca\x6e\xbd\x21\xb5\x2b\xdd\x5f\x54\xc9\x42\x28\x08\x8e\xab\xd9\xf6\xf7\x3d\x3d\x1e\xa1\x3c\xb8\x07\xc7\xb1\x67\x05\x8e\xb8\x90\xb7\xf7\x97\x97\xc3\xf2\x6d\xb1\xfd\xd7\x06\x75\x67\x67\x2f\x4f\xeb\xed\x6a\xff\xfc\x7a\x58\xd9\x27\x8a\x92\x18\xa1\x61\x79\x91\x3f\x36\xf9\xb1\xb5\xca\x46\xb5\x7a\x10\x6b\x09\xff\xff\xe5\xe5\x7b\x25\x7a\xa8\x03\x88\xb9\x87\x81\xd7\x61\x76\xf1\x36\xa6\x68\xba\x4b\x3f\xf2\x6d\x94\xe7\xe7\xcb\xab\xc2\xd2\x8e\x3e\x55\xe2\xc4\x18\x72\x02\x64\xc8\x52\x02\x18\xa6\x29\x56\xa5\x6a\xcf\x45\x53\x1e\x33\x5a\x55\x3f\x3c\xdb\x24\x68\xa2\x7d\xd3\x39\x54\x35\x82\x72\x4c\x1b\x05\x8a\x25\xea\x19\xad\x6a\x05\x3d\x53\xa1\xa5\xfe\xf0\xa3\x52\x55\xac\xe0\xb6\xf5\x07\x66\x09\x4d\x13\x8f\x14\x75\xd4\x99\xfe\x9a\x03\xd2\xd7\x3f\x74\xf9\x21\xe0\x2c\xc4\x68\xf0\x6e\x3f\xdb\xa2\x16\xff\x6e\xb3\xdc\xbe\x9a\x56\x11\x04\x4c\x91\xa1\xa5\x99\x78\xd8\x2d\x69\x75\x45\x03\xab\x4a\x8f\x7f\xf1\x89\x45\x98\x28\xa8\x86\x22\x22\x1a\xa8\xe4\x33\x00\xaa\x76\xb1\x1a\xaa\xba\x5d\x26\xa7\x6d\x0c\x00\xaa\x22\x1d\x5f\x56\xd9\xd8\x7c\x99\xfe\xde\x05\x92\x04\x89\xb6\x31\x94\x84\xea\xb4\x11\x2d\x1d\xe2\x3b\x83\xd3\x75\x22\x86\xa3\xd5\x41\x3a\x14\x90\xce\xe2\x21\x3d\xa6\x7d\x2b\x40\xba\x94\x62\xcc\x70\x59\x9f\x9e\x0b\x91\x41\xf9\xdb\x5d\x86\x09\xe9\xca\x44\x73\x62\x68\x80\x43\x3f\xa0\xa1\xfb\x78\x89\x40\x02\x85\xe5\x27\xe4\xf5\x16\xab\x7b\xb6\x69\x35\xe4\x4d\xb4\x5c\x39\xe3\x17\x24\x7d\x12\x18\x99\xb2\x76\x60\xfb\xc4\x7c\x75\xe9\x13\x30\x92\x17\xef\xcd\x98\xa7\x42\xfa\x11\x27\x9a\x17\x46\x81\xc6\x27\xa7\xbd\x24\x7e\xa0\xea\x1c\xaf\xaf\x50\x9f\x0a\x31\x30\xed\x24\x89\x42\x87\x59\x95\x86\x0d\x94\x72\x24\xe9\xcf\x24\x11\x31\xf2\xcf\xcc\x9a\x76\x37\xa0\xdf\x20\xf9\x24\x81\xc0\xa8\xce\x6b\xc6\x4b\x1c\xcb\x5a\xae\xce\x3c\x56\x90\xb8\x98\xe3\xa0\x42\xbc\x14\x45\xcd\x8a\x3b\xf9\x62\x19\x50\x0f\xb1\x57\xe7\x34\x6f\x77\x1b\xc3\x87\x65\xce\x13\x82\x52\x00\xaf\xe0\x26\xca\x36\xba\xaf\xc8\x4b\x12\x66\xd9\x2b\x36\x46\xff\x24\x1f\xe9\xd6\x30\x19\x25\x3c\xe9\xeb\x38\x4c\xa9\xf1\x31\x19\x09\x0f\x15\x05\xab\x53\xd1\x64\xad\x23\x07\x65\xad\x38\x84\xea\xa6\xec\x57\xe8\xca\x48\x86\x8c\x76\x35\x49\x3b\xc8\x32\xb7\xb5\x89\xb4\x5e\x8d\x79\x92\xd8\x15\xa2\x5d\x95\xde\x36\xfb\xc1\x40\x8d\x35\x8d\xdd\x85\x5e\x6f\x06\x53\x6f\xc8\x1a\x3b\x51\xc6\x71\xa0\x23\xea\x02\xb9\xe2\x06\x83\xd5\x73\x86\x23\x3b\x96\x14\xef\x6d\x96\x9e\xd3\x6f\x22\x11\x32\xa1\xcc\x0c\x91\x4d\x09\x15\x64\xd9\xfb\x65\x5f\xf4\x6f\x9f\x72\x11\x7a\xfd\x24\x86\x32\xfb\xa6\xd8\x9f\x99\xa4\xd2\xc7\x09\xa5\xf7\xc8\x81\xa1\x2b\xb9\xef\xe3\x1e\xf9\xfb\xc3\xca\x9c\x9c\x13\x6e\xa0\x99\x3b\xbc\xfd\xbe\x21\x26\x85\x47\xb1\x4c\xae\x63\xe7\x33\x94\x3d\xd3\xcb\x91\x14\x1e\x60\x25\x01\x6b\xae\x73\x5a\xa5\xfc\x3d\x4f\x6f\x38\xe6\x4d\xd7\xc4\x35\x9a\x6a\x1a\x7e\x89\x42\x72\xe5\xa8\x36\x72\x8a\x9c\x92\x49\x41\x15\xa7\x00\x0a\xb2\x8d\xcb\xdb\x25\x78\x04\xa9\x73\xcf\x69\x8e\x0c\xe2\x18\x2f\x7b\x2c\x4a\xc5\x09\x76\xd2\xb9\x4c\x35\x3a\x5d\x2f\xb6\x4b\x1a\x50\x07\x5d\x40\x6d\x43\x0c\x05\x25\x99\x04\x29\x02\xae\xdf\x86\x22\x3d\xec\x11\x29\x49\x49\x58\xa8\x88\x79\xe8\xe5\x91\x96\xd3\x02\x50\x4c\xca\x20\xf4\x15\xf7\x39\xe5\xa7\xbd\xe2\xd2\x1b\xdd\xbe\x0c\xa4\xa2\x34\xca\x79\x71\xbe\x64\x50\x77\xd7\xe0\x11\x68\x92\xab\xdf\x26\x34\x15\xb8\xe3\xba\x2a\x02\xf6\x95\xe6\x79\x9a\x1f\x0f\xe7\x22\xaf\x4f\xbf\x99\x46\xc6\x14\xc3\x63\x71\x7c\x83\xaf\xdb\xa9\xc7\x1d\x57\x04\x48\xcf\xa2\xe9\xe2\x5a\x3b\xc1\xca\x9a\x4c\xda\x67\xdc\xf1\x22\x60\x7a\x00\x69\xce\xc1\xb2\xa4\xd7\x17\x45\xea\x3d\xea\x2a\x94\x08\xce\xa5\x04\x3b\xa0\xcc\xbd\xf9\x81\x1b\x44\x83\x91\xa6\xf1\x54\x07\xde\x93\xf4\x33\xbd\x09\x89\x22\x23\x29\xa9\x22\xc8\xa6\x81\x49\x54\xb2\x33\xf6\xca\xea\x8f\xfd\x8d\x7d\xd9\x9b\xa6\xdc\x09\x3c\xc7\xb7\xc2\xf0\xad\xbf\x88\xda\x24\x8f\x45\xf9\xd6\x9c\xff\x06\x54\x91\x3b\x61\x10\x71\xbd\x4f\x60\x41\x31\xcd\x7a\x91\xba\x6a\xf4\x06\xc2\x38\xf4\xf4\x4a\xb9\xa0\xf9\xbc\xb9\x76\xab\x19\x77\x22\x3f\x89\xfb\xf2\xda\x6b\x86\xfe\xfe\xf8\x1b\x45\xb1\xaa\xa8\xab\x20\x17\x07\x83\xb3\xbf\xa5\x04\x18\x5e\x38\x4e\x1c\x12\x1b\x97\x1e\x93\x6a\x18\xda\x37\x51\x22\xee\xc4\x94\xe1\x8b\x5b\xbe\xfd\x03\x1d\x28\xd9\xe4\xd3\xb8\x4a\xee\xc4\xa0\x56\xac\x3e\x8b\xf7\x06\xca\xdb\x14\x00\x77\x92\x84\x70\xd7\xe0\x08\x78\x59\x28\x73\x70\xaa\x2a\x87\x3b\x09\x53\x6c\x8a\x98\x2e\xd8\x01\x0a\x9c\xeb\x26\xea\xf8\x21\x33\xc5\xfb\x56\xd3\x82\x3b\xd4\xf7\x31\xe1\x38\xef\x74\x9d\xed\xf2\xde\xb6\xca\x58\x41\xa7\x2a\x25\x65\x37\xfd\x01\x69\xc0\x15\xf9\x57\x73\x5d\x75\xc7\x46\xaa\x9e\xe2\xa2\xb2\xf8\xcb\xfa\xf4\xb3\x53\x45\x34\x7d\xa8\xc0\x87\xcb\xe1\x17\xa2\xdc\xb4\x84\xd2\x6b\x9a\xcf\x15\xf3\xa9\xe9\xc8\x12\x25\x8b\xd8\x41\x1c\x61\xbe\x7f\x1a\x19\x54\xdc\x61\xc0\x3d\x69\x30\xc9\x9a\x3b\x40\x8b\x10\xe9\x1e\x3c\x54\x08\xfd\x59\x5a\xee\x4b\x2a\x65\xca\x7b\xb5\xf5\xc3\x59\xda\x73\xe8\x87\x5f\x8f\xc7\x8a\xb5\x7f\xa7\x0c\xdd\xc9\x55\x8a\x3b\xc2\x11\x08\x29\x9f\x09\xa1\xb5\xd8\x47\x5f\x4b\x10\x40\x4a\xfc\xed\xbf\xde\xd6\xfb\xa5\xb9\x41\x70\x1c\x9b\x96\x5e\xe5\x4f\x8d\xf9\xca\xb1\x69\xf7\x63\x2c\xd3\x47\x4c\xf8\x2a\xff\xd6\xae\xe0\x8e\x74\x7d\xaa\x15\xe8\xac\x52\xf1\x8d\x06\x1d\x77\x64\xc4\x50\xda\x38\x6f\xce\xc6\x57\xab\x6c\x1b\x57\x2c\x24\x66\x4e\x3d\xd3\x5c\x8c\xb6\x45\xee\x3a\x90\x38\x5d\x52\xe3\x2e\x9a\x88\xbb\x6e\x98\x50\x9c\x24\x2f\x6b\x9d\x9e\xe1\xae\xc7\x39\x2e\x45\xcf\x4d\x73\x46\x8a\xe2\x5c\xb4\x8e\xc7\xdf\x62\x58\xe3\xae\x1f\x78\x5c\xaa\x08\x6e\x4d\x79\x3d\x8c\x7f\xb7\xcd\x0c\x9d\xdf\x33\xba\x8e\x56\x6c\x8e\xbb\x7e\xec\xf9\x61\x07\xec\xd7\x78\x98\x9f\x3d\x7e\x26\xee\x12\x2f\x40\x35\xd3\x43\x21\x65\x96\xe6\xd0\xaf\x1c\x9d\xdc\x56\xb9\x4b\x02\xc0\x09\xf5\xd0\xd4\xdc\x6c\x93\x7f\x55\xc7\x39\x19\xb8\xb2\x67\x0c\x88\x4f\xac\x3c\x8c\x35\x0c\x7b\xba\xff\xdc\x0d\x79\xc8\x75\xc9\xc4\xa6\x4c\x3f\xd3\x0c\x8e\x93\xcc\x1a\x6d\x4f\x55\x10\x5b\x02\x2f\x46\xb8\x01\xee\x46\xc4\x41\xdf\x73\x83\x39\xff\xdd\x44\x49\x8e\xee\x18\xbb\x89\x67\xc8\x2e\x4f\x34\xcd\x7f\x16\xe5\x87\xb9\x97\xd8\x97\x58\xfe\xad\x90\x33\x1f\x90\xb7\xd3\x1e\x8d\x98\xc9\x75\xd5\x4d\xa2\x04\xa7\xf6\x8f\xb4\xac\x1b\x9a\x99\x08\xc5\xf4\x80\x76\x93\x24\x8e\x15\x69\x97\x42\x92\x0f\x86\x42\x22\x14\x56\x05\xce\x69\x3d\xc3\xe2\xae\xa7\xf4\xb3\x67\x36\x0e\xbf\x54\x22\x15\x83\x8f\xc6\xf1\xee\x6f\xb0\x27\xba\x1f\x73\x15\x92\x6b\x5e\xe4\x73\x43\x55\x3f\xbc\x29\xe4\x61\xea\xa8\x8e\x15\x79\xf9\xf8\xe5\x32\xce\xb0\x22\xc6\xcc\x58\x1d\x79\x9c\x88\x93\x72\x97\xcb\x50\x76\x1a\x0b\x48\x78\xb6\xab\x69\xdd\xf4\x30\x92\x6d\xa7\x08\x81\x9c\xcb\xfd\x73\x6a\x8a\x76\x74\x93\x08\x15\x45\x32\x02\x7f\x70\xa4\x3c\xf7\x3d\x1c\xee\x82\xa3\x18\x48\x0e\xb8\xcb\xb7\xc6\xc2\xcf\xdd\x6a\x31\xba\x63\x08\xc1\x28\x6e\xcf\x1e\xce\x69\x8e\x2a\x06\xed\xb0\xde\x94\xc5\xaf\xeb\xe8\x1d\x40\xac\x18\xfd\x31\xbf\x7e\x4e\xf3\xe9\xe1\x07\x94\x84\x6e\x5f\x68\x58\x2d\xbc\xa6\x15\x44\xa0\x20\x80\x2a\xd5\x76\x67\x0c\x48\x57\xc6\xb2\x8b\x13\x69\x2b\xde\x3e\x9b\x04\x2e\xd5\xd7\x50\xcc\xb8\x1d\x87\x38\x77\xa5\x54\x82\x59\x67\x05\x9f\xc1\x7a\x21\xd5\xe4\x39\x3e\x08\xed\x1a\x62\x72\x6e\x94\x77\x1b\x0e\x0a\xcf\x25\x21\xa5\xa6\xb6\xee\x3a\x7d\xa3\x9e\x1b\x24\xc9\x90\xb5\xbf\x19\x88\x9a\x73\xcf\x05\xe5\xce\x41\x7d\x52\xca\x83\xa3\x2d\xdd\xf3\x1c\x05\xf0\xae\x34\x2f\xde\x16\x2e\x45\x89\x62\x5a\x93\x23\xc7\xf3\xa8\x44\xd6\x08\xae\x87\x61\x3f\xf5\xc0\x3d\x4f\x7a\x80\x2a\xf2\x4d\x99\xef\x2e\x59\x5a\x0f\x22\x26\xdc\xf3\xa3\xc4\xd5\xfa\x0a\xed\xec\x69\xbd\x41\x5d\xb2\xf1\x98\xd2\x69\x2f\x84\x7b\x44\xb3\x4e\x5a\xbb\xf3\x07\x8e\x45\x43\xad\xfd\x5d\x04\x87\x7b\x24\x71\x4c\x1c\xb4\x35\x30\x84\xb5\x85\x8c\x3d\xea\x11\xcd\xd2\x3f\x87\xbe\x8c\x36\xf7\x42\xcf\xc3\x98\xc6\xcb\x7a\xf1\xfb\x61\xf7\xb2\xde\xef\x6c\x4b\x9c\x98\x04\xb9\x62\x6c\x30\x63\xf1\x36\x11\xcd\xbd\xc8\x09\x15\x59\x11\xb4\x7e\xc2\x83\x96\xd5\xdc\x97\x94\x7f\xa4\xf9\xb1\x23\x34\x6f\x7b\x72\xe4\x75\x50\x39\x9d\xc7\xa2\x74\x97\xf5\x69\xe3\xd9\xe6\x30\x44\x82\x5d\x4c\xae\xad\x9b\xd1\x6e\xef\x45\x10\xc4\x8a\xeb\xb2\x35\xb6\x07\xee\x35\xf7\x62\x4a\x91\x64\x73\x3b\xdb\x2f\x0f\x8f\xeb\xed\xe1\xe7\x72\xf9\xbb\x6f\x5b\x65\xa0\x4c\xf5\xe2\xc5\x8a\xe6\x73\x2f\x09\x43\xa4\x7e\x1b\xd2\x77\x3d\xc0\xa7\xcd\x91\x8d\xc7\x52\x12\x29\xce\xf2\x4b\x59\x64\x45\x7e\x7c\x1e\x37\x83\x9a\x00\x95\xf6\xf7\x2c\xcd\xef\xb7\xd6\xbb\x47\x69\x88\x08\x9f\x4d\xf1\x01\x5a\xb1\xca\xdc\x22\x05\x8e\xd1\xef\xb4\xda\xa8\x01\xf5\x06\x60\x0a\x69\x38\x52\x79\x69\x54\xb0\x1e\x86\x6b\x89\xdc\x0d\x23\x9b\xc1\x43\xb8\x1a\x7e\xe9\x9f\xab\x7f\x9a\xa3\x39\x17\x58\x6e\xf0\x91\xd6\xf5\x75\x51\x94\xf6\x23\xeb\x76\x41\x7d\xae\xb4\x23\x2f\x63\xc6\x5e\xee\x09\x20\x0e\xb5\xe1\x96\xd6\x47\x6a\x87\xba\x15\xe2\x1b\xbf\x38\xf0\x55\x75\xa0\x21\x33\x9d\xe2\x3d\xe7\x9e\x14\xdc\x0f\x06\xac\xed\x4a\x12\xb5\x19\xa1\xb4\xb8\xef\x04\x14\xab\xd9\x7a\xa5\x01\xe2\xad\xf9\x9e\x35\x8a\xfb\x4e\xac\xf0\xd5\x25\x06\x71\xe6\x50\xcf\x72\xd1\xb1\xc8\x6b\x18\x01\xf7\x3d\x17\xb0\xbe\x84\xf6\x69\x86\xb9\xef\x45\x01\x86\x85\xb5\xb4\xcf\x43\x9a\xa5\x47\xc8\x39\x0c\x3b\x25\x80\x63\xf8\x85\x56\xf5\x81\xb5\x26\xa8\xc1\x59\xd3\x5c\xe0\x0f\x75\x7a\x86\x43\xc7\x25\xc0\x7d\x42\x04\xde\x15\xce\x0a\x15\x32\x56\x32\x9d\xb6\x43\x12\x22\x20\x4a\xc5\x03\xfa\x57\x23\x1c\x9c\xa0\x97\xcd\x10\xbd\x9a\x02\xee\x13\x08\x99\x2a\x6c\x17\x3a\x93\xfc\xcf\x9b\xda\x31\xee\x07\xc4\xc1\x32\x37\x40\x68\x7a\x5a\xe4\x98\x57\x5c\x0f\xe3\x01\xdc\x0f\x92\x04\x23\x71\x3f\x56\x6f\x83\x5b\x88\x62\x55\x67\x60\x8c\x5b\x2c\xe8\x91\xed\x30\x1d\xe5\x44\xb9\x1f\xd1\x00\xd7\x46\x86\x92\x0f\x37\x31\x32\xee\x27\x22\xc6\x54\xb3\x86\x12\xcc\x72\xf1\x58\x94\x88\xce\x9c\x06\x5a\x4d\x83\xf5\x27\xad\x4a\x3f\x11\x14\xf7\x09\x46\x6b\x7e\xea\xe3\xfe\x74\x6a\xd0\x19\x1b\xda\x3e\x75\x03\x14\xa8\x59\xa6\xa2\xa8\x26\x21\x36\xb6\xa3\x02\x47\xbd\x41\x59\xd4\xfd\x77\x43\x65\x82\xd6\xe0\x53\xeb\x39\x0c\xde\x1a\xa3\x09\xe8\xa4\xde\x2b\xcd\x7b\x45\xc0\x63\x87\xcc\xe7\xc4\xc3\x84\xd5\xcf\x97\x57\x73\x30\xa7\x09\x2a\xd1\x9e\xd0\x8f\xd0\xae\x11\xba\xd2\x6a\x14\x4c\x5b\x61\x3e\xe7\x0c\xf7\xd2\x0c\x3e\x21\x7b\xbf\xcc\xaf\x1b\xc8\x8f\x4d\x7a\x63\x67\xf9\xc2\x27\x88\x85\xe0\x5d\x02\xb3\xfd\x51\x21\x79\xad\x51\x6a\x8a\x97\xc6\xa9\xa8\xd1\xcb\x11\x5c\x70\x65\x91\x54\x0d\x3c\x34\xed\xbe\xd1\x3a\xcf\xd3\xb7\x28\x24\xa7\x3a\xbd\xb2\x39\x2d\x7f\x71\xb8\x74\x74\x71\xf6\x4b\x02\xc4\xb1\x4d\xfc\x09\x80\xf3\x84\x8c\x14\xf7\xa5\xab\x92\x08\x47\xa8\x77\x59\x51\xeb\x58\x90\x69\x0c\x29\x91\x9d\xac\xa8\xad\x5e\x19\x9d\x22\x61\xb1\x8e\xcd\x2b\x2a\x91\xc7\x8c\x1e\xad\x8c\x88\xce\x26\x73\xe2\xc4\x4e\xa0\x4d\xf9\x47\x5d\x46\x32\x5c\x49\x89\x93\xc4\x98\xc2\x7d\x2d\x58\xaa\x17\xc8\x59\x66\xb5\x6c\x38\x71\xc3\x08\x3d\x56\x31\xa8\x8b\xbe\x83\x2e\xec\xb2\x12\x9c\x78\x8e\xe7\xb8\x1d\xbf\x16\xa6\x62\xa1\x7c\x2c\xca\x5d\xc3\xfe\x17\xc6\xfe\x32\xf1\x5c\x07\x49\x8a\xe0\xd7\x25\x2b\x4a\x58\xee\x9f\x2d\x7f\x2b\x27\x5e\x10\x62\x1d\xc6\xb2\x3e\xed\x81\x76\x52\x5f\xc3\xa4\x77\xff\x9e\xb4\x54\xc0\x48\xa2\x9e\x93\xd6\x46\x52\x71\x9e\x76\x9e\xb5\x4b\xf8\xae\x2e\xca\x6e\xf3\x20\x84\x24\xc8\x02\x72\x28\x69\xfe\x31\xbf\x4e\x14\xb3\x70\x42\x02\x4f\x41\x2f\x2f\xf4\xba\xd4\x91\x95\x59\x2e\x6c\x5d\x36\x8c\xfb\x87\x04\x0d\xf6\x87\xf2\x4a\x85\xbd\x50\xec\x61\xfe\xea\x40\xab\x2a\x3d\x2a\xe2\x8b\xf2\x3a\x3e\x92\x7a\x68\x51\xeb\xbd\xa4\xdb\xb6\x91\x32\x17\xd7\xa7\xe1\x01\x81\x74\xc2\x81\x66\xac\x89\xd7\x2b\x90\xe1\xd0\xf9\x24\xa1\x1b\x09\xa3\x88\x82\xd9\x19\xa5\x3d\xd5\x37\xa1\x48\xc8\x3c\x5c\xc7\xff\xd3\x80\x49\x88\x72\x12\x8a\x18\x01\x08\x4b\x2d\x4d\x31\xba\x8b\x88\xb8\x18\x5f\xc6\x24\xe2\xe6\x69\xd9\x5f\x5f\x48\xec\x84\x58\x90\x59\xb4\x76\x78\x6b\x69\xd9\x86\x28\xc1\x3a\xb3\xd9\xe3\x4f\x1c\x6b\xc3\x73\xc6\xb1\x8b\x7a\x4f\xa6\x6e\x17\x4b\x73\xe7\x57\x25\xe9\x34\xea\x0a\x91\x62\x14\x57\x6b\xf5\xbe\xff\x2e\xba\x5e\x34\x26\x2a\x6d\x59\xd3\x5f\x83\x1b\xa4\x2c\x0c\x75\xfa\x95\xd7\x96\x74\x85\x66\x87\x23\x06\x7d\xcb\x03\xfc\xa7\xc7\x5b\x34\x6d\x38\x11\xca\xa3\xc8\x10\xb2\x18\xf6\x84\x81\xa7\x3a\xdc\x03\x08\x05\x8e\xc1\xb2\x8a\xb6\x96\xea\xbc\x28\xb2\x2d\xce\xd9\xca\x8e\x4c\xe6\xf9\xbe\x76\x16\xda\x49\x30\x0c\x15\x0e\x47\x39\xf3\x22\x2c\x4f\x6c\x3d\x81\x59\x8a\xec\x7d\xbf\xdd\xc4\xbd\x4c\x5f\x4e\x3d\xc5\x17\xa2\x61\x21\x0f\x40\x45\x96\xe6\xdd\x75\xa5\x92\xef\x35\x1b\x39\x66\x61\xea\x6f\x4b\x6f\x38\xe1\x5e\xe4\x26\xaa\xd4\x11\x95\x3e\x6c\x29\x16\x27\x9c\x11\x06\x16\x59\x61\x52\xed\xed\x54\x7c\xc3\x20\x61\xaf\x80\x53\x1f\x21\xbc\x00\x2d\xcd\x07\xa0\xf5\x49\x15\x19\x1f\xd2\xd4\x9c\x4f\x10\xa1\x3c\x14\x23\xdf\x57\x8f\x43\xc2\x04\x02\x95\x2b\xfe\x48\xb3\x0c\x46\x4a\xc3\x6d\x6b\xe2\x5a\x45\x37\xac\xda\xb5\x2d\x91\xaa\xb5\x2d\xbb\x40\x3c\x81\x38\xc6\x88\x46\x93\xbf\xa4\xf9\x47\x7b\xdb\xaa\xbe\x44\x7d\x0f\x0b\xab\x98\xdc\x71\x08\x24\x02\xe3\xdb\x3a\x74\x64\x38\x65\x6e\x56\xab\xd1\xdb\x04\x50\x0b\xc8\x9a\xa5\x65\x73\xde\xd3\xcc\xc4\x63\x88\xa4\x31\x6e\xc1\x6a\x11\x99\xe5\x45\xbb\x1c\x4d\x64\x2e\x02\xd7\x21\xf8\x0e\x5f\xf7\x9a\x8c\x89\x07\xae\x1b\xc5\xb1\x41\xe9\x5a\xbe\x5f\xcd\x24\x6c\xb8\x7e\x27\x20\xf3\x3c\x70\x3d\xc5\x65\x63\xf5\xe6\xa7\x47\x41\xe0\x85\x2e\x82\x99\x0e\xe7\x74\xbc\x09\x06\x9e\x48\x30\xcf\x23\x01\x1e\x8b\x72\x56\xd6\x3f\x8b\xf2\x63\x61\xdd\x1d\x4b\xdf\xc5\x03\xdf\x53\xba\x95\xaa\xd1\x8a\xbe\x5b\x26\xc8\x78\x74\x55\xdf\x8f\x84\xb0\x2a\xc6\xb3\x3c\x2f\x9a\x9c\xdf\x02\xc9\x4c\x6f\xe9\xe3\xd7\x47\x09\xe7\x9f\x69\x2e\x8a\x2f\x6f\x68\xfb\x05\xc4\x0f\x10\xac\x9d\xa5\x12\x34\xc8\xb0\xf7\x96\x4c\x27\x01\xb8\x6f\x0f\x90\x20\x77\x63\x83\xc3\x7b\x20\x10\x0a\x13\x71\xa3\xf9\x27\xed\x53\x76\xf1\x20\x74\x00\x11\xeb\xb8\x02\x77\xf4\x65\x3c\x08\x49\x88\x01\x71\x2a\x44\x7b\x3f\x5f\xbd\xa1\x3d\xfc\xf8\x61\x48\x11\x4f\xac\xa5\x64\x87\x8d\x91\x07\xe8\x50\x1f\xd2\xea\xb1\x41\xf4\xe5\xf0\xe6\x22\xa2\xac\x53\xd4\x1d\xab\x8b\x2f\x28\x0f\x29\x4e\x52\xd3\x1e\xf9\x28\x30\xa5\xe7\x1f\xfd\x80\xb1\xcc\x12\x0f\x22\x29\x24\xb1\x98\xf4\x1b\xd6\x2b\x3b\xfe\x75\xf7\xd8\xa1\x7e\x60\x8b\xec\x67\xb9\xd0\x50\x46\x73\xc9\xd8\xf5\x13\x55\xb0\x4e\xcf\xba\x8c\x74\xf4\x50\x34\xf2\x31\xe6\xdd\xa5\x14\x74\xf6\xa1\x27\x7d\xc9\x03\x2a\x95\xc4\x6e\x5a\x59\xfe\xec\x17\x95\xd0\x30\x3d\x98\xcf\x90\xe5\xc3\x60\xd7\x7a\x95\xaf\x3c\xe0\xb1\xaa\x9b\x37\xc4\x4f\x8a\x31\x6a\x87\xc4\xc3\xb3\x2c\x53\xa0\x31\xd3\x37\x11\xb8\x04\xcd\x21\x13\x90\xf7\x33\x0b\xa6\x83\xde\x75\x2a\x8b\x0f\x7f\x04\x50\xe3\x51\x85\x85\xd2\xfc\xd8\x67\x2f\xd3\x87\x09\x47\x95\xa7\xfd\xde\xd0\x6f\xd2\xe8\x3c\x10\xa1\xad\xae\x45\x27\xaa\x7a\xcf\xeb\x34\x6b\x47\xf3\x78\xb0\x40\xe0\xe1\x36\xbc\xa0\xb9\xb8\xb6\x5b\xc7\xaa\x5a\x5f\xec\xee\x18\xc8\xc0\xf3\x89\x96\x99\x57\x0a\x0d\x69\x85\x13\x61\xdb\xfe\x6b\x7b\x51\x8e\x91\xdc\xb4\x5a\xf1\x02\xb9\xb8\xd0\xe9\x52\xad\xa1\xe3\x24\x8a\x60\x22\x85\x2f\xc5\x45\xd9\xfe\xab\xf0\x5f\x48\x8d\xd6\xab\x1c\xef\xcc\xc0\xd0\xa1\x0e\xfa\x60\xaf\xf4\xb2\xef\xd6\x87\xd0\x75\x14\xc4\xa4\x82\x7a\x99\xa1\x2a\xde\x2b\x88\xb4\x13\xc7\xe2\xa1\xeb\x45\x4a\x0b\xd2\xd0\xbd\xcf\xc1\xe0\x0a\x79\xe8\x25\x1e\xba\xc5\x34\xcb\xd6\x17\x28\xfb\x85\x8d\x3c\xf4\x24\xc5\x52\x01\x5a\x55\x50\x8f\xc9\xba\xda\x66\x89\x8c\x36\x02\x32\x18\x32\xa9\xea\x0e\x7e\x1c\x2b\xe6\x40\x2c\x83\x53\xd9\xaa\xea\x19\x32\xfb\x2a\x7c\xe6\x63\x71\xf0\x19\xce\x45\xa9\x72\xc3\xc3\x2f\x1c\x12\x2f\x51\x62\xe0\x8a\xd0\x0b\xd9\x37\x8d\xe5\x7b\x03\x26\xb5\xc7\x48\x0d\xea\xc9\x3b\xaa\xb1\xe9\x91\x11\x12\xa6\x89\xd5\x5b\xa7\xf7\xe1\xbd\xb5\x2d\xcc\xcd\x85\x24\x42\x1b\x5e\x29\x1a\x1c\x2e\x50\x1e\xfa\x4e\x64\x18\x52\x05\x9d\x9f\x67\xe9\x9f\x7f\x5a\xb6\x39\x1e\x46\x31\x0f\x49\xa7\xd7\xd3\xfd\x4e\x63\x53\xc1\xbd\xaa\xe1\x5c\x4d\xe1\x5b\x78\x18\x13\xa5\x92\x82\x22\x68\x3f\x8a\x1a\xde\x8a\x05\xad\x4e\xf3\x01\xa5\x66\xdb\x4d\xe2\x06\x72\x29\x2a\x5d\xf4\x3c\x82\x76\x8d\x99\x5f\x87\xbf\xf6\x8d\xdc\x30\x96\x5c\x90\xbe\x3a\x9a\x02\xdd\x8d\xa3\x9b\xc3\xfb\x4c\x20\x54\xfa\x19\x18\x88\x9e\x8f\x27\x52\x98\x80\xc0\x39\x30\x87\xb2\xbc\xbe\x74\x09\x9d\x90\x3a\x2e\x56\x41\xf0\xa6\x2e\xa4\xec\x51\xaf\xf0\x90\x79\x5c\x15\x00\x9e\x80\x7f\xa8\xf5\xe4\xa5\xa8\xaa\x5d\x9a\x73\x58\x69\x42\x47\xb5\x0f\xda\x23\xa2\x48\xbb\xeb\xe7\x34\x3f\xa4\xd5\x86\x5e\x31\x26\xde\xe5\x12\x42\xee\xba\x98\xc1\xa5\x4d\x5d\xec\x81\x96\x0f\xc5\x57\xde\xfa\x2b\x03\x9a\x53\x1e\x82\x1f\x23\x48\xf0\x5c\x88\x54\x5e\xdf\xe0\x57\xbd\x29\xe1\x9c\x36\x67\x9b\x2b\x1a\xed\xb4\x21\x10\x0a\x03\xc9\x40\x7c\x0f\x39\xc8\x94\xa7\xd4\x7a\x0b\x21\x44\x41\xa2\x9c\xae\x59\xc5\xd3\x54\xe1\x68\x46\x2f\x0b\xe2\x28\x51\xc9\xdd\xba\x5d\xe9\xaa\xdd\x57\x5a\xf3\x93\xf2\x47\x4c\x17\x11\x62\x8c\x46\x7d\xb9\x7d\x81\xe4\xbb\xc1\xc0\x5b\x09\xa5\xeb\x32\x2b\x92\x64\xca\x41\x4d\x9b\x9f\x68\x4e\xab\xfa\x25\xe5\x90\x57\xe8\x49\x55\x66\xcf\x9c\x34\xa5\x43\x49\x3d\x5f\x3b\xda\x3b\x55\x71\xdd\xee\xc0\xe5\x99\x0e\x52\x7f\x7d\xaf\x2a\x94\x34\x26\x18\x33\xa5\x4d\xd5\x4b\x4f\x44\x4e\x14\xe1\x3e\xae\x60\x9d\x8f\x30\x0c\xe3\x76\x25\x79\x3c\x72\x58\x84\x19\x3f\x38\xa7\x35\x6a\x7b\x5c\x51\x1f\xae\x99\x4a\x37\x9a\x43\x84\x1a\x8c\x4d\xde\x49\x7e\xf3\xc8\x75\x54\xdd\x36\x6f\xdd\xc5\xd5\xad\xb4\x2a\x8f\x5c\x11\x60\xc0\x66\xc5\x8b\xc1\x98\x37\xcd\x10\x2a\x4e\xa3\x92\xde\x53\x74\x6f\x3b\x71\x9c\xb0\x07\x55\xd8\xdc\x1b\xcf\x91\x27\x85\xe4\x06\xbd\xa5\x78\xfe\xc7\x97\xf0\x03\x90\xda\x65\xc5\x44\x98\xca\x63\x9b\x13\x04\x11\x40\x17\xb7\xc6\x0a\x98\xd1\xf1\xa1\xe7\x21\xc0\xb4\xfe\x55\x94\xe9\xd1\xee\xce\x51\x18\xa9\x00\x84\x9a\x18\xb4\x5f\x27\xcf\xa3\x50\x04\xc8\xfb\xfc\x67\x9a\xd7\x07\xbd\x8a\xee\x0b\x3d\x32\x07\x4b\x78\x14\x33\x8a\xa6\xc4\xac\x64\xfb\x02\x0d\xfe\xe7\x1b\xa9\xfc\xb6\x97\x14\x5c\xbb\x5c\xad\x89\x3a\xf2\x49\xa3\xc4\x8d\xd5\x3a\x5f\xa4\x56\x81\xd6\xdc\x4c\xe2\x79\x91\x72\x38\xc5\xb8\x18\x91\x47\x09\x05\x2c\xa7\x6a\x57\x25\xa5\xf5\x31\xc8\xfa\x44\x34\x24\xb8\xb7\xa5\x95\xdd\xbd\x54\x44\x68\xf4\x18\x34\x0e\x82\xc4\x46\xc5\x9f\x52\x39\x1e\x09\xcc\x51\xf8\xfa\x4d\xc1\x3f\x74\xe6\xd7\x5c\x83\xd1\x20\x34\xae\xa7\x36\x6f\x55\x96\x50\x8d\xfb\xd1\x50\xe4\x44\xf1\xf1\xeb\x12\x0e\x1b\x78\x1f\x5d\x8f\x73\x57\xaa\x7c\x2e\x94\x47\xc8\xf9\x75\x59\x9f\x1e\x4a\x3a\xf6\xe6\x23\xce\x01\x09\xb7\xa8\xf2\x99\x5e\x53\x55\xde\x69\x23\x8a\xba\x1b\x38\x21\x02\x7d\xdb\x0d\x67\x49\xcb\xec\x8a\x20\x08\xd7\x36\x73\x0f\x61\x48\x07\xd9\x64\x32\xcd\xcc\x5e\xfc\x97\x95\x89\xc3\x47\x03\x88\xd1\x16\x9e\x7b\x2f\x94\x1d\x54\xad\x69\xd6\x8c\xd6\x8c\x08\x20\x21\x61\xb7\x96\x4d\x67\xd6\x62\x27\xf6\xd0\x08\xda\xa4\x73\xa8\xe9\xe0\xa3\x22\x4b\x22\xf2\x81\x4d\x3a\x13\xd3\xe7\xf3\x23\x15\x1f\x68\xa7\x5a\x6b\x22\xdc\xe9\x25\x22\xcc\x73\x1d\x0b\x59\x94\x16\xde\x14\x13\x26\xa9\x2a\x3b\xc9\xa1\xec\x17\x1a\xf5\x42\x7a\x31\x11\x01\x02\x82\x71\xd3\x1e\x8a\x55\xf3\x98\x80\xef\x1a\x67\x64\x44\x03\x39\xf6\x7e\x4c\x00\x39\x0e\x88\x2a\x81\x4b\xab\x15\xde\x23\x26\xd8\x57\x79\x48\x7e\x1b\xdc\x73\x40\x04\x82\x19\x67\xef\xfb\xe7\xc3\x76\xf9\xba\xfe\xb1\x5c\xff\x7c\x33\xea\xb0\x3c\x0e\x12\xc5\x17\xa1\xa3\x64\xaa\x0a\xe5\x95\xde\xaf\xee\x1f\xbe\x92\x40\xc6\x88\x33\x2f\x34\xe1\xce\x41\x85\xba\xa6\xcc\x85\xd1\x91\xa1\xe3\xab\x92\xca\x76\xb7\xd6\xfb\x47\x6b\x3f\xad\xf3\x91\x3f\x12\x87\x3a\x67\x6f\x76\xca\xb7\x62\x40\x9b\x7d\xe7\xce\xc2\xd8\x8b\xfb\xdc\x79\xfb\x76\xfb\x3e\xef\x6a\xb8\x8c\x16\xc1\x38\x14\x0e\x92\x12\xd8\x4a\xfc\x69\x58\x44\x1c\x8a\x24\x06\x1d\x68\xef\x85\x3d\xe3\x10\x7c\x46\x7a\x60\xe6\xd6\x65\x2a\xca\xc1\xde\x1a\x47\x7e\x14\xba\x56\x3f\xb9\xa4\xc7\xce\x4e\x8e\x23\x0a\xc8\xbc\xaa\x82\x7a\x87\x0a\xb2\xec\x90\x8d\x45\x48\x79\x1c\x31\xea\x7a\x86\x9b\xae\x6e\x32\x9a\x96\x70\x58\x14\xe7\x4b\x0d\x07\x93\x6b\x8d\x63\xcf\x47\x6c\xd9\x67\x51\xd3\x43\x93\x1f\xb8\xd6\x70\x29\x46\x27\x8b\x23\x1f\x0d\x77\x1d\xe6\xbb\x07\xdd\xf9\x2e\xf5\x12\xc7\xb1\x8f\xd3\xe1\x47\x81\x85\x27\xe9\xf1\x54\x57\x66\x64\xdf\x71\xa5\xe2\x58\x52\x4d\xca\x2c\x6c\xd4\x04\xc4\x0d\x3b\x29\x8f\x13\x27\x08\x54\xb5\xeb\xa6\x75\x9b\xbd\xd1\xfd\x27\x09\xc5\x6d\x73\x01\x7c\x61\x45\x72\x79\x9c\x68\xf3\x61\x71\x2a\x8b\xbc\xa8\x14\xd4\x45\xc3\x29\x4c\x1f\xca\x88\x97\xf4\x32\x5b\xaf\x30\x16\xfc\xe3\x31\xe5\x80\xa9\x5b\x1c\x0f\xaa\x9c\x43\x2f\xd7\x13\x70\xab\xff\x1a\x1d\x2b\x3d\x8c\xd1\x56\xa8\x9d\x78\xe7\x3d\x30\x8f\x8a\x01\x24\x55\xaf\xa9\x4f\xc5\x2d\x05\xc7\xf8\xd0\x98\xe1\x3a\xaa\x16\x8b\x12\x44\x5a\x83\x30\xf6\xed\x6f\xd3\x81\x7c\xcb\xec\x7d\xef\x9c\x5c\x20\xe9\x82\xf6\x93\xd2\x1b\x78\xe6\x98\xc4\xe2\xde\x79\x20\xc4\x1a\xf7\xf5\x9b\xc1\x51\xc6\xdc\x21\x48\x7c\x80\x0a\x04\x9d\x93\x38\xbb\x83\x7a\x8a\xb9\x17\x63\xae\x28\x2b\xa8\x78\x83\x2f\xa5\xcb\x67\xe9\x4b\xec\xf2\xc7\xe3\x04\xa3\x81\x26\xf3\x8c\xe6\xe8\x77\x01\xb5\x98\x53\x07\xa8\xa6\xd1\xca\xd3\xea\x64\x6f\x90\x29\xe9\xb5\x4a\x81\x66\x2c\xb4\x32\x16\x32\x4c\x14\x9a\x11\x6d\x57\xc3\x46\xa0\xb4\xf7\xc5\xe4\x2a\x0f\x3e\x68\xed\x33\x5e\xe4\xa2\xa7\x3f\xbd\xa5\x35\x3c\x40\x5e\x9c\xd3\xbc\xe7\x5c\xc7\x20\x88\x92\xd0\xae\x8b\x6f\xe5\xb3\x4d\x77\xf0\x80\x9b\x35\xf3\x67\x3a\x5d\xcb\xc1\x63\xe9\x32\x0c\xfa\x55\x05\x4f\x69\xb6\x42\xf2\xef\xfa\xba\x96\xc8\xc1\xd3\x31\xc2\x4c\x1e\x9c\x38\x21\xa3\x9e\x2d\xad\xd6\xba\x2d\xbf\x99\x46\xce\x99\x2e\x44\x6b\x7d\x1c\x04\xde\xcc\xaf\x03\xe2\xae\xe1\x2d\x27\xae\xef\xe1\x8c\x6c\x2a\x28\xab\x49\x70\x6e\xe2\x06\x14\xad\x34\x8c\x13\x74\x35\x41\xba\xd5\xa3\x1e\xd3\xa4\x9f\x1d\x4c\x76\x24\x9c\xc1\x13\x8f\x3b\xf8\xc8\x07\x2a\xc4\x86\x5e\xf7\x56\x97\x6e\xa8\x39\xf7\x7f\xf9\x63\xce\x0c\x01\x12\x61\xa9\xc8\xcf\x85\x72\x3d\xcc\xec\x95\x25\x4b\x12\x5b\x2d\x30\x56\xf3\xe6\x09\x89\x1d\x5f\xc1\x56\xf3\xe3\x1e\xca\x33\x6b\xc4\x11\x54\xa4\x78\x98\x4e\x4c\x08\xf5\xfc\xc0\x46\x0c\xfa\xf4\xba\xbb\x0b\xb5\xd7\x0b\xa8\xe2\xa9\xa1\x42\xac\x6a\x38\x0f\x2d\xd5\x24\x74\x02\x2c\xb9\xb0\x49\x2f\x6e\xb9\xf0\xcc\x09\x42\x37\x41\x8c\xf7\xe3\x62\xbd\x7a\x73\x1d\x3f\x9c\xc4\x93\x4e\xed\xd9\x49\xc8\x00\x51\x52\xaa\x40\x21\x55\x15\xf7\xc3\x32\xbc\x71\x38\x25\x89\xc3\x18\x29\x55\x35\xaf\xe5\x2c\xc7\xea\xd5\x91\xf7\xd7\x9f\x44\x49\xcc\x14\xe3\xd6\x4f\xc8\x78\x71\x86\xd7\xea\x38\xd8\x4b\x93\x24\x00\x8c\x3a\x63\xdc\xd6\xbc\xa6\x27\x54\x88\x34\xcf\x48\x1d\x9a\x18\x64\x68\x99\xf2\x34\x3f\xa2\x73\xd4\xae\x3a\xa6\x47\x1c\x0a\x2d\x96\xb7\xa0\x65\x9e\xde\xf2\x22\x98\x8e\x92\xb9\x3a\xd2\x5f\x3e\x52\x56\x6a\x5c\x74\x97\x03\x49\x98\x1b\x22\x49\xeb\xe3\xfb\xfe\x75\xbd\x37\x0b\x5f\xc2\x1d\x89\xb1\x61\x15\x12\x30\xf7\xd9\x0e\x4c\x04\xa9\xd9\xe5\xc3\xba\xae\x09\x17\x8a\x4d\xc7\xf2\x9e\x4c\x84\x5b\x12\x11\x26\x18\x19\x31\x76\xcd\xc3\x47\x36\xa0\xc3\xe2\x09\x50\x17\x47\x6c\x0e\xbf\xea\xdd\x07\x02\x01\x74\x8b\x74\x12\x0c\x7a\xab\xa8\xcb\xbe\x98\x88\x20\x25\x92\x48\xac\x08\x4a\xab\xae\x8c\x7c\xf8\x46\x64\x18\x61\x9c\x05\xce\x54\xe1\x61\xed\x08\x96\x89\x44\x87\x13\x03\x5d\xbd\x0a\x80\x44\x72\x81\xb9\x7d\x44\x91\xd9\xe5\x8f\x3a\x9e\x87\x98\x5b\xad\xd1\x37\xa6\xcf\xe4\xd4\xe1\xb1\x0e\x66\x4b\x28\x4b\x28\xd1\xcd\x5e\xd8\xfa\x8e\xc1\x7d\x51\x47\x28\xcf\x1f\xa1\x20\xe6\x7d\xbb\xf7\x06\x26\x75\xbd\x10\x7d\x67\xc8\x45\xdd\x39\xcd\xd4\x0d\x5c\x2c\x24\xa9\xd2\x63\x6e\x7f\x0b\x29\x92\x16\x20\x44\xad\x07\x74\x9e\x9a\x24\xd4\xa5\x14\x6b\x41\x35\x2d\x68\xbb\x31\xa1\xbd\xba\xe9\x56\x5e\xd3\x93\x45\x58\x4f\xb5\xd8\xae\x7f\x3e\x20\xf3\xe2\x72\xff\x3c\xa0\x30\xe6\xd4\xf3\x39\xa6\x46\x7e\xa7\x17\xc8\x68\x7f\xe5\xa1\x5e\xa0\xec\x2f\x95\x3c\x78\x2b\xea\x5d\x91\x89\xe1\x16\x68\x7a\x86\x31\xc6\xc7\xf7\x9c\x0f\x19\x48\x27\x06\x18\xf5\x7d\x85\xbe\xff\x57\xd1\xd4\x0d\x83\xb2\xea\x19\x58\xd4\x0f\x05\x82\x67\x32\x90\xb5\x9f\x8c\x3e\x80\x1f\xfb\x08\xff\xc7\x2a\x8b\xa5\x85\x65\xd0\x20\x51\xa8\x2e\x75\xa3\x9d\x3c\xf1\x9e\x7e\x8c\x87\x1f\x0d\x68\xe8\x75\x55\xbe\x07\x99\xd1\xe3\xe8\x2a\x01\xa8\xca\xf1\x12\x2e\xd9\x75\x96\x8d\x39\x23\xdb\x0e\xa1\x17\xf6\xf0\xaa\xda\x74\xfb\x77\xac\x6d\x07\x1a\x3a\x02\xbd\xf5\x4f\x45\x4d\x81\x1b\xa4\xb9\xd7\x50\x28\x31\x10\x04\x87\x28\x94\x70\xaf\xa2\x55\x77\x8a\x42\xc7\xf1\x7b\xfb\x70\x6e\x2f\x62\x3a\xc4\x2e\x12\xee\x49\x45\xd8\x69\xf6\x4f\x1a\xf3\x10\xab\x05\x0d\x7b\x4e\x2f\x96\x4e\x63\xce\x84\x46\xe2\xc0\xe6\x64\x52\x44\x34\xe1\x8a\x8b\x7c\xa4\xd3\x39\x6d\xe4\x50\x2a\x59\x40\x3a\x3d\x6d\xe4\x69\xef\x63\xf1\x28\x73\x1c\x01\xa6\xa4\x78\x30\xd7\x58\xc8\x43\xc3\x3b\xb2\x4f\x27\xb7\xcf\xd8\xfc\xcf\xf0\x75\x70\xa6\x38\xa9\x9e\x30\x50\x25\xd3\x7a\x49\xcb\x1c\xc4\xfc\xaa\xdd\xc9\xd1\xdb\xe3\x5a\x52\xa8\xa6\x1f\xd0\x7d\xa0\xbb\x56\x0f\x15\x09\xc1\x48\x79\x45\xb3\x4f\x7a\x04\x65\xbd\xd9\xc0\x38\x05\x87\x2b\xa6\x6b\x93\xdc\x5c\x55\xeb\x4f\x0b\x9d\xa6\xe0\x11\xa4\x37\x2b\x3f\x35\x58\x6e\x34\x09\x21\x54\x90\x0a\x25\x4a\x66\xd2\xa7\x06\xfa\xf1\x77\xea\x12\x7a\xa9\xe7\xde\x36\x46\x21\xa6\x86\xe7\x74\x43\xaf\xad\x39\x6b\x2f\x99\x50\x4c\xb2\xa2\x57\x3a\x86\x22\x53\x48\x38\xc2\x14\xab\x0b\xe4\xa2\x35\x79\x9e\xe8\x5f\xd4\x89\x51\x60\xb1\xb4\x76\xe1\xeb\xf5\x3d\xef\x06\x8b\x2d\xe5\x1c\x1d\x21\xa3\x50\x17\xe0\xce\x15\x03\xc3\x58\x47\x53\x77\x94\xae\x34\xe4\xaf\x4a\xb3\xa7\xfc\x67\xcf\xc3\x57\x9d\x98\xa3\x95\x12\x2a\xa8\x97\x22\xad\x47\x31\x74\xe6\x08\x70\x35\x9e\xf5\x11\x0c\xeb\xe6\x44\xb9\x00\x73\x83\x38\x24\xdd\x7e\xd0\x8f\x86\x32\x4f\x06\x1e\x0c\xf9\xb7\x5e\xa1\xa6\x82\xf6\x76\xee\xc1\x4d\xf9\x1c\x70\xcf\xd9\xaf\x96\x5b\xff\xb0\x9d\xd9\x4a\x22\x46\x88\x1b\x18\xa2\x5f\x28\x9f\xd2\x4f\xa8\x16\x3f\x17\xd3\x33\x8a\x11\xa9\x44\x49\x70\x51\x3b\xd4\xb4\x3c\xda\x2a\x18\x16\xb8\x09\x2e\x95\x07\xdc\x72\xc8\x21\xe5\x45\x45\x33\x18\x16\x14\xd9\xce\xb1\x1f\xc5\x9d\x32\x14\x6c\x8b\xa2\x1e\x5a\x6f\x2c\x8c\x42\x84\x77\xbc\xfd\x98\x0f\xc6\x04\x0b\x29\xc1\x7d\xb0\xc8\x11\xb8\xd4\x9f\xb7\x2c\x72\x29\xd2\x40\xaa\x00\x72\x83\xf2\x69\xd3\xb6\x0c\x8b\x49\x88\xc5\x48\x9b\xac\xa9\x9b\xea\xc1\xe6\xa1\x59\x1c\x28\x1d\x76\x71\xfc\x35\xb2\x6e\x58\x1c\xc6\x9e\x62\xda\x83\x95\xae\x95\x9a\x75\x8d\xd2\x43\x3a\x69\x05\x32\xb5\xaa\x4c\xc3\x90\x3c\xa3\xb1\x92\x25\xb8\x14\x17\x3e\x3a\x3b\x8b\xbd\x48\x0e\xa2\x34\x3b\xc8\x64\x3f\x88\xcb\x18\x13\x98\x27\xdc\x3d\xaf\x36\xdf\xc0\x35\x19\x13\x8a\xcf\x0b\x05\x58\xb3\x51\x32\x91\x71\xca\x68\x7b\xa7\xbb\xf4\x7c\xc9\xa0\xab\xf3\x63\x82\x05\x08\x97\xa6\x42\x2c\x4e\x4d\xfe\xe1\x6b\x3c\xc7\x4b\x6a\xb3\xa4\x0c\xc2\x08\x8b\xd0\xf7\x25\xfd\x84\x0c\xca\x8a\x53\xeb\x3f\x32\x90\x8e\x34\x02\xfd\x52\xa6\x59\x8a\x9c\xbc\xe7\x01\x7b\x14\x67\xd2\x65\x18\xbd\x59\xa4\x25\xcf\xa0\xdb\x12\x98\x74\x25\x26\x97\xdb\x1d\x35\x1c\x85\x39\x98\x24\x80\x10\x61\x85\xf7\xe9\x15\x39\xdd\x79\x07\x32\xe1\x58\x1e\xf3\x9a\xe6\x75\x17\x3b\x36\x8d\xc2\xd1\x14\x98\x75\x6b\x82\xb7\x4b\x4b\x97\x33\x8d\xff\x4d\xf4\xf6\xc8\x1d\xea\xe1\xc4\x39\x9c\x91\x02\x5b\xec\xe9\xb1\xe7\x7f\xff\xd7\xc8\x13\xe7\x0e\x53\x54\x8c\x69\xbf\x92\x69\xf0\xf2\xb9\xeb\xc7\x1a\xb6\xf4\x45\x4b\x31\xce\x53\x70\x97\x25\x9e\x2e\xd2\x2a\x0f\xbc\x38\x9f\x9b\x3c\xad\xaf\x46\x7e\xa9\xff\x0c\xdc\x73\x02\x34\x91\x15\xb5\x5c\xbb\x83\x88\x09\xa6\x7c\xd3\x39\xf2\x89\xa6\x67\x78\x4d\xf3\x57\x5a\x1e\xc7\x01\x72\xee\x87\x2e\x0d\xed\x0b\xde\xd3\xfc\x63\xb8\x24\xf1\xc0\x8f\xb0\x8e\xff\xe9\x17\x52\x44\x54\xe3\x66\x2e\x91\x17\xd5\x5a\xe3\x96\x14\xf4\xf1\x06\xdd\xce\x03\x11\xa2\x69\x4d\x4b\xfa\x35\x28\xa7\xe3\xa1\xef\xfb\x9e\x45\xb0\x2f\x8a\xe6\xd2\x25\xab\xfe\xed\x75\xc5\x82\xf1\xff\x0c\x23\x72\xff\xf6\xcc\x57\x08\xe3\x44\x71\x45\xd0\xf2\x43\x81\xcd\xab\x5d\xef\xfc\x49\x20\xb4\xca\xed\x02\xca\x3a\x95\x29\xa7\x37\x8c\xf6\x9c\x87\x5c\x79\x5e\xf3\xd9\x7c\x65\x0f\x15\x11\xa2\x22\xb7\x58\x17\x97\xe6\x47\x15\xd5\xf8\x41\x9b\x6c\x94\xb4\xe5\x51\xe0\x9b\x7a\xe7\x3d\xd0\x73\xb5\xce\x5f\x50\x95\x07\x39\x7e\xcc\xf9\xa2\xd0\x87\x08\x17\xdf\x2c\x4b\x87\x55\x36\x3c\xe2\x04\xf9\xd8\xd4\xae\x48\x33\x30\xd5\xc4\xd3\xb1\x0a\x1e\x49\x8e\x95\x8a\xab\xc5\xfa\x8e\xb3\xc2\x63\xcf\xf3\xf4\xfe\x85\xab\xa6\x3a\x63\x7e\x5c\x9c\x68\x9e\x43\x76\xd3\x3b\x0c\x4c\xef\x53\x8f\xd0\xd3\x34\xc7\x04\xd3\x62\x5f\x69\xd9\x69\xfb\x4f\x6e\x1b\x3c\x66\x24\x08\x74\x39\xe1\xa7\xb5\xfc\x1f\xcb\xe2\x6c\xa2\x18\x63\x8d\xe7\x49\x58\xb0\x3e\x5b\xe2\x31\x4f\xe9\x6c\xad\x16\xeb\xf5\x05\x72\x6b\xfe\xf0\x24\xf4\x0d\x8f\x2c\x94\x4a\x59\xf4\x37\x03\x58\xfd\xce\x6a\x31\x01\x0e\x9e\x70\xa5\x6a\xa2\x0a\xb6\x3a\x55\x8e\xe1\xab\xa6\x6e\x94\x68\x76\x00\x5c\x5d\xc7\x26\xdb\x58\xc7\x95\xb7\xae\x0b\xda\xc0\xed\x4c\xcf\x3a\x83\x8b\xd3\x80\x83\x21\x5d\xca\x8f\x69\x0e\x13\xae\x30\xa7\xa1\x2a\xc3\x53\xd8\x0f\xac\x79\xfb\xa9\x68\x07\xba\xf3\x44\x01\xda\xd2\xbb\xba\xb9\xa4\xa2\xe7\xa4\x70\x4a\x7d\x48\xba\xc4\x29\x94\xb5\xc6\x4a\x0c\x9e\x9b\xb9\x0c\xb3\xd3\x1d\xe8\xec\xce\xa7\x64\x42\x69\xd4\x55\xbd\xdd\x6d\x32\xc1\x31\xe1\x4d\x71\x4e\x02\xdc\xbd\x2e\x4d\x75\x9a\x5f\xeb\x51\x66\x91\xf3\xc4\x41\x6a\x02\xac\x6f\xea\xfc\xc0\x9d\x29\x71\xe2\x1c\x02\x34\xad\x14\x49\xe6\xd3\x48\xae\x98\x73\xe1\x24\x98\xbc\x80\x5f\x75\x49\x1f\x68\x4d\x5d\xcc\xb2\xb6\xfb\xd3\xdf\xbe\x47\x91\x28\x9f\x4b\x79\xd9\x34\x7b\xa5\x39\x3d\x5a\x0b\x9a\x0b\xc6\x3d\x1d\x97\x3a\x43\x7d\x82\xa6\xfa\x51\x34\xfc\x04\x65\x85\x80\x51\x3b\x12\x05\x10\x26\x7a\x6b\xe1\x2c\xcb\x6e\x05\x8b\x74\x5f\x70\x38\xa6\xc3\xa0\x3e\x1d\xea\xe2\xd0\x54\xf6\x2c\x40\x54\x49\xd1\x41\x05\x20\xdf\x0a\xab\xe1\x60\x3a\x44\x81\x6f\xdd\xfc\x99\x10\xf7\x58\x84\x38\x87\xd8\xa5\xb4\x87\xdb\xc2\xb7\x32\xf8\xb4\xd2\x0d\x71\xd5\x5c\xd0\xea\x84\xe4\x0c\xf6\x06\xa5\x17\x61\x24\x77\x43\xeb\x32\xe5\x1f\xcf\xcd\x35\x3f\x0d\x76\x22\x19\x0b\x0c\x1b\x3f\xff\x98\xbd\xd8\xdf\x78\x80\x3b\xe7\x23\x40\xb5\x05\x0e\xe9\xe7\x3d\xe8\xa4\x70\x48\x08\xcc\x14\xa2\xbe\x42\xeb\x0e\x9a\x6b\x0b\x47\x87\x20\xfe\x7b\xf9\xb6\xde\x61\x3e\xd6\x2e\x36\xb6\x87\x87\x05\xa8\x19\xad\xd4\xa3\x1d\xa4\xdf\x3e\xdd\x41\x5f\xc4\xf4\x73\xdd\xb8\x2f\xc9\x34\x13\x9f\x69\x55\xdc\xc1\x1d\x0b\x97\x51\xa6\x42\x62\xe8\xb5\x19\x96\x2f\x2e\x3c\xdf\xc7\xb2\xd2\xfa\x44\xbf\x26\x91\x1e\xc2\xf7\x69\xa0\xab\x35\x0d\x33\xa9\x69\x91\x02\x4d\xe4\x79\x53\xe6\x53\x25\x64\x82\x10\x07\x6d\xfe\xf7\xb7\xe7\xc5\x37\x91\x48\xdd\x3b\xf0\x55\x09\x2b\x15\x62\x29\x1a\xbd\x89\x0d\x7a\x84\xbe\x82\x64\x35\x79\x05\x59\x86\xb5\x55\xe6\x5e\x42\x22\x43\xbb\xbd\xb4\x63\xf7\x09\x33\xb6\x26\x6a\x28\xa2\x58\x09\xfd\x53\x5e\x63\xb1\xc0\xf2\xd7\xa5\x28\x5b\x97\x65\x71\x6a\xcd\x7e\xb5\x03\x8e\x9e\x3c\xe6\x09\xc2\xc5\x31\x2f\x6e\xb7\x8c\x69\xc2\x28\x2e\x12\xf0\x30\x3d\xf7\xcf\x86\x96\x75\x8f\x16\x6f\xd4\x8d\xba\x4a\x23\xa2\x4e\xeb\x6c\x8c\x5a\x14\x54\x10\x64\x5a\x49\xab\x55\x5e\x5d\x80\xf7\xb2\x3e\xba\x07\x73\x3c\xcc\xf9\x0a\x9a\x66\xd7\xe7\xa2\x29\x7b\x92\xd0\x5c\xb0\x18\x80\x0f\x1d\x29\xc5\xcb\x33\x7d\x2f\x8c\x46\x98\xd2\x39\x1c\x15\x03\x53\x51\x64\x1d\xc6\x53\x70\x97\x63\xe9\x49\xa6\x84\xd4\xcc\xaf\x4c\xc9\x9f\x7f\x95\x45\x7e\xd4\xab\xc9\xba\x7c\xcf\x2b\xa8\x57\xb9\xce\x42\x98\xbe\x82\x6b\x65\x48\xb3\x0c\xd3\x5f\x50\x4d\x6c\x09\x02\x5c\x25\xa5\xf3\x05\x29\x42\x39\xb6\x34\xed\xaa\xed\x04\x08\xc5\x9f\x83\xae\x95\xd9\xdc\xef\x79\xef\xdf\x6c\xb5\x42\x7a\x4c\x23\x9d\xb2\x6c\x43\x6b\xc8\xeb\x7e\x20\xa4\x7b\x2f\xd2\x8f\x30\x2b\x7d\xa0\xfd\x2a\x8a\x71\xa7\x20\xa0\xed\x60\xdc\x1a\xe0\x38\x38\x84\x79\x8e\x09\x91\xbe\x14\xfc\xa3\x68\x6a\x15\x45\xb5\x3d\xa8\x22\x1b\xac\x6c\xb5\xa4\xfa\x7c\x83\x33\x83\xd3\x3a\xa6\xca\xf4\x39\x3c\xae\xde\x56\xbb\x67\x7b\x3c\x57\x02\x63\x95\x06\xa2\xf4\x81\xaf\xff\x76\x1d\xbd\x38\x82\x4b\x04\x32\x8e\x1e\xbe\xd2\x2c\x7b\x1c\xae\xb1\xe0\x02\xc7\xe2\xc1\x67\xc8\xb2\x02\xb7\xd6\xd1\xa4\x6c\x6e\xe8\x26\xc0\x73\x54\x31\xee\xb9\xa9\xe9\x11\x72\xef\x71\x42\x70\xdb\x74\x75\x13\xcc\x99\x48\x80\xea\x30\x7a\x30\x2f\x71\x90\x65\x48\xab\xa9\x17\x4d\x79\x67\xd7\x35\xfd\x85\x42\x86\x19\x3a\x23\xc5\x2b\xd4\xd7\x6c\x35\x3b\x3e\xf8\x11\x73\x9d\x4e\xe9\xa5\x0f\x14\x07\xbf\x5d\x88\xec\xac\x30\xca\x20\x83\x79\x05\x24\x12\x18\xd1\xb9\xd0\xab\x0a\xfa\x55\x26\x2b\xdc\xfb\x63\x15\x10\x9a\x1b\xce\x6d\x0e\x81\x27\x14\x9b\xd9\x89\x96\xa0\x69\xe0\xd1\x4d\xec\x51\xba\x40\xc0\xbd\x98\x74\xb5\xe6\x76\x8c\x43\x20\x59\xa4\xb3\x1a\xcf\x45\x59\xc1\xee\x54\x8c\x2c\x54\x08\x63\x2f\xec\x27\xb7\xe7\xd7\x97\x1e\x6f\x5f\xeb\xbd\xd9\x09\x05\x51\x2c\x4d\xa8\xf3\x01\xce\x34\x17\xe3\x93\x45\x89\x63\xe8\xc3\x70\x99\x40\x4b\xae\xe0\x1f\x8b\x89\x77\x13\x7b\x2e\xa6\x25\x98\x1a\xb2\x26\xfc\x5e\x4e\x90\xd0\xf6\x66\x1b\x24\x0e\x47\x1e\x11\xcb\x98\x6c\x36\x41\x48\x5c\x81\xc0\x4b\xcd\x3e\x52\x94\x36\xd9\x07\x89\xa7\x04\x36\xd5\xb7\x7a\x4d\xf3\x27\x5a\x3d\x16\xe5\x43\x49\xbf\x0c\x64\xc8\xbe\xf1\x84\x28\x75\x9f\x1a\xa8\x75\x38\x81\x3a\x61\xa0\x11\x1b\x6a\xbd\xc8\x8a\x0a\xc4\x4a\xaa\xbf\xb6\x57\xe0\x33\xd1\x39\x65\x27\x7a\x86\xfa\x4f\xdb\x18\x29\x3a\xaf\xb4\x9a\xd9\xfc\x07\xd0\xc4\x41\x1d\xcd\xd5\xec\x75\xd9\xaf\x13\xb7\xcd\x04\x69\xff\xd0\xa8\x45\x32\xcc\xb4\x7f\x39\x41\xb0\x98\x48\xf3\x63\xad\xf2\x76\xed\xb9\xf1\xd1\x80\x8a\x10\x8b\xc3\x17\xc5\xf9\x42\xf3\x2e\xc2\x00\x14\x02\x4c\x0c\xce\x7e\xcc\x56\x2f\xb3\xf9\xcb\xf2\x30\x5f\xbf\xbd\xef\x5c\x4d\x48\x6a\xba\x31\x97\x69\xc9\x68\xb1\x29\x61\x99\xb7\xeb\x2e\x07\x63\x81\xdc\x24\x4b\x46\x33\x57\x44\x1c\x94\xea\xfb\x71\xd2\xbe\x34\xdd\x78\x80\x7b\x8c\x82\x6b\x6a\x49\xb6\x91\x8a\x0c\x07\x00\xd7\x53\x2b\x1d\xcc\x53\xd1\x63\xe1\x00\x49\x04\xed\xf6\x28\x55\x24\xb4\x28\x2e\x57\xdb\xce\x15\x86\xa3\x5d\xa4\x17\x46\xe6\x65\x84\xb0\x05\x09\xcc\xd1\xfc\xcf\xf9\xd8\x6e\x96\x8e\xef\x53\x9d\xf5\x7f\x03\x15\x86\x9d\x34\x6d\xa4\xc3\x80\x90\x81\x9b\xa0\xf1\x00\xe3\x14\xe6\xb7\x41\x6c\xe9\x08\x45\x44\xb3\x79\x99\x99\xdc\x8e\x74\xa9\x0e\x3d\x29\xb5\x3a\x4d\x83\xa1\x1b\x3d\xe9\xe2\x76\x57\xe6\x62\x0b\xa2\xe1\x60\x73\xde\x07\xd3\xc5\xf7\x18\xb2\xf2\x6e\xe8\xb5\x68\x30\xe8\x8e\xfe\xd1\x94\xb7\x17\x9b\x43\xa4\x2b\xb5\x2f\xa3\xb2\x6d\x93\xdc\x5a\x92\x78\x5a\x08\x1b\xbd\x8e\xe7\x2b\x2b\x53\x91\xfe\x39\x70\xc5\x4d\xcf\x20\x71\x34\x23\xe4\xf3\x85\xbd\x15\x02\x50\x38\xad\xbf\xe2\x4c\xd0\x37\x8f\x62\x48\x92\x08\x86\x3e\xa8\xb2\x1d\x11\x85\x6b\xd7\x50\x73\xeb\x04\x82\xb0\x1f\x2a\x9c\x63\xb9\xb9\x79\x17\x81\x4f\xb4\xd2\xa1\x45\x79\xce\xba\x8d\x63\x70\xcb\x81\x84\x58\x85\x4a\x7e\x2d\x4e\x69\x26\xfa\xfb\x80\x0c\x03\x8a\x45\x07\x59\x71\x4c\x47\xe5\x9c\x32\x64\x01\x46\x69\x76\xfb\xd9\xf6\xc5\x1e\x00\x11\xb1\x52\x48\xbb\xc6\xe0\xff\x65\x14\xa8\x95\xed\x60\x60\x81\x2f\xc5\xb1\xbf\x5d\xc4\xff\x75\xf3\x3f\xf1\xe0\x79\xe3\xd0\x71\xc2\x81\xbe\x94\x2d\x46\x18\x7e\x82\x98\xba\x18\x83\x5a\x2c\xb6\x7d\x0f\x45\x26\xae\xe3\xe9\x04\xc4\x63\x96\x1e\x4f\x35\xd6\x3f\x4d\x60\x1c\x64\xe2\xc6\x01\x37\xe8\x34\xc5\xba\x30\xb1\xc6\xcb\x24\x52\xd6\x4c\x5a\x6d\x74\x42\x56\x7b\x75\x93\xdb\xa5\x4c\x12\xa2\x28\xf9\x74\xd6\x74\xd8\x4a\x43\x47\x49\x3f\x7f\xf2\x65\x7d\xc2\x68\x99\x69\x89\x08\xa6\x45\x59\x73\xfd\x1d\xae\xd5\x64\x74\x5f\x52\x1e\x82\x29\x63\x1a\xc4\xca\x25\x63\x8a\x75\x0f\xab\x9e\xb4\x0a\x54\x6f\xcb\x91\x4c\x38\x86\x3e\xe1\x0d\xbe\x54\x8e\xe1\x0e\xfc\xcd\x8e\x4f\xee\x4a\xd2\xad\x47\x7d\x00\xf0\x74\x85\x84\x39\x8c\x78\x8a\xe4\x3a\xa3\xfc\xa3\x35\x91\x37\xb4\xac\x6f\x38\x71\x7a\x7b\xb2\x14\xae\x83\xcb\x92\x25\x1a\x7f\xed\xa0\xc4\x52\xf8\x8e\xa3\xd5\x60\xef\x44\x5a\xa5\xf0\x03\x74\x5b\xe1\x7c\xc9\x8a\x2b\xc0\xab\xaa\x22\xa9\xf6\xc5\x1b\x7c\x2d\x77\xeb\xcd\xe8\x2b\x08\x11\x21\x3a\x23\x87\x2f\xfd\xaa\x74\x03\x88\x44\xea\xf5\x71\x77\x81\x7e\xa2\x76\x10\x83\x13\x8e\x43\x5c\xae\x43\x66\xb3\x33\xa3\x55\x45\x45\xcf\xc3\xb4\x8f\x26\x1c\x87\xa9\xdd\xef\xd0\x81\xcc\xee\x84\xbe\xf4\x01\xae\x43\x70\xeb\xd6\x7a\x30\x69\x59\xd5\x0f\x0d\x64\xee\x6f\xa3\x6e\x44\x71\x50\x43\xe2\x0f\x73\x17\xc2\x71\x83\x10\x3f\x5b\x96\xd6\x08\xcd\x84\xbc\x5e\xfe\x4a\xab\x7a\xa8\x86\x25\x1c\x37\x51\x55\x92\x47\xa8\x0f\x88\x42\x3a\xa4\xed\x54\x19\x76\xf2\xdc\x10\xa7\xd3\x7c\x3f\xef\x4d\x33\xe1\x78\x34\x40\xb7\xb9\x82\xfa\xa9\x30\x39\xd5\xe1\x2d\xfa\x7e\x40\xb5\x21\xf5\x56\x8c\x79\x55\x85\xe3\x73\x82\xb1\x80\xfc\x17\xdf\x40\x39\xe7\x57\x73\x6a\xe2\xa8\x44\xa1\xd6\x02\x52\xe5\xbe\xb8\x0a\xab\xe2\x8e\x3e\xa2\xcf\x1c\xe2\x51\x4c\xa8\x6c\x8a\xfc\xcf\x74\x0b\x9f\xba\xf2\x61\x6e\x2b\x93\x84\x43\x82\x08\xf9\x0f\x54\xe5\xde\x57\x3b\x89\xe7\xcd\xd5\xaa\xe0\xfe\x4c\xeb\x53\xd1\xd4\x3f\xa0\x9c\x0e\x13\x0b\x87\x08\x07\x75\xae\x8e\x0a\xb4\x66\x24\x59\x0a\xfb\x4a\x88\x8c\xd1\xc9\x79\x58\xfe\x18\xc0\x19\x84\x13\xba\x51\x44\x2d\x41\x06\x46\x99\x86\xe7\x0e\x3d\x55\xdf\xb3\x4b\xdb\x79\xb4\x68\x67\xa7\xb1\xe5\x4d\x8f\x48\x10\xae\x35\xc0\xca\xee\x57\xea\xa2\xd0\xd5\xec\xe5\x71\x66\x7f\x93\xc2\x10\xb9\xa2\xc7\x68\x83\xf3\x8b\xc6\x0e\x91\x28\x52\xec\xde\x2f\xb8\x6b\x99\x1f\x99\x44\x9c\x8c\xf2\x41\x9e\x69\xc9\x8a\xd2\xd2\xaf\xe9\x3e\x71\x94\x10\xc5\xd6\x51\xcd\x9b\xeb\x5b\xf1\xd5\x31\xce\x74\x5f\x23\x16\x04\x8d\xd8\x3e\x31\xc9\x0d\xf7\x9f\x70\x92\xd8\xc7\x02\x1e\x45\xa0\x74\xb8\x34\xa3\xd5\x52\x38\x34\x8e\x9d\x44\x33\x76\xcf\x84\x68\x77\x48\x63\x2d\x09\x87\xb9\x04\x77\xcf\x07\xf8\x2c\xea\x1a\x06\xa3\x93\x45\x22\xf0\x7b\x0e\x01\x0a\xeb\xdf\x0d\xa9\x0b\x87\x73\x17\xb9\xe1\x5f\x0b\x2c\x17\x30\xf0\xf9\x09\x89\x84\xd1\xc0\x13\x24\xc6\x54\x15\xa6\x21\x57\xbc\x70\xef\x65\xf5\xff\xbf\xfe\x35\xd7\x4b\xb8\xe1\xc4\x5f\x68\xd7\x4f\x60\x01\x7a\x3b\x35\xd2\xaa\x4e\xb9\x7d\x3f\x22\x51\x42\x43\x9a\xcf\x4e\x33\xab\x54\xb8\xb9\x0c\xe7\xb8\xa0\x9c\xc6\x7d\x79\x8f\x40\xcb\x7b\x04\xff\x35\xf8\x6b\x0f\x80\x30\xf4\x43\xf3\xe5\xf6\x05\xda\x52\x7a\x56\x99\xab\xcb\x40\x29\x17\x97\xed\x16\xec\x07\xa3\x11\x22\xa5\x62\x9b\xc5\xdd\x6a\xb9\xde\xf1\x8c\x56\x95\xe1\x9c\x15\xae\xe3\x83\x20\x83\x32\xe5\xe7\xd5\x62\xca\x50\x15\xae\x23\x88\xd0\x8b\xd8\x22\xad\xaf\xaa\x90\xc5\x24\xd1\xa6\xd9\xda\x84\xeb\x86\x2e\xd6\xf2\x08\x48\xeb\xeb\x00\x47\x26\x5c\x37\x66\xac\xff\xda\x28\xa6\x96\x91\x88\xca\xf4\x90\x0a\xea\x54\x9f\xca\xe2\xab\xfa\x79\x02\xab\x1f\x92\xe6\x47\xad\xdb\xa9\x2c\x84\x39\xc8\xa2\x84\x45\x96\x4a\x39\xba\x6d\xcf\xa7\x58\x7b\xd2\x54\x46\x54\x62\xa8\x20\x20\x5c\x2f\xf4\x94\xb4\x2f\xcd\xf8\x2c\x17\x4f\x26\xad\xd5\xb6\x28\x4a\x80\x34\x17\x0b\x93\x36\x7c\xe8\x2b\x14\x09\xd7\xf7\x08\x46\x32\x58\x73\xdd\x60\x06\xbb\xef\x65\x0a\xd7\xf7\x95\x84\xcd\xef\xff\x5a\x1c\xf6\xcf\xdb\xe5\xee\x79\xfd\xf2\x60\x1b\x43\x21\x54\x25\x49\x9a\x65\xa9\x61\x38\x34\x8d\x09\x71\xa3\xae\x4e\x13\x37\xd8\x37\xf8\xea\x80\x14\xa3\xcd\xc8\xf5\xb9\x8b\x81\xce\x03\x2f\xce\x97\x06\x11\xdf\x4a\x22\x7f\x72\x22\xba\x84\x40\x38\xca\x80\xf4\xed\x1c\xe1\x86\x4e\x8c\x4c\x1d\xff\x2a\x9a\x97\x62\x90\x26\x15\x6e\xe8\x71\x8c\xba\x22\x0e\xa4\xa9\x6e\x6b\x25\x3a\x83\x48\xb8\x91\xeb\x11\xbd\x4c\xbe\xe7\x69\x5d\x75\xcc\x43\xdf\xc2\x4e\x84\x1b\x89\x24\x08\x0d\x96\x68\x7b\xcb\x3b\x29\xdc\x84\xb8\x5a\x33\xa9\xfe\x07\xe5\x1f\x97\xa2\xfe\xb6\x1a\xe7\xaf\x34\xce\xf4\x59\xa9\xaf\xa4\x70\x14\x73\xe9\xb9\x28\xeb\x14\xec\x17\xa5\x21\x89\x22\x5b\xaf\xbf\xec\xd3\x8d\xf4\xbc\xda\xc1\x5d\xd2\x50\x95\x81\xbe\x80\x38\xde\xd7\xc8\xd7\x9d\x99\xb6\xe9\x20\xe7\xed\xee\xa0\xb9\x79\x7e\x1b\x75\xa2\x0c\x44\x27\x0c\x50\x8d\x9a\x79\x10\x52\x9b\xc5\xde\xff\xfa\x51\x64\xcd\xd9\x4e\x3b\x0e\x22\xf6\x0c\xe0\x64\x5e\xfc\x72\x4d\x83\x88\x08\x51\x00\xf6\x0d\xad\xec\xf3\x0a\xcd\x22\xa6\x76\xa7\x91\xda\xe7\x68\x4c\x89\x44\x02\xeb\xe8\x43\xb6\xb3\xd1\x5c\x04\x27\x70\x43\x1b\x7a\xfc\xde\x3c\x73\xa5\xe3\xa0\xcc\xdd\x1b\xfc\xc2\x8a\xe4\x95\x9d\x37\xd2\x71\x8c\x9a\xc6\x03\xad\xe9\xc1\x8d\x6d\x0b\xf3\xd1\xf5\xba\x95\x8a\xe8\x0c\x45\x57\x0a\xc0\xd0\x26\xfc\xaa\x21\x17\x96\x52\x65\xf2\x73\x78\x8e\x27\x3c\x62\xfc\xf8\x5f\xf5\x2d\xa2\x55\x78\x8e\x64\xe8\xf3\x16\x5f\x39\x08\x55\xa8\x39\xec\xe0\x06\x01\xe2\x93\x54\xb2\x60\xfa\x3a\x6e\x24\x70\x92\xcc\xf2\x9a\xf6\x10\x91\xc2\x73\x39\xc5\xf8\xf5\x6a\xb1\x56\x62\x73\xb4\x14\x96\x4c\x57\x78\x5e\xa8\x8b\xe0\x4d\x9d\x02\x94\x9f\xcd\x80\x1f\x4f\x78\x1e\x25\x98\x11\x6d\xfd\x2a\x0c\x1a\x75\x0a\x3e\x9b\x2e\xeb\x23\x3c\x8f\x91\xb0\x63\x82\x58\x1e\x8f\xa3\x52\x76\xdd\x8d\xb8\x9e\x61\x27\x7d\x04\x68\x8d\xa4\x11\xf2\x54\x78\x84\xa8\xa2\x8c\x97\x79\xfb\x28\xff\xb0\x3f\x47\x1c\x81\x3a\xbc\xb0\x85\x82\x56\x7a\x52\x78\x51\xac\x5e\x13\x6e\x72\x36\xbd\x75\x67\xea\xda\x63\x54\x01\xe2\x25\xe5\x45\x47\xe4\x6d\x1a\x79\xcc\x05\xda\x6c\x2f\xeb\xc5\x01\x13\x9f\x4f\xcb\xb7\xe5\xd6\x24\xd4\x84\x17\x3b\x8e\x54\x2c\x74\xdd\x42\xea\xc5\x11\xe0\xa7\x48\x91\x53\x7d\xb8\x83\x7b\x71\x92\xb0\xd0\x70\xae\xd7\x0a\xdf\x32\xea\xc1\x98\xe3\xf5\x42\x20\x08\x47\x19\x4e\x50\x2f\x16\x84\xf7\x09\x49\x56\x52\x45\x88\x0c\x07\xc2\xb7\xd5\xed\xc2\x8b\x21\xc6\x64\xf9\xeb\xea\x0d\x19\x7c\x1e\xde\xb7\x3d\xc9\x55\xe1\x25\x8e\x40\x82\xda\xd7\xd9\x1f\x2a\xe9\xab\x1e\x7e\xbf\xfe\x7d\xf9\xb6\xb3\x9d\xbc\x00\x8b\x53\xed\x3d\xf4\x40\xd2\xf6\x43\x26\x21\x93\xfd\xda\xb5\xd1\x73\x24\xb1\x8a\x29\x36\x97\x63\x49\x05\x6c\x4e\x05\xe4\xe9\xaf\xd6\x42\xaa\xc6\x3d\x93\xc0\x1f\x44\x57\xae\xc8\xe5\x78\x5b\xaa\xdd\x3b\x84\x79\x09\xeb\x76\xc0\x5d\x71\x86\x51\x0a\x56\x78\x09\x8f\x3c\x55\x82\x5c\x5c\xde\xf1\x26\x6c\xf2\x48\x78\x8c\xb9\x18\x86\xfd\xb8\xf2\x3e\x1c\x46\x78\x8c\x0b\xdf\x28\xb7\x41\x46\xaf\xdf\x95\x99\x0b\x8f\x13\x22\x3d\x14\x02\x6f\x32\x7b\x0a\x1e\x04\x2a\xd7\xb7\x5d\xce\x76\xef\xdb\x7f\xd9\xdf\x13\x50\xd5\x59\x85\xac\x39\xbd\x6c\x81\xf2\x93\x12\xd4\xa2\xcc\xe4\x3f\x84\x27\x3c\x1f\x13\x70\x8b\xa2\x14\x8c\xe6\xf6\x77\xf0\x19\xfa\x7a\x8a\xb3\xe2\x31\xcd\x2d\x9e\x6d\x38\xc6\x64\x04\xa4\x9f\x0a\x9f\xa7\xe2\xb1\x28\xdb\x91\x36\x7a\xed\x32\x96\x89\xf6\x0c\x67\x42\xbc\xa4\x55\x8f\xdc\x5d\x78\x92\x2a\xd1\xdf\x53\xef\x16\x24\x24\x68\x11\x56\x35\xfd\x80\x9f\xb4\x9d\x83\x07\x8b\xb5\x16\xbe\x43\x95\x26\x54\x87\x00\xb5\xa1\x84\x6f\xaa\xa3\x84\xef\x26\x0e\xe6\x78\x37\xdb\xd5\x62\x79\x88\xcc\xe9\x5c\x91\x60\x88\xb1\x3d\xbe\x32\xb8\x12\xd3\x26\x3d\x34\x32\xde\xdf\xfa\xd2\x27\xc2\xf7\x62\xa5\x8a\x63\x40\xce\xcf\x34\xfb\xec\x80\x1b\xc2\x27\x41\x88\xc7\x69\x86\x1a\x4c\x9f\x0d\xbe\xa8\x4f\x82\x28\xe9\x25\x13\xd6\x72\x53\x42\x5d\x5f\xc7\xbd\x12\x8a\x55\xb3\x29\x2f\x5e\x6a\x6e\xcf\xce\x68\x94\x58\xa1\xe4\xc9\x98\x85\x1f\x10\x8e\xd0\xff\x43\x5a\x7d\x4b\x13\x2f\xfc\x20\x8e\x70\xf9\x7e\x9e\x6d\xff\x31\x34\x5d\xee\x25\xc2\x84\x1f\xd0\x98\x6a\x21\x6a\xac\xbd\x84\x3e\x25\x91\xf0\x43\xa2\x08\xf9\xea\xe2\xa5\xe1\x1f\x57\xfb\x33\x15\x18\x1e\xe1\x19\xd0\xfc\xfd\x32\x7a\xd6\xc8\x51\xe0\xd1\x4a\x51\x3b\xd0\x0c\xb4\x57\x8c\xc5\x89\x13\x10\xb8\xd1\xe7\x8d\xbc\x08\x6d\x79\xcc\x70\x3c\xa4\x9f\xe6\xaa\x91\xef\x21\x3a\xba\x03\x12\x7c\x92\x5b\x20\x81\xf0\x23\x08\x85\x8e\x10\xda\xf1\xd4\xd1\x29\x09\x3f\x76\x25\xe6\xac\x66\xfb\xfd\xf6\xf0\xb4\x7e\x79\x58\xbe\x3d\xad\xd7\xbb\xa5\x6d\x67\x32\xa2\x16\x01\xb8\x2c\xa9\x69\xa0\x89\x87\x71\x5b\x6d\x14\x2f\x46\xf4\xc0\xc2\x67\xbe\x8b\x20\x3e\x7c\x50\x43\x81\x7f\x07\x87\xd3\x19\x11\x7e\xbb\x55\x2a\x25\x55\xe5\x86\x98\xeb\xb1\xd0\x57\x15\xa2\x56\xc9\xef\x6f\xda\x9e\xff\x7f\xfd\x35\xf7\x95\x40\x90\xf4\xaa\x13\xa1\xcf\x64\x20\x7c\x1e\x08\x2f\x36\x05\x34\x20\x96\xf5\x49\x05\xfd\xef\xcc\x66\xce\x42\x4c\x5d\x9d\x9b\xec\x8f\x69\x83\xc6\x17\x6e\x88\xec\xa6\x17\x5a\xd2\x33\xd4\xd0\x5a\x63\xa5\x22\x88\xb3\x63\x52\x10\x07\xa1\x36\xfc\xd4\x2e\xcf\x58\xbb\x31\x3d\x5b\x46\xb3\x06\x3c\x27\xd4\x81\xca\x39\xd4\x9d\x09\xe1\x03\x89\xd0\x84\x3d\x1b\xb9\x3a\xdb\x10\x44\x89\xd6\xa3\xdf\x16\x19\x8c\xa3\x9b\xe3\xf3\x27\x80\x28\x10\x0c\x84\xf6\x3d\x1a\x13\xba\xed\x22\x2c\x37\xec\x9a\xc2\x07\xae\xf8\xa1\x15\x2c\x34\x3d\x37\xe7\x15\x2f\xb6\xe3\x7a\x22\xe1\x83\x70\x30\xdd\xda\x21\x26\x61\x54\xf9\xa3\x3b\x4a\xe6\x88\x60\x34\x39\x7a\xec\x2b\x6d\x87\x48\x29\x42\xab\xb2\xd0\x76\x63\x5d\x2d\xd6\x0f\x69\xc5\xfb\x0b\x83\xe4\x1c\x61\x58\x0c\xd2\xfc\xf8\x63\xa5\x49\xff\x04\x71\x02\x86\x43\xf9\x67\x3a\xdc\x89\xe3\xa1\x37\x37\xaa\xda\xb6\xcf\x41\x9c\x44\x51\xb0\xed\x4f\xa0\x6b\x55\x74\x83\x4b\x22\xb4\x3b\x15\x71\x6f\x7f\x0d\x27\x6e\xc8\x70\x03\x63\xad\x6b\xdd\x3d\xbf\x37\x2c\xf6\x1b\x1a\x9e\xc4\x8d\x22\xbc\xd0\x2e\xa7\x97\xea\x54\xd4\x8a\xb8\xfd\xbe\x0a\x69\xff\x25\x12\x37\x51\x5c\x1c\x47\xcb\xe7\x8e\xfe\xa4\x51\x43\x1d\x33\x89\x0a\xe2\x32\xae\x72\xe9\x75\xa1\x79\xd7\xe2\xdb\xb4\xe5\xf4\x6c\x23\x2e\x8f\x30\xe8\xf0\x96\x7e\x14\x86\xad\x51\x10\x9f\xb8\xbe\xce\x0c\x2c\x9a\xaa\x2e\xce\x50\xbe\x6d\xe1\x3f\x33\xce\xbf\x1f\xef\xc4\x0f\x22\x14\x4f\xcb\x68\x2e\xda\xa1\x3d\x32\xae\x88\x1f\x12\x04\x09\x29\x7e\xae\x6f\xb6\x61\x42\x62\x4e\xf4\xee\xb5\xf6\x86\x7b\x00\x21\x09\x43\x9d\xcf\x25\x06\x9b\x78\x47\x32\x22\x08\xe1\x0e\x1e\xa6\x6a\x0d\x11\xe3\x3a\x19\x84\x27\x41\xa2\x42\x1a\xf5\x14\x05\x25\x89\xfb\xf3\x84\x04\x3c\xd2\x9a\x41\xc8\xa0\x3e\x53\x3e\x5b\xd5\x63\xee\x13\x24\xf4\x94\xd9\x68\xc3\x2f\x3f\x53\x64\x22\xf9\xea\x3a\x28\x59\xd1\xb2\xc8\xb2\x97\xc2\xfe\x1a\x29\x86\xf3\x97\xd9\x66\xbf\xde\xa0\xdd\x6b\x9b\xa8\x2a\x4f\x3d\x42\xfd\x03\x2a\x84\xea\xa2\xbb\x23\xee\x54\x8c\x0b\x12\xb2\x00\xe9\x7b\x4e\xb4\x3a\xbd\x56\xc7\x1b\xb7\xf5\x5b\x80\x6d\x57\xc5\x37\x18\x8d\xa1\x0c\x84\xec\x85\x4d\x8d\x50\xcd\xf0\x8b\x44\x81\x8f\xd1\xb3\xa2\x4f\xea\xf1\x9e\x6b\xe9\xe0\x05\xd6\xe6\x1b\xb3\x87\x44\x54\xa0\x5c\xcc\x9c\xe6\xbc\x28\xdf\xa0\xfe\x2a\xca\x8f\xc1\xa4\x8b\xb8\x87\xce\x12\x12\x51\xe2\xf7\xad\x30\x42\x50\xf5\xe3\x3e\x24\x76\x28\x86\xef\xeb\xd6\x2a\xfc\x57\xd1\xd8\xdf\x7d\x06\xdc\x66\xb4\x6f\xd7\x33\x12\x33\x8e\x1d\x2e\x45\x91\x1d\x04\xb2\xc5\x0c\x1f\x27\xf1\x13\x34\x76\x4c\x84\x4a\xd1\x58\xd9\x52\x13\x41\x12\x19\x20\xae\x4b\x41\x85\x15\x2f\xc2\xe8\x14\x52\x72\x4d\x95\xa7\x65\x3c\x74\x03\x75\x23\x87\xf6\xb3\x99\xf3\x91\x2a\xa2\x20\x5c\x33\x62\x3d\xad\xf7\x4f\x8b\xf5\xca\x8e\x08\x11\x46\x68\xe7\x61\x64\x79\x0b\x9f\x40\xb3\x34\x3f\xf6\x3d\x63\x02\x84\x44\x1e\x46\xf1\x73\x81\xf8\xb2\xa5\x2a\x48\xf9\x0e\x7c\x22\x08\x08\xc0\x02\x7f\x65\xcd\xbf\x15\x62\x94\x98\x21\x92\x38\xdc\xc4\x43\x8a\x69\xef\x83\x48\x91\xa8\x62\x2e\xf8\x5f\xe0\xb5\x96\xa4\x1e\x3e\x59\xe0\xb8\x21\xe6\x82\x37\xcb\xed\x62\xf9\xb6\x57\xc0\x8c\xdf\x4c\x23\x78\x66\xf7\xd8\x35\x17\x28\x39\x08\xa8\x4c\x0c\xd4\xea\x68\xdb\xe8\x4a\xe0\xfa\x9e\x79\xc5\xeb\xe6\x33\x15\x45\x99\xd2\x65\xde\xde\xff\x79\x74\xff\x81\xeb\x2b\x9a\xde\x0a\xea\xd9\xe5\x92\x8d\xb2\x39\xc3\x45\x2c\xf0\x5c\x05\xb9\x6e\x5d\xb5\x0a\x32\x13\xe4\x6d\x7f\xc7\x34\xdc\xe6\x79\xb6\x5b\x1e\x16\xcf\xb3\x97\x97\xe5\xdb\xd3\xd2\x36\x0b\x97\x7a\xd6\xb2\xb3\x3c\xce\xad\x69\x9a\x5b\xda\x42\x11\x10\xca\x48\xa0\xab\x44\x2c\xbc\xff\x2e\x40\xef\xdb\xd5\x3b\x20\xd2\xc1\xcd\x49\x85\xbc\x14\xfd\x88\x2a\xcf\xff\xab\x9c\x83\x3e\x41\xe0\x04\x9a\x74\x0b\xea\x59\x09\xb7\xf5\x75\xb6\x1f\xc7\x40\x63\x71\x51\xea\x6b\xa9\xc1\x1b\x88\x20\xa4\x5c\x2b\xa5\xb5\x46\xc4\x8c\x73\xb8\x20\x0d\x87\x92\x8c\xbb\xab\x10\xd4\x1e\x28\x43\x4b\x76\xd5\xc5\x91\x82\x50\x04\x91\x7a\x8f\xc8\xc9\xf9\x4a\xf3\xeb\xfd\x8c\x51\x10\xb9\x8e\xd5\x28\x04\x10\x73\xca\x3f\x1e\x01\x66\x98\xc1\xed\x2f\x64\x41\xe4\x72\xde\xc5\x8c\x26\x62\x04\x41\x14\x2b\x46\xf5\xa1\x42\x95\xa9\xf4\xec\xf6\x8e\x20\x62\x21\x8f\x4d\x68\x45\xd1\x8d\x8c\x94\xec\x4d\x47\xa0\x98\xc3\x7b\x6c\x5a\x63\x3d\x55\x55\xcb\xf3\x66\xe4\xbf\x05\xb1\xa3\xe2\x7c\x54\x88\x69\x83\x22\x88\x5d\x30\x1a\xd9\x87\xa6\x1a\x07\xf6\x82\x38\x88\x91\x38\x42\x29\x87\xec\x0a\x59\x2f\xac\x47\x6f\x5e\x6b\xcc\x13\x1c\x9e\x47\xfb\xe5\x62\x49\x51\xd9\x00\xa3\x7d\x8b\x9f\x0b\xf3\x7b\xe2\x51\xcd\x11\x9d\x65\xbf\xa7\x55\x35\xdf\x2f\x46\x6f\x2a\x21\x89\xc5\x0c\x35\x67\x45\xb9\x59\x8d\xfb\x84\x3e\x56\x15\xb0\x33\xdf\x64\xb4\x96\x45\x79\xb6\x17\x08\x63\xac\xf4\xc2\xf5\x37\xb7\x70\x34\x11\x24\xb1\x88\x54\x75\x47\x47\xe8\x32\x7a\xd4\x24\x89\x82\x0e\x9e\xf8\x5e\x66\x93\x96\x68\x90\x08\x8e\x55\x66\x22\xad\x2e\x19\xbd\x9a\x12\x13\xd3\x0a\x0a\xd5\x53\x54\x9c\x96\x4f\x4d\x9a\x8b\x3f\x19\x94\xc7\x61\x6c\x30\xa0\x81\xc0\xf7\x60\x41\x0b\x23\x74\x47\x7f\x48\xd0\x58\x01\xde\xb1\xf0\x54\x21\xd2\xae\x6f\xf4\x0c\x3a\x50\xa6\xc4\xc1\x87\xdf\x94\x79\x80\x05\xa5\x8b\x97\xd5\x63\x51\x3e\x51\x7b\x5d\x16\x29\xd5\x26\x45\x4e\x90\xe6\xc7\x21\x99\xb6\x08\x58\x2c\x30\x2a\x70\xd1\x54\xa0\x6b\x69\x5b\x98\xc4\x6a\x82\xaa\x61\x15\x2f\xd3\xa1\xbe\x8e\xee\xc3\x7d\xc0\xf4\xd8\xef\x3f\x9f\xef\x17\x50\x8b\x80\xb3\x00\x57\x63\x95\xfa\xfd\x3d\xad\x7b\xb9\x85\x80\x0b\x85\xb4\x51\xb4\x12\x7f\x8e\x97\x5b\xa0\x31\xe8\xea\xee\x0b\x26\x6c\xec\x81\x52\xc4\x89\x4e\xa5\xe1\xf6\x84\x85\x1a\xc3\x1b\x0c\x1d\x1a\x61\xac\xee\x61\xb9\x59\xef\x56\xfb\xdd\xe1\xf7\xe5\xc6\xe4\xcd\x43\x97\xd0\xff\x87\xb3\x37\xeb\x6e\x1c\x47\xb2\xc7\xbf\x4e\x3d\xcc\x03\x57\x90\x7c\x94\x25\xd9\x56\xa7\x65\xbb\x25\x39\xb3\xea\x3f\xa7\x8f\x0e\x96\x80\xcc\x36\x45\xaa\x49\xca\x4b\x7f\xfa\xff\x61\x04\xc0\x4d\x94\xb3\xe6\xf7\x30\x93\xd5\x26\xc4\x15\x08\xc4\x72\xe3\x5e\xa4\xab\xf8\x05\xe2\x74\x56\xca\xc6\x4d\xcc\x73\xc0\x05\xdc\xc2\x40\x55\x4f\x7a\x22\xfd\xcd\x3c\x09\xd8\x17\x29\xa9\x4c\x3f\x23\xb0\xd9\xf0\xab\x30\x4f\x07\x5e\x6c\x32\xbf\xab\xaa\x3a\x83\xea\x80\x8b\x8a\xf9\x90\x20\x05\x71\x1f\x81\xf0\xb7\xca\xbb\xf1\xc4\xff\xef\x4f\x58\xe6\xeb\x08\xaf\xdb\x44\x72\x8d\x03\xd5\xb6\xf4\x8e\x77\x82\xc1\xaf\x02\x16\x61\xae\xc4\xb4\x9d\xde\xf1\x23\x58\x86\xc4\x3f\x26\x36\x7a\x16\xc6\x31\xe6\xe8\x37\x85\x28\x6a\x5e\x76\x24\x82\xc3\x37\xc5\x42\x9f\x93\xf3\x0d\x6a\xdf\xbc\x89\x6a\xff\xce\xcf\x59\x6d\x2b\x30\x8c\xc5\x8a\x77\x42\x33\x33\xa3\xb7\xbf\x3b\xc2\xa7\x59\x43\x73\x9e\x93\xa7\x08\xe3\x53\x73\x49\x84\x00\x45\x59\x9f\x73\xd8\x17\xa7\xb1\x1d\x66\x11\x8f\xd0\xfb\x23\xe7\x6a\xbc\xe8\x26\x9c\x54\x16\x09\x81\xbd\x3f\x3d\x70\xac\x62\x71\xe0\x89\xb0\xa5\x6e\xc4\x00\x17\xd9\x73\x09\xe3\x3f\xb9\x27\xb1\x38\xa4\x26\xef\x9a\xbf\xa1\xd0\xf1\xef\xea\x73\xf6\x67\x82\x48\xac\x5a\x0a\xd3\xa2\xdf\x44\x35\xb9\xbe\x58\x2c\x24\xd2\x9f\x37\x31\x32\x6a\x1f\x81\xaa\x2e\x11\x88\x8a\xc5\x0a\x90\xc1\xc5\xb2\x68\xd4\xdc\xca\x81\x76\xc5\x15\x96\x38\x1a\x67\xcf\x43\x71\xd8\x5a\x40\xe3\x25\xfc\x86\x71\x3f\xc0\x8a\x1a\xca\xc5\x3d\xa4\x18\x54\x5c\x44\x09\xc3\x47\xe3\x52\x60\xe6\x63\xb3\xdc\x2e\x37\x3f\x97\xfb\xe7\xa7\xa7\x87\xfd\x6c\xb1\xd8\xd8\x4b\x73\x4d\x6c\x0d\xe7\xbc\x71\x3c\x9a\xa9\xbb\x3d\xc1\x15\x59\x53\xc5\x84\x4b\x94\x07\x69\xbe\xaf\x5e\x79\xf3\x09\xf7\xa7\x9e\xff\xca\xa4\x1b\x71\x42\x69\x7c\xa4\x23\x45\x08\xc5\xa4\x17\x6a\xab\x4c\x78\x3c\x42\xe3\x55\x75\x4f\xe9\xb6\xa3\x42\x1e\xd3\xdc\x7c\x87\xf2\xa2\x22\xc9\x94\xcb\x90\x15\xf1\x9c\x63\xf4\xd8\x25\x99\x99\x0a\x24\x37\x90\x9c\xba\xe8\x08\xec\x2e\x19\x08\xa7\xe7\x8e\x52\x1a\xd1\x7a\x48\x93\xba\xa6\xf8\xb3\x99\xb9\x28\xbc\x62\xc7\x68\x1f\x7b\x48\x45\x51\x96\xbc\x34\x56\xa4\x18\xa3\xee\xcc\x60\xf0\x84\xa0\xf4\xf0\xe1\x9c\xf1\xf2\xbe\xe8\xe6\x36\x68\x1f\x03\x14\xbc\xd6\x05\x91\xa8\x62\x3a\x72\x74\xbf\x64\xf2\xd3\xf8\x1e\x43\xe2\xcd\xdf\x38\x9d\xf6\x5c\xb1\x63\x23\xf1\x9b\x2e\x3f\x52\x19\x0e\xfb\xf1\x85\x65\xe2\xb4\x81\x42\x7e\xae\xe0\x7b\x75\x37\x15\x39\x8c\x9c\x8d\xb4\x6a\xb6\xcb\xa1\xb1\x88\x5c\x87\x12\xe8\x2f\xd9\xa0\x83\x5b\x45\x5e\x40\x9a\xb4\x27\xfe\xb5\x2b\x14\xff\x32\x90\xbd\xe1\xaf\x03\x27\xf2\x3c\xfb\x92\xf6\xa7\x12\xf6\xa9\xb4\x81\x77\x14\x4a\x1f\xf3\x6c\x7b\x2a\x01\xcf\x33\xe0\x84\xd5\x48\x25\x20\x83\x24\x1f\xb7\x13\xa9\x88\x79\xc2\x51\x43\x4d\xde\x6f\x0b\x32\x11\xe3\x31\xc2\xe0\x9f\x9b\x7d\xfc\xcf\x79\xdb\x2b\xaf\x22\x26\x80\xba\x21\x71\x7b\xdc\x37\xfb\x28\x71\xc6\xef\x3e\x5b\xfc\xd9\x74\x78\x12\x31\x15\x99\x69\x81\xfe\xb1\x81\x95\x8c\x7f\x64\x06\x47\x81\xe2\x44\x62\xb4\x85\xba\xc3\x96\xaa\x28\x62\x11\x85\x7c\xc5\x47\xfe\x5e\x50\xa3\x3e\xe4\xf5\xb7\xd2\xa5\x2a\x8a\x62\x82\x5a\x50\x8c\xd7\xe7\x08\xe9\xbe\x68\x1c\xf9\xa6\x6f\xa5\x71\xb4\xa9\xd6\x05\x73\x5e\xaa\xdf\x06\x25\xdf\x07\x2b\x51\x2c\x22\x0c\xba\x5b\x35\x15\xeb\x7c\x4f\x50\xfd\xa8\x88\xf3\xd8\x40\x62\xb0\x5a\xd8\xac\xf3\xff\xb7\xcb\x72\x70\x30\xb7\xd1\xb8\xb9\xf7\xc5\xb9\xac\x2e\xde\x91\xdd\x68\x5b\x77\x30\xe2\xda\xd1\x7d\xac\xfc\x43\xc1\xf3\x69\x28\x42\x24\xbc\x24\x31\x08\x09\x94\x12\xec\x6f\x6c\x91\x88\x25\x92\x5e\xd3\x3e\xdb\x55\xc3\xab\x5d\x31\x7a\x5c\xa1\x13\x44\x3f\x10\xce\xb5\x71\xfb\x3c\xfb\xa9\x65\x98\x10\xb5\xc4\x6b\x91\x8e\x70\x5e\x91\x4c\xa8\x43\xd8\xa6\x77\xf6\x24\x91\x30\xb8\x09\xa9\x02\x49\x2c\x2d\xb9\x72\xdb\x93\x2a\x10\x6e\x6f\xcb\xfb\x63\xc4\x93\x3e\x88\x63\xcc\x6f\x14\x37\xca\xac\xe7\x0c\x66\xa3\x59\xa3\x64\xec\x4a\x43\x36\x3f\xd3\x35\x94\x2b\x59\x8c\x87\x00\x47\xd2\xb5\x1a\x2a\xa3\x82\x6e\xe9\xd7\x06\x45\xd3\x08\x12\x0f\xe3\xf4\xf9\xaf\x39\x35\x52\xa2\x1f\x37\x7a\x5f\x20\x38\xe6\xeb\x0e\x3c\xe7\x43\xb8\x57\x04\xca\x45\x10\xf8\xcd\xe3\x0d\x55\xa2\xf7\x54\x0b\x5c\x2c\x1f\x9f\x8c\x46\x99\x8a\x9d\x40\xe2\xc2\x22\xa0\xfe\x2d\x6a\xc2\x5c\x78\x0b\xbf\xab\xa4\x0c\x6e\x29\x76\x18\x35\xdc\x51\x84\x6a\x13\x6d\xe3\xc9\xd6\x85\xc2\xe6\x24\x57\xce\x25\x95\xc5\xdd\x60\x18\xf1\xc7\xe8\xb8\x90\xb1\x71\xe0\x1f\x4d\x75\xb2\x47\xaa\x51\x3d\x21\x09\x76\xd5\x3e\xac\x26\xf4\xd2\xb2\x7e\xc5\x37\xb5\x3d\x15\x79\x35\x36\x8f\xb1\x1b\xf1\x64\x30\x25\xce\x44\x37\xf5\x2f\x7b\x3c\x0e\x30\x3d\xb9\xb7\x0f\x08\x32\x2d\xce\x97\x6d\x1a\xfd\xc9\x17\xbb\x10\x23\x8a\xe9\xae\x90\x32\xb1\xf7\xe3\x31\xc0\xad\x96\x82\xc0\xfa\x1b\xda\xbe\xef\xf8\x77\x7b\x0b\x36\xf6\x12\x37\x20\x04\xd7\x17\xb6\xa4\x8d\xac\x49\xec\x87\x01\x8a\x85\x40\x25\xcb\xe2\x63\xb4\x8a\x62\x3f\x21\x2a\x3a\xd9\xdf\x45\xe6\x85\xb2\x53\x2a\xf6\x75\x88\x6e\x8d\x4a\xdf\x67\x47\x3b\x51\xe3\x40\xfa\xc8\x68\xd5\x98\xff\x6d\x7a\x68\x22\x96\xc1\xd7\x36\xc3\x42\x8f\xfa\x99\x28\x8d\xba\x98\x3d\xd9\xdf\x87\x4a\x20\x32\x8e\xb8\xfc\x97\xb9\xba\xf9\xb2\x58\xe2\xc1\xca\x89\x23\x5f\x63\xd9\x05\x8b\x32\x0b\x78\xef\x09\xcf\x0c\x1f\x33\x92\x94\x15\x5f\x1c\xb3\xd6\x01\xba\x8a\x7b\x88\x63\x9f\x47\x26\xf7\x72\xf3\x45\x9a\x4b\xa3\x01\x01\xc7\xfd\x3b\x95\xc5\xd3\x09\xf2\x66\x7b\x6b\xd9\x4e\x54\x13\x8a\x30\x02\x7f\x0d\xc0\x5a\xf6\x28\x27\x0a\x8e\x0a\xea\x67\x7e\x99\xf3\x88\x63\xa5\xb1\x0b\x26\x7b\x47\x12\x99\xeb\x6c\x8d\x2a\x4e\x42\xe2\x9f\xa7\xc5\xbc\x7a\xbc\x7d\xda\xac\x11\x86\x82\x8e\xec\x72\x6b\x33\x90\x71\x12\xd1\x2c\xa0\x0d\x1e\x1d\x18\xcb\x10\xde\x53\x08\x1d\x9e\x9c\x3b\x31\xa6\xd0\x4c\x06\x08\xc9\x51\xae\xbc\x2f\x1e\x28\x69\x4a\xbc\x48\x05\x00\x3f\x52\xf9\xf6\xb3\xa8\x2f\x66\x1b\xe7\xa4\x13\x49\xde\xc1\x2a\x3f\x9d\x47\x99\xa5\x58\xba\xa4\x24\x8a\x5a\x87\xfb\xb3\x0d\x04\x62\x15\xb4\xda\x81\xc6\x80\x58\x0f\xa5\x63\xe2\xf9\x05\xe9\xe8\x6c\x2a\x61\xe8\x58\x57\x75\x21\xdf\x9a\xb8\x67\x0e\x65\xcd\xd3\xfc\x5b\x52\xb2\xd1\xc3\x29\x4d\x1a\x80\x3c\x4b\x8f\x3d\x7d\x0f\x15\x83\xef\x61\xc6\xe6\x27\x91\xcc\x0d\xf6\x96\xe6\x20\x71\x41\x95\x3c\xaf\x9f\xa1\xb4\x64\x41\xc3\xfb\x03\xa1\x31\x68\xfc\x77\x91\x92\xe6\x04\x25\xdb\xa6\x6f\x04\x54\x1c\x18\x3c\xf4\xf2\xf3\x94\x96\x5f\x8b\xae\x00\x19\x6b\x27\x89\x0d\x13\xce\xf3\x6a\xdf\xac\xa7\xbd\x1b\x0c\x6e\x29\x71\xbc\x84\x74\x13\x78\x99\x91\x64\x42\x47\x83\x3f\x5d\x68\xb4\x3f\x64\x31\x62\x1d\x91\x2d\xe8\x54\x14\xd9\x30\x9f\x94\x38\x8c\xa3\x9c\xd9\xb6\xc8\x78\x69\x55\x6e\x54\xe2\x70\x48\x86\x7d\x75\x94\xbc\x30\x87\x5d\xc7\x47\x56\xb7\xf7\x26\x6c\xbd\x2d\x8b\xa3\xa5\x8a\x99\x7c\xfa\xc4\x65\x21\x7a\x5f\x87\xf4\x1d\xe6\x45\x5e\x35\x23\x27\x42\xe6\xc4\xe5\x0a\x9d\xe3\xbb\xb2\x38\x9f\xf6\x61\x7b\x35\xa1\x5d\x0a\xcf\x3f\xe5\x44\xb7\xf3\xe0\x14\x9e\x1f\x32\xd7\xe4\x09\x91\x81\x75\xfa\x8e\xbc\x80\x68\xa1\x28\xcd\x68\xb9\xe9\x3a\x5a\x34\x95\x78\xc2\x95\x8e\x45\xaa\x60\x39\xe3\xc2\x55\xec\x67\x7e\xfb\x35\xed\xa2\xc8\xec\xfe\x92\x78\xc2\xb7\x49\xd2\x9f\x3d\xf1\xb4\x49\xb7\x2b\xf1\x03\xc6\x4d\x73\xf8\xec\x00\xf9\xa0\xcb\xc3\x0a\x02\x8e\xe3\xa2\x81\xd1\x4f\xfc\x50\xe1\xab\x6a\x0b\x39\xe8\x6b\x3c\xe5\xd9\xd7\xcd\xf9\x6b\x22\xfa\x4e\x7c\x16\x21\x2b\xe4\x2b\x47\x7e\xf7\x1f\x00\xa7\x34\x3f\x0c\x29\xf0\x55\xe2\x47\x1a\x37\x85\xb4\xba\x81\x03\x56\xa9\x51\xd4\x76\x04\xa2\x4e\x7c\x4e\x9b\x69\x33\xcb\x4d\xa9\xa7\x37\xcf\x13\x5f\xf9\x5c\x5a\x32\xde\xb2\xa2\xb4\xc1\xc0\x4d\x4a\x02\x15\x60\xc6\x6c\xb1\xfc\x39\x7f\x98\x6d\xb7\xfb\xdb\xdd\xc3\x7e\xfb\xbc\x5c\xda\x02\x4b\x12\x7a\x21\xee\x06\x7f\xf1\xfc\x0d\xa0\x71\x0a\x8a\x0c\xaa\x20\x6e\x8f\x47\x11\x76\xce\x37\x0e\xd9\x06\x8e\x45\x0d\xbf\xfa\x5b\xff\x77\x2e\xf6\x54\xc8\x79\x41\xaf\x3e\xfa\x64\x61\x4c\x32\x20\x23\xc0\xc7\x35\x27\xab\x37\xc1\x42\xad\xac\x3a\x19\xe9\xb9\x20\x59\xd6\x2c\x9b\x56\xd8\x53\x09\xf3\x14\xf6\x49\x88\x73\x99\x3f\x80\xae\x07\x50\xc3\x84\x25\x1e\xd6\x09\x7e\xa4\xf9\xe1\x1f\xfc\x38\xa0\x41\x56\x09\xe3\x1e\x62\x7e\xb9\x52\xdb\xb6\x20\x7f\xb9\x2a\x22\x16\x98\x62\x03\xc6\x47\x46\x12\x69\xfc\x4c\x83\xf5\x16\xc5\x2c\x8a\x0d\x41\x9a\xe7\x8f\x26\x57\xa4\x65\x68\x9d\xf4\xe9\xdc\x4b\x12\x3b\x94\xf9\xe0\x59\x56\x7c\x34\x6e\xdc\x32\x4b\x91\x86\xfb\xa2\xfc\x64\x7f\x10\x4a\x6c\xcb\xad\xed\xfc\x2b\xb2\x0d\x60\xf1\xf1\xd1\x60\x1a\x3a\x65\x1a\x95\xc4\xca\xc3\xcd\x7e\x56\xd6\xbc\xf8\x1d\x81\x89\x4a\x12\x4f\x10\x13\x17\x76\xa8\x5a\xbe\xb8\xef\x31\xe7\x09\xf7\x23\x65\x3c\x8e\x35\xff\x34\x13\xc1\x1e\x13\x1c\xcd\x6f\x4b\x11\x73\x65\xae\x99\xe1\xc2\x0d\xb1\x3e\x81\x6a\x5f\x65\x31\xb0\x76\xc3\x8b\x8a\x80\x23\x8d\xb0\xc8\xf2\x13\x94\xd0\x42\x0c\x13\xe9\x3b\xe8\x98\x19\x7f\x96\x9f\x3a\xa6\xe2\xe9\x33\x49\xe6\x58\x29\xac\x21\x81\xd0\xb6\x18\x74\xdf\xaa\x44\x85\x74\xcd\x0e\x85\x3a\x34\x49\xdf\x45\x18\xd3\x32\x05\x2a\x51\x40\xb5\xe1\x0a\x8c\xb5\x1b\x71\x84\xa9\x04\xe2\x40\x98\x16\x94\x72\xce\x8f\x27\x9e\x1e\xf2\xd5\x62\xda\x9b\x49\x20\x8e\x6c\xbf\x23\x85\x18\x43\xb6\xcb\x66\x00\x28\x53\xd6\x5a\xe6\x58\xc2\xfd\x0b\xf8\x25\xd5\xcb\xf8\xb4\xd2\xc7\x74\x53\xe3\xac\xed\xee\xf7\xcf\x9b\x25\x41\x82\xef\x37\x4b\x5b\x6a\x4d\x40\x92\xda\xe0\xcd\x72\x77\xbf\xdc\xc8\xae\x78\x98\x68\xc6\x4c\x34\x9d\x2b\xcc\x84\x97\xd7\xfd\xd7\x44\x73\x12\x8c\xae\xce\x95\x2c\x53\x01\xbb\x32\xe5\xd9\xe8\x95\x68\xed\x12\x19\xed\x1e\x77\x65\x1b\x54\x73\xc7\x0f\xb0\x0f\x4d\x67\xe7\xea\xd5\xa8\x78\xc3\x28\x13\x31\x9c\x71\xdc\x49\x34\x97\x66\xbf\xbc\x79\x3b\xcc\xea\xe5\xa7\x7c\x9d\x16\x76\x51\xdc\x91\x1e\x06\xa1\xd8\xfc\x40\x0e\x7e\xd9\x5e\x5b\xb9\x88\x0f\x68\xa6\x10\x4e\x1d\x7b\xc0\x75\x05\xf2\x08\x88\x54\x29\x6a\x1a\x6c\x69\x15\x14\x77\x7d\x85\xa8\x99\xf9\xd3\xe3\x6e\xb3\xba\x79\x69\x1c\xe0\xed\x7e\xdd\xc2\x0b\xb8\xcb\x22\xb4\x7a\xaa\x45\xb8\xc0\xf5\xf2\x2d\xf7\x82\x00\x29\x34\x6d\xe6\x00\xb1\x4a\x57\x18\x08\x15\xf7\x13\x6a\x5d\x32\x65\xbb\x0a\xca\x2d\x85\x59\xe6\x78\xe0\x50\x61\x62\xc7\xab\x37\x8b\x96\x1a\xcc\xe9\x76\x1c\x47\x70\x14\x1c\xd3\x2b\xaa\xa1\xa3\xdb\x0c\x94\x52\x5d\x50\xbd\xfd\xaa\x6a\x38\xf6\x50\xa3\xb6\x11\xbd\x03\xcb\xd9\x3c\x32\x0f\x79\x10\x04\x2d\x28\x62\x9b\x1a\x53\x6e\x97\x13\x0f\x45\x1c\x5b\x09\xda\x1a\xb6\x50\xf7\xf8\x8f\xaf\xba\xc9\x3c\x54\x20\x4c\x1f\xdb\xcd\xb9\x4d\xa5\xf6\x3b\x86\x06\x66\x92\xb3\x20\x66\x84\x6b\xcf\xde\x4c\xca\x95\x7e\xd4\x6c\x60\xf4\xe4\x30\xc1\x56\x31\xf2\x8d\x38\xe3\x8e\x32\x25\xeb\x9b\xe2\x28\xfa\x90\x4a\xce\x44\xac\x6d\x18\x8a\x9d\x8e\x95\x21\x0c\x18\x92\xb6\x28\x1e\x79\x09\x32\xc0\xa6\x15\xe2\x33\x2a\x54\x63\x1c\x7e\xe7\x28\x8c\x31\x39\xd9\xdc\x2a\x2f\xe5\x2b\x7a\xeb\xd8\x6c\x7a\x6c\xe9\x0d\x15\x8f\x9d\x18\x93\x8f\x98\xfa\xdf\xfb\xfb\x4e\x1a\x57\xf1\x58\x78\x48\x7b\x66\x08\x81\x05\x7a\x3d\xd7\xb1\x73\xf6\x57\xca\x07\xa4\x9f\x2c\xba\x13\xe9\x88\xf4\xa6\xce\xe2\x98\xd6\x3f\x53\x05\xc5\xe4\x1b\x4e\x3c\x70\x8c\x1d\x5b\x9a\xf0\x63\xce\x4f\x43\x33\xc0\x13\x11\xba\x96\x8b\xc8\x74\x12\x1a\xa4\x9d\x1b\xb1\x7f\x5d\x16\xf7\xec\xcf\x94\x83\x1d\x28\xb8\x69\xfe\xf3\x0c\xe3\x34\x14\x17\x8e\x1f\x05\xc6\x5e\x91\x70\xea\x2d\xd5\x7c\x6d\x4e\xea\x2a\xf2\x81\x0b\x1f\x22\x3e\xd2\xd3\xca\xf8\xe5\x16\xd1\x59\x64\x2e\x22\x92\x2d\x90\x45\xfe\x0e\x65\x6d\xd4\xef\x2c\x64\xd0\x0e\x12\x24\x96\x56\x1a\xb9\xd4\xe1\x8b\x90\x6e\x64\x41\x37\x37\xbc\xae\x33\xf8\x71\x1e\x57\x98\xb9\x54\x1c\xab\x0f\x26\xd1\x73\x97\x96\xd9\x1f\x13\xf2\xea\xdd\x0f\x94\xa7\x6d\x9f\xd4\x03\xf0\xaa\x89\xdb\x20\xaf\xd2\x77\x40\x23\x71\xc5\x00\xa9\x30\xc6\xed\x2c\x87\x8f\x59\x5d\xb7\x9c\x4d\x8a\x2b\x26\x10\x49\xbd\xbf\xc2\x14\x6e\x87\x29\x81\x24\x16\x3f\x7f\xf6\xfd\x37\xae\x74\x84\x11\xe2\x8f\xb3\x2a\xaa\xa7\xf2\xc0\x73\x83\xf4\x1b\x05\xe9\x1c\xfc\x10\x01\x25\x9b\xbb\x3f\xa9\x97\x6a\x3a\xc9\xd4\x9f\x0e\x90\xc4\xe8\xc1\xdd\xf0\xfc\x0d\xb7\x93\x3d\x69\xa8\xcc\x8b\x3c\x07\x59\x37\x7f\x6e\x49\xa1\x1f\xe1\x03\x87\x0c\x83\x48\x0e\x82\x58\xbc\x9b\x0d\xf7\xf9\x7c\x3a\xb5\xbc\xe9\x8a\x83\x22\x41\x0c\x6c\x88\xb8\x88\x58\x87\x2f\x4f\x3b\xe0\xd2\xf6\x82\xa0\xf0\x87\x66\x8d\x9a\xf3\x08\x47\xb9\xc8\x29\xf3\x73\xb5\x98\x3d\xf4\xf0\x67\xc2\xf3\x89\x0a\x70\x3d\xdb\xdc\xad\x1e\xf7\xdb\xe7\x87\xd5\x6e\x6f\xa0\x5c\xb3\xbb\xe5\xfe\x66\xd6\xe2\xdc\x85\x17\xd2\xaa\x3a\xe0\xec\x1c\x31\x2a\x29\xe1\x31\x85\x9d\x86\x88\x97\x30\x73\x7d\xcc\x5b\xa8\x04\xf2\x73\x37\x53\xf1\x68\x9b\xce\xa7\x08\x36\x94\xf0\x0d\xda\xe3\xb6\x2c\xfe\x0b\xb9\x19\xb3\x87\xeb\xa9\x18\x11\x68\x8f\xba\x8d\x71\x86\x6e\x8a\xe2\xf8\xc7\x54\xea\x48\x84\x51\x82\x2d\x35\xcb\xdd\xfd\x73\x7f\x9a\x88\x30\x01\x2c\x2f\xac\x91\x51\xd3\x6e\xb2\x82\x71\xe5\xdb\x1c\xf5\xf2\x78\x6a\x61\x52\x82\x81\xa3\x89\x1e\xef\x93\x7a\x58\x6f\x7b\x84\xfe\x03\x83\x24\x98\xe6\xd8\x4a\x6d\x79\x1d\x7b\xba\xda\x17\x6f\x28\x8a\x95\x91\xdf\x3e\xa6\xf9\x16\x78\x66\xa4\x5d\xfb\x76\x5b\xc4\x0e\x43\xd0\xc5\x91\xbf\x19\x7e\xa3\x27\xdd\xe2\x54\xaf\xbc\xa0\x38\x09\x91\x4c\xa2\x71\x05\x0c\xa9\xd0\xf0\x9d\x27\x7e\x82\xb5\xad\x56\x0e\x77\x5c\x92\x10\x89\xaf\xa5\xe9\x38\xbe\x19\x89\x17\x28\x91\x84\x9c\x27\x96\x92\xe0\xc8\x91\xe0\xac\xdd\x20\x04\x77\x79\x10\xd8\x84\x14\x71\xb9\x6e\x21\xcb\x7e\x4f\x92\xaf\x04\xf7\x99\x1b\x50\x5c\xb1\xe7\x83\xb5\x23\x78\x28\x31\xcd\x65\x33\x2d\xf3\x22\xbd\x86\x3f\x16\x3c\x01\x0c\xd6\x97\xeb\xd9\x7c\x02\x2c\x26\xb8\xd4\xc8\xae\x78\x22\x75\xd3\x4e\xdc\x58\x09\x91\x38\xa1\x65\x0c\x01\x79\x2e\x53\x5b\x32\x1d\x65\x6e\xcc\x70\xc9\x3c\x54\x3d\xbb\xc9\xd2\x5c\xcd\xcb\xe2\x7c\x4a\x8d\x23\xd9\xc7\x10\xb6\x5f\xde\x65\xdd\x56\xe0\x32\x3b\x0f\xa4\x74\x9d\xa0\x6d\x9f\x2a\x0d\xc3\xee\xc3\x58\x3c\x4d\x09\x09\x7e\x62\x6e\xce\xa4\xd1\x78\xf9\xb5\xd7\xe7\x1c\xdd\xa1\xbd\x34\x12\x61\xc3\x1f\x29\xe6\x30\xb3\xfb\xed\x1b\x73\xd1\xbe\xd8\xc9\xcc\x88\x80\xc8\x45\x14\xf8\xf2\x69\xfb\x9c\x9d\x07\xe1\xb1\x00\x45\x9c\x43\x39\x7c\x9a\xda\x86\x71\xbe\xfe\xce\x3f\xe6\x1c\x3a\x22\xbf\x5d\xf6\xfa\x11\xec\xa1\x58\x68\x43\xe5\xb6\x29\xb0\x26\x63\x0f\x68\x4e\xa2\x0e\x86\xa0\xfd\xfc\x35\x59\xbd\x94\x8e\xef\x85\xfd\x82\x58\xe3\xaa\x0e\xb3\xfd\xd2\xf1\x85\xd7\x85\x7d\x8f\xbb\x9f\x2f\x7f\xd8\x23\x21\xc3\xaa\x6e\xcd\x3f\x07\xb9\x16\xe9\x24\x12\xdd\xdf\x53\x59\xd4\x28\x2e\x6d\xb5\xc8\x27\x27\x9f\xf4\x18\x43\xa7\x8f\x30\x15\x4f\xe7\x5a\x16\x2d\x6d\xd7\x78\xa8\x12\x68\xa0\x9a\xb5\x4d\x94\xee\x0b\xe0\x97\x84\x8f\xa3\xbc\xa5\xf9\x71\x10\xb9\x21\xf1\x63\xd6\x5c\x43\xfb\xb2\x9a\x19\x89\xb8\xd2\x75\x9a\xd7\xcf\x65\x51\xe8\x27\x8d\x14\xe3\xf6\x78\xe4\x88\x8e\x72\xa2\x2c\xf1\x89\x90\x58\xe4\xe6\xf9\x49\x0f\xc9\x4d\xad\xa5\x92\x11\xf7\x20\x34\x96\x71\x0b\xf5\xf9\x84\xc5\xbb\x2a\xb5\x08\x2e\x19\xc7\xae\x1f\xb7\xfe\x5a\x5f\xdc\x7c\x60\x1e\x65\x2c\x12\x4c\x1c\x68\x77\x68\x6f\x50\x74\x2d\x20\x7b\x53\x9c\xeb\xe1\x07\x68\xcc\xa4\xa2\x70\xea\x9d\xd7\xb8\xe7\xed\xc5\x58\x64\x58\xc9\x24\x0c\x03\x32\xa7\xff\x3e\x1b\x68\x94\xdd\x79\x2e\x71\xe4\x32\xe1\x0a\x0b\xab\x47\x7c\x92\x49\x66\x13\x3b\x52\xc4\xe8\x11\x19\x87\xe8\xdc\x57\x1d\xfb\x5b\xe9\x75\x99\x28\x1f\x42\xdb\x39\xd1\xd8\x42\xca\x36\xf6\x64\x5d\x46\x3f\xe0\x7e\x84\x7a\x39\xb7\x03\x92\x1e\xc9\x65\x8c\x59\xcb\xdd\xee\xb1\x4f\x67\x69\x8e\x8a\x80\x61\x09\x0f\xab\x18\x4d\x7c\xd2\xe3\x81\xff\xcd\x0d\x8a\x50\xe2\x1b\xfe\xe4\xe7\xf2\x7c\x44\x80\xc9\xaf\xa2\x7c\xeb\x5a\x9b\xa4\xe0\xd2\x7a\x79\x77\x63\x7b\x2a\x85\x56\x68\x9b\x21\x57\x48\xf4\x7b\x93\x96\xed\x74\x94\xdc\x45\x72\x62\x7c\x90\x0d\xd4\x65\x0a\xad\xae\x89\x92\x52\x70\xb4\x28\xeb\xd9\x9f\xfb\xc5\xf2\x79\xb6\xd9\xbd\x6c\x96\xfb\x87\x95\x2d\xd5\x4a\x15\x40\x60\xf8\x40\xee\xc6\xca\xb0\x4a\x2a\xa9\x1c\x23\xab\x86\x24\x68\xa3\xc3\xc0\xa8\xb7\xf2\xc7\xfd\xee\xbb\x74\x96\x04\xa1\x2c\x63\x00\xa2\xd0\x76\x25\xf0\xea\x5c\x4e\xc3\x32\x94\xe3\x01\x2a\x47\x7d\xc0\x5d\x51\xcf\x4c\xe0\x38\x69\x0b\x94\x03\x84\x86\xc3\x94\x57\xf9\x06\xf5\xde\x6e\xdd\x2f\xd5\x90\x4c\x5a\x29\xd7\x8d\x50\x84\xd4\x80\xb5\x16\xa6\x91\x7a\x7f\xf3\xf4\xf2\xb8\x5b\x2d\xb7\xfb\xd9\xe2\xe7\x6a\xfb\xb4\xd9\xb6\x3f\xe0\x09\xba\x2b\xbf\x96\x7e\xbf\xf7\x44\xb9\x52\x1a\x34\x81\x7c\x9d\x4f\x64\xc6\x7e\xfb\xef\x64\x16\x40\x79\x71\xe4\x5b\xc9\xfe\xd0\xb1\x17\xf3\x12\xf2\x24\x30\x99\xd3\xf8\x9b\x03\x7a\x0f\xe5\xe9\x98\x11\xc9\xc5\x67\x87\x97\x37\xc7\x7c\x87\xe9\xa8\x25\xda\x2f\x87\x85\x7c\xe5\xbb\x31\xf2\x1e\x9e\xf3\xc6\x77\x6a\xb6\xe8\x4e\x3e\x7a\x60\x08\x95\x1f\x68\x4c\x7d\xb4\x8e\x16\xe6\xb2\x86\x37\xdf\xf8\x3b\xcd\x87\xd8\xbe\xb4\xaf\xc9\x07\x95\x18\xc4\x58\x33\xd7\x0d\x2f\xf2\xc0\xd6\xda\x74\x82\x0a\x1c\xdf\xe9\x98\xfd\xfe\x71\x2e\x8b\x72\x14\x37\xa9\xc0\x89\x70\x9e\xff\xe4\x76\xcd\xa8\x40\x93\xe4\x6b\x8f\xcd\xef\x2f\xe0\x76\xee\xab\xd0\xf3\xb0\x2f\x63\xb6\x6b\xef\x29\x14\x61\x0c\x6d\xf7\xcb\x1d\x3f\xc2\x43\x71\x48\xe5\xe8\x61\x98\x13\x5b\xd4\xfe\x73\x09\xab\xf9\xd3\x25\xb5\xae\x52\x2c\x09\x74\xf3\x56\x30\x7b\x87\x7c\x61\xb3\xac\x04\xae\xbe\xc6\xc1\x85\x1d\x2f\x78\x04\x1d\x32\x69\x5f\xc2\xb1\x6b\xcd\x52\x91\x43\x64\x25\x04\xb8\xea\xe7\x5f\xba\x33\x44\x71\x84\xbb\x2f\xd7\xba\x59\x38\xfb\xf6\xb7\x9c\xb4\x05\x6f\x32\x2e\xdf\xb6\x39\x4f\xb3\xf1\x62\x3c\x5f\x40\x6a\x55\xec\x02\x26\x8b\x3b\x36\xf9\xcd\xf2\xd7\x6c\xd3\xae\x8a\xc7\x97\x75\xbb\x10\xe2\x30\xb0\xf4\x42\x0f\x05\xcf\x77\xc5\x73\x51\xd6\xba\xc8\xd2\x62\x3a\xfa\x54\x31\xf7\x30\x9b\xb6\xe6\x6f\xc4\xf1\xca\xff\x06\x51\x8c\x4a\x98\x34\x8c\xb6\xb8\x05\xdd\x95\x3c\xaf\x01\xaa\x9e\xcc\xb0\x19\xc8\x9d\xc0\x98\xc3\x9a\x08\x74\xac\xa7\xd2\xe6\x64\xec\xc6\xaa\xb8\xef\xf0\x3e\xd6\x6f\x96\x2b\x23\xdf\xf9\xb7\x0c\x77\x13\xc8\xa2\xd3\xf2\xb2\xeb\x75\x61\x28\x21\x1d\xac\xa2\x9e\x32\xfe\xe5\x5d\x31\x4d\x42\x26\x91\xe1\x20\xa7\x8c\xe1\xe8\x21\x84\xd5\xb7\x6a\x26\xaf\x3d\xb1\xf4\x19\x2a\x67\xde\x58\x2a\x68\xd5\x6c\x4a\xa8\x22\xb6\xc7\x68\x70\x6a\x26\x4a\xe1\xa1\x15\xce\x9a\x63\x43\xf3\xa0\xdc\x04\x71\x00\xa2\x28\xde\xee\x2e\x88\x77\x94\x62\x9a\x53\xbb\x8d\x2c\x8e\x69\x7e\xd8\xf0\x5c\x15\x47\xc2\xbc\x2c\xcb\xf2\xe2\x9e\x95\x22\x1d\xe7\x6e\xd2\xdc\xcf\x36\x8b\xf9\xec\xb9\xbd\x9e\xf6\xc1\x35\xcd\x80\x50\xd5\x2d\x18\xed\x52\xae\xd6\xfc\x00\xdc\x04\x77\x5c\xd3\xc3\x5f\xad\x8e\xa7\xa2\xac\xbb\x54\xb2\x82\xc8\x0b\x5c\x9b\xea\xc5\xb6\x41\xdb\x0f\x7b\xe5\x84\x91\x42\x21\x50\xdc\xf0\x76\xf7\xed\x69\x12\x8e\x75\x6b\x85\xd0\xa8\x5e\xba\x4d\x41\xa2\x63\xb7\xeb\x45\xfb\x75\x0b\xad\x89\x04\x4e\x8d\x6c\xc4\x4f\xbb\xac\x24\x3f\xc1\x7d\x8f\x01\x4e\x01\x97\xae\x01\x0a\xdd\x16\x25\xa4\x07\x22\x7f\x1a\xa5\xa7\x86\x76\x1e\x1c\x4f\xe0\xec\xb5\x5c\x2f\xdf\x43\xa1\xc1\x65\x1a\x51\x85\x1a\x6a\xf9\xba\xe0\x5f\x83\x4d\x0d\x5c\xf0\xfc\xa0\x7b\xe1\x2f\xdb\x05\x15\x57\xfb\x9f\x19\x3c\x4f\xe2\x29\x0c\x4a\x9a\xf4\x18\x86\xe7\xf1\x13\x85\x89\xc5\x45\xaa\x75\x2a\xcf\x59\xfd\x85\x82\xa0\x23\xa7\x0e\x7c\xae\x1c\xaf\x23\xfb\x22\x37\xf2\xe6\xab\xf9\xef\x31\x79\xae\x02\x5f\x2a\x25\xad\xe2\x75\xe3\x30\x12\xe8\x71\x74\xca\xc0\x21\xa1\x0f\x1b\x53\xb4\x8e\x36\x04\x92\xa3\xbd\x9b\x37\x13\xbf\xfd\xa3\x16\x98\xab\x5d\xf0\x62\x73\xce\xa0\xb2\x9b\xd6\x4c\xa9\x51\x56\xfc\xff\xf2\x2f\x52\x24\x0e\x3f\x53\x18\xb8\xd0\xa3\xfa\x7e\xe7\x35\x2f\x91\xcb\x60\x1a\x91\x35\xfa\x6a\x21\xe7\x76\xef\xc5\x0a\xfa\xe8\xa1\x99\xab\xdc\x4e\xeb\x70\x25\x8b\x5d\x7a\x84\x0d\x12\x07\x4e\x4e\x6b\x60\x9a\x4b\x62\x60\xcb\x7e\xfc\x35\x1f\x2e\x4b\x88\x99\x0c\x45\xcf\xc8\x51\x0e\xe5\x06\x25\x64\xc7\x43\x13\x46\xd2\x4f\xc6\x5f\x68\xc2\x6e\x93\x12\x1a\x55\x16\xcc\x0f\x12\x27\x76\x5c\xd3\x36\x5b\xf3\x01\x7f\x18\x24\x61\x80\x4c\xaf\x3a\xfd\x04\xf5\x50\x1c\xbc\xa9\xaa\x04\x24\x9c\x0c\xdd\xae\xb8\x2b\xe6\x45\xde\xc4\xa5\xf6\x04\x3c\xd4\x4c\x99\x46\xff\x79\x71\x14\xbc\x46\x9a\x9d\x8b\x9b\xe0\xb1\x87\x75\x01\x52\x81\x97\xf5\x99\x67\xfd\x8e\x53\x10\x8c\x48\x70\xee\xa0\x7e\x2e\x8a\xac\xf9\x4c\xe5\xb1\xdf\x81\x0c\x22\x0a\x11\xfe\x80\xc2\xf3\x84\x07\x1e\xbd\x19\x11\xb5\x94\x40\x5b\x44\xfa\x50\x09\x66\x78\x23\x2a\x74\x31\xd6\x3f\xa4\xba\x5e\x55\x3b\x0b\x53\x01\x08\x18\x33\x89\xdf\x59\x96\x11\xa9\x9e\xd9\xc4\xdb\x25\xa6\x19\xf3\xa8\x17\xa0\xea\x85\x8b\xda\x09\x89\x84\x61\xa4\x1f\x7d\x9d\x37\xbb\xf9\x09\x27\xb1\x39\x2c\xf1\x12\xb6\xcc\x1c\xb2\x4c\x75\x78\xf7\xcb\xaa\xb6\xc8\x8b\x8e\xc8\xe2\x6f\xe1\xf5\xb5\x1f\x07\x8c\x6e\x76\x7a\xbb\xb4\xc3\x92\x10\xab\xe6\x2d\x7d\x31\xed\x20\x03\x17\x68\x54\x28\xd1\xbe\x8e\x3d\x93\x9a\x9f\xf7\xf0\xb4\xc3\x47\x0c\x42\x86\x2e\xc7\x16\x5f\xa8\x91\x3d\xaf\xb6\x17\x2b\x49\x87\x8c\xb8\x76\x1a\x9f\x9f\x72\xee\xcb\xfa\xb5\x31\x37\xe3\x71\x3c\x44\x63\xf2\x05\xbc\x0c\x1a\x43\x3f\x4c\x1d\xeb\x50\x02\x32\x00\x36\xae\x2a\x06\x8e\x2d\x5d\x24\x35\x50\x78\xf1\x24\x04\x53\x33\x88\x9d\x4e\x79\x07\xb3\xb9\x44\xf1\x39\xf0\xa1\x75\x24\x19\x72\x15\x41\x5e\x9d\x4b\x98\xf7\xda\x55\xec\x0d\xc4\x8e\x87\x0d\xdb\x19\xaf\xea\x3e\x2d\x84\x8e\x1d\x89\x4c\x30\x4d\x74\x9e\x66\x70\x00\xd5\x18\xf0\x87\x56\xf4\x50\xe9\x18\x1c\x84\xde\x0b\x40\x25\xe4\xa2\xac\xc7\x95\x5a\x9d\xf8\x09\x56\x26\x6e\x78\x7e\xc8\x78\x1f\x82\xa6\x13\x0d\xdc\xe0\xdb\x4e\xcb\x21\x45\xab\xe6\x9a\xd0\x1c\x26\x31\xd4\xe2\x6c\xfa\xaf\xc4\xf5\xcc\x4a\xd7\xca\x8b\x10\x9d\xa3\x41\xbe\xf2\x72\x51\x70\x59\xb4\x45\x4c\xad\xb8\xee\xac\xf9\xb6\x48\xb3\x1d\x1c\x4f\xcb\x4f\x09\xd8\x87\x37\x9a\x31\xf6\x37\xda\xc1\x52\xb6\x11\xa6\xe9\x67\x41\xb5\x76\x94\xa3\x5a\x7c\xa5\x1a\xbd\x6f\xed\x07\x09\xe9\x91\x65\x56\x44\x4f\x69\xcd\x12\x74\xe6\x8a\xe6\xfb\x1a\x1e\xf5\xd1\xcf\x58\x82\xde\x86\x24\x1a\xe0\xf1\xd1\x88\x93\x9a\xbc\xad\x00\xaf\x2f\xa4\x69\xc1\x71\xbc\x50\x36\xa7\xd8\x3c\x3d\x2c\xf7\x37\xb3\xf9\x8f\xe5\xa3\xc1\x0c\x81\xe3\xba\xae\xcf\x5a\x2f\x64\x58\xa2\xbd\x28\x62\x81\xe3\x7a\x0c\x1f\xe2\x9d\x5a\x2e\x86\xaa\x50\xe0\xb8\x51\x8c\x99\x44\xc9\x33\x79\xea\xcc\x61\x73\x20\x11\xc6\xad\x43\x78\x26\xc1\x7a\x38\x6a\xf9\x6d\x21\x57\x97\x2c\xcd\x83\x65\x0d\x8e\xab\x3c\x2c\x72\x50\xe9\xe8\xe2\x11\xbd\x30\x46\xc4\xf3\x47\x51\xaa\xac\x15\x40\x04\xc7\x8b\x3d\xe2\x2c\x6a\x5c\xbf\x22\x87\x55\x8e\x77\x3e\x43\x9a\xd4\x5b\x9e\x55\xed\x1d\x7a\x89\x44\xea\x17\xe3\x3e\xda\xa0\xa3\x15\x5c\x6c\x9c\x24\x52\x84\x7f\x5e\xcf\xaf\x37\x62\x82\xe3\xc7\x1c\xb7\xa0\x92\xe7\x8a\x17\x83\x35\x0d\x4e\xa0\x22\x9f\x54\x85\xbe\xee\x8a\x42\x55\xfd\xc4\x3f\x38\xa1\x4b\x3c\x24\x4d\xe8\xdb\xca\xa8\x77\x0b\x03\x9c\x30\x14\xd2\x94\x81\x9a\xb0\xba\xef\x59\x83\x13\x0a\x6a\xe4\xa8\xa0\xb1\x39\x8d\xd3\xf8\x77\x0c\x2b\x38\x4c\x46\x21\xa9\x5c\x8e\x6b\xda\x53\xb5\xb1\x31\x4e\x09\x9c\xc8\x55\x28\xcc\xd0\x61\x05\x66\x87\x69\xeb\x0c\x4e\xec\x6a\xbf\xed\x61\xde\xfb\xf6\xd6\x63\xe9\xab\xb6\xbc\x84\x6e\x5c\xab\x64\x39\xbc\x56\x0c\x02\xe1\xe5\x96\x53\xae\x04\xe8\x7d\xa1\x44\xfa\x48\x7f\xdc\x04\x41\x48\x56\x73\xe5\x2e\xb8\xe3\x39\xd0\x76\xec\x9e\xad\xca\x7a\x07\xc8\x03\x47\xb8\x31\x7a\xb1\x27\x94\xb8\xb9\xf9\x1a\x1c\x03\xc0\x17\x4d\xd9\x41\x0b\xbc\x99\xae\x27\xfe\x4d\x66\x17\x70\x24\x23\x49\xc0\xcd\xec\xf1\x6e\xb9\x7c\x5c\x74\x2f\x47\x72\x17\xc0\x6a\x32\xef\x4f\xbc\xfd\xe0\x52\x90\x45\x69\x1c\x21\xea\x92\x1c\xae\x46\x05\xa1\x95\xc0\xdd\xa5\xc3\x0a\x39\x38\x8d\x25\x95\x06\xd8\x90\x15\x4d\x18\x57\x8d\xbb\xb7\xc1\x01\xd7\xc5\xad\x0c\xb7\x9f\x75\x13\x67\xdc\xf2\x34\x3b\x97\xdd\xe7\x1d\xe5\x8f\xbe\x7d\x44\x08\x25\xb4\xa0\x86\xfc\x8c\x1d\x64\xed\xca\x00\xc1\xb0\x9b\xe2\xe1\x2c\xbf\xba\xbf\x25\x01\x35\x3d\xf5\x79\xa8\xaf\x58\x08\x68\xb6\xfe\xc6\x34\x15\x35\x3c\xe5\x8f\xf0\x81\x69\x90\x5b\x80\x6a\x5f\xe4\xd9\xd7\xfe\xe7\xea\xb9\x07\xa3\x00\x47\x7b\xa4\x7e\xbf\x58\xce\x57\xeb\xd9\xc3\xd6\x5e\x54\x0b\x02\x34\x1d\x79\x8a\xb9\xab\x2d\x72\x1f\x2d\x73\xd5\x9f\x02\x5a\x46\x28\xbf\x49\x73\xbe\x6b\x3e\xfc\x9e\x84\x15\x5c\xc7\x03\x30\xac\x9f\x77\xbc\xea\x50\xa7\xb1\x3d\x1e\xbb\x58\xc6\xfb\x4f\xf5\x8a\xcd\xce\xd3\x09\xea\x66\x1c\x61\x7f\x8e\xfc\x0d\x66\x39\xf2\xae\xd8\x9d\x10\xab\xd0\x26\xad\x3f\xfc\x9c\xae\xa3\x01\x13\x44\x5c\xa9\x6d\x7a\xb8\xf9\x6a\x3d\xbb\xc1\xbc\x71\x7d\xa1\xb0\x5b\x31\x2f\xac\x1d\x75\x03\xd0\x98\x00\x3d\x9e\xeb\xb4\xf9\x16\xf3\x22\xcd\xd1\x76\xf3\x23\x0c\x45\xb8\xae\xdd\x71\x28\x38\x16\xe8\x34\x61\xaf\x16\xbc\xe6\x93\x1d\x56\xe0\x32\xa9\x43\xd3\xac\x8c\x99\xe3\x21\x75\x93\x1d\x04\x31\x42\xa7\x6e\xd2\x5a\x16\x69\x3e\x4f\xeb\xaf\x2e\x1d\x02\x6e\xa4\x00\x2b\xf7\xd6\xb3\x1d\xde\x4b\xec\xd1\xdb\x2b\x89\x0b\xf4\x66\x37\x1f\xb7\x2b\x4f\x38\x56\xe0\xc6\x11\xc3\x46\xf7\x87\xe2\x40\x91\x89\x6d\x68\x23\xf1\xf0\xed\xf9\x38\xbe\x8e\x04\x8e\x10\xc7\x9e\xa4\xce\xef\x7a\x8c\x46\x67\x50\x31\x96\x5d\xc9\x8f\xba\x39\x67\x59\x75\xe4\x9d\x62\x19\xb8\x89\xa3\x30\x17\x63\xfa\x1e\xda\x66\x96\x0b\x96\xb8\xe1\x79\x93\x30\x49\x0c\xde\x78\x87\xca\xd0\x1b\x38\x51\xba\x7a\xce\xa9\xd2\x73\xca\xd2\xde\x55\x94\xef\x0a\xaa\x87\x61\x68\xbb\x83\xcf\x76\x6a\x24\x20\x30\xa6\x3e\xad\x16\x9f\xcd\x8a\xde\x8f\x66\x13\xf7\x03\x4c\x70\xee\x52\xb9\xe3\x72\x57\x50\xff\x6b\x7b\x30\x42\xdb\xb6\x9b\xf7\xf7\x39\x97\x47\x6a\x40\x43\x39\x7a\xaf\x3c\xd1\xda\xe4\xd8\x9f\xe1\x34\xfe\xba\xc2\x73\xd0\x2c\x52\xcc\x69\x48\x98\x86\x35\xf1\xd1\xdb\x10\x91\x36\x6c\xf7\xe4\xff\x5f\xd4\x8e\xc0\x15\x02\x12\x23\x05\x8e\x09\xaf\xa5\x29\xb3\x77\x23\xa4\xab\x70\x82\xa3\x2c\xf9\x1a\x90\x25\xce\x20\xfa\xa6\x62\x7b\xfb\xab\x20\x51\x96\x1f\xbf\xd9\xd4\x10\x11\xd0\x38\xee\x2f\xcd\xb7\xb4\xbc\xdc\x2d\x90\x1c\x1a\x3f\xc8\x06\x85\xf4\x80\x56\x5d\x65\xb4\x40\x94\x0c\x44\xdc\x63\x8b\x9d\x68\xb9\x05\x57\x01\x49\xae\x91\x19\xa3\x6e\x49\x73\x08\xa2\x98\x99\x8e\xb4\x09\x38\xc3\xe5\x32\xb7\x2e\xa2\x0b\x22\xc2\x8f\x53\x65\xa9\x04\xdf\xfb\x63\xc0\x6b\x67\xc7\x68\x27\x32\x05\xc9\x96\x8c\x60\x50\x86\x1c\x8d\xd7\x5c\x23\xa3\x5d\x3d\x70\x8a\xbe\x37\xb5\x5a\xb4\x8c\x4e\x36\x23\xf3\x24\xfe\x4d\xc1\xc4\x54\xfb\x13\x78\x8e\x17\x9a\x1c\x71\xb3\xc2\x26\x21\xd1\x17\x69\x6b\xf0\x1c\xc1\x98\xc5\x75\xbd\xf6\x75\x8c\xa6\x7a\x20\xcc\x6f\xdc\x28\x40\xb4\x0d\xe6\x47\x41\x91\x85\x1b\x16\x9d\xc0\x73\x85\x13\x87\x26\xfc\xc2\x45\xfd\xa4\x47\x37\xec\x99\xf4\x34\x51\x18\xf5\x94\xc4\xcc\x71\xdf\xa1\xfa\xb6\xf5\xba\x6f\xda\xce\x7d\xf0\x7c\x8f\x21\x5f\x08\x71\x37\x53\x14\x37\xba\x81\x20\x02\x2c\x49\x6e\x37\x77\xfd\xd5\xe9\x85\x9c\x27\xac\x15\xea\x2b\x2f\x7b\x27\xc0\x0b\x95\x87\xfb\x23\xf1\x25\x3e\x67\xbc\x0d\x05\x3c\xe6\x7b\x58\x78\xdc\xf0\x74\x70\xd6\xc8\xd5\x56\x8e\x7c\x79\xe4\xe9\x34\xd6\x1f\xbc\x88\x05\x58\x5a\x38\xa6\xb9\x89\xc1\xdb\x13\x24\x7e\x60\x30\x15\x0f\xe7\x5c\xbe\x7d\x75\x3c\x9f\xe0\x45\xd2\x75\xf8\xb0\x91\xc8\x0b\xff\x18\x7c\xc8\xd8\x17\xd8\xd8\x43\xd9\x89\xc6\x0e\x04\xfd\x9d\xe1\xff\x64\xb8\xbd\x58\xf8\xc8\xb6\xbe\xbd\xfb\x73\xd8\xb5\x06\x5e\xac\x9c\xd8\xf8\x00\x84\xe7\xbb\x6c\x4e\x02\x2f\xd6\x86\x55\xd5\xc4\xfc\x53\xd0\x23\xf0\x12\x1f\xc2\xd8\x26\x2e\x52\xc8\xeb\x67\x9e\xaa\x97\xd3\x15\x45\x60\xf0\x92\x88\xdb\x57\xb4\x3d\xf2\xb2\xed\x52\xa9\x1e\x90\x74\xde\xde\x61\x12\xd3\x72\x6b\x5e\x56\x13\xe5\xa6\xef\x70\x57\x16\x1f\xf5\x40\x84\x16\x3c\x1e\xba\x98\x27\xfa\x95\xd6\x24\x81\x8f\x52\x12\xf7\x45\xf6\xdb\x70\xce\xe3\x8c\xc4\x33\xe1\x9d\x67\x67\x4c\x8b\xed\xab\x9a\x1f\x60\x2f\x90\xcb\xb5\x6a\x69\x1e\xc0\xe3\x5c\xe1\x3d\x3f\xae\xd6\xb7\xb3\x49\x1d\xfd\xdf\xb1\x70\x99\x13\x09\x5f\x23\x4a\xc3\x64\x9f\x80\x5f\xf8\xbb\x9e\x08\x49\xad\x64\x85\x39\x11\x62\x2a\x9c\x9e\x86\x82\x4b\xc7\x14\xa0\x26\x94\x13\x46\x63\x41\xb6\x2a\x55\x69\x0e\x25\xa1\xf7\x86\x37\x27\x25\x60\x0b\x61\x2a\x0b\x8c\x5c\x42\xfb\xf8\x8a\x11\xeb\xd3\x02\x50\xde\xca\xce\xf9\xdf\x34\x16\x98\x1f\x43\xe0\x06\x66\xb1\xec\x8a\x63\x31\xe8\x11\xb5\x43\x14\xc3\x72\xd4\xf3\xec\x61\x68\xf1\x86\xcf\xa0\x81\x1c\x91\xff\xef\xaf\x07\xfb\x4b\xad\x23\xd9\xa7\x64\x7c\xa6\xa0\xf4\x1b\x9a\x48\xf0\xdd\x84\x38\xd9\x2a\xa8\xa7\x38\xe0\xc1\xf7\x7c\x8d\x7d\x31\xe4\x60\x5d\xec\x9c\xfd\xd9\xef\x7b\xa1\xe3\x39\x36\x3f\x3a\xee\xf4\x04\xdf\x77\x23\x54\xa0\xfe\x2f\xb5\x3b\xcc\x32\xa3\x46\x61\xb7\x38\xdf\x0f\x82\xd0\x94\x0e\x88\xfd\xec\x07\x7c\xb5\xc7\x18\x20\x66\x1f\x9b\xd7\x53\x58\xe9\x75\x9a\x6f\xb0\xab\xdf\x69\x87\xc4\x4a\x87\x03\x9e\xf3\x6b\xa8\x00\xf0\x7d\xa9\x70\xc3\x23\x5d\x0b\x59\x13\xe5\x77\xe7\x07\xf8\x81\x13\xa2\x59\x4b\xad\xd4\x59\xf7\xdb\xc0\x89\x91\x5e\x95\xf2\x79\x23\xa0\x0e\xf8\xa1\x8a\x78\x6c\x2c\x05\xcf\x4d\x0a\xc7\xa4\xf3\xec\xad\xb2\x18\x1c\x62\x68\xb5\x10\x9a\x14\xaa\x5e\x8b\xec\xd5\xdd\xdc\x67\x3c\xc2\x15\x41\xb5\xb7\xe1\x8d\x45\xae\x87\x88\xda\x9b\xc6\x3d\xc0\xae\x9c\x1c\xac\x8e\x1c\xf8\x11\xe3\xd8\xf4\xfd\x61\xbd\x07\xdc\x72\xc7\xa5\x53\xf0\xa3\xc4\x43\x18\xd0\x6c\xb5\x59\x6c\x9e\x9e\xf7\xf3\x87\xd9\x6a\xbd\x9f\xad\xd7\x4f\x2f\x8f\xbb\xf6\x64\x9a\x23\x16\x45\x15\x39\x3c\x9d\x7a\x49\x6c\xf0\x13\xe9\xe1\x02\x21\x62\xab\x6f\xfc\x77\x3f\xd1\xc4\xf5\x9c\x56\x77\x90\xc3\xf6\x2b\xaf\x5f\xa1\x4a\xdb\x13\x71\x87\x47\x12\x53\x61\x55\x5d\x1a\xb2\x82\x53\x06\xab\x1a\x8e\x63\x78\x14\xf8\x3c\x50\x08\x61\x7d\xe5\xb9\xca\x60\xb3\x5d\xcf\x69\xc6\xee\x3e\x2f\x1a\x19\xaf\x2c\xd1\xe9\x25\xdb\x9c\x18\x48\xab\x6e\x97\x42\xe9\x8d\x5e\x16\x0f\x89\x90\x91\x52\x0f\xdf\x67\x6b\xbe\xfb\xab\x3d\x5d\xe4\xa2\x13\xa0\xa7\xa0\xec\x76\x8c\xd4\x4c\x98\x04\x64\x63\xdc\x08\x7f\xd0\x1e\xd5\xda\x37\x3c\xf0\xdb\x13\xe2\x62\x26\xdc\x01\x5f\xf8\x2e\x4e\xe1\x3d\x42\xaf\xb6\x50\x7f\x33\xe3\x44\xc2\x04\xb5\xb5\x18\xd1\xab\x81\xe8\x04\xf8\x02\x88\xdd\x95\xa0\x10\x32\xad\xd2\x22\x5f\xa4\x25\x98\x1c\xb0\x89\xa4\x7d\xe9\x11\x30\xf0\x94\xf1\xaf\xc6\x93\x6e\x61\x7f\xe0\xcb\x04\xc8\x85\xa0\xe6\x7b\xac\xbc\xd8\x43\xdc\xc1\x7e\x6c\x12\xff\xda\xaf\x67\x9b\x1f\xcb\xdd\xea\xf1\xae\x3d\x2e\x84\x2f\xac\xc8\x72\x17\x9f\x4f\xef\x38\xbe\x04\x85\x3b\x0e\x25\x91\x9a\x17\xb7\x7b\xda\x63\x6f\x41\xd7\x57\x0f\xbe\x12\xb1\x17\x0f\xb1\xa0\x45\xd9\xd6\x2f\x87\xe6\x11\x14\x75\x3a\xe6\x75\xb5\xb0\xd2\xe8\xfd\x04\xa3\xaf\x39\x65\x2f\xd2\xea\xe1\x44\x02\x11\x74\x20\x70\x02\x67\x40\x43\x03\xfc\x68\x34\x10\x75\x0d\x25\x5b\x17\x79\xfd\x5a\x75\x83\x25\x5e\x66\x5f\x41\xbd\xa0\xf6\xe6\xc9\x58\x3d\x70\x42\xd2\x9b\x68\xe2\x60\x8f\x93\x4a\xfb\x74\x3f\x15\x04\x4e\x92\xa0\xbb\xd0\x02\x1f\x0c\xa1\xdb\xc5\x54\xe8\x3b\x42\x81\x1b\xc4\x08\x80\x6d\xa9\xbc\xa7\x43\x84\xc0\x0d\x83\x81\xdc\xe9\x4b\x9e\xfe\xe7\x0c\xa3\x2c\x3c\x04\x2e\x73\x19\x02\xbe\xdf\x2a\xc4\x68\xd8\x3f\x47\x4c\x9a\xea\x67\x5a\x36\x73\xae\xdd\x20\x03\xcf\x65\xd2\x6d\x09\x33\x3b\x4e\x17\x92\x18\x19\xde\x84\x27\x1c\xb4\x0a\x58\xcd\x99\x80\xbe\x43\xe0\xe9\x18\xe1\x6b\xf3\xc5\xfc\x8f\xee\x4f\x8c\x94\xb5\x5f\x30\x19\xfc\x47\xff\xf1\x7d\x27\xf6\xcc\x63\xc9\xb7\x3e\xca\x69\xf4\x72\x7d\x41\xd2\xc2\x9c\xfa\x65\x17\x40\x1e\xff\xf4\x76\x14\x34\xb3\x01\x2b\xdc\x05\x2d\x79\x7b\x2b\x41\xac\x03\x31\xc0\xa6\x1c\x26\xd4\xc8\x9b\x73\xb1\xc0\xfc\x24\x74\x62\x04\x2b\x98\xc6\x3f\x4c\x9b\xaf\x67\x7f\x36\xff\x6d\x3d\xde\x80\x85\x01\xe6\xd6\x4f\x94\x6f\xa2\xd8\x6b\xa2\x48\x0d\x01\x63\x3e\x69\x8e\x41\x75\x3e\xc2\x33\xad\xdd\xf6\x34\x52\xe0\x5e\x34\x53\x6a\xfe\x9a\x9e\x76\x70\x3c\xe1\x3a\x3a\x5f\xe2\x29\x21\x60\xa0\xd0\x9b\x47\x9b\xb0\x2b\xb6\x78\xb5\xbe\x85\x08\x22\x57\x05\xa6\xf3\x97\xbe\xaa\xbd\x4e\x14\x2b\x2c\xe8\x9b\xdb\xed\xd3\xa8\x4f\xcf\xbd\xd8\x8f\xd0\x59\x38\xa5\xf2\xed\xe5\x64\x4f\x13\x6b\xd6\x73\x65\x48\x32\xcb\x1c\x4a\x14\x51\x46\x1a\x1d\xe7\x73\x35\xb8\x31\xee\xb3\x30\x6a\x59\x84\xfa\x41\x52\xc0\x05\x31\x2d\xd7\x20\x5f\xf3\x54\xf2\x6c\x94\x1e\x08\x84\xaf\xc2\x64\x08\x66\x9f\x82\xb1\x43\x20\x94\x8b\xde\x91\x69\xb0\x26\xf2\xfe\x75\x9a\xd7\x69\x7e\xb0\x50\x6b\x33\x54\x06\x1c\xfb\x11\xb2\x73\xfe\x55\x9a\xb3\x35\x01\x7b\x8b\x12\x82\x40\x32\xe2\x2c\x3a\x15\x17\xbd\xe4\x66\x84\xf2\x38\x7e\xbc\xc5\xba\x9d\xf8\xca\x27\xe9\xed\x1e\x24\xe7\x5b\x7b\x1a\xa8\x30\x41\x87\x63\xde\xeb\x42\x19\xad\x2f\x15\x4b\x94\x03\x81\x4f\x28\x65\x5a\xc1\xe0\xed\x01\xe7\x6e\xd8\xed\xf0\x83\x63\x3a\xf0\x71\xdb\xe1\x59\x36\x8e\xb3\x03\xad\x1c\x69\x70\x83\x1b\xd2\x8f\x1d\xb9\x42\xa1\xe3\x85\xc8\x8d\x82\x7d\x8e\x13\x12\xe2\x57\xf6\x7e\xfb\xeb\x40\x20\x1a\x66\xd4\x00\xf5\x3d\x17\x1b\x84\x0e\xf8\x98\xce\xad\xd2\x23\x12\x1a\x3c\xf5\xf8\x43\xc7\x95\xee\x89\x7f\xe2\x7e\x65\x13\x42\xd7\xf5\xa9\x6d\x1a\x7d\x44\xfb\xf1\x43\x37\xe1\xe8\x22\xfc\xbb\x48\xf3\x3b\x7e\x04\xf3\x02\xa6\x35\x50\xe3\xf6\x47\x4a\x75\x0a\xa8\x0f\x45\x5d\x17\xcf\xbc\xe4\xc7\xdf\x3d\x91\x2b\x95\x66\x17\x6d\x11\xbd\xae\xb7\xfe\xd6\x10\x7a\x8a\x21\x79\x9d\xfd\x86\xa1\xef\x09\xee\xd9\x66\x37\xf9\x76\x40\xf3\xb6\x3a\xf2\x6b\xe5\xa8\xd0\xf7\x99\xef\x98\x76\x3e\x94\x7f\x9e\xee\xcd\x34\xa3\x03\x97\x90\x4d\xb3\x2c\xa3\x4c\xcf\xc0\x31\x09\xc3\x98\x63\xb6\x65\xb9\xeb\xcb\xca\x40\xc8\x34\xf9\xfe\x06\xeb\x84\x81\x1c\x16\x28\x7a\x5d\x5c\x10\x46\x81\x8b\x50\xee\xc7\xe5\x4b\xab\x23\x05\x61\x0c\x2c\xe4\x3d\x25\x7b\x53\xf7\xea\x41\x4d\x20\x4c\x22\x72\xb4\xe7\xaf\x30\x30\x16\x61\x92\x38\x61\xd0\xd5\xaa\x97\xbb\xfb\x2b\xaf\x81\x33\xed\x46\x9d\x6f\x30\x33\xfb\xf8\xf0\xf1\x78\x94\x0c\xe9\xdc\xbe\xeb\x11\x84\x90\x8b\x04\x93\x47\x37\x0f\x4f\xf3\x1f\xdb\xfd\xf3\x72\xb3\x47\x22\xee\xf6\x74\x32\x11\xee\x88\xdf\xf9\x4a\x3c\x6f\x7e\x21\x1c\x8f\x1b\x0c\xec\xbc\x94\x96\xba\x62\x72\x9b\x0d\x85\xe7\x22\x71\xe3\x91\x7f\xde\x40\x3b\x97\x45\x20\xb1\x9e\x84\x8c\x0a\xbb\xbe\xa6\x13\x84\x82\x39\x48\xd0\x91\x15\xf2\x6d\xa0\xb5\x36\x7a\x2e\x19\x90\x90\xfc\x66\xb3\xd9\xec\x07\xaf\x5b\x4a\x17\x37\x55\x7a\x22\xa3\x09\x89\x14\xa1\x8b\xe2\xa2\x6d\xfc\x6a\x54\x30\xbc\x9a\x72\x9d\xc0\xeb\xc0\x74\x86\x41\xe1\x22\x9f\xfc\x4d\xef\x20\x84\x2a\x26\xbf\x0b\xcb\x7c\xc7\xe2\xcf\xaf\xff\xda\x3b\x56\x9a\x9a\xdc\xaa\xf4\x90\xbf\x9c\x16\x90\xc1\x81\xd7\xa0\xb0\x87\x66\xe2\xe3\x4e\x13\x15\x40\x08\x8e\x83\x10\xcb\xfd\xed\xea\x76\xf7\x97\x3d\x39\x48\x07\x29\x8f\xf6\x3d\x06\xf7\x0d\x62\x89\x47\x3e\x59\xa8\x21\x22\x1a\x27\xdb\xe3\x36\x98\x78\xcc\x49\x24\x96\xa3\x0c\x08\x17\xbd\xda\x6a\x66\x3f\x2a\x73\x7d\x37\x51\x43\x6a\xb4\xae\xd1\xda\x8e\x89\x42\xd7\xbb\xb0\x2b\x8f\x17\xfe\x35\xf3\xdc\x04\xdd\x33\x64\xef\x69\xa6\xd8\x2d\x8c\x62\x19\xe6\x05\x21\xa6\x3d\xd2\xbc\x6e\x5c\xf4\x6c\x18\x2e\x31\x0f\xb4\x30\x01\xd1\xd3\xc9\x74\x7c\x0c\x40\x7a\x83\x89\xca\x7c\x27\x20\xbc\xd9\x97\x68\x91\x92\xf6\x50\x44\xba\xf1\xcf\x65\xba\x92\xc5\xb7\xc5\xa3\x2b\xe7\x4e\x34\x5a\xe1\x3b\x5b\x2a\xe8\x25\x44\x99\x2f\x35\x7e\xb4\xdd\x47\xc1\x73\x55\x7f\x74\x07\x94\x8c\x4d\x56\x65\xaf\xa0\xa5\xa5\xde\x9f\x4b\x6b\xab\x58\x20\x88\x14\xf8\x03\xd2\x5f\x3c\xaf\x41\x3d\x0d\xc5\x51\x81\x05\x12\xa4\xdb\xab\xe1\xd9\x5f\x86\x1e\x51\x89\x3f\xa4\x55\xfd\x58\xd4\x86\xb9\xd3\x02\x2c\x81\x31\x27\xc0\xcc\x23\xaa\x40\xe3\x34\xf8\xe9\xb7\xc7\x00\x5c\x31\x60\xd6\x6d\xec\x86\x71\xec\xcc\x98\x04\x98\x95\x25\xfb\xe7\x99\xe7\x75\x3a\x12\xdf\x6a\x46\xc4\x48\x83\x31\xe7\x65\x91\xf5\xd7\x2f\xe3\x3c\xf6\x9d\x5e\x29\x26\x6d\xbf\x6d\x33\x11\x1e\xe1\x63\x0d\x35\xef\x15\x19\x99\xf0\x18\xc6\x12\x15\xd1\xeb\x19\x8d\xc6\x75\x6f\x40\xe2\x61\xd7\x2e\xf6\x8e\x75\xc4\x9f\x63\xdd\x30\x60\x42\x28\xec\x16\xda\x9b\x7a\x32\x3d\xe1\x2c\xaf\x3e\xc6\x1c\x73\x43\x3c\x12\x30\x29\x85\xdd\x31\x8d\x06\x92\x98\xaa\x6d\x30\xe5\xc6\x20\x6d\xa3\x5d\x81\x3c\xde\xe3\x11\x21\x73\x85\xd9\x0b\x5f\xf2\xaa\xc8\x0c\x1e\x77\x57\xd8\xde\x98\xd1\x4d\x83\x9b\x20\x8a\xa2\x99\x5b\xd3\x4e\x1f\x6b\x5c\x1b\xea\xe0\x3c\x57\x35\xc0\x90\x3b\x09\x18\x44\x09\x26\x46\x91\xc2\x8f\xf2\xc6\xd5\xd8\xf9\x62\xda\x23\x84\x52\x4b\x21\x31\x6d\x98\x99\xf6\x01\xaf\x65\xb5\x2a\x36\xb3\x9d\xdd\x6c\x98\x0e\x42\xd6\xc9\xe0\x63\x71\xf4\x5b\x60\xae\xf1\x63\x22\x47\x28\xdc\xc4\x8e\x69\xde\xac\x66\x62\xea\xec\x61\xbe\x20\x72\x3d\x29\x5d\x6b\x59\x8e\x69\x3e\x2f\x2c\x25\x9a\x1d\x00\x0c\x1d\xd2\xd5\xe2\x4f\xfb\x27\xcf\x09\x11\x87\x7f\x07\xf5\x43\xca\xab\x22\x7f\xd9\x3c\x7c\xef\x18\x45\x9e\x47\xdc\x5d\x6d\x5d\xb7\x4b\x3a\x4f\x27\x6c\x23\x2f\x88\xd1\x9f\xb5\x52\x8e\xdb\xe5\xc3\xc3\xea\xf1\x6e\xff\x32\xef\x5a\xc4\x21\xf2\x12\xc5\x75\x2b\xe8\xba\xa9\x7e\xf1\x43\x87\x77\x86\xc8\x57\x02\x85\x03\x6e\x21\x87\xb2\xe8\xaf\x96\x88\x71\x82\x43\x5a\xcc\xf8\xda\x2a\x63\x7d\x97\xff\x8d\x22\x57\xa0\xa7\xb1\x3d\x4d\x25\xb1\xfb\xb9\xa9\x28\x12\x3e\x32\xb9\xf0\x3c\x3f\xf3\x6c\x2f\xd3\x12\x69\xbb\xd2\xfc\xb0\xef\xeb\xca\x40\x14\xc7\x41\x60\x62\x46\xe4\x7e\xfb\xce\x2d\x89\xe2\x58\xe3\x03\xdf\x3f\x3d\x3c\x2d\x96\xf3\x1f\xdb\xf6\x2c\x3a\xe1\x06\x1e\x3d\xe7\xa5\x1a\xb0\x8e\x9b\x21\x49\x60\x64\xa2\xee\x2c\x7c\x2e\x4a\x12\x4e\x74\x97\x1c\xdb\xd1\x86\x09\xa1\x66\xcd\xb6\x19\xde\x28\x51\x11\x02\xd5\xb9\x52\xcf\x45\x96\xca\xaf\xcd\x39\x33\xdb\x4f\x70\x21\xf9\x33\x3d\x0b\xb8\xc7\x88\xee\x11\xb2\x34\x87\xda\x9a\xec\x88\x27\x44\x6e\xb3\xff\x48\xf3\x7f\xa0\xd4\xf5\x98\x7f\xdd\x0c\x14\x52\x12\x51\xe1\xf9\x7b\xe6\x60\x88\x24\x08\xcc\x00\xed\xee\x57\x9b\xc5\x7e\xb7\x5a\x6e\xfa\x0b\x2a\x52\xcc\xc3\x4e\xd4\xef\xc4\x50\xec\x50\x11\x04\x66\xfb\x3e\xf5\xa9\x9e\xda\x4b\x29\xc9\xf0\x93\x54\xa5\xb4\xa7\x07\xdf\x47\x15\x23\xa2\xd9\xc8\xd5\x25\x6b\x4c\x2f\x0e\x88\x20\xe1\x9a\xba\x40\x3b\x19\x17\xb8\xe2\xf2\x47\x90\x90\x4a\xf1\xba\x50\x08\x0f\xbe\x49\xb3\x1e\xf7\x7e\xf7\xb9\x74\xe8\x62\x33\xda\xfe\x54\x16\x12\xaa\x8a\xd8\x3c\xaf\x9c\x54\x27\xae\x67\xf4\x6a\xb6\x96\xb9\x78\x58\x26\x8e\x34\x77\xd0\x2f\xd8\xc0\xd7\x23\xb2\x61\x99\x67\x8d\x1d\x1e\x87\xca\x94\x79\xf7\xff\x6e\x79\x31\x20\x76\xa4\x44\x5c\x9e\xb4\x1c\x7c\xdd\xce\x12\x3b\x8a\xa0\xe1\xff\x7c\x79\xda\xbc\xac\xdb\xbf\x42\x14\x99\xde\xc8\xf4\x78\x3e\xfe\x82\x94\xaa\xeb\xf6\xb8\x1b\x25\x08\x51\xc0\xbe\x70\x95\x0d\xed\x79\xec\x4a\xa5\x4c\x89\x74\x55\xc3\xd1\x46\x93\xdf\xd5\x3d\x8d\x9d\x8c\x3d\xce\xb1\xab\xb9\xf1\x30\xbf\x65\xb2\x80\xd8\x77\x25\x42\xfd\xc8\x14\xef\x05\xe1\x77\xf6\x68\x5a\xff\x18\x0d\x0d\xc2\xa8\xd5\xa8\xaf\x6e\x8b\xf2\x02\x74\x11\xfb\x9a\x23\x7e\x04\x65\xcf\x54\xca\x73\xc3\x5f\x7d\xd1\x0f\x08\x71\xc0\x89\xba\xc5\xf0\xa4\xa0\x63\x7e\xad\x50\x1a\x07\x82\xd4\x56\x7f\x2e\xb7\xbb\xc6\x6a\x7a\xfb\x59\xbf\x1e\x11\x07\x10\x63\x46\x60\x55\x57\x73\xec\x53\xba\x2f\x8e\x83\x5c\x43\x1c\xba\x6e\xdb\xd9\x0e\x07\xb7\xfd\xb3\x52\xa1\xa9\xc0\xde\x3d\x6f\xd7\xfc\xb3\x95\x40\x85\x98\x39\x5a\x7a\x56\x7c\x3b\xad\xe0\xb2\xb3\x0a\x62\x16\x49\x34\x38\x96\x67\x0b\x15\x99\x2c\xa9\x47\x7b\x22\x29\xdc\x4e\x5f\xe6\x0e\xea\x59\x55\xc1\x74\x7b\x12\xc4\x51\x48\xd9\x9d\x4d\xbe\x26\x68\xd1\x06\xfe\x63\x4f\x14\x89\x80\xb9\x7d\xb0\xc9\x6d\x59\xe4\xa8\x8d\x7d\x5b\x94\xeb\xae\xb6\x3f\xa0\x0b\xb7\xbf\x05\x85\xc8\x16\xbb\x01\x3d\xcf\x36\xbb\xd5\x7c\xf5\x6c\x98\x5c\x07\xaf\x33\xd2\x01\x96\x05\xf7\xcd\x26\xbf\x29\x32\xa0\xde\x99\x89\xd4\x42\x1c\xbb\x89\x6b\x4a\xde\x3f\x79\x99\xf2\xdc\x60\xb0\xa7\x1f\x2e\x09\x3c\xc7\x28\x65\x3d\xa4\x93\xac\xef\x10\x27\x31\x35\x05\x59\x4c\xf3\x0e\x8e\xa7\xa2\xe4\xd9\x4b\x7e\xf1\xf6\xb9\x1f\x70\x93\x32\xdc\x15\x93\x5d\x95\x10\x73\xe9\x63\x95\x09\x0b\xec\x2b\x05\xe8\x84\x5a\x59\xac\x3f\xda\x41\x21\xee\x83\xb4\x59\x52\xfb\xd3\xf7\xc9\xaf\x58\x3a\x1c\x67\x07\xf5\xa5\x35\x3e\xaf\x19\x36\x3d\x3a\x24\xbe\xf8\xc6\x25\x3d\x3e\x97\xc5\x71\xb0\x7b\xc7\x52\xe8\x48\x21\xe7\x0e\xd4\x50\x1e\xd3\x1c\x0c\x27\xcf\xf0\x2c\xc0\x98\x20\xf6\x87\x0f\x9b\x13\x1c\xbe\x3b\x48\x04\x0e\xf8\x09\xf9\xb9\x42\xe5\x11\x73\x85\xc4\x61\x2e\x7a\xfa\xfc\xac\xd2\x1a\xdb\x4f\x1a\x5f\xfc\x7c\x09\xa7\xb9\xb8\xf7\xc4\x61\x0c\x51\xa7\x3d\x6d\x57\xd6\x9e\x96\x73\xc4\x90\xca\x73\x6b\x28\x13\xd7\x77\x71\x4a\xd4\x9f\x3b\x5e\xbd\xad\x47\x64\x50\x90\xb8\xb1\xeb\xd9\x6c\xeb\x91\x67\xd9\x9c\x9f\x5a\x48\x53\x9f\x45\xfb\x1a\xda\x32\xf1\xb8\x50\x7d\x38\x9a\x85\x5c\xb5\x0f\xeb\x7b\x89\xa1\x56\xc5\xca\xce\x72\x24\x85\x01\x89\x1f\x50\xeb\x25\x0a\xee\x51\x47\xca\x7d\x2b\x2f\x00\x89\x9f\x78\x42\xb4\x70\x99\xe5\xe1\xd0\x9e\x39\x08\x7d\x69\x48\x82\x6a\x78\xd2\x5d\xe5\x2d\x09\xb8\xc6\x6e\xb0\xe5\xe2\xb1\xfd\x93\x74\x70\xdb\x6c\x53\x34\x13\x4c\xfb\x90\x84\x0e\x89\x01\x1d\xf9\xe7\xee\xb5\x84\xea\xb5\x65\xa4\x83\x84\xf9\x1c\xd7\x42\x9d\x1e\x01\x85\xc9\x5a\x84\xc8\xe8\x24\x51\xd4\xb6\x17\xe1\x27\xb2\x27\x88\x64\x88\x2b\x19\xea\xd7\x5d\xf1\x50\xbc\xc3\xd7\xa6\x83\xcd\x26\x91\x76\x85\xf9\x12\x56\xa8\x72\xf7\x39\xab\x86\xde\xe0\xc0\x11\x49\xe2\x20\x42\xfd\xb5\x13\x2f\xeb\x1c\xca\x8e\xde\xd0\x1e\x67\xc4\x86\x96\x56\xd5\x19\xca\xc7\x0e\x5b\x98\xc4\x4c\xa0\xa9\xb5\xf9\x58\xa3\x99\x7a\x0b\x8d\xf3\xac\xd3\xf2\x78\x45\x04\x3e\xb6\xbf\xe7\x81\x61\x7f\x04\x4c\x38\xcf\x72\xd5\x63\xae\x9e\xf4\xba\x93\xc4\x4f\x92\xa0\xed\xa2\x7b\xc9\x75\x51\xbe\x8d\x51\x26\x49\x12\x6a\x65\xbc\x05\x6c\x69\x4c\xff\x0b\x33\xcb\xf1\x39\x9a\x37\x89\xa2\x92\x35\xc5\xa3\x35\x96\xed\xda\xb9\xc1\x1d\x82\x4c\xa7\x15\xc6\xd1\xab\xe7\xdb\x2d\x16\xad\x5f\x9b\x99\xd5\x73\x90\x12\xee\x13\x73\xf7\xfa\x69\xd3\xcd\x1f\x11\x04\xae\xc5\x02\x9d\xf8\x47\xde\xed\x36\x9d\x44\xc2\xf0\x66\x44\xe8\x60\x22\xa9\xf1\x60\x61\xdc\x82\x91\x08\x21\x10\x70\x68\x6b\x47\x58\x36\xac\x5e\xd3\x93\x29\x8c\x5f\xe2\x91\x13\x01\x09\x26\x28\xaa\xf4\x90\xb7\xb1\xe1\xa4\x17\x99\x48\xd7\x0f\x0d\x02\xf5\xf3\xcb\x24\x34\xed\x93\xc8\x10\x22\x02\x07\x6c\x1b\x1b\xb6\xfc\xac\x21\xaf\xc6\xcd\xea\x90\xc8\xc4\xe5\x71\x0b\x17\x29\x6b\x93\x91\x1e\x4e\x37\xd0\x02\xd1\xaa\xc4\xf9\xbd\x2b\x7e\x01\xbc\x4d\xef\x2d\x89\x8e\x99\xec\xa8\x0a\x9d\x3f\x26\x5c\x53\xee\x28\xca\xb2\xd8\x97\x72\x5b\x16\xc7\x6f\xeb\x69\xdc\xd5\x09\xb7\x74\xd8\xa7\xb4\x2a\x14\x0c\xb0\x59\xdc\xf3\x05\x22\x00\x6a\xa8\xda\x4a\x43\x73\xd6\x45\x01\xd5\x63\x51\xcf\x4c\x6a\x13\xff\xde\xaa\x8c\xec\x5e\x79\x7d\xcf\x9b\xe3\x37\x00\xb9\xe5\xd4\xb5\xa7\x6c\x66\x87\x6f\x79\x63\x0d\xd7\x7f\xfa\xdf\x6b\x08\x54\xee\x73\x85\x8e\x94\xc6\x92\xd1\x73\x09\x2b\x2b\xd3\x02\xdc\xd7\x94\x24\x3e\x40\x46\xfd\x6a\xbd\x66\xe2\xce\xb9\xe6\x41\x98\xe0\x5c\xa1\xc4\xc8\x6b\x59\xe4\xd0\x9f\xb0\x9c\x39\x80\xb9\x43\x5d\x9c\xcb\xfa\xb5\xf9\x06\x94\x92\xb5\x87\x63\x85\x65\xca\x07\xfe\xdf\xaf\x79\xa1\x88\x19\xaa\x3d\xa8\x18\xba\xb1\x5c\x60\x2a\x66\xb0\x49\x9a\x21\x11\x38\x28\x4a\xb6\x83\xaa\x0e\x87\xb3\x84\xf3\x48\xa0\xc2\xc6\x73\x51\x64\x5b\x38\x94\x70\xa0\xa0\x7f\x0c\xa8\xb6\xc3\x15\x95\xd5\xf7\xd4\x67\x89\x94\x24\x25\xe4\xc3\x59\xc5\xa5\xcf\x71\xbb\x55\xe9\xfb\x9c\x57\xaf\xfd\xdb\x95\xa1\x89\x20\xa1\x1e\x6c\xa0\x5c\x86\xa4\x58\x41\x7c\x96\x43\x3c\x80\xe7\xd8\x41\x9a\xf0\x00\x24\x9a\x35\x0d\x97\xe6\xca\x8b\xb1\xbd\xfb\xe6\x66\x37\xb1\x0a\xb9\x52\x1c\xed\x24\xc9\xde\xef\xeb\x62\x8f\x06\x64\x78\x0e\x70\x1c\xeb\x76\xad\xf9\x27\x3e\xe6\xc0\xef\x6a\x87\x29\x84\x59\x6e\x69\x23\xbc\x82\xe7\xe5\x3a\xa2\xbd\x4b\x18\x4a\xcd\xe7\xa2\xaa\x9b\x59\x34\xe9\x8c\x73\x1d\x13\x9f\x8c\x2c\x72\x99\x9d\x15\xec\x8a\x33\xbe\x8b\x6b\x5e\x1f\xd7\x22\xd1\xbc\x2d\xd9\x53\xd6\x68\xa0\x30\x37\x34\x2e\x5c\x4b\x8f\x93\xca\x55\x55\xf3\x2c\x1b\x12\x83\xd2\x18\xe1\xb8\x2e\xe5\xf2\x28\x37\x87\xb4\xe7\x43\xec\x85\x70\x44\x10\x9a\xcb\xde\x65\x85\xe0\x59\xb5\xed\xc9\xd8\x98\x41\x6e\x40\xbd\xa6\x69\x75\x5f\x94\x15\xac\xf2\x6d\x7d\x56\xe3\x31\x00\x58\xe5\x9d\xf3\x5c\x7d\x3d\xf0\x31\xb6\x5b\x78\x61\x88\xc9\x3c\x95\xbe\x9f\x78\x6a\xd7\xb1\xf0\xa4\x87\x1b\x7b\xc5\x35\x60\x35\x6b\xf7\x3b\xab\x73\xc1\xcf\xde\xad\x41\xe1\x47\x01\x63\x2d\xff\x47\xeb\x30\x81\xfa\x4e\xee\x08\x84\xcf\x23\xcb\x1a\x74\x03\xf5\x0f\xf8\x1a\x3d\x5b\x10\x00\x5a\x88\xd5\xfc\x09\xd1\x82\x5f\x27\xbb\x61\x8b\x80\x47\xc8\xf1\x7e\x84\xf2\x2d\x83\x4d\xd1\xb6\x9f\x88\xd0\x0d\xd0\x5d\x4e\xab\x66\x9b\xa0\xbe\x9c\x89\xe8\x48\x84\x2e\xb3\xa0\xf7\xbb\xc7\xcd\xf7\x89\x09\x11\x32\xae\x82\x8e\x39\xc0\xe6\x67\xef\x7a\xba\x56\x83\x5c\xab\x08\x25\xc3\x16\x79\x34\xbd\xaf\x65\xf1\x51\xd1\xd6\xf6\xc0\x89\x51\xfd\x1d\xb1\x48\xcb\x66\xd3\x97\x60\xff\x67\x3b\x3b\x98\xab\xdc\xd0\x66\x0a\xb1\xc0\x66\x4a\xff\xc3\xbb\x62\x91\xc6\xcc\x4a\x5a\x91\x4c\xb1\xf9\x73\xe4\xfb\x98\x8e\xb0\x55\x87\xa1\x4a\xcc\x70\xfe\x8b\x24\xf4\x98\x49\x30\xde\x14\x69\x06\x65\xd5\xcb\xfc\x8b\xc6\xfd\xc0\xb2\x60\x71\x9f\xfe\xbb\xe7\xf3\x7f\x8f\x68\x16\x09\x4b\x62\xb3\x7d\xae\xa1\x1e\x56\x3d\x44\x12\x93\xf6\xe6\x6b\x51\x9d\xf6\x3d\x71\x78\x10\x09\x0f\xd1\x70\xcc\x5b\x56\x2e\xdb\x9b\x74\xe5\x32\x3a\xc6\x0e\xc1\xc6\x15\x9e\x55\xb7\xc5\x19\x9b\x43\xcd\x41\xee\x4a\xcc\x25\x19\xe1\xe3\xb1\x02\x19\x08\x9e\x48\x84\xa9\x66\xe9\x7f\xce\xa9\x6d\x47\xbc\xf2\x96\xb8\x00\xee\x74\xcd\x94\x18\x72\xdb\x0b\x09\xee\x21\x1e\xe8\x9c\xa7\x75\xf5\x0c\xe5\xb2\x7e\x9d\x8d\x27\x9b\xe0\x12\x93\xca\xa9\x2c\x82\x56\xdb\x0f\x84\x90\xa1\x95\xf4\x98\x65\xd9\xa6\x38\x77\xdd\x3a\x42\x06\x5e\x62\x31\xee\xf5\x2b\x94\x1d\x5c\x52\xc8\x88\x21\xdd\xce\xec\xfd\x99\xea\x5c\xf6\x80\x72\xc1\xeb\x37\x72\x5c\x10\x05\x80\x50\xcc\xf7\x0c\x3e\x81\x18\x93\xaf\xac\x4d\x95\x78\x58\x4d\xdc\x3d\xed\x66\x0f\x97\x1d\xae\x02\xdc\x00\x37\xb3\xc6\xfb\x2f\xce\xb5\x91\x26\xb6\x07\x65\x82\xcc\x22\x1d\x5a\x83\xda\x9e\xda\xe3\x00\xb8\x15\xd9\x66\x83\x75\x9a\x5b\x6a\xf7\x7f\xd6\x63\x2b\xa0\xb9\x87\x1d\x37\xd8\xf0\x69\xfa\xf9\x47\x23\x80\x73\x4b\xd5\x31\xbf\x27\xc4\xbe\xef\x0f\x10\xfb\xd2\x71\x12\xdc\x6d\xec\x2d\xe1\x3b\x1d\xce\x4c\xe9\x68\xce\x7b\x2a\x4d\xbc\xaa\x4e\x45\x8b\x8a\x93\x6e\x42\x44\x52\x69\x0d\xc7\xdd\x48\x5a\xde\x0c\xf1\x5c\x40\x2f\xfb\xe9\xdc\xdb\xb6\xa5\x97\x48\xc4\xd9\x34\x66\xac\xcd\xc3\xfc\xe3\x69\xf5\xb8\xa3\xd7\xda\x8e\x93\x9e\x91\x2f\xb4\x6c\x22\xa3\xd3\x07\x0e\x97\x24\x19\xd6\x93\xff\x05\x19\x04\x09\xc6\x08\x6b\x50\xf0\xd9\xe9\x7e\xda\xa3\x91\x83\x0e\x3d\xaf\x1a\xd7\x19\x17\x09\x7a\x29\xa6\x21\x78\x78\x05\x26\x02\x5b\x22\x7a\xc9\x89\xa9\xcf\x68\xcd\xa4\x45\xde\xeb\xf5\xfa\x16\xb1\x2f\x19\x70\xac\x8e\xdd\x17\xca\xd6\x01\x65\xec\x09\xac\x6d\x18\xaa\x9c\x27\xbd\x1a\x17\xe2\x65\xcc\xa8\x28\xde\x38\x7f\xc0\xf3\x5d\xf1\xd2\x8c\xe9\x5c\x41\x99\x38\xe0\x13\x48\x41\x96\xd0\xec\xe9\xc8\xcf\x3a\x2b\xe1\x42\x4a\xd5\xfe\xc0\xf7\x3c\xd5\xa2\xa3\xb6\x2d\x9a\x72\x34\xca\x74\x0d\x18\xf6\x2a\x29\xa1\x1a\x2b\x60\x81\x4c\x64\x88\x14\x08\xeb\xaf\xdb\x74\xfe\xca\xbb\xaf\xcb\x43\x17\x89\x97\x21\xc3\x5b\xfa\x0d\x6c\x45\x0a\x47\xb1\xa0\x5f\x82\x1e\xba\x7f\x52\x78\x0e\x32\x5b\xe9\xb2\x38\xde\xc3\xe7\xfc\x95\x97\x7d\xc0\x97\x14\x09\xb1\xdb\x7e\x41\xd5\xcb\x0a\x48\xa1\x18\x26\x21\x11\xae\x80\x12\x18\x36\x48\x6a\x6f\x54\xc6\x11\xbe\xde\xc3\x99\x97\x0a\x35\xd7\xdf\x5b\x50\x96\x94\x3c\x40\x92\xed\xbd\xc1\x3b\x3d\xa6\xf9\xbf\x47\x55\x3f\xa9\x9c\x08\x89\xb2\x69\x0d\x0e\x37\x14\x16\x8c\x9e\x53\x45\x2d\xe0\x1e\xd1\x5f\xc4\xef\xd6\xa5\x0f\xa4\x82\xc0\x01\x9b\xf4\xd4\xc3\xc6\xcd\xa1\x2d\x92\xe0\x44\xd2\xe4\xa2\xb1\x65\x3c\x2d\x17\x65\x71\x6a\x3b\xef\xda\x77\xa7\x7d\x07\x33\x27\xc8\x61\xfa\x58\xd4\x8f\xe7\x6c\x94\xb8\x96\x9a\x31\x6a\xaa\x25\x21\xed\xfe\x4a\x51\x8e\x17\x2b\x63\x1a\xef\x52\x5d\x4f\xa5\x14\x95\x9b\x10\xdf\x89\x94\x24\xfd\xff\x72\x1a\x33\x1c\xdb\x81\x3c\xd2\xcc\x42\x8f\x4d\x27\xe4\xee\x61\xf8\x46\x95\x0b\xa1\x47\x39\x53\xe2\x1f\xf9\x95\xe6\x6b\x5e\x97\x29\x55\x64\xdd\x76\x98\xa6\x3d\x9a\x38\x43\xd1\x5d\xeb\x03\x17\xda\x54\x94\x19\xee\x39\x80\x7c\x32\x7f\xa5\xaf\xdc\x3e\x9b\x67\xf4\xbc\xf6\xad\xb4\xe4\xe8\x7e\xbd\xd0\x93\x08\xe7\x2c\xc8\x97\xf8\x76\x16\xab\xc0\x13\x86\x06\xbc\xc8\xb5\xe5\xf9\x04\x15\x04\xbe\x63\x10\x85\x2b\x49\x30\x2e\xa8\xa1\xfc\x7b\x92\xf5\xa0\x82\x90\xd8\x02\x4f\x5d\xa2\xad\xdf\x86\xb2\xca\x97\xf5\xeb\xe8\xb6\x03\xee\xe1\xb3\x52\x12\x85\x98\x47\xa6\xbe\x5b\x20\x18\x42\x18\x49\x7a\xfc\xf6\x9c\x2b\xec\x11\x1a\x7a\xe5\x2a\x74\x5c\xec\xcf\xdb\x16\x59\xaa\xb6\x35\x3f\x9e\x36\x56\x02\x61\x34\x50\x72\x2f\x31\x72\xb5\xa5\xba\x4d\x2d\x7f\xf1\xb7\xf5\x0c\xc5\x9c\x40\xd2\xf6\x2c\x8b\x5c\x55\x0f\x69\x0b\x76\x50\x91\x4f\x68\x36\x44\x7c\x43\xf9\xcc\xe5\xdb\x9c\x97\xaa\x0f\xfb\x52\x49\x60\x55\xf5\xb3\xb7\x71\x0a\xa4\xfd\xf8\x49\x1c\x62\x8a\xfe\x95\x57\xdb\x22\x3f\xfc\x2a\xd3\x1a\x4a\x54\xa0\x1b\x45\x06\x4a\x84\x3e\x49\x36\xc2\x29\x83\x26\x3c\xff\xae\x1a\xab\xa4\x24\xde\x5a\x69\x83\xdb\x31\x0d\x82\x92\xa0\x10\xec\x72\xe2\x48\x0d\xba\xfd\x48\x07\x20\x39\x33\x0a\xb4\xf4\x18\x85\xeb\x8d\xb7\x66\x65\x1e\x47\xef\x57\xc7\x8e\x69\x69\x43\x3d\x6f\x6c\x3e\xaf\x2e\x04\xcf\x01\x1c\xd7\x0b\x9c\x6e\xbf\xfa\x07\x57\xb0\xad\x81\x67\x69\x7e\xf8\xbb\xbb\x15\x38\x61\x64\xc8\xd5\x6c\x7d\xfa\xaa\xe2\x15\x34\x96\xc8\x69\xd5\x79\x49\x10\xee\x62\x00\xd6\xd2\x67\x9f\x29\xcc\x9b\xe5\x3a\xc5\x86\x08\xe0\xba\x09\x2e\x37\x05\xc7\xf4\x0a\x93\x39\x80\x0b\x0c\x59\x44\xea\x62\xf3\xf0\x8c\x37\x45\x0d\xb2\xdd\x96\x08\xbe\xd4\x71\xd7\xf0\x83\x93\xd0\xc0\x46\x48\x69\xbc\x71\xaa\x3a\x99\xb0\xc1\xa7\x80\xc0\x49\x9c\xd8\x92\xca\xdf\x5e\xf2\x11\x98\x61\x61\xe8\xe2\x13\xb5\xcc\xa3\x48\x39\xfa\xd7\xfe\x6e\xf3\xf4\x62\xa8\xf3\x00\x42\xe5\x21\x0f\x1a\x56\x26\xb5\xd5\x4c\x31\x2a\x01\xd6\xe6\x03\x8b\xa9\x97\xb7\x6c\xfc\x67\xa4\xe8\x5e\x40\xe3\x5c\x8c\x36\x93\x71\x9d\x04\x98\x26\x21\x3e\x5a\xe5\x65\x2f\x10\x04\xa6\xa9\x19\xae\xb1\xf9\x18\xb7\x53\xf1\x69\x57\xec\x80\x1f\x27\x73\xb6\x97\x1f\x35\x4a\x14\x74\xe2\xbf\xf6\xcc\x31\x4b\xa2\x1e\x56\xe0\x7e\xf7\x30\xbf\x6a\xc7\xc6\x72\xb1\x3d\x33\x70\x05\x09\x07\xb1\x52\x18\x7e\xd8\x49\xd7\x79\x66\xfd\x4d\x09\x12\x8f\x11\xbd\xb4\xf1\x8f\x89\x31\x7d\xb8\xa8\x20\x09\x7c\x94\x9f\xdb\x80\x4c\xe1\x1d\x54\xcf\x4e\x8e\x1e\x95\xbb\x60\xdb\xe1\x5b\x57\xb9\x8d\x1c\x41\x28\xc0\x98\x78\x4f\x60\xf3\x37\x18\x35\x68\x0e\xcf\x25\x80\x60\x9b\x1f\x90\x62\x40\xa4\x06\x15\x64\x90\x42\x46\xba\xa5\x0b\x5a\xc3\x82\x17\x03\x97\x1c\xa4\x0c\x98\xd5\x85\xb5\xf8\x21\x4b\x93\x60\x4f\xa2\x1c\xa7\x47\xe6\xbf\x4e\x65\x59\xac\x0b\x75\xce\xc6\x4d\xae\xd7\x76\x96\x2b\x5f\x1c\x0c\x07\x19\x62\x59\x4c\x10\x45\xb7\xf0\x57\xe3\xaf\xcc\x2c\xb9\xa1\x19\xae\x5d\x5f\x76\x13\x64\x56\x76\x88\x88\xbf\x21\x49\x3a\xfc\x54\xda\x57\xd8\xdf\x80\x54\x6e\xa3\xd3\xd0\x10\xed\xb8\x31\x61\xc5\xce\xa2\x85\xd4\x2d\xa0\xe6\x69\x36\x32\x7f\xda\xe1\x9e\xe9\x6f\x2a\xf9\xe9\x35\x3d\x8e\x8c\xad\x76\x03\x07\x2c\x36\xe2\x77\x6c\x12\xe6\x27\x9e\x27\x7c\xd3\x71\xbc\xfc\x3c\x11\x13\xc0\x95\xd4\x9c\xf6\x44\xe8\x62\xb8\xf3\xeb\x71\xb9\xd9\xef\x66\x3f\x96\xfb\xed\xfd\x6c\x63\x91\x1f\xda\x53\xd4\x24\xdf\xbc\xb6\x1c\xb2\x1d\x85\x8a\xed\x51\x50\x38\xd9\x20\x57\x4d\x64\x54\xf3\x03\xd8\xd2\xb7\xf6\x83\x10\xdd\xb4\xc5\xec\x74\xda\xbe\x7d\xb5\x7f\x0e\x3d\x37\xb0\x32\x57\x28\x71\x7f\x49\xbf\xa0\x7d\x1e\x81\x29\xb0\x19\xdf\xac\xeb\x5e\x9c\x48\x04\x69\x9f\x4b\xd9\xea\x6a\x76\xec\x93\xa3\x67\x0d\x92\x00\xa3\xbf\x2e\xa4\xad\x48\xde\xd3\x1e\x57\x89\xe7\xb5\xd2\xf4\x6b\x3b\x75\x74\x28\xa3\xd8\x60\x9f\x9a\xe7\x1f\xb6\x95\x6a\xa6\x18\xca\x23\x62\x1a\xe4\x17\x88\x2a\xad\x47\x69\x0a\x1d\x39\x21\xf6\xc3\x6d\x7f\x1a\xd0\x6d\x07\x18\xd3\x51\x08\x48\x17\xba\xdd\xcd\xee\x96\x6d\x69\xbf\x8f\xbe\xd1\x11\x73\x31\x9e\x10\xe7\xaf\x5d\x9a\x59\xb8\x49\xcf\x35\xd2\x51\xe4\x22\x56\xfa\xb5\x50\xd9\xed\xb8\x71\x53\xc7\x51\xa8\xa9\xdf\xe0\xdd\x75\x26\x18\x12\x41\xc7\xd2\xc3\x92\xe9\xed\x39\x47\x7a\xec\xc6\xae\xf7\x4d\x98\x4e\x44\x80\x29\xd3\x65\x7e\x78\x3b\x57\x3b\x90\xaf\x56\x42\xa8\x1b\x11\xf2\x68\x28\xce\xda\xdb\xbe\x87\x37\xc4\x7d\x22\x94\xa3\xe5\x3a\x09\x0e\xb3\x23\xa3\x04\x1f\xdd\x60\x42\x50\x40\xc4\x5e\x91\x73\x62\x08\xac\xa1\xa2\x8a\xb3\xe5\x5c\xb1\xc7\x55\x88\x48\xe1\xe5\xb1\x31\x5e\x00\x5b\x28\xdf\x47\x1f\x46\xf8\xda\x09\x86\x60\xe2\xad\xec\x4a\x6e\x5a\x44\x91\xec\xea\x7b\x8d\xa7\x74\x6d\x1d\x09\x41\x8d\x5e\x5c\xa9\x35\x70\xd4\xd2\x2d\xe6\xc5\xbb\x06\x3d\xdd\xcb\xaf\x65\xe8\x20\x68\x63\x56\x5d\x66\xe4\x86\x37\x29\x45\x88\xd9\xf3\x5d\xab\x8b\x61\xa5\x62\x2f\x95\x2f\x40\x2b\x27\x56\x2d\xc4\xef\x99\x53\x87\x4f\xd5\x07\x31\x6a\x15\x32\xa4\x15\x97\x36\xdf\x3c\xf4\xdc\x34\x88\x00\xe1\xa9\x0f\xc5\xe1\x3b\x18\xb2\x19\xad\x05\xf5\x23\x40\x96\x1e\x52\x91\xc1\xae\xf9\x1c\xb9\x42\x86\x9a\xa9\xde\x75\xfc\x99\x76\x1c\x2f\xc4\xc2\xd6\x7b\x0a\x1f\x3b\x73\xaf\xc6\xc9\xd0\x8e\x13\x78\x98\x45\xb4\xab\x61\xfe\xb4\x5e\xaf\xb6\xdb\xd5\xd3\x63\x3b\x42\x90\x8c\xec\x76\x39\xff\x9d\x98\xa1\x76\x5c\xe6\x40\x64\x02\xf2\x27\x24\x4f\xc2\xac\xbe\x4c\x7b\x9f\xb3\xff\xce\xb5\xe3\x07\x1a\x2b\x52\xcf\x50\xea\xa2\x3c\x36\xbe\x68\x91\xd7\xaf\xd9\x97\x69\x99\xfa\x63\xf8\x30\x7e\x4c\xd0\x6b\xe2\xe9\xed\x05\xfb\xda\x09\x23\x1f\x71\x31\x8b\x2d\xdd\x67\xdf\x83\x68\x8e\x26\xd8\x0a\xb4\x4f\xab\x9b\x12\x40\xa5\xf9\x01\x65\x76\xeb\xb1\xc2\x5a\x77\xad\x28\xa0\x86\xd9\x73\x5e\x41\xfd\x2b\xcd\x54\x13\x64\x5c\xce\x04\xed\x44\xb1\x40\x14\xfc\x3d\xaf\x5e\xef\x28\x3a\xb5\x9b\xb2\x76\xe2\x88\xdb\x2e\x54\x22\x48\xb0\x19\x4d\xed\xc4\x9c\x74\x58\x96\x9f\x75\xf3\x05\xed\x9f\x93\x38\x01\xd9\x75\x8d\xb8\xde\xd1\x1e\xe1\x10\xba\xfe\x50\x6a\xb5\x26\xae\x3f\xb4\xb2\xc2\xec\xcb\xc6\xb5\x98\xca\x0f\x68\x47\x38\x1e\xda\xde\xdc\x2c\x43\xe2\x73\xb3\x07\xdd\x10\x23\xab\x66\xa5\xdf\x35\x61\x42\x65\x9b\x3c\xb4\x23\x42\x29\xc2\x5e\xbe\xb4\x15\xdb\xba\x50\x84\x1e\xbd\x47\x91\x28\x69\xb0\xe3\xb3\xb2\xe4\x5f\x9e\x3d\xa3\xf4\x64\x64\xb1\xd3\xc4\xa2\xd3\xcb\x50\x68\x47\x86\x09\x4e\xa6\xc5\x6a\xdb\x0a\xf5\xed\x57\x8f\x3f\x97\xdb\x5d\x4b\xdd\xaf\x1d\x99\xf8\x64\xe2\xa0\xaa\xe7\x69\xfd\xb5\xcd\xf9\xa9\x7a\x2d\xae\xad\x06\x29\x39\xfa\x48\x8a\xd7\x7c\x8d\xf5\x90\x3f\x2e\x0a\x36\xa3\x9f\x28\x8f\xdc\xaa\x03\x90\xaa\xf5\x0d\xcf\xdf\xaa\xd1\x14\x50\x71\x82\x6e\x08\x65\xe3\x6f\xa1\xd7\xc7\x35\x1a\x28\x38\x6e\xb8\x6b\xfe\xb9\x9a\x3f\x11\x90\xac\x4f\x37\xa8\x1d\x64\xf9\xb6\x5c\xfe\xf2\x15\x0d\xbc\x37\xba\x1c\x78\x3e\x6e\x34\xd6\xd1\x5d\xe6\xaa\xeb\x7c\xd6\x0e\xf8\x9c\x9c\xc5\x41\x21\x64\x38\x11\x5c\xc7\x8d\xec\x67\xf9\xc0\xc2\x5c\x13\xa5\xd9\x69\xeb\x3a\x89\x22\x02\x4c\x5d\x43\xf9\xeb\xd5\xd6\xa8\xfe\x18\x9e\xc3\xf5\x35\xe2\x33\x1f\x9e\xe6\x3f\xf6\xdb\xc6\xa9\xb1\xbf\xf7\x84\x44\x54\xee\x43\xfa\x9f\x33\x7c\xf6\x89\xba\xcc\x00\xdf\x0f\xb1\x12\x50\x9d\x32\xca\x31\x8c\x5e\xa9\xeb\x0b\x86\x86\x3e\xad\x50\xbe\xda\x06\x46\xda\x0d\x62\x8d\x51\x4c\xf5\x5a\x7c\xac\x07\x91\xa5\x9d\x3a\x6e\xc8\x34\xe6\x71\x0d\xfb\xe6\x01\xf1\x1d\xc6\x0b\x9a\x9e\x18\x6e\x18\x53\x03\x73\x05\xf5\xfd\x8f\x7b\x59\xa4\xf9\x77\xf5\x38\xed\xb2\x28\x44\x66\xcc\xed\xab\x15\x21\xf9\x2d\xa7\x91\x76\x23\xc6\xb0\x49\x82\x2b\x35\x9f\x5d\x84\xda\x7f\xc3\x3f\x1e\x9e\x8d\x53\x25\x91\x90\x66\xcd\xfb\x95\xaf\x80\xfe\xfe\xf0\x56\x63\x16\xc5\xf6\x85\x99\xda\xc2\x68\x00\x4f\xbc\x4e\x0c\xe9\x3c\xea\xed\xd0\x6e\xe2\xd1\x54\x39\x95\x70\xe2\x25\x6c\x8a\xec\x82\xe4\x7d\xf4\x36\x93\x00\x30\xd7\x90\x22\x06\x6f\x51\xe4\xed\x77\xe7\x1e\xa0\x5c\xdd\x05\x27\x7a\x07\xd6\xd0\x2e\xf7\xa9\xf0\xf2\xd4\xc1\xba\x4c\x02\x78\x78\x19\x1e\xbb\x58\xe4\xff\x80\x74\x57\xdc\xe4\xa3\x72\x48\x73\x5c\x20\x30\xf7\x58\xa8\x54\x7f\xed\x57\xf3\x27\xcb\x37\x38\x1a\xa7\x5d\x9c\x2f\xcb\x4a\x96\xc5\xc7\xfa\x0b\x0b\x1e\xed\x1d\x6b\x81\x15\x13\x55\x8c\x3a\xeb\xaf\x92\x75\x69\x57\xfa\x01\x90\x72\xf2\xd7\xb6\xe6\xe3\xdb\x96\x2c\x20\xa9\xf3\x03\x6c\xa1\x46\xbf\xa1\x1f\x0e\x6a\x57\x26\x7e\x68\x5a\xf2\xb6\x6f\x69\x3e\xc9\x7f\xa3\x5d\xc9\x21\x26\xaa\xa9\x55\x55\x9d\x3b\x0d\x62\xed\x4a\x49\xa8\x1e\xec\x4a\x39\xe7\xea\xa6\x4d\xa0\x4f\x7f\x2e\xe5\x25\x58\x8b\xb9\xe7\xe5\xbf\x6f\x79\x79\xec\x1e\x5e\xf9\xb6\x4a\x96\xab\xd9\x07\x6e\x80\x0f\xbc\xb2\x1a\x9f\x76\x50\xc8\x99\x99\x3f\xd4\xcd\xd1\x6a\x72\x8e\xee\x58\x29\x81\x99\x8f\xbc\x50\x3c\x43\x4a\xa2\xed\x6b\x51\xd6\x0f\x69\xfe\x36\xe5\xbc\x69\x57\x01\x45\x04\x07\xa2\xfb\xae\x66\xa8\xea\x36\xd8\xda\x5d\x08\x12\xd3\x93\xf8\x06\x8f\xf0\x61\x33\xc8\x53\xa1\x89\x76\x01\x42\x23\x5b\x20\xbf\x64\x06\x2f\xb9\xe1\x2a\x54\xc3\xde\xc4\xe1\x6d\x6b\x57\x05\xa6\xbc\x58\x58\xf4\x95\x67\xd2\xce\xd3\x0b\xc0\x73\xbc\xc8\x31\xf9\xf1\x47\xf8\x78\x69\x95\x1f\xed\x61\x3f\xc4\x2c\x0a\xf2\xe7\x6a\x00\x44\xc5\xbc\xf2\x12\xf6\x79\x41\xf0\x23\x59\xb4\xf5\x59\xed\x39\x81\xe7\x47\x56\x19\x7e\x6b\xdb\x54\x2e\x66\x84\xe7\x7a\x11\xf6\x98\xfd\xf8\x6b\x2e\xd2\x3a\xb0\x3f\xf7\x1c\xea\x94\x35\xdc\xce\x34\xcb\xa7\x1d\x32\xcf\x8f\x20\xf6\xae\x31\xa1\x74\x38\x06\xed\x05\x42\x49\xc2\x0e\xec\xeb\x9e\xf0\xc7\xe0\xdb\x78\x61\xa0\x30\xc9\xfd\x72\xf7\xb3\xcf\x44\xa8\x3d\xe6\x05\xc8\xd2\xde\xf6\xd0\x11\xd4\x79\x78\x2f\x2c\x94\x98\x39\x47\x17\x1b\x23\xc8\x26\xe6\x1a\x5e\x81\x89\x10\x71\xef\x0a\x32\xfe\xb5\x92\xc5\x18\x23\xaa\x3d\xa6\x99\x36\x00\x81\x55\x35\x27\x36\x9f\xd1\x85\x22\xd7\xd3\x1d\x84\xad\x9e\x24\xe5\xd0\x5e\x14\xa8\x84\x34\x68\xbf\x28\x9c\xed\xb9\x9f\x5e\xc4\x12\xbc\x0f\x8e\x14\xc8\xcb\xff\x5c\xb1\xee\x76\x74\xe4\xd8\xce\xf4\xde\xba\xf5\xa2\x18\xa4\xb0\x81\x71\x05\x3d\x1a\x33\x3b\x40\x84\xd4\xbb\xc0\x4b\x45\x8c\x27\xfb\xc6\xf4\xf7\x8d\x87\x97\x28\xea\xc4\x83\x8c\x9f\x5a\xdd\x63\xed\x09\x3f\xb0\xfc\x2e\x37\x9d\xe2\x97\x3b\x7a\x13\x42\x85\x68\xec\xfa\x30\x38\xa3\x6d\x96\x7d\x6d\x21\x57\x83\xee\x65\xed\x49\xc7\x41\x76\xb9\xe7\xdd\x1a\xa1\x5c\xb7\x9d\x37\xe9\xa9\x28\xf6\xa1\xa5\xd1\xdb\x14\x75\x71\x8d\xc3\xc7\xfe\x20\x71\x71\xb6\x98\xd4\x11\x59\x5b\xf4\x71\xc7\x95\x6e\xed\x29\xc9\xc0\xec\xd7\x38\x75\x2e\x51\x53\xda\x03\x8f\x84\xc9\x74\x85\x19\x6f\xcc\x58\x2c\x20\x2f\x70\xb7\x6c\x5d\x74\x24\x94\xe1\x46\xee\xbb\x85\x20\xff\x82\x74\xda\x1a\x78\x20\x48\x47\xcb\x3a\xc2\xc1\x1d\x1f\xf9\x2e\x4d\x24\x84\xbe\xcb\xd3\xfc\xa1\xa8\x6b\x28\xbf\x86\x58\x3f\xdd\x2c\x69\x6c\x6f\x5b\x3d\xce\xef\xdb\xbf\x05\x31\x96\xbe\x1b\x87\xa2\xf8\x28\xca\x4c\x75\x47\x88\xe3\x55\x9c\xbf\x28\x6b\x70\x3e\xb5\x3c\x33\xc3\x2b\xfb\x8e\x47\xef\x1c\xe5\xe5\x50\x5d\xbd\xed\xe2\xd4\xbe\x13\x87\x08\x64\x7a\x58\xde\xcd\x1e\xf6\xcb\x3f\x9f\x97\x8f\xdb\xe5\x76\xdf\xaf\xac\x6b\xdf\x91\xcc\x16\xe3\xa6\x4d\x84\xef\x48\x15\x6a\x2b\x12\xd4\xd1\xeb\x4f\xfa\x55\xbe\xeb\x08\x4e\x65\x65\x05\x70\xec\xdb\x00\xdf\x8d\x1d\x9f\x38\x75\xec\x4c\x9b\x22\x62\x19\x9d\xcf\x73\x48\x54\xf1\x47\x81\x5d\x05\xf6\x5c\xbe\xe3\x04\x7d\x40\xe8\xc5\xed\xd8\xad\xd9\xf7\x03\x17\x81\x30\x19\xaf\xea\x99\x52\x9d\x8c\x54\x73\x88\x85\xa4\x5a\xca\x8f\x48\x54\xd8\xae\x1e\xdf\x0f\x49\x37\xb1\xf1\xca\xd3\xfa\x9c\xf1\xb4\x84\x3d\x01\x31\xf7\x89\x1d\x14\x78\x3e\x66\xe9\x0e\x25\x37\xe8\x38\x2c\xfc\x3c\x16\x1f\x7f\x2b\xa1\xa8\xfd\x20\x02\xd4\xdd\x5b\xa4\x87\xb4\xe6\xd9\x2e\x6d\x71\x22\xda\x0f\xb8\x22\xc5\x6c\x5a\x16\x8f\xe7\xa3\xd7\x1e\x92\x2c\xa0\xa8\x58\xdd\x34\xcb\x60\x64\xde\xfc\x90\x53\x31\x1a\x81\x27\xb2\x2b\xc8\x6b\x9f\x31\x12\x2b\xc0\x8c\x97\x7c\x83\x7a\x34\x93\xfd\x28\x4a\xd0\x8f\x47\xc8\xdc\xa2\x2c\x4e\xa8\xf0\xd9\x16\x55\xb4\x1f\x25\x5a\x12\x4e\x7c\x95\x63\x5e\xb2\xbd\xab\xd8\x55\xd8\xa9\xf3\x50\xe4\xaa\x68\xaf\x18\x7b\x0c\x5d\xbb\x3b\xc0\x40\x6a\x80\x2a\xd1\x7e\x1c\x50\x02\x8f\xe0\x05\x13\x61\x81\x1f\x33\x6e\x74\xbd\xb2\x2c\xcd\x0f\x8b\x81\x01\xf5\x63\x11\x62\x55\x94\x24\x94\x28\x11\x3c\x91\x88\xd3\x7e\x22\x34\xee\x94\x0f\x69\xf9\x36\x98\x94\x89\x0e\x25\x71\x0b\x63\xa2\x9b\x9a\x71\x46\xef\x93\x7b\xae\x07\x3d\xf6\x7b\x84\x89\x2f\xff\xf3\xd2\x5c\xe7\x8f\x76\x0c\x23\x06\x5e\x4b\xad\x9a\x1e\x1b\x67\x6f\xf4\x34\xc2\x0b\x10\x31\x7b\x07\x39\x54\x69\xb5\x26\xe6\xac\x6b\x00\xbb\xd1\x3a\x14\x21\x73\x4c\xa9\x9f\x08\x0c\x28\x63\xdb\xfb\x38\x32\x16\xca\x1d\x32\xde\x8c\x15\x8b\x06\xbb\xa9\xaf\x62\x22\x17\xc0\x19\xdc\x04\x4c\xad\x7a\xd0\xdf\x9b\xc0\x10\x06\x58\x26\xab\xf9\x1b\x94\xb7\x60\xb3\xc9\xf6\xa5\x40\x22\x70\x6b\x92\x3c\xdf\x42\xa6\x17\x40\xac\x7d\xf6\xb0\xf6\x1c\x64\xc3\x9e\x6d\x56\x4f\x8f\x3d\x21\xbe\xe6\x88\x8f\x59\xa8\xcd\xc3\x7c\x0b\xcd\xda\x5a\x5a\xc1\x27\xed\x6b\x90\x46\xd5\x82\x97\x35\x2a\x72\xf4\x4c\x9e\xd6\xa1\x63\x3a\xad\x16\x5f\x39\x3f\xa6\x72\x49\xd8\x93\x11\xec\x4c\x07\x8e\xeb\x63\xb5\x72\xf9\x3c\xeb\x2f\x91\xc0\x09\x85\xb0\x0d\xac\x45\xb3\x2d\xdf\x16\x58\x72\x1e\x73\xd7\xe9\xc0\x89\x93\xa4\xcb\x93\x4a\xa8\x2a\x4c\x31\x55\x3d\xb8\xa2\x0e\x7c\x07\x10\x72\x69\x08\xa5\x76\x9f\x7d\x2f\x22\xf0\x83\x28\x88\x3b\x84\xed\x2c\x57\x37\xe7\x72\x88\xb1\x35\x23\x03\xdf\xb7\xb0\xc7\x3d\xa1\xf2\xd2\xfa\x6b\xcf\x27\x58\x3b\x74\x10\x86\x2a\x74\xdb\x7d\xb5\x2d\x03\xd8\x8b\x86\x9c\x1b\x64\x45\x8d\x3e\xf9\x06\xde\x21\x3f\x37\xdf\x8e\x6c\xc2\xe8\x45\xb1\x88\x56\xc8\x53\xc9\xf3\xc3\x79\x3b\x41\x86\x7d\xf5\xdf\x2b\xa6\xfd\x7f\x46\x17\x10\xbe\x2d\x32\xac\xbf\x36\x80\xb8\xb2\xa9\xba\x60\x33\x92\x47\x0e\x96\x3e\x9e\x68\x11\x4f\x72\xf3\x99\xc1\x91\x4f\x00\xf6\xbd\xe4\x6d\xf2\x0a\xf1\x21\xa3\xe7\x8b\xc2\xc8\x25\xa6\xc0\x39\x3f\x71\x91\x66\x69\xfd\x45\x3c\x96\xc3\x45\x13\xb4\xe3\x25\x66\x79\x6d\xb5\xe3\x99\x97\x57\xb2\x4f\x41\xec\x25\xb8\xbc\xb6\xb7\x7d\x2a\x1b\x1d\xc4\x5c\x20\x8e\xfd\x5c\xa9\xba\xfd\x9b\xa4\x4a\x40\x05\xb5\x41\x6b\x1a\xd7\x6b\x82\xb7\x5d\x07\xb1\x76\xf1\x13\x73\xa5\x5a\x59\x33\x1d\xf0\xc6\x06\x63\xb9\xe2\x63\xcd\xf3\x2f\x6a\x1d\x59\x80\x4c\x55\x3b\x44\x3a\x02\x57\x2c\xf2\x10\x35\x3e\xff\x3d\x2f\x8f\x45\x3e\x21\xd5\xa3\x03\xe9\xf3\x38\xb8\x50\x9f\x1a\xbd\x3e\xa9\x19\x16\x7f\x2c\x5a\x81\x6e\xf7\x57\x5a\xbf\x36\x26\x10\xc5\x6c\x2e\xe2\xe6\xd1\x6b\x02\xdf\x43\x8f\xfd\x36\x83\xcf\x14\x21\x36\x83\xb7\x05\x01\xa9\x72\x22\x77\xe6\xc8\xb3\x0a\x80\x07\xd0\x17\x5f\x74\xdb\x03\x10\xaa\xa0\xa7\x3e\xd6\x6f\x8f\xb8\x98\xa0\xd3\xf7\xa5\x7d\x1f\xa1\x9a\xcd\x5e\x57\xd5\x3c\xaf\x53\xde\x17\x3b\xb4\xa3\x14\x21\xfa\x6e\x56\x77\xfb\xc7\x97\xf5\xcd\x72\x63\x6e\x21\x74\x3d\x81\x94\x8f\x0f\xc5\x11\xb2\x14\x5f\x50\x76\x6a\x99\x5d\xcd\x20\xcf\x71\x62\xe3\x5e\x5a\x9c\x27\x42\xfe\x6b\x7e\x3c\xf5\x29\xa8\x6c\xb2\x24\xf4\xa5\x44\xda\xe8\xf9\xfd\xea\x71\xb9\x5d\xee\x97\x7f\xce\xef\x67\x8f\x77\x4b\xab\x74\xa1\xc3\xc0\x21\xce\x36\x6a\x6a\x5d\xaf\x16\xed\x01\xce\x5c\xe8\x09\x34\x41\x79\x5b\x94\x6d\xe9\xcb\x1d\x39\x7e\x61\x20\x34\x62\xab\xd2\x6a\xc2\x22\x85\xa1\xaf\xd0\xb1\x4a\x2b\x4b\x02\x3c\x58\xac\x61\x18\x78\x08\x74\xc6\xf6\xc0\xf2\x4b\xd6\x85\xdd\x2c\xc3\x30\x50\x08\xce\xe6\x87\x12\xe0\xb6\x2c\x8e\xcf\x85\x6a\x8f\x85\x34\x19\x7e\xcc\x1e\x58\x7f\x1a\x84\x61\x14\xd8\x24\xc7\x33\x20\xdd\xde\xbc\x44\x6c\x00\x92\x3c\x5a\x2a\xf2\xc9\x85\x18\x86\x31\x11\x30\x34\x8b\x0b\xdb\x6d\xfe\x18\x1d\xd7\xae\x17\x5a\xf4\x24\xaf\xba\x3e\xb2\xa7\x72\x79\xac\x4f\xd3\x6a\xf1\x3a\x64\x4a\x5a\x35\xf4\x13\x2f\x31\x4a\x4f\xf3\x73\x71\xae\xec\x97\xb4\xf7\x1e\x39\xdc\xb3\xad\x41\xfd\x00\x2f\x8c\x98\xc6\x54\x9c\x2a\x1e\x8b\xbe\xef\x1e\xc6\x6e\x80\x0e\x0b\x3a\x62\xf3\x22\xcd\x6f\xd2\xc3\x0d\xef\x1d\x67\x11\xaa\xc5\x74\x36\xbe\xea\xd5\x2f\xbb\x5b\x8c\x23\xe2\xcd\xb0\xb4\xa3\x45\xd9\xce\xbc\xc4\xe5\x96\x71\x7d\x43\x2f\xb2\xaf\xe8\x79\x65\x89\xd8\xdf\xfa\x01\x16\xf8\x48\xa8\x6c\xfe\x25\x33\x58\xe5\x0b\xfe\xd5\x9d\x3c\x82\xc8\xf6\x57\x3d\x14\xf9\x61\x95\x9f\x6c\x79\x5b\x87\x49\x1c\xd8\xf2\xe0\x9c\xd7\xb6\x7e\x8f\xef\x25\xb4\x43\x0c\xc6\x1a\xb3\xf0\x96\xdc\xfa\xe6\x6b\x5b\x9f\x15\xe4\xf5\x6a\x31\xb9\x34\x78\x68\xe4\xf2\xd2\x23\x1c\xda\x16\x46\x1d\x0a\xc1\x6c\xff\xf5\x23\x7c\xda\xfa\x38\x0a\x9b\x8c\x26\xb5\xf4\x5d\xf4\x7f\xd7\xfc\x0d\xf6\x8b\x7e\x7f\x9c\x0e\x65\xc8\x1d\xb3\x59\x2f\xeb\x57\x30\xb8\xcd\xe9\xa8\x31\x54\x3e\xc1\xbc\xb1\x19\xac\x25\x19\x31\x2d\x63\xbb\x32\x3d\x1c\xa0\xac\x28\x95\x6d\x7e\x01\xb1\x83\x48\xce\x41\xd3\xe9\x60\xe2\xb9\xac\x1d\xaa\x3c\x83\x25\x5c\xcc\x56\x9b\x6b\x8c\x8a\x3a\x04\x21\x70\x53\xa1\x86\xd8\x4b\x08\x60\x37\x52\xfb\x02\xf3\xdb\xa7\x02\x5b\x23\xcc\x4d\x31\x27\x74\x1d\xab\x9d\x47\xf4\x3c\xd3\x57\x62\xae\xeb\x63\xc7\x2b\x41\xa9\x09\xb4\x70\x79\xb1\xff\x99\xf0\xcd\x99\x1b\x51\xf2\xb4\xb9\x46\x7a\xe8\x59\xe8\x69\x78\x90\x66\x1e\x67\x9a\xd4\x09\x4f\x95\x05\x21\x5e\xcc\xd7\xde\x2a\x63\x7e\xc0\x13\x03\x85\x1b\xf6\x2f\x0d\x9f\xc1\x0f\x25\x2e\x88\x9f\x45\x76\x3e\xc2\xea\x68\xf0\xd8\xa4\x6f\x3c\xb6\x7f\xcc\x07\x0f\xcb\x79\xfb\xd4\x56\x64\x07\x0e\x77\x2f\x5d\x68\xfe\x99\x96\xcd\xd0\x2c\x70\xb8\x45\x86\xda\x8e\xda\xf1\xb5\x02\x26\xb0\x0e\x3a\x2b\x8f\x48\x80\x99\xa5\xb7\x76\x72\xb3\xd0\x0d\x3c\xab\x41\xd2\x46\xc3\xf6\x98\xef\xd9\x5a\xd6\xc6\x24\x3e\x51\xc8\xee\xca\x0b\x08\x63\xe9\x23\x9c\x8d\x6b\x3d\x6a\xd1\xd3\x2c\x14\x10\xf6\xbd\x01\xcc\xa0\x2e\x79\x99\xa3\x58\x83\x19\xc4\xdc\x84\x38\xc8\xb2\x54\xeb\x67\xe4\xeb\x6d\x0f\xc5\x44\xdf\x0e\xf5\x2b\xc6\x0a\x2d\x0d\x87\x66\x4c\x11\xc6\xe1\xc7\xf3\xd3\xf3\x7e\xb5\x5b\xae\xf7\xf3\xa7\xc7\xdd\x66\x36\xdf\x0d\x49\xff\x35\x8b\x1c\x17\x5b\x2b\x3a\xa8\x09\xaa\x5b\x99\xf9\xd1\x09\x6a\xd8\xe1\x01\x17\x44\x51\xfc\x25\xc0\x70\xa1\xdb\x43\x91\xe3\xb7\xc1\x7b\xb3\x83\x6c\x8a\x0c\xc6\xd8\xa5\xd1\xd9\xa4\xc6\x6c\x1c\xd4\xaf\x7b\xcd\xb3\x4c\xf0\xce\xb9\x19\xcc\xb7\x38\x10\x88\x3c\xe4\x4a\x35\xde\xd7\x91\x67\xd3\xf0\x06\xcd\x92\xd0\x09\x4d\xaa\xd9\xf0\xa3\x42\x39\xab\x2f\x99\xa7\x34\x4b\x24\x77\x3b\x5a\x3c\x4c\x7f\x55\xd3\x89\x4b\x96\x68\x97\xb5\xca\xef\x47\xd8\x40\x75\xce\xea\x4b\x3e\x69\xcd\x38\xf3\x91\x3f\xf5\x0e\xbb\x11\xfb\x55\x10\xc6\x19\xe0\xc6\xd4\xd6\x9e\x9b\x01\x87\xc3\x1d\xe1\x5c\xac\xc5\x65\x1c\x02\xd6\x57\x61\x5e\x14\xf2\x7c\x6c\xf5\xf5\x46\xf7\x25\x22\x81\x00\xf1\xbb\xb3\x10\x50\x76\x9a\x13\x9a\x89\xd8\xc5\x8c\xfb\x07\xd4\xaf\xc3\x14\x01\x13\x89\x93\x24\x3d\x05\x87\xa7\x72\x4a\x16\x61\xfc\xef\x64\xc2\x91\xc9\x20\x41\x23\x47\x60\xf1\xd1\x1a\x53\x92\x89\x2e\x17\x71\x53\x94\x65\xf1\x91\xe6\x07\x8c\x30\xfb\xa8\x57\x33\x1c\xbc\x08\x71\x16\x2b\xfc\xa3\xd1\xd4\x1d\x8e\x48\xfc\x9e\x14\x6c\x13\xd8\x3d\xf3\x73\x05\xea\xa2\xcd\x42\x33\xed\x4a\xac\x69\x54\x27\x90\x29\x54\xdb\xaf\xa3\x28\x86\xd2\x06\x3a\x72\x1c\x8d\x40\x4f\x7e\xae\x8b\x7f\x9c\x95\x05\x63\xea\xc8\x71\x13\xac\xab\xef\x0f\x2d\xaa\x8b\x38\xcc\x86\x0e\x59\xe4\x06\x4c\x9a\x56\xa0\xc6\x2d\x4f\xf3\x43\xeb\x68\x36\x3e\xd8\x6e\x5a\xf3\x5b\x47\xae\x72\x10\x42\x70\xee\x1a\xd0\xb1\x0f\x6e\x22\x64\x88\x3c\x9f\x80\x8d\x54\xe0\xbf\x2f\x16\x0f\x9d\x35\x8a\x3c\xc5\xb0\xa7\xf1\x6e\xfe\xf4\xe7\xd3\xaf\xc7\x6b\x21\xdc\xc8\x85\x89\x3c\x4d\x5c\x53\xa8\x68\x82\x90\xa3\x36\x0a\xa8\x1a\x8f\x60\xaa\xe8\x3d\xd5\x96\x69\x4e\xe7\x3b\x24\x61\xd2\x38\x8f\xcf\x50\xfe\x82\xf4\x36\x2d\x2b\xea\x44\xb5\x77\xea\x87\x09\xf7\xb1\xc3\xeb\xc7\xf2\x71\xbf\xdd\xcd\x1e\x17\xb3\xcd\x62\xdf\xc4\x26\x9e\xdf\x0e\x02\x9d\x98\x65\x86\x99\x2b\xa3\x99\x3c\x98\xbe\x51\xe0\x87\xa6\x88\x50\xe6\xe4\x7a\xb6\x49\xc6\x28\x08\x88\xae\xa2\xb3\xa8\xfd\x64\xde\xe8\x2d\x04\x21\x75\x4a\x21\x62\xeb\x49\xe3\x3e\xf6\xad\xd3\x1b\x85\x3c\x41\x2f\x01\x3e\xf1\x5d\x6d\xc8\x9b\x29\xca\xaf\x41\x6d\x2a\x62\xd2\x47\xa4\x22\xb2\xbc\xee\x3e\x0a\xca\x2a\x99\x83\x51\xe0\x99\x3e\x7e\x04\x9b\xab\x73\x55\xf3\x5a\x0e\x63\xb0\x28\x0a\xc0\xca\xa1\xac\xab\x03\x02\xea\xcb\x09\x35\x16\x1d\x45\x2c\x46\x7b\xb3\x23\x07\xec\x85\x80\xce\xdf\x41\x8c\xa2\x48\x09\x1e\xd8\xc7\xa6\x0e\xc2\xd6\x48\x45\xb1\xeb\x61\xb5\x72\xf5\x6f\x5e\x75\x5d\x65\xcd\xdf\xfd\xc4\x64\xca\xac\xa8\xf8\xb6\x86\xd3\x68\x41\xc5\x9e\xa0\x40\x1e\xd2\xb6\x95\xa2\xfb\x38\xb1\x20\xc1\x90\x66\xa9\x2c\xd2\xf7\x2b\xef\x38\x56\x12\x51\x97\xcb\xb2\x5c\x57\x1d\xd6\x60\xf0\x08\x89\x13\x21\x60\xb3\x35\xa5\x37\x50\x75\x9c\xfb\x7f\xab\xff\x43\x47\x49\xec\x4a\xe3\x0f\xff\x02\x9e\xd5\xaf\x4f\x7a\xd0\x93\x39\xb0\x65\x51\x12\x87\x16\x8a\xdf\xa2\xec\xb7\x75\x51\xf2\xce\x6a\x70\x97\x21\x05\x7f\x0e\xbc\x84\xaa\xfe\x91\x17\x1f\x39\x26\x8c\xbb\xd6\x29\x1d\xf1\xc0\x41\x89\x46\xf8\x24\x23\x76\x5b\x94\xc7\x73\xc6\xdb\xc3\x91\x9b\x10\xe0\xed\x74\x9b\xb6\xc9\xf9\x48\xf8\x2c\x8a\xda\x16\x57\xae\x78\xcd\x5f\xca\xb1\x39\x93\x4a\x60\x8f\xd3\x62\xf9\x73\x3f\xd4\x0e\xd4\x91\x12\x12\xe9\x27\x75\x59\x1c\xc9\xbe\x0e\x2c\x6b\xa4\x7d\x90\xe4\x00\xe6\xaa\x71\xe8\xef\x8b\x73\x39\xc1\x1b\xa1\x23\x1d\x11\x76\xc4\x64\xdf\xba\x54\x49\xec\xf8\xa4\x42\xba\x7c\xd9\x3c\xb5\x7f\x63\xae\x49\x19\x9c\xbe\x97\x87\x31\xe3\xdd\x10\x94\x3b\x90\xd3\xb2\x76\x89\x58\x59\xae\x19\x25\xba\xc5\xc1\x24\x89\x5d\x21\x31\x5e\x42\x65\x87\x75\xaf\xef\xe1\xd2\x82\xc5\x3e\xb8\x48\x1a\xb3\xb7\xa0\x8a\x09\x7e\x1a\x1d\xfb\xcd\x3a\xb0\xf2\xf2\xdb\x33\x26\x28\xf5\x39\xdb\xf2\x0c\x9e\xcb\x42\x42\x3b\xd5\xe3\xd0\x75\x31\xcf\x73\x1f\x2c\x06\x88\x45\x1d\x87\x21\x51\xf5\x99\x0a\xdd\x7c\xb2\xcc\x1f\x87\x9a\xf2\xb8\xca\xf6\x57\x56\x96\xfa\xd8\x9e\x87\x79\x24\x33\x88\x04\x30\x8d\x4f\x42\x9a\x0a\x5d\xea\x3a\x66\x61\xc8\xe2\x7e\xc7\xf1\xe8\x1a\x2c\x51\x9e\xa5\xb4\xae\x2a\x82\x07\x4c\xdf\x0d\xd3\x1e\x66\x84\xd6\xb3\x3f\xf7\x4f\xcf\x8d\xf9\x7e\x7a\xb0\x19\x90\x38\x76\x7c\x34\xb9\xe6\x27\xf3\xa7\xf6\xe3\xc7\xa1\x46\x57\xb9\x2e\xf9\xa0\x42\x10\xc7\x1c\x42\xdd\x36\x6e\xf9\x43\x4a\x71\x33\x26\x49\x34\x62\xf8\x9e\x5f\x79\x79\xe4\x75\x39\xea\x69\xd1\x31\x77\x3d\x6d\x32\x2f\xeb\xea\xe0\x0d\x2c\x70\xcc\x85\x46\x89\x7e\xe2\xd9\x1e\xe5\x5f\x63\xe1\x78\x58\x01\x33\xed\x8b\x53\x64\x04\xdd\xc8\xd0\x64\x39\x0c\x42\x6c\x25\x0b\x03\x1e\x1f\x9d\x53\xc5\xb8\x2b\x29\x14\xfc\x58\x5f\x6b\xb3\xd1\xb1\xf4\x7c\x6c\x99\x3a\xa4\xef\xc4\x67\x3d\x51\x6a\xb3\x43\x93\x18\x2d\x94\xce\xd2\xd3\xba\x78\x6f\xdb\x9c\x76\x45\xff\x3b\x4b\x0d\xb8\xec\xa9\xf5\x7c\x03\x55\x71\x2e\xe5\x80\x2e\x9c\x92\xad\xed\x64\x57\x9e\xc2\xfe\x8d\xc6\x7f\x9a\x61\x70\x09\xea\x16\xe0\xea\x8e\x6f\x7f\x06\xb1\xeb\xb4\xfb\x46\xe3\xfb\x92\xd0\x84\x39\x0c\x11\x09\x84\x62\xd3\xe0\xcd\x8f\xd1\xeb\xd1\x8e\x34\x76\x2d\xb7\x39\x80\x49\x4f\x3b\xd6\x6e\x44\xcc\xab\xc0\xa7\xf5\x1d\x7a\xe7\x8c\x25\x36\xa6\x1b\x53\xd4\x57\x43\x18\x9d\x53\x93\xbc\x2b\xcf\x32\xd4\xcc\xf9\x55\x16\x6d\xda\x27\x71\x3c\x57\xab\x41\x92\x60\x5e\x14\x88\xc1\xb9\x12\xd3\x25\x8e\xe2\x3a\xb0\x7d\x45\x8a\xd8\xff\xda\x1d\x34\x71\x63\x0f\x83\xc7\xe5\xee\x7e\x4e\x5b\x7c\xd1\x1d\x13\xe4\xba\x10\xdb\xf4\x9a\xf2\x02\x83\x7b\x4d\x3c\xbf\xe7\x94\xcc\xf9\xe9\xb6\x28\xd1\x99\x5a\xf3\x34\xef\x69\xa0\xeb\xc4\x63\x91\xef\xf5\xb2\xb1\xd3\x09\xfe\xc4\xe3\x12\x0b\x46\x58\x69\x0b\xf6\x1c\x8d\xd6\x06\x9a\xd5\x82\x7b\xd8\xde\x40\x5a\xf6\xd5\x6b\x71\xce\x14\xb2\x47\xb4\x97\x10\x94\x12\xbf\x2f\xea\x87\xe2\xbd\xbb\xb2\x0e\x31\xf5\x87\x4d\x25\xee\x5e\xe7\x72\xda\xdf\x18\xbd\xb6\x80\x6b\x41\xea\xef\x85\x3d\x53\x00\x3e\x31\x71\x53\x08\xf6\xc0\x8f\xa2\x98\x4c\x93\xd9\xe8\xa8\x09\xee\xc2\x6e\xb2\xdf\xa7\x4a\x21\x47\x4b\xda\x26\xd8\xa8\x2d\x8a\x05\xff\xeb\x99\x79\x6f\x53\x3c\x49\x28\x62\xdf\x37\x8c\xe5\x69\x09\x0a\x29\x99\x16\x70\xb2\x0c\x46\x3a\x61\x09\xa1\x94\x1a\x3b\xf7\xf2\xd8\x18\xb9\xfd\x66\xb6\x5b\x59\x83\x96\x44\x91\xc0\x60\x3e\x87\x8f\x1d\xaf\xde\xa6\x6b\x25\xa3\xa7\x8e\x62\x90\x4e\x2b\xf6\x88\xa2\xb6\x03\xd2\xed\xe1\xe8\x66\xe3\x90\x6d\x48\x7a\x9f\x56\xe8\x5c\x8e\x05\x0d\x86\x33\xa6\x99\x55\x9c\x7a\x30\xd7\x70\x14\x50\x52\xe5\x6c\x34\xaf\x12\x49\xa1\xca\xcd\xf2\x71\x79\xbb\x9a\xaf\x66\x9b\xbf\xec\x63\xf1\x48\x62\x34\xd2\x09\x7b\xff\xe2\xef\x3d\xbc\x79\xdf\xb2\x26\x3c\x16\x48\xa8\xb9\xad\x4b\xe0\xc7\x2e\x6e\x20\xdc\xee\x34\xef\x87\x4e\x84\xef\xf6\xfb\x30\x11\xa8\x65\x2f\x2f\x02\x27\xe9\xe8\x5c\x96\x9f\x44\x23\xd2\xa3\x11\x1e\x3e\x88\x74\xa9\x77\xd5\x92\xd9\x93\x31\xf9\xb6\xec\x90\x48\xd1\x52\x57\xcd\xb3\xa2\x32\x71\x9a\xbd\x01\xad\x29\xa5\x31\x6b\xd6\x19\xb7\x24\xf4\x9a\x3b\x0e\x69\x18\xea\xf4\xd4\xe2\x2b\x2c\xcb\xd1\xf0\x1b\x70\x27\x24\xd6\x08\xe4\x37\xe5\xd9\x5d\xc1\xb3\x4d\x9f\x36\x41\x73\x87\x69\x64\x26\xb7\x7e\x5f\xd5\x78\xc1\x4b\x4c\xba\x5b\xc6\x78\xcd\x9d\x48\x90\x92\xc1\x58\x8d\xfe\x7b\xb7\x89\xbb\x01\xf5\xe3\x17\x1a\x41\x49\x19\xc9\x54\xda\x83\x4a\x63\xe3\xdc\x66\x75\x67\xff\xe4\x05\x2e\x5e\xe7\x84\xe5\xa7\x9b\xa2\x78\x6b\x8f\xb0\x08\x8f\x6c\x80\xab\x9b\x54\x64\x53\x59\xb7\xf6\x9f\xf6\x37\x9c\x52\xa2\xf4\xf0\x68\x0d\xad\x9f\xc2\x7d\x47\xf9\x16\x71\xbf\x31\x3c\xc8\xdf\x7e\x2c\xee\xf3\xc0\x85\x36\xcf\xfd\x61\x60\x54\xb6\x7d\x47\x73\x1f\x1c\x4c\xa0\x9a\x1a\x49\xdf\xb3\xe0\x41\x22\xf1\xd8\x16\xea\xdd\x67\x8f\x21\x7f\x74\x89\x40\xb3\xc4\x74\x76\x35\xae\x4f\x55\x15\x65\xe3\xfd\x7c\x9f\xa1\xe7\x58\x9f\x31\x48\x4e\x94\x4b\xbc\xf9\xfa\x26\xf7\xc9\x43\xe6\x61\x54\xbc\x3e\xf1\x0b\x7a\xc9\xfe\x92\xe2\xcc\x95\x2a\xee\xf5\xe5\x0f\x27\x3c\x67\xa1\x8b\xda\xf1\x32\x03\x5e\x52\x44\x6c\xaa\x35\xf6\xa9\x59\x12\x12\x3c\xb9\x2e\xd3\x37\x98\xf3\xac\xfd\xf6\x51\x4c\x61\x1b\xc1\x17\xb0\xaa\x33\x42\x2f\x58\x2f\xc1\xeb\x9c\xe2\xe8\x5f\xc3\x5c\xf1\xff\x7a\xff\xb2\xa7\x93\x42\x9b\x82\xd1\xf2\x13\xe4\xbc\xa8\x46\xae\x15\x8f\x1d\x97\x34\xf3\x0e\x65\x8f\x95\x44\xf3\x38\x4c\xf0\xa3\xee\x66\xf3\xdd\x6a\x3e\x7b\x98\x6f\x5e\x56\xdb\xb6\xae\xc7\x13\x4f\xa9\xe6\xf0\xbf\xb9\x7c\x3b\x15\xf5\xbc\xc8\x15\x9a\xf4\x21\xfa\x81\x27\x81\x16\xbe\x81\x17\xed\xca\x33\x82\x04\x7a\xc0\x3d\x9e\x44\xa1\xa4\x0e\x0b\x5e\x57\x7d\x91\xfe\xd1\xa7\x49\x92\x08\xf7\xe1\x41\x06\xec\xe6\x6b\xcb\x35\x0c\x32\xac\x9c\x7b\x49\x12\x5b\x64\xc4\x6a\xfe\xb4\xf7\x9c\xfd\x02\x24\x9a\xd9\x76\x8c\xef\xb8\x56\xcf\xe9\xf6\xdc\xdb\x0c\x87\xd7\xe4\x21\x60\xa6\x8c\x96\xbf\xed\x95\xb6\x0f\x30\xbd\xae\x79\x22\x84\x30\x11\xb3\x85\x53\x4d\x3f\x11\x57\x01\x33\x88\xb2\x59\xcf\xab\xa5\xa4\xd5\xf0\xa4\x82\x11\x7e\x68\x6f\x4b\x73\x88\x93\x30\x86\x06\x35\xd7\xae\x7b\xaf\x5c\x48\x17\x29\xf6\x9a\xa0\xea\xb6\xe4\x72\x0e\x69\xd6\x6b\x32\xba\xb2\xa4\xa5\x6b\x88\xdc\xe0\xc3\x30\x17\x14\x45\xf6\xb7\x9a\x67\x9b\xdf\x2a\x9f\x4a\xc6\x8d\x4d\xfa\xba\xbd\x78\x1e\x29\x03\xf4\xee\x0c\xf7\xe2\x5d\xf1\xde\x6c\x20\x3d\xc6\xca\xff\x19\x8f\x17\x20\xba\xf6\xee\xe7\xb2\x38\x95\x69\x31\x3a\xa9\xf2\x49\x0e\x42\x9c\x4b\xec\x6d\xff\x3e\xe9\xcc\x21\xa0\x5a\xcd\x71\xbf\xdc\xdd\xa3\x6f\xdc\x58\x2e\x4c\x3f\xb5\x73\x09\x84\xb0\x1c\x25\x37\x50\xd7\x50\x56\xd8\xcc\xd3\x27\x51\xd4\x1c\x74\x80\x40\xe3\x99\x90\x03\xc3\x06\x9a\x1a\xdd\x0e\x50\xdf\x95\x3c\xaf\x01\x88\xc2\xcd\x1c\xd6\x6e\x9c\xe0\xc4\xe7\xef\x2d\xb2\x99\x4a\x61\x53\x06\x47\x27\x3c\xf1\x2d\xc7\x11\x29\x2a\xb4\x27\x12\xae\x6b\xd8\x53\xf7\x27\xec\x74\xd8\x8b\xaf\x7d\xb3\x11\xef\x89\xef\x6a\xf2\xf9\x85\x13\x05\x31\x39\xa3\x8d\xc7\x02\xbf\x40\xf4\x39\x4d\xcc\x20\xd7\xa7\x64\xc0\xa9\x84\x54\x16\x46\x81\xdc\x1e\x8b\x48\x6d\xa4\x31\x53\x4f\xf9\xae\xe4\xaa\x07\x4a\x13\xae\xf0\x28\x60\x4c\x0f\xa3\x30\x50\x78\x9e\x69\x01\x9b\x3f\xed\xb7\x7f\x6d\x77\xcb\xf5\xa0\x8d\x46\x78\xcc\x41\x77\x01\x77\x25\x74\xaa\x17\x90\xd5\xfc\x6a\xba\xfb\xdb\xc9\x28\xbc\x88\x61\x9b\x83\x61\xe6\x9a\x5b\x0d\x64\x7b\x98\x3b\x58\x26\x30\x55\x74\xac\xde\x8e\x4e\x20\x24\xc6\x0e\xa7\xa2\xaa\x77\x1f\x69\x3d\x08\x5b\x85\xa7\x7d\xa4\xf3\xa5\xbc\x30\xf5\x90\x5e\x12\x23\x6a\x11\x86\xcc\xc0\xba\xdf\x20\x7f\x04\x0c\x42\xb0\x78\x84\x0c\x1e\x8e\xbd\x9d\x90\x85\xb8\x32\xce\x93\x92\xb5\x76\x90\x08\x2d\x5a\xf5\x11\x3e\x6b\xdb\xfd\x35\xde\x27\x86\x3f\x62\xae\x36\xb4\x91\xd5\xe9\x3c\x62\xd2\x1c\x0d\x8d\x58\x84\x36\x59\xf3\x34\xdb\x9e\x05\x4e\xcd\x5f\xaf\x90\xcf\x1e\x88\xfe\x33\xbf\xb1\xb7\x1b\x07\xce\x40\xb6\x16\xe3\xf1\x29\x8d\x91\xee\xe4\x71\xec\xc5\x54\x34\x2f\x2b\xd8\x3c\x3c\xdf\x03\x6f\x89\x51\xcc\x90\x44\x11\xd1\xf6\xcf\xa2\x86\xed\x59\x98\x86\xc5\x41\x55\xc3\x94\x4d\x05\x17\xdc\x33\xaf\xe2\xbe\x47\x34\x39\x58\x3c\x82\x4b\x07\x03\x54\x7b\x97\x88\x38\x3c\x42\x5e\x8f\x80\xe0\x42\xc8\x44\x26\xc6\xf3\x41\xf6\x09\x5b\x2f\x1c\x4d\x09\xa1\xc0\x23\x53\xf3\xb5\x28\xf9\xc1\x06\x47\x42\x3a\x42\x9b\x64\x38\x65\x98\x5a\x05\x1e\x2d\xa4\x17\xa0\x98\xe6\xfc\xc9\x08\x1b\xb6\x07\x62\x1f\xab\x5f\xd8\x65\x31\xe7\x79\x13\xe3\xf7\x92\x05\x42\x6a\x4a\x0a\x35\x9e\x30\xf1\x45\xce\xcb\xaf\x53\xcd\xf3\xc6\x9a\xe3\x63\x0c\xae\xa3\x3c\x17\xfb\xf3\xf7\xc7\xf4\xd0\x4c\x6a\xd3\x48\x86\x30\x91\xaa\x1b\x14\x60\x24\x6a\xdf\x88\x75\xe1\xa7\xa5\xb3\x86\x0f\x0f\x42\x61\xcd\x50\x17\xc5\xe8\xb5\x68\xa6\x91\x10\x63\xb7\x79\x5c\xf4\x4d\xa1\x68\x1e\x12\x1b\x5e\x97\xbb\x5d\xa7\x18\xa2\x85\x96\x1e\x62\x8f\xc9\xae\xef\x80\x1f\x97\xbb\xfb\xc9\x84\x96\xd0\xd2\x47\xfe\xfe\xfb\xcd\x5f\xdf\x79\x66\x42\x43\xd2\x83\xfd\xed\x8f\x69\xbe\x37\x9d\x02\xa3\x7b\x05\xc1\x93\x5e\x8b\xaa\xb9\xea\xcd\x17\x12\x01\xf6\x4f\x29\x1d\xce\x15\xb1\x28\x3e\x9e\x8f\x50\xa6\xd2\xc8\x04\x0d\x06\xb9\x21\x91\xb0\xbf\x41\xd6\xb6\x35\x4a\x37\xa2\x8e\xb0\x9d\x82\x6d\x5d\x9c\x4e\xe3\x89\x24\xdd\x48\x5b\xed\x46\x83\xab\xf6\x87\xa7\xf5\xc3\x04\xb1\x91\xdb\x79\x4b\x9a\x69\x4f\xee\x6b\x17\x43\xdb\x5f\x69\xae\x8a\x0f\x72\x82\x8c\x85\x9e\xfc\x70\x32\x00\xe2\x28\xa4\xa8\xed\x42\xb0\x4a\xcb\xd0\x65\xd8\xa9\x34\x7f\x5a\xaf\x9f\x1e\xf7\x37\x2f\x8b\xbb\xe5\x6e\xc0\xae\xaf\x65\xe8\x79\xb6\x6d\xee\xf9\xe9\xe9\x81\x08\x42\xdc\x64\x78\xd7\x21\x27\x81\xa0\x7f\x14\xe7\xac\x9d\x74\x92\x39\x81\x13\xa2\x43\xf9\xf8\x63\xbf\xfb\xeb\x79\xd9\x1e\x08\x34\xda\xc6\xa2\x3c\xf0\x3c\xfd\x2f\x94\x71\x7b\x04\x62\x41\xfd\x36\xcb\x76\x57\x96\x91\x1b\xb2\xd0\xd2\xc7\x96\x6f\x50\x9f\x32\x2e\xe1\xdb\xce\x45\x19\x31\x97\x77\x21\xe8\x80\xbf\x67\x5a\xe2\xe5\xfb\x5d\x45\x46\x91\xc2\x19\x8d\x8d\x1a\xcb\xdd\xfd\x5d\xfa\xde\xd8\xfd\xc7\xa2\xac\x5f\x9f\x8b\x76\x1b\x94\xb1\xeb\x05\xaa\x95\xd0\x2c\x72\x35\x05\x64\x94\x71\xa0\xd0\xea\xff\x39\x1f\x40\x24\x65\x2c\x7d\x24\x19\xd8\xcd\x16\xcf\x4f\x0f\xcb\xfd\xcd\x6c\xbb\xdc\x6f\x96\xff\xb4\xc7\x93\x40\xf0\xa1\xc4\x61\xdf\x3f\x19\x7e\xdc\x84\x07\x6e\x2b\x8b\x40\xf9\x06\xbc\xe9\x69\x50\xb4\xe4\xbe\x40\x6f\x6a\x77\xb3\xec\xe8\x8a\xed\xb1\x90\xd8\xbe\xd3\x6a\x37\x7b\x1a\x3d\x0a\xe7\xc4\x0f\x4c\x93\xcc\x00\xca\x87\x2c\x31\x66\xa4\xf0\x1c\xe8\x1a\x5f\x36\x50\x41\xf9\x8e\x36\x60\x03\x32\x3d\xa5\x30\x46\xf4\xca\xc6\x0b\x26\xf2\x19\xfc\x62\x77\xbc\x9a\x72\x95\xa4\x0a\xa8\xb4\xb9\x4e\xf3\xb4\x09\x11\x97\x48\x61\x63\xef\x5d\x31\x07\x45\xc1\xb0\xca\x53\xc3\xdb\x4b\x9e\xbe\x43\x59\x8d\xb5\xbd\xb4\x54\x20\x38\x56\x0e\xce\xb9\xda\xa3\x6d\xb6\xa7\x00\xd7\xc3\x50\x64\x29\xcb\xb6\xd6\xf1\x77\xd1\xc0\xe6\x14\x3a\x0e\x84\x1e\x72\x77\x22\x02\xb0\xc7\x7f\xad\x95\xa3\x7d\x64\xab\x43\x62\xeb\x79\xd1\x38\x7d\x08\x00\x43\x42\xed\x87\xa2\xb8\x12\x82\x28\xcf\x8f\xd1\x14\xad\x6f\x77\x2f\xf6\x5c\xbe\x50\x58\x7b\x38\xf1\xaa\xea\x88\x84\xda\xa3\x0a\x70\xfe\x91\x40\x3d\xfa\x07\x0a\xf1\xfd\x6b\x38\x16\xe5\x17\xcd\x96\x2d\xfc\xe7\x0c\x5d\x51\x57\xf9\x5a\xe2\xe4\x14\xf5\x6b\x77\x46\x33\xbd\xcd\x90\x80\xf9\xd8\x78\xb8\xdd\xcd\x36\xbb\xf5\x72\x37\x5b\x3c\x3d\x3c\xcc\x36\xed\xe1\x88\xd9\x16\x43\xec\xd8\x5c\x55\xd5\xb9\xf5\x2f\x55\x00\xd2\x8b\xfb\x9d\xbe\xbd\x57\x13\x68\x4f\x77\x73\x87\x54\xc4\xaf\x13\x68\x68\x15\x86\x1e\x0b\xbb\x80\x63\xc2\x41\x53\x21\xa7\x1e\x9b\x3b\xa8\xe7\x59\x33\xfb\xe6\xbc\x86\x43\x61\x65\x36\xb4\x0a\x41\x22\x94\x5a\x30\x66\x2a\x3b\xb7\xe7\x5c\x59\xe5\xec\x63\xfb\xd0\x4c\x05\x8e\x68\x83\x06\xd4\x7e\x42\x22\xe0\x11\x77\x83\x4a\x82\x04\x69\xc5\xda\xe7\x1b\xa1\x7a\x55\x12\x72\x0c\x10\xc9\x66\xdd\x41\x3e\x4d\xba\xe7\xf6\xa4\x86\xb4\x4a\x22\x89\x6e\x1e\x36\x8d\x62\xf3\xaa\x3d\x1d\x8f\x5c\x46\x0c\x72\xc5\xc9\xf8\x35\x06\xea\x6e\x07\x28\xe9\xb9\x26\x59\x52\x17\xb3\xe1\x56\xa5\x38\xf8\xb6\x8d\x7b\xd4\x6d\x6a\x07\x68\x92\x5e\xc2\xe9\xba\xaf\xaf\x73\xc5\x69\x25\x7c\x60\xd2\x6a\xab\xa2\xd3\xda\xd3\x13\xb5\x63\x84\x8f\xa1\x87\x3c\x1f\x9b\xf9\x77\xaa\xc1\xbe\x6b\xbb\xa1\x28\x19\x3a\x98\x59\x3e\xa6\xf9\x68\x2b\x53\xb2\xf1\x71\xfa\xd4\x51\xdf\x3b\x35\x4a\xb1\xd0\x37\xb4\x57\xb7\x45\x59\x9f\xf3\x11\x38\x45\x29\xa0\x48\x88\x28\x26\x77\xe9\x11\x6e\x78\x65\x3b\x68\x7b\xef\x5f\x69\x6a\x68\x3b\x10\xbe\xc4\xb6\x92\xec\x47\x4f\x07\x92\x63\x0f\xd2\x62\x79\x3b\x7b\x79\xd8\xed\x77\xcb\x3f\xed\x16\xab\xb4\x1b\x92\xe0\xad\xa1\x69\xdf\x15\x76\x6f\x1b\x3e\xa3\x8e\x88\x0d\xd1\xd0\xad\x19\x0a\xde\x81\x7c\x8f\x56\x5a\x91\xd0\x29\x06\x8e\x5b\x90\x65\xfb\xbd\xc1\x09\x42\x4d\x4c\xe5\xa4\x07\x81\xe9\x8a\x56\xb8\xf3\x8f\x7e\xfb\xeb\xb7\x54\x65\x1a\x5c\xe9\x60\x2b\x69\xdd\xe7\xc8\xb8\x96\x00\xb5\x45\x2d\x68\xec\x7f\x60\x3b\x5d\x6d\x7d\xa3\xed\xbd\xb1\x83\x12\x19\x61\x21\x88\xea\xf7\x2b\xb5\x2b\xb6\xd0\x97\xaa\x33\xe3\x82\x90\x63\xa7\xe7\x06\x71\xb4\xdf\x49\x89\xfd\x3d\x13\x0d\x81\xf0\x90\x5a\xa5\xc2\x00\x64\x5b\x03\x7f\xbb\x38\xe3\xf0\x2d\x84\x86\xf9\xe6\x11\x3e\x3f\xcf\x55\x7f\x23\x07\x96\x04\x08\x8f\xc7\x3f\x0e\xf9\x33\xaf\x12\x27\x00\xe3\x01\x42\x9a\x32\x5e\x1e\x10\x2c\x51\xb4\xa7\x03\xa2\xcb\x40\x11\x5c\x7f\xbf\x7d\x79\x7e\x7e\xb0\xb5\x01\x88\xdc\x04\x37\x7a\x23\xf3\x7a\x91\x21\xed\x07\x7e\xf6\x27\x9c\xc4\x38\xc4\xb9\x2c\xd3\xba\xb8\x10\x74\xd4\x10\x73\x09\x1d\xd2\x7a\x7b\x3e\xf5\x34\x39\x86\x53\x1b\x92\x30\x70\x4d\x5e\x0b\x0d\xba\x01\xf4\x4c\x15\x98\x20\x89\xc0\xe7\x5d\x3d\x70\x96\x2b\x4c\x85\x8e\xbf\xd4\xe0\xb5\x24\x49\x88\xc5\x53\x94\x29\xd8\x42\xbd\x38\xc3\x05\x33\x43\x3b\x54\x60\x8e\x27\xcd\x2b\x28\x47\x89\x95\xd1\x49\xc1\xe5\xdd\x86\xb2\x37\x37\x70\xed\xdd\xd9\x1f\xe9\x98\x0c\x66\xcd\xcb\x9a\x48\xd4\xdb\x79\xcb\x1d\x62\x17\x2f\xe1\x1d\x78\x76\x93\x5e\x70\xa3\xfc\x0e\xad\x37\x7a\x14\xce\xe8\xab\x7e\x40\xba\x81\xff\xf4\x3a\x8e\x81\x47\xc2\xa3\x76\xba\x21\x64\xf2\xda\x89\x22\x11\x9b\x18\xd5\x0a\x4a\x8d\x3e\x20\x4f\x98\x87\xdc\x6a\x16\x2b\x55\xfd\xb3\xb6\xbb\x20\x48\x10\x88\x6d\x85\xcf\x1a\x72\xb5\x6f\xfe\x0f\xfb\xa7\x46\xf3\x45\xf9\x12\x55\x07\x9a\x10\x7e\xce\x47\x59\x5d\xb7\x1d\x15\x29\xee\x74\x90\xf4\x1b\x2e\xdf\x5e\x2a\x28\x57\xed\xb3\x29\x4e\xf0\xe2\xe7\xa7\x95\xfd\x13\x78\x4c\x82\x49\x9b\x9e\x2e\x34\x12\xcd\x3f\x83\x6f\x0b\x10\x61\xa6\xeb\xaf\x5f\x37\x83\x45\x09\xda\xc3\x28\x05\x3e\x4f\xd0\x18\x9e\x01\x1d\x85\x76\xa2\x08\xf1\x08\x94\x89\xb9\x21\xca\x8a\xa7\x13\xe4\x15\x16\xa2\x26\x93\x1b\xda\x8b\x03\xe9\x99\x2c\xf5\xb9\x86\xab\xe5\x0c\xed\x41\x82\x33\x73\xf5\xb8\xda\xad\x66\x0f\xc3\x25\xac\x7d\x06\x08\xfd\xb9\xd9\xdd\xdf\xf4\x52\xf2\x3a\xf0\x88\xae\x6f\x7e\x7f\xbb\x47\xea\xaa\xe7\xe5\x66\xdf\x4f\x26\xe8\xc0\x8b\xc2\xe8\xfa\x82\xfa\x16\x8b\x63\x4f\xa1\x3d\x14\xaf\x36\x05\xde\xe2\xbd\x89\x5d\x6d\x49\xd3\x65\xe3\x2d\x60\xf4\x60\xa1\x23\x30\xfe\x26\xf6\x11\x62\x5d\x18\xa0\x6e\xc7\xe3\x13\x65\xb5\x64\x97\xf5\x2b\xae\x23\x6c\xc4\x33\xe4\x48\xed\x28\x40\x5a\xa4\x63\x9a\xa7\xf9\x61\x95\xcb\x66\xe2\xbe\xc3\xc0\xdb\xd4\x21\x38\x8e\x81\x76\xa2\x00\x99\x9c\x26\x8c\xd0\x21\x10\xc0\x9b\x97\xc7\xaf\x1d\xcf\xdf\xa6\xda\xe8\x35\x93\x21\xe6\x2f\x17\xcb\x9f\xcb\x87\xa7\xe7\x75\xf3\xb6\x6f\x5f\x1e\x17\x7b\xa4\xfd\xd9\xad\xd6\xcb\xed\xf3\xac\x7d\xed\x4c\x03\x66\x27\x4e\xcd\x93\xf6\x27\x99\x8e\x98\xcb\x7c\x1b\xa2\x95\xc6\x41\xb5\x0b\x40\x47\x3c\x76\x4d\x1c\x30\x7b\x3f\x50\xdb\x1f\x85\x36\xfd\x9c\x8e\x4e\x3c\x1f\x3b\x67\x0a\xa3\xf0\xb4\x27\x72\xc8\xc9\x3c\xc8\xff\x06\xff\xb2\xbf\x8a\x95\x85\x55\x23\x0c\xa1\x5f\x47\x1d\x3e\x6c\x22\x1c\x9f\xea\xd1\xf2\x6d\x81\x90\xbc\xcb\x92\x9f\x1d\xaa\x1d\x0c\x2e\x6c\x51\xf4\xb1\x38\xa6\xa8\xa7\x78\xcf\xdf\xdf\x21\xaf\x66\xf5\xf5\x4e\x0c\xcd\x63\x37\xec\xf2\xf8\xf7\xc5\xb9\x82\x3d\xcf\xd5\x1e\xb7\x92\xfd\x05\x61\xf5\xd0\xdc\x6a\xe1\x84\x01\x5c\xc4\xfd\xa3\xf6\x61\x3b\x36\x66\xbe\x6b\x31\xff\xd8\x14\xd7\x78\x63\x3a\xcd\xe0\x65\xb3\x1a\xfa\x51\x5a\x24\x80\x05\x30\x5a\xe9\x77\xbc\x79\x9a\x3f\xf9\xb9\xec\x6f\x83\xa3\x07\x11\x9a\xf4\x2b\x4e\xbc\x71\xf1\x88\xb2\x62\x38\x42\x46\x02\x83\x37\x9d\x96\x55\x8b\xbf\x1c\x7c\x54\xc5\x5d\x30\x99\x94\x9b\x8c\xcb\x37\x9d\xf1\xae\x28\xd3\x6d\xce\x5a\xf1\x04\x93\x64\x1f\x6d\x4f\x61\x4f\x8d\x6d\x78\x51\xc5\x39\x62\x50\x6f\x06\xe9\x37\xad\x23\x81\x35\x38\x6a\x4b\xc1\x16\xbc\x91\x73\x60\x07\x72\x8e\x88\xc9\x1f\x69\x7e\x50\xc5\xb1\xfd\xbd\xf0\x75\xcf\xa7\x45\x9c\xaf\x79\xab\x38\x99\x86\xaf\x5e\x83\xa3\x08\x4a\xdb\x04\x17\xb3\xb2\x4c\xdf\x79\x36\x31\xe9\x34\x40\xe2\xb5\x1d\x1f\xcd\xb4\x87\x5c\x7e\x0d\x14\x5a\x9b\x91\xbe\xe3\x38\x11\x10\x4f\xe3\x81\x20\x73\x9d\x48\x5c\x73\x30\x16\x98\x21\x3b\x9d\xb3\xcc\x12\x59\x3c\x1b\xe4\x62\xef\x82\xbe\xe3\xb8\x5e\x82\x5b\x32\xba\xc2\x3b\xe0\x47\xe2\xa9\xa7\xcc\xd9\xd3\xfb\x34\x8e\xb4\xf9\x5d\xec\x91\x10\x0c\xcf\xc0\x9d\x5a\x16\xbe\xe3\x78\xae\x40\x37\x7b\x7b\x16\x8b\xf4\x7d\x74\x61\x2f\x70\x90\x82\x62\x3d\xfb\x73\xbf\x59\xde\xbd\xd8\x10\xd8\x77\x1c\xdf\x49\xb4\xd3\x31\xd7\x3f\xf3\x2f\xc1\xe5\xdb\x98\xb4\xd4\x77\x9c\xc0\x57\x38\xf9\x51\xcc\x72\x57\x4c\xf3\xee\x8e\x6e\x2a\x00\x8e\xb3\x74\xf9\xb4\x5d\x6c\x66\x6b\x7b\x4d\x16\x09\xc3\x32\x5e\x1b\x29\x49\x0c\xdd\x07\x24\x07\xcd\x30\x6d\x88\xf7\x8a\xc6\xcd\xca\xd5\x22\xd5\x1a\x4a\xc8\x29\xa4\xbd\x86\xcc\xf4\x1d\x27\xf2\x43\x4c\x0f\x59\x64\x66\xaf\x5b\xf4\x6a\xab\xc2\xf0\x8d\x47\x01\xa9\xa1\x18\xaa\x38\x2b\xa8\xa2\xec\x13\x24\x5e\x9f\x8f\xb9\xf1\x31\x7e\x41\x7a\x78\xad\xfb\xbc\x5a\xdd\x6b\x48\x7c\x22\x3f\xde\xe3\x03\x37\xee\x58\x75\x55\xe6\xb3\x19\xce\x29\x57\x90\x56\x1b\x38\x8c\x66\x62\x22\x24\x76\xd6\x63\x8c\xdb\x4c\x1f\x4c\xff\xe7\xf6\xbe\xb8\xcb\x23\x92\xf8\xfe\x6c\xd6\x29\xe5\x89\xb1\xc0\x3c\xb4\xd4\x58\x73\xe9\x7c\x94\xe6\x97\x1e\x15\x83\x25\xcf\xf7\x07\x18\xe9\x17\xba\x9e\x1d\x15\xb8\x6e\x2b\x89\x20\x8b\x52\x5d\xa1\x76\x6b\x86\x0a\x85\x75\xad\xe3\x3e\x3f\x1f\x09\x64\x54\xb5\xb7\x29\x29\xf3\x46\xbb\x55\xda\x44\x98\x58\x25\xe8\x72\x42\xbe\xe3\x88\x30\x51\x36\x3a\x1c\x42\x6b\x87\x2a\x4f\xcd\xa3\xf4\x66\x8d\xe0\x0e\xee\xe7\xa7\x12\xde\x77\x1f\x40\xd2\x5d\xed\x39\x79\x8c\xa2\x4c\x7b\x05\xb2\x50\xed\x9f\xa5\xe7\x25\x1d\xc0\x76\xcd\x3f\xdb\xa4\xca\x78\x63\x6e\x06\xfb\x4e\xe2\x5a\xb6\x80\x83\x55\x51\xa7\x8d\x7e\xa2\x74\xd0\xfc\x22\x72\x70\x0b\xde\x8a\xce\x2a\x36\x7f\x96\x7e\x44\x62\x02\x5f\xdb\xe2\x08\x7d\x26\xe3\x81\x30\xbe\xef\x38\x2a\x24\x21\x4a\x5b\x2e\x31\xf9\x1f\xf7\x3a\x21\x7e\xf3\xa3\x04\xb0\xdf\x2e\x95\x45\x63\x5c\x7c\x7b\x5d\x08\xa8\xc9\xb0\x82\xfa\x98\xe6\xa7\x71\x47\x52\x33\x22\x12\x58\x5e\xc2\xbd\xc3\x00\xd7\x2b\x54\x22\x54\xa0\x16\xe7\xc1\x77\x72\x9d\x30\xc6\x9a\xd5\xe2\x65\x43\x6a\xb8\x46\xcd\xb7\x3d\xce\x48\x25\x5d\xf2\x4c\xbe\xc1\xb0\xba\xd9\x1c\x16\x44\x6c\x40\x50\x95\xf4\xbf\xff\x45\xee\x74\xfb\x7d\xbd\x7f\xd9\x61\x9a\x32\xd1\x04\x3f\xaa\x76\xc5\x0d\x46\x1b\x69\x0f\xb5\x3a\x7c\x7c\xd7\x15\xe4\x0a\x13\xe6\x67\xb6\xd9\x3d\x5c\x19\xe8\x05\x3e\x16\xc6\x4c\xa3\xe1\x43\x21\x87\xdf\xcf\xf5\x82\x04\x4c\x91\xc4\x80\x4b\x7e\x41\xba\x9e\x8f\x1e\xc4\xe7\x0a\xd5\x0a\x36\x58\x4a\xea\x7d\x68\xd7\x97\x80\x2d\x20\x06\xcf\x3e\x38\x16\x38\xd4\x7a\x26\xce\x65\xbe\x92\x45\x2f\xf7\xe0\x3b\x6e\xe8\x27\x08\x8f\x27\xee\xfc\xcd\xe5\x96\xd9\x8c\x09\xb5\x65\xad\xfb\xef\xe4\xf4\x73\x43\x4e\x1a\x1e\x98\xe6\xd8\xa6\x87\x9c\xd7\xe7\x12\xda\x8b\x30\x1e\xf8\x66\x73\x5d\x1d\xf9\x01\x6e\xb2\x73\x59\x82\x9a\x8d\x2f\xc4\xc0\x75\xe2\x36\xb1\x7e\xc7\x8f\xb0\xe6\xf2\x35\xcd\x61\x74\xb9\x48\x83\x67\x1a\x2d\xb2\xd9\xf3\xea\x27\x94\x55\x6f\xb6\xc4\x9e\x13\x6a\x4b\xec\xd1\xc2\xf5\xec\x41\x9f\x23\x0e\xf6\x0e\x8e\x55\x5d\xe4\xc3\xb7\x18\x07\xcc\x37\x70\x86\x75\x8a\x8c\xae\xc3\xeb\xc6\x61\x84\x11\x1f\x51\x00\xf1\xe3\x29\x83\xbb\xf6\xb7\xb1\x46\x4a\x86\x9b\xc6\x64\x0e\xd2\x9c\xcd\x41\x49\xc2\x4b\x8d\x9b\x7a\x16\x08\x36\x31\xed\x4c\x13\xe9\x6d\xdf\x71\x93\x24\xc2\xad\xb6\x09\xb7\x0d\xab\xdb\xdf\x40\x02\xf8\x8e\xcb\x13\x41\x2d\xa6\x28\xd8\xd9\x6a\xc7\xff\x26\x15\xe4\x3b\xae\x48\x48\x2f\xad\xf1\xd2\x6f\x2a\xab\xf8\xe4\x3b\xae\x0c\x3c\x15\x59\xbd\xd8\x0d\x62\x1b\xe5\xe2\xdc\x98\x75\x2b\x84\xd5\x0c\x12\x12\xbd\x2f\x4c\x82\xaf\x1e\xef\xf6\x9b\xd5\xbc\x5d\x9d\x52\x33\x0c\x6c\xa8\x85\xbc\xa2\xde\x38\x7b\x50\x85\x9e\x93\x18\xe4\xec\x81\xd7\xd0\x7c\xd2\x7d\x05\x99\x56\x96\x43\x66\xf8\x66\x54\x08\x68\xb2\x4d\x12\x83\xa8\xd2\x2e\xa2\xf3\x66\xa0\x72\x90\x4c\x02\xa5\xf8\xbd\xfd\x7c\xf6\xdc\x5e\x52\x93\x6c\x9e\x81\xf7\x5e\x59\xb2\xc0\x13\xec\xd3\x20\xe2\x14\x74\x04\x17\xbc\x06\xb7\xe5\x95\x6a\xc6\x48\x8d\x51\xb7\x39\x13\xc9\x69\x95\xc5\x04\xc9\x82\xef\xb8\xda\x09\x58\xd0\xb5\xa3\x2d\xeb\x57\xfc\x3e\xd6\x66\xba\xda\x53\xbc\x65\xcd\x3d\x50\x0d\xa4\x6d\x2f\xb6\x63\x12\x1f\x06\xcd\x9a\xad\x2a\xda\xf0\xe6\xb5\x50\xd0\x72\x58\xff\x42\x12\x4d\xe8\xa4\xfe\xdb\x97\xaf\x95\xb0\xe2\xea\x44\x34\x54\xfd\xd1\x62\x95\xed\xc6\xe0\x39\x46\xa2\xb7\x42\x12\xa8\xfd\xa9\xf5\xef\x9b\x63\xdc\x8d\x2d\x9f\x25\xcf\x60\x89\xec\xcd\xaa\xe7\x61\x79\x0e\xf0\x98\x6a\x65\x75\x99\xc2\x3b\x0c\xfa\x88\x7d\xc7\x73\xc3\x10\x11\x44\xf3\xfb\x59\x7f\x29\x7a\x9e\x2f\x5d\xa3\xe6\xb9\x3f\x91\xfa\xd6\xf0\x19\x3d\x8f\xb9\x68\x73\xe6\xf3\x3f\xbb\xea\xdd\xa4\xaf\xe5\x79\x31\xc7\x93\xfd\x55\x9c\x67\x25\x6c\x52\xf9\x3a\xb8\x96\xef\x44\x89\x01\x58\x60\xd3\xf4\xec\x66\x75\xdf\x4a\x02\xb7\xef\xc1\x77\x81\x93\xd1\xc9\x37\x90\x17\xe7\xfc\xff\xe7\xec\x4f\xb6\x1b\xc7\xb1\xed\x71\xf8\x75\x72\x70\x07\x04\xc0\x06\x1c\xca\xb2\x1c\xa1\x1b\x6e\x54\x92\x1c\x91\x59\x77\xd5\xd2\x42\x73\x60\xb3\x4c\x91\xfa\x48\xca\x61\xd5\xd3\x7f\x8b\x07\x00\x3b\xd1\xce\xfa\xff\x6a\x90\x8e\x12\xc0\x1e\xcd\x69\xf6\xd9\xbb\x7f\x0d\x8c\x2a\xe9\xe4\x39\x77\x00\xf9\x64\xb9\xa2\x2c\x0e\x6d\xe1\x1d\x2e\x6b\x78\x69\x44\x4b\x4d\xbb\xf1\x18\x19\x8f\x17\xf7\xf7\x4f\xcb\xc3\xe3\xea\xd7\xe1\x79\xb7\x72\x84\xc8\x6d\xb3\x0e\x90\x4a\x7d\xd5\xbc\xd6\x4d\xd6\x39\x07\x34\x4a\x52\xe5\x12\xa4\xbf\x44\x95\x97\x95\x5e\xbe\x62\x28\x75\xf0\x9d\xa2\xc4\x4a\x15\xbd\x40\xd3\x69\xdc\x4e\xae\x1e\x0b\x82\xa9\xa8\xfb\xa7\x6f\x07\x2f\x40\xb1\xfa\xb8\xc6\x30\x77\xdd\x41\x1b\x8f\x2d\x38\xdd\x64\x5a\xf7\xc6\x17\xe5\xdc\x78\x02\xab\xbb\x2c\x9f\x92\x4d\x5e\x47\x3c\xdb\x43\x52\xe5\x4b\x99\x3d\x4d\xc4\xf8\xfe\x52\x16\x04\x16\xe5\xfe\xd1\xec\xc0\x0a\x09\x4c\xbb\xa4\x21\x8e\xb5\x53\x3b\xaf\x0e\xf4\x20\x3b\x0d\xdc\xb6\x51\x0a\xc4\x48\xf9\x82\x0a\x1b\xb2\xfd\xca\xba\xa1\x22\x24\x81\x55\x4f\x54\xe2\x32\x5f\x90\x73\x15\x65\x1a\xdf\x91\x48\x8c\x71\xe1\x89\x5b\x14\xa4\x99\x8c\x29\xa9\x14\x86\xb2\xac\xc9\xd1\x73\xcc\xb7\x4d\x5a\x50\x2f\x37\x0d\xf9\x35\x08\x78\x7c\x21\x15\xc6\x58\xc5\xe0\x5d\xd6\xf6\xb1\xee\xca\xaa\xf5\x00\x7d\x35\xcf\xc6\x0a\x82\x77\x2f\x44\x33\x1b\x63\x46\x0b\x0c\xd5\xdc\x00\x03\x69\x52\x4c\xd7\x52\xaa\x0d\x60\x3d\xaf\xea\x88\xf3\x37\xdd\x8e\x4a\x41\x5a\x09\xa5\x0e\x1f\xe5\xe3\xb6\x2c\xa0\x86\xd9\x88\x6e\xe7\x52\x7f\xf2\xa6\x4d\xc8\xfc\x80\xb1\xac\xc0\x8e\x6e\x1d\x1e\xa0\x79\x2d\x75\x9f\x53\x64\x01\x23\x84\x23\xf8\x75\x71\x4d\x89\xc5\x02\x46\x29\x8b\x4d\x9f\x05\x5d\x14\xfa\x27\x5c\x03\x6e\xbf\xde\x0c\x19\xa5\x96\xf8\xfd\x37\x64\x77\x65\xf5\xa0\xfc\xb3\x32\xca\x22\x24\x2b\x39\x68\xc8\xaf\xa8\x72\xda\xf6\x90\x21\x6f\x15\x96\xe2\x39\xf8\xee\x5a\xb7\x7e\xd2\x06\x19\x95\x86\x43\x9e\xd1\xd0\xd6\x2c\xde\x9e\x1b\xf5\xea\x4c\xe0\x7d\x79\x73\xbe\x7c\xe6\x49\xfa\xe3\x62\x85\xd6\xee\xc9\xa7\x28\x27\x37\x6f\x52\xc7\x18\x65\x4b\xf3\x5c\xf6\xf1\x61\x6a\xcd\x30\x46\x05\xd2\x63\x6e\xa8\x7f\x3c\x66\x42\x0c\x42\x9c\x44\xdd\x3c\x15\x80\xd5\x96\xae\x29\x4c\xac\xf4\x5f\xb7\xc3\x2f\x17\x7b\xdf\x16\xc7\xda\x1b\x5c\x88\xee\xac\x87\x03\x99\xc5\x3a\xc1\x89\x77\xcc\x0a\x1f\xf3\xfb\xf6\xdb\x15\x68\xb1\x80\x25\x61\x80\x49\xad\x4e\x13\x71\xd1\x0c\xa7\xf6\xe4\xcb\x24\x3c\x20\xd0\x69\x8e\x3d\x3a\x39\xd0\xb6\x41\x01\x16\x72\xbf\x15\xe5\xef\x62\x5b\xe6\x88\xfd\xa9\xe7\xaa\x8f\xda\xce\x60\x81\xf6\x3a\xab\xe5\xb9\xaa\xa1\x23\x07\x9d\xbc\x4a\x4e\x8c\x7f\x30\x5b\xf4\x92\x29\x91\x0f\x14\x48\xce\x5d\x0d\x50\xdb\x39\x55\x48\xd6\x88\xc5\x7d\x04\x93\xa6\xbb\x06\x4e\x7e\xbe\xb1\x54\x12\x05\x9d\xe5\xb2\xda\x7f\x77\xb5\xf9\x53\x7d\xd2\xb6\x2b\xc4\x18\x8c\x5a\x7e\x5f\x6c\xd7\xfb\xbf\xfc\x19\x04\x65\x89\x2b\x0d\xbe\xdd\x6d\x26\xc7\x08\x66\x79\x53\x11\x68\xf0\x7b\xf2\x20\x82\x73\xe4\x98\x54\x65\xf1\x0e\x95\x0d\x5f\x4e\x73\x32\x23\xc2\x2c\x77\x9c\x0c\x62\xf4\x5a\xad\x2c\xc3\xea\x08\x15\x06\xb0\x7e\xf5\xfa\x2f\xfe\xde\x64\xa4\x99\x95\xce\x5b\x17\xcd\x78\x9c\x4b\x4e\x30\x62\xf7\x50\xca\x2c\xcf\x8a\xb7\xe1\xde\xcb\x64\xca\xb0\x1a\x73\x07\xcd\x7d\xf9\x82\xbb\xc5\xf8\xb9\x24\x98\x24\xec\x4a\xab\x16\x79\xfe\x00\x75\x2d\x5e\x60\xb2\x3f\x30\x45\xa3\xd8\x79\x40\x5b\xf1\x06\x6b\xa7\xfb\xfb\xc9\x38\xd2\x01\xc7\x89\x9a\x67\xc7\xac\xb9\x2b\x2b\xac\x57\xcd\xb3\xba\x59\x8f\x17\x1b\x48\x42\x6d\x97\x13\xab\x42\x54\x76\x13\x02\x74\xc2\x44\x47\xe5\x9d\xe7\x9f\x32\x29\xfa\x98\x11\x03\x48\xb9\xa5\x45\x75\x85\x12\xb7\x50\x0d\x62\x53\x93\xe7\x31\x91\xc1\x69\x7c\xbf\xfa\xb6\x7a\xbc\xf5\x57\x35\x86\x60\x51\xc6\x5f\xb7\xfb\xa5\xfb\x2d\x0c\xe2\x90\xda\x59\x7b\xf9\x5f\x5b\xa8\xe0\x5b\x08\x11\x68\x03\x23\x71\xa1\xd6\xdf\x44\xd6\x39\x7e\x21\x91\x82\x76\x34\x74\x15\x28\x31\x22\xd1\x77\x9d\xa8\x24\x89\x83\x76\x3d\x1f\xdf\x84\xb7\x1c\x86\x9f\x37\x64\x84\xe3\xa2\x01\x3a\x6b\x3a\xc7\x7d\xf4\xb6\x43\xa6\x2c\x3d\x24\x56\xa8\x15\x6f\x43\xf7\x7b\xf4\xb6\xfa\xe4\xd6\x4c\x84\x22\x0c\x59\x80\x4c\xfe\x27\x28\xce\x79\x93\x1d\x05\x26\x9f\x6c\x68\xb3\x97\x35\x75\x9d\x23\x41\x91\x4d\x64\x57\xaa\x0c\xfa\xd4\xec\xf8\xf1\x22\x21\x70\x7b\x76\x34\x1c\xee\xd7\x98\xc7\xb8\x22\xb9\x0d\x66\x87\x6e\xc8\x64\xb8\x85\xb1\x01\x04\xe5\xfe\x79\xce\x87\xe3\x39\x4c\x98\xa2\xa6\xdb\xb6\x31\xe7\xf6\x28\xfa\xdb\x4a\x03\xc0\xc8\xce\xa9\x2a\x91\x47\xd2\x2f\xe1\xa3\xf5\x29\x14\x61\xe4\x39\x00\xde\x45\x7e\xee\x1c\xe9\x50\xf0\x44\x26\x1d\x21\x7b\xf1\xad\x2a\xcf\xa7\xc9\xbb\x16\x32\x41\x6e\xa3\x5b\x90\x4e\x98\xc4\x91\xb6\x7d\x01\x0e\x61\x41\x28\x85\xc2\x7d\xd3\x9c\x0b\x75\x08\x16\xb1\xf7\xde\x42\x15\xa7\x18\x87\x3c\x9c\x84\x7a\x5b\x37\x70\xc4\x94\xc1\xfc\x49\x94\x64\xda\x4b\x2f\x57\xe7\x7a\xee\xaa\xbd\x6b\x10\xea\x28\xc0\x0c\xbf\xd0\xf8\xf9\x46\xe7\xe4\x83\xff\x76\xac\x4a\xd3\xff\xf6\x17\x46\x1c\x11\x9a\x3f\xad\xc7\xbc\x29\x67\xd2\x81\x9f\xed\xfc\xc3\x1b\xd2\x09\xba\x43\xeb\x1a\xd5\x90\xba\x8f\xa6\x35\x60\x9a\x14\xda\xcd\x6d\x07\xcd\x58\xef\xfe\x93\x17\xaa\x21\x09\x11\xa1\xb6\xd8\xfe\x58\xed\x5b\xff\x13\x33\x99\xdb\xa7\xe7\x6e\x36\x87\xda\xd8\x2a\xb4\x43\x59\x58\xb3\xe7\x4e\x64\xf9\x98\x5f\x8f\x05\x21\x84\xdc\x95\xdb\xbc\xb4\x36\x54\x56\xbc\x74\x90\xed\x2f\x63\xe3\xa1\x61\xa1\x25\xc3\x3b\xe5\x59\x73\x93\xe9\xc9\x48\x31\x91\xf5\x90\x8f\x97\xe7\x1a\xaa\x6b\xd0\x66\xdb\x85\xdb\x9a\xe2\xba\x63\x20\x1e\x45\x8f\xa2\x20\x88\xad\xb0\x97\xd6\x2b\x51\xe5\x97\x9b\xac\x9a\x45\xe6\xb6\x5d\x29\x8d\x1d\x71\xfe\x90\x15\xfa\x13\x05\xd7\xf6\x80\x24\x8c\x1c\xa3\x7f\xfb\xb0\x37\x03\x63\x3e\x0a\x92\x08\x69\xd6\x1f\xcb\xea\x28\xf2\xec\x3f\xb0\x45\xed\x16\xdf\x9a\x86\xe8\xe0\x67\x75\x3b\x66\xdb\xbd\x42\xe4\x30\x28\xec\xc0\x2e\x12\x81\x69\x18\xe4\x1e\x32\xb9\xb4\x6d\x4a\x88\x11\x8d\x07\xaa\x00\xda\x8f\xe2\xd0\x41\x91\xef\x6a\xac\x6d\x33\x20\xca\xaf\x7d\x45\xd4\xf8\xf1\xa9\x4c\xa2\xc1\xee\x5f\x5c\x91\x03\xb1\x20\x62\x02\xb4\x8d\xc5\x9d\x6e\xcb\xb3\xcc\x87\xc4\x3d\xfe\xe6\x42\x95\xa4\xa2\xb3\xb6\xcb\xca\x1b\x40\x51\xc2\x34\xc2\x08\xc4\x59\x67\xcd\xb7\xf3\x10\xd9\x31\x82\xdf\xcc\x6c\xf3\x51\xc2\x2d\xa0\xb5\x5d\x9f\x3d\x05\xa8\x5f\x99\xfc\xd7\x1c\xae\xf9\x51\xa2\xad\xa2\x56\x05\x75\xa6\xcf\x22\xb7\x51\xec\x4d\x55\x1e\xb3\x3c\xef\x5e\x24\x4f\x62\x61\x43\x47\x08\x7d\xc4\xf4\x93\x6b\x4a\x59\x2a\x03\x9f\x9f\x51\x90\x9d\x2c\xd9\xc3\xbc\xff\x1e\xa5\x69\x82\xd9\x1c\x84\xdb\xec\x84\x99\xcd\xbd\x62\x3f\x89\x17\xdc\x3d\xed\x6e\x9e\xf6\xfb\xa7\x87\xee\x72\xa9\x51\x91\x33\x1b\xdf\xa1\xba\x4e\x2c\xb6\x7d\x84\x42\xfc\xd2\x24\xde\x36\xbe\x13\x11\x27\x82\x77\xe1\xd2\xfb\xac\x9e\x6a\x59\xb5\x7d\x12\x5b\xc9\x86\x94\xe2\xc8\xbd\x8d\xf6\xf0\xcd\xe5\xe6\x7c\xb9\x5e\x36\xfc\x41\x69\x8a\xc4\xf1\x3f\xe0\x58\x16\xa5\xf2\x80\x08\x16\x44\xd2\xe9\x5f\x59\x95\xe1\x73\xf5\x29\x91\xfa\xe7\xf0\xb5\xf6\x2c\xca\xe0\x9c\xc0\x75\x39\x87\xba\x1e\x50\x40\x1e\x36\x55\xd9\x80\xfd\xa7\x45\x70\x77\x53\x49\xc7\x96\xfb\xb3\x6e\xca\x53\xbb\xf8\x6c\x45\x56\xfb\x12\x4f\x16\x44\xc0\x22\xcc\xdb\xc2\xcb\xcb\x30\xde\x10\x81\x00\xb4\xea\x1c\xb0\xe4\x5c\x67\x05\xd4\xf5\xe7\xfa\xd6\xed\x21\xed\x46\x63\xa9\x5e\xb2\xfa\xf5\x8f\x49\xa3\x0e\x2c\x29\x72\xf6\xee\x51\x13\xe3\x0e\x86\x24\xda\xe1\xe5\x97\xd5\x45\x57\xf3\x75\xda\x6d\x47\x05\xb8\xe5\xeb\x9e\x2c\x97\x05\x71\x40\x19\x7a\x0f\x1d\xcf\x8a\x67\xe1\xf7\x2f\x22\x26\xda\x56\xa8\x7c\x7b\x5a\x76\x3f\x81\x45\xaa\x78\x70\x37\x0e\xad\xbf\x71\xde\x62\xaa\xb4\x8d\x51\x78\x85\x27\xc7\x77\xcd\x82\x98\x05\x31\x9a\x2c\x43\x84\x32\x4a\x17\x8f\xb3\x92\x48\xc7\xde\x74\xb7\xce\x78\x22\x42\xa7\xdc\x3b\x8e\x29\xbb\x0e\x61\x10\x13\xe9\x53\xc2\x8f\x65\xb3\x3b\x8a\xaa\x99\x83\x8d\xb4\x7d\xc3\x10\xe3\x79\x8b\xdd\x72\x39\x34\x6b\xe2\x28\x05\x5b\x60\x59\x16\x70\xb9\x11\x5d\xf4\x29\x8e\x44\x94\xb8\x17\xbf\x58\xe5\xe6\x16\xde\x31\xf7\x5e\x67\x13\x53\x32\x8e\xb4\x25\xa0\xa8\xa1\xf9\x29\xaa\xcc\xa1\xbc\x4b\x29\x64\x7e\x99\xdc\x71\x92\x58\x56\xbd\x63\x27\x7f\xe8\x68\xce\x7c\x3b\x27\x8a\x8c\xaa\x85\x6c\xf4\x72\x98\x33\x8f\xb9\x34\x48\xa0\x81\xb4\x7f\x08\xd2\x9b\x0c\x85\x38\x6d\x4d\xbd\xf6\xa3\x37\x39\x88\xba\xf9\x27\x54\xe5\x1f\xa3\xfb\x10\x14\x70\xb2\xeb\xac\x76\x58\xa3\x11\x13\xd3\x68\x82\xc5\x22\x0c\x30\xc8\xa7\x21\xb7\xc8\x8d\x07\xf1\x06\x53\xb9\x9c\xc9\x60\x10\x3c\x42\x8f\xe0\x74\xb0\x13\xe5\x70\x7c\x84\xdf\x9b\xbc\x6c\xf6\xe2\xc3\xd7\x18\x8f\x5f\x8d\x90\x04\xe3\x3c\x4e\x5d\x18\x63\x2a\x73\x29\xc4\x58\x40\x84\x84\x4e\x75\x23\x0a\xbd\x28\xf4\x16\x24\x8c\xb3\xc1\xdc\x53\xb0\x74\xc0\xd7\xd9\xf5\x63\x8c\x9f\x1a\xfc\x3e\x7e\x7c\x19\x30\x5f\xa1\xe9\x62\x37\x59\x59\xac\x8a\xab\x1c\x4f\x2c\x03\x8d\x26\xc3\x0e\x1a\xe4\x5b\xd0\x9e\xae\x6a\xfe\x15\xc9\x50\x83\x33\x1b\xfe\x71\x16\x08\xe5\x6b\x57\x5d\x2b\x04\x5d\x96\xf9\x7f\x43\x3d\xce\x82\x58\x85\xd6\x84\xeb\x87\x8c\xad\xde\x07\x4b\x01\x3a\xb9\x47\x95\x50\x4c\x6b\x42\xf3\x7a\x90\x23\xe3\x20\xd6\x21\xe0\x6a\x7c\xae\xa1\xfa\x2e\x6a\xef\x09\x4f\xbc\xb7\x58\x1b\x8a\xe9\xcd\x6f\x9b\xdd\x2d\x72\xa0\x59\xb7\xc8\xdd\xdb\xec\x2d\x02\x83\xd4\x16\xcf\x3d\x6c\x16\x8f\x7f\x0d\x54\x64\x59\x90\x04\x2c\x42\xd9\x36\x79\xbe\x2c\x1e\xd6\x23\x07\x2c\x09\x94\x25\x77\x74\x98\x0f\x8b\xb4\xef\xf3\x61\x09\x09\x0c\x26\xf4\x97\xd5\x90\xc6\x72\xf6\x3d\x25\x34\x52\x08\x7d\xb4\xd5\x20\x4f\x66\x53\x9e\xd6\xc5\xa2\xb8\x6c\x72\xd1\xa0\xb5\x31\xe9\xae\x0c\x0a\x44\x1d\x2c\xbe\xba\xb5\xc4\xbc\x89\x95\xb0\x88\x05\x72\x40\xd8\x4d\xbb\x06\x65\x19\x73\xed\x1e\x6a\xb7\xdb\x9b\x8b\xa7\x21\x99\x5c\x81\x81\xb1\x22\xe8\xde\x18\xb3\x42\x54\x59\x59\x78\xe0\xa1\x1f\x82\x49\xc8\x29\x92\x85\x6d\x9e\xd6\x8f\xfb\xc3\xf6\xe9\x69\xff\xf8\x74\xbb\x3a\x6c\x9f\xba\x44\x71\x12\x2a\x35\xd0\x58\x3d\xe8\xd6\x95\x19\x8d\xe3\x24\x34\x56\x88\x67\x59\x1e\x4f\x95\x38\x8c\x89\xf2\x27\x2f\x2b\x0a\x6d\x11\x2f\xa6\x9c\xfd\x6f\xb1\x40\xf2\xc6\x87\xcb\xde\x93\x64\x75\x4d\xc6\x6e\x96\x2f\x48\xc2\xe9\x7f\x8d\x29\x60\xd5\x0a\xb2\x3e\x3d\x88\xe2\x2c\xf2\xfc\x72\xe3\x55\x1d\xba\xf3\xc6\xae\xf6\xce\x80\x7a\x5d\xe4\xf9\xee\x7c\x7c\x3c\x1f\xef\xca\x6a\x29\x0a\x8d\x34\x5a\x48\x90\xf8\x32\x19\xc9\x49\xac\x15\xbe\x3e\xe4\xf4\x79\x17\xf9\x24\xb3\x9e\xc4\x10\xa1\x55\xde\x88\xe2\xed\xe9\xec\x03\x07\x49\x62\xb4\xe9\x50\xbf\x8f\xf0\x7b\xbd\x7c\xb2\x7a\x92\xf3\x2f\x82\x6b\x19\x0f\x8b\x4f\x17\xe7\xe6\xb5\xac\x26\xa8\x5b\x16\x24\xa9\xd6\x8a\x39\x06\xfe\xe2\xe6\x7c\xf1\x97\x13\xc4\x84\x4e\x35\x5f\x1c\x6b\xac\xca\xf1\x4d\x2a\x36\xb8\x23\xfd\xbb\x94\x7f\x4f\x6c\xd3\xf6\x4f\x44\x30\xe4\x4d\x5a\x7d\xb4\x7e\xf6\x27\xf4\x12\xfe\x18\x11\x84\x5e\x72\xc1\x16\x52\x1e\x8e\x59\x71\xae\x0f\x06\xa6\xef\x53\x53\x4b\x30\x8c\x59\xb0\xd5\xb3\xc7\x38\x25\xc0\x38\xfa\x13\x59\xbd\x5e\x2e\x26\xa1\xb9\x04\x78\x4c\xc2\xaf\xe8\x2e\x3a\x56\xa0\x6e\x18\x82\x36\xc6\xe9\x42\xbb\x64\x73\x67\x56\x27\x86\x45\xd0\xbe\xad\x45\x39\xac\xc6\x6f\x1b\x62\x1a\x86\x03\x2e\x07\x9d\x89\xc9\x9d\x98\xd8\x06\xb6\x4d\x56\x68\xeb\xc5\x4e\xac\x05\xde\xde\x6d\x0f\x09\x5e\xee\x7e\xce\x80\xda\xdb\x6e\x32\x45\x91\xb0\x5d\xa9\x32\x91\x0f\x37\x5e\x4e\x38\xc1\x4d\x0d\xb3\x2f\xc4\xff\x4a\x23\xc6\x8d\xb3\xbb\x8e\x22\x1f\x28\x1b\xbb\x0e\x2c\xb2\x8c\x50\x37\xb7\xcb\x65\xf7\x9b\x08\xcd\x30\x67\xd3\xad\x21\x9c\x09\x69\x29\x57\x5b\xaf\xae\x35\x66\x3c\x6a\xc1\xbf\x41\x1e\x06\x8a\x91\x31\x2f\xb7\x8d\x84\xd8\x68\x7c\xbb\x05\xdc\x95\x15\x64\x2f\xc5\x63\xd9\xac\xdb\xaf\xe2\xcf\x1d\x02\xc3\x44\x6c\x71\xbb\xfa\xf3\x6f\x41\x5d\x5f\x26\x12\x78\x44\xad\xbc\x77\x01\xbf\xbf\x89\xe3\xa7\xb9\x78\xdf\x3b\x4d\x3b\x1c\x6d\xd3\x54\x3f\x5d\x68\x3f\x0e\xff\x67\x10\x92\xe4\x91\x4a\x71\xa7\xdd\x41\x9e\x63\x8a\xc1\xaa\xe1\x83\x57\x59\x1d\x0f\x6e\x1e\x47\x2c\x1e\xaa\x58\x6c\xe1\x28\x10\x61\xec\xc1\x40\x5d\xbf\x08\x69\x30\x17\x74\x94\x88\xe5\x71\x42\xd0\xe1\x3c\x78\x59\xac\xe7\x2a\x9b\x29\x41\x67\x01\x4f\x88\x2d\x4a\xd4\x65\x51\x76\x69\x26\xce\x83\x10\x05\x9c\x24\xf2\xec\x0e\x78\x32\xe6\xe3\x26\x9c\x27\xa9\x74\x2c\x7c\x08\xac\x2f\xa7\x70\x14\x2e\xd2\x04\x97\xc2\x83\xee\x32\xda\xe3\x61\xce\x85\x21\x08\x6f\xcb\x05\x96\x94\xb4\x2b\x00\xe8\x5b\xe1\xd7\x1b\x2e\xa9\xd1\x9d\xda\xb9\xf5\x73\x5d\x0d\xdb\x15\x21\x73\xdb\x3b\x31\x60\x79\x64\xdf\x46\x70\x11\xae\x82\x00\x2f\xa3\x9c\x11\xda\xe5\xeb\xbb\x41\xa8\xe3\x98\xb0\x8e\xf1\xbc\xb8\x42\xdb\xfa\x6f\xaa\x55\x82\x15\xc7\xb7\x59\x8d\x5c\x44\xde\x63\xfa\xa3\x6b\x57\x38\x24\x31\xdd\x8f\x24\x3f\x7d\xe8\x9d\x03\x91\x18\x72\xcc\x1b\xb5\xd6\xdd\x8f\xd4\xea\xbd\xf9\x54\x6e\x3d\xba\x73\x88\x19\xc6\x75\xf6\xd9\x8b\xf3\x86\x3f\x2f\x38\x67\x01\x37\x51\x10\x49\xa7\xcd\x34\x10\xb5\x6d\x5b\x24\x43\x0e\xc6\x6f\x95\x38\x8d\x5e\x4e\x1a\x48\xc0\x94\x73\xd5\x43\x93\x41\x4f\xd6\x3d\xd7\x95\x48\x85\x06\x8c\xc0\x1a\xb8\x05\x62\x5b\xa7\xc5\x07\x23\x40\xde\xe8\xfb\xa4\x34\x88\xb0\xe6\xda\xd5\x3d\xe3\x03\x4f\xfd\x9b\xf9\x19\x97\x52\x61\x65\xa7\xab\x4f\x98\xef\xda\x2e\x90\x30\x17\xd0\x7d\x2c\x9f\x8c\xdd\x95\xbb\xfa\xaf\x41\x9c\xba\x3f\x2b\x8b\x20\x74\x01\xbb\xc1\x04\xfd\x9b\x5b\x09\x69\x68\xc0\x6f\x42\x79\x7e\x28\x30\x7f\xe5\x1b\x99\x41\xd3\xc6\xf2\x27\xb4\x3b\x54\xb7\x70\xa6\x61\x14\x62\x85\xa9\xa3\xd3\x18\xc7\x6b\x46\xdf\x31\x8d\x52\xfb\xb5\xc0\x27\x72\xf6\xaf\xe2\xb7\x3f\x4f\x4c\x35\x96\x71\xff\xb8\x48\xcb\x9f\x96\x55\xf2\xdc\x94\xd5\xb8\x28\xbf\xed\x18\x51\x5f\xce\xb0\x29\xcb\x1c\x79\xea\x7d\x5b\xe2\xd8\x56\x6b\x91\x43\x4f\xa7\xd6\x36\x18\x8b\x33\x93\x79\xe9\x77\x8a\x94\x53\x1e\x45\x5e\x11\x45\xe6\x59\xfd\x8a\xb0\xa8\xb7\xd9\xca\x93\xb6\x7f\x6c\x7d\x81\x06\xe1\x9c\x96\x64\xd9\x55\x5f\x77\xa7\xd4\x8c\x89\x0e\x6b\x34\x49\x79\xa7\x69\x18\x59\xae\x3f\xcb\x80\xe8\xf8\x25\xc7\x17\x49\x63\x9e\xba\x94\xbc\x82\x9b\x69\x44\x34\x15\x32\x01\x5f\x5a\x84\x29\xf5\x4c\x65\xa7\x4f\x51\x44\xa9\x0c\x6d\x8c\xbb\x53\x72\x72\x2e\xba\x6f\x76\xa8\x6f\x9b\xdc\xb2\xbb\xd2\xe4\x7e\xa4\x20\xb8\x34\x9c\x4f\x2f\x95\xd0\xb0\xcc\x45\x3d\xbd\x65\x45\x6c\x14\x72\x53\x95\xf5\x09\x99\x1d\xeb\x27\x99\x67\x36\x49\x39\x9a\x94\x8a\x91\x48\x3b\x6b\x7a\xdf\x11\x66\x8e\xbc\xeb\x54\x31\xc0\x44\xe2\xa1\xf5\x9c\xf5\xe6\xe7\xc6\x1a\x0a\x03\x25\xef\xfe\xca\x3a\x48\x71\xa4\x6f\x57\xf7\xab\xc5\x6e\x75\xb8\x5d\xec\xbd\xad\x9d\xea\xd8\x92\xd2\x08\xad\x7f\x42\x65\x29\x30\x87\x30\xe9\xb9\x01\xaa\x39\x45\x32\xcf\xf5\xf2\x09\xd5\x96\xfc\xcf\x29\x43\xca\xbb\x3f\x57\x8f\xfb\xd1\xf3\x40\x90\x60\x34\xa5\x27\xa4\xc5\x28\x75\xd6\xcf\x1c\xa0\xb6\xe8\xcd\x6a\x55\x4e\x22\x94\x29\xb0\xd8\x2b\x52\x3c\x3a\xdd\x74\x97\xf5\xe9\x4f\x10\x07\xb8\xba\x48\xd1\xa8\x57\x3f\xef\x2d\xb5\xe6\x15\x56\xb8\x3b\x84\x21\xa6\x69\x97\x1d\x4f\x28\xe9\x6a\x91\x6c\x65\xb5\xfe\x0c\x90\x9d\x9a\x24\xa4\x96\x3d\x3c\xcb\xf5\x1e\xc4\xf1\x41\x9c\x4e\x3d\x01\xc7\xec\xcb\x32\xa9\xd5\xc4\xf3\x74\xed\xa7\x4c\xdd\xba\x34\x65\x27\xd8\x4a\xa2\xb1\x61\x99\x1a\x25\xb1\x72\xe1\xa1\xdd\xcc\x3c\x9f\x51\x9f\x03\x11\x81\xa4\x68\x36\x7d\x5d\x86\x83\xe7\xf4\x91\x7a\x41\x74\x82\xe6\x7b\xdd\x4e\xf8\x57\x44\xed\xbb\x58\xdf\x90\x65\x98\x05\x82\x86\x02\x6b\x30\x1d\xf0\xce\x12\xc0\xf6\x85\x59\x2c\x10\x8c\xc4\x68\xbe\xbb\x78\x4b\x97\xc5\xf5\xcd\x91\xf2\x49\xee\x9e\x99\x83\x06\x5d\x73\xaa\x71\x78\x9f\x2a\xe4\x1b\x77\x8a\x72\x1d\x0d\x6a\xdb\x43\x81\xaf\x0c\x7c\x3c\x1f\x97\xaf\x59\x97\x9f\x17\x51\x64\x45\xa0\xea\x63\xdd\x29\x34\xf8\xb6\x38\x4d\xfd\x4a\x75\x07\x30\x20\xc5\xef\xda\x25\x42\x6c\x37\xf9\xb9\x29\x55\x25\xd4\x65\xa1\x5e\x33\x78\xef\x4b\x8c\x47\xdd\x13\x16\x21\x9f\xa6\x53\x43\xac\xca\xa3\xd3\x8b\xd1\xb3\xd8\x2c\x91\x08\xcb\xbf\xe9\x04\x7c\x30\xd5\x72\x4d\xf7\xcb\x02\xc1\x25\x45\xa0\xf4\xe3\xf3\xc3\x61\xbf\x5a\x3c\x78\xf0\x98\x48\x23\x21\x1c\x06\x73\x07\xd5\x7b\x76\x4d\xa1\x34\x2e\x2b\xfc\x9f\x81\xe1\xf9\xf5\x9f\xee\x02\x80\xfa\x10\x9d\xa9\x0e\xcd\xeb\xe4\xe6\x52\x30\x51\x1f\xa7\x28\xdf\x66\x8d\x01\x21\x18\x21\xed\xa8\xfe\xc7\xc3\x3f\x96\x7d\x14\x5c\x08\x4e\x3c\xca\xcd\x42\x69\xfc\xef\x4a\x05\x2e\x8d\xbd\xa9\xca\x7f\x83\x6a\x16\x2f\x30\x45\x05\x09\x19\x08\xe2\x10\x7e\xeb\x6e\x36\x5e\x19\xa2\x73\x9f\x4a\x0a\x85\x71\xb4\xca\x8a\x95\xc3\xc7\x27\x33\x58\x48\x13\x62\x2e\xaf\xce\x5e\x8a\x9b\x9b\xa7\xb1\x3e\xc6\x90\x1e\x9f\x05\x42\xb1\x20\xea\x2a\xf7\xdb\x53\xce\x5d\x59\x31\x1a\x3a\x1e\xe1\x3e\x42\x3a\xb9\xa8\xd2\x14\x71\xe5\x65\x61\x91\xa0\xeb\xe2\x47\x27\x2d\xda\x36\x83\x44\x57\xec\x5d\xa0\xa6\x2a\x38\x78\xf7\x06\xdd\xec\x6e\xf9\x62\xff\xba\x12\x53\x20\xe4\x5f\xe3\xb8\xdf\xf4\xba\x60\xe3\x03\x68\x8f\xd8\x12\xa3\x51\xb8\x42\x68\x42\x31\x21\xdb\xc7\x85\xee\xce\x85\x46\x6a\xe2\xea\x8a\x99\xa2\xed\xaf\x2c\x5b\x34\x6a\xc6\x74\xe9\x4d\xd7\x08\x5c\x63\xd1\xe3\x9f\x59\x61\xfa\x11\x61\x42\x22\x9d\x6d\xfd\xd3\x3e\x5f\x59\xcd\x1a\xf0\x32\x80\x00\x03\x60\xc2\x0b\x0f\xbf\x41\xd1\xa1\x61\x87\x5b\xd2\xe4\x30\x23\x44\x5f\xc9\xe7\x05\xdd\xbf\x4e\xfb\x4a\x2a\xb9\x67\x1d\x6d\x9c\x6d\xf2\x15\xc6\x50\xb2\x30\x48\x9d\xd9\xb7\xb6\xef\x6a\x28\x46\xd5\x76\x48\xc5\xc8\x7f\x9b\xf5\xc7\x25\x13\x29\xbe\xa2\xd6\x4b\xeb\x62\xe2\x75\x7d\x2a\xab\xe6\xbe\x7c\xc9\xd4\x68\xb9\x92\x61\x48\xf1\xa2\xb6\xee\xff\x66\x88\x9e\x1e\x8e\x53\x19\x91\x14\x9d\x76\xc4\x57\xdb\x0d\xd2\x6a\xeb\xf8\x4f\x23\xa3\x44\x22\x1e\xcb\x02\x18\xc7\xb1\x34\x19\xc7\x21\xe6\x06\x70\xfb\xef\xaa\x02\x9c\x62\xcc\xf0\x3a\x71\xac\xa0\x63\x81\xd9\x54\xe5\x87\xb7\x27\x65\x9c\x86\x34\x1e\x86\xff\x0e\x90\x67\x2f\x99\xcc\xc1\xb2\x6f\x74\xe1\xd9\xf9\xb7\x9b\x50\x4a\x8d\xfb\x1a\x83\x9c\x9a\x4c\x22\x82\x51\xdc\x2a\x7b\x87\xe6\x3f\x0e\x34\x39\x19\x35\x9c\x32\x74\x60\xce\x35\x54\xdf\xaa\xf2\x77\xf3\x3a\xde\xcd\x24\x37\x1c\x77\x9b\xef\xbb\x1b\xff\x53\x2a\x0c\x62\x13\xfd\xc7\x72\xf9\x7a\xdf\x2c\x82\x10\x17\x2b\x2c\x67\x7e\x7a\x58\x2f\xff\xec\x5a\x9c\xf1\x0d\x99\x2e\x4b\x27\xac\xe1\x9a\x64\x12\x62\x5c\xf8\x80\x16\x88\x45\x26\xb4\xbe\xe1\xb3\x35\x08\xff\x98\x71\x90\xfc\x91\xd2\xb2\x52\x67\x6e\xc9\xeb\xe4\x4a\x59\x20\x35\xb5\xdc\x60\x0f\xa2\xae\xb3\x77\xc8\x2f\x18\x91\xb1\xc2\x8f\x4f\x45\x9e\x15\xf0\x33\xd3\x50\x7e\x1b\x78\x21\x52\x33\x00\xe9\x29\x30\x7c\xf8\x60\x34\x8f\xa5\x8e\x6d\x4e\xec\x28\xaa\x97\xac\xc0\xba\xec\x59\x5b\x5e\x6a\xcd\xbc\x94\xc8\xa6\xac\xeb\xf6\x8b\xfe\xca\x8a\x71\x2a\x63\x7a\x88\xa1\x28\xd9\xb6\x2d\x65\x56\x7c\x2f\xcb\x6e\x10\x42\x64\xf5\x59\x9d\x21\xf4\x9a\x55\xda\xf2\x3e\xdf\x5c\xd7\x05\x48\x43\x35\xb2\xa0\xfc\x7e\x15\x39\x8c\x33\xff\xd2\x80\xad\xb9\x5b\x19\x03\x58\x69\x05\x57\x11\x4f\xff\x72\x55\x60\x38\x16\x3c\xd6\xea\x15\xf4\x39\x87\xa1\xa4\xde\x28\x43\xe4\xfa\xd3\x94\x22\x94\x4a\x95\x85\xca\xcf\x1a\x9e\xef\x3c\x7e\x52\x51\x23\x51\x25\xef\xb9\xb6\xa1\xd3\x99\x72\x5f\x16\x28\x16\x70\xed\x09\x8c\xd6\x48\xf6\xb0\x14\x5d\xd0\x4a\xb5\x06\x4c\x60\x45\x83\x5e\xcb\x2a\xfb\x0f\x3a\xb3\x77\xe7\xdc\x64\xd7\x49\x50\xc5\x98\x46\x6b\xe0\x80\x44\x37\xd6\x81\x9a\x7d\xe7\x8a\x81\x10\x9d\x78\x96\xbf\x56\x98\x18\x2f\xfb\x81\xbb\x4e\xbb\x4f\x0f\xd3\xbf\x2a\x62\x16\xec\xd0\x99\xbe\xdf\x11\x47\xd5\x5b\xf4\x2a\x12\x36\x24\x0a\xae\x7e\x61\x5f\x7a\x0e\x99\xf9\xfb\x48\x42\x08\x3a\x75\x18\x9f\x74\xf1\x27\xe3\x22\xb4\x35\xa0\xdb\x51\xd2\x52\x71\xd3\xe1\x25\x1d\x1c\x69\xf7\x5a\x9e\x86\xe0\x54\x95\x32\x5b\xf6\xf2\x0d\xeb\xae\x1c\xb8\x79\xad\x27\x3b\x88\x4a\x93\x00\x53\x85\xa7\x76\x40\xdd\xe5\xc2\xcf\x68\x25\x02\x81\x86\xdf\xed\xea\x7e\xf5\xcd\xd6\xa6\x7d\x5f\xec\xbe\x1f\x56\xeb\x4d\x42\x7c\xb4\x52\x49\x62\xd5\xa0\x4f\xe5\x69\x60\x6b\x2b\x45\x34\xe1\x76\x5f\xba\xad\xca\xd3\xee\x55\xe8\xf2\xf7\xbe\x3f\xb9\xa2\x36\x1b\xeb\x69\xb7\x37\xc8\x7c\xda\xb5\x2a\x2b\xed\x30\x54\xf4\xff\x2e\x0a\x9d\x43\xfd\x88\x00\xd5\x77\xb0\xd3\xc9\x17\x75\xf9\xe3\x40\xca\xa8\x2b\x99\x1f\x48\x2a\xb9\x76\x9d\x06\x18\xb3\xec\xc5\x4e\x3e\x49\x62\x5e\x33\x2b\xe0\xd1\x02\xed\x34\x4b\x38\x68\x17\x1d\xcf\x47\xaa\x3f\xe5\x69\x19\xbf\x6d\xad\x08\xd2\xc6\x7e\xa8\xfc\xdc\x2e\x4e\x58\x9d\x3b\x0c\x3b\x29\xad\x54\xec\x29\xf1\xd7\xbb\xdd\xf3\xea\xf6\x70\xb7\x7d\x7a\x38\x3c\xed\xbf\xaf\xb6\x87\xe5\xf3\x76\xbb\x7a\x5c\xae\x57\xbb\xae\xbf\x56\xbc\xa3\x96\x5d\x1b\x54\x6d\xd1\x19\xd4\xad\x2d\x0c\x7a\x40\xcc\xd4\x4d\x6f\x48\x64\xa4\x07\xec\xd7\xbf\xb2\xc2\x6e\x80\xfe\x94\xc0\xad\x52\xdf\xa1\xca\x5e\x5e\x9b\xe5\x6b\x96\x8f\x90\xa3\x0a\x74\x8c\x2e\x03\x22\xa2\x2d\xba\xeb\x1e\xf4\x4b\x6b\xdd\xbc\x83\xc8\x3f\x07\x6f\xcd\x97\x12\x28\x93\x08\x4c\x36\xb5\xd6\xd6\x3f\xcb\xa3\xcc\x60\x34\x90\x8d\xb0\xe5\xc4\xb6\xfe\x7d\x3f\xaf\x57\xd0\xbd\x62\x1d\x50\x8d\x2f\x04\xf7\x94\x6e\x3e\xcd\xce\x3d\x1d\x24\xda\x97\x66\x74\x01\x8f\xa2\x79\x9c\x89\x67\xbb\x03\x08\x8d\xb1\x08\x5d\x5b\x0d\xf7\x1e\x2d\xfc\x87\xef\x10\x49\xdc\x07\xdb\xd9\xb4\x2e\xfe\x71\x16\x55\x03\xd5\x5d\x56\x88\x1c\x79\xdf\xba\x6e\x8a\xe0\x08\x7f\x80\x46\x6c\xa6\x25\x93\x9a\x52\x92\x3a\x85\x97\x59\x2f\x79\xf2\x67\x64\x9a\x68\x1a\x26\xc8\x3e\x2f\xcf\x17\xd2\xf4\x0c\x61\x6d\x0b\xb7\x94\x05\x2f\x80\xe2\x01\x05\xe4\xe8\xee\xb9\x56\x46\x19\x16\xe6\x3d\x7e\xf7\x49\x0a\x1d\xca\x14\x3d\x9f\x27\xd5\x94\x2f\x95\x38\x76\xbf\x6b\xae\x31\x37\xfa\xde\x9a\x3f\x17\xa7\x9a\x80\xf2\xa8\x4f\x38\x08\xae\xd5\xaf\xaf\x72\xee\xe3\x27\x8e\x82\x00\x43\xe3\xcb\x3b\x5f\x78\xa7\x63\x16\x23\xc4\x0f\x41\x1d\x68\x67\x5d\x7a\x7b\x43\xc7\x91\xf4\x0b\xa0\xa3\x0b\xa8\x27\x44\xd5\x6d\x27\x4e\x49\x38\xc6\xb0\x6d\xa1\xb5\xe7\xe6\x6d\x2a\xcd\xe3\x08\x7d\x29\xfb\x58\x7e\xe5\x99\x98\x77\x03\x59\x88\x2f\x50\x49\x9a\x73\x81\x86\xe8\xed\x7a\xb7\xb9\x5f\xfc\x75\xf8\xb9\xbe\x5d\x75\xcf\x96\x92\x98\xe8\x2e\x4f\x8c\xc9\x9b\xb2\x72\x4b\x0a\x8e\xbc\x30\x70\x3d\x45\x68\x61\x88\xf2\x7c\xb1\x01\xad\xac\x8f\x19\x68\x99\xc4\x88\xea\x14\x68\x39\xf5\x59\x47\x2d\x65\x08\x96\xe2\xf1\x19\x65\x02\xe7\x49\x45\x59\xa0\x95\x09\x80\x0f\x8d\xd0\x4f\xb4\xf3\x5d\x77\x1d\x0b\xcc\xb9\xda\x62\xd8\x32\xd7\xc3\x4d\x49\xeb\x14\x20\xf4\x70\xae\xea\x88\xc1\xfc\x7f\x9c\x07\x35\x2a\xae\x1f\x24\x80\x9b\xda\xdd\xfa\xf1\xcf\xd1\x09\x0c\x55\x08\x2c\x75\x59\x07\xc7\x14\xe6\x1b\x93\x84\x26\xbe\x48\xed\x58\x76\x18\x56\x6d\x54\x4c\x1d\xbe\x57\x63\xae\x63\xb8\x7a\x68\x03\x44\x8b\x81\xb4\xa8\x70\xeb\x76\xdb\xa5\xdf\xb0\x20\x48\x38\x7e\xae\x43\x33\xe5\x3f\x9b\x7d\x13\x10\x24\xd2\xcf\xa5\x07\xf1\x61\x77\xa3\x7d\xf9\x0b\x8d\x9b\x49\x4f\x2e\x62\xcb\x78\xf4\xef\x73\xdd\x8c\x03\xf1\xb6\xfe\x7e\xd4\x9d\x80\xe5\x1d\x37\xe8\x7a\x7e\x1d\x59\x07\x62\x48\xdc\x91\xf6\xf9\x52\x8f\x45\xee\x07\x08\xd0\x58\x49\xde\x2f\x57\x37\xe7\x42\xe7\xfd\x24\x02\x9a\x06\xf8\xc1\xf6\xbf\xb3\xa6\x0f\xbb\x03\x0b\x59\x1c\x78\x3c\x53\x7e\x86\xf1\x5c\x26\x0e\x21\x0a\x61\x48\x91\xdb\xed\xb5\xfc\xfd\xb3\x6c\xa0\xfe\x2e\x6a\x87\xed\x9a\xbc\x81\x30\xb2\x02\x73\x8e\xc3\xfb\xbb\xa8\x57\x85\xee\x1c\x2d\x08\x8d\xd5\x0a\xf1\x92\x7c\x63\x58\x0a\x44\x89\x8c\x93\x71\x20\x73\x59\x5d\x76\x65\xfe\x24\xff\x0d\xaa\x8b\x66\x42\x24\x01\x23\x0f\x9b\xaa\x6c\xca\xe6\x72\xea\x4e\x10\x47\x56\xab\x43\x68\xbd\x40\xbd\x8c\x3f\xa6\xb8\x9f\xc1\xe6\x06\x71\x94\x20\xb6\xe3\xe6\xdc\x2e\x9d\x58\x9f\xf6\x19\xf5\xd7\xf8\x29\xe3\x38\x34\x2e\x8c\xd3\xcf\x44\x88\x15\xc3\xd8\x89\x2d\xf4\x04\xfd\xad\xcc\xf5\x52\x74\xa1\x39\x88\xb5\x2d\x31\x10\x5a\x3b\x27\xd9\xa7\xb5\xc6\x93\x06\x92\x20\x40\x90\xd9\xe6\x69\xf9\xe8\x0f\x4e\x62\x2d\x60\x50\x0e\x2e\x94\xb5\x5a\xc7\xb6\x3f\x24\x89\x42\x67\x75\xd5\xbc\x3a\x68\x50\xbb\x94\x0c\xd0\x9d\xde\x34\x00\x1e\x84\xa8\x06\xd7\x39\x79\xc8\x6a\x8a\xb1\xa7\xbf\x99\x0f\x3c\xe0\x71\x38\xc2\xc7\x5f\x17\xff\x00\xa7\x3c\x60\xc3\x82\xa8\x9b\x0b\x6e\xbb\x7d\x50\x77\x9a\xe3\x05\x2e\x6d\xe2\xb8\xb2\x04\xb3\x0f\x30\x30\x54\x20\x55\x0c\x13\xb0\xce\x3b\xf2\x5a\xfd\xe3\x3b\x4b\x4d\x8c\x9e\xcf\x6e\xbf\xd8\x3f\xef\x0e\x8f\x4f\x87\xdb\xd5\xe2\xde\x9f\x42\x44\x56\x5a\xc9\x9e\x02\x2d\x1a\xb4\xe6\x3f\xa5\x09\x6b\x8f\x11\x29\x9a\x99\x27\x2b\xc9\x65\x2d\xd8\x03\x0d\x0e\x77\x20\xab\xb3\xa8\xba\x8f\x2f\x43\x29\x5c\xd1\xc0\xf7\x32\xd7\xf3\x25\x24\xa0\x02\xa0\xb2\xef\xf5\xb9\x32\xac\xef\x9f\x72\xa4\xb6\x7d\xfa\x71\x37\x5c\x3d\x41\x01\xf1\x91\xc0\xa7\x13\x14\x43\xcd\x1d\x16\x80\x8e\x42\x70\xf5\x2e\x4e\x3b\xfc\x53\xe9\x6f\x16\x00\x24\x09\xda\x5c\xbb\xa6\x3c\xf5\x2a\x45\x83\x8b\x19\xa6\x11\x4c\xd4\x88\x37\x70\xd6\xe3\xf8\xa9\x8c\x50\x61\x8f\x0a\x5f\x62\x86\xe2\x8a\x2b\x03\x8c\xb4\xc3\x5f\x97\xcf\xc5\x49\x9c\x3b\xa7\xcf\x10\x12\xa1\x15\x63\xbf\xcb\x63\xa9\x61\xbd\xb9\xdb\xf5\xb5\xcb\xbe\x1b\x8d\x2d\x86\xca\x29\x0a\xdb\x49\x80\xc2\x94\xe5\xb9\xb5\x08\x56\x56\xd6\xe4\x6a\x1d\x1d\x06\x8d\x0c\x31\xc0\xa9\xb7\xa1\x1d\xfd\xf2\xa8\x03\x0d\x38\x6e\x4c\xa8\x64\x7f\x53\x7a\x84\x93\xa1\x61\x88\x96\xf0\xc1\xa6\xdb\xf5\x59\x35\xad\x1f\x86\x66\xd5\xe8\x41\x0d\x33\x01\xc2\xfa\xbd\xc3\x33\x69\x0e\x63\x89\x45\x5b\xa7\xf2\xb7\x7b\x93\xd7\x35\x21\xfc\xff\x48\x12\xff\xcb\x1f\x60\x18\x16\x76\x3f\xef\x2d\x2b\xde\x7e\xc8\x15\x39\x13\x73\x35\xa1\x09\xa5\xf4\x1b\x56\xf5\x06\xcd\xed\x15\x42\xcc\x44\xb1\xc6\x54\x0d\x02\xa2\x3c\x90\xdf\xb7\xa5\x0a\xb1\xb6\xb9\xa8\x1d\xf6\xfb\xa6\x3c\xbf\xbc\x4e\x72\x7a\x26\x4e\xec\x8e\xf4\xfd\x6e\x10\xe2\x36\x31\x48\x1c\x9a\xc7\x76\xf7\xd3\x77\x65\xe5\x52\x51\x6b\x2b\xd7\x39\x6f\x6d\x98\x24\xe2\x18\xfc\x78\xc8\x72\x40\x46\x8b\x7a\x65\x09\x0f\x7d\xbb\x32\x3c\xb0\x08\xee\xee\x8b\x24\x86\x20\x9f\xd4\xd3\xe3\x6a\xb3\xf0\xe5\x85\x86\x47\x89\x61\x9e\xfd\x36\x7b\x17\x0d\x6e\x44\xad\xf5\xfe\x50\x16\xcd\x6b\x7e\x69\xd7\x8d\xf3\x69\x7a\x1f\xd3\xf4\x97\x11\x34\x41\x4d\xaf\xc3\x4d\x57\xa3\x66\x44\x6a\x61\xd7\x3b\x51\x34\x59\x6b\x88\x62\x56\xf9\xbe\xcf\x2a\x1b\x21\x18\x78\xf9\x67\x51\x41\xeb\xc9\xd6\xc3\x6f\xec\xba\xc9\x38\xc4\x37\xbc\x71\xf8\x69\x57\x31\x33\x0b\x85\xef\x0e\xb1\xf2\x40\x35\x34\xae\x76\xd0\x13\x34\x8c\xbe\xbd\x4c\x22\x5c\x27\x1d\x99\xc3\xee\xed\x9c\x5f\x71\x6e\x7e\xed\xa3\x19\x29\x6c\xb8\xd1\x93\xfc\x14\xd9\xa9\xb5\x17\xcb\x2b\x18\x70\x6f\x53\x19\x09\x21\xca\x4b\x43\xa1\xd7\xaa\xf4\x6c\x10\x46\xbb\x72\x77\xaf\xa3\x77\x63\xc7\xe0\x3c\xf8\xd8\xe8\x24\x4e\xe3\x6b\x3e\x43\x94\x88\xe9\x46\xf0\xe7\xbc\x86\xe3\x17\x01\x3c\xc6\x22\x33\x0d\x2a\x17\x15\x6c\xce\x79\xa6\x50\x1c\x3b\x2b\x5e\x36\xb9\xb8\x12\xb2\xf5\x87\x41\x2a\x1d\x69\xd1\x7a\xf9\xd4\x64\x9f\xb9\x87\xc6\x50\xa1\x6d\x35\x20\xb8\xcc\x30\x68\x5f\xcc\xdd\xbd\x18\x12\x04\xd4\x22\x31\x5f\xa0\xf1\x96\xe3\xb7\xec\xdd\x87\x8f\x87\xa7\x24\x41\x90\x52\xd4\x4a\xdb\xae\x90\xbf\x70\xbf\x7e\x70\x69\x68\x12\x04\x60\x30\x81\x73\x77\xce\x55\xe5\xeb\x85\x49\x40\x88\xb5\x60\xda\xc1\x9e\x7d\x40\xbe\x11\x17\x21\xaf\xc3\x60\x5f\xe2\xbb\x48\x40\x42\xee\xa8\x75\x2e\xbb\x5f\xf7\xdd\xb9\x85\xb4\x62\xaa\xd6\xc4\x5f\xb5\x96\x41\x27\x82\xce\x48\x40\x25\x25\x2e\x67\xb5\xb8\xa2\x0f\xbb\x8a\xe3\xb6\xfd\x01\xb1\x13\x98\x6d\x71\x7e\xe4\x93\xf9\x63\x7c\x2b\x54\x03\x7e\xb5\x1d\x34\x36\x8a\x8b\xec\x45\x6e\x89\xe5\xf3\xb5\x22\xee\x50\x66\xac\xc0\x88\xc9\x2a\xd8\x88\xac\xe3\xbe\xb6\x52\x3d\x73\xcb\x0e\x09\xc2\x90\x18\x07\xb4\x80\x49\x2d\x2e\x09\xc2\x24\x45\x91\x8c\x3c\x7b\x79\x6d\x4e\xa5\x2f\xad\x24\x41\xe8\x9e\xfc\x5c\xb8\x84\xe7\x27\x67\x8f\x85\xe0\xce\x71\xb8\xbf\xff\xe9\xd2\xbc\xc4\x9f\x25\x36\x56\xe4\xe1\xbd\x6c\xe0\xa9\xd8\x4c\xca\xe0\xaf\xd4\x5e\x18\x09\x92\x38\x24\xae\x6e\xd2\x62\xd8\x76\xb7\x57\xfc\x73\x24\x48\x92\x50\xb0\x9e\xad\xcf\x6d\x92\xeb\xe5\xd3\xec\xfe\x4f\x82\x84\x13\x24\xb6\xb9\x2f\x5f\x7a\x95\xcf\xac\x2c\x6e\xe5\xd6\xcd\x5a\xd0\x93\x37\xc3\x49\x04\x8e\x30\xe5\x16\x6a\xf4\x99\x41\x5b\x4e\x4c\xa8\x76\xaf\xe5\xef\x21\x7b\x0a\x09\x78\xa4\x7c\x01\x7a\x2f\xde\x91\xa9\xb7\x62\x2c\xe0\xd1\xf6\xe4\x01\x12\x33\x3f\xf4\x54\xa9\xf8\x2b\x13\xbc\x4b\xcf\xd0\x49\x35\x19\x09\xb8\xd4\x48\x39\xd2\xbe\xc9\xc7\xb2\x5d\xdf\x6f\x44\xa3\x5e\xbf\x18\x8b\xdc\x04\x8e\x0e\xe8\xb1\xb4\x25\x13\x33\x6b\x08\x09\x64\x10\xdb\x5c\x2f\x54\x65\xd3\x05\x1f\x49\x20\x55\x84\x42\x7e\x05\xfc\xb6\x05\x5f\x9f\xcd\xb3\xbf\xa9\x42\xf0\xa7\xd3\x49\x28\x9d\xe1\xdb\x4c\xbe\xa6\x0a\x14\x71\xcc\xe9\xdb\x32\xcf\x9f\x51\x27\xca\xb7\x71\xbb\x45\x3d\xde\xed\x47\x49\x1d\x12\x28\x08\x11\x61\xe0\xf4\x47\xaf\xa2\x19\xa3\x4b\x68\x66\xe2\x4e\x15\xf5\xa0\x07\xe0\x0b\xd7\x01\x22\x05\xf6\x6d\xdd\x54\x00\x3a\x2b\x5e\xac\x59\xd1\xb5\xab\x50\x24\xfd\x4a\xf0\xfb\xd3\x54\x16\x69\xad\xc0\xb0\x63\x34\xac\xcf\xf9\x7c\x96\xa4\xed\x67\x2c\x06\x42\xbc\xc0\xcd\xc5\x56\x08\xcf\xa4\x0c\x49\x60\x42\x85\x48\x90\xd6\xdc\x98\x2b\x15\xfc\x6c\x9b\x23\x24\xa0\x0c\x81\x27\x47\xf1\x61\xfd\xb0\x3f\xba\x06\x8e\xf4\xf8\x2e\xeb\x8b\xc2\x21\xc3\xc0\x2d\x21\x24\x08\x3d\x21\x4a\xeb\xe4\xbb\xd0\x74\x3d\x50\x1b\x6b\x3b\xa5\x32\xec\xa9\x0f\x6f\xe1\x1d\xf2\xf2\x34\x49\x62\x10\x42\xb4\xc2\x02\x9f\x43\x01\x1f\x43\x1a\x3d\xfe\x77\x6b\xf7\xf8\x3d\x10\x9a\x24\x58\x4d\xe4\x88\xc6\xb7\x1d\x84\x89\x10\x6a\x24\x46\x25\x6e\x84\x7a\xdb\x97\xf7\x99\x01\xdf\xc2\x68\x84\x48\x16\x8c\xf1\x6c\x72\xd0\x2f\x0e\x4c\xe6\xdb\xc3\x18\x8b\x57\x75\x59\x20\x36\xa7\xdd\x92\xab\x11\xb9\x7d\xdb\x89\x47\x88\xc2\x9c\x60\x6d\x46\x18\x1b\xf6\xaf\xc9\xed\x32\xc9\x3b\x46\xfb\x5b\x90\x55\x56\x5f\xb9\xde\x83\xb5\x9d\x44\x24\xc2\x35\xcd\x05\x37\x10\x50\x63\x84\x1a\xaf\x1e\x24\x8a\x88\xd0\xce\x44\x5f\xba\x28\x17\x2a\xc9\x8b\xaa\x35\x81\x61\x72\xe3\x51\x44\x70\x11\x78\x10\xed\x22\x57\x94\x1a\x1e\xb2\xe2\xcb\xa8\x18\x21\x51\x9a\x52\x8b\xfd\x77\x7b\x1e\xe8\x8e\x40\x8c\x90\x48\x86\xca\x46\xf0\xf2\xb7\xd6\x74\x81\xa1\x64\xd6\xf4\x4c\xca\xa1\x18\x3f\x4e\x79\x59\xc1\xea\xe1\xe9\x71\xef\x05\xdf\xdb\x66\x4d\x91\x67\xe3\x9f\x59\xf3\xc3\xeb\x30\xb1\x76\xbb\x57\x88\x30\xf8\xdf\xf2\x52\x97\xf3\x0b\x3a\x49\x74\x2c\xe5\x80\x56\xde\xbf\xd8\x6b\x57\x81\x10\x1e\xda\x5a\x86\x17\x68\xe8\x78\xe5\x21\x9c\xdb\x1a\x5d\x0b\xef\xd9\x9d\xab\x77\xb8\x4c\xde\x20\xd7\x56\x05\x5e\xec\xb2\x09\xaf\x2e\x23\x24\xa5\x91\x13\x9b\x6e\x27\xc9\x0d\xa6\xa6\xf6\x1f\xd3\x4e\xdc\xca\x65\x37\x3d\x24\xed\xae\x2a\x8f\x9f\x01\x5f\xdd\x51\x22\x56\x68\x54\x55\xe7\x4f\x52\x7e\x84\x88\x94\xe3\x9e\xd3\x2e\xdb\x8f\x65\xb3\x2a\x5a\x0f\xc6\x8a\xa4\xf8\x77\x29\x29\xa4\xdc\x8f\xfe\x1b\x68\xea\x07\xa1\xbb\xf7\x2f\x95\x16\xb1\xe7\x0b\x23\x7d\xe1\x02\x21\x8a\xc6\x98\xf3\xcd\x2a\x07\x4b\xac\x45\x0e\xdb\x73\x51\x74\xd1\x36\x42\x74\x64\x69\x29\x2c\xc1\xcb\x1c\x44\x88\x90\xd6\x09\xb0\xf6\x15\x7a\x47\x0e\xe0\x6c\x6b\xff\x7d\xc4\x8c\xd0\x40\x01\x4e\x94\x76\xbf\x2c\xb3\x21\x0e\x92\x50\x42\x45\x2c\xd1\x0e\xc9\x54\x59\x15\x5b\x51\xa8\x71\x76\x9f\x50\xc2\x62\x64\x83\x1c\x62\x67\x26\xfa\xcc\xa3\xf7\x46\x89\x4a\x94\x23\x01\x9b\x56\x37\x10\x4a\x09\x55\xbe\x8e\xb6\x0b\x9e\xfa\x36\x1a\x48\xd5\x61\x56\xff\x71\xce\xd4\x9b\x2d\x76\x1f\x3d\x35\xa5\x91\x4d\x3d\x14\xf0\xfb\xe9\x34\x8c\x90\x7c\xb6\x67\x76\xc7\x09\x0c\x57\x65\xaa\xdc\xbf\x56\x50\xbf\x96\xb9\x66\xdd\xb5\x63\x83\xe3\xf0\x77\x95\x35\x5e\xfd\x53\x67\x35\x78\xd7\x6b\x38\xe4\x29\x0b\x48\xac\x3b\xe9\xb8\xba\x41\x59\xbf\x71\x4d\xdb\xc4\x19\x6c\x8f\x01\x9c\xf6\x6a\x52\x7b\xf1\x59\xea\xc3\x1f\x46\x95\x65\x22\xaa\xc0\x97\xe4\xe0\x78\x9a\x4c\x15\xca\x9c\xaf\xd2\x80\x7a\x75\x1b\x45\x6b\x69\xaf\x9a\xd7\x01\x6f\x7a\xdb\x4f\x6a\xfc\x9a\x47\x0c\x8d\xd9\x44\xea\x00\x9f\x4c\x68\x48\x62\x74\x13\x0e\x9d\x58\xda\x18\x8a\x30\x57\x6b\xe8\x0f\x8d\x28\x02\x91\x8e\xf7\xa5\xb0\xa5\x96\xcd\xb9\x2a\x26\x37\x1a\x85\x21\xb3\x91\x25\x55\x16\x23\x78\x82\xeb\x90\x24\x0c\x35\x82\xe5\xf9\x72\x73\x59\x35\xaf\xf3\x13\x98\x72\xce\x52\x07\xe4\x6b\x5f\x66\x79\x6e\x90\xba\xa6\x76\x14\x80\x84\xf2\xc9\xdd\x71\x4d\xb0\xf2\x51\x9e\xa7\xb2\x6f\x8c\xd0\x34\xb1\xbc\x19\xd6\xa8\xc0\x64\xe8\x7f\x11\x5d\x23\x34\xe5\x56\x58\xf4\xbe\x7c\xb9\x2b\xab\xb7\x45\x61\xf9\xf0\xa6\x89\xb8\xf1\xad\xa7\x12\x90\x5d\xb3\x4b\xa3\xa0\xfc\xe0\x06\xaa\x5f\x90\x2d\x0a\x6d\x91\x45\x8b\x77\x91\xe5\xb8\x53\xa9\x12\xdb\x27\xef\x31\x85\x18\x35\x6a\xda\x6d\xfa\xb0\x5b\xdc\xaf\x76\xfb\xc5\xb7\x55\x37\x9e\x53\x48\x12\xb7\x2a\x0f\x05\xd0\x5c\xab\xd0\xa1\xb4\x34\xac\x45\x37\x15\xfc\x91\xca\x51\x59\x3c\xa1\x40\x9b\x72\x3a\x4c\x6d\x83\x23\x8e\x5b\x59\x28\xaa\x2b\x57\x45\x94\xd2\x5d\x59\x6d\xc4\x25\xb3\x74\xe3\x35\x14\x7a\x6a\xa4\x50\x2d\x80\xf7\x74\x95\x1d\x4f\xe1\x27\x34\xf5\xed\x01\xad\x9d\x37\x10\x4d\x58\x3d\xde\x0e\xbc\x59\xaa\x0d\xc3\xe0\x53\x5f\x31\xbc\x05\x33\x57\x2a\x4c\xa8\xe1\x12\x37\x08\x69\x73\x5b\xd7\xd7\x62\x01\xb5\xf5\x62\x5e\x48\xa1\x9e\x46\xd5\xff\x67\xdc\x1d\x38\xce\x21\x8c\x9e\xef\x5e\x3d\xcd\x10\x61\x84\x71\xc4\xc4\x37\xe7\x62\x22\x96\x3f\xbe\x1e\xe1\x96\x08\xf4\xd0\x8d\x00\xb4\x10\x3f\x2f\x0d\x21\x8c\x68\xae\x3b\x5c\xa0\xc9\xb3\xd3\x98\x59\x95\x30\x1a\xda\x54\xf2\xfa\xe9\xcf\xa7\xdf\x45\xb7\xfa\x33\x1a\x07\x68\x06\xdf\x66\x45\x39\x2a\x70\x71\xed\x2c\x0a\xad\x34\xae\xf8\xd8\x41\x9e\x77\xb2\xae\x6d\x93\xa1\x68\x94\x97\xe7\x06\xab\xa7\xb3\xe2\x65\x94\x2b\x20\x2c\x74\xba\xb2\xcb\xdd\xea\xfe\xef\xaa\x67\x08\x0b\x81\xe2\xeb\x41\x6c\x9e\xad\x3c\xc0\xd8\xa1\x33\x7a\xc7\xf7\x15\x42\x8a\xd3\xd5\x66\x57\xef\xb3\xe2\xcd\xc5\xe2\x7e\xc0\xa7\xd4\x02\xff\x45\xaa\x95\xb0\xd0\x84\x08\xd9\xdc\x9d\x40\x65\x22\x6f\xdd\x5f\x3d\x56\xbd\x63\x84\x45\x61\x42\x2c\x80\x1a\xaf\x89\x5f\xfa\x6e\xb8\xab\xb2\x08\x34\x06\x29\x2b\xa1\xc6\xec\xab\xae\x3d\x0e\xa8\x95\xb4\xca\x45\x76\xec\x6a\xcd\x86\xe0\x50\xc2\x62\xc2\x10\xd1\x66\x23\x45\xb7\x57\x8e\x38\x8b\x99\xe2\x28\xc0\x52\x37\x00\xc7\xa9\x19\x36\x1e\x21\xb1\x11\xd8\xf7\x11\xce\x55\xe9\x88\x2c\xba\x0b\x19\x29\x7b\x3b\x45\xd4\x70\x2f\x2a\xd8\x95\xb9\x5e\x17\x0f\x22\x1b\x14\x55\x12\x96\x44\x14\x63\xe4\x18\x63\xd9\x41\xb3\xaf\x40\xd4\xe7\xea\x32\x19\x8f\x09\xe7\xa4\x4f\xa6\x3c\xd7\x50\x39\xb6\xca\x75\x71\x73\xce\xdf\xe6\x1c\xe7\xb9\x7f\xf9\xb3\x19\xab\xff\x75\xf7\x5a\xfc\x1e\xda\x27\x8c\x07\x0a\x81\xbb\x93\xda\x4f\xc2\xb8\x66\xc8\xd2\xf9\x22\x8e\xad\xcd\xfd\x19\x37\x7a\xdb\x91\x63\x90\x6d\x40\xfb\xf3\x65\x89\x7c\x3b\x87\x21\xf2\x65\x3d\x50\x59\x41\x5a\x3f\xdb\xba\x4f\x97\x12\x6e\xf5\x09\x9d\xfa\xcb\xbe\x3c\xa3\x7e\x57\x6b\x87\x39\xc1\x92\x71\xa1\xc8\xe4\x22\xa9\x73\xed\xb2\x42\xc3\xc7\x93\xb1\xc5\xdc\x93\x34\x1e\x61\xa9\x8a\x11\xf8\x71\xc8\xea\x75\x81\x91\xe2\x2b\x9a\x20\xd7\x53\xa4\x34\x70\x04\x44\x3e\x22\xfc\x35\xd3\x15\x61\x42\x18\x8c\x95\x22\xc5\xce\x38\x7b\xe5\x9c\x26\x26\x13\xbb\x74\x9a\xac\x18\x4e\x7b\x15\x06\x28\x50\x5d\xc0\xef\x4f\x99\x51\x09\x53\x10\xc5\x49\x5f\xe9\xda\xbd\x3a\x2d\xac\xd0\x76\xe3\x46\xd6\x64\x4d\x31\x91\x40\x2a\xd0\x06\x19\x68\xb3\xaa\xfe\x2d\xae\x42\xed\x5f\x56\x9d\x7e\x36\xf1\x4d\x1a\xa2\xb5\x0c\x4e\xff\xd6\xbf\xa7\x4f\x6e\xdf\x28\x66\xdc\x30\x78\xb8\x38\xa1\x9a\xf1\xf4\x0c\x83\xd4\xd2\x9e\x6b\x78\x37\x9d\xdf\x15\x06\xd2\x22\x99\xfb\xaa\x4c\xb4\x62\x47\x53\x3f\x6c\xb7\x30\x17\x62\xc3\xc5\x05\x55\xaf\x57\x18\x6b\x99\x8e\x82\x90\x85\x81\xad\x1c\x3d\x57\xc5\x6e\xbf\xbc\xdd\xce\x8f\xa9\x90\xe9\x34\x71\xee\xd2\x34\xbb\x39\xed\x69\x74\x6c\x09\x5d\xdf\x87\xc2\x0d\xae\x35\x4c\x22\xac\xd5\xb2\x02\x66\x83\x24\x4a\xdb\x24\x30\xba\xf6\x03\x4e\xb9\xcb\xf1\xf5\x6b\xe7\xf4\xe3\x8c\x9f\x22\x54\x56\x2c\xcf\x05\x94\x96\xa5\x86\x41\x72\x8e\x84\x31\x95\x38\x1c\x9b\x57\x38\x14\xe5\x31\x2b\x44\x7e\x10\x45\x71\x16\xf9\x01\x51\x10\x50\x37\x87\xaa\xe3\x7b\x21\x61\x2c\xac\x8f\xda\xc1\xf3\x40\x1c\xe7\x3f\x65\x18\x6b\x8a\xdb\xd4\xf7\xcb\xa9\xed\x37\xa2\x23\x20\x61\x92\xc8\x54\x7a\x1c\x20\x8a\xfd\xce\x8e\x9f\x90\x33\x2b\x30\xb6\x39\xd7\xaf\xa3\x13\xf0\xd0\x46\x22\x96\xeb\x3e\x8b\x45\x42\x2e\x14\xe2\xd5\x5d\xa2\xbe\xdd\x67\xac\xb5\x3b\x19\x44\xdc\x10\x1c\x96\xc7\x52\xaf\x3e\x4e\x5f\x56\x46\x93\x30\x8d\xd3\x50\xb8\xa1\xf0\x5d\x58\xda\xcc\xe3\x90\xfd\x75\xb4\xe3\x86\x29\x4f\xf1\x4b\xda\x02\xac\xcd\xf7\x3f\xdb\x25\xb4\x9e\x98\x0e\x61\xaa\xc2\x30\x18\xbc\xc9\xdb\xb2\xdd\xad\x3c\xcf\xd7\xdc\x66\x13\x8a\xc0\xf2\x8e\xe1\x2e\xb1\x75\x94\xd6\xfe\xbc\x4b\x24\x68\xa2\xfe\xf4\x22\xa2\xd4\xe1\x0e\xf6\x50\x1d\xbb\xcb\x63\xf5\x05\x34\x57\xe1\xa0\x50\x08\x0b\xcc\x5c\x35\xaf\xb7\x99\x82\x28\xf0\x67\x52\x9a\x20\xaa\xc1\xfa\x50\x9b\xaa\x3c\x8e\x4d\x9a\xc9\x4d\x6a\x9d\x20\xb6\xef\x5b\x99\xeb\x4c\x1c\xfb\x28\x4b\x08\x81\x91\xff\x15\x66\xb9\xdb\xa9\xa6\xe1\xa7\x10\x58\x8a\x61\x8f\xa6\x3a\x5f\x57\xd9\xfa\x3e\x69\x2a\x90\xd8\x4f\xea\x4c\x0d\x86\x2e\x28\x0a\xae\x8a\xea\xd0\xce\x1c\x27\x39\x7b\x95\x14\x23\x21\x18\xae\x10\x5f\x02\x75\xf6\xd6\x08\xbf\x7c\x44\x01\x03\x15\x76\x75\x58\xe3\x1a\xb3\xd1\x3d\x44\x41\x18\x61\xe8\xee\x1b\x14\xcb\xd7\xec\x74\xad\x1a\xc7\xff\x9b\x1d\x3a\x0a\x44\x82\xc0\xa8\xef\xa2\x6a\x4d\xe3\xd6\x4c\x95\x97\x9b\x4a\x74\xe3\x3d\x0a\xc0\x58\x5d\x41\x28\xc0\x64\x2a\x13\xd5\xa5\x63\x40\x72\x5d\x08\x01\x0f\xa0\x5c\x18\x93\xe5\x28\x44\xd9\xc3\xaf\x48\x44\x58\xc0\xd2\x11\xe4\xb6\x5d\x33\xb1\x2e\xac\x40\x37\xaf\x47\xd7\x7d\x65\xfa\x7d\x15\xf3\x1c\x2c\x39\x11\x89\xed\x4a\x8d\x09\xd1\x46\xe8\x61\x55\xfa\x68\x48\x46\x04\x14\x6e\x06\xc7\x4b\x4f\x91\xeb\x9a\xa8\xd6\x48\x8e\x6d\x6c\x89\xc3\x90\x31\x91\x44\x21\x53\x26\xf4\x63\xff\x78\xca\xaf\x4c\xbc\x28\xd4\x49\x6a\x19\xe4\x8a\xe6\xe6\xb2\x68\xca\xe3\xfc\x9a\x1d\x45\x31\xf5\xc1\xb0\x65\x0e\x99\x9e\x9e\x28\x52\xdc\xa7\x09\xd1\x9b\xb8\x8b\xfc\x4d\xc4\x51\x1c\xb8\xc7\x74\xd9\xa6\xc9\x0e\x13\x25\x89\x52\x1e\x9f\x56\xb6\x13\x62\x7d\x3b\x4f\x8f\x4e\xa2\x44\x02\x56\x5a\x65\x47\xf1\x02\x3e\x6b\xe9\xaf\x94\x68\x86\xc8\x87\xa2\x2c\x7e\xe2\x28\x19\x10\xcc\xb9\x0a\x39\x12\xf1\x20\xc4\x2a\x49\x5b\xe5\x3e\x4f\x39\x4c\x22\x6e\xac\x5e\x70\xa6\x4a\x32\x00\x80\x91\x48\x04\x69\x34\x24\x36\x99\xe1\xb0\x6b\x3b\x09\x54\x53\xb8\x11\x75\xa6\x66\x68\x5d\xaf\x0c\x89\xd9\x3d\x2b\x12\xb1\x2d\x98\xf2\x24\x65\xcf\x45\xf6\xff\x3b\xc3\xee\x64\x79\x2f\x87\x4b\x6d\x24\x62\x8d\x1c\x08\xdd\x6d\x79\xe6\xb4\xc9\xfb\x13\x3a\x52\xe0\x33\x35\x98\x95\xb8\xc2\x7f\x90\x48\xf2\x18\x67\xdb\xc3\xe3\xe6\xaf\xe1\x56\x13\x29\x65\x31\x17\x0f\x8b\x3f\x0f\xab\xfd\xf7\xd5\xd6\x37\x68\x12\x5a\x9e\x25\x71\x19\x6c\x42\x91\x4e\x22\x2c\x5c\x6a\x5d\x2e\x94\x22\x45\x54\x41\x93\xc9\x2c\x6f\x77\xf5\x7e\xa5\x89\x80\x1a\xe2\xc0\x01\xed\x0e\x79\x25\x7b\xdf\x76\x61\x04\x99\xd8\x4f\x42\xbd\xf9\x9a\xd5\xf1\xc3\x41\x6c\x8b\x10\x5d\x49\x8e\xbe\x52\xcc\x9e\x7f\xcd\x20\x6d\x31\xaa\x75\x80\x9f\xce\x13\x0d\xa2\x4f\xf8\xfd\xe6\xa7\x89\xe1\x44\x39\x41\xdd\x9f\xe2\x9c\x37\xb3\x2a\xd1\x6d\x3f\x1d\xa0\x92\xe6\xc3\x65\xbc\x85\x7c\xe1\xc0\x46\x46\x5b\x6e\x6d\xe7\x13\x01\xea\x0b\xf8\x57\x6d\xc0\xc6\x4d\xd0\x5e\x1c\xc0\xb7\x49\x1c\x10\x8d\x83\xd1\x57\x01\x38\x1e\xda\xcf\x56\xa8\xd1\xbb\x89\x83\xd8\x3a\x1a\x43\x86\xe4\x51\x65\x1c\x89\x03\x1d\x33\x39\x08\xb3\x9f\x4e\x65\x35\xd9\x8a\x62\x12\xb3\xd4\x72\x43\xf8\xc8\xcb\xd8\x08\x88\x29\xb3\x05\xc7\x28\x19\x7f\x53\x8a\x4a\x6f\x05\xca\x13\x8e\x74\xe3\x67\x32\x2b\x31\x4d\x19\xe7\x5e\xb2\x07\xd7\x40\x8b\x03\x9d\x5d\x49\x63\xc6\x15\x38\x7e\xb4\x5b\xd1\x88\x1a\x9a\xb9\x5a\x45\x12\x33\x19\x62\x86\x7c\x81\x40\x58\x21\x73\xc0\x58\x41\x3d\x57\x13\x44\xe2\xb0\xbd\x8d\x9e\x64\x63\x57\x1e\xe1\x47\x76\x9c\xac\x0a\x71\x98\x52\x36\x64\x37\xd4\xb8\x50\xfa\x37\x10\xd1\xd0\xef\xca\xdf\xa0\x80\x99\x42\x40\x12\x47\x49\x8a\x08\x01\x0b\x95\xaf\x9f\xcc\xe4\x3e\x22\x49\x71\xb7\xf5\x1b\xd8\x53\x71\x03\xaf\x22\x37\x5f\xd6\x38\x7c\xe2\xb0\xc4\x71\x6c\xf9\xc2\x6f\xf6\xcb\x53\x5f\x0b\x88\xbf\xe3\x4a\xdf\xee\x26\x75\xb3\x05\xe4\x44\x54\x36\x8a\x3a\xac\xcd\x20\x71\x0c\x04\x1f\xf8\x01\x9a\xaa\x3c\x95\x79\x56\x77\x2d\x26\x44\x42\x73\x07\xae\xac\x0f\xa6\xac\x0e\x15\x66\x0e\x26\x8f\x94\x04\x31\xfa\x80\xdf\xb6\x4f\xbf\x96\xdf\x17\x5d\x22\x29\x4e\x02\x10\x89\x5f\xc9\x7c\x6d\x03\x3a\x33\xfb\xf2\xe7\x80\xad\x99\xc4\x09\x11\x41\xe7\x50\x20\x2d\xec\xdf\xb1\x12\x77\x07\x1a\xf4\x05\xef\xb3\x06\x8b\x5f\x5c\x38\xa6\x3b\x6f\x92\x22\x3a\xe2\xd8\x6b\x83\xf9\x02\x1b\xdf\x03\x52\x6d\x69\xbf\x4c\xf9\x5c\x75\x9f\x9a\xc7\xb1\x97\xe4\xb7\xa3\xbc\xbe\xbb\xc2\x26\xb9\xae\x69\xc8\xd4\x90\xd2\x6b\xf5\xd1\xcc\x8a\x21\x63\x57\x8d\x68\xb6\xfd\x6a\xf1\xe0\x15\xba\x07\x5a\xaf\x6d\x0f\x63\xb0\xe6\xee\xbe\x2c\x0b\xb8\xdc\x97\x4d\x03\x5d\x32\x29\x16\x01\x41\xc6\x81\xf7\x0c\x7e\xff\xca\x30\x19\xf4\x34\x4c\xa2\xc7\x32\xe0\x96\xc6\xf8\xbf\xb6\x5a\x93\x89\xd5\x1a\x4b\xc2\x64\xe8\x2d\x9e\xa3\xe3\x37\xb9\xb6\x5c\x63\xc9\x15\x96\xfc\x3e\x95\x2f\x55\x99\x77\xef\x4d\xaa\x98\x3b\x19\xc7\x1f\x7f\x2d\x2d\x0c\x6e\xfd\x52\x94\xd6\x6b\xea\x36\x93\x58\x49\x82\x97\xf1\x9b\xe1\x8f\xac\x69\xa0\xb0\x61\x6c\xd7\x45\xcb\xc4\xd0\x2e\x80\x74\xbd\x07\xc6\x10\x31\x34\xce\x3c\xbc\xdf\x45\x20\xfd\xf1\x86\x1a\x4c\x13\xb8\x14\xe5\x73\xa1\x1c\xdd\xb0\x6f\x97\x89\x1a\x08\x7d\x96\x13\x79\x08\x12\x1b\x2d\x10\x58\xa6\x2e\x2a\x1f\x59\xa1\x49\x10\x31\xe3\x16\x34\xbb\x0d\x3a\x1c\xf1\x70\x2f\x48\x82\x44\x20\x1d\x46\x56\x64\xcd\x48\x01\x63\xbc\x7e\x27\x84\x70\xde\x15\xec\x6d\xfb\xc1\x9b\x10\x22\x6c\x3e\xa2\x2c\xdf\xde\x00\xae\x63\x1c\xa3\xdb\x4d\x48\xaa\x30\xfa\x6e\xa9\x9c\x32\x05\x3b\xb0\x19\x69\xd7\x4e\x99\xa5\x94\xb8\x7d\xb0\xb3\xac\xfb\x3d\x15\xa1\x27\x84\xed\x54\x4b\xe6\xfd\xe4\x24\xe4\x61\x60\xc3\x4d\x2e\xfe\xdd\x47\x9b\x26\x1d\x95\xe2\x76\xea\xb7\x0b\x06\x6a\x75\x40\x55\xaf\xcd\xae\x34\xcd\x52\x9c\x1e\xcb\x66\x0b\xa2\x1d\xa5\xfe\x2e\xa2\xc4\xa0\x0f\xa8\xca\x3c\xcf\xea\xae\xa4\xc2\xb5\xc6\xd2\xd6\xff\x59\xae\xc0\x0e\x6c\xec\x5b\x35\x4b\x7a\x5e\x1f\x5b\xd7\xa2\xb2\xf9\x6d\x3d\x89\x21\x61\x2e\x0e\xf6\x3d\xd3\x1a\x8a\x4d\xbb\x53\xfa\x24\xe1\x74\x89\x4d\x62\x93\x12\x5f\x18\x64\xd5\xee\x6e\x44\xd3\xe4\xb0\x41\x64\xed\xfc\x17\x4d\x02\xab\x60\xf8\xb5\x8e\xb9\xef\x2c\x39\xb3\x7c\x78\x58\x6b\x77\x44\xb2\xcc\xc5\x72\x39\x9e\x6f\x09\x67\x81\xd5\xa5\xf0\xdb\xf3\x50\x1c\x8c\x24\x3c\x91\x18\x07\x3c\x8a\x8f\xb5\x2a\xc7\xdc\x85\x24\x49\x39\xc7\x70\xdc\x40\xd8\x6a\x57\xde\x79\x75\x2e\x92\x88\x84\x20\x5d\xd0\xc1\x1a\x08\x6e\x93\x76\x90\x93\xb5\x1e\x32\x75\x91\x44\xc8\xd8\x53\x82\x2d\x5f\xc5\xf1\x54\x8f\xbe\x94\x0c\x65\x12\x7b\x96\x09\x58\xab\xf2\x21\x9b\x24\x14\x12\x15\x04\x38\xae\x8f\xe2\xc3\x9a\x71\x1b\xa8\x16\x55\x93\xa9\x2e\x78\x9b\xa8\x40\x40\x07\x17\xaa\x6f\x2e\xff\x04\xb5\xff\x18\x4f\x2f\x45\x28\x3e\x71\x56\x63\x7c\xe9\xee\x5c\xe8\x91\x67\x95\xe8\x48\xa7\x9e\x8f\x62\xfc\x04\x3a\x11\x88\x90\x77\xca\x37\xd7\x4b\x4b\xa2\xd3\xd0\x8b\x25\xfb\xf5\x0f\x6f\x75\x1c\x89\x4c\x40\x2a\x24\x6f\xae\x55\x59\x21\x13\xb2\x17\x8c\xfc\xbf\x7f\xfd\x8f\xff\xeb\x7f\xf0\x87\xa8\x80\xf7\xa6\xd8\x83\xc8\x33\x84\x96\x77\xbc\x0c\x93\xcf\x0e\x3a\xd1\x96\xff\x44\x8a\x06\xf6\xbf\xcb\x3b\x28\xfe\x93\x1d\xfc\x0d\x18\xa3\x8c\x1b\x9d\xd6\x68\x7c\xb6\x69\xfa\x41\x8d\x31\xe1\x41\x2c\x10\x6b\x74\xc6\xda\x2d\xf7\x08\x37\x97\x1f\x30\xcf\x95\x41\x78\x90\x24\xc2\x5a\xdb\x2f\x57\xf8\x8f\x91\xbd\xcb\x83\x14\x90\x3b\x4d\x8b\xcb\xc2\x34\x50\xad\x8b\x87\xac\x38\x37\xdd\xc6\xce\xa9\x62\xb6\x18\xc7\x22\x85\x67\xca\xa7\xa7\xf6\xf4\xf8\x56\x58\xac\xa4\x67\x7a\x7e\xc8\xb4\xb6\x7b\x9a\xf2\x00\x28\xce\xd2\xc4\x7f\x28\xcb\x4f\x8b\x91\xd4\x2f\x8a\xe3\x09\x67\xc2\x62\x46\x16\xb9\x7a\x85\xe3\x67\xef\x80\x81\xc1\x2c\xf4\xc1\x19\x8c\xe3\xef\xc2\xc3\xc8\x78\xb9\x0f\x24\xe4\x52\xe3\x01\xc4\x23\x4a\xb0\xf0\x7b\x59\x16\x43\x3e\xb9\xb6\xc1\x5a\x3a\xde\xc2\x8c\x5d\x3d\xcc\xb8\x53\x6a\x01\xbd\x56\x9b\xb0\x82\xac\xcb\xb1\xf2\x48\xc4\x5e\xf4\xb5\xa3\x35\xb4\x08\x84\xc0\xf5\x88\x89\x15\x39\x39\x74\x3a\x30\x1b\xd4\xa5\xde\xc2\x3b\x2e\xac\x1d\xb4\xd1\x45\xd5\x68\x77\xa0\x61\x18\x68\xb0\x93\x6e\x5f\x3a\x4e\x30\x7f\xe5\x84\x27\x38\x72\xef\xca\x3c\x2f\xbb\x5f\x79\x44\x88\xd3\x2c\x6a\x6f\xc8\x74\xbf\xa7\x21\x22\x7b\x6e\xd7\xfb\xee\x27\x65\x79\x13\x3d\x0b\x53\x23\x72\x5b\x0c\x3c\xbb\x8a\x72\xae\x05\xa2\x6b\x8e\x90\x37\xe8\xb1\xce\xae\x9f\x9c\x83\x46\xe2\xc0\xe7\xc7\xdd\xd3\xfd\xed\x01\x25\xe1\x6c\x79\xf9\x6e\xfd\x4f\x9f\x0d\xe6\x69\x48\xb8\x03\x1a\x17\xa0\x9a\x43\x53\x1e\x8a\x52\x0f\xc8\xda\x08\x4f\x53\x8a\x55\xa8\x5b\xf8\x9d\x55\x30\xfa\x1e\x82\x19\xb0\x2e\x79\x2e\x2e\xfb\x0f\x87\xb5\x9a\xc2\x39\x46\xff\xdf\x1d\x29\x23\x8a\x85\x2f\x8b\xf5\x37\x9b\x32\x1e\xa0\x9b\xb9\x92\x80\x79\x0e\xab\x17\x71\xf3\xcd\xff\xae\xa5\x12\xd0\xfb\x2a\x48\x5d\x6d\x19\xf1\x5d\x07\x88\x15\x96\xca\x21\xd8\xf5\x98\x15\x5f\x71\x67\x13\x6e\x02\x83\x8b\xa9\x0d\xa7\xf8\x1a\xf7\x4f\xfa\xea\x04\x4b\xf8\xbe\x97\x47\x40\xa5\xb3\x99\x08\x05\x37\x3a\x65\x7a\x80\xb8\x77\x85\x95\x33\x0e\x71\x1a\xc4\x80\x46\x47\x47\x28\xd3\xf4\x42\x09\xbe\x8b\x90\x18\x5a\x12\x5a\xfb\x1d\x70\xf6\x54\x94\x58\x2c\x53\xa6\xbb\x7d\x22\xa5\x44\x21\x1a\xef\x15\x31\x70\xcb\xb2\x1f\x98\x29\xe5\xdc\x2b\xac\x3c\xfe\xdc\x23\x90\x6f\x7c\x5d\x2a\x53\x74\x78\xb5\x47\x4d\x1e\xba\xbd\xf5\xd0\xf4\x54\x43\xbe\xb7\x52\x18\x67\x45\xe0\xe1\x27\xc2\x84\x24\x65\xcc\x12\x36\xbf\x74\x05\x14\xc3\xcd\x31\x65\x2a\xc1\xd0\x58\xc7\x98\xf7\xd9\x5a\x38\x1c\x43\x69\x14\x58\xc0\xf2\xb8\x28\x69\x94\x8e\xf3\x05\x0b\xe3\x98\xc7\x98\xa3\xca\x75\x8d\x43\xcf\x66\xce\xbb\xdd\x69\x6c\xf3\xa4\x71\x90\x62\xba\x02\x5d\xb5\x4d\xf6\xf2\x72\xb9\x11\x85\xcf\x5b\xa7\x49\x20\x35\x77\xf2\x82\x28\xaf\xbb\xbe\xed\x9a\xb8\xc4\x74\xb5\xc5\x70\x60\x8c\xa0\x0b\x9b\x4e\x51\x4c\xa3\xb7\x9b\x28\x89\xe1\x76\x18\x16\x09\x91\x94\x47\x32\x22\x8e\xfd\xe9\x5b\xd6\x5a\x8e\xd5\x27\xab\x45\xca\x85\x65\xcd\x35\x19\x56\xac\x2e\xf3\x0c\x11\x54\xd6\x92\xd9\x8b\xfa\xed\x8f\x69\x7f\x3b\x72\x6e\xb2\x3c\xcf\xca\xa2\x7e\x11\xfd\x65\x53\x6e\xcd\xfb\xbb\xf2\x5c\x68\x0b\xef\x1c\x42\x73\xd3\x34\xb5\x9f\xf1\xc5\xa6\xd1\xac\xae\x52\xfd\x5c\x4f\xa4\x4c\x48\x2a\x68\x98\xba\x88\x0f\xfa\xde\xd3\x68\x40\x2a\x58\xa0\xc3\x0e\x47\x8f\xa2\x15\x62\x16\xb0\xf6\x5f\xfe\xf5\xa7\x4d\x6d\x2c\xa7\x86\xe6\x5b\x5e\x4a\x0b\x1c\x19\xb8\x5f\xa9\x80\x10\xd3\x3e\xf5\x49\xa8\xf1\x10\x15\xc6\x16\x98\xe6\xe5\xcb\x9c\x12\x14\x49\x65\xa0\xf4\x88\x66\xfc\xba\x3c\x20\x95\x01\x24\xd1\x20\xd2\x6c\x97\xbe\x29\xc4\x3f\x55\x41\xcc\x55\xef\xc0\x1d\x50\x0f\xce\xdf\x88\x62\xd6\xad\xae\xa1\xb1\x40\xa3\xff\xd8\x37\x33\x1a\x37\x2a\x49\x10\xea\x7d\xf8\x91\xfd\xce\x86\x4b\x76\xaa\x85\xc2\x16\x8c\x69\xbc\x6e\xcb\xf3\xcb\xeb\xae\x29\x8b\xe9\x9d\x6a\xc9\x24\xf4\x12\x80\x23\x28\x5c\xaa\x0d\xc3\x20\x40\xa6\x4a\x1f\x54\x72\x2d\x26\xe0\x58\x1c\xfc\xb0\x5b\xee\xff\x16\xd6\x92\x1a\x4a\x70\x74\xe3\xb4\xef\xd8\x8d\xe7\xd1\xd7\x9f\x84\x7a\x52\xc3\x52\x16\xb8\x7d\xf6\xae\x12\x33\x80\xaf\xd4\x24\x09\xe6\x19\x76\x20\xf2\x29\x5e\x25\x35\x29\x47\x87\x6c\x57\x94\xbf\x35\x14\x0b\xe4\xed\x71\x8d\x22\xa0\xd2\x85\x9c\x71\x6f\x78\xc8\x3e\x2b\x66\x11\x41\x9c\x20\x4f\x42\xad\x2a\x31\xd6\xd3\x22\x22\x48\x52\x64\xf6\x5e\x54\x0d\x7c\x0c\x3f\x86\xa0\xc2\x16\xae\xce\xcb\x08\xff\x77\xa1\x76\xc1\x62\xeb\x01\xdd\x3f\xff\x5c\x0f\x4b\x37\x04\x8b\x43\xaf\xff\xb9\xc8\x73\x2b\x1e\xea\x9b\xb8\x45\x87\xb8\x94\xb2\xee\x7e\x17\x11\xc6\x06\x90\x14\x7b\x44\x3d\x45\x04\x93\x56\x17\x13\xc1\x3a\xb7\x65\x33\x2d\x05\x11\x4c\x72\x74\x37\xd7\xcb\xa7\xc3\xc3\xfa\xb1\x17\x4c\x26\x22\x0c\x64\xec\xb4\x78\x17\x9e\x5e\x68\x32\xea\x45\xe4\x28\xdc\xa7\x0c\x02\x58\x01\x75\x05\x51\x77\x07\xc5\x21\xd5\x72\x70\x90\x69\x6d\x6d\x63\xa3\x68\x9f\x7c\xaa\x84\xa5\xe8\x20\x7d\x83\xe6\xb9\x86\x6a\xad\x3f\x49\xd8\x88\x24\xb6\x0a\x4f\x77\x4f\xcf\x8f\xb7\xab\xed\xee\xf0\x73\xb5\xb3\xc2\x95\xf7\xeb\xbb\x3b\xff\x68\x89\xb6\x50\x86\xfb\xf2\x05\x5d\xcf\x11\xde\xd3\xf5\xe1\x4c\x61\x3a\xb3\x83\xe9\x5b\x2e\xc0\xdb\xdd\xc1\x07\x17\x9a\x6b\xa6\x3f\x3f\xc4\x05\x17\x80\xe8\xd0\xba\x11\x6f\x30\x92\x8e\x1d\x3f\x58\x1a\xa9\xc4\x02\x9f\x35\xc0\xf1\xeb\x4c\x80\x3f\x24\x31\x26\xc0\xb4\x53\x03\x3e\xdd\x8e\xa5\x44\x59\xf1\xe2\xa5\x36\xfd\x83\xa6\x92\xa2\x4f\x75\x14\x1f\xd9\xf1\x7c\xec\x40\x20\xae\x59\x04\x44\x85\x9e\x5e\xc0\xfa\xd2\x74\xf2\x42\x45\x4a\x30\x17\xa8\x5c\xb0\x71\xe9\xbb\x4e\xb5\x0b\x89\x10\x22\xc1\x74\xbd\xb0\x55\x7d\x0e\xf1\x3b\xee\x23\xc3\x20\x8e\xbd\x36\xa1\xd7\x0b\xd8\x57\x97\xf6\xdf\xfe\xae\x64\x1c\x60\xe5\xf0\xfe\x61\x90\xdc\x11\x52\x6b\x84\x88\x0f\x45\xb0\x71\xc8\xb4\x6f\x77\x9c\x16\x9b\xbc\x30\x95\xd0\x88\x0d\xc2\xe5\x8d\x68\xbc\xfe\x76\xdb\x18\xab\xc4\x73\x75\x37\xd6\x54\x9e\x83\xe8\x09\x1d\xdb\xe9\x80\xec\x8d\x96\x5e\xb4\x29\x1b\x18\xc0\x8f\x47\x0b\xae\xd0\x9c\x61\x70\xfc\x2e\x17\x52\x0a\xff\x2b\x04\x01\xba\x18\x3f\xb2\xba\xee\x0a\x65\x89\x80\x30\x0a\xe4\xc0\x08\xae\xbb\x86\xd8\xd6\xa2\x64\xf5\x1d\xd6\xa5\x59\xb5\x0c\x07\x8f\x42\x8b\x7f\x7e\x81\x31\x91\xad\xec\xc7\x40\xee\xfe\xda\xf3\x1d\x3f\x9b\x11\x51\xe4\x68\xfa\xb1\x02\xfb\xa1\x2c\x5a\x5b\xd8\x23\x34\x1c\xeb\xa7\x1f\xdc\x32\x48\xd2\x48\x0d\x6c\xe6\x2f\x4d\x76\x49\xa3\x54\x39\x6a\xf7\x91\x90\xce\xd8\x09\xff\x82\xb7\x87\x48\x9a\x28\xcc\x0d\xdc\xc2\xb9\xb6\xa5\x54\xb8\xfd\x7c\x76\x41\x1e\x23\xdf\xc2\x66\xf1\x6d\x35\x74\x9c\x24\x4d\x6d\xde\x04\x01\x08\x0b\xad\x5b\x4b\x70\x10\xf0\x95\x54\x87\xa9\xea\xa8\x67\xac\x3b\x3a\xb9\xc4\xff\x45\x3d\x5a\x80\x4f\x95\x74\x66\x97\x02\xc9\x88\xf4\x19\x23\x2b\xd0\x3c\x91\x97\x20\x92\xc5\x56\x43\x76\xf9\x7d\xb5\xfc\xf1\x22\x8e\x12\xaa\xfd\x6f\xef\x25\x4b\x96\x0a\x74\xa0\x85\xd6\x76\x84\x59\xeb\xea\xef\xcc\x2a\x7f\x34\xc8\x74\x18\x9c\xf6\x8c\x40\xe3\x79\x29\xc3\x84\x23\x25\x41\x2e\xea\xc6\x42\xb2\x9f\xde\xa1\x12\xfd\xbb\x09\xb9\xe1\x3e\x16\x66\x6d\xc4\x3f\xce\xd7\x2c\xe8\x44\x46\x89\x0c\xc7\x14\xa0\x57\x1f\x7c\xbe\xb8\xee\xef\x7e\x9e\x5c\x26\x8d\x02\xd4\x2d\xef\x7d\x72\x19\x69\x5b\x44\x52\x9c\x8f\x0f\x7e\x66\xc9\x98\x80\x82\x6e\x43\xbd\x07\xd3\x7c\x17\x9d\x61\x26\x63\x6a\x84\xc5\x8b\xa0\x3d\xde\x45\xcf\xba\x8f\x17\x87\x14\x43\x14\xbe\x70\xf5\x7a\xa3\x90\x49\xa2\x85\xdb\xb2\x57\xc7\x53\xe3\xf2\x7b\xbe\x51\x10\xc4\x79\xc1\x31\xb3\x0a\x49\x99\xba\x2f\x5f\xe6\x7c\x42\x99\xa8\x10\xe9\xae\x5d\x68\x7f\x31\xa0\x2d\xf5\xcb\x81\xe4\xd2\x6a\x93\xb7\x6b\x58\xa6\xfc\xaf\x29\x13\x28\x0d\xd2\x6e\xe0\x9b\xed\x6a\xb7\xb8\x5f\xd1\xae\x2d\x01\x1c\x5b\x42\x6b\xb4\xd6\xe6\xc7\x68\xaa\x39\x22\x80\xdf\x6a\x75\x33\x64\xbc\xde\x97\x2b\x55\xd6\x97\xba\x81\xab\x24\xd6\x1c\x80\x66\xf0\xcb\xe8\xd1\x44\x02\x88\xe7\x9e\xd8\x4c\xd3\x2f\x3e\x75\xab\x26\xbf\xfb\x93\xb5\x9b\xab\x8b\x13\x66\x4d\xf6\x1f\x28\x96\xaf\xa2\xf5\x22\xa1\xca\xea\x26\x53\x13\x53\x52\xb6\xfb\x89\x0b\x30\xfc\x84\xaa\x6e\x3d\x20\x94\x68\x2d\xab\x2b\xa1\xe8\xe9\x95\x54\x88\xe1\xf5\xb3\xe5\xdf\x78\xc8\xa6\x68\x7b\x29\x80\x44\xf1\x80\x24\xcd\x6b\x22\x62\xf6\x16\xf4\xf3\xdf\x20\xdc\xa4\x94\x31\x3a\x37\xad\x95\xb0\x14\xa7\xac\x4f\xd0\x4a\xa5\x00\xd9\x9f\x97\xd5\xe5\xd4\x94\x8b\xa6\x3c\x76\xa3\x40\x69\xea\xf4\x60\x0b\xfd\xd5\xce\x27\x35\x31\x02\x15\x31\xe0\x7d\x5c\xe7\x24\x81\x32\x70\x83\xd6\x26\xe6\x32\x18\x97\x63\x4a\x88\x53\x1e\xb9\x9d\xfa\x26\x6b\xfe\x2c\xab\xdd\x59\xa9\xe1\x29\x62\x81\xd5\xd5\x42\xeb\x47\xf8\x6d\x4b\x4e\xe7\x6a\x12\xfb\xdb\x01\xd0\xda\x21\xc0\x9f\xae\x36\x30\x1f\x55\x96\x26\x88\x11\x49\xdb\xf8\x5a\xb1\xd1\xbe\x2a\x4d\x20\x43\x97\x95\xdb\xdd\x8c\x9e\x9b\xb8\xeb\xa8\x20\x20\x18\xdd\x6b\x4f\xbf\x38\x65\x57\x9c\x46\x5f\x14\xf8\xa9\x20\x92\xdc\x25\x4b\xc7\x40\x33\x1b\x66\x70\xbd\x48\xc4\x02\x97\xa2\xb0\x24\x7f\xb3\x68\xeb\xae\x37\x80\x13\xeb\xcb\x97\xab\x8f\xf1\xca\xab\x68\xaa\xa8\x53\x49\x9e\xb3\xad\xc6\xaf\x50\x51\x19\xe3\x54\x17\x45\x76\x14\x1d\x7d\x7f\xfb\xbb\x46\x03\xc2\xaa\xc3\xc3\x7c\x86\xd4\xf5\x65\xcc\x52\xf4\xb7\x8b\xde\x6b\xeb\x25\x4d\x99\xcd\x89\x62\x91\x8d\x9a\xbc\x80\xcd\xb8\x57\x22\x1f\x0f\x20\xc5\xc0\x72\x8e\xff\x2c\x5b\xbb\xd3\xb2\xf7\xce\x6e\xc7\x8a\x41\x88\x73\xc4\x29\x55\x7c\x4a\x6d\x4f\x54\x48\x6d\x04\xe1\x5c\x58\x86\x2f\xbf\x0a\x75\x17\x0d\xa9\x12\xde\x7a\x44\xfa\x29\xf7\x7b\x94\x10\xe3\x62\x04\xf7\xa2\x6e\x76\x0d\xe4\xf9\x44\x5a\xf8\xd3\x39\xa8\x22\x08\x91\x0c\xd4\xed\x8c\x3b\x64\x47\x1e\x8a\x18\x8f\xa3\x51\xdd\x51\x51\x2c\xdd\x3e\xf7\xb7\x9c\x8e\xb3\xce\xb1\x3b\x51\xac\x42\x34\x8f\x7c\xca\xbd\x35\x67\x7f\x65\xcd\x6b\x87\x74\xf8\x9a\x80\x73\x12\x7d\x52\x09\x0f\xb1\x48\x13\x63\x55\x25\xbe\x06\xd7\xc2\x53\x4b\x81\xdb\x5e\xe0\x1f\x67\x38\x7f\x62\x3e\xa9\x94\x10\x32\xe4\x74\x5f\xe4\xf9\x80\x4c\x9f\xa8\x34\x4c\xa8\xe3\x24\xab\x1b\x51\x34\x45\x1f\x6d\x52\x22\x90\xb8\x36\xdf\x2e\x9e\x3e\x19\xc0\x82\x06\x18\x27\x79\xa9\xe0\x32\x9c\xfe\xbe\x39\x64\x88\xce\xfd\xe6\x8c\xa5\xa1\x76\x8e\xef\x12\x5b\xd2\xb3\xda\x4b\x32\x7b\xf9\xb4\x49\x3f\x49\x13\x2c\x57\x76\xa2\xdb\xed\xb6\xbf\x2a\xf4\xee\x94\x67\x9f\x64\x53\x94\x14\x9c\xb5\xef\xee\xe6\xe9\xf9\x71\xff\xd7\x61\x71\x7b\xbb\x5d\xed\x76\xfe\xd9\xa4\xa1\x9c\x5f\x87\x2e\xc7\x81\xa5\xd9\xd4\x92\x92\x26\x02\xa7\xd5\x3e\x8f\xde\x55\x10\xcb\x30\x19\xaa\xc7\x8e\xe4\x5e\x88\x32\xca\x60\x62\x7d\x7d\xbb\xf8\x36\x0c\x47\xe8\x80\x45\x3e\x2c\x87\x6c\x2d\xd7\x4c\x52\x44\x13\x65\xa3\xc3\x96\x4b\x9a\x1c\x32\x55\xa2\x52\x8b\x57\x4f\x1f\x46\x04\x34\x4d\x85\x21\x1e\xd9\x35\x23\x0f\x4d\x34\x35\x96\x82\xb6\x0b\x31\x8f\x97\x06\xcd\x48\x8c\xcf\xf2\x2a\xea\x1d\x56\xc7\xfd\x2c\x9b\x69\x38\x51\xb3\x88\x60\x89\xdc\xfa\xbd\x74\x31\xe8\xee\xf0\x48\x49\xea\x31\x53\x97\x55\xf3\xba\x2e\xa6\xc7\xc6\xca\x04\x3e\x85\x61\x03\xf6\x4e\x6c\xc7\x33\xde\x7c\x05\xb8\x71\xc2\xe2\x84\x7e\x22\x7d\xe9\x2f\x92\x26\x30\x60\x35\x18\x6d\x42\x3a\x24\x96\xca\xa9\x80\x8f\xa6\xee\xc1\x6f\x3a\x24\x0c\x17\xf3\xac\x7e\x28\x0b\x68\x5e\xc5\x6c\x94\x42\x87\x54\x1a\xa7\x81\x7e\x93\x0b\xf5\xe6\x79\x70\x26\xbd\x84\x75\x0b\x64\x59\xbe\xb5\x2b\xc2\x7d\x66\xe6\x8b\x7f\x27\xe9\xc6\xff\xfb\xd7\xe4\x51\x42\xd0\x88\x47\x38\x64\x35\xf2\x61\xdc\x67\xc7\xac\x7f\x14\x23\x74\xd8\xa1\x1b\xdc\x22\x78\xb5\x9d\x0d\x87\xb3\x8e\x09\x67\x72\x90\x5c\x5b\xf5\xce\xf2\x78\x46\xe9\x38\x61\x11\x1b\x2c\x6e\x56\x7b\x71\xfa\x55\xc6\x27\x4f\xad\x7c\xf9\xe3\xea\xc6\x1b\xf1\x3a\xe1\x96\xe6\xba\xce\x5e\x0a\xd0\x8b\x79\x28\xc2\x97\xcb\xe4\x3c\x32\x7a\x3c\x09\x35\x4f\x34\x38\xd3\x62\x7b\xb3\x58\xce\x7f\xbb\x34\xb0\x9c\xd4\x4a\x58\x70\x97\x15\xa1\xf5\x77\x9a\x72\xe9\x75\xa3\xec\x4c\x1c\x7f\x89\x34\x65\xc4\xf9\xc2\x58\xb7\x68\xad\xb7\x6b\x98\x7a\xff\x06\x85\x90\x68\xeb\xd9\xdd\xd3\x62\x6f\xc6\x3d\x64\x28\x6d\xee\xa7\xdc\x57\xd9\xcb\x8b\x25\x13\xf7\xf7\x23\x63\x1b\x3a\xde\xff\xb5\x59\x1d\x56\x7f\x6e\xee\x9f\xb6\x1d\x8c\x56\xcb\x14\x90\x4b\x03\xb9\x8c\x39\x9f\x9e\x57\x73\x34\x1e\x0d\x40\xaf\xec\xe8\xda\x80\x30\xe4\x46\x6d\x30\x45\x8d\xa2\x24\xab\xce\xab\xd2\x90\x00\x06\x56\x33\x85\xf1\xc8\xee\x67\x27\xa2\x54\x94\xda\x0a\xbc\xd9\xdf\x81\x50\x45\x1d\xa7\xa6\x2d\x0d\xf0\xbf\xa7\xca\x1b\x21\xbb\xa6\x12\x0d\xbc\x5c\x86\xe1\x7d\x60\x69\xac\x46\x04\xad\x7f\x95\xe7\x0a\x43\x42\x63\x81\x14\x02\x0c\x28\xaa\x6c\x21\x33\x56\x47\x21\x4e\x20\x24\x06\x95\xa1\x0e\x79\xa9\x44\x7e\x97\x79\xce\x36\x67\xc1\xfa\xcf\x06\x11\x09\x91\x8a\x29\xab\xbb\x42\xe5\x3f\xc6\x1d\x92\x50\x44\x9e\x44\x0d\xb9\xee\x3e\x19\xe4\xa3\xb1\x0e\x91\xb1\x91\xae\xb2\x80\x83\x12\x95\x7f\x53\x10\x33\x62\x73\x4f\xa5\x86\xc1\xf6\x0a\xb1\x48\x82\x64\x68\x9c\xb6\x96\xdb\x2c\xa2\x14\x12\x19\x60\xd1\x93\xf2\x64\xec\x9b\xaa\x2c\xcd\xd4\xe1\xf1\x4b\x05\xf1\xd6\x37\x24\xd2\x60\xb9\x2f\x56\x33\xbc\x4f\x09\x6a\x09\x70\x6e\x7a\xd1\x06\xd0\x2e\xaf\x3e\x26\x4c\xf2\x5d\x55\x82\x6f\x77\x09\x55\xd3\xe5\xd5\x80\x83\xc4\x4a\xa6\x5b\x18\x91\x33\x40\x4a\x0d\x66\x06\x31\x54\x5d\x6f\xa0\x42\xfa\xb9\xae\x35\xb5\x44\x90\xbd\x92\x2f\x72\x1f\xef\x4e\x00\x7a\x18\xf1\x84\x14\x52\xcc\xc0\x5a\x80\xc8\x98\xc7\x71\xfc\x86\x52\x10\xb8\x03\x6d\x26\x92\x5f\xd7\x4b\x45\xe7\xeb\x43\x0a\x90\x0c\xb2\x3c\x6b\x55\x8e\xf6\x05\x10\x44\x60\x49\x87\x8d\x20\xdd\xc2\x14\x87\x07\x42\x44\x68\x36\x43\xa5\x68\xb0\xf4\x2a\xe0\x04\xa4\x26\xb8\x6e\xe4\xe5\xcb\x22\xcf\x07\xa4\xf9\x04\x20\xe0\x81\xee\x30\x6d\x08\x7b\xc0\x1c\x54\x59\xad\x8b\x49\xc0\x78\x70\xa7\xc0\x69\x92\xf4\xbc\x76\x08\xe0\x9c\x35\x3d\xc0\x90\x00\x79\xcb\x76\xc8\xd3\x68\xb2\xe6\x8a\x9d\x94\x80\x49\x09\x0a\xc6\x3a\x14\xd8\xa1\x41\xf0\xe1\x97\x18\x3e\x13\x10\x12\xba\x32\x0b\x8c\xd9\xdb\xa1\x3a\xb1\x03\x4c\x10\xd1\x81\xf2\xe8\x23\x7c\x34\xdf\x6c\x91\xeb\xa2\xd0\x0f\xe2\x03\x53\x8d\xcf\x45\x93\xe5\xed\xcf\xab\x4f\xb4\x68\x89\x09\x92\x40\xa7\x1e\x4a\xe2\x5f\x9d\x09\x52\x3a\x2a\x53\xb8\xba\xe3\x01\xda\xd9\x04\x46\x21\x52\xe8\x20\xb4\x5d\x97\xf7\xa5\xa3\x84\xbd\x0a\x58\x8c\xaf\x4d\x92\x00\xb3\x09\x53\xc2\x7a\x62\x88\xd1\x9e\xbe\x74\x59\x65\xad\x97\x6d\x21\x2b\x93\x77\x40\x23\x86\xf9\x30\x67\x6a\x6c\x07\xa9\x43\x43\x13\x85\x01\xa4\xac\xfe\x25\xaa\x2a\x2b\x2b\x0b\xc3\x9f\x9c\x40\xd9\xa5\xfa\xb7\x77\xaa\x41\x5b\xcb\xab\x87\x34\xfa\x9e\x3a\xc1\xca\x89\x3d\xe4\xf0\x22\xda\x4e\xe3\x2f\x6d\x98\x30\xae\x42\xe7\xd8\xee\xb1\x67\x9d\x35\x25\xfa\x24\xb8\x20\x38\xc0\xc5\x02\xe9\xe6\xe7\x0c\x05\x77\x96\x50\x50\x1c\xce\x7d\xb5\xe7\xaf\x61\x01\xcb\xfc\x8c\x34\xa1\xb1\x80\xdb\xac\x43\x97\x3c\x74\xf1\x7f\x13\xb1\x10\xad\xca\xd2\x15\x0f\xbb\x75\xb6\x87\x79\xae\x8b\x0d\x54\x3e\x26\x66\xe2\x20\xc1\x57\xb2\x2c\xb3\xe2\xd0\x05\x88\xba\x56\x10\xb8\x75\x08\xbf\x9c\x5b\xc0\x55\x7f\xbb\xff\x9f\x6a\x70\x67\xda\xdd\x75\x12\x2a\x31\x70\xfd\x08\xbf\x37\xaf\x9e\xda\x94\xfb\xc6\x38\x08\x3d\x7f\x6f\xb3\xbb\x1c\x65\x99\x8f\xbc\x70\xc3\xa3\x00\xe2\xbf\x4f\x35\x0e\xd7\xa9\xd1\xfe\x62\x52\x41\x89\xb3\xe5\x31\x9a\x8d\xa9\x0f\xcf\x18\xd2\xf5\xe1\xd6\x16\xc5\xe0\xce\x57\x9f\x27\x55\x69\x07\x8f\x9a\xd6\x7e\x19\x11\x58\xe4\x6d\xe7\x35\x6a\x71\x54\x03\x08\xb4\x11\x49\x8c\x59\xbf\xfa\xb5\xac\x1a\x2b\xe3\x33\x89\xd4\x19\x91\x28\x1e\x76\xab\xe7\x16\x3e\x83\xbd\x19\xc1\x21\x71\xfe\x54\x55\xe6\x79\x7f\x8d\x34\xb0\x38\x99\xa6\x3c\xad\xeb\xfa\x9c\x15\x2f\xeb\x42\x67\xef\x99\x3e\x8b\x7c\x14\x49\x35\x32\x54\x8e\xf3\x00\xd6\xca\xa9\x4a\x0e\xe0\x1a\x46\xc6\x89\x9a\x11\x60\x72\xad\x2a\x92\x16\xc3\xbb\x7e\x3c\xdc\xac\x6f\x0f\x77\xdb\xc5\xf2\xb0\x7f\xf2\xb9\x53\xa3\x13\x8a\x5c\x69\x1b\xd1\x3a\x9e\xf5\x0d\x40\xd1\x2e\x4b\x23\x63\xd0\x68\x99\x78\x38\xee\x1d\x72\x26\xfa\xa3\x41\x50\xe6\xc3\x1c\x77\x22\xcb\xf7\xc3\xd0\xc0\x2b\x14\xbb\xa6\x3c\x9d\xba\x04\xb0\x31\xc4\x8a\xd3\xe7\x59\xf1\x76\x9b\x55\xa0\x9a\xfc\xf2\xc7\x17\x72\xd9\xc4\x18\x65\xc3\x3b\xb7\x50\x34\xa2\xfd\x4a\x5d\x05\x35\x76\xa0\x41\x20\x04\xa6\x25\x11\xb4\x87\xeb\xd1\x8d\x6f\x22\x4c\x28\xc7\xd1\xe3\x71\x7f\x5f\x6e\x04\x34\xa0\xd4\xaa\x64\x1f\xb3\x22\x3b\x9e\x8b\x95\xdf\xd5\x69\xc0\x18\xc5\x84\x0c\xf2\x10\xe1\xb6\xe3\x1b\x22\x1b\xe8\x39\x0a\x0d\x9e\x2d\xe0\xae\xac\x3e\xc9\x8f\xce\x5b\xfc\xfd\xda\x4e\x03\x66\xac\x36\x6b\x5d\x9a\x46\x89\x13\x19\x01\xb6\x69\x10\x6a\x89\x65\x54\x7d\x11\xfb\xea\x7e\xbf\x9c\x44\x26\x69\x10\xa9\x08\xe9\x9c\xb2\xa2\x39\xb7\xab\xab\xc9\xcb\xdf\x7f\x8c\x9f\x35\x32\x96\xe9\xb0\x1d\x74\x75\x87\x5a\xa6\x41\x4c\x62\x5c\x10\x5b\xeb\x53\x21\xb4\xeb\x6f\x16\x16\x7f\x5c\x98\x86\x1d\x7a\xf2\x20\x11\x38\x37\xf7\xd8\x6e\x50\xb5\x07\x68\xf4\x17\x72\x30\x0d\x0d\x26\x77\x17\xc7\x96\xf8\xe7\x66\xb9\xec\xbe\x67\x2c\xa9\x97\xd8\xbb\x2f\x5f\x26\x07\x24\x94\xa1\xed\xe1\x4b\x02\x7f\xc2\x6b\xa6\x72\xd8\x9d\xc4\x27\x52\x82\x83\x43\xc3\x00\x03\xa9\x03\x52\xe1\x25\x74\x0a\x9b\x34\x48\x22\x85\xc0\x23\x79\xbe\xec\x96\xfb\x1f\xb3\x6b\x0e\x0d\x12\x19\xd9\xaa\xa0\xed\xda\x1f\xc8\x99\x4d\x06\x5a\xe2\xac\xbb\xb2\x42\x65\x81\x45\xa1\x9f\xce\x8d\x2a\x27\xfc\xb3\xdc\x1f\x94\x38\x62\x8c\xbb\x61\x89\x21\x0d\x78\x2a\x13\x04\x62\xac\xbe\xdd\x5f\x13\xc6\xd0\x20\xe5\x3a\xf4\x75\xa8\xde\xcd\xb8\xcb\x4b\x2c\xa3\x19\x15\x7e\xf9\xfe\x69\x88\x41\x36\x0c\x3a\x81\xae\x47\xa1\x11\x1a\xa4\x2a\xc6\x44\x48\x6b\x0b\x88\xc6\x51\xa9\x74\x8d\x90\x42\xdc\x11\xc0\x65\xc7\xf3\x71\x72\x72\xc1\x22\x8c\xbc\xad\x3e\x4e\x25\x56\xe4\x79\x41\xdb\x59\xf5\x8d\xc1\x71\x51\x60\x57\x2b\x4f\x16\x8d\x72\x24\xfe\xb2\x22\x56\xc9\xd0\x47\xbf\x2b\xab\xc3\x97\xf9\x62\x1a\x88\x94\xa3\xe3\x88\x14\x30\x83\x85\x91\x06\x92\x0a\x5c\x8b\x0e\x03\xc6\x72\x1a\x48\x90\xa2\x97\x6b\x3c\x96\x0f\x59\xe1\xa1\x08\xab\x49\xa2\x9d\x06\xca\x18\xa5\x3d\x5e\xbd\x6e\x3f\xf0\x12\x25\xc7\xbe\x8a\xe2\xd2\x40\x53\x6e\x0b\x93\xb3\x02\xb3\x8e\x08\xcf\x9e\xbf\x7b\x4d\x0d\x46\x18\xac\x3a\xaf\x95\xcb\xf5\xbc\x50\x9e\x54\xc9\x77\x0d\x23\x16\x76\x9f\x64\xf7\x5b\x9c\xc6\x70\xec\xae\x9b\xa5\xa7\x42\xfd\x0d\x9b\x13\x1f\x99\x55\x34\xd0\x2a\xc6\xca\x08\x4b\x8e\xb9\x5f\xce\x6e\x6c\x34\x80\x80\xf2\xce\xd6\x3f\x17\x8d\x0f\x8d\x8d\x4f\x06\xb1\x0a\x1c\xe7\xf2\x41\x83\x11\xe7\xbc\x39\x58\xcb\x5c\xe4\x07\x3d\xc7\xa4\x4f\x03\x10\x01\xb5\xb2\x27\x9d\x2c\x6f\x39\xbd\x49\xa3\xad\x18\xc2\x00\x5a\x36\xbe\x3f\x12\x50\x8a\x56\x95\xb5\xd6\x77\xd0\x34\x39\x58\x1a\x98\xba\xc9\x9a\x6b\x50\x08\x25\x01\x23\x68\xdf\x6f\xca\x46\x94\xf5\xcd\xb9\xd3\xa9\xa4\x84\x48\x89\xa6\xe6\x93\x4b\xc7\x23\x36\xd8\x37\x52\xc2\xd1\xee\xfd\x76\xfb\xc3\xff\xc4\x52\x11\x38\xd5\xc1\xc6\x94\xd5\xd1\x6f\x0c\x8f\x70\x3e\x8a\xea\xcd\x32\xd0\x0c\xe8\xdd\x28\x09\x23\x8d\xf8\xbe\x17\x71\x04\x5b\xf1\x32\xac\x18\xa4\x24\xe4\xa9\x0e\xfb\xf2\xcc\x39\x4f\x9a\x92\x10\x62\x2b\x1f\x7d\x2a\x7f\xd3\xf9\x21\x45\x22\x19\x72\xe6\x41\x82\xb6\xcc\xe3\x01\xaa\xb7\x1c\x46\x5e\xf7\xff\x5d\x49\x6e\xba\xc3\x63\x1a\x45\xde\x4f\xe8\x28\x85\xe7\x53\x25\x5f\xfd\x71\x67\x4b\x20\xc4\x5c\xfe\xf6\xdb\x77\x8f\x30\xa1\x84\xcb\x14\xfd\xfa\xf6\x55\x0c\xdc\x4b\x4a\x38\x48\xc4\x26\xee\x9e\x6f\x1e\xd6\xbb\xdd\xfa\xe9\x71\xbb\xfa\xb5\xd8\xde\xfa\xf6\x94\x04\xa4\x0f\x40\xdd\x01\xb4\x13\xb2\xab\x52\x7b\x43\x13\xab\x81\xea\xdd\x67\x2e\x29\x49\x85\xc2\x65\xaa\x7e\x2d\x7f\x3f\x5c\x7e\x96\x4d\xf7\x3d\x52\xa7\xaa\x2e\xb4\xde\xa9\xb2\x1a\xd1\xd2\x51\xd2\x9a\x7f\x3d\xe1\x85\x53\x62\xb8\xb9\xf8\x02\xa0\x85\x0b\xde\x5f\x51\x8d\x7e\x99\xdf\xa1\x44\x32\x82\x65\x95\x26\xab\x50\x04\xb5\x79\x32\x5d\xb9\x7a\xbd\x1c\xd6\xd1\x51\x22\xa5\xc2\xa4\x6b\x6b\x79\x1d\x32\x94\xdb\x3b\x98\xac\xd0\xad\xf7\xf2\x3d\x2b\x9a\xd6\x3f\xb5\xf0\x88\xef\x20\xf4\x1f\xa3\xeb\xa8\x90\xfb\xfa\x95\x8e\xfd\xc0\x37\xc9\x94\x77\x95\x23\x59\x59\x3c\x88\x8f\xa5\x38\xf9\x56\x2d\x43\x3f\x0a\xff\x71\x86\xea\x32\xde\x33\x88\x06\x82\xcd\x37\xe7\xcb\xac\x75\x3e\xfe\xf8\x26\x8c\xd0\x86\x6e\xc7\xf3\x80\x8f\x7a\x68\x79\x52\x62\x62\x86\xd8\xb6\xef\x0f\xc3\xcd\x90\x06\x31\x45\xe2\xac\xbb\xec\xe3\x06\x1a\x46\xba\xdf\x85\xe6\x69\x17\x22\x76\x69\x60\x73\xce\xa7\x7e\xb1\xef\x2e\xd3\xc8\xc5\xed\x56\xb5\xaa\xca\xdf\xe8\x7b\x1c\x6a\x8b\xac\x1f\x7d\x9c\x76\x0a\xe2\xfe\x6b\x89\xcf\x26\xec\x2e\x9f\x06\x62\x28\x25\x40\xa8\x0b\xb8\xdd\x88\x89\xd5\x42\x69\x12\x62\x63\xeb\x06\x38\x55\x59\x9b\x54\x99\xf6\x13\x90\x0c\x14\x62\xad\x13\xd0\x0d\x06\xca\x92\xc0\x18\xa4\x23\x69\xe0\xc3\x11\x00\xfa\xb6\x30\x06\x5b\x16\x67\xab\xdc\x07\x81\x09\xdf\x21\x21\x98\xd6\xb3\x83\xb9\x23\x00\x19\xad\xab\xbd\xa8\xf2\x5c\x26\x8e\xd2\x28\x4c\x53\x5f\xaf\x57\xc1\x3b\x2a\x7c\x8c\x2e\x12\x45\x3a\x0d\x7a\xca\xf9\xdd\x6b\x66\xe5\xc3\xc7\xb7\x12\xf1\x24\x0d\x7b\x97\xde\x87\x04\x5a\x6f\x02\xb3\x0f\x33\x59\x78\x4a\xe3\x84\xe0\x2e\x7c\xb0\xc2\x1f\xa5\x7a\x7b\x1e\x57\x00\x53\x1a\x73\xbb\x0d\x89\xaa\xc9\xea\xa6\x5e\x54\xcd\xef\xb2\x7a\x9b\x67\x02\xa6\x34\x16\x29\xae\x4a\xfb\xed\x63\x0f\xeb\xa3\x34\x89\xec\xc6\x98\x97\x2f\x18\xc7\xc3\xd2\xab\xae\x51\x6a\x4c\xe4\xdf\x56\xe2\xa5\x2c\x86\x87\xf1\x28\x8a\x5d\x20\xbd\x97\x04\xe7\xa3\xf5\x84\x72\x61\xb0\xcc\x01\x89\x90\xd6\x75\x2e\x0a\x3d\x3c\x45\xca\x52\x54\x08\xbb\x2f\x5f\x9c\x28\x3e\x64\x75\x7d\xfe\x44\x0f\xac\xdd\xf8\x20\x1a\x14\x91\x8f\x29\x05\x28\x15\x49\x10\xb9\xd2\x8f\xef\x65\x6d\xa1\x1c\x73\x33\x94\x0a\x9e\x5a\xca\x2f\xbf\x08\xb5\xce\x57\x4f\xa6\x47\xa9\x24\xd2\xf3\x93\x88\xaa\x12\x97\x43\x3e\x00\x66\x50\x2a\xb9\x4a\x90\x71\xeb\xc7\x6a\xfb\xb8\xba\x3f\x6c\x16\x8f\x6b\xbf\xcc\x53\x88\x02\xa4\xcc\xd8\x40\x21\xf2\x66\x5e\xcc\x8d\x52\x50\x0a\x2b\xf1\x3a\xd9\x6e\x91\xe7\x07\x81\x60\xe3\xd1\x27\x66\x41\x18\x63\x99\x93\xee\x17\x33\x16\x24\x0a\xf3\xaf\xf7\xcb\xc5\xee\x7b\xf7\x23\xa7\x98\x6c\xc5\xd5\x7e\xf8\xb8\x2c\xd0\x21\x77\xfe\xc5\x77\xa8\x4a\x4f\xa8\xbb\xfa\x38\xdd\x95\x15\x72\xc9\x3e\x8f\xc1\xd7\x94\x91\x98\x0a\x17\xcc\x73\xaa\x59\x03\x05\xc2\x7a\xda\x59\x58\x11\x88\xf7\xb2\x81\x5d\x21\x4e\xf5\x6b\xd9\xb8\xba\xc0\xc5\xb9\x29\xbf\x66\xb6\xa7\x8c\xc6\x36\x42\x33\x85\xf5\x8f\x53\x86\x2e\x5a\x42\x19\x35\x96\x79\x6e\xb7\x59\x3c\x74\x2b\x05\x63\x24\x44\x03\x7b\xf5\x61\xab\x45\x5c\xf8\xf0\x9f\xbf\x96\x5f\x1b\xd2\x8c\x49\x2b\x92\x23\x4e\xa7\xd6\xfa\x19\x51\x5d\x50\xc6\x54\xcc\xe3\x2e\xd6\x5e\x5d\xb5\x26\x98\x86\x2d\xe0\xa3\xc9\xcb\xa6\x18\x5a\x36\xc8\x55\x89\x9b\x5e\x59\xb5\x56\x11\x9a\x56\xfb\x51\xb0\x9a\xb2\x88\x59\x0e\xa3\x0a\xea\xf3\x11\xbc\xc4\x9e\x6f\x8c\x03\xa4\xa5\xfa\x27\xc8\x4a\xcc\x96\x05\x9c\xa7\x54\xc1\x94\xc5\xcc\x66\xb1\x4f\x88\x10\x24\x5d\x4a\xa8\x6d\x81\x60\x84\xde\xed\xc9\x92\x71\xc6\xdf\x0c\xb8\x73\xe7\xf7\x71\x16\xc7\xc4\xc4\x3d\x8c\x77\xcc\x1f\xda\xf5\x01\x61\xf3\xaf\x4f\x0f\x6b\x5b\x1a\x3e\x9e\xa6\x2c\x8e\x0d\x0e\x97\xa3\x78\x83\x7d\x79\x14\x4d\x39\x61\x17\xa4\x2c\x4e\x01\x61\x00\xdf\x7c\x99\xf4\xed\xa5\x10\xc7\x4c\x6d\xdb\xbd\x7b\x7e\x46\xb1\x84\x01\x6e\x39\xcb\xed\x6a\xb1\x5f\xdd\x1e\x76\xfb\xc5\x36\xf4\xd7\x4c\x12\x8a\x39\x13\x9b\x93\x68\xba\x28\x13\x65\x89\x8e\x19\xda\x1b\x2f\x70\xdf\x05\xd3\x28\xe3\xcc\x92\xcf\xfe\x12\xf5\xeb\xa4\xfa\x81\x32\xae\x38\xeb\xb9\x04\x6e\x6f\xfe\xd9\x4e\x2b\xc7\x47\x39\xfd\x46\x5f\x8f\xbe\x34\x52\xd4\xab\xa1\x88\x0b\x7c\x8a\x34\xf1\xdd\xb9\xe5\x64\x02\xbd\x2c\xab\xe9\xfa\xc7\x52\x4d\xf1\xb6\x7e\x03\xbc\x6d\x2c\xe4\x62\x92\xf4\xa7\x4c\x44\x10\x0c\x8a\x95\xbd\x89\xc3\x44\xc2\x5c\xf4\xde\xca\xae\xae\x3f\xe5\x8b\xe9\x0e\x10\xb8\xb4\xff\x6f\x79\xa9\xc0\xcb\xbb\x50\x26\x94\x40\xa9\x28\xb4\x48\x2d\x70\xee\xb1\xd4\xdd\x9b\x93\x44\xe2\xa4\x18\x48\xd7\xf7\x10\xa3\xab\x1c\x0a\x65\x92\x2a\xe4\x3f\x79\x58\xfc\x79\xd8\xae\xee\x57\x8b\xdd\xea\x70\xdb\x09\x05\x50\x26\x15\x27\xbc\xcf\xb1\x20\x27\xdf\x2c\x15\xf2\x78\x5f\x67\x12\x2c\x6b\x8f\x12\xc5\x66\xe0\x26\x33\x69\xac\x06\x6f\xa6\x4a\x8c\x16\xd3\x91\xce\x14\x65\x8a\x06\x18\xb6\xc3\xe0\xe9\xa6\xf9\xe8\x7e\x8f\x52\x84\xf1\x2f\xcb\xe3\xb1\x9f\xc1\x4a\x46\xa9\x65\x3b\x57\xa5\x0d\x9a\x67\xef\x48\x41\x3c\xf6\x8b\x7d\xd5\x5d\xea\xcc\x37\xa6\x23\x15\x73\x87\x2e\xdc\xf4\x2b\x8a\x56\x11\x52\xd4\x3c\x74\x3c\x74\xf3\xa3\x44\x83\xd5\x34\x3f\xbc\x40\x73\x0f\x2f\x50\x68\x51\x5d\x36\xf9\xb9\xde\x0a\xcc\x20\x0f\xa3\x55\x4c\x1b\x8e\x45\xe7\x0f\xeb\xfb\xfb\xf5\xd3\xa3\xe3\x11\xf1\x97\x84\x84\x60\x98\xa1\x39\x57\xc5\x93\x31\x4b\x51\x58\xdb\xfb\xae\x2a\x8b\xe6\x57\x56\xe8\xf2\xb7\x25\xcc\x39\xa2\xd8\x6e\x3b\x3b\xfd\x91\x82\x19\x2c\x4e\x7c\x2d\x9b\x72\x0f\x1f\xdd\x28\x05\x23\x94\xf6\x72\x66\x0e\x41\xb0\x13\xa6\x83\x9a\x7d\x0d\xb6\x72\x27\x31\xb1\x41\x81\x4b\x5f\x5b\xf2\x74\x77\xb7\x5b\xed\xfd\x25\x0c\xa4\x54\xf9\x60\x47\x6b\xd1\x34\x4d\xf5\x45\x91\xd4\xff\x6b\x65\x1c\x0d\x49\x68\xe9\x79\x96\xa2\xda\x8b\x8f\x6c\x26\x52\x10\x12\x1e\x45\xdc\x97\xa1\x58\x8f\xa7\x43\x4b\x7d\x19\xbe\x0b\x69\x28\x84\xab\xbc\x1e\x12\x9a\xd2\x90\xa6\x1c\xad\xe2\x45\x6b\x9a\xdc\xc2\xd1\xbf\xf3\x90\x85\x82\xc2\xa0\x2a\xe0\x8f\x19\xec\x08\x0d\x59\x6c\x0b\xa7\x3d\x8a\x0a\x23\x58\xd9\x9c\x06\xd3\xac\x4d\x1c\xfa\x5d\xaf\x0f\xd5\xce\x73\xaa\xd1\x30\x64\x1a\xcb\xda\x75\x5f\xa1\xd1\x6e\x83\x56\xf5\x75\x30\xad\xc2\x88\xc5\x4e\xe0\xbe\x13\x2e\x39\x74\x6d\xae\x32\xe2\x68\x75\xd5\xe7\x89\x2f\x68\x18\x73\xee\x4b\xe8\xad\xdc\xf3\xe4\x3b\xc4\x52\x28\x57\x44\xf8\x4d\x1c\x61\x7d\x32\xd3\xbb\x4d\xb4\x35\x75\x2f\x3b\x14\x72\xee\xbd\xb2\x90\x87\x5a\x74\xb7\xb7\xec\x2b\x75\x9e\x8b\x7e\x05\x0d\x79\xcc\x13\xe1\xa3\xb8\xea\x6d\x37\xc0\xdd\xbb\x1e\x29\xb5\x04\xb8\x88\xa6\x40\x7c\xe4\x78\xef\x0c\xd3\x48\x45\xdc\x15\xce\xa1\x85\xd6\x5e\x09\xba\x2b\xa4\x49\x84\xc5\x11\xfb\xc5\xe8\xee\x44\x14\xb9\xb2\x98\xe6\x41\x7c\x0c\xe4\x0e\xb9\xef\x20\x03\xa4\x2d\xc2\x54\xc9\xd3\xe3\xb3\x9f\xdd\xa1\x0c\x02\x1e\x75\x23\xe1\x26\x2f\x5f\xba\xa2\x44\x1a\x4a\x2e\x74\xa7\xa6\xdb\x1a\x07\xf7\x65\x53\xcf\x17\x7d\xb5\x9d\x35\x16\xc9\x60\xa9\x16\xb8\xf2\x08\xd7\xa6\x62\x81\x7a\x37\x3f\x6e\x7e\x06\xa4\xfb\x51\x32\xdc\x3e\xbc\xac\xaa\xb5\x25\xba\x56\x13\x79\xa1\x2e\x1f\xa5\x44\xf6\xce\xe5\x75\xe4\x2f\xd4\x22\x8e\x4d\xe7\x5b\x61\x70\xb3\xe7\x7a\xf5\xcb\x5c\xa8\x35\x93\xce\xa2\x47\x90\x09\x54\x38\x7b\xfe\x98\x18\xa3\x21\x28\x8d\xdf\x08\xa5\x0e\xc9\x24\x7a\x1f\x05\x40\xb0\x82\x78\x23\xde\x56\x3f\x1c\xbb\x27\x8d\x90\x7a\x78\x80\x1f\x16\xaa\x19\x64\x52\x22\x92\x02\x06\xcd\xb0\x1e\xb5\x4f\xbd\x44\x34\x32\x41\x3a\xd1\x91\x6f\x3d\xc2\xdb\x12\xea\xc7\xd2\xea\x12\xf9\xdf\x9f\xcc\x43\x59\xc1\xfe\x55\x14\xf8\x33\xe8\x9b\xcb\x2d\xe6\x8f\x3b\xa7\x20\xa2\xa9\xa5\x13\x1b\x56\x67\xb5\xbb\xea\xf8\x09\xa8\xe4\xc6\x12\x86\xb4\x4b\x3a\x16\x9d\x3b\x0c\xd4\xa4\x23\xa3\x09\xe2\x2c\xa4\xd0\x2f\x9f\x84\x71\x23\xa6\x94\x36\x8e\x1d\xf6\xb1\x3c\x4e\x6b\x48\x69\x14\xc6\x06\x1d\xa5\xef\xe2\x78\x84\x0a\x19\x00\xfc\xed\x86\x1a\x10\x16\xb5\xde\xef\xc6\x7b\x6c\x14\x45\x96\x69\x49\x67\x75\x6d\x95\x1a\xc6\x27\x8d\xb8\x65\x8c\xc1\x0d\x04\xf3\xa9\x83\x10\xdf\xe7\x19\xa8\x28\x0e\xb5\xcd\x6d\x6b\x28\x9a\xcc\x64\x50\xed\x4b\x1b\x6d\x1c\x0d\x95\x28\x8e\x42\x01\x9d\x62\x84\x4b\x9e\xdc\x8f\x57\xac\x28\x91\x9a\x79\x88\xa4\x35\xa5\xca\x6a\xa0\x3e\x32\x9a\x1d\x51\xa2\xad\x95\xf2\x2a\xea\x2d\xd4\xa7\x12\xe9\x25\xc7\x17\xe5\xc4\xf8\xf1\xb9\xa8\x9a\x76\x8f\x6c\xae\xa0\x1a\x34\xe2\x40\xa3\xc8\x03\x6f\xad\xe3\x78\x03\xa6\x1d\x19\x53\x48\x03\x8d\x04\x49\x4d\xbf\xcc\xfb\xa9\x15\x09\x99\x22\xc7\x8a\x3c\x67\xb9\x5e\xbe\x8a\xea\xa5\x2b\x56\xa5\x91\xd0\x0c\x0d\x96\xe7\xbc\xa9\xc4\x63\x1f\x36\x8c\x84\xd6\xa9\xb5\x48\xf2\xfc\x56\x64\x77\x65\xf5\x19\xe2\x90\x46\x8a\x46\x96\x85\xd6\xba\x33\xc3\x9a\x06\x1a\x29\x16\x29\xf7\x04\x38\x0f\xeb\xd9\xf5\x24\x52\xc6\x25\x62\x4e\x79\xe6\x25\xd4\xfd\x29\xb4\x20\xe8\x9c\xdf\x23\x50\x07\xd3\x9f\xe3\xd8\xd2\x1c\x64\x92\x46\xda\x68\x1c\xac\xbf\x45\xd6\x34\x83\x44\x34\x8d\x40\x19\xc4\x7a\x09\xad\x6d\x69\x5b\xc7\x08\x35\xeb\x81\x46\x86\x31\x34\x3e\x70\x00\x3e\xd7\x50\xdd\x5c\x46\x6e\x5d\x64\x52\x83\x04\xda\x0e\xf7\x8c\x01\xf1\xc9\xd4\x88\x83\x98\xa1\x25\x7c\x68\x3f\xa2\xab\x85\xa4\x71\xc0\x29\x02\x12\xd6\xe5\xb9\xfb\x49\x4b\xe4\xb1\x6e\x37\x9b\xf9\xf0\xa3\xeb\x48\x88\x53\xea\x6d\xc4\x0b\xd0\x51\x62\x2b\x26\x51\x88\x11\x8f\x76\x03\x45\xfd\x37\x1b\x98\xf4\x64\x70\x34\x26\x0e\x26\xfa\xad\xcc\xf5\x8d\xdd\x9e\x91\x71\xb0\x6b\x4f\x19\x26\x26\x2c\xa5\xb4\x65\xc0\x1f\x13\xce\xbb\x8e\x94\x06\x89\x05\xea\xf9\xb5\xcb\x56\x26\x38\x43\x77\xf4\x99\x63\x1a\x06\x56\xc6\x11\x11\x67\xad\x77\x9c\x35\xbb\xd7\xb2\xbf\x6f\x1a\x12\xe2\x72\x26\x22\xcf\xf4\x02\xe3\x9e\x5e\x4c\x74\x54\xe8\x31\x8b\x21\xa6\x31\x35\x3a\x15\x9e\x69\xb6\x80\xcb\xe4\x6e\x59\x1c\x18\x70\x16\xfa\xd1\x16\x1d\x5c\x33\x33\xd1\x38\x64\x11\xb2\xc2\x78\xf6\xfd\x76\x99\x47\x74\x4f\x8d\xd9\xa4\xef\x9f\x16\x19\x7d\x6d\x3f\xc6\x61\xc8\x1d\x8d\x24\xee\x5d\xe8\xea\x62\x50\xb0\x6c\x5f\xec\xfc\x13\x85\x82\x85\x0e\x87\x67\xbb\x75\xbf\x73\x0c\xa3\xbc\x9e\x0b\x5d\x81\x6e\x7d\xdc\xee\xeb\x45\xd2\x44\x72\x60\x18\xda\x2b\xed\x4b\x7b\x82\xf1\x3d\x45\x2a\x44\xe8\x83\x6c\xd4\x24\x77\x1a\xc7\x91\x31\xd2\x47\x43\x5b\x87\xa6\x99\xbe\xcf\x38\x16\xcc\xe5\xc5\x5c\x05\xeb\x93\xfc\xb7\xaf\x60\xbd\x66\x0f\x19\xa3\x3c\x69\x1c\xf3\x04\x43\x03\xe5\x40\x7b\x81\xc6\xb1\x63\x1a\xfe\x25\x8a\xf9\xf0\xfb\xe4\x1e\x8c\x44\xa6\xbc\x81\xfc\xca\x78\xd4\x25\x81\x26\xc1\xb0\xe6\xba\xac\xea\x83\xed\x3d\xed\x29\x28\xae\x56\x76\xb7\x6c\xc7\x86\xe5\x62\xf4\x77\x96\x68\xe9\x93\x93\x2e\x21\x73\x83\xdb\xe5\xf8\x8b\x71\x4a\x3a\x81\x87\xf3\xe9\x74\x69\xdd\x11\x34\x20\xa7\x6b\x02\x0f\x49\x6a\x13\xf6\xf3\xdc\x56\x5f\x06\x07\xe2\x94\x58\x56\x3b\x1b\x95\xb8\x17\xf5\x90\x10\x60\xe6\x35\xa4\x51\x8a\x69\xa7\x87\x87\x51\x0e\x22\x4e\x63\x91\x76\x86\xdf\x49\x34\x59\xbf\xf6\xc6\x22\x49\xd1\xb5\xac\x85\x81\x07\xd1\xbc\xee\xce\x72\x7e\x17\x88\x45\xa2\x11\xfd\x78\xbf\xfa\xb9\xba\x3f\xb4\xfe\xfb\xcf\xc5\xfd\xf3\xaa\x3b\x91\x34\xca\xb1\x2d\x42\xd1\x1c\x8e\x67\x9f\xbb\x8a\x65\x60\x83\xab\x37\xe7\xcb\xa6\x02\xcb\x4d\xa7\xde\xbc\x78\x30\x9f\xac\x20\x92\x58\xc6\x64\xac\x84\xb0\xfa\xfd\x95\xee\x33\x3b\xb1\x4c\x04\x2e\x20\xbf\x3c\xf6\xed\x93\xc5\x53\x99\xd8\xa6\x9d\x4a\x14\xfc\x9d\x7c\x41\xad\x63\xaa\x87\xc4\x9f\x98\xbf\x83\xa1\xd9\x12\x03\xb7\x1a\x07\x2f\xd0\xec\xcf\x55\x81\xac\xd7\xe3\xb3\x18\xa1\x62\x18\x21\x68\x5b\x4f\xa4\x1b\x4c\x46\xdb\xbc\xd1\x51\x7c\xa0\xe9\xd6\x3f\x45\x12\xf0\x34\x8e\x47\xd3\x0a\x0d\x97\x7d\xe9\x80\xf8\x57\x52\x23\xfe\x38\x63\xf9\xcc\x5c\xb4\xe7\x7b\x79\xae\x61\x2f\xde\xa0\x83\xcb\xd3\x84\x04\x89\xc1\x58\xb8\xa8\x7c\xea\xb4\x6b\x8a\x6c\x8d\xc4\xb9\xb6\xbc\x9d\xc8\x18\x3e\x93\x9f\x4d\x48\xbb\x9b\x39\xd3\xd3\x72\x81\xc3\x4c\x9d\x2e\x4d\xa8\xa4\x98\x5e\x14\xd6\x86\xb5\x00\x49\xff\xfc\x09\x63\x02\xab\x44\x5d\x74\xff\xa6\xfb\x3d\xb6\xa6\xd1\xe7\x7c\xbc\x34\x61\x92\x90\xa0\x43\x09\x8c\xa4\xec\xfd\xeb\x4f\x42\x92\x22\x2e\xe7\x11\x40\xd7\x83\x34\x44\x12\x52\x2e\x3d\x1d\xf4\x50\x8b\xd8\x35\x47\x01\x8b\xdc\xb9\x95\xa8\xb4\x18\x1b\x2c\xf3\x93\x31\x89\xa9\xe5\xbb\x7d\xaf\xd4\xc8\x36\x48\x62\xce\xa4\x4b\x34\xaf\xd7\xeb\xc3\x96\x4d\xae\x16\x83\xc0\xc8\x3b\x4a\xb1\xb7\x66\x4f\xfb\xe6\xb3\xe2\x9c\x35\x97\x81\x6b\xc7\xe8\xff\x8c\x8e\x4a\x98\xc4\x58\x81\x7a\x6d\x2f\x56\xbc\x00\xea\xa4\x5c\x65\xef\x7a\x9b\xf8\xda\x3e\x4e\x12\x29\xb5\x73\xba\x9e\x5b\x5f\x9b\xac\x8b\xe6\x8e\xb9\x2d\xe0\xae\xbb\xcf\xff\x99\x1d\x69\x3c\xd0\xb8\xe8\x22\x05\x4a\x6b\x24\x14\xbe\x16\x68\x50\x8b\xfa\x77\x88\xce\xd9\x5a\xe0\xd1\x3d\x72\x29\xa8\x2b\xee\x78\x3c\x1f\x91\xe9\xac\x77\x90\x13\xae\x52\x9c\x82\x0d\x54\xc7\xac\x40\x78\x44\x6e\x6e\xc1\xa2\xef\xbb\x4e\xda\x26\x4f\x90\x8e\xa9\x73\x77\x93\x34\xa4\x68\xb5\xb6\x1b\xf1\x2c\x6b\x4a\xdb\x85\x23\x15\x5e\xcf\x04\x8f\xbb\x01\xea\xc0\x75\xa7\x49\x0c\xee\xc2\x06\xe5\xd1\xbb\xd2\xae\x1d\xfa\x12\xf5\xc2\x7e\x13\xe2\xcf\x28\x92\x18\xf3\xb4\x87\x5e\x0b\x64\x36\xa1\x9b\x88\x34\x64\xa2\x47\x72\x8f\xb3\xb4\xae\x8f\x4c\x23\xcc\x17\x3c\xef\x6e\xff\x1c\x0e\x6f\x15\xd8\x9a\x5f\x04\xb9\x3a\x0e\xe0\x2e\x04\xe5\xfb\xa8\x04\xdd\x19\xcf\xfa\x5d\x34\x76\x9e\x8f\xaf\x00\xcc\x7a\x5e\x56\xf1\x11\xe9\xce\xaf\x6b\xd2\x7d\x5f\x23\x03\x8c\xc1\x61\x34\x27\xcf\x8e\x59\x53\xf7\xb3\xc0\x04\x12\x6b\x37\x4f\x65\x9e\xef\xb3\xe6\x6a\xce\x19\xc5\x98\xb5\x22\x9f\x4f\xaa\x7f\x16\x1e\x24\x12\x4d\xef\x4d\x75\x39\xc2\x87\xad\x79\xb8\x16\x84\xf9\x64\xdf\xf4\xe7\x48\x29\xda\xc9\x9e\x31\x79\x71\xbf\xea\x4e\x2f\x38\xeb\x8a\xc9\x47\x65\x58\xae\x03\x49\x22\x0c\x5e\x02\x82\xb2\x77\xd9\x4b\x31\xcd\xc9\x72\xa2\x42\xac\xb1\x69\xef\xa8\x5e\x4c\xc4\x6e\xb0\x19\x23\xc8\xe7\x93\x05\x99\x7f\x36\x17\x86\xcb\xe7\xff\x5b\x74\x92\x13\x1d\x25\x16\xb8\xee\xc3\x12\xad\xdd\xfe\xad\xab\x66\xa1\x9c\x06\x3a\x72\x39\xdc\xf3\xe9\x17\x64\x4b\x71\x9a\x2f\x64\xa7\xad\x5f\x82\xf0\x3d\x9b\x5e\xfb\x92\x7a\x73\x72\x20\xd7\xc8\xab\x7c\x23\xe5\x7f\x99\xc4\xe2\x34\x15\x38\xd1\x9e\x4e\xad\x25\x5e\x74\xc5\x79\xbe\x59\xd8\xb2\x91\xac\x03\x16\x5b\x34\xc7\x2f\xc8\x7c\x17\xc6\x34\x06\x6a\x30\x8c\x33\x7b\xa3\x13\xd3\x93\x33\x13\xa3\xcf\xd6\x88\xda\x4f\x66\x1e\xc6\x14\x93\x19\x2f\x65\x8e\xb6\xc5\xa0\x6a\x8f\xf2\x50\x27\x4e\x1f\xa3\xd0\x5b\x30\xfb\x9f\x13\x1f\x96\x87\x46\x63\x64\x1d\x53\xda\x7f\xcc\x41\x45\x79\x94\x32\x34\xb5\xb4\x0b\xa0\xde\x3a\xf6\x97\x3b\xa1\xba\xca\x72\xca\x23\x50\x08\x59\xb4\x5e\xeb\x43\x56\x34\xa0\x6f\xcf\x15\x16\x7d\x43\xa7\x32\x43\x79\x64\x42\x0c\x9c\x7c\xeb\xa3\x03\x22\xb7\x90\xae\xf1\x9d\xc5\x32\x26\x96\xcb\xc9\x26\x7b\x3e\x0d\xb9\x8f\xbf\x64\x6c\x64\xe2\x10\x1f\x6d\xaf\xc7\x12\x0b\x3d\x66\x83\xc4\x3c\x51\x56\x6a\x2e\xab\x77\x58\x31\x78\x73\xb9\x42\x48\x0e\xd6\x75\x9e\xe8\x40\x77\x4a\xfb\xa3\x58\x60\xdb\x84\x49\xc7\xfa\x77\xd6\xa8\x57\xa7\x96\x39\x79\xa0\x44\x4b\xf4\x89\x5a\x23\xde\x3e\xf0\xfc\x13\x70\x90\x98\xfd\x5a\xbe\x66\x05\xd4\xb0\x2c\xcb\xb7\x7e\xfb\xe0\xa9\x63\x59\xc5\x85\xe1\xf0\x73\xb5\xdd\xad\x9f\x1e\xfb\xc6\x14\x57\x1e\x2c\xf1\xfd\x94\x50\x65\x6e\xa4\x75\x81\x03\x9e\x46\x16\x96\xb5\xda\x7e\xef\x4e\x0b\x41\x10\x76\xec\x53\x43\x4b\xf7\x8b\x0d\xd2\x2f\xb2\x3c\x35\x52\xf8\x88\xb2\x28\x36\x15\xbc\x5f\x97\x27\x52\x2e\xa8\x42\xeb\xd5\x41\x06\x3b\x6d\xe9\xf9\x77\x24\xb8\x52\x8e\xd1\x7a\xdb\x6e\x5e\xe7\x2b\x62\xca\xd6\x5c\xb2\x62\xf4\xef\x16\x21\x86\xa7\xec\x5e\xa3\x0a\x00\xe3\x33\x50\x68\x3b\x3e\x07\x56\x32\xd7\xc4\x4a\x6f\x1f\x7a\x23\xf8\x17\x40\x37\xe3\x34\x37\x89\x8b\x65\xaf\x8a\xd6\x16\x1b\xa8\xf2\x53\xae\xa5\x25\xc4\x68\x97\xe7\xb2\x59\x16\x23\x52\x4d\xca\x41\x03\xc2\x49\x6e\x17\x77\xff\x7c\x1a\x7b\x8a\x9f\xfc\xb5\x07\xa6\x01\x4d\x11\x99\x59\x67\x2f\x45\x6b\x94\xde\x66\xe2\x58\x16\x7a\x5e\x86\x7a\xca\x9a\xe4\x0b\x9e\x47\x6f\x31\x0d\xa4\xc5\x05\xbd\xd8\x0a\x41\x74\xea\x33\xad\x3b\xb5\xaf\xf1\xfe\x9e\x06\x0a\x30\x10\xe0\x51\xde\xc3\x4a\x09\x9a\x06\x26\x22\x6e\xe2\xad\x9d\x34\xd9\xf8\x13\xa7\xa4\xfd\x9f\xbd\x1c\x86\x99\xb3\x09\x8d\x0e\x4d\x91\xc5\xa8\xfb\xac\xc3\x39\xe4\x97\xc3\xfe\x45\xa7\x94\xc4\x69\x17\xe1\xb2\x9a\xcb\xb3\x66\x6e\x4a\x65\x42\x86\xd4\x09\x4b\xef\x86\xfd\x31\x3c\x9b\xd2\x6c\x20\x9d\x7b\x2b\xb2\xfc\x72\x57\x01\x6c\xca\xac\x5b\xd4\x53\x46\x0c\xda\xc5\x39\x98\x86\x4c\x9e\x8e\x45\x01\xd8\x5a\x88\xb2\x82\x2b\x35\x84\xc9\xc7\x64\x3a\x08\x92\x3e\x64\x74\x8b\xe1\xc1\xe3\xdf\xee\x56\xf3\x6b\x5e\x1a\xb2\x00\x2b\x27\x1a\x10\xc7\x4e\x3f\xdd\xdf\x73\x98\x10\xea\x70\x00\x8b\xac\xba\xf5\x5c\x41\x68\x71\x96\x97\xe1\x2b\x08\xb9\xfd\x82\xff\xb8\xcf\x8a\xb7\xa1\x93\x95\x86\x42\x22\x6a\xda\x1b\x95\x37\x8d\x9a\x11\x5f\xa7\x69\xa8\x2c\xbc\xc7\x61\x0e\x4a\x75\x3e\x7e\x56\x9d\x43\xd3\x88\x5b\xdc\x55\x7b\x07\x7b\xeb\xd1\x32\x3a\xbc\x9f\xc8\x58\x72\xbc\xe2\x7c\xf4\x95\xc5\xfd\x42\x98\xc6\x09\x20\x3c\x3b\xab\x9f\x72\x0d\xd5\xe7\x72\x03\x34\x8d\x85\x25\xcb\x1f\x48\xa4\x6d\xa0\xaa\xcb\x2b\x8d\xb4\xc9\x1d\x26\x60\x23\x52\xef\x48\x5e\x62\x83\x95\xfd\x8b\xe5\x91\x15\xc8\xfd\x77\x79\x99\x83\x90\xa4\x5c\xd9\xd4\xe8\x0b\x34\xb7\x65\x01\xdb\x81\x56\xcd\x9c\x69\x9c\x72\xb0\x75\xca\xdf\x44\x21\x2c\xc1\xf6\x08\x9c\x3e\xff\x68\x69\x60\x13\x60\x15\x86\x39\x9d\x34\x58\x59\x2d\xf3\x0c\x3e\x21\xb4\xa4\x69\x2a\x34\x5a\x2e\x1b\x71\x3a\xd7\xaf\x62\xf4\xa5\x05\x65\x88\x2d\x18\x33\x3a\xf8\xb5\x3c\x15\x34\x81\x51\x65\xf1\x38\x06\x99\x0a\x6e\xeb\x27\x9e\x6f\xd6\x8b\xfd\x62\xbb\xb9\x5f\xfc\xd5\x73\x45\xd2\x54\x12\xe5\x91\x8a\x9e\x2f\xa6\x6b\x8a\x52\x14\x22\x37\x22\xcf\xa5\x98\xe6\x53\x52\xc9\x0d\x82\x6d\x2e\x50\xcf\xe4\xd7\x52\xd9\xda\xe2\xa3\xa8\x85\xe5\xfc\xf0\x67\x57\x41\x1a\xb9\xa0\xe0\xbd\x13\x88\x11\x7a\xa2\xe5\x44\x53\xa5\x14\x5a\xc5\xef\x3e\xba\xb1\x81\x6a\xcc\x85\x48\x53\xa5\xd3\xc8\xd1\x44\x1d\x0a\xf8\x68\x0e\x59\x03\xc7\x43\x56\xb4\xa3\xa3\x81\x83\xa9\xca\x23\xfe\x34\x1f\x18\x4d\x15\x10\x69\xf5\x3f\xf3\xaf\x46\x6c\xbb\xd2\x3a\x5d\xee\x7d\x36\x75\x3c\x52\x4d\x04\xf3\x9c\x4b\x5b\x00\x1c\x76\x97\x6f\xe7\x3e\xce\xda\xf6\xe0\x23\xba\xff\xab\x78\x48\xaa\x19\x0b\x3b\x3e\xd0\x01\xfa\x3a\xd5\x91\x09\xcc\x48\x19\x4d\x0f\x09\xf9\x7c\x2f\x11\xe0\x62\x6e\x69\x9d\xec\x18\x9a\x47\x13\x75\x07\xd8\x8a\xd1\xb2\xc8\x2f\x08\x67\xa9\x1e\x7a\x30\x63\x0a\x42\xe1\xda\x73\x42\x40\xcb\xa0\x54\x9b\xa6\x86\xc5\xe8\x32\x62\x56\xf8\xb0\x5f\xaf\xb6\x07\x7a\xb8\x5f\x3f\x78\x46\x37\x9a\x9a\x48\x22\x9a\xf1\x36\x13\x4d\x79\x74\x8c\x68\xf3\x6f\x56\x90\xd8\x84\x96\x29\xd1\x59\x70\xa3\xef\x23\x28\x11\x03\x65\x29\xa8\xd6\xc5\x7b\x36\xd4\xbc\x1e\x9f\x8c\xaa\x48\x07\x63\xcd\x84\x71\x34\x5a\x50\xa3\x85\x5d\xe8\x51\x36\x17\x2b\x50\x5d\x42\x73\x16\xf8\x20\x58\x0c\x18\x0d\x83\x76\x0f\xb5\xde\x57\xbf\x24\x0a\xc6\x63\x9f\x29\x40\x4a\x05\x57\x87\x22\x26\x02\x9a\x54\x30\x61\xcb\xe7\xef\x17\xf7\x36\x11\x3f\xb9\xaf\x90\x72\xcc\x33\xca\xf3\xc5\x47\xc9\xd7\xc5\xe6\xcf\x7b\xe7\xfa\x8f\x57\x0c\x11\x46\x16\x97\x20\xb4\x9e\xcb\x6b\x5c\xad\xed\x22\xa2\x44\x39\xf8\x05\xc6\xd1\xf6\x25\x96\x0d\xce\xbf\xc5\x88\xda\x4a\x9e\xbb\xa7\xed\xa1\xf7\x14\x44\x14\xda\xba\xc7\x5b\x50\x22\xcf\x8a\x8f\x41\xb8\x40\x44\x91\xb4\x92\x3d\xbf\xc5\x09\x0b\x4c\x3b\xd2\x09\x2a\x22\xae\x6d\x9d\x35\x3a\x81\x07\x85\x4b\xe1\xe1\x38\x17\x92\x13\xb1\x14\xc6\x7a\x9f\xc8\x6a\x2d\xea\x4e\x5f\x84\x8a\x84\x48\xf4\xb3\x17\x39\x88\xe1\xb5\x13\x01\x8e\x44\x1d\x89\x4e\x87\xca\x4d\xbe\x87\xb6\x45\xa1\xee\x9d\x77\xc6\x40\x57\x52\xd3\xbb\xda\x22\x81\x10\xa3\x2b\x50\xd6\x37\xb8\x94\x3e\x19\xdf\xc4\x03\x46\xd3\x41\xb5\x88\xcf\x55\xf5\x72\xe4\x54\xf0\x88\xe3\x80\xb8\x83\x4a\x0d\x6f\x92\xa7\x80\xf1\xc0\x47\xf8\x68\x6e\x84\xbc\xac\x3f\xc1\x5b\x0b\x2e\xa5\x5f\x39\x07\xe8\xd9\xb5\xae\xbf\x2a\x0d\xa5\x82\xeb\x10\x17\xa8\xc5\xed\xcf\xc3\x40\xda\xa9\xbb\x3c\x24\x58\x0f\x77\xf2\xa7\x6c\xe0\xe6\x7c\xc1\x75\xdd\xf5\x48\xa9\xad\xe9\x54\x15\xe8\xcc\x6f\x23\x13\xb2\x70\x2a\x52\x6d\x89\x83\x6b\x68\x6c\x74\x0a\x47\xfd\x64\xac\x8b\x34\xc2\x78\xdb\xb3\xab\x36\xca\xf3\xc5\x0b\x14\x56\x1d\xa4\xac\xe6\xf9\x46\xa9\x10\xc0\x30\x4b\x70\x5f\xbe\xb4\xab\xdf\xbe\xb4\x70\xbf\xd9\x81\xcd\x07\x76\xa7\x10\x26\xd5\x8e\xd0\xae\xaf\x2a\x9f\xc8\x6f\x8c\x2f\x25\x63\x61\xa9\x78\xe1\xf7\x16\x4e\x65\x6b\x5f\x3a\x8a\xc1\xe9\x92\x69\x67\xdf\xff\xb1\x7f\xcd\x39\xa0\x42\x8a\xd8\x69\x64\x64\x79\xde\x53\x8c\xf8\x56\x63\xb8\xe7\xe6\xc4\xec\xe8\xe1\x3d\xfa\x2e\xea\xd7\x83\xbb\x29\xdf\x4f\x25\x11\x86\x96\x8e\xa2\x51\xaf\x50\x8f\xb6\x40\xa1\x20\x4c\xdd\x98\x6b\x87\x0e\x96\x64\xd8\xd5\xf8\xcb\x50\xb2\x00\x61\x13\xd7\xed\x75\x5b\x9f\x1f\x91\xbd\xeb\x02\xc9\x39\xba\x45\xc7\x44\x1c\xf7\x4e\x89\xf2\x6f\x5f\x70\x69\xf8\xfe\x82\x22\x3c\x0f\x81\xcd\xb8\x21\xcf\x78\x8e\x92\x50\x2b\xc8\x52\x43\x73\xe7\x8d\x87\xd1\xfb\x97\xa8\xc9\xd2\xce\xb1\x3c\x7b\x41\x0c\xd9\xec\x33\x48\x22\x34\x4e\x45\x74\x28\x70\x3d\x3f\xab\x66\x5d\x8f\x3c\x7d\x49\xb9\xa5\xd1\x01\xdd\xda\x90\xbf\x20\xbb\x75\xc0\x37\x8f\x05\x93\x2c\x90\x71\x38\xc4\xb8\x3c\x17\x75\x99\xeb\x91\xb7\x24\x99\x62\x68\x83\x89\xe2\x52\x16\xb0\x2a\x74\xbf\xf0\xc9\x90\x11\x1f\xe3\xde\xe4\xa2\x80\xc6\x61\xae\x67\x51\x08\x32\x8c\x2c\x39\xcc\x6a\xbb\x5a\xdd\xac\xb6\xdb\xbf\xba\xd3\xc4\x94\xd9\xfa\x2a\x51\xc1\xdf\xd6\x8b\x4d\x3f\xef\x70\x54\xc8\x50\x46\x48\x13\x5c\x9e\xa0\xf0\xe4\xc2\x7f\x0c\x78\x04\xa6\x38\xd6\x51\xd4\x0c\xfb\x4d\xee\x59\xdb\xe5\xc1\x46\xc8\xb7\x70\x14\x98\xab\xdf\x81\xe8\x3c\x74\x19\xd1\x08\x77\x30\x09\x2f\x59\xf1\x50\x5e\xd7\x0c\xca\x48\x52\x34\x19\xdb\x29\x08\x7a\xb8\xb8\xee\x72\x51\xbf\xba\x29\xe9\x3a\xc7\x91\x48\x9d\x5b\x8e\xe5\x61\xd6\x8a\x1c\x3d\x65\xcc\x03\x1d\x5b\x17\xd0\x95\x03\x4d\xb6\x0b\x19\xa7\x16\xa0\xb5\x81\x66\xb0\xd8\xca\xd8\xa4\x88\xaa\x7b\xfe\xf3\x76\x68\x4c\xcb\x84\x92\xd0\x69\xcc\xb6\x93\xc9\x97\x1d\x5c\xe3\x60\x64\xc2\x42\x34\x0b\x45\x6b\xc5\xd7\x3d\x20\x5e\xf2\x48\xa0\x93\xa1\x7c\x18\xa2\x27\x00\xa0\x92\xab\x80\x77\x3c\x87\xe7\x13\x54\xd7\x76\x9a\x4c\x79\x4c\x7a\x5a\xc5\xa5\xa8\xb4\xc5\x80\xcf\xe7\x5d\xbc\x1d\x24\x05\x8b\xf1\x5d\xe0\xac\x1b\x16\x4b\x4a\x11\x4a\x34\x2d\xb7\x8b\xc7\x6f\xab\xd5\xe3\xed\x21\xea\x5a\xe2\xc8\x0a\x1f\xe5\xd0\xa3\x06\xc7\x77\x23\x04\xd7\x96\x9c\x3e\xc3\xa0\xcc\x52\x34\xf0\x52\x56\x93\x0c\xbd\x14\x46\xd2\x61\xe1\xc9\x43\xfe\x09\x9e\x44\x4a\xaa\xb0\xf2\xbc\x9d\x6c\xf3\x7e\xa6\x94\x92\x63\x0a\xf9\xf8\x82\x0c\x73\x93\xdd\x03\x4b\xf9\xd0\xe3\x59\xad\x0f\x9b\xd5\xf6\xf0\xbc\xf3\x35\x8d\x52\xf1\x04\x45\x5f\x16\xff\xf4\x15\x1b\x7f\xcb\x29\x30\x7f\x0b\x2a\x65\x38\xde\x1d\x7e\xd9\x9f\x5f\xf3\x18\x3f\xee\xc3\xe6\xaf\xed\x48\x65\x72\x72\x38\xa4\x51\xe0\xdc\x26\x5c\x00\xd7\xc5\xa2\xb8\x6c\x5c\x79\xeb\x35\x02\x4b\x1a\xa2\x91\x93\xee\x6e\xb1\xdc\x3f\x6d\x0f\xd4\x5f\xcf\x24\x09\xaa\x04\xb7\xe3\x05\xd7\xb7\xb2\xe3\x8c\xb8\xcd\x6a\x1b\xc9\xf2\x5d\x53\x40\x87\x69\x61\xaa\x4c\x59\xee\x87\xe1\xc8\x36\xc2\x06\xbf\x7b\xfa\x66\xfb\x00\xed\x39\xee\xce\x85\xae\x44\x56\x5f\x2d\xd4\x46\x2b\xf4\xe1\xb6\x4f\xbe\x0e\x49\x05\x2a\xe2\x4e\xf1\xff\x16\x8a\xcb\xa6\x82\x63\x76\x1e\xf8\x4e\xdd\xae\xab\x02\xc3\x31\x87\x8e\xf1\xe5\x3b\xa1\x40\x96\xe5\x5b\x77\x1a\x23\x2d\xaf\x96\x0d\x70\x7c\xbd\x57\x29\x02\x92\xbb\xd7\xb9\x50\xcd\xd9\xca\xd0\xfb\x53\x51\x4a\x30\x3e\x97\x67\xef\x70\x02\xa7\xb6\xdd\x35\xc6\xb6\x26\xcb\x9a\x8b\x7d\x82\x5a\x51\xb0\x08\x9e\xac\x40\x50\xec\xfc\x48\x54\x2c\x62\x91\xa5\xd9\xaf\xde\xa0\x19\xa5\x27\xbe\x72\x9d\x14\xd3\x80\xdf\x2d\xcf\x6a\xa7\x79\x36\xde\x4d\x54\x18\x52\x9c\xad\xb8\x08\xf0\x64\xb0\x36\xa9\x30\xb6\x3a\xfc\x56\x9c\xce\xe9\x3e\x74\x94\x8e\xe3\x2f\xa4\xc2\x34\x60\xba\x63\xc1\xb6\xcc\xfc\x13\x98\x81\x8a\x48\xa8\xdd\x42\xfa\xbf\xa5\x74\x05\x25\xeb\xcd\xdd\x0e\xeb\x0e\xc7\xe7\x8b\x63\x81\xd5\xc4\x8f\xe5\x11\x0e\xef\x59\xa1\x5a\x5f\xaa\x7b\xd5\xb1\xa1\xa9\xe5\xbb\x15\x3a\xcf\x0a\x20\x34\xe8\x9b\x18\xba\x83\xe0\xe6\xdd\xba\xde\x9e\x51\xfc\xd3\x77\x48\x48\x2c\xe3\x41\x52\xa2\x5e\x28\x35\x5e\x6b\x54\xa2\x01\x13\xad\x87\xad\x38\xc2\xb0\x2a\x50\xf1\x98\xe2\x76\x96\x21\x82\xc7\xda\x2a\x5d\x5b\x6a\x6b\xf4\xb7\xab\xbb\xd5\x76\xbb\xb8\xb7\x60\xe4\x03\x22\x44\x7c\xa5\x8e\x4a\x63\x86\xb3\xe3\xf0\x02\xcd\xaa\x79\x7d\xae\x87\xe4\x62\x54\xa5\xa9\x95\xed\x70\x89\xd0\x1f\x70\x99\x6c\xda\x4a\x44\x11\xb7\x03\xe9\x57\x99\x69\x17\x1a\x9a\x22\x7b\x94\x48\x63\x2b\x9c\x5b\xee\xb3\x1c\xd6\x58\x48\x6c\x93\xea\xdd\xd7\x10\x10\xa0\xcc\x48\xeb\x4f\x6f\xca\x32\xef\x89\xf4\xa8\x92\x61\x0c\xc1\x0c\x22\xbc\x4f\x41\x29\x19\xdb\x04\xe8\xc3\xe2\xcf\x91\x2a\x2b\x55\x32\xf5\xb5\x36\xcd\x46\x58\x26\x9f\x47\x71\x35\x60\x54\x40\x02\x87\x94\xb4\xdb\xed\x5d\x59\x5d\xd1\x99\x51\xa5\x62\x81\x40\x83\x63\xa9\x33\x73\x69\xf7\xc2\xa5\xb8\x82\xa3\xf9\xbe\x40\x90\x72\xfa\x30\xa0\x66\x9b\x45\x74\x28\x1d\xd8\xe2\x35\x3d\x47\x10\xdd\x36\x4b\x1c\xcc\xf8\xf8\xd6\xc6\x18\xd2\x6e\x51\xa5\x19\x41\x74\xef\x52\xd4\xaf\xc7\xb2\x80\xcb\x68\xae\xeb\x84\x86\x1d\xad\xa0\x4f\x49\xe0\x9c\x19\xcf\x07\x48\xa9\x72\x58\x89\xbb\xf5\x76\xb7\x3f\xec\xf6\xab\xcd\xe1\xe1\xf9\x7e\xbf\xde\xdc\xaf\x57\xdb\x51\x32\x5d\x81\xe0\x48\xfc\x21\xb3\xaa\x79\xfd\x63\x60\xdc\x2b\x00\x0a\x2e\x44\xf5\x90\x61\x5a\x61\x7c\xb7\x46\x42\x3a\x60\xff\x9a\xdd\x5f\x75\x10\x09\x8c\x1e\xac\xf5\xbe\x5c\x58\x6b\x71\xf4\xce\x74\x10\xa9\x78\x28\x14\xff\xe7\x66\x31\xef\xb4\x68\x92\xa4\x58\xd0\xbf\xdb\xac\x96\xeb\xc5\xfd\x7a\xb7\x3f\xec\xbf\x6f\x57\x3e\x0d\xad\x89\x00\xac\xe3\xd8\xc2\x49\x64\xd5\x12\xe3\x15\xf3\xae\x96\xa6\x60\xe5\x07\xeb\xb3\xdc\x09\xf3\xc9\xea\xa8\xa9\x91\xa9\xe9\x82\x83\x9d\x51\x78\xbd\x4c\x69\xc6\x94\xb6\xa1\xdf\x2d\x66\xa4\xa6\x05\x64\x9a\x25\x14\xe7\xa7\x3c\x57\xc5\xee\x3a\x3a\xa2\x99\x4c\x7c\x26\x62\xb3\xb6\x45\xc1\x34\xf5\x0f\x16\x85\x01\x6a\x47\x1e\xd0\x8e\x59\x7d\x34\x95\xf0\xe6\x60\xdd\xf5\x31\x90\xda\x30\xd1\x3b\x88\x7c\x29\x8e\x27\x91\xbd\x5c\x55\x26\xba\xce\x31\x37\xb8\x62\x76\xcc\x29\x00\x8f\x5d\x31\x9a\x8e\x53\x86\x44\xe5\x03\x3c\x48\xf5\x3e\xc9\x07\x73\xdf\x17\x40\xf6\xf9\x6d\x64\x01\xb8\x85\x5c\x4c\xcc\x27\x9d\xd0\x38\x1d\xc8\xfc\x8a\x23\x26\x17\xea\xd9\x53\x26\x69\x8c\x45\xfb\xce\xc0\x7c\xcc\x14\x7c\x3b\x5f\xd6\xda\x57\x8d\x69\x1e\x84\x38\xee\x6e\x45\xa1\x2f\xdd\x8f\x82\x49\xed\x06\x63\xeb\x04\x9f\x8b\xac\xb9\x6c\xe1\x74\x6e\xc4\xb5\xa1\xae\x39\x00\x44\x03\xa2\xaa\x1d\x34\x8f\xa5\x25\x48\x68\xc7\xf9\x63\xe9\xc4\x82\x5d\x77\x41\x6c\xdc\x03\xa5\x86\x45\xd5\x78\xe8\xfd\xfc\xdb\x15\xcc\x80\x55\xc2\x45\x79\xfd\x65\x79\x3c\x95\xc5\x1c\x37\xed\xf8\x9e\x44\x94\x28\x37\xda\xf6\xaf\xb0\x6b\x2c\xb6\x77\xb0\xa9\x6a\x91\x84\xb8\x3c\x88\x63\xbf\xd1\x6b\x91\xf0\xd0\x0e\xbd\x8e\x99\x1e\x83\x0d\x93\x27\x16\x60\x09\x50\x8e\xe2\xc3\xae\x8b\xbd\x7b\xa7\x25\xb7\x10\x68\x5b\x2e\xb8\x5c\xad\x7f\xae\x6e\xd1\xf2\xdc\xac\xb6\xeb\xa7\xdb\xae\x9b\x4a\x70\x23\x7a\x5c\x2d\x37\xc3\x85\x49\x4b\xb0\xd1\xce\x6f\xa5\xc8\x1d\x01\x90\xe7\xa9\xfa\xd2\x9d\xd6\x2a\x08\xad\x7d\x6e\xa5\xea\x7c\x7d\xd3\xe2\x1d\xaa\xeb\x29\xa2\xa8\xf0\xe4\x31\xc7\xfa\xe5\x54\xa9\x69\xcc\x5d\xab\x14\x38\x46\xec\xcf\x05\xba\xa7\x77\xd9\xfb\x7f\x09\xb7\xd0\x4a\x06\xa4\xa7\xf0\x70\xa9\x9f\xfa\x8f\x09\xdb\x68\x9f\x43\xd6\x20\x08\x73\xb4\x3d\xd9\xa0\xd6\xf5\xc1\x6e\x4c\x7f\x74\xbd\x14\x71\x4b\xf1\xfe\x35\xab\xf4\x30\x44\x3a\xb9\x79\xc3\x82\x98\x7b\x5f\x05\x37\xe8\x49\x7b\x44\xf1\x5d\xdd\x67\x2f\xc7\x51\x86\x04\x82\x44\x20\x0d\xed\x6b\xf9\xfb\x41\x14\x17\x5b\xc0\xb2\x2f\x7f\x64\x79\x3e\xc9\x00\x01\xa1\x9d\xee\xf2\xee\x04\xea\xff\xcf\xda\x9f\x75\x37\x8a\x64\xfb\xc3\xf0\x77\x39\x57\x75\xd1\x17\x40\x0c\xc0\xff\x4e\x96\xe4\x4c\x75\x79\x6a\x4b\xce\xac\x3a\xbd\x7a\x69\xc5\xb0\xc3\xa6\x8d\x40\x0d\xc8\x43\x7f\xfa\x77\xb1\x23\x82\x49\xc8\x59\x67\xbd\xcf\x4d\x67\xb5\x09\x21\x04\x41\xc4\x1e\x7e\x43\x26\xf2\x71\x63\x7e\xf0\x1e\x42\x08\x3a\xea\xdf\x59\x07\x26\xb1\xaf\xc5\x68\xbf\x81\x88\xdb\x81\xcb\xc7\xfb\x9f\xab\xfd\xcf\xc5\x8f\x75\x38\x22\x4c\x01\x09\xc0\x6a\x80\xdf\xed\xd6\x8f\xd7\x8b\xa5\x5f\xb1\x81\x12\x81\xab\x9e\x3e\x1d\x0e\x9f\xfd\x1f\x25\x2e\x95\x0e\x6d\xdd\x2e\x51\xc7\xb2\x6a\xce\xd1\x9a\xf3\x8f\x12\x28\x4b\xa5\x93\x47\xb8\x76\x9a\x4a\x93\xd5\x18\x28\xb3\x19\xe3\xf3\x09\x95\x03\x1b\x91\x5f\x81\x28\xee\xcd\x64\x18\xa3\xb6\xad\x8e\xb6\xfe\x0f\xe2\x53\x0c\x2b\x35\x33\x02\x36\xc0\x18\xc1\x7a\x4d\x83\x2c\x00\x07\x4d\x9b\x9c\x93\x53\xa6\x07\x98\xf8\x36\xf4\x70\x02\x14\xc3\x88\x0d\x58\x1a\xe0\x5d\x30\x59\x7e\xe8\xfe\xa6\x39\x22\x93\xd4\xfe\xd8\x0e\x7d\xcc\x5c\xc7\x7b\x54\x57\x00\x06\xcc\xd7\x15\x7a\x8d\xf4\xd1\x65\xf2\x88\x60\xd5\x6b\xef\x05\x89\x46\xfb\x3a\xc4\x41\x80\xab\xdd\xed\xb7\x25\xae\xd4\xc3\xb9\x16\x87\x31\xa6\x15\x16\x4e\x73\x33\x42\x7f\x4f\x9e\x43\xac\x18\x1a\xf7\x5d\x75\x9f\x05\x85\x22\x87\x4d\x06\xd5\xd4\x90\x3a\x82\xd8\x24\xd8\x13\xf7\xda\x7c\x37\x28\x72\x75\xe1\xdc\x29\xb5\x6f\x7a\xed\x99\xee\xeb\xe2\x39\x2b\x00\x2a\xd7\x8b\xfb\x7a\x86\xa4\x69\xe8\x8c\x9d\xf2\x7c\xab\x7a\xc8\x3c\xa4\x69\xec\x1d\x57\x2c\x57\x63\x87\xf0\x5e\x7f\x58\x46\x04\x51\xd1\xf7\xce\x59\x0d\xb7\xbb\x1d\xd4\x83\x01\x0c\x0b\x6d\xed\x26\x34\x00\x8c\x81\x64\x40\x5d\xf8\x2d\x34\x72\x0c\xc6\xab\x33\x28\x92\xa2\xd1\xc6\xa1\x68\x8e\xb7\x1e\x2d\x3d\xf4\xf4\x8e\x40\xc5\x02\x4b\x37\x7b\x38\x64\xcd\x4a\x7c\x22\xaa\xca\xf2\x4a\xf4\x97\xf6\x25\x11\xa8\xf6\x07\x5b\x88\x70\x5e\x36\xfd\x34\x1f\x6f\x40\xa0\x89\x85\x62\x5b\xc3\xe3\x32\x3f\xaf\xc8\x8c\x4f\x6b\xe2\x44\xf5\xf2\x2c\xfb\x5a\x55\x99\x9c\xfe\x30\x93\x68\x4c\xf6\x8e\x15\xbc\x65\xe5\xa9\xee\xcc\xcf\xfb\x86\x83\x09\x68\x84\x8c\x3e\x78\x7b\xec\xbd\x76\xe7\x1f\xbc\x09\x98\xc1\x0a\x9b\xd3\x52\x58\x78\x5a\xec\xa5\xe1\xb1\x0e\x9c\x89\xb6\x0d\xcc\xee\xd6\xbb\x79\x2d\x5d\xbf\x9a\x99\x90\x2b\x14\xf6\xc1\x12\xef\x03\x1c\xfd\x43\x34\x51\x18\x75\x9d\x2e\x68\x16\x55\xd5\x1d\x20\xdc\x6f\x4c\xdb\x93\xdc\x95\xa7\x0a\x0b\xf7\x08\x34\x9b\x7a\x1a\x44\x26\x4a\xac\xab\x18\x9e\x7f\x86\xfa\x6c\x22\x29\xb1\x51\x82\xb0\xf3\x4d\x61\xca\x1b\x5b\x99\x9a\x0c\xa3\x81\x25\x59\xd8\x1d\x6b\xe4\x83\x3b\x8f\x86\xec\x4b\x17\x86\x72\x62\x7f\xa3\xd5\x67\x1d\xa7\xfa\x03\xb1\xaf\xf1\x37\xb2\xc4\x28\x1b\x62\x36\x55\x06\x6f\xd0\x05\xc4\xe8\x83\xf9\x50\xd6\xcd\x80\x7e\x62\x18\x88\xa8\x8d\xd6\x9f\x64\xf6\xd8\x43\x01\xfc\x51\x4e\x62\x14\x55\x1d\x49\x66\xfd\x0a\x50\x37\x3f\x0f\x0d\xa7\x24\xf1\x22\x64\xd7\xf7\x33\x7a\x08\x26\x8e\x14\x5e\x8b\x9d\xa9\x23\x29\x22\x13\x47\x40\xd2\xee\xe9\xb9\xe6\x89\x57\x2c\x19\x7f\x51\x4c\x63\xc4\xc1\xad\x16\xbb\xf5\x9e\x84\xfb\xd5\x7a\xb9\x8f\x82\x30\xf1\x3f\x2a\xe6\xca\x6e\x67\x99\xde\xb5\x91\xdf\x43\x7b\x8e\x76\xa2\x4f\x31\x7c\x5f\x2e\x4f\x26\x96\xd4\x07\x0d\xcb\xe5\xf7\x2e\x19\x18\x2e\xe1\x26\x89\xd2\x40\x75\x14\x9b\x5b\xa1\x5e\xb2\xa2\xbb\xf5\x49\xca\x85\xe9\x34\xa5\xdb\x3b\xbb\xd1\x57\x9f\xbb\xc5\x3d\xe6\xcb\x73\xf5\x74\x93\x68\x9b\xe3\x3e\x96\xea\x75\x50\x98\x30\x89\x96\x58\x21\xc3\x5c\xd5\xc6\x37\x3d\x17\xd7\x24\x10\x60\x38\xe1\xb5\x0b\x37\xaa\x5c\xf5\x95\x2b\x23\x14\x41\xbc\x09\xc6\xa4\xf6\x5b\xa1\xfe\xad\x9b\x8c\x83\xff\x99\x64\xca\x46\x06\x09\x36\xd0\x5e\x44\x8d\x0d\x1f\xd0\x8f\xa5\x2c\xb1\x1f\x58\x4f\xc9\xc7\x46\xb2\x04\x1b\x86\x8b\x53\x53\x1e\x44\x03\xba\xab\x8d\xfa\x01\x90\x68\x57\xd3\xdb\x8a\xb7\x5e\x7b\x65\x7c\xdb\x75\x42\xd1\xcf\xdb\xaa\x42\xf5\x8d\xb4\xc9\x30\x20\x96\x48\x86\x49\xbc\xc5\x64\x88\xcc\x57\x38\x0c\x30\x61\x5c\xeb\x67\xb3\xbc\x5f\x37\x2f\x73\x4b\x00\x18\x89\xc5\x57\xa1\xf5\x5e\x8c\x1d\x34\x26\xaf\x9c\xe1\x10\xb9\xa5\x65\x08\x95\x9a\x2c\x05\x06\x28\x75\xe5\xc3\xf5\xc7\x11\x85\x35\x7f\xdd\x21\x23\x41\x10\x5b\x1e\xb2\x83\x64\x8c\x56\x8f\x90\x45\x6e\x54\x18\xb1\x20\xf6\x9d\xf6\x83\x84\x0a\xb1\x74\xc5\xc4\x41\x9c\x04\x21\x57\x7c\x60\x60\xba\xbf\x7e\xba\x5b\xed\x1d\x43\x93\x04\x28\xb1\xd3\xee\x5e\x05\x7c\x34\xd8\x83\x0b\xeb\x76\x17\xeb\x23\x94\xb9\x77\x81\x04\x11\xb7\x9e\xd4\x42\x77\x1a\x43\xf3\x3f\x26\x8a\x13\x2c\x2d\x49\x8c\x08\x14\x9c\x59\x54\xcf\xbe\x6c\x24\x88\x40\x41\xe0\x53\xbb\xf2\xb8\x9a\xfa\x28\x93\x80\xa4\x1a\xab\x36\x6d\x76\xb4\xbb\xdf\x2d\x6e\x46\x75\x29\x12\x30\x65\x10\x5e\xf9\x0e\xd9\xae\xec\xd8\x47\x24\xe0\x0e\xa2\x80\xf2\x7d\xf8\xd8\x36\x7a\x72\xcf\xb8\x33\x82\x78\x78\x5c\xdf\x6e\xee\xd6\x8f\xfb\xe5\xf7\xc5\xdd\xb7\xf5\xea\x4b\x88\x15\x09\x62\x92\xe0\x7b\xf5\x3b\xb4\xd3\xef\x7b\x79\x80\xa3\x38\xef\x04\xb8\xc1\x09\x28\x4b\x68\x2e\xb3\x42\x14\x1f\xfe\xea\x12\x43\x23\x57\x58\xb5\x11\x94\x3f\x90\x86\xd2\xe1\xb7\xda\x95\x65\x44\xeb\xf4\x6f\x69\xd4\xab\x51\xc5\xff\x1a\xf3\x48\xff\x19\xfd\xcb\x9f\x27\x95\x56\x9c\xe2\x05\x96\x9f\xb2\x3f\xbf\xa0\x09\xa2\xff\x9c\xf6\xcc\xd8\xac\xf2\xab\x85\x9e\x04\x42\x44\x38\x15\x4d\x55\xfe\x17\x0a\x97\x91\xb4\xab\xd5\xd5\xe7\x90\xa8\x77\xe9\xd3\x60\xcd\xc9\xb5\x6d\x2c\x2c\x0e\x52\xd4\xb5\xd0\x65\xf5\xd0\xa3\xa9\xda\x51\x31\x42\xfc\x84\x46\x8c\xd1\x95\x68\x9a\x1c\x2e\x3b\xfc\x92\x40\x11\x03\xac\x5b\x03\x6b\x98\x3c\x62\x45\xed\xfc\x92\x8e\x09\xd9\xed\x81\x24\x50\x82\x0e\x76\x25\x84\x5d\x62\xdc\xf7\x50\x81\x45\x7f\x4f\x59\x2d\xe3\x5b\x3d\x2b\xea\x4f\x02\x25\xad\x16\xaa\xbd\xbd\x6b\x9d\x9d\x69\xaa\x92\x40\xb3\xd8\x58\x2d\xa9\x0f\x79\xfa\xcc\x8a\x7f\x9c\x44\xd1\x74\x80\x15\x12\x18\x1a\xda\x82\x40\x59\x1d\x5f\x46\xd7\x6c\x52\x86\x5e\x52\x1f\x9e\x6c\x4c\x02\x23\x6d\xd1\xb2\x86\x66\xbd\xfb\xfe\xd8\xe6\x8a\xc3\xfa\x43\xbf\x0f\xb7\x43\x29\x4e\xdc\xe3\xa9\x19\x38\x73\x91\xc0\x68\x82\x02\xed\xb7\xb7\x03\x4f\x69\x12\x06\x91\xc1\xcb\x2c\x8f\x50\x3c\x96\x03\xaf\xba\xd1\xaf\x09\x03\x16\x21\x83\xd3\x2b\xc4\x4e\x3a\x8e\x24\x0c\xe3\xc8\x90\x91\x2c\x1b\xc2\x98\x3c\xdf\x6d\x53\x38\x9e\x91\xff\x5e\x12\x25\x18\x08\xaf\xd5\x23\xa8\x21\x23\x71\x80\x7d\x20\x21\x61\x01\x8a\x63\xd9\x0a\xc0\x94\xb2\x42\x42\xa2\x23\x64\x64\x3a\x85\xc8\x3c\x77\x0f\x75\xf2\x23\xfe\x49\xfe\x35\xfd\xcf\xe4\x9f\x61\xcc\xff\xd5\x9d\x26\xc5\x34\x0a\xbf\x7a\x57\xba\xa4\x72\x80\x86\x0e\xfd\x40\x48\x31\xb3\xac\x9b\x4a\x1d\xcf\x74\xd4\x07\xbb\x3d\x09\x69\x10\x60\x0b\xd6\x00\xd4\x57\x9f\xae\xdd\x30\xbe\x67\x94\x59\x6a\xc1\x21\xb3\x2e\x29\x3d\x1a\x9d\x84\x54\x12\xec\xe3\x23\x0f\xfa\x16\x90\xf9\x3f\x2e\x57\xb4\x63\x2c\xf7\x73\x71\x7a\x80\x26\xc3\xb7\x74\x38\x91\x42\xaa\x08\x52\x4d\x30\x50\x3a\x7b\x73\x2f\xfd\xff\xd9\x57\x30\x64\x89\xc4\xec\xa9\x9d\x27\x77\xd0\x98\x47\x78\x83\xe2\x04\x23\xa6\x90\x1b\xca\xe3\xc0\xeb\xd9\x6c\x6a\x8f\x95\x9f\x0c\xd1\x16\x9e\x9c\x3b\x51\xf1\x5f\xc7\x6d\x93\xcb\x89\x23\xcb\x28\x53\x22\xcf\x17\x85\xb6\xd1\xef\x3e\x98\x57\xd8\xf2\x9f\x91\x56\xcc\xd6\xc9\xe0\x8c\xdb\x69\x24\x4c\xb4\xb5\xe9\xc9\x0a\x55\x1e\xe0\x1a\xa0\x3b\x92\x32\xa3\x5c\x56\x82\xd8\x48\x39\xd2\x50\x9e\xdf\x40\xc2\x54\x9a\x50\xf4\x15\xca\x6f\x22\x6f\xb3\xa9\x7a\x32\x05\x04\x97\xde\x9c\xd0\x2b\x1d\x9f\xa1\x3d\x48\x28\xe2\xc8\x32\x33\xe3\xdf\x46\xd3\x51\xc4\x16\x0b\x81\xc5\x73\x2c\x42\x61\xf9\x64\x98\x6c\x91\x50\xa4\x1a\x71\xd0\x9d\x9d\xc5\x76\xb7\x1c\xff\x72\xc9\x8d\xe5\xf0\x66\xff\x85\x7b\x33\xc2\x0c\x92\x50\x51\xeb\x21\xb7\x13\x39\x0c\x2a\x9a\x24\x54\x8c\x49\x57\xe7\x42\xc9\xdc\x0c\x9d\x59\xbe\x50\xe0\xed\x17\xa9\x50\x31\x9b\x06\xdf\x94\xcf\x5b\x68\x30\x64\x1e\xbd\x3c\x3a\x20\xf8\xc3\xae\x4e\xf2\x3c\x18\x23\xa1\x4e\x6c\x6b\xf4\x34\xce\x4b\xcf\xd1\x53\x24\x04\x96\x08\x8b\x58\xfd\xf7\xa9\x6e\x40\x3f\x8a\xac\x43\xfb\x91\x10\xb8\x8c\x3b\xfb\xe5\xbb\xb2\xb9\x2e\xab\xd7\xae\xb4\x48\x42\x10\x56\xc4\x74\x6b\x09\x23\x8e\x9d\xa0\x43\x7f\xdc\x48\xeb\x13\x61\xe9\x4f\x4b\x2f\xe0\x9b\x75\x6f\xa0\x01\x6b\x8c\x2c\xad\x13\x96\xf5\xa9\x72\x07\xa3\x30\x20\x8c\xfb\x36\x78\x0e\xcf\x42\x97\x2b\xb0\xc9\x7b\x53\xce\x12\x3d\x09\xe6\xc7\x0e\x8a\xfd\xf7\x3f\x1f\x96\xe7\xc0\x38\x12\x85\x2a\xe6\x48\x85\xdc\xec\x9e\x16\x37\xfb\xe5\xfd\xed\xc3\xfa\x6e\xbb\xd8\x75\x10\x04\x12\x45\xc4\x84\x0e\x0c\x06\x95\xed\xe4\xbb\xf8\x63\x63\xee\x00\xf4\x85\x7a\x13\x89\xa2\x44\xa2\x0a\xcb\x7a\xef\xd0\x49\x9d\x2c\xee\xaf\x56\x97\xf1\x79\x48\xc4\xb1\x1c\x21\x73\xf1\x0a\x91\x74\x32\x0c\x4e\x81\x73\xf0\x1f\x6e\x38\x8d\xa4\x27\xb0\xdf\xaf\xd6\xb7\x23\xf4\xe5\xa8\xb4\x40\x22\x16\x52\x5b\x00\x6b\x53\x87\x5d\xb2\xfe\x63\x5b\xe6\x7a\xff\xf0\xb8\xf9\xd1\x69\xf3\x91\x88\xb1\x54\xbb\xcd\x4a\x89\xe2\x34\x0d\x28\x22\x1e\x18\x0f\x78\xc7\x48\xdc\x0a\x15\x8c\xe2\x7d\x3f\x92\x59\xee\x15\x42\x73\x4f\x45\xe3\x44\xa8\xfc\x17\xf1\x38\xe5\x58\x4a\x39\x15\xd1\x6f\x93\x5a\xc8\x57\x1e\xc9\x17\x6e\x5b\x1c\x30\x54\x30\x59\x54\x59\x21\xf6\xff\x3e\xe9\xe7\x5e\x7d\x86\x44\x71\x28\x88\x1c\xea\x8c\x3f\x40\xf5\x53\xbc\x4d\x62\xed\x28\x4e\x84\x13\x11\x6a\x9e\x8a\xa6\x5d\x9b\x7a\x3c\x21\x89\x62\x43\x3d\x72\x60\x83\xe6\x60\x28\x9f\xe7\x25\x59\xc6\x3f\x3e\x09\x93\xd0\x2d\xf4\x8f\xbf\x72\xfa\x20\x51\x42\x00\xd5\x62\x4e\x35\xe8\x76\xf7\xa8\xbc\x9e\x9a\xff\xea\x84\x19\x5c\x50\x9c\x60\xf1\xa2\x79\xb5\x51\xf3\x3f\x4e\x53\xa7\x31\x12\x25\x31\xa5\xbd\x1d\x82\xfd\xb9\x5e\x3d\xf6\xba\xac\x3c\x5e\x79\x72\x05\xa9\xc0\x0f\xf9\x36\xe8\x5c\x05\x82\x44\x89\xb4\xa5\xf6\x76\x69\x99\x9a\xd7\x4f\x46\x6a\x62\x11\x9e\xc8\x7e\xbf\x37\x6d\x62\xd3\x3d\xfa\xc4\x10\x94\xeb\xc2\x89\x78\x03\x6f\xd8\x79\xe9\x8e\xa6\x61\x88\xf2\x7c\xfb\x46\xbc\x41\x35\x89\x1d\xa3\x94\x51\xe4\xa9\xfd\x79\x3a\x40\x95\x9d\x0e\xed\xfa\x3a\xe4\xea\xb7\x23\x62\xac\xc7\x6c\xdb\x54\xb4\x3a\x1d\xee\x00\xcb\xdb\xdd\xe1\xc4\x2a\x8e\x66\xc5\x5b\xf9\x3a\xdf\x43\x23\x91\x88\x22\x8c\x08\xf7\xcf\x65\xa9\x67\x37\x9e\x48\xe8\x84\x39\x1f\x0e\x27\x5d\x3f\x5c\x70\xa6\xe7\x83\x88\xcf\xe9\xa3\xdf\x95\xdf\xb3\x62\xa8\x8c\xee\xc6\xcb\xc0\x4a\x94\x94\xae\xd4\xbb\xaf\xd0\x2d\x79\xb5\x45\xce\x39\x60\x61\xe0\xe1\x24\x7f\x87\x4f\x04\x99\xf8\x4f\x11\x4b\x85\xb4\x2f\xb8\x53\x47\x06\x7d\x05\x05\x98\x4c\x65\xa2\x97\xa5\x23\x91\x4c\xad\x5e\x97\x2a\x8b\xfa\x74\x80\x0e\xdb\xba\xe9\xaf\x41\x52\x84\xac\x7b\x87\x84\xe5\x04\x4b\x3a\x2e\x60\xba\x0f\xa9\xc8\xc2\xe4\xf0\x32\x55\x05\xcd\xa2\x41\xad\xe2\xc9\x53\x84\x50\x24\xe1\x80\x27\xe0\xf4\x5c\x7e\x1b\x57\x0a\x49\x04\x11\x93\x5e\x7c\xc3\xd7\xa2\xc2\xd4\x5f\x21\x88\x04\x0b\xe2\xe2\xb0\xb1\x31\x7f\xf7\xf7\x14\xe1\x2c\x3f\x1e\xdb\xb8\xaf\x67\x9a\x8f\x1f\x20\x48\x8b\x3c\xa8\x1b\x10\xf9\xde\x36\xae\x2f\xcc\x66\x50\x0c\x33\x81\x53\x81\x9a\x47\xb6\x10\x31\x3d\x9d\x11\xa8\xd7\x87\x0d\xb4\x3b\x78\xc7\x98\xe5\xea\x42\x0b\x81\x44\x26\x16\x58\x87\x15\x07\x9b\x45\x7a\x47\x92\xee\xb0\x95\xe6\xbb\x39\xbe\xfa\x2e\x79\x77\x28\x25\xa8\x35\x51\xc0\x47\x63\x4d\x34\xbf\x95\x9e\x36\x44\x22\x23\xa2\x84\xb9\xa3\xe8\x08\xe7\xbc\xe0\xfa\xe3\x16\x45\x8a\x9c\x5d\xac\xf0\x6f\xfa\x1b\x67\x0c\xc7\xdf\x79\xd5\x66\x65\x7f\x2d\x2b\x26\x81\xe0\xd2\x49\x38\xee\x0f\x59\xb1\x3f\x88\x8f\xfd\xf2\xe7\xb2\x5d\x61\x1f\x31\x87\x9f\x7f\x25\x48\x68\x08\x0a\x52\x3e\x67\xa6\x41\x71\xab\xf9\x1b\x45\x22\x4a\x69\xdf\xe2\xb7\x3c\xae\x0e\x25\x79\xe1\x23\xd2\x12\xcd\x9c\x22\xcf\xca\xc1\xa9\x7e\xf3\x87\x4d\x8c\x0d\xcb\xce\x5c\xb5\xf2\x95\xe4\xbd\x39\x15\xba\xde\x37\xe5\xfe\x58\x95\xff\x06\xdf\xb8\x24\x84\x12\x6b\x84\xb9\xef\x08\x7f\xed\xcb\xde\x2b\xce\x4c\x2e\x80\x9a\xd0\xb8\x46\x8e\x6d\x8e\xfd\xcc\x9a\x97\x99\x80\x84\x30\x21\x30\xc8\x82\x79\xb8\xe3\x28\x6d\x22\x3c\xe0\x5e\xbd\xee\xee\x74\x40\x69\x45\x68\x3a\x0c\x46\x7b\x3c\xc5\x93\x8d\x94\xf9\x08\xe1\x9a\x81\xe3\xaa\x2c\xae\xc4\x64\xd5\x1e\xcd\x61\x12\xc7\xd6\x4b\x12\x85\x63\x8b\xeb\x53\x55\x88\xde\x8a\x75\x5e\xe8\xc3\x47\x17\x24\x4e\x43\xe4\x8b\x76\xa4\x52\x4c\xb9\x86\x00\xdc\xf9\xf4\x89\x24\x09\x43\xde\xa2\xeb\x7d\x67\xf9\xa4\xb4\x47\x52\xca\x42\xdb\x8b\xac\x60\x05\x79\xf6\x06\x15\x72\x74\xca\x5a\xe4\xeb\xb7\x4b\xb4\x3e\x42\xd2\x38\x09\x87\x7b\x9a\xab\xd8\xcc\x01\x85\x08\x49\x4d\x8a\x38\x20\x93\x97\xe2\x75\x2c\xa1\x45\x88\xe0\x0c\x97\x8a\x07\x10\xaf\x38\x57\xfb\x1a\x35\x21\x42\x32\xd4\x1b\xf8\x09\xd9\xf6\xf2\xc5\x08\x47\x2d\x16\x4a\xc1\xb1\xf9\xdd\x6d\xcc\x3d\x2d\xd6\x0f\x03\x2b\x77\xe8\x5f\x5f\x57\x40\xef\xae\x44\x1a\x50\x9e\x6b\xf3\x2c\x1a\xd0\x36\xab\xb7\x7e\x11\xbf\x8d\xcc\x79\xff\x6f\x69\x23\x51\xc6\x6a\x2e\x21\xd8\x1f\x97\x8c\x5b\xd1\x9c\x2e\x40\x37\x09\xd1\x52\x23\xce\xee\x68\x15\x37\xea\x4d\x71\x8f\xf2\x47\x88\x9a\x51\x9f\x17\x3e\x05\x6d\x5e\xd6\x39\x15\x96\x55\x7d\x53\x76\x26\x8b\x84\x00\x0b\x13\x57\x0c\xbd\xef\xdc\x0a\xb3\xb7\x2c\x87\xe7\x01\x58\xe7\xbc\xb0\x43\x20\x4d\xb1\x9d\x93\xd5\x67\xc6\x0c\x6e\x84\x61\x16\xb0\xef\x58\x4f\x5b\xc8\xcd\xa3\xed\xc6\x74\x03\x6c\xe1\xcd\x4b\x9b\x6e\x87\xdc\x56\x42\x4c\x6c\xe2\xa0\x5b\x85\xae\xb1\x02\xb8\x6d\x44\x73\x3a\x97\x14\xea\xaf\x8b\x06\xc4\x6e\x73\xfb\x8e\xfa\xe0\x58\x98\xa3\xbb\x42\xc3\x34\x44\x35\x27\x5d\x16\xed\x6f\x76\x0a\x7d\xfe\xa0\xb4\xeb\xdf\xd1\xcd\xf8\x49\x1c\x42\x23\xda\xa5\x3d\x9e\x89\xe0\x2c\x90\x26\xdf\x42\x68\x80\x95\xd5\x75\xf3\x82\xd3\x77\x7c\x1a\xa2\x42\x54\x79\x5a\x68\x7d\xb5\x5b\x0e\x34\xc8\x2e\xe7\xac\xed\x64\x73\x69\x08\xa5\x3c\x10\x7d\x4b\x0f\x4d\xf4\x45\x23\x2e\x2e\x1d\x43\x16\xfe\xa5\x52\x22\xa5\x10\xe0\x23\xf9\xf9\xf3\xa7\xbf\x19\x8c\x69\x04\xba\x3d\x3c\x6e\x96\x6b\x0f\xb4\x27\x94\x25\x0c\xa9\x4b\x77\xf0\x8e\x7d\xef\x4b\x5f\x3b\xfb\x6a\x52\x26\x39\xea\xa9\xb4\xd3\xa6\x8d\x83\xae\xcb\xd3\xc0\x3a\xcb\x0b\x41\xb4\xe3\x62\xc4\x91\x60\x4a\xdb\x6e\x2c\x3f\x21\xeb\x13\x5a\xca\x99\x62\x03\x6b\x93\x79\x48\x31\xa1\xb1\x0e\x22\xe6\xb8\xe9\xb6\x79\xec\xbb\x14\x34\x49\x03\xec\xed\xd8\x98\xe0\xde\x5c\x75\x52\x8e\x84\x26\x4a\x20\xc9\x6a\x2f\x2b\x00\xf4\xd5\xc1\xf3\xd2\xe0\x6f\xf6\x1f\x3f\xcc\x30\x5c\x85\x0f\xa2\xb6\x1e\x3d\xd8\xa7\x3f\x2f\xfb\xb9\xe1\x69\x14\x62\x7f\xed\xdf\x65\x56\x5c\xbb\x5c\xee\xac\xed\xde\xc3\x35\x09\x4d\xa5\xc2\xc0\xb8\x28\x0b\xa4\x19\x62\x56\xdf\xeb\x96\xfc\x9f\x6a\xf4\x54\x26\x31\xfa\xc8\x2c\x36\x8f\xab\xc7\xfb\x87\x36\x4b\xf4\x08\x14\x42\x65\x6a\x42\x3a\x42\xd4\x8f\xb4\x7f\xdd\x28\xc5\xd2\xb4\xfd\xbd\x7f\x17\x6f\x62\xfb\x2e\x8e\xbb\x81\xca\xc2\x0c\x46\x86\x50\xa5\x08\xee\x86\xed\x93\x59\x81\x12\x9f\x5e\x36\xd4\xaa\xb7\x58\xfe\xff\x78\x5b\xa4\x3a\xe1\xd2\x8c\xd1\x91\xb1\xbf\x4c\xad\x62\x54\x02\x58\x8a\x42\x54\x9f\x3f\xe2\xf6\x02\x8a\x2e\x19\xa1\xda\x84\x91\x4f\x82\xbb\x30\xfc\x13\x29\x0a\xf3\x93\x11\x4c\x84\x29\x16\xea\x0b\xbf\x54\xe5\x7b\xfd\xe4\x94\x01\x2d\xb9\xd9\xda\x23\x8e\x11\x82\xed\xa7\x28\xd1\x03\x67\x79\x5c\x01\xce\xd6\x19\x13\x58\x05\x19\x55\x74\xab\x8b\x89\x22\xe5\x56\x8f\xa7\x2a\x1f\x97\xc7\xa8\xa1\x0c\x06\xae\xcd\xdb\x06\x8e\x16\x76\xec\x8f\x03\x27\xc9\x60\xe9\x69\xaf\x6c\x89\xf4\xc5\xba\x6b\xce\x4f\xf5\x2a\x46\x57\xc4\x82\x00\x30\xd7\x93\x99\x9d\xa1\x89\xff\x3b\x0f\x43\x57\xfb\x43\x6a\xf4\x56\x74\x2b\x35\x0b\x52\xaa\xa2\x0e\xc0\xbf\x59\xde\x4f\x4d\x84\x08\x0b\x04\x20\x53\xd5\x64\x7d\x64\x8d\x4d\x94\x4d\xd1\x94\x8f\xd8\x9b\x9d\x7c\x40\xa6\xfe\xfb\x56\xa7\xe2\x19\xb0\x0b\x72\x14\xb6\x40\x7f\xfe\x12\xb3\x40\x11\xf4\x36\xc3\x7d\x72\x8d\x4c\xf7\x61\x79\x99\x85\x91\xf0\x4e\x2c\x6d\x04\xe4\x56\xf4\xe1\x0e\x31\xd8\x26\x58\x48\x62\xc4\x00\xe4\xe5\x3b\x54\x4b\xc8\xf2\x29\x6e\x8b\xb0\x90\x51\x70\x51\xf6\x23\x62\xaf\xe1\x38\xe8\x44\xff\x6d\xdc\x93\x26\x2c\x4c\x12\x2f\x5a\x78\x9d\xe5\x87\xe9\xc9\x00\xf0\x25\xc6\xfd\x06\x3a\x42\xff\xa9\xc7\xd1\x13\x46\x88\x05\xcd\xdd\xb5\x21\xe6\x18\xc7\x47\x18\x65\xda\xf7\x5c\x36\xa8\xcb\x3c\x70\xcc\x99\xe9\xef\x13\x46\x63\x8a\x15\x5f\x78\x6b\xf7\xce\xc3\x25\x19\x62\xc2\x68\x4a\x05\xed\x20\x50\x6d\xe8\xf3\xd0\xde\x94\x33\x4e\x0f\x61\x54\x5b\xd3\x63\x6d\x75\x3b\x7e\x94\x1f\x2e\xcb\x4c\xfe\x36\xf8\x5f\x37\x98\x87\xa1\xf6\xee\x25\xb6\xe5\xf7\x8b\xd2\xfe\xe4\xb2\x78\x94\x52\x87\x89\x58\x7c\x8a\xa2\x59\x55\x65\xd6\xac\x55\x59\x94\x87\xec\x3f\x27\xd8\x2f\xcb\xc3\xb1\x81\x3d\x99\x5c\x23\xe7\x4c\x39\x7f\xc3\xab\xd3\x67\x3b\x48\x14\x9f\xe3\x97\x8c\xc5\x21\xc7\x66\x57\xbf\xce\xcd\xf3\x11\x4f\x43\x1d\xcd\x2f\xa5\x71\x08\x8b\xa3\x50\x5a\xb2\xf3\xfb\x23\xd4\x65\x3e\xec\x21\x4d\x46\x32\x83\x90\x31\x79\xfa\x7c\x14\xc5\xeb\xe4\xfa\x63\x6d\xb5\xa3\xb6\x8b\x9b\xf5\x7e\x7d\xb7\x5a\xaf\xfc\x0c\x48\x82\x14\xab\x1f\xc7\xb2\xcc\x07\xfd\x00\x96\x38\xc0\x95\x2e\x3b\xdb\xcf\x51\xeb\x6c\xfc\xdb\x13\x1d\x61\xb1\x11\x65\xad\x57\x5b\xbb\x0e\x57\x56\xa6\xd7\x9f\x31\x8d\x44\x68\xc6\xf1\xcd\xcc\x6c\x10\x5c\xa2\x91\xc0\xcf\x4c\x99\x81\x27\x70\x9b\x60\x71\x2f\x4a\x7f\x2b\x3e\x1e\xaa\xec\xbf\x70\x5f\xc0\x6a\xba\x91\x30\x01\x01\xb2\x16\xbe\x79\xf3\xb5\x91\x90\x07\x61\x92\xa6\x8e\x7a\xd2\x88\x8e\x24\x56\x6f\x8a\xad\x7a\x01\x7d\xca\xfb\x71\x2c\x32\xd1\x00\x83\xb7\xe8\xae\x44\xf2\x10\x30\xd7\xc3\xb6\xcf\xa2\x02\x31\x2a\xec\x33\x19\x2b\x94\x2b\x46\xc5\x07\xb6\x2e\xf4\x30\x6f\x67\x32\xa5\xa8\x42\x25\x2a\x99\x61\xb1\x7c\x49\xaf\xbb\xd7\xf2\x1c\x3f\x4b\x98\x4a\x24\xb7\x5e\xcf\x6a\x08\xed\x24\x4c\x53\x0b\x8b\xf9\xfd\x24\xa1\x12\xfe\xaf\x90\x04\xdc\xa6\x6f\x59\x1b\x40\x17\xcf\x5b\x8f\xc8\x27\x0c\x24\x0f\x8c\xaf\xd6\x9c\xaa\x1a\xea\xa1\x3c\x38\x61\x86\x72\xdc\x7d\x56\x3f\xac\x58\xfc\x17\xfb\x2f\x33\x8c\x7b\xb0\x48\x56\x98\xf2\xfd\xbc\xce\xe0\x07\xa6\x24\xc0\x24\xfe\x54\xa8\x51\x13\x98\x19\x29\xb0\xb3\xd9\x05\xd5\x16\x5b\x37\x5f\x6d\x98\xdd\x77\x78\x10\xc7\x8a\x0c\xda\x56\x6f\xa0\xaf\xe6\x3c\x82\xfd\x70\xa1\xd2\x61\xc5\xe0\xea\xf3\x9c\x77\x4d\x78\xa0\x04\x26\xb2\xc7\x4e\xab\x66\x60\x18\x49\x78\x18\x59\xd5\x6a\xdb\x6f\xc7\x5f\x74\x33\x48\x54\xfe\x36\x5c\x7e\x79\x48\x62\xd5\xcb\x02\x8f\x0b\x4e\x93\xdf\x12\x12\xe5\x6b\x64\x57\x65\xa1\x67\xd3\x5b\x4e\x62\xed\xbd\x05\x1f\x00\x29\x6f\xe7\x22\xfd\x84\xd3\x30\x8e\xfb\x5a\xcb\xbe\x16\x39\xec\xc5\x5c\xf5\x93\xd3\xc4\x9a\x2b\xea\x2d\xf4\x7c\x87\x2b\x04\x78\x76\x7d\xcd\x33\xd2\x22\xe1\x4c\xd8\x3a\xbc\x86\x5a\x55\xd9\xb1\xdd\x5d\x23\x7f\x7f\x98\xb6\xb0\x60\x94\x11\x18\x6b\x87\xcc\x3f\x15\x4e\xa8\xb4\xbc\x81\xed\xe6\xf7\xcd\x70\x8a\x70\x0e\x20\xa3\xb3\x7e\xa6\x3f\x1a\x07\xd6\xad\x72\x7b\x3a\x1e\xcb\xaa\xcd\x5d\x1b\xa8\x8c\x50\xd0\x06\xb2\x37\x65\xf9\x7a\x3a\x76\x43\x63\x45\xac\xad\xbf\xfa\x54\xf9\x34\x9e\xe9\xef\x5c\x2c\xec\x17\x1e\xc4\xc7\xc3\x8f\x2b\xff\xe9\x84\x00\x7a\x44\xd7\xc2\xc0\xf7\x12\x55\x99\xcc\xe4\x96\x27\xc2\x06\x88\x9e\xb7\x37\x5e\x76\x78\xa2\x25\x45\xff\xeb\xe5\x7a\x3f\x28\x3a\xf0\x04\x52\x84\xeb\xb7\xcb\xcc\x6f\x63\x72\x00\xe1\x69\x92\x0a\x2b\xd3\x5c\x37\xe5\x61\x60\xd2\xe4\x8f\x2b\x42\x9c\x87\xfb\x73\xd1\xee\x66\x65\x57\x60\x68\x8f\x21\xe2\xc9\xbe\x4d\x16\xcc\x7f\x5d\x5e\x9a\x7b\xa9\x16\x28\x08\x6d\xf2\xec\xb8\x7b\x81\xf6\x0a\x17\x85\xfe\xd9\x5f\xa7\x90\x5a\xab\x01\xac\x7a\xd9\x97\xab\xb9\x8c\xad\xb8\x19\xd6\x53\xde\xe6\xf4\x48\x08\x97\xa9\xc1\x92\x80\x7d\x0f\x50\x05\xaa\x7e\x41\xc6\xd0\x18\x2f\xe6\x2f\x48\x71\xed\xe1\x94\xb8\xd6\x3f\x94\xe5\xa4\x9c\xc4\x55\x2a\x31\x65\xd8\xdb\x73\x3a\x88\xca\xee\xf3\x08\xf6\xd1\xaf\xda\xc4\x75\x36\x0c\xe0\x0a\x38\x8a\x7c\x20\xa2\xc8\x96\xfd\x7b\xcc\x29\xe1\x5a\x04\xb8\x29\xf6\x50\x2d\x2b\x4a\xb8\xb8\xbd\x7f\xba\xdb\xed\xef\xaf\xaf\xd7\x8f\xeb\xd5\x7e\x77\xbf\x7f\x78\xba\xba\xf1\xe6\x83\x84\x43\x64\x79\x28\xd6\xc8\xb4\xb6\xa6\xad\xf5\xbb\x4b\xe4\x27\x13\xc6\x88\x38\x72\xe8\xbd\xa1\xfe\xc9\x6c\x93\x22\x0e\xa2\x00\x51\xdb\x96\x8c\x86\xf3\x24\xf1\x87\x18\xc3\xd0\xfb\xe8\xb3\xe8\x38\x8c\xb9\x37\x90\xfe\x91\x69\x28\xd1\x71\xa7\x81\xc3\xcc\x5a\x17\x87\x89\xe5\xad\xd7\x60\x17\xba\x23\xaa\x42\xef\x3e\x26\x7e\x6a\x6e\x74\x14\x29\x1a\xbb\xa4\xe6\x1b\x34\x37\xe2\xfd\x13\xaa\x45\x33\x4c\x26\x62\x12\x2a\xd4\x54\x3c\xe6\x1f\xc3\x97\x35\x6e\x63\x63\xe9\x7a\x63\xa3\xde\x7c\x4c\x52\x6b\x1e\x0c\xcd\x84\x68\x42\x62\x16\x1a\xcc\x5c\x7e\x82\x68\x67\xf0\xe8\x84\x8c\x5b\x6f\x6a\xa7\x73\x32\x8e\xca\xc7\xd7\xcd\x52\x40\xfd\xab\x4e\x20\xcf\x1a\x5e\xfa\x80\xf9\x2f\xc5\x8e\x31\x03\x82\xc2\xa7\x8e\xa8\x3c\x5a\x77\xcf\x8a\x2a\x53\xc8\xd5\x97\x35\xd7\x98\x27\xd6\xbd\x08\xdb\x4a\x65\x61\x41\x5c\xeb\xff\x6c\x8a\xc6\xaf\xaa\x31\x87\xc8\xfa\xae\x88\x3c\xf7\x8e\x4f\x8b\x42\xdb\xac\xc4\x74\xe4\x58\x12\xc7\xa1\x45\x1d\xd5\xd0\x7c\x2b\x73\x3d\x8d\x2d\xfc\x28\x9a\xa0\x1c\x1a\xee\x6c\xd7\xa7\x1a\x84\x6b\xaf\x9d\x23\xeb\x49\x1c\x9b\x28\x74\x99\x1a\x45\x34\xcc\x79\x26\x15\x27\x44\xe2\x2b\xf5\x20\x8e\x62\xf4\x98\x12\x90\x48\x03\x59\xb7\xe9\x5b\x95\xa9\x7f\x9c\xe0\x34\xd9\xd5\xe2\x34\x54\x98\xe7\x0d\x18\xf6\xb3\x5b\x45\x9c\xea\xd8\x4a\xcf\x55\x00\xfa\xb3\x1c\xa4\xce\xb1\xe0\x29\x8a\x16\x2f\x5e\xb3\xf3\xb2\x58\x2c\x12\x85\x95\x45\x14\x6d\xba\xf5\xfb\x76\x37\x05\x65\xa8\x8c\x5b\x6e\x36\x47\x53\x63\x33\x6e\xd0\x0e\x8b\x25\x4b\x11\xaf\x86\x82\x14\xd9\xe1\x98\xc3\x9d\x38\x40\xe7\x75\xee\x47\xf1\x04\xb3\xc9\x46\xa0\x9d\x6a\x69\xb2\x6e\x22\x4b\x6d\x15\x6e\xda\x33\x6f\xdb\x40\x7e\xaa\x92\x35\x99\x11\x2a\x84\x28\xf1\xed\x79\x0d\x1f\x8f\x65\xd9\x8c\xae\x48\x51\x4b\x00\x42\xa5\x72\x51\xc3\xcf\xb2\xd2\xdb\x3e\xe9\xf0\xa3\x54\x8c\xdd\xc1\xbe\x98\xef\x66\xc3\x5f\x34\xd3\x26\xb1\x8e\x04\xaa\x3f\x3e\x7c\x5f\x6c\xd7\x04\x7d\x1d\x77\xfb\xdd\xe6\xd6\x03\x0d\x62\x43\x15\x76\x9c\x9f\xc5\x01\x56\xd6\x6a\xac\xbb\x23\x49\x10\x06\xc8\x35\xde\x36\x15\x88\x43\x0f\x0d\x4c\x02\x15\x20\x86\x41\xb5\x9b\x64\x3e\x2c\x53\x8e\xa6\x55\x12\x86\x5c\x06\x23\xe9\x9a\x7e\x75\x48\x42\x63\x7d\xe8\xfc\xaf\xdb\x55\xa7\xba\x81\x73\x8d\x4a\x37\x3c\xa2\x1c\x22\x8b\x45\x1b\x38\xd9\xfb\x83\x42\xa1\x02\x82\xdd\x6b\xed\x3b\xee\xe6\xc8\xec\x96\x99\x44\xda\xdb\x92\xbd\x42\x71\x75\xaa\xc6\x42\x64\x24\x21\x24\xc0\x0a\x9e\xc8\xf3\x71\x2c\x90\x10\x16\xf2\xd0\xef\x97\xe8\xd5\xf5\x0b\x68\xc4\xfc\x82\x94\x10\x20\xa8\x96\x77\x53\x3e\xef\xc4\xeb\x79\xb5\xf4\x17\x39\xe6\xdf\x5c\x55\x74\xf4\xaf\xc7\xa3\x24\x34\xb0\x22\x65\x78\xe3\x37\x07\xf1\x0c\x9b\xe2\x78\xea\xc9\xe8\x21\xbf\x88\xe8\xf8\xe7\xbf\xa6\x95\x91\x84\x86\x81\x89\x3c\x20\x23\x53\x65\x55\x5c\xb5\x6f\xf0\x94\x8e\x42\x12\x9a\x04\x48\x9d\x2a\xc0\x43\x17\xc6\x82\x8d\x7e\x58\x0a\xa8\x0d\xf4\x56\x36\x70\x5f\x6c\xcb\xfc\x34\x5b\xf1\x1c\x5e\x81\x8e\x90\xcc\xf0\xb0\x78\xfc\x7d\xb8\x3e\x25\x14\x42\x7c\xd3\xea\x32\xd7\xdb\xad\xff\x2b\x8f\x2c\x85\xcb\x09\x6e\x43\xf5\x96\xa9\xf9\xbd\x39\xe1\x51\x8a\x05\xce\xed\xfd\x9f\x8b\xee\xe3\x04\x70\x5b\x2d\x47\x35\x8a\xf1\xe3\x8b\xc1\xaa\x7b\xdd\xdc\xfc\xd8\x93\x30\xdc\xaf\x57\x9b\x5d\x87\x74\x4f\x92\x88\xa2\x7e\xf5\xc1\xda\x5a\x7d\x3a\x35\xa6\xb1\x6c\xf9\xf8\x84\x09\x50\x5c\x69\x41\x55\x16\x6f\xba\x02\x35\xf0\x62\x9b\x87\xfd\xfa\xcf\x1a\xdb\xd0\x59\x9d\x2a\x51\x64\x5d\xca\x98\xa4\x24\xc0\xd2\x2e\x4e\x83\xdb\x4f\x5f\x21\x9e\xdc\x82\xd4\x44\x31\xf1\xc9\x79\xf1\xd9\x83\x58\xeb\x5e\xbc\x60\x72\xb1\x22\x88\x2c\x6c\xe8\x25\xf3\xdf\x25\x42\x82\x3f\x79\x8f\xd5\x42\x44\x3c\xb4\x7b\xac\x33\x5e\xc0\xeb\x8d\x82\xe9\x69\x38\xc1\x3a\x93\x83\x81\xff\x9e\x35\xcd\x59\xcf\xea\xd2\xe6\xec\x4e\x21\x99\xc6\x15\xce\xf1\x17\x2e\x9b\x3c\x91\x44\x1a\xa5\x79\x67\x04\xef\x10\x48\xd6\x26\x65\xa2\xd2\x40\x12\xa5\x95\x08\x9d\x9d\x60\xc7\xed\x23\x89\xa6\x04\x85\xf9\xf6\x1a\x9c\xc5\xc4\x08\x1b\x7f\xea\x55\x0a\x43\x3e\xa9\x15\x8d\xaf\x45\x4b\x83\x41\xaa\xa5\xd9\x59\x9f\xb4\x41\x10\x9b\x68\x23\xb0\x82\xf3\xfd\xc7\xdd\x68\xbe\x43\x14\x19\x6b\x73\x83\xf6\x58\x6d\xcc\x59\xf7\x82\x95\x24\x01\x6a\x34\xf7\x78\xc1\x57\x28\xae\xcb\x6a\x56\x6f\x7e\xf0\x6e\x01\x8b\x71\xef\x6f\xaa\x4f\x4f\x95\xed\xce\x96\x5a\x94\x63\xbb\xb8\xbf\xc1\xde\x67\x47\x93\xf9\x03\x9a\x60\x0c\xeb\x4c\x31\xdd\x12\xfc\x2b\x63\x81\x5f\xc5\x5e\xf3\x8f\x1b\x4c\x98\x5a\xf9\xf5\xe6\x0a\xdd\x28\x65\x3e\x35\xea\x23\x89\x21\x01\xa6\x1f\xb6\x83\xd3\x29\xd2\xed\xca\xee\x05\xf0\x03\x29\x11\x81\x87\xa7\x5a\xe8\xa4\x9d\x16\x37\x59\xdd\xfc\x10\xf9\xa6\x18\x6f\x22\xdd\xc7\x84\x1e\xb6\xb4\x6f\xb3\x02\x2a\x91\x5f\x30\xc8\x69\xc7\x5b\x17\x09\x74\x72\xd8\x65\x50\x45\xdd\x05\x18\xe6\x54\x02\xda\x24\xa8\x73\xf1\x1e\x7d\x3c\x0d\xa2\x74\xa0\x13\xec\x2e\xd4\x5e\x98\xf5\x91\xf0\xe3\xa8\x42\x2f\x96\x5b\xd1\x86\x35\x77\xf0\x65\x0b\x26\x0d\x98\x46\xd1\xfe\x97\xec\xf9\xc5\xe9\xef\x74\x27\x02\xee\xdb\x11\x9b\xda\xc2\xe2\x91\x1e\x71\xf5\xb9\x6d\xd3\xe7\x71\x02\x90\x86\x61\xcc\x7d\x54\x57\xd4\x2f\x25\x60\x4b\x0a\xba\xc3\x2a\xe2\x43\x99\x09\x34\xa1\x69\xdf\x9c\x68\x7c\x57\xd3\x28\x30\xdc\x81\xf5\xd6\xa2\xca\x33\xa8\x9b\x8e\x3b\x37\x19\x19\x5a\x1d\xae\xd5\xfa\x8f\xef\x9b\x6f\xdf\xf7\x3f\x3c\xde\x35\x8d\x92\x48\xc6\x4e\x82\xc3\x46\x77\xa0\xbd\x48\xf3\xe7\xf4\x2c\x26\x45\xe6\xc5\x8b\xa8\x97\x65\xf1\x06\x55\x33\x51\xba\x69\x87\x58\xb2\x63\x1b\x38\xae\x3f\x8e\xbf\xf5\xad\xb8\xb3\xf5\x3b\x25\x24\x61\x03\x66\x89\xed\x17\x75\x37\x89\xc4\x09\x16\xef\x56\xba\xac\x6f\xb3\x26\x7b\x1e\xb2\x04\x52\x22\x03\x6e\xfb\x79\xcd\x4b\x56\x3c\xdf\x64\xd2\xcf\x90\x94\x69\x15\xf7\x88\x85\x5f\x19\xfd\xba\x0f\x71\xae\xb0\x7c\xb0\xf7\x1d\x9d\x4b\x62\xd2\x24\xe5\xb1\x65\xba\x66\xf5\xff\x42\x55\x4e\x64\xdb\xfd\x18\x45\x51\x4e\xc7\xf6\xb5\x16\x95\xa7\x65\x77\x87\x63\xac\x0e\xc8\x28\x44\x9c\xb5\x1d\x35\x8a\xa7\xd2\x58\x09\x94\x6d\x29\x4e\x07\xb7\x58\x3e\x82\x2a\xab\x89\xbd\x02\x49\x63\xcd\x34\x1b\xac\x5f\x3d\x73\xce\x65\xcc\x69\xc2\x14\x86\x02\xeb\x8f\xbe\x6e\x9a\x26\xa9\xc5\x32\xba\xe5\xfa\x0e\xde\xb1\x66\xf2\x08\x22\xdf\xac\x66\xc3\x65\xf7\x41\x11\x73\xbc\xbd\x87\xac\x80\x73\x2b\x4f\x92\x8a\x94\x59\x07\x05\x7c\x0b\xba\x0c\x74\x5d\xe8\x9e\xe3\x48\x52\x21\xb9\x89\xbc\x4b\x99\x4d\x4b\x67\xb4\xb4\x49\x2a\x54\x18\xdb\xec\x5a\x7c\x42\xb5\xc5\x86\x5e\xe7\xa3\x43\x52\xc9\x25\x49\xdd\xec\x7d\x2b\x11\x33\x68\xca\x6a\xde\x52\x87\xa4\xca\x48\x2b\xee\x55\xdb\xa2\xd6\x97\x65\xba\x14\x22\xbb\x94\x63\xd6\x85\x19\xf7\x05\x87\xa1\x6e\x3c\x0f\xa8\xef\xfd\x7d\x5e\x09\xf5\xfa\x78\xc6\x8a\x4b\x21\x52\x94\x4d\x5e\xb7\x5d\x79\x9d\x55\x87\x09\x9d\xd8\x8f\x4f\x19\xb2\x9a\xf7\xd6\xf8\xe3\xcc\x02\x91\xa4\x26\x49\x03\xdd\xc1\x66\x31\x82\x18\x75\xc6\x06\x23\xb5\xed\x7d\xb8\xe2\xe2\xf8\x7e\x4f\xbe\xd7\x38\x58\x51\x9f\x48\x1d\x0e\x19\xfa\x6e\x8f\x1f\x90\x08\x22\xc1\xbd\xa2\xe4\x8d\x40\xcb\xd9\xc1\xae\x2c\x82\x48\x21\x2b\x44\x42\xb3\xd0\xfa\xbc\x9f\x3f\xff\x8e\x89\x88\x13\x74\xe4\x3c\xc2\xf3\x33\xe8\xed\xe7\x41\x96\x1e\x29\x28\xa2\xd8\x60\xb1\x17\xea\x26\x3b\x08\x2b\x05\xf1\x50\x36\x5b\x00\x3d\x4a\x71\x04\x91\x9c\xd1\x0e\x3b\xd3\x5e\xfb\xe4\xb8\x0e\x50\xfb\xce\xd1\x70\x71\x7d\x99\xb8\xef\x13\x41\x80\x73\x97\x29\x5b\x0c\xdf\x8d\xa8\x9b\x07\x91\xe9\x33\x78\xb4\x7b\xdd\x04\x05\x95\x20\xa8\x63\x79\x3b\x6b\x41\x33\x7c\x9b\x04\x4b\x42\xeb\x4f\x6e\x15\xed\x01\xaa\x71\xfc\x7f\xce\x2e\x3f\xef\x9a\xb6\x27\x41\x84\xcc\xed\xe2\x8f\xfd\xd3\xe6\x6e\xd7\x69\xc4\x12\xc1\xc0\xfa\xdb\xd9\xb8\x7e\x28\x7b\x31\xbe\xe1\xb1\x8e\x70\x5b\xb5\x22\x69\xab\xa7\x47\x24\x17\x78\xc5\x41\x22\x12\x12\x62\xc8\x83\x8b\xc4\xdf\x4b\xd9\xfd\x3d\x16\xe8\x16\xf3\x2c\xea\x6e\xeb\xf7\x87\x94\x15\x44\x56\x65\xd1\xf4\x49\xac\x48\xb4\x25\x58\x58\x18\xe8\xb4\x94\x2f\xd2\xc4\xaa\x75\x3d\x94\xc7\x53\xbe\x6d\xc4\x50\xcb\x8b\x88\x34\x05\xf7\x8e\xe5\xa0\x46\xd2\xf0\x44\x08\x65\xab\x91\x57\xa2\x86\xdb\x72\xd0\xdb\x12\x32\x60\xd4\x25\xa0\xed\x41\x04\xf6\x3e\x1d\x07\xb6\x71\x6e\x9c\x8a\x02\xa4\x30\x20\xdc\xae\x27\x16\x76\xbf\x48\x71\xdb\x7d\xd9\xbe\x94\xef\x68\x66\x0b\xcb\xf3\x25\x4b\xa8\x38\x62\x9d\xad\x53\xd5\xbe\x31\xb3\xab\x91\xd0\x29\x45\xc1\x11\x1f\x62\xb5\x73\xb8\xd7\xe7\x24\x42\xcb\xc8\xa9\x62\xb4\x2b\xdb\xae\xf4\xb5\x7d\x01\xdc\xb5\xc1\x3b\x4b\xf4\x1e\x33\xfd\x55\x0a\x2f\x20\x0e\x91\x14\xd4\x64\x50\xd1\xee\x6c\x49\x22\xf4\x00\xf1\xfe\x7b\x56\x3c\xeb\xf2\xd0\xfd\x68\x13\xd8\x26\x9a\x63\x5c\x6f\x8a\x6f\x65\xa9\xb7\x8d\x28\x7a\x7b\x11\x9f\x55\xc9\xc0\x58\x7b\xbf\xa3\xc8\xb4\x2d\x29\xfc\xcc\x5e\xb3\x07\xf1\xfc\x45\x6f\xb8\xbb\x3c\x19\x32\x2b\x5a\xf8\x50\xd6\xcd\xcf\xac\x3e\x73\x01\x19\x79\xc9\xcd\xa6\x84\x32\xe4\x3a\xb5\x16\x84\x56\x85\x0b\x46\x53\x44\x86\x09\x47\x68\xf8\x42\xbf\x65\x75\x59\xd5\x0f\xa2\x6a\x0a\xa8\xea\xd1\xba\x20\xc3\x94\xe2\xce\x7b\x57\x6a\x98\x18\x00\xfa\x57\x4e\x86\x26\x09\x3b\xdb\x4a\x34\xa2\x18\xce\x14\x49\xe2\x0e\x97\x81\x6d\xfb\x4e\x08\x96\x48\xa2\x6d\xbd\x58\x89\xba\xc1\x5d\x65\xd8\x27\x77\x63\x68\xc8\xb1\x7a\xd7\xce\xd6\xcd\xf2\x7e\x66\x9b\x95\x8c\x5b\x0c\x8b\x2b\x4d\x2f\xf2\xdc\x56\xa7\xbb\x4b\x60\x09\x45\x20\xc4\xcf\xf5\xfa\xf7\xed\x3e\x0c\x68\x77\x40\x72\xd4\x7b\x3b\x64\xc5\xd8\x13\x81\x48\x66\x04\x2e\xad\x1d\x37\xa0\x9d\x9b\x8f\x30\x16\xf3\x26\x92\x4b\x61\x58\xef\xb4\x6f\x37\x52\x7f\x8e\x58\x87\x89\x0b\x85\x57\x1d\xde\x79\xf6\x0d\x90\x09\x93\x18\xa6\x5b\x35\xc1\x5e\x7e\x4c\x34\x70\x46\x48\xb8\xf8\xef\x57\x96\x65\xfe\x7b\xa4\x15\xb1\xf7\x9b\xd9\xe6\x7c\xdb\x9b\x49\xf3\x64\xa2\xa2\xb4\x77\x32\xc2\xb8\xea\xde\x0c\x20\x20\x6e\x58\x1a\x6a\xe4\x2d\x7e\x6b\x03\x30\x35\x6c\x59\xcb\x54\x13\xeb\x3f\x24\x4f\x9f\xa8\xf6\x31\xff\x62\x4a\x11\x01\x96\x63\x5f\xb2\x63\x1b\x12\x1c\x30\x1d\x79\x84\xff\xf8\xf3\xc8\xd8\x72\x66\x9f\x2d\x82\x77\xf1\xdc\x7d\x83\x14\x90\x5a\x97\x01\xbd\xd7\x7d\x7c\x25\x55\xa8\x50\xa9\xaf\xef\xe9\x76\x47\x78\x84\xdd\x87\x5d\x75\xea\x75\xde\x86\x8b\xac\xd4\x49\x40\x78\xef\xbc\xe5\x14\x9c\xae\x4f\x85\x9a\xcc\x03\x9d\x52\x84\x17\x0b\x29\x0a\x5d\x16\x4e\x70\xc5\x15\x8f\x26\x77\x09\xa4\x44\x8e\x87\x29\x2b\x05\x7f\x2d\x28\x97\x46\x58\x8b\x87\xdb\x4c\xbd\x8e\x44\x1d\x89\x34\x46\x21\xf1\xd3\x0a\x59\x0f\x0b\x01\x2a\x88\x08\x8a\xe6\xea\xd2\x66\x87\x87\x39\x0d\xb9\x09\xcd\xb7\x7f\xea\x2a\xa4\x51\xd0\x6e\x23\x95\x30\xa6\x3f\x69\x44\x25\x22\x3e\xfc\x2a\xa8\x27\x19\xb4\xa2\x22\xb4\xca\xad\xd0\x6c\x55\xa1\x47\x9e\x20\x6e\x08\xd3\x82\xba\xa2\xe0\x37\x51\xa3\x16\xd5\xad\xf8\x98\x9c\x87\xab\x50\x38\xd3\x8e\x25\x1a\x82\xe4\x8b\xb1\xd4\x45\x37\x4e\xeb\xfe\xdd\x69\x5f\x99\x87\x5c\x9c\xc5\x1a\xa3\xe5\x59\xc5\x11\x05\x47\x13\xbb\x29\xeb\x7e\xad\x50\x31\x05\xac\x44\x1d\x7b\xe3\x80\x8e\xde\x72\x96\x4c\xaa\x38\xb6\x21\xdf\x51\x9c\xea\xde\x11\x8e\xa8\x58\x5a\xa5\x00\x9f\xe4\xef\x9b\x72\x0f\x4d\xd6\x1d\x56\x41\xe4\xd8\xd3\x23\x8f\x75\xa2\x62\x1d\x2a\xab\xca\x62\x6d\xc4\x07\x4f\x23\xa1\x69\x1a\x78\xe5\xed\x77\x44\x86\x5e\x6a\x96\xa8\x44\x68\xd5\x35\x0d\x6f\x40\x3c\x9f\xe0\x1c\x6a\x36\x64\xfd\xa8\xd4\x31\x13\x6c\xf4\xe5\x67\xa5\xe3\x41\xfe\x25\x09\x3c\xa2\xd2\xd0\x82\x13\x6b\x61\xda\xdf\x75\x31\xc0\x1d\x7d\xaf\x4c\xb0\x77\x73\xac\x60\xa3\xca\xed\x44\x54\x9e\xa8\x54\x29\x63\xb3\x84\xdf\xe1\x73\xa4\x1d\x37\xf9\xc9\x82\xc6\xb1\xc3\x83\x5c\x55\x02\x53\x2c\x31\x79\x5a\x82\x31\x1d\xf7\x89\x9e\xff\x91\xcb\x97\x2c\xd7\xd5\x10\xc9\x3f\xf9\x98\x10\xe8\x0d\x8f\x19\xac\x4d\x3c\x26\xed\x08\x25\x01\x30\x7e\x6e\xda\x14\xf6\xbd\x5c\x65\x6f\x56\x14\xce\x1f\x57\xd4\xa0\x0e\xe8\xf5\x66\xb5\x18\xbe\xbc\x4a\xa5\x8a\xb8\xe5\xec\xe6\xa4\x5e\x3f\x1d\xb2\x63\xdb\xd7\xd1\x94\x26\x24\x21\x1d\xe0\x1e\x91\xfa\x13\x4f\x09\xa2\x74\x0c\xba\x83\x36\xfd\x5d\xa8\xd7\x63\xd9\xdc\x6b\xdd\x9d\xc2\x28\x94\x7d\x73\xaf\xac\xb7\xe3\x20\x0a\x42\x85\xb2\xfc\x7f\xdf\xfe\x7d\xd9\xfd\xcd\x89\xc4\xb6\x69\xd6\xe0\x79\xcc\xae\x4b\x0a\xe2\x38\x89\x47\xfb\x89\x65\x05\x2c\xbe\x10\xa5\x21\x0a\x34\x89\x2c\x77\xac\xc0\x08\x74\xfd\xe1\x23\x3a\x65\x88\xb2\x16\x58\xaa\x9c\x90\x7e\x94\x61\x09\x6e\x0d\x0b\xac\x66\x74\xc0\x7e\x65\x94\xad\x83\xad\xd6\xd7\xc3\x7b\xab\x83\x28\x10\xee\xde\xde\x8a\x22\x33\x50\x37\x9b\x73\x45\x8c\xd1\xba\xa0\x83\x38\x02\x27\xd8\xa7\xa0\xae\x47\x26\x8e\xb3\xfb\xad\xff\x9c\x60\xe8\xab\x7a\x0b\xf9\x64\x79\xd2\x21\x0d\x10\xac\xb0\x2a\x1f\xcb\x7c\x9e\xed\x32\xde\xc1\x27\xff\xf3\xe5\x3b\xa7\x43\x60\x32\x75\x7c\xce\xd3\xf1\xc2\x6d\x9f\x7c\x26\xa2\x5a\xb9\xf4\x7c\xf7\x79\x84\x85\x7e\x13\xe8\xb7\xe3\x5f\x3a\x1d\x29\x10\x91\x97\xbb\x50\x6d\xe4\x38\xf1\x02\x99\xbf\x16\x42\xa5\xf0\xf9\x4c\x5e\x36\x85\x0f\x84\x34\x8b\x14\xb6\x12\x32\x55\x92\x5e\xdf\x46\xb3\x44\xa1\x8b\xe2\x75\xf4\x34\x7a\x70\x2c\x35\x81\x43\x95\xfc\xbd\x94\x8e\xa3\x31\xfc\xca\xc4\x0f\xd4\x11\x02\x0b\x30\xaf\xca\x8a\xda\x53\x4e\x26\x4f\x80\x01\x45\x85\x83\x9b\xf2\x79\x5d\x55\x65\x75\x5b\x8f\x4c\xb2\x88\xe6\x84\x6a\x2f\x77\x75\xcc\x8a\x47\xa8\x4f\x79\x73\x39\xee\x1a\x9f\x9d\x93\x04\xd3\xe2\x4c\x95\xae\xbc\x3a\x22\xfe\x6a\x4e\x05\x37\xbe\xdf\xbe\x6f\xcf\x7d\x80\xde\x13\x88\x68\xae\x02\x2c\x5d\x3e\x40\x71\x5e\xf8\x9e\x7d\x7f\x74\xcc\x29\x3e\x1f\xff\xd6\xf5\x7a\x2f\x63\xfa\xd0\xfc\x63\x4a\x99\x95\xa1\xc3\x15\x4a\x4e\x94\x79\xfe\xe5\x07\xc5\x14\x9b\xa2\xdf\x1e\x17\x0f\xeb\xfd\x76\xbd\xdc\xee\x77\xf7\xfb\x6f\x8f\xf7\x3f\xf7\x3f\x36\x77\xbe\x05\xac\x05\x8f\x85\xdb\x94\xae\xdb\x70\xe6\xae\x36\xef\xae\x93\xe1\x7a\x81\x7e\xa0\x10\x0c\x7c\x9f\xe8\x15\xe1\x3f\xe7\x35\x21\x2d\x93\xc8\x60\x09\xe5\xd4\x8c\x66\x84\x0e\x65\xe2\x66\xc4\xc2\x7a\x98\xff\x62\x8a\x6b\x66\x10\xe4\xd0\x6d\x64\x45\x93\xfd\xe7\x04\x97\x74\xd4\xfc\xa7\xb4\x42\x59\x12\xac\xe0\x94\x65\x23\xcb\x8f\xc9\x54\x82\x80\x0f\xdc\x78\xd7\xb5\x12\x47\xf8\x2e\x1a\xf5\xb2\x14\x79\x3e\x0d\x73\x34\xf0\xd0\xe0\xaa\x20\xaa\xb7\x0e\x50\xa5\x21\xe5\x08\x29\x3b\x6f\x80\x4f\x3e\xad\xb4\xe2\x9d\x8e\xd2\x8f\x32\x5f\x58\x95\x87\x09\x90\x47\x1b\x1a\x32\x97\x61\x6d\x1f\x16\x8f\xcb\xd9\x5e\xa5\x36\xca\x82\x24\x4e\x05\xee\x63\x08\xac\x9a\x17\x97\xf3\x1f\x80\x14\xab\x13\x59\xbd\x02\xe3\xa0\xf7\x3d\xf0\xde\xbd\x82\x10\x70\x40\x31\x81\x2e\x4f\x5a\xcc\xb2\xe5\xdd\xe8\x30\x04\xe5\xb0\xe1\x57\xaa\x3c\x1d\xcb\xce\x00\x6a\x59\x76\x8d\x32\x08\x09\x20\x90\x77\xfd\x01\xea\x74\x8e\x0c\x80\x48\x1b\x8c\xe8\x0b\x78\xdf\x81\x70\x1d\x7b\x3d\x69\x82\xff\x85\x7f\x06\xa7\xb3\x3f\x14\x7f\x01\x56\x3b\x46\xeb\x03\x10\x62\xf9\x8d\xa6\x2a\x0f\x2e\x60\xfb\x26\x1a\x78\x17\x93\xb6\x00\x10\x4e\xf1\xca\x2b\x7c\xcb\x07\xa1\x38\x10\xae\xb0\x7a\x89\x3b\xca\x4d\x29\xf4\xb9\x1a\xad\x1f\x09\x09\x17\xbd\x8f\xe6\x56\x14\xe3\x8b\x61\xd2\x3a\xfa\x21\x9e\x65\x5f\x1f\xcf\x7a\x6a\xc0\x5d\x67\x14\xe9\xaa\x6b\x51\x15\x97\x14\x2f\x80\x73\x06\x0e\x14\x7f\x5b\x16\xed\xdc\x9a\xf7\xe5\x99\x5c\x22\x8f\x83\x30\xea\xdb\x15\x23\xc8\xb0\x1b\x12\x87\x96\x6e\xeb\x95\x94\xd7\x03\x44\x37\xc4\xd4\x32\xf5\xda\xc8\x5e\x1c\x17\xcd\x4f\xc8\xa6\x1f\x07\x6d\x81\x12\x27\x79\xc8\x1a\x84\x00\x4e\x06\x18\x0b\x01\xb4\x41\xbf\x9d\x29\xa5\xcd\xbe\xc7\xd7\x9a\x30\x6b\xa5\xf4\x0c\xcd\xfe\x35\x2b\x9e\xad\xf2\xad\xbf\x92\x44\x06\x89\xf5\x6b\x78\x80\xba\x1c\xae\x39\x90\xc8\xa4\xf3\x60\xb2\x96\xf5\x03\x85\xa6\xf9\xdb\x99\x68\x13\xbb\x88\x63\x7f\x74\x16\x74\x1d\xfa\x76\x3c\x34\x0d\x0c\xaa\xad\x1f\x50\xab\x15\x6e\x8b\xe6\x38\x7e\xcc\x29\x4f\x91\xcd\x87\x6f\xeb\xa6\xae\x4f\x53\x12\x34\x08\xa2\x95\x03\x0a\x5d\x44\xd1\x80\x88\x45\xe4\x9e\xf0\x15\x36\xea\x5e\xc6\x98\x75\x10\x89\x45\xcd\x5b\x70\x3e\xf2\x13\x9f\xb2\xa2\xf9\x6d\x6e\xeb\x00\xc9\xac\x3c\xed\x21\x3b\x2f\x5f\x4f\x46\x72\x1a\x63\xa7\x65\x79\xd7\xfb\xc8\x13\x80\x28\xc2\xc7\x66\xd5\x7f\xbf\x55\x70\x81\x00\x0e\x20\x43\x6a\x9b\x71\x96\xa9\xe9\x4f\x60\x18\x4f\x1d\x6f\x05\x4b\x84\xbb\x0a\x4d\x2f\x27\x42\x4c\x83\x9d\xc7\x04\x09\x89\x6c\x15\xc6\x9a\x6e\xef\x1d\xdf\x75\xb3\x1a\xdf\x2a\x13\x6a\x81\xb4\xbe\xab\xec\x1f\x7f\xdd\xc4\xb8\xfd\x98\xc1\xa2\x87\xcf\xf5\x9c\xbb\xc3\x42\x1f\x2e\x01\xe3\x4d\xa4\xad\x71\xd3\x54\x4b\xe2\x67\xd6\xbc\x7c\xcf\x0a\xa4\x30\xda\x1e\xe0\x4e\x64\xf9\x6f\xe3\xcf\x42\x8c\xc4\xf4\x46\xbc\x82\x95\xde\x1e\x9f\x9b\x04\x36\x5b\x79\x86\xe6\x4e\x54\xaa\x9c\x1e\x0e\x53\x9c\xa2\x57\x67\x1d\x5e\x3f\x20\x8a\x11\x8b\x7e\x0d\x70\x18\xc0\x95\x0d\x21\x94\xda\xcc\x54\xe8\x4e\xed\x6d\xfe\xe7\x11\xa6\x50\x50\xfe\x1d\xe4\x08\xb5\x6d\x48\x4c\xb0\xe0\xd7\x8c\x72\x3c\x43\xa9\x4d\x87\x0f\x59\x61\x5f\xb5\xac\x78\xee\x9b\x81\x17\xbe\x84\xd2\x80\x8b\xbe\x34\xd3\x95\xcc\xba\x93\xc6\x11\x06\xc6\xb7\x0f\x3e\xd2\x32\x2c\x90\x08\x1a\x87\x8f\x06\x06\xee\x64\xc4\xc4\x41\xdc\xf7\xb7\xba\x3e\xff\xf8\xfb\x62\x95\xe2\x82\xf6\x54\x43\x85\x2d\x7e\xff\xe1\x24\xb1\x70\x3c\x2c\x7a\x35\x22\x7f\xcc\x9e\x07\xb2\xcb\xed\x71\x1d\x39\xec\x59\x33\x83\xc3\x35\x09\x24\x1d\x7f\xaf\x76\x40\xd7\x4d\x61\xca\x31\x43\xc3\xa4\x29\xc5\x17\x19\xed\xb4\xac\x83\xf3\x28\x75\x31\xa9\x24\xdc\x05\xb1\x6d\x26\xdd\xb9\x8d\xbb\xc3\xa2\x8d\xaa\x7d\x82\x8f\x7a\x3f\x03\x90\xa2\x91\x21\x04\xc3\x49\xbc\x7c\x19\x28\x6a\xfa\x31\x29\x20\xe8\xec\x35\xcb\xf3\x2d\xe4\x66\x7a\x58\x84\xc8\x6f\xdb\x23\x63\xed\xf9\xa5\xe9\x50\xd8\xdd\x25\x4a\x63\xc5\x09\x6a\xeb\x14\x34\x59\xaa\x8d\x62\x1c\xa1\x0e\xfe\x22\x9e\x0a\x94\x38\xee\x32\x3d\xa3\x98\xc1\x45\xc1\x12\xa9\xe1\xe1\x54\x0d\x44\x2b\xc7\x77\x43\x71\xc2\x7b\xdb\x66\x8b\x93\x45\xcf\x93\xee\x5c\xc6\x20\xfb\xfd\xfe\x38\x5b\xe1\xf8\x35\x4a\x72\xca\x80\x9e\xd4\xd3\xe6\x67\xad\x0e\x38\x16\x8c\x74\xe9\x3a\xd9\xd7\xd3\x6c\xc5\x68\x1a\x20\xf0\xb9\x13\x8e\xf9\xcf\x09\xaa\x4e\x8d\x0f\xbf\xed\x9f\xf4\x5f\xd3\xf3\xa6\x24\x75\x61\xd8\x95\x67\x0b\x75\x9e\x38\xc4\x68\x69\x73\xd0\xab\xdd\x76\xd9\xff\x4d\x22\x8d\x76\xb5\x5e\x6e\x6e\x17\x37\x7b\xeb\xac\xe5\x8f\x1a\x96\x60\xeb\xce\x8a\x8c\x60\xb4\xeb\xed\x8a\xba\xb5\x95\x06\x81\xe0\xda\xf6\xec\x7e\x81\xd8\xf1\xe3\x75\x80\x1d\xda\x07\xd7\xcc\xba\x98\x5b\xbb\xf1\xa1\x8a\xb0\x54\x5a\x9f\xa4\x65\x93\x1c\xbe\x12\x67\x9f\x7c\x38\x92\x09\xf6\xba\x3a\x37\x60\xdb\xb9\x45\x34\xca\xc6\x4c\xf3\x88\xb9\x7a\x00\x0d\x48\x64\x90\xbc\xd1\x80\x70\x1a\xf7\x61\x34\x34\x80\xa4\x01\x15\x12\xd7\x21\x25\x72\xe5\x8d\x13\xdc\x6f\x3b\x4f\x59\x69\xc0\x48\x84\x51\xf5\xde\xd2\x1b\xd4\xbc\x38\x03\x0d\x58\x2c\xb0\x3b\x5e\x95\x79\x3e\x82\x43\xd0\x80\x09\xa0\x41\xc7\x87\xdb\x9e\xa4\xd5\x4d\x9f\x20\x99\x68\xc0\x34\xe0\x0b\x29\xf2\x77\xf1\x59\xa3\x28\x55\x33\x1d\xc3\x99\xe4\x5e\xec\xe7\x20\xf2\xdc\x2a\x9c\xf8\x83\x71\x82\x9c\xfc\x59\xc2\xda\xf0\x47\xf1\x94\xe1\x3d\x90\x28\x12\x66\xb1\x63\x1d\x2e\x1d\x0f\x2b\x4b\xf9\x5f\x23\x0d\xf1\xb1\x13\x2b\xa3\x01\x07\x82\x29\x52\x9d\x15\xcf\xb9\xad\x3b\x7e\x13\x75\x9f\x0d\xd0\x20\x0e\x02\x9c\xa7\x5b\xd1\x94\xea\x25\xa3\xdd\xdf\x99\x92\x7a\xa0\xaa\x60\xeb\x04\x30\xfd\x85\x09\xb1\xee\xc7\xdf\x27\x6e\x48\x34\x48\x18\xa3\xa9\xa7\x2e\x2e\xbe\x2e\x6e\xd0\x20\xe9\x33\xdd\xdb\xac\xc8\xda\x90\x74\x8d\x5a\x46\xc3\x70\x8a\x06\x89\x89\x49\x67\xb1\x54\xa2\x09\x89\x3b\x92\x32\x86\xc2\xce\x59\x7d\x57\x36\xab\xd3\x31\x47\xe7\x4a\xcb\x0b\x1b\x1b\x92\xd1\x20\x4d\x99\x8f\xda\xdc\x59\x3a\x82\xd3\x68\xb5\xa0\x81\x88\x68\xac\x3a\xe2\x49\xf5\x89\x77\x6e\x74\x45\x22\xb6\x57\x34\x64\x51\x5d\xee\xc3\xd3\x40\x68\xe9\x2d\x7a\xd7\x1f\xc7\xb2\x42\x06\xaf\xa8\xfc\xce\x4a\x03\xad\x68\xe2\xd4\x68\xd6\x07\x91\xe5\x43\x93\xb4\xbf\x8d\xaf\x4e\x6b\x8d\x15\x9e\x5b\x10\x8d\xc5\x49\x21\xc1\xdc\xb1\xfe\xca\x79\x7c\x2c\x0d\xb4\x89\xb0\x7c\x6e\x85\x51\x9f\xac\xc6\xa4\xff\x7a\xa0\x36\x00\x12\x56\xbc\x00\xb6\xe8\xbf\xe6\x97\xc7\x7e\x6d\x02\xea\x2c\x8a\xac\x57\x16\x96\x7c\x47\xed\x4d\x1a\x80\x60\xcc\xea\xbe\x5e\x8b\xb7\xb2\x72\x12\x2c\xf3\x3f\xc5\x50\x03\xae\x04\x71\x85\x77\x26\xb3\xd4\x72\xa7\x7c\x36\xfe\x01\x86\xa5\x48\x09\x7b\xcf\x0a\xeb\xf7\xa4\x5e\x51\xf1\x47\x4e\x76\xff\x76\x24\x50\x9f\x32\x88\x3c\xdf\x17\xa7\xc3\x3e\x87\x37\xc8\xbb\xb7\xd0\x80\x41\x89\xca\xdb\xdb\x5b\x39\x16\xc3\xfa\x45\x7d\xea\xcb\xb8\x95\x86\x41\x10\x60\x5c\xec\x77\xdb\x1b\x78\xb6\x96\x6a\x59\xf1\x0c\x85\xfa\xb4\xb5\x4f\x3f\x98\x00\xb8\x92\x61\xf7\xfd\xe7\x26\x41\x34\x0c\x28\x8b\x84\x07\x45\xda\x5b\x3e\x08\x86\x68\x18\x70\x85\xd6\x4c\x7e\x5b\x2e\xd6\x1f\x33\x28\x49\x1a\x06\x71\x84\xd4\xf0\x3a\x7b\x2e\xa0\x0a\xbb\x8f\x2b\x89\xcf\x14\x21\x50\xf5\x23\xcc\xfb\x63\xd2\x30\x00\xeb\x00\x73\xea\x38\x32\x3d\xbe\xd2\x0f\x31\x80\x6c\xe0\xd5\xe6\xc7\x66\xeb\xf7\x3d\x1a\x86\x11\xc1\x18\x71\x71\xf7\xc7\x70\xb1\x08\xc3\xd8\xaa\xa2\x75\x3b\x9d\x6f\x87\xfb\xe3\xa9\xf6\x6d\xee\x2d\xe4\xf9\x35\xc0\xd5\x71\x32\x2b\xc2\x50\x25\xd6\x22\xc8\x4a\x00\x3a\x44\xc5\xec\x74\x0b\x43\x25\xbd\x91\xc8\x75\x05\x80\xb1\xc2\xdc\x0d\x8f\xa2\x94\x45\x7e\x11\xeb\xce\x35\xfe\x67\xb0\x54\x87\x51\xcc\x71\xd1\xfb\xfb\x9b\x38\xd7\x1e\xa5\x61\x24\x42\xa6\x7a\x3b\xcd\x02\x54\x0f\x35\x6c\x8f\xd2\x2e\x25\xb6\x61\xfa\x7a\x86\x11\x44\x43\x42\x34\x56\xea\x77\xdd\x6d\x25\x3c\x06\xe5\x6b\xf1\x1f\xcb\xc5\x83\x3f\x40\x83\x18\x75\x08\xf6\x4e\x49\xf6\xec\x39\x51\x96\x04\x49\xff\x1a\x4f\x7c\x20\x68\xc8\x38\x0b\xc0\x46\x3e\xae\x52\xec\x0f\x48\xad\x1d\x2f\x7e\xf1\x3b\x20\x7e\x7d\x22\x89\x38\x1b\xa3\xd1\x90\x9b\x14\x3f\xe8\x83\x8e\xad\x30\x90\xcf\xcb\x21\xd1\x30\xa6\x84\x58\x40\x4d\x6e\xbe\x7f\xca\x2a\xd3\x0e\x3e\x75\x69\xbc\xb1\x4e\x02\x42\x6b\x8b\xbc\xfb\x3a\x02\x0a\x13\x66\x3d\x70\xbe\x8b\xe3\xf1\xf3\x2a\xab\x9a\x17\x3d\x02\x02\xd1\x30\x49\x42\x04\x88\x59\x15\xd7\x8d\x2a\xfd\x81\x34\x60\x18\x02\xaf\x40\x9e\x9e\x37\x5d\x4a\xef\x8f\x86\x11\x16\xeb\xb7\xf7\xcb\xcd\xe2\xe6\x8f\xab\xfb\xa7\xbb\xdd\x9f\xfe\xa3\x32\xe5\x28\xd0\x61\x11\x58\x2e\xfe\xf0\x56\x31\xe3\xe7\x23\x53\x85\x43\xb1\x42\xf8\xcb\xdd\x25\x94\x4a\x22\x00\xa1\x4d\xc0\x54\x19\xf9\x2f\x54\xc4\x66\x86\x47\x0b\xa9\xb7\x6b\xc2\xb6\xcc\x75\x37\x40\x25\xa1\x0d\xfd\x21\x53\xa5\xac\x2c\xe8\xc6\x5e\x5f\xf8\xa0\xba\x05\x46\x81\xc4\xce\xb2\xf3\x9c\x72\x32\x3c\x6b\xa1\x5e\x96\x2f\xe5\xc5\x70\x2b\x34\x21\x41\x10\xa6\xb0\x78\xdf\xff\xc2\x0a\x8e\x79\xf9\x39\xf9\xad\x86\x01\x76\x87\xca\x43\x2d\xb2\x4a\x1c\xbc\x71\x07\x0d\x0d\xe7\xb6\x01\x58\xfa\x60\x6d\xb4\xa1\x47\x11\x04\xd4\xbf\xce\x9d\x9a\xbf\x9f\xaa\x51\x04\x1a\x4b\x7a\x16\x91\x7d\x09\x8f\xf1\xe5\xac\x8d\x22\x13\x23\x62\x0b\xdf\x93\x2d\x14\x6a\x22\x48\x48\x23\x12\x42\xec\xba\x3a\xb7\x9f\xbe\xee\x5a\x81\xfe\xd9\xd5\x94\x68\x44\x78\x82\xeb\xfc\xf6\x24\xaf\xab\xf2\xe0\xe9\x86\x93\x95\x2c\x22\x22\x46\xee\xb2\xb7\xed\xb0\x2a\x2e\x93\x41\x94\x46\x18\xa0\xa1\x29\x1b\x88\x03\x2a\x59\x63\x83\xc4\x7f\x1b\x65\x54\xd9\x22\xcf\x2a\x7b\xf6\x2c\xe8\xd0\x1f\x8c\xad\x1a\xaf\x2d\xb5\xaf\xae\xe6\xca\xda\x34\x62\x44\xb8\xfe\xf0\x66\x79\x3f\x32\x54\xa5\x11\xe3\x42\xf6\x3d\xed\x7f\x9c\xca\xbe\xdf\x30\x1f\xee\x47\x9c\x29\x9a\xf4\xe6\x40\xbb\xa9\xcf\x12\x8d\x62\x62\x55\xc7\xfd\xae\x19\x4d\x7e\x74\x92\x52\xee\x35\x24\x8b\xd3\x71\xba\x9c\x45\x09\xc4\xb2\x33\x64\xbf\x2e\xab\x3b\x78\x5f\x09\x1f\x5a\x45\x29\x09\x10\xb8\x77\x04\x78\xc5\xb6\x82\x3f\x20\x63\x88\xc3\x01\xb4\xf9\xe6\xdc\x1d\x94\x46\x32\xb1\x24\xc4\x1a\x2b\x00\xbb\x6c\x1a\x6c\x44\x52\x24\xda\x05\x1b\xdf\xa0\x08\x36\x3f\xba\x19\x28\xb5\x2d\x92\x7d\x83\x02\xea\xac\xb6\xeb\xec\x03\x54\x57\x43\x09\x6a\x37\x56\x85\x31\x02\x35\xf1\xe1\xbb\x27\x3a\x15\xaf\xa7\x91\x12\xcc\x3a\x8f\xb7\x49\x0e\xd6\x2b\x46\x05\x0d\x1a\xe9\x34\x4c\x58\x37\xc0\x15\x3e\x16\x8d\x95\x9f\x43\xa6\x43\x3f\x52\x58\x9c\xd8\x4b\xfb\xba\xa3\x84\x24\x88\x6a\x8a\xb9\xa3\x11\x04\x91\x17\x52\x6e\xaa\x13\x60\x18\x35\xb9\x76\x60\x76\x7f\x73\x94\xd4\xd3\x61\xba\x58\xe1\x5e\x39\x5a\xb2\x48\x10\x25\x18\x8b\xac\x77\x7f\x8e\xcf\x46\x82\xc8\x4a\xfd\x1d\x32\xdc\x05\x31\x79\x42\xb5\xae\xdf\xfc\x00\xae\xb0\x0d\x75\xcc\x85\x02\x2f\xdb\x7b\x16\xaa\x92\x20\x85\x34\xee\x30\xf2\x03\x59\x28\x4a\x02\x13\x23\x2f\x63\x97\x35\xc8\x10\xff\xc2\xc4\xee\x97\xb8\x42\x4a\xc2\x20\xa2\x8e\x67\xe0\x44\x33\xb0\x9c\x35\x9d\x49\x24\x14\x81\xb4\x46\xa8\x16\x99\xdd\x86\x34\x83\xad\xea\x57\xdc\x51\x4a\xa2\x20\x40\x77\xa1\xd7\xac\x69\x32\xa8\xc7\x78\x09\x4a\xa2\x90\x62\x6b\x3e\xc3\x0e\x3b\x9a\x5d\x39\xcf\xe2\x75\xa1\xbb\x15\x8b\x10\x0a\x69\xaf\xb7\xd1\x09\x03\x82\x3e\x33\x85\xa7\x84\x30\xab\x66\x8e\x75\x6c\xdc\x44\xfc\xe6\x42\x18\x35\x88\x0c\x5b\x5c\x2d\xbb\x3f\x69\xdb\xe1\x6e\xd3\xb8\xbf\x97\x99\x77\x55\x18\x0a\x0f\x9d\x6d\x12\x84\x01\x43\x17\x88\x02\xde\x97\x2f\x59\x8f\x05\x3c\x1b\x66\x65\x64\x85\xd6\xa7\xfa\x82\xe6\x07\x25\x31\x67\xb8\x51\xe1\xd3\xb6\xc5\xde\xd9\x6e\x4b\x3b\xd2\x42\x22\xba\xbd\xe9\xea\x54\x4d\x21\x55\x94\x24\x2a\xc6\x5c\x06\xcd\x53\x41\xbb\x36\xd5\xc5\x26\xb6\xfb\x54\x9a\x02\x56\xc1\x54\x59\xd4\xa8\x3b\x68\xdf\x3e\xcc\x36\x3b\xea\x1a\x25\xa9\xa4\x68\x90\xf4\xb8\x7d\xb8\xd9\xed\x7d\xf2\x4e\x44\x62\xcd\xd7\x9f\xa1\x79\x6a\xef\x5b\xff\x77\x8d\xb8\x5f\x84\xb4\x24\x49\x32\x8c\x57\x88\x10\xf6\xa5\x31\x79\xf9\xde\xfd\x4d\x52\xaf\x5b\x60\x6d\xf3\xda\xe7\x32\x14\x1b\x6f\x87\xf0\x44\x4e\x02\xe2\x8e\xd4\x3c\x31\xed\x1b\xdf\x19\xa9\x63\xb0\xf2\x4c\x35\x54\xcd\x39\x1c\x8d\x12\x15\x84\x78\xee\x6f\xa2\x3a\x69\x31\xba\x5a\x2d\x01\xd9\x30\x59\xed\xc0\x7c\x56\x73\x52\xcf\x69\xbe\x50\xa2\x8d\x8c\xed\x84\x6d\xb7\x56\x91\x7b\xa3\x4e\x77\x18\x8c\x42\x0d\xe9\x9f\x65\xd5\xbc\xe4\xe8\x1c\x39\xf8\x2a\x43\x84\xd7\x2f\x5a\xe4\xf9\x15\x34\x9b\x55\xf7\xeb\x0d\x0d\x70\x0e\x78\xbb\x59\xdb\xf3\xdc\x3a\x79\x87\x4d\xf7\xc6\x18\x63\x8b\xc9\x1a\xf4\x49\x35\xf5\x8b\xa8\xce\x65\x37\xed\x50\x1a\x50\x8e\x1d\xf9\x36\x8d\xcf\x91\x13\x30\x5e\x4e\x69\xc0\x0d\x3e\xf4\xfa\x45\x90\x55\xa9\xea\xe9\xe1\xd4\x12\x7b\xef\xdf\xb1\xf7\xe2\x73\x34\x1a\xa4\x80\x70\xdc\xbd\x6f\xb8\xdc\xc1\xfb\x56\x68\xfd\xeb\x84\xd5\x9d\x20\x04\x85\x27\x1e\x94\x09\xdc\x91\x28\xa1\x34\xf0\xeb\xa4\xf7\xe8\x7a\x14\x0d\xdc\x66\x83\x0b\x88\x44\xc2\x5d\xac\x75\xd5\xa8\xeb\xb2\x7a\xb5\x80\x53\x77\x98\x28\x4e\x7b\xcb\xd8\xf5\xfa\x76\x86\x66\x4c\x29\x0d\x13\x8c\x3e\x0a\x78\xff\xfd\xa4\xcb\x1a\xdd\x0c\xe7\xe4\xbc\xbe\x7c\xbf\x28\x8b\x0c\xde\x0c\xd7\x29\xbd\xcd\xba\xc9\x40\x19\xb7\x46\x98\x4f\xdb\x55\x53\x86\xeb\xdd\xf7\xee\x40\x6c\xd5\x80\xd6\x1f\xd6\xf5\x37\x13\xf9\x58\xe6\xd0\xb5\x54\xfd\x78\x1e\x30\x84\xd6\xae\x77\xd7\x79\x59\x56\x13\x56\xaa\x1f\x14\x32\xe4\xac\x9f\x8a\x76\x2d\xef\x3e\x2a\x85\x33\x60\x6c\xb2\x4a\x54\x3e\xdc\x2b\xbb\x9b\x15\x33\x9d\xb8\x17\x73\xfd\xb8\x8c\xa3\xb0\x7d\x29\x27\xd1\x20\x8d\x45\x8c\x30\x53\xa1\xf5\xa6\x40\x0f\xe1\x9b\xa9\x7c\x2b\xa5\x09\xa1\xdd\x99\xde\xa0\x68\x7a\x88\x1b\xa5\x09\x95\x58\xd7\xf7\xcd\xe2\x6d\xf6\xd1\x1d\xe2\x14\xa5\x3e\x96\x65\x51\x43\xd1\x78\x89\x47\x7f\x54\xc5\xba\x67\x8f\x7e\xcf\xea\xa6\x83\x58\xcf\x57\x3d\x68\x02\x8a\x76\xf1\xd7\x6d\x1b\x62\x5d\x61\x9c\x35\x59\xa4\xff\x19\x3a\xfb\x1c\x4a\xd3\x28\xc5\x90\x78\xb9\xdb\x7e\x95\xd9\xd0\x94\x24\xb1\x7b\x7d\xaf\xb3\x1c\x6e\x7c\x3c\x34\x7e\x6b\x52\xc3\xb1\x06\xb0\xb7\x5a\x4f\x17\xe4\xe6\x29\x95\x09\x49\xb8\xf7\xfe\xfa\x13\x44\x65\xb7\xc7\xee\xc1\x48\xa5\x50\x2d\x0d\x0b\x24\x9d\x8c\x4c\x1b\xb3\x5f\x6c\x5b\x5e\x7a\xfb\x46\xb7\xab\x3b\xbd\x8e\x6d\xed\x38\x1f\x2b\xa7\x74\x17\xa0\x02\xad\x99\xdf\x0c\x67\xec\xd7\xfe\xff\xfe\xf7\x4c\xc5\x93\x52\xc5\x00\x89\xd5\xb7\x59\x51\x76\xd7\xc1\x2c\x69\x19\x6f\x94\xbd\x49\xf7\xa6\xeb\xed\x51\xaa\x54\x24\xbd\x90\x77\x9e\x5f\x65\xba\xbe\xfa\x5c\xe8\x53\x31\x71\x46\xa0\x54\x87\xe0\x79\x78\x4b\x81\x11\x8f\xd7\x70\xec\x1e\x9e\x4e\x59\x6c\x95\x95\x2c\x18\x73\xe8\x5a\x40\x29\x44\x04\xf5\xe0\xd1\xa9\x34\xcf\x9e\x3b\x9b\xc0\x09\x5c\x93\x52\x50\x96\x5c\x60\x39\xc6\xd6\xb4\xa5\xbf\x64\x16\x04\x5c\xf2\x2e\x4c\x07\x5b\x67\xbc\x2e\xab\xa5\x98\x08\x6b\x53\x16\x84\x21\xa1\x1d\xe2\x00\xf6\xaf\x9f\x6a\x8f\x76\x2c\x7b\x0d\x45\x89\xe6\xeb\x93\x06\x13\x65\x21\x0f\xbc\xe6\x67\xfb\x2b\x87\xf5\x39\x16\x11\x25\xd5\x80\x02\xd3\x39\x82\xd7\xdd\x08\xc3\xb0\x81\x71\x3c\x4d\x68\x29\x5e\x65\x97\x32\x92\x5a\xe7\x88\x67\x68\xee\x4f\x37\x99\x28\x50\xf4\x49\x8d\xdb\x18\x8c\x45\x02\x51\x7e\x3d\xfb\x6f\x2a\x51\x32\xbe\x6c\x46\x84\xb7\xc0\xf5\x5e\x18\xc3\xde\x87\x1f\xc5\x03\x6c\x52\x66\xaa\x5c\x96\x87\x63\x0e\x0d\x5c\x75\xc7\xd2\x10\x8b\x50\x59\x31\x94\xba\xb9\x2d\xbb\xda\x32\xe3\x41\x8c\xab\x24\xd6\x94\x1f\xaa\xb2\x34\xf7\xe6\xe9\x98\x67\x05\xa0\x45\xe3\x2f\x0a\xab\xbf\x92\xed\x76\x5f\x12\x53\x83\x61\xe4\x1f\xd7\xb7\x83\x0a\x07\x4b\x52\xdb\x60\x16\x5a\x3f\x96\x39\x0c\xad\xc3\x67\x97\x32\x96\x46\x14\xe9\xec\x59\x61\x3a\x72\xba\x8f\x79\x59\x4a\x23\xd5\xbb\xf9\x5f\x0d\x68\x74\xc3\x45\x8b\xa5\xd2\x62\xec\xdb\xf7\xfb\x0e\xde\xbb\x4f\xeb\x48\x0a\xef\x00\x9d\x5b\xc2\x87\xc7\x82\xfb\x21\x46\x62\xbb\xf9\x54\x1c\x85\x7a\xdd\x6b\xd1\x88\xfd\x73\x55\x9e\x8e\xb5\xab\x33\x0d\xf1\x7f\x94\x89\x50\xe0\x2a\x7a\xb3\xd8\xee\x76\x8f\x9b\xc5\x4d\x18\x11\x7f\x2a\x41\x92\x34\xfd\x9f\xff\xf7\x3f\x9b\xa2\x3e\x55\xd0\xc9\xa5\x50\x26\x28\xc5\xaa\xca\xbb\x83\x17\xf9\x09\x26\x98\x01\x67\xce\xe4\xfc\xd5\x3e\xe7\xbc\x4c\xba\xe1\x09\xd8\x6a\x70\x7b\x61\x78\x57\xc7\xaf\x3e\x13\x8a\x07\x18\x92\x66\x1f\xa3\x06\x01\x93\x91\x6d\x6c\x39\x2f\x01\xd7\x8b\x19\x10\xe7\x29\x93\x44\x63\x7b\xa5\x80\xf7\xb1\x13\xe1\x7c\xb2\xf4\x65\xb8\xc0\xa4\x62\x94\x3a\x8f\x7d\xdb\x9f\x6c\xc3\xc0\x11\x9b\x90\x32\x95\x58\xc3\xae\xda\x46\xc2\xff\x85\xdd\xc7\xe4\x0d\x57\x42\x63\x18\x7a\xaa\x31\x3c\xfc\xba\xc4\xc8\x74\x18\xe2\x93\xbc\x29\x9b\x06\xaa\x4f\xd4\x19\x71\x64\xb1\x51\x73\x94\xfa\xf1\x22\x40\x13\x45\xe4\x81\x8a\xba\x46\x83\xab\xf3\xbc\x99\x41\x64\xd2\x21\xd7\x68\x2d\xaa\x36\xb4\xaf\x77\xe5\x30\xc3\x65\x40\x68\x68\x39\x36\x87\xac\x78\x74\xce\xc0\xab\xb2\x18\x12\x0e\x29\x03\x63\xcd\xab\x6d\x82\x52\x03\xfc\x35\xac\x2c\x65\xa6\xcd\xfa\x6d\x86\xa3\xf2\x93\x86\x1f\x65\x33\xd5\xe6\xa5\xcc\xb0\x04\x2b\x45\x0b\xa5\x00\xea\xba\xac\x3e\x7f\x56\xe2\x78\x84\x2a\x8e\x7c\x58\xc9\xc3\x20\x4c\xdc\xfe\x70\x7d\x82\xbc\xde\x74\x9b\x31\x0f\x99\xc4\x00\x68\xaf\xb3\x5a\x65\xc7\x1c\x7e\x60\x31\xf6\x62\xb9\x91\x87\x82\xa1\x90\xe8\xe2\xb1\x5b\xf5\x79\x14\x11\xac\x64\x2d\x4b\x55\xf6\x08\xb3\x4b\x6f\x3f\x8f\x0c\x41\x7b\x3c\xf8\x00\xd5\xbe\xfd\xdf\x84\x2b\x3d\x5c\x50\x64\x9f\x5c\x01\x49\xad\x09\xed\xd5\x7f\x9a\xfd\x30\x0b\xe1\x44\x31\x65\x89\x8b\x0d\x38\xea\x67\x6f\x45\x41\x39\xd1\xb1\x05\x30\x88\x46\x48\x51\xc3\xaa\x7c\x2f\xf2\x52\xe8\xa7\xca\x07\x95\x9c\xf2\x90\x7b\xb3\x44\xd1\x88\x4b\xbe\x20\x94\x53\x61\xb8\xe8\x9a\x0d\xc7\xe9\x3b\xec\x47\x01\x45\x8e\xc2\x73\x25\x9c\x62\x0a\x82\x7d\xca\x62\x28\x0c\x38\x39\x33\xd3\x16\xa6\x5b\xa1\x4e\xc0\xe4\x84\x3c\xb5\x3a\x0f\x98\x45\xfc\x0e\x9f\x93\xd5\x80\x73\x13\x20\x74\x6d\xf5\xb8\xf8\xdd\xa7\xba\x3c\xe1\x96\xa0\xe7\x37\xc6\xf1\x66\xc6\x93\x94\xab\xa0\x4b\x60\xa1\xba\x79\x0b\x27\xdf\x9a\x48\x6a\xf1\x26\x1f\x0e\xe1\xe3\xb5\x82\xa7\x97\x97\x0a\xc6\x5c\xa2\xeb\xfa\x15\x9b\xd5\xd9\x10\x25\xbd\xe0\xf0\x52\x54\xda\xaf\xfa\x3c\x35\x56\xe7\xca\xd7\x65\xcf\x0d\x0c\x29\x17\x91\xc1\xa2\xca\xd1\xe6\xa6\x57\xa2\x78\xf5\x1f\x17\x24\xd6\x56\x02\xb3\xcd\x99\xec\xee\x39\x8e\x5f\xb9\x24\x16\x76\x35\x8f\x4e\x99\x89\x8b\xb9\x8c\x2d\xc3\xc7\x2b\xe7\x38\xb3\xd8\xf1\x2f\x92\x71\x4a\xc6\x20\x7a\x3d\x44\xd1\x53\x2e\x8d\x46\x06\x0d\xb4\xb9\xc3\xd5\xa9\x9a\x87\xd6\x51\xae\x42\xe1\xe1\x9e\x77\xf0\xd1\xeb\xb7\x5c\x95\x1d\x1e\x81\xab\x94\x21\xdc\x7f\x7b\xba\xbb\xde\xf5\x7f\xe4\x90\xda\x3d\xe5\xfa\xfc\xa6\x29\x21\x31\x2e\xaa\x9d\x56\xf0\x30\x14\x73\xab\xe3\x24\x9e\x9e\x7c\xde\x58\x37\x3c\x74\x24\xb3\xce\x04\xf3\xd7\x0f\x89\xc2\x36\x73\x1b\x78\x8b\xaa\xde\x14\xc6\x47\xba\xdc\x44\x20\xdd\xba\xeb\x62\xbc\x0a\x14\x64\x6f\xa0\x07\x90\x1c\x6e\x58\x9a\x86\x8e\xbe\xb3\x73\x5a\xf2\x3b\x10\x87\x9b\xb3\x42\x2e\x37\x49\x12\x39\x63\xe6\x9f\xed\xa4\xfd\xb4\xfc\x89\x39\xbf\xf1\xaf\x6a\x8b\x36\xfa\xe3\xe3\xa7\x6e\x52\x83\x10\x47\x65\xbb\x10\x3d\x2d\x96\x72\xd3\xa6\x0e\x76\x93\xeb\x16\x71\xfb\xb0\xdb\xec\xb1\x9c\x24\x1a\xdc\x18\x2e\x49\xe7\x99\x83\x33\x7a\x70\x4c\xd0\xbe\x47\x80\x2d\xa8\x3a\x9c\xf5\x07\xff\x8a\x4a\xf3\x7f\xfd\xd7\x7e\x79\x1c\x84\x5a\xf6\x66\x7c\xd8\xe2\x1f\xb6\xac\xe2\x80\x29\x54\xf9\x7a\xb3\xf4\xf9\x9e\x54\x37\x0b\x62\xf2\x1f\x92\xd6\x8a\x5c\xe6\x42\xbd\xb6\x69\xf4\xfa\x71\x19\x45\x64\xfc\xe4\xe2\x90\x1b\x6c\xed\x1d\x7b\xb4\xc7\xdf\x9c\x4a\x96\xaf\xe1\xc6\x61\x1c\x21\x67\xc2\x52\x68\xa7\x7a\xbc\x7e\x90\x00\x0c\xd5\x5f\x44\xa1\x65\x05\xe2\xb5\x3b\x20\xad\x31\x7b\xef\x68\x3f\x4d\x7e\x2f\xa5\x97\xc3\x69\x10\x47\x21\x04\x9e\x9b\x1d\x2c\xf2\x0e\x79\x4d\x63\x22\x0d\x71\x78\x9a\xb5\x45\x7c\x9e\xf5\x91\x63\x62\x18\xc6\x79\xdf\x45\xfd\x72\x6f\x56\x3e\x90\x8f\x29\xd7\x98\x1c\xbf\x66\x79\x6e\x27\xcb\x75\x59\x7d\x43\x99\x79\x3f\x84\x85\xb6\x10\x86\x37\xdf\x93\xbb\x67\xbe\x82\xc5\x46\x58\xa1\x83\xaa\x02\xe5\xec\x08\x9c\x9f\xed\x64\x64\xa2\xac\xbd\x8c\x2d\x91\xae\x9f\x9f\xcf\x9d\xd9\x69\xcc\x54\x88\x7c\x08\xd1\x34\x70\x38\x36\x4e\xee\xf6\xde\x2c\xaa\x26\x53\xf9\x74\x34\x8f\x04\x62\x3b\xa0\x79\xf9\x2e\x0a\x9d\xc3\x66\x20\x86\x32\x5e\x79\x63\x4e\x22\xf0\x69\xdb\x8b\xa8\xe0\xc5\x09\xb7\xb4\x37\xff\xea\x73\x82\x66\x6e\x87\x33\xbc\x47\x0e\xbb\x5e\x2f\x0a\xed\x39\xfe\xf6\x96\x21\xa6\xfc\x97\xd6\x96\xfe\x6c\x1c\x90\x97\x8a\x56\x0e\xf7\xc6\x0c\xc3\xf1\x98\x0b\x40\xa5\x46\x0b\xd6\x88\xf6\x1e\x91\xe5\x9f\x45\x1c\x9a\xc4\x35\xaf\xda\x80\x60\xcf\x46\x00\xa5\x38\xe6\xca\x22\x31\xd6\x43\x6e\x24\x8d\x93\x28\xc0\xba\x2d\xe6\xd3\xe5\xc9\xb9\x68\x0c\x82\x91\x38\x61\x96\xac\xdb\xce\xa1\xe6\xe5\x11\xf2\x6c\x42\xd0\xa7\x71\xc2\xb5\x33\x31\x6d\x5f\x52\xbf\x1e\x8e\xfc\xd8\x68\x9c\x08\x89\xf7\xea\xfb\x9f\xe3\x0b\x10\x0a\x51\x58\xb6\xba\xb4\x7d\x29\xdf\x27\xf7\x38\xd1\xaa\x4f\x49\xdb\x48\x03\x01\xd9\x93\x42\x69\x9c\x86\x41\x68\xbc\xa0\xb1\x95\xbf\x77\x7b\xdb\xd7\xeb\x4b\x1a\x0a\x04\xbe\x3d\xdc\x3f\x3c\x8c\xae\x2b\x35\x01\xf6\xc2\x5d\x45\x7a\x04\xc9\x8b\x46\x62\x8c\xfd\x7f\x7d\x9d\x7e\x8c\x86\xfe\xc5\xac\xd6\x5d\x8c\x10\x29\x8a\xbc\x6f\x57\xf7\xdf\xd6\xbf\xee\xa6\xc5\x42\x0a\xcc\xe9\xe0\x0d\x1e\xa0\x5a\x77\xfd\xc0\x58\x28\x83\xcb\xe5\xc1\x9a\x46\xd8\x4a\x5f\x36\xcd\xd5\x62\x49\xd2\xc8\x39\x80\x0f\x21\xcc\x34\x96\x2c\xc4\x2e\xcf\x4d\xf6\x9f\x13\x7c\x38\x59\xbc\x01\xef\x7d\x7c\xd9\x4a\x00\xda\x71\x3e\xbc\x7c\x7c\x87\x69\x59\x25\x56\x5a\x24\x56\x8b\x12\x74\x8d\x3d\xd0\xeb\x81\x32\x8e\xff\x46\xcd\x64\x67\x63\x82\x2e\x7e\xf7\x7a\xda\x29\x8f\x21\xb2\x81\x61\xa6\x4a\x44\x87\x76\x64\xf2\x69\xdc\x17\x1b\x66\xd0\x86\x66\x5e\xa0\xf8\xeb\xa9\x62\x12\x83\xfa\x3e\xfb\x1a\x0d\xca\xd5\x1c\x59\xd3\x0f\x35\x56\x94\xc2\x6e\x99\x8b\xac\x9a\x11\xc1\xa1\x49\xc0\x00\x61\x85\x8d\xa8\x9e\xa1\x19\x8a\x31\x4e\xc6\xa5\x96\xfe\xa5\xcb\x0e\xe8\x98\x84\x01\x41\xd1\x04\xed\x2e\x64\x64\x66\x47\x93\x90\x02\x36\xaa\x3a\x25\x7e\x5b\x24\x6b\x73\x98\xa1\x26\xf8\x5f\x44\x41\xb8\x93\x46\xcc\xce\xaa\x63\x2e\x3e\xbf\x89\xc3\x85\xbc\x2b\x89\x20\x50\x69\x47\xbd\x73\xe2\x6e\xff\x1d\x53\x7a\xc6\x27\x26\xa1\xc4\x25\xe6\xc7\xfa\xae\xa7\x73\xd1\x84\x10\x4b\xfc\xcf\x54\x79\x56\xe4\x9b\x9e\x81\x31\xec\x4a\x63\x46\xdd\xde\xc8\xde\x56\xca\x8f\x88\x13\xb4\xc4\xea\x8a\x6d\x33\xcb\xf2\xf0\x5f\xbf\xb2\x24\x2c\x48\xb0\xe2\xd8\xbc\x64\x95\x5e\x9d\xa0\xc7\xfb\xd3\x84\xd1\x10\xfb\xa1\xeb\xdd\xf7\xfd\xee\x7e\xff\x73\xbd\xf1\x47\x38\xa7\x28\x36\x67\xca\xea\xf5\xd1\x46\x90\xf3\xc1\x48\xc2\x8d\x24\x4e\xe0\x0c\x75\xb2\xec\xbe\x38\x2a\x98\xcf\xf9\xfc\xba\x4f\xc7\x3a\x8d\x55\x27\xe4\xae\x60\x59\x81\xb6\xed\x0c\xd7\xb3\x9a\xc5\x60\x24\x82\x33\x2c\xa8\x2c\xef\xef\xae\x37\xdf\x3a\x01\x26\x7f\xf5\x32\xb4\x36\x21\xed\xf6\xda\x46\xab\xa7\x0a\x3a\x07\x2f\x9a\x48\x20\x28\x41\x70\x53\x3e\x5f\x65\xfa\xfe\x08\xc5\x17\x0d\xf3\x0b\x19\xf2\xf4\xb8\x3b\x35\xa4\x31\xce\x84\x47\x27\xcd\x30\xfa\xb1\x69\x48\x38\x16\xd2\xb0\xa6\xbf\x55\x2f\xd0\x3d\xde\x34\x14\x21\x8a\xa7\xe0\x8b\xbd\x82\x43\xf9\x55\x1f\xc9\x7f\x46\x07\x26\xec\x79\xe8\x03\x7e\xd7\x54\x37\xbf\xff\x4c\x14\x85\xd8\x37\x5a\x96\x79\x59\x0d\x85\xb0\xc7\x13\x32\x8d\x52\x2e\x98\xab\xf9\x8d\x8b\x7a\x29\x09\x62\xe6\xe5\x08\xe0\x0d\xf2\x65\xd6\x64\xff\x85\xc2\x01\x37\xc6\x5f\x47\x85\x44\x8d\x22\x8c\xb0\xd6\x8b\xd1\x2e\x34\x21\x93\xd2\x94\x9a\x08\x49\x30\x59\x1b\x74\x6c\x4f\x47\xa8\x6e\xa1\xb9\x60\xd6\x4a\x53\x16\x84\xa8\x97\xf5\x54\xe4\xd6\xfb\x6c\x33\xda\x00\xdb\xe3\x32\xf6\x4d\x9c\x15\x1c\xcf\xae\x8d\x05\xda\x5a\xb3\x3a\x67\x90\x3e\x8a\xad\xa7\x23\xa9\x48\x7b\x40\xea\xc4\x79\x63\x3e\x18\x4a\x19\xeb\x38\x75\x3b\x34\x38\x9e\x55\x5a\xa7\x29\x93\x51\x08\x9d\x62\xc7\xa3\xc5\x14\xf9\xd5\xf0\xcb\x9a\x5c\x1a\x87\x09\x62\xf7\x6f\x45\xf5\x3a\xf4\xaa\x6c\x8f\x68\xdd\x39\x2f\xdb\x2d\xc5\x33\xea\x69\x9a\x50\xa1\xff\xbf\xec\x0a\x9d\x3d\xc7\x24\x91\x98\xd6\x59\xd8\x6e\xf7\xb5\x42\x08\x5b\x41\x7c\x76\x65\xcb\xf6\x2b\xa7\x25\xd9\x3e\x49\x4d\x13\x19\x78\x3b\x9a\xad\x85\x98\xa2\xd4\x79\xfb\x29\xeb\x46\x65\xb2\x0b\xe2\xc9\x34\x4d\x14\x0b\x9d\x7e\xfd\x33\x2c\xf3\xb2\x9e\x68\x9e\xd2\x54\x84\x26\xe8\x33\xc6\xed\xc9\x2b\x78\xd1\x54\x90\x18\xcd\x4b\x64\xbb\x84\xd9\xb0\xee\x2d\xcb\xf3\xa9\x99\x36\x4d\x05\x07\x94\x9d\xda\x1f\x7d\xea\x30\xa6\x74\x8c\xef\x8a\x10\x96\x54\x07\xed\xe3\x80\xd3\xc1\x33\x40\xa2\xfd\xf4\xb4\x32\x4d\x2d\x71\xf6\x6d\x79\x6a\x2c\x45\xd0\x1f\x82\x88\xc8\x3e\x61\x9e\xf2\x82\x68\x2a\x59\xc2\x2d\x7f\xa0\xcb\x9a\xbd\xe4\xae\x4f\x39\x53\xc9\x69\x62\x29\xe3\x6f\xe5\x2b\x7c\xab\xc4\xa5\x3c\x33\x55\x21\x00\xe9\xac\x8c\x26\x5a\x7f\x34\x55\x44\x0f\x6c\x64\xda\x95\x02\x17\xb6\x21\x65\x7f\x58\x62\x4f\x55\x12\x07\xca\x57\xa4\x5e\x44\x56\xdc\x80\x7e\xbe\x20\x4f\x43\x53\x25\xb8\x0d\x75\xc4\x73\xf7\x68\x94\x56\xc2\x96\x89\x6e\x4a\xa1\xff\xf8\x05\xc1\x94\xa6\x3a\xe4\xc8\x10\xbe\x72\xc4\xf3\x79\x89\x34\xbf\x7a\xa7\x9a\x68\x74\x5d\x45\xef\xc5\xf6\x05\x2c\x4f\x3e\x72\x4c\x75\x22\xa9\x2d\x11\x3b\x0e\xe1\xed\x29\x6f\xb2\x3a\x7b\xee\x06\x28\x82\x94\x88\x43\xd6\xd7\xad\x53\x90\xf6\x8f\xff\xae\xcb\x62\x29\x26\xba\xfa\x6e\x8c\x89\x43\xac\x1a\xe6\xa2\x6e\xee\x2b\xa1\x5c\x2b\xc5\x9f\xc2\xa4\xd6\x3e\xc5\xa9\x82\x5e\xa0\x69\xd3\xd4\x28\x83\x50\x39\x9b\x01\xb9\xf7\xea\x41\x7c\x5e\x97\x95\x97\x98\x9a\xbf\xd1\x48\xfc\xf2\xe2\xeb\x98\xbb\xf9\xa9\x22\x82\x90\xa2\xab\x44\x7b\x69\xbd\xfb\xe3\x20\x2c\x11\x01\x8d\x50\xa8\xdf\xb2\x7a\x7a\x44\x8e\x7f\x64\x22\x92\xb1\x27\x0f\xd9\x75\x6a\xa8\xb9\x33\xbe\x12\x41\x48\x18\x41\xcf\x68\x81\xdf\xe6\xab\x08\x7e\xb4\x4c\xbc\xe7\xe2\x1d\xbc\x5f\x3b\xdb\x72\x57\x0e\x75\xd9\xb9\x1b\x4a\x05\x73\xf4\xde\x06\x3b\x99\x16\x55\xdd\x5d\x23\x95\x61\x20\x07\xee\x35\x4e\x86\xb6\xd0\x3f\x6f\xbe\x5e\x82\x05\x0b\x08\x58\x64\x7a\x63\xb6\x78\xb1\x6e\x1b\x1c\x3e\x61\xc1\xc0\xda\x04\xee\xbd\x6c\x65\x55\x97\xc5\xf4\xc7\x8d\x4f\xcc\x83\x98\x3a\xc4\x3a\x9a\x4a\x0f\x2d\x02\xa8\xe0\x24\xf0\x9b\xc6\xc1\x02\x06\xab\xf1\x37\x72\x9d\x58\xa5\x26\x31\x11\xad\xa3\x82\x03\x43\x3d\xfa\x93\xe3\x0e\xd7\xaf\x96\xf2\x38\x33\x35\x45\x0c\x3a\xb4\xf4\x8f\xd7\x6c\xa1\x6d\xa9\xf0\x82\x08\x35\x15\x49\x48\x85\x57\x79\xff\x5c\xf7\xd7\x7c\x61\xb4\x22\xb8\xca\xbd\x83\xdc\x66\x5d\x44\x2a\x12\x90\xcc\x2d\xcb\xa2\x7a\xde\x87\xfb\x0c\x6d\x05\xfc\x51\x93\x70\xee\x59\x6d\x6d\x54\xa7\x47\xbd\x77\x91\x06\x1a\x7b\x74\x6d\x04\x3d\xdb\x28\x10\x69\x1a\x26\xb6\x8e\xf0\x73\x79\xbf\xf1\x01\x63\xfb\x67\x5c\xca\xed\x4a\x37\x51\x31\x1c\x6c\x4a\x22\x15\xa1\xd7\x0b\x72\xa1\x9a\x11\xa7\xbc\x79\x10\x55\x93\x0d\x7b\x51\x22\x95\xd2\x37\xdd\x1d\x5e\xce\x36\xb8\xaf\x2a\xa1\x5e\x3b\x3c\x80\x10\x01\xc4\x66\xe0\x0b\x65\x2b\x3b\xd5\x30\x85\x14\x22\x4d\x3c\x5f\x66\x53\x98\xf2\xba\xac\x56\x59\x7d\x3c\x35\xb0\x28\xb4\x93\xdd\xbc\x28\x5a\x32\x79\x67\x24\x89\x10\x44\x8e\x8b\x14\x32\x91\xff\x04\xd1\xbf\x08\x32\xb1\x5a\x9c\x8f\x4f\xab\xc5\xcf\xfb\xc7\x9b\x55\x77\x40\x87\x88\x30\x75\x3e\x65\xe2\x03\x09\x92\x63\x1f\x44\x2a\x14\x37\x18\x19\x2e\x7e\x2c\x36\x37\x8b\xab\x9b\xf5\xfe\xfa\xfe\xe9\x6e\xb5\x7e\xdc\x6f\x9f\x1e\x1e\x6e\x3c\x73\x40\x28\x15\x87\xbc\xef\x98\xae\xca\x0e\x5b\x2e\x74\x08\xf6\xf9\x67\x6f\x30\x14\xbd\xbf\xb8\xc6\x0b\x4d\x22\xaa\xba\x5a\xb6\xd5\xe7\x9a\x5c\x97\xe6\x2e\x6b\xce\x0e\xf0\x20\xea\xfa\xea\xf3\xb7\x39\xe4\xab\x00\x9e\xa2\xd0\xc3\x5b\x06\xef\x9c\xfb\x4b\x02\xb0\x1c\x31\x0b\xea\x9b\xeb\x4c\x08\x43\x62\x0c\x55\x10\xc5\x3e\x13\xb8\xd9\x61\x32\x00\xeb\x4e\x9d\xa9\x72\xb8\xc4\xcb\x30\x8a\x10\xd4\x27\x74\x57\x8d\x77\x2e\x77\x97\x02\xb1\x7e\x46\xca\x28\x60\x58\xcb\xb7\x6b\xcb\xfa\x71\x19\x05\xb3\x0c\x8b\xf3\x32\x8b\x44\x89\x53\xd7\x92\x74\x05\x07\x7f\x49\x44\x06\xa1\x05\x7d\xa1\xaf\xe4\xa8\xcf\x22\x29\x80\xb7\xeb\xc0\x3c\x75\xd3\xfe\x1e\xd8\x2c\xef\xa3\x42\xcf\x74\x93\x24\x63\x11\xb1\x9d\x36\x5b\xb6\x5c\x18\x93\xe5\xd9\x10\xcc\x3a\xba\x2c\x4e\x18\x2e\x0d\x78\x70\x7c\xa7\x65\x4c\xec\xaf\x5d\xc1\x9b\x05\x81\x3a\xb6\xcf\x5f\x51\x48\xa4\x32\xe6\xb6\xe0\x5b\x9f\x0e\x87\xb2\xf8\x0e\xd5\x78\x2d\x4b\xfe\x36\x1e\x2d\x14\xc2\xfb\xd6\x77\xab\xfd\xed\xe6\x6e\xb7\xb9\xfb\xe6\xef\x40\x92\x58\x61\x5d\xe4\x9e\x2f\xcb\xea\x2b\x2f\x18\x2a\x13\xc9\x51\x95\xef\xcf\x53\x95\xf9\x33\xa4\x49\x8c\x70\xb6\xb2\xc8\xad\x64\xdd\x37\x68\x76\x20\x0e\x23\xb8\x90\x14\x06\x90\x09\xd4\xbe\x75\x7b\x7b\x93\x7e\xf3\x17\x9a\x0c\x1c\x9b\xa9\x94\xa1\xc0\x8e\x9d\xb1\xa5\xdc\x76\x16\xde\x74\xb6\x0d\x54\x4a\x62\x2d\xae\x9c\x19\x5a\xf3\xb2\x59\xde\xff\x10\x55\x86\xfe\x0e\xf3\x41\xb4\x94\xd4\xca\x73\xfc\x52\xe1\x6b\x30\x1b\xa5\x90\xc8\xe7\x78\x44\x39\xc8\x5d\xfd\x92\x55\xcd\xec\xcb\x26\x15\x0b\x71\xad\xb9\xd8\xa3\xf7\xe3\xd2\x04\xf3\xb8\x1c\x9d\x91\x1f\xce\xfa\xf2\x52\x07\x89\xd7\x0b\xba\x11\xd5\xb3\xe3\xf3\x8c\x70\x73\x7e\xa4\xd2\x81\xf0\x99\x6b\x1b\x7a\x62\x33\xe8\xcb\x28\x43\x6a\x10\x89\xe3\xec\xb5\x13\xfc\x61\xb0\x95\x4a\x6d\x22\xaf\x91\xf6\x08\x06\x2c\x2c\x65\xfc\x71\x60\x06\xc1\x42\x87\xac\x68\x37\x09\x05\xf9\x97\x33\x05\x64\x84\xf3\xea\x7f\xff\x77\xf9\x15\x8e\x50\x82\x0e\x31\xce\xb7\x61\x97\x73\xf8\x9a\x3f\xa5\x49\xe3\x8e\x93\xda\xde\x13\x18\x18\x0a\xdb\x21\x2a\x60\x0a\xdb\xce\x56\x27\xc7\xbb\xba\x7f\x17\xf5\xcb\x60\x6e\x5c\xb0\x28\xfb\xe7\xbf\x06\x52\x8d\x54\x05\x2a\x55\xbc\x5b\x2c\xbd\xe9\xe6\x57\x4a\x41\x54\x05\xda\x0a\x8f\x3b\x5f\x17\xf1\x0c\x2b\x39\xbe\x8d\x2a\x4c\x65\x4a\x3c\xee\x2e\xcf\xbf\x55\x42\x39\x2e\xc0\xb8\x8e\xae\x42\x49\x2d\xbd\xe5\x45\xfc\x36\xbc\xae\x10\x0c\x8a\x04\xf4\x02\xaf\x4e\x89\xca\xf7\x7e\xdd\x33\x55\x91\x33\x67\x6f\x37\x20\x0f\x75\xc5\x7b\xe0\xac\x8f\xa8\x8a\x24\xef\xe2\xce\x4c\xbd\x16\x62\xda\x2f\x52\x24\xb4\xb1\x0d\x36\xcb\xac\xa8\x75\xfd\x5d\xbc\xc1\x37\x5c\xa2\xab\x87\x2a\xb3\x76\x11\xb3\x13\x5e\x91\x88\x60\xf7\xbc\xcd\xcf\x31\xc8\x59\x55\xe5\x71\x8b\xd4\xf7\x71\x57\x70\x5a\x4c\x53\x24\xd5\x88\x1b\xdd\xbd\x54\x00\xab\x1b\x17\xa0\x58\x3a\xa3\x1b\x42\xa3\x10\x1d\xbf\xae\xee\xff\xf0\x5d\x6d\xc5\x94\xf5\x33\x14\x5a\xaf\xad\x8d\xde\xf6\xd8\xe6\xa8\xfe\x38\x8f\x79\x27\x1a\x72\x70\x64\xef\xde\xf3\xc2\x0f\x12\xe9\x28\x30\xf2\x1a\xdb\xde\x29\x70\x76\x72\xaa\x38\x0a\x45\xcf\x23\xcf\xcb\x0a\xac\xae\xde\xfc\x8a\xa4\x62\x92\xe0\x06\x3d\x80\x48\xab\x98\xc5\x58\xc6\xb9\xbb\x5a\xec\xc2\x20\xfa\xab\xf8\x3b\xff\x69\x99\xf8\x86\xd9\x23\x08\xed\xe8\x37\x93\xa8\x51\xc5\x5a\x21\x9d\xdc\x69\x8a\x20\xb5\xe4\x77\xe8\x7e\x7b\x02\xa1\xdf\x2c\x11\x95\xb0\x82\xba\xc9\xc6\xd8\x24\x95\x80\x88\x9c\xe0\xed\xe9\x98\x5d\x65\x95\x9e\xa9\xf0\xfd\x15\xa2\xf6\xf8\x8e\x08\x91\xa6\x69\xaf\x38\x70\x38\x1d\x1c\xe9\x76\xae\x62\xaf\x84\xe2\x58\x83\xc8\x9c\x02\x67\x7d\xee\xb5\x4f\x95\xd0\x5c\x5a\x54\x60\x53\x41\x36\xb6\xc2\x6b\x8f\x26\x58\xb8\x57\x65\x56\xb4\xab\xf6\x58\x70\x8a\x2a\x29\xad\x36\xf3\xba\x40\xc9\x7f\xcb\x07\x9d\x7c\x83\x0a\x13\xac\x8d\xd9\xcd\x68\x95\x89\x43\x59\x5c\xb8\x1d\xfe\x13\x54\x22\xd9\xbf\xb2\xe9\xd3\x4f\xc8\x36\xc5\x99\xa9\x11\x55\x5a\x86\xcc\xf4\x7a\x3f\xbb\xb2\x9d\x85\x75\x23\x0e\xc7\x4b\x13\x50\x9b\x18\x11\xe7\xb2\x9d\xab\xe3\x15\xcf\x8d\x00\x65\x05\x2e\x0e\xe2\x63\x29\x8e\xce\xdc\x7b\x53\xbc\x41\x31\x00\x99\xeb\x80\x49\xec\xdf\x19\x04\xdb\xad\x20\xcf\xde\x2e\xd3\x76\xe7\x23\x59\x1d\xa4\xc6\xd8\xd8\xe6\x50\x56\xa2\xb7\x50\xa5\x3a\x50\x12\x3b\x09\xcb\xbb\x51\xf3\x51\x47\x34\xb1\x4c\xec\x2a\x93\x30\xc7\x91\xd7\x11\x95\x68\xe7\x54\x94\x73\xf1\x60\xff\xdd\x91\xb2\xa2\x74\xb8\x4f\x55\xe5\x07\x66\x9d\xe5\xa9\x59\x8a\xe3\xfc\x9d\xd3\x24\xd4\x58\x1c\xca\xfb\xba\x6f\xe2\x0f\x11\xab\x64\xfb\xfa\xa9\xda\xad\xa9\x9e\x6c\x8a\x9a\x06\x04\x51\x72\x05\x7c\xf8\xd2\xde\x78\x19\xd7\x34\x8e\xb9\xec\x48\x5d\x76\x1b\xf1\xea\x1d\xd3\x93\x29\xed\x21\x77\xde\x90\xaa\x8d\xa3\x2e\x5c\x35\x63\x0a\xe5\x83\xb6\x50\x1d\xa1\xb0\xd5\x80\x55\xf9\xde\xdd\x51\xc6\x25\x86\x08\x2e\x67\x9b\x74\xa9\x35\x8b\x19\xda\x8c\xbb\x9a\xb1\xaf\xe9\x9e\x83\xae\x35\x33\x04\x91\xfe\xd5\x79\x3c\xac\x99\x51\xb8\xc7\xf4\x82\xb8\x88\xf3\xea\xf9\x91\xed\xcd\x6f\xa7\xae\x1e\x02\x72\x2e\xcc\x1a\x1e\xa4\x58\x13\x13\x27\x9d\x35\x65\xf5\x5d\xd4\xdb\x46\xbc\x5e\x50\x0e\xa4\x9a\x53\x60\x6e\xf7\x6a\xf3\xae\x45\x56\xe9\xaa\x3c\xce\x98\xc9\x50\x1d\x87\x11\xb1\x32\x6a\x85\x1a\x17\x20\x74\x1c\x45\xca\x15\xbb\x9a\xde\x18\xc6\x1d\x4c\x88\xb5\x3e\xb4\x22\x3a\x1d\x78\x51\x27\x2c\x0a\xdb\xbf\xff\xe7\x24\xaa\x06\xaa\xbc\xb3\x8b\x1b\xec\xbf\x3a\x51\x11\xd5\xde\xf1\xf8\x57\x6b\xe1\x5f\xec\xff\xcd\xd3\x06\xfa\xa8\x55\xa7\x11\x4d\x83\xae\x92\x79\x7d\x52\xaf\x9f\xe5\xc9\x5f\x51\xca\x24\xc2\x5f\xb6\x2f\x59\xb3\xcc\xcb\x02\xea\xbc\xac\xf4\xe4\x37\xa7\xc2\x96\x4a\x45\x5d\x43\xd5\xac\xff\x13\xdb\x09\x1d\xdb\xe0\x28\x76\xa3\x24\x50\xaa\x7d\xa8\x5a\x0f\x5b\xa6\x4f\x7d\xd5\x4d\xab\x28\x44\x06\x41\xe6\x17\x99\x87\xaa\xd4\x27\x35\xa1\x5e\x69\x45\x14\x89\x06\xdc\xd8\x4e\xca\x89\x6a\x95\x70\xcc\x89\xff\xfc\x73\xbc\x5e\x28\x63\xa5\x35\x0f\xed\x56\x21\xf2\x9e\x4f\xa4\x0d\xb5\xbd\x97\x17\x51\x5f\x01\x14\x37\x59\xf1\xda\x15\x57\x46\x59\x91\x36\xce\x70\xfe\x61\xfd\xb8\x7f\xda\xae\x1f\xf7\xb7\x8b\x3f\xf6\x8b\x1f\x8b\xdd\xe2\x71\xbf\xbc\x7f\xba\xdb\x75\xa7\x4c\xa5\x67\xda\x2e\xa7\xa8\x08\x08\xd3\xd4\xe3\x83\xb7\xef\xe2\xcc\x5c\x84\x42\x28\x34\xca\x3f\xaf\x0f\x65\xd1\x5c\x57\x50\xfc\xf7\x73\x37\x35\x79\xa6\x10\x45\x29\x8e\xc2\x17\xd0\xff\xcd\x61\x85\x73\x51\x37\xaa\x3c\xc8\xb2\x3b\x40\x39\x0d\xbc\x11\xc8\xfc\xfa\x00\xed\x8a\x6a\x4b\xde\xe8\x8d\x38\xf9\x36\xc6\x50\x33\xf3\xe7\x0e\xd4\xcb\x0e\x01\xa9\x5d\x6d\x1e\x68\xc8\xb0\x84\xf4\x5c\x95\xef\x3f\x61\xda\x6f\x00\x1a\x4a\xd4\x68\x78\x5c\xec\xd6\xfb\xd5\xe2\xcf\x7d\xd8\x7d\x50\x05\xdc\x6d\x30\x36\xcd\xb6\x7c\x8e\xfe\x9d\x00\x26\x98\x71\x41\x8a\x2d\x3f\x6c\x1c\x9a\x1f\x93\xed\x29\xaa\x07\x98\xe0\xae\x81\xd0\x65\xf5\xa7\x21\xf7\x02\x18\xa4\xe8\x27\x2c\xea\x36\xc6\xf4\xb3\xeb\x2f\x6d\x52\x10\x07\x56\xca\xa1\x39\x49\x7f\x79\x31\x09\xa3\x68\x68\xd4\x3f\x78\x9a\xd3\x4f\x13\xc3\x1d\xf2\xd2\x75\x15\x51\x8b\x68\xce\xef\x82\x42\x2c\x18\x5e\x66\x51\x16\x3f\x6f\x2e\xd0\x64\x20\x09\x94\xaf\xb3\x21\x4c\x77\x72\x34\xb5\xae\x68\xb2\x2c\x9b\xa7\xe3\x77\x51\x3c\x97\xa7\x8e\xa6\x02\x89\xe2\xd8\xad\xad\x1c\xa0\xfc\xab\xd4\x0c\x12\xb0\xa0\xcb\xeb\xac\xd0\xbb\x17\x58\x9e\x2a\x18\x3e\xfe\xc4\x44\x34\x1e\xd4\x44\xda\xe5\xdb\x4a\xec\x3d\x4f\xeb\x64\x90\x26\xd6\xfb\x15\x3b\x4c\x0b\x7c\x08\x43\xf4\xc9\x99\x65\x11\x85\x54\x87\xe8\xa2\xbb\xae\x1b\x6f\x3c\x3b\x39\xa7\x60\x06\x5c\x9e\x7a\x77\x3a\x58\x89\xeb\xd5\x80\xde\x33\xff\x3c\x84\xb0\x40\x99\x76\x97\xc5\xd8\xff\xc2\x8f\x17\x2a\xe6\x43\xaf\x02\x91\x5b\xed\x8b\x6e\xd1\x02\x61\x42\x46\x07\xa1\xe5\xdc\x8e\x02\xc2\x48\xec\xbc\x63\x5f\x72\xc8\x29\x02\x19\x78\x09\xff\x36\xb6\x1e\xb0\xb8\xbb\x01\x24\x0a\x02\x9f\x6b\x5b\x66\xcf\x43\x55\x3e\xb7\x27\xbf\x37\x0f\x0e\xfd\xb5\x3a\x15\xcf\xe0\x50\x88\x7e\x9d\x04\x29\x39\xaa\xee\x1c\xc4\x87\x2b\x60\x5f\x9d\x7c\xdc\x06\x8a\x85\xd4\xb5\x69\xdd\x2e\x8c\x7e\xf2\xdd\xe1\x94\xe3\x5b\xdb\x2e\xf7\x67\xee\x2c\xdd\xbf\x53\x47\x71\x0a\x9a\xb1\xd8\x0c\xa4\x18\x3a\xd7\xe8\x11\x1c\xb8\xbb\x44\x10\x56\xab\x1b\x50\xa2\x16\x1e\xcb\xf2\x30\x79\xbc\x86\xa4\xa6\x53\x9f\xdc\xbf\x8f\x6c\x26\x29\x98\xc4\xf6\x03\xde\xd5\x7d\x31\x80\xcb\x2a\xd5\xef\x50\x60\x94\x4c\xa0\x5b\x44\x0a\x98\xe4\x06\x26\x08\x20\x21\x13\xf5\x26\x9c\xc9\xbf\xf9\x01\xc4\x0a\xf2\x3f\x2c\x6f\xa7\x1f\x05\x92\x3a\x56\xd2\xf2\x74\x2e\xae\x4e\x4d\x18\x28\x44\x6e\xab\x97\x57\x25\xce\xbb\x70\xe3\xb3\x85\x26\xc5\x5a\x73\x2e\x87\x7b\x97\x89\x02\xe3\x44\x74\x9a\x21\xab\xb7\x4d\x44\x27\xdf\x16\x51\xa6\xdc\x5e\x66\xbd\x25\x9f\x8a\xac\x2c\x36\xba\x9e\x07\x93\x98\x88\xd9\x97\xab\x38\x1d\xee\x8d\xeb\xc0\xeb\xee\x6b\xb5\xe5\x83\x79\x50\xf7\x53\x51\x97\xb9\x3e\x93\xb2\x30\x84\x87\xb8\x37\x20\xe8\xda\x7e\xed\x4f\x00\x5f\x7f\x33\x2c\x48\x42\xdc\x35\xab\xde\xa1\x68\x7c\xd5\x9c\x6a\x94\x35\x97\xa5\xbc\x15\xaf\x50\xaf\x2b\x15\x05\xde\xf9\xe3\x82\x95\x9e\xc7\xf3\xfe\x6d\x72\xaa\xc4\x1a\x14\x7c\x73\xa0\x9a\x7b\xf3\x98\x3d\xff\x82\xe5\x6f\xb8\x04\x64\x9c\x09\x0f\x97\x75\x96\xc2\xb5\x5b\x79\xfd\x44\x32\x5c\x07\x88\x71\x5d\x96\xc5\xf3\x79\x87\xc5\xc4\x0e\x82\xda\x2f\x15\x37\xbe\x2a\xee\x46\x24\x4a\xe1\x86\xb7\xaa\x50\xac\x6a\xf4\x94\x53\x4a\x99\x63\xe2\xd4\xa7\x03\xac\x0b\xa8\x9e\xe7\x25\x64\xa9\x49\x79\x8a\xe5\x6b\x6b\xe5\xe5\x2e\x73\xb8\xaa\x18\x11\xf0\x80\xfb\x10\xa4\x68\xaa\x32\x6f\x77\x4e\xfc\xc2\xbc\x53\x67\xa5\x46\x84\xb1\x97\x37\x6e\x53\x87\x2b\x18\xab\xe3\x19\x41\xe2\x29\xbb\xc4\x7f\x54\x06\x24\x72\x6f\x15\xc2\xd7\x67\x8a\x75\xed\x9a\x07\xbd\xe5\x20\xe2\x16\x01\xbc\x18\x71\x1f\x85\x1a\x15\xd9\xda\x76\x53\x3e\x3f\xe7\x60\x69\x5b\xfe\x7b\x14\xb7\xb6\xbc\x7b\x29\xf4\xb3\xb5\x30\x1f\xa7\xd6\x93\x29\xa0\x14\x01\xd7\xf1\xbc\x82\x66\xc8\x66\x9a\x0e\x34\x94\xb8\x7d\xeb\x4c\x6b\x9f\x1a\x08\x02\x19\xfa\x6c\x41\x9d\xda\xb9\x78\x2b\xfe\x5d\x56\x59\x93\xf5\x13\x02\xdc\xda\x7d\x14\x9f\x5f\x81\xf3\x2e\x75\xa8\x06\x77\x00\x18\x75\xad\xf0\xea\x19\xea\xc6\x13\xbc\xba\x2f\x52\x94\x0f\x8d\x44\xbc\x3c\xa7\x3f\x0c\x04\x91\xe0\x2e\xb2\x70\xeb\x9f\x39\xe5\x17\xf3\x88\xf1\x8f\x35\x24\xc6\x37\xc0\x6a\xe9\xdf\x94\xc5\xf3\x12\xe5\xe7\x27\x55\x37\xf2\xaf\x29\x28\xcc\x7f\x1e\x44\xd4\xa9\x71\xef\xb3\xba\x1c\xca\x88\xb3\x20\x08\x05\xe6\x8e\x98\x32\x15\x22\xc7\x22\xd6\xdc\x95\xb0\x20\x88\x13\x2c\xc1\xb4\xbb\x7d\xa6\xb0\x36\xd1\x9d\x45\x58\x8a\xfc\xd0\x69\x12\xf1\x08\xf6\x3f\xe6\xe7\x03\x0b\x42\xd7\x53\x41\xc9\x49\xf1\x0c\x6d\x5e\x3f\xfe\xce\x28\x50\x32\xf5\x95\x30\x57\xcc\xde\x7d\x1e\xc7\xdc\x1e\x16\x44\xa1\xa5\x8e\x38\x05\x01\xdc\x21\x26\xc1\x2e\x0b\xa2\xd8\x56\x81\xfd\xb7\xf5\x86\x1e\x2c\x88\x24\x60\x2f\x7e\x27\x3e\x76\x59\x9e\xdf\x0d\xc4\x14\xc7\x27\x21\x29\x8b\x6c\x48\x70\x25\xaa\xe5\xc0\xa9\xdc\x1d\xa7\x3c\xc0\xa8\x58\x8a\x3a\x53\xce\x6c\x7b\x00\x16\x6e\x07\xc4\x51\xd4\xbf\x9b\x50\xd7\x93\x96\xb4\x1f\x97\x70\x7c\xbd\x17\xcf\x59\xb7\xf3\xdd\x0e\x13\xef\xbf\x58\xc6\x99\x5c\x3f\x4b\x44\x34\xa8\x15\x78\xdf\x91\x41\xff\xfc\xec\x0d\x60\x01\x83\x04\xd1\xe2\xa7\x1a\xaa\xf5\x07\x72\xaa\xe7\x0a\x97\x2c\xe0\x01\xc5\x80\xa0\x6a\xf7\x8a\xfb\xf7\xa9\x55\x3e\x0b\xb8\x24\x38\x1b\xaf\x45\x96\xc3\x79\x83\x6c\x7c\xad\x49\x94\x12\xb7\xf9\x23\xe0\x68\x46\xee\x82\x05\x09\x65\xc6\x05\x52\xf6\xa9\xf6\xbb\xe0\x43\xef\xea\xe3\xef\x7e\xc2\x24\x42\x78\xdf\x01\x5e\xb1\x20\x3d\x08\x26\x58\x90\xa4\xdc\xc4\x1d\x2a\x1f\x6b\xe2\x0a\x6e\x45\x71\x12\x79\xfe\x39\x99\x4d\x09\x68\xcc\xac\x16\xc5\x6b\x36\xdc\x2d\x58\x90\x18\xbb\xd7\xdc\x96\x85\x1e\x78\x49\x9d\x2f\xc2\x2c\x10\x9c\x7a\x78\x8e\x7d\x9f\xbb\xe4\x97\x05\x92\x2a\xee\xa2\xb5\x9f\x37\xb7\xbb\xab\xf2\x54\x4c\x38\x1b\x38\x06\xf9\xf6\x57\xa2\xf6\x45\x93\x0b\x4f\x46\xca\x10\x1f\xa1\x73\x2b\x77\x25\xa2\x6f\x59\x95\xff\x36\xba\x22\x15\x08\x2c\x5c\x23\x40\xb1\xcd\xe6\x2a\xf1\xbe\x6d\xa6\x0c\x2c\x16\x28\xc2\x60\xa8\x78\xbd\x2c\xf3\x36\xc9\xaa\x2e\x20\x23\x59\xa0\x4c\x6a\x25\x24\xf1\x02\xda\x9b\x6a\x84\x6a\x4e\xd5\xaf\x78\xc7\xee\xe3\x3a\xa4\xa1\xdb\xd2\x7e\x0a\x2f\x01\xe5\x9c\x82\xc7\xd5\x5e\x16\xe8\x54\xa2\x2d\xf2\x3b\xce\x97\x59\x55\x74\x16\x68\xa9\x94\xf3\xdd\xde\x6f\x8f\x65\x51\x97\x55\xbd\x6f\xf7\xdf\xbd\xfc\xdc\xff\xbd\x94\xd3\xe1\x9a\x62\x24\x75\x07\x4d\x03\xaf\xbd\x31\x00\x0b\x00\x38\xca\xf4\x0a\xad\x7f\x40\x95\x99\x0c\x34\x72\xdf\x2e\xfc\xaa\x61\xc7\x7b\xfc\x13\x0d\x8d\xd0\x94\xb9\x3e\x82\xca\x4c\xa6\x7e\xf1\x76\x98\x14\x10\x26\x5d\xbf\x7f\x1e\xfd\xb6\xc7\x02\x23\xc1\x92\x86\x45\xae\xee\xe0\xa3\x59\x55\xe2\xbd\x0f\x73\x58\x18\x04\x42\xb9\xc7\xa0\xb3\x66\xdf\x0c\x63\xbe\x49\xeb\x86\x85\x41\xa8\x31\x3a\x77\x56\x3b\xf5\x75\x59\xdd\x9f\x1a\x55\x76\xac\xe9\xd1\x9c\x08\x03\x06\x08\x04\x74\x09\x03\xba\x93\xad\x44\xf9\x30\x2a\x57\xb2\x30\x48\x15\xae\xc3\x0f\x8f\xeb\x3d\xaa\x2a\xef\xee\x77\x8b\x9b\xfd\xee\xfe\xf7\xf5\xdd\xb6\x1b\x24\x39\xb7\xa0\x3a\x7d\x52\x80\xa0\x90\x31\xf5\xc4\x8d\x0b\x9d\xd5\x1e\x4a\x03\x6e\x0b\xf1\xda\xfd\xd2\x50\x89\x14\x97\x9a\x36\x64\x19\xac\x44\xf3\x0b\x63\x18\x85\x36\x80\xbc\x3a\x7e\x0c\xdf\xe6\x30\xe2\x04\x91\xe4\xdf\x44\x61\xf5\x95\x50\x8d\x78\x1e\x1f\xc8\x42\x12\xf0\xd8\x4d\x06\x44\xde\xb4\x99\x1b\xdc\x66\xc5\xe4\xc5\x0d\x49\x48\x11\xc9\x5c\x6e\x56\x88\x1f\xdd\xfb\xaf\x23\x9c\xe1\x6b\xb2\x3d\x0e\x50\xd0\xb3\x17\x4c\x52\x0b\x86\x38\x62\xf0\x5e\x0f\xd6\xb1\x90\x28\x2b\x1f\xd8\xbe\x2c\x00\xaf\xf9\xe7\xd5\xe9\xf3\x47\x99\x9f\xfa\x69\x40\x34\xc1\xdc\x07\xad\x8f\xb6\x1d\xe1\x72\xfc\x92\x87\x2c\x48\xb1\x05\xbb\x5b\x2f\x6e\xf7\x8b\xd5\xea\x71\xbd\xed\x1e\x10\x63\x61\xaa\x3c\xfe\x07\x73\xd4\xb7\xfe\x11\x73\x6d\x22\x6b\x82\xd2\x3e\x32\x24\xbd\x8e\x2f\x3e\x16\x31\xf5\xed\xca\x52\xc3\xd0\x63\xd7\x8d\x48\xc2\x18\xb3\xf2\xed\xb8\x74\x31\x39\x4f\x1a\x27\x7e\x91\xec\x9a\xa6\xd7\xb9\xe8\xee\x44\x1a\x6b\x2e\x1d\x0e\x67\x84\xf1\x3b\x2b\xbe\x0e\xbe\x3a\x4d\x6d\xf8\xdc\xc9\x96\xe9\xbd\xa5\x63\x6f\x1b\x51\xbf\xa0\x42\x59\x79\x6a\xa6\x57\x22\x22\xdc\xf8\xcd\xa9\xd0\x53\x5e\x93\x1b\x22\x52\xaf\xff\x8c\xec\x92\xdf\xb3\x89\xff\x0d\x0b\x85\x56\xc8\x47\xdb\x96\xaa\x4d\xfa\xbd\xbc\x22\x0b\x25\x4f\x70\xb7\xd9\xfe\x5c\x3c\xec\x6f\xd6\x77\xdf\xba\x7d\x22\x94\xc0\x51\x0e\xd5\x29\x3f\xfa\xc2\xd9\xf8\xc4\xd2\x58\xe8\xb1\x0f\xd0\xbc\x89\x95\x3b\xac\x22\x2b\x0f\xa3\x1c\x75\x1a\x45\xa5\xbb\x83\x69\x88\xdb\x70\xbb\xfb\xbf\xc2\x67\xbd\x3f\x13\x50\xe1\x74\xfc\x8f\xfb\xa0\x16\xda\x50\x37\x0b\xca\xaa\xd9\x4b\x51\xec\x4b\x33\xb9\x32\xa0\x5c\x3b\xd4\xe0\xd5\xcd\xbc\x56\x38\x0b\x0d\x8d\xd0\xb4\xf9\x50\x3f\xcf\x57\xc2\x58\x68\xd2\x44\x5b\x1e\x76\xe1\x2c\x57\x59\x14\xa4\x71\x68\xad\x70\xab\x2a\x6b\xca\x87\xb2\xcc\x07\xe6\x86\xed\xf1\x04\xa7\xe9\xc1\x81\x0b\xc6\x62\x7f\x2c\x0a\x89\x40\x83\x34\xe7\x8d\x0a\xc8\xaf\xee\x21\xa7\xdd\x30\x2e\xb1\xbd\x6f\x71\x7a\xb6\x9c\xe3\xd7\xee\x3e\x8a\x8a\x42\x6d\x13\xb6\x63\xf5\xa6\xfd\x47\x23\xb0\x8a\x5f\xb6\x74\x70\x53\x3e\x67\x6a\xca\x77\x1d\xdd\x89\x88\xa5\x06\xe3\xf5\xdd\x4b\xe5\xbb\xa0\xfe\x5c\x4c\x5b\x87\x86\xa5\x28\xde\x44\x7d\x5d\x89\x67\x7f\x84\xa7\x9c\x23\x87\x01\x1b\xe5\x50\x5d\x89\xe2\xd5\xc3\x81\x59\x14\x2b\x01\x68\x4f\xaf\xa1\x7d\xf6\x4f\x53\x83\x0e\x16\x25\xc4\x2a\xe7\xc8\xf2\x94\xc3\x0a\xde\xc6\x28\x63\x16\x25\x22\x40\xc9\x96\x6f\x79\x29\x45\xee\x7f\x7b\x6d\x75\xdb\x87\xb7\x20\x51\x01\x06\xbf\x5a\x7c\xd6\x7b\x4c\x39\xfa\x45\x23\x4a\x8c\xb5\xe8\x41\x7b\xa8\x76\xbf\x79\x80\xea\x4f\x10\xdd\x75\x0a\x9a\x20\xcd\xee\x45\xbc\x81\x5e\x65\xb5\x75\x5c\xe9\xcb\x9d\x2c\x12\x29\x43\x2c\xb7\x6d\xe1\x2e\x8b\xcf\xab\x46\x9d\xe5\x8f\x2c\x92\x52\x63\xda\xea\xb5\xee\x3a\x2d\xbe\xc9\xbd\x56\x29\x91\x2e\x5d\xbd\xee\x6a\x56\x2c\xd2\x51\x8c\x7d\x99\xa7\xa7\xcd\x8a\x76\x7f\x64\x4a\xbb\x4a\x20\x76\x98\xe6\x79\x92\x6e\x30\x04\x09\xa6\x2b\x7b\xef\x94\xe5\x41\x15\x8b\x42\xdf\x42\xf3\x52\x4e\xcc\x1d\xfc\xc7\x42\x7b\xdd\xed\xb2\x5e\x56\xaf\x26\x2f\xdf\x17\xaa\xc9\xde\x86\xa8\x8d\xf1\x17\x19\x4a\x70\x01\x7f\x2c\x8b\xe7\x9f\xff\xf8\x6b\x08\x3c\x16\x19\x4e\x8d\x4b\xba\x30\xa7\x9f\xf6\x41\x58\x64\x34\xc7\x08\xeb\x61\xfd\xb8\x5c\xdf\xed\x16\xdf\xd6\xfb\xfb\x6b\xb7\x83\xef\xb7\xf7\x37\xab\xfd\xe6\x0e\xf7\x76\x7f\x7b\x8c\xb1\x8a\xba\xc8\xa8\xc2\xee\xf8\xcc\x73\x31\x46\x5a\x7b\xbf\x2a\xd3\x9d\xf6\x20\x23\x41\x60\xed\x63\x8f\x55\x79\x74\xd9\xc7\x68\x7a\x92\x20\xb1\xda\x11\xb7\x8b\x3f\xf6\x57\xeb\xdd\xfe\xc7\xe2\xe6\x69\xdd\x7d\x1a\x92\xd4\xc5\x79\xe8\x3c\xbb\x9e\xe8\xbb\x31\x12\x9a\x00\x57\xa0\x9b\xf2\xf9\x27\x64\xfe\xf5\x9e\x97\x69\x60\x84\xc6\xcc\x37\x90\x6e\xc4\x41\x96\x8b\xc6\xb5\x33\xc6\x2d\x7a\x46\x18\x91\xc8\xe5\x38\x8a\xaa\x6e\x1f\xac\xc5\x20\x9e\x19\x85\x33\xc2\x58\x8a\x85\x1e\x57\x0c\xca\xa1\xda\xbb\x77\x9f\xf8\x1f\xc1\x52\x41\x8c\x4f\xe2\xbf\x3b\xfa\xf4\xa0\xd5\xc7\x08\x13\x12\xf3\x3a\xd9\xa8\xa7\x5a\x0f\xd6\x76\xc2\x94\x66\x91\xe7\x30\x67\x39\xfa\x2c\x4c\xaf\x95\x07\x94\x3b\x0c\xda\xd3\xa6\x18\x15\x9a\x18\xe1\x61\x1a\x0c\x43\xfd\x61\xca\x44\xe2\x30\xc2\x8d\x05\xad\x4a\xbc\x2f\xdf\x2a\xab\x40\x35\xf9\x99\x65\xf8\x38\x58\x22\x89\x0c\x91\x2f\xd7\x3e\x37\x37\x77\x1c\x34\xd7\x47\x19\x24\x91\x29\xee\x7b\xe8\x37\xd5\xbc\x97\xf8\xba\xac\xff\x73\x65\xcf\xeb\x47\xa5\x41\x1c\x3a\xf1\x21\x04\x9b\x40\xf7\xe3\xd3\x28\x41\x26\xc0\x0b\xe4\xc7\x47\x5f\x94\x61\x24\x25\x61\x1a\x0f\x31\x72\xd5\x64\x4e\xa4\x5c\x0d\xb2\x15\x94\x22\xfa\x8b\x79\xf6\x64\xba\xa4\x8a\x72\x8b\x5b\x39\x08\x84\x86\x5a\xb1\xe0\x81\x56\x13\x23\xa2\x9d\x54\x9e\x95\x55\xf5\x85\x81\xf9\x18\x93\x48\x91\x60\xea\xf5\xf6\xa6\xbe\x4a\x2e\x89\x04\xfb\x68\x76\x65\x59\x0d\x37\x0a\xa2\x02\x86\x05\x2d\x79\xaa\x8a\x8d\xab\xfb\x5c\x98\xed\x3a\xb5\x96\x3e\xc5\xe9\xe0\x74\x22\xfc\x49\xb4\xa4\xc4\xa1\xde\xfb\x19\x15\x46\x89\xeb\x0e\x31\x02\xdc\x65\x88\x98\x85\x5d\xd8\xb6\x09\x68\xc3\x92\x5e\x3e\x7d\x5d\xe8\xa6\xcf\x56\x88\x09\xc0\x87\x89\xcb\x53\x55\x7d\x13\x07\x68\x73\xab\x07\x51\x35\x61\x37\x26\x94\xca\x3d\xcb\x4d\xed\x93\xff\xe2\xb9\x13\x82\xed\xb7\x1f\x62\x80\x61\x1f\xf5\xea\x6e\x35\xbc\x21\x34\x08\xb4\xf7\xeb\xde\x65\x50\x45\x0f\xbd\x85\xf6\x54\x61\x98\xd1\x20\x22\xc4\x35\x67\xf6\x35\x62\x3f\xf6\x23\xb1\xdc\xf3\xfa\x09\x0d\x24\x8b\x52\xe7\x40\xb6\x29\x94\x25\xc3\xe8\xfb\x91\x3d\x22\xa3\x01\xa4\xbc\xab\xd4\xdd\xff\xbc\xf1\x57\x17\x06\x96\x43\xf3\xfb\xc3\x60\xaf\xa3\xa1\x26\x68\xbe\xfa\xed\xe1\xc9\x62\x8e\xbb\x03\x46\x33\xd2\xf5\xfc\x5e\x61\xb6\x8f\xd9\x0e\x03\x14\x70\x68\x40\x1c\x7e\x20\x34\xec\x79\xbc\xa4\xd0\x28\x0c\x11\x4e\xb1\xab\xb2\x77\x18\xcd\x20\x1a\x11\xee\x8c\xa5\x1b\x91\x1f\xca\x02\x3e\xc1\x9a\x35\xfa\xe3\x71\x28\xa9\x7f\x6d\xe3\xbd\xc0\x9a\xe7\x23\xb4\x3f\x17\xab\xa0\xfb\x27\x54\x76\x50\x08\xad\x3b\x94\x6f\xce\x4c\x66\x5f\xbf\x94\xa7\x5c\xef\x5e\x2a\x2f\xb0\xdb\x9e\x8a\x25\x0e\x3d\x35\x12\xc0\x1d\xcd\x75\x1a\x25\x14\xc1\xdf\xc7\xde\xee\x85\xd1\x48\x58\xd1\xfb\x43\x56\x34\x57\x9f\xe3\x4f\x8f\x6f\x46\xa4\x03\xc3\x6d\x7c\xf9\x8f\x87\xd3\x78\xfd\xa3\x84\xc7\x91\x95\xb7\xca\x8a\xdb\xf2\x0d\x86\x5d\xd1\xbf\x0d\x52\x34\x1f\xf7\x52\x22\x23\xd4\x0d\xb2\x9d\xec\xf9\x0b\xa6\x5c\xc5\xce\x0d\x70\x91\x55\xab\xaa\x3c\x3a\x8b\xfe\x9d\xb0\x3e\x55\x93\x2b\xa4\x22\xc1\xe0\xe8\xbd\x13\x29\x75\x07\x98\x6b\x03\xd4\xc2\x58\x4e\x61\x0f\x3d\x63\x94\x09\x9b\x4f\x08\xd3\x40\xb5\xc7\xa7\x11\xee\x0f\x36\xc2\x70\x43\x78\xc2\x8c\xec\xed\x3f\x3c\xba\xd4\xeb\xff\x8e\xaf\x82\x27\x29\xb7\xc5\xe8\xa2\xb9\x2d\x35\x16\x3b\xbe\xce\xab\x69\x1c\xa4\x5a\x7b\xfd\xa0\xbf\x5c\xbc\x9c\x7f\x4c\x71\x12\x20\x0e\x0a\x19\x0d\xa3\x84\xf5\xac\x3b\xcd\x68\x42\xb8\x4c\xfd\xba\xf0\x08\x1e\x22\xda\x06\x4c\x30\x58\x14\x68\x62\x94\x8e\x3b\xf5\x4c\xdd\xee\xe7\x53\x30\x32\xa3\x69\x00\xe0\x4e\x66\x19\x33\xa8\x97\x71\x59\x28\x8d\xd1\x94\x50\x6f\x1b\xec\xaa\xd2\xe7\xa2\x2b\xed\x28\x40\x53\x48\x2f\xb2\xe0\x58\xed\xba\x0d\x92\xb0\x5d\x37\x7c\x9a\x29\xb7\xa0\xb2\x87\xfb\x9f\xdf\x55\xde\xf1\x53\x18\x15\x2c\xf4\xed\x12\x2b\x7f\xd7\x26\xcb\x0e\x97\x36\xf8\xa5\x32\x8a\x89\x37\x6f\x74\x2e\x11\xfe\x48\x2c\x31\xc0\xb7\x81\xb3\x2f\x63\xcd\xf6\x85\x19\xd5\x3c\xc1\x77\xcd\xab\x03\x9d\xaf\x7c\x93\x9e\xca\x28\xc7\xfe\xe2\xef\xf3\x37\x52\xc7\x76\x0f\x70\x59\xb7\xff\x6b\x92\x02\x0c\x7a\xd9\xed\x7d\x9a\x25\x33\x33\x0a\x61\xc0\x89\xef\xd1\x36\x55\x9b\xe5\x99\xec\xf9\xc2\x63\x03\xae\x44\x7b\x2b\xbf\x67\xc7\x63\x86\x58\x8a\x37\x1f\x66\x50\x90\x14\x19\x79\x70\x28\xff\x9d\xd5\xa2\x5b\x0d\x4d\xc8\xd1\x59\xc1\x67\xcf\x57\x88\x7f\x1f\x2a\x75\x76\x23\x39\xb1\x8f\xdb\x3a\x67\x2a\x51\x68\x7b\x0b\x2f\x17\x07\xe7\xb6\x76\x16\xa4\x29\xe9\xa5\x30\x06\x19\xe9\x6c\xc4\xc0\x02\x69\xed\x09\x3d\x1a\xd1\x37\x1e\x3e\xb7\x9f\x07\x59\x8e\x2b\xc0\x2c\x00\xdb\xa7\xb5\xe7\xbe\xb2\x7d\xcc\x76\x42\x5d\x97\xd5\x55\x6f\x93\x36\x09\x21\x59\x28\x38\x6a\x3b\x16\xa7\x3c\xcf\xcc\xe7\x90\xb9\xed\x47\xa8\x44\xa6\x7e\x7f\x83\x3a\x13\xee\xae\xb0\x88\xd9\x12\xbe\x35\x00\xf9\x2c\x34\xfa\x8b\x6d\xad\x04\xb8\x1f\x13\x13\x46\x3b\x5b\xdd\x3b\x78\x47\xe0\xc2\x97\x33\x87\x45\x31\x05\x6b\x70\x77\xec\x4e\x63\x18\x06\xc3\xfb\xaa\xcd\xe8\x2f\x06\x75\xdd\xe8\x14\xb7\x85\x6f\xd8\xaf\x7c\x04\xa1\x3f\x07\xb5\x54\x46\x0c\x0f\x1c\x70\xce\x72\x4c\x0f\x13\x33\x61\xd6\x6e\xa2\x56\xa5\x1e\xe3\xc8\x8b\x31\xe4\xfc\x63\xa3\x31\xf1\x39\xe5\xe9\xd8\x6d\xae\x8c\xc6\x14\xb5\xee\x14\x9a\x02\xb6\x57\x75\xd6\x67\x61\xb4\xcd\xb4\xff\xe7\xff\xfd\xcf\xcf\xcd\xdd\xdd\xfa\x71\xb7\xf8\x63\xff\xf0\xb8\x6e\x53\x35\x7f\x12\x16\x69\xa9\x06\x05\xa1\xd5\xf6\xe1\x71\x24\x39\x38\xb9\x16\xe6\xb4\x4f\xb6\x20\x2a\xf5\xf2\x54\x43\x75\x26\xf4\x32\x9a\x45\xcc\x08\x0b\x5e\x74\xef\xe4\x76\xe8\xf6\x3c\xb9\xcd\x9c\x1b\xc4\x32\x56\xc8\x9a\xda\x96\xa7\x4a\x4d\xb3\x29\xc6\x85\xc1\x40\xfe\xb0\x87\x01\xce\xc2\xff\x9a\x38\xb1\x40\xe1\x1a\x9a\xc6\x55\x60\xce\xb8\x87\xf3\x8f\x38\x4e\x0d\x96\x0c\x7c\x72\x33\xae\x88\xcf\xef\x43\x2c\x56\xa1\xb1\x60\x3e\x39\x8e\x99\x58\xac\x62\xdc\xa1\x2c\x44\xf8\x76\x28\x08\xf4\x39\x79\x44\xb1\x0e\x70\x4b\x69\x57\x63\x8c\x78\x36\xe6\xae\x6c\x30\xc1\xf5\x67\x4b\x89\xc4\x66\xcc\x1b\xd4\x0d\x68\x9b\x34\x4c\xb8\x21\x8c\xa5\x4c\xf9\x04\x77\xfb\x9a\xe5\xf9\xdd\x94\xfa\xc1\x98\x80\xc0\x96\xc2\xf3\xd3\x7f\x07\xad\x0b\x26\x45\x84\x35\x56\x38\x40\x85\xce\x69\xf7\x6f\x50\xbd\x57\x59\x33\x0e\x1a\x93\x61\xba\xca\x14\xb7\xfe\xfa\x4d\xf5\xb9\x2b\x27\x73\x66\xfc\xb5\x9a\xa5\xd6\x13\x06\x77\xcc\x59\x6a\x0b\x63\x3a\xd6\x98\x26\x5b\xd8\x99\xe3\x3a\x7f\xa5\xd1\xe2\xf7\x64\xa6\xe3\xb1\xf3\xeb\xd5\xe7\xe5\xe6\x35\xd3\x89\xc2\xf8\xe9\xe9\xd8\x54\x50\x14\xdd\xcb\xa4\x75\x88\x65\x7f\xec\xea\xc3\xfe\xe6\xf4\xad\xd4\x7a\xf0\x40\x21\x50\x4c\xfb\x45\xeb\xc9\x33\xe5\x18\x83\x50\x5a\xd2\x47\xdd\x0c\xef\x28\x30\x1b\x74\x2c\xea\x1a\x0e\x32\x9f\x3e\x73\xe0\x92\x7a\x38\x53\xfb\xf6\x8e\xe4\xe9\xfc\x18\x19\xa1\xee\x92\x12\xc5\x4f\x7c\x14\x33\x9a\xd2\x8c\x19\x6a\x39\x2a\x47\x71\x2e\xc6\x35\x53\x3b\x62\x86\x85\x68\xc3\x50\x65\xcf\x2f\x0d\x4d\x27\xdf\x69\x62\xc0\x5d\x4f\x89\xc2\x26\x27\x77\xf0\xd1\xb4\xd9\xd6\x6d\x56\x2c\x0a\x7d\x2b\x3e\x70\x1f\x78\x2a\x9a\x2c\x6f\xff\xbc\xee\x6f\xa0\xd1\xb6\x32\x8d\x4a\x3e\x48\xf0\xeb\x3b\x71\x3c\x20\xd4\x19\x7e\xaa\xe6\x4c\xc2\x84\xf1\xc0\x04\x96\x9a\x5b\xff\xe1\x3f\x11\x25\x91\xee\x75\x11\x6f\xb3\xe2\x2a\xd3\x58\x6e\x3c\xe6\x53\x57\x20\xc6\x23\x61\x09\xd2\xcb\x52\x43\x75\x5d\x56\xcf\xdd\x17\x47\x46\x47\x6e\xe9\x7c\xda\xa0\x18\xec\xe9\x42\x22\xc4\x49\x0a\xe1\x80\x45\x9c\x15\xdf\x44\x8d\xa1\xda\x75\x59\xad\x2a\xf1\x3e\xd1\x52\x67\x9c\x52\xeb\xcf\x9c\x5b\x5d\xa1\x36\x4c\x16\xfd\x37\xb3\x94\x22\xce\xdc\x92\x96\x46\x72\x6d\x8c\xc7\x61\xe4\x7b\x36\x6f\x93\xdf\x12\xbb\xda\x25\xe2\x2a\xd4\x8b\xc8\x3a\x9b\x88\x73\x66\xe3\x30\x1c\xe3\xb1\x66\x28\xe1\x7b\x75\xfa\xfc\x56\x96\x13\x79\xce\xc1\x28\x4e\xe2\x33\xcb\xf5\x36\x91\x18\x7a\x1b\x31\x9e\x48\x4d\x3c\x86\x1e\x0b\x3d\x51\x77\xc4\xc8\xa0\xef\x20\x3f\xd9\x6b\xb9\x70\x4f\x55\x14\x81\x72\xc9\xe5\x7d\x3f\x1d\x94\x60\x18\x28\xfd\xef\x0b\x1a\x5b\xfc\xba\x14\xc9\x35\x0d\xe9\x70\x9b\xfa\x3f\x09\xc2\x8c\x01\xf5\xed\xc9\x04\xd6\x9b\xec\x2f\xf8\xbb\xa8\xca\x6d\x0e\x30\x4f\x25\x61\x5c\x73\x19\x51\x54\xa4\x35\xcd\x8b\x15\x47\x12\x39\xd4\xeb\x4e\xc4\x93\x71\x88\x52\x44\x8d\x64\xaa\xbc\x46\xc3\xcf\x6e\x93\xe6\x10\x03\x4a\x27\xb5\xf7\x71\x57\x2e\x6c\xc7\xe7\xc2\x37\x01\x08\x9c\x32\x47\xf1\xe9\x9c\xc6\xfc\x0e\xc0\x4d\xc0\xb8\x19\xdb\x7a\x91\xfe\x58\x42\x00\xd1\x57\xf6\x19\xec\x4a\x2b\xf6\x30\x0b\x28\x64\xdc\x30\x26\x63\xaf\x56\xdd\x26\x9c\x3d\xd6\x80\x9b\x24\xc5\xd5\xd1\xdf\xe6\xdb\x0b\x82\x1e\x8c\x9b\x34\xe1\xcc\xaf\x87\x43\x7c\x3f\xe3\x06\x0c\x2e\xa5\x1a\xde\x20\x2f\x8f\x50\xed\x6d\x8b\x19\x3e\x9a\x7d\x6f\xb3\x3c\x13\xce\xc6\x41\xc0\x91\x01\xf0\x50\x95\x47\xf4\x6b\x7a\x01\xe1\xef\x64\x1c\xa8\x08\x23\xfd\x87\xd2\x99\x7b\xd5\xdd\x11\x13\xa1\x10\xc4\x52\x54\xb2\x2c\xb0\x82\xe8\x0f\x85\x60\x1d\x04\x1f\xc4\x09\xed\x4b\x96\xe2\x78\x04\xed\x93\xdb\x73\xa8\x32\x8b\x23\x11\x61\xaf\x7b\xfd\xe0\x63\xa4\x98\x50\x29\xac\x64\x90\xad\x91\x6d\x3d\x1f\x38\xb9\x60\x95\x3d\xbe\x57\x31\x61\x51\xc4\x3b\xe8\xd6\xc0\xa0\x98\xc5\x44\x1b\x24\xbc\x58\x37\x9c\xdb\xbb\xd5\xfc\xed\x8e\x69\x10\x62\x68\x6c\x65\xdf\xae\x26\xf8\x58\x16\x53\x22\xb0\x46\xe3\x29\x41\x2e\xbd\x9d\x0c\xd2\x22\x51\xf8\x60\xda\x9c\x6f\xfb\xd2\x83\x44\xdc\x00\x96\x12\xec\xf0\x21\xe8\x03\x8b\x0b\xb3\x05\xdb\x98\x81\xed\xdc\x5f\x55\x20\x5e\x65\xd6\x0c\x5d\x80\x58\xcc\x59\xe2\x81\x10\xdb\xcf\xba\x81\x43\x1b\x25\x7a\xe9\xf4\xc9\x25\x71\x41\x22\x57\x71\xbb\x12\xea\xf5\x74\x3c\x37\x37\x62\x71\xac\x53\x94\x1b\xc9\x4b\x51\xec\xa0\x3a\xf8\x2f\x4a\x18\x58\x6d\x98\x77\x80\x63\x3d\xf0\x46\x67\x71\x22\x24\xb6\x1c\xff\xd1\x7e\x1d\xd4\x35\xe2\xc5\x86\x17\x99\xc8\x58\xba\x1d\xf8\xea\xf4\x39\x4e\xe0\x47\x73\x32\x91\x12\xc1\xd2\x1d\x7f\x60\xab\xca\xca\x3d\x7e\x1f\x82\xc4\x29\xe7\x98\x51\x17\xa7\x03\xaa\xe0\xb4\x7b\x63\xf7\x8c\x53\x15\xa0\x58\x73\x01\xef\x8b\x76\xde\xfa\xbf\x8b\xc0\xde\xed\xac\xc8\x9a\x99\xd4\x6d\x7c\xa3\x44\xc0\x94\xf5\x29\x3f\x67\x8f\x8d\x2f\x58\x04\x0c\xb1\x57\x3d\x75\xfd\xd2\x3a\x39\xbe\xcb\x22\x90\x08\xf3\xae\x9f\x9b\xee\x0a\x4d\x12\xf0\x81\x60\x9c\xfb\xb3\xd4\xd6\xb3\xe6\xf1\xfe\xfb\xf7\xee\x6f\x10\xc6\xd6\xaa\xf3\xb0\x2d\x7f\x7f\x29\xc5\xf7\x52\xf9\x63\x3a\xb0\x1a\x42\x8e\x2f\x57\xc9\xac\xb9\x54\x81\x8b\x35\xd5\xd8\xd7\xdc\x2c\xf3\xf2\xa4\xb7\x30\xf6\xdc\x60\x31\x80\xd5\x87\xb2\x6b\x77\x27\xb2\xdf\x6b\x80\xb3\xd8\x40\x18\xf5\xcb\xfb\x43\x55\x1e\xca\xdb\xb2\xa8\x1b\xa8\x90\xb9\x86\x88\xf7\x8e\x3d\x34\x76\xda\x19\x5d\x4b\x12\x04\x04\xaf\xc5\xc1\x7d\xeb\x6f\xc2\x5f\x46\x12\xd0\xd4\xf3\xd6\xbd\x5a\x65\x27\xcd\xeb\xeb\x7f\x49\x40\xad\x06\xa7\x7f\xef\xcb\xd7\x33\x21\xbf\xd1\x23\x48\x42\x66\xb5\xc9\x86\x46\xf6\x2c\x09\xe3\x38\x26\x03\x9c\x70\xef\x2f\xe2\x07\xc8\x08\x23\xf1\xbd\xd0\xdd\xd2\x56\x5f\x97\xd5\x97\xed\x83\x24\x4a\x14\x62\x35\x07\x61\x80\x05\x70\x34\x33\x82\x83\xbf\xfa\x77\x36\x24\x49\x48\x4c\xb0\xdb\xd7\xa3\xad\xb1\x1a\xbf\xac\x3e\x8f\x4d\x39\xb7\x03\x24\x34\x32\x31\xb5\x4b\x54\x59\x67\xcd\x4a\x64\xe3\x05\x23\xa1\x8c\x75\x15\x65\x27\x6f\x33\x14\xa5\x60\x09\x35\xc2\xf1\x02\x9b\x15\xe4\xf0\xec\xd3\xed\x09\x48\x29\x61\x41\x8c\xe5\x3e\x14\xc9\xb0\x1a\x05\xf7\xc5\x53\x51\x77\xb8\x5c\xf4\x78\xf2\x67\x65\x3c\x48\x1d\x08\xfb\xef\xa5\x5c\x8a\x62\x69\xf5\x37\x4d\x3b\x93\xad\xe9\xe7\x45\x32\xf4\x64\x56\x31\x4e\x71\x1f\xf3\x7a\x4e\x37\xe5\xa7\xc8\x9b\x4f\x9b\x18\x4f\x86\xa6\x91\xc2\x9d\xdd\x12\x77\xcf\x25\x7f\x58\xc2\x80\x21\xf3\xa4\x43\x1a\x74\x53\xb4\x0d\xa1\xa9\xf5\x15\x55\xe5\xfd\xb1\x5b\xfa\x12\xce\x09\x4f\x26\xb1\x54\xfb\x66\x2c\x4f\x75\x53\x1e\xac\x78\x7d\x56\x3c\xdf\xc1\x2f\x8d\x5c\xdd\x09\x63\x66\xad\x63\x9f\xa1\xb1\xc8\x39\xf7\xf4\xf6\xaf\x30\x49\x7c\x92\x98\x53\xc7\x1e\xf4\xe6\x01\x7f\x95\x12\x7f\xe1\x95\x89\x9d\x22\x02\xca\x2c\xde\x1b\x24\xd7\xfa\x43\x32\xe2\x4e\xbd\x73\x71\x6a\x90\x57\x33\xbe\xee\x44\x08\xac\xe3\x5d\xdd\xfe\xf0\x9f\x11\x41\x8c\x71\x26\x06\x47\xfb\xac\x76\x6c\x1e\x84\x0c\x0d\xee\xba\x08\x12\xab\x89\xe3\x1c\xdc\xcf\x56\xe4\x5f\xd5\xb5\x27\x21\x69\x22\x42\xdb\x28\xb1\x91\x3e\x7a\xd1\x8c\xdf\x71\x11\x5a\x7f\x8f\xdd\x0b\x3c\x88\xa6\xca\xca\x01\xbd\x0f\xb1\xbc\x98\x85\x36\xe5\xf7\xb2\xaa\x27\xfb\x7e\xa2\x22\x8a\x38\x79\xa7\x47\x7a\xbb\xb9\xdb\x3f\xdc\x2c\xfe\xec\xdb\xab\x89\x52\x1c\x0b\x19\x42\x29\x38\x36\xbf\x7f\xaa\xc9\x63\x53\x46\x44\xbe\x33\xd9\xa9\x36\xa2\x7b\xc5\xf0\x87\x25\xc3\x5f\xa4\x43\xc0\xa0\xe7\xbb\x47\xc5\x7e\x65\x3d\x37\xff\x6c\x35\xd3\xca\xc1\xd7\x36\xf5\x12\x21\x57\xf3\xd5\xda\x44\x1b\x83\x84\xcd\x43\x56\xac\x9b\x97\x07\x97\x70\x89\x81\x32\x28\x4b\x4c\x6c\xac\xcd\x0d\x52\x5a\x1f\x31\xa3\xfa\xff\x71\xf6\x26\xdb\x8d\xe3\x58\xfe\xf0\xeb\xe4\xa2\x16\x04\x07\x00\x5c\xca\xb2\xec\x50\xa5\x07\xb5\x25\x67\x54\x56\x9d\x3c\x3a\x18\x2e\x64\xfe\x83\x22\xd5\x24\x65\x87\xea\xe9\xbf\xc3\x0b\x80\x93\x68\x47\xf6\xd7\x8b\x8c\x2e\x13\xa2\x28\x12\x04\xee\xf0\x1b\xfc\x21\x41\x31\x9e\x69\xf7\xf8\x9b\xf3\x35\xa8\x8b\x1b\x65\xcb\xfe\x06\x1a\xf5\xa6\xb3\xf7\x09\x42\x84\x1b\xa3\x91\xab\xd7\xb7\xee\xbf\xae\x1c\xa5\x01\x4d\x31\x2d\xd8\x17\xf0\xb1\x55\x6f\xd6\xaa\x0b\x91\x01\x76\xd9\x99\xfd\x99\x29\x61\x01\xb8\x5e\x6b\xf7\xba\x7b\xaa\x86\x1f\x22\x6c\x3d\x40\x89\xe2\xb6\xca\x3e\x41\x01\xa7\xc4\x24\x52\x77\x3b\xf2\xb6\x3c\xc2\xed\x6a\x57\x8f\x92\xaa\xc9\x37\x1b\x81\x5a\x7b\x5b\xc4\x78\x84\xfb\xbb\xf5\xd3\x7a\xeb\x37\xff\x34\x8c\x22\x4f\x9c\x7c\x41\x45\x0d\xa8\xc6\x6c\xf8\xc9\xd7\x87\x2a\x92\x89\xb3\x33\xea\xb2\x95\xf9\x9f\x1c\x6a\x83\x1b\xad\xcd\xca\x9d\x02\xcb\x34\x61\x9c\x9c\xdd\x44\x88\xd6\x72\x8e\x85\xb6\x2d\xf0\x21\x4e\xbd\xe2\x50\x92\x46\x01\x90\x68\xa0\x4c\xe1\x8d\xd9\x3b\xa6\xce\x78\x02\xa4\x51\x18\x78\xdf\x61\x47\xbe\xff\x03\xf2\x52\x75\x12\x23\x49\x9a\x44\x24\xe0\x7d\x90\x63\xaf\x08\xf0\x9e\x76\xaa\xc8\x83\x72\xd6\xf0\xe5\x6e\x3f\x6b\x3a\xc4\xd3\xb2\xa8\x7b\x20\xd2\xb4\x78\x39\xda\x5f\xd3\x84\x06\xc8\x8a\xdb\x88\x4a\xc8\x32\x17\xdd\xb5\x50\x85\xce\xac\x8b\x9b\xa5\xf7\x52\xfc\x5b\x95\xe6\x34\xe1\x24\xf5\xbe\x6d\x6d\x08\x3b\x7c\xc5\x7d\xb0\x9b\x26\x3c\xc4\x0a\xbf\x2e\x3f\x8a\xba\xa9\xfa\x15\x37\x4d\x64\xc2\x6c\xb1\xf7\x74\x99\x65\x33\xa4\x34\x08\x30\x37\x38\x89\xcb\x23\xdc\x39\xe6\x27\xf1\x77\x99\x86\x0c\x5c\x96\xb3\x11\xf3\xc4\xaa\x24\xa5\x2c\x09\x88\x97\xd9\x2b\xce\x22\x7f\x7e\x87\xaa\xca\xf4\xb0\x99\x97\xb2\xd0\x20\x6b\xae\x01\xf5\xe6\x93\x6e\x7f\x28\x11\xd1\x90\x0b\xdb\xfd\x9d\x85\x28\xf6\x8c\x6b\xdb\xed\x83\xcf\xfe\x52\x1e\x44\x18\x79\x9f\xc4\xb9\xf6\x95\xdc\xe1\x57\x71\x92\x22\x92\xfa\xbe\x2a\xcf\xa7\x69\xab\xec\x1f\x13\xd4\x40\xca\x43\x0b\x64\x41\x3a\x5f\x9b\xf2\xf4\x3b\x76\xca\x85\x65\x0b\x2f\x33\xdd\x95\x8a\xd2\x34\x09\x3c\x4f\x04\x01\x65\xcb\x2b\xe5\x94\x24\x4d\x19\x15\xbe\x75\xd9\xa6\x6e\xdb\xf3\xf1\x37\x47\xbe\x73\x23\x04\x04\xc6\xcd\xf7\x7d\x9b\xf8\x0d\x1b\xa6\xd3\x4b\x94\x8a\x58\xb1\x2e\xa7\xcd\x3a\x0a\x6a\x53\x45\x52\xe2\x60\x44\xaf\x59\xd1\xdc\x91\xc9\xb5\x28\x62\xbc\x47\xfb\x7d\x25\xde\x45\x23\x26\xe9\x5c\xaa\xb8\x40\xb9\x24\x8c\xbc\x6e\xfd\xef\x54\xca\xe6\xdd\x76\x07\x5c\xab\xf2\x16\x84\x7e\xb8\x42\x4c\xa7\xca\x58\xef\xa3\x0a\xfe\xf7\x0c\x63\x1b\xfa\x24\xd5\x81\xa5\xaa\xbe\x97\x0d\xbc\x9c\xf3\xe1\xb2\x32\x78\x62\x3a\x4a\xad\xee\x73\xd9\x40\xbd\x17\x07\x91\x15\x5d\xad\x3d\xd5\x69\x88\x89\xcc\xbf\xdc\xff\x05\xe4\x93\x79\xa8\x25\x57\xdc\x41\x0d\x32\x91\x77\x6d\x3e\x2f\xcc\x74\x95\x3c\xf7\xb7\xba\x3b\x83\x40\xbf\x3c\xd7\x40\x2d\xab\xef\x55\xd9\xae\x71\xd5\x27\x79\x77\x0a\x86\x25\xde\x35\xe9\xff\x24\x25\x94\xa4\x26\x21\xcc\x51\x17\x4d\x56\x1d\xaf\xc0\xab\xa9\x01\x12\x85\x03\x73\x8e\xfa\xe6\x82\xff\xce\x24\xe4\xa9\x01\xc6\xad\x20\x7c\x9b\x63\xd9\xb7\xc2\xcb\xa0\xcc\xdf\x2d\x11\xd0\x08\x03\x1c\x21\xcb\xee\x95\x13\x01\x0b\x11\xff\x78\x14\x3f\x60\xd1\xae\x96\xf5\x71\x66\xf3\x9b\x8f\x3a\x05\x49\x42\x0c\xc9\x75\x95\x9d\x46\x38\x2a\x41\xa4\x41\x3b\x0e\xc4\x39\xb8\x16\xab\xc9\x2c\x62\xf7\x5b\x56\xa0\xad\x92\x33\x41\x76\x8e\x1c\x22\xcb\x7f\x1b\x9f\x5c\xa7\x89\xee\x67\xd9\xb6\x10\xa7\xfa\xad\x9c\xe2\xe5\x44\x48\x18\x2e\x67\xc7\x73\xde\x64\x56\xdd\xf0\x13\xad\xbf\xeb\xbe\x85\x08\x23\x9a\xb8\x12\xab\x33\x8f\xc1\xc0\x25\xf3\x4d\x4a\x11\x52\x86\x46\x07\x8b\x73\xf3\x86\xfc\xcd\x2f\x1f\xb1\x88\x98\xd5\xc3\x45\x85\x72\x67\x85\x37\x50\xbe\x49\x44\x24\x52\x2c\x22\x1e\x51\xea\x16\xe5\x09\x55\x76\xca\xfa\x34\x47\x44\xca\x58\x93\x66\x5f\xff\xc3\x91\xa2\x63\x52\x7d\xa1\x41\x90\x88\x08\xac\x4d\x56\xb7\x47\xaa\x8b\x67\xe9\x4e\x6e\x5b\x64\x24\xc2\x51\xf6\x4d\x95\x1d\x0e\x18\x2c\xf4\x78\xfa\xee\x0e\x8e\x3f\x13\x07\x04\x9f\x88\xb7\x2f\xbb\x39\x6b\x47\x16\xf7\x17\x1f\xa7\xb6\xbf\x7f\x42\x05\x5b\x91\x67\xcd\x65\x37\xa0\xc4\x88\x36\x33\x0c\xc6\x75\x81\xef\x6f\xc3\xfa\xc8\x8c\xf6\x50\x22\x92\x28\xc2\xd0\x6e\xef\x27\xfb\xf7\xac\xd8\x94\xcd\xf2\xad\x57\x9c\x49\x44\x42\xb9\xc7\x98\xa0\xcb\x40\x59\x8f\x0c\x19\xbe\x9e\xc8\x89\x8a\x23\x07\xba\xdc\xdf\xed\xfe\xc0\xfa\xe5\x7e\xf5\x8a\x88\xda\xc9\x4d\x48\xc0\xaa\x71\xb4\x81\x56\x59\x76\x20\x3c\x91\x00\x47\x25\x80\x2d\xa8\xa6\x74\x5e\xec\xda\xed\xad\xf3\x74\xaa\x7f\x4c\x3d\xfc\x13\x41\x29\x58\x5a\x42\x55\x89\xcb\xb3\x71\xdb\x66\xbd\x7b\x13\xcd\x37\xf1\x0e\x88\x9a\xed\x02\x4d\x41\x39\x25\x16\x83\x73\xc8\xc6\x6c\xf1\x44\x50\x45\x20\xf0\x8d\x7c\x2b\xda\x6c\x51\x2c\xdd\x05\x53\xd0\xe9\x48\x95\x03\xab\xa2\xf3\xbe\x52\xe3\xa0\x47\xf0\xc0\xaa\x2f\xf9\xeb\x9b\x8f\x31\x45\x9a\x10\x64\xa9\x82\x53\xab\x1f\x9f\x24\x65\x11\xaa\xfd\x38\xfa\xa3\xd3\x28\xf4\x07\x45\xa2\x3a\x18\x8d\x5d\x27\x27\x85\x7b\x3f\x50\x71\x5f\xbd\xdc\x82\xaa\xa0\x99\x7e\x8b\x0e\x12\xef\x60\x21\x46\x75\x2c\x21\xa8\xc4\xce\x08\x96\x5a\x57\x3f\x4f\xa0\x1a\xd0\x63\x40\xc5\x94\x86\x25\x04\x55\x91\xe3\x3b\x3f\x96\x05\x7c\x12\x20\x09\x25\x14\x96\x4b\xed\x52\x3b\x0c\x34\x85\x92\xca\x0a\x3e\x8a\x1f\xb0\x6d\xce\xed\x2e\xb5\xbe\x1d\xd2\x6d\x84\xe6\x16\xf3\x2d\xcf\x08\xdd\xb0\x0d\xb3\xe1\x22\xa2\xdb\x20\x11\x71\x66\x16\xbb\x6d\x1f\xec\x6d\x47\x51\x11\x5a\x05\xca\xe6\x8a\x6d\x1e\x64\xeb\x24\x7f\xab\x44\xe2\xc3\x40\x01\x61\x80\xe6\x80\x0b\x94\xfc\xfb\x4a\xa9\x39\x11\x10\x5b\x70\xe2\xa1\xd4\x6d\x92\x7f\x14\x4d\xa6\x96\x4e\x80\xbe\x83\xff\x0a\xd0\xcc\xab\xf5\x3f\x9d\x8f\x0b\x0c\xf8\xeb\x7f\x59\xb9\x9a\x7f\x21\x8f\x78\x78\x76\xff\x53\x0d\x49\xb9\xb5\x81\x79\x0f\xd9\x7c\x7e\x22\x4c\xa8\x62\x6b\x22\x5b\x43\x63\x95\xff\xaf\xb5\x13\x27\x53\xd3\x24\x96\x91\xf6\xf8\xbc\x5b\xce\x62\xf1\x87\xcf\x4c\x06\x89\x46\xc6\xa3\xd7\xf1\x7f\xb1\x5b\xd2\xfc\xf5\xc8\x20\x15\xb8\xf7\xd5\xe5\x11\xc6\x36\xeb\x89\x24\x41\xca\x46\x2a\xf1\x76\xbe\x59\x1c\x79\x37\x88\x10\xb4\x17\x7f\x59\xfd\xcf\xeb\x6a\xbb\xdb\x2f\x17\x4f\xcb\xd5\xc3\xea\x76\x7f\xf3\xe7\xfe\xe6\xf9\xe5\xe5\xf9\xfb\xea\x65\xbf\xdd\x2d\x76\xaf\xdb\xfe\x23\x92\x85\xbe\x9b\x9d\x97\x0e\x36\x47\x7a\x6f\xa6\x64\x32\x93\x65\x48\x14\x1a\x63\x59\xa9\x95\xb7\x2c\xd7\x5f\xb8\x13\x24\x32\xe4\x04\xa1\xac\x42\xeb\x59\xc7\x1b\x37\x2c\x52\xc2\x04\x5d\x93\x04\xbd\x6c\xdb\xf7\x77\xd3\x3e\xe5\x9b\x8b\x85\xe5\xcc\x65\x8c\x32\x02\x08\xda\x1b\xf3\x74\xbf\xf0\xbf\x29\xa6\x71\x92\x5e\xcb\x14\x8d\xc3\xb9\x4f\x5e\x54\x19\x0b\x8b\xb3\x72\x96\x1c\xbb\xe5\x40\x50\xb9\x3d\x9a\x62\xbf\xee\xdb\xf6\xf6\x9f\x83\x22\x8e\x4c\x12\x8d\xa0\xb0\xed\xeb\xcd\x76\xf9\xb2\xde\xec\xd6\xcf\x4f\xfb\xc7\xe7\xdb\xd7\x8e\x3e\x21\x69\x1c\x69\xa7\x27\xe4\x5e\x8b\x4e\x43\x70\xbc\x53\x48\xea\x4a\x1a\x8d\x37\x97\x5b\xe8\xf7\xac\x2e\xbb\x64\x43\x52\xa5\x10\x6f\xf1\x22\x8a\x1f\x59\x71\xb8\x11\x79\x7e\x5f\xe6\xba\xef\x1a\x78\x09\xd5\xe4\x2f\xff\x09\x6d\x70\x07\xbe\x39\x57\x63\xcb\x85\xcf\xea\x3b\xd7\xb3\x93\x82\xc0\x6c\x3e\xab\xdb\x87\x32\x61\xbd\x49\x96\x44\x56\x62\xa2\x8d\xdb\xac\xed\x9d\x6b\x67\xad\x90\x49\x3a\x98\xca\x2c\xe1\x16\x0d\x6c\x45\x16\x7c\x5a\xe6\x8e\x72\xe8\xc4\xf7\x97\x1d\xb4\x6e\x7c\x25\x69\x2c\xf1\xc7\x3c\xae\x9f\x77\xbf\x7e\x07\x05\xb1\xda\xbc\xc8\x6e\x78\x2e\x6e\xe0\x4d\xe4\xe6\xda\x2f\x69\x56\x7a\x21\x91\x82\x5a\x6a\xdb\x62\xb9\xe8\x30\x8a\x7f\x17\x01\xeb\x4f\x91\x0a\xbb\x37\x77\xe4\xc6\xb2\xba\x8a\xe1\xa5\x0c\x2c\xac\x50\x5b\x2a\xd1\x55\x32\xea\x8a\x74\x33\xf6\xba\xdc\x9f\x21\x02\x94\x27\x43\x31\x11\xfb\xc6\x8c\x9f\x91\x4c\x8c\xb6\x36\x38\xbb\xb2\x2c\x7a\x9e\x9e\x3f\x0c\x2c\x80\xce\xab\xfe\x8f\xb2\xe9\xd3\x5b\xa9\x80\xc2\xa8\xb9\xdc\x06\xcd\x9f\x03\x77\xa5\xe6\x12\x91\xe9\x4f\xa5\xcc\x41\x5e\x0b\xee\xb9\x61\xc0\xa4\x89\x3a\x27\x96\xd2\x11\x6c\x5e\xfa\x46\xb9\xff\x7e\xc3\x43\xe3\x99\x0a\x6f\x22\xcf\xa1\x38\xc0\x15\xa5\x49\x9a\x34\x50\x62\xd0\x6d\x69\xdf\xfd\xb2\xba\xb9\xcc\x98\x87\x25\xd2\x00\x49\x7a\xda\x5e\xfb\xfe\xa0\x27\x61\xfb\x86\xdc\xc1\x27\x38\x54\x15\x90\x14\x81\x95\x0f\xe5\xe1\xee\x5c\xfc\x42\xfc\x40\x05\x89\xc0\x58\xf9\xad\xd4\xf9\x5d\x59\x45\x7e\x9f\x55\x44\x47\x71\xea\xf3\x4f\x4f\x52\x18\x7f\x36\x74\xb2\x54\xaa\x3c\x9e\xce\x16\xcc\x33\x03\x3e\x56\xa1\x8e\x3d\x46\xc1\xea\x24\xf4\x88\x00\x15\x07\x06\xa5\x03\x51\xde\x5a\x54\xe2\xf8\x7c\x6e\x9e\xcd\x0d\x7a\x98\xde\xb5\x69\x93\x1f\x17\x6a\x2f\xc7\xbd\x81\xe6\xe6\x82\x6c\xe6\x4f\x7e\x52\xac\x01\xa5\xd3\xac\x9f\x88\xdf\xcf\xc6\x37\x29\x91\x96\x0b\x63\xb5\x77\x31\x3a\x72\xaa\xf3\x6e\x00\x8d\xb9\xb2\xde\x82\x8f\xb7\x8b\xee\x8f\x09\x21\xd6\x29\xa1\x5d\x12\x32\xf4\x51\xf3\x87\xd2\xd4\x0b\x71\xbf\x16\xca\xc6\xb2\x58\xea\x59\x9b\x45\x31\xe9\x0c\x28\x16\x6a\xdc\x49\x64\x75\xe9\xf2\x0b\xc5\x62\xab\x10\xd9\xde\x8a\x47\x34\xfa\x3e\x57\x45\x14\xa2\xd4\xdd\xe8\xd2\x18\x03\xcc\xb3\x30\xd7\x3e\xa0\xb4\x81\x3b\xc2\x03\xc5\x9d\x03\xce\xb9\x6e\x4a\x9d\x89\xc9\xfb\xa5\x78\x42\xb8\xf4\xd6\xe4\x65\x6d\x71\xb7\x93\xab\x4b\x49\xac\x9c\x47\x72\x56\xb7\xdb\x9b\x18\xf0\x3e\x54\x4a\x6d\x6b\xd2\x57\xfe\xfe\x2e\x4a\x66\xf6\xed\x52\x69\x1a\xf8\x1d\xa7\xbd\x9b\x4b\x17\xaf\x67\x65\xe1\x05\xce\x26\x17\x27\xb8\x02\x32\xf0\x4c\xdb\x95\x2f\x70\x18\xa0\xd7\x95\x00\xa5\x22\x3f\x53\x86\x2e\xa5\x93\x6f\x16\x86\xc6\xdc\x23\xf2\xb2\xb2\x78\x14\x8d\x7a\xfb\x0c\x8f\xa2\x24\xb1\x1d\x80\x0f\x68\xde\x46\xaa\xd2\x89\x92\x21\xc3\x6a\xf3\x31\x2b\x60\x00\xf9\x20\xdd\x47\xb5\xc2\xe6\xc6\x02\x9b\x1f\xf5\xa6\x2a\x4b\x53\x9a\x6f\xe7\xa3\x68\x63\xa4\xc9\xf3\x91\x60\xdd\x21\xb0\xd4\xed\xa8\x5c\x4e\x71\x63\x7b\xae\x4e\xf9\xb9\xee\x4a\xbf\x23\x40\x95\x52\xa1\xb6\x35\x93\x7a\x5d\x0c\xa1\x0a\x4a\x25\xa9\xad\xd8\x5b\x8f\x4e\xf5\x06\xc7\xa1\x3a\x78\xa2\x74\x18\x25\x9e\x22\xe2\xbc\x09\x66\x92\x4b\x3f\x38\x56\xbd\xde\x7c\xdd\xfc\x9e\xa9\x9e\xe1\xab\x34\xe3\x16\xf4\x20\xde\xe1\x11\x1a\x31\x62\xc2\x7f\x22\xa1\x3e\x30\x83\x9e\x31\x9a\xbb\x76\x8a\x4e\x94\xa1\x16\xef\x60\x69\xd0\x56\x29\x0a\xa7\x42\x9b\x2e\xbc\x40\x9b\xf2\x8d\xe7\x8c\x0e\x64\x8c\xa2\x24\x0f\xe5\xe1\x05\x34\xc0\x71\xd6\x0f\xc9\x0d\x26\xa1\x05\x63\x9f\x8b\x46\x1c\x46\xe9\x8d\x26\x51\x4a\xad\x7e\x6e\xa1\x17\x79\x6e\x93\x24\x7f\xcc\x58\xb5\x2d\x0d\x75\x53\x95\x97\xa5\xa8\x26\xdd\x56\x4d\x0c\xa7\x2e\x89\x5f\x34\xe5\xd1\x16\xbe\x66\x03\x52\x1d\x25\x0c\x65\x6d\xf3\xf2\xb0\x84\x2c\x77\xc6\x07\xe1\xc8\x52\x2a\xd1\x11\xd3\x98\xc7\x1c\x0f\xc7\x36\x19\xb9\xc2\x08\xea\x58\xc4\xa9\x43\x11\x6c\xcf\xd2\x0b\x54\xcc\x2c\xd1\x9a\x26\xc4\x5b\xe6\x60\x1e\xee\x48\x10\xe3\xab\xa2\xda\xa2\x0a\xdb\xe8\x30\xd3\x57\xe4\x15\x4d\x35\x45\x84\xe3\xed\xe2\xcf\xb1\x76\x80\x66\xa9\x41\xed\x80\x25\x54\x4d\x66\x32\x5b\xec\xe9\x75\xee\xe7\x79\x9b\x9a\x89\x00\x41\xf4\xae\x3b\x3d\xfb\x1a\x6b\xa6\x03\xfc\x8d\x05\xfc\x6c\xf6\x3a\x13\xd5\x65\x9f\xe9\xee\x7b\x0d\xc1\x3d\xac\x11\x3f\xe0\xe6\x7c\xc1\x90\x7d\x28\x65\xe5\x7f\x41\xff\xff\xce\xc7\x30\xee\x74\x3c\xd4\xc4\xed\xf0\x56\xa6\x14\x15\xd5\x06\xc5\x7a\x9d\x12\xc9\x93\x71\x8a\xb0\xef\xbe\x90\xf5\x5f\xe8\xfe\x5f\x3e\xfa\xaf\x9d\xec\xc3\xff\x7e\x75\x31\x69\xcc\x90\x5b\xfa\x0e\x55\x66\x2e\x37\xd0\x3c\x8a\x7a\xb2\x92\xeb\x94\xc5\x08\x5d\xf6\x06\x3b\x3e\x56\xd2\x69\x6a\xa2\xa4\xb3\xbe\x7e\x44\x8a\x7c\x77\x4c\x0a\xe2\xb6\xda\x5d\xe6\x95\x65\x13\x9d\x2a\x40\x5c\x41\xfb\x0d\x8f\xe2\xa7\xff\xb3\x88\x14\xe9\xd1\x30\x4f\xf0\x71\x2f\x72\xf1\x73\xd6\x63\x26\xd1\x42\x30\xac\x30\x94\xed\x8d\xa9\x07\x6a\x75\x89\x96\x21\x0f\x53\xa7\xa0\xb1\x6d\xda\x37\xdb\x76\xcc\xfe\x1e\x46\x40\xcb\xd0\xe6\x88\xdf\xb3\x02\x41\xad\xfe\xb4\x90\x00\xf7\x84\xaa\xec\x27\xe4\xb8\xdf\xe1\x1b\x30\x53\x07\xb9\x0e\x12\x35\xb0\x18\xcb\x3c\x9b\x9b\x65\x77\x4a\xa5\x50\x67\xdd\x7b\x48\x55\x9e\xee\xf2\xc9\x82\x62\x94\xc2\x5a\x94\x4d\x46\x45\xdd\x74\x7b\x95\x36\x46\x63\x43\xca\x9e\xca\xc5\x94\x33\xe2\xf5\x09\x04\xb1\xb5\xd2\x38\x55\xe0\x65\x11\xfd\x91\x34\x40\x50\x8f\x06\xf5\xa9\x7c\x0d\x04\x26\x46\x1c\x60\xdd\x2e\x0f\x8f\xe2\x27\x96\xc3\xae\x16\x0c\x08\x63\x41\xe5\x50\xeb\xa5\xdb\x46\x20\x4e\x21\x31\xae\xec\x82\x37\xb1\xfe\xed\x7a\x06\x9f\xaf\x8c\x3a\x13\x88\x75\x14\x58\x11\xf6\xe2\xbf\x50\x95\xdd\xf6\xb5\xca\x91\xe1\xd8\xa6\x8e\xa7\x6c\xfe\xe5\x86\xc4\x50\x32\xd4\xbc\xdb\x43\xa5\xc2\xe0\x57\x21\x87\xfb\x30\x0d\xb8\x74\xc2\x9c\xaf\xa7\xc3\x2c\x2d\x70\xb0\x0d\x02\x0d\xa4\x8e\xc7\xcd\xef\x2b\x61\x09\xa0\xb1\x40\xaa\x81\xbf\xa0\x07\x51\x68\xbf\x34\xcf\xad\x61\x40\x05\x13\x8e\x56\x2a\xa4\xbf\x97\x14\x12\x49\xbb\x5e\x2e\x72\xef\x6a\x54\x83\xf4\x03\x78\x68\xb1\x04\xa3\x66\xef\x5d\x55\x1e\x3b\x6d\xd8\xf1\xd2\x0c\x3c\x8a\x5d\x3f\xb2\xf6\x32\x39\x03\xd7\xe0\x27\xf8\x78\xbc\x0c\x62\x24\x48\x35\x8f\x86\x1a\xec\xbb\x72\x8a\xe5\x1a\x6d\xc0\xee\x53\x82\x3a\x19\x13\x5c\x34\x8a\x52\x77\x86\xfd\xd6\x78\xea\x2d\x9b\x00\x3e\x41\xa4\xb1\xe8\x8c\x5d\xd1\xf9\xff\xcb\xb7\x18\x64\x12\xba\x26\xb7\xf3\x4a\x1a\xde\x14\xc9\x82\xd0\x0c\x85\xa0\xbf\x67\x45\x31\x23\xb8\xe4\x87\xf3\xd8\x5a\x9f\xbf\x95\x1f\x37\x99\xee\x4b\x50\x20\xa5\xd1\xc4\x8b\xb3\x7d\x94\xc3\x2e\x2d\x28\x6a\xe5\xdb\x41\x54\xf9\x65\x84\xfc\x02\x1d\x19\x6d\xdd\x43\x9e\x5e\xb7\xfb\x5e\x92\xa2\x3b\x9e\xc4\xdc\x5f\x9f\x13\x28\xf0\x62\xbd\x3e\x62\x1c\xad\xe0\xa0\x69\x8c\x91\xea\xf2\xdf\xbf\x44\xb0\x74\x9f\xa0\xd8\x59\x5c\x3d\xfd\x73\x37\xcb\x1f\x9a\x2d\x08\x02\x84\x0c\xfb\xf8\x8b\x5c\x74\xe8\x56\x80\xd0\x70\xe1\x0d\x29\x45\xf1\x6c\x0c\xd2\xd2\xbb\x8c\x06\x80\x85\x58\xa6\x5e\x6f\xb7\x43\x68\x2b\x80\xd0\x31\xb1\x53\xfa\xa9\x1c\x50\x78\x66\x0a\x1b\x00\x8a\x51\xab\x45\x83\x38\x26\xa7\xc9\xd1\xce\x84\x51\x63\xd5\x04\xd4\xfa\x98\xb8\x35\x15\x49\x30\x2f\xeb\x4d\x05\x26\xfb\x39\x8a\xc1\x4c\x90\x5a\x9d\xca\xac\x7e\x2e\x6e\x44\xd3\xe4\xe3\xfe\xb1\x09\x34\xa5\xd6\x6e\x2b\x2f\x85\x46\x27\xc5\x9b\xcb\x35\x57\xc9\x90\xc0\xa6\x09\xed\x7e\xe3\x26\xd2\x17\x2c\x5f\x43\xa4\xc6\xd8\x66\xa5\x4a\x07\x2f\x74\x07\x42\x62\xb0\x74\x73\x9f\x0b\x9d\xa1\xbd\x69\x8d\x79\x67\xa7\xa3\x9c\x98\x30\x09\x98\x05\xd7\xab\xf2\x1d\xd5\xee\x27\x0d\x4f\x13\x32\x19\x06\xbd\xb5\xa9\x63\x6a\xe3\x6d\xb8\x11\x1d\xaa\xc4\x84\x46\x0a\xab\x83\x9a\xfd\xe2\x4d\x32\x91\x33\xc4\x6c\x43\x3f\xd1\x99\xfa\xcd\x6a\xfd\x98\x98\xa6\x58\x08\xd1\x59\x77\xc9\xb1\xb6\x3a\x95\x36\x4b\xf9\xdf\xf5\xf2\x79\xf2\x19\x1a\xdb\x66\x97\xc8\x65\x59\x8f\xde\x13\x43\x79\x40\x9d\xa1\xdb\x13\x74\x9d\x8d\xaf\x91\xec\x93\xab\xa7\x3c\x0e\xe3\x01\x91\xb4\xbe\xb9\xdc\xec\x96\x93\x27\x48\x15\xa1\xbd\xf7\x9b\xbb\x86\x41\x7c\x6c\x58\x2a\x71\xda\x3f\x94\xd5\x50\xbe\xc7\x30\x63\x2c\x51\x17\x2f\xa9\x9d\x22\xed\x16\x38\x7a\x37\x0d\x0f\x04\x26\xe3\xaf\x32\x13\x8d\xa8\xda\x05\xe7\x0f\x71\xce\x3f\x85\x2c\xfa\x8f\x85\x1c\xf1\x87\x26\xcb\x6d\xf4\xf7\x54\x5a\x95\x81\x99\xf5\xd4\xf0\x38\xb2\x40\x85\xb2\x68\xaa\xb3\x6a\xca\x39\x05\xdd\xc4\x70\xce\x51\x09\xa6\x5d\xf6\xb7\x4a\x1c\xe7\xe8\x2c\x83\x2b\x10\xa1\xf3\xa0\x32\xe7\x42\x8f\xad\x6b\x07\x49\xd6\x8c\x9c\xf2\xf8\x3c\x69\x44\x10\x82\xb8\x38\x4a\x2f\xca\x30\x19\x40\x05\xda\x8c\x1f\xca\x5c\xdf\x94\xe7\xc3\xdb\x15\xaa\xe0\x1f\xb3\x2b\xc3\x17\x7c\x63\x23\x22\x82\xfd\xee\x9b\xdd\x6e\x3b\x5e\xe0\xbe\x42\xf7\x4d\xc0\x8e\x46\x44\xdc\xb3\xdf\xa0\xeb\xba\x19\x21\xac\x33\x02\xa2\xf9\xbb\x3f\x2a\xc3\xf8\xb0\x67\x6b\x15\x04\x67\xef\xac\x0c\x09\xe6\xf1\x65\x91\x5f\xac\x4a\x66\xf5\x8b\xfd\xcf\xc8\x28\x42\xcc\x0f\x42\x5d\x7a\x19\x58\x23\x39\xa0\xa8\x89\xeb\x4f\xef\xa0\x6e\x86\x70\x60\xa3\x22\xb0\xac\xd6\x1e\x3c\x3c\x12\xa8\xf7\xc3\x58\x82\x39\x67\x9b\xef\xd7\xb8\xbd\xba\x03\x9a\x73\x04\x99\x64\x08\x6b\xc4\x25\x64\xfc\x49\x88\x28\xce\xa9\xc7\xf5\xed\xfe\xfe\x65\x71\xbb\xda\x2f\x17\xbb\xd5\xfd\xf3\xcb\x9f\xfe\x14\x26\x48\xb8\x25\x55\xd6\x6f\xd6\x28\x69\xb6\xf8\x6c\x4c\x48\x70\x1a\xe0\x2c\x6b\x2f\xb4\xb7\x5c\x9e\x0c\x8c\x44\xe2\xba\x8b\x2f\x22\xab\x5d\x75\xac\xfb\x3a\x11\x22\xc7\xf9\x4d\x14\x3a\xef\x98\xe6\x9f\xc1\x9d\x3e\xa7\x62\xcd\xa5\x4a\xc6\x48\x40\xd4\xb7\x4d\x95\x30\xc1\xfd\x6d\x54\x59\x98\xfe\x3b\x9f\x12\x5c\x6d\x0a\x46\x53\xce\x06\x4a\xbf\x0f\xd9\x31\x1b\x2e\x41\x34\x08\xa2\xc4\xbd\x8d\xa7\x72\xb0\x89\xb6\x07\x38\x16\x8d\x10\x4f\xf5\xfc\xee\x6f\x04\x0d\x02\x61\x78\x6f\x0f\xb5\xa9\x4a\x93\xe5\xb0\x3e\x1e\xce\x63\x05\x55\x1a\x04\x40\x2c\x7f\xde\x62\x42\xf1\xbb\xc7\x2b\x3b\x0d\x48\x44\x30\xfb\xb1\x2c\xf4\xa2\xeb\x0f\xd3\x80\xf0\x18\xac\x30\xe3\xb9\x12\x3d\xb3\x94\x06\x44\x6b\xfc\x4d\xbb\xa7\xf9\xbe\xc5\x79\x4a\x9e\xa3\x41\x98\x48\x6c\x1e\xe4\x99\x82\xa2\x86\x1d\x54\xc7\xfa\x9b\xa8\x1f\xc5\xcf\x91\xbf\xc5\xf0\x99\xd0\x20\xa4\x21\xce\x9b\x1b\x7d\x5a\x1f\xc5\x01\x46\xcb\xb0\xbf\x7d\x91\x0c\xb0\x38\xfd\xf8\xfa\xb0\x5b\x6f\xd7\xf7\xfb\xef\x8b\x87\x87\xd5\x6e\xac\x11\x49\x83\x38\x06\x2b\x36\x8a\x65\x72\xbc\xec\x71\xf2\xe8\xc7\x29\x21\xc8\xbc\x43\xae\x7b\xa6\x34\x48\x62\x83\xd3\x54\xb8\x52\xd8\xee\xad\x82\xfa\xad\xcc\x75\xec\xbf\x2d\xe1\x91\xd7\x77\x6e\xb7\xf2\xfa\xfe\x5c\xd4\x6b\xdd\xdd\x59\x4a\x0d\x0a\xb3\xcf\xae\x5f\xe7\x39\x56\xd7\xf8\x22\x29\x4b\x70\xf5\xba\xcb\xaa\xda\xca\x03\xdb\x69\xe5\x0f\xab\x14\x37\x35\x27\xb0\xdb\xce\xe5\xc7\xfa\x30\x1f\x84\x4d\xce\xcc\x03\x6a\xf7\x79\xd4\xdf\x7b\xe9\x8c\x73\x63\x7f\x3c\x24\xc0\x47\x76\x6a\x37\x19\xb2\x8e\x77\xa5\xad\xdb\x8f\xde\x68\x1a\x70\xca\x50\x64\x39\xcf\xde\xe1\x06\x1a\xf8\xd9\xd9\x1d\xd1\x80\xab\x14\x3b\xb0\xed\x93\xdb\x0f\xf9\x26\x34\x48\x53\x0e\xd6\xfb\xf2\x72\x6a\x06\x45\xfc\xff\x4b\xc7\x0a\x7d\x9f\x30\xda\xde\xee\x16\x2f\xbb\xfd\xe6\x65\xbd\x5c\x75\x5f\x20\x4d\x30\x68\x8f\x9e\xeb\xac\x18\xd4\x91\x27\xe7\x11\x22\xc4\xf7\x2d\xab\xff\x80\xaa\x46\x4f\x96\xa1\x38\x63\x3b\x40\x21\xc5\xcf\xa9\x69\xde\x8b\xa3\xb7\xe9\x9b\xdb\x38\x69\x20\x23\xe9\xad\x1a\x5c\xe1\xf6\x4a\xed\x9e\x06\x92\x13\x54\x8c\xfc\x23\x3b\x3d\x66\x87\xea\xf3\x8a\x2b\x0d\x54\xca\x50\xd8\xc6\x54\xe5\x7f\xa1\x58\x14\x4e\x25\xba\x3b\x0a\xa8\xdd\xa0\xe1\x54\x81\x42\xa0\x8b\xbe\x6c\xcf\xb2\xb9\x9c\x60\xb4\x12\x29\xed\xec\x89\xeb\xe7\xcb\x68\x25\x82\xc4\xa0\xe2\x05\xfe\xf1\x3e\x33\x9f\xfd\x2e\x50\x16\xf0\x72\xaa\x4a\x05\x75\xdd\xc9\x32\xf8\x99\xd7\xad\x92\xa3\x45\x92\x06\xa0\x53\xec\x26\x54\x56\x72\x66\x54\xf6\xa1\x81\x21\x1a\xeb\xea\xd2\x9b\xe7\x5f\x19\xdb\xd1\xc0\x50\x89\x79\xa7\x7a\x13\xd5\xa1\x8d\xd8\x3e\xb2\x46\xbd\xc1\x74\xb1\x33\x86\x62\x21\xa4\xc9\x8e\xb0\xcb\xa0\x72\x04\x56\x4a\x02\x16\x7a\x3b\xf1\x19\x49\x11\x4a\xc2\x90\x63\x47\xe3\x03\xb2\xbb\x91\x84\x19\x25\x21\xd3\x08\x69\x70\xce\xb1\x8f\x8b\xc9\x47\xd1\x3f\xdd\x26\x99\xe7\x5c\xdf\x74\x8a\xf0\xfe\xb0\x64\x08\x66\xa9\xe0\xbd\xfc\x01\x4e\xfe\x6a\x16\x50\x44\x49\x1c\xab\x54\xf4\xcb\x0a\xea\xc5\x4d\x05\xe3\x28\x41\x9f\x69\x97\xe8\xc7\xfb\x1a\x55\x32\xb6\xe2\x08\x4f\xa5\xf6\xf7\x8b\xd0\x94\x1b\xe3\x49\x26\x5b\x14\x71\xcc\xb5\x87\x18\x8e\x00\xab\xbf\x6a\xd2\xfc\xdd\x7f\xbb\x2f\xd6\x18\xb6\xd8\x10\x6b\xee\x3d\xe6\xff\xf9\x6b\xea\x9d\xda\xfe\x7f\xee\xf3\x2c\x10\xd6\xc6\xa7\xbd\x8b\x59\x71\xb8\x15\x0d\x38\x47\x47\xff\xdb\x58\xc4\x90\x41\x6c\xdf\x86\xf9\xa9\x4a\x18\x4d\x10\x01\x71\x2a\x3f\xa0\x9a\xbc\xcf\x84\x69\xbb\x25\xbf\x67\xf0\x81\x5d\x44\xd7\x79\x75\x87\x39\x09\x42\xea\x65\x27\x7c\x2c\xd3\x1f\x4c\x71\x85\x7c\x59\x3c\xdd\xaf\x56\x4f\xb7\xfb\xb8\x3b\x42\xad\xc0\x6a\xa6\xca\xef\x00\x3f\xc2\x01\x0b\x97\x12\x9e\x46\xc6\xfb\x51\xb4\x5b\xf1\xe4\x99\x72\x19\xa6\x83\x16\x6c\x78\xe9\x3e\xa7\x42\x11\x5e\x63\xfe\xb7\x13\x71\x7a\x4a\xd2\x94\x13\x87\x28\xc3\x4b\xee\x50\x1b\xcf\xc6\x57\xfa\x06\x8d\x30\xff\x21\xa5\xd1\x3d\xf3\x78\xf9\x26\x72\x73\x3b\x2e\x11\x53\x22\x62\xb0\x95\xcf\x5e\xea\x8c\x12\x91\x58\x99\xc1\x76\xfa\xdd\x89\x2c\x7f\x2c\xdf\xe1\xfb\x1b\x14\xdb\xa6\x3c\x9d\xfa\x79\x2f\x80\xe2\x1b\xfb\x90\x19\x0b\xf1\x74\x4e\xed\x59\x59\x3c\x42\xbb\x4b\x67\xf5\x35\xcb\x74\x5c\x81\x1f\xff\x40\x99\x80\xad\xbb\xf5\x92\x2b\x24\xf4\xc7\xd2\x58\x82\x0f\x84\x6c\x3b\xfd\x31\x2b\x06\xde\x8d\x7e\x9c\x8c\x50\x24\x22\x07\xd3\xc4\x7c\x72\x33\xa4\x51\x08\x7d\x5e\xed\xbe\xed\x4f\x50\xed\x6f\x5e\x16\xfe\xc7\x28\x12\x63\x10\xd2\x80\x38\xbe\x16\x6d\xec\xd0\x3d\x75\x25\x14\x2a\x65\x59\xc4\x2b\x16\x1b\xba\xfb\xa7\x54\x24\x64\xff\x3e\x63\x6d\x16\x41\xa1\x76\x6a\xcc\x2f\x02\x3a\x08\x62\xd3\x8b\x22\x89\xe2\xc7\xe4\x47\xe8\x30\xf5\x96\x2b\x4b\x51\x39\xb3\x0f\x67\x82\xe6\x63\x2b\xa2\x63\xeb\x23\x7f\xae\x5d\x43\x72\x8e\x2c\x41\x89\x4e\x12\xe9\x34\xdc\x73\x29\xd4\x8f\xfd\x5d\x59\xa1\x60\xde\x47\x95\x8d\x4c\x53\x3c\x96\xb3\xcb\x5d\x29\x31\x24\xf0\x8e\x5b\xdb\xac\x01\x97\xe5\x7f\xc5\x08\xa5\xc4\x08\xe9\x59\x5e\xb6\x48\xdd\xc7\xcb\xfd\x83\x30\x9a\x06\x5d\xf8\xb3\x3f\x89\xcb\x5e\xe5\x19\x14\xcd\xd1\x56\x30\xdc\xdd\x0d\x03\x93\x20\x52\x55\x68\xfd\x3f\x57\xed\x7d\x1a\x86\xd2\x8a\x55\x6c\xd6\xf7\xf7\x7f\xee\x6f\x16\x4f\xbf\x4f\x06\x44\x31\x89\x86\x95\xc6\x8d\xc8\xe6\xb5\xd6\xdb\xa1\xb6\x05\xf0\xb8\xf8\xd7\xfe\xcf\xc5\x9f\x3e\xea\x0c\x23\x15\xe2\xcf\x91\x99\x9e\x00\xd2\xfc\x00\x93\xc4\xbc\x03\xab\x58\xc5\x34\xff\xe1\x38\x25\x38\x19\x51\xce\x64\xdf\x13\x58\xc7\x77\x23\xa4\xa4\x73\x0a\xfc\x7c\xeb\x08\x69\x68\x6b\x5e\x5e\x48\xb7\xcd\x44\xf1\xb9\x2f\x47\x78\xd7\xc9\x87\x52\x8e\x8b\x8b\x9d\xd2\xd0\x49\xc6\x4e\x52\x2d\x3f\x5a\x08\x6f\xa9\xf3\x08\x5a\xe4\x3b\x1f\x5f\xf4\xd7\xca\x62\x8a\xfd\xcd\x4d\xe9\x9b\x46\x6d\x88\x4f\x2c\xe3\xf8\xec\x94\xf4\xfa\x03\x11\x86\xe2\xd6\x72\x75\x96\xe4\xe8\x46\x72\x22\xf1\x49\x9d\x4f\x27\xa8\x94\xa8\xe1\xd9\x8c\x12\xa1\x90\x27\xda\x74\x21\xc4\xf7\xac\xd0\xe5\x07\x59\x39\x54\xae\x1f\xc2\x22\xa2\x1c\xc0\xcf\xaf\xa2\xd3\xc8\x3f\xe4\x4a\x78\xc5\xdd\xd5\x29\xab\x4b\x3d\xd0\x3f\xa4\x21\x07\x8a\x75\xc7\x9b\xc7\xdd\xe8\x87\xa4\x8a\x23\xf8\xca\x51\x35\x3b\x0c\x19\x0d\x45\xa0\xb0\x86\xd6\x3d\xdd\xef\x68\xf8\x77\x57\x95\xc7\xfb\x41\x3d\x72\x7e\x2f\x0d\x05\x49\x91\x3e\x5d\xc0\xcf\xc6\xe1\x7d\x16\x72\x12\xb9\x84\x22\xa2\xc8\x7a\x90\x99\xee\x1b\xc0\x75\x77\x01\x26\x60\x3d\x97\x7d\x82\x83\xf9\x4f\xf4\xd7\x34\xd2\xfe\x0f\x21\x7f\xcd\x14\xfe\x69\x28\xb5\xb5\x0a\xb4\x51\xd0\x1d\xda\x99\xd8\x6c\x6d\xfe\x91\x29\x42\x03\x98\x91\x8d\xbb\xfd\xfc\x29\x2b\x66\x11\xee\x59\xf1\x9e\x21\x16\xa7\x57\x32\xa0\xa1\x92\x36\xa0\xc9\x54\x89\xbe\x46\xa0\x61\x70\x4c\x60\x40\xb4\xc9\xcb\x66\xfb\x37\x98\x68\xa3\xaa\x91\x3b\x07\x84\x89\xab\x19\x37\xe7\xca\x9b\x86\x77\xb7\x11\xe2\x34\x4e\x3a\xaf\xdf\x7e\xfe\xf8\xc3\x94\x62\xdc\x76\x23\xaa\xaa\xac\x77\xd0\x4f\x19\x50\x89\xcd\xd0\x7d\x71\x49\xdb\xe5\xfa\xb5\xc8\x9a\xc4\x0f\x32\x41\x8c\x32\x4c\x03\x98\xd5\x30\x40\x0e\x4d\x62\xbc\xc7\xc2\x6d\x79\xc0\x7e\xf3\xf8\xce\x19\x16\xe3\x9b\xe9\xb2\x1d\xd1\xa8\xb7\xad\x15\xc2\x1f\x24\x1c\xa1\xe1\xdc\x7a\xdc\x34\xe2\x07\xbc\x94\x4d\x39\x0b\xde\x1b\x9c\x15\x52\xcc\x42\x1f\x45\x56\xdc\x54\x99\xbe\x7e\xd6\x13\x5e\x17\x8d\x82\x18\x10\x5e\x29\xf2\xdc\x2a\x91\x75\x2e\x59\x34\x22\x3c\xc4\x3e\x00\x12\x59\xf2\x01\xeb\x6a\xfc\xb5\x11\x01\xeb\x50\xec\xfa\x05\x83\xd6\x0c\x8d\x42\x12\x20\x31\xef\xa3\x6b\x4a\xe3\xdf\x10\x9e\x8d\x9a\xf2\x07\xd1\x40\xbb\x97\xcd\x56\xaa\x68\x14\x86\xc4\xd8\x7e\x20\x22\x55\x87\x0d\x08\x1a\x85\x3c\x88\x46\x32\x1c\xf7\x95\x38\xc1\x16\xf2\xc9\x8a\x1c\x85\x32\xd6\x63\x43\x9a\xac\xf8\xe4\x0b\xa3\x40\x0e\x64\xe2\x5d\x5b\xee\xdf\x50\x4d\x9e\x60\x14\xc5\xa9\x84\x61\xd1\xb8\x7e\x3d\xf5\x46\x49\xff\x49\xfe\x1a\x94\x9e\xe8\xe0\x7f\xf4\x21\xfc\x97\x61\x75\x14\x25\x40\xd2\x61\x80\x04\x56\x5b\xd4\xff\xf6\x48\x12\xa1\x07\xeb\x84\xc8\x8f\xb3\x6f\xd2\xe4\xaa\x55\x82\xc4\xc1\x36\x65\xdc\x94\x65\xde\xa1\x19\x3f\x4d\x65\xa3\x38\xb6\x5c\xc3\x36\x7a\x5c\x74\xa6\x17\x63\xf1\x2a\x1a\xc5\x9c\xa1\x64\xa0\xb2\x44\xd8\xf5\x48\xbe\x9f\x46\xb1\x20\x48\xd0\x73\x78\x26\xc0\x69\x36\x29\x7f\xcc\x3f\x8f\x58\x46\xb8\x1e\xde\x2f\x76\x6a\x46\x16\xea\x4a\x32\x9d\x46\xb1\x56\xa8\x06\x58\x9f\x65\xf0\xc9\x8c\x4d\x88\x62\xd6\x40\x06\xd3\xd3\x4f\xd6\x37\x54\x45\xed\x1b\x5c\x58\xd6\x59\x14\xba\x19\x88\x74\x7f\xd5\xcf\xa1\x51\x02\x51\x98\x8e\x08\xc2\x36\xa6\xbf\xb9\xac\x46\x94\x00\x37\xbc\xdd\xb0\x75\xef\x05\x0f\xf5\xae\xc4\x00\xf4\x3b\x64\x9b\x5c\xa8\x09\x34\x9a\x46\x8c\x58\xb7\x30\xf5\x76\x2e\x7e\xc4\xeb\x7a\xa1\xfb\x25\x36\xe2\x61\x1a\x93\x71\x79\x0d\xc3\x0c\xdb\x72\x99\xeb\x29\xd1\x88\x0b\x2b\x9a\xe7\x3b\xcc\xab\xdd\xb7\xa6\xdc\x54\x65\x9b\x64\x54\x57\x01\xe2\x97\xbd\x08\x1a\x71\x23\x83\x21\x6d\xec\xaa\xdc\xde\x4d\xf9\xde\x9e\xce\x63\x7a\xf8\x7f\x22\xff\x1e\xa4\x5a\xa3\xce\xd2\xb1\x2c\x9a\xb7\xfc\x62\x25\x18\xf7\x87\xaa\xfc\xf0\x30\x3a\x1a\x89\x20\xc5\xf0\x13\x05\x93\x7a\xfd\x40\x1a\x89\x98\x05\x7d\x71\xac\xb9\x03\x70\x1a\xba\x9f\x84\x8d\x91\xd0\x01\x75\xed\xe0\x3b\x5b\xba\x39\xce\x39\xc3\xb8\xd1\x52\x45\x18\x8d\x89\xbc\x02\xa1\x2f\x8b\x73\x53\x8e\xdd\xc9\xfd\x38\x63\x15\xb4\xea\xee\xc6\xc3\xf5\xdd\x1c\x5f\x88\x8a\x18\x9a\xf3\xb6\x5b\xd3\x6c\x22\x10\xa9\x84\x68\xe5\xa5\xc6\xc5\x7b\x56\x1c\xea\xfd\xa1\x9c\x06\xa3\x91\xa2\x12\xab\x19\x6d\x20\xbc\x59\x3d\xdd\xae\x9f\xee\xf7\x8e\xc6\xe1\x83\xe2\x48\x31\x1b\x26\x7d\x7b\x58\xf6\x30\x1c\x1a\xa9\x54\x22\xea\xb9\x3a\x17\x6d\x5c\x86\xba\x26\xdb\xd2\x34\x4b\x71\x7a\x01\xa1\xde\xfa\xc9\xa6\x65\x84\xc0\xf9\xb5\x2a\x87\x70\x16\x7f\x54\x59\x8d\xec\xfd\xb9\x38\x09\xf5\x63\x53\x95\x8d\x95\xfc\x43\xec\xf0\x24\x3c\x8a\xb4\xb6\x4c\xe3\xfa\x7c\x3c\x76\x71\x59\xa4\x4d\x82\x1b\xf6\xeb\xd3\xfd\x2f\xa1\xf9\x34\x02\x93\xe2\xbd\x59\x6c\x6e\xfc\x09\x0c\x63\x08\xb6\x78\x1f\x79\x6a\x38\x38\xcc\x6c\xb5\x3b\x32\x82\x4a\x9b\xc9\x17\xe2\x08\xcb\xb7\x4c\x66\x73\x72\x50\x34\x0e\x02\x85\xf8\xf7\xc5\xc3\xe3\x6f\xfe\x4f\x49\xea\x1d\x90\x36\x6b\xab\x75\x46\xbb\x63\x3c\x32\xb1\x27\x5c\x0d\xd6\x6c\x7f\x58\x09\xcc\x6a\xb7\xe7\x13\x54\x36\x49\xfd\x1d\xcb\x21\x3f\xba\x13\x40\x8c\x42\x05\x7f\x9e\x8b\x0d\x38\xd7\x80\x5f\x97\xfc\xe3\xc0\x50\xfc\x98\xc5\xb9\x21\x74\x76\x58\x6d\x8c\x03\x93\x92\xc0\x22\x2e\x57\x4e\x5c\x7a\xae\xde\xe4\x46\x87\x6d\x8c\xd5\x3e\x55\xbb\xa6\x5b\x86\x7c\x79\x40\x39\xa5\xec\xf3\x48\xf9\xb3\x55\x63\x72\xf6\x48\x5b\x97\xe3\x81\xf4\xea\xdf\x62\x4e\xd2\x38\x01\x69\x2c\x1f\x1a\x1d\x79\x46\xb8\x5f\x1a\xb3\xc0\x66\x5d\x12\x51\x08\xb2\x14\x15\x5a\x3f\x4d\xea\x4d\x31\x23\x29\x2e\x1c\x68\x5e\xbc\x81\x6a\xf7\x56\x9e\x6b\x51\x68\x64\x3f\xdf\x95\xd5\xa3\xe8\xa9\x25\x34\x66\x09\xa5\xdc\xd3\x03\x1c\x8d\xea\x76\xa2\xd6\x42\x63\x26\x03\xee\x57\x01\x5c\x1e\xb0\xa6\x30\x0f\x69\xeb\x3e\xc2\x11\x14\x2f\xcf\x59\xae\xbd\x52\xac\x3b\xc6\xa3\x10\x25\x08\xb2\x7a\xdb\x54\x65\x71\xf8\x26\x7c\xdb\x94\xc6\x3c\x06\xa4\xec\x6e\xbe\x2d\xb6\xab\x70\x6f\xcb\xed\xbb\xf5\xe3\xaa\x1b\x90\x32\x44\xd2\xbf\x6e\x6f\xff\xbd\x78\x99\x4c\x40\x21\x6c\x16\xe3\xe4\xb4\xbe\xd2\x26\x1e\x7f\x50\x31\x8e\x05\x72\xa1\xf5\x12\x2d\xe4\x66\x91\xb2\x34\x56\x8a\x61\xa9\x2f\xab\x57\x78\x1f\x17\x85\xbe\xad\x32\xa4\x1c\x8d\x17\xb9\x58\x07\x32\x89\x46\x86\x98\xbf\x7d\xc9\x5b\xf1\x1f\x0b\x19\xae\x16\xa7\x37\x51\x43\x78\x7b\xae\x86\x39\x5e\xac\x43\x81\x1d\xd8\xff\x3d\x43\x75\xc1\x3d\xe3\xec\x29\xed\x7e\x84\x96\x98\x0b\xe5\x60\x9a\x24\x9c\xdc\x1e\xad\x55\xe8\xf8\xb6\x47\x74\x26\x38\x39\xe0\xd0\x27\xbf\x56\x03\x60\x59\x63\xab\x40\x34\xdd\x0c\x83\x20\xc4\xd8\x42\x9e\x2f\xde\x95\x6b\x34\x5b\x20\x10\xb8\x26\xfb\xd7\xcb\x5a\xc6\xfd\xf6\x05\x93\x8a\xc6\x40\x14\xf2\xd3\xac\xa6\x6e\x2d\x72\xa8\x61\x94\x53\xc7\x40\x53\xe9\xb4\x5c\xa7\x7a\x81\x34\x06\x16\x63\xfb\xc7\xeb\x49\xa2\x57\xd5\xf0\xc3\x22\x05\x57\xd7\xb8\x9a\x10\xed\x42\x31\x33\x81\x01\x58\xd2\x71\x93\xcf\x85\x5e\xf5\x73\xd4\xc4\x1c\x65\x45\xc0\x2b\xdd\x7e\xd5\x4a\x22\x23\x36\x28\x8d\x0d\xb5\x6d\x03\x44\x7c\xc9\xac\xd2\xfb\x36\x38\xf4\x89\x41\x12\xc4\xb1\xb0\x6d\x8f\x4c\x39\xe9\x05\xff\x6c\x13\x42\x05\xef\x84\x87\xeb\xb7\x89\x59\x0e\x4d\x88\x8c\x03\xe2\x15\xb4\xf1\xca\xee\xa1\x69\x06\x9f\x97\x89\x36\x43\x43\x96\xb1\xf3\xe8\xf8\xe1\x27\x61\x62\x79\xb7\x15\xd4\xb6\xd6\xd8\x01\x37\x29\xca\x96\xbb\xf2\x0c\xfa\x6a\x4d\x16\xc6\xe1\x74\x48\x22\x65\x52\x17\x98\x3c\xe7\x7a\xb5\x7d\xde\xf8\xb3\xc4\x81\x44\x58\xa0\xc0\x35\xa5\x5d\xf2\x36\xb9\x68\x4c\xe9\x41\x63\x34\x89\xb9\xf5\x35\x45\x0e\x37\x56\xcf\x07\x7c\x9d\xf1\x1c\x48\x92\xc4\x62\xa1\x85\xd6\x73\x80\x0a\x9a\x50\x6a\x02\xda\x59\x3e\x5b\x1e\xb7\xff\x22\xaa\x21\x74\x68\x01\x8f\xca\xb8\xb9\xac\x27\x25\xec\x84\x02\x60\x6f\xc9\x19\x47\x3e\x9b\xf9\xf7\x26\x61\xa9\x41\x4c\xbf\xa7\x16\xfa\x6f\x61\x52\x44\x74\x20\x4a\xa1\x5d\x1d\x73\xf3\x71\xed\x73\x3f\x5c\x15\x12\x9e\x28\x1d\x79\xa2\x64\x9b\x71\x7b\xeb\xc0\x11\x2b\x83\x26\x3c\xa5\x56\x57\xb6\x0d\x65\x6e\x7a\xf5\x0a\x77\x38\x0d\x18\xf2\x75\xd0\x30\xe9\x36\x7b\xef\x66\x4e\x1a\x53\x26\x07\xe5\xc9\x21\x80\x6d\x72\x29\x29\xe7\xcc\x72\x7e\x16\x36\x76\x7c\x9d\x71\x89\xf1\x63\x85\x55\xf9\xc2\x52\xd9\xaa\xd0\x35\xe9\xbe\x50\x19\x6c\xca\x9e\x2d\x52\xb6\x4f\x3f\xfd\x71\x9d\x22\x8a\x17\x63\x67\x12\x7a\x01\xed\xee\x79\x89\x24\xc2\x67\x99\x97\xa2\x98\x3c\x24\xc1\xa9\x69\x2f\xf0\xed\x2c\xbb\xd1\x26\xa6\x08\x93\x42\x7b\xde\x2b\xfd\x22\x37\x4a\x12\x49\x92\xfe\x9a\x7e\xcf\x9e\x7d\x98\x99\xc8\xd0\x36\x62\xbe\xaf\x6e\x36\xcf\xaf\x4f\xb7\xdd\xdf\x93\x20\xb1\xb6\xc9\xee\x49\x5a\x7a\xc8\xbc\xda\x3c\x4d\xa4\xc3\xa7\xb6\xeb\xdb\x58\x59\xb7\x3d\x66\xef\xd5\xb9\x86\x6a\x3a\xb5\x55\x08\xb8\x66\xbc\x89\x7a\x55\x94\xe7\xc3\xdb\x7c\x54\x9f\x28\x4e\x30\x80\x38\x9d\xa5\xe7\xb3\xfb\xd3\x2b\x25\x71\x29\xd7\x99\xde\x89\x1f\x60\xa9\x09\x9f\x68\xc9\xfb\x8f\x40\x18\x0d\x74\x2e\xed\x0f\x7c\x01\xa1\x3f\x7d\xde\x10\x05\x31\x9a\xcd\x2f\x76\xab\x7d\x44\xf6\xb7\xab\xe5\x3e\x0c\xc2\xee\xa9\x03\x0f\x46\x7e\xda\x77\x55\x79\xfc\x76\x39\x41\x55\x37\xa2\xdd\x42\x75\x56\xcb\x73\x55\x23\x50\x1b\x15\x0c\xe6\x2f\x0c\x34\xc4\xdc\xdb\x5c\x9d\x7a\x55\x80\x7f\xcc\x85\xb8\x89\xa1\xe0\xd7\x9f\x25\xe4\x79\xbd\xcd\x0a\x05\x0f\xc2\x43\xa0\xc6\xbf\xc0\x40\x6a\x6c\x68\x32\xf4\xb9\xf0\x25\x83\xaa\x7b\x5c\x34\x08\x52\xec\x66\x19\x24\x67\xe2\x3e\xda\x47\x38\x34\x60\x0c\x1c\x16\x7c\x57\x6e\xca\xc9\x76\x45\x83\x34\x46\x5c\x2d\xaa\x25\x58\xf6\xd4\xa0\xfe\x49\x03\x61\xc3\x2d\x7f\x9b\xda\x98\x7f\xda\x99\xa5\x81\xe9\x9c\xf9\xee\xcf\x50\x37\xf8\xca\x0e\x7f\x38\x25\xce\x64\xbc\x6e\xca\x0a\x9e\x4f\x56\xa9\x7c\xf6\x8e\xb6\xa1\x27\xee\x1c\xab\xdc\xa6\x37\x9f\x46\x4d\xe3\x6b\x88\x45\x00\xa2\x67\x67\x2d\x45\x9e\xff\x0e\xdd\x4d\x88\x25\xc1\x68\x03\x2a\x15\x86\xd1\xc2\x69\x0b\x76\x77\x30\x21\x3a\xf4\x9a\xa3\x68\x66\x7d\x99\x4d\xed\x69\xc2\x02\x54\x52\x2a\xe0\x67\x9b\x0a\x6f\x72\xd1\x7d\x03\x65\x49\xe0\x2b\x59\xdf\x20\x1f\x59\xa1\x5e\x6f\xe9\x94\x25\xd6\x84\x76\x63\x25\x8e\xf8\xb6\x83\xeb\x51\xca\x43\x9d\x74\xf2\xa1\xcd\xa0\xe2\x4e\x79\x62\x99\x96\xff\xaf\x94\x9f\xab\xe0\xb8\xb1\xa9\x50\xc2\xeb\xe0\x75\xa4\x5c\x07\x18\xfe\x87\xfb\x67\xfe\x09\x88\x98\x84\x41\x1f\xc1\xcc\x57\x7f\xa8\xa0\xdc\x67\xce\x48\x8a\x78\x98\xb2\x29\x29\x15\x8a\xa3\x58\xc9\xc3\xfd\xb2\x07\xa1\x52\x2a\x29\xd8\xdc\x14\xd4\xb9\x82\xd7\xc2\x29\x85\x8c\x60\xa8\x94\x4a\x41\xb1\xa6\xba\xbc\xf9\x57\xf7\x41\x19\x44\x7e\x4b\xd9\x81\x38\x76\x34\xc1\x6e\x80\x8a\xb0\x74\xbb\x40\x5b\xa8\x3b\x80\x5d\x39\x1f\x57\x4c\x7e\x8b\x54\x3e\x5a\x41\x10\x32\xe8\xd7\xed\xed\xf7\xd5\xda\x9f\x56\x87\x12\xc3\x0f\xab\xb8\x91\x83\xbe\xb9\x6c\x51\x82\x63\x72\xc9\xda\x58\x13\xcf\x5e\x82\xf3\x31\x2b\x9a\x4e\x29\xaf\x8d\x2a\x2a\x91\xb5\x7b\xd4\xa7\x75\x37\xaa\x8d\xc1\x94\xd7\x7a\xba\x2d\xbc\x51\xe7\xa7\x95\x8e\x6e\x46\x01\x27\x88\xd1\xef\x09\x07\xbf\xca\x19\xc7\x73\x1b\x38\x77\x92\xbc\xc7\x63\xd6\xa0\x14\xf3\x17\x49\x15\x35\xa1\x46\x05\x8f\x93\xa5\xe4\xdc\x9e\x27\x95\x15\x6a\x18\xb3\x41\x72\xbb\xb0\x2c\xdf\x4a\xcf\xbc\x73\x3f\x94\x05\x10\x78\x35\xb3\xa6\xd4\xdd\x8b\xc4\xc2\x38\x88\xc1\x93\xce\xab\xf7\x4c\xc1\xb0\x29\xc0\x42\x6a\xcd\xb4\x7a\xfe\xc6\x0f\x28\x6a\x2b\x57\x37\xbf\xa2\xb0\x28\x88\x11\xc6\x54\x9f\xf2\x09\xd5\xfd\x4a\x26\xf3\x3f\xd7\x9d\xa1\xbf\xfc\x59\x22\x2b\xe0\x24\xb4\xb6\x0a\x97\x9f\x7c\x19\x97\xf1\xdf\xd3\x88\xfe\x3f\xa6\xf6\xee\xfc\x31\xb5\x55\x0b\xd7\x39\xb4\xe8\xb4\x9e\x14\x45\x59\xcc\x39\x2a\xdb\x56\xe5\x39\x6f\x43\xee\xf1\x3b\xc9\x12\x62\x79\x4e\xe7\x53\x5e\x0a\xbd\x2c\x35\xfc\x76\xdd\xe3\x66\x09\x4d\x91\x24\x87\x90\x8a\xa5\x15\x36\x1b\x23\xb5\x46\x33\x9f\x25\x54\x84\x0e\xcf\x5d\x7b\x40\xf7\x27\x0b\x13\xa3\x41\x9c\x3a\x1e\x76\xfb\x46\xdc\x01\xcc\x2e\xb6\x8c\x06\x89\x72\x8b\xb2\x57\x40\xbb\x2b\xab\x45\x7e\x65\xc1\x34\xe8\x67\x31\x1a\x58\x11\x85\x6f\xaf\x0f\xbf\x0f\x97\x4e\x46\x59\x88\x55\x59\xaf\x35\xd5\x19\x8d\x7f\xf2\x1c\xa9\x8c\xe2\xbe\x83\xb5\xd0\xbd\x97\xe0\x64\x20\x93\x09\x7a\x75\x3d\x58\x05\x0a\x47\x28\x9c\x7d\xc7\x18\x53\x56\x97\xbc\xb3\xbd\x6e\xa3\x72\xd7\x9d\x9c\xee\xaa\x8c\xa7\x51\x64\xa3\xdb\xd5\xa9\x54\x6f\xed\x86\xb2\x85\xee\x31\x73\x43\x98\xe5\x36\x97\xb5\xc8\xaa\xed\x5b\x76\xc2\xaf\xf6\xbb\x08\x13\x81\x49\x99\xa7\x53\x9f\xce\x8d\x67\x96\xcb\x1c\x8e\xf5\x6f\x73\xe9\x11\x13\x9a\x82\xe5\x5e\x69\x80\xe3\x46\x4c\x17\x74\x26\x8c\xc0\x4a\xca\xbe\x98\xd5\x3b\xa0\x4c\x8a\x04\x71\x91\xd6\x43\xca\x46\x76\xe7\x09\x3f\x6e\x6c\x65\x4d\xe8\xdf\xfd\x67\xf0\x2d\x52\x5b\x67\xbf\xa6\xca\x61\x64\xf1\x48\x99\x54\x1c\xd3\x13\xdc\x3c\x8f\xe7\x06\xae\x55\x20\x3e\xab\xbc\xcf\xd4\x40\x99\x34\x21\x8a\x36\xb9\x8e\x0c\xee\x74\xdf\x20\x3b\xbc\x75\x0f\x42\x25\x0c\x71\x2b\xb7\xeb\xcd\x1e\x45\x3d\xfd\xdf\x85\x46\x00\xb2\xc8\xd1\xda\xa0\xc9\xde\x61\xef\xfd\x46\xea\x7d\x9e\x15\x3f\x7c\xca\xc3\x40\x4a\x0c\xe0\x34\x88\x06\x9f\xf3\x5e\x90\xb0\x3b\xa8\x35\xf2\x93\x2d\xe7\x7b\x52\x62\x63\x26\xb0\xb5\xf9\x4c\x95\x04\xb1\xe5\xdd\x81\xd0\xfa\x2d\xba\x72\xf1\x8d\xa8\xe1\x56\x1c\xc5\x01\x7a\xdd\xa9\xfe\x86\x9a\x28\xc6\x4e\xfe\x09\xaa\x36\xe5\x5d\x3c\xbc\xba\xd3\xf0\x20\x49\x29\xf1\x92\x9e\x73\x24\x0d\xca\x09\xa7\x18\xce\xdf\x66\x87\x4c\x42\x35\x82\x58\xf2\x30\xb5\xfe\x33\x2f\xeb\xe5\xf3\xb6\x11\x85\x16\x95\xde\x94\xb7\xfd\xe1\x18\xfb\x73\xed\x0a\x60\x97\x32\x6f\x8a\x4e\x79\x24\x63\x94\x4b\xc2\x0d\x64\xd3\xbe\x2d\x2e\xcb\xf3\x0e\x7e\x5f\xf7\x8d\x78\x04\x16\xbd\xba\x14\xef\xf5\x7b\xbd\x11\x0a\xaa\x3a\x0e\x93\xee\xf4\x60\x30\x96\x3b\x55\x80\x8a\x2e\xb3\x7a\xb0\x6e\x6c\x1c\xc4\xb8\xbc\x2d\xb4\x5e\xe8\xea\x9f\xe7\x3c\x17\x15\xea\x61\xcf\xbe\xe6\x3c\x0e\x09\x96\x80\x3f\x44\xdd\x6d\x03\xdb\xa6\xec\x51\x62\x3c\x21\x29\x16\x2d\x3a\xad\x8a\x79\x5b\x76\xca\x69\x12\x61\xfc\x7d\x73\xb6\x9a\x91\x13\x22\xcb\xfc\xf7\x53\x25\xb0\x32\x28\xa1\x00\x93\xa9\x4c\x54\x97\xa9\xa2\x0d\xe5\x54\x27\x18\xf3\x9e\x4e\x75\x3b\x39\xba\x3f\x83\x46\xea\xdb\xbe\xcd\xef\x8f\xea\x56\x5c\x9c\x76\xdc\x5d\x69\xe9\x5b\x5f\x19\xc2\x51\xce\xc0\x0a\xe6\xef\xa0\x10\x45\xb3\x83\xea\x98\x15\xbd\xfb\x5e\x37\x28\x0d\x49\x67\xd6\x6a\xae\x6a\xd2\x7e\x98\x09\x63\xb7\x01\x78\x31\x19\x12\xba\xf0\x81\xf3\x40\x72\x87\xad\x2d\x2b\xeb\x5b\xfa\x6c\xc6\xf1\x18\xe7\x84\x23\x74\xce\x36\xa1\x1e\x41\x67\xa2\x0b\xc4\xae\x03\xaa\x7e\x17\xe1\x9c\x46\xa1\xb3\x3e\x5c\xbc\xa3\xc4\x46\x7d\x2d\x0e\x4b\x39\x57\xa1\x0f\x61\xf0\xbc\xb8\x22\x3e\x64\x75\x73\x73\x59\x5f\x89\x04\x50\xce\x8d\x08\x3b\x15\xc9\xd1\x6f\x76\x14\x3e\xca\x53\x61\x7d\x0e\x5d\x54\x85\xb2\xd1\xa3\xda\xc7\x27\x4f\x5c\x24\xd6\xc8\x60\x7b\x82\xea\xf8\xe0\xe9\xb6\xed\xdf\x01\x75\x6f\x17\xeb\x97\xdb\x97\xe7\xcd\x66\xf5\xd2\x1d\x11\x29\xee\xae\xa7\xbd\xed\xcb\xee\xb1\xca\x67\xf5\x0d\x67\x68\xd8\x94\x0b\x63\xd9\x87\x9d\x4e\xd2\xa6\x2c\xfe\x9b\xf9\xd3\xc9\x80\xa2\xd0\x8d\x35\x40\x59\xd5\xaa\x2a\x3f\x96\x68\xa0\x39\xbe\x50\x19\x72\xdc\x56\x6b\x61\x2c\x60\xe3\x33\x8d\x9e\x11\xfb\x64\xf8\x2e\xca\x48\x61\x2b\x6e\xb3\xdb\xfd\xb9\xfc\xaa\x7f\xc5\x25\x67\x5e\x3c\xed\x11\xea\x5a\x1c\x26\xd3\x50\x1a\x86\x91\xe6\x6e\xb5\x78\xdc\x3f\xac\x1f\xd7\x3b\xff\x6b\x74\x90\x6a\xde\x6b\x94\x5a\x35\x1d\xbb\x70\xfa\x11\xb4\x03\xf4\xbd\x9c\x6b\xec\xd5\x74\x49\x96\xf3\xd0\x99\xf3\x77\xa5\x5c\x0b\x63\xa9\xb2\x65\xae\x3b\xfc\xfb\x08\x18\xce\xb5\x06\xec\xda\xb8\x3d\x07\x99\x24\xee\x10\x24\x1a\x2f\xf9\x66\xb7\xdc\x6f\x5f\xd7\xdb\xed\x6a\xbf\x5b\xaf\x5e\x3a\x30\x2e\x07\x9e\x20\x5e\x68\xbd\x5e\x3e\xff\xb2\x79\x34\x9b\x49\x73\x13\xc5\x48\xda\x5f\x14\x70\x2c\xb3\x91\xeb\xa7\x1f\xc1\x28\xea\xaa\xc8\xb2\xae\x97\xe7\x66\x4a\xa6\xa7\x69\x90\x6a\x6d\x4b\x17\x8b\xdd\xa3\x13\xc1\x1b\x7d\x49\x1a\x18\xeb\x49\xb7\xdc\x3c\x78\x0c\x9c\x3b\x42\x48\x98\x08\x04\xd0\x8a\x62\x23\xb2\xe1\x6e\x92\x12\xa6\x8d\xf0\x3c\xe3\x89\xb4\x10\x4d\x89\xb6\x44\xd5\x73\x0d\xd5\xc2\xe5\x94\x5f\x6e\x11\x69\xa8\x3b\xa5\xcd\x09\x06\xd0\x0d\x88\xa2\x94\x0e\xaa\x0a\x58\xfd\x18\xb6\x02\xd2\x88\x59\x98\x7b\x9f\xf2\xed\xbd\x51\x50\x37\x84\x73\xa4\xe8\xac\x1e\xd7\xdb\xed\xfa\xf9\x69\x7f\xf7\xfc\xb2\xbf\x79\x7e\x7d\xda\xfd\xd9\x0d\xd1\x12\x99\xb4\xce\x9b\x7d\xff\xfc\xe4\x7b\x4c\x69\x1c\xdb\x06\x61\x6d\x05\xb8\x90\x10\x67\x65\xb8\x44\x03\x4f\xe7\x23\x54\xa2\xdf\x33\xd3\x38\x89\x42\xde\xf7\xc8\xfd\x83\x5b\x8a\xa1\x70\x7e\x37\x96\x52\xf0\xac\xb4\xe6\x93\x1a\x6b\x3b\x0a\x93\xf5\xf5\x37\xd1\xc0\xaa\xac\x47\xaf\x50\x1a\xd3\xd0\x23\xf7\x11\x8b\x9a\x95\x85\x03\x8e\x63\xad\x79\x7c\xb7\x93\x24\xc0\xca\xee\xfa\x65\xb9\xdf\xac\x5e\xf6\xab\xdd\xb7\xfd\xe6\x65\xb5\xdf\x2e\x1e\xba\x9f\x9b\x50\x16\x4a\xeb\xe8\xe3\x2b\xd6\xcf\x27\x28\xbc\xf0\xc3\x1c\x92\x6d\xb6\xd4\x96\x26\xdc\xe6\x49\x1f\x20\x4e\x65\x81\x48\x91\x6c\x62\x79\x49\x53\x9a\x00\x8a\x0d\x6c\xa1\x59\xac\x72\x73\x0b\xef\xa8\x9c\x56\x67\x9f\xc0\x4d\x53\xa6\x03\x61\x25\xb2\x0b\x6d\x25\x10\xb2\xe2\x80\x3e\xa9\x7e\x00\x58\xcc\xda\x63\x56\x40\xb5\xd2\x07\xe8\x5a\x99\xdd\x08\x63\xeb\xb4\xbe\x27\xeb\x51\xfe\xe3\x2b\xe3\x5c\x62\xa5\xc7\xad\x01\x0f\xa5\x28\x36\x28\xbe\xeb\x4f\xc3\x35\xe0\x94\xa9\xcb\x3c\xd3\x59\xd3\x46\x07\xd1\x78\xfb\x4b\x85\x0a\x71\xa9\xd1\x90\x37\x62\x38\x69\x25\x51\x90\xf4\x93\xf6\xe6\x7c\x99\x22\x42\x53\x29\xb4\x71\x4d\x08\xdb\x84\xac\x17\x8d\x15\x1e\x1b\x5f\xa7\x54\x1a\x41\x19\x7b\x1b\xa5\x65\x3f\x21\x47\x1c\xf5\x64\x98\x92\xd2\x99\x70\x80\xfa\xf1\x68\x41\x28\x16\x02\x3d\xbe\xbf\x4a\xc7\xb4\x97\xb7\xcd\x72\x03\x7d\x9d\x33\xd5\x51\x88\xd7\xb4\x6e\xda\x0c\xc6\xff\x91\x5b\x34\xb3\xcb\xd3\xea\x1a\x9a\xdf\x66\xd9\xb6\xe3\x0b\xd2\x10\x20\x07\x6f\x73\xbb\xf3\xe5\xa5\x14\xc2\x18\x91\x40\x03\x26\x3e\xee\xe8\x1b\xa8\x5e\xb7\xb7\x93\x5f\x04\x5c\x61\xad\xc7\x96\x4b\x26\x3f\xc3\xa4\x21\xd2\xde\xdb\x1b\x8c\x29\x03\x66\x70\xfe\x7b\x0c\xa4\xd4\xe3\x1a\xb3\xfa\x74\x6e\xe0\x11\x8e\x65\x75\xd9\x66\xff\x9d\xbc\x32\x22\x20\x11\x2a\xa1\x3f\x94\x87\x41\xa6\xff\x65\x31\x4b\x04\x29\x08\xb0\x93\x1a\x2f\xdf\x79\x3b\x5e\x9d\xda\x24\x84\x0c\xc5\xc2\xbc\xd2\xe3\x78\x18\x09\x39\xf6\x99\x1e\x2f\xff\xcc\xca\x41\x15\x4f\x10\x29\xb1\x3c\x2d\xdb\x64\x1a\x5b\x78\x63\x38\x8b\x20\x8a\x60\xe8\xba\xae\x17\x1d\x92\x51\x10\x23\x93\x1e\xe5\xdf\x06\x94\x13\x3b\x8b\x3e\x0a\x13\x61\xa4\x51\x7a\xd9\x38\xf5\xa6\xdf\x86\xc7\xa8\x4d\x99\x56\x4f\xb7\xd8\x92\x6f\x17\x92\xc1\x3a\x22\x42\x6a\x10\xab\x88\x4f\xf1\x16\xc4\xa4\xe2\x2b\x42\x13\x98\x1e\xd8\xe5\xd4\x4e\xdc\xb1\x88\x58\x69\x1a\xfc\x49\x36\x00\x18\x09\x56\x8d\x6f\x50\x14\x19\xbc\x92\xac\xc6\x09\x8d\x06\xa9\xfe\x10\xa5\xd8\x24\x6d\x40\x58\xdd\xad\x36\x26\x70\x84\x94\x6e\x88\xc1\x16\x96\x84\x06\x7e\x8e\x3b\x9b\x22\x4a\x39\x86\xb8\x7b\xe4\x9d\x81\xde\x0e\xb6\x58\x11\x87\x14\xb1\x07\xaa\x3c\xca\xac\x00\xcc\x1f\x3c\x4f\x71\xe8\x26\x4b\x45\x6c\x42\xd9\xcb\x14\xdd\x34\x9d\xef\x97\xff\x3d\x93\x68\x60\xf4\xeb\x68\xc0\x53\xd2\x49\xc3\x60\xb1\xf5\x0e\xe0\x13\xbb\x50\x2a\x68\x4c\x70\xf9\x96\xe7\xcb\x63\xa6\xaa\xf2\x77\xb8\xd4\xa8\x0d\x8f\xdc\xe6\xd9\x3d\x56\x50\xa1\xb1\xb1\x8a\x78\x78\x51\x35\x43\x14\xbf\x7f\xcd\x05\x23\x54\xf7\x3f\x02\x0b\x0b\xb8\xec\x4e\xab\xa1\x03\x65\xab\xe4\xaf\xf1\x4f\x61\xca\x90\xce\x10\x2f\xcf\xcb\x66\xce\x34\x98\x8a\xd4\x84\x88\xa9\xff\x69\x3d\x6e\xee\xe0\x6a\x97\x15\x22\x65\x98\x1e\xdc\x9d\xf3\x7c\x23\x2e\x43\xb8\x97\x90\x81\x21\x6e\xf2\x3c\xc1\x47\x5f\xbf\x5d\x19\x03\xaa\x39\x0f\x21\x14\x42\x32\x4b\xd6\x42\xd2\x97\xdd\xda\xfb\x62\xb6\x90\xc6\xa0\x2a\xcf\xde\xd1\x07\x6d\xd6\xe2\x0e\x2a\x66\x33\x14\xbb\x56\x59\x75\xce\x65\x6f\x27\x3e\x79\x2c\x9a\x02\xc2\xb6\xb6\xde\x99\xb1\xde\x95\x77\x6d\x10\x31\xe8\xef\xcd\x87\x48\x42\x6b\xa2\xed\x52\x66\x27\xd8\xb5\xe7\x3a\x15\x10\x86\xa8\xe9\x08\xc7\xcc\xa9\xb1\x65\xa5\x7e\x29\xf3\xbc\x7c\xbf\x9a\x21\x10\x11\xf0\x52\xf6\xc2\x71\x36\xba\xf3\x24\x41\x6c\x85\xfc\x46\xa5\x2c\x01\x2a\x11\x51\xd7\x9c\xef\xd0\xb6\x53\x28\xa7\x30\x24\x45\x3e\xa7\xdf\x5a\x8b\x17\x10\x7a\xd0\xf4\x16\x26\x09\x70\xcd\x72\xd2\x20\xd3\x8f\x73\x92\xf8\x5a\xc7\x49\x54\xf0\x02\xed\xe2\x3e\xb4\x07\xb0\x03\x65\x10\x5a\x03\xda\x81\x5e\x52\xfb\x2d\x1d\xc6\xc7\xa7\x73\x32\x48\x63\x66\x2f\x08\x55\x56\x2c\xdd\xae\xde\x64\x83\xd5\x46\x92\x88\x24\xca\x4e\x7f\x1a\x8f\xfb\x33\x7e\x44\xaa\x74\x67\x2b\x3a\x14\x1c\xa1\x32\x0c\x43\x94\x1d\x44\xfc\x34\xb6\xd5\xfe\x86\xd0\xdb\x7f\xc2\xbf\x06\xf8\xe9\x0e\x35\x1a\xfe\xe5\x4f\x0a\x01\xd6\xbc\xac\x65\xd5\x4d\xa6\xef\xca\xca\x09\x7f\x67\xf2\x57\xe0\x68\x89\xf8\x79\x27\x3b\xe6\x88\xb2\xd7\x6a\xb7\x54\x46\x61\x6c\xac\xba\xf7\xe3\x94\xae\x26\xa3\x28\x26\x16\xad\xaa\x33\x73\x79\x44\x78\x10\xd6\x09\x7e\x25\xa3\x41\x65\xa4\x05\x96\x79\x2d\x22\xd9\x63\x3e\xdd\xc1\x38\x90\x28\x3e\x95\x83\x69\x9e\x8b\x36\xa0\x1f\xac\xd6\x92\x12\xc0\x7a\x6b\xd9\xa8\xee\x4f\x31\xb1\x9b\x9f\xf8\x01\x8f\x97\x2f\xc4\x98\xfd\xf8\x34\xc2\x92\x53\x3b\x7b\x10\x28\x3b\xa9\x69\x4b\xc6\x08\x92\x9a\x72\x51\x37\x63\x4c\x9d\xe4\xc4\x20\x6e\xe8\x16\xa6\xf3\x5a\xa6\xcc\xe8\xc4\xc1\x58\xf1\x22\x92\x5f\xa9\x1f\xfd\x2d\xeb\x12\x2a\x53\x6e\xa9\x64\x05\x7c\x78\xe5\x1e\x8c\x1a\xca\x72\x4c\x34\x92\x42\x59\xa8\xf7\x01\x9a\x5d\x9b\xea\x35\xd9\x3b\x38\xe9\x20\xab\x97\x38\x5c\x16\x06\xf1\xb0\x94\xa9\xc1\x8c\xed\x71\xf1\xf4\x6d\xb1\xdb\x2d\x9e\x36\x2f\xcf\xff\xfa\x73\xb3\x78\xf9\x7d\xf1\x87\xdf\xac\xa5\x8a\x2c\xd9\x13\x9c\x1c\xed\x8c\x04\x23\x95\x4a\xc6\xc8\x77\xb0\x3b\xf6\xe2\x30\xea\x26\xe1\x51\x8d\xac\xf2\x66\xe8\x46\x4a\xa5\x06\x2b\x80\x81\x11\x65\xa7\xbe\x4b\x25\x84\x82\x39\xa5\x94\x07\xd0\x87\xae\x4e\x3d\x7a\x9e\x00\x84\x39\xbf\xd5\x7d\x53\x76\x6c\xa6\xbd\x6c\xd7\x21\x1f\xd1\x4b\x13\xa4\x98\xaf\x0f\xf8\xa6\xa3\x84\x5e\x9a\x10\x70\x3e\xa3\x8d\xc9\xfa\x78\xca\x9d\x28\x1b\x2e\x4d\xe3\x5f\x69\xa2\x14\x37\xd0\x5e\x1c\xdd\x97\x45\xeb\x81\xa0\xf2\x64\xda\x19\x03\xc4\xb7\xa5\xdb\x7c\xa3\x2c\x76\xbb\x47\xe7\xc6\xc9\xdc\x45\xa8\x40\x08\xed\xaa\x69\x58\xc9\x58\x4c\xf9\x1d\x2a\x50\x1c\x8b\x45\xf2\x7c\xe9\xa1\xbd\xce\x5e\xc0\x0d\x21\x22\x71\x8a\x76\xcd\xbf\xa1\x2a\x9f\xca\x66\x8b\x99\xd0\xf8\x57\xa8\x90\x5b\x90\xcb\x46\x14\xe0\xf3\x60\x15\x8a\x14\xc3\xeb\xdf\x51\x44\xea\x34\xaa\x13\xab\x50\x33\x0f\x07\xb4\xd8\xe7\x5c\xbc\x4f\xdf\x1e\x15\x25\x26\x8d\x07\xf6\x49\x1e\xcc\xa1\x62\x91\x60\xc7\xfa\x8f\x32\xef\xaa\xea\x2a\x16\x3a\x70\x73\x76\xd5\xbc\xdd\x55\xe5\xb1\x8d\x46\xe6\x6f\xa1\x8a\xb5\x0c\x9c\x58\xe2\xf2\xf9\xf9\xb7\x99\x22\xb0\x8a\x8d\xc1\xe6\xc7\x09\x67\x27\x6e\x0b\xee\x48\xc2\x38\x03\xef\xe1\xd7\xee\xae\xdf\xc5\xfb\xd5\xb3\xfa\x0f\x09\xfe\xf2\xe3\xa5\x41\xec\xd3\x1e\x81\xb1\x4e\xfb\x70\x28\x75\xa1\x12\xcd\x50\x05\xca\xe2\x5d\xae\x35\x88\xa8\x4a\x8c\x95\x8c\x47\x58\xc7\xc0\x93\xef\x36\xab\x9d\x72\xfb\xc3\x15\xac\x48\x51\x22\x31\xbd\xda\x7b\x3d\x80\xaf\xd7\x72\x45\x23\x89\x20\x99\x85\xac\xb1\x8e\xf0\x47\x56\x35\x67\x91\x8f\x9e\x1c\x15\x31\x16\xbb\x6f\x44\x23\x8a\x41\x82\xa0\x98\x8e\xd1\x09\xcf\xa9\x26\xbc\x40\x36\x52\xd2\xf8\xe4\x2b\x79\x10\x62\x9b\x15\xcb\x91\x18\xf1\xfa\x4e\x88\xe2\x71\x17\x97\x5b\x15\xbc\x5b\xd1\x88\x9b\x79\xa8\x86\xe2\xc2\xde\x9f\xfd\x01\x9a\xb5\xee\x4e\xa1\x02\xd4\x7e\x11\x5a\xe3\xdb\x7a\xd3\xc1\xb7\x6d\xa1\x71\x92\x06\x2b\xae\x12\x04\xcf\xbc\x97\x0d\xb4\xbb\xe0\xac\xe4\x3d\x55\x1c\x38\x0a\x5f\x6c\xde\xb2\x3c\xf7\x66\x3e\xfe\x3b\xd3\x50\x45\x2e\xee\xc4\xc2\x4d\x07\xa4\x1d\x9f\x23\x55\x34\x1c\x02\x92\xf6\xe5\xe9\x17\x99\x9e\x12\xa9\x75\x0b\xc6\x46\x67\xcf\x82\xf4\x5f\x2c\x63\x85\xd8\xa4\xbc\x3c\x84\x09\x9d\x7c\x9d\xe4\x01\x0a\xda\xdf\x94\xe7\xb1\x4a\xd6\xa7\x08\x01\x25\x39\xb3\xc4\x5d\xa8\x9b\x7d\xb4\x17\xca\x3e\xd6\x76\xa1\xc2\xa9\xb7\x6f\xef\xd2\xde\xea\x41\x58\xe9\x2f\xff\x41\x00\x6c\x9f\xd8\x65\x73\x18\xc7\x2a\x45\x98\xb0\x5e\xb1\x19\x14\x8d\xd5\x27\x1a\x4e\x0c\x1f\x04\x29\x45\xac\x6a\x90\x17\xbf\x5e\xeb\xf7\x69\xcb\xa6\x1b\x09\xd2\xeb\x7c\x2f\xbf\x59\xd6\x00\x89\x46\xfb\x99\x52\x54\xe0\xa4\xb5\x11\xc6\xce\xdd\x3f\x7f\x51\x3a\x8c\x85\x95\xee\x83\x76\x27\xff\x63\x28\xf5\x37\xbe\x8b\x90\xc6\x98\xa2\xe2\xd1\x4e\x4a\x92\x0c\x21\x54\xca\x30\x85\xb2\x42\xba\x73\x5c\xa7\xca\x40\x84\x9b\x7d\x1b\xf9\xb7\x09\xf4\x4a\x54\xf9\xa5\xd3\x15\xb1\x83\x74\x10\x72\x5c\x26\x96\x0f\xfd\x5f\x54\xda\x7b\x99\x6e\x2d\x33\xfa\x93\x25\x4d\x07\x51\x94\x50\x5f\x0b\xb4\x0e\x15\x3b\x10\xc7\xd9\xd7\x45\x93\x00\x90\xe9\xf9\x00\xc7\xb2\xa8\x3b\x60\xcd\xae\xbc\xad\xca\x93\xff\x7a\x92\x44\x1e\x87\xbc\xea\x4d\x11\xdb\xbf\x1b\x6c\x25\xed\x9d\xdd\x1a\x5e\x59\x0e\xdd\x26\x52\x8f\x21\xa5\xd7\xff\xf5\xe7\xe1\x12\xc3\xa7\x97\xd5\x6d\x77\x6a\x93\xe0\xde\xfa\x5a\x64\x0d\x68\x23\x0a\x6b\x88\x7e\x85\xae\x70\xc3\xc3\x50\x23\xb8\xfa\x54\xfe\x80\x4a\x96\x3f\x3f\xb9\x35\x51\x10\x48\xef\x7a\xf2\x25\xc8\xcc\x8f\x67\x11\x32\x55\x3f\xaa\xac\x81\x5b\x30\x58\x38\x2b\x0b\xaf\x03\x3b\x9c\x5a\x3a\xe2\x4e\x4c\x55\xf9\x49\xae\xe3\x48\x85\xc3\xbc\xa4\x5b\x8f\x74\x12\x24\xca\xca\x1a\x56\x00\xe8\xa2\xf6\x8b\x2b\xa1\x84\x10\x57\x3b\xfa\x03\x30\x5d\xdc\x36\x70\xfa\x9f\x29\x0b\x4e\xd3\xd8\xaa\x4a\x22\xdc\x15\xbd\xfe\xdc\x01\xee\xd4\xdc\x9d\x36\x83\xdf\x42\x75\x1a\x58\x3c\xfe\xad\x5d\xc1\x3e\xca\x2a\xd7\x03\x71\x2c\x9d\x46\x0c\xf7\xb8\x7b\x04\x25\x0d\x34\x57\x74\x1a\x71\x6c\x96\x0c\x8d\x61\x7f\x81\x65\x99\x80\x6f\x46\x95\x67\x7f\xd6\xc4\xe0\xec\x7d\x5c\x3f\xed\xef\x5e\x2d\xe3\xea\xfe\x79\xd1\xbd\x0a\x82\xc4\xcc\x4a\x20\x96\x1f\xc8\xb2\x41\x39\xb1\xee\x68\x6c\xc5\x3a\xea\xf3\xc9\x96\x29\xfc\xdf\x13\xcb\x6a\x14\x4d\x79\x1c\x2e\xd2\x5a\xa4\x80\xd1\x65\xd5\xae\xd0\xbb\x8f\x72\x80\x57\xd5\x42\x85\x4a\x79\x01\x80\x46\x4c\xee\xb4\x22\x5a\xf7\x40\x91\x9b\xed\x23\x86\xbf\xa3\x29\xa1\x12\x6e\xa8\x8f\x41\xf7\xdb\xdb\xe5\x72\x5f\x0f\xb9\x5d\x5a\x87\x81\x77\x99\xfc\x67\x29\xbf\x97\xd5\x8f\x69\xde\xac\x75\xc2\x11\x66\xa2\xb3\xfa\x84\x9b\xd6\xf4\x96\x8e\xbe\x11\xe2\x18\x91\x77\xf7\x77\x9f\xb4\xc8\xdc\x13\x18\xbf\x3d\x26\x48\x90\x7e\xfa\xf1\x56\xe6\xe8\x70\xf0\x00\xc6\xef\x26\xda\xa4\x29\x26\x4f\x32\x17\xea\x47\xfd\x21\x46\x9b\x9c\x36\x10\x52\xcb\xe5\xbe\x3c\x17\xe8\x0d\x32\xe2\xb1\x43\x10\x04\x71\xc7\x82\xde\x66\x87\xee\xef\x89\xb6\x21\xdd\xb9\xd0\xa2\xca\x84\x6d\x72\xfb\x83\x60\x7d\xb6\x45\x3d\x24\x4b\x0c\x66\x09\x04\x86\xe2\xa3\xc1\x90\x07\x29\xcb\xee\x40\x0c\x1c\x33\xfd\xe6\x9c\x67\xa7\x5d\x39\x2a\xe0\xf9\x21\x26\xc5\xa8\x1c\x95\x06\x77\xbd\xba\x4a\xcf\xa5\x1d\xdd\x1d\x48\xc2\x00\xef\x8e\x95\xd2\xfb\x54\x4c\x01\x28\x51\x86\x39\x55\x6a\x71\x9a\x7c\x29\xe5\x89\x71\xdb\xd8\xf2\x01\xde\x21\xff\x25\x95\x71\x72\x15\x54\x5a\x15\x94\x46\xd4\x3f\x36\x36\xb2\xb2\x0b\xc7\xb2\xac\x9b\xcf\xcc\x7e\x29\xb0\x28\x25\xdc\xd7\x34\x0f\x59\x59\x3c\xc1\xcf\x06\xd5\xe7\xa6\xcc\x02\x48\x4d\x8c\xf1\xca\xf6\xf1\x65\x98\xd5\x59\x0d\x50\x37\x46\x30\x8a\xfc\x7e\x44\x4c\xf7\x95\x20\x10\xdc\xaa\xee\xdd\xa2\x57\x71\xed\xed\xf2\xe6\x7c\x71\xfa\x2f\x14\x9c\x05\xa1\x63\xf2\xb5\x2f\x98\xa3\x68\x0f\x7b\x3c\x6e\xa4\x8c\x04\x36\x1e\x1f\xee\x6f\x7c\xaf\x16\x64\x22\xe3\x0e\xe7\x54\x97\xdb\xa5\xe3\x43\xfa\xc3\xca\x5a\x37\xee\xf7\xde\x15\x7e\xec\xb4\xe8\x86\x69\x11\x76\x41\xda\x76\x37\x3d\x28\x81\xf4\xbc\x6b\x1b\x7b\xce\x63\x16\x00\x88\xc1\xfc\x6d\x7b\x3b\xd2\xca\x00\x88\x29\x3e\xf7\x1f\x59\x9e\x5b\x93\xb4\x41\xa5\x96\x74\x9f\x66\xb6\x8d\x7f\xf0\x25\xca\x7a\x5c\x12\x06\xe0\x91\x71\x5c\x68\x2c\xf4\x38\x1f\x90\x66\x4a\x58\x05\xe0\x9c\x84\x53\x79\x75\x3d\xae\x87\x00\x38\x63\x58\x7f\x67\x74\xfc\x27\x08\xbf\x56\x82\x09\x14\xf4\x25\xd7\xad\x13\xa6\x72\x36\x64\x7e\x0c\x11\xd2\xa5\xab\x88\x96\x9f\x4a\x29\x81\xa1\x56\x26\x48\x68\xbd\x3a\x4a\x51\xd7\x97\x67\x83\xb9\x71\x35\xef\xb1\x47\xc1\xf0\x40\x3b\xf1\xa0\xf5\x27\xe4\x05\x13\x04\xc0\x7b\x64\xc8\x5d\x2e\x26\x5d\x76\x43\x52\xc9\xdc\xa4\xf0\x51\x95\xc6\xc2\xe8\x5b\xbb\x38\x8f\xc7\x86\x91\x35\x0d\x1b\x70\xbc\x67\x05\x98\xa9\x09\xa9\xd5\x9b\x3f\x5a\x5f\xeb\x4e\xd5\x94\x9a\x50\x72\x6c\x67\x3f\x2b\x10\x45\xcd\x5f\xfc\xec\x34\x91\xa3\xb9\x59\x77\xef\xbb\xe7\x57\x6c\x7b\x5a\x15\x50\x3f\x26\x89\x19\x86\x3d\x7f\x64\x8d\x38\x66\xc5\x2f\x89\xb9\x86\x26\xd4\xee\x62\x75\x0d\x55\xb3\xfa\xdf\xd9\xba\x98\x1f\x4b\x13\xec\x08\x5b\x66\x29\xe4\xd7\x34\xec\xf1\xfd\x37\x8c\x6b\xbc\x75\x05\x7c\x8c\x7c\x97\xff\xf3\xd7\x67\x1f\x48\x6d\xc9\xe2\x74\x6e\x9e\x8b\x39\xf5\x04\x3f\x4e\xc8\xc4\x8b\x55\x09\xd5\xac\x0b\x53\x7a\x50\xa9\x1f\xa1\x34\x0b\x06\x31\xfe\x06\xbb\x43\x3f\x26\xd9\x96\xe1\xd0\x99\xd7\xdb\x77\x71\xfb\x96\x9d\xac\x20\xf6\x43\xd9\x2e\xa5\x1d\x5d\xca\x67\x0f\x26\x8d\x44\x6a\x75\x20\x8c\x2b\x7b\x5b\x72\xb5\xd3\xa5\xc3\xc9\x7d\xdb\x6f\xf9\x26\xe5\x21\xb6\xa9\x9c\xf2\xe1\x4c\xe7\xd3\xa4\x26\x46\xa0\x36\x0a\x5f\xa3\xc8\xe8\x16\xfa\x67\x2a\x44\x62\xeb\x09\xf5\xa9\x1e\x5f\x8a\x04\x8d\x00\x45\xf8\x99\xd5\x4d\xbd\x38\xeb\xac\x29\x91\x7d\x82\x4d\x15\xd7\x70\xb2\x00\xf6\xe3\x8c\xd5\xb1\x3b\x8b\x62\x36\x31\x45\xde\xc9\xa1\xce\x9a\x4a\xcc\x4a\x5c\x53\x63\x22\x86\x3c\x69\xbb\x16\x0f\xb4\x76\xa9\x31\x22\x0d\x5c\x42\xfd\x78\xf1\x5c\x33\xf7\xea\xb2\x20\x20\xb1\x09\x9d\x4c\x78\x9b\xb3\x7d\x2b\x7d\x07\x99\x05\x41\x6a\x5d\x5a\x74\x59\x94\xcd\xeb\xf6\xe6\x56\x9c\x4e\x83\xf5\xae\x1d\x90\x62\x14\x2c\xb2\x6a\xfb\xe1\xdf\x13\x16\x90\xc4\xea\x0d\x66\x85\x29\xbb\xbf\x51\x91\x38\x52\x8c\x13\xf5\x72\x52\x82\x8b\xf1\x5b\xcd\x02\x62\x6c\x09\x6b\x73\xb7\xf4\x1f\x0e\xd3\x10\x13\x29\x95\x83\xa8\xa6\x46\xc9\xff\x21\xf4\x0a\xcf\xed\x3f\x27\x24\xbe\xb0\xf2\x7c\xb9\x11\x75\xa6\x96\xa2\xd2\xf3\x89\x14\x0b\xa2\x48\x22\x41\xac\x2b\x64\xd4\x50\x59\xbd\xa3\xf6\xb6\x7c\x25\xfe\x31\x3d\x51\xcc\x91\x87\x8b\x65\x9f\x6f\x19\x12\x4d\x06\x85\x42\x16\x44\x3a\x25\xbd\xae\xf7\xba\x81\xe3\x27\x54\xd5\xd1\xaf\xea\x03\x96\x73\x2f\x85\xc6\x82\x98\xa4\x58\x2e\xe9\x84\xef\x59\x10\x73\x0b\x3e\xda\x17\xf0\xf1\x87\xb7\xc6\xde\x02\xe2\x43\xfa\x3e\x09\x0b\xe2\x54\x06\xd4\xfb\xa0\xb8\xc0\x69\xb2\x6d\xb3\x20\x31\x16\x19\xa2\x44\xe1\xf6\x17\xff\x71\x16\x82\x72\xab\xef\x37\x10\x79\xf3\xb6\xcc\x9a\xec\xbf\x53\xf5\x49\x16\xb0\x58\x0b\xe8\xf5\x31\x67\x84\x9e\x59\xc0\x58\x8c\x2f\x92\x83\xa9\xb9\xd5\xdc\xbe\xb3\x0d\x4c\x07\x8b\xd4\xd6\xdf\xcf\xcd\x5d\x59\x79\xb4\xed\xf4\x5b\x95\x51\xa4\xdb\x1a\x3f\x4b\x55\xfc\x60\xb0\x2a\x98\xc8\x52\x38\xd5\x93\xef\xe3\x54\xd9\x0d\xd4\xea\x55\xb4\x61\xd8\x43\xa9\x7e\x0c\xcc\xea\xaf\x00\x2b\x5d\xf0\xca\x02\xae\x52\xbc\x81\xe5\x09\x8a\x8e\x08\x38\x92\xef\x62\x41\x1a\x47\x68\x12\xf7\xef\x71\x55\x89\x05\x92\xa6\x91\x45\xce\x5a\xa5\xcb\xdb\x4a\x7c\x5c\xdd\x3c\xc9\x55\x1a\xf8\xd7\x6d\xf8\xd5\x8a\x5a\x41\x21\x34\xb2\x1d\x26\x6e\xee\xb8\x8e\x15\x75\xcb\xcb\xbd\x38\xc2\x73\xd1\xf7\xde\x59\xa0\x69\x68\x15\x56\x8a\x4b\x9b\x26\xad\xeb\x6d\xd3\xb9\x5a\xc6\x2e\x0c\x66\x01\x04\x49\xe8\xb4\xf0\x9d\xf7\x81\xa3\x6a\x7c\xe9\x4d\xc8\x02\x48\xad\xb6\x7d\x55\xe6\xf9\xed\x00\x61\x3e\x99\x7d\xa0\x08\x9a\xd4\xed\x3b\xe9\xa0\xd9\x78\x82\x05\x26\xe4\xa8\x45\x66\x2d\xdd\xfe\x29\xd4\x8f\x53\x39\x6f\x78\xc8\x02\x13\x71\x7c\x9e\x8f\x70\x10\x4b\x51\xe8\xcb\xe4\x7e\x1a\x19\x33\x39\x10\x2f\x1f\x3c\x28\xa3\xb8\x37\xef\xdf\xd7\xed\x54\x69\x93\x91\xc1\x4d\x33\xa0\xfd\x1d\x75\xca\xd6\x9f\xc3\x54\xfc\x2b\x4c\x48\x60\xe7\x33\xf8\xa6\x2d\xd2\xc4\x66\x7f\x27\x21\x24\x41\x6b\x8f\x07\x71\x94\xe5\xdf\x13\xb3\x60\x84\xe8\x14\xd9\x34\x6d\xb2\x37\x26\xf8\x33\x42\xc0\xda\x12\x75\xdd\xd4\x0e\x07\xdc\x3e\x4c\xd4\x73\x1c\x0e\x0f\xa9\x15\xab\x3b\x58\x2b\x8d\x64\x7c\xeb\x48\xc8\x79\x30\x11\xaa\xf6\xef\xe7\xcb\xb4\xa0\xda\x8e\x16\x78\x37\x11\x40\x53\x96\x75\x83\x74\x3a\x77\x30\x0a\x6c\x35\x26\x2b\x54\xf7\xa7\x84\x20\x90\x0b\x1d\xbe\x9f\xbb\xbf\x0a\xcb\xc5\xf9\xbe\xf9\x57\x2f\x11\xcf\x48\x1c\x5a\x33\xd4\x7b\x40\xbc\x81\x33\x88\xf8\xed\x7c\xe5\x3a\xc2\x48\x2c\x00\x51\x64\x05\x7c\xf4\x78\xa0\xee\x3c\x10\x62\x6b\xe9\x98\x15\xcd\x22\xcf\xbd\x10\x85\x3b\x9a\x08\xab\x44\xd9\x6e\x9f\x0e\x8d\xd8\xf5\xde\x3b\xa8\xfb\xfc\xa3\xa4\x71\x8c\x34\x91\x5e\x68\x0b\x09\x38\xb3\xa1\x00\x23\x54\x72\xc4\x56\xa1\x9b\x1f\x2e\xe7\x37\x02\xf5\x16\x47\x4f\x9a\x4a\x8d\xdd\x97\xfa\xad\xfc\x18\x7b\x91\xd9\x54\x6d\xf2\x00\xa8\x12\x78\x09\x76\x91\xb4\x96\x5f\x68\xeb\xd2\xfe\x77\x3a\xd6\x50\x2c\x0b\xfa\xcb\xbd\x6d\xde\xb6\x6f\xe5\x69\x32\x01\x18\x4b\x51\x6d\x5a\x8c\xf6\xf8\xf1\x45\x32\x61\xab\xc1\xcf\xc7\x22\x53\x7f\xc3\xf6\x96\x11\x66\x22\x64\x99\xeb\xec\xdd\x16\x2d\xe7\xdf\x6c\xc2\x03\x96\x38\x85\xc3\x9d\xa8\x7f\xfc\x0e\x97\x39\x3c\x1b\x23\x9c\x51\xa4\x47\x61\x9c\xf4\x3f\xe7\xac\x71\x46\x2b\xf3\x0f\x8a\xa7\x24\xe9\x38\x6e\x3d\xc4\x7e\x61\x21\xd2\x59\x3e\x30\x39\x9c\x3c\x34\x2e\xd2\xd0\xa9\xc8\x6c\xdf\x20\x37\xe3\xfb\x90\xc6\x21\x83\xae\x03\xdf\x27\x55\xc3\xdf\xd6\x2d\x12\x22\x06\xc1\x3f\xd1\x0b\xe8\x07\x09\x6b\xa7\xda\xbe\x50\x9f\x2f\xbe\x44\x48\x9b\x8a\xb7\x11\x61\xa6\xaa\xf2\xb1\xd4\xe7\x1c\xda\xd3\xb5\x6f\x4a\x38\xb9\x59\x12\x12\xee\xb2\x51\x6b\xc8\xe9\xe7\xbe\x62\x5a\x7a\xea\x56\x9e\x97\x1f\x9b\x1e\x5b\x3e\x58\x13\x89\x96\xd6\x21\xca\x3a\x93\x59\x88\xe7\xf6\x52\xb7\x61\x8f\x1f\xa1\x13\xf0\x8c\x4a\x6c\x9e\xf8\x03\xc0\xad\x4b\xcb\xa1\xd3\x24\xaf\x1f\xca\xc3\x01\xfa\x01\xca\x20\xa5\x65\xaf\xb3\x0a\x54\xf3\xa5\x15\x2c\x23\x26\xa6\x58\x6a\xbf\xcf\x4b\x89\xc2\x4b\x50\xb5\xfb\xde\xaf\x52\x31\x46\x0c\x84\x58\x7d\xb0\xf8\xc7\x6f\xa2\x7e\x5b\xf4\xbe\xb3\xd6\x5b\xb9\xac\xee\x00\x26\x15\xf0\x2f\xe3\xc4\x30\x48\x34\xaa\xb5\x65\x96\x3e\x82\xbe\x41\xd0\x9c\x7d\x14\x1d\x06\xce\x44\x6b\xb5\x1f\x07\xcc\x5f\x87\x9f\x21\x01\xdb\x86\xc6\xf0\x73\x81\xdd\x1b\x0c\x40\x73\xcf\xb4\x9e\xbd\x37\x61\x48\x02\xed\x4c\x8f\xda\x75\xa0\xce\x66\xc0\x7a\x2c\x8c\x48\x80\x2e\x16\xc7\x73\x93\xad\x9a\x2b\x58\xff\xf5\x5c\x0b\xa3\x84\x59\x87\x5f\x0b\x71\x5d\x15\xba\x5e\xf8\x48\x38\x8c\xa4\x42\x3a\x75\xfd\x26\x2a\x78\x43\x04\x79\xdd\x1d\x73\xd6\x86\x88\x96\x5e\xa0\x97\xf7\xf6\xdb\xe2\x65\xe5\x8f\xc7\x4c\x60\xad\x65\x5f\x41\xa7\x69\xb8\xf0\xac\x85\xf1\xaa\x14\xc6\x46\x86\x8e\xdf\xae\x61\x7b\xb2\x8c\x94\x77\xa8\xba\x0b\x49\x82\x40\xc8\xde\x8f\x04\x91\xfd\xdd\xb1\x08\x22\xeb\x3f\x67\xaa\xd2\x41\x33\x3e\x49\x22\xc2\x24\xb6\x68\xc8\xff\xf7\xde\xf7\x48\x59\x98\x70\x6b\x09\xdf\xbe\x6f\xe2\xe7\x44\x60\xb3\x3d\x1c\xe1\xeb\xb8\x3d\xcb\x8f\xb2\xf4\x6c\x57\x7f\x94\x72\x6b\x82\xb9\x47\x6c\x56\x21\xf2\x2e\xe0\x1d\xb5\xaf\xe3\x71\xf0\x19\x5f\x13\x5e\x58\xc8\x82\x00\x05\x6c\x8f\xe2\xe7\x77\xc8\x86\xe5\x89\xf6\x58\x8a\x4a\x21\xaa\x3c\x1e\x45\xd1\x69\xc0\xb0\x90\x11\x85\x61\xbe\x5f\xf7\x6f\xb2\xfe\x33\x91\x44\x76\x30\x9a\x13\xec\x6d\xf1\x63\x84\xd0\x64\x21\x13\x80\x95\x91\x45\xf3\xe6\x84\x9a\xbb\x04\x22\xe4\x42\xe0\xaa\xde\x86\x25\x53\x9d\x34\x16\x72\x09\x3e\xff\x5f\xbe\x89\x4a\xa8\xa6\x4b\x51\xfc\x08\x43\xb0\x04\x8b\x09\x05\x9c\x8f\xcf\x45\x77\xea\x34\x04\x4c\x18\x17\x7f\x2c\xd6\x0f\x8b\x9b\x87\xd5\x7e\xf9\xfc\xb8\x59\x3c\xfd\xb9\xdf\xbe\x6e\x36\x0f\x7f\x76\xe3\xb8\x0d\xf5\x5c\xd2\x87\x1c\xa0\x36\xf4\xc9\x8a\x43\x0e\x37\xe7\xcb\x27\x06\xa6\x2c\x14\xa1\x15\x56\xb9\xcd\x0e\x59\x23\xf2\x45\xd5\x0c\xf0\x81\x2c\x14\x71\x8a\x5d\xf1\x63\x7d\x5a\x5a\xfb\x92\xbc\xbf\xa3\x8a\x08\xe3\x7d\xd4\xb0\x08\x3a\x44\x2c\xf8\x31\x34\xc1\x9d\xd9\xca\x51\xdd\x2e\x76\xdd\x1d\x55\x94\x42\xbf\x67\x2f\x46\x45\xf3\xaf\x20\xd1\x93\x1f\xa0\x24\x41\xe8\x6c\x9b\x14\x0e\xb3\xd3\x50\x69\xc2\x7d\xd7\x6c\x88\xe8\xea\x85\x62\xfa\x09\xa5\x34\xb3\xc2\x9a\x98\x97\x9f\x9b\xb7\x67\xb3\x81\x6a\x22\x52\xe4\xc7\x1a\xeb\x47\x56\x94\xd6\xfc\xc0\xa1\x71\x3f\x59\xcc\x26\xef\x95\xa6\x32\xec\x8d\x68\x9a\xac\x6e\x32\xd5\xbd\x3f\xc0\x03\x3c\xf3\xdd\xc3\x7a\xb3\x59\x3f\x75\xbe\x29\x2c\x04\xc1\xac\xbd\x22\xd4\xcd\xbe\x2c\x60\x5d\x60\xef\x72\x75\x3c\x35\x97\x91\x94\x11\x0b\x41\x5b\xfe\x46\x0d\x8d\x07\x49\xdd\x42\x2e\x2e\x93\xe7\x62\xa8\x44\x8d\xd5\x7d\x05\x06\x2a\xa8\xdc\x76\x37\xbb\xfd\x87\x86\x73\x5c\xc1\xd7\x4b\x5f\xc9\x08\x8d\x23\xae\x7e\xdb\x0d\x75\xff\x58\x68\x8c\xd5\xe0\xcd\xea\x75\xb1\x79\x1b\xe8\x31\xd8\xe3\x51\x90\x00\x36\x5f\x3b\x3e\x41\x55\x1e\x2d\xad\xf0\xf2\x65\x3f\x9f\x45\x01\x0d\xb1\x28\xe6\x89\x16\xc3\xc5\x25\x0a\xa4\xc4\x66\xff\xe5\xe7\x0f\x0c\xaa\xfd\xdf\x43\x22\x35\x73\xca\xe9\xa8\xe6\xa1\xc5\x4c\xd9\x89\x45\x61\xa4\x91\xd9\xf9\x70\x56\x3f\x2e\x1d\xee\x8a\x45\xa1\xe2\x18\x60\xe9\xf2\xdc\x7e\xa5\xdb\x26\xda\xd8\xa9\xbd\x8c\x2f\xe5\xab\xfa\xdf\x1c\x02\xc1\xd8\x7a\xb5\xfb\x36\x8c\xc8\xa3\x28\xe6\x88\xd7\xda\x7e\x7b\x7e\xd9\x2d\x6e\x6f\x5f\x46\x97\x1e\xa5\xd6\x33\xaa\x72\x90\x05\xd0\x23\xc0\x04\x8b\x22\x19\xe1\xc7\x3b\xb1\x93\x46\xa8\x1f\x8b\x42\xb7\x6f\xc2\xaf\xa6\xe3\x7c\x33\xd3\xaf\x48\x51\x64\x04\x46\x44\xa6\xac\x14\x72\x41\x97\x17\x95\xf7\xd7\x6d\x8c\xb2\xda\x0b\xb8\xf7\xec\xca\xaf\x62\x8e\x28\x89\x05\x36\x37\xf3\xf6\xd6\x5a\x4c\xe9\xb3\x99\x2b\xfe\xb1\x28\x11\x12\x51\xe2\xf2\x7c\x71\xf6\xab\x93\xe3\x3a\xb1\x34\x08\xbb\x36\xef\xad\xc1\xe3\x80\x0b\xc7\x22\xaa\xb9\xcb\x63\x9a\xc5\x3b\x54\xc2\x21\x8c\x87\xea\x84\x6e\x24\x23\x52\x79\xdc\x3c\x16\x44\x5f\xca\x73\x27\xf9\xc5\x22\x96\x88\x78\x60\xdf\xe3\xa8\x49\x4e\x92\x6d\x00\x31\xfd\x5a\x9f\x8d\x45\x8c\x2a\x8c\x77\xad\x00\x63\x67\x5c\x36\xbe\xdf\x3c\xea\xe4\xe5\x30\x94\x1f\xc8\x29\xb3\x88\x0b\x81\x73\xd3\x95\xad\x10\x90\x32\x48\xca\xfc\x28\x90\xd8\x64\xb8\x2f\x73\x33\xd8\xb3\xa3\x94\x28\xf0\x52\xbe\xaf\x05\xd4\x4a\x9c\x40\xff\xcf\xb9\x6c\x60\x5d\x6c\xf1\xc2\xfd\x48\x41\xa4\x35\x5a\x6c\x77\xaf\x73\xbb\x95\x0d\xe6\xd1\xc0\x7f\x88\x45\x22\x12\x86\x7b\x94\x75\x0d\xaa\xf9\x54\x79\x83\x45\x82\x29\xac\xdd\x98\x73\xa1\xaf\x74\x42\x59\x24\x20\x44\x7b\x42\x0c\x48\x47\x1c\x9b\xf9\x52\x68\xa4\x88\xc6\x9e\x92\x83\xf5\x68\x2b\x80\x63\x83\x99\x85\x52\x55\x59\xd7\xd6\xf5\x76\xef\xb5\x13\xec\xff\xbc\xb9\x90\x20\x08\xfc\xd7\x2a\xa7\xa9\x2f\xce\xcd\xdb\xf5\xef\xec\x9e\x8b\x8e\x29\x3a\x4a\xac\x37\xcf\xeb\xc9\xf4\xd1\x1a\xac\x01\x04\xca\x90\xf9\xae\x0d\x52\x8a\xfc\x5a\x1c\x41\xa0\xb8\xeb\x10\x58\x79\x2b\xef\xb1\x78\x1d\xd3\x44\x10\xc7\x5e\xf9\x1e\x5d\x65\xca\x7c\xc4\xff\x64\x11\x80\x41\x6c\xc9\xe2\xa6\x5e\xa2\xee\xdd\xfc\xfd\x31\x89\x41\x74\xfb\xf2\xf9\xe1\xf9\x65\x7f\xff\xb2\xf2\x31\x42\x1c\x00\x80\x35\x45\x47\x25\x8b\xf1\xbb\x15\x13\xa2\x55\x3f\xdf\xed\x1b\xf1\xef\xf2\x28\x33\xd8\x0f\xfc\xdf\x58\x4c\xa4\xed\x9f\xfc\x3f\x67\x92\xb9\xbf\xcc\x87\x90\x31\x51\x69\xe0\x80\x4d\xbd\x84\xf4\x20\xeb\xbc\x66\xed\xb2\x38\x32\x81\x34\x8e\x82\x62\x0b\xd7\xe0\x04\xcc\xfa\xd2\x4d\x4c\x03\x12\xe8\x81\x5a\x7b\xf6\x5f\xb8\xcb\x0e\x6f\x3e\xac\x22\x53\x83\x92\xeb\xff\x8e\x7f\x39\x95\xd6\x92\x77\x53\x81\xce\x54\xff\x4a\xc5\x2c\x54\xb1\xf4\x3a\x4b\x9d\x50\xd5\xf8\xc3\x29\x08\x3e\xf2\x34\xb9\x56\x50\x99\xbf\x3d\x42\x0a\xd5\x7d\x50\xa8\x06\x59\x15\x4d\x5f\xa2\x8b\x05\x68\xaf\x88\x81\xea\x5b\xfe\xef\x92\x2b\xed\x82\xf0\x1d\x7a\x25\x7f\xb9\x6d\xc6\x32\x8d\x91\x93\xf5\xb8\x5a\x76\x67\x10\x61\xe0\xfa\xb6\xfb\xb7\xb2\x3e\x91\x2f\x51\x3c\x2c\x96\x32\xb0\x75\xd9\xda\x2d\xdb\xdb\x4f\xa4\x0f\x59\x2c\x8d\x74\x00\x39\x91\x1d\xdb\x39\x6f\xdd\x91\x44\xbe\xe9\xdc\x51\x59\x0c\xc4\x6a\xed\x09\xad\xff\xc8\xaa\x73\x7d\x0b\x66\x7e\x32\xc7\x90\x5a\x1f\x38\x74\xc3\xbe\x2b\xab\x6b\xb6\x08\x8b\x0d\x93\x0c\xba\x15\xa4\x14\xc5\x84\xa2\x35\x1a\x9d\x04\x61\x64\x3a\x8f\xef\xe0\xa7\x6c\x54\xa7\xcf\xe0\x47\x40\x90\x74\xc5\xb9\xed\xfe\xe6\xf9\xf5\xfe\x9b\xdf\x5e\x12\x42\x01\x03\xc5\x63\xa6\xaa\x72\x97\x9d\xba\xbf\x73\x2b\x2f\x55\xc0\x4f\xac\xd8\x74\x7f\x07\x2a\x1d\x18\x67\x9f\x8b\xba\xd9\x1f\x30\x65\xdf\x8b\xb3\xce\x9a\xbd\x2e\xd5\xb9\x17\xc3\x61\x49\xe8\xde\xdd\x3c\xab\x9b\x75\x03\xc7\x36\x38\x7a\x41\x61\xc1\x6a\x12\xbf\x25\x11\x91\x18\x67\x6d\x9b\xb3\x46\xd6\x75\xb7\xe2\x27\x71\xa8\x89\x97\xfe\xf1\xde\x54\xfe\x10\x4f\x1c\x3d\xb7\x79\x01\x95\x9d\x32\xdc\x6b\x70\x13\x98\xd9\xba\x13\xca\x74\x6c\xf3\xac\x76\xa5\x2f\xda\x1d\xac\x27\xa7\x5d\xb9\xe3\xb2\x84\x4a\x8a\x6b\x43\x53\xde\x44\xe1\x7c\xc2\x91\x50\x69\x2f\xbc\x28\x9f\xcd\x2e\x53\x3f\xa0\xa9\x9f\x3f\x8a\x09\x89\x80\x25\x14\x42\x04\x7e\xad\x7e\x36\x15\x1c\xb3\xf3\x10\xff\xc4\x12\x16\x4b\x94\x81\xc3\x67\x84\x0c\xe5\xdd\x6a\xf1\xe8\x8f\xa6\x91\x89\x3b\xad\xd7\xa7\xbd\x29\xd4\x34\x40\x19\x79\x4a\xba\x4f\x09\x4e\x22\x57\x38\x70\x37\x75\x6a\xb4\x32\xba\x37\x32\x52\xc8\x68\x3d\x66\x85\xed\xfa\xfa\xbf\x33\xeb\x15\xad\xbc\x56\x86\x3f\xa0\x02\x82\x31\x7c\x1b\x38\x8e\x41\x1d\xff\xb8\xc2\x8e\xb0\x44\x85\x04\x77\x1e\xdb\xab\x1d\xe1\x39\xfd\xee\x94\xa8\x38\xc0\x4a\xa6\x12\xc5\xba\xae\xcf\xb0\x2e\x74\xf6\x9e\xe9\xb3\x27\x73\xb7\x23\x28\xa6\x1b\x16\xbf\xb5\x99\xba\x03\xb3\x44\x71\x8a\xd4\xf7\xe3\xfe\x54\x96\xdd\x1a\x93\x68\x6a\xfd\xc1\x7c\xab\x6b\x6f\xfd\x92\x27\x1f\xd6\xa9\x56\xb4\xe7\x12\x5e\x8b\x37\x4e\xee\xb0\x56\x40\x5d\x01\xae\xbd\xde\x41\x0b\x2f\x81\xc8\x56\x05\x2d\x5a\xbd\x7d\xd3\xcf\xfa\x70\x2d\x39\xeb\x47\x73\x2e\xf5\x40\x1d\xe9\x66\xb7\x74\x45\x80\xf1\x38\x13\xca\x94\x7a\x8d\xe6\x7a\x68\xf8\xc9\x12\x13\x09\x94\x80\xd8\xac\x5e\x96\x7b\xf7\xae\xef\x9e\xf7\xeb\xa7\x3f\x56\xdb\xce\x03\x91\x25\x26\x8e\x11\x78\xbc\x05\x8c\xfd\x1e\x3b\x24\x21\xa3\x01\x49\x90\x81\xb3\xda\x7d\x83\xaa\xec\xfe\x1a\x11\x14\xc0\x79\x29\xf3\xfc\xa1\x6c\x1a\x70\xaf\xae\xeb\xa8\x33\x1a\x28\xc0\x27\xfb\x7d\xb1\xde\xed\xd6\x8f\xab\xd7\xa7\xdd\xfa\xe1\xfb\x7a\xf7\xed\xf6\x65\xf1\xfd\xf9\x65\xf7\xb2\x78\xda\xde\x79\xe5\x0b\x46\x49\x48\x51\x16\xe2\x84\x82\xc1\xdd\xab\x4c\x89\x88\x10\x4d\x2d\xcf\x97\x57\xb5\xec\x85\x70\x19\x25\xba\x03\x07\xdd\x01\x0c\x41\x51\x8b\x42\xdb\xc5\xb1\xf3\xca\xbc\x92\x3b\xea\x6e\x1e\x25\xda\x3e\x12\xeb\x0b\x86\x66\x04\xbf\xda\xda\xc6\xaf\x3a\x0d\x89\x16\x41\xa7\xc4\xbf\x7c\xcb\x72\x7d\xad\x4b\xc2\x68\x18\xc5\x98\x63\xc1\x4f\x5b\x17\xf2\xc1\xd4\x27\x2f\xc9\xe4\xc3\x71\x18\xc4\xa8\x37\xa4\x37\x15\xac\x55\xd9\xe3\x22\x18\x0d\x53\xed\xb7\xca\x45\xd5\x64\x2a\xb7\x4d\xea\x4f\xce\x64\x02\xcc\x88\xb3\x22\x6b\x2c\x89\xab\xbb\xa3\x51\x18\xd0\x0e\x7b\x87\x84\xf1\xfc\x32\xd0\xad\xfe\x4f\xd8\x87\xbd\xec\xaf\x79\x9e\x1a\xa3\x51\x64\xc2\x8e\xe3\x5b\xdf\x7f\xa5\xb0\x3d\xbe\x8d\x11\x27\xc4\xbd\x36\xdf\xca\x73\x0d\x2b\x7d\x98\x68\x9e\x4c\x7e\x49\x94\x52\x84\x28\x38\x6f\x96\xfd\xa9\x2a\x4d\x67\x93\xc3\x68\xa4\x63\x69\x3d\xbb\x0b\xa8\x44\xbe\x15\x39\xac\x0a\x3d\xbc\x6f\xb1\x32\x38\x83\x9e\x5e\x1f\x5f\xb7\xdd\x1f\x21\x94\xae\x25\x78\x3e\xfd\x9d\x6e\x07\xa5\x31\x8d\xad\x0c\x2a\x46\x38\x0f\xa2\x8d\xd9\x5f\xe0\x3d\xc3\xaa\xca\x28\xd2\xa6\x94\x71\xac\x06\xdd\x2c\x6e\xfe\xf4\xbb\x2d\xa5\x5c\x60\x13\xc6\x46\x7a\xf3\x9a\x47\xd7\xff\xdb\x7f\x58\xda\x1c\xd6\xa7\xc7\x8b\x3c\x6f\xf7\xd3\xbb\xb2\x52\x99\xcc\x3f\xe9\x74\x50\x26\x00\xd7\x34\x6b\x6f\xdc\xa6\x8d\xb6\x3e\xee\x10\xd4\x7e\x14\x88\x9e\x42\xd3\x20\xb6\x4a\xa8\xa9\xb9\x07\xa3\x3c\x30\x08\x63\x44\x26\x95\xd7\x93\xfa\x2a\x59\xa6\x9c\x04\x58\xb4\xc2\x95\xad\x0d\x0d\x7a\x31\xb4\xe9\xb9\xa3\xc0\x06\x51\xe7\xa6\xec\x79\x81\x8c\xf2\x34\x22\xac\x7b\xba\x8d\x2b\x4f\xcd\xd8\x69\x32\xca\xa5\x46\xb0\xc2\xf1\x9c\xef\xca\xbb\xea\x13\x30\xf4\xf8\x33\x29\xa7\x28\x61\x9e\xd5\x0b\xcb\xdb\x19\x89\x18\xcf\x4f\x60\x11\x2b\x70\xeb\x80\xfd\xb1\x93\x5b\xe0\x86\xc9\x54\x85\xb6\x3e\x8d\xb1\xb6\xf7\x20\xf1\x3f\x4c\xb1\xc8\xb2\x53\xf7\x37\x03\x3e\x1b\xa3\x9a\x24\x49\xe2\x3b\x97\xe7\x66\xac\x87\xcc\xa8\x4e\x28\x73\xf5\xb0\xc7\x52\x4f\x0f\xca\xc8\xb3\x3f\x6d\x82\x36\x1f\x35\x52\xd0\xa9\xea\x20\xd1\xdf\x40\x1f\x20\xbf\x38\x42\x61\x37\x27\x40\x9b\xd4\xa3\x21\x33\x5d\xdf\x5c\x16\xba\xce\x3f\xeb\xdd\x53\x30\x29\x7a\xd5\x99\xaa\x3c\xfa\xe2\x42\x4f\xd2\x62\xd4\x28\x86\x3b\xb0\x39\xe7\xf9\xb4\x3b\xd1\x0d\x49\x13\x2f\x18\x24\x7e\xfa\x50\x0f\xfb\xba\x2f\xf0\xbf\xe7\xcc\x4e\xa0\xc9\x33\x37\x40\x02\x2f\x96\xbc\x9e\xde\x0e\x63\x98\xb1\x81\xbe\xa5\x77\xbb\x47\xec\xae\x89\x05\x41\x88\xed\x77\x09\x8b\x4a\x66\xcd\x80\x64\xce\x18\x89\x6d\x77\xf9\xae\x6a\xa3\xc4\xf7\x7a\x51\x1d\xa0\x68\xb2\x42\x74\x03\x98\x55\x28\x44\xea\xc0\xf3\xc7\x27\x9d\x4f\x46\x84\x4c\x2d\x27\xf5\xe2\x1a\x89\xdd\xc2\xc5\x42\x22\x24\xf3\x0e\x5b\xe7\xc3\x54\xb7\x97\xb1\x90\x59\x7e\xb1\x5d\x2f\xac\x02\xd2\xec\x03\x65\xa1\x8a\x98\x93\x93\x38\x55\x9d\x6f\x28\x63\x51\x1a\x61\x23\x07\x7b\xd8\x87\x73\x05\x77\xe7\x62\xb6\xdb\xf4\x8f\xf3\x8c\xf0\x9f\x3b\x49\xcc\x09\xd6\xc7\xce\xce\xb0\x6f\x5c\xa1\x65\x31\x58\x70\xad\x67\xd3\xd8\x0d\x36\x2b\x0e\x4b\x71\x3c\x89\xec\xe0\x23\x46\x96\x10\x69\x1b\x36\xe5\xaf\x44\x01\xdd\x07\x58\x48\x51\xe5\xc3\x49\xd4\xea\xde\xdd\x6b\xf4\x9c\x19\x4b\xb8\xf5\xf2\x3d\x5f\xa0\x72\x28\xdb\x5f\x5a\xfd\xf8\xcf\x9a\x44\x07\x9e\xc5\x55\x6f\xa0\xfa\x0e\x19\xce\xb9\x28\x8a\xfc\x85\x73\x48\xac\x15\x5a\x55\x9e\x4f\x9d\x13\x9a\x5f\x99\x59\x1a\xc4\x48\x7c\xdf\x54\x59\xd1\xb8\xd7\x68\xdd\x61\x7e\x3e\x11\x6b\x63\x2c\x15\x11\x56\xa1\x51\xa0\xfb\x5c\xf4\x4a\xba\x8c\x89\xc0\x60\xd5\x4f\x8a\xe2\x87\xaf\xb1\xf8\x43\xd2\x6a\x94\x61\x66\x76\xae\xae\xe6\x5d\x6f\x3f\x44\x18\x75\x7b\x35\x93\x61\x10\xa4\xce\x96\xbf\xe8\x81\xfa\x8c\xc9\x98\x21\xb7\x3f\x2f\x0f\xeb\xee\x39\x29\x6a\x05\xec\xe0\x9a\x0f\xe3\x46\xe8\x24\xc6\x64\xdf\x42\x60\x9f\x8b\xfc\xb2\xe9\x5d\xe4\x26\xcb\x32\xd3\xcc\x4a\xa2\x6a\x30\x59\x01\x9b\xaa\xfc\x7f\xa0\x26\x86\x03\x7e\xa4\x16\x28\x08\xf5\x24\x8e\x59\xd7\x7b\xfd\x0c\x99\x6f\x3f\xc3\x83\x40\x6a\x18\xfa\xa7\xf9\xb9\x35\x20\xec\xfa\xa1\xd4\x91\x6f\x50\x8f\xe9\xd2\xb7\xa5\x38\x11\x06\xd3\xda\x7d\x56\x2f\xcb\xaa\x02\xd5\xdc\x9d\xf3\xfc\xe6\x7c\xc9\x26\xdb\x14\x27\xda\xaa\x82\xd4\x56\xb6\x29\x8a\x59\x77\x0e\x48\x5c\xdb\xf8\xf9\x64\x05\x2b\xee\xca\xaa\xbd\x18\xf5\x76\xbd\xd5\x8f\x7f\x43\x18\xa8\xc4\xce\xdf\xfc\x07\xee\x7d\x7e\xd8\x0c\xcd\x9d\xf1\x30\x09\x31\xe5\x57\x79\x59\x83\x6b\x41\xfb\x8b\x08\xb9\xc2\x35\xf4\x79\xf7\x6d\xf5\xb2\xdf\xee\x16\xbf\xaf\xba\x43\x4a\x80\x87\x48\x1d\xc5\xcf\xbd\x1a\x22\x27\xc7\xdf\x10\x91\x6e\xd1\x1a\xdb\xd9\x7f\x5d\x03\xe2\x31\x97\x54\xf6\x76\xa0\x7a\xfb\x96\x9d\x46\x4e\xa0\x7e\x9c\x09\x02\xb7\x81\xfa\x48\x6d\x7c\xa2\x24\x4c\x30\x21\x92\x50\x37\x8b\xe2\xe0\x59\xcc\x8c\x27\x71\x8c\x7a\x18\xcd\xc4\xcb\xc9\x1f\xa7\x49\x88\x74\x20\x84\xb9\xe1\x4c\x38\xcd\x75\xc1\xdd\x68\x26\x22\xcc\x79\xb1\x25\xef\x4b\x79\xab\xe6\x6d\x72\xb9\x4c\x32\x64\x72\xda\x39\xbb\x1c\x35\x79\xdd\x10\x1e\x44\xd4\x85\x11\x87\x0a\x70\xa3\xb2\x6a\x65\xe3\xb0\x90\x73\x62\x9b\x3e\xd6\x65\xe7\xd4\xb1\x6d\xda\x23\x9c\xb8\x7b\xb2\x74\xb6\xb8\xb3\x4d\x05\xce\xc1\x2e\xf5\x37\xc2\x52\xc4\x96\x65\x35\x05\xb3\x9d\xbf\x56\x7b\x0d\xaf\x3c\x14\x19\x4f\x03\x4b\xee\x3e\x8a\x3c\x53\x60\xc5\xf4\xa7\x45\x0c\x2e\x42\x4b\xc8\x6f\x44\x9e\x5f\xfe\x28\x9b\xae\x55\xce\x85\x60\x01\x19\xb9\xc4\x59\x80\xa8\x3f\x6c\xb4\x1e\x3a\x21\x3d\xfe\x79\xe3\x0f\x49\x2a\x10\xc5\xa2\x44\xb1\xbc\xae\x39\x8e\x9f\x97\x54\x1c\x73\x5c\x93\x15\x7a\x6a\xa5\x33\xbe\xcf\x2a\xa0\x81\xeb\xbc\xb8\xa2\xcc\xe4\xa7\xa8\x58\x61\x79\x5a\x95\x47\x2b\x01\x55\xfd\xc8\xe1\xa5\x2c\x9b\xdf\xa6\xc4\x48\xc6\x15\xb3\xde\x90\x79\x79\xb0\x34\xb7\xf3\x35\xb2\xaf\xbf\x48\x95\x46\xc2\xa9\x9c\x20\xa1\x16\xcb\x02\x7d\x25\x84\x2b\xc1\x39\xef\xc2\x1c\xaf\xd7\x86\xe6\x02\x57\x4d\x1d\xae\xb4\xa4\x2e\x5b\xfe\x79\x41\x4a\xf9\xf8\xb8\x56\x11\xd6\xe9\x9c\x96\xd8\xa8\x17\xc1\x21\xa0\xc4\x66\x80\x58\xe3\x82\xfd\x49\x5c\x06\x45\x0a\x0e\x81\x85\xe2\x62\xa5\xf1\xf7\x8f\xb7\x5b\x54\x8f\x9c\x98\xc9\x30\x0e\xa1\x95\x58\xee\xf4\x17\xc2\x76\xea\xe6\xd0\x49\xc4\x30\x0e\xd2\xc6\x8a\x9e\x82\xbf\x2b\xad\xd1\xa0\x8b\xb7\x06\xbf\x1e\x8c\x88\x98\x45\x8c\x0d\x82\xe1\x34\x08\x34\x16\x29\x51\x9c\x53\xb7\x79\xcd\x73\x7b\x02\x3b\x97\x54\xe7\xe7\xc9\xd2\x80\x12\x4c\xe5\x8e\xa3\x04\xdc\x1f\xe4\x81\x45\xa8\x23\xee\xe1\xf1\xf5\x61\xb7\xde\x3c\xac\x57\x2f\xfb\xcd\xcb\x6a\xbd\x7c\x26\x7e\x1c\x21\x29\x22\x9f\xb6\xff\xdc\x75\x7f\x62\x49\x6a\x75\x60\x0e\x6d\x96\x71\x07\x50\xdf\x9e\x61\x57\xde\x95\xd5\x8f\x7e\x4c\x1a\x8a\x4e\x2a\x69\x30\x0f\x3e\xb1\x6c\xf9\xff\xfb\xaf\xff\x3a\x2e\x95\xb4\x4c\xb6\x5c\x54\xf0\xf8\x7e\x7a\x10\xe7\x02\xa1\x18\xa3\x49\x90\x86\x22\xc0\xb4\x2c\x07\xd3\xf0\xab\x63\x1c\x53\xfd\x47\xa1\xaa\xd2\x59\x33\x0f\xe5\x24\x59\x1a\x82\xad\xe3\xdd\x0b\xa7\xcf\xea\x0f\x44\x01\x45\xc0\x12\xfc\x6c\xa0\xd0\x5e\x8a\xc2\x2d\xa2\xbe\xfc\x93\x46\x8a\x80\xc3\xbf\xed\x8b\xf3\x71\x5f\x9a\xfd\x79\x86\x4f\xd7\x8d\x56\x18\xd1\x66\xb5\xe5\x8e\x3c\x17\x37\xe5\x30\x87\x1c\x8f\x8e\x89\x45\xb8\xb5\x79\x36\x09\xa3\xe6\x57\x78\xb0\x34\x11\x1a\x53\xae\x36\x4e\x9d\xb0\x4a\x58\x4a\x03\x66\xba\xaa\xc7\xe4\x36\xd1\x40\xa1\xc6\xcb\xc9\xe3\x3e\xb6\x7d\x10\x9d\xd2\x94\xdb\xf7\xc4\x87\x18\x9b\xac\x3b\xc6\x02\x6d\xab\x08\xc8\xbb\x77\xce\x89\xdd\xc1\xd0\xd2\x44\x6c\xe1\x56\x1c\xfb\x4f\x25\x96\xfa\xb5\xce\xf3\x73\x9d\x95\xc5\xed\xb9\xee\x9e\x07\x93\x56\x0d\xda\x94\x55\xbb\xf5\x4e\x5c\x16\x58\xca\x89\x8a\xec\x92\x00\xed\x3e\x7e\x5f\x76\xe5\xd1\x94\x47\x02\xb4\x67\x94\x58\x4e\xc5\xf8\x86\x72\xaa\xb1\xa0\x6d\x6c\xf7\x0e\xe9\x13\x26\xab\xd5\x15\x96\x3f\xe5\x29\x48\x47\x5f\x47\xf6\xe6\xcd\xb9\x9a\x3a\x8f\xb0\x34\x8d\x02\x04\xfa\x7c\xff\xb6\x5a\x3d\xec\xb7\xeb\x7f\xfb\x60\x23\x6d\xbf\x29\xc5\xb9\x03\xea\xdc\xa0\xd0\x7a\xd7\x2a\x1e\xdf\xf9\x34\x4d\x94\x4b\x33\x6f\x41\xe4\xe8\x4e\x8a\xa8\x85\x2b\xc7\x61\x96\xa6\x52\x22\x48\xc3\x15\x82\x36\x15\xd2\x64\x7d\x47\xcd\x9b\x08\xfa\xc1\x2a\x41\xa8\x11\x36\x56\xb3\xa2\x0d\x54\xf7\xed\xc6\x81\x82\x68\x68\xfe\x0d\xef\x2f\x28\xf0\xa1\x2d\x58\xe4\x5b\xa7\x10\xc0\x52\x21\x01\x39\x5e\x8b\x27\x2c\x14\xbe\x8d\x44\x54\x27\xb3\x54\x32\x3b\x4b\x6b\x2b\x4f\xfa\x2b\xbd\xf3\x4f\x90\x0a\xd3\x93\x0a\x0b\x03\xb2\x22\x57\xda\x31\x2e\xce\xf5\x60\x2d\x4d\xa5\x08\x85\x2d\x34\x5a\xe0\xd9\x5d\x59\xfd\xcf\xfa\xf5\xb7\xee\x68\x64\x1d\x20\xce\x15\x42\xc6\xd1\x76\xa5\x9b\x81\x8a\x48\x9d\x76\xa9\xe5\xb7\xb2\xaa\x61\xfb\x56\x42\xfc\x69\x0d\xef\xef\xfe\x3b\xfe\x19\x2a\xb1\x4d\x88\x03\x34\x37\x17\x4b\x03\x9e\x0e\xd0\xb8\x9e\x5b\xa8\xeb\xb5\xd4\x0a\x4b\x15\x37\x14\x63\xf3\x1f\x00\xa7\x07\x51\xcf\x10\x26\x52\x25\x82\x14\x7a\xd9\x12\x38\x25\xfe\x88\x96\x1a\x67\x81\x95\xcb\xe8\x04\xe1\x3e\x79\x94\x10\x04\xda\x46\x41\x3f\x77\xf0\xb3\x19\x5a\x6a\xb1\x14\xc2\x94\xa4\xbe\x7d\xfa\x3e\x10\xfc\x18\x5f\x2f\xa4\x56\x5c\xdc\x64\xef\x80\xfe\x94\x56\x4f\x69\x5d\x8c\xe1\x2e\xa9\x49\x63\x2a\xdc\xd6\x6d\x11\xde\xf9\xa2\x69\x46\x6c\x9f\x6e\x91\x35\xa0\x53\xbb\x3d\x3e\x8a\xba\x81\xea\xd9\x2c\xa1\x82\x63\x59\x5c\xdc\x0c\x76\x27\x15\x81\x4c\x11\xd5\x79\xbb\xd8\x2d\x86\x6f\x83\x20\xb1\x4c\xc2\x8e\x00\xb0\x5e\x3e\xb7\x2b\xe3\xd7\xea\x73\x4c\x10\x95\x20\x0a\xc9\xb1\xf6\xc8\x50\xfd\xac\x3d\xca\x11\x31\x30\xb4\x0a\x7b\x81\xba\xcc\xdf\x7b\x8b\x95\xd1\xed\x15\x21\x4f\x03\xeb\x03\x24\x6e\x2e\x33\xf8\xef\x76\x00\x73\xb7\xf8\x4b\x79\x8d\x36\x70\xd7\xd1\x40\xa5\xd9\xea\x67\xef\x45\xd3\x94\xd6\x5d\xb7\xde\x9f\xa0\xda\x7f\x40\xe6\xaf\x36\x22\x01\x9e\xfa\x54\x66\x45\x53\x0f\xe4\x7e\xda\x43\x3c\x1d\x6a\xc2\x6e\x21\x07\x35\xc9\x59\x44\x44\x2d\xeb\x33\x47\x9c\xf3\x55\x91\x61\x72\x75\x5c\x4a\x82\xdd\x4c\xd1\x80\x4d\x18\xf4\x98\xe1\x30\xda\xb7\x44\x94\x46\xc4\xca\xfc\x79\x0d\x8f\xc9\xb7\xc7\x8c\x04\xbd\xa3\xfe\x55\xe0\xf1\xf5\x63\x4c\xb8\x95\x7f\xfd\xfd\xac\xcb\x7a\x53\x7a\x97\x74\x1f\x27\x8a\x24\x25\x48\x66\x82\xba\xc9\x8e\x13\xb9\x78\x26\x12\x01\x78\x6d\xdd\xdd\x71\x18\xcc\x36\xaa\xfe\x7b\x28\x41\x91\x18\x89\x0b\x15\x42\xa9\x07\x50\x20\xd1\xde\x53\x2f\x2b\x33\x70\xe1\x63\x82\xca\xd4\xf0\x4e\x5f\xde\x27\x44\xd7\x0d\xc6\x69\xac\x2e\xa8\x8e\x2d\x1d\xb6\xaf\x47\xf8\x73\xb2\x20\x45\x4f\xda\x07\x78\xcf\x44\xf3\x36\x92\x50\x60\x82\xc5\x06\x4b\xe0\x9d\x22\xbb\x9b\x59\x9b\xbc\x6c\x56\xc7\x53\x56\x01\x9a\xf2\x4c\x26\x6c\xbb\xe7\xca\xee\xb5\x6a\x83\x52\x9b\xc3\xcc\xa1\x41\x04\x93\x0c\xa7\x90\x81\xfe\x87\x32\x13\xe2\x2a\xfd\xb8\xf6\x40\x39\xc1\x9d\xcc\xb6\xbd\x8e\xa1\x8e\xd4\x0c\x76\x58\xa4\x84\x61\xd9\xe1\x79\xbb\x18\xc2\xed\x44\x1a\x5a\x89\xd5\xd7\x22\x7b\x87\xaa\x03\xf7\x0a\x41\xa8\x67\x0d\xac\x55\x79\x9b\xd5\xc3\xea\x92\x10\xcc\x20\x39\x27\xab\x1d\xc6\xa5\x06\xfd\x28\x7e\x4c\x97\x6d\x21\xb9\x41\xc9\xaf\xa2\x6c\x32\x73\x71\x9c\xfc\x5f\x6c\x0d\xfe\xa3\xa9\x56\xde\x85\x6d\xd3\xc9\xfe\x30\xa1\x78\xe8\x2d\x11\x37\x6d\x98\x8b\xf1\xcb\xb3\x99\x7c\xb1\x4a\x2d\xf6\xf0\x05\x9a\x2a\x83\x77\x98\x5f\x68\xb4\x89\xb0\xac\xf5\x26\xea\x17\x30\x58\xce\xf3\x5f\x03\x11\x41\xd8\xf4\x2d\x1c\xb7\x59\xf1\xf6\x47\x06\xde\x02\xa6\x1f\x12\xdb\x4f\xdf\x40\xf3\x8c\x72\x7a\x7f\x70\x9f\x3a\x08\x93\xd8\xe8\x6b\xf1\xf4\x67\x33\x9c\x3e\xc6\x30\xea\x42\x2f\xcb\xa1\x58\xb4\x6f\x72\x9b\x6d\x0d\x13\x61\x19\x24\x2c\xb6\x0b\xf9\x32\x17\x75\xed\xad\xf0\x99\x0c\x18\xb7\xbb\x81\x2a\x7b\xa9\xe1\xef\x90\xcd\x2f\x30\x32\x10\xca\xea\xaf\x58\x6e\xd2\x0e\xc4\x71\xea\x31\xc1\x64\x60\xac\x1b\x44\x9b\x89\xda\x71\x57\x6a\x9a\x4c\x46\x71\xca\xac\xd6\x99\x9d\x26\xa3\x1c\x44\xc6\x2c\xc1\x0d\x71\xfb\x7c\xb7\xdb\x2f\x17\x9b\xc5\x72\xed\x75\xd3\xdb\x38\x95\xd3\xc8\xee\x96\xb2\xdb\x16\x64\x6c\x6c\x89\x63\xfd\xb8\xc3\x3e\x91\xff\x7b\x12\x13\xdc\x4c\xbc\xf8\x59\x7d\x57\xce\x72\xa6\x99\x4c\xb4\x02\xac\xa7\xde\x6e\xfc\x87\x29\x58\x79\x46\x28\x0e\x95\x78\x87\x5b\x30\xa8\x87\x31\x51\x0c\x19\xae\x5b\x92\x49\x83\x6c\xde\x5d\x96\x83\xb7\x25\x1d\xdd\x43\x9e\x32\xcf\xbf\x5e\x1c\x90\x2d\x74\x6d\xce\xc2\x24\x57\x02\xc3\x71\xb4\x0e\xd3\xab\xe6\x6d\x71\xec\x7e\x2a\xd7\x12\xeb\x95\x2e\xca\xfd\x03\x2a\x9d\xa9\xe6\x5a\x3a\x83\xc9\x94\x25\x54\xfa\x86\x0b\x82\x05\x10\x7b\x22\x9b\x7d\x6e\xa1\x06\xdb\xb3\x67\xdd\x48\x41\x24\x7a\x27\xde\x9d\x0e\x4a\xbd\x0d\x49\x55\x73\x3f\x53\x50\x8e\x50\x4b\x2f\xc5\xec\xcf\x22\xc3\x10\x8b\xb8\xcb\xd7\x65\xff\x27\x27\x30\xd3\xcd\x94\x6b\x11\x70\x26\x75\xa0\x51\xb2\xe0\xad\xfc\x78\x14\xc5\xe5\xee\xac\x7e\xd4\xf7\xd9\xfb\x20\xf3\x1a\xfc\x2e\x4d\x38\x75\xc5\x8c\x6f\x6d\xac\x03\x7a\x75\x38\xfc\x76\xbe\x92\x51\x65\x52\x33\xee\x9a\xe7\xaa\x2c\x74\xbd\xcb\x8e\x23\xdd\x67\x26\xb5\x22\x88\x72\xf9\x80\xcc\x8a\xe3\x0e\x8e\xa4\xa9\xbc\x76\xc4\x73\x47\x21\xb0\xed\xdf\xd5\xbf\x7d\x47\xf2\x6f\xd2\x2f\x25\xf0\x10\xe1\xb7\xfd\xbd\x57\x01\xb7\xc4\x30\x7c\x4e\x43\x6e\x79\xdd\x8d\x10\x09\xfa\xed\x74\xae\x9d\xe7\x5f\x80\xf3\xce\x3d\x48\x43\x45\x81\x40\xf4\x05\xea\x1c\xed\xfd\x29\xa3\x38\x41\xf5\xcc\xfa\x04\x2a\x13\xb9\x63\x44\xba\x77\x63\xaa\xcf\xca\x54\x94\x58\xda\x9b\x13\x4a\x87\x6a\x92\xcc\xaa\x28\x0d\xb0\xf7\x8c\xb2\x3c\xfb\x36\x3e\xfc\x6d\xd8\xcf\x51\x91\x4e\x30\x0c\x93\xe7\xcb\x22\xbf\xde\xc3\x87\xf7\x48\xc5\x51\x80\xd5\xaa\x37\x51\xbf\x41\x3d\xc8\x8a\x55\x1c\xf3\xc0\x93\x44\x1f\xcb\xa2\x8d\x00\x71\x4d\x5b\x0e\xb9\x68\x2a\x61\x0c\x6b\x13\xed\x36\x96\x15\x87\x9b\xf2\x7c\x78\x6b\x3e\xb3\x1b\xfd\x3a\x99\x50\x34\x04\xdd\x07\x41\xaf\x45\xa6\xca\xca\x72\x42\xd7\x85\xe5\x0b\xfb\x81\x46\x61\xab\xfc\x41\x14\x3a\x2f\x2b\xdd\x1b\xe1\xcc\xfe\x46\x16\xa7\xf1\x80\xc2\x07\x55\x73\x71\xae\x18\x08\x8f\x19\xdd\x3b\x96\xa4\x68\xcf\x71\xb4\x72\xed\xeb\x7a\xec\xde\xca\x14\xd7\x21\x86\x4b\xa0\xde\xca\x39\x10\x9a\xe2\x86\x20\xa1\x6b\xb1\x3e\xb4\x51\x88\x9d\xac\xff\x47\x78\xbb\x3b\x95\x10\x96\xc7\x80\xb2\x9d\xa7\xc9\x2c\x90\x91\x42\x12\x50\xaf\x65\xba\xcd\xcb\x66\xe0\x36\xf0\xc9\x49\x15\x63\x94\x0c\x80\x9c\x0e\xb7\x3a\x56\xaf\x69\x87\x29\xa4\x01\x4b\x51\x14\xa0\x11\x4f\x3f\x69\xfc\x28\x90\x41\xe2\xda\x01\x77\xd9\x4f\x2b\x45\xe7\x0f\x19\x96\x92\x81\xfb\xc5\xe8\x41\xeb\x20\x88\x65\xe4\xfa\x21\x2f\x90\x8b\xcb\xf2\x71\xb9\x9b\xe3\xb2\x8d\x2b\x66\x3a\x08\x03\xe4\x11\xca\x2a\x93\xfe\x42\x75\x10\x5b\x6d\xda\xc6\x2a\xd7\x81\x73\x62\x43\xae\x4b\xdf\x39\xd0\x41\x12\x47\xf1\xa8\x82\x8d\x8c\x47\x04\xa2\xf9\x87\xab\x09\xd8\x0e\x66\x0d\xcd\xb3\x31\xc8\x2c\x1a\xbf\xad\x93\x1f\x12\xd2\x18\xf3\x36\xec\x86\x18\xdf\x7a\xf5\x07\x75\x94\xb8\x8a\xff\xcd\xf3\x66\x3b\x7f\x86\x28\x8a\x91\xd7\x3d\xec\xd4\xdb\x00\xa1\xbf\xaa\x28\x8e\x30\x87\xee\xe9\x76\xce\x9a\xbf\x7d\xd7\x36\x15\x0c\xcc\x68\xfc\x27\x92\x04\x3b\x61\xa3\x7b\xf2\x88\xd1\x6b\x1b\x05\x0c\x2e\x32\xa2\x89\x06\xaf\x7e\xbd\x47\x7a\xfd\x5b\x79\xda\x36\x65\x05\x2f\x2e\xef\x9b\xcf\xa5\x75\x04\x0a\x05\x5b\xff\x7d\x63\x35\xed\x44\xd6\x35\x3b\x74\x9c\xd8\x55\x65\x80\x65\x29\x3f\x40\xef\x3f\xc3\xfe\x8e\xa7\xa8\x8e\x39\x0d\xbb\x9b\xe2\x9e\xe3\x6b\xd1\x43\x82\x74\x6c\x14\xd2\xfd\x16\xf9\xe9\xcd\x77\xec\x35\xa3\x14\x03\xcc\x6c\x06\x33\x35\xcc\x21\x34\x67\x14\x5f\xab\xfb\x3f\x76\x28\xd9\x68\xeb\x4b\x1d\x36\x40\xa7\x9a\x19\xe5\x8b\x1a\x38\xff\xe6\xbb\x10\x3a\x35\x46\x93\x41\x86\xbc\x44\x99\xcd\xd1\xfb\x37\xd5\xf5\xd0\x82\x07\x8e\x2a\xbc\x6f\xca\xd3\xfe\x13\x5c\x81\x16\xae\xe2\x71\x80\xe6\xf5\x34\x2c\x82\x6b\xa1\x28\xf3\x71\xf4\xf3\xf3\x83\x55\xe0\xe4\xdd\x51\x13\xf8\x12\xe1\x6a\xf7\xcd\xbd\xd3\xeb\x5e\x0f\x46\xcb\x80\x05\x91\x8b\x50\x41\x8c\xec\xfd\x98\x96\x24\x44\x5f\x14\x4c\xd6\xbc\x2b\x8c\x3f\x26\x05\x1e\xd3\x90\x43\x03\x8f\x17\x34\x7d\x99\x20\x88\xb4\x8a\x09\x42\xd0\x3b\xdf\x74\xeb\x5d\x31\x99\xf4\x2a\x96\x24\xf6\x52\xf0\x00\xfa\xe6\x7c\x3c\x0d\x0a\x5f\xba\x8d\x3a\x64\xa7\xcf\x7b\xcd\x6c\x1b\x2d\xb8\x5a\x27\x1a\xb7\x8d\x53\x99\xf5\x92\x8a\xb6\xd7\xec\x31\x4f\x3f\x66\xec\x14\x99\x06\x12\xe1\x92\x50\x89\x42\x13\xfa\xdb\x2c\x52\xc2\x0f\xe5\x31\xa2\x08\xec\xd6\x74\xdf\x23\x39\xfe\x31\xc6\xdc\xfe\xe7\xaf\x4f\x20\x66\x5f\xaf\xf4\xda\x04\x81\x15\x48\xb4\x00\xd6\x99\x3a\x99\x36\x31\xc7\x97\x42\x9e\x2f\xfb\x53\x2e\x8a\x2e\x22\xd7\x86\xaa\xc0\x73\x88\x2c\x98\x60\x39\xb9\xe1\x46\x31\x2f\xd6\xbc\x2e\xde\x33\x0b\xd0\xea\x9c\x4b\xec\x20\x08\x92\x24\x75\xeb\xd5\xef\x7f\x2e\xbd\x6e\xc3\xe8\x44\x10\x40\x88\x63\x0a\x07\x70\xae\x07\xca\x0f\x40\x42\xd1\x7b\xd2\xde\x97\x22\x47\x66\xe9\xf8\x67\x00\x49\xc2\xb8\x43\x7b\xb7\xc9\xff\xf4\x38\x35\x78\xdc\xa5\xe7\xd8\x04\x5e\xab\x72\xe8\xeb\xc1\x20\x8c\xa9\xb0\x0e\x58\xcf\x85\xef\x90\x8f\x4f\x13\xa6\x80\x1d\xab\x9b\xfc\x0c\xdf\xb2\x3c\x7f\x1c\xd6\xd8\x21\x09\x0c\x56\x44\xc4\x87\xa8\x34\x32\x32\xea\xee\x50\x44\x70\xdf\x33\xa0\xde\xfe\x28\xd1\x04\x6a\x24\x4d\x3c\xbb\x62\x41\xc2\x43\x74\xe0\x7e\x28\x0f\x16\x8a\x54\xaf\x90\xf4\x37\xe9\xb0\x42\xc2\x25\x96\x08\xee\xf3\xf2\x63\x48\x53\x01\x2a\x43\xa4\xde\x58\xf9\xc3\xa5\xb5\xbd\x99\x9b\x33\x7c\xbe\x9b\x04\x14\x82\xc8\x91\x3f\xbc\xcb\xd2\xa6\x9a\x6c\xbc\xc0\x04\x8b\x3a\x4c\x67\x74\xef\xbf\x9c\x87\xa1\xe4\x9d\xf9\xee\x8f\x4f\x13\xfd\xe1\x6b\x07\x9c\x29\x8c\xae\xb1\xea\x6b\x67\xcb\xdf\xab\x10\x00\x57\xdd\xda\x76\x03\xcd\x38\x23\x85\x34\x0c\x91\x01\xb9\x5b\xbd\x3c\x6e\xf7\x8b\xa7\xdb\xfd\xf2\xf9\xe9\x76\xbd\x5b\x3f\xfb\xd2\x07\xa4\x71\x12\xa6\x3e\x29\xa9\xf4\x52\x9c\xae\x34\x1c\xba\x91\x96\x5d\xb7\x13\x3f\xa0\xb2\xfb\xa5\x25\xee\xfe\xad\xba\x16\xa4\xc2\xe0\x6b\xb3\xae\xc7\x8c\xdc\xf1\x4d\x4d\x41\x4a\x97\x67\xae\x50\x75\xec\xb7\x6e\x31\x70\x23\x44\x40\x82\x21\xb4\xb3\x4d\xe5\x5f\xae\x49\x24\x93\x6f\x17\xc4\x50\xd7\x39\xe9\x73\x7f\xdc\x0a\xfa\x69\x23\xa9\xad\xe7\x3c\x64\xff\x7b\xce\xf4\xf6\x43\x8c\x74\xc2\x40\xea\x00\x91\x8c\x1f\x5e\xff\x68\xf6\x2b\xbb\x7b\xaf\x22\xdb\x52\xa8\x7d\x6b\xed\xd9\xbc\xd6\xb0\xeb\xfc\x75\xfc\x69\x15\x4b\x98\xf1\xac\x60\x54\x57\x5b\x4f\x5f\x63\x1d\x4a\x4c\xa3\x1a\xa7\xc9\x82\x5e\xc0\xfe\x18\x4f\x11\x6e\x75\x93\x35\xed\x82\xbd\xe9\xc0\xe8\xa0\x21\x0e\xdb\xa5\xfc\xfb\x9b\xc8\xe1\xbb\x18\xfc\x50\x20\x1c\xfb\xca\x03\xd1\x86\x31\xa6\x0a\x20\x02\x2d\x87\xf5\x07\x77\x97\x2d\xa1\x64\xfc\xc8\x8c\x88\x52\x2b\x39\x79\x39\x35\xe5\x4b\x79\x84\x51\xe9\xdb\x04\x91\xed\xe1\x9f\x44\x91\xa9\x9b\x73\xd3\x94\x43\x89\x26\x13\x18\xcb\xb5\x6c\x37\x95\xac\x38\xdc\x4e\xd9\xca\x86\x44\x09\x46\x6c\x1b\x71\xd9\x94\x65\xbe\x6a\x23\xed\x42\xc1\x1d\x8c\x6b\xaf\x86\x44\x46\x3b\xed\xb3\x77\x11\xfa\x6f\x27\x22\x46\xa1\x3e\x71\xc2\x62\xf6\xf8\xda\x0d\x01\x66\xbc\x3e\x5f\x35\xb6\xfd\x66\x26\xa4\x0c\x93\x6c\xdb\x55\x9c\x3a\x85\x31\x13\x4a\xf0\xe1\x81\xef\xd7\xb5\x8b\x5c\x75\x0d\x3d\x30\x21\x08\x94\xd5\x15\x5a\x0f\x3b\x32\xbf\x2c\xd1\x9a\x28\x92\xd8\x6b\x5d\xbd\xc3\x40\xb1\x9e\x99\x28\xb6\x9e\x24\x9d\x18\x17\x68\x2b\xcc\x3d\x28\xe5\x5e\x17\x40\x4d\xa4\x9c\x86\x04\xd4\xcd\xda\x59\xaa\xd9\xe8\xe2\xb5\x6e\x6f\xbe\x05\x35\xe8\x49\xdb\xdb\xc4\x21\x47\x75\x22\xec\xcd\xfa\xdc\x66\x7c\x27\xe3\xd8\x3a\x4b\x28\x51\x37\x28\xe2\x3c\xda\xf9\xc7\xeb\xab\x89\x29\x60\xfd\xb8\x4d\x0c\xed\xfc\xba\x41\xe2\xf5\xec\x7e\x60\x62\x15\x20\x2e\x53\x14\xea\xad\xac\xee\x45\x3d\x24\x52\x9b\x58\x1b\xb0\x80\xcb\x5a\x18\xf8\x5e\x65\x0d\x60\xa0\xf9\xdb\x4c\xb4\x6a\x92\xc0\x24\x56\x07\xa2\xcd\xd0\x7f\x1b\xfc\x55\x22\x26\xe0\x70\xc8\xee\xaa\xab\xb2\x89\x49\x22\x82\xdf\xb1\x17\x5a\x7f\x2b\x73\xb4\x3e\xb2\x2d\xfe\xb0\x1b\x11\x63\x18\x7c\x93\x97\xca\x94\xd5\x71\x72\x77\x92\x36\x67\xb2\x3d\x8e\xaa\x71\xda\x18\x03\x15\x09\xc3\x48\x42\xda\x2b\x78\xdc\x6d\x86\x6b\x8e\x61\x2a\xc6\x92\xe2\xa9\xfc\xe8\x66\x34\x0f\x04\x06\xbd\x96\xad\xf2\xb8\x7a\xc2\x62\xe3\x7e\xbd\x7c\xde\x6f\xbe\x2d\xb6\xab\xfd\xf3\xd3\x6a\xbf\x79\x7e\x7d\xba\xdd\x76\x1f\x89\x42\x5c\xd9\x8e\x65\x81\x9c\xb3\xc9\xd2\x6e\x38\xd5\x88\x3a\x3c\x64\xef\x70\x3e\xdd\x64\x93\x05\xc8\xa4\x41\x14\xbb\x99\x3e\x50\x84\xed\x1e\x67\x1a\xc7\x28\x3b\x80\x65\xbf\x1b\x5f\x59\x30\x22\x8a\x90\x54\xb1\xfa\x63\x54\x6d\x37\x32\x24\x98\xec\xbc\x8b\xfc\x0c\x3d\xee\x6f\x7a\x51\x92\x01\x5a\xef\xea\x21\x89\x65\x84\xb6\x31\x52\x47\xe8\xf1\x81\x0c\x25\x67\xde\xe9\x0f\x81\x4a\x3b\xd4\xf6\x4e\xfc\xec\x32\x40\xa3\x92\x04\x79\xa6\xed\x8f\x9d\xd2\xb7\x47\x0b\x8a\x4a\x09\x44\x7d\xfc\xfd\xbd\xac\xdb\xf5\x67\x57\xa2\x9d\xb2\x1f\x23\x59\xcc\x9c\xdf\x0d\x56\x70\x47\x8f\x4f\x49\xe6\x5a\x74\x88\xa7\xbe\x83\x81\xf2\xfe\x64\x86\xe8\x30\xc1\x52\x7b\x17\xec\x0f\x52\xf8\xc9\x48\x4a\x5c\x42\xf7\x03\x8a\x17\xd1\x00\xf1\x0d\x5c\xa3\x29\x47\x64\x5d\x7f\x92\x71\xc5\x7f\x72\x26\x13\x5a\x95\x01\x4f\xa9\x5f\x3e\x3f\xed\x5e\x16\x4b\x8f\xf3\x31\x86\x26\x08\x11\xba\x39\x1f\xb2\x7a\xdf\x0b\xd9\xe3\x61\x1e\x04\xc2\x72\x53\x10\x5b\x79\x2f\x1a\xf8\x10\x97\xee\x98\x0e\x84\xa7\x99\x7a\x97\xd1\xfd\xa0\x7b\xc2\x03\x12\x47\xd8\x48\x2c\xab\xec\x90\x15\x22\x1f\x81\x33\x79\x40\x94\x95\xc7\xbf\x2b\x4b\x9d\x41\x9f\x8b\xf0\x80\x80\xcd\x38\x97\x79\x79\xd6\x57\x51\xd2\x38\x93\x18\xfe\x5e\x1e\x84\x22\x16\x61\x67\xb3\x72\x0b\x22\x7f\x41\x78\xa2\x3f\xac\x23\xb7\xcd\x36\xce\x38\xa4\x5e\x1d\xb3\xa6\x2b\x1e\xf0\x20\x4a\x63\xdf\x72\xbd\xf2\xd7\x98\x29\x38\xf3\x20\x92\x4c\x47\xce\x3e\xda\x3d\xf7\x87\xcf\x22\x07\x3f\xf3\x79\x10\x19\x1e\x40\x27\x1b\x80\x14\xf5\x39\xe0\x03\x0f\xe2\x98\x87\xa2\x83\xc7\x0d\xd9\x5e\xe3\x97\x89\x07\xb1\xb0\xf6\x28\xde\xff\x79\x10\xeb\xfb\x11\x8a\x21\xad\xf2\x20\x8e\xb6\xef\x68\xf9\xb6\xee\x68\x12\x33\xe5\x32\x0d\xc4\x62\x16\x97\xe9\xd4\xba\x2a\x78\xf3\x80\x12\x6b\x1a\xd7\x64\x50\x85\xfe\x4c\x34\x0e\xed\x35\x37\xe2\x00\x43\xf3\x21\x1e\xb0\xc4\x92\xb1\x2d\x3e\x08\xa5\x27\xca\x0c\x21\xd8\x5d\x68\xc2\x03\x26\x84\xd4\x03\x8e\xcb\xec\xa6\xc1\x03\x6c\x0d\xd8\x44\xd6\x7f\x92\xd3\x50\x86\xbe\xed\x54\x34\x6f\x50\x67\xff\x05\xaf\x77\x37\xb9\x5f\x5c\x28\x6c\x88\xdc\xfe\xeb\xc9\x7f\x3c\x4d\x04\xb6\xa3\x8c\x52\x53\x39\x1c\x1e\xa4\xd2\x66\x62\x35\xda\x49\x1c\xc1\x79\xbf\x09\xd7\xe1\x70\x95\x7d\x1e\xa4\xca\x92\xdc\x75\xb9\x2e\xd0\x9b\xa1\x9b\x7d\x32\x89\xbd\xec\xdb\xa6\x02\x07\xb5\xd4\xab\x5d\xb9\x7b\x83\xc9\xc5\x49\x11\x59\x81\x42\xdb\xa8\x42\x28\xfd\x28\xf2\xe7\x81\x94\x86\xf1\xc1\xf3\x5e\xeb\x4e\x77\x63\x51\x68\x0b\x27\xf8\xaa\x6e\xc4\x03\x69\x82\xc0\x17\x6f\xf1\x29\xdd\x5c\x76\x70\x3c\xe5\x53\x00\x32\x0f\x14\xe5\x54\x0f\x00\x8d\xb8\x3d\x7b\x04\xcb\xfc\x0c\x57\x4c\xa0\x5a\xa4\x38\x37\x6f\x50\x34\x99\x12\xfd\x8d\xd0\x3c\x22\xb6\x7d\x65\x21\xed\xee\xcf\x90\x40\x1c\x3b\xe9\xf5\x0e\x1e\xf5\xb9\xc3\x19\x0f\x80\xdb\xcc\x48\x0e\xbd\xbb\x51\xbd\xb8\x9d\xbd\x57\xab\x6b\x5f\x28\x75\x9f\x37\x51\xc0\xad\x97\x9d\xfe\x86\x05\xfd\xc9\xcf\x36\x11\xc3\xb6\xe2\x7b\x06\x1f\x2f\xc2\xeb\xbd\x71\x42\x42\x8a\xf3\x64\x55\x55\x65\xf5\x50\x1e\xe6\x0a\x2d\x9c\x10\x4a\xb8\xa3\x61\x6c\x4f\x99\xa7\x10\x73\x42\x38\xb5\xe5\x9c\xec\x80\xf5\xb4\x42\xa3\x23\x0a\x54\xf5\xea\xf6\x75\x08\x59\xe5\x24\x64\x3c\x02\x8f\x06\xb3\x81\x1b\x0a\x88\xd4\x7e\x40\xe4\x54\x4e\x2a\xd0\x00\xc7\xe7\xaa\x7d\x93\x90\x2d\xba\x2b\x67\x3c\xb7\xfd\x87\x42\x1e\xf1\x4e\xfd\x13\x81\xa7\xee\x6b\x3f\x19\x2f\xba\x10\xfa\x7b\x56\xc0\x5a\xb7\xcf\xd3\x64\x50\x2d\xae\x96\x39\xff\x09\x09\x58\x74\x73\x55\x89\x7b\x71\x1c\xbb\xdf\x71\x12\x87\x36\xe4\x3f\x54\xa2\x68\xbc\xfb\xe3\x8c\x18\x3e\x27\xb1\xb0\x9c\x0c\x6c\x80\xf7\x11\x15\x27\xb1\x64\xd4\x95\xc5\x6e\xaa\x4c\x1f\xe0\x7b\xa6\x9b\x71\xfd\x84\x93\xa4\xdd\x4c\xda\xb0\xec\x43\x9c\x7c\x8d\xc6\x1f\x22\x1c\xc1\xc4\xdb\x6f\xdb\xc1\x96\xde\xfe\x3d\x8d\x2c\x4d\xca\xd9\xa4\x5a\xe2\x69\xd7\x37\xe8\xa6\x41\xe2\xe8\xf6\x4f\xab\xa7\xe5\x75\x09\x8a\x93\x44\x31\xe4\x44\xfd\x5e\x5e\x4a\xff\x19\x1a\x6b\x8c\xb3\xb7\xf7\xb7\xf5\xe8\x5b\x69\x62\x4d\x0c\x34\xa8\x3c\x2b\xd0\x10\xcd\x1f\xd1\x31\xc2\x26\xb3\xf6\x89\xba\xbf\xb1\x88\x20\xce\xd2\x51\x81\x7e\x25\x0b\xd4\x07\xc8\x9c\x30\x6e\xec\x47\xb5\xfe\x54\x1b\x80\x13\x66\x0c\x06\x06\xbe\x21\xbb\xf3\x9d\x5a\xab\xba\xdf\xae\x11\xd5\x04\xbc\xc8\x09\xa7\x09\xca\x94\x65\xb5\x45\xd7\xdd\x55\x00\xf8\xd4\xe7\x8b\xe2\x9c\x70\x9d\x06\xac\x93\xe5\xb5\xee\xc5\x73\xd6\xda\x6e\x78\x1a\x0b\x04\xce\xb4\x41\xfa\x13\x7c\xb8\x6d\x0a\x65\x32\xaa\xc9\xbb\x4b\x52\xae\x10\xe9\x6b\xad\xf6\xda\xe8\xf1\xbe\x2c\x5f\xa0\x06\x51\xa9\xb7\x36\xca\xf3\xb7\x32\x4d\x39\x6a\xe1\xda\x5a\xe5\x13\x7c\x6c\xca\x3c\xff\x4c\xe9\x7a\xf2\x1d\x60\xb5\x8f\xb6\xd9\xf1\x94\x3b\xa2\x97\x3f\xad\x08\xac\x72\xf0\xee\xe5\xf9\x69\xfd\xaf\xfb\xe7\x87\xdb\xee\x08\xb3\x24\xb4\x0e\x40\x1e\x75\x47\x24\x60\x69\xe4\xa5\x2c\x44\xae\xcb\x81\x54\x1b\x27\x02\x68\xda\x1b\x20\x60\xa2\x0e\xf3\xb8\x3d\x4e\x54\x48\x90\x21\xbc\x5d\xfd\xeb\xcf\xe5\xb3\x87\xd2\x70\xa2\x40\x39\x38\xcb\x50\x6a\xbe\x9f\xd0\x3a\x89\x63\xab\x76\x3c\x78\x4d\xb4\xa4\xf1\x28\x48\xb7\xe5\xd6\x45\xa1\xb1\x48\xf1\x65\x9c\x43\x00\x28\xca\x41\xe4\xa2\xb6\xd1\xc6\xfe\x3d\xf0\x27\x36\xb1\xc4\xd5\xfb\xe5\xe5\xe5\x79\xf4\x2a\x18\x48\x91\x60\x77\x7b\xf8\x79\x0b\xc7\x73\x55\x89\x03\x2c\x5d\x33\xa7\xbc\x46\x92\xce\xde\x83\x30\x08\xb8\xa7\x60\xac\x7e\x36\x50\xd4\x59\x59\x58\x19\x3b\x31\x50\x75\xf2\x83\x05\xc5\xe6\xa0\x12\xc5\x50\xf8\xcb\x1d\x25\x3c\x25\x56\x19\x1c\x81\x31\x4e\xb2\x63\x78\x9a\x7f\x4c\x3f\x60\x75\x4d\x6c\xc5\xae\x29\xab\x21\x78\x77\xb6\x9b\xcb\x43\x92\x72\x44\xd2\xd4\x27\x28\xc6\xda\xe3\xe3\x5b\x1a\x86\x21\x4f\xdc\xea\x8d\xbe\x66\xcf\xc5\xba\x68\x63\x09\x81\x7e\xa8\x5d\x4c\xd2\x07\x69\x61\xa8\x01\x73\xa8\x1f\xef\xcd\xf0\x3e\x87\x51\xc2\x78\x47\x78\xe8\x17\x97\x30\x4a\x29\xb8\x5d\xe7\xde\x86\x8a\x8d\x07\x0c\xf1\x30\xd2\x94\x0e\x51\x13\x63\xa6\x77\x7b\xdc\x60\xd0\xdf\x40\xdd\x6c\x3c\xf6\x9b\x87\x31\x51\x84\x76\xd5\xf2\xeb\xbd\xd9\xef\xc9\x61\xac\x39\x7e\xb9\x3c\x5f\x48\x10\xdc\x8a\xf2\xae\xac\xc8\xca\xc3\x4e\x79\x18\x83\xf0\x10\xda\x6f\xd9\xe1\xcd\xa2\xd0\xdc\x31\x4a\x65\xe8\xbd\xcc\x45\xef\x2d\xe1\x8e\x32\x6d\x03\xb3\xbd\x7d\x85\x6e\xff\x3f\xca\xde\xac\xb9\x71\x1c\xd9\x1e\xff\x3a\xfd\x70\x1f\xb8\x82\xc0\xa3\x2c\xcb\x55\x9e\xf6\x36\x96\xaa\xab\xe7\x7f\xe3\x86\x22\x01\x24\x64\x8e\x29\x52\x43\x52\x76\x79\x3e\xfd\x3f\x98\x00\xb8\x89\x76\xf7\x6f\x1e\xa6\x3a\x0c\x90\x22\x41\x2c\xb9\x9c\x3c\x07\xca\xd7\x4f\x2c\x5c\x77\x01\x0f\x90\xc9\x91\xd5\xd3\x1f\x01\x55\x3d\xbb\x35\x4f\x4c\xcc\x2e\x21\x19\x8b\xdb\x07\xbf\xd4\xae\x58\x76\x6d\xfc\xbd\xd3\xd4\x66\x62\xe1\x88\xd7\xf8\x86\x45\x75\xea\xcf\x6b\xdf\x45\xa6\x96\x4e\x19\xeb\xb7\x5c\xf5\x06\xef\xd5\x72\x15\x3c\x27\xce\x4a\x57\x34\x6d\x8b\xad\x17\xf0\x79\x3c\x12\x61\x48\xa9\xfb\xab\xf3\xc7\x43\xf5\x6e\xb5\x1a\xfe\x4e\xe1\x1b\x8f\x04\x4b\x60\x8c\x20\xbd\xa9\x6a\xf2\xa8\xa7\x4f\x21\x04\x90\x2a\x92\xdd\xf8\xb1\xd4\x63\xcc\x23\x8f\x84\xb6\x1c\xd1\xad\x47\x47\x3d\x96\x38\x9a\x07\x92\x19\x26\x16\x38\x13\xff\x63\x43\x43\xae\x97\x4a\x23\x35\xd6\x31\xec\x99\x05\xbf\x26\x9e\xe0\x91\x92\x8a\xfc\xc0\x73\x43\x42\x25\x38\x4b\xca\xf3\x48\x99\x00\x98\xfb\x2c\xb6\x7a\x63\xe6\x60\x44\x3a\x16\xc4\x88\x7a\x2a\xa0\x1c\x3b\x41\x91\x66\x01\xcd\xab\xf5\xf3\xe3\x76\x75\xfb\xbc\xff\xe3\xf1\xc7\xfa\x3b\x95\xe5\xdc\xae\x37\x7d\x27\x29\xe2\x81\x29\x7e\x8c\xbd\x71\xb9\x9d\xd9\x8f\x99\xc0\xab\xe1\x0d\x80\xb9\x65\x39\x4a\x1e\x61\x1a\x65\x4e\x07\xe7\x1b\xa1\x94\x29\xb1\xf4\x37\x41\x17\xfe\x1e\x8e\x09\x72\x41\x00\xfb\xff\x29\x99\xc7\x23\x93\x58\x6f\xa0\x3a\x79\xd1\x2b\xdf\xc0\x13\xf2\xd0\xdc\x82\x7d\x82\xa6\x39\x55\x75\x3b\x7b\x19\x03\x40\x50\x41\xeb\x4a\x2f\xd8\x61\x91\x51\x81\x30\xf4\xa8\x79\xf9\x47\x5e\xc0\x08\x73\xcb\x23\xa3\x39\x85\x38\x5e\x3f\xd4\xf2\x6a\x89\x83\xc0\x78\xa0\xfb\x7a\xf5\x38\xe1\x1c\xf7\xbb\x56\x1c\x44\xc2\xc3\x48\x7f\x34\x58\x97\x70\xc4\x4f\xf0\x7c\x3c\x0e\x44\x40\x30\x39\x20\x59\x95\xdb\xe3\xb1\xaa\x5b\x28\x9a\x5d\xe5\xd8\xbd\x27\x0f\x1f\x07\xca\x52\xc4\x92\x1d\x53\xe7\xcd\xab\xea\xcc\x7b\xbb\xfe\xfd\x34\x8f\xc3\xc0\x90\x25\xfa\x8e\xf9\x7d\x5e\xe6\xc7\xf3\xd1\xad\x68\xdf\x0e\x9c\x62\xcc\x57\xe7\xfa\x80\xf5\xef\x70\xca\xff\x0d\xbe\x2d\x62\x19\x25\xa6\x4e\x50\xb7\x13\xa9\x73\x1e\xc7\x61\x4c\xf9\xa0\xfb\xaa\xc6\xd5\xad\xff\x6b\x1a\xa4\x64\x10\x58\xc1\xd8\x47\x33\x7b\xe0\x34\x0e\x03\x6f\x96\x77\x27\xfe\x75\x45\x14\xfc\x4d\x0b\xc7\xd3\xac\x2b\x0b\x6c\x59\x89\x0b\x66\xfd\xb6\xc0\xc4\xc4\x63\x06\x4c\x47\xfd\xc9\x41\x32\x65\xcd\xd5\xb9\x78\x9d\x01\x60\x78\xff\x2d\x98\x8e\x49\x63\xe6\x1f\x70\x82\xf2\xad\x79\xaa\x8a\xc1\x75\x8b\x99\x41\xe6\xac\x5f\x4a\x94\xb7\xed\x28\x16\x3e\xfd\x4e\x19\x0b\xd3\xc4\xcb\x4e\xd0\x06\xe4\x08\x57\x67\x6f\x91\xa1\x70\xe1\x8a\xf6\x5b\x55\xad\xab\xa6\xbd\xa9\xea\x1f\xe5\x27\x09\xc9\xe1\x3a\x0e\x01\x21\x43\x41\x56\xe7\x76\xcc\x5c\xe3\xda\x21\x14\x44\x01\x22\xcf\x1f\x0e\xdc\xf5\x33\x6f\x5f\x36\x73\x17\x27\x96\x32\xea\x43\x44\x79\x59\xd5\x1b\x9d\xb7\xcd\x05\xb4\x95\xc7\xca\x84\xdc\xf8\xe7\x7c\x6b\x57\xa7\x93\x37\x86\x5c\x8c\x66\x32\xec\x18\x43\xea\x50\x71\xe4\xed\xcf\xf4\x6f\x78\x8c\x89\x74\xe4\x53\xf2\x98\xb7\xcf\x63\xc2\x9c\xe4\xff\x16\x9c\x6e\xf6\x7f\xb3\x83\x8f\xff\x6f\xe8\xff\xc4\x29\xa6\x34\x7c\xc9\x11\x3e\x60\xf8\xaf\xf1\x0d\xc3\xfe\x29\x04\x90\xd6\xc2\xa0\x9b\xd7\xdc\xd4\x4e\x4e\xd1\x9e\xd7\xaa\x0d\x7e\x3d\x60\xfb\x5e\xd5\xaf\x13\x70\x99\xbf\x01\x02\x59\xe3\xfe\x84\xb8\xc6\xb7\xe6\x25\x3f\xcd\x7a\x19\x16\x4a\x1b\xe5\x33\xe7\x52\x5b\x80\x77\x73\x5b\x3e\x57\xd5\xfc\xab\x19\xa5\x63\x47\x4a\x74\x07\x0d\x69\x42\x5d\x43\x4b\x54\x33\x9f\xec\x2f\x06\x13\x8a\x94\xf8\x27\xa0\xa7\xa4\xd0\xca\xf8\x41\x2e\x2e\x62\xda\x81\x18\xd6\x58\xb6\xcd\x13\xd6\xf7\x55\x39\x9f\x1b\x49\x10\x33\x31\xd2\x08\xb1\x87\xf8\xb4\x87\x66\x14\x14\x3c\x97\xaf\x65\xf5\x5e\x7a\x78\x9b\x5b\x2f\x49\xc8\xe2\xc4\x99\x5b\xd2\x59\x55\x67\x2f\x4d\x3e\x65\x5a\xe4\x49\x28\x38\xd5\xb1\xb7\xf0\x51\x54\x63\x76\x70\x9e\x44\x61\x62\x03\x02\x54\x18\xe0\x0e\xfa\xc1\x44\x4d\x22\x95\x12\x8d\xcb\x09\xdb\x11\xf3\xea\xf4\x5d\x62\xa6\x48\xd5\xd1\x8f\x93\x87\xd6\x5e\xd8\xd2\x49\x77\xf0\xb2\x1e\x12\xba\x6f\x6b\x0f\xab\xe7\x49\x92\x44\x64\xbe\x6e\xb6\xbb\xaf\xc2\xba\x49\x82\xa1\xf2\xf8\x37\x82\x29\x2d\xe5\xc4\x78\x92\x3a\xd6\xa7\x1e\xd2\x04\x9f\xae\xfa\xaf\x4f\xc1\x24\x0b\x43\x65\x05\x1d\x9b\x16\xb5\xdb\xbe\xa7\x3f\x96\x85\x16\xb9\x03\xed\x0b\x96\x39\xf8\x04\x33\x4f\x32\x1e\x64\x36\xe0\x5a\x9d\xbe\xc1\xf1\x1b\x4e\xec\xfc\x24\xe3\x80\x59\xbf\x41\x74\x4f\xb9\xb8\xe1\x25\x22\xd5\x6c\x18\x36\x2b\xb1\x38\x7d\x48\x91\x89\xc4\x71\x8f\x75\x53\x61\x5b\x9d\x6b\x85\xb3\x53\x6e\xf6\x2d\x80\x25\x9e\x83\x87\xce\x5d\x07\x35\x9c\xdd\x18\x4c\xa0\xb1\x7f\xc4\xee\x00\x3b\x5d\x20\x90\x78\x22\xc3\x98\x50\x2a\xa6\x2a\x8a\xea\x7d\xde\x28\x2c\xf5\xe3\xe9\x5c\x14\xbb\x17\xec\x0e\x0a\xef\xc3\x26\x12\x80\xd8\x73\x09\x68\x1c\xd2\x73\x0c\x72\x39\x3c\x91\x32\x0b\xe4\xe0\x37\xec\xc3\xac\x6f\x31\x40\x45\xc7\xbd\x54\xdb\x6d\xa9\x73\x35\x63\x5c\xe1\x89\x8a\xe3\x38\x75\x1e\x62\x5e\xa3\x1e\x52\x40\xbe\x43\x92\xd0\x2f\x5c\xdf\x6e\x77\xcf\xb7\x57\x3f\x48\x27\x60\x20\x35\xec\x3a\xe8\xc8\x56\x8f\xd1\xfa\xbb\x41\x6c\x6e\xcb\xab\xd3\xfc\x87\x74\x20\xc3\xc8\x6f\x77\x57\x1f\x4f\x75\x55\x99\xdf\x96\x36\xcb\xe9\xd8\x68\x29\x08\xa2\x37\x22\x75\x98\xe5\xba\x79\xa2\xb5\x2d\xe5\xf8\xc7\xfd\x7e\xb3\xfb\xbe\x9f\xe8\xe1\xb8\x2e\x18\x24\xca\x59\x42\x50\x1f\xf6\xd1\xec\x0e\x18\x49\xaa\x28\xbe\x7f\xb8\x1b\x65\x03\x79\x82\xa9\x2d\xc8\x1e\xc4\xe9\xe6\x94\x0e\xae\xa3\x49\xb9\xd5\x4f\x73\xf3\xd3\x5a\x18\x7d\x2b\x20\x41\x76\x5e\xa0\x79\xa1\xd9\xd7\xd6\x23\xa7\x62\x86\x2c\xb3\xd7\xa4\x41\x6c\x88\x3d\x6a\xa5\xff\x7d\x6e\xda\xeb\xdc\x98\x5c\x9d\x8b\x19\x0e\x8f\xa7\x21\x0b\x98\x5b\xed\x37\x88\xa3\xe8\x50\x1a\x29\x1b\xa7\x94\x64\x9b\x35\xbb\xbc\x28\xac\x99\xb6\xae\xaa\x42\x57\xef\x7e\x91\xa5\x31\xe3\x91\x22\xe1\xe1\x8f\xc9\x41\xda\x35\xf8\x38\xfd\xe3\xfb\x25\x89\xa2\xeb\x95\x48\x15\xb9\x05\xf0\x63\x7b\x3d\x7b\xbc\x34\xb6\x94\x7f\x76\x61\xfe\x8e\x97\x98\xe5\xe5\x9b\xa6\x4c\xc5\x30\x1a\x4f\xee\x31\xb7\x3e\x55\x93\xa6\x19\x23\xac\xb7\x2b\xd9\xd8\xe2\x4c\xbe\xca\x77\x93\x96\x57\xe1\x1b\xb6\x9b\x46\xd5\xd5\xfb\x43\xe5\x22\xc0\x93\x0f\x98\xa6\xca\xd0\x61\xfa\x54\x57\xbf\x3e\x2e\x04\x2e\x78\x9a\x6a\xa5\x7b\xc6\xc6\xee\x99\xea\x6e\x1b\xdb\xcb\x8f\x7d\x7e\x51\xfe\xc8\xd3\xd4\xc4\x34\x26\xaf\xf8\xd1\x3c\xa3\x9a\xb5\x66\x22\xa1\x1d\xfa\x7e\xf5\x6d\xf3\x70\xbd\xfa\xe3\xd6\x07\xd8\x52\x91\x59\xe1\x3a\x38\x9d\xb0\xd4\xbf\xa3\x2b\x64\x59\x4a\x21\xa4\x42\x33\xa2\x02\xaa\x41\xa9\xaa\x68\xe1\x1e\x9b\x06\x0e\x07\x9f\x51\x4a\x41\x5a\x7c\x55\xaf\xe9\x3b\xe4\xa9\x52\x40\xc6\x1c\x92\xa9\x27\x3e\x2f\xcb\xca\xc2\x05\x67\x2b\x37\x05\x13\x2a\x7f\x60\xbf\x40\x5e\x3e\xd5\xf8\x36\xeb\xa2\x02\xa4\x52\xb0\x1e\x7e\x74\x4f\x02\x18\xcb\x87\x5c\xaa\xb4\xe5\x92\x6b\x0f\x93\x5a\x66\x9e\x6a\x6e\x81\x89\x16\x15\x37\xa7\x2d\xe1\xa9\x36\xb1\xa5\x11\x70\xe2\xa2\x8e\xf4\x7c\x36\xbc\x18\x65\x04\x7d\xe9\xfc\xeb\xed\x59\x8e\xc0\x22\x3c\x45\x81\xf4\x61\xba\xd3\xe4\xe1\x66\x37\xbb\xbf\x01\x4c\xdc\x9b\x5e\x61\x4b\xa9\xe3\xd9\xbd\x8d\xe4\xe4\x3b\x5b\x29\x8e\x78\x7f\xbf\xfa\x73\xbd\x7a\xfa\xad\x6f\x45\x42\xb0\xb8\x1a\x89\x9e\x9b\xdd\x02\x68\x7d\x27\x84\x54\x79\x7e\xee\x75\x91\xbb\xd8\xbe\x9f\x89\x2c\x8c\x19\x0d\x02\x1c\xb0\x6c\xa7\xb3\x94\x85\x2c\x24\xa8\xc6\x5d\x75\xb8\xc6\xa6\xad\xab\xd9\x76\xc0\x42\xc4\x80\x7b\xdd\xa5\xab\xf3\xc7\x1a\xea\x25\x94\xb2\xdf\x65\x58\xc4\xa3\xc8\xd9\xca\xdf\xab\xd9\xbd\x22\xec\x83\x69\x9b\x37\x28\xce\x34\x39\x5c\xb6\xcd\x3a\xde\x58\xdf\x5e\xff\x36\xbd\x1f\x5a\xf2\x52\xcb\x2f\x76\x95\xb7\xc7\x9e\x73\x98\xb3\x38\x48\x30\x19\xb0\xaf\x9d\xb5\xfb\xad\xe7\x52\xe0\x2c\x4e\x62\x8a\x1b\xf4\xb9\xfc\x69\xf9\xcf\x79\x6c\xb7\x4d\x67\x14\xa3\x60\xef\x48\xfe\xda\xc6\x79\xa7\x63\x97\x24\xa9\xcf\x1d\xad\xb4\x9d\x38\x97\x58\x61\xce\x12\x21\x23\x57\xd8\x57\x95\x4d\x5b\x9f\x55\x4b\xb4\x70\xbd\x61\xc9\x52\x69\x68\x6f\xfa\x77\x95\x97\xce\x3c\xef\xfd\x07\x47\xd4\xc5\x19\x43\x45\xfc\xb5\x24\x54\xe0\x0f\xaf\x05\x2b\x9e\x65\x81\xa2\xaa\x27\x2f\xa8\xba\x87\xe9\x63\x67\x49\x48\x45\xa4\x55\xb9\x3d\xcb\x07\x7c\x5f\xce\x74\xb1\x8c\x59\x0a\xbc\xbe\xb8\xb7\xac\xde\x4d\x01\xaf\x3e\x7b\xd5\x0d\xf6\x1f\x39\x7c\x82\xb9\xf8\x14\xe4\xc5\x19\x17\x11\x79\xba\x58\xea\xdb\xf5\xe3\xb6\x85\x03\xfa\xa8\x3f\xe3\x22\xa3\x68\xcc\x4d\xfe\xeb\x0a\xdb\x90\xf9\xbf\x8b\x48\x01\xeb\x55\x55\xfb\x90\xf3\x28\xfc\xc3\x7d\xcf\x24\xf4\x44\x53\xd7\x79\x73\x3a\x3b\x81\xe4\x91\x89\xc3\x04\x5a\x31\x97\x1f\xdb\xcd\x6c\x68\x84\x31\x84\xd5\x2e\xf1\xfd\xb6\xc5\xb1\xea\x1e\x67\xc0\x12\xf2\x96\xff\x79\x3d\x36\x28\x99\x4c\x0d\x19\x94\x80\x85\xb9\xc6\x37\x0f\xa0\xf5\xcd\x2a\x05\xaa\xa1\xbc\xab\x0e\x37\x88\xbb\xea\xf4\x63\xe6\xf8\x33\xc5\x84\x53\x73\x6d\xd7\x2e\xe4\x3e\x38\x03\x4c\x41\xe2\xb1\x63\x2e\xc5\x63\x37\x70\xd7\xac\xb5\x7d\xa8\xab\xdd\xef\xfe\x4f\x18\xe8\xcc\x17\x4e\x57\x27\xa2\x16\x59\xc0\xfb\x70\x86\x91\x1c\x99\xeb\xdf\xcb\xe6\x8a\xd4\xeb\x2f\x7c\x4c\x1f\x4b\x60\x18\xdb\x8c\x88\x0d\x42\xda\xea\x17\x57\x0c\xd5\xff\x36\x13\x3d\x37\x38\xd5\xc8\xd0\xd8\xf7\xea\x51\x9c\x21\xa6\x64\xb3\x0d\xe8\x9a\x2f\x3d\x01\x66\x62\x66\x62\x2a\xc9\xb5\x19\xdf\xc5\xee\xfd\x5e\x61\x94\x26\x1e\xdf\x6e\x9f\x5e\x3b\x31\x8b\x66\x62\xff\x67\x41\xc0\xd5\x20\xbf\xed\xc2\xf9\x97\x60\x8e\x2c\x94\x4c\xb8\xef\x46\xa4\x78\x7f\x07\xf5\xdb\x5d\xa5\x75\x36\xe6\xf5\x24\x16\x12\xd2\x50\xa1\x42\xe3\xbf\x77\x97\x28\x34\xe0\x2c\x30\xcb\x17\x47\xbb\xe4\x0c\x65\xc9\xb3\x48\xc6\xa8\x7c\x0d\x6f\x55\x5c\x9f\xcb\x03\xba\xa3\xcb\x8f\x48\x16\x27\xd6\xd8\x2d\xdd\x99\xec\x75\x0e\x49\x75\x2b\x0d\x1c\xef\xc4\xb4\xd4\xbb\xbb\x4a\x91\x92\xd1\x63\xb9\xa8\xa1\xdb\x0d\xd3\x5f\xbc\x42\x8c\x68\x61\xe1\x36\xfc\x4e\x2c\xd7\xf5\xb2\x8e\x19\xcf\x92\x88\x51\xa9\xff\x09\x0f\x87\x02\x65\xd5\x3f\x47\x12\x0b\x0a\x9f\x1d\x2b\x8d\x23\x0a\x4e\x9e\xa5\x11\xa6\xdc\x83\x1d\x5c\x88\x7f\x88\x43\x4e\xb7\xf2\x2c\x75\x34\x62\x07\x6c\x6d\xc4\x6c\x1c\x80\xce\x52\xa1\xd0\xb5\xde\xbc\xdc\x57\x25\x5e\x64\xfe\x3f\x79\x45\x16\x18\x52\xa0\x7c\xc0\xf7\x95\x52\x35\xea\xbc\x45\x7d\xa1\x1f\x39\x7d\x14\x16\x85\xc6\x8b\x22\x97\xe7\x93\x55\x2b\xf2\x6d\x2a\xa4\xc3\xea\xe6\x79\xb5\xde\xef\x1e\x9f\xfa\xbf\xeb\xde\x8e\x24\x76\x44\x3b\x99\x74\xf3\x95\x16\x0b\xcf\x18\x06\xa9\x4b\x8a\x8f\xf1\xc9\x5d\x83\x0f\x96\xa8\x73\x9d\xb7\x16\xf0\xfc\xc7\xb8\xb2\x8b\x67\xcc\xf0\xd0\x43\x7d\x69\x87\xbd\xaa\xce\x7d\x9d\x3c\xcf\xb2\x30\xa2\x5c\xbe\xf2\x5c\x5f\xfd\xfa\xce\x32\x6e\x2d\xa5\x66\xa8\x97\x1c\xa6\xcd\x42\xf1\x01\xcf\x78\x1a\x10\x02\x64\xc8\x8a\x9a\xe4\x3b\x34\x2f\x7b\xf7\x3e\xfe\xce\xdc\x24\x91\x8d\x3a\x39\xd2\xa3\xdb\xf2\xcd\xa9\x65\xf4\x0f\x26\x00\xa8\x8f\xc9\xeb\xa6\x25\x3e\x36\x8b\x82\xf6\xcd\x4a\xd0\x66\xd2\x22\x1c\xd7\x45\x6e\x8c\x6f\x80\x34\xb1\x8c\x37\x50\x14\xb7\x4e\xb2\xed\x6f\xf1\x90\xf2\x0c\x32\x46\x58\x52\x5b\x2e\x47\x5e\x62\x3f\x4b\x25\x53\xe4\xc7\xd2\x59\xdf\xd3\x9f\xf8\x46\xb4\xe1\x83\xe3\x38\x46\xed\xc8\x6c\xf5\xd0\xc9\xa4\x8c\xb8\x14\xf4\x85\x3a\x08\xcf\x94\x3b\xe8\x3b\x27\xd0\x9f\x8a\xfd\xfd\x75\xcc\x09\x4f\xea\x89\xe3\x6d\x46\x7e\x52\xc6\x3e\x7b\x15\x9d\x58\x65\xf0\x3e\x13\x76\x85\x25\x9a\x5c\xe5\x50\xe7\x1e\xba\x36\xbb\x02\x6c\xfe\xf3\x7e\x5d\xe5\xe5\x64\x9b\xd5\x5a\xd0\xaa\x6a\x8a\x6a\x06\xbf\xe5\x19\x06\x21\xe5\xba\x6e\x77\x8f\x9e\x8d\xfe\x69\xf3\xbc\xde\x3c\xec\xfc\xd5\x98\x59\x56\x92\x6d\x5e\x1e\xce\x05\xd0\x34\xc5\xa6\x4d\xfa\x76\xb0\x78\xfd\x7f\x7f\x9c\xd4\x88\xc1\xa1\x9b\x7b\xa9\xb0\x6e\x31\xd5\x76\xec\xc8\x65\x70\x6d\x26\x09\xc9\xb4\xf8\x56\xd5\x79\x51\xc0\x92\x1e\xfe\x72\x3a\x9a\x07\x3c\x25\x94\xc8\x91\x88\x88\xa6\xd6\x16\x0f\xc3\x8c\xaa\x7e\x75\xde\x90\x5f\x44\x90\xec\xe5\x11\xe6\xa1\xdb\xb6\x7c\xfc\xa7\x67\xf5\xf3\x80\x39\x1e\xc6\x48\x55\x17\x50\x14\xa3\x1a\x1f\xce\x23\x13\xd3\x8e\x7c\x82\xba\x2d\xb1\xee\x45\x9b\xc7\xc6\x00\x8f\x8c\xc5\xd8\xe0\xaf\xbc\x1d\x09\x35\x70\x1e\x03\x62\x34\xae\xae\x6a\x26\xc2\x7d\x9c\x27\x61\x4a\x8a\xe4\x17\x3a\x85\x73\x9f\xfa\xeb\x81\x4a\xb8\x75\x36\xdd\x64\xb6\x3a\x05\x8b\xeb\x86\x27\x9a\x51\x94\x08\xc6\xb4\x68\x9c\x27\x26\x0e\xc6\xca\x85\xbb\xea\xd3\x47\x19\x99\x94\x3c\x65\x48\xa1\x29\x4b\x3a\xbb\xf9\x4f\x6a\xcd\x98\xf4\x7f\xc6\xff\xf8\x2d\x87\xa7\x59\xc6\x6d\xe9\x04\x1d\xcf\x1a\x41\x17\x79\xd9\x8f\x56\xaa\x90\xa0\x00\xf0\x76\xa0\x6f\x70\xe5\x97\x8d\x6f\x37\x3a\xd6\x0e\xe6\x3c\x05\x27\x2c\xbf\x2a\x93\x61\x68\xe3\xbd\xaf\x9d\x03\x70\xbe\x34\x26\xa6\x8f\xc7\x94\x65\x89\xa2\x2d\xe5\x0e\xf5\xb0\xa3\xf0\x2c\xb1\x89\x46\xed\x73\xdf\xcd\x64\x73\xe7\x59\x96\x11\xb3\x4b\x83\x2d\x61\x95\x9a\x99\x9a\x86\x0b\x86\xf5\xff\xd1\x27\x8a\x78\x26\xac\xe9\xf4\xff\xcc\x51\x36\x7d\xd7\x0c\xe4\x50\xc7\x37\x2e\xbc\xe3\x9c\x87\x9c\xeb\x01\x17\x70\x57\xa9\x57\xc2\xba\x8d\xb7\x34\xce\x59\x94\xd8\x18\xfd\x19\x1f\xeb\x1b\x28\x7a\x88\x1b\xe7\x5a\x11\x4b\xc4\x7f\xf6\x9d\x79\x37\x89\x2b\x75\xd3\x8e\xec\xce\xe6\xac\x2b\x5f\x3d\xe7\x9b\x94\x95\xab\x79\x82\x8f\xfc\xbf\x3e\xd1\xc7\x21\x4c\xa9\x5a\x48\x5b\xb6\x90\x5d\x8d\xd8\x3c\x55\xef\xc3\x48\x43\x96\x10\xbc\x8a\x12\xe9\x5e\xa6\x81\x38\x0e\xa6\x53\x1e\xd0\x90\xef\xfd\x73\x75\xbb\x1b\x91\x6c\x70\x2e\x53\x3b\xc9\x50\x55\x3e\x91\xe0\x89\x2d\xfa\x2e\xc2\xd0\x89\x7f\x57\x1d\xa6\x98\x8a\xcf\x24\x5f\x39\x97\x90\x10\x2a\x6a\xfd\x78\xfb\xe0\x74\x31\xf7\xf7\xbf\xef\xf6\xbb\xc7\xdd\xea\xce\xdf\x17\x23\x4e\xba\x61\x4d\x5b\x9d\xf6\xd0\x83\xe7\xb8\x89\x54\xec\x2a\x45\xab\xee\x24\xfa\x8c\x6b\x72\xe4\x4e\x71\x13\x2b\x6d\xe5\x90\x9b\x97\xfc\xb3\xa7\x32\x29\x27\x64\x01\x68\xed\x80\x5f\x74\xab\xbe\x59\x06\x30\x8a\xe7\x3a\x86\xfe\x09\xe7\x19\xe7\x06\xed\xde\x51\xe2\xfb\xbe\xed\xbe\x60\xeb\x52\xdd\xfa\xc2\x80\x98\x7c\x01\x11\xa4\x92\xaa\x55\x8a\x73\x31\x26\xa9\xe4\x22\x60\x9a\x72\x91\x83\xd3\x3f\xa7\xd8\x9a\x38\x44\x22\x10\x92\xb9\xe0\x24\x1d\x2a\x3f\x88\xd3\xbc\xb7\x6d\x44\xa0\x33\x2a\x5d\xc3\xa6\x3a\x8d\x98\x7b\xb8\x08\x55\x4c\x8c\x47\x6f\x55\x8b\x93\x84\x92\x88\x24\x92\x71\x63\xb5\x5e\x9e\x6a\x7c\xcb\xab\x73\xf3\x5c\xf5\xdf\x44\xc4\x82\x11\x9a\x78\x40\x94\x2d\x92\x19\x8c\x3e\x89\x48\xe2\x14\xf9\x84\xd6\xba\x6a\xa1\xe8\xeb\xfc\x64\x81\x4b\x19\x13\x91\x38\x08\x06\x65\xd3\x88\x81\xb8\x3d\xd7\xa3\x5f\xf3\xdd\x92\xd0\xc3\xc6\xa9\x62\xe5\xdf\x55\x5e\x16\x79\xd3\xee\xf1\x6d\x0e\x26\x10\x09\x57\xa9\xb5\xb7\x88\xa9\x16\x07\x06\x59\x2e\x12\x05\x56\x81\x1b\x2c\x4b\xa4\xdb\x8a\x52\xdf\x8c\x69\xc8\x46\xb8\x76\xfb\x91\x96\xc2\x92\x22\x8d\x2d\xe8\xe7\x6a\xb7\xde\xfc\xe9\x6f\x9f\x9a\x84\x39\x4d\x98\xea\x4c\x46\x71\x9f\x8f\xbb\xac\x8b\x58\xfa\xda\x2c\x08\x22\x1b\xcc\xcc\xdf\x70\x9b\x0f\x70\x5c\xc1\x84\xa6\x00\xb8\x3d\x0a\xff\xbf\xfc\x74\x9a\xc7\x80\x45\x96\xa6\x90\x79\xbe\x3f\xb7\x83\xd8\x7d\xb3\x97\xcc\xf7\x59\x59\xc1\x11\x59\x38\x7e\x53\x22\x1d\x9e\x3c\xed\x79\xc6\x06\xc3\x85\x00\x0b\x8d\xb5\xbc\xfa\x5b\x22\xc6\x01\x4f\xcb\xc6\x05\x80\x55\x7a\x00\xad\x6d\x88\xfa\x93\xea\x84\xd9\x70\x4c\x5f\x02\x64\x1c\x5a\x67\x9d\x22\x4e\x0e\x4f\x45\xe4\x52\xe3\x43\x45\x00\x26\x44\x55\xe0\xe3\x49\xbf\x63\xff\x1c\x32\x95\xda\xba\xf3\x1f\xa7\xb6\x92\xe7\xa2\x68\x86\xb2\x3d\x2e\x64\x66\x15\x71\x2d\x4d\xec\xb5\x3f\x67\xa7\x9f\x57\x66\xa9\x76\xe2\x9f\xd8\x52\xba\x61\xec\xc1\x0a\x05\x92\x62\x86\x0a\xab\xe9\x63\x29\xdd\x17\xe9\xf7\x45\x72\x5f\x1e\x4e\x42\x0b\xcb\xf2\x20\xcf\x1f\xd7\x39\x1c\xab\x72\x06\x1c\x12\x5a\x26\x74\x7c\xee\x61\x9e\x22\x71\x1d\x30\x09\xe8\x7d\x9f\x56\x04\x25\xfd\x6a\x37\xc1\x84\xc7\xa2\xb7\xf5\x5a\x5c\xe4\x81\xe0\x02\xa5\xa0\xbd\x7a\x20\x5e\x1a\x45\xaa\x04\x2a\x24\x0f\xc2\x4e\xc5\x1d\x16\x78\x7a\xa9\x4a\xbc\x64\xcb\xe4\xc2\x04\x9c\xaa\x49\x1c\x7e\x64\x59\xe4\x76\xcc\x72\xc5\x21\x08\x62\x74\x35\x18\x34\x8b\x7a\x95\xeb\x9b\xaa\x9e\x17\xa6\x72\x08\x98\x05\xd2\xee\x40\x56\xd5\x78\xa3\x85\xc0\x28\x82\xe3\xfa\xc4\x2f\x7d\xc4\xbf\xc7\x65\xd0\xdf\x41\xfb\x94\xe7\xb6\x84\x53\xf3\xd2\xc7\x00\x20\x0c\x79\xa6\xc7\xbb\x1d\xf1\x6c\x4d\xa4\x25\xbf\xbe\x77\xc8\x95\x1c\x30\xcd\x04\x90\x9e\xe7\x7c\xff\xe2\x0e\x51\x18\x92\x51\x43\xea\xaa\xd5\x89\x82\x08\xd7\x55\xe7\x86\xf6\xc8\x04\xbf\xfc\xbd\x27\x02\x51\xa8\x29\x00\x32\xd3\xf3\xf1\xd1\xb5\xf8\xff\x96\xdd\x61\x88\x94\x0e\x46\x59\xe5\x7d\x3c\x31\x74\x20\x32\x92\xbc\x46\xff\x7b\x57\xd0\x5c\xbc\x8d\xeb\x1a\x47\x8c\x62\xe3\x5e\xc4\x8e\xca\x4b\x1a\xab\xe1\x33\x0a\x80\x40\x1c\x47\x94\x68\xdc\x94\x04\x80\x9b\x8c\x09\x9f\x8d\x44\x12\x24\xa9\xd5\x6b\x68\x4e\x55\x3e\x73\x07\x21\x91\xe0\x53\xc7\x2b\x4d\x0b\xf2\x3b\x14\xe6\xba\x0f\x71\x40\x1a\x19\xe9\xcc\xd3\x4d\xfb\xf2\x54\xc0\xe7\xec\x46\x43\x28\x0e\xd2\x4c\x07\x16\xfb\x93\x17\xa4\x1b\x30\x2b\xb6\x3d\x8f\xa9\x0d\xfc\x35\x18\xd0\xf1\x02\x4a\xe1\xa9\x9d\xa1\x48\x5c\x1f\x26\x04\x85\xd9\x70\x52\x79\xef\x1b\x91\x87\x23\xc9\x6e\x4b\x42\xd3\x2f\x90\x49\x55\xdb\xe8\x51\xb3\x44\x12\xac\x16\xed\x58\xfa\x58\x82\xff\xc5\x2c\x4d\xa8\x84\x85\xa8\xcc\x67\x1a\x73\x1c\x38\x04\x16\xea\x8d\xa0\xd7\xd5\xfb\xb2\xad\x05\x82\x25\x3e\x6d\x78\x83\x53\xe1\x17\xdf\x03\x18\x11\x64\xca\xce\x88\x79\xa2\x6d\xd5\x3f\x80\x30\x11\x71\xa9\x5b\xd0\xce\x1d\x48\xdf\x00\x61\xca\x1c\xcb\xc7\xef\xa8\x14\xbc\x46\x29\xfb\x12\xcb\x00\x32\x88\xa8\xa2\xa7\xc4\x5f\x84\xa4\x78\xaa\x9a\x26\x97\x56\x47\xca\xdf\x55\x72\x24\xf4\xd9\x33\x16\x58\xb6\x05\x12\x03\x58\xa3\x72\x2c\x15\x4e\x76\x10\xa9\x0d\x1d\x77\xeb\x1a\xf2\xc3\xb7\x1a\xca\x76\xfb\x52\xe7\xc7\x53\x6f\x8f\x83\x89\x6d\xf5\xb9\xec\x63\x12\xfd\xac\x32\x09\x9a\x9e\x2f\x60\x3d\xaa\x08\x92\x41\x64\xc5\x59\x4e\x50\x37\xdd\xc7\x08\xd9\xfa\x05\xea\xc9\x8a\x92\x81\xe0\x14\x1d\xfc\x23\xb7\x02\x32\xe7\xe3\x03\xbe\x8f\x1f\x4e\x06\x08\xdc\x8b\xd8\xb4\xcf\xa8\xf1\x78\xba\xcc\x11\xca\x30\xd5\xe0\x49\x34\x3e\x5c\xc5\xf3\x04\x25\x33\xfd\x8e\x32\x46\xc1\x1d\x93\x64\xfb\x39\x41\xa6\xeb\x9c\x46\x83\xb8\x61\x55\xb7\x0d\x4d\x2c\x03\x63\x96\x59\xab\x5a\xec\xcd\x38\x99\x26\x22\x94\x73\x0c\xec\x22\xcf\x36\x97\xa9\x53\xfa\x6c\xb0\xfd\xf1\x7c\x3b\xb6\xc4\x7c\x07\x11\xa7\x24\x3c\x4f\xc7\x50\xb7\x74\x2f\xd3\x5c\x32\x15\x12\x59\x8f\x26\x54\xe3\xba\xeb\xf9\xdb\xa0\x95\x9f\x2b\xcf\xc7\x8d\xad\x1e\x6c\x36\x6f\xc3\x78\x33\x4c\x28\x06\xd0\x2d\xa2\x6e\x2a\xac\x86\xaa\xb9\xb9\x44\x3d\x97\x19\xa4\xb1\xab\xd4\xdc\x55\xab\xb7\xc3\x33\xb1\x7d\x5f\x9c\x7b\x0b\x22\x18\xee\x06\x9c\x07\x56\x5a\xaa\x85\xc9\xe4\x95\x22\xb0\x21\x17\x5f\x26\xbc\xff\x63\xf3\xbc\xed\xa9\x44\xb8\x14\x71\x92\x58\xe1\xc8\x53\x01\x0a\x2d\x4b\xf5\xdc\x10\x1b\xf6\x06\x29\x12\x4b\x55\xa8\xf2\x9a\x0e\xb2\xbc\x2a\xe7\x99\x29\x29\xb4\x95\x65\xa0\xa5\x4b\x0c\x8c\x49\xdf\x84\x86\x54\x08\xa4\xa5\xf4\xa0\xec\xca\x6f\x8b\x01\x04\x29\x63\x91\x75\x03\xf8\x8f\xf3\x1b\x96\xed\xb9\x79\x6b\x9e\x11\x8a\x7b\xd0\x75\xee\xdd\x62\x29\xa5\x1a\x28\xd0\x0d\xe4\x05\xea\xfd\xc9\xb2\x36\xed\xcb\xaa\x6c\x5f\xea\xea\x3d\x2f\x0f\xfb\x76\xbc\x12\xa4\x01\x2a\xda\xdc\xef\x95\xa7\xdd\x9d\xd1\x6c\x8e\x82\x32\x52\x1a\x45\x72\x44\x37\x9d\xad\x14\x06\x69\xb0\x48\xbe\xb8\x64\xf2\x4b\x15\x84\x9e\x17\xa5\xdf\x73\x67\xd4\x28\x5c\xaa\xd0\x4a\x5e\xee\x7d\x0c\x69\x79\xa1\x29\x6d\xe5\x3c\x0e\xdd\xec\xf6\x3e\xb2\xd4\x49\x62\x06\xfd\xac\xed\xf5\x7a\xfd\x75\x14\x47\x6a\x1e\xa7\x7e\xbf\xdb\xbf\x23\xbe\xee\xdb\x1e\xc9\xeb\xbb\xa0\xb5\x2f\xbf\x55\x95\xbe\xaa\x3e\x9e\x88\x4e\xda\x37\x62\x16\x90\xa3\x37\x1a\xbb\xe9\x0f\xa0\xd7\x66\xa6\xbd\x79\xb2\x03\xa1\x64\x9e\x34\x65\x8d\x75\x9b\x1b\xaa\x20\xfd\x0e\xcd\xcb\x5f\x3c\x34\x9a\x98\xa2\x13\xeb\x9b\x35\x39\x98\x67\x17\x5c\x70\xcd\x26\xcb\x3c\x0e\xe3\x06\xb1\xf3\xc8\x77\x58\xee\x5e\xaa\x73\x03\x73\xdb\x58\x05\xa0\xc8\xfc\x23\x2a\xfb\xbe\xbe\x59\x85\x92\x5b\x8a\x0d\x6f\x90\x54\xd5\xeb\xef\x88\xa7\x85\x45\xe8\xae\x88\x82\xc4\x42\x7d\x95\xb2\x08\xbc\xdd\xbb\xaf\x08\x54\x71\x6c\xcb\x10\xdf\xf3\x12\x49\xcc\x6b\xc6\x62\xed\xbb\xe9\x84\x0e\x83\xa7\xc7\xe7\x87\xf5\x6a\xfb\xdd\x5f\x9e\x04\xc2\x1b\x20\x36\x0e\x41\x66\xed\x25\x75\x2b\x57\x89\x4e\x28\x9f\x7c\x82\xbc\xbe\x08\x79\x4d\xbb\xa6\x42\xfb\x04\x91\x45\xb6\xf8\x1c\x8f\xff\xb4\x2a\x05\x8b\x08\x72\x20\x31\x84\xc2\x61\x94\x17\x31\xef\x8a\x65\x32\xf3\xe8\x97\x5e\x10\xe7\x30\x7f\x42\xc6\x0d\x21\x94\xeb\xfc\xf0\xd2\xf2\x64\xd6\x9a\x45\x9c\xdb\xbc\x28\x14\x37\xe7\xa2\xf8\xb8\xb1\xb4\xa8\xb3\x5e\xb1\x21\xb0\xbf\xfc\xf8\x64\x20\x33\x2d\x33\xb7\xce\x7e\x94\xb6\x6e\x76\x60\x73\x5c\xfe\x7c\x3c\xe0\x96\x62\x94\x3c\xd3\xf0\x5f\xbf\xf5\x7f\x37\x5e\xac\xa1\x67\x69\x99\xa5\x57\x67\x37\x42\x16\x86\x7d\x05\xb8\xc5\x7e\xf4\x64\x73\x5d\xb3\xa2\x53\x57\x11\xef\x60\x1b\x2e\x55\x66\x2a\x11\x44\x19\x38\xe7\x60\xf6\xee\x22\x42\x12\xf8\xb3\x74\x0c\xce\x02\x9f\x9d\x07\xbe\x6b\x26\xa8\x62\xc0\x93\xc4\x8e\x20\x24\x4a\x68\x49\xfb\xc4\x6e\xb3\xba\x1f\x8b\x66\x71\x05\xa9\x20\x84\x92\xf3\x2b\x88\xac\x0e\xf5\x1f\x50\x90\x18\x20\x3a\xe6\xe8\xdf\x16\x23\x11\xd3\x91\x00\x16\x10\x51\xc3\xed\xd5\x76\xd7\xdf\x9d\x59\xf6\xf0\xfb\xd5\xf3\xef\xbb\x7e\x90\x81\xdb\x52\x78\x6b\x95\xd2\x38\x93\x29\x3a\x1c\x33\x0a\x20\x22\xfd\xc6\x7b\xf8\xb5\x86\x93\x8f\xf3\x4f\xc7\x46\x46\x69\x64\x46\x91\xae\x69\x28\x4e\xc9\x94\x53\x80\x9b\x82\xb8\xab\xd2\x69\x60\xd0\x8e\x74\x53\xd5\xf7\x50\x9e\xe7\x26\x84\x52\x61\x86\xbd\x33\x7e\x74\xc4\xd6\xa3\xa7\x52\x09\xf7\x95\x6a\x53\x10\x8d\x52\x2c\x26\x7c\xcf\xbe\xb1\xe5\x22\xab\x76\x88\x81\x7e\xc2\x05\xeb\xae\xd4\x91\xa2\xda\x11\xbf\x7e\xb7\x58\x14\xab\x03\xc9\x6b\xb5\xf8\x8c\x07\x82\x62\x5c\x46\xd3\xfc\xd5\x00\x32\x1c\xab\x1e\x0c\xcf\x3c\x3a\xb5\x95\xc6\x98\xc8\xd5\x6c\xb7\x9f\xd8\xad\xc6\xd9\xbb\x63\xa8\xc9\xde\x6e\x72\x8d\x5b\x5b\x75\x36\x49\x31\x2b\x4c\x74\x6a\x45\x62\xca\x67\x5a\x63\x3f\x76\x7f\x3e\xda\x97\x8b\x82\x79\x12\xc0\x1f\x6f\x0a\x99\x0d\xc4\xf5\x44\x98\xa5\x9e\x09\x77\xfe\x05\xf2\x66\xd1\xf8\x52\x08\x86\x0c\xc3\xbb\x5c\x61\xd9\xe0\x8c\xab\x6f\xba\x30\xd0\x84\x64\xd3\x6e\xb6\xeb\xab\x75\x95\x97\x7f\x25\x78\xc2\x95\x89\x2c\x8b\xc0\x09\x6a\x38\x62\x8b\x75\xb3\xaa\x71\xdb\x3b\x20\xca\x44\x11\xc6\x5e\xe0\x97\x98\x85\x9a\x49\xf9\x9e\x0e\xb8\x0d\x70\xbb\xdb\x26\xd0\x37\xa0\x95\x51\xdb\x5e\x6d\x37\xfa\x6c\x6d\xc1\xf1\x21\xa9\x43\x16\xd0\x7e\x62\x69\xf0\x46\x85\x95\xbe\x1d\x75\x9a\x79\x8e\x88\x16\x88\x9e\x66\x54\xc8\x3e\xfe\x62\x3a\xe2\x3a\x71\xd0\x0a\x1b\xae\xa3\xd6\x7b\x98\xa1\x32\xbb\x7e\xfe\x75\xbe\x55\x85\xee\xf6\x2f\x37\x45\xa6\xbf\x1d\x49\x9b\x7b\x2c\xaa\xf7\x59\x5a\x52\xc7\xb1\xc5\xa8\x91\x41\xb7\x72\xa4\x74\x43\xa3\x65\x94\xde\xbe\x54\xef\x3b\x6c\xda\xab\xd1\x9a\xd2\x49\xa0\x50\xf7\x53\xb3\x38\x85\xe9\xec\x57\x93\x04\xb4\x45\x62\x77\x26\xc7\x22\x0a\x48\x27\xdc\x96\xee\xc9\x73\x51\xcc\xd7\xa6\x4e\x74\xe6\xfc\xd5\x3f\xaa\x16\x75\x67\xd7\xcc\x06\x20\x8d\x6c\x39\x2d\x34\x83\x97\xa9\x53\x16\x58\xee\xe1\xe3\xfc\x86\x2c\x0d\x28\x52\xfe\x0f\x50\xaf\xa7\xaa\x5d\x91\xf2\x8a\xa3\x17\xe9\xfb\x64\x9a\x08\xd4\xec\x6b\xf9\xe0\xc6\xc3\x05\x6f\xa6\xeb\x9e\xb1\x88\x86\xe8\xae\x3a\x7c\x0e\x31\xd1\x99\x44\x12\x30\xff\xf9\xe7\xd5\xc6\xef\xb1\x9a\x73\x0b\xbd\xcc\x8f\xa7\xc9\x4c\x12\xb1\x25\x54\x7c\x22\x31\xe9\xee\x09\x20\xbf\x08\xb8\x69\x50\xb6\x00\xbf\x45\x38\xce\x32\x3b\x5a\x32\xed\x88\x70\x6c\x44\x8c\x88\xd2\x66\xd7\x4b\xe9\xf8\xfe\x2d\x31\xd9\xa8\x96\xea\x22\xf2\xbf\x94\x81\x9d\xdd\x4c\x03\x86\xb6\xbe\xf2\x03\x6b\x0f\xa7\xd3\x2a\x4a\x29\x74\xfb\xfb\xfd\x7a\xf2\x86\x4a\x44\x44\xf7\xfe\xb0\x7e\xea\xff\x04\x31\x3d\xce\x4a\xeb\x6d\x7b\xd6\xc3\x71\xa0\x75\x14\x39\xa9\x5c\x0a\xa1\x3c\xd6\x9f\x33\x1a\x72\x8d\x60\x05\x53\xe0\xac\x2e\xbd\x35\x8d\x2a\x20\xe8\xa1\xd3\xdc\xd5\xfa\xb3\xfc\xb0\x36\xcc\xd0\xee\x37\xf0\x2b\x3c\x55\xcd\xbc\xae\xd2\x11\xc9\x8f\xae\xc2\xc8\xa4\x3d\xbb\x60\x5e\x1e\xbc\x9d\x8a\x41\xc6\x09\x52\x60\x81\x85\x99\x87\x95\x60\x18\x5a\xce\xaa\x47\xcf\xcb\xf4\x55\xd0\x03\xc3\xc8\x96\xa1\xd9\xf3\xf7\xea\xfc\x31\x57\x5e\xe2\x18\x71\x4e\x31\xe4\x99\x53\x32\xab\xf7\xf2\xd9\x01\x8c\x84\x35\x53\x6e\xd7\x8f\xfb\xab\xc7\x87\x1f\x5b\x4a\x22\xee\x43\xff\x7c\x91\x8a\x84\xa3\xf9\xeb\xd6\x8a\x5b\x38\xd7\x16\x5f\xf6\x75\x19\x3d\xc6\x00\xf4\x28\x44\xcd\xb2\xec\x8b\x63\x12\x73\xcb\x99\x6a\x2b\x8d\xe6\x00\x69\x4c\x52\x4b\x1d\x81\x8e\x55\xc3\xff\x39\x63\xb1\x18\x2a\xcf\x47\x7c\x8b\x1c\x13\x6e\x02\x2b\x5e\xfb\x36\xe1\x2c\xa4\x96\x2c\xf0\xaa\xc6\x25\x7c\x9e\xe7\xc4\x44\x06\x6c\xc4\xeb\xaf\x07\x12\x32\x8e\x69\x8a\x14\xb1\xd9\xe6\x87\xe3\x24\xe3\x87\x29\x67\xb6\x8a\xba\xdb\x82\xd3\xe9\x56\x85\x2c\x31\xc2\x22\x29\x8b\xce\x7c\xef\x2c\xb4\x31\x06\x02\x49\x90\xb9\x2f\x6b\x1b\x38\x47\x30\x13\x51\x00\xa3\xd2\xf7\xe7\x05\x3d\x7b\xdf\x15\xe2\xcc\x16\xfc\xff\x6a\x01\x96\x09\xdc\x5d\x57\x6e\x6c\x40\xcb\x21\xf2\xfe\x16\xda\x08\x45\x88\x96\x7f\x02\xdf\xc6\xfc\x6f\x1c\x45\xaa\xa9\xb6\x03\x28\x32\xbe\xab\x08\x7b\x71\x5b\xfe\x68\xf4\x38\x20\x86\x42\x70\x70\x34\x3c\x77\x9d\x8b\x67\xf1\xdb\xa3\x74\x0b\x0a\x64\x32\x1d\x49\x54\x12\xe8\xbc\x99\x63\x78\x10\x42\x95\xe8\x5e\x83\x8c\x1e\x7d\x4d\x10\xb8\xab\x6a\x76\xf6\x21\x68\x08\x5d\xae\x6a\xd1\x1f\x42\x30\x22\x74\xfe\xd0\x75\x5e\xa3\x6a\xab\xfa\xa1\xd2\xb3\xa9\xa3\x42\x4e\xee\x85\x3d\x15\x1c\x57\xf1\x7d\xa5\xa9\xf2\x62\x7e\x47\xc5\x24\xf0\x89\xb5\xf9\x68\xe6\x12\xda\x9d\x7f\xc1\xe8\x50\x2e\xf1\x7d\xf5\xd6\x56\xf3\xc6\x8c\x7c\x79\x8f\x28\x09\x43\x47\x81\x18\xfe\x8f\xfb\xd7\x77\x04\x0d\x14\x97\x21\xc8\xd4\xd1\x9a\x53\xdb\x97\x5e\xbe\x95\xa3\xd2\x0a\x84\xaf\x53\x7a\xaa\x2b\x7d\xbe\xcc\x3c\xb8\xae\x9a\xa7\x92\x02\x2c\x56\x88\x70\xfa\x56\x1a\x02\x02\xe9\x58\x87\x63\x0d\x85\xba\x39\x97\xca\xff\x8a\x46\xad\xbc\x9b\x5a\xb5\xf8\x05\x1d\x15\xa2\x48\x2d\x75\x0c\x1e\xf3\x76\x0d\x27\x90\x24\x71\xe2\xf5\xc2\xa6\x11\xc5\x71\xb0\x0c\x11\x05\x19\x04\x4d\xb7\x70\xce\x05\x4e\x88\x76\x46\x48\xef\x69\x68\xde\x1f\x66\xa9\x33\x6d\xd1\x44\x9a\xe8\xd5\xa8\x9e\x22\x3f\x94\x51\x65\xfc\x91\x85\xc6\x30\x65\xf3\x58\xea\x75\xb3\xfb\x3e\x9d\x77\x26\xd0\x56\x71\x6a\x6f\xac\xb8\x82\xbb\xca\x84\x09\x77\xc0\x98\x02\x5b\x24\xa1\xfe\xe9\x85\xa1\x60\xf6\x3c\x79\x7c\xf6\xd7\x44\x91\x24\xb8\xd4\x5b\x8e\xef\xdb\x13\xaa\xdc\xe4\x6a\x31\x03\x6d\x92\x30\x23\xd3\xd2\x6e\xfb\x6b\x38\xad\x4a\xbd\x50\x13\x66\x92\xc8\x66\x6d\x3b\x17\xe8\xe7\x25\x5a\x62\x9c\xe7\x9d\x0e\xcd\xfc\xf7\x98\xa5\x57\xdb\xda\x88\x73\xb7\x1f\xf5\x3f\x21\x33\xaf\x45\xb0\x7d\xf1\x3a\x65\xdc\x24\xca\x32\xea\xff\xb3\x75\xec\xda\xbe\x21\x0d\x24\x99\xcd\xc7\x6e\xa9\x7c\xac\xce\xad\x43\x78\xbb\x84\x09\x1f\xf9\x3a\x26\x4d\x91\xc2\xbc\xba\xea\xec\x95\x69\x42\xc4\x64\x31\x53\x36\x0a\x8e\xa7\x05\xc0\xb4\xc9\x32\xcd\x44\x8f\xbb\x77\x56\xb5\xb5\xa0\x9a\x91\x5f\x6f\x78\x98\xa9\x74\x60\x07\x68\x36\xe5\x21\x2f\xb1\xb9\xd5\x4d\xdf\x23\xb1\x9c\x60\xe7\x06\x3b\xa3\x1a\x4b\x6b\x82\x4f\xd6\xa7\xe1\xdc\x02\xe5\xda\x3e\xb5\x63\xa7\xef\x74\xcd\x18\x6e\x62\xaa\x24\xfd\xcf\x99\x98\x48\xfd\xb1\x6a\x04\xd7\x81\x7b\xda\x9f\x08\xa7\xaa\x5c\x08\x12\x19\x08\x53\x3a\xae\x9a\x97\xea\xfd\x1a\xdf\xd6\xe7\x7e\xb8\x21\x09\x08\x3b\xaf\x46\xf1\x1b\xcb\x32\xe7\x3b\x48\x4e\x6f\x59\xe4\x66\xf2\x39\xb4\x04\x2a\xff\xd3\xd5\xf6\x54\x0c\x9f\x0f\x13\x2e\x7b\x3c\xf3\x33\xb6\xe7\xba\xfc\xf1\xb0\x9b\x3d\x8e\x31\x91\xf6\x94\x79\x55\x55\xdc\xba\x39\x21\x82\x80\xc5\x64\x43\x10\x79\xf8\xae\xba\xdf\xde\x4c\xae\x14\x41\x20\x02\x02\xb3\xaf\xab\xea\x84\x75\xee\x35\x6d\xba\x86\x84\x24\xcb\x6b\xfa\xc9\xdd\xb9\xa7\x74\x17\x41\x60\x38\x71\xf8\x1e\xf3\xf2\xdc\x90\xe3\x99\x97\x87\xb1\x0c\xf1\xff\x4c\x7f\x23\x0a\x84\x72\x1e\xfe\x3d\xb6\xa0\x3d\xbe\x21\x8c\xb8\xef\x91\xd8\x25\x28\x73\x3d\x09\x47\xd9\x39\x38\x3a\x85\x44\x10\xb9\x1a\xcd\x03\xb6\x57\x72\xe9\xd4\xe8\xba\x18\xda\xbd\x75\x55\x2e\x24\x58\x47\x81\x68\x11\x44\x4a\x12\x44\x73\xb7\x79\x5e\xed\x1e\xfd\x0b\x76\x6b\x35\xb3\xb8\x83\xf3\x11\x27\xf2\xac\x22\x88\x53\x9d\xb2\x5e\x64\x6e\xd1\x1a\x14\x41\x67\xe8\xb8\xca\x8d\xad\x7a\xb1\xf5\x70\xe4\xc6\x39\x65\xf4\xe9\x00\x25\x2a\xa5\x01\x6a\xde\x11\x4f\x37\xdd\xa7\x5a\x3c\x04\x44\x90\x60\x48\x49\xc4\x73\x83\xf5\xd5\xf9\x63\x39\x7e\x26\x82\x34\xb5\x3e\xe5\x8f\xd3\xa1\x06\x8d\x63\x9a\x6d\x11\xa4\x99\x15\x59\xdd\x56\x07\x28\xfb\x3f\x8a\x90\x90\xe4\x14\x18\xb1\xdc\x79\xdf\xf3\x86\xe4\xfe\x66\xb7\x56\x40\xd3\x51\xd7\xa7\x31\x31\x9b\x08\x98\xd0\x5c\x4d\xca\x70\x3e\x26\xce\x80\xef\x66\x52\xaa\x4e\x77\x00\xb5\xbb\xdb\xfb\xdb\x9d\xbf\x45\x96\x98\xd4\xef\x13\x48\x54\x31\x14\x82\x5a\x80\x2c\x89\x00\x82\xd4\x9f\xe3\x23\xa6\xe7\x5e\x60\xd1\xf5\x92\x89\xa5\x5a\x7f\x80\x6f\x78\x95\xf7\x7f\xe5\x76\x6a\x9b\xbc\x20\x6c\x94\x23\x35\x74\xad\x2a\xd0\x54\x4c\x75\x72\xc8\x3e\x5f\x68\x2f\x67\xd5\xd8\x22\x50\xb1\x15\x7f\x29\xf1\x57\x5b\x83\x31\x05\x96\x75\x7f\x97\x94\x67\xbe\x30\x1e\x9a\x97\xee\xc8\xba\x90\xac\x11\x81\xc2\x40\xbb\x20\xc1\x50\x53\x3a\xfd\x11\x9d\x05\xde\x6f\xb1\xe6\x54\x55\x1f\x6d\x44\x71\x7f\xbc\x70\x3d\x45\x80\x21\xa3\xa9\xb4\xf9\x73\xb7\x79\xb8\xde\x5c\xef\xb7\x77\xab\xf5\xef\xfb\xa7\xcd\xf3\xed\xe3\xb5\x7f\x38\x4c\x38\x99\x84\xf7\xde\xde\xdd\xd5\xa0\x5e\x17\x4c\xcc\xd9\xbd\x15\x90\xe5\x6d\xb9\x76\xc6\x9b\xae\x08\x8c\x09\x69\x2c\xf2\xc6\xd3\x2a\xdd\x54\xcb\x61\x73\x11\x06\xcc\xe2\xcf\x8f\x48\x31\xf3\xa9\x5f\x21\xc2\x80\x5b\xb5\x0f\x6d\x81\x38\x13\x76\x56\x11\x86\x22\x06\x1c\xc7\x6a\xa2\xbe\x05\x43\x0c\x47\x54\x76\xbf\xd6\xbd\xe3\xe2\x7a\x44\x91\xa5\x61\x95\x54\x57\x6b\xcb\xf2\x9a\xbe\x31\x8d\xc2\xd4\x61\x77\x69\x19\x6c\xf3\xc3\x32\x1c\xf7\x12\x91\x30\xec\x28\x61\x94\x66\x51\x6f\xbc\xaf\xef\xd6\x5f\x20\x81\x44\x18\xb1\x94\xce\xe6\x51\x85\x43\x18\x5e\x96\x38\x88\x30\x92\x82\xc2\xf5\x37\x8f\x3f\x1e\xae\x37\xcf\xdb\xfd\xf6\xfb\xea\x79\xe3\x5b\x63\x16\x4b\x47\x6f\x79\x56\xd8\xf6\x59\x43\x11\xc6\x3c\x21\xc9\x68\x6b\x90\xdc\x63\x37\xa5\xcb\x76\xfd\x02\xf5\x21\x2f\x0f\xce\x56\x9e\xef\x22\xc3\xd9\x2d\xc2\x18\x6c\x42\xb6\x5b\x67\x14\x40\x58\xd1\xfe\x35\xfd\x62\xb1\x66\x68\x45\xfa\xea\x72\x53\x62\x7d\xf8\x18\x85\x6a\x3f\xf7\x74\x44\x18\x9b\x84\x62\x82\xcf\xb7\x4f\xab\x8b\x91\x3a\xcf\xb5\xd7\x44\x98\x38\xc9\x03\xb7\xea\x4b\xac\xbb\xc5\xf5\xdb\xe8\xa8\x58\x2a\x44\x72\x17\xa7\x61\x18\xba\x57\xa1\xad\x98\x14\x3a\xa6\xab\x2d\x64\x0c\x29\xa3\xf3\xe2\xb8\xcd\xa7\xef\xc9\x78\x46\x31\x3d\xa2\xf7\xb6\x7c\x8a\x5e\xce\x08\xe7\x63\xc2\x3a\x43\xc0\xc5\xe7\x3a\x23\x67\xdb\x4e\xd0\x05\x22\xcc\xc2\x84\x62\xc3\x54\xf9\x4b\x25\x07\xa3\x61\xcf\x04\x12\xf6\xcb\x89\x19\xdc\x80\x57\xfa\x16\x61\x26\xad\xd2\xd6\xc9\xba\x0b\xd1\xbe\x41\xef\x90\x8a\x90\x87\x68\xcb\x2e\xaa\xb2\x7d\x39\x59\x13\x6b\xa0\x71\x12\xa1\x88\x0c\x55\xa1\x1d\xf3\xd2\x4b\x74\x2d\xf3\x7c\xb9\xfe\x32\x0c\xa9\x86\xc5\x9a\xb7\x6e\xcc\xa3\xfd\x5b\xf5\xde\x4c\xdf\x46\x25\x89\x8c\x7c\xb2\x7d\xc8\x3e\x7c\x12\x78\xf6\x17\x89\x90\x8f\x49\x65\x48\xc1\x7f\x0c\x60\xfb\x92\x40\x4d\x84\x3a\x42\x8a\xdc\xdc\x57\x6d\x5b\x0d\xe8\x42\x11\xa2\x52\xc4\x32\xb0\xf7\x42\xe4\xcd\x0c\xcc\x2a\x42\x34\xe0\xd9\x5a\x6d\xad\xfe\xcd\xb9\x28\xc8\x1a\x9d\x7e\x47\x13\x21\x45\x59\x6c\x6a\x6f\x4d\xec\x59\xfe\x67\x4c\x2c\x69\xad\xef\xbb\x13\xe0\xa9\x6a\x5d\x08\x66\x3a\xa7\xa2\x20\xb6\x47\xc1\xea\xee\x34\x20\xe7\x96\xb6\x83\x28\xe0\x99\x19\xc2\xb6\xdb\xca\x74\x2e\xd8\xec\x6e\x61\x98\x58\x35\x0d\x6b\x54\xac\x08\xc5\x34\x9a\x3a\x51\x14\x5a\x9f\x79\xef\xa4\xe0\x77\xc9\x6e\x76\x8b\x38\xca\x68\xbb\x20\xda\x08\x52\xe7\x32\x35\x5c\x52\xc9\x88\x28\xee\x2c\xff\xde\xad\x7c\xaa\xe6\x39\x2b\xdf\x8d\x59\x55\x0e\xf2\x4c\xbf\x8d\xaa\x4a\x7d\x3b\x18\xca\x00\x81\x2d\x53\xc2\x5d\x45\x0a\x0d\x7d\x01\xe1\x67\x07\x45\x94\x30\xab\x0b\xd4\xd9\x7a\x7e\x9b\x8f\x12\x66\x8b\x58\x5d\x61\xda\x7d\xa5\xfb\x0f\x12\x25\xd2\xea\x06\x1e\x2d\x38\x61\x24\x8f\x20\xa2\xc4\x04\xbe\xd6\x6f\xa2\xf1\x21\xa2\x34\xb1\xe5\xcc\xe7\xd2\x65\x51\xc6\xee\x8d\x88\xd2\xb4\xa7\x66\x21\x8b\xc6\xed\x9a\xc3\x94\x8a\xff\xcf\xf7\x04\xcd\xc1\xeb\xd3\x95\xaf\x41\xe6\x7f\x81\x05\x31\x9d\xf3\xfb\xce\x1c\xb0\xa4\x53\xbe\x25\xe6\x3e\x5a\x72\x0f\xbf\x46\x6a\xac\xd3\x91\x60\x2c\x21\x07\xff\x1b\x96\xd8\xe4\x8d\xb3\x7b\x69\xd7\xf8\x5b\x4b\x25\x62\x22\xa5\x69\x8c\xa5\x2f\xcc\xbd\x55\x95\x7f\x88\x2c\x08\x49\xda\x91\x26\x04\xb1\x0e\x0d\x79\x4e\x11\x65\xa9\x55\x21\x2a\x72\x83\x56\x03\x7a\x9f\xbf\xf9\x46\x2e\x15\x97\xbe\x32\xac\x6a\xa6\xe0\xe5\xaf\x1f\x49\xc4\x21\x4d\x54\xec\x26\xc3\x55\x3e\xca\x6e\x88\x48\x70\x16\xc7\xbe\xa2\x7d\x4c\x59\xfd\x65\x14\xac\xbb\xce\x50\xa8\xba\xc8\x1b\xab\xc9\x73\x29\x56\x3e\x5a\x2a\x02\x13\x22\x0c\xf1\xbc\xfc\x9b\x5f\xa7\xbc\xc6\x55\xbb\x98\x12\x17\x11\x44\x8a\x92\x17\x3d\x5f\x63\x5d\x1d\x6f\x08\x1f\x73\x57\xb5\x2d\xd6\x1f\x63\x78\xb2\x88\x00\x12\xca\xb1\x54\x27\x2c\xc7\x9e\xba\x88\x54\x60\xb3\xba\xdd\x2e\xfc\xdb\x27\x63\x35\xb2\x29\x22\xc5\x22\x62\x13\x70\x3e\xe5\x43\xae\xf0\xdb\xf9\x63\xe4\x55\xda\x2e\x04\xbf\xac\xd4\xf4\xef\x52\x50\x2c\xf1\xfa\x05\x68\x83\xfc\x6a\xfb\xd1\x49\x44\xa6\x55\x81\xa6\x8d\xf9\x6c\x06\x6a\x10\x96\x3a\x00\x5b\xf5\x62\xb7\xc1\x02\x2d\xc4\xbc\xb9\xa9\x6a\x6f\x5a\x4c\x77\xcf\x48\x4b\xe1\xce\xdc\xf2\x9c\x97\x33\xf3\x37\xc2\x34\x56\x56\x70\xeb\xb6\xcf\x74\xf4\x83\x84\x8c\x11\x21\x0c\x95\xd9\x0c\x22\x03\xd3\xb5\x89\x00\x94\x35\xf8\x0e\xea\xf5\x1a\xfa\x09\x8d\x2a\x22\xe8\x97\x13\x9b\xbb\xb1\x3b\xe1\x27\xa9\xc9\xae\x3b\x23\xc3\x56\x56\x92\x22\x9b\x8d\x17\xa9\x9b\x2b\xa5\xcf\x27\x9f\x4f\xd4\x8e\x3f\x16\x2a\xe3\xd2\x66\x1f\xdd\x72\x76\xc7\xeb\xec\xb1\x31\xa4\x98\xd4\xbf\x41\xbd\x3e\x55\xed\xca\x3f\xb7\x89\x33\x32\x3f\x8e\xde\x4d\xf6\x7f\x4f\x0d\xd5\x1d\xd4\x55\xd1\x3b\x2a\x91\x31\xca\xf4\x38\xad\xf6\xbd\xfa\xa3\x1b\x28\xe2\xb4\x77\x14\x9f\x93\x0c\x9b\x88\x83\x80\x53\xdc\xb2\x9b\x89\x54\x64\x3f\x9a\x92\x71\xa0\x63\xf2\x7a\x8e\x79\x79\x75\x26\x09\x1a\xd7\x10\xf2\x24\xd5\x7d\xbe\xaa\x86\x55\x71\x2e\x67\x67\x64\x1c\x2a\x41\xce\x98\x77\x99\xfa\xf7\x9e\xce\xa1\x38\x8e\x24\x31\x8a\x98\xaa\xc6\xfc\x50\x5a\x3a\xf2\x4d\xad\x76\xd5\xa6\x56\xb7\xc7\x93\x45\xfc\x8d\xaa\xbe\x44\x1c\xc7\x52\xf6\x45\xb4\x57\x50\xbe\xd6\x55\x51\x5c\x75\x93\xdf\xf7\x48\x42\x0b\x10\x3f\x97\x0d\x42\xfb\xfb\x18\x5d\x34\xfd\xf5\x24\xd3\x69\xe4\xb7\xda\xfa\x95\x52\xd0\xb3\x17\x49\x93\x88\xa8\xf5\x4f\x16\xf5\x30\xd4\xd5\xde\x20\x3e\x9c\x8f\xe3\x4a\x73\x11\xa7\x80\x04\xc3\x79\x7a\xfc\x7d\xf3\x3c\xf0\x47\x8b\x98\xc5\x56\x0e\xb8\xd7\xe5\xcf\xab\xd2\x96\xcd\xf6\x3d\xb4\x44\xab\x7a\xa8\xf2\x23\x14\xcd\xbc\x8e\xc9\x77\x43\xe1\xd0\xf3\x94\xea\x98\x6e\x68\xae\x0f\x4f\xc2\xc8\x73\x05\xc1\xf1\x04\xf9\xa1\xa4\x89\x70\xf5\x71\xab\xa7\xb3\x2e\xe6\x52\xd3\x8a\xf2\xc6\x9c\x9d\xe3\x8b\x21\x84\x98\x1b\xcb\xcd\x4c\x81\x60\xca\x12\xad\xbd\xaa\xed\xf0\xdb\x10\x8a\xd4\xda\x07\x6e\x36\xe5\xe5\xc1\x49\x33\xfa\x1e\x89\xee\x63\x92\x6d\x55\xc3\x01\x67\x93\x52\x06\x61\xe8\xc2\x06\x64\xa8\x39\xbc\xc9\x1c\xf4\x24\x62\x29\x64\x30\x86\xb7\x3f\xd5\xbe\xec\x19\xb5\x0d\x99\x7c\x72\xea\xf8\xeb\x65\xca\x1c\x0c\xc5\x7a\xa8\x50\xb8\x0c\xdd\xf4\xc5\xa5\x94\x64\x96\x1f\xbb\x09\xf7\x70\x61\xcc\xc4\x4a\x5a\x1f\xc0\x58\x54\xdc\xbd\x95\x29\xf5\xaf\x83\x81\xf2\xe2\xe6\x56\x42\x15\x2c\x93\xc9\x08\xc8\x20\x62\xcc\x32\x8a\xc7\x1f\xf3\xd2\x49\x20\x7f\xcf\xfb\x11\x43\x54\x99\x3b\x50\xb7\x60\xf0\x92\xc5\xa5\xeb\x62\x28\x06\xe3\xcf\xa1\xfb\x0f\xaf\x54\xe7\x6f\x62\x12\xe6\x45\xca\xbd\x74\xc1\x4f\x94\x4d\xde\xce\xdf\xc6\x64\x8a\x0a\xbb\xf3\x32\x6f\xf7\x1a\xdf\xf6\x50\xea\xbd\x2b\x7e\xdd\xc3\x50\x56\xbe\xb8\x6f\xc6\x46\xc6\x99\x03\xd5\xb5\xf5\x19\x0b\x7c\xc3\x62\x39\x06\x98\x04\x5c\x11\x2a\x2d\x57\x95\xd7\x3e\xbe\xee\xc3\xe3\x22\x09\x50\x20\x7a\xdf\x7d\xdf\x8c\x87\x2b\x09\x13\x0b\x40\x37\x75\x55\xb6\x58\xea\xe9\x0c\x4a\x42\xa1\x29\xa2\x74\xa8\xa1\xd4\xeb\xaa\x6c\x2a\x8b\xa0\xb5\x91\xb6\xbe\x5b\x14\x72\x02\xf5\x60\x81\xaa\x7d\xc0\xf7\x7b\xf8\x98\xf1\x53\x8b\x24\x02\x61\x55\x6d\x98\xcb\xe8\xb8\xbf\xc7\x61\x4c\x44\x47\xc4\xbc\x4f\x9a\xa1\x6e\x9a\xde\x54\x35\x91\x89\xf4\x9b\x42\x12\xc7\x9c\x22\x4e\xaf\xd8\x3f\x3f\x69\xb0\xd0\x18\x37\x58\xbb\x33\xc5\x05\x12\x26\x43\x14\x0b\x2b\xd3\xb1\x55\x70\xdc\x0e\xe0\x51\x91\x24\xb1\xe4\x4e\x05\x67\x96\xdd\xf5\x1d\x58\x98\x2a\xcf\x17\x46\x4c\x30\xb3\x31\x4a\x32\xab\xdd\xbd\x5a\xaf\x37\x4f\xbb\xfd\xe6\xcf\xf5\xf7\xd5\xc3\xb7\xcd\xd0\x2c\x28\x24\xbd\xc3\xa6\xfd\x1d\xf3\x6a\x12\xd9\x4b\xd2\x10\x78\x2f\xb3\x44\x40\x8a\xe9\xaf\xa7\xdc\x56\x3e\x0d\x75\x8a\xf7\x50\x7e\x4c\xdd\x4a\xef\x76\x25\x2c\x0c\xd4\x58\xc1\xaf\xf5\x25\x10\x22\x61\x09\x27\xf9\x5d\x2c\xdb\xfa\x63\x4c\x05\xef\xda\xb3\x20\xa5\x1d\xc0\x72\xe3\xb9\xc8\xbf\x6f\xe3\x29\x15\x68\xe6\x8d\x13\xc9\xf0\x0d\x22\x35\x34\x76\xcf\x48\xbc\x0d\x23\x9d\xfd\x05\x0b\x28\x11\xcc\x6a\x0e\x48\xec\x8e\x28\xaa\x26\xde\x1f\xb1\x7d\xf1\xa5\xca\x22\x11\xd2\x02\x79\x75\x75\x0d\x1f\xcd\x0d\x31\x2c\x6e\x40\xbd\x3c\x8e\xa9\x02\xfb\xb7\x85\x40\x44\x0e\xf8\xee\x70\x9f\xcb\x67\x53\x02\xb1\x61\x43\x1a\xc9\xde\x76\x94\xa4\x1b\x6c\xd6\x04\x38\x13\x7c\x14\xff\xba\xaa\x4a\x3d\xaa\x41\x17\x89\x0c\x24\xe5\x14\x9f\xb1\xc5\xf2\x50\x4d\x3e\xa5\x54\x92\xe0\x8c\x2e\x5b\x35\x11\x16\x76\x5d\x54\x14\x62\xd6\xf3\x44\x4f\x58\xee\xfe\x37\x1d\xd0\x27\xec\xff\x66\x6f\xa0\x74\x48\x41\xbd\xff\xd4\x1f\x16\xef\x7e\x8d\x2d\xe4\xc5\x92\xc3\x98\xe8\x34\x23\xfb\x97\x4a\xe4\xc9\x49\x73\x35\x69\xd3\x5b\x6a\xb0\x82\xbd\x3f\x37\x9b\x91\x73\x9f\x68\x63\xc8\xee\xf9\x76\xb3\xbe\xfd\xeb\x98\x51\x82\x81\x25\xc7\x6a\x5a\xa0\x03\xca\x9a\xac\x5e\x95\x67\xf9\x73\x98\x04\x29\xd3\x48\xd9\xc2\xcf\x6a\xa1\x97\xaa\xb4\x44\x62\x54\x0c\x16\x64\x89\x0a\x4b\x98\x2c\xa5\x34\x08\x02\xe2\xc8\x7e\xab\x5a\x32\x92\x5c\x6e\xd1\x13\x99\x5e\x80\x9a\xbf\x24\x55\xe8\x6e\x67\x19\xda\xf0\xa0\xb4\xf7\x23\xc6\xef\x91\x06\x22\x4e\xc7\x4c\x1f\x54\xac\xf4\x69\xe5\x89\x48\x03\x6d\x81\x85\xa7\x70\xaf\xcf\x63\x8e\x2b\x91\x06\x26\x06\x4f\x66\xf1\x56\xbd\x4f\x72\x0a\x69\x98\x5a\x0c\x15\x15\x27\x3c\xbe\x61\x1d\x07\x83\x09\x99\x86\x5c\x52\x69\x18\x45\xa2\x7c\xaa\xc8\xb5\x45\x99\x55\xe7\xef\x59\x1d\xa0\x5d\x60\xd9\x17\x69\xcc\x23\x8b\x22\xfd\xcf\x19\x6a\xfc\x99\x97\xcb\x15\x24\x22\x8d\x15\x78\x87\xd4\xd3\xcc\x3c\x57\xef\xeb\xaa\x70\x38\x97\x79\xea\xd9\x5f\x66\x12\x70\xf5\x67\x77\xd0\xb4\x8e\xec\x6f\x60\xed\x9e\x75\x4f\xc0\x92\x03\xaa\xfd\x3d\xfc\xca\x8f\xe7\xa3\x35\x41\x7c\xab\xb4\x52\x34\x44\xce\xfa\x84\xf5\x88\xaf\x43\xa4\xa9\x0c\x28\x75\x78\x2e\x5f\xaa\x62\x96\x09\x4a\x53\xc9\x60\x24\xbe\x30\x2d\x8b\x98\x7e\xfc\x54\x85\x24\xb8\x77\x0f\xad\x7a\x39\x02\x55\x57\xd6\xf8\x06\x79\x71\x01\x51\xfa\x12\xf7\x29\xd2\xd4\xd8\x18\x6f\x83\x45\xb1\x39\x1c\xfa\xd7\x48\x4d\x18\xa1\x37\xef\xb6\x50\xe0\x63\x3f\x1b\x58\x92\x32\x2b\x91\xb2\x86\x8b\x22\x68\x91\x32\x14\x64\x06\xdd\x7f\x68\xef\x93\xa5\x59\x9a\x09\x67\x93\xf8\x34\x4d\xd8\xb7\x31\x2b\xe2\xf9\x98\x17\x93\x6a\xef\x85\x94\xbb\x48\x33\x13\x88\x78\x5a\xe4\xde\xcd\xc5\x95\xc3\xb7\x2c\xb1\xb7\xb8\x2b\x79\x10\xa4\x3d\x7b\xd6\xa9\x2a\x7b\x24\x9b\x48\x39\xe7\x89\x8d\x01\x49\x52\x7b\x9b\x2c\xea\x54\x48\x4b\xae\xd1\x99\xb1\x96\xaa\x67\x81\x83\x5d\xa4\x20\x80\xe8\xaf\xb7\x67\x42\x2f\xfa\x7b\x83\xd2\x54\x50\x63\x79\x0a\xd7\x76\xa5\xbb\x36\xc9\x4c\x16\x8e\x0a\x6d\xaf\xaa\xea\xf5\x32\x0a\x99\x4a\xe1\xc8\xaf\x49\xbb\xfe\xc7\xbd\xbf\x5c\x45\x91\xa5\x9a\x25\x76\x71\xab\xca\x93\xab\x8f\x65\x68\xf9\x5f\xff\xe3\xee\xaa\x11\x3d\x16\xaf\xc6\xe6\xe5\x1a\x3e\x46\x54\x3a\x22\x45\xb0\xb2\xe2\xf7\xa8\xf3\xd7\x1c\xfa\x3f\x6b\x20\x2b\xe9\xfe\xf6\xe1\xf6\xe9\xf1\xf1\x6e\xbb\xbf\xbb\xfb\x63\x7f\x73\x7b\xb3\xda\x87\x43\x1f\xa4\x70\x97\xc3\x94\x2d\x58\xb7\x69\x67\x00\x5b\x8a\x8a\xb3\xbe\xb4\x02\x58\xa0\x02\x12\xac\x91\x67\x1f\x6e\x19\x23\x4a\xfc\x76\x3c\x13\x5a\x15\x2c\x40\xad\x09\x2e\x7b\xee\xb6\x5c\x6c\x16\x0b\x8e\x2e\x4f\x0f\x16\x98\x8c\x5b\xda\x36\x52\xf5\x9d\x9f\xf0\x2c\x8c\x64\x80\x3d\x34\x8c\xb8\xa7\x86\xe8\x0b\x0b\x93\x2c\xb5\x1c\xa2\x57\xd0\x60\xca\x89\x78\x0a\x67\xc5\x59\x61\xdf\x19\x13\x5b\x92\xd1\x76\xcf\xe7\x54\xa7\x46\xa1\x05\x16\x25\x3c\xc9\xfa\x7a\x93\x9f\x79\x59\xf6\x65\xc5\x82\x45\xa9\xa1\xad\xe3\x54\xbd\x62\x2d\xab\xfe\x19\x22\x65\xd7\x56\xb7\xeb\x8e\x24\x1d\x04\x8b\xb4\x20\x0c\xe0\xe2\x21\x37\x1d\xf4\xc8\xf0\x68\x22\x9a\x38\x82\x44\x0b\x16\x87\x9c\xac\x0a\x1f\xc6\x7f\x3c\xb7\x13\x19\x33\xc1\xe2\x58\x79\x76\xcf\xce\x40\x6d\x71\x1f\x8b\xbe\x2d\xd5\x14\x06\x1c\x78\x7d\x76\xd8\x19\xc0\x78\x0a\x67\x9f\x3e\x66\x69\x90\x38\x58\xed\x40\x3e\x2c\x58\x9c\x31\x2f\x9a\xd3\xbd\xa4\xfe\x94\x41\xd0\xf7\x17\x46\x3a\xb5\x13\xb5\x40\x76\x2f\x58\xac\x03\x4a\xa2\x52\x16\xa5\xf8\x78\x82\x8f\x2d\x8e\x4a\xea\xa6\x9d\x53\x1e\x59\x85\x8f\x17\x28\x4b\xa4\x1a\xfd\xea\xdc\x8f\x4d\x8a\x59\xaa\x7b\x73\x6a\x53\xce\xc1\xbe\x82\xb1\xc8\x86\xc8\x3a\x6f\x34\x57\x9b\xf6\x85\x08\xf8\x40\x16\x78\x61\x3d\xb3\x2c\x4a\x7c\x25\xcd\x7a\xfd\x7d\x8f\x3a\x6f\xfb\xb5\xc5\xb2\x38\xa6\x07\xd9\x3c\xad\x97\x36\xd1\xc9\xb4\xce\x32\xab\xc9\x7d\xc0\xf6\x3b\xc2\x45\xd6\x99\xf1\xd0\x56\x38\x1e\xb0\xdd\x17\xd0\xb4\xfb\x43\x51\x49\x28\xf6\x70\xee\x7e\x72\x94\x61\x64\x3c\x63\xd2\x05\x8e\xda\xc1\xbc\xf0\x8d\x3c\x4a\x99\xb7\xf6\x27\x00\x76\xc1\x3a\x2b\xab\xdf\xd2\x7e\x94\x14\x78\xeb\xa3\x7f\x4c\x9a\x8c\x42\xe9\x3f\xa1\x50\x2f\x30\xa1\x10\x13\x4c\xf1\x28\x1a\xc7\x9b\xfc\xc1\x3e\x1d\x58\x1d\xda\x25\x4f\x3f\x40\xda\x81\xbd\x9b\xc6\x30\xb3\x12\xe6\x36\x63\xea\x84\x0a\xfe\x01\x1a\x1d\x08\xef\x33\xf8\xa9\x60\xa8\x03\x42\xc8\x91\x23\xe4\xfe\x66\x4c\x26\x1c\xa1\xc3\x54\xa3\xcf\xd2\x52\xdc\xd3\xe1\x3c\xfd\xec\x59\x60\xac\x1d\xdf\xba\xda\x99\x41\xe1\x51\x64\x61\x02\x5a\xfa\x09\xfa\x7d\x52\x54\xe1\x7b\x70\x0b\x6d\x97\xe7\x8f\xdb\x92\x20\x85\xe3\x5c\x47\x16\x22\x12\x7e\xed\x54\x57\xc7\x6a\x3e\x8b\xba\x56\xb2\x75\x64\xae\xad\x92\x39\x7c\xe2\xb5\x67\x51\x1c\x11\xfb\xac\x63\xd8\xf5\xe8\x8a\x69\xa7\x38\x43\x2a\x96\xf7\x51\x74\x4a\x01\x7c\xa6\x89\x3a\xec\x66\x59\x8c\x3c\x73\xd9\xf8\x6d\xfe\x5f\xbc\xb9\x7d\x78\xd8\xfc\xcb\xbf\x41\x12\x46\x4a\xf6\x4c\xf7\x2e\x65\xd1\x8d\xd1\xd5\xf9\x63\xf6\xfb\x49\x9a\x91\x5c\x5b\x4d\x28\xaf\x8b\xdc\x63\xff\xda\x09\xcf\x2c\xae\x60\x11\x7b\xed\x3a\xa5\x18\x47\x92\x8e\x3e\xaa\xd1\xea\x3c\xe2\x45\x7a\x0e\x91\x11\xc3\x30\x7d\xc0\xd3\xf9\x64\xb3\xde\xb3\x07\x63\xa9\xc5\x2b\x22\xd1\x4e\xed\xce\x25\x3e\x5e\x96\x87\x8b\x8c\xc9\x80\x14\x9c\xee\x1e\xbf\xed\x9d\xe5\x60\xce\x05\xed\x38\x5f\x26\x50\x32\x26\xd1\xb2\xe5\xaf\xff\xe6\x69\x96\x75\x63\x45\x65\x0d\xcd\x7d\x7e\x55\x55\xba\x18\xd7\xda\x8b\x8c\xa7\x11\xd1\x9b\xbd\xe7\xa5\xb5\xa6\xe2\xa1\x25\xa5\xf2\x5e\xbf\x49\xaf\xca\x0f\x12\x79\xfe\x3a\x1d\x93\xf1\xcc\xee\xb4\x27\xf8\x40\x5c\xd5\x35\xcc\x87\x88\x73\xa9\x06\x32\xd0\x3e\x16\x90\x71\x91\x52\x6d\x5d\x37\xf9\x6d\x69\xf9\x5f\x0d\x86\xe0\xcc\x1b\xf0\x3f\x4e\xf3\x8d\x28\x13\x02\x53\x4f\xd3\xbd\xef\xf9\xe1\xf7\x14\xcd\x29\x0f\x3d\x5e\x2e\x03\x26\xa9\xbe\x8d\xb0\x01\xcf\xd8\x9c\x8b\xd6\x4b\xea\x5d\x32\xcc\xf6\x33\x0b\x24\xa3\x03\xf0\x0a\x2f\x33\xde\x7f\x61\x82\x7f\x32\x70\x32\x8e\x29\x54\x5b\x53\x10\xab\x3b\xec\x26\x21\xc4\x4c\x72\x19\x3a\xb4\xf6\xce\x0b\x7f\xdd\xe4\xb0\x0c\x1e\x16\x99\x14\x01\x29\x8d\x11\xbb\xc4\x38\xef\x3f\xfb\x1c\x1a\xa3\x6c\x20\x95\x71\x15\x6b\xbe\x04\x70\xda\x15\x1d\xc9\x43\x83\xad\x55\x3a\x6d\x3f\x48\x40\x50\x3b\xc5\x92\xff\x99\x96\xcb\x89\x0c\x79\x40\xcb\x54\x52\x45\xf1\x7d\xef\xcf\x67\x28\xac\x76\xc0\xe6\x79\x9d\x45\xe1\x54\x71\x5f\x64\x28\x2d\x5b\x01\xc1\x24\xee\x2a\x28\x1f\xcb\x2b\x7c\x81\xc2\x0c\xc2\xe0\xff\x33\x8b\x9e\xcf\x5e\x1e\x35\xc8\x81\xa2\xc0\xd2\xe6\x56\xb5\xc7\xbe\x4c\xf7\x55\x34\x9a\xaa\x5f\xd6\x95\xc6\x7b\xc8\x0b\x8a\xc3\x8d\xb7\x66\x13\x81\xb7\xd7\x1f\xe4\x03\x1c\xb1\x39\xc1\x00\x38\xcb\x0c\x04\x04\x22\x72\x01\x16\x6f\x88\x8c\x2d\xfa\xe9\x8a\x34\xc8\xe8\x43\x7a\x91\x33\x12\x37\xdb\xef\xbe\x3f\x6f\xb6\xdf\x7b\x31\x4c\xc1\x03\xc9\xb8\x2d\xb4\xf9\x5e\x15\xb9\x86\x8f\x5d\xa5\x3d\x79\x8a\xe0\x91\xb4\xf9\xdb\x1a\x41\xef\x9d\x69\x5d\x0d\xec\xde\xfd\xe3\xf1\x48\xa6\xb4\x0c\xfe\x5c\x43\x8d\x5f\xd4\xdc\xbb\xee\x31\x98\xc0\x69\x39\xff\x0b\xa1\xde\xbd\x57\x04\x8c\x3a\x15\xf9\xdc\x60\xe0\xb1\x4e\x49\x66\xa0\x73\xca\x3a\x5b\xf7\x06\x67\xd1\x1c\x9e\x44\x19\x32\x87\xaf\xba\xfa\x58\xbf\x74\x1b\xec\xdf\xc0\x57\xf1\xe5\x38\x0b\x4f\x98\x15\x4e\x6e\xaa\x62\x4f\x9c\xb9\xcb\x47\x18\x4f\x84\x15\x27\x3e\xc2\xaf\x2b\x6c\xaf\xf3\xb1\x19\xc0\x13\x61\x6f\x92\x37\xdb\xee\x33\x6e\x7e\xe5\x33\x2a\x65\xc1\x13\xe0\xc4\xcd\xe0\x22\x73\x70\x44\x62\xae\x9e\x82\xe8\x27\x93\x88\x27\x80\xc4\x64\x4d\xb8\xff\x1c\x27\x6a\x61\x82\xa7\x60\xe9\x03\x95\x9f\x1c\x9b\x52\x5f\xa3\x2a\xc0\xc6\x5b\x46\xc1\x11\x9e\x85\x11\x01\x35\xba\xf7\xab\x77\x2f\xb8\x45\x68\xa6\x34\xce\x82\x67\xc6\x32\xbd\xf6\xf2\x5b\x37\x77\xbf\x5f\xcf\xde\x81\x47\x10\x79\x16\x8f\x06\xfb\x1a\xec\x9b\x02\x0e\x23\xe4\x08\xe7\xa9\x74\x1c\xb9\x65\xde\xbc\x78\x05\x1a\xdf\x28\x81\xa8\xd9\x4f\x48\x6e\x8e\x8b\xae\x0f\x8b\xd0\x75\xeb\x9c\xec\xd0\x0b\x41\x58\x21\xd1\xbe\x80\xc5\x77\x51\x8c\x79\xc2\xf6\x85\x7a\x99\xd9\xf7\x03\x29\xa0\x37\x13\x69\x5b\x1e\x99\xfe\x1c\x0c\x27\xfc\xee\x3f\xf2\xe3\x88\x8e\x42\x70\x19\xa7\x9e\x4e\x68\x4b\x1a\xea\x84\xae\xeb\x9f\x47\x8f\xc1\x56\x5c\x6a\x57\x00\xe0\xb3\xda\xb3\x77\x52\xa1\x65\x89\x3e\xe6\x87\x1a\x5a\xec\xdc\x9b\xce\x27\xe8\xac\xfc\xfe\x24\x58\x00\x9c\x71\x95\x25\x51\x32\x89\x78\x58\x50\xe0\x74\x87\xe3\x3a\xc8\x08\xa3\x7d\x97\x1f\x5e\xda\x3b\x3c\x56\xa5\x8f\x15\xfb\x0e\xb1\x8a\x9d\xb1\xbe\xfa\x80\xb2\xbd\xae\xab\xbc\xdd\xa8\xaa\xac\x8e\xf9\x7f\xce\xb8\x77\x2e\x55\xd8\xf7\x17\x91\x94\x13\x8f\x8a\x62\x75\xcb\x93\x15\x45\x04\xc3\x8e\xf5\x54\x54\xed\x22\x5f\x9a\xef\x2d\x45\x6c\x01\xb5\xb5\xae\x76\x1e\x93\xc3\x4d\x20\x2c\x1c\x9e\xd8\xe8\x9a\xdb\x72\x24\x99\x2f\xb8\x89\xac\x7a\x8a\x3d\x55\xf6\x47\xf8\xb5\x87\x85\x18\x9f\x08\x02\x4d\x88\x7c\xfa\xd4\x57\xe7\x3a\xc7\xce\x5f\x68\xce\x43\xce\x5b\x04\xa1\xc4\x9e\x88\xb1\xea\xcc\xea\x31\xe0\xc4\x77\x8a\x63\xc1\x47\x89\x71\xe2\x0a\x5d\x51\xb5\xce\x70\xa3\x2c\x25\xe1\xe6\xe7\xcd\xf6\x62\x13\xfa\x8c\x11\xa6\xbb\xca\x96\xcd\x11\x5e\xd7\x92\x64\x8f\x63\xef\x22\x10\x26\x18\x8f\xfc\xcd\xb9\xd4\xbb\xea\x71\x90\xe7\x11\x22\x90\x99\xca\x46\xf5\x9f\xdf\xaa\xe2\x02\x44\x3e\xdd\xea\x44\xc8\x55\x62\xc6\x3b\xc6\x9c\xef\x59\x88\x50\x05\xa2\xa7\xd9\x6c\xd5\xcb\xf2\xe7\x13\x51\x1a\x90\x79\xb3\x7b\xbe\x7d\x5a\x7d\xf3\x78\x77\x11\x65\x28\x71\xfc\x4c\x63\xb2\xaf\x61\xa1\x88\x48\x5a\x24\x14\x92\xb5\x3b\x9b\xc7\x22\xc9\x38\x3d\x43\x55\xde\xae\x1f\x97\x0d\x11\x91\x48\x4b\x4e\xb1\xad\x94\x22\xfa\xdc\xe5\xcc\xa2\x48\xa4\xa2\x04\xf9\x76\x75\xb7\xd9\xaf\x57\x4f\xfb\x1f\x5b\x7f\x16\x8a\x54\x24\xc4\x7f\x70\xf3\xe3\xe1\x7a\x3f\xa5\x44\x17\x82\x05\xc2\x51\xef\x58\x0c\xba\xb3\xe3\x5d\xe9\xb5\xef\x94\x46\xe4\xdd\x02\x19\x57\xdd\x9e\x32\xf3\x69\x04\xc7\x88\x92\x28\x9b\xab\x51\xe6\x41\x88\x34\xa5\x62\x1f\x43\x30\xb1\x55\x61\x99\xc0\x2d\x74\xae\x9f\x59\x42\x30\x02\xc2\x5b\x88\xa5\xb1\xb5\x6f\x9f\xe0\x2b\x85\x90\x92\xf0\x95\xdb\x23\xd4\xad\x03\x7b\xfa\x1b\x41\x94\x48\x1b\xbc\x7f\xab\x5e\xf1\xc6\x53\xc3\xf8\x56\xcc\x22\x9f\xb9\xfd\xe4\xe6\x2a\x48\xa2\xd4\x1a\x89\x79\x79\x18\x3b\x88\x42\x31\x2b\xf8\xf4\x80\xef\x13\x86\x91\x2f\xa8\x77\x84\x50\x3a\x25\x9e\x17\xef\x34\xda\x33\xe0\x52\xab\xe9\xef\x85\x9d\x85\x66\x89\xd7\x05\xba\xab\xd4\xeb\x12\xcc\x5f\xe8\xcc\x6a\x65\xc1\x01\xf2\xb2\x69\xf7\x12\xca\x7d\x35\x3b\x73\x04\xc6\x8a\xe0\x27\x23\x2f\xd1\xe7\x98\xfd\xfb\x62\x16\x52\xf0\x79\x8d\xdd\x9c\x5d\x35\x39\x0c\x7e\xa2\xeb\x62\x58\x44\xbb\x94\x9f\xd6\x3d\x29\xdc\xc8\xd3\x17\x06\xb8\x9b\x5e\x9d\xaf\x49\x6a\x94\xd3\x67\x31\x9a\xeb\xbe\xd6\x09\xea\x8f\x3b\x2c\x0f\x5e\x8d\xb7\x6b\x95\xc4\xfc\xdb\xed\x4c\x37\x90\x17\x0f\x55\x7d\x84\xa2\x3f\x90\x9f\x07\x42\x36\x01\x61\xa4\x68\x9a\xdb\xe3\x6a\x3e\x94\x73\xfe\x8b\xc9\x53\x40\x18\x1b\x0a\x44\x3b\xcf\xb3\xdb\xff\x47\x67\x39\x84\x28\x28\x24\xb8\x3d\x42\x51\x38\xf1\x80\xa1\xad\x3f\x6c\x3c\x9b\xcd\xb5\x45\x8b\x74\xe7\xdd\xf4\x67\xa2\x84\x1b\x87\x85\x20\x63\xba\xdf\xe5\x20\x62\x01\xb3\x38\xea\x73\x83\x13\x0e\x91\xae\x2d\xa4\x7c\xfe\xde\x0e\xa2\x63\x49\xf5\x76\xf9\xfc\x27\x20\x93\x36\x60\x5c\x9a\xbc\x3e\x8e\xf3\xdf\x8e\x19\x5d\x40\x24\x53\x32\x8e\xf7\xae\x5e\x7e\x42\x96\xdc\xf7\x51\x44\x31\xbd\xfd\x28\xd5\x4b\x5d\x4d\xb0\x70\x5f\x26\xd9\x20\x42\xe9\x74\x43\x0b\xd2\x58\xb0\x41\xd7\xc9\x54\x86\xd8\x84\x8c\xf7\xe7\x9f\x25\xb7\xfe\x99\x97\xba\x7a\xf7\xdb\x02\x24\xa9\x53\x62\xa2\xc4\xce\xb7\xf3\xa2\xbb\xfe\x05\x1d\xe6\xd7\x8b\x09\x52\x48\xc8\x54\x27\xd6\xfc\xfd\xf6\xf1\x66\xb7\xef\xb5\xa2\x04\xa4\x46\xd3\x69\x67\xa1\x96\x54\xeb\x31\xf1\x27\x81\x21\x64\x1e\x0d\x4d\x88\x15\xdf\x90\x75\xce\x38\xe5\x45\x4e\xa0\x5e\x07\xbe\xb8\x69\x82\x04\x32\x11\x8a\x91\xe3\x68\xef\x3d\x7d\xc2\x4c\xc5\xb4\x32\xaa\xb2\xb3\x87\xbf\x0e\x1c\x40\xa6\x64\x68\x8b\xac\xda\x3a\xc7\x37\x74\x6c\x48\x5e\xa3\x64\x7c\xa2\x02\xcf\x24\xdd\x98\x60\x8b\xb3\x98\x31\x70\x91\x51\xb9\xd8\xd5\x39\x2f\x16\xb6\xaa\xbe\x97\xe5\x8b\x19\x49\x94\xcd\x2c\x0f\x10\x81\xa1\x52\x8d\xdb\xed\xfe\x7e\x75\xfb\xf0\xe0\xb9\x22\x04\x88\x30\xa1\xb8\xd2\x3e\x6f\x3c\x57\xb7\x5d\x0d\xb3\xe4\x1e\x08\xb4\x75\x92\x64\xce\xbb\x83\xa9\xbf\x3f\x64\x29\xc5\x10\x6f\x77\xd7\x55\x51\x40\xfd\xd7\xd1\x1c\x00\x09\x91\xdb\x40\xf7\xcd\x48\x7d\x5e\x80\x8a\x34\x39\x2d\xdb\xf3\x09\xeb\x5d\x4d\xb5\x7d\xcd\xf3\xae\x19\x54\xe0\x05\xa8\x38\xa6\x19\xb3\x69\xa1\x70\x55\x1a\x4e\x94\xe6\x93\x41\x52\x99\xcd\xef\xe4\xcd\x3d\x15\xee\x7c\xd2\x4d\x07\x51\x18\x8d\x82\xb3\x73\x90\x1d\x68\x6e\xb3\x18\x26\x37\xed\xcb\xfe\xfd\x13\xc8\x33\x68\x14\xd0\x0d\xb8\xb6\x02\x3f\x57\x9d\x47\x71\x11\x8b\x5b\x76\xf9\x01\x19\x8b\x1c\xaa\xcc\x22\x96\x2f\x61\xc0\xd3\xe1\xf5\xd7\x61\x4c\x47\xee\x7a\x3d\x3a\xf6\xc1\x04\x29\x65\x28\xba\xe3\xb7\xa8\x0e\xc3\x9f\x81\xa2\x65\x8f\x4f\x9b\x87\xf5\x8f\xdf\x7f\xb8\xea\x61\x21\x03\x61\xf5\x9a\xf3\x86\x94\x19\x67\xd3\x40\x06\x92\x8d\x74\x86\x9e\xba\xfd\x6c\x1c\x6e\x5e\x5a\xde\x32\x90\x2a\xed\x4b\xb8\x17\xf2\xf7\xe3\xc0\xaa\x0c\xa4\xa5\x25\xb3\x9a\x62\x6a\x40\x27\xc9\x28\xb4\x6a\xe9\x14\x07\x5a\x06\x1d\xca\x28\x0a\xa3\x60\xa4\x86\xf8\x29\x75\x8a\x90\x51\x62\x15\xa8\x40\xeb\xf5\xb9\xcd\xed\x29\x95\x04\xf3\x5e\x69\x44\x67\xc1\x11\x5e\xf1\x71\x09\x85\xfb\xf7\x62\x62\x32\x4a\x81\x18\x4b\xfe\xec\xf5\xcb\x27\xf3\x4a\x46\x2c\x23\xdd\x88\x5d\xae\xa8\xd9\x06\x28\x5d\x63\x1c\xdb\xdd\xe7\xa9\x70\x31\xc8\xcb\x62\x6b\xee\xbb\xa6\x19\x51\x97\xc3\xb9\x75\x40\xe7\xd9\x0f\xc5\x19\x50\x29\xbe\x99\xc7\x38\x64\x6c\x2c\xbb\x00\xb9\xb6\x52\xe6\x97\x5c\xde\xbd\xde\xc2\xf8\x9f\xbf\x88\x75\xc8\x34\x60\x96\xf7\x86\x9e\x66\xa8\x14\xf4\xcd\x29\x66\xc9\x20\xfd\xe0\xe2\x7b\x17\x4e\x82\x4c\x33\x4e\x03\x74\x3c\x17\xed\x4f\xfc\xc4\xc5\x93\xa9\x02\x62\x23\xec\x76\xe9\xde\x8c\x9a\x0e\x00\x0b\x05\x95\x61\x5f\x63\xa3\xea\x9c\x62\xda\xe4\x5a\x53\xd7\x05\x1e\x33\x21\x59\x1a\x2a\x4b\xaa\x47\xa0\x53\x6f\x63\x4d\x61\x6a\x92\xc9\xd0\xd2\x18\xd0\x7b\x5e\xe5\xcb\x0c\x30\x42\x66\x71\x48\x11\x73\x7b\x96\x76\x63\xdc\xf4\x45\xe0\x8b\x0b\x5b\x66\xb1\x8d\x02\xed\x65\xbc\x54\xc7\x2f\x64\x86\x8c\x78\xcf\xbe\x6d\x1e\x9e\x46\x6b\x5f\xf2\x00\x43\x39\x08\x23\xb8\x07\xbe\xa9\xab\xe3\xba\x3a\x1e\xab\x72\x9b\x1f\x4a\x20\xb6\xfc\xbf\xc2\x8a\xff\xd5\xdf\xc7\x2b\x98\xc7\x56\x6f\x80\xa2\x28\x57\x50\xbe\x7e\x4a\x1e\x2a\x24\x57\x48\xde\xee\x3b\xe6\xf3\x82\x47\xc9\xb5\x22\x73\xb5\x39\x97\x8d\x25\x07\xb5\x5b\xed\x58\x7e\x43\x48\x8e\x81\x19\xca\x20\xc6\x13\xe7\xcb\x43\x5a\x72\x64\xb1\x83\x1d\x3e\xdd\xda\x64\xa4\xcf\xea\x4a\x60\x49\x6a\xc7\xad\x73\x5e\xe6\x94\x5b\x42\x4a\x40\x02\x0d\x6e\x1f\x1e\x7b\xe7\x4d\x2a\x61\xe5\x07\xe9\x78\xbf\x5d\x3f\x4e\x70\xa0\x12\x21\x34\x76\x63\xca\x4b\x5d\x57\xa7\x89\xc0\x89\x90\x68\xa2\x2c\x19\x0a\x90\xab\x72\x5d\x55\xb5\xce\x4b\x68\xf1\xf3\xdd\x7f\x79\x09\x98\x20\xa6\x98\xda\xc3\xd5\xea\xb1\x2c\xf2\x12\xef\xe0\x5c\xaa\x97\xa7\xba\x3a\x56\xe3\x05\x65\xd2\x84\x38\x29\xef\x57\x0f\xdf\x57\xbb\xdd\xea\xe1\xe9\xf9\xf1\xcf\x7f\xfd\xdc\x7e\xff\xe9\xf3\x58\x2a\x50\x09\x05\x84\xdb\xea\x2a\x8e\x96\x57\x9c\x0a\x10\x08\x9a\x5c\x03\xd1\x22\x58\x69\xac\x69\x97\x90\xa7\x14\xc1\x1b\x4e\xcb\xfd\x09\xea\xf6\x63\x2f\xf7\x07\xec\x8d\x08\x15\x31\x41\xe4\xff\xd7\x9b\xbb\xdb\x3f\x36\xcf\x9b\xeb\xfd\xcd\x66\xb3\xbf\xb9\x5b\x7d\xeb\x7b\x64\xd2\x2a\x39\x9d\x65\xd3\x57\x24\x2e\x0f\x83\x8a\x38\x52\x9d\xf4\x76\xfb\xf4\xd4\x93\xb6\xcd\xb2\x31\xbe\xab\x48\xa4\xd3\x22\xbc\xa7\xda\xd2\xfe\xf7\x0c\x83\xc0\x2b\xd1\x95\x26\x3f\x78\x58\xd9\x67\x5f\x62\xf2\x04\x31\x8f\x28\x54\x78\x24\x62\xc1\xab\xf3\x85\xa2\xaf\xeb\x97\x70\x8b\x48\xc1\x92\x50\xc5\x3e\x2e\xa5\x52\x08\x2d\x29\x09\xd9\xe5\x7f\x60\xe3\xc1\x65\xbe\x5d\x6b\x17\x93\x6e\x5d\x05\xca\xbc\x5a\x70\x9e\xeb\x51\xa9\x89\x3d\xff\x80\xd3\xe3\xec\xb3\x47\x8a\x25\x96\x40\xaf\xc1\xf6\xe9\xf1\xf1\xce\x2e\x89\x74\x52\x28\xa9\x58\x16\xd8\x59\x6c\xf3\xdd\x8e\x5c\x60\x8a\x96\x75\x5d\xb3\x38\x64\xa2\x07\xfd\xd0\x5a\xe8\xbc\x38\x1f\xe7\x53\x99\x60\xc4\x7f\x4f\xe2\x22\x9f\x9d\xa5\x93\x1f\xcf\x84\xa2\x87\xff\xfe\x8f\xef\x97\x7a\xa7\xc3\x70\x66\x02\x09\xc4\x6c\x45\x69\x27\x67\x91\xca\x20\xa6\x14\xe2\x5d\x75\xb0\x3a\x8a\x5f\xe7\xe5\x54\x26\x99\x1f\xaf\x7b\xf8\xb5\x1d\x40\xea\x4a\x70\xf0\x3c\xd4\xeb\x71\x40\xbd\xff\x29\x61\x0c\x41\xed\x2d\x73\x0b\xf1\x3c\x4d\x9f\x05\x18\x72\x36\x0a\xf6\x5c\x81\xd7\x04\x12\x0a\x14\x32\x9b\xc9\x03\xfd\x6b\x9c\xe5\x54\x60\x32\x0a\x8f\x76\xf6\xc8\xf6\x1d\x2e\xc8\x81\xa7\x87\xaf\x52\x1c\x08\x41\xfc\x6d\xa2\xd5\x2f\x94\xd2\x9a\x92\x7e\xf6\x10\x7a\x46\xb3\x88\x09\x53\x5a\x68\xd9\xed\x69\xbf\xe7\xef\xf9\xe8\x60\x51\x5a\x23\xe9\x88\xa3\xb2\xac\x84\x53\xcb\x76\x7a\x7c\x2a\x8c\x2d\x23\xb8\x46\x49\x24\xd6\x93\xfd\x5b\x61\x66\xb9\xe3\x1d\xdd\xf4\xfa\x05\xba\xb3\x15\x27\x78\xc7\xd0\x7f\x0f\x34\x81\xec\x4d\xc0\x3e\x77\xb8\x54\x5a\xa2\x8c\x4a\x59\xf7\xe8\x9b\xdd\xf7\xcd\x33\x94\x03\x5c\x5f\x07\x81\x09\xc7\x04\x94\xcb\x11\xe6\x99\xdc\xa2\xd0\x41\xe7\x87\x92\x60\x47\x5b\xbd\x8e\x07\x53\x07\x5c\x59\x27\x9b\x50\x86\x87\x6a\xa8\xce\xd4\xa1\x11\xe4\x76\x80\x6a\xbb\x3d\x60\x02\x2c\xd2\x51\x10\x5b\xea\x64\x57\x69\x83\x34\xc7\x8a\x62\x09\x43\xaa\xa3\x00\x52\xe3\xd3\x64\xe7\x66\x0e\xaa\xd0\x51\xc8\x8c\xd3\x42\x33\x63\x0f\x53\x47\x2c\x48\x7b\x90\xde\x1a\xd4\x8b\xe3\x74\x7d\xc6\x53\x55\x53\xbc\xb4\xb1\x4c\x58\xbe\xbf\xc4\x38\xf0\xb4\x55\x3d\x8d\xe4\xea\xdc\x56\x65\x75\xac\xce\xcd\x85\x96\xda\xf4\x39\xe2\x50\x90\x19\xe4\xb0\x88\x3f\x2e\x9f\x34\x0e\xad\x78\xd0\xba\xaa\x27\x00\x6f\x1d\x27\x31\xa5\x70\x5c\x71\x78\x3c\x2e\x0e\xd7\x49\xc4\xd1\xf1\xf8\x4d\x8b\xf2\x2f\x16\xc0\x45\x2e\x43\x27\x18\x91\x87\x4c\xf5\xdd\xdd\x08\xdf\x8d\x52\x65\xcb\x4b\x5f\xa7\xa1\x52\xae\x7c\x97\xa0\xf4\x79\x79\x70\x02\xe6\xae\x03\x63\x86\x3a\xa0\x31\x48\xda\xdc\x36\x98\x3e\x62\x97\xea\x97\xa3\x8b\xf5\x68\xee\x22\x68\xdd\x8e\xbd\x7e\x7c\x7a\x19\x56\xbc\xe6\x5a\x91\xd3\x7b\xb5\xf1\x5c\xb9\x42\x83\xb6\x15\xcc\x44\x55\xb3\xab\xce\xf5\x5f\xd3\xd5\x68\x09\x11\x11\x00\xcd\xf4\xd4\x3f\x79\x49\x95\x22\x4d\x1a\xa7\xeb\x3a\xab\xa6\x5f\x3c\xae\xb4\x0e\xe3\xc4\xf2\x9e\x51\x36\xf2\x63\x94\xd1\xd2\x3a\xb1\x35\x35\x79\xd3\x99\x6b\x79\x79\xbb\x7e\x24\xb6\xf7\xd9\x5c\x46\x48\xe3\x71\x1a\xe1\x21\x57\xaf\xe5\x8c\xc7\x4c\x68\x13\xb2\x80\x7b\xc1\xdf\xf2\xb0\x48\x97\x83\x41\xc4\xa5\x9d\x16\x6f\x79\x83\x75\x4f\x58\xb9\x38\x39\x31\x50\x59\x1a\xf6\x73\x9b\x02\x1d\xd3\x08\xf2\x97\xc3\x85\x61\x10\x73\xc7\x2f\xec\xee\x6b\x2a\x75\x6e\x14\xd4\xda\x33\xd0\x0b\x0c\x91\x93\xb7\x8b\x23\x22\xad\x9b\x1f\xbb\x3f\x7d\x7b\x14\xa4\x91\xa3\x85\x23\x4d\xc5\xd9\xf2\xc0\x28\x4a\xe9\x0b\xe6\xcd\xfa\xdc\xb4\xd5\x11\xeb\xef\xd0\x5c\xd8\xa0\x18\xb1\x98\xd0\x0e\x23\x6f\x71\x39\x0c\x3e\xbd\x2c\x0e\x42\x32\x97\xcb\x1e\x82\xb9\xab\x9e\x60\x5a\xfc\x8b\x71\x68\x49\xf4\xdd\xa5\x0f\x55\x6b\xc9\x78\x06\x1d\x2c\x81\x71\x6c\x6b\x49\x36\xbf\xff\xde\xff\x29\x71\xb5\x42\xcd\x6d\x79\x93\x97\xb6\x46\x6d\xb8\x40\xa4\xe8\x68\x92\x1e\xcb\xed\x47\xd9\xbe\x60\x93\x77\xb3\xd9\x73\xa4\x2c\x8f\x79\x0c\x46\x48\x07\xd6\xee\x1c\xab\x79\x44\x02\x63\x04\x1e\x7b\x56\xe7\x87\xca\x5a\x6a\xf5\x11\xf5\x72\x21\x34\x26\x89\x22\xc4\x57\x55\x83\x2a\xf2\xff\xe2\xde\xe9\x44\xed\xcb\xa1\x6c\x1c\x13\x66\x93\x4a\xff\x3c\x3b\xa9\xff\xdf\x96\x4c\x12\x4c\xb4\x0a\xb9\x97\x4c\xdc\x7d\x5f\x06\x5b\x61\x1a\xa5\xc6\xea\xd3\x91\x54\xea\x7a\x89\x27\x5f\x60\x1a\x2b\x18\x94\x59\x88\x43\xcc\xc2\x71\x97\x5f\x23\x4d\x14\x15\x27\xee\x5b\x78\xc5\x47\x63\x28\x9c\x3f\xf1\xc7\x7d\x47\xb0\x34\x25\x57\x9b\xdd\xf6\x9f\x3f\x06\xe2\x15\x64\xa1\x8d\x2a\x1c\xf3\xb2\xed\xac\xcb\xcf\x51\x4a\xb3\x9f\x66\xa9\x4c\xfc\x36\xd6\x3c\x63\xd9\x5e\x7d\xac\xda\x6a\xfa\xeb\x3d\x3d\x16\x66\x46\x13\x8b\xbc\x41\x1c\x71\x07\x20\x4f\x14\x81\x00\x37\x7f\xee\xf6\xeb\xc7\xfb\xa7\xd5\xc3\xbf\x2c\x0f\xf9\x7e\xf7\xf3\xb1\xef\x94\x86\x34\x26\xfb\x81\x99\x67\xd9\x88\x46\x2e\x84\x27\xea\xbe\x00\xd1\xf9\x2e\x52\x53\x8e\xe4\x35\x2f\x8a\x7b\x6c\x5e\x48\xc7\xe0\x62\xb3\x5b\x5c\x35\x5c\x87\x60\x4b\x98\xcf\xa5\x0e\x37\xa5\x1e\x01\x1d\x50\xa0\x26\xf0\xd6\x15\xa8\xd7\xf3\x69\x0e\xf8\x9a\xde\x08\x98\xdd\xae\xbc\xed\xb1\x21\xec\x91\x2d\x1e\x3d\x5f\xca\x1e\xf8\xab\xa4\xa1\xb5\x2e\x7b\x91\x97\xe9\x34\x94\x71\x22\xc2\xde\x4c\xcd\x8f\xe7\xa3\x03\x85\xfa\x47\x94\x69\xa2\x2d\xa8\xa3\x7a\xf5\x40\xa7\x3f\xf2\x8b\x5a\x3c\x94\x60\x67\xea\x9f\xee\x7f\x41\xf4\x19\xd6\x10\x15\xe3\x10\x8f\x08\x69\x3e\x59\xbe\x0a\x14\x38\x96\xcc\x45\xcd\xed\x59\x6f\x65\xc5\x83\x1b\x5f\x45\x48\xbb\xdb\x34\xd0\x82\x1a\x32\xca\x2d\xfd\xbb\xa9\x4a\x57\x7a\xf5\x39\x58\x18\xb5\x64\x2c\xf0\xe5\x2c\x37\x36\x1f\x34\x7b\x6b\x8d\x11\x05\x4e\xb7\xb6\x0e\xa1\x6a\xa7\x07\x11\x1a\x67\x5a\xed\xb0\x69\xa3\x7f\xf8\xc7\x30\xc2\xd6\x2f\x3d\xbd\x60\x99\xff\xfa\x9b\x20\x46\x34\x10\x65\xde\xa5\x2c\x2e\x92\x52\x26\x48\xd3\x28\x1c\xb9\xca\x76\x5d\x4e\xea\x95\x4c\xc8\x52\x0a\x47\x8d\xa8\xc3\x16\x19\x87\xa7\x63\x6b\x62\x16\x45\x5e\x51\xe6\xa5\x33\x51\xc7\xd2\x26\x83\xd2\xc9\xf8\x69\x4d\x92\x71\xcb\xfb\x4a\x28\x64\x32\x4b\x1f\xcd\x4f\xcc\x9f\x20\xd7\xbb\x8a\xf6\x28\xff\x54\x89\x86\xcc\x6b\x00\x9f\x15\x36\xcd\x3c\x1b\x66\x12\x8d\x04\x4f\x33\xb9\x0b\x01\x76\x36\xa5\xbf\x3c\x95\x4c\xb2\x9e\xeb\xaf\x46\x68\xce\x5e\x09\x49\x18\x16\x33\x8b\x3a\x72\x42\x14\x56\x4c\xba\x8f\x5e\xcd\x4c\x7f\xc3\x92\x88\x20\x2f\x8e\x1c\x31\xea\x6f\x93\x48\xaa\xa1\x57\x50\xa8\xdd\x9c\x62\xc5\x30\x66\x65\xe7\xf3\xe6\xc6\x16\x43\xdc\x58\x08\x5d\x7f\x82\x99\x2c\x06\xda\x40\x0c\xf6\x4e\xba\xe1\x68\x29\xe1\x28\x70\xf3\x0e\xf5\x9c\x0b\x76\xba\x92\x8d\x88\x5d\x8d\x5a\xe7\xeb\x34\xdb\xaa\xf0\x66\x83\x11\x29\xb2\x41\x73\xb2\xc1\x21\x8d\x65\x64\x18\x24\xb4\x0b\x2a\x28\x8a\x67\x54\xf9\x69\x5c\xfa\xf8\x75\x4c\xce\xff\x7f\x1f\x72\x33\x32\x89\x09\x46\x97\x97\x39\x29\x0a\x6c\x71\xb6\x0b\x18\x15\x24\xc6\xa3\xb2\x4c\xdb\x8d\x86\x0b\x56\x7d\x69\x18\x1a\x25\x32\xca\x52\x3a\x1e\x57\x2c\x50\x7e\x12\xa2\x19\x15\x60\xfe\x2f\x73\xb1\x09\xa3\xa3\x20\xe8\xde\xf2\x9f\x4f\xdb\xcd\xd8\x2d\x30\xda\x15\x08\x5b\x59\xf6\x5f\x79\xfb\x71\x53\xd5\x57\xad\x72\x23\xfd\x54\xa3\xc9\x89\x7c\xc6\xa5\xab\x27\x30\x3c\x7f\x0f\x95\x3a\xe2\xa1\x76\xf3\xeb\x44\x61\x46\x5b\x4e\x32\xeb\x86\x9a\xb2\x3b\x63\xcf\xda\x37\x99\x88\xe8\x8d\x1e\xff\xd8\x3c\xaf\xee\xee\xb6\x03\xbe\xd1\x18\x6e\x68\xd7\xb4\x21\x05\xed\x92\x3d\x9f\x9d\xa5\x13\xdb\xc0\x18\x19\xd1\x31\xee\x06\xcd\x85\x96\xb7\xaa\xfb\xc2\xf9\x54\x0e\x58\x18\xa3\x33\xcf\xcb\xf7\x00\x47\x2c\xb0\xe9\xdc\x02\x35\xf0\xff\x19\x83\x56\x40\xd3\xef\x1f\x8f\xc5\x34\xd8\x05\x41\x10\x18\xe7\x64\xa1\xa7\x34\xfa\xcd\x37\x25\x0c\x5c\xd3\xad\xb2\xae\x99\xc5\xef\x37\xb3\x7b\x84\xa9\x25\xf8\xf2\xa7\xd8\xc9\x2a\x02\x2d\x4d\x0b\x08\x42\x4c\x63\x97\x9e\x5c\x75\x7e\x52\xee\xe2\x83\xa1\xef\x10\x45\x36\x12\x5b\xe2\xbb\xa3\xcc\x2f\xbc\xf7\x0a\x41\x94\xe8\x70\xfc\x42\x1e\xb6\xf1\x05\xf1\x17\x04\x51\x26\xa9\x72\x99\x0c\xfc\xeb\xea\xbd\xdc\x55\x9b\x72\x54\x59\xe3\xbb\x41\xa4\xdc\xd9\xf4\x87\xf3\xc0\xe7\xa3\x15\x87\x19\xfd\xfc\xf7\xd5\xf3\xf5\x90\x93\x86\x20\x4e\x51\x1b\x67\xf8\x59\x3b\x9a\xf6\x92\x5d\xb5\x2a\x8a\x05\x2b\x0c\x82\x58\x21\xf7\x5a\x8b\x57\x04\x72\x5a\x88\xd2\x2d\xfd\x97\xbb\x3e\x0d\x63\x9a\x27\x56\xc1\xf3\xfe\x71\x77\x83\xe8\x5d\x98\xdf\xa6\x6f\x9f\xc6\x4c\x98\xde\x1a\x70\x96\x7d\x7f\x23\x16\x48\x65\xdd\x8b\xc7\xf2\x6e\x8e\x8c\x86\x80\x45\x40\xac\x36\x77\xd5\xc1\x32\x8b\xcd\xdb\x33\x64\x63\x5d\x24\xcf\x1a\x36\x1d\xb6\x4c\x48\x4a\xd9\xaf\x8e\xd8\xbe\x7c\x34\xed\x10\x3b\x82\x20\x43\x5b\x1c\x93\xab\xea\xb6\xb9\xa4\x53\x80\x80\x07\x28\xac\xc8\x80\xac\x4a\x7d\x53\x57\xc7\x1f\x65\xf7\x5f\x9f\xd8\x7e\x10\x70\xa1\x09\x86\xec\x5a\xdd\x36\x30\x7d\x22\x11\x33\xc2\x2a\x29\x6f\x84\xe0\x7d\x73\x98\x90\xe3\xf6\x23\x04\x71\x46\x6e\x4c\x89\xef\x7b\xef\xd6\x41\x00\xa8\x08\xf8\x31\x10\x05\x5c\x6f\xfe\xdc\x5d\x7e\xc5\xd9\xb3\x69\x16\x53\xed\x01\x31\xe0\x4e\xc1\xa4\x5d\x63\x42\x14\x29\x8e\xe0\x96\x72\x25\xae\x09\x83\x24\xb4\xb0\x20\x3c\xf5\x9c\xdb\x10\x60\x94\xd0\x81\x8c\xed\x0b\xd6\x3d\xd7\x7c\xbf\xbb\x43\x60\xc2\x88\xac\xed\x43\x0d\x1e\x71\x70\xf5\x61\x69\xbb\xbf\x32\x0f\x20\x30\x69\x4a\x19\xf5\x81\xcd\x11\xd8\x25\x99\x23\x84\x41\x1a\x93\xb5\x6b\xa5\x00\x09\x98\xea\xb1\xdc\x10\x06\x60\x29\x8e\x0f\xd8\xee\x5f\x72\xad\xb1\xdc\x3b\x43\x74\x36\xc8\x61\x08\x40\xd6\xc8\xf1\xdc\xe6\x5b\xeb\x3d\x51\x4d\x39\x1c\xa7\xda\x8f\x33\xbb\x13\xc2\x50\x32\xe2\x60\x58\x95\x15\x15\xe0\x0f\x46\xd0\xd7\x2f\x18\x46\x11\x12\x62\x6b\xfb\xb4\x59\xef\x9e\x7d\x15\x2a\x84\x11\x0a\xc2\xd3\x51\x81\xb7\x05\xd9\x7e\x5a\x85\x0b\x61\x9c\xa8\xc0\x62\xd9\x6f\x6a\xec\xc9\xbd\x9c\x8e\xa6\xbf\x65\xc2\x02\xf0\x28\xba\xfe\x45\x42\xf6\x7f\x8b\x07\x27\x84\x89\x34\x14\x51\x91\x79\x59\x1d\xf3\x4f\xea\x99\x20\x4c\x03\x1b\xc5\x72\x68\xa2\x55\xa9\x1d\x35\x94\x2f\x2a\xf8\x04\x90\x3e\xf3\x1f\xff\x37\xf2\x1a\xf9\x51\x2f\xd6\x3a\xfd\x4f\xff\x7b\x19\x27\xd3\xc6\x02\x06\x47\xa0\x58\x08\x53\xe9\xc4\x8b\xad\xc8\x50\x0f\xac\xf1\xc0\xf9\xb0\x7f\x66\xcc\x48\xfb\xd3\xa1\x8f\xbb\xc5\x7c\x87\x07\x50\x1f\xcf\x78\x9a\x42\x30\x21\x64\x2a\x0d\xd1\x45\x38\x3f\x1e\x3b\xef\xdc\x9f\x6b\x10\x32\xe4\xa1\x15\x68\x6d\xb1\x3e\xe6\x25\x3e\xdd\x5e\x4f\x57\x78\x67\xa3\xe3\x04\x68\xba\x6d\xab\xd3\x68\x69\x84\x19\xcb\x5c\x82\xb6\x3b\x60\x56\x7a\xd9\x47\x83\x30\xe3\x5a\xd8\x1d\xb2\x2f\x66\x9c\x6e\x82\x21\x0f\x0c\xfa\x9a\xf3\x7f\x9e\x81\x7c\x38\xff\xa4\x22\x40\x1a\xb5\x3b\xc4\x7a\xaa\x95\x07\x21\xb0\x38\x1d\x24\x7b\x1f\xf0\xfd\x19\xdf\xf2\xa6\x57\x84\xf2\x5c\x5c\xce\x38\x80\x50\x41\x28\x5c\xe5\xe9\xfe\xe4\x72\x6b\xdd\x82\x1a\x81\xb7\x5d\x4f\x2d\x20\xd3\x03\x86\x8b\xce\xa2\xde\x45\x85\x10\x03\x8e\xce\x4a\x75\x53\x75\xf9\xfc\x1c\x82\xdf\xfe\xc2\x2c\x8c\x03\x57\xb5\x4a\x65\xd4\x33\x63\x1b\xa2\x40\x82\x1e\xc3\x6f\x6f\x4b\x55\x1d\x97\x29\x1a\x20\x0a\x50\x68\xd3\x53\xfb\x90\x60\xc0\xe4\x8d\xa3\x50\x49\x82\xe1\xbe\xd9\x88\x2b\xc9\x5e\xfd\xe6\xdb\xd0\xa2\xe0\x64\x81\xa0\x5e\x46\xb6\x3b\x44\x11\xa4\x74\x64\xb8\x98\x64\xcf\xad\x34\x1a\x83\x28\x02\x41\xd5\xdb\xb6\x1c\xd0\xbe\xff\xac\x02\x00\xa2\x38\x52\xbe\x56\xd8\xa1\xb6\xe8\xad\x6f\xcb\x09\x0c\x10\xa2\x38\x16\xc2\x13\x79\xe7\xb6\x2a\xfe\xea\xe3\x12\xd7\x01\x51\x9c\xc5\x94\xed\x6f\xce\x27\x22\x99\xeb\xcf\xc1\xa8\x73\x26\xe2\xbe\x7a\xac\xdf\x4a\x66\xc2\x55\xae\x73\xa2\x33\xaa\x4c\xd0\xd5\xf6\x9c\xab\x5c\xf7\x6f\x95\x46\x09\x55\xfb\x5a\xb0\x24\x7d\xdc\xab\xf3\x47\xdf\xea\x4a\x97\x2d\x58\xd1\xd1\xc9\x5b\xfd\xb6\xe9\xfd\x53\xa6\x01\xfa\x0f\xe3\xf8\x04\x51\x9d\xfb\xa2\x8e\x19\x64\xd3\x5f\x96\x19\xa7\x10\x88\xea\xf5\xe6\xdd\x3b\x3f\x8e\xba\xdb\x3f\x05\x4b\x32\xda\xb2\x41\xeb\x7b\x6c\x1a\x38\xe0\xae\xfa\xe7\x19\xcf\x73\xbf\x7d\x3a\x57\x78\xac\x33\x5b\xf5\x76\x3c\x15\x94\x07\xf7\x0d\x42\x87\x43\x51\x8b\xb5\x52\xbe\x55\x50\x4c\x74\x4f\x20\x12\x2c\x20\x46\xe5\xf2\x7c\x1c\x40\x01\xfd\x4d\x84\x8a\x89\x1e\xe2\x7e\x7d\xb5\xfa\x1b\x81\x53\x88\x84\x31\x64\x80\x59\x35\x5e\x22\xda\xfb\x64\x50\x20\xb0\xe4\xac\xf7\xeb\xed\xc8\x8f\x81\x48\x26\x4a\xbb\x61\x58\x1d\x6a\xc4\xd9\xd4\x97\xc2\x62\x57\xbf\xfd\x5a\x43\x41\xbb\xce\xd5\x87\x45\x8f\x75\x3b\xeb\x25\x1d\x39\x44\x52\x25\x54\xee\x69\x7a\x3e\x60\xd7\x40\x79\x4e\x2b\xbe\xd3\x0c\x0e\x2c\x44\x9a\x67\x3c\xf1\x1c\xe5\x14\xf1\x1f\x95\x44\xb9\x3e\x26\xb4\xce\xf3\x55\xde\xfe\xf3\x9c\xab\xd7\x53\x7f\xba\x47\x86\x21\x29\x8d\x0d\xca\x6d\xb6\x8e\x72\x9a\x8f\x19\x7f\xc4\x38\x08\x12\x22\x41\xbd\x87\xfa\xf5\x19\xc1\x7f\x9c\x38\x08\x34\x1b\xbe\xa1\x2b\x67\x9b\xe6\xbd\xa6\xd3\x21\x0e\x92\x94\x92\x6c\xbd\x67\xf3\x86\xb5\x29\x06\x39\x69\xdf\x8d\x31\x4a\xfb\x7f\xdb\xf6\xc7\xcb\xec\x3e\x4a\x93\x9b\x7f\xaa\x9a\xd6\xba\xb5\x33\x2e\x39\xd7\x2f\x0c\x25\x8d\xd5\x36\xef\xbc\xce\xce\xdd\x72\x15\x85\xfe\x15\xc2\x24\x22\x33\xd1\x92\xd8\xee\x7e\xed\xa0\x79\x25\xf2\xf9\xe5\xbd\x2f\x0e\x13\x49\x98\x77\x67\xed\xcc\x9e\x3b\x14\x56\xec\xf9\xe1\xff\x1b\xcf\x99\x38\x8a\x25\xcd\x99\xdc\x29\x6e\x7f\x8a\x67\x83\x38\x82\xb8\xf7\x30\xdc\x48\x7e\x45\xf6\x03\x71\x1c\x6b\xda\xdb\x77\x58\xe0\x3b\xbc\xe1\xc8\x48\x8f\x63\x57\xfb\x7e\xc0\x16\xea\x83\xaf\xce\x81\x38\x49\x2c\x83\xfe\x75\x0d\x87\x19\x3b\xb6\xef\x21\x74\xe4\xc5\xf7\x4f\x58\x5e\xe5\xba\xb9\xfa\xb8\xcb\xcb\xd9\x74\x8f\x13\x13\x88\x81\x6e\x56\xbb\xf0\xb1\x87\xb4\x4d\xef\x99\x66\x32\xb4\x54\x9b\x6b\xcf\xe6\x42\x81\x99\x3e\x46\x02\x31\x8b\x85\xc0\xc1\x07\xe8\x1f\x98\xa5\x96\xb2\x0b\xcf\x35\x69\x07\xe9\xa1\x21\x09\x1c\xd9\xdd\x4f\xcc\xfd\xbe\x10\x67\xb1\xa6\x40\xc1\xc4\x5e\xff\x3c\xe1\xc8\x67\xf2\x86\x10\x67\x29\x50\x51\x17\xa1\x9f\x9a\x59\x2d\x6f\xe7\x5a\x28\x9a\x9f\xfb\x23\x1c\x72\x35\x9b\x73\x19\x08\x72\x64\x7e\xff\xbe\x9e\xcc\x02\x0e\x01\x55\x65\xd8\x64\xbb\x05\x9b\xcf\x83\xa8\xfd\xc0\x72\x29\x88\x69\xcc\x9c\x3b\xcb\x62\xfd\x92\xcb\xfc\xaf\x00\xa4\x97\xd5\x42\x10\x83\xb4\x2a\x42\x9d\x9f\xd8\x63\xfc\x67\xdf\x1a\x8c\x2d\x7e\x3d\x78\x9a\x80\x87\x4a\xe3\x27\x4e\x79\x2c\x83\x98\xde\xfc\xe9\x6e\xb5\xbb\x79\x7c\xbe\xdf\xdf\xfc\x78\xb8\xbe\x7d\xf8\xb6\xb7\x6a\x0a\xfe\x5d\xa5\x48\x09\x7b\x65\x0f\xb4\x3e\xd9\x3c\xbb\x97\x0a\xa8\xc0\xde\x20\xae\x2b\x22\xfe\x9d\xc4\x88\xa1\x5b\x35\x34\x7f\x09\xa8\x42\xe7\x5e\x67\x9a\x4e\x9f\x5e\xe9\x80\x00\x50\x8a\x98\xc4\x3c\xbe\x6c\xf6\x4b\x3a\x8c\x08\x72\x54\x3a\x64\xf5\x6d\x8b\xc7\x66\xc2\x78\x00\xb1\x4e\xa3\xd8\x8c\x84\xb4\xee\xaa\xee\xd3\x4e\x7f\x0c\x13\x61\x1c\xd5\x0a\xd6\x50\x38\xe4\x8c\x63\x5a\x98\x3d\x3c\x72\xf4\xdb\xf4\xea\xdc\xbe\x54\xdd\xd6\x5e\xcf\x9e\x0b\x35\x50\x1f\x4a\xb2\x5b\xd8\xf7\x4d\x55\x5b\xb1\x77\xbf\x61\xc7\x26\x8b\x32\x31\x31\xb7\x9e\x89\xd7\xec\xe2\x6e\x86\x47\x71\x2f\xe5\x74\x29\xe4\x00\xb1\xd1\x26\xb0\x24\xfd\x47\xc8\xcb\x89\xa8\x08\x24\x41\x64\x31\x29\xd6\xac\x25\x15\x6f\x2b\x14\xe2\x23\xcc\xa3\x8c\xfc\x74\x65\x27\x81\x4a\x89\xb3\xd4\x27\x4b\xff\xba\x2e\x1f\x92\x30\xe1\x1a\x3d\x49\x16\x15\xcc\x34\x44\x45\x06\xc5\x18\x6c\x30\xbb\x28\x62\x9c\x98\xe1\x74\x45\xda\x4e\x8b\x27\x77\x12\x99\x4c\x0f\x6e\xcd\xf6\xa5\x9a\x06\x01\x21\x49\xb2\x98\x84\x90\xb6\xa7\x02\x4b\xdd\xbb\x89\x61\xc4\xff\xe7\xab\x7f\xe7\x2b\xef\xab\xfe\x9f\x45\x75\x3f\xf9\xd7\x3d\x58\x1a\x31\x22\x0e\xbb\xab\xd4\x2b\xd1\x47\xdb\x56\xbb\x88\x66\x2f\x91\x82\x21\x14\x82\x95\x4e\x72\x13\xc3\xa6\xe9\x97\x52\x8d\x90\xa4\x3a\x46\x33\xf2\x1e\xba\xfd\xec\x8a\x48\x06\x47\x94\xdf\x5f\x7f\x33\x16\x27\x54\x12\xe7\xc4\x2f\xeb\x0f\x92\x24\x69\x96\x72\xfa\x90\x64\x81\x14\x83\xd5\xea\x35\xd1\xf2\x0b\xfa\x19\x48\x32\x8d\x74\xa6\xda\xb2\x41\xff\x47\x64\x24\x62\x54\xae\xcf\xf5\x5b\x6f\x36\x26\xdc\x70\x35\x30\x6d\x74\xde\x3b\x81\x71\x2e\x26\xcc\x0c\xf8\x03\x89\x90\x22\x75\x27\xd5\xfd\xc7\xa8\x88\xc4\x35\x43\x62\xeb\xf1\x5e\xaa\xf7\xfe\x4f\x22\x72\x9e\xec\x5b\xf5\x8a\x2e\xb7\xea\xdb\x94\xa0\xf0\x97\xe7\x90\xdc\xb4\x2f\x97\x4c\x89\x90\xc8\x98\x51\x9c\x8d\x36\xb7\x0b\xde\x4a\x48\x64\x92\x12\x02\x4b\x55\x8e\xd4\xd3\xdf\x5f\xa6\x16\x3a\xa6\xf3\x86\x8e\xa0\x11\x16\x08\x12\xc9\x18\x95\x80\x36\x2d\xbc\x62\xff\x47\x91\x10\xaa\xe1\x05\x6a\xdd\xfd\xd2\xf6\xfe\xa2\xaa\xd4\xf7\x44\x85\x5e\xbc\x12\x55\xdb\x79\xf3\xa3\x22\xc2\x4f\x2e\x52\x61\x28\x9d\xef\xf9\xfd\x43\xd7\xd5\xb6\x85\xd7\xbc\x3c\xdc\xe7\x65\x7e\x3c\x1f\x67\xaf\xa5\x24\x27\x92\xb3\xab\x1a\x5f\xaa\xbe\xd8\xd8\x96\x41\xf8\x6d\x2d\x51\x12\x68\x33\xda\x76\x4e\x9a\x85\x48\xf4\x5c\x5b\x2c\x71\xbc\x54\x33\x38\xba\xd3\xb5\x83\x44\x2b\x45\x70\xf4\x5d\x3d\x57\xf7\x98\xfb\xc2\x9f\x25\xf1\x20\xd1\x18\x0a\x5b\x48\xd7\x59\x91\x53\xc3\x26\xc1\x38\x26\xfa\x9a\x1a\x5a\xdc\x5f\xed\xd6\x7d\xf1\x27\x24\x86\x09\x61\x8b\x09\x7e\xd9\x2d\xbb\x6f\x00\x9b\xe0\x3d\xc2\x2f\x96\xf8\xf7\x38\x0f\x65\x62\x90\x06\x81\xd5\xae\x26\xe0\x16\x14\x7f\xc2\xb9\xee\xec\xb5\x7e\x5e\xa5\x41\x00\xb4\xc1\xfd\xe3\xf1\x5f\x63\xdb\x21\x0d\xc2\x70\xa0\x39\x26\x0e\x9a\x31\x08\x0d\xd2\x40\x29\x4f\xa6\xd4\x2b\xea\x8c\x08\xd3\x20\x0d\x99\xa5\xf5\x76\x8a\x0c\x3d\x4c\x7b\xc4\x0b\x08\x69\xc8\x25\x95\x28\x9a\x73\x49\x73\xa1\xb3\x97\x93\xe9\xc0\xa4\xa1\x8e\x12\x36\xa9\x28\x1f\x67\x37\x20\x8d\x52\x8b\x13\x24\x66\xd0\x19\xef\x30\xa4\x71\x28\x3c\x75\xe8\x75\xde\x9c\xce\x2d\x52\xda\xf9\xda\x41\x72\xb7\xb6\x78\xbb\xef\x9d\x49\x02\x81\x6a\x2c\xf2\xb7\xcf\x0e\x85\x34\xe6\x21\x51\x14\x38\xfc\x5d\xd5\xbf\x4e\x1a\x2a\x5a\x44\xdf\xa1\x96\x55\x3d\xaf\x2c\xfa\xcc\x98\xfa\x3b\xe8\x09\x48\x53\x61\x61\xbb\xf9\xb7\x32\x6f\x87\x11\x4c\x4d\x48\x4b\xd3\xd5\xd1\x5e\xd5\xf0\x06\x9e\x7f\x10\x52\x16\xc9\xcc\xbd\xfd\xe3\x7b\xb9\x00\xb8\x85\x34\x8b\x91\x34\x5b\xf6\x12\x74\xe7\x61\xf7\xb0\x5b\x7f\x8f\x4c\x80\x54\x17\x95\xf5\x37\x15\x31\x3c\x62\x0d\x84\x51\xfd\x24\x10\x94\x66\x68\x19\x9f\xfa\x2a\xeb\x73\xae\x67\x07\x4b\xca\x59\x40\x34\x1a\x04\xb9\x5c\xf7\xa6\x9b\x6b\x95\x51\x40\x85\x8e\xce\x6d\xf7\x5a\xd7\x4b\x39\x73\x1f\x3e\x4c\x65\x2a\xe9\x40\xc6\xd2\x12\xd8\x4d\xe6\x8b\xce\x62\xdd\x2b\xd2\x9e\x4e\xce\xe6\xf0\x8d\x9a\x05\x16\x15\x74\x2e\x5f\xa3\xdb\xc6\x66\xc8\x5d\x23\x46\x96\x49\xc8\x3e\xca\x57\xd4\xdd\x90\xa2\x8a\x88\x52\xbb\xc0\x63\x55\x36\xd7\x75\x75\x3a\xa1\xde\x55\xbb\x17\xfc\x59\xd5\xc5\x70\x4b\xb4\x68\xc0\xcd\x23\x91\x71\xf8\x3f\x9b\x38\xa2\x74\x8a\x2b\x97\x22\x0c\x42\x8d\xff\x71\xcd\x2c\x08\x14\x66\x2e\x8d\xb4\xb8\x19\xf9\x7e\x59\x40\x90\x87\xbd\x77\xbd\xe7\xdf\x69\xf9\xd8\x65\x61\x14\x38\x71\xc3\xea\xb4\x7b\xc9\xcb\x6e\xe3\xfd\x6d\xde\x85\x6b\x07\xfb\xbe\xbb\xfb\x63\x01\xf5\x0d\x2c\x4c\x6d\xfc\xa6\xce\xd5\xcb\x35\xb4\x20\x3d\x6b\xd9\xe8\x2e\x59\x6c\x73\xbf\x50\x28\xf7\x21\xa6\x6f\x10\x72\x4d\x29\xb9\xb6\xce\x0f\x07\xac\x9f\x1b\x57\x47\x38\xd0\xf8\x03\x0b\xb5\x24\x1b\xd9\x1b\xf4\x3f\xab\xfa\xf5\x79\x2a\x54\x37\x89\x6c\xfb\x69\xc2\xa2\x30\x08\xf9\x48\x03\xe5\x42\xe4\xe4\xff\x7c\xc7\x28\x21\x7c\x49\x77\x60\xbd\x41\xdb\x07\xdd\xfc\xbe\xc1\x22\x10\x24\x31\xe4\x0c\x93\x4b\x81\xa4\xc9\x41\xc0\x22\xa5\x2d\xc9\xa8\x8d\x15\xae\xe1\x34\xde\x15\x59\x64\x18\x73\x18\x99\x55\x51\x3c\x61\xf1\x96\x2b\xdf\x16\x6b\xee\xe0\xdf\x4d\x75\xae\xfb\x19\xc3\x92\xd4\x6e\x3d\x07\xcb\xe5\xda\x3d\xa1\x7a\xe9\x5b\xd3\x30\x21\xca\xa9\x47\xad\x47\xee\x3a\x63\x42\x13\x94\x8b\xe6\xd0\x1f\x36\x76\xfa\x97\xdb\xd5\x60\x6d\x30\xa6\x80\x2c\xbc\x75\x55\x9c\xef\x2a\x05\x85\x0d\x7e\x5e\x70\x71\x9e\x27\xe2\x9e\x93\xa1\xc8\xa2\xcc\x96\x35\xa9\xc9\xae\xc3\xb2\xc4\xe6\x95\x2c\xae\xe1\xbf\xe8\x71\x5c\xfe\x6c\xef\x87\x3e\xcb\x98\x60\x9e\x34\xad\xcf\x16\xcc\xa6\x51\x06\x01\xa9\x37\x76\xd6\x8d\x2c\x2e\xbf\x1f\x17\x01\x39\x99\xdd\x1e\x57\xc3\x7b\xe7\xf4\xb9\x16\x11\x5b\x36\x4b\x8f\x21\x69\xd4\x19\x97\x68\x94\x80\x09\x11\x11\x51\xc4\x56\xbd\x1c\x51\xbd\x16\xc3\x2d\x40\x7a\x71\xe8\xce\x0d\xf4\x12\x05\x89\x6f\xd6\x92\xae\x3b\x9e\x8b\x36\xbf\xfe\x28\xe1\x38\x38\xf8\xff\x1b\xfd\x5f\x3f\x09\x21\x48\x28\x8b\xff\x47\xde\x9c\xa1\xd8\xa1\x7a\x29\xab\xa2\x3a\x7c\x8c\x8f\x6d\x06\x11\x50\xf9\x04\x45\x73\x9a\xce\x76\x1a\xe9\x22\x03\x83\x24\x26\x88\xc6\x91\xb4\x20\xf2\xf2\x60\x81\x52\xb3\xaa\xb9\xae\x9f\x9d\xa0\x43\xd6\x72\xc4\xf5\x0b\x0c\x64\xca\x1c\xf7\x9f\x2d\x8b\x9d\x70\x3d\x4d\x8e\x6f\xa6\xb5\x71\xc8\xa5\x52\x7f\xc2\xda\x00\x0c\x63\x2d\xb8\xdb\x07\xd6\x3d\xe1\xfc\x6c\xb3\x40\x19\x87\xdc\x9b\x1c\x65\xcf\xc7\x33\xeb\x65\xb8\x65\xc1\xd9\xdd\x6e\x9e\x23\xab\x21\xee\x1f\xdb\x48\x20\xf7\xdf\x2d\x3b\x1b\xed\x7a\x46\x85\xf9\x1b\x6a\x17\xd9\x0c\x69\x25\x86\xfc\xda\xab\x54\xf8\x6b\x8d\xa2\xf8\xcc\x37\x6c\xaf\x3a\x5b\xaa\x39\x17\xde\x94\xcf\x82\xc4\xb2\x59\x12\xe3\x74\x67\xe3\x5f\x41\xdb\x16\xa3\x0a\xac\x61\xc9\x64\x01\x02\xd5\xf6\x7f\xa3\x97\xc0\xfa\x47\xe9\x8a\x62\x3a\xcb\x65\x9c\x6f\x75\xfd\xc3\x20\xd1\x23\x92\xf4\x02\x0e\xfe\x57\xc3\x98\x33\x33\xb3\x9d\xa2\xa9\xed\x94\x45\x51\x68\x45\xea\xb0\xe9\x99\x0d\x06\xf5\x59\xc8\x22\x65\xeb\x39\x4e\xf5\x84\x41\xe2\xc9\xaa\xab\x4f\x47\x36\x8b\xa3\x0c\x1c\x02\x79\x45\x8c\x7d\x77\xa4\x7d\xb0\xf8\x45\xb3\x38\x89\xa5\x53\x09\xbf\xc2\x12\x4d\xae\x72\xa8\x2f\x4a\x99\x96\x6d\x9d\x2c\x96\x01\x90\x1d\xf5\x71\x1a\x93\xf5\x41\x96\x04\xe0\x77\x46\x6b\x6c\x4e\x07\x2b\x81\x8c\xa8\xad\xf6\x5e\xb6\x6a\xde\x2e\x83\x74\x00\x84\x5d\x63\x93\x1f\xe6\x6a\x92\x90\x25\xca\x76\xb2\x23\x6e\x03\x54\xe5\x5c\x07\x04\xb2\x34\x08\xb9\x45\x57\x75\xf3\xb5\xfd\x0e\xcd\xcb\x6c\xf0\xd3\x48\xc5\xa1\x03\x81\xac\x57\x4f\x7b\xa2\x29\xd8\xee\x9f\x9e\x37\xfb\x21\x02\x99\xa5\xcc\x92\x7c\x83\xd6\x77\x78\xc8\xdb\x67\x50\xb8\xe8\xdf\x66\x2c\x32\x59\x3c\x11\xf3\x7a\x86\xff\xde\x96\x4d\x4b\x36\xf1\xf4\xe9\x58\x62\xab\xf4\x46\x64\x18\x33\x14\x41\xc6\x20\xe2\x8e\xfe\x80\x92\xb4\xcd\x2e\x2f\x8a\x7b\x68\xdb\x17\x7c\x1f\xfa\x48\x0a\x2f\xef\xb1\x86\x06\x1f\x46\xa3\x30\x04\x30\xa7\xeb\x3d\xcb\x12\x41\x16\x0d\xd1\xa2\x3f\x77\xd6\x0b\xd5\xed\xec\xde\xfb\x49\x97\x25\x32\x19\xdb\x84\x7f\x73\x52\x64\x99\xa2\xb9\xbc\x5f\xef\xad\xdd\xb3\xab\x5a\xbc\xcb\xff\x73\xb6\x36\xf8\xb8\x30\x12\xb2\x4c\x89\xd0\x4d\xbf\x87\xaa\xc5\x89\x70\x1f\x64\x5c\x58\x36\x7d\x4b\xb4\xb9\x2a\xf5\x3d\xfc\xa2\x75\xdf\x99\xb5\x7f\x95\xcb\xcf\x38\xc6\x14\x3d\xb0\x13\xe4\xb6\x59\xb5\xad\xcd\x20\x2d\x77\x17\x71\x48\x1a\xdd\x4f\x45\x75\x6e\x2b\xbf\xa1\x64\x02\xd2\xd4\xc2\x97\x50\x37\x4e\x4b\xeb\xc6\x1e\x76\xe3\xad\x38\x83\xd0\x4a\x1b\x6c\x1a\x05\x27\xfc\x0e\xa4\x44\x55\xcc\xf1\xec\x90\x41\x1c\x50\xf9\x3f\xd5\xa8\xf5\xa9\x6c\xa8\x87\x18\x42\x06\x69\x44\x70\xde\xef\xd0\xac\x61\x66\x1d\xf5\xdf\x4f\x6a\x2b\x94\x97\x37\xf7\xf9\xaf\x6f\xc3\xd2\x93\x68\x08\x3e\x4a\x39\xbb\x1f\x8d\x8b\x6e\x7b\x8f\x6c\x3a\x53\x95\x88\x88\x96\xf9\xae\x3a\xfc\x44\x7c\xed\x19\xcf\xe6\x21\xa2\x4c\x47\x91\x74\xf9\xd0\x8d\x15\x42\xfa\x6d\xde\xc1\x4a\x8b\x14\xd5\x21\x2f\xa7\x1f\x51\x73\x4d\x44\x2c\xeb\xe2\x2c\x27\x9b\x04\x32\x1b\x0c\x68\xb0\x2d\xf1\xdd\x42\x9a\xe7\xd4\x7c\x90\x99\x14\xfd\x78\xd1\xd9\xf6\xa3\xb4\x19\xde\xaf\xe1\x20\x99\x91\x99\x70\x3a\xd0\xed\xb7\x1a\xb1\xfc\x44\xcb\xcc\x76\xe7\x81\xd4\x44\x57\xd1\x59\x5d\x7f\xe4\x45\x01\x3b\x28\x3c\x1c\x82\xc7\x01\xd0\xbd\xee\x30\x3f\xf6\x8f\xcf\xe3\x24\x46\x1c\xf0\x1a\x14\xaa\xd0\x39\x94\x16\x21\x3e\xdd\x63\x78\xcc\x6d\x39\x45\xef\x9c\x75\xce\xd8\xe4\x63\xf0\x24\x0a\x92\x3e\x7b\xf7\x96\x2b\x24\x95\xa4\x51\xcc\x9e\x27\x8c\x1b\x5b\x1e\xb7\xab\x1e\x8d\x59\xbf\x40\x5e\x2e\x6e\x41\x3c\x31\x41\x10\x79\x51\x18\xef\x50\x4f\x07\x96\xa7\x41\x22\x3d\xcd\xd2\x57\xee\xef\x70\x28\xf2\x8c\x21\x77\x20\xe0\xfb\xeb\xd5\xd3\xd3\xf8\x3a\xdf\x85\xa7\x91\xeb\x52\xbc\x15\x0f\xd5\xb1\x5b\x2a\x16\xf2\x33\x9e\x15\x9c\xa7\x36\x5d\x9f\x37\x96\x77\xf6\x09\xf2\x05\xbd\xd2\xbf\xf2\xbd\xdd\xcd\x20\xb0\xfc\x35\xa7\x3a\xff\x2f\xde\x57\x25\x7e\x90\x4d\xe5\xbf\x14\x64\x22\x70\x31\x10\x89\x96\xf6\x80\x0c\xdd\xcb\x54\x14\x07\x95\x86\x96\x14\xfa\xf7\xfc\x3d\x9f\x8d\x98\x0c\x98\xc0\xa1\x9c\x6a\xa2\xae\x03\x5c\x42\x62\x58\x1f\x80\x7c\xb6\xc5\x20\x93\x72\xdd\xd1\x48\x4a\xa5\x44\xd8\xa3\x92\xc6\xa4\x76\xae\x83\x4a\x03\x82\x33\x39\xde\x04\xac\xf7\xa0\xf5\xde\x3b\xdd\xd3\x7d\x92\xeb\x10\xc9\x96\x52\xc4\xe7\x65\x01\x8b\xfe\xb1\x34\x43\x02\xa5\xbc\xe5\xf8\xfe\xfb\xbf\xd6\x36\x9d\x39\x07\x42\x72\x74\x14\x99\x1a\xa1\x7d\x71\x42\x8a\x6f\xfe\x16\x26\x4c\xf9\x20\xb5\xe9\xb8\xc4\x3f\x73\x51\xfd\x35\xda\xa6\xf7\xbb\x1d\xc3\x3d\xf4\xba\x6a\x3e\xc5\x18\x8f\x18\x06\x40\x04\xb1\xa6\x52\xfb\xbb\xcd\xbf\xae\x56\x9b\x67\x57\x30\x07\x22\x0c\x6d\x46\xf3\x40\x32\x59\x8e\xe7\x7d\xf2\xb3\x22\x4c\x62\x8a\xbe\xac\xd7\xdf\xff\x8a\x42\x14\x44\xa8\xa5\xc8\x88\xf5\xe7\x01\xdf\xbd\x40\xd9\x22\x15\x21\x88\x28\xc8\xa8\xda\xfb\xe7\xea\xee\x6e\xb3\xdb\xef\x36\x2b\x8f\x30\x13\x51\x68\xab\x2f\x56\x4d\x0e\xbe\x44\x7e\xe4\xbd\x89\x28\x8d\xc9\x1e\xbb\x3a\xd7\xe5\xfd\x6c\xbd\x88\x08\x52\x8a\x35\xfe\xeb\x0c\xe5\x0e\xf2\xbf\x57\x67\x00\x22\x09\x32\x4a\x73\x83\x6c\x6c\x08\xf5\x5c\x7a\xd7\x53\x24\x20\xc9\x9e\xd9\x9f\xbd\xc4\xfa\x27\xef\x94\x86\xa9\x47\xc3\x6c\xde\xa0\x38\xd3\x79\xe6\xc0\x2e\xdb\xf6\xac\xb1\x6c\x6f\xaf\xc7\xa5\x63\x20\x52\x6e\x0b\x5c\xec\x17\xa5\xd0\xca\x48\x48\x70\x76\x7b\x88\x29\x86\x5d\xa0\x69\xd3\x6c\x3a\xbf\xbb\x46\xf2\x74\x89\x22\xee\x7c\x21\x7a\x02\x82\xc5\x01\xc5\xdd\xbb\x79\x4f\x85\x52\x63\xe2\x3f\xdf\x47\x87\x4c\x4f\x4a\xe4\x07\x17\x69\x97\x1f\xb1\x18\x97\x0a\x4e\xde\x83\x69\x43\xfc\x38\x52\xbe\x8f\xed\x11\xc1\xba\x79\xeb\xc0\xe8\x9d\x91\xbf\x34\x6d\xb8\x4a\x3d\xff\xbc\x3b\x0c\x5d\x61\xfe\x79\x0a\x82\x14\x1c\x4d\x3c\xd4\xc8\x77\x4e\x83\xb7\x2a\x84\x72\xe1\x5c\xaa\x74\xf6\x0a\x69\x93\x10\x97\x50\x99\xa6\x90\xf0\x11\x7e\x0d\x30\x8e\xab\x8f\xc5\x0d\x9f\xea\xd1\xbb\xf9\xf0\x62\x85\xf1\x47\x12\x08\x20\x34\xb7\xbc\x94\xa3\x6c\xcb\xe3\x79\x68\x95\x29\x71\x98\xf6\x64\x47\x0b\x06\xbb\xc0\x2c\xb1\x20\xca\xce\x7e\x3a\x17\x38\x24\xd9\x92\x45\x6b\x90\xfb\xeb\x84\x26\xf2\x5f\xda\x98\xd7\x55\x55\xe8\xea\xbd\x9c\xf9\x2b\x02\x25\x12\xf4\x5e\xa3\x73\xcb\xe6\xed\x08\x54\xd0\x7d\x7b\x3c\x75\x8f\x94\x7b\x03\x55\x18\xc1\x88\xe2\xc7\x19\xec\x53\x62\x31\x80\x20\x4c\x7c\x62\x87\x0c\xb6\x05\xfc\x09\xf7\x5d\x63\xc1\xc0\x59\x0b\x37\x75\x75\xfc\x8c\x24\x12\x20\x40\x30\x72\x24\x39\x59\xff\x68\xce\x50\xe7\xd5\x5f\x29\x31\xb9\xcb\x23\xd0\xe4\x18\x75\x9e\x8f\xb5\x78\x6e\x3f\xb1\x47\x21\x66\x9a\x52\xd3\xdf\xb0\xdd\x3a\x9a\xe6\xbd\x0f\x55\x8f\x9f\x3d\x36\x21\x99\x51\x03\x93\xde\x67\x7b\xec\xec\xfe\x26\xa3\xe1\xe9\x4e\xe0\x19\xcb\x3f\x40\x12\xa7\xc4\xbc\x7a\xbd\x9d\xec\x75\x90\x70\xc6\xc1\xad\x8f\x73\x8b\x54\x6f\xfe\x5c\x55\x9f\x56\x5b\x2f\x81\xde\xfd\xad\x04\xa3\x1c\xfe\xe9\x05\x1a\x8c\xbc\x65\xdf\x8b\x30\x00\xa4\x21\x52\x36\xf6\x0d\xce\x45\x3b\x8e\x6b\x40\x6a\x12\x32\x84\xec\x2e\x64\x5f\x1c\xdb\x36\x2f\x0f\xcd\x98\x57\xe0\xf2\x9d\x53\x83\x14\x25\x7a\x81\xe6\x65\x71\x21\x01\x0b\xad\xa0\xf0\x8d\x7d\x6f\x42\x31\xf8\x9f\x65\x2c\xe0\x56\x3a\x89\xdc\xee\x21\x91\x3e\x4a\x04\xfb\xae\x2a\xa1\x12\x8a\x9e\x13\x45\xf6\x99\x99\x39\x28\x11\x98\x09\xbc\x00\xc9\x33\x6a\x3c\x9e\xac\x42\xa0\xc5\xf1\x4d\x6f\x9b\x85\x9c\x64\x7b\xbd\x63\xec\x6c\x83\xf5\x6a\x77\x4d\x51\x41\xda\xf9\x96\x5f\x2c\x4b\x22\x82\x34\xee\xb0\x69\xff\xf4\x6f\xc4\x05\x72\x5f\x12\xb2\x7e\xa4\xfa\x8d\x7e\x0a\x88\x80\x13\x52\xcc\xd4\xd5\x7f\xb1\x24\xe5\xe5\x11\xde\x12\x44\x9c\x7a\x11\x04\x0f\x54\x27\x68\x61\xfd\x69\xb1\x6f\x77\x4d\x46\x20\x7b\xa7\x19\xda\xcf\xd8\x7f\xdc\x7f\xb2\xda\x44\x62\x91\x41\xa4\xcd\x92\x97\xdb\x16\x66\x44\x10\xd0\xad\x13\x3a\xf1\x6f\xb0\xdf\x5d\xbb\xb9\x1d\x39\xcf\x82\xaa\xf0\xb7\x23\x31\xab\xd9\x2f\x40\x66\xb5\xe1\x7b\xc3\x3c\x3f\xf5\xb7\x91\x71\x1c\x30\x4f\x80\x3a\xaa\x5d\x99\x0e\xac\x4c\x32\xba\xc3\x0f\x62\x21\xbc\x7e\xdc\x8d\x64\x71\x00\x54\x12\x93\x63\xb4\x5b\xfd\xbe\xf1\xf7\x55\x19\x23\x81\x2a\xfb\x15\x9d\xcc\x66\x5f\x24\xbf\x14\x7e\x05\x54\x96\x1c\xf7\x35\x2f\x0f\xdf\x0a\xd0\xf9\xc8\xf2\x04\x54\x29\xa5\x01\x96\xf5\xed\x2f\x16\x9e\x09\x39\x05\xf1\x88\xc1\x68\x61\xc3\x05\x13\x47\x74\x70\x1f\xe1\x97\x4d\xc2\x61\xd1\xa3\x04\x65\x08\xbd\xe2\xb8\x87\x07\x2c\x4e\x38\x19\xca\x8c\x2c\xd8\x7b\x62\x47\xad\x11\xdb\x41\xd8\xf7\xb3\x98\xf5\x67\x29\xb7\x2f\xd1\x11\x32\xc4\x8c\x92\x41\x54\xbe\x4b\xe6\xff\x75\xf5\x5e\xc6\xdb\x9b\xe9\x7b\xc9\x28\xb0\x81\xb1\x9b\x02\x1a\x0f\x27\x90\x91\x56\xa8\x7c\x31\xd1\xba\x27\xc5\xec\x3e\x7e\x46\x3b\x01\x68\xdd\x33\xa5\xf1\xcf\x95\xa9\x40\xc6\xd2\x10\x02\xa1\x39\x15\xb9\xdb\xaf\x26\xed\x89\x8a\x29\x89\xba\xdd\xad\x9e\x77\x84\x8c\xfa\xe7\x8f\xdb\xe7\xe7\xcd\x9d\xff\xc5\x34\x00\x8f\x3a\x76\x02\xf2\xd3\x1b\xa4\xa9\xf2\x1e\xe2\x98\x73\x92\xdc\x87\xee\xc4\x9a\xbe\x6d\xca\x22\xc2\xa9\x96\xf8\xab\x1d\x0b\xdf\x76\x2d\xa9\xb7\xcd\xb7\x94\x9c\xb0\x64\x7c\x90\x5f\xa2\x33\xff\x67\x76\x4f\x6e\x47\x5a\x55\x85\x76\x9a\xb9\xff\x42\xe8\xe3\xf3\x92\x25\x8a\xec\x04\x39\x84\x12\xc9\x76\xd9\xe6\x3e\x1c\x2a\xb3\x30\xa4\x6d\x65\xaf\x09\xab\xd4\x8c\x49\x68\x41\xf2\xd0\x82\xb6\xbe\x3d\x7a\x06\x68\x90\x5c\xd8\xe4\xa8\x27\xa6\xfd\x9e\xb7\xee\x1c\x5c\xc3\xe9\xa9\xc6\x81\xc6\xa4\xbf\x02\x19\x45\x95\xfe\x73\xc6\xfa\x43\xda\x6d\x37\x1a\x1a\x91\xd8\xd4\xbe\x57\x65\xb7\x67\x36\x8e\x1f\xe0\x76\xfd\x58\xe3\xe1\x5c\x4c\x70\xc4\x52\x30\x46\x81\xf8\x02\x9a\xd1\x60\xff\xc4\xdc\x77\xe8\x6c\x1c\xd2\x81\xcc\x6b\x87\x3a\xf7\x2d\xd2\x58\x86\x9a\x3d\x45\xf7\xcf\x75\x61\xe9\xb8\xaf\x51\xc1\x47\x1f\x69\xf1\x75\xf4\x20\x55\x14\xd2\x66\xd3\x58\x00\xf8\xac\x7a\x42\x2a\x13\x5b\xe9\xcb\x17\x74\x19\x83\x6e\x8d\x4f\x07\x4f\x07\x61\xcc\x06\x8e\xf2\xa1\x42\x1c\xa4\x8e\xc1\x92\xc0\x9e\x8f\xc7\x27\xa8\x5b\x47\x1f\xdc\xac\x4a\x3d\xf8\x94\xbe\x2f\xc7\xc4\x9d\x47\xd5\x28\xdd\x25\x35\xe8\xa4\xd7\xc1\x5d\x43\xa3\x40\x5b\xba\x1f\x9f\x59\xf5\xfd\x4c\x46\x21\xf8\xab\xd5\x6e\x77\xb7\xd9\x3f\x3d\xde\x3e\xec\xf6\xd7\x9b\xf5\xed\xfd\xea\xce\xc7\xf8\x25\x46\xd1\x28\x5d\xbc\xc3\x23\xa1\x1e\xcf\xf5\xc4\xb6\x91\x88\x01\xa1\xb2\xf1\x98\xb7\xcf\x77\xeb\xd9\x0c\x37\x71\x60\x8d\xde\x51\x4c\x77\x3a\x61\x55\x90\xd9\xe8\x6f\x43\x90\xe8\x1a\xa9\x6c\x60\x1a\x9b\x51\x81\x41\x50\xbd\x5b\x49\xd9\x2b\x0f\x92\xf7\x63\xa2\xc2\x24\xa0\x39\xb8\xdd\x6c\xae\x07\xb8\xe4\xd0\x48\x06\x76\x9f\x85\xa9\xea\xb1\x01\xae\x42\x16\x93\x89\xfd\x8c\xa7\x69\x16\x78\xd1\x2d\x53\xa1\x00\xca\xc7\x7e\xc3\x72\xfd\x92\x9f\x28\x7a\xbf\xff\x86\x25\x2e\x68\x21\xcd\x5e\x37\x4a\x99\xe6\x93\x1d\xa2\x07\x7d\x3c\x55\x4d\x7b\xaa\x4a\x22\xdb\x76\x5a\x48\x13\x15\x4d\x50\x91\x89\xa9\x5e\xf2\x5f\x79\xa9\x5e\xd0\xe5\x9c\x96\x33\xd6\x2a\x0e\x2d\x1a\x21\x57\xd5\x14\x70\xa2\x62\xa1\x93\x21\x2c\x7f\x0d\xf5\x6b\x59\x69\xbc\xc6\xba\x0f\xee\xac\x3e\xc9\x2e\xa9\x18\x22\x4a\x10\x93\x86\x1a\x79\x0c\x05\xe4\x33\x08\x91\x4a\xa2\x30\x73\xf4\xa9\xb3\xe2\xc4\xd9\xdd\x12\x26\x3d\x03\xed\xcf\x91\x15\x66\xbd\x80\xa7\x81\x5a\xbf\xef\x8e\x04\x59\xbf\xad\xa5\x7f\x95\x04\xd0\xf2\xa4\xd0\x25\xdd\x8e\x3e\x62\x1d\x99\x91\x1e\x4e\x6f\x96\x2a\x49\x29\x80\x6f\x58\x1d\xb1\xad\x73\xf5\x54\x95\xff\xf5\x7b\x86\x62\x5a\x8b\xa1\x92\xba\x67\xee\x83\xe2\x69\xac\x19\xf6\x57\xa4\xa3\xa0\xb2\x20\xf2\x62\x15\xbb\x8f\xd3\x27\x61\x70\x95\x69\x46\xa3\xea\xc4\x31\xa6\x60\x54\x95\x19\x0b\x46\xed\xcc\xc2\x1f\x6d\x3e\xcc\x78\x9e\x59\xcd\x5c\x97\x84\xfb\x59\xd5\xaf\xc4\xa5\x33\xad\x94\x51\x9c\xa7\x7c\x08\xd1\xe7\x47\x28\xae\x66\x05\xe7\xa0\xb8\x0c\x08\x1c\xd0\xb9\xa6\xb8\x7d\xc9\x4f\x53\xf2\xaf\x59\xda\x79\xba\x38\xb9\xb2\x99\x24\x89\x87\xbc\x74\x14\x13\xfe\xb7\x05\x64\x44\x7b\xec\x68\xab\xb1\x0c\x96\xb8\x66\xc2\x2f\xff\xf1\xb7\xd2\x86\x4c\x83\xd5\xa1\xae\x8a\xaa\x1d\x6f\xe4\x0a\xe2\x8c\xa2\x9e\x3f\x88\x78\x97\x7c\xb1\xe6\x71\x96\xf4\x54\x20\x8c\xd1\xe3\xda\xaf\xfb\xe6\xb0\x7a\x87\x9c\xca\x9c\xce\x3a\x9f\x53\x80\xfa\xcb\x9c\x76\xce\x16\x0c\xde\x43\xbf\x95\x2b\x50\x46\x5a\x59\xed\x53\xde\x42\xd1\xcd\xbd\x81\x9d\x07\x94\xd4\x82\x66\xa6\xae\xb0\x79\x7c\x2f\x89\x5b\x6e\x11\xf3\xaa\x24\x26\x54\xa0\xda\xcc\x4b\x7d\x95\x8a\x32\xcb\x85\x0c\x75\x9b\x43\x61\xe3\xea\xab\xf2\x80\x45\xf3\x19\xc0\x42\x29\x99\x44\x93\x9d\x2e\xb7\x8c\xd9\xfd\x21\xa1\x14\x46\x64\x0d\x83\xd6\x0e\xdb\x31\x5b\x28\x4b\xd5\x37\x4a\x73\x69\x25\x84\xca\xbc\xdd\xfc\x5a\x15\xf9\x27\x2a\xc0\xa0\xb4\xb6\x46\x16\x65\xc6\xfb\x5f\xc5\x20\xb1\xe5\x01\xb6\xfa\x6d\x8b\xa4\x73\x37\x7b\x61\x93\x18\x2a\x9c\xae\x3c\x79\xfe\x8f\x32\x6f\x3f\xa9\xf2\x51\x26\xb5\x6c\x95\x56\x5b\x90\x28\x26\xfb\xa5\x61\x40\x53\x61\xce\x94\x37\x73\x92\x56\xf7\x3d\x55\x48\x91\xd3\x23\xa9\x4e\xfb\xa5\x37\x36\xea\x94\xd1\x22\x10\xbe\xa0\xa2\x9d\xdb\x7c\x3a\x48\xac\xce\x34\xcd\xc8\xbe\x50\x43\x07\x89\xe6\x0e\xb3\x7b\x3e\x39\x42\x8b\x4f\x69\xc3\x40\x07\x4c\x87\x16\x11\xf5\x65\x44\x50\x07\x59\x4a\x2c\x6c\x47\x4b\x33\xb3\x45\x5b\xa9\x34\x26\x28\x01\x1d\x68\xab\x33\xd0\x60\xdb\x57\x50\x6e\xf1\xc2\x33\xd3\x61\x20\xd1\xa6\xf1\xbd\x4b\xaf\xc3\x00\x2d\xbe\x03\xdf\xa6\xfb\x90\x0e\x13\x30\xb6\xc4\x4f\x8f\x53\x50\x7e\x1f\xd0\x61\x1a\xa5\xbc\xc7\xba\x9b\xbc\x1d\xae\xcc\xac\x6e\xb5\xf7\x89\x29\x36\xbf\x6d\xab\x53\x37\x1e\x37\x75\x75\x7c\x98\x4f\x7d\x1d\x85\x31\x3a\x1a\xe9\x12\x95\x15\xb7\x9d\x80\xcb\xbf\x3c\xa0\x75\x9c\x0a\x65\xbc\x51\x51\xe0\x01\x5a\x9c\x32\x68\xf8\x7e\x5c\x90\x05\xbe\x85\xf2\x1f\xf0\x96\x63\xad\xaa\xbc\x34\x55\xfd\xee\xd7\xb1\x4e\x44\x14\x45\x03\x54\xe2\x78\x3e\x2e\x28\x4d\x80\x4e\xa3\xc0\x92\x76\x77\x2b\x0d\x9b\xf6\x52\xad\x0e\x74\x9a\x4a\x0b\xaf\xfc\xf8\x6f\x7f\xa4\xeb\x54\x5a\x61\x6c\xbb\x2b\xb9\x79\xf2\xf7\xf2\xb8\x9a\x19\x0e\x03\x39\x26\x1d\xc5\xdd\x97\xfe\x89\xf9\x98\xa7\x14\x74\xa6\x2c\x7f\x07\x8d\x06\xc9\x25\x50\xdf\xcf\x10\x77\x9a\x27\x8a\x1c\x80\xdd\x9f\x8f\x9d\x0d\x3f\x24\x9c\xb5\x88\x12\xee\x19\x64\x3c\x0a\xc2\x6d\x45\xdd\x09\xbe\x10\x98\xd4\x82\x07\xb6\x74\xe8\x78\xaa\xea\x76\x0a\x4d\x9b\xbd\x8f\x00\xe1\x33\x53\x37\x38\x17\x8e\x9b\x7d\x61\x61\x2c\xda\xa9\xc1\x92\x04\xee\xc8\xa9\x9c\xbd\x07\x84\x11\x71\x47\x4c\xf9\x40\x5c\xa3\x8c\x34\x99\xeb\x12\xdb\x7d\xfb\x92\x37\xfb\xe6\xd4\x27\x04\xb4\xec\xbe\x8c\x77\x4f\xb6\x38\x4f\x11\x6b\x29\x63\xa2\xa3\x3a\x7a\x87\x6c\x4e\xcc\xed\xfa\xe9\x14\x84\xf0\xd1\x11\xeb\x2e\x50\x4e\x2a\xaf\xca\x6f\xd0\xaf\x0f\x0d\x8c\x2a\xb1\x74\x35\x54\x8e\x6a\x8d\x5a\x7b\xb1\xd6\xaa\x69\x6f\xaa\x9a\xb2\xe3\xaf\x63\xeb\x5b\x9b\xcc\xda\xe8\x5e\xce\xff\x3b\x34\x2f\xcf\x43\xbd\xa1\x36\x82\x51\xb0\x7c\xdf\x1b\x32\xbf\x3e\xa6\xe3\x80\x41\x68\xc8\xbc\xf8\xb1\xbd\xb6\x25\xdf\xbf\xf9\x86\x38\x26\xee\xdd\x13\x7c\x5c\x39\x29\xb2\x25\xca\x0c\xdf\x1b\x19\x95\xe0\x5c\xb5\xdd\xf6\x35\x93\x47\x01\x0c\x53\x46\x1e\xc7\x66\x73\x43\x22\x35\xd3\x67\x08\x33\x0b\xc0\xa9\xb1\x3d\xd7\xe5\x94\x0e\xd4\x77\x11\x91\x55\xf2\xa0\x3d\xc4\xe1\xd1\xb7\x67\xd9\x53\x88\x5f\xe4\xa5\x31\x0a\x43\x61\x0d\x9f\xc2\xfc\x9e\x7b\x22\x4b\xc0\x28\x49\x42\x77\x00\xae\xb4\xfe\xa4\xb4\x0a\xa3\x34\x20\xa2\x87\xbd\x47\xc8\x7c\x55\x1c\x89\x11\x03\xd3\x17\xd3\xb5\x38\x8d\x35\xbb\x3e\x71\x62\x0b\xde\x9a\x6e\xc9\x85\x63\x88\x37\x26\x0c\xb0\x7b\xbb\x1f\xf5\xf9\x70\x86\x8f\xb7\xe6\xa9\xaa\xdb\xf3\x01\xfa\x67\x4e\x44\x14\xf8\x98\x0e\xd4\xd0\x8d\x61\xaf\x0c\x3f\x7d\x92\x44\x06\x44\xda\x68\xbf\x38\x7d\xb9\x8f\xd9\x09\x3f\x8f\x37\x61\xea\x50\xb0\x7e\x96\x90\xeb\xee\x64\xc4\x96\x95\xbf\x00\x99\xc8\xdc\xef\x7c\x9c\x5a\x38\xd7\xa4\x0b\xd2\x43\x49\x31\x53\x36\x43\x68\xf2\x53\xe3\x09\x07\x1c\x48\xc5\x95\xda\xcf\xcb\x3c\x30\x33\x22\xe6\xde\x59\xfc\x8b\xb8\x93\xbb\x84\xc7\x96\x8f\xda\xa3\x72\x2d\xfa\xd4\x3f\x83\x08\xe3\xd8\xaa\xbf\x9c\x4f\xcb\x26\xe7\x32\x65\x3e\xa0\xe0\x31\x31\xf1\x3f\xd6\xf9\x21\x2f\xa1\xb8\xff\xb0\x38\x2d\x17\x62\xec\x7f\x40\xa6\x61\xe0\xa1\xa2\x2d\x36\xed\x3d\xfc\xbb\xaa\x77\x17\xa5\xc5\x28\xb4\x8d\x41\x6c\x49\x67\xc3\x8b\x7f\xf9\xdb\x80\x4a\x30\x9c\xe3\xc2\x97\xdd\x3a\x04\xa5\x88\x92\x74\x7a\x38\xa3\x4c\x43\xc2\x60\x38\x67\xbd\x1b\x0e\x55\x69\x9b\xfa\xa3\xb8\xeb\x97\x99\x06\x94\x4c\x11\xc1\xbd\xab\xfa\x9f\x7a\x10\x28\x79\x1a\x74\xdf\xf2\x1a\x3e\x08\xda\x64\x0d\xd1\xbe\x15\x23\x32\xcc\xbf\x15\xe7\xff\x9f\xb2\x37\xe9\x6e\x5c\xb7\xb6\xc7\xbf\xcb\x6f\x94\x41\x06\x20\x40\x82\xe4\x7f\x26\xc9\x72\x95\x5e\xb9\x51\x2c\x55\xd5\xcd\xcd\x7a\x4b\x0b\xcd\x81\xcd\x98\x22\x15\x92\xb2\x4b\xf9\xf4\xff\xc5\x03\x80\x9d\x68\xd7\x7d\x83\x94\x6f\x44\xb0\x03\xd1\x9c\x66\x9f\xbd\xcf\x56\xa1\xce\x17\x3a\xfc\xe5\x20\xe2\x47\xc1\xc4\xdf\x04\x19\xdd\x03\xa8\x30\xc4\x24\xde\xc3\x6e\xb5\xf4\xcb\x87\x7f\x38\x15\x85\x91\x83\x43\xe6\xeb\x63\xd6\x34\x57\xf3\x45\x29\x5b\xaa\x5d\xc0\xfb\xbd\x28\xce\x76\x3d\xf9\xc0\x87\xec\x56\x3b\xa5\x09\xb0\x81\xa2\xf9\x2c\x78\x07\xda\x35\x1c\x09\xea\xbe\x2f\xef\x36\xab\xc3\x6e\x71\xb7\xde\x1d\xd8\xe1\x69\xb1\xf7\x81\x66\xd0\x26\xc5\xae\x7d\x87\xec\x50\x0d\xcb\x63\x41\x1b\x99\x0c\xc5\xe0\xba\x41\x07\x84\x46\x96\x88\xc8\x11\x1f\x4d\x5e\x08\x78\x2a\x7b\x68\xde\x1e\xc4\x71\x36\xfa\x0b\x26\x88\x62\x7b\x83\xe2\xd9\x95\x41\x8e\xd2\x9b\x60\x58\x4a\xc8\x40\x99\x79\x12\xf0\x02\x23\x04\xae\x90\x2e\xd3\x84\xb8\xbd\xa1\x65\x0c\xa6\x1d\x3a\xce\xfb\x75\x13\xf4\x69\x4a\xfe\x27\x0c\x89\x52\xd2\xf3\x74\xfb\xf8\x8e\x35\xd7\x66\x9f\xdc\x10\x2d\xd1\xc3\x50\x03\x3e\xc3\x2b\x26\x09\x13\x40\x10\xc3\x98\x0d\x0d\x27\xdd\x7c\x58\x60\x16\x54\x33\xdd\xe5\x0c\x0d\x2d\x07\x99\xdb\x4f\xf7\x95\xc8\xda\x0f\x30\xaa\x9c\x18\x8f\x4e\x43\x65\x8c\xa8\xdd\xe5\xe3\xf2\x11\xd3\xa0\x4e\x15\x59\x18\x46\x85\x34\x96\xab\xd7\xef\x41\x53\xd4\x87\x61\xa1\xfd\xd8\x77\xe5\xb3\x45\x2d\xf9\x4a\x7d\xdb\xea\xb6\xac\x76\xa7\xb2\xa8\x61\x1e\xe8\x68\x58\xaa\x30\x44\x70\x2e\x34\x98\x41\xb1\x92\x61\x2a\xa6\xfd\x76\x8a\x7b\xd1\xf7\xa2\xc9\xf2\x9b\x1e\x60\xe6\x5b\x6a\x19\xf9\x84\x56\x01\xf9\x8f\xae\x52\xe7\x7c\x5d\x24\x65\x98\xa1\xa1\xe9\x03\x90\x79\x17\xac\x30\x61\xa0\x95\xdd\x74\x8f\x59\x71\x83\x9f\xfa\xc9\xf1\xae\xfb\x26\xad\x29\x8c\xae\x4d\x59\x34\x2f\x61\x32\x5a\x65\x4c\xa4\xa5\x74\x5c\xfe\x88\x15\xb4\xcc\x47\xdd\xe5\x79\x98\x70\x70\x11\x68\xc4\xea\x0d\xf1\x22\xbe\x4d\x4a\x14\xf5\x35\xb6\x9b\x79\x76\x5a\x61\xe2\x30\x0d\x3b\x3e\xc1\xa3\x40\x78\xf4\x80\x89\x6d\xd2\xc1\x71\x04\x10\xf8\xc0\x09\x3e\x92\x5b\x71\x1d\x09\xde\x30\x62\xf2\xf7\xf1\x7d\x38\xc7\xdd\x4e\x23\xc3\xc4\xa2\xd0\x3b\x68\x16\x0f\xfb\xe9\xf5\xb5\xa5\x3f\xbb\x2b\x9f\x1f\xa6\xb0\xf0\x69\x9d\xdc\x58\xfd\xd6\x16\x68\x4c\x5e\x2e\xa1\x1c\xed\x56\x61\xa3\x30\x4e\x9f\x66\xda\xc6\x1a\x63\x5d\xed\xdf\x76\xe5\x7b\x30\x09\x63\x04\x0b\xb4\xb3\x98\x77\x3f\x26\x14\x73\x65\x8e\x67\xff\x13\x5a\x38\x93\x80\x15\xaf\x95\x48\xd4\x3a\x2c\x8c\x34\x29\x31\xcc\xd6\x37\x23\xb7\x64\xed\xe3\x44\xa3\x7d\xd4\xa4\x81\xe5\x59\x55\x65\xf1\x06\x95\x8f\x67\xed\x4b\x64\xa2\x9c\xbe\x48\x4a\x19\x42\x6e\x2d\x2b\xe0\xd3\xea\xe1\x83\xa7\x4a\x43\x8e\xe8\xa0\x76\xec\x14\x7d\x28\xf2\x83\x72\x4a\x93\x86\x49\xe0\xb0\x6a\xdb\xb2\x78\x7e\x13\xf9\x13\x1c\xcb\xce\xe6\x36\x29\x04\x1e\xd2\x8f\x23\x71\xa3\xca\x7b\x81\x4c\xdc\xd3\xe7\x73\xee\xdb\xa2\xaa\xca\xf7\xd5\x63\xe7\x7d\x18\x11\xda\x24\xec\xb9\xa8\x9b\x81\x2d\xe4\x8f\x26\x29\xf2\xd0\xdb\xfe\xb6\x65\x77\xa2\x9a\xa2\x4e\x26\xab\x90\x24\x81\x35\x94\xa0\x6e\xbe\xa0\x83\xfe\x3c\x30\x1f\x8c\x34\x04\xb7\xd0\x93\xa8\x9b\x3d\x14\xf7\x59\x71\xee\xf9\x5e\x8c\x8a\x3b\x7c\xf3\x8f\xb2\xb9\xaa\x60\x32\x3a\x94\x96\x55\xa9\x04\xe3\xcf\xd1\x71\xc0\x9d\x07\xfe\x63\xb3\xbd\xcb\x64\x75\xfd\x8c\xbe\xa9\xd4\xe8\x17\x2f\x5c\x4d\xd0\x74\xf3\x1d\xee\x29\x46\x2b\x40\x79\xa5\x02\xde\x7b\x3b\x63\x2e\xe5\x37\xf9\x6a\xc0\x04\xc2\x22\xbe\x40\x63\x29\x7f\x7d\x5c\x40\x3f\x61\x8d\x70\x35\x5a\x0e\xac\x7f\x25\x09\x21\x31\x06\x48\x6c\x04\xed\x33\x66\x61\x49\x02\x62\xb5\xe2\x94\x57\x7c\xdf\x42\x65\xca\xea\x88\xc5\xda\x68\xec\x0f\x9f\x48\x92\x20\x90\x1e\x2b\xd7\x7a\x98\xb7\x4e\x20\x62\xa3\xa7\xed\xb8\xed\x1e\x5b\xc3\x34\xba\xd2\xdf\x27\x2d\xe3\xc4\x56\x36\xbf\x54\xe5\xfb\xc6\xec\xc0\x67\xe1\x1c\xc9\x81\x69\xa0\x72\x9d\xdc\x25\x15\x24\x61\x9c\xa1\xa5\x5e\x9f\x8f\xc7\xdb\x73\x73\xae\x1c\x9d\x58\x77\x3c\x0d\xb0\x56\xcf\x4e\xa3\x35\x02\xa1\xd4\xf4\x23\xb9\xb6\x21\x31\xb8\xe3\x1b\x91\xe5\xa0\xbf\x5d\xd4\x20\xcb\x22\x49\x98\x04\xc8\x7c\x59\x16\xf9\x65\x53\xac\x8f\x50\x3d\x63\x89\x53\x77\x98\x26\x61\xb7\x79\x94\x59\xd1\x21\x4d\x24\x89\x08\x37\x71\x37\x04\xe1\x0a\x64\x35\xe9\x89\x48\x24\xdc\xd1\xcc\xaf\x9b\x17\x17\x71\xfa\x6c\x86\x48\xc2\xb9\xc5\x95\x2d\xcf\xc5\x50\x5c\x42\x12\x9e\x12\xa7\x8f\x21\xea\x3a\x7b\x2e\xee\x5b\xbb\xfa\x4a\x6b\x52\x12\x2e\xac\x54\x49\x53\x3e\x3f\xe7\xe0\x79\x23\xc6\x3c\x21\xc3\xd5\x4c\x92\x98\x51\x11\xfa\xa0\x91\xd0\xba\x99\x4d\x3d\x8d\xdf\x2c\x4e\x34\xb0\x9e\xf8\xad\xde\x8a\x0b\xd2\x74\x60\x75\x42\x3b\x88\x16\xde\xd1\x95\x24\x4e\x01\xdd\x13\xab\x7f\x33\xe6\x52\x71\x4d\x92\x20\x95\xbd\xb7\xf8\x61\x56\xe3\x23\x23\xe9\x0a\x23\xea\xf1\xb3\x92\x24\xda\x52\xad\xd5\xd0\x60\x74\xdd\xaa\x5d\x2c\x7b\xb6\x8c\x0f\x06\x71\x9a\x28\x0c\x31\x09\x54\x5c\x5e\xff\x27\x60\x76\xa8\x05\xec\xef\xa3\xbf\x5d\x2f\xb6\xeb\x61\x27\x4f\xae\xd7\xcd\xcb\x95\x8d\x29\x89\x48\x23\x34\x62\x1c\x81\x6f\x33\x24\xf1\xb9\x66\xab\x95\x44\x68\x0b\xa2\x72\x98\xc5\xec\xbf\xa0\xaf\xa9\x76\x24\x91\x84\xc5\x1d\x69\x57\x86\xda\x29\x53\xaa\x14\x49\x54\x90\xc6\xd0\x89\x4e\xbf\xfa\x9e\xd7\x34\x46\x7e\x81\xdd\x64\xcf\x97\x44\x0b\xca\xc9\x88\xbc\x60\x10\x12\xec\xda\x30\xfc\x6e\x5e\x05\x30\xcf\xd4\x85\x4e\x17\xce\x61\x07\x4f\x67\xaa\x21\x86\x1a\x0f\x69\xb2\x82\xbc\x93\x5b\x18\x66\x85\x92\x9f\xad\xee\xbd\x86\x42\x8f\x43\x9f\x7f\x9f\xb6\x07\x0c\x58\x89\xa6\x81\xa2\x0b\x11\x0f\x6f\x1a\x90\x20\x05\x77\x53\x27\x17\xd1\x7a\xd4\xf5\x39\x6f\x44\xd1\xd4\xc3\x18\xb6\x0c\x08\xb5\x82\xba\x9d\x18\x76\x55\x1e\x27\x6e\xd6\xf8\xa3\x05\x24\xb6\xcc\x53\x37\x67\x91\x6f\x7a\xa1\x10\x19\x04\x81\xc4\xc8\x35\x86\x4b\xf6\xef\xd6\x0b\xf4\xc7\x38\x43\xf3\xfc\x8b\xc8\x85\x6a\x32\xf5\xc7\x27\x78\x64\x19\x04\x32\x8a\x63\xd4\x7a\xb7\xa6\xe5\xe3\x09\xc6\x69\x26\x19\x30\xc2\xb1\x10\x4c\x67\x6f\x34\xe2\x87\x80\x26\xcb\x0b\x8d\xf8\xa7\x69\x61\x19\xb0\x24\x66\x63\x26\x5c\x44\x6b\x41\x6b\xd8\x0c\x76\x9c\xd1\x1e\xf5\xa9\x8a\xa5\x0c\x98\x49\x04\xf7\x51\x5f\x91\x43\xb5\x72\xa4\x85\x6e\x73\x0b\x42\x16\x24\x56\x06\xa6\xb0\xc6\xc0\xf4\x11\x67\xe2\x3e\xed\x59\x32\xb2\x2e\x45\x53\x9d\x5b\x8f\xa5\xcf\xc4\x8f\xef\x1f\x0a\x19\xb8\x3a\xbf\x85\xe5\x0b\x47\x50\xc4\x28\x19\x2d\x83\x48\x30\x57\xd6\x6e\xb9\x0d\x0a\x9f\x9f\xff\xe0\x23\xf3\x80\xe1\xca\xfe\xa3\xcc\xf4\xa4\x7a\x74\x36\x07\x2b\x03\xce\x99\xec\x39\x65\x16\x96\xa0\x70\x3c\xd6\x03\xae\x28\x4e\xe4\x46\xf8\xe7\xe2\x26\x72\xb5\x02\x08\x84\x43\x8c\x0c\xf2\xa3\x62\xbc\x7c\x1c\x0f\x90\x41\x4c\x05\xe2\xb1\xa4\x28\xd4\x48\xe8\xa9\x3d\x64\x10\xa4\xd4\x1a\xb4\xe7\x7a\x7c\x08\x24\x16\x05\xa0\x4f\xb4\xe8\xdc\x79\x77\x34\xa5\x96\xde\xfe\xe0\x0a\x91\x7b\x86\x5e\x19\xa4\x22\x40\x7c\x50\x05\x35\xd8\xe4\xc8\x46\xf7\x29\x23\xdf\x48\x25\x88\x28\x69\x57\x9d\xac\x78\x76\x4c\xfd\x73\x4b\x79\x32\xe9\xb2\x54\x73\xec\x0e\x3d\xa4\xf8\x92\x41\x0a\x49\xe8\x96\xbb\x31\x41\xbc\x0c\x44\x18\xe0\x34\x52\xc7\x73\x7e\x2a\xdf\xe9\xe4\x51\x44\x44\x89\xf6\xee\x19\xf2\xb9\x2d\xcf\x55\xd1\xc9\x34\xc9\x40\xf2\x14\xd1\x98\x03\x99\x93\xd1\xc4\x93\x89\xc2\x60\xb4\x1b\x73\x2b\x64\x8c\xaa\x27\x5f\x51\x82\xd4\x81\xa7\x78\x82\xae\xb3\x94\x14\x1e\x72\x81\x69\x99\x5d\x47\xd4\x27\x03\xa5\x05\xce\xd6\x2f\xed\xc0\xac\xe1\x61\xf2\xdc\x9a\x06\x82\x7a\x91\x31\x8f\x48\x93\x01\xd0\x28\xec\x35\x58\xc7\x15\x01\xc3\xfe\xf5\x33\x0d\x14\x18\x27\x81\xd0\x1a\xb8\xed\x17\xfd\x22\x8e\x30\xe0\xb6\x97\x01\x68\xc0\x24\xc0\xdd\xe3\xe3\xfd\x66\x41\x0f\x8b\x9b\x9b\xa7\xee\x98\x49\xd1\x0b\x7c\x80\x4b\x55\xd6\x4e\x38\xce\x1f\x34\x10\x05\x83\x78\x4f\x76\x84\xba\x11\xc7\x6b\x5d\xb2\xd1\x9b\x51\xa2\x98\xb1\x88\x3c\xf5\xda\x8e\xaf\x73\xa1\xc6\x8e\x86\xa4\x41\x94\xa0\xb9\xd6\x88\x5f\xb7\x00\x4b\x8f\xba\x94\xd4\xf3\x85\x1f\xcb\x37\xf8\xdb\x79\x8a\x10\x48\x7c\x2b\xee\x72\x70\x97\xba\x81\xe3\x42\xa9\xee\x74\x95\x00\xeb\xd5\x58\xda\x9e\x58\x5e\xbe\x8a\x62\x2e\xad\x28\x29\x13\x11\x12\xd8\xd6\xef\x59\xa3\x5e\x6c\x00\xb5\x27\x95\x95\x34\xa4\x36\xfa\x87\x48\x99\x1b\x28\xb0\x9e\xa9\x83\x5e\x4a\x1a\x09\x2e\xd3\x1e\x12\xec\x6c\xc1\x0f\x0c\x47\x1a\x29\x83\xd1\xc0\x6d\x56\x34\x8f\xda\x5f\x83\x47\x9a\x45\x9e\xe5\x28\x2b\x9e\xd7\xc5\x73\x56\xf8\x2f\x47\x63\x12\xa3\x99\x95\xa9\x32\xa8\x9b\x01\x2d\xaa\xa4\x71\x62\xa8\xa3\xda\x46\x78\x6e\x77\xc5\x24\xa0\x58\x97\x5b\xc0\xbb\x55\xfa\x9e\xa9\xb0\x90\x34\x61\x96\xd7\x7e\xc4\x72\xdc\xae\x9e\xb7\x83\xf5\x71\xd0\x17\xa9\x0a\xed\x2c\xf4\xfa\x0a\x3d\x81\xee\xbe\x5c\x9e\x2f\x28\x7a\xe3\xdb\x1a\x88\x6c\x75\xa2\x75\x21\xef\x4a\xf5\xda\x0e\x9e\x75\xd1\x3d\xa4\x10\x89\x72\x28\xc4\x9f\x20\x4e\x65\x61\x3d\xa7\xc9\x30\x91\xb1\x01\xe5\x35\x1a\x8f\xa7\x06\x0e\x34\x18\x4d\x5e\x8a\x22\xa3\xce\x14\xb4\xc4\x65\xa7\x49\xa0\x4b\x52\x2d\x65\x6c\x3c\x2b\x13\xb5\xc0\xfb\x0f\xbe\x91\x61\x1a\x0b\xd3\x96\x99\xa5\x35\xff\x4d\xb2\x74\x36\x6a\x2c\xa9\xd1\x0c\xaf\xd2\xf6\x89\x13\xb1\xff\x63\x10\x91\x90\xd4\x40\x9c\x04\x5e\x5a\xa8\x79\x99\xae\xf9\x8c\x84\x01\x4a\x15\x5c\x71\xd6\x49\x46\xa2\x14\x6d\x3b\xa1\x14\xfa\x6b\x23\xcb\x86\x11\x29\x10\xe2\xfe\xe7\xd3\x1f\xb6\x92\xf9\xb0\x7a\x7c\xd8\x3f\x2d\x56\x7b\xdf\x02\x97\xac\x61\x08\xe6\x3c\x47\xbe\x3e\xee\x16\xc6\x82\x38\x92\x03\x01\x9e\x3c\xab\x9b\x4d\x31\x33\x4c\x18\x4b\xb4\x20\xbd\x20\x40\x59\xb8\x42\xad\x3e\x59\x25\x19\x33\x10\xfb\x12\x75\x1b\x8a\xb9\xae\x81\x93\x2c\x24\x56\xa7\xea\xe6\xe7\x50\x31\x42\xb2\x90\x89\x80\x79\xc1\x69\xdd\x05\x27\x87\x37\x08\x53\x86\xe6\x62\x5e\x76\xae\x26\x8b\x22\x81\x9b\xae\x14\x35\xea\xf2\x76\xbf\xf3\x00\x41\x0f\x3d\xa8\xd4\x6e\x66\x13\x57\x99\x45\x5c\x63\x1a\xe3\x84\xc3\xe7\x5b\xd6\xeb\x18\x48\x16\xc5\x96\xde\xc7\xc2\xa0\xbe\x96\xe7\x1a\x56\x79\xeb\xd1\xa9\xe9\x45\x62\x13\x8e\x98\xae\x37\xc5\x5b\x36\xc8\x1b\x8c\xdd\x0f\x16\x29\x8d\xa4\xd6\x5f\xa0\x80\x3a\x9b\x6c\x49\x8c\x13\x15\x3b\x8b\xd7\xe7\xcb\xeb\x45\xa1\xf7\x2f\x90\x55\xce\x12\xea\xc6\x05\x8f\x6d\x8a\xf3\xb9\x8b\x7b\x0f\xc1\xa3\x92\xc5\x24\xc4\x11\xfb\xf3\xe7\xcf\xdf\x55\xce\x49\x16\x27\x16\x8d\xba\xde\x7f\x75\x25\xd1\x9e\xd7\xd8\x35\x48\x5b\xd7\xbe\x1d\x85\x65\x55\x95\x84\x8e\x3e\x5f\x2a\x41\xd9\xd2\xcf\x7b\x61\xf1\x54\xae\x4c\xde\x37\x10\x81\x88\x3b\x0e\xb5\x8d\x46\x92\xed\xfe\xd2\x02\x78\x4c\x3c\xcf\x54\x0d\x8e\x5d\xd4\x1d\x94\x91\xa5\xf8\x6b\xfb\xe9\x6f\xe3\xae\x54\x24\xc6\xc8\x9a\x5d\xea\x9f\x40\x5d\x94\x63\x54\x06\x3d\x58\xf2\x99\x8a\xd2\x01\x80\xf1\x31\x9f\xf3\xcd\x98\x8a\x6c\x4a\x55\x68\xed\xc8\x09\x9f\xac\xbe\x87\xce\x2c\x7e\x78\x76\x71\x61\x3a\x92\x56\x2c\x1b\xb5\x4e\x1a\x70\x51\xe8\xdf\x1b\xde\xf3\xa9\x44\xc9\x74\x1a\x26\x91\x27\xe6\xc1\x9e\x18\x32\x8f\x49\xa6\x95\xc0\xf0\x4a\x25\xba\x85\x97\x69\xc3\x30\x71\x84\xb9\xf4\xcd\x7c\x20\x52\x32\xe0\x31\xba\x70\x3e\xf9\xf9\xa1\xaa\x85\x6b\x6f\x1c\xb9\xa9\x0f\x4c\xb6\xab\xfd\x16\x95\x46\x26\x33\xc0\x48\x96\xd8\x0a\x2a\x79\xbe\xec\xce\xe3\x32\x68\x19\x92\xd0\x82\x1a\x2d\x89\x71\x5e\x5e\x16\xcd\xdc\xce\x1d\x06\x51\x8a\x1a\x14\x6f\xa5\x15\x26\x6e\x9d\x84\xdf\x71\xbd\x0d\x56\x88\x30\x90\x91\xa1\x9e\xd5\xb3\x11\xb9\x5b\xa5\x67\x54\x31\x64\x48\x03\x63\x89\xda\x2b\x80\x06\x26\x03\x2b\xa4\xa1\x21\x6e\x03\xda\xb6\x73\xda\x72\xa2\x4c\x9d\xaa\x7e\x84\x85\x34\x96\x56\xc5\x1e\x6d\xaa\x6e\x39\x5d\x95\x55\x01\x15\x82\x75\x9d\x21\x72\xbd\xba\x86\x34\xb1\x42\x92\x38\x37\x6e\xcb\xea\x27\x64\xd3\x87\xd5\x06\x97\xf7\x76\x2d\xfb\x09\x19\x32\x3f\xb6\xbe\x45\x79\x6e\xbe\xfd\xd3\x05\xdb\x65\xc8\xc2\x2e\x8e\xfc\xbd\xd6\x5b\xa8\xbe\x9e\x0b\x5d\x21\xed\xdb\xe4\x7a\xcc\x08\x9b\x9f\xdd\x2d\xce\xdd\x72\x11\x86\x01\x0b\x1d\x64\xe0\xb1\x75\x7c\x9f\x32\xf5\xc2\x6e\x26\xdf\x32\xa4\x56\x46\x05\xab\x8a\xdb\x25\xf7\x20\x82\xb0\xbb\x02\x4b\xd8\x5f\x52\x38\x1c\x98\x7d\x21\xa7\x1a\xb7\x21\x69\x91\x07\x1f\x0e\xc7\x90\x33\x1a\xb8\x08\x31\x7a\x57\xed\x3e\x7b\xad\x55\x29\x43\x1e\x71\xd1\xd3\x46\x2e\xea\xba\x54\x59\xbb\xf6\x8f\x32\xe0\x32\xe4\x3c\x34\x5e\x5d\xab\x74\xac\x32\xe3\xeb\x88\xd8\x32\x39\xa3\xe0\xf1\xe0\x83\x71\x61\x75\xff\x0c\xb4\x06\x66\x21\x4e\xf5\x4b\x69\x03\x55\xcb\x8b\x8d\x23\x8c\x1f\x28\x26\x04\x03\xa6\xce\x35\x44\xc3\x69\xb0\x7a\x86\x31\x89\x7c\xb8\xfc\xf1\x0d\x2a\xd1\x05\xe4\xc2\x38\x48\xb5\x5b\x18\xff\xa7\xb5\xbb\x2f\xd3\x2b\x47\x01\x86\x5c\xca\x22\xbf\x0c\x73\x82\x23\x51\xdf\x4f\x21\x11\x32\x8c\x13\xa3\x9c\x40\xc9\xf7\x5a\xf7\x60\x20\x19\xc6\xa9\xd5\x9e\x6e\x3b\xfa\x4b\x66\xae\xe5\x3a\x86\x1b\x48\x18\x6b\x1b\xdb\x7a\x02\x91\xb7\x2b\xc5\x93\xb8\xec\x2b\xa1\xfa\x4d\x20\x8c\xb5\x90\x2e\xc0\xd0\x6e\x11\x63\x7e\xd0\xc9\x53\xa5\x94\x60\xbc\x0a\x59\x9d\xdb\x96\xa3\xc8\xf4\x27\xa3\x24\x8d\x2c\x4f\xf9\x16\x90\x95\xcf\xdf\x3b\xe5\x06\xd3\x00\x9b\xba\x46\x16\x29\x5b\x31\x3f\xb9\xa7\xb0\x32\x32\x2f\xa2\x9e\x48\x52\x8e\x4d\xc1\x30\x55\x14\xb1\x97\x2e\xab\xbb\x73\x25\xb4\xbf\x35\x2c\xe7\x3f\x40\x6a\x92\xb0\xc3\x83\xde\xfc\xb6\x52\x5c\x86\x82\x10\xd4\x8b\x3f\xdb\x12\xbe\x0e\x03\x26\x43\x41\x89\xa1\xbe\x44\xdf\xf2\x8f\x63\xd5\x92\x23\xd2\x1e\x5f\x25\x24\x58\x1b\xe0\xb6\xf9\x91\x20\x9d\x6b\x22\xe3\x84\x24\x1d\xcc\x6a\xdd\xbc\x78\xc6\x26\x7f\x3f\x15\x5a\x40\x3e\x4a\xc8\x21\x87\xd8\xf8\xd5\x94\x8c\xac\xad\x53\xe6\xba\xaf\xe6\x93\xa1\x52\xb6\x6c\xcb\x45\xee\x8f\x27\x51\x64\xfd\x51\x1d\x47\x3a\x19\x29\x48\x1d\x45\xd6\x9a\x93\x6f\xb8\x21\x67\x93\x08\x5a\xa8\x53\x82\xcb\xd9\xc3\xe2\xe1\xb1\xbb\x86\x34\x1e\xc4\xbe\x03\x55\xc1\x74\x91\x00\x62\x6b\x0c\x3d\x20\xc3\x46\x2a\xeb\x69\xab\x44\xcb\xce\xc9\xb8\x81\x37\x7f\x75\x23\x39\x62\x75\xef\xfe\xf8\x36\x9c\xc9\x11\x0d\xc2\xd8\x0c\x98\x4d\x90\x50\xab\x69\xae\x53\x40\xbf\xf3\x3d\xfc\xf5\xa2\xc0\x53\x7d\x5a\x0f\xe7\x47\xd9\x80\x05\x5d\x7c\x60\x8f\x44\xd4\x50\x8c\x5e\xbd\x5b\xad\xd8\x91\x45\x18\x31\x43\x63\x87\x0e\xd8\x14\xb3\xf8\x75\x19\x85\x24\x09\x46\x10\xa9\x2b\x35\x39\xdf\x30\xd2\x68\x4e\xa0\xb2\xd1\xbe\xdc\x41\xa1\x57\x2f\xa2\xc7\x29\xc9\x28\x62\x91\x4c\x7b\x66\xbc\x9f\x00\xaf\x3b\xe4\xb1\x1d\x5f\x28\xd2\x14\x53\x7f\xef\x65\xf5\x7a\x53\x16\xd3\xc3\x3c\x88\xad\xbc\x6e\x91\x75\xb0\x90\x45\x55\xcd\xad\x01\xd3\xd5\x20\xe2\x2c\x60\x43\x01\x84\x25\x7c\xb4\xe2\x44\x71\x68\xb1\xcd\xc7\xcc\x01\x0a\xf7\x3d\xba\x52\x46\xb1\x10\xa9\xe7\xc4\x15\x03\xd9\x4f\x17\xcd\x18\x99\x0f\x51\x6c\x34\x26\x92\xe1\x98\x21\x0b\xf2\x07\x77\x4c\x22\x1a\xba\x44\xc4\xa7\xa9\xa6\x28\xd1\x91\xf6\xc3\xa0\x82\x63\x76\x3e\xae\x44\x35\x37\xe1\xa2\xc4\x58\x7d\x2a\xeb\xb4\x38\x30\xdf\xb8\x49\x1a\x00\x96\x2e\xd9\x11\xbf\x2f\x6f\xcb\xea\x19\xf6\x2f\xf0\x00\xbf\x9a\x81\x64\x90\x8c\xd2\x50\xe1\xe6\x73\xd0\x2e\xf3\x89\xe1\x58\x27\x49\x72\x44\x65\xd7\x39\xa0\xbd\x8c\xd2\x54\x22\x5b\x1c\xb2\xd9\xa8\x31\x47\x90\x8c\x04\x63\x23\x4d\x8a\xdb\xb2\xba\xcd\x8a\xd6\xb1\x19\x32\xe8\x4c\xba\x4a\xa4\x0c\xf3\x2b\xaf\x99\x03\xb4\x76\x7d\x2d\xb4\x55\xa5\xad\xa0\x86\xea\x0d\xb4\x9d\x77\x2f\xa2\x7a\xbe\x4a\x82\x44\x02\x22\xaf\x94\xa1\xfa\xe8\x5c\x24\xb9\x55\x4f\xb4\x20\x81\xba\xf7\x6f\xdd\x71\x45\x6c\x30\x72\xf9\xb8\x3f\xac\xef\xd6\xf7\xeb\x87\xfd\xc1\xdb\x3c\x91\xd6\x31\x41\xf3\x25\x7b\x46\xd7\x7d\x04\x85\x93\x11\xd0\x14\xa1\xd4\x47\xf1\xeb\x58\x16\x70\x39\x4d\x0e\x47\x2c\xf6\x0e\x2c\xae\x83\x55\x5f\x13\xd2\x5a\xb3\x21\x0e\x49\x77\x52\x36\x91\x35\x92\x91\x61\x04\xa9\x40\xd7\xdf\xbe\xad\x7a\xa5\x1a\x19\x19\x6d\x91\xe3\xf2\x7c\xd9\x32\x57\xec\x2e\x79\x10\x71\xea\x8a\x4d\xd7\x85\x2e\xab\x1a\x2b\x85\xeb\xb1\xed\xcb\x03\x2d\x51\xdb\xaa\x6e\xca\x53\x6b\xea\x8f\xba\x90\x07\x26\x42\x38\xa1\x03\x17\x59\x4f\xdf\x32\xb5\x4d\x5a\x52\xa6\x10\xc4\xbf\x6b\xaa\xec\x74\x1a\xa7\x11\x39\xe5\xd2\xe7\xa8\x7f\x66\x1a\x99\x1f\x5b\x03\xf9\xb6\xac\x46\x9b\x14\x67\x24\x44\x99\xa0\x9b\xc5\x76\x3b\xba\x00\xa3\xc2\x0b\x2b\x6e\x5a\x33\xe2\x3e\xfb\xd5\x6d\x4b\x3c\x84\x38\x86\x8e\x82\xad\xe3\xe4\x1a\x72\x97\x4a\x1e\xb1\x38\xb2\x7b\x17\xe8\x7b\x24\x65\x1c\x77\x2e\xe7\x2c\xc0\xe2\x5e\xe4\x33\x19\xf7\x11\x0f\xb5\x72\xfa\x75\x4f\x65\x0e\xb7\xe5\xb8\xd6\x60\xf4\x0a\x9c\x43\xd8\x17\xf0\x7d\xed\xc7\x1d\xe7\x09\xc1\xb8\x8e\x8f\xda\x8c\x33\x1d\x9c\xab\x30\x68\xef\xdf\xe5\xbd\x7b\xee\xf6\x5b\x4c\x97\x4f\x3a\x9c\x6b\x42\x7b\x3f\xc2\x4b\x56\xcf\xce\x27\x9e\x98\x04\xa1\x53\x16\x13\x82\xd5\xfe\xd3\x1c\x07\x4f\x01\x74\x4f\xb6\xb6\xcd\x45\x61\x45\x2c\x3f\x44\x69\x8e\x5e\x5b\x72\x86\x95\xcf\xf9\x59\xbd\x5e\x76\xad\x07\xb4\x16\xc3\x08\x3e\x97\xa9\xc0\x7c\xaf\x39\xab\xd7\xac\x78\x7e\xed\x00\xd7\x92\x2b\x16\xa9\xf6\xab\xdf\x9f\xe5\x28\x01\xc2\x15\x57\x28\x71\xb1\x5b\xdc\xad\x0f\xf7\x9b\x87\x9e\x1b\x44\x72\x25\x05\x4e\x96\xd6\x84\xae\x41\xd4\x36\x6b\x0b\x30\xbe\x82\x26\x11\x7e\xb9\xa3\x6e\x86\x48\x47\x7f\x94\x5a\x71\x83\xdb\x4e\x1f\x39\xf1\x47\x34\xf8\x00\xd5\xc8\x29\x1f\x77\x19\xd0\x14\x03\x19\x9d\x2a\x68\xbb\xdb\xcd\x04\x1b\x38\xb0\x40\x5a\x8d\xf4\x4e\xdd\xeb\xbb\x23\x1c\x9e\x22\xee\x25\x87\x38\x22\x16\xf7\xe7\x0d\xd7\xd9\x4b\x26\x80\x9d\xa6\xcb\x6d\x55\xbe\x65\x1a\xee\xe1\x58\x56\x0e\x87\x3c\x64\xc4\x9c\x88\xcb\x5d\x6d\x9a\x1c\x04\x49\x3a\x7d\xbd\xd6\x94\x6f\x97\x01\x7f\x4c\x13\xdc\x3d\x5c\x74\x7c\xd7\xc0\xe9\x03\x74\x09\x07\x9d\x22\x84\x7f\xb7\x5f\x8e\x3e\x01\x80\xc4\x34\xc1\xd7\xec\xf9\x05\x6a\x54\xe3\x9a\xe0\x64\x46\xd7\x89\x49\x18\x61\x84\x65\xd9\xc5\x3b\x63\x92\x02\x92\x17\xff\x84\xec\xa1\xfb\x4d\x06\x18\xcb\xab\xc5\x9b\x93\xbe\x1b\x8e\xc7\x98\x28\x83\x9f\xd6\x64\x55\x6d\xf5\xaf\x57\x65\x7d\x2c\xeb\x3e\x7c\x1d\x07\x24\x44\xeb\x19\x0b\xb2\x9d\xbf\xee\x0f\xf1\xd4\xd3\x16\x96\xa7\x1f\xe2\x9c\xe3\x8e\x3d\xfe\x02\x31\x15\x01\xfa\x37\x4e\x1f\xec\xc6\x32\x99\xe3\x82\x3e\x5a\x3e\xe2\x90\x84\xc8\xbd\x67\xdd\x07\x97\x61\x98\xf9\xf2\x71\xc8\x53\x2c\x95\x3c\x66\x05\x7a\xba\xce\x06\xee\x69\x5d\x64\x3b\x34\x90\x95\xf8\xe6\xe6\x7f\x6e\xf6\x3d\x47\x95\x8c\xa3\xc0\x32\xd4\x23\x7a\x71\xff\x52\x95\x05\x3c\x6d\xc7\x7d\xc2\x03\x8e\x76\x8a\x79\xb7\x2e\x30\xd2\x9b\x0d\x83\xae\x31\x77\x9c\x6e\x8e\x1f\xcd\x52\x20\x8c\x3f\x0f\x4f\x42\xcf\x9d\xb4\xbc\x20\x34\x00\x0a\x05\xab\x52\x4f\xdf\x3a\xa6\x14\xeb\xef\x3a\xfa\xa7\xc9\xcb\xc6\x31\xc3\x20\xe2\x4f\x51\xa0\xec\xda\x6f\xd5\xc7\x65\x9c\x84\x80\x51\x9c\x9d\x30\xf0\xf8\x5e\x0c\xf6\xce\x38\x49\xe3\x88\x0c\xa5\xaf\x72\xeb\x0a\x4d\x6e\x2a\x98\x4b\x23\xbc\x64\x75\x6b\x5c\x57\x35\x2e\x71\xfe\x68\x62\x8c\xa3\xe1\xe8\xa2\xb1\xb3\x76\xa7\x2c\xcb\xdc\xcf\x9f\x58\xa6\x16\x80\x65\xa9\x7e\x71\xec\x53\x42\x03\x7f\x51\x69\x6c\x34\xbd\x3d\xc7\x31\x2e\x4c\x7a\x4a\x49\xa3\x4c\xdf\xeb\xce\xa4\xe8\x06\xa3\x26\x69\xd8\xd3\xd2\x6d\xcb\x72\x82\xc4\x88\xb5\xe0\x03\xe6\x64\x4b\x0f\x5d\x5d\x4e\x4d\xd9\x21\xb2\xe7\x76\xaa\x58\xab\x08\x57\x64\x5b\x00\xea\xa8\x2e\xdd\x31\x48\x13\xf4\xf4\xc4\xe9\x04\x85\xee\xab\xd5\x12\xd7\x0d\x6e\x9d\x8c\x4d\xac\x7c\x5d\x0b\xe2\x12\x7a\x6f\x20\x36\xa9\x05\x3a\xe4\xed\xf3\xd4\xfb\xea\xdc\xbc\x7c\xf0\x59\x8d\x09\x49\xd8\x83\xb7\xaa\x7a\x2b\xaa\xe6\xf2\xa3\xc3\x4c\xca\x84\xa4\x14\xb3\x0d\x67\x47\x1d\xf9\x64\xad\xbf\x45\xa1\xdb\x55\x7d\xc0\x2c\xd4\x36\x65\x09\x74\x7c\x01\x6d\x7f\x8e\x7b\x2b\x21\x46\xa8\x9e\xb7\xe0\x47\x56\x8b\x0f\x1d\xf9\x29\x90\xf6\x53\xc7\x3e\x21\x46\x21\xf0\x12\x72\x9f\xca\x4c\x02\x11\x59\x3c\xad\x03\x2b\x51\x07\x56\xa2\x0e\xa4\x44\x27\x60\xa5\x24\x90\x31\x46\x83\xeb\x97\xf2\xfd\x07\xd2\xa9\x8e\x1f\x3e\x50\x02\x71\x6e\x9d\x63\xa4\x8f\x59\xb1\x85\x51\x55\xa0\x6b\x4a\x23\x86\x05\xfe\x03\xdc\xed\x97\x4a\x14\xd3\xee\xa0\x06\x88\x97\xca\xdc\x34\x70\x9c\x97\xfc\x1b\x8d\x9c\x76\x05\x40\xc8\xdb\xad\x38\x2b\x18\x96\x5a\xcb\x24\x94\xa0\x5c\x10\x79\xbf\xb9\x5f\x1f\xf6\x8f\x87\xfb\xc5\xb7\xf6\xef\xfd\x62\xff\xb8\xde\x8d\x57\x93\x24\x04\x2d\x9d\x4f\xf4\xf4\xf0\x65\xf2\x68\x51\x1c\xa2\xa3\x08\xbf\xb2\xba\xb1\x36\x7a\xbd\xbc\xe0\x84\x1d\xf7\x1a\x8f\xa3\xc4\x4a\xcf\x15\xba\x7c\x67\xae\xca\xc4\xd6\xd1\xf5\x20\xc1\x84\xc7\x9d\x2e\xd1\x0d\x18\x40\xdc\xe5\x84\x7b\x59\x26\x71\x20\x11\xc4\x20\xac\xd7\x3d\xff\xa9\xe3\x30\xa2\x7d\x45\x8e\xd7\x95\x91\x49\x0c\x56\x9d\x12\x54\xb9\xc3\xb4\xf6\x6d\x6f\x81\x26\x09\x4d\x18\x1d\xb0\xd9\x3e\xc1\x1b\x20\x69\x6c\x1f\x6b\x4c\x52\x92\xe0\x9e\x94\x75\x2a\x36\x23\xdf\x24\x49\x99\x55\x45\xb4\x42\x63\x87\xda\x2b\xec\x77\xcc\x75\xe1\xff\xce\xc8\xc9\x76\x27\xdb\xa7\xcb\x54\x89\x01\xf3\xb1\x01\x9a\xa4\x91\xb1\xe5\x95\x8d\x78\xee\x8b\x3a\x65\x92\x8a\x04\xf5\xc1\x11\x86\x32\x32\xaa\x93\x54\xda\x2c\xa0\xa7\x86\x98\x31\x8b\x3f\x98\x2c\x82\x69\x0f\xff\xdb\x6e\xac\xa8\x41\x38\xda\xad\x12\x19\x0a\x1e\x74\xbb\xe6\xf8\xbe\x5a\x1a\xa4\x0d\x2c\x4f\x16\x6a\xb9\x83\x42\x2f\x2f\x9e\x8a\x7f\xe2\xa6\x7e\xa6\xbb\xef\xae\x07\x54\x20\xbf\xc1\x3b\x64\x2b\x71\x1a\xe9\x54\xca\x04\x38\x41\x38\x43\x79\x6e\x4e\xe7\x46\x4e\xc6\x1e\x70\x83\x5f\xc4\x91\xd4\x7c\x40\x8d\x21\x13\x10\x29\xc4\xdd\x4a\x79\x06\x2f\x6a\xf8\x41\x6b\xa5\x31\xb3\x5f\x65\xcf\x2f\x0d\x9b\x0c\x51\x00\xab\x20\x84\x86\xcb\x4d\x36\xa6\xa5\x9e\x5c\xc8\x10\x70\xce\xee\xb9\xf5\x9b\xe6\x48\xc9\x64\x62\x4c\x2c\x3d\x04\x71\x49\xfe\xd6\xfd\x6a\x2d\x76\xa1\xb5\x5d\x96\x07\x5b\xe1\x58\x54\x4f\xa6\x24\x88\xb9\x19\x14\x9a\x3e\x94\x15\x02\xef\xad\xbc\xf5\x1c\xae\x5b\xa6\x84\xd9\x49\x54\x43\x73\x5f\xea\x0f\xf8\xcd\x65\x4a\x22\x8e\x41\xb9\x73\x6d\xcb\xd5\xae\xf3\xe9\x69\x10\x5b\x5a\x5d\xbf\xf9\xaf\x8b\x26\xab\x60\x26\xf6\x94\x06\x8a\x46\xce\x7a\xd9\xb5\x2e\x48\xbb\x98\x7c\x30\xc9\xd3\x40\x81\x57\xd5\xf2\x32\xed\x33\x8d\x00\x70\xe4\x88\x21\x54\x39\xa5\x24\xf0\xa3\xdb\x86\x79\x9d\x10\xfc\xfe\xa5\x82\xfa\x65\xc0\x65\xe6\xdb\x6b\x66\xc5\xe2\x44\x55\x65\x50\xed\x9a\x6a\x18\xc7\x4b\xa9\x61\x98\x9a\x38\x8d\xc7\x8c\x3b\xca\x88\x95\x43\x78\x2b\xdd\x32\x3f\x57\x6d\x26\x53\x46\x23\x7b\x8f\xf3\x65\x52\x84\x31\x93\x1f\x4e\x43\x1a\x23\x84\xa9\x03\x5b\x0f\x45\x23\x64\x1a\xc6\x96\x40\xc1\xda\x24\xbb\xa6\x35\xc5\xae\x0a\x77\x65\x1a\xa6\x76\x3b\xc3\xd2\xb5\x9b\x32\xcf\x45\x55\xf7\x6e\xad\x2d\x2f\xc9\x27\x9e\x40\xc0\xc9\xdf\xed\x1f\x7f\x11\x49\x10\x28\x58\x01\x7a\x28\xad\xb1\xd2\xee\x76\xa3\xc7\x8d\x62\xc9\xdd\xec\xda\xf9\x12\xfc\x47\xe3\x68\x93\x35\xba\x2d\xdb\xaa\xbc\x29\x55\x8f\xfc\x69\x97\x3b\x66\x13\xf9\x5e\x6d\x64\x2b\xd4\xeb\xb4\xdc\x5d\xa6\x3c\xb1\x56\x79\xfd\x52\x56\x1e\xa0\xd2\xf3\xe8\xc9\x34\x0e\x2c\x2b\xc5\xa1\xe9\xe8\xa5\xba\x43\x90\x44\xbc\x0f\x28\x0f\x85\x0e\x64\x9a\x44\x96\xaa\x01\x7e\x9d\xa0\xca\xda\xed\x68\x5f\x5a\xa2\xff\xf1\xfd\x53\x12\x28\x57\xc6\xef\x98\x7b\xeb\xe5\xe5\x49\x14\xaf\x9f\x57\x6d\xca\x34\xa5\x36\xa3\xf5\xf5\xc7\x9f\xe3\xaf\x97\x72\x83\x35\x4c\xff\x39\x8b\xca\x23\x17\xa6\x15\xea\xa3\x5c\x6d\x9a\xa6\x41\xa4\x3d\x95\x40\x6b\xe6\x0e\x49\xe0\x65\x2a\x04\x37\x89\x77\x97\xab\x31\x36\x2f\x15\x42\xa0\xb4\x9c\x78\xeb\xda\x4b\x29\x31\x96\xdc\x57\xb4\xf6\xdb\x51\xaf\x4a\xf1\x13\xb2\xc9\x78\x92\x3a\x42\xff\xc4\xe1\xfb\xbe\x8a\x42\xf7\x10\x8e\x54\x11\x2b\x76\x6c\x2d\x9e\xa7\x72\xc0\x53\xe7\x5b\xf0\x18\xcb\xb1\xb6\x73\x78\x56\xdf\x26\x16\x7d\x19\xd8\xdd\x40\x8b\xba\xbb\x8d\xa0\x18\x28\x75\x92\xe9\x57\x1f\x61\xfc\xc8\x10\x84\x48\x51\xec\xcd\xcd\xea\x3c\x5d\x07\x21\xb5\x4c\xd2\x08\x7e\x84\xa6\xe9\x9c\x9a\x14\xb4\x45\x8e\x29\x61\x2b\x46\x6e\xb3\xfc\x43\xfe\xa8\xc9\x5b\x98\xd8\xe6\xc5\x8e\x87\xb3\xd7\xbd\xb0\x05\x6a\x1b\xed\x71\xcf\xa9\x49\x62\xe1\xd2\x39\x0f\x00\xd6\x27\x6c\xcd\xea\x49\xa7\x19\x13\xa1\x45\xbd\x50\x42\xc3\x31\x53\x1f\x90\x43\x4a\x41\xc2\x10\x27\xca\xe9\x50\x0f\xe0\x2c\x53\x9e\x86\xc9\x39\x32\x45\xd2\x7d\xaf\x2f\x39\x48\x48\x8a\x80\x45\x58\xe7\x04\xa2\x2a\x40\x4f\x0a\x38\xa5\x08\x22\xc2\xb8\x87\x9f\x65\xfe\x24\x2a\x2c\xa5\x6c\xeb\x28\xdc\x5e\x8d\x00\x41\x85\xf0\xa0\x01\x0c\x6d\xcf\x84\x56\x04\x55\x96\xa1\xc6\x95\xc8\x5b\xbd\x2f\xb7\x87\x6d\x2b\x30\x19\x4a\x09\xff\x6d\x5c\x4f\xe7\xff\xce\xfe\x5f\x77\x61\x46\x12\xad\x7b\x11\x90\xe1\x62\xed\x47\x97\x88\xa9\x03\x98\x20\x4d\x9c\x85\xe7\x65\x79\xd6\xa7\xca\xc7\xe3\x4b\xc4\xa0\xd0\x9d\x59\x9e\xff\x6b\xe3\xea\x99\xc8\x77\x4d\x3b\x30\x9f\xfd\x7c\x17\x09\x0f\x91\xc8\xb1\xac\x84\xca\xb3\xff\xc2\x3f\xce\x50\x5d\x56\x3d\xb0\x4a\x24\x31\x30\x18\xe4\xda\x9d\x99\x70\x8b\xc1\x13\xfb\xdf\x1f\xb0\xdc\x4a\x91\x48\x22\x12\x0f\x9e\x40\x47\x64\xe7\xad\xd2\x09\x08\x62\x72\x9e\x4a\x31\xb4\x74\xb4\xeb\xb9\x55\x44\xe9\x1e\xc8\x04\x98\x8a\xdc\xb9\xcf\xf4\xb7\x19\xd2\x21\x29\x52\x16\x04\x3e\xc2\xdd\xbc\x40\xe5\x88\x38\x3b\xad\xc1\xfe\x66\x22\x09\x9c\x36\x8e\x8d\x69\xce\xa5\xc2\x84\xd0\xb6\xa4\x40\x43\x7e\xc5\xfa\x30\x29\xf1\x96\x42\x32\x82\xdf\xe9\xe6\x71\xd5\xf3\xf6\xfa\x63\x22\xd4\xf6\xd5\x1c\x75\xdb\x38\x2f\x27\x14\x4d\x30\x4d\xb5\xdb\x2d\x86\xce\x93\x50\x26\x02\x3d\x66\xc5\x1d\x57\x95\x4e\xde\x5f\x2b\x81\x5e\xfa\x48\x0b\xf9\x93\x6c\xb9\x80\x20\xd2\x7d\x6d\xe0\x10\xce\x28\x20\x4e\x23\x70\x55\x76\x65\xe1\xcb\x2b\xc7\xf7\x33\x2c\xc2\xb0\x58\xe1\x8c\xd7\x6e\xd0\x9a\x10\x50\x97\xa7\x80\xf7\x89\x58\xf7\xa4\x8b\x0d\x07\xaf\xc4\x3b\x2d\x2b\x99\x87\xe7\x0b\x13\xc7\x18\xba\x46\xc9\x1f\x51\x5b\x46\xb9\xfa\xd3\x4a\x0f\x61\x54\xa4\x48\x67\x9d\x2c\x45\xf1\x5a\x95\xf9\x64\x5b\x95\x44\x29\x4c\x08\x34\xae\xb4\x7d\x94\xea\x96\x01\x4f\x10\x55\x92\xd5\x0e\x89\x70\x7b\xbe\xba\x42\x90\x5a\xd9\xb5\x4c\x95\x48\x52\x6b\xcd\x0e\xd6\x5d\x42\x24\x88\xf3\xd8\x57\x42\x23\xd9\xc9\x90\xb9\xe7\x2f\x26\x88\xdd\xa5\x68\x92\x62\x12\xed\x44\x0f\x68\x03\xf9\x5b\x50\x0d\x42\xf7\x50\x69\x0f\x0b\x6c\x9d\x86\xf1\xa7\x93\x8c\xe9\xa8\x13\x15\x59\x34\xaf\x36\xbf\xfc\x0f\x74\x06\x26\x2d\x85\x4d\x53\xfa\x54\xf9\xf7\xa7\xcd\xe4\xbd\x43\x1a\x24\xa2\xaf\xc5\xf5\x51\xa6\x35\xba\xe9\x7d\xe0\xb9\xf3\x6a\x65\x18\x3a\x2a\x2e\x2b\xb3\x66\xe3\xd5\x9e\xda\x52\xca\x28\xb4\x29\xa8\xbb\xc7\x2f\x87\x3e\x94\x6e\x51\xc0\xbe\x89\xb0\x9a\x2b\xe7\xc2\x6b\xdc\x82\xc6\x95\xea\xed\xfa\x05\x22\xcd\x31\x9c\xe4\x69\x31\x3f\x9c\xcb\xae\x3d\xe7\x22\x76\x85\x4c\xeb\xfd\xd7\x59\xe3\x59\xc6\x2c\x42\xef\x6d\x51\x55\x2f\x38\x23\x27\x61\x03\x99\x04\x12\x8b\xb2\xd0\x5e\x3e\x48\x68\x0e\x27\x47\x05\xd8\xbd\x43\x22\x12\x8f\xf5\x5c\x95\x45\xdd\x76\xc1\xc4\xb4\x90\x89\xd4\x68\x2f\xef\x37\xab\xd6\xaf\x9b\xde\x43\x0b\xea\x8a\x11\x50\xda\x70\x00\x81\x6d\xbd\x15\xac\x3c\xea\xab\x4b\xc5\xa5\x3c\x4f\xaf\x90\x9a\x00\x83\xb7\x6d\x6f\xd8\x3a\x0b\xaf\x99\x7f\x1e\x96\x63\x7d\x0e\x8d\x96\x22\xe0\x08\xdc\xcb\xcc\xca\x5a\x16\x0f\x13\x95\x7f\x29\x05\x0d\xd0\x14\xab\xdf\x85\x65\xcc\x44\x1d\xdd\x8f\x15\x88\xfc\x69\x2c\xb4\xaa\xa0\xa8\x07\x95\x15\x7d\xb4\xbe\xdd\x18\x31\xdf\xb1\xff\xef\x7e\xb8\x66\x4a\xa1\x22\x94\xd0\xce\xea\x65\x39\x1d\x09\x42\x59\x6e\x82\xdd\xfe\xc7\xea\x71\xf3\xf0\x19\x20\x56\x4a\x42\x70\x2d\x45\x6e\xb9\x47\xf3\x54\xca\x72\xda\x7b\x32\x08\x70\x4d\x78\x86\x66\x73\x14\xcf\x70\x0f\x8d\xd0\x9e\x58\x78\xd0\x2c\x0c\xb1\x22\x01\x9a\x97\x43\x56\x1f\x6a\x00\xdd\x0f\x02\x25\x62\x04\xf3\x6c\x8e\x8e\x49\x74\x3e\xdc\x36\xbe\x22\x10\x89\x59\xe5\xc7\x6f\xb7\x5d\x76\xd3\x5f\x10\x74\x28\x3a\x3e\x02\x95\x9d\xb2\x2b\x07\x51\x9a\x30\x40\xf1\xc1\x69\x4d\x89\x22\xa1\x65\xd9\xd5\xf0\x36\xa5\x47\x92\x8a\x44\x89\x8f\xe4\x2d\x77\xb3\xe5\xbc\x2a\x88\x25\x46\x8c\x90\xb6\x99\x79\x8e\x90\xa3\x18\xe4\xfd\x54\x10\x1b\xfc\x6e\x2b\x4f\xab\x38\x0c\x60\xff\x16\x1f\x83\x2c\x1b\x57\xfb\xd9\xb8\x7b\x54\x90\x4a\x69\x49\x52\xe4\x97\xcc\x34\xbb\x4e\x71\xae\x7b\x06\x20\x26\x18\xc8\xbe\xb4\x8e\xea\x6c\x51\x9c\xa2\xdc\x26\xea\x5c\x34\xc7\x46\x12\x47\xbc\x26\x52\xd1\x98\xc9\x01\xf8\x13\x72\x55\x1e\xc7\x2e\x8f\xa2\x49\x84\x89\x0a\x14\x7f\x7f\x34\xa6\x9e\x66\x9b\x15\x95\x89\x07\xc9\x2e\x73\xd1\x5d\x5a\x2a\xf4\xba\x17\x5a\x3b\xee\x2a\x79\x1d\x50\x1b\xdd\x89\xd1\x08\x60\xca\x0d\xb4\x2f\xbd\xf5\xed\x2f\xcc\x54\x8c\xf1\x24\x44\x69\xfe\xe5\x81\xa7\xc2\x28\x4a\xfb\x32\xd2\xc3\xee\xe9\x61\x7f\x38\x5d\xe3\xfc\x55\x18\x7b\xb2\x4b\x5b\xf7\xb8\x2e\xfa\x21\xaf\x42\x09\x11\xed\x58\x1b\x6d\x11\xfb\x30\x1f\x34\xb9\x67\x14\x24\x20\x86\xdc\x39\x97\x1d\xe4\xc6\x5f\x2c\x8a\x13\xe3\x42\x55\xab\xbc\xac\x1d\x69\xe2\xf2\xb2\xbb\xe2\xa9\x93\x2a\x4a\xac\x04\xf7\x4b\x39\xf0\x12\x55\x24\x88\xec\x1d\xb2\x65\x3b\x0c\x9c\xf4\xc0\x55\xce\xf4\xb3\x8e\x8f\x64\x8c\x26\xf3\x01\xe5\xbf\x86\xee\xb5\x8a\x34\xf8\xca\xfd\xc1\x12\xad\x22\x13\x26\x36\x8e\xaa\xb1\xd0\x77\x74\x39\xae\x6d\xb5\x7f\x8d\x0e\xe0\xa2\xd0\xed\xdb\x75\x13\x35\x26\xb6\x14\xf3\x19\x9a\x8f\x18\x66\x7d\xcb\x88\xa3\x73\xfa\xb0\x58\xfd\x35\x25\x1a\xa9\x62\x6e\xb5\x18\xfc\xec\xd8\xee\xaf\x56\xe9\x51\xc8\x53\xc5\x20\x91\x98\xe2\x94\x15\x05\x68\x4c\xfd\xb9\x23\x09\x0b\x11\x42\x7a\xae\xa1\x9a\xd5\x8e\x97\x2a\xe1\xb1\x71\xa4\xbe\xd6\xb9\x5e\x77\x76\xb1\x4a\x03\xf0\x04\x7f\x8e\xfc\x78\xc6\x89\x57\x69\x62\x2b\x43\x50\x6d\xa4\x35\xbb\xea\xfa\x5c\x89\xe2\x0d\x3a\xab\x74\x7e\x60\x89\x34\xc0\xfc\xcc\x43\xa6\x5e\x77\x0d\xe2\xe1\xbb\x07\x97\x01\x20\xb2\xe6\x70\xc2\x6d\xd3\x17\x34\x5f\x21\xb4\x26\x97\x94\xd2\xb2\x35\xff\x29\xaa\xac\xe8\x3e\xb4\x92\x12\xf3\xbd\xa8\x8b\x61\x97\x45\xd4\x2f\x70\x87\x35\xb7\xb8\x1c\x97\x37\x76\x85\x58\x85\x46\x49\x96\x4f\x53\x51\xfe\x02\x52\x23\xb7\xe1\xfe\xbd\xdd\x5a\xb0\xe6\xca\x6e\xc4\xdd\x18\x07\xa7\x42\x5b\x20\x6a\xe1\xd1\xb4\xd6\x6d\xe1\x30\x85\x75\xd7\x48\x5a\x9f\xc8\xf2\x4a\x7d\x10\xa5\x55\xa0\x03\xd4\xf0\x68\x3c\x67\x18\x5a\xca\xa7\x66\x40\xe7\x74\x95\x2f\xbb\x66\xb7\x93\xca\xc4\xf6\xa1\x0b\x78\x5f\xb6\xcb\x9a\x5e\x65\x4d\xf6\xdf\xa9\xef\xad\x8c\xb1\x8b\xab\x65\x09\xfd\x37\xa8\x66\x98\xff\xd0\x24\xd4\xdc\x51\xfa\xf7\x1c\x82\xa3\xd1\xa9\x49\x9a\xe2\xf0\xd8\xac\x1e\x07\x54\x5a\x52\x13\xc1\x11\x9c\xaa\xf2\x4c\xbd\x2e\xcf\x4d\xd3\x51\x5c\x68\x22\x04\x96\x6a\x1d\x4b\x9d\x99\xcb\x30\x0b\xf6\x41\x6c\xc7\x06\x2a\x1d\xf3\xbb\xd4\x44\xeb\x30\xf6\x05\x2d\xea\x75\x20\x31\x2c\x35\x31\x96\x4d\xd0\x49\x45\x4c\xd1\xac\x3a\x20\x12\xf7\xa6\xd6\x4e\x78\x7d\xd4\x1f\x78\xd9\x3a\x60\x31\x58\xae\x86\x57\xa8\x6e\x16\x8f\xf7\xa0\x33\x51\x64\xff\xed\x6f\xc4\xa2\x14\x5d\xab\x83\x5f\x21\x36\x05\xce\x8b\x2e\x1a\xa9\x43\x21\x70\xe5\x3b\x34\x2f\x59\xa5\x31\xd4\xd8\x4f\x3e\x1d\xc5\x11\xa6\x72\x05\x82\x4e\xf6\xd5\xb9\x6e\x76\xab\xf1\xd7\xd1\x91\xb0\xf5\x5c\xc5\x84\x5e\x5d\xea\x48\x51\xf2\x01\x93\xe5\x60\x0d\xd4\x9c\x5b\x2f\xb3\x81\xba\x19\xa0\x17\x74\x1c\x26\x48\x54\xe9\x14\x3c\xbb\x9f\x23\x6e\x21\x16\x5a\x3b\x2c\x04\x86\x74\x66\x27\xa3\x8e\xd3\x50\x5b\xa2\xe4\xfc\x0d\xbc\x62\xde\xb4\x88\xe3\xba\x20\x43\xc7\x69\x8c\x43\x6e\x2f\xea\xd7\x0f\x20\x99\x3a\x16\x11\x5a\x4a\x1b\xe3\xdf\xce\xb2\x53\xcd\x53\xcb\x0c\x97\x57\x9d\xc4\x80\x29\xce\x17\x51\xe9\x95\x18\x46\x8e\x75\x92\x6a\x5b\x1e\xb7\xf8\xc3\xff\xa4\xa2\x00\x33\x6a\x3a\xab\x91\x0a\xf9\xa1\xac\x9a\x97\x6d\x69\xe1\xf3\xbd\x59\xa5\x95\x10\x1e\x6b\xbb\x2e\xf4\xa9\xcc\x8a\x66\x59\x21\x4f\xcd\xf4\x8d\x47\x7d\xa4\x23\x82\xd9\xcd\x4a\x34\xf0\x68\xfe\x7c\xf0\x10\x1b\x0d\x24\xc4\xc5\xb1\x5b\x31\xca\x41\x52\xbd\xdd\xcf\x10\x88\x55\x16\x08\x0a\xed\x9c\xe5\x0f\xfc\x84\xbf\x8f\x0b\x12\x06\xcb\x80\x86\x48\x62\xb4\xa8\x41\x3d\x8b\x71\xa6\x4d\x83\x94\x23\xa2\xc3\x81\xb5\x32\xfe\x1c\x26\x88\x62\x87\x7b\xc5\x98\x16\x3c\x8b\x7a\xc6\x2e\xd1\x86\x2a\xe2\x6a\x4f\x97\xa2\x06\xab\x62\x38\x3f\xc1\x8c\x30\xb8\xa9\x55\x08\xf7\xf2\xc4\xf4\xfe\xa0\x49\x68\xec\xf8\x19\x33\xb5\xa8\x64\x36\x00\x40\xfa\xe8\x0a\x90\x44\x0b\xf9\x29\xc0\x77\x3c\xaa\x20\xa0\x01\x66\x51\xdc\x4e\x80\x08\x0a\xcf\xe9\x7f\x73\xe5\x58\x40\xa0\x42\x0c\x07\x6b\x78\xa3\x36\xfe\x4e\xb7\x9d\x59\x0a\x01\xa4\x68\x66\x19\xe4\xb8\xdc\x97\xb3\x5b\x89\x63\x62\x93\x40\x63\x2a\x7a\xe6\xf5\xa7\xb2\x2b\xc0\x03\x2a\x39\xf6\xd9\xbf\xcb\xac\x40\x95\xee\x59\xfa\x0f\x60\x81\xd5\xc1\x72\x71\x6d\xa8\x32\x93\x59\xdd\x36\x1b\xf5\x83\x59\xdd\x44\x09\x4c\x30\xe3\x82\xce\x68\xe2\x0c\x39\xaf\x7d\x13\x69\xc5\xd2\x4b\x63\xda\xa3\x77\x3d\x48\x19\x42\xce\x62\x5f\xab\x6f\x4c\x96\x67\x57\x5c\x2e\x10\x42\x67\x7d\x75\xe2\xa9\x88\x89\x99\xc6\x8c\xc6\xef\x13\x51\x45\x55\x57\xfd\xd6\x9c\xeb\xe5\xb9\x2a\x30\x35\x3f\x7c\xfa\x28\xe4\x58\xf0\x3f\x4c\x68\x8d\x4a\x29\x66\x53\x58\x10\x45\xa1\x0e\x7d\x0d\x74\xdd\x6c\xa1\xba\x99\xd0\x3f\x4b\x88\xd2\x30\xf4\xc2\x62\x8e\x69\x77\xfc\x84\x3c\x04\xed\x50\xa8\x56\xe9\xf7\x73\xce\x10\xe0\x4a\xe9\xb4\x1b\x10\x5d\xea\xf4\x43\x0b\xa3\x7f\xcb\x38\xb4\xcb\x6e\xeb\xbd\x58\x87\x71\xb8\xa2\x41\x1c\x09\x2b\x4f\xfd\x22\x2a\xb0\x25\x59\xee\x48\xc2\xa5\x70\x29\xdd\x8d\x2a\x17\xcf\xc3\x04\xf7\xe0\xfa\x89\xd1\x5c\xf8\xee\x28\x1a\xe8\x6a\x13\xdc\xf1\x94\x86\xb8\x15\xbd\x88\x1a\x2b\xd6\x26\x07\x13\xab\x27\x70\xae\x8a\xbb\xb2\x41\x8d\xd5\x91\x05\x00\x29\x93\x69\x4f\x5a\x84\xf6\x43\x35\x15\xca\x9f\x0b\x00\x43\x1a\x52\xc4\x30\xfb\xd0\x8d\x63\x54\xf6\x47\x95\x91\xbd\x66\xd9\x0d\x96\xa9\x4f\x30\x81\x20\x52\x4b\x76\x8a\x55\x66\x7b\x04\x42\xff\xe3\x0c\x83\x45\x67\xd2\x5c\x53\x07\x62\xcc\x81\xcd\x6f\x6b\x20\x89\x55\x95\x7d\x39\x66\x1f\x52\x7b\x81\xa4\x5c\xb9\x01\x36\x33\xa1\x64\xa8\x65\xff\x59\x66\x5c\x25\xd0\x8c\xa9\xa1\x1b\x79\xcd\x1c\x2c\x41\xa7\x0c\x53\x27\xf7\x8b\x3f\x0e\xab\xc7\xbb\xbb\xf5\x6a\xff\xf8\xb4\xf3\xbd\x03\x84\x07\xfd\x7a\xe0\x63\x6f\x57\x7c\x0c\x00\x49\x4c\x79\x4f\x4a\x8e\x9f\x7f\x10\x0c\x04\x10\x3c\xb5\xac\xa1\x55\x75\x3e\x35\xeb\x3c\xeb\xac\x74\x00\x6d\x61\x1f\xb9\xad\x58\x1e\xa3\x79\xc1\x80\xf6\x8e\xe3\x16\xaa\xba\x2c\xb6\xa2\x82\x62\x36\x22\x69\x08\xb3\x48\xc2\xaf\x90\xe7\x25\x06\xd3\x26\x5e\xbe\x09\x02\x81\xc9\x27\x2c\x43\x99\x23\xdc\x9d\x9f\x75\x26\xa0\x0a\xf3\x02\x4f\xa2\x81\xa0\xbb\x18\xd3\x7d\x60\xdf\x56\x4a\x8e\x06\x82\x09\x62\x13\x7b\xf0\xb9\x25\x94\xb2\x65\x52\x97\x19\xb2\x6b\x69\x28\x0b\x90\xb8\xf8\x70\x68\x3a\xd2\xae\xcd\x6a\xb1\x6d\xe7\x78\x07\xc9\x9c\x46\x38\x46\x56\x89\xa1\x8e\x01\x4d\x61\x0e\xde\x0a\xe1\x75\x94\xa6\x7e\x26\x19\x2a\x43\xc4\x68\x7a\x88\x6b\x56\xcb\xbe\x0c\xd9\x50\x25\x10\x4f\xf5\xef\x73\xdd\xba\xa5\xad\x6d\x66\xb3\x06\xa3\x87\x65\xc4\x60\x4c\x13\x7e\x81\x1a\x58\x64\x1e\x44\xe2\x5b\xd1\x14\x51\x1e\xa6\xfd\x06\xfe\x1a\x81\xcd\x9f\x05\xdd\xa5\x74\x84\xba\xa8\x47\xcb\xba\xf9\x52\x01\x6c\x73\xd1\x7d\xb2\x30\x8e\x69\x17\x83\xed\xd3\x21\xfe\x68\xc2\xd1\x86\x59\x8a\xd6\xc3\x9e\xb1\x2a\x4c\x28\x54\x64\xa3\x8f\x17\xb6\x1b\x84\xd9\x4d\xc4\x04\x16\x92\x9c\x8b\x1f\x65\x03\x3d\x83\x9a\x89\xa4\x95\x60\x7f\x86\xc6\x02\xc4\x97\x97\xd5\x4b\x79\x65\x87\x98\xc8\x58\xae\x88\x7d\x85\x83\x7d\x50\xa9\x68\xb8\x06\x2b\x73\xdd\x43\x4c\xbc\x41\x61\x92\x40\x76\x99\xe1\x85\x43\xe1\xf8\xf3\x12\xc3\x42\x1b\xbb\xb3\x20\x30\xd0\x96\x41\x0d\xaa\xdd\x0b\x16\xc4\xbb\x76\x69\x2a\xd1\x2d\xe8\x60\x1f\xcb\xcb\x72\xbf\x9a\x5f\x6b\x4c\x2a\x13\x82\xce\xc8\xd7\x6e\x4d\x37\x82\x68\xe8\xd1\xa5\x7d\x79\x18\x9d\xf4\x9e\x08\x43\xc4\x7b\x3a\xa5\x82\x0a\x60\x14\x67\x1a\x37\x96\x8c\x22\xa6\xf5\xa0\xa1\x01\xd5\x25\x8b\xbf\x54\xe5\xf9\x34\xbf\x56\x1a\xc9\x14\x92\xac\x98\xf2\x5c\x39\x29\x81\x75\x6f\xa2\x1a\x25\x28\xe9\x8a\x91\xe7\xbe\xae\x8e\x0d\xfa\x85\x98\x48\x3a\x42\x61\x61\x58\xfe\x74\xad\x2d\xed\x80\x9f\x50\x58\x26\x79\x0d\xb6\x31\xa0\xa4\xf1\x89\x44\x78\x83\x4a\x67\x96\x83\xab\x9a\xf5\x9e\x0d\xe8\x08\xe3\xe0\x37\x65\x6e\xbb\x9f\xfa\x1b\x1a\x99\x20\x2f\x8d\x45\xea\xb6\x2b\x5a\x19\x7c\x2d\xcf\xd7\x0a\x16\xb3\xe6\x8a\x31\x9a\x05\x03\x25\x6b\xb1\x15\xcf\xa2\x7d\xdc\xb2\xbb\xbe\x51\x61\xda\x21\x62\x1e\x0d\xbe\xed\x54\xe1\x56\x11\x92\x32\x64\x01\xbb\x6f\x2d\xbd\x2c\x1f\x84\xd6\x15\x09\x44\xea\xc1\xbd\x56\x13\xdf\xa5\x82\xeb\x61\x49\x96\x22\x34\xd6\xa1\x71\xa2\xe6\xa8\xe3\x99\xe7\x53\x0e\x50\x45\x58\x94\x22\x12\x56\x41\xd5\x74\x96\x62\x3d\x6d\xa4\x13\x69\x17\x14\xfd\x0c\xa3\xd5\x5d\x91\x30\xb6\x54\x4b\xa7\x0a\x9e\x0b\x51\x34\x77\x59\xf1\x9c\x97\xc5\xf3\x4a\x34\x5d\x9b\x28\x48\x30\x93\xe3\x97\x9a\xf3\x2c\x1b\xc3\xe7\xb0\xc0\xb9\x89\xa1\x08\x8f\xd3\x10\x07\xdf\xb9\xd0\x23\xd8\xa4\x22\x5c\x00\xd2\x68\xa1\x49\xb8\x3c\x5f\x70\x2d\x45\x26\xa0\xff\x43\x1d\xe8\x5f\xfd\x3b\xb0\x2a\x15\x89\x89\xcd\x39\x69\xd1\x08\x27\x03\xe8\xca\x80\x50\x2d\x77\x6c\x2b\x24\xff\x0a\xfd\x37\x8f\x63\xe1\x4b\x94\x16\x93\xa4\xa6\x22\x49\x4c\x84\xa3\x43\xcb\x73\x18\xd0\x15\x7e\x6c\x30\x2a\x92\x72\x82\x5c\x64\x47\x57\x5c\x3c\x88\xbe\x2b\x92\x3a\x88\xdc\x68\x52\x4e\x34\x06\x14\x11\x92\x23\x80\x5f\x9e\x2f\x8b\x3c\x9f\x67\x12\x9c\x0d\xc3\x0c\x2e\x61\xe4\x00\x07\x8f\x2b\xf8\xcd\x0c\x6b\xa5\x6b\x2d\x09\xc5\xc4\xd1\xb7\x17\xf1\x3e\xac\x32\x9e\x71\xe2\x15\x91\xad\xef\xf5\xff\xfe\xbf\xff\xb7\xb8\x1d\x55\xb7\x28\x22\x13\xcb\xf8\xe7\xbc\x0d\x4b\x4f\x3e\x71\x96\x14\x91\xa9\x46\x4d\xa5\x6d\x99\x5f\x6e\x06\xca\x4b\x93\xbe\x97\x82\x47\x2e\xc1\x74\x73\x6e\xd4\x8b\xcb\xc2\x63\x65\xea\x64\x3a\x28\xcd\x2c\xbe\x07\xb9\x3b\x7d\xc8\xe7\x13\x76\x65\x45\x14\x44\x88\x91\x43\x1e\x03\x57\xf1\x3e\x8d\x16\xf8\xa6\x46\x5a\xe5\xea\xac\x68\xee\x11\xe6\x84\x8f\xf1\xc9\xc5\xb5\x90\x5a\x7a\x1d\x1c\x8d\x1a\x45\xf3\x45\xab\x8a\x68\x0d\x81\x2f\x0c\xd9\x96\x65\x3e\x1f\x73\x51\x44\x43\x88\x59\xe3\x53\x55\x4a\x8b\x81\xe9\x8a\xc6\x15\x81\x40\x29\x0b\x0a\x7c\x03\x91\x63\xfa\xfd\x3e\x2b\x2c\x55\x55\xfd\x53\x64\xcd\x6d\x59\xad\x72\x10\x15\x4a\x2e\x74\x65\x09\x8a\x40\xa4\xb1\x92\xd0\x8a\xe2\xae\x5e\x60\x50\x34\x37\xbe\x3f\x70\xa1\x95\x27\xd1\x3b\x64\x85\xce\xde\x32\x7d\x16\xf9\xa1\xb6\x42\xe0\xe3\xd6\x86\x13\xa1\xbb\x0a\x74\xcb\xb9\xec\xcb\x3d\x26\x2d\x53\x8a\xfc\x66\xf5\xf9\xd4\x6e\xd8\x0b\xad\x9d\x16\x59\x30\x1d\xa2\x46\x71\xb0\x65\xb0\x7d\x64\xb8\x5b\xb9\x8d\xd2\x7a\x90\xd4\x5a\x3f\x43\x05\x93\x55\x37\x20\x24\xb1\x75\x67\x85\x65\x07\x38\xf4\x42\x18\xe5\xf1\xd3\xd8\xb6\x0a\x48\x1c\x62\xfd\xc0\x5d\x59\x3c\x6f\x73\xd1\x3b\xce\xff\xa2\x3d\xb0\x24\x76\xe5\x20\x1d\x20\x98\xfe\xef\xf4\x32\x3a\x46\x13\x52\xb6\x1b\xf6\xa6\xc0\x2f\xe5\x36\x41\x15\x04\x49\x88\xe1\xc0\x2e\x64\x88\x32\xa6\x67\x44\x69\x0e\xe7\x5f\x10\x98\xd4\x91\x9d\x14\xae\x7b\xfd\x25\x68\x00\xc6\xf2\x94\x1d\xe0\x78\xea\xbe\x73\x40\x79\x8c\x7e\xc4\xe3\xfd\xe6\xc7\x66\xe1\x7f\x65\x44\xa7\xc4\x83\x3e\xbe\x3f\x6d\xba\xdf\x59\x12\x24\xae\x8c\x3e\x2b\x9e\xb1\xf6\x64\x34\x25\x02\x06\x8a\x51\x27\x6d\x18\xdc\x95\xea\x75\x5d\xe8\x3e\x96\xa7\x02\x66\xac\x70\x6a\xcf\xb6\x53\xc3\xe4\x6b\x44\x29\xc3\xf8\x10\x14\x1a\x91\x55\x3f\x01\x5e\xfd\xe9\x91\xa6\x48\x31\x60\xad\x27\xc4\x65\xf4\x4a\x62\xd3\xb0\xf3\xa4\x8b\x79\x44\x8c\xe9\xf3\x4d\x07\xca\xfc\x55\x79\xcc\x91\x43\x65\xf7\xfd\xbe\xfb\x29\x21\xa9\xf3\x50\x7b\xf9\xeb\xbf\xc0\xe9\xeb\x4e\x8f\x99\xb5\x7f\xfe\x14\x55\xbb\x17\x0e\xab\x2d\x55\x10\x87\xa9\xaf\x70\x77\x03\xfa\x5f\xff\x3b\x1b\x1a\x1d\xec\x1d\x41\xcc\x29\x75\xc1\x80\xd6\x68\xc4\xbd\xb5\x42\x70\xf6\x87\xd9\x17\x3f\x07\x82\x58\x5a\x05\xf2\xbe\x5c\xe2\x8b\x68\xe0\x5d\x74\xa3\x20\x21\xc4\x31\x55\x39\x18\xcf\xba\x1f\x39\x49\x64\x29\xb0\x90\xd0\x60\xd9\x39\xfa\x2a\x48\x34\xc3\xc1\x50\xbf\x03\x9c\xa0\x9a\x00\x0f\x55\x90\x26\x04\xc3\xfd\x4f\x65\x3e\x32\x98\x82\x54\x1b\xab\x00\xdb\x88\x57\xb0\xe1\xef\x37\xc4\xb3\x62\x89\xb9\x0d\x74\xcc\x26\x76\x92\xbf\xcf\x6e\x3e\x9f\x04\x2b\x54\x90\x1a\x85\x37\x73\x08\x31\xf7\xab\x88\x15\xef\x40\x26\xe7\xa2\x59\xb4\x0b\x70\xbb\x16\x0e\xed\xae\xbe\x31\x50\xed\x2b\x3b\x7c\x80\x68\xb9\x5a\x3f\x0e\x6a\x61\xb1\x15\xc2\x3d\x7a\xd3\x0d\xa6\x5a\xf9\xbe\x65\x92\x60\x84\x0a\xd3\xde\x9f\x6d\x17\x81\x90\x36\x4e\xf2\xfd\xe9\xce\x3f\x0c\x56\x4b\xf9\x12\xef\x6e\x15\xe8\x0e\xda\xfc\x35\xae\xae\x03\x9d\xf8\x3e\xae\x39\xfc\xd3\xdf\x47\x85\x94\x29\x7f\x51\x53\x22\xcf\xfc\x64\x62\xab\x28\x45\xa7\xf2\x54\x95\xc7\x72\x55\x6a\xd8\x77\x75\x73\x23\x5e\xba\xa0\xbb\xa6\x0a\x90\x00\xae\x6e\x4a\x8b\xe1\xd8\xbd\xfb\x1a\x23\x15\x28\xe0\xf8\x16\xed\xce\x79\x93\x3d\x1f\x27\x4b\x80\xa6\x89\xb0\x05\x33\x1a\xe0\x78\x07\x6f\x8b\x42\xdf\xc2\x64\x87\x08\x74\x6c\xb5\x6a\x97\x65\xf9\x6a\x71\x13\x7a\xd2\x02\x38\x11\x1d\xb0\x1c\xb5\x0d\xa1\x81\xaa\xde\x79\x48\xb6\x0a\x4c\xa0\xa4\x1b\xdd\x3b\xf1\xd6\x0d\x10\x4a\x18\x41\x1b\x79\xb5\xff\xd9\x0c\xc6\x2e\x25\x4c\x63\x98\x69\x5b\xd9\x0a\xfa\x45\x9e\x97\xa3\xd1\x42\x49\x48\x94\x8f\x22\x21\xe5\x1d\x16\x9f\x8d\x1f\x8c\x92\x30\xc1\x15\x3d\xcf\x8e\x59\xb3\x51\xe5\x10\xdf\xa4\x28\x89\x24\xda\x89\xea\x5c\xd9\xd2\xb5\xf5\xa9\x54\x2f\xdd\x51\x6e\x05\x65\x74\x56\x23\x67\xb9\x2f\x84\x1f\xd0\x54\x28\x4a\x92\x58\xa5\x28\xd7\xec\xcb\x08\xa6\xe4\x1c\xa3\x1e\xa7\x44\x77\xc3\x0a\x03\x5f\x2b\x71\x1a\x8e\x6e\x4a\x00\x50\x19\xe4\xd0\x89\x53\x29\x1a\x10\xe2\x45\xeb\xef\x2f\x3b\x28\x1a\x84\xf0\x3d\x1a\x03\xd5\xa6\x6f\x24\x94\xe2\xe8\x6c\x34\x95\xb8\xcf\x0a\x4b\x1e\x3b\xa9\xc5\xf3\x2b\x15\x0d\x64\x8a\x5e\x42\x5e\x0a\xdd\x41\x7e\x27\xcb\x19\x0d\xb4\x24\x96\xa0\x1f\x59\x4f\x27\xee\x11\x0d\x0c\xc1\xe8\xea\x97\xaf\x9b\x6b\x07\xb7\x3d\x2c\xa8\x03\xf1\xae\xef\xbe\x42\x65\xfb\xfe\xaa\x70\x59\x51\xca\x6d\x60\x78\xe5\xf4\x16\x85\xbe\xcb\x0a\x18\x85\xc9\x26\x9d\x48\x55\x8a\xbe\xb7\x2b\x03\xef\x24\x89\x2d\x68\x17\xba\x3e\x61\x54\x7a\xca\xa7\x03\x92\xd3\x69\x5b\x14\x71\x10\x63\x1c\x94\xa2\x2c\x0e\x78\xc7\x71\x52\xea\xd6\xd0\x7d\xcb\x9a\x8b\x4b\x0a\x4f\xdf\x3c\x24\x62\x90\x6c\xb8\xc5\x08\xc0\xfa\x57\x0f\x18\x9f\xb4\x8e\x22\xcc\x60\x64\xb5\xad\x1a\x1b\x6c\xd3\x94\x33\x85\xf5\x50\xb5\x78\xcb\x8a\x67\x24\x26\xec\x46\x27\x0f\x13\x4a\x3c\x4b\x05\xda\x01\x16\x44\xf7\x70\x3e\x3a\x46\xff\xf1\x7d\x78\x6c\x09\xa4\xd0\xd3\x00\xdd\x7e\xb2\x0f\xa3\xeb\x93\x33\xd3\x04\x09\xfc\xfe\xf9\xfd\xe1\x6e\xb1\xe9\xee\x9f\xca\xd4\xf5\x9e\x8f\x9f\xf6\x91\x53\x45\xb9\x32\x68\x37\xb6\xa3\xde\x71\x36\x8e\x8c\x24\x1a\x47\x40\xc3\x7e\xb1\xfb\x14\x6b\xa7\x68\xcc\x35\x56\x92\x23\x7e\xc5\x97\xfe\x5b\x6a\x60\xdf\x22\x91\xf8\x94\xf9\x80\x0c\xcc\x1f\x4a\x8d\x25\x67\x3b\x4b\x47\x4e\xd7\x83\x8f\x5a\x03\x48\x8c\x55\x7c\x67\x37\x01\x9a\x30\x62\x71\xa4\x85\x7e\x28\xfd\x4d\x93\x58\x58\xa1\x40\x0b\xbb\xbf\xc9\xc4\xb1\x2c\x86\xba\xec\x8a\x26\x2e\xea\x06\xbf\x4e\x99\x75\x4d\x36\xde\xf2\xf7\x4d\x84\x14\x58\x93\x63\x1d\x52\x2f\x1a\xe5\x63\x82\xf7\xe5\x88\xbf\x6b\xd0\xc7\x92\xc4\x88\x02\xf4\x1c\x38\xe3\xa8\xb0\xa2\x92\x46\x88\x4b\xdf\x3e\xad\xef\x37\x0f\xeb\xa7\xc3\xe2\xe6\x66\x7d\xf3\xb9\x25\x4d\xdb\xb5\x02\x63\x46\x8e\x38\x6c\x16\xe8\x81\x7b\x4c\xe8\xcf\x70\x8a\x29\xf7\x8b\xdd\x7e\xfd\x74\xf8\xb9\xb8\xbb\x5b\xef\xfd\x33\x28\xc3\x2c\x6f\xf7\xe6\x8b\x85\x42\xfa\x3a\x67\x77\x5c\x47\x11\x72\x5d\x7d\x81\xa6\x07\x91\x75\x3d\xa3\x79\x18\xc6\x5d\x2e\x60\x52\x9c\xe1\xdb\xc4\xc4\x12\xf2\x62\x10\x74\xfe\xa5\xb4\x14\x94\x79\x5b\x47\xdf\x96\xd5\xb6\xcc\xf3\xcd\xcd\xbc\x43\x49\x81\x5a\xcc\xcb\x20\xbc\x76\xb9\xc9\x2a\xe8\x6b\xd3\xa7\x01\x01\x0a\xd4\xca\x87\x39\xff\x66\xef\xe8\x12\x47\x25\xa6\x73\x91\x42\x45\x81\xc7\x18\x1b\x33\xe5\xb9\xd0\x50\xb1\x61\xad\x52\x7b\x54\xa2\x21\xbf\xf8\xcf\x59\x20\x68\xff\xaf\xc6\x66\x7e\x13\x98\xfb\xdc\x70\xa6\x10\x6b\x54\xea\x3a\x55\xd9\xdb\x21\x2b\xee\x45\x56\x20\x87\xcf\xe1\xf0\xb7\x3e\xb6\x33\x68\x6e\x24\xc2\x65\xb2\x7a\xc8\x8b\xf0\xd4\x49\xb0\x8f\x8d\x18\x6a\x68\x28\x0c\x6e\x2f\xe5\xe9\xb6\xbc\x36\xea\xc7\xcf\x62\x62\x6d\x7d\xa6\x42\x7d\x81\x82\x0c\x52\x78\x8a\x11\x4e\x31\x0e\x73\xbc\xc8\x19\x24\xb4\x62\x41\x60\x98\xf5\xca\xe1\x2d\x2b\x27\xaa\x35\x8a\x05\xa1\x48\x7b\x8a\xdd\x2f\x5d\x4d\xc8\xfe\xd7\x3c\xc0\x48\xb1\xd6\x01\x50\x1d\x87\x95\x8f\x64\x8c\x52\xf5\xbe\xa5\x11\x9c\x76\xfa\xaf\xed\xc2\x5f\x0f\xfd\xe6\xb1\x22\xb8\x62\x34\x54\xb8\x1f\xba\x12\xc6\x3c\x07\xd5\x74\x5a\xc8\xfe\x75\x29\x8f\xed\x72\xb3\xdf\xef\x2c\xdc\xdd\x31\x07\xcf\xc6\x04\x18\x4d\x35\xe6\xd9\x34\xe4\x6e\x11\x19\xae\xc0\x8c\xea\xc4\x0b\x58\x3c\x1a\x83\xdf\x77\xe3\x10\x5a\x1f\x5c\x90\x05\x56\x49\xd2\x57\x50\xdf\x95\x62\xb2\xaf\x33\x16\x49\x02\x5e\x8a\x03\x57\xa3\x9e\x63\x84\x12\xdf\x28\x21\x89\x2b\x2d\x12\xd6\x72\x73\xd2\x4f\x23\x41\x82\xf9\xf1\xc0\x58\x62\x09\xdb\x9d\x52\x1f\x46\xe1\xd1\x51\x77\xfb\xe3\x79\x42\xde\xae\x18\xd3\xa1\xa7\x7f\xbe\x13\x15\x5a\x55\x37\x90\x4f\x72\xda\x8a\x85\x11\x63\x8e\x50\x63\x37\x2d\x55\xf7\x4d\x62\x85\xf0\x98\x03\xf9\xb5\x87\xba\x19\x7d\x9c\x28\x09\x13\x77\x17\x74\x6c\x03\x32\xee\xee\x48\x24\xa8\xde\xe8\xcc\x92\xad\xfd\xd3\xf6\x4e\x6f\xbd\xd6\xdd\xc5\x94\x55\x3f\xaa\x5b\xf7\xfb\x5c\xe8\xaf\xe5\xb1\x0b\x44\xb0\x58\x24\x96\x3f\xb0\xed\xad\x70\x58\x64\xa1\x58\x2c\x79\x68\xb5\xa6\x8f\xc7\xcc\xe2\xde\x46\x93\x8f\x25\xdc\x12\xc1\x60\xf5\xa3\x1a\xe9\xe3\x29\x96\xa4\x0a\x47\x0c\x54\x8a\x92\xcd\xf1\x94\xfb\xcb\xa6\x81\x4a\xa3\xbe\x18\x0c\x13\x1a\x74\x60\xaa\x30\x91\x28\x66\x35\x0f\xd4\xa8\x57\x84\x26\x48\x47\x69\xca\x4a\x81\x15\x44\x98\x2a\x4e\x28\x26\x43\xc9\x5c\x28\x11\xb9\xac\xf7\x95\xc8\x9a\xe9\x64\x95\x71\xea\x1e\x01\xb1\x55\xa3\x75\x40\x6a\x69\xa5\xf9\xd1\x0e\xe9\xec\x91\xf1\xd0\x94\x10\x62\xe9\xb1\xb6\x60\x2f\x58\x65\xcd\x05\x81\x2b\x9f\x8f\x37\x45\xa9\x44\xa1\xa7\x5c\x77\x42\x52\x8a\xa9\x24\xc1\x2c\x75\x9f\x03\x7d\x2c\xfc\x8e\xdd\xb5\x49\x15\xed\x98\x24\x3b\xf0\x9a\x62\x4a\x29\x4b\x66\x6b\xb5\xfd\x7e\x39\xe0\xa8\x3f\x0a\x56\x0e\x23\x2b\xea\x76\x00\xba\x5f\x75\xc0\x30\x31\xd9\x64\xc5\x4b\x53\x0e\xe0\xbf\xe3\x87\xd5\xcc\x92\x8e\x0b\x0c\x49\xdb\x4c\xd5\xd4\x1f\x63\x3a\x15\xe8\x23\x1f\xa4\x6a\xd4\xef\x4a\x34\x27\x4b\x80\x06\x19\x85\x5e\xae\xd2\xe3\xe6\x40\x4f\xcd\x31\x06\x01\xc7\xe5\x4f\x35\xe6\xd0\x45\xe7\x0f\x42\xeb\x83\x70\x62\x52\xa0\x0f\x35\x26\x18\x27\x4f\x07\xd4\xee\xf9\xf7\x9b\x87\xcd\xfd\xf7\xfb\xc3\xf2\xfb\x3f\x0f\x8b\xfb\xc7\xef\x1e\xfe\xa5\x18\x70\x81\x66\xf1\x3f\xf6\x7f\x74\x3f\x19\x8d\x8e\x56\x57\x51\xe2\x08\xbd\xa6\x83\xc8\x84\xca\x92\x16\x89\x5f\xbb\x53\xef\x44\x31\x63\x18\x8e\x8d\xcd\xd3\x7a\x35\x1c\xbf\x21\x21\x9c\xeb\x2e\x68\xb3\xbc\xdc\xc1\xb3\xc8\xf7\xa3\xe7\x9e\x1f\x37\x21\xa1\x56\xc0\x63\x71\x3f\x8e\xc2\x87\x81\x4a\x70\x4a\xac\x9b\x17\xdc\xb3\x86\x46\x82\x6b\x42\x53\xa6\xed\x42\xdb\xba\x04\x87\xe3\xe5\x00\x3d\x4c\x53\x85\xd4\xa4\x91\x67\x52\xf4\x65\x1d\x73\xe8\x56\xd7\x9c\xc9\x34\xd0\x1d\x5a\xe8\x19\xe8\x7a\xca\x94\xa4\xc2\x30\xe4\x2c\xee\xf9\x6f\xaf\x35\xde\x54\x18\x85\xda\x97\x04\x9d\xfa\x67\x89\x24\x8b\x59\x47\xbc\x30\xa3\xf7\xee\xda\x71\x63\x0b\x9d\x1a\xa8\x1b\x2b\x99\xb9\x12\x1e\x33\xae\xc2\x98\x31\x2c\x8f\xcd\x6a\x44\xe3\xef\x2b\xd1\xf3\x94\xbb\x26\x49\x14\x63\x09\xe6\xc1\xe5\xf7\x3f\xc2\xf3\xf9\xe6\x29\x45\x49\xca\xaf\xe2\x74\xba\x58\x29\xb8\xd1\x57\x48\x5c\x0e\xb5\x7e\x11\x27\xa8\x5f\x32\xd3\xf1\x77\x7e\x96\x5b\x09\x53\x22\x3c\x1d\xfc\x97\xbc\x94\x13\x9d\x46\x15\xa6\x3c\xc0\xf0\xe6\xc1\x2d\xf3\xae\x04\xff\x83\x4e\x49\xb5\xc6\x6a\x73\xbf\xa1\x22\xd9\xdd\x47\x94\x52\x2a\x4c\xc1\xc2\x35\xd0\xd5\xff\x06\x52\x48\xbf\x61\x84\xa9\x31\xe8\x46\xb6\xce\xd1\xaa\xcc\x50\x6e\x69\x4e\xb5\xf8\x37\xf6\xdf\x07\x63\x59\xd0\x14\x31\x05\xdb\xc7\xed\xea\xeb\x62\xf3\xb0\x5a\xec\xbe\xfa\x3b\x8b\x50\x06\xbd\x34\xad\xf5\xaa\xb2\x23\x60\x18\x64\xfe\x35\x24\xb1\x5d\x0f\xbf\x1a\xcb\x48\xbf\x2c\xc7\xa1\xc6\xa0\x6b\xc9\x08\xa6\x76\xac\x5f\xae\x47\x9c\x04\x2a\x94\xa1\xe5\x61\x6e\xe7\x48\x56\x3c\x8f\x2c\xe7\xd6\x27\xa1\x72\x18\x00\x82\x85\x52\xe7\x63\xbb\x38\x7c\xa0\xc7\xa4\x42\x15\x05\xca\xe3\x82\xbb\x74\xbb\x0a\xb5\x94\xc8\x35\x8f\x6c\x09\x3f\x01\x5e\x1f\x8b\xee\x18\xc4\x3a\x75\x35\xa2\xeb\xdd\x6a\x79\x03\x6f\x96\xff\x3b\x7b\x9e\x4c\x69\x50\x31\x26\x05\x7e\x78\xa6\x38\x15\x1a\xa6\x02\x6b\x36\xd7\x67\x97\x0d\x9b\xb3\xf1\x7d\xeb\x48\xf8\x22\x1c\xd4\x3d\x84\x11\x42\xbe\x3d\x2e\xa1\xa7\xb7\xa9\x44\xd1\x3c\x9a\x51\x55\x85\x6d\x17\x11\x61\x10\xb7\x7a\xc8\x54\x39\x2c\x05\x51\x11\x71\xfc\x46\xcf\xd0\xec\x32\x0d\x35\xa2\xd5\x66\x07\x44\x14\xa4\x14\x03\x76\x96\xbf\x7e\x5d\x2b\x91\x8b\x91\x13\x3d\x6e\x4e\x49\x1a\x86\x5d\x00\xc5\x46\x2e\x91\x5b\xd5\x9b\x27\x41\xd7\x92\x83\x45\x98\x63\x02\x0b\x1c\x0d\xc5\xa8\xb2\x62\x7e\x8c\x46\x8c\x08\x05\x83\xb9\x64\x23\x35\xd3\xa5\x35\x62\xdc\x0a\xb3\xbb\xb4\xfb\x5c\x00\x60\x72\xdd\x34\x92\xb4\x53\xb0\x1b\x85\x11\xff\x3e\xb9\xb4\xb2\x21\x91\x5c\xd4\x96\xad\xf6\xf0\x46\x5a\x0b\xec\xe0\x2e\xe8\xfb\x99\x69\x81\xc8\x81\x25\x3c\x3f\x8b\x6a\xe9\xea\x79\xdc\xc1\x90\xf0\x04\xe9\x61\x7e\x0d\x6a\x09\x54\x14\x2a\x81\x4a\x82\xcd\xd0\x80\x9a\xdc\x3f\x54\x42\x58\xd9\x59\xcb\xab\x37\x8c\x66\x46\x11\x0d\x71\x4b\xb1\xd4\xff\x8e\xd4\xf3\x62\xfd\x82\x61\x95\xf9\x70\xb5\x8b\x22\x1a\x61\xca\xe2\x8a\xc1\xe9\x73\x09\x89\xf9\xc7\x8b\x22\xce\x6c\xdd\x55\xa5\xeb\xc3\x11\x1a\x91\x1f\xd0\x34\xf2\x8f\xc8\x09\x41\xa5\x99\x63\x56\x34\x5b\x51\x35\xc5\x07\x7c\xc8\x2a\xe2\xdc\x20\x7e\xa6\x7e\x29\x4f\xbb\xa6\xac\x3a\xfc\xc5\xa4\x99\xa6\xb8\xab\xb4\x1f\xe1\xae\x6c\x3c\xde\x44\x45\x1c\xa8\x18\x8e\x95\xd1\x6d\xe6\xc5\x2f\xda\x93\x04\x38\x03\xff\xb6\xb5\x66\x9f\x40\xe8\xcb\x15\x80\x51\x45\x71\xc8\xb5\xad\x73\x76\x15\x8e\x6b\x0c\xba\x6e\xf6\x93\x91\x98\x10\x48\x9d\x87\x88\x90\xdf\x2f\x9e\xbf\x74\x22\xbb\xad\xa2\x24\xb4\xd1\x2f\xa7\x14\xfc\x73\x3f\xb9\x63\x12\x5b\xd5\xc8\x17\x51\xdf\x02\x62\x39\xb6\x55\x69\x26\x64\x72\x2a\x4a\xb4\xc5\x23\xb7\x43\xd3\x86\x53\xbb\xd1\x91\x80\xf1\x13\xf4\x67\x56\xbf\x6c\xf4\x2f\xa8\x17\xd3\xf3\xd3\x30\xc1\x46\x39\x98\x66\x5f\xea\x2e\x71\x15\xa5\x31\xc5\x4d\xef\xd8\x2e\x7d\x3b\x27\xd9\x73\x37\xa8\x09\xf6\x96\x7e\x94\xaa\x00\x0d\x75\x44\xdb\x8e\x16\xec\x48\x04\x54\xc9\x8e\x73\x6a\xe4\x3b\x45\x42\x5b\x79\xa2\x1b\x90\xe7\xe7\x39\x3e\x04\x15\xc9\x58\x77\xd0\xb1\xd7\xe9\x9a\x27\x75\x8a\xf8\xa2\x63\x56\xc0\xe1\xdf\xc2\xd7\x80\xb5\x07\xac\xc3\x73\xbb\x7a\xdc\x3c\x90\x94\xa5\x9f\x88\xd1\x4c\x6e\xa8\x38\x63\x56\xf0\xce\xab\x37\xec\xcb\xef\x45\xf6\x9f\x33\xdc\x8b\xd3\xa4\xe7\x74\x90\x04\x1d\x41\x11\x3a\xab\x5d\xcf\x03\x8d\x71\x28\x37\x20\x8e\x76\x39\x1e\x83\x27\x22\xa0\x89\xe6\x1e\x83\xde\x0e\x27\x74\xd2\x9f\xe0\xdf\xa0\x9a\xbb\x41\xa1\xf8\x88\xec\x50\x45\x10\x5a\xc5\xf8\x43\x3b\x9b\x5c\x4c\x11\x31\x06\x1f\x2c\x1e\x10\xc5\x68\x8a\x1c\x2c\x2d\x8e\x97\xc6\xea\x2e\x97\x86\x38\xa8\xe5\x39\x7f\xf5\x81\x9d\x6d\xb9\x98\xe6\xd6\x66\xe5\x1b\x55\x64\x02\x82\x99\x24\x97\xb1\x3e\x34\x99\x7a\xed\xbf\xbc\xa1\xd2\x2b\x03\xdc\x9e\xf3\xbc\x73\x4b\x07\xe7\x2b\x4e\xac\xef\x0c\x37\x5f\xfe\x6c\xca\x9b\x2f\x7f\xae\xaf\x38\x58\x14\x0f\x62\x8e\x4e\xd2\xae\x54\x99\xc8\xb1\xea\x68\xdb\x8d\x52\x1e\x68\x42\xac\xa5\xda\x4e\xa2\xac\xce\x8a\x67\x1f\x8c\x1c\xdd\x8d\xd3\x28\x90\x5e\xe0\xef\x50\x16\xb6\xd4\x61\xfd\x9f\xef\xed\xd4\xf4\x17\xa3\xb1\x15\x46\x71\xba\x19\x8b\x42\x77\x50\x99\xee\x71\x18\x61\xb8\x7a\x2e\xb2\x6a\x55\x75\xdc\xca\x8a\x33\x4d\x88\x83\xe5\x2d\xcf\x55\xe1\x80\x6a\x3b\x1c\x64\xf7\xe2\xf4\x99\xfd\xc9\x43\xc2\xb0\x24\xfb\x4b\x6b\x05\x20\x4d\xd7\xa6\x7e\x28\x9b\x5b\x0b\x10\x19\xec\x18\x3c\x8c\x0d\xbe\x45\xdb\x49\xf9\xbd\xf8\x35\xc2\x39\xf1\x30\xd1\xf8\x3d\xdf\xca\x06\x76\x6f\x27\x12\x0c\x82\xf7\x3c\x34\x29\xd6\x5b\xac\xf2\x73\xfb\x9d\x87\x76\x33\x8f\x54\x44\x6c\x95\xd3\xbf\xcf\x75\x73\xd0\x99\x31\x99\x3a\xe7\x1d\x96\x81\xf3\x38\xc6\xf1\x8a\x29\xca\xe5\xf9\x83\xcd\x92\xf3\x58\x06\xd6\x5c\x29\x1a\x91\xd7\x93\xd8\x35\x8f\x03\x2b\x8d\xad\x6c\x28\xcc\x11\x04\x8c\x2f\x11\x33\xa7\x10\x87\x96\xa7\x85\x63\x4e\x22\xba\x13\x26\x94\xf6\x1c\xcb\xfc\xed\x89\x26\x4f\x13\xc9\x2c\xc5\x63\xc9\xbd\xae\x01\x16\x2a\xde\xc1\x34\xa1\xc0\x63\x15\x05\xbe\x30\xec\xae\x7c\xae\xbb\x87\xd6\x42\x47\x0e\xe7\x53\x35\x77\x67\xf5\x7a\x59\x4d\x79\xc6\x14\x4f\x08\x97\x89\xd7\xa2\x15\xd5\x24\x0c\xc5\x93\xa0\x13\x34\x5b\x89\x42\x8f\xd3\x26\x3c\xe1\xb1\xad\x50\x17\x79\x8e\x30\x80\xa1\xd6\x90\xdf\xaa\x78\x02\x32\x09\x26\x3a\x09\xdd\x53\xa6\x91\xc6\x94\xb0\x73\xc4\x9b\xc9\x82\xc3\x53\x61\x43\xf2\xc7\x5e\xd9\x04\xdd\xc1\x6e\xcd\xe2\x82\xa6\xd4\x6b\xe0\x55\xd5\xa6\x68\x6e\xe9\xa2\xaa\xda\xf9\x71\xcb\x16\x55\xb5\x2c\xcb\xfc\x36\xf8\x9b\x5f\xfa\x7b\x20\xc4\x90\x8a\x56\x71\x11\x07\x58\xca\x3b\x64\x53\x72\x12\x4e\xbe\x85\x48\x5d\x29\xbc\x35\xfc\x07\x20\x58\xc5\x65\x6a\x73\xab\x7d\xd9\xbb\xc7\xa9\x75\x0d\x74\x62\x35\xcc\x4f\x8d\xc8\x3a\x4b\x88\x4b\x19\xa2\x55\xf0\xd6\x59\x1e\x5c\x2a\x1a\xba\xbd\x67\x59\x65\xea\xf5\x06\x1a\x91\x4d\x5c\x3b\x2e\x8d\x95\xc2\x59\xe7\x88\xc8\x5d\x96\xe7\xe7\x97\x6b\x88\xc4\x07\x59\xa4\x79\xa3\x95\x2b\x1e\x03\xf5\xb0\x8e\x4e\x11\xd1\x3f\x96\xa6\x3c\xb0\xc5\x7e\x39\x14\xcd\x4c\x1a\x95\x6b\x0a\x38\x9c\xd5\xe0\xfd\xeb\xf5\xfe\xeb\xb4\x59\xcc\x30\x8a\xf1\xe7\x9f\x7f\xb6\x03\x72\x50\xaa\xd6\x35\x90\x3e\xd1\x82\x7b\xec\x58\xd5\xda\x37\x32\xb6\x60\x46\x9e\x2f\x43\xb4\x6a\xa7\xc9\x3c\x0c\x25\x72\x20\x0c\xe1\x15\xcd\x0b\xbc\xbf\x88\x1c\x9e\x3b\xea\x62\xc5\x21\x4a\xa9\x9b\x62\x8e\x05\xc9\x55\x50\xef\x1a\xe1\xe2\x7e\xae\xf6\x4b\x71\x10\x14\x8d\xda\xaf\x65\x79\x19\x3d\x32\x08\x89\x7b\xc2\xb7\xcd\xea\xdb\x66\xf5\xd8\x73\x4d\xfc\x5f\x53\x1f\xe3\xae\x02\x60\x68\x95\x0d\xdc\xd9\xf9\x3a\x16\xc5\x0d\x55\xae\x8e\xa5\xd0\x9b\xd5\xe3\x67\x18\x92\x98\x84\x04\x3d\xe8\x9b\xec\x39\x6b\x44\xde\x0b\xb0\xb6\x87\x22\x64\x09\x68\xc4\x2b\xac\x27\xf0\x9e\x98\x70\x8e\x51\x24\x03\xb0\xba\x9f\xd8\x7d\x31\x49\xad\x54\x8d\x25\x7d\x5c\xbd\x88\x6a\xa3\x47\x01\xdd\x98\x48\x1d\x52\x47\x98\x7b\x98\x9c\x1d\x70\x20\x3d\x5f\xc2\xc2\xaf\x06\xe3\xa1\x13\x07\x32\x40\xdb\xd3\x8d\x7a\x38\x1f\x67\x25\x62\xff\xf5\xbf\xd3\xa5\x36\x0e\x64\x2c\xdd\x3c\xcb\xf4\x8d\xcb\x51\xf6\x91\x75\xdf\x4f\xa3\x5a\xff\x0f\xcc\x09\x7f\x45\x63\xf9\xd0\x96\xf7\xc3\x91\x10\xd3\xd8\x2e\xc7\x39\x54\xa7\xdf\x86\x33\xc7\x7d\x40\x45\xc2\x5c\xba\xe2\xdb\x45\x42\xe5\xe4\x68\xc7\x2b\x62\x4c\xc1\xd6\x7b\x6c\xee\x6f\xd6\x7f\x8c\xf0\x47\x1f\x25\xf7\xa6\xb7\x31\x04\x77\x2a\x17\x2d\x76\xb5\x0d\x23\x68\x76\xcc\xb4\x44\x70\xae\x93\x0a\x1c\xbd\x61\x18\x31\x2c\xbd\x32\x59\x21\xf2\xc9\xc3\x85\x91\xdd\x74\x0a\xf8\xd5\xa0\xd9\x9f\x77\x97\x0c\xb5\x24\x66\x94\x7b\x9e\xe4\xb3\x62\x2e\x04\xae\x1f\xab\x9f\x2b\x2b\xa4\x84\x6c\x6b\x7d\x11\xb4\x8a\xe3\x80\x79\xb9\xb9\x5d\xd6\x7e\xa9\xa7\x0f\x51\xca\x71\x7b\x43\x69\x17\x88\xd5\x4b\x6b\xe2\x15\x5b\x51\xbd\x5e\x6f\x81\x71\x1c\xd9\xb9\x2b\x6c\x74\x6c\x18\xcb\x8f\x63\x69\x55\x49\xda\xcd\x75\xfd\xeb\xf4\xbd\xa8\xca\x3c\x0f\xf8\x38\xf1\x38\xbd\x31\x84\x88\x93\x3d\xd8\xb1\xfc\x0d\x2e\xd7\x02\x9f\x2a\x4e\x02\x4b\x93\x85\x71\x77\x0c\x29\xdc\xf8\x9b\x26\x29\x4d\x3d\x11\xdf\xf7\xa2\xc9\xf2\xee\x80\x01\x12\xfb\x7c\x16\x16\x12\x57\xe3\x19\x96\xf2\xd0\x57\x70\x3e\x16\x58\x20\xea\x49\xc5\x7c\x83\x34\xc2\xa5\xd5\x86\xe4\x3b\x0d\x5b\x7f\x58\x30\x2b\x4d\xb6\x29\x6e\x00\x4e\xa3\xaf\x2e\x98\x40\xb7\xca\xe6\x72\xfc\xaf\x92\x59\x54\xa8\x15\x19\xff\x34\xbe\x18\x4b\x9e\x20\x66\x6e\x7b\x2e\x5e\x11\x11\x04\xd7\x51\x94\xf1\x97\x91\x3c\xc1\x30\x95\x41\xb0\x8c\xdb\xfe\x27\xfd\xa8\x68\x84\x41\x74\xbb\x44\x36\x33\x04\x2d\x33\x96\x6b\xac\x54\x42\xba\xe5\x40\x34\x80\x80\x4e\xb7\xea\xfc\x17\x07\xe7\xe1\x8a\x0c\xf9\x13\x77\x3c\xd6\xdc\x60\xc7\x9f\xce\x32\xcf\x14\x82\x42\x9e\xe0\xf9\x9c\x8b\x0a\x1d\x2c\xdf\x5d\x40\x98\x0a\xfc\x07\xcc\xc5\x25\x2b\x9e\xbf\xf5\xe1\x96\x18\x58\xe0\x95\xf6\x56\xe7\x26\xeb\xb8\xa5\xce\x03\xf0\xea\xcc\x5f\x77\xb6\xd1\x0a\xe7\xb5\xc9\x64\x59\x08\xa5\xb2\x87\xb2\xc9\xcc\xc4\xa2\x4b\x48\x9c\xc4\x1d\x57\x75\x1f\x3b\x4c\x82\x00\xc0\xbe\x41\xb3\x83\xdc\xd5\xb5\xfd\x25\xbb\x21\x09\x78\x80\xc2\x78\xdf\x7e\xac\x7e\x4b\x9a\xd2\xb6\xa6\x18\xc0\x7c\xcd\xf2\x7c\x59\x8a\x4a\xff\x6d\x18\x65\x4d\x02\x6d\xa8\xeb\xa2\x2e\x78\xe9\x0e\xd1\x28\x45\x77\x63\xb7\xe8\x09\x10\x54\xc2\x62\x19\xf7\xd4\x7f\x1e\xe3\x78\x28\x8b\xfc\x72\xb8\x81\xb7\xd9\x35\x38\x19\xfc\xdb\xbf\x07\x4b\x43\x2c\x64\xdf\xac\x1e\x9d\x0e\x9c\x3f\x60\x2c\x93\x5e\x85\x10\xaa\x6a\x84\xc4\x4e\x42\xc7\x80\x7d\xd8\xb7\x1e\xda\xa3\x23\x8a\xec\x8e\xc6\x96\xc2\xc7\x97\x87\xfe\x98\xc9\x81\x25\xa1\xb1\x7a\xf2\x35\x78\x65\xc5\xf9\xa5\x3b\x89\x82\x08\x13\x7d\x4e\x4f\xcf\x56\x40\xcd\x62\x9d\xaf\xa8\xa0\x06\xfe\x73\xc2\x89\xcd\x5a\x67\x45\x0d\x95\x45\x3c\x7d\x42\x66\xa4\x92\x98\x73\xc5\x9d\x6d\x61\x83\x39\xb5\xd5\x56\x9b\xbc\x47\xcc\x2d\x84\xb6\x80\xf7\x8d\xde\xbd\x64\x27\x07\x50\xf3\x9d\x11\xcb\x2e\xc9\x7f\xb0\x30\x87\x43\xdd\xb3\x6a\xa9\x24\x49\xc1\x43\x70\x97\x99\x9e\x0c\xdc\x24\xb5\xa1\xe2\x23\x6a\x28\xad\x5c\x6e\x6d\x0a\x2d\x4b\x52\x02\xa1\xea\x25\x11\x2c\x95\xf5\x47\xfb\x6f\xef\x66\x26\x29\x8b\x11\xba\xec\xbd\x94\xd5\x0c\xf2\x60\xd2\x2d\x69\x18\x22\xce\xc6\xa3\x93\x86\xe1\xdb\x91\xeb\x37\x1e\x6d\xff\xe2\xff\x3b\xbd\x90\x49\x75\xd8\x11\x88\xcc\x58\x33\x93\xc8\x55\x22\x48\x6c\x01\x1a\x70\x3c\x95\x95\xc8\xbf\x17\xdd\x92\x9c\x08\x46\x03\x87\x0a\x71\x8b\xbf\x43\x76\x0f\xe3\x33\xbe\xad\x4a\x92\x3e\x5d\xe2\x01\x17\xad\x3d\x31\x42\x5a\x4d\xff\x0e\xf2\x79\x89\x24\xca\xa9\x43\x35\x07\x51\xc9\xac\xa9\x0f\xc7\xac\x38\xa8\xdf\x69\x92\xa8\x44\xf2\x28\x8d\x47\x14\x25\x1d\xb5\x6b\x8d\x53\xff\x1a\xe0\xd4\x75\x80\x94\x0c\xdd\xc2\x77\x8c\xf2\x0d\x2a\x65\xa6\xf7\x70\x95\xfc\x08\xea\xf6\xec\xc8\x93\x11\xd3\x7a\xb9\xa8\xc7\x89\x5a\x37\x3d\xdf\x50\x7b\x44\x04\xe0\xc6\xfd\x7c\x25\xf3\xfc\x9b\x29\x91\x60\xa6\xa8\x75\x33\x96\xf0\x9c\x15\x03\x70\x42\xa2\x74\xc8\x42\xef\x52\xcb\x76\x25\xab\x47\xd1\x90\x44\x53\x2b\x73\x59\xd9\x2d\x7e\xd9\xa8\x19\xfb\x21\xd1\xc2\x8a\xfd\x20\x79\xc7\xa6\xe8\x78\x7c\x55\x02\x4c\x46\x74\xc0\x28\x3f\x12\x5a\x53\x09\x70\x8e\x54\xa4\x5d\x76\x1a\x1b\x59\x48\xd9\x0d\xc8\xcc\x33\xc0\x7d\xbe\xe6\x83\x50\x89\x33\x45\x06\xc3\xde\x52\x1e\x8c\x5b\x1a\x4a\x70\xac\xde\x88\xfa\x25\x53\x33\xe5\x62\x33\x7b\x84\x61\x14\x37\xa9\x17\x5f\xdb\x7b\xb5\xdb\x25\x26\xe5\xe8\x8e\xcb\x81\x0c\xfc\xe8\xc6\x29\x09\x39\xfa\xe4\x17\x10\xd5\xfe\xbd\x74\x8c\x8b\x7f\xf3\x47\x63\x22\x23\x5b\x40\x53\x9f\xf3\x46\x6c\xab\xf2\x4d\x8c\xa7\x47\x4a\x12\x8e\x53\x69\x5d\x64\xcf\x47\xd1\x9d\x09\x80\x1c\x0c\x37\x0f\x8b\xa7\xa6\xfc\x52\xe6\xfa\x0f\xf5\xf2\x3c\x08\xfd\xa5\x41\x22\x31\xa2\xff\x8e\x31\x65\x5f\x53\x92\x52\xa2\x51\x1e\x2f\xcf\xfe\x73\x46\xc1\x97\x6d\x59\xe6\xfb\x41\xd2\x21\xa5\x91\x09\xba\xb4\x1a\x06\xd4\x46\x35\x0a\x29\xe5\x1c\x88\x1b\x90\x3b\x91\x8b\x6a\xe2\x20\xa5\x2c\xb4\x35\x88\x65\xbb\x7d\xdf\x96\xd5\x8d\xb8\x58\x0e\x01\x3f\x73\x52\xc6\x01\x67\x9d\x4d\x75\xf6\x7d\x37\x8b\xaa\x0c\xfc\x49\xae\xbc\x14\x0f\xbe\xc0\xaf\xba\x99\x2c\xbb\x69\x18\x84\x94\x79\xe9\x6a\x5f\x57\x8d\xca\x38\xd5\x2c\x61\xa0\x4a\xa3\x54\x20\xd9\x23\x16\x92\xed\x31\x06\xeb\xdd\x88\x94\x13\x89\x30\xca\x61\xd1\xd5\x0e\x71\x0e\x5b\x71\xa9\x07\xb0\xff\xf9\x52\x54\x7f\x95\x80\x12\x37\x11\xbe\x66\xcf\x2f\xb5\x2a\x3b\x08\x4b\xca\x45\x2c\x86\xd2\xa9\xc8\xe8\xdb\x5e\xd8\x1f\xd7\x24\x74\x5b\x72\x31\xd1\xc4\x56\x69\x1c\x58\x02\x66\x6b\xc6\x81\x40\xe0\xd4\xb5\x68\x92\x4a\x93\xd0\x84\xc2\x79\xbc\xb6\x9f\x6f\xcb\x6a\x7d\x9e\x92\x32\xcf\xcf\xb1\x34\x65\x21\xc6\x78\x0e\x27\x71\x31\xfd\xa3\x89\x50\x0a\x4f\x22\x0b\x75\xf3\x88\xe2\x1a\x7f\x1b\xbe\xb8\x88\x74\xe4\x56\xbd\xc5\x59\x67\xf6\x9f\xe9\x4e\x99\x0a\x1d\x06\x9d\x0c\x1e\xca\xfd\xea\x61\x22\x25\x15\x86\x05\x6e\x27\xdd\x9d\xca\xa2\x2e\x3b\xba\xfb\xd1\x65\x54\x48\xb0\xf2\xfd\xfd\x25\x6b\xe0\xc5\x73\x0a\xa8\x54\xa5\xb1\xaf\xf7\xc6\xfc\x63\xbd\x85\xaa\x4f\x9d\xfa\x90\x4a\xaa\x59\x8c\xe6\x9b\x89\xfc\x89\x3a\x65\x32\xe9\x65\xa9\x2d\x65\xed\x2c\x02\x32\x05\x20\xe1\x10\x52\x89\x46\xad\xb5\x2c\xbc\x7d\x96\x9a\x84\x07\xda\xa7\x3b\x90\x9a\xc6\x1f\x30\x56\x1d\xa1\x41\x0d\xe6\xe2\xd9\xd6\x1d\xc1\x17\x28\x9c\x90\x87\x12\x41\x64\xb1\x2d\x42\xeb\x07\x78\x7f\x12\xff\xfd\xad\x47\x3f\x5c\xc6\x44\x90\xa6\x7e\x25\x5e\x96\xe5\x6b\x56\x3c\xaf\x86\xc5\xb9\xae\x15\xa5\x29\x4e\x7a\x8d\xa4\x38\x5b\xa8\x30\xee\xf2\xd4\x7a\x21\xfe\x39\x22\x4a\x10\x76\x7a\x27\xce\x85\x7a\x71\xe9\xc8\xf1\xb6\x21\x22\xc5\x51\x47\x70\x91\xe7\xf7\xad\xcd\xd3\xfd\x9c\xc8\x9e\xd2\xe5\x36\xcb\x8f\x23\x72\x81\xd1\x90\x10\x9c\xf2\xc4\x7a\x9e\x5d\x62\x6b\x7c\x9c\xf1\x38\x1a\xb2\x36\x3c\x1a\xab\xb5\x34\x5a\x9b\x05\x8f\x00\xa3\x07\xff\x73\xff\x3f\x43\x1f\x52\x70\x11\x22\xae\x47\xd4\xed\x0a\x61\x71\xff\x93\x58\xbb\xe0\x92\x52\x17\x90\x5e\x1f\x4f\x79\x79\xb9\x9e\xec\xbe\xa5\x22\x9e\xca\xca\xd7\x6b\x4c\x7a\x96\xeb\x80\xf4\x31\xf9\x79\xde\xce\xae\x69\x24\xd2\x3e\x28\xb2\x3c\x5f\x06\x72\x14\x4a\xc4\x42\x60\x00\xf1\x57\x59\x3d\x81\x3e\xbb\xdd\x38\x99\x42\xaf\x45\x42\x22\x24\x54\x3d\xbd\x57\xb7\x79\x29\x3e\x8e\xc8\x4e\x4e\x4b\x04\xaa\x3a\x28\x51\x2c\xcf\x13\x8f\x4d\x24\x92\x10\x8b\xcc\xb8\x81\xb6\x43\x5a\x93\x6e\xa6\x80\x48\xa4\x91\x4a\x7a\x5b\xe7\xd4\xc0\x81\xfa\x2c\xbf\x48\x79\x6c\x58\xa7\xad\x59\x61\x1e\xf8\x2a\x65\x25\x52\x6e\x15\xad\x1a\x10\x47\xdc\x1b\x1c\x18\x74\x4c\xb6\xac\x84\xe4\x96\x8f\x13\x43\xa6\xad\xe5\xeb\x66\xa7\x93\x98\x1a\xcd\x01\xe5\x08\x15\x6d\x44\xc7\xea\xa1\xf9\x43\x94\x59\x74\x41\x75\xae\xfb\x7b\x8c\x5f\x4a\xb1\xc4\x4a\x60\xe8\x37\x51\x28\xd8\x35\x70\xea\x4e\x37\x09\x62\x30\x75\x39\x26\x55\x57\x42\xc7\x01\xd2\x8b\x3f\x59\x46\x2a\x97\x55\xe9\xc7\xa7\x8e\x55\x08\x5d\xb2\xfb\xf5\x1f\xcd\x65\x5f\xe2\x3a\xb3\xaf\x84\xbe\x62\x60\x10\x40\x52\xf4\x0b\xeb\x2c\x87\x42\x81\xa3\x90\xf2\x07\xa5\xc2\x07\x5c\x3e\xdd\x8e\xc6\x3a\xe8\x04\x05\x6b\x6d\x9d\xc7\xd0\x35\xb0\x0d\x24\x21\x46\x53\xef\x0c\xd9\xd0\xc6\x21\x53\x65\x91\xfd\xc7\xdb\xd1\x27\xa8\x1c\xd4\x6e\xd4\x27\x92\xd0\x08\xe3\xf4\x8e\x87\x5a\x98\x51\x7c\x4e\x12\x19\xe1\xba\xfe\x84\x95\x72\x94\x90\xc5\xed\xfe\x5b\xc0\x77\x70\x6a\x76\xa2\xd0\xb2\xfc\xe5\x5b\xd2\x20\xc0\x24\x64\x27\xae\x79\x2b\x54\xe3\x49\xc6\xe7\x67\x9d\xa4\x9c\x48\x07\x14\x38\xe8\xec\x08\x45\x3d\xa4\xa3\x18\x8f\x6b\x49\xe3\x00\x03\x38\xce\x94\xad\x5a\xef\x17\x81\x90\xf3\xd7\x66\xd4\x58\x2a\x6e\x3b\x44\xbf\x3a\xbe\x70\x7f\x54\x13\x1f\xa8\x77\xfa\x0f\x96\x9d\xde\x0d\xbe\xd6\x46\xd8\x67\x2e\x22\x96\xf8\x73\x40\xa0\x67\x7d\xb7\xb8\x5f\x3e\x1e\xf6\xff\xdc\xae\xfd\xd5\x42\x02\xb8\xea\xf6\xf4\xbf\x03\x52\x7f\x25\xc3\x34\x41\x23\xef\x4f\x38\x8f\x2a\x75\x65\x68\x8c\xaf\x8b\xb4\xc8\xa7\x15\xaa\x9d\xb9\xa3\x51\x9c\xfa\x4a\x3f\xa7\x55\x55\x89\x49\x25\xa3\x8c\xa4\x8a\xc3\x0e\xb6\xdf\x60\xbc\xf1\xaa\x03\x27\x1d\x19\xf9\x95\xcc\xbb\x55\xe5\x84\x47\x1d\x9b\xc4\x64\xe8\xac\x58\xd3\xa4\x9d\x57\x2e\xb8\xbb\x71\xb5\xec\x9f\x72\xeb\xe1\x85\x50\xea\x60\x9f\xa9\xbd\x50\xdb\xb2\x11\x1d\x56\x45\xf2\x90\x63\x79\x4d\x71\x3e\x3e\x9a\x9f\xa8\x9c\xde\x1d\x02\x8a\xa0\xbf\x3b\x10\xba\x35\xf3\x77\x47\x51\x8d\x40\xe9\x32\x21\x54\x5a\x32\x20\xa7\xab\xd2\x93\xc5\xfa\x16\x2c\xf6\x34\x0e\xab\xd2\x15\xa1\x0c\xf3\xc8\x32\x51\x06\x57\x13\x47\xb5\xf9\x49\x92\x03\x9b\xea\x01\xe0\x19\x7d\xa4\xdb\xb2\x1a\x65\xf5\x64\x4a\xac\x2c\x1c\x56\x7e\xbd\x95\x99\x82\x7a\xb4\x47\x4f\x2e\x9a\x86\x51\xea\x68\x35\xdb\xa3\x8f\x66\x68\x77\xc9\xd4\xd5\x96\xb6\xae\xd5\xea\xf1\xa9\x29\xd7\xfb\xd5\xe4\x2b\x09\x66\xd9\xe6\x1f\x51\x7f\x2d\x2b\x0b\x91\xef\x4e\xf9\x34\xeb\x2f\x45\x18\x60\x90\xbf\x6e\x4a\x0f\x70\x9a\x7c\x25\x65\x2c\x2d\x4c\x6b\x27\x14\xcf\x63\xef\x74\x7c\x2d\x1d\xd2\xc4\x95\x12\x60\x71\xde\xf3\xc7\x3a\x17\x4a\x6a\x1e\x62\x36\xd5\x1a\x51\x9b\xc9\x8e\x2a\xb5\xb1\xfe\xb4\x44\xc1\x74\x2f\xff\x3e\x6b\x9c\x49\x88\x6d\xb0\x7e\xf1\x5c\x65\x58\xd0\x31\xe2\xef\xf0\x8d\x64\xa7\xc3\xbe\x2a\xf3\xb2\x5a\xf6\x49\x55\x09\x8a\xa1\x48\xc9\xed\xd3\x77\x0f\x53\x44\x46\x76\xea\x0a\x2e\x10\xb7\x3b\x66\x75\x57\xd2\x80\xf6\x7a\xd7\xcb\x72\x4a\x39\xa3\x5a\xbf\xa2\xbb\x1d\xee\x91\x2c\x1e\xed\x57\x8a\x18\x89\x7c\x35\x0d\xd4\xcd\xad\xc8\x72\x57\x38\xf2\x50\x36\xc3\xf5\x41\x05\x94\xe3\xd2\xb9\x58\xae\x66\x70\x8d\x2a\x60\xd6\x51\xd3\x50\x37\x55\x79\x79\x2a\x9b\x72\xbe\xbe\x4b\x05\x21\x4d\x7b\x89\xdb\x75\xe3\xa9\x4b\x3e\xaf\x00\x54\x41\x44\x02\x1b\x09\xec\x40\xe6\xbf\x14\xc2\x7e\x3e\xce\x11\xaa\x80\xb3\xa8\x97\x79\x5a\x96\x65\x0e\xa2\xb0\x79\xec\xf1\x43\x51\x9a\x18\xc7\x62\x62\xed\x3b\xff\x3b\x97\x71\xe0\xcb\xde\x0f\x28\xfe\x05\x0e\x1c\x59\x4c\x86\x8a\x62\x8a\x49\xdb\x91\x55\x25\x4c\x59\x1d\xbd\x46\x92\x3b\x1e\x46\x76\x2a\xd9\x2c\xc9\x4a\xf4\x50\xe7\xbf\x22\x1e\x1a\x5c\x07\x72\x47\xff\xfa\x9b\x28\xee\x70\x98\xf5\xf9\x88\xa5\xc1\xfe\xf6\x51\x28\xd0\x53\xb6\xb7\xff\x02\xc5\x97\x33\xca\x15\x7f\xd0\x75\x9c\x5a\x62\xc7\x6d\xd9\x94\xc3\x45\x4d\xf1\x30\x44\xf7\x62\x77\xec\x73\x5d\x2a\x0e\x14\xe2\xbf\x56\x8f\xf7\xf7\xdf\x1f\x36\xfb\x7f\x1e\x16\x77\x77\x8f\x3f\x17\x0f\xab\xf5\xe1\x6e\xb3\xdb\x77\xed\x22\x82\xdc\x15\xe7\x42\x95\x56\x91\xb1\xdd\x50\x90\xbf\x7c\x9c\x75\x18\x3f\x4c\x1c\xc5\x88\x20\x7b\x2b\xf3\xf3\x11\xf6\x97\x53\x17\x8d\x56\x71\x9c\x62\x21\xf4\x97\xdd\xa6\xfb\xc9\x68\xa4\x40\xcf\x0a\x63\x1f\x7d\x97\xe5\x6f\x63\x07\x43\x25\x5c\x22\x8b\xf0\x17\x4c\x82\xc3\x65\x96\x49\x0c\x9b\xe1\xf4\x69\xc4\x6b\xeb\x98\x3d\x94\x8d\x8b\xaa\xdc\xb6\x76\xb1\x39\x17\xda\x9e\xed\x9b\x6b\xab\xb9\xea\xb4\x83\xec\x04\x9a\x59\xcc\x94\xa0\x21\x25\x83\x42\x8e\x41\xce\x4f\x89\x38\x46\x70\xd3\x73\x7b\x85\x53\xdf\xf1\x42\x73\xe3\x36\xe2\xf6\xe2\xde\x43\xec\x07\xab\x30\x51\xca\x06\x32\x98\xa7\xb2\xfa\x94\x75\x78\x34\x70\x24\x8d\x04\xf5\xe2\x10\x28\xd6\xa2\xad\x17\xbb\xce\xc5\xa9\xc6\x17\xfe\x91\xa9\xa6\x9c\x22\x66\x94\x0c\x63\x44\x0e\xa2\xb2\xc3\xd6\x13\xe1\xb6\xbf\x5b\x2d\xb7\xd6\xc1\x40\x84\xe5\x03\x32\x82\x9f\xce\x8d\xb8\xd2\x0b\x52\x4a\x72\xc5\x9c\x1d\x31\xc7\x19\xa7\x94\x8c\x6d\x8d\x09\xae\x7f\xb7\x33\x80\x64\xdf\x4e\xe8\x88\x8c\x4a\x83\xfe\x32\x24\xe1\x2f\x6a\xf8\x4e\x6e\xa8\x22\xc0\xa2\xc4\x4c\x95\xbd\xb0\x93\x52\x2a\x09\xf0\x63\xe4\xa2\x6e\x7e\x5a\x12\x42\x0c\xf9\x38\x6c\x87\x6f\x65\x14\x9a\xae\x08\xd7\x42\x0d\x5a\x0c\xda\x66\x65\x31\x0e\x62\x2a\x1d\x28\x5f\xfe\xd1\xda\xac\x65\x75\x71\x20\xd3\xf9\x71\xab\xa5\x95\xdb\x18\x69\x3d\x7c\x5e\x0b\xab\x4c\x40\x11\xb3\x88\xec\x64\xbe\x82\xc1\x1f\x8b\x2c\x07\xe4\xfe\x71\xb7\x29\xea\x26\x6b\x2c\xd6\x65\x53\xb4\xcf\x88\xcc\x25\x23\xa7\x56\x99\x48\x25\xc6\x23\x5a\x72\x78\x16\xba\xbc\x81\x75\xad\xce\x90\x0b\x24\x00\xbe\x5c\x61\x17\xe7\x7b\xd7\x68\x4e\xe4\xe0\x45\xdc\x0d\x74\x40\x52\x1c\x75\x42\xeb\x45\x57\xd2\x84\xf3\x6d\xb2\x2b\xb7\x46\x22\xef\x69\xe2\x91\x8a\x7c\x40\x48\xef\x1b\x49\x6e\x0b\xca\x6a\x17\xf9\xc1\x24\xf1\xec\x4e\xa4\x69\xa0\x31\x10\x8d\xcb\x96\xf5\x8d\xd6\x6f\x73\x7c\x2d\xb3\x6f\xa4\x29\x27\x60\xa3\x1f\x3f\xcb\xea\x75\x51\xe8\xad\xb8\xac\x97\x7e\x85\xd4\x54\x1b\x8c\x81\x0d\xa2\xd5\xed\x06\xf7\x33\x6b\x5e\xca\x73\x33\x53\x19\xa4\x59\x64\x2d\x98\x9b\x7f\x0c\xb2\x84\x9a\x71\x86\x05\x8f\x87\xd6\x6e\x77\x45\xed\x1f\xbc\x50\x14\x10\x80\x8e\xcc\xc0\x0e\xd0\xfa\xd3\x04\x99\x8e\x74\x84\x6b\xd1\x4e\x28\x51\x1d\x96\xb9\x50\xaf\xd7\xd9\x16\x1d\x19\xab\xcf\x21\xb4\x5e\x95\xe7\xaa\x9e\xd4\x04\xea\x38\x11\x54\x7a\x0a\xdc\xdd\x09\x54\x26\x72\xac\xd5\xbd\x17\xa7\xd3\x9c\x04\xd6\xf8\x21\x12\x62\x29\xa1\xea\xd6\x9e\xec\xf8\x2e\x95\x4e\x53\xe9\x15\xdc\xee\xc5\xaf\x1b\x38\x89\xaa\x39\x23\xfd\xf0\xa4\xe7\x52\x41\x90\xb5\x10\xa3\x68\x07\x7a\x38\x8a\x5f\xaa\xe3\x67\xd1\x82\x58\x67\xb1\x46\x5c\xf0\xa3\x19\x8f\x18\x41\xac\xd9\xd4\x39\x28\xce\xa4\x48\xfc\x71\x1e\x59\xe9\x06\xad\xbf\x3b\x29\xf2\x0f\x98\xbe\xdd\x09\x92\x04\xb8\x3f\x8b\xe6\x97\x85\x87\xb7\xcd\x87\xbe\x80\x96\x4c\xa0\xb5\xed\x35\x48\x87\x42\xc7\x4a\xcb\x34\xe6\x74\xe4\x2d\x5a\x43\x70\x86\x54\xb3\x6d\x9c\x50\xd9\xc5\xb5\xa0\x2a\x6f\xe0\xf1\xfc\x96\xe9\xb2\xca\x44\xdd\x5d\x51\x87\x68\x8e\x1e\xbd\x7a\xd6\xf2\x7c\xf9\xbc\xf6\xc0\x9d\xa8\x99\xd5\xce\xfc\x69\xa9\x0d\x1d\xd2\x7c\xfe\xb5\x75\x4a\xf1\xb1\x4f\x70\x2f\x7e\x6d\xa1\xb2\x7c\xbc\xfe\x11\x20\xe2\x96\x4d\x1d\x0a\x8d\x51\xc2\x7d\x79\x03\xbf\x26\x9f\xd1\x70\x82\xe1\x81\xfd\xd9\xc1\x5d\xba\xdf\xe3\x84\x0d\xd6\x8e\x1b\xa4\x27\xef\x32\x22\x40\x84\xe5\xb7\x7a\x86\x41\xa9\x6e\xe2\x0f\xaa\x10\x6b\xff\xb1\x2f\xb7\x9d\x40\xd7\xef\x2a\xb7\x06\xde\x11\x04\x94\x21\x2b\xdc\x4b\xf6\xfc\xb2\xcc\x74\x9f\xd6\x80\x80\x05\xa1\x5b\x1e\xed\xe0\xb0\x1c\xb2\xa3\xd7\x82\x20\x36\x38\x82\x5c\xee\xdb\x16\x1c\xfd\x65\x0a\x82\x4f\x17\x21\x08\x4c\x88\x84\x56\xde\xe8\xb7\xa5\xec\x77\xed\xdc\x6b\x9e\xe0\x0d\x77\xa0\x87\xb2\xc1\x9f\x07\x78\x19\xa0\x21\xc5\x42\xe3\x85\xd6\xbb\x17\x51\x81\x76\x59\x9b\x2b\xec\xc8\xa7\x50\x32\xa0\x31\xf7\xcc\xee\xb7\x96\x83\xde\x57\xff\xf5\x09\x6a\x60\x54\xa1\x65\xb7\xf8\x39\x94\x3e\x54\xc0\xc2\x04\x7f\x57\xed\xfa\xbb\x1b\xa3\x3a\x80\xa5\x82\xd9\xe2\xf6\x76\xa9\x87\xfd\xbc\x74\x90\x82\x28\x14\x88\xe4\xf5\x1d\x60\x43\xe1\xed\x2a\x6b\xa9\xa0\xed\xbf\x3b\x71\x84\x4d\x03\xc7\x8e\xca\x07\x22\x23\xd0\xc9\xfe\x0a\x17\x23\x8a\xd1\x73\x71\x9d\xa4\x03\x8a\xfe\xbd\xf8\x75\x45\xcc\xaf\x20\x26\x42\x38\x23\xee\xa6\x54\xe7\x23\x92\xd4\xfd\xe7\xdc\xb3\x30\x07\x7c\xd2\x57\x71\xc0\x91\xcf\xca\xce\x22\xbb\x34\x4c\x5c\x0f\x88\xb5\x7d\x6b\x1f\x19\xde\x5d\x8e\xb2\xcc\xaf\x62\x93\x90\x04\x29\x50\x07\xca\x55\x2f\xde\xe2\x84\x34\x4c\x30\xc8\x80\xe7\x1e\x58\xf7\x73\x0c\xd2\x89\xc8\xdd\x8b\x22\x33\x50\x37\xe5\xb0\x2a\xcd\x37\xd3\xd4\x93\x09\x9d\x4f\x48\x27\x3a\x69\x20\x78\x8a\x9a\xa2\xcf\xa2\xbe\xef\x66\x27\xc8\xd8\xce\xce\x4a\x14\xaf\x6e\xcf\x39\x74\xc7\xa4\x55\xc5\xac\xa1\x79\x3c\x7d\x11\xbf\x09\x16\x81\x94\x09\xe6\xe2\x6c\x80\x17\x6d\x91\x12\x13\x71\xe3\x5e\x92\xc6\xa0\xe7\xe9\x70\x6f\xa8\x2e\xe6\x0e\x29\x1a\xa8\x21\xb7\xc2\x04\xad\x09\x2a\x8c\x31\x2f\xa2\xca\xa2\x00\xd5\xec\xfb\x5a\x74\x50\xa9\x87\xe8\x21\x09\xf0\xae\xc7\xc2\x80\xd2\xb1\xc5\x07\xb7\x6e\xe7\xf9\xd4\xfd\x0c\x31\x32\x08\x1c\x0e\x56\x8d\x74\x26\xdb\x0d\xca\x50\xe0\x13\x78\xb6\x8d\x25\x8f\xdb\xe9\x28\xe0\xd6\xc3\xad\x55\x95\x9d\x5a\xab\xac\x5d\xcb\xa0\x1e\x3b\xb8\xa0\x93\x90\x4a\x27\x0a\x73\x28\x4d\x5f\x27\x0f\x5a\x13\xd2\x47\xe7\xb2\xe3\xf9\xb8\xf1\x29\x01\xfd\x8c\xc5\x56\x98\x4d\x9b\x58\x1d\x00\x8c\xfa\x7a\xac\x03\xca\x8f\x1c\xfc\x32\x7b\x10\xa3\x7c\xba\x6f\x2f\x8c\xe8\x81\x78\xae\x38\xb2\x6e\xbf\x81\x67\x5c\x04\x13\x70\xa4\xf7\xf3\xac\x14\x8d\x97\x3b\xfa\x79\xf7\xc1\x2c\x36\x91\x05\x62\x1d\xc5\xaf\x9f\x90\xed\x33\xa8\xba\xc1\x6b\x54\x80\x01\x89\x17\x51\xcf\xc5\xd9\xc1\x18\x8d\x34\xad\x1f\xac\xef\xb3\x03\xcd\x10\x1e\xa1\x3b\x88\x5a\xfb\x34\x1a\xbf\xa2\xa1\x5c\x8c\x78\x1d\x51\x00\xc5\xfa\x80\xa3\x7b\x1b\x1a\x87\x88\xaa\x96\xd9\xf3\xcb\xe5\xe4\x87\x8b\xa1\x20\x31\x6e\xa5\xb3\xfa\x54\xb6\x8e\xdd\x07\x91\x3e\xc3\x52\x70\xfc\xd4\xd9\xa1\x1e\x16\x91\x1a\x26\x18\xd6\x57\x76\x34\x4b\x59\xf3\xd2\x39\x88\x86\x69\xab\x41\x65\xd9\x7c\x57\x90\xe7\x08\x85\xf2\x47\xdb\xf1\xea\x39\xaa\xbe\x9c\xa1\xae\x0f\xcd\xfb\x5c\x61\xa2\x61\x26\xb0\xdc\x6c\x2f\xa0\x5e\x37\xc5\x9b\xb0\x9a\xe4\xfe\x42\x21\xb3\xd0\x66\x5b\x88\x31\x89\x59\x8e\x7b\x22\x64\xd6\x79\x92\x8d\xea\xd6\x58\x13\x72\x83\xf6\xa8\xc5\xa7\x60\x70\x60\x6e\xfe\xbb\x9d\xda\x44\x24\x24\x62\xba\x8d\xfb\x81\x6f\x22\x6a\x8c\xec\x37\x84\x2b\xae\x04\x13\xc5\x54\x78\x9f\xbd\x6c\x32\x35\x5e\x32\x4d\xa4\x85\xcf\x00\x3a\x3d\xba\xb7\x09\x5d\x88\xe1\x71\x8a\x9f\x73\x50\x79\x1a\xa4\x33\xa5\xa7\x86\x27\x14\x53\x93\xab\xec\xf5\x55\x0c\x2c\x15\xc3\x41\x63\x66\x07\x0d\x51\x44\x31\x4c\x51\x25\x26\x56\x96\x35\xb7\x7e\x29\xdf\xbd\xd4\x89\x8d\x64\x8d\x7b\x34\xd6\x21\x32\x8d\x6d\x9c\x08\xae\x67\xa1\xf8\x09\xd9\x3c\xce\xc5\x9d\x97\x24\x11\xc2\xe9\xb3\x7a\x99\x35\x3b\x18\x37\xf3\x5d\x9d\x08\x05\x6a\x30\x43\x97\x99\x8e\x26\xfd\x9d\x6a\x89\xf3\xaa\x1d\x7d\x2e\x5e\x3e\x77\x25\x91\x52\xac\x42\x5f\x2e\xfe\xba\x62\x82\x32\x42\xa4\xe0\xc9\x86\xbd\x5d\xd9\x7d\x06\x21\x14\x96\xee\xdc\xdc\x3f\x0d\xf7\x65\x83\x29\xb5\x01\xf4\x75\x5b\x81\xce\x6c\xc8\x71\xce\xf7\xf4\x4f\x28\x59\x84\xa8\x03\x28\xea\xdd\x59\xea\xf2\x28\x32\x47\xaa\x54\x09\x4b\xd9\xea\x1b\x0a\x82\x2b\x21\x34\x2f\x1d\x5d\xdf\xf8\x9b\xa8\x30\xee\xe4\x26\xca\x1a\xff\x37\x2d\xef\x30\x2a\xb1\x62\x37\x42\x5b\x76\xb8\x39\xb3\xdd\xe8\xc0\x60\xd4\xea\x47\x56\x3d\x67\x23\xeb\xc3\xe8\x38\xc1\x84\x67\x59\xe4\x97\x65\x79\x2e\x14\xf2\xcc\xaf\x7f\x35\x36\x61\x35\x79\x22\x9d\x58\x30\xd1\x4a\xd4\x2f\xdb\xf2\x15\xeb\xb5\x47\x97\x03\x1a\x29\x9b\xa0\x3d\x1d\x16\xab\x75\xf7\x33\x8f\x31\x4c\x83\xf9\x0c\x53\x56\x5d\x28\xd4\x1d\x37\x91\xf4\x65\xf2\x1b\x2b\xc8\x32\xbc\xaf\x26\x44\x26\xc0\x86\x12\x03\x57\x33\xbb\x37\xa0\x35\x09\xc2\x00\xf9\x54\xde\x5f\x44\xe7\xbb\x8f\x86\x9b\x26\x81\xd4\x38\x22\x57\xfb\xc7\xbf\xb9\x9f\xa8\x4a\x22\x0b\x27\xfb\x77\xbb\x55\x7f\x9c\x32\xd1\x84\x45\x89\x4d\x43\xdb\x3a\xb7\xbe\xf4\x43\x13\x96\x30\xe5\xdc\xa9\xe6\x25\xab\x8f\x67\xf5\x02\xcd\x8b\x29\xab\x4b\xeb\xc9\x9e\xce\x63\x2b\xa8\x6d\x9f\x78\xa1\x1a\x14\x84\xbd\x22\x53\xd4\x84\x09\xea\xa5\x19\xef\x2f\x4b\x0f\x1c\xd1\x84\x81\xa2\xe9\x40\x84\xc6\xaf\x0b\x9a\x44\xda\xc6\x0a\xee\xb3\xa2\x19\x66\x5b\x35\xe1\x34\xf4\x54\xb8\x3f\x36\xdb\xa9\x24\x6b\x7b\x5c\x0c\xe4\xbb\xef\xe1\x28\x3f\x48\x70\x6a\xc2\x63\xa6\xc3\x01\x7c\x6e\x74\x9f\x84\x48\xcc\x7f\x68\xf4\x37\x31\xbf\xc6\xba\x63\xa9\xc4\xcf\x63\xa9\x38\x96\xe7\x3a\x2b\xa0\xae\x77\x97\xba\x81\xe3\xff\x89\xd8\x46\x93\x94\x5a\x16\x71\x94\x7a\x69\xd4\xcb\xe4\x6d\xd2\xd8\x3a\x94\xab\xa7\xc7\x9f\x37\x87\x9f\xeb\xf5\x37\x7a\xd8\xae\x9f\x36\x8f\x37\xfe\x59\x84\x13\xd4\x6a\xfd\xc4\x5f\x2a\x3f\xd7\x99\x0f\xbc\x6b\x22\x9c\x7a\xa1\x01\xd8\x42\xf5\xbd\xc8\x9a\x47\x33\xa4\x71\xef\x9a\xc5\x90\x58\x5a\xd3\x5a\xe4\xb0\xfa\x1d\xa0\x53\x13\xa1\xb4\x10\x1e\x16\x85\xb1\x7e\xed\xc2\x76\xe2\x19\x10\xa2\x3a\x7e\x4b\xc5\x12\xac\x7d\x03\x4f\x57\x8a\xa5\x60\x37\x95\xb8\x7a\x16\x15\x5a\x6d\xce\xb6\x3f\xa0\xae\xc5\xb3\xcf\xd2\x75\xc7\x53\xf4\x0d\xef\x17\x7f\x20\x4d\xcf\xee\xfb\x76\x7b\xf7\xcf\xee\x68\x0c\x18\xbb\xf7\xe2\x44\x36\xf2\x38\x1b\x2a\xd4\x44\x39\xd6\xa9\xed\x62\xf5\xed\xb0\xdb\xfc\xb9\xf6\x57\x01\x2e\x8c\x4d\xd4\x94\xef\x85\x75\xd3\x3e\x35\x8f\x34\x01\x87\x21\xd3\x90\x63\x48\x28\x9f\x86\x84\x34\x01\x63\x4d\x75\x57\xfb\xfb\x84\x20\x89\x0f\xba\xd7\xa4\x96\xb2\xc0\x66\x2c\xae\xb4\xb9\x6d\xab\x20\x30\x22\xb4\x1a\x9f\xf9\xf7\x22\x53\x65\xd5\xab\xf0\x8e\x1b\xd2\x50\xa5\x58\x8e\x51\x66\x45\xd3\xae\xb1\x5b\x51\x35\x99\xca\x4e\xa2\xf9\xcd\x8b\x05\x34\x32\x64\xbc\x6c\xfd\x15\x5c\xac\x0e\x28\x17\xa1\x25\x26\x7c\x73\xf6\xee\x30\xaa\xdb\x1e\x07\x14\x6b\xdf\x9d\x44\xf5\x8a\x29\xc3\xe1\xe4\x0b\x18\x0b\x2d\xfd\xbd\x5b\xf3\x86\x96\x89\x0e\x98\x00\xf4\x59\x6a\xf1\xf6\x7b\x66\xc2\x8f\xa1\x40\x3a\x08\x89\xc6\x0a\x04\x4f\xed\xd3\xf9\xf0\xde\x17\xd7\x41\x48\x39\x6b\x47\x7a\xeb\x2a\x83\xde\xc1\x07\xca\x8a\x3a\x08\xe3\x38\xb1\x4c\x64\x96\xd8\x1f\x8b\x67\x26\xfe\xaa\x0e\xb8\x13\x8a\x41\x2c\x6f\xbd\xa8\x5a\x37\xde\x07\x19\xda\xa3\x80\x31\xdf\xef\x0f\x77\x8f\xab\x6f\x87\xed\xd7\xc5\x6e\xbd\xeb\x0e\x46\xb1\x67\x30\xf7\x26\x8e\x8f\x74\xcd\x7f\x3b\x1e\x27\x26\xec\x78\x94\xd7\x05\xf2\xfa\x75\xf0\x64\x1d\xf0\x34\x0d\x84\x67\xfd\x85\xd3\x88\x11\x45\x07\xb1\xa0\x68\x32\x1f\xa1\x9d\x4a\x45\xf3\x35\xab\x31\x07\xe2\x0e\x27\xd4\xaa\x30\x3b\x5a\xb4\xc3\x0e\x9a\xad\x38\xd7\x03\x32\x56\x1d\x24\x21\xc3\x50\x83\x12\x79\xbe\x28\x74\xdb\x85\xdd\xe9\x3c\x4e\xa0\xa3\x29\x1c\xbb\x58\x3a\x48\x64\x1a\x50\xbf\xbc\x60\xf5\x41\x77\x40\x62\x32\xe0\xeb\xb6\xfb\x45\xf1\xc0\xe2\xe5\xea\x6e\xa7\xdc\xdc\x74\x47\x21\xc6\xcc\xa4\x38\x6e\xbe\x06\xfe\xc7\x94\x11\x8c\x44\xb4\xb6\x54\x6b\x30\xa0\x64\xc2\xf8\x33\xa5\x61\x82\xd4\xad\x8e\xde\xd1\xe5\x04\x22\x7f\x05\xc1\x23\xe6\x70\x13\xaf\xd0\x1c\xbe\x88\x42\xe8\x6b\x42\x49\xdf\x58\xa4\xdc\xf9\xe8\xd5\x33\x7c\x82\x68\xed\xda\x5b\xce\xbb\x2e\x21\xb4\x2f\x2d\x01\xc3\x6f\x22\x4e\xee\x74\x99\x6a\xc4\x8f\xec\x9f\x56\xa3\x29\x25\xb5\xc5\x19\x20\x48\xc2\xaa\x0a\x7f\x15\x6f\x6f\x50\xd4\x07\x79\xe9\xca\xc3\xfc\x4f\x48\x4d\x0d\x7a\x77\x3e\xfa\xf3\x15\x68\x6a\xc1\xe4\x85\xbe\x9c\xeb\xeb\x4d\x75\xf2\x1a\xad\x23\x8a\x25\x3c\xe7\xea\x0d\x2e\xd7\x99\x73\x1d\x68\xda\x81\x76\xef\xb3\x02\xaa\xfa\xb1\xd8\x0d\x26\x83\x0e\x63\x5c\x7a\x0a\x78\xdf\x57\x99\x9c\x63\x8a\xd1\x01\xd0\x20\xb2\xa4\x27\xba\xe3\x41\xf8\xc4\xef\xd2\x01\x84\x44\xf4\x02\x75\xed\x74\x70\x09\x06\x1b\x08\x9c\x3c\x22\x08\x2b\x05\xfa\x0c\x4d\xbb\xab\x59\x86\x2b\xcb\xc4\x5c\x16\x7e\x16\x7e\x2e\x80\xac\x29\x09\x0c\x5a\x94\xb8\xbf\xaf\x07\xf9\xbb\xe1\x9b\x50\xa2\x53\x54\x58\x5d\x3e\x3e\x7c\xdf\x1d\x50\x98\xf7\xf1\xfb\xc3\x8d\x4b\xf7\x6a\x4a\x80\xd8\x52\xc1\xd3\x32\xd3\x03\xc4\x62\x7b\xc4\x96\x3c\xef\xda\x2d\xb3\x35\x77\x50\xb5\x76\xf6\xa1\x12\x77\x4a\x20\x84\xab\xcf\x2d\xf4\x54\x8e\x65\xde\x50\xa1\x94\x07\xa8\x46\xe5\xd0\x0b\x98\xf7\x99\xc4\x38\xbd\x5c\x59\xc0\xaf\xe0\x26\x9a\xd2\x38\x30\x2e\x52\x87\x7a\xe2\x4f\xe2\x7d\xb4\xaa\x53\x9a\x28\x70\x64\x1b\xb5\xaf\x0e\xf1\xf2\xb8\x3d\x74\x51\x53\xaa\x23\x44\x26\xb4\x63\x70\x29\x90\xd8\x63\x3c\x7b\x29\x8b\x6c\x9e\xea\xdb\x76\xe8\x0f\x69\xca\x84\xc1\xfa\xad\x02\xde\x9d\x3f\x83\x05\x30\xbf\xd5\x00\xef\xdf\x65\xfc\xc9\x42\x92\x04\xbd\x1c\xea\xee\x35\x2b\x16\xa7\x13\x88\x6a\xb8\x26\xfb\xa6\x29\x41\xf7\x01\xab\x5d\x7a\x69\x33\x4d\x79\x62\x45\x73\x47\xaa\x23\x07\x79\xd9\x56\xe5\xaf\xeb\xaa\xa4\xf9\x01\x16\xa7\x36\xa8\x7c\x5b\x56\xed\x62\x39\x89\xba\x68\x9a\xa4\x02\x01\x8a\x59\x25\xe7\x69\xf2\x34\x4d\xa4\x40\xac\xdf\x0e\x9a\x2f\xa2\x9e\x22\x53\x75\xfb\x6d\x30\x18\xb0\x7a\x29\x4b\xfc\xdf\xe0\x15\x12\xa0\xb8\x9e\x36\xb6\xba\xc4\xfa\x45\x5b\x71\x79\x3c\x7b\x17\x55\x53\x91\xca\xd4\xa5\x5d\x5a\xe3\x03\xb5\xed\xa7\xcb\x3e\x55\x89\xc6\xc2\xac\x5c\xd4\xcd\x1a\x2f\xa3\xc0\x8a\xcf\xf8\x06\x10\x51\x97\xaa\xd7\x22\xcb\xa7\x0f\xa9\x93\x00\x9d\x1a\xec\x64\x1f\x58\x77\x9a\x5e\x1f\xe1\xa0\xda\xb3\x28\x67\x1e\x1c\x7f\xdb\xe5\x95\x34\xd5\x60\x09\xd5\xbb\xa8\x56\xf1\x79\x99\x98\xa6\x10\x47\x18\x84\xda\x6c\xdf\xf8\x68\xe4\x99\x48\x6a\xe1\x4b\x80\x1d\x5f\xe1\xf8\x54\x23\x35\xc6\x72\xce\xb5\x5e\xd7\x4d\x76\x14\x0d\x6c\x8a\x71\x72\x59\x33\x42\x63\x14\x34\x9a\xd4\xc7\x8e\x67\x2a\x23\xda\x96\x54\x38\xf1\x7e\x14\x81\xcb\xb3\xe7\x4c\x4e\xab\xec\x35\x0b\x78\x80\x15\x4a\x47\xf1\xcb\x23\xbc\x06\x4b\x30\x0b\x20\x8d\x5d\x60\x1f\x0a\x7d\x03\xb2\xb9\x03\xfd\xec\xfa\x74\xfc\x02\x8c\x2a\x39\xa0\x9f\xef\xe1\x0e\x3b\x55\x56\xf3\x5a\x18\x9a\x31\x62\xf5\xd7\x4c\x56\xe8\x75\x0e\x6f\x50\x6c\x8f\xdf\x1b\x35\xb9\x72\x28\xac\x06\x49\xc7\x23\xe9\x1f\x2f\x34\x29\x9a\x6f\x5f\xe1\x17\xe4\xeb\x4a\x79\x72\x89\x59\x93\x6f\xd2\x49\x91\x8e\xa5\x5b\xd9\x97\xe7\xcb\x60\x7d\x61\xdc\xc4\x48\x51\x23\xea\x1a\xaa\x66\x55\x56\x15\xa8\xe6\x8a\x2b\x57\xb3\x38\xb2\x81\xe5\x1c\x91\xfa\x8f\xe7\x46\x95\x9d\x6d\xc5\x62\x30\x48\x02\xf2\xb4\xde\xad\x9f\x7e\xac\x6f\x0e\xdb\xc5\xd3\xfe\x61\xfd\xb4\x3b\xb4\x96\xdd\xfa\xe6\xb0\xdb\xdc\x78\x7f\x83\x25\xc4\x18\xd6\x93\xfa\x2c\xd1\x0f\xf4\xc7\x52\x23\x1c\xbf\x94\xb5\xe0\xba\x03\xc2\xfa\xa7\xf7\x50\x29\xa1\xcb\xfb\x12\xb4\xf0\xc7\xd2\x24\xc4\xbd\x3e\xab\xca\xc2\x11\xfe\x4e\x2d\x51\x96\x2a\xca\x49\x2f\x47\x36\x99\x8b\x4c\x06\x8a\xd0\x71\xfe\xb1\x2f\xe1\x1d\x36\x33\xe8\x6d\xef\xf6\x4f\xc3\x5c\x95\x66\x92\x92\xc8\xf3\xfd\x82\xd0\x9d\xed\x39\x39\x9d\x72\x61\xb5\x69\x4c\x3e\xe3\x8c\xf8\x56\x61\x8c\xd3\xea\xcb\x1f\x3f\x56\x4f\x58\xf4\xf1\xc1\xc8\x97\x2a\xf4\xb4\x0a\xce\x79\x74\x24\x47\x5f\x45\xfd\xf2\xbd\xce\x8a\x67\x0f\x79\x9e\x66\xa4\xe7\xaf\xa7\x98\xc1\x3a\xf6\xba\x10\xa7\xfa\xa5\xf4\x36\xc2\xf4\xa4\xe1\xa6\xc0\x54\xa4\x90\x99\xd1\x41\xdd\x6f\x33\x57\x61\xdd\x25\xfa\x3e\x5d\x42\x98\x92\xc2\xe9\x57\x3b\x05\xc6\x4d\x81\xe3\x6a\xbe\xb5\x16\x09\x6e\x2b\x6f\xed\x84\x5c\x98\x06\x5f\x0c\x5f\x13\x8e\xd9\xf9\x38\xe9\x6d\x90\x56\x45\x48\x43\x3d\xf1\x78\x5c\x03\x13\x05\x98\xf7\xbe\x5f\xff\x3c\x60\xc4\x61\xb7\xb8\x5b\x1f\x6e\xbf\x3f\x78\x83\x3a\x24\x11\x43\xc3\xc1\x80\x7a\x59\xe4\xf9\x4a\x14\x1a\x43\x8b\xf5\xf2\xb2\x73\x9d\x64\x95\x48\x46\x77\x0e\x89\xa2\x18\x1d\x6b\xc4\x2b\xec\x7c\x85\xd4\xa8\xf0\xfc\x5f\xac\x5f\x99\xfb\xff\xfc\x24\xd9\xae\xc3\x80\x32\x84\x15\xfe\xcf\xf2\x8f\xed\xfa\x69\xbd\xff\xea\x1f\x32\xe8\xeb\x91\x7e\x4c\x72\x72\x3a\xa4\xa1\x56\x36\x92\x08\xef\xcd\x12\x26\xbe\x72\xc8\x82\x00\xbc\xeb\x81\x51\x78\x51\x37\x30\xd6\x85\xf4\x2d\x69\x42\x92\x1e\xf8\x39\x89\xea\xcd\xb9\xa5\x89\x37\x90\x7a\x53\xa9\xfd\x2f\x7f\x3d\x0e\xc2\x21\xa2\xd7\xcd\xcb\xf2\xdc\x93\xd4\xe9\x90\x25\x0a\xcb\x53\xf7\x2f\xf0\xf5\x7c\x14\xc5\x08\x06\xf6\x51\x71\xa5\x0e\x99\xd4\x81\xc5\x44\x9e\x72\xa1\xe0\x66\xb7\xf5\x76\xcf\xe4\xad\x43\x15\xc6\x6e\xb6\xde\x65\xc5\xeb\x4d\xf6\x0c\xf5\x95\xa3\xe1\xda\x46\xdc\xd2\x3d\xc2\xaf\x06\x0a\x6d\xc3\x23\xcb\xc9\x56\x1c\x46\x32\x85\x4e\x69\x74\x75\xb7\xba\xa2\x0b\x18\x3d\x27\x97\x49\xe0\xea\x59\x1e\xca\x2b\xe3\x29\x8c\xa9\x46\xc9\x2c\x0d\x6f\x5f\xb2\x37\xc0\x01\x36\xf2\x0b\xc3\x24\x51\xbe\xfc\x6a\x2b\xd4\xab\x78\x46\x6e\xc9\x47\xb3\x12\xc7\x93\xc8\x9e\x8b\x71\xec\x34\x4c\x14\xe1\x1e\x04\x80\xe0\xf5\x6e\xa3\x1d\x3d\x56\xca\xa2\xd8\x99\x1b\xbb\xd2\x34\x2b\x71\x1a\x69\xf1\xeb\x30\x95\x02\x89\x4e\xec\x9e\x77\x0f\x47\xf8\x5e\xe5\xb3\xe6\x7d\x28\x62\xe5\x0a\x8c\xed\x26\x16\x5c\x91\x21\xeb\x50\x24\x12\x8b\x55\x76\xea\xa5\xcc\xc5\x90\xff\x4c\x87\xc2\x24\x48\x52\xb9\x12\xcd\xe8\x77\xe9\x24\xd9\x9b\x2e\x80\x39\xc2\x41\xeb\x50\x0a\xe6\x6b\xa7\xbc\xcc\xdf\xfe\xa5\x82\xfa\xa5\xcc\x27\x8b\x79\xa8\x13\x2b\x52\xda\x09\x5c\x7b\x32\xeb\xf1\x00\x00\x88\x31\xdd\xd0\x0e\x42\x51\x65\x62\xf4\x3c\x60\x08\x12\x97\xbc\xd9\xfa\x8f\xeb\x2a\x38\x1d\x91\x54\x61\x5d\xaa\xad\xfa\xb3\x1f\xf2\x9a\x64\x4a\x47\x8c\x0a\xcc\x71\xee\x7e\xae\xd7\xfb\xcf\xc6\x4f\xc4\xa8\xd4\xd0\x5d\x71\xe7\x8a\xf4\xaf\x42\xec\x7e\xaa\x45\x8c\x5b\x15\xa0\x7f\x97\x59\xf1\x65\x82\x15\xd0\x51\x28\x6d\xcd\x53\xeb\x7c\xac\x7b\xfe\x6b\x1d\xf1\xc0\xc4\x0e\x36\x63\x05\x92\xe5\x94\xd4\x42\x47\x3c\x0a\xd0\x26\x69\xc7\xe8\xf9\x74\x80\x42\xeb\xde\xb6\x88\x78\x12\x60\xa2\xd3\x3a\x51\x0e\xf8\x65\xcb\x4a\xce\x03\x02\x90\x11\x1d\xb1\x8e\xb8\x56\xc2\xdf\x17\xda\xdd\xe0\x6b\x59\x37\x1d\xa3\xd1\x74\x2b\xfb\x8c\xd8\xc8\x5d\x30\xa1\x2c\x75\x98\xd3\x76\x18\x2e\x9a\xef\x93\xea\x05\x1d\x25\x21\xe1\xcc\xc7\xa5\xd1\x42\x98\x7c\x9d\x84\x47\x68\xb0\x2e\x2b\x10\x08\x3e\x1a\x0e\x83\x28\xd1\x04\x43\x3f\x37\x4f\x8f\x3e\x54\x13\xa5\xc4\x16\xde\xd5\xe0\xea\x7d\x3e\xd8\x84\x7d\xf3\xc8\xda\xa6\x4e\x4a\xfe\x2c\xb3\xb9\xe2\x03\x1d\xa5\xa9\x25\xee\x69\x3f\x7e\x03\x3b\xab\x4b\x74\x4d\xa7\x3d\x1b\x9c\x89\x52\xa5\xd1\x0a\x72\x58\x83\xb2\x6c\xc6\x4b\x45\x24\x98\x15\x12\x50\xa2\xf8\x52\x36\x65\x5f\xf6\x9e\xf8\x06\xa0\x11\x15\x7e\xa8\xcf\xf2\x0b\x14\x1f\x32\x50\xb8\xe6\x92\x04\x18\xbf\x7e\x5a\x3d\xf9\x7e\x91\xd4\x4e\xfb\x2f\xbf\x26\x55\x7f\x75\xd7\x42\xc6\x26\xf4\x1a\x0f\x3f\xb2\x42\x65\x93\x3e\xd0\x64\xa0\xea\xdd\xc5\xef\x41\xf7\x9b\x62\xa4\x65\x80\x69\x9d\xac\x50\xa8\x0f\xf3\x58\xb4\x2b\xc0\x72\xc6\xef\xef\x23\x78\x91\x36\xd6\xa8\x3f\x5c\x05\x09\x26\xf7\x37\x26\xea\x7c\xa8\xfa\xf1\x7d\x6a\x6d\x72\x92\xd8\xa5\xb4\x5d\x71\x1d\x4c\x65\x0a\x3c\xaa\xa7\x98\x23\xcd\x83\x94\x62\x1c\x50\x8a\x1a\xb6\xc8\xb7\x83\x22\x9b\x3d\xcd\x91\xe6\xd4\x88\xc4\xe5\x0b\x96\x97\xd6\x77\x5e\x14\x7a\x5f\x7e\xfe\x11\x38\x8b\x41\x42\xf7\xb8\x3e\xc8\xf0\x63\xb3\xad\x57\x1e\x05\xa9\x39\x4b\x2d\x98\xfe\xf0\x0c\x4d\xfb\x58\xd7\x60\x15\xcd\xc3\x80\x62\xc6\xcd\xc5\x09\x4b\x33\x79\xed\x28\x0e\x00\xf1\x0e\xf9\x59\xfa\xeb\x46\x22\xc2\x68\xfc\x66\xf5\xa5\xfb\x49\x59\x7c\x4e\x56\x64\x0d\xd6\x91\xd5\xd3\xeb\x80\x42\x33\xfb\x24\x2e\xfb\x72\x5a\xb6\xe7\xda\x70\xaa\x8c\xf1\x2f\x75\x63\x8d\x12\x7f\x03\xae\x85\x65\xff\xc8\x45\x76\x74\xe8\xc9\xd9\x2f\xc9\xe3\x28\xc5\xb4\xa2\xc3\xde\x21\x92\xe3\xb7\x31\xf6\xc9\x25\x62\xbb\xbb\xca\xf3\x65\x5b\x95\x1f\x52\xa3\xb9\xd6\x09\x09\x30\x00\xb2\x7d\x5a\xed\x0f\xfb\xf5\xe2\xde\x3f\x73\xc2\x52\xa4\xa2\x79\x5a\x2f\xee\x26\xaf\x9a\x44\xa9\xa1\x9d\x3a\x42\x59\xcd\x29\x79\xf9\xa6\x9a\x39\xed\x9a\x95\x5f\x88\x78\x1a\x5a\x0a\x27\x67\x04\x3b\x22\x21\x3f\x0c\xfe\x76\x3d\x0f\x78\x1a\xd9\xc2\xdc\x83\xbb\xc9\x43\xd9\x3c\x9c\xf3\x7c\xf2\x58\xa9\x0c\x5d\x91\xa5\xf3\x06\x77\x30\xac\xd6\xd7\x3c\x35\x21\x72\x94\x96\xe7\xa6\x46\x2d\xea\x1b\xc8\xb3\x37\xa8\xae\x38\x4d\xfe\xfe\xc9\x1f\x77\x2d\x41\x29\x9a\xfe\x37\xd5\x88\xbe\x4b\x73\xd1\xee\x86\x3d\x93\xa0\x4d\x46\x8c\xf3\x42\x1f\x7e\x48\xe4\x0f\x1a\xbc\xb7\x60\x9c\x87\x5e\xc9\xfd\x1d\x19\x8f\x26\x3e\x03\x17\x91\x85\x3a\x3b\x92\xe8\xdd\x73\xb1\x2f\x77\xcf\x62\x32\x51\x44\x1c\x60\x4d\x04\x14\x1a\xf4\xa2\x9b\xbd\x22\x8d\xb1\x66\x61\x87\xd8\x0e\x4b\x0c\xf1\xf9\x70\x11\x92\x23\xbe\x7e\xf5\xb4\x5e\xec\xd7\x87\xed\xfa\xe9\x7e\xb3\xdb\x6d\x1e\x1f\x76\x87\xa7\xc7\xbb\x75\x77\x61\x9d\x5a\x1d\x90\x76\xc0\x6f\xab\xec\xbf\x1e\x0b\xa4\xb9\x24\x56\xf4\xf1\x23\x00\xe4\x6d\x59\x41\xf6\x5c\x3c\x94\xcd\xa6\xf8\xee\xc1\x0e\x9a\x4b\xae\x1c\x97\x9e\x8d\xfa\xfe\x8f\x50\xaf\xa7\x81\x80\xc0\x6f\x94\xd3\xfd\x55\x62\x86\x14\x0a\x15\x88\x41\x19\xcb\xc4\x15\xe0\x52\x25\x68\x44\xa9\x76\x51\xc9\x2d\x39\x63\x55\x4e\xca\xc5\xba\xb6\x02\x2d\xed\x2f\xd0\xfc\x6c\xb7\x69\x84\x5e\x8e\xf6\x30\xae\x42\x8d\xc5\x39\x2e\x9d\x38\x06\x25\x0f\x4d\x1f\xae\x0d\xd1\xb6\xd0\x5a\x7d\xed\xa8\x22\x35\x07\xe6\x98\x05\x2c\x06\xf3\x14\x4c\xc6\x00\x24\x31\xd6\xc2\xda\xe7\x45\x21\x8f\x59\x21\x2b\xcd\x41\x24\xd2\x16\xf5\xa1\xb4\xf6\xbd\x28\x2e\xfd\xdb\xcf\xd1\x20\xfd\xde\x71\xe2\x00\x0a\xa3\x62\xed\xee\xfd\x50\xb2\xdf\xfb\x45\xdc\x30\xc6\x3b\xb5\xf5\x49\x5d\xa1\xe6\x46\x59\xdd\x92\x1d\x12\x9c\x34\xd9\x44\x1b\x63\xfc\x42\x46\x5b\x26\xc3\xba\x29\x4f\xc8\xac\xe1\xae\x12\x93\xd4\x98\x8e\x00\xee\x98\x39\x5a\xfd\xd1\xb7\x8b\x69\x68\xeb\x9c\x5d\x75\xfa\xc7\x41\xca\x98\x46\x89\x97\x2a\x6a\xcd\x6e\x5f\x42\xbf\xbc\x60\x24\xb5\xf3\xd4\xe6\xb2\x9c\x31\x55\x31\x96\xda\xd8\x22\xf2\xe1\x5a\x11\x53\x13\x12\xd3\x2b\xb3\x6f\xd9\x4d\x8f\x8b\xd3\x31\x53\xd4\x99\xd5\x98\xe2\x5f\x2d\xf6\xc3\xfe\xf0\x8d\xb4\xb6\x05\x11\x5f\x1e\xee\xfc\x6f\x21\x61\xa2\x8f\x05\x8e\xac\xeb\x38\x0c\xd2\xd4\x6a\xbc\xc1\x46\x95\xbb\x5e\x44\x4a\xc7\x61\x6c\x70\xe3\xc8\x0a\x8f\x58\x9a\x71\x0b\xe2\x10\x92\x88\x77\xb0\x4d\x37\x0d\x97\x30\xed\xdb\x88\xd8\x42\x20\xd3\x8b\x1c\xe9\x38\xe2\xa9\xb7\xe0\x7f\x56\xe2\x74\x72\xd3\xc5\x1f\x55\x21\xa6\x58\x1e\xd7\xcb\xd5\x52\x14\xaf\xdd\xef\x10\x20\x85\xe0\xe6\x78\x2a\x2b\x84\xc0\xae\xfc\x21\x1e\x72\xe3\xf9\x61\xca\xee\x04\x9e\x02\x82\x3a\xd6\x7f\xec\x0f\xab\xc7\xfb\xed\xe2\xe1\x9f\x87\xc7\x87\x75\x77\x58\x5a\xfe\x54\x44\x11\xe2\x3c\x1b\x3f\x7a\xaa\x98\x55\xdf\xbb\xfb\xee\x4f\x49\xb5\x85\xe9\x4a\xcf\x20\xa4\x63\x91\x48\xe1\xa0\xf4\xff\x38\x97\xc8\x3e\x39\xb9\x8e\x48\x14\x92\x3c\x6c\x1f\xb7\xdf\x1e\x37\x0f\xfe\x44\x09\x3a\x4d\x3d\x1b\x57\xf9\xeb\x72\x5b\x56\xbb\xb1\xb2\xd0\xb8\xc3\x55\x6a\x63\x99\xfb\xaf\xcb\xc3\xe3\xb1\xc8\x2c\x7b\x89\xbf\x9a\x66\xc6\x02\x84\xad\x4b\x23\x72\x98\x96\xb5\x7e\xba\xa0\xc7\x5a\x08\xd4\xb9\x3a\x64\x35\x12\x9e\xf7\x7e\x4d\xa1\x47\x32\x59\x83\x8d\x34\x86\xc0\xe2\x2d\x7c\x50\xad\x82\xae\xd6\xe4\x33\x92\x23\xbf\x22\xc6\x86\xa4\xf8\x05\x40\x67\x0d\x2e\xaf\x96\x0a\x74\xfc\x64\x86\x47\xcc\x05\x45\xbe\x54\xc2\x98\xac\xc9\xc6\x2d\x12\x22\x23\x46\x7b\xf3\x6f\x34\xd0\x13\x02\x02\x07\x20\x6e\x41\xdf\x77\x1b\x67\xab\x0c\xf9\x35\x74\x12\x30\x9d\x38\xb9\x18\x4c\x45\x5f\x2c\x54\xb1\x3f\x1e\x32\x2c\x22\x7f\xcf\x0a\x5d\xbe\xb3\x4e\x83\xd4\x1f\xa7\x44\x20\x2b\xe7\xfe\xf1\xdb\xfa\xe1\xf0\x84\x5b\xe2\xd3\x7a\xb7\xe8\x76\xc2\x84\xc6\x96\x50\x06\x0b\xed\x3b\x4a\x81\xf1\x9c\x4a\xa8\xb2\x1f\xf1\x28\x7e\x59\xcf\x16\x63\x5f\xdd\x53\x50\x08\xb0\x48\xcc\x86\xc4\xd7\xff\x61\x6e\xc1\xf9\xfb\xe8\x0f\xf5\xad\x8d\x95\x96\xec\x33\xb2\xeb\x2f\x8f\x7f\xf4\x8b\x9b\x6b\xc6\x28\x41\xcb\xbd\x7c\x2f\xa0\xda\x41\xe3\x66\xf2\xa3\x41\x2d\xb6\xb5\x7e\x86\x91\x67\x9d\x30\xca\x70\xad\x12\x76\x78\xed\xce\x4a\x41\x5d\x9b\x73\x3e\x1a\x68\x01\x4d\x66\xc9\x0e\x74\xc2\x40\x5b\xad\x27\xb7\x81\xb7\x93\x46\x5c\x0d\xd2\xf1\x39\xa1\x4c\x70\x63\xb3\xb0\xcb\xdb\xb2\xf2\x39\xf8\x71\xb3\x88\x2b\x9f\xdd\x5a\x1d\x45\xbd\xbc\x5c\x63\x9f\x75\x12\xb3\x00\xd3\x64\x08\xed\xb8\x5f\xfc\xe1\x3b\x37\x21\xb1\x49\xbc\x3e\xc9\xa3\x99\x3b\x35\x49\x6c\xc8\x6d\x0b\x95\x29\xab\xe3\x22\xab\x6e\x5a\xc3\xda\x1d\x15\x84\x09\x33\x84\x90\xf9\xdf\x39\x43\x9b\xab\x56\xc2\x67\xf1\x13\x19\x06\xa6\xaf\x94\x1d\xc8\x00\xf8\x06\x8a\xd9\x6a\x53\xac\x4c\x6b\x44\x3e\x94\xea\xd1\x89\x8a\xac\x04\x5a\xa9\x75\xbd\xcb\x8a\xe7\x09\x47\xab\x4e\x54\x2a\x71\xad\xf0\x00\xac\x9f\x65\xfe\x3a\x79\x19\x4d\x28\x06\x0e\xde\xa7\x5c\xc6\xb3\x09\xeb\x59\x85\x87\x0f\xe2\x1a\x89\x26\x1a\x69\x43\x1d\x01\xd4\x98\x8d\x77\xbc\xee\x24\x40\x0c\x7a\xdd\xb8\x08\x3f\x21\x60\x9b\x4e\x5e\x06\x02\x19\x23\x1b\xcc\xf9\xb8\x59\x3d\x62\xd8\x8e\xfb\x9e\x00\x9a\x86\x6e\xe1\xbf\xcd\x3a\x5a\x9c\xa1\xb5\x9f\x98\x24\xf5\xb5\x1c\xa3\x02\xfc\xa9\xbc\xbf\x4e\x49\xa2\xb0\xf4\x71\x8a\x61\x40\xae\x9a\x76\x63\xf6\x33\x31\x25\x3a\x0c\xff\x7f\xda\xfe\xa4\xbb\x71\x1c\x4b\x1b\xc7\xbf\xcb\xbb\xca\x45\x2f\x00\x10\x9c\xfe\x3b\x59\x96\x1d\xea\xf4\xf4\x5a\x8a\xc8\xac\xea\x53\x47\x07\xc3\x85\xcd\x0e\x8a\x54\x91\x94\x1d\xae\x4f\xff\x3f\xbc\x18\x38\x88\x76\xe6\xbb\xf8\x2d\xba\x23\xcb\x00\x29\x12\xc4\x70\x87\xe7\x3e\x8f\x76\x7b\x77\xfd\x0e\xcd\x0e\xdd\x88\xaf\x41\x5c\x39\x01\x5b\xce\x82\x3c\x84\x4d\xb7\x3b\x4b\xab\x7f\x33\xf9\x2e\x39\x05\xc0\xc0\xf8\x03\x48\x09\xbf\x16\xd9\xb6\x5d\x4f\xc6\x4c\x4e\x06\xd5\xd9\x70\x16\xe4\x2c\xb5\x81\xf7\x33\xee\xc5\xfb\xe2\x34\x35\x44\x73\x96\xa5\x58\x76\xf8\xee\x11\x6d\x21\x94\x9a\x47\x29\xc7\xbc\xc7\xba\xfe\x09\xca\x47\x93\x86\x6a\x93\xbe\x43\xc6\xf8\x94\xcf\x21\x9e\x6c\xb8\x79\x24\x22\xe4\xa7\xdc\x0e\x17\x53\xf6\xd7\xd6\x60\xce\x79\x1e\x8f\xab\xe5\x9c\x0c\x2a\xe8\x67\xb0\x5e\x5a\x18\x7d\x9e\xd8\x87\x2c\x5a\x87\x08\x1a\x13\x04\xf5\xcd\x2a\xb6\x79\x3c\xcc\xf3\x6e\xfa\xbb\x0c\x96\x52\xce\x81\x45\xfd\x2e\xf1\x56\xc0\xfb\x9f\xeb\xd5\xfe\x62\xe2\x4f\x07\x2b\x8e\x05\x9e\x51\xa7\xba\x9c\xe5\x30\xf2\x38\x49\x30\x7e\xd7\xf9\x9c\x2d\x94\xde\x2c\xc8\xe3\x54\x22\x86\xac\x7b\x2d\x1a\x7d\x40\xce\x44\x5f\x97\xe2\x7a\x24\x04\x30\x36\x87\x75\xeb\x6c\x60\xc1\xd4\x79\xa2\xd2\xd8\x1e\xab\x80\x45\xa3\xfe\xcf\x46\x04\x22\x9c\xb2\x74\x94\xea\x75\x33\x21\x04\xd7\x79\xca\x32\xac\x90\x0b\xeb\x7a\xbc\x7b\xe7\x42\xe4\x78\x54\xd6\x13\xd6\x5c\x9d\x0b\x9d\x22\x6d\xc3\x6e\xf3\xb0\xfd\x7e\x1f\xfe\x0a\x60\xec\x40\x5f\x41\xb7\xeb\xea\x46\xbc\x0c\x57\x18\xae\xa9\xb7\xff\x5e\x1a\xd1\xc1\xf5\x19\xf6\xf5\x43\x6d\xeb\xfe\xdb\x11\x02\x2d\x57\x60\x2b\xd3\x26\xaa\xd2\x56\x45\x7a\xc4\xd7\x3a\x0c\xac\x56\xd2\xd3\x6e\xdf\x88\x23\xe8\xfe\xbc\xbd\xfa\xd8\x5e\xcf\xc6\x1f\x58\x84\x84\x86\x9e\x9e\x6d\x84\x1a\xc8\x81\xb3\x28\x1a\x15\x54\xad\x4a\x79\x3e\xfe\xb6\xe0\xbd\x7c\xf5\x5f\xb3\xa9\x60\x08\x35\xd2\x89\x96\x40\xf3\x68\x66\x8f\x63\x72\x3b\xb1\xac\xb9\x7d\x0d\x55\x7d\xf4\x46\xba\xad\xec\x9c\xae\x5f\x41\x68\xc4\x6c\x54\xaa\x56\x3f\x2f\x64\x20\xb5\x20\x1c\x02\xea\xa9\x85\x06\x15\x4e\xda\x79\x9f\x44\x27\x6e\x4e\xec\x2d\x35\x6d\xf3\xe1\x04\xe1\x6f\xc6\xec\x57\x5a\x90\x5c\xa3\x34\xec\x73\x71\x3a\x05\x27\x4b\x10\xa1\xd2\xdc\xb1\xbb\x88\x26\xfc\x99\x2a\x1b\x37\x2e\x5a\x2c\x96\x2f\x40\x2f\x3c\x1f\x05\x83\x26\x0d\x5a\x56\x78\x5e\x4e\x4e\x29\x41\x4d\x6a\x8b\x95\x50\x3a\x6d\x59\x54\x57\x0b\x46\x13\xc4\x64\xa0\x5e\x0a\x92\x59\xfc\x25\x10\xc8\x5d\x19\x31\x8d\x89\x89\x1b\xd5\x8e\x70\x30\x22\x4a\x32\xdc\x40\x37\xfb\x6f\xaa\x3e\x82\x14\xea\x67\xc6\x88\x6f\xe5\x52\xe0\xa0\xae\x0a\x59\x8f\xa9\xe9\xa7\x33\x50\xc4\xb1\x90\x2e\x5d\xf3\xcf\xb2\xee\xda\x45\x37\x5a\xc4\x2a\xc2\x55\x73\x3a\xff\xe7\x3f\x63\x91\xf6\xf1\xac\x11\xb1\xa6\xe8\xec\xfc\x13\x9a\x7a\xf3\x6b\xae\x4e\x3b\x9b\x13\x09\xa5\x58\xde\xe9\x43\x45\x9b\xee\x15\x6d\x62\x5f\x76\xb9\x78\xb2\x88\x84\x0b\x92\x4c\xa4\x04\xf7\xf5\xed\x59\x34\xa2\xea\xe0\xb2\xec\x7b\x62\x8b\xfb\x3b\xe4\x06\x2d\x8a\x9d\x28\x07\xf8\x84\x48\x93\xd4\x2b\x4e\xf6\x3e\xc0\x1d\x54\x2f\x5e\xc7\x56\x8b\x34\xcf\x11\x89\x26\xca\x72\xd3\xbd\x3e\x7a\xc6\x20\x2d\x32\xa2\x13\xa7\x57\x66\x95\x57\x06\x7f\x7a\xfa\xb2\x79\xc6\xf3\xcc\x53\x6a\x04\xd2\x1b\x2d\x44\x14\x61\xf8\x43\x9e\x3f\x56\x95\xee\x77\xd5\x31\xd0\x4e\x08\xcd\x10\x7e\x24\xda\xe3\x7e\x84\xd6\xfa\x7b\x28\x2d\x21\x79\x2c\xbd\xdf\xda\xe9\xa7\x06\x56\x97\xd5\x82\x5a\x48\x49\xcc\x20\x7d\x77\x29\x5b\xf1\xa5\x71\xe4\xee\xa1\x92\x4c\x3a\xc3\xc3\x7d\x82\x95\x7e\x9b\xcd\x20\x05\x1a\xb3\xcd\xce\x6d\xfb\xa8\x74\xa1\xbe\x80\x83\x2f\x5b\x16\x42\xd3\x38\x73\xfe\xf4\xea\x63\x9e\x21\x17\x90\x73\xdc\xc5\x9d\xfe\x65\xf1\x06\x18\xad\x18\xf6\xaf\x19\xa9\xa2\x16\x00\x14\x03\x4d\xef\x00\x3f\xf7\xaf\x0d\x8c\x38\x0b\xb5\x00\x03\xc8\x96\xec\xcf\x55\x0f\xe8\x15\x86\xe4\x0e\x72\x61\x3f\x0a\x7a\x74\x30\xc0\x1f\x66\x5f\xdf\x44\x14\x41\xc1\xfd\x41\x75\xed\xb5\x3d\x97\xdf\xcf\x48\x83\xaa\x2c\xbb\x87\xa7\x71\xdc\x44\x92\x98\x20\xd9\x5c\x57\xdf\xd4\x0d\x28\xd1\x76\xa1\xe2\xd9\x73\x13\x0d\x54\xec\x63\xe4\xa5\x24\x59\xc6\x12\x67\x42\xd4\xb5\x41\x97\xf7\xf2\x74\x70\x9d\x69\x64\x30\x18\xff\x84\x21\xbb\xc7\x6a\x12\xbc\x91\x54\x31\x34\x37\x4e\x4d\xfd\xbf\xa0\x3a\x8b\x50\x0f\x8d\x86\xa0\x95\xbd\x7f\xdc\xdd\x17\xfa\x5b\x5d\x6a\xcc\xc6\x4e\xf0\x64\x92\xb1\x18\x47\xd4\xd6\xca\xac\xca\xd2\x1f\xa1\xbe\x5d\x50\x04\x8c\x6c\x8e\x27\x2f\xb4\xa5\x65\x94\xc8\x78\x3c\xda\x8e\xed\xb6\xa9\x8f\x7b\x10\xc7\x2f\x73\x7a\x32\x32\x0c\xa1\xb0\x96\x2a\xf1\xaa\xd0\xcb\x5b\x97\x4c\x98\x35\xc9\xd4\x94\xc1\xd2\x55\xd8\xb8\x4e\xa9\xa0\x08\x17\xc4\x63\xec\xba\xee\xae\x67\x9a\x60\x5a\xa6\x8a\x22\xbe\xcc\xe6\xf8\x8b\xee\xe3\xaf\xd5\x7a\xbe\x9c\xef\x32\x85\x08\xad\xfe\x11\x39\xdf\x6a\xb9\xae\x50\xcb\x8c\x44\x16\x30\x5b\xd6\xad\x53\x09\x3b\x0f\x0a\x1e\x5a\x66\x51\xcc\x1c\x20\x76\xf3\x26\xca\xf3\x05\xc3\xbd\x96\x19\x8f\x22\x47\xf0\x7e\x07\xe2\xe5\x0c\xcf\x58\x40\xb7\xaa\xf4\xba\xc6\x00\x49\xff\x41\x61\x10\xd6\xfc\x84\x67\x63\x3a\xff\x65\xc6\x73\x2c\x69\x38\x9d\xbb\xaf\xb2\xea\x32\x57\x5c\x0c\x91\x9d\x6d\xd5\x41\x75\xc1\x5f\xa4\xa5\x20\x12\x2b\x39\xee\xd7\x7b\xcf\xcd\x3a\xb2\x0a\xa5\x48\x28\x26\xfb\xad\xd2\xd4\x48\x0a\xd7\xb7\x6b\x2b\x50\x34\x24\x2d\xbf\x06\x48\x49\x01\x04\x45\x25\x36\xa2\xfd\x98\x2c\x07\x01\xb9\xc9\x3d\xc6\x72\xab\xea\xfd\xbb\x0f\x64\x4a\x49\x52\x4b\xeb\xc9\xb2\xdf\x46\x6c\xd7\x5a\x4a\x96\x22\x4f\xf7\xaa\x7d\x5d\x8b\xf6\x75\x72\x3f\x99\x1a\xee\xf6\x6b\x4c\x20\xf4\x46\x9e\x65\x20\x9a\x7d\x25\x99\xa5\xdc\xa1\xce\x9e\x9c\x78\xdb\x44\x4c\x4a\x4b\x29\x48\xac\x5c\x21\xc4\x35\x18\x71\x2e\x1d\x9b\xb4\xdf\xdb\xa4\x4a\x15\xd2\x67\xa2\x63\x36\x4f\xb6\xba\x3e\x10\x27\x86\x78\x30\xba\x41\xdc\xcd\x12\x93\xaa\x96\x90\x70\xbc\x99\x3d\xbb\xaf\xce\x1f\x73\x0b\x4a\x82\x96\x58\xf9\xb6\xeb\xea\xd3\x76\xed\x0b\x08\x15\x61\x16\xa6\x65\x8a\x53\xeb\xd5\x16\xa7\x2f\xab\x48\x6e\x85\xa8\x1f\xdf\x1f\xc7\xa3\xa5\x88\x4e\xb0\xec\xa0\xaa\x8f\x70\x78\x2b\x2a\x55\x74\x81\x83\x5b\x2b\x4a\x35\xda\xec\xd0\xbd\xee\xde\xc5\x69\xb4\xab\x2b\x1a\x5b\x63\xed\x79\x73\xb7\x59\xed\x36\x87\xfd\xf6\x7e\x13\xda\x72\x8d\xc7\x01\x6a\x5d\x1e\x8b\xaa\x68\x3b\x71\x11\xbc\x52\x54\x24\xd2\xb3\x57\xff\x2c\xca\x72\x62\x2d\x28\x0a\x06\x61\x04\x58\xd1\x70\x2f\x7e\x4d\x4c\x45\xc5\x22\x8e\x32\x53\x07\xa1\x03\x81\xe0\x97\x98\x40\xc5\x92\x0c\x21\x8b\xde\x91\x39\xfc\xfb\x3c\x4e\xe0\x8d\x75\xf1\xfe\x87\xcd\xce\x37\xc5\xb2\x44\xb8\xa9\xb2\xa9\xd4\x0e\xd4\x4f\x08\x8f\x12\xa5\x71\x94\xbb\xe2\x71\x51\x1e\x50\x05\x12\x25\xd6\xc3\x59\x39\xb9\x55\x94\x19\x45\x27\x14\x43\x8b\xdb\x90\xe2\x4a\x60\x40\xe7\xfe\x43\x59\x0d\x91\xb2\xa8\xc2\xe0\xc7\x99\xdd\x20\x91\xcb\xdd\xd5\xa5\xa9\x7a\xa6\xf6\xa1\x55\x2c\x8d\xd5\x6f\x40\x2e\xce\x50\x0b\x3c\x70\x97\x2c\xd0\xbe\x6b\x95\x10\xf0\xa0\xac\xdf\x8b\xae\xfb\x58\xc0\x02\xa9\x04\x6c\xd5\x83\xdd\xdf\xef\xc5\xaf\xbb\x7e\x2f\x3f\x37\xe2\x32\xd3\xa5\x52\xce\x12\x08\xec\x46\xc5\xf1\x7c\xbc\x2f\x2a\x24\x69\xf9\xbf\x67\x81\x72\x16\xcb\xa7\x8e\x4a\x55\x8c\x6f\xd9\x9e\x8f\xdf\x44\xa3\xd7\x62\x3c\xe7\x53\x10\x58\x52\xd4\x80\x82\xaa\x2b\x3f\xfa\x99\x00\xda\x27\x7a\x7d\xaf\x9c\x32\x1e\xd8\x50\xef\x6a\xa1\x41\x87\xb3\xc4\x73\x28\x84\xce\x92\x58\x19\xc4\xa7\xba\x2c\x2d\x78\xc6\xf2\xb6\x7d\x76\xe6\xfc\xcd\x7f\x7d\xe4\x54\xc9\x24\xc1\x8a\x78\x94\x20\x6e\xc2\xaf\x0a\x89\x7e\xd6\xf7\xca\xaa\x72\x4e\x58\xea\x67\x23\x22\x4d\x0a\x72\x26\x22\xeb\x42\x9b\x37\x23\x99\x72\xeb\x22\x4f\x68\xfc\xa6\x07\xb5\xd2\x51\x4c\x4d\x08\x0d\xa0\x54\xd5\xc9\x9b\x17\x4a\x27\x14\x51\x85\x96\x10\x7a\x02\x4e\xf3\xaf\xc4\x66\x26\x8f\x02\x0a\x08\x12\x52\xe7\xc6\x8a\x6f\x06\x34\x88\x02\x4d\x3d\x6b\xd1\xd3\xf6\x00\xba\xe8\x0e\x91\x2f\xc9\x55\x26\xce\xd1\x25\xb7\xec\x77\x1d\xd8\xd0\xc0\xa7\x79\x3b\x65\xa4\xf6\x75\xa6\x28\xbd\x38\x3d\xb6\x34\x21\xb6\xbc\x0d\x2b\x96\x6d\x75\x92\x3b\xe8\xa7\x82\x83\x5a\x13\x66\x88\xd7\xc9\xad\x8b\xca\x07\x2b\x16\x7f\x55\xd3\x24\x49\x23\x47\xbb\xbd\xd9\x7f\x9b\xfd\x28\xcb\x52\xdc\x95\x8f\x56\x9c\xf0\xe1\x66\x3f\x33\xd8\x34\xcb\x53\x5b\x47\x20\x0c\xdc\x7f\xa5\x87\xa2\x35\x93\x19\xd2\x86\xae\x77\x0f\x8f\xe1\x72\x20\x78\x82\xd4\x48\x97\x62\x6b\x9e\x8b\x63\x98\xb8\x3a\x8a\x19\x3a\xe5\x47\x2c\x23\xb2\xa9\xc5\xe9\x0b\xc4\x92\x69\x31\x89\x95\x39\x77\x31\x00\x8d\x74\x0c\x04\x8d\xd6\x07\x78\xdf\xd5\xe7\xee\x95\xd1\xf1\x41\xa1\xd3\x84\xe0\x7e\xbf\xd9\x7f\xdb\x3c\x1f\x56\xf7\x8f\xdf\x1f\xf6\xa1\x4d\x52\xb4\x47\xed\xf3\x3d\xd5\x75\x39\x05\x33\xea\x54\x51\x8c\x64\x56\xf0\xee\x05\x87\x96\xc1\xfe\xd3\xb1\xc8\x58\x82\x6c\xf4\x76\xc3\xaa\x9b\xe3\x10\x51\xd5\x59\x64\xc5\x86\xfa\x5b\x7e\x49\x34\xe5\xfb\x27\x1c\x05\x4b\x0a\x34\x79\x2d\x1e\xec\x4b\x8b\x45\xe7\x91\xc8\x46\xe1\x94\xf6\x16\x2a\x68\xfa\x73\xac\xdd\x86\x14\x8b\x16\xd4\x8a\xae\xdd\xd4\x75\x27\x45\x08\xe7\x69\x11\xa5\x48\xa5\x65\x4a\xf1\x09\x99\xb6\xd6\x22\x95\x98\xb0\x36\x67\xad\x27\x63\x2d\x14\x47\x75\x08\xbb\xbb\x1e\x8b\xea\xb4\x20\xac\xa6\xb5\x4c\x53\x44\x8c\x1c\x74\xd1\x3b\x32\xfe\x44\xd2\x2a\x62\xa9\xab\x95\x6b\x8a\xee\xe3\xa6\x3e\x57\x1a\xd7\xd4\x56\xff\x0a\x7d\x32\x40\xe8\x92\x29\x7e\x81\xbe\xab\x5f\x60\x81\xf4\x42\xf7\x9b\x13\xc6\x2b\xac\x6e\xff\xd7\xf6\xa9\xd6\x3c\xc9\xc7\x94\x44\x0f\xe2\x08\x7f\xf6\x5d\xe6\x5a\x1a\x43\xa0\x4f\xeb\x38\x42\x59\x5f\x7b\x42\x4d\x59\xe2\xb5\x06\x1a\xbb\x3b\x6a\x80\xa3\xcd\x70\xad\x1b\x31\x78\xfe\x1a\xa2\x9c\x8e\x94\x28\x9c\xb1\x61\xbf\xd2\x74\x09\x00\x89\x62\x2c\xae\x80\x4a\xff\x51\x37\x33\xa4\x3b\x50\xc1\xbd\x31\xe2\x4e\xd4\x81\x6d\x49\x03\xe3\x8a\x5a\xe8\xab\x39\x57\xda\xd1\x50\x2f\x7f\x55\x88\x22\x81\x11\x53\x5d\x6f\x43\x74\xe5\x93\xfd\x1c\xa2\x34\xc5\x35\x77\xbc\x80\xde\x43\x94\x2b\x6a\xc5\xb4\x7e\xdd\x8a\x76\x1c\xcf\x80\x08\xa4\x71\x51\x16\x3b\xf5\x37\x15\x34\x2f\x33\x6c\x38\x44\xc6\x16\x9a\x0c\x08\x63\x0b\xd9\xf5\x63\x07\x5c\x09\x4c\x9b\xff\x2e\x9a\xa3\xf8\xe4\x65\x38\x48\xea\x02\xab\x2b\x5d\x9f\xba\x61\x01\x42\x92\x27\xc8\xe9\x73\xb2\x15\xe2\x37\x80\x85\x22\x6d\x1c\xda\x05\x41\x04\x17\x26\x6a\xfa\xf5\x76\x6e\xb7\xeb\xd5\xd3\x05\x85\xc9\x02\x6f\x88\x86\x54\x1b\xcc\x5c\xda\x58\xcb\xa1\x36\x87\xf5\x6b\x71\x30\x75\x73\x78\xac\xe0\x30\xec\x5a\x90\xa9\x14\x3d\xfd\xab\xef\xff\xd8\x3c\x1f\x76\xfb\xcd\xd3\x81\x5f\xfc\x84\xf5\x1d\x66\x3f\x91\xe9\x08\xcf\x5d\xcf\x08\xd2\x5a\xf6\x58\x7f\xe3\x5c\x65\xc8\x64\xf1\x2a\x4a\x84\x6e\x34\x02\x25\xc0\x43\x33\x70\x44\xb9\x1d\x26\x05\x80\x7f\x14\xdd\xeb\x33\x18\x68\xa0\xba\x9c\x1f\x8b\x75\x27\x20\x1c\x61\x2f\xd6\xbe\xcc\x0b\x6d\x40\x08\x96\xa7\xe3\x5a\xb6\xb2\x9c\x51\xb2\xf7\x7d\x22\x64\x28\x38\x16\x81\x16\x6a\xa4\x90\xa9\x41\xe8\x1c\x0b\x34\xef\x3f\x7c\x7c\xc5\x37\x98\x44\x8f\x39\x19\x6e\xb6\xcf\xbb\xfd\xe1\x7a\xf5\x8f\xc3\xfa\xf1\x61\xff\xbc\xbd\xfa\xbe\xdf\x3e\x7a\xf8\x01\x48\x16\x21\xaf\xf7\x6e\xbf\x7a\xb8\x5e\x3d\x5f\x63\xd6\x3a\x34\xe6\x54\xa5\x01\xdc\xe1\x79\xa4\xa7\xef\x22\xb5\xad\x4c\xb7\xf4\xf7\x5f\x06\x1c\x40\x71\x25\x6d\x8c\x04\x25\x17\x0e\xed\x08\x6f\x02\x5a\x45\x89\xb3\xc6\x6f\xcf\xd5\xd5\xc7\x56\x3f\x89\x8b\x2c\x20\x40\xca\xa2\x31\x7f\xd7\xd5\xd3\x7c\x47\x30\x9c\x63\x96\xe1\xa6\x38\xb5\x0f\x75\x27\x42\x95\x3c\x18\x69\x61\x68\xaf\x20\x9a\x4e\x42\x60\x3e\x31\x24\x53\x48\x9a\x72\x1a\xe4\xd0\x1c\x5b\xd7\x28\x1f\x63\x68\x62\xb3\xff\xc8\x5d\xd6\x6f\x4c\x07\x51\xe9\x03\x86\xbd\x0f\x6f\x53\x4e\xe2\x71\xa8\xe9\xeb\xff\xef\xef\x9d\x69\x8c\xed\x1c\x6b\x0d\x33\x4f\xd3\xd0\x0c\x30\x78\xe4\xe6\xff\xbe\xfe\x36\x60\x8c\x7c\x97\x3c\x26\x16\xab\xd3\xed\xeb\x6b\x98\xd5\xec\x19\x26\x19\x82\x5c\x4f\xf5\x3b\x34\xd7\xf5\xfb\xa7\x3c\x47\xa1\x7f\xca\x22\x4f\x37\x8e\x2e\xb4\x53\x18\x75\x56\x0e\x7c\x8e\x8d\x32\x4c\x27\x58\x59\x7c\xb3\xbd\xfd\xb6\xbf\x7f\x7c\xd8\x78\x3a\x10\xc3\x89\x4a\x43\xd9\xa5\x55\x03\xb8\x1e\x5c\x4f\xc3\x05\xcb\x5c\x7d\x87\x17\x82\x16\x25\x5c\x8b\x8f\x55\xa5\x07\xbe\x59\x3f\x60\x5c\x6b\x8c\x54\x9b\xa2\x09\x59\x49\x13\x53\x4e\x5c\x84\x66\x6b\x3f\xe0\x5a\x54\x57\x58\xe3\x34\xca\x43\x99\x38\x8f\x11\xb5\xf8\xa3\x28\x4b\x51\xd5\x6f\xe2\xad\x7d\x16\xda\xd4\xa1\x82\xc5\x24\x92\x61\xa8\x07\x65\xf3\x9f\x47\x98\x25\x93\x26\x56\x1b\xaa\x77\xca\x11\x04\xdd\xbe\x0e\x18\x3f\x46\xc6\xd1\x74\x93\xa6\x8a\x78\x85\x78\x67\x3a\x3d\x9a\x70\x23\x95\xa1\x1a\xf7\xb1\xf6\x2b\xd7\x64\x89\x41\x83\x0f\x89\x64\x23\x76\x60\xe4\x40\xd9\xec\x4b\xe7\x94\x7a\x7a\xd5\x81\x15\xd3\xfd\xb8\xef\x12\x1b\xf4\x31\xbf\xad\xfe\xb1\x0a\x74\x44\x26\x4f\x32\x1b\xc4\x13\xcd\x56\xef\xeb\x67\x4c\x5e\xcd\xe6\x89\x20\x11\x82\xac\x8f\xb6\x5c\xcf\xe2\x90\xa6\x66\xb1\x11\x54\x61\x20\xe6\xee\xee\xc7\xe1\x2d\xa2\x07\x7f\x32\x18\xc9\x33\xee\xb4\xfc\xe1\xfd\x1a\x40\xcf\x9e\x5c\x71\x66\xd9\x1d\x35\x20\x3b\x63\xf1\x1f\x98\x95\xbc\x18\x95\xe4\x99\x2b\x15\x3b\xbc\x8d\x32\x4e\xed\x63\x55\x7e\xdc\xd7\x7a\xcc\x67\x61\x94\x60\x42\x07\x91\x5a\x57\xc6\xbb\x3c\x9f\x55\x3f\xa5\x31\xac\x55\x54\x3f\x8a\x52\xcc\x16\x98\x66\x19\x9a\x84\x78\xa6\xd9\x1b\xdd\xd4\xc1\x9f\xfe\x03\x8a\xfe\x10\xf0\x51\xcf\x7d\x3d\x91\xf6\xd5\x46\x67\x11\x9e\x19\xbb\xa7\xd5\x94\xe4\xc1\x80\x50\x88\x8b\x42\xff\x58\x94\x16\x73\xd4\x5f\x3a\x4b\xe3\x60\x77\x20\x44\xe6\x98\xcf\xf6\xec\x2e\x4e\x30\x63\xe9\x95\x80\x50\x2a\x29\x1d\xf1\xc1\xb5\x57\x42\xfd\x5c\xdd\x74\xd0\xac\xeb\x66\x8c\xa0\x04\x12\x31\x81\x09\xc9\xb6\x2c\x4e\xa7\x90\xba\x05\x82\x02\xa8\x83\x0e\x99\x65\xa1\x98\x0c\x0d\x90\x48\xc7\x08\xf3\x29\xda\x3d\xcc\x04\x55\x80\x70\x9e\x61\x11\x83\x7b\x9d\x41\xb4\x62\x7c\x16\x02\xe1\x71\x86\xec\x33\x98\x96\xda\x81\x3a\x63\xd5\xd3\x32\x30\x6c\xf6\x03\xd2\x30\x8b\x5c\x44\x16\x97\xdd\x6b\x71\x1a\x7b\x7d\x99\xeb\x16\x67\x16\x17\x6d\xa5\x27\xce\x9e\xdd\x66\x88\x6b\x01\x89\x55\x8e\x5d\xbc\xa7\x54\x5d\x7d\x5c\x41\x05\xa6\x50\x45\x38\x20\xfa\x5e\x22\x75\xe6\xe2\xe1\x09\x2a\x5d\x54\x2f\xb7\xe3\xd4\xd5\xa5\xea\x9d\x9f\x8e\x40\x62\x20\x88\xeb\x84\xde\x56\x18\xaa\xe1\x80\x24\x49\x84\x0c\x90\x68\xc6\x5e\x37\xe2\xdd\xd5\x00\x87\x76\x09\x58\x2d\xa2\xeb\xf7\x0a\x5f\x73\x5f\x5f\x89\xb6\x50\x93\xe5\x03\x24\xcd\x09\xb2\x4c\x43\xa5\xaf\xce\x03\x71\x26\x90\x8c\xa4\xe8\x6b\x57\x48\x5e\x7a\xd5\x29\x5b\x17\x1b\xee\x9f\x45\xb6\x86\xf2\x74\xee\x76\x5d\xdd\xdb\x32\x57\xdd\x65\x49\xc6\xdf\x25\x9d\x5f\x04\x00\x85\x5f\x32\xa9\xad\x0c\xfc\x2c\x87\x03\x24\x8b\x15\x82\x31\x85\x45\x4d\xed\xeb\xc7\xd2\x7a\x49\x5e\x74\x68\x1a\x5e\xe9\x2f\xd0\x76\x13\x9d\x57\xec\xf6\xf7\xe5\x2e\xe9\x36\x9d\x70\x59\xaa\x89\x0b\xc6\xd9\x52\xfb\x12\xb1\x55\xb3\xb8\x2b\x90\x9c\x32\xb4\xd3\x7f\x17\xd5\xcb\xe6\x71\xe7\x07\x2c\x8f\x0c\x16\x38\xf7\xdb\xf6\xd3\xb9\x2c\x91\x95\xa2\x39\xfb\x63\x06\x48\x9e\xa5\x68\x2e\xbc\xc1\x6b\xa1\x4a\x40\x4f\xec\x93\x65\x2a\x22\xe6\xd3\x0a\x03\x5a\x70\xd6\x25\xa6\x08\x93\xda\xbf\x43\x50\x9f\xf4\xbf\x24\x52\x21\x1d\x1b\xdf\xe3\xc3\xed\x61\xf5\xfd\x7a\xbb\x9f\xc3\x8b\x27\xaf\x2e\xa4\x40\xc3\xd9\xd4\xe7\xa6\x7b\x3d\xb8\x1a\xf6\xf9\x2f\x6a\x86\x16\xe2\xfe\xe9\xab\x42\x50\x20\x02\x34\x42\xd9\xf6\x0d\xc0\x53\x39\xd1\x63\x02\x22\x53\x40\xec\xb8\x85\x39\xe0\x66\xa9\x6a\x0d\x8d\x35\x96\xad\x4b\xf2\xf5\xea\x56\xd4\xa0\xcd\x63\xa0\x53\xaf\x0f\xf0\xab\x9b\xd6\x2c\xbb\x5e\xda\x49\x39\x3a\xf2\x78\x1f\xe2\xa8\x9b\xc0\xc4\xe7\x3b\x1a\xa9\x03\x23\x93\x45\x77\x2e\xe3\xde\x81\x80\x01\x84\x36\x9f\xce\xdd\x55\xa7\xfa\x27\xde\xfd\x7f\xb4\x24\x8c\xd6\xe8\xcc\xa3\x11\xf5\xad\xd6\xe5\xb2\x02\xc2\x64\x60\x28\xc9\x19\x16\xd4\xb8\x30\x2c\x2a\xbd\xf9\x04\x80\x05\x24\x4e\xc3\x2c\x93\x97\xa3\x24\xb7\x18\xf8\x63\x51\x5d\x15\x7e\x17\xa2\x94\x49\xe3\xd8\x9f\xd4\x33\xb4\x0b\x82\x2b\xb3\x87\xa0\x0c\x74\x3a\x82\x9b\xd7\xc5\x27\xfe\x2e\x50\xca\x63\x94\x8f\x7e\x7a\xde\xfe\x58\xed\x37\x07\xac\x53\x5f\xad\xd7\x43\x30\x09\x28\x4d\x39\x35\x63\x45\xce\xbf\x18\x03\x9a\x69\x2c\x0a\xeb\xed\x80\x36\xe0\x57\xfa\xbf\x1b\xbc\xcf\x3b\x14\xf7\x05\x32\x14\x05\x51\x29\xa0\x54\xa6\xc8\xf0\x2c\x45\xa7\x5e\x57\xd3\xa2\xfa\x0b\x53\x15\x28\x85\x28\xcd\xbe\xe0\x6b\x9e\x0d\x2c\x4b\x85\xb4\xf6\xff\xaf\xa7\xda\x27\x2d\xfa\x3f\x83\x15\x9c\x13\x06\x0e\x42\xcf\x4e\x75\xca\xf2\x3c\x71\xdc\x6a\x0a\xfe\xf0\xe8\x3c\xa0\x3c\x4e\x31\xe5\x5f\x54\x05\x9e\x54\xed\x65\x1a\x3e\x3c\x68\xcc\x34\x16\x8c\x1d\xc5\x2f\x2b\x1d\x3b\x56\x6d\x05\x1a\x47\x3c\xd1\x21\x5c\x62\x69\x10\xd7\x75\xd5\x76\x8d\x28\x2a\xa4\xf9\x0c\x6f\xb4\x90\x44\x01\x1a\x27\x09\xee\x97\xa7\x83\x75\xf4\x06\x43\x65\xf6\x2e\x31\x58\xa8\xe1\xad\x05\x82\x20\x83\xdd\xe5\xb2\xa9\xeb\x72\xb2\x8f\xd0\x24\xce\xa8\xd7\x42\xb9\xba\x5f\xff\x3f\xa1\x1a\x80\xa6\xb1\x42\x08\xdd\x4b\x5d\xea\xef\x9e\x00\xd0\xb7\xc9\x0c\xad\xf1\xe3\xb9\x43\x59\x76\x21\x9f\x46\x04\xf6\x9f\xdc\x30\xa3\x14\xfd\x90\xd5\x6b\x5d\x97\x30\xce\xe2\x03\xcd\x98\xc6\xf0\x86\xd0\x7a\x07\xa5\xea\x6e\x90\x61\xf9\x1a\xc4\x40\x21\xfa\x37\x1f\x3b\x03\xcb\xa9\xd6\xbb\xc5\xc5\x11\x8a\xea\xbe\xa8\xce\xc3\xb1\x4c\x45\x14\xa5\x83\x0c\x93\xdf\xb1\xda\x75\xbd\x24\x96\x0d\x54\x70\x86\x86\xd8\xc9\xfa\x1c\x76\x87\x2d\xa1\x6d\xf7\xa2\x45\xcd\x8b\xde\xfa\xfd\x1b\xea\xb6\x40\x45\x1e\x11\x17\x6b\xbf\x13\xad\x25\xff\xf1\x0f\x25\x89\x46\x0a\x50\x47\x28\xf1\xa3\xee\xa0\xf9\x92\x4c\x02\xa8\xe4\x09\x5a\x77\xff\x3e\x8b\x12\x0d\xf6\xc5\x2d\x97\xca\x58\x46\xe0\xa4\xfc\x37\xa2\x29\x3f\x10\xc0\xcb\xc3\x0f\x8b\xc4\xab\x36\x5a\xe4\xbd\x4b\x0c\x4e\x7f\x4b\x11\x8b\x15\x51\xe2\x54\x74\xa2\x1c\x68\x60\xfc\x6d\x14\xd3\x88\x9c\xf7\xbb\xe5\xef\xf0\xb1\x68\x93\x52\xa5\x28\x66\xc3\xcc\xb9\xd2\x5e\xe8\xc7\x35\xe9\x8c\x62\x45\x8b\xad\x1f\x9a\xa5\x1d\x67\x63\xa9\x05\xe1\x89\x93\x08\x45\x1c\x66\xef\xe0\x4d\x72\x33\xee\x20\xa0\xc0\x72\x3c\xec\x2c\x40\xe0\xf4\x31\xc2\x26\x03\x05\x21\xa3\xfe\xbd\x7e\x7c\xdf\x6f\x76\xfb\xf0\x24\x46\x13\x1d\xfc\x92\x15\x02\xec\x17\x59\x20\x80\x11\x93\x22\x24\xf1\x9b\x68\x5f\xab\x5a\x03\x56\xc5\x04\x30\x1c\x30\xca\x01\xc9\x39\xec\x4e\xe7\x10\xeb\x73\x7b\x88\xd1\x38\xc2\x58\xea\x5b\x01\xef\x23\xeb\xf8\x1a\x3a\x51\x94\xed\xbc\xb3\x24\x38\x21\xd7\x9c\x8c\x7f\x29\xca\xc1\xd3\x18\x7e\xab\xcf\x53\x07\x13\x58\x04\x80\xda\x3e\xf0\x0b\xd4\xd9\x95\x43\x7e\x6a\x5c\x2f\x4e\xdf\xfe\x16\x18\xe2\x46\x66\xcf\x6f\x75\xd3\xfa\x12\x3a\xd7\xce\x8d\x92\x8e\x31\xf8\x5b\xa1\x26\x36\x0b\x8b\xb9\xc0\xf8\xc0\x3f\xf6\x41\x20\x2c\x34\xc5\x29\xa2\x08\x0f\xc8\x05\x79\xe8\xea\x9f\x15\xd2\xbe\xb5\xa0\x6a\xef\xfd\x03\x8b\x21\x8b\xd2\x49\xc2\x25\x68\xdb\xfb\x1e\x46\x7b\x16\xdb\x7e\x75\xed\x3a\x18\xca\x73\x80\x25\x44\xb0\x31\x71\xb5\x0b\xa9\x8d\xab\x50\x80\x25\x0c\x78\x12\x24\xde\x35\x3c\xf6\xd6\xbe\xab\x09\x9a\x8e\x45\xc2\x89\x4e\x02\xf9\xc7\xba\xac\x5b\xd4\x77\x9a\x9b\x98\x2c\x65\xb9\x65\x20\x6a\x9f\xe1\xcd\x0a\xcb\x8e\xe7\x1f\x4b\x81\xca\x31\x35\x75\xff\x58\xdd\x35\x08\xbd\xa0\xef\x0e\x2c\xcb\x2d\xb1\x17\x32\x55\x36\x37\x05\x94\x3a\xf2\xcf\xae\x13\x85\x80\xb9\x03\x1c\x8b\xce\xb3\xbf\x7f\xad\xf8\x04\x4c\xa7\x96\xfa\xdf\xfb\xb2\x23\xc7\x8d\xe9\x54\x83\xaf\xf9\x18\x24\x88\xb6\x95\x2a\xcf\xbd\x7b\xb6\xf5\x25\x67\xcb\xa6\x09\xd3\x5a\x26\xe3\x8c\xf6\xff\xd6\xcd\xc0\xb7\xb1\xe4\xcd\xfd\xd7\x78\x5c\x20\x23\xee\x60\x0d\xac\x18\xed\x4d\x59\xd7\xcb\x59\x29\xef\xaa\x31\x80\x08\x43\xf0\x1a\xe4\xf9\xe5\xd0\x1b\x50\x1d\x52\x34\xba\x66\xa3\x20\x72\x05\xa0\xab\x73\x57\xbb\x13\x6d\x70\x25\x99\x81\x80\x03\x78\x80\xf7\x91\xfc\x21\x44\x84\xf0\xc4\x95\x06\x0d\xd4\x60\x10\x91\x2c\xca\xac\xe7\x55\x5a\x81\xcb\x19\x2c\x03\x22\x1a\x19\xac\x7f\x3a\x78\x63\xa7\x1c\xad\xce\x4f\xc2\x92\x10\x51\x95\xa6\xae\xaa\xed\x9f\xf5\x65\xc9\x3d\x44\x8c\x32\x7c\xd4\x27\xed\x8b\x14\xa6\x3f\xcb\x18\x43\xeb\xfd\xea\x66\x9c\x77\x84\x88\xc5\x71\xe6\x65\x9f\x3f\xdd\x00\x46\x0f\xc2\x12\x5b\x62\xd6\xf7\x9f\xac\xf7\x88\x49\x10\xcc\x73\xb8\x7a\x12\xc8\x27\x68\x7c\xd0\xdc\xf7\x8b\x54\x94\x7a\x39\x3b\x04\x6a\xfd\x9a\x59\x37\x11\x8f\x25\x46\xb2\x6f\x84\x65\xd8\x1a\x3d\x2e\x37\x11\x02\x0e\x8a\xf6\x7b\x0b\xcd\x37\xd1\x3e\x41\xd3\x2f\xfc\xba\xda\xd7\xf7\xb5\x2e\xcc\xf2\x31\x13\xc5\xd4\x12\xef\x96\x75\xd7\x81\x85\x64\x0f\xdf\x32\x66\x9a\x0f\xcc\x70\x83\x4c\x7d\xf7\x0a\xd0\x88\xcb\x78\x4b\x94\x50\x86\x48\x06\x09\x5d\xfb\x47\xd8\x72\xa2\x84\x29\xdc\xdc\xad\x36\xe8\x88\x9f\x19\xa2\x24\x4a\xb0\xe9\xea\xfc\x61\x4b\xaa\xbb\xd7\x77\x81\xc4\x0c\xe3\xe8\xc7\xe2\xd2\x89\x92\x38\x15\xb1\x87\xb4\x54\xa6\x78\xd9\x54\x5d\xf3\xb1\x1d\x11\x4d\x4e\xfb\xa7\xb1\xc5\x41\x20\xf1\xec\x63\xf5\xdb\x78\x1e\xa5\xb9\xf6\x95\xeb\x36\x94\xeb\xfe\x9e\x09\x86\x26\xb5\x76\xa7\xe7\xe4\xe1\x33\x2d\x9c\x1e\x7d\x7f\x4a\xdf\x94\xb3\x02\x16\x88\x72\x96\x60\x49\xd5\xfb\x9c\x92\x79\xf1\x08\x09\x97\x49\xce\x30\x37\xa3\x44\xc8\xac\xcc\x66\xad\x54\x29\x86\x32\x57\x47\xf1\x9f\xa2\x7a\xb9\x9e\x25\xde\x21\x52\x39\x20\x72\xe8\xdf\x6d\x28\x9e\x80\x48\x49\x91\x99\xb0\xd7\x78\x0e\xfe\xeb\xab\xf9\xb5\xc0\xd1\x13\xbb\xdd\x6d\x1e\xfc\xa5\x3a\xe1\x18\xa3\x79\xed\x1d\x97\xa2\x7a\x69\x1f\x00\xb4\x87\x8f\x42\xa4\x05\x70\x97\x35\x2c\x8e\xe7\x63\xbf\xf2\x31\x17\xf4\xbd\x2a\x82\x17\x10\x69\x90\x58\xbc\x78\xff\x71\x6f\x11\x0b\x97\x08\x1f\x88\xb4\x31\xe8\x21\x61\x58\x6b\xed\xb5\xdd\x3e\xd5\x1b\x59\x3e\x83\x7b\xef\x1f\x99\x40\xda\xae\x3e\xdd\x17\x55\x17\x32\x68\x10\x01\x64\x98\xe4\x7e\x80\xf7\xff\x7b\x86\x16\x8d\xb3\x31\x0a\x2b\x7c\x05\xc3\xc1\x52\xaf\x80\x28\x37\xad\x35\xdf\x3f\x4e\x5d\x7d\x73\xae\xb4\xcb\x36\x4c\x9f\x9d\x13\x21\x24\x1f\x14\xcd\x55\x37\x16\xc0\xfe\x9f\x6c\x8a\xee\x02\x4e\x59\x8c\xa5\x1f\x1b\xd1\x7a\x5f\x8d\xd3\xd8\xaa\xd1\x2d\x06\x93\xc6\x66\xde\xd2\x78\x2c\x57\xbf\x8d\x7e\x50\xc7\x1e\xc6\x63\x15\x00\xfb\x25\xf7\xad\x7e\xc7\xb2\xfa\x0b\x2f\xd4\x5d\xc4\x52\xc8\xf2\xf0\x52\xdf\xea\xb6\x5b\x55\x1a\x49\x10\xea\x66\x7d\x9e\x6d\x51\x9c\x09\x8d\x19\x82\x6d\xd5\x76\xa2\xea\x0a\x9f\xf5\x03\xce\x40\x63\xe8\xfc\xa9\xa9\x5f\xfa\x1f\x2a\x9c\x55\xf1\xdb\x17\x0c\xaa\x17\xff\x4e\xc7\x3b\x92\x09\xda\xc8\xd2\x69\x6a\x3f\x9a\xd9\x07\x89\x20\xc3\x0f\xb2\xaa\x8a\x23\x7c\xae\x84\x0c\x9c\x53\xb0\x65\x05\x96\xbb\xe5\x6b\x73\x80\xf3\x98\xa3\xfd\xb3\xdb\xaf\x9e\xf7\xdb\x87\xdb\xc3\xef\xdb\xbb\x10\x9d\xe3\x3c\x8e\x2d\xc2\x27\x54\x9c\x4e\x34\x22\x81\xf3\x24\xc7\xb0\xf6\xb5\x27\x9e\x06\xce\xd3\x44\x44\x33\x80\x95\xb3\x1b\x02\xf9\x7a\xd5\x7d\x12\xde\xe0\x31\x31\xc6\xf8\x6c\xd8\xb5\x05\x67\x4f\xc2\x74\x3c\x4e\x62\xed\xf9\x74\x36\x4d\x53\x37\xdf\x2b\x11\xd4\x20\x1f\xc4\x31\x44\x6f\xbc\x69\xcf\x13\xc2\xa5\xad\xfa\xf2\x1a\x0d\xa1\x41\x60\x0a\x66\x28\x3e\xbc\xaa\xeb\x9f\x73\x86\x52\xe0\x09\x58\xc3\xc6\xd4\x4d\x77\xae\xe0\x00\x95\x16\x0b\x8c\x14\xc0\xd3\x84\x60\xde\xe7\x58\xbf\xc1\xe7\x20\x34\xe0\x59\x6c\x89\x4a\xb0\xbe\xba\x3e\x9f\x2e\x44\xc3\x80\x67\x19\x43\x72\x01\x37\x86\x6b\x1f\x36\x31\x45\x73\xbc\xd4\xa4\x73\x17\xe5\x24\x4d\xc7\x15\xe9\xa6\xac\x7f\xf6\x6e\xd9\x27\xca\x6c\xd3\x5d\x82\xe7\xa9\xe5\x58\xfd\xf1\x78\xf7\xfd\x7e\xe3\x93\x4d\xc0\xf3\x8c\x21\x54\xd8\x13\x47\xab\x9f\xd0\xad\xc5\x69\xf6\xc0\x79\xae\xdd\x97\xd3\xbf\xff\x63\x3d\x9b\xbd\xb9\x04\xed\x92\x4d\xe3\x43\x6d\x72\x03\x91\x5b\x36\x5a\xa8\x4c\xdd\x28\xd8\xa1\x33\x30\x26\x87\x98\xbd\xac\x64\x44\x0d\x14\x74\xb7\xe2\x68\x59\xc5\x4c\xa1\x3e\x89\x87\x73\xc9\x62\x47\x64\xe2\x02\x00\x17\x4e\x2d\x97\x5a\xe1\x31\xf7\x2a\x5a\x37\xef\x5c\x6e\x02\x29\x1b\x67\x7e\x19\x97\x00\x96\x9e\xf3\xf1\x2e\xcc\x7f\x45\x6c\x45\xab\x15\x17\x3f\xd0\xd9\x30\xa9\x3c\x8e\xf8\x38\x72\x7a\x84\xaa\x0b\x12\x69\xc0\x75\x4e\xd1\xfa\x19\x84\x85\x0c\x65\x97\xc2\x42\xc0\x81\x58\xb1\xc2\xaa\xee\x0a\xf3\xf1\x68\x56\x8d\x2c\x3a\x0b\xfc\xf3\x85\xcd\x8b\xfe\x2b\x37\x3c\x47\x58\x46\xdb\xcd\x59\xbf\x81\x1b\x23\x7c\x39\xf7\xf6\x28\x46\x90\xa6\xa1\x4e\x63\x71\x68\x63\x92\xa5\x4a\x85\xf4\x6b\x5b\xa8\xfd\xeb\x70\x50\xc5\x44\x12\xe9\x71\x0b\xb8\x5d\x5b\x72\xb9\xc9\x73\xc5\x44\x03\x72\x13\x05\x15\xd4\x09\xd8\x06\x62\x4a\x32\xfc\x7a\xfe\x3c\x79\x7c\xda\x0d\x00\x23\x88\x99\x8e\x31\x35\x58\x9f\xa0\xba\xaa\x7f\x8d\x63\x7c\xae\x47\x44\x01\xe7\x31\xc2\x96\x71\xbe\x20\xa4\x66\x3a\x04\x71\xa4\x14\x2a\x51\x09\xd5\x9d\x85\xad\x82\xba\x2e\xde\x8a\x76\x06\x7e\x87\x98\xf3\xb0\x88\xaf\x8a\xae\xad\x27\xb9\x5b\x88\x79\x92\x20\x6f\xb4\x0f\x56\x5c\x9f\x45\xf9\xf8\x5e\x4d\x44\x66\xa7\x03\x10\x83\x40\x44\xf0\x49\x34\x56\xa1\x22\xe0\x6c\x7d\xc4\x6a\x36\x62\x09\x8d\x11\x71\x75\x53\x9f\x27\x26\x74\x9c\x64\x06\x79\x83\x31\x76\xf8\xd1\x6e\xab\x47\x63\x02\xfa\x09\xe2\xc4\xd8\x7a\x01\xe4\x8c\xfc\xa8\xe7\x27\x5f\x9c\x46\x16\xf2\xbb\xf1\x9a\x25\x56\xdf\xc0\xb5\x66\x89\x40\xcb\xf8\x0a\x1c\x21\xa3\x97\xb3\x5b\xcc\xb4\xc6\x59\x4e\xe2\xc1\x2b\xfc\x1d\x3e\xda\x89\x8d\x42\xc3\xe7\xc9\x04\x4f\x1c\x5d\x03\xea\x4c\xa2\xb8\xac\x6f\x53\x71\xa6\xdc\x04\x9a\x0d\x42\xce\xac\xf8\x73\x28\x59\xb6\x3e\x9c\x3d\x83\x67\x5d\xa3\xc8\x0c\x64\x89\xab\x81\xc5\x2a\x3c\x83\x60\xc4\x6a\xac\x7c\xac\x50\xf7\xdd\xff\xbe\x50\x2c\xb3\xe9\xdb\x97\x97\x32\x28\x57\x86\x6f\x2d\x69\x0c\x01\x91\x5e\x54\xbe\xce\x76\xfa\xeb\x32\x86\x28\x90\x8f\x80\x42\x95\x0c\x8c\xfb\x7e\x9e\xe8\x8c\x65\x6a\xcb\xa0\xf6\xef\xf5\x53\x6f\x3b\x7b\x82\x11\xdf\x0c\x02\x41\xa1\x28\xc6\x37\x46\x17\xbb\x76\x05\x40\x42\x36\x78\xfb\xf8\x7d\x2e\xf0\x3b\xed\xad\x63\x3b\xf3\x5b\x5f\xfd\xb7\x72\x01\xcb\xe9\x07\xd5\x39\x41\x92\x0b\x71\x76\x2a\xf1\xbb\x90\xa0\x87\x58\x0b\x43\x98\xc7\x9d\x58\x1a\x59\xdf\x04\xda\x62\x35\x9f\x37\x37\xdf\x1f\xae\x91\x0d\xfa\x70\xfd\xfd\x79\x35\x20\xa4\x20\x06\xa3\x73\xe6\xd4\x13\x9b\xc0\xdf\x3c\xa7\xb8\x81\xd8\x48\x40\xa6\xea\x87\xc7\xfd\xc3\x28\x22\x16\x1b\x9d\x63\xd0\x52\xfb\x42\x38\xe7\x0c\x3e\x5c\x6a\xd1\xda\x08\xc4\x64\x04\x12\xc2\x0d\x1f\xe3\x2f\x57\x42\xbf\x8a\xc6\xc7\xe4\x96\xf4\xd4\xfd\x85\x69\x2c\xb8\x4d\x86\x74\xa5\xf5\xac\x3c\xfa\x04\x12\xa2\x32\xac\x3a\xb2\x08\xcd\x7b\xd0\xc5\x25\xc6\x1f\x12\xa6\xb3\xc8\x89\x5f\x58\x69\xcc\x47\xe3\xb8\xd4\x66\x3b\x54\x12\x13\x45\xe3\x51\x60\x4c\x20\x51\x82\xff\xb5\x58\x50\xb4\x41\xca\xba\x7a\xb9\x9f\x51\x84\x0c\xf7\x48\x63\x35\xad\x3e\x40\xab\xf3\x0a\xb5\x1f\x37\x8b\x51\xf1\x24\xcd\x38\x6e\xe2\xab\xfd\xdd\x78\xb3\x49\x32\x4a\x73\xe9\x75\xbf\xe5\xf9\xc5\x3e\x3d\xfb\xe4\x87\x33\x1a\xe1\xb6\x68\x29\xf3\x9b\xfa\xb4\x1a\x55\xe8\x43\x92\x25\x4e\xe8\x15\x2d\x98\xe5\x8d\x32\xc9\x84\x88\x84\x8f\x61\x9d\xac\xa3\x3f\x1f\xa4\x4c\x03\x9a\xa1\x57\xfd\xaa\xb1\x27\xf9\x0e\x9a\xb7\xcf\x40\xa7\x90\xe4\x91\x41\x2c\xd5\xea\x74\xda\xcd\xb8\x91\x21\xc9\x93\x4c\xba\x30\xa1\xc3\x4b\x05\xb0\x30\x24\x22\x4e\xac\x8f\x6b\x29\x06\x11\x8f\xb0\x14\xa1\x48\x44\x22\x22\x1b\x53\x08\xf1\x80\x5d\x10\x52\x83\x44\xd2\x44\x3b\x96\xd0\xdd\x6b\xfd\xbe\xad\x3a\x68\xde\x66\x2c\xce\x90\x28\x62\x11\xdd\x48\xbf\xd1\xb4\x36\xd5\xdd\x9f\x2a\xe3\xe4\x42\xa2\x39\x78\x1d\x99\x47\x84\x94\xbb\xfb\x70\xe2\x3b\x24\x22\x91\xbe\x52\x16\x8f\xb7\xc5\x5c\x42\xa2\x13\x4d\x64\xd8\x33\xef\x45\xbf\x2c\x94\x68\x2e\x8b\xd3\xb1\x2b\x16\x78\xfa\x79\xb9\x72\xd9\xc7\xf9\xa7\xd1\x79\x3a\x32\xc3\x2c\x5c\x79\xd1\x4e\x4e\x80\x58\x45\x33\x0c\x3a\xf4\xe7\xc1\x98\x75\x02\x12\x60\x02\x6b\x0a\x0e\xc7\xa2\xea\xac\x5f\xbb\x3c\xf0\x20\x04\x71\xf8\xce\x50\xca\x30\x7d\x76\x43\x29\xc2\x92\x64\x6f\x77\x3d\x9a\x99\xf7\x95\x18\x4e\xd1\x03\x40\xe2\x08\xe4\xa9\x84\xee\x62\xce\xa5\x24\xcf\xd1\xf4\x2b\xda\x6b\x70\xf5\xad\x17\xc1\xbe\xcb\xc0\x5f\x4a\x63\x8d\x51\xb5\xb2\x7e\x79\x6a\xea\x63\xd1\xc2\xcd\xb9\x34\x45\x59\xce\xcf\xd2\x94\x51\x42\xe3\x81\x0b\x6d\xfe\xfb\x4c\x32\xe9\x9c\x62\x2b\x87\xf2\xb9\xf8\x03\xa4\x4c\x1b\x8c\x73\x98\x89\xc8\x39\xa4\x09\xa1\x99\x97\x09\x87\x5f\x5e\x1f\xf6\x2a\x04\x01\xd3\x84\x72\xac\x97\xdf\x6f\x37\xcf\xd1\xe1\xe9\x79\xeb\xa5\x02\x21\x4d\xb8\xc1\xb0\xd4\xc1\x46\x53\x31\x7c\x3b\x66\x86\x75\xdd\x52\xce\x51\x3e\x17\xbf\xdb\xe7\x78\x9f\xa1\x04\xc7\x5f\xa7\x95\x71\x73\x76\xd0\x5c\x6b\xbf\x1e\xe3\xc9\x48\x67\x89\x75\xdc\xaf\x0b\xf5\xf3\x15\x84\x5e\x07\xa6\x3f\x48\xb3\x4c\x7a\xaa\x61\x67\x3f\x2f\x56\x38\xf8\xde\xc2\x60\xfc\xf2\xd9\xea\x8b\x37\x36\x55\x6c\x49\x49\xc4\xa7\xce\x79\x9a\x29\x83\x0e\x1a\xda\xb0\x96\x2c\xe2\x06\x60\x30\xff\xd3\x3c\x83\x2c\x1a\x1b\xc1\xfd\x3a\x1b\x65\x3e\xa6\xb7\xcb\xf3\x08\xcf\x0c\xcb\x6b\xea\xd9\x8a\x7d\x23\x70\x44\x8c\xa9\x73\xdb\xd5\x47\x68\x9e\xea\xb2\x50\x23\xc1\xa7\xd9\xa3\xc9\x24\x43\x7e\x9d\x87\xab\x05\x7e\x96\xaf\xca\x16\x20\x95\x92\x23\x82\xd3\x5b\xe6\xbf\x7f\x28\xcb\x4d\xf1\x5a\x9c\x3e\x19\x3f\x25\x09\x42\xdf\x6d\xb1\xff\x25\xf1\x28\xa4\x9a\x64\x98\xdc\x82\x63\xd1\xa1\xfe\x02\xaa\xc2\xea\xc5\xae\x54\xa0\xf3\xe1\x6a\xa6\x07\xaf\x6e\x5c\x0f\x09\x29\xb0\x18\xd1\x4d\xbd\x55\xfc\x51\x89\x63\xa1\xd6\xa2\xd1\x23\x2e\x82\x79\x94\x29\x85\x88\x20\x25\xc5\xa9\xae\xcb\x61\xc6\x85\xfb\x71\x66\x86\xc2\xab\xd2\x05\x92\x7c\xb8\x62\x3c\xef\x20\x25\x82\x7b\xf4\x1f\x56\xa5\x4e\xe2\xea\x29\xa4\x11\x71\xdc\x46\x36\x60\x82\xe5\x64\x6f\xd0\xec\x6b\xfb\x78\xfd\x2b\xbd\x7f\xe6\xf6\xa7\x86\x25\x18\x3d\x7e\x85\xa6\xde\xea\x7d\x6d\xeb\x5e\xa7\xaf\x62\x62\x2e\x86\x00\xf8\xea\x74\xb2\x61\xad\xe0\x14\x64\x24\x8a\x30\x0e\xdb\x9e\xe5\xb6\xdd\x09\xb3\x5c\x55\x09\x19\x51\x12\xfd\x2c\x8c\xd0\x7c\x5f\xe0\xd5\x74\xfd\xa8\x14\x58\x51\x7b\x6a\xc0\xf1\xbb\xe9\x21\xca\x9a\x51\x1d\x23\x00\x3d\xcc\x73\x4f\xed\x3b\x97\xb5\x84\x8c\x91\x18\xf3\xcc\x42\xeb\x0b\x42\x93\xff\x9a\xe8\xa7\xfb\x0b\x40\x89\x50\x71\x81\x8f\xf4\x58\xcd\x2c\xe3\x2c\x32\x09\x6e\x62\x0f\x85\xfa\x09\xe5\x20\x4b\xd4\xb7\x80\xe7\xbe\xbb\xff\x40\x47\xc4\x9b\xf9\x19\x97\xcc\xbd\x52\x81\x6c\xf2\x4f\xa2\x6d\xe7\x05\xe8\xae\x6b\x1c\x51\xe6\x0a\x4c\x6e\x45\x7b\x53\x37\x7f\x8a\xf3\xec\x11\xe2\x94\x22\x3a\xef\x28\x9a\x9f\xd0\x15\xd5\x8b\xc7\xfc\x87\x76\xfb\xde\x48\x64\xb4\xad\x3c\xef\x52\xef\x06\xb0\xd0\x27\x37\x6a\xe0\xbf\x19\x05\x65\x66\x1f\x2d\xa1\x89\xd5\x0d\x84\xee\xea\x5c\x96\x0b\xfc\x1b\x90\x25\xa9\xad\x47\x47\x3b\xae\xf7\x59\x75\x7d\x0d\x9b\x56\x9d\xa1\x14\x17\x11\xa4\xd9\xa5\x59\xa2\x7c\x1d\xf2\x59\x2e\xee\x55\x59\x22\x18\x12\x42\x0f\xe4\x09\x9f\x92\xa4\xcc\x52\x83\x59\x4a\x74\xe2\xa6\xe6\x37\xd1\xbe\x36\x9f\xe9\xa5\x40\x96\x66\x89\xb0\x24\xb3\x68\x8c\x8d\x6b\x4f\x7d\x0f\x6d\x69\x68\x3b\x8b\xfa\xc5\x3c\xd6\xe6\xdc\xd4\xeb\xa1\x6a\x0a\xb2\x8c\xa6\x5e\xe4\xd3\x01\x90\x27\x56\x6a\x96\xe9\x3c\x92\xfe\xac\x50\x75\xa3\xa1\xd9\x5e\xcf\x7e\x28\x8f\x2c\xc1\x68\x59\xfb\xda\x1d\x7f\xb5\x20\x31\x52\xe1\x5f\x15\xa8\x58\x32\xfc\x59\x22\x94\xbc\xbf\x40\xd7\xef\x61\x42\x8a\xd4\x66\x5e\xfa\x53\xa0\xdf\x83\x30\x2a\xb4\x90\xff\xcb\x44\xce\xa3\x3c\xc8\x5e\x8b\xf2\x82\xb2\x14\x32\x49\x35\x02\xcd\x70\x74\x16\xa5\x90\x3f\x0d\xc0\xfb\x3b\x00\x03\x3b\xc2\x88\xa1\xb4\xe6\xee\x28\x0e\x93\xa9\x88\x43\xec\x48\xfd\x50\x25\xc0\x29\x74\x5e\x52\x24\x40\xa6\x14\x43\x03\x4e\xd7\xf8\x52\xd3\x9a\x4f\xc8\x54\xef\x58\x4d\xc2\xcf\xe5\xc7\x41\xd9\x63\x20\x74\x01\x4f\x5b\xf5\xf4\xf8\x78\x67\x6b\x63\xe3\xd0\x6a\x04\x5a\xa4\x0f\x97\x7c\x0f\xe7\x39\xb9\x11\x64\x3a\x01\x24\x53\x39\x9e\xcb\xee\x63\x1f\xd2\x50\xff\x43\x09\x19\xcc\xa7\xfe\x7f\xf8\xfe\x79\x8a\x51\x96\x73\xa5\xa1\x79\x6f\x8a\x6e\x02\x6f\xca\x40\x09\x04\x54\x9f\xca\x73\x8b\x79\xe7\x45\xbc\x40\x66\x62\x99\x13\x5f\x45\x5b\x99\xe2\xe5\xb7\x05\x2a\x5b\xc8\x4c\x62\x65\x8b\x5b\xe8\x36\xfb\x6f\x97\xbb\xa4\x31\xdc\xd6\x8a\x59\x32\x6a\x68\xf6\x41\x65\x1e\x72\xc2\x33\x44\xfc\x68\x78\x83\x5f\xbe\xac\x09\x72\x9a\x27\x98\x53\x78\xa8\x7f\x9e\x6d\x8d\xf2\x02\x72\x37\xa7\x22\x41\xee\x9f\xbb\xc7\x31\xe2\x1e\x72\x46\x59\xe6\x16\x7d\xd7\x9c\xa1\x9c\x48\xef\x4d\x1e\x2e\x67\xee\x3b\xe0\xb4\x5b\xd7\x47\xaf\x90\xf5\xdb\xb8\xcc\x7a\x7a\x09\xcf\x29\x1a\xc5\x0d\xbc\x41\x75\x0e\x6f\xc2\x55\x8e\xf0\x05\xa7\xde\x5c\xd4\xd5\x3c\x53\x92\xc7\x31\x63\xce\x48\xf6\x71\x85\x3c\x56\x39\xfa\x6f\xf7\x8f\x8f\x0f\xfb\xe7\xd5\xf6\x2e\x34\x18\x8b\x3a\x38\xbc\x8a\x4a\x97\x30\x48\x1c\x5e\x83\xcd\x6e\x7f\xf2\x46\x89\xa2\x38\xef\x9e\xa0\x3e\x8d\xe4\xc8\x3e\x9d\x5c\x79\xa2\x99\x97\xfd\x74\x04\x18\xab\x97\x21\x6e\x92\x27\xfd\x26\x6a\x0f\xb9\xe7\xba\x9c\xf0\xa9\x42\x9e\x72\x6e\x4b\x8f\xf1\x9c\x75\xa7\x69\xa5\x9d\xdf\xe6\x57\x53\x9e\x26\x16\xdc\xec\x58\x71\x16\x62\x37\x79\xaa\xe5\x28\x94\x7f\x2f\x8a\x6a\xe9\xec\xce\x53\x00\xa4\x38\x2b\x6c\x30\xed\xd1\xac\xca\xd2\xd6\x49\x0e\x8a\x1d\x16\x3d\x39\xbd\x2e\x23\x11\x7a\xc2\xfd\x0a\x2a\xac\x09\x58\xe8\x70\x7e\xe6\x59\x94\xa8\x31\x81\xc4\xad\x18\x9a\x64\xee\x5d\xfa\xd5\x9b\xe8\xc4\x52\x42\x35\xcf\x13\xcb\x68\xff\x2a\xca\x6e\xbb\x79\xf4\xd7\xf6\xcb\x90\x5a\x62\x21\x68\x7a\x4f\x77\x9c\x34\xf0\x7d\x44\x84\x88\xfe\xab\xa2\xbb\x17\x55\x37\xfc\x70\xae\xa2\xdc\x86\xc8\xd0\x61\xb3\x5a\x0b\x23\x42\xe1\xd9\x77\xcf\x35\xc3\x4d\xfa\xa6\xae\x17\x54\x39\x21\xcf\x81\x21\x66\x64\x07\x25\xaa\x8a\x2e\x2b\xdd\xff\x3f\x65\x80\x73\xc9\x15\x06\x25\xd7\x0f\x93\xf5\x27\x01\xa8\xf4\x9a\x2c\x98\xff\xc6\x38\xf5\xec\xc5\x55\x9a\x62\xac\xd7\xc1\x16\x83\x0a\xd2\x97\x8e\x52\x0e\xb9\xd5\x8b\x1c\x32\x63\x6b\x51\x96\x52\x0c\x88\xc4\x79\x0c\xd1\xfb\x95\x39\xc8\x44\xb9\x23\xf8\xdc\xb4\xc5\x1b\x1c\x1a\x10\x33\x47\x36\x07\x9d\xe2\x99\x26\xcf\x4d\xf5\x39\xd3\xd7\xdf\x1c\xa6\xb1\xad\x90\x9b\x3c\x99\x14\x9f\x2c\xe5\x40\x6d\x57\x41\xe2\x08\x2c\x07\x54\xef\x89\xbd\x8d\xac\x0a\xdf\xc1\x48\x2f\xaa\xe6\xa2\x3e\x03\x2c\xc7\x1f\x88\x82\x52\x4b\x8d\x66\x23\x56\xa8\xa9\xb3\x18\x5e\x15\x94\x0b\xcc\x95\x42\xab\x06\xd6\x44\x10\x2c\x66\xf8\x14\xa6\xa8\x44\x69\x63\x35\x6d\x68\x53\x1a\x1c\x2c\xe4\xa6\x10\xee\x21\xd4\xc7\xb3\x28\xda\x79\x6c\x40\x44\x69\x62\xa5\xbb\x2d\xec\xb0\xb7\xce\x2f\x43\x9e\x2e\x8b\x13\xfd\x6b\xfc\x9f\xf8\xe1\xff\x27\xfa\x97\xbf\x91\xb2\x51\x84\x83\x35\x2a\xfb\x67\x2d\xaa\x97\xdb\x3a\xa0\xff\x45\xd4\x7b\x3e\xff\xe7\xff\xf7\x7f\x56\x2f\x4d\x81\x0a\xd6\xcf\x75\xdd\x0d\x74\xe2\x20\x7a\xeb\x3a\xb6\x39\x14\x1c\xd7\xc0\x9b\xe2\x3b\xc4\x54\xa3\x6f\xfa\xcf\xed\xf3\x3a\xfc\x2d\xb6\xac\x84\x56\x05\x0c\x9a\x9b\xc0\x18\x3d\xb1\x4b\x7c\x6f\xa5\xd1\x35\xbb\xdf\x3e\x1c\xb6\x0f\x3f\x36\xbb\xfd\xfd\xe6\x61\x8f\x30\x42\x14\x8f\x3e\x3c\x3e\x6c\x0e\x4f\x8f\xdf\x1f\xae\x7d\x36\x5b\x24\xb9\x4e\x1d\x5f\xc5\xe6\x78\x2a\xeb\x0f\xb8\xe0\x0f\x1c\x79\x95\x22\x51\x39\x12\xe4\x94\x9d\x72\x03\xee\x1a\xd2\xd8\x72\x9c\x0b\xad\xff\xbb\x96\xde\x68\x71\xb2\x7b\x9f\x4e\xe2\xa5\x53\x5d\xa4\xb9\xc2\x22\xed\xfb\xdd\xe4\x6c\x15\x59\x6e\x90\x35\xe8\x54\x9f\xfe\xef\x19\xc2\xf1\x27\xf2\x94\x90\x7c\x70\x39\x27\xd7\x88\x34\x41\x07\x0e\xac\xe2\x65\x59\x74\x23\x71\x47\x10\x22\xb3\x1e\x89\x3c\x7f\xac\xeb\x37\x03\x66\x66\x41\x08\x21\x19\xf2\x2d\xdc\x08\x59\x8f\x01\xad\x42\x98\x0c\x43\x85\x87\x6e\x4e\x8b\x8c\x45\x77\x82\xf8\x50\x6c\x27\x2c\x8a\x79\xd9\x4d\x15\x2a\x56\xc2\x72\xba\x7d\x14\xd5\xcb\x95\xb8\x30\xf8\x84\x4e\xac\x68\xf5\xa8\x48\x40\xa8\xee\x92\x17\x1a\x84\x96\x16\x00\x55\xc1\xaf\xee\x69\x04\x3d\x13\x10\xe5\x58\x1f\x71\x5b\xeb\xff\xec\xde\xc5\xa9\xff\x17\xa7\x53\x6f\x76\x94\xc5\xc8\xe3\x15\x90\x09\x74\x8a\x90\x3a\x09\xe7\xf1\x5c\x5d\xf4\x93\xbd\xee\x33\x04\x8b\xbb\xaf\x89\xb5\x25\xe5\x2b\x42\x65\x8d\x30\x69\x9c\x53\x57\xcf\xdc\x8f\xd1\x6c\xec\x4d\x9e\xa3\xad\xd8\x14\x2f\xaf\x5d\x92\xcd\x5b\x41\x31\x3a\xae\xe7\xf8\x5a\x77\x19\x24\x25\x96\x59\x1e\xf1\x3d\x13\xf8\x84\xa4\x3a\x4d\xc7\x92\xa2\xbf\xcd\xae\x04\x89\x51\x97\xa2\x6d\xcf\xfd\x47\xaa\xb5\xff\xd4\x92\x89\x08\x2b\xce\x10\xfc\x67\x25\x63\xaa\x97\xf5\xab\xa8\x2a\x28\xbf\xe2\xca\x04\xc9\x64\x2c\xdc\x82\xd9\x83\x38\xda\xd8\xe4\xf4\x83\x4a\xa6\x24\x26\x8e\xec\x1c\xfb\xf7\x59\xa0\x40\xfc\x4f\x68\xaf\x3e\xc6\xa1\xe6\xe5\x23\x52\x46\x1c\x70\x5d\xac\x4a\xc4\x62\x55\x9d\x50\xdd\x43\xbf\x15\x7f\xa5\x18\x0e\x32\x12\x02\x1f\xec\xd0\xef\xf0\x16\xd1\xfb\x28\xcb\xe2\x65\x64\x9c\x86\xbe\xfd\x96\xc5\x07\xa9\xd2\x7e\x77\x02\x71\x1c\xcc\xb0\xe5\x43\x46\xc6\xdc\x61\x85\x20\xa0\x66\x64\x9c\x66\x08\x11\x5e\x5d\xff\xd8\xee\x90\x73\x61\xf5\xfb\x86\x85\x56\x25\x94\xf0\xec\x6b\x68\x8e\xa2\x29\x7f\x69\x53\xca\x84\x5a\x82\xfb\x43\x63\x03\x96\x21\x16\xe1\xaa\x71\x16\xf3\xff\x32\x4d\x64\x6e\x29\xd9\xda\xee\x72\x2a\xca\x34\xe3\xcc\xaa\xa3\x16\xd5\xc2\xfc\x49\xb5\x44\xaa\xd7\x9b\xfa\xd7\xbe\x11\xfd\xc9\x30\xde\x84\x64\x9e\x08\xd0\xa8\xcd\x73\xae\x7e\x8e\x36\x11\x29\x98\xad\xf2\x5e\xd7\xa7\x8f\x09\x04\x5b\x8a\x1c\x34\x5b\x20\x0b\xbf\xdc\x92\xa5\x24\x1c\x21\xb2\x21\xdf\x19\x78\xb8\x7c\x07\x26\x90\x6c\xc3\x2a\xdb\x38\x5a\xd6\x7b\x0c\xb0\x7c\xf2\x7d\x24\xd3\xb8\xb9\x15\x55\xdb\x35\x67\xd5\x59\xa5\x9f\x7d\x7d\x1d\x2c\x9f\xd9\xf8\x48\x13\xa1\x8a\xc7\x15\x34\x2f\xe3\x17\x54\xcc\xae\xb9\xa2\xed\x77\x1a\x1b\xc7\x9f\x05\x1f\xa4\xe2\xb1\xc5\xe7\xf4\x3e\xac\x33\x29\x6e\x60\xc2\xa5\x0d\x52\x27\xc4\xe6\x40\x5f\x41\xfd\x74\xd8\x57\x1f\x4e\x99\x65\xb4\xa5\x56\x69\xec\xe5\xd1\x8a\x56\x15\xa7\xd2\xc2\xb3\x96\x57\x89\x51\x39\x62\x4f\xba\xaf\x28\x5c\x27\x33\xcc\x68\x81\x55\x89\xfd\x4e\xfa\x5b\xf8\x1b\x10\xe7\x66\x28\x00\x6d\x2b\xa7\xf7\x43\x40\xfb\x8b\xa4\x83\x22\x3c\x46\x0a\x39\x71\xd6\x45\xa0\x42\x04\x45\x13\x8a\x63\x1a\xa2\x81\x2e\xee\x36\x79\x7c\x45\x75\x82\x3e\xd2\x0f\xa8\x74\xed\xa8\xd7\xa6\x6f\xa8\x58\x1a\x71\x1a\x24\x1f\x4c\xf1\x32\x0d\x38\x28\x96\x2a\xee\xd6\x56\xef\x8a\x3f\xf7\xbb\xd6\x2d\x54\x64\xf6\x4b\x51\x22\x73\x47\xd1\x7c\x2c\x70\x91\x8c\x7d\x9e\x0b\x2c\xcc\xc2\x8b\x46\x02\xf0\x30\x75\xc5\x17\xc8\x8a\xf0\xe5\x16\xa6\x38\xe5\x78\x1a\x81\x2e\xba\x7b\xe8\xc4\x62\x18\xa0\x3f\x6e\x51\xbf\xf1\x58\x87\x40\xa1\x8a\xb9\x4d\x4e\xf6\x46\xc1\x9d\xcd\x77\xe3\xd3\xd2\x4f\x22\x3a\xee\xb2\x44\x70\xc5\x2f\xe4\x31\xda\x05\xc7\x4b\x25\x5a\x28\x97\x4d\xdc\x15\xff\x81\xe9\xce\xa8\xb2\x84\x89\xcc\x03\x6a\x37\x2f\x33\xd5\x4c\x50\x99\x93\xad\xdf\x37\x75\xb5\xe8\x0f\xf9\x7e\xa0\x62\xe1\x33\x9b\x55\x11\x52\x33\x4a\xb0\xc4\xd3\x4c\xfe\x31\x93\x4e\xf0\x3d\x38\x77\x01\x39\x24\x98\xf2\xec\x90\x23\xa8\xa2\x12\x3c\x43\x8b\x01\x33\x35\xd0\xae\xca\xf2\x1e\xa5\x2d\xe6\x77\x82\x38\xb1\x53\xb1\xda\xc1\x02\x73\xdd\x22\x31\x8e\xbf\xd6\x80\xb1\xbe\xe4\x54\xdf\x07\x94\xcc\x33\x44\x1a\x1a\xe4\xa7\x6b\x2d\xa2\x60\xf6\xcb\xb8\xb3\x20\x5d\x63\x7b\x91\x14\xf3\x5d\x4c\x8a\x85\x4d\x07\x53\xcc\x03\x9b\x4a\x29\x41\x61\xca\x73\xb3\x6c\x2b\xf8\xfe\x9a\xc7\xc9\x60\x4a\x16\xff\xb1\x3b\x87\x5f\xbb\xf1\x30\xa7\x93\x7f\x7d\x0d\xc9\x9d\x4d\x51\xc8\x55\x42\x1d\xd3\xdb\xb7\xba\xd4\x93\xd0\xa9\x32\x79\x82\x1c\xba\x58\x9b\xb6\xff\x76\xb8\x5a\x5f\xfb\xba\x55\x4d\x28\x58\x1b\x40\xfc\x84\xe6\xba\x68\x4f\xa3\xdd\x77\xf9\xc7\x34\x89\xd2\x3c\xf3\xa2\x1d\xbb\x4e\x2c\x53\xd2\x82\x26\x89\x03\x29\x74\xc2\x9a\xc6\x98\x52\x42\x11\xa0\xf0\xeb\x99\xd5\xff\x90\x9e\x3d\x64\xd3\xbd\xde\x00\x84\x66\x11\x79\x01\x25\x47\x6f\xb5\x08\x8f\xd1\xc4\xc4\x4c\x79\x6a\x95\xb6\xab\x8f\x16\x84\x3f\x41\x9d\x5c\x42\x4f\x34\x25\x12\x77\xfd\x70\xb4\xf9\x3d\x4b\xb3\xc8\xa0\xe9\x88\x21\xd2\x27\xf1\xe1\xab\x28\x67\x31\xa7\xf1\xbe\xad\x59\x66\xe7\x12\x12\xa6\x16\xc8\xce\x37\x80\xe7\x35\xd3\x39\x71\xae\x80\xab\xbd\x40\x5b\xc9\xb5\x46\x71\x86\x62\x12\x36\xe3\x8f\x3f\x38\x9d\x6a\x3a\xca\x68\x46\x3d\x9a\x13\xeb\x98\xc2\xb5\xda\xaa\x9a\xbf\x40\x87\x2a\x0c\x73\x0c\x9e\xe6\x84\xe0\x71\x8b\x36\xfd\x5a\xb4\xaf\xf5\xd9\x4f\x0d\xcd\x95\xdd\x01\x4f\x88\x74\xd2\xba\x2b\x51\x92\x6b\x3a\xbc\x71\x66\xa5\x89\x1a\x8c\xbb\x1f\x5e\xcf\x47\x51\x61\x84\x41\xc8\x12\x0e\x48\x88\xfc\x3a\x64\x75\x75\xec\x66\xb9\x25\x2e\xb1\x12\xea\xd6\x5f\x98\xde\x36\x61\x36\x43\x67\x7d\x5e\x74\xf3\xbf\xd6\xe3\x03\x9d\x24\x3a\xd2\xce\x2a\x77\xc0\x7c\x7f\xda\x2c\x5f\x90\x92\x04\x3d\xb0\xdd\xfa\x69\xf7\xd7\x9f\x30\x65\x0a\x8f\xde\x42\xd5\x0b\xa1\x73\x9d\x46\x14\xb1\x7f\xbd\x43\xe1\x64\x3b\x0a\x59\xc2\xf7\x4a\xbc\x89\xc2\x85\x9e\xc6\x0b\xfa\xeb\x18\x93\x4e\x63\x97\x81\x74\x54\x4f\x4f\xd0\x4c\x78\x7a\x41\x67\xc6\x60\x58\x15\xdd\xbc\x1b\x80\xd6\xe5\x28\xc3\xb7\xcf\xa5\xca\xa6\x1b\xca\xd8\x32\xd4\x82\x90\x5c\x86\xfa\x2e\xcb\xf3\x33\x7d\x06\x41\x12\x5c\x39\xae\x46\x67\x8e\x30\xd6\x22\x95\x48\x8d\xaf\x02\x2d\xc1\x98\x8b\xfe\xb0\x53\xf5\xf9\x74\xc9\x7a\x39\x7b\x51\x21\x73\x44\x22\x3b\x24\xdd\x1a\x75\xfb\x86\x97\x10\x86\xd9\xe2\x99\xae\x3e\xd9\x40\xab\x6f\x91\x3a\x4d\x5c\xf6\x78\xfd\x2a\xca\x12\x7a\x0f\xd5\xa6\x7c\x67\xcf\xa9\x92\x58\x47\x61\x8a\x2e\x9f\x58\x5a\x25\x39\xa2\xa9\x8e\xe2\xd7\x4a\xb6\xbf\x17\x95\xae\x46\x5f\x57\xe9\x84\x5a\x17\xf2\x08\x6d\xe6\xff\xaa\xa9\x75\xe1\x9d\xfa\xcc\x17\xc0\x41\xad\x73\x82\xb9\x89\x50\xd3\x36\xfd\x75\xad\x15\x11\x5e\x11\xea\x08\x55\xf7\x47\x53\x84\x50\x81\x06\x43\x90\x8c\x12\x89\x83\x9d\x7d\x37\x36\xd9\xb5\xd1\x39\x9a\x9d\x13\xfc\xc6\x67\x4e\xf3\x64\x56\x1b\xb0\x71\x58\x70\x98\xd1\x6d\x35\x4e\xbc\x01\x49\x12\x0c\x78\xb5\xed\x29\x44\x2a\x7d\x93\x4a\x50\x31\xd0\x25\xf9\xaf\x84\x0e\x99\x78\x60\x5a\xa3\x54\xf1\xcd\xd9\x8a\x5a\xbb\x3f\x47\xb9\x05\x34\x62\x1d\xb0\xa8\xaa\xba\x5b\xb9\x80\xd4\x15\x98\xba\x01\x2b\x3a\xdc\xaf\xdb\xc0\x9d\x00\x91\xe1\x68\xfa\xf9\xf2\x4c\x14\xa9\x9b\xd8\x3b\x10\x47\x14\xc3\xd0\x3b\xe8\x76\x97\x18\x6a\x88\x33\x4d\x23\x0f\x85\x3e\x37\xd5\xed\xf9\x63\x75\x0e\x28\x04\x88\x0d\xc3\xd0\x27\xaa\x47\x8f\x57\x08\x24\x3a\xb7\xfa\x29\x95\xde\x56\x45\x77\x18\xfe\x0e\x68\xb6\xbf\xd7\xcd\xcf\x99\x60\x26\x40\x4a\x01\x93\x89\x0f\x75\xd3\xd5\x15\x66\x35\x37\xcf\x6b\x46\xbe\xda\x5b\x20\xcd\x32\x4c\xe2\xb9\x10\xdf\x5d\xfd\x06\x3b\xa4\x54\x9b\xa4\xd3\x17\x4e\xfa\xe9\x5d\x84\xc4\x9f\x16\xb6\x82\xe8\xfb\xe9\x42\xb7\xf0\xd2\x30\x86\x8c\x31\x2f\xe8\xbc\x2a\xcb\x3b\x07\xd4\xb8\x00\x6b\x43\x96\xf2\xd4\x06\x22\x1e\x9b\x17\x51\x15\x2d\xf6\xdb\xfc\x2a\xba\x99\x79\x09\x59\x2e\x12\x2f\x62\xa4\x3c\xc1\x17\x40\x4e\x04\x96\xd7\xdf\x3c\x7e\x7f\xb8\xf6\x4e\x76\x68\xd4\x09\x02\x3d\x4b\xd1\x76\xfd\x8c\xf1\x54\xbb\x00\x22\xa6\x08\x27\x3e\x16\xe5\xcf\x0b\x19\x30\x00\x61\x94\xcf\x74\xa3\xa1\xdc\x7c\xf4\x53\x60\xe6\xa9\x80\x8c\x58\x64\x53\x50\xbd\x2f\xd8\x6f\x75\x48\xec\xd8\x89\xe3\xa9\xbd\xa9\x1b\xc6\xef\xeb\xaa\x7b\xbd\xb8\x4a\xb9\x3a\xcd\xd6\x7a\xac\x53\x3c\x4f\x7f\xec\x62\xa0\x59\x16\x2f\x23\x2e\x4b\xe8\xcf\x38\xeb\xf3\x16\xa7\xd7\x51\x6f\x91\xe2\x26\xa4\xad\xce\xee\x27\x14\x50\x73\x41\xae\xfe\x3a\xa9\xbc\xa4\x1a\x94\x75\x65\x65\x90\x7d\xa3\x49\x75\x36\x09\x88\xbb\x6d\x74\x74\x60\x52\x96\x85\x8f\x08\x2e\xe1\x73\x40\x96\xb5\xaf\xcf\x53\x80\x2c\x32\x0e\x44\xbd\x42\xa4\x2c\x2c\x68\xe3\x03\x80\xa4\xa8\x93\x63\x44\xdb\x6d\x5a\x25\x42\x96\x13\x0c\xb0\xc8\x91\xb1\x74\x0e\x4b\xa1\x27\xfb\x16\x18\x30\x58\x97\xea\x05\x70\xc7\xe7\xc7\x0e\x4a\xf3\x50\x57\xae\x8c\xa2\xf9\x18\x19\x4c\x86\x24\x12\xad\x96\x53\x03\x6f\x45\x7d\x6e\x4f\xa3\xf1\x37\x24\xcd\xac\x9c\x1a\x3a\x9c\x8e\xc0\x1b\x99\x6e\x0b\x75\xa9\xba\xb0\xf8\xee\x86\x46\x11\x12\x97\x98\xf2\xec\xb8\xf8\x67\xb3\xdc\x44\xa9\xad\x8e\x70\xe8\xe9\xa7\xcd\xf3\x7a\x13\x76\x2d\x13\xe5\xb1\x4b\x81\x3d\xc3\xbf\xcf\x45\x03\xa3\x68\xbc\xe1\x49\x8e\x87\xc9\xfd\xc7\x4d\x03\x48\x2e\xf3\xd7\xf9\x4a\xc3\x15\xc5\x57\xf6\x79\x94\x1f\x4f\x6b\xf2\x6b\xf1\xc9\xb8\xe1\x18\xaf\x7a\xaf\x9b\x72\x76\xa4\x9b\x58\x00\xe4\x8e\xc6\xa5\xa9\x4f\x75\x33\x02\x23\x98\x58\x47\x3e\x51\x7b\x25\x5a\xb0\x51\x9f\xd9\xf5\xc0\xb1\xa6\xb7\x3d\x4b\x1b\x28\x5e\x1e\xbe\xd8\x44\x18\x19\x38\x89\x8f\xc0\x9a\x38\xed\x91\xaa\x24\x73\x38\x81\xcd\xaf\x53\xd1\xbf\xe8\xf7\xde\x5d\x1e\x6a\x0c\x4c\xc6\x2d\x96\x66\xcc\x37\x50\x57\xe3\xe1\xf2\x1d\x53\x4e\xb9\x47\x7f\xbc\x15\x6d\x6f\x46\xa0\x8b\x33\xa6\x06\x04\x93\x41\x86\xc2\xef\x95\x43\x73\xdb\xc1\x5b\x92\x39\xec\xfb\x2a\x64\xc7\xe9\x0f\xa9\x73\xa5\xe0\x60\x2f\xfa\x1a\xdb\x38\xc7\x66\x98\x9c\xd9\xbd\x6b\xbb\x7e\x9c\x3d\xb2\x88\xa8\x24\x83\x6d\xb6\x08\xf5\x35\x22\xd3\x31\x22\x42\x01\x5a\x5f\xce\x64\x84\x64\x98\x65\xf4\x66\x68\x8b\x54\x1d\x7e\xbb\x34\x32\x8e\x52\xaf\x00\xe1\xf6\x52\xcb\x78\x34\xdb\xdc\x8c\x4c\x13\x34\x30\x2b\xf8\xd5\xdd\x21\x54\xc0\x35\x28\xa1\x31\x03\xbf\xb9\x7f\x7a\x0e\x7f\xd3\x0c\xc6\xa5\x3e\x4f\x0d\x6a\x59\xfd\xcd\xda\xd9\x6c\xec\x94\x1b\x4d\xad\x34\xf9\x2c\x3f\x37\x8b\x86\x18\x88\x39\x72\x49\x38\x2e\xde\x3f\xa0\xf0\x2c\xb1\xfe\xa1\x20\xe1\x7c\x90\x35\x16\x45\x35\x8b\x7d\x1a\x10\x56\x9e\x4d\x9e\x2f\x55\xcd\x97\x8d\xa2\xa5\xc3\xd9\x18\x0a\x58\xb3\x7c\xfd\x8f\xab\xd1\xed\x0d\x21\x0e\xbb\x73\xbf\xfd\x8a\x49\xcc\x10\x12\xe9\x38\x1f\x11\x3a\xe3\x80\xf5\x3b\xdc\x6d\x23\xaa\xce\x51\x9b\x8c\xbf\xbc\x21\xc4\xc4\x88\x77\xfa\xb6\x7a\x9c\xfc\x24\xd5\x0a\x8d\xa1\xcd\xfe\xdb\xcd\xf6\x61\xf3\xe7\xe1\x66\xb3\x09\x6d\x90\x20\x4f\x3c\x42\xa2\x27\x12\xcf\x93\xc5\x69\x08\xa3\x99\x95\x20\x41\x4e\xb6\xde\x2b\x1c\x25\x6c\xfa\x66\xc0\x88\x56\xdd\x08\x85\x5e\xc3\xe1\x45\xb4\xe5\xc0\xbe\x6b\x08\x03\x6e\x26\x39\xa6\xde\x34\xdb\xff\xf4\xcd\x91\x2b\x55\x56\xf5\xf1\x78\xae\x0a\x04\x1a\x36\x07\xdf\xca\x63\x48\x2c\xf5\xd3\xaa\x69\xc4\xb8\x36\x78\x3a\x04\x3c\xb5\xa5\x9b\x6d\xed\xbe\x6a\x50\x0d\xf3\x1d\xa4\x45\x8a\xb4\x58\x9b\x34\x22\xbb\x5a\x74\x34\x0c\x89\x89\xab\x84\x39\x4b\x5d\xf7\xd3\x65\x08\x46\x19\x12\x27\x96\x82\x76\xd7\x35\x75\xf5\xf2\xad\x2e\xf5\x7e\xb3\xdb\xfb\xd6\x04\x68\x3a\xa4\x72\xaf\xeb\xa9\x0c\xb7\xeb\x94\x46\x24\xf2\x35\x47\x0d\xe8\x50\x9c\x6e\x48\x9a\xd0\x6c\x90\xc1\xbf\x6e\xc4\x4b\xfd\x29\x03\xd8\xf2\xbf\xae\x4a\xc0\x90\x2c\xb3\xa8\x23\x2b\x7f\xbb\x6d\xff\x18\xc9\x57\x4e\x1f\x27\xcb\x35\xee\xf4\x76\x07\x30\xa8\xd4\xfd\xdb\x74\x44\x72\x29\x30\xf1\xb0\x3f\x9f\x4a\xb8\x86\x63\xed\x1f\x58\x90\xd4\x2a\xe5\xfc\x9a\x26\xfe\x42\x7b\x6e\x0b\xe9\x1b\x7b\xb6\x69\x0f\x16\x33\x45\x73\x14\xa3\x84\xb9\x21\x42\x2b\xf0\x25\x14\x47\x51\x96\x16\xdd\xb2\xb4\xdd\x19\x22\x93\x14\xfb\x1e\x84\xd6\x13\xc2\xff\xd9\xcc\x90\x29\xb1\xe1\xd5\xce\x4e\x8c\x90\x73\xb8\x70\xbb\x0c\x51\x20\xd0\x35\xf0\x67\xc8\xe5\x5e\x6f\x88\x32\x14\x21\xde\xf7\xb5\xfa\xb9\x14\xac\x5f\xcc\x2a\x1a\xa2\x73\x81\x0a\x6d\xde\xfb\x75\x98\x8f\x30\xd1\x41\xa5\x58\xa8\xe1\xc0\xeb\x56\xaf\xe7\x63\xf6\xdb\xa0\x89\x36\x01\x6c\x66\x07\x79\x81\xd8\xce\x10\x93\x32\x34\x90\x77\x27\x31\x24\x39\x0c\x25\x39\x23\xae\x48\x69\xc4\x89\x5f\x75\xd0\x18\x31\xab\x3e\x33\x94\x68\xc0\x60\x90\x12\xd5\xf7\x4f\x80\x54\x86\x12\x43\xb0\xf0\xa2\x3f\x17\xec\x89\xbb\xdf\xdf\xe3\x38\x6f\x3d\xd3\x8d\xa1\x34\xb5\x9e\x46\x1b\xf0\x98\x9f\xe8\x3e\xf9\xfe\xb9\x2d\x71\x95\xe7\xa6\x98\xcf\x54\x4a\x81\x47\xf6\x24\x7a\xc7\xc4\xb0\x86\xb2\x13\xb3\x3e\x8c\x1b\xac\x55\xc3\x6c\xe4\x7d\x31\xfc\x9e\x9f\x69\x34\xd2\x91\x8f\xb0\xed\x7f\x55\x0f\xe7\x65\x90\x89\xa1\x3c\xa5\x78\xee\xf5\xeb\x62\x83\x8b\xe2\xef\xa0\x5b\x32\x7f\x35\x30\x3d\xb6\x49\x4c\x00\x8e\x18\x1a\x33\x6d\x65\x2e\x46\x92\x8a\xbe\x89\xc7\xa9\x25\xea\x0f\xcf\x9b\x72\x62\xe3\xda\x41\xbb\x65\xa8\xe9\x34\x34\xa3\x60\xd8\x68\x8b\xfd\x5e\x15\xff\x3e\xc3\x7a\x28\xbf\x35\x34\xe3\x04\xd1\xf3\xf5\x7b\x79\xc4\x2a\xa0\x67\xf8\x77\x68\xcb\x52\xbf\xf8\x65\x09\x4d\x7b\xf8\x5e\x75\x45\x79\xf0\x74\x41\xbe\x97\x50\xb8\x51\xaf\x45\xf3\x5c\x9f\xa7\xea\xf8\x86\xe6\xd2\x48\x33\xa2\x6b\xba\x9b\x1a\xef\x86\xe6\x9a\xf0\x68\x96\xaf\x18\xa7\x9b\x5c\x37\x41\x2d\xca\xe0\xdc\x82\xd5\x69\x46\x04\xd0\x57\xae\x87\xa1\x22\xd2\x96\x44\xa8\xa9\x4f\x1b\x2c\xd1\x0d\xa3\x2c\xc0\x6a\x6f\xa3\x4e\x72\xeb\x2b\xf0\x47\xe9\xae\xe9\x26\x47\x25\x65\x56\xc9\x5f\xd5\xbb\x22\x80\x0d\x0c\x95\x46\x87\x58\x44\xef\x7a\xd8\x0c\xe5\xee\xb5\x6e\xba\xad\x5e\x95\x0d\x08\xfd\xb1\xf9\x55\xb4\xc3\x0c\xd3\xc2\x12\x34\x0f\x95\xe0\x6f\x94\x5e\x56\x82\x1b\x0a\x89\x15\xbc\xb3\xb8\x97\x49\x49\x8e\xa1\x26\xce\x31\xb0\xb9\x5d\x3f\x1e\x90\xe4\x81\x85\x96\xcc\x24\x16\x13\xfe\x06\x55\xf7\x7a\x18\xca\x09\xa7\xaf\xc4\x08\xcb\xd1\x2e\xdc\x89\xe3\xa9\x1c\x8a\x92\xff\xd2\xc6\x99\x7c\x17\x46\x8c\xd5\x4a\x70\xb9\x6a\x1f\xde\xf7\x11\x87\xbf\x58\x15\xee\x26\x2c\x49\x30\x11\x85\xca\xe9\xab\xea\x05\xca\x75\x00\x82\x2e\x2f\x40\xc6\x24\xc1\xa2\xa1\x7e\x18\x63\x72\xea\x1d\x2c\xa1\x7e\x7a\x47\xd9\xb0\x28\x26\x16\x86\x5f\x54\x57\x9d\xb2\x4e\x88\x6f\x12\x31\xe2\xfd\x8f\x36\xba\xbb\xf6\x39\x50\xc3\x38\xcb\x11\xb4\x8b\xf1\x96\x6f\xa2\xd1\x6a\xd4\xd6\x7b\x1b\x76\xb3\xba\x2d\xf4\xbd\xf8\x35\x2a\x05\x31\x2c\x26\x1c\xa5\x7c\xc2\x30\xfa\x99\xc6\xe2\x34\x4d\x5d\xec\xfc\x81\x39\x82\x4c\x64\x9e\x69\x27\xf1\x27\xc3\x92\x58\x63\xf1\xeb\x4d\x73\x56\xdd\x84\x29\xd6\xb0\x24\x61\x5e\xbd\x67\x77\x96\xff\x0b\xca\x86\x29\x96\xc9\x59\x0d\x4b\x54\x6c\x8b\xdd\xb5\xbe\x2f\x4a\x68\xbb\xba\xfa\xeb\xef\xba\x60\x74\xb2\xc4\x08\x84\xd5\x0f\x9c\x06\x58\x6e\xf4\xe1\x81\x21\x43\xda\x63\x9c\xfb\x98\x4d\x91\x14\x72\x87\x2d\x57\xf5\x5b\x20\x43\x47\x06\x25\x7b\xd8\xa1\x70\xa4\x8d\x33\x79\xb8\xd5\x67\x91\xaa\xc9\xdf\x47\x0e\x81\x61\xa9\xa1\x24\x10\x97\xfa\xc3\x7c\xd7\xfb\x05\x17\x51\x2b\x77\x45\x96\xc5\xe8\x19\x3a\x3e\xc8\x65\x46\xd8\xff\x9a\x7e\xa4\x2c\x33\xc4\x41\xf7\x9e\xce\xf2\x77\xf8\x18\x02\x89\x8c\x8c\xdd\x94\xc9\xb3\x65\x92\xe1\x26\x7b\x35\x58\x47\x2c\x83\x1c\x27\xb0\x13\xae\xb7\x41\xe9\xd9\x03\x1a\xc6\x95\xc7\x57\x1f\x1a\x68\x51\xef\xc3\x6a\x64\xa3\x70\x42\x0b\xa5\xd1\x60\x11\x0e\xfe\xbe\x79\x12\xa3\x59\xed\x8b\x9d\x77\x30\xe6\x63\xf5\x9d\x94\x66\x0e\x2e\xe4\x96\xea\x74\xa8\xbd\xa5\xc8\x24\x25\xa8\x05\x02\x55\x80\xbd\xfe\x11\x36\x14\xbf\xa7\x31\x45\x20\xf2\xd8\x6c\xe7\x16\x4f\x54\xf8\x0d\x53\x32\xb6\x7e\x58\x7d\xda\xe8\xf3\x98\x9c\xa3\x6f\x13\x48\x2d\xef\x02\x8e\xf7\x3f\x9e\x3e\xfd\x64\x4a\x4b\x6b\xce\x23\x5c\x1e\xc3\x53\x77\xf5\x3b\x34\x57\x17\x79\x07\xc3\x80\xc4\x9e\x30\x6b\xab\xea\x05\x40\xb4\x61\x90\x13\x5c\xd3\x0d\xb4\xe7\x63\x40\x9d\x4c\x56\x1e\xe4\x63\xa3\xdd\x2d\xdc\xd9\x0f\x81\x8e\xc2\x3c\x52\x1e\x6c\xe6\x1a\x0d\x8d\x73\x87\x4e\x3c\x9f\xf6\x0d\x88\xf6\xfc\x09\x5d\x98\x61\x86\x27\x8e\x9d\xe9\x0d\x44\xf9\x5c\xab\x9f\x93\xb3\x34\xa2\xcc\xd6\xce\xd9\x67\xf9\xde\x4e\xc8\x39\x7d\x9f\x34\x42\x37\xf3\xde\xc2\x71\x3e\x5c\x88\xd3\x44\x54\x46\xc2\x42\x17\x5c\x02\x73\x54\x3a\xb8\x54\xfe\x63\x22\xc6\x13\x31\x62\x39\xb5\xe5\x67\xbe\x4d\x58\xd5\x44\xeb\x8d\xa2\xc2\x8b\x2f\xe6\x5d\xc4\x27\xf5\x57\x58\x6b\x3f\x80\x41\x6e\x44\x03\x0b\x60\x6b\x13\x45\xcc\xea\x88\x3a\x3f\xa9\x68\xeb\xf7\xd9\x71\x1c\x45\xcc\x8a\xdb\xbc\xf4\x9b\xb1\xe9\x2c\xba\x61\x78\x3a\xae\x75\xec\xf6\xea\x1f\x58\x2d\xf3\x82\xd9\x6a\xbd\xaa\xb4\xe7\xc0\xfe\x2b\xdd\x54\x77\xa7\x58\x13\x0c\xde\x0f\xe5\x4d\xc1\xc0\xbe\x48\xd3\x0c\x0b\x3e\x4a\x74\x14\x39\x12\x91\x53\xdd\x8d\xc9\xec\x4d\x94\xaa\x5c\xdb\x79\x89\x75\xeb\xf3\x02\x44\x13\x65\x9c\xb0\x24\x60\xf9\xba\x73\x7b\x75\xfe\x08\xfa\x1b\x23\xb7\x24\xca\x99\xc4\x53\xa1\x1b\x73\x80\x8e\x53\xfc\x94\x0e\x30\xe0\x80\x6f\x49\xfe\xe5\x2f\x8f\x62\x0c\x6c\x28\x6b\xfc\x38\x53\x68\x3a\xe5\xf2\x38\xc5\x9c\xf0\x5a\x9c\xda\x73\xb9\x8c\x81\x36\x91\xa0\x16\xeb\x25\xca\xba\x73\x14\x93\x17\xea\xdc\xd3\x0f\x28\x58\x9a\x7b\x96\x15\xe8\x1c\x9b\xb6\x6f\xe3\x79\xe2\x4e\x4c\xab\x24\xf1\xd4\x2f\xf1\xcf\xfc\x29\x7f\x51\x9a\xa1\x1f\xd5\x88\x0e\xd0\x82\x08\x95\xfc\x26\x92\x5a\x25\x6a\xd0\x40\x58\xcd\x69\x35\x66\xb7\x52\x8c\xe2\xfc\xfb\x59\x74\x1d\x54\x7b\x51\xfa\x98\x44\xa4\x62\x1b\xa4\xde\x41\x77\xfc\x10\x0b\x27\x6f\xa4\xe2\x1c\xb7\xec\xbd\x9d\x76\xe3\xad\x24\x52\xda\xd2\x76\x04\xae\xbd\x9b\xa2\xec\xa0\x1f\xec\xdd\x7b\xd1\xa9\x57\xdf\x4f\x67\x11\xfe\xca\xc9\x32\xeb\x21\xb5\x8c\x6b\x02\x6e\xb5\xaf\xac\x62\xe4\x38\x91\x31\x1d\x5e\xd0\x06\xcd\xc3\xe7\x7a\x8c\xf9\x35\x91\xe1\x91\xc8\x3c\x08\x11\xae\x6f\xff\xd9\xd5\xd7\x2f\xff\x79\x9e\x67\xbb\x0c\x27\x4c\x23\xec\x7c\x1d\xc2\x6b\x9f\xe9\x68\x18\x4e\x84\x15\x35\xb5\x27\xd9\x13\x74\xc5\x98\xb2\x6e\xc6\x4d\x32\xa7\xb6\x36\x9c\xc6\x69\xca\x06\x04\xa6\xb3\x96\x27\xc7\x2e\xa7\xb9\xe2\xc4\xa7\x2f\xd0\x42\xb8\x17\xbf\xd6\xaf\xa2\x5f\x88\x81\xb0\xc5\x70\x16\x09\x64\x82\xb9\xde\xfe\xd8\xee\x1e\x27\xc9\x21\xc3\x59\x12\x41\x6f\xf2\xff\x9a\xbd\x6a\x44\x12\xea\xb9\x62\x5f\x0b\x97\xc3\x76\x59\x72\x2c\xec\xf2\xfd\x54\x8a\x29\x94\xfa\x34\x4a\xf1\x7f\x91\x15\x35\x9c\x73\x2d\x6d\x90\xaa\x83\xa6\x12\xe5\x75\xfd\x5c\xf7\xcb\xf8\x6b\xbc\xcd\x6c\x74\xb9\xce\x10\x76\xfc\x50\xbc\x40\x53\x88\xea\x41\x14\x8d\x18\xcf\x2b\x1e\x93\x1c\xe9\x03\x0e\x47\xd1\x41\x7f\x3a\x2f\x3e\x9d\xb3\x54\x79\xc2\x32\x2c\xe4\xd0\xd6\x52\xc7\x13\x0d\xb4\xd5\xc9\x1e\x0d\x65\x22\x18\xf4\x67\xcd\xf5\x59\xdd\xd5\xd3\x89\xcc\xd3\x2c\xb2\x21\x70\x78\x77\x98\x99\xd9\x90\xa6\x79\x8c\x0a\x3b\x3f\x8b\xea\xe5\xb6\x14\xba\x10\x5d\xdd\x60\x64\x21\xec\xd1\x3c\x85\x04\xfb\xe8\x99\x60\xb9\x6b\xce\x52\x4b\xc5\xd8\x3a\xb1\x93\xdb\xb3\x68\x74\x7f\x0c\xad\x5f\x41\xfd\x0c\x33\x9a\x67\xc2\x92\x25\x17\x55\xd1\x6d\x2b\xec\x3d\x0b\x58\xf0\x3c\x12\xe8\xf5\x3f\x95\xe2\xc3\xd4\x8d\x69\x00\xba\xf1\xeb\xe4\xa9\xb6\x24\x7d\x48\x79\x6f\x89\x9d\x3f\x3b\x16\xe6\x16\x09\x17\x09\xcf\x78\x38\x08\xd7\xe2\x34\xe7\x84\x36\x5c\x28\x89\x32\x63\x87\x0e\xc4\x71\x2f\x7e\x2d\x44\x98\xb8\xd0\xb6\x6a\xf8\xee\x71\xbf\xf9\x2a\x0c\xcc\x25\xe5\x84\x0e\xab\xc5\x86\x01\x27\x1e\x35\x97\xc2\x12\xd3\x9c\xab\xd3\x28\x18\xc0\x25\x64\x98\x87\x54\xa2\x2c\x17\xcb\x9b\x0d\x57\x24\xc5\xd3\x6e\x62\x43\x63\x34\x05\x05\x1e\xc4\xd1\x4b\xfc\x7f\x36\x1a\x2a\xb3\xa2\xa5\xed\x6b\xfd\x7e\x38\x5a\x8e\x89\x83\x18\x21\xc5\x0c\xd7\xcc\xa0\xaf\x67\x39\x51\x2b\x50\xdd\x0c\x64\x3d\xc6\x06\x1b\xae\xf3\x14\xcd\xd9\xfd\xe3\x7e\x75\x77\xd8\x6f\x56\xf7\x87\xfd\xe3\xef\x9b\x87\x5d\xb8\x9f\x66\x49\x36\x0c\xc8\x42\x6d\xc9\xf0\x78\x10\x5b\x62\xa5\xfe\xd4\xa1\xfe\x06\x90\x68\x3c\x6e\x1c\x77\x66\xff\xb4\xb3\x5d\x9d\x43\x1e\xeb\x74\xc2\x30\x67\xd1\xd3\x17\xfd\x64\x8a\x1f\xc7\xe6\xdf\xbf\xf7\xd3\xbd\xfc\x18\xb1\xca\x4f\x9f\xc6\x10\x1b\xce\x51\xa2\xd2\x08\x4a\xc0\x70\x80\x35\xa0\xbf\x05\xb0\x53\xdf\x2f\x45\xca\xed\x0a\xde\x51\x01\xa1\x7d\x2d\x4e\xdf\xed\x51\xe6\x8c\xf7\x51\xf6\x68\x74\xfb\x88\xa4\xb1\x2f\x4d\xac\xe0\x1d\xcf\x91\x85\xa9\x67\x62\x82\xf8\xac\xcd\x5b\xf7\xbd\x2a\xc7\xc4\x7c\x93\xfb\xc5\x24\x8a\x70\x19\x4d\x26\xc7\x93\x28\x66\x92\xdd\x17\xe0\x00\x13\xd3\x84\x50\x77\xea\x78\x68\xcd\x64\xdc\x62\x9a\x72\x8c\x5f\xfa\x9c\x1a\xb2\xdb\xcf\x54\x88\x4d\xcc\x58\x86\x52\x7a\xa6\x30\x45\xfb\x1a\x14\x8f\x4d\xcc\x54\x82\x34\x2e\x56\xf2\x09\x9a\xa0\x82\x68\x62\x06\xb1\xaf\x7e\x47\xe4\xe6\x52\xb1\xae\x89\x39\xd5\x0e\x39\xd7\x54\x5f\xa0\x2b\xfb\x8e\xc6\xa8\x51\x48\xdb\x57\x34\x7d\x13\x6f\x6f\xc3\x0a\x8c\x79\xae\xb3\x89\xaa\x3e\x5c\x7d\x58\x04\xfa\x27\x63\x1b\xcb\x0c\xcb\x15\x3d\x89\xef\x34\x97\x35\xf5\x41\xe3\x94\x59\x8a\xc0\xe2\x42\x63\xe2\xab\xaa\x24\x13\xa7\x31\x51\xb3\xea\x3f\x54\x24\xf1\xcd\x89\xc0\x95\x76\x5b\xd7\xfa\x5a\x4c\xd0\xfc\x26\x4e\x73\x83\xa6\xe6\xc0\x3a\x1f\x02\x65\x5f\xd8\xc1\x71\x96\xa6\x08\x39\x02\x35\xca\x9e\xf9\x36\x61\x03\x7f\x0a\x6a\x1c\xc6\x89\x32\xae\x89\x33\x93\x61\x45\xc2\x5b\xdd\xc1\xf3\xb9\x1c\xd1\x77\xce\x0f\xca\x30\xcf\x72\x42\x12\x36\x22\x41\xb7\xd5\x2c\x75\x85\x5f\x7c\xbc\x8b\xc6\xb9\xa4\x42\xfa\x19\xb3\x3d\x9e\xca\x65\x6b\xc5\xf7\x06\x6e\x29\x1b\x8a\xaa\x37\xd5\x8b\x37\xb8\xab\x5f\x02\x84\xc3\xc4\x82\x48\xed\x20\x83\xe6\xda\xbb\xe3\xd3\x89\x23\x72\x60\xee\xd1\x56\x0e\x8b\xb7\x2f\xba\xae\x18\x66\xb7\x90\xcc\xd8\x4a\x62\xd0\x07\xf0\xc0\x22\x13\xf7\xc6\x55\xff\xf7\xbb\xed\xf3\xea\x4f\xff\x47\x99\x5a\x16\xc2\x13\x96\x18\xec\xdf\xeb\xd0\xe0\x2a\xa2\x8f\xe2\x27\xac\xd6\xe2\x12\x9e\xee\xfa\xa9\x44\x60\x4e\xd9\xf1\x00\x85\x64\x94\x6f\x96\x5a\x0e\x42\xd7\x7f\x40\x11\x1a\x34\x89\x6d\xfc\xc3\x16\x29\x3b\xf7\xca\x37\x6b\xc2\x88\x0f\xe6\xba\xc1\xff\x03\x8a\x75\x1d\x02\x01\xb1\x66\x12\xe9\x77\x83\x03\x66\x31\xe1\x9f\x14\x19\x99\x58\x67\x04\x91\x9e\xea\xdc\x34\x23\x15\x41\x13\x03\x4b\x32\x5f\x19\x5f\xa8\x6e\x6b\x53\xe0\x9f\xdc\x05\x22\x40\xa3\xc7\x71\x9d\x0e\xb3\x77\xa6\x6e\xed\xbb\x0b\xe2\xcb\xb6\xef\x6a\xd4\x8d\x18\x9f\x7a\xb3\x7b\x9b\x98\xd1\xd4\x01\x46\x57\x83\xf1\x65\x5b\x13\x42\x73\xb4\x95\xf6\x41\x6c\xf6\x37\xdf\x92\x28\xbb\x97\x60\x68\x65\x75\xee\x6a\x17\xaa\xf1\xed\x60\xb0\x54\xfe\xdb\xea\xe1\xfa\xce\x5b\xb1\x09\x8d\x59\xca\x1c\x65\x62\xbf\x05\x7e\x52\xbb\xe6\x7b\x6b\xab\x25\xe0\xc2\x37\x6e\xd3\x1e\x3e\x58\xc2\x14\xc9\x46\x85\xf7\x9f\x55\x3b\x4e\xdf\x29\x8a\x2d\x68\x05\xba\xd7\x8b\xac\xd9\xf2\x15\x5c\xa4\xc2\xd6\xe4\xbe\xd9\xc2\x18\x15\x8a\xe4\x4d\xc2\x65\x44\x3d\x31\xfd\xee\x0b\x97\x7c\xf6\x6e\x31\x95\x76\x0d\x3f\x7e\x7f\x7e\x58\x61\x99\xe8\x26\x94\x85\x9a\x24\xee\x2d\x87\x60\x98\x6d\x2a\x5d\x37\x2d\x62\x22\xe7\xf6\xb7\xeb\x9f\x46\x09\xd6\x90\x3c\x89\x8f\x1f\xa2\x6c\xf7\xf5\xdd\x08\xb0\x7f\x79\xa8\x25\xa9\xc8\x7d\xf5\xc2\xa3\x31\x58\x67\xe8\xac\xa9\xb0\xa6\x93\x2c\x92\x89\x45\xbb\xed\xba\xfa\x74\x0a\x41\xe1\x24\xe3\x39\x48\x57\x14\x00\xfa\xbe\xae\x6e\xea\xe6\xde\x25\x1d\x12\xee\x3b\x25\x14\x63\x2c\x06\xd5\x0d\x56\x63\x01\x4e\x93\xe4\x24\xb2\x65\xc7\xf8\x65\x9d\x02\xf7\xb0\x82\x93\x3c\x75\x29\xd3\xfe\xd4\xbb\x2a\xe7\xa5\xf3\x26\xc9\xa5\x40\x9e\x53\x85\x50\xd9\xcd\xdb\x5c\xaa\xc8\x24\x82\x29\xcc\xdf\x0e\x64\x3e\x75\x11\x40\x9d\x26\x11\x89\x13\x18\x6e\x0a\xf9\xd9\xf2\x4d\x64\x14\x61\x35\xca\x69\x41\x59\x72\xde\x35\x36\x1a\x46\xc5\x1e\xbf\x2d\x94\x2e\x99\x44\x26\x06\x71\x05\x9e\xdf\xdc\xfd\x59\x11\xcb\xd2\xdf\x9e\x4f\xd0\xdc\x7f\x81\x5f\x0d\xfd\x15\x9a\x0c\x45\xeb\x67\xf0\x43\x6d\x21\x44\x9f\xbe\x8a\x8a\x62\x4c\x01\xf5\xdf\x0c\xe5\x6d\x67\xc3\xa5\xb8\xf0\x85\xfb\x58\x42\x78\xd1\xac\x90\x88\xd0\xe7\x63\xe6\x7c\x0f\x1f\xe1\x55\x52\x8a\x55\xd6\xa0\x5f\xe0\xa9\x78\xe9\xa7\xec\x73\x68\xcb\x63\x3c\x24\x0a\x27\xd2\xe0\xea\x82\xfc\xd1\x39\xfd\x45\x9d\x31\xdc\x3a\x1d\xe6\xb5\x6e\x42\xd9\x83\x49\xb4\xce\xad\x88\xf6\xb9\xec\x8a\xb6\x78\x39\xd4\x83\x44\x46\xdf\x2a\xf1\x78\x71\x94\x5b\x0b\x00\x9d\xd1\x4c\x04\x61\xeb\x84\xee\xb7\x0f\x87\xbb\xcd\xea\x7a\xf3\x7c\xb8\x79\x5e\xad\x0f\xfb\xc7\x27\x7f\x3f\x50\x29\x7a\x24\x45\x07\xc7\x1f\x75\x07\xdf\x4f\xcb\x7b\x69\x62\x52\xd0\x83\xa2\xd3\xa6\x7b\xbd\x0c\x4d\x24\x46\x24\xae\x90\xa1\xad\xcb\xb7\x61\x4d\x19\x63\x2c\x60\x0f\xab\xf0\x3e\xd4\x0c\x2c\x66\x52\xa2\x98\x74\x00\x2f\x57\x81\x79\xf5\xb1\x9d\x45\x8d\x53\x46\x72\xc6\x26\xbc\x2d\x7f\x0b\x5a\x31\x5c\x1f\xa9\xc4\xb9\x37\x96\x43\xe8\x73\x7e\x51\x93\x46\x91\xad\x9a\xe9\xf7\x90\x0a\x6e\x9a\x59\x49\x86\x49\x31\x16\x88\xc2\x5d\xa2\xdc\x7a\x50\xb7\x7b\xe1\x94\x8b\x48\x5a\xe4\xd0\x03\xaa\x54\xff\xd8\xec\x90\xeb\xfd\x69\xf3\xbc\x7d\xbc\x1e\x7a\x65\x28\x4c\x83\x39\xef\x4d\xf7\xea\xb2\xb7\x2e\xc1\x16\x86\x2f\xe5\x06\x30\x1b\x72\xbd\xdb\x37\x67\xb8\x71\xbc\x10\xfb\x21\x86\x9f\xc6\x54\x20\xc6\x5e\x68\xbd\xff\xb5\xaf\x7d\x14\x39\x20\xba\xbf\x5c\x71\x69\xcc\xac\xca\xfc\x40\xdf\x05\xed\x0e\xc2\xcd\x13\x23\x2d\xb0\xf5\xb5\x3e\x89\x9f\x03\x73\x97\x49\x53\x19\xe3\x52\xad\xe0\xfd\xba\x56\xe7\x61\x0b\xf7\xed\x40\x71\xa7\xc3\x14\x6c\x98\xe1\x69\x2e\x88\x70\x2a\x0a\xb7\xe3\x92\xe1\xcf\xfe\x5d\x9c\x90\xa9\x20\x2c\x75\x34\x3e\x0f\xb3\x99\x22\x40\x78\xa8\xc0\x7a\xb3\xe7\x61\x2e\xf9\x13\x25\x95\x0c\x84\x7f\xb0\x7e\x4b\x9a\x14\xd5\x98\x54\xc6\x1c\x29\x3c\xae\xe1\xcd\xa6\xd3\xee\x11\x7b\xe6\x82\xc5\xd3\xdf\x92\x89\x0d\x21\xb8\x10\x5b\xa0\xb3\xf9\x5e\x15\x5e\x75\xcb\xa4\x8a\x33\xe1\x92\x3a\xff\x5d\xcb\xcf\x2c\x83\xff\x5a\xb4\x74\x2f\x19\xc0\x5d\xe0\x38\x14\x89\x8d\xf2\x7b\xfe\x0c\x4c\x95\x48\x90\x8e\xf4\xe6\xfe\x8f\x3b\xff\x14\x3a\x8e\x92\xc1\xd4\xda\x09\x03\xdd\x87\x55\x5d\x9f\xbe\x92\x4e\xad\xe8\x79\xb3\x83\x6e\x33\x9b\xf6\x5a\x58\xc2\x99\x10\x29\x9d\x49\x28\x9b\x14\x18\xc5\x72\x66\x64\x0f\xbc\x2d\x4c\x98\x47\x20\x2c\xdd\x56\xef\xf5\xd6\xb2\x9e\xd9\xe1\x29\x48\x82\x1b\xa8\x39\x57\xea\xe0\x43\x00\xa9\x61\x80\x1c\x15\xc8\x06\xff\xe9\xc0\xfd\xad\x84\x78\x6a\xb8\xa1\x0e\x92\xfa\xbd\x05\xcf\x1b\xe8\x77\xe8\x59\xdf\x44\x23\x3f\x80\xd3\x96\x99\x96\x94\xfd\x9d\x0a\x1f\x93\x9a\x4c\x32\xb7\xa9\x0d\x04\x89\x41\xd7\x73\xd6\x37\x37\x58\x7b\x24\xba\x4e\xa8\x57\x64\xfc\x9f\x79\xe2\x19\xa1\x11\xee\x48\xfd\x9c\x3d\x74\xaf\x0d\x80\x9b\xb5\x9b\x7f\x4f\xbf\x40\x46\xa8\xad\x5f\x3b\x35\xf5\xaf\x8f\x15\x02\xc9\x26\x23\x37\x86\x6b\x9a\x8c\x30\xc6\x9c\xb6\x06\x3e\x99\x65\x0d\x9c\x3c\x5e\x46\x98\xc2\x7c\x53\x8b\xf8\x0e\xcb\x5c\x3c\x8e\x35\x7c\x16\x75\xca\x48\x92\x22\xf4\xea\x54\x63\x1d\xeb\x12\x61\xb9\xc9\x48\x4a\x6d\xf1\x2f\xb6\x2e\x69\x56\xf8\x69\x9d\x11\x91\x31\x77\x92\xcb\xf3\xc7\x08\x95\x6f\x32\xa2\x65\x92\x07\xd2\x0c\xcb\x93\x1d\xf4\xed\x4d\x46\xa9\x44\x70\x87\x5d\xa7\x21\x55\x34\xb1\x34\x33\xca\x12\x4c\x55\xdc\xfa\xfc\xce\xec\x49\x69\xca\x51\xd4\x08\x83\x94\xbb\xa3\x68\x3a\x35\x45\xce\x65\x14\xb8\x9c\xaa\x09\x88\x7c\x01\x42\x92\x31\x92\xc4\x72\x5a\x47\xfe\x03\xaa\x4f\x0c\x9c\x8c\x01\xc3\xf8\xc0\xd3\xf7\xab\xbb\xed\xfa\xf0\xbc\xd9\x3d\xde\xfd\xd8\x3c\x1f\x1e\x1e\xaf\xbd\xfb\x91\x45\x89\x56\x4e\x0e\x62\xd5\xfa\x19\xb1\x98\xf0\xcb\x22\xa1\x8c\xdb\xf0\x0f\x6a\x79\x24\x38\x4d\x30\x07\xae\x6b\x1f\xcf\x9a\xde\x22\x96\xe0\x38\x0d\x4a\x65\xbf\xea\xd7\xd5\x7b\x26\x8b\x4d\x8e\xc1\x7c\x63\x83\xcd\x33\xc8\x61\x96\x30\x2b\xec\xda\x20\xd2\xb7\x5f\x9f\x96\x20\x6d\x69\x75\x66\xa9\xb1\xca\x04\x58\xb1\xef\xf3\xd9\x9f\x9f\xe6\x59\x16\x69\x7c\x1b\x9f\x2b\xdc\xfc\xb2\x61\xff\x09\xef\x41\x98\x64\x59\x6a\x90\xa4\x42\x9e\x3f\xa6\x65\xf1\xd3\x60\xde\xec\xfd\x72\x49\xf2\xa1\x98\xee\x60\x60\x99\x14\xc0\x64\x82\x70\xcf\x75\xe8\x6a\x3a\xfa\xb7\x7d\x6a\xea\x63\x3d\x92\x8f\x32\x99\xe0\x0a\xcb\x9a\x7c\x0d\xc4\xae\x12\x45\xf9\x14\xd0\x5d\x99\xc8\x99\x74\x19\xf7\x63\xff\x01\x9a\xf3\x98\xb6\x63\x30\x03\x33\x01\x96\xe6\xfa\xd6\xee\x7b\xd6\x96\x9e\x8d\xa8\x30\x1c\x23\x99\xe2\x08\x95\x06\x3d\x0b\xf3\x4d\x5f\x40\x12\x1b\xb5\x7f\x81\xce\x62\xd3\xaf\xbc\x85\x9c\x29\x16\x23\x21\x33\x74\xaf\x63\x7f\xd1\xb7\xa6\x96\x8c\xe0\x60\x17\xe1\x5d\xa1\xa0\x6a\x3f\x87\x63\x2e\xee\xe2\x99\x32\x12\x6f\x52\x16\x06\x5c\x8c\x63\x67\x69\x89\x5d\x07\x9d\xc7\x89\x2b\xb6\x2d\xe6\x60\xb5\xbe\x11\x7d\xab\x83\x46\xa9\x9b\x79\xab\xc9\x2d\x90\xd7\xfb\x55\xf7\x1f\x4b\x87\x7e\x06\x84\xe5\xb6\xfc\xa1\x69\x9d\x3e\xcb\xac\x87\x21\x29\x96\x2c\xec\x8a\xe3\xa9\x84\xbb\xc2\xf8\x7d\x2a\x27\x24\x47\x33\xf4\x28\xaa\xb3\x28\x9f\x85\x31\x21\x89\x98\x53\x2e\xc0\xa1\x45\x03\xf0\x77\x4e\xda\x39\x7c\xd8\x9c\x45\x06\x53\xb5\x0f\xdb\x7f\x6e\x6f\xbd\xde\x96\xc9\x99\x53\xb6\x7e\xc1\x54\xe4\x75\x53\x9f\xda\x27\x68\xf6\xbf\x7c\x7b\x14\x47\x18\xe8\x39\x14\xad\x05\xec\xdd\x94\x62\xaa\xc0\x63\x72\x9e\x13\xf4\xb9\xa5\xa8\x7e\xfe\x10\xe5\x84\x29\xd5\xe4\xb1\x22\x98\x29\xe8\x8a\x23\x48\xac\xb6\x82\xcf\xf5\xc9\xdc\x35\x09\xcb\xc0\x45\x6e\x1e\x4b\x3d\x86\xaa\x7c\xea\xc9\xe7\x49\x42\xec\x74\x72\x41\xdd\x76\x24\x17\x68\xf2\xc4\x44\x48\x20\xdd\xd5\xdb\x60\x7a\xe7\xa9\xa4\xa8\xa0\xd4\x6f\xe1\xe7\xf6\x14\xca\x09\x4c\x9e\xea\x1c\x23\xb9\x3f\x56\x77\xdb\xeb\x20\x8e\x69\xf2\x8c\xc9\x94\x87\x93\xc1\x45\xab\xfa\x13\xdb\x06\x70\x97\xe2\x8e\x79\xce\x99\x31\xc1\x45\x0f\xa6\x7a\x9e\x73\xab\x95\x74\xf5\xb1\x7f\x05\x47\x55\x38\x99\x62\x79\x2e\x28\x9e\x60\xad\x28\x61\x53\xe9\x91\x1a\xb8\xc9\x73\x23\xb0\xca\x13\xf1\xd1\xf8\x18\x53\xe6\x9e\xd9\x43\x88\x28\xc3\xfa\xdf\xc7\x3f\x1e\x36\xcf\xbb\xc3\xea\xee\xee\x71\xbd\xda\x6f\xae\xa7\x69\x98\x5c\x18\x8e\x68\x9b\xd5\xef\x7c\x1c\xe5\xca\x25\x8b\x89\xdb\x87\x82\xf5\x3e\xfd\x01\x99\x19\x3d\x6c\x69\x8e\x12\x79\xd0\xe2\x98\x9b\x43\xa3\x99\xa9\x52\x5b\x3a\x77\x6a\x7a\x87\x7f\x71\x3e\x28\xa9\x11\x75\xe2\x91\xfa\x16\xc1\x34\x62\x69\x36\xb9\x82\xd8\x1b\x6c\xcf\x60\xa6\x56\x4e\xae\x89\x2d\x89\xbd\x11\x0d\x86\x78\x26\xef\xa6\xf3\x18\xf4\x17\xa5\x6d\x9f\xcc\x51\x20\x80\x7e\xdb\xe1\xc5\xeb\xb8\x60\xdd\xe0\xf2\x46\x9e\x03\x8b\xb0\x76\xf6\x58\xbc\xd8\x08\x4f\x08\x98\xfa\x0e\x11\xcf\xad\x0a\x1c\x26\xc0\x1c\x1e\xe0\x2f\x1e\x21\x26\x18\x8c\xb8\x2b\xba\xc9\x1b\x41\x2e\xbc\x0a\x81\x27\xd4\xb8\xe4\x14\xee\xbb\x69\xc3\x42\x6c\x6d\x5b\x0d\xd8\x9f\xe9\x34\x34\xb1\x4c\x06\xb8\x01\x9e\x2f\xdb\xeb\xf0\x9e\x93\x5b\x9a\x34\xc5\xed\xe2\xaa\xe8\xd6\x4d\xff\xd3\xde\x38\x17\x94\x00\xce\x20\x57\x98\x39\x45\x1f\x0b\xca\x23\xac\xdf\x1e\x29\x40\xf6\xdf\xd9\x56\xf0\xfa\x3e\xb9\xad\x82\xef\x1d\x7f\xa4\xbb\x9c\x2b\x8f\xf4\x5d\x32\x32\x10\x05\xec\x6d\x20\x76\xb0\x62\xa9\x55\xd2\xfc\x2f\x4b\xbf\x32\x4c\x41\xc1\x68\x86\x1b\x41\x6f\x89\x8d\x72\x76\x82\x69\x5b\x09\xf2\xe2\xf8\xb8\xd8\x80\x32\x15\xcc\x40\xea\x49\x31\x51\x8e\xc6\x92\xc1\x0f\x39\x52\xc1\x89\xc9\xf9\x44\xb1\x75\x6e\xa3\x0a\x9e\x64\x58\xf3\x88\x8f\xe7\x49\x97\xc7\x7e\xb1\xe0\xa0\xc9\x10\x4b\x99\x92\x2f\x4d\x5f\x9e\x1b\x86\xe5\x78\x6f\x23\x94\xac\x88\x39\xe8\xcc\x73\xea\x94\xb0\xff\x38\xc1\xaa\x1b\x13\xd0\xd0\xb1\xa5\x42\xfd\xbd\xe2\x4c\xa2\xfb\x17\x4e\x96\x11\x7c\x45\x24\x84\x12\x77\xf2\xdc\xf6\x6b\xb0\xf9\xd8\x15\xbf\x2e\x35\x51\x8d\x48\x68\x2c\x6d\xb9\x6e\x35\x1a\xb8\x84\xdb\x90\x2e\xb2\x20\xae\xb4\xb6\x62\x09\xbe\x31\xcb\x1c\x83\x84\xe5\xb7\x08\xf6\xfd\x18\xa7\x2b\x92\xdc\x08\xaf\x21\x3d\x06\x01\x88\x2c\xe6\x18\xa2\xda\xde\x6f\xfe\xdc\x4f\x1a\x44\x2a\xe7\xf9\x65\xab\x4d\x38\xa2\xc1\x77\x7d\x73\x4a\x05\x04\xb9\x4d\xcf\xee\xee\x1b\x8d\x32\x23\x1f\x1e\x27\xa2\x6f\x13\x60\xa5\x65\xaf\xce\x4d\x75\xb3\x5b\x2d\xe8\x6b\x18\x21\x8c\x55\x61\x98\x70\x0a\x1a\x21\x33\x83\x43\xb5\x11\xdd\xf4\xef\x2e\x7f\xa6\xe1\x0d\xca\xfa\x84\x6c\xd7\x67\x5d\x74\x68\x02\x62\x56\x0c\x7f\x64\x1a\x8b\x17\x2a\xb1\x30\xaa\x93\xf8\x78\x34\x26\xfc\x55\xc7\x0e\x27\x69\x31\xa5\x57\x45\x59\x5e\x44\xfc\xff\x96\xbf\x2a\x94\x36\x56\x72\x45\x74\x03\x5d\xa6\x11\x9a\x66\x11\x9f\xc8\x34\x4c\x16\x84\xce\x05\x56\x0e\xfe\xdb\xeb\x61\xfa\xbf\x4b\x8d\x54\x9e\x47\xb7\x33\x4f\x15\x6b\x8d\xd0\x2a\xb2\xdc\x12\xd6\x04\x3e\x9c\xca\xba\x3b\x8c\xca\x7c\x8d\x00\x9a\xe3\xc8\xf7\x46\x46\x55\xbf\x87\x3f\x6b\x1e\x39\x0c\xde\x9f\xfb\x1f\x96\xa9\xc3\x46\x9c\x9d\xcb\x36\xda\x03\x4c\x4c\xb1\x10\xf7\xad\x3e\xab\x29\xa9\x80\x11\xc6\xe4\x76\x3c\xdd\x83\xcd\xe0\x09\x97\x87\x9a\x24\xd2\x52\xd1\x5a\x0a\x8b\x67\x07\x5b\x7c\xf6\x33\xca\x3d\xa0\xa4\x99\x40\x09\xa9\xde\xb3\x12\xbd\x05\xba\xe0\x91\x48\x2a\x24\x22\x5b\x0e\x2e\x18\xd1\x9f\x0d\x75\xd3\x39\x92\xbb\x6d\xb5\xaf\xcf\x4d\x25\x26\x19\xe4\xc9\xd7\x92\xd4\x80\xc5\x2a\xba\xdc\xb9\x47\xf5\x8d\x7d\x62\xc9\x22\x8a\x00\x8a\xfe\x9e\xd3\x7c\xa0\x64\x51\x86\xc7\xaf\xb1\x6c\xa3\x63\xc2\x74\x23\x59\x28\xff\x11\xe1\xb5\x22\x96\x58\xfe\xcf\xd5\x9f\x87\xcd\xfe\xdb\xe6\xf9\xb0\x7e\x7c\xd8\x3f\x87\xe6\xdc\xa2\x82\x2c\xdb\xc8\x5f\x09\xf0\x1a\x19\x49\x50\x6c\xc2\x05\x3b\x42\x74\xc9\x08\x94\x23\xde\xb0\x59\x77\xc7\x69\xd4\x5e\x7d\x78\x75\xb7\xe9\xfa\x96\x3c\x53\x88\xee\x5b\xad\x56\x23\x54\x9d\x8c\xa9\x40\x88\xbf\xa5\x81\xea\x8f\x74\xd3\x8f\x70\xdb\xcd\x8a\x0d\x65\x9c\x65\xd4\x85\x0c\xef\x8b\xea\x56\xb4\x93\x71\x8c\x15\x55\x72\x2c\x15\x35\xdd\x00\x64\xc2\x01\xa3\xf2\x2f\xe2\x08\xdb\xca\xab\x94\xfa\xab\x93\x38\x46\x3b\x75\xfd\x64\x75\x9c\x3c\x32\xcb\x35\x67\x32\xb1\x44\x44\xc6\x14\x65\xd1\x1b\x5a\x21\x59\x35\xfd\x95\x9c\x49\x4a\xdc\xaf\x3c\x48\xbf\x43\xc9\x3c\xcd\xe2\x34\x30\x24\x9c\xea\xea\xfe\x5c\xda\x62\x34\xdf\x43\xc6\x11\xfa\x09\xad\x7a\x05\x7d\x2e\x61\x92\x7d\x9e\xb0\xba\x8d\x23\x43\x52\x66\x06\xbd\x9c\xde\x4e\xdf\x43\xd3\xa1\x5c\xfe\x92\xf8\x93\x91\x8a\x59\x2e\xac\x93\xd5\x4c\xd8\xdf\xfd\xe3\x34\x06\x7b\x48\x95\x44\x3c\xf6\x59\xfd\x43\xa8\xe6\xf5\xcd\x9a\x5b\xa3\xc7\x09\x90\x5d\x37\xe2\x3d\x34\x09\x86\x05\x7e\xeb\x57\xd1\x14\xdd\xc7\x78\x23\x95\x46\x83\x63\xe0\x05\xf5\xf3\xfe\x63\xf5\x32\x4a\x65\xf9\x2e\x46\x79\x7e\xa4\x7e\x11\x5c\xcd\x9e\xdb\x18\x85\x0e\x97\x2c\x74\x3b\xde\xd6\x14\x61\x11\x8a\xb3\x74\x8d\x28\x2a\xba\xbc\x06\x15\x8d\x0d\xf5\x26\xec\xf8\xc1\x14\x63\x2a\x76\x85\xc9\x4e\x45\x62\xa1\x90\xdf\xa8\x08\x62\x7c\x37\xc7\xf8\xeb\xaf\xe6\x5c\x78\xc7\xde\x46\xf2\x27\x29\xc0\x25\xbc\xe6\xec\xb9\x78\x9e\x4b\x84\xa1\xbc\xd6\x47\xf8\x09\x1f\xe1\xc6\x4a\xa0\x58\x03\x32\xc7\xef\x5f\x1b\x00\x1b\x70\x98\x5d\x0d\x19\x6e\x1a\xcf\x67\x5d\x88\xca\x49\xce\xf9\x5b\xc4\x9e\x35\xeb\xc5\xe3\x75\x7c\x03\x8b\x10\x02\x84\xe1\x49\x53\x9f\x9b\x10\x9d\xfc\x5e\x0c\xc3\x1a\xcb\xc4\x4b\x97\x1d\x7a\x0f\xe8\x20\x1a\x59\x74\xed\xe1\x04\xcd\x01\x50\xa2\x72\xfa\x2c\x31\x58\xad\xc1\x43\x7d\x82\x6a\xa8\x75\x9f\xe1\xf0\x5c\xe7\x44\xe4\xa9\x70\xe9\xfe\x87\x70\x60\xa8\x44\x2a\x34\xd9\x4e\xe2\xe3\x7a\xf5\x18\xfe\xaa\xd3\x58\x8c\xcb\xf3\xf6\x41\x9f\xc2\x77\x49\x21\xc2\x13\xe2\xad\x2e\xcf\x47\x34\xb3\x7c\x7d\xa4\xca\x18\x05\x08\x46\xa4\xfa\xf9\x5a\x97\x36\xa6\x15\x2a\x64\xd7\x97\xc6\xb9\xca\x12\x1d\x39\x74\x66\x10\x98\x74\xf6\xda\x97\x4e\x81\xca\x24\x61\x3e\x5f\xd1\xcf\xa6\x6f\xc2\xf1\xc4\x07\x20\x4d\x78\x30\x25\x50\x03\xfa\xbf\x61\x26\xf3\xde\x37\xd9\x32\xf7\xf7\x01\xc2\xa2\x72\x62\x4b\xa7\x84\xdf\x72\xe8\xec\x91\xf3\x4c\x5a\xf0\x76\x2d\xeb\xee\x82\x1d\xcc\x28\xc9\x28\x26\x87\x40\xd5\x6e\x16\x8f\xe9\x5b\x8c\x52\x90\x78\xc4\xfc\x35\x9c\x1a\x98\xe6\x2c\x17\x4e\x46\xa5\x49\x62\x44\x58\xd4\x45\x55\x1c\x45\x39\x70\x61\x1b\xa5\x35\xd3\x63\xdc\x7f\x37\x21\xf6\x9a\x2e\x30\xa0\x32\x73\x29\xbf\x15\xde\x68\x6c\x71\x2a\x10\x1a\xc7\x6a\xff\xfb\xf3\xd3\x78\xa4\x34\xa1\x02\x29\x7b\x8b\xf6\xe0\xad\x83\x83\x98\x98\x8c\x9a\x98\x94\xa5\x9e\x79\x70\xdf\x04\xe3\x5c\x53\xc3\xf0\x1b\xdf\xd5\xf5\xcf\x55\xb7\x2a\xcb\xfd\x2b\xb4\xb0\x17\x6d\xf7\x71\x03\x21\x48\xa5\x59\x44\xac\x2e\xc0\xb9\xe9\xdd\xb4\x0e\x5e\x9a\x79\x52\x40\xb3\x34\xcf\x5d\xdd\x2c\x96\x2d\x3e\xf5\xa7\xc6\x08\xd7\xf5\x3f\xe9\x10\x31\xe1\xff\x72\x08\x4d\x4f\x2b\x6e\x34\xcb\x23\x0c\x88\xd7\xc6\x40\xb3\x18\x1d\x9d\xce\x32\x1d\x45\x29\xba\x73\x37\x75\x3d\x5a\xd9\x3a\x12\x11\x52\x9d\xb4\xbd\xb7\x84\xbb\xc6\x26\x58\x87\x3a\x52\x39\x22\x11\x44\x6b\xd9\x73\x7f\x85\xa2\x15\x87\x95\xd0\x49\x66\xc5\x81\x4a\x8f\x10\xf6\xae\xb8\x6f\x97\x14\x8d\xe7\x6d\x55\x2f\x31\xa5\x8c\xe7\x86\x4e\x13\x81\x27\xd2\xfd\xea\x61\x75\xbb\x41\x60\xc9\xdd\xe3\xfa\xf7\xcd\xb5\x0d\x7e\xf8\x5b\xf6\xcb\xc5\x2b\xc1\x8c\xa9\x5e\x8d\xce\x94\xc2\x4c\x34\x2a\x17\x1c\x8b\xee\xa2\xac\x5e\x67\x4a\xe3\x0e\xb5\xd9\x7f\x7b\x46\x88\xd5\xb2\xfd\xa2\x73\x9e\x60\xf0\xc5\xa1\x0d\x91\x02\xbc\x84\xeb\xba\xfa\x09\x1f\xb3\x1d\x55\xe7\x69\xc2\xa8\x5b\xbe\x3e\x7c\xf2\x0d\xe5\x2f\xda\x7d\x5d\xdf\x89\xe6\x05\xa6\x45\x59\x3a\x57\x71\xa2\xfd\x22\xb8\xae\xcf\xb2\x04\xfd\xd4\xd4\xe6\x92\xd3\xc7\x5d\x20\x28\xcb\x1c\x57\xc6\x01\x9f\xc0\xff\x9d\x53\xdc\x13\xef\x56\xd7\x7f\x39\xba\x22\x8e\x10\x91\x69\x46\x3e\x84\x6f\xca\x59\xe2\xca\x16\x6f\x47\x85\x7b\xd3\xeb\x65\x64\xe9\xf6\xc4\xcb\x4b\x83\x36\xda\xfa\xfa\x09\x9d\xdb\x59\xcd\x80\x96\x91\x65\xd5\x94\xe7\xa2\xd4\x7f\x14\x15\x04\x88\x85\x96\x71\x4a\x2d\x36\xe8\xb6\xb9\xac\x1c\xd3\x32\x25\x98\x36\x39\x95\xa2\x33\x75\x73\xb4\x51\x85\xf1\x8e\xa3\x65\xa6\x30\xc2\xab\xc3\x60\x4a\x99\xe0\xd1\xf4\xbc\xda\x6f\x0e\xfb\x6f\xcf\x9b\xdd\xb7\xc7\xbb\xc0\xe8\xb3\xba\xf5\x29\x14\xad\x94\xce\xb4\xdb\xac\xd6\x0f\x37\x75\x73\x2b\xe6\x9f\x52\x81\xc1\x75\x8b\x25\xbf\x87\xab\xcd\xcd\xe3\xf3\xe6\xb0\x7b\xbc\xd9\xaf\x57\x4f\xbf\x0d\x7d\xd0\x25\xd2\xf5\xee\xb2\x0a\x50\x6b\x9d\x23\xab\xf7\x9f\x7f\xf9\x3d\xb4\x36\x88\x59\xde\xdc\xde\xee\x0e\xfb\xc7\xc3\xb7\xd5\x7e\xfd\xed\x40\x9f\x56\xeb\xed\xcd\x36\x90\x57\x68\x0d\x29\x0e\xfb\xfd\xfe\xa9\x7f\xa7\xde\x38\x3f\xec\x56\x01\x97\xa6\x35\x00\xc6\xff\x8a\x76\x85\xda\xc2\xb3\x09\x0f\x9a\xe7\xb6\x5e\xcc\x40\xd3\x88\xf2\xba\x68\x9d\x0c\x77\xa8\x7e\x9a\x5d\x00\x06\x2f\x30\x6d\x37\x4a\xb0\x01\x89\x99\xa7\xe1\xdc\x37\xe2\x0d\xca\x75\x3d\xcf\x32\x00\xe5\x40\x9c\x65\xb3\x42\x09\xf9\x09\xf6\x13\xa2\xc8\x52\x90\xe1\x66\x32\xc8\xe9\x18\x88\xb4\x41\x33\xbe\x04\x61\x0e\xa6\xa9\x8f\x07\x77\x5f\xac\xb5\xac\xce\x47\x57\x7a\xb9\xbc\x56\x21\x32\x1c\x37\x6b\x47\xe3\xf7\x35\xa3\xfb\xbc\xa0\xd5\xdd\x83\x47\x84\x59\xa7\xdd\xe2\x7b\x9e\xe1\xb4\xf2\xc4\x8f\x37\x75\xb3\xf9\xd5\x35\xe2\xaa\xae\xb4\xd5\x77\x9e\x4d\x1b\xe0\x8e\x4a\xcc\x61\x3b\x66\xad\x69\x2c\x71\xde\x7d\xaf\x0a\x4f\x7f\x68\x20\x4f\x01\xb3\x50\x25\x98\x8e\xe7\xb3\x2b\x72\x69\xb0\x6c\x75\x29\x9b\x39\x7b\xf9\xdc\x30\x2c\x38\x42\x23\x12\xb9\xff\x9e\x5c\xe5\xc0\x57\x1c\xf2\x78\x9d\x0c\xfc\xf0\x56\xa5\x65\xe9\x84\x07\x41\x95\x4f\xc9\x6e\xfb\x4d\x6d\x82\xb4\x00\xc1\x22\x4c\x62\x4d\xb3\xcb\x5f\x82\x18\x41\x48\x1b\xf6\xbd\x6e\x40\x1c\xff\x16\x7b\x96\x01\x49\x25\xc6\xc4\xbc\x55\x70\xc1\x43\x3f\xfd\x09\xc9\x4d\x66\xc5\x6a\xab\x9f\xe0\x8b\x76\xc6\xe3\xe0\xa1\x7e\x20\x63\xc3\xe4\xb8\xc0\x60\xf6\x25\xa4\x24\x98\x8a\x94\x42\xfd\x2c\xeb\x97\x31\xf7\xae\x01\x09\x19\xa2\x08\xd6\xa5\x38\xf5\xff\x37\x3e\xf8\x40\x91\x38\x71\x7c\x32\xaa\x9c\x07\xac\x40\xd1\x18\xe9\xc0\xba\xe2\x08\x77\xb5\xfa\xd9\x7b\x2f\x17\x5d\x84\x2f\x23\xd8\xaa\xda\xaf\xdb\xd9\xf3\x29\x2e\xd0\x31\x46\x0d\xf6\xff\x2d\xaa\x97\xff\xbc\x16\x8b\xe6\x33\xa8\x9c\x0a\xee\xe5\xb2\x97\x50\x0a\xa0\x34\x38\x59\x04\x0c\x3c\x0e\xe1\xc1\x6c\x39\x57\x07\x0a\xb4\x97\x81\xb5\x03\x33\xe0\x95\xfb\x6d\x87\x7a\x3c\xc3\xae\xab\x1b\x70\xa9\xde\x95\xe9\xfa\xa9\x09\xea\x67\x60\xaa\x35\xa0\x95\x42\xee\x9d\xee\x33\x50\xeb\x67\x8b\xf9\xa2\xe2\x1b\x80\x65\x58\xfa\x55\xd6\x2f\x9b\xee\x75\xff\x6b\x7a\x36\x81\x51\x2c\xd6\x83\xe2\xeb\xd5\x87\x27\x05\x9c\xbe\x99\xd1\x92\xd0\x91\xaa\xc3\x2d\x54\x41\x38\x3a\x5b\x24\x9b\x5a\xda\xe2\xc1\x98\x18\x5d\xfa\xf6\xb5\x7e\xbf\x17\x85\x63\x92\x0c\x8d\x69\xa2\x3d\xda\x40\x4c\xb2\x1f\x86\x10\x29\x46\x54\x90\x8e\x0e\xf7\xf3\x54\x9a\x21\x82\x62\xb2\x02\x6b\xbd\xc6\xf3\xd0\x10\x21\xc9\x20\x69\xf8\xbd\x85\xa0\xbf\x3d\x19\x19\x43\xa9\xb2\x11\x9e\xe2\xe5\xb5\xcb\xe2\xe9\xdc\x30\x54\xc4\x48\xa8\xb6\x6d\xf1\xdb\x3d\x00\xe8\xcf\xb6\x16\x43\xb5\x05\x88\x5b\xa8\xc6\x9f\xfe\x24\x33\x1e\x13\x8d\xb6\x99\xa8\x86\x3a\x12\x43\xc1\x9e\xfb\x6f\x05\xbc\x4f\xab\x11\x0c\x23\x2a\xf3\xea\x0d\x58\x54\x35\x32\xf1\x0d\x4b\x14\x7e\x26\x25\x3a\xf5\x0a\x33\xff\xdb\x44\x11\xc5\x30\x57\x05\xef\x6b\x71\x59\x8b\x6f\x38\xb3\xce\x6e\x10\x8c\x5c\x69\xed\x83\x2a\x86\xf7\x13\xd8\x9b\x68\x37\x45\x09\xb3\xe1\x8a\x79\x46\x07\x14\xef\x0e\xca\xd2\xe6\xfa\x96\x87\x24\xe6\xca\xf1\x09\xb6\xe7\xc5\x60\x81\x49\x92\x08\x2d\xbc\xd5\x7a\xed\x0d\x5d\x93\xe4\x14\x77\xd7\xe3\xc7\xa6\xea\x8a\xee\x63\x1c\xc2\x30\xa9\x61\x54\x59\x20\xe9\x24\x1c\x64\x32\x95\xfb\x34\xa3\xf5\x8a\xda\xc9\x98\x65\x5a\x58\xc2\x70\x50\xc5\xa9\x80\xaa\xf3\x5e\xaf\xc9\x33\x1e\xbb\x0d\xe7\x70\x1a\x85\xf1\xff\x66\x9c\xd9\x46\x2c\xc6\x3f\x95\x8b\x0c\x1d\xad\xa3\xf8\x09\x7f\x0e\xf9\x27\xd7\x2a\x58\xca\xc5\x68\xd1\xb7\x3e\x03\x59\xcf\x86\x46\x66\xc6\x32\xd5\x7a\xb0\xde\x58\x12\x67\x69\x63\x32\x52\x73\x07\x41\xb7\x61\xf3\xa5\x18\xad\x51\x2c\x43\x57\xee\x20\xcf\x1f\x5b\xd5\x2e\x33\x7a\xfa\xbe\x99\xa5\xa8\xed\xea\x75\x7d\x3c\x89\xe6\x13\xf0\x07\x3a\x75\xd9\xa4\xd2\x07\x41\xc6\x96\x27\xa1\xbb\x4c\x0e\x0e\xe1\x67\xa3\x85\xd4\x56\x1b\xb7\x38\x8c\x13\x24\x06\x62\x9b\xb5\x44\x32\x8a\x3f\xea\xe6\x62\x8e\xfd\x0f\xfb\xd7\xd4\x9a\x31\xfd\xb9\xa5\xbd\x04\x48\x75\x6e\xe7\xe2\xe2\x9c\x10\x42\x18\xe2\xc3\x8f\xb5\x2e\xcc\xc7\xe3\x09\xaa\x59\x7c\xbd\xef\x43\x13\xee\x36\xcb\x75\xff\xe3\xd7\xa2\x13\x6c\xfc\x15\xfb\x3e\x09\xa1\xc6\x45\x65\xac\xc0\xcc\x5f\xcd\x17\x7f\xa1\x00\x31\xe6\x24\x5c\x55\x7a\xa9\x6c\x66\xd8\xdc\xfb\x6b\x74\x8c\x05\xda\x57\xab\xf5\x1e\xda\x8e\x2e\xb2\x7e\xcf\xcd\x07\x4e\x08\x65\x09\xc6\x2f\x31\x16\x0d\xfb\xc2\xe5\x7f\xfa\x96\x58\xe7\x79\x80\x26\xa3\x62\xee\x3c\x0c\xd2\xf7\x52\x00\x2e\xcc\xf8\x04\xd0\x2c\x66\xa1\xfa\x6e\x10\xa1\x29\xbe\x83\x4a\x6f\xba\x57\x9f\xc7\xe1\x84\x30\x1d\xd9\xb4\x6f\xef\x0c\xde\x9c\x2b\x15\x82\x3a\x7d\x23\x68\x0c\x62\x56\xf0\xab\xc3\xb4\x83\x63\xcf\xed\x9b\x0c\xc1\x1c\x13\x6e\xba\xeb\xfa\xdc\x4c\x89\xd6\x39\x21\x51\x6c\x63\xd7\xa2\x37\xda\x6e\xea\x66\xed\x6b\x1a\x67\xc8\x86\xe5\xd3\x6a\x3e\x0f\x39\x21\x5c\x06\xd9\xb0\xd5\x51\x8a\xb6\x15\xba\x9e\x4f\x9e\x38\x33\x68\xdb\xec\xb7\x9b\x67\xe6\x9f\x35\x49\x6c\x0d\xeb\x44\xba\x6a\x14\x76\xed\xbb\xa4\x0a\x37\xd5\xbe\xc9\x13\xaa\xf9\x26\xa5\x2c\xf8\xde\x45\xee\x9f\x45\x57\xd4\xbe\x31\xa5\x19\xd6\x44\xc3\xaf\x53\xff\x14\x57\xe7\x8f\x87\xf3\x71\x07\xea\x62\x25\xcc\x0e\xc6\xfe\xd2\x5c\x7b\xb2\x43\x4f\x40\x39\x51\x19\xf8\xaf\xc9\x68\x66\x09\xc5\x98\x51\x40\x08\x85\xd4\x32\x36\x0a\x9c\xb1\xba\x68\x40\x75\xd7\x20\x8b\x45\x5d\x09\x4e\x88\xe0\x1c\x8d\xeb\xcd\x45\x49\xf1\xc2\xe4\x14\x5c\x83\x74\x85\x45\x8e\xc3\x64\x54\x02\xd8\x77\x10\x02\x37\x80\xf5\xde\xc5\x40\xf0\x6f\x80\x85\x93\x45\xbb\xad\x1c\xcc\x6c\x54\x8a\x32\x7b\x1a\x0d\x10\x0d\x89\xd4\xab\x8f\xf5\x67\x45\x55\x9c\x10\x19\x3b\xc6\x70\xe8\x9e\xe1\x65\xbe\xda\x65\x26\xcd\x28\x27\x7b\x3f\xa4\xc9\x7d\x07\x41\x92\x7c\x42\x36\x02\x8b\xdc\x15\x7d\x57\x19\xe1\x2b\x58\x0c\xd5\xfe\x76\xf3\x77\x39\x15\xc3\xf5\xd6\x27\x68\xc0\x29\x4c\xdc\xba\xea\xc3\x76\x8f\x05\x5d\xab\x4a\x5f\x9d\xc3\xfc\xd2\xd4\x60\x8a\x42\x77\xb7\xa8\x87\xb7\x80\x3c\xe4\x84\x40\x94\x23\x02\xb4\x3a\x1f\xbd\x91\x1c\x5e\xad\xf7\x2a\x62\xac\x53\x6a\x44\xf0\x5e\xfb\xbf\x83\x05\xc1\x5a\x58\x8e\x8f\x58\xd1\x7f\x1c\xb0\x72\xda\xf7\x32\xa9\x4d\xa1\x20\xb1\x6b\x61\x37\x99\xe5\xc9\xd3\x9f\x9b\xdc\x62\x93\x6f\xbd\x03\xce\x09\x25\xc2\xd6\xf2\x62\x3a\xd2\xbb\xa6\xd3\xc7\xa7\x94\x1a\x34\x29\x9f\x37\xbb\xcd\xf3\x8f\x00\x15\x3a\x5c\xad\xd6\x1b\x2c\xe1\xf6\x37\xa3\xa9\xc1\xc0\xfb\x5a\x54\xe3\xe2\xb8\xbe\x45\x0a\x04\xc7\xdf\xaf\x9e\x7f\xdf\xd8\xaa\x86\xc7\xc7\xbb\x31\xe6\x88\x13\xca\x28\xc7\xa0\x9f\x53\x77\x10\x8d\x38\x7e\x8a\x0f\x5d\xfe\x7a\x94\x65\x5a\x46\xa3\x23\x7a\xd5\x86\xd4\xdf\xe8\x2c\xeb\x3b\xe6\x02\x19\x28\x1c\x4a\xe9\x73\xe4\x6b\xdf\x17\x08\xd6\x28\xe1\xe8\xba\xbf\x45\x71\x62\x2c\xdb\x5a\xd9\x0d\x7f\xcb\xe9\x68\x45\x60\x1d\xea\xf4\xf1\xb8\xa2\x6a\x64\x73\x9c\x7b\x27\xa0\x62\x37\x42\xc1\x9c\x86\xc6\x5d\x10\x43\x16\xd9\x04\x69\xb5\x71\xbc\xce\x13\x0c\x2c\x27\x34\xa1\xd4\xa2\x96\x10\xb2\xf4\x17\x85\x71\x7d\xff\x38\xc2\x1c\x06\xc2\x10\xad\x75\x79\x11\x01\xe8\xbb\x41\x8e\x4b\x0e\x43\xd8\x03\x82\x8e\x13\x9a\x01\xb3\x3a\xdf\x18\xda\x7d\xaf\x3d\xa2\x83\x13\x9a\x47\x19\x4e\xda\x17\x1f\x7a\xc7\xbf\x69\x8f\xc7\x7a\xaa\xab\x97\x37\x51\xae\x6b\x14\xb5\x0f\x6f\x90\x73\xcb\xa9\xf4\x0c\xa2\x37\x77\xff\x1d\xfe\x6e\x94\xd5\x2f\x40\x22\xc3\x31\xb2\xf7\x1b\x66\x4e\x7c\x3f\x19\x5b\x3d\x42\x7f\xe6\xf7\x9e\xaf\x8f\x17\x4f\x5f\x4a\xea\x08\xcb\x05\x06\x43\x6a\xd3\xbd\x7e\xe6\xff\x70\x42\x55\x24\x31\xf7\x75\x57\xbf\xa0\xa9\x62\xd3\xf6\xcb\x7b\x1c\xd5\x29\x45\xcf\xfa\x80\x10\xe0\xe2\xb4\xbc\x41\x51\xad\x48\xee\x41\x33\x50\xc1\xee\xa3\xea\x5e\xa1\x2d\xda\x39\x64\x73\x7a\x15\x38\xea\xf1\x2f\x45\xc1\x16\x82\x50\xfd\xa5\x69\x8a\x85\x78\xb7\xe2\x68\xa5\x30\x40\x5f\x04\x3a\x2e\xcf\x6f\x3a\x0e\x69\x70\x42\x0d\x93\x56\x30\xdc\x06\xa3\x42\x36\x76\x00\xed\x70\xc2\x08\xb3\xd8\xd2\xbb\xfa\xe5\x8b\x92\x72\xd7\x99\xc6\x96\xfe\x4a\xd7\x65\x29\x9a\xc5\x9d\x93\xd1\x94\x23\xe2\xe1\xa9\xa9\xf5\xd5\x78\x47\x61\x34\x4d\x33\x97\x23\x7a\x46\x9a\x9a\xe6\xb1\xb2\xf5\xfb\xbf\xcd\x7e\x46\xe7\x28\x69\xb7\x2a\x0b\x29\xa4\x08\xa5\x48\x9c\x30\x46\x24\x19\x83\xa5\x7f\x40\xd3\x8e\x24\x05\xa7\xe3\xc8\x18\x93\x68\x87\x89\x50\x97\xd1\x5e\x28\x0b\xf5\xdd\x72\x40\x10\xef\xd5\x61\xed\x64\x0e\x38\x61\x91\x16\x11\x02\x82\x84\x2a\xaa\x79\x28\x65\xe1\xf8\x66\x3c\x02\xa5\xc3\x31\xe6\xe9\x54\xad\x8c\xe3\x27\xe3\xc9\xe3\x44\x11\x87\xbe\xa5\x3f\xc2\x02\x64\x5c\x44\x08\xaa\xc1\xf5\x8a\x86\xfb\x28\x4a\x3b\xbb\x85\xb6\xf5\x0e\xa5\x03\x59\x4f\x07\x80\x83\xc4\x08\xbc\xb0\x9c\x5b\xce\xb4\x7e\xf8\x0a\x9b\xc8\x09\x8b\x09\xc1\xfd\x06\x2b\x1f\xb6\x1a\xd0\xe7\xf4\xcf\x16\x4b\xc6\x9c\x2f\x30\x5e\x32\x43\x6b\x6e\x37\x54\x0d\x70\x5c\x95\xe5\xe3\xb9\x53\x18\x31\x59\x00\xbe\x61\xff\x18\x4b\x17\xb1\xf8\xd1\x12\x10\xae\xa7\x3c\xbc\xb3\x1f\x48\x52\x40\xfe\x39\x7b\x0a\x04\x8c\x1b\x96\xa9\xcc\xb6\x85\xcc\x5f\x22\x19\x1a\xa9\x4f\xa5\x18\x67\xb9\xfb\x16\x45\x31\x6c\xa0\x41\x74\xaf\xd6\x0e\x3d\x14\x45\x11\x9a\xc1\xc6\x05\xa0\xd2\x4d\x28\x7c\xe7\x84\xa5\x2e\x04\x7e\x2d\x2a\xe8\xea\x6a\x72\xcb\x34\x36\xa8\x66\x25\xb4\xbe\x17\xa7\xd3\x40\x3d\x32\xb4\x67\xb1\xf7\x20\x9a\xb6\xae\x44\xe9\x55\xaf\xa6\xbb\x89\xef\x9f\x26\x63\x5d\x76\xd0\x37\x00\xed\xb6\xda\xbf\x43\x78\xcc\x34\xa3\xcc\xd1\xec\xdd\x61\x35\xf3\x9c\x5f\xa3\xef\xa3\xb9\xc5\x12\x9e\xa0\xd2\xa8\xca\xf0\x2e\x4e\xf3\x6f\x32\xdd\xc0\x58\x16\xc5\x48\x1d\xf1\x54\x0a\x05\xab\xeb\x42\x81\x47\x6d\xfa\x91\xcd\x62\x4b\x9d\xdc\x42\x67\x60\x8a\x63\xe9\x5b\xb5\x25\x1a\x28\xda\x1b\x84\xe5\xcc\x8a\xf8\x5d\xaf\x9c\x5a\x6b\x0a\xbd\xda\x4b\x53\x86\xe5\x09\x43\x3d\x26\x0b\xe4\x0f\x98\x99\x40\x78\x57\x4e\x8a\xc4\xfd\x45\x22\x52\x0e\x95\xd6\xdd\x8b\xea\xe3\xf3\x03\x83\x09\x1a\xa3\xb7\xd2\x1f\xef\xa5\x8d\x5e\x4e\x71\x2b\x9c\x30\xc9\x24\x92\xea\x78\xf5\xb9\x6b\x0f\x6d\xed\xdb\x0c\xc1\x22\xf8\x83\x86\xd2\x1d\x72\xd3\x17\x50\x71\xc2\xfb\xcf\xf3\xe7\xc3\xe3\xc3\x6f\xc3\xdf\x6c\x11\x09\xd2\xbd\xe0\x0a\x77\xa6\x42\x3f\x0a\xa1\x97\x50\xb8\xa3\x3c\xaf\x1e\x6e\x37\xc8\x31\x7b\x48\x7c\x9b\xa6\x0a\xef\xb0\x7e\x7c\xb8\xd9\xde\x1e\x10\xad\xf5\xe7\xd3\xe3\xee\xfb\xf3\xe6\x70\xff\xfd\x2e\x74\x8b\x6d\xb1\xb6\xfd\xa1\x01\xfb\xb0\x1e\x50\x51\x7d\xaf\xcc\x1a\x01\x0d\x9c\x44\x58\xe8\xc0\x13\x99\x3b\x85\xaf\xae\x0e\x7f\x4d\x58\x34\xe6\x8c\xb7\xcc\xc4\xe1\x38\x81\x9c\x62\x4a\x16\xe3\x5b\x7a\x5b\xb5\xe7\x26\x04\xf1\xfa\x66\x99\xe4\x4e\xeb\xb5\x70\x7a\x71\x33\xf6\x3d\x4e\x22\x92\x2a\x47\xe6\xd1\xad\x1f\xef\xef\xbf\x3f\x6c\xf7\xff\xb0\xc6\xe7\xea\xfa\xfa\x79\x3a\xba\x11\x91\x8a\xe6\xce\x69\x7a\xde\x5f\x2d\x6f\xb4\x11\xd1\xda\x6e\xb4\xfd\x28\xfc\x18\x73\x2f\xf9\x1f\xa5\xc6\xca\x28\x6c\x1f\xee\xd7\x8f\x5b\xff\xa1\x22\x96\xd8\xf4\xef\xc9\x6e\xe7\xed\x9c\x2b\xc3\x77\x93\xa9\x25\xd0\xd4\xfa\x77\x80\xd3\x7c\x0e\x44\x11\xb3\x18\x69\x1b\x5d\xa8\xcd\xa3\xc1\x10\x89\x2b\x3a\x59\xb4\x1f\xa2\x48\x59\x5a\xa5\xa2\xbd\x39\x97\xa5\x05\x92\x4c\xd1\x5c\x71\xe8\xa9\x31\xbc\x16\x5c\x7f\x68\xba\xc2\x14\x8e\xe3\xf3\x6f\xfa\xfb\x11\xe7\x89\x9c\x60\xb4\xdb\x9b\x42\x8e\x7d\xba\x88\x0b\x43\xc8\xac\x6c\x65\xeb\x98\xd5\x2e\xea\x56\xfa\xfe\x32\x43\x3b\xb2\xac\x85\xf6\x07\xf5\xf4\x1d\xb9\x32\x68\x09\xf7\x36\x9a\xad\x09\xa0\xfe\xc7\xe2\x7e\x27\x0d\x44\x7b\x8e\x16\xa3\xdd\xd7\xa7\xdf\x42\xde\xa9\xef\xa5\x69\x22\xc6\x65\xb9\xc7\xda\x8b\x70\xff\xa5\xa1\x34\x7c\xbe\x24\xb2\x18\x51\x5c\xdc\x5f\x8a\xbb\xfd\x3f\x40\x6d\xfb\xfb\xc6\x59\x1c\xa4\x1c\x06\xdd\xca\xbe\x25\x4d\x33\x13\x88\x46\x7f\x5b\x34\x03\xa3\x44\xc8\xd4\xa9\x02\x05\xa5\xe2\xd1\xcd\x8d\x89\x48\xf0\x4c\xbe\xd5\xe7\x16\xd6\xe7\xee\x33\x43\x21\xca\x29\xc5\xe0\x52\x37\x02\xe8\x0f\xcf\x93\x73\x8d\xf2\x4b\x8e\xe9\xc2\x95\xcc\x7e\xe0\x49\xb2\xbc\xa4\xf2\x2c\x53\xc9\x08\xbd\xa6\x91\x19\xef\x78\xa1\xfc\xee\xba\x0b\x22\xf0\x5d\x4e\xfd\x61\x32\x42\xff\x7f\x1e\x44\x5e\xe6\xe8\xf3\xb7\x4b\x23\x8c\x19\xdf\xdf\xdf\xcb\xb9\x92\x4c\xdf\x9c\x99\x78\xec\x54\xde\xd4\x8d\xad\xc0\xf2\x41\xaa\x48\x48\xa9\x06\xcf\xf5\xa6\x68\x5a\x57\x0a\x60\x37\x34\xdf\x4d\x12\xcb\x19\x71\x57\xbf\x6c\x9a\x99\x9d\x1a\xc9\x28\xf5\x88\x4c\xc4\x3f\xec\xe7\xe6\x50\x24\x53\xed\x70\x70\xaa\xae\x2c\xaf\xe1\x76\xfd\xb8\x09\xa6\x44\x24\xa5\xe5\x30\x41\xb1\x2b\xb4\x85\xe1\x7c\x1c\xa9\xe2\x73\x12\xa9\x84\xa2\x12\xcc\xb7\x0f\xdd\xd4\x2f\xc1\xd2\x88\x54\x6e\x44\xe6\xbd\xb4\xf0\x21\x75\x26\x12\x31\x08\xd2\xdc\x8b\x06\xf5\xec\x8b\x63\xd8\xa3\x23\xad\x04\x86\xf7\x31\x2b\x63\x2b\xfb\xd0\xa5\x19\x03\x7a\xfa\x6e\x40\x49\x3a\x10\x4e\x5d\x83\x2a\xda\x19\x2d\x3b\x27\x11\xa4\x11\x46\xe4\x0e\xd7\x70\xdc\x15\xd5\xeb\x8f\x02\xaa\x6b\x11\x1e\xc7\x24\xb6\x04\xf5\x74\xee\xb6\x95\xc5\x94\x3e\xd5\xf5\xcc\xc9\x8e\x8c\x34\xe8\x36\xda\x87\x46\x17\xef\x7b\xab\x2d\x5f\x97\x35\x0a\xa7\xfb\x06\x27\xc4\x08\x5f\x25\x73\x6e\x2a\xd0\xdb\x0e\x8e\xe3\x08\x23\x67\x51\x6e\x46\xd4\x1b\x70\x07\x2f\xa2\x1c\x73\x59\x2c\x6c\x81\x9c\x25\x16\xc9\xdf\x76\xf5\x69\x6b\x85\xda\xa7\x4f\xca\x99\x4c\x50\x05\xff\x1d\x8a\xc9\x57\xe2\x9c\x64\x18\xd1\x44\x1e\x27\x38\xb4\xf5\x11\x1c\xed\x9e\xe5\x89\x16\x6f\x70\xf8\xa8\xcf\xcd\xa1\xed\x37\xfe\x83\x85\x4f\xcf\x2c\x26\xce\x29\x20\xa4\xdc\xc5\xb1\x58\xb8\x79\x2c\xb8\x63\x67\xdb\x17\x9e\x22\xb2\xff\x7b\x16\xe3\xc7\x3e\xa1\x94\x20\x4e\x9f\xa1\x0d\x32\x0b\x4f\xc7\xbc\x14\xd6\xd5\xff\x51\x74\xaf\x4f\x58\xf4\x70\x29\x4d\xc1\x09\x8f\x55\xc6\xdd\x8a\x5e\x29\x85\xd2\x27\x78\x82\xd8\x75\x71\x49\xdf\x30\x8c\x5b\x12\xc5\x88\xed\x3a\x28\x51\x5d\x35\x00\xfa\x47\x21\x9c\x80\xd9\x52\x7e\x84\x13\x9e\x12\x2e\xfd\xb1\xbd\x9c\x12\xf1\x1d\x53\x8a\xc0\x42\x1f\x0e\xbe\x2c\xcc\xe0\x84\x67\x2c\x42\x1e\xdd\x77\xf1\xe2\xe6\x57\x68\xe0\x36\x75\x8e\x12\x39\xb8\xf3\xbd\x87\xd8\x07\xcf\x94\x2d\xf3\xc6\x50\x5c\x33\x8a\xbf\xb8\xf6\x9c\x88\xdc\x73\x9e\x5a\xf5\xab\x21\x61\xc0\xf3\xc4\xd6\x70\xee\x90\xf0\x12\x0b\x1d\x9f\xeb\xde\x12\x5a\x1c\xdb\x3c\x8b\x8c\x33\x10\xda\x0b\xd1\x04\xdf\x27\x17\xb6\x72\xd2\x3a\x6b\x7a\x5f\x94\xe1\x45\x44\x6e\x49\xa7\x4e\xfd\x09\xb7\xb1\xb2\x77\xa1\x0d\x32\xac\xe9\x3d\x34\xa2\xd2\xf5\x71\x2d\x1a\xbd\x83\xa9\x84\xee\xec\x97\x94\x34\xf8\x34\xd6\xb3\xc3\xb2\xb1\x59\x07\x93\x63\x4a\xac\xb7\x9f\xf1\x9c\x88\xfc\x8f\x69\x02\x91\xe3\x08\x22\x1e\x94\x7a\x17\x44\x85\x38\xe1\xa0\xa9\xb1\x52\xca\xb6\x00\xfc\xd0\xbd\xd7\xa1\xcd\x24\x48\xa6\xa2\x8b\xd6\xbd\xa4\x8d\xd0\xce\x7e\x1d\x8c\xc2\xdd\xbb\x04\xd3\xb1\x64\xd6\x68\x32\x8d\x64\x89\xbf\x3f\xff\x71\x78\x3c\x56\x85\x8d\x45\xf8\x5f\x30\xda\x20\x8f\xe1\xa1\x85\x6e\x0f\xc7\xd3\x37\x68\x6a\x4b\x5e\x6c\x3b\xc4\x44\x58\x95\x79\x94\xbc\x6e\x5f\x1f\xc4\xdc\x55\x8a\x29\x89\x72\xa7\x76\x57\x54\x2f\xbf\x0f\x6e\x40\x4c\x99\x3d\x24\xd1\xf0\xf5\x49\x84\xde\x35\xc7\xf2\xf1\xd0\x2b\xb2\xc0\x56\x24\xf6\x71\x19\xa0\xd0\x96\x12\x34\xb4\x75\xf1\x32\xff\x55\xad\x85\xf2\xfa\x02\xc7\xa3\x08\x09\x91\x98\x82\xc6\x15\x70\xf5\xf8\xf0\x7d\x77\xd8\xdd\xad\xae\x7c\x0b\x23\xd6\x97\xec\xac\x1c\x3f\xae\xff\xe7\xc1\x35\x89\x59\x94\xdb\x05\x7d\x02\xd5\x35\x80\xd0\x12\xdf\xe4\x30\xff\xd6\xef\xfe\x94\x74\xb2\xef\xa9\x08\x86\x10\x9e\x9a\xfa\x6f\x66\xd9\xe2\x28\x8e\x30\xba\xf7\xf0\x34\x76\x8d\xe3\x28\x4b\x31\xac\x73\x68\x85\x19\xa8\xde\x7f\x7e\x29\x2c\xdb\x5f\xa6\xac\x88\x51\xbf\x85\x4e\x17\x68\xcc\xa3\x38\x72\x47\xe0\x01\xc1\x64\x07\x94\xdc\x68\x0f\x6a\x90\x8d\x1b\x3a\x9b\x18\x83\x6a\x9b\xee\xf5\x07\x54\xdd\xb9\x81\xd6\xcf\xea\x38\x4e\x68\xee\xe5\xed\x3d\x50\x7c\xf0\x2e\x7d\xa7\x54\x61\x00\xb9\x6f\x1c\x0f\x73\x9c\x02\x72\x4d\xe2\x79\x7a\x55\x57\xda\x02\xa7\x0e\x57\x9b\xd5\xb3\xef\x93\x24\x31\xae\xb8\xa2\xbd\x9f\x54\x6b\x86\xe6\x34\x86\x09\xc9\xf9\xa4\xc6\xcd\xf7\x32\x19\x9e\xf8\x8e\xd6\x75\x92\x70\x89\x13\x03\x58\x6c\xd8\x7b\x82\xb7\x8f\xab\xbb\xc3\xe6\xca\x27\x89\xe2\x94\x12\x47\x3a\x5d\x85\xcc\x08\xe6\xaf\xab\x30\xcb\x32\x66\xa8\x4b\xda\xfd\x31\x3b\xdb\xe2\x2c\xb5\x98\x92\x1d\x88\xf2\xa9\xc1\x22\x9e\x81\xbd\xdd\xf5\xc9\x99\x25\x16\xc0\xa4\xfc\x9b\x08\xc0\x7c\x4e\x62\x91\xd8\x44\x22\x7a\xf8\x8f\x01\xaf\x3e\x8b\x74\xc4\x42\x4a\x3e\x50\xb7\x2e\x1d\xd5\xae\xa3\xcc\x32\x64\x98\xe8\xa0\xed\xb6\x21\xb8\xfe\x4f\x68\xfc\x3e\x13\x4b\x9d\x4a\x39\xa1\x5e\xf0\xa2\x08\x36\x17\xe9\xfb\xa9\x84\xa3\x13\x8d\xe0\x2b\x30\xb3\xd0\x44\xac\x12\xe3\xd1\xb0\x21\x27\x31\x99\xe8\x4a\x00\xc6\xfa\xef\x1e\x6f\x0f\xbb\x53\x51\x6d\xac\xa9\x74\x19\xac\xfd\xd2\x4d\x88\x95\x4c\xd1\x56\xf9\xbd\x38\xfe\xf7\x7a\x08\x76\xc6\x3a\x12\xb8\x99\xf9\xb3\xcf\xd9\x67\x53\x13\x99\x4f\x4f\x9a\x58\xeb\x0c\xa1\xfe\x9b\xd5\x3e\xdc\xc7\x44\xb8\x4c\xf0\x14\x3c\x3c\x3d\x6f\x3c\xe2\x86\x93\xd8\x24\x11\xea\x19\xdf\xaf\x1e\xbe\xad\xf6\xfb\xd5\xc3\xd3\xf3\xe3\x9f\xff\xc8\xf7\xdf\xd6\x8f\x77\xab\x1f\x9b\xd0\x2d\x23\x38\xbb\xae\xca\x5a\x4d\x16\xb5\x01\xc1\x5c\x6c\xdc\xd6\xe8\x9d\xf5\x65\x36\x74\x89\x3f\x90\x93\x84\xe8\xdc\xc9\xfa\xaf\x45\xb3\x3b\x81\x2a\xc4\xec\x28\x48\x18\xe5\xc8\x6f\x74\x05\x1d\xfc\x1a\xc9\x2f\xfe\xff\x29\xfb\xb2\xee\xc6\x6d\xe4\xfb\xaf\x93\x87\x79\x20\xc0\xfd\x51\x92\xe5\x6e\x4f\xbc\x68\x24\xb9\x3b\xf9\xcd\xc9\xd1\xc1\x52\xb0\x38\xa6\x48\x85\xa4\x6c\x2b\x9f\xfe\x7f\x58\x05\x50\x24\x45\x3b\xf9\xbf\x4c\x4f\x0c\x70\x11\x88\xa5\x96\x5b\xf7\xfe\xad\x63\x36\x7c\x92\xaf\xc3\x88\xa2\x72\x6f\xad\x6f\x5c\x8f\xec\xc9\x28\x48\x53\xac\xe7\x5f\x83\xde\x97\x55\xed\x66\x75\x14\x7a\x94\xa7\x7e\xb8\x7b\xa4\x32\xb8\xbb\xf9\xf3\xf6\xae\x8b\xe3\x44\x21\x0f\x50\x76\x63\xfe\xbc\x5e\x3e\x2e\x7e\xef\xfe\x1c\x50\x40\xb9\xaf\x78\x3f\x7a\x62\x18\xa5\xf8\x46\x17\x82\xda\x1e\xe0\x22\x8a\x82\x20\x75\xe5\x4c\x2e\x7d\x00\x5f\x92\x42\xb6\x17\x19\x8d\xa6\xb8\x01\x70\x10\x06\xf7\x42\xb1\x31\xba\x83\xd8\x50\x88\xbf\x7e\x2a\x6e\xcb\x6a\x2a\x62\x15\x25\x7e\x82\x29\x39\x22\xe9\x76\x56\x68\x94\x04\x2c\xb6\x0c\xaa\x77\x8b\x27\xda\x22\x7a\x38\x48\xec\xe1\x03\x58\x9d\x99\xc3\x01\xd3\xd8\x03\x6d\xd2\xb6\x4b\x14\x21\xee\x0e\x27\x8b\xab\x55\xfc\x47\x80\xa2\xe1\x3b\xa6\xa1\x8f\xe3\x67\xf2\xb2\xec\x7e\x66\x1a\x46\x28\x7c\xda\xee\x0c\x6b\xc0\x6d\xe1\x5e\xd0\x7f\x90\x9c\x68\xd7\x31\x89\xb1\xd0\xc6\x51\x01\x22\x1e\x6f\x12\xf3\xd3\x76\x4e\x39\x86\xc3\x6d\x92\xb0\x7d\xe9\x61\x39\x41\xdb\x47\x03\x82\xe6\x1e\xdc\xa1\xdf\x43\x26\x0d\x7b\x0a\x8f\x74\x13\x7f\x3c\xdd\x3f\x3f\x2c\x77\xa1\xe7\xde\x49\x30\x86\x91\xfc\xdb\xd9\x76\x3d\x7b\xdc\x3c\x3d\x74\x0d\x3e\x4b\x6c\xf0\x68\x61\x4d\x72\x22\xb6\xab\xef\xa1\x78\x69\xf6\xc3\x73\x2e\x12\x91\x41\xb6\x36\xcb\x31\x35\x56\xfa\x6d\x7b\x98\x04\x35\xe8\x66\x15\x14\xc7\x5c\x9c\xfb\x0b\x3a\x92\x5e\x98\xfa\x9d\x02\x13\x4e\x8f\x7a\x7e\x26\x6b\xd2\x75\x49\xc9\x86\xc2\xfa\x32\x6f\xec\xf0\x8f\x46\x4f\x71\xaa\xe3\x79\x81\xe6\xbe\x54\xed\xc1\xa0\x61\x0d\xc7\x53\x33\x81\x50\x88\x54\xc8\x49\x8b\xcf\x56\x5b\x20\x37\xf9\x95\xfb\x17\xa9\x30\x44\xc3\xfc\xf6\xee\xde\x6d\x64\x91\x8a\x22\x8c\xe3\x1e\xd0\xaa\x7c\x84\x8f\x66\x01\x59\x7e\xb1\xde\x22\x95\x72\xb4\x4a\x56\xeb\xbb\x1f\xb3\xed\x12\xb1\xf3\xbb\xae\xca\xd5\xf5\xd2\x31\xa4\x14\x75\x43\x14\x5a\x56\xbc\x5c\x88\x30\x5c\x97\x84\x52\xc2\xad\x19\xd3\x7e\x6a\xca\xa7\x4d\xcf\x1d\xc3\x34\x02\xc2\xb1\xfc\x6c\x23\x72\xb0\xea\x27\x9f\x75\xf7\x53\x32\xe5\x4f\x45\x7b\xf7\xcf\xe8\x83\x03\x2f\xf6\x3c\x86\xe1\x97\x6d\x75\xfa\xa7\x5a\x87\xed\x55\x7e\x8c\xc9\x1b\x10\x55\x7e\x76\xb5\x69\x35\x22\xe9\xf4\xc0\x9c\x88\x59\x7b\xec\x93\xda\x5b\x55\x2f\x44\xd1\xc9\x9f\xb8\xf6\x28\x96\x56\x83\xb0\x59\x16\x4d\xa6\x85\x86\xcb\xc5\x91\xc1\x11\xba\x41\x0f\x60\x0e\x4d\xd7\x60\x12\x8c\x87\x1c\xc5\xd9\x16\x7a\xba\x16\xce\x9d\x5f\xd1\x3c\x62\xfd\x9f\xd0\x50\xdd\xe9\xe1\xdc\x8e\xb9\x1f\x62\x71\xf2\x7d\xf9\xb2\x69\xca\x63\x77\x71\x18\x4a\x9b\x54\xb9\x64\x84\xce\x43\x0f\x68\x38\x10\x1c\x00\x3a\xa2\xea\x63\xa6\x3e\x19\x65\xdf\x23\x1c\x01\x8a\x75\x5f\x14\xd1\x1e\x4f\xce\x90\x8e\x7d\xa6\x1c\xfb\xdb\xaa\x1c\xfb\x51\xb1\xcf\x55\x92\x5a\xe0\x63\xbf\x1c\xb8\x6d\x0a\x7c\xb2\x1a\xa1\x3a\x64\x3d\xee\xe7\xc0\x8b\x83\x30\x42\x77\xd6\xb4\x13\xeb\xc9\x74\x7f\x4e\x52\x63\xf9\x96\x95\x68\x76\x45\xa9\xa1\x1e\x67\x3e\xe2\x40\x91\x00\xfb\x20\x20\x4a\xef\x2d\x73\xd4\xa6\x20\x92\xc3\x2b\x64\xf5\x3f\x42\x6b\xc4\xa1\xcf\xa5\x15\xec\x46\xea\x68\xaa\x14\xd8\x8a\xaa\x3d\x14\x0a\x4a\xe6\x76\x5d\xa9\x26\x5b\x68\x7d\xad\x90\xd2\xb6\x07\x44\x9d\x84\x31\xf9\x45\x9e\xc1\x38\x35\x14\x47\x2c\x46\xbb\xd3\x22\x3e\xf0\xa8\xb9\xb3\xbc\xab\xa3\x9b\x45\x82\x64\x35\xe7\xed\x67\xb8\xb8\x7b\x71\xec\x73\xcc\x41\x1d\xc5\x79\xf7\x55\x9c\x21\x8e\x93\x18\x91\x7d\xad\x5b\x57\x7f\x1a\xb7\x88\x63\x21\x18\xa5\xe3\x2a\xd8\x34\xc2\x98\xc1\x01\xd8\x36\x23\x2c\xca\xba\x02\xed\xf3\x86\xcb\x2a\x06\xe3\x60\xe7\xed\x77\x58\x95\x65\xbe\xd4\x59\xb3\x0b\x5c\x87\x24\x00\x42\x6c\xe6\xa2\xde\xdb\xda\xda\xe7\x1a\x90\x24\x60\x8c\xe4\x1b\xbe\x5a\x12\x69\x0c\xf8\xb4\x3e\xfb\x55\x66\x6f\xb8\x8c\x12\xa3\xd0\x1f\x30\x00\xae\x78\x3b\xf0\xe2\x34\x35\x24\x76\x46\x26\xf3\x8d\x38\xb7\x46\x38\xf3\x3c\xcf\x9d\x51\xb1\x08\x95\x53\x7d\x42\x0a\x90\xfb\xf2\xe5\xb1\x6b\x8b\xa8\x54\x12\x7f\xfb\x8f\xbb\x95\xfb\xbb\x4c\xd2\x54\x76\x4c\xe6\x77\x45\x13\x05\xbf\xf4\x60\x0a\xb1\x0a\xc3\xc0\xe2\x0c\xb7\x9b\x2d\x19\x91\x3d\x10\x7c\xdb\x43\x44\x38\xaa\xf3\xfa\xb5\x19\x9c\x67\xfd\x74\xde\x34\xbe\xd1\xdd\x41\x0a\xc4\x62\xc8\xd3\xf9\xd7\xc7\xa7\x9f\xdd\x8d\x0d\x84\xe0\xfc\xc7\x3c\xdf\x1d\x29\xef\xe1\x9a\xb5\xa7\x1c\xdd\xea\xb7\x89\xe1\x1f\xf0\xc9\xb5\xdd\x99\xf0\x28\xa9\xd7\xee\xaa\xf0\xbd\x35\x24\xc7\x93\x5e\x87\x21\x7a\xd3\xff\x23\x0e\x1d\x2b\xe7\x56\x50\x22\xa8\xe7\x54\xc6\x10\x42\x68\x8b\x42\x49\x82\xc9\x42\x7e\x06\x3f\x0b\xd2\x30\x21\xe4\xdb\xff\x40\x21\xc3\xa9\xab\x2f\x1c\x0e\x46\xd7\x1d\x5c\xe9\x56\x6b\x9f\x65\x35\x29\xac\x93\x1f\x38\x7c\x4f\x10\x9c\x75\xdb\x5a\x35\x08\xe4\x0d\xd7\x28\x68\x0e\x54\xf1\x74\x38\x9e\x1a\xb8\x8e\xe6\xc4\xc6\x02\x09\xbf\x2f\x3b\x10\x5c\xdc\xba\x13\xac\x8b\x8b\xd7\x2b\xa8\x7a\xf5\x9b\x6d\xbb\x24\x55\xf9\xb1\xca\xc3\x63\x79\xc8\x2e\x8b\xc9\x28\x8e\x01\x33\x78\x79\xa9\x37\x17\x84\x5c\x6c\x5c\x15\x49\x97\xee\x7c\xde\xdc\x5c\x1a\x01\x69\x7b\x72\x30\x0d\x1b\xc1\x1a\x13\x8f\xc7\x88\x17\x7f\x39\xed\xe5\x70\x33\x4a\xbc\x30\x82\x80\x22\xbf\x0f\x59\x71\x91\x63\xfc\xa5\x6b\x8f\x55\xe0\x4a\xc5\x51\x46\xf9\x2a\xd7\x9d\x78\x11\x95\x61\xb7\xcb\xa7\x2b\x2a\x83\xee\xdc\x4c\xbc\xd8\x23\xde\x49\x6b\x72\x3c\x88\xe2\x7c\x2f\x0a\x7d\x85\xa9\x1b\xaa\x6c\xb7\x57\xa6\x02\x53\xc5\x18\x5d\xfe\x67\xc6\x40\xe2\xa5\x04\xfd\x51\x22\x57\xcb\x83\x98\x74\xad\xc6\xe6\x5c\xe2\xa9\x04\xe9\xea\x7f\x6b\x9d\xc9\xbe\xe1\x98\x30\x06\x69\x1f\xc7\x7d\x23\x1a\x41\xd5\x7f\x59\x73\x1e\x0d\x04\x53\x9e\x25\x05\xab\x6b\x54\x4f\x1f\x9f\x63\x09\xd3\x44\x23\x89\x65\x17\x94\x8f\xb4\xba\x54\xc3\x3b\xf1\x38\x94\x72\x10\x39\xf9\x21\x4e\xf9\x95\x04\xde\xb4\xcb\x94\xf0\x24\x42\x6b\xef\x53\xac\xba\xeb\x27\x83\x34\x75\x7b\x9b\x8b\x25\x0c\xe5\x51\xda\x5e\x1a\x6c\x90\x67\x2e\xea\x4c\x4d\xe2\x1d\x12\x9f\x25\xc2\x06\x15\xd0\xc2\x5c\xf4\xf0\x81\xe3\x97\x1e\xec\xda\x89\xaf\x42\xcc\xdb\x3c\x89\x3a\xab\xff\x3e\x0c\x97\xf8\x4a\xe3\xd0\xf4\x03\xe7\x57\x3c\xc0\x6d\x3f\xe0\x8e\x47\xf0\x36\x2b\x04\x31\xde\x58\xa6\x79\x4a\x97\x7a\x5d\xcf\xd4\xef\xc3\xf6\x28\xe3\xd0\xa5\x80\x6d\xaf\x20\x10\x54\x5e\x2b\x0c\xdc\x80\x3e\xa9\xc9\x62\xe6\xb6\x63\x22\x4c\x68\xeb\x6e\x1e\xce\x3f\xcb\x4a\x0f\xce\xad\xee\x87\x07\xca\x47\x88\x85\x69\xdf\x2e\xfb\x0b\x7a\x6c\x7a\x81\x97\x84\x31\x78\xbc\xb3\x78\xfe\x0e\x61\x37\x80\x79\x27\x91\x8c\xb0\xda\xb3\x7e\x07\x38\xd6\x03\xb5\x12\xdb\x23\x8e\x3c\x69\x49\xb8\x50\xd4\xee\x5e\xd4\xcd\x8f\x7a\x2e\x9a\x26\x87\x0e\x67\xe3\xce\xb2\x24\xb6\x11\x23\xa2\x64\x7c\x10\xaf\x50\x0d\xf5\x9a\x86\x9f\xd6\x5d\x95\x7a\x98\x0c\x5e\x67\x6a\x80\x4f\x4a\x92\x40\x85\xf6\xb8\xa5\x64\x58\x37\xd5\x52\x4f\x2a\x3e\x88\x70\x8d\x5c\xfe\x24\xf5\x13\x3c\xbc\x5a\xf7\xf7\xd9\xc2\x73\xd5\xab\x78\x81\x1b\xd9\x75\x09\x22\xf4\x06\x5c\x96\xd4\x76\xe8\x3e\xc2\x60\x36\xa5\x51\x88\x48\x61\x69\xad\x9a\xe6\xf2\xc1\x53\x49\x32\x09\x54\x42\x6a\x0b\x63\x5d\x9b\xe6\xb6\x06\xfc\xdc\x1a\xc0\xa3\xc5\x20\xb8\x40\xaa\x25\xa1\xf5\x23\xbc\xa3\x99\x98\x5d\x7b\xce\xa3\x69\x23\x12\xcf\x81\x48\x90\x0f\x0c\x84\x0d\x85\x62\x49\x21\x0f\x90\xcb\xaf\x7b\x01\x01\x90\xb0\x8e\x95\xec\x07\x14\xba\xac\x26\x55\x7b\x03\x2f\x91\x69\x1a\x84\x2e\xad\x78\x86\xca\x92\x00\xb9\x56\x25\x5d\x41\x84\xc5\xa6\x39\x07\xdc\x75\x30\x81\xf2\x3b\x26\x68\x3a\x58\xb3\xcb\x37\x53\x8c\x92\x2a\x17\x28\xab\xd5\x6a\x1e\x3a\x90\x9f\xfd\x7b\xba\x62\x01\x9f\xb4\xd5\x13\xf7\x34\x03\xe8\x98\x64\x83\x19\xa5\x5b\x1b\x64\x54\xc9\xf3\x59\x4c\xcd\x5d\x12\xc6\x88\x68\x1b\xd6\x20\x3b\x94\xc5\x14\xba\xc2\x5d\x98\x06\x98\xb8\x46\x18\x21\xbd\xc5\x84\x6d\x96\xe8\x94\xa4\x6b\x29\x78\x5a\x76\xe5\xca\xc3\x4f\x03\x5e\x4a\x2a\xb0\xf8\x16\x4e\xe3\xa7\xf5\x69\x16\x79\x59\xc0\x34\xeb\xe3\xc4\xde\xd8\x4b\x5b\x26\xc0\xc9\x62\x7d\x43\x03\xcb\xa6\x39\xbb\x36\x40\xa9\x82\x4c\x95\x7c\x60\xc2\x27\x00\xb1\xe9\x36\x70\xa8\x9a\x71\xf8\x2c\x31\x40\x98\xab\x0a\xfe\x3c\x65\x15\x68\x8b\x5d\x19\xcc\x95\xd4\x63\x12\x8b\x1e\x8e\x3b\x84\xed\x59\x09\x40\x2a\xcd\xaf\x1f\x4a\xdd\x0f\x07\xa6\x5e\x42\x3c\xb4\x96\x9c\x64\x72\xf2\xa6\x9e\x22\xb0\x6b\xeb\x04\xf7\xbf\x79\xea\x01\x29\x73\x7c\x43\x9f\x63\xd1\xf3\x52\xa7\xbf\x78\xca\x84\xc6\x7d\xb9\x2c\xf2\x33\x26\x21\xbe\xb5\xce\x2f\x9a\x89\x3d\xe2\xce\xb6\xa3\xa2\xa2\xe3\x17\x68\x9a\xf2\x78\xba\x2a\x2e\x4b\x99\x09\x14\x51\x02\x9a\x0a\xea\xfd\x43\x59\x88\x4a\xed\xcf\xad\x35\xed\xc6\x33\xe5\x01\x27\x76\x27\x1b\xdb\x1a\x9e\x4e\x29\x17\x11\xa3\xb4\xc0\x8f\xb2\x93\x35\xb7\x59\x68\xc6\xbb\x4e\x04\x19\x43\x8b\xef\xf6\x94\x9b\x2c\xcf\x5b\xe3\xcc\xf9\xdc\xce\xba\xe0\x17\x87\x21\xe9\x78\xf5\xad\x19\xcf\xff\x70\x37\x03\xee\xf4\xf1\x2c\x2f\xeb\x64\x91\x41\xea\xb3\x10\x41\x86\x16\x20\xb1\x3a\x75\x39\xc0\xd4\x97\x94\x58\x78\x2b\x1b\xa8\x77\xa6\x8b\x50\xa6\x81\x50\x98\x90\xb6\x28\xb0\x9f\x20\x5e\xbf\xb7\x06\xde\x22\x17\x75\x9d\xa9\xae\x1b\x98\xd0\x65\x1e\x44\x23\x86\xd4\xd7\xb6\x4f\xe8\x33\x3c\xf7\x26\xd9\xbe\x06\xa7\xde\xf4\x3e\x31\xfa\xe8\x61\xc0\x5d\xb5\x28\xb1\x00\xa0\xc2\x8a\x8d\xca\x5f\xd7\x0d\xa6\xa1\x91\x18\x8a\xd9\x9c\xe4\x21\x6b\xfa\xd8\xf1\x81\xd5\x92\x46\x91\xc0\xf4\xdd\xe2\x61\xe1\xf0\x2d\x43\xde\xfb\xd1\x7b\xc4\x91\x8c\x9c\xde\x03\xbc\xcf\x5e\xae\xc2\x02\x69\xac\x89\xd2\xce\x49\xb0\xac\x7b\xd8\xdc\x34\x69\x07\x66\x84\x51\x7b\x32\xa6\xbf\x9a\x52\x0e\x4e\xf9\x16\x8f\x31\x2b\x38\x79\x1c\x45\xb3\xd3\x34\x49\xf0\x34\xd8\x55\x18\x6d\xed\x83\x9b\x6c\x0f\xe1\x6b\x3c\xb8\x67\xf7\xf7\xb3\xc7\x1e\x6c\x30\x95\x41\x8c\xdf\xff\x9b\x7d\xc4\x6a\xe0\x58\xa6\x52\x05\xfe\x45\xd2\xda\xe1\x80\x1f\xc4\x87\x12\x23\x04\x51\x2a\x75\x1a\xca\x81\x64\x8a\x35\x50\xe6\xa7\x3a\x2b\xda\x5d\x60\xd8\x5f\xc5\x12\x8d\x39\xca\x16\x3f\xdc\x3d\xee\x6e\x9e\xd7\xb3\x5e\xce\x22\x55\x69\x84\xdb\xd3\x5b\x06\xef\xbe\x8b\x3b\xa4\x5a\x0a\xcc\x4c\xb7\xce\xc0\xaf\x70\xae\xd7\xa0\x20\x7b\x1b\x03\x1d\x53\x48\x88\x3c\x80\xaa\x12\xfe\x1e\xc4\x75\x19\x75\xd0\xc4\xff\x53\x43\xb3\x58\x7c\xdf\x81\xce\x9a\x5d\x38\x9c\xd1\x86\x47\x88\x38\x5a\x6e\x16\x4f\x83\x1d\xcc\xf8\x3e\x8a\x87\xd5\xa7\xc3\x65\x6e\x76\x8d\x32\x40\x6c\x27\x8a\x28\xbf\x3c\x88\x8f\x5f\x1d\x2f\x4e\xdb\xa8\x7c\x5b\xc7\x57\x7c\xcb\xde\xe0\xa1\x2c\xe0\x3c\x17\x9d\xf1\x28\x3c\xad\x83\x4b\x51\x3c\x72\xd6\xce\x45\x0d\xfa\xa9\x6f\x04\x0a\x16\x30\x73\x51\xb2\xfa\xe1\xd4\x7c\x86\xb3\x41\xb0\x54\x60\x6d\xf7\xfc\xfe\x69\xf1\xeb\xe6\xf9\x71\x7b\x77\xbf\xb8\x5f\xce\x1e\x9f\x57\x9b\xed\x6c\xf1\x6b\x77\x33\x99\x3a\x1b\x91\x28\xc5\xeb\x3e\xa6\x5a\x30\x13\x68\x9a\xdd\x0e\xba\xb4\xb9\x46\xf3\x09\x66\x92\xb8\x3f\x87\x7b\x05\x34\xad\x37\x7d\xbd\x5e\x05\xf7\x48\x07\x6a\x51\x66\xc5\x8f\x2c\xcf\x05\x21\xbf\xdc\x5b\x71\x69\x94\x25\x3a\xf8\x6d\x35\xc3\x78\xe7\xe8\x80\x11\xbe\x48\xa9\x14\x0a\xbf\x3d\x3e\x0b\x1f\xfb\x49\xa6\x43\xf8\x9a\x07\x84\x38\x7c\x79\xe9\x3e\x97\x08\x3c\xa6\xed\xfa\x7e\x28\x8b\xd6\xec\xc4\x38\xed\xb6\xa4\x8a\xa5\xc9\x28\x83\x08\xc2\xc0\xa9\x0f\x77\xfc\xc1\x64\x9c\x8d\x5f\x32\x48\x85\x55\x7b\x6f\x4f\x9a\xcd\xa1\x3d\xaf\xea\xa6\xa3\x61\x73\xbd\x94\x8f\x48\x8e\xbc\x14\x85\x13\xc4\xec\x9a\x42\x4c\xc3\xb8\xd1\x1f\x6b\x5f\xfc\x1d\xf5\x44\xe0\x89\xd0\x13\x21\xd8\x2d\xac\xac\x0e\x22\x9f\x9f\xae\x05\x58\xda\x7e\x8c\x04\x31\x56\x27\xe9\x34\xeb\xbf\x4c\x63\x8a\xd0\xf7\x10\x50\x7b\x0b\xa0\x97\x2f\x2e\xb3\x21\x42\x9f\x44\x55\x2b\x40\x74\x25\xa6\x60\xcb\x2b\x55\x20\xd7\x39\xf6\x63\x9b\xb0\x9d\xa8\x85\x11\x61\xac\xd0\xdf\x41\xf9\x42\x7d\xc8\x8a\x09\x60\xaf\x08\xa5\xc1\x1a\xdd\x15\x14\x8d\x50\x65\x05\xfd\xd5\x2a\x62\x4e\xa9\xb9\x3a\x7b\x41\x19\x2e\x2b\xb0\x05\x55\x3d\x8c\xeb\x89\x18\x34\x26\xcd\xda\x37\xb8\x3d\x15\x57\x55\xbc\xc3\x93\x41\x24\x22\x45\x11\xf1\x5f\xb3\xe2\x45\x97\x07\x5b\x18\x75\xa5\x9b\x16\x78\x22\x65\xa1\x08\x7b\x49\xe9\x9a\x96\x47\xef\x10\x10\x29\x37\x8e\x08\xf9\x21\x2b\x36\xd9\x0b\xd9\x1d\x81\x75\x75\x85\x90\x09\x6a\x89\x91\xeb\xa4\x27\x39\x1d\x3e\x55\x32\x9a\xb4\x17\x84\xd0\xa4\x7c\x63\xa9\x60\x57\x22\x1b\xaf\x51\xc9\x23\xe4\xe0\xbd\xa8\x8a\x98\xc4\x0d\x96\x0c\x12\x8a\x64\xf7\xa8\x5f\xdb\x3f\xc7\x32\x41\xc8\x60\x77\x6e\x09\x15\x78\x92\xbb\x2f\xfc\x66\xad\x2a\x0b\x60\x1b\xef\x23\x2a\x49\x05\xef\x05\x67\x47\x51\x2d\xa1\x24\x95\x0c\xe3\x30\xda\x4a\x6d\x4b\xc3\x3b\xf8\xe6\xca\x24\x5e\xe8\x44\xbb\xd0\x52\xc4\xd2\xcb\x29\x4f\x52\xe8\x28\x44\xab\xb1\x2b\x8c\x2b\x2b\x34\xed\x26\xed\x01\xa1\x0d\x21\x64\x6b\xeb\x03\x67\x7f\x41\x47\xdb\x3a\x3d\x4f\xc0\x4b\x90\x95\xb3\x4b\xee\x36\x9f\xa4\x77\x04\xa8\x28\x20\x9f\xb6\x38\xd5\x17\xc2\xf2\xb6\x05\x98\xb0\xf5\xbf\xdf\x45\xbd\xdf\x9e\x8f\x9d\xc1\x2a\x0c\x13\x01\xd9\x70\x08\x85\x69\xcf\xa2\x1b\xd1\x1d\x39\xd2\xf3\x3c\x4c\x44\x5a\x16\xaa\xc9\xa8\xf1\xd0\xf4\x1c\xc6\x79\xa4\x27\x28\x08\x49\x67\xd2\x1d\x55\x5e\x6e\xc7\xe2\x2c\x6d\x47\x45\xb0\xc7\x9b\x2c\xcf\x5e\xa0\x50\x83\x65\x28\x19\x97\x81\xd7\xc1\x64\x3a\xee\xc2\xb6\x25\x88\x3c\x8b\x2e\x78\x7a\x83\x6a\x75\xdf\x11\x61\xb7\x8d\x82\xb4\xb8\x31\x01\x61\xf5\x20\xae\x32\x10\x5d\xe8\x7b\x38\xa0\xd2\x67\x29\xb2\xd7\x1f\x73\xd0\x2f\x70\x03\x2a\xcf\x8a\xd1\x94\x93\x7e\x98\x76\x51\x9f\xad\xa8\x5f\xdb\xf9\x92\x43\x9f\x2e\x72\x38\x1c\x81\x4f\x92\xce\x2f\xd0\x6c\xa0\x69\xae\x30\xb9\x32\xf4\x7d\x2c\x76\xde\xd1\x80\x59\x9b\xdf\x92\xd5\x7f\xbd\xa7\xc8\x30\x49\x22\x6b\x5e\x7d\x2f\x1b\xf2\x6e\x86\xbb\x94\x0c\x15\xe0\xf3\x4d\xf6\xb2\x27\x30\x64\xcf\x34\x90\x91\x47\x14\xca\xa6\xac\x14\xcc\x4f\x67\x29\x86\x3a\x8f\x6d\x17\x66\x20\xed\xac\x87\xa7\x23\x54\x7d\xe3\xe1\x5f\xa3\xce\x3c\xc5\x7d\x89\x6a\x83\x7b\x76\x8e\x8c\x14\x51\xe6\x2d\x9b\xfd\xfd\xb9\x19\x7e\xeb\xd8\x4f\x52\x8b\x87\xbe\x05\xf8\x99\x15\xba\x7c\x1f\x8d\x52\x1c\x10\x94\x45\x67\x75\x9e\xbd\xc2\xac\x6a\x46\x6a\x01\x6d\x9f\xc4\xc3\x80\x50\x6b\x2a\x3d\x1f\xb7\x7b\xb8\x29\x4f\x2f\xfb\x71\x27\xc9\x71\x5e\x75\x95\xfd\xc3\x08\x97\xed\x95\x78\x11\xc6\x89\xb1\x5e\x7c\x37\x7b\x78\x7a\x7e\xdc\xee\xee\x16\x4f\xbb\xcd\x76\xf6\x6d\xc9\x76\xab\x35\x65\xe0\x9d\x01\x2a\x93\x38\x41\xfd\xf5\x4a\x64\x35\x6c\x72\x71\x38\xf4\x1c\xaf\xe9\x85\x92\xe8\x10\x19\xe3\x11\xd7\x74\x0b\xb0\xfc\xc8\x3e\x61\x33\x90\x69\xc2\x43\x32\x6f\x8b\xc5\x05\x71\x63\x1b\x85\x07\x69\x47\x7d\xfe\x72\xe5\x82\x4a\x69\x25\x4d\xde\x45\xa3\xf6\x3f\x32\x0d\xe5\x7c\xf4\x6b\x65\x12\xa0\xb6\xc8\x7a\xf9\xb8\x5c\xe2\x4f\x76\xf7\x96\x26\xc4\xb3\x79\xb1\x3f\x15\xaf\xf5\xe0\xa3\xa9\x94\x78\x0f\x6a\x37\xa7\xd0\x91\x61\x5d\xb3\x21\xd6\x61\x09\x0d\xf3\x3c\x6f\xe7\x31\xe8\xc2\x07\x52\x27\x31\x06\x2e\x77\xe4\x42\x3c\xb5\xdf\x34\x43\xce\xa7\x09\x58\x85\xd4\xda\xc7\x19\x88\xc3\xb7\xfc\xf3\x24\xf2\x5f\xae\xac\x16\x09\x22\x41\x0c\x54\x8e\x67\xa5\xc5\x18\x3f\x99\xd1\xad\x40\x18\x8c\xd8\x75\x1c\x7b\xdb\x9f\x77\xa3\xe1\x02\x00\x6e\x2d\xfd\x15\x54\x07\x51\x40\xd1\x5a\x6d\x4d\x56\x9c\x0e\xf7\xf0\xd6\xab\x86\xed\x1f\x0b\xd2\x44\x01\xef\x74\xfc\x11\x68\xd8\x9d\x72\xd2\x18\x8e\x93\xc3\x2a\x0a\x2d\x7a\x52\x3d\xc3\xf5\xa3\xbc\x30\x70\xbb\x45\xa7\x3d\x23\x73\x3b\x47\x6f\xef\xee\xb6\xbf\x8c\xfa\x4b\x25\x53\x97\x67\x98\x0f\x78\xbf\x93\x71\x1c\x7e\x38\xfd\x94\xa7\x42\xf4\x0a\x56\x03\xbe\xea\xb6\x01\x14\x5c\x6a\x54\x1f\xce\x44\x30\x3a\xf2\xd4\x14\xf3\x0c\x4b\x5d\xbe\x76\x72\xd6\x2a\x1e\xf8\x2a\xed\x29\x47\x52\x31\x7b\x67\xb4\x2b\xae\x95\x4b\x9d\x76\x3e\x95\xab\x10\x54\x3e\x4b\x1d\x6c\x68\x0e\xc5\x5f\x73\x0a\xe5\x8c\x7e\xbe\x1f\xb0\x44\x59\x1c\x7e\x87\xe9\x1c\x15\x76\x8f\x5e\xca\x8f\x42\x87\x78\xb8\xad\x00\xbe\xb7\x8b\x62\xd1\x59\x0c\xca\x8f\x41\x73\xcb\x03\xf4\x4d\x10\xa9\xdd\x64\x69\xbf\xf2\x45\x84\x1e\xe1\x83\xf8\x70\x29\x95\x39\x34\xf5\x84\x78\x5c\xdb\x59\x32\xcc\x08\xe6\x60\x1a\x3f\x9e\x68\x84\x0b\x72\xde\x99\xec\xa8\xb8\xdc\x77\x3e\x54\x10\x28\xf4\xa6\x29\xcb\x2f\x73\x2a\xfc\x59\x94\x87\x43\x59\xd4\xb7\x65\x65\x41\xb5\x97\xee\x26\x12\x5d\x2c\x62\x71\xfb\x34\x1a\xbd\x20\x51\x8e\x48\xf4\x11\xde\x71\xc6\xde\x15\xb7\x59\x51\x8c\xf3\xbe\x2a\x48\x34\x82\xc2\x97\x45\x53\x95\x47\x87\x7a\x51\x61\x98\x48\x7e\x09\x65\x2f\x04\xd9\xe4\xcf\xc7\x23\x31\x45\x8d\x47\xa1\xed\x6e\x8f\xab\x9d\x29\x2b\xc8\x5e\x8a\x9d\x9c\x2a\xc3\x57\xa1\xf4\x49\x8b\xd5\x66\x07\xf6\xa2\x86\x8e\x4e\x48\x45\xa1\x87\x65\xf4\x68\xf8\x2c\x2f\x74\x00\x2a\x0a\x63\x65\x13\xe5\xd3\x3c\x58\x5f\xe3\x43\x54\x6c\xa9\x23\x68\x5b\x42\xda\xb1\x2b\x47\x59\xc5\xa1\x8f\x5f\x61\x2b\x8a\x97\xc1\x78\xc7\x40\x68\x0d\x17\x39\x1d\x86\x4d\x54\x0c\xb1\x37\x12\xf5\xdf\x2e\x3e\x99\xa5\x49\x28\x42\x5b\xdb\x71\x0f\xee\x13\x3f\x9c\xf2\x59\x55\x89\xf1\xc7\x49\x62\x4a\x76\xef\x70\x27\x7e\x84\x77\x82\xc8\x2c\x8f\xa5\x72\x1b\xae\x4a\x44\x8a\xa4\xc9\xdf\xa0\xb9\x17\x75\xf3\x50\x3b\xef\x4b\xa5\x4c\x91\xe9\x7b\x92\x87\xf2\x8a\x0a\x6f\xf4\x5a\x29\x17\x08\x33\x71\xaa\xbf\xef\x14\x4f\xbd\xc2\x33\xb8\xee\x71\xd4\x53\x46\xc2\xe0\xb0\xb5\x4e\xfa\x25\x07\x2a\x15\xa4\x09\xb8\xb3\xc5\x3e\xc6\x8c\x39\x15\x54\x0a\x24\xaf\xb3\x11\x45\xd6\x20\xb0\x63\xe4\x39\x2b\xe1\x19\xfc\x1d\x3f\xbd\x57\x98\xdd\x3a\x87\xf4\xb3\xcf\x3e\xba\x36\x25\x36\x45\x4b\x77\x60\xb9\x14\xc7\x0c\x29\xe3\x8b\x04\x21\xd6\x5b\xcb\xbe\xc7\x56\xa2\x14\xe3\x28\xeb\x8a\x53\x63\x69\x61\x0a\x13\x89\x86\x51\x04\x53\x29\x9f\xe2\xb1\x0d\x88\xc3\x45\x77\x8c\xe8\x7b\x2e\x7b\xa6\x4a\x12\x8c\x73\xca\x6c\xcc\x30\xa3\x74\x9a\x24\xba\x13\x8f\x99\x57\xa5\xd0\x0a\x89\x4c\x46\x63\xa9\x21\xc0\xd5\xe3\xd0\x09\x73\x07\xf3\x1d\x8d\x28\x30\x1d\xb4\xfd\x96\x3f\x7f\xf6\x82\x83\x0a\x42\x0f\x95\xe1\xb2\xfa\x12\xcc\x7a\xec\x69\x02\xb6\x5d\x64\x80\x2e\x8c\x0b\x71\x12\x8e\x8b\x1c\xde\x7e\x99\x9b\xf6\x04\xc3\x57\x79\x40\xea\x42\xac\xf2\xba\x56\x11\x60\x3c\xe9\x0d\x18\xfb\x64\x6e\x6a\xc6\x7c\xcc\x6f\xd5\x7f\x56\xcd\xec\x52\xa5\xe4\x5a\x35\x0f\xbb\x3a\xfd\x61\x05\x92\xe6\x0c\x22\xe1\xa6\x69\x4e\x44\x1b\xa3\xcb\x39\xb7\xda\x3b\xce\xda\x6f\x4d\xff\xab\x4e\x40\x15\x22\x3f\x44\xf1\x5d\x54\xfa\x5d\x54\xb0\x86\xba\x3c\x55\x0a\x6a\x14\xff\x72\x0f\xf4\xb9\x26\x72\x22\x68\x84\x23\xa8\x70\x04\x9e\xff\x68\xc6\x6a\x5f\x13\xa8\xd7\x42\x7e\x36\x4d\x59\x8d\x28\x90\x03\x4f\x63\x30\xa3\xe3\x21\xdf\x39\xee\xe7\xb6\x25\x49\x31\xae\xb8\x83\xe1\x48\x44\x31\x63\x51\x3f\xf2\x60\x59\x4e\xb6\xdf\x47\x3f\x35\x4a\x3a\xa9\x91\xd3\xd1\x2e\xb6\x7e\xf1\xbf\x8e\xd2\x54\xc6\x8e\x9b\xe2\x46\x34\x62\x27\x9c\xad\xac\xe3\x30\xf0\x6d\x35\xd8\x5b\xa6\x61\x79\xa1\x4a\xfb\x74\xc1\xba\x2b\x25\x69\x29\x51\xd5\x54\xdf\xc6\xd2\xb1\x89\xd1\xca\xc5\xca\xf4\x2b\x67\xec\x9f\xed\xff\x3a\x61\x21\xee\x44\x8b\xb3\x84\x2a\xeb\x60\x92\x3a\x09\x48\x07\x87\x4c\xa2\x85\xa8\x3f\xb1\x2e\x74\xa2\x62\x2c\x75\x24\xba\xcd\xb2\xa2\x74\xb2\xbb\x4d\x1a\x01\x86\x80\x1c\x12\xa0\x5d\x3a\xae\x88\x47\x8b\x34\x48\x2e\x7e\xf3\x73\x31\x8e\xb7\x69\x19\x48\xaf\x93\x75\xad\x9f\xde\x41\xcf\xcf\x77\xb6\x5e\xe5\x6f\xc6\x4d\x09\xdf\xb3\xe7\xe2\xa2\xcc\x8a\xfa\xf9\x12\x2f\x1e\x3d\x44\x8b\x14\x03\xf0\xcf\x9b\xe5\x1a\x39\xc0\x76\x14\x0f\x76\x6f\x09\x3c\x46\xc7\x08\x49\xd1\xef\x16\x4f\x1b\xcb\xc9\xd4\xb5\x4b\xc0\x8a\xe3\x4d\x79\x00\x2c\x06\x99\xd8\xf8\x5c\x57\xf0\x30\x0c\x77\x5f\xbe\xac\x91\x6f\x65\x3a\xfd\xe3\xf6\x37\x6d\x78\x82\x6c\xd2\x22\xcf\x33\x18\xb3\x52\x69\x13\x27\x88\xe8\x95\xa2\x78\x45\x15\xac\x3e\x5f\xd1\xe0\x37\x82\x17\x85\x54\xc9\x85\xa7\x6b\x6b\xd1\x8f\xda\xd3\x14\x8b\xd9\x0e\xe2\x15\xb7\xae\x6c\x8c\xd7\x04\x16\x32\x8c\x74\x59\x1c\xe9\xcd\xa5\x16\x0a\x18\x44\x68\xe3\xac\x41\x6f\xca\x8f\xdf\x45\xf1\x0a\x50\x07\xcc\x95\x21\x00\xb7\x72\x0e\xf2\x84\x16\xad\x5e\x65\x1f\x30\x24\xb1\x0d\x3c\xf0\x19\xb1\x9d\xbf\x66\x79\xde\x93\x84\x70\xb9\x69\x08\xbc\x38\xea\x47\x08\x49\x6d\xa3\xd2\x8b\x71\x02\x06\x02\x1e\x60\x4d\x83\xda\x97\x65\x0d\x54\xc2\x3c\x7a\x58\x00\xd2\x04\x68\x1b\x14\x04\x9a\xcc\x46\xbc\x91\x10\x7a\x1a\x99\x13\x5e\x54\xad\xc6\x4d\x09\x10\x4b\x13\x1e\xdd\xe3\x46\xe3\x2b\x6b\xef\x61\xf2\xcc\x9d\x34\xc5\xb8\xfe\x0a\x22\x9f\x54\x3f\x5e\xa0\x59\x9d\xe4\xaf\x70\x9e\x9f\x91\xb2\xb0\xef\x62\x41\x94\xc4\x18\xd5\x42\xc8\x6d\x51\x76\xd7\x4a\xcf\xbb\x90\x28\x90\x93\xb1\x2a\xbb\xe2\x53\x88\x79\x84\x14\xb7\xdf\xca\x1c\xdc\x8a\x86\x24\xa6\x82\xb1\x2e\x14\xf8\x83\x8f\x41\x5c\x20\x21\x44\xee\x96\xcd\xf7\xd9\xda\x01\xf0\x40\x79\x92\x2a\xd4\xeb\xc5\xa9\xca\x4a\x57\x27\xec\x5a\x65\x6c\xe8\x70\x74\x56\x3c\xa6\x5b\xbe\x86\x84\x80\x8e\x53\xfc\x02\x7b\x51\xef\xb3\x43\xd9\x94\xc3\xc8\x41\x72\x0d\x13\x1d\x9b\x5a\xa0\x35\x49\x46\xbc\xc0\x45\x99\xbf\x8f\x67\x06\xe0\x01\x46\x7a\x16\xd5\xf9\xd8\x38\x96\x89\xba\x6b\xd5\x42\x12\xac\x50\x5c\x40\x38\x60\x82\xd8\xeb\x40\x81\x1d\xa5\x1d\xf3\x5c\x73\x9c\xb8\x32\xf6\xe5\xc7\x31\x2f\x2b\xe8\xe3\x31\xa8\x93\xf1\xfc\xc8\x23\x42\xcc\x0c\xab\x65\xba\xf8\x45\x9f\xa7\x6b\x70\x6e\x19\x2f\x88\xf0\x14\xda\xc9\xd3\xd9\xf1\x85\x6f\xb7\x3f\xff\x19\x2e\xd0\x78\x82\x63\xa0\x49\x41\x36\x9a\x8f\x86\x79\xc2\xca\x4e\xbe\x95\xaf\x30\x6b\x5c\x20\x65\xfc\x75\xfa\x61\x42\x77\x29\x17\x1e\x77\x13\xb4\x82\x9f\x20\x8e\x65\x71\x23\x0e\xe2\x05\xda\x9d\x06\xa7\xd0\x9d\x1e\x3f\xcf\x57\x18\x0d\x3b\x10\xef\xf5\x2d\x95\x14\x5b\x16\x96\x5f\xba\x4e\x1a\xd1\xff\x42\xeb\x2e\xe5\x7b\x4d\x3e\xef\x3a\xa7\x5a\x90\xa0\x8b\xbd\xc9\xa4\x6f\x6f\x78\xaa\x49\x73\x96\x2a\x89\x5a\xf7\xdd\xa6\x5f\xef\x0a\x53\x5a\xed\x1f\xf7\x02\x5c\x84\x9e\xc5\xa7\xe9\x9b\x7a\x44\x06\x6b\x7c\xe6\x63\x84\xe1\xee\x70\x2c\x2b\xe4\x16\x42\x5a\xa8\x2d\xd4\xcd\xcc\xdd\xc1\x0f\x03\x5c\xbd\x59\x51\x43\x65\x2b\x12\x68\xaa\x84\xd3\x84\x6f\xee\xba\x88\x88\xc2\x32\x55\x3e\x74\xd6\x91\xf1\x25\x31\x1d\x9e\xcb\x53\x65\x95\xad\x47\xaf\xa4\x88\x9f\x76\x55\x95\xff\x03\xd5\x6c\x85\x73\x66\x4c\x10\xeb\x80\xf5\x20\x61\x8f\xe2\x00\xf3\xf3\xe2\xe9\x69\xb2\xac\xdd\x84\xdc\x37\x64\xaa\x9f\xaa\x87\x65\xdf\x97\x33\x61\xa0\x30\xba\xb5\xad\x4e\x87\x23\x9e\x99\x5d\x4b\xa4\x10\x26\xb9\xfa\x7d\x35\xbc\xc2\xf2\x55\xd7\xa7\x83\x3b\x17\x93\x0b\x70\xd7\x84\xa0\x11\xec\xfc\xdb\xca\x9d\xa5\x26\xf6\x38\x82\x74\x4e\xb5\x65\xeb\xbd\xd6\xbb\x09\x3c\xd3\x5a\x5a\xe1\xc5\x5a\xaa\x10\x76\x39\x08\x70\x5c\xf2\x42\x26\xe1\x89\xe0\x8e\x4c\xeb\xcf\x53\xd6\x4f\x1a\x99\x54\xfa\x98\xb9\x98\x43\x53\x0d\xd5\x0e\x3f\x4b\x0e\x0e\xdf\x24\x55\x91\x03\x60\x23\x01\xf0\x30\xde\x3c\x1c\xda\x54\x91\x89\xdb\xba\xfa\x64\xb0\xec\xae\x78\xff\x03\xcf\x08\x3f\x4a\x94\x83\x08\x6a\xa8\x70\xd3\x1f\xd9\x6c\xff\xe5\x7f\x0c\x74\x0e\xf1\xef\x69\x77\x87\x88\x19\x62\x42\x41\x01\xf8\x5b\x70\x67\x8a\x51\x21\xc9\xa4\xda\x16\x0c\xa7\x60\xa5\x87\xeb\xa0\xc1\x24\x04\x90\x3f\xb4\x8b\xa9\xa9\x06\x00\x9e\x31\xd7\xd0\xa4\x21\x6e\xb4\x09\x59\xe8\x18\xa3\x9a\x61\xe5\xdc\xf4\x28\x42\xea\xb9\x0c\xf2\x2d\xd2\xd5\x3c\x9d\xfa\x1e\x74\xef\x7b\x19\xab\x65\x28\xac\x5c\xe9\x64\xe0\xd1\x18\xdf\x06\x61\xca\xb2\xb9\x29\x0f\x17\x37\xc3\x18\x43\xcc\x0a\x94\xd5\xb2\x9e\xe8\xd4\xe7\x62\x9e\xc7\x03\x74\x5a\xc5\xe1\x6e\x0d\x42\x9f\x27\xb7\x1f\xe6\x79\x49\xa8\x4d\xe7\x62\x4e\x9a\x57\xcc\xf3\x52\x0f\x03\x63\x14\x09\x73\x1e\xf0\xb7\xaa\x7c\x6f\xf6\x8b\x12\x8c\xc9\x54\x06\x7d\x59\xd5\x80\x79\x2c\x4c\x10\x00\xfe\x33\x2b\xea\x7a\x2f\xaa\xd1\xeb\x71\x69\xc2\x31\xf2\x7c\x18\xb7\x77\x80\xa8\x76\xbe\x44\x7f\x8c\xa0\x42\x53\x9b\x24\xf3\xb8\x09\xd0\x63\x38\x4c\xa2\xef\x6c\x27\x9f\x49\x34\x1e\x1e\x4f\xcd\x5f\xcb\xa2\x7d\xee\xf4\xd6\xcc\x3c\x9f\x87\x88\x17\x74\xd0\x93\xd6\x69\xfa\xe4\x9e\x51\xe4\xc0\x0a\x4d\xee\x50\x94\x57\x35\x2f\xa3\x6b\x54\x80\xf8\x07\xb4\x19\xbf\x43\x7e\x74\xa7\x34\xf3\x82\xd0\x17\x94\x62\xac\xde\xa0\x5a\x16\x54\xed\x71\x22\xf8\xfb\x27\xa9\xde\x4f\x8e\xd0\xde\x91\xc7\xbc\x40\x1b\x4e\xaa\x04\x95\xb6\x45\x76\xee\x91\xa1\x17\x60\xa8\x61\x8d\xfc\x4f\x23\x05\x05\xf7\x4d\x43\xee\xe1\xca\xb4\x89\x46\x9b\x8c\xbb\x54\x88\x33\x2f\x04\x52\xc0\xaa\xe0\x20\xaa\x57\xe6\xfe\x1c\x31\xe5\x59\x2c\x97\x2d\xb1\x1d\x09\x8c\xff\x4d\x50\xcf\xdd\x26\x88\xc0\xa2\x2e\x9e\x0b\xf4\xfb\x3b\x88\x54\xff\x06\xac\xeb\x9f\x08\xac\x05\xb1\x82\xff\x28\x0c\x64\x9b\x12\x4f\x19\x1b\x21\xb8\xbf\xff\x41\x91\xea\xd8\x35\xa6\x21\x41\xbe\xde\xca\x06\x6e\xcb\xea\x39\x6f\xb2\x83\x68\xc0\x52\x47\xf6\xb8\x6e\xbb\x27\xa5\x51\x82\x74\x86\x0f\xe2\x7f\xf7\xa2\x6e\x1e\xcb\xa6\x63\xcf\x64\x5e\x1a\x93\x5e\xfa\x7d\xf9\x62\xa1\x5d\x9f\x4c\xa3\x54\xc4\x48\x67\xba\x80\xaa\x69\x32\x73\xbe\x18\xd5\x5f\xc1\x30\x98\x27\x18\xe9\xfb\xa1\xa2\x7a\x71\x9d\x70\xc1\x1e\x92\x5d\x36\x8e\x53\x91\x35\x67\xe4\xa5\x19\x75\x8b\x62\xdf\x32\x37\xce\xac\x6e\x44\xbb\x7f\x3b\xab\xb2\xed\x90\xc8\x70\x98\xfc\x5e\x88\x3c\x97\x42\xbd\x8e\x93\xe0\xee\x0a\x05\x94\x25\x7c\xda\xcc\xa1\xd9\xe4\x65\x73\xb9\x99\x89\xd0\xc1\x43\x14\xa9\xdd\xc5\xc6\x32\xab\xa3\x5f\x2a\x99\x16\x3d\xf5\x5e\x84\x1a\xf5\x64\x81\xda\x1e\x26\x90\xe8\xf0\xe7\xe5\x49\x3f\x94\x65\x2e\xf6\xae\x49\xf1\xc8\x73\x72\x68\xdf\x90\x53\x08\x49\xc5\x7a\xb2\x1e\x6d\xa7\x20\x46\x2e\x75\x29\x47\x3f\x44\x25\x9e\x47\xa4\x13\xcd\x1a\x54\xf6\x06\xe3\x2d\x4d\x25\xbe\xf0\x5d\xf1\x16\x31\x2d\xb5\xff\x57\x9e\xce\xe3\x3b\x49\x85\x20\xd4\xdf\x45\x79\x9d\x86\x60\x9e\x16\x1c\xa1\x54\xf5\xa9\x7a\x83\xf3\xb2\xd0\xb3\xc6\xbd\x9c\x96\x42\xdb\x68\x8e\x18\xee\xfa\x5f\xf2\x0d\x30\x4f\x2b\x15\x58\x2b\x62\x03\xa0\xf1\x50\x9e\xf2\xc9\x99\x07\x5e\x88\xb5\xf6\x52\xc3\x1b\x22\xb2\x3e\x99\xab\x10\x4b\xbc\xe3\x16\x83\xd9\x97\x1d\x00\x12\x9f\xb2\xb1\x7b\x50\xaf\xb3\x42\x5b\x6d\xca\xc9\x5c\x3a\x63\x5e\x00\x68\x54\x7c\xcb\x4b\x29\x72\x97\x8a\x1e\x21\xae\x87\xbf\x85\x79\xb1\x44\x07\x18\xd9\xa7\x37\xa7\x43\x4f\xe3\xbc\x6d\x15\x01\x56\xb8\xbe\x39\x50\x9c\xc5\x51\x8c\xee\x61\x25\x95\x85\x6e\x3d\xec\xac\xab\x1d\x60\x8c\xc7\xbe\x76\x1c\x77\x1d\x8d\xcd\x4c\x6b\x32\x66\x32\x7b\xca\xb9\x08\x26\xe3\x89\xbb\x2e\x25\x9a\x8b\xba\xa9\x16\x58\x0f\x3b\xc9\x73\xe8\x3a\xcb\xd8\x90\xac\xd0\xf9\x1b\xd5\x17\x53\xc0\xb9\xff\x43\x38\x90\xca\xd2\xa6\xb4\x49\x09\x17\x55\x73\x71\x92\x0d\x4c\x54\x71\x38\x5b\x83\x31\xdf\xe3\x58\x62\x68\x3e\x3e\x5e\x33\x55\xa2\x06\xe0\xc5\xba\x65\xcc\xd7\x24\x6d\x43\x4e\xf6\x37\x28\x3c\x5b\xfc\xd7\xec\x6f\x8a\xa1\xcf\xc7\x58\xc4\x04\x06\x50\x7e\x1b\xdb\x52\x83\x9f\x15\xf9\x54\x4e\xa6\x61\x10\x15\x66\x2c\xd2\xc6\x15\x22\x3c\x40\x23\x5a\xa7\x72\x48\xf5\x3f\x9c\x15\xb1\x1f\x3a\x95\x53\xbb\x2d\x7c\x43\x41\xeb\xe1\x37\x8c\xd3\x88\x90\x0e\x36\xf6\x86\xe3\x72\xea\x25\xd2\x19\x4b\x94\x54\x69\x2f\xaa\x32\x08\x4c\x4e\xce\x6b\x96\xf2\xd8\x96\x30\x0e\x0c\xa2\xab\x84\x88\x8d\x29\x30\x96\xfa\x0a\xe9\xef\x31\x86\xb1\xca\xc5\x19\x29\x7a\x06\xe3\x22\x18\x55\x16\xb7\xbb\xe6\xd1\x4a\x21\x5c\x18\x2a\xfb\x26\x62\xdb\x57\xa0\x29\x31\xcf\x1a\x55\x66\xc5\xf2\xdc\xfd\x18\xe1\x53\x52\xc5\x94\xd5\x80\xa5\x73\xf2\xac\x64\x22\xe0\x48\xbe\xb1\x28\x0b\xd8\x3a\x85\x47\xfc\x7b\xca\x5d\x5d\xfb\xe9\xf0\x64\xee\xcb\xa6\x81\xea\xec\x90\x9f\xae\x17\x84\x91\x25\xbb\xdc\xe4\xe5\x8b\x28\x86\xbb\x85\xed\x25\x3d\x0f\x0d\x24\xcb\xac\xd5\x5d\x2d\xa3\x10\x2c\x96\x6d\x55\x95\x47\xa8\x9a\x73\x7b\x2a\x5a\xe6\xbc\xd3\x35\xe3\x25\x63\x2a\x00\x8a\x6c\xa3\xea\xcb\x2d\xc0\x6d\x25\xd4\x15\xfa\x9e\x31\xa5\xe2\xb4\x2f\xc8\x45\x14\x72\x48\xf3\xff\xff\x93\x18\x64\x4c\xfb\x1e\xda\x42\x0f\x62\x2f\x72\xd1\xdb\xc1\x98\x8e\x00\xf3\xe0\xcf\x9b\x9b\xae\x18\x99\x31\xad\x35\x1a\xe5\xdb\xea\x04\x3f\xe0\x45\x14\xed\x25\x2e\x29\x65\xfb\x40\x44\xc2\x3d\xe8\x1e\x3d\xc9\xff\xb9\xbf\x9b\x94\x70\x51\x5d\x4d\x20\x0e\xf6\x27\xdb\x9b\x51\x0a\xe3\x6f\x76\x02\x6c\x4a\xe3\xbe\x1d\xf7\x7c\x8e\xf9\x9b\x76\x18\x9f\x0c\x26\x68\xd6\x94\xa8\xed\x7a\x08\x8e\x22\xf5\xad\x1f\xf2\x28\x8e\xaf\x9d\x97\xdb\x36\x25\x18\xf2\x5b\x55\x70\x14\x15\xac\xcb\x3c\xa7\xcc\xcc\xe4\x3a\xe0\x9e\x54\x58\xbd\x8d\x38\xa2\x35\xa8\xf2\x0d\xaa\x45\x99\xe7\xa2\x81\x4a\xe4\x4f\xc5\x1c\xf6\x22\x37\x97\x14\xd3\x24\xc6\x90\x71\x16\x0a\xc4\x24\x3c\xc2\xfb\x33\x79\x6d\x0f\x94\xc1\x1a\x75\x93\x29\x66\x63\x36\xf3\x65\xef\x53\x70\x1e\x04\x9e\xad\x7f\xda\x1d\x73\x51\x40\x5f\xaa\xbf\x6d\x0f\x25\x06\x90\xa5\x4b\x8d\x6d\xd4\x1e\xf2\x3c\x2b\x5e\xd6\xfd\x64\xf5\xe8\xa7\xf1\x84\xa3\x6b\x22\xb4\xc6\x6d\x77\xaa\x2e\xb2\xed\x95\x78\x17\xd0\xc4\x27\x10\x84\xde\xca\xe5\xbe\x47\xee\x02\x5d\xb0\x2b\xad\x7d\xe4\xde\xd5\x8f\x0d\xe2\xa8\x73\x78\x43\xc3\x6a\xb4\x9d\x71\x5f\x78\xe2\xc2\x2b\xdd\xdf\xaa\xb9\x2f\x02\x94\x13\xee\xe6\xcf\xc7\x27\x1f\xcd\x57\x12\xd1\x63\x87\x5d\x71\x3a\x10\x5d\x97\xbb\x47\xe0\xf9\xb8\x07\x35\x20\x0e\xdb\xf7\x12\xc3\x30\xab\xfe\x58\x06\x22\x72\xb1\x3f\x82\x48\xf4\x68\xf9\x19\x0f\xb9\xc4\x6c\x1b\x39\xb8\x17\x0a\x92\xeb\x83\x87\x47\x01\xf1\x74\x6e\x97\xbd\x14\x59\xfb\xe7\x44\xda\x4d\x61\xf6\x26\x1a\x51\x5d\xa3\x7d\x19\x8f\x22\xa6\x02\x4b\x97\x37\x3b\x5d\x48\x8a\x46\xb3\x2a\x8a\x02\xeb\x20\x39\x4d\xb9\xe9\xf1\x88\x22\x62\x30\x5c\x94\x07\xca\xb9\x8e\xbd\x24\xf2\xa9\xfe\x1b\xfe\xd1\xfb\x7f\x13\xf9\x8d\xff\x72\xef\x0f\x77\x4b\xcd\xd3\xf6\xd1\xff\x3b\xd5\xcd\xad\xc8\xf2\x35\x41\x03\xdc\xaf\x8c\x03\x4a\x81\x58\x10\x44\xbb\x3d\x61\x46\x07\xea\xf1\xfc\x8a\x43\xaa\x04\x30\x00\x03\x80\x1f\xe3\xb1\x26\x02\x02\x8a\xb2\xdc\x96\x95\xdd\x66\x9c\x3b\xc5\x13\x4e\x42\xaf\x8e\x0b\xe5\xb9\x20\x9a\xdc\xae\x3d\x81\x38\xb2\xc3\xb3\x24\x7e\xb3\x07\x9b\xdf\x77\x5d\xd2\x30\xc2\xdc\xf4\x4b\x39\x17\xea\x75\x5b\xf6\xb0\xa3\x5d\x97\xf6\x36\x84\x23\x98\xe0\xcb\x60\x3c\x4d\x19\x27\x7e\x87\xfa\x24\x6d\xd9\xe9\xbf\x4e\x97\xea\x53\xc6\x53\x41\x34\xc6\x05\xbc\xdf\xa9\x72\x72\x49\xfe\xd3\x7f\xdd\x1d\xad\xdd\x86\x68\xaa\xa2\x18\x65\xc2\xdb\xf6\x04\xb4\xf5\x3f\x11\x33\xb1\xbd\xb0\x06\x75\xbf\x4b\xc7\xb8\x1b\xdb\x32\xb8\x0d\x7c\xa1\x24\xf7\xa9\x6c\x75\xc0\xb8\x08\x05\x69\x25\x0f\xb5\x50\x5d\x6b\x2c\x81\x58\x8f\xf6\xed\x7a\x76\x7f\x96\x1c\xf0\xcf\xa6\xac\x5e\x1f\xba\xbf\x2a\x4f\xe2\x5c\x70\x7c\xb3\x9f\x15\x5e\x8f\xde\x40\x79\xca\x49\x1f\xfc\x1c\x51\x0e\x33\xae\x62\x8d\x51\xcd\xdb\xa7\xe7\xc7\x9b\xe5\x7a\xf7\x73\x76\xbf\xdc\x76\x0f\x94\x0a\xa1\x0e\x48\x52\x58\x5f\x53\x03\x30\x0e\x09\x47\x8d\x91\x7b\xc2\x2f\x61\x59\x85\x6b\x52\x69\x70\xc9\x6b\x52\xdc\xb1\x2c\xf3\xc9\x38\x14\x07\x4d\x2a\x14\x35\x34\x37\xb3\xa7\x59\xa1\x89\x91\x2a\x7b\xf9\x64\x69\x03\x00\x65\x17\x0a\xa1\xd0\x7a\x18\xfd\x2c\x93\xf8\xd2\x62\x85\xad\xaf\x58\x56\xcf\x85\x2c\x91\xf7\xe5\xfe\x33\xda\x48\xe6\x7b\x9e\xb6\x12\xc0\xaa\x2c\x34\x9d\x9d\x1d\xbe\x9a\xf9\x5e\x60\x04\x15\x60\x0c\xf4\x11\x98\xcf\x3c\xcf\xc5\x1c\xee\xc1\x34\xed\x31\xf8\x13\xb2\xe1\x8f\xf4\x59\x4c\x74\x89\x3b\x82\xd4\x3e\xd7\x50\x2d\xb2\x4f\xa8\x5d\x18\x52\xbb\xa3\x8b\x02\x55\x66\xce\x3f\x87\xf4\x37\xe3\x7f\x7b\xb8\x48\x8a\x95\x4e\x86\xbe\x7c\x1e\x45\xa4\x6d\x50\x20\xdd\x80\xdb\x4b\x7c\x2e\x69\x07\xec\xc0\xb1\xeb\xd9\xf3\xc6\x35\xfa\x10\xa3\x36\xcd\xb7\x8f\xc5\x85\x94\x77\xf4\x01\xfd\x20\xf1\x88\xba\x5a\x34\xb0\xca\x45\xf1\x64\xa8\x66\x79\xfa\x70\xf5\x83\x34\x35\xac\x3b\xc6\xfa\xf4\x86\xcc\x0f\x44\xca\x45\x2f\x98\xef\xb0\x14\x9f\xb1\xc3\x0c\xbc\x0b\x3f\x0c\x88\x64\xab\x3d\x1a\x9a\xf2\x70\x57\xcf\x4f\xe7\x31\xac\xc4\x76\x8d\xd2\x54\x43\x0f\xc9\xf3\x38\xad\x1d\xde\xf6\x14\xc2\x0f\x2d\xbd\x56\x57\x6d\xcb\xfc\x24\x11\xd0\xb1\xc2\xf5\xf2\x96\x9f\xc3\x7d\xda\x6b\x48\x4a\xf3\xa6\xcc\xfb\xf0\x4b\xe6\xa7\x21\x60\xac\x49\xbf\x7c\x0c\x83\x0d\x7e\x9a\x48\x8c\x35\x03\xba\x98\xbd\x33\xc0\x4f\x53\x2e\x2f\x45\xce\x3f\x45\x55\x89\xa2\x39\x8f\xde\xe2\x1f\x45\xcd\x7c\x11\x9b\x54\x10\x36\x65\xff\x38\x08\x96\xf8\x42\x06\x18\x4e\xd9\x55\x14\xca\xbb\xfc\x5d\x21\xbc\xf5\x90\x15\xbb\xba\xb5\x14\x06\x66\x97\x2f\x85\x8a\x7b\xa4\x31\x59\x27\x6a\xc5\x7c\x29\xa9\xba\xd2\xd5\x3a\x0c\xfd\x86\x7f\x0d\x13\xb2\xcc\x97\x2a\x01\x42\xde\xc9\x1c\x6e\x60\x8d\x80\x49\xb5\x47\xf1\xa9\x9d\xcf\xb9\xbb\xad\x8a\x34\x73\x02\xde\x74\x0b\x24\x38\x9f\x4a\x02\x31\x5f\xb7\x7e\xdf\x25\x48\x64\xf7\xf9\xe1\x3e\xe2\xeb\x98\xea\x9d\xdb\x73\xa2\x3d\xf5\xb6\xf7\xbf\x1f\xa1\xba\x18\xfc\xbe\x4e\x15\x82\xb9\x11\x32\xb1\xbd\x7b\x58\x76\x0d\x8a\xb0\x50\x4e\xad\xdc\x10\x57\xd4\x78\xdd\x80\xcf\x70\x6c\x5b\xe7\x2b\x6b\x84\xbb\x1a\x02\x81\x70\x8c\x6e\x41\xe2\x04\xed\x89\xd1\xb9\x7e\xa9\x87\xa7\xef\xf1\xd4\xd8\x10\xdc\xb8\x9d\xa3\x3e\x44\x59\xc0\x43\x96\xe7\x5d\xf6\x8f\xf9\xa0\x79\x4a\xb8\xe9\x17\x0a\x7d\x5c\x21\x35\x98\x6f\x42\x4f\x0b\x5b\x33\x4e\x6f\xbd\x2d\x2f\xfc\xb2\x53\x89\x11\xe6\x9b\x58\x63\xb2\x69\xb3\x5c\x3c\x3d\xde\x6c\x76\xf3\xe5\xf6\xe7\x72\xf9\xb8\x5b\xb7\x07\x8c\xdb\x53\x02\x2f\xf4\x25\x9a\xe4\x50\x37\x3b\xa1\x5b\x33\x09\x3f\xa6\x29\xab\x5f\xba\x5c\x4f\xb7\x52\x03\x2f\x0d\xa8\x40\xe3\x24\xf3\xac\xde\xbb\xe8\xc0\x30\x0b\xca\x6c\x67\x26\x18\xfa\x6c\x48\x90\x97\xc3\xa1\xfb\xcd\x01\x37\x81\x2d\xd2\x7d\x39\x15\xba\x74\xcb\x28\xf0\x19\x47\x4d\x59\x7d\xaa\x9b\xa6\xac\x90\x72\xff\xe8\xc8\xe9\xdb\xe6\xd4\x4b\x9c\xa6\x03\xa2\xb5\x26\x0f\xb1\xc0\x0f\x7c\xfc\xe4\x65\x01\xda\x09\x92\xb0\x20\x08\x0d\x22\x8b\x55\xa0\xba\x3f\x45\x80\xc8\x05\x89\xfa\xde\xf5\x0c\x8b\x26\x08\x8b\x77\x03\x5d\x90\x29\x08\x85\xa0\x8a\xdf\x76\x55\x3f\x9c\x9b\x3d\x7c\x7c\xae\xf2\x1a\xb0\x20\x62\x52\xd8\xfe\x0a\x88\x99\x08\x0b\x3f\x7a\xbc\x23\x2c\x88\x2c\x1d\x1b\x49\xab\xf4\x4b\x87\x59\xfb\x5a\x4e\x4d\x74\x71\xaa\x88\xf7\xff\xb2\x6a\x83\xd8\x8b\x3c\xe1\x80\x3b\x68\xcf\x3a\xad\xa8\xf1\xba\x09\x62\x8f\xa4\x73\xa9\x40\xcb\x11\x66\xba\x46\x60\x78\x0e\xd2\xc9\xf6\x74\x6c\x1d\xf8\xd6\x34\xa0\x68\xff\x78\x54\x63\x63\xd0\xd3\x95\x59\x63\xde\x75\x7f\xcb\x0c\x12\xe6\x63\x38\xe0\x36\x7b\xd9\x5f\xb3\x03\xd0\x39\xd8\x79\x1c\x41\x9a\x86\xb8\x5d\x39\xff\x68\x8d\xb5\x95\x5f\xd3\x93\xb2\x40\x06\xa9\xcb\xac\xb6\x5e\xcd\xfd\xd3\x76\xf4\x7e\x32\xa6\x68\xab\xa5\x7b\x33\xe6\xef\x8c\x57\x77\x5d\x12\x22\x33\x53\x56\xaf\x90\x07\x7f\x34\x82\x52\x6a\x7c\xae\xa6\x6a\x24\x4a\x45\x4f\xbf\xa2\xe2\x02\x89\x66\x68\xfc\xbe\x8b\x42\xe7\xd3\x64\xf9\x2c\x50\x7e\x1c\xf7\x0a\x87\x45\x0e\xd7\x15\x9e\x2c\x50\x96\x0a\xe7\x20\x3e\x68\x82\x58\xbe\x73\xd7\x0c\x02\x4b\x97\x9d\xe8\xfc\x4c\xeb\xab\x9d\x29\xd0\x71\x82\xc0\x94\x9b\xe5\xe2\xee\x61\x76\xbf\xfb\xbf\xe5\xfa\xa9\x5b\xfe\x5a\x7a\x98\x33\xbf\x2f\xeb\xe1\x8f\x4a\x3e\x2d\x52\x9c\x1e\x44\x2d\x13\xf4\xb3\x88\x41\xa1\xac\xfa\xa4\x92\xb6\x0b\x70\xc0\x2e\xef\x22\x7f\xdd\x96\xa8\x5f\x30\x28\x8b\x74\xdd\x80\x61\x79\x5c\xaf\x88\x91\x25\xed\x9e\xba\xb3\xfd\xec\xbb\x87\x1e\x8b\x4c\x30\xe0\x53\xe9\x63\xb4\x58\xe8\x99\xc0\x99\xb2\x9b\x73\xbb\xb6\x87\xf3\x25\x64\x69\x60\x88\x58\x8e\x90\xd1\x3b\x2c\x3a\x1b\x85\x3a\x42\xce\x21\xb0\xa9\x98\xef\xd9\xcb\xfe\xa7\x18\xe3\x79\x59\xc8\x83\xc0\xf7\x6d\xc9\xc2\xaf\x59\x5d\xcf\xb7\x8b\xd6\x91\x74\x99\x96\xcf\xa8\x12\xed\xd5\xbe\x97\x7a\xd0\x55\x21\x89\xb7\xb2\x5a\xd6\xaa\xba\xd4\x5f\x4d\x0f\x78\xe8\xfb\xd2\xf9\xff\xad\x61\x6c\xb5\x56\x5c\xa3\x8e\x42\xab\x1b\x72\xaa\x60\x35\x42\xac\xb7\xed\xb1\xdd\x20\x5d\x68\xe0\x4a\x8a\x78\x38\x5f\xc3\xd6\x0e\x1e\xf1\x42\x3e\x66\xc5\xff\xc4\xf4\xe1\x13\x06\x02\x34\x7c\x9a\xa7\x1e\x75\x0e\x99\x87\x49\x6d\xfb\xd7\x55\xd5\xf7\x6b\xc3\x30\x10\x18\x01\xcd\xea\xfa\x34\x8a\x73\x87\x61\xe8\x68\xcb\xca\x0a\xae\xeb\x53\x58\x18\x71\x88\xd2\x0e\x18\xf3\x58\x6a\x20\xa5\xb7\xd1\xa4\xfe\x2f\xff\xe3\xbf\xe1\x1f\xee\x9a\x28\xc4\x40\xf5\xbb\x3b\x60\x27\x0f\x99\x30\x32\x5a\x5e\xca\xd9\x51\x17\x62\xf8\x72\x89\xaf\x90\x1b\x60\xe7\x40\xab\x95\x46\x84\xee\xe5\xd4\x9a\x1e\x8e\x24\xf4\x22\x2b\xd7\xe9\xa4\xd3\x07\x44\x41\x6d\x0f\x61\xc9\xd2\x09\xde\xbd\xb8\xa2\xab\x67\x61\x62\x0d\x26\xa1\x35\x61\xa5\x28\xdd\xff\x5f\x16\x47\x7f\xf4\x56\x78\xe2\xba\x6b\xe2\xf4\x6d\x3f\x17\x8a\x44\x5f\x8e\x89\x30\x0d\x0d\xa6\x83\x67\xf7\xf7\x4f\x8b\x9d\xd3\x84\xed\x5a\x63\xc6\xed\x61\x84\x5f\x60\xd9\xec\x1d\x7a\xfe\x33\x46\x1d\x7b\xa5\xf0\x34\x16\xf8\xef\x8e\x95\x23\x45\x20\xf7\xf4\xaa\x66\x7e\x38\xb0\x52\x51\x45\xe7\xf7\xc5\x6a\xdb\x3f\x86\x42\xa9\x7d\xd2\x8e\xa8\xe0\x58\x56\x0d\x19\x30\x83\x47\xaa\x98\xd8\x89\xc5\xa9\x29\xd7\x50\x34\xf3\x73\xeb\x9b\x4c\xfb\x46\xa1\xd6\x31\xe6\x96\x0a\x78\x5f\xa3\x34\x06\x19\xb1\x03\xd3\x78\x74\x09\x80\xc0\xb2\xef\xb7\xd6\xab\xeb\x68\x5e\x59\x08\xc6\xc7\x54\xcb\x3b\x64\x17\xa6\xc1\xf6\xcf\xe4\x50\x20\x8a\xfb\x6b\xa5\xad\x2f\x42\x1b\xa1\x61\x54\x52\x99\x23\xe2\x68\x8c\x29\x66\xa1\x09\x62\x4c\x2e\x68\x50\xa5\x06\x74\x1b\x5b\x9f\x77\x04\x97\x63\xa1\x49\x83\xd4\x82\xec\x2d\x68\xc4\x59\xf4\xa1\x11\x9a\xb9\x6a\xe0\x5d\xb3\xaf\x00\x2c\xb9\xe8\xf2\xcf\xbb\xce\x6e\x09\x8d\xa1\x4d\x49\xe5\xe5\x05\xb2\xdb\xcf\x41\x44\xcc\x4b\x30\xc7\xbf\x5c\xaf\xef\x7b\xa1\xe3\x88\xb3\x08\xe3\x17\x5a\x94\xdd\x9f\x7c\xe2\x95\x5b\x88\xc3\x51\x64\x2f\xc5\x67\xe5\x20\x9f\x8a\x6a\xf5\xbf\x7c\xe4\x0b\x23\xa3\x2b\xa2\xfa\x64\xfb\xbd\x63\xa9\x67\x91\x2f\x43\x61\x39\x1a\x9f\xeb\x1e\x9d\x26\x8b\xda\x0d\x53\x93\x9b\xbc\x2a\x5f\x5b\x53\x16\x45\x10\x29\x78\x7d\xdf\xab\x84\x1d\x7e\x99\x28\xe4\x69\x28\x1c\x5f\xeb\xc7\xea\xb2\xa2\xef\xf4\x85\x44\xec\x6f\x30\x21\xf6\x56\x91\x97\x20\xf8\xd6\x86\x71\xe0\x70\xcc\xbf\xa2\x50\x99\x48\xf8\x45\x91\x62\xc6\x06\xa0\x96\x39\xbc\x5d\xd0\x56\x83\xbd\x20\x8a\x40\x20\x2c\xee\x2f\x10\x75\x23\x74\x4d\x5a\x3e\xce\x48\x8f\xe2\xc8\x58\xc4\xd5\x53\xf5\x22\x8a\xec\xaf\xf1\xae\x1b\xc5\x8a\x1b\x7b\xf2\xda\xf0\xc6\xdf\x7d\xb2\xe1\xf5\x49\xc8\x84\x9b\x6c\x44\x5c\xf7\x9f\x13\x54\xe7\x09\xfa\x2f\x16\x25\x11\xc3\xe8\xeb\x5b\x99\x9f\x0e\x24\x76\x3a\x9c\xd5\x51\xa2\x21\x8c\x6d\x28\x1d\x53\xe4\x9f\xd0\xc6\xdb\xee\x69\x44\xba\x58\xae\xfa\x72\x49\xf2\xa5\x9f\x99\x43\x5f\x11\xaa\xd9\x3b\x0a\x26\x23\xc2\xb5\xfc\x79\x72\xe0\x37\x16\x09\x88\xa3\xe4\x42\xe7\x30\x91\xf6\x8e\xa4\x22\x61\x07\x7b\xc4\x1c\xf3\xac\xe9\xe5\x62\xfe\xfb\xc7\x70\x24\x94\xa7\xfd\xc4\xa1\xd5\xd6\xd0\x54\x19\xbc\xf5\xf8\xd6\x0a\xd3\x85\x93\x23\xe5\x1b\x04\xf8\x42\x9e\xbd\x64\x57\x50\xae\xd1\xeb\xab\xc8\x4f\x1c\x96\x95\x72\xe5\x0f\x70\x28\xab\xb3\xcf\xe6\xed\x18\x74\xf7\x4c\x68\x57\x96\x70\x2e\x1d\x9f\x12\x8b\x54\x1a\xf1\x9e\xc2\x37\x45\xc6\xa7\xbe\x92\x52\x1a\xf1\xbd\x79\x6b\x06\x77\xf4\xbf\x2c\x52\x86\x0a\x11\x9f\xef\x17\x5f\xa4\x0e\x22\x2d\x62\xbc\x9c\xea\xc5\x9f\x37\x37\x8b\xe5\xe3\x76\xb7\x5a\xdf\x2d\xba\xd5\xad\x55\x1c\x59\x39\xd6\xed\x3e\xab\x34\x39\x66\x28\x6d\xd6\x88\xc3\xb1\xeb\x66\x48\xc4\x4b\xe5\x20\x8a\xd3\xf1\x79\x7d\xdf\xfd\x44\x08\x49\x4a\xad\x86\xc6\x81\x8b\x86\x6f\x01\x91\x46\x87\xca\xa6\x13\x5c\x49\x91\x6b\x8d\x3d\xfc\x9c\x79\x56\xbc\x6e\x4b\x4a\xac\xfd\x1c\x14\xf0\x8d\xd6\x81\xe1\x44\x7e\x58\x23\x47\xd6\x3c\xfb\xba\x3a\x90\x45\x26\x0c\x88\x84\xc9\x91\xde\x4e\x5a\x2e\xb1\x97\xc6\x41\xd2\x23\xff\xb9\xa9\xca\xc2\xed\x74\xb1\x27\x02\x2b\x88\x79\xa9\x09\xf6\x83\x41\x90\x35\xf6\x80\xe4\x6e\x1e\xb2\x22\x7b\x40\xc2\xa3\x2b\xe8\x53\xd7\x13\x3c\x4a\xcf\x23\x45\xc7\xe0\x75\x63\xe6\x0b\x0c\x26\xe8\xac\x02\x45\x0c\x15\x33\x62\xa8\x73\x2f\xc3\x12\x2f\x6a\x47\x6c\x9f\x35\x97\xe2\xf4\x55\x05\xaa\xa3\x18\x61\x31\x4f\x09\x01\x84\x00\x50\x72\xcb\xfb\x12\x8c\x2e\x76\x15\x73\xed\x25\x9e\xf3\x50\x06\xc8\x02\xdb\xc1\xf7\x0d\x86\xc9\x4c\xd9\x67\xd1\x64\xb1\x2f\x59\x62\x3d\x80\x9f\x90\x4d\x80\xa6\x62\x5f\x71\xbc\x72\xbd\x5c\xde\x0e\x2f\x35\x46\x2a\x67\xa4\x7f\x96\xe0\x8c\x83\x40\xeb\x80\x52\x4b\x54\xfc\xe1\xfe\x2e\x52\xcc\x1f\x5b\x46\x8a\x6b\x84\xcd\xb4\x11\x12\x07\x86\x21\x7d\x0d\xad\x85\xf5\x6c\xeb\x96\x40\x1c\x4a\x2a\x43\xba\xc4\x91\xfa\x14\xf0\x83\xed\x24\x8e\x3c\x61\x94\xcd\xed\x61\xe6\xb9\xfe\x9e\xb5\x76\xf6\x79\xf4\x89\x23\x9f\xa3\x68\x86\xab\xfe\x68\x1d\xbb\x1e\x65\x7c\xff\x7c\xb9\x3a\xe1\xbe\x9c\xce\x71\xe4\x47\x58\x90\x65\xc5\x53\x37\xd9\x5f\xd0\xfd\x92\x48\x01\xee\x9e\x77\xf5\x34\x47\x30\x8b\x63\xbb\xeb\xd2\x87\xbe\x75\xfa\xc2\x89\x6b\xf6\x03\x0a\xc8\x1d\xa1\xf8\x26\x0e\xb0\xca\xc5\xf9\x71\xe4\xfb\xc7\xb1\x30\x28\x7a\xb9\xbd\x5b\xae\x77\x7c\x37\x7f\xfe\xdd\x95\x61\xb2\x38\x89\x58\x6c\x7a\x44\xbc\xa0\xaf\xb5\x32\x58\x9c\x46\x12\x4d\x2f\xac\xa9\x75\x5a\xec\x93\x41\x56\x77\x41\x4a\x5a\xba\x1a\xc8\xb6\x6f\xcd\x45\x94\xdb\x9c\xc8\xe9\xc5\x82\xa7\x9e\x8d\x13\x11\x5a\xa3\x27\xd4\xc8\x62\x11\x47\x71\x57\xc1\xdf\xd4\xfd\xe8\x53\x2c\x62\x1d\x75\xb8\x2f\x1b\x72\xc5\x48\xde\xf0\x6d\xa4\x1f\xe0\x03\x6e\xca\xf7\x22\x2f\x85\x7e\x38\xd5\x99\xfa\xda\xa1\x8d\x65\x12\x19\x47\x39\x57\xe6\x99\x3a\xdf\x40\x23\xb2\xbc\xb6\x15\x45\x03\x37\x25\x96\x22\x09\x7a\xef\x71\x90\x50\x0d\x38\x1e\x6c\x37\x15\xfb\xc2\x4e\xdc\x6d\x39\xcf\x85\x7a\xbd\x1f\xd3\x8f\xb0\x58\x25\x1a\xef\xb5\x59\xfe\x7a\x25\xed\xc6\x62\x25\xfd\xd0\x77\x64\x08\x37\xa0\xb2\x83\xc8\xbb\xa1\xd2\xa1\x91\x84\x78\x25\xa6\x29\x3a\x1b\xea\x3e\x81\x2b\x8b\x35\x90\x4c\xc4\x21\x2b\x9a\x01\x89\xd1\xf0\xf7\x43\x02\x51\xec\x2a\x81\x0e\x47\x04\xdb\xe8\x2e\xab\xfc\xf5\x94\x07\xc1\xb5\xa2\xb2\xd2\xc6\x94\xd5\x81\xbe\xfa\x48\x50\x9a\xc5\x86\x7b\x78\x28\x7e\x9b\x6d\x17\x5f\x41\xbc\x62\xa3\x09\xb3\x49\x34\x55\xf3\xcc\xe1\x6f\x07\x4f\x4d\xbc\x44\x53\x06\xbb\x35\xee\x29\x27\xb6\x6b\x3f\xd9\x2f\xae\x5d\xc6\xb8\x56\x7e\xfd\xf5\x12\x4e\x4d\x3c\x45\x5a\x2b\x47\xaa\xb0\x1c\x6d\xb7\x89\x67\x22\x04\xa4\x38\x77\x71\x87\xbb\xd1\x66\x67\xf3\x9b\x9b\xdd\x76\x39\x7b\x70\xf7\x62\x51\xc0\x48\x50\xf0\xa5\x12\x6f\x63\x9a\x20\xdb\x89\xa7\x41\x70\xd9\x68\x1e\xe1\x7d\xb1\xfc\x65\xd4\x03\x42\x4c\x4f\x50\x32\xab\xf3\x17\xa6\xa6\x6b\xf2\xdf\x3f\x7a\x2c\x44\x43\x2a\x7e\x96\x70\x23\x82\xc8\xd1\xfa\x9c\x6a\xb8\x2e\x9a\x67\x89\xcf\x38\xa3\x8c\xc4\x07\xf1\xcf\x5f\x04\x82\x58\xe2\x73\x09\x64\x69\x17\x50\x89\x06\xba\xda\x8a\xde\x7e\x1b\xf4\xc9\x44\xdd\x75\x51\x82\x6e\x50\x56\x64\xcd\x26\x7b\x29\x00\x75\xe6\xba\xbb\x1a\x0f\xb3\x4c\x18\x2a\x42\x9d\xc6\x4b\x9c\x24\x09\x7c\x21\x2c\x8f\xc0\xa9\x86\xea\x50\x16\xf0\x49\x46\x33\x09\x52\x02\x82\x2d\x37\xab\x5c\x34\x9d\x65\x9f\x84\x1c\x10\x34\x35\x3f\x0d\x32\x62\x49\x98\xa6\x98\xa1\xd9\x40\x05\x45\xd6\x9c\x91\x96\x2d\xcf\x4b\x75\x21\xbe\x63\x49\x68\x28\x37\x54\x11\xfc\xbe\x53\x2d\x6c\x5b\x34\x82\x2c\xdc\x96\x46\x72\xee\x9f\xbc\x5b\xe4\x0b\x84\xd3\xbe\x65\xaa\x29\xab\x0c\xb0\x98\x87\x0d\x5e\x27\x8a\x7d\x2c\x81\x2d\xe0\x7d\x87\x0c\x14\x3b\x53\x56\xbb\x02\x3e\x9a\xdd\xb1\x27\x03\xc0\x92\x28\x89\x31\xfa\xb3\x10\x79\x3e\x93\x65\x75\x45\x12\x65\xfb\xc5\x82\xa5\x76\x5c\x5f\x60\xdb\x3a\xb7\x3d\x71\x63\x96\x24\x3e\xe9\x28\xbb\x24\x19\x4e\x89\xa5\xa8\xda\x15\xd9\x8d\x5d\xa2\x89\xb2\xd3\x52\x71\x58\xb2\xf9\x9e\xbb\xde\xb1\x92\xbb\x7f\x26\xd6\x6b\x92\xfa\x29\x46\x74\x4d\x96\xe7\xad\xbd\xe7\xfe\x2c\xa2\x04\x6c\x84\x71\x3a\x6a\x94\x08\x20\x6d\x4c\x8c\xe5\x5b\xed\x6e\x3b\x6d\xad\x0a\x53\xbb\x63\x62\xa4\xe8\x41\x0c\x6b\xcc\x58\x22\x15\x87\x0b\x16\x0a\x29\x59\xb2\xe2\x65\xdd\xe5\x13\x2c\xfe\xcf\x85\x56\x13\xa9\x62\xac\xa3\x7e\x11\xf5\x6d\x59\xfd\xfa\xd3\x65\xe1\x12\x15\x6b\x60\x97\x5c\x5e\x8f\x4a\x77\x60\x41\x26\x4a\x78\xca\x82\x55\x9e\x0a\x22\xa8\xfc\xd2\x87\x4a\x94\xf4\x30\x8f\x81\x5a\xd1\x87\xc1\x74\x50\x86\x68\x10\x5b\x3b\xa5\x26\xe8\xff\x14\x49\xb1\xed\xad\xad\x52\xb5\x22\x13\x85\xea\xc3\x6f\xcb\x71\x26\x69\x34\xba\x3a\x0e\x1d\x8c\x01\x99\xbd\x29\x57\xe2\xde\xc0\xb0\x20\x89\x1d\x85\x68\x75\xe8\xa4\x3d\x6f\xab\xf2\xd0\x69\x2b\xb3\xc4\xf8\x02\x95\x4c\x46\x5a\xec\xd7\x93\xa3\x7b\xdb\xd4\x13\xc4\x05\x4d\x3c\x1f\xf8\xb3\xa9\x8c\xa3\x57\x40\xc8\x52\x4f\x11\xf9\x26\x11\x87\xff\xe7\xd4\xfa\xb7\xdd\xd7\xef\xb6\x8f\xd4\x33\x3e\x16\x2d\xaf\x9e\xe7\xf7\x77\x0b\xd4\xae\xba\x16\xa5\x63\x29\xf3\x98\x17\x74\x29\xa3\xcd\xa9\x3e\x42\x7b\x82\xad\xac\x84\xfd\x70\xea\xb4\xbd\x51\x61\xef\x06\x8d\xf2\x39\x0c\x15\x56\xfe\xbf\x04\xcf\xdb\x9b\x19\xc4\x0c\xcc\x67\x9b\x65\xdf\x70\x4d\xb9\xaf\x30\xe2\x89\x0e\xdd\xae\xdd\x11\xba\x96\x30\x05\x2a\x61\x41\x07\x60\x01\x55\x33\x8c\xee\x5e\x25\x2e\x86\xad\xc3\x17\xe0\x11\xc3\x60\xbc\x12\x79\xbe\xdd\x67\xf5\xb6\xbc\xe8\x44\xb1\xd4\xf7\x12\x13\x3b\x32\x5d\x78\xcb\xca\x53\xfd\x88\x54\xdb\xfd\x53\x28\xf5\x65\x82\x81\x61\xfc\xeb\xb6\x7c\xce\x8a\xe6\x97\xeb\x48\x58\xea\x03\xc3\x5c\xe7\x53\x25\x4f\x7d\x62\x2f\x96\x06\x51\x6a\xa0\x9f\x73\x5e\x40\x9e\x5f\x29\xa3\xb0\x34\xf4\x49\x31\x63\x51\x66\xc5\x16\xdc\x69\x9d\x46\x8a\x4e\xf3\xba\x41\xfa\x3f\x24\x47\xb5\xb2\x61\xa3\x80\x5f\x1a\x19\xa1\x91\x43\xea\xf2\x1b\x63\x4b\xaf\x67\x09\xba\x06\x79\xc9\x34\x8e\xc0\xd9\x9b\xe4\x07\x0d\xe7\x42\xa2\x39\x3e\x19\x0d\x24\x3a\x1f\x90\xca\xc3\x35\x43\x1a\xd8\xb0\x10\xa9\x00\x8c\xde\x26\x0d\x42\x44\x95\x2e\x3f\x8e\x59\xbb\x57\x10\x29\xc9\xb8\x93\x96\xc8\x80\x23\xde\xde\x32\xb1\x7b\x2b\x1b\xf1\x57\x56\x16\x99\x7b\x86\xf0\x35\xb8\x22\x95\xe6\xae\x81\x4f\x62\xbb\xa9\x48\x88\xad\xe0\xb7\xd5\xac\xbb\x54\xfa\x0c\x2c\xf3\xc2\x66\x27\x06\x00\x8f\x54\xea\x08\x37\xe6\x47\x91\x55\x65\xe3\xb4\xec\x58\xaa\x80\x63\x29\x2c\x54\x6a\x5b\x3e\x8a\x26\x7b\x83\x79\x95\xe9\x17\xa8\x87\xae\x6c\xaa\xa5\x17\x4b\x67\x11\x94\xa7\xba\xab\x93\x64\x29\x44\xe0\x8a\xeb\xd0\x1f\x7f\x14\x07\xa8\xfb\x80\xfc\x14\xe2\x30\x49\x3b\x84\x36\x56\xa1\x5a\xa3\x7a\xda\xfa\x1b\x47\x01\x4f\x7d\x3a\x32\x77\x4f\x61\xd0\xd4\x7c\xcf\x0a\x2b\xfa\x3f\x1a\x69\x30\x09\x46\x83\xef\xe6\xeb\xc1\xf4\x34\x91\xf0\xa9\x00\xdf\x1a\xc1\x4f\x6f\x9d\x8d\x9c\x1a\x23\x10\xb7\x65\xb2\x63\xbd\xb6\xb8\xa1\xe1\x2c\x11\x5e\x42\xd3\xa0\x47\x4a\x54\x5f\x75\x21\xd4\xc5\xff\x4e\xfa\xa5\x17\x47\xee\x52\xc8\xc2\x93\xa4\xc2\x53\x41\x21\x0e\x23\xa9\xa4\xc1\x89\x2a\x98\x17\xfa\x86\x0a\x3d\xd6\x68\xd9\xde\x8b\xba\x59\xec\x45\x6b\x19\x76\xc9\x59\xd7\x57\x84\x89\xd3\xcb\x78\x2f\xc0\x91\x87\x0c\x86\x45\x30\x1d\x45\xaa\x0f\x66\xad\xb7\xa5\x0b\x27\x8c\xba\xf2\x88\xe0\x0c\xa8\x64\x09\x99\x72\x9e\xbd\xe0\x89\x36\x4e\x2a\xdd\xd6\x96\x8e\x47\x89\xa7\x5c\xba\x4d\x00\xd7\xda\x6c\xfc\x22\x01\x0b\x39\x72\xab\xde\x3d\x2c\x6f\x96\xbf\xb9\x7b\x07\x5c\x8a\x0b\x55\xca\x23\x34\xef\x65\xf5\xba\x28\x8b\x82\xb4\xe7\xa6\x31\x49\xee\xda\x88\xa1\xeb\xb6\xb9\x99\xf5\x3f\xb9\x08\x52\x72\x03\xfb\xac\xe8\x2e\xb8\x35\xba\x43\x1a\xa0\xad\x27\xb0\xe6\xc1\xfd\x51\xf9\x78\xf9\x4e\x9e\xaa\xc2\x6e\x45\x8b\x1c\xc4\x34\x89\x65\xdb\x3f\x94\xa6\x73\xdd\x07\xd1\xc2\x7f\x06\x3c\x15\x21\x23\xc2\x0c\x74\xf6\xbc\x0f\xd9\xa8\x21\x94\x4b\x84\x21\x4b\x4c\x27\xa4\x06\x77\x85\x29\xef\x8a\x1b\x71\x65\x31\x8f\xef\x9b\x2a\x52\x6d\xbf\xf9\xb6\x9d\xaa\x53\x4e\x86\x93\x2f\x94\x3e\x22\x1d\x9c\xe5\xd8\x31\x15\x7c\x8d\x75\x10\x91\x22\xbd\xd5\xf5\xd3\x66\xa1\xca\xec\xaa\x24\x7a\xf0\x90\xc8\x04\x48\x08\x7e\x7b\xb7\xdc\x6c\xdd\x6e\x26\x62\x4f\x22\xfc\x47\x68\x3d\xab\x5e\x4e\x07\x2c\xbf\xb3\x42\x00\x1b\xbc\xfc\xb3\x90\xb6\xbb\x41\xc4\x93\x4b\xe4\xb6\x3d\xc5\x46\xf4\xa9\x57\xd1\x9c\xa9\x97\x8b\x63\x1e\xd9\x10\x66\xad\xaa\x4c\x8e\x8e\x0c\x91\x78\x91\xb2\xc8\xa6\x5b\x71\xc8\xf2\xf3\xb8\x9d\x2b\x34\x6d\xaa\x53\x0e\xf3\xd1\x02\x48\x02\xe1\xe9\x5e\xed\x57\x6b\x8b\x4e\xb2\x5b\xf4\x6d\x57\x91\xf2\x04\x4f\x57\x5d\xbe\x17\xdb\xec\x9a\x95\xd9\x75\x0b\x7c\xe0\x2e\x54\xd6\xe7\xb1\xee\x43\xe8\x07\x10\x4f\x7b\xa1\x50\xca\xc6\x8f\x45\x76\xd8\x41\xb3\xdf\xc9\xf3\xe8\x34\x11\x12\x62\x44\xcd\xea\x72\x02\xcb\x2b\x54\x48\xd4\x4d\x07\x51\xd7\xe3\x54\xa8\x73\x51\x85\x0a\x35\x56\xb1\xd3\xe7\xe9\x1b\xda\xd3\x99\x20\x7b\x99\xf6\x4d\x48\x04\x7b\x99\xc2\x72\xb9\x59\xde\x88\x11\xa0\x41\xe8\x50\xc5\x17\x49\xa4\x6f\x55\x79\x3a\x8e\x93\x54\xae\x67\x9c\x84\x54\xdc\x77\x9e\x15\x1a\xab\x59\x3f\xa9\x05\x15\x5a\xfa\x68\x58\xd4\xe2\x0d\x7a\x64\x0b\xae\x15\x22\x69\x2b\x98\xdc\xb1\x01\xfa\x36\xab\x0e\xbf\x8c\x75\x57\x98\x00\x01\x82\x30\x4d\x75\xf3\x13\xdc\xd1\x2f\x40\xc7\x8a\xe4\xb3\x48\x8a\x65\x79\x38\xe6\xe5\xf9\x13\x7a\x79\x26\x0c\x23\x1e\xca\xbe\xc3\xb4\x28\x35\x60\x90\xca\xf5\x31\x54\x5b\x74\xec\x88\xd6\x28\x5e\x3f\x4a\x5e\xc8\x76\xad\xe9\x81\x34\x8f\x6e\x7d\x64\xa4\xc2\x72\x1f\x5d\xf2\x20\x09\x89\xe6\x43\x34\x23\xf8\xb9\xe4\x89\xa7\x9d\x9e\xe8\x6f\xed\x6e\xb1\xb8\xb2\x2b\xa5\xcf\x3d\x64\x4d\x5a\xe5\xe2\xbc\xc9\x0e\xc7\x1c\xba\x3a\xf3\xa4\x37\x3c\xd2\x17\x1e\x1a\x75\xca\x3e\xc3\x55\xcd\xbb\x66\xcd\x12\x1b\xc5\x1a\x48\x8a\x32\x19\x04\x7e\xca\x3b\xa2\xe1\x1b\x51\xbd\x16\xe5\x88\x34\x9a\xc9\x40\x44\x9c\x84\x5b\xeb\x7d\x3f\xce\x3e\x9c\x18\x32\x90\x24\x6a\x8f\x41\xc0\x32\x97\xe7\x6f\xcd\xf9\x08\xfd\x08\xac\x0c\x83\x28\x16\xae\x3c\xfc\x28\x32\xbd\x82\xca\x58\x08\xd4\x27\xfe\x90\x8c\x8c\xad\x83\x20\x42\x9c\x53\x8d\x30\xbd\xe1\x38\x45\x46\xa1\x95\x6e\xc3\xc6\x37\xd9\x4b\xeb\x6d\x4d\xce\x5f\x99\x78\x2c\x71\x8c\xe9\xab\xaa\x34\x59\xa7\x97\x3d\xce\x0b\xc9\x24\x0c\x30\x85\x7f\x03\x6f\xbb\x01\x2c\x57\xa6\x81\xc1\xdc\xf8\xae\x29\xb7\xe2\x63\x6c\x64\xcb\x34\x49\x71\xa5\x2e\x44\xbd\x1f\x09\xca\x8c\xde\x26\x55\xcc\xe9\xe1\x6c\xf6\xd9\xb1\x76\x9c\xab\xae\x59\x2b\x64\xb6\xda\x8b\x7a\x92\x76\x86\x49\x11\xc4\x98\x02\xfc\xf6\x74\x7f\xe3\x48\x93\x1f\x6f\x16\xee\x06\x22\x15\x2c\xee\x3e\xf0\x43\x96\x43\xdd\x94\xc5\x30\x30\x2e\xa5\x17\x22\xf3\x65\x7d\x3e\xc8\x32\x1f\xac\x52\x29\x79\x84\x62\xcc\x7b\x84\xb6\x59\x8f\x70\x34\x41\x64\x48\xac\x03\x20\xd4\x9e\x34\x22\x06\x3e\x84\x74\xfc\x4d\xf7\xd9\x1b\x1c\x01\xaa\x1f\xb8\xfe\x26\xc8\x05\x06\x4f\x56\x9c\xe2\xe8\x3d\x0b\xf8\x73\xc1\x07\x26\x55\x2c\x99\xe9\x2b\x9f\x39\x73\xd9\xb5\xeb\x18\xbd\xd6\xf5\xb6\xcf\x21\xc3\xa4\x4e\x02\x21\x2e\x95\x01\x33\x63\xb2\x3c\xbb\x02\x54\x48\xf0\x48\xc6\x75\xb3\x7a\xda\xa6\xee\x5a\x08\x48\x79\xe3\xb7\xd9\xf3\xcd\xe0\xa6\x90\x04\xca\x74\x75\x1f\x2f\x16\x0b\x3d\xba\xa3\x12\x68\x58\x60\x76\x0a\x87\xad\x27\x99\xcd\x24\x80\x71\x9a\x33\x1b\x2c\x07\x44\x85\x74\x34\x1b\xa9\x87\xf2\x22\xc9\xed\x9b\x0b\xb5\x1f\x4f\x42\xe5\x09\x81\x8e\x6d\x5e\xaa\xd7\xe7\xa2\x2e\x73\x3d\x44\xb0\xba\x6e\x5a\xe1\xc7\x5f\xcd\x7e\x7f\x7a\xde\xee\x6e\xd7\xb3\xc5\x6e\xfb\xb4\xea\x1e\x02\x0c\x23\xe0\xaf\x59\x07\x42\x54\x8c\x8b\xd8\xb1\x2f\x3c\x96\xdd\x5f\x03\xd2\xbf\x9a\x57\xe5\x2b\x54\x77\x87\x2b\x5c\xd9\x34\x16\x4c\xb1\x98\x8e\xdd\x63\x05\x77\x8b\xa7\xe9\x75\xa2\x98\x21\x1d\x8b\xc5\xd3\xe3\xed\xdd\x37\x12\xe1\xfe\x6d\xf5\xb4\x79\x5e\x2f\x77\x37\x77\x3f\xba\x77\x30\x21\xbe\x83\xae\x9c\xc4\xdb\xa5\x25\xc2\xd1\xc8\x0a\xd2\x01\xdb\x85\xae\x85\xab\x04\x2d\xf3\xdb\x53\x23\x06\x97\xf8\x40\xcc\xb6\x16\x5a\x34\x08\x23\xf6\xa8\x72\xfa\xc5\xc1\x2a\x60\x1e\x0f\x7b\x67\x74\xa1\x07\x35\x78\x83\xaa\x89\xd1\x4f\xc4\x98\x47\x7b\x58\x60\xa5\xd8\x4e\x0d\xcf\x0b\x15\x44\x86\xa8\x3d\x66\xf7\xf8\x96\xc9\xf4\x3a\x50\xa1\x22\xde\x96\xbb\xc5\x13\x74\x49\x79\x15\x31\x9b\xd1\x6f\xad\x63\xc4\xa4\xd5\x5d\x93\x2d\x76\xe9\x08\x9c\xe0\x7d\xc4\xfd\x31\x7c\xcf\x18\x24\xc2\x23\x8f\xe5\x11\x43\x15\xed\xf6\xa9\xf6\x40\x04\xb1\xb6\x4f\xc2\x82\xe8\x22\x57\x84\xe2\x43\xad\x49\x0f\xff\xd8\xa8\x1f\x3d\x33\xf1\x13\xc7\x6a\xb7\x99\x3d\x66\x4d\xf6\x17\xe8\xc1\x3e\xa5\x12\xc9\x10\x7e\x98\x03\xd6\x19\xb9\xe4\x4b\xfb\x56\xd6\xd7\x15\x2f\xd0\xbd\x9e\x14\xe8\xf7\x3f\xdc\x3d\x0e\xe2\x61\xbb\xc5\xf7\x5b\xd7\x27\x8d\x52\xdc\x7a\x8f\x7b\x51\x03\xbb\x39\x55\xfd\xf8\x5b\xdb\xea\xa4\xd3\x9c\x52\x0c\x5a\x38\xc3\xd7\x4e\x15\x89\xa7\x3b\x99\x01\x5b\x0d\x45\x19\xd3\x7e\x1a\xb6\x9b\x4b\xf6\x42\x11\x05\xcc\x1d\x7a\x7b\x51\xc1\x9e\xe2\xb9\xee\xe9\x22\xe6\x48\xed\x70\x10\x1f\x0b\x71\x5c\x75\x19\x0a\xd5\x9a\x49\xed\x03\x31\x7b\xeb\x30\x79\x9f\x7c\x47\xa9\x23\x70\x2a\xca\xd5\xa9\x6e\x40\xaf\x44\xd5\x5c\x01\x2a\x95\x34\xca\x86\x31\x9a\x5f\xe1\x5c\xcf\xcf\x5b\x77\xac\x5f\xee\xd5\x6e\x36\x21\xa6\x7e\xb6\xbb\x87\xe7\x7b\xf7\x3a\x2a\x49\x19\xef\x7c\xf6\xcf\x04\xfd\x98\x52\x26\x45\xd3\xa1\x44\x76\xc6\xb2\xec\x76\x1a\x1d\xc4\xe8\x16\xde\x2e\x97\xbb\xc7\xe7\x87\xe5\x7a\xb6\x7d\x5a\x77\x8d\x9a\x18\xfa\xb7\x50\x37\xb7\x0f\xb3\xaf\x3c\x26\x05\xb1\xc1\xc5\x35\x9f\x2d\x06\x09\xbc\xcf\x3d\x39\x05\xa9\x87\x89\x99\x79\xd6\x54\x65\x01\x1d\xb2\x4f\x41\x1a\xe3\xce\xfc\x83\x88\x91\x29\xfa\x3f\x9a\x8e\x90\x1a\xcf\xe2\x46\xe6\xff\xb7\xa6\xda\x01\x67\x01\x4e\x42\x34\x94\x91\x12\x65\x88\x30\x23\x57\x97\x07\x78\x42\x05\x63\x91\xd7\x7d\x76\x00\xed\x79\xbe\x63\x81\xc5\x25\xe5\x14\x48\xd7\x57\x47\x96\xf6\xbc\x38\x26\xfd\x26\x30\x6b\x78\xbf\xdc\x81\xe8\x95\x96\xf3\xbb\xfe\x76\xa7\x3d\xdf\x43\x2b\xf1\x71\xf9\xf3\xe9\x71\xd9\xfd\x35\x35\xd2\x15\xf2\xfe\xcc\x8a\x7e\x02\x44\x7b\x46\xb9\x54\xe3\x46\x14\xaa\x39\x89\x6a\x2c\x93\x39\xdc\x9c\x34\x0b\x25\x82\xcf\x3b\x4c\xb1\x95\x27\x7b\x2e\xb2\x66\x30\x46\x57\x18\x82\xe4\x9f\xed\x14\x9a\x89\x40\x47\xce\x5c\xac\x44\x03\x2f\xe7\xd9\x84\x6c\x11\xd3\x4c\x0b\x34\xf4\x91\x86\x06\xa4\xfb\x4d\xdc\x8b\x31\x95\x0b\x28\x7b\x3f\xf0\x2d\x5d\x0f\x45\x58\x1a\xd1\x1a\x84\x48\xae\x35\xbd\x13\x6b\x9f\x19\x70\xd4\xeb\x15\x08\xbd\x2b\x8b\xfc\xbc\x7b\xed\xb4\xc6\x98\x0e\x42\x83\xd1\xd3\xe7\xc7\xe5\xaf\xdd\xdf\x04\xc3\x8a\x02\x4c\x73\x0d\x3e\x50\x20\xfc\xd4\xce\xa9\x0e\x7c\xb3\xc8\xb1\x6a\x7a\x54\x6f\xa1\x43\x2d\x9c\x48\xc9\xc3\x99\xcc\xe6\x69\xfb\x51\x87\xc0\x30\xcc\x3e\xcf\x9a\xe6\x5d\x34\xcd\x44\x7a\x5b\x87\x26\xc6\xd2\xcb\x21\x76\x0c\x31\xc3\xd3\x7b\x8b\x8e\x23\x91\x12\xeb\x6e\x55\xf7\xc4\x4f\x98\x4e\x3c\x0f\x35\x61\xb1\x74\xfd\x5b\xf9\x89\x59\xac\x93\x38\xd4\x96\x46\x6d\xd3\x54\x93\x61\x3e\x9d\x48\x15\xda\x72\xf5\x3e\xb6\x87\x8c\xbf\xe1\xe2\xd2\xa9\x52\x88\xab\x31\x65\xf5\x02\x77\x0d\x1c\xae\x0e\x22\xdb\x51\xc4\xa1\x6f\x81\x52\xff\x16\xba\x37\x43\x47\x37\x14\x31\x29\x2b\x97\x18\x34\x1c\x1f\x30\x5a\xb2\x24\x0e\x2d\x9d\xed\xfc\x74\xc6\x5c\xf0\x27\x3f\x55\x46\x0c\x48\x7a\xfc\xdb\xc3\x76\x34\xf0\x32\x06\x04\xed\xad\xbf\x3d\x76\x77\x4e\x14\x26\x2e\x89\x79\xfe\x9a\x7f\x6a\x74\x03\x19\xe2\x39\x72\x57\xdb\x0c\x6c\xf7\x77\x19\x31\x27\xb4\x0a\x1f\xf8\x35\x86\xd0\x35\x2d\x21\xc4\x84\xf8\x77\xd0\x7d\x02\x31\xad\x3c\xae\x2e\x91\xba\x95\x68\xa0\x68\xba\xd2\x8f\x31\x6b\x88\x56\x26\xc0\x05\x8f\x46\xee\xf3\xfa\x6e\xfa\x53\x02\x67\xee\x34\x45\xd9\x81\x8b\x66\xce\xf0\x6e\x10\x10\x2e\xcb\x64\x95\x13\xed\xd9\x96\x8b\x7d\x96\x4f\x68\x7a\xb5\xbd\x09\xf2\xf8\xe7\x09\xa0\x50\xfb\xe7\xcd\x7c\xb0\x9c\x40\x2b\x2c\xe9\x46\xce\x8b\x5e\x85\xa4\x06\xa3\x31\x26\x4c\xfc\xba\xff\x2e\xe5\xfc\x4c\xf1\xa0\xcf\x50\xbb\xc3\xc7\x9a\x88\xd4\xfa\xf0\x03\xed\x8e\xb9\x38\xef\xfe\x3c\x65\x7f\x4d\x1d\x7c\xda\x80\xc6\xc0\xfa\x5b\x06\xef\x9d\x2a\xf3\xa5\x8e\x13\x3c\x19\x22\x4e\xec\x16\x0a\xa8\xa4\xd8\xf7\x5a\x54\xe0\xc5\x6e\x9f\x3b\x69\x28\x9a\x7e\xfa\x00\x18\x27\x0c\xa5\x65\x4b\xbe\x85\x83\xc8\x07\x29\x6e\x60\x01\x0f\xa9\x0c\xf8\xed\x04\x39\x95\x44\xd7\x5d\x63\xe2\x63\x22\x40\x8a\x46\xed\x9d\x7f\x7c\x5b\x95\x87\x07\x51\x9c\xb7\x65\xfb\xbf\x3d\xeb\xe5\x53\x3b\x06\xfc\x40\xa2\x8c\xcc\xa9\xc8\x9a\x0d\xe4\x48\x22\x38\xfc\x4a\xe0\x8b\x48\x5e\x2c\x66\x44\xbc\x3a\xad\x64\xf7\x36\xa1\x97\xa0\xef\x75\xb3\xfc\xb1\xe8\x87\x46\x87\x37\x8a\x38\xa5\x89\x7e\x0c\x72\x17\x10\x19\xd2\x6b\xdc\x8b\x7a\x03\xaa\x1a\x67\x97\x20\x16\x31\xda\x1e\xcb\xf5\x82\x73\x7f\xd3\x88\x42\x8b\x4a\x4f\xd8\x2a\xc3\x94\xca\xe8\xe1\xb1\x22\xe5\xe2\xdb\xf9\xda\x01\xe8\x21\x49\x02\xfc\x78\xed\xc7\xc5\x14\x04\xf1\xe1\xb9\x5c\xf1\xf4\x11\x09\x89\x4c\x31\x22\x90\xd5\xdb\x3d\x54\x30\x43\x0c\xd7\xac\x59\x94\x65\xa5\xb3\x02\x8d\xec\x89\xfc\x3c\x24\x5a\x84\xdc\xed\x38\x70\x1d\x12\xfc\x32\xc8\x0d\x89\x01\xb4\x75\x70\x19\x51\xe5\xc3\x3d\x96\x46\x75\x6c\x83\x9f\x65\x73\x87\x2f\x9f\x7a\x11\x84\x8e\x9e\x18\x2a\x95\xd5\x23\x59\x66\x06\x22\x64\x08\x0f\x9e\x8b\x1a\x06\x4c\xce\x6d\x53\x8a\x78\xf7\xac\xbe\x40\x3f\x29\xee\x32\xab\xeb\xec\xa5\xe8\x22\x5a\x20\x99\x08\x6c\x6c\xe0\x39\x2b\x1a\x62\xfa\x19\x6f\xd5\x9f\x66\xa0\x2f\x07\x25\x48\x1e\x48\x9b\x55\x2a\x4f\x85\x82\x95\xb8\xd2\x24\x66\x20\xa5\x87\xf2\x84\xbf\xae\xbf\x2f\x26\x42\xf3\xd7\xb6\x23\x48\x48\x91\x40\x6e\xa3\x44\xa5\x00\x59\x82\xfa\x6b\x4f\x69\xa6\xfa\x49\x02\x8c\x6b\x3c\x17\xd5\x98\xda\x71\xf8\x1a\xad\xe1\x79\xa9\x76\x7c\xc8\x7a\xe2\x7b\x44\x41\x72\x55\xc9\x08\xca\x90\x16\x6c\xaf\x0c\xe1\xdf\x65\x56\xd8\x47\x0c\xd4\x1d\xc6\xc4\x40\xa0\xb9\x62\xdc\xaa\xae\x75\xd5\xb7\xee\x17\x68\x6d\xbc\x0e\xc4\x77\x67\xec\xde\x95\x9f\xad\x24\xf6\xf0\x2d\x20\xf5\x90\x73\x58\x61\x02\x68\x7a\x06\x82\x64\x36\x3e\xee\x08\x93\xa8\xb0\xf8\x9a\x2f\xb3\x7f\x3d\x1b\xf1\x0a\x80\xf1\x49\xf3\x10\x71\x3d\x6c\x50\x14\x0f\x26\x92\x18\x70\x3e\x15\x2a\xab\x28\xcd\xae\x69\x7a\x0d\xb6\x4e\x93\x84\x98\x27\xfa\xac\x18\xec\x93\x1d\xc0\xa4\x14\x57\x5c\x55\xd0\x94\x55\x26\xdc\xac\x36\x2c\x91\x68\x7b\x90\x0c\x86\xa8\xf2\xf3\x5d\xa1\xca\x03\xc8\x49\x49\x79\x66\x98\x0e\x50\x99\xba\x7b\x3e\x1a\xa1\x9d\x4f\x64\x18\x10\x12\xe7\x90\x15\xed\xb9\x9d\x15\x2f\xdf\x4a\x91\xaf\x6d\x0c\xc8\x75\x32\xbe\x5b\x88\x2b\x71\x06\x1b\x5a\x1a\x93\x96\x0c\x1f\xcc\x15\x38\x12\xb4\xd9\x57\x82\x4e\xcc\xf8\x2c\xc6\x40\xfa\xf6\x2f\xd0\xe2\xb5\xe3\x6f\x34\x7e\x94\xe2\x18\x58\xa4\x0d\x82\x6c\x07\x09\xd5\xd1\x7d\x82\x38\xf5\x45\x57\xf4\xdc\xce\xa0\xbb\xc3\xb1\xfd\x21\xed\x9c\xfe\x51\x36\x50\xb7\xdf\xa7\xac\x7a\x15\xcc\x26\x48\x80\x32\x85\xf6\x82\x2e\xc5\x6a\x02\x21\x53\x5b\xff\x46\xc7\x94\xad\x3d\xb8\x94\xcd\x8f\x32\x2a\x26\x30\x0a\x93\xce\x59\x7d\xd3\xe3\x31\x19\x0d\x4b\xc8\x52\x8c\x77\xe8\x12\x27\xb7\xe3\xe0\x19\x75\x4a\x21\x61\x16\xc5\xe7\x42\x1d\xb6\x29\x0a\x48\xef\x8f\x20\x8a\x73\x31\x14\x23\x64\x26\x0a\x43\x3c\xc9\x8f\x14\xb9\x20\xfb\x75\xd6\x5d\x0d\x31\x1d\x2c\x59\xa1\xb7\x7b\x58\x9c\x2a\xb4\xc6\xdc\x21\x63\x62\x2f\x20\x59\x02\x34\x07\xcb\xac\x40\xd8\xf1\x57\x7c\x25\xc3\xa7\xc7\x31\x47\x54\xb0\xdb\x8a\x36\xe7\x42\x67\xca\x95\xe5\x75\x3f\x22\x11\x94\x3a\xf9\xe1\x52\x27\x1d\x0a\xd0\xa4\xa9\x8c\x5c\xa6\xb8\xd3\xd0\x59\x94\x65\x9e\x15\x2f\x04\xaa\x1d\xfd\xe0\x34\x05\x6e\x5c\xa2\xa0\xee\x08\x51\xbf\xaa\x48\x31\x22\x48\xe2\x4e\x05\x09\x8f\x44\x3a\xa5\xbe\xc1\x27\xe6\x80\x11\x1a\x5c\xba\x97\x74\x9e\x47\x5f\x4c\x86\x21\x6e\xd1\x87\x07\xf1\x31\x3b\x1e\x31\xfb\xe2\x9a\x24\x39\x29\xe6\xa2\x8e\x67\x5b\x94\xa4\x48\xb7\x3c\x9d\x1d\x79\xdb\xf0\xae\xda\x27\xeb\x78\x23\x0c\xb8\x08\x5e\xbd\x5d\x2f\x7f\x43\x4b\xdd\xd0\x7a\x75\x77\x03\x4f\xf0\xc0\x4a\x84\x54\xe7\x1a\x41\xca\x87\x89\xa2\x81\xa9\x88\x86\x01\x20\xac\x06\xd5\xdb\x3a\x3c\x87\x6d\x34\x01\x47\xff\x63\xd7\x01\x8a\x9e\x8b\xbc\x27\xf8\xfc\x8f\xc2\x70\x89\xbb\x99\x54\x18\x59\xaf\x30\xae\xd6\x85\xa8\xb9\xe7\xc5\x46\x3b\x29\xa1\xb5\xf8\x6b\x56\x3b\x61\xce\xc1\x07\xe7\x1e\xd7\xa4\x96\xe5\xd2\x74\x57\x5a\xd3\xdc\xf3\x41\x60\x92\xf2\xd0\x3f\xd5\x56\x14\x11\xb6\x5d\x02\x13\x6b\x0b\x53\xca\xcb\xf3\x43\x56\x40\x55\x6f\x1d\xbe\xba\xb7\xa9\xd1\x7f\xfe\xf7\x8f\xeb\xff\x63\x6f\x14\x26\x31\x3a\x8e\x48\x8b\xb1\x8b\x76\xab\xf5\x72\x33\xbb\x5f\xee\x50\x00\xdd\x3d\x2d\x84\x50\x50\x25\xc2\xa9\x46\x2f\x3b\x2b\x5e\x2e\x8e\x2c\xf7\x22\x9f\x21\x7e\xb9\xfd\xdb\x7d\xa9\x5e\x37\x13\x16\xdd\xbf\x86\xc3\x10\xb3\x40\x6a\xab\x55\x86\x0a\xd3\xbd\xa1\x8c\x99\x88\x91\xd4\x35\x6f\xd6\xd0\x88\xac\xb3\x75\xb8\x17\xeb\x08\xe3\x0d\x54\x33\x53\x56\xff\x3e\x55\x59\xad\x6d\xfa\xd2\x75\x4a\x19\xf3\x2d\x5a\x9e\x52\xfd\x2e\x73\x3f\xcd\x47\x33\x91\x70\x69\xef\x61\x49\xc9\x44\xde\x4c\x21\x16\x5c\xb7\x90\x88\x8c\xf2\xac\xd0\xe7\x3d\xd1\x2c\x76\xaf\x11\x53\xfd\x6c\x6b\xf2\x5a\xb7\x64\x34\x17\x52\x63\x90\x7d\x28\xab\x27\x66\x81\x48\x7c\xa4\x54\x69\xc6\x9c\x60\x6d\x93\x50\x09\xa2\xb1\x8a\x72\x75\xae\xc4\x21\xd3\x97\x26\x89\xef\x7d\xd3\x9e\x58\x97\x0b\x84\x47\x24\xbd\x50\xbd\x65\x0a\xb6\x95\xc0\x1c\x5f\x89\xc2\x31\x53\xa9\xc1\xf6\x12\x2d\x49\xa2\xe9\x03\x54\x47\x52\xca\x3d\x01\x41\xe0\x10\x66\xed\xd6\x48\xb4\x6f\xb3\x42\xff\xbc\x5f\x7e\x5c\x51\x45\x8f\x6e\x2a\x43\xa2\x82\x23\xe6\xb0\x3c\xfb\xcb\x15\x23\xde\x96\xe3\x9f\x2f\x13\x86\x99\x88\x23\xc0\x2b\x56\x66\xb8\xbf\xa7\x29\xb2\xaa\x80\xaa\x4f\x72\x08\x70\xff\xff\x09\xa3\x73\x4f\xa5\x14\xf2\x2d\xe0\x7d\x56\x21\x4a\xe8\xca\xa7\xfd\xaa\x22\xd9\xde\x45\x7b\x12\x6b\x66\x8b\x52\x96\xfa\xbc\x10\xc5\x4d\xb9\xdd\x67\xb5\x7b\x5b\xcd\x7d\x2c\x05\x5d\x3d\x3d\xdd\xef\x96\x37\x77\xdb\x1d\xeb\x9a\x82\x4e\xd1\xc3\xed\x47\x13\x52\xb0\x6d\x3f\x89\x26\xd0\x62\xfd\xfb\x6a\x3b\x7b\xee\x2e\xd7\xcc\x95\xd6\xb6\xfe\xd4\x2f\x83\xd9\xab\xb5\xc0\xc2\x1d\x28\x54\xa9\xe1\xd7\xdf\x17\xb7\xb9\x78\xb9\x48\x31\x70\x0f\xda\xa3\x7c\x5c\x0d\xd6\xbd\x35\xc4\x20\x22\xd7\x4a\x2f\xb5\x16\x75\x76\x59\x86\x60\x88\xef\x89\xf4\x0c\x2e\x90\x01\xce\x3c\xa1\x31\xd6\x5b\xc0\xfb\xfc\x54\x61\xea\xfd\xe9\x08\xc5\x28\x57\x3a\x1c\x44\xc6\x98\xef\xa7\x03\x65\xc2\xfb\x52\x39\xfe\x19\xce\x58\x42\x2f\x7b\x10\xc5\x49\xe4\xf7\x0b\xf7\x9e\x8c\x47\x0c\x23\x7b\xed\x4c\xcc\x69\x0d\xd9\x96\xc0\x0f\x31\xd9\xf0\x5e\x65\x0d\xec\xde\xf7\xa2\xd9\xbd\xb7\x1e\xe4\xee\x45\xe8\x97\x6b\x8f\xd0\x5d\xa5\x43\xde\x97\x8e\x6e\xf7\xa4\xc9\x75\xcf\x42\xce\x24\xeb\xb1\xf9\xb6\xbf\xf1\x52\x8d\xc0\x59\x18\x40\xaa\x1c\xeb\xd2\x80\x2c\x8b\xb3\x30\x55\x8e\x79\xfb\x41\x7c\xdc\x40\x2e\xce\x17\x01\x6c\xce\x42\xe1\xa7\x36\x5c\x49\x05\x53\x84\x03\x7d\x3c\x1d\x6c\xd1\xa5\x4d\xa0\xba\xee\x9a\xb2\x1c\x8e\x04\xa5\xd3\x62\xb3\xed\x51\x48\xb0\x89\x1a\x9a\xdb\x53\xb1\x69\x06\x98\x3f\xce\x62\x2f\xf6\xa3\x8e\x68\x6e\x14\x70\x72\x7d\x58\xa8\x6c\x0c\x68\x5e\x56\x55\xf9\xde\x35\xf8\x0a\x8f\xdd\xa3\xd5\xf1\xb0\xda\xe5\xbf\xf4\x8b\x83\x6d\xd7\xd4\x0f\x70\x4f\xbf\x79\xde\x6c\x77\xf7\x77\x0f\x77\x5b\x77\x13\x11\xc6\xe8\x03\xd7\x0d\x88\xbc\x83\x8b\x73\x26\x20\x0d\x50\x6e\x6c\x2f\xde\x07\xb4\x08\xf5\xa5\x87\x74\x94\x38\x4b\x9d\x35\xa0\x31\x41\x30\x5c\x3e\x4c\x80\xc6\xb9\xbc\x81\x66\x77\x2e\x4f\xd5\xee\x45\x1c\x60\x57\x50\x65\xd3\x60\x28\x24\xf7\xd3\xf6\x4c\x7d\xce\x9b\xac\xdd\xc7\x2f\xc7\x2d\x93\x9c\xa4\xf6\x85\xd6\xd7\x3b\x35\x53\x9e\xc6\x8f\x7d\x2a\x5c\xda\x70\x2c\x63\xc3\x99\x8e\x39\x58\xd5\x42\x5a\x0a\xb7\x65\xf5\x3a\x4a\x53\x73\xa6\x25\x95\x76\xe4\x60\x9a\xbb\xc5\x53\xdf\xec\xe4\x0c\xb8\x56\x4e\x02\x88\x92\x53\x53\xfb\x05\x83\x90\x83\x6f\x65\x13\x76\x2f\x65\xae\x77\x87\xac\x10\x3d\x0c\x02\x67\xa0\x63\xdc\x52\x6c\x9d\x6e\x7d\xd7\x6d\xc7\x6e\x85\x23\x79\xaf\xec\x11\x8e\xf5\x5c\x76\xce\xbd\xd8\x4b\xec\x0c\x6e\xdd\x1a\x24\x68\x6a\x57\xc0\xf4\xb2\x6a\xd7\x37\x66\x61\x37\xa6\x3c\x94\x93\x19\xa7\xfe\x77\xe0\x3c\x02\x8f\x3b\x9a\xab\x8f\x65\xb3\x1f\x0e\x12\xf7\x43\xfa\xa2\x87\xac\xc8\x0e\xa7\x43\x5f\x53\x85\x73\x5f\x90\xe4\xd1\x6c\xbe\xe8\x45\xbe\xda\xbf\x6b\x84\x10\x3f\xc2\x3b\x29\x74\xe1\x6c\x1a\x92\x36\x93\xa1\x97\xd8\x2b\x02\xc3\x11\x9a\xf7\xfd\xaf\x8f\xbd\x9a\x44\x2d\xda\x8e\x11\x03\x3c\x02\x28\x44\x3a\x51\x7c\xcb\x79\xc4\x03\x4d\x24\x4a\x75\x53\x95\x67\x35\xa2\x72\xe8\x7a\xc5\x8e\x77\x7c\xcc\x69\xce\x79\xe4\x0b\x37\xd9\x49\xd0\xa6\x03\xd5\x0d\x6f\x12\x87\x5c\x9a\xcb\x2c\xc9\x44\x6e\xc5\x9b\xf3\xf2\x9a\x05\x71\xf4\xa1\xe2\x14\x92\x0b\x02\x0a\xcb\x37\x88\x8c\x86\x86\x6c\x9a\xf7\x89\xf3\x84\x79\x78\x92\x22\xa1\x55\xbf\x8a\x72\x58\x73\xe0\x7a\x87\x12\x21\xb2\x3b\x28\xea\x53\xd5\xde\x7a\xf4\x0b\x92\x58\x46\xd1\x90\x6b\x67\x05\x55\xdd\x8b\x65\x4d\x9d\xc4\x3c\x49\x63\x8c\x15\xa2\xc2\xb8\x5b\x34\x3c\x8d\x18\xd1\x9e\xda\x7a\x17\x72\x0d\x9e\x4c\x57\x10\x7b\xb9\x41\xaa\xfc\xd0\xa6\x94\xee\x1a\x38\x0c\x2a\x9d\x47\xcf\x92\x9e\x87\x91\x32\x2d\x1a\x01\x45\x53\x9d\x55\x0e\xd5\xab\x7b\xa6\x64\x2a\xf6\xba\xaa\xc3\x77\xc8\x26\xaa\x0e\x39\x97\x01\xf7\x9d\x62\xda\x1e\x44\x63\x59\x13\xbb\x9b\xc4\x94\x54\xdf\x59\x55\xe6\x49\x87\x9c\x73\xc5\x53\x61\xb3\x05\x0e\x9b\x37\xea\xe0\x53\x8d\x83\x2d\x8a\xb7\x7a\x9b\x5f\x9a\x69\x5c\x49\x19\x24\xd6\x97\x29\xeb\xc1\x3a\xd2\xbe\x8f\x79\xd4\xe6\x8a\x06\xad\x6d\x8b\x91\x0e\xf9\x90\x51\xbe\x9d\xf2\x10\x5f\xe4\x07\x38\xd7\x81\xc2\x0c\x65\xa7\xd4\x3a\x19\x21\x19\x5f\x24\x24\xa6\xe0\x9c\x09\x4a\x3a\x73\xd3\xe3\x03\xbe\x8f\xd2\x60\x87\xec\x85\x40\x0b\x8f\xf0\x3e\x15\x6a\xe2\x1c\x12\x8e\xb0\xca\x65\xb3\xdf\x96\x48\x73\xe6\x4c\x35\x6e\x98\x87\x51\x2b\xa1\x35\xa9\x5a\xf5\x19\x31\xa6\xdf\xd1\xf8\x02\xe9\x86\x0b\xa8\x1b\x44\x72\xd6\xcd\xac\x38\x6f\xcb\x4d\x8f\x35\x61\x7c\x89\x92\xe8\xd3\x3d\x2c\x36\xee\x70\xf4\x3d\x29\x11\x5b\x27\x5b\xb3\x85\xa2\xd0\xae\x89\xc5\x12\x8b\xeb\x4d\x9e\x1d\x69\x7d\x6e\xde\xb3\x46\xed\xb7\x65\xcf\xd0\xf3\x59\x02\x08\xc1\x3e\x0e\x6b\x1c\x86\x8f\xf6\x99\xe0\x6e\xe7\x69\x8d\x49\xe2\x3e\x76\x6d\xc0\x75\xdc\xa3\xab\x23\x4e\xed\x01\x59\x56\xd7\x93\x32\x74\x42\xeb\xbb\x62\x8e\x25\x2e\xab\xaa\x7c\xa9\xc4\x61\x5c\x72\xc7\x7d\xee\xc5\x48\x3e\x2f\xf2\x81\x22\x0a\xf7\x79\xc8\x51\x63\x43\x9e\x6a\x25\xaa\x9b\x52\x21\x76\xbb\x5c\x95\xd5\x36\x6b\x4e\x79\x39\x40\x3b\x72\x9f\x0b\x1f\xab\xdf\x7e\x5b\xb8\x1b\x04\x5e\x10\x92\x8b\x58\x77\x19\x96\xc4\xb5\x45\x2a\xec\xc4\x38\xee\x86\x55\x79\xdc\x0f\x53\xae\xba\x64\xd5\xd6\x85\x40\xb8\x1f\x82\x8f\x36\xd2\x1c\x9a\x1b\xeb\x77\x9e\x2f\x6d\x24\x13\xef\xd8\x5d\x93\xa9\x23\xcd\x8f\x62\x1f\x4f\x1f\xa2\x0f\x7a\x2f\x7f\x74\xd4\x41\xdc\xdd\x28\x92\x3e\xa3\x23\x42\xe4\x57\xa5\xbb\x9f\x48\x81\x0d\x9f\xa1\x05\xd5\xab\x3c\x6e\xd7\xcb\xd5\xdd\xcd\xce\x16\x8b\x3d\x2e\xd6\xcb\x87\xe5\x63\x37\xa5\x12\x4e\x85\xe0\x15\xd0\xef\xdc\xc3\x7f\x4e\xd0\xd9\x93\x7e\x22\x13\xdc\x46\x6f\x1e\xfa\x19\x42\xee\xa7\x41\x82\x9e\x8c\x53\xf5\x70\xdc\xfa\x53\x7b\x9b\x9f\xa6\x9c\xdb\x1d\xd0\xd1\x17\x61\x58\x7f\x7e\xbe\xd3\xe3\xc0\xab\xbd\x44\xc4\x24\x5f\xa7\xe1\x0d\xf2\xf2\x08\x95\x81\xee\x9d\x44\x1a\x21\x0f\xe0\xae\x86\x66\xbd\x59\x6d\x54\x06\x85\x82\xc9\x65\xec\x4b\x46\xd6\xb5\x14\x4d\x93\x8f\x78\xae\xb9\xaf\x7c\x11\x90\xfa\x69\x55\x8c\x38\x2c\x27\x37\x28\x5f\x05\x49\x28\x2e\xf5\x60\x63\x7e\x41\xee\xeb\x00\xcc\x05\x2c\x6e\x15\xbc\xdd\xe3\xb4\x48\x70\x76\x3c\x17\xd9\xc7\xae\x83\xd4\xee\xe6\x59\x21\xaa\xf3\x6e\x5b\x09\xdd\x0b\x4e\xba\x6b\x94\xe1\xa9\x25\x01\x45\x39\x17\xe8\x0b\x0d\x73\x1f\x18\x4f\x2d\x0b\xe8\x4d\xf9\x58\x36\x33\xe4\xf2\x42\x93\x66\xb0\xf2\x21\x06\x0c\x4d\xec\x74\x56\x1f\x45\xa3\xf6\xc3\x92\x5d\xee\x1b\x4f\x46\x44\x52\x77\xcc\x85\x82\x87\x52\x9f\x46\xa1\x5c\xee\x9b\x88\x0a\x3e\x6a\x61\xe0\x4b\x5a\x32\xee\x1b\xc9\x90\x7e\xa0\x4b\xc3\x7f\x96\x36\xbc\xde\x7e\x8c\x22\xde\x98\xdd\xb1\x3d\xec\xed\xfb\x05\x1e\x57\x5c\xd9\x5a\x2a\xf7\x6c\xa4\xe3\xa6\x19\xc4\xbd\x4b\xb6\xd5\x5d\x21\x52\xac\x54\xbe\x5b\x3c\xed\xb6\x77\xf7\xf7\xee\x4e\x2c\xa5\x05\xdc\xfe\x1d\x03\x5b\xbd\xe2\x4a\x1e\xf0\x58\x9a\xe4\xa2\xd3\x67\x33\x0c\xf9\x27\xc8\x79\x1e\xf8\x4a\xe2\xdd\x8e\xe2\xbc\x28\x8b\x37\xaa\x7c\xc7\xd2\x96\x09\x93\x72\x72\xac\x82\x00\x08\x4e\x45\xd4\x14\x0d\x54\x73\x8a\x50\x21\x6c\x6e\xf8\xb4\x30\xf4\x12\x27\x0e\xde\x6e\xcb\x0f\xe2\x83\x68\x19\x9e\xcc\x7c\x8c\xc4\xe7\x41\xbb\x85\x89\x7e\xed\xe4\xcd\x05\x92\xef\xb4\x9a\xed\x3c\x98\x3e\x0a\x82\x30\x4d\x15\x25\x3e\x00\xeb\xeb\xf1\x2b\xde\x83\x69\xc6\xef\x65\xa3\xbf\x56\x91\xc5\x0d\x66\xa8\x83\xc4\x5a\x35\x7d\x2d\x2e\x1e\x84\x86\xe4\xd1\x49\x6d\xc4\xb8\xed\xe0\x0a\x8c\xc4\x83\x28\x14\x0e\xef\x87\x0f\x7f\x2e\xb2\xb1\x55\x13\x44\x29\x20\x71\xf3\xce\x41\xbf\xae\x20\x5f\x3c\x88\x84\xe6\x41\x7f\x2c\x1e\xb2\x02\x34\x9e\xec\xb7\x65\xb5\xfd\xed\x93\x01\x88\x0d\x85\x0e\x6e\xca\x75\x27\xe2\xcb\x83\xc4\x4b\x7c\x49\x40\xa7\xaa\x1c\x46\x6d\x47\xd7\x27\xc2\x80\xcd\xbc\xe0\x52\xe8\x06\xb1\xa6\xc9\xfb\x19\x40\x80\x07\x69\x1c\x99\x0b\xf8\xb4\x3a\xaf\x41\xe8\x49\xa4\x12\x0f\xd2\xc4\x1e\x28\x76\x5d\x20\x7b\x2a\x89\x60\x6c\xcb\x91\x42\xc8\xe8\xfd\x44\x92\xa6\x96\xae\x13\x54\xe3\x32\x24\xa4\xf3\x6f\x75\x9e\x93\xae\xab\xf2\xc8\x78\xb6\x40\xe1\xb2\x5a\x83\x2a\x8b\xa1\x37\xf4\x05\xd7\xf8\x88\xfb\x96\x07\x42\x78\x98\x8a\xdb\x34\xa5\x7a\x1d\x40\xba\x78\x20\x13\x8e\x49\x8a\xc5\x5e\x54\x88\x25\x44\x92\xef\xda\x52\x44\xb9\x4e\x8a\x23\x88\xa2\x80\x77\x2c\xff\x98\x38\x6d\x03\x1d\x49\x0c\xce\xd0\x51\x35\x3b\x66\x9f\x2c\x64\xad\x49\x26\x0a\x25\xd0\x9c\xac\xe3\x2e\xb3\x68\xd9\xdd\xc0\x67\x0e\x20\xa0\x8a\x39\x32\xea\x37\x18\x2e\x11\xd5\x79\xea\xf8\x0b\x20\x0d\x70\xae\xff\x28\x1b\xf8\x7e\x92\xa3\xb9\x0b\xc2\x27\xc1\x4c\xdc\xb4\x77\xf6\x64\xa9\x07\xb6\x48\x00\x22\xc1\x1a\xa4\xda\x05\x63\xf0\xe4\xe8\x12\x7c\x3c\x00\x49\x55\xd2\x08\xba\xed\x60\x22\xa3\x47\x99\x34\x0d\x30\x9d\x46\x7a\x19\x77\xaa\xa4\x6a\x42\xd7\x2c\x52\x24\x29\x59\x55\x59\x7d\x10\xea\x12\xbb\x0e\x0c\x68\x3c\x27\x97\xf3\xd5\x00\x04\xf2\x77\xd9\x7e\x1e\x18\x43\xb5\x7b\x96\xf5\xb3\x2c\x9a\xf6\xf8\xed\x77\x09\x59\x10\x60\xe5\x0b\xe6\x22\xef\xb3\x7a\xa0\x0d\x36\x18\xc9\x90\x45\x86\x69\x37\x0c\xb6\xde\x76\x7e\xf6\x3a\x76\x0d\x1e\xb2\x24\x75\x8a\x07\xb7\xa2\xde\x8f\x35\x98\x78\xc8\x44\x2c\x02\x87\xf6\x7e\xcc\xf6\x59\xee\xd0\xab\x3c\x64\xa0\x10\x22\x5f\x3c\xd4\x2f\xee\x6f\x3c\x02\x44\x0b\xd9\xfa\xf5\x01\x4b\xa1\xed\x12\xf8\x5c\x76\xd1\xd3\x7a\x35\xcd\xc3\xcd\xc3\x20\x4c\x10\xff\xbe\x17\x75\x3b\x13\xa6\xf5\x4a\x79\x18\xc4\x1e\x0a\x54\x10\x5f\xd5\xe2\x7e\x76\xf7\xb0\xfb\x39\xbb\xdb\xee\x56\xcb\xf5\xdd\xd3\x8d\x7b\xaf\x40\x32\x44\xd9\xb9\x18\xd3\x2f\x23\x00\xfd\xd8\x8e\x19\xbe\x4b\x18\xf8\x98\x6a\xa0\x90\xe2\xcd\xe9\x70\x38\xaf\x72\x71\xee\xdd\xe6\x34\x45\x51\xe5\xae\x86\x04\x79\xcc\x2c\x85\xfe\xc8\xaa\x0a\xa3\x90\x84\x8f\x6a\x68\x1e\xe1\x54\x95\xa8\xa4\xe3\xc6\x64\xf0\xe9\xa3\xd4\xa0\x3b\x96\xd3\x7e\xb5\xaa\x70\xb5\x75\xf7\xd1\x12\x7c\x57\x05\x47\x14\xff\xc3\xa1\x8a\x8c\x40\x6b\xac\xc9\x0e\xb0\x2d\xe7\x65\x55\xfc\x72\x69\xc1\x13\x15\x6c\x2c\xfb\x0b\x82\x72\x1e\xc6\x3e\x01\x94\xa8\xba\xc0\x6e\x97\x93\xf4\x7a\xe3\x0b\xe3\xd4\xbf\x70\xf0\xac\xda\x95\x31\x7d\x8a\x84\xb1\xf6\x71\x5a\xda\xcc\x7c\xbb\x57\x61\xa6\xb6\x4f\xa9\xc4\xc3\x24\x94\xbe\x13\x38\x2f\x46\x0c\xba\x3c\x4c\xe2\x38\xbd\x24\xf9\xa8\xe6\xad\x1b\xfa\x2f\x92\x12\x61\xa2\x28\x09\xf4\x9c\xb7\x7d\x2f\xd1\xf9\x30\xd1\x31\x8a\x3e\xd8\xdc\xeb\x0e\x99\x2d\x5c\x63\x1a\x44\x6e\xf4\x17\x4e\x8b\xa0\x5f\xfa\xe0\xba\xc5\x1e\x73\xe5\x07\xa5\xca\x44\x6e\xc7\x6f\xf5\x3e\x7d\x56\x85\xa9\x0c\x91\xc4\x83\x32\xcf\xb6\x76\xe0\x53\xb0\xe6\x67\x20\xad\xff\xfe\xf1\x45\x5e\x96\x87\x42\x0b\x20\x61\x72\xdc\xe1\x06\x45\x7f\x3c\xd4\x41\x8a\xe4\x77\xc8\xcc\x30\x88\xc6\x87\x3a\x24\xfe\x5e\x52\x7c\x19\x93\xac\xda\x4e\xe0\x69\x0c\xa2\xcf\x45\x9d\xa9\x4f\x77\xc2\xb1\x4b\x16\x9a\x38\x21\xea\x4d\x61\x41\xef\x96\x00\x8d\x9a\x23\x4f\xc5\x0e\x9f\x53\x35\xbb\xae\x3e\x9e\x47\x2c\xd2\x98\xe3\x7a\xc1\x3a\xa5\x91\x68\x28\x8f\x58\x22\x91\x7f\x50\x9e\xce\x68\x12\xfe\x0a\x43\x2a\x09\x1e\x71\x8f\xa1\xd9\x7e\x21\x11\x7f\x63\xa9\xbb\x9c\xfb\x3e\xa9\x0f\x34\xe2\x15\x9e\x46\xd1\xb7\xc8\x8f\x42\x61\x59\x2a\x6e\xcb\x4a\xc1\x93\x31\x35\x34\xc3\x63\x6e\x38\xdd\x22\x3f\x52\x58\x34\x83\x12\xfb\x77\x7a\x66\x1a\x2c\x6b\x43\x42\xa8\xc1\x54\x88\x7c\xd0\x09\x15\xd0\xd5\x8f\xf0\xd1\x89\x7b\xce\xdc\xab\x05\x32\xc0\x55\x53\xf6\xe8\x07\x6c\x53\x94\x78\x98\xeb\x51\x86\x91\x45\xc0\x57\xaa\xd7\x18\xfb\x4e\xad\x2b\x53\xd7\x1c\x85\x3c\x8a\x52\x42\x38\xa0\x10\x0f\xe8\x9e\x1b\x3a\xec\x17\x03\x4b\xd5\x85\x03\xc1\x42\x04\x26\xcc\xd4\x28\x89\x24\x16\x03\x7c\xa3\x40\xeb\x85\xbf\x3e\x19\xdd\x32\x11\x3c\xbc\x54\x92\x77\x6a\x06\x03\x15\x7c\x1e\x25\x5a\x62\x1e\x47\x65\xcd\xa4\x55\x13\xa5\x3a\xc1\x6f\xba\x6b\x7d\xb1\x41\x86\x7d\xf8\x38\xe1\x09\x73\x51\x82\x7b\x10\xc5\xf9\x5e\x14\x1a\xc3\xb2\xa3\xcf\x37\xa4\x3c\xe4\x91\x48\x02\x62\x87\xb6\x11\xc7\x2f\xf7\xc2\x48\x88\x04\x09\x00\x09\xca\xd3\xda\x85\xd5\xb5\x37\x1b\x61\xc5\xb5\x8b\x72\x8a\xac\x78\xbc\x68\x43\xdb\x1e\x32\x66\xcc\xef\x0e\xd3\x4d\x99\xeb\xae\x86\x87\x47\x52\x45\x88\xc8\x5f\xea\xd3\x14\x11\xc0\xb5\xfd\x11\xe9\xc0\x70\xa4\x39\xfd\x38\x8a\x42\x3f\xc2\x0b\x92\x92\x30\x9e\xcc\xb3\x66\x21\xea\x91\xa9\x16\xe9\x10\xf0\x5c\x2c\x47\xfa\xc0\xf5\x68\xe6\xea\xd8\x33\xc2\xaa\x24\x38\x5b\xca\xe2\xfb\x6c\x0f\xf0\x24\xc6\x3c\xb4\x28\xb1\xf0\xd9\x22\x5c\xbb\xe6\x50\x80\x53\x39\x03\x92\xbf\x1f\x70\x32\xf0\x08\x22\x93\x5c\x58\xa8\x30\xc9\x37\x2b\xf4\x43\xf6\xe9\xba\x03\x01\xc8\x08\x67\xe5\xa4\x06\xa8\x44\x1e\x81\xa4\x2a\xc1\x53\x95\x8d\x96\xb8\x09\x43\x9f\x59\x59\x85\x3c\xa7\xba\x5f\x77\x95\x11\x41\x4a\xb0\xd3\x3b\x55\x62\xd2\xe7\xf2\x13\x0c\x04\x8c\xf5\xd3\xb4\x65\x35\x28\xa1\xe6\xb1\xa7\x83\x84\x72\xea\x1f\x0d\x41\x25\xcb\xd6\xbf\x70\xcd\x2c\x20\xff\x9c\xf2\x0b\xae\x56\x6c\xf8\x76\x31\x8b\x7c\xad\x3a\xf3\x78\x9e\xe9\xe1\x97\x88\xb9\x21\xe2\xbd\x3d\x54\xe5\xb0\x4c\xc6\x76\xf0\x23\x8f\x61\xdc\x40\x60\xa4\xae\x57\x43\xcc\x63\x5f\x52\x81\xa7\xcc\x74\xbd\xab\x91\x12\x6d\x47\x0f\xea\x7e\x66\x1c\x78\x1c\x05\xb0\x0f\xe2\xa3\x1d\xfc\x55\xe9\x70\x30\x71\xe8\x79\xbc\xe3\x50\xad\x87\xbb\x79\x1c\xfa\x10\x13\x51\xff\x5d\x3f\x15\x1c\x47\x1e\x8b\xda\x75\x52\x62\xa4\xe0\x65\x3f\x3a\x80\xe2\x28\x24\x67\xa1\xdd\x99\x44\x96\x9f\x71\x23\x79\xae\x2f\x37\x8e\x62\x0f\x99\xf6\xea\x83\xc8\xf3\x0b\x63\x2b\x8f\x23\xed\x61\xba\x86\xca\x19\x28\x0a\x6e\x9b\x62\x4e\x86\xbf\x12\x79\xbe\x2c\x34\x6e\x3a\x03\xe8\x24\x8f\x63\x19\x5a\x2f\xa9\x5f\xba\xf2\x65\x34\x2c\x8e\x21\x40\xb7\xdb\xe6\x30\xd7\xf0\x3f\x50\x57\xac\x72\xc9\xd5\x45\x09\x11\xb5\x54\xe2\x0d\x72\xd2\x8e\xff\x9a\x25\xeb\x4b\x53\x36\x6e\xcd\xa2\xc4\xc9\xd1\x80\x76\x9f\x7f\x64\x7d\xc7\x89\x31\xbe\xe5\xad\xdd\x8a\x82\x6a\x75\xea\x8b\x22\xd3\xa8\x77\xca\x7c\x63\x93\xab\x76\xe1\xde\x66\x85\x28\x5a\xfb\xa6\x87\x3e\x89\xd3\x90\x92\x36\x16\x48\x43\x9a\x33\xd7\xca\x0b\x3c\x4e\x13\x6e\x3a\x71\xd5\x76\x3a\x3c\x08\x87\x6f\x8a\x05\x37\xaa\xff\xac\xe9\xe5\x1d\x0b\x45\xc2\x2c\xf8\x81\x6e\xcb\x8a\x28\x4e\xbb\x79\x23\xc3\x14\x01\x67\xdf\xb3\x55\x05\x2a\x2b\x4f\x97\x96\x98\x23\x75\xed\xb1\x2a\x4b\x73\x2b\xb2\x09\xc8\xba\xed\xa9\x92\x10\xb9\x88\x76\x96\x62\xfb\xf5\xd4\x23\xd8\xfb\xc4\x20\x73\x97\xa6\x42\x59\xdd\x03\x4b\x22\x37\xf9\xa0\xd1\x03\x75\x48\x84\x6e\x4d\xe6\xb2\xd7\x0b\x71\x1c\x05\xb1\x62\x2d\x08\xb0\x57\x81\x06\x38\x3c\x6f\x7f\x7b\x1a\x73\xb5\x38\xce\xca\x7f\x75\x1a\x4d\xc9\x24\x8d\x0b\x8f\xc1\x23\x4e\x2e\x2c\x5a\xc9\xea\xa6\xa2\x9a\xd3\x03\xb2\x81\x4d\xcf\x2f\xf0\x7d\x3e\x34\x9e\x44\xe2\x86\x16\x40\x1a\xd5\x91\xc3\x75\xaa\x21\x4f\xa6\x1f\xc9\x88\x8d\x27\x11\x10\x5e\x75\xca\x45\xc3\x1f\x68\xc2\x08\xb5\x8f\xb0\xac\x0d\x99\xc2\x46\x7b\x82\x49\x23\x16\xf4\x38\xa2\xa0\x50\x30\xda\x06\x8d\x60\x8e\x32\x83\x34\xfc\x47\x54\x15\x3c\x36\x8a\xa3\xae\xc8\x11\xc1\xf0\xab\x1e\x35\x24\x4f\xbc\x88\xac\x29\xa1\xdb\xf5\xa3\xb3\xa6\x67\xab\x8d\xb5\x71\xff\x35\x1c\xfb\x4f\xfe\x6c\x6f\xcc\x78\x84\x05\xb2\xf2\x74\xbe\x5f\xcc\xd6\x6e\xeb\x4c\x98\x88\x10\xc3\xb3\x39\x96\x45\x5d\x56\xa0\xef\x1a\x38\x7c\x2b\xcb\x35\x8a\x5c\x75\xbd\x24\xf3\x4d\xc7\xe4\x27\xa1\x99\x9f\x1f\x4f\x07\x6b\x55\x5d\xac\xfd\x84\x49\x1f\xd1\x09\xc7\x5c\x5c\x25\xe2\x5c\x38\x2d\xf1\x23\x85\x73\x6d\x2f\xea\xaf\x0a\x31\x79\xe2\x1b\x89\x41\x29\xdd\x7a\xc5\xdf\x44\x3d\x3f\x55\x97\x23\x23\x09\x38\x50\xf5\x6a\x2f\x04\x7e\x5b\x95\x87\xaf\x13\x07\x49\x60\x8d\x62\x0a\xb8\x0c\x1f\x18\xa4\x21\x26\x88\x0f\x67\xaa\x7e\x76\x8f\x0a\x75\x10\x3b\xaa\x7e\x4b\xe9\x43\x4a\xa9\xc3\xcb\xa3\x30\x36\xb1\x93\x7d\x79\x84\xf7\x31\xa1\xff\x94\x4f\x98\x44\xa0\x7d\x47\xed\x37\x6f\xca\x9f\x59\xb3\xdf\x34\xea\x6a\xb1\x7f\x22\x73\x74\x5d\x36\x32\x21\x8b\xe4\xbe\x4e\x0c\x24\x93\x6f\x40\xed\x91\xdc\x12\x57\xd1\x64\xb0\x37\x89\x0d\xb3\xdc\xbb\xe2\xb0\xee\xcb\xfa\xf1\x24\x09\x88\x2f\xde\x08\xdd\x8d\x50\xa2\x63\x3a\xbf\xa1\x19\x7b\x2e\x49\xaa\x62\x47\x54\xbe\x81\xd6\xae\xe9\xe7\xef\xfb\x36\x62\x22\x38\x60\xa2\x8f\x76\x3d\x1c\x69\x14\x6a\x18\xbd\x9b\x48\x18\x1d\xf7\x19\x54\x1e\xfa\x61\xee\x35\x84\x51\xda\x3e\xca\xea\x44\x8f\x90\x3c\x89\x04\x1f\x67\xb2\x2d\xe0\xc0\xa2\xc2\x99\x63\x4c\x73\xb7\x51\x29\x13\x14\xc3\x73\xd1\x92\x76\x62\x7d\xdb\xde\x3d\x32\x5f\x8b\x69\x3f\x20\xd1\x41\x8c\x31\x10\x09\x8b\xb2\xa8\x9b\x0b\x64\x20\xd1\x61\xe4\x3b\x2f\xf7\xa9\xb0\xf0\xe9\xe9\xd9\xa9\x23\x82\xdf\xba\x9a\xfa\x2b\x5a\x86\x6e\x15\x01\xd7\xae\x1c\xf1\xa1\x7e\x19\x0d\x39\xf8\xa1\x2b\x87\x7f\xbe\x2b\x9a\x64\x3a\x02\x90\x40\x28\x84\x70\xf4\xd5\xab\xaa\x93\x99\xe6\x09\x48\x0f\x95\x5d\xb1\xb6\xce\xc6\xf7\xda\xa9\xd9\x97\x46\xed\x79\xfe\x97\x48\x72\x02\x32\x74\xac\x22\x84\x7e\xb7\x91\x15\xdb\x73\xf0\x6b\x0d\x4b\x3c\x75\x41\x0c\x6d\x8e\x1d\x19\x04\x4f\x4c\xc0\x10\xcf\x4a\xe1\x95\xd5\xf7\xdf\x3a\x32\x3b\xea\x90\x7a\x91\xc7\x6d\xc4\x79\x68\x61\xa7\x5e\x2a\xd2\xcb\x34\x42\x60\x59\xd7\x24\x42\x69\x6b\xfd\x8a\xd6\x46\x1a\x8e\x5b\xea\x49\x8d\xe7\x6e\x46\x11\x70\x0c\xc2\x4f\x11\xa8\xf3\xd4\xd3\x12\x4b\xd9\xe4\xa9\xc2\x1c\xd3\xac\x28\x5b\x3b\xef\xcb\x10\x7f\xea\x41\x47\x7b\x8d\xf7\x1c\x08\x8a\x4e\xad\x88\x94\x85\xa9\xd5\xdb\xae\x1b\x4c\x18\x42\x55\x77\xd3\x3d\xe5\x3e\x47\xee\x9f\x5d\x56\x3f\x9c\xef\x41\xbc\x9c\x06\x69\xf5\x94\x5b\x9a\xf4\x59\x95\x15\xfd\x83\x30\xe5\x22\x46\x7b\xf1\xff\x66\xff\xe7\x7c\xfc\xd4\xe7\x21\xc6\x52\x3a\xcb\xe8\xbe\x7c\xb7\x09\x8c\xae\x4b\x1c\xa0\x0b\xbb\x51\x65\x75\xcc\x10\x8c\x31\x1a\x96\x20\xd2\x89\x2d\x4d\xbe\xfb\xf6\xd4\x8e\x46\x3b\x1c\xa4\x29\x33\xee\x9a\x84\x31\xd5\xb5\xac\xe1\xad\x7c\x85\x91\x3f\x91\x06\x09\x30\x7b\xab\x0d\xfa\x66\xc3\xb3\x38\x0d\x24\xa0\xc0\xc2\x5c\x54\x0a\xf2\xb2\x10\x6f\xf5\xba\x3c\x88\xae\x59\x91\xd2\xfe\x3c\xfb\x50\xab\xaa\xfc\x7b\x0f\x35\x0d\x13\xaa\xfb\x47\xc2\xd6\xeb\x49\x6e\x7b\x45\x91\x8a\x5c\xa6\xfa\x97\x51\x93\x48\x1d\x01\x48\x7b\xec\xaf\x5b\xa7\x02\x0b\x7f\xfb\x41\xea\x34\x92\x01\xe2\x59\x28\xc8\x69\x83\xbd\xc3\xa1\x89\x03\xc9\x5c\x1c\xd4\x71\x51\xae\x5a\xe7\x77\xe8\xbb\xa6\x89\x07\xb8\x11\xde\x67\x06\x06\xdf\x37\xf1\x13\x8c\xd7\x20\xd9\xe7\x6e\xd9\xba\x85\x9d\x81\x9a\xa6\x5c\xa3\xa3\x96\x59\x47\xb2\xcb\x62\xe0\x99\xc0\xbb\x6e\x01\xf1\x8e\xae\x97\xb3\xfb\x87\xde\xb2\x77\xcd\x21\x30\x0b\x3e\x5d\x13\xb5\x76\xeb\x94\x5d\xca\x98\x5c\x37\xc5\x31\x8a\xd0\x1a\x6d\x6b\xa0\xbc\xfa\xe8\x46\x26\xc6\xad\x66\x55\x16\x7f\x65\x1b\x54\x6d\x1d\x8d\xab\xe0\x61\x6a\xfd\xdb\x37\xa8\x1a\x27\x39\x38\xac\x12\x71\x7d\x85\x87\x59\x85\x9b\xd9\xdd\xfd\xef\x0e\x7b\x92\x0a\xad\x70\xd9\x1f\xb2\x62\x83\xcc\xdd\xf8\x53\xe3\xe7\x8d\x8b\xe2\xa7\x32\xe2\x68\x6b\xa0\x4a\xcd\xc8\x2e\x48\x65\x7a\xc1\xee\xd9\x7c\x5c\x17\x2f\xb9\x3c\x5a\xb1\x30\x62\x2e\x4a\x7e\x3c\x35\x56\x15\xa4\x94\x39\x1c\xea\x5f\xa6\xaa\x19\x52\x15\x41\x28\x07\xde\xcd\x54\xde\x2a\x55\x5a\x2b\x71\x49\x0d\xb6\xd6\xad\x3b\x97\xca\xaa\x97\xdd\xbe\x85\x91\x49\x92\x6a\x16\x4a\xd1\x89\xe4\x54\x15\xa8\xe6\xf6\x54\x60\xe7\xbb\x7a\x21\xf2\x1c\xf4\xd3\x45\xd7\xcc\x5d\x14\x09\x2c\x96\x22\x76\xe7\x39\x14\x60\x32\x95\x89\x2e\x99\x9c\x1a\x9f\x70\x68\x12\xcb\x7e\xed\x96\x37\x78\x65\xe1\x05\xc6\x11\xb7\xcc\x85\xbe\x60\xd8\x05\x4b\x39\x42\x76\x91\x4a\xbe\xa7\xc6\x38\xed\x98\x08\x96\x92\x1c\xf2\x4b\xf6\x06\xab\xaa\x6c\xf7\xec\xaf\x52\x08\x82\x19\x1f\xf9\x2c\x56\x55\xf9\xd6\x5f\x12\xc2\x8f\x19\x15\x8e\xec\xcb\xf7\x87\x33\x3a\xe5\xc3\x38\x8f\xf0\x13\x81\xde\xc1\x01\x74\xd6\x7a\x23\x83\x04\xa7\x08\x84\x89\x2e\x85\xad\x0b\xd1\x58\x0b\xe2\x62\xce\x8c\x63\x96\x22\xf4\x3c\xaf\x4b\x92\xd9\x02\x1e\x77\xbb\xc8\xf7\x71\xb2\x58\xd9\xac\x2a\x93\x8e\xc7\x61\x34\xf9\x44\x6b\x55\x6a\xca\x15\x1e\x44\x75\xbe\xcf\x7a\x5a\xa9\x5c\x44\x11\xa3\x0a\x92\x06\x8e\xdb\xf7\xb2\x17\x86\x10\x51\x64\x70\xa7\xc2\x04\xdb\xa0\x21\x26\x24\xbb\x40\x5d\x59\x3a\xa5\x87\x16\x82\xeb\x28\x39\x73\xa5\x8f\x3d\x92\x11\x3a\x13\x46\x6f\xa9\xa8\x20\xb4\xfd\xde\x99\x9e\x9f\xff\x41\xd6\x46\xc4\x41\x88\xfb\x65\x3b\x39\xe7\x59\xb3\xfc\xf3\x24\xf2\xcd\x49\xa9\xcb\x26\x2f\xe2\x24\x26\xd1\x6b\x68\xa0\x3a\x64\x85\xdb\x2f\xa9\x9e\xd6\xd5\xd5\x7e\xe5\x69\x8a\x58\xd0\x5e\x88\x34\x12\x7f\x0d\xe6\x44\xac\x02\x74\x21\xb6\xfb\x4c\xa9\x5e\x89\x90\x88\x95\xc1\x2d\xb2\x10\xcd\xa9\x12\xf9\x73\xd1\x9d\x81\x22\x31\x1c\xe5\x3d\x31\x41\x56\x88\x7c\xb4\x78\x84\x34\x1a\xec\xb1\x75\x7f\x2a\xd4\xeb\x94\x75\x2d\x34\x57\x18\x7b\x3a\x88\x0f\x2a\x89\x1e\x52\x37\x71\x01\x5e\x8c\xbc\xce\x6b\xd4\xae\x39\xf4\xa2\xbe\x5d\x07\xc1\x08\x8c\x6b\xf3\x35\xa3\xc9\x0c\x52\xa0\xcd\xb9\xd9\x67\xc7\x41\x85\xc7\x34\x3a\x60\x60\x9d\x7d\xf2\xb9\x0c\x0f\x30\x4a\x68\xe1\xcb\x68\x3a\x77\xbf\x7e\xd4\x35\x48\x30\x51\xb2\x7d\xbe\x71\x54\x48\x5c\x98\xc4\xa0\xb5\x27\x4f\xd7\x20\xcd\x2f\x23\x4b\xd2\x8b\x35\x81\x85\x45\xbd\x9f\x0b\xf5\x4a\x08\xe8\xf2\xda\x80\x93\xcc\x0a\xdb\x09\xad\x11\xd5\x71\xcc\x9d\x76\xd3\x84\xb0\x90\xbd\x86\x33\x0f\x6b\x95\x2f\xf5\xfc\xee\x57\x55\x9f\xc5\x22\x24\xe7\x1c\xed\xf4\x76\x37\xb1\x7e\x4a\x7e\x1a\x7d\x23\xe9\x33\x62\xfb\x5b\xe6\xe7\x66\x5f\x65\x5d\x7a\x5b\xfa\x49\x14\x93\xa5\x81\x80\x43\x2b\x32\x59\x56\x9b\xec\x05\x67\x1c\x5c\x91\xb1\x0d\xfe\xdb\xde\x25\x60\x42\x04\x36\x72\xdd\x37\xc5\xbe\x8e\x15\xca\x20\xf2\x29\xed\x27\x0a\x3a\xcc\xc6\xaf\x1d\x24\x9e\x23\xc0\x5c\xc3\x0b\xd2\x8f\x0e\x69\x1d\x7a\xf7\x02\x83\x99\x50\x0a\x1e\xba\x9f\x17\x7a\xc2\xdd\x00\x49\x65\x10\x5d\x38\xbc\x30\x4c\x03\x65\xc3\x11\xdb\x4c\xbd\x42\x33\x3f\xf7\x0a\x0a\xae\xd5\xec\xfa\x2b\x5a\x86\x82\x23\x05\xc3\x41\x7c\x6c\x3f\xbe\x89\xba\x0f\xc3\x93\x11\x0b\xb0\x11\x63\x3c\x3b\x61\x2e\x69\x6c\x19\x05\x02\x9d\xd4\x1f\x59\x9d\x95\xc5\x6f\xee\xcf\x89\x0a\x50\x38\xd0\x56\x5d\xf4\x1d\x4a\x29\xc3\x18\x2d\xe8\xe1\x64\x77\x8d\x51\x64\x21\x59\x96\x5f\x6d\x3a\x60\x28\xb5\x97\x86\xb6\xf8\xf8\xae\x9e\x9f\xce\x13\xea\x9e\x8e\x1c\x80\x4b\x08\x81\x40\xfb\xfb\xeb\xca\xc8\x6b\xa3\x55\x42\x4a\xd2\x59\xe4\x1b\xe1\x81\x7a\x71\xc6\x24\xc8\x30\x91\x8e\x9e\x12\x5b\x9f\x8c\x71\xaf\x6f\x18\xc7\x68\x87\xaa\xf3\xfe\xae\x28\x4d\x40\xde\xaf\xae\x44\x56\x6c\x9a\x4a\x9c\x07\x40\xee\xae\x57\xe0\x53\x82\x46\x43\xf5\x80\x14\x2c\x5f\xe8\x08\x7d\xb2\xb3\x5c\x4d\xd5\xe1\x23\x42\x3f\x88\x2f\x52\x84\x14\x73\xe9\x43\xf1\x46\xe3\x6c\x12\x2d\xfd\x8b\xf6\x70\x5f\xe5\x24\x0a\x5c\x1f\xe3\x69\x6f\x48\xc8\x34\xd3\xe2\xd8\xb4\xbf\xe1\x9a\x38\x9c\x2b\x8f\xd1\xb1\x5f\xd3\x3d\x91\x1a\x01\x8d\x47\x7f\x38\x1e\x8a\x25\x14\x60\xc3\x54\xf6\xcb\x95\x22\x05\x57\x0c\x04\xfa\xab\x80\xcc\x2a\x0a\x1c\xec\xcf\x0e\xbb\xe2\xbe\x46\x8e\x99\x59\xeb\x8c\x77\x5a\x1d\xa3\xa7\x70\xed\xe3\x89\x8c\x5f\x04\x0e\x63\xc8\xd7\x97\xdb\xa8\xf2\xbd\x00\x33\xa3\x82\x2c\x36\x54\x5e\xe9\x2b\xf8\x72\xe5\xfb\x1e\xde\xbe\xdd\xd6\xfe\x4d\x98\x92\xed\x3e\xab\xd7\xce\xe3\x50\x41\x44\xa8\x9e\x6f\xe2\x00\x9b\x63\x56\x65\x4d\xef\xd8\x54\xa1\xc7\x04\xeb\x69\xee\x7e\x8d\x4c\x55\xa1\x67\x30\x9e\xbc\x05\x71\xb0\xda\xee\x7d\x4e\x56\xae\xc2\x80\x64\x67\x90\x0d\x7d\xc0\x0a\xdb\xbb\x89\x8e\x6d\x5e\xbc\xd0\x33\xfd\x96\xd5\x65\x55\x7f\x45\x0c\xc1\x55\xc4\x13\x64\x23\x70\x6c\x02\x7d\x4d\x03\xae\xa2\x20\xb5\xb8\xce\x02\xea\xac\xee\xd5\xdb\xa9\x28\x14\xe8\x23\xc0\xc5\x6f\x50\x51\x1a\x46\x91\xc3\xaa\x8d\xa2\x99\xfd\x85\xaa\x62\x46\x88\xa9\x17\x68\x66\xc7\xe3\xd0\xd7\x55\x71\xa0\xb0\x0a\x6f\xb9\xfa\xd1\x5f\x8a\x2a\x0e\x89\x1a\xab\x21\x85\x95\x83\xb8\x8c\x75\x0c\x22\x34\x1d\x7c\x0a\x63\x2c\x33\x87\x95\x73\x7d\x12\xcf\x28\x4a\x1a\x76\xd1\x30\xd7\xc2\x0c\xa6\x28\x1f\xee\xe7\xbb\x7b\x78\xb9\xcc\xc2\x24\xf6\xd0\x23\x79\xc8\x8a\xcb\x6d\x62\x8e\x30\xa2\x1f\x59\xf5\x52\x8e\xb2\x7a\x2a\x8d\x88\x8b\x0e\x67\xe4\xf7\xec\xde\x81\x25\x94\xf0\x12\x0c\x04\x21\x05\xdd\xad\xd0\x50\x9e\x9a\x6d\x49\x0a\x35\x75\xdf\x60\xbe\x22\x55\x1e\x7d\x2f\xc1\x0d\xe2\x5f\x6e\x17\x4f\x77\x8f\x8c\x31\xef\x8b\x52\xb5\xd1\xa5\x92\x91\xd0\xe1\x72\xfb\x7d\xe9\xec\x10\x25\x25\x73\xba\x16\xd7\xd0\x1f\xa5\x22\xe9\x05\x96\x60\x9d\x24\xfc\xfe\x02\xbd\xd4\x19\x2d\xea\xd1\x9a\xd6\x10\xa0\xb1\xd7\xec\x2b\xa8\xf7\x9d\x82\x32\x57\xda\x80\xdf\x15\x89\x3b\xc6\x09\xda\x46\x87\x77\x00\x8f\x38\xda\x6e\xa8\x2a\x62\x73\xca\x54\xd6\x55\x38\x28\xf0\x84\x31\x3d\x6c\xd9\xac\xd0\x03\x45\xea\x2f\xb0\x9e\xd7\xe3\x08\x9e\xf1\x9d\x7c\xed\x76\x5f\x95\xef\x94\xb8\xba\x6f\xcf\xf5\x66\x0d\x6f\x78\x2a\x3e\x96\x4d\x3f\x31\xab\x80\x05\x09\x81\xb0\xf3\x52\x0c\xf8\x23\xb9\x32\x9e\x08\x64\xaf\x48\x68\xd9\xec\xbf\x5e\x79\xc6\x03\x02\x4f\x82\xa8\xd4\xde\xd1\x48\x0f\x07\xc4\x70\x93\x30\x17\xf6\xf9\xf3\x74\xc9\xb0\xb8\x76\x1d\x23\x1b\xf8\xb1\xac\x9b\x7f\x97\xf2\xd3\x03\x67\xb8\xc0\x8c\xd1\x68\x15\x6c\xd7\xcb\x25\xe2\xf9\xec\xef\xd3\x1e\x4b\xd0\xa8\x7d\x85\xf3\x1a\xfe\x3c\x65\x55\xb7\x46\xb4\xc7\x25\x8e\xd7\xf7\xd9\xfa\x66\xb7\x98\xad\x76\x77\x8f\x56\x2d\xce\xf5\x60\x51\xa7\x58\xfa\x90\x15\x98\x25\xbe\xb0\x8b\xf4\x23\x67\x9a\x49\x8e\xb5\x93\x3b\xa1\xcb\x63\xb3\x11\x07\x58\xe4\xa2\xae\x67\x1f\x19\x0c\x3d\xd9\x4f\x90\x7e\x9a\x19\x92\x75\x94\xa2\x78\x25\x14\xfc\xb6\xb7\xd2\x91\x06\xa9\x63\x5a\x13\x2f\x50\xcf\xe1\x25\x2b\x96\x5d\x38\x55\x07\x91\x48\x09\x80\x5e\x37\x7d\xcd\xd3\xab\xc4\xc1\x84\xc6\x1d\xd7\x61\x10\xa0\x00\x87\xce\x6a\xd1\x9a\xd3\xbd\x3c\xba\x0e\xd3\x88\xb8\x03\xea\x55\xd9\xd3\x14\x9a\x9c\x83\x3a\x0a\x22\x54\xe3\x3d\x0a\x95\x99\xac\x6e\x0e\xa8\x36\xbb\x86\x3f\xdd\xdd\x62\xa5\x10\x6c\xb1\xfd\xf8\x32\x30\xaa\x13\x13\x92\x0e\x09\x0a\x6f\x7d\x59\xc6\xae\x53\x9e\x60\x72\x70\xf3\xf3\xee\x76\xbb\xb9\xd0\x37\xbb\xe6\x28\xc0\xc0\xe7\xaf\xbf\x2f\xf0\x9b\xf5\xcb\xb8\xb5\xf0\xa5\x23\xa9\x1c\x61\xad\x86\x37\x11\x26\x42\xa9\x32\x17\x54\x5b\x45\xee\x0e\x52\xe8\x20\xb0\xa4\x67\xd5\x93\x19\x2c\x21\x2d\x95\xc6\xf8\xcc\x3b\x64\x6b\x71\x45\x44\xc6\xb5\x12\xa9\x0b\xa3\x3c\x88\x22\x33\x50\x37\x77\xba\x9e\x9f\x49\x8c\x00\xeb\x12\x87\x17\xe8\xb0\xc3\x49\x2d\xf2\x0c\xcd\x90\xe1\x60\xe8\x34\xc2\x24\xd5\x6b\x96\xe7\x35\x16\xa6\xb9\x17\x35\x31\x71\xab\xae\x9f\xee\x97\xbb\xe5\x6f\x8b\xef\xb3\xc7\x6f\xdd\xae\xa9\x8d\xf4\xfc\xc8\xa2\xf6\x5b\x4b\xa8\xf5\xc1\xfe\xf3\x79\xb9\xdd\xf0\x13\x80\x17\x01\xc2\x00\xbf\x97\xcd\xe2\xb2\x4d\x02\x63\x3e\x79\xb1\xb9\xc8\x0e\x6b\x10\xda\xd6\xaf\x4d\x7d\x72\x60\x41\x88\x88\xc0\x55\x99\x8b\x2a\xab\x9f\x8b\xec\x0d\xa3\xe1\xfd\x13\x13\x58\xa8\x62\x1a\xed\xd6\x9a\xd3\xb6\x4a\xa2\x57\x9f\x07\x2c\xf2\x98\xb5\xb3\x40\x4f\x6b\x76\x72\xe0\x29\x31\xca\xd7\xad\x17\xb1\x34\x06\x54\x33\xcd\xc6\xc9\x81\x6b\x96\xa8\x0b\x8b\xe1\x5d\xbd\x3e\x15\x17\x51\xcc\xb6\x5d\xa0\x0b\xf1\x9f\x93\x28\x1a\xa4\x40\x9b\x0c\x7b\xfd\x8d\xf3\xf6\xc9\xb8\x72\x13\x62\x55\x58\xbd\x3f\x35\x37\xe5\x3b\x92\x6d\x8d\x7e\x8a\x1f\x9a\xc8\x16\x49\x7e\x2b\xc5\x80\x39\x9f\x83\x2f\x53\x24\x98\x7d\x7c\xb8\x1d\x0c\x63\x90\x6a\xf4\xa3\x6f\x9f\x1f\x6f\xee\x1e\xbf\xed\xbe\x3d\xcd\xee\xbb\x36\x1d\x23\xe9\x74\xf9\x71\xe9\x1f\x7a\x3e\x66\x31\x5d\x59\xfa\x12\x91\x6d\xd0\x35\xa7\x02\xc3\x38\x15\xb4\xa7\x08\x95\x31\x4e\xae\x55\x08\x65\x6a\x58\x27\x87\x7a\x29\x92\xb9\x18\xc4\xae\xa3\x0e\x95\xdd\x7b\x57\x77\xa4\x07\xcd\xe2\x4b\x23\x49\xb0\xd0\x09\xb7\xb2\xaa\xa5\x63\x8c\xee\x70\x9c\x22\x3f\xc6\x1d\xf6\x5e\xc8\xa6\xac\x4e\x87\xc1\x78\x44\x2a\x41\xab\xd0\x42\xf0\x9e\xe4\xff\x40\x35\x6b\x50\x70\x6c\xae\x90\xed\x10\x4b\x11\x5b\x36\x47\xeb\x54\xcc\x28\xa8\x35\x7c\x60\xe2\x85\x88\x87\x6a\x8f\xdf\xe5\x07\x45\x93\xdc\xf3\x12\x26\x31\x56\xa2\xb3\x3a\xcf\x5e\x61\x01\x39\xc8\x6a\xa2\xba\xd5\x75\x8f\x34\x77\xb0\xa2\x41\xa1\x77\xef\xe4\x84\xd4\x53\xbe\x4f\x35\x1e\x1d\x90\x0f\xd2\x30\x0c\xa1\x0b\x6d\xa3\x80\xc1\xbd\xa8\x1b\x02\xb6\xde\xdd\x8c\x7e\x59\x1a\x46\xc6\x56\x92\x36\x25\xf1\x5f\x64\xc5\xcb\xfc\x54\x67\x05\xd4\xf5\x0d\xbc\x7d\x96\x7c\x1f\xbd\x6f\xaa\x48\x2f\xe3\x78\xca\xf3\x09\xc2\x7f\x0e\x22\x0e\x9c\xe5\x8f\xed\xe8\xe2\xdf\x15\x3f\x97\x77\xee\xc5\x85\x54\xe8\x4e\x1d\xcb\x3a\x93\x39\xac\x41\xc3\x01\x3f\xc6\x38\xff\x0c\x42\xa7\x4e\x74\xe1\x01\x5e\x84\x2c\x47\xd1\x38\x10\x46\x90\x04\xcc\xbe\x7c\xbf\x5d\xb5\x0e\xe6\xac\x2b\x30\x02\xe5\x27\xc0\x2f\xf5\x51\xa3\x7b\x6b\xcf\x73\x20\x31\x9b\xa4\xaa\x0e\xe7\x81\xa8\x03\x07\x1d\x46\x98\xa5\x6b\x0e\xc7\xff\x9c\xa0\x3a\x6f\x00\xa6\x25\xb7\xdb\xae\x09\x09\xe0\x37\xfb\x0b\xe6\xac\xbb\x4f\xe4\xa1\xf5\x44\xaa\x2f\x73\xac\xa3\x3c\x1e\x5c\xbe\x06\x20\x00\x4f\xda\x62\x3a\x2c\x31\x0d\x5d\x8b\x09\x14\x7a\x75\xfb\x52\xe7\xa4\x20\x12\x3d\x74\x6d\x89\x8a\x89\x36\x68\x50\xf4\x03\x46\x13\x83\x1d\x74\x4e\xf2\xa1\xf3\x3d\x8c\xe7\x7b\x60\x0b\xca\x4f\xf5\xb6\x3c\x91\x6b\xee\xc8\xa7\x06\x3f\xc9\x78\x92\x44\x5d\xa9\xee\xf8\xf6\x52\xc0\x6c\x3c\x45\x8b\xf4\x12\x9c\x70\xbb\xc6\xf0\x0e\x8c\x25\xe8\x04\x0d\x2c\xf2\x49\xb4\x98\xf1\x23\x2e\x44\x5f\x26\xa0\x35\xb4\xda\xd9\x3e\xde\x65\xaf\x02\x4d\xc3\x7a\x28\xe3\xa7\x3e\x5a\xa1\x76\x53\xef\x45\xcf\x8d\x9f\x0a\x8c\xdd\xce\xd6\xbf\xad\x84\x7a\x15\x36\xea\xe2\x5a\x4d\x8c\xd6\x90\xb0\x34\x7c\xbb\x6a\x00\x9e\x30\x41\x18\xa7\xce\x08\x9f\xfe\x0d\x61\x0c\xb8\xa5\x03\x42\xe5\x07\x05\x6d\xbd\x17\x0c\xff\x1f\x67\x6f\xd6\xdc\x38\xae\x6c\x0b\xff\x9d\x7e\xd8\x0f\x04\x31\x90\x7c\x94\x65\xb9\x4a\xb7\x3d\x7d\x96\xaa\xab\xfb\x9c\xb8\xa1\xc0\x90\xb0\x79\x4c\x91\xda\x24\x65\x97\xf7\xaf\xff\x82\x09\x80\x93\x68\x77\x9f\xfb\xd2\xd5\x61\x40\x1c\xc1\x44\x0e\x2b\xd7\x32\x19\x37\xae\xc2\xf7\xa3\xbc\xed\x15\xb4\x63\x2b\xe2\x28\x0d\x8a\x1a\xf3\x54\xa7\x15\x2c\xc5\xcc\x9c\xd7\xa0\xe9\x7f\x03\xae\x6b\x2d\x6f\x96\x9a\x4d\x6d\x4a\x38\xa2\xf4\x5d\x0b\xcc\xf5\x66\x75\x7d\xbb\x0d\xe4\xeb\xb1\x4d\xb9\x06\x2f\xb8\xfc\x59\xbe\xbf\x3f\x7f\x9a\x72\x96\x0e\x90\x6b\xcc\x2e\x3e\xe6\xbf\xa0\x98\xc8\x36\xfe\x37\x11\x17\x4d\x05\xfd\x01\x04\xc2\x60\x37\xbf\x76\x2f\x50\x4c\xb6\x7e\x9b\x91\x0c\xfd\x83\x52\x1e\xe1\x26\x2f\x66\x32\x7a\xdd\x38\x20\x2c\xe0\x4a\xff\x6a\x9a\xe9\x2f\xd3\x0c\x3c\x87\x87\xa3\x7c\xea\xd6\xf1\x0e\x55\x76\xa6\xa7\xcf\x52\x45\x3c\x19\x1e\x8a\xa1\xd4\x13\xdc\x88\xcd\x14\x8d\x84\x07\xcd\x74\xef\xe4\xeb\xfc\x87\x95\x34\x13\x2e\x48\xdc\x15\x79\x08\x73\x7c\x2c\x1c\xa6\x64\xae\x78\xf1\x50\x8f\xa0\x0f\x56\xc9\xc8\x81\xb7\x1d\xd2\xd2\x5d\xc4\x77\x59\x9b\xb5\x3c\xf5\x73\x94\x46\x47\xd0\x39\x42\x63\xfa\xef\x89\x6b\x6f\xb5\xa0\xe8\x48\x5f\x83\x3a\x3f\x0f\x4a\xe8\x7e\xd4\x08\xe9\x64\x69\x5f\x40\xbf\x3e\xd6\x55\x65\x7f\xbb\x90\xa7\x0e\x53\x13\x83\xeb\xf6\xa0\xce\x1f\xb3\x05\x64\x14\x18\xd7\x04\x72\x0d\xd7\xb0\xdc\xcb\x61\x41\x46\xe8\x56\x78\xb5\xda\x47\xac\xf3\x2c\xaf\x02\x50\x12\xe9\x78\x64\xad\x72\x0c\x1f\x9a\x53\x55\x36\xee\x2b\x9d\x1e\xd4\x12\x1d\x2a\x58\x77\xd0\x4a\x23\x5b\xf9\xe3\x29\x78\x32\xd6\xaa\x24\x38\xf7\x3f\xab\xfa\xd5\x16\xd5\xfb\x7d\x0f\x16\xa1\x51\x94\x44\x7c\xcc\x80\xfb\x6d\xff\xd0\x0f\x81\x03\xfd\x3b\x9c\xde\xe4\x76\xc6\x4e\x2b\x8d\x88\xe2\x21\x9f\xd2\x3e\x9c\xa0\xa7\xcc\xa3\x11\xd1\x2a\xb0\x9f\xae\x0a\x27\xae\xf9\xdb\xe4\xa7\x31\x89\x10\x8f\x70\xb5\xef\x02\xf6\xff\x65\xb8\xdf\xfd\xdc\x85\x9c\xf6\x8c\x49\x83\x33\x3c\x76\xfb\x46\xf3\xf2\x65\xc1\x95\x76\x41\x2f\xfa\x55\xc7\x8f\x8b\x0e\x17\x1a\x51\x02\x81\x03\x6b\x77\x3e\x3e\x58\x57\x8d\x6b\xfa\xe1\x24\xf2\xca\xfe\x4e\x5e\x7c\x02\x00\x9a\x9e\x86\x66\x8c\x0e\x92\x4d\x4f\x08\xdb\x1c\x00\xbd\x34\x62\x22\xc5\xa8\x09\x5b\xe0\x03\x57\x74\x1a\x06\x25\xa3\x03\x1f\x98\x99\x94\xbe\xba\x51\xa1\xb2\xf0\x35\x3b\x94\xc5\x32\x57\x3b\x8d\x38\x4f\xb5\x43\xf1\x7c\x7c\xcb\x6d\x5b\x85\x43\x88\xd8\x49\xb9\x79\xfe\xf8\x40\xa3\x35\xeb\x04\xa3\x91\xd0\x1a\x2f\xe4\xdf\xdd\xbe\xde\xf7\xf1\x8f\x97\x20\x8d\x12\x13\xe1\x56\xf2\x3f\xf2\x3f\xff\xf9\x35\x32\x3b\x34\x4a\x25\x0d\xcb\x6f\xab\xab\x51\x15\x83\x46\x59\x44\xb9\x93\xf5\x91\xc8\x6c\x15\x2e\xc1\xec\x2b\x23\x3f\x66\x67\xc8\x14\x53\x81\x80\xaa\x2a\x8a\xad\x81\xb2\x9d\x6a\x57\x2d\xd5\x51\x68\x24\x13\x86\x5c\xc3\xeb\xfa\xe3\xa4\xa1\x9c\x5c\x9b\x54\xdc\x09\x24\x42\x69\x56\x45\x81\xbc\x6f\x98\xbf\x9a\xdf\x9e\x84\x04\xf9\x8f\x56\x6f\xad\x9e\x1c\x41\x59\xd7\x20\xff\x26\xcf\xc5\x14\x5b\x4f\x23\x1d\xbb\x67\x92\x37\x41\x01\xf8\xa1\x9e\x24\x83\x66\x8b\x52\xc7\x0e\x91\xa0\x6b\xf3\x3f\x41\xca\x39\x0c\x25\x54\xf3\xc0\x4a\xd5\x39\xa4\x5f\x61\x4a\x69\xa4\x25\xc3\xdd\xdb\xe6\x65\xde\xbc\x4c\xb8\xbd\x69\x64\xe2\x34\xa2\x23\xc5\xdb\xc7\xaa\x41\xe7\x72\x6c\xe5\x69\x64\x84\x93\xa3\x7f\x94\xb5\x34\x79\x03\x97\xf0\x30\x1a\x19\x70\x59\xe4\x6f\x80\x82\xf8\xa3\x4f\x20\xfd\xd7\x78\x25\x03\x4b\x03\x47\xf8\xf9\xe4\x45\x51\xc3\x79\x40\x5b\xeb\x50\x16\xaf\xcd\x7f\xfa\x95\x61\x81\xdb\xa8\x5f\x9a\x9d\xd9\x0a\x3c\x14\xd3\x47\x66\x21\x0b\xe2\xdb\x43\x24\x46\x49\x14\x39\xe9\xcf\x6f\x55\x3b\x7a\x8a\x24\xea\x1c\x6a\xd7\x24\xd1\x06\xf8\x62\x5e\x56\xa7\x02\xfe\x0a\x10\x08\x4a\x22\x66\xb2\x78\x5a\x5c\x75\xed\x45\xcd\xae\xad\xf3\x81\x16\xc5\x6f\xf7\x94\x44\x49\x8c\xce\x8e\x03\xe2\x79\x95\xcf\xf9\x8b\xf9\xef\xff\xfb\xaf\xf0\xb3\x25\xca\x4f\x4a\x08\x4b\x51\x48\xc8\xc1\x15\xd6\x2f\xb2\x28\x60\x24\x6a\xbb\x6c\xc7\x08\xf1\xd4\xba\xd8\xb2\xd6\xab\x0c\xf9\xc1\x38\x95\xb8\x57\x59\x18\x72\xf9\x94\xc4\xd6\xe5\x4e\x1a\xe8\xe5\xf6\x36\xc7\xbc\x6d\x3b\x3f\xac\x99\x38\x61\x83\x27\xd6\xfd\xca\x81\x56\x51\x91\x13\xa7\xec\xab\xcf\x29\x0a\x29\xa1\x54\x39\x51\x04\x79\x04\xcc\xd2\x75\x46\x34\x28\x94\x51\x42\x55\x06\x3c\xac\x88\xe9\x3b\x25\xd4\x38\x1e\x30\x5d\x54\x0d\x5c\xe5\xc6\x49\x76\xf8\x41\x46\x84\xd3\x71\x2a\xdb\xe6\xdf\xc7\xfe\xaf\xdc\x65\xee\x30\x9e\xee\x36\x21\x30\xce\x13\x9f\xac\x69\xc2\x84\xc5\xec\x4e\xe7\xad\xb6\x57\xc3\x2b\xe7\x22\x56\x59\xe0\x4b\x0c\x4f\xb1\x19\x46\x0d\xe2\x19\x7b\x8a\xf8\xc2\x2c\xe2\x3e\xc2\x74\xcb\xb1\xe8\x80\xfd\x0f\xfb\x8f\x13\x1c\xee\x7b\x11\x1f\x4a\x44\xe4\x18\x91\xea\xaa\x6a\x1f\x2c\xaa\x3d\xf5\x43\x52\x21\xad\x57\x09\xef\xff\x07\x2e\xa4\x9b\x29\x11\xd6\x15\x66\xee\x57\x57\xeb\xf0\x9b\x84\x30\xcc\x66\xb5\xde\x39\xc2\x0e\xb6\x87\x73\x7f\xcc\xc4\x46\xf8\xe5\x5d\xf8\x68\x0b\xc9\x01\x4a\x52\x4e\xb0\xca\x74\x0f\x65\x35\x36\x3f\x24\xcb\x28\x3e\x20\xd4\x52\x46\x8f\xbf\x1f\x31\x16\x09\xbe\x0c\x58\x58\x48\x89\xbb\xb2\xaf\x98\xca\xbd\xf7\x5f\x8e\x64\x86\x89\x11\xf2\x46\xea\x76\x27\x8f\xa7\x02\x26\x2e\x02\x91\x8a\x60\x37\xcb\xaf\xa3\x6c\xba\xd0\x6a\x0c\x59\xea\x46\x63\xdc\x63\x65\x51\x3c\x9c\xa0\x96\x43\xe5\x65\x78\x27\xd2\x68\xe5\x2c\xf1\x0e\x70\x5a\x7f\x67\xca\x5a\xcc\xa4\xdd\x6d\xef\xb7\xf7\xdf\x0e\xc8\x94\xea\xb4\x1b\xc3\x0c\xad\xa9\xa7\x2b\x6c\xf5\xcb\x5c\xc8\xab\xbf\x15\x23\x62\x2e\x50\xe1\x29\x70\xb2\xfc\x1d\x50\xe1\xcb\x9c\x17\x25\x46\x6a\x22\x46\x41\xde\x24\x44\xfa\x84\x91\x69\x56\x2c\x1a\x7d\xbe\x46\x99\x0c\x42\xbf\x06\x56\x42\xb0\xf3\x61\xdb\x6b\xad\x50\x62\x34\xc3\x65\xee\x7b\xc6\x0f\xa7\x51\xcb\x46\x37\x9a\xa2\x55\xc4\xb6\xd4\xc7\xba\xfa\x35\xdb\x9e\x09\x44\x8e\xdb\x68\x55\xb6\x90\x17\x93\xd5\x03\x29\x75\xb6\x43\x35\x77\xf2\x57\xaf\xbd\x4e\x09\xd8\x0c\x8b\xc1\xbe\x5c\x36\x3c\x3b\x0f\x49\x5e\xcc\xb3\xf4\x85\x34\x7f\x10\x4b\xd2\xd4\xdb\xb3\x83\x0f\x64\x0f\xe8\x32\x37\xdd\x2d\x1c\xe0\xa2\xaa\x4f\x89\x8d\x09\xe6\x33\x9c\xc5\x0e\xdb\xe3\x3f\x7b\x2f\x56\x50\x9d\x8d\xd0\xcd\x93\x98\x6e\x3a\x37\x8e\x40\x62\xee\x6b\x3d\xc0\x97\x9a\x4f\x2d\xfa\x7c\x9d\x84\xa5\x15\x93\x98\x21\xb8\xb4\xb3\xbb\x3e\x0f\xd2\xfd\x51\x53\x9f\x01\xff\x9e\x3f\xbf\x40\xe3\x6a\xc7\x33\x9d\x72\x1a\x13\x26\x12\xde\x13\x87\x4c\xcb\x7b\xa3\x05\x12\x13\x21\xb1\xbb\xf2\x6e\xf5\xe7\xe1\xfe\xc7\xdd\x61\xf5\xc7\x6a\x7b\x1b\x4e\x16\x0b\x81\x28\x88\xf5\x8f\xa7\xa7\xcd\xfd\xfe\xf6\xaf\xc3\x76\xb7\xfb\xb1\xb9\xee\xc7\x55\x42\x43\xf9\xc0\x98\xd9\x15\x50\xee\xa8\xd5\x0f\x81\x2d\xe6\xb1\xae\x4e\x50\xfb\x2c\x1f\xf9\x54\x0f\xc5\x17\x8a\x26\xab\x2c\x66\xd4\x41\xba\x91\x10\x72\x96\xa7\xa2\x31\xf3\x89\xa5\x36\x28\xc3\x77\xef\xfe\x30\xbb\x1e\xc6\x33\x64\x20\x5b\x57\x01\x2e\x3e\xfb\x6c\x2e\xf0\x27\x34\x66\x52\x22\xd2\x4b\x17\xb2\xe9\x4e\x3b\x3b\xa2\x04\xa4\xd0\x78\x7c\xa9\xa0\xcc\x7f\x05\xc4\xc5\xa4\x3b\x95\xc6\xdc\x0a\x34\xef\xb8\xb6\xf7\xd5\x5a\x36\xed\x65\x82\xdc\xcf\x15\x51\x82\xb5\x1c\x47\xea\xf9\xff\x64\x49\x96\x81\x82\x34\x16\x10\xc7\x41\x8f\x0c\xea\xd7\x02\xf6\x35\xc0\x53\x55\xb5\x81\xd7\x6a\xec\xb9\xc5\xc2\xd2\xa0\x95\x7f\xe7\xda\x17\x70\xbd\xaf\x2f\xb0\xb0\x34\x4e\x08\xc1\x18\xf0\x80\x25\x87\x7d\xf5\xcd\x85\x47\x73\x29\xf0\xd1\x0f\xb2\x24\x93\xbd\x30\x06\xb2\xcc\xcb\x5a\x1e\xc7\x82\xb8\x34\x4e\xa4\x36\x1e\xea\x86\x6a\xc3\xff\x8f\x46\x75\xa9\x70\x4e\xe3\x34\xcd\xf0\xc5\x35\x2f\xd5\xfb\x13\x4a\x8b\xde\x54\xf5\x5d\x55\x7a\x8c\x16\x11\x93\x67\x91\x19\x85\xbb\x55\x58\xc7\x9b\xfd\xf7\xd9\x23\x90\x11\x8b\x95\x2f\x82\x85\xda\x55\x3b\xe7\x21\xa0\xb1\xa4\x06\xbd\x15\x04\x6f\xed\x5a\x79\x59\xa7\x0c\x13\x53\x07\x53\xf0\xeb\x49\xe6\xc5\x07\x46\xff\x4b\xe4\x01\xdd\x6c\x86\x5b\x31\xfa\x82\x7e\xf1\x05\xf1\xcd\xdf\xfa\x39\x99\xf4\x1e\xfb\xd5\x39\x2f\x4c\x5e\x3e\xe3\x43\x9f\xdf\x88\x15\xc8\x73\xd4\x93\x57\xf5\x12\xef\xee\xe9\x4c\x3f\x3b\x45\x2d\x3a\x21\x16\x5a\xfd\xf2\x47\xd5\xf9\xc0\xcd\xb9\xe8\x9e\xe5\x5a\x96\x06\xeb\xf8\x57\x1f\xbb\x52\x9e\x9a\x97\xca\x81\x11\x3e\x59\x11\x4a\xa6\x98\xa5\x79\xab\xda\xee\x13\xb9\x92\x45\x51\xb5\xdb\xeb\xd9\xe9\x34\x8b\xb1\xd4\xb4\xfd\xff\xf6\x87\xeb\xcd\x7a\x7b\xb7\xba\xdd\xdd\xac\xd6\xbd\x1c\x25\x8d\xb5\x48\x1d\x6a\xa4\x73\xaf\x5c\x81\x70\x7e\x0c\xe0\x2c\xf3\x81\xdf\xbe\x9a\xec\xad\xcb\x97\xa6\xc1\x20\x60\x22\x24\x3a\xa7\x6f\xd4\x24\x8e\x34\xec\x60\x42\x01\xe7\xe1\xdc\x76\xe1\xc5\x45\x27\x00\x8d\xbb\xdd\x90\x07\x27\xd4\xf5\x57\x9a\x4b\x21\xfa\x6e\x5e\x86\xcb\xcd\x33\x49\xce\x3d\x38\x3f\xcb\x46\x06\x9b\x23\x36\x7f\xac\x66\xef\xd0\xd2\x18\x1b\x9f\x57\x1a\x86\x7c\x74\xf7\x67\x1d\xc7\x83\xf4\xc1\xe1\x5c\xb6\xb9\x2f\x03\x50\x1a\xc5\x8e\x20\x07\x0b\xb1\x79\xd9\xca\xbc\x1c\xb6\x6b\x1a\xd1\x08\x4b\x0c\x07\x5c\xd5\xe1\xaf\x84\x27\x18\x6b\x5e\x6d\xf7\x7f\xdc\xf5\x7f\x84\x28\x72\x9a\x0d\x1f\x07\xed\xdb\x39\x26\x17\xde\x79\x05\xc6\xe7\xc5\x6f\xb1\x24\x3a\x1b\x8f\xd3\x34\x30\x0e\x3b\x3e\x18\xfd\xf1\xdb\x27\x5c\x43\xe7\xa9\x08\x3b\xa5\x4c\xb8\xb6\xbe\x3c\x34\x53\x4e\x0f\xcd\x64\x8a\x12\xa9\xeb\xef\xab\xb0\x85\x51\x1e\x39\x43\xe7\x7a\xaa\x37\xc7\xbc\x69\x50\xf2\xea\x38\xfb\x34\x28\x57\x11\xbe\x96\xf5\xd3\xea\xe7\x35\x8a\x55\x6c\x56\x4f\xb7\x7f\x5d\x6d\x9f\xae\x0f\x9b\xfb\xeb\xc3\xf5\xea\xaf\xfe\x98\xc6\x86\xf2\x4e\xc8\x6c\xcc\x84\xcd\x29\x15\x44\x22\x0d\x22\x8a\x68\xc8\x02\x1d\x84\x30\x24\xb9\x4c\x03\xe6\xe8\x5b\x5f\x4f\xa6\x34\x61\x11\x86\xcc\xe1\xa0\x8b\x4e\x77\x58\x9b\x34\x51\x14\xfb\x4a\xd0\x70\x5f\xe7\x8d\xae\xde\xa0\xfe\x58\x0e\xdb\x68\x4a\x85\x53\x7b\xd4\x2f\x60\xce\x7e\xd5\xc9\xa9\x96\xd7\xe0\xcb\xf7\x30\x8e\xff\xa6\xd3\x06\x22\x4a\x53\x01\x08\x45\x41\x7d\x81\xfc\xdf\x67\xb8\xd4\xdd\xa6\x34\x8b\x22\xa3\x86\xfa\x83\x33\x32\xa3\x6a\x10\xa5\x19\x61\xe8\x6d\xfd\x01\xc8\xdf\xf1\x67\xff\xf7\x54\xa0\xc9\xb9\x92\xa5\xae\xea\x9b\xaa\x3e\x9e\x0b\xd9\x0f\x2a\x4d\x87\xe4\x01\x8a\xd8\x4e\xef\x52\xa6\x14\x3f\x8d\x1f\x65\xde\x7e\x0c\xd0\x3e\x4a\xa5\x51\xd1\x10\x4e\xf9\x8e\xd0\xfe\xb9\x2b\xe6\x65\x68\xf7\xfb\x9d\x2b\xb9\xe7\xd3\xd6\xd7\xcf\x13\x97\x9f\x71\xd2\x51\xaa\x04\xc3\xd0\x04\xde\xa0\x6c\x67\x08\x62\x4a\x55\xe2\x84\xaf\x9f\xbf\xa0\x32\x0d\x53\x95\x2b\x57\xd9\xbc\x28\xa6\x2a\x97\xf3\x7f\x3f\xd1\x9e\x9a\xbd\x41\x65\xb2\xd8\xb7\x5e\x5e\xd5\xa1\x98\xd7\x9f\x4d\xd3\xcc\xda\xd1\x66\xd8\x99\xfd\x4b\xee\xca\x30\xd9\xe8\x58\x84\x25\xb8\x32\xff\x83\x12\xc7\xcb\x7b\x1e\x35\x91\xa5\x8e\x40\xbe\xec\xcc\xf2\x1a\x3d\xa0\x20\x91\xb1\xbc\x68\x0d\x93\xd2\x29\xc7\x35\x55\xe1\x59\xbb\x26\x09\x28\x6a\x12\x82\x44\xc6\xa7\xba\x7a\x93\xb3\xdc\x1e\x85\xd4\x51\x2e\xda\xe2\xdc\xbc\x2c\x43\x52\x29\xb5\xda\x85\x0c\x57\x9d\x4d\x0f\xcb\x93\x45\x82\x60\xaa\xc2\x55\xb1\x3c\x19\xe5\xb7\xfc\x0d\xbe\xf7\x58\x4b\xca\xa2\xcc\x51\x8e\x17\x79\xe9\xb4\x44\x86\xd2\x03\x65\x24\x4e\x98\xe7\xd5\x19\xa3\xa5\x86\x5c\xd7\x94\xcf\x82\x32\x22\x41\xf9\x9a\xb9\x47\x0d\xec\xbd\xb7\xfb\x24\xcb\xd7\x21\x39\x35\xfb\x59\x9c\x3a\xb6\x16\xdf\x84\xda\x93\x78\x76\xbb\x71\xe7\x29\x97\xe6\xdb\x50\x13\x60\x31\x64\x88\xf7\x5c\xe2\xe2\x49\xc3\x1c\x6b\x31\x1d\xe1\xbe\x32\xef\x1d\x8e\x1b\x68\x50\x09\x0f\x93\x05\x28\xec\x30\x7d\xa0\x8c\x82\x81\x51\xb8\x89\x78\xae\x31\x46\x91\x32\x46\x1c\x89\x35\x26\x75\xba\x87\x5a\x2e\xe4\x74\x18\xb3\x09\x26\x54\x56\x93\x6a\x17\x65\x5c\x27\x68\x39\x0e\x9e\x58\x75\x5f\x2d\x01\x22\x28\x13\x71\x6c\x7d\x62\x0b\x79\x08\x5c\xfe\x28\x1c\x45\x50\x27\x64\xe6\xa5\xab\x86\x3f\x6b\x54\x4b\x43\x03\x72\xa9\xd3\x4b\x99\x90\x12\x69\xa0\xb7\xfb\xfd\x5d\xff\x23\x90\xd8\x5f\xff\x58\xe7\x47\x39\xbd\xd8\x6e\x79\x92\x71\x81\xfd\x66\x4c\x78\x1f\x26\xa5\xc2\x86\x0f\x52\x16\x52\x97\xfd\xeb\x4a\x99\x2b\xc7\xbe\xe7\xed\xcb\x75\x2d\xdf\x91\x5e\xde\x8f\x65\x44\xa4\x8e\x28\x0a\x91\xbe\x3b\x59\xf8\xd5\x35\xc2\x03\x53\x26\x39\x87\x5e\xea\x18\xf9\xc2\xf7\xef\xd5\xb5\xfc\x68\xc6\xc4\x0d\x94\x49\x6b\x6c\xff\x4a\x1e\x54\xa0\x73\xa1\x4c\x91\x38\x72\xdc\x3a\x8d\x3e\x83\x33\x3f\xd3\x27\xa2\x08\x43\x6c\x54\x3d\x17\x0b\x0b\xe3\x94\x61\x5a\xf2\x76\xbd\x99\x3c\x1a\x25\x68\x80\x6e\xdc\xc9\x5f\x57\x73\x80\x9a\x9f\xa5\x19\xcb\xfc\x5e\x79\x82\xfa\xb1\xea\x1f\x8d\x56\xc2\x41\x87\x5a\x59\xb7\xf7\xf0\xab\x1d\x85\x25\x7e\x8a\x21\x02\xeb\x8c\x75\xd5\xb9\xe2\x87\x02\x6c\xfb\xdb\x42\xa2\x81\x19\x92\x06\x44\xed\xef\x79\xf9\x6c\xaa\xa3\x4b\xe6\x8f\x23\x45\x66\xac\x2b\x0e\xdd\xc3\xfb\x0e\xea\xd3\x5c\x75\x89\x32\xe8\x6c\x86\x4f\x2f\x83\xc9\xb5\x2c\x02\x22\xe5\x09\x4e\xc5\xc7\x72\xf1\x2b\xfc\x56\x48\xee\xda\x37\xcd\x4f\x50\x4d\x3e\x14\x02\x67\xf3\x64\x82\xb8\xae\x43\xe1\x2c\x12\xbf\x40\x06\x4c\x57\x16\x68\x86\x71\xf3\xe6\xcf\xfd\x61\xfd\x70\xf7\xb8\xba\xff\xeb\xb0\xdb\xaf\x7e\xdf\x1c\x86\xcc\x25\xb3\xdc\x3a\xf4\xcd\x0b\xe8\x57\x30\x87\x59\x57\x34\x65\x36\x75\x3a\x5c\x27\x59\x3b\x45\xad\x7d\x15\xea\x1e\xb3\x67\x60\x55\x8c\xbd\x17\x8e\x23\xfc\xee\xc7\xed\x7e\xfb\x78\xbb\xdd\x3c\x1d\xb6\xeb\x07\xea\xcf\xc7\x23\x12\xa1\x80\xd5\xae\x9e\x54\x5c\x3a\x47\x2d\xf0\xa6\xfe\xac\xea\xd9\xa1\x79\x94\x11\xea\xf8\xd7\xdf\x16\x9a\xf1\x29\x27\x22\xa5\x71\xa8\xed\x9d\x4e\x45\x3e\x14\xf6\x78\xcc\x0d\xe2\xd3\xef\x56\x7f\x1e\x02\x24\x6c\xf7\xe3\xf1\xf1\xf6\xaf\x7e\x86\xa0\x58\x10\x05\x5d\x35\x1f\x4d\x0b\xc7\x49\x2a\x92\xc7\xe0\x94\x80\x9f\xaa\xff\x40\xfb\x2a\x91\xec\xb7\x1f\xf3\x14\x91\x88\x03\xc9\xf5\xb8\x43\x6b\x9e\x17\xe5\x94\x39\x47\xfb\x1e\xda\xd7\xbc\xdb\x4f\x57\xe6\xad\xdb\x07\x5d\xde\x79\x95\xd7\x13\x8d\xc4\xcf\xa1\xe1\x94\x33\x1a\x33\x27\xfc\xd2\x77\x5d\x3d\xbc\x8e\x20\x0c\xb3\x48\xf2\xbf\x69\xb8\x04\x2e\x18\x72\x04\x74\xcb\xb4\x0b\xf9\x96\x71\x81\x94\xf3\x34\xc5\xad\x3d\x20\x68\xfe\x8d\x6c\xee\x93\x85\xc1\x79\x96\xa0\x80\x01\x98\x67\x78\xcc\x9f\x8f\xe1\xa3\xf0\x3b\x09\x17\xb1\xc2\x6e\x95\xee\xf3\x74\x94\x24\x23\x9e\x58\xca\x85\xa5\x5c\x05\x62\xff\x16\x6a\xec\x5c\xad\x67\xf9\x47\x9e\x30\x97\xe1\xc4\xe8\x37\x9e\xe7\x68\x78\x92\x3a\x04\x98\x3d\x17\x9d\x83\xb4\x1c\x42\xf3\x24\x73\xec\xc9\x8e\x55\x6e\xf7\x52\x05\x3f\x9d\x27\x8a\x9a\xa0\x97\xd1\x53\x8c\x2f\x15\x1f\x67\x07\x34\x6e\x1f\x40\xed\xba\x00\x8a\x0c\x63\x10\x63\x8c\x74\x97\x97\xbb\x22\x3f\x9d\xe4\x33\xdc\x20\x69\xd8\xee\x73\xd1\xe0\xe1\xa7\x08\x65\x09\x05\xaa\x5f\x97\xde\x5e\xbf\x98\x52\xa2\x11\xd7\xd2\x1a\xc7\x03\xe2\x10\xb8\xdb\xf2\x27\xe4\xe1\x4a\x52\x41\xf1\x4a\xd6\x50\xb7\x4e\x53\x12\xfe\xae\xd9\x66\x76\x41\xa9\x26\x98\xfe\xf6\x04\x98\xe1\xc0\x99\x50\xa9\x4f\x36\xdd\xde\xfe\xe1\xf0\x8b\x31\x0f\xa3\x32\x72\x85\xc8\x16\x9a\xf6\xbe\x7a\x5f\x17\x3d\xc0\x87\x72\x49\x1c\x87\xbf\x4b\xd1\x6e\x9e\xd6\xb1\x6b\x88\x08\xd5\xc3\xe5\xcb\x90\x86\x87\x72\xe0\x5d\xfe\x0b\xcc\xae\x95\xfa\x75\xea\x27\x73\x69\x1c\xd8\x03\xc3\xaa\x5a\xb6\xf0\xe3\xf4\x89\x2f\xca\x25\x70\x6c\xcd\x7a\x82\xe6\x7c\x74\x7e\xd6\x6a\x54\x65\xe8\xaf\xd5\x4a\xce\x7a\x4f\xe8\x09\x4e\x95\x97\xfc\x9b\x7e\x34\x13\x97\x94\x2b\xe5\xea\xf7\x25\xfc\x6a\x43\x13\x52\xdf\x85\x43\xb9\xa6\xdc\x91\x68\x74\xfb\x96\xdb\xb3\x8a\xf1\xe2\xd1\xc0\x22\xe9\x85\x1c\xa7\x64\x1c\xd3\x27\xa2\x41\x8d\x52\xdd\x53\x4a\xd5\x7f\x7d\x52\xec\xe3\xda\x26\x98\x22\x7d\xcf\x4b\xe7\x25\x7c\xa5\x56\x4b\xb9\xd1\xd4\xfa\xfe\x3b\xef\x65\xfc\x13\x9d\x5e\xca\x81\x10\xfc\x64\x77\xd0\x9e\x4f\x9e\x8a\x69\x36\x83\x52\x8c\xd4\xf7\xae\x33\xa8\x33\x0d\x0d\xa6\x17\x97\x13\x48\xdc\x46\x4e\xbe\x63\xb5\xde\xde\x4c\x36\x0d\x6b\x21\xf3\x4d\x8c\xdf\xa1\x28\xaa\xc9\xa6\x2d\x22\x41\x10\xca\xba\x83\x91\x65\xf8\x2c\xb3\xb8\xf8\x0c\x44\x64\xb3\xc8\xc3\x2f\x31\xc1\xeb\xd2\x7a\x23\x4f\x5f\x90\x28\x75\xb4\x3f\x5e\xad\xbf\x69\xde\x2f\xd4\x28\xbe\xca\xdc\x0a\xc2\x58\xa0\xa7\x72\xc4\x6d\x33\xd3\xd3\x4f\xb3\xf8\xcd\x41\x89\x24\x72\x05\x7a\xd6\x5e\x4c\x86\x0a\xa2\x28\x3e\xa1\xfd\x84\x44\x70\xf1\x69\x8a\x38\xb2\x18\x01\xe2\x1a\xfc\xd9\x7d\x75\xe7\x39\xa0\x70\x72\xe6\x58\x68\x64\x8b\x59\x15\x45\x60\x57\x6c\x9e\x02\xbd\xe1\xec\xd0\x3a\xc2\x86\x1b\x69\x6d\x5e\xe4\xb2\x85\x5b\x78\x0b\xc2\x15\xdd\x28\x21\xe3\x4c\xeb\x72\xcb\x03\x15\x94\x69\x54\xee\x3b\x37\xb0\x3b\xa3\xdf\xf7\x3e\x6c\xe7\x82\x66\x14\xc3\xc2\x55\x51\xff\xa7\x71\x7d\x9b\x61\x04\x52\x3c\x7b\xa8\xe8\x0e\xe6\xe5\x72\xc9\x2e\x9f\x99\x73\xa7\xb7\xfa\x56\xb5\xd0\x6c\x5b\x38\x2e\x85\x48\x82\x27\x89\x1c\x28\x7a\xb6\x4d\x73\x46\x04\xcf\x3f\xcc\x55\x2f\xa5\x0f\xc2\x81\x81\x60\xbe\xf1\x2a\x2f\x9f\xab\xdb\xfc\xf9\xa5\xbf\x35\x91\x02\x62\xd0\x03\x83\xc7\xa8\x1e\xb3\x88\x3b\x10\x42\x5a\xf4\x29\x9f\xf6\xeb\x65\x8f\xc2\xcf\x4b\x12\x2d\x7b\xf7\x6f\xeb\x69\x01\xa6\x98\x24\x91\x48\x49\x3d\x53\x8f\xcf\x9d\x04\x6d\xc9\x30\x23\x15\x11\x22\xbe\xf3\x32\x6f\xa7\xf5\x11\x91\x89\x18\xd9\xd0\x0f\x48\x99\x88\xaa\x6a\xd3\x4f\x2c\x93\xb1\x13\x02\x74\x0c\xfd\xab\x63\xbb\xaf\x3c\x5b\xff\x7c\xa6\x8e\x51\x35\xb8\x76\x16\xc3\xed\xaa\xe1\x3c\x52\x08\x0c\x44\x0a\xd7\x13\x3a\xb9\x49\x99\xa6\xb8\x7f\x5c\x6f\xfe\x38\xdc\x6c\x82\xeb\x2b\x94\x20\xb8\x8b\x6b\x59\x9b\x18\x17\x99\x2b\x55\xb6\x43\x94\x13\xb6\x5b\xa1\x52\x8b\x26\x6b\x27\x8b\xa3\x2c\x0f\x65\x75\x94\x65\xbe\x47\x62\x92\x3e\xcf\x24\x0c\xb3\xd6\x73\xb3\xbf\x2c\x86\xa5\xc2\x24\x99\xe8\xe3\x96\x05\x41\x79\x2a\x4c\x6a\x8d\x2f\xcd\x20\xbf\xb7\x2c\x5f\xe7\x89\x17\x61\x24\xc7\xe0\xb6\x17\x6a\xa8\x9e\x67\x47\x01\x02\x9e\x1e\xfb\x78\x3a\xb7\xe0\x49\xb0\x66\x87\x01\x9a\xa2\x02\x0e\x74\xaf\x7d\xe2\xf2\x0a\x00\x86\xe2\xbc\xbb\xcd\xe6\x7a\x77\xd8\x3f\x1c\xbe\xaf\xf6\xeb\xef\x07\xd2\x79\xf6\x61\x8e\x15\x0c\x3d\xf6\x7a\x5b\xde\x9c\xfa\x3f\x1a\x1d\x41\x88\x66\x51\x2c\xa7\x7b\x55\x17\x74\x85\x54\x58\x30\x41\x1d\xca\x41\x69\x5d\xbb\x83\x99\x97\x3a\x93\x28\x92\xd6\x09\x28\x75\xaf\x47\xcb\x39\x4b\xf9\x17\xff\x84\x23\x50\x15\xae\x09\xd5\xc3\xe6\xd9\x9a\x84\xf0\x0c\xbd\xc0\xdd\x5f\x6b\x9f\xda\xc0\x56\xe9\x3e\x11\x1b\xa6\x69\xa7\x04\x9e\x37\x3f\x01\x5e\x37\xe5\xcc\xfa\x25\x04\x18\x26\x7d\x91\x59\x66\xa8\xa5\xf9\xf6\x6d\x9a\xc4\xb1\x13\xc9\xb8\x7f\xdc\xed\x17\x70\x57\x49\x1c\x2b\x4f\x79\x3d\x6e\x63\xa4\x49\xcc\x13\xe4\x6b\x70\x70\x43\x6c\x54\x1b\xa1\x4b\x97\x5c\x9c\x24\x36\x36\xcb\x02\x9b\x53\x2b\xeb\x8f\x9b\xce\xff\xbc\xcc\xe1\x25\xd4\x52\xc5\x7a\x25\x4f\xf3\x0f\x64\xcd\xa7\x29\xcf\xe9\x69\x3b\xb7\xbe\xb3\xcd\xd7\x4f\x3f\xbe\xe1\xb2\x79\x7c\x7a\xb8\xfe\xb1\xde\x1c\xc8\xef\xdb\xdb\x80\x3f\x4d\x78\x4a\x31\x89\x1c\x80\xd4\x68\x52\xc6\xfb\x7a\x22\xd2\x0c\xdf\x18\x3c\x4f\x82\xc4\x24\x11\xcc\x04\x89\x9b\x3a\x37\xcf\x70\xd7\x8b\x8a\xd3\x24\x49\x08\x49\x42\x4a\xa1\x7e\x85\x36\xb4\xeb\x86\x71\x6d\xf1\xf5\x95\x3e\x49\xb6\x1e\x18\x87\x87\x39\x86\x60\x72\x6a\xfd\x52\x55\x0d\xfc\xfc\xfe\xcd\x81\x3b\x83\xe3\x33\xbd\xdb\x94\xc7\x4a\x8c\x09\x35\xeb\x4b\x5d\x07\x9a\xa4\xd2\x31\xe0\x3f\x43\xbb\x6a\x7d\x6e\x6f\x7e\xa4\x8c\x52\xed\xc1\x0e\xdd\xe2\xbc\xf1\x14\xe6\x13\x2b\x96\xc8\xd4\x91\x3d\x1f\x7d\x74\x10\xae\x59\x11\x89\xcd\xd9\xbf\x6f\xf7\xfb\xbf\x0e\x57\x3f\x9e\xee\xc7\x5a\xa8\x34\xd1\x3c\xc5\x82\xc3\x5f\xd5\xb9\x6e\xe1\x75\xf2\x40\x75\x46\x44\xec\x52\xf5\x87\x63\x5e\x82\x39\x34\x63\xcc\x6c\xa2\xad\x0c\x10\xbf\x00\xe5\xd9\xae\x1f\x96\xb0\xff\x34\x31\x91\x93\x0f\x3f\xbe\xa2\x51\xec\xe1\xdc\x34\x31\xca\x62\x59\xee\x90\x37\x1e\x95\xb1\x52\x73\xa7\x30\xb1\x5c\xf9\xaf\xeb\xf6\xc7\xbd\x63\x4e\x0c\x23\xc2\xb5\xea\x9e\x1b\xa8\xef\xe4\x2b\x2c\xa7\xc1\xbf\x0c\xad\x12\x2b\x05\xc2\xd5\xe5\xe9\xb4\x0a\x0c\x02\x23\xf6\x00\x9a\x46\x52\x39\x9a\x16\x0c\x57\x26\x1e\x50\x4a\x32\x8e\xde\xd5\xdd\xea\xcf\xc3\xcf\xef\xdb\xfd\xe6\x76\xbb\xdb\x6f\xae\x0f\xeb\x11\xa0\x28\x25\x32\x4a\x54\xa8\x6c\x35\x6d\x75\xbc\xce\x9b\xce\xf6\xde\xc0\x27\x95\xdd\x94\x00\xc1\x0c\xf2\x5b\x90\xfc\xef\x1e\x8c\xbb\x6a\x27\xcd\x8d\x24\x07\x2e\x7b\x3a\x12\xbb\x9b\x1d\x85\x8a\x88\xfa\xf3\x22\x5b\xcc\x77\x59\xd8\xdb\xdc\x8e\xa8\x34\x68\xca\x44\x94\xb0\xd0\x28\x05\x6f\x79\x75\x6e\xae\x65\xfd\x5a\x56\x06\x96\xb9\xa8\xba\x9f\x58\x84\x52\x37\x2f\x55\xdd\x0e\x3d\x1a\x34\x65\x86\x63\x92\xf4\xea\x5c\x96\xe3\x2a\x4b\xca\x33\x81\x39\x98\x5e\x99\x64\xf1\x4d\x74\x41\x29\xf3\xd9\xae\x1f\x79\xd9\xce\x64\xd4\x3f\x71\xc7\x27\x06\x3d\x15\x3c\x76\x7d\x2a\xc6\x84\xfa\x69\x2f\xfb\xf2\xdb\xec\x6c\x16\x22\x33\x4e\x67\xef\x03\x43\xe0\x74\xf9\xa5\x89\x48\x12\xbf\xef\x3e\x9e\xd5\x48\xfd\x60\xf6\x5c\x12\x43\xb1\xb9\xd0\x39\x40\x93\x5d\x33\x4d\x45\x16\x80\x6f\x0e\x5c\xbe\x87\x79\x0d\x3e\xcd\x98\xd4\x74\x40\xee\x38\x4b\xd5\xad\xea\xda\x65\xd5\x3e\x07\x43\xf8\x03\x48\xeb\x0a\x38\x63\x26\xa2\x4b\x53\x9c\xaa\x58\x82\x09\xc4\xa5\x0b\x61\xeb\xe5\x9d\xa9\x44\x65\x59\x48\x65\x55\x36\x6f\x9f\xb0\x1e\x3c\x9b\x94\x59\x04\xed\x9d\x64\xb7\xa5\xfc\xa8\x8b\xc5\x54\x65\xaa\x29\x4f\x5d\x35\x1c\x79\xc6\x9c\x13\x7e\x35\xca\x04\xa4\x9a\x3a\x76\x80\x20\x5b\xbb\x9d\xd7\x66\x52\x9d\x45\x48\x01\x86\xa9\x9f\xc6\x13\x8c\xad\xab\xa3\x2f\xe2\x6e\xcb\x47\xa8\x75\x7f\xb8\x8c\x47\xbd\x18\x62\x5e\xbe\xc9\x22\x77\x69\x35\x4f\x76\x1b\xa6\x99\xd8\xb8\x12\xe1\xa3\x3c\xf7\x3b\x7b\x6a\x88\x32\x3d\xf9\xed\xd5\x59\xa9\x02\x76\x55\x7d\x81\x09\x4e\x0d\xe5\x18\xda\xaa\xf3\xc7\x9f\xa5\x3c\xce\xf0\x02\x29\xf8\x8e\xe0\x2e\xf8\x77\xa9\xb0\xa8\x1f\xe1\x0e\xf9\x53\x61\xf5\xfd\x93\xb4\x5b\x6a\x09\x60\x23\xf6\x63\xf5\xfe\x5f\x55\x39\xd9\x13\xb3\x28\x8b\x31\x38\x18\x2a\x44\x0f\xe5\x27\x08\xb5\x2c\xca\x0c\x2e\xe6\x4d\xfb\xb2\x96\x65\x29\x55\x3e\x33\xd6\x59\x24\x99\xc3\x67\x23\xf9\x8d\xff\x88\xbe\xe6\x63\x99\x04\xb1\xe1\x91\x64\x24\x4b\xd1\x53\x6c\xf3\x23\xdc\x82\xed\x9c\xf7\xaa\xec\xde\xc2\x48\xdc\x99\x66\x71\xec\xda\xe0\x76\xeb\xfd\x9f\xfd\xdf\x68\xcc\xd3\x19\xf6\xd8\xf5\x9a\x06\x52\xf9\x85\xe0\x2b\x8b\xb9\xee\xfd\xc6\xaa\x3a\x86\x26\x8e\xe9\xfd\xc7\x49\x82\x19\xdb\x7b\x78\x91\xc5\xc8\x46\x65\x71\xaa\xad\xcf\x7f\x2e\x01\x48\x32\x9a\x44\x58\xb6\xf5\xfa\x59\xbd\x24\x14\xcd\x98\xd6\x99\x70\xc6\xba\x5b\x7d\x58\xd1\x5f\x8c\x97\x33\x4e\xb2\xe0\x7b\x39\xf4\x51\x5e\x3e\xff\xcc\x4b\x53\xbd\xdf\x60\x4d\xfb\x35\xe8\xe5\x86\xf9\x46\x47\x62\xd4\x2e\xda\x39\xcb\x7d\x1d\x3a\x4c\x4a\xa8\x13\x42\xc4\x38\xed\x80\x04\xe2\x1e\xc9\xb9\x68\x25\xb2\x44\xf8\x26\xd5\x6e\x99\x4f\x69\x4f\x68\x96\x24\x19\xa2\x02\xa5\x31\xee\xf3\xb8\x34\x9c\x59\x6a\xe4\x08\x82\x3c\x74\x60\xdd\x54\xf5\xef\xf0\xe1\xf6\xa7\x70\xbc\xd4\x2a\xe3\x02\x7b\x80\x9f\xb2\xfd\xa4\xf5\x89\x66\x52\xe9\xc0\x18\x79\xeb\xc8\x9b\xcd\x05\xd0\x7c\x52\x9c\xc9\x54\x46\xb4\x27\x34\xb9\x72\x16\xf7\x52\x2b\x9d\x66\x0a\xa2\x50\xc2\xb9\xad\x64\x79\x93\x17\x45\x4f\x46\x39\x7d\x37\x86\xc5\xc2\xd9\x25\x5d\xd5\x66\x5f\x7d\xd6\xe4\x36\xbb\x70\x93\x38\xf2\x78\x64\x57\xad\x77\x1f\xc7\xa1\x46\x96\x01\x71\xea\x73\x2e\x1b\xe0\x50\x11\xbb\x53\x5e\x0e\x35\xa4\xe5\x64\x43\x06\x99\x53\x36\x96\x05\xd4\x4e\x95\xbf\xba\x58\xc8\x96\xcb\xc0\xea\x3f\x5b\x35\x36\x31\x01\x29\xea\xe9\xcf\x27\x95\xfc\xcc\x4a\xa7\xe7\x93\xf7\x32\xec\x63\xaf\x54\x46\xa9\x93\xdf\x7f\xac\xab\xe6\x04\xf5\xe3\x08\xaa\xf1\x0f\x1a\xb5\xfc\xc7\x28\x29\xe5\xf8\xe2\xd7\x35\x98\xbc\x5d\xcb\x7a\x6c\xb1\x24\x96\x71\x3d\xdc\xcc\x27\x78\xe7\x52\xa7\x54\x32\x66\xd1\x32\x60\x89\x12\x71\x34\xd3\x97\x2b\x99\x48\x75\x48\xde\x3f\xcb\x36\x70\x05\xce\x51\xa2\x92\x25\x14\xfd\x0a\x5b\x54\xb2\x9d\xac\x4f\xc9\x12\x89\x2d\x92\x9b\xf6\x65\x0f\xf5\xf1\x3a\x88\xe3\xf9\x61\x41\x24\xd6\x52\x11\xbc\xdf\x6d\x36\xf3\x32\x83\x14\xa9\x45\x9f\xe7\x1e\x9e\xff\x21\xb6\x54\x0a\x10\x98\x9f\xbf\xae\x4a\x74\xec\x76\x50\xb6\x57\xe7\x2e\x1a\xbb\xae\xce\xea\x33\xf5\x04\x2a\x93\x84\xd3\x68\x10\x83\x70\xc8\xde\x30\x96\x2a\x4c\x80\xdc\x7d\x4c\x5b\x92\x64\x62\x13\x96\x0d\xba\x7d\xb9\x74\x3d\xa9\x41\x41\x60\x7a\x86\x34\x71\x5c\xdf\x4e\x8a\xf0\xc1\x5e\xc9\xe7\xfd\xc7\xa9\x2f\x2d\xcb\x34\x15\x48\xdb\x61\xb1\x0d\xf5\xaa\xce\xf5\x45\x86\xf0\x13\xdd\xac\xd1\x39\x52\x27\xa7\xaf\xce\x1f\x23\x58\xbe\x4c\x4d\x86\x21\x82\x0c\xad\xd0\x03\xe3\x4c\x98\x92\xc5\x36\xe0\x53\x56\x6f\xb2\x95\xf5\x65\xee\x40\xca\x34\xc1\x16\x4a\x54\x1a\xfb\x86\x6d\xd2\x43\xd1\x5b\x2a\x9e\x61\x49\x6e\xf3\xb8\x1b\x99\x7e\xa9\x52\x1e\x79\x3f\x79\x8a\x06\x09\x9f\x8c\x54\x52\x61\xd1\xeb\x3d\xf0\x00\x1f\xa4\x31\x1f\x73\xce\x45\x2a\xb5\x8a\x30\x96\x58\xbf\x80\xdd\xae\x43\x58\x2b\xb5\x49\x94\xd3\xf3\xca\x8b\x5e\x63\x8a\x4a\x88\x45\xe6\x1b\x47\x10\x1f\x3d\xf9\x44\xc0\x6a\x19\x8d\x52\x96\xfb\x17\x68\x2f\x29\x05\xa8\xb4\x09\x77\xfc\xec\xce\x08\x5e\x83\x34\xb7\x3d\xc9\x15\x55\x11\x35\xc8\xd8\x74\x21\x4a\x39\x7d\x2d\x2a\x82\xd4\xf8\x6a\xe5\xd7\xce\xa0\x22\x84\x59\xcf\xf8\x75\xf7\x31\xae\x78\x2a\x12\x03\xde\xcf\xd5\xb4\xa2\xaf\x48\x46\x53\xff\x0b\x04\x86\x2c\x11\x85\x84\xa9\x9a\xc7\x7e\xb9\xee\xf2\xde\xf5\xc7\xb5\xe5\x73\x25\x2a\xe6\x8c\x0f\x0a\xc8\x8f\x55\xdd\xda\xaa\x98\x7b\xa3\x8a\x92\x14\x91\xf8\xab\xed\xc3\x2e\x5c\x07\x4d\x84\x23\x50\xef\x76\xca\x5d\x2b\xdb\xf3\x45\x88\xb3\xd8\x26\xa3\xa8\x94\x6c\xbc\x0f\xaf\xfc\xf7\x31\x7d\x15\x8a\x47\x06\xad\x05\xbc\xfd\x9e\xeb\xd7\xca\xda\xaf\xf7\x0e\xc5\x49\x2c\xfc\x73\xf9\x03\x30\xc3\xb2\xd0\xf1\xa6\x84\x4e\x02\xb5\x5f\x90\x8a\x29\xe4\xf3\x28\x86\x53\x42\x3b\x09\x2e\x1f\x38\x3c\x42\xed\xfc\xe9\xe9\x71\x12\x93\x69\x8f\x50\x19\xbf\x9c\xc4\x1a\xf4\xb5\x3a\x97\x09\x19\x4c\x42\x02\xd9\x5b\x72\x95\x92\x18\x4b\xe0\x75\xfc\x47\x68\x79\x0c\xbf\x4d\x33\x2d\xfc\x1e\x34\xc2\x0d\xae\xda\x69\x9f\xd8\xf4\x32\x52\x09\x2e\x51\x93\x1f\x8f\xb0\xef\x6e\xfb\xb3\x40\x53\x65\x49\x8a\xc4\x87\x27\xf4\xe4\x5c\x2b\xf1\xf4\x89\xcb\x58\x63\x5a\x75\xe8\x34\x80\x41\xff\x76\x39\xca\x54\x4a\x48\xe1\xdd\xc4\x23\x1c\x6b\xf8\x77\x73\x49\xf4\x4c\x95\x26\x02\x79\xc0\x65\xdd\x0e\xbe\x96\xd2\xa9\x40\xb0\x07\x22\x5c\x77\xed\xf9\x94\x9b\x9b\xe2\x6c\xed\xc7\x63\xee\xa1\x58\x21\xa5\xa7\xb4\x75\xb4\x3e\x4a\x99\xc9\xf3\x36\xb1\xc0\xfc\xab\x23\xea\x77\x86\x6c\xe7\x2c\xfa\xec\xe6\x8c\x00\xc4\xd9\xf6\x12\xe8\x55\xfd\x17\x74\x71\x7c\x7f\x28\x29\x03\x31\xbb\x73\x76\x43\x96\x7e\x12\x7b\x2a\x63\x2c\x3a\x88\x2f\x55\xdd\xf4\xb6\x5c\x19\xab\x90\x76\xc3\x37\x1b\x8f\x1c\x08\x65\x05\xc5\xa2\xf8\xc9\xb3\x93\x40\xbe\xf1\x92\x2d\xd3\x67\x64\x13\x32\x16\x5f\x7e\xb0\xfb\x17\x08\x65\x88\xa0\xa4\xdf\x1f\x33\x61\xe0\xed\xcb\xef\x7f\xad\x17\x3f\x8c\x59\xcd\x43\x59\x9b\x88\x89\x9f\x79\x97\xeb\xba\x1a\xe9\x4e\x51\x1d\x65\x90\x0c\x5a\x77\xf7\x81\x00\x4c\xb0\x49\x1b\x1a\x19\xd3\x3f\x53\x1d\x19\x9a\x06\xff\xa8\xa8\xda\xed\x27\xfb\xad\x26\x4c\x79\xe0\xf4\x5b\xf5\x0a\xc8\x2e\x16\x46\x78\x86\x06\x0d\x79\x8e\xbb\x78\xb8\xdb\x36\x9a\xbe\xe2\xa0\x89\x8d\x30\xc2\xee\x22\x9f\x2b\xb0\x55\x0d\xbe\xe0\x1b\x26\xc4\x34\x45\x1c\xec\xe3\xc3\xdd\xfa\x61\x7b\xdf\xff\x39\xa1\x08\xfe\xbc\x86\x37\xd7\xa0\x7e\xf0\x6c\xdc\xa6\x9f\x91\x71\xbc\xa6\xc7\x1f\x57\xb7\xdb\x35\xa2\x91\x7f\xec\xae\x0f\x8f\x9b\xa7\xc3\xdd\x6e\x73\x1f\xda\x04\x35\xa5\xd2\x35\x2d\x9d\xd5\x31\x0f\x9a\x1b\x8b\x56\x48\x53\xee\xa4\x72\x74\x75\x3c\x15\xd0\x42\xaf\x22\xdd\x1f\x4b\x70\x7c\xcd\x9b\xe3\xa9\xaa\x61\xc2\x20\x44\x35\x4d\xa8\x93\x77\xae\x8a\x37\xd8\xcb\xe6\xf5\x93\xb3\x70\x91\x21\x96\x0d\x1b\x90\x7f\xf6\x7b\xaf\xe6\x26\x45\x60\x43\x51\xb9\x2c\xd7\x83\xfd\x6d\xd2\x3a\xe8\xa7\x09\x9a\x61\x0d\x07\x23\xfe\x27\x68\x5c\x98\x00\xc6\xdf\x59\x98\xe5\xfb\x06\xfb\xce\x23\x54\xe0\xfa\x7a\xe7\xd3\xc2\x70\x34\x80\xbb\x2e\x20\x6b\xae\xa0\xfd\x6d\x09\x58\xa3\x05\x90\x28\x10\x5d\x86\x1a\xa6\x4b\x39\x0c\xc0\x00\x2d\xc0\x22\xcd\x93\x7b\xec\x8b\x6a\x5b\x8b\xc9\x72\xff\xf3\x94\xc4\x88\xc1\x79\xac\xaa\x22\x90\x7e\x86\x43\xa7\xa9\xa3\xbc\xef\xbc\xf6\x61\x3d\xa4\x9a\x46\xd0\x4b\xdc\xdd\x55\x06\x50\x71\x0a\xd9\xc6\xfc\x94\x4c\x12\x7c\xc2\xb2\xc0\x67\x0c\x64\xcc\x37\x1f\x26\x49\x26\x10\x9c\x7f\xa8\xde\xcb\xe6\x8b\x66\x57\x2d\xb9\x73\x65\x30\x84\x6d\x65\x5e\xb8\xca\xf7\x4c\x73\x88\x6a\x99\x38\x34\x7f\x5f\x66\xb8\xd0\x9a\xa7\x5a\xa6\x02\x45\x32\xcb\xf3\x2b\xac\x4e\xa7\xfe\x56\x65\x66\xd0\xdb\xaa\xca\x7b\x78\x0f\x28\xe8\xcf\xb8\x6e\xc2\x6f\x0c\x10\xa7\x94\xb5\x1b\x15\xd0\xc2\xa0\x8d\x4c\x0f\xa1\xad\x3e\x16\x2a\x2c\x5a\x45\xd2\xfa\x12\xc1\x55\xb7\xfe\x56\x75\x2d\x3f\x7c\x1e\x78\x12\x28\x6a\x15\xab\xd0\x4d\xef\x75\x6b\xbd\x2c\x60\xbf\x4d\xe8\xce\xfb\xc8\x1c\x3f\xe7\x7f\x4d\x1e\xb3\x52\x1a\x13\xf5\xb9\xae\x70\xaf\x0d\xdd\x7d\x5a\x13\x82\xa9\xda\x17\x97\xdd\xbd\x54\x71\xa2\xda\x10\xe1\x80\x6e\x2e\x46\x09\xb0\x39\x6d\x62\x8d\xe6\xdd\x55\xc9\x6e\xaa\x1a\xb4\x6c\xda\x0b\x75\xad\xc9\xbf\x24\xdc\x8c\xe1\x20\x89\x6f\x8b\xb9\x3a\x37\x8e\xf0\x6a\xc6\x60\x39\x7b\xd2\x26\x13\x58\x3f\xfe\xf3\x6a\x0f\x13\xe2\x07\x6d\xa4\x44\x8d\xb0\x63\x65\xa0\xd8\xf6\x6b\xd4\x68\x86\x6e\xd7\xd9\x71\xd0\x5c\xca\x1c\x84\x3d\x53\x03\x49\x32\x08\xc1\x34\x5e\xc3\xdd\x88\xe5\x28\x4c\x4a\x58\x1c\x07\xff\x73\xf3\xfc\xdc\x2f\x1b\xcb\x1d\x11\xfb\xe3\xb9\x94\x65\x3e\x61\xf8\xd0\x56\x19\x11\x74\x41\xab\xe3\x49\x96\x1f\x23\x46\x14\x6d\x0d\x63\xda\xc7\xfe\x6f\x50\x1f\xce\xa5\x6f\x61\x39\x28\x68\x87\xe3\x5b\xb0\x1e\xcf\xe1\x5b\xf5\xa7\xe4\x92\x6e\x9a\x89\x48\xea\x1c\xf7\x10\x2b\xdc\xa1\x1c\xef\xf4\x6d\x9a\x08\x00\x21\x44\xe7\x06\x6a\x5c\x0a\xb3\xd7\x6d\x08\x71\x74\xd5\x2a\x2f\x77\x5a\x5e\x2c\xff\x30\x8b\x65\x81\x09\x7b\x5d\x39\x1a\xa9\xf9\x71\x14\x24\x03\x57\x76\x17\xca\x3f\x8e\x2a\x97\x26\x66\x92\x7b\x34\xb4\x5b\x40\xf3\xdf\xd3\x18\x02\xf3\xe2\x20\x73\x15\xc6\x24\x0b\xe8\x2b\xb4\xeb\xdd\x1e\x39\x4f\x54\x18\x16\x27\x18\xee\xe6\xba\xda\x55\xc5\x44\x92\x8a\x1a\x96\x70\x8c\xc8\xbe\x9f\xcf\xe7\xf3\x51\x96\xbb\xff\x95\xfc\x7b\xf7\x7b\x9b\xfa\x64\xc5\xff\x38\x11\x10\xd3\x1f\x5a\x25\xee\xd1\xb4\x08\xc5\xf8\x29\xf3\x36\x2f\x9f\x9f\x60\x2c\xe2\xe6\xa7\xf2\xc4\xb5\xb3\xee\x4e\x52\xc3\xba\x96\xb6\x5d\xf7\x5c\x72\xd4\x08\x96\x61\xca\xb4\x97\xdf\xbb\x46\xb0\xe0\x27\xf9\x35\x23\xa4\x41\xb1\x2e\x89\x09\xcb\xaa\xfe\x78\x28\x5d\xbf\x93\xaa\x64\xed\x03\xcb\xb0\xe2\x8d\xd0\xd2\xf7\x86\x75\xf6\x1b\xef\x3a\x10\xfa\xcc\xae\x51\x80\x6b\x0f\xbf\xdd\xde\x6c\x6e\x1e\x9e\xee\xfa\xab\xb3\x12\x4b\x8d\x4f\xf0\x7c\x2e\x64\x3d\x4b\xe8\x99\x24\x16\x46\x04\x6e\x85\xfe\x8f\x89\x4e\xbc\x9e\x5d\x7b\xf1\x03\x65\x75\x20\xfc\x9e\xc0\xef\x2f\xd0\xab\xe1\x07\xda\xd9\xb4\x10\x1c\x2d\x9b\x0d\x93\x32\xc3\x86\xd2\x6e\x0f\xa9\xc4\x6d\x61\xf2\x4a\x53\xe5\xd4\xea\xf2\x66\x0f\xf2\xe8\xc5\xe6\x5c\xee\x62\xd8\xf8\x4c\x06\x51\xe2\xa2\xa2\x52\xef\x86\x56\x29\xa3\x22\x8e\x8c\x8d\x21\x6c\xee\x5c\xa9\xce\x47\xe8\xc7\x63\x86\x8c\x07\x8e\x69\xfc\x7c\xfc\x89\xe5\x8f\x30\xc8\x29\x66\x18\xd0\xcb\xd8\x41\xbb\x96\xe5\x5d\x8e\xa4\x97\xc3\x26\x6d\x54\xe2\x44\x20\xae\xb6\xf7\xbf\x6f\xfe\xea\x7f\xaa\x62\x04\x0a\xdc\xad\xfe\x3c\x6c\xf6\xdf\x11\x4e\x1c\xc6\x34\x95\x2a\x1e\x4b\xe9\xcf\xd2\x06\x46\x27\x8e\xd1\x20\x3c\x42\x4c\xf9\xe5\x55\x39\xf0\xb3\x51\xa3\xbb\xe0\xc3\x6b\x59\xe3\x86\x7a\x05\x28\xe3\x36\xef\xb3\x33\x26\x75\xfc\xbe\xee\x41\xff\x1c\xac\xd0\xe9\x34\x6a\x5d\x1a\xb1\x92\x8c\xee\xcd\x68\xa2\xa2\xa0\xe3\xba\xff\x3e\x3b\x32\x50\x86\xdb\x68\x7e\x3c\x15\x07\xd7\xa9\xfc\x84\x9a\x99\x9f\xbc\x72\x10\x76\xc4\x93\xf2\x1d\xea\x6a\xec\x5a\x91\xc0\x15\x11\x66\xa7\x31\x46\xb1\x35\xbc\x81\x33\x25\x33\x30\xe5\x92\x06\xe0\x3c\xc5\x6e\x40\x45\xa8\x1f\x77\x0b\xc7\xaa\xdc\x41\x61\x11\x39\xdd\x0f\xa6\x98\x90\xdd\xed\x57\x4f\xfb\xc3\xee\xf7\x07\x72\xf8\x71\xbf\xdd\xef\xfa\x71\x93\x62\x41\xfe\xee\xe3\x5b\x51\x29\xf8\x82\x90\x3b\xfc\xc0\x6a\x12\x0d\x11\x7c\x55\x5f\x7d\x2c\x56\xc0\x0d\x58\x83\x88\x98\xd5\xd9\xb4\xff\x4b\x1b\x07\x51\x2a\x8d\xcf\xc9\x0f\x44\x66\xe1\x86\x21\xca\x84\x57\xed\x0f\xdc\x7c\x8f\xb2\x69\xe6\x93\xb4\x70\x89\xbd\x2e\x7c\xdc\x57\x57\xe7\x7a\xe6\xff\x40\x64\x2c\x3a\x80\xb7\xf0\x06\xb5\x0c\x9c\x6c\x14\x88\x72\x1d\xd3\xab\xc9\x8e\x09\x04\x54\xea\x9b\x35\x77\xb9\xed\x8d\xc8\xe2\xcd\x43\x1c\x31\x8c\xe3\xbd\xfc\xdc\x58\x6c\xef\x5f\xf3\x99\x36\x4b\x02\xe5\x53\x55\xa8\x8f\x6f\xed\xc7\x09\x7e\x1b\xb2\x11\x10\x27\x8e\xb1\xe4\xbd\xaa\xcc\x7b\x55\xbf\x36\xeb\xbc\xcd\xe7\xa8\x09\x88\x81\x63\xf3\xee\x37\xd7\x39\x53\xce\x63\x6b\xa0\x34\x46\xbb\x7b\x2b\x9b\xf6\x80\xa9\xb3\x83\x03\x7f\x1c\x64\x69\xdc\x1f\x5e\x64\xf3\x72\x38\x0f\xb1\x17\x50\xe0\xd8\x0f\xf1\x13\x5e\x83\x67\x09\x8c\x68\xe4\xf3\xfa\xbd\x6a\x8b\xbc\xdf\x7b\x80\x69\x27\xf3\x7d\xaa\xab\x6e\x13\x08\x5d\x51\x01\x35\xb4\xb8\x97\x83\x20\x31\xf2\xb2\xa1\xb0\xd4\xec\x7a\x85\x76\x4e\x1e\x7a\x46\xd3\xf4\x46\xb0\x22\xdd\x1c\x5c\xfa\xbb\xb6\x3a\x8d\xfd\x32\x48\x62\x8d\x6f\xbf\x75\xe4\x4f\xed\xf7\xea\x08\x58\x7f\x0e\xe3\xcc\xb2\xa0\x15\xfe\x58\xc3\x49\xe6\x66\xd3\xbe\xec\xdf\x61\x94\x0b\xfc\x1c\x44\x05\x89\x90\xe8\xae\x3b\x14\x91\xa7\x43\x02\xe3\x1a\xf9\x66\x0b\x31\x91\x0e\x91\xa2\xbb\xc8\xc9\x65\x03\x27\x60\x0b\xc8\x08\x4d\x83\xf8\xc8\xfa\x61\x89\x39\x93\x42\x16\xa7\x42\xf4\xad\xd9\x79\xf9\x3c\x62\x01\xf4\x53\x64\x44\x89\x4f\x89\x3d\xe5\xed\x59\x16\x17\xe5\x05\x90\xa9\x49\x3c\xfb\x8e\xcf\x35\xfb\xb4\xc9\xf4\xc9\x2b\x9a\x60\x85\xa0\x8b\xbb\xd6\x2f\xb2\x7e\x86\xff\x73\xbf\x5f\x2c\x6d\x83\xe2\x32\xf4\x6e\x5e\xcb\x56\x1e\xe2\x00\xc2\x05\x4d\x09\x1e\x64\xbf\x20\xba\xd8\x8d\x5a\x9a\x0e\x84\x89\x57\x34\x9e\x3d\x35\x13\xa7\xc2\x51\xdc\x8e\x2d\xc7\x02\x6a\xd4\xcf\x07\x91\xa0\x46\x41\x1f\x07\xdf\x78\x99\xf9\x8b\xbc\xcb\x28\x2f\x62\x23\x92\x20\x0b\x5e\x2b\x5f\xa1\x1e\xba\xc0\x6d\x9c\xd1\x24\xee\xf5\x91\x7f\xe6\x48\x03\x3d\x71\xe3\x6c\x9c\x31\xe9\x21\x12\xfd\xce\xde\x2d\xc3\x30\x4e\x8d\x53\x74\x44\x27\xd4\xbf\xad\xe9\xeb\xb0\x8c\x70\x4c\x73\xc2\x2f\xd0\xe7\x16\xae\x41\xcb\x8f\xa0\xe9\x36\x47\xb4\x7d\x95\x9f\xb6\x4c\xc8\x50\xf2\x7b\xac\x8a\x5c\x7f\x4c\x08\x17\xc2\xa4\xd4\x22\x70\xae\x1e\x24\xae\xa9\x65\x5a\x21\x9a\xe8\xdb\x10\xd9\x7d\x9c\xa0\xd7\xb0\x9a\x1e\x81\xa7\x16\x3d\x57\xb7\xb9\x85\x2e\x85\xbf\xe1\xe9\x99\x1e\x42\x68\x81\x6d\x32\x27\x6f\x17\x02\x93\xd8\x7c\x56\xc2\x3a\x5b\xf2\xfd\xdb\xf8\xa3\xb6\x49\x94\x21\xa6\xcd\x9d\xff\x9f\x76\x6f\x4c\x4d\x8e\x4d\x22\x2b\xba\x87\x6e\x4a\xc9\x67\xa7\x4d\xa8\xa4\x03\xd7\x74\xdf\x91\xff\x95\x3d\x98\x7c\x0d\x36\x11\xa1\x93\xd2\xb1\x26\xde\x9e\xf5\xeb\x87\x83\x2c\xcd\xcc\xb5\x4d\xb5\x40\x58\x77\x8b\x9a\x49\x0d\x89\xa2\xd7\xd3\x28\xce\xb0\x59\x22\x62\x6c\xf6\x0b\x5d\x58\x23\x3f\xdf\x66\xa9\xab\xee\xf5\xd4\x15\xab\xa2\x78\x02\x1f\xc0\xdd\xf7\xd9\x52\x9b\xa5\x92\x7b\x8c\xb9\xc9\xcb\xe7\x11\x7b\x9c\xcd\x32\x10\xae\x99\xd1\x9e\x4b\x13\x48\xab\xbf\xec\xb6\x1f\x2e\x5e\xa5\x22\x28\x63\x7f\x93\xc7\xa9\x39\xb3\x1a\x52\x6c\xfe\xf3\xc4\x43\xe5\x33\x14\x6b\x59\x9b\x1d\xd4\x61\xd3\x4a\x27\x87\xf5\x99\xcb\x74\xec\x21\x85\x60\xc1\x1a\x9a\x20\xcd\xed\xfa\x45\x96\x25\x14\xf7\xf0\xfe\xb7\xaf\xfd\xeb\x05\x68\x84\x42\x57\xd6\x65\x38\xb1\x77\xc6\x25\x20\xd6\x8e\xac\x74\x69\xdd\x03\x75\x6a\xef\xbd\xb7\xe1\x9b\x19\xa7\x36\xcd\x82\x31\x11\x09\x35\x35\x44\xbb\x5d\x8f\x62\x9a\xd0\x76\xc6\xa2\x88\x69\x0c\x21\x27\xc8\xfc\x2f\x33\x76\x2c\x22\x1e\x42\xd4\xf4\x3c\x32\x98\xbd\xfe\x64\x72\xa2\x1d\x02\x01\x9a\xf6\x70\x55\x95\xe6\xb1\xea\x76\x27\x2c\xb8\xde\xc9\xff\xa9\x10\x4d\x1e\xe6\x66\x4e\x69\x09\x65\x25\xf1\x8d\x75\x3b\xc3\xa3\xac\x51\x70\x20\x4c\x92\x02\xdb\xee\x1b\x69\x61\x07\x33\x5e\x7a\x16\x11\x9d\x21\xa3\xc0\xf6\x7e\xff\xb4\x79\xdc\x5e\x3b\xd2\xea\xc3\xfe\xfb\xd3\x66\xf7\xfd\xe1\xf6\xba\x3f\x8c\xb5\xdc\x99\xc4\xa2\xf0\x59\xcc\x05\x9e\x85\xd9\xcd\xc4\x51\x8a\x10\x97\x3a\x7f\x7e\x69\x49\xfc\xdb\x6c\x94\x72\x3d\xd0\x20\xec\x6b\x69\x2e\xec\x82\x9f\x49\x23\x48\x7c\xe0\xbe\x75\xe0\xab\x27\x78\x83\xf2\x0c\xeb\xf0\x11\x99\xd9\xb1\xa9\x50\xc2\xe7\xef\x6f\x00\xbc\x09\xdf\xc3\xb8\x51\xb0\x9f\xa9\x59\x48\x0a\xd4\xd8\xf8\x1f\xa0\x14\xd7\x18\xcb\xe1\xa2\x1a\x89\x51\xb0\x88\x42\x2c\x95\x07\x47\xf9\x96\xfa\xfd\xfe\xa7\x43\xbc\x18\x3a\xcc\x82\xd8\x27\x32\xb6\x37\xbb\x4f\xde\x36\x4b\xa5\xe4\x33\x69\xc7\xaa\xfe\xb1\xbb\x9e\xbd\x25\x9e\x30\x50\x41\x17\xd5\xd3\xe9\xcb\x8f\xea\xfc\xb9\xd2\x57\x1f\x25\xb1\x48\x58\xa9\x7b\x2e\xea\x4b\xd3\xd7\x4d\x50\x78\x43\xf7\xa0\x5b\x59\xf7\x3b\xe2\x3f\x25\x02\xf3\x47\x49\x98\x46\x77\xe2\x4e\xfe\x1a\xaa\xd5\x2c\x4a\x64\xe2\xdd\xc4\x26\xd7\xc3\xb1\x3f\xb3\x00\x53\x0b\xfd\x95\x29\x63\x51\x9a\xa4\x4e\xf9\x0d\xa9\xf4\xdd\x72\x5c\xac\xd4\x84\xf9\x9a\x22\x1d\xe8\xf7\xed\xef\x9b\xfb\xbf\x8d\x64\x58\x94\x5a\xd7\x8b\x84\xec\xb7\x07\x35\xa1\xbf\x65\x51\x16\x31\xe6\xdc\xa0\x45\x54\x2c\x8b\x32\x41\xb4\x93\x7c\xf8\x9f\x73\xd3\x22\xda\xbd\x71\x7e\x82\xeb\xf7\x98\xcd\x4e\x8c\xd3\x81\xab\x9a\xb6\x6f\x7d\x64\x51\x96\x11\xdc\xf9\x1d\x83\xee\x54\xa0\x92\x45\x92\x38\xed\xbb\xdd\xe6\xab\xe6\x18\x16\xc9\x44\x62\xae\xf1\x5c\x62\xac\x80\x0d\xf4\xbb\xce\x71\xea\x0f\x94\xc5\xc2\x91\xd3\xcf\xd8\x79\x59\x24\x8d\x42\x77\xef\xea\x5c\x14\x48\x6f\x38\xda\xd7\x59\x64\x62\x86\x05\x7b\x03\x0d\x36\xf0\x82\x71\x50\xb1\x61\x5c\xa2\x9f\x84\x66\xe5\x76\xb3\xdb\x85\x01\x4b\x32\x2c\x10\x20\x5b\xe1\xf2\x03\xb4\xa9\xeb\x55\x2f\x2a\x69\xee\xa0\x91\xf3\x24\xb1\xcf\xed\xa4\x3e\xa4\x60\x24\x22\x31\xf6\x25\xa3\xf1\x7c\xab\x5a\xd8\x9d\xe4\xf1\x98\x97\xcf\x37\xa1\xd8\xc5\x08\xe1\x02\x9d\xcd\xc7\xe2\xdc\xca\x12\x82\x1c\x24\x23\x44\xa5\xd6\x75\x66\x3b\xb4\xb3\x7c\x1b\xfd\x48\x53\x34\x27\xf2\xcd\x79\x92\x45\xd5\x34\x63\x9b\x40\x62\xcf\xc5\x1f\x72\x26\xdf\xb1\xc3\xe1\x22\xab\x3d\xf9\x62\x48\x0c\x24\xf2\x08\x91\xff\xaa\x8e\x2a\x87\x79\x2a\xdb\xcf\xa3\x52\x60\x3b\x98\xcb\x89\xfa\xc2\xc8\xd0\x10\xc0\x48\xe8\x56\xe8\xbe\x2c\xba\x42\x82\xd6\x5e\xfa\x84\x11\x26\x1c\xbb\x09\x8a\xed\x9d\x40\xfb\xf2\xe9\x72\x81\x8d\x11\x96\x38\xa3\x7d\xea\x42\xab\x1a\xf6\x95\xeb\x6b\x7c\x74\xb1\x61\x7f\x50\xe9\x84\x3f\x30\x48\xbb\xed\x93\x75\x8c\x30\x93\x61\xe8\x57\xca\xd3\x6b\x5e\x8e\xf2\xaf\x8c\x70\x4e\x02\xd3\x72\xe7\xa9\xfe\x36\xca\xa7\x30\xc2\x65\x84\x52\x07\x27\x57\x13\x47\x22\xa0\x73\xd9\x4e\x0e\x20\xe2\xd4\x92\x9e\x15\xcb\xb1\x8a\xb8\xa4\xdf\x42\x2c\xc4\x88\x10\x02\xa3\x66\x27\x5e\x3f\xcd\x1c\x32\x22\x32\x57\x7d\xbb\x85\x5f\xf9\xb8\xba\xd4\x8d\x24\x08\xd9\xf8\xb9\xba\xbd\xdd\xec\x0f\xab\xeb\xeb\xa7\x30\x94\x28\x8d\xb1\xdc\x1f\x1b\xc4\xcd\xef\x37\xab\xbb\xc3\xea\xfa\x8f\xed\xee\xe1\x69\x77\xd8\x7d\x5f\x3d\x6d\xfa\x99\x96\x19\xe5\x15\xca\x1f\x7e\xde\x2e\x6f\x00\x24\x4d\x0c\x73\xd2\x9d\xb5\xc9\xcf\xcd\xe4\x32\xd2\xd4\x95\xbc\xab\x13\x94\x8f\x35\x6c\xd7\x0f\xc8\x1d\xae\xc3\x78\x46\x4c\x66\x3e\x6d\x95\x5c\x3e\x5f\xc6\x2d\x7a\x7f\xab\x53\x55\x14\xd5\x0e\x4e\x9d\x77\x9a\x97\x08\xab\x33\xfd\x81\xb5\xf1\xbc\xd0\xe1\x99\xdd\x57\x06\x46\x9d\x3c\x8c\x64\x46\x3a\x16\x1c\xdc\xbb\x43\x37\xe5\x57\xa4\xcf\x8c\x64\x36\x13\x5e\x82\xe7\x76\x38\x99\x24\x09\x16\x33\xb0\x19\x64\x2d\x8b\x62\xdf\x39\x0b\xc5\xc7\xa3\xd4\x23\x35\xfa\x21\xff\x17\x7e\x16\x83\xcb\x7d\xc9\xf2\xb9\xd2\xc3\x7e\x43\x24\x85\x64\x0c\x44\xfa\x64\x95\xab\x28\x33\xbe\xcc\x38\x2e\xca\x32\xa2\x88\x62\xa1\xc3\xc0\x49\xec\x4e\x98\xa1\x96\xb7\x22\xa2\x98\x8d\x1c\x48\xf1\x0d\x5b\xe9\xdc\x63\xf3\xf8\xbc\xe1\x66\x35\x65\x03\xa2\xd6\xf6\xbd\xa0\x8c\xe8\xc4\x29\x0d\xbb\x6c\xa2\x23\x35\x59\x75\x2e\xeb\xcc\x1a\x13\x23\x24\x2a\x56\xb7\xf9\x11\x7e\xca\xbc\x5f\xcd\x06\x20\xf4\xff\xef\xa4\x5d\x66\xf7\x67\x04\xa8\x13\x2a\x3a\x20\xa6\xa8\x3a\xb7\x43\x19\x90\x11\x90\x4e\x59\xf8\x1b\xb4\xb7\xb2\x34\x33\xae\x27\x16\x47\x29\xc7\xbc\xb0\x1e\x3c\x95\xb5\x9c\xb6\xe2\xb1\x38\x02\x96\x8a\x85\xe4\xb1\x1f\x26\x91\x52\x26\x20\x52\x1e\x8b\x0a\xd9\x8c\xc7\xae\xf6\x27\x4d\xa6\x0b\x9b\x5a\x4c\x32\x47\x86\xe5\x23\x99\xc7\x42\x7e\xe4\xe5\xb3\x2f\xef\xfa\x39\x2c\x65\x08\xce\xdf\xfc\xf2\x6c\xa8\xf3\x20\x69\xf1\x33\x89\x59\x66\xd1\x32\xb7\x81\x56\x30\xf4\x71\xfa\x71\xae\x23\xf4\xc7\xf0\x36\xfa\x9c\xf5\x23\x36\xf3\xf7\x8e\x57\xcc\x8d\x10\x8e\x99\x57\xbf\x9e\x4f\x87\x40\x41\xb1\x69\x5f\x76\xed\x85\x64\x9e\xff\x8d\x20\x19\x66\xc5\xf0\xc8\x37\x67\xac\x60\xfd\x07\x66\x4f\x51\xa4\x22\xf0\xac\xac\xeb\xea\x7c\xca\x2f\x9e\xb3\xd0\x06\x01\x15\xfd\x19\xa1\x5e\x5e\x12\x71\x22\x12\xda\xc3\xd0\x8b\xf9\x99\xd2\x2c\x32\x7c\xca\x80\x3c\xb6\x03\x71\xaa\x9c\x1a\x8e\x83\x88\x17\x1f\xf3\x9d\x7c\x76\x77\x59\x0c\x61\x27\xfb\xaf\xa7\x3f\x2f\x93\x4b\x2c\x96\xcc\x25\x70\xef\xe1\x3d\x30\x54\xce\xef\x4d\x25\x16\xdb\xf9\x4f\xd5\xfb\x2c\xa4\x88\x55\xaa\x93\xcc\x3d\x98\xbf\x40\xd6\x9f\x6c\x71\xb1\xd2\x8e\xd4\x0a\x1d\xbb\xff\xef\xdc\xf9\xf9\x33\x7e\xdd\x74\xb6\x0e\xfd\x0f\xb5\xd2\xca\xab\x78\xa1\x71\xd0\xf9\x49\xce\x04\xef\xd2\x30\xd5\x46\xd8\x01\xd1\x04\x81\x94\x6e\x19\xdd\xb6\xfa\x13\x28\xf5\xec\x0a\x4d\x94\xc5\x49\x4f\x08\x1d\x18\xf0\xc3\x53\x37\x24\x41\x29\xe3\x6f\xdb\xa7\xdb\xf1\x96\x11\x9b\x38\x31\x23\xfc\xf8\xfe\x7c\x9a\xb5\x07\xb1\xd8\x50\xa2\xa5\xc7\x7c\x4e\x7f\x6b\x1d\xb6\xf8\xf8\xda\x8e\x8b\xd1\xac\xf3\x52\xf0\xa1\xde\x6d\xef\x0f\xdb\xf5\xc3\x48\x85\x0c\x25\xc7\x5c\x82\x14\x77\x9f\xd0\x31\xbd\xfc\x51\x81\x12\x29\x75\xed\x7b\xed\xcb\xe4\xd4\x5d\xf4\x4d\x91\x81\xac\x69\xb1\x59\xfd\x93\x88\x23\x4c\xb7\x06\x83\xf0\xbb\xfc\xb9\x96\x9f\xd2\xba\xb1\xd8\x72\x17\xa8\xa9\xbc\x0b\x11\x6b\x59\xac\xbf\xa6\xab\xed\x2b\x4c\xa3\x6c\x26\xa3\x11\x73\x08\xc0\xfd\xb7\x35\x5e\xf4\x84\x23\xf9\xb3\xa4\x26\x32\xc1\x7b\xae\xdf\x56\x16\x4f\x55\x51\x34\x57\x1f\x88\xf8\xf7\xe3\xb1\xa0\x58\x51\xc7\xbe\x86\x6d\xd0\x34\x71\xd4\x9f\xb6\xa7\xbf\x37\xae\x61\xe8\xd7\xc7\xf2\xd7\x4b\x69\xe2\x00\x11\xd2\x98\x7d\x85\x32\x7a\xc5\xbc\x03\x82\x51\x2a\x19\xba\x64\xab\xeb\x3f\x87\xda\x23\x12\x7e\x61\x19\xd9\x95\xc6\x1e\xca\xe7\x2a\x2f\x9f\xf7\xbf\xae\x3e\x9c\xca\xd4\xf4\x29\xb0\x54\x26\x3e\xe7\x04\x75\x2d\x8b\x4b\x3d\x7d\x46\x79\x64\xf0\xd2\x4b\xa8\xc2\x39\x78\xc6\x30\x93\xda\x45\x84\x1f\x77\xa8\xee\xdf\x45\xa3\x7f\x1f\x7c\x51\x6e\x5d\xf4\xb4\x2b\x64\x33\x59\x2d\x34\x21\x0e\xaa\xd8\xb8\xaa\xcb\xec\x66\x93\x04\x94\xba\x00\xbf\xfe\xb6\x10\x0f\xd2\x04\x12\x84\x3e\xdc\x14\xd5\xf3\x51\x16\x85\x6f\x2e\x3f\x7d\x82\x25\x61\x34\x4d\x98\xeb\xdf\x44\x68\xc8\x37\x14\x7e\x0c\x43\x99\xc0\xe7\x83\x7c\x27\x9d\x5b\x65\x36\xbf\x7c\xcb\x8c\x97\xcb\x9a\xb1\x00\x30\x9a\xea\x14\x97\x67\xe0\x63\x1e\xca\xa7\xdd\x98\xc5\x80\xa3\xf3\x1e\x9f\x82\xf0\x4c\xd3\x8f\x9a\x18\x31\x25\xe7\xa6\x8b\x34\x9a\x11\x42\xd1\x4f\xc8\xa4\xa2\x5e\x23\xc2\x69\x43\x6c\xca\xb6\x9e\x9f\x3f\x33\x8e\x8a\x01\x31\x4f\xbd\xc0\x6b\xdf\x11\xc5\xa8\xd4\x80\x5d\x2e\xa1\x9a\xfd\xf3\x45\xba\x36\xf8\x70\x1d\xd2\x7a\x2d\x34\x9f\x5f\xa9\x3c\x64\xa3\x6e\x6e\xea\xea\xd8\x23\xca\xbb\x89\x2e\x19\xa2\x9a\x26\xe8\xd9\xf4\xf6\x85\xaa\x38\xc6\x8a\xbc\xf3\x77\x1c\x01\xdc\x80\xf9\x60\x54\x19\x2e\x6c\xc0\x6d\x76\x61\x95\xdb\x81\xa6\xeb\x53\x19\xcd\x7c\x05\x65\xd7\xc2\xe9\xa1\x74\x8f\x73\xfa\xfe\x0c\xd3\x5e\x5a\xa2\x34\x3e\x7f\x12\x46\x52\x27\x02\x35\x25\xd1\x3f\x3b\x4d\xf8\xc1\xf9\x1c\x73\x61\xfd\xab\x1f\x0d\xc7\x00\x12\xe9\x09\xd2\x0a\x43\xec\x59\xc6\x8d\x02\xd1\xd6\x99\xf6\x9b\xce\xd3\x45\x56\xa1\x89\x02\x0a\xa3\x96\x38\xf4\x61\x68\xf0\x9e\x01\x84\xa7\x37\x65\x19\x31\x3d\xee\xf4\x4b\x0b\x4c\x2d\xe3\x12\x1b\x75\xba\x80\xee\x84\x8e\xc5\x6c\x02\x4f\xbc\x74\x90\x43\xc8\x84\x6a\xe4\x08\xd1\xce\xa8\xcd\x38\x6e\x32\x9d\xeb\x3c\xb4\xc6\x61\x68\xed\x64\x09\xf1\x03\x40\x96\x99\xdf\x96\x76\xd1\x2e\x0a\x91\xd4\x13\xb1\x95\xdd\x62\x71\x30\xee\xa1\x0f\xa4\x73\xa8\x15\xba\xe7\x8d\x7e\x81\xa3\xf4\x9e\x40\x58\x31\x2c\xe6\x09\x1e\xe0\x90\x97\xba\x38\x9b\x5e\xb2\xe9\xbf\xe9\xff\x9d\x9e\x29\x56\x36\xea\xa5\x3a\x56\x35\x4c\x51\x2a\x9d\x95\x16\x08\x1d\xbe\xcb\xcb\xfc\x0e\x16\xf1\x20\x9f\x9b\x28\x46\x09\x60\x9c\x78\xcc\xcb\x87\x3f\xd6\xe1\xe2\x58\x24\xb9\x93\x71\xeb\x85\x33\xf3\xaa\x7c\x02\x69\xfa\xeb\x67\x89\x45\xde\xa6\x1e\x60\x36\xd9\x70\x19\xd3\xdc\xf3\x18\xc3\x88\xe0\xfa\x14\x1c\x95\xe6\xa1\x5c\xd4\x0e\x9e\xde\x1a\x03\xaa\x4d\xd8\x7f\xfc\xf1\x17\x37\x38\xc6\xd3\xb1\xda\xc0\xba\xe8\xfb\x35\x17\xee\x7c\x92\x5f\x9c\x6e\xcb\x8c\x2b\x8e\xf1\xdd\x5b\xd5\xc2\x4f\xe8\xd6\xf6\xd0\x7e\x34\xbb\x38\xa1\x14\xf6\xed\x61\xc3\xf8\xc7\xa1\x09\xdc\x6f\x13\xf7\xf1\x12\x42\x31\x3d\x9f\xd0\x19\x02\xa3\x6d\x75\x2e\x8d\x5f\x46\xfb\xfc\x08\xdd\x53\x25\xb3\xf5\x94\x00\x4b\x75\x90\x35\x7b\x3e\xd7\xf0\x3b\x7c\xf4\xf2\xe7\x9f\x21\x35\x7a\x4f\x9e\xa5\xb1\x54\x48\xc8\x13\xbd\xc2\xea\xc6\x5b\xb9\xd9\x29\x52\x11\xe1\xe6\xd0\x42\xd3\xde\xc8\xbc\x78\xac\x61\x50\x4e\xed\x27\x59\x6e\xfd\xee\xb4\x69\xb4\x3c\x85\x22\x5a\x33\xb0\x6c\xf4\xef\x25\xa3\xae\x0f\x5f\x1a\xf3\xfb\x87\x9e\xc7\xd6\xa3\xab\xcb\xb8\xc1\xaf\xf6\xe8\xfc\x21\xa4\x62\x9e\x2c\x54\x15\x69\x44\xb6\xb8\xd6\xb4\x97\xbc\x36\x3f\x01\x5e\xc7\xd4\x99\x8c\x29\x11\x31\xef\x9a\xdf\x41\x17\x24\x95\xed\x35\xc8\xa2\xf9\x9e\x77\x91\xfd\x6c\xef\x60\x4a\xc5\xa9\xcb\x3d\xbc\x97\xeb\x3a\xef\xdd\x1a\xa6\xa9\xc9\xa4\xcf\x1d\x1c\x4f\xd0\x22\x10\xdf\x47\xb2\x61\x4a\x6a\x7c\xa3\xed\xa9\x5a\x57\xe5\x33\x14\xf2\x08\x65\x90\xfd\x62\x4c\x83\xf5\x41\x42\x39\xc9\xcb\x30\x93\x71\x15\x05\xe5\x9a\x29\x66\x84\x31\x23\x5d\x1c\x93\x37\x88\x4f\xec\x45\xb7\xbb\x91\x0c\x11\xe3\xf0\x0b\x3d\xa8\x9f\x90\xcf\xac\x80\x31\x02\xa1\x3c\x9b\x62\x94\x48\x60\x90\x2a\x5f\xee\x54\xaf\xf0\xd1\x90\xd9\x8f\x20\x4b\xdd\xeb\xae\xf3\xe7\x67\xa8\x57\x2d\x52\xb9\x4d\x5e\xa0\x35\xd2\xa1\x4e\xce\xea\x8b\x68\x84\x47\x84\xb9\x34\x60\x55\x98\x71\xba\x8b\x47\x8c\x6b\xa7\xe5\x97\x5f\x30\xc0\x4d\xbf\x05\x4e\x32\xa7\x6e\x7a\xf3\xf0\xe3\xfe\x7a\xb5\xdf\x3e\xdc\x7b\xa9\x98\x21\x77\xc5\x89\x76\x52\x38\xd7\x60\xce\xba\x45\x0e\xd6\xc5\x6d\x82\x13\x93\xba\x5a\x71\x17\x83\x8e\xdf\x00\x8f\xb9\x2b\x25\xa0\x32\xc0\xad\x6c\x6f\x3d\xcb\x4a\xfa\xaf\xc9\x01\x62\xe1\x72\x5f\xd2\xbc\x41\xd9\x7d\xd7\xfe\x8b\x09\x87\xa1\x5e\x28\xd7\xe5\xac\x0e\xab\x73\x5b\x21\xbb\xef\xf4\x32\x68\xa6\xbd\x4e\x7d\x7b\x27\xcb\x8f\x3e\xcc\x1e\x61\xc2\x86\x8f\x80\xb3\x08\x78\x0f\xb9\xbf\x3a\xd7\xe5\x83\x46\xea\xde\xb0\x0c\x38\xef\x16\x56\x08\x55\x8d\x3a\x17\x41\x1b\x96\x71\x9e\x12\x14\x8f\xb9\xb9\xdb\x1f\x86\x12\x45\x18\xcc\x2c\x02\x42\x91\xe9\xe8\x80\xbb\xec\xa1\xed\xdb\x4f\x18\x17\xc2\x22\x87\xc3\xf7\x4b\x40\x68\x98\x01\x46\x3a\x92\x4b\x47\xcd\xd7\xe7\x95\x91\xf5\xd1\x77\x8e\xbb\x96\x98\x00\x7b\xfb\x52\x5a\x70\xf6\xba\x12\xef\xa6\xad\xd7\xdf\x0f\xb7\xb7\x7f\x1c\x68\x44\xfb\xe3\x1b\x2f\x53\xe6\x9a\xcf\x1c\xea\xf4\x93\x83\x4f\x17\x54\x9a\x00\x02\x13\x0f\x0d\xb4\x0b\xd2\x81\x8c\xa7\xc6\xf8\x38\xb2\xce\xc7\xe4\x51\x8c\x67\xa9\x46\xe3\xfe\x22\x1b\x74\x02\x5c\x52\xa6\x1e\xd2\x60\x5c\x26\x32\x76\xdf\xea\x43\x2d\x75\x01\x4e\xaf\xc7\x0f\xaa\x94\x61\x93\x4c\xdf\x14\x71\x36\x79\x3b\xc3\x09\x33\xae\x55\x1c\x08\x74\xfe\xa8\x30\xdb\x3d\x31\x07\xdc\x10\x8a\xd0\xac\xa3\xfc\x15\xea\x79\xfd\xeb\x36\x04\x30\x29\x74\x40\x4c\xb6\xef\xa1\x6c\x9b\x51\xea\x86\x1b\x11\x19\xda\x0b\x1f\x9e\x3f\x66\x58\x87\x4f\xde\x84\x11\x29\x62\x78\xd7\x0f\xfb\xfd\x64\x05\x98\x2c\xa3\x3e\x05\xbf\x87\xe3\xe9\x3b\xd4\x15\xd2\x74\xf5\xe3\x36\x42\xbc\x5d\x21\x9b\xf6\x10\x3a\x5b\xcc\xc1\x19\xf4\xc1\x31\xe4\xc6\x66\x46\xf4\x6a\x95\x9e\xa7\xd5\x8f\x01\xcb\x30\x4c\x3f\xd4\xd0\xbd\xe5\x31\x57\xe6\x65\x51\x90\x5b\xe2\xc8\x4f\x9a\x97\xea\x1d\x2b\xaa\x47\xd9\xe6\xba\x19\xff\xca\xcd\x14\x51\x2c\x13\xd3\xef\x6b\x0e\x98\xe3\xc8\x84\xfa\x19\x1c\x30\x8e\x3a\x75\x5e\xfb\x81\x1c\x6a\x38\x4a\xc4\xa1\x1e\xda\x71\xd8\x22\x22\xeb\x98\x69\xd4\x08\xcf\xb7\xc8\x4b\xca\x04\xe1\xae\xc7\xd5\xc0\xdb\x66\xff\x7d\x54\x89\x0d\xc7\x8a\x09\xc1\xc4\xf9\x73\x55\x99\xe6\xe1\xf7\xe9\xe2\x14\x71\xe6\x60\xb3\x98\x54\x76\x54\x0c\xdf\xc0\x65\xae\xfa\xab\x89\x33\x27\x29\xfd\x74\xee\xcc\xab\xff\x23\x8d\xa8\xa5\x43\x15\xa2\xa7\xfe\x61\x82\x49\xc0\xf2\x66\xf7\x18\xf6\xf5\xc7\xb7\xd0\xb0\xc6\x04\xd3\x8e\x01\xfa\xdb\xfd\x7e\xd5\xd7\x66\xa6\xcb\x55\x70\x70\x4d\x5c\x9b\x22\x7f\x3e\x4a\xdf\x81\x31\xa9\x47\x08\x91\x0a\x0c\x6b\x1d\x01\x75\xdb\xd3\x01\x32\x21\x32\xc0\xf8\xfd\x74\xae\x9f\xb1\xb1\xeb\x93\xf8\x54\x24\x54\xc5\xc6\x13\xd5\x8e\xd3\x74\x58\xea\x40\x3a\x2b\x57\xdb\x1a\xfd\x19\x1d\x87\x17\xd9\x4c\xbf\x50\x91\x65\x29\xba\xa0\xb2\xae\x25\xf6\xc2\xdc\x54\x41\xb2\x65\xf6\xa8\x65\x92\x21\x23\xcf\x4d\xf5\x9a\xb7\x81\x4c\x80\x09\xc5\x09\xf6\x0d\x56\xb5\x81\x3a\x88\xe3\xce\x1e\x8a\xb2\x56\x79\xed\x9c\xe9\xd7\x2b\x74\x94\xf5\x44\xd2\xb9\xcd\x97\xaa\xd6\xc2\x70\x29\xd9\x05\x1d\xd5\xf4\x0c\x46\x66\x48\x0e\xf0\xeb\x34\x3c\x0b\xa3\x64\x1a\xa8\xb7\xb0\x6f\x65\xd1\x00\x0a\x63\x9c\xc8\x2a\xca\x56\xb5\x55\x09\x6b\xd9\xbc\x5c\x49\xa7\x4a\x1c\x8e\x05\x91\xc2\x37\x53\x95\xbb\xb3\xda\x38\x28\xd8\x2c\x6d\x2e\x80\xbb\xf4\xd9\x0e\xca\x5e\x3f\xff\x4b\x8c\x0e\x13\x56\x44\x6e\xb5\x34\xba\xae\xde\x3b\x47\xb1\x90\x8b\x12\x60\xd3\x4b\xb6\x42\x13\x1b\x30\x1a\x6d\x55\xff\xcf\xec\x4a\xac\xd2\x88\xcc\x5d\xd7\x60\x76\xf9\x73\xff\x2d\x59\x6d\x7d\xe7\xa0\x3d\x97\x7e\x23\x9a\x3e\xc8\x24\x4a\x6d\x32\xb0\x0f\xe1\xfe\x77\x40\x9d\x90\xee\xbf\xed\xf9\x92\x91\x67\xfc\xaa\x92\xc8\xc8\x2c\x1a\x17\x05\x3e\x71\xec\x17\x79\x3b\x59\x42\x22\xe2\x64\xc0\x65\xdd\x80\x47\x13\x61\x5b\x4c\x8b\x49\xd1\x01\x14\xc8\x92\x38\x02\x0c\x86\xf7\xf9\x33\xd4\xdd\x1b\xfb\x2d\x0c\xc4\x29\x2e\xf5\xf2\x7c\x1c\x87\x65\x4d\x3f\x6e\x68\x68\x14\xdb\xbd\x54\x27\xfc\x7a\xd0\xc4\x22\x59\x0f\xd2\x8a\x4c\x6e\x89\x45\xae\x5c\x79\x3c\x7f\xaa\x8f\xc4\x12\x96\x3a\x41\x8e\xb6\x3a\xd7\x25\x3a\xb9\x9b\xd2\x8c\xc8\x83\x58\xc2\x20\x42\xaf\x65\xbb\x7e\xd8\xbd\xcb\xd3\x28\x05\x94\x70\x92\x88\xc8\x8b\xcf\x2e\x34\x19\x76\x13\x80\x06\x0a\xc6\x6e\xff\x9d\xc6\x23\x89\x20\x1c\x77\xc8\x0b\xbf\x69\x76\x18\x91\x38\x35\xf0\x1a\x74\x2b\xcb\xe7\x4f\x7a\xdd\x59\x22\x8c\x40\x88\xc0\x11\xe5\x2b\xb7\xe5\x65\xd3\x36\x4b\x04\x64\x48\x88\x07\x27\xfd\xbe\x50\x91\x4d\x92\x38\xc5\xfa\x17\xfa\x8f\x62\xd0\x03\x0e\xc3\x54\x0a\xdd\xd7\x77\x03\x79\xf4\x8c\x40\xf8\x82\x8f\x9c\x25\x89\xe6\x18\xc1\x36\x6d\x75\x0a\xe4\x7f\x7e\x28\x25\x32\xc2\x72\x74\xd5\x6e\xfe\x7d\x96\xc5\x6f\x3d\x97\xf0\x74\x89\xa6\x8c\x22\x2c\xc0\x2b\x4a\xac\x5f\xf2\x62\xb9\x63\x86\x25\x69\xea\x9c\xaa\x67\xf8\x9a\x78\x98\x25\xa9\x55\xae\x62\xf6\x32\xed\x50\x1b\xf6\xe1\x24\xe3\x1a\x91\xbf\x4f\xae\x97\xeb\x63\xf7\x22\x63\x2e\x2e\xec\xc3\xdf\x00\xe4\x96\xe3\x65\x7f\x0a\x29\x98\x76\xbd\x5b\x66\x2c\x7f\xf1\xc9\x72\xd0\x46\xb8\xa0\xe5\x0b\x85\x9d\xe9\x2f\x4c\xe2\x40\xd2\x87\xb6\xba\x45\xa7\x66\xf2\x60\x21\x36\xd8\x35\xa9\x3f\x79\x9a\xc0\x63\x74\x1e\x64\xd9\xbc\x43\x7d\x51\x8c\x99\x1e\x4b\xb8\x2c\x1d\x94\xc6\x95\xc2\x77\x08\xdc\xed\x81\xd4\x2c\x01\x60\x68\xdc\x8f\xf2\x17\xaa\xb3\xb8\xa2\xf8\x23\xd4\xb6\xaa\x8f\x03\x15\x2c\x4b\xac\xe4\x58\x47\x5d\xaf\x76\xfb\xe1\x6f\x29\x2a\x31\x37\xd0\x5e\x0f\x84\x00\x61\x50\x29\x2c\x38\x1f\x65\x79\x96\x45\x67\xcc\x5d\x6b\xf7\x97\x85\xc4\xc4\x5a\x99\x11\x2f\x9f\xb4\xae\xaa\xc2\x54\xef\x53\x84\x22\x4b\x23\x26\xb0\xe2\xf7\x50\xe7\xcf\x79\x89\x6d\xbd\x0b\x85\xb1\x94\x08\xc0\xbd\xbd\x33\x07\x2f\x18\x93\xe7\x5a\x16\xb5\xeb\xc5\x0b\x73\xa4\x2b\xbe\xf6\x0a\x70\xeb\x87\x3b\x3c\x96\xe3\xb2\x42\x6f\x63\x7a\xf2\x98\x09\xcc\xb2\x07\x06\x4b\x97\xdc\xbf\x93\xcd\xeb\x0c\x27\x97\xd2\x28\xc1\xa8\xbc\x7b\x3f\xc7\x5e\x71\xed\x67\xde\xbe\xac\x74\x7b\x96\x85\x87\x36\xce\x7f\x45\x5c\xf1\xc4\xc0\x1b\x14\xd5\x09\xc1\x8f\x20\x5d\x50\xd9\x38\x21\xdc\x70\xf1\x94\x49\x0c\x28\xd4\xf9\x63\xe0\x9f\xf4\x63\x8c\x6b\x44\xd4\xde\x81\xc9\xe5\xc8\xac\xa7\x2c\x49\x23\x15\x38\x32\x9e\x40\x43\xd9\x3a\x30\xc2\x71\x4e\x89\xc5\x52\x26\x63\x44\x7d\xdb\xaa\x46\x9f\x7e\x09\x61\x1e\xa6\x9a\x2c\x56\xa3\x3c\xe8\x40\xd6\x36\x89\xf0\x53\xae\x9d\xea\xb0\xa7\x34\x72\xe2\x5c\x33\x07\x20\xe5\x86\xc6\x3a\xc0\xd4\x2e\x08\x40\x66\x09\xe5\xd9\xff\xf9\x43\x08\x9e\x61\x4f\xfb\x7f\x00\x9a\x17\x59\x4a\xa5\x02\x0a\x24\x15\xc2\xb9\x4a\xfa\x45\x1e\x4f\x83\x83\x9c\x26\x8a\x66\x71\xdf\xaa\xf7\x07\x32\x33\xce\x73\xd1\x69\x9a\x52\xa4\x8b\x73\x91\xbe\xfc\x15\x7e\x9c\x6a\x89\xce\xcf\x8b\x6c\x3e\x23\xf3\xeb\x67\xba\xbc\xfb\x41\x1a\xb3\xf9\x85\xd9\xd8\xf9\x49\xb2\x28\x22\x81\x99\xf5\xd7\xd5\xa9\xc1\x4d\x6e\x16\x7c\x8e\x3f\xf3\x34\x53\x31\xf8\xbd\x78\x75\xe5\x8f\x75\xf5\xb1\x50\x71\x4a\x65\x24\xb0\x90\xfb\xd7\xb9\x44\x55\x9c\xe9\x89\x65\xa4\xc1\x43\x30\x9f\xaa\xf3\xf3\x8b\xcf\x82\xce\x0e\xc1\x01\xa3\xd5\x6e\x5b\xeb\x9c\x5c\xe7\x21\xbb\x2c\x40\x75\xae\x35\xd4\xbf\x2d\x6d\x87\xa9\xe4\x36\x0a\x4b\x04\xbf\x89\xaa\xcc\xbb\x85\xd2\xf3\xf7\xb0\x54\x0a\xd7\x46\xb0\xc3\xe2\xb9\xcd\x6b\xc7\x58\x32\x4f\x72\xf6\x9b\x41\x2a\xb3\x8c\x70\x74\x27\xe1\x2a\x2f\x8a\xd1\xdb\x54\xc4\x22\xd1\x4c\x0f\x48\xd8\xd7\xf9\x5b\x1e\xc8\x86\x58\xaa\x23\x8a\x28\xd6\x9b\x3f\x9f\x56\xfb\x4d\xff\x57\x21\x10\x43\x5e\x56\xc6\xb5\xd1\xf6\x1f\x94\x49\x04\x66\xd0\x9f\x6b\x59\xb6\x9e\xb8\x76\x92\x84\x4e\x4d\x9a\x61\xaf\x98\x93\xac\x1a\xaa\x66\xa9\x25\x80\xd5\xd7\xce\xc8\xd8\x29\xe1\xd6\x27\x09\xa5\xd4\xd2\x08\xcf\x56\x56\xed\xcb\xb0\x37\xa7\x36\x75\x3d\x82\xab\xee\xb3\xcd\x21\xac\xbe\x2c\xca\x34\x7a\x09\xd7\x95\x6d\x47\x19\xb9\x2c\x02\x8b\x26\x18\x0d\x6f\x09\x6d\x67\x08\x82\xce\x8c\x9f\x42\x22\x21\xbd\x4f\xf4\x3c\x8a\xde\x32\x62\xbd\x0e\x79\x59\x7c\x3c\xca\x70\x93\x19\x4d\x1d\xed\x3e\x9a\x8f\x47\x57\x8e\x58\x5e\xe8\x19\x55\xa9\xf4\x04\x6e\xf5\x35\xbc\x0d\x0d\x49\x2c\xa3\xd6\x62\x33\xff\x1b\x36\x12\x5d\xd0\x7a\xcd\x0e\xc4\x12\x95\x79\x66\x86\x87\x73\xab\xab\x23\x3c\xd8\x1d\xe8\xaa\x34\x2e\x21\x7b\xf5\xb1\x29\xdb\xbc\x9d\xad\xd3\x8c\x59\x93\xd9\x01\xed\x12\xce\xcd\x09\xc3\x24\xf1\x53\x8b\xc5\xd5\xd9\x8f\xb8\x52\x58\x6b\xba\x7e\xf8\xf3\xaf\x81\xb9\x83\x65\x82\x19\xec\x9a\x6d\x5f\x60\xe0\xe6\x63\x99\x90\x09\x12\x66\x1d\x86\x12\x16\xae\xd8\x41\x86\x99\x65\x89\x86\xd0\xcf\x7e\x9b\x6b\x28\x1b\x78\x82\xfc\xa8\xce\x75\x03\x97\x36\x37\x4b\xa5\xc6\x10\x0f\x9d\xaa\xf2\xf3\x1c\x76\x96\x25\x4e\x88\xe4\x2e\x2f\xa7\x30\xb8\x2c\x93\x36\xf5\xd0\x7c\xd4\xd8\xbb\x05\xf3\x3c\x8f\x4f\xb2\x0c\x22\x34\x43\x3f\xee\x77\x0f\xb7\xd7\x87\xd5\xed\xed\xc3\xda\xa5\x41\x37\x7f\x3e\x3e\xdc\x6f\x02\xbb\x2d\xcb\x64\xc4\x7b\x76\x27\x87\x94\x1f\xb7\x40\x74\xe3\x19\xbe\x67\xe4\xa6\xb6\x52\x63\x9a\x7f\xa9\x81\x8a\x65\x92\xc7\x88\x18\xed\x4c\xc7\xbe\x5a\x5e\xfb\x99\x26\x8e\x7c\x05\xe9\x4b\x65\xd1\xef\x77\x99\x4e\xa4\xa1\x23\xa0\xda\xf7\xea\xdc\xc0\xfa\xdc\xde\xd4\xd5\xf1\x32\x1b\x9a\x99\x08\x90\xd0\x11\x97\xaa\x77\x89\x77\xde\x47\x9b\x3d\x0c\x13\x39\x63\x61\xf2\x46\xbe\x55\xef\x63\x5b\x16\x0c\x40\x66\x88\xc2\xdb\xec\x22\x3e\x07\xa1\x5c\x95\x66\xbc\xa8\x4d\x9c\x20\xa3\xd0\xed\xe6\xa6\xff\x93\x94\x59\xcf\xa1\xdc\xb4\x8f\x50\x6f\x4a\xa8\x9f\xe7\x2b\xd5\x00\xf5\x5a\x2b\xdb\xd2\x6f\x08\xd3\x09\x90\x12\x1e\x5e\xc1\xa7\xea\xd4\x2c\x03\xe3\x54\xc3\x74\xe8\x06\x5b\xe0\x2f\x60\x32\x4a\x15\xa6\xd6\xc2\x73\xe9\xd6\xd7\x02\x2b\x16\x93\x91\x11\xe9\xe8\xea\xa7\xd7\x24\x49\xc2\x89\xd7\x47\xc7\x02\x91\x1c\xe0\x36\x32\xe6\x2c\x96\x3d\x03\x21\xba\x49\x23\x33\x1e\x26\x99\xc8\xcc\xd0\x71\x4d\x5f\x64\x1a\xce\x43\xb3\x34\x36\x23\x78\x02\x3e\x80\x9b\xaa\xf6\xc5\x98\xd9\x64\xe5\xda\x56\xfd\x37\xef\x76\x40\x3f\xc6\x19\x47\x41\x8f\xc7\xa7\x0d\xf2\xea\x38\xb0\x6a\x3f\xaa\x04\x56\xba\x9f\x00\x0c\xd4\x70\x9c\x1d\x58\x44\x29\xa2\x15\xae\xd7\x7f\x7e\xd6\x9c\x37\xdf\x95\xa5\x90\x69\x08\x7b\x02\x15\xe0\xe4\xcb\x91\x09\x51\xe8\xe9\x5b\x17\x81\xdd\xc9\x5f\x6b\x79\x1a\xe9\xf8\x30\x99\xc8\x0c\x7d\x12\x94\xf4\x85\x16\xea\x66\xe6\x31\x2d\xe7\x43\x64\x16\x0b\x04\xe2\xcb\xa6\xc9\x9f\x91\xdb\x7b\x0c\xd9\x94\x99\xb5\x89\x08\xe2\xf1\x4d\xfb\x5d\xb6\xfa\x65\xb2\xb0\xfc\x3c\xc9\x92\xc8\xe7\x9b\xba\xbf\xce\x7d\xa2\xe9\xed\x4a\x9e\xe0\xb3\xbf\x95\xcf\x63\x73\x24\x65\x22\x42\xfa\x68\x90\x0c\x12\xfd\x68\xea\x18\xfa\x7d\x03\xd5\x73\x0d\xce\x2a\x7e\xa5\xb8\xf9\x49\x52\x67\x39\xa2\x90\x8a\xe8\x38\x70\x51\xa2\xc9\xd8\x98\xe7\x99\xad\x90\x4a\x64\x49\xd4\xb7\x40\x5e\x55\x7d\x5a\x4e\x2a\xe1\x30\x1f\xba\x3a\x5e\x1d\xfa\x3f\xea\xd8\x91\x87\x99\x63\x5e\x06\xf0\xc3\x66\xfb\x98\x24\xc9\xa7\x81\xe8\xd8\x84\x7f\x1d\x85\xce\xaf\xdf\x24\x98\x0b\x3a\xca\x57\x78\x2c\x64\x79\x91\x53\xf7\xf3\x34\x8b\x31\x41\xbd\xae\x8a\x02\xf4\xa7\xb3\x32\x07\x55\xae\x51\x01\x69\x22\x60\xc5\xa4\x56\xa9\x2f\x6c\x07\x41\xac\x8b\x5a\xbb\xd4\x90\x60\x00\xb4\xaf\x73\x35\x57\xab\x5b\x62\xd7\x63\xd2\x70\x4e\xb9\xe3\xf0\xa8\xac\x27\xdf\x97\xba\xdd\x95\xf9\x69\xb0\xaf\x12\x22\xee\x68\xda\x3d\x2f\xd2\x94\x19\x8b\x49\x88\x75\xa0\xe5\x59\x9d\x4e\xf7\xb9\x7e\x2d\x87\x5d\x5d\x02\x4f\x11\x4a\x71\x95\xb7\x6d\x0d\x23\xa8\xfe\x42\x22\x54\x5a\x42\xd0\xbb\xc2\x02\xd5\xd5\xf9\xe3\x4a\xea\xd7\x87\xb2\x3f\x96\x25\xa9\x63\x5e\xad\xaa\x42\x76\x16\x7e\x1a\x5b\x49\x4b\x2c\x73\xea\xa4\x58\xec\x78\xb0\x36\xd7\xb9\x2c\xe6\x6c\x91\x4c\xda\x98\x85\xe2\x83\x77\x0e\x46\x8d\xcc\xd3\x67\x64\x33\x26\xec\xb8\xc9\x71\xc2\xf9\xca\xa4\x35\x32\xf3\x42\x2c\x7f\xc8\x22\x37\x57\xb2\x81\x5b\xe4\x3f\x7e\x28\x07\x0f\x7d\xc6\xdd\xc1\x54\x14\x33\xee\x49\x8f\x03\x90\xf7\x6f\x4c\x87\x8a\x92\x94\x86\xde\x09\x99\x9b\x47\xa9\x5f\xe5\xf3\xdf\x4a\xdc\xf4\x3f\x96\x58\x04\x2b\xe1\x3d\x10\xc5\xcd\xdf\xc4\x64\x13\x50\x84\xd8\xd8\xb3\x9b\x38\xc0\xca\xf8\x1b\x08\xad\x0e\x8a\xc4\x14\xf3\xb4\xce\x5f\xf4\x00\xb5\x30\x66\x9c\xc8\xc2\xf5\xe6\xcf\xdb\x6d\xef\xc9\x2b\x02\x51\x66\xc2\x2e\xe7\xd4\x67\x9e\x40\x76\xdb\xff\x30\x43\x10\xe9\x61\x45\x75\x83\xec\xa9\x61\x28\x8e\x20\x09\xad\x36\xf7\xe7\xe3\xa1\xff\x7b\x6a\x10\xa9\xe2\xd4\x61\x07\x59\x51\xa6\x62\x49\xb0\xf4\xaa\x65\x6d\x9a\xc3\x11\xda\xe1\xc6\xfd\x0c\x96\x65\x4e\x38\xce\xb9\xff\xe8\x92\x3b\xe5\xb6\x70\x0c\x66\x62\xcc\x7b\x9f\x10\x68\x35\x30\x95\xfa\x61\xce\x49\x8a\xae\x69\x55\x14\x13\xba\xdd\x6e\xc8\xa9\x97\xe2\x3b\xab\x5f\x83\x94\x47\xff\x94\x93\xc8\xe0\x91\x6f\xf3\x7f\x9f\x73\x93\xb7\x1f\xa1\x9d\x39\x8c\x0b\x85\xbc\x4c\xdb\xf5\x43\xb7\xe8\xea\xfe\xef\x89\x63\xb2\xed\xf6\xf1\xcf\xf2\x36\x61\xb5\xab\x24\x15\x9e\x6a\xaa\xed\x02\xd6\xc3\xd5\x7e\xfd\x63\x77\x3d\x7b\x0a\x89\xa4\x98\x31\x3a\x38\x7b\xbf\xd3\xb5\x3c\x75\x61\x44\xc0\x73\x4d\x67\xa7\x91\x6b\x75\xf0\x0d\x8f\x55\x2b\x8b\xe9\xcb\x4f\x49\x8a\x98\xd0\xdd\x7e\xb7\xdf\xec\xf6\x64\xf8\xbb\x53\x66\xbd\xca\x31\x1e\x9a\x3c\xac\x34\x95\x58\x54\x6b\xb4\x2c\x4b\x30\x57\x75\x55\xfe\xa7\x8b\x7c\xfa\x07\x9d\x6a\x8d\x56\x70\xd3\xbe\xdc\x56\xe5\xf3\xe6\x17\xd4\x1a\xdf\x53\xf8\xbe\xe3\x21\xdf\x90\xce\xbf\xb8\x4c\x4b\xc5\x43\xc2\xf6\xaa\x97\x83\xe9\x97\x50\x06\x56\xf9\x1a\xfd\xb6\x3c\x9d\xdb\x45\x28\xff\xf4\x90\x92\x08\xac\x86\xaf\x1f\x6e\x1f\x9e\x0e\x8f\xdb\xfb\xdf\xc3\xc1\x14\x55\xb8\xb5\x35\x6d\x75\x1a\x67\xc9\x95\x12\x11\x26\x67\x9b\xfc\x79\x54\x0a\xf4\xe2\x9d\x61\x92\xa6\x80\xa0\x82\x2b\x68\x7f\x6e\x56\xcb\x3e\xa5\x32\x09\xc1\x90\xf3\x5b\x77\x98\xc9\x73\x34\x89\x4a\xfc\xfb\x76\xfe\xf0\x52\xdf\x3f\x53\xa0\x53\xd7\xf5\xf7\x92\xd7\x06\x83\xa3\x30\x2f\x4c\x00\xd7\x1c\x3e\xb0\xdb\xcf\xc0\x57\xd3\xe3\x59\xc9\x05\x8c\x88\xdc\x5c\xb3\xc9\xc4\xaa\xe8\x88\x44\xe8\x58\x1d\x42\xdb\x48\x2d\x8b\x49\xe9\x2a\xcc\x63\x11\x26\xb8\xee\x3e\x26\x7a\x9c\x9f\x80\x95\x27\x16\x5b\x13\x62\xb1\x81\xcd\xcb\x1d\x87\x9a\x39\x2a\xfb\x2f\xd4\xee\x34\x49\xa5\x4c\xfa\xa6\xe6\x51\x27\xaa\x1f\x8f\xa3\x8c\x87\xf1\x9e\x44\xe4\x53\x9f\xa7\xff\x91\xa3\x10\xad\xa1\xad\x73\x78\x83\xcd\xaf\xce\x9d\x1f\x51\x68\x32\x1d\x1b\x83\xaf\xe9\xfb\x6e\xfd\xcf\x6f\x8e\x6a\x85\x01\x11\x8a\x29\xf8\xfa\xd6\x62\x09\x4d\x53\xad\xb1\xb5\xbe\xdb\x90\x1e\xab\xe2\x12\x2b\x3e\xbf\x81\x21\x84\xd5\x2c\x71\x29\xe5\xf7\xa0\xe0\xd1\xdb\x42\xcd\x94\x25\x9e\x14\x77\x00\x69\x8f\x7f\x6a\x34\x25\x01\xac\xd7\x27\xe9\x67\x7b\x43\x37\x0b\x33\x2f\x81\x80\x21\x0c\x4f\x6f\x81\xc7\x42\x3b\xe6\xff\x37\xd7\xb9\xe7\x69\x78\xc3\x51\x38\x4f\x43\xab\xfb\x1f\xb2\xce\x55\xd1\xc3\x27\x97\x24\x5a\x99\xe6\x4a\x61\x94\xeb\x52\xc4\x0b\x3c\xc4\x69\x98\x08\x09\x4f\x83\x7f\xd0\xb4\xd5\x11\x6a\xc7\x68\xb1\x5e\xb8\x4a\x41\x01\x42\xce\x64\x48\x09\xe9\x84\x80\x8d\x7b\x13\x89\xe9\xfd\xa0\xf9\xf1\x77\x6f\x62\x7a\xd5\x09\x65\xb8\xb7\xbd\x43\xde\x13\x0c\x87\x21\x23\xc0\x0e\xac\xb8\xf2\x75\xe6\x3e\xeb\x2c\x21\x58\xe9\xba\xfa\x63\x15\x7e\x93\x49\x1b\xfb\x7b\xbb\xe4\xe7\x60\x3a\x83\x14\xd9\x27\xc2\x9b\x59\x05\x5a\xf0\x7e\xdd\x4a\x2a\x70\xcf\xbf\xad\x9e\xc9\x12\x63\x27\xd3\x52\xa6\xc6\x85\xcd\xab\xba\xf6\x01\xfe\xb6\xb9\xa9\xab\xff\xcc\x6b\x01\x5a\x11\x8d\x58\xb7\x42\xf6\xc8\xf0\xe9\x04\x4d\x62\x47\x1d\x8d\xc6\x1a\xad\xc9\xec\x8a\x35\x77\xa5\xff\xe3\x01\x3c\x7f\x44\xb7\xff\xe7\xe5\xf3\x06\x9d\x81\x7e\xb5\xe8\xc4\x22\xb8\x01\x3f\x9d\x10\x1b\x2c\xcb\x6b\xcc\x4e\xa0\xc0\xf8\x70\x11\x69\x4d\xbd\x1f\x0f\xe6\xa1\x86\x2b\x59\x60\x8e\x6c\x7e\x51\x60\x05\xa6\x9d\x5d\xd9\xc6\x57\x2e\x06\x39\xd3\xe5\x13\xd9\xd8\xe1\x26\xfc\xa8\x8b\x28\xdd\x0b\x9f\x3e\x14\x6b\x5d\xbb\x6d\x03\xbd\x58\x4d\x29\x9f\xe1\xeb\xae\x45\x13\xc5\xda\x07\xff\xb6\x1a\x10\xed\x26\xa2\x12\x6d\xf2\x55\xe0\x5e\xba\x81\x56\xbf\xfc\x36\xfb\xad\xb4\x58\x54\xee\xa2\xd6\xbc\x7c\xbe\xad\x9e\xfb\xee\x4d\x43\x38\xf3\x2c\x46\xed\xf5\x50\x1c\x41\xb0\xd3\x63\x5d\x1d\xab\xee\x8e\xf7\x63\xc9\x8a\xe9\xb3\x32\x24\x33\xb1\xea\x59\x85\xc0\x4c\xc2\x1a\x43\xa4\xd3\x49\x3a\xe2\x8d\x36\x67\xd5\xe8\x2e\xc0\xe9\xe3\x13\x43\x64\x26\xc1\x67\x43\x64\x6d\xae\x6b\xf9\x7e\xc9\xe6\xcd\x0c\x65\x4e\x30\xea\x47\xa0\x98\x74\x26\xa5\x57\x9b\x58\xfc\xf8\x0c\xb3\x86\x74\xbf\xea\xe9\x4c\x98\x11\x11\x60\x3c\xb4\x1f\x53\xdd\x5e\xf2\x99\x4f\x9f\x9f\x30\x31\x7e\xc4\xd8\x90\x72\x49\x1e\xc7\x4c\xc2\xed\x48\x80\xed\x2e\x2f\xab\x7a\x5f\xc3\x6c\xff\x34\x09\x30\xa7\x20\xd4\x56\xa7\x6d\xd3\x9c\x07\x7b\x63\x32\xa5\xb1\x65\xe5\x59\x1e\x67\x31\x8a\xe9\x82\x98\x80\x90\xda\xb4\x2f\x13\x29\x49\x66\x94\xe2\xb8\x0f\x61\xee\xc5\x11\xb4\xed\xb7\x77\x9b\x7e\x58\xc7\x69\x3c\x30\x6a\xad\xfb\x14\xd6\x08\x36\xbd\xfc\xe1\x18\x1d\x39\x68\xad\x23\xc8\x77\x09\xff\x19\x77\x3b\x33\x9a\x19\xd0\x23\x44\xc5\x4d\x55\x3f\xc9\x8b\xb7\x67\x98\xc2\x0e\x9f\xa2\xaa\x5e\xcf\xa7\x91\xb2\xfc\xc5\x34\xfc\xc6\xff\x41\xc9\x77\xc4\xc0\xc4\x0c\x18\xcb\x5c\x49\xb2\x3d\xd7\x25\x8a\x37\xdf\x54\xf5\x8f\xa6\x5b\x66\xb3\xe0\xd1\x80\x35\x48\xc3\x7f\x92\xb9\xd9\x96\x4d\x2b\x8b\xe2\x38\xa2\x29\x31\x36\x75\x6d\xbb\x6a\xc0\x95\x19\x6b\x34\x78\x13\x72\x2f\x8f\xe3\xb6\x0f\x37\x01\xa2\xd8\x28\xdd\x5f\x40\x67\x61\x5c\x9f\xd7\xf4\xfe\x80\x30\xe0\x9e\xb4\xf9\x35\xf8\x4f\xcb\x9c\xeb\xff\x9a\xfd\x30\x23\xd6\x7d\xfb\x9d\x7f\xdf\x80\xf7\x38\x57\xa5\xe9\x5e\xe8\x57\xcf\x06\xe2\x28\x66\x63\xbe\xa5\xf7\x9b\x1a\x00\x57\x50\x5f\x89\x1d\x07\xf1\x10\x47\xae\x31\x7b\x23\x9b\x8f\xc7\xee\xcd\xb7\xe3\x74\xfe\xe7\x4d\x08\x10\x0b\x8e\xc5\x87\xde\xeb\x98\xaf\x15\x88\xa5\x19\x9a\x55\x3d\x1d\x7f\x18\xd2\x1a\x19\x24\x47\x02\xcf\x75\x3f\x66\x33\x69\x42\x3d\x76\x5b\xda\xea\xe2\xc0\x8c\x6a\x35\xa2\xf8\xf5\x9c\x2c\xe1\xf7\xdd\xfb\x31\x2e\x4f\x62\x01\x86\x3f\x6b\xea\xd8\xd0\x8e\x9e\x6e\x65\x7e\x50\x13\x63\x08\x2d\x8b\x1a\xa4\xf9\x70\x02\x6c\x93\x3b\xe6\x31\x43\xe9\xed\xfd\xd3\xea\x7a\xf3\xb4\x1b\xd5\x35\x80\x77\x66\x15\xdd\x7b\x94\x79\xfe\x56\x54\x4a\x16\xfb\xd0\x3f\x15\x66\x09\x9a\x20\x17\xd5\xad\x54\xd5\x74\x40\x00\x0c\x24\xf3\x77\xd0\x42\x7d\xd9\xfc\x9d\xce\x16\x49\x92\x46\x18\x03\x3e\x3a\xbe\x84\xa7\xaa\x28\x50\x9c\xf3\x33\x8c\xd7\xc5\xcf\x4d\xe6\xca\x00\x27\xb8\x5e\x6d\x97\x2d\x2a\x24\x99\xc0\xf6\x6e\x83\x92\x2b\xe8\xfc\x23\xe5\xf3\xfc\x3b\x83\xc4\x3a\x54\x5c\x91\x1f\xf3\x36\xc8\xba\x35\x7e\xa7\x0b\xf7\x99\x0a\x17\x68\x15\x60\xdb\x64\x06\x6c\x87\x34\x8d\x1c\x4b\xae\x6c\x56\xb6\x85\x3a\xc4\x7a\x20\x99\xc4\x72\xe6\xc0\xf9\xe9\xb3\x2f\x63\xe1\x70\x06\x92\x33\x3b\xe8\x48\xef\xba\x10\xa9\x0b\x5a\x9b\xe5\x0e\x46\xd0\x44\x06\xa2\xf2\x41\x6f\xab\x3d\x77\x96\xe4\x5a\xb6\xe0\x7a\x11\xc7\xe1\x3f\x68\x9f\x3a\x0b\xa2\x79\x52\x2f\x62\xe3\xc6\xff\x12\xb1\x9c\x8d\x04\xad\x2d\xa6\xfd\x1f\x77\xfb\xab\x11\x86\x19\x4c\x16\x61\x14\x77\x73\x3b\x45\xf2\x82\xb1\x42\x79\x9d\xc9\xad\xae\x02\xe1\x9f\x1f\x04\x1a\xe8\x8d\x75\x55\x9a\xfd\x8b\x7c\x9f\x8e\x4a\xfc\x52\x3b\x87\xab\x34\xb7\x17\xe8\x29\x00\xeb\x35\x75\x91\x63\x29\x3f\x85\xfe\x94\xaf\x17\x90\x8d\x29\x41\xb0\x7d\xfd\x8c\x12\x06\xe3\x12\xb4\x8d\x98\xeb\x2d\xb0\x55\xfd\xbc\x20\x89\x1a\x66\x09\x15\x98\x00\xd7\x2f\xf2\x78\xea\xde\xc0\xcc\x37\xb3\x51\x66\xe2\xa1\x4b\xe8\xfa\x5c\x3e\xc3\xdf\x01\x12\x6d\x24\x19\x0a\x76\xb6\x06\xe6\x58\x2f\x1b\x69\x8a\xd0\x89\x40\x20\x32\x5b\x17\x96\x10\x48\x20\x54\xbc\xaf\xaa\xf3\xf3\x4b\xfb\x08\x35\x1e\x61\x7a\x61\x44\x29\xb4\x53\xcf\xb9\x75\x42\x7f\x73\x3b\x65\x89\x02\xdc\xff\xef\x64\x3d\x54\x75\x2c\x01\x07\x9b\xc7\x3c\xee\xec\x17\x31\x8b\x53\xd9\x53\xf7\xdc\xce\xce\x18\x7b\xc8\x12\x36\x13\x35\x7a\xc4\x67\x17\x26\x08\x83\x84\xea\x88\x34\xf9\xd1\xed\x76\xaf\x17\x53\x12\xa0\xc1\x3d\x76\xc9\xa2\xeb\x39\x89\x32\xb3\x94\xf1\x20\xe5\xe8\x85\x07\xf1\x39\xcc\x67\xa5\x09\xf7\x2c\xed\x2e\x36\x09\x7f\xcf\x84\x95\x21\x2f\x8c\x28\xa9\x78\x18\x4a\x23\xdf\x2d\xe9\x44\x02\x67\x56\xd8\x72\x60\xd8\xa1\x56\xf9\x86\x85\x1b\x80\x95\xee\xb1\xca\x56\x98\xc4\xb5\x3a\xe6\xd6\x01\x8d\x03\x3c\x63\x71\x1f\xb5\x09\xa5\xf8\xa8\x0f\xae\xdf\x6b\xf5\x26\xf3\x42\xaa\xbc\xb8\xa8\x72\xdb\x84\x6b\xe4\x87\xc8\x9b\x5e\xb5\x20\x9c\x33\x11\x14\xbf\x8e\x13\x22\xbf\x42\x67\xc1\x58\x3b\x84\xd9\x24\x49\x13\x34\x6c\x17\x2b\x33\x4c\x30\x11\x06\x6a\x6f\x9d\x59\xf7\xed\x69\x63\x08\x86\x4d\x19\xc7\xdc\xe2\xff\x79\x3c\xbc\x3b\xe9\x33\x3f\x90\x09\x57\x67\xc4\x1c\x8c\xc7\xb7\x7b\xc4\x80\x7b\x37\x23\xec\xf7\xf0\x13\x8c\x11\x8e\xd8\xdb\x66\x10\x35\x8b\xa0\xd9\x7e\x42\x92\x18\x08\x4d\xab\x55\x0d\x5f\xc9\xac\x31\x9b\x49\xdd\x33\x45\x3a\xfd\x9d\x41\x74\x6a\xfe\xb5\x66\x26\x42\xf0\x28\xb6\x38\xe4\x65\x7e\x3c\x1f\xa7\x4e\xb1\x95\x99\x40\xd4\x9e\x41\x76\xf0\x5b\xf9\x7e\x01\xfa\xb5\x32\xd3\x98\x4f\xaa\xb0\x49\x63\xdb\x20\xf1\xd8\xe0\x3c\x5b\x29\x09\x1a\xc9\x49\xbf\x6c\x7f\x02\xc5\x25\x26\xa4\xd7\xb2\x85\xe7\xaa\xfe\x98\x6c\xe2\x56\x49\x1b\xa1\x6c\xa3\xab\x3d\x63\x22\xe3\x16\x6c\xff\x26\x95\x26\x18\xa4\xbb\xf4\x70\xff\x57\xe0\x28\xa0\x73\x0f\xef\x57\xf9\xf3\x33\x34\xed\x75\x3e\x27\x35\x9b\x3d\x35\x1d\x3b\x28\xd3\xfd\xc3\xed\x2d\x62\x20\xb0\x1c\x3e\x30\x32\x32\xab\xa9\x60\x7a\x1c\x17\xd2\xd9\x73\xd0\x49\x94\xf9\xd7\x74\x08\xe2\x57\x07\x2b\xf5\x64\x01\xff\x6b\x19\x58\x6a\x75\x4a\x1d\x53\x71\xe5\xea\x88\x2e\x80\xfa\xe4\x43\xd1\x19\xc5\x14\xd2\x51\xfe\xea\x5e\xd9\x00\x65\x1b\x97\x51\xad\x56\x2e\xff\xed\xd5\x07\xbb\xad\x72\x1e\xc3\x4e\x0f\x6b\x08\xc7\x64\x1c\xb2\x15\x8e\x0b\xbe\x61\x9c\xa7\xe8\xc8\x3b\x26\x80\xdb\xce\xd5\x1d\xda\x77\xd3\x30\x49\x59\xae\x06\x25\xd4\x55\xa0\xb5\x08\x57\x65\x0c\xa0\x1f\x74\x75\xfb\xb0\xfe\x7d\xf5\xf8\x18\x98\xbe\x2c\xc4\x80\x6d\x7b\x8e\xcf\x57\xe6\x66\x5e\x0b\xb0\x90\x68\x44\x6d\x6f\x3a\xaf\xa5\x94\x17\x4e\xa1\xb5\xdc\x15\x62\xd6\x3f\xd7\x87\x69\xf9\xca\x5a\x4b\xf1\xab\xa8\x4e\x9d\x53\x52\xbd\x1b\xdb\xbf\x5a\x1e\x45\x11\x47\x2f\x3c\x6f\x1c\xf5\x43\x31\x94\xf5\x79\x14\x31\xea\x92\x72\xf9\x73\xf9\xe3\x84\xdc\x0c\xa3\xa7\xc2\xa3\x08\x1c\xb8\xac\x0b\x00\xbb\xe7\x8c\xae\xe0\x72\x9a\x80\x47\x8c\x08\xc4\x46\xf8\x4a\xc0\x4d\x81\x48\xd8\xbf\x29\x33\xcd\x8f\xc1\x04\x42\xd1\x10\x4a\x28\x4f\xcd\x79\xb8\x56\x96\x6a\x70\xce\x34\x7c\x49\xcd\xb7\x7c\x60\x4e\x09\xca\xd1\xc8\xdc\x3c\x56\xd5\xe4\xbd\xf1\x88\x1b\x4e\x2d\x92\x1a\xf8\x00\xa1\x9b\xd2\x74\x27\xea\xb3\xda\x3c\x12\xc4\x25\x01\xdb\x46\xf7\x7f\x02\xc1\x5c\xce\xab\x7d\x58\x36\xb7\x3c\x4a\x52\x8e\x79\xcd\x00\x52\xb8\xdd\xfc\xb1\xb9\x3d\xf0\x70\x88\x44\x72\x6c\xe2\x69\x5e\xaa\x73\x61\xae\x60\x16\x11\xcc\xee\x22\xb1\xda\x41\xb4\x8d\xb9\x86\x51\x25\xee\x93\x7a\xf3\x22\x1a\x9a\x47\x29\xb5\x09\x75\x40\x6f\x28\xd1\x81\xd4\x2f\x9f\x5c\x7d\x16\x71\x57\x8f\x70\xa5\x95\xa1\xa8\xc2\xa3\xcc\x9a\xd0\x92\x80\x2d\xec\x93\x22\x00\x8f\x64\xe4\x3e\xfa\x67\x68\x7f\x3f\x97\xcd\x7d\x60\x99\xe3\x91\xcc\x48\xe4\xc9\x40\xff\xd2\x5f\x12\x91\xf3\x48\x09\xd7\x39\xf2\x04\xed\x53\xee\xa5\x8a\x48\x9c\xfa\x51\xcd\x14\x22\xbf\x82\x61\x09\xce\xc1\x3f\x81\x8a\x0f\xf7\xa8\xb3\x0c\x51\x48\x80\x05\x3c\x90\xc5\xf6\xfa\x22\xb1\x37\x35\xaf\xfd\x66\xc9\x23\x2d\x15\xc2\xc8\xdc\x96\xfc\x0d\xda\x4b\x2a\x0b\x1e\x99\xcc\x49\x69\x8d\x7c\x75\x8f\x86\x04\x83\x01\xc6\x65\x7f\x4b\xf8\xa5\xaf\xdf\x87\xa7\xf4\xe3\xf4\x3c\x26\x09\x0d\xb3\xb4\xc6\x5a\xb9\xa7\x31\xa9\x0d\xd4\xdd\x86\x14\x9a\x98\x03\x9d\xc9\x42\x61\x80\x47\x10\x83\xe9\x4b\xe7\xf7\xf0\xab\x5d\x7f\xe8\xe1\xa3\x03\xb0\x98\x23\xf3\x1c\xcf\x9f\x30\x03\x84\xc9\x16\x62\x32\x02\xf6\xcc\x5e\x26\x89\x62\x2d\x93\x11\xbf\xf0\x5a\xd6\x33\x86\x2d\x4e\x22\xe6\x5a\xd2\xf2\x66\x75\xbb\x1e\x9a\xc7\x83\x39\x23\x11\x53\x18\xad\x6c\xfe\xdc\xac\x7f\x20\xba\xed\xdb\x6a\x77\x78\xf8\x63\xf3\xf4\x7d\xb3\xba\x0e\xb3\x08\x97\x18\xde\x3e\xfe\xb8\xfa\xd6\xff\x4d\x6b\xec\xdf\x09\xe9\xb7\x43\x59\x19\xd9\xca\x03\x8c\xb3\xbd\x9c\xc4\x22\x41\x0b\xe4\x8c\xd8\x13\x76\xa2\xf9\xee\xcf\xf1\xcd\x92\x58\xd1\x4c\xf9\x46\x8d\x55\xe9\xb5\x77\x17\x57\x9e\x67\x03\xe6\x84\x4a\xc6\x50\x38\x59\x0e\xad\x83\xdd\x5f\x13\x64\xba\xd8\x36\xbd\x74\x33\x1c\x4f\x37\x75\x75\x7c\x28\x4c\x4f\xa3\x56\x05\x34\x03\x27\xdd\x93\x46\x26\x4b\xbf\x16\x16\x57\x35\x61\x3c\xc6\xcf\x33\xf0\x40\x3b\xc6\xcd\x8f\x65\xc3\x42\x38\x89\xd1\xb8\xa2\xbb\x1e\x5a\xe4\xa6\x07\xe4\x84\xfb\x8e\x66\xe3\x5b\x82\x2e\x4c\xf0\x12\x49\x01\x27\x3c\x56\x84\x79\xb8\xcb\x8f\x32\xd7\x7b\xd9\xbc\x7e\x97\xcd\xcb\xd6\xcc\xd6\x87\x60\x0a\xb7\xb8\xfd\xd3\xea\x7e\x77\xb3\x79\x3a\x3c\x3e\x3d\xfc\xf9\xd7\xe1\x8f\xcd\xcd\x9f\xe1\xde\x05\x77\x9c\x75\x81\x48\x6c\x6a\x01\x3d\xf0\x26\x0d\x93\x05\xc5\xae\xf7\x9b\xa7\xab\xfe\xf7\xca\x89\x49\x5f\x0f\x29\x13\x4e\x12\x61\x31\xdd\xb8\x2e\xaa\x73\x3b\x2d\xa9\x4d\x2f\x30\x91\x71\x42\x87\xfd\xff\xb1\x86\x63\x3e\xbc\x97\x44\x19\x16\x3b\x5b\xd5\xbd\xb2\xa7\xea\xdc\x79\x8a\xd7\x4f\x17\xad\x5e\x97\xc9\x32\x4e\xd2\x2c\x45\x84\xbc\xcd\xeb\xc6\x35\xe5\xb9\x4f\xe8\x36\x3f\x06\x14\x03\x27\x59\xc4\x53\x47\xb1\xd9\x79\xdf\x8f\xb2\xec\x09\x41\x38\xc9\x32\x88\xe4\xc4\x35\x1e\x60\xad\x9c\x64\x32\x12\x0e\x3c\xfd\x03\x1d\x54\xdf\x4d\x75\xd9\x53\xc5\x49\xa6\x19\xef\x89\xdf\x42\xb7\xeb\xe6\xd7\x49\x96\xe6\x52\xe8\xf6\x5f\x13\xca\xd9\x70\x04\xb0\x41\x65\xf0\x2e\x2f\xc7\x3d\x89\xb3\x89\x8a\x3b\x12\x90\x53\x0d\x48\x99\x3b\xea\xcc\x09\x33\x8c\xe3\xa1\xf4\x35\xd9\x89\x22\xf3\x88\x28\x80\x13\x05\x8e\x08\xfa\x79\x90\xc8\x5f\x7b\x15\xc6\x81\x18\x7b\x7d\x21\x1b\xd9\xfd\x10\x1c\x3b\xb6\xbb\xb2\x7d\xb5\x3b\x15\x79\x8b\xc0\xbc\x19\x9d\xe4\xf4\x77\x9a\x1a\x44\x52\x48\xcf\x75\x34\x4a\x91\x70\xa2\x4d\x1c\x3b\x8e\xbf\x69\x4b\x1a\x27\x46\x70\x34\xb7\xd7\xa0\xce\xcf\x17\xb9\xd7\x89\x85\x31\x36\x42\x78\xe3\xae\x2a\x83\xdf\x7c\xac\xde\x46\x17\x34\x6c\x43\x04\x28\x20\xcf\xa7\xf7\xbd\xee\x47\x7a\xf6\xb3\x67\x0e\x2c\x8e\x9d\xdc\x4e\x69\xaa\xf7\x31\x01\x06\x27\x36\x12\x11\x09\x88\xad\x6e\x4b\xf7\x5b\x7b\x3f\x9e\x24\x82\x06\x94\xdc\x01\x63\x01\xf9\x81\xfe\xe4\xe8\x52\x2c\x28\xa4\x6c\x00\xd7\x6b\xd6\x93\x57\x0e\xff\x37\xbe\xcb\x38\xa2\x91\xf6\xfa\xbf\x87\xc7\xa7\xed\x1f\xab\x3d\xfa\x49\xbf\x85\x61\xc3\x48\x1f\x73\x62\x99\xe7\x38\x6a\x99\xe1\x31\x8d\x29\x26\xcd\x2d\xe8\x97\x3f\xaa\x16\xee\x64\x5e\x0e\x58\x6d\x1e\xd3\x4c\x65\xa1\xec\x0c\x25\x20\xb0\xab\xff\x68\x62\xaa\x5c\x82\xf6\x5a\xe6\x45\xff\x47\xa6\x93\xc8\x1b\xba\xcd\xf1\x54\x54\x1f\x00\x17\xad\xda\x5f\x71\xfc\xf1\x98\xdb\x14\x53\x4e\xba\x2a\x9b\xb6\x3e\xeb\x51\xef\xfe\xf4\x6d\xc4\x82\x90\xc8\xc5\xc7\xbf\xae\xa0\x6d\xa6\x75\x5a\x8e\x54\x88\x30\x2c\xce\xab\xfe\xef\xb1\x0a\x2e\xd4\x35\x58\x79\x2e\x5a\xdf\x79\x7b\x91\x1c\xe2\xb1\x10\x8e\x1a\xe5\xaa\x96\xc8\x31\xb4\x40\x90\x7a\xe1\xd6\xc4\x09\x4f\x9c\x47\x11\xbe\xa1\x56\xe6\x73\x56\x5e\x1e\x27\x42\x20\x77\xf7\xe6\xdb\xb7\xdd\x61\xff\x70\xf8\xbe\xda\xaf\xbf\x1f\xc8\x5a\x06\xbb\x13\x27\x29\xc5\xee\x02\x97\x4e\xbe\x86\xe3\xb9\xae\xe5\x33\x38\x82\xe4\x90\x59\xe0\x71\x92\x69\xdc\xac\xc0\x5a\x40\xa2\x94\x3b\x7c\x1e\xfd\xb0\x62\xa8\x98\xf5\xfd\xdb\x8f\xd5\x38\x17\xc9\xe3\xd4\x52\x08\xac\x01\x3d\xb1\xa5\x1f\xcb\xa8\x45\x20\x2a\xca\x18\xa8\x73\xff\x7e\x33\x2d\x21\x19\x75\x36\x39\x34\x44\x33\x0c\x3b\x78\xc5\xee\xe1\x66\x7f\x58\xaf\x1e\x0f\xdb\xfb\xc3\x66\xff\x7d\xf3\x34\x9a\x80\x99\xb1\x95\x79\x83\xba\xcd\x1d\xe8\x7f\xd7\x56\x83\x08\x0f\x8f\x25\xa5\x0e\x29\x5c\xcb\xb2\xdd\xd7\xd5\xe9\x65\x99\x7a\xa8\x9b\xe9\x84\xd5\xef\x72\x24\xcb\xaa\x47\x6b\x5b\x02\xc5\xd0\x41\x3a\x62\x95\x4f\xbc\xda\x30\xd9\x3a\x69\xc6\x9b\xaa\x86\x67\xc4\x2a\xf9\x76\xb4\x27\x68\xce\x85\x83\x5a\x7c\xd6\x4b\xe9\x0f\xa1\x92\x04\x63\xe4\x55\x5e\x5f\xd7\xd5\xe9\x51\x7e\x5c\xe5\x6d\xf3\x44\x67\x19\x76\x1e\x6b\x2d\x8d\xea\x57\x87\xc3\x0a\xdd\x9c\x0b\x9b\xbb\x8a\xd6\x02\xdf\xdc\x70\x12\xc3\x9c\x24\x15\xc2\xf8\xae\xaa\xf6\xe5\xbe\x6a\xef\xcf\x45\x11\x6e\xda\x18\xd0\xba\x87\x72\xca\xa2\xa8\xfa\x65\x00\x91\x89\x71\xd5\xff\x78\xba\xed\xff\x96\xba\xee\xb7\x1a\xa4\x59\xd5\x6d\xde\xf9\xae\x13\xfb\x02\x99\x93\xdc\x6d\xa0\xbd\x6b\x9e\x2f\xe4\x98\x78\x6c\x25\x43\x4e\xc6\xfd\xc3\x9f\x93\xa5\x65\x95\x63\xc5\xff\xb1\xbb\xbf\xf8\x60\x26\xfb\xe6\x34\xcd\x1e\x82\x13\x1a\x91\x68\x90\x26\x9b\xb9\x54\xcb\xef\x90\x46\xd2\xbd\xc3\x67\x68\x7f\xe6\xcd\xcb\xde\x13\x27\x4d\x27\x11\x29\x11\xeb\xba\x79\x83\xfa\xc3\x48\x27\xf6\xf6\xbf\x53\xa8\xe2\x34\x4e\x2c\x04\x74\x2a\x92\xff\xe2\x66\xba\x2a\x8d\x4f\xe1\x01\x72\xe3\xf8\xc9\x94\xa5\x19\x0b\xd4\x1d\x05\x7e\xba\x97\x85\x72\x4e\xa9\x4d\x30\x56\x33\xd0\x42\xdd\x39\x46\x3f\x71\x9b\x7e\x30\x93\xe2\x15\xa7\x3c\x72\xd4\x9d\xd2\x98\x7d\xfe\x49\x01\xbd\x9b\xa5\x44\x78\xb1\x9d\x33\xec\x3f\xb0\x3f\x72\x78\x0f\xd7\x25\xe2\x0c\x21\xfc\xff\x3e\x43\xfd\x41\x16\x18\x12\x38\x15\xca\xd5\x54\x4f\xb8\xcf\x6d\xf7\x0f\x87\x17\x59\x9b\x29\x28\x9f\xd3\x84\x3b\x35\xc9\xce\x43\x0d\xb0\x93\xd6\x21\xbf\xa6\x16\x8f\x26\xca\xa5\x2b\x7d\x33\x67\x5e\x3e\x0f\x69\x34\x4e\x53\xee\xf8\xf0\xaf\x36\x9b\xa7\x5d\xff\xc7\xc4\xa0\x67\x77\x40\x7b\x13\xba\xe0\x77\xe7\x53\xf7\x1c\xa7\x9f\x4a\xf8\x85\x4a\xd0\xa8\xad\x65\x51\xf4\x8c\x0a\x7f\x17\xd3\x0e\xc6\x9b\x66\x71\xa4\xd5\x08\x64\xf9\x0a\x25\x3a\x04\x4b\x0f\x28\xe3\x4e\x1b\xd5\x15\xd9\xb7\x4d\x73\x06\x33\xe2\xcd\xe0\x34\x53\x16\xf5\x50\x3a\xfb\x1d\x91\x1b\x50\x71\x44\xb2\x30\x28\x05\xf4\x12\xbb\x78\x27\xeb\xaa\xec\x8c\x62\x6f\xc3\xa8\x94\x8c\x47\x9e\x11\x0d\x33\x87\x55\x03\xe6\xe0\x6f\x66\xf1\x8a\x54\x02\xc8\x09\x39\x00\xc1\xaa\xa2\xe8\x7b\xca\xc2\x71\x75\xec\x32\x57\x47\xf9\xeb\x11\xea\x71\x0a\x9c\x53\x2d\x13\xe4\x9d\x7d\x82\xf7\x41\xfb\x9c\x53\xed\x19\xd7\xb4\x2c\xfd\x65\x4e\xb2\x40\x54\x1b\x47\xca\x75\x72\xad\xd2\x23\x02\x46\x4e\x8d\x8e\x03\xb7\xe2\xcf\xaa\x32\x8b\xc9\x0a\x6a\x4c\x96\xf8\xbe\x88\x6b\x78\x9b\x5e\x93\xb1\x1a\x03\xe9\x93\xfc\xd8\xfc\x6a\x6b\x39\x2d\xbe\xfb\x49\xc0\x65\x3c\x86\x34\xb8\x5c\xec\x97\x1d\xf6\x9c\x82\xb0\x58\x8a\xf1\xd0\x85\x6e\xd1\x8e\x31\x73\x9c\x82\x76\xbc\xa5\x0e\x30\x5d\x1c\x87\x54\x0c\xb5\x90\xba\x95\x22\x0b\xfd\xa3\xbc\x93\xcd\x2b\x98\x8d\xac\xcb\x31\xda\xac\x9f\x6a\x31\x82\x70\x0c\xfc\x27\x99\x7f\xbe\x24\x17\x92\xd0\x9c\x45\x3c\xc6\xc6\xba\x2e\x76\xea\xaf\x8d\x45\x82\xa0\xc7\xb9\xdf\xaf\x2f\x3b\xbe\x39\x8b\x52\x99\x7a\xc2\x85\xb5\x6c\x5e\x7a\xb6\x4a\xce\x22\x49\x33\xe1\x94\x0d\xab\x3a\x48\xc6\x8d\x40\x22\x61\xaf\x62\x84\xe8\xb4\x87\x8d\x77\xd6\xed\x1d\x9c\xd9\x59\x82\xa0\xa4\xe1\x47\xcc\x20\xcb\xbe\x8a\x9b\x11\xda\x82\x33\xa2\x29\x82\xf6\xdb\xea\xd0\xf9\xab\x79\x10\x2c\xe6\x8c\x80\x2b\xbb\x37\xe7\xe3\x76\xfd\x80\xa5\x26\x16\xc6\x62\x11\xa5\x71\x80\xa2\x99\xea\xbd\xbc\x06\x5d\xc3\x71\xf4\x18\x3a\x0b\x64\xc3\x9a\xff\xd1\xa0\x42\xf3\xeb\x8c\xca\x85\x33\x6a\x9d\xd8\xee\x44\x79\x67\x5f\x5d\xea\x25\x70\xc6\x28\xc1\x0a\xf6\x53\x67\x01\xbe\xc9\x23\xca\xe2\x6c\xf7\xdf\x96\x83\x19\xc6\x52\x82\xc9\xba\x89\x9e\xcb\x9d\xd7\x73\xe9\xef\x83\xa5\x12\x11\x80\x9e\x20\x62\x65\x9c\xa5\x08\xc4\x50\x61\x96\x34\xd8\x1d\x29\x8b\xe2\xea\x63\x2a\x70\x3b\x3f\xab\x76\x8c\x84\x03\x4e\xd8\x4b\x95\xcd\xbe\x0b\xc6\x53\x86\xf4\xa8\x07\x5c\x7c\x4e\xbd\x68\x5b\xbe\xe5\x2d\x18\xcc\x59\xcf\xdd\x9a\xc1\x16\x32\x9e\x8a\xf0\xe1\x3e\x6e\x5d\xab\x12\x11\x93\xfd\x88\x09\x02\xf8\x7d\xdc\x8d\xb7\x7f\x26\xa4\x89\x06\x89\x3d\xdf\xf9\x30\xf9\x5d\x9a\xc6\x58\xcc\xde\xfc\xba\x92\xad\xc4\x5e\xe5\xa1\x7e\xde\x0d\x4b\x7c\x05\xea\xfc\x31\xd2\x19\xe1\x2c\xa3\x8e\xef\x04\xe1\x84\xc8\x36\x19\x28\xe6\xe6\xef\x5b\xc6\x31\xe2\x44\xcc\x4b\x75\x92\xaf\x7d\xca\x63\xbe\x70\xff\x09\xc8\xa2\x3b\x98\xeb\x56\x08\x54\x91\x0e\x5a\xe8\xb9\x22\x7f\xeb\x27\x49\x8c\xa2\x47\x6c\x7b\x61\x44\x3a\xcd\x90\x67\x68\x1f\x5f\x2a\x28\xf3\x5f\xb3\x09\x2a\x72\xfd\x12\x9f\x89\x30\x4c\x6f\x4d\x45\x22\x4a\x07\xbe\xc6\xf9\xb1\xb4\x46\xe0\xe4\x31\x2f\xf3\xf2\x7c\x1c\xd0\xc0\xc3\x9e\xcd\x94\x65\x4e\xd2\xe3\xa3\x71\xf2\x46\xc7\xbc\x28\x06\x0f\x9c\x69\xee\x36\x01\x84\xab\x56\xfa\xf5\xea\xfc\x81\x89\x51\xcf\x18\x36\x3d\xa1\xe6\x86\xb2\x91\xe2\x7a\xd8\x6c\x16\xd3\x40\x4c\xa7\x89\xa2\x43\x51\xb3\x3f\xa3\xcc\xac\xdf\x0c\x0f\xc7\x8f\x09\xf1\x17\x67\x5a\xbb\x9e\x35\xfc\xc2\x51\x55\xac\x1f\x32\x14\x62\xd6\x0b\x27\x54\x75\x33\xdd\xea\x98\xc9\x94\x62\xc8\xfc\x50\xbf\x62\x8f\xca\x65\x38\xfa\x77\xb5\x90\xe5\x25\x61\x8c\xd3\x41\xfb\xd6\x17\x48\xaf\xa0\x3d\x8c\xb0\xe6\x9c\x19\x2b\xe5\x00\x14\xee\x1b\xcb\x38\xb3\x89\x4a\xed\x50\xd1\x1a\x88\x84\x39\x8f\x78\xac\x7c\x6d\x0e\x61\x6e\xa5\x86\x45\x85\x64\xce\x23\x2b\x93\x38\xa8\x6c\x34\x50\x36\xe7\xe6\x41\x61\xa4\x39\x5b\x7e\x9c\x28\x62\x1c\xc2\xa8\xfa\xf5\x11\x78\x36\x16\x97\x16\x27\xc6\x78\xf2\xd9\x19\x8f\x21\xe7\x31\xcf\xb4\x0a\xcd\xa4\xcd\x38\x7f\xc4\xe3\x54\x4a\x4f\x43\xb8\x6d\xe1\xb8\xaf\xb6\xa5\xc3\x04\xff\xd3\x62\xc2\xf2\x33\xe6\x54\x53\xe6\xf3\x52\x7e\x63\xbd\x83\xb6\xce\x75\xb3\x1c\x0e\x72\x6a\x0d\x33\xc1\x1f\x3b\x20\x56\x31\x0e\xd7\xc8\x23\x82\xb9\xa3\xdd\x59\x05\x2a\x8e\xc9\xe6\x15\xf6\x3c\xce\x23\xc9\xc9\xa0\x8e\xee\xbd\x15\xf4\xa2\x2f\x68\x66\x47\xdb\x1b\xc7\x08\xa4\xdb\x8d\xa1\x69\x27\x99\xef\x30\x2e\x9c\x7c\xc9\x35\xc8\x02\xea\xdd\x80\xd1\x0b\xe3\x86\xa3\xe4\xc2\xa9\x7b\x4b\xa8\x6f\xd3\x0f\x28\x12\x85\xbb\x0a\x3c\x3f\x5f\xa2\xa7\x39\x17\x82\x10\x70\xf0\xf5\x7d\xe5\x14\xa1\xa7\x13\x12\x61\x1d\x73\xc1\x00\x95\x9e\x18\x68\x9e\x24\x91\x0c\xca\xa4\xba\x42\x7f\x8e\x2c\x47\x1b\x3c\x49\x52\x30\xa3\x5e\x45\x67\x8f\x1d\x27\x81\xef\x5b\x1c\x90\x3b\x9c\x27\x99\x72\x2a\x4b\x3e\x63\xef\xf5\x53\x16\xcd\x05\x4f\x24\x0f\x8a\x0c\x3f\x41\x9e\x2e\x98\x7d\xbe\xe8\xdb\xe0\x3c\x51\x0c\xb9\xdc\xb1\x61\x6b\xbe\xcf\xcd\xa6\xea\x04\x9d\x71\x5c\xf6\x53\x35\xa0\x4f\x1e\x71\xca\x25\xe2\xd4\x8e\x88\x8d\xc3\x1d\xd5\xab\x2a\xcd\xce\x34\xa6\xff\x0e\xbf\x4d\x39\xe2\x5f\xe4\xe9\xd4\xcc\x33\xdc\x61\x8a\x71\x20\x43\xb7\x6f\x05\xe1\xbf\x4b\x37\x8f\x67\x11\x68\xff\xf1\xed\xe5\xf3\x12\xf1\x11\xe7\x99\x80\x18\x7a\x39\xbb\x0b\x66\x73\xce\xb3\x54\x21\x58\xd9\x15\xc1\xd6\xf2\x78\x92\xf9\x73\x39\x9f\x94\x11\x2a\xfa\xe4\x36\xf4\x2f\x34\x53\x31\xb2\x60\x3b\x31\xc5\xd5\x64\x15\x84\x39\x32\x96\xa8\xf3\xf5\x37\xbd\x45\x97\xd1\x36\x97\x34\x8d\xcc\x28\xe3\xd4\xf9\xe7\x0e\x8e\xb4\x18\x48\x70\x45\x29\x86\x40\xcf\xf2\xa8\x0a\xa8\x7b\x03\xa0\x2c\x61\x03\x4b\x1d\x40\x73\x9b\x37\xed\xb8\x03\x9d\x73\x1d\x39\xad\x43\x47\xc8\x30\x21\x24\x59\x5c\xf8\x3a\x89\x30\x3e\x73\x3c\x7b\x13\x90\x24\xe7\x5a\x66\x4e\x73\x15\xcf\xb7\xe4\xa3\x70\xc3\x22\xec\xcb\x3b\x60\xbe\xe6\xb6\xd2\xaf\xe7\x53\xf8\xb9\x49\x85\x4a\xbd\xa2\x4f\x79\x06\xfc\x48\x1c\xab\xdc\x24\x27\xce\x8d\x66\x22\x78\x9f\x7e\x23\xda\x9c\x2a\xfd\x82\x26\xf8\x2d\x30\xbc\x70\x6e\xac\xfb\x90\x0a\xb0\x6d\xca\x66\x6f\x16\xa4\xa3\xc2\xc6\x5d\xe7\x47\x33\x05\xc0\x73\x0e\x2a\xc1\xeb\xd4\x48\x50\xfb\xfa\xa9\x44\x68\x28\x24\x7d\xf9\x89\x2e\x73\xd2\x86\x33\xd9\x14\xfb\x05\x3c\xe2\x73\x08\xc4\xb8\x25\x49\xcc\x67\xcb\xa0\x6c\x1f\x2c\xa6\x7c\xfb\xa7\x61\x85\x1d\x1a\xa1\x7c\x59\xfb\x5c\x8f\x8e\x62\x44\x4c\xc3\x78\x8f\x3b\x0a\x83\x20\x59\x90\xf6\x97\xe5\xeb\x35\xb4\x32\x2f\x9a\x31\x2a\x89\x73\x6b\x1d\xbd\x47\x21\x9b\x16\x4f\x7d\x78\x23\xe2\x3b\x6a\x67\xbb\x1b\xf1\x07\x13\x24\x11\x88\x9a\x7e\x5c\x5f\xcf\xb0\x8b\x5c\xc4\xb1\x6b\xd7\x6a\x06\x55\x1c\x0c\xae\xc6\xca\xdd\xd3\x07\x23\xe2\x2e\x10\xf2\x58\xf6\xf3\xf1\xb1\x6a\x90\x18\x7b\xe8\x6d\x99\x21\xbf\xc6\x5f\x90\x88\x05\x68\xd5\x53\x39\xe1\xa7\xd3\xf4\x97\x92\xb1\x68\x68\x98\xf2\xf9\xf0\xfe\xc1\x2c\xda\x4a\x41\x55\x12\xb6\xe5\xc7\xd5\x88\x3b\x73\xfc\xa0\x04\xb5\x14\x4b\x6a\xc1\xca\x37\x8f\x72\x50\x17\xe7\x82\x31\x6b\x44\x7f\x4d\x8e\xc6\x77\x8e\xfa\xe7\xa2\x33\xcc\xf1\xd0\x25\xfc\x75\x16\x57\x30\x90\xb4\x27\xe8\xfa\xa3\xca\x7b\x69\xdb\x70\x52\x4e\x5d\xaf\xab\xdb\xf4\xea\xfe\xcf\xc2\xa5\x6e\x4f\xc4\x7d\x88\xe1\xef\x22\xcd\x70\xb1\xac\xf2\xd7\x81\x46\xa8\xfb\xb3\x23\x43\x7d\x78\x5a\xad\x6f\xb7\xff\xb5\x39\x7c\x5b\xed\xfa\xb1\xcc\x05\xcc\xa7\xba\x6a\x9d\x52\x5e\x28\x4b\x57\xd8\x1f\x3d\x2b\xf6\xfa\x5f\x25\x52\xf8\xda\x7e\xfb\xe7\xfa\xb1\x38\x3f\x0f\x27\x4b\x34\x47\x06\x9e\x2e\x10\xf2\xa9\xc6\xb7\xe9\xc7\x2b\xd2\x08\xa2\x6c\x20\x69\xce\x7f\xc1\x0c\xce\xc7\x45\x6a\x15\x1a\x2a\x9b\x97\x79\xf3\x82\x6d\xa7\xab\xd2\xec\x1c\x6a\x21\xac\x7f\x91\x19\x95\xca\x69\x03\xde\xfe\x97\xfb\xce\x7e\xff\xf9\xb2\xec\x73\x09\x19\x65\xb8\xfd\xcc\xf5\xd2\x26\x7c\x64\xd3\xf5\xa3\xe3\x14\x69\x3c\xac\x17\x8e\xf3\x41\x73\xb8\x0c\x2d\x58\x68\xdb\xe8\x82\xef\xe6\xc1\x98\xb9\xfa\x3b\x17\x3a\xd5\x8e\xa8\xc9\x4b\x6f\x9f\x86\xa5\xa5\x55\x82\x89\x60\x19\x9a\xe8\x46\x23\x12\xcb\x95\xde\x84\xfe\x94\x75\x73\x05\xad\xec\x87\x01\x82\xca\xbf\xbb\xeb\x47\xa8\x9d\x43\x3f\x7d\x9a\x96\x6a\xaa\x02\xc5\x4f\x29\x8b\xad\xae\x6e\xf0\xc1\xce\x3d\x6f\x61\xc1\x19\xdd\xb2\x6a\xe5\x02\x00\x64\xf6\x6f\xb8\xb9\x24\x22\x02\x8b\x2f\x77\x43\x17\xd7\x6f\x61\x88\x67\x91\xeb\xf2\xbb\x05\x14\x76\x66\x37\x37\xd3\x5d\x25\x89\xb8\xeb\x08\xb8\x7a\xcf\x67\xbf\xcd\x98\xf6\x65\xf2\x60\x8a\x12\x12\xb9\x46\xaf\x06\xfa\x2a\x42\x42\x98\x46\x64\xd0\xfe\xe1\xf7\xcd\xfd\x61\x7d\xbb\xda\xde\x1d\x7e\xae\xb6\xfb\xed\xfd\xb7\xc3\xe3\xe6\x69\xfb\x70\xdd\xcf\x94\x89\xf5\x78\xc3\x11\x8d\x22\x4f\x88\x71\x94\x91\x37\xe7\xce\x5d\x5e\x6c\x76\x39\x3b\x58\xfd\xb4\x28\xf0\x79\x69\xa0\x7f\xa6\x09\x65\xae\x71\xad\xc9\xff\x03\x0f\x76\xeb\x3f\x2a\xd2\x0f\x27\x8a\x0c\xed\x03\x4b\x8a\xfa\x3c\xa1\x19\x01\xde\x7f\x31\xdf\x46\xf5\xde\x30\x41\x32\x04\xe3\xe4\xba\x62\x83\xe4\x11\x4f\x98\x01\xe9\x4b\x87\x57\x35\x40\xf7\xfc\xe7\x4a\xfb\x3c\xe1\x84\xa0\xab\x53\xc2\xfb\x27\x72\x2a\xb3\x3b\xe2\xdd\x27\xe1\x16\xfc\x8f\x2b\x68\xd7\x2f\x30\xec\x68\x09\xe7\xc6\x1b\xca\xbe\x49\x6a\x76\x3e\x41\x22\x77\x37\xe8\xbb\x8d\x5b\x1a\xa6\x84\x47\x7f\x57\x7f\xfd\x9b\xe7\x2e\xa4\xa0\x3c\x74\xfc\x39\x48\xee\x5a\x9e\x96\x43\x82\x24\xe1\x2e\x7a\x70\xfd\x83\xdb\x12\x19\xda\xde\xe0\x02\xe4\xcc\x93\x24\x89\x4c\xea\x90\x89\xdb\xf5\xc3\xdf\x75\xe9\x86\x1f\x65\x2c\x0e\x95\xcb\xd1\x0d\x8f\xf6\xd8\x24\x4d\x2c\x06\x25\x3f\xab\xc2\xd6\xf2\x18\x90\x65\x4e\xb9\x34\xcc\x49\x35\xf8\xed\xe5\x6d\xf6\x11\x65\xb1\x08\xb6\x70\xa2\x44\x13\x86\x53\x8e\xdf\xd8\xc0\x77\x3e\xda\x84\xff\xf1\x3f\xe1\x60\x3a\x8d\x86\xe5\xe8\x70\x5b\x6d\x85\xf4\x42\x1f\xb3\xf3\xca\x98\x60\xc7\xda\xb7\x73\x51\xe4\xe3\xf0\x31\x91\x69\xe6\x60\x98\xa7\x29\x01\xf3\x3f\x7d\xdb\xfe\x30\x8a\x01\x76\x83\x1c\x1a\x68\xef\xaa\x1a\xc6\x4e\xd0\x3f\x09\xe0\xa7\x4f\x51\x29\x81\xec\xb4\x8e\xf9\xaa\xb3\xf5\xae\xbb\xcf\x0f\x6b\x11\x05\xc5\xa3\x6d\x0b\xc7\xde\x07\x9a\xd5\x40\x17\xbd\x90\x44\x43\x44\xe3\x31\x60\xae\x0b\xd1\x37\xf3\x3c\xdf\xf4\xee\xb4\x75\x92\xf2\xba\x3a\x9f\x66\x86\xd5\x10\xaa\x03\x04\x08\x1f\xe0\x15\xb4\x8b\xa0\xbf\xc4\x98\x54\xd1\x80\xf7\x6e\x5a\xa8\x7f\x87\x8f\xd9\xea\x01\xce\x03\x98\x6f\x55\x14\xd8\xc5\x9e\x0f\xcb\x0e\x52\xab\x93\x31\xbb\x8d\xc7\x74\x3b\xff\xe9\x93\xdb\x05\x6b\x31\x07\xf6\x0d\xda\xbb\x8f\x5d\x89\x2f\xc5\x0f\x59\x66\x98\x13\x4c\x38\xf6\xfd\x77\x3c\xb1\xdc\x49\xc5\x78\x6a\xd6\xfc\xf9\xa5\x9d\x6e\xb4\x69\x24\x33\x1e\x05\x20\x84\xeb\x50\x7c\x82\x93\xef\xae\x28\xe0\xa6\xaa\xb1\xda\x82\x2a\xf2\x98\xa4\x1a\x49\x1c\xf0\x34\xd2\x9a\x87\x98\x72\xb6\xfb\x4d\x9f\x7a\x1a\xa7\xcc\xfa\x2a\xf2\x6a\x7d\xfb\x54\x15\x90\x90\x98\x66\x51\x16\x13\x9a\x45\x09\x4f\x49\x94\xc5\xd3\x27\x98\xd2\xc4\xc9\xd8\xb9\xab\xbf\x95\x68\xc7\xe5\x62\x74\x9b\x32\x42\xbc\x7e\x4d\x89\x9a\xab\xcd\x6f\xd3\xcd\x25\x4c\x93\x16\xed\xa4\x3a\x7f\xdc\xca\xa3\x0a\xd5\x87\x94\x47\x02\x93\xbb\x4e\xe4\x09\x29\xc2\xb0\xb5\x74\x6b\x1f\x4e\xfd\xfa\x48\xb9\x34\xe8\x28\x1b\x28\xe4\x87\xf7\x93\x57\x23\xd5\x2d\x9e\x0a\xc9\x49\x12\xb4\xf4\x5a\x59\xec\x4e\x55\xd9\x54\xf5\xdf\x68\xea\xf2\x54\x00\x73\x32\x83\x2e\x73\xb9\x2d\xbb\xf5\x17\x0e\x9a\x90\x0c\x2b\x88\xb5\xd4\xb0\xaf\xae\x64\x03\x97\xcd\x55\x3c\x4d\x68\xec\x18\x7a\x2a\xaf\x41\x37\x78\xd2\xb3\x93\x25\x4c\xa3\xe1\x7a\x84\xba\xa9\x4a\xb9\x35\xe0\xc8\x22\xc3\x30\x8f\x70\xf7\x54\xb2\x81\xad\xae\xc6\x59\xbe\x34\xf5\x2d\x15\xa3\x6a\x40\x3c\xc9\x19\xa5\x19\x17\x71\x68\x4a\x7a\x93\xad\xfc\xa4\x76\x91\x4a\xe1\x78\x98\x6a\x40\x76\xd0\xb0\x4b\xfa\x51\x45\x58\x12\x18\x55\xbb\x0d\xd6\x2f\xae\x91\x71\x4f\x75\xa6\x71\x7b\xf9\x00\x59\xd3\x1f\xe5\x28\x0b\x9f\x1a\x9e\x09\x5f\xb0\xbb\x73\xe5\xfd\x66\x73\xcc\x43\xa3\x30\x4f\x4d\x26\x94\x1a\xc5\x25\xb7\xd8\x26\xed\xb9\xc2\x3f\x2e\x9f\xdb\x17\xbc\xba\x3c\x35\x32\x49\x10\x39\x36\xb0\x91\x7d\xb9\x71\xa5\x40\x52\x4c\xc5\xae\xee\x6e\x1f\xde\xa0\xb3\xdf\x5e\x7d\x64\xba\x54\x21\x49\x83\x6c\xea\x4e\xbf\x40\x51\xe4\xe5\xb3\xe3\x7e\x9d\x1d\xce\x1a\x64\x7b\x7a\x1b\x4a\x48\xa9\x4d\x29\x16\x52\x8f\x79\xb9\x1b\xea\x69\xe4\xc7\xee\xba\x9f\x21\x19\x96\xa2\x9a\xf3\xf1\x18\x7a\x29\x3c\x3e\xac\x9f\x62\x9d\xc2\x69\xef\x43\x5f\xa1\xf3\x81\x28\x95\x79\xbd\x2c\x8b\x84\xc2\x3c\xf7\x13\x74\xab\x41\xb7\xa3\x26\x89\x2c\xca\x64\x10\xdf\xeb\x89\x4d\xb1\xec\x34\x3d\x04\x91\x19\x02\x02\x5d\x83\xd7\xae\x85\xd3\x34\x54\x1a\xff\x37\xfc\xc4\xbb\xf9\xdd\x25\x75\x26\xaa\x99\x1f\x52\xbb\x16\x26\xdb\x33\x3b\xf1\x2c\x8e\x53\xcc\x83\xdd\x5e\xad\xfb\x3f\x69\x43\x7a\x45\xe1\x89\x46\x6d\xf3\x92\x9f\xfa\x59\xd6\x25\xd9\x9c\x17\x76\x95\x9b\x4f\xf2\x95\x19\x65\x29\x22\x74\xae\xb6\xbb\xfd\x66\x82\x89\xc9\x28\x33\x81\xf1\x37\x7c\x76\xf7\x3d\x67\x1b\xcf\x18\x91\xc8\x34\x86\x3e\x4d\x7e\x84\x07\x7b\x0f\xef\xeb\xba\xfb\xce\xfa\x29\x5c\x62\xbf\x83\xd7\xa8\x1a\xcb\x62\xf1\x8c\x89\x0c\xc3\x26\x74\x11\x7b\x02\xb1\x8b\xf5\x3c\xbb\x5e\x96\x38\xf6\x8b\x6e\xa5\xbd\xe6\x45\xf1\x35\xc8\x26\x63\x59\x82\x11\x54\x35\xca\x44\x6d\xcb\xdb\x1f\xfb\xdf\x66\xf3\x4c\x84\x14\x28\x06\x90\x17\x64\x20\x41\x9e\x9e\x9d\x47\xda\xf8\xe8\xc3\x4a\x6f\xb9\xc2\x10\x65\xe8\xcf\x98\xd0\xec\x83\x3b\x58\xf3\x60\x0f\xb3\xf7\x2c\xb8\xcb\xc8\xcc\xb7\xfe\x30\x9c\x70\xe4\xb7\x36\x80\x68\xc4\x1e\x14\xbe\xdc\xeb\xc4\xb3\x24\x71\x5a\xb2\x33\x80\x78\x3f\xea\xd4\x41\x6f\xb7\xf7\xeb\xc9\xcb\x4d\x8c\x46\xd8\x6e\x20\x69\xdf\xbf\xd4\xd0\xbc\x0c\xa1\x43\x96\x52\xe5\x0a\x55\x4d\xa0\x10\xf0\x28\x96\x3e\x3c\xcd\x32\x1a\xa5\x4e\xb4\xf3\x63\x1d\x98\x2f\x78\x26\x63\x27\x2e\xa5\x65\x6d\xbc\x37\x86\xe0\xe4\xe9\x85\xc9\x6e\x87\xf2\xf2\x32\x23\xfa\x93\xfe\x20\x82\x63\x47\x69\xb0\x7a\xdb\x12\xa3\x9e\x2f\x37\xa6\x4c\x42\x16\xd4\x8a\xef\xe0\xa8\x46\xb4\x0c\x73\xb0\x7a\x30\x88\x99\x8a\x0c\xca\x26\xf5\x92\xf9\x01\xc2\x89\xe4\x54\xcb\xa9\xee\x4c\xc5\x1a\x43\x9c\x87\x77\xec\x26\xf8\x99\xb7\x2f\xf3\x32\x87\x5f\xbf\x69\xf8\x05\xcd\xb0\x7e\xe9\x77\xbb\xc3\x18\xe8\x9d\xe9\xc4\x7d\x67\x98\xa6\xde\xea\xea\x47\x63\xd6\x50\xb6\xe3\xbd\x2c\xd3\x2a\x56\x88\x0d\x7d\xee\xc2\xb8\x3d\x42\xae\x16\x5a\x48\x32\xad\x0d\x16\xcf\x8f\x95\xc9\xed\xc7\xb8\xac\x13\xcf\x66\x82\x52\x98\x42\xbd\x5a\xdf\x0d\xda\x3b\x3c\x03\xcd\x5d\x9f\x22\xb4\x0f\xe5\xba\x2a\xce\xc7\xf2\xb7\xf1\x9d\xd8\x8c\x5a\x9f\xfa\xb9\x3a\x23\x92\x72\xf1\x3b\x95\x84\xc6\xf8\xa5\xdc\xc2\xb1\x2a\x77\x50\xd8\xeb\xba\x3a\x79\x82\x37\x2e\x09\xa7\x48\xae\xef\xc2\xad\xf1\x9d\x4a\xa2\x32\x0c\x95\xaa\xf2\x6a\x2c\x9b\x34\xb9\x78\x49\x4c\x82\x56\xe0\xd0\x56\xea\xfc\xf1\x19\xab\xc5\xfc\x47\x96\x0c\xa5\x4a\xf4\xef\xc3\x26\x2b\xe3\x2e\xa4\x0d\x77\xa5\x5f\xa1\x7d\x78\xef\xd9\xa6\xa6\x07\x89\x25\x45\x82\xff\x90\x3e\xda\x83\x3c\x3e\x42\x6d\xfb\xd7\x29\x69\xa2\x70\x75\xbc\x7e\x68\x9f\x61\x9f\x80\x83\x24\x4d\x89\x70\x32\x8e\xb5\xcd\x1d\x4f\x90\x1c\x06\x95\x93\x59\xf1\x9e\x06\xea\x2a\x16\x60\xfa\x4c\x85\xa4\xda\xed\x22\x1e\xfb\xed\xcb\x55\x33\xfe\xbd\x7f\x16\x3b\x49\x16\x39\x01\xfc\xee\xfb\x9f\xed\x46\xf2\xff\xa7\xec\xcd\xba\x1b\xd5\xb1\xbf\xe1\xef\xf2\x5c\x9d\x8b\xbe\x40\x80\x06\xde\x3b\xc7\x49\xaa\xd2\x27\x83\x3b\x76\xea\xf4\xb0\x7a\x79\x69\xd8\x4a\xe8\x60\x70\x03\x4e\x2a\xfd\xe9\xdf\xc5\x96\xc4\x64\x92\x3a\xff\x9b\xae\xd3\x41\xc6\x18\x84\xb4\x87\xdf\x90\x52\x96\x51\x1f\x58\x39\xfd\xc5\x31\x88\x4e\xa6\xc2\xcd\xb3\xee\x86\xe5\xcf\x28\xe0\xd3\xb3\x84\x27\x15\x6e\x99\x4a\x87\xa2\x09\x2e\x5f\x9b\x11\xf5\x7d\x36\x67\x78\xec\xf0\x76\x88\xde\xb9\xae\x6a\xe4\xdf\x82\xff\x27\x9c\x8f\xa7\x09\x9a\xfa\xec\x1e\x76\xab\xdb\xfd\xea\xe6\xf1\xf2\xf1\x61\xb3\xb9\xba\xdc\x63\xf5\x67\xdb\x0f\x53\x59\x46\x46\x46\xee\x9e\x6a\xf0\x5d\x36\x2f\x7d\x62\x23\x85\xb0\x0e\xf8\x1c\xdc\xf9\x83\x05\xcb\xbc\x7c\x27\x85\x11\x58\xe1\xda\xe4\x9b\x7c\x94\xc5\x4a\x19\x53\x0c\x64\x7f\xdc\xac\x27\x7f\x4e\xe2\xb4\xc7\xb5\xee\xbb\x48\x65\x2e\xfb\x1c\x16\x13\x29\x19\x64\xa2\xc7\xe4\x8d\x65\x26\xce\x1f\x98\xe4\x0e\x96\xf5\x60\xed\x1d\x94\xa7\xbb\xaa\x6e\xa0\x18\xaf\x9b\x52\x8a\x04\xab\x13\xaa\x7b\x06\xd5\x71\x64\xf9\x43\xa5\x22\x5c\xf9\x78\xd8\x29\x3a\xf7\xd4\x66\x2a\x15\x4b\xf0\xdd\x70\x2e\x36\xd7\x00\xcd\x4d\x79\x71\x9c\x4f\x0a\x25\x00\x09\x35\xdd\x4f\x6d\x4c\x75\x38\x53\x60\xa7\x52\xe9\x88\x25\x83\xcc\x81\x34\x60\xbc\x7c\x74\x18\x00\x71\x24\xc7\x00\x88\x73\x9f\x03\x2a\xb5\x4e\x11\xc8\xef\x99\x68\xab\x03\x94\xa6\xcb\x71\xee\x64\x69\xce\xca\x63\xd2\x24\x54\x85\xea\xca\x5a\x16\xc5\xb4\xe3\x24\x0d\x75\xb6\x92\x9b\xc7\x2b\xf4\x73\xbf\x7c\x7a\x44\xa9\xf4\xfe\x38\x44\xd4\x4f\x95\xa7\x36\x2f\xf2\xff\xe1\xc2\xfa\xf8\x99\xcd\x11\x95\x90\x72\xc4\x7e\xac\x65\x6d\x02\xd3\x2a\x1c\xb2\x96\x91\x11\x10\xa5\x4b\xb5\x71\xf3\xf0\x71\x61\x38\x85\x4d\x15\x96\xd0\xfe\xfa\xd7\xc9\xe3\xb3\xdc\x39\x38\xe4\x65\x00\x0c\x9d\x63\x98\x55\x64\x1d\x92\xa3\x01\x59\x74\x6b\xe4\xcc\x1b\x9a\x2a\xc2\x25\x6e\xfa\x03\xd4\x6a\x7f\xac\xf3\x37\xd9\xc2\xbe\x91\x05\xec\xf1\x71\x7c\xb9\x56\xa2\xe0\x9a\xd7\x58\xf8\x03\xe0\x35\x71\xf2\x8b\xfe\x60\x4c\x78\x90\x06\x58\x5f\xac\x9c\x7c\xc9\x1d\x34\x8d\x7c\x06\xdf\x9f\x9c\x4c\x1b\x15\xb3\x04\x41\xd7\xbd\x54\x38\x20\x8e\x76\x9c\x8a\xa9\xc4\x6b\xb6\x7e\xdb\x5d\x8c\xef\x88\x4a\xa8\xa5\x83\x03\xa0\x2b\x3c\xf4\x17\x92\x58\xc0\x16\xe9\x3f\xc2\x1f\xd2\x98\xa1\x9c\x9e\x9b\xf9\x49\xd4\x7c\x1c\x54\x10\x83\xa6\x8a\x46\x31\xa5\xc1\x09\xad\x7a\x1d\xf9\x4e\x2e\xdf\x04\x4a\x52\xac\x9b\xef\x9e\xee\x6e\x70\x75\xf9\x75\xf7\x57\x51\x41\xa4\xaf\xf2\x6c\xaa\xb6\x8b\x9a\x65\xb1\xa9\x2b\x3b\x2a\xaa\x4e\xc7\xcb\xd4\xfd\x6e\x68\xc7\x58\x1c\xc5\x52\x82\x92\x77\xdf\xbf\x3f\x62\xc6\x37\x1c\x60\x11\xb6\x69\x11\xbd\xeb\xf2\xc5\x5d\x75\x13\x5e\xa6\xe5\xfd\x52\x31\xad\x71\xc6\xde\xad\xfe\xbe\xbf\xbb\xb9\xfc\xf6\xb8\xba\x0c\xa4\x1b\xc5\x63\x6e\x93\xc1\x09\x6c\xfa\x6e\x29\x9e\x3a\xd3\xf6\xed\x76\xf3\x54\x06\xa8\xea\x8c\xaf\x4e\x15\x37\xde\x90\x0a\x5a\x27\xe0\x37\xf3\xb0\x1a\x81\xf4\x14\xb7\x06\x23\x83\xdd\x0b\x7c\xeb\x56\xbb\x3f\xf2\xe6\xe5\xc1\xae\x5f\xf2\x32\x34\x36\x94\xf0\x7d\x0f\x5b\x54\x55\x7d\x5b\x3d\xcf\x62\x17\x25\x74\x84\x6f\xcf\x51\xd6\x1a\x8a\x6f\xff\xc3\x10\x0c\xa7\xe8\x83\xb5\x23\x26\x9c\x12\x56\x62\x70\x8c\xf7\xe9\xff\xa0\x06\x3b\xbb\x7d\x99\x96\xa1\x3c\x36\xf4\x57\x7a\xf0\xbf\x92\x40\x9c\xe0\x94\xac\x57\x5a\xcf\x8b\x1d\x4a\x02\x4d\xb2\xd9\x56\x04\x1b\x59\xb7\xb9\xce\x8f\xbd\xa5\x3e\x55\x0a\x00\xeb\x08\xf5\x01\xc5\xe2\x66\xb7\x58\xd9\x0c\x95\x69\x77\x1e\x83\x75\x66\x3e\x44\x95\x36\x4e\xaa\xfd\x22\x6f\x7f\xe4\x06\xaa\xd1\x8e\xa4\x4c\xe2\xb8\x75\x79\xd9\xde\xc1\xa1\xaa\x3f\x9c\x9c\xd2\xe4\xf3\x86\xdb\x20\x34\xe4\x2d\x12\xdc\x15\x9c\x37\x3a\x95\x91\x14\x4d\x9c\xb6\x9b\xab\xf5\xcd\xea\xf6\x66\xbb\xdb\x6f\x77\xab\xdf\xaf\xf6\xbb\xef\x8f\x57\xfd\xd4\x32\x46\x29\x27\x1e\x2b\xcb\xd7\x66\x55\x14\x5e\xa7\x6a\x5c\x54\x55\xc6\x82\xf1\x69\xe6\xca\xd4\x4b\xbe\x37\x54\x01\x73\xcd\x69\x74\x8b\x6a\x06\xb2\x90\x02\xc5\xc0\x21\xc3\x5b\xfd\xb2\x7a\x96\x79\xd9\xe0\xbb\x1d\x9e\xd0\xd7\x11\x90\xb2\x54\xa3\xba\x51\x17\x01\xfb\x98\xf0\xa2\x92\xb5\x79\x6a\xf2\xf2\xf9\x72\x96\x81\x85\xef\xb4\xc6\xc9\x84\x48\xe3\x81\x37\xc3\x6d\x5a\x8c\x85\x75\x24\x38\x19\x14\x45\x7d\x8a\x3c\x1d\x42\xe2\x24\x75\xd6\x39\x0b\x25\x99\x85\x1a\xbc\x26\x31\xc5\x6a\xc1\x6d\xf5\x7c\x57\x95\xf0\xb1\xab\x66\x0d\x89\xa5\xca\xa3\x26\xd4\x89\xcc\x3f\xfc\x6f\xec\x39\x42\x35\x61\x32\x98\x9c\xcc\x2c\xc6\xa8\x26\x3a\xb3\x3a\x68\xe7\x7c\x38\xb9\xcc\x51\x5d\x55\x27\xd4\x62\xed\x67\xaa\x53\x33\x41\xd3\xe8\x44\x44\x14\xa3\x02\x59\xbe\x0e\xc8\x01\x7f\x30\x25\x04\x0b\xe3\x7b\x38\xe4\x6d\xcf\x63\xf2\xf2\xf1\x93\xe7\xa5\x53\x92\x06\x74\xbb\x83\xcb\xfb\x14\x6d\x76\xc3\x53\xc6\x48\x00\x61\x05\x37\x40\x30\xe3\x7c\xc2\x0f\xa4\x09\xb1\x49\x2f\x60\x75\x99\x37\xb8\x6a\x8d\xf3\x11\x4d\xb3\x28\x75\x0e\x6b\x85\x2c\x9f\xdb\xf1\x5d\xa3\x4a\x48\x7f\x67\xf6\xcf\xa3\xf4\x34\x1c\x36\x80\x3c\xb7\xee\xdb\x07\x13\xb0\xd9\x2f\x62\x34\xc5\x99\xbd\xab\xe5\xdb\x34\x96\xd3\x4c\x0a\x9e\x06\x02\x26\x46\xa6\xdb\x3c\x04\x6c\x9a\xcb\x28\x73\x68\x4a\x14\x94\x1f\xa0\x7e\xe3\xe7\x9f\x46\xe3\x7f\xe6\xaf\xc3\xb2\x7f\x1e\xd5\x42\x11\x9c\xdf\xa7\xd2\x4e\x78\xee\xe1\x30\x10\x9c\xcd\x6f\x39\xbc\xa7\x01\x2e\xae\x33\xe2\x68\x2c\x58\x94\x9e\x16\x48\x75\x26\x09\x2a\xe3\x1c\xe4\x4f\xb7\x15\x8e\x74\xf4\xfb\x21\x34\x68\xe9\x3a\x96\x6a\x3f\x75\x64\x4c\x61\x70\xe2\xbc\x1f\x57\x01\x26\x53\x5b\x25\xc6\x8c\xf1\xf2\xa3\xf2\xab\x56\x89\x13\x6e\x7c\xc9\x9f\x5f\xa0\x69\x2f\x72\x33\x79\xc4\x2a\xa5\x08\x22\xed\x9e\xe1\xb7\xdc\xb6\xdd\xf2\x84\xcb\xec\xb8\xf9\xa6\x55\x96\x21\x02\xf1\x16\xc5\x25\xfb\xbf\x5a\x11\xb4\x69\xf0\xad\xb9\xf8\xc0\xf4\x67\xc1\x42\x9a\x6a\x4d\x12\xdd\xd3\x6f\xf2\xff\xf5\xdf\xaf\x69\x84\xd2\x60\xe0\x04\x39\x6f\x7a\xa2\x81\xd6\xc6\xe1\x9e\x1f\x54\xf5\x3a\x5b\x86\xb4\x49\x05\x16\xaf\x8f\x61\x27\x59\x68\xd8\x2f\xb2\x82\xb5\x51\x9c\xa4\x23\xbe\x67\x51\xd5\xf8\x9a\x84\x33\x43\x64\xb4\x63\x06\x1b\xd7\x78\x98\x45\x49\xa3\x97\x1f\x58\x46\xbc\x89\xdd\x9f\x6e\xb9\x4d\x6f\x0a\x08\xb7\xb4\xbf\x87\x17\x75\x75\x3c\x16\xa1\x41\x39\x9d\x98\x36\xca\x9c\x4e\xfe\xa9\x2f\x03\x87\x4b\xb6\x22\x65\xbe\x2c\xb1\xfd\xef\xfc\xbe\x5b\x69\x9c\xd4\x00\xe2\x03\x36\x8f\x37\xeb\xab\xfd\x7d\xff\x49\xad\x53\xbf\xf4\xfd\x0e\x28\xbf\xb8\xc8\x54\x32\x11\xcb\xa8\x77\x08\x5e\x4e\x0b\x0c\x51\x0c\x61\x39\x5d\x9e\x81\xea\x2f\x49\x14\x45\xfb\xab\xdd\x77\xff\x55\x26\xe6\xce\x1c\xd0\x56\x75\x17\xc6\xee\x0f\xd0\xbe\x54\x66\xba\x82\x4d\x1f\x9d\xff\x60\x12\x39\x85\x0b\x2f\x45\x30\x91\xc9\xa6\x26\x89\x33\xaf\x8c\xab\x21\x7f\x83\x60\x56\xd3\x1f\x56\x02\xf7\xd7\xe6\x74\x9c\x83\xf1\x4c\xa2\x1d\x15\xb7\xdb\x7b\xcb\xfc\x30\x53\x12\xa5\x26\xd5\x0e\x3a\x14\xfc\xd4\xf3\xb7\xbc\x80\xe7\x33\xdd\xae\xc9\xf4\x32\x94\xa4\x99\x2f\xe8\x8f\x53\xef\xe9\x45\xd3\xc4\xd9\x2b\x96\xa7\x03\x22\xf5\xfb\x4b\xa2\x42\xa6\x1e\xca\xef\x76\xd7\x87\x1e\x6c\x6e\x58\xc4\x11\xc2\x5a\xfb\x8a\xe4\x35\xc0\xbe\x3f\x96\x28\xcc\x4d\x2f\xea\xea\x15\xea\x7b\x78\xad\x26\x2e\x09\x38\xc0\x09\x71\x82\xae\x0e\x87\x99\xaf\x33\x35\x4c\x67\x78\x9b\x36\x3f\x36\xfb\x8b\xd5\x6e\xd7\xb3\xd2\x0d\x17\x26\x12\xa3\xc6\xed\x80\x09\xe8\x2f\x9a\x5b\x37\xc3\x1a\x70\xc5\xcc\xee\xe7\x2e\x81\x3d\x8d\x90\x31\xee\x75\x2d\x96\x54\x46\x6b\x94\x11\x92\xe1\xe4\xc0\x6e\xc4\x12\x6f\xc1\x64\x92\xe8\xf1\x0a\x17\x98\x03\x5f\x16\x45\x4d\xa6\x0c\x19\x25\x3d\x07\x59\xf7\xb5\x19\x23\xb9\xd3\x27\x70\x34\xaf\x06\x6d\xe1\xe1\x12\xee\xa0\x91\xbe\x9b\xff\x8b\x66\x7c\x38\x8f\x05\xcc\x48\xef\x30\x1e\x2f\xaa\x11\xfa\xcc\x28\x1e\xa3\xf9\x7c\x97\x9c\xdf\x56\x6f\x70\x0b\xed\x00\x65\x33\x9a\x30\xed\x51\x77\x43\xed\xfa\x5f\x24\x1e\x20\xc8\xa9\xaf\xa4\x76\x81\x7a\x50\x15\x48\xff\x1d\x3e\x9e\x18\xe3\xdd\x4e\xee\xe6\xa5\x08\xa3\x95\x9b\x62\x46\xb6\x72\x8b\x76\x60\xdf\xc0\xf9\xbb\x3d\xd8\x6d\xfe\xb3\x05\x98\x7f\xc2\x68\x81\x7d\xbe\xb7\xaa\x0d\x62\x79\x67\xd1\x9c\x31\xda\xa2\x5b\xdf\x09\xdb\x78\x4f\x25\x5e\x7a\xf7\xd0\xd6\x98\x9a\x4e\x07\x43\xec\x6c\x71\xda\x1e\x56\x37\x91\xe1\x9d\x7e\xbd\x4d\x9c\xa5\x56\x18\xbc\x29\x4e\xcd\x19\x5c\xc7\xd8\x2c\xc6\x85\xa8\x46\x6d\xba\x51\xb6\x63\x2c\xb8\x4c\xae\xf6\x7d\xad\x20\x87\xea\x8f\x43\x44\x2d\xe2\x20\xe5\x54\x6a\x90\x42\x94\x01\x4d\xc3\x1c\x09\x9d\xfd\xfe\x1b\x21\x82\x24\x76\x96\xe7\x95\x71\xba\x7d\xfd\x81\x14\x8d\x94\xfc\x82\xf6\x85\x27\x22\x85\x38\x71\x51\xc5\xdf\xd7\x0f\xf7\xe3\x30\x07\x62\xe6\x14\xa2\xbc\x08\xad\xcc\xcb\x16\x4a\xe4\x91\x54\x66\x1c\x68\x42\x9c\x39\x2e\xd5\xfe\xf0\x81\x2c\xff\x09\x5d\x01\x12\x4a\xc3\x2b\x78\x87\x71\x46\x5b\x79\xbd\xa1\x00\xb5\x82\x84\x27\x10\xa4\x57\x07\xdf\xff\x8b\x8f\x9b\x69\x2d\x02\x12\x41\xa4\x67\x3f\xee\x0f\x79\x79\x9d\x97\x25\x7c\x6c\xa0\xfe\x0e\xe6\x19\xe6\x52\xe0\xe1\x33\x19\x8f\xe8\xb8\xf7\xb0\x88\xc5\x80\xa4\xcb\x5d\xbb\x38\xff\xfb\xc3\x26\x5c\x79\x4a\x52\xec\x00\xa3\x1d\xd1\x16\x3e\xc1\x9e\x0d\x5f\x95\xf2\xcc\x3a\x4f\x8f\xf6\x32\x7f\xeb\xcf\xa2\x9d\x94\x5e\xdd\x82\x3c\xfc\xc0\x6e\xff\x40\x87\x85\xd4\x38\xe3\x76\x69\xcc\xee\xe7\x4d\x79\x71\x42\x8c\xd0\x9f\x64\xbb\x84\x73\x58\x83\xfa\x14\xdd\x26\x7d\xd3\x0e\x1e\x6b\x8b\x20\x5e\xa0\x46\xe2\x7a\x7c\xb5\xfb\xee\xb5\xcf\xc3\x01\x6b\x50\x34\xb6\xac\x4a\x6c\x08\xe2\x6a\xb9\x7d\xa9\xea\x76\x90\x77\x5c\xca\xce\xf9\xbf\xa7\x51\xeb\xbf\x62\xbf\x0a\x00\x07\x92\x46\x13\xd9\x10\x33\x44\x98\x97\xa0\xbb\x8d\x6d\xf6\x62\xe2\x67\xd0\x47\x12\x8e\x27\xc7\x83\x70\x65\x66\xf3\x49\x49\xe8\x2b\xde\x06\x88\x98\x60\x5b\xbd\x80\x37\x28\xf6\x74\x7f\x9c\xa8\xa3\x81\x50\xce\x3b\x04\xeb\xda\x7d\xa4\xde\xfc\x76\xd6\x29\x9e\x9d\x36\x4b\x32\xcc\xc7\xb7\xc7\xaa\x7a\x6d\x5a\xa8\x47\x09\x3d\x64\x8c\x6a\x27\xf2\x5e\xaf\xab\x52\xcb\xb9\xe7\xda\x42\x0c\x03\x32\xe1\xb8\x74\x74\xa1\xfb\xa6\x97\x5a\x00\x69\x64\x70\xeb\x08\x84\xcb\x19\xbc\x05\x54\xaa\x62\x27\x7d\x3d\xd8\xd1\xb8\x01\x71\x14\x4e\xa3\x78\x68\x29\xba\x4a\xff\xca\x98\x87\x4f\xc4\x95\x40\x69\x92\xf6\x49\x63\xf3\xf2\x35\x49\x66\xb4\x06\x28\x20\x98\x48\x1e\xaa\xb7\x91\x1e\xf1\xc5\xc7\x43\x09\x77\x55\xd9\xbe\xcc\xde\x4a\x1d\x3b\x7b\xd4\xa1\x12\x6a\xc6\x20\x7d\xd0\x9c\xa1\x62\x40\xb7\x4e\x6e\xdb\x1a\x26\x0c\x27\xd0\x19\xa0\x65\xd3\xd5\xa9\xbb\x2b\xcd\x10\x53\x81\x36\x51\xec\x74\x16\x5d\x4f\xdb\xbf\xf2\xd3\xdf\x68\x98\x00\x77\xcf\x10\x7c\xd3\x25\xd6\xe3\xb4\x03\x0c\x64\xd1\x70\xdb\x51\x65\x13\xfb\xf8\xc3\xc0\x29\x2c\x68\xf6\x3a\x42\x9a\x85\x76\xd6\x53\xe1\x3c\xaa\xbd\xbf\xea\x84\xc6\x0c\x90\x11\x2c\x6f\xbb\x92\x4e\xbf\x7c\x7d\x19\x35\x80\xed\xa6\x34\xa6\x73\x20\xeb\xbd\x6b\xd3\xf9\xeb\xb6\x51\xa4\x3c\x59\xb6\xbd\x87\xf7\x9d\x2c\xa0\x6c\x9b\x55\x69\x82\x80\xd0\x4b\x3e\x6f\x1c\xd8\x28\x71\x34\x07\xac\x9e\xc1\xe9\x10\x80\x5d\x5f\xf2\x46\x6d\x94\xb9\xf7\x5a\xbf\x74\xd1\x92\x92\xfa\x15\x1b\x0f\xcb\x53\xca\x46\xc6\x35\xac\x9f\xa1\xdd\xeb\xb3\xc6\x84\x25\xc4\x22\x22\xa2\x45\x05\x44\x0f\xd9\xdb\xf4\xe9\x94\x8d\x13\x67\x59\xd3\x9b\xe7\x21\x2e\x61\xb2\x81\xda\x58\x00\xf7\x9a\x76\xbb\x0a\xd1\xe8\x0b\xd2\x18\x36\x89\x55\x34\x92\xb1\xba\xab\x4c\x6e\xf3\x7e\xa3\xea\x0e\x33\xd3\x4b\x1e\xe4\x35\x42\xea\x86\x56\x8c\x4d\x62\xf7\x25\xdd\xc7\xc7\xfa\x40\x36\xa5\x69\x9a\x85\x9b\x38\x98\x82\x53\x9b\xf2\xd8\x7a\x6c\x79\x7b\xff\x7d\x7c\x40\x13\xe7\x46\x2b\x3f\xfa\x82\xd8\xf4\xa6\xd1\x84\x59\x1e\x88\xcf\x03\xf9\xc8\xb2\x24\x43\x73\xa9\xe0\x04\x30\x58\xf0\x52\xcb\x38\xa8\xa0\x10\x52\x15\x50\x63\x10\xba\x24\x37\x4e\x2d\x03\x48\x49\x98\xe2\xa3\x19\x3d\xfa\x47\xcc\x3e\xc2\x6d\x9c\x66\x3d\x77\xd6\x53\x74\x43\x9e\x67\x45\xcc\x42\xa1\xd9\x93\x87\x46\xf6\xe7\xd3\x13\x09\xca\x50\xbe\xfd\x28\x3f\xb6\x07\x59\xf7\xcc\x95\xb9\xc2\xc2\x39\x4c\xca\x0a\x4b\xf0\xcd\x7d\x94\xff\xd9\x41\xd3\x8e\xca\x6a\x7e\x40\x16\xf1\x58\x05\x42\x4c\x51\xd5\x0f\x35\x22\x39\xc2\x51\xe1\xac\x93\x8f\xdd\x4f\xde\xf5\xf7\x34\xcb\x0c\xbe\x88\xd8\x6d\xbc\x96\xf9\xa0\x43\x68\x65\x1a\xa5\x3e\x48\xff\xe1\x0c\x82\x5c\x15\x64\x12\xe2\x58\x49\x13\xd4\x32\x3a\xe6\x41\xb8\x64\x96\x22\x58\x15\x39\x64\x42\x17\x85\xf8\x56\x66\x5f\x9c\xdc\x55\x6b\x79\x3c\x82\xf9\xb4\xa8\x6b\x15\x38\xc6\x6c\x73\x94\xef\xe5\xfa\x25\x2f\xa6\x71\x91\x55\x56\xe9\xa1\x75\x37\x92\x34\xb0\x3a\x23\x5e\xc9\x1d\x9f\x73\x77\xfd\x85\x9c\x15\xdb\xac\xd6\x6e\xde\x4c\x48\xe9\xcd\x14\xc8\x65\x4d\xec\x2a\x7c\x7b\x6c\x47\xe4\x47\x24\x96\x4e\x7f\xa4\x49\x18\x73\x94\x82\xdd\xa9\x46\x19\xf1\xad\x7c\x1b\xee\xa5\x49\xa3\x10\xea\x60\xa9\x71\x7d\x2e\xc5\x3f\xaf\x8b\x4c\x0b\x60\xd6\x08\x86\xd8\x94\xef\xf2\x7f\xff\x93\xe3\x58\xd5\x9a\x0c\x90\x61\x83\x8f\xb0\x07\x5d\x91\xfe\x30\x58\xe6\x83\xc0\xb5\x2c\x0d\x36\xf0\x3e\x53\x13\xf3\x1f\x01\x2a\x10\xd3\xfa\x50\x3f\xcb\xf2\xfa\x54\xea\x73\x60\x76\x3f\x52\x62\x17\xcd\x40\x91\xbf\x41\xfd\x31\x4a\x1e\xbb\x63\xa8\xb7\x71\x6a\x60\x04\xee\x9d\xbd\x59\xc0\x00\x41\x13\xc1\x45\xb9\x9f\x57\xa0\x34\x26\xa5\x17\xa7\xe7\xbc\xb9\x1f\x96\x3b\x4b\x33\xac\x8e\x8f\x38\xb7\xcd\x75\x55\xaf\xeb\x8f\x63\xdb\xef\x85\xd6\x0a\xc5\xfd\xdc\xdd\x7f\x47\x46\x65\xe3\x1b\x5e\xcb\xeb\xb4\x15\xd6\xb8\x24\xde\x29\x49\x2c\xa5\x98\xd3\x45\x81\x45\x24\x4e\x50\x90\xc0\xe6\x65\x98\xbf\x17\x1f\x57\xa5\x39\x56\x79\x39\x31\x16\x61\x11\xd1\x26\x04\xf9\xf7\xa7\xc3\x36\x37\xa1\x82\xc7\xa2\x98\x38\x63\x10\xef\x9b\xeb\x41\x13\x60\xba\x79\x76\x63\xc2\xa8\x24\x4a\xf0\x36\xf5\x69\xf6\x07\xda\x44\x2f\xdd\x53\x16\x25\x31\x71\x72\x12\x4e\xda\x60\xf5\x0c\x65\xbb\x9d\xf5\x6e\x58\x94\x0a\x8a\x5d\x0a\x8b\x5b\x8a\x3f\x6f\x79\xe1\xb6\xfb\xfe\xf2\x28\x71\x82\xd2\x68\x13\x8d\x9a\x9b\xdf\xf3\xa6\xad\xea\x0f\xc4\x1f\x8e\xa7\x0d\x8b\x68\x4a\xd2\xee\x5d\x5a\x6d\x6f\xae\xfe\xde\x9f\x80\x4a\x0c\x09\x2f\x41\x17\x23\xe1\x80\x70\x94\x2b\x8c\x75\xda\xfc\x00\x0f\x6f\xe1\xe9\xb3\x88\x11\xc7\xf9\xc1\xe8\x74\x6a\x8e\xc1\x22\xa6\x35\xa2\x2d\x9a\x63\x5e\xce\x14\xb0\x59\xc4\x75\x8c\x09\x81\xd3\x5b\x6a\x36\xb2\xe9\x09\x73\x2c\xe2\x60\xa9\x97\x7b\xbc\x59\x3f\x8c\xa4\xc0\x7b\x9c\x48\x18\x29\x22\xe9\x14\xa7\x4e\xaa\x5b\x0c\x64\x3d\xf8\x4a\xcd\xee\xb6\x88\x9d\x40\x81\xd7\x24\xb9\x84\x63\x0d\x7a\x02\x83\x3a\x57\x05\x61\x91\x10\x14\x5b\x98\xfb\xde\x9b\x66\x82\x2b\x67\x5d\x98\x91\x8d\xc1\x66\xd7\x75\x75\x98\x87\x26\x67\xbb\x04\x8b\xb2\xc4\x79\x1f\x37\xd0\x3a\x3e\xe0\x57\xc6\x5a\x2c\x92\x8c\x62\x42\xf4\x9c\xbf\xc1\x4c\x14\x7d\xf9\xd7\x4a\xe5\xac\xee\xbd\x90\x92\x53\xb8\x9c\xe8\xbf\xcc\xbf\xc1\x50\x7c\xc2\x25\xbc\xe3\x05\xe5\xff\x83\xa0\x07\x77\xee\x24\xce\x22\x95\xca\x74\xcc\x50\xc5\x06\x2a\x34\x2e\x32\xea\x51\xf5\xb3\x89\xa7\x89\xe4\x72\xaa\x3e\xdc\xcf\x07\x9d\x28\x04\xac\x23\xd8\x72\x7f\x5b\xe9\x57\x97\x53\xb9\xaa\xd9\x67\x1d\x61\x16\x19\xc6\x31\x17\x7b\x85\x8f\xee\xd6\x9f\x37\x00\x59\x04\x71\x94\x66\x63\xb6\x43\x33\x1b\x60\x79\x3a\x32\xa2\x46\xec\xfd\xa7\x89\x10\x8b\xac\x06\xec\xec\x1f\xf2\x02\x9a\xb6\x2a\x21\x88\xf1\x4d\x4e\x4a\x22\xe9\x24\xbe\xbc\x69\xdf\x48\x53\xf2\xba\xaa\x17\x2e\x93\x90\x88\x22\x53\xa2\x5f\x3b\xaa\x76\x59\x6c\x9b\x11\xc2\x12\x7c\x79\xa0\xd6\x71\xf4\xe3\xdb\x7a\x84\xb2\xeb\x0e\x3a\x63\xc8\x26\xaf\x21\xc8\x18\x55\x61\x7a\xcd\xce\x23\x29\x42\xaa\xb5\x2c\xb4\x47\xda\x2c\xce\x0e\x42\xc0\x9a\x81\x68\xb6\xbb\x38\x93\x62\x61\x84\x58\x37\xa3\x1f\xb7\x1e\x6e\xcc\x48\xac\x84\x18\x6c\x13\x2e\xf3\x32\x0f\x0a\x40\xd3\x8f\x26\x29\x24\x49\xef\x71\xff\x26\x5b\x34\x33\x9c\xf8\xc5\x30\x92\x12\x57\x21\xdf\x42\x6b\xf2\xb7\xeb\xaa\xde\xc9\xf2\x75\x76\xa2\x94\x38\x60\xe8\xcd\xeb\xa9\x96\x7f\x2a\x5b\x61\x24\x4d\x64\xe2\x0b\x36\x1e\x87\xb2\x3d\xca\x72\x5c\xfc\x61\x24\x65\x02\x71\x68\xcd\x4b\xf5\xee\xb4\xea\xe6\x77\x32\x15\x3c\x1d\xa6\x90\xe3\xc8\x2f\x2f\x44\x84\x32\x40\x19\xae\xca\x98\xf9\x59\x58\x4a\x95\xed\x25\x57\xc3\x2f\x67\x5a\x62\x49\xe9\x78\x6a\x5e\x26\x46\x57\x0b\xb5\x13\x46\x98\xd5\x89\x47\x6a\x6d\x3f\x9a\x16\x50\x8c\x65\xa9\xa0\xcc\x08\x8f\xb5\x53\x1f\x9d\x72\x73\x06\x8b\x84\xd5\xd7\xba\x10\x8c\x70\x4a\x80\x79\x63\xbd\xf6\x2e\x77\x10\xaa\xdb\x4a\x86\x95\x9c\x88\xc4\x89\x23\x75\xeb\xc4\xeb\xb8\x39\xca\x48\x16\x41\x10\x6c\xdd\x1e\x41\xdf\x98\x51\xe6\x89\x47\x91\x55\x59\xc2\xcf\x76\xa6\xff\xcc\x48\x96\x09\x4c\x5a\xdc\x42\xf2\x08\x5d\xba\x83\x16\x23\x13\xb9\x97\x30\x58\x4a\x6c\xe8\x1e\xdf\x8e\xb8\x00\xae\x43\x4f\x80\x91\x4c\x47\x3e\x28\x6d\xa0\x1e\xc9\xbe\xe6\xe7\x42\xc4\x5f\xd6\xb7\x18\x91\xb1\x41\x2e\xff\xa6\x46\x71\xf8\xde\xfc\x90\x11\x99\xba\xa0\xd4\xa3\x32\x27\x01\x07\x91\x3a\x22\xd9\x08\xb0\x3d\xc4\x65\x8c\x48\x93\x01\x4e\x4c\xf9\x06\xdf\xa0\x5c\x57\xe6\x4b\x55\x75\x46\xb4\xc8\xbc\xda\x50\xd3\xf4\x04\x6c\x31\x56\xe4\x98\x6f\x43\xc4\x28\xe7\x5b\xf6\xad\x72\x81\xd9\x50\xc1\x60\xc4\xd8\x28\x3c\x9f\xbf\x9d\x64\xd9\xe6\x6d\x0e\xf3\x19\x04\x91\x5b\xb5\xaf\x8a\xe3\xcb\x28\xd8\x65\x04\xac\xf7\x40\x80\xc6\xc1\x5e\xba\x8c\xf8\x0e\x7a\xd3\x89\x61\x0b\x27\x36\x15\x41\x77\x13\xb1\x1d\xae\xd6\xb0\x44\x4e\x09\x1f\x30\xc2\x2d\xc0\x1f\x78\xe6\x8b\xba\x9a\x5d\x56\x1c\x25\x80\xbd\x1e\x3b\xc6\x13\x75\xbf\xed\xe2\xe3\x7b\x75\xfa\xb4\x76\x19\x3e\x4d\x25\xb6\x5a\x5f\x2a\x53\x5c\x57\x35\x09\x7b\x7d\x1c\x49\xa3\x7a\xb0\x35\xce\xe5\x0d\xd4\x3d\xd7\x84\xc5\x44\x52\xd4\x1c\x97\xae\x34\x09\x8f\x23\x39\x0b\x04\xc2\x43\x39\x4b\xf8\x59\x4c\x80\x52\x47\xb5\x0a\xa4\xb4\x2e\xc2\x71\x44\x9d\x41\xa4\xee\x93\x2b\x8d\x49\x86\x77\x59\xc9\x56\xbf\xf4\xeb\xdd\x79\x8e\x3a\x3b\x4b\xb8\x93\x71\xcc\x28\x71\x38\xfd\x79\x0b\x27\xfc\xa4\x44\x68\x44\x8d\x76\xaf\xe1\x23\x18\x38\x20\x38\x6e\x71\x19\x8f\x13\x05\x28\xbe\x8b\x6a\x1c\xd0\xb4\x5d\xfa\xbb\xbc\x9f\xc4\x89\x16\x48\xbd\xda\xdd\xdc\x5d\xdd\x3e\xac\x7f\x9f\xe1\x2a\xbb\x01\x19\x32\x55\xd0\x78\x17\xd1\x8c\x23\x71\xb8\x61\xfb\x8f\xd3\x24\x26\x30\xba\x7d\xce\x75\xd0\xc9\x5d\xe0\x46\xfe\x79\x6b\x94\xc5\x94\xa9\xa0\xef\x8b\xc1\xf7\xca\x27\x07\x33\xaf\x01\x16\xf3\xd8\x69\x29\x1c\x3e\xb6\xf2\x0d\x65\xe7\xc2\x01\x03\xa1\x01\x7c\xe3\xab\x1d\xe1\x90\x88\xa4\x88\x02\xd9\xfc\xb4\x64\xe8\x1c\x06\x52\xc0\x50\xca\xe9\xdc\xba\xbe\xdc\xea\x0c\xc8\x13\x06\x33\x8d\x00\x8a\x7d\xc0\x78\x76\xaf\x8c\xe7\xc6\x4c\x6f\xb1\xe0\x06\x7b\x92\x35\x52\x0a\x9b\xf6\x0f\x80\xd7\xab\xd0\xf4\x66\xb1\x50\x09\xa7\x3d\xba\xad\x37\x13\xea\x0e\xe8\xd8\xc1\x9a\x02\xea\xe4\xc7\xd8\x76\x98\xc5\x02\x52\xe4\x42\xae\x2e\x56\xe3\x57\x3e\xce\xc0\x01\x67\x6a\xa9\xa1\x57\x8e\x64\x71\x66\x2d\xa6\x97\x25\xbc\x8f\x95\x97\x26\x4b\x57\x2c\x05\x04\x99\xea\x47\xa9\x54\xde\x6e\xf3\x7a\x54\xc7\x9c\xd5\x86\x58\xdc\x2d\xe9\x30\x32\xfb\x9a\x26\xca\x7e\x90\x8a\xad\x5b\xdd\x9b\x6e\xe6\xc2\xc1\xbd\x54\xb3\xdb\xa4\x89\xc2\x16\xe3\xf7\xb4\x7f\x8d\x35\x8b\x78\x34\x58\x06\x85\x96\xf9\xfe\x3f\x79\xf3\x92\xcf\x97\x1a\xcd\x1c\x02\xed\x25\x7f\x76\x28\xc2\xc1\xce\x83\xc5\x46\x3b\xc5\xcd\x12\xde\x1d\x7b\x76\xf6\x61\xc8\x08\xe8\x79\xce\x3f\xb9\x31\x36\x93\xc1\x4b\xf9\x33\x77\x00\x37\x32\x89\xb8\xc3\xf8\xe1\x56\xec\x90\xc5\x3d\x0d\x97\x25\x91\x8c\x60\x14\xc0\xe5\xfa\x15\x16\xea\x8f\x2c\x89\x8c\x23\x8d\x79\x46\xd0\x02\xec\x88\x25\x91\x25\x08\xda\x6a\xab\xe7\xe7\x02\x7e\xcf\x8b\x62\xfb\x9e\xb7\xfa\x25\x7c\x17\x89\x38\x82\x34\xd1\x0c\xd3\x02\x38\xbc\x45\x7f\x94\xc6\xa8\x18\x60\xf3\x37\xe8\x16\xe3\xfe\x12\x09\xe7\xd8\x10\x2c\x64\xd3\x5e\x82\x6a\x6f\xc1\x3c\x43\x7d\x35\x58\x17\xb0\x84\x64\x09\x86\xc8\x08\x8d\x6f\xa0\xb0\x03\x89\x8a\x25\xc4\x28\x6c\x44\xee\xd5\xa9\x2e\x17\x2f\x9c\x00\x41\x57\xa6\x2e\xd7\xac\xdb\xab\xff\x12\xea\xee\x29\xa1\x7f\xf1\xff\xfa\x81\x31\x55\x18\xbb\xaf\x77\xa3\x0d\x31\x49\x98\x36\x89\x17\x1a\x9e\x04\xe6\xde\xb7\x83\x25\x69\x14\x65\x32\xb0\xde\x7e\x7e\x61\xb5\xd5\x0d\x55\x78\x1b\x1e\xe5\xeb\xe9\xb9\xfa\x95\x55\xd1\x64\xda\x24\xa9\x80\x48\x8d\xe3\xb6\x55\x0d\x72\xf6\x5b\x53\x23\x88\x67\xa5\x0c\x16\x52\xb3\xd3\x80\x74\xc9\x3b\xee\x8e\xae\xe0\x1c\x42\x28\x3f\x84\xc6\xd2\x64\x93\x16\xf4\xb7\xba\x7a\x6f\x5f\x26\x85\x37\x96\x50\xe5\xaa\xcb\xb5\xcc\x1b\x30\xc3\x8e\x98\x50\x70\x66\x55\x8e\xe7\xd7\x4d\xba\x71\x55\x92\x25\x4c\x12\xea\xb6\x97\xf7\xcd\x4b\x55\x82\x4b\x54\x96\xd7\xbe\x84\x19\x15\x0d\xd0\xa3\x8b\xdc\x4c\xca\x3f\x63\x63\xcd\x2e\x3d\x8a\x90\x82\xe2\x4c\x17\x2e\xa0\x1d\x0b\xf6\xb0\x84\xfb\x66\xfd\x7b\x5e\x18\x1d\xba\xcf\x7d\x19\x27\xe1\x46\xc4\xae\xf3\x7e\x9a\x79\x2d\x76\xc7\x20\xd1\xbd\x98\xcf\x5d\x65\xe6\xc7\xad\x21\x8e\x5e\xe4\xef\x99\x43\xfd\x2e\xff\xa4\x8c\x66\xd6\xcb\xd6\x7a\x5b\xd9\x1e\x9f\xca\x92\x4c\x08\x6c\x76\xfe\xa7\x5b\x84\xba\xac\x71\xbb\x30\x45\xfc\x58\xa9\x9d\xb1\x25\x6a\x88\xf6\x5d\x76\x96\xe8\x24\x49\x79\x60\x08\xdf\xca\x32\x94\x76\xf3\xe1\x19\x68\x4e\x31\x6c\xfc\x56\x03\x94\xef\x55\x5d\x98\x6b\x59\x1f\xc6\x4b\x7b\xa2\x0d\xe0\x72\xbb\x79\xba\xf8\xd6\x2e\x49\x99\x8d\xd7\xac\x44\x5b\x9e\x78\xc5\xe5\xab\xf6\x65\x2d\x8f\x17\xa7\x8f\x9b\xf2\xba\x7f\x51\x4d\xa2\xb1\x0e\xef\x9e\x4d\xd0\x2d\xea\xc3\x97\x59\x0f\x75\xf1\xed\x31\x34\x52\x62\x56\x75\xc1\xbe\xf5\xd7\xf9\x4a\x62\xa8\x06\xd4\x3a\x41\x18\xf1\xd0\x33\x1e\xc5\xdd\x89\xd1\x16\x49\x26\x07\xa8\xcf\xb5\x15\xe6\xe7\xb3\x12\x82\xe9\x64\xfd\x3c\x9b\x09\x00\x42\x0c\x2e\xa0\x17\xa7\x26\x2f\x47\x29\xf8\x27\x67\xb4\xb1\x76\x70\xf1\xfc\xcd\xa3\x7d\x97\x41\x11\x2c\xb1\x5c\xa2\x4d\xd1\x3e\x58\x26\x1c\xa1\x34\x50\xea\xd1\xaa\x6f\xb9\x14\x59\x5f\x15\xc4\x2e\xe1\xb4\x24\x93\x58\x45\xad\x6b\xf0\x3d\x57\xad\x1e\x2d\x76\x56\xa9\xde\x4e\xb3\xbb\xc9\xc7\xaa\x76\xad\xee\x6b\x80\xd1\x1c\x9a\x5c\x52\x1a\x51\x8b\x79\xd9\xc3\xcb\xfd\xd8\x2c\x98\xa5\x11\x63\xe8\x45\xf8\x56\xb5\x10\x25\xf7\xd5\xa8\x91\xca\xd2\xc8\x3a\x13\x6f\x0f\x14\xc3\x12\xcd\xe4\xd3\x24\xa6\xf8\x4b\x5f\x64\x3d\x90\xbf\x59\x1a\x67\x99\xcd\x42\xeb\x1e\x05\x63\xea\xea\x70\x57\x95\xb8\xd1\x8e\xd7\xe5\x34\xa1\x56\x92\x91\x6a\x54\x2d\xcb\x17\x39\x89\x46\x96\x1e\xf3\x64\x45\x49\x13\xa3\x70\xf3\x08\x10\xb9\xb5\x33\x80\xfb\x3f\x70\x01\x58\x9a\x1a\x27\xde\xd0\x05\x9c\xce\x3a\x61\x52\x14\x4d\x59\x96\x64\xd0\xc3\x59\x7a\xf8\xf1\x9d\x3c\x1e\x47\xbc\xf9\x7f\xfd\x7b\x14\x01\xa7\x2c\x73\xaf\xaf\xe3\x80\x6d\xab\xc2\xec\xaa\xe9\x44\x4c\x99\x75\xbc\xe7\x26\x48\x15\x4c\x8a\x94\xe3\x77\x37\xe5\x02\x90\xfa\xd6\xf7\xee\xd0\x15\x3a\x44\xf4\x0b\xac\x46\x96\xf2\x8c\x86\x3e\x9d\xeb\x78\xce\xd3\xf5\x94\x9b\x08\x79\x87\xeb\xa7\xfb\xd1\x7e\x9a\x0a\x2a\xf0\xcf\xf7\x3f\x76\xfd\x9f\x44\x4a\xb3\x50\x56\x3c\xba\xc2\x78\x5e\x95\x97\x03\x72\x20\x8c\xcc\x94\x85\x80\x9a\x5b\x7f\xf7\x0a\x0d\x74\x12\x3c\xa5\x12\x04\x82\x09\x7b\x71\x8a\xdb\xbc\x7c\x0d\x27\x50\x8a\xa3\x3b\x02\xb6\x05\xb4\x3e\xab\x8e\xa4\x5a\x6b\x47\x83\xaf\x4e\xa5\x49\xd7\x32\xac\x5f\xa9\x06\x67\xe5\xfd\x0c\xed\xf7\x8f\xe3\x3c\xa8\x4b\x0d\x89\x23\x11\xfa\x3c\x5f\x17\x6b\x97\x57\xa9\xd4\x48\x81\xd3\x44\x57\xa1\xdd\xb5\x3d\x1d\x8f\xc5\x87\x0f\xc4\x9d\x0f\x1f\x78\x0d\xfe\x70\x55\x06\x94\x93\x64\xad\x31\x8f\xfb\x73\x8a\x93\x2c\x05\x62\x52\xff\x9e\xf7\x9a\x05\x9f\xef\xc1\x29\xa4\x1c\xfb\x70\xef\xb2\xd9\x56\xb6\x5d\xcb\xe3\x5d\xbf\x61\xa5\x36\xe1\x3a\x0b\xdb\x26\x18\xec\x02\x8e\x09\x7c\x8c\x46\x09\xc3\x55\x65\x7f\x6a\x60\x9d\xb7\x79\x97\x9d\x37\xb7\x18\x12\xfc\x67\xee\x5c\xf2\x55\xab\xb7\x3b\x93\x46\x3d\xf8\xdf\x65\xd9\xc8\xe6\xad\x59\x17\x70\x68\xfa\xe9\x41\x23\x9d\x78\xdc\x65\x09\x75\xae\x27\xaa\x5c\xa3\x1c\x81\x92\x88\xa2\xfd\xca\x60\xd4\xd9\x63\x6e\x19\x25\xdc\x01\x4d\xfa\xda\xff\xba\x0b\x15\x46\x4d\xc5\xaf\x8b\x42\x94\x58\x8e\x15\x94\x3e\xde\x4c\x7d\xbc\x99\xfa\x78\x33\xed\x07\xda\x50\x83\xac\x7a\x19\x16\x46\x63\xc8\x6c\xaf\x4c\x2d\xeb\xf6\x52\xb6\xf0\x60\xb1\x3b\xea\x47\x24\x91\x76\x72\xd4\x5d\x06\x98\xb7\x1f\x57\x3f\xe7\x6c\x79\x46\x93\xc4\xb0\xa8\x87\x5c\x78\x72\x84\xb7\x73\xfa\x72\x77\xa3\x49\xf7\x9e\x8d\x20\xb3\xfd\x04\x99\xce\x78\x9a\x78\x6a\x27\x66\xb0\x78\x09\xcd\xc3\x7b\x09\xe6\x0e\x8c\x47\x05\x87\x95\x98\x26\x92\xd8\xb0\x14\xa1\x59\xcd\x45\x55\x35\xed\x48\x5b\xcb\x8f\x4b\x15\x43\xb5\x2a\x69\x8c\x5f\xd1\x1f\xd4\x7f\xfc\xa9\x26\x57\x3b\x6a\xc4\x2e\xc4\x22\x94\x71\x87\x24\x0b\x7d\x8a\xaf\x34\x4f\xfc\x47\x78\xc4\x10\x26\xb4\x6f\xce\xa4\x84\x19\xe5\x4c\x10\x5f\xac\xda\x97\xa7\xc3\xbe\xb2\xdd\x54\x5e\xae\x16\x8a\xf0\x19\x69\x84\x77\x74\xd8\xfd\x44\xbb\x94\xc5\x0c\x8e\x72\x23\x52\x11\x1a\xf9\xa5\xa9\xea\x1b\xb3\x8c\xf6\x64\x54\x90\x18\xf5\xc9\x1c\x8e\x74\x9a\x02\x8f\x2b\xd7\x34\x4b\x9d\xfa\xdb\x6a\x77\xe7\xfb\xab\xb3\x1f\x94\xd9\x74\xd2\xb1\x44\x97\xc9\xd9\xf3\x95\x51\x86\x26\x65\xc1\x99\xf4\x6a\xf7\x7d\xbf\x5e\x6d\xc2\x24\x94\xd2\xf5\x1e\x5d\xd5\x1a\x93\xe0\x3b\xf9\xb3\x3f\x6a\x29\xf5\x88\x8f\x2e\x9b\xf6\x61\xee\x6c\xb1\xa5\x2a\x4d\x50\xc8\xfd\x3f\x55\x48\xf6\xa8\x8e\x35\x26\xc7\x08\xc0\x70\xa2\x27\xe1\x88\xd0\x41\x34\xf1\xb1\x52\xd5\xb9\xbd\xe0\xf4\x27\x6a\x10\x08\x8a\xf9\x2e\x9b\x97\xb2\x32\xb0\x83\x52\xd6\x72\xb4\x13\x51\x43\xb4\x82\xe0\xc7\x81\xf4\x93\x66\xe4\xb2\x3c\x3d\x9b\xa1\x1a\x73\x03\x27\xdb\x7e\xd3\xb8\x8a\xd3\x27\xee\x6f\x8c\x1a\x06\xce\xd9\x79\xf5\xb4\xbd\x0a\xdf\x07\x9c\xa2\x25\x64\x0b\x4d\xfb\x08\x23\x1d\x4e\x46\x21\x8b\x23\x7f\x29\xb7\x79\x09\x67\x46\xe7\x8c\x5a\x62\x1c\x91\xba\xae\xde\xcd\xee\x50\x95\xf0\x41\xc3\xa7\x6d\x4a\x14\xca\x09\x75\x11\xda\xa4\xdd\x17\x6a\x7e\x88\x17\x11\xe3\xe4\x11\xcb\x00\xd7\x55\xbd\x94\x32\x53\x0b\x09\x5a\xa1\xfc\x7e\x15\x1e\x37\x8b\x48\x8c\x05\x6d\xc7\x72\x79\x78\x85\xd2\xed\x4e\xfd\xf1\x58\x63\x55\xed\xfa\xe1\xe9\xfe\xf2\xea\x71\xbb\xdf\x3c\x3c\xdc\xee\x57\x97\x97\x8f\x61\x04\x51\x2a\xf3\xc8\xeb\x75\x21\x9b\xa6\x0f\x74\x42\xb1\x67\x08\x6f\x58\x4c\x62\x5c\xe1\xda\xc3\xb1\xdb\x96\x62\x3d\x72\x81\x9d\xce\x21\x16\xc7\x59\xe6\xea\x3d\xcd\xa9\x5b\xa7\x7a\xa5\xae\x70\xdc\x2a\x44\xc9\x1f\xeb\xea\x50\xb5\x3e\x9d\xf2\xc7\x92\x24\x43\xd9\xae\x7d\xed\x59\xc2\x8b\x53\xa9\x8b\x39\x31\x3a\x77\x29\xe8\x5d\x65\x9c\xe3\xfb\xec\x42\xd2\x20\x48\xee\x4c\x2a\x26\x29\x2f\x4b\x95\x7b\x75\xfd\x1a\xb0\x6f\xab\xbd\x1a\xf4\x42\xce\xb4\x7f\x18\x4b\xad\x53\xa9\xf3\xdf\x99\x2f\xe8\x22\x32\x46\xa3\x0c\x2b\x94\xf0\xf3\x98\xd7\xe3\x40\x89\xd1\x24\x46\x20\xa2\xdb\xc4\x3c\x51\xf1\x0b\xb4\x35\x63\x94\x12\xcc\x09\x6e\xf3\xf2\xbf\xe3\x38\x9c\x51\x9a\xe1\xa2\xbc\x8d\xd9\xd0\xe0\x60\x94\x69\x8c\x20\x1e\x7e\x4e\x07\x67\xdc\xeb\x5e\x39\xde\x2f\xaa\xac\x9a\x7c\x40\xf6\x4c\x8b\x1a\x4c\xc4\x5a\xba\xa2\x46\xe9\x1e\xdc\x60\x81\x14\x4e\x29\x12\xb7\xa9\x3b\x6a\x99\x2f\xeb\x5f\x23\xcb\x37\xd7\x0b\xd5\x61\x26\x32\x8d\x4c\x53\x7c\xc3\x36\x85\xd4\x80\x4d\xe7\x45\x70\x09\x63\x42\x39\xca\xb6\x8b\xbe\x77\x50\xc0\x73\x2d\x0f\x4b\x32\x6c\x8c\x09\x9b\x70\xc7\x5a\xf8\x79\x87\x80\x04\x1f\xe8\xf9\xc3\x99\xa7\x26\x1c\xe5\xc9\x89\x98\x05\x02\x3c\x63\x99\xa0\x08\xb4\x87\x46\xcb\x19\x3c\x89\xb1\x0c\x98\x88\x42\xc2\x06\x57\x25\x02\x0e\x3d\x42\x74\x9c\x33\x31\x99\xa4\x41\x96\xf8\xa6\x44\xd9\xa0\x93\x2c\x26\xc6\xca\x8c\x49\x48\x48\x3a\x20\xec\xc1\x78\x88\xe7\xd6\x91\x47\x46\xee\xfa\x8c\x29\x95\x90\x78\xb2\x02\xce\x2b\xa5\x4c\xe9\x04\xc9\xe3\xdf\x1e\xfe\xfe\xf7\xaf\xf2\x7f\xa6\x6c\x1c\x40\x3d\xd7\x35\xc0\x6e\x68\x07\x32\x9d\x50\x4c\x10\xef\x6e\xee\x77\xb8\x24\x5c\x6d\xb7\xc3\x31\x19\x7b\x84\x8d\x53\x05\x3d\x1d\x56\xc5\x73\x55\xe7\xed\xcb\x61\xf2\xdb\xb5\x96\xda\x8b\x5d\x8d\x5f\x61\x6d\x33\x64\x30\x3f\xe7\xb6\x9d\xd1\x5b\xfc\x08\x63\x29\xf2\x1e\xdf\xaa\x01\x25\x37\x66\xdc\xf9\x61\x90\x70\xf0\x9a\xa6\x3b\x79\x0c\x96\x2e\x5d\xce\x84\x13\x7c\x71\x1f\x65\x40\x19\x19\x34\xfc\x42\x7d\x6c\x12\x0e\xfc\x65\xec\xac\x17\x3e\xa6\x8c\xf5\xe1\xb7\xef\xb9\x3e\x9c\x66\x15\x27\x66\xa3\x28\xf2\xe0\xd4\x6e\x3b\xd8\x93\x28\x5c\xa9\x15\x02\x2b\xd5\xdb\xaa\xf7\xfd\x67\x9c\x00\xc3\xfa\xbc\x87\x7e\x5c\x61\x1d\xa3\xd4\x1f\xe7\x08\x79\xff\x81\xd8\x3a\xd5\xa8\x63\xf5\xfe\x9b\x07\x7a\x8e\x28\xea\x8c\xa7\x09\xc3\x9c\xb0\xa7\x96\x38\xdc\x35\xd4\x8f\xa0\xab\xf3\xe4\xc6\x7f\x8a\xc6\x49\x88\xf4\x50\xec\xe7\x71\x81\x63\x18\x86\x52\xcd\xfc\x7e\x70\x85\xad\x41\x07\x5d\x9d\x0d\x12\x4e\xe9\xa8\xf1\xcd\x9a\x2f\xce\xc7\x94\x40\x61\x26\xd5\x8b\xb0\x05\xbb\xf6\xd9\x2f\xe7\x49\x64\x5d\x43\xef\xba\x1a\xb2\x14\xce\x15\x45\x14\xe0\x6a\xf7\x30\x5e\xd2\x38\xb7\x80\x91\x21\xf6\x5e\x9e\xca\xbc\x9d\x37\x8a\xb8\x04\xd0\x9e\x3c\x8c\x5d\xbf\xe0\x12\xb0\xd0\x7d\xe7\x86\xc7\x58\x9c\x41\x98\xf4\x44\xf0\xee\x8c\x82\x39\xb1\x64\xfc\x32\xd8\xe1\x06\x22\x31\x46\x91\xcc\x1c\x0a\x96\x6f\x18\x28\xa7\x3f\xe6\x14\xe9\x7a\x9d\xc4\x39\xfa\x70\xf6\x21\x13\x07\xb9\x92\xcb\xed\xee\x5e\x1e\xc0\xe9\x5e\xf9\xc3\x36\x72\x96\xeb\x06\x8a\x7d\x7d\x06\xd5\xe0\x56\x50\xb4\x1f\x08\xc5\xe9\x99\x2a\xc1\xf4\xbb\x44\x44\x52\xac\xdb\x35\x41\x5d\xbe\x7b\xf1\x3d\x74\x92\x89\x28\x75\x22\xc4\xaa\x0b\x3d\x51\x4f\x2f\x1c\xe0\x02\x49\x10\xfb\x23\x4a\x7a\xba\x95\x7a\x79\xf5\x17\x24\x62\x58\x64\xca\x4b\x8d\x26\xe8\x68\x2c\x10\x4e\x44\xe2\x2c\x68\x21\x3f\x8d\xfd\x35\x96\xaf\x96\xf0\x84\xc5\xbd\xe5\x18\xd4\xcd\x85\x2c\x5f\x9b\xcb\x5a\xda\xf6\x4e\xb6\xa7\x3a\x6f\x3f\x46\xc8\x16\x11\xc7\x02\x7b\xac\x17\xbb\xeb\xbb\xfe\x6f\xd6\x3a\x3d\x07\xec\x5c\x39\xbe\x7a\x60\xc6\x4f\x8a\x1c\x22\x01\xcb\x92\xa0\xd5\x39\xb1\xe4\x63\x22\x15\x84\xf4\xfb\x5f\x60\xd7\xff\x92\x6b\x3b\x6c\xa0\x82\x45\x49\x14\x42\x26\x68\x5f\xbc\xc7\x60\x38\x3d\x8b\x05\x04\x06\xa8\x4f\x40\xc7\xcd\xd3\xd9\x5d\x61\xb1\x16\x9e\xda\xd9\x3e\x74\x8b\xf3\x72\xe9\x2d\x8c\xe6\x34\xe9\x3d\x4a\xa6\x88\x01\xc1\x69\x8a\x84\xef\xd5\x63\x7f\xbf\x84\x74\xfb\xf1\xfb\x5c\xcd\x7f\xe4\xf3\xcd\x44\x26\x15\x72\xb9\xeb\xfc\xf9\xa5\x8d\x67\x78\x45\x21\xbb\x79\xe4\x48\xd1\xcd\x32\xf8\x6d\x36\x65\x24\xb0\xcc\x84\x68\x1b\x11\x17\x4b\xd9\xe5\xe4\x69\xa9\x48\x63\x5f\x7b\x55\x14\x9b\x20\x7c\xda\xfd\xd5\x6a\xa7\xa4\x8f\x13\xfb\x5b\x25\x8b\x47\x90\x7a\x88\x5d\xbb\x11\x10\x07\x31\xee\xdc\x3c\xc3\xfd\x18\x0e\x72\x1e\xfa\x08\x95\x28\xc4\x54\xb9\x0c\xb1\x77\x45\x3c\x87\x14\xf8\xf1\x9a\x70\xe3\xec\x39\xa0\x34\x77\xcd\xf3\xb6\x34\x9f\x40\x05\x05\x10\x85\xcb\xe0\xe5\xd5\x9a\xd0\x29\xb3\x9c\x09\x48\x69\xe4\x4b\x19\xab\x53\x5b\xd5\xb9\x91\xe6\xaa\x00\xdd\x56\xf5\x60\xf2\x1c\xc6\x9a\x08\xc9\x0e\x37\xf7\x37\xbb\x9b\xd5\xed\xfe\xc7\xd3\xc6\x29\x71\xed\xb7\x4f\x9b\xcd\xed\x3f\xfa\x73\x02\x68\xf0\xf6\x20\x75\xfb\x6d\xae\x96\xc0\x84\x8d\x62\x13\x44\xc5\x4b\x03\x75\xf1\xd1\xed\xef\x23\xb0\x91\xb0\x89\xd1\x66\xc4\xc3\xf5\x9b\xf8\x38\xae\xc8\xa2\x54\xa4\xce\x21\x1a\x1e\x41\xe7\xc7\x1c\x46\xc7\x58\x86\x72\xf9\x12\xd3\xc2\x47\xec\x73\x5d\x05\x33\x15\x96\x11\xa2\x30\xd0\xec\x12\x3a\xef\xe0\x6a\xfe\xa8\xf3\x16\x10\xbc\xd0\x8f\x8a\x25\x4e\xbf\xcd\xd5\xe3\xda\x4b\x8e\xed\x77\x0f\xfb\x8b\x9b\x7f\x5e\x5e\xfd\xe8\x07\xc9\x2c\xf3\x16\x37\xa1\xf1\xfe\x65\x95\x26\x8b\x65\x8a\x3c\xec\x3f\xf2\xa2\xc8\xe5\x61\x94\xd7\x66\xb1\xe1\x88\xef\xbb\xc8\xdb\xbf\x85\xbf\x25\x8c\x39\x10\xa6\x4b\x27\x4c\x8b\x5b\xdf\xa7\xb4\x63\x96\xa5\x34\xd2\x9e\x07\x25\x55\x01\x5d\x12\x7f\x59\xbd\xf7\xdf\x91\x5a\x10\x34\xb4\x54\xc2\x6c\xb8\x76\xe2\x0f\x7e\x08\x8d\x98\xf2\xba\xa8\xd7\x79\x29\x8b\x2d\x7c\xa2\x52\xd6\x0d\x75\x12\x75\x21\xd6\x18\xa9\x45\x9f\x2d\xd9\x19\xd5\x96\x07\x3d\xcf\x16\xe4\xeb\xa6\xce\x87\x2f\x65\x22\xc3\x44\x1a\xda\x17\x6c\x6a\x85\xbf\xf3\x84\x63\x4b\x12\x8d\x33\x1e\xe1\x3f\xa0\x5b\x47\xdc\x5f\xd2\x3b\x60\x19\xa7\x0a\x93\xca\xe6\xfd\xe3\x08\x88\xc1\x0a\x07\x6c\x44\x3d\x42\xc5\xa3\x2c\x17\x32\x90\x4c\x48\x83\xc0\x86\xf0\x7b\xfe\x78\xc9\xdd\x2d\xfc\xac\x60\x90\x09\x43\x90\x4b\x54\x9e\x0e\x41\x88\xb2\x3f\x92\xc5\x51\xcf\x5f\x69\x57\x27\x93\xb7\x01\xef\xf2\x25\x1b\xaa\xfb\xa8\xcc\xcc\x50\xe6\xec\x26\x16\xcc\x29\xb7\xd3\x4f\x64\x24\x36\x7d\x95\x61\xd2\x9b\xfe\x64\x7c\x06\xe0\xe9\x0b\x5d\x28\xd0\x1c\x65\xc8\x5b\x96\xc8\xac\x2c\x93\x2c\xc3\xc6\xa4\xaf\x60\xa1\x06\xec\x6c\xe2\x49\x29\xf1\x4d\xb8\xc8\xdb\xed\xee\x72\x92\xe4\x85\x11\x8a\x40\x2f\x0e\x26\x75\xdb\x7d\xf3\xc0\x61\x62\x99\x52\x4e\x02\xc3\x22\x61\x26\x74\x6e\xe6\x13\x5c\xb3\x18\x2b\xe7\xea\x34\xf5\xe2\x63\x99\xe6\x4e\xfb\x23\x3c\x3d\xdc\x5c\xe3\xf9\xc7\x05\xf1\x0c\xc8\xd2\x78\x04\xe9\x64\x87\xce\xb4\x70\xb0\xb1\xd0\xe9\xec\xdb\xb8\xe2\x8c\x4b\xb2\xfc\x52\x40\x6c\xa8\x76\x20\xf7\x43\x8e\x6c\x7b\xdf\x94\xb3\x50\xf7\x01\x57\x06\x59\xc4\xb8\xd7\x28\x98\x93\xc9\x59\x06\x5d\x16\x81\x3d\xb4\xe6\x87\x2c\x4e\xf0\xdb\x19\x3a\xcc\x0f\xb4\xa9\x1e\x68\x57\x70\xa3\x2b\x9f\xbe\x4e\x2e\x49\x46\xcc\x04\xe1\xa5\x4d\x0d\x6f\x79\x91\x3f\x83\x91\xb3\xf7\x60\x72\x62\x19\x31\x40\xce\xe1\x6d\xf5\xdc\x3d\x6e\xe7\x16\x93\x9f\x49\x4f\xfa\xbd\x5a\x12\x9e\xe2\x8b\xb7\x7a\xf6\x2d\x8f\xaf\xb0\xbc\xd3\x1b\x26\x89\xee\x55\x17\x7a\x2c\xfa\xb4\x13\x13\x06\x1a\x27\xcc\x81\xca\x33\x63\x13\xdd\x70\xdc\x4a\x5c\xb9\xce\x4c\x82\x96\x62\x26\xf7\x3f\xe3\x47\x2f\x63\xc6\x03\x20\x64\x7b\x52\xc7\xaa\xf5\x3b\xce\xf4\x72\x63\xe5\xe8\xe7\xdf\x56\xdb\xfd\xe3\xd5\xdf\x9e\x6e\x1e\xaf\xee\xae\xee\x43\x53\x4c\x26\x10\xa3\xa0\xe1\x25\x4c\x35\x75\x96\x23\x27\x99\x80\xc6\x79\xb0\x7b\x81\x55\xd9\xbc\x43\x7d\xd3\x4c\xe6\xa3\xa4\x29\xa0\xaa\x83\xd7\xf5\x43\x59\x3f\x27\x36\xd9\x0e\x6d\x70\x49\x55\x82\x48\xb3\xcb\x53\xab\x5f\x82\x46\xe8\xf2\x37\x52\x65\x9d\xc3\x9b\xeb\x69\x8e\x14\xa0\x98\x64\x11\x20\x3f\x42\x9d\x3e\x1e\xab\x06\xbe\x3d\xde\xae\xe7\x41\xd5\xf4\x64\x8c\xc7\x6a\xe8\x06\xaf\xbb\x67\x36\xb9\x7a\xa6\x1d\xe1\xc2\xdd\x8b\xbb\x8f\x49\x35\x6c\x76\x2e\x4e\x29\x46\x5b\x79\xf3\x50\x5e\xc8\xb6\x9d\xb9\x2a\x85\xae\x84\xe4\x99\xd3\x0d\x71\x7b\x62\x17\x60\x6c\xa1\x6d\xc7\xfe\xb2\xbf\xca\xbe\x3e\xcd\xf0\x65\x66\x5c\x49\x27\xd0\x57\xbf\xf5\x3a\xc9\x4c\x4a\xc6\xd2\xd4\x2f\x1d\xab\xa2\xb8\x06\x18\x90\xfa\xd3\x89\x2a\x2d\x09\x3a\x70\xdb\xfc\xb9\xec\x43\x97\x49\x40\x25\x55\x62\x30\xf5\x87\x37\x59\x9c\xb0\xb4\xeb\x6a\x17\x7e\x66\x4f\x2f\x4c\x59\x21\x45\x80\x58\xd6\x79\xf7\x8e\x34\x23\xa0\xe2\xb4\xfd\x16\x1a\x0a\x52\x83\xb0\x66\xf0\xd7\x82\xfa\xad\x5f\xe1\xfd\x08\x43\xc5\xd0\xc3\x75\x2c\xbd\x29\x69\x47\x1a\x88\x91\x4d\xf0\x78\xb5\xbd\x7a\xfc\xd1\xcb\xaf\xee\xaf\x1f\x1e\xf7\x5e\x68\x33\x0c\x85\xc4\x5d\xe4\x33\xb4\xdf\xe1\xe7\xd6\x49\x32\x4e\xbe\x0e\xc0\x11\xdd\xdd\xb3\x3b\xe4\xe5\xc5\xe9\x63\xf6\x4b\x6d\x9c\x20\xfa\xc0\x99\x8c\xb6\x9f\x11\x88\xf1\xe1\x4d\x6f\xbb\x55\x19\x26\x57\xfd\x2e\xb8\x6d\x87\xc4\x4d\x45\xa9\xab\x07\x38\xc8\xc2\x4d\x69\xab\x0d\xd4\xff\xac\xca\x4f\x40\x3a\x8a\x98\x44\x8d\xb4\x9a\xbc\xe8\x9a\x3f\x18\x47\x1c\xbb\xca\xbe\x89\x76\xcc\x7b\xd8\x9b\x8a\x3d\x5b\x1b\x37\xa7\x6e\xf7\x78\xc0\xf8\x35\x1c\x4e\x22\x8a\xc4\xcd\x6e\x23\xbd\x80\xb6\xb9\xae\xea\xa9\xdb\x1b\x53\x49\xa2\x82\xeb\xce\x65\x55\x82\x72\x0a\x7d\x87\x31\xa9\xa6\x1f\xe9\x90\x98\xa1\x78\x77\xaa\xdb\xbe\xc4\xa6\xd2\x24\x8e\x02\x0f\xe2\xa9\x81\x7a\xb1\xcc\xa6\x50\x8b\x14\xdf\xba\x2e\x4c\x19\x04\xf2\x99\xa2\x34\xc5\x86\x68\x73\x52\xdd\x53\x9a\x03\x1a\x17\x23\x30\x45\x99\x72\x42\xbb\x7e\x93\xdf\x37\x2f\xb2\xf7\x9e\x63\x8a\x1a\x82\xed\x90\x2e\xf4\xbe\x96\x39\x4a\xb0\x7f\x3b\x7d\xdc\x57\xab\x53\xfb\xf2\xdb\xe4\xfe\x53\x88\xa3\x78\xd4\xbc\x43\xc9\x85\x4f\xd6\x0e\xc5\x48\x84\x94\xc9\x6f\xd5\x65\xfe\x3c\x4a\xf9\x17\x2a\x9e\x8a\x51\x1b\x0c\x7d\xef\x2a\x73\xea\xb7\xf7\xe9\x19\x79\xc4\x84\xee\x75\xf5\xa1\x9d\x6a\xb3\x32\xc5\x69\x22\xfd\xe5\xad\x91\xb5\x7e\x0d\xb0\xa9\xaa\x59\xb9\x4e\x71\x6e\x32\x27\x26\x05\x5e\xfe\xde\x09\x3b\xed\xaa\x8b\x93\x79\xee\xbb\xf1\x4a\xa4\x5a\xfa\x8b\xda\x48\xfd\x8a\xfa\x62\xf3\x82\x95\x12\x3a\x0d\x40\x5a\x5f\xb3\x5c\x44\x4d\x4f\xaf\x20\x13\x26\xea\x15\x8a\xcf\xa8\xd1\xe3\x95\x55\x49\xe6\x34\x6d\x9b\x6e\x03\x3c\x1e\xbb\x93\x80\xc1\x0c\xee\xbc\xda\xa0\x24\xe7\xc2\x4b\x0a\x5d\x06\xd1\x85\xbc\x2a\xbd\xa8\xfe\xf4\x1a\x54\x2c\x30\xbf\xf5\x08\x89\x89\x36\x15\x53\x4a\x39\x13\x6a\xbf\x4a\x35\x2f\xbf\xc3\xc7\x64\xd9\x50\x3a\xce\x42\x4e\xd2\xad\xc8\x3d\xd4\x64\x76\x7f\x8c\x96\xb8\x81\xc3\x7f\x4f\xbd\xab\xf7\xf4\xd9\x43\x9c\x10\x27\x37\x7c\xac\x6a\x7f\x17\xc4\x2f\x2d\xb7\x47\x41\x86\x82\x18\xf0\x76\x16\x60\xdb\x24\x9e\x5d\x00\x30\x2b\x7c\x31\xba\xbf\x6d\x62\xae\x71\x31\x99\x46\x90\x31\xa4\x2f\xb8\x54\xf5\x3a\x2f\x8a\xf3\x5c\xe3\x57\xac\x96\xbf\xcc\x0a\xd7\x0b\xf4\xe3\xee\x8b\x34\xf6\xab\xbb\x75\x67\xb2\x2e\xda\xc4\xd8\xc4\xfb\x2a\x39\x48\xd0\x79\x83\x7c\x31\x46\x54\x96\x0a\xcc\xa3\xaf\x1e\xd7\x71\x9c\xe0\xf6\xb1\xdf\xee\x56\xfe\xc4\x3a\x22\x1c\x31\xce\xff\x7b\x39\xe9\x97\xd3\xf4\x4e\xe9\xee\xed\x4a\x02\xe5\xc4\x73\x65\xfb\x0f\x66\xb1\x1a\x79\x2b\x7e\x3b\xc9\x5a\x96\x2d\x80\x71\x62\xfa\x93\x8b\xd0\x24\x31\xb1\xe8\x77\x14\x87\x0d\xda\x05\x1b\xd8\x19\xd8\x60\x71\xed\xd0\x71\x96\x61\x62\x5a\x56\xe8\x2b\xb5\x7b\xe9\x11\x1b\x3a\x21\x0c\xd9\x79\xdd\x55\xee\x5e\xea\xea\xfd\x11\xf0\xf5\xb9\x95\xae\x19\xec\xb4\x42\xee\xab\x76\x5c\xc8\xd3\x49\x2a\x90\x65\xed\xc8\x67\x5e\x68\xc5\x8c\x52\x1d\x9d\x66\x1a\x6b\x62\xce\xcc\x70\x01\x69\xbf\x84\xa2\xd1\xdd\x06\x96\x8c\xca\x66\x5e\x2e\x7d\x4e\xab\xfe\x53\xb3\x39\xcc\x8f\xf1\xdc\xd6\x34\x56\x4e\xe3\xaf\x9b\x24\xdf\xe1\xe7\xba\xea\x72\x13\x57\x15\xc1\xeb\x19\x22\x7e\x4d\xb3\x84\x27\x2e\x63\x77\xe2\xf7\x07\x74\x32\xa8\x8e\xf2\x79\x98\x5c\x9a\x31\xe5\xfb\xef\x3e\x27\x58\x9d\x8b\x1e\x85\xa1\x36\x41\x1b\xd5\xdd\xd5\x6a\xfd\xdd\xd9\xd8\x8f\xca\xf9\x9a\x13\x8a\x1d\x8a\xaa\xce\x9f\xf3\xde\x39\x93\x69\x9e\x71\xac\xb5\x05\x51\xa9\xba\xce\xe5\x33\xdc\xe6\x1a\x4a\x0d\x37\x07\xf9\x0c\x37\x9b\xeb\xed\x4b\x2f\xae\x1d\x3e\xa6\x49\x1c\x94\xad\x5f\xba\x59\x5f\xf6\xd6\xa3\x4c\x67\xcc\x09\xe9\xe1\x7d\x68\x4f\x0a\xd6\x45\x7e\xfc\x4c\x2e\x68\xfa\x2b\x32\x95\x7a\x32\x34\x86\xeb\x1b\x57\x23\x1c\x57\xb7\xb4\x4c\x05\xee\x1c\x5d\x4c\xbc\xb4\xab\x6b\x69\x29\x8a\x52\x5c\xec\x2e\xc2\x67\x74\x42\x78\xaf\x2c\x7c\x38\x56\x25\x94\xed\xd2\x02\xa7\x75\x9a\x58\x57\xc8\xd7\x95\x01\xb3\x05\x5d\xf7\x9b\x8c\x36\x99\x42\x51\x83\x7d\x5b\xe7\xcf\xcf\x50\xdf\xc3\xfb\xe6\xc7\xa6\xdb\x13\xa0\x5b\x96\xbf\x2e\x5d\x69\xa3\x22\x8c\xe5\x9b\xa1\x57\x72\x73\x39\xbb\x74\x48\x12\x64\x13\x60\x9b\xe4\xb6\xea\x29\x32\xf3\x61\x20\x30\xe8\xd8\xc1\xe1\x58\xd5\xb2\xfe\xd8\x7c\xd4\xf2\xd0\xd7\xde\xb4\x25\x0a\x97\x8e\x61\xb1\x5a\x9e\x33\x96\x19\x24\x40\xf4\x04\x9b\x3f\x9b\x01\x84\xcf\x5b\x17\x0a\xdc\xc3\xfb\xaa\x06\x39\x4d\x9e\xc7\xb0\xd2\xb3\xff\xed\xcf\x61\x22\x19\xc5\x63\x2d\xb7\x5f\x2d\x9e\xe7\x1c\x39\x13\x81\xb3\x1d\x3d\xc8\x57\x78\x38\x2e\x5a\x75\xcf\xbf\x14\x14\xeb\xa5\x2f\x72\xd9\x2c\xe2\x43\x4d\x64\xdd\x28\x07\xa0\xc6\x77\xa2\xf1\x45\xce\xc5\xf1\x84\x46\xf8\xfe\x6f\xaa\x80\x1f\x31\x84\x2b\xbc\x43\xb7\x55\xf9\x7c\x51\x9d\x9e\x5f\xda\x25\x0c\x6d\x3c\x57\xec\x4a\x66\x38\x2d\x43\xb8\x46\x45\xcf\x41\x5a\x7c\xf9\x91\x1a\xa2\x59\x44\xc7\xed\xc0\x8b\x53\x7b\x16\x50\x98\x38\xd6\xd8\x4b\xd5\xb2\x44\xbb\x4b\xdc\x3e\x16\x9f\xb1\x89\x53\xad\xd4\xe0\xae\x6d\x7a\x6f\x0b\x66\x12\xe6\x18\x3f\xeb\x97\x3a\x6f\xda\xea\xf8\x02\xf5\x63\xa5\xf2\xf2\x31\x64\xf3\xa6\x4b\x61\x11\x10\x24\x9b\x97\x1d\x14\xf0\xb3\x3f\xc0\xb5\xb1\xa3\x40\xd6\xd9\x39\x74\x97\xb1\x91\x35\x94\x6d\xe3\xfe\xb9\xaf\x9c\x6d\x75\x68\x02\x1b\xca\x04\xc2\xcb\x1e\x57\xbb\xab\xfd\xfa\xf1\xe1\x8f\x4b\x04\x69\x6d\x43\x7b\xcc\xb0\x54\xe2\xea\xf0\xfb\x49\x41\x2d\xfb\x36\xa7\x61\x8c\x1b\xdf\x51\xbd\x70\x37\x79\xbc\x9e\x19\xa6\x9c\x90\x8d\x5b\xcf\x0e\xc7\xe6\x7a\xd2\x6f\x37\x4c\x67\x08\x97\x90\xc6\x5c\x43\xdf\xa9\x30\x9c\x64\xbd\x0e\xe2\xfe\x54\xb6\x79\xd1\x1f\x49\x0c\x7a\xaa\xbd\xc8\xe6\xbb\x2c\xda\xd1\x47\x8c\x4d\xe3\x11\x9b\xab\x5b\x3e\xa4\x6e\xbb\x84\xaa\x3e\x8c\xdd\x26\xfd\x78\x91\xa5\xa9\x6f\x88\xf7\x89\xd9\x2e\xef\xa6\x63\x0f\x0e\x37\x19\x25\x88\x4a\x91\xe5\x5b\xb1\x03\x3d\x61\xa7\x1a\xc5\x12\xe3\x4a\x65\xef\x28\xd8\x7d\x0e\x09\x99\x3d\x71\x65\x33\x85\x7a\xb9\xb9\x7e\x3d\x1d\xbd\xc2\xc6\x34\xfe\x30\x46\xf5\xb7\xd3\x43\x53\xe6\x22\x9b\xd3\xf1\x10\x59\xe5\xb8\x08\x4e\xf6\x7e\xb9\x6c\x66\x40\xc5\xb8\x4e\x5f\x15\xb8\x1f\x3e\x39\x62\xd6\x79\xaf\xf8\x4f\x46\x76\xfe\xac\x96\x50\xcf\x4a\xb6\x16\xea\x91\x43\x03\x33\x36\xd6\x81\x8f\xfb\xa9\x8f\x05\x83\x28\x95\xb1\x0d\x28\xe7\x25\xe8\x18\x44\x8c\x39\x6c\xaa\x03\xc8\xfd\xfe\x8f\xf5\xa4\x40\xfe\x97\xd3\x02\xae\x06\x22\x1d\xbb\xfd\xc4\x95\x7f\x1e\xec\xaa\x7d\x29\xa0\x3d\x8b\xbb\xfe\xd4\xaf\x04\x22\x52\x64\x9a\x3c\x14\xb9\x0d\xf3\x16\x88\xb2\xf8\xf6\x3a\xfa\xc9\xaa\xfd\x56\x57\xa7\xe3\xf2\x33\x02\x62\x79\x12\x8f\x0d\x47\x36\x75\xa5\x61\x24\x55\x02\xc4\x4a\x04\x4f\xec\x5d\xaa\xe1\xcd\x12\x9d\x57\x79\x55\x5f\x7c\x78\xb0\xf6\x72\x77\x01\x62\xea\x3c\x3a\xa5\x31\x41\x3d\xef\xb7\xd9\x08\x49\x78\xea\xa5\x50\xb4\x23\x55\x34\x83\x4b\x2f\x83\x24\x71\x76\x07\x5d\xbe\xbe\x5a\xef\x1e\x1e\xfb\x03\xa9\x88\xbd\x6c\xfa\x57\xb9\x2b\x24\xcc\x59\xc7\x75\x39\xb9\x9b\xaf\xcd\xe7\xdc\x6b\x48\xb4\x8b\xe7\x1a\x28\x8a\x5d\x37\x11\xd7\x55\x69\xf3\x10\xa7\x42\x9a\xba\x66\x74\xc0\xf0\x38\x84\xc8\x6e\x3b\x5e\x58\x20\xcd\xa8\x6b\x9b\xe6\xa5\x33\xcd\xf9\xe2\xfb\x52\x93\xe0\x6a\x52\x9e\x0e\x0f\xd6\x59\xc2\x5c\xc9\xba\xf8\xd8\x9c\x6a\xfd\x22\x9b\x3e\xc0\x02\x4a\x23\xec\x54\xdf\x56\xcf\xd7\xde\x6a\xfb\x93\x0e\x0b\x50\x9d\xe0\x9d\x29\xba\x1c\xbb\x69\xbf\x3f\x5c\xde\x5e\x3d\x86\x77\xd5\x8f\x61\xd6\x1a\x33\xd8\x74\x6d\xdb\xaa\x1e\x8a\x9a\xc0\x19\x47\xd3\x18\xb4\x97\xf8\x04\x25\xb1\x2c\x47\x38\x89\x98\xc9\x27\xd3\x96\x8b\x48\x45\x3d\x06\xf4\x15\xc3\xfc\xe9\xac\xe0\xda\x39\x82\xe7\xcd\x2a\x98\x16\xce\x27\x8e\xf0\xde\xd0\x8f\xcf\xb9\x75\xcb\xea\x68\xf1\x86\x2c\x31\xf8\x0b\x0e\x1e\x8f\xe0\xe7\xf5\x6f\x23\xd5\xc4\x4f\x2e\x2e\x93\x0a\x83\x93\x6f\xb2\x85\xf7\xbe\x85\x0d\x19\x24\x58\x61\xaa\xc1\x19\x22\x39\x7c\xb9\x3f\x28\x63\x47\x72\x0f\x01\x8d\xf7\xb6\xea\x0f\x6b\xea\xc4\x70\x4e\x47\xa8\xcf\x4a\xfd\xd3\xaf\x57\x32\x42\x7d\xf1\x6e\xe7\xfd\xac\x2a\x1f\x86\x2a\x8a\x71\x3c\x76\x1b\x3c\xc3\xf2\xbc\x9d\xf5\xf5\x0a\xa2\x29\xd3\xb4\x57\x84\x1a\xf4\xe2\xfa\x79\x67\xe2\x54\xfa\x9a\x85\x37\x68\x9b\x30\x2f\xc2\xa8\x84\x60\xa0\xbb\xda\x8d\x9d\xf4\x18\x18\xb0\xa8\x7d\x26\xb5\x1e\x4a\x81\x00\x32\x93\xa4\x77\x16\xc0\x72\xba\xeb\x38\xf7\x03\xc0\x38\x19\xdf\xaa\x28\xaa\x37\xa8\xc7\x89\xe9\xf2\xef\xb0\x8c\xb1\x68\x2a\xc7\xf5\x99\xb0\x99\xfb\x84\x8d\x62\x97\x72\xfe\xf7\x04\xf5\xc7\x06\xea\x43\xde\x34\x83\x6c\x35\xb3\x51\xca\x50\x79\xc9\x09\x38\x05\xeb\x4d\xd1\x1f\xce\x38\x4a\xb1\x34\xae\x5a\x1d\xfe\x4c\x32\x21\x7c\x50\xb1\x47\x95\xbe\x7d\x5e\xda\x2a\x1c\x8d\x53\x8d\xb1\x91\xf5\x5a\x66\xdb\xfc\xe7\x9f\x7b\x4e\x36\xa6\xae\xd8\xe5\x60\x07\x2f\x55\xfd\xdb\xe7\x9a\xab\xcc\xc6\x20\x84\x93\xbf\xff\xb8\xae\xea\xbb\x8f\x06\x0a\xdb\x4d\xa6\x80\x3b\xec\x05\x0f\xdd\x6b\xea\x3f\x95\xc6\xc6\xba\x66\xd0\xe7\x66\x69\x8b\x33\xd1\xa6\x89\xc5\x8e\xcb\xb6\xcd\xa1\xbe\xc8\xdb\xf1\x1c\xb0\x3c\xd5\x2c\x5c\x7a\xad\xf2\xd6\xd5\xa1\x46\x36\x07\xa3\xae\x98\xe5\x8c\xa5\x62\xc4\x67\xb8\x6a\x5f\xb6\x5d\xa6\x65\xfa\xb3\x49\x81\x35\xb4\x8b\xd3\x87\x23\xdc\xfe\x76\x96\x6d\x84\x91\xda\x55\x96\x9c\xf8\xc9\xa7\x15\xa2\xe9\x9d\x13\xa9\x41\x59\x96\xe7\x5a\x96\xed\x30\x2b\xce\x6b\xe9\xdd\x8d\x4b\xe7\x1f\x06\x0a\xc1\x29\x0f\x7d\xde\x9e\xba\xf0\x70\x3b\x82\xbf\xdb\x2c\x16\x44\xf4\x62\xe8\x26\x6f\x2f\xe5\x72\x47\xc4\x66\xd9\xc8\x2c\x6c\x3b\x40\x35\x6c\xa6\x9c\x52\xbe\xae\x9a\xee\x0a\xfd\x5d\xf0\x07\x25\x49\xb1\x4d\x7d\xf7\xd1\xc5\xac\xf1\xe4\x41\xc8\x98\x8e\xb6\xda\x99\x0b\x64\x18\x03\x2c\x89\x7a\x4b\x29\x54\xed\x76\x3c\x96\x70\x12\x65\x19\x46\xe3\x79\xb3\x91\xa7\xb9\xf7\x2b\xb3\x3a\x8b\x10\xaa\xb6\xdf\xab\x41\x10\x6a\x51\x16\x9a\x59\x2d\x1d\xe6\x07\x15\x65\xc6\x6a\xf8\xf3\x8b\xd2\xd6\xa2\x01\x8c\xec\xdd\xac\x4f\x03\x5b\xc2\x9a\x2c\x0d\x0c\xaf\xa7\xc6\x60\x1b\x6a\x81\xf9\x6f\x0d\x10\x4e\x42\x2b\x74\x6d\xce\x22\xa2\xe5\x5a\xb0\x85\xd8\xe9\x1f\xd4\xae\x7a\x7c\xb3\xba\x3b\x27\xeb\x59\xd0\x09\x62\x01\x6f\xab\x67\xa7\xee\x12\x53\x76\x76\xfe\x71\x54\x62\x6d\x94\x61\x8c\x30\x92\x0a\xbb\xf8\xd8\xa0\xd7\xfb\x74\x5c\x9a\xa0\x05\x2d\xce\x82\x9b\x72\x3d\x5a\x9a\xbb\x9b\x82\xe4\x5c\x05\xed\x23\x98\x11\x2e\xc6\x5a\x96\x7a\xeb\x96\xb6\x17\x3b\xab\x4e\xa5\xf9\x26\xcf\x34\xd3\x99\xb5\x1c\x9c\x0e\xb0\xc3\x45\xfb\x65\x73\x3e\x48\xc5\xd8\xd9\x38\xec\x7b\x88\xe2\x18\x5f\x6d\xad\xb1\x4a\x07\xf3\x99\x9f\x5e\x5d\xca\x47\x39\x3c\x8a\x62\xb7\x04\x38\x5f\xc2\xc7\xab\xf5\xd5\xcd\x8f\xab\xcb\xc1\xfe\x81\x47\x11\x4b\x99\xe7\x54\x3b\xe1\x52\xe7\x37\x74\xfa\xa8\x4e\x0b\x3a\x0e\x3c\x8a\x4c\x82\x39\xef\x51\x96\xb9\xee\x4f\x62\x34\xe5\xc1\xc5\xbc\x6e\x5a\x0c\xfb\x5d\x48\xe9\xea\xa0\xb3\x73\x58\x89\xd1\xf3\xb7\x1f\x53\x82\xd1\x78\x02\xf0\x28\x26\x1c\xd7\xd2\xbf\x6d\x2f\xfa\xab\x8d\x99\xc1\x8e\xf5\x8f\xaa\x78\x6d\xba\x7c\x36\xe9\x8f\x08\xab\x6d\x10\x7d\x42\x56\x66\xf3\x92\x1f\xa7\x35\xab\xbf\x4c\x2f\x23\x36\x04\x17\x4f\x23\x5b\xb9\x96\x85\x5e\x4c\x48\x78\x14\x5b\x89\x08\xf6\x7d\x17\x7b\x3a\x31\x83\xc7\x01\xd4\xcb\xa3\x34\xd2\x2a\xed\xc9\x74\xd8\x1b\xad\xec\xaa\x34\x83\x49\xde\xec\x84\xa9\xd0\xdc\x43\x1c\xdc\x5a\x70\x51\xcd\x16\x21\x1e\x51\x9a\x20\x1f\xc4\x00\x26\x84\xcb\x3f\x80\x2a\x8a\xcc\xe1\xbf\xaf\x1f\x6e\xee\xc3\xe5\x50\xd3\x6f\x84\x85\x6c\x5a\xa4\xf1\x84\x63\x2c\x4e\xb1\x4f\xa5\x4e\xdd\x2a\xd5\xff\x35\x35\xcc\x03\xaa\x47\x12\x75\xe1\xa0\x70\x12\x76\x06\x9a\xb6\xae\x3e\xd0\xdd\x38\x1c\xd2\x4e\xe9\x65\x1f\x8a\xbc\x57\xff\x3d\x8d\xd1\xbd\xd3\x8b\xe5\x36\x45\xcb\x22\x07\x84\x79\xb0\x58\x86\x0e\xc6\x5a\xcb\x1f\x11\x34\xc3\xd2\xf3\x16\xb9\x08\x27\xb4\x62\x9e\x5c\x9c\xc8\x2c\x8b\x03\xa4\xad\xce\x6d\x3e\xc6\x4a\x8d\x82\x0e\x1e\x65\x11\xc5\x9c\xf8\xda\x75\x75\xfa\x69\x23\xa9\x4d\x1d\x02\xd0\x65\x62\xbf\xcd\x2a\xcf\x7e\x98\x22\x99\x48\xfb\x74\x0d\xcc\xc5\x6e\xfd\x5b\x7f\xc8\xa2\xa2\xef\xaa\x1c\xeb\x74\xf3\x48\xc5\xc2\x99\x2c\x74\xeb\x66\xbb\xaf\x86\xaa\x3b\x8f\x14\x03\xbc\xa9\xd2\x74\x41\x98\x7e\x75\x15\x4a\x5c\xad\xe5\x14\x0f\xd1\x37\xb1\x78\xa4\x14\x0b\x8e\x2a\x55\x8f\x5d\xf8\xcb\xe4\x7e\x68\x19\x67\xa4\xe7\x55\x42\x7d\x0b\x6f\x50\x24\x23\x0b\x3f\x1e\x19\xce\x31\xca\x46\x65\xa7\x95\x59\x12\xde\x9d\xe5\x4a\x3c\x02\xc1\xd1\xfd\x36\x44\xd9\x17\x79\x31\xed\x1d\x72\x12\xc5\x12\xd3\xa9\xab\xdd\x7a\xf9\x61\x92\x28\x25\x08\x99\x68\xdf\xa1\x6c\x3f\x82\x1a\xfd\xbe\xb2\x7b\x39\xf2\x60\xe1\x24\xd2\x4e\xaa\xce\x43\x56\x93\xe1\xef\x0c\xe5\x31\xe0\xa7\x96\x6f\xa3\x4d\xa0\x3b\x62\xb1\xe8\x52\x4e\x21\xa3\x9c\x10\x4a\x02\x2d\x03\x7a\x71\x36\x4e\x08\x4f\x85\x8f\x8b\xee\x2f\xd7\xeb\x11\xef\x6b\x1e\x0c\x70\x42\x8c\x02\xd2\x93\x8d\x5c\x04\xe5\x75\xc4\xfc\x88\xc4\xc6\x99\xea\xe9\x08\x79\xf9\xbc\xae\x9a\xf6\x74\x80\xc7\xb9\x92\x21\x27\x29\x73\x7a\xf5\xb8\x4c\x36\x5a\x9e\xfb\x84\x4f\x66\x1d\x49\x75\x24\xa5\x03\x49\xff\xfc\xf0\xa5\x9f\xee\x0b\xbc\x99\xcb\x97\x91\x39\x27\x94\x09\x07\x1f\xf3\xca\xba\xf7\xf0\x7e\x09\x58\xea\xcf\xdf\x60\x71\xe1\x9d\x9f\x40\x39\x56\xd4\x5c\x02\x6b\x53\x03\x42\x45\x0c\x46\xb5\xbf\x42\x4e\xcd\x81\x2c\x7d\xbe\xce\x09\x63\xee\xf5\xfd\xdb\x49\xd6\xaf\xfa\x45\x9e\x87\xbf\x7e\x20\x8f\x00\x21\x0c\xb7\xd5\x33\x4e\xe6\xcf\x52\xb9\xf9\xc7\x0c\xc8\x00\x18\x71\xc1\xda\xf4\xe1\x72\x1b\x53\x8f\x58\xad\xab\xb2\xb9\xa8\x64\x3f\x47\xb8\xcd\xb8\xee\xdd\x1b\x4e\x45\xd8\xfc\x39\x11\x86\xe0\x5d\xd9\x7f\x5a\x44\x1f\xbf\x92\x44\x18\x8d\x48\xbf\xa3\xfc\x78\x38\x21\x20\xb4\x3e\xeb\x96\x73\x92\x09\xa7\x68\xdb\x65\x2f\xaa\xbb\xd5\xe7\x7a\x08\x9c\xc8\x38\x0a\xaa\x62\x8f\xd0\x74\x9b\x1c\x2c\x63\x0c\xba\xa1\x31\x77\x46\x7c\x0e\x91\x32\x84\xe7\xdd\xb1\x04\xe5\x07\xd4\xa9\x2e\xef\xe6\x53\x54\xaa\x18\x93\xaf\x17\x59\x9a\x22\xa8\x2b\xd7\xd5\xe1\xa1\x0f\x15\x27\xae\xef\xcb\x13\x47\x1a\x07\x6e\x71\x1c\x83\x9e\xe7\x84\xb1\xe3\x74\x86\xab\x84\xe3\xae\xfd\xe3\x6a\xbb\xbb\xb9\xff\xb6\x5f\x5d\xfe\xb8\xd9\x3e\x3c\xce\x54\xdb\x38\xd1\x19\x35\xde\x90\xce\xc9\xb2\x00\x2c\x53\x4e\x38\x31\x91\x43\x2d\xd7\x68\x33\x7e\x11\xce\x60\x52\x67\x10\xe7\x81\xaa\x5d\x1c\x75\x3d\x6c\xe2\xc4\x30\x86\xb5\x49\xf8\xa9\x01\x4c\x73\x27\x7f\xde\x94\x6f\x53\x43\x25\x4e\x40\x2a\x3a\x28\xf4\x78\x70\xee\x76\xd2\x8f\x0a\x23\xad\x06\xda\x6f\x76\xd7\x55\x3d\x86\xe4\x74\x87\x81\xf9\xc8\x79\x2f\xe7\x0b\xf0\x34\x0c\x22\x96\x38\x29\xaf\xa3\x2f\x4c\xed\xaa\xf7\x72\xf6\xd0\x6c\xea\xd6\xf4\x2e\xea\xc4\x62\xcc\xe2\xf4\xb1\xbe\x0d\x60\xe5\x5b\x55\xe7\x2d\x8c\xb9\x69\x1c\xf1\x88\xc8\xf3\x84\x9f\xc7\xa2\xca\xdb\x87\xf7\x32\x2c\xb0\x71\x44\x9c\xbe\xfd\xd1\x89\xdc\x9e\x39\x4b\x86\x61\xb1\x20\xce\x83\x28\xf4\x4d\xba\x68\x72\x7a\x67\x62\x02\x06\xdb\xd4\x50\x3a\xec\x64\x50\xfe\x0b\xdf\x15\x47\x16\x5b\xab\x68\xcb\x07\x87\xfc\x74\xb8\xac\xe5\x73\x55\x8e\x11\xf5\x3c\x8e\x13\x46\xbc\x4e\x27\x66\x79\x5b\x68\xdb\x22\x2f\x9f\x17\xab\xa1\x3c\x8e\x55\x2a\x03\xf6\x08\x60\x23\x6b\x79\x80\xb6\x2f\x1e\xf0\x38\xe1\x16\x31\xc3\xb6\x86\xbe\x22\x37\xfd\x6d\x29\x91\x31\xef\xe9\x74\x08\x2e\xf5\xda\xc4\x81\x1b\x39\x7a\xc5\xe2\x34\x8d\x31\x64\x0c\xf5\xfc\xf1\x8a\x10\xa7\x94\x6b\xdf\xde\x70\x3f\xed\x7e\x8c\x5a\x99\x0e\xcd\x5c\x51\xf4\x1b\xb4\x57\x6f\x50\x62\xe3\x22\x5c\x33\x8d\x09\x19\xc2\x81\xee\x1c\x93\x3b\x44\x29\xcd\x3c\x3e\xe6\xe1\xf4\x06\x75\x7b\xaa\x61\x6f\xa0\xd9\x9b\xba\xca\xdb\xf9\xa3\xa3\x86\x62\xe3\x63\x7f\x6a\x2b\xb9\x80\x9a\xe5\x31\x4f\x0d\x42\xcc\x3c\x58\xff\xa9\xf9\x44\xf0\x99\xc7\x3c\x73\xab\xea\xef\x57\xbf\x5f\xe9\xe1\xc1\x0a\x9a\xe0\x8a\xda\xe5\xe7\xa7\xe3\xb2\xe2\x03\x8f\x85\x49\x24\xda\xb5\x38\xcb\xf1\xab\xcb\xa7\xe5\xd7\x3c\xce\x22\xaa\xa5\xef\x43\x22\xad\x6a\x76\xa2\x2c\xe9\x1d\xc6\xfa\xf9\x3a\xb9\x41\x52\x72\x97\xcd\x7b\x17\x39\xf7\xa4\xc6\xb5\xd6\x91\x35\x65\xf8\x8c\x49\xd0\x31\x64\x54\xae\x9b\x9c\x53\xb1\x14\x03\x8e\x95\x19\x38\x1c\xdd\x5f\xc1\x7a\xac\xee\x1f\xf9\x60\xe1\x1d\xee\xac\x66\x02\x09\x9e\xd2\x98\xcd\x48\xaa\x24\xc4\x61\xe9\xfc\x3f\x48\xb8\x1a\x2d\x1d\xd3\x4d\x7a\x3f\x8a\x8b\xdc\x24\xd3\xf5\x35\x36\x09\x55\x9e\x34\x73\x0d\x10\xaa\xa3\xd3\x3b\x05\x24\xc3\x38\xc1\x71\xf4\x1e\x8e\x50\x9e\xfb\x76\x8e\xf0\x17\xfd\xb9\x41\x45\x89\xdf\xd9\x6e\x2b\xd9\x3f\x67\x9b\x38\x81\x8d\xc1\x25\x63\xf9\x01\x5a\xa3\x5c\x7c\x8c\x6c\xff\x73\xd7\x05\x9e\x44\xdd\xbc\xf4\xf6\x50\x55\xb7\x60\x3b\x7a\x03\x36\xe3\x26\x3f\x21\x89\x94\x45\x31\xe0\xed\x6e\xf5\xed\x6a\x4f\xc2\x09\x62\xc9\x8d\x0e\xbc\x06\x0f\xc3\x5a\x0c\xf3\x92\x84\x4b\xe4\x88\x5f\xb4\x50\x0e\x62\x55\x3c\x49\x64\x82\x98\xf5\x2d\x02\xe4\x51\x99\x69\xde\x30\x1a\xbf\xb0\x49\x62\x1c\x15\xad\x67\xb4\x76\x91\xdb\xd7\xbb\x65\x92\x66\x71\x2c\x83\xa2\x8c\x6c\xc1\xd7\x24\x26\x93\xfa\x2c\xb8\xfa\x54\x46\x9c\x27\x34\x16\x08\x49\xf2\xf2\x5d\xbe\xa1\x91\x97\xcf\x8b\xe8\x84\xd9\xc5\xd0\x24\xc1\xd2\x06\x34\xce\xbc\xc7\xfc\x01\xf9\xf3\x4b\x98\xe0\x09\xa5\x0a\x17\xd2\x4d\x7e\x1c\xdb\xc2\xf2\x84\x32\x65\x32\x0f\xe0\xdc\xcb\x53\x5b\xe1\x87\xf7\x17\xa7\x8f\xfd\x71\x00\x94\x74\xe3\x9c\x37\x5e\x97\x2c\x43\xfd\x96\x6b\x70\xc8\xa0\xb3\x34\x04\xaf\x2b\xcc\xb5\x04\x2d\xd7\x07\x21\xf5\x5c\x1e\xaa\xd2\x04\xec\xf8\x9f\x29\xe4\xf2\x84\x6a\x9e\x4e\x78\x27\x9f\x41\x99\x86\x58\xf5\x3c\x09\x4b\x28\x44\xa8\xe1\xb6\xae\x8a\x02\x74\x9b\xab\x02\x3c\xd4\xe0\x57\x85\xdb\xe9\x84\x63\x5c\x30\x35\x02\x6f\x3f\x95\x79\x55\x4e\xee\x28\xcb\x64\x88\x40\x37\x95\xa3\x33\x5c\x02\x18\xc7\x2f\x9b\xbe\xe6\x09\x53\x14\xd7\xa5\x9d\x59\xd4\x8c\xe7\x09\x8f\x1d\x60\xc9\xb5\xdc\xcb\x12\x8a\x6d\x3e\xf3\xd0\xe5\x09\x4f\x22\xc4\x6c\x81\xef\x4c\xc9\xba\xf5\xd8\xf6\xc9\xfc\xe2\x34\xc1\xfd\x0b\x33\xc8\x35\x96\xd1\xc2\x35\x73\x41\x82\x78\xff\x98\xfe\x3e\xbd\x58\x0e\x02\x7b\x36\x6f\x39\xbc\x87\x88\xb2\xfb\x55\x3d\x0b\xd5\x8f\x13\x3c\x45\x76\xfa\xfe\x19\x90\x9a\x87\x17\xe4\x9f\xf9\xdd\xa8\xaa\x91\x64\x54\xa3\xb9\x86\x3c\x1e\xa1\x34\x9f\x2b\xec\xf3\x44\xc6\x71\x12\xbc\xf6\x8a\xaa\x7b\x27\x50\x9f\x6f\x7a\x7d\x52\xc6\x7d\xb0\x90\x17\x67\x47\xbd\x74\x52\x0b\x4d\x3b\x07\x52\x84\x0b\x52\x51\x2f\x7d\x75\x37\xb5\x1b\x9d\x3d\x16\x95\x6a\xc4\x79\x5f\xd4\xf0\x52\x9d\xf7\x4d\xe6\xaf\xea\x2f\x48\x3d\xff\xd7\xbf\x87\x8b\xf0\x9d\xf1\x67\x79\x70\x4e\xc6\xfd\xdf\x65\x12\xf7\xcd\xa2\xc1\x5f\x34\x1c\xd7\x32\xc3\x16\xd3\xfb\xb0\x5c\x42\xe6\x24\x60\xba\x47\xb6\x6a\xbd\xb9\x59\xf3\x60\xcf\x3b\x57\x3c\x01\x63\x11\x94\xb7\x9a\xe8\x98\x4d\xc7\xd8\x88\x38\xc3\xaf\xd1\x2d\xbc\xb9\xfc\x12\x52\xc1\x13\x4b\x1c\x37\x7b\x24\x93\x76\x5d\xd5\x4b\x58\x0c\xf7\x81\x34\x92\x91\xf0\xf5\xb8\xab\xe7\xe7\x33\x61\x1c\x9e\x12\x9a\x2a\x47\x54\x7c\xbb\x69\xb6\xd2\x2e\x43\x17\x78\x4a\x98\x04\x3d\x83\x9b\x8c\xea\x11\x29\x51\x19\x0d\x86\x44\x2e\x6a\x74\x00\x8d\x3f\x5e\xa0\x9c\xae\x22\xfe\x03\xb1\x10\x88\x01\x08\x3a\x5f\x01\x48\x33\x43\xcc\xf2\x34\x89\x54\xc2\x1c\xc3\xb8\xec\x8d\x4c\x79\x9a\xa6\x02\x9b\x2a\x16\x75\x4f\x1e\x9d\x50\x3c\xa6\x3d\x0b\xde\x1b\x3c\x4d\x05\x08\x5f\x08\x9c\x53\x69\xa6\x5f\xc7\xa2\x14\x43\x96\x2e\x85\xc4\x02\x1e\x98\x89\xf2\xdf\xf4\x57\x30\x0d\x28\x26\xbe\xd7\xd8\xd2\x3f\xac\xca\x59\xe5\x60\x7a\x72\x4e\x08\x36\x9a\xba\x60\x7c\xf0\x3b\x0d\x07\xd3\x08\xeb\x78\xb8\xf8\xb8\xda\xb2\x3f\x22\x2c\xc7\x3e\x71\xae\xab\x4d\x97\x27\x91\xee\xd5\xc6\x08\xfd\xa6\x9c\x5b\x7b\xf3\x34\x8b\x13\x5c\x84\x1e\x1f\x6e\xaf\xf6\x9b\xd5\xd3\xf6\x6a\xbf\xba\xbc\xeb\xab\xa8\xa9\xa4\x12\xd9\xc6\xe8\x12\x79\x21\xbb\xb8\xe3\xcf\x09\xdf\xf1\x54\x0a\x27\x3b\x6f\x65\x5e\x34\xd2\xf6\x5f\xa9\xe2\x5e\xce\x30\xa0\x71\xa7\x0b\x70\xaa\x94\x74\xd6\x46\x41\x41\xc9\x85\x45\xbb\xaa\xcb\x31\x3f\x99\x73\x3a\x12\x4c\x8c\xa8\xf2\x70\x71\xfa\xc0\xb5\x7d\x7a\x53\xb5\xd1\x08\xd5\xc2\x1a\xd2\xce\xf5\x34\x3c\xf2\x24\x5c\x9f\x86\x04\xcf\xb4\xae\x0e\xc7\xd3\x68\x12\x69\x10\x3c\xf6\x54\xfd\xbc\xe9\xcb\xc6\xa9\x06\xc7\x79\x6f\x46\x60\xa9\xcb\x3f\x81\x6b\xf4\x1f\x37\x59\x94\xaa\x69\xfc\xd7\xad\xa4\xd5\xa9\xf5\x96\x2f\xb3\x9b\x63\xa4\x63\xbc\xe9\xbe\x08\x31\x3d\x1f\x64\x80\x4d\xb6\x2e\x75\x5f\x3f\x6c\xa1\x28\xc6\xea\x51\x3c\x05\xc9\xd1\xf5\x60\xfd\x51\x9f\xfa\xdf\x6c\x23\xc6\xbd\xa7\x05\xca\xef\x2d\xbe\x16\x56\x12\xdc\x5d\xe1\x67\x5b\x4b\x24\xc8\xd6\xb5\xfc\xd8\x00\x4a\x07\x04\x7c\xc3\xe4\x62\x28\x61\x2e\xa6\xee\x36\x90\x01\x4c\xcd\x29\xe1\x14\x61\x39\x77\xd0\xd6\x55\x59\xf5\x8b\x2d\x8d\x45\x86\x29\x76\x89\x3b\xe6\x83\xbd\xab\x7a\xb7\x79\x4e\xe3\xcc\xa1\x42\xb0\x83\x76\x01\xad\xaf\xa2\x90\x80\xf6\xf8\xe4\x16\xd3\x58\x26\x48\x6f\xdf\xb6\xe6\xe9\xa6\x0c\x14\x80\x30\x27\x68\x42\x0d\xf6\x21\xf2\xe6\xa1\xd7\x06\xe4\x34\x8d\x54\xe2\xa7\xe9\x0e\xe4\xe1\x13\xfb\xa0\xe9\x12\x4a\x53\xe9\xd4\xbc\x1c\x2a\x75\xb6\xee\xd1\xd4\x90\xc4\x99\x79\xd4\x15\x92\xd1\xc2\x01\xca\x14\xee\x01\x79\xb3\x3d\x1d\xa1\x0e\x53\x72\xfa\xe4\x29\x97\x1a\xf3\x9c\xde\x17\x27\x78\x79\xce\xa2\x1c\xca\x2d\x31\x71\x5f\x77\x5a\x15\x45\x6f\x3d\xb9\x7c\x7f\x44\xec\xca\xe5\x38\x05\x9b\x56\xbe\xc2\xa4\x14\x4d\x85\xe0\x58\xb2\xf6\x82\x63\xfb\xab\xbf\xaf\xbf\xaf\xee\xbf\x5d\xed\x1f\x57\xbb\xab\x7e\x90\xca\x50\x00\x00\xe9\x55\x93\x9a\x0a\xcd\x12\x89\x05\xbb\xaa\x18\x5b\xfb\x73\x2a\x63\x89\x5c\xf4\x83\xcc\x1d\x76\x66\x71\xdd\xa4\x32\xb3\x58\xbe\xcc\x9b\xe6\x04\x5f\xc8\xac\x70\x2a\x95\x42\xa1\xbc\xcd\xed\x6a\xb7\xba\x7b\x78\x0a\x14\x4f\x4e\x15\x4d\x51\x37\x66\x65\xde\xba\x48\xcd\x78\xd8\x51\x7f\x98\xc7\x89\x1c\x20\x79\x09\x8b\xc3\x11\x1d\x39\x86\xe3\xac\x1f\x7f\xd1\xad\xbb\xa3\x14\x75\xfc\xa2\x50\x9d\x44\x28\x9d\x19\x64\xb6\x26\xd0\x20\x4e\x75\xea\x49\x5e\xd0\x7e\x87\xe2\x78\xe7\x7e\xd3\x46\xd6\xed\xdc\xf5\x8f\x53\x4d\x39\x52\x9a\xde\x91\xe5\x71\xb6\x7e\x53\x4d\x01\x0b\xa6\x7d\x64\xd0\xad\xcf\xdb\xdd\xc3\x6c\xea\x68\xee\x10\xba\x37\x87\x23\x48\xfd\xd2\x65\xec\xdd\xaa\x50\x9d\xc3\x12\xc2\x07\x64\x9a\x04\xdf\x38\x57\x59\xd9\xab\x8f\x7d\x5d\xbd\xcf\xa6\x9a\x49\x09\x4a\x04\x6f\x6f\xb6\xbf\x8f\xba\x3e\xd4\xd0\x0c\xbb\x01\xef\x55\x61\xe3\x09\xf4\x8b\x77\xa9\x03\x96\xbb\xb1\x7b\xd8\x3b\x26\x70\x0a\xa9\x8e\xdc\x6e\xda\x68\x59\x5f\x56\xfa\xd4\x5d\x67\xb5\xa9\xea\xa1\x85\xd8\xbf\xb4\xa0\x33\xac\xae\x04\xc9\xc4\xbb\x9b\xfb\x9b\xbb\xa7\xbb\xfd\xf5\xd3\xfd\xe5\xcd\xfd\xb7\x70\x4e\x6b\x22\x8c\x1c\x1a\x5c\x03\x6f\xc1\xb6\xab\xf6\x01\xe9\x08\x7e\x04\x8b\x00\x20\x19\x69\x80\x3a\x87\xbc\x9f\x1f\x13\xc2\x13\x67\xc4\x2b\x1c\x3f\xca\xf2\x75\xab\xab\x7a\x96\x34\xb0\x98\x3a\xb4\xce\x33\x3e\x25\xc4\xd5\xce\xbd\x48\x38\x4b\xd2\x04\xc6\x26\xf1\x58\xbe\x0d\xc7\xa8\x91\xe3\xe6\xd2\x3c\x0a\x0e\xc3\x20\xc1\xb8\xfb\xf6\xe1\xdb\xfe\x9f\x50\xbb\x2d\xd1\x1f\x63\x9e\x8d\xdb\x05\x70\x3f\x9d\x1b\x6b\x7f\x44\x82\xe8\xfd\xb7\xaf\xda\x97\xcd\xc0\xe8\x9a\x5e\x22\x93\xc0\x9c\xbb\x66\x0d\xe3\x34\x84\x71\x42\x70\x3b\xf7\xc6\xa9\x0e\x7f\xe6\xdc\x4e\x5d\x0e\x08\xfd\x75\xa0\x4a\x93\x0f\x7f\xe5\xfb\xdc\xb2\x9c\x33\xee\x7b\xe7\x58\xcb\x73\xc9\xc3\x63\xde\xcc\xc4\x69\xe3\x65\x3b\x0f\xce\x04\x89\x90\x68\x90\xeb\x8a\xdc\x0d\xcf\x51\x10\x67\xd9\x75\x07\x45\x55\x8e\x9d\x61\x39\x13\x89\x8d\x1c\xa6\xfe\xa6\xdc\xe5\x73\x81\x01\xce\x84\xd0\xb8\x65\x9e\x1a\xa8\x57\xe3\x95\x8f\x65\x14\x10\x15\x70\x77\x75\xbf\x7b\x78\xdc\xf6\x7f\x06\x23\xac\xef\x1f\xd7\xd5\xe1\xf1\xac\xd7\x37\xbb\x64\x19\x3b\x5d\xbf\x5e\xad\x0e\xb6\xdd\x14\xd0\xfd\x12\xc9\x64\x4a\xb1\xc5\x8b\x54\x48\x59\xdc\xc9\x16\x6a\x99\xcf\xee\x9b\xe4\x09\x8c\xa7\xc8\x55\xfb\xb2\xab\x10\xe0\xd9\xe4\xcf\xfd\x99\x24\x43\xba\x66\x17\x86\x7c\x97\xb5\x59\xcb\xe3\x44\xea\x86\x33\xc5\x9d\xbf\x5a\x0d\xd2\x7c\xec\xaa\xeb\x53\x61\x87\x6e\x36\xd3\x91\xc0\xf8\xc2\xe6\xa5\x2c\x3e\x82\xdc\x07\x67\x3a\xcd\x10\x03\x53\xc2\xbb\x63\xbd\x2f\x6f\x26\x4c\x67\xd6\x95\x8a\x40\x23\xf0\xf1\x33\x4f\x12\xce\x0c\xd7\x28\x07\xd4\xdd\xf6\x5d\x75\x7f\x3a\xac\x9d\x03\xd2\xe4\x45\x67\x10\xa5\x68\x49\x71\x0f\xef\x0b\xe2\x0f\x9c\x41\x2a\xd1\xcf\xf5\x11\x9b\x11\xb3\x3b\x06\x8c\x70\x4f\xcb\x0d\xfe\x0b\x58\xbb\x0f\x3f\xca\x42\x46\xb2\x10\x8b\xf6\x0d\x91\xe5\x35\x91\x47\x5a\x62\xe7\x75\x65\xcc\xc5\x6e\x3d\xea\x52\x77\x73\x00\x63\xa1\xa5\xde\xf1\xe8\xbf\x1c\x66\x2b\xac\xed\x3c\x8e\xe3\x00\xc5\xfa\xfd\x43\x2f\x14\x6f\x79\x0c\xca\xb9\x0d\xcb\xa2\xb8\x74\x05\xe7\xb5\x2c\x0a\x25\xf5\xeb\xe4\x26\xf0\x24\x75\x6c\x94\x67\x67\xf1\xb4\xc4\xe0\xe1\x3c\x81\xc8\x97\xae\x4d\x97\xf5\x03\x56\x2b\xcf\xcc\x56\xe7\x04\x7b\xce\xd3\x28\xc6\x0a\x8c\xa3\xeb\x3d\x58\x8b\x2d\xca\xa7\x63\x51\xc9\x4f\xb4\xd7\x78\x97\x58\x60\xc9\xf1\x6e\x75\x73\xbf\x5f\x3f\xdc\xdc\xef\x37\x5d\xe0\xb0\xfb\x7e\xf5\x38\xb0\xcf\x39\x4f\xc1\x15\x2c\xbd\x82\xe2\x37\xf9\xc9\xce\xce\x29\x71\x8a\xa6\x4e\x19\xce\x41\xf4\xe7\xdd\x43\x4e\x63\x07\x91\xb5\xc5\xa9\x79\xb9\x7a\x5c\xc7\xd1\xec\xaa\x18\xd7\x58\x49\x5d\x3f\xfe\x63\xb3\x7b\xf8\xe7\xc3\xed\x78\x85\xe3\x0c\x0c\xca\x84\xad\xca\x67\xf0\x91\xb8\xaf\x32\x7d\x19\xf4\x71\x1e\x13\x8c\xa8\x5d\x12\x3b\xd0\x75\xfb\x6a\x19\xe7\x49\x82\xbb\x78\x21\x1b\x07\x26\xda\xc8\x40\x9c\xe2\x9c\x6b\x62\xd3\x20\x7d\x56\xbd\x97\xe0\x82\xa4\x9b\xf2\xea\x13\x7e\x0c\xe7\xdc\x28\x6c\x17\x5e\x79\xbd\x13\xd7\xaa\xc1\x6d\xeb\xba\xaa\xbb\xff\x7b\x70\xcb\xc2\x42\x4f\x8e\x8b\xc8\x49\xd8\x7a\xa3\x55\xdc\x85\x7d\x6f\xb7\xdb\xe3\xf3\x33\xe7\x44\xce\x05\x33\x89\xef\xfa\xcc\x95\xa4\xbb\x83\x16\x9d\x93\xbf\x3f\x5c\xde\x86\xdf\x24\x24\xc5\xa9\x56\xd5\x06\x6a\x57\x34\xee\xf6\x87\xc9\x9b\xcd\x85\xb1\x4a\x0c\xb4\xa1\xf3\x76\x30\xcf\x32\x83\xe2\x04\xdd\x7d\x0b\xa7\xce\xac\x73\x4c\x41\x3b\xc1\xb2\xed\x95\xf7\xc6\xfd\xa7\xe1\x0c\x32\x02\x95\x0c\xad\xca\xd6\xc1\x6c\x02\xe5\xe9\xdf\xb3\xfb\x2a\x79\x14\xdc\xa6\xd6\xb2\x7c\x93\x8d\x2b\x15\x8f\xb3\x05\x2e\x8d\xc2\xb4\x1c\x9e\x9f\xbb\xe7\xfc\xda\x2f\x26\x5c\x5a\x8e\x2b\x9f\xcd\xeb\xa6\xdb\x66\x27\x5b\x09\x57\x46\x62\x3e\xf1\xdf\xb2\x25\xd1\xeb\xf0\x57\x23\x65\xf0\xaa\xfe\x02\x80\xc1\xb5\x71\xf4\x3a\x57\xf9\xfd\x55\x95\x35\x7c\x08\x62\xb7\x7e\x54\xcd\x39\xfe\x74\xce\x25\xe5\xdc\xa4\x8e\xfd\xfb\x96\xc3\xbb\x67\x41\x3a\x75\xf9\xe6\xa6\xbc\x9b\xc5\xe8\xe1\x23\x4c\x63\xf1\x6b\x0f\x87\xbc\xbd\xa8\xba\xfd\xc6\x75\xac\xe6\x00\xa2\x5f\x16\xed\xfa\xf1\xc3\x6b\x03\x52\x61\x91\xb9\x95\x3f\x0f\x7d\x63\x85\x5b\x48\x81\xf5\xd8\xe2\x9d\x6c\x5e\x67\xcf\xdc\x5a\x12\x47\xa1\x5f\xf2\x0a\xf3\x56\xc7\xf4\x1e\x89\x28\x81\x8c\x0f\x78\xac\x91\xf0\x03\x17\x11\x48\xc4\xc2\xbf\x43\xfb\x32\x4b\xe6\xba\x28\x04\x35\x65\x6e\x77\xff\xe8\xff\xc4\x5c\x82\x7c\x75\x7c\xa9\xab\x72\x07\x4d\x3b\x71\x93\x9c\xff\xfb\xb9\x7b\x11\x17\xb1\x65\x76\x68\xb1\x8f\xad\x88\xb9\x48\x74\x82\x70\xb7\xc3\x74\xe7\x17\x94\x27\x5a\x06\x08\x64\x5e\x06\x62\x78\x38\x2a\x34\xd2\x9c\x6c\x20\x6f\xf8\x55\x34\x1c\x67\x51\x86\xfc\xce\x43\xee\xbd\x0d\x9a\xdf\xfe\x4c\xd9\x54\x30\xed\xec\xc7\xf6\xa1\x55\xe2\xcb\x0d\x7f\xaa\xfa\x21\x78\xac\xf0\x8d\x3b\x95\x0d\xc8\x62\x6e\x39\x74\x06\x05\x12\x9c\x12\x4c\xd4\xda\x65\x8d\x39\x2e\x38\x38\xd1\x4c\x2d\x0b\xfd\xb7\x53\xae\x5f\x37\x75\x75\xa8\x1c\xff\x6a\xfa\xd5\x22\xb1\xb8\x90\x1c\x5d\xcb\x33\xdd\x17\x27\xfd\xfa\xa1\x4e\x1f\xbb\xc9\x6b\x2d\x84\x96\x41\xc8\x20\xcc\x81\x9b\x7e\x86\x64\x52\x82\x1d\xf5\x2f\x2e\x87\xf4\x56\x48\xc9\x9c\xd9\x48\x29\x03\x87\xe4\x69\x0e\x58\xe6\x42\x42\x86\x51\xc5\xb1\x90\x1f\xbb\x6a\x04\x7d\xf7\xc7\x55\x6c\xb1\x2a\xdb\xd6\x39\x38\x61\xa9\x33\x1d\xeb\xd9\x3d\x52\x46\x43\xe0\xb2\xf7\xea\xd8\x0d\x06\xdb\x8b\xed\x75\xa1\xd3\x38\xe9\x96\xd9\xa3\x6f\x95\xed\x0f\x8f\xc8\xe5\xd8\x14\x9e\x25\xbf\xb8\xb6\x0a\x9d\x3a\xf4\x1e\xca\x65\x61\xb9\x38\x1c\x30\x51\xe2\x97\x51\x44\xde\x2d\xc1\x30\x84\x89\x5d\x31\xe4\xe8\x61\x31\xcd\xc5\xc7\x48\xd1\x35\x9c\xca\x28\x1e\xb0\x3e\xdd\x37\xe0\xa3\x41\x23\xd2\x1e\xba\x30\x3d\x2b\xc4\x0e\x35\x87\xd7\xb4\x72\x7d\xb1\xe9\xdd\x01\x6e\xf8\x14\x20\xdb\x85\x55\x7f\xad\x54\xff\xa6\xd8\x88\x63\xee\xfb\x57\x79\x90\xed\x28\x40\x10\x96\x67\x08\x10\x45\x0c\x63\x33\xc9\x31\x84\xe5\x8a\xc6\xa3\x5a\xc6\x5d\x5e\x7a\xc5\xd5\x9e\xbc\xda\x0d\x02\x7c\x43\xd7\xe5\xc7\x18\x23\x99\x91\xc4\x60\x52\xd7\xb4\xb2\xcd\x35\x86\x92\xce\x50\xda\x3d\xf0\x33\x06\x33\xcf\xe2\xc4\xc1\x47\xf6\xd2\x98\xde\x7e\x6c\xf0\x95\x9d\xce\xb1\x2c\x4e\x29\x32\xf2\xf6\x13\x9d\xb5\xe6\x25\x3f\x2e\x2f\x8a\x59\x12\x11\xd4\x6a\x6d\x5a\xf9\x0c\xb7\x30\x12\x07\xed\x8e\x51\x6c\x58\xbf\xc8\xe6\x25\x74\xe4\x82\xae\x3c\x2a\x93\xfc\x2b\xfe\x77\x28\xc8\x85\x8f\xd0\x08\xd1\xa5\xee\x4a\xa7\x30\x7c\x9e\x25\x1a\x30\x58\x08\xfd\xfb\x5e\xce\x68\xec\xdd\xc3\xb3\x54\xf0\x90\xa8\xaf\xe5\x04\xa5\xce\x33\xca\x52\x13\x50\x0e\x4d\x53\xe9\xbc\xdb\x82\x76\xab\x07\xaf\x32\x35\xf6\x22\x9f\xcc\x86\x8c\x4a\xed\x68\x3b\x2e\x87\x9d\x89\xe4\xfa\x41\x2c\xd1\x58\xb8\xef\xe2\xd8\xab\x9b\xa7\xbb\x70\x45\x8c\x39\xd1\x9f\xe6\x28\x0f\xe1\x6f\xdc\xf8\x1f\xe3\x48\x99\xde\xaf\xbb\x34\x5b\x0f\x09\x7f\xf2\x29\xc6\x9f\xea\x49\x65\xdc\xc6\xc1\x0d\xe3\xb6\x7a\x9e\x3d\x55\x91\xa4\x7a\xdc\x30\x7f\x44\xa4\xd7\xd8\x9f\x49\xfc\x8b\xa4\xff\x9e\x74\x90\x33\x21\x63\xbc\x8b\x45\x7e\xa8\xea\x5c\x07\x18\x4d\x96\xc5\x0a\x3b\xa3\x97\xdb\xdd\xde\xcb\x46\x85\x43\x32\x95\xe0\xea\x6f\xdb\xef\xab\x98\xb2\xef\xb2\x79\x79\xf4\xc8\xa6\x79\x50\x97\x49\x6a\x68\x40\xfe\x77\x6b\x62\x0f\x38\xd8\x56\xa7\x7a\x42\x7d\x0c\x1f\x30\xa9\x1e\x22\xb4\xdb\xdc\x29\x72\x4e\x6f\x83\xf2\x26\xa4\xeb\x0f\x05\xf5\x7a\xa8\x23\x67\x4a\x26\xd2\x93\x43\x1b\x67\x3e\x3e\x86\xa4\x67\x4a\x72\x09\x3d\x0d\xb9\x99\xa3\x6c\x32\x13\x67\x18\x7a\x5f\xe4\x1f\xa7\x02\x26\x9b\xf5\x42\xc2\x9a\x41\x9c\x06\x33\xb2\x7b\x78\x77\x55\xda\x75\x75\x08\x14\x9d\xe9\x35\x43\xe2\xd6\xf5\x67\x68\x2f\xdc\x2c\xdc\xb6\xb2\x69\x73\xdd\x4f\x68\x10\xa9\xd3\xfe\x2d\xe4\x87\x7b\xd1\xc3\x01\x13\x87\x2e\xf5\xdd\xc7\x37\x44\x34\x85\x42\xef\x62\x76\x94\x59\x61\xb0\x63\xdd\xbe\xd4\x00\xdf\xab\x16\x6d\x1f\x2f\x4f\x63\x9f\x02\x9e\x59\xc5\xc5\x88\x2e\x1c\xb8\xa8\x7f\xc8\xbc\xbb\xb8\x11\x7b\x38\x3c\x1a\x19\x89\xcc\x51\x6f\xbd\x62\xfd\xd7\x00\x0e\x19\x59\x83\xae\x4a\xcd\x4b\x0e\x85\x69\x9e\x3c\x37\x83\x4b\x42\x2c\x0a\x77\x14\x37\xbf\x5f\xa1\x12\xd9\x57\x77\x59\x12\x19\xa3\xda\xd6\xa9\x31\xf3\xca\x92\x8c\x09\xe3\x99\x67\xc7\xfe\x0e\x1f\xe7\xea\x71\x93\xc9\x28\x63\x02\xd8\x4d\x50\x27\xb7\xb7\x74\x2b\xe4\x74\x0a\xc8\x38\xd6\x58\x3e\x30\xf0\xb6\x0e\xfe\x0f\x83\xdb\xc0\xf4\x07\x26\xa9\xd2\x6a\xd4\xd6\xbf\x93\x3f\x9d\xb2\xe9\xe2\xcb\x2b\x13\x26\x11\x4a\x88\x65\xf5\x6b\x80\xeb\xa2\x7a\x0f\x0f\x5f\xa6\xb1\xc5\x70\x4b\x9d\x3e\xf6\xcd\x50\x1c\x96\x34\x4a\x99\xf3\xd8\xf8\xfd\x1f\xeb\x47\xf8\xef\x29\xaf\xc1\xec\xaa\x47\xd0\x90\xbf\x8d\x79\x47\x5c\x52\x45\x30\xb7\x91\xc6\x04\x8f\x94\x2f\x73\x08\xc9\x52\x8b\xe8\xb6\xee\xda\x67\x8e\xff\x61\x04\x53\x48\x60\x91\x06\x49\xfb\x57\xa5\xa9\xea\x06\xc6\x9e\xdf\x63\x0d\xc6\xe9\x73\x63\x42\xa3\x8e\xc8\xd5\xc3\xf6\x02\xda\x51\x20\x24\x59\x46\xb0\xde\x77\x0f\xef\xe8\x35\xd3\x3d\x0b\x04\x88\xfb\x88\xfa\x13\x95\x96\x45\x7e\xef\xf4\x2b\x33\x83\x77\xf8\x07\x3c\xc3\xa2\x6d\xe2\x79\x5b\x52\x32\x60\x51\xd0\xd4\xee\x3d\x7b\x26\xfd\x0a\xc9\xa5\xc4\xdd\x64\xff\x06\x0b\x79\xd3\x79\xa2\x22\x45\x1c\x51\x3b\x28\xc8\xfc\x01\xf9\x98\x4e\xca\x65\x16\x25\x01\xcc\xb9\x96\xc7\x2b\x5d\x35\x68\x1c\xdf\x1f\x16\x60\xe2\x91\x08\xe6\x35\xaa\xa9\x9e\x27\x6c\xc3\x17\x66\x59\xcc\x7c\xcd\xe0\xe2\xdd\x03\x88\x50\x24\x64\xdd\x05\x25\xf3\x39\x9e\x59\xe3\xa0\xc0\x95\x9a\x1d\x91\xdc\x3d\xb3\x6e\xf1\xac\xaa\x62\x6c\xa4\xc1\xa5\xb4\x29\x04\xe6\x59\xfb\x50\x18\xb7\x8b\xdd\xc3\xfb\x65\xde\xe0\xe4\xe9\x27\xfe\x39\x57\x42\x2a\x2a\xb0\x56\xe9\x84\x12\xf3\xaa\x5c\x95\x66\x7d\x6a\x1f\xac\x0d\xa7\xd7\x3c\x42\x22\x0c\x1a\xea\x4d\x5b\x24\xd2\x24\x19\xf3\xfb\xde\xb5\x93\x26\x7f\x3c\x15\xe7\x50\xe7\x5f\xfd\xeb\xcf\x06\xc0\x10\x09\x71\x79\xf3\xc7\xf2\x02\x2a\xc1\x46\xd8\x62\x52\x88\xf3\xe9\xef\x80\xcd\x68\xda\x4b\x65\x8e\x40\x73\xfd\xe1\xcc\x09\x07\xc9\x53\x03\x01\x92\x3d\x1c\x95\x29\x0c\x6e\xaa\xfb\x63\x0d\xfb\x5c\x57\x8e\xbe\x36\x5d\x58\x54\x9c\x3a\xfa\xea\xad\x7c\x93\x3e\xac\x9c\x3c\x27\x15\xf3\x18\x1d\x39\xf0\xc3\x53\x95\xfd\x7e\x84\xc2\x34\xe1\x54\xaa\xde\xb1\xea\x17\xf8\x74\x15\x73\x8b\x9e\x50\x2d\x34\xed\x4d\x13\x36\x19\x7f\xfd\x2a\x91\xd6\x79\x9f\x9f\x4a\xd3\x2b\x57\xfa\x63\x69\xa4\xb0\x8d\xae\x9c\x88\xe1\x44\x6f\x6e\x32\x8e\x13\x47\xb4\x92\xaf\xb0\xae\xaa\xd7\x7c\x5a\xbc\x55\x29\xc4\x3c\x1e\xa8\x7f\x17\xe7\xac\x99\xe5\x95\x5d\xa5\x36\x43\x7b\x16\x2d\xcb\x2e\x61\x0d\xd7\x4c\xa9\x93\x61\x3e\xba\x90\xb5\xf7\x3d\x0a\x58\xe5\x7e\x9c\xd4\x41\x4f\x30\xc0\xf2\x83\xe9\x86\x59\x9d\x19\x41\x87\x0f\x19\x43\x53\x8f\xf6\xe8\xc5\x9d\xfd\x31\x16\x01\x3e\xa0\x5e\xc7\xe2\x5b\x2d\xcb\x60\x72\xd5\x0f\x4a\x41\x79\x7d\x69\xa7\xeb\xb9\xb8\x4c\x2b\x26\x15\xea\x7b\x9e\xbb\x8e\x2d\x57\x0d\xc2\xcd\xe6\x24\x45\x62\x54\x23\x2d\x6c\x4f\xaa\xad\xff\xf9\xd7\xeb\xe5\xad\x49\xf1\x58\x05\xdf\x52\x03\xc7\xf6\xe0\xa8\xb8\x2f\xf9\xb1\x99\xca\x29\x4d\x2f\x8c\x67\xae\x84\x55\xf7\x01\x7a\xd0\x48\x0e\x2b\x5d\x37\x24\x75\x34\xca\xd2\xd9\xc5\x4e\xbf\x57\xc4\x0a\x57\x85\xeb\xa7\xdd\xd3\xe3\xea\xef\xe1\x53\x22\xa5\x63\xa9\xac\x16\xf6\x49\xd4\x1f\xe3\x80\x84\xec\x6f\xd0\x76\x2b\x04\x42\xbf\xc7\xbf\x5a\xa8\x24\x72\xf8\x89\x09\x06\x4f\x65\x34\x52\x3e\x58\xfb\xa3\xaa\x5f\xa1\xbe\x6c\x37\xd5\xd9\x9b\x97\x89\x4c\x5a\xa4\x2b\x3f\x7a\xae\x58\xff\x79\xa1\x51\xa7\xea\xf1\xf2\x8f\x71\x95\x58\x49\x46\x83\x14\xfe\x6f\x23\xef\x03\xae\xa4\x95\x22\xee\x45\x8b\x70\x7f\x9b\xbe\x50\x2a\x62\xc4\x19\x49\xa0\x9b\xa0\x6c\xe1\x33\xa4\x5b\xf8\x00\x71\x3a\x1e\x5d\xbc\x81\x8d\xa6\x55\x69\x76\xd5\x44\xe0\x78\xf6\x5c\x15\x71\xe4\x74\xed\xb0\x2b\x4b\x51\x8c\x52\x22\x43\x47\x46\x5f\x76\x9d\x1f\x95\x91\x53\xf4\x2d\xc3\x45\x6e\xa1\xb0\xfd\x4f\x00\x47\xe6\x0b\x24\x8c\xbb\x7e\xe2\x84\x11\x9a\x58\xec\x83\xf6\x52\xaa\xae\x1c\x34\x93\xa8\xe5\x4a\x27\x80\x55\xe3\xee\xed\xf5\x44\xb2\x4f\x89\x77\x4a\xf3\x28\x1b\x72\x04\xb4\xe5\x9c\xed\x71\xca\x48\xc6\x06\x55\xe3\xd5\xdd\xcd\x76\x3e\x40\x71\x8c\xf5\x43\x0a\xec\xfb\x29\xee\x19\xc6\x51\x18\xa5\x05\x92\x58\x2b\xcf\x5a\xde\xa3\x3a\xc3\x6f\x63\xf4\xd7\xbf\xe8\xac\x6c\xac\x0c\x38\x42\xfc\x33\xf8\xf6\xd2\x13\x9e\xda\xad\x10\xe3\xea\x94\x02\x42\xa4\x27\x3c\x62\x96\x7f\xd3\x45\x01\x8b\x40\xea\xd9\x57\x00\x57\x08\x61\xb1\x55\x7d\x38\x15\x72\x53\x83\x76\xc8\x29\x7f\xdc\x76\x49\x7e\x97\x21\x15\x32\x3f\x6c\xbf\xdf\xec\x96\x37\x3a\x1d\x51\x1d\xbb\x32\x45\xd3\x6c\x7d\x5e\x3f\x0b\xfb\x75\x04\x12\x37\xdf\xbd\xa7\x82\x2e\x9f\x89\x24\x51\xe2\x20\x3c\xd0\x36\x0f\x65\x98\xe5\x9a\xa4\x4e\x40\x61\xd0\x2d\xf2\x70\xf6\xdb\x5e\x22\x88\x6b\xc2\x95\x0c\x6c\x6d\x97\xaf\x5e\xc2\xcf\x73\x28\xae\x26\x8a\x6a\x8f\x4b\xfa\xf6\xed\x2a\x50\xc7\x45\x38\xaa\xa5\xb5\x33\x0b\xf6\x07\xbb\x5f\x20\x8d\xea\x38\x51\xd6\x9f\xe8\x38\x21\xa3\x7c\xa5\x33\xc9\x75\x42\x08\x16\x2e\x1e\x8e\x67\x28\x46\x9d\x50\x87\x6d\xea\x8b\x7b\x5f\xef\xb6\x3a\x01\x65\x1d\xc8\x67\xef\x55\x32\xf7\x83\x17\x29\xd7\x69\x4c\x5c\x81\xdf\x75\xd9\xba\xf9\x37\xbf\x1b\x94\x38\xa8\xe8\x8f\xbc\xc9\x55\x5e\xe4\xed\xc7\x25\x1c\x42\x06\xaf\x29\x8d\x52\x3a\xb1\x92\x0f\xa4\xb5\x11\x7e\x89\x7c\xf2\x34\x19\x23\x69\x34\xdd\x10\x27\xa9\x4d\x18\x06\x1a\xb7\x39\xa7\xd6\xe9\x54\xb5\xe6\xa2\xec\x5c\xf3\xc8\xb1\x2d\xbc\xd8\xe5\xbc\xd4\xb1\xc4\x0f\xd4\xdc\xfb\x91\xe6\x65\xde\x5e\xb5\x2f\x97\x30\x98\x99\x4c\x35\x2f\xe2\xe8\x2f\x93\x57\x56\x73\x60\x41\xc1\x1a\x51\x8a\x1b\xa9\x5f\xc7\x54\x22\x3f\x4c\x10\x96\xf9\xbe\xd1\xf2\xa3\xef\xc7\x59\x7c\x43\x76\xbb\xdd\xaf\xb3\x09\x2d\x52\x81\x41\xde\xbe\xad\x36\xfa\x93\x55\x59\x0b\xea\x84\xba\x1a\x68\xcf\xcc\xc2\x16\x43\x00\x2d\x38\x47\x5e\x57\xdd\x20\x9f\xfb\x63\x53\xe5\x9f\xad\xf9\x5a\x68\xcd\xb2\x49\x8f\x7b\x77\x79\x35\x12\x1c\xe3\x5a\x80\x95\x48\x0c\x96\x87\xe0\xe9\xc4\x75\x96\x44\x88\x5d\x85\x5a\xc7\xd1\xdd\xe3\xed\xe4\xcd\xca\x04\x8d\x49\x5f\x38\xd9\xbd\x80\xd3\x45\x9d\x8e\xb1\x59\x90\xaf\xbb\x87\x9f\xa8\xc8\xe0\x05\x7a\xfe\x5a\xcd\x3b\xd9\x5a\x12\x16\xa4\x97\xef\x9c\xc2\x02\xae\x54\xd8\xe9\xec\xd2\xa5\xcd\xec\x69\x49\x2e\x8c\x0b\xad\xb1\x20\x77\x2d\x8b\xe2\x62\xee\x5f\x3c\x1a\x6d\x20\x56\xbd\xd7\x05\x46\x72\x41\x93\x41\x77\x49\x32\x0d\x15\xe4\xbc\xf8\xf0\xfe\xa8\x93\xa6\x9e\x56\x5d\xfa\xda\xbd\x3b\xf9\x01\xce\x2c\x49\xb9\x56\x3a\x45\xc3\xc6\xef\xb2\xb9\xaf\xbc\x4e\x5c\x38\xbf\xd6\x12\x43\xdc\xd2\xf6\x7f\x32\x89\xc5\xb2\x83\xdb\xae\x42\x90\x34\xf6\x53\x0b\x03\x25\x75\xfa\xa9\x75\xae\x02\xf5\xaa\x7f\x6a\x10\x39\xc3\xa0\x7b\x78\xdf\xc8\xa6\x99\x91\x96\xbe\xd4\xf9\xe5\xda\x32\x8b\x3e\xd0\x79\xf3\x03\xbd\xf8\x1c\x26\x36\x9c\xda\x72\x20\xc6\x37\x49\x2e\xab\x93\x2a\xe0\x22\x2f\x0d\x98\x8b\x22\x77\x7a\x0d\x31\x65\x73\xf7\xa8\xd9\xf9\x95\xc4\xdd\xf4\xf2\xee\x72\xd3\xad\x57\xa1\xf6\x6f\x22\xc2\xb0\x55\x8c\xea\x0f\x0f\x76\x5d\x1d\x0e\xa7\x32\xef\x69\xe2\x26\x4a\x35\x27\x81\x04\xe6\x5e\x81\xf1\x0e\x69\x22\x63\xb0\x6c\xb6\x7e\xd8\xdc\xf8\x9e\xca\x57\xd5\x22\x43\xa2\x94\xda\x50\x93\xfb\xd9\x6e\xc1\xab\xf6\x4e\x1e\xa0\x21\x09\xd7\xce\xce\xd7\x2f\x5a\xe1\xef\x86\x24\xde\x76\x6c\x93\xff\x84\x62\x5d\x15\xd5\x14\xd8\x12\xa6\x88\x89\x23\x27\x9e\x8b\x25\xf1\xf0\x90\x4c\x2c\x32\x99\x05\xcd\x88\xe3\x5a\xd6\x93\xa0\xdd\x0f\x4a\x04\xc5\x9a\x0e\x62\xa1\x36\xd5\xbc\xe0\xd1\x8f\x72\xb7\xf4\x5e\xde\x57\x1e\x06\x34\x0e\x3c\x4d\x62\x00\xa1\x76\x3e\x9f\x99\xb4\x34\x67\x67\x02\xe3\x1c\x6e\xe0\xfd\x72\xa2\xa9\xf2\x49\xa0\x69\x52\x12\x61\x37\x61\x5d\x7f\x1c\xdb\x6a\x2b\x9f\xe5\xaa\x86\x52\xce\xec\x07\x4f\x33\x85\x23\x6e\xd2\x58\xe3\x3d\xf1\x65\x73\x57\x3e\x08\x8c\x97\x4f\xbe\x8b\xc6\x46\xb0\xa0\xfa\x81\x78\x9e\x71\xed\xd3\xd0\xd4\x6d\xd4\xd6\x7b\xcb\xae\xfa\x99\x41\x0d\xc5\x0d\xf2\xea\x71\xcd\x63\x82\xb7\xe6\xae\xea\x81\x30\xd3\x59\xc1\xb2\x08\xc3\xb8\x22\x3f\xe4\xe8\xea\x8d\xc8\xec\x3f\xe4\x5b\xbf\xfe\x19\xa6\x8d\x8b\x72\xa4\x5b\xb4\x26\xa9\x9a\xe1\x91\x45\x48\x58\xae\xab\xab\xd2\x79\x58\x86\x43\x82\x38\x1f\x3b\x75\xfa\xc0\x25\x69\x71\x55\x36\x22\x21\x9e\x28\x5b\x3a\x4e\xc0\x27\xfd\xef\x30\x3c\x55\x48\xbc\x43\xd8\xc6\x36\x7f\xde\xb6\x27\x75\x1e\x10\x87\xc1\x56\x63\xe1\x0f\xc2\x66\xb2\x85\x76\x85\xe0\xfc\x11\xa3\x61\x7a\xd7\x33\x01\x78\x43\xfe\xf6\xb4\xda\xde\x84\x5f\x92\x29\xa7\xab\x70\xfd\x77\x57\x95\xf5\x7f\x96\x84\xd0\xc1\xc0\xea\x6a\xf7\x3d\x5e\xe0\xad\x18\x69\xa3\xcc\xb9\x47\xb7\x2f\x93\x79\xaa\x22\x19\xbb\x34\xf9\xc3\x29\x4c\x35\xab\xd2\x6c\xc7\x94\xa4\x49\xa5\xe0\x93\x1b\x62\x12\x27\x8a\xfc\x03\xea\xd3\x61\x72\x7e\x43\x09\x76\x2b\xaf\x36\xdb\x8b\xa1\xbf\xdd\xfd\xd9\xc1\xf3\xfb\xb4\x7a\x2d\x8f\xfd\x41\x45\x18\xf5\x18\x95\x9b\x5d\xff\x57\x2b\xb8\x6f\x3c\x75\xbb\x57\xd8\x19\xfc\x51\x88\x78\xea\xa3\xcb\xfb\xca\xcc\x43\x21\x03\x89\xc2\x15\x56\x1a\xe3\x01\x2e\x21\x62\x99\xdd\x7a\x4b\x34\xce\x68\xdd\x7d\x0d\x6a\x64\x07\xf2\xfe\xa7\x54\x11\x88\x0c\x4d\xe5\x60\x70\xec\x54\x1b\xc2\x4f\x05\x12\x3b\x70\x15\xc8\xba\xf8\xb8\xc8\x6b\x57\x8b\x78\xec\x35\xbc\x39\x10\x4e\xb0\xc8\xb9\x79\xbc\xf9\xe7\x95\x77\xff\x18\x8e\x25\xa9\xb7\xd0\x0c\x0c\x83\xe9\x97\x13\x43\xa9\x8f\x05\xbf\xc9\xc3\x90\x71\x0f\x23\xe2\xc8\x51\x53\x8e\x55\x3e\x2f\x21\x43\xcc\x84\x30\x63\x2f\xb2\x31\xfb\x00\x62\x4e\x94\x0f\x1a\xfe\x00\x78\x2d\x3e\xbc\x32\xc3\x46\xd6\x6d\xae\xf3\xa3\x2c\xe7\x84\x06\x88\x25\xc3\x75\xef\x1b\xb4\x5b\x28\x8a\xd0\x17\xf4\x56\x25\x61\x90\xca\x50\x6e\xb5\x77\x3c\x59\x3f\xdc\x6d\x56\xf7\xff\xd8\x3f\xdd\xdf\x3e\xac\x7f\xdf\xaf\x76\xfd\x48\xe3\xbc\x4a\xfe\x07\x75\x75\xd3\xbf\xf0\x90\x46\x14\xfb\x56\x25\xfc\x9c\xc8\x1a\x41\xca\x04\x42\xd4\xda\x6a\x8b\xb3\xb7\xff\xbb\x31\x36\xee\x13\x4e\xef\xc7\xb6\xb8\x16\x40\xea\x0d\x63\x6f\xee\xaf\x6f\x6f\x7e\x84\x13\x50\x62\x12\xd1\xe3\x0a\x6c\xfe\xdc\x0c\xb8\xa4\x30\x84\x27\x98\x24\x07\xbc\xf0\x10\xd2\xff\x9e\x97\xcf\xdd\xfe\x79\x4e\x51\xfe\x8c\x34\xf7\x29\xde\x66\x00\x00\x01\xcd\x08\x52\x70\x83\xd2\xc9\x57\x60\x7b\xa0\x0a\x74\x12\xd8\x18\x63\xcd\x9e\xe9\x30\x16\xc5\x89\xaf\xc3\xdc\xac\x1f\xe4\xc8\x55\x7c\x94\x9f\x01\x8b\x89\x72\x8e\xb2\xd8\xdf\x1f\xbf\xf0\xc0\xb2\x18\x5f\xc4\x46\x76\x81\x44\x37\xcd\xe7\xcc\x0a\xe0\x69\x8a\x34\xa5\x02\x64\x97\xd2\x7e\x93\xc3\x73\xea\x12\x67\x24\x5d\x74\x0f\xd5\xb3\x42\x67\xea\x61\x1c\x38\xd8\x38\x1d\xea\x90\x9f\xfc\x62\x41\x74\x88\x35\x2e\x4e\x79\x61\xc6\x3d\x8c\xe9\x4b\x20\xb8\xf3\x9b\x3c\xc8\x9f\x5b\x59\xc0\x14\x00\x0f\x19\x4b\x30\xc6\xf1\xdb\x66\xaf\x30\x7a\x66\xc3\x37\xfb\xfe\x2c\x8b\x11\x57\x61\xaa\x47\x50\xa7\xfe\x9d\x92\x24\x31\xfe\xb2\x7c\x02\x80\xed\xfd\x6b\x80\x45\xdc\x06\x48\xad\x9d\x34\xb1\x6c\x01\xb1\x8e\xfd\x89\x2c\x58\x1d\x30\x0c\x41\x65\x2d\x1c\x54\x82\xd9\xc1\x99\xdd\x51\x16\xc6\xba\x68\xcb\x19\x34\x68\xe1\x56\xeb\xde\x9f\x2f\x6f\x5f\x6e\xab\xf3\x48\x7e\x12\x6c\x81\x16\x46\x38\xf2\x7c\xbb\xad\x74\x2e\x0b\xdf\xae\xda\xbc\x7f\xe6\x69\xd3\x7f\x10\x30\x71\x51\xfd\x75\x6b\xc5\x70\xe9\x6f\x83\xdd\xb8\xff\xbb\x89\x08\x89\x27\xc6\xd0\xd7\x08\x84\xb4\x50\xcf\x0c\x9c\x39\x40\x94\x60\x51\x0b\x11\x65\x58\x54\x3e\x27\xdf\x03\x44\x12\xf3\xb0\xb9\x4c\xd0\x4d\xe9\x50\x9a\x9f\x4c\x2a\x88\x33\x84\xee\xae\x1f\x6e\xee\xb7\x01\x25\x1b\x2e\x12\x14\xa7\xbd\x08\xf4\x1d\xb4\x2f\x95\x59\x5d\xdc\xf4\x47\x8d\xb3\xc1\x6f\xa1\x69\xf7\xb6\x3a\xd5\x37\x25\xe2\x63\xaf\x65\xd1\xc0\xd5\x7f\x6f\xab\xfe\x25\x00\xeb\xe8\xda\x48\xa1\x79\x2a\x9b\xd0\x73\x09\xc7\x6d\x44\xa4\x93\x59\x2b\xa0\x85\x47\x78\x3e\x7f\x8f\x2d\xa5\x88\x51\xe9\xb6\xf5\xaa\xfe\xc5\x63\xb7\x51\xe2\xcc\xa4\xbb\x5d\xc0\x23\x96\x43\x13\x39\x8c\xe0\x4e\x22\x74\xfd\x22\x51\x84\x77\x7c\x3d\x96\x18\x97\xfe\x1d\xf2\xd2\xbf\x3b\xd7\x55\xed\xe7\x40\xd8\x06\x6d\xcc\x53\x11\xf0\x6e\xf9\x4f\xa8\x77\x1f\x47\x18\x0e\x0a\x17\xdb\x78\xbd\xe8\xaf\x48\xee\x93\xc7\x68\x13\xc3\xf1\x59\x23\x49\xf3\xf9\x34\xfb\xa5\x67\xa4\x84\x4f\x7e\x7f\x62\x0c\x0a\xdf\x78\xe4\xc1\xaf\xc4\xa1\xfc\xa7\xd2\x28\x49\x65\xb0\x59\xcd\xdb\xbf\x4a\x03\xdb\x16\x64\xb7\xe7\xdd\x94\x6e\x56\xfd\xa2\xa7\x63\x29\x73\xf6\x27\xcf\xd0\x6e\x65\x79\x83\xb1\x27\x56\x43\xc6\xf1\xb1\xa5\x5c\x25\xae\x56\x3d\x5e\x46\x2d\x23\x12\xb5\x01\xbe\x4b\x95\x0f\xf7\x99\x31\x9e\x05\x3c\xe5\x4b\xb7\x03\x2e\x9a\xe3\x4c\x5f\x44\xcb\x98\xd3\x1d\x51\xd0\xb4\x08\xc1\x3b\xb5\xce\xc1\xab\x3f\x2b\x07\xd9\xab\xb9\xa3\x20\x2b\xae\x26\x4b\xa9\x91\xe5\x24\x92\x41\x97\x66\xd0\x9b\x0a\x07\xa5\x65\x2e\xd2\x96\x85\x19\x62\x20\xcb\x55\x82\xbc\x79\x44\x6b\xf9\x06\xf9\x2c\xb6\xb0\x5d\xea\x33\x76\x35\x9e\x64\x87\x56\x28\x11\xc4\xb6\xbb\xdc\x72\x7d\x6a\x2b\x6b\x47\x6b\xa2\xcd\x68\x86\x94\x71\x59\xb4\x50\x6f\x00\xea\x5d\xd5\xfd\xaf\x73\x83\x3b\x16\x52\x8f\xf7\xc5\xb9\xf0\x25\xb7\x99\x88\x70\x92\x0c\xa5\xd2\xc5\x6a\x90\xcd\xa4\x74\x86\x54\x27\x93\x23\x53\x75\x76\x58\x27\x98\x52\x63\xca\xbd\xaf\xec\x7e\xdb\xca\xd7\xfe\x1a\x65\xc4\x08\x0c\x5b\x9b\xdf\x64\xc4\x6c\xd6\x4b\xe2\xa4\x9c\x6f\xd6\x0f\xdb\x13\x1a\xf2\xf4\x9f\x27\x1a\xed\x02\xe1\x0d\xeb\xee\x83\x71\xcc\x17\x9a\xc8\xa3\x9d\xdd\x4a\xea\xea\xc1\x77\x79\xd9\xbd\x0b\xfd\x69\x2d\x70\x33\x11\xf3\xef\xf5\xd9\x97\xae\x4f\x45\x0a\x7a\x76\xa1\x97\x9a\xf2\x87\x74\x4c\x90\xf8\xf3\xec\xc5\x81\x9a\x5b\x28\x9f\x7b\xd5\x19\xab\xd3\x24\x1a\xbb\x9b\x4d\x9d\xdb\xb8\xd5\x22\x8e\x03\xf5\x55\xd6\x23\x90\xe7\xec\x2e\x1b\x65\x31\x42\x41\x15\x66\x07\x15\x31\xd3\x97\x0a\x80\x53\x5f\x69\xfa\x86\x90\xac\x62\xd5\xb6\x75\x80\xc6\x8d\xf2\x66\x6b\x99\x63\x9c\xaa\x2e\x8a\xb8\x59\x46\xf5\x88\x88\x10\xe2\x3c\x11\x2a\x44\x4c\x4c\x8b\x47\x22\x22\x71\x84\xbf\xfb\xa1\x32\x05\xa8\x89\xe6\xb1\x88\x48\x1a\x69\xd9\xdf\xaf\xdc\xc0\xa6\x00\x33\x53\x73\x12\x11\x61\x1a\x5f\x91\xc0\xab\xbf\x04\x9d\x1f\x64\x11\x80\xbf\x0b\x6b\x94\x88\x88\x48\x83\x98\xdc\x3d\xbc\x9f\x67\x86\x22\x8a\x69\xc4\x7d\x9b\xf3\x5b\xfe\x06\xe5\xa3\x0b\xca\x06\x03\xe0\xde\xcb\x33\x7c\x80\x33\xac\x57\xf4\x6a\x31\x32\x37\x0f\xa7\xaf\xe1\x46\x22\x4a\x78\xec\x25\x2b\x11\x38\xd6\x67\xe8\x22\x4a\x54\x8a\xd1\x83\xab\x3f\xbb\xec\xfd\x57\xba\x2f\xb3\x93\xa7\x69\x82\x4f\x3b\x98\xd4\x5c\x6c\xef\x96\xec\xd4\x97\x9d\xbb\x44\x94\x4a\x16\xfb\x95\xc3\x16\xf2\x39\x5c\x58\x0a\xae\xce\x82\x0c\x01\x9c\x48\x77\x39\x4a\x19\x0e\x6e\xf5\xdd\x20\x22\xc7\x5a\xee\x17\xce\x5f\x7c\x38\xec\x64\x39\x1c\x4e\x60\x5d\x95\x25\x7a\x7f\x2f\xb6\x6c\x45\x44\x55\x84\x41\xc9\xfd\xfa\x71\x32\x3f\x58\xec\x6c\xe9\x94\x34\xcf\x50\x8f\xa1\xac\x22\x62\x32\xc2\x37\xde\x80\x2e\xf2\x12\xd0\x85\x00\xbd\xed\x67\xcf\x99\xa9\xde\x14\x7c\x53\x55\x05\xae\xdf\x4d\x38\x09\x8f\x39\x06\x00\x5e\x5f\xb8\xff\x38\x09\x9f\xe6\x69\x0a\x7e\x96\x60\xb8\xba\x6a\x1c\x03\xca\x1f\x16\xca\x62\x05\xdc\x17\x80\x9b\x8b\x0f\x67\xbc\x15\xde\x7b\x11\xc9\x34\x41\x70\x86\x92\x0d\x8c\xb4\x75\x44\xa4\x88\x75\xc5\x6b\x14\x25\xe9\xcf\xa8\xb8\xfb\x59\x41\x07\x72\x2d\x47\xbe\x56\x5e\x4e\x7b\x79\x32\x28\x91\x45\x66\xa2\x57\x71\x26\x6a\x29\x22\x95\x11\xec\x1b\x5c\x82\x3a\x3d\xaf\xb1\x60\x34\x1f\xc0\x91\x98\xe7\x30\xd6\x5b\x54\x13\x59\x00\x7b\x88\x48\xe9\x84\xd8\x91\x04\xf9\xa6\xea\x1f\x8d\x66\x3a\x68\xb2\xb8\xdc\x0c\xd7\xe4\x7e\x6e\x98\x44\xe1\x5a\x76\x90\xe5\x49\x16\x28\x2e\x31\x48\x74\x05\x30\xd9\x62\x92\x2a\x22\xc3\x69\x94\x86\x68\xaa\x74\x01\xfe\xb8\x26\x26\x22\x88\x2d\x2a\x6f\xdf\xca\xa6\xed\xc5\x5c\xaa\x3a\xac\x85\x93\x1f\x41\x22\x1f\xca\xac\x9c\x65\xed\x71\xa8\x5c\x9f\xf5\x77\x05\x89\x92\x88\x7b\x7e\x91\x37\x88\xde\xd7\x0e\xf0\x16\x7e\x1a\x89\xb8\x48\xc7\x7b\xb1\x2c\x8a\x6d\xae\x8a\x51\xff\xd2\x0f\x24\x2c\xe5\x7a\x9c\x33\xe7\x53\xc2\x92\x20\x44\xda\x54\x0e\x32\xe4\xf2\x67\xf8\x0e\xa2\xdd\xc2\xd5\x82\x3c\x90\x09\xd6\x47\x90\x98\xb1\xa4\xbb\xb5\xe5\xca\x6f\xc2\xfd\xed\xf4\x03\x12\x23\xa4\xab\xb8\x7b\x41\xc4\x5d\x75\x37\xaf\x8e\x08\x92\x40\x82\x5b\xfe\x8b\x2c\xde\xba\xf4\xf1\x43\x07\xd0\x93\x20\x69\x0a\xe8\xc3\x79\x91\x17\xc5\x77\x28\xeb\x8f\x9e\x41\x12\x06\x50\x57\x09\x39\xd6\x95\x92\xae\x01\xd8\x1f\x62\xa4\xe7\x52\x4e\x02\xed\xee\x90\xd3\xee\x0a\x6e\x6b\x3f\xbf\xc9\xe6\x5c\xd1\x5a\x10\x9a\x78\x1a\x1b\x8c\x89\xbf\x82\x50\x66\x32\xe7\xc5\x31\x2b\x38\x8b\x39\x36\x67\xee\xd0\x11\x4e\xa0\x35\xc8\x10\x51\xa3\xec\xc9\xb5\xa3\xfb\x3d\x94\x17\xf0\x22\x9d\x33\xc0\x23\xbc\x2d\x89\xe4\x4f\xf8\x0d\xfd\xbc\x09\xde\x55\x3d\xd2\x3c\x89\xa7\xff\x19\xbe\xd9\xb8\xbd\x6a\x7b\xb5\x7e\xb8\xbf\xdc\x6f\x9f\x36\x9b\xdb\x7f\xf4\xbf\xcb\x88\x24\x64\xf3\x08\x40\xd8\x81\x3c\x3c\x95\xce\xf6\x78\x8c\xd1\xf6\xe3\xb9\x4e\x30\x44\xda\x1f\x2a\x93\xdb\x8f\x5d\x75\x7c\x3a\x9e\xab\x7a\x0b\xc2\x8d\xc2\x59\x14\x10\xe0\x25\x82\xf2\xce\x1a\xaf\xa3\xc2\x8b\x20\x99\x89\xc7\x9f\x79\xac\x54\xb5\x5c\x84\x10\x44\x26\x56\xa7\xa1\xec\xf2\x25\xef\x58\x10\x99\xda\xd8\xdb\x3d\x98\x6e\x83\x5c\xac\x3c\x7e\xf2\x35\x40\x4d\x14\x88\x69\x85\xb9\xed\xa2\x87\x7a\x36\x99\xa5\x4d\x4c\x37\xe9\x5e\xf3\xb6\x75\x02\xd6\xbb\x2a\x20\x51\x67\x37\x45\x25\xce\xa2\x1d\xf5\xe3\x27\xd3\x4b\x31\xea\x21\x5b\xf5\x21\x47\x85\x05\x59\x42\x79\xe6\xbb\xef\x47\x6b\x26\xb9\x43\x52\x8e\x0c\x4e\x04\x31\x89\x32\x34\xf0\x78\xbb\xe4\xd5\x6f\xfd\xab\xe5\xa6\xa9\x20\x46\x39\xd6\xb0\x13\xba\xe8\x26\xe0\xf9\x3a\x01\x86\x20\xe3\xf9\x1f\xd0\xae\xca\xaa\x7d\x81\xfa\xa9\x81\x22\x78\x55\x86\xaf\x06\x9b\x06\x28\xd9\xca\x31\x37\x2f\x65\xff\x5a\xda\x8c\x62\x48\xb8\xba\xbd\x7d\x58\xef\xb7\xeb\xfe\xef\x8a\xc7\x5e\xe6\xe4\xb1\x6f\x9c\xf4\x9b\x27\xb1\x5a\x61\x2b\x68\x75\xac\x8a\xa2\xea\x96\x80\x01\x21\xf9\x65\xdc\x12\x47\x11\xcd\x6c\xef\xf0\xea\xfd\xe2\xaf\xab\xda\xc7\x19\x8b\x3d\x19\x11\x47\x9c\x29\xe6\x57\xc4\xf5\x83\xc7\xc4\xfe\x36\x1b\x93\x39\x60\x72\x88\x90\xdd\xe2\xdf\xe3\x7a\x46\x72\xab\xd3\xcf\xc5\xa9\x4b\xcf\xdc\xcb\x87\x16\xd4\xdb\xd5\xad\x27\x17\x88\x38\x36\x11\x4a\x65\xbd\xc0\x4f\x3c\x6d\x55\x14\xae\x80\x1f\x06\x50\xab\x71\xf3\x75\xca\xe1\x93\x48\x25\x66\x24\x8b\x03\x95\xd5\xd7\x91\xeb\xfc\x7f\x93\x8a\xf5\xec\xfe\x30\x99\xc6\x4e\x0f\x42\xed\x75\x65\x72\x0d\x16\x15\xa8\x17\x13\x4f\x11\x33\xc8\xb0\x6f\xf8\xb4\x5b\xc7\x77\xff\xd8\x85\xef\xe5\x84\xe3\xec\xf9\xe6\x6a\x47\xdd\xfb\xfd\xb7\x01\xc0\x14\x06\xb1\x0c\xf1\x1e\x26\x38\xed\xc2\xe7\x4e\xea\x22\x16\x9c\x60\x82\xd3\xa7\xb7\xce\x85\x7c\x76\x4e\x21\x9d\x29\x2f\xb6\x89\x76\x93\x44\x58\xc4\xc2\xa6\xd2\x3b\x04\x55\x6f\x33\x7e\xfe\xb2\x98\x82\x88\xb3\x44\x4a\xf0\x7a\x85\x63\x40\x7d\x38\xcc\x08\x0c\x7b\x87\x0f\xe4\x3f\xf9\x05\x99\x4a\x10\xa4\xb5\xab\x0e\xaa\x2a\x64\xb8\x2a\x19\x29\x54\x5e\xf1\x90\xb4\x51\x5c\xb1\x2a\x8a\xd9\xd7\x49\x70\x36\x9b\x85\x6c\x1c\xc2\x7e\xff\x26\xbe\xcb\xe6\x65\xef\x87\x85\x73\xaa\x98\xeb\x2c\xdc\xff\x43\x3e\xc5\xe5\x8a\x58\x6b\x40\x6f\xa9\xfd\x51\x7e\x2c\x29\x24\xfb\x68\xcf\x8f\x36\x89\x44\x3c\x9c\x2c\x0a\x0c\x44\x9d\xb5\xd8\x99\x0b\x88\x88\x0d\x25\xd0\x83\x70\xef\xbd\x5d\x70\x38\xc6\x0d\xf6\xcc\xf6\x87\xbc\x9c\x6d\x1c\xb1\x91\x29\xc2\x8f\xd5\xe9\x63\xf8\x80\x65\x89\x4f\xee\x9a\xd0\x07\x9d\x96\x36\xc3\x38\x25\xdd\xae\x53\x23\x45\x7b\x57\x3d\x56\xc5\xc4\xa0\x5d\x24\x91\x60\xc2\x57\x52\x36\xf5\x52\x44\x99\x44\x86\x22\xd5\xd1\xa5\x4a\x8f\xd0\x7d\x5c\x0f\x78\x58\x91\x44\x10\xa3\x10\xb3\x3a\x79\x1c\xe4\x7c\xe1\x4d\x22\x60\xa1\x8c\x7f\x5d\x03\x20\x7a\x03\x03\x9d\x4f\x0d\xf8\x44\x12\x59\xe7\xa2\x84\x51\xec\x6d\xb7\x5d\xf9\x03\x44\x68\xe5\xb5\x24\x6e\xcc\x4e\x96\xaf\x41\x76\xd6\x1f\x4f\xa2\x98\x39\xa9\x2d\x24\xc2\xbb\xca\xd7\x3e\x8e\xf6\x7f\xed\x02\xdb\xe0\xdb\xde\x8d\xd3\x18\x31\xb9\xe9\xb9\x72\xee\x2c\x2e\x2e\x9a\x5e\x49\x42\x1d\xc3\xd1\xd5\x77\xdc\x7b\x78\xd6\x85\x10\x49\x22\x92\x90\xb6\x3d\xca\xb2\x3a\x8c\xad\x58\xbb\xa3\x9c\xb2\x51\x64\xb9\xaa\xd5\x88\x8f\x21\x92\x44\xa7\x41\xa9\x12\x67\xf9\xc5\xc7\x45\x6e\xc6\x38\x13\x91\xb0\xcc\x11\x8e\x7a\x3d\x6c\x72\xd5\xbe\x6c\xc2\xbc\x4e\x98\x75\x96\x72\x8d\x2c\xa0\xc1\x46\xc7\xec\x77\xf0\x88\x32\x8f\xf1\x32\xbe\x6f\x3e\x7d\x4c\x9c\xbb\xde\xed\x7e\xbf\xcf\x9d\x85\xc9\x12\x30\x6d\xf6\x19\x01\xe0\x57\xf6\x8b\xaa\x2a\xe2\x70\x35\x1c\x62\xd4\xeb\x75\x7b\xe4\x83\xbd\x85\xe7\xfe\xb7\x8a\x4c\x38\x33\xcf\x53\xbb\xab\x7a\x09\xb5\x80\xc2\x43\x53\xf5\xe9\x95\x0b\xe3\x3a\xb0\xaa\x90\xfa\xf5\xac\x7a\x2e\x12\x49\x28\x04\x87\x77\xb7\xb7\xcf\xb9\x3a\x22\x91\x71\xa4\xe2\x99\xd2\xda\x7c\x08\xd3\x18\x22\x87\x55\xf4\xba\xaa\xaf\x7e\xba\x96\xc5\x27\x48\xea\xf0\x41\xd1\x37\x51\x46\x54\x28\x7f\x50\x45\x29\x92\xe6\xba\xd3\x14\xe1\x7c\x43\xbf\x55\x24\x8a\x48\x0f\xb7\xb9\x29\x37\xb2\x69\xae\xf3\x62\x6e\x80\x2a\x12\x25\xa3\x60\x05\x7f\x91\xb7\xba\xca\xcb\x8b\x3a\x37\xcf\xf3\x9f\xa0\x45\x8a\x6a\x35\x77\x37\xf7\x53\x35\xa3\xee\x90\xc4\x14\xf6\xe9\x18\x8a\x74\x0b\xee\x5b\x22\x31\x3e\x92\x6f\xac\xfe\x02\x3b\x23\x12\x93\x52\x35\xa0\xe0\x5d\xf1\x2d\x1c\x12\x4e\x79\xa4\x2a\xe1\xa5\x3a\xf5\x7f\x86\x24\xc3\x57\xe0\x35\x2f\x8a\x4d\x15\x44\x63\x44\x02\xdc\x69\xe3\xf9\x3b\x03\xb2\xf8\x67\x3e\xce\xf9\xc2\x30\x99\xa0\x89\x8f\xca\x4b\x83\xf2\xbe\x58\xa9\x1c\x5e\xc5\xc9\x8c\x01\xb0\x28\x8f\xa2\xab\xc3\x21\x2f\x9f\x0b\xa8\xb7\x50\x14\x8d\x5f\x2a\xb6\xbf\x3f\xa1\xe0\x68\x5d\x3d\xca\x56\xde\x94\xcf\xf5\x02\x63\x66\x56\xe8\x5f\xba\x07\x96\x28\xe2\xca\x93\xcf\x35\x92\x46\x3f\x6f\x79\x8a\xc4\x26\x04\x6b\xd6\xba\x2a\x9b\xd3\x3c\x41\x48\x2c\x8d\x44\xa8\x87\x74\x0b\xd7\xd8\x18\x4b\x24\x96\x65\x08\x9d\xfc\xbe\x19\x87\x8f\x89\x95\x19\xca\xff\x61\xb5\x18\xe5\x32\x96\xb7\xd7\x34\x22\x16\x35\xd0\xff\xd3\xcd\x9b\x6e\x83\x38\xe7\x81\x87\x91\x89\x34\x69\x1f\xcd\xb5\x33\x47\x4b\x91\x92\xc8\x62\xe7\xe5\xa5\x8b\xd7\x7d\x53\x7b\x52\xbe\x4a\x49\x26\xc1\xf4\xcb\xd4\x10\xe3\xb5\xf2\x39\x00\x68\x44\xda\xc5\x0e\xdc\x21\x34\x5a\xf8\x39\xca\x53\xd3\x6e\x73\xf3\xa0\x28\x74\xfa\xcd\xcb\xe7\xd5\xb8\xef\x3b\x99\x14\x69\xa2\x12\x94\x3e\x0a\xcb\xaa\x2c\x42\x06\x1d\xce\x97\x92\x18\x93\xe6\x15\xbd\x1c\xdf\xbb\x14\x39\xb0\xff\xef\xff\xfb\x7f\x7f\xcb\xef\xb0\x15\xeb\xc3\xe4\x5f\xc2\x36\x45\x9a\xda\xc4\xe1\xd8\xbb\xbb\x7e\x31\x47\x84\xfa\x41\x34\x73\xf6\xe5\x50\xea\xca\xfc\x22\xf0\x4e\xa9\x49\xac\xf0\x69\x99\xd7\xd3\xbd\xfa\xd9\x42\xd9\x38\xab\xb9\xde\xab\xb1\x1b\x99\x46\xe3\x02\xc5\x6a\x3a\xe5\xfc\x28\x66\x29\xf5\x65\xd6\x9b\xc6\xa1\x2f\xb7\x30\x26\x43\x8a\x94\x4b\x8e\x89\xf9\xb9\x03\xc7\xf4\xd2\x04\xc9\x02\xbb\xe2\x7b\x55\x37\x30\xdb\x1c\xbb\x1c\x0c\xfb\x68\x57\x05\x1c\xf3\xe7\x5f\x1b\x38\x7e\x56\x41\xfd\x72\x97\x49\x85\x22\x92\x8e\xdc\x95\x96\x6f\x63\x46\x18\xba\x3d\xf6\xfc\xda\x6a\xfa\xab\xe6\xc5\x85\x34\x13\x3c\xee\x7e\xdc\xde\x42\xab\x5f\x70\x51\x41\x9f\x09\x54\x79\x9a\x5e\x81\xf2\x2c\xd9\x06\x5a\x17\x25\x7d\xe1\x8a\x25\x52\x95\x71\x6c\xd2\x63\xda\x31\xae\xe4\xcc\xc6\xe9\x34\xc2\x25\xf1\x11\xc5\x16\x17\x16\xa1\xe5\x1f\xaa\x05\xc3\x44\x36\x90\xde\xa7\x93\x20\x54\xc6\x52\x9d\x09\xe4\xa7\x38\xfd\xba\xa0\x5f\x33\x3b\x95\x22\x88\xc2\xbb\xcb\x8d\x29\xba\xc8\xac\x8f\x84\x53\xa3\x5c\xd5\x0a\x0b\xce\xa3\x0d\x2b\x35\x26\x12\x3e\xe3\xf3\x04\xbb\x91\x4b\x60\x77\x38\xc5\xf5\xbc\x79\xa9\x54\xf5\xbf\xbc\x98\xbc\x76\xa0\x63\xd4\x7c\xa9\xca\x8d\xfc\xa8\x4e\x9f\xa4\xd8\x29\x68\xe7\x07\xd6\x05\xf3\xdf\xa0\x8c\x7a\x53\xfd\x59\x50\x93\xda\x54\xe1\xca\x58\x56\xdb\xb6\xaa\xa1\xd9\xf6\x8b\x66\x6a\xa9\x44\x35\x8f\x6f\x23\xcb\xff\xb1\x6b\xf5\xe4\x44\x34\xca\x0c\xfa\x33\xb9\x70\x70\x2d\x8f\xcd\xaa\x34\x4b\x16\xcb\xcb\xcf\x84\x92\x8c\x20\x2b\xea\xae\x2a\xc1\xc8\x55\xa1\x65\x21\x97\x56\x06\x1a\xcb\x98\x87\x99\x14\x28\x66\x9e\x3b\x39\x7f\x09\x86\xe8\x92\xc6\x40\x71\xa9\xdf\x56\x85\xac\xef\x57\x9f\xd7\x43\x69\x22\x1c\x36\x01\x99\xc3\x8e\x4a\xea\xe6\xea\x4d\xb9\x2e\x43\xf4\x4b\x53\x2a\x64\xb8\x39\xbe\x67\x85\x2b\xf4\x0e\xea\xc3\xc4\x1f\x50\xd0\x94\x65\x83\xf7\xe0\x4d\x60\xfd\x0b\x9a\x2a\x83\x29\xcd\xf1\xad\xdd\x1f\x8b\x43\xbb\x6f\xfa\x7b\x4f\xa9\xe0\x98\x8c\xc1\xe1\x58\x54\x1f\x00\x5d\x50\x37\x26\xbd\x75\x23\x54\x10\xe7\x78\x28\x27\xd0\x36\x0c\x4d\x47\xb8\x4e\x41\x59\xe4\x7c\x1d\x55\x55\x9e\x9a\xe4\x6a\x08\x9b\x29\x42\x42\xbd\xc6\x41\xfe\xdf\x53\x6e\xf2\xf6\x03\xf5\x3d\xce\xd9\xdd\xff\xc7\x7f\xfd\x17\x88\x58\x62\xb1\xe5\x54\xe6\x6d\x93\x46\xde\x71\xeb\xea\x67\x5b\x87\x24\x95\x66\x89\x92\xa1\x87\x58\x9e\x0e\x93\x2b\xcf\x52\x9b\x3a\xb0\xdb\xfb\xa4\x32\x41\x33\x9b\xe2\x4f\x0a\x2e\x2f\x3f\xe0\x25\xd7\x43\x25\x61\xb2\xfb\x4c\x56\x22\x2a\x75\x86\x35\xa3\xbd\x96\xe5\xd6\xa1\xec\x1e\xde\xfa\xe0\x8b\x6a\x0a\x19\x1b\x09\x3b\xb8\xbb\xbe\x1a\xda\x15\x0b\x53\x46\x6b\xc7\xd5\xff\x3c\xea\xf7\x03\x8d\x57\xbb\xdd\x6d\x77\x0f\x8f\xff\x5c\xbf\x85\xfd\xbc\x3b\x80\xed\x9c\x4b\xf9\x71\x53\x6e\x41\xf7\x0f\xc8\x70\x83\x88\x08\xaf\xa1\x35\xa0\x95\x66\x27\xce\xb2\xd8\xa7\x3f\x97\x95\x9e\x1f\xd4\x4c\x0f\xc6\x05\x31\xf9\x3d\x6f\xdb\x1c\x9a\xe9\x7c\x02\xc2\xdc\x16\x71\x3a\x1c\x26\x1e\x18\x82\x42\x42\xb1\xd4\xe8\x5e\xed\x33\x08\xce\xd2\xeb\x06\x5d\x56\x1e\x82\x98\x1b\x54\x47\xd9\x81\x3c\x4c\x12\x32\x6a\x63\x8d\x91\xfd\x4a\x6b\x28\x4d\xbe\x96\x4d\x23\xff\x7f\xd6\xde\xa4\xb9\x71\x1d\xcb\x1f\xfd\x2e\xff\xd5\x5d\xf4\x82\x33\x80\xb7\x93\x65\x39\x53\x7d\x3d\x95\xa5\xcc\xac\xfb\x3a\x3a\x14\x07\xc0\x81\xcd\x4a\x8a\x54\x91\x94\x9d\xae\x4f\xff\x82\x07\x00\x27\xd1\xce\xfb\x8f\x78\xbd\xb8\xd9\x65\x42\x14\x45\x82\xc0\x19\x7e\xc3\xca\xda\x36\xe4\xaa\x9f\x1e\x86\x01\x01\x45\x9d\x17\x5b\x17\x9e\xb4\x03\x07\x80\x67\x41\x98\xa5\x6a\x30\x07\xdc\x6a\x2c\xdb\xdc\xe4\x33\xc9\xff\x6e\x1c\x30\x17\x70\xef\x7f\x95\xf7\xe7\x63\x7f\x02\x6e\x55\x3d\xf3\x16\x8f\xde\xab\xca\x1d\x0a\x23\x43\xab\xe3\x76\xf5\x75\x6c\x6d\xcc\xb3\x28\xb0\xc1\xa8\x46\x57\x35\xee\x0f\x24\x48\x34\xff\xd5\x7e\xff\xd8\xc5\x37\x7f\x43\xc4\x8e\x67\x11\x66\xa9\xab\xf7\x5a\x0b\x41\x2b\x97\xb2\xae\xb4\x15\x6e\x1e\xaf\x7f\x59\x9c\x45\x69\x32\x5a\xff\xae\xac\x60\xd2\xe5\x43\xc8\x62\x09\x21\xf3\x2f\xb7\xac\xa1\x7e\x5f\x82\x38\xf0\x2c\x46\x2d\xbc\xc2\x1c\x09\x97\x2e\x5f\x65\x12\x80\xa4\xd6\x0d\x29\x9b\xcf\x78\xf6\x3c\x4b\x22\x87\xfe\x2a\x10\xd4\x0b\xd1\x3d\x46\xda\xe8\x3c\x4b\xb4\x65\x39\x8d\xac\xc5\xfa\x23\x9c\x2a\x24\x44\x7a\xc4\xdd\x20\xb1\xcb\xb3\x34\x88\xe3\x71\x7c\xda\x53\xcd\x66\x3f\x21\x4d\x8d\x97\x72\x73\xd5\xd6\x05\x12\x17\xcf\x52\x96\x82\x45\x06\xe9\xb3\x72\x6d\x79\x4d\x55\xaa\xc9\xaa\x95\xa5\x10\x51\x97\xaa\x69\xeb\x7d\x65\x03\xfe\xc9\x33\x48\x15\x23\xa5\xa3\x36\x77\x10\x5d\xf7\xf7\x2c\x4e\x2d\x0b\x58\xd5\x70\x22\x6a\x45\xbf\xb0\x64\x59\xa2\x28\xff\x1a\x6c\x59\x9c\x83\x5d\xf7\x88\x17\xca\xc3\xbf\x03\x91\xba\xd3\x32\x54\x04\xd0\xd4\xd8\x05\xca\xb4\x76\x3f\xcc\x8a\xe9\x19\x8f\xac\xcc\x79\x17\x6d\xfc\x2d\xdb\x3a\x9e\x75\x53\x9c\x24\x69\xf0\x75\x5d\x95\x3b\xf5\x52\x55\x85\x63\xb4\xfa\x11\xdc\x86\xf1\xe6\x5c\x6a\x77\xcf\x57\xcf\xa3\xf7\x92\x83\x24\x3c\xd3\x5f\xe7\x23\xd6\xf9\xf0\xba\x89\x8c\x7b\xe7\xd1\xd5\x73\x97\xa1\xdc\xa1\xce\x61\x10\x81\xe7\x99\xe0\x16\x80\xbd\x6b\xcd\xd9\x7a\x18\xf4\x61\xb1\x1b\x01\x41\x8c\xa3\x96\xcd\x1d\x9c\x4e\x56\x06\x9d\xc8\x73\x1f\xcc\x5f\x60\x98\x49\x47\x21\x9f\x4e\x40\xc9\xa2\xd0\xed\xa5\xe5\x48\x8c\x82\x67\x2a\xe4\xb4\xac\x1e\xf3\xb2\x5b\xa4\x4e\xed\xc8\xc6\x92\x67\x2a\xce\xe2\x49\xd9\xd8\xf6\x4f\x3f\x6f\xee\x64\x2a\x0d\x4c\xec\x89\x93\x56\xcb\xe1\x6b\x75\xae\x9f\x29\x74\x1c\x37\xdb\xb8\xfb\x80\xce\x80\x38\x76\x06\x14\x15\xfd\xc7\x0f\x41\xa3\x05\xcc\x1d\x4e\xb0\xec\x79\xca\x33\xcc\xac\x71\xda\xcb\xb9\x7c\xae\x67\xe9\x47\x86\x82\x91\xb3\xf8\xf7\xdb\x6f\x93\xf5\x0d\xc1\xda\x53\x5a\xf0\xbd\xfb\xa3\x51\x8c\x48\x67\xf4\x2b\x2f\x54\xac\xec\x20\x16\x04\x8a\x0a\x71\x9b\xef\x9e\xd4\xc0\x59\x20\x2c\x64\x5d\x52\xab\xef\xaa\xf7\x86\xce\x27\x76\x58\x9c\x05\x92\x5b\x7b\xce\x9e\x45\x39\x69\x39\xb0\x40\x6b\x92\xc7\x7d\xdc\x3c\xad\x37\xf7\xfb\xc3\xf5\x96\x9c\xfa\xfc\xe1\x30\xb0\x6f\xdf\x6d\xf5\xfc\x81\x7b\x94\x1f\x28\xac\x48\x61\x8d\x25\xbe\xdd\x40\x7d\xc4\x7a\x8d\x75\x6b\x17\xde\x0f\x0a\xaa\x2c\x54\x09\xe9\x11\xda\x56\x48\x0f\x0a\xf7\x5f\x1e\x25\x11\x71\x4e\xfe\xcc\xd5\xcf\xee\xde\xe8\xfe\x40\x16\x50\xf7\x8d\x2a\xd7\x54\x58\x1f\xf1\x03\xbb\xc3\xc2\x72\x2d\x6e\x27\x3b\x0c\x8b\x98\x26\x10\x11\x21\x40\xa6\xae\xea\x9c\xc5\x8a\xd1\x5a\x7b\xe8\xd5\x00\xac\xe5\xf8\xec\x59\x24\x22\x0b\xb3\x01\x24\x32\x0e\xde\xfd\x08\xb0\x26\x1a\x7b\x03\xf5\xb1\xff\x23\x66\x14\x14\xaa\xaa\x54\x30\x27\x6c\x8e\xd7\x41\x96\xf2\x4c\x78\x37\x48\xa8\x2f\x4a\xbf\x2c\x8b\x42\xa5\x2c\x7a\xf1\x1e\xdf\x64\x55\xea\xf9\x00\x88\x63\xbb\xf4\x77\x6f\x57\xb8\x9c\xcd\xb0\xcc\xd8\xc6\xbd\xaa\x8e\x26\xaf\x8f\x36\xdb\x9b\x9d\x49\x24\x21\x31\x2b\x54\x8d\xba\xf2\x2e\x5e\x73\xc3\x18\xce\x20\x0d\x52\x36\xf0\x2b\x6c\xe2\xb5\xfc\xc0\x21\x43\x8b\xf8\xc6\x22\xf7\x2d\x9d\x2c\x99\xf4\xc3\x87\xff\xe9\x3f\xc3\x83\xc4\x92\xe5\x09\x41\x31\x6f\xa4\x5e\xa4\xeb\x17\x05\x24\x06\x02\x69\x1e\x7d\xdb\x5d\x1f\xd6\xab\x47\x7f\xdd\x4a\x73\x42\x2f\xd5\xf9\xf3\x4b\x1b\x27\xb3\x1f\x8f\xa1\xf6\xa8\x95\xfb\x2e\x9e\x35\x9f\xc9\x6e\x72\x66\x62\xab\xfc\xdb\x22\x1c\xbd\xf7\xe3\x41\x8d\xdf\x44\x63\xb8\xcc\x06\x0e\x0c\x0c\x91\x37\x0f\xe2\x24\xc8\xfa\x88\xb4\xdb\x52\x96\xe4\x8c\x38\x0f\x98\xf6\x52\xb7\x8f\xdb\x03\xea\xbc\x3d\x84\xbe\xbc\xcd\xc3\x30\x21\x38\x4b\x03\x06\xbf\x60\x4b\x0c\x14\x70\x5a\x85\x37\x45\x55\x5d\x14\xe2\xa6\xcf\x86\x87\x80\xcc\xc9\x2f\x39\x64\xd3\x7f\x8d\x01\x4e\x3c\x8a\x19\xa5\xd8\x50\x14\x4d\xdb\xbd\x19\x83\xcf\x26\xe7\x51\x12\x52\xd7\x3b\x6f\x36\xa7\x4a\xf5\x3b\x13\x8f\x05\xa3\x14\xd4\xd1\x27\x57\xdb\xeb\x5d\x7f\x48\x66\x0a\x7b\x92\xde\xbe\xaa\xd5\x4b\x7f\x48\x09\x22\x04\x9d\x6a\x7c\xfd\x5a\xe9\xa2\x57\xa1\xe1\x3c\x11\x8a\x1a\x02\x56\x15\x66\xa1\xff\xef\xc7\x99\x84\xea\x4d\xf2\xfc\xbe\xa4\xc1\xc6\x79\x2a\x6d\xcc\x47\x8e\x33\x9f\x01\x09\x2e\x93\x93\x2e\x85\xa0\x69\xdc\x27\x32\xcb\x8e\x78\xb3\x1b\x9c\xf1\x98\x76\xa9\xc3\x47\x12\xe2\xdd\x10\x20\x0f\x57\x4b\x0d\xb1\x6e\x3a\x8b\x88\x3c\x9e\xe9\xc8\x23\x04\xb6\x0d\x25\x5b\x43\x94\xca\x99\x4b\x4e\x41\xe6\xfe\xbe\xb1\x28\x05\xe7\x06\xd8\x5c\xf6\x02\x39\x67\xca\xf7\xdc\x6e\x6a\xc4\x55\x91\xbb\xba\x63\xff\xf8\xb9\xe0\x84\xc8\x39\xe6\x65\x8b\xda\xe1\xc6\x9c\x05\x54\xff\x74\xb8\xca\x42\xbb\x62\x74\xcf\x54\x55\xc7\x13\xd4\x78\xd5\x2a\x1b\x39\x7e\xab\x8b\x69\x02\xc1\x45\x02\xa4\x8d\x76\x93\xbf\x4e\x49\x25\xf4\x75\xd6\x7f\xa3\x9b\xbf\xeb\xea\x5c\x37\xc3\x21\x05\x9c\xff\xfd\x15\xc1\x7d\x0a\xa2\x44\xd9\x9e\x46\x0f\x35\x1c\x81\xc5\x39\x87\x8c\x51\x78\xb6\xd2\x7a\x5d\x95\x0d\x96\xed\x85\x65\x14\xe7\x20\xad\x70\x11\x51\xd0\x96\x8c\x43\x38\x97\x71\x4a\xf1\x75\x43\x0a\x6d\xd3\xcd\xd2\x4a\x4a\x0e\xa7\x93\x31\x0f\xbc\x1e\xe2\x69\xdb\xd8\xa5\x73\xf4\x20\xa5\x01\x8b\x3a\x24\x72\xb9\x85\x0e\x7e\x56\xd1\xe7\x2a\x64\x41\x2f\x00\xdf\x85\x91\x36\x7e\x9c\xde\x09\x95\xa5\xc4\x8b\x21\x6b\x94\x29\xeb\x6a\xae\x56\xfb\xd1\xbf\xa3\xe5\x95\x2b\x26\x88\xd5\x05\xb2\xa1\x1b\x7a\x33\xab\x63\x71\x85\x96\xd1\x6f\xcb\xef\xab\xda\x77\x36\xfb\xe0\x93\x6b\x15\x11\x6a\xc2\xa6\xc3\xdd\x3c\x99\xdd\xb6\xff\x49\xff\x77\xf6\x38\x51\xa3\x77\xf7\xfa\xd6\x10\x1b\xfd\x43\x3c\x08\x37\x21\x7a\xb0\x9d\xa3\xdc\x75\xfb\xb6\x37\xa9\x9f\x5e\xac\x89\x2c\x5a\xd1\x09\xaf\x38\xf5\xcd\x05\x3f\x42\x3f\x3e\x96\x84\x23\x69\xeb\x77\x52\xa1\x7f\xaa\x2e\x59\x90\xf3\x8f\x68\x49\xfa\x65\xce\x6e\x61\xb1\xe9\x25\x82\x20\xf1\x74\x3a\xd7\x3e\xe8\xb5\x37\xbd\x45\x11\x95\xe1\x17\x4a\x74\xe3\x57\x4c\x04\x99\xa2\xcd\x0f\xad\x72\x19\xde\x41\x79\x11\xd6\x0e\x0b\xdc\xec\xff\xe3\x7e\xc9\x13\x61\x16\x85\xe1\x00\xc0\x1e\xa3\x9f\x97\x04\x8e\xfd\xa7\x98\x26\x81\xfa\x02\x9a\xf6\xba\x8b\xed\xfc\x4a\x21\x42\x15\x64\x30\xb3\x80\xa3\x36\xab\x3f\x6e\x12\xcf\xf8\x5c\xf7\xd6\x9f\x5c\x44\x26\xa0\xfa\x31\x4d\xa5\xc7\xaa\x1e\x92\x41\x11\x07\x19\xc9\xbb\x2d\x4b\xdd\x8c\x97\x59\x11\x87\xd6\x25\x6c\xff\xb0\x5f\xdd\x3a\x18\xdd\x28\x32\x10\xb1\xc6\x08\x7a\xb6\xcb\xb7\x32\x57\xd5\x2c\xbf\x11\x31\x6a\x12\xad\xb6\x72\xbf\x48\xf2\x82\x7f\xa2\x77\x8f\xfa\x56\xb6\x79\xff\x53\x92\x80\x13\x75\x44\x57\xfb\x3a\x7f\x7e\xc6\x7a\x42\xcc\xe5\x22\x09\x63\xaa\x8e\xae\xab\xbc\x5c\xe9\xd7\xbc\xa9\x6a\xca\xce\x26\x16\x42\x9f\xce\x28\x91\x60\x4c\x22\xc0\x87\x83\xf2\x7e\x0a\x36\x0c\x1a\x73\x5a\xdc\xd8\x94\x19\x4f\x59\x5d\xbd\x43\xd9\x5e\xd7\x55\xde\x6e\x54\x55\x56\xc7\xfc\xdf\x67\x3c\x38\xc5\xaa\xc4\x5f\x5e\x96\x31\x12\x8e\x72\x38\x5f\x5f\xf5\x5e\x7e\x1d\xba\xd1\x44\x4f\x3c\xe4\xcd\xee\xbd\x6c\x5f\xb0\xc9\xff\xd3\xa5\xb1\xae\x03\xb6\xfc\x21\x1e\x30\xaa\x21\x5c\x57\xe5\x42\x75\xdb\x0f\x4a\x53\xe2\x07\x90\x08\x53\x5b\x9d\x4e\x1f\xc8\x87\x72\xc1\x59\xe4\x2b\xb0\xbb\xbc\xbc\x70\xde\x1d\x36\x72\xc1\x45\x48\x2d\x4e\x6c\x5f\x06\xdc\xac\x10\x4c\x40\x3c\xe9\x65\x9c\xce\xa7\x65\xf5\xb2\xe9\x17\x0b\xb4\x5b\x4c\x37\xea\xda\xc3\xa4\x86\x48\x59\x80\x42\x65\x55\xd0\x09\x6b\x4b\xa8\xa7\x53\x31\xeb\xbb\x0a\x19\x5a\x68\x8a\x77\xbc\xa3\x7c\x4e\x57\x6f\xfd\x69\x64\x1a\x90\x0f\xe5\x17\x6c\xaf\xa0\xfc\x89\xf5\x1a\x4a\x9d\xeb\xa9\x01\x31\x17\x12\x02\xe1\xe0\x05\x5d\x04\x7b\xdb\xdd\x8a\xa5\xb7\x41\x85\x11\x29\x7e\xe4\xcd\x97\xf3\xc8\xb3\xb1\x3f\x6a\xf1\x80\x27\x68\x5f\xdc\xec\xb4\x4a\x68\xfd\x71\x2e\x03\x8f\x59\x53\x3f\x27\x6c\x15\x2e\x74\x14\x06\x83\x68\xa0\xdb\xc1\x16\x19\x29\xdd\x58\x4e\x75\xbe\xb2\x6a\x73\xf3\x7e\x75\x7e\xff\x3b\xb7\x5c\x27\x11\xcd\x8a\x9a\xcc\x9e\x71\x10\x5d\xe4\x42\x83\x6d\xdb\x92\x5d\x87\x7f\xc9\x1d\x8d\x9a\xde\x7c\x3f\x10\xd3\x8c\x5a\x5e\x77\xab\x7f\x1e\xd6\xab\xfb\xef\xab\xdd\xe1\x7e\x75\xb7\x39\xdc\x6e\xee\xbf\x78\xee\x22\x17\x26\x56\x14\x75\x9c\xc6\xfb\xcc\xa7\x21\xb5\x30\x1a\xbd\x1c\xc7\xa6\x4b\x14\x15\x8e\x36\x77\x08\x14\xd7\x36\x66\x76\x08\xe7\xd1\x8e\x08\x81\x66\x14\x9e\xc2\x6c\xab\x84\xc0\x40\x64\x37\xd3\xe7\x67\xa7\xc9\xd5\x23\x42\xdc\x90\x30\x8d\x7c\xed\xf3\xea\x5c\x97\x4f\xf8\xef\x33\x36\xed\xb7\xbc\x6c\xef\x06\xb7\x8b\x25\xb5\x20\x0e\x61\x26\xc9\xd9\xe3\x90\xb7\x15\xfc\x31\x06\xdc\xf9\x01\x12\x29\xb7\xee\xd6\xbb\x1b\xaa\x9e\xcc\x70\x82\x10\x2b\x69\xfd\xe8\xcf\xa5\xa6\x02\xb5\xfb\x7b\x92\x49\x6d\xf5\xa2\x9e\xf0\x5f\xb6\xf1\x3b\xfd\x60\x22\x02\x23\xc7\x58\x97\xba\x3a\xee\x6b\x84\xe6\x5c\x7f\x50\x88\x81\x34\x00\x5b\xb8\x85\x02\x69\xf7\x9d\x53\xa1\x39\xa4\x89\x51\xa9\xdf\xb8\x06\x33\x93\xf1\x1e\x09\xa9\x66\x54\x4f\xb0\x7a\x4b\xdd\x2e\xf4\x9b\xe7\x3b\xbb\x8c\x2c\x90\x99\x1a\x0b\xa6\x0d\x42\x0e\x1c\x58\xec\xbb\x1f\x14\x5a\xdf\xc3\xe9\x67\xef\x64\xc5\x81\x65\x2c\xe9\x15\xa8\x3e\x6e\x24\x03\x33\xa1\xc7\xca\x77\xfb\x0d\x11\x50\x16\xf8\xda\xd3\x20\x02\x78\x16\x68\x3d\x40\xd5\x47\xec\xbd\x95\x69\xb1\xde\xfc\x3a\xe5\xf5\xfb\x9c\xc8\xc7\x81\x33\x43\xe5\x31\x3c\x9e\xda\xf7\xfd\xde\xe3\x44\x81\xcb\x24\x62\x63\x23\x4b\xe2\x71\xad\xeb\xf7\xa6\x85\x19\x40\x0a\x44\x6c\x19\x78\x5d\x82\x52\xea\xfc\x35\xd7\x67\x28\xd6\x70\x6a\x3e\x5e\x8e\x41\xf0\x8c\xca\x89\x3f\xf3\xa2\x98\x41\xf3\x97\xa2\x8d\x0f\xd8\x4a\x00\xcc\x3a\xd0\xe4\xcd\xf6\xa2\xce\x09\xa0\xe2\xd8\x3d\x8e\x7b\x67\xca\x38\x16\x6b\x78\xc4\x9a\x34\xfe\xfd\x70\x99\x84\xda\x85\x8e\x8f\x0f\x0f\xb7\x36\xe9\x8e\xfd\x51\x15\x18\xa7\xee\xf3\xf4\xf8\xd0\x25\x01\x53\x4c\x3e\x28\x85\xb4\x52\x9f\xaa\xf2\x3f\xf9\x14\xd5\x09\x4a\x0b\x39\x10\xd0\x6f\x10\x5d\xce\x1f\xcd\x5e\x0b\x9d\x2a\x42\xae\x3b\x9d\xb7\xfe\xbb\xb5\x91\x5a\x7a\xcd\x39\x8d\x35\xb4\x95\x8f\x85\xc0\xa8\x80\xfa\x2f\x37\x0f\x77\x0f\xf1\xf5\x6d\xde\x37\xca\xc1\x68\x2b\xb2\xfc\x02\xcd\x13\xb6\xe7\xfa\xa3\x4c\x02\x0c\x26\xa4\x2b\x31\xf8\xa3\x35\x55\x09\x85\xed\x3f\x4c\xae\x50\x86\x69\x68\xd1\x96\x94\x93\xf7\x7c\x52\x2e\x43\x26\x49\xd6\xb7\x3b\x47\xb7\x32\x4f\x15\x24\xb9\x8c\x12\x49\x4b\xea\x76\x75\xe7\x99\xe2\x87\xab\xd5\x6e\x92\x4f\xc9\x24\x0e\xa8\xb2\x78\xb0\x18\x70\x82\x7a\xba\x5b\xf9\x41\x31\x46\x26\xa9\x16\x91\x5b\x6a\x68\xed\x73\x28\xfe\xe9\x6b\x2f\x13\x61\x75\xc4\xe4\xf9\xfd\xcb\xbc\xf8\x25\x13\x1d\x13\x26\x7a\x73\xcc\xdb\xd1\x7b\xb3\xd5\x23\x95\x60\x37\x34\x8d\x14\x9b\x14\xad\x3f\xe3\x23\x4c\xf6\x5e\x99\xc6\x8c\x8a\x20\x77\xf0\xfc\x9c\x4f\x78\x2a\x32\xcd\x18\x33\x8e\xc3\xfe\x0c\x2d\x6a\xdb\xda\x78\x42\xd2\x66\xe9\x32\xe5\x89\x3a\xcb\xff\x5d\x8f\x43\xa6\x42\x53\xe6\x6d\x67\x9f\xcb\xaf\x3f\x18\x2a\x43\xea\x06\xb6\xd8\xb4\x5f\xa1\x59\x57\x75\x8d\xca\x42\xc2\x6e\xaa\xda\x1a\x33\x8d\x1a\x4c\x32\xd5\xe8\x7d\xc0\x36\x8d\x82\x13\x7e\x1d\x9b\x4b\xba\x41\x2c\x09\x35\x75\xa8\x29\xcd\xaa\xe9\x6c\x77\x0d\x69\x8c\x82\x9d\xca\xcb\x17\xc3\xd2\x20\xb1\xcd\x5b\xb2\x37\xfb\x60\x02\xf0\x44\xe9\xa9\x9b\xf7\x86\x6c\xdd\xab\xf2\xe1\x64\xa1\xd0\x7e\xa0\x31\x54\x46\xef\x01\xac\xab\xba\xfb\x35\xfe\xb0\x40\x1d\xbb\xe0\x46\xe7\x8d\xae\xca\xfe\x47\x0a\xc3\xad\x65\x5e\x37\xe7\xaf\x73\x2f\x03\xcd\x25\x44\x9a\xb2\xe1\xdb\xea\xf9\x2a\xd7\xb6\xb5\x40\xe8\xe2\xdf\xc8\x61\x70\x09\x46\x93\xff\x48\xe9\xa0\xd8\x93\x89\x22\x93\x80\x5a\x43\x2d\xc2\xd1\x92\xe4\x86\x9d\x6e\xfa\xdb\x65\x12\x53\x93\xe8\x40\x3b\xde\xc3\x09\x4b\x22\xab\xba\xa3\x2a\x02\xdb\x52\xac\xca\x73\x63\x49\x7b\x03\x7e\x42\xaa\xd8\x26\x3e\xed\x5b\xb5\x6b\xf1\x34\x42\xd8\x48\x95\x58\x51\x50\xaa\xb9\x5b\xe9\xec\x65\x54\x83\x1b\xaf\xb3\x44\xb9\x5b\x47\xd2\xa0\x5f\xa1\x79\xb9\xcd\x65\xfd\xfe\xc7\xd8\x4b\x83\x4b\x0d\x56\xf4\x92\x8a\xf2\x1f\x80\x4e\x96\xbf\x01\x93\x80\x1e\xce\xf6\x7e\x02\xa3\x93\x08\x48\xa9\xe5\xcf\x9f\x9e\x70\xe6\xd3\x47\x69\xd2\xd0\xf8\xaa\x59\xd9\x62\x8d\x16\x45\xf4\x78\x2e\x73\x8a\x64\xa6\x5f\x60\x44\x48\x40\x33\x82\x56\x68\x54\x23\x19\xc0\xd9\x7c\x33\xc2\x52\xc2\x1a\xac\x73\x28\xec\xbe\xb2\x6d\xbe\x35\x53\x4a\x35\x57\x81\x64\xdc\xaa\x42\xb6\x58\x1f\x51\x5f\x36\x6c\x54\xa0\x15\x25\x96\xdb\xb2\x2a\xf3\xb9\xc1\xcd\x52\xc7\x40\x85\x88\xd6\x9b\x14\xf4\x31\x2f\x07\x4f\x94\x19\x5e\x4c\x45\x4e\xc8\xea\x19\xdb\xf5\x4b\x5e\xe8\x66\x89\xdf\xa2\xa2\xc8\x10\xc4\xaa\xbb\x2f\xeb\x22\x9f\xcb\xad\x70\x15\x65\x48\xc4\x50\xaf\x99\x3b\x9a\x24\x2a\x32\x9c\x34\x3b\xfd\x31\xed\xe8\x8f\xfe\x78\x12\x68\xa9\x2f\x34\x3d\xf7\x2f\x75\x75\x7e\x7e\x21\xbf\xb7\x7d\xf5\x3b\xbb\x7c\x7f\xaa\x84\x85\x83\x3c\xf1\xc4\x1d\xef\xa3\x4f\x28\xeb\xfb\xe1\xf2\xa1\x27\x04\x8d\xf5\x56\x2f\x17\x58\x55\xa2\xed\xca\xac\xb1\x51\xe8\xf4\x8f\x47\x8f\x29\x4d\x24\x15\xbc\x07\xad\x83\xfe\x47\xa6\x12\xe9\x55\x2d\xcf\xc7\x71\x12\xd8\xcc\x34\x83\xb9\xca\xc0\x50\x72\x44\x7a\x27\x55\x89\x4e\xee\x64\xf3\xef\xb1\x32\x13\x57\x19\x46\x64\xad\x70\x05\xd5\x0d\x96\xcf\xeb\x17\x1c\x71\x56\x3e\xc4\x84\x2a\x06\x01\x35\xd4\x29\x46\x1b\xf9\x14\x73\xc5\x8c\x2d\x2d\x59\x19\x7c\xec\x97\x3b\xc5\x43\xdb\x4f\xef\x96\x9f\x7a\x42\x0b\x53\x3c\xb6\xaf\x73\x9b\x63\x9d\x8c\x1f\x39\x67\x56\xd2\x96\x54\xf5\xdd\x76\x3b\x9d\xf4\x5c\x69\x22\x6c\x76\x09\xea\x28\x3a\x50\x22\x8c\xb8\x43\x5d\xdc\x85\xb3\x59\x28\x78\xe8\xa2\xc7\xd2\x9a\xb2\xce\x8f\xa3\xb5\xb0\x21\x46\x18\x5d\xe8\x47\x34\x17\x25\x53\xa0\xba\xd0\x86\xdc\x4a\x3e\xf7\x44\xe1\x4a\xc5\x9c\x18\x42\x25\x36\x2d\x6a\xb2\xb8\x59\x15\xc5\xbe\x5a\x15\x45\x34\x7b\x11\x48\xe3\xd5\xaf\x88\x37\x55\xdd\xef\x80\x4a\x27\x8a\x42\xbb\xa1\x3f\xd9\x1f\xc9\x2c\x73\xe5\xb9\x5b\x80\xba\x5c\xa1\xbb\xd5\xfd\xcc\xc1\x98\x53\xe1\x02\xb4\x26\x81\xcb\xbc\x7d\x9f\x35\x82\x16\xa3\x08\x85\x52\x5b\xf8\xaf\xd5\xe1\x1d\x81\xa3\x95\x11\x98\xba\xd4\xe4\x4b\x5d\x9d\x4f\x0b\x25\x4f\x65\x40\x50\xa2\x7c\xcc\xcb\xf5\xa8\x1c\x77\x38\x5e\xed\xd7\xfd\x79\x54\x46\xa5\x0d\xe5\x2b\x53\x1b\x32\x9c\xf6\xdf\xa3\x03\x30\x96\x1d\x56\x43\x5e\xe2\xaf\x41\x71\x83\xeb\x28\xb4\x3d\x20\x79\xae\xcb\x9b\x73\x69\x89\x3a\x8b\xaf\xa8\x8e\x12\x13\x8f\x35\x7f\x3d\x08\xe2\xb3\xd6\x9b\x8e\x32\xad\xc3\x91\x13\x1c\x39\xbe\xfb\x63\xda\x90\x5a\xc7\xb9\xc1\xfa\xea\xfc\x3e\x9b\x1b\x3a\x0e\xed\x4b\xde\xb4\x78\xda\xbf\x55\x7f\x4c\x2e\x26\x4e\xa4\x72\x99\x42\xb7\x79\x7d\xa4\x7b\xf4\x79\xa0\xa5\x63\x06\x13\x38\x38\x31\xfa\xfc\xe5\x25\xa9\x35\x50\x7e\x56\x9b\x52\x8f\xde\x0d\x4d\x1a\x5e\xb4\xbc\xa8\xfe\x4f\x08\xb4\x0c\x34\x6d\x55\x23\x65\x8a\x63\x6f\xd3\x79\xf5\x77\x32\x41\x74\x1a\x82\x65\xfc\x93\xb2\x5f\x0f\xea\x18\x27\x53\xfd\x3f\xfe\x23\x82\x51\x83\x18\x34\x69\xee\x38\x3c\xc8\xf2\x66\xaf\x53\x48\x55\xe0\x88\x04\x58\x36\xe7\x66\x11\x15\xa5\xb3\x20\xa0\xf0\x82\xc8\xa7\xce\xb9\xf6\xa2\xdb\xd6\x8f\xb5\xec\xa3\x1e\x90\x6a\xbb\x36\x8e\x08\x3b\x3f\x71\x62\xf4\x20\x36\x4d\xa1\x84\x77\xbd\x9b\x0d\x54\xe0\x35\x4d\xd6\x7d\xde\x75\x69\xe7\xc6\x35\xd3\x98\xc5\xde\x2e\xbf\x84\xb2\xfd\x48\xf0\x72\x7a\xa3\x79\x94\x51\x23\x63\x90\x29\x78\xac\x8a\x5c\xbd\x7b\x51\x81\x5e\x2a\x64\x36\x87\x79\xf7\x0a\x59\x01\xa3\x73\x5d\x5e\x55\x55\x81\x50\x8e\x8a\x45\x9a\x4b\xe9\xd9\xdd\x5d\xbc\xb6\xfc\x26\x88\x2c\x24\x09\x89\x2f\xd8\xf6\x6e\xfc\x5c\x0b\x88\x49\xfb\x73\xd2\x32\xfd\xe0\x05\x84\x80\x53\xf9\x76\x97\x17\xaf\x58\x8f\x48\x10\x1a\xc2\x94\x7a\x9e\x65\xa5\xf1\xd0\xe4\x7a\x56\x33\xd0\x90\xd9\xca\x3c\x49\x94\xda\x5a\xcc\xa8\x18\xa7\x41\xa4\x54\x75\xfe\x9e\xd7\xed\x19\x8a\x39\x89\xc9\x8d\x92\x49\x40\x68\x14\xdb\x7c\x99\x57\x6b\x5c\x3f\xfa\xa2\xe3\xf0\x29\x8a\xc0\xfd\x4f\xff\x05\xa9\xa1\xb5\xe8\x34\xb2\x4d\xe6\x5a\x2b\xab\x1d\xed\x52\xf1\xbc\x79\xc1\xfa\x0e\xca\xe6\x06\x71\xed\x4a\x1d\x73\xf2\x96\xd6\x5a\x51\x8d\xe4\x98\x97\x56\x0c\xd4\xfd\x1d\x03\xa5\xc7\x74\x88\xed\x85\xb7\xfe\x87\xf5\x0f\x6d\x30\x24\x10\x7d\xb7\xc9\xc6\xc4\x32\x74\x67\xc5\xc0\x79\xf2\xbe\x61\xbe\xae\x1a\xdf\x77\xed\x8f\x66\xb1\x33\x04\xdf\xfc\xfb\x9c\x9f\x50\xaf\xca\xf7\xe8\xf3\xc2\x29\x06\x2c\xd4\x56\x22\xb0\x7c\xbf\xb0\x71\xe4\x18\x98\x84\x34\x6c\xba\xe0\xea\x09\xf2\x66\x88\x47\x30\x0c\x0d\x71\xe5\x1e\xee\xbe\xac\x61\x2c\xe8\x80\x61\x04\xde\xd2\xae\xe7\x52\x4e\xc8\x22\x18\x02\xcb\x5c\x56\xe0\xfe\x6f\x3a\x8d\x30\x54\x21\xb5\xf5\xf2\x16\x8f\x8d\x05\xfd\x4c\x2f\x2c\x4a\x23\x82\x89\x5a\xd8\xc0\x5d\x5e\xe4\xed\xc0\xa0\xc4\x28\x95\xce\x7a\xa8\x9c\xdc\xa1\x88\x71\x2a\x9f\xdd\xc3\xb9\xcd\xd5\x79\x12\xdb\x60\xcc\xa2\x28\x18\xb6\xcf\x6b\x68\x71\xcc\x1e\xc0\x18\x02\x22\x5a\x1c\xcf\xc5\xe3\xb2\x29\xf6\x30\x90\xea\x1d\xbb\x16\x4a\x4d\x5e\xe5\xc7\x13\xe4\xcf\xe5\x47\x8e\x50\x8b\x6f\x31\x26\x18\x11\x02\x08\xbc\xee\xc6\xa3\x8b\xa6\xfd\xf5\xa4\x22\xf4\x6e\x03\xdf\xab\x76\xb9\x47\xe4\xd7\x71\x4c\x15\xa3\xb9\xfd\xf6\x52\x6d\x77\xbd\xf1\x43\xbf\xb0\x60\x16\xda\x94\xa4\x40\xd3\xce\x30\x30\x98\x65\x2c\x72\x0c\x30\x0b\x10\x72\xf1\xdd\xb4\xc8\x8f\x19\x47\x4a\xc4\x1a\xdf\xf0\xa1\xa6\xf2\xea\xdc\x7e\xc0\x5a\xc7\xcc\x51\xab\x29\xf0\x2d\xaa\x3e\x3b\x45\x96\x32\xea\x17\xa2\x72\xa4\xef\x6e\xeb\xd9\xe5\xcf\xcb\x31\x3a\xb2\x2c\xa5\x45\xba\x6f\xf9\x91\x6a\x76\xfb\x56\xd5\x3f\xe7\x1a\x71\x1c\x19\x84\x81\x5d\x62\x4f\xd6\x6d\xb3\xdb\x88\x7b\xb7\xf9\x45\xa9\x0f\xe4\x31\x93\xa2\x5f\x8f\xbe\xcc\x55\xf8\x39\x8a\x2c\xf5\x08\xe8\xbe\x89\xee\x59\x2d\x4b\x05\x76\x14\x26\xa4\x4c\x71\xf3\xf8\xcf\x79\x69\x12\x41\x30\xf2\x5a\xec\xbd\x46\x1e\xe1\xdc\xa0\x9e\x1a\xdf\x71\x04\x48\x6c\x57\x01\x0c\x6e\x7e\x9d\x3e\xb8\xc7\x20\x03\x12\x80\x35\xd5\xb9\x6e\x5f\xf6\x08\xc7\x1f\x3d\x21\xad\x3f\x13\x4a\xa2\xc5\x5c\x3d\xae\xd7\x9f\x45\xc5\x28\x59\x46\x71\x0a\xb4\xed\xc8\x4b\x96\xa3\xe2\x10\x28\xdf\x58\xb7\xfe\xf8\x54\x20\xec\x1f\xa8\x0e\x05\x09\x35\x0e\x0c\x78\x13\x86\xc3\x41\x6b\xdc\x7f\x5b\x55\x3f\xbf\x9d\x7a\x50\xc0\x75\xfe\xba\x9d\xa7\xa5\xa8\x63\xa4\xa7\xd7\xed\xfe\x59\x18\xf4\xa7\x10\xbd\x8b\xbf\xc7\x99\x4f\x6f\x83\x96\x86\xf0\x8f\xbb\x3f\x3d\xf0\x08\x4d\x94\x50\x86\xed\x94\x6e\xe1\xac\x70\x9a\xb1\xa0\x49\x2d\x3c\xf4\x9b\x93\x98\xc9\xcb\xd6\x65\x6e\xa3\x17\xc7\x64\x8c\xca\x35\xdf\x4e\x55\xdd\x5a\xff\xc8\x79\x2f\xc4\x04\x69\xc8\xd9\x6f\x34\x9a\x6c\x15\x6f\x72\xd5\x26\xe0\x11\xc1\x42\x35\xbc\x93\xec\xce\x74\xc1\x32\x81\xe4\x7e\x9d\xf5\x35\x6c\xca\x23\x06\x5f\x45\x37\x30\x8c\x13\x22\x94\x13\x4f\x66\x87\xed\xf9\xd4\x1f\x41\xa1\xbc\x35\x78\x8f\xd3\xcc\xab\xf2\xba\x52\xe7\x89\x3f\xde\xf4\xc2\xa2\x40\x10\x20\x45\x8f\x12\x5b\xaf\xca\xea\x87\x84\x16\x48\xfc\xb8\x79\x3a\x7c\xdb\x6d\x9e\x0e\xab\xbb\x87\x6f\xf7\xfb\xfe\x70\x14\xca\x6c\xd4\x11\xac\xdb\x12\xeb\x59\xfa\x67\xe2\x2c\x4c\x12\x9f\x5d\x3b\xd8\xb9\x3f\x84\x99\x71\x55\x8c\x1b\x9a\xda\x2e\xd4\x9c\xc2\x87\x4c\x9a\x08\x2a\xdf\xda\xea\xdf\x65\x27\x91\x4f\xc0\x6d\x26\xcb\x12\x42\x50\x1f\xbb\xbd\x9a\xe4\x53\x5e\x30\xaf\xa7\xb5\xad\x30\x9a\x7f\x48\x44\x54\x82\xf8\x6b\x73\x7b\xfb\x8f\xd5\xce\x77\x0a\x0d\x33\x11\xf5\x8f\x35\x54\xbe\x45\xe6\x8e\xf0\x18\x2d\x86\xce\x93\x4e\x56\x96\xf6\xbc\xb8\x11\x18\x6e\x90\x70\x33\xa6\x7c\x5d\x7e\xc9\x8d\x08\x39\xda\x35\x8d\xee\xd4\x2d\x9a\xb6\x5b\x35\x37\xfd\xda\x6c\x44\x6a\x29\x1a\x4e\x2e\xd1\xd6\x9a\x6e\xaa\xfa\x72\xcb\x37\x02\xa3\x24\x73\xdd\x69\x6c\xda\xed\xf1\x54\xac\x17\x82\x34\x03\x32\xa2\x8e\x2f\x1e\xf3\xd6\x01\xbb\x96\x82\x72\x23\x59\x4c\x11\xe3\xf6\x7e\xff\xb4\x79\xdc\x5e\x1f\xee\x56\xff\x3c\x10\x9e\xc3\x5f\x9c\xca\x32\x8a\x6a\xee\xff\x73\xbc\x9d\x4c\x70\x25\x13\xef\xc5\x61\x25\x0e\x5c\x1a\xdc\x05\x1b\xeb\xcb\xa2\x95\xd1\x92\x13\x90\xf8\x64\xa7\x53\x39\x4a\xaa\x0d\x62\x16\x58\x33\x80\xfc\xd4\x56\x2f\x67\xa9\x86\x88\xc5\xa0\xd1\x54\x3b\x6b\xce\xa7\xee\x35\x6e\x26\xd0\xbc\xe5\xa7\x82\xc6\xba\x1b\x5a\xd7\xd4\x2f\x35\x62\x3b\x88\x88\xba\x31\x26\xb0\xd1\xae\x05\x74\x7e\xb3\xcf\x6c\xda\x7d\x30\x26\x50\x09\x73\x9b\xe0\xcd\x6c\xe7\x35\x26\x8c\x69\xe1\xa8\x49\x18\x79\x7e\x2c\xb5\x3e\x99\x04\xf0\xbd\x9b\x28\x07\x19\x13\x07\x54\x4e\xbd\xaa\x11\x7e\x9e\x4f\xf3\x8f\x66\xd6\xa0\x03\xac\x87\x95\xc6\xb2\x9a\x52\xeb\x44\x10\xa4\x11\xad\x7d\x36\x42\x26\x75\x8e\xf3\xcc\x28\x41\x04\x01\x8b\xa9\x09\xbd\x5e\xaf\x9f\x2e\x5c\xf4\x45\x10\xc8\x84\xba\xc8\xb6\x02\x3d\x61\x8d\x5c\xb4\x29\xe6\x5a\x58\xff\xeb\xce\x11\x82\x65\x4b\x28\x28\x77\x2f\x58\x98\x25\x94\x94\x08\xa2\xc0\x92\xb6\xad\xca\xdb\x60\x74\xea\x0f\xeb\x90\x02\x04\xe7\x9f\x47\xf1\x24\xa1\xec\xfb\x01\x98\xc0\x60\x6d\xb2\x3b\x93\xda\xfe\x71\x66\xf7\x22\x82\x98\x31\x70\x74\x9e\x91\x55\xf7\x6c\x8c\xb2\x88\x25\xfa\xfc\x65\x0d\x7b\x3a\x38\x09\x45\x10\x0f\x98\xe9\x3f\x46\x49\x8a\x08\x92\x44\x51\xcb\xfa\x54\xe3\x31\x9f\xb0\xf7\x44\x90\x86\xca\xe2\xf9\x5f\x6a\x6c\x5e\xaa\x42\x47\xfd\x91\x54\x43\x34\xf8\xe6\x78\xa9\xfb\x6e\x85\x1d\xc6\xa8\x94\x5e\xdd\x43\xde\x74\x0b\xc0\xb6\xa4\x2f\x9f\x5e\x5a\xaa\x18\xad\x3a\xb4\xa5\x42\xf9\x91\x40\xf5\xdf\x16\x64\xff\x20\xe8\x75\xdf\x96\x85\x5c\x5b\xa5\x66\x4f\x3b\xbc\xaa\xab\x79\xde\x2e\x82\x4c\x43\x88\x5e\x4e\xe3\xd7\x88\x32\x22\x02\xa6\x74\x60\x29\xc5\xb2\x51\x75\x2e\xff\x9e\x24\xa6\x08\x78\x94\x92\x98\x1a\xf5\x88\xac\x54\x93\x4f\x8e\x6d\x6d\xeb\xbe\x6a\xfd\x1f\x06\x00\x46\xf7\x39\x49\x16\xf9\xfb\x1f\x0f\x87\xbf\x36\xab\xa7\xc3\x9f\x9b\xcd\x63\x2f\x6a\x21\x02\xae\x6d\x67\x0b\x8a\x62\xa4\x4c\x3d\x42\x09\xbb\x71\x10\x47\x54\x5e\x3a\x4e\xd5\x72\xfc\xd1\x2c\x25\x24\xf0\x63\x71\x6e\xab\xf2\x12\x4c\xd4\x8d\xd0\x94\x05\x34\xd8\x8e\xdc\x8c\xc6\xf2\x75\xf3\xdf\x3f\xfd\x06\x99\x18\x6a\x92\x76\xcb\xe1\xea\x19\x07\xb3\xf5\xd5\xe7\xa5\x77\x11\x48\x63\x9d\x4e\x2d\x97\x73\xf2\x30\x54\xca\x8d\xd7\x56\x26\x02\x6d\xb5\x18\x48\x88\x40\x29\xa4\xa2\xc4\x4d\x5e\x7a\x25\xdb\x91\xcc\xb0\x3f\x9d\xce\x34\xa1\x0e\x9f\x90\xf4\x29\xdc\x5f\x31\x4a\x69\xb5\x5f\x27\x37\x9b\x46\xd5\xd5\xdb\x87\x5c\x80\xf3\x05\x82\xa5\xfb\xb4\xa4\x19\xd7\xe5\x27\x05\xf6\xb7\xd3\x04\x11\x03\xaf\x3a\x94\xff\x67\xe0\xaf\xfd\x4f\xc4\xfd\x9a\x64\x32\x2b\x50\xfe\x50\x2f\x26\x24\x22\x30\x2a\x26\x53\xae\xd7\xaa\x45\xfd\x67\xae\x7e\x56\xc6\x2c\x2a\x99\x8a\xc0\x68\x69\xe9\x9c\xbe\x15\x92\x3b\x20\x58\x8f\xbb\x5f\xa0\xda\x8a\xc0\x20\x24\xda\xbb\x5d\x8c\x6d\x06\x97\x9f\x55\x18\x24\x29\x95\x65\x6e\x73\xd3\x05\x80\x87\x20\xf0\x8b\x41\x18\xb1\xc4\xae\xf4\x36\xed\x1d\x4b\x60\x0e\x9d\x0e\x11\xc6\xa9\x0c\x4c\x9f\xd4\xaf\x8a\xe7\xaa\xe9\x0f\xb1\x38\x72\x1a\xea\xde\x41\xed\x38\x60\x11\x3e\x7a\x18\x7d\x0c\xdd\x9d\x40\x2a\xbb\xfc\x92\x12\xd7\x41\x91\xb8\xb8\x3f\x88\x16\x70\xb5\x29\xb1\x7e\xce\xc7\x11\xb0\x08\x93\x24\xa3\x1e\xf3\x0f\x68\x7e\x07\xbc\x17\x61\x62\x24\xc1\x56\x1c\xb5\x6d\x94\x07\x4d\xee\x6d\x98\xa2\x15\xd2\xb4\x2d\xa5\x83\x9f\x97\x07\x6c\x5f\x0e\xaf\xa3\x45\x38\xcc\x12\x49\x1d\x0d\x5b\x83\xb8\xce\x49\xea\xd1\x1d\x63\x31\x23\x1f\x8d\x5c\x55\xb1\xf2\x8e\x2d\x22\x64\xa9\x70\x6c\x4a\x6a\x68\xec\xdf\xf0\xc2\xb7\x6d\x14\x41\x88\x90\xa9\x98\x40\x79\xab\xf5\x7a\xf3\xb8\xdf\x5c\x4f\xa2\x68\x11\x72\x9d\xd2\xbd\xa1\x0c\xfa\xaa\x2a\xf5\x63\xd5\xdd\x88\x55\xa9\x1f\x5e\xb1\xbe\x83\x7f\x55\x75\xaf\xa6\x29\x42\xc8\x42\xaa\x7a\x3e\x6d\x6e\x36\x4f\x4f\xab\xdb\xc3\xd5\xc3\xfd\x37\x12\xe7\xbf\xdb\xde\x7a\xed\x3a\x11\x02\x13\x41\x32\xef\xce\xed\xab\xe5\x09\x1c\x82\xc4\xc0\xae\x3f\x64\xd7\xec\xb0\x7d\x7f\x4c\x6f\xbd\x0c\x6c\x97\xae\x29\x4f\x72\x7e\x88\xab\xc4\xf5\x62\x7f\xac\x9e\x3e\x94\x0b\x17\xa1\xe2\x48\x35\xd5\x21\x87\x84\xcc\x5f\xb2\x32\x2a\x54\x83\x5d\x16\x39\x9d\xf4\xf9\xf2\xf4\xfb\x74\x1a\x11\x73\xe4\x74\x97\xf7\x20\x7a\xff\xcb\x3e\x59\x36\x46\x27\x60\xa9\x19\x2b\xe9\xd3\x97\xf4\x32\x01\xea\x85\x9a\x6c\xa3\x1a\xb9\x0f\x65\x42\xad\x0c\x0a\x4f\x35\x19\x3b\x97\x89\x10\x03\x4d\xeb\x25\x29\x23\x8c\xde\xc0\x66\xdc\x88\xe9\x07\xa7\x29\x21\x7e\xbe\xac\xee\x36\x87\xf5\xc3\xae\x9f\x0d\xc8\x12\x6a\xbe\xfc\xb5\x5d\x7f\x5d\x6d\xef\x87\x92\x9c\x08\x11\x65\x6c\xe7\x74\xb7\x82\xda\xb2\xb4\x3f\x66\x74\x94\x0d\x24\x74\xaf\xda\xb6\xb8\x5b\x44\x41\xa0\x99\x6b\x6a\x52\xbe\xf9\x70\x6e\x55\xd5\x47\xd9\x22\x0a\x18\x0f\xed\xb5\xed\x7f\xd3\x63\x13\x51\x00\x9a\x60\xb0\x77\xef\xdd\x7e\x9f\x9f\x8f\x17\xea\x57\x9f\x3f\x89\x28\x30\xd6\x5f\x7a\x87\xed\xd7\x6a\x5a\xe7\xe9\x52\x32\x25\xac\xd8\x9a\xb5\x10\x87\x16\x89\x48\xf3\xa1\xdb\xb6\xff\x1c\x08\x12\x24\x7a\xce\x5f\xf1\xce\x3f\xa0\x28\x54\x08\x63\x8a\xf1\x0d\xe2\x38\x80\x8c\x42\x0c\x13\xd6\xb3\xa4\x7f\x60\x3e\x2a\xd7\xcd\xce\x6f\x04\xcd\x82\x55\x59\x95\x4f\x78\x9a\x7b\xf7\x8a\x28\xd2\x89\xb5\x35\xb7\xa5\xaf\x69\x2d\x41\x44\x71\x98\x0a\xe2\xac\x62\x37\x8b\x0a\xf2\xb3\xac\x9b\xab\xf7\x5d\x09\xa7\xe6\xa5\x72\x7d\xc6\xe9\x29\xe3\x50\x46\x7c\xd0\xb1\x82\x8f\xcc\xfd\x45\x14\x0b\x0c\x83\x7e\xed\x23\xc2\xf8\xcc\x32\x45\x44\x49\x1c\x50\x35\xe1\x3a\x6f\x9a\xaa\xa0\xa9\x49\x6c\x07\x87\xc5\xeb\x97\xf5\x28\xd1\x31\x55\x30\x9f\xb0\x39\x55\xe5\x32\x4c\x5b\x44\xa9\x93\xaa\x5a\x12\xb1\xf3\xff\x4e\x9e\x6c\x9a\x70\xaa\xb8\x98\xbc\xc6\x85\x28\x3d\xca\x02\xeb\x90\x50\x5e\x6f\xfe\xe9\xaf\x39\x8b\x12\x6e\x3c\x61\xbf\x69\xb1\xbc\x6c\x39\xf9\x91\x49\x40\xe9\x2a\x55\xf3\x87\x1c\x51\x44\x59\x66\x9c\x0a\xf5\xaf\xab\x5c\xf7\xb9\xb5\x88\x98\x49\x68\x61\xb2\x8a\x51\x87\xa9\x58\xd3\xf2\x6f\xe6\xa9\x4c\x79\x5f\xba\x25\x67\x20\x9b\x63\x93\x58\xa5\x1b\x04\x52\x59\x07\x08\x92\xcc\xdc\x36\xbd\x06\xed\xa5\xa0\xa2\x88\x64\x2c\x0d\x73\x1a\x00\x96\xd9\x0d\xa7\xc7\xc1\x8a\xdb\x8f\xca\x98\x2d\x3b\x76\xc1\x9a\xae\x54\xff\x77\xae\x69\x11\x7e\x7c\x18\xbb\x42\x8b\x48\xea\x88\x65\xbe\x4f\xdd\x62\xfd\x0a\x45\x7f\x2e\xe5\xdc\xff\x7b\x14\xe8\x3d\xbe\x2d\xa9\xd2\xf8\xe1\xcc\xc2\x7a\x9b\xb7\xfc\x84\x93\x2f\x51\xc2\xae\x19\x58\xb6\xf5\xfb\x98\x49\x3b\xcb\x0d\xfd\x70\x97\x98\x74\x19\xf1\x64\x5e\xe8\xc0\x8a\x71\x9c\xcb\x91\x6d\x15\xf7\x07\x35\x04\x56\x9f\x80\xf6\xdc\x49\x7e\x18\x61\x1c\x53\x57\xcd\x23\xfd\xd3\xc7\xba\xfa\x17\xaa\x76\x72\x99\xe8\x08\x10\xd7\xeb\xcd\x7e\x7a\x00\x15\xdd\x08\xcb\xc1\x7e\x30\xa6\xf0\x42\xe3\xfd\xbd\x32\xa1\x95\x5a\xef\x61\xdc\xeb\xea\x78\xcc\x9b\xc1\xea\x58\x44\x86\x33\x82\xe5\xb8\xfc\x85\xf0\x69\xbb\x89\x6d\xb9\x1f\x28\x63\x62\x31\x19\xc4\x81\xef\xfd\xde\x9f\x06\x81\xea\xbd\x07\x5b\xd6\x7c\xc4\x0b\x1d\xa3\xbf\x9b\xb1\xd9\x13\xc6\xa1\x8c\x65\x32\x08\x5c\x1d\xe2\x60\x72\xd7\xe3\x08\x2c\x77\xed\x5c\x56\x5d\x5a\xfd\x58\x40\x89\xb3\x25\x2d\x8e\x94\xe5\xfb\xda\xf5\x67\x9c\x6c\xce\xbe\x2c\x32\x31\x59\x8a\xdd\x57\x63\x73\x3c\x11\xc7\x81\x92\x7c\xd4\xea\x58\xbe\xd4\x38\xb2\xac\xbc\x7e\x46\xda\xa7\x7c\xd1\xb1\x5f\xfe\xee\x38\x8b\x92\xd4\x8b\xe5\xb4\x1e\xa0\xe6\x0f\x32\xcb\x41\xa7\x2c\x11\xca\x75\x51\x95\x48\xd8\xe9\xa9\x5a\xad\x88\x63\x61\x28\x4c\xbe\x76\x70\xcd\xe9\xda\x14\x27\x49\x4a\xfb\xf0\xfe\x71\x3b\xf9\x81\xa9\x8c\xa9\x1c\xfa\x78\xed\xb1\x16\x22\x4e\xd1\x62\xc2\x7d\x0b\xf1\xee\x7d\xa4\xcb\x29\xe2\x2c\x54\x04\xee\xed\xe2\xa1\xa1\xcf\x3c\x5a\xa8\x63\xc6\x02\xe5\xa2\x22\x7f\x99\x6e\x46\x0d\x8b\x74\xcc\xb3\x44\x58\x41\x8e\xea\xb4\xe9\xf6\x9b\xf6\xa5\x6f\xf2\x75\x47\x4d\xe4\x16\x80\xa2\x5b\x37\xf5\xb6\xc5\x63\x7f\x09\x22\x8d\xb5\xf3\xfd\x7e\x78\x2b\x27\x3f\x48\x08\x2b\x60\x76\xcc\xcb\xfc\x78\x3e\x5e\xe5\x7a\x4c\x9c\x12\xb1\x90\x46\xe3\x50\x65\x44\x7d\xf5\xde\x1f\x52\xc8\xbb\x07\xb1\xbe\x5d\xed\x76\x87\xab\xcd\xaa\x8f\x70\x62\xc8\x12\xf2\x25\xde\x39\x62\xb3\x45\x6b\x3f\x55\x1f\x84\x0c\xdc\x7f\x8c\x45\x96\x0e\xd9\x56\xa7\xab\x73\xff\x45\xc0\x35\x85\xae\xd4\x68\x99\x04\x64\xb1\x8c\x38\xb9\x70\xa0\x6b\x50\xdf\x57\xc7\x9c\x80\xa1\x5f\xe1\xf5\x75\x14\x32\xfa\xe1\x4a\x51\x9a\x4e\x56\xa8\x77\x79\xd3\x38\x7b\x0e\xab\x47\xb0\xb8\x8e\xc5\x0a\xe2\xd0\xb6\x80\x56\x7f\xad\x6f\xbf\x5d\xfd\xd1\xff\xdd\xea\x96\xda\x5a\x94\xb5\xa2\xa7\x46\xda\x52\x54\x1c\x6b\xa9\x29\x41\x20\x5a\xc9\xa6\xd4\x97\x95\x9c\xd8\x70\xed\x04\x9d\x40\x1f\x34\x1e\xcf\x75\x0d\xcf\x78\xb0\xf1\xeb\xe1\x5c\x6a\xac\x8b\xf7\xd1\x33\x37\xca\x7a\x54\xb4\xf0\xab\x5b\xcf\xef\xcf\xc7\x31\xaa\x5c\x24\x41\x6c\x35\x27\xf2\xe6\x11\xba\x5f\x3a\xbd\x17\x49\x90\x68\x5a\x0e\x47\x6a\xc7\x61\xdc\x7f\x36\x4d\x6c\xf0\x4c\xab\xd3\x7d\xd5\x2e\x29\x91\x89\x24\x60\x30\x14\xfe\x6d\x65\x61\xf6\x25\x8a\x93\xeb\x44\x73\x3e\x3a\xe3\x62\xfb\x48\x3c\x53\x51\x24\x61\x86\xf4\x3a\x3f\xad\xaf\xfd\x97\x87\x3a\x20\x32\x38\xea\xbc\xf5\x6a\xc1\xa8\xe7\xa8\xa2\xe1\xdd\x48\x42\x1d\x11\x67\xe3\x44\xcd\xeb\xed\xfe\xe1\xd0\xcc\x82\xa1\x24\x0a\x18\x9d\xd3\x4e\x93\x3e\xa7\x94\x33\x3a\x97\x48\x22\xd6\x37\x6b\x9e\xe1\x88\x5d\x8a\xeb\xbe\x71\x3e\x10\x98\x57\x1c\xe8\x12\xe9\x2b\x28\x67\xe1\x5c\x12\x47\xd6\x9f\xe9\xe4\x5f\x81\x6e\xaf\xf8\x9a\x37\x17\x2c\x1c\x91\xc4\xb1\x48\xba\xe9\x41\x4e\xdb\xd8\x9b\x5a\x8c\x5e\x8e\x24\x4e\xad\x12\xf9\x5b\x2f\xf9\x76\x3e\x9d\x8a\xbc\x5f\xd2\x92\x98\x45\xa1\x6b\xd6\x53\x85\x9f\x7e\xdc\x64\x2e\x27\x49\x20\x45\x17\xb3\x76\x8f\xfb\xae\x6c\x4f\x7e\xb9\x19\xaf\x34\x49\x12\x1a\x72\x56\xbc\xdb\xde\x1f\x36\xfb\xaf\x9b\xa7\xc3\xfa\xe1\x7e\xff\xe4\xbf\x26\x85\x94\x59\xf0\x4e\x5e\xe8\x3e\xd6\x59\x5c\xab\x93\x2c\x0e\x88\x15\xfe\x78\x2e\x0a\x8f\xed\x2f\xba\xf9\xfd\x3e\xc7\x58\x5f\x56\x1b\x92\x2c\x96\xa4\x90\xb0\x43\x2c\x26\x91\x48\x92\xa5\x40\x8c\x29\x87\x1f\x82\x9f\x58\x5f\x23\xe8\x62\x2e\x7e\xdd\x8d\xb4\xa2\x8b\xdd\x24\xb7\x10\x78\xec\x4b\x7a\x49\xa6\x52\xe6\x7a\x53\xf6\x46\x54\xf5\xf1\x2e\x2f\x71\x5b\x5e\x5f\x6a\xc9\xcc\x7f\x19\x46\x4e\x03\xa2\x51\x67\x5c\x43\x3b\xbb\xd3\x4c\x71\x6f\x60\x70\x43\x5e\xc2\x17\x96\x0e\x82\xbc\x56\xc2\x01\x1c\xff\x58\xe7\xaf\x79\x81\xcf\xfd\x9c\xe5\x49\x42\x3f\xd3\xa9\x31\xdc\x57\xbb\x32\x3f\xf5\xe2\x0a\x22\xe1\x2a\xd2\xd2\x7b\x42\x27\x87\x91\x0b\x8d\x48\xb8\x16\xb6\x91\x9a\xab\xab\x6a\x36\xd9\x38\xa6\xb4\xa2\x39\xaf\x89\x25\xda\x9e\x1b\x29\x04\x86\x89\xd7\xc5\x22\x9e\x69\x98\x4e\xc2\x8a\x44\x68\x41\x2a\xa5\x12\xca\x9f\xa4\x9e\xdf\x6d\x10\xd3\xaf\x03\x65\x8d\x0c\x6e\x1f\xf6\xfb\xcd\xd3\x5f\xfe\x0a\x65\x62\xed\x44\x0e\xf6\x29\x4e\x32\x84\x69\xac\x9f\xc8\x14\x03\x97\x15\x8c\x88\x6c\x8b\xbc\x44\x91\x48\x11\x58\x8d\x1e\x84\xe3\x63\x55\x15\xd3\xd0\x3a\x91\xc6\x42\xbe\x06\x5d\xfc\x71\x45\x34\x51\x11\xd0\x57\xed\xf6\xff\xb8\x48\x73\x07\x30\xd0\xec\xfa\x94\x89\x63\x0f\xa4\xb1\x07\xbe\x6d\x89\xbd\x77\x9a\x1b\xc4\x74\x63\x55\x36\x96\xe9\xfe\x20\xc3\x4b\xb4\x88\x1d\xf9\xb4\x39\x17\xed\x41\x0e\xb0\x54\x91\xa0\xeb\x96\x3a\xd2\xbb\x6d\xb6\x75\x6b\x9a\xef\xaa\x8e\xb0\x0c\x61\xd6\x7f\x48\xd2\x6b\xdd\x25\x8c\x9f\x4a\xb6\x8a\xc4\xc8\x8c\x80\x24\xbb\x99\x58\xea\x52\x01\x6c\xba\x21\x18\xb4\xbe\x6a\xd8\xb4\xf9\x11\x5a\x9c\x54\xc2\x27\x37\x22\x0d\x64\x4c\x89\x3f\xfe\xc2\x5a\xe5\x8d\x6d\xb6\x7f\x1a\xe3\xa6\x21\xb3\x85\x3c\xd0\x7a\xe7\x32\xda\xbf\x73\x6d\x93\x4b\x4c\x43\x08\xb9\xf1\xd0\x58\xaa\xa4\xf6\x65\xbf\x34\xe2\x42\xa2\x97\xe9\x68\xce\x4b\xa2\x72\x22\x8d\x74\x44\x2c\xbd\xa2\x7a\x7e\xac\xab\x63\xde\xe0\xb7\xd2\x9c\x0b\x93\x17\xc5\x78\x3f\x59\x0e\x5f\xd3\x58\x5a\x08\x4a\x6e\x0d\xa7\xac\x88\x14\x55\x3e\xfc\x45\xa4\x81\xce\x6c\x0d\xe3\xbd\x5b\xda\x3e\x74\xf9\x16\x69\x0a\x8c\x24\xbd\x7b\x0e\x81\x57\xa4\xea\xd1\xd5\xfd\x39\x4d\x44\xa2\xcb\x53\xa4\x9e\x65\x89\x4d\x5e\xe8\x34\x73\x51\xc5\x91\x14\xa9\x87\x70\x23\xcd\xd0\x1a\x15\x68\x3c\x15\xd5\x32\xc3\x53\xa4\x2c\x88\x08\x2a\x74\x00\xad\x7d\x61\x45\x7f\xd4\x55\x48\x59\x6c\x9d\x12\xda\x67\xdc\x61\xdb\x7d\x59\xe3\x5a\xd8\xcb\xbf\x97\x87\x19\xe5\x38\x57\x0f\xdf\xee\xf7\x7f\x39\x63\xe9\x69\xa9\x35\xe5\x51\x4a\x31\xe4\x76\xfd\x70\x78\xb8\x1f\xfe\x0a\x84\x19\x1b\xf4\x29\x9d\x31\xf4\xe7\x13\x8e\x83\x24\x1f\xb6\xe6\x2d\x6f\xd5\xcb\x0d\xa2\x85\x87\x8e\x76\xcb\x94\x83\x42\x4b\x6c\xa0\x98\xe3\xb2\xbd\x9a\x8a\xd8\x50\xaa\x67\xd1\xbc\xe3\x77\x33\x4b\xa6\x58\xde\x69\xe4\x99\x8a\x0c\x32\x2f\xaa\xe9\x32\xdd\x4f\x6a\xd0\x5d\x6a\x42\x2b\xc6\xed\xce\xb6\x59\xa6\x8a\x29\x22\x95\x52\x81\x67\x59\xdd\x23\x6a\xd4\x83\xb9\xa9\x1f\x4b\xf8\x8b\xd1\xbc\x91\x26\x22\x8a\x67\x41\x08\xb2\x07\x33\x9d\x2b\x2a\xcc\x98\xed\xe5\x79\xb5\x13\xbf\xcc\xa6\x2a\xe5\x22\x1c\xb9\x88\x0d\xba\x9d\x56\x1e\x79\xd0\xaf\x14\xa9\x12\xb6\x3a\x7e\xcc\xcb\x4d\x91\x3f\xe7\x63\x6f\x29\x91\x2a\xa5\x08\x9e\xf1\x63\xb3\xe9\xf2\xaa\xb1\x1e\x9a\x48\x75\x1c\x29\x69\x43\xac\xfe\x4f\x4c\x46\x56\x5b\xb8\x52\xd8\x34\x3b\x55\x8d\x84\x52\x26\x97\xaf\x4d\x28\x28\x81\xe9\xf6\x2d\xd5\x6e\xa0\x2e\x47\xf3\x1d\x43\x49\xda\x76\xd8\x6d\x0f\xf6\x8e\x4e\xb7\x92\xd4\x88\x5e\xb6\xd5\x63\xb4\xa9\xca\xd7\xfd\xc7\xb1\x84\x16\x6b\xf1\xa9\xc1\x28\x95\x93\xca\xfd\x45\xb4\x31\x4a\x6a\xb3\x20\x32\x44\x0a\x78\x38\x4d\x80\x45\x22\x0b\xb2\x84\x1a\x05\x64\xb8\x39\x41\xdd\x46\xbc\x1f\x62\xf9\x6d\xf7\xf9\x4b\x5e\x78\xa1\x27\x91\x05\x80\x14\x6f\xfa\xfa\xb0\x15\xdd\x1c\x62\x8b\x2c\xd0\x91\x74\xdb\xd4\x2d\x94\x7a\x6f\x73\x8c\x69\x00\x93\x85\x11\x47\x2b\xfc\x54\x35\xdd\x8a\x33\xb9\xb8\x30\x41\x9a\x01\x79\xf3\xe4\x5a\xc5\x97\x31\xfc\xe4\xb6\x64\xa1\x4c\x3c\x3c\xed\xc9\x86\x44\xae\x22\xdc\xe7\x34\x59\x04\x40\x6b\xa3\x76\xba\x81\xa8\x2f\x7d\x2a\xba\x51\x32\x08\x67\xa9\xd9\xa5\xb4\xcf\x14\xc2\xde\x7d\x4a\x53\x64\xe0\x9d\xb3\x8a\xe7\xaa\xff\x5a\x29\x32\x17\x29\x3e\x9e\x4f\xa7\x2e\x1a\x1a\x72\xe4\x2c\x0e\xb4\x1e\x32\xc1\x7f\x74\x51\xee\xc5\x76\x97\xc5\x69\x18\xa3\x2d\xb2\x62\x3d\xae\x0e\x4e\x87\x25\xc2\x10\x0d\xa8\x97\x67\x2f\x8a\x71\x35\x21\x4b\x8d\xe2\xc2\xe3\xa9\x6a\x83\xf9\x1c\xc8\x23\xb2\x2c\x34\xca\xf8\xb0\x30\x9a\x14\xb8\x32\x16\xea\xc8\x71\x89\x6c\x9e\xbf\xab\x0a\xfd\x88\xb5\x83\xfd\x4e\x6f\x23\x64\x82\x24\x10\x1d\xa7\x78\x75\x1e\x99\xb6\x88\x4c\x6a\xab\xff\x40\xce\xe6\x87\xf3\xe9\xa0\xf3\xd7\x9c\x2a\x65\x93\x2e\x8d\x1f\x8d\x11\x5d\x14\xb4\x8b\x46\x4b\x22\x53\x89\x01\xdd\x37\x74\x15\x5e\x2a\x21\x89\x4c\xa5\xa0\xb9\x45\x53\x54\x6f\xcd\x8f\x17\x2c\xbf\xd8\x6d\xc3\xfe\x48\xd2\x46\xb2\x52\x23\x03\x96\x5d\x64\xd8\xe5\x87\xff\xe7\xff\xf9\x3f\xff\x3e\x57\x2d\x10\xc9\x6f\x7a\x56\x23\x91\x00\x3a\xf4\x36\x9e\xaa\xba\x05\xe7\x97\xeb\x04\x3f\x86\x14\x2b\x33\x4a\x30\x67\x43\xb3\x4e\x6e\xfa\x6d\xd4\xbb\x57\x2c\x4f\x6b\xa3\x23\xc2\x87\x6c\xd7\x0f\xb6\x46\x7f\x61\x5a\x2a\x58\x60\x24\xd1\xdc\xa1\x3e\xc2\x33\x6a\x1c\xa6\x8f\x9f\x9e\x2c\x0c\x23\xa2\xb0\xad\xa1\xbd\x60\x05\x2c\x6e\xaf\x2c\x8c\x79\x18\x3a\x09\x3b\xac\xc7\xbc\x45\xc1\xc2\xc4\xaa\xdc\x90\x96\xe3\x9f\x79\x51\xcc\x76\x0b\x16\x66\x86\xfa\x6f\x55\x9d\x3f\xe7\x25\x14\xb4\x8a\xff\xc0\xfc\xf9\xa5\x1f\x12\x47\x56\x45\xae\x3a\xb7\xa7\x73\x9b\xcf\x7e\x52\x9c\x30\xb2\x4b\x39\x10\x03\xa6\x3b\xfd\x18\xa7\x38\x83\x58\x2f\xbe\x0c\x2c\xd6\x92\x3a\x18\x44\xd5\xdf\xec\xbf\x1e\xd6\xdf\x36\xfd\x97\x6b\x5b\xbe\x38\x97\x54\xbc\xd8\xfc\xb2\xc5\xc3\x59\x9d\x8f\x25\x61\x40\x6d\x18\x4b\xb6\x6c\xb0\x3d\x74\xff\x9e\xe0\x7d\x76\xb5\x09\xb7\xd0\x4b\x82\x5a\xd9\x72\xd0\x02\x1a\x81\x25\x60\x28\xe9\xef\xf6\xd0\xc7\xb3\x2c\x72\x35\xe0\x0e\x02\xff\xa4\x12\x69\x35\x9c\x74\xf5\x56\x16\x15\xe8\xfe\x5a\x34\x70\x17\xbe\xfe\xa8\xea\x09\xd7\x54\xb0\x34\x92\x60\x49\x0d\x75\x55\x56\x57\x50\xfe\x7c\x2c\xa0\xed\x52\x52\xff\xf1\x34\x95\x14\xed\x91\x8b\x3a\xa9\xf5\x38\x55\xa7\x64\xf6\xdc\x53\x6d\x15\x62\xa4\xdd\xde\x1f\xcc\xb8\x05\xc6\x52\xe4\x22\x9e\xee\x5a\x16\x75\xa9\x57\xed\x32\x4e\x82\xb1\x2c\xe5\x61\xaf\xad\x4d\x80\x53\x87\x21\xfc\x6e\xf5\xe9\xb6\xb3\xa5\x83\x31\xc6\x2c\xc3\xc7\x6e\xad\x7f\xcc\xce\xa7\x33\xca\x5f\xae\x6b\x84\x49\x01\x99\xf1\x2c\x25\xa5\x78\x2b\x70\x84\x7d\xfd\x86\x71\x6d\x9b\x90\x7e\xcb\x5c\x3d\x6e\x97\xf5\x57\x05\x13\x49\x12\x38\x43\xa1\xaf\xf9\xf3\x0b\x36\xed\x55\x1f\x5c\x33\xa1\x02\xab\xde\x34\x18\x65\x74\xe1\x4f\x51\x8d\xb6\x7e\x26\x74\x86\x6a\xc8\x37\x1d\x66\x6f\x39\xdf\x64\xc0\x24\x71\xd6\x5a\x68\x7e\xda\x42\x36\x95\xbe\x97\x10\xea\x82\x01\x6a\xd2\xe8\x7c\x7c\xda\xde\xad\x9e\xfe\x3a\xec\xf6\xab\xa7\xfd\x18\x65\x29\x98\x8c\x79\x8c\x23\x33\xac\x05\x01\x39\x3f\x1b\x25\x0f\x42\x57\x6e\xbf\x82\xa2\xa8\xda\x87\x93\x43\x18\xfb\x93\x29\x65\x6d\x55\x6d\x81\xae\xff\xab\x8e\x69\x82\xee\xef\x1e\xee\x37\x7f\x45\x2c\x62\x01\x1f\x8e\x25\x51\x36\xf2\x5c\xeb\x7e\x50\x9f\xc5\xcd\x68\x35\x82\x69\x16\x58\x21\x49\x55\xd9\x2f\xbe\xf2\x73\x6e\x39\xe4\x67\x5a\x2a\x6a\xab\x1e\xac\xe9\xf3\x88\xcc\xf5\x5b\x6f\xfb\xc5\x7f\xf9\xfc\xfc\x3a\xa0\x80\xd0\xa6\x2f\x63\x94\xcc\xdc\xdd\x42\x30\x13\x87\x71\xe4\x63\x9c\xc6\x83\xc2\x6d\xfc\xeb\xd6\xa7\xc9\xb9\x8d\x4c\xe5\x20\x8c\xe7\x6b\x88\x7e\xee\xf2\x20\x8a\xa8\x20\x8c\xaf\x6e\x19\xca\x7d\x6f\xc8\xcf\x62\x1e\xc6\x48\x37\xf7\x0e\xcb\xea\x75\x12\x2e\xf1\x50\xc6\x84\xad\x39\x61\xdd\xbd\xf4\x3b\x1c\xe9\xed\xf3\x81\xbb\x92\xfd\xef\x07\xb7\x61\xf1\xcd\xe5\x49\x2c\xb8\x17\x2b\x9b\xbe\xa2\x3c\x05\x85\x38\xae\x7e\x39\x09\x9f\x6a\x0c\x60\xe4\xa9\xb4\xdd\xc3\x2e\xe5\x3e\xd7\xa7\xc2\xcb\xf6\x0a\x9e\x65\x48\x5d\x1c\x63\xcb\x5b\xd6\xe7\x07\xe6\xf5\x54\xce\xd1\xd0\x02\x7c\xfb\xb0\xfe\xd3\x67\x6c\xd7\xdf\x9e\x56\xfb\x6d\x9f\x9d\x71\x01\x48\x95\xbe\xa7\xcd\x6e\xf3\xf4\x7d\x73\xed\xc7\xdd\x3c\x7c\xbb\xbf\xde\x3c\xed\xfa\x71\x32\x90\x7e\xfb\x25\x3b\xe6\xab\xf3\x3b\xd6\x13\x8d\x93\xe5\xad\x90\x43\xcc\x8c\x2b\xc7\xed\x8e\x50\x14\x8b\xee\x2e\x17\xf9\x1f\x87\x58\x24\xc9\xc0\x41\xff\x51\xe7\xed\x87\x1c\x74\xc1\x21\x51\x56\xc8\xac\xe7\x11\x4f\x5e\x46\x0e\x99\xa0\xda\x52\xb7\x80\x13\xf6\x55\x55\x75\x17\x12\xff\x16\x09\x38\xab\x71\xcc\xae\x31\xd3\xc8\xbc\x86\xe4\x2b\x96\x67\x5c\x5e\xa8\xb8\x64\x8c\x56\x8b\xff\xe6\xfb\xc3\xf5\x66\xbd\xbd\x5b\xdd\xee\x0e\x37\xab\xf5\xde\xeb\x47\x0b\x2e\x31\xa4\xe4\xf9\x66\xf5\x78\x53\x51\xc7\x61\x50\x8d\x15\x5c\x05\x8c\x70\x2b\xf4\xfb\xfa\xea\x58\x38\xfb\x1a\x25\x99\x72\x22\x99\xb6\xb9\xa6\xab\x6b\xdc\x34\xea\x8c\x05\x50\x9a\xf1\xfe\x91\x6c\xa5\x3f\x81\x62\x81\xf6\x69\x40\x73\x2e\x26\x6c\x0f\xc1\x75\x04\x18\xf4\x18\x62\xcf\x61\x77\x99\xc5\x58\x31\x6b\x72\xd3\xdc\x87\x91\x71\xa2\x7a\x9f\x4b\x8f\x5f\xf5\x80\xec\xc5\xd8\x8d\x23\x67\xe0\x44\x08\xbc\x84\x6f\x14\x4e\xaf\x07\x51\x49\xbf\x8a\x74\x33\x11\xb5\x85\x8b\x60\xdd\x5c\xe7\xcd\xe9\xdc\xe2\x55\x55\xea\xc9\xbb\x6e\x22\x46\x89\xa3\x05\xc9\x3b\xd6\xd9\xac\x63\xc4\x4d\x17\x98\x5a\x2f\xa2\xdd\xa8\xd7\xfc\x9b\x19\x6b\xb4\xb5\xe8\xa4\x62\xf0\xf5\xbe\xff\x46\x63\xbb\x87\x35\x9e\xe0\x7d\x7b\x24\x2d\x8b\x16\x8b\x59\x14\x24\xc2\x30\xf3\x2d\x84\x6b\x17\x22\x85\xfd\xb1\xc8\x70\x97\x1e\xe1\x20\x1f\x35\x4e\x54\x45\xc8\xd2\xd0\x29\x65\x92\x8d\xc2\xa5\x2e\xe2\x62\x3e\x2c\xa2\x2c\xa0\xac\xa4\x7d\x3f\x59\xbb\x07\xf7\xf7\x98\xa1\xed\xd8\x9f\xdf\x1f\xeb\xfc\x58\xd5\x3a\x87\xb1\x19\x90\x10\x49\x94\x50\x8f\x6b\xbb\x7e\x38\x3c\x7e\x5d\xed\x36\xd1\x00\x96\x5b\x6f\xee\xf7\xab\x2f\x9b\x61\xa8\xb2\xf3\x72\x4c\xee\x19\x9b\x98\x2d\xde\x50\x91\xc4\x40\x42\xba\x8f\xab\xa7\xfd\x76\xbd\x7d\xa4\x85\xeb\x70\xb3\xe9\xcf\x9b\xa6\x49\x4c\xc2\x50\xe7\x53\xde\xff\x4d\x26\x96\x45\x8e\xf8\xb3\xff\x1b\x5a\x99\x73\xb7\xa8\x1d\x56\xd7\xd7\x4f\x9b\xdd\xce\xe3\x3b\x45\x86\x5c\xb8\xcc\xee\xcb\x19\x6a\x28\x5b\x44\x3d\xde\xbf\x6e\xb1\x1c\x82\x6f\xc1\x02\x24\xf1\x07\x63\xcd\xac\x1f\x0b\xb8\xc4\x96\x4e\xed\xab\xc7\x4f\x8a\xc7\x21\xc1\x1e\x4f\x70\x6e\x70\x70\x12\x15\x82\x2b\x4c\xdc\x42\x49\x9a\x33\xd3\x1a\xb5\x1b\x24\xb2\x8c\xd6\xf4\xb6\x3e\x37\x43\x67\x6e\xd7\x33\xe5\x85\x80\x50\x2a\x97\xcd\xad\xfe\x71\xbb\x1c\x0b\x08\xe0\xc6\xc9\xb0\xb4\xeb\xe2\x8c\xf1\xe4\xbd\x12\xa0\xac\x6f\x58\x8d\x43\xa9\x7e\xdf\xeb\xfe\xd8\x13\x8e\xf0\x51\xb3\xcd\x5d\x80\x61\x44\x48\x77\xc9\xeb\xa1\x39\xe5\xe5\x61\xec\x6d\x20\x84\x02\xe3\xd4\x77\x55\x35\xe6\xf3\x0b\xa1\x74\x48\x79\x1e\x96\x7a\x45\x1c\xba\xcb\x5b\x3b\x26\xf3\x7f\x5a\x44\x14\xca\x58\xd5\x82\xab\x87\x7f\xf6\x40\x27\xa1\xc3\x80\x42\xea\xe3\x82\xb5\xd7\xb4\x84\x23\x34\x60\xea\x7a\xfb\x94\x91\xba\x15\xcf\xfd\x53\xcd\x5a\xae\x02\x23\xe5\x83\xf5\x87\xda\x46\xf6\x3f\x20\xef\xb2\xe4\xab\x0a\x6a\x3d\x1f\x9d\xa9\xd0\x72\x91\xf7\x2f\x38\xcb\x01\x85\x81\x94\xc0\x01\xce\x3f\xba\xf7\x4d\x16\xc2\xe8\x30\xf1\x19\x41\x7d\x3e\xe1\x08\xc3\x28\x8c\x89\x28\x97\x3d\xc2\xaf\x55\x59\x95\xef\xc7\xea\xbc\x84\x8f\x84\x00\x62\x19\x7b\x29\x92\xb9\x01\xd9\x9c\x60\x02\x81\x4b\xbd\xcf\x25\xa5\x7b\x53\x54\x0e\x04\x98\x59\x30\x5e\x0f\x97\x84\x28\xb1\x54\xaa\xeb\xaa\xb0\x70\xe7\xc4\x1f\x89\x75\x44\xfa\x81\xce\xb7\xd5\x69\x9d\x7e\x1a\x40\x40\x1a\x72\x12\xdd\xd8\x7c\xf9\xb2\x3b\xec\x1f\x0e\x5f\x57\xfb\xf5\xd7\x43\x78\xfb\x70\xb5\xdb\x6f\xfc\xfe\x09\x59\x9c\x50\x98\x71\xbb\xdf\xf5\x7f\x62\x32\x4d\xbd\x8f\x64\xeb\x24\xa3\xc7\x61\x43\x17\x15\xb0\x29\x60\xd6\xa4\xfd\xa7\x21\xd1\xde\x20\x99\xe4\x0e\xc9\x6b\x65\xfa\x79\x96\x44\xa4\x98\x42\x6a\x34\x97\x55\x3a\x60\x59\x42\x41\xcc\xd7\xf7\xe7\x7e\xe1\x04\x06\x51\x46\x2f\x68\x55\xf4\xd6\x4f\x02\x78\xa6\x04\x7a\x3e\x80\x25\xbb\x15\x73\xb3\x54\x01\x5c\xc7\x31\x73\x5d\x64\x24\xd1\xc8\xc1\x65\x60\x52\x6e\x02\x11\x89\xd0\xad\x26\x33\xfd\x88\x51\xf9\xfb\xf3\x7f\xfc\x99\x74\x4a\xe5\xa1\xf5\x97\xcd\xfd\x42\x01\x05\x20\xe1\x94\xf4\x7d\xcf\x47\x5e\x90\xdd\x9f\xd1\x55\xe7\x8f\xd5\x2b\x52\x62\xe6\x8f\x18\xd0\x13\xda\xf6\xd5\xb9\x9e\x9f\x54\x86\x9a\xbb\x78\xf3\x0b\x96\x78\x0b\x72\x76\x27\x24\x22\x75\x68\xc9\x10\x68\x44\x42\x17\x20\x4d\x44\x82\x6d\x4d\x0b\x56\xc6\x66\xb6\x86\x82\x52\x48\x64\xde\x55\xf9\x33\x6f\xbf\xe7\xaa\xed\x95\x94\xc6\x1b\x1c\x68\x13\x12\x79\x83\xfa\xe5\x87\xfd\xd3\x6a\x7d\x08\x79\x1a\x0c\x87\x63\x6a\xd0\x1e\xec\x5c\x5e\x36\x07\x12\x80\xa1\x21\x7b\x97\x3f\x7f\x7c\xdd\x2f\x1a\xb4\xcc\x86\x0b\x69\xb7\x34\x28\x9f\x10\xf4\xfd\x18\x08\x36\x9d\x7b\x26\x00\x13\x3a\x38\xe3\xa6\x7d\x19\x5a\x69\x60\xb2\xd8\x47\x4e\xdd\xf2\xd3\xb7\xbf\xb9\x3f\xae\x32\x12\x2c\xa1\x64\xca\xf7\x2d\xa7\xb7\xc8\x28\x45\x00\x52\x0d\x2d\xec\xaa\x73\xad\xf0\x0b\xb6\x3b\x3c\xe6\x2e\x2c\x9c\x8c\x96\x61\x68\x08\x98\xa7\x21\x2f\xde\x5d\xad\x72\x8e\x89\x95\xa1\x8c\xb4\x63\x4b\x51\x91\xe7\x00\xa5\x3e\x94\xf8\x36\x96\x3d\x10\x32\x32\xa9\xb1\x55\x1e\xf5\x52\xe6\x0a\x8a\x75\x75\x3c\x9e\xcb\xbc\x7d\x77\x5d\x23\x37\x2e\x96\x11\xd9\xdd\xab\xaa\x69\x67\xcf\x57\x26\x41\x12\x44\x23\x64\xd2\xde\x33\xc0\xfc\x87\x89\xb0\xef\x76\x3f\x22\xde\x51\x91\x66\xe8\x2c\xc9\x34\xc9\x08\x5f\xe5\x1e\xed\x69\xfe\x0d\xa9\x4c\x69\x0d\x76\xd6\xe6\xcb\x9b\xac\xcc\xe2\x30\x56\x03\xcf\x0c\x4b\xd2\x54\x27\x41\xd2\x3f\xce\x83\xf2\x80\x90\x2c\x44\x82\x46\x0f\xbb\xad\xe5\x29\x91\xc0\xea\x52\xe6\x21\x59\x96\x06\x6e\x13\xd8\xb5\x55\x0d\x63\x53\x62\x21\x19\x58\xca\xb2\x76\x73\xd2\x05\xda\xd3\x1e\x8a\x64\x68\xa8\x1d\x6e\xd7\x12\xca\x7a\xdd\x11\x9e\x02\x05\x38\x3f\xdf\xd5\xec\x33\x9c\x47\xc4\xc6\xd3\xa8\x0a\x12\xcb\xa2\xd6\xd8\x35\x9a\x41\xe8\xb8\x1b\x24\x42\x37\xff\xb6\x47\x78\xc6\x6b\xb4\x21\xf4\x4c\xaa\xd0\x87\xb7\x92\x1b\x2b\xf5\x64\x93\xfb\xeb\x73\xf7\x7b\x49\xcf\xf9\xa1\xec\x7f\x92\x08\x52\xb2\x4e\xc9\x9b\xd5\x59\xe7\x17\xd5\x10\x29\x58\x4c\x6c\x1f\xfb\xc4\xef\x20\x2f\xbd\x4e\xd0\xf4\xc6\x09\x88\xb4\xa3\x5d\x75\x9f\x3e\xb4\xd5\xa1\x25\xb7\xde\x66\x7e\x42\x60\x56\xa5\xc5\xc3\x57\x6c\xd9\x6d\x3c\xa3\x21\x85\x84\xf7\x4a\xef\xf0\x8a\x7a\x33\xe0\x00\xa6\x67\x03\xa9\x49\xcf\xc7\x36\x41\x2f\x67\xcc\x72\x15\x56\x82\x4a\xa9\x57\xb4\x49\x9e\xaa\x37\xdb\x08\xfb\xe6\xbf\x1d\xb5\x49\x1c\xbb\xf6\xb6\xaa\x7e\x9e\x67\xb5\x38\x89\x88\xb4\x7c\x81\xfe\xd7\xb9\x69\x0f\xbe\xd0\x70\x28\x2b\xed\x25\x91\xdc\x48\x13\x29\xfa\xa9\xda\xe6\x4c\x23\x0d\xcf\xd9\xcd\x33\x59\xa6\x9d\xf1\x89\xa7\xf1\x6f\xcb\xb6\xba\x27\x02\xa5\xc6\x5f\xb3\x2b\x30\x32\x20\x0f\xcf\xf6\xd7\x0d\xe2\xb5\x67\xd0\xf6\x1d\x25\x69\x4c\xa0\xd9\x2c\xc3\x13\x93\x48\x54\x05\x71\x4c\x56\x2b\x0e\x16\xbb\x7f\x58\x84\xf8\xa9\x20\x31\x54\x55\xfb\x51\xd5\x85\xbe\xca\xdb\xcd\xeb\xb8\xe0\x4d\xf7\x36\xf2\xff\x7c\x90\xd9\x7f\xdc\xdd\x55\x61\x2a\x69\x7e\x4e\xd5\x45\x84\x0a\x33\x45\xb0\x8e\xf5\xdd\xfa\x76\xd1\x7f\x78\x7a\x96\x0c\x43\xbb\xea\x7e\xcb\xfb\x66\x80\x0a\xc1\x72\x32\x9f\xab\xb6\xba\xc7\x5f\xed\xb8\x66\xa5\x42\x9d\x26\xba\x0f\xf6\x71\xfa\x2e\xaa\x08\x42\xc8\x7a\x60\x41\x2f\x55\x35\xf9\xd2\x38\xcd\x28\x14\x5f\xd5\x12\xd6\xbf\x61\x9b\xa8\x98\x19\x22\x23\x1f\xe1\x23\x38\x90\x8a\x41\x78\x76\xe9\xee\x54\x95\x4d\x45\x55\xe0\xc6\x2a\xf0\x2c\xae\x82\x2a\xc9\xac\x1b\xa3\xbd\xcc\x6d\xf9\x9a\xfb\x12\xad\x1b\x90\xc6\x92\x6a\x37\xba\xba\xcb\x75\x99\x3f\xbf\xb4\x4f\x67\xbf\x09\xab\x2c\x4e\xfd\x1a\xba\x2d\x5f\xb7\x7e\x09\x57\x2c\xb4\xc2\xcb\xe7\xb2\x5b\xd8\xf7\xbe\x98\xdd\xdf\x1c\xd6\xc5\x83\x7e\x46\xbc\xe5\x1a\xbf\xe4\xa6\x5d\x57\xba\xbf\xb7\x5e\x60\xe0\x5c\x8e\xc3\xac\xd9\xb5\x8b\x30\xca\x98\x57\xed\x40\x7d\xf5\xee\xf8\xa3\xd3\x9b\x22\x74\x48\x84\x48\x5f\xb7\x25\xaf\x95\xcb\xa2\xa7\x12\x5a\x91\xa6\x26\x41\x60\x9f\xc0\x18\x32\x08\xf8\xcf\x07\xdb\x87\x82\x38\x20\xfd\x1e\x67\xde\x32\xd1\xa3\xfb\x30\xff\x19\x5e\x6b\x05\xcc\x8a\xb5\xdb\x77\x87\xf6\xb8\x07\x73\x57\x95\xd8\xbe\xc0\xb7\x06\x6b\x8a\x6b\xdc\xee\x31\xfb\x45\xc0\x95\x72\x09\x31\xbd\x4a\x5b\xbd\x1c\x84\x28\x50\x92\x6a\xfa\xba\xae\x4e\x76\x17\x9d\x9e\x48\xa2\xb5\x50\x6c\xeb\xf7\x2e\x9c\x99\xb0\xb7\x95\x8a\x90\x2a\x42\x37\x90\xd7\x4b\xbe\xd3\x7e\x58\x16\x93\xd4\x8d\xbb\x0f\x36\x9a\xa5\x60\x7c\x0e\xf7\x59\x2c\xfc\x2b\xc5\x53\x2a\x23\x1c\x9e\xb1\xc4\x07\xb3\xae\x61\x46\xb0\x53\x4a\x58\x7f\xde\xf6\xad\xfa\x0b\xa1\xf6\xa0\x5d\x77\x54\x27\xa9\x15\x98\x37\x2d\xd6\x5b\x55\xcd\x3e\x8c\x01\x50\xe5\x85\x4c\xd5\x87\xf0\x51\x61\xca\x03\x57\xc0\xdc\xa1\x6a\x2b\x0b\x11\x5a\x9f\x67\xc1\x93\x32\x91\xa5\xca\x52\xaf\x6e\x92\x25\x2b\x13\xa1\x2d\x56\x59\xdd\x91\xf9\x0e\xae\x4c\x6a\x88\x16\x72\xbd\x23\x45\xd0\xe9\xbd\xd7\x81\xd2\x14\xc4\x18\xa7\x24\xd8\xcb\xee\xf8\xcf\xeb\x30\xb0\xaa\xd3\x7e\xe2\x3a\x65\x16\x77\x34\x4a\x6c\x98\xf8\x8c\xed\x15\xb6\x57\xd0\xe4\x6a\x38\x04\x38\x96\xea\xb3\x08\xc2\xee\x77\x25\x81\x1f\xa2\xec\x6d\xf1\x72\xc2\x1f\xca\x1a\x2c\x2e\x34\x3a\x0e\x32\x87\x3b\xec\x3e\x6f\x5f\xbb\x3e\xf6\xd6\x49\x9a\x89\x61\x5b\x38\xe6\xe5\xa9\xce\x5f\xa1\xc5\xe6\xa2\x08\xae\x93\x2c\xc6\xcc\xd1\x49\x6d\x16\x6e\x55\x75\x83\xbf\x53\xc4\xd7\x09\xc4\xb6\xd3\xde\x2d\x4b\x42\xcc\xce\x9d\xa6\x5a\x8c\x66\x66\xdf\x00\x9d\x8d\x12\x99\x95\x18\xdf\xdd\xf9\xeb\xcf\xb8\x30\x6e\x6e\x38\x8b\x93\x4f\xe1\x19\x9a\x61\x20\xad\xae\x56\x9b\xff\x5f\x39\x70\x09\xcd\x83\x00\x2c\x31\x9c\x60\x1d\x20\x3d\xa0\xf7\xd3\xca\x89\xe6\x71\x42\x55\xa4\xfd\x6e\xbf\xe9\xc9\x05\x9a\xa3\xa1\x57\x89\xb0\xc9\x37\xdf\xee\xaf\xef\x36\x87\x87\xfb\xdb\xed\xfd\x66\x54\x96\xd3\x22\xe1\xac\x57\x4e\xb6\x20\x91\xe9\xcf\x11\x89\xa2\xd2\xe1\x1a\x4e\x27\xd4\x17\xbe\xf3\x6e\x14\x70\xab\x34\x93\x3f\x42\x3f\x27\x41\x01\xb3\x1e\x42\xa0\x67\xfb\xa1\x96\xda\xc4\x53\xa0\x99\x35\x76\xf2\xc7\x55\x24\xb9\xf3\xe5\xca\xcb\x67\x0b\x0d\xc6\xe1\x68\x1a\x7b\x1e\x97\xdd\x49\xc6\xe0\x3f\x3f\x86\x1b\x5a\x91\xef\xb0\x3c\x07\xd9\xe7\x65\x0b\xad\xa4\x4a\x71\xe0\x31\x2f\x2f\xf2\x5a\x69\xe6\x2b\x4c\x2e\x47\xb0\xb9\xdc\x05\x31\x4d\xeb\xc0\xa0\xbb\x7c\x54\x2f\xd0\x27\xda\x5a\x87\x51\x16\xf5\x6f\xb1\x33\x5a\xf7\xc7\x22\x4e\xe0\xc3\x2f\x5d\xf6\xb3\x7c\x05\x18\x24\xdc\xb5\x99\x46\x25\xcf\x3b\x28\xcf\x50\x14\xbf\xc1\x62\x6b\x8c\x05\xe1\xb8\x36\xed\x0b\x85\xbd\x9e\x1a\x3b\x7d\xde\x86\x59\xd3\x2a\xd0\xda\x22\x82\x96\x77\x93\x6e\x1c\x1f\x2b\x02\x4e\x2b\x53\x76\x10\x06\x42\x83\xf7\xc8\x6e\xf2\xe6\x53\x99\x46\x81\x81\x32\xd1\x58\x27\xd1\xe6\x92\xcb\x5d\x24\x0c\x34\x10\x9a\xa8\xc0\x57\x2c\x0e\xc9\xe1\x34\xd6\x6b\x12\x18\x46\x31\x51\x58\x8e\x55\xd9\xb4\x58\x7f\x45\x28\x7a\x8a\x23\x86\x49\x4c\x6e\xad\x9a\x9c\x79\xf6\xd5\x63\x35\x7c\x4e\x45\x04\x65\x5c\xed\xef\xc6\x3b\x04\x46\x3c\x21\x7d\x85\xff\xb7\xaa\x8a\xea\xb9\x4b\x76\xbf\x40\xad\x87\xe3\x71\xc2\x3c\xc8\xcd\x61\x38\x46\x8a\xfa\xb3\xdf\x99\xc4\xf6\x65\x51\x4e\xd8\x6a\xbb\x7e\xf0\xa7\x49\x12\x43\x6b\x98\xcb\x02\x27\x5b\xc5\xec\x06\x24\xd2\x7a\x5d\x76\x11\x39\xd6\xae\xd0\x37\x6b\xd3\xb8\xa1\x69\x28\x48\xdb\x70\x5d\x35\x6d\x5e\x38\x2d\xb9\xc9\xcf\x4b\x39\xd7\x66\x20\xca\x9e\xa5\x2f\x1c\x2e\x3f\xa9\x2c\x62\x3a\xf2\xe0\x08\xdc\xaa\x8a\x4e\x66\x2d\xac\x9b\xbe\xe8\x3c\x46\xd2\x60\x96\x26\xbe\x62\xbe\x7b\x3f\xca\x6a\x6a\x9a\x27\x30\x63\x29\xfd\xf2\x2e\x3c\x1c\x75\xd3\x30\x53\x49\xea\x30\x65\x77\xef\x9b\xb2\xcd\xdb\x77\x1b\xbc\x4c\xaf\x88\x39\xab\xbf\x17\x68\x36\x65\x75\x7e\x76\x9d\xd6\x11\x6f\x79\x01\x19\x80\x22\xb1\xfd\x1e\x27\x16\xd1\x0c\x85\x19\x14\x0a\xa9\x03\xff\x85\xb4\x59\x1e\x6b\x6c\xda\xfc\x19\x47\x2e\x1a\x02\x21\x8e\xe9\xa6\xe5\xaa\xda\x94\xfa\x1a\x5a\x6c\x87\x8c\x13\x41\x0b\x99\x8c\x2d\xd7\xb0\xfd\x40\x31\xd1\x7d\x40\x66\x9a\x9c\x3b\x6d\x37\x74\x28\xdd\xbb\xc3\x2a\x34\x7d\x6f\xb6\x32\xed\x1b\xd4\xae\xce\xef\xa0\x9e\xd3\x47\xae\x98\x22\x0e\xe8\x73\xfe\x8a\x57\x79\xdd\xbe\x7c\x18\x8d\x8e\xc2\x7b\xd4\x46\x92\x4b\xf0\xcd\x66\x73\x78\xf8\x71\xdf\x57\x6c\x51\x1b\xf4\x0a\xcf\xc4\x03\xb8\xa9\xea\x5d\x0b\x3f\xe7\x90\x42\xc4\x30\x0b\xe5\xe0\x9b\xf4\x58\xd9\xee\xfe\xac\xf9\x89\x18\x01\x86\xbd\xfa\xc6\x7f\xe7\xe5\x73\x31\xdf\x78\x10\x63\x41\x2e\xe2\xe5\xb9\x28\xa8\x08\xe5\xd7\x2b\x7f\x3c\x53\xa9\x6b\xc2\xdd\xe3\xdb\xb6\xc5\xe3\xd0\x71\xf6\x43\x58\x64\x94\x5f\x2e\xcf\x65\x5b\xbf\xaf\xf3\x36\xbf\x64\x8b\xff\xcf\x05\x5a\xc0\x9f\x00\x43\x70\x7b\x3f\x89\x30\x2c\x11\x82\x67\x1f\x31\x41\x64\xfd\x57\xc9\xf3\xbc\x9b\xc9\x03\x62\x06\x8d\x96\x04\x5b\xf4\x4a\xf2\xbb\x97\xea\x6d\x7a\x07\x4d\x10\x58\x0c\xa5\xb1\x8d\xe5\xe6\xe0\x3b\x5f\x26\x70\xd0\xa7\xbf\x66\x7d\x52\x13\x30\x5b\xa4\x5e\x63\xd9\x3d\x1b\xec\xf1\xab\x26\x50\x8e\xa8\xdb\xc5\x7c\x3b\x6c\x1d\x07\x82\x42\x40\x0b\xe2\x98\x17\x67\x4c\x18\x01\x89\x42\xbd\x40\xf3\x62\x13\xdc\x4f\x77\x15\x13\x66\x40\x0b\xe3\x88\x95\x39\x11\xd1\x16\x26\x14\x09\x84\x17\x22\xbf\xfe\xa0\x01\xca\xda\xbe\x60\x7b\x9b\x43\x53\x95\xf7\x23\x39\xca\x0f\xbe\x32\x0a\x22\x63\x46\xdb\xff\x56\x2f\x99\x1e\x76\xe3\x04\x78\x14\xda\xfe\xa5\xae\xde\x0e\xf1\x21\xb7\x6a\xf4\xb4\x84\x1c\x80\x4a\xf7\x9e\x3b\x97\x57\x25\x8d\xf2\xd7\x1d\x45\x92\x84\x53\x64\xae\xad\x50\xfe\xf1\x54\x95\xc3\x16\x63\x22\x66\x89\xd2\x8f\x75\xa5\x37\x93\x07\x12\x09\x4e\x22\x48\x6f\xc4\xc0\xfe\xd9\xff\x19\x82\xc4\xb6\xea\x6c\x4f\xbd\x67\xf2\x8e\x33\x7b\x13\x07\x21\xf5\x39\x4a\xfc\xd5\xde\x10\xa4\x30\x3f\x62\x75\xee\xbf\x36\x0e\x18\x64\xbd\x52\x1b\x85\x10\xfb\xaa\x9b\xfe\x9f\xae\x2e\x26\x09\x21\x19\x22\x8f\x05\xd8\xa8\x49\x94\x0a\xc7\xda\x3d\xb4\x64\x7d\x68\x5b\xe1\x3f\x64\x52\xda\x86\xff\x79\x9b\x9b\x71\x7b\xcb\x64\x49\x92\x38\x7c\xd6\xed\x59\xfd\x7c\xdf\xb5\xbd\xcf\x88\x30\x59\xaa\x88\xf8\xfa\x02\xa5\x2e\x46\xe5\x78\x77\x98\xc5\x9a\x30\xe5\x3d\xf3\xd9\xbf\xbd\xf3\x84\xcc\x30\x6e\x21\xe2\xdd\x6d\xf6\x92\x89\xef\x7f\xfe\xb5\x9e\xfd\x34\x11\xc5\x44\xf3\xba\xed\x52\x83\xee\x2a\x27\x8f\x4b\x30\xab\x14\x5f\x56\xed\xe6\xdf\xe7\xfe\x79\x2c\xd5\x5d\x8c\x90\x81\x99\x9a\x45\x41\x81\xd6\x73\x68\x71\xd6\xce\x33\x5c\x23\x54\x80\x63\x39\x9a\xcd\x68\x69\x9e\x5d\x34\x0a\x0a\x4a\x7d\x84\x75\x80\x5a\xe6\x6d\x0d\xf5\xfb\xcc\x3e\x7e\xf6\x05\x26\xa1\xaa\xa9\x3c\xd7\x96\x36\xb3\xd4\x9b\x36\xc0\x13\xd2\xfb\x7a\xa9\xca\xb0\xcc\xcb\x7f\x81\xbf\x19\x20\x44\x68\xfa\x56\xd0\xaa\xed\x5e\x1e\xb8\x04\x6a\x1b\x19\x69\xe5\x42\xd1\x43\x5b\x1d\xe0\x63\x4b\xd1\xd9\xf5\x29\x04\x7a\xad\x6e\xdf\x0d\x8e\x04\x29\x8c\x32\xca\x02\x74\xa0\xc0\x6d\x99\x0f\x9a\x62\x46\xa7\x4c\x78\x13\xf3\xea\x15\x6f\xa1\x69\xe9\x87\x75\xf1\x46\x5e\x3e\x37\x16\x8f\xf5\x3b\x57\xbd\xee\x3c\xc6\xc3\xd3\x57\x45\xd1\x4d\xef\xa3\x2c\x66\x99\xb8\xd1\x60\xa5\x51\xf2\xe6\xaa\xce\x7d\xbb\x61\x5e\xbc\x98\x7e\x04\xd3\x88\x6a\xa7\xeb\xa7\x87\xdd\x6a\xfb\x64\x71\x8a\x87\xed\xfd\xfa\x69\x73\xb7\xe9\x29\x37\xc6\xa0\xe4\xf6\xce\xaa\x73\xdd\xe4\xaf\xbd\x0a\x77\xdf\xa0\x85\x20\x88\x62\x4a\xe5\x4c\x5e\xea\xd5\xb9\x06\x5a\x74\x9a\xbc\xf5\x5a\x7a\xe3\x6e\x1f\x04\x01\xa4\x44\x40\x7b\xa9\x8e\x28\xbb\x18\x67\x02\xe9\xf1\x83\xb4\xea\x2d\x57\x6b\x84\xc1\xe6\x92\xff\xd7\xc5\x7f\xdd\x47\xc2\xd8\x12\x85\x15\x94\xd6\xeb\xc8\xc9\x25\x4d\xd5\xf4\x21\x88\x12\x41\x80\x94\xeb\x20\xf8\x73\xbb\xf1\xbf\x21\x66\x01\xd5\x31\xbb\x39\xbb\x38\x47\x21\x88\x91\x51\x7e\xb4\xaf\x73\xb2\x84\xfe\x3b\xe6\x28\x10\x24\x91\xa1\xdd\xec\x5f\x55\x5e\x5e\x41\xdb\xce\xb2\x50\x08\x92\x4c\x13\x8c\xef\xdc\xe8\x47\x7a\xb3\x7c\x79\x06\x82\x84\xc5\x94\xd8\xbf\x92\x3e\x49\x73\x98\x3c\x75\x08\x12\x1e\xab\xf4\x02\xaa\x71\xfb\x6d\x3f\xfb\x06\x96\x31\xaf\x41\xb0\x6d\x1e\x6b\x7c\xc5\xd2\x0d\x9f\x50\xe0\x86\xd2\x1e\x04\x3c\x61\xf1\x80\x14\x75\xea\x53\x9b\xf6\xe5\xa1\xd6\x58\xff\xf8\x9a\x3b\x5c\xe7\x40\x49\x99\xfc\x3b\xf5\x56\x86\x40\xe8\x58\x4d\x88\x0f\xfa\x35\x6f\xbc\xad\xc9\xb2\xeb\x19\x04\xc0\x8c\xab\xda\x8e\x89\x86\x4f\x13\x0a\xd9\x47\x55\x09\x08\xc0\x58\x25\x09\xc2\xb3\x79\x37\xca\x0f\xde\xb4\xd9\x17\xcb\x30\xa6\x8c\x6e\xbf\xbd\xdb\x1c\xf6\x0f\x87\xbb\xd5\x9f\x9b\x43\x78\xd8\x7d\xdd\xee\xd7\xb7\x0f\xf7\xfd\x94\x91\x90\x08\x6b\xc7\x79\x89\xce\x59\xfe\x49\x52\x5a\x6c\xf4\x0f\x4b\x24\xf1\x27\x52\x5a\x44\xce\xab\xd4\x9a\x88\x2e\xf5\x20\x20\xd0\xdc\xc6\x96\xcf\xd8\xee\xde\xe0\x34\x7b\xc8\x9a\xcb\xd4\xb9\x24\x7c\x85\xa6\x8b\xfe\x5d\xb8\x66\x21\x94\xa3\x67\x6b\x02\x69\x2c\xf7\x9a\xd4\xc2\x16\xf5\x92\x21\x30\x71\x18\x53\x54\x7d\x2e\xb5\x8f\x91\x3e\xe0\x82\x43\x60\x52\x41\x6c\xeb\x02\x4d\x1b\xb1\xe9\x95\x85\x51\x14\x65\x59\x4f\x6b\x21\x40\x93\xbb\xb4\x1b\xc4\x66\xef\x88\x38\x10\x46\x31\xa7\xbc\xe6\xee\x7d\xc1\x95\xdd\xbd\xf0\x93\x6b\x0c\xa3\x18\x43\x87\x44\xba\xc5\xd7\x68\xfe\xbd\x3c\xa4\x80\xa6\x3c\xbb\xd2\xbd\x35\xeb\xf2\x5f\x17\x87\xd6\xc6\xb1\xb2\xb6\x5c\xb6\x1e\xf1\x7e\x37\xb2\x05\x82\x30\xc1\x58\x5a\xb2\x6c\xe9\xe0\xcc\xfb\x6a\x71\x71\x75\xe3\xd3\x00\x23\xe5\xc1\xf4\x56\xcc\xb5\xb9\x14\xc9\x85\x30\x45\xa9\x1c\x16\x63\x2d\x2f\xc4\x0f\xa8\x7c\x38\x3b\x73\x96\x31\x12\xe8\x6e\x5e\xaa\x73\xa1\x77\xa3\xa2\xa5\xbf\xd6\x8c\xf3\xd4\x65\x3b\xab\x57\xd8\xaa\x6a\x2c\xf6\x01\x61\xd6\x25\xdf\x9e\xee\x9d\x97\x54\xde\x9e\x7e\x05\x8b\x63\x6e\x5b\xaf\x6d\x97\x9a\x97\x38\xed\x45\xcc\x3b\x89\xfe\x53\x69\x0c\x3d\x6e\x97\xea\x4b\x17\xf2\x17\x10\xb2\x2c\xa0\x28\xcd\xfb\xc2\x8c\x81\xb1\xf3\x91\x12\x5c\x4d\xb8\x3b\x30\x7b\xa4\x4c\x4a\x8d\xd3\xb6\x81\x3b\xc2\x03\xe5\x00\x47\xa4\x1e\x7b\x42\x95\x43\x71\x83\x24\x20\x30\x3b\x09\x4f\x4c\x1a\x5e\x40\x5d\x17\x0b\xa3\x10\xf2\x4c\x7b\xa5\x23\xab\xab\x38\xcb\x3d\x20\xe4\x8c\xd9\xf2\x16\x40\xa9\xb7\x64\xf3\xda\x0c\xff\x59\x7e\x61\x42\xae\x22\x0a\x93\x36\xdf\x36\x57\xa3\xb0\x0e\x42\xc1\x02\x6a\x43\x77\x37\x71\x53\xea\x8f\x9d\xea\x3e\x41\xcc\x73\x7f\x2e\x11\x53\xd4\x66\xf2\xba\x69\x9d\xb1\xed\x75\xdf\xfd\x83\x10\x22\x46\x2d\xae\x7f\xfb\x14\xab\x3f\x10\x27\x91\xf4\x30\x33\x8d\xf5\x5d\x55\xe2\xbb\xed\x0e\xe3\x34\x5d\xed\xc6\x6a\xd4\x83\x9a\x08\xbe\xed\xa1\x59\xe6\x34\x43\x08\x59\x4a\x7b\xa1\x45\x47\xdf\xfb\x94\x0f\x42\xe0\x82\xa0\x26\x8f\x5f\xff\xb9\xff\xf3\x7e\x75\x7d\xfd\xd4\x1f\x01\x46\xa9\x16\x91\x1c\x0e\xaf\xb9\x1a\x9b\xc3\x7d\x14\x0b\x84\xa0\xad\xf1\x3f\x35\xce\xfd\xea\xe5\x3d\x9e\xbd\x2c\xd0\x05\x2c\xec\xc2\x73\x7d\xb9\xe2\x00\xa1\x4c\xad\xea\xea\x00\xa7\x98\x88\xcc\xf8\x4d\x28\x94\x82\xcb\x31\x4e\xe4\x5b\x97\x1c\xbf\xd5\xf9\x07\x80\x0e\x08\x25\x24\xb4\xc4\xd3\xa5\xca\xaa\x7f\x20\x2a\x8c\x3d\xe4\x72\xab\x2a\x42\xbe\x5c\xcf\xc1\x60\x10\xaa\x2c\xa5\x54\x6d\xb3\xff\x7a\xb5\xdd\xaf\xfc\x87\x75\xc0\x6d\xf7\xbd\x86\xb7\x27\x28\x75\x75\xec\x12\xaf\xe9\xe2\xa1\x4d\x1c\xa7\x03\x6a\x61\xbd\x79\xf0\x47\x30\x08\x48\xe1\x41\x3a\x44\x98\x25\xd5\x58\x8c\x3d\xea\x71\x4f\x14\x42\x13\xa4\x7d\xb5\xa7\x0b\x88\x8f\x83\x49\xd1\xd8\x68\x67\xf6\xa3\xbb\xfd\x88\x82\xd7\xf2\x05\xeb\xbc\xdd\x53\x9b\xfa\x0b\x96\x9e\xe6\x3e\x7d\xdd\x4c\x18\x52\xaa\x7f\xb7\xef\xbf\x55\x46\x84\x95\x31\x6d\x3b\x5d\xe1\x0d\x5a\x6f\x0b\x1f\x76\x0c\x22\x36\x7e\xf6\x46\x01\x57\xde\x7f\x6d\xfb\xfd\xf0\x34\xdb\x42\xa2\xd0\x70\x4a\x9c\xfe\x45\xd9\x17\xa1\x65\x16\x67\x76\x14\x45\x92\x36\x40\x54\xd5\x6d\xa5\x7e\x46\x4e\x6c\x07\xa2\x48\x31\xeb\xa4\x4c\x37\xea\x60\x6d\xec\x9b\x03\x4c\x25\x88\x21\x8a\x93\x90\xc3\xa8\x82\x32\xa9\x92\xf9\x31\x9c\x1b\x27\x95\xe1\x80\x8d\x37\x95\xf7\xe5\x5a\x5e\xbe\xa2\x58\x2b\xb2\xd7\xbf\xc9\xc9\xa9\xbd\xf6\xef\x7e\x94\x30\xa1\x46\xbd\x0c\xcb\xb7\x22\x7f\xba\xa6\x1f\x82\xda\xc3\xdc\x1c\xf7\xfd\xb3\xa5\x67\xb8\x17\x89\xc9\x7c\xd9\xed\x3b\x96\xba\xaa\x57\xa7\x53\xe1\x3c\x0d\x76\xaa\xea\x76\x73\x72\x84\xb2\x1b\xe3\x28\x51\x85\x28\x4d\x2c\xde\xda\xc9\x6b\x78\xc8\x81\x7b\xac\x9f\x06\x57\x51\xca\xac\x08\xda\x13\xea\xa7\x5c\xca\xaa\x1c\x12\x7b\x88\x52\x19\x19\xab\xbd\xaf\xcf\xca\x1a\xe5\x2c\x9f\x25\x4b\x42\x3a\xcb\xce\xc2\x02\x9b\xbc\xb9\x22\x80\xfa\x0c\xc0\x06\x51\xc6\x0d\xdd\xd9\xcd\x2f\xf5\x72\xd5\xaa\xf1\x22\x1e\x65\x22\x0a\xa4\xeb\xcc\xcc\x62\xdc\xdf\xf5\xd3\xba\x0f\x33\xaa\xff\xf5\x0c\x3f\xa7\x56\xe1\x0e\xb3\x48\xd2\x24\xf8\x82\xed\xd7\xea\x19\x26\x3f\x23\x8e\x46\x31\x7c\xc4\x52\x2b\xd4\x4d\xb8\x53\x5d\x57\x53\xfc\x0e\x44\x3c\xb0\x06\x5c\x9f\x5a\xe5\x2e\x6e\xfe\xee\x04\x22\x12\xc4\x32\x92\xb6\x6e\x3a\x20\x97\x20\x12\xa9\xe5\xe5\xae\x9a\x1c\xca\x35\x9c\xf2\x16\x8a\x35\xf5\x94\xce\x53\x7c\xc8\x79\xee\x96\x08\x51\xb7\x09\xa2\xd7\x55\x9e\x93\x35\xff\x7f\xfc\xd7\x7f\x5d\x82\xc4\x86\xa7\x1d\xb0\xf6\x85\x56\xb7\x93\x44\x32\xb0\x0b\x84\x2f\xf7\x3c\xd6\x95\xc9\xfb\x37\x52\x46\x11\xc5\x90\xdd\x6e\x7d\xd5\x03\x77\x20\x52\x71\x14\xb8\xa4\x9d\x44\x6d\x6e\xd7\x1b\xa8\xcb\xcb\x29\xec\x87\x6b\xab\x8c\x69\x3b\x13\xaf\x79\x75\x6e\x68\x79\x77\x8d\x64\x37\x4a\xa7\x32\x93\x13\x0a\xfd\x53\xf7\x4e\xcd\xd2\x84\x48\xcb\x84\x88\xd4\x5f\x48\x8c\x7c\x3d\xc8\x38\x43\xa4\x8d\xa4\xea\x3e\xd4\xed\x8f\xaa\xfe\x69\xf5\x38\xbc\x51\xe4\xe2\x83\x59\x6a\x63\x41\x84\x8c\xd1\xdc\x7f\x81\xe6\xe5\x2a\xbf\xd4\x7c\xfe\xdd\x24\x9a\x3e\x00\x44\x96\x1a\x67\xb5\x58\xb7\xb9\xf2\xca\x56\xe3\xb9\x6c\x22\xab\xc2\x73\x95\xb7\xaa\xca\xcb\xbb\x4a\xe6\x45\x7f\xb7\x4d\x6c\x8b\x8b\x36\x59\xed\x36\xb7\x7d\x0d\x79\xbb\xac\xbe\x03\x91\x91\x21\x85\x45\x87\x23\x96\xc4\x1d\xf4\x7f\x47\x5b\xc0\x23\x21\xe7\x5d\xfe\xab\x7d\x77\x76\x2a\x4f\xe7\x62\x58\x15\x8d\xb1\x88\xee\xee\x29\x40\xdb\xed\x85\x93\x25\x2c\x0e\x62\xab\xf4\x56\x9d\x7c\xcb\x7d\x5b\xb6\x95\xab\xfa\x2c\x2f\x3a\x71\x60\x2c\xfe\x5d\xa1\x07\x3c\x4d\xf7\xcd\xe1\x46\xc4\x61\x94\x12\x2c\x95\x54\x8a\xef\xdb\x66\x57\x15\x9a\xd4\x81\xe8\x4d\xf1\x83\x34\x7a\xc3\xf7\xe5\x5a\xf3\xec\xfb\x23\x66\x71\x72\x74\xdb\x3d\x60\x67\xf2\xc8\xe3\x38\x88\xc3\x01\x42\x49\xa6\x93\x23\x56\x05\xc4\x71\x18\x90\x3a\xe4\x0b\x34\x6b\xeb\x70\x7f\x29\x83\x30\x9d\xf5\x71\x9c\x58\xc1\x68\x72\xc4\x79\x2c\x40\x79\x54\xa6\x3f\x27\x79\xd5\xf5\x6c\x66\xbb\x70\x0f\x51\x6a\x9c\x06\x31\xb1\xd8\xbb\xa5\x6d\x4c\xc6\x83\x38\x65\x31\x85\x93\xd0\x34\xf9\x73\xe9\x55\x19\x96\xc8\xb6\xb3\x1b\x91\xea\x98\xe2\xaf\x1d\xb6\x57\xe7\x9c\x1e\xd9\xdf\xdf\xf8\xe2\x54\x4b\xa6\x06\xb9\x18\x27\x70\x31\x14\xca\xe2\x2c\x36\x52\xf5\x2a\x2d\xd4\xd0\xbc\x26\xc5\x9d\x41\x31\x05\xe2\x2c\x53\xe4\xfd\xb2\x7f\x09\x8e\xc9\x7f\xfa\xbf\xb2\x90\x3a\x91\x8e\xba\xd7\x2c\xf2\x00\xbb\x61\x9c\x70\x8a\x47\x1b\x15\xec\xda\xea\x34\x8a\xf8\xe3\x8c\xa9\x8c\xac\x0c\x2c\x9a\xa5\xfb\x6d\x33\x18\x75\x37\x46\x13\x22\xf2\xdb\xe9\xb9\x06\x8d\x77\xd0\xb4\xc3\x9d\xcd\x38\x23\x28\x3e\xa5\x14\x96\x40\x6c\xe1\xd5\x13\xe7\x21\x88\x33\x6d\xa2\xd4\x6b\x31\x0f\x6c\xdd\xcb\x0b\x66\xa9\x54\x54\x66\x28\xe0\xf9\x5b\x3e\x13\x2d\x87\x98\x65\x8a\xe4\x8b\x1f\x4e\x58\xee\xab\xfd\x0b\x3a\x62\xbe\x3f\x2c\x53\x8a\xcf\xee\xde\x7f\xe4\x23\x3b\xa7\x45\xc4\xe5\xf4\x7b\x79\xa4\xa8\xc0\x65\x75\xd2\xe6\xd6\xae\x63\x06\x90\xff\x00\xb3\x5e\x13\xae\x9c\x5b\x0d\xbc\x21\x37\x40\xc4\x21\x45\xdf\x55\xf9\xb7\x24\x1c\x20\x16\x5c\x11\x80\x69\xf7\x63\x7b\xb3\xf7\x3e\x75\x8b\x30\xcf\xcb\x4d\x32\x16\x60\x15\xd0\x57\xb7\xeb\x9e\xf0\x39\xe6\x7b\x42\x0c\x3c\x4e\xc7\x58\x07\x92\x4a\xdd\xf8\x1e\x75\x77\x9c\xd1\x22\xb1\xf6\xe8\xce\x5f\xef\xdd\x42\x32\x52\xf0\x28\xf5\x93\xd3\xbf\xfe\x13\x3f\x34\x37\x98\xfd\x28\x10\x11\x05\xf3\xc7\xbc\x3c\x37\xa4\x01\xec\x98\xf8\x93\x77\xc8\x17\x83\x63\x19\x20\xb1\xf1\x7b\x17\xa6\xee\x41\x4f\x17\xbf\xc9\xcf\x96\x19\x77\xca\x69\x06\xeb\x7a\xee\xfc\x02\xb1\xd4\x19\x31\x2f\xda\xfc\x88\xa1\xff\xa5\xd2\xc4\x24\x98\x4e\x6b\x26\x09\xf8\x5c\xac\xda\x2a\x89\x59\xda\x57\xd9\xd7\xe4\x9d\xda\xee\xf1\x78\x2a\x08\x5d\xe4\x47\x69\x43\x8e\xed\xc7\xc3\x66\xff\x95\x82\xc2\x5b\x68\x9c\x5c\x82\x1f\xa3\xa3\x58\x28\x6b\x0f\xe9\x59\xe4\x7d\x94\x1f\xeb\x38\x25\xce\x8c\xdd\xa9\xe8\x52\x1e\x3e\x9c\x2e\xfd\x67\x14\x31\xd9\x14\x34\x6d\x81\x77\x79\x49\x25\xfe\xfe\x8c\x29\x12\x90\x92\x74\x04\xb7\xc7\x53\x31\xbb\x21\x9a\x45\x10\x0e\xd1\x64\x33\xa5\x81\x41\xac\x25\xa3\x06\x06\x61\x17\xeb\x71\xa7\x78\x7a\x1e\x8c\x64\x64\xc9\xb5\x27\xc8\x3d\xc4\xcd\x6f\x0e\x98\x18\x41\x79\x9f\x82\x63\xf7\x22\xcf\x9f\x0a\x72\xbb\x67\xa2\x03\x68\x78\x21\x3d\x7b\xe3\xa6\x63\x4d\x68\x2f\xe8\xa5\xd2\xc5\xc5\xf3\x4d\x02\xe4\xa9\xab\x62\xdd\xad\xfe\xf2\xd6\xa5\x17\xc4\x28\x48\xc2\xd0\x4a\x9c\x50\x99\x88\x7a\x79\x76\x8b\x78\xf2\x5a\xb7\x9f\x16\x83\x67\x85\xc6\x24\xe4\x46\x3a\xc9\xfd\x07\x33\x76\xa2\x59\x57\xc7\x13\x94\xef\xcd\x24\x0f\x4e\x42\x6d\x5d\x21\x5f\x2d\x25\x7a\x52\xd8\xeb\x87\x64\x04\xd5\x3d\xa8\x02\xa1\x5e\x15\x85\x55\xdb\xf4\x86\x80\x90\x84\x18\x78\x29\xe4\x6e\x5d\xe4\x7f\x0c\x41\x69\x12\x05\xa1\xcd\x5a\x1d\xdd\xf5\x2b\x42\xdd\x4a\x04\xff\x54\x93\x28\xca\xa8\x8a\xb6\x47\x38\x7e\x45\xd0\xcd\xfa\xa5\xca\x67\x9c\x01\x48\x22\xb0\xda\xf0\x7b\xf8\x89\x44\x1c\xa9\x35\xd6\x1f\x9a\xeb\xce\xff\x5d\x9c\xad\x49\xa4\x05\xb9\x78\xe9\x8a\x0c\x8d\xbe\xe4\xa6\xbd\xcd\xcb\x11\xab\x01\x92\x24\x4e\x08\xbd\x77\x38\x56\x25\xbe\xf7\x7f\xcd\x32\xaa\x4f\xfa\xe5\xea\xfb\xe3\xfa\xd7\x02\x3c\x0b\x92\x44\x6a\xaf\x43\x3d\xd1\xd9\x9f\x2e\x44\x49\x1a\x30\xe3\xfb\xe8\x5b\x9b\xe4\x4e\x7c\xe9\x20\x49\x65\xe6\x54\xb3\x7d\x6f\x7b\xf9\x0d\x4c\x52\x89\x54\xe2\x5a\x91\xcb\xd7\x92\xde\x18\x24\xa9\x8e\x1c\x0a\xd4\xda\x52\xcd\xa6\x63\x96\x65\xca\xc9\xc3\xf4\x6a\x69\xb3\x42\x62\xc2\xd2\x98\xa2\x03\x0a\xe5\xb0\xe9\xbb\x1e\xfd\xf2\x91\xf0\xd8\x12\xc6\xec\xbb\xd1\xdd\xd3\xf8\xce\x1f\x13\xa0\x12\xd5\xef\x4f\xa4\x5a\x5b\x80\xfa\x79\x3b\xa7\xf8\x41\x97\x0d\x67\xbe\x50\x7c\xd6\x6b\x2c\xdb\x1f\x98\x8f\x5c\xe9\xbb\x11\x19\xc5\x83\x9b\x92\x52\x84\x71\x6e\xdb\x25\x4c\x34\x69\x9c\x96\xc5\x13\x62\xb7\xa0\x94\xea\xdd\x91\x69\xfb\x61\x92\x52\x84\x73\xe9\x76\xd8\x01\xbd\x91\x57\xe5\x6c\x15\x4a\x64\x82\x64\x86\xf5\x63\xbb\xbb\x7e\xb8\x5b\x3f\x6c\xef\xfb\x23\x19\x4b\xbc\x17\x10\x96\x50\xb4\xef\xb3\x3b\x2b\x99\x15\xc4\x79\x7c\xbc\x5a\x1f\x56\x8f\xdb\xfe\x83\x4c\xd3\x03\xd1\x9e\x69\x3d\xfe\x3a\x40\xcf\x0b\xb1\x3a\xfd\x76\xcf\xdb\x96\xa6\xea\xdf\x61\xe5\x58\xce\xb7\xf8\x9a\x9f\x9b\xeb\xd5\x43\x7f\x20\xcd\xa6\x5a\xbd\x17\xfe\x7d\xdd\x18\xa4\x5a\x3c\xe9\xd4\xb9\xc8\xf3\x1a\xa1\x68\x66\x17\xaf\xb8\x35\x9e\x3a\x10\x4f\x76\x77\xea\x36\x9d\x4a\x43\xff\x52\x60\x2c\x49\x6a\x07\x8f\x58\x3f\x63\xa9\xde\xbf\x95\xc4\xea\xee\x8f\xa7\xcc\x6a\x56\xb5\x78\x9a\x7a\x93\x42\x82\x99\x11\xde\x35\x1c\x51\x3f\x9c\x2f\x3b\x95\x9f\x45\xb3\x09\x72\xce\x47\x39\xac\xef\x52\x4c\xd2\x82\x04\xb5\x25\x49\xfa\x1a\x42\x17\x51\x36\x84\xd3\x18\xe0\x7d\xf3\x17\x18\x0d\x8b\x1d\x58\xd3\x9d\x74\x5f\xb9\x80\x94\x1c\xc6\x6f\x3f\xa2\x4b\x40\x62\x58\xa6\x53\x4f\xd6\xf0\x20\xdc\x69\x26\x92\x18\x69\x43\x8a\xbc\xb9\xa5\x8a\xe5\xec\xdb\x8d\x8e\xbc\x6b\xd3\x5d\x5e\x20\x3c\x23\xe9\x32\x5f\x6c\x07\xe3\xef\x4d\x83\x38\x46\x5b\x5b\x7a\xc5\x7a\x78\x21\xd3\x20\x01\x82\x9e\xb9\x94\x07\x3e\xf4\xd3\x87\x34\x50\xd6\x1e\x8f\x8a\x90\xfb\xea\x07\x4e\x35\xb5\x20\x0d\xb3\x58\xa6\x76\x8f\xb9\x46\x93\x97\x48\x3a\xe2\x7e\x3e\xa6\xa1\x56\x68\xbb\x92\x9b\xa7\xf8\xb0\x5e\x3d\xfa\x03\x51\x84\x89\x45\x5c\x94\xeb\x8a\x60\x05\x5f\x96\xd0\x48\xe3\xd5\x2a\x8d\x20\x35\x9c\xf6\x87\xba\x86\x9b\xee\xca\xfb\xb3\x61\x1a\x58\x76\x7c\xb7\xbd\xdd\x56\x4d\xbb\x2a\x35\x25\x1d\x9f\xea\x3c\x40\x1a\xab\x30\xf2\xef\x14\xd4\xcf\xd8\x5e\x3b\x19\x3f\x92\x9c\x99\xf5\x04\xd3\x24\x0e\x53\x35\x42\x15\xd1\x3b\xb4\xb4\xb0\xa6\x89\x91\x01\x8c\xc0\xc7\x94\x07\xce\x86\x2e\x9b\x8c\xcd\x1e\x40\x1a\x07\x84\xfd\xa5\xd4\xa5\xdb\xee\xc6\x4b\x5e\x9a\x45\xda\x39\xbe\xb4\xe7\xba\xbc\xc6\xf9\xbc\x49\x59\xa2\x49\x61\x85\x30\xe7\x77\x3d\xcf\x07\x52\x26\x42\xd2\x2c\xf9\xe6\x2c\x2f\xfc\x25\x4e\xbf\x9d\x29\x6b\x69\xb2\x55\x95\xbf\x31\x04\xcb\x6c\xbc\x1c\xf8\xa7\x61\x75\xca\x30\xa4\x30\xcf\x37\xd0\x3e\xa2\xd0\x41\xca\xb9\x26\xbb\xca\xf5\x5f\x57\x9f\x70\xb1\x20\xe5\xce\xb9\xda\x46\x50\x1b\x0b\xea\x72\xb9\xbf\x5f\x2f\x17\xfb\xd0\x29\x57\x49\x30\xc8\xad\xef\xe6\xd5\xe1\x7e\x94\x21\x98\x07\x05\xdd\x96\x5a\xbb\x2d\xbb\x59\xef\x8f\x6b\x49\x05\x05\xd0\xda\xb5\xa6\xfc\x91\x2e\x68\x75\x5b\xa9\x0f\xb3\x7b\xb0\xf8\xf4\x3b\x80\xc7\x04\xdc\xf4\xe0\x70\x7a\x0d\x9f\x67\x97\x2b\x01\x68\xd0\xf7\x6f\xb7\xeb\xd5\xfd\xe1\xf1\xe1\xfa\xb0\xf9\xe7\xfe\x69\xb5\x26\xb1\x8f\xab\xd5\xce\x37\xf4\x53\x15\xe9\xac\x7b\x93\xa6\x56\xab\x17\x01\xcf\xf2\xfc\x57\xdc\x84\xae\x3b\xbf\x81\xba\xdc\x80\x7a\xb9\x1a\x70\x74\x90\x6a\x69\x5f\xef\xc1\x6f\x76\xf1\xe6\x6a\x25\x29\xc0\x5d\x43\xa9\x2f\x72\xae\x7e\x8c\xa6\xc9\xf0\xb4\xba\xff\xb2\xd9\xdc\x5f\x1f\x44\xff\x25\x5a\x6b\x6b\xb8\x54\xfd\x7a\x9f\x83\x88\xfd\x18\x13\xd1\x92\x5d\xe2\xaf\x76\x2c\xdd\xb0\x86\x19\x0b\x19\x52\x0c\x15\x89\x02\xe5\x65\xde\x8e\x3d\x9d\xc3\x59\xb4\xec\x87\x27\x96\x32\xd7\x3d\xb8\x5f\x27\x67\xef\x32\x6e\xb7\xa4\xc8\x02\xea\x3a\x3c\xc8\xbc\x85\x92\x0a\xc2\xe3\xe0\x22\x45\xa5\x08\x2a\xb0\xfb\xb0\x21\x9b\x1a\x05\x14\x03\x55\xc6\x0c\x9f\xef\x57\x49\x63\x58\x22\x9c\x40\xf8\xa0\x40\x09\x59\x10\x0a\x61\x91\x17\xcd\x1e\xd5\xcb\xf8\x4b\xb3\x20\x53\xd6\xae\x45\xcb\xfe\x4f\x2c\x0d\x07\x64\x79\x5e\x3e\x6f\x4a\x3d\xc0\xa4\x21\x0b\x43\x46\x51\xee\xdd\xea\xfe\xeb\x6a\xbf\x5f\xdd\x3f\x3e\x3d\xfc\xf3\xaf\x30\xdc\x7f\xfd\xb1\x59\x7d\xdf\xf4\xc3\x98\xb1\x4e\x73\x2f\x70\x95\xeb\x0b\x69\xa4\xc9\x56\xda\x0d\xb6\xf0\x8e\xaa\xf2\xbd\xda\xfc\x75\x5a\x56\xc9\x42\x13\x27\xcc\xcb\x6a\x6c\x34\xc1\x94\x9d\xcb\xf7\xe4\xc9\x65\xa1\x51\x9e\x46\x69\x1b\x7d\xb3\x8d\x3b\x8b\xc2\x98\xf2\xc2\xbb\xd5\x9f\x9b\xa7\xeb\xd5\xc3\xe1\x66\xb3\xb9\x3e\xdc\x7d\xbb\xdd\x6f\x1f\x6f\xb7\x1e\x43\x0d\x59\x94\xc4\x5e\x35\x68\x55\x3e\x23\xc5\x48\x57\xef\x73\x87\x44\xee\x47\x33\x24\x50\x59\x53\x1d\x71\x24\x35\x06\x59\xa4\x14\x15\x95\xe0\xac\xf3\xf6\x1f\x67\x3c\xe3\xe6\x57\xde\x78\x49\x61\xc8\x22\x93\xd2\x06\x7b\x70\xe6\x82\x63\x27\x10\xc8\xe2\x24\x4b\x7a\x44\x30\xb1\x0a\x57\x79\x3d\xee\x68\x4c\x57\xcb\x2c\x4e\x35\x19\x0d\x59\xa7\x18\x2b\xc1\xf4\xa5\x82\xe2\x09\x41\xf5\x8c\x1c\xc8\x62\x6e\x53\x0e\x92\xa0\x24\xd5\xb2\xc3\x6e\xdd\x0b\xa1\x40\x16\xcb\x98\xd8\xc8\xe4\x22\x32\x7a\x97\xb3\xd8\x70\xc2\xf1\x9c\xba\xe7\x50\x10\xd6\xb5\x9f\x69\x49\xca\xc1\x69\xc1\xaa\xf3\xef\xd6\xf5\x2c\x51\x51\x3c\x54\x95\x2e\xb0\x20\x6e\x54\x16\x86\xa9\x63\x2e\x1c\x7c\x2f\xf9\xf0\xd6\xaf\xa5\x59\xa6\xb5\xcd\x75\xde\xf2\xb2\xf7\x4a\xf4\x07\x99\xb1\x5a\x29\x44\xe3\xa6\x77\xf8\x06\x67\x8b\x75\xc6\x43\x69\x17\xd2\x7f\x3e\x6e\xd6\xfb\xcd\xb5\xff\x2c\x8f\xad\x4a\x35\x68\x7d\xb5\x5f\x2f\x6c\x3a\x0e\xac\x32\x5b\x0c\x33\x9e\x88\x68\xe6\x7a\x43\x41\xa1\xb3\xbe\x19\x97\xd9\xdc\x27\x20\xb2\x80\x08\xbb\x72\x39\x0d\xe9\x49\xe2\x9c\x8c\xf3\xe7\x0c\x40\x51\x43\xe0\xba\x7b\x76\x71\x78\xb8\xde\xac\x0f\x51\x10\x05\xfe\xca\x65\x20\x69\x0a\xdc\xe3\xdb\xaa\xa6\x4a\xeb\x9c\x91\xf2\x5f\x8b\xbb\xe3\xc5\x6a\x3f\x2b\xc0\x67\x92\x2b\xe3\x13\xbd\x1a\xdb\xe7\xe5\x75\x3c\x93\x22\x61\xf1\x28\xc0\x59\xd1\x6d\xb3\xb4\xf1\xe9\x9b\x28\x65\x02\x83\x14\xc4\x94\x17\x31\xbb\xad\xd2\x80\x15\xa1\xa3\x28\x7b\xf2\x8a\xa8\x30\x22\x28\xd4\x99\x1c\x15\xaf\xec\x37\x2c\xa7\xc6\x99\x32\xca\x3b\x35\x5b\x1d\x98\x39\xa4\x62\x18\xaa\x83\x88\x84\xfc\x41\xeb\x0b\xf5\x73\xc8\x34\xa6\xca\x11\x5f\xdb\x95\xb7\xd5\x9a\x66\xd9\x19\x46\x86\xd0\x66\x23\x43\x28\xd3\x45\x9d\xc5\xb8\xcd\x96\x99\x28\x13\x0e\x6e\x7f\x55\x55\xc5\x4d\x38\x02\xac\xb1\x20\x48\xa4\x18\xe9\x8d\xbb\x74\x8a\xd6\xc8\xab\xf7\xc5\xfb\xcf\x82\x20\xb5\x6e\x6a\x43\xa5\x7b\x42\x77\x03\x16\x38\x2b\x94\x06\x5b\x12\xca\x1d\x23\xa2\x2e\x1c\x96\x27\x8f\x8c\x05\x3c\x91\xae\x0a\x65\xeb\xd1\x24\xb9\x71\xfd\x3b\x9e\x05\xb0\x30\x89\xa9\x10\xd6\x56\xcf\xcf\x05\x7e\xb7\x56\xd8\xcb\xb7\x9e\x85\x89\x22\xcd\x93\x13\xbc\x5f\xd4\xc1\x58\x98\x05\xe0\x9f\x0b\xce\x66\x14\x0b\x33\x20\x8a\x8f\x4f\xca\xa8\xce\xb8\x5c\xd7\x63\xa1\x80\xc8\xcd\x05\x1b\xb6\x3f\xe1\xc9\xba\xff\xae\xe1\xb4\x2d\x57\x6d\x5b\xa1\xe7\xa0\x01\x0b\x81\x65\x6e\x87\xff\x81\xf9\x94\x45\x38\xbb\x7a\x9d\x50\x91\xc1\x89\xc4\x3e\xe1\xab\x3f\x47\x14\x44\xdc\x25\x0a\x1b\xa8\x8b\xf7\x25\x19\x0d\x60\x91\x30\x18\xce\xc0\x95\x93\xa2\x23\x8b\x1d\xf0\xe8\x04\xef\x92\xd0\x04\x23\x15\xaa\xe9\xb9\x62\x2e\x29\x75\xf2\xa5\xa5\x1f\x79\xfb\xd2\xad\x81\x1f\x00\xdb\x3e\x76\xc9\x05\x96\x28\x20\x21\x37\xd2\x28\x2f\x4b\x54\x16\x20\x65\x53\x89\xbf\x55\x21\x67\x69\x18\x50\x89\xba\x86\x16\xaf\xba\xc4\x0a\xea\x1c\xe7\xb7\x2f\x0d\x03\x02\x01\xec\x5a\xec\xb6\xad\x86\x14\x72\x2e\x06\x29\x6b\x30\x4f\xc0\x0e\x2f\xde\x3b\x4f\x8d\xc6\x41\x3f\x4b\x31\x73\x73\x7e\x62\x14\xbb\xb8\x8b\xb2\x14\x99\x77\xe4\x38\x54\x17\xd4\x7b\x22\xff\x53\x8f\x67\x55\xe4\x8f\x50\x37\x60\xbc\x4e\x3f\x1d\xa2\x9c\x94\xba\x85\xae\x59\xad\xfb\x83\x3c\x73\xca\x3a\xc7\x63\x6e\xef\xdf\xa4\x18\xcf\x32\x8e\x14\x36\xc9\xf3\xfb\xc7\x9c\x01\x60\x2c\x15\x94\xc4\x5e\xad\x6e\x6f\xfd\xb9\x59\x16\x5a\x4d\x5c\x28\x2d\xff\xf6\xf1\xfb\x63\x7f\xcc\x70\x22\x14\x3a\xf9\xd8\x95\x97\xa3\x01\xc6\x21\x15\xae\xd4\x41\xd1\xc5\x1f\x8b\x9d\xa3\xd9\xd7\x73\xa5\x29\x5e\xfb\x17\xa8\x9f\x3d\x17\x13\x98\x08\x22\x3d\xf8\xec\x3d\x55\xd5\xac\xfc\xc6\x44\x90\x26\x2e\xa2\x7a\x84\xc6\x85\x67\xce\xe7\xda\x0f\x89\x15\x89\xe5\xab\x5c\x0f\x0b\xde\x58\x9e\x08\x98\x60\x89\x48\xbc\x16\x24\xd1\xbc\xe2\xfe\x10\x67\x10\xf9\x1d\xca\xa9\x97\x2f\xa9\xbf\x00\x13\x3a\xb5\xe6\x6b\x79\xdb\x77\xd3\x99\x0c\xc1\x5a\xc2\xc2\xe9\x1a\x8f\x55\xff\xe7\xc8\xea\x26\xff\xab\xca\xcb\xc3\x33\x5c\xbc\xb0\x92\xa1\x72\xec\x61\x67\x1f\x7e\x07\x3f\xb1\x5e\x77\x7b\xc1\x85\xed\x9f\xff\x0c\xb7\xfd\x14\xd0\xfa\x2b\xd4\xaf\xd8\xb4\xbd\xb9\xc9\xa6\xd4\x55\xdd\x90\xab\x98\x7f\x1a\xa3\x6e\xd0\x74\x56\x4b\x99\x51\x49\x72\x45\xed\xde\x2f\x5f\xd6\x8f\x55\x55\x5c\x8a\x45\x00\x53\x0c\xa9\xb5\x6a\x37\xc9\x55\xa3\xf2\x59\x11\x86\x29\x19\x50\x59\x9e\x2a\x1e\x74\x21\x97\x0d\x83\xd9\x1e\xe1\x3e\xa9\xd3\x80\x2a\x1a\x5d\xae\x74\x85\xed\xfe\xfd\xd4\xdf\x51\xcd\xad\x79\xc7\x40\xc1\xa6\x07\x4a\x8b\xc6\xa9\x26\x26\xed\xf4\x2a\xb4\x33\x30\x24\x55\x90\xb6\xb5\xe6\x6a\xb6\xcf\x3a\x34\xf0\x98\xd6\x69\x14\x3b\x9e\x72\x7d\xd1\x01\x61\x1a\x03\x5a\xab\x7d\xc9\x60\xe7\x35\x5b\x5b\xd4\x04\xf5\x71\xe3\x30\x08\x9c\x0b\xe0\xbf\x50\xb5\xae\xa1\x31\x88\xbe\xcd\x6e\x21\x06\x89\x70\x89\xc5\xcd\xb9\x28\xdc\xf0\x0f\xde\x50\x0c\xe3\xc0\x9e\xfa\xd8\x65\x6a\x43\x02\xc5\x8c\x51\x54\xeb\xd6\x50\xcd\x8a\xb3\x3c\x08\x24\x09\x50\x2a\x9a\x39\xeb\x17\x38\x9e\x2e\xcb\x0b\x3c\x88\x63\xda\x45\xf2\xb2\xc1\xfa\xd2\x5f\x73\x36\x98\xa5\x54\xeb\xa0\x28\xe0\xac\x2e\x7f\x16\x0f\xb4\x02\xd9\x43\x0d\xba\x1b\x71\x97\x17\xd8\xb4\x55\xe9\x19\xc1\x93\xa7\xcd\x03\x13\x49\x18\x85\x77\x7f\xe2\xc4\x08\x15\x78\x18\x05\x91\xcd\x1d\x9e\xbf\x95\xa4\xd6\x82\x37\x55\xfd\xb3\x5f\x05\x79\xa8\x25\xa1\xdd\xa9\x09\xd2\x6d\x60\x30\xa4\xab\x3c\xd4\x8a\x26\x00\x39\x0a\x7e\xf3\xb4\xfb\xb1\x13\xbe\x43\x8b\xf1\x28\x8d\x29\x87\xb1\xf0\xdb\xdf\xc2\xb7\xce\x33\xc0\xec\x70\x8f\xa2\xd4\x42\x03\x08\x32\x4b\x0b\xca\x30\xd5\x78\x94\xf1\xc8\xc5\x4a\x6b\x6a\x43\x4e\x99\x3d\x9f\xfd\xe3\xcf\xc0\x83\x04\x7b\x02\xa0\x67\xc5\x4e\x6e\x59\x1c\x44\xb4\x6e\xed\xde\xcb\xfc\xd7\xdf\xec\x83\xf3\x38\x48\x09\xd2\x54\xe2\xdb\xba\x72\x96\x4b\xb3\x67\x1b\x73\xab\x3e\x85\xed\x8b\xa9\xea\xb6\xcc\xfb\x66\x2d\x8f\x95\x01\xe1\x68\x67\x77\xa8\x07\xe9\x5b\x77\x3c\x31\x56\xd5\xdf\xdd\x94\x9f\xbb\x5e\xe3\x0d\x78\x1a\x45\x84\xc8\x07\xad\xc7\x1d\x80\x59\x3a\xb1\x50\x7d\xe5\x69\x64\xcd\x93\xf3\x66\x70\xce\x59\x8c\x62\x79\x9a\x86\xe4\x77\x0c\xd6\x43\xf5\xd5\xbe\x91\xd3\xa9\x98\xea\x80\x6a\xe2\x5f\xb1\xc8\xcf\x47\x07\x2b\xe9\x2f\x52\xf7\x5a\xad\xdf\x61\x51\xea\x0d\x78\x96\xd8\xa0\xe0\x6b\x75\xc4\xdb\x0a\xca\xe6\xc3\x7b\x7f\xf1\x4b\x32\x16\x12\xd0\xa6\xc4\xb7\x09\x54\x95\x67\x2c\xe1\x2e\x50\xfc\x8e\x4d\x9b\x97\xcf\xbe\x92\x31\xfd\x6e\x26\x93\x50\xf4\x2f\xbb\x73\x1c\xec\x62\x33\x7f\x1c\x03\x82\xc5\x5e\x7d\xfb\xeb\xb0\xde\xee\xff\x1a\x54\x40\x80\xf3\x10\x54\x36\xe9\x23\x78\x1d\xb8\x91\xc8\xfb\xf4\x7e\x72\x94\xe4\xb0\x02\x85\xc7\xc3\x37\xfd\xd9\x8c\x50\x8c\xb0\xda\x37\x38\x8f\xb4\xb8\x08\x91\xcc\x90\x6e\xdc\x5a\x7a\x57\xbd\xe2\xf2\x03\xf7\x1f\xc8\x62\x6a\x9e\x40\xd3\x3f\x0a\x91\x59\x94\xda\xa1\x1d\x75\x78\x38\x64\x48\x4b\xd3\x1a\xea\xc1\x4a\x67\xf6\xed\xc0\x63\xf2\x02\xec\x53\xa8\xef\x23\xec\xf5\x05\xb6\xe2\xb7\x38\x25\x2e\x23\xd9\x1b\xe9\xf6\x0a\x78\xc0\x65\x1a\xbb\x9b\x63\xb1\xc9\x57\xe4\xa5\xbc\x2a\xf5\x46\x55\xcd\x7b\xd3\xe2\x44\x01\x0b\xba\xa0\x9a\x20\x28\x1a\x15\xb9\x33\x4e\x6e\x80\x0a\x0d\xbd\x97\xb9\xcd\x53\x47\x50\x67\xae\x22\x4d\x8c\xc6\x7d\x75\x6a\xfe\xf9\x77\xdf\x73\x15\x87\x24\x57\x4b\xc8\x78\x8b\x56\xee\xcf\x27\x2d\x2f\x5f\xbd\x40\x9d\xf7\xa0\x3d\x7f\x14\x13\xed\xf1\x7a\xd7\x67\x6c\xb6\xb3\xe4\x80\x63\x9a\xa5\x61\xef\xc5\xe7\x5a\xbc\xfe\x98\x49\xa4\x7b\x7b\x28\x4c\xbd\xaa\xaa\x9f\x2b\x75\xc9\xe7\xe1\x68\x38\x9d\xe4\x74\x6e\x5e\xf6\xa4\xf6\xb7\xeb\x72\x55\x0f\x2b\x5a\x7c\x0c\x22\x10\x3a\x1d\xa7\x69\x5d\x5a\x72\x5b\xa9\x91\xd0\xde\xf2\xf3\x13\x61\x10\x24\xd9\xe0\x6d\x30\xa8\x6a\x83\x08\x13\xa4\x26\x47\x3f\x55\x28\x7e\xdc\xfc\x3a\x61\xd9\x4c\x9c\x51\x27\xe4\x20\x11\xa6\x48\x4b\xef\x6b\xd5\xa2\x0f\xc5\xfa\x63\x98\xc6\xd9\xb8\x94\x78\x8d\x2d\xe4\xf3\x56\xa6\x08\x51\x91\x10\x8c\xf5\x8b\x52\x6d\x55\x37\x07\x8d\xaf\x1e\xe9\x3e\x34\x26\x45\x88\x48\xfc\x3a\x52\x67\xbd\x7a\x7f\x84\xa6\x79\xab\xbc\x6c\x12\x1f\x57\x79\x44\xe8\x5c\xbc\xa8\x89\x70\x55\x9d\x7b\x8d\x6c\x10\x51\x1c\x52\x26\x76\x84\x5f\xf9\xf1\x7c\xdc\xdf\x5f\xf5\x47\x0c\x04\x13\xd9\xba\x63\xf5\x94\xeb\x8b\xf7\x95\xbe\x87\xcd\x6e\x6d\x64\x64\x0c\xbe\x0c\xf5\xf7\x70\x5c\x22\x89\xad\xc7\x50\x79\x3e\x36\x67\xaa\xa7\xf4\x91\xbc\x48\x52\xc3\xbd\x56\xb6\xfd\x30\x7e\x88\x05\x9f\xae\x55\x22\x61\x92\xde\xfa\xd3\xb9\xbd\x23\xb3\xbe\x39\x50\x77\x7a\x15\x69\xa0\x65\xe6\x85\x8b\xda\xb1\x52\x58\x77\xcc\x04\xdd\xb3\xd9\x9f\xeb\x9f\xf8\x7e\x75\xae\x9f\x1d\xc1\x7a\xf6\x0c\xd3\x34\xa3\xb6\xf5\xc1\xca\x53\xb8\x72\xe1\xe0\x20\xe3\x86\x65\x2c\x8c\xac\xc4\x3d\x75\x3d\x3f\x45\x8c\x7c\x00\x21\x16\x99\xb6\xef\x33\x55\x4e\x46\x91\xa1\x60\xa9\x26\x94\xb3\x5f\x85\x06\x93\x60\xc7\x42\x9d\x4b\xeb\x2c\x8a\xb2\x81\xe0\x81\xa4\x4e\xc0\xb6\x7b\xf6\x93\xbb\xc1\xc3\x24\x23\x39\xe1\xed\xed\xed\xea\xcb\xe6\xd2\xa7\x05\x84\x48\x34\x35\xaf\x0e\x03\xd6\xfa\x92\x6f\x23\x44\x82\x68\xc6\x6e\x08\xa3\x00\x6c\xa8\x19\x08\x91\x46\x8a\x79\x2c\xa4\x8b\xfd\x6d\x9c\xf2\x19\x92\x46\x40\x66\xc2\x74\xf0\x20\xbe\x81\xb3\xc2\x29\x5d\x42\xc8\xd8\xb6\xf8\x4f\xe4\xf5\x68\xe3\xc4\x89\x14\xc5\x74\x74\xaa\xe8\xb1\xad\x9f\x36\xab\xfd\xc3\x93\x35\xe2\x38\x6c\xee\x7d\xb5\x57\x48\x2d\xa9\xda\x2b\xdf\xcf\xd5\x79\x82\xb5\x15\x4a\x0f\x0e\x5e\x24\x8f\x77\xbb\x32\xe6\x83\x99\xa8\xe3\x8c\xd9\x66\xb9\xca\x4f\x39\x96\xed\xbc\xc5\x39\xfd\x9d\x5a\x84\x16\xb2\x87\x4d\x7b\x20\xe2\xbe\x24\x54\x2a\xc1\x21\x7d\xf5\x7e\x25\x49\xcc\xba\xcb\x83\x08\xc7\xf8\x08\xef\xbd\xba\x04\x08\x13\x84\x5e\x8a\x7a\x87\x45\x71\x0d\x79\xf1\x6e\x69\xaf\x93\xd2\xce\x7c\x8a\x98\x4c\x7b\x6c\x89\x55\xcb\x21\x32\xe0\x90\xfa\x3c\x62\xdd\x7b\x89\xcc\x3e\x89\x46\x31\x0f\xc5\xb7\x48\xc4\xe9\x8e\x00\x61\xc6\x48\x47\x1b\xcb\xd6\x71\x8e\xb8\x3f\x02\x96\xa9\x38\x62\x25\x4d\x2f\xd3\x8f\xd3\x51\x38\x36\x12\xbc\xae\xdf\x9f\xce\x97\x2a\x77\x8b\xcf\x00\x42\xad\xd1\x6e\xbf\xd7\x79\xa3\x8a\xaa\x39\xd7\xd8\xe5\x6b\xef\xbb\xfc\xb9\x9c\x07\x18\x10\x19\x9b\xf5\x7e\xfd\xf3\xfa\xf0\x70\x2c\x73\x5d\x15\x45\x5f\xcc\x81\xd8\x28\xed\xab\xbc\xbb\x9f\xd6\x4e\xcc\xe4\xcf\x7e\x8d\x83\xa4\xdb\x21\x6c\xe6\x7f\xd3\x6d\x10\xdd\x0e\xfc\x15\xf5\x33\x4e\xfd\xba\x00\x12\x66\xad\x9d\xf3\x86\x44\x44\x9c\x51\xc5\xf7\x41\xd9\x17\x20\x91\x20\xa4\xd7\x2a\xbc\x82\x56\xbd\x4c\x66\x3c\xa4\x10\x90\x54\xe3\x11\x7e\x3d\x86\xbd\xf0\x11\x40\x2a\x63\x4a\x1a\xbb\x0d\xcc\xe5\xd8\x4e\x48\xda\x0d\xc8\x32\x41\xac\x88\xab\xf3\xfb\xa1\x0b\x55\x0f\x56\x82\x2b\x2f\x47\x7d\x14\xc8\x32\x19\x79\x68\xd9\x98\x79\xe2\x0f\x33\xae\x62\xaf\xea\xf4\x8d\xb4\xea\xc7\x4d\x2e\xc8\x54\x20\xe0\x43\x08\x44\x3c\x3b\x1b\x8b\x53\xea\x85\x5e\x79\xf5\x3b\x00\x96\x58\x73\xb1\x03\x1e\xf3\xf6\xe6\xdc\x9e\xeb\x0b\xaf\xa9\x0f\x9e\x37\x63\x8a\x30\x75\xdf\xf3\xe6\x0c\x45\x5d\xa9\x9f\xed\x68\xc9\xeb\xd2\x24\x26\x06\x62\x9e\x4f\xb9\x6d\x38\x3b\x77\xcd\x03\xe0\x3c\x20\xb4\xda\x0e\x5b\xe7\xc7\x4c\x98\x36\xeb\x24\xbe\x00\x8e\xee\xa2\x28\xe6\x74\x53\xae\xaa\x5f\x61\xff\xb5\xc8\x98\x95\xe1\xa3\x22\x90\xfb\xab\x4c\x6c\xab\xa2\x7d\xae\x6d\x14\xe2\x3c\x3a\xfb\x08\x11\x24\x57\xde\x9a\xfa\xb1\x2a\xff\x93\xff\xb1\x90\xb0\x82\x54\x48\xef\xe0\x2e\x3f\x9e\x0a\x9c\xa4\x1f\xa0\x62\x41\xa0\x91\x17\x68\x6e\xa1\x7c\x3e\x8f\x14\xe3\x96\x37\x71\x50\x2c\x05\xbf\x48\x43\x5e\x76\x77\xe9\x7a\xec\x3e\x39\x1f\x0e\x3c\xf3\x9d\x98\x5d\xdb\x0b\x3c\x01\x28\x9d\xd0\x7b\x3f\xc1\x95\x3f\x42\xdd\xe6\x70\xa9\x75\xe7\x3f\x83\x48\x2f\x58\xae\x2a\x9a\x76\x91\x3f\x99\x86\x84\x22\xc4\x3f\xf3\xb6\xc5\xb2\xb9\xae\xab\xd3\xa5\xad\xba\x1b\x8b\x31\xa7\xb1\x27\xab\x75\x70\x43\x28\x97\x9e\x28\xea\x06\x99\x04\x42\xd7\x48\xb4\x3b\xd0\xe4\xe5\x32\x99\x24\xc5\x5a\xdf\x41\x3c\x34\x83\x56\x30\xc8\x40\x05\xe8\x2d\x66\xd7\x55\xa9\xa0\xbd\xc3\x63\x55\xbf\xc7\x11\x75\x9b\xfa\x61\x46\x05\xdc\x6f\x8a\xa4\xda\xfd\xed\x69\xbb\x29\x27\x8e\x78\x20\x43\x25\x9c\xac\x08\xc5\x34\x03\xe8\xdc\x4f\x4d\xcb\x1a\xb8\x28\xd4\xc8\x28\xb1\x90\x84\x53\x55\x4f\xa0\x03\x32\x62\x31\x71\x4f\xbb\x0d\x60\xf3\xdc\xaf\x4e\x32\x8e\x02\x4a\x44\x5e\x73\x7c\x5b\x36\x22\xf6\x03\x53\xae\x6c\x6f\x9d\x30\xef\xd6\x99\x73\x36\x44\x4a\xdd\x45\xd7\x07\x59\x57\x3f\xb1\xbe\xc1\xc1\x03\xfb\x6f\x72\x44\x64\x2c\x95\x2b\xda\x75\x5b\x95\x59\x43\xad\xaf\xa1\x85\xe1\x72\x75\x42\x75\xad\x12\xdf\x36\x65\x5b\xcf\x10\x2f\x32\x09\x5c\xce\x5b\x14\x44\x89\xe8\x82\xbd\xc6\xbe\x45\xfd\x29\xd2\x24\xa6\x35\x74\xbf\x59\xdd\x1d\x1e\x1f\x1e\x6e\x0f\x23\x42\xb5\x4c\x93\xd4\x89\x58\x3a\x55\x8c\x70\xac\x8f\x0f\x32\x55\x8a\xe4\x48\x08\xf8\xde\x8e\xd7\x37\x99\x39\x6f\x08\x27\x17\x38\xf6\xae\xe9\x5b\x44\x92\x25\x96\x75\xd8\x56\x3f\xfb\x3f\xa5\x36\x89\x3f\x76\xb9\xdb\xe4\x45\x95\x8c\x73\xeb\xf1\x5b\xa3\xac\x73\xdd\xbf\x47\x92\x09\x4e\x95\x05\xdb\x29\x9b\xed\x24\x92\x29\x2b\x61\x61\x7d\xa2\xb0\xfe\x0a\xc5\x6b\x5e\x3e\x77\x99\xd0\x13\xb4\x23\x87\x3a\x37\x9e\x8b\x84\x02\x60\x5b\x66\x70\xaa\x9d\xd3\x21\x82\x89\x48\x8f\x30\xa1\x63\x36\xa4\x1b\x02\xa9\x89\x7d\x9b\x00\x4a\x9d\x77\xe1\x56\x43\x68\x45\x3f\x80\x65\x64\x67\xbc\xd9\x15\x55\xdb\x4c\xa6\x27\x30\x23\x32\x1f\x04\xfe\xfa\x82\xe5\x67\x7a\xac\x20\x41\x27\x01\x9b\x68\x14\xd0\x25\x4f\x27\x83\x4c\xa3\xd4\x96\x10\xab\x72\x5b\xaa\x59\x21\x55\x4a\xa1\x49\x21\x4a\xe3\xa9\x40\x8a\xaa\xfc\x11\xc5\x33\xc2\x13\x74\x73\xa0\x6f\x8f\x4e\xa7\x81\xe6\x82\x52\xdf\xbb\x6b\x6b\x6d\xfa\x8c\xd1\xef\x42\x8f\x0f\x66\xbc\xe6\x18\xd8\xdc\xb8\xdd\xb5\x8a\xb8\x6a\xad\xba\x78\x5b\x7e\x67\x8f\x36\x1f\x37\x1e\xcf\xfb\x6f\x32\xd9\xd0\x49\x9f\x08\xba\x81\xd4\x26\x42\x17\x23\xfa\x3c\x78\x12\x22\xba\x61\x18\x42\xe6\x9a\x27\x6d\x81\x04\xd6\x74\xbe\xe0\xee\x57\x2f\x89\x04\x5c\xb2\x78\x25\xc6\x09\x99\x30\xed\x51\x7d\xac\x66\x32\xfb\x6a\x03\x3e\xd1\xde\x1c\x4f\x45\xf5\x8e\xc3\xaa\x6a\x40\x99\x41\x65\x61\x8f\x30\xef\x51\x9d\x27\x5e\xe3\xd3\x13\x1b\x29\x31\x1e\x21\xe6\x7b\x69\xeb\x89\x68\x82\x0a\x74\x46\xf0\xb7\x12\xdf\xbe\xd4\x88\xc4\x2a\x1f\x2f\xda\x2a\x84\xbe\x94\xf2\x03\xf1\xa7\x9e\x19\xad\x82\x0a\xa5\xf5\xd6\xf8\x52\x15\xfa\x98\x97\xed\xb7\xb2\x19\xcb\xc2\x4e\xa6\xb8\x8a\xd2\x28\xb2\x21\x6a\xb7\x1c\x97\x48\x0b\xda\x1f\xfe\xa0\x0e\x83\x41\x4a\xd7\x41\xc9\xdc\xb1\x38\x8b\x68\x42\xfd\x05\xea\xa5\x55\xd5\xf0\xe7\x94\x3c\x29\x3c\x53\x77\x24\x5a\x73\xfe\x00\xc1\xb7\x38\x61\x55\xcc\xad\x06\xf1\x55\x71\x3e\x41\x33\x79\x8d\x55\x2c\x0c\x2d\x81\xe7\xb2\x01\x83\xdb\x66\x14\x4e\x87\xfe\xf3\x49\x24\x8c\xf5\x65\x2c\x9b\x16\xca\x36\x2f\xab\x53\x81\xe4\x03\x72\xe3\x94\xb2\xfd\xe9\xd2\xc4\xaa\x14\x1d\xcc\xb9\x30\x79\x31\x95\x17\x05\x95\x02\x78\x81\xec\xbd\xad\x80\x0c\x24\x4f\x95\x6a\xf4\xec\x48\x2a\xd7\x13\x8c\x19\xeb\xe5\xf0\x40\x65\x32\x92\x5e\xea\x95\x8a\xd9\x24\xc1\x41\xa9\x7d\x55\x8f\xd4\xf2\x41\x65\xda\x32\xcb\x4c\x5d\x35\xed\xa4\xe2\xa7\x98\x60\x94\x6f\x7a\x0e\xdc\x73\xae\xa6\x4b\xa4\x62\x12\x49\xe9\xc9\x06\x65\xdd\xdd\xf1\x9f\xe5\x49\x44\xf8\xd9\x27\xfc\xf7\x39\xaf\x51\xdf\x20\xde\x57\xed\x1d\x7e\x50\xcf\xe8\xc6\x93\xf4\xdf\xfa\xc7\xfe\x33\x1c\xab\xe2\x0c\x8c\x0d\xb8\xaa\xff\x60\xb9\x54\x4e\xec\x07\x5a\x0f\x94\xab\xbc\x6d\xdf\xa0\x9d\xbd\xf8\x8a\x3b\x3f\x2c\xfb\x86\x39\x77\xbf\xd9\x18\xe1\xfc\x24\x24\xbe\x40\x31\x6c\x47\x4a\x18\x4e\x6d\x82\x76\x42\xa4\xf1\x0b\x46\x3c\xac\x0e\xf1\xff\xfe\x9d\xe2\x88\x12\x46\xd9\x59\x46\x0b\xd9\xba\x2a\x5f\xb1\xb6\xe2\x57\x17\x97\x24\x43\xa6\xdc\x3b\xf9\x88\xcf\xcf\xae\x4a\xf2\xc1\xe6\x32\xbb\xc5\x32\x8a\x49\xe6\xc5\xa9\x10\xff\xc0\xfc\x6e\xed\x7f\x92\x8c\x2d\x83\xe1\x1f\xeb\x87\x4f\x5d\x85\x96\x8b\x17\x4a\xa5\x01\xe1\xf9\xb6\xe5\x6b\xf5\x73\xa9\x77\x7a\x91\x43\x28\x85\x48\x28\x0d\xbb\xe3\x3f\x76\x01\x81\xce\xfb\x80\x40\xe9\x20\x25\x1f\x51\xb0\xfd\xbb\x85\xfc\x4c\xe9\x24\xa1\x8a\x99\x87\x86\x7a\x5d\xe1\xfe\xb0\xa6\x0e\x6d\xb7\x32\xdd\x56\xea\xe7\x1a\x9a\x97\xea\xfc\x01\xfa\x41\x69\x15\xa6\x6e\xbf\x38\x9f\x96\x15\xc4\x41\x69\x1d\xd9\x8c\x8f\x70\x6d\x8f\x0b\x02\x59\x33\x1d\xe5\xee\x23\x06\x82\x51\xe7\x70\x5e\x96\x5c\x9c\xeb\x93\x9a\x65\xe4\x04\x01\x14\x0a\x65\xc9\x90\xd0\xe2\x63\x01\x65\xf3\x60\xac\xe0\xc6\xe7\xed\x50\x85\x10\x91\x3a\x71\x4e\x56\x19\x36\x7a\xb4\x7b\xa1\x1f\x60\xac\x6f\x02\xb6\x2f\x50\xb7\xab\xba\x5d\x75\xeb\x6f\xbf\x97\x2a\x13\xb0\xd0\xc1\xfb\x76\x2d\x9e\xf6\x6f\xd5\x52\x17\xc2\x0f\x4e\x2c\xc2\xc8\xd7\x3b\xec\x62\x19\xf1\xc5\xd5\xd8\x3b\xe3\x81\x32\x9c\x93\xf0\xcf\x63\x5e\x14\x50\x2f\xce\x41\x3b\x52\x07\x4c\x52\x3b\xad\xaa\x41\x15\xf8\x70\x6e\x55\x75\xc4\x66\x19\xf2\xa0\x03\xff\x9a\xdb\x22\x41\x9f\x66\xd8\x84\xdd\xfd\x40\x1d\x2a\x49\xe5\xae\x5e\x27\x7c\xb0\xff\x58\x9c\x2d\x3a\x4a\xad\x7b\x50\x17\x90\x5a\xf1\xee\xfb\xf3\x8c\x03\xa6\x23\xe6\xfa\x14\x05\xe4\xc7\x5e\x46\x75\xf9\x37\xc5\xcc\x6a\xda\x68\x6c\xda\xba\x7a\x5f\x8f\xcc\xfd\xfe\x6b\xbc\xd9\xe8\x98\x59\xa5\xa3\xeb\xff\x7e\x1c\x6f\x54\x3a\x89\x52\x8a\x78\x73\x55\x45\x59\xff\xc7\x84\x51\xd7\xfa\xf1\xdc\xe6\x63\x79\x14\x9d\x18\xa0\xb2\xca\xe6\x69\x1d\xf5\xda\x35\x3a\x15\x8a\xe6\x49\x97\x0e\x9d\xe0\x7d\xd6\x9c\xd4\x29\x64\x5c\xf5\x94\x89\xad\x26\x2b\xa6\x09\xde\xbb\xdb\x49\x08\xeb\x42\xf5\x7b\xaf\xb8\xdd\x8c\xba\xa8\x3a\xc3\x2c\xb1\x28\x85\xe7\x17\x57\x6c\xe8\x0f\x19\x61\xe2\x5e\xc4\xe9\xd7\x24\x16\xd1\x8c\x09\x02\x11\xb9\xee\x62\x8f\x31\x5a\x7e\x3c\x3c\x65\xe0\x26\x34\xd6\xbb\x8b\x36\xa4\xe6\x3c\xce\x7a\xbb\xc2\x03\x0c\x7a\x35\xb3\x9f\xcc\x15\xcf\xac\x18\xee\xba\x3a\x1e\xa9\xc8\x34\x8a\x4c\x34\x57\xc2\xca\x4e\xd1\x1e\xb2\xcb\xbb\xeb\xf5\x78\x83\xbf\x15\x2c\x6b\xa1\x99\xc7\x21\x74\x41\x94\xc5\xcb\x8e\x1a\x83\xd3\xcb\x81\x28\xe4\xae\x44\x68\x41\xea\xe3\x88\x57\x43\x2c\x89\x72\x02\xb6\xab\xaa\x97\x48\xee\x7e\x28\x6a\x57\xc9\x2e\xf5\xc1\xb9\xe6\xf5\xa7\x31\xa9\x19\x5c\x5e\xba\xb4\x78\xa1\xc9\xae\xc1\x30\x7a\x8e\x48\x11\xe6\x63\xf5\xd6\xaf\xbb\x5a\x62\x4a\xcd\xb1\x9e\x30\x67\xcd\x3c\xdc\x51\x15\x48\x67\xd4\xd9\x5a\xe9\xfe\xe6\x25\x3f\xcd\xf5\x3e\x87\x1b\xa4\xa4\xa6\x86\x71\xde\xec\x5f\xf2\xe6\x2b\xd4\xda\x10\xac\xc2\x99\xd5\xfb\xb3\x9a\x2c\xf5\x78\x52\xeb\xd8\xdb\x2d\x50\x4d\x0b\xc7\x99\x6c\x22\x06\x41\x60\x8d\xd6\x60\xa4\x1f\x30\xf1\x8c\xf5\x03\x41\x65\x56\x80\x41\x36\xa3\x57\x07\x03\x93\x26\x54\x90\x20\x20\xe8\x6a\xde\xed\xc2\x30\x42\x9a\xa8\x37\x5f\x6f\xc6\x2f\x28\x86\xdc\x26\x08\x6e\xae\xb4\x40\x58\xd0\x49\xe4\xf0\x61\x12\x34\x7e\x13\x30\x92\xdc\xda\xce\x7f\x5d\xed\x36\x33\xfb\x6d\xc0\x48\xc5\x74\xf3\x9d\x3d\x81\xdf\xc7\xf6\xf9\x88\x12\xf0\xbb\x94\x66\xf4\xff\x75\x73\xa6\xff\xc7\x7d\x45\x1c\x5a\x74\xbe\x6d\x1a\x7d\xf9\x70\x91\xc4\x38\x01\x31\xcc\xa4\xe2\x14\x66\xd3\x49\x84\x71\x22\x69\xdf\xd9\x18\x24\x70\xf3\xe4\x86\xc5\x59\x42\x50\x79\xf2\x63\x3c\x24\x56\x4e\xf8\x70\x1a\x91\xb8\x30\xd1\xb6\x77\xf4\x27\xbe\x3b\x6d\x8a\xb1\x62\xd7\xe2\x4a\x8b\x09\x0a\x0a\x3b\x8e\x07\x35\xc2\x66\x8d\xd7\x28\x4c\x43\x10\x30\xae\xc4\xe3\xeb\x12\x33\x19\xd3\x54\x5b\xeb\xb7\x23\x96\x1a\x35\xa1\x5b\x3d\x09\x87\xe4\x57\xfa\x7c\x0e\x53\x9d\x30\x57\x25\xbb\xaf\x34\x36\xdf\x61\x0e\xf1\xc5\x14\x51\xc9\x81\x7f\xf9\x18\x5f\x5f\xe7\xaf\x1b\xa8\xbb\x84\x68\x3e\x36\x03\x49\xd0\x46\xdb\xaf\x7a\xcd\xbb\x57\x61\x98\xf1\x2e\x6a\x98\x3d\x0d\x9e\x66\x16\xf9\x5b\xe7\xa5\xfe\x56\xe6\xaa\xaa\x67\x82\xcb\x80\x3c\x0b\x68\x41\xa3\xae\x3b\x85\x5c\x43\x24\xe4\x87\xa8\x34\x75\x58\xb5\x1f\x6f\x93\x52\x10\x72\x34\x81\xab\x79\xdc\x42\xd3\x76\x73\x6e\x92\x29\x21\x37\xce\x36\x79\xb7\xf6\x28\x4d\x14\x01\x24\xb6\x49\x70\x5f\xb5\x50\xbf\xaf\xb4\xa5\xb9\x90\x9a\xca\x6f\x4b\x10\xe3\x38\xc9\x9f\x30\x0e\xbd\xfa\xed\xa3\xe5\x6b\x7c\x3b\xed\xab\x4b\xc8\x31\x8a\x0c\x19\x1b\x93\x16\xaa\xfa\xe8\xc2\x82\xd9\x40\x30\x59\xe8\xdb\x04\xc4\x69\xf8\xa0\x4c\x8c\x10\x00\x81\x26\x0b\x2c\xf5\x80\x6a\x41\x48\x2d\xbe\x6f\x55\x93\x9a\xd1\xe7\xed\x7e\x04\x06\x94\xe8\xed\xb0\xdd\x5e\x5b\x11\xad\xe5\xa9\x2c\x03\x1b\x34\xdc\xe6\x0d\x4c\x5e\x1d\x09\x21\x0c\x79\x9b\xb5\xd7\xef\xf6\x41\x02\x01\xcf\xa6\x92\x4a\x32\xc6\x06\x94\xec\x6d\xd5\xe4\x8e\x01\xde\x4f\x5e\x95\x25\xe4\xde\x68\x4f\xd7\x13\x3c\x4a\xbd\x86\xa2\xf8\xe1\x57\xf9\xf9\x79\x8d\xa0\xaa\x3f\xf5\x36\x7c\xa9\xea\x89\xce\xf0\x41\x85\x00\x35\x07\x96\x8d\x4b\x95\x93\x12\x15\x6a\xb0\x5e\xf2\x76\x39\x71\xfb\xec\xb2\xcc\x0c\x6a\x0d\xda\x9a\x89\x50\x2e\x75\xf5\x73\xbe\x0f\x98\x20\x05\xc7\x74\xd9\x55\xe5\xf3\x8f\x3a\x6f\xfb\xf2\xf8\x32\xe3\x0f\x0d\xb7\x72\x3f\x87\xbc\x79\xd0\xfa\xa6\x80\xe7\xf9\x39\x55\xac\x1c\x3b\xb8\x87\xa6\x93\x3b\xc1\x12\xe7\xd3\xc5\xbd\x26\x4c\xad\xb7\xea\xe1\xe8\x30\x72\x93\x73\x9a\x30\x4b\x69\x55\xd8\x3c\x12\x0f\x7c\x9a\x3c\xf8\x31\x92\x53\x2f\xe3\x74\x2e\x8a\x11\x09\xce\x84\x46\x64\xe0\x79\x1f\xdd\xfa\xda\xe5\xaa\xe4\xec\x3d\x49\x3f\x4d\xc4\x24\xa1\x41\x0e\x35\x6a\xc4\x4b\x4d\xb8\x49\x2d\x6e\xfc\xae\x99\xd8\xa5\x7d\x7e\xa5\x5c\x8e\x99\xa7\xf7\x91\x7a\x12\xcc\x33\x6b\x27\x8f\xd8\x24\x2a\xa4\x6d\x7c\xbf\xdd\x3c\x25\x87\xa7\xd5\xde\x77\xe8\xbb\x4d\xd7\xd9\xd1\xd7\xe5\xae\x3a\xe2\x82\x5e\x3c\x98\x34\x53\x32\xe8\x97\xd0\xa9\xfd\x18\x98\x4c\x84\x84\x77\x6a\xac\xcf\x20\x6a\xe7\x94\x35\x7e\x75\x4c\x66\x0c\x55\x95\x80\x34\xe5\x67\xe7\x67\x88\x44\xb4\xf8\xbe\xbd\xfe\x3d\x84\xc9\xf0\xc0\x04\xe8\x15\x78\xbb\x69\xd8\xad\xd2\x1f\xbc\x2e\x46\x70\xeb\xbc\xd6\x60\x4b\x6d\x06\x0b\xe3\x9e\x7e\xbd\x0c\x98\x4a\x7a\x1e\x0f\x79\x64\x74\x8f\x35\x6f\x67\x5a\xce\x46\x06\xd6\xae\xb5\xfb\x9e\xeb\xfd\x57\xff\xdb\x24\x28\x31\x95\x8c\xa0\x9f\xfe\x31\xff\xde\x48\xc9\xb4\x4b\x73\x1c\x7e\x0e\xea\xf7\x83\x99\x56\xb5\x8c\x0a\x12\x7a\x6f\x9f\x50\x3f\x52\xbb\x38\xff\xff\x58\x7b\xb7\xe6\x56\x71\x35\x6f\xfc\xbb\xbc\x57\x7d\x31\x17\x20\x09\x10\xff\x3b\xdb\x71\xb2\x3c\x9d\x83\x27\xf6\x5a\x6b\x76\xef\x9a\x72\xe9\xf0\xc8\x61\x2f\x0c\xde\x80\x93\xb8\x3f\xfd\xbf\x78\x24\x71\x0a\x49\xf7\xd4\xfb\x5e\xa5\x2a\xc8\x18\xb0\x90\x9e\xc3\xef\xd0\x1f\x4a\x12\xd4\xc9\x3c\x64\x75\xf7\x2f\xb0\x72\x20\xd8\xff\xaf\x6c\x75\xa8\x3e\x68\x38\xbb\xbe\xb8\xdf\x2d\x8c\x4e\x98\x77\xd0\xb0\x15\xfc\x69\x3c\x6c\x34\x17\xa1\x2b\x89\xdd\x5b\x6e\xcd\x88\xd4\x33\xbe\x17\xcd\x85\x35\xba\x87\xba\x59\x37\x2f\x3e\x3b\xf1\x97\xd5\x46\x9a\xe0\x5d\xf4\x2d\x2c\xbd\x4b\x4d\x0c\x10\xc3\x5d\x71\xa0\xab\xc9\xf8\x17\x18\x62\x82\x44\xdf\x73\x2e\x14\x2c\x3f\xab\x6f\x19\x23\x39\xa6\x1c\x59\xbd\x15\x55\x53\x7c\x22\x3e\x22\x83\x00\x24\xee\x91\x58\xb5\x5b\xbf\x83\xba\x0c\xe0\x8d\x6e\x4c\x48\x0d\x4a\x10\x1f\x84\xd6\x3f\x2c\x5e\xe1\xaf\x42\xc8\x2e\xf8\x97\x01\xa1\xca\xf0\x6e\xaa\x4d\xb2\x04\x3f\x06\x28\x76\xc6\x37\x85\x2a\xab\x0a\x54\x33\xc3\x9f\x71\x43\x69\xc0\x30\x85\xf1\x02\xd8\xce\xae\xf2\x6b\x26\xa4\x0c\x68\x68\xc5\x68\x7e\x65\xed\xa2\x75\xca\x8a\xa7\xc2\xb3\x1d\xda\x83\xd6\xc4\xb4\x7e\x29\x2b\x84\x78\x38\xa5\xd2\x3e\x50\xe7\x9f\x9d\x56\x84\xc8\x2b\x3c\x58\x4d\xeb\x36\xd4\x76\xa2\x39\x93\x3b\x64\x44\x59\xcd\x4e\x2b\x1d\x5d\x0f\xfd\x1f\xdd\x90\x48\x43\x62\x45\xcd\x5e\xa1\x68\x5e\xf6\x20\x4e\x1d\xa4\x2e\xf7\x97\x1a\xa7\x09\x0c\xcc\xb0\x26\xdf\x12\x43\x88\x4d\x46\x67\x6f\xfc\x33\x2b\x9c\x57\xdc\xf1\xa5\xf9\x38\xd8\x58\x38\x02\x88\xc6\xc7\x67\x8b\xbc\xe3\xfc\xc9\x20\x21\x01\xae\xf3\x0a\x37\xf4\x3b\x51\x0f\x14\x0d\x64\x90\xa4\x06\xf1\xa6\x48\xdd\x29\x8d\xff\x37\x67\x9a\xa5\x3e\xab\xee\x20\xde\x32\xe0\xa9\x35\xda\xf4\x25\x0f\x77\xfd\x83\x92\xb3\x0c\x52\x99\x10\xe1\xd2\xe4\xea\x75\x84\x21\x94\x41\x0a\xd2\x8a\x1d\x1f\xe0\xfd\x3c\x79\x72\x22\xd0\x96\x96\x63\x4b\xcf\xd8\xf3\xed\xdc\x22\xdd\xaf\xf8\xa1\xbf\x32\xd8\x59\x64\x20\x34\x37\x5e\xfc\xbe\x11\xbf\x40\xef\x5e\x26\x82\xa6\xed\x18\xeb\x37\xed\x24\x71\x91\x71\x3a\xdd\x6a\x07\xf3\x5e\x0a\xa9\xad\xb9\x22\xd6\x0e\x66\x76\x10\x19\x48\x69\x2c\x8e\x57\xeb\x75\xd1\x54\xe5\xb9\x9b\x92\xd2\x51\xed\x11\xd9\x77\x1a\xc4\x64\x83\x6f\x50\x49\x8a\x44\xa6\xe6\x52\x15\x4f\xc5\x53\x25\x54\xde\xee\xb6\xee\xa8\x8e\x58\xe8\x4c\xb9\x11\xf2\x04\x79\x3e\x58\x81\x64\xa0\x85\xd0\xb2\xbb\xe5\x26\x53\x8b\xaa\x12\xdd\xf7\x6b\xc3\xb0\x59\x2f\xea\x1a\xaa\x66\xfd\x6f\x42\x5d\x9c\x4f\x5d\x95\x90\xba\x81\x40\x14\x8a\x73\x59\x45\x0f\x5f\x77\xba\xef\xe8\xcc\x32\x80\x28\x40\x17\xb3\x6f\x65\xae\x47\x85\x36\x7f\x3c\x21\xa1\x8b\xe3\x97\x97\x6a\x5a\x5c\xf6\x83\x20\x20\xa2\x83\x6a\x7a\xed\xda\xc9\x20\xc3\xa8\x6d\x63\x89\xc2\x2e\x65\x9f\x2c\x22\x61\x10\xf3\xd4\x2a\x0f\x08\x8c\x54\x0e\x5d\xf5\x70\x74\xc2\x30\x24\x3c\x84\xae\x06\xe5\xda\x19\x13\xa9\x9a\x71\xa9\xfd\x9f\xe4\x7f\xfc\x67\x59\x44\x7a\x05\x8c\x9e\xf1\x33\x7b\x7f\x61\xc8\x2c\x43\xf5\xdc\xbb\xc3\x7e\x18\xa0\x50\xa0\x05\x61\x75\xbb\xef\xdb\xed\xfd\x3f\x0e\xcb\xa7\xef\x8f\xfb\x7f\x1c\xee\x37\x0f\x1b\x87\xf2\x91\x61\x98\x72\xd2\xc5\x01\x65\xae\xcb\xb7\xc2\xd1\x29\xfc\x00\x48\x84\x0b\x5b\x7e\x94\x56\xc6\x51\x54\xfe\x3d\x0b\x09\x0b\x63\x97\xcf\x7c\x83\xaa\xec\x05\x8c\xa6\x51\xaf\x0c\x89\xb6\x1d\xe0\xe5\x7e\xd7\x6f\xc2\x32\xa4\x24\x02\xd1\x71\x31\x2c\x98\x7a\x65\xcd\x0d\x1c\x02\x7f\xfc\x16\x84\x8c\x4a\xdc\xd2\x5e\x44\x25\xce\xa2\x3b\x0f\x83\x00\x9b\x74\x9d\xf7\x52\x3e\x5f\xce\x94\x61\x4c\xad\x60\xba\x6f\xae\xcf\x5a\x1e\xb8\xb1\x49\x10\x60\x50\xd5\xc5\x22\xd6\x9c\xa1\xaf\xe4\xcb\x30\x61\x01\x96\x67\x9b\x0c\x2a\xda\xfd\x53\x6a\xcd\x3f\xc4\x9e\x7f\x47\xd4\xd8\x9d\x80\x4b\xeb\x26\x81\xbd\x2d\x30\xcd\x53\x9b\x29\x38\x43\x3e\x51\x35\x59\xdd\x60\x39\xc1\x8d\x4e\xc1\xd6\xad\xb2\x1a\x43\xfa\xa1\x2e\xa5\x0c\x45\x64\x81\x4f\xae\xb8\xf3\x26\xce\x2e\x91\xf4\xa9\xf8\x67\x21\xf5\xf8\xb1\x49\x60\x84\x75\x13\x01\xea\x25\x34\x6f\x60\x3d\x08\x3e\xdb\xd7\xc7\x27\x50\x51\x94\xba\x25\x06\xf1\x93\xbd\x47\xa1\x0c\x15\xb7\x4a\x3f\xd2\xca\x8d\x61\xd4\x37\x7e\x20\x4a\x48\x36\xa2\x6e\xaf\x9b\x97\x7d\x39\x6b\xee\xea\x3f\xa1\x15\x82\x28\xf0\xb1\xc5\x37\xd9\x6b\xfd\xf4\x36\x90\xbd\xf5\xa3\x8c\xc1\xad\xf6\x5c\x36\x07\x7f\x35\x3a\xb0\xe8\x22\xb7\x18\xeb\x01\xfa\x54\x86\x9a\x58\x57\xc2\x93\x78\x47\x83\xbe\x41\x8e\x20\x43\xad\x08\xd2\x50\x9d\x72\xfa\x10\xe4\x8e\x6a\xb2\xdd\x04\xd1\x9a\x78\x85\x96\x2e\xea\xb6\x6d\x8f\xf1\xe5\x69\x6d\x6b\x87\xd6\x36\xc1\x41\xf8\x3a\xac\xa1\x0c\x41\x2a\x84\x5d\x9c\xa1\x3a\x43\x73\xf1\x2e\x06\x32\x04\x45\x82\xae\xd2\x50\x9e\xa1\x6a\xae\x0e\x5f\x81\x7a\x41\x36\x98\x1d\xec\x0f\x21\x98\xd8\x3b\x0a\x3e\x5c\x6d\x47\xf6\x93\xf5\xd0\x84\x11\x1a\xd6\xd9\x8e\xe0\x4d\x25\x8e\x65\xf1\x51\x95\x5c\x86\x46\xc6\x9a\x75\x21\xfd\xa3\x50\xed\xfc\x7f\x84\xc6\x4c\xc7\x41\x88\x80\xbd\xf5\xe3\xee\x19\x70\x6a\x4c\x82\x0f\x12\x04\xc6\x12\x53\x72\x10\xd5\x60\xf5\x20\x81\x00\x9a\xfe\xef\x18\x67\x9f\xd5\xbb\x25\x09\x19\x45\xbc\x7d\xbb\x10\x6e\x7c\xab\xd1\x1f\x13\x91\x23\x8a\xe7\x39\x54\xc6\x67\x41\xfd\x61\xe1\xcd\x4b\x97\x65\xa1\x67\x9e\x06\x21\xce\xeb\xd2\x9b\x77\xec\x2e\x72\x96\x06\x2f\x09\x49\x42\x4c\x59\xce\x9b\x1b\x3f\x25\x09\x8d\x59\xd0\xf5\x6b\xb6\x79\x39\x1f\xc9\x4b\xc2\x08\x41\x34\x0d\x22\x4a\x97\xd7\x8f\xc0\x7a\x49\x18\x08\xec\x3d\xab\x5e\x5c\xd5\xad\x80\x7e\x80\xe9\x5c\x54\x5c\x16\x3a\x15\xe9\x68\xc7\x24\x18\x4d\xac\x76\x67\xa1\xa0\x1e\x3d\x2b\x66\x74\xe0\x6a\xb0\xbf\xc3\x15\xc9\xa7\xe3\x1b\x8c\xe2\x10\x5b\xca\x79\xa9\x7e\xa1\x2f\xe0\x10\x2b\x24\x49\x94\xca\xa8\xa3\xa8\x9e\xd0\xdf\xeb\x15\xd0\x64\xa0\xd7\x72\x90\x24\x92\x06\x6d\x6b\xba\x4a\xfe\x27\x4f\x33\x4e\x05\x36\x9f\xba\x4d\x7b\x04\x8e\x91\x24\x09\x08\x42\xa0\xed\x8f\xf2\x96\x35\xea\x65\xb6\x43\xec\x87\x13\x85\x38\xed\xbb\x0a\xa0\x90\x59\x77\xd1\x09\x63\x91\xeb\x7d\x7f\x2f\x54\xc7\x69\x19\x3f\xb5\x44\x10\xdc\x96\x0d\xa8\x97\x76\x11\x7d\x10\xd6\xfc\xe6\xb6\x44\x5d\x84\x6a\x79\xdd\x15\xe2\x5c\xbf\x94\x4e\x4d\x72\xf6\xfd\x23\x5c\xc4\x98\xb7\x96\xd5\x51\x14\xd9\x9f\x50\x11\x7f\x11\x5c\x6a\x5b\x20\xc8\xf3\x67\x78\x05\xd1\x35\x60\x24\x49\x69\x80\x45\xa7\x4d\xbd\x59\x3d\x55\x97\xa2\x77\x16\x92\x24\x55\x8c\xb9\xa4\xeb\xae\x9c\xf0\x0e\x25\x11\x0c\x10\x2c\x81\xf8\xbe\x6a\x64\x03\x21\x89\x88\x19\xa6\xed\xeb\x95\x93\xe7\xfd\x59\x89\xf3\x79\x5c\xad\x9a\x47\x16\x48\x22\x94\x10\x81\x33\x3d\xba\x13\x0d\xbc\x75\x01\x25\x91\x22\xc0\x70\xb8\xac\xb2\x63\x56\x78\xcd\xae\xee\x28\x04\xc8\x88\x58\x66\x85\x78\x1f\x4d\x3d\x15\x24\x41\xec\x11\x08\xb8\x30\x8f\xef\x45\x91\x08\xab\xfe\x0f\x50\xb5\x91\x56\x83\x3a\x88\xdf\xb2\x1a\x8d\x5c\x86\x69\x2c\x51\x3c\xd5\xb6\x4c\xa9\x01\x4e\x63\x82\x9e\x24\x4a\x2a\xb4\xdb\xc2\x1e\xde\x04\x32\x2c\x89\x8e\xc2\x78\xe8\x50\x78\x70\x86\x1b\xe8\xa9\x7f\xd8\xac\x9e\x3e\xe2\xb7\xdc\x27\x0d\xb1\x76\xba\x59\xbd\xcf\x72\xb8\xcf\x5e\x67\x94\x8d\x24\x31\x29\xc8\x41\xe2\xf6\x08\x6f\x4e\x18\x7b\x34\xf3\x69\x48\x03\xdb\x0d\x42\x83\xe1\x07\xf1\x7e\x2f\x3a\x95\x23\x49\x43\x26\x11\x40\x78\x5f\x1e\xb7\xbd\x8c\xa3\xa4\x61\x9a\x20\xe2\x08\x63\x67\xbf\x81\xf9\x07\x4c\x49\x18\x05\x4e\xeb\xe3\x5b\x79\xa9\xe6\x6b\xcd\x92\xd2\x50\xf9\xa8\x71\x95\x35\xe2\x83\x0e\x86\xa4\x14\x84\xea\xdd\x34\x1d\x4f\xad\xa9\x2e\x0a\xb3\xb0\xcb\x18\x61\xf7\xbf\x68\x0a\x5d\xc6\xaf\x37\x65\xa1\x00\xdd\x49\xbf\x61\xb6\x36\xb5\x4d\x92\x34\x62\x0c\x7f\xec\xff\x14\xbf\xca\x57\x7f\xab\x91\x00\xea\x78\xc6\xfb\xec\x64\xad\xcb\x26\x6c\x05\x49\xe3\x94\x13\x57\x7c\xb1\x10\xd9\xe1\x24\xa2\xb1\x54\x58\x3f\xfd\xd9\x06\x8c\x03\x05\x45\x49\x13\x62\xad\x58\x76\xf5\xcb\xef\x5e\x77\x56\xd2\x84\x19\x04\x46\x2d\xf7\xeb\xc7\xee\x7f\x71\x84\xbf\x47\x2e\x6a\xbb\x2a\x1c\x5e\x43\xfa\x4d\xd4\x2f\x07\x77\x25\xfd\x40\x40\xfc\xd6\xb2\x2c\x75\x39\xac\x1f\x49\x9a\xa8\x64\xa0\xec\xe4\x60\xf4\x93\x67\x90\x28\x83\xdb\x42\x9e\x35\xcd\xa6\x5e\x89\x73\x7d\xc9\xc7\xc5\x58\x49\x39\x0f\x9d\xc8\x87\xf8\x05\x37\x16\x0e\xf0\x11\x04\x3e\x2b\x4a\x20\x69\x1a\xd9\xaa\x76\x1b\x28\x07\xf7\x4f\x3e\x05\xa1\x69\x2c\xb0\xb8\x65\xe7\x00\x76\x77\xf6\x20\xaa\x31\xa6\x70\xe6\x97\x4d\x79\x64\xad\x85\x5f\x44\x35\xd0\xf4\x6d\x0f\x08\x8b\xad\x11\x59\x51\x58\x3b\x90\xee\xdd\xa4\x22\xb2\x95\x88\xda\xcb\xcd\x23\x38\xfd\x46\x5c\xfb\xf2\x03\x15\x32\xb2\x26\xc3\xe2\xba\xbb\xc8\x8e\xc6\xdb\x35\x4d\xda\x11\xa9\x72\x60\x38\xac\xfe\x4c\x9e\xa5\x30\x5d\x3e\x8e\xa8\xcd\x42\x5c\x9a\x7a\xa2\x67\x38\xf9\x88\x0c\xad\xb7\x57\x51\x36\x7f\x40\x35\xa9\xf6\x50\x19\x59\x53\x8e\x73\x05\x0f\x59\xd1\x5d\x86\x8c\x43\xe4\xc9\xef\x30\x79\x5a\x66\xc7\x4f\x4e\xae\x58\xe4\xb3\xf7\x76\xc5\xbb\x11\x8d\x58\x3a\x0d\xea\xc9\x17\x29\x08\x99\x43\x1e\x1f\x4e\x59\xf1\x7d\xbd\xaf\xb7\x50\x59\x7b\xd6\x87\xb2\x82\xfd\x8b\x98\xbe\xc9\x9a\x87\x32\xee\xdd\x7b\x70\x8e\xf6\xfd\x3e\x37\x08\x54\x80\xb1\x15\xe2\xc0\x17\xab\x55\x9b\x8a\xfa\x63\x86\xa6\x18\x5b\x1d\xec\x5a\x70\x3f\xd4\x51\x1e\xdd\x07\x0b\x53\x19\xb9\xd4\x4d\x89\x6a\x1c\x66\x8d\x57\x20\x16\x2a\xab\xd5\x8b\xb3\xca\x27\x6b\x2c\x54\x32\x1e\x06\x03\xdb\x0a\x1c\x6a\xf2\x93\xe4\xe7\xb3\x9c\xe6\xab\x8d\x8d\x85\x60\x7d\x8f\xff\xb8\x56\x57\x51\x94\xaf\xbf\x5f\xe4\xee\x3b\x09\x42\xde\x5d\x86\x61\x23\x51\xa4\x36\x3f\x18\xcc\x60\x46\x34\x09\xf8\x40\x6f\x1b\x15\x94\xaf\x0d\x50\xf2\xdb\x47\xac\xb1\x64\x94\xa4\xa8\x54\x78\x12\xef\x07\x53\x56\xcd\xa5\xe8\x16\x1a\x46\x65\xc4\x7b\x09\x18\xac\x0e\xcd\xd8\x9d\x4b\x46\xb5\x8a\x7c\xe5\xdb\x66\xab\x8b\x0a\xec\xab\x73\x73\xa9\xbc\xf7\x84\x1b\xcc\x52\x85\xd8\x1d\x87\x7f\x1b\x89\xde\x4a\x16\x91\x14\x43\xa1\x43\x6d\xeb\x63\x59\x71\x5c\x9f\x4b\xf5\x82\xaf\xdb\x48\x26\xdb\x7d\x20\x4e\x42\xd4\x47\x7b\xc3\x0b\x5b\x95\xa7\xd3\xa5\xc8\x9a\xab\xf3\xca\xf8\xad\x1f\x15\x59\x18\x7a\x79\x5e\x7b\x0d\xe2\x0f\x35\x4f\x16\x73\x8b\xc0\xfa\xcf\x9b\x45\xd1\x40\xd6\xff\x3f\x65\x58\x7a\x7a\xce\xbc\xe4\xe2\xf8\x01\x24\xa1\x6d\x98\x0f\x30\xd9\x22\x47\xdb\x81\x0c\x79\x77\x27\x28\xba\x56\xe1\x3c\x52\x5e\xb2\x34\x66\x58\xbc\x12\x7f\x8a\x26\x3b\x0f\x97\x60\x26\x58\x84\xfd\xae\xd5\x4b\x9b\x7c\xdf\x66\xef\x93\x67\x20\xa2\xc0\x8a\x14\x60\x04\x8a\x52\x26\x4d\x26\x73\x20\x41\xaf\x3e\x26\x99\x30\x16\x55\xe8\x09\xa9\x08\xbe\x9e\x8d\x12\x99\x8c\xa9\x6d\x97\xaf\x31\x61\x9a\x1c\xe4\x09\xf2\xbd\x10\x1b\x33\x48\xa8\x98\x94\x09\x4a\x7e\xde\xec\x66\x90\xe2\x6e\x8c\x0a\x42\x04\xe5\x3e\x97\x32\x2b\x54\x99\x15\xeb\xe7\x15\x09\xbe\x00\xc6\xb6\x1f\xd1\xd8\x9e\x5c\x3e\x3d\x7e\xdf\xf9\x70\x95\x29\x12\x60\xf6\x76\x58\x1e\xac\x3b\x15\x2e\x96\x4d\xd9\xc0\x4d\x9b\xbe\x94\xe7\xf6\x99\x8f\xe2\x4d\x06\x84\x42\xe8\xfc\x50\x77\xfb\xc5\xc3\xf6\xb0\xfc\xbe\xfa\x7d\xbd\x3f\xec\x36\x7f\xac\xbb\x41\x94\x6b\x67\x4b\xe5\xf8\x77\xdb\xb2\xcc\x47\x15\x62\x66\x38\x50\x27\xd8\xb0\xfa\xe3\xf9\x7e\x26\xda\x9e\xcf\x12\x99\x49\x03\x0b\x4f\x12\x39\x6c\xea\x27\xff\xe4\xa2\x80\x01\xaa\x5b\xe4\xe5\xf1\x11\xde\x2c\x31\x75\x3c\xc5\xa2\x40\xa5\xc6\x45\x45\x6d\x30\x30\x71\x3b\x91\x51\x48\x01\xdf\x55\xd7\x1c\x14\x45\xd3\x09\xf1\x8f\x4f\x44\x98\xd5\x6f\x5d\xef\xef\xf6\xc8\x58\xea\x7e\xc0\x88\x18\xbb\x53\xf8\x15\xee\x1e\x4c\xd3\x1f\xe3\xa9\xeb\xe3\xdd\x65\xa6\x99\x79\x0b\x22\x1a\x04\xa9\x17\x64\xf5\xe5\x86\xfd\xfe\xa7\x73\xee\x09\xfd\x99\x28\x53\x98\x31\x5c\x90\x78\xe8\x54\x6a\x86\xf3\x3d\x62\x3a\x44\xf7\xb4\xb7\xec\x0c\xd6\x3a\x0d\xb4\xd5\x1d\xac\xbb\x21\x26\xb4\x31\x50\x38\xbc\x81\x38\x14\xa1\x0b\xe1\x1f\x44\xa3\x5e\x3e\xf6\x3e\xa2\x98\xc6\x91\xe7\xc7\xd9\xc6\x74\x3d\x26\x62\xfb\x71\x32\xc4\x44\xd4\x06\xc0\xdd\x17\x28\x4d\x6c\xf4\x6c\x45\xfb\xca\xe6\x65\xfe\x15\x8a\x62\xad\x8c\x0b\x91\x6d\xe9\x7e\x53\x6f\xc5\xb5\x5d\xac\x47\xe8\x36\x19\x25\x32\xc0\xb8\xed\x0d\x9a\x97\xd1\x53\x48\x40\xa3\xad\xd9\xba\x28\x8b\xe7\xf1\x11\x23\x51\x08\x66\x87\xac\xa1\xd5\x0b\xfc\xfb\xe2\x54\x4a\xc7\xd7\xc0\xa9\xa5\x8c\xed\xd6\x8f\xab\xc3\xea\xe9\x11\xc5\x82\x91\x44\xb5\xde\xed\xfc\xc9\x38\xe3\xb8\x6b\x1f\x9c\xcc\xc0\x68\xf2\x8d\xd7\xa8\x88\xeb\x00\xf5\x02\x5d\xdf\xe4\xf6\x52\xe8\x71\xfe\x1f\xa5\xc0\xad\x7a\xc2\xe5\xcf\x3f\x07\xd2\xb7\xb3\x7b\x5d\x24\x02\x88\xa3\x5e\x91\xc1\x16\x88\x8f\x80\xbf\x9a\x1f\x92\x90\x58\x77\x7a\x46\xc7\x4a\x9c\x66\x7e\x53\x15\x10\x4c\x47\x9a\x97\xaa\x7c\xab\x7f\xbe\x40\xf1\x2d\x43\x82\xdc\x37\x64\x5e\xfb\x40\x22\x52\x8c\x24\xb6\x76\x70\x9c\x5b\x9c\x22\xad\x2c\x89\xab\x2a\x2f\x85\x46\xaf\xd0\x9b\xf2\xad\xa0\xbb\xdb\xf5\xfb\x24\x1b\x8f\xb4\x12\xd8\x40\x76\xd8\x93\xdd\x8c\x4b\xbb\x8c\x80\xeb\x78\xa8\x9d\xd9\x91\xb0\xdd\x71\x43\xd2\xc4\xb1\x3b\x17\x8d\xa7\xdf\xcd\x4f\x27\x43\x0c\x06\xac\xfb\x4a\xbc\x42\xfe\x07\xe8\xec\xef\x09\x8e\xc8\xc8\x50\x08\x5c\xb5\xb0\xf7\x62\xeb\x7e\x02\xa3\x69\x34\x0c\x6a\xbe\x41\xae\x67\x0b\xa3\xf3\x2b\x5a\x64\x40\x58\x4a\x9c\x57\x99\xea\xc8\xf2\x93\x0e\x54\x1c\x90\xd8\x2a\xe7\x5a\x15\xd3\x0f\x87\xa9\xe0\x5e\x76\xcd\xc6\x10\x87\x2f\xe1\x16\x32\x0e\x95\xc1\xb6\xd3\xee\xe7\xfd\xd8\x6f\x5c\xc6\x84\x86\x88\x4a\xeb\x01\x01\xb6\xac\x3d\x0f\x52\x90\x31\x49\xc2\x20\xe9\xd4\x85\x32\x2d\x9a\xb2\x1a\x6a\xf0\xcc\xa0\x53\x64\x4c\x20\xd0\xce\x51\x77\x33\xed\xb7\xc5\x34\xa0\x38\x6f\x5f\xca\x5c\xf7\x64\x50\x7f\x7d\x34\xe4\x58\xf9\xa8\x4b\xd3\x28\x71\xf6\xb6\xde\xfe\x28\xc4\x58\xaf\xf3\xae\x28\xab\x21\xa4\x73\xa6\xa7\x18\xb3\xd0\x5a\x38\xb6\xfb\xa9\x44\x8c\x5e\x57\x5b\x8a\x99\x08\xb0\xe3\xec\x17\x64\xf4\xb0\x9c\xc9\xbb\xc6\x97\xcf\x80\xa5\xd6\xf0\x75\xd4\xdc\x72\x47\xa3\x40\x07\x5e\x64\x0c\x97\x8b\x55\x9e\x79\x1b\xcc\xf9\xdf\x2a\x8a\x25\x0b\xbb\xc2\x00\x64\xcf\x22\xab\x7d\x70\x88\xc5\x6d\xbf\x3b\xc4\xb1\x92\x09\x38\xe1\xeb\x6f\xf8\xf0\xfc\x11\x6f\x2b\xa2\x72\x0b\xe5\xea\x37\xbf\x38\x31\x31\x2e\x88\x85\x38\x81\x8f\x10\x62\x9e\x2a\x6f\xe2\xda\x85\x85\x0e\x14\xf0\x11\xf8\x2b\xe3\x54\x51\xcd\x3c\x2a\xc3\x02\x6c\xda\x5c\xc7\x11\x11\xdc\x20\x41\x29\x65\x83\xe4\x0c\xb3\x88\x4f\x0a\x19\xb1\xe0\x71\xe0\x06\x2f\x33\xad\xb3\xe2\xf8\x3c\xa3\xac\xea\x07\xa7\x06\x9b\x36\xbb\xfd\xd3\xf3\x7a\x77\xd8\x3f\x1d\xbe\x6f\xef\x9e\x17\x37\xeb\x43\xb8\x5a\x3f\xee\xbd\x90\xb5\x8c\x85\x12\xce\x88\xb5\x11\xb9\xe7\x88\x75\x07\x75\x8a\xf5\xb6\xac\x76\xc1\xcb\xf7\xba\xcd\xc0\x4c\x27\x6a\xeb\x07\x4a\x42\x83\x60\xe0\x8b\x7f\xce\xd4\xa2\xae\x51\x36\xd2\x37\x1c\xc3\x68\x3c\xdf\xa5\x8a\x71\x3f\xca\xac\x1d\xd6\xbc\xae\xb9\x8c\xa5\xb6\x37\x72\x2e\xfb\xdc\x29\x56\x21\x63\x62\x20\x4c\xb9\xbc\x6e\x46\x44\x6a\x19\x6b\x63\xdd\x1f\x5c\x26\xd8\x6e\x2d\x23\x01\x5e\x19\x43\x62\x59\x7b\xed\xaf\xd2\xfd\x4f\x58\x90\x9f\xa5\x4c\x7c\x7f\xbe\xef\x0e\x68\x40\x7a\x44\x7b\xff\x7e\x73\x4a\x02\x22\xb0\xf7\x2e\xec\x2c\xd8\x75\xff\x57\xe0\xf1\x47\x38\xab\x46\x37\x94\x84\xd2\x20\x7c\x5f\x58\xa9\xee\x21\x52\x5e\x26\x24\xb6\x10\x4a\x04\x04\x78\x40\xe2\xdc\xe6\x92\x90\x54\x18\x57\xc3\x9f\xcb\x9e\x13\x22\xed\xa6\x7e\x84\x66\x97\x55\xd0\xe7\xa7\x7e\xad\x4e\x68\x2a\x63\x27\x25\xbb\xbc\x0e\xd4\x36\xfc\x61\x25\x70\xba\x99\x3c\x3b\xd7\x6d\x12\x90\x43\x5f\x57\x4c\x58\x48\x1d\xe5\x0d\x41\x0b\x8f\xf0\xf6\x30\xe3\x16\xe2\x07\xa7\x11\x75\x7d\xd2\x76\xff\x1c\xa2\x26\x65\x12\x05\xfe\x1d\x18\x59\x4f\xc8\x24\x32\x56\xce\xa9\x19\x98\xd4\x23\xcc\xb6\x1f\x10\x31\xa7\x06\x78\xba\xe4\xfe\x47\x4c\xe2\x20\x46\xc4\x46\x9b\x96\xe4\x88\x49\x6f\x3e\xdf\xdb\xbe\xc8\x14\x92\x98\x1a\xb4\xdc\xda\x42\x55\xfb\x9e\x98\xc7\x4d\x8c\x6f\x30\x8e\x25\x3e\x8d\x93\xa8\x7e\xd9\x1f\xb4\xde\x8d\x45\x69\x64\x12\x2b\x19\x3a\xb6\xe9\xc1\xf2\xa2\x0e\x97\xfa\xb3\xd0\x28\x89\x0d\x20\x64\xcb\x2d\x0b\xa0\xb3\x6e\xb9\x4f\x12\xce\x98\xc3\x64\x22\xc3\xf1\xeb\xc5\x37\x49\x24\x47\x19\x85\x36\x59\xed\x28\xd3\x7d\xc9\x3d\x49\x14\xc3\xca\x8d\xa5\x3d\x4d\x66\x6b\xa2\x43\x54\x49\xcf\xea\x43\x9b\x3c\x1f\xb0\x9b\xe8\x3f\xc9\x49\xea\xc8\xe8\xbf\xa0\x38\x58\x2b\xf2\x37\x91\xb5\xa1\xd2\xe1\x3c\x6c\x46\x26\xbc\x7d\x96\xce\x4f\xda\xbf\x87\xf3\x57\xcb\x85\x9d\x95\x45\xd9\x88\x2a\xfb\x53\x58\x29\xff\x69\x0f\x36\x49\xb9\xe4\xae\xac\x75\x9b\xbd\x43\x3d\xfb\x8e\xa4\xc0\xc1\xbd\x03\x3f\x44\x95\xb5\x0b\x56\x7d\x5b\x56\x37\xe2\xec\x63\xb8\x44\x44\x0a\x85\x03\xb6\xf7\x8b\xfd\xe6\xf1\xfb\xc3\x61\xf1\xf0\xf4\xfd\x71\x7f\x78\xbc\x59\x75\x43\x12\x81\xaa\x1b\xdb\x0a\x6a\xaf\x20\xf1\x69\x9d\x71\xfc\xf4\x04\xa4\x26\xee\x60\x18\x0f\xdd\xd4\x96\x04\xb0\x6d\xe9\x94\xa2\x86\x02\xf2\xe3\x13\x48\x66\x65\x1c\x6f\x2a\x10\x27\x14\x8e\xed\x4e\x21\x39\x92\x97\x57\xa6\x1c\xc7\xcc\x89\x0a\x35\xe2\x37\x06\x67\xed\xad\x47\xe7\x1f\x3a\x10\x8a\x8d\xa7\xdd\x8b\x38\x43\xfd\x92\x99\x36\x15\xb9\x2f\xcb\x5f\x97\xee\x41\x19\x11\x63\xba\xff\x9a\xc1\xdb\xed\x24\x87\x4f\x8c\x02\x7c\x53\x10\x53\x85\x25\x7c\x2b\x44\x54\x0f\x0a\x06\x3c\x20\xda\x09\xaa\x16\x8d\xc8\xfd\xe5\xf2\x80\x06\x56\xac\xa9\x2a\x15\xd4\xb5\x97\x41\xdf\xa1\xb2\xde\xfc\xdb\xc1\x43\x6a\x69\x02\x56\xcb\x78\x29\xf2\x41\x17\xd2\x0f\x49\xac\x98\x64\x9b\x9e\x1c\x1e\x16\xff\x58\x1c\x16\xbb\xdd\xd3\x6a\x33\x60\x81\x48\x4e\xb4\x45\x6c\x3b\x71\x90\x1d\xa8\x12\xf5\x3d\x7b\x6d\x10\xc9\x09\x00\xa2\xcd\x2c\x91\xf6\x46\x5c\xdb\x29\x84\x1c\x86\x49\xfc\xcd\x89\xb1\x1a\x27\x38\x27\xd1\x07\xf4\x5c\x56\x4d\x1b\xae\x9d\xce\x50\xd4\xd6\xe1\xab\x5d\xd8\x27\x97\x4a\xe3\x10\x69\xb2\xcb\xcb\xd5\x16\x9e\xc7\x93\x80\xd3\x34\x35\x3e\x4a\x28\xba\xb6\x3a\x67\xa1\x15\xe9\x74\x68\xe4\x09\x26\x7b\xf8\xf7\x93\xe2\x20\x67\x00\xf8\xc5\xf7\xe5\x71\xa1\x6d\x9c\xbe\x15\x59\xf5\x21\xac\x9d\x3c\xfd\x28\x94\xa8\xd5\xf1\x22\x6a\x27\x65\xe2\x68\x66\xfe\xca\x22\xa2\x02\xd7\xae\xe8\xdc\xb7\x86\x48\x1e\x1e\x45\x0a\xd5\x04\xce\x8e\x05\xf2\x7b\x56\x1c\x75\x39\xe5\xee\x0f\xbd\xf1\xfd\x07\x13\x86\x08\x97\x05\xc2\x8e\xf1\xcc\x63\x0c\x0c\x8f\x8c\x4d\x73\x6b\x68\x16\x97\xa6\x5c\x66\x95\x15\x35\x1f\x3f\xf2\x98\x30\xdc\xa2\xb1\x08\xe4\x3f\x1a\x47\x1c\x37\x9c\xfa\x52\x9f\x61\xa2\x2a\x21\x79\x1c\xa7\xf6\x61\x6d\xbf\x2a\x2f\xf1\x38\x05\x94\x27\xb3\x95\x3a\x68\x5e\x48\x10\x26\xdd\x37\x38\x4c\xc6\xa8\xa3\xfa\x25\xfe\x93\xc7\x46\x60\x7d\x13\x57\xd7\x6f\xa5\xce\x47\x01\x03\x8f\x8d\xc2\x22\x59\x56\xaf\xf3\xec\x98\xc9\xfc\x2b\xfd\x4d\xc9\x93\x84\x28\x0b\x0f\xbf\x7e\x2f\xb2\x4f\x3a\xf7\x9c\xc7\x06\x31\x3c\x3f\x44\xd1\x60\x9b\xe0\x6f\xf8\x93\x4b\x9e\x86\x11\x06\x8b\x87\x23\x96\x8b\x50\xf1\x6f\x3e\x7e\xe7\xa9\x62\xa1\x2b\xed\xaf\x06\xe1\xf7\xf8\x2a\x04\xb5\x94\x54\x59\x56\x55\xf9\x36\x1f\x5a\x70\xa1\x15\xd2\xdc\x11\x8e\x3c\xd2\xba\x77\x03\x24\x53\x08\xa0\x39\x97\x75\xb3\x7e\xb7\x20\xbf\x4f\xf4\xdd\x27\xef\xcc\xf8\x8b\x64\x62\x85\x7a\x33\xcf\xd6\x1c\x22\x71\xb8\x4c\x84\xd5\x6e\xd4\x7a\x55\x5e\xaa\x1a\xa6\xaf\xe3\x2c\x6d\x79\xf4\xf8\x94\x20\x38\x71\x9e\xaa\x36\xed\xe8\x4f\xad\x43\x62\x86\xf2\xec\xa3\xc5\x9e\x6b\xa9\x11\xbc\xf3\xe3\xf9\x76\xa0\x6c\x25\xb9\x56\x11\xd6\x70\xd1\x44\xda\xc2\xc2\xad\xa0\xd8\x60\x41\x86\x50\x0a\x1b\xdd\x3f\x58\x89\x84\xd9\xdf\x0a\x68\x68\x59\x0f\x50\x29\x12\x8c\xbe\x04\x28\xc7\x3d\xa1\xa3\x00\x50\xf2\x4f\x12\xdb\xf6\x18\x25\xff\x64\xae\x3d\xc6\x0d\x93\x08\x36\x7e\x28\x2b\x0d\x23\x7d\x22\xc9\x4d\x6a\x78\xb7\x75\xd8\x0a\x94\x45\x7a\x2c\x61\xba\xa4\x1b\x90\x18\xef\xa1\x5e\xce\x2e\x3b\x8e\xca\xb1\x69\x10\x4a\xd4\xcb\x93\x1e\x63\xb9\x44\xa1\x4a\xf5\x02\xb3\x94\x67\x99\x06\x3c\x94\x66\xa0\x6a\x36\xe7\x68\xed\x87\x0a\x85\xa0\xd2\xac\xb6\xe2\xaf\xbb\xfe\xf7\x49\x43\x46\x8d\x5b\xf5\x91\x1c\x37\xfe\x64\x18\x09\x0c\xae\x44\x9e\x29\xc0\x5c\xa5\xf6\xb6\x5e\x53\x69\x97\x0f\x48\x8f\x01\xa9\x5d\xa6\xa1\x90\x18\x43\x5f\x0a\x53\xe6\x79\xf9\x36\x2e\xbc\xa4\x84\x48\xaf\x60\xd5\x26\x34\xab\x32\xcf\xc5\x61\xb1\x3c\x04\xe1\x28\x0a\x4d\x49\x42\x51\x2e\xc0\xcd\x26\x17\x8b\xd5\x3d\x0a\xc0\x8f\x33\x14\xf5\xcc\x1d\x85\xd6\xe6\x71\xe3\xe7\x47\x83\x28\x18\x96\xa3\x50\x61\x71\xae\xb4\x91\xd2\x30\xc6\xec\x10\x5e\x45\x7e\x11\x0d\xac\x44\x03\xc7\x41\xdb\xf7\x2b\xa4\x7a\x4a\x09\xc5\x1a\x69\x51\xb6\x9f\x86\xd9\x58\x7e\xfc\x6d\x06\xac\x80\x1c\x34\x93\x42\x49\xca\x98\x4c\xa5\x5b\x0c\xa6\x7a\x99\x7e\x88\x89\x02\xf0\xda\x22\x5e\x8d\xde\x7f\x3e\xd2\x0a\x4f\xfd\x23\x93\x28\x2d\x3f\x61\xfd\xc9\x34\x0e\x12\xb4\x1f\xa8\xcf\x65\x53\x0f\xea\xdd\x69\x4c\x03\xe2\x62\xf6\xef\x45\xf6\xef\x0b\xc6\x1b\x76\x21\xc1\x36\xf3\x9c\x8c\x8e\xff\xa8\xf4\x10\x40\xfb\x9c\xff\x28\x0b\x37\xa5\xb9\x1f\x61\x38\xee\x79\xf2\x52\x15\x4e\xe6\x57\x1c\xc1\xed\xcd\xfe\x0a\x12\x01\x58\x5f\x2a\x2e\xa7\xa7\xf3\xb0\xf8\x9d\x26\x10\x2b\x35\x56\x5e\x74\xf3\x62\x27\xba\x9e\x57\x9a\x86\x96\xf8\xa1\x5e\xda\xd7\xce\xeb\x84\x39\x3d\xf3\x09\xed\x69\x58\x4e\x4a\xd3\x44\x3b\xf9\xbf\x42\x8f\xc1\xe4\x33\xa0\xa6\x34\x35\x81\x8a\x3a\xb6\x61\x3b\xf7\xda\x90\x64\x75\x69\x4a\x63\xea\x59\xca\xa6\x4c\x05\x21\xc2\xb8\x22\xcf\xcf\x6e\xe9\x4f\x25\x0f\xbc\xc8\xec\x33\xd4\x16\x2b\xfa\x7b\x56\xe8\x02\xea\x7a\xfd\x0a\x13\x11\x31\x99\x2a\x46\xb1\x59\x28\xb1\x0e\xa5\xfe\x8a\x9a\x91\xaa\x84\x83\x7d\xec\xd7\x75\x71\xcc\x0a\xe8\x93\xf0\xee\xc7\x53\x5a\x62\x64\xdc\x6e\x0c\x58\x42\x51\xd7\x4e\xe2\x60\x72\x36\xe0\x54\x39\x9d\xb5\x4a\x63\xf5\xa4\x4f\xda\x43\xc2\xff\x63\xf2\xd7\x7d\x4c\x47\x01\x62\x25\xb6\xf9\xa5\x19\x21\x2d\x52\xdd\x46\x39\x8e\xf5\x93\x15\xbf\xa6\xaf\xaf\x06\x6b\x87\xa1\x45\x23\x36\x1a\x8a\x26\x33\x48\x7e\x1e\x5f\x95\x06\x0b\x24\x07\xdb\x57\xc5\x7c\xd3\x97\xc4\x52\x48\x6c\x9f\x09\x29\x4a\xe1\xa1\x72\x92\xb4\x37\xe5\x45\xe6\xe8\xe2\x7d\xa8\x5f\xca\x4b\xae\xf7\x2f\xed\x06\xee\x3f\x24\x13\xe4\x35\xad\x16\xfb\xc3\x76\xfd\x7c\x58\xef\xbf\x1d\x6e\x37\xcf\xbb\xfd\x61\xbd\x78\xbe\xff\xc7\x61\xb9\x79\xbe\x19\x50\xda\x64\x0a\x9a\x06\x64\x60\x8c\xe3\xc3\xee\xfa\xa3\xd6\x89\x4c\x01\x42\xcf\xad\x7d\x80\x46\x2c\xd1\x90\xe7\xf8\xd2\x7c\x18\x66\xf5\x34\x35\xa8\x52\xc3\xef\xff\x58\x75\x34\xc5\xfe\xc9\x9a\x48\x75\xda\x99\x83\x6d\x33\x35\xc2\x30\x35\x00\x6d\x4f\xf3\xd9\x7e\xa8\x08\x28\x43\x61\x3c\xdb\x9b\xba\xab\xca\xb7\xe6\x65\x5b\x96\x1f\x8d\x4b\x10\x64\x46\xad\xcb\x71\x73\x2b\xaa\xce\x38\x4d\x8a\xd0\x04\x78\x19\x02\x25\xb8\x27\x62\xc7\x6e\x0c\x09\x82\x28\xe8\xda\x1a\x68\xb3\xe9\x8f\xd0\xd8\x0a\x37\x97\xfd\xbf\x62\x86\x2d\xfa\xfd\x76\x4b\x82\x90\x23\x2e\xbf\x3b\x26\x24\xd6\xdf\x9f\x4b\xf5\x6b\x2b\xce\x50\xed\x54\x56\xd7\x65\x55\x2f\xf4\x6b\x7b\x93\xba\x1b\xa8\xad\xa4\x55\xfb\x10\x5e\x2a\x00\xec\xde\x2e\x8e\x1f\x8b\x97\x7f\x0f\xf0\x2a\x28\x8d\xf1\x5d\xea\x30\xd5\xed\x63\x5a\x5d\xa6\x37\xca\x82\x04\xd7\x12\x4b\xda\x70\x10\xc9\xd1\x02\x2e\x98\x0a\x91\xec\x7e\xbc\xf8\xf8\x93\xfb\x23\x3a\xf1\xce\xbd\x0f\x59\x71\x69\x26\x72\xf6\x52\x44\x32\x91\x16\x9e\xee\x96\x75\xa7\x88\xe7\x0e\xc7\x90\x20\x41\x41\xe8\xd7\xac\x2e\xab\xeb\xbe\xb7\xf0\xf4\x43\x92\xd0\xe0\xaf\xf8\xf4\x3e\xd3\xd1\x14\x49\xaa\x0d\x74\x7d\x84\x59\x3e\x85\xe0\x46\xa3\x1e\xdb\x41\x95\xa7\xf3\xa5\x81\x4d\xd1\x2e\xe7\xd9\x2b\x0c\x1e\xc6\xe4\xd9\xa5\x81\x15\xfe\xc2\xbc\x13\xcd\x7d\x3e\x9a\xa7\x48\x91\x4a\x89\xc2\x31\xa2\xfa\x5a\xb8\x5b\x8a\xd4\xc8\x24\xf4\xb1\xe3\xa2\xfe\x65\xc5\x17\xdc\x41\x41\x53\xec\x2f\x82\x46\x3f\x97\xaf\x6b\x4f\x42\xf0\x30\xb6\x3e\xc8\xd9\xf1\x08\x95\xf3\xc2\xbe\xf4\x6a\x6c\xdd\xeb\x26\x44\xaa\x95\x5f\x29\x45\xfd\x22\xdb\x81\xf3\x46\x43\x1f\xf7\x48\x21\x84\xc4\x3e\xe1\xc3\xf5\x33\x55\xb9\xbf\x2c\xd6\x08\x19\x10\x6c\xc3\xbf\x41\xa5\xfa\x26\xb0\xd0\x81\x15\xb1\xda\xb2\x9f\x37\xc3\xf5\x55\x68\x92\x5a\xf7\xc5\xfa\xf6\x52\xa8\xc9\xd3\xd6\xd4\x46\x2d\x87\xd3\x25\xff\xe4\x67\x03\x02\xc6\x2a\xec\x5b\xa5\xe4\x21\xa5\x4c\x40\x6c\x25\xc7\x4d\xf6\x0e\x9d\x11\xec\xf8\xf3\x86\x59\x1a\xb8\x68\x53\xf7\xce\x21\x1a\xa3\x89\x73\x9f\x06\xfe\xf3\x7f\xfe\x63\x12\xdb\x09\x93\x08\x94\xba\xdc\x5f\xcf\x50\x3b\x53\x3c\xff\xbd\x46\x10\x6c\x0c\x62\x3b\xa0\x27\xe7\x08\x23\xba\xda\xc6\x6e\xbd\x7a\x7a\xbc\x39\xec\xf6\xeb\xed\xd0\x18\xf3\xd2\x73\x52\xa5\x30\x46\x5b\x03\xef\xae\x11\x58\xe6\x2e\x01\x19\xdd\x84\x0c\x42\xab\x40\xe3\x04\x7d\xd0\x27\x7b\x96\x22\x28\x83\x24\xc6\xee\xee\xac\xbf\xf8\x78\x2e\xc9\x90\x06\x51\xd4\xd5\xdd\x16\x79\xde\x35\x2c\xac\x7c\x69\x37\x0c\x62\x0f\xab\xac\xda\x87\xf6\x5c\x96\xa7\x87\x29\x42\x45\x12\x22\x91\xd8\x00\xef\xa0\x2c\xfc\x6c\xa6\x3b\x2e\x09\xa3\x28\xbc\x5f\x5f\xaa\xd7\xec\xf5\x6b\x5d\x5d\x29\x49\xc2\xb1\x0b\xe0\x5d\x88\xfc\x25\x11\xb0\xe4\xb7\x5d\xf9\x6b\x38\xd9\x24\x25\xd6\xc0\xa0\x86\xe6\xe6\xb1\x5c\xeb\xac\xdd\x00\xc7\x2b\x9f\xa4\x49\x92\x5a\x09\x2d\xbb\x0f\x67\x65\xb1\x7e\x3f\x67\x95\x68\xba\x98\x48\x32\x49\x62\xab\xf8\x59\xbf\x2c\xf2\xfc\xc9\x8b\x85\x4b\x19\xa5\x54\xf6\x28\xd8\x39\xeb\x96\xcf\x56\xf2\x41\xb9\xc6\x9d\x2b\x86\x24\x8e\x3b\x89\xa2\x9e\x06\x85\xfa\x39\xb3\x6f\x9f\x4c\x88\xf6\xe4\x2b\x0c\x7b\x76\x0d\x9c\xd9\xe4\x11\x27\x89\x46\xa8\xb3\xbd\xc4\xe7\xa1\x0e\xb1\x9f\xdc\x92\x47\x29\xaa\x35\x9e\xec\x24\xda\x75\x09\x22\x56\x1d\xb4\x8b\x43\x6d\x1a\xe7\x8f\xa4\x69\x8c\x76\x32\xdf\xe0\x1d\xf2\x75\x9b\xe6\x7e\xb1\x8a\xb8\xcf\x08\x4a\x4c\xd7\xdc\xa7\x53\xfc\x8c\x14\x94\x4b\xde\x91\xb2\x3f\xb9\x67\xc1\x63\xea\x72\x8d\x75\xf3\x82\x92\xff\x13\x49\xf5\x76\x8c\x88\xac\x3e\x60\x9b\xb4\x64\xff\xfd\xd9\xa9\x44\xea\xbd\x2f\xda\xe9\x5e\x81\x6f\x87\x48\x49\x2c\x2f\xee\xd0\x58\xaa\xd5\xf8\x73\x32\xe2\xd2\x05\x57\x3f\xb2\xea\x32\xa2\xf7\x4e\xee\x58\x42\x80\x69\x02\xbc\xdb\xb2\xa6\xff\x02\x15\x32\xac\x37\xa3\x3e\x92\x65\xcd\xbd\x64\x13\x0e\xaa\x54\x44\x60\xc7\xce\x62\xff\xa4\x28\x7e\x4d\x07\xa8\x10\xdb\xb1\x67\x2c\x1c\xef\x20\x37\xd3\x01\x3a\x06\x6e\xa3\x6d\x57\x89\x9f\x11\x9b\x91\x52\xd3\x00\xfb\x07\x37\x98\x9e\xa1\x2a\xe8\xf0\x3d\x32\x44\x21\xb6\x15\xde\x55\x7e\xd1\xd0\x95\x70\xc7\x27\x31\x54\x20\x92\xa2\x7e\x73\xdd\xaa\xf1\x8f\xa2\x82\x34\x14\xae\x97\xd3\xa5\x80\x38\x05\x16\x58\x3e\x46\xc8\xa9\xfb\x46\x15\x72\x11\x5b\x3b\x98\x1c\x1c\xa2\x74\x94\xf6\xfa\x61\x42\xa0\xae\xe3\x8f\xf5\x6e\xbf\x79\xbc\x3b\x2c\x6e\x7e\x6c\x76\x4f\xcf\x87\xd5\xfd\xe6\xf6\xd6\x9f\x8b\x30\xc0\xe4\xa8\x6a\x43\xda\x38\x9c\x5c\x15\x11\x1d\x16\x09\x29\x1c\xe3\x9b\x52\x94\x58\x33\x93\x23\xf6\x8f\xb1\x7c\x75\x5b\x56\x13\x1d\x2e\x3f\x36\xb6\x19\x7b\x05\x9e\xd9\xe1\x44\xa8\xfc\x95\x50\x19\xa2\xb8\xfd\xf3\xfa\xe7\xe2\xf9\xe6\x70\xfb\xf4\x8c\x7f\xb7\x4f\xbb\xcd\xa0\xc0\xae\xa8\x36\xbe\xb4\xbd\x2c\xcb\xba\x99\xb6\x29\x15\x8b\x2c\x69\x03\xcd\x7f\x7a\x71\x21\xa9\x98\xb6\x4e\x62\xbf\x6f\x1e\x31\x4d\xf8\xb9\xde\x74\x87\x80\x23\x9a\x00\x45\x80\x1f\xe1\xbd\x59\x57\x62\xbc\x14\xaa\x88\x12\xeb\x77\x5d\x2e\x07\x76\xaf\x23\xfd\xaa\xf1\x0b\xa4\xa2\x44\x20\x2c\xf0\x01\x74\xd6\xdd\x65\xa4\x43\x8c\xac\x1c\x81\xf6\xe7\x50\xaa\xaf\xbf\x87\x24\x90\x98\x23\xf9\xbd\xae\x97\xc8\xf6\xfb\xa1\xe2\x8a\x61\x63\xf9\x47\x56\x35\x17\x34\x5c\xce\xd7\x03\x15\x71\xa9\x52\x1a\x21\x00\xe8\x15\xaa\xcc\x5c\xb7\x55\x59\x9a\x81\x0c\xd5\x6c\xa9\x42\xa5\xc6\x52\x6c\xda\x98\xf9\x41\xbc\x77\x57\xe7\x0e\x0b\x16\x93\xd8\x12\x43\x3a\x88\x44\x77\x2c\xb2\x85\x8c\xc3\x17\x34\x6d\x25\x12\x6b\xa3\xf1\x98\x1d\xa1\xca\xc4\xa3\xc8\xaa\xa1\x7e\x8e\x54\x82\xa7\x54\x23\x4b\xed\x33\x37\x1f\xa9\x64\x92\xc4\x98\x28\xe4\x99\xb2\x6a\x4f\xc3\x6c\x50\x49\xa5\xb9\x93\xa6\xf0\x39\xf4\xfd\x6b\x38\x99\xb9\x9a\x30\x94\xe1\x3b\x5a\xa4\x62\x73\xc1\xee\xea\xe0\x4a\x81\x40\xda\x81\x18\xd6\xc5\xbf\x86\x13\x09\x92\x54\x84\xdd\xca\xb8\x2b\x55\x26\x72\x87\xdb\x98\x6c\xa0\xca\x10\x86\xa6\x71\x53\x06\xd1\xed\x3c\x65\x7a\xf2\x73\x98\x84\xe1\x52\xea\x4e\x6e\x6b\xaa\x0b\xad\x3f\xdb\xf2\x94\xe1\x31\xeb\xa3\x14\x9c\x35\xfb\x72\x95\x67\x7d\x71\x51\x07\xa9\xc2\xba\xb2\xee\xf4\xd4\xc7\x8b\xde\xc7\x50\x58\x87\x8a\xe0\x9b\xb9\x7a\xc9\xce\xce\x4c\x7c\xd8\xf6\xd7\x24\xb4\xb2\x32\xfe\x97\xbf\x87\x57\xc8\xe7\x96\x24\x4d\x48\x84\x36\x94\xeb\x1c\x54\x1b\x50\x64\xcd\x75\xae\xcd\xaa\x09\xb1\xbb\xbd\x75\x85\x5f\xef\xbf\xcd\xd7\xea\x35\x15\xb6\xfb\x51\x43\x17\xa5\x3a\xa8\x52\xbd\xb3\xea\x12\x16\x5e\xf1\x09\x23\x49\x53\x61\x12\xe2\x90\x02\x77\x65\xde\xc5\x71\x9a\x4a\xe6\xd5\xdf\xcb\xb7\xc5\x05\x83\xa3\xf1\x14\xd2\x4c\x6b\x99\x7a\x4c\x79\x3b\x01\x0f\x59\xf1\x2a\xf2\x4c\xff\x01\x55\x89\xe1\x9c\x87\x0c\x69\x06\x09\x8a\x86\x61\xab\x0e\xa5\x7a\xe7\x6e\x3a\x0a\xb4\xf2\xd2\x80\xb7\x55\x79\x9a\xd2\x1d\x26\xd7\x1e\x31\x06\x7c\xd4\xa7\xd9\x97\xdb\x5c\x4c\x98\x2f\x3a\x62\x06\x41\x17\xfa\x5a\x88\x53\xc7\x9b\xd6\x51\x6c\xd1\xa3\xff\xaa\xcb\x62\x25\x9a\xdf\xe6\xbc\xf4\xfc\x50\xae\x70\x71\xbc\x2f\x8f\xcb\xcb\xf5\xb6\xac\x6e\x33\xf1\xd9\x45\xc5\x89\x02\x87\x86\x3c\xe4\xa2\x6e\x0e\xa2\xae\xa1\x39\xe8\x89\x65\xae\x1b\x9d\x04\x80\x9b\x5e\xfb\x08\x6f\x45\x96\xdf\x41\xf3\xbd\xa8\xbb\xf8\x4a\x27\x09\x45\x18\xd7\x0e\x8a\x73\x59\x88\xbf\xee\x18\xe9\x24\x15\xd8\x8d\x6a\xbf\x7b\xe5\x12\x7f\x54\x46\x79\x13\xd5\x10\xc6\xaf\x39\xb7\x44\x67\x9b\x38\x6f\xd1\xd6\xc7\x69\x35\x8c\x9f\x1f\x17\x80\xab\x0d\x14\x7a\x55\x66\xc5\x6d\x9e\x9d\x3f\xf3\x45\x72\x9f\x48\x75\x12\xbb\xb8\xe3\x7b\xa1\xa1\x7a\xb3\x0a\x57\xee\xa8\x20\x56\x1f\x4b\x68\xfd\x58\x7a\xb4\x23\x09\xc6\xb7\x21\xa8\x21\xbe\x0d\x72\xb0\xc6\x9b\x07\x93\x15\xba\x5d\x90\xbf\x65\x45\xb3\xad\xe0\xd5\x9a\x10\xed\x45\x47\x02\xd0\x82\x27\x08\x9c\xbe\x5b\x7d\xfb\x7b\x4a\xe8\x52\xcb\x84\x62\xf0\xf2\x22\x6a\x6b\xfa\xb5\x3e\x4e\x38\xe4\x5a\xca\x14\x61\xff\x77\xa5\x7e\xcd\xe0\xcd\xca\xa2\xfd\xf5\x2f\x21\x41\x60\x04\x6c\xdd\x0d\x5c\x45\xcb\xf6\xaa\xc7\xe7\x57\x8c\x09\xef\x57\x59\x36\x13\x76\xdc\xf4\xc1\x28\x66\x3d\xce\x2d\xe8\x5a\xe4\x7b\x91\x7f\x05\x16\x1c\xec\x3d\x5a\xc7\x02\xfb\x14\xbf\x6f\x9f\xb6\x9b\xa7\xcf\xd0\xc6\x1a\x28\x47\x99\xe7\x73\x2e\x1a\x53\x56\xa7\xee\xff\xca\x02\xc4\xac\x4e\xc4\x73\x1b\x2e\xd5\x77\x95\x28\x9a\x4f\xa4\x50\xa5\x36\xa1\x74\x9e\xac\x28\xcb\x33\x45\xbb\x4f\x47\xc7\x31\x16\x53\x36\xf5\x1d\x14\x50\x67\xf5\x6c\x31\x47\x9b\x04\x50\x88\xd4\xd1\x89\xd6\xef\x67\xa8\x32\x28\x26\xe2\x72\x52\x1b\x61\x83\xd6\x36\xc4\x77\x27\xc4\x65\xf1\x33\x97\x9b\xee\x63\x29\xa6\x9c\x77\xd9\xeb\xa0\x27\x32\x39\xb5\x94\x89\x85\xd9\xad\x44\xf1\x2a\x6a\x5b\x21\x72\x3f\x82\x7f\x0b\x20\x20\x86\x92\x21\x04\x73\x40\x66\x99\xfd\x6e\x08\x98\xd1\xa9\xe7\xe8\xdf\x8b\xba\xd9\xa9\xb2\xf2\x2f\x2c\x84\x3c\xc2\xa6\x25\x58\x91\xc2\xa7\x09\xcf\x1e\x68\x4c\x11\x42\x80\x22\x0b\x58\x54\xde\x68\x4f\x30\x07\x1a\xc7\x48\x81\x44\x74\xc0\xd7\x79\x34\xd0\xd4\xe0\xc4\xbd\x5d\xaf\x6f\x7c\x5d\x1a\x18\x21\x38\x49\xf3\xf2\xd8\x27\xb8\xc0\x88\x75\x60\x71\xd9\x23\x2e\x32\x8e\x88\xf1\x95\x65\x9a\x84\x28\xb1\xbd\xb0\xed\xf7\xe5\xfd\x66\x75\xd8\x2d\xee\xd7\x23\xe5\x12\x88\x49\x8c\x4d\xbe\xce\x21\xa7\xdb\xad\x75\x37\x44\x11\x84\x4d\xaf\x2b\x9f\xe2\xf1\xf9\x32\x14\x24\x21\xc7\x8a\x6d\x36\xd3\x9f\xff\xbf\xfd\xeb\xbf\x42\x81\x1e\x4a\x4f\x1f\x1a\x10\xa7\xc3\x07\xf3\x0f\x09\x3c\xb6\xba\x75\xb6\x62\x7a\xe7\xed\x58\x24\xa4\x32\xc5\x5d\x66\xff\xed\x79\xbd\xfb\xf6\x74\x7f\x43\xbb\x23\x9a\xe2\x4c\x9a\xdf\xaa\x86\xcb\x03\x08\xa6\x8d\xab\xf8\xdd\x83\xd0\x50\xc9\x52\x54\x7a\xce\x8c\x55\x82\x0c\x28\xea\xbe\x15\x97\x93\x85\xfb\x74\x97\x22\x23\x8a\x09\xbf\xc8\x73\xe4\xb6\xf6\xcf\x5c\xa6\x30\x14\xfa\x5d\x5e\x67\x5f\x52\x90\xd2\x78\x57\xa5\x12\x51\xdf\xff\x6f\x1f\xb6\xd4\x02\x19\xd2\xed\x7f\x51\xa9\x68\x5f\xee\xf0\x0e\xa7\xa5\x0b\x50\x9c\x62\x8b\xd7\xe6\xc8\x3b\x61\xe0\x78\x11\x95\x13\x3b\xf6\x37\xa5\x8c\x8e\xe2\x91\x69\xf6\x9d\x38\x21\x44\x3b\x13\xf9\x43\x56\x2c\xa1\xd9\xf5\xf5\x24\xd0\x94\x62\x1d\x62\xf7\x6d\xf1\xbc\x3e\x6c\xbf\x3f\xaf\xbe\x2d\x76\xeb\xe7\x5d\x77\x3c\xb6\xbe\x3b\xda\xa9\x92\x8d\x98\x49\xa0\x79\xe8\x55\xf4\x6d\xb3\x1d\xcb\x42\x98\xd9\x44\x7e\xe9\xd0\xc2\x8a\x2d\x2f\x37\xf7\xf7\x7d\xe6\x07\x10\xa4\xde\x7d\xb4\x38\xc2\x1c\xae\x09\x4c\xac\xc1\x1a\xb1\x58\x11\x32\xeb\xe5\x3c\x59\x29\x4c\x12\x8a\x5e\x8d\x68\x55\xe6\x65\xb5\x87\x8e\x62\x07\x46\x51\x4c\x72\x1a\x38\xa1\x16\xdd\xa5\x82\x07\xf1\xee\x8e\x9a\x20\xa0\x88\xd0\x45\x6f\xbc\x29\x93\xdb\x8f\x21\x8c\x84\xc3\xce\x43\xc7\x9d\xc0\xfa\xfe\xa4\x47\x60\x02\x4d\xa9\x1d\x5e\xf8\xb2\xec\xe8\xae\x4c\x28\x63\x3e\x34\xcc\xc1\x06\x41\x36\xcd\xc6\x0d\x51\x89\x4a\x7b\xf1\xa8\x0f\x10\x25\x43\x34\xf5\xd3\x72\xe1\x1a\x0e\xa8\xb3\x33\x3e\x0d\x8d\x23\xe4\x97\x9d\xb2\x62\x60\x65\x23\x0d\x4b\x69\x48\x7b\x7c\xae\x47\xbc\x7c\x52\xba\x1b\x9f\x93\x81\x7b\x22\x98\x8a\x1c\xc4\x08\x71\x62\x22\xa1\xa8\x67\x2d\xa3\x94\x98\x5f\x76\x4d\x9c\x12\xdb\x7b\x6b\xc4\x2f\xf8\xc0\x6c\x37\x49\xaa\x70\xc7\x78\xba\x34\xab\xbc\xbc\x7c\x92\x15\x19\x1e\x58\x71\xa6\x63\xf6\x0a\xab\xb2\xa8\xfb\x6c\xc8\xf0\x34\xc5\x08\x54\x5e\xae\xdb\xf6\xc9\x0f\xb9\x14\xe3\x87\xc7\x5d\x73\xf3\xe8\xaa\x89\x9b\x62\x2b\xea\x66\xe2\x71\x3e\xbf\xa5\x98\x94\x05\x68\x6a\x6c\x67\x5c\x47\x40\x99\x5d\x3c\x4c\x1a\x43\xec\x49\x6a\x4e\xd3\xb8\xfd\x19\x90\x5a\x5a\x58\x5c\xb6\x1b\x29\x02\x8d\xca\x9c\xfb\x9b\xf5\x18\x61\x68\x44\x92\x72\x2f\xc0\x23\xaa\xbc\xac\xf4\xea\x05\xea\x66\x0a\xb2\x37\x42\x5b\x42\xb4\xb5\x9b\xdd\x66\xc8\x25\x1f\x6f\x25\xc3\xa2\x83\x11\x86\x40\xe7\x81\x81\x90\x5f\xa7\x06\x3e\xa5\x44\x1b\x09\x76\x16\xa1\x80\xdf\xf0\xd2\x14\x4b\x06\x94\xdd\x83\x98\xdc\xbd\x06\x8a\x72\x64\xa7\xeb\xcf\xac\xb0\xec\x73\x77\x04\x48\xe2\x9d\xf5\xd6\xfb\x6f\x1f\x0c\x3a\xa4\x81\x98\x11\x4b\x88\x2b\x47\x38\x1e\x63\x42\x8b\xa5\x46\xfb\xd1\xcd\xe3\xdd\xe1\xf7\xf5\x72\xb1\xec\x8e\x46\x41\x90\xf6\xea\xcf\xcb\x2b\xa2\x4e\x86\xdb\x8a\x31\x1c\x90\x3e\x7c\xa8\x2e\x85\x6b\x5b\xae\x86\x4c\xdf\xff\x37\xeb\xba\x31\x2a\x42\x41\x43\xd1\xa9\xc1\x7c\x85\x16\x50\x41\x90\x58\x00\xcf\x32\xeb\x5c\x66\xdd\x11\xca\x38\x02\x3c\x8a\x8d\x4d\x49\x05\x9a\x0d\xd7\x2f\xbe\x86\xa8\x02\x66\x12\xe3\xa4\x2e\xb0\x9a\x9e\x8b\xa6\x44\x16\x10\x4c\x14\x29\x55\x10\x89\x98\xc6\x03\xe2\x66\x35\x8d\x21\xfd\x38\xc9\x30\xde\x75\x52\x5c\x2f\x65\xd5\x6c\xf4\x2c\x26\x46\x05\x91\x36\xd8\x82\xc6\x82\x1b\xf6\xe0\x97\x99\x87\x20\xaa\x20\x26\x0a\x6b\x7c\x56\x59\xe9\xfc\x2b\x2b\xea\x7d\x39\x1b\x8d\xaa\x20\x31\x16\xc2\xd5\xc6\x85\x33\xe6\xe4\x33\xe8\x21\x15\xf0\x30\x44\xf6\xb0\xa8\xeb\x36\x19\x1f\xdf\x46\x9a\x28\xc9\xfa\x06\xe3\x6f\xe3\x0b\x4f\x53\x6b\x5e\xee\xfe\xeb\x7b\x5d\xe3\x41\x22\x8e\x30\x4c\xc8\x2b\x35\x12\x61\xf3\x87\x85\xc2\x96\xf3\xcf\x51\x75\xcf\x1d\x94\xa1\x15\x11\x44\x86\x68\xf5\x0b\xba\xd4\x51\x05\x92\xa4\x48\x50\x3b\x99\xea\xc9\x4c\xbe\x52\x2a\xd3\x19\x18\x0d\x78\xf7\x1e\x49\x30\x7e\x66\x52\x53\x8f\x62\xbf\xbf\xff\x71\x68\x1f\xdd\x21\x8c\xfd\xd7\xa8\xc0\x8a\x97\x54\x96\x76\x30\x15\xda\x57\x81\xd6\x80\x28\x3f\x0b\x75\xb0\xec\xd9\x93\x03\xc9\x21\xf7\x65\xfc\x40\x81\x04\x58\xfa\x3e\x1c\xca\x4b\x73\xbe\xb4\x79\x79\x2e\xc5\x04\xb3\xac\x02\x48\x21\xb6\xdc\x97\x7f\x5f\x32\xbb\x14\x8f\xe4\x78\x54\x00\x0a\x9c\xde\xeb\xa5\x7e\x2a\xc0\x1a\x56\xfa\x63\x40\x30\x38\xb8\x14\x16\x2c\xde\x2e\xd1\x58\xa0\xec\x07\x68\x7c\x87\x85\xd6\xf6\xb9\x5a\xec\xfb\xdc\x8e\xa1\xc2\x40\x07\x5e\xa3\xfa\xb6\x37\x67\xfa\x14\x56\x35\xa9\x98\xa9\x90\xd0\x20\x4c\x3d\x8d\xe1\xd6\xdf\xef\x67\xf0\xdc\x1e\xda\xa4\x42\x12\x41\xd2\xdb\xf4\x0f\x31\xce\x2a\x24\x92\x52\xe3\x40\x59\x1d\xdb\x42\x85\x44\x73\x69\x51\xdb\x6e\x5f\x19\xd4\xcb\xfc\x10\xc3\x91\x16\xab\xaa\xf6\xb7\x5e\xad\x9f\xfc\x67\x69\x60\xd5\xc9\x3a\xdb\xbf\x4f\x1c\xa6\xfd\x70\xca\xf0\x97\xbf\x2b\x4b\x3d\x78\x23\x3f\x86\xe2\x2a\xa4\x8c\x61\x90\x9a\xd5\x77\x97\x2c\x9f\x08\x25\xab\x90\xc6\x76\x0e\xd9\xfa\xea\xcd\xf7\x9d\x9b\x66\x3e\xd6\x56\x21\x35\x56\xe5\x14\xcd\x4e\x86\xab\x5b\xc8\x62\x43\x79\xe7\xd7\x5c\x34\x6b\x87\x02\x9b\xd7\xc2\x54\x21\x4b\x18\x6d\xef\xde\x1a\xc9\x82\xfe\x74\x1c\x07\x2b\x00\x6c\x25\x8f\xa6\x98\xde\xf9\x47\xc2\x0c\xed\xac\x0a\xcb\xcb\xd9\xfb\x25\x8d\x9e\x45\xc4\x62\xdb\x92\xa8\xa0\x7e\xe9\xcb\x8c\x2a\x8c\x13\x86\x6f\xad\x86\x5a\x4d\x32\xda\xf6\xa0\xb0\x69\x88\x4d\x36\x7a\x35\x8f\x91\x8a\xeb\xfc\xde\x10\x26\x34\x46\x8d\xa2\xfa\x22\x6f\x91\x66\xf0\x29\x34\xb9\x2b\x91\xa8\x30\x61\x60\xac\x23\xc0\xcf\xac\x29\x3e\xf3\x4c\x54\x61\x12\x4b\x0c\xe7\x7e\x2e\xee\xef\xd7\x7b\x4c\x5f\xfd\x1d\x25\x92\xa2\x7a\xd5\x19\x2a\x53\x56\xa7\x67\x10\x1e\xdc\xa5\x42\x4e\x04\xee\xc3\xba\x74\x0a\x08\x50\x61\x05\xa5\x3b\xee\xbc\x6d\x6d\x24\xf6\x0a\x3f\x5f\x2e\xc6\x64\x50\xef\xbe\xf8\x15\xc6\x93\x8e\x43\x8a\xb1\x13\xee\xa0\xcf\xa0\x2e\x55\x7b\x70\x99\xe5\xf9\x20\x3b\xfa\x72\x17\x56\x61\x2a\xac\xdd\xbd\x15\xee\x3a\x81\x73\x37\xfe\xba\x55\xed\x3f\xab\x35\xda\x35\xfd\xc8\xd4\x0d\x9c\x46\x93\x56\x12\xc6\x62\xaf\x8a\x72\xca\x9a\x4d\xd1\xc0\x00\x92\x30\xc2\x3a\x0e\xbf\x23\xf4\xd7\x25\x63\xa6\x64\xd7\xf5\x9b\x13\x8f\x56\xa1\xe4\x06\x55\x5f\xd1\x9c\xb9\xac\xbb\x27\x2b\x25\x18\xee\x21\xff\x50\x75\xa2\x4c\x2a\x54\x4a\x60\x9c\xb6\x3b\x89\xaa\x81\xf7\x4d\xf1\x5a\x0e\x9c\x0a\x26\xbf\xbb\x0e\x8d\x1e\xb6\xa5\x3e\x11\x9d\x1f\x3f\x4f\x9d\xa4\x00\xbd\x23\xb2\x53\x2e\x1b\x3d\x36\x9d\x6a\xc6\xfd\x72\x89\x1d\x1d\xa4\x5f\x8e\xcf\x03\x2c\xc4\x52\xe5\x72\xf3\xc7\xcd\xfa\xc7\xc1\xce\x3d\x7f\x1b\x86\x04\x68\xff\xb0\x5a\x3f\x1d\xf6\xeb\xc5\x43\xf7\xff\x88\x60\x74\xa0\xac\x1b\xc1\xbe\x7c\xc8\x8a\x6c\xdf\xa8\xc9\xb9\x4d\x12\xd3\x68\xa4\xef\xfe\x0c\xf5\xf4\xe1\x1a\x1e\x61\x0d\xc8\x56\x7b\xbe\x5d\x75\x55\x3e\x88\xf3\x5f\xdc\xbd\x91\xba\x8b\x98\x2d\x13\xb9\xcd\x37\xe7\x63\x19\x12\x84\x09\x96\x85\x34\xbc\x7e\xd8\x75\x49\x10\x27\x18\x79\xc0\xfb\x39\xeb\x4a\x12\xaa\xdd\x5b\x15\xef\xd0\xad\xe7\x31\x5a\x2e\x1c\x6d\x2e\x24\x04\x19\x58\xbb\x82\x11\x93\x50\x91\xd0\x08\xe6\xee\xff\xb1\x6c\x60\x79\xc5\x1f\x61\xfc\x90\x08\xa1\x14\x37\x45\xff\xeb\x2f\xf2\x0f\x8e\x2f\x7e\x24\x8f\xa3\xb8\x87\xb5\x0d\x42\x08\x9b\xbf\x42\x31\x5f\x33\x55\x84\x08\x8e\x34\xb6\x5f\xaf\x6a\xa1\xe7\xb9\x65\x8a\x10\x99\xa4\xbe\x4b\x79\x78\x83\xec\xe0\x22\x95\x2f\x91\x63\x8a\x10\x15\x3a\x43\x23\xac\x39\xb8\xff\x52\xc2\xa4\x6d\xf4\xd9\x48\x6e\xb2\x95\x13\x2a\xad\x95\xba\x6f\x14\x4c\xd2\x6e\x45\xa2\x30\xc6\x86\xda\x52\x48\x31\xe0\x32\xe0\x01\x7c\x5b\x3e\xb4\xfc\x27\x4f\x2b\x4a\x48\xe2\x79\x70\xdb\x32\xcf\xbb\x10\x8a\xfb\x01\xdc\x9a\xc4\x1d\xa1\xf9\xaf\xe6\x7a\x9b\xe5\x39\xe8\xa7\xca\x5a\x7d\xe7\x80\xbd\x22\x0b\xa8\x1b\x85\x84\x24\xd2\x36\x5c\xfa\xbe\x5b\x3f\x1f\xee\x9e\x9f\x7e\xee\xbf\x1d\x10\x9a\xb9\x3b\x3c\xaf\x77\xeb\xe7\x1f\xeb\x1b\x7f\xa9\x71\x10\x63\x9b\xf2\xe1\xc7\x9d\x9a\xa1\xe6\x8c\xe6\x4a\x1c\x43\xe8\xb0\x81\xeb\x77\x9b\xc5\xdd\x55\xe5\xe5\xc3\x8b\xe0\x87\x0b\x81\x79\x33\x3e\x01\xff\x81\xee\x7b\x65\x0c\x5d\x97\xf5\x20\x2f\x7e\x59\x22\x3c\x8c\x03\x3a\x7c\x6d\x1e\xc4\x74\x3a\x72\x61\x05\x00\x85\x3e\x65\xc5\x9d\x33\x6f\xf0\x65\x1c\x45\x52\x16\x5a\xba\x8a\xa3\x3c\x1f\x1a\x2c\x18\xcd\x3b\x26\x29\x22\x62\xfb\x04\x3c\x7f\xac\x7d\x0d\xea\xc9\x37\x0a\xe7\x84\x86\x18\xa4\xdb\x2c\x87\x51\x53\xbd\x93\xf3\x0b\x83\x3e\x20\x64\xff\xf3\x51\xe5\xcf\x9d\x4d\xaa\x14\xc9\x76\x9d\xac\x78\xec\x7a\x41\xbe\xf5\xd1\x0d\xd4\x84\xc4\x5e\xdf\xac\xcb\x6c\xda\x74\x6e\x32\x13\x75\x40\xbd\x6b\xec\x22\xcf\x07\x64\xcd\x4d\x17\x71\x10\x9d\x84\x92\x76\xd6\x18\x26\x3b\x4e\x25\xbc\x27\xa7\xe4\xb1\x45\x3d\xb8\xf8\xd0\xb3\xb6\xbf\x50\x7b\x50\x44\xcb\x58\x3b\x5c\x4d\x47\xf4\xf2\xdb\x18\x31\x01\x43\x38\xe0\x42\x6b\x27\x6f\xf3\xe1\x5c\xa3\xe9\x66\x84\x8a\x7c\xd9\x29\xab\x60\xec\xeb\xaa\x88\x51\x16\x6d\x64\xb1\xcc\x5e\x8b\xe7\xc1\x8b\x7d\x4c\x32\x33\x62\x80\xe1\xca\x84\x70\x97\x94\x4d\x7e\x60\x63\x02\x2f\x74\xdb\xe5\x45\xd4\x75\x71\x15\x0d\x22\x62\xdf\xe7\x8b\x3c\x65\x75\x9d\x95\x85\x37\x02\x18\x58\x3a\x2a\x1a\xc6\x26\xb1\xec\xaa\x02\x79\x6e\x93\x59\x44\x43\x11\x28\xe1\xea\x6b\xb7\x56\x49\xb9\x76\x0c\xef\xee\x49\x8c\x3f\xa0\x4d\xe4\x0b\x42\x88\x0d\xab\xcb\xbc\x36\x65\xf5\x92\xf9\xe2\x88\xa2\x84\x84\xb6\x36\x8a\xbf\xcf\x7b\xd6\x5c\x6f\xcb\x6a\xd9\x28\xf7\xeb\x6e\x2b\x30\xd9\xfb\xc0\x7c\x56\x51\x22\xac\x9a\xd7\xa1\x2c\x6c\x1b\xc7\x42\x9b\x26\xbb\x2e\xa5\x81\xf5\x0c\xb1\xa8\x33\xe4\xd1\x8e\x54\x0f\x14\xa5\x06\x90\xa0\xe2\x32\x96\xd1\xfc\xa1\x4c\x71\x7c\x66\xdf\x77\x37\xab\x61\x38\x44\x99\x4e\xb0\x52\xfb\xfd\x71\xb3\x5f\xdf\x1c\x1e\x91\x44\xbb\x3b\xdc\x7e\x7f\xf4\x8b\x12\x8d\x08\xf5\x06\xee\x8f\xf0\x66\xfb\x6e\xd3\x8a\xeb\x10\x8b\x3a\xcd\xc2\x68\xcc\x14\xc8\xae\x20\x61\xe9\x83\xa5\xe3\x68\x70\x3f\x46\xd9\x5a\x7f\x65\xb5\x99\xa7\x14\xb1\x76\x80\x09\xe3\x01\x35\x7e\x56\x96\x6f\x8a\x00\xea\x2e\x21\x09\x12\x5f\xf9\xab\x8e\xb0\xbc\x5c\xe1\xc3\xde\x3f\xbf\x5b\x51\x1e\x5a\xdd\x9b\x13\xa0\x1f\xe1\x47\xd1\x65\x45\x39\xd1\xa9\x45\x20\x38\xc3\x0d\x6f\x66\x3d\x7a\xa3\x46\x72\x7a\x8a\xf2\x38\x46\xa2\x64\x2e\xea\x66\x3b\x55\x0c\x57\x94\x27\x1a\xcb\x73\x8f\xbb\xf1\xef\xc5\x15\x75\x88\x8c\xfb\x52\xe8\xff\x6e\x3f\x34\xb9\x9a\x34\x4d\x74\x3f\x0f\x96\x97\xeb\xd4\x8f\x71\xfc\x45\x22\x08\x54\xb7\xf4\xa3\xfa\xae\x95\xe5\xf6\x2b\x15\x15\xa1\x08\x45\x87\x65\x69\xb7\xec\x09\xdb\xe1\x93\xa5\x9c\x8a\x58\x80\xcd\x62\x1e\x66\x68\x7d\x8a\x8a\x34\xc6\xfe\xa5\x03\x05\x6f\xab\xf2\xfd\x6a\x45\xe3\x1f\x4a\xf5\xeb\x07\x99\x3c\x11\xa1\x24\x32\xf5\x34\xc8\xcb\x9c\x2a\x93\xa2\x32\x4e\xb0\x62\xd4\x35\xbf\xcc\xa4\x52\xad\xa8\x14\x24\x76\x4b\xf3\xf2\xba\x83\x93\x28\x9a\x4c\x79\x27\x45\xbb\x3e\xfe\x93\xfa\x49\x23\x4d\x20\xfb\xae\x8d\x6b\xc4\x60\x38\x3f\xbe\x51\x1d\x1a\x84\xd4\xad\x9b\x97\x1b\x91\xe5\xd7\x81\x9c\xc4\x74\xa4\x31\x88\x3a\x73\xe7\x5a\x8a\x3a\x53\x93\xd7\x18\x54\x84\x58\x8b\x5b\x51\xfd\x99\x8d\x7e\x7a\x00\x91\xda\x55\xb1\x80\x4a\xe4\xf7\xe5\x71\x72\x76\x30\xb1\x76\x76\xbf\xd9\xe9\x62\xd3\x9e\xfd\x8b\xcb\x75\xfd\x59\x0c\xb5\xc5\x8b\xdf\x45\x7e\x3d\xd7\x65\xf7\x6f\x6e\xa9\x75\xfb\x0c\xaa\xc3\xcf\x2c\xd7\x4a\x34\x07\x5f\x69\x1c\x2c\xf4\x2c\x48\x2d\x1e\xdf\xde\xdf\x58\xe5\x71\x3c\xb5\x58\x48\x43\xac\xf7\x9f\x2c\x25\x63\x5f\x6e\xfb\x54\xa8\x8d\x0a\x92\xae\xcb\x7c\x93\x15\x65\x77\x40\xc4\xb6\xb2\x87\x12\x9f\x93\xcb\x67\xa1\x34\xa9\x03\xb6\x3c\x15\xcb\x4b\xe5\x6c\x6c\x2d\x6c\xdb\x8d\xa1\xa1\x3d\x03\x76\xbe\x46\x64\xb6\x98\xcd\x57\x0f\x18\xa5\xdc\xaa\x18\x8b\x2a\x6b\xae\x56\xf5\xc7\x1f\x4a\x99\x37\xa9\xb7\xbd\xae\x7a\xd1\x2c\x46\x0d\x83\xc9\x6d\x33\x1d\x51\xe3\x41\x23\xa6\xbc\x54\xae\xf8\xbb\xfe\xf7\xd2\x2e\x96\x7e\xbf\x75\xe3\x23\x95\x80\x17\xd1\x6f\x43\x1e\x57\xf8\xff\xdf\xd4\xac\x15\x8b\x63\x6d\x51\xfc\xd9\xb1\x80\xa1\xbd\xb9\x62\x31\x58\xd7\x8f\xc6\x72\x66\x9f\x0a\xf8\xa4\xf0\xc2\x62\x23\x13\xab\x27\x22\x8e\xb0\x1a\x24\x31\xee\x78\x12\x2a\xbb\xf3\xce\xe9\x4d\xe1\x57\xb2\x99\xcc\x79\x9e\x77\xad\x58\x12\x5b\xd8\xef\xef\x59\xd3\x40\x31\xf6\x2a\x53\x2c\xe1\x12\x85\x04\xd6\xcf\x2b\x4e\x12\x9c\xcb\x0f\x9f\xa9\x95\x2b\x96\x40\x97\xdc\x5a\x39\x51\x1b\x54\xfd\x9d\x22\x21\xe3\x81\x45\xe2\x21\x4f\x79\x25\x0a\x9d\x69\xd1\x4d\x53\x9e\x04\xaa\xc3\xbb\xa3\x6e\xb9\x3f\xc0\xb5\xf0\xfa\xf1\xd6\xcd\x1f\x05\xc1\xbe\x17\x4d\x96\x8f\x1e\x7f\x1a\x85\x91\xd3\x07\xec\xa1\xcd\x56\xf3\xc6\x9f\x4b\x50\x1e\x9b\x1e\x66\x37\x94\xfd\x53\x4c\x30\x65\xd9\x3d\x3e\x3e\x75\xe1\xa9\x8b\x4e\xfd\xa8\x34\x89\x3b\xc1\x96\x67\xd1\x00\xeb\x3e\x0f\x82\x27\x3e\x72\x40\x31\x07\x4c\x6c\x46\xf1\x18\x93\x26\xc5\x49\x9e\x0b\x6c\x60\x09\x4f\x18\x1f\x3d\x64\x45\xa8\xb6\x20\xfd\x63\xbb\x4f\xdc\xb5\xdb\xf9\x6a\xe0\xe6\xe8\x87\x31\x96\x40\xbf\x01\x89\xa6\x99\xb8\x88\x2b\xa6\x64\x8c\x4b\xd9\xe6\xf1\xc7\x7a\xb7\x77\xca\x2c\xfe\x82\x15\x08\x24\x65\x28\x17\xe3\x2e\xba\x1f\x43\x19\x45\x65\xa7\x1b\x74\x5b\x56\x6b\x55\xd6\x56\x4d\xc4\x8d\xd0\x41\x02\x49\x47\xe7\x56\xd3\x24\x91\x69\x16\x63\x6f\xe4\xbe\x3c\xae\xc4\xe9\x2c\xb2\x63\xe1\xe3\xad\xc9\x40\x15\xe3\xe6\xa5\x4b\x35\x90\x03\x50\x4c\x3b\x8f\xd2\xc3\x41\x4d\xca\xe7\xa3\xbd\x88\x41\x40\xb1\xaf\x73\x38\xb6\xe9\x59\x53\x89\xad\xa8\xc4\x69\x34\x31\x80\x93\x74\xa2\xe6\xf2\x0c\xd6\x3c\x7e\xfc\xb4\xc0\x00\xa2\x29\x70\x8b\x5e\xdd\x3f\x62\x2a\xa5\x33\xd1\xad\xc9\x26\xa4\xb8\x35\xfe\x14\x55\x03\x6a\xb8\x69\x30\x23\x78\xea\xf5\xb4\x5e\xb2\x5c\x2f\x71\x11\x18\xff\xfa\x51\x00\xd6\xb0\xfc\xf9\xdb\xd3\x6a\x3e\x4c\x88\xc2\xc8\xe0\x5e\x88\xd2\xca\x1e\xc9\x3e\x40\xb0\xab\x28\x94\x01\x16\x23\xeb\x8b\xac\x11\x2f\x79\xc8\x0a\x9d\xbd\x66\xfa\x22\xf2\x43\x6d\xdd\xcb\x46\xf7\x15\x11\x26\xc1\xe9\x43\x81\x6a\x6c\xef\x73\x32\x84\x0a\x8d\x7e\x86\x32\x17\xea\xd7\x6d\x95\x69\x94\xd0\xb6\xf2\xbe\x6e\x08\x53\xca\x9a\xd8\xd8\x30\x62\xbd\xff\x36\x6a\x6b\xab\x28\x06\x8b\x68\x69\x63\xef\x3c\x1f\x13\xc7\x55\x94\x30\x81\x48\xb6\x4b\x81\x1b\x8e\x15\x8a\x41\xe9\xf1\x6e\x44\x64\x90\x1d\x61\x9b\xbe\x4f\xe6\x59\xbc\x8d\x8c\x6e\xbb\x2f\x4a\x8c\x22\x7c\x80\x0f\x78\x68\x33\x0b\x00\x67\x07\xf7\x91\x9b\x37\xbb\x7d\x44\x3c\xb0\x42\x1e\x47\xb7\x1d\x8c\x9b\x56\x11\x8f\x94\x6d\x4e\xda\x6a\xb4\x87\xdb\x4e\xf0\xb5\x7e\x70\x92\x22\x94\xf5\x67\xa6\x5d\x17\xb7\x3f\x4f\x9a\x32\x3b\xfb\xae\xe7\x09\xd9\x5d\x45\x29\x53\x88\x7b\xcf\xdb\x48\xe6\xc6\xd3\xe1\x7f\x8a\x57\xef\x2d\xa3\xa2\x54\x32\x44\xd5\xa3\x8c\x15\x5c\x4e\xf7\x65\xd3\xc0\x80\xf8\x3f\xbe\xa9\xd4\xd8\xc9\xb1\x12\xbf\xfa\x2f\xfb\x8b\xe0\xdd\x7d\x54\x10\xeb\xd5\x95\x67\x0a\x8a\x1a\xcb\xa9\x37\x50\x94\x18\x69\x7b\x85\x1e\x15\x09\x4e\xac\x22\xa7\xf5\xbe\xee\x31\x23\xed\x4a\xc6\xff\xd9\x29\x57\xf8\x27\x23\x52\x86\x3f\xfb\xc1\x59\xba\x8e\xdc\xf6\xc7\x73\x50\xc6\xd4\x2b\x80\x60\x51\x66\x26\xf4\x8c\x24\x44\x89\xeb\x3e\x3c\xe9\x2e\x76\x8e\x94\x04\xff\xf6\x79\x3d\x86\x5b\x44\xb9\x9c\xc6\xcb\x4d\xa4\x63\x9d\x76\x7e\x08\xf8\x84\x76\x83\x9f\x43\x9b\x08\x3b\x77\x36\x81\xba\x2f\xc5\x47\xa0\xc3\x27\x70\xc2\xbf\xfc\x3b\xba\x0b\x6d\x12\xda\x11\x35\xab\x59\x80\x97\x2f\x67\xce\xc0\x4b\x54\x64\x28\xe5\x9d\x73\xe3\xae\xb9\x68\x28\x9a\xd2\x38\xd9\x94\xd1\x43\x8d\xc3\x40\xf6\x6c\x44\x07\x0b\x7e\xc9\xea\x7f\x80\xf0\x3f\x69\x1c\x86\x36\x56\xef\x64\x3f\xbe\x17\xb6\x6e\xae\x57\x65\xf9\x2b\x9b\x34\x53\x63\x42\x62\xa3\xbc\xc2\x5f\xf6\x27\x74\x42\xfa\x2a\x26\x22\x66\xc3\xc4\x60\x55\xba\xc2\x81\x1f\xc0\x28\x67\x56\xcc\xff\xdd\xf9\x17\x0d\x1e\x7f\xcc\x94\xc1\x05\xe4\x94\x15\xcd\xa1\xc9\x4e\x70\xb0\xfd\x2b\xeb\xb8\x31\x3f\x6b\xe2\x48\x5a\xc7\x17\x68\x5e\x86\xe1\x64\x1c\xa9\x18\xa9\xc6\xd6\xab\xcf\x2d\x46\x70\x27\x72\xf1\xfe\xe1\xe5\xf9\x3a\x35\x8d\xe3\x50\x60\x60\x77\x23\xca\x8e\x9c\xe5\x1b\x88\xd5\x27\xdc\x04\x15\xc7\xd4\x0a\xe5\x6a\xf0\xb2\x13\xab\x49\x63\xd4\x0f\xe4\xb6\x7c\xb4\x7a\x7a\xbc\xdd\xdc\x1d\x6e\xd7\xeb\x9d\xbf\x89\x58\x2a\x5c\xa3\x7e\x96\x55\xae\x7f\x66\x1a\xee\xcb\x91\x77\xb9\x8a\x93\x28\xc6\x29\x8b\x96\x52\x6d\x48\x36\x84\x9f\xa9\x38\x89\x13\x6b\x61\x75\x29\x74\xfb\x3a\xa0\x14\x79\xe1\x83\xbf\x98\x6b\x13\x27\xfd\xec\x18\x28\xb4\xab\x38\x55\x56\xa7\xb4\x86\x06\xfd\x05\x67\xd9\xd6\x2a\x4e\x41\xe1\x1b\xd5\x61\x7d\x66\xd7\x60\x37\xd8\xab\x75\xca\xcb\x75\xdd\xbc\xdc\x97\x65\x23\xcb\xf7\xc9\x09\x85\x96\xb4\x33\xc9\xfa\x5c\x00\x6c\xfc\x21\x49\x22\x69\x99\xc0\xf5\x25\x9f\xb0\x52\x54\x2c\x63\x85\x9a\x57\x05\xbc\x79\x20\xf5\x6f\x1f\xfc\xbc\x55\xac\x88\x65\xd2\xfe\xeb\xa2\x8f\xce\xcb\xfa\x33\xe8\xfb\x7f\x4c\xea\x32\x73\x05\xd0\xcf\xea\xa2\xfe\xdb\x62\x6b\x6c\xe1\xa2\xbc\x59\x3b\xb9\xf1\x3c\x54\x5c\x2a\x3a\xa2\xb2\xcc\xc6\xdd\xd3\x2f\xd2\xa1\x4e\xc1\x87\xd6\x4f\x97\x66\x2f\x8e\xa3\x6e\x48\xac\xa9\x4d\x85\xdd\x56\xb7\x7b\xb9\x34\x9d\x75\x60\xff\xed\x9a\x0b\x0c\xc4\x5f\x44\x8d\x31\x16\x34\x1d\x99\x4d\xc5\xc0\x18\x56\x2d\xd7\xaa\xbc\xef\xd4\x4f\x55\x0c\x51\x4a\x62\x47\xf1\x38\x34\xe5\xa1\xce\x34\x1c\xd4\x08\x51\x3f\x7f\xab\x20\xa5\xb4\x1c\xd4\x77\x6f\x9f\x3b\x2c\x3a\xc6\x46\x11\x3f\x39\x6f\xb2\x5a\x5e\xaa\x3a\x2b\xb0\xb4\x3b\x9e\x17\x49\x40\x15\xea\x6b\xa0\x9a\x1c\x2a\xdb\xef\xbd\x25\xc2\x6f\x7e\x88\x8c\xb1\xa2\xaa\xe1\x7e\xaa\x43\xac\x92\x90\x01\x16\x79\x06\x85\x68\xaf\x5f\x39\xb3\x3d\x25\x84\x85\xd8\x77\xdc\x96\x0d\x14\x8d\xcf\x61\x12\xca\xd3\xa0\xcb\xc1\xc7\x75\x88\x84\x02\xa0\xc0\xa1\x12\x95\x3e\x60\xf8\x75\x68\xb7\xdc\xe1\x5b\x9c\x30\xaa\xb0\x5d\x75\xbb\x1a\x48\x4d\xa8\x24\x0a\x24\x56\x56\x25\x52\x71\x2d\xaa\x66\xf6\x71\x26\x91\x56\xa8\x23\xbf\xbe\x7d\x6a\xc3\xe9\x65\xaf\x0c\xe0\x07\x18\x7b\xaa\x36\xf9\x7e\xc9\x2a\x2f\x22\x3e\xb9\xd6\x98\x86\x48\x29\x10\xa8\x9f\x36\x7a\xc7\x92\x44\x10\x04\x6d\x2e\xce\xe7\x1c\x7a\x09\x78\x95\x24\x2a\x00\xd7\x21\xcf\x4a\x4d\x1e\x2f\xa7\xa1\xe3\xb1\x4a\x12\x88\xa4\xf7\x0e\xb7\xdf\x6a\x8b\x0c\xe3\xd3\xf3\xc0\x7a\x3d\x7d\xb7\x6f\x0b\x1a\x95\x0d\x12\x78\x5f\x6e\x4f\x38\x95\xc6\x81\xf5\x9d\x23\x5a\x8f\xff\x53\x09\x8f\x48\xea\xd2\xd7\x27\x63\x32\x24\x4c\x55\xf9\xf8\x51\x70\x49\x92\x78\xc6\x0d\x66\xf2\x48\x53\x16\xa8\x4e\x2a\xbd\x79\xb1\xa0\x83\x5d\x53\xaa\x5f\x13\x0c\xd2\xfc\x0c\x4f\x52\x61\x30\xf1\x59\xbf\x42\xd1\x2c\x2f\xd7\xdd\x80\xf1\x3b\xac\x63\x76\x4f\x40\x04\x24\x71\xc2\x73\x0f\xd9\x20\x82\xff\x27\xff\x1f\x3f\x82\x90\xa8\xf3\xc2\x7d\xb8\x8e\xd9\x8c\x2a\x11\x91\xc2\x77\x66\x51\x35\x99\x11\x6a\x26\xa5\x4c\x84\x24\x1e\x79\xfb\x20\xde\xf7\xe5\x0e\xf2\xb1\xc8\x8e\x4a\x04\x50\x9f\x8f\x3f\x8a\x13\x2e\x5b\xbf\x97\xd9\xaf\xd1\xae\x94\xc8\x90\x63\x5f\x1e\x4b\x5a\x8e\xb8\xd3\x91\x91\x54\x22\xb9\xb1\x8a\x7c\x03\xb5\x39\x07\xd7\x1b\x7f\x99\xa2\x0a\x57\xe4\xdf\xab\xeb\xb9\x29\xcf\xd7\x2e\xa6\x7d\xf8\xdf\xa0\x11\xc7\xf7\xa8\x92\xd0\x0a\xa9\x7a\xc2\xb9\x5f\xc4\x12\x05\x21\xa2\x48\x7d\xf8\x62\x95\x0a\xfa\xc3\x46\x23\x45\xd2\xc2\xa9\x10\x69\xef\x4c\x44\xb1\x58\x3d\xd1\xb5\x9d\xfc\xdc\x9a\x02\x16\xab\x32\x55\x6e\xea\x55\x5e\x76\x4c\x52\x95\xe8\x44\xe3\xa1\xba\x11\x85\x6e\xe3\xb3\xe1\x93\x84\x58\x8a\x3e\x15\xdf\x42\xb5\x82\xa2\xa9\x6f\xc4\xf5\xa9\xe8\x1e\xa7\x09\xac\xdd\x70\x56\xb7\x2f\x36\x4c\x38\x08\x2a\x31\x89\x35\xa8\xc1\x14\xe2\x06\xf2\x46\xfc\xdd\x00\x68\x72\x13\x46\x24\x64\xd4\xdc\xbf\x07\xd3\x74\x8a\xd7\xa3\x2f\xe5\x01\xd7\x08\x78\x42\x03\x01\x3b\x05\x66\xd7\x4c\x1e\xc8\x00\x8b\x0d\xa7\xac\xc0\xa0\x6a\x14\xc0\xf0\x40\xa5\xd4\x55\x55\xd0\x76\x66\x88\xb7\x1b\x5f\x1d\x0f\x4c\x84\xc1\x92\x2b\xcb\xda\xf3\xec\xcb\xad\xa8\x9a\x4c\x65\xe7\x0e\x93\xab\x78\x48\x75\xec\x75\x0c\x36\xcd\xcd\xeb\x68\x01\xe0\xa1\x08\xad\x2d\x8b\xeb\x25\x59\x93\x08\x54\x28\x99\x8d\x6a\x78\xa8\x98\x4e\xfc\x8c\xc2\xfb\x25\x83\xd9\xce\x43\x08\x1d\x1d\xc5\xe9\xd0\x74\xe4\x96\xac\x2c\xb0\xc7\xf2\x31\xcf\xe2\x21\x30\x2e\x3b\x07\x9f\xef\x59\xff\x44\x68\x18\x5b\xcf\xab\x97\xd2\x01\x52\xac\x11\x5a\x77\x9c\x5a\x30\x66\x1b\x0a\x9d\xa0\x03\xba\xf9\xa3\xa9\xf4\x7c\x94\xa1\xd6\xe3\x8c\x10\x80\xe2\x2c\x20\x21\xf3\x59\x95\xfa\x35\xce\xdd\x66\x57\x35\xce\x42\xc0\x22\xdc\xa1\x86\x66\xd9\x6e\x66\x79\x1b\xf9\xea\xa1\x16\x86\x1b\x19\x09\x2b\xdf\x91\xd5\x4e\xd5\x02\xb1\x2a\x9f\x94\xb8\x79\x24\x19\x71\x42\x61\x2e\xbd\x9e\x1c\xd7\x04\x5c\xd7\x6a\x73\xb2\xca\x7c\x48\x9a\xc2\x9a\xd2\x44\x26\xaf\xbf\xda\x58\x11\x70\x74\xda\x6d\x59\x35\x76\x96\x8e\xda\xb7\x3c\x86\x14\xc1\x0a\x48\xb3\xb2\x4f\xa9\x17\xa5\x53\x3c\xa1\xaa\x47\xf2\xec\xa0\x19\xc0\x02\xe6\x6f\x24\x01\x8b\x58\xb2\xa8\xa6\xf1\x26\xc7\xb9\x54\x18\x2e\xfd\x63\xbd\x78\x3e\xec\x7f\x3e\x39\xaf\x67\xff\x65\x69\x1a\x86\xbc\xd3\xa8\xc2\x30\xb6\x5d\x7e\x37\x37\xf3\x00\x65\x9e\x2a\xa6\xdc\xbb\x83\xdd\x73\x2b\x22\x1f\x0c\xdb\x63\x5c\x86\xb1\x57\xc6\x6d\xe7\xec\xae\x81\xb1\xc3\xba\xe2\x92\x2b\x91\xf8\xa8\xb3\xbc\x62\x4f\xef\xa3\xa2\x83\xe2\x52\x00\x26\x02\x87\xac\xc6\xf6\x16\xee\xbb\xe3\x21\x2a\x24\x21\xf4\x96\x39\xc3\x96\xfe\xe4\xd2\x95\x90\xd8\xb5\xc8\x45\x75\x84\xba\x19\xd6\x89\xb8\x52\x24\xb0\x4b\xa2\xc3\x6f\x6f\x6e\xa6\x3a\x2b\xf3\xaa\x47\xee\xf3\x3a\x04\xd4\x89\xb8\x29\xd5\x4c\x91\x64\xfe\x67\x33\x34\x8a\x89\xab\x95\x5e\x1a\xf0\xee\xda\xb6\x8a\xe5\x95\x0a\x46\x91\x08\x37\x8c\x87\x81\xdb\xaf\x57\xfb\x4f\xee\xd3\x40\x84\xbf\x78\x01\xef\x7e\x4e\xa5\x81\x10\xf8\x8a\x56\xa2\xd0\xe5\x29\xfb\x73\x32\x4b\xd2\x30\x0a\x71\xae\xfb\x57\x1b\x65\x33\x3e\xa6\xa1\x1f\x2b\xf1\xee\xf3\x84\x88\xd4\x8c\xf9\x40\xdb\x4b\x75\xee\xa2\xa4\x94\xa4\x09\x72\x7e\x7c\xfb\xc1\x9a\x84\x8f\x4f\x42\xa3\xc0\x9b\xb7\xd9\x62\x6a\x2f\x26\xa0\x52\x1a\x13\xe1\x2a\x39\x0b\x34\x59\x6f\xdf\xff\x76\xaf\x5c\x54\x93\x65\x20\xa5\x2a\xc4\xd5\xec\x0e\x9a\xef\xe7\x7d\xa6\x7e\xcd\x34\x7e\x53\x96\x70\x74\x87\x3d\x5c\x41\x54\x28\x96\xb6\xb2\x05\x8a\xdf\xba\x01\x56\x5d\xf4\x08\xcd\xa6\xc8\x9a\x4d\x71\xbe\x34\xd6\x17\xaf\x81\x0f\xed\xa3\xf9\x9f\x38\x65\x42\xc5\x56\x26\x18\x44\x35\x00\x54\xb8\xc3\x51\x9a\x62\xa1\x19\x5b\x4c\x59\x73\xed\x39\x1e\x2a\x8d\xa4\xc0\xb5\xac\x9d\x1d\xa5\x95\x86\xbf\xad\xe0\xdf\xdd\x61\x25\x52\xd7\x78\x7a\x16\x0d\xcc\x68\x8b\xb5\x63\x24\x12\x04\x6c\xaa\xbd\xec\xa4\xa0\x55\x1a\xc7\x1c\x11\xa6\x6f\x58\xb7\x9d\x5a\xa4\xa9\x34\x16\x94\x5b\x0e\xd8\x39\x2f\x27\xb0\xe3\x34\x36\x56\x71\x66\x60\xa4\x3e\xf4\x0e\x68\x07\x10\xde\x6b\x3b\xa0\x29\x4b\xfd\xd2\x27\x76\x69\x12\xd8\x92\xd8\x7d\x79\x74\x85\xe3\xe1\x5e\x99\x26\x81\x24\xd6\x40\xa0\xfc\x6d\x74\x3f\x49\x92\xa2\xd2\xc0\xae\x34\xcd\xa1\x73\xfc\x51\x69\xa2\x38\x36\x40\x5c\xd6\xbb\x2a\x8b\xba\xc9\x9a\xcb\x07\x01\x15\x95\x72\xc2\xf1\x0c\xeb\x1c\x71\x20\x83\x94\x22\xe5\x91\x46\xe0\x72\x01\x9f\x40\x32\xfd\x38\x01\xc8\x10\x5b\x2d\x76\xdf\xfe\xdb\x7f\x38\x0d\x94\xea\x76\xeb\x85\xb5\x90\xf8\x54\x0c\x42\xa5\xd2\x59\x36\x89\x5e\x32\x96\xfb\x43\x71\xa0\x7b\x62\x5d\x3b\xc7\xd7\xcd\xcb\xd4\x80\x7e\xfc\x7b\xc8\x24\x46\x19\x02\xfb\x91\x07\xf1\x3e\x12\x5c\x9e\xbf\x0b\x4f\x04\x72\xf5\xb9\xda\x36\xde\x88\xdf\x16\x52\x88\x02\xac\x74\x61\x11\xe7\xbe\x14\x23\x06\xa2\x4a\x41\x27\xf1\x80\xc7\x66\x1f\x18\x66\x80\x6e\x80\x09\x63\x8c\x86\x24\xa0\x45\x93\x17\x99\xf2\x47\x59\x04\xbe\xe0\x5b\xd7\x80\xe5\x3c\xab\xfd\xb4\x85\xea\xdb\xa5\xd0\xd5\x60\x6c\x6c\x1b\xc2\x06\x60\xeb\xd5\x12\x95\x08\x04\x45\x43\xc0\xbb\xbc\x94\x22\xdf\xe8\x32\x6f\x7f\xcb\x61\x94\x2b\x42\x46\x10\x43\xe4\x1e\xde\x24\xc5\x9e\x7d\x94\x22\x8c\x28\x7a\xec\x88\xac\xba\xa9\xca\x33\xee\xf4\x87\xee\x84\x31\x57\x66\xa0\xf8\xfa\xdb\xac\x70\xcd\x9c\x2e\x95\x12\x21\x07\x89\xc9\x0b\xfc\x0b\x54\x33\x47\xfd\x1f\x8c\x55\x56\x6c\x2c\xab\xb1\x2b\xd9\x66\x44\xf7\x50\x1c\x9b\x97\xd1\x6b\x22\x42\x23\xb0\xc4\x27\xb4\x9e\x93\x9f\x54\x82\x8a\x30\x74\xaf\xe1\x4f\xc8\x70\x0d\x7c\xc8\x54\x55\xfe\x0e\x57\xff\x2a\x0a\x0a\xa9\xec\xb7\xff\xf6\xda\xfc\x5c\x1b\x9f\x8b\x05\x56\x45\xfc\x19\x96\x65\x55\xac\x0b\xa8\x8e\xd7\xbf\x25\x40\xae\x04\xa3\xc6\xba\x02\xf9\xe5\xa2\xb8\x7e\xa2\x25\xa2\x44\x14\x98\x28\x75\x5a\x22\xf5\x68\x51\x11\x51\x14\xa1\xd4\xda\x22\xcf\x57\xe2\xdc\xa8\x17\xe1\x8f\xc4\x54\xa0\x80\xe4\xc0\x83\x77\xd7\x94\xe7\xf3\x20\x49\x17\x31\x93\x18\x2f\xcb\x4b\xde\x29\x9f\x7d\x7a\x15\xb1\xb4\xb2\x0b\x8b\x73\x59\x79\x9f\xdc\xbf\xbe\xcf\x58\x27\xb8\x85\x36\x19\x54\xc3\x58\x5d\xc4\x46\x19\x35\x98\x37\x3f\x36\xdb\xaf\x23\x5e\x91\x18\xa9\x87\xbe\x3d\x5e\xf0\xf8\x27\xc0\xaf\xfd\x9b\x47\x5b\x08\x4e\x24\xce\x56\x54\xab\xbb\x2f\xcb\xee\x59\x71\x69\xad\xbc\xfd\x37\xa2\xe0\x4c\x56\x1c\xf7\x2f\x55\xa7\x52\xfc\x75\x7d\x5a\x70\x15\x3a\x65\x94\x4d\xf1\x20\xb2\xa2\x11\x59\x31\x28\xdb\x88\x94\x40\x60\xf9\x4b\xfa\xa2\x6c\x97\x74\x5a\xa3\x18\x9f\x30\xe5\x69\xea\x02\xc7\xb1\xf3\xf9\x74\x9c\x24\xa8\xac\xd6\xe5\xf1\x65\x35\xd4\xfb\x54\x42\x84\x02\x0b\x5f\x87\x5e\x94\xd4\x92\x4c\xf6\xb6\x92\x3e\x99\xb9\x22\x31\x74\xc8\xaa\xdf\x15\xe5\x9b\xc9\xc5\x2f\x0f\xa4\x68\xa3\xdd\x1f\x99\x98\xae\x0b\x13\x71\xbd\xa9\x7e\xb2\x12\x3a\x24\x58\x6b\x41\xf1\xf4\xfa\xd0\xce\xd8\xc3\xb9\xca\xa6\x3c\x31\xa1\x29\xa3\xbc\xdf\xa8\x6f\xd1\xac\xbc\xcd\xe7\xc2\xc9\x85\x6a\x46\xb4\x17\x72\xf9\xd9\x7b\x27\x28\x01\x91\x41\x88\x5a\x5e\x8a\xe2\x19\xce\xf6\x66\x1f\xcb\x26\x33\x99\xfa\x68\x9c\xad\x04\x80\x9d\x3d\xbb\xfd\xe2\x6e\x7d\xb8\x7d\xfa\xfe\x7c\xd8\x6f\x1e\xd6\x87\x75\x07\x0b\x14\x26\x26\x58\x0f\x5f\x3d\xdd\x3f\x3d\x1f\x7e\x7e\xdb\x78\x5d\x5f\x25\x03\x95\x78\x61\x26\x04\x44\xd7\x4f\xc6\xb9\x63\x7d\x96\xcf\xf7\x41\x9a\x0c\x03\xd0\xce\x83\xa2\xd3\xde\xdb\x8a\xba\x86\x49\x65\x4f\x32\x66\xb8\xee\x52\x46\x93\x1d\xd1\x1b\x1b\x8b\xad\xe3\x81\x11\x25\x98\x38\xd7\xa5\xfa\x29\x2a\x30\xa2\xc2\x9e\x81\xbf\xda\x88\xc5\xd1\xd0\x27\xb7\x0d\x65\x46\x62\x6e\x5f\x49\x75\x28\x19\x09\x2b\x61\x75\xb7\xfb\xfe\x00\xba\x8b\x7f\x64\x04\x06\x85\xc1\x50\x6b\xf5\x47\xd9\x80\x35\xcb\xc7\x9e\xee\xc6\x4c\x25\x13\x67\xe9\x99\x32\x32\xa1\x8a\xfd\x16\x5a\x7b\x83\x10\x25\x63\x69\x10\xa8\x73\xfb\xc7\xfe\xa3\x1a\xad\x92\xb1\xb6\x2e\x67\x5e\x82\xb2\xcf\x26\x26\xe3\x0c\x43\x26\xc1\x2b\x5e\xdd\xcc\xfa\x2f\x93\xd0\xca\xaa\xdb\x30\xcc\xe1\x47\x46\x0c\x56\x99\xa4\x11\x8d\x7b\x7c\xcb\xc0\x7f\xd7\x0f\xd0\x02\xe5\x3d\x85\x2c\x2b\xeb\xb6\x39\xfd\x12\xad\x11\xfe\x72\x2e\xcf\x56\x2d\x62\x72\x99\x9c\x49\xdf\x45\xdd\xa8\xb2\x0f\xda\x24\x8f\x28\x4a\xe3\x1f\xda\xf4\x7a\x4e\xef\x0f\x87\x20\xd0\xd8\xe2\x1e\x76\x50\xe8\x4f\xe4\x02\x94\xe4\xdc\x6e\x86\x8b\xe5\x7a\x18\x04\xc8\x94\x1a\x4b\xda\x71\xf4\x81\x51\x18\x23\x45\xbb\x3d\x75\xeb\xec\x1d\x14\x13\xe5\x1c\x3f\x2c\xb2\x51\xbc\x55\x2c\xc7\x5e\x50\xdf\x83\xf1\x63\xe2\x44\x81\x4b\x4f\xec\x4d\xec\x4b\x47\x83\xb9\x2d\xab\x91\x6e\xe7\x90\xa5\x34\x99\x42\xfe\x64\x52\x61\x10\x68\xdd\x4a\x06\x59\x90\x14\x8a\x6a\x32\x12\x64\x76\x40\x86\xa9\x86\xfb\xf8\x57\x92\x4c\xa0\xce\xc9\xb0\x63\xde\x2e\x7c\x5d\xe8\xbe\x2e\x6c\x09\xfd\xc3\x6a\x22\x65\x62\x4b\x3f\x35\x34\x4b\xb4\xfc\x58\x1c\x2b\x80\xaf\x64\x0b\x86\xbb\xa2\x94\xd2\x5a\x77\xdf\x3c\xed\xfe\x7b\xf4\xcb\xa8\xc0\x92\xa7\xdf\x20\xab\xb7\x50\x2d\xb3\xe3\xf8\x30\x4b\xb1\xbd\x86\x5d\x63\xdb\x63\x7e\x10\xc5\x45\xe4\xf9\x24\x1d\x91\x8a\x13\xa5\x3b\xd6\xae\xfa\xb5\xbc\x2e\xaa\x66\x68\x93\x33\xbe\x1f\x4d\x64\x32\x22\x88\x2f\xaf\xf7\x70\x14\xea\x13\xf4\x83\x84\x80\xe0\x7b\xe6\x00\xd0\x97\xe6\xa5\xac\x6e\x2a\xf1\x96\x15\xc7\xfa\x43\x27\x6f\xbc\x7b\xf8\x33\x44\x16\xc3\x77\xba\xae\x8b\x26\x6b\xae\xbb\xa6\xba\xa8\x89\x73\xa6\x92\x00\xdc\xba\xf8\x97\xc7\x72\x42\x2d\x92\x86\x6a\xe6\xeb\xe3\x08\x64\xa9\x9f\xcc\x36\x9b\x54\xab\xb9\x1f\x1c\xdb\xee\xfc\x8b\xa8\x6f\x1e\x77\x1e\x10\x3c\xbf\x46\x19\x1e\x5b\x1f\xb1\xa2\x81\xea\x55\xe4\x3b\x50\xdd\xda\x60\x84\x95\x12\x1a\x9b\x09\xdd\x40\x2e\xae\x5d\x74\x2e\x8d\x34\xa8\x73\xff\xbc\x5e\x6c\xd7\xcf\x87\xcd\xe3\xfe\x79\xbd\xdd\xdc\x1c\x1e\x16\xff\x7d\x58\x2d\x9e\xef\x3c\x49\x56\x05\x91\x48\xc2\x51\x1b\xbf\x7f\x0f\x55\x90\x82\x50\x43\x00\xdc\xb6\x43\xe5\xab\x40\x70\x6e\x4d\xdc\xde\xed\x22\xec\xeb\x23\xfe\x38\x00\x6a\x7b\x9f\x4a\x9d\x99\xeb\x5f\xd1\xd6\x15\x21\x11\x19\x6e\xc7\x65\x35\xa2\xfd\x8c\x27\x8b\x22\xa4\x43\xac\xee\x44\x0e\xeb\x2e\x0a\x51\x44\x58\xca\xd3\xe1\x5c\x81\x73\x13\x85\x69\x60\x39\x1f\xdd\x29\x22\x23\xaf\x5e\xb6\x2d\xf3\x4c\x5d\x3f\xd3\x93\x9a\x05\x7a\x28\xa2\x02\xd3\x59\x61\x34\x22\xbf\x2d\x3f\x68\xe3\xb8\x91\x54\xc4\x08\xc0\x5a\x59\xe2\xde\x7f\x5d\xca\x89\xde\x83\x52\x2c\xb2\xbc\x08\x6f\xfe\x8e\xd7\xfb\x5f\x17\x98\x6e\x4b\x8a\x25\x69\x18\x0c\x10\x1a\xff\x75\x81\xea\xba\xd1\xf5\xbe\x5c\x42\xb3\x29\x34\x3a\x64\x8e\x26\x97\x8a\x28\xf7\x14\xe3\xf6\xe1\x79\xbc\x84\x05\xfd\x62\xdf\xe0\x61\xda\x2c\x52\x71\x90\x44\x2e\x4a\x7c\x3a\xbb\x9e\xde\xec\x7b\xa9\xe2\xc0\x0a\x32\x75\xd8\xf7\x9e\xcd\xad\x62\xc2\x30\x44\x5c\x3f\xed\xda\x90\xb0\xfb\xd1\xe2\x88\x2a\x3e\x5c\x3d\x7d\x9f\xa1\x3e\x4c\x9e\x4b\xcc\x09\xb8\x87\xbc\xbd\xc8\xdf\xe1\xda\x17\x3b\xc9\xa8\xd8\xa9\x12\x96\x28\x67\x74\x9d\xd5\xed\x46\xfb\x74\x6e\xa3\x75\x5b\x4a\xed\x66\x69\xc2\x53\x4e\xbd\x8e\x32\xbc\x66\xe5\xa5\xbe\xb9\x14\x47\x28\xcb\x62\x33\x12\xfd\x52\x2a\x11\x9c\xfb\x46\x42\x0f\xcd\xb8\x58\x04\xf4\xa7\xba\x4d\x4a\x71\x62\x9d\x8a\xec\x12\x3f\xb9\x1f\x9e\x50\xc2\x3d\xd1\xcb\xd7\x7b\x1e\xb2\x5a\x7d\x55\xeb\x50\x9c\x47\xd8\xa9\xb6\xc2\xb6\xd1\xe4\x9c\xa9\x61\xc8\x97\x41\xac\x77\x7b\x1a\xdf\x1d\xed\x42\xd7\x36\xc0\xa2\xd4\xc2\x49\xb1\x3f\xd5\x66\xf0\xa3\x8b\x96\x69\x80\x4d\x64\x61\x79\x0e\xbb\x0b\x12\x4c\x06\x9a\xeb\x4a\x49\x1d\xa0\x73\xc0\xc3\xe6\xf1\x70\xb3\xde\x2e\x9e\xf7\xdf\x9f\x51\xe9\xab\x1b\x00\x9c\xbb\x79\x76\x5f\x16\x47\xcc\x45\xba\x63\x26\xc4\x52\xbb\x0b\x70\xdc\x04\xb7\x51\xc0\xd0\x78\x56\x29\xc5\x94\x87\x8a\x3b\x59\x16\x5b\x36\x9b\x2a\xe6\x28\xa5\x22\x6d\x69\xe1\x65\x3e\x09\x6b\x95\x92\x09\x36\x21\x2f\x85\x57\xfb\x06\x3d\x92\xa7\x0d\x09\x9f\x4d\xbc\xbc\x48\xba\x52\x3a\x00\xac\x67\xdf\xe6\xd9\xf9\x9c\x35\x53\xa9\xae\xcb\x8c\x3f\xa6\xfb\x24\x30\x6b\x44\x2d\xb4\x7e\x84\x37\x8f\xca\xf9\x0b\x95\xf0\xf1\x4f\x0a\x90\xca\xb8\xef\x9b\x4f\xee\x0e\xc0\x02\x1f\x6a\x24\x0a\xba\x59\x3b\x79\x2d\xc1\x24\x98\x16\x89\x57\xa8\xc4\x11\x76\x65\xae\x07\x5e\x3d\x4a\x99\x20\x52\x56\x9c\x16\x2f\xcf\xe6\xb6\x17\x94\xbe\x9b\x9f\x83\x86\x0b\xa4\x15\x0f\x55\x9b\xbe\xb6\x80\x51\x3a\x88\x05\x66\x05\x59\x83\x7e\x40\x8f\x30\x71\xf6\x56\x3a\xe0\x7a\xe4\x92\xf4\xb9\x20\x9a\xd2\x61\x98\x22\xbf\xe0\x11\xde\x6c\x08\x32\x0d\x57\x27\xdf\x1e\x72\x6b\x72\x7d\xcc\x4e\x27\xc0\x75\xce\x4f\x32\x4d\xc2\x44\x26\xbe\xdc\x02\x6d\xce\xd3\x46\x20\xfb\xb2\x3b\x9e\x50\xa4\xee\x36\x48\x8c\xec\x1f\x9b\x26\x3c\xb0\x3a\xdc\xe5\x79\x28\x45\xdb\x1e\x10\x58\xeb\x3e\xfc\xfb\x02\x97\x4f\x38\xe7\x9a\x48\x8a\x77\xf0\x0c\x7a\x99\x5f\x46\x6d\x75\x4d\x63\x83\x97\xf4\x90\x15\x7f\xa1\x95\xa3\x69\xe2\x04\x7f\xdb\xbd\xb3\xd0\xe5\x09\xfd\xa7\xa6\x24\x73\xcd\x42\x82\x42\x81\x3e\x27\x1b\x63\xe2\x35\x63\x11\x52\x88\x91\xa8\xe0\x2a\x87\x28\x9b\x39\xe4\x94\xe9\x88\x10\xa4\x59\x5b\xff\xd2\x8f\x54\xc9\x2e\x24\xd6\x91\x30\xa9\x55\x83\x2e\xdf\xf4\xed\xa5\xd0\xae\x13\x3e\xbe\xa8\x48\x27\x88\xc0\xb8\xb5\xa5\x74\xff\x52\x7e\x52\x1f\xd5\x49\x9c\x5a\x47\x93\x57\x28\x9a\x95\xa8\xf4\xb3\xab\xad\xfa\xbb\xe0\x11\xc7\xb2\xc2\x29\x2b\x9a\xcd\xea\xe9\xef\xb0\xf8\x35\xe7\x12\xaf\xc1\xb9\x1f\x67\x7f\xc2\x5c\xf3\x5a\xa7\x69\xa4\xc5\x60\x6e\xfa\x37\x79\x2e\x9e\xd1\xa9\xa2\x08\x29\xee\xcc\x51\xd6\x85\xae\x3b\xd4\xbd\x16\x52\x22\xf3\xae\x8d\xc7\xb6\xcf\xeb\x87\xcd\x77\xbf\x6c\x6a\xc9\x38\x7e\xd2\x97\x19\xaf\x13\x5c\xab\x56\xb1\xc0\x44\xf5\x41\x54\x55\xd6\x73\x5e\xb4\x4a\x23\xe4\xb3\x1e\xb2\xda\xea\x71\x82\x7e\xaa\x46\x66\xdb\x93\xfb\x56\xa9\x8a\xa9\x23\x3f\xd5\x59\x3d\x4c\x30\xb5\x92\x16\xbd\xd7\x74\xd8\xc7\x6a\xd2\x87\xd5\x9a\x06\xde\x69\xe8\xa3\xb8\xa9\x0f\x69\x3b\x91\xd3\xf1\xe3\xd1\x54\x32\xc7\x7f\x44\x25\xcc\xdb\xb2\x9a\x4a\x53\x29\xad\x85\xf5\x12\xad\xc0\x52\x0c\xfd\xb5\x19\x15\x63\x91\xd9\xd6\x9f\xac\x2f\xb0\x3d\x04\x41\x40\xb1\x44\xb8\xbf\x34\x65\x95\x89\x7c\x26\x93\x87\x20\xd4\xbc\x2b\x00\x2c\xc7\x3c\xa7\x36\xab\xc0\x9d\xb1\x7c\x85\x4a\x57\xc2\x34\xab\x3c\x33\xa6\x3b\x1a\x51\x31\x40\xcf\x2d\x0a\x6d\x9d\x5b\x47\x7d\x64\x08\xc0\x2a\x81\xb7\x37\x67\xd5\x08\x67\x9f\x3f\x84\xa1\xb2\xce\xf1\x2f\x59\xae\x2b\x28\xc6\xcb\x3a\x84\x2c\xd5\x4e\x7a\x7a\x25\x0a\x7d\xbd\x17\x85\x45\x30\x8f\x6f\x27\x64\x06\x0b\xb0\xb7\x4f\x0f\x4f\x83\xc6\x09\x84\x5c\xc7\x72\x54\xd8\x1b\xe4\xce\x10\x72\x50\x6e\x53\xda\xb8\x24\xe3\x73\xa1\xd9\xf1\x65\xa5\x09\x36\xc0\xee\x00\x21\xe1\xbb\xe6\x62\x0c\x1a\x67\x4c\xa9\x99\x7e\x3c\x50\x2c\x9b\xef\x41\x9c\x16\x85\x5e\x7c\xd0\x4d\xf8\xe4\xe9\xd0\x20\x35\x2e\x7c\x40\x49\xed\xbf\x92\xa2\x53\x40\x13\x86\x0d\x56\x5c\xdb\x9f\xf2\xeb\xe9\x9c\x75\x69\x13\x30\x93\x12\xb7\xc4\x5b\xc7\xc4\xc9\xd6\x03\x51\x28\x11\x91\xec\x97\x20\x27\xb2\xbd\x6e\x3e\xe9\x5b\x43\x14\x2b\x5c\x76\xa1\x79\x99\x88\xcf\x29\x88\x43\xeb\x3e\xbf\xe9\x96\x14\xbd\xcf\x3e\xf2\x63\xfd\x68\x1a\x60\xee\xeb\x24\x91\xdb\x94\xb6\xb6\xa2\x78\xcb\x6b\x14\x04\x41\x77\xd6\x34\x26\x8e\x35\xe1\xeb\x0b\x5d\xf7\x0e\x62\x61\xf5\xc7\xe1\x84\x62\x61\x28\x32\x25\xc6\x1d\x40\x88\x45\xc2\xc0\x7d\x11\x54\x8f\x65\xf1\x0c\x80\x9b\x9d\x5f\x98\x20\x09\x28\x8a\xd4\x63\x0f\xd0\x05\x48\xf3\xb7\x9f\x84\xc6\x83\xc3\x9e\xe1\x98\x95\x85\xbf\xa4\x6d\xf6\x0e\xf9\x4c\x6b\x17\x92\x88\x24\x9d\x33\x2f\x3a\x52\x41\x9e\x0f\xaa\x28\x90\xa6\x11\x6e\x19\x3f\xe0\xd8\x11\x71\x40\x24\x02\x85\x7b\x9c\xa5\xc2\x4b\x76\xf6\x2d\xa3\xf1\x43\x14\x32\x41\xdb\xcc\x02\xde\x36\x7a\x2f\x8a\x5f\xdd\x09\x24\xc7\xca\xf5\xc9\xd1\x3a\xde\x0f\x42\x7f\xf8\x30\x58\xb9\xb9\x2d\x26\xd3\x5b\x71\x7d\x98\x37\xb7\x54\x20\x83\x30\xb1\xac\x82\x3e\x77\xef\xef\x40\x8a\x00\x83\xfd\xfb\xf2\xe8\x94\x96\x26\xcf\x40\x25\x54\xf6\x96\xf5\xed\x1e\x6a\xe5\x9d\x66\xd5\x56\x15\x28\xa1\x62\xdd\x37\xf4\x86\x6e\xb6\x0a\x74\x20\x70\xbe\xef\xac\x8b\xe5\xdc\xa6\x05\x9a\x25\xd4\xee\x26\x4e\x3c\xbe\xfb\xb0\xb1\x53\xe1\x08\xcd\xe1\x2c\xaa\xe6\x1a\xf6\x47\x54\x60\x55\x2d\xaa\x42\xe8\xd2\x8a\x62\x0f\x8e\xa1\x7b\x89\x6a\x10\xd2\xdf\x9b\x1f\x0f\x1e\x02\xf0\x50\xc9\xe1\x06\x35\x7d\x6d\xe7\x2e\xd4\x04\x0a\x95\xbe\x2e\xb5\xde\x62\x73\xb5\xdf\xd4\xc1\x04\x06\x71\xb3\x9e\x9f\x53\x7e\x86\xd4\x04\x43\x08\xbe\x04\x7f\x88\x3f\x87\xd1\x14\x98\xc8\x02\xb0\x0b\x38\x3a\x41\xf9\x67\x4c\x33\xbb\xa5\xdd\x04\x41\x12\x7a\xa5\x58\x2c\x29\xdd\x82\xab\xc7\x01\xfc\xcc\x0a\x5d\xbe\x0d\xf7\x09\x13\xb0\x48\x3b\x15\xb5\x5d\x69\x9a\x37\x51\xc1\x1a\x0d\x8f\x54\x59\x7d\x10\x06\x9c\x8f\x3b\x4c\x20\x8c\xea\x5d\x5e\x26\xb4\xdf\x41\xd0\x65\xc2\x30\xf4\x2b\x4d\xcf\xc0\x30\x21\x89\x90\x39\x7a\x0f\xba\xef\x4a\x98\x90\x24\xe8\xd3\x7a\x2a\x35\x8c\xec\xd6\x94\x09\x13\x6e\xdd\xdb\x9f\x7e\xae\x9f\x9f\x6e\xf7\xdf\x9e\xd7\xbe\xbd\x60\x48\x10\x06\xd0\xd3\x54\xc6\x17\x4a\x42\x83\x71\xfb\xea\xf6\x71\x68\xea\xa5\x0c\x51\x04\x05\x50\x6e\xe0\xbd\xd7\xf2\x33\x04\x08\x96\x49\xef\xac\x01\x45\xe5\x17\x17\x43\x89\x06\xda\xd5\xcb\x06\x1c\xbd\xba\x1b\x41\x03\x2c\x67\x78\xa9\x12\x8b\xca\x1d\x5f\x0d\x4d\xa8\xc7\x7f\xdd\x96\x55\x73\x29\xc6\x61\x83\x69\xb7\x81\x76\x26\x2d\xec\x7e\x38\xdc\x32\xc7\xeb\xae\x61\x94\x31\xbb\xb4\x1c\x45\x5e\xbe\xfc\xd6\xfd\x3b\xc5\xa2\xf5\x01\xbd\xc2\xb6\x65\x99\x4f\x5e\x4b\xc3\x04\x49\x9d\x60\xea\xb7\xf2\x52\xc3\x5a\x77\xd1\x89\x69\x17\xec\xb4\x8f\xaa\x70\x32\xf5\xb4\x18\x13\x11\x83\x8f\x4c\x5e\xae\xcb\x4b\xfe\x6b\x5b\xc1\x29\xbb\x9c\xda\x67\xfe\x11\xcb\x33\xfe\xd2\x48\xda\x8e\xfb\x29\xcb\x73\xb4\x28\xe9\x40\x29\x26\x0e\xad\xed\xf5\x41\x89\xe2\x53\xb9\xbb\xcf\xf0\x9f\x1f\x7a\x68\x26\x66\x89\x4f\x28\x2c\xf6\x73\xd7\xae\xba\x1f\x35\xb9\x4c\x12\x2b\x9c\xc1\xcd\x4b\x56\xe9\x9b\xac\xc6\xba\xfa\x30\x41\x32\x09\x0f\x93\x4e\xb5\x0c\xf4\x98\x78\x67\x78\x48\xd0\xc6\xaa\xcd\x06\x11\x1d\xb9\x83\x2e\x21\x31\x5c\x06\x08\xef\x5e\xe6\xd9\x79\x46\xf3\xdf\x8f\xd2\x0a\xd9\xa9\x1d\xa3\xe9\xa9\x9a\x44\x48\x26\x0d\x03\x62\xfd\x88\x1d\x04\xe4\xdc\xd7\xa4\x4c\x4a\xa3\xd4\xe1\xf5\xb7\x22\xd3\xe8\xe8\x34\xfa\x82\x34\x52\x96\x83\xd9\x4e\xc5\x17\xac\x4d\x6c\xea\xd1\x5b\x90\xc6\x11\xfe\xe2\xb5\x30\xd0\x63\x76\x16\xb9\x6f\x5b\x19\xc9\x2c\x89\xb1\xb2\x22\x1b\xa5\xc9\x3e\xa9\x82\x1b\xc5\x34\x9a\xcd\x79\x36\xe8\xcd\xf7\xe7\x81\x05\xbf\x32\x3a\x12\x28\x61\x71\x6e\x5f\x8e\xa7\x62\xa4\xce\x62\xb4\x56\x46\x0e\xe5\x35\xb1\x84\xda\xd9\x07\x8f\xbf\x09\x28\xa0\x7a\x87\x06\x99\x35\x13\xc5\xb5\xc9\x45\x01\xb3\x2e\x50\x16\x8c\xf0\x9a\x69\xa8\xda\xc9\xf7\x2d\x6b\x93\xed\xeb\x6c\xd8\xe8\x57\x2e\x88\xac\x12\xc6\x72\x71\x3b\xd2\xdc\x30\x10\xa5\xc2\x72\xeb\x4f\x58\xf1\x1b\x3c\xb7\xd3\xe8\x52\xc6\x3f\x25\xc4\x04\xdf\x01\x9f\x96\x3c\x97\x39\xfc\x36\xc7\x9b\x33\x20\x62\x04\x78\x23\x03\xb5\xde\x42\x75\x23\xba\x85\xb0\xdd\x26\x9c\x0e\xe9\xee\x2c\x8a\x5f\xdb\x32\x2b\x3e\x53\x4f\x32\x26\xd2\x49\x34\x60\xa0\xba\xc0\x75\x5a\x7e\x32\x26\x16\x08\x30\x5d\xe4\xcd\x4c\xd6\x61\x4c\x62\x7f\x39\xdb\xaf\x70\xc5\xfb\x76\x85\x74\x2f\x83\x0e\x02\x1a\xe0\xab\xd2\x74\x7a\xc3\xc3\xc0\x5b\x07\xa1\xe3\xcc\x6e\x4b\x3f\x7b\x75\xe0\x0b\x17\x48\xa0\xb2\xd5\x5c\x27\x62\xe4\x07\x50\x16\xf4\x5e\x20\x18\xea\x9f\x40\x67\xa2\x1a\xb7\x6b\x74\x40\x98\xe5\x19\xe2\xe4\x79\xcf\x4e\x97\xd3\xb2\x5d\xdc\x4e\xfd\x99\x04\xc7\xd9\x85\x8c\xa9\x5b\xf1\x0b\x3e\x02\x43\x75\xc0\x12\x6b\x25\x78\x2a\x8b\x36\xc2\xdc\xe8\x7d\xf9\x98\xa9\x5f\x85\x98\xf8\xd5\xeb\x36\x93\x32\xf1\xc0\xdd\xb3\x9e\x5c\x4f\x14\x1b\x8c\x7c\x54\x59\xe6\x37\xe5\x5b\xe1\x2f\x23\x4a\x38\x56\x88\x90\x34\x7d\xff\xb4\xfa\x1d\x9b\xe8\xdd\x51\x61\x01\x74\xff\x79\xa9\x9b\x4c\xd9\x4b\xfc\x41\xfc\xd1\x38\xb0\x73\x42\xd8\x65\x60\x30\x21\x75\x10\x53\x6a\x63\x0c\xd4\xcd\x05\xed\x21\xe5\xab\xb2\x2a\xa0\x42\x7c\xa0\xad\x2f\xf5\x6e\xf3\x3a\x48\x24\xc1\x68\x19\x5d\xd6\x7c\xc0\xcb\xdd\x41\x0e\x16\x4d\x86\xcf\xdb\xc6\xe1\x43\xd3\x6f\x37\x4a\xb8\x46\xfa\x29\x2b\xc6\x33\xbf\x3b\x9e\xa2\xec\xa2\xd0\xfa\x13\x59\x72\x3f\x30\xd2\x08\x65\x6a\x07\x42\xe5\xc9\x98\x93\x93\xe9\x90\x59\x37\xe1\xed\xe1\xfb\xee\xc6\xdf\x86\x24\x02\x77\xcc\xc7\xef\x0f\x87\xfd\xe6\xde\x73\x12\x75\xa0\x28\x47\x9d\x1a\xbc\xfa\x34\x9d\x4d\x5f\x74\xa0\x22\xcb\x39\xaf\x40\xc3\x09\x7b\x3c\x16\xb6\x36\xf9\x72\x15\xa7\xd8\xb8\x5a\xb7\x93\x70\xf7\x26\xce\x1f\x56\x8e\x36\x86\x9c\x9e\x5b\xa8\xd4\x57\xdd\xad\x2a\x9c\x0d\xc3\x3e\x2d\x3c\xe9\x40\x87\x36\x92\x3c\x57\xa5\x82\xba\xfe\xab\xee\xcf\x60\xe7\xd3\x81\xa6\xd6\xa8\xb7\xdb\xf9\x16\x53\x31\x20\x1d\x68\x1e\x08\x2f\x43\x60\xeb\x6d\xc3\x46\x81\x0e\x34\x58\xe3\xa6\x23\x34\x3f\xcb\xea\x17\x54\x73\x42\xc5\x3a\x00\x6e\x8b\xa1\x0f\xff\x58\x3b\xbc\xa2\x0e\x49\x9c\x60\x86\xe4\x85\xad\xbb\xf0\x7a\xfa\x30\x43\x92\x84\x18\x4a\x39\x9d\x1d\xd7\x67\x9e\x0e\x4a\x19\x56\x3a\x4e\xe2\xdd\xa9\x05\x20\x31\x0f\xfc\xce\xd4\x8e\xb0\x12\x04\x08\x90\xec\xba\x7b\x3a\x24\x32\x4e\xad\x7f\xbe\x14\xc5\x07\x44\xbf\x0e\x89\xb1\x1d\x7a\x70\xa2\x77\x95\xff\x20\x0d\xac\xe9\x0e\x76\x2e\x51\x4a\x3f\x9b\x5e\x3a\x0d\x00\x2d\xfe\x0e\xca\x66\x48\xb7\xf0\x35\x7f\x4a\x87\x94\x59\xdb\x12\xd7\xeb\xb5\x63\xfa\xbe\xd6\x07\xd3\x56\x1d\xd2\x28\x48\x6c\xde\x84\x09\xdd\xed\xd4\xac\x43\x87\x94\x5b\x61\x23\xc7\x65\x6d\x63\xb4\xf9\x17\x2b\xa4\x22\xc2\xba\xf1\xb6\x82\xb3\xc8\x5c\x43\xdf\x81\x92\x91\xd1\xf5\x29\x02\x67\x72\x1e\x15\x21\x66\x43\xfe\xc8\x34\x94\xbd\x84\xa9\x0e\x69\x7b\x8b\x18\xf5\xca\x3c\x53\xbe\x32\x52\x0c\x3b\xef\x3a\x64\x01\x43\xfe\xae\xf5\xfd\x46\x8b\x9f\xcd\xf2\xfb\xfe\xe9\x79\x4e\x3a\x42\x87\x4c\x59\xc1\x59\xac\xd3\xa2\x28\xd2\x33\xd4\xe5\xa5\x52\xdd\x86\x13\x32\xa0\x48\xe1\xf6\x22\x0c\xab\x97\x32\x1b\x1c\x8e\x62\x86\x1c\x7d\x9c\x1b\x0f\xeb\xc5\x83\x5b\x52\x66\xf7\xfb\xc9\xbd\x46\x3a\x41\x54\xd9\x01\xac\xa7\x9a\x1b\x3a\x1a\x13\xd3\x18\x4b\x50\x65\x81\x06\x74\x5f\xd5\x68\x75\x18\x6b\xcd\x9c\x08\xdc\xe9\x52\x64\xcd\xf5\x3b\x2e\xc6\x3e\x5a\xd4\x61\x02\xd6\x30\xe0\xfe\xfb\x8f\xcd\xe8\xb9\x25\x26\x41\x98\x5f\xdd\x08\xff\x2f\x4e\xa4\x51\x9e\x68\x94\xd5\xa5\x46\xf9\x96\xc1\xbb\xfc\xf9\x8f\x98\x26\x11\x4e\x9b\xa3\x38\xc1\xa0\x57\xae\xc3\x34\xb5\xb6\x6e\x3f\xd7\x9b\xc3\x6a\xb1\xed\xfe\xad\x34\x56\xb1\x6e\xba\x3d\x2a\x14\x01\xc7\x56\xcb\xc3\xe6\x71\x68\x8c\xa3\x43\x91\x5a\xf4\xee\x9e\xaf\xe6\xde\x66\x99\x52\x64\xbf\xbb\x50\xda\xaf\x6b\x43\x01\x30\x1d\x4a\x45\xac\x37\xc1\xfb\x19\xaa\x66\x22\xf5\xa4\x43\xa9\x43\x84\xfb\x9f\xad\xef\x39\x39\xe4\x17\xf5\xeb\x2a\x2f\x57\x84\x68\xf4\xaf\xb1\x34\x80\x51\xf1\x12\x0a\x30\x19\xc6\x29\xa3\x87\xaa\x98\xb5\xbf\x5d\xef\xbf\x7d\xdf\xdd\x6c\x9f\x37\xab\xee\xf6\x54\x64\xf0\x75\x59\xeb\xac\x79\x28\x75\xb7\xa4\x80\x4e\x50\x85\xf2\x24\xde\xef\x2e\x02\xdd\xa5\x40\x0f\xe2\x57\x1d\x1a\xae\x10\xfd\x56\x76\x70\x41\x27\x0f\xae\x43\x93\xda\x06\xde\xbd\xa8\x1d\xd6\x67\x9c\x28\x4f\x7e\x25\x63\x42\xee\x74\x3c\xdd\xa6\xe9\x9b\x1d\xfd\x3e\x41\x82\x44\x63\x2f\x21\xb3\x76\xfe\x93\x80\x88\x04\xce\xb4\xa7\x86\xe6\x5e\x54\xa8\xdd\xd4\x2d\xc7\x1d\xcf\x6c\x10\x36\x7e\xc0\x93\x6b\x12\x68\x86\xdd\xa1\xe5\x7a\x7f\xd8\xff\x63\xbb\xfe\xb6\xd8\x7d\x73\x37\x4b\x42\x41\x1c\x76\xa4\xc0\x66\x58\xbb\x65\x6e\xfc\xef\x44\x88\x4c\x95\x9d\x36\xbb\xb1\xb8\x8a\x26\x44\x87\xd8\x8b\x6a\xa7\x7f\x0f\x67\xd5\x84\x06\xa1\x52\x9d\x3d\xee\xec\x9e\x43\x28\x57\xdc\x65\xf9\x0e\x1c\x31\x09\x63\x35\xa1\x42\x20\x97\xcf\x94\x15\x64\xc7\x62\x79\xf9\x40\xa8\x1a\x3f\x6b\xc2\x88\x94\x36\x40\xf9\xd7\xa5\x6e\x06\x2e\xef\xc8\xdd\x3f\xdb\xd0\xda\x8d\x8d\x68\x8c\x81\x86\x05\x76\xd9\x3a\xde\xa2\x69\xda\xa8\xe1\x63\x7a\xa9\x49\xa4\x54\x3a\x84\x28\x7f\x21\x0e\xa1\x49\xcc\x35\x32\x23\xcf\xe2\xba\x39\x59\x25\x81\xa5\x28\x7e\xdd\x96\xd5\x5d\x59\x6a\xdf\xcb\x72\x83\x13\x11\x21\x97\xab\xda\xac\x9e\x66\x53\x0d\x4d\xb8\x12\x81\x73\x91\xf0\x82\x30\xfe\xa7\xf8\x08\x30\xfa\x04\x70\xd4\x33\xf4\xdd\x49\x53\x4e\x62\x4b\x59\x1e\x6c\xed\xce\xa0\x77\x72\xf3\x22\x8c\xb1\xcc\x71\xba\x22\xc5\x6a\x50\x7d\xd2\x44\xd0\x00\xe9\x8f\x5e\x00\xd6\x79\xeb\x80\xc6\xd2\x77\x37\x2a\x4d\x11\x22\x75\xf7\xe3\x09\xa3\xb2\x6d\x55\x1e\x2b\xf1\x51\x79\x60\xfc\xbd\x32\xb4\xe2\x99\x3f\x17\x1b\xdc\x55\x06\xe1\x35\x51\x24\xc5\x16\x3b\xfe\x0e\xe8\xc0\xec\xa9\xf8\x6e\x40\x1b\xaf\x6a\x3f\xe0\xd0\x4c\x2d\xff\x35\xd1\x34\xc2\xd9\x62\x1b\xcc\xa2\x6a\x8a\x41\x63\x69\x7e\xfb\x27\x5a\xf2\x10\xc1\x08\x79\x05\x42\x0f\x7c\x6f\x35\x81\x54\x63\x7a\xb3\x7b\x29\xdf\xdc\x43\xc0\x0c\x7e\x7c\x4b\x00\x1c\x6b\x04\x77\xd0\xdc\x97\xa2\x18\xb9\x36\x0f\x16\x04\x30\x80\x25\x51\x17\x97\x3c\xbd\x81\xee\x80\x28\xee\x0b\x69\x10\x05\x58\xfe\x6d\x3f\x8e\x15\x8b\xf9\xa0\x81\x06\x89\xe5\x00\xf7\xc6\x53\xae\x76\x3b\xba\x32\x1a\xc8\x18\xb5\x0f\xe4\x54\x3d\x6e\x3c\x6f\x68\xc8\xac\xa9\x3a\xca\x1a\x3c\x6c\x76\xfb\x2f\x64\x8c\x35\x0d\xb9\x75\xe7\x6b\x44\x9e\x5f\x7f\x7c\x50\xfb\xd5\x94\x88\x30\xb4\x6a\x7e\xd6\xbb\xb2\xde\xe8\x0f\x43\xc0\xb6\x95\x5e\x2e\x55\x66\xae\xa7\xec\xf3\x30\xc7\x7d\x80\x86\x0c\xd9\x85\x16\xfc\xe4\xcb\x94\x9a\x52\x88\xb1\x8d\xf5\x22\xea\x9b\xac\x3e\x5f\x1a\xd8\x95\xf9\xeb\xa4\x11\xac\x29\x0b\xed\x32\x62\xb2\x42\xef\x2e\xb2\x56\x55\x26\xa1\xb2\x5a\xdd\xe3\x67\xc6\xe2\x08\x69\x95\x6f\x90\x29\x8f\x5b\xd5\x94\x69\x85\xa8\x97\xc5\xb7\xdd\x7c\x27\xb2\x7b\x96\x11\x17\x28\x2d\xe9\x0b\xe2\xb3\xaf\x01\x8d\x63\x8a\x24\xad\xea\x52\x6c\xa1\x8f\xe1\xfd\x51\xad\x79\x32\x40\x03\xfb\xcd\x18\xf5\xc0\x26\x77\x96\x80\x42\x75\xfc\xc3\xc1\xaf\xf5\x58\x97\xb1\x88\xdf\xc3\xa1\xdb\x3f\x58\xbf\x81\x38\x9a\xbf\xa6\x3c\x10\x81\x8d\x63\x5f\x41\xe4\xcb\xec\xa3\x1b\xe4\xf8\xde\x38\x09\x1c\x83\xc7\xf6\xa8\x7b\x35\x70\x4d\x39\x0d\x20\x1a\xc7\xc4\x1d\x9b\x71\xfe\x19\xf0\x44\x63\x57\x24\x2f\xd5\xaf\x69\x89\x68\xf6\x55\xa5\xdc\xc4\xa8\x94\xd0\xe6\xd0\xfb\xea\x02\x79\xf9\xda\x51\x1a\x67\xa7\x6a\x1a\x46\xe0\x9d\x66\x6f\xe9\xe4\xc9\xa5\x84\x62\xd0\xb7\x59\x3d\x1d\x96\x4f\x8f\xdf\x77\xe1\xe1\x79\xe1\x21\xf1\xed\x61\x60\xae\x2e\xb5\xbb\xc8\x7f\x81\x6a\x3e\x48\xeb\x6b\x9a\x46\x14\x59\x28\x0a\xe1\xec\xce\x4b\xce\x1f\x4b\x15\x46\x54\x76\x3b\xea\x7b\x19\x1f\x6b\xf0\x9a\xa6\xa0\x83\x01\x48\xc0\xab\x1b\x0f\x81\xcb\x9a\xa6\x26\xa2\x43\x88\x05\x0a\xbd\xb4\x67\x61\x41\x37\x42\x24\xae\xb4\xea\x76\x95\x0c\xaa\x85\xdd\xc8\xc7\x17\x2e\x82\x50\x86\x5e\x7e\xb1\x38\xba\xd2\x25\xfa\x58\x4d\xf6\x6c\x2a\x88\xc1\xaa\x79\x8e\xd1\x11\xaa\xf2\x4c\x05\xa8\xdd\x48\xd9\x3e\x6f\x47\xc0\x47\xe0\x4e\xd7\x11\xd2\x54\x6a\x89\x15\xaa\xdf\x33\xf5\x4b\x65\xcd\x75\x18\xf0\x51\xa5\x39\x83\xae\x19\xbd\x28\xae\x48\xe0\xc6\x84\x7d\x74\xd5\x0a\xc0\xa0\xa2\x4f\x05\xf0\xe7\xd8\x13\x75\x32\x55\x94\x09\xec\xb3\xc2\x7c\x8a\xc0\xd0\x4c\xb0\x1b\x22\x31\x52\x7e\x84\xf7\xa6\x63\x2b\xfb\x1f\x44\x07\x29\xf6\xb7\xb3\x1a\x69\x34\xbf\x8d\xa6\x95\x0e\x99\x19\xe1\xb1\xfd\x0b\xfa\x97\xc9\x26\x85\x24\xc6\xc7\xd0\xa6\x04\x3b\x70\x40\x6c\xff\x18\x40\x05\xde\x2f\xf8\x19\xce\xb9\x50\x5f\xa8\x9c\x69\x0a\xc6\x50\x47\x06\xdd\xac\x9e\x76\x67\x50\x7f\x5b\xc7\xe2\x7f\xf9\xd7\x7d\xa1\x09\xac\xad\x8a\x04\x55\x9e\xe0\x19\x8a\xbe\x70\x46\xbd\xd8\x38\x56\x2d\xd0\xe7\x75\x28\xa6\x3b\x7f\x42\x16\x80\xf6\x74\xd6\x9d\x28\x1e\xc4\xfb\x6d\x35\xb1\xde\xd3\x2c\x30\x01\xde\xe5\xae\x7c\xcd\xa0\xe9\x21\x08\x9a\x85\x4c\x21\x3b\xed\x47\xa6\x9a\xec\xd4\xfd\xd7\x00\x96\x8b\xf2\xf2\xd8\xc5\xfe\x8c\x44\x3c\x24\x9d\xd5\x4c\xd1\x54\xd7\x61\x76\xc5\x08\x27\x01\x1b\x5b\x40\x0d\x62\xdf\xf6\x30\xae\x22\x6e\xa5\xd9\xd4\xeb\xd3\xb9\xb9\x8e\xeb\xa7\x8c\xc8\xc0\xdb\x48\x21\x47\xb9\x3c\x4e\x60\xae\x9a\x11\x95\x00\x1b\x60\x78\x37\x9d\xda\xe2\x4f\xc8\xe6\xca\x73\x8c\xa8\x34\xb2\x8a\x42\xc8\x98\x87\xa1\xa2\x87\x66\xc4\xa8\xd8\x36\x15\x8b\xc0\xd5\xfd\xdd\x11\x9a\x04\xde\x5a\x67\xe3\x32\xd9\xa1\xcf\xcf\xe4\x5b\x68\x22\x90\x92\xbe\xdf\xae\x46\xe7\x67\xed\x7a\xf2\x7f\xfe\xbf\xff\xf3\x47\x76\x3e\x43\x85\x0b\x4a\x9d\x1d\x6f\x85\xc2\xc2\xfc\xf8\x1c\x8c\xd9\x7e\x7d\x56\xbb\x40\x69\x44\xfe\xd4\x8c\x25\x29\x06\xfe\xb7\xf7\xab\xb1\x89\xa1\x66\xcc\x84\x48\x2a\xc3\xa6\xf5\xc8\x18\xc0\x0d\x88\x58\x8a\xb5\xe1\xbb\x9b\x95\x05\xc2\x87\xfe\xa3\x11\x27\x22\xf4\xc2\xf2\xcd\xea\xa5\x4d\x56\xdb\x69\x37\xbb\x35\xb3\x38\x04\x1d\x0e\x64\x4a\x07\xcb\x13\x8b\x59\x82\x26\xc5\x25\xc6\xb2\x61\x50\x5f\x4f\xb2\xf4\x85\x2c\x96\x30\x8e\xdb\xf5\x29\x2b\xa6\xf3\x33\x71\xf8\xcb\x87\xc5\x76\xdf\x0d\x8f\x23\x4b\xe7\x75\x5f\x74\x90\x97\xeb\x01\x46\x0e\x0e\x9a\x25\x02\xb8\x17\x11\x16\x55\x73\x5d\x4e\x9e\x68\xa2\x20\xb2\x8a\x57\xf0\x51\xa0\xa6\x8f\x2b\x59\x62\x00\x29\xf2\xbb\xbe\x83\x74\xb3\x9c\x5c\x24\x0f\x8c\x10\x9d\x1a\x0f\xa2\xf9\xe7\x23\x4b\xc6\x63\x16\xb8\xf6\xe7\xfa\x24\x45\x5d\x4f\x7f\xe8\x94\x48\xc4\x8e\xfb\x4d\x68\x62\xed\xe5\x47\x51\x43\x98\x4d\xc7\x3b\x61\x6b\x54\xd0\xf5\x77\x9f\xb2\x08\x0b\xcf\xca\xa9\xf7\xc2\x7a\xf2\x78\x44\x1a\xa2\xb6\x80\x14\x59\x5e\x5e\xba\x99\x2d\x84\x95\x85\xef\xb4\x9d\x6f\xa0\x11\x59\xde\xd5\x80\xa6\x0f\x6a\x7c\xf1\xc2\xd0\xd8\x69\x0d\x3c\x64\x9f\xf0\x66\x34\x93\xa1\xe0\x8e\x63\x6b\x15\xb9\xab\x4b\x3d\x7d\x33\x25\x49\x39\x74\xbe\x60\x73\x9e\x42\x9a\x49\x4a\x02\xe2\x97\x95\x0b\xbe\x84\x5e\x68\x01\x4b\x65\xc3\xa4\x8b\x49\x11\x62\x20\x6b\x9f\xc2\x4d\xd6\xbe\xb5\x53\x23\x52\xcd\x14\x49\x70\x83\x7f\x58\x6c\x1e\xf7\xeb\xc7\xc5\xe3\x6a\x7d\xb8\x5d\xaf\x0f\xdb\xf5\xf3\x6a\xfd\xd8\x4d\xc0\x36\xcf\x72\x0a\x6b\x6d\x80\x3e\x2f\x2c\xa8\x19\x80\xcd\xc6\xf3\xf2\x58\x6e\xbb\xc0\x25\x0a\x42\xab\xf5\xab\x07\xea\x32\x5d\xad\x67\x12\xc9\x47\x81\x8e\x0c\xf1\x3d\x22\x17\xf4\x3a\x4f\x4d\xdf\x19\x89\x42\x23\x34\x52\xba\xb2\xa6\x29\xff\xfd\x97\xac\x5a\x1d\x11\x11\xf9\xf5\x7a\x57\x9a\xa6\x23\x90\xe9\x88\xc6\x2a\x70\xb6\xa3\xed\x37\x21\xc8\xc8\x9a\x2b\x0c\xb7\xef\x88\xc6\x06\x67\x8f\x2f\x75\x3f\x8a\x13\xac\xdf\x87\x20\x35\x1c\x03\xd6\x6e\xb7\x5b\x38\x23\xaa\x28\x2a\x5b\x35\xac\x41\x0f\x3c\xbf\x7e\x45\x2c\x11\x08\xcf\x7c\xc3\x9a\x7b\xf7\x5f\xad\x52\xdb\xfb\x7d\x2c\x8b\x4f\x04\x6a\x74\x14\x89\x14\x5f\x86\xdf\x2f\xba\xac\x9f\xcb\x4b\xd3\x9f\x20\x0e\x13\x0b\xab\x6a\xe3\x13\xac\x10\xee\xa0\x79\x84\xa6\xfd\x9a\x6e\x0c\x51\x18\x32\xd8\xa0\x67\x5b\x95\x2f\x99\xcc\xfa\xda\x64\x14\x8b\x10\xbb\xba\xcb\xac\x31\x97\x6a\x14\x58\x45\x3c\xb6\x0f\xf2\xd0\x9e\x7c\x7e\xba\x47\x3c\x55\x11\x9a\x3d\x5c\x90\x79\xb1\xb9\x99\xa8\x8c\xeb\x88\x03\x43\x96\xd2\xf9\x52\xbf\xf8\x9c\xb5\xa3\xdf\xf6\x05\xf3\xc9\x3b\xe7\x17\x83\x28\x4d\x24\xd1\x1d\x69\xc3\x16\xb8\x87\xea\x91\x3a\x6a\x13\x46\x3a\x0c\xa8\x7c\x93\xf0\x52\x15\xf3\xbc\xe1\xc9\x3d\x08\x42\x10\x81\x03\xcd\xcb\x20\x44\x88\x84\x0e\xbd\x4c\xcc\xa2\x28\x2e\x22\x47\xd7\xb4\xda\x11\xeb\xdd\x20\x19\x04\x3c\xec\x5c\x1b\xe7\x5f\x95\x48\x06\x1c\xa1\x49\x5e\xc9\x64\x00\x2f\xf9\x52\x80\x50\x47\x92\x52\x84\x3b\xb4\x49\xee\x37\xa8\xca\x45\x5d\xc3\x7c\x2f\x5c\x47\x32\x0e\x7a\xad\xa6\x49\x67\xc9\x0f\xe1\x11\x86\xc0\x4e\x59\x36\x3b\xbe\x34\x2f\xe5\xa5\xfe\x18\x6a\x8d\x5e\x28\x15\x24\xb8\x01\xac\x50\xfe\x6c\xd7\x85\x4b\x91\x8e\x08\x36\x2d\x6f\x21\x93\x90\x4d\xaa\x81\x91\x86\x58\x8a\x0e\xb5\xfd\x52\x01\x8c\xea\x2d\x11\x44\x5c\xb0\x01\xa0\xc6\xb5\x2f\xc6\xaf\x0e\xa4\x82\x78\x32\xa8\xeb\xdb\x20\xdb\xeb\x52\x64\xcd\x14\x39\xa0\x23\x50\x96\x15\x56\xc0\x7b\xb3\xb0\xdd\x52\xb0\x79\xba\x1b\x60\x28\x41\x19\xe3\xfa\x72\x3e\x97\x55\x53\x8f\xe6\xbb\x51\xd4\xf6\x60\x71\xd2\x3c\x99\x61\x0b\x3c\x0e\x03\x8b\xde\xce\x0a\x3d\x82\xab\xe9\x38\x8c\x68\x62\xf7\x05\x55\x41\xb3\xb3\x8a\xfc\xee\x18\x09\x08\x16\xab\xcf\xa5\xed\x81\x7f\x46\x32\xf6\xc3\x09\xa7\x8e\x49\x7d\x2f\xba\x26\x4c\x4c\x58\x8a\xfb\xea\x48\xe0\xed\xcb\x92\x47\x4c\xb8\x62\x0e\xd0\x88\xcc\xf0\xb1\xdc\xf6\x78\x7e\xc6\x44\xa4\xb8\x3e\x3d\x64\x85\x1e\xbc\x01\x31\x31\x1c\xc3\xe7\x43\x2f\xf5\xe9\xdc\x45\xf6\xbd\x2f\xd4\xe4\x5c\x51\x24\xb0\x4d\xa9\xa5\x3f\x4b\x24\x3b\x1f\xad\x1f\xd9\x79\x58\xe1\x72\x03\x62\x61\xa1\xcb\xed\xc4\x6d\xde\xcb\x2a\x3b\xf6\x97\x10\x6b\x86\x56\xc9\x8b\xaa\xd9\x97\x97\x7f\x95\x97\x6a\x20\x5a\xf3\x97\x29\xc8\xf8\xd2\x92\x44\x23\x2f\xd5\x39\x90\x7c\x5d\x6c\x8c\x79\xc0\xd0\x8f\xd5\xc7\x2a\x76\x76\x22\xf7\x5f\x0c\x8b\xfc\xb3\x2f\x63\xcc\x09\x27\x66\xae\xa2\x31\x18\x92\x46\x08\x34\x3f\x9d\xee\x33\x39\x42\x1f\xe9\x58\x10\x5b\x7c\x6b\xaa\xeb\xd3\x19\x8a\xe7\xb2\xfc\x48\x68\x98\xff\xe1\x45\xa2\x2d\x7f\xca\x61\x3c\xc7\xc0\x67\xbf\xac\xc6\x82\x3b\x35\xb8\x7a\x75\x69\x32\x58\x95\x5d\x83\x35\x16\x82\xb8\x64\xc4\x96\x84\xfc\x1e\x39\x07\x03\xd5\xb1\x00\xed\x73\xb7\xa1\xcb\x81\x8e\x25\xd5\xd8\x6c\x59\x56\xe2\xb5\x3b\xb7\x54\x01\xeb\x44\x62\xb6\xee\xa1\x3a\xa0\xba\x1b\xa2\x28\xb3\xea\xf4\xeb\xbb\xef\xf7\x8b\x67\xec\x4e\x1c\x56\xbd\x63\x40\x3b\x42\x62\x7a\x8d\x66\x5a\xa7\x73\x03\x07\x36\x4a\xb1\x63\x13\x71\x44\x40\x22\x24\xb3\xd3\x4a\x76\x22\x16\xc3\xa7\x95\x04\xda\x06\x4e\xfe\x5e\xa7\x35\x9a\x24\x24\x84\x58\xfd\xc0\x12\x95\xec\xf4\xc0\x4c\xe1\xd3\x12\xfb\x5f\xfd\x1d\xf6\x8f\x92\x50\xdb\x9f\xda\xd7\xeb\x6e\x20\x87\xe3\x00\x97\xa7\x13\x12\x10\x04\x71\x79\x22\xec\x50\xb8\x6f\xf5\x7c\xdf\x0d\x23\x8a\x29\x9f\x0a\xb9\xf7\x7d\xf4\x5b\x25\x24\xb5\x68\x88\x6e\xa7\xbc\x45\x95\xa5\x93\x28\xea\xbe\x2a\x9a\xd0\xc0\x5a\xf6\x16\x97\xd3\x93\x99\x90\xc5\x9f\x8a\xf5\x79\x39\x89\xea\x13\xca\x22\x54\xfe\x41\xa3\xef\xc3\xcf\xf5\xfa\xf7\x03\xf5\x27\x63\x34\x55\x0e\xbb\xb3\xbc\xd4\x59\x31\xd5\x89\xd1\x09\xe3\x01\x02\xed\x0e\xd8\x3c\x74\xd2\x4f\x3b\x5c\x4b\xbb\x93\x68\x2a\xdd\x62\xf6\x00\x8d\x68\x7f\x03\xbf\xd9\xcc\x4e\xca\x24\x62\x49\x18\xf5\x96\xbd\x23\x3a\x91\x4e\xa2\x28\xed\x4d\x70\xef\xca\x5c\x8f\xf6\xa5\x24\x8a\x53\xdc\x44\x50\xe4\xd6\x69\xdf\x1d\x56\xcf\x4f\x3f\x3d\x28\x25\x49\xa2\x08\xb1\x27\x90\x23\xd9\xe7\x65\x90\xef\x27\x9c\xc4\x08\x33\xc2\xa2\x5e\x75\x5a\x41\xe5\x54\x37\x26\xd1\x78\xc2\x89\xc2\xaa\x32\xbc\x83\xba\x34\x08\x38\xb7\xbc\x62\x7f\xdc\x68\x84\xc4\x3a\xa7\x82\xd9\x2c\x21\x49\x99\x15\x8a\xb1\x8f\x7e\x8d\x56\x83\x87\x36\x98\xf7\x38\x99\x24\xe5\x16\x4c\xed\x83\xd9\x7b\x51\xe8\xbd\xf8\x05\xe5\xeb\x47\xf2\xcd\x78\x29\x49\x52\xad\xa5\x0b\xa4\xb1\x52\x7f\x5b\x56\x9b\x06\x4e\xb8\x04\x96\x8d\xaf\x80\x7f\xb9\x1c\x25\x22\x89\x50\x16\xc3\xa3\x05\x0f\x3f\x36\xdb\xed\xfd\x62\xb5\x7e\xe8\x33\x8e\x44\xe8\x50\xf7\x6a\x84\x9d\x36\xf6\xb8\x38\xdb\x8d\x25\xc8\xb0\x39\x0a\x67\xdf\xb6\x85\x4a\xf5\xb8\xa7\x44\x72\x8d\x0b\xef\xcd\xcf\xe5\x7e\xa6\x83\xf6\xf7\xaa\x55\x89\x4c\xa5\x8e\xfc\xbb\xf4\x95\x4a\x8d\x4e\xa4\x88\xb8\xe3\xc2\xdc\x80\xca\xa6\x7a\x16\x3a\x91\x8a\xab\xb4\x83\x93\xd9\xe0\xf5\x03\xfe\x29\x51\x41\x98\xf6\x06\xfd\x2b\x51\x38\x89\xe1\x41\x5b\x38\x51\x09\xe3\x9d\x5f\x6a\x93\xbd\xc2\x6d\x2e\x8e\x43\x82\x8f\x4e\x74\x10\x60\x73\x47\xa3\x16\x55\x56\xd4\xbb\xac\x38\xe6\x33\x0a\xdd\x7e\x7c\x48\xc1\x6d\xce\xdf\x8b\xec\xdf\x17\xd8\xe8\x27\x63\xf1\x45\xcb\xab\xc3\x19\xb5\x41\x01\xd6\xbd\x36\x37\x93\x39\xac\x79\x82\x33\xe4\x5c\x95\xfa\x0b\x5a\x70\x3b\x50\xa0\x43\xf0\xc9\xe1\xee\x7b\xd9\x3a\x9d\xe8\x54\x8c\x5a\xa9\xab\x12\x29\xc7\xf5\x40\x89\xd8\x8f\x54\x46\xda\x3e\x6a\x55\xc3\x0f\x51\x6d\x3c\x73\x68\xf2\x6d\x40\x44\xdc\x61\xc3\x0e\xde\x7f\xda\x7f\x1f\xf0\x14\xe3\xb5\xaa\xcc\xf3\xa7\x09\x83\x91\xfb\x31\x2a\x76\xfc\xae\x5e\xad\xac\xfb\xbc\x02\x8b\x1b\xb6\x74\xa1\x1f\x80\x42\x49\x9f\xf7\xda\x13\xd0\x0a\x57\x23\x8b\xdf\xfb\xf2\x39\x01\x30\x80\x6e\x16\x58\xa9\xb2\x29\xab\xdd\x0e\xe5\x01\x03\x7c\xa4\x3f\x37\xfb\x6f\x37\xcf\x8b\x9f\x8b\xfb\xc3\xfe\x79\x73\x77\xb7\x7e\x1e\x19\xec\x68\x1e\x48\x83\xfa\xa9\x96\x8c\xda\xcb\x04\x69\x4e\x8c\x4d\x7c\xdc\x2d\xd8\x3a\xc3\xa4\xc0\xc7\x69\x68\x1b\x07\xc2\x39\x85\x6f\x7f\xec\x0f\x9b\xe2\x75\x7c\x1b\x1f\xef\x9a\x53\x63\xf0\xa5\xb6\xb9\xc6\x48\xce\x64\xb6\x41\xc4\x59\x20\x95\xf2\x36\xd8\x16\x71\xdb\xd1\x96\x34\x67\x54\xa8\x5e\x57\x41\xb8\x54\xb5\xc6\x5a\xe8\x9c\x00\x99\xe6\x2c\x16\x1e\x3e\xfd\xe0\xed\x30\x09\xef\xae\x8f\xc5\x16\x70\xd0\xb7\x41\x91\xca\x36\xea\x9a\x70\x26\x05\x46\xfd\xda\xd6\x25\xeb\x71\x98\xc6\xa3\x20\x40\x24\xe8\xa6\xc0\x52\x8e\xcc\xa1\x26\xcf\xdd\x83\x8f\x28\x60\x20\x65\x6c\x43\xa6\xfb\x77\x9b\x33\x77\x98\xe5\xd2\x3c\x19\xd4\x15\xb5\xab\xd9\xf7\x5e\xbf\x6b\x3e\x99\xe4\x91\xe4\x3a\xf0\x4b\xd3\xba\xd0\x4f\xa6\x2f\x5d\xba\x21\xb1\x64\x58\x71\x5c\x5e\x54\xb9\x87\x7a\x58\xf8\xe6\x89\x60\x28\xf1\x63\x1b\x4b\x9b\xe2\xd5\x46\xb3\xb3\xcb\x20\xe7\x44\x21\x56\x6a\xdd\xbc\x6c\xa1\xc8\xba\xfb\xe6\x22\xa6\xe9\x40\xf1\xc9\x96\x4f\x82\xee\xa8\x55\xbd\x43\x2f\xa4\xac\x59\x5e\x77\x79\xd9\xb8\xc8\xca\x87\x3d\x3c\x65\x9a\xb8\x2a\xf3\x3d\xbc\x42\x3e\x67\x7e\xdc\xae\x1a\x31\x86\x7a\x08\xcc\x5c\x17\x4d\xa6\x85\x86\x5a\x97\x85\x50\x19\xca\x62\x8e\x9f\x8d\x48\x69\x68\x3d\x08\x3b\x0d\x24\xd4\x75\xeb\x5e\x7e\x2e\x93\x00\x0b\xa3\x37\x9f\xe4\xea\x5c\xea\x84\xbb\xeb\xba\x9b\xbe\xfa\x5c\x85\x01\x52\xa7\x17\xff\xb9\x7a\x18\x1f\xa0\x20\xbc\x6b\xdc\x7b\xbb\x39\xfa\xca\xe2\x78\x8a\xab\x38\x44\x70\xc4\x7d\x79\xb4\x69\xdc\xbe\x03\x54\x7f\xb9\x15\x73\x25\x44\x02\x03\xa4\x77\xbd\x85\xea\x27\x64\x93\xa7\xa5\x53\xc0\x3d\xa4\x53\xe9\xb6\xc2\x27\xfe\x22\xb5\x52\x89\x70\x7d\x42\x57\x68\x9f\x9e\x00\x18\x86\x13\x97\x42\xb6\x9f\x9b\x4d\x52\x39\x84\xb6\x68\xf7\xbb\x17\x71\xf0\xe7\x37\x41\x80\x6d\x76\xdb\xc3\xa9\xbb\x7a\xc0\xfc\x83\x36\x60\xb0\xcc\x68\xf1\x5e\xf0\x33\xeb\xd3\xe6\x34\xe0\x02\x83\x28\xcb\x51\x6c\x60\x25\x3c\x99\x50\xa7\x41\x1a\x86\x81\xa7\x52\x2e\x3b\x32\x9d\x4e\x43\x42\x51\xf9\xf7\x94\xa1\x8f\x38\x54\xaf\x23\x0e\xe7\xc7\x25\x2a\x0d\xdb\x2c\xcd\xd6\x6a\x4f\x65\x01\x7f\x01\x27\x4a\x43\x15\x60\xc1\xae\x6e\x5f\xd7\x55\x79\x3a\x41\xdf\x76\x4f\x43\xcd\xb0\xb4\x82\x1c\xc9\x13\x14\xcd\x52\xd4\xbf\xa0\xa9\x1f\xb2\x62\x60\xef\x3a\x7e\x06\x29\x89\x02\x85\xc0\x04\xf1\x0b\x1e\xae\x43\x84\x4c\x4a\x63\x8e\x7a\xaa\xab\xb2\xa8\xa1\x40\x3e\x6b\x1b\xb1\x4f\xc5\x19\x3e\x15\x21\xd0\x29\xd5\x56\x40\x1c\x81\xa0\x96\x38\xb6\x28\x8e\xbd\x57\xec\x28\x0d\x49\x99\x33\x88\x42\xd4\xdd\xc1\xe2\x2e\xfd\xb5\x30\x05\x08\x52\x29\xcf\xd0\x8c\x30\x7d\x69\x94\x24\xc2\xbd\xea\xe8\x6d\xd1\x09\xd6\x22\xb9\xaa\x63\x95\xeb\x34\x12\x89\xe8\xa7\xe6\xbe\x7c\x06\x95\xc1\x44\x73\x44\xa7\x91\x4a\xe2\x8e\xc3\x07\xce\x20\x77\xb0\x1e\xa7\x31\xd3\x56\xa7\x77\xb9\x5c\x3d\x6d\x1e\xbf\x82\x9a\xa4\x31\x04\xd8\x99\x7a\x7b\x81\x02\x57\xd8\x95\x28\x96\x60\xd5\xf4\xbb\x05\x21\xe5\xb1\xf5\xa4\xc8\x54\xb9\x13\x39\xd4\xa3\x5c\x20\xe5\x22\x36\x3d\xbc\xd7\x1a\x6e\x7f\xea\x93\xf4\x77\x2a\x12\x7d\x34\x97\xa6\x41\x14\x39\x54\x9c\x55\x2f\xf9\xb2\x14\x98\xa6\x29\x03\x27\x43\xe4\x72\x81\x8e\xbe\x30\xba\xed\x34\x4d\xa2\xb8\x5f\x04\xac\xca\xaf\x3b\x26\x68\x88\x8a\x25\x26\x2b\xf4\xf2\x3a\xa5\xb5\xeb\x54\xf0\x10\xd5\x5b\x36\xb5\xcb\x31\xbd\xa8\xb3\x3f\x2e\x18\x99\x4a\x07\xf8\x63\x92\x26\xde\xcc\xdf\x56\x3b\xba\xff\x6b\xcf\xd8\x92\x23\xa4\x4a\x2a\xb9\x51\xc6\xa3\x46\x3f\x60\xe1\x07\x4f\x4a\x2a\xa1\xd8\x98\xe5\xd3\x79\xbf\xcc\xa3\x92\x52\x15\x4a\x63\x1d\x3e\xaf\xae\x79\xd9\xf4\x3e\x78\x23\x9f\x9a\x69\x82\x30\xa8\xf2\xa7\xc0\x02\x9c\xde\x36\x15\x5c\x3d\xaf\x17\xfb\xa7\xe7\xdd\x48\x0f\xbd\x1d\x04\x48\xec\xc0\xd7\x37\xf3\x48\xde\xd4\xc8\x10\xab\xf3\x08\x91\xeb\xfe\xa9\x00\x52\xbf\x35\x9e\xcb\x0a\x95\x6e\x51\x20\x2c\x6b\xfc\xa4\x13\x41\x62\x7c\x37\x78\x25\x2a\xbd\xbf\x9e\x61\x04\xe3\x17\x81\xb0\xcb\xf4\xb9\x2a\x4f\xe5\x70\x09\xfe\xff\x39\xfb\xb2\xe6\xc6\x71\x64\xeb\xbf\xd3\x0f\xf3\x40\x10\x04\x97\x47\x6d\x2e\x6b\xca\xb6\x34\x92\xaa\xaa\x7b\x6e\x4c\x28\xb0\x24\x6c\x8e\x29\x52\x43\x52\xb6\xd5\xbf\xfe\x0b\x26\x00\x6e\xa2\xdd\x1d\xdf\xc4\xbd\x55\xd5\x02\xb8\x63\xc9\xe5\xe4\x39\x9c\xd0\x04\xe3\x9b\xea\xe2\xa8\xe7\x1f\x5a\xe6\x04\xc5\x49\x18\x1a\x0a\xc5\x54\xd7\x4f\x77\x37\x64\xe0\xc3\x01\xc7\x89\xf0\x99\x05\x33\x59\x0a\x8c\x2e\x95\xc2\x09\x78\x58\xdd\x63\x54\x1f\x3b\xc0\xc6\x78\x0c\x77\x5f\x91\xfb\x94\xa0\xdd\x7d\xc6\x70\x4f\x5b\x83\xa6\xb8\xcf\xa4\xa9\x31\x2f\xd3\xc5\xe9\xa6\xf4\xc2\x75\x4a\x0c\xa7\x8f\xb1\x5b\xd0\x9c\xfc\x9b\xe1\x16\x77\x02\x11\xb4\xf6\x1e\x1f\x6d\x7c\x9c\x86\x09\x31\x7b\x87\xe5\xec\xef\x47\x8d\x39\x15\x21\xae\xa4\x45\xf3\x85\xef\xe8\xf2\xe8\x1a\x82\x48\x20\xe8\xb0\x7b\xfe\xc9\xb9\xcb\x19\xf1\x31\x4b\xbd\xf9\xfe\x38\x25\xf4\x7f\x9b\xc4\xe2\x8c\x84\x5e\x7f\x61\x5d\x5a\x38\xdc\x5a\xe1\x94\x6c\x86\x4d\x8d\x38\xd9\x16\xc7\xd3\xbb\x1a\x4b\x30\x8e\x5d\x5d\x73\x85\x91\x87\x6d\x09\x32\xed\x04\xd0\x14\x67\x2a\x90\xc6\x4e\xc2\x41\x9b\xf3\x4b\x5d\xad\x3e\xce\x59\x17\x05\xe4\x0c\x14\xfa\x9a\x2a\xad\x1a\x33\xbc\xd9\xcc\xd3\xfc\x52\x5c\xaa\x25\x64\xe9\x1b\x94\xed\x68\x8d\x02\x00\x93\x6a\xc6\x28\xc1\x1a\xb9\xf0\xfb\x99\x0d\x44\xe2\xe0\x1f\x83\x27\x8c\x24\xc3\xbc\xde\x83\xa1\x4e\x9a\xb7\x9c\x50\x83\xc2\x05\xdb\x39\xa6\x11\xa6\xdb\x9c\x8f\xb8\x6c\x4c\xc6\xe2\x7c\x9a\xe8\x19\x30\xa3\xb4\xff\xce\xcf\x36\x08\xe6\x5a\x78\x84\x7c\x72\xeb\xa7\xfb\xd5\x6e\x7d\x98\x3d\x2d\x56\x7f\x29\x4e\x68\x0f\x4d\x82\x10\xeb\x83\x9a\x7d\x7a\xa3\x35\xea\xa0\xbd\xa7\xed\xb4\xe6\x89\x14\x48\x3d\xf3\x90\x66\x69\xfd\x32\x49\xff\xdb\xff\xd4\xf6\x28\x6e\x47\xc5\x1e\xea\x6d\x51\x64\xae\x1c\xf7\x26\x71\xcb\x39\x4f\x70\x8f\x52\x45\xbf\xca\x5e\x71\xae\x00\x41\x2c\x87\x92\xbf\xc1\x98\xce\xba\x69\xd6\x3a\xc1\x08\x13\xda\x61\x8b\x87\x27\x5d\x16\x27\x53\x7f\xf9\xc8\xbb\x4c\x24\x17\x2c\x30\x3a\x39\x18\xa1\x40\x31\x87\xfc\xe3\x06\x73\xe6\x3a\x87\x14\xb7\xc4\xe3\x25\x3f\x73\xf9\xba\xae\xe1\xd4\x57\x43\x71\xbd\x44\x18\x75\x35\x2c\xc8\x82\x7a\x28\x9e\x8a\xf2\xc4\xb3\x87\x54\xb7\x2f\x4e\x46\xca\x4a\xe1\xe6\x80\xee\xde\x46\x8f\x4e\xa4\xc2\x50\x9b\x71\xf8\x76\x57\x94\x1d\x79\x82\xe2\x2a\xf1\xbc\xfe\x98\x78\xe4\x39\x12\x91\xfc\xd6\x2e\xed\xe3\x35\xde\x1e\x08\xdc\x54\x8f\x1c\x36\xbf\x9e\x8e\xeb\xa7\x66\x59\xdf\xaf\xfa\xf0\x3d\xae\x83\xc4\xb3\x5b\xf3\x1d\x2f\x4f\xed\xcf\x71\xe2\x19\x03\xfa\xad\x78\x05\x27\x81\xe9\x1a\x95\x44\x6c\x83\x83\x6a\xb4\x88\x79\xe1\x79\x81\x07\xad\x11\xf1\xab\x68\x9c\xc1\xa7\xa2\x76\x42\xed\xfd\x59\x21\xbc\x98\x63\x34\x74\x3f\x7b\x58\xb5\xc7\xc7\xc0\xc4\x04\x2b\x1e\x6e\xf0\xd6\xbe\x1c\x3c\xa1\x20\x09\xa0\xbb\xe0\x44\x84\x7f\x9b\x9e\x83\x82\x08\xa3\xbd\x3b\xc9\xaa\x7e\x68\x47\x92\x20\xd2\xc4\x79\xda\x27\x9b\x9c\x26\xc2\xf7\x62\xcc\xf8\x1d\xd2\x9a\xe7\xe9\x9f\xfd\x20\xb6\xf0\x05\x80\xee\xf4\x3b\x26\x2a\x34\x05\x0d\x22\x8e\x55\x24\x52\xc2\xb9\x07\xc8\x19\x3e\x1b\x95\x06\xb4\x2b\x2e\x36\x04\xf0\x2b\xad\x5f\x30\x47\xc1\xb3\x71\x57\x65\x68\xb5\x06\x02\xd6\x46\xb8\xda\xf5\x00\xd0\xb1\x8d\x3c\x3e\xf3\x1a\xc7\x7e\x67\x8c\xc5\x76\xa6\x8a\x00\x38\xae\x71\xc7\xba\x38\xf7\x98\xe6\x9a\x06\x8d\x0c\x20\x2f\x8d\x79\x81\xf1\xb6\xd1\x2d\x30\xdf\xa4\xef\x2b\xe4\x15\xb0\xc8\xc7\x0a\x93\x84\x9f\xf8\x57\x82\x51\x8e\xf1\xa5\x9f\x8d\xeb\xee\x2e\xc4\x12\x53\xa1\xf5\x0c\xb5\x2d\x6e\x46\x88\xf7\x6d\x36\x4d\x30\xc5\x7c\x3b\x5a\x30\xf3\x37\xa0\x59\xb2\x7d\x42\xa2\x7c\x07\x66\xe2\x25\x3c\x15\x0b\x5e\x4d\x31\x4b\x29\x11\x52\x13\x2c\xeb\xd8\x63\x31\x26\x38\xa8\x74\xb4\x5d\xa3\x48\x39\xe6\xcb\x47\xfe\xf1\xcf\xcb\xe9\x3c\xba\xb3\x98\x06\x08\x0d\x11\x46\xbb\x65\x0f\x79\xfd\x0b\xd2\x31\x60\x40\xc4\x52\x60\xbc\xf4\xbd\x28\x4d\xe0\xb1\x5d\xa8\x44\x12\x04\x88\xba\x45\xa1\x5a\x94\xd4\x9c\x43\x5b\xc2\x21\x12\xa1\xc1\xf1\xf1\x15\x15\xee\x46\x8b\x7e\xfa\xdf\x76\xe3\x9c\x84\x06\x88\x2c\x8b\x37\x23\x1e\xd5\xfc\x3d\x34\x95\x05\x97\x11\xe6\xd1\xd6\x4f\xeb\xc3\x7a\xf6\xd0\x5f\x1e\x84\x20\x49\x18\x38\xe8\x61\x06\x15\xde\xc9\xe8\x29\x04\x8d\x10\xee\x8c\x61\x9a\xe6\x1a\xfd\xa5\x59\x88\x66\x87\x75\xde\x22\xaf\x7a\x12\x0c\xbd\x5c\x82\x10\x8c\x60\xe1\xef\x3d\xaf\x5e\x74\x6b\x8e\x08\xa1\x14\xae\xc0\xf3\xcd\xdc\x54\x11\x0f\x23\x90\x7f\xc3\xf7\x10\x42\x4b\x19\xba\xdc\xfc\x00\xd1\x20\x24\x65\x76\x4d\xc0\xcc\x25\xaa\xd7\xda\x26\x25\x3c\xdc\x27\xaa\xf4\x39\xff\x71\xbe\x2b\xca\xed\xcf\xed\xe8\xe5\x2a\x25\x5b\x71\xa0\xa2\xc8\xd6\x2e\x67\x22\x80\x19\x7f\xd6\xc8\xae\x23\x43\x9b\x6d\xd1\x7e\x84\x71\x3f\x5d\xa0\xb6\xc5\xf0\x35\x6a\x11\x22\x7c\x6f\x5b\x82\x4a\x71\xbd\x34\xfb\xd7\xf0\xb2\xd2\x8b\xe3\x00\x6d\x4b\x1c\x9d\x8d\xd5\x5c\xdd\xf4\x90\xa8\xff\xf7\x8d\x9f\x9a\x25\x78\xda\x21\x97\x84\x52\x6e\x8a\x4e\x8b\xf3\xe1\xb9\x1f\x7c\x97\x84\x26\xcc\x14\x37\xa1\xbd\x32\xab\x6b\xde\x2c\x2b\xfb\xba\x0b\x65\x4b\x12\x27\xd0\xb9\x8b\x6e\xa1\xfe\xf5\xc2\xb3\xa1\xa3\x25\x49\x6c\x88\x6c\x30\xe9\xb7\x87\x5c\xf5\xc9\x90\x94\x24\x4a\x80\x31\xf0\xb1\x52\xfc\xb1\xd5\xdd\x52\xd2\x0f\x43\x93\x0b\x43\xd4\xe2\x2c\xaf\xde\xa1\x34\x2c\xb7\x7f\x8b\xda\x45\x49\x5f\x1a\xa9\xd6\x37\x28\xd3\x2d\xaf\xaa\xe1\x8d\x51\x12\x10\xd4\xf4\xe5\x99\xec\x4c\x74\x49\x05\x37\xa4\x9b\x18\xc2\xc6\xec\xcf\x63\x51\x82\x29\xe0\x98\xb4\x79\x25\xd5\x3e\x7e\x70\xa7\xef\x73\x3a\x15\xb9\xe3\xe1\x18\x7d\x9b\x80\xf8\x86\x5a\xa5\x84\x96\x03\xfe\xb7\xb6\xcd\x50\xc9\x58\x19\x0c\xf7\x2b\x05\x6e\xb1\x78\x87\x66\x02\x5d\x6e\xc9\x1e\x5c\xcf\x44\xf8\x5d\x28\x29\x43\x3e\x85\x1f\x79\x0b\xda\x92\x2c\x21\x06\x85\x25\x8b\x1e\xef\x97\x6b\x94\x61\xa2\x7b\xa0\xdb\xf6\xfe\x87\xa3\x86\x49\x63\x59\x2a\x57\x92\xe3\x92\x75\xae\x5d\x73\xcc\xc1\x3d\xae\x96\xeb\x19\x7a\x8f\x9b\xdd\xe1\xf8\x6b\xf6\xf0\xb0\x72\xc1\x62\x19\xb2\x00\x8b\x44\xbf\xad\x1e\xdb\x9f\xc2\xd0\x98\xb2\xed\xf8\x18\xf3\x59\x7f\xf2\x89\x43\xc1\x7c\xa3\xd0\xea\x80\x80\xb6\x21\xa2\x01\xa6\x35\xfa\x45\x00\xf3\xeb\x63\xd1\x6c\x8e\x9f\x17\xa1\x77\x73\x20\x92\x12\xe3\x72\x35\x94\x28\x14\x07\xb3\xac\x7d\xc8\x48\x51\x1c\x39\x2d\xff\xc5\x7b\x39\x4a\xa6\xcb\x18\x14\x8e\xfa\xf5\x62\x83\x42\x66\x28\x6a\x30\x9e\xa8\x09\x8b\x31\x23\x85\x00\x4a\x63\x8c\x8c\x7b\x24\x21\x26\xe7\x8c\x2b\x58\xdf\xf2\xaf\x4c\x85\x83\x24\xf7\x23\xdc\x56\xe7\x08\x40\x37\x94\x5d\x0b\x07\x20\x1d\xc6\x69\x25\x57\x86\x91\xcd\xc4\x50\xf6\x45\xa6\xf0\xf3\xbb\x47\x15\x1e\xd3\x49\x97\x15\x98\x17\xf9\xf8\x49\x85\x88\x1d\x19\xf0\x2c\xcb\x66\x17\x95\xd6\x45\x1b\xc2\x94\x32\x8e\x13\xc3\x68\x9a\x6b\x28\x31\x8a\xf8\x17\x61\xa4\xc1\x93\xa8\x40\x23\xa0\xe6\x11\x6a\xee\xd0\x40\x5f\xfa\xbe\x52\xc5\x4c\xc5\x8e\x4b\x38\x95\xb0\xd1\xb3\x73\x3a\x7e\xf1\x10\x10\x14\x24\x2b\xce\x98\x12\xe8\xd5\xce\x49\x00\xa3\x5c\xf1\xd2\xa9\x63\xba\x8c\xa3\xd4\x7e\x82\x05\x5b\x18\xc5\xb1\x49\xcb\xf6\x49\x75\x14\x50\x23\x2b\x82\xa5\x1f\x46\x41\xb7\xe8\x08\xee\xba\x48\x8c\x75\x82\x27\xef\x5f\x79\x9a\x38\x8e\x67\xe3\xd3\xb5\x31\x91\xf6\xf6\x15\xf1\x29\x16\x70\x22\xf3\x30\xe2\x99\x7b\x6c\x3f\x4a\x91\x24\xa0\x6d\xbe\x81\x6b\x7f\x7c\x34\xc4\xa4\xe5\x13\x9f\x5f\xae\x7d\xd9\xb8\xe1\xec\x52\x94\xc6\xd4\x1f\x0c\x8e\x59\xbd\x96\x85\xbb\x10\x0d\xb9\x07\x7d\xfb\xd4\x98\x92\xc3\x8d\x46\xd1\x48\x93\xa4\x13\xc5\xdb\xf1\x1a\x36\xda\xe6\xa1\xee\x79\xf6\xd6\xdb\xcf\xdd\x11\xc0\x90\xec\x05\x72\xd5\xec\x07\x4d\x87\x6e\x66\xaa\x80\x05\x88\xed\xd5\x69\x09\x9b\x7c\x3c\x2a\x46\x81\x6f\x15\x24\x61\xec\x19\xcf\x73\xf5\xc6\xb3\x8b\x43\x27\xd8\xae\x71\xdf\x4d\x55\x41\xc2\x85\x7d\x73\x53\xd9\x56\x15\x24\x4e\xd7\x05\x03\x03\x5f\xe5\x37\x15\x53\xba\xc5\xad\x6f\x36\x0f\x47\x50\x69\x7d\x24\xe1\x60\x0f\x52\xa1\x67\xfc\x56\x71\xb9\x3e\x2d\x17\x9f\x14\xf5\x4f\x0f\x94\x48\xfb\x98\x03\xf8\xce\xaf\xfc\xb5\xfd\x24\x31\xf5\x03\xab\x31\xf2\x04\x1f\xf5\x77\x18\xad\x28\x2a\xa6\xd2\xea\x76\xeb\x12\xaa\x17\x04\xa1\x48\x1b\xf4\xea\xd7\x3f\x8d\x9e\x26\x66\x1e\x1a\x27\x3f\x74\xb1\x2d\xf2\x3f\xd3\xf6\x7a\x1c\xd0\x4e\x5a\x1e\xdc\xf2\xae\x12\x2a\x14\xed\x17\x55\x9c\x20\xef\xd3\x7b\x2a\x95\x40\x40\xfb\xfc\x41\x3f\xaa\xe6\x5d\x0e\xf2\xa6\x5f\x42\xce\x14\x27\x11\x5a\xa5\x0b\xae\xa1\xef\xde\x2b\x1e\x11\xc4\xbb\xe4\xf0\xee\x7c\x4e\x9b\x0c\x9d\xde\x3f\x1a\xa7\xdb\x12\xce\xe5\x50\x59\x7b\xcb\x36\x09\xa6\xbd\xe6\x4d\xed\x36\x5b\x0c\xc0\xbb\x9f\xb5\x91\xbf\xaf\x81\x1b\xbc\xfe\x5d\x2b\xbf\xa3\x94\xa4\xa1\xb2\x4e\x7e\x71\xc9\x25\x2c\x32\xe0\xa5\xd3\xab\xed\x8a\xbd\x5d\xef\x58\x63\xe4\x60\xbf\x6d\xc9\x47\x94\x22\x1e\x46\xb4\x4c\x96\xc6\xfd\x18\x1a\x6d\x52\x74\x27\x8e\x67\xac\x61\x39\x9e\x8b\x22\x3b\xf6\x65\xab\x55\xf3\x3f\xcc\x6c\xec\x81\x97\xf2\x65\xbd\xdd\x0d\x47\x1b\x50\x0d\x64\x40\x11\x33\x4c\xf2\x2a\x88\x15\x84\xfd\xc2\xc5\x39\xd4\xc3\xea\xb1\x2f\x33\x02\xf6\x3f\x07\x2f\x58\x2b\xa3\x1b\x5e\x68\x0d\xe5\x31\x75\x6f\x0a\x3c\x2f\xc6\xba\x7f\x53\x24\x75\x9f\x9e\x9b\xeb\x9d\x78\xd5\xb9\x40\xe0\xd1\xc8\xa9\x69\x1e\xd2\xfa\x92\xf1\xb4\x84\xa3\x85\xc1\xc5\x6d\x27\xa9\xb4\xdf\x56\x77\x61\xac\xfc\xa6\x5e\x61\xf8\xcd\x81\x04\x0c\x2d\xe8\x1a\xb9\xf6\x77\x80\xc6\xed\x6f\xa3\x3e\xa1\xe7\xb0\x7e\x0f\x05\x96\xdb\xa8\x8b\xac\xfb\x09\x1a\x20\xa1\x0f\x41\x17\x73\xb2\x86\xd0\xc0\xc3\x00\xa2\x8d\x15\xd1\x37\x61\x6f\x37\x04\xb7\x58\x81\xcf\xa2\xd8\x88\x61\xd9\x54\xe1\x70\x41\x1d\x3d\x87\x1f\x1a\x0a\x9c\x97\x56\x5a\xae\xf9\x8d\xa0\x59\x6e\x29\xdd\xbb\xd2\x5c\xf0\x15\xeb\x70\x3e\xdb\x32\xfd\x13\xda\x16\x30\x91\xfa\x3f\xf9\xf9\x67\x9a\x65\x7d\xad\xf8\xd1\x05\x35\x09\x0c\xd5\x65\x5e\x3b\x66\xa6\x27\x48\x9f\x5f\x44\x71\x29\x6f\x92\x3a\xf6\x20\x4a\x18\x18\xd6\x77\xc4\x76\x99\xb6\x09\x66\x8d\x66\x4f\x46\x2a\x9e\xa3\x5b\x16\x8c\xa6\xcd\x96\x5f\xab\x3b\x80\xa3\xb8\x6e\xcb\xe2\xe3\x46\x88\x64\x74\x8b\x81\x0e\x50\xba\x6f\x97\x56\xaf\xfd\x4d\x11\x98\x17\x38\x7a\x76\x97\x7f\x69\x3e\x2c\x56\xd2\xb9\x2e\xc4\xc7\xed\x2c\xe3\x55\xdd\x31\xa1\xe1\xa2\x38\xbc\xd3\xd0\x97\xaa\x63\xcd\xfa\x06\xa7\xd3\xf5\xf1\x52\xa5\xb2\xaf\xad\x64\xbb\x46\x49\x22\xfd\x2e\x79\x00\xfc\x34\xd6\x93\x54\x10\x33\x03\x31\xd0\x3c\xcd\x4c\xd9\xc0\x5d\x69\x20\xf3\x3c\x9b\x5f\xff\x0d\x65\xd1\xf6\xe4\x11\xe2\x3c\xb8\x52\xdb\x12\xa9\x3f\x1b\xa7\x1c\x05\x62\xa7\x77\x21\x48\x3c\x8d\xb6\xc0\x29\xcd\xef\x8a\xf2\x09\xde\x0f\xc5\x39\x95\xee\x7c\x49\x40\x91\x82\x2d\x2b\x9e\x53\x79\x94\x43\x54\x3b\x24\x41\x88\x24\x96\xa9\x02\x8e\xf0\x0d\x17\x99\x9f\xda\x1b\x21\x61\x86\x14\x4e\x9e\x2e\xd9\xb9\x78\xf7\x3f\xbb\xa1\xc8\x38\xd6\xbb\xd9\x61\x15\xb4\x57\x82\x00\xb3\xd3\xab\xa7\xe5\x3d\x2f\xdf\xba\x60\x10\x70\xdf\x20\xfd\xad\x7a\xe5\xf7\x34\x7f\x56\xc5\x09\x6d\xa2\x09\x79\x40\x05\x3c\x50\x84\x39\xc0\x6c\xae\xd3\x67\x0b\xc5\xf8\x2c\x79\x39\x5c\xd7\xdc\x49\xb8\x62\xda\xd6\x7b\x97\x15\x18\x4d\xd3\xe1\x75\x44\x18\x9b\x00\x9e\x95\x66\x40\x82\xcd\x2f\xbd\x51\x10\x89\x51\x83\x31\x20\xad\x9d\xbd\xb5\xd8\xb5\x72\x63\x77\x3e\x14\xcf\x26\x81\xfd\x45\x49\x2b\x48\xa6\x30\x4b\x08\xa7\x73\x56\x5c\x01\x56\x1f\x50\xca\xb4\x02\xc3\x30\x51\xf5\xac\x25\x90\x89\x40\x7b\xb2\x86\xaa\xfe\x99\xc2\xbb\x7b\xb1\xca\x22\x59\xd7\xf9\x5b\x5a\x83\xb9\xe4\x28\xb6\x0a\x2a\x04\xf4\x6b\x2d\x53\xdb\x80\x6f\xc5\x75\x49\x84\x86\x2e\x84\x82\x55\x6e\x76\x25\xac\xc6\xd5\x6e\x00\xcc\xc7\x35\xff\xf1\xf2\xfc\x0c\x59\x3b\xaa\xb5\x17\x30\xda\x7e\xb3\x1a\xf2\xfa\xc7\x6e\xfd\xdb\x94\x3f\x00\x5a\x11\x61\x9d\xe1\x4e\x99\x7e\x88\x71\x37\x3d\xb5\x27\xa2\x9e\xb4\x3c\xbc\x1f\x5e\xd2\xea\x0f\xe0\x6e\x73\xd1\x9e\x34\x30\x93\x15\x2f\xb3\xeb\x4c\x15\xe7\x1a\xca\x11\xe6\x49\x93\xc8\x28\x4d\x9d\xf8\x07\x26\x8f\x6e\xa8\xe7\xb4\x1f\x73\x0b\x33\x3e\xf7\x3c\x79\x4d\x03\x82\xa1\xd0\xdd\xf5\x63\xf5\xf1\x57\x36\xcd\xf4\x70\xd1\x94\xab\x30\xee\xe1\x60\x70\x35\x5b\xe7\x0b\x18\xc7\x14\x74\x90\xc4\x0e\xbc\xda\x15\x96\xb9\x5b\x61\x94\x9b\x4a\x2d\xa8\xea\x3d\xd4\x86\x93\x9e\x67\x4b\x57\xb3\xa0\x43\xdf\x04\x1a\xcf\x06\x5c\xba\xd1\x96\x08\xa5\x47\xf0\xa1\x43\x16\x47\x76\x37\x74\x82\x47\xcf\x62\xf4\xc2\xc3\x28\xc1\xbc\x15\x06\x8d\x27\x78\xc5\x27\x4d\x06\x77\x6c\x6c\xaa\xc6\x00\xd1\xcb\xbd\xe1\xab\x43\x61\x54\x15\x5c\xd4\xfa\xd0\xaf\xe9\xff\xec\x85\x8e\x6e\x4c\x9a\xba\x9a\x0a\xea\x7f\x5d\xa0\x9a\xcc\x3b\xe9\x50\x85\x18\x99\xb3\xb4\x4e\x3b\x90\xe9\x39\x85\xde\x20\xb6\xfd\x22\xa0\x08\x49\x6b\x5f\x5f\x1c\x12\x43\xff\xbc\x5a\x6c\x9e\x96\xfb\xe3\x76\xb5\x3b\xde\x6f\x7e\xec\x5c\x7b\x42\x4d\xd0\xe5\x9f\x05\xf8\xbe\xc3\x8a\x6b\xee\x47\x98\x48\x37\x75\x46\xbf\x2e\x1f\x29\xff\x59\xd4\x1d\x29\x82\xe6\x54\x63\x70\xd1\x84\xd7\x9e\xe0\x1d\xad\xe3\x09\x67\x5f\x73\xc5\x30\x9a\x72\x6c\xac\x3a\xb8\xa9\x9d\xb0\xbd\x04\x31\x12\x19\x25\xf0\x0c\x4b\x1d\x07\xe0\x0f\x2d\x82\x18\xb3\x7a\x58\x5f\xd7\x0f\x00\x68\x19\x71\x2c\x1d\x36\x14\x62\x06\x2b\x51\x8f\x02\xf1\x5a\x26\x11\xe2\xfc\xce\xa8\xd8\x34\x28\xa1\x76\x3d\xb4\x09\xc5\x3d\x41\x59\x0c\x2f\xad\x48\x60\x48\xac\x1e\x67\x8b\xbf\x4c\x52\x4e\x17\xb0\x34\xab\x82\x13\x41\xf8\xd1\xac\xa9\xbf\x8d\x3d\x3b\xad\x92\x10\x6d\xbe\xc3\xfe\xb0\xe0\x59\x36\xdb\xae\xdb\xeb\x4b\x1f\x79\x6d\x4e\xfc\xe3\xc9\xe9\x10\x2a\xad\x40\xa0\x4d\x64\xf4\x44\xfe\xd5\x22\x16\x34\xf8\x86\xc5\xc6\x2e\x78\x26\x5a\x35\x0e\xec\x6b\x48\x18\x32\x86\x9c\x2f\xe5\x33\x38\x78\xb3\x6d\xd3\xda\xc3\x5b\xb1\x3c\xda\xfb\xb4\x9c\x88\x68\x63\x5f\xf0\x88\x97\x04\x96\xe9\x60\x63\xb5\xa5\x9a\xdb\x17\xbc\x27\x6f\x36\x22\xf6\xe8\x40\x1d\xe0\x11\xdf\xb0\x85\xbe\xf3\x5a\xbe\xf4\xcc\xa1\xa6\x25\xc1\xf1\xf5\xde\x12\x20\x95\xc3\x7a\x73\xf0\x48\x94\x24\x76\x6d\x5b\x39\x8b\x16\x3c\x22\x04\x62\x71\x8d\xec\xc3\x16\xca\xb4\x50\x9b\x37\x67\xb4\x37\xed\x0a\x03\x9c\x70\x82\xf2\x19\x72\x3b\x1a\x7a\x46\xcf\xf0\x01\x7d\xe2\x45\xdc\xc9\xf0\xaa\xc6\x09\xc5\x0c\xab\x6b\xf5\x35\xb1\xec\x1b\xfb\x33\x2f\x87\xc6\x15\x78\x3e\xd5\x98\x3e\xb9\xe3\xaf\xf0\xfb\x8f\x45\x7b\x54\x2c\x91\xa3\x6f\x3f\xeb\x7e\x02\x85\x1c\xd3\x8b\xd5\x7e\x4a\x98\xb7\x37\xa1\xc0\xa3\x89\xf2\xc3\x56\x8d\x8a\xb7\x2b\xd9\x2d\x33\x49\xbb\x4e\x81\x17\x90\x10\xd1\x5a\x4b\x5e\xec\x2e\x19\x54\x0e\xd9\x3f\x53\x0a\x6e\xe9\x62\xfe\xee\xdf\x7d\x2a\xce\xd1\xc8\x60\x01\x0f\x2d\x16\x7f\x9e\x71\xf9\x7a\x93\xbe\x06\x8f\x35\x3b\x38\x8e\x61\x5e\x55\xa9\x34\x8e\x9c\x6d\x0b\x69\x98\x48\x27\xe1\x85\x75\x2f\xcd\xca\xdb\x47\x04\x83\x17\x45\xda\xb7\xa2\xf2\xdf\x78\xd5\x83\xec\x81\x17\xf1\x08\x93\x07\x48\x39\x8d\xb1\x4d\x9b\x9c\xb5\xed\x71\x0c\x22\xb2\xc9\x85\x9e\xa5\xda\x36\x27\x21\x2e\x2a\x8d\x0f\x8d\xf0\x93\x43\x61\xe8\x43\x86\xcf\xc8\x3d\x8d\xb9\xbb\x33\xa6\xab\xaa\x61\xbc\x1c\x3c\x4e\x69\x94\x58\x63\xe0\x6e\x33\x7a\x78\xde\xb8\x98\xcd\x20\x38\xf1\xb2\x1e\xb1\xba\x4f\x2d\x22\xd0\x18\x0c\x58\xce\x7e\x34\xc1\x56\x7c\x2a\x77\x29\xc1\x69\x62\x60\x03\x15\x94\x6f\x30\x53\x7f\xf9\x4d\xdd\x81\x90\x24\xa4\xab\x88\x40\x62\xa2\xe9\xcb\xcb\xa0\xd5\xac\x5f\x14\x27\xcb\x1c\x3b\x32\x6b\xc0\x93\x90\x20\xb3\xe7\x09\x03\xd9\x43\xf8\x45\xb7\xde\x81\xa7\x12\x8a\xf6\xa9\xcb\xba\xe1\xe4\x47\x0f\x60\xec\xae\xd9\x03\x20\x09\x23\xc3\x89\xb6\x46\x26\xbe\xfa\x3a\xba\xb2\x26\x5e\x68\x63\x63\x8f\x45\x5e\xbf\x64\xd7\x5e\x6d\xef\xcf\x22\xbb\x9c\xc0\xb0\xde\xb4\xbb\x18\x10\xcf\x37\x89\x24\xc9\xf3\x91\x54\xd1\xe4\x3b\x20\x1e\xa3\xb8\x0b\xef\x0a\x91\xe6\xf7\x45\xa1\x7a\xb1\x26\x20\x9e\xf4\xb1\x48\xfb\xf0\x81\x19\xa9\xd7\x3e\x3e\xb3\x69\xa5\x00\x23\xb1\xdb\xe2\x32\x22\xfc\x1a\x7e\x1d\x42\x42\x10\x46\x9e\x6e\xe7\xe4\x84\xda\x22\xa6\xb4\xc8\x97\x43\x1b\x07\x88\x1f\x50\x54\x00\x9b\x29\x65\xf2\x7a\x36\x92\xd8\x5f\x7a\x27\x04\x2f\x2f\x1d\xa2\x0d\x88\x0f\xa6\xa2\xca\x61\x21\x1f\xd2\xaa\x7d\x06\x4a\x13\xb4\xa6\xef\x67\x0f\x87\xf6\x37\xed\x21\x7b\xc9\x0e\xd4\xbe\xf8\xd8\xf1\x6b\x15\xc4\xae\x2d\xf0\x8c\x96\x47\x5a\xb5\xe9\x1a\xd7\x42\x58\x5b\x68\x7a\x78\x29\x8b\xf7\xd5\xa8\xf6\x6a\xc9\x8b\x16\x76\xd0\xac\xe5\x15\x54\x8d\xa7\xd9\xc3\x33\x02\x09\x20\x40\xfe\xc3\xc5\x15\x13\x08\xe7\xb4\x76\xf2\x5e\xbd\x0c\x2f\x10\x46\x03\xdc\x4b\x8c\x13\xe1\xb0\x22\x83\x87\x66\x09\xc7\x52\x26\x99\x71\xb9\x28\x8a\xb3\x55\x1e\x03\xd5\xb8\xcc\xc3\xca\x75\x77\x44\xb3\x89\xe2\x06\x55\xd8\x71\x5e\x19\x45\x0a\x77\xd5\x50\x00\xa2\x65\xfe\xcb\xe5\xeb\xf1\xe4\x64\x2a\x80\x84\xe0\xa1\x1f\x7a\xee\xbc\x95\x05\xcf\x5b\xdf\xa5\x86\xd1\x37\x8d\x03\x0f\x2d\xcc\xc3\xe6\x30\x7b\x38\xce\x76\xdf\xdd\x89\x62\x49\x90\x1c\x7d\x2d\x0b\x04\xf5\x98\xdb\x6c\xa5\xf2\xff\xd6\xfc\x27\x09\x89\x30\x88\x98\xf1\x93\x28\xb6\x03\x9d\x3d\x77\x9d\x24\x90\xd2\x9b\xd2\xbc\x68\x3b\x30\x8d\x19\x40\x2c\xe2\xc3\x65\x18\x2e\xa7\x7e\xed\x38\x90\x44\x12\xe2\xb7\x65\x65\xb7\x72\x53\x76\x59\x20\x9c\x30\x4f\x60\x7c\xd4\x18\x7a\xbd\xab\x70\x12\xa3\x17\xb6\xe5\x58\x20\x52\xa4\xf9\x54\xc1\x21\x10\xce\x0c\x1c\xb2\xb2\xe3\x17\x3e\x0d\xb7\x8d\x5e\x85\x50\x1a\x63\xa3\xae\xb6\x73\xd3\x09\x0c\x02\x51\xd2\x43\xa8\xcb\xc3\xec\x8f\x99\xfb\x4d\x87\x12\xab\x79\xee\x7e\xa0\xa8\x61\x3f\x89\x08\x44\x73\x53\xa4\x7e\x80\xaa\x5e\xed\x16\x91\x6f\xc9\x6e\xc0\xf7\x98\xc4\x85\xc0\x32\x88\xb7\x22\x51\x8d\xe1\x84\x42\x95\x9f\x66\xff\xbe\x70\xdf\xc1\xf7\x92\x30\x8a\x1d\x47\x1a\x4f\xb3\x79\x09\x5c\xba\xd1\xe8\x13\x4a\x85\xdd\x2b\x1d\x43\x8b\xe5\x55\x74\xaa\x8a\xb9\xda\xf5\x06\xdf\xe8\xe4\x44\xfb\xc8\x08\x56\xa1\x22\xa0\x21\xa2\xb4\x4d\x3e\xf1\x10\xe4\x82\x24\xb5\xfb\xe3\xea\x69\x79\x5c\xb6\x00\x0d\xf0\xfd\xd8\xe0\xea\x65\x06\xbc\xfc\xd7\x25\x95\xaf\xf3\xcb\x75\xcb\xdb\x79\xe2\xfb\xb1\xc2\x7c\xb6\xbb\xad\x66\x9f\xbf\x0d\xbf\x81\x4f\x89\x01\xa4\x8b\xcb\x75\x37\x5f\xf4\x93\xf4\xe0\x53\x3f\xc2\xdc\x16\x22\x1a\x36\x37\x47\x52\x0f\x01\x3b\x0a\xb2\xef\x70\x35\x91\xfe\xd1\x3b\x75\x3d\x39\xc1\x52\xfd\xc6\x74\x9c\x2a\x93\xb2\xdd\x58\xc8\x62\x5b\x02\xb2\x87\x67\xf4\xb7\x7b\x6e\xa3\xfd\x42\x63\x2a\xbb\x29\x5b\xce\x67\x61\xe4\xd4\x64\x5b\xc5\xe9\x87\x1b\x4b\xc9\x67\x32\xc1\x60\x48\x5d\x67\xfb\xd6\x35\x01\x3f\x24\x84\x63\x41\x69\x0e\x83\x15\xcf\x0f\x6d\x59\xad\xf1\xce\x10\x37\x32\x5c\xfb\xff\xc6\x5f\xee\x54\x32\xc1\x2f\xbf\x9a\xed\xff\x78\x58\xdf\xad\xbe\x32\x4d\xfd\xc8\x8f\xc2\xb8\xb5\x26\x8e\xc2\xa4\x8c\x5d\x63\x40\x6d\x0e\xbd\xde\xd7\x5c\xde\x90\x21\xb9\x6e\xcc\x4f\x3a\xc6\xb7\x7d\x4b\x43\x0e\x7e\x14\x1b\x00\x0a\x0a\x64\x3c\xf5\xca\x22\xc0\x8f\x20\xc1\x34\xc9\x5b\x61\x38\x72\x47\xef\x2f\xf6\x62\xf4\xdf\x4d\x94\xb3\x2b\x43\x6f\x9b\x35\x1a\xa2\xfb\x22\xe3\x65\x5a\x0c\x5e\x65\x1c\x70\x6d\xa0\xaa\x8b\xd5\xd3\xe1\x78\xf7\xe3\x69\x79\x7c\xda\x3c\x39\x3a\xed\xb6\x1b\xe3\xd2\x16\xc2\x57\x90\xab\xe7\xa2\x18\xc1\x5e\xc0\x4f\xa4\x40\x13\x5c\xa5\x95\xb8\x94\x15\x56\xa6\x8c\xfb\xf0\x84\x21\x17\xc0\xb3\x13\xc5\x01\xe5\x0a\x37\xc0\xe7\x1c\xa8\x35\xfc\xff\xfc\x61\x0e\x6b\xdf\xe1\xf0\x2c\x22\xa1\x74\x4c\x30\xf8\xe5\xaa\x32\xfc\x8c\x5c\x19\xcd\xcc\x13\x37\xc2\x38\xb8\x8e\xae\x72\xd5\x33\x6e\x7d\xc1\x22\x6d\x39\x02\xdb\x20\x3e\xf8\x82\x13\x0c\x6f\x2e\xef\x7e\x0e\xde\xa2\x50\x89\x34\x61\xb8\x4a\xa6\x23\x96\xf5\xa6\x55\x2b\x6b\xba\xcd\xa1\x7e\xbc\xd4\xcd\x1a\xd0\xf3\xb3\x90\x3e\x2d\xe8\xa2\xac\xcb\x4b\x9d\x42\x3b\xf9\x15\x24\x60\x9d\xb0\x6f\x7f\x9a\x7b\xdd\x68\xfd\x70\x63\xae\xfb\x10\x73\x74\xfd\x2a\x40\x33\x9d\x7e\x32\xbb\x21\x09\x74\xd4\xa9\x2e\x1e\xf7\xb3\x87\xd5\xa0\x8e\x13\x7c\xed\xfb\x08\x4a\xb5\xe0\x22\x54\x47\x43\xf9\x36\xa3\x3a\xdb\xa3\x27\x6a\xfa\x72\x2c\xc5\x32\xd4\x0a\xbb\x36\xb5\xf5\x65\x12\x08\x7c\xcd\xc3\x58\xf7\xeb\x3b\x4c\x19\x4f\x7b\x07\x2a\x70\x4c\x8b\x8d\xff\x32\x7c\xa1\xd4\x0b\x04\xce\x94\xc5\x6e\xb6\x76\x3e\x26\xf5\x98\x17\xba\x7a\xe4\x8e\xd2\x04\xa8\xc7\x43\x5c\x58\x2b\xae\x01\x69\x80\xa6\x27\x26\x25\x11\x18\x51\x77\x9b\x2a\x30\x55\x50\x6d\x89\xf8\xe4\xcb\xa4\x84\x03\xda\xf9\x48\x2b\x75\x78\xe1\xef\x5d\xb9\x31\x50\x3f\x31\x99\xd8\x7b\xe0\x99\x25\xfc\x19\x1e\xcd\x62\x23\xdb\xb3\x5c\x1f\xba\x14\x27\x50\xc6\xb9\xec\x63\xbb\xa6\xb4\x72\x6d\xd7\xd0\x33\xe8\xa4\x95\x73\xf7\xf7\x75\x71\x9e\x59\x5d\x32\x67\x9e\xd0\x30\xa2\x38\x35\x65\x91\xe7\x20\xbb\xd0\xed\xb8\x6e\xce\x75\xd7\x0a\x2d\x85\xdf\x15\x37\x12\xcc\x5d\x5c\x68\xf4\x16\x06\xe5\x2d\xc3\x3b\x8b\xb8\xc6\x2f\x58\x68\x9d\xa5\x79\x17\x36\x19\xec\x48\x34\x0e\x08\xb5\x01\xe5\xb9\x69\xf8\xbc\xd6\xa2\xf5\xf6\x69\xcc\x0c\x5d\x14\xf2\x70\x9e\xce\x3c\x7d\xce\x31\xb9\x9b\x76\x74\x87\x83\xee\xda\x16\xf2\x5b\xea\x8d\x2e\x1a\x82\xf6\xc8\x28\x35\x31\x7c\x17\x89\x67\x9c\xf0\x34\x4f\xeb\xbe\x69\xfd\x97\xf6\x16\x4d\x18\x98\x23\x2b\x63\xfb\xf7\x71\x1e\xb6\x0b\x97\x1c\x17\x99\x45\x49\xea\xf4\x95\x67\xeb\x6a\xff\x52\x94\xed\xc8\x15\x94\xe2\xba\x71\x2e\xe1\xcc\x4b\x30\x21\x9f\xb6\x91\xf9\x66\x81\x82\x9a\x77\x55\xb7\x40\xa5\x6f\xd2\x1c\xb6\xa4\x67\x99\xbe\x4d\xf3\xc7\x01\x95\xcc\xe3\x76\x73\x9e\x3b\x04\xc9\xce\x54\xa1\x4f\x47\x8d\xed\x71\xca\x8f\x02\x66\xc8\x6d\x8a\x6c\xb0\x9b\x50\xc5\x28\x66\x18\x72\x78\x47\xc5\xbc\x2c\xcd\x5f\x9b\xb7\xbd\x7a\xda\x4f\x56\x4f\x01\x55\xd2\xc7\xfd\x67\x7f\x98\x1d\x8e\x8f\xb3\xdf\xdb\x33\xe9\x98\x45\xed\x56\xbb\x9a\x0d\xfc\x19\x0a\x81\xa1\x4d\xcd\x8b\x7a\xf5\xbf\x0b\xcf\x86\xd2\x0a\x83\xdb\x0d\x3c\x4f\x28\xeb\xf0\x99\x8c\xe6\x17\x72\xa4\x10\x78\x21\x71\x71\x1d\x37\x3b\x7a\xdc\x0e\xae\x53\xdc\x66\x79\x9f\x73\x9e\xd7\xf3\xa2\x5d\xb9\x02\x42\x3c\xac\x7c\xea\xea\x45\x21\x20\x11\x4f\xac\xb4\x7b\xd6\x5b\xf7\x03\xc2\x09\xae\x63\x96\xc5\x71\x78\x27\x04\x04\x42\x72\xdb\x55\xa0\x8d\x49\xf4\xa1\x15\x9f\x0b\xf3\xdb\xd3\xf8\x22\x44\x0c\xd1\xaf\xd5\x5c\x76\xc3\x24\xa0\xcc\xc3\xd1\x39\x5f\xee\x1f\xb1\xe6\xec\x2f\x2b\x85\x20\xa0\xa1\x47\x79\xc7\x1d\xda\xbc\xc7\x91\x77\x12\x04\xb1\xd6\x26\xed\x93\xe7\x50\x3e\x5c\xe4\xeb\x75\x60\xc9\x04\x81\x60\x18\x62\xf8\x9e\xbe\xa7\x37\xd8\xc2\xcf\xd4\xc4\x63\x77\xb0\x8c\x99\xcd\x2e\x5a\x59\xbd\xfa\xd2\xbe\xf8\x40\x25\x2c\x6c\x39\x8e\x2f\xa5\x09\x89\x7d\x62\xe3\x06\x2c\x96\xd2\xe9\xf6\xc2\xbb\xdb\xfc\xc7\x7d\x00\xc3\x0d\xe7\xa2\xaa\xea\xde\x30\x0f\x98\x16\x7c\xa4\x05\xe6\xaa\xb0\xa7\xaf\x16\x6a\xe9\xcb\x1e\xf3\x4e\x1f\x00\x0e\x41\xa4\x8c\x9e\xf3\xaf\x8b\xc0\x99\x3c\x7c\xa5\x31\xb3\x02\xb9\x59\x51\xb5\xf9\x17\x77\x68\xcc\x83\xa4\x45\x15\xfc\xa5\xc8\xcf\xf0\xa6\x92\xd0\xc8\xfc\xcc\xd6\xdb\xd9\x1f\xee\x84\x49\xc2\x82\xae\x82\x04\x23\x4a\xe7\xf1\x72\xe0\xba\x72\xc9\x3b\x66\x50\x7e\x1a\x8f\x05\x2e\x62\xf4\x5a\xf8\x69\x6d\x3c\x62\xf7\xbb\x34\x44\x2d\x18\x91\xba\x03\x64\x7b\x31\x2c\xf2\xd3\x2f\x8f\x6b\x4e\xac\x38\x14\x92\x74\x22\x9f\x66\xfb\xd9\xa5\x0e\x99\xc1\x74\x97\xef\xbc\x54\x8f\x1d\x6e\x07\x02\xe5\x19\x59\xa9\x25\xf0\xfa\xc5\x10\xc2\x1e\xd3\x34\x6d\x9b\xa9\xa1\x2e\x7d\x86\xfa\xd8\x2c\xad\xd5\x31\x03\x5d\x1f\x75\x51\x1e\x4b\x48\x47\xc9\x46\x68\x4c\x31\xa4\x60\xb0\x94\x82\x77\xe6\x82\x9f\xf0\xa3\xf5\xb4\xf4\xdd\xe1\x51\x1c\xda\x12\xf0\x5e\x38\xfe\x2b\x38\x05\x04\x3a\x32\x4e\xe1\x61\x71\xc3\x75\x3f\x31\x3f\xb5\x00\x8b\x2f\x32\xe8\x27\x04\x6c\x0c\x88\x38\x20\xd0\x40\x3d\xfb\xcc\xfd\x5a\xaa\xe1\x75\x99\xe7\x45\x98\x65\x58\x20\x6d\xe8\x8f\x3c\x6d\xdf\x37\xf3\x02\x8a\xf5\x8b\x8d\x5f\x4d\xdb\x1f\x19\x0d\xa3\x8e\x17\xdc\x48\xc4\xf5\x83\xd9\x8c\x90\x84\x1a\x07\xc2\x40\x3a\x0c\x15\x81\x6b\x6c\x16\xbb\x1b\x20\xe3\x5f\x45\xe8\xa7\x91\x79\xcd\xd9\x42\x9c\x9d\x2f\xf0\x71\x28\x66\x95\x4c\xd3\x5e\xa6\x1f\x98\xef\xf1\x24\x68\xf5\x37\x8d\x56\xe9\x68\xe8\x32\x9f\x98\x9c\xe5\xfa\x69\xf1\xa3\xbf\xc1\x31\x9f\x0a\x8c\x27\x37\xc3\xac\x7e\xe1\x9f\x83\x04\x80\xf9\xa1\x8f\x81\x03\xa8\x5f\xc2\x66\x17\xde\xbc\x8f\x91\x96\x4d\x9f\x28\x36\x14\xa6\xcf\xa9\x8b\xa0\x31\xca\x3d\xd1\xe9\x83\x4c\x91\x0a\x4c\xfd\xcb\x1d\x2c\x18\x86\x89\x91\xd8\xa6\x25\xe4\xb7\x3b\x99\x4b\x0a\x0e\x6f\x34\xf0\x85\xb6\xc0\x9f\xf4\xf9\x19\xca\xed\xcf\xed\x1e\xcb\x2e\x3e\x19\x1c\x81\x2f\x99\x6e\x83\x5d\x37\x6c\xf3\xc0\x02\x2a\x5c\x06\x67\x07\x55\x91\xbd\x8d\xc3\xe8\x2c\x48\x22\x84\xda\xcf\x2f\x8d\xd3\xe0\xb8\x3a\xff\x2e\x83\x92\x3d\x09\x4b\x28\xce\xc7\xa7\xa2\xac\x5f\xb6\x45\x06\x16\xac\x3a\xe0\xe0\x02\x16\x26\x3e\xde\xae\x79\x9d\x8f\x08\x71\xcb\x0b\x05\xb3\xea\x00\xfc\x64\xd0\xd9\xa3\xdb\x8b\x94\x8f\x10\xd7\xa3\x01\x55\xef\xe0\x0d\x6b\x5a\xdb\x71\x6b\xc9\x36\x7c\xcf\xf6\x8f\x21\x41\x1c\x4f\xa1\x75\x2a\x53\x9e\xdd\x71\x09\xa2\x28\xdc\xfe\xcf\x92\x84\x31\xd2\x22\x04\xde\xd2\xe2\x52\x19\x70\x71\x3b\xab\x12\x9d\xa0\xd5\xb6\xbf\xc8\xc1\x78\xe3\x94\x62\x66\xd7\x52\x77\x61\xdb\x0e\x30\xb6\xda\x77\xb2\x5c\x6f\x2e\x2c\x7e\x10\x83\x10\x90\x65\x7c\xa8\xd9\x00\x8c\xcb\x08\x43\x40\xdb\xe5\xb6\x67\x35\x36\xde\x3d\xe9\x54\x78\x67\x17\x14\x0f\xbf\x29\xe7\x02\x26\x3c\xe5\x27\x8e\x61\xb1\xe2\x48\x96\xf2\x17\x0c\x91\xc0\x04\x95\x18\xe6\xc7\xd8\xe9\xa5\xfa\x44\x72\x62\x3a\x27\xc1\x04\xd3\xac\xcf\xdd\x39\xd2\x89\x19\x5d\x4a\x7a\xac\x8b\xae\x8c\x54\xd6\xbb\x21\xa1\x02\xa3\xe0\xb2\xe4\x65\x6a\x59\x9f\x47\xcf\xa9\x22\x82\xa2\x71\x0f\xc5\xb3\x0d\x5b\xb9\x0c\xc5\x2d\x4b\xf1\xdf\xaa\x0a\x6f\x4e\x99\x38\x57\x67\x92\x5b\xf5\x93\x97\xa7\x62\x40\x72\xa3\x9f\x9b\x87\x1f\x8f\xab\x63\xe4\xb9\x87\x00\x15\x62\xad\xe6\x31\xcd\x15\x7c\x4c\x91\xb6\x01\xd3\x84\x22\xec\x20\xe3\xb9\x32\x94\x9e\x06\xf7\xed\xce\xa1\xe3\xc8\x10\xf0\xc1\xbb\x49\x2c\x0c\x33\x75\xa6\x57\xe8\xb1\x30\xb6\x50\x98\x79\x2d\x07\x70\x37\xd7\x23\xa1\x58\xdc\x78\x0f\x69\x39\x66\x0d\x1d\xf6\x24\x5e\xe8\x28\x89\x76\xc0\xb3\xb4\xea\x55\xc1\x40\x48\x24\x0d\xfd\x21\x6b\xf7\xf4\x87\x0e\x89\xd2\xb8\x8f\x2d\x9b\x95\x53\x14\xb5\x8b\xcb\x8f\x6e\x8c\x80\x76\x97\xfb\x95\xfe\xf9\xe7\xe1\x7a\x1e\xd7\xfd\x42\x48\x23\xcd\x8d\x95\x60\x98\x97\xdc\xaa\x39\x31\xb0\xed\x11\x2c\x21\xe8\x01\x65\xf0\xb6\xed\xcb\x8b\x40\x18\x52\x4f\x78\x66\xd1\x1f\x4e\xbc\x30\xa6\xc6\xb0\x7a\x28\x9e\x1f\x0a\xf9\x8a\xc5\x5c\x78\xa5\x6e\x22\x0f\x8c\xdd\x30\x8e\x19\xf2\x4a\xd8\xd2\x8f\x29\x7d\x24\x08\x93\x20\x90\x6d\x6e\xa2\x39\x67\xda\x18\xf9\x06\xe1\xe1\x16\x97\x30\x09\x15\x95\x4e\xc3\xae\x55\x83\x9e\xf4\x77\xc3\x44\xb1\xd0\xa9\xc2\xf6\xcd\xeb\x90\x0b\x86\x45\x2d\x69\x5e\x41\x59\x1f\x8b\x52\x8d\x18\x34\xfa\xc1\x61\xe2\xbb\xa7\x10\x7e\x02\x26\x32\x56\x5f\xca\x7c\x5d\x99\xf4\xc6\x64\x6a\x23\x14\x8c\xc5\xbc\xf5\xf9\x7e\x42\x99\xea\xb4\x53\x4b\x1e\xf5\x4d\x22\x4d\xc7\xfc\xee\x7b\x7e\x82\x9f\xfc\xf2\x29\x09\x1d\x84\x82\x7b\xdc\x29\xad\x2c\xac\x63\x55\xd5\x4e\x33\xc0\x3d\xab\x0c\x09\xd2\x10\xbb\x5c\xc3\x0c\x45\xb6\x21\x7d\xce\x31\x83\xfc\x54\xd4\x26\x93\x6c\xbb\x2b\x12\x78\xcc\x16\x6b\xa3\x76\xe0\xf0\x9a\x8a\x1a\x04\xae\x34\x73\x2f\xbb\xee\x2c\x76\xa5\x3d\x3e\xa2\xae\x9c\x75\x7f\x39\x37\xbb\xd3\x1b\x1f\x8d\x1e\x15\x51\x74\x62\x1f\x8a\xe7\x66\xb8\x35\xff\xbf\xc3\xb7\x84\xac\x0c\x08\x8d\xb8\x8d\xab\x87\xc0\x14\x66\xab\x2f\xf9\x63\x3a\x5e\x1b\x42\x08\x13\xac\xd0\xca\x38\x3e\x66\x99\x42\x1b\x5c\x08\x41\xfa\xb8\x1d\x1d\xa7\x24\x8f\x6c\x1f\x1d\xf8\xa2\xdb\x32\xf6\x90\xfe\xe9\xa8\x3b\x27\x17\x11\x0d\x4a\x58\x87\x9e\xa7\x39\x32\x91\x3d\x7f\xb2\x8a\x47\x1e\x63\x41\xe2\x88\x0e\x35\x1a\x95\xc3\x29\x72\xfb\xa7\x3b\x32\xa2\x9a\xb4\xcc\xf9\xab\xc3\xfd\x6f\xa3\x33\xf3\x10\x25\x34\x3e\x03\xc4\x44\x9e\x20\x88\x39\xcc\x1d\x16\x09\x22\x92\x18\xc9\x71\x34\x67\x9e\xc9\xe8\x00\xa2\x12\x64\x0d\x97\x5d\xa1\x29\x44\x04\x3c\xcc\xdc\xe2\x8f\xe3\x78\x7c\xe4\x07\x1a\x31\x81\xf9\xe5\x84\x5c\x14\xd5\x43\x8f\x35\x10\x22\x9f\x89\xc8\x8d\xbe\xe3\x0b\x37\x2a\x9b\x8d\x49\xb3\x37\xea\xa5\x79\x91\xff\x1b\xca\xa2\xfb\xb9\xe6\xaf\xd0\x1e\x0c\x46\x2d\xae\x71\xca\x0a\xe3\x00\xf7\xdf\x8f\xaf\x09\x16\x46\xef\x21\x57\x98\x6b\x46\x7e\x24\x48\xdf\x46\xb2\x33\x10\x51\xcf\xf3\x59\xaf\x16\xe1\x93\xe2\x98\xdb\x3f\xfb\x2e\x49\x44\x03\x0a\xae\x04\x54\x5f\x37\x83\x45\x63\x7c\xc2\xc1\x78\x89\x68\x10\x20\x5e\x7e\x36\x4f\xeb\x5e\xe0\x22\xa2\xcc\x90\x79\x98\xfd\xb8\xe4\xcd\xce\x7c\x2a\xde\x46\x15\xf9\x10\x05\x01\xc3\x4f\xa0\x4a\x9e\xe6\x3b\x1c\x74\xad\x98\xe8\xa8\x27\x63\x86\xe6\x0e\xd7\x83\x96\x57\xaa\x1a\xd2\x8a\x0c\xdf\x4e\xe8\xf9\x8a\xba\x31\x31\xc6\x2a\x3a\x63\x3c\x0a\x89\xe1\x9b\xdc\x1f\x56\xdb\xe3\x7e\xfd\x6f\x97\x35\x8c\x42\x1e\xf9\xcc\x7d\xe2\xf7\xb4\x7e\x99\x21\x7d\xc2\xa1\xbc\x40\xd7\x25\x46\xb0\x7f\x7e\x39\xdd\x02\x7f\x21\x0a\x35\x53\xbe\x51\x73\x7b\x34\x7e\xf1\x1c\xea\x23\xf4\x40\x42\x51\xc4\x69\xdc\xc3\x06\x1f\xca\x54\xbe\x66\xb0\x2c\xde\x73\x97\x38\xb6\x1d\x63\xf0\x5c\x2c\xc4\x2c\xba\x06\x7e\xb1\xcf\x78\xf5\x92\xe6\xcf\x06\x64\x36\x1a\x1e\x49\xe2\x21\x5c\xa6\x27\x59\x6e\x32\xbd\x13\xe2\x5c\xbd\xd7\xd7\x87\xc7\x45\x89\x56\x86\x22\xbd\x86\xb3\x99\x02\x7d\xdb\x37\xe2\x2c\xc0\x64\xb9\x2a\x2c\x82\x0f\x69\xd9\xf3\x9b\x2f\xcd\xc3\x04\x33\xc3\x5b\x28\xab\x94\x1b\x62\x92\x09\xea\x6e\xd7\x5b\x19\x57\x55\xa7\x25\x20\xff\xcb\x43\xf1\x4c\x66\x79\x91\x5f\xdb\xd9\x2b\x88\x51\x51\xdb\xf2\xeb\x53\xfa\x92\x66\x8d\x89\x38\xa4\x9c\x87\x48\x02\x77\x6c\xc3\x77\x30\x82\x14\x44\x52\x6b\x6a\x68\x7f\xe7\xc6\x4f\x98\x40\xec\x43\xa4\x42\x86\xdc\xa1\x68\xba\xec\xcf\x50\x9e\x7a\x31\xc3\x48\x09\x81\x96\xf6\xe1\x30\xdb\x2d\xdd\x8f\x90\x84\xb8\xbc\x89\xcb\x75\xce\xe5\xab\x13\xcd\xe9\x55\x77\x41\x04\xd2\x03\x4b\x19\x60\x58\x3d\x1b\xb7\x65\x40\xbd\xd8\x76\x34\x4c\x37\xbb\xd9\xd3\xb7\xd5\xea\x69\x79\x0c\xdd\x29\x34\xf1\xd1\x89\xcc\x80\xbf\x81\xd3\xd0\x1a\xcc\x6b\x9d\x08\x57\x54\xb8\x83\x73\x51\x8e\xce\x1d\x7b\xda\x47\x54\xf3\x1f\x8b\x7d\xcd\x73\xc5\x4b\x35\x49\x55\x73\xbb\x62\xc4\xc4\x8f\xb4\xad\x92\xee\x03\x55\x21\x26\x2c\x4c\xba\xe4\x6b\x0b\xba\x1b\x99\x07\xc3\x55\x24\x26\xb1\x2f\xad\x46\xca\x3f\x2f\xcf\x5c\xf1\x2f\xc8\x72\x6e\xc6\x4a\x4c\x04\x89\x3a\x62\x51\x0b\xbb\x9a\xa7\x59\xd6\xdb\x8b\x26\x8e\x02\x40\x58\x24\x8e\x2e\x5b\xb9\xb4\xca\x55\x6b\x74\x39\x8f\x20\xf6\xbd\x80\x5b\xba\x54\x8c\x7f\x39\x0a\xb4\xbf\x70\x0c\xbe\x76\x18\x62\x3f\x36\x3c\xf6\xe8\x0f\xfc\x4a\xb1\x8c\xd6\x35\x49\xe2\x2a\x53\xed\x6b\x6b\xac\x87\xc6\x98\x18\x93\xbb\x41\x4c\x93\xc8\x14\xef\x9b\xaa\xb9\xb4\xc8\x07\x78\xaf\x38\xf0\x04\xae\xec\xeb\x6f\x87\xfe\xac\x8d\x03\x19\x92\xc0\x91\x82\xa4\x8d\x3f\xde\xe3\x2d\x80\x38\xf4\x40\x88\x8e\xec\xa9\x55\xdc\xe9\x19\x3b\x71\x14\x02\xc6\x88\x55\x5a\x82\xac\xf7\x90\x65\xbb\xde\x19\x22\x69\x18\xb7\x97\xab\xbb\xd9\x8f\x87\xc3\xd1\xd1\x66\x2c\x36\x7b\x97\xc0\x8c\x63\xcf\xc3\x82\x96\x4e\x4d\xe0\xf0\x02\x8d\x75\x38\xb3\x82\x0b\x9f\x71\xca\xda\xe3\x13\x10\x38\xd6\xb0\x76\x7c\x99\x5a\x9e\x45\x77\x76\x1e\x10\x0c\x48\x2a\x87\x4e\xfd\x5a\x4d\x0d\x62\xae\x4d\xc4\x04\x67\x8b\xdd\x4e\x87\x98\x35\xdb\x51\x44\x0c\x57\xd5\xf9\xc5\xec\x95\x55\x4f\x0b\x73\x78\x4a\x11\x99\x4d\x6b\xbd\x43\x57\x17\xb3\x2d\x5f\x61\x17\x62\x01\x21\x0e\x0b\x23\x15\xf4\x39\x6f\x94\xed\x2e\x7d\x53\x97\x7e\x57\x0e\xd1\x50\x31\x70\x4e\x68\x9b\x26\xed\xa7\x22\x6e\xf6\xf0\x18\x64\x44\x9b\x1d\xe8\xbf\xcd\xe2\x7e\xdd\x8e\x4c\x8c\x58\x7b\x4c\xb9\xcc\x76\x59\xbc\x5b\x3a\xab\x49\xf3\x31\xd6\x91\x41\x2f\xb9\x37\x6e\x4a\x3f\x8b\x12\xc1\x1f\xa3\xae\x82\x32\x83\xb5\x37\x6a\x02\xa6\xb2\xdf\x9c\x7b\xb8\x50\x27\xc4\x33\xb8\x9f\x87\xf4\x7f\x97\x54\x4d\xe0\x83\xbe\x9e\x6b\x09\x91\x1c\x33\x22\x36\xb6\x84\xa0\xd0\x51\x7a\xa9\xcb\x43\x26\x44\x09\x2f\xfe\x32\xd9\xe9\x3a\xea\xc4\x05\x69\x9f\xe0\x7d\x6b\x32\x79\xb7\x2e\x62\xe2\xfb\x11\x25\x96\x32\x67\x07\x7a\xc0\xed\xe8\xba\x84\xc0\x45\x5b\x0d\x9c\xd6\x00\xdb\xf5\xb2\x7d\x7e\x3f\xf6\x1d\xb9\xc5\x7c\x69\x37\xf0\xdf\x26\xb6\xea\x84\x7a\x01\xf2\x1b\x71\xa5\x44\x7d\x95\x93\x1c\xa6\xae\x6b\x1c\x28\x0b\xc5\x32\xa4\xb0\x5b\xfc\x10\x90\xcb\x81\x58\x7d\xef\xbd\xd0\x98\x61\x01\xde\xd9\x04\x86\xcc\x51\x3d\xf2\x23\x48\xa8\xd0\x98\xc4\x3a\x39\xbd\x1d\xdc\xfe\xcc\x64\x5e\xe7\xbf\x56\x6b\xd7\x31\x08\x43\x04\x37\x38\x90\xdb\xa1\x78\xe4\xf9\x75\x6c\x98\x25\x41\x42\x70\x71\x43\x1b\xfa\x78\xd8\xcd\x16\x47\xdf\xf3\x3c\xaf\x3d\x8d\x8c\x5d\x98\x6b\x76\x79\xbe\x94\xed\xef\x5a\x48\xfb\xbe\xd0\x18\x79\xe3\xd9\xa2\x00\x8c\xfa\xb5\x75\x79\x7f\x91\x90\x4b\x58\xa0\x91\xc5\x7d\x5d\xb5\x31\x0b\xdb\x12\x92\xc4\x27\x03\x9e\x68\x13\xef\xeb\x16\xbf\x24\x04\xce\xec\x77\xf8\x8c\xf4\x76\xaa\xa6\x0e\x92\x48\x18\xfa\xfe\x01\x50\xc0\x9d\x35\xa6\xbe\x93\x68\x34\xa4\xa5\xb7\x34\x43\x4d\x27\xca\x65\xeb\xef\xdd\x17\x19\x96\xac\xf3\x0f\xf7\x22\x46\x03\x2f\x4e\x38\x86\xa7\x52\x94\xa1\x36\x5c\x4e\x37\xbb\x74\xfb\x41\x62\x6e\xb8\xf4\x2c\x7b\x03\x06\xc8\xc6\x43\x39\x11\xb1\xd7\xea\x2e\xcf\x79\x05\x3f\x76\xed\x77\x17\x4c\x61\xdc\x65\x3e\xdb\xaf\x7a\x42\xec\x90\xc8\x50\x98\xf2\x92\x34\xcb\xba\x40\x53\x22\x35\xc3\x32\x7c\xf3\x30\x86\xf7\x1c\x0b\x3e\x27\xf0\x03\x89\x6a\x36\xd5\x9e\x2b\x34\xbb\xd4\x2f\xd3\xd0\x89\x04\x02\x86\x8c\x4f\x85\xad\x16\x39\xfe\xef\xd2\x47\x0c\xf4\x17\xfd\xff\x23\xee\xe1\x41\xc6\x08\xcf\x70\xb1\x8c\xd5\xe1\xbe\xee\x0c\xce\xe1\x4b\x00\x88\xa8\x83\x41\x1e\xe3\xa3\xe0\x55\x2a\x5d\xc0\xaa\x9a\x43\xfd\x0e\x90\xbb\x02\xc0\xa3\x43\x9f\x1b\x2f\x73\x7e\xa5\xdd\x08\xd7\x9e\x89\x9f\x7d\x4b\x4f\x27\x8b\x44\x9d\x0c\xca\x4e\x8f\x61\x9d\x28\x1a\xb9\x88\x52\x63\x5f\x1e\xde\x8b\xf6\xcc\x9c\x63\x5c\xe0\x58\x41\xf6\x49\xf4\x2e\xd1\x60\x98\x1c\xcd\xeb\xbf\x2b\x8b\x3f\x21\xbf\x4d\xc0\x72\x8f\x85\x71\xe8\x4c\x99\x7d\x6b\x7b\x70\x4f\x09\x4c\x8b\xdd\xf3\x52\x2d\xf8\xd9\x95\x90\x4f\x5e\x8b\x13\xcf\x70\x7e\x5a\xb1\xda\xae\x34\x6e\x80\xb1\xe4\x24\x08\x5c\x35\xc3\xb6\x2c\xfe\x0b\xb2\x3e\x14\xe8\x0d\x7d\xb2\xce\x71\xa2\xa5\x08\x5d\x68\xd1\xac\x36\x13\xe2\x98\xc0\x7d\x2b\x49\x2f\xc0\xa8\x72\xbb\x9f\x63\xf3\x0a\x1e\xaf\xb7\x55\x04\xdd\x45\x7c\xe0\x49\xbb\xed\x3d\xf0\xaa\x3e\x7c\x18\x44\xfd\xfc\x7a\xcf\xdb\x78\x0d\xf7\x75\x88\xae\x84\x41\xf9\xaf\xf5\x13\x80\x02\x75\x40\x3a\x62\xe8\xa6\xe6\xd8\xd5\x9e\x4e\xa3\x4d\x7f\x73\x4e\x03\xa9\x44\x27\x09\x51\xe4\xd3\x53\x80\xd3\x48\x5b\x46\x29\x68\x71\x5d\xe3\x8c\x1f\x0f\x88\xaf\x83\x1e\x4d\x0c\x1d\x7d\xf9\x20\xa0\xcc\x6e\x95\xdf\x20\xf7\x5a\xdd\xdb\xae\x07\x23\x09\x92\x87\xf5\x70\xe6\x68\x44\x2f\x78\x26\x27\x62\xf4\xa3\x83\x79\xc8\x6d\xf9\xcd\xae\x90\xb6\x04\xc6\xe4\x3b\x86\x1d\x43\x42\x5c\xd9\xba\xc5\x13\x2f\x2f\x65\x3f\x87\x36\x3a\x71\x18\x78\x46\xdf\x8a\xe7\xc5\xac\x79\x3d\x7d\xdd\x2f\xe0\x61\x28\x71\xf6\x8a\xcb\x35\xcd\xc7\xee\xec\xf8\x54\x32\xc6\x50\x4d\x5a\xb9\x9c\x11\x86\xcc\xee\x2c\x84\xa0\xfd\xf6\x11\x35\x8c\xa0\xb3\xed\x66\x04\xd6\x72\x1d\x94\xd9\xbb\x91\xe2\xab\xf9\x1c\xec\xa9\x78\x77\x8d\xb1\x47\x30\x40\xfe\x5e\xa6\x35\xec\x6e\x69\xbf\x5d\x37\x11\x5a\x29\x00\x84\x56\x97\x85\x4e\x33\xd8\xa6\xb2\xbe\x94\x43\x46\x23\xe0\x09\x0b\xb1\x8c\xff\xae\xa8\x5e\xb8\x15\x6c\x76\x57\x4b\xb8\x1f\xf1\xde\x4a\x7a\x8f\x3a\xa0\xbf\x4d\x15\x6c\x74\xd7\x4e\x80\x23\xe7\xd5\xd1\xb0\x38\xf4\x25\xed\xa6\xc1\x9e\xe6\xcf\xe1\xa8\xe4\x5c\x45\x02\x5d\x5a\x5d\x47\xfe\xe8\x2b\x0b\x9a\xa0\xb9\xdf\xad\x0d\xed\xb2\xa0\x02\x43\xb8\xf5\x0c\xf5\x7c\xbd\xec\x15\x8b\x70\x60\x44\x5b\x47\xe7\x1e\xd2\x36\x95\xc7\x21\x06\x6a\x18\x6f\x0d\xdc\xc8\xc5\x45\xee\x8a\xf1\xe0\x02\x1d\x73\x27\xf7\xbb\xda\xdc\x9b\x68\xcb\xf4\x68\x10\x1e\xd5\x28\x6a\x6c\x2d\xcd\x01\xb4\xc5\x75\x61\x01\x74\x80\xa1\x6d\x9a\x3f\x16\x87\x56\xd7\x65\x7a\x52\x0b\x2f\xd4\x21\x41\xc3\x2a\xbf\xf0\x0c\x19\x19\x7a\x15\x28\xc2\x4b\x84\x7b\xc6\x96\x06\xbb\x42\xd0\xdc\x5f\xf9\xa4\x93\xee\xb8\x20\x41\x4c\x95\xa9\xe9\x18\x5a\xe2\x82\x84\x21\x5a\xa2\xc8\xa9\x14\x8d\x96\x03\x41\x20\x22\xd2\xd2\x13\x0e\x65\x26\x40\x10\xcd\x30\xfc\xd3\x0c\xf9\x9f\x3c\x7b\xeb\xd5\x2f\x83\xf0\x09\xc5\xfa\x0f\x1b\x7b\x47\x52\xd3\x16\xce\x2b\x7c\x96\x60\x9c\x5f\x34\x26\x4f\xae\xac\xed\xa3\x51\x00\x42\x8d\xca\xf1\x41\xf8\xdc\x54\x73\xce\x79\x0e\xbc\x3c\x6e\x4a\x2e\x2f\x59\x31\xea\x44\x89\xe1\x7e\xd6\x00\xd5\x81\x37\x3e\x4a\x59\x9c\x0c\xdd\xc7\xf4\x17\xa0\x94\xba\xe8\xf2\xfe\x9a\xd7\x2f\x50\xa5\x7f\x22\x55\xb7\xec\x13\xc4\x4c\xbf\xce\x66\xa9\xc5\x22\x8c\xe2\x82\x1e\xfc\xe7\xfa\x93\x9f\x7c\x7e\x9a\x84\xd2\x89\x3e\xce\x51\xcd\x1c\x51\x8a\xd3\x43\x30\xf0\x09\x92\x85\x3f\x36\xa3\x84\xa7\x99\x8d\xca\x75\x05\x0d\xae\x9f\x86\xd8\xa6\x90\x1a\x2b\xdd\xb2\x2e\xaf\x6b\x38\x59\x32\x08\xdb\x8f\x91\x10\x51\xff\x56\x3f\xae\xf1\xf3\x5b\x02\x39\x10\x2c\x4c\x90\x6b\x03\x77\x34\x03\x7d\xc4\x20\xd6\x38\x9a\x2e\xc2\x90\x39\x1f\xa6\x19\xbf\x4b\xcb\x47\x3e\x1a\x41\x91\xef\x63\x82\xbb\x79\x4d\x36\x74\xec\x22\x4b\x22\x52\xb1\xe3\xfc\xda\xa7\x23\xf5\x2c\x10\x31\x11\xdc\xce\x81\xbd\x7c\x81\x2c\x4b\xf3\x67\xdc\x69\x1c\xe4\xcb\xf5\xd3\x1a\xc9\xab\x36\xbb\xd9\xe2\x61\xfd\xef\xd5\xf1\xdb\x6c\x7f\xc4\xaa\x11\xd7\x23\xa1\x54\xf4\x2b\x70\x7a\xde\xd0\x67\x20\x8f\x30\xb0\xff\x88\x1b\x97\xa9\x73\x9e\xdc\xbf\xdc\x99\x03\xe2\x0a\xb0\xed\xc0\xb1\xb0\x9f\xaf\xc7\x4f\x12\xc4\x11\xd6\x7e\x97\xe5\x20\xf8\x23\x12\x26\x50\x8d\x65\x59\x16\xe7\xa7\xa2\x4e\x7b\xfb\xdd\xe7\xd5\x1e\x82\x0b\x66\xbc\xa3\x33\xc8\x54\xa7\xd2\x39\x94\xd3\xc3\x49\x52\xa2\x0d\x0a\x1f\xef\x74\x75\xb8\x77\x22\xcb\xa3\xa5\x41\x46\xa6\x32\xf3\x5c\x16\x12\xaa\x6a\x67\xa1\x59\x13\x1e\xb6\x90\x4a\x22\xe6\x66\xff\xce\xcf\x2e\x9a\x36\xbc\xaa\x8a\xa2\x80\x38\xd6\xa0\xdb\xac\x98\x00\x5f\x05\xdd\x22\x3a\x4a\x0c\x0a\xcd\x63\x21\x3b\x04\xe4\x1c\xea\xba\x19\xda\x8d\x59\x37\xfd\x90\x5a\x85\x28\xa5\xa0\x4b\x80\xbb\xa2\x6c\x79\x2e\x41\x7a\x61\x82\x21\xaa\x33\xbf\x0a\x2e\x5f\x0f\x85\x4d\x3f\x7f\x86\x58\x94\x5e\x64\xe2\x7a\x3f\xea\xf2\x32\xac\x00\x94\x24\x0c\xc2\x36\x07\x75\x57\x02\xcc\xf2\xf4\xc4\xb3\x66\xe9\xb1\xff\xb2\x62\xe8\x13\x5f\x4d\x92\x58\x09\x23\x1c\x5a\x64\xfb\x96\x96\x08\x24\x49\x0c\xc8\xba\xe5\xe3\xdd\x5d\xf2\x77\x7e\x6d\x9b\xb9\xd2\x36\xf6\x90\xcd\x1e\xa1\x7e\x29\xd4\x68\x5b\x95\x7e\xa0\xb9\xe7\x68\x7a\x9b\x8f\x7c\x32\x01\xd1\x0f\x57\x9d\xf8\x8f\x61\x77\x11\x90\xc8\xad\x1b\xf9\xeb\xf7\x3f\x16\xc3\x6f\x23\x7d\x69\xe8\xb1\x4c\xb2\x1b\x83\xc3\x77\x45\xd9\xda\x3b\x33\x43\x57\xe7\x6e\xd0\x57\x1e\xda\xe7\xe2\xd2\x2c\x6c\x7d\xde\x27\xdb\x81\xfa\xcc\xb3\x95\x8a\x90\xd7\xe8\x23\xb5\xbe\xac\xed\x12\xf8\x80\xab\x39\xcf\x87\x2f\x3c\x88\xa3\xd8\xa4\x26\x72\x5e\xc3\x3f\xb9\x7c\x3d\x17\xed\x85\x43\x9a\xe0\xd7\x40\x43\xc5\x04\xe6\x5c\x0b\x0f\x71\x11\xb2\x0c\xa1\xe9\x9f\x60\x98\xd4\x6f\xc4\x98\x41\x46\x9e\x46\x84\xd4\x19\x09\xe2\x1e\xbb\x73\x44\xd4\x54\x46\x3c\x42\xcd\xef\x8a\x8f\xc1\x6d\x45\x94\x71\x93\xf1\x79\x2b\x5e\x61\x0b\xa5\x85\x0c\x4f\x23\x56\x02\x77\x54\x92\xa0\x33\x67\x09\x11\x26\x3c\x60\x19\xf1\x10\x37\x1a\xf8\x30\x26\xeb\x94\x00\xc1\xf4\x16\x23\x23\xc1\xcc\xab\x02\x3c\x6a\x02\x54\x24\x23\xa5\xa4\xe7\x82\x1a\xa7\x53\x5a\xd7\x80\x7c\xaf\xa3\x6e\x71\x4c\x31\x5c\x08\x2a\xad\x77\xd0\x8c\x61\x59\x7f\x02\x0f\x90\x31\x8f\x11\xd3\x76\xc9\xcf\xfc\x52\xc1\x90\x5a\x09\x64\x02\x3a\x91\xfd\xb1\x6d\x28\x5e\x2c\xc4\x68\x7a\xa7\x96\x3c\x30\x39\x8f\x0a\x8c\x76\xed\xcd\xaa\x3a\xea\x2f\x3c\x1f\xad\x0b\x53\x1b\x92\x42\xe9\x8a\x84\x7f\x9c\xcf\x50\x3e\xa4\xa7\xb4\xee\x17\xf5\x4b\x41\x68\xe2\x59\x43\xe6\x0b\x6a\x43\x90\x82\x32\x53\x73\x68\x84\x1f\xad\xc1\x3a\x7c\x01\x82\x01\xba\xb3\x6b\x7e\xfa\xb6\xdb\x6c\x0e\xed\x45\x62\x65\xf8\x68\x6c\xcc\xa0\xdd\x4e\xf7\x30\xae\x5b\x92\xd2\xc6\x0e\xab\x96\x76\x06\xb1\x3f\x8d\x1b\xba\xe5\xa9\x9a\x8d\x62\x13\x52\x46\x9a\x25\x2d\x75\xef\xb6\x84\x54\x16\x03\x27\x5b\xaa\x80\x23\xfc\xc2\xa1\x8b\xb1\xd8\x60\x56\x6d\xf9\x15\x60\x26\x47\x1a\x4a\x7d\x11\xd5\x9e\x7a\xca\x6d\x41\x97\x54\x11\x45\xc6\xe5\x56\xae\x14\x1c\xa4\x70\x14\x43\x92\x2a\x26\x36\xce\xa4\x00\x4e\x3f\x0e\xbf\x6f\xc6\xa5\x92\xed\x85\x5b\xab\xf9\xd6\x41\x1e\xbe\x26\xa5\x09\xd6\x5f\x96\xbc\x84\xb5\xda\xf1\x56\x1e\x0d\xa4\x8e\x22\xc7\xc5\xf8\x23\xd7\x69\x9e\x56\x2f\xa0\x7a\x62\xcf\xa0\xbc\x30\x41\x36\x92\xd7\xd7\xf5\x62\xd3\x98\xb6\x51\xd4\x36\x81\xb6\xe1\xf1\x4c\xab\x66\xbc\x5f\x64\x9b\xff\x55\x3e\xf3\xd0\x96\x30\x6a\xeb\x9f\x32\x47\x82\xa2\x71\x4c\xfa\x7a\x5e\x2e\x58\x64\x68\x06\x74\x3a\x4a\x45\x04\xdd\x61\xcc\x1e\x36\x30\x0d\x1a\x5f\x12\xd7\x30\x24\xb8\x2f\x8a\xec\xff\xa2\xff\xb8\x16\x65\xc4\x0e\x06\x32\xc6\x93\xd3\x53\xb1\x28\xc2\x2c\x90\xd1\xf1\x3d\x4c\xf0\xea\x4e\x3f\x4c\xe8\x79\x8a\x74\x23\xdf\xd2\x91\xef\x2d\xe9\xfe\xdf\x2b\xcc\x51\x51\x18\x19\xf6\x8b\x66\x1b\x31\xee\x74\x07\xc6\x51\x91\x14\x58\x45\xf7\xbb\xfd\x1f\xf1\x46\xf7\x1e\xb3\x28\xb1\x6f\xe6\xdb\x76\xff\x88\xdc\x54\xc3\x51\xa6\xe2\x28\x32\x18\xe9\xe5\xcf\xf5\x7e\xb3\xdb\xbb\x73\x73\x19\x73\x0b\x2e\x31\x91\x9a\xee\xb2\x82\x47\xf8\x3d\xb9\xe2\x67\xf4\x3f\xfa\x18\x56\x25\x24\x0f\x3b\x45\x19\x78\x2e\x3e\x21\xa1\x06\x25\x20\x31\xd5\x7d\x69\x8e\x3c\x16\x7c\x18\x49\x57\x32\x34\x84\xc0\x48\xb4\x34\xb6\x0e\xbb\x15\x5f\xc9\x58\x4a\xdd\xf3\xd4\x57\xeb\x6d\x14\x45\xb8\x3f\x6a\xde\xa6\xea\x94\x94\x8a\x1a\xc8\xf9\x39\xe3\x12\x8e\xd5\xff\x2e\xbc\x84\x49\xe4\xc4\x70\xd6\x28\x09\x01\x26\xd9\xcf\x97\xea\xe5\xb7\x5e\x77\xdb\xac\x3c\xe5\x75\x75\x38\xd5\xe5\x04\x5f\x0c\x27\x15\x19\xc1\x2a\x4b\x0f\x52\x0d\xc1\x53\x4a\x09\x15\xab\x41\x5c\xdd\x70\xf1\x5c\x7a\xd4\xa4\x2d\x45\x69\xf0\x8f\xbe\x93\xa2\xc0\xa7\x2e\x81\xdc\x5c\xf0\xa9\xa8\x9f\x2e\xd9\x08\x81\xa0\x40\x9b\xb7\x50\xa1\xd6\x52\x5a\xc2\x12\x32\x7e\x1d\x0d\x0a\xd0\x80\x61\x18\x55\xcc\xcb\x82\x2b\xd9\x95\x28\x82\xc7\x05\xd2\x15\xe9\xa2\x94\x1d\x79\x18\x80\x27\x12\x5c\x2e\x97\xbc\xb8\xbf\x08\x1b\x8d\x74\x6d\x52\x20\x58\x0e\x45\xb5\xe7\x69\x77\x2e\xa9\x12\x1b\x39\x6b\x5c\x79\x8b\x89\x9e\x08\xe8\x83\xa7\x0c\xb3\x45\x65\x29\xc7\x6f\x64\xf4\x6c\x3f\x12\x9a\x80\xae\x34\xb2\x01\x08\x43\xde\x5e\xca\x6a\xe4\x28\x01\x51\x5e\x60\xaa\x73\xe4\x16\x4a\xb4\xa7\xdc\x4d\xf9\x09\x38\x18\xa6\x29\x07\xda\x68\x83\x78\xc1\x9d\xeb\xd2\x47\x0c\x82\xcf\xa9\x72\x84\xeb\xc8\x10\xea\xb6\x4d\x44\x39\x8c\x6c\x4c\xf0\xa5\x42\x1e\x39\x2b\xf8\xb5\xd1\xb3\x4f\xf0\x6a\x40\x43\x86\x23\x7f\xf6\xcd\x95\x8c\x02\xe5\x66\x90\xdd\xf3\x12\xe0\xd4\x0b\x2a\x00\x95\x0c\xb7\xcf\xe5\xa5\x2d\x98\xfe\xac\x38\xa9\x77\x05\x65\xb0\x57\xc6\x66\xeb\x5b\x66\x10\x28\x93\xa9\x33\x0c\x6b\x8f\xab\x43\x1b\xb3\xef\x7a\xc4\xda\x94\x0b\x1a\xd4\x46\x33\xea\xeb\x92\xa7\x93\xc8\xe3\xa9\x19\x05\x8c\x70\x4c\xd9\x5a\xba\xc0\x71\x8a\xdb\xf6\x0a\xad\x6a\x3b\x9a\x1e\x5c\xa5\x6d\xfa\x09\x22\x9b\xcc\x84\x52\xfa\xde\xdd\x66\xbe\xff\xed\x53\x94\x06\x24\x20\x10\x0d\xda\xb8\x3e\xe5\x69\x07\x58\xb9\x31\x9d\x05\x06\x1e\x52\x2c\xcc\xfd\xb6\xdb\xfc\x5a\xdc\xcf\xbe\xd4\xd2\x03\xe0\x09\xc7\xc9\xea\x9c\x64\x7f\x34\x1a\xa5\x47\x50\x2d\x8a\x17\xa7\x92\xf7\x80\x61\x20\x83\x00\xfd\x6f\x01\xba\x28\xc1\x2e\x01\x06\x8c\x5c\x8d\xcf\xc1\xbd\x08\x99\x99\xfa\x9a\x1f\xcd\xcf\x1a\x23\xdc\xa9\x5e\xe5\xea\x9b\xf1\xed\x5c\x9b\x8a\x39\x0e\xee\x87\xc2\x60\xc8\x26\x18\xf6\x26\x17\x64\x50\x49\x88\x1b\xe9\xd1\x0a\xfb\x75\x40\x8b\x69\xb3\x11\x80\x18\x42\xb4\x0a\xea\x4d\xb9\xe0\xf2\x05\x0e\x96\x28\xf7\x5c\x94\x35\x94\xdf\x78\xb5\x28\xaa\x71\x76\x0c\x20\xf0\x83\x0e\x3c\x6b\xe8\x71\x06\x81\x59\x00\x96\xa0\xed\xf3\x7c\x81\xa1\x16\x03\x00\xc4\xd2\x67\x3d\x4e\xf2\xe6\x02\xee\xc9\x21\x09\x43\xdd\x33\x20\xcc\x27\xe7\x3d\x41\xa1\xe1\x07\x04\xee\xe3\x3c\x73\x66\x80\x85\xfb\x7f\x25\x6d\x0d\xd0\x2c\x8f\xcd\xfc\x98\x2f\x66\x0f\xb3\x7a\xe0\x6c\x35\x77\x87\xbb\xa6\x09\x7d\xde\xa5\xcf\x2f\x35\x94\x73\x5e\xd7\x26\xd7\x3e\x2c\x16\x0a\xcd\xfa\x4d\xa6\xfe\x8b\xb8\xab\xe9\x20\xc0\xfa\x76\x84\x77\xa0\x26\xac\x67\xb5\xbd\x1f\x0b\x65\x6c\x22\xd7\x33\x34\x01\xcb\xed\xec\x61\xb6\xb6\xa4\x82\xa0\x3d\x5f\x1a\xc9\x3f\x34\x71\x57\xb9\xea\x55\x7d\x6b\x8f\x29\x84\x55\xc1\x1b\x97\x97\xde\xef\x84\xfb\x38\xbd\x4c\xa8\x75\x9d\x57\x26\x91\x80\x15\x32\x28\xb0\x3f\xe0\x2f\x8d\x87\x90\x00\xed\x7b\x1e\x46\x95\x8f\xee\x33\x34\xfe\xdf\x54\xaa\x5e\xd3\xc8\x08\x4a\x37\xbb\x9d\x63\x18\x1a\xd4\x60\x6a\x9a\x08\xe4\x9a\x72\xd5\x88\xc3\xd9\xa1\xa9\xf6\x29\x6b\x63\xfd\x8f\xcd\x12\x04\x79\x73\xab\x9f\x5b\x99\x3a\x60\xa6\x16\x70\x96\x9b\xd2\x33\x43\xfe\x60\x1b\x99\x17\x21\x8d\x1c\x6f\x3c\xf6\x60\x67\x78\x12\x87\xc7\xb3\x88\xa0\xde\xd5\x2f\x5e\xcb\x17\xb7\x45\x98\xa4\xf1\x3a\xb7\x9b\xb6\xa9\x11\xb4\x07\x84\x4c\xda\x7a\x32\xa4\x1c\x1c\x9d\x2e\x14\x31\xf2\x31\xf4\x35\xf1\x6d\x53\xec\xc5\x98\x2a\xab\xde\xd3\x5a\xbe\xb8\x30\x59\xae\x0c\x9c\x7a\x93\xa9\x4d\xde\xf5\xb5\xfa\x48\xcd\x5a\xb4\x2c\xf9\xfb\x8d\xa5\xa7\x63\x46\x0c\xb1\xdd\x6c\x33\xc9\x9b\x38\x31\x41\x74\x1c\xc7\x0e\x0d\xb4\x2f\x64\xca\x33\x9b\xaf\xdd\xbe\x7f\xa9\xad\x00\x3a\xd6\x1a\x97\xee\xc7\xf5\xd3\x71\xfd\xf4\x73\xb5\x3f\x74\xd2\xf6\xa0\x93\x00\x68\xe0\xa0\xcf\x03\x0c\x6b\x2b\x43\x19\xdb\xbf\xbb\xc8\xa1\x4e\x62\x43\xc0\xbe\x80\x0c\x44\xb5\xe5\x65\x7d\xfd\xd6\x7b\x5b\x3c\x60\xdc\x4a\x64\x58\xd3\x6b\x6f\xd7\xc5\xd1\x1a\xf6\x15\xf8\x40\x0b\xcf\x47\x1c\x10\x5a\xdc\x8f\x85\x32\x2a\xe3\xed\xf8\x10\x5e\xd0\x93\x3e\x55\x2d\x11\xf2\x68\xd9\xd6\x22\xf2\x91\xcb\xd3\x2c\x04\xdb\xac\x18\x96\x30\x4e\xbd\x6b\x21\x22\x7c\x29\xc8\xb3\x5f\xbd\x40\xe9\x62\xbf\x3b\x63\xb0\x7e\x52\xa6\xa2\x05\x18\x8a\x11\x71\xb9\xde\x15\xe5\x3d\x97\xaf\x50\x7e\x2b\xb2\x51\x34\x51\x4b\x2f\x8c\xb4\xc3\x89\x94\x7c\xc0\xbd\xe3\xba\xc8\x10\xdd\x85\xd5\x07\x96\xa6\x7e\xa5\xd8\x37\xbc\x05\x45\x4c\xd1\x18\x57\x7f\x59\x18\xe7\x8e\x48\xc0\x97\xfd\x1c\xd1\xc2\x59\x6c\x37\xf1\x70\xad\x54\x80\xca\x07\x6f\x29\xbc\xff\xc8\xad\x33\xb2\x83\x0a\x99\xeb\x3b\xef\xb9\xed\x2d\x51\x95\x90\x97\xf5\xaf\xa2\x7c\x35\xbb\xea\xfc\x3a\x53\xa7\x69\x89\xc9\xee\x3a\x20\x7c\xd9\xf2\x7c\xb4\xfe\x79\x87\xc4\xd0\x9a\x50\x04\xdc\x6f\xee\xee\x56\xbb\x3e\x48\x5a\xeb\xd8\x04\x9d\x76\xf3\xbb\xbf\xc2\xab\x69\xcf\x23\x26\x41\x89\xb1\x99\x21\x72\x62\x84\x58\x9f\x9a\x5b\xda\xf3\x7c\xe6\xdb\x08\xba\xd9\xa9\x2f\x25\x1c\xc5\x25\xcd\xd4\x28\x5c\xa5\x3d\x42\x5a\xf5\x31\xf4\x87\x4e\xa0\x52\x5e\x0e\xcd\x7d\xed\x11\x4a\x50\xdd\xdb\x04\xab\xd7\xf9\xe1\x05\xf6\xd7\xaa\x06\x6b\x6e\x35\x1d\x8c\x90\xf7\xf1\x70\xbf\xf9\xb1\x9f\x3d\x2d\xdb\x06\x16\x38\x8f\xdd\x61\xf3\xbf\x0a\xe3\x6b\x8f\xa8\x08\x6d\x60\xb3\xb3\x1c\x33\x4b\x53\x31\x7c\x40\x5f\x06\x58\xa3\x78\xea\x11\x45\x6a\x8f\x4a\x1a\x18\x3d\xa4\xe2\x5c\x54\x70\xf8\x18\x3d\x6b\x10\x06\xb4\xab\x45\x75\x01\xb2\x7d\x2f\x9d\xe5\x3a\x72\x1a\x82\x8b\x15\x55\xe9\x73\xde\xcc\x64\x63\xb2\x18\x66\x18\xcc\x1a\x0e\x6f\x29\xe0\x1a\x37\x9a\xc5\x66\xb7\xb3\xc4\x8e\x23\x5d\x24\xed\x31\x3f\x0c\x9a\xdd\xec\x77\x7e\x29\x2f\x28\xff\x38\x44\x62\x37\x3d\x04\x06\xd2\x7f\x3c\x3d\x6c\x16\xdf\x8f\x9b\x1f\x87\xf5\xd3\xb7\xdd\x6a\xbf\xda\xfd\x5c\xb5\x7d\x22\x86\x68\x17\x0c\xba\xb5\x3f\x26\x3c\xb0\xc1\x19\x34\x97\x0c\x7a\xe3\xae\xe8\xbb\x2e\xda\x0b\x7d\xc9\xb8\x53\x41\x18\xe1\x03\xb4\x17\xb2\x10\x33\x28\x86\x80\x7c\x02\xd3\xa9\xbd\x30\xa1\xb8\x84\xce\x37\x4f\x3f\xf6\xc7\x87\xd9\x61\x71\xdf\x9e\x3b\x61\xa4\x23\xb9\x30\x5a\x20\x46\x1a\xfa\x0c\xcd\xc6\x70\x13\x17\xd6\x5e\x44\xbd\x48\xb8\x6c\x17\xcf\xb1\x86\xa9\xb8\xed\x44\xd0\x58\xa8\xf9\x2b\x98\x9a\x8b\x4f\x53\xc0\xda\x8b\x78\x18\x52\xc7\x2f\x30\x30\xcf\x5c\x31\x57\xe2\xf7\x13\xeb\xee\x30\xc1\x50\x8f\x10\x21\x40\xfb\xaf\x38\x83\x3f\x49\x0d\xbb\xf3\x48\x89\x01\xb0\xd5\xe1\xfe\xd8\x6c\x6c\xbd\x8c\x99\xf6\x62\x3f\xc6\x4f\x64\xdc\xa6\x01\xc8\xd5\xf5\x08\x24\x9a\x72\x67\x7e\x45\xd2\x9f\x51\x6b\xe2\x27\xa6\xf2\x54\x8e\x07\x5f\x9c\xc4\xd8\x64\x46\x36\xc2\xc9\x1f\xd2\xaa\xc6\x8c\xf9\x84\x34\xb4\xf6\x12\xcf\x88\xd3\x88\x4b\x99\x6f\xcb\xf4\x54\x94\xca\x95\xba\x8f\xae\x9a\x10\x8a\xf4\x20\x8f\xb3\xa7\xfb\xd9\xe1\x30\x7b\xda\xee\x36\xbf\xff\x11\x1e\xee\xf7\xed\x83\x25\xd2\xd4\x25\x1a\x1b\xab\x59\x6f\x77\xbc\x1e\xcf\xa9\x04\x04\x32\x20\x9e\xcb\xe2\xe3\xfa\x49\x32\x6d\x34\xd8\x38\x31\x74\x66\xb8\xd3\xce\x79\x95\xca\x75\x2e\x0b\x47\x6b\xa5\x3d\x1e\x05\x68\xcc\x8b\xbf\x03\x9f\xd7\x1e\x4f\x22\xe1\xca\xe5\x2c\xd6\xec\xa5\x74\xe0\x11\xed\x09\x4f\x61\xdd\xfe\x33\x3f\x59\x0a\xfb\xb6\x85\xc5\x81\x0b\x58\x2d\xee\xad\xf8\x4e\xdc\xb6\xc6\x34\x0a\x1c\x2d\xdc\xb6\x4c\xdf\xd2\x0c\x9e\x41\xdd\x54\xb0\x69\x4f\x24\x1c\x13\x7a\xdf\xb9\x09\x27\xae\x76\x0b\xdf\xfb\x72\x23\x90\x2c\xa4\x7a\xa0\x98\xe5\x82\x5f\xda\x93\xdc\x63\x36\x0c\xf1\x98\xe6\xe9\xb6\x28\xb2\x55\x73\x67\xac\xeb\x00\x58\xe9\x6a\xa3\x09\x87\x97\xb4\x1a\xdd\x90\x94\x26\x8a\x50\xbd\xf3\xf3\x7a\x39\x26\xb5\x19\x4d\x2d\xa9\xfc\xc8\x42\xa6\x16\x37\xc8\xb0\xa6\xb9\x2d\xa6\xb6\x9f\x61\x7e\x6d\xa6\xfc\x58\x2d\x5d\x7b\x52\x47\x18\x2c\xd3\x69\x96\xe1\x08\xad\x30\xe7\xf8\x09\x60\xcb\x1a\x77\xda\x53\x31\xa3\x16\x2d\xfa\x04\xef\xfb\xba\x04\xa8\x7b\xda\x0d\xae\x97\x52\xbe\xd3\x79\x19\x69\xff\x0f\xfa\x01\xa5\x78\xb6\x77\x50\xbc\x9f\xa1\x6d\x5a\x14\x52\x67\xfd\xd8\x2f\x8f\xdf\x36\xb3\x87\xf6\xf7\x28\x44\xab\xfe\x88\x0b\x91\xcb\x34\x58\xf4\x7d\x5f\x4e\x7a\x34\xec\x20\x0e\x91\x98\xa3\x7a\x29\xde\x8d\x8d\xe1\x1a\xb8\x46\x0b\xb0\x18\x91\x71\x7f\xe3\xed\xbd\x68\x9b\x62\x78\x86\xfa\xa9\x50\xe3\x29\xa5\x19\x4d\xa0\x03\xb1\x75\xd5\x2d\xae\x3d\x89\x30\xe5\xe1\xe0\xe5\x1d\x6b\xb2\x26\x5e\x98\x70\x83\x05\x2b\xe5\x0b\x62\xc6\x1a\x0b\xe8\x36\x1e\xa9\x89\xc7\x3d\xa1\x3a\x9f\x7f\xf6\xc6\x6b\x5e\x7e\xe5\xf5\x37\x87\x48\x49\xda\xe5\xa8\x31\x35\xef\x00\x6e\xd4\x8e\x35\x21\x2c\xe2\x6d\xd1\x50\x7a\x39\xfd\xe2\x59\x36\xf8\x9c\x84\xc4\x1c\xa9\x3c\xbf\x41\x0e\xa5\x0b\x43\x4d\x44\x72\x46\x37\x40\x24\x0f\xd9\xb0\x64\xc2\x29\x2c\xb9\x77\x4b\x08\x78\x91\x6a\x79\x6f\x8a\x61\x6d\xc2\xd0\x63\xd5\x84\x26\x94\x04\x56\xf9\x15\xf2\x8a\xd7\xf0\x80\x95\xa6\x8f\x45\xde\xd8\x98\xa3\xe7\xa2\x60\xb6\x2c\xdd\xb8\xf7\xb3\xea\x52\xa6\x8f\x45\xde\xa9\x11\x69\x42\xb5\xf4\x78\xcb\xcf\x7c\xae\xe1\x48\xbd\xe1\x83\x33\x2f\x42\x60\xb5\x68\x7c\xc8\xbb\x34\xcb\x36\xe5\xf7\xd4\xd2\xed\x76\x71\x30\xf6\x9f\x1e\xc8\x22\xfc\xcf\x0d\xe2\xe2\x2b\xa0\x85\x26\x21\xf1\x03\xbb\x82\xfc\x58\x3b\x59\xad\xc1\x5d\x84\xbe\x46\x62\x3b\x13\x18\x68\x81\x8f\x88\xdd\x0b\xdc\xc3\xc4\xca\x50\x3d\xce\xd7\x87\x99\xb3\xfb\x48\xe2\x81\xea\xa4\x8f\x97\xf0\xfa\xe7\xf4\xe8\x4a\x7c\x8d\x9c\x73\x8f\xfc\xbf\x50\xd5\x57\x83\x95\xfe\xe7\x25\x97\x3d\xbb\x89\x24\x11\x40\x5f\xe3\x6b\xcb\xe5\x2b\x7f\xb6\xe9\xd7\x09\x7f\x43\x93\x04\x12\xa4\xe5\x59\x3f\xfd\x9c\x3d\xac\x97\xc7\xcd\x6e\x89\x06\xf9\xb7\xa7\xd9\xe1\xc7\x6e\x35\xdc\x3e\x09\x67\x22\x0e\x5d\xc4\xc8\x5a\x6f\x8a\xb8\xab\xf3\xc8\x90\xb5\xa2\x89\x6c\x03\x1d\xcd\x60\x9e\x5f\xd7\xcb\x3e\x08\x48\x13\x1e\x27\xbe\x70\x5c\xa3\xf8\x04\x6e\xd6\x4d\x5a\x2b\x84\x83\x49\xa1\xdb\xa2\xc6\x3b\x80\x6a\x96\x2b\x53\xe2\xf1\xcf\xc7\xc9\xe8\x92\x26\x5c\x0b\x34\x71\x90\x3f\x15\x83\xec\xee\x46\x85\xaf\x8c\x16\x55\x31\x2f\x8a\xac\xfd\x55\x48\x84\x5a\xec\x2f\x52\x42\x55\x59\x48\xcd\x40\x2d\xfe\x4b\x57\x4c\x13\x49\x5b\x2c\xc3\xfe\xcc\xdf\xf3\xcf\x50\x0f\x4d\x4f\xe1\xa2\xf0\x36\x0e\x80\xb3\xfe\xab\x99\x25\x6d\x0e\xf7\x94\x66\xaf\x73\x17\xf7\x1e\x0d\x12\x45\x63\x93\x53\xc7\x55\xae\xc5\x48\x20\x93\x32\x1d\xcd\x3d\x15\x85\x68\xaf\x08\x23\x46\xd8\xa3\xba\xd2\x04\x3c\xe5\xd9\x2d\xac\x59\x94\x9a\x6d\x67\x71\xa9\xea\x42\xa5\x3c\x1f\x5d\x12\x02\xda\x05\x20\x9c\x00\xc5\x5d\xd1\xb2\xcf\x38\xd5\xf9\xd1\xd5\x81\x1b\xb5\x4c\x21\xa7\x77\x03\x02\xc2\x28\x54\x9c\x2d\x15\xe3\xba\x79\x9b\xcf\xbd\xfd\x87\x80\xf6\xe3\xb0\xe3\xcf\x3c\x14\x96\x6e\x78\xb8\x3d\xdb\xce\x3a\xf0\xb1\x7a\x6b\x7f\x79\x6c\xa1\x19\x9a\xe8\xc4\x40\x01\x6d\x41\xc0\x9f\x25\x8c\xea\x4c\x35\xd1\x3c\xc2\xd7\x54\xd5\x25\xf0\x53\x5a\x5f\xdd\x83\x0d\xf0\x4a\xda\xf7\x34\xb5\xc8\xe4\xeb\xea\xa3\x59\xfa\x3e\x11\xae\xd5\x3e\x49\x24\xd8\x97\xbb\xcd\xf8\xb5\x6f\x02\x8e\x7a\xfa\x54\x63\x50\x11\x6b\xe9\xf4\x65\x1a\xd0\x33\xd8\xae\x7d\x3f\x10\xdc\x2e\x98\x8f\x50\x73\x2c\x98\x28\x87\x7b\x85\xef\x33\xc3\x30\xc8\x95\xda\xd7\x17\xd5\x63\xfa\x1d\xfe\x35\x18\x7f\xbe\x2f\x24\xb2\x7d\x74\xda\x0c\xf6\x0d\xdc\x90\x92\x6a\x9f\xfa\x3a\x8a\x46\x5c\xad\xbb\xa2\xf8\x74\x1e\xb9\xc3\x62\xcf\x99\x46\xcd\x62\x30\x42\x43\xba\x4e\x52\x42\x4b\x8b\x3c\x87\xba\x9a\x30\xb2\x7c\x0a\x0c\xf7\x0d\x05\x3a\xcd\xc1\xd2\xd1\x4f\x6f\xc5\xa3\x7b\x08\x88\x89\x14\xe6\xf0\xde\xb2\x80\x0e\xde\x5e\xe0\x4b\xc4\xe8\xa0\x0b\xd4\xaf\x38\x1e\xde\x41\xc0\x00\x53\xb2\x03\xad\x2a\xd7\x16\x07\x5e\x62\xc2\x16\x2d\x21\x9c\xf6\x03\x08\x10\x74\x9c\x5f\x4e\xe6\x86\xab\xd9\x1b\x4f\x33\x2c\xf6\x87\xc6\x43\x45\xfa\x89\xc9\xdd\xc1\x67\x4c\x38\xf4\xe5\xe2\x85\x37\xc3\x13\x4a\x34\x56\xfa\xb5\xa7\xda\x67\x61\x98\x58\xd3\xf0\x2e\xcd\x60\xb2\x10\x4d\xfb\x2c\x32\x32\xfb\xcf\x50\xff\xc4\x4a\x63\x5b\x44\x31\x30\x0b\x7c\xc6\x29\x02\x63\xb6\x3f\xe6\x0f\xeb\x05\xf2\xc9\xee\x0f\xb3\xdd\xe1\xb0\x7e\x5c\xed\x0f\xb3\xc7\x6d\xdb\x51\x85\xc8\x65\x83\x9c\x50\x1d\xdb\xae\xf6\x19\x48\x8c\x1e\xb4\xda\x73\x77\x70\xeb\xe9\x8c\x9e\x13\x24\xa8\x81\xbd\xd2\x27\x1c\xd3\x7e\x08\x1a\xdf\x83\xb8\x5c\x67\xea\x2b\x8f\xc1\x8f\x48\x84\x31\x90\x1f\x4f\x77\xbb\xd5\xea\xdf\xab\x1e\xbf\xb7\xf6\xa3\xd8\x84\xef\x94\x01\xc0\xac\x3e\xd2\x7a\x18\x75\x1f\xc6\x93\x3e\xff\xcd\x9d\x4f\x82\x93\x95\xda\x67\xc5\x33\xcf\xed\x76\x38\xba\x25\x05\x58\x80\x3d\xbf\xd6\xb0\x32\xfa\x86\x4e\xb6\x52\xfb\xb1\x4f\x70\x5c\x66\xc5\x7b\x3f\xc0\x37\xeb\x0b\x2d\xb8\xae\x01\x4b\x4c\x10\x4a\x17\xc7\x43\x07\x9b\x6b\x4f\xc5\x35\x9e\xea\x85\xe7\x2a\x83\x39\x8c\x67\x6f\x2c\x03\xf4\xbf\x67\xeb\xdd\x72\xb7\xd9\x1e\x91\x29\x12\x45\x96\x16\x6d\xe4\x59\xfb\x49\x24\xfc\xd6\x68\xae\xbe\xa5\x6f\x9f\x70\xa2\x69\x3f\x89\x13\xc4\xea\x22\x65\x11\x4a\x8e\x54\x43\xbb\xc2\x4f\x92\xd0\xd5\x2b\xda\x1d\x64\x7e\x5d\x55\xb2\x2c\xde\x47\x34\x63\xda\xe7\x3a\x46\x76\x93\x8c\x57\xf5\xc2\x01\xb9\xfa\x14\x02\xda\x17\x1e\x04\xa4\xab\x2c\xec\xa4\x42\xb5\x2f\x20\x21\xda\x86\x57\xed\x4f\xd2\x0a\x74\x1b\x74\xa7\x9a\x5f\xf7\x85\xae\xdf\x79\x39\x90\xad\xd7\xbe\x54\x89\xd1\xaa\xba\xa8\xd4\xa8\xdc\x95\x2e\xa8\xe7\xab\x88\x0b\xd6\xcf\x95\xa7\x45\x6e\xf9\x19\x5c\x17\x00\x21\xa9\xd1\x99\xdf\xf7\xeb\x63\x6c\x3b\x25\xb1\x42\x05\xe5\xff\x3f\x8c\xcb\xf0\x85\x53\x22\x25\x06\x91\xb5\x29\xb1\xea\x03\x80\x26\xf3\x96\xb1\x3b\x0e\x28\x16\xf1\x9c\xd2\xdc\x94\xa6\xb7\xc0\x50\x4d\x7d\x69\x88\xa7\xe0\x94\xd6\x77\x97\x7e\x05\xc8\x5f\xdc\x8c\xaf\xc0\x33\xb6\x1b\xe2\xbe\x8e\x67\x0c\x0c\x1e\x5f\x8a\x4e\x89\x40\x53\x1a\xf8\x31\xef\x80\x1f\x45\x86\x1b\x8c\x5d\x06\x77\xf0\xbf\x4b\x5a\x82\xba\xe3\xe9\x28\x15\xa3\x29\xe5\x1e\x82\x6e\x78\x69\x62\x8d\xf6\xe7\x20\xe4\xe8\xb3\x34\x77\xfb\x65\xaa\x56\xd3\x20\x16\x41\xe8\x34\xd8\x5b\x06\xc3\x4d\xde\xe3\x8c\xb6\x3d\x43\xc6\x90\x80\xde\xd0\x9a\xf4\xe6\xcd\xe8\x8c\xa1\x16\x4a\xb6\x26\xd1\x23\xff\xb0\x2a\x72\xbf\x20\xfd\xf4\x08\x40\xbc\xc9\x8b\x29\x6d\xeb\xf9\x9f\x34\x0a\x08\x8e\xad\xc6\x4c\x18\x93\x6c\x7d\xfd\xe2\x23\x50\x28\xfa\xd8\xd5\x39\x94\x29\xbc\x8d\x7c\x63\x1a\xd3\xa4\xb5\xdf\x4c\x9e\xa2\x1f\x90\x71\x2e\x10\x4d\x24\x47\x94\x1f\xd6\xf5\x0c\x26\x2f\x15\x44\x23\xe4\xd6\x68\x8d\x8e\x77\xd9\xa1\x50\x96\x3b\x24\x4e\xb0\x22\xea\x74\xad\x91\xaf\xb1\x87\xf1\x71\x3d\x44\x62\x45\x32\xe5\xeb\xb2\x78\xcf\x2d\x1d\x89\x6d\x55\x1e\xc3\x8a\x22\x84\x11\x0d\xce\xac\x48\x40\x8c\x5a\x6a\xbd\x29\xd3\xe7\x34\xc7\x40\xe9\x17\x9a\x05\x7f\xe7\xaf\x89\xf4\x56\x73\x25\xe9\x5b\xac\xd2\xc3\xf9\x91\x7f\x18\x35\x9e\xd1\xdb\x55\xd4\xf3\xe8\x44\xbd\x9a\x71\x21\xbf\xb4\x86\xa8\x62\x86\x8f\x1d\x23\xd5\xc0\xcb\x7e\x22\xdd\x75\x01\x15\xdb\x9d\x1a\x21\x6d\x96\xa4\x74\xb0\x27\x52\xa5\x3d\x1e\x3b\x1e\x02\xc7\x88\x93\x9e\xc6\x94\x68\x9a\x6a\x5f\x8a\xae\xd6\xf7\x0e\xc0\xe5\xc5\x47\xd6\x06\x6d\x8c\x69\x4c\x52\x35\xd3\x73\xc9\xd3\xec\xea\x48\xb2\xa7\x9f\x44\xb3\x08\xa7\x58\xfb\x16\x0c\x7e\x7e\x7c\x56\x49\x90\x06\xce\xc4\xc5\xcd\xd7\x9b\x5f\x3b\x2b\xa6\x77\x3e\x45\x9c\x32\x22\xf1\x0c\xd6\x7d\x20\x1a\xaf\xa9\x06\x85\x5b\x60\x6d\xb0\x0b\xa6\x20\xd6\xbe\x90\xc0\xf3\x8d\x3e\xc5\xfe\x7e\xb6\x5b\xdd\x6f\x1e\x96\xab\xdd\xfe\x88\xff\xe1\x7a\xf8\x9e\x07\x96\x72\xd8\x8e\xcb\x8d\xc6\x20\xe4\x90\xfa\x73\x70\xff\x81\x1f\x28\x6e\xb4\x18\x2f\x79\x9d\x42\x75\xec\x53\x67\xe8\x80\xc6\x9c\x58\x87\xe6\x2d\x55\xd0\x2b\x68\xbb\x03\x50\x62\xac\x1d\x31\x72\xff\x02\x1a\x2b\x84\xa9\xd8\x5a\x3c\x03\x5c\xf8\x6d\x62\x15\x0f\x82\xc8\x47\x2c\x0d\x1a\xc8\x66\xc9\xb8\xc5\x5f\xeb\x80\xf9\xbe\xf0\xba\x84\x56\x96\xa5\xcf\x90\xa3\x5e\xf6\x28\x9b\xd9\x74\x15\x89\x41\x29\xed\xeb\xa2\x3c\xcd\xd3\x52\x8d\xf2\x31\x01\x0b\x62\xcc\x2c\x76\xd5\xd2\x2a\xad\x7f\x1b\x59\x44\x6d\x58\x3d\x60\x51\x94\x68\x9b\x97\xb2\xfc\x0f\x69\xfd\x92\xe6\x7d\xdd\xdf\x7f\x8c\x6e\x42\x52\xe4\x51\x70\x7a\xb8\x7b\x54\x9a\x99\xb6\xbe\x83\x30\x94\x58\x34\x60\xf4\x85\x0e\xf1\xea\x77\x34\x62\x8e\xfb\x1f\xdb\xed\xc3\x1f\xee\xa6\x63\x9f\x60\x80\xd5\x82\x74\x52\xdd\x85\x42\xff\x3a\xa5\xaf\x83\x18\x4c\x01\xc6\x33\xd4\x47\x9e\x65\xcd\xce\x76\x1a\x0b\x85\xea\x20\x09\x24\xef\xe8\x64\xc6\xd4\x19\x97\x21\x1a\xd1\x1d\xc3\x18\xb1\xc5\x9b\x4e\xc5\xed\x0b\x6c\xb8\x0e\x78\x98\xe0\xfe\x71\x30\x2a\x51\xaf\xbd\x0d\x24\x10\xd4\x43\x6b\xbe\x59\xb9\x1f\x31\x57\xd8\xa3\x66\xd1\x81\x88\x13\x8f\xbb\x72\xc4\x43\xd8\x12\xbb\xb6\x03\x4f\xaa\x90\xd9\x71\x32\xcb\xb2\x03\x64\x59\x8b\x5f\xd3\x81\xf2\x0c\xdd\xad\xf5\xc1\xff\x75\xe1\x59\xcb\x24\x35\xbf\x0e\x1c\x86\x40\x35\x03\xd3\x89\x92\x23\x63\xab\x6a\x53\x92\x81\xd2\x01\x6a\x2e\xf2\x4f\x12\x1e\x93\x5b\x5c\x00\x44\x60\x4a\x41\x1b\x07\x65\x8f\xe8\x0e\xc7\x66\x3f\xe9\xdc\x34\x4e\x96\xe1\x8a\xab\x8b\xf3\xa0\x4e\x55\x07\x20\x8d\x6c\xdc\xf6\x22\x26\x12\x3c\x01\x68\xe2\x13\x87\xec\xc7\x0c\x03\x66\xed\x56\x6d\xc6\x5c\xa3\xe3\xa9\x31\xca\x90\x2b\x7e\xbd\xc3\x3f\xfb\xa6\x69\xa0\x39\xe3\x9d\x88\xf5\xce\x72\x95\x0c\x67\x26\xf3\x88\xc6\x9d\xc5\x46\x25\x2e\xf5\x6d\xcd\xc1\xe8\x80\x40\x45\xfe\xc0\x7c\x5e\xe7\xdb\xcc\x55\xed\x68\x46\x48\x5b\x28\xb6\x84\x37\xc8\x8a\xf3\x2d\x5d\xb8\xeb\x2a\xb4\xb3\x86\xe6\xa9\x5a\xab\xae\xf6\x55\x33\x5f\xf8\xc2\xf2\x99\xa3\x84\xd8\xe5\xbc\xd6\x8b\xc3\x72\x74\xf7\xbe\x94\xda\x68\xcc\xe7\x80\xc4\xb8\xe5\xd5\x45\x08\x19\x25\x7e\x68\x82\x24\x97\xca\x80\xe2\xba\x35\x81\xd1\x98\x1b\x22\x6b\x9e\xe6\x9f\x70\xf4\x68\x46\x21\x46\x50\x49\x75\xe2\x65\xdd\x38\xe8\x50\xd6\x37\x4c\x0b\x83\x80\xf7\xdf\x1a\x49\xac\x19\x82\xb1\xab\x5a\xaa\xe5\x8b\x2b\xf3\x1b\x0c\x1e\xc6\x68\x82\xf1\xb5\x3d\xf4\xc0\xc4\xdd\x49\x58\x28\x7c\x8c\x38\xe6\x12\x8a\x0b\xda\xf7\xdb\xd6\xc6\x65\x2c\x36\xc5\x19\x46\xd4\x75\x7c\xa8\xf6\x13\xdf\xd8\xff\x6f\x50\x36\x2b\x72\x71\x5f\x67\xf2\xb3\x22\xe9\x9b\xbf\x87\xf7\x19\x51\x89\xc1\x33\x07\xa7\xdc\xc1\x1b\xe4\x8e\x2c\x4c\xb3\x28\x0c\x88\xb5\x2c\xee\x8b\x31\xa4\x57\xb3\x38\xf2\x02\x84\x75\x39\xa6\x0d\xcd\x62\xc5\x64\xd2\x33\x92\x7f\xec\x97\x1d\x41\x89\x66\x49\x48\x31\xb2\xdd\x56\xd6\xfc\x51\x5c\x4a\xdc\x49\x56\x6f\xe3\x79\xc4\x78\x00\x22\xe9\x51\xe2\x0e\x2a\xf0\x47\xc3\x91\xeb\x88\x26\x6e\x38\x96\xf5\xcb\x0d\x5d\x84\x66\x82\x52\x14\xc2\x53\xbc\x86\x55\xae\xd6\xb2\x70\x77\x25\x12\x8d\x9f\xe3\x5c\xbc\x43\xe9\x4f\xfa\x50\xad\xac\x95\x3b\x84\x87\x58\x39\x6c\xd1\xb4\x1b\x37\x71\x99\x0c\x8d\x17\x83\xe0\xc1\x4d\x3e\xbe\x09\xe5\x85\xd2\x1f\x28\x7b\xc2\x60\x80\x8c\x46\x9b\xb2\x72\x50\xf2\x85\xa7\x43\xae\x66\xcd\x20\xb4\x50\xd8\x56\x24\x56\x8d\x9d\x37\xdb\x53\x33\x93\x68\xb3\xab\xdf\xd8\x9e\x63\x5a\x72\xac\xe7\x1c\x17\x1d\x35\x2d\x02\x8d\x7e\x7e\xa9\x5f\x0a\x2c\x53\xee\x6f\x6c\xa1\x17\x32\xb0\x4b\xfe\xd1\x12\x3a\x1c\x79\x29\xd2\xba\x3a\x62\x8a\x79\x78\x1f\xa1\xc7\x01\x4b\x7a\x1d\x80\xc8\xe2\x57\xa6\xa9\x39\x74\xe8\x69\x13\x31\x3e\x59\xd9\x72\xa8\xaa\x99\x52\x13\x26\x4a\x48\x3c\x88\x02\xa7\x80\x2d\x33\x5e\xf6\x41\x22\x21\x89\x44\x8c\xc9\xb3\xfc\xd3\x34\x82\xeb\xa9\x04\x92\x87\xfd\x5c\x7d\x9b\xed\xdb\xc3\xb5\xc6\x12\xb5\xd7\xab\x80\xf2\x09\xea\xf7\xa2\x7c\x1d\x59\x35\xa1\x1f\x44\xda\xc9\x81\xbf\xa4\xa5\x0b\xbe\x8d\x50\xad\xb6\x73\xc0\x12\x0c\xae\x65\xbc\xc2\x44\x73\xfe\xdc\x87\x94\x84\x41\x6c\x24\x42\xac\xb2\x07\x86\xd3\xaf\xe3\x53\x70\x8e\x81\x41\x6e\x39\xac\x1f\xfa\xc7\x0b\x5f\x40\x2b\x21\x36\x7a\x42\x46\x35\x1e\x78\xac\x6c\xc4\xa0\x57\x1c\xee\xba\x30\x1e\x76\x24\xa9\x18\x9b\x68\x17\x8f\x76\x11\x0e\x99\x94\x48\x0a\x04\xf5\xcb\xa1\x18\xd1\xf2\xf7\xba\x45\x24\xc4\x12\xa7\x76\x90\x3a\xc1\xbd\xb2\xe4\x63\xe2\x25\x1d\x46\x01\xb1\xf4\xf4\x6a\x5e\x14\xaf\x68\xb9\x59\xfe\x07\x32\x9a\xf1\x61\x14\x24\x71\x47\x79\xf0\x63\x0f\xff\x33\x1e\x80\x6b\x66\x81\x32\xca\xfa\xf9\x40\xbb\x4b\x87\x91\x50\x18\xb3\xcb\x11\x47\x3a\xe6\x5d\xd0\x61\xa4\x01\xb1\x5e\x0f\x9b\x6f\x47\x1c\x6c\xf6\x96\xbf\x62\xae\xd6\x61\xa2\x14\x35\xb8\x66\x64\xc9\x77\x9c\x2f\xa3\xef\xc6\x83\x76\x41\xdd\xf1\x5c\x15\xa7\xf8\x86\xb7\xab\xe9\x64\x92\x58\x0b\x5e\xf3\xac\x78\x76\xe4\x48\xae\x55\x1a\xc9\xef\x67\xa8\x1f\x40\x3d\x43\x69\xc2\xda\x83\x79\xc9\x95\x0e\x62\xc7\x4b\x72\x45\xc3\x60\xb8\xf3\xd9\x7e\x82\x18\x04\xeb\xdb\x05\xb6\xfc\xba\x3a\xdc\x2f\x31\x9c\x34\x98\x3d\x22\x88\x90\xc1\x16\x87\x13\xc6\x07\x5b\xf5\x31\x1d\x4a\x4a\x23\xa3\x94\x5e\xbc\x23\x85\xe1\xf1\x9e\x67\xed\x48\x92\xa1\xa1\x77\x3d\x00\x3f\xf5\xca\x14\x26\x9d\xe5\xfe\xa0\x91\x71\x84\xbb\x84\x09\x13\xf7\xcc\xa2\x50\x8a\x80\x6a\x37\xee\x7b\x2f\x45\x4a\x23\x95\x65\x10\xea\x53\xbe\x60\xa8\xbc\x00\xbb\x98\x69\xb5\x07\x50\x0b\xc3\x2c\x90\x3a\xe5\xa5\x78\x58\xb6\xf1\xf7\x0c\x82\x50\x11\x23\x26\xfe\x70\x79\xbb\xd1\xf0\xd2\xa1\xf2\x3d\xde\x32\x61\x36\x5e\xf0\x5d\xf1\x35\x5c\x2f\x54\x94\x83\x11\x33\xd6\x97\x5c\x75\xd0\x85\x50\x25\x11\x36\x3c\xf2\x57\xf8\x8a\xe5\x64\xd2\x13\x19\x0c\x30\x95\x00\xc6\x3e\x8e\x15\xd4\x35\x56\x46\xef\xa0\xea\xe5\x1d\x42\x25\x35\xae\xa7\xdb\xa2\x5d\x05\x15\xc4\x94\x38\x6a\xec\xe2\x74\xce\xe0\x63\x51\x9c\xc4\x68\xb0\x68\x29\x9d\x55\x68\x6d\xe6\x9e\x5d\x18\x79\x94\x21\x46\x6a\x89\xd2\x10\x28\x9d\x80\x16\xb8\x7b\xc4\x88\x50\x1f\xcd\x26\xfc\xe6\x4b\x38\x15\x5f\x19\x6c\xee\x98\xc0\xb0\x08\x3a\x13\x66\x96\xdd\xc8\xa6\xb8\xf5\x25\x22\xa0\x71\x27\x38\xf3\xc6\x98\x19\x98\x42\x91\x0f\x44\x5a\x4c\xef\xe2\x85\x9f\x86\x84\x42\x3a\xa2\xc4\x8b\xa3\x56\x4a\xe7\x46\x43\x5f\x47\x34\x48\x42\x1b\x0a\x98\xcf\x97\x13\x56\x5f\x44\x93\x5e\xec\xf2\x74\x6a\x29\xe1\xe8\xf0\x81\x68\xa2\xb5\xad\x77\xbe\x2f\x2e\x55\x9f\xc0\x59\x47\x54\x44\xba\x05\x78\xe4\x69\x7d\xbd\x4b\x73\x9e\xcb\x94\x67\x56\x7c\xaf\xed\x17\xa3\x5f\xbb\x3f\xcc\xbe\xaf\x8e\x06\x5c\xf8\xb8\x7e\x3a\x1e\xee\x77\xab\xfd\xfd\xe6\x61\xd9\x76\xd4\x04\x77\xae\x8e\x12\x6f\x36\x1c\x9d\xa3\x67\xd0\x11\xb1\xae\xec\xe6\x3d\x3b\xa1\x5c\xc6\x0e\xfe\xe7\xce\x16\x44\x01\xf2\xde\x22\x5a\xb0\x8f\xf6\x1f\xbd\x8a\x80\x4b\x94\x27\x13\x97\xeb\xea\xf9\xb9\xfd\xfe\x81\x0a\x90\xdd\x55\xd7\x20\x5f\xd2\x3f\xdd\xcf\x8c\x19\x22\x13\xed\x9e\xd5\xc9\x19\xb8\x76\xae\xb1\x76\xc2\x8a\x66\x9a\x35\x0a\xa9\xcf\x5b\xc7\xc9\xf5\x94\x01\x6e\x30\x38\xda\x31\x5b\xd3\x81\x39\x86\x77\xc8\x20\xa1\x5e\x8b\x1b\x5d\x3f\x1d\x56\xbb\x9f\x2d\x74\x29\x0a\xb9\x87\x79\x4b\xae\x94\x61\xd9\x2d\xca\x43\x31\xcd\xb3\xae\xa3\x66\x3d\xeb\xf4\x12\xf7\xe7\xa2\xac\x0d\x58\xe0\xd3\x62\xb1\xe6\x18\x81\x9e\x58\x33\xdd\xbe\x35\x36\x2d\x32\xcd\xe3\xba\xb6\xd9\xcc\xdd\x6d\x44\xbe\x41\xed\xda\x40\xdc\x25\xbf\xa1\xfd\x73\x1d\x93\x08\x89\x01\x97\xe9\xa9\x27\x07\xa7\xa3\x48\x03\x38\xa1\xf9\xc2\x68\x0d\x20\x68\x19\xaa\x1a\xcd\xf6\xe1\x14\x49\x02\x0f\x83\x31\x0f\xc5\xf3\xfc\xf2\x49\x0c\x2f\xe2\xd2\x60\xa4\xea\xa2\x79\x19\x86\x38\xb3\x28\x07\x21\xae\x88\x83\x82\xc4\x66\x57\xcc\xd3\x4f\x9f\x4b\x70\xc0\xf5\x00\x01\x86\x48\x36\x3f\x68\x96\x2a\x8c\x5b\x9a\xed\xe6\xb5\x3a\xd6\x6f\x1b\x2c\x1b\x0d\x3a\x15\x24\x0e\x32\xff\x73\xbd\x1d\xbd\x21\xc5\xcc\x2d\x59\x79\xcc\xdd\x62\xda\x22\x8f\x54\x1c\x61\x29\xcb\xb6\x48\xab\x3e\xb1\x8d\x8e\x14\x57\x21\xef\xc9\x14\x7d\x95\x55\x8c\x20\xf2\x62\xcb\x63\x9c\xa7\xff\x1b\x9c\x07\x04\x73\x9c\x52\xf7\xc5\xfb\xe3\x45\xbe\xfc\xc8\xeb\x34\xb3\x6c\x76\xc7\xd1\x43\x69\x69\x24\x12\x17\x0f\xeb\xd5\xd3\xe1\x78\x58\x3f\xae\x8e\x87\xcd\x71\xb9\x5a\xac\x97\x2e\x4c\x19\x7b\xc4\xc7\x7d\xde\xc0\x62\xb8\x68\xeb\xad\xc6\xc0\x90\xd8\xa3\x8c\xd8\x05\x7c\x53\x1a\xd0\xa6\xe3\x17\x73\x7f\xdf\x01\xfc\x4a\x73\xd5\xe2\x3c\x63\x42\x18\x12\x55\xd5\x03\x0e\xd5\xc1\x6d\xc6\x24\x32\x92\x49\xf5\x3a\xaf\xea\xde\xb2\x19\x13\x91\xb8\xca\x25\xcb\x39\x3f\x3d\xae\x62\x3f\x01\xb0\x36\xcd\x8d\x8b\xe6\xba\x68\x8d\xf9\xbc\xb4\xb2\x95\x3d\x23\x7e\x17\x1d\x53\x6d\x32\xa7\x75\x7a\x02\x4b\xab\x3f\x7c\xfe\xc0\x8b\xd0\xf8\x55\x70\xe2\xb9\x3a\x94\xe9\x88\xb9\xb2\xe9\x21\x1d\x24\xe9\x31\x7d\x2e\x91\x1d\x62\x32\xd7\x1e\x07\xc4\x30\x22\x1d\x79\x8f\xe3\x6b\xfa\xe1\x18\x51\x18\xa8\x9e\xa7\x39\x5c\xca\xbe\x6a\xa2\x8e\x59\x14\x62\x50\xb5\x59\x53\x6d\x44\xde\x24\x39\xda\x52\x24\x1d\x87\xd4\xa8\x2d\x5c\x5a\xb1\x11\x1d\x87\xb1\xc0\xd0\x36\xb2\xbe\xef\xd3\x5c\x82\xef\xb5\x6d\x42\x21\x25\xc2\xfc\x72\x6d\x96\xc9\xbb\x22\xcb\x1a\xdf\x77\xf4\x00\x91\xdd\x89\x50\xb0\xd8\x45\xee\x6d\x5b\x4c\x23\x9c\x7b\x8b\x66\x3f\x44\xb8\xdf\x46\x77\xe4\x4b\x83\x75\x23\x8e\xad\xaf\x60\x54\x3e\x66\x59\xb6\x2d\xb2\x0c\xb7\xb5\x51\xdc\x24\x4e\x98\x47\x49\xaf\xf6\xec\x53\xe4\x78\x1b\x02\x8d\x93\xd0\x60\xb4\x4a\xa3\x25\x35\xfa\x5a\x22\x31\x1f\xfc\x19\x0c\x3b\x45\x4f\xd0\x5f\xc7\xd2\xe7\xb8\x21\x8b\xc6\xfd\xf2\xfc\x76\x40\xab\xc0\x33\xe1\x5e\xd4\xd4\xeb\x1c\xa4\xe1\xbd\x2a\x4e\x70\x0f\x33\x76\xdd\x90\x96\xf8\xa6\xe0\x69\x78\x57\x4a\x05\x2e\x96\xba\x39\xa7\xf9\x0d\xea\x29\x06\xdf\xf0\x19\x3f\xa4\xf9\xeb\x60\x30\x40\xe8\x23\x72\xfa\x5b\x09\xd0\xf1\x44\xdb\x46\x2d\x18\xaa\x37\x41\x29\x7d\x9f\x7e\xe6\x5d\x7f\x72\x4f\x5a\xc6\x60\x0b\x39\x9f\x0a\x03\xcd\x32\x25\x07\xdf\xe1\xfa\xfb\x27\x13\x4e\x43\x88\xe4\x57\x8d\x55\xb1\x3a\xfe\xb1\x9a\xed\x8e\xdf\x57\xab\x6d\xab\x0c\xad\x63\xad\x95\x2b\x57\x3d\xda\xac\xb7\x8b\x10\x9c\xc6\xc6\x72\xe2\x79\x46\x72\x34\x87\x8f\x1a\x49\xd1\xb6\x45\x91\xb9\x0c\x86\xed\x43\x7d\x85\xcf\x78\x74\x72\xad\x86\xa9\xa2\xfe\x7b\xba\xab\x3a\xa1\x2c\x41\x88\xa6\xec\x88\x41\x5d\x4b\x92\x30\x65\x09\x56\x9e\x8a\xba\x2d\xb4\xd7\x09\x15\x89\x5b\x7a\x1a\xc3\xed\xd2\xd8\x5d\x37\x3a\xdb\x3a\x09\x98\x19\x4e\x3d\xf2\x94\x21\x11\xcc\xf0\x4e\x18\x4b\x0c\xc9\xac\x91\xe5\x46\x1c\xea\x8f\x73\x57\x27\xed\xba\xc5\x24\x30\x5a\x53\xf9\xf3\x03\xb4\xb6\x52\xc2\xb8\x17\x58\x01\xb9\xcf\x72\xf6\xae\xa7\x52\xb8\xc9\x57\x2f\xc5\x79\x5f\x17\xa5\x8d\x38\xb9\x56\x48\x9c\xa4\x0f\x42\x40\x96\x65\x71\xae\xc6\xfb\x42\x12\x12\x8e\xcc\xb5\xbb\xd9\x61\x75\x3c\xac\x57\x3b\xea\x8e\x0f\x7d\x11\xf9\x3d\xae\xce\xcf\x61\x6a\x49\x18\x7a\xa0\x2c\x45\xce\xa1\x40\x6e\x6e\xd7\x12\xc7\x88\x7b\xd9\xf2\x8b\xdd\x55\x47\x11\x96\x24\xe4\xc2\xca\x55\x98\xec\xf4\x8f\x66\xbf\xef\x18\x53\x75\x12\x0a\x23\x55\x6e\xac\xac\x27\x78\x9f\xd2\xbc\x6a\xba\x49\xcf\x6c\x85\x46\xd9\xaf\x8f\x4d\x20\xe1\x3f\x86\xff\xe9\x8e\x91\x4a\xa9\x7e\xd4\x72\x5b\xc2\x2d\x9b\xb6\x4e\x42\x05\xd2\x24\xab\x70\x5f\x30\x8e\xfb\x92\xd7\x9c\x8c\xa3\x96\x7f\x59\x05\xf3\xf7\x06\x73\x08\x1e\x46\x3d\xdf\x0d\x95\xbe\x71\x01\xda\x11\x12\xea\x00\x47\x4e\x9d\x42\x49\x1e\x1c\xc9\x4f\xf3\xbb\x29\x1c\x41\x3a\x38\x95\xd6\x33\x24\xe4\xc1\x18\x94\xad\x04\x9e\xbe\x5a\xd4\xfc\x9f\x43\xd4\x0c\x69\x44\x75\x12\x27\x89\xc1\xad\x5c\xeb\x97\x22\xef\xd9\x98\xcd\xac\xf2\x6c\xc4\x7c\x0b\xc5\xb9\x3b\x24\x69\xac\x68\xcb\x11\x06\xe5\x12\x6e\xfc\x36\xd7\x8f\x27\x8e\xde\x64\x5e\x94\x65\xf1\x6e\xf9\x02\xe7\xd7\x8d\xf8\xaf\xcd\x42\x39\xc4\x70\x92\x88\xc8\x94\xce\x98\xaa\xe0\xae\xf4\xba\x69\x8a\x7d\xcb\xd6\x3a\xbf\x94\xb9\x55\x33\xfb\xd2\x1b\x4f\x44\x24\x64\xec\x2a\x66\x4c\x98\xab\x97\x33\x4b\x84\x36\x61\x60\xd3\xfc\x71\x07\x30\x5a\xae\x84\x56\x68\x2e\x6e\x7e\xae\xf7\xf3\xcd\xe6\xfb\x6a\x69\x9c\x31\x03\x95\x72\xbd\x24\xf3\x99\xc1\x6f\x16\xe5\x30\xc4\x9a\x48\x26\xb0\x98\xdc\x06\x9a\x8f\xe7\xe1\xf9\x55\x10\xa3\x5d\x75\x3f\x7b\xb8\x43\xe3\xaf\x6d\x88\x8c\x94\x4f\x63\x3a\x1b\x6f\xc3\x35\x00\x41\xee\xdc\xa3\x99\x85\xfd\x64\xa1\xed\x01\xdc\x78\xc2\x3a\x4b\x9f\x5f\xea\x65\x91\x0f\x84\x29\x74\x02\x02\x3c\x1b\xd3\x58\x16\xc6\xff\xef\xaf\x28\xdc\xa3\x91\x0c\x7a\x94\x00\x8f\x69\x5e\x37\x6f\xa6\x2c\xce\x5f\x23\x19\xb8\x17\x51\x24\x1a\xe0\x4a\x61\xf0\x6c\xd4\xca\x03\xd4\x88\x3a\x22\xcf\x4d\xfe\xc6\xab\xc1\x7d\x71\xe2\x19\x12\xf3\x67\xa8\x55\x2b\xa3\xac\x39\x21\x4a\x39\xf6\xc3\xb4\x54\x45\x79\x1e\x02\x57\x7a\x91\x27\xee\x7b\x1c\xd5\x74\xd3\x0a\x39\x5a\xda\xcd\x81\xfb\xd4\xe8\x69\x3f\x43\xbd\x96\xc5\x12\x74\xc6\x3b\xcc\x1d\xf7\xa5\xc0\xd4\x27\x5a\x20\x6a\xaa\x3c\x86\x53\x65\x20\xab\x15\xd4\xfb\x83\xc3\xe7\x0e\xde\x3b\xa7\x00\xba\x4f\x00\xe9\x96\x58\x1e\x78\x21\xaa\xa4\xcd\x91\xbb\x62\xf1\x92\x9e\x91\x81\x61\xf0\xf0\x01\x35\x39\xc9\x67\xa8\x67\x65\x6d\x4a\xd5\x3a\x3d\xf5\xe1\xa8\xe6\x41\xcc\xb1\x90\x29\xad\xf6\xfc\x04\x4b\x3e\x4d\x17\xa4\x79\xc0\x19\xb5\x27\x45\x16\xc2\xf9\xe8\x8b\x04\xca\xc3\x48\xe5\x91\xbf\x41\xc9\x9f\xd1\x5c\xfb\x22\x9d\xc1\x19\x49\xb4\x8d\x80\xf4\x44\x69\x34\x0f\x99\xc2\x31\xf9\x6b\xf7\xd0\xb7\x76\x78\x18\x25\x98\x6c\xb3\xea\xbd\xa3\xab\x87\x3c\x44\x0d\x28\xe9\x82\x8f\x53\x64\xd2\x9a\x87\x92\xeb\xd0\xf1\x77\x76\x01\xe5\x71\x39\x16\x0f\xa5\x42\x65\x1c\x8b\x3f\x5b\xd5\x2f\x3f\xaa\xf1\x25\x23\xa0\x38\x51\xcf\x19\x28\x44\xbe\x8c\xb6\x00\x1e\x47\x1a\xe3\xdd\x06\x51\xf7\x85\x3f\xc3\xe3\x38\x42\xdf\x1d\xe5\x1e\xce\xbc\xaa\x3e\x53\x86\xd0\x3c\x89\x7c\x30\x34\xbc\x1f\x2d\xaf\xe1\xaa\x6c\x07\x78\x92\x04\x26\x6b\x7b\x46\xd5\x50\x8c\x07\x57\xf3\x2b\x96\x72\x0d\xaf\x99\x24\x0a\x01\x2d\x98\xb9\x4c\xf3\xe7\x23\x86\x91\xaa\xf6\x44\x82\x29\x13\xc2\x02\x75\x14\xbc\x82\x63\x1f\xec\xcf\x13\x08\x94\xec\x86\x58\xb3\xd5\x6c\xde\xdb\x56\xee\x2b\x16\xb8\x4a\xd8\x13\xac\x32\x7e\xae\xba\xf9\xc3\x63\x8e\xa2\xaf\xb6\xee\x0e\xaf\x7b\x37\xae\x4c\xe5\xc2\xb7\xc2\xed\xf0\x3e\x24\x53\xfd\x64\x3c\x09\x5f\xa2\xfd\x69\xa3\x24\x77\x65\x91\xd7\xad\x4e\x9d\xe6\x32\x32\xf8\xce\x67\x93\x3b\x34\xab\xdd\x7a\x24\xe7\xab\xb9\x4c\x24\x46\xee\x30\x65\x87\x39\xac\x5f\x90\xee\x78\xda\xbb\x7d\xc9\x63\x4b\x48\x6e\xd7\xcc\xc6\x78\xb1\x02\xa2\xd3\x3b\x07\x57\x81\x17\xf0\x0e\xa8\x39\xc2\x88\x8f\x1e\x44\x31\x19\xf3\xee\xf5\x18\x3e\xa6\x2f\x03\xba\xee\xc0\xc4\x60\xa6\x97\xfb\xc3\xb1\x83\x88\x73\xa0\x3e\x73\x60\x3d\xfe\x81\xbb\xfc\x24\xf3\xad\xe6\xc0\x03\x14\x4c\xbb\x2b\x79\xfe\x6a\x61\x21\x90\x93\xf6\x44\x8a\x26\xa1\x0b\x7b\xfe\x2c\x1a\x2b\xe3\xae\x28\xf7\x90\xab\x5f\x90\x36\xae\xe3\xea\xc3\x04\x9f\xdc\x01\x3a\x31\x21\x29\xbb\x5f\xdd\x7e\x63\x0d\x10\x18\xc0\x5e\x5d\x17\xfd\x7d\x43\x78\x2c\x42\x00\x4c\xab\xac\x8f\xa1\x82\x3a\x1d\xf2\xe8\x0c\xce\x26\x3c\x4e\x65\xcb\x6d\x6a\xf2\x0c\x58\x6c\xd4\x9e\x53\x99\x8a\xd7\x67\xa4\xff\x75\x6a\x2f\x7d\xa5\x63\x67\xe5\x09\x92\x28\x04\x50\xaa\x22\xcb\x78\xd9\x71\xdc\x68\xe1\x43\xc0\xd4\x98\x15\x71\xf8\x58\x82\x7a\x0a\xb3\x84\xf5\x87\x9b\x4e\x82\x12\x1e\xf2\x8e\xfd\x6c\x5b\x16\x75\x61\x2f\xf9\x8f\x71\xbe\xe1\x33\xcd\x42\x2d\x68\xc0\x7c\x2b\xf4\x99\x15\xd7\x7d\x0d\xe7\xbb\xc2\x49\x8e\x68\x41\x15\x15\xa4\xa3\x9c\xbd\x4f\xab\xdb\x8d\x45\x50\x6d\x4a\x0c\xd0\x4a\x59\x19\xad\x60\xb5\x6d\x4c\xd3\x11\x2d\x81\x08\x42\xc5\x5a\xe6\x7b\xa3\x39\x55\xa3\x16\xdc\xe0\x4d\x05\x42\x82\x53\x66\x73\xc5\xb1\x22\x80\x98\x9a\x62\xec\xba\xbc\x36\x86\x0c\x7f\x1e\xc5\x0f\x45\xa0\x19\x02\xdf\x56\x87\xfb\xc7\x9e\x85\x28\x18\x8b\x1d\x9d\xff\x04\xa7\x57\x30\xba\xc7\x30\x22\x08\x2a\xbc\xd4\x7a\x8f\x53\xc1\xe2\xaf\x7b\x04\x85\x5a\x44\x61\x80\x38\x84\xc2\x94\xf7\xb9\x5f\x35\x51\x91\x23\x2c\xaf\x6a\xa3\xb2\x6c\x0d\xc0\xd6\x6e\x16\x71\x1c\x50\xd9\x02\x99\xfa\x25\xc2\x82\x87\x31\x5a\x97\xe7\x5f\x2e\x9f\x39\x7a\xd5\x32\x02\xd2\x31\x79\xe1\x5c\xea\x34\xf0\xa6\x16\x77\xa1\x3c\x86\x11\x75\x03\x16\xee\x28\x69\x26\x52\x3b\xee\x08\xee\x11\x1b\x86\xdd\x42\xce\xb3\xfa\xba\x4c\x2b\x71\x29\xab\x2f\x7c\xfd\xe1\x5d\x02\xf5\xb0\xb0\xc7\x4c\xdd\x4e\x46\x66\x78\x1d\xe0\x31\xa6\xef\x6c\xf8\xea\xfb\xb5\x27\x85\xed\x52\x2a\x42\x87\x90\x68\x87\x2c\xb5\xcc\xef\xed\x07\xd7\xa1\x16\x16\xae\x8f\x5c\xc9\x36\xdf\xf3\xc0\xab\xda\xfe\x73\x0c\xdb\x97\x1e\x00\x71\xcc\x7e\x28\x2f\xff\xb8\x58\x5c\xca\x5b\x16\x03\xe9\xc7\x3a\x8c\x1d\x79\x66\x57\xe6\xa1\x6e\x22\x9b\xc3\xb7\x27\x7d\x45\x85\xa5\xa2\x98\xf3\x0a\xdc\xfa\x75\xfb\xfc\x92\xea\x80\xb4\xf9\x9a\x22\x53\xc5\xfb\x68\xf1\x94\x81\x60\x18\xb0\x78\x49\x9f\x5f\x70\x4b\xc3\xc1\xd2\x37\x6d\x24\x8b\x0c\x81\x7b\x73\x33\x16\x53\xd5\x4b\xb6\x4b\x96\x40\x68\xa3\x89\xc7\x89\x5b\x60\xdc\x48\x9d\xa2\x65\xe3\x20\x81\x53\x3b\x88\x0c\x29\xa0\x11\xb0\x42\x94\xf4\x5f\xc5\xa1\xa6\xfd\x49\x19\xc5\x52\xdb\x08\xf9\xb1\x34\xb5\x50\xae\x85\x07\x06\x27\xff\x51\x97\xfc\x58\xa7\x27\x38\x8a\xe2\xf2\xfc\xd2\x3e\x48\x1c\x44\x56\x59\x14\x55\x0d\x06\x20\x6d\x99\x90\x90\x52\x17\x5b\xaa\x1f\xa0\xaa\x0e\x2f\x7c\xfc\x32\x13\x16\xe3\x86\x79\x32\x35\xd7\xfb\x33\xcf\x51\xd8\xc3\x35\xcb\x04\xbf\x46\x6a\xe3\x3d\x1b\x3d\x5c\x5d\x24\xa7\x04\x91\xe7\x25\x7f\x9f\x5f\xae\x37\x8d\x7e\x62\xc0\x8d\xfc\x7d\x5e\x14\x18\xcd\x74\xa1\x03\xc9\xb9\xe2\x3d\x12\xb6\x65\xfa\xb6\xf8\xbb\x65\x60\x52\xf8\x09\x0e\xc3\xd7\x34\x7f\xde\x9f\xd3\xb2\x25\x10\x91\x22\x01\xdf\xce\x0c\xc3\x89\x8b\x62\xf6\x9d\x3f\x2a\x25\xf5\x90\x36\xc7\x7e\x57\x5b\x4e\xaa\x2f\x9f\x0a\xb2\xb8\xe3\x12\xf0\xec\x2a\xb6\xbc\xe6\xfc\x94\x4a\x44\x53\xf4\x8a\x30\x24\x28\x0f\x15\xb1\x36\x39\x7c\xff\x92\x55\xc8\xf6\xd7\x44\x53\x83\xca\x7d\x03\x9e\x99\x75\xf1\xb7\x61\x8f\xd8\x47\xe2\x53\x28\x79\x05\x3b\x0c\x9e\x0c\x5f\xb1\xf2\xac\xe2\xcd\xd9\x28\xa1\x18\x6c\xb9\xa1\x54\x19\xdc\xbf\x22\x8c\x24\x76\x7d\xfd\xc9\xb3\x54\x39\xcb\xc4\xe8\x10\x2d\x3b\xd7\x4d\xf9\x54\xe1\x3a\x35\x90\x71\xfe\x74\x6c\xff\xff\xfe\x3d\xf8\xa0\xca\x07\x60\x16\xa1\x65\x36\xa3\xc6\x1c\xe1\xb2\xde\x5e\xc4\x77\xb8\x4e\x3b\x54\x8a\x26\x81\xab\x84\x7b\xe4\x06\x79\x40\xfc\xd8\x2d\x92\x8a\x2a\x82\x7e\x6d\x91\x67\x86\x15\xa9\x5a\xf0\x7c\x59\x20\x81\x84\xed\x12\x28\x53\x8f\x79\x84\x53\x5a\xaf\xca\xb2\x28\x47\xaf\x37\x24\x86\x5f\x01\x49\x6e\x2c\x14\x65\x0c\xfa\x9b\xf8\xb4\x2a\x24\x49\x60\xa3\x1e\x97\xf3\x68\x4c\xb7\x37\x18\x06\x2c\x21\x2e\x85\xb3\xc8\xd2\x6e\x85\x52\xa1\xa0\x9d\x18\x2d\x6b\xc3\xae\x46\x86\xcd\xc6\xd8\xec\x9a\x7b\xa3\x28\x45\x5a\xd1\x34\x64\xba\xc7\x48\x08\xcf\xd5\xe1\x05\xcc\x10\x5b\xb7\x8f\x1f\x6a\x23\x60\xb2\xd8\x6d\xf6\xb3\xf5\xee\xb8\xbf\x5f\x6f\x8f\x3d\xa9\x2e\xad\xa2\x88\xa0\x81\x85\xa8\x5a\xac\x97\x6f\x2d\x5a\xd7\x23\x89\xd1\x16\x3a\x54\x69\xfe\xbc\xe4\x7d\x4f\x52\xc5\x24\xf1\xc3\xd6\x20\x76\x00\xb4\x25\x9c\xc7\x85\x42\x2a\xa6\x89\x0c\x1d\x44\x47\x88\xb4\x5e\x3e\x7d\x1f\xec\x6a\x2a\x0e\x08\x82\x78\x06\xb8\x20\xbb\x9f\x7d\x86\x0f\x52\x71\xcc\xf1\xa0\xea\xfc\x59\x9e\x6b\xf8\xd9\x12\x99\xe0\xeb\x5a\x7d\x9c\x8b\xea\x52\xc2\x22\x2b\xaa\x89\x2f\x3e\xb9\x28\x29\x11\x49\x14\xe8\xde\xd5\x62\x77\xe6\x9f\x64\x6a\x95\x48\x88\x61\xb3\x40\xc4\xfb\xec\x71\xf3\xe3\x09\x9d\x88\xe3\xfe\x30\xfb\xb6\x22\xc7\xed\x6e\x75\xdc\xcf\x1e\x56\xce\x19\x50\x02\x7c\x0c\x0c\xd9\x74\x73\x63\x20\xf2\x29\x19\x92\x29\x02\x01\x25\x2d\xd6\x28\x95\xc5\xa2\x28\x47\x1b\x9d\x92\x81\x01\x3a\x1e\x11\xf4\x6d\xa2\x3b\x16\xa3\xd7\x0a\x21\x5d\x3a\x1c\xe6\xcd\xa2\xa8\x24\xa3\x3a\xec\x05\x9d\x06\x36\xfa\xe8\xc1\x25\xd3\xe8\xf0\x3d\xa4\x6f\x50\x9e\x8b\x22\x7b\xab\x1e\x79\xbe\x48\x6b\x97\xdd\x52\xca\xef\x95\x46\x6c\xb4\xcb\x8d\x8f\xa6\x24\x44\x86\xf7\xac\x36\xa2\x99\xb6\xfa\xd5\x9d\x43\x07\x12\xb7\x9c\xb5\x04\x51\x8c\xd0\x48\x4a\x87\x81\xec\x98\x78\xfa\x51\xcd\xf6\xf0\x98\x63\x45\xd0\xcf\x87\xc3\x50\x67\x42\x2b\x2d\x55\xd0\x15\xc0\x58\xb1\xc8\x9e\x7a\xa2\xe9\x06\x1e\x51\x34\xee\xbd\x12\x5b\xdd\x3c\xb8\x11\xf0\xc2\x24\x36\x01\xce\x2e\x70\xf2\xa5\x91\x00\x9e\x50\x48\x40\xa6\x9b\x41\xdc\x56\x1e\xff\xe6\x5a\xb5\x36\x46\x13\xaa\x31\x59\x29\x83\x47\x28\x5f\x0d\x1d\xe7\xb0\x18\x30\x0c\xfe\x71\x83\xbf\xe8\xfe\x35\xc6\x2c\xb7\x3d\xfc\xff\x4c\x8a\x92\x59\x8f\x09\x7c\x20\x8c\xb7\x50\x9d\x54\xbe\x7e\x56\x80\x07\xbe\xf6\x90\x2d\xd6\xd0\x25\x6e\x76\x7b\x57\xc2\x6a\x09\xc2\x1c\x4a\x06\x82\x48\x22\x72\xa9\x59\x9c\x31\x48\x3b\xcb\xd5\xb6\xc5\xcd\x43\x10\xe9\xc8\xeb\xdc\x6d\x53\x55\x35\xbc\x14\xf3\x04\x2e\x2b\x82\xdb\x04\xc7\x37\xa8\x7b\xc8\x68\x60\xc4\x08\xbe\xfd\xe4\xd9\xeb\xb5\x4c\xc1\x02\x4d\xdb\x66\xe9\xe3\x0d\xfc\x4c\x55\x9e\x7e\xb4\xbf\x6a\x86\xa0\xa4\xc5\xe2\xf7\xfe\x6a\x07\x21\x11\xa6\x2c\xd9\xc8\xe8\xf6\x5d\x18\x08\xb9\x12\x56\x56\x78\x8a\xb9\x78\x6a\xee\x42\x44\x00\x67\xa7\x8b\x4c\x36\xae\xe6\xae\x6f\x1f\x42\xe4\x1b\x26\xb8\xe5\xea\xe7\xea\x61\xb3\x5d\xed\x86\x15\x34\x10\x25\x46\xad\xbb\x7a\x29\xde\x8f\x6e\xbb\xe0\x6e\xf0\x1c\x75\x51\x1e\x11\x3e\x98\xe6\xc7\xd5\xe1\xfe\x08\xff\xbb\xa4\x6f\x3c\xeb\xb6\x21\x88\x89\xc6\x22\x45\x8e\xc1\xcd\x6a\x56\xe2\xeb\x69\x9f\x2a\xf6\x83\xc0\x22\x47\x57\x56\x7e\xd1\x31\x09\x7e\xb9\xdd\x43\xcc\x58\x68\x64\xae\xbf\xe1\xb7\x6f\x4f\x18\x69\x84\x36\xe3\x52\xed\x5c\xb8\xaf\x49\x3e\xdc\x91\x82\x60\x19\x9d\x59\x25\xab\x22\x53\x29\x94\x25\x9c\x33\xc8\xd3\xea\xa5\xbc\x31\xf2\x21\x16\x81\x34\x98\x83\x0c\xea\x09\x56\x1f\x88\x95\x87\x18\x0f\xd1\x93\xaa\x75\x39\xbf\xb2\x0d\x52\x41\x22\x25\x3e\x4a\x33\xe9\xee\x8b\xaa\xfe\x8a\x53\x57\x03\x67\x11\x82\xb1\x7b\xe5\x6a\x9f\x22\x06\x41\x08\xc3\x07\xf9\xab\x28\x33\xb5\xb8\x9c\xfb\xba\xba\x83\x7d\x0b\x04\x44\x08\x6e\x6e\x86\x17\x7c\x8c\x09\x23\xa6\x6f\x45\x6a\x1f\x13\x33\xcd\x0b\x78\xe6\x35\x74\x72\x30\x43\xcb\x11\xa4\x4e\x30\xc1\x76\x0f\x59\x8b\xf4\x05\x45\xa4\xa9\x62\xaf\x06\xb4\x4c\xc3\x4b\xa8\x90\x13\x83\x24\xe2\xa7\x66\xa1\xeb\x01\xae\x41\x25\x1c\x33\xa0\x83\x94\xde\xe8\x16\x15\x08\x6d\xf5\xf6\x37\xba\x97\xb9\x04\x20\x54\x4b\x87\x28\x9b\x2a\xda\xea\xce\x01\x7e\x40\x5b\x90\x6a\x35\x51\xdc\x0d\xc0\x28\xde\x89\xb3\x77\x1f\xd2\xd7\xcf\x3e\x1f\x84\x54\x19\xe7\x54\x5e\xca\xb4\x4e\xe1\x26\x67\x0b\x20\x08\x06\x15\x51\xd9\xef\x5f\x17\x28\xaf\xfb\x6e\x42\x69\x4f\x78\x08\x33\xda\xaf\x1f\x10\x38\xd4\x5b\x3f\x34\xa1\x06\x82\xf4\xe1\xb7\xbf\xd8\x1c\x72\x0f\x78\x6a\x6b\xdb\x41\x19\x49\xb4\x8f\x73\xfa\x89\xec\x80\xd6\xbe\x90\xc2\xf1\xdd\x34\x96\xdb\x17\x6f\x5a\x53\xcf\xa8\x61\xe7\xf0\x51\x3f\xa6\x79\xbd\x2d\xaa\x2a\x15\x19\xf4\x3c\x27\x4d\x79\x12\x37\xc3\x71\xfe\xb0\x59\x7c\x77\x3f\x06\x81\xc6\x37\x82\x15\xe3\x2d\x37\xb7\xd6\x01\x33\xd8\x9a\x4b\x6e\x03\x19\x2e\x5a\xd2\xf3\xc3\x75\xc0\x8d\x66\x68\x8d\xdb\x45\x65\x90\x2c\xd3\xaf\x5e\xb3\xc8\x84\x3c\x6c\x88\x73\x96\xab\xf9\xa5\x6c\xdf\x5d\xe8\x87\xa6\x28\xcb\x14\xe8\xa0\xad\xf3\xa5\xb5\xa6\x43\xce\x03\x13\x1b\x47\x3a\x1e\x6e\xb8\xb5\xda\xf3\x41\xec\xb2\x9f\x5b\x53\x11\xda\xe1\x32\x86\x1f\x5c\x47\xda\xe8\x20\xbb\x65\xba\x9b\xda\xa3\x90\xb7\x4e\x7c\x15\x3a\x66\x5a\xcc\xfe\x82\x1a\x50\x3f\x68\xe1\x11\x69\xc0\x2d\x8d\x89\xb1\x42\x73\x59\x8e\xe2\x79\x5a\x50\x1f\x93\x1d\x48\x8f\xb8\xcf\x79\x9a\xad\xda\xe3\xe3\x10\x8d\x84\x23\x57\x6a\x66\x8b\x47\xbe\x88\xe3\x6a\x99\xf8\x1e\x46\xa4\x20\xaf\x4b\x9e\xcd\x79\xfe\x3a\x8c\x21\x68\xa9\x12\x84\xc4\x40\x2f\x60\xd3\x35\x6a\xc0\xf4\xdc\xe9\xf8\x0e\xa9\x5d\xf7\xc6\xcf\xac\x7c\x6a\xd3\xde\x59\xd6\x33\xe8\x99\xe7\x79\x54\x62\xb1\x5d\x9b\xdf\xef\x1f\xd9\xb4\x73\xc3\x73\xf1\xdf\x34\x7f\xfe\xf7\x4b\x6a\x59\xa1\x7f\xb3\xad\xc4\x0b\xf0\x83\x0b\xf8\x94\x41\xa0\xff\xc1\x9b\x23\xa8\x91\x69\x7e\x58\x2f\x56\xbb\xf5\xa6\x9b\x7a\x4d\x5b\x14\xe3\x46\x79\xe2\x1f\xcd\xd6\x93\xe6\xcf\xdf\x0a\x8b\x5f\x6d\x5a\x35\xc5\x18\xb5\x70\x55\xca\xcc\xf3\x7c\x8f\xe1\xa2\x61\x2a\x64\x52\x67\x8b\x35\x2d\xc2\xc7\x02\xaa\xbb\x4b\x55\x94\x7c\x70\x19\xca\x40\xb4\x14\x5c\x3f\x1c\x18\xda\xf7\x5c\xb3\xf4\xa5\xec\x81\x3a\x1c\xa5\x92\x5b\xdc\x48\xd8\x76\x8c\x31\x7a\xd9\x0c\x35\x9f\xee\x6b\x9e\x2b\x5e\x9a\x14\xc9\x44\x92\xb3\x39\x40\xb1\x58\xb7\x58\xb0\x01\x90\xda\x39\xa5\x7e\x67\x0b\xc6\xff\x19\xd6\x38\xff\x9f\xff\x1f\x77\x1e\x08\x50\xeb\x65\x32\xb6\x71\x99\xa8\xeb\x6b\x8f\xd3\x92\x5b\xad\xaa\x5c\xd9\x9c\x90\x13\x7d\x64\x9e\x17\xc4\xc4\x91\x4f\x36\xd6\xb8\x95\x27\xec\x67\x8c\x47\x1f\x33\x80\x88\x1b\xb5\x80\x34\xbf\x73\xaa\x1d\xcc\xf3\x98\x17\x21\xff\x88\x1d\xad\x9f\x23\x53\x9b\xbe\x44\x62\xd2\x64\xb1\x7a\x18\x7c\x25\x16\xb3\x16\x3a\x71\x11\xaf\x3d\x51\xf5\xe1\x43\x31\xc1\x83\xa8\xa5\xd7\xad\xcb\xe2\xea\x14\x62\x5c\xa0\x99\x79\x5e\xe8\x69\xea\xa0\x70\xbc\x96\x2f\x43\x12\x31\xd7\x49\x68\x1c\x7e\xa9\x75\xba\x6c\xb6\x60\x69\x77\x66\xc9\x6f\x45\x9b\x3b\x02\x9b\xe6\x78\x30\xa5\x66\x85\x83\x02\x1e\x0a\x47\x42\x6b\x7b\x44\x34\x0c\x5c\x58\x0c\xb8\x82\x52\x14\xce\x2b\x69\x47\x55\x14\x69\x04\xe9\xfc\xb7\x2a\xf2\x05\x1f\x1b\x11\xc3\x77\x17\x41\x10\x41\x5b\x9e\x5e\x16\xd5\xd9\x54\x78\x0d\x64\x1c\xb1\x9f\x44\x1b\x76\x2d\xfe\x6c\x73\x0f\xcd\xcf\x5a\x63\xc9\xd7\xb7\x32\x55\xf2\x22\x60\x9b\xf1\x5a\x17\xe5\x69\xf0\x1d\xe2\x20\x50\xaa\xa7\x85\xb2\xaf\xf9\x6b\x9a\x3f\xbb\x6c\x8b\xeb\x25\x22\x65\x78\x34\xae\xdb\xb2\x50\x97\x09\xf1\xf5\xe1\xad\xc7\x52\xe3\x2c\x7b\x2b\x6a\xd8\xa2\xc6\x61\x7b\x2a\x1d\x26\x16\x2d\xb0\x2b\xb2\xac\x78\x1b\x52\x0b\x33\xcf\x4b\x02\x8a\x36\xd3\xe3\xec\xf7\xe3\x76\xb7\xfe\x39\x3b\xac\x8e\x77\x3f\x9e\x96\xeb\xa7\x6f\x7d\xd3\x9b\x79\x9e\x08\x05\x16\x48\xb8\xd5\x0d\xb5\xad\x87\x5c\x3f\x4d\xaf\x24\xc0\x00\x09\x37\x11\x9d\x5b\x70\x2c\xf3\x3c\x19\x46\x48\x90\x6a\xb5\x08\x87\x7e\xce\x3f\x06\x5f\x50\x86\xda\x77\x45\x64\xad\x35\x77\x07\xb0\x78\xe1\x65\xcb\x4a\xc0\x9f\x27\x81\x02\xcc\xf3\x94\xef\x2b\xa7\x2d\xc6\x6b\x7e\x24\x41\x2f\x1a\xc9\x3c\x0f\x22\x8a\x89\xdf\xfd\x1e\x59\x7f\x07\x1f\x0b\x12\xb0\xc2\x6a\x8d\xbd\xfd\x6f\x28\x8b\x1b\x62\xf1\xa6\x97\x0c\x88\x68\x51\x21\xd6\x35\x6d\x27\x0b\xf1\x22\xe9\x00\xfe\x87\x97\x1e\xa1\xfd\x90\xa5\xa4\x5f\x4d\xcb\x3c\x42\x82\x10\x5d\xab\xa3\xa9\x49\x7b\x82\x8f\xda\x20\x75\xb7\x45\x9a\xd7\x93\xe6\x04\x1e\x95\x98\x00\x9b\x35\xfa\xdc\x5c\xfb\x4b\x5e\xf7\x69\x3f\xd9\x9d\x35\xe4\xda\x08\xeb\x99\x90\x9c\xe1\x81\x9c\xc4\x45\x37\xbd\x81\x26\x49\x97\xaa\xb4\x38\x89\xa9\xeb\x4e\x32\xa4\x33\x8f\xf8\x01\x41\x8b\xc2\xca\x70\xce\x72\x65\x90\xc1\xbc\xe4\xa7\xa9\x48\xfa\x17\x44\x9a\xcd\xd9\x18\x33\x3a\x9b\x88\x8d\x1c\x15\xea\xbb\x3e\x51\x80\xf5\xbc\xff\x6a\xda\xfa\x96\xc5\xb4\x46\xd8\x3f\xfa\x03\x88\xf8\x5c\x49\x53\x60\x2e\x5f\x07\x02\x9d\xfd\x77\xe8\x83\x08\x0d\x3b\x9d\x53\x9e\x65\x1e\xa1\x54\x21\xd6\xc7\xd6\x46\xfe\x4c\x3b\x85\xdb\xe1\x3b\xa5\x42\x60\x19\xf7\xe1\xc5\x34\xcf\xdd\x19\x02\x4f\xc3\x90\x4b\x75\xde\x73\xec\x3e\x19\x25\x41\x6c\xe8\x3f\xd3\x3c\xad\x57\xe7\x42\xbe\xf4\xcb\x8f\x9a\x76\x4e\x10\x1f\x99\x17\x0a\x8e\x46\xb3\x72\x74\x3f\x2c\x8a\xf1\x91\x57\x79\x5d\x5e\x67\x4a\xf5\xa2\x89\x93\x93\x90\xb0\xc4\x08\x6a\xe2\x5a\x6e\x0c\xc1\x05\x14\xc3\x35\x81\x84\xc4\x8f\x8d\x0e\xf9\x18\x11\xdb\x34\x0a\x03\x71\x15\x06\x66\x8e\x76\xe2\x23\x2f\x3f\x09\xc8\x34\x07\x28\x3f\xd1\x6d\xf1\x1b\xa8\x5b\xc9\x7c\xe6\x91\x48\x13\x6d\x65\xde\x8c\xec\x5d\x51\x1e\xdd\x6b\x88\xbd\x04\xe3\x00\x4f\x2b\xcb\xa6\xdd\xfc\x16\x1b\x95\x67\x67\x16\xf3\xce\x44\x22\x31\xf7\x74\x5f\x4f\xa8\x31\x3a\x47\x97\x4b\x7c\x6e\x74\x45\xa1\xaa\x8f\x94\x1c\x39\x4a\x53\x7d\xe3\xd5\x8f\x8a\x3f\x03\xf3\xe6\xcd\xfe\x55\xb9\x13\x26\x2c\x12\x2d\x3f\x40\x9e\xea\x81\x14\xed\xe4\xcc\x49\xa2\x10\xc7\x7a\xb9\x56\xee\x24\x3c\x50\x61\x17\x42\x78\xe2\x27\xd8\x5f\x4f\xa2\xc8\x6e\x91\x65\x4d\xe7\x88\xa3\xc5\x62\xdf\xe4\x63\x3a\xe9\x7f\x32\x8f\x08\x4f\x10\xa3\x83\x86\xc0\xf0\x87\x82\xe7\x1d\x62\x7f\x74\x8f\xee\x10\x0e\x91\x8d\xaa\x96\x3e\x0a\x2c\x4f\xbc\x20\xa1\xc5\xc0\x6b\xdd\xd7\xfc\x74\xae\x26\x14\xf3\x99\x47\x24\xf3\x3d\xd6\x2d\x91\x0f\x1c\xd5\x71\xf8\x27\x58\x17\x7b\x10\x50\x8e\xca\x15\xc7\x54\x16\x7d\x7c\x65\xd3\x14\x07\x4e\xce\x66\xcb\x4b\xbb\x44\x8c\x9e\x5b\x2b\xc5\xec\xee\xbd\x3f\x83\x5c\x2f\x87\x0b\x89\xef\x29\xa9\x83\xce\x63\x3b\x14\x2b\xde\x11\x10\x4f\x1a\x1d\x3e\xf1\x98\x13\x61\x58\xe7\x3a\xe3\xbd\x9d\xc5\x27\x54\xe2\x18\x5e\xfd\xbe\x5d\xed\x0e\xfb\xe3\x76\xb3\x79\x38\xce\x96\xcb\x5d\xdb\x21\x8a\xb1\x5c\x8d\x2b\xb5\x45\xc2\xd9\x53\x6f\xad\xfd\xa4\xd0\xb1\x39\x0c\x18\xda\x6f\x47\xe5\xf4\x37\xf6\x5d\x69\xb6\x5b\x39\x7d\xdf\xa7\x68\x5f\xcf\x7e\xce\xd6\x0f\xb3\xf9\xc3\xea\xb8\x7e\x6a\x23\xf9\xee\x0e\xfc\xd8\xf7\x88\x63\x1e\xc7\x22\xd8\xd6\x3e\xf3\x7d\xe5\xa3\x13\x89\x92\x2f\x65\x5a\x5f\xe7\x25\x80\x23\x75\x6c\x3b\x41\x82\x20\x1e\xf8\x30\xbc\x1a\xf6\x67\x1a\x18\xbe\x25\xae\xd4\x53\x51\xf3\x5b\x9e\xa7\xc9\xef\xeb\x53\x45\xfc\xc0\xb2\xd2\x38\xaf\xc1\x36\x05\x9e\x41\xab\x96\xf0\x5f\x90\xf5\x54\x5c\xaf\xed\xc8\xf1\xed\x14\xb9\x2d\x54\x69\x99\x85\xc7\x1d\x49\x80\x30\xbf\x13\xae\x43\x8f\xfc\x75\x90\xe9\x6c\x3a\xc4\x12\x3d\x0b\x5c\xf6\xfe\xb8\x77\xcb\x88\xcf\x12\xa9\x7a\x5c\x3b\xdb\x12\xd6\x8b\xcd\x5d\x09\x26\x9a\x31\x1c\x97\x3e\x13\x09\xa6\x94\x01\x05\xff\x26\x23\xea\xf1\x2d\x27\xa4\x3d\x38\x66\x49\x60\x81\x07\x73\xc3\x6b\xd6\x2c\x37\x26\x95\x3a\x1c\x87\x3c\x0e\x51\x17\xf2\x99\x9f\x90\x96\xe8\x47\x85\xa8\x1e\x0c\xe5\xbb\x5b\xe1\xdc\xf8\x8c\x97\xca\x95\xbf\x0c\xcf\x21\x28\x31\xf8\xd8\x73\xd6\x67\x7f\x68\x5a\x62\x61\x62\x4c\xd7\xbc\x7e\xa9\x7a\x00\x9b\xa6\x0d\x08\x02\xab\x2e\xb9\x63\x72\x9a\x5f\x3f\xc1\xd5\x32\xcf\x97\x89\x50\xee\x1e\x3a\xbc\xcd\xf0\x3e\xa4\x24\xc8\x08\xfe\x3d\xad\xeb\xeb\x60\xb4\xa9\x88\xa1\x75\x82\x7a\xa0\xd3\xbb\xe4\x68\x7e\x2a\xae\x90\xb3\xca\x06\xc0\x6f\xd0\x3a\xed\x74\x01\x6a\x48\xfd\x56\x5a\x03\x52\xf5\xc2\x10\x6b\x18\xb7\x3d\xb5\xaf\x00\x2c\xc0\xa1\xd9\xcc\x0e\xc0\x4f\xa3\xa2\x9f\xe1\x3d\x68\xf0\x99\x83\x66\xa5\xea\x81\x57\xf5\x0f\x5c\xf3\x06\xa3\x8d\x7a\xd2\xa4\x57\x11\x82\x7f\xb9\x8e\x17\x4c\x4a\x7c\x83\xab\x5f\xef\x17\xbf\xb5\x3f\x49\x8c\xee\x63\x7e\xc3\x81\xe5\x86\xe6\x00\xf5\x83\xd8\x04\x44\x52\x83\xcd\xbe\x2b\x4a\x43\x35\x61\x65\xf9\xdb\x7e\x9a\xd2\x96\x9c\x13\x8d\xfe\x49\x3c\x23\xf3\x28\x8b\x04\xb2\x11\x8b\xcb\x75\xd1\x4b\x23\x8d\x7a\x85\xbe\xd5\x73\x36\x2f\x7e\xa2\x30\xae\xe9\x14\xc4\xf8\xcc\xeb\xbc\xd9\x49\xd7\xa7\xc6\x0f\x18\xbc\x94\x30\x8c\x0c\x43\xbe\xb8\x94\xf9\x27\x55\x73\x4d\xb7\x38\x72\x7a\xeb\x36\xc1\x85\xac\xdf\x3d\xef\xc2\x75\x54\x21\x46\x7f\xb7\x86\xa3\xc4\xfd\x1c\xf9\x26\xfd\x63\x23\xc7\x83\x92\x93\xa6\x39\x64\x98\xb2\x79\xd8\x2c\xbe\x9b\x0e\x9b\xf5\x53\xdf\xca\xf9\x3a\xcc\x43\x23\x90\x61\x9f\xb1\x7d\x24\xfa\xc9\x3c\x1a\xcb\xc4\x09\x5f\x36\x73\x27\xcd\x9f\x67\x6d\x1d\x6e\xaf\xac\x81\x79\x34\x21\x09\xae\xca\x3a\xed\x6a\x7c\x7f\x42\x59\x21\x7d\xd6\xf4\x5b\x4e\x88\x31\xbe\x2e\x39\xd6\xb7\xdd\xc6\x01\x9b\x3e\xbe\x40\x0f\x74\x91\x01\xcf\xef\x8a\x42\x2d\xca\xeb\xd9\x02\x63\x9a\x66\x46\x4c\x72\x90\xe7\xc7\x2c\xe5\x79\xfb\xbb\x0c\x71\x43\x4e\xf3\xb7\xb4\x86\x7b\xa4\x87\x2d\x87\xbb\x2a\xe5\x1e\xe8\xb8\x83\x53\x37\xd6\xc6\x27\xb6\x2d\xe5\x34\xc4\x82\x82\x13\x4f\x73\xc4\x71\x23\xb6\x00\xa3\xe3\x6d\xd4\xb7\xe9\xa6\x4c\x0c\xde\xbc\xcf\xa1\xd9\xed\x1c\x4f\x2a\xc2\x40\x7a\xae\x26\x18\xaf\xbc\x35\x1e\x09\x4c\x82\x88\x99\x47\x65\x10\x24\xba\xe7\x29\x6d\x4b\x78\xce\x79\x5e\xf7\xe5\x1f\x9b\x6e\x71\x60\x66\x1d\xaf\x5e\x36\x97\x2e\x77\xd7\x34\x71\x8e\xbe\xe4\xd9\xec\xe6\x06\xe9\xd3\x6b\x34\x90\xf1\x17\x5e\x81\x6f\x94\xc4\x0d\xcd\xe7\xca\x92\xc6\x32\x8f\x2a\x48\x90\x34\x35\x87\xf7\x85\x63\x27\x65\x1e\x05\x42\x14\xb4\x61\x5a\xa8\xd7\x6a\xc1\xcb\xe7\xc2\x90\xa7\xf4\x43\x98\x14\x12\xa3\xdb\x69\xde\xcd\x2f\x38\x94\x97\xaa\x1e\xba\x71\xae\xa7\x08\xb0\x10\x41\x19\x8c\x7b\x97\xc5\x6f\x2f\xaa\x13\x0d\x7d\x76\xc7\xd9\xc9\x6c\x19\x36\x46\x14\x78\x1e\x41\x9b\x6b\x97\x56\xaf\x03\xa9\x5c\xd7\x4e\x3d\xac\x77\xe7\x86\x20\x55\x63\x69\xdb\xbf\x2e\x70\x71\x2f\x2c\xf0\x98\x76\x22\xae\x8f\x70\x12\x50\xa2\xca\xe2\x54\x40\x2a\xf0\x12\x0f\x31\xdc\x47\x59\x9c\xce\x17\x43\x71\x57\x2d\x2e\xa3\x4d\x2c\xf0\xa4\x51\x03\xb3\x55\xd2\xee\x42\x84\x30\x66\xa7\xa0\x91\x3a\x34\xb8\x93\xdb\x4c\x78\xd3\x37\x14\x98\xb9\x42\x81\x08\xa3\x90\x39\x39\x60\x02\x12\x19\x25\x6b\x91\xaa\x4d\xf3\x11\xf7\x69\xb3\x74\x7d\x92\xfb\xe9\x6f\xf5\xf6\x78\x3f\xd6\x56\xfb\xab\x59\xfe\x10\x1b\x96\x5d\x47\xbb\x61\xe0\x27\x04\x6b\x6f\x4f\xfc\xe3\x50\xec\x21\x73\x21\xe0\xc0\xd7\x1a\xf1\x8b\x9d\xde\xee\x3a\x77\x5c\x56\xcc\x0b\xa8\x4f\x30\x6f\x59\x63\x7d\x9d\xcb\x85\x76\xab\x5a\x40\x69\x20\x6d\x39\xcc\xd7\x8e\x45\x10\x24\x46\xc9\xec\xdd\xf1\x1a\x58\x4e\xe2\x01\xee\xa6\xe9\x27\x08\xf1\x1d\xa7\x38\xc8\xd7\xea\x72\x5a\xb4\xf4\x0c\xcc\x0b\x22\x2a\x51\x82\x4b\x01\xaf\x5f\x30\x9c\xa3\x09\x6b\x1b\x13\x2f\x64\xad\xa7\xdf\x8a\x00\xb8\x56\x41\x69\x34\x70\x84\x1c\x1b\x90\xeb\xa0\xe3\x30\xea\x8a\x7b\xca\xe2\x8c\x11\x87\x6a\x20\x69\x65\xfb\x26\xc2\x47\x3c\xc4\xb9\xa8\x21\xaf\xd3\x16\xe7\xe6\x9a\x75\x80\x2c\x58\x79\x71\x4a\xf3\x5e\x12\x60\xb8\xc3\x05\xff\x8f\xb2\x37\xd9\x6e\x1c\xc7\xb6\x86\xdf\xe5\x1b\xc5\xa0\x06\x04\x48\x90\xe0\x3f\x93\x64\xd9\xa1\x9b\x6e\x54\x96\x9c\x91\x59\x77\xd5\xd2\x42\x73\x60\xb3\x4c\x91\x2a\x92\x0a\x87\xea\xe9\xff\xc5\x03\x80\x9d\x68\x67\xdd\x41\x46\x64\x08\x60\x8f\xe6\x34\xfb\xec\x2d\x54\x8a\x4f\xe3\xbd\x9d\xd9\x57\x27\x03\x81\x15\xa3\xf7\x4f\x77\x07\x84\x83\x6e\xea\x7d\x59\x2e\x1d\x84\xa3\xed\x40\x28\xb5\x8e\xae\xd0\x16\xd5\x36\x71\x0e\xbd\xdd\x11\xc9\xd4\xf2\xfa\xde\x41\x56\xbf\x89\x41\xe8\x32\x92\x69\x22\xdc\xea\xa0\x7c\x5c\x47\x4f\xb2\xc7\x6d\x37\xa5\x21\xf1\x2a\x84\xca\x86\xff\xde\xa1\xd8\xdc\xd4\xae\x62\x7b\xbc\x40\x44\x2a\x65\xf8\x80\xdb\xc5\xf3\xfe\x71\xcc\x78\xda\xb6\x2a\x40\x5c\xd2\xc9\xb1\x97\x4d\xa8\x9f\xc6\xa7\xd2\x01\xf7\xf2\x10\x56\xbf\xdf\x1b\xa5\x91\xa6\x89\x19\x42\xea\x07\x4c\xb4\x2c\x88\x0c\x89\x3d\x05\xc2\x6e\xa2\x40\xda\xb6\x32\x40\xfd\x1f\x93\x97\xe5\xc4\x5c\x8a\x4c\x6c\xb7\xf4\x1a\xaa\x9f\x99\x82\xaf\x2a\x63\xdb\xde\x42\x25\xae\xf6\x75\x48\xea\xd9\x71\x5b\x0e\x7a\x4a\x89\x24\xf6\xf7\x99\x19\x0b\x8d\x5d\x63\xee\x58\xc0\x82\xc0\x72\x25\x57\xd9\xeb\x5b\x43\xf9\xf8\x5c\x2c\x08\x0c\xbe\xc2\x7b\x71\x2e\xd4\xdb\xd6\xc2\x25\xeb\x61\xba\x8b\x05\x8c\x38\x6a\x0f\x27\xfe\x00\x95\xc7\xc4\x8f\x5f\x06\x23\x8c\x7b\x88\xb5\x45\x65\xd6\xc3\xb9\xc7\x08\xd3\x4c\xf4\xd5\xf1\x37\x59\xdd\x2e\xa2\x1d\xa5\x56\x6f\xa2\x33\x1a\x48\x44\x95\x0f\xb9\xc9\xfd\x59\x28\xe3\x58\xf9\xb9\x7b\x2b\x3f\x0e\xe2\xdc\x94\x47\x54\xe2\x6c\x97\xa5\xc3\xa9\x2b\xe1\x68\x3b\x0a\x89\x25\x1c\x3f\x33\xf8\xf8\xdc\x59\x63\x11\xd7\xdc\xc9\x25\xb7\x0e\x98\x8b\x27\x7f\x01\x88\x6b\x8f\x01\x2e\xed\xfd\xa1\xc3\x7a\x03\x3f\xb1\xfc\xca\xb5\x32\x4a\x99\xe9\xa9\xdc\xa7\xb6\x03\x63\xcc\x11\x41\xdb\x2d\xfa\x50\x43\x6e\xda\x1d\xb0\x3a\xab\xc9\x56\xc2\x18\xd7\xae\x0a\x0a\x79\x23\xdf\xa0\x79\x9b\xdc\x3e\xd3\x09\xda\xe4\x3e\x68\x54\x3c\x40\xde\xbf\xac\x38\x10\xb6\x28\xce\xcb\x50\xe1\xd6\xe7\xd6\x9a\xc1\x0b\x8f\x45\x88\xe5\x21\xa3\xf4\xe8\x6e\xe0\x4e\x0c\xfb\xca\xd0\x97\x5c\xee\x06\xca\xd3\x2c\x60\x5c\x45\x18\x7c\xa9\x85\x81\x29\xe9\xd8\x78\xb4\x33\x6e\x2c\x05\xfa\x09\x63\xd2\x3f\x00\xde\xfd\x49\xd2\x20\x44\xf8\xea\x1d\xb4\x26\xc1\xd8\x95\x60\x29\x89\x92\x5e\x31\x38\x2b\x6e\x2a\xf1\x91\x15\xaf\xf5\xf2\x82\xff\x9c\x86\x53\x58\x6a\x04\xfa\xcf\x7e\x6a\xa3\xd7\x76\xc5\xdb\x38\x5e\x29\x98\xa0\x01\xb2\x6a\xe0\x68\x5a\xf5\xab\xbd\x6f\x4e\x24\xa6\xa3\x4f\xe7\x3c\xb7\x2e\xea\xec\x82\xc3\xa4\xb0\x6b\xb8\x8b\x42\x5b\x6e\x9e\x21\x90\x64\x0e\x3d\xc8\x02\xa6\x42\x85\x61\x86\x07\x51\x2f\x8a\xf3\xb7\xee\x57\x8d\x3e\xee\x29\x03\x85\xb5\x6e\xe0\x23\x74\x4c\x0b\x86\xb0\xfe\x03\x16\x8d\xed\x4b\xa7\x3b\x5d\x0f\x41\x8a\x7c\xf2\xfe\x21\x21\xba\x63\xb3\x69\x3e\xca\x4d\xf1\x53\xe4\x99\xbe\x15\x79\x0d\xeb\x7f\xdf\x97\xdd\x37\x05\x4d\x30\xed\x67\xe1\xe8\x5b\x68\x5a\x87\x6b\x07\x55\xe6\x7c\x66\x7b\xe2\xee\x85\x1b\x1a\xa7\x49\x1f\x23\x19\x55\x90\xf8\x2e\x32\x42\x78\x83\xd0\x57\x56\xf0\xe4\x26\x8d\x61\x49\x34\xe0\x67\xbe\xce\xf6\x75\xa3\x32\x0e\x52\x6a\xfc\xce\x72\x94\x19\x14\xcd\x7d\xfb\x1a\xd6\xbf\x14\x9c\xa6\x70\x49\xec\xae\xb0\x9e\xa4\x1c\x2b\x0d\xac\x5a\xd3\xcc\xbf\xd8\x98\x04\x56\x1f\xfc\x61\xf3\xb8\xee\x7e\x0b\x85\x2f\xbe\xbd\xa9\xca\xd3\x63\xd9\xf4\x4b\x4e\x4c\xc1\x90\xd8\xed\xa4\x4f\xa7\xd6\xef\xab\xdf\xfd\xb2\x10\x87\x2c\x44\x6c\x10\x96\x87\xf5\x30\x38\x6c\xb1\xe8\xfc\xd5\x9f\xdb\xef\xeb\xe7\x3f\xba\x9f\x63\x81\x91\x57\x9b\xcf\x9e\x09\xeb\xc7\x61\xe2\xca\x89\x5b\x07\x73\x30\x46\xe3\xd0\x84\xb1\x2b\x9e\xb0\x46\x6d\x3d\x45\xeb\xfa\x3d\x3d\x8e\x78\x84\xd8\x4e\xff\x92\xdb\x89\xbb\x41\x5f\xaa\x72\x0a\x58\xfd\xf5\x58\xc8\xb0\x00\xdc\xd6\x07\x5d\xc5\x92\xbf\xc8\xc9\xc4\x8c\x69\x8e\x32\x0d\x18\xe4\xf2\x3f\x2a\xe9\x25\x34\xae\x56\xb6\x38\x4e\x6d\xc2\xb9\xb5\xd2\x6a\x68\xbe\x9f\xe5\xb7\xae\xc5\xc2\x51\xcf\xc5\xa9\xe3\x68\xe8\xda\x84\xc5\x2a\xd7\xd0\xdc\x6f\x2d\x68\x7e\x5b\xd6\xd3\x62\xc3\xb6\x23\x50\xf4\xeb\x1b\x10\xc7\xdf\x00\x4e\x59\xf1\xda\xad\x59\xe3\x9e\x89\xb1\xe9\xcd\xdf\x16\xa3\x8c\x78\xcc\x99\x42\x06\xb7\xdd\x87\xa8\x8e\xcf\xa0\xaf\x33\x7b\x71\x4a\x75\x6a\xd9\xc0\x56\x58\x0e\xda\x0c\x84\x18\xe7\xd1\x68\xe3\xb7\x96\xa6\xc0\xd3\xde\x71\x5d\x9e\x2f\xed\x3a\x7f\xfb\xc7\xe4\x0e\x53\x11\x8f\x41\x23\xbf\x81\x14\x72\xe7\xc1\x25\x7d\x47\x11\x08\x21\x5c\x6d\x45\x55\xc3\xee\x94\x67\x8e\xca\xdc\xd6\x73\x8f\xb2\x93\x93\x43\x3d\x6a\x0d\xf3\x47\xed\xf0\xbd\x2d\x2b\x24\x18\xf5\x0f\x2b\x04\x68\x9b\x7e\xa9\xcf\xe0\x61\xed\xbe\x51\xb2\x18\xe3\x77\x03\x50\x4d\x3f\x0e\xa4\x0e\x07\x0c\xd3\xbe\x0c\x6a\x62\x0c\xc6\xd2\x18\xac\x67\xcb\xc1\x34\xc9\xe4\xee\x94\xb4\xd1\x81\x47\xf8\xb0\x32\xb2\x9f\x2c\xf1\xff\x6d\xfe\xd2\x9f\xd6\x58\x3c\x0b\x8a\x90\x66\xde\xef\x89\x35\x8b\x54\xe2\x19\x7e\x5f\x47\xa6\x7b\xac\x53\x90\x8e\x95\x0e\xfd\x0b\xde\x35\x28\xab\x8c\x89\xe5\x91\xe2\x15\x3c\x5b\xb3\x6b\x06\x12\xc4\xca\xe7\xf5\x77\xa3\x18\x54\x0c\x2a\x40\xbc\x80\xdd\x2d\xd7\xfd\x5b\x05\x20\x48\x94\xd3\xa0\x16\x2c\x72\xe5\x4c\xc2\x2a\x09\x09\xc0\x60\x96\x03\x79\x8c\xb0\x92\xd2\xde\x70\x8d\xfb\xc4\x37\xdf\x2d\xd4\x2a\x98\xd6\x95\xd6\x6f\x99\xa3\x5f\x7f\x40\x10\xc6\xf4\xd4\x46\x19\xcf\x5f\xf2\x13\xaa\x5d\x79\xee\xcb\x0a\xe7\x40\xd4\x7e\xcd\x49\xa8\xb0\xc2\x66\xae\xc8\x69\x5b\x36\xa2\x29\xff\x8a\x34\x67\xbc\x4d\x26\x21\x58\xe5\x82\xd6\x34\x7a\x7a\xba\xb7\xc2\xad\x94\x8d\x5e\x5c\x12\xb5\x8e\xa3\x8d\xaa\x55\x42\x0f\x92\x6d\x49\xeb\x64\xb5\x9f\xd0\x89\xd6\x5c\x19\xe7\x5f\xc6\x74\x13\x16\x59\xb3\x19\x21\xf3\x1d\x0f\x6f\xde\x4e\xbd\x4a\xe4\x59\x3d\xdc\xf0\x92\x58\x47\x48\xf3\x83\xd5\x36\x56\xbf\xd9\x71\xb8\xcf\xda\x46\x49\x22\x54\x00\x83\x15\xd9\x06\x25\x47\x89\xf5\xc9\x11\x3c\x0a\xad\xcc\x59\x5d\xc3\x51\xe6\x97\xdd\x9b\x38\x66\x57\xd4\x29\x9f\x3c\x0b\x4f\x42\x8c\x6a\x14\x65\x75\x44\xa2\x2b\xbd\x16\x55\x7e\xf1\x94\xd0\x7e\x80\x26\x29\x4b\x71\xfc\x16\xf0\xb1\xec\x69\xd2\x27\x43\x42\x70\x4b\xb3\x2a\x2a\x51\xcc\x72\x29\x63\x1f\x5b\x75\x8d\x61\xa4\xff\x23\x66\x2a\x11\x46\x22\xf8\xd3\x59\x55\xcb\xf3\xe5\x1a\xe2\xce\x82\x44\x86\x91\x17\x00\xf8\xed\x71\xf5\x2c\x1a\x78\x6e\x97\x94\x1d\xca\x7d\x9f\xab\xfe\xa9\x34\x49\xd0\x67\x41\xc7\xf7\x94\x5f\xa6\xa4\x85\xff\xb7\x05\x23\xd1\x2c\xb5\xc5\xee\x4d\x79\x1a\xf3\xd2\xb4\x8d\x9c\xf3\x64\x24\x0c\x4a\xd2\xf1\x78\x85\x84\xe3\x32\x56\x9f\x65\xad\xaa\x4c\xc2\xa4\x39\x4d\x84\x83\xe2\x2c\x5f\x16\x57\x29\xf3\xf1\x9b\x02\x30\x88\x93\xc6\xb5\x61\x08\x68\x1b\x6d\x35\xc3\x68\x10\x0f\x12\x50\xca\x9b\xf6\x79\x0e\x95\xe9\xb0\x06\x9c\x70\x5b\x3f\xeb\xd1\x58\x77\xb3\x94\x80\xe3\xcf\xc0\xc3\x90\x21\xa2\xc9\x71\xba\x5a\x1a\xb0\xac\x78\x1d\xfa\x63\xfe\x53\xb4\x9d\x31\xb9\x7d\x14\xbf\x9e\xa1\x68\x06\xea\x39\x6d\x63\x14\x22\x37\x40\x86\x55\x1c\x0d\x58\xa5\x2d\x17\x98\xfe\x6c\xa9\xf8\xec\x6f\x7f\x4e\x69\x33\xfc\x76\xbb\x59\x96\xe5\x7b\x56\xbc\x5e\x21\xe2\x78\x94\x86\x52\xf5\x24\xd6\xf3\xe7\x8a\x52\x85\xc9\x0b\xc4\xac\x60\xe1\xd0\x7c\xc4\x8e\x47\x92\x5a\x4d\xd4\xac\x68\x9c\xbb\xd5\x4c\x66\x11\x8f\xb4\xc0\xec\xb8\xc9\x4e\x16\xfe\x3b\x86\x44\x72\xa6\x52\xe3\x54\xf7\xec\xee\xbd\x29\x56\x96\x63\xa8\x1d\x57\x42\x35\x5d\xe1\x22\x0b\x78\x9c\xd0\xd0\x42\x7a\xe5\xf9\xd5\xb2\x68\x1c\x9c\x6a\x74\x69\x0e\x46\x9c\x15\xf8\x5d\x80\x27\xd4\xd6\xd3\x94\x9d\x45\x8c\xda\xc7\x7f\xb1\x89\x76\x07\x03\xe6\x05\xd6\x2f\xcf\x4f\x7f\x7f\xd9\x3c\x3e\x7e\x51\xeb\x39\x3d\x94\x59\xc8\x73\xe5\xb5\x7e\xee\x4b\xf5\x3e\xf0\x99\x79\x12\x53\xac\x4b\xc0\x28\x06\x09\x26\x5f\x28\x11\x12\xf7\xe3\x7f\x95\x59\xf1\x74\x6e\x96\xa2\x69\xf2\xf1\xd4\xe1\x69\x14\x31\x3b\xb8\xda\xed\x2c\xbf\x3c\xa0\xe0\x7c\xaf\xcd\x7c\xb5\x58\x62\xd0\xae\xfb\xc3\x9d\x45\x04\x02\x03\xef\x8f\x59\x33\x4a\x42\x73\xc1\x53\x0b\x4e\x68\x1d\xfe\x33\x16\xd6\x75\x7e\x04\x17\x32\x42\x87\xbf\x7e\x2b\x3f\xb6\x65\x99\x77\x6b\xcc\xf8\x29\x64\x90\x32\x5f\xdd\xf8\xe8\x78\xcc\xf7\x1f\x65\x7b\x77\xdd\x1c\x91\x92\xc7\xae\x22\xf0\xe1\x32\x51\xc1\x63\x01\x57\x1a\x48\xe8\x11\x1f\xa7\xd6\xa6\xdd\xdc\xcc\x68\xe8\xb2\x80\xeb\xc0\x30\x67\xc2\x58\xa2\xad\x27\x63\x27\xdc\x2c\x16\xbe\x3d\x20\x0e\xd0\x74\x6c\xed\xe5\xf5\xfe\xfb\x0b\x0a\x67\x51\x7f\x5f\xda\x30\x8c\xa2\xa3\x0e\x64\x7d\x2a\x8b\x1a\x9e\x4e\xa3\xd9\x0d\x61\x42\x78\xc7\xb7\x93\xe9\xdf\xfe\x5c\x0d\x22\x10\xdc\x84\x0c\x8d\xec\x37\x10\xa7\x5d\x59\x35\x2e\x93\xe2\x4d\x06\x6e\xa2\x58\xf8\xf0\x98\x38\x82\x8b\x3c\xf8\xb3\xa7\x41\x14\x58\x36\x65\xbf\x6b\x0d\x23\x4f\x69\x10\x33\x04\xc2\xf4\xca\x3d\xb7\x65\x75\xdb\x15\x6f\x76\xdd\x52\xce\xba\x6c\xfb\xfa\x98\x75\xc7\x13\x65\xf3\x2d\xe8\x60\xef\xa0\xfb\xb2\x29\x01\x4f\x2f\xe5\x42\x38\xe5\xa5\x6b\x32\x9c\xf7\x32\xd9\x96\x07\x69\x55\x1e\x8f\x59\x8f\x5c\xbe\x7a\xc9\x29\x25\x76\x1e\xac\xef\xee\x76\x87\xfd\xd3\xe1\xfb\x62\xbf\xfa\x7e\x20\xab\xe7\xa7\xd5\xce\x9f\x98\x3a\x3d\x0f\x9b\xd2\xe8\x56\x52\xd0\xcb\xc9\x32\x92\x52\x2e\x11\x99\xa8\x44\x61\xe9\x53\xdb\x37\xd7\xbd\x32\x6a\x52\x04\xab\xe2\x92\x51\x74\xf7\x1d\x06\x4a\x58\xea\x91\x5b\x91\xe5\x03\xd3\x08\x57\x02\xdf\x29\x14\xa8\xeb\xbb\xcc\x9a\xe2\x5c\x9f\xbb\x9f\x95\xf4\x55\x7e\x18\x19\xb9\x81\xbc\x17\x08\xf6\x7d\xb4\x4a\xf4\x90\x77\x69\xf4\x02\xa2\x48\xf0\x51\x36\x66\x08\x08\xf2\x7d\x78\xe4\x83\x62\x48\xdc\x39\xc7\x33\xcc\x82\x94\x11\x26\x5d\x42\xd3\x91\x6b\x0c\x98\x9a\x59\x90\xc6\xa1\x54\xd1\x18\xfd\x5d\xef\x27\x90\xb2\x34\x66\x76\x9a\x38\x0a\xb7\x1f\xe7\x3c\x2b\x1e\x90\x69\x7a\x3b\x88\x35\xa6\x49\x62\x50\x2d\xd2\x40\xa3\xde\xae\x18\xb9\xdb\x0e\xc0\x30\xa2\x69\xcb\x25\xfc\xaf\x82\x84\x88\xd2\x45\xab\xbc\x83\x5c\xa5\x22\x01\x4f\x5f\x84\x02\xb4\x73\x65\x8a\xae\xab\x34\x14\x23\x91\xe2\x57\x77\x29\x15\x1a\xd5\x47\x6c\xf6\xed\x62\x62\x0b\xc7\x67\xcd\x9a\xff\x2a\x7d\x9c\x2a\xa6\x8d\x75\xd0\xac\x7c\xb6\x2d\x1a\xee\x1a\x01\xd1\x08\x8b\xdd\xdd\x70\x4d\x4c\x55\x1a\xc8\xd0\x71\xea\x39\x14\xbe\xd5\xc0\xff\xd4\xb6\x1a\x3e\x99\xd2\xa1\xab\x84\x12\x9d\x8b\x99\xea\xd8\x8a\x06\x1d\x41\x67\xe7\xe3\xe8\x13\x68\xae\xb0\xe9\xf7\xc5\xfd\x8b\x8f\xd6\xa4\x26\x30\x10\xf9\x82\x73\x57\xc3\x30\x94\x63\xf9\xe4\x71\x4d\x6c\xd0\x9e\x5e\xfc\xfb\x2c\xfe\x6a\x13\xf3\x3c\x39\xe3\x71\x63\x12\x65\x3c\x67\xb6\xe5\x29\xba\x3d\x17\x53\x80\x54\x6a\xb8\xe5\xa2\xb0\x9f\xea\x20\x46\x03\x54\xb4\x8f\x8b\x94\xb7\x22\x87\x4d\x7d\x9f\xfd\x84\xae\xc5\x24\x78\x1c\xba\x74\x87\xfa\x4d\x54\x50\x1f\xea\x32\xf7\xef\x49\x90\x20\xf1\x35\x13\x96\x28\x09\xd5\xb4\xbb\xd6\x30\x09\x6c\x12\xac\xb8\xd8\xf8\x66\x8d\xe6\x6f\x73\x1d\x62\x12\x24\x02\xd1\xcf\x12\x97\x75\xfb\x0a\x1d\x2a\x48\x9c\x60\x91\x90\x7d\x28\xbd\x68\xa6\x67\xd4\xd6\x41\xae\x4a\xb9\xe8\x52\x89\x82\x52\x40\xef\x62\x29\x0a\x55\x56\x77\xa2\xc6\x8f\x3b\x83\x33\x12\xa1\xd4\xa1\x15\x22\x6e\x67\xa1\xd7\x42\x67\x81\x88\x52\xc3\x8c\xe7\xd7\xad\x0a\x8f\x5d\xf6\xe3\x54\x30\x2e\x43\xe3\xb5\x8c\xa6\x63\xd0\x7f\x13\xc1\x14\xc7\x71\xf4\x56\xd6\xcd\xc1\x72\x50\x4c\x6e\x80\x81\xc4\x52\x6b\xbb\xb2\xef\x4e\x42\x41\xbb\x4a\x39\xce\x34\xd7\x29\x4e\x18\xc6\x09\xff\xfe\xf7\xe5\x48\x7f\xcf\x37\x73\xcb\xc3\xee\x20\x30\xfa\xb1\xd4\x16\x14\xe4\xdb\x65\x44\x9d\x77\xdb\xe4\x08\x58\xb7\xe2\x19\x73\x7c\x71\x2c\x10\x49\xc2\x30\x3a\x5c\xc0\xc7\x8d\xe8\x46\x01\xa7\x14\xf3\x99\x58\x29\xba\x3e\x42\xf5\x0a\x85\xba\xec\x9a\xf2\xd4\xf7\x88\x10\x29\xdd\x0e\xd3\xe7\xcd\x76\xfd\x70\x43\xe2\xa0\x6b\x64\x1a\x0d\xc7\x1b\x10\xcd\x5b\x7b\x83\x5d\x83\xb6\xb5\x3c\xd6\x76\xd8\x65\xaf\x2e\x1e\x3d\x8a\x5d\x89\x54\x32\xf4\x2b\x65\x59\x8e\x31\x54\x22\x05\x62\xab\x94\x84\x7a\x3f\x9f\xfa\x5f\xad\x58\xa0\x55\x75\x28\x9a\xaa\xcc\x77\xc8\xd1\x82\x50\xa5\xd6\x77\x7f\x2c\x9d\xee\x92\x3b\x42\xc6\x26\x71\x1f\xfc\xa1\xee\x6c\x01\x4c\x8a\xb6\xb3\xf7\x36\xcb\x61\x60\x08\x0b\x4d\x0d\xda\x68\x3f\xa1\xd0\x77\x67\x51\xa1\x30\xfc\xf8\x3d\xea\x24\xc4\x52\x81\xbb\xed\xee\x06\x94\xb8\xb4\xcb\x45\x7b\xe7\xeb\xe2\x67\x56\x95\xc5\x71\x86\x0a\xcd\x1f\xa9\x12\x2c\x36\xf9\xc8\x8a\xd6\x7e\x3d\xe0\x4c\xae\x2e\x07\xbb\x52\x74\xb7\xa0\x34\x16\x1f\x9a\x73\xa1\x47\xaf\x04\xa8\xe5\x37\xf2\x55\x4b\x7d\xe4\x1c\xbe\x14\x02\x1d\xdf\x04\x70\xa6\xf9\x60\x99\x46\x80\xac\x6f\xd3\x1a\xeb\x55\x15\x14\x75\x59\xad\xde\x44\xf3\x60\xc9\x6d\xc6\xaf\x40\x06\x01\x45\x72\x08\xb7\xe3\x59\x69\x98\x6f\xbe\x31\x12\x11\x78\xb0\x26\x3e\x60\x97\x9f\xe4\xbe\x4b\x1c\xcb\x1e\x69\x94\x9f\x48\x38\x1e\xfa\x92\x44\xa9\x77\x62\x71\x8e\xef\x1a\x38\x91\xc9\x4d\x10\x61\xd3\x08\x4d\x69\x55\x13\xa6\x50\x34\x49\x84\xc4\x8a\xa6\xed\x7a\xff\x55\xf6\x53\x12\x13\x60\x32\x05\x37\xe6\xad\xc8\xb4\xe5\x36\xbe\x2d\xab\xad\xb8\x4c\x03\x5a\x92\x0a\x40\xeb\xda\x07\xc1\x56\x6f\xd9\xe9\x5a\xc7\x6e\x7c\x27\x51\x94\x20\xe2\xc0\x55\x6b\x4e\xee\x33\xe2\x0a\x27\xa6\x38\x37\x65\x51\x1e\xcb\x73\xbd\xb2\xc8\xde\x6e\x14\x4b\xc6\x55\xd0\x5e\xf4\x7f\xce\xaf\xaf\xad\x67\x7d\x6e\x86\x23\x43\x32\xa9\xd2\xb0\x53\xaa\x45\xa3\x75\x20\x51\xc8\x02\x19\xd3\xd4\xcb\x8d\xcd\x4b\x3d\x8d\xb7\x26\x19\x4b\xe1\x13\xe1\x3f\xfa\x15\xdf\x7f\xbe\x24\x4d\xa8\x83\x64\xec\x44\xe1\xe8\xcc\x66\x87\xbc\x4c\x64\x22\x5c\xd7\x67\x54\x47\x9d\x5f\x9c\x64\x02\xa9\x95\x49\x54\x28\x89\x3c\xc9\xd2\x4f\x5d\xf6\xf1\xb1\x9c\x0a\x54\x0f\x2a\xe5\xbf\x40\x35\x3b\xa1\x7c\x9e\x50\xa6\xc4\xda\xd7\x35\x34\xbf\x5d\xd4\x15\xaa\xf2\x6f\xd7\x99\x4b\x99\xd2\x18\x13\xfd\x2f\x45\x36\x5e\x91\x64\x1a\xca\x50\x3a\x40\xe5\xf2\xfc\x9f\xff\xac\x84\x81\xae\x2d\x8d\x71\xdb\x40\xce\xf0\xac\x70\xa8\x4f\x1f\x1e\x9b\xdf\x04\x65\xaa\x2c\x16\xdc\xe7\x5d\x3b\xcc\xac\x6b\x17\x22\xa6\x74\x24\x75\x72\xb5\xf5\x4a\xa1\x00\x27\x4a\xa6\x4a\xdc\xbe\x6d\xa0\x8b\xf8\x53\x48\x42\x12\xcb\xd3\x68\xaa\xb2\xb6\x19\xe6\xf1\x97\x96\x11\x24\x5e\xb0\xf4\x47\xd6\x58\xc3\xf4\xe5\x79\xf3\x65\x72\x5b\x2a\x87\x27\xcf\xb1\xec\xea\xb6\xac\x30\x4e\x37\x5e\xdc\xa5\x0a\x93\x50\xbb\x18\x65\x59\xf4\xcc\x1b\xf3\x23\x45\x45\xb6\x6c\xe1\xd0\x3a\xe8\xfb\xd2\xd7\x0e\xcf\x27\x4e\xa5\x8a\x25\x66\x80\x9d\x46\x89\xc8\x47\x02\xa4\x51\x60\xab\xbb\x7a\xfd\xd1\xbf\xd9\x9f\xdd\xd1\x9a\xa4\x68\x1b\xbd\x48\xef\x7f\xf8\x06\x11\x32\x4f\xa1\x86\x95\x5f\x03\xf7\x53\x6a\x91\x24\xbd\x82\xd7\xff\x94\xf2\x79\xca\x0f\xd2\x3f\x0d\x24\x0c\xd3\x4f\xaf\xd9\x4f\x18\x6b\xeb\x4e\xc7\xf2\xe0\x02\x20\x79\xc8\xbc\x2c\xdc\x29\x2f\x67\xcb\xd3\xdb\x7e\x4a\x24\xdc\x47\xac\xb3\x2b\x44\x8c\x04\x1d\x44\xa1\x87\xfe\x5e\x51\xf7\x4c\xd2\xbc\xd2\x80\xd0\xaa\x8b\x9a\xe5\xa3\x85\x43\x05\x41\xa2\xe2\x2e\x9b\xb7\xef\x68\x61\x86\x45\xaf\xa3\xff\xfd\xb4\xe1\xbf\xff\x5f\xf6\x4f\x7f\x71\x63\x6d\x88\x3c\x6b\x37\x24\xd8\x43\x75\xac\x27\x65\x92\x8a\x30\xbb\xf4\x39\x26\x52\x04\x74\xb5\xcb\xcc\xf0\x89\xfd\x88\x54\x14\xac\x5e\xcf\xe2\xe6\xf7\xcd\xee\xe9\x79\x5c\x78\xa8\xc2\x88\xe3\x6b\xc5\x9c\xfe\x93\x59\xbc\x14\x99\x2a\xab\x62\x53\xdc\xb6\xae\x61\x77\xc5\x90\x51\x5b\x30\x6f\xb3\x54\x13\x8b\x5c\x85\x3c\x4a\x52\xb7\xbf\x36\x2e\xe2\x66\x19\x7e\x9c\x3c\xec\x80\xa9\xb5\xed\x0e\x71\x12\xf7\x80\x17\x64\xd2\xb2\xe2\x30\xdf\xae\x33\xd8\x2a\x0a\x38\x96\xf9\x3d\x8a\xcc\x9f\x20\xa2\x29\x9a\x23\x15\x9c\x72\x6b\x0b\xf8\x06\x19\xa3\xda\xe5\xe1\x5c\x9c\x84\x7a\x5f\x9c\x2b\x71\xa5\x81\xdc\x76\x03\xeb\xe2\xa2\x9f\xd0\x71\xea\x3c\x19\x5f\x25\xd0\xc7\x57\x15\x53\x69\xea\x66\xc7\x4e\x55\xe2\x74\x69\xbd\xae\xd1\xd0\x53\x71\x92\x78\xd5\xf5\x76\xe3\xce\x8a\xd7\x5d\x53\x89\x06\x5e\x2f\x57\x1d\x39\xd2\x7c\xed\x5a\xc7\xa4\x5d\x16\x1e\x06\x40\xe5\xb1\xba\x51\xdb\x5b\x44\x88\x12\x3c\xc8\xf3\x65\x9b\xfd\x82\xdc\x2a\x10\xfe\x55\x36\x68\xb4\x1e\xa9\x18\x0c\xe7\xdd\xe4\x3e\x9e\x6a\xcc\x86\xcf\xad\x6f\x2a\x11\x2a\x71\xc4\xde\xed\x8c\xf9\x86\xd3\xa6\xdf\x01\x15\x67\x04\xe1\x1f\x03\x49\xb6\xc7\xf2\xbe\x2c\x5e\x91\x25\x78\x4e\x05\xc4\x1f\xc8\x49\xe0\x6c\xf6\x75\x75\xc6\xe8\xd7\xfe\xad\x82\xfa\xad\x75\xcc\x26\x5d\xb5\xd4\xb4\xa3\x5c\x42\x86\xb2\x87\xac\x87\x74\xa8\x34\x20\x68\x7a\x9b\xec\x17\xe8\xfb\xf2\x75\x72\x78\x1a\x08\x4c\xbc\x9d\x11\x26\x3f\xb0\xf2\x54\x1a\xc5\x1e\x9e\x80\x16\xfb\xf8\x2d\xb5\x9b\x4e\x32\x00\xa9\x6f\x0a\x53\x0e\x2c\x64\x25\x92\x10\x43\x07\x62\x07\x8d\x45\x84\x4d\x2e\xac\x98\x8e\xa4\xbf\xef\x1f\x90\x39\xfd\x78\xdf\x2a\xac\x34\xb5\x05\x7f\x3c\x88\x2c\x9f\x1e\x6e\xc2\xd8\x9b\x1e\x90\xa1\xf5\xf7\x54\xc0\x4b\xdd\x3d\xb7\x8e\x34\xba\xcd\x65\xff\x83\xc1\xcd\xb7\x1d\x93\x8d\x7a\xdb\x3b\x23\xeb\x93\xb2\xca\xf1\x30\xd4\x52\x7a\x3e\x4b\x9b\xd1\xea\xf5\xec\xaf\xcd\x85\xf1\x8d\x42\x12\x23\x95\x80\x0d\x8d\xda\xe0\xd9\x74\x3a\x00\x58\xc2\x4d\xa1\xf5\xbe\xfc\xaa\xfa\x42\x19\x1a\x60\x98\xa7\xca\xd4\x5b\xeb\xdd\x18\xf3\x55\xc2\xcb\x1f\xc4\x62\xcf\x4c\xf8\x52\x43\xb5\x68\xfa\xc4\xfc\x0c\xef\x1f\x0b\x74\x10\x48\x4c\x12\x77\xfa\xa8\x0e\x6c\x7e\xcd\x0a\x3d\x67\x29\xeb\xd6\x72\x0f\xba\x5d\xf7\xf7\x3e\x6e\xe1\x98\xc4\xc6\x17\x23\x54\xa0\x97\x7c\x12\x97\xce\x42\x9f\x7d\x78\x4d\x92\x04\x69\x43\x97\xe7\x0b\x5a\x40\x9f\xc4\x97\x35\x4d\x52\x0c\x0b\x78\x8e\x82\x0f\x51\xe9\x87\xac\xc0\x42\x84\x71\x71\xf7\xf8\x30\x69\x84\x27\x2d\xf5\x74\x1c\x87\x21\xb1\x91\x77\xec\x75\xe4\x28\xe6\xce\x35\x54\x77\xd0\x6c\x2d\x9b\xc2\xfe\xd7\x55\xcd\xc2\xe4\xbd\x46\xc2\xee\x54\xca\xa7\xf3\xee\x4a\x91\x0f\xf5\x5a\xda\x3e\xd2\x56\xee\xcb\xf3\x85\x04\xc1\xbb\xf7\x05\x5c\x2b\xd6\xc0\xb8\xa4\x20\x82\x96\xe1\x54\x76\x6d\x29\xc1\xfa\x2a\x47\xf6\xb5\x5d\x3f\x1f\xd6\xfb\xef\xeb\xe7\xc3\xf6\x79\x3d\x28\x93\xd3\xb1\xe6\xb8\x17\x1e\xec\xe4\x1a\x8a\x2e\xce\x8e\x7e\x9d\x70\x83\x71\x56\x24\xdb\xb9\x45\x0a\xf8\x91\x02\x8c\xef\x26\xad\x08\xab\xd5\x20\xf9\x92\x80\xcb\x66\x43\xe6\x7a\xf8\x73\x69\x9a\x06\x03\xa3\xf6\x60\x4b\x67\xbf\x75\xcd\x02\x99\x14\xee\x76\xdf\xbf\xf2\xd9\x34\x0f\x38\x32\x6d\x5a\x4a\xa2\x71\xde\x5e\xf3\xc0\x80\x55\xdd\xd4\x4f\xc6\x20\xea\xef\xeb\xcf\xc7\xa5\x42\xcc\xd2\xee\xe1\x7e\x26\x10\xa3\x53\xca\xb0\x36\xfd\x79\xbd\x5c\xdf\xaf\x9e\x36\x8f\xfe\x42\xa9\xb4\x55\x2e\x5b\xd1\x54\x65\xf1\x54\x40\xcf\x9d\xdc\x75\xd1\x11\x4e\x82\xc2\x25\x50\x9c\x99\xda\x7d\x77\x91\x1a\xd4\xda\xdf\x41\x9e\x7b\x85\x8d\xf6\x67\x1d\x62\x6e\xfa\x7b\xa9\x73\xf4\x9a\x3a\x1b\x40\xcb\x84\x22\x79\xc6\x51\xfc\x5a\x89\x93\x8b\xb6\xf9\xe3\x14\x8d\x2d\xef\x11\x9a\xf1\xf5\xd5\x9c\x54\x51\x28\x1c\xe8\xeb\x4e\x1c\xe1\x41\xa8\xb7\xac\x80\xab\x4e\x12\x37\x08\xa1\x75\x7b\x8a\x5b\x00\x3d\x0a\xc9\x4e\x4d\xd8\xaf\x82\x0f\x9f\x70\x74\xb5\x57\x51\x80\xb6\xf6\xf9\x34\x8c\xd1\x6a\xad\x63\xe3\x99\x0c\xca\xf5\xb1\x35\x83\xa1\x5a\xfc\x7c\x75\xee\xe3\x9c\xa3\xed\xcf\x08\xdc\x12\x93\xad\xa0\xce\x2a\x31\xc2\x7c\x69\xd0\x96\xcf\x52\x68\xdd\xcc\xda\xe3\xe3\x95\x06\x34\xa0\x29\x6e\xab\x2e\x6f\xaa\x73\x17\x3a\xd2\x86\x04\x88\xa6\xc5\x22\xa5\xec\x9a\x5f\xc4\x77\x4b\x00\xc9\x15\xce\x45\x5d\xe6\x4e\xb8\x64\x84\x1a\xd7\x86\x9b\xc4\xca\xbf\x3d\x83\xd0\x93\x5a\x2b\x08\x88\x15\x3d\x1d\x08\xd1\x8e\x92\xf2\xd1\x68\x42\x40\x10\xc6\x28\xc6\x21\x50\x19\xad\xab\xb9\x1a\xe5\xb8\x20\x88\x25\x66\x2a\x30\xf1\xe2\x09\x8e\x7c\x1b\xb7\xa1\x35\x0d\xae\x5a\x77\xcc\xcf\xc5\x02\x20\x51\x82\xea\x1a\xcb\xdf\xd6\x7f\xac\xca\x11\xe3\x08\x90\x24\x44\x20\xde\x51\xfc\x6a\x8d\x94\x8e\xdb\x17\x9b\x52\xb4\xa5\x0e\x52\xe8\x57\xb8\xad\x00\xfe\x33\xb1\x41\x81\xc8\x94\x39\x3a\xda\xdd\x5b\x76\x72\x6c\x24\xab\x5c\xd4\xf5\xf2\xf2\x50\x6a\xc8\x47\x45\x53\x40\x63\x45\xc3\x41\x9d\xd1\x52\xd4\xd0\x69\x2b\xb5\xed\x89\xc1\x44\xe1\x3e\x53\x7b\xa1\xf6\xa5\xd3\xce\xb3\xac\x19\x7f\x91\xf7\x1f\x2f\x0d\x40\xb9\xc2\x04\xc5\x6e\xbd\x7a\x7a\xbc\x39\xbc\xec\xd6\xcf\x87\xd5\xcb\xbe\xbb\x92\x52\x4e\x03\xa0\x42\x16\xac\x45\xa1\xdd\x66\x58\x8f\xf8\x4a\x20\x8c\x42\x04\xd3\x9e\x86\xd2\x92\xed\xef\x49\xea\xd5\xab\x3b\x83\x63\xea\xbf\x74\xa5\x4a\x10\x72\x40\xca\xbc\xd7\xaa\x3c\x9f\x6c\xf2\x0b\x9f\xdb\x7a\x39\x93\x5b\x0f\x25\xc1\xaf\x6d\x63\xff\x33\xb6\x3f\x44\xa1\x42\xfb\x41\x75\x97\x9b\xd9\x3e\x21\x92\x41\xec\x82\x71\xc1\x2f\x0f\xbc\xfb\x51\x89\xd3\x69\xba\xbc\x00\x23\x21\x62\x9e\x5c\x9e\xf3\xa5\xee\x42\x58\xc0\x52\xc0\x17\x99\xd5\x0e\x27\xe6\x7e\x4f\x82\xd8\xc8\x8e\x2f\x0c\x35\x27\xac\xcf\x3a\xbe\xd5\x84\x1a\x7c\x4f\xcb\x0a\xc4\x7b\x77\x2c\x8f\xd3\xc0\x4b\x4f\x1e\xc1\x67\x04\xbe\x0d\x72\x44\x90\x68\x2b\x1d\x88\xda\xd2\x15\x34\xe5\xcc\x0a\x0f\x9c\x08\x17\xdb\xe9\x48\xcb\xac\x68\x70\x33\xe2\x24\x02\x4e\x00\x87\xf9\xc1\x2a\x53\xc2\xec\xb9\x1c\x3f\x4a\x6b\x06\xac\x0b\x1d\xfa\x9b\xe5\x8c\x63\xf8\xc0\xca\xc3\x5b\x6a\xb7\x39\x24\x9c\xef\x1e\x83\x2f\xd9\xc7\x80\x36\x26\xc4\x45\x33\x5f\xa2\x0a\x3c\xe1\x98\x5b\xb7\xb1\x09\x0c\x60\x8e\xb9\x28\xae\xf2\x68\x9f\xe3\xa4\x21\x35\x29\x06\xd4\x5c\x44\xe0\x36\x13\xcd\x16\xaa\x75\xf3\x36\x28\x22\x04\xe1\x2a\x3c\xf3\xb2\x7c\x3f\x9f\x36\xbb\xa7\x90\x90\xf8\x40\x0e\x22\x3f\xbd\x89\x03\x1d\x7d\x03\x41\x2c\x97\xd1\xc3\x65\xa3\xcb\x7c\x55\x8e\x19\x70\x40\xb0\xd0\x46\xf5\x3d\x02\xbf\x50\x65\x55\x81\x6a\x5c\xf9\xc7\xb2\x2c\x74\xbd\x2f\x7f\xd8\xb0\xb9\xf5\x8e\x7d\xd4\xbd\x3b\x47\x4a\x11\x07\xee\x0a\x6b\xd1\xa6\x98\x5d\x98\x41\x52\x8d\x99\xad\xe5\xf2\x71\x74\x06\x99\x00\x3a\xc2\xbb\xf3\x09\x2a\x25\xaa\x71\xa3\x88\xb0\x9a\xf8\x67\xd9\xc0\xae\x10\xa7\xfa\xad\xf4\x25\xcc\x23\x72\xaa\x99\x0f\xa9\xa8\x95\xd5\xb0\x75\x7a\x58\x36\xd6\xf5\x66\xff\x1c\x1c\x10\xff\x73\xee\x68\x96\xa2\xc3\x88\xe8\xd2\xfb\xac\x6e\x76\xad\xe5\xa4\xae\x66\x9e\x8a\x25\x71\xd3\xa8\x75\x6b\xdb\x65\xc4\x05\x66\x5d\x07\x4d\x2d\x29\xc5\xa9\x7c\xef\x0a\x20\x47\xd1\x11\xd0\x31\x45\xed\xc9\x5c\x20\xe6\xe1\x1d\xb1\x13\xe3\xab\x68\xcd\xb1\x18\xaf\x40\xea\x68\x0c\x34\x2f\x8a\xcb\xbe\x5c\x14\xd3\xed\x0b\x62\x3b\xed\x94\x28\xf4\xe5\x5e\x74\x16\x1e\x80\x14\xb8\xbf\x1f\xb3\x22\x2b\xce\xc7\xed\xb0\x2e\xeb\xef\x67\x61\xb5\x11\x5d\x5f\x13\x4a\x5f\x31\xe6\x59\x73\x7e\x2f\xfb\x6c\xc7\xf8\x8a\x46\x25\x2a\xe8\x68\x6a\x54\xb3\x2f\x97\xe7\x0c\x99\x15\xdd\x26\x38\xea\x6e\x82\x44\x19\x4f\x59\x05\xa2\xed\x36\x53\xf1\x6c\x02\xce\x03\x5f\x45\x8f\xae\x89\xc7\x00\x78\x44\xc4\xa4\xbb\xe1\xa1\x03\xf6\x0e\x21\x11\xed\x7f\xbd\xca\x02\x0b\x0c\x21\x89\x8f\xa4\x6c\x5d\xb4\xa9\xfe\xc4\xe9\x31\x44\xc5\x63\x9f\xad\x75\xf6\x5f\xbd\x4a\x08\x0b\x0c\x35\xd2\xa7\xb8\x86\x38\x20\x13\x6a\x8d\xc1\x5f\x87\xf8\x04\x17\xcf\xf2\xcd\x11\x63\xe8\xfa\xe2\xb6\xf3\xfc\x96\x15\x65\xd7\x12\x53\xcc\xe7\xfe\xb4\x4b\x4e\x56\x16\xb7\x22\xcb\xa7\xce\xad\x89\x62\x40\x33\x5b\x89\x5c\xcd\xc4\xa6\x4d\x94\x6a\xaf\xf5\xb2\xcb\x33\xdd\x2e\x86\xc3\xbc\xba\xef\x65\x52\x8b\x4b\xd5\x1a\x63\x41\xf3\xb3\xd6\xb0\x20\x54\xd6\x58\xda\xd5\xa7\x6b\x9b\xc8\xf7\x02\xe3\x6b\x7f\x7e\x94\xd5\xa7\x20\x02\xd7\x3b\x21\x0c\x39\xc4\x0a\x50\xa2\x7e\x1b\xce\x77\x93\x28\xcb\xef\x88\xe5\xac\xef\x50\x8c\x36\x73\xc3\x8d\xc2\xd4\xd3\x7d\xf9\x3a\x2a\x5f\xb9\x29\xd5\xf9\x08\x45\x63\xc9\x87\xf4\x3c\x49\x8d\x49\x09\x40\x38\x8d\xeb\xd7\xcf\x1e\xd6\xe6\x2f\x92\xb2\x58\x4b\x47\x2c\x3a\x32\x1c\x4d\x1a\x4b\x24\x88\x39\x66\xc5\xba\x79\xdb\x42\xf5\x58\x5e\x95\xd0\x98\x54\x86\x29\x0c\x95\xfc\xbf\xb6\x78\x8d\x60\x1a\x61\x61\x58\x27\x12\x2d\xe1\x35\x2b\x3a\xaa\x57\x16\x18\xc9\x44\x4a\xad\xf7\xda\x3a\x39\x9d\x50\xf9\xc8\x3e\x31\xca\x18\xd4\xe3\x81\x5f\x36\x12\xfb\x5d\xe4\xe6\x3e\xeb\xf2\x24\x46\xcb\xc0\x4b\x94\x3c\xc2\x87\x03\xc5\xcf\x7f\x1c\x60\x96\xe9\x01\x79\xf7\x7e\x66\x0d\x9a\xff\xcb\x6c\xaa\x81\xe9\x19\x07\x0c\x08\x85\xdc\x04\x38\x9f\x2c\x20\xdd\x5f\x15\x74\x88\xa6\xb8\xbc\x16\x01\xbf\x0e\x19\x76\xdb\xa0\x01\x43\x11\x18\x82\xfe\x82\x83\x63\xdf\x83\xe9\x3e\x83\x71\xda\xcb\xcf\x87\xc7\xc3\xcd\xe1\xc7\xe2\xfe\x7e\xbd\xef\xda\x68\x80\xce\x3e\x14\x7a\x61\x49\x51\xba\x96\x84\x52\xd9\x95\xa7\x15\x05\xe4\xf5\xdd\x39\xeb\x90\x32\xc6\x48\xc0\x9c\x15\xb2\x65\x2c\xc5\xd8\xba\x20\xc8\xfd\x29\xdd\xf2\x79\x3c\x1f\x37\xaa\xec\x37\x65\x12\x04\x51\x80\x7a\xf6\xce\x3c\x71\xac\x78\xbe\x31\x0e\xa8\xe5\xd7\x85\xd6\x4b\x50\x43\x63\x78\xf8\xee\x49\x10\x68\x89\x29\xff\xdd\x9f\xab\x95\x3f\x9a\x24\x16\x10\x92\xd5\x4f\xe7\x46\x95\x08\xaf\x1b\x85\x0e\x49\x40\x38\x47\xc4\xd7\x6a\xfb\xc7\xd0\xc8\x25\x01\x25\xa9\xb2\x84\xc9\x06\x39\x99\xac\x0f\x3c\xae\xcb\x26\x01\x4d\x42\x2c\x21\x5d\xbf\x3c\x3e\x3d\x6c\x16\xdd\xcf\x42\x7b\xf3\x73\x83\xc0\xd5\x2e\x05\x30\x7e\x33\x54\xaa\xd4\x93\x1e\x66\x4d\x3e\x1b\xd9\x25\x01\x05\x5b\x54\x8d\x45\x6d\x65\x01\xae\xa8\x6d\xfd\xef\x51\x3d\x2b\x09\x42\x61\xb5\x9f\x6c\xa5\xf2\x55\x1d\x93\xeb\x15\x09\xcb\xd1\x2a\xcf\x95\xd7\x6b\x1b\x7a\x5c\x24\x88\x94\x64\xaa\x23\x08\x7b\x2a\x96\xf0\x26\x72\x33\xb9\x73\xa6\x4d\xe8\xa8\x4a\x6c\xf0\x72\x79\x59\x0f\x32\xaa\x53\xee\xf8\xb9\xe2\x29\x12\xc4\xd2\x32\xa8\x34\x9f\x54\x29\x4c\x62\xea\x24\x48\x52\x8a\x81\xdc\xb7\x8b\xae\x4a\x57\xd5\xfb\xd0\xa3\xb3\xff\x36\xbe\xc7\x44\x05\xc8\x12\x7e\xbb\x5c\xaf\xfd\xc3\x25\x46\x63\xd5\xb8\xcd\x02\x76\x24\xc0\x8c\x04\x22\x04\x1c\x6a\x55\xeb\x0b\xd1\x41\x21\x1b\x09\x04\x10\xcc\x57\xfc\x29\x8a\xd7\xfa\xed\x2c\xb2\xbf\x8c\x73\x92\x40\x12\x86\x1c\x10\x58\x35\xd4\x6e\xac\xea\x6d\xbc\x8d\x90\x40\x9a\xc0\xca\xb4\x61\x48\xda\x85\x26\xfd\x35\x15\xb5\x4a\x6d\xa8\x12\x2f\x54\x0e\x9d\xaa\x76\xdb\xc8\x38\x4a\x6f\xdd\x65\xaf\x69\xf7\x1b\xa7\x98\x41\x5b\x89\x06\x5e\xcb\xea\x72\x03\xd6\x15\x18\x5f\x53\x29\x19\x85\xc3\x25\xb6\x9e\xf0\xf5\x90\x40\x3b\x6e\xff\xcd\xea\x69\xd7\xfa\x03\x8e\xc5\x75\x72\x22\xa0\x21\x58\xdc\xbc\x1d\x8c\xc3\xda\x8a\x4d\xa1\xe1\xd7\x84\x7c\x88\x04\x10\x51\x8c\x4f\xb8\xea\x98\xdb\xb2\x6a\xf7\xb0\x6b\x0d\xbe\xc9\x51\x82\xa2\x3a\x5e\x27\x1c\x24\x8e\x65\x71\x25\x1c\xf4\x45\x00\xc7\x9f\x47\xb1\x14\xe1\x83\x96\xe3\xc2\x65\xb9\x26\xdb\xcc\x78\xfc\x80\xb1\x04\xcd\xd6\x7b\xfc\xfb\x59\x54\x0d\x54\x3b\x10\x75\x59\x7c\xeb\x42\x38\xd8\x4d\xc3\x50\x8b\x15\x1a\x31\xe4\x08\x18\xdf\x87\x89\x22\x5c\xee\x06\x44\x5c\xbd\xcb\x49\x02\x23\x0d\x1f\xc1\x48\xc7\x4f\x68\x7b\x91\x20\x61\xc2\x61\x23\x36\x27\x53\xfb\x64\x76\x3d\x09\x0e\x13\x12\xe8\x90\x38\x4e\x71\x0d\xeb\xe6\x6d\xf7\xf6\x49\x79\x0e\x21\x84\x46\x3d\xe5\xd1\xc3\x39\x6f\x9e\x7e\x42\x65\xf2\xf2\x63\xd6\xc6\x23\x84\x44\x92\x46\xbe\x70\x02\xd5\x0a\xb3\xe6\xed\xa9\x79\x83\x6a\xcc\xe0\x3f\x39\x8a\x1b\x32\x24\x25\x68\xcd\xcc\xdd\xa5\x6e\xe0\x1a\x8d\x3f\x3e\x90\x9a\x80\x2a\x6f\x31\x7a\xe4\x24\x21\x61\xbb\xca\xdb\xf7\x65\xa9\x9f\xee\x44\xdd\x29\xb7\xf6\x47\x87\x2c\xc2\x18\xa2\x65\x88\x79\x70\x16\x92\xcf\x7b\xf9\x4e\x9a\xa1\x99\xbf\xdc\xaf\xd6\xfb\xd5\xe4\x0c\x11\x55\xca\x66\xc1\x1c\x71\xce\x2b\x74\x24\x28\x84\x44\x22\x45\x14\xf9\xfe\x0d\x96\x50\x37\x5e\x26\xb2\x6d\x51\x12\xe9\x51\x8e\xe2\x1d\xb6\xe2\x72\x9c\x92\x46\x12\x92\x50\x8a\x95\xfa\xfb\x8f\x72\x61\xaa\x4c\x4d\x07\xce\xf8\xd3\x27\x0c\x02\x17\x7c\x79\x3c\x1f\xdd\x1c\xee\x80\x0a\xed\x48\xb0\xaf\x0f\x06\x83\x61\x02\x06\x24\x84\x07\x56\xc6\xc0\x16\x26\xda\x81\x36\x5a\x9a\x49\x4a\x39\x32\x85\xdd\x41\x01\x75\x56\x2f\xcf\x17\x1b\xa6\x98\x9d\x29\x24\x0d\x2d\x27\xc1\xfd\xcb\xef\xbd\xc2\x43\xfb\xbb\x08\x11\x22\x73\x67\x93\x3d\x7d\xbc\x8b\x10\x21\x00\x59\xac\x84\xd6\xb7\x15\x00\xba\xa5\xd5\x5f\x55\x29\xf9\x63\x95\x46\xbe\x1f\xab\xaa\x83\x7a\xe9\x61\x70\xd8\xae\x9f\x57\xeb\xc7\xbd\x15\x7f\xf6\x97\x91\x44\xa3\xcb\xd4\x9e\xe8\xdb\xe8\x45\xca\x28\xb2\x7c\x40\xe5\xc7\x69\x90\x32\x26\x44\xca\x88\xd8\xfd\x4f\x8a\x06\xf6\x1f\xe5\x2d\x14\xc7\xf3\xa1\x6b\x56\x01\x26\xe4\x0f\x42\xeb\x6b\x6e\x0f\x42\x14\xd3\x08\xb6\xda\x75\xb8\xa5\xdb\xb2\x7a\x46\x98\xe9\xa4\xa7\xa6\x14\x39\xd7\x7c\xcd\xd7\xe3\x72\x75\x45\x0c\x41\x08\xd0\xd8\xd7\x3e\x94\x5a\x2f\x0a\xdd\x4e\xaf\x25\x7c\x92\x70\x22\x04\x58\x8c\xb8\xa9\xdf\xc4\xf1\x3c\xf0\x0f\x08\x01\x6e\xf5\x70\x5a\xa3\xa4\x5e\x9c\x9b\xd2\x55\x2f\xf5\xc1\x22\x42\x40\x72\x3d\x50\x54\xb5\x35\xa7\x7f\x15\x7d\x1c\x8f\x1c\x23\x22\xee\x92\xb1\x0f\x59\x81\xc5\xba\xa3\xc7\xa6\x41\x44\xd3\x2e\xde\xbf\x1b\x24\x91\xc7\x0f\x42\x83\x58\x73\xe2\xb7\x2a\x33\xb2\xce\x68\x20\x25\xed\xca\x3a\x6d\xbe\xa8\x7e\x2a\xba\x56\x13\x50\xee\x3c\xe0\x49\x92\x6d\x7c\x2b\x34\xa0\x5e\xac\xf2\xe9\xfc\x33\xd3\x65\x95\x89\x75\xa1\x4f\x65\x56\x34\xdf\xe6\x8f\x08\x0d\x22\x4f\x5a\x37\x6a\xc4\x5f\x34\x3b\x52\x29\x8d\x13\x69\x4b\x49\xdb\x79\xba\x53\xa2\x52\x59\x73\xb1\xeb\xbe\xbf\x5b\xca\x55\xe4\x52\x17\xde\x45\xd9\x56\xa5\xc9\xfe\x62\x16\x50\xaa\x62\x4b\xa2\x68\x5f\xf2\x27\x55\x73\x7f\xf9\xef\xff\x06\x29\x4f\x68\x98\x5a\xb6\xfa\xe5\x66\xbf\x7a\xda\x3c\x6c\x1e\x37\x77\xdf\xba\x26\xa3\xbb\x20\x61\x57\x69\x0d\x53\xbb\x82\x86\x40\x50\x99\x1a\x46\xb1\x27\xd7\x18\x85\x16\x53\x72\x5f\xbe\x2e\xcb\x72\x2a\x29\x34\xb7\x09\xd2\x48\x58\xc5\x1c\xc4\x04\x5c\x55\x08\x13\xca\x68\x84\x08\xc6\x2e\xc1\x69\xcb\xe6\x97\xcf\xde\x4c\xa7\x2c\x4a\xd0\x46\x5b\x5d\x8a\x77\x95\x89\xea\x3f\xc3\xf9\x42\x59\x12\x60\x69\x9e\x8d\x4f\x2e\x47\x95\x9f\x9e\x9b\xba\x9b\x39\x94\x25\x69\x2c\x3a\x63\xc1\x97\x60\x6d\xab\xb2\x34\xa8\x12\x6d\xe9\x60\x7c\xe7\x34\x41\x52\x1c\x4b\x06\x32\xdc\x94\x5d\x87\x24\xe2\x91\x8d\x54\xbe\xda\xdd\x74\xc6\xe0\xec\x09\xc1\xbf\xac\xea\x25\x34\x11\x96\xeb\x12\xe5\xd6\xb2\xba\xa3\xfc\x1d\xbd\xcd\x44\x09\x2c\x2b\xa9\x5a\xd3\x2c\xab\x6a\x2b\x4e\xeb\xdf\x05\x17\x32\x91\xf6\x86\xad\x5e\x98\x29\x0f\xbe\xda\xb7\x4f\x67\x11\x9a\x06\x29\x16\xfa\x6c\x1e\xef\x56\xf7\xdf\xba\x1f\x35\x22\x41\x55\x69\x6c\x9e\x61\xd9\xb5\x24\x0a\xa1\x5a\x22\xab\x6e\xaa\xf2\xe4\x30\xc9\x96\x56\xdf\x75\x11\xa9\x0a\x43\x2f\xfe\xd2\x97\x9e\x7e\x56\xb0\xf0\x15\xb4\xe6\x13\x58\xc5\x78\x54\xc9\x38\xc2\x5b\x3a\x9c\x6c\x46\xe7\xa6\x84\xfa\xb1\x6c\xd6\xbf\xa6\xac\x9e\x6d\x57\xc6\x75\x57\x7e\xe5\x9d\xb1\xf9\x95\x46\x05\x12\x17\xbd\x0a\x71\xc7\x37\x3b\x47\xce\xbb\xb3\x82\x0f\x56\xf8\xb0\xfe\x2e\xea\xb7\xb1\xc4\x18\x23\x54\xc7\x54\xfb\x50\x59\x2e\xea\x89\x55\x4d\x35\x17\xb8\xdc\xae\xf5\x87\x28\xc6\x03\x58\xeb\xc0\xf3\x1b\x6d\x1a\x38\x8e\xbc\x3c\x6a\x08\x60\xe4\x14\xd5\x7b\x51\xae\x73\x10\x7a\x25\xd4\x70\x93\xf6\x70\x67\xc7\xf7\x3a\x19\xa4\x26\xe5\x69\xd0\x7f\xbd\x5b\x24\x83\xef\xbf\x9c\x51\xb6\xce\xc3\xcd\x88\x76\xab\x0c\xa7\x67\x30\x14\xfd\x98\xd5\xf7\xf5\x1f\x63\xc8\xe1\x97\x23\x3a\x0c\x62\xc1\x11\x5b\x95\xd5\xbf\x97\x88\xa1\x1f\x9b\x2f\x61\x20\xa3\xc0\xd5\x52\x39\x12\xf1\x65\xa6\x67\x2a\xaa\x49\x18\x28\x8e\x19\x27\x53\x56\xef\xbd\xfb\x15\x12\x1d\x82\xf3\xe0\x5f\x6a\x9f\x01\xec\xa7\x7b\x48\x4c\x80\x76\x6c\xaf\xaf\x65\x53\x56\xfe\x78\x9a\xd8\x08\x3a\x1c\x4f\xcd\xa5\xc3\xd1\xf8\x46\x6e\xc7\x98\x43\x82\x5e\x4d\xff\x90\x1a\x81\x3c\xe2\x75\x23\xde\x61\x86\x38\x93\x84\x21\x49\x30\x95\xb1\x59\x3d\x1d\xec\x2e\xde\x35\x08\xbf\xa5\x3d\x97\x39\x8c\x84\x54\x48\x18\x91\x14\xe3\x78\x6e\xf4\x79\x71\xa4\x07\x57\x3d\x3a\xbf\x13\x87\x11\x67\x28\xc0\xb4\x12\x79\xfe\x8c\x38\x8d\x4f\x02\x85\x24\x8c\x52\x8d\xc5\x2a\xb5\x7a\x03\x7d\xce\x61\x9f\x7d\x52\x31\x4c\x42\x16\x24\x89\xf4\x65\xe3\xc8\x22\x82\xe0\xb6\xe1\x6c\x0c\x19\x0b\xe3\x21\x13\x5c\xeb\x63\xdc\xc2\x97\x6a\x3f\x78\x94\xf2\xf9\xb9\xaf\xae\x1f\x73\x74\x1d\x74\xb9\x3d\x7f\x92\x12\x27\x21\xd3\x56\xa5\xf0\x15\x9a\x9d\x2a\x3f\xa1\x19\x1e\x78\x5c\x21\xd3\x06\x77\xb9\xc7\xb2\x58\x58\xa9\xa1\xac\x1c\xe8\x53\x0f\x0b\xd6\xfd\xa1\xfc\x9f\xd3\x8b\x9a\x04\x8d\xef\xa5\xa8\x33\x35\x19\x1a\x71\x90\xa6\x96\x28\x00\x8e\xd9\xf9\x68\x49\xf8\xfe\xc2\x42\xbb\xca\xd1\x90\x30\x6e\x0d\xc5\xae\xd8\xb0\x39\xd7\xa3\x72\xc8\xc1\x40\x8f\x69\x1c\xe8\x4e\xdd\xfd\xdd\xd5\xc8\x39\x1a\xd8\x3e\xda\x4a\xc2\x24\x15\x18\xfb\xed\xd7\xe8\xab\xab\x4f\x1e\x33\x11\x22\x91\x9d\x22\xee\x95\x01\x33\x1e\x58\x89\xd6\x68\x2c\x97\x45\x7e\x89\xe3\xb8\xbb\xaa\x86\x44\xf4\x8c\xd1\x33\xf7\xc5\x59\x12\x49\x1f\xbf\xfd\x85\xb5\xaa\x65\xb1\xdf\x3f\x58\xa4\xa0\x0e\xbf\x0d\x42\xb2\x24\x4c\xa9\xe5\xc2\x44\x85\x74\x8b\x2a\x18\xd6\x3d\x4e\x00\x06\x24\x14\x01\x89\x3a\x15\x11\xb5\x2a\xab\xd9\x64\x27\x09\x45\x6a\xab\xc7\xfe\x14\xff\x2e\xcb\x61\x25\x04\x09\x85\x4e\x31\x22\xb0\xfe\x69\x13\x81\x57\x9c\x98\x93\xd7\xa6\x24\x41\xde\x8d\x8e\x4b\xfd\x65\x77\xf3\xc9\x10\xd7\x01\x47\x1f\x67\x2b\x0a\x0d\xc7\xd6\xb5\xf4\x0d\x24\x76\x42\x4d\x8d\x2b\x1f\xec\x85\xd2\x26\xa7\x00\xa2\x7b\xd6\xd3\xf6\x9d\xd4\x13\x46\x40\x12\x9a\xc4\x96\xd7\x63\xd4\x79\x14\xb6\xf0\x1d\xd2\x14\x3a\x59\x36\x0b\xda\x9a\x9e\x42\x2b\x70\x7e\xda\x2a\x07\xd1\x2e\x01\xe8\x70\xba\x14\x72\x39\xf1\xb2\xa2\x80\x68\xc4\xe2\xbe\x22\x22\xe8\xd7\x12\x46\xf9\x06\x12\x05\x91\x42\x0a\x4f\x53\x56\xaa\xbd\x6b\xa8\x9b\x27\xf3\x84\xb1\x53\xa8\x67\x4e\x97\x1a\x2c\x91\x76\xd5\x41\xfb\x0a\xb3\x6b\x2e\x30\xe1\xfa\x50\x69\x45\x00\x2a\xa7\x16\x73\x0b\x30\xc4\x1a\xb7\x1d\x14\x81\x4e\xd4\xbe\xfc\x00\x8d\xe4\x1c\x4f\x66\xf5\x56\x66\xaa\xdb\x1b\x22\xaa\x42\x04\x3c\x59\x95\x83\xf5\xbf\x49\xe8\xac\xc3\xf0\x6f\xee\x6f\xd7\x31\x0c\x2c\x90\x03\xa9\xb5\x7a\xd5\x4b\xdf\x4a\x78\x10\x78\x56\x8b\x02\xd1\x64\x03\x6a\x71\x12\xb5\xdb\x8c\xf6\x96\x53\xf4\x88\x34\x28\xe3\x1b\x0e\x63\x86\xe1\x67\x3c\xbf\xd7\x5f\xaf\xfb\xd6\x38\x22\xc3\x71\xd6\xee\xa4\xab\xbf\xef\xc6\x5f\x2e\x0a\x39\xb5\x32\x64\xc7\xf2\x27\xec\xcb\x45\x05\xe2\xdb\xd8\x2c\xed\x3a\x32\x39\x50\xcc\x5c\x95\x45\x81\xac\xf8\x3d\x23\xcb\x10\x90\xe7\x0f\x12\x96\x29\x57\x7f\xc2\x5f\x38\xda\x85\xfc\x31\x40\x91\x70\xbc\xb5\xcb\xc6\x22\x3b\x7f\x9b\xdc\x3a\x00\x56\xfa\x78\x4f\xbe\x5d\xfb\x9e\x2d\xe9\xcf\xbc\x0c\x14\x89\xa2\x20\x94\x0e\x0c\x5d\x94\x1a\x8e\x65\x01\xb3\xda\xbf\x6d\xd7\x88\x60\x2d\x64\x01\x1f\xdd\x3b\x8d\x62\xc0\x58\xcf\x6a\xb3\x7f\x7e\xf9\xc3\xff\x1a\x47\x29\x5a\x2b\x76\x57\xbe\x2b\x73\xfd\xc9\x30\x8d\x19\xb7\xb2\xab\x22\x57\xa8\xd9\x0b\x35\xb2\x24\x3f\x9e\x8f\x60\x05\xfc\xc7\xb7\x10\xc7\xa9\xa3\xdc\xc1\xc2\xb9\x7a\x64\x86\x44\x89\x30\x3e\x3f\x36\xae\xe3\x21\x11\x4f\x99\x27\x56\xb7\x6b\xd5\xe0\x93\x70\xa5\x10\x38\xea\x84\xd1\x57\x80\xe5\xf4\x9f\xbc\x2f\xae\xc1\xdb\xc8\xad\x15\xd6\x2e\x30\x96\x92\xcb\x11\xb5\xbb\x6e\xa9\x31\xb8\x06\x76\x4c\x5f\xbb\xb3\x74\x94\x02\x18\x4c\x9e\x3c\x97\x88\xb8\x53\x93\xc7\x55\xc9\x21\x53\x6e\x26\xba\x9f\x6d\x47\x6e\x3b\x56\xf0\xb3\x7c\x87\x9d\x33\x4a\xfe\x2a\xa2\xe1\x0f\x06\x8e\xf4\x5d\x0f\xe2\xb5\x80\x26\x53\xf5\x75\xc6\x98\x44\x92\x84\x08\xed\x3e\x59\xde\x73\x5b\x06\xd7\xde\xf7\x20\xc7\x15\xe9\xd8\xca\xc9\xbf\x95\x55\xdd\xda\x7b\x70\x3b\x9d\x45\x3a\x09\x90\x64\xf7\xa3\xac\xde\x31\xea\xb2\x9a\x16\x95\x7f\x1e\xdb\x8e\x74\x62\x47\x9a\x86\x9f\x90\x97\xa7\x67\xfb\xb5\xc7\x1f\x5b\x2b\x03\xa1\x93\xe6\x83\xea\x20\x94\x82\x53\xd7\x08\xca\xbe\x26\x1b\x50\x5b\xad\x1f\xf7\x3e\x80\x16\x99\x20\x0c\x7b\x2b\x7e\x5b\x95\x4d\xa9\xca\xfc\x16\xe0\x19\x54\x76\xca\x26\x02\xa2\xed\x01\x21\xc1\x8c\xda\xe1\x11\x3e\x56\x9e\x13\x7a\x6a\x2d\x4e\xa6\x8a\x51\x02\x89\x4e\x2c\x43\xf1\x88\xe9\xcc\xf6\x60\x01\x0b\x55\xdc\xaf\x03\xcb\xf2\x13\xac\x0c\x61\x01\x70\x0c\x73\xad\xb6\xdb\x61\xdd\x3e\x69\x8d\x53\x9c\xba\xfb\x4c\x14\xff\x78\x3b\xf7\x34\xbf\x84\x11\xb0\xd1\x8d\xbb\xe7\xf5\xfa\x71\xb9\xd9\xfb\xdf\x29\x8d\xd0\xd8\xda\x8a\xbc\xdd\x10\xbe\x0a\xcc\x32\x1a\x01\xee\xb5\x0b\xeb\x0d\x7d\x8a\xae\x21\x8c\x0a\x89\x31\x49\xf7\x9d\xdb\x47\xce\x27\x65\xc6\x84\x85\x31\xc1\x30\xa3\xdf\x24\xe6\xe7\x17\x0b\x13\x22\xc2\x11\x1b\xc4\xd8\x0d\x75\xdd\x22\x1e\xdb\x85\xa3\x35\xce\xda\x1d\x7f\x9c\x3a\x64\x11\x17\x16\x7d\x38\xab\x53\x4e\x7d\x37\x46\x39\x5a\x5b\x1f\x1e\xf6\x07\xfa\x21\x9b\x84\x35\x19\x0b\xad\xfe\x8c\x87\xf9\x4e\x5a\xa5\x40\xfb\xf8\x28\x7e\x79\x62\x16\xdf\xa2\x3b\x55\xf8\x19\x3e\x4e\xd7\x29\x0e\xb4\xb0\x7a\xe0\xa7\x9b\xf2\x75\x10\x50\x66\x71\xc8\xb0\x08\xe4\x24\xea\xfa\x46\x74\x3f\x27\x31\x43\x7e\x3f\x14\xf6\xcd\x26\x4b\x20\xe3\x14\x8c\x2f\x3b\xdb\x56\xe5\xaf\xcb\x10\x80\xfe\x59\x64\x6c\xb0\xd7\x30\x1e\xa5\x08\x79\xb5\x18\xd6\x5f\x96\x43\xea\x2a\x8c\x7d\x95\xa9\x27\x8c\x2b\x8e\xb1\xa7\xe7\xf5\xea\x76\xf5\xf4\xc9\xd7\xe5\x20\x98\xdf\x32\xdb\x0b\xbc\xd4\x43\xc9\xd4\x49\x0c\x8d\xa5\x61\xc2\x10\xd1\x2f\xaa\x95\xa5\x85\x9f\xbc\x7b\x41\x03\xe9\xa0\x0c\xa8\x25\x2b\xae\xf8\x10\x09\x93\x04\x70\xd7\xff\x4f\x3f\x38\x64\xc8\xd0\x45\xde\xed\x17\xcf\xfb\xcd\xe3\xdd\x61\xc0\xdb\x42\x98\x22\x11\xb6\xc2\x31\x6b\x3e\xa5\x9b\x9b\xda\xf6\xa3\x99\xa3\xa4\x55\xfe\xd6\x55\x79\x42\x2c\xbf\x65\xeb\xfe\x7c\x02\x29\xb0\xf1\x7f\x09\x75\x73\xa8\xbb\x9d\xe2\x90\xe1\x56\xe1\x3a\xe9\xc8\x95\x33\x42\xb3\x6c\x5f\x88\xc6\xa2\xf9\x45\x63\xf7\x93\xd9\x75\x88\xe9\x48\xb3\xae\x7e\xc9\x5a\x5b\xf5\x94\x8d\x88\x30\x2d\x22\x99\x8e\x83\xcf\x83\xe4\x2c\x33\x84\x62\x66\x63\xf5\xf4\xf0\xf0\xf2\xb8\xd9\xff\x69\xe5\x89\x6c\x25\x44\xd7\x89\x32\x5c\x71\x6d\xee\x77\xf7\x96\x9d\x9e\x8a\x87\xf5\x62\x64\xc7\xfb\x31\x6f\xb4\xc6\xa5\xfb\x98\xbd\x62\x74\x6e\x54\x1e\x39\x19\x04\x71\x40\x19\x06\x65\x9a\xb7\x0a\xe0\x7b\xd9\x7c\x2f\xcf\x55\xed\x00\x5b\xae\x38\xea\x07\xb8\x4a\x3c\x12\x07\x4c\x63\x20\x25\x3b\x8a\x57\xf8\xde\xc9\x22\x90\x38\x10\xd6\xaa\x5b\x68\x7d\x53\x1e\x45\x66\x6b\xaa\x1c\x56\x68\x86\x8f\x9d\xc4\x24\x8c\x79\xe8\x97\x98\x8e\x20\xda\x9f\x8f\x4a\x2a\x2d\x14\xc3\xad\x3c\x9f\x56\x36\xbb\x03\xc2\x90\x78\x63\xfa\x5e\xd4\x6e\x71\x73\x61\x61\xd7\x25\x0a\x0c\xf8\xaa\xfd\x01\xaf\xc0\xe8\x63\xc5\x91\x94\x91\xf3\x5f\x5d\xce\x77\xd7\x64\xc5\xfb\xe5\xbe\xfd\xc3\x0f\xf1\x18\x51\x2a\x68\x27\x68\x28\xca\xe3\x41\x8b\xf2\xd0\xd7\x78\xb4\xed\x89\x85\xb0\x88\xf7\xe9\x05\x58\x2c\x90\x88\xf2\xee\x9c\xbd\x5a\x0b\x61\xae\x96\xee\xd3\xe0\xe3\x97\x31\xfe\x98\xc5\x06\xc1\xbb\x8b\x57\xa8\x87\x9b\x59\xcc\x12\x97\xad\xb5\x6c\x38\x9f\x69\x8b\xcf\x96\x90\x91\x98\xf1\x70\x68\x55\xa3\xcf\x3f\xb9\xb0\x08\x10\x15\x78\xb2\x42\x1b\x9f\xe1\x3a\x06\xc3\x34\x8e\x65\x8c\x1c\x47\xe7\xc2\x60\xb8\xcc\x2f\x06\x35\x12\xe9\x8d\xe2\x3a\x71\xac\x0c\x9e\x5e\x89\x62\xd1\x34\x33\xdc\x39\xae\x1f\x17\x46\x44\x5e\x7b\x4c\xbd\xfb\x41\xda\x93\x45\xf2\xe1\x9f\xee\xa0\x14\x74\xe0\xc7\xc5\xea\xbb\x63\xd0\xf4\x38\x89\x58\xc4\x12\x4b\xd4\xb7\x59\xf1\x5a\x8e\xde\xa9\x80\x34\x0d\x87\x95\xd4\x53\xce\x3c\x12\x0b\x43\x99\x73\xf7\xbb\xd1\xd4\x31\x6d\x91\x58\x46\xdc\xc8\x5e\x76\x22\xab\x1b\xf2\x09\xc5\xce\xe7\xd6\x5c\xac\x12\x9b\xb3\xf7\x28\xea\x19\xb7\x28\x56\x12\x10\x94\x06\xe6\xa3\x81\x6e\xe9\x89\x95\x0e\x53\xd9\x99\xbb\x5b\xa8\xdc\xca\x38\x64\xbb\x73\x5d\x75\xd2\x97\x84\x2c\x2c\xb4\x2a\x2b\xa7\x35\x47\xbe\xaf\x06\x04\x8d\xa0\xd2\xd6\xa5\xe7\xaf\x23\xb1\x06\x8e\x69\x9b\xd7\x72\x24\x1a\x41\x62\x48\x24\x24\x9e\xea\x5e\xa8\xc6\xa1\x31\x7d\x6b\x2a\xd0\x03\xc6\x8b\x17\xfa\xe6\x33\x42\x75\x12\x83\xb6\x84\x02\x9e\x34\xf4\x66\xf3\x38\xb1\x6d\x62\xd0\x0a\x23\x43\xb8\xd6\xf6\xa5\x4e\x24\x36\x34\x49\x5d\xc5\xff\x10\xb4\x15\x9b\x58\x20\x5f\xc2\xb6\x2a\xff\x05\xaa\x39\xd8\x8c\xc3\xe4\xac\x86\xa7\x3c\xf6\x16\xd1\xe2\xe6\xe6\x79\xbd\xf3\x8b\x77\x12\x88\x54\x07\x1d\x79\x50\xeb\x7c\x77\x5e\x77\x42\x28\xb3\xf6\x8d\x03\x8c\xd7\x63\x90\x41\x42\x22\x8d\x96\xd6\x6a\xf3\xbc\xba\x5f\x0f\x6e\x37\x21\x3c\x46\x5b\x04\x69\xda\x1e\x4a\xfd\x74\x72\x3e\xdd\xf0\xfb\x8f\x5f\x4f\x42\xa4\xd5\x8c\xef\xbf\x60\x2f\xc5\xf3\xe5\xca\x92\xd0\x40\xe2\x3e\xdf\x60\x52\xcc\x5b\x2c\x9e\xac\x8b\x24\x21\xb1\xea\xb2\x4e\xa2\xc6\xcf\x68\x3d\xaa\xec\x22\x49\xbb\xf0\x23\x39\xa2\x27\x08\xf3\xc7\x33\x1e\x77\x8c\x7e\x50\x8f\x05\x33\x48\xc2\x4c\x8c\x18\xb3\x03\x3e\xac\xf3\xdf\x3e\xb1\xe8\x93\x38\x12\xc8\x30\x7e\x0f\x75\x5d\x16\x87\xf0\xb3\x6e\x1c\x70\xa5\xb7\x5e\xf4\xa6\x81\xe3\x57\x59\xb3\xab\x60\x59\x92\x24\x84\x0f\xc4\xe7\x0e\xc8\xff\x51\xe8\xf2\xb8\xd8\x6e\x0e\xf0\xcb\x5a\x74\xc3\x99\x9a\x24\xa9\x55\xa9\xa9\xa1\x69\x1d\x22\xbf\xf9\xb8\x75\x28\xe1\x81\xc1\x88\xe8\xc7\x5f\x7c\x0a\x1e\x09\xac\x36\xf2\xe0\xda\x6d\x2e\xfc\x8c\x4e\x38\x0f\x9c\x8c\x8f\x2a\x0b\x2d\xaa\xcb\x66\xf5\x34\x7c\xff\x9c\x47\x98\xed\x7f\x13\xf5\x9b\xd7\x70\xfd\xab\xcc\xee\x68\x72\x27\x22\xa6\x5e\xa7\xbe\x35\x2f\x6d\x1a\x08\x45\x77\xfa\x41\x2d\x92\x00\x4b\x17\x8f\x59\xe1\xe2\x6c\x61\xd7\x94\x6a\xcc\x23\xd5\x23\x20\xf4\xe4\x12\x46\x22\x47\xcf\x4f\xe4\xec\x72\x24\x48\x79\x7f\x7a\x49\xb4\x67\xc7\x7b\x46\xe2\x0d\xb7\xb6\x62\xd9\x7c\x2f\x7f\x74\xfd\xc9\x24\x35\x88\xf0\x73\xfb\xd8\x8d\xc8\x6e\xcb\x79\xfa\x0d\x92\xa8\x88\xe3\x82\x77\xbf\xd8\x6f\x47\x23\x55\x71\x49\x1c\x48\xc5\xda\x17\x03\x32\x26\x92\x28\x93\x84\x6e\x33\xb1\x80\xea\xe7\x19\x0c\xea\xe4\xb6\x74\x6a\xd7\x00\xa1\xf5\xb9\x86\xea\x8b\x20\x51\x02\x31\xf5\x54\xf1\xfb\x5f\x1d\x95\x81\x03\x0a\xfd\xf6\xe3\x6d\xec\x15\x26\x20\x05\x3a\xb7\x50\x4e\x6b\xdd\x48\x02\x40\x11\xda\xb8\xda\xf9\x74\x5d\xd7\x10\x62\x08\xdf\xd6\x7b\x7f\x7f\xba\xff\xf3\x93\x9b\x31\x91\xc0\x1a\x35\x14\x80\x1a\x67\x8e\x12\x13\x2b\x8c\x08\x7d\x17\x95\x56\xa5\x06\xdd\xc7\xf9\xff\x4b\x53\xc7\x9f\x08\x22\x0b\x97\x7b\xb3\xfe\xcc\xf8\x29\x78\x10\x25\xb8\xd7\xdc\x8b\x42\x5b\xb9\x7d\x37\x5e\xa6\xfd\x62\x2b\x62\xe0\x33\x43\xcb\x0b\x7e\xb6\xcf\x5c\x2f\x77\x14\x61\x01\xbe\x8a\xf5\xaf\xf2\x94\x8b\x02\x46\x91\x78\x4e\x52\xc0\x09\x0b\x9e\x53\xcc\xe7\x6d\xb6\xa2\xaa\x41\x4d\x36\x1e\x4e\x84\x40\x28\xd6\xf3\xfa\x7e\xbd\xd8\xad\x0f\xeb\xc7\x1b\x7f\xa6\x90\x27\xc4\x55\x84\xee\x8e\xa2\xba\xe2\x29\x74\xdd\xa2\x50\x62\x66\xbc\x3e\x9f\x4e\x65\xd5\x40\xe5\xd2\x0c\xf5\xb4\x5f\xec\x01\x2d\xcd\xaa\xcc\xcb\xaa\xfe\x83\x7b\x22\xd1\x3e\x79\xf4\xbf\x51\x30\x49\x24\xf1\x28\xb5\xa4\x55\x27\xac\x52\x03\x3d\xad\xf5\x25\x3c\x52\x29\xd6\xf2\x02\xf2\x0e\x0f\xdc\x18\x1e\x29\xe5\x91\xa2\x23\xbc\x0a\x8f\x8c\x51\xce\x06\x5a\x1c\x65\x36\x2d\x53\x1e\x78\xc7\x9c\x71\xa0\xc9\xf0\x85\x6e\xc5\xd9\xf3\xf5\x11\xce\x64\x82\x08\x42\x8f\xec\x76\x71\x2b\xfd\x05\x0d\x1f\xe1\x71\x62\x55\x82\x3a\x61\x98\x6b\xdb\x86\x27\x8c\x26\xa6\x97\x03\x98\x72\x1a\xf9\x5e\x22\xc1\x4c\xe9\x1d\xa0\x8a\xdb\x1c\x9f\x2c\xe1\x3c\x34\x98\xb7\x79\x06\x95\xc1\x4f\xd0\x8b\xa2\x2c\x6e\xca\x42\xcc\x05\x08\xfc\x21\x3c\xc1\x40\x50\xa7\x85\x9c\x8f\x06\x19\xe7\x29\x62\xc3\x3f\x20\xb3\x68\x8c\x6d\x05\x9d\xb8\x18\xe1\xdc\xa4\x88\x77\x15\xba\x2b\x88\x9d\x25\x46\x20\x3c\xa5\xca\x92\x95\x6e\xee\xd6\xcf\xdf\xa6\x6d\x26\xe8\x45\xbd\x3c\xdf\xc0\x9c\x71\xc7\xd3\x94\x21\xd0\x1d\x33\x2f\xd9\x69\xb4\xc3\x71\x21\x29\x2e\xb0\x96\x23\x7a\xd7\x51\x31\x12\x2e\xb4\x2d\x3f\x74\xd0\x3e\x04\xa4\x8d\x4f\x2c\xb4\xc0\x13\x17\x65\x93\x99\x4b\xcf\x09\x3d\x63\xf3\x72\x49\x04\xa2\x3c\x16\xf7\xf7\x4f\xab\xc3\xfd\xe6\xef\x2f\x9b\x9b\xc3\x7e\xbd\x78\xf0\x97\x93\x51\x98\x38\x01\xb4\x4d\xf1\xd3\xa6\x53\xe6\x5f\xbf\x4c\x04\x4d\xbd\x0f\x7f\xb3\xde\x8f\xee\x5a\x6a\xad\x53\xef\x0d\xd6\x4d\x79\x1c\x2b\xd3\x12\x2e\x41\x87\x66\x18\x88\x1e\x55\x41\x8f\xaf\xa4\x02\x43\xba\xac\x56\xfd\x54\xec\xdf\xb2\xda\x0a\x57\xb9\x0e\x3a\x94\x71\xe4\xa3\xe8\x8d\xc8\x77\x9d\x7a\x2d\xe1\x3a\x56\x68\x07\x1e\x4e\x15\x4c\x2a\x2b\x7d\x8f\x24\xe5\xb6\xee\xfd\x5f\xe7\xba\xf9\x84\xfc\xec\x6f\xa3\x3b\x82\xd8\x6a\xfa\x5b\xaf\x70\x1e\xbd\xf7\xa5\x11\xc4\x8d\x8e\xd0\x77\x52\xda\x2e\x8d\xe3\x38\x61\x1a\xc4\x36\x99\x5a\x41\x9d\xbd\x16\x8b\x7a\x75\xae\xae\x93\x73\x69\x10\x4b\x44\xbd\x81\xad\x9e\x42\xb1\x6a\x7f\x06\x12\x5a\x21\x62\x2c\x2d\xf4\x2e\xe2\xc3\xee\xe1\xf3\x70\x4f\x4a\x20\xc4\xe9\x9c\x67\x75\xe3\xf8\xec\xd1\xbc\x1b\x22\x5c\x67\xe2\x26\x29\xa5\x56\x01\xa0\xab\xd1\x5c\x3d\x79\xae\x54\x0f\xc8\x18\x3d\x7c\x4a\x4d\xa8\x6c\xac\xb0\xcc\xf7\xe5\xa6\x18\x42\x23\x53\xc6\x52\xd0\x03\x8f\xe6\x41\xf8\x50\x53\xca\x80\x63\x1d\x4f\x6b\x1e\xf5\xbc\x33\x24\x8d\x19\x24\xcc\x63\x31\x54\x55\xaa\x89\xe6\x19\x49\x13\x42\x90\xa6\xe2\xa5\x68\xce\xc5\xeb\x0f\x91\x9f\x2f\x7e\x25\x48\x93\x30\x4c\x2d\xd2\xb7\x68\x86\xe5\x08\x69\x12\x02\x2e\xc0\xb9\x97\x33\x22\x69\xa2\x12\xe1\x20\x5e\x3e\xab\x94\xa6\x41\x68\xac\x38\x69\x56\x8e\x79\x7b\x49\x9a\x52\x9b\x6f\x41\xc6\x82\xc1\x67\x1e\x7f\xc7\x34\xb4\xe5\x5c\x18\xc9\xf1\x64\x65\xf3\xb6\xb4\x3f\xc2\x61\xe1\x73\x51\x37\x7f\x82\xa8\xec\xb0\x1f\x14\xa2\x91\x54\x04\x09\xf7\x78\xa6\xf2\x78\x3c\x17\x59\x73\x91\x97\x99\x2c\x4f\x2a\x88\xf0\xb9\xf8\x1d\x34\xe7\x79\x01\x75\x92\x8a\x24\xb4\xc8\xec\xa6\x3c\x2d\x30\xad\x91\x15\xaf\xdd\x1a\xed\x3b\x99\x10\xc7\x75\x27\x42\x8f\x22\x57\xbe\x55\x02\xc5\x18\x0e\x12\x60\xdd\xc0\xb1\xfb\x06\xd2\xc4\x01\xed\xf0\x9b\xdc\xff\xac\xe2\x10\x39\xad\xda\x49\x70\x1e\x2f\x99\xa9\x26\x81\x0f\x11\xf8\x8d\xe7\x53\x5f\x6c\xf2\xf6\x80\x31\xed\x39\x05\x9a\xb2\x9a\x68\xf6\x92\x14\x52\x5b\xd0\x76\x5f\xbe\xd2\xcf\x32\x2a\x5f\xf2\x69\xfe\x6d\x88\x42\x4c\x01\x48\xda\xa5\xed\x07\xab\x64\x6a\x52\x1b\x43\x14\x27\x44\xc2\x3e\xc2\xc7\xea\xf6\x69\x3c\x36\x44\x90\x84\x46\x76\x10\x72\x84\xf1\x9f\x40\x65\x22\x6f\xed\xe3\xda\xb1\xb4\xcf\xfb\x03\x22\x10\x06\x79\x9e\xea\xa6\x54\xef\xcb\xf3\x65\x2c\x6d\x33\xfb\x6e\x44\xa0\x42\x44\x7b\x1e\x2f\x2f\x75\x56\xbc\x7a\x80\xa5\xbb\x65\x41\x08\xa4\x5d\xe1\x1b\xca\xa1\xe9\xae\x29\xb2\x62\xf1\x77\x56\xbf\xfe\x07\xa0\x3e\xcc\xf9\x8a\x56\x8e\x08\x22\x34\x96\x97\xfe\x9e\xbd\xbf\x5b\x22\xc5\xa9\xa2\xc9\xf8\x39\x88\x22\xa9\xdb\x94\x0e\x75\x99\x0f\x61\xdb\x82\x72\x8a\x01\x5e\x99\xe9\xf5\xc3\xd3\xe3\x7e\x53\xa8\x0a\x09\x6f\xfb\x0e\x0c\x77\xb4\xdd\xe2\x7e\x1d\x20\x88\xdd\xb7\x84\x31\x20\x21\x99\xdd\xbc\xd1\xce\x36\xe7\x5e\x93\x78\xf2\x21\x42\x01\x9a\x75\xf3\xe9\x24\x8a\xcb\xb6\x02\x03\x15\xa0\x1d\x39\x1c\x3f\x22\x52\x3a\xf1\x39\x40\x4b\x9a\x33\x7e\xfe\xc8\x24\x98\xcb\xfc\x2e\x3e\x07\x7d\x7f\xfd\x95\x98\xa1\x78\x86\x55\x59\xd4\xed\x4a\x5d\xbc\x7e\x1f\xd4\x8e\x4d\x5e\x5f\x2c\x2d\x2f\xbd\x50\xcd\x59\xe4\x07\x03\xa0\x3b\x51\x5f\x22\x92\x38\xa5\x6e\xf3\xdc\x9d\xc0\xd5\x1f\x39\x4d\x0c\x0f\xd7\x11\x09\x8f\x30\x34\xee\x70\x1b\xab\xac\xc2\x5d\xbb\x07\xf2\x09\xce\x05\x16\xcf\x6d\x33\xd5\x9c\x2b\xb8\xcf\x64\x25\xaa\x0b\x26\xff\xc6\xb7\xce\x55\x88\xe6\x60\x6b\xa2\x22\x3e\xa1\xf3\x6f\xfa\x4d\x40\xa4\x84\x60\xdc\x0d\x6b\x0c\x50\xf3\xbf\x2f\xf5\x68\xbd\x01\x0c\x44\x41\xeb\x3a\xc3\x88\xc7\xbb\x6d\x14\x98\x47\x3d\x96\x3a\x33\x97\xed\xc3\xde\xd3\xb6\x8f\xdf\x89\xd0\x0a\xfd\xfd\x2e\x8a\x3e\x01\xfe\x09\x19\x32\x8c\x0e\xe2\x1d\x3c\x3d\xae\x0f\x37\x83\x91\x23\x13\x8a\xee\x4d\x71\x3e\x3e\x19\xf4\x26\x77\x0d\x74\xc6\xbe\x50\x81\x26\x81\xc7\xc5\x1d\x61\xd9\x2e\x4d\xb8\xb3\x0c\x72\xd5\x42\x07\xb6\x2a\x61\xf7\xd6\x19\x83\x93\x8f\x0c\x89\xc1\xa9\xb8\x7a\x7a\xd8\x2e\x1e\xff\x74\x99\x8d\xc3\xfd\xd3\xea\xb7\xc3\x76\xfd\xbc\x79\xf2\x6e\x90\x00\x9e\xb0\xc8\x59\x53\x3b\xb0\xc2\xa8\x63\x3e\xd9\xeb\xed\x5e\x98\x80\xa3\x65\xd9\xce\x9a\xef\x87\xcd\xe3\xe1\x61\xf3\xf8\xb2\x5f\xfb\xe8\x9b\x30\x2a\x42\x52\xfa\x83\xad\x30\x70\xfb\x92\x15\xb4\xf6\x7b\xa4\x0c\x12\x91\xba\xf0\xd3\xcb\xee\x66\x3f\xfe\xd6\x32\x90\x69\xd8\x89\x18\x88\xfb\x52\xbd\x3b\x41\x73\x7f\x38\xa5\x49\xe0\x36\xa9\xcd\xea\x69\x04\x8d\x95\x61\x90\x3a\xdc\x4d\x01\x95\x68\xe0\x01\x8e\x65\x75\x41\xa4\xf7\xf5\x53\xf9\x63\xe2\x18\x83\x2c\xa2\xdd\x09\x97\x65\x89\xb2\x7f\xb3\x53\x48\x86\x3a\xc1\xec\xd2\x61\x88\x79\x7c\xf6\x33\xfa\x2a\xf2\x30\x9c\xe0\x32\x22\x32\xa6\x1d\x02\xc9\x6a\x5d\x3d\x99\xd5\x94\xf3\x90\xc8\x88\x4a\x7c\x06\x0d\xc2\x82\x14\xfd\xe7\x97\x51\x1c\xa6\x36\xb9\x95\xbd\xbe\x42\xf5\x62\xb5\xe8\x2c\x08\xdd\x77\xe1\x96\xc8\xaa\x79\xab\xca\x8f\xfa\xc7\x1b\x14\x77\x56\xb6\xc2\x8b\xb6\x3c\x96\xcd\xc6\xe9\xd9\xe8\x41\xec\x53\xb2\x28\xc6\x2f\xb7\xbe\x59\x95\x15\x38\x6d\x75\xf2\xdf\xa1\x31\x24\x4b\xad\x35\xf7\x50\x16\xaa\xba\x9c\x46\x9e\xbb\x8c\x23\x2b\x49\x8e\xc5\x9b\xa0\x6f\xb2\x9f\x9f\xbc\xdd\xd8\xf1\x92\xdd\x8b\x6a\x12\x93\x94\x71\x6a\x2b\x7e\xb3\xda\xf9\x2a\x35\x4c\x5f\x5b\x6c\x00\x47\x55\xa7\x89\x37\xa5\x8c\xff\xd4\x88\x95\x09\x15\xa9\xe8\xf6\x4b\x07\x0d\x9d\x5a\xce\x32\x49\x23\xaf\x88\x66\xca\xea\x78\x0b\x90\x43\x5d\xcf\x25\xa5\x47\xdb\xff\x5c\x6a\x5a\x26\xa9\x66\xcc\x65\xda\x1d\x58\xd4\xb5\xa4\x2c\xc2\xaf\xbf\x2b\x4f\x6f\xe5\x28\xaf\x24\x53\x9e\xa2\xc7\x7e\xe8\x82\x91\xb6\x14\xc5\x37\x0b\x8a\xcc\x07\xb2\xf5\xd9\x9b\xdf\xcb\xa1\x1e\xe7\xf8\x49\x52\x95\x58\x95\xe0\x06\x4e\x87\x1c\xb5\xc7\x5d\x8b\xa0\x56\x65\x0e\xaf\x7b\xf0\xe4\x3c\x03\xae\x09\x22\x05\x33\x41\x34\x92\x0a\x3b\xf5\xc1\xd7\xf9\xad\x47\x8a\x84\xe1\xae\x79\x2f\xea\x66\xfd\x0b\x54\x77\x2e\x69\x02\xe5\x36\xbd\x79\x5a\xdb\xeb\xec\xbc\x94\x82\x20\x20\x24\x6b\xe0\xe8\x9d\x94\xaa\xc7\x68\x7c\x96\xc5\x73\x47\x2b\xc5\xc2\xae\x94\xf2\x36\x2f\x71\x43\x7a\xfa\xf0\x8c\x0c\x73\xa8\x80\xc9\xc3\x68\xcd\xf0\xed\xf9\x7d\xad\xc3\xd1\xf8\x76\x43\xd1\xc9\xbd\x39\x1f\x8f\x97\xa9\xee\xce\x15\x36\x99\x04\x7e\x14\x02\xb5\x02\x9a\x08\x1e\x5b\xb5\xd3\xa8\x3c\x8c\x10\x11\x2a\x08\x25\x67\x2e\xd3\xb9\xcc\xf4\x90\xc4\x8a\xa8\x80\x9b\x0e\x75\xd9\xee\x20\x4f\xdd\x76\xad\x48\x28\x30\x7b\xf1\xb0\xf8\xe3\xd0\x7a\xf1\x3f\xd6\x37\x87\xe5\xd3\xcb\xe3\xfe\xcf\xae\x07\x4b\xd1\x9f\x81\x42\xdf\x89\xa3\xcc\xb3\xe2\xb5\xb5\xc7\x2e\x13\x02\xc4\x91\x47\xab\x88\x00\x1c\xaa\x37\x77\xab\xfc\x2c\x07\x98\x1d\x85\x1f\xe9\xff\xfd\x7f\xff\xaf\x34\x26\xcf\x0a\xd4\x80\x19\x4f\x26\x45\x29\xc1\xe4\xc8\x5b\x99\x6b\xa8\x5c\x74\x69\xc8\x15\x4c\x54\x98\x86\x51\xe7\x8c\x38\xfa\xb1\xe5\xc5\x49\x1e\xcc\x8d\x13\xee\x0f\x14\x14\xc1\x2a\xab\xed\x6a\xdd\x3a\x95\x5e\x5f\xb9\x6b\x66\xda\x05\xcf\xb6\x65\x9e\xd7\x3d\xb9\x18\x51\xa1\xb4\xb0\xb2\x1a\x1a\x4c\xab\x4c\xa9\xb3\xa6\x5f\xd0\x5f\x32\x0a\x54\xec\xa2\xe4\x9b\xa2\xa9\xca\xfa\x64\x77\xd4\x79\x6e\x01\x15\x81\x35\x98\xf3\xf2\xf5\x01\x19\xe1\x1c\xdd\xe7\x50\x0b\x96\x28\x16\x29\x14\x63\x95\xe7\xcb\xee\x54\x65\xd3\xf4\xb9\x62\x11\xa8\x21\x75\xfc\x22\xcf\x27\x91\x08\xdf\x51\x33\x1c\x1a\x15\x56\xb5\xb4\x7b\xf1\x0f\x80\xf7\x4e\xd3\x91\xa8\x98\x51\x2c\xc0\x86\x5f\xa7\xb2\x42\xd4\x71\xd7\x92\xda\x00\x7c\xf3\x51\x3e\x94\x45\xf3\x56\xdf\x8b\x8e\x6c\x8b\xa8\x84\x2a\x2c\x70\xb1\xa5\x54\x20\x8e\x48\xa7\x33\xbe\x78\x12\x59\xfd\x2a\xa1\x47\x0a\x03\x03\x25\x38\xf7\xe7\xf8\x30\x4e\x8c\xaf\xa5\x5d\x9e\xab\x5a\x4c\x56\x63\xc5\x19\x43\xa1\x89\x02\x7e\x35\xfb\xf2\x5c\x15\xa2\x35\xe0\x97\xa2\x78\xf7\x37\xc7\x13\x86\x84\xb7\x37\xcb\xee\x17\x1d\x69\x67\x63\x1d\x44\x25\xb3\xa6\x3e\x7c\x7c\x0d\x75\x50\x1c\x02\x9f\x46\x6a\xdd\xbe\x91\x74\x10\x51\xa9\xa4\x61\x0f\xc0\x3e\xa1\xd0\x0e\x0a\x36\x4d\xbe\x94\x08\x00\xc5\xa0\x6e\x17\xab\xfd\xd3\x84\x67\x93\x28\x11\xa7\xb1\xa5\xe6\x6b\x5d\x89\xb1\x7d\xeb\xbb\x24\x36\xcd\x26\x34\xca\x76\xd4\xb3\x01\x51\x25\x29\x31\x6e\xc6\xb4\xab\x80\x12\x95\x2e\xc4\x14\x35\xae\x64\x0c\x3e\xa8\x68\x73\x68\x28\xca\x49\x51\x72\x63\xda\x95\xc7\x81\x7b\x7a\x67\x12\x3f\xf6\x7c\x49\xbe\x4f\x6a\xc5\x08\x0a\xf8\x58\xff\x3a\xb5\x5f\xb8\xfe\x24\x25\xa4\x54\x98\x62\x61\xce\xc3\xcb\xfd\x7e\x73\xd8\x75\x65\x8a\x4a\x45\x9a\x38\x44\xc3\x0d\x1c\xcf\x15\xba\xd7\xf3\x1f\x44\xb1\x00\x41\xab\xff\x80\xac\x38\x77\x0b\x8e\x4a\x2c\xa4\x7c\x2b\x3e\x86\xeb\x90\x4e\x6c\x18\xf6\x41\xa0\x14\xc3\xa5\x1c\xd0\xe0\x7e\xe9\x2c\x29\x08\x69\x90\x74\xee\xbe\x7a\x47\x7b\x0d\x21\x6d\xf3\xb7\x65\x1c\x72\x41\x9e\xab\xc2\x03\x84\xe7\xed\x8f\xc9\x85\x8c\x88\x22\xe9\x2f\x34\x0e\xca\x0c\x17\x18\xa3\x2c\x59\xe2\xb0\x36\x7f\xea\x74\x5e\x5b\x36\xca\xb4\x9b\x15\xea\xa9\x7c\xa8\xc1\x7b\x31\x86\xeb\x61\xa0\x7e\x3c\xb7\x34\x09\x48\x6c\x65\x54\xce\xaf\x6f\xcd\xbe\xd4\x62\xb2\x80\x69\x1a\x28\x44\xb5\x7a\x0b\xe1\xb0\xde\x7f\xa7\xf7\xe7\x19\x10\xae\xa6\x91\x0d\x1f\xb7\x43\x17\x3e\xac\xb4\x92\xdf\xaa\x87\x03\x49\x53\x2e\x90\xd0\xae\xf6\x6a\x3f\x43\x1f\x4d\x53\x61\xf9\x48\x96\x9b\xdf\x76\xdb\xe7\xa7\xbf\x66\xf9\xd0\x54\x29\x1b\xcc\xaa\xb2\x49\x68\x4f\x87\x84\x7b\xc5\x09\xbb\xfe\x22\x9f\xf5\xf8\x11\xc3\xc8\x32\x80\x58\x20\xc1\x72\xca\x4e\xa3\x43\x6e\xab\xa9\x84\xd6\x37\x16\xdb\x3b\x08\xe8\x8e\x6e\x24\x8a\x13\xc3\x7c\x99\xce\xeb\x6d\x96\xe7\x8b\xea\x15\xc1\x5a\x7e\xaf\xd3\x2c\x94\x08\x97\xfa\xfe\xfc\xfd\x2f\xd5\x49\xfd\x21\x2c\xd0\xd4\x43\x32\x31\x72\x3a\xbb\xf8\x6b\x96\x0a\x6a\x61\x64\xa7\xfc\x90\x15\xaa\x3c\xc2\x93\x21\xc1\x7b\x77\x69\x9d\xe2\x84\x7a\x13\xf5\xba\x68\x3f\xb8\x1d\xb6\xc8\x4c\x34\x7e\x6b\xcc\x44\xb8\x21\xb7\x1f\xe8\x3b\x54\xe5\xa4\x39\x06\x16\x25\x83\x9a\xdf\x01\x65\x1f\xd1\x49\xa4\xb0\xa6\x69\x07\xcd\x0f\xf1\x0a\x15\xe8\x1f\x90\xcd\x23\xfd\x74\xc2\x34\xee\x6b\xcb\x97\x3f\xd7\xcf\x87\xdd\x7e\xbd\xf5\xfc\x7f\xdd\xcb\x4f\x63\x0a\xce\x5e\x71\x65\x45\xfe\x71\xd2\x24\xc1\x1d\x7c\xbf\xde\xed\xbb\xdf\xd2\xc4\x03\xdc\x64\xdd\x88\xac\xc0\x12\x10\xdf\x2a\xa4\xc6\x9a\x1d\x9d\xd5\xc2\x06\xfb\x17\xd3\xba\x78\x2d\x55\x84\x99\xad\x83\xae\x44\x56\xa0\x3d\x33\x49\xfc\x5c\x1b\x74\x5a\x25\x31\xb3\xb3\xac\x78\xec\x0c\x7c\xad\x12\xe3\xc5\xe8\x6c\x30\xa8\x02\x6d\x73\xea\x6a\x42\x0b\xe4\x02\x29\x5a\x87\xc4\xa7\x2a\x5c\xf2\xdd\xd5\x4d\xfa\x53\x6a\x4e\xf0\xee\x44\x51\x94\xe7\x42\xc1\x6d\x59\xbd\xcf\x20\xce\xfa\x37\x0c\x41\x8a\x51\x7b\x38\x4c\xf5\xc7\xe7\x97\x43\x0d\xcc\x0a\x2b\x29\x51\x37\x4e\x3f\x0a\xb7\xfa\xf3\x50\x87\x6c\x60\xa4\x6b\x10\x81\xe8\xc5\x2d\x70\xf5\xdc\xd9\x22\xcc\x4f\x17\x2b\x0d\x3a\xc1\x8b\xb4\x66\x0a\xaa\x7c\x8f\xad\x14\x6d\x62\x8d\xfe\xcf\x5d\x5e\x4a\x91\xbb\x44\xfa\xd0\x43\xd2\x26\xd5\xe8\x9f\x17\xf0\x31\x5a\x3c\x8c\x22\x68\x00\xb9\x6c\x90\x69\x1d\x76\x3d\x4d\xd2\x43\x10\xa4\x48\x82\xb3\xa8\x2a\xd1\xc1\x0f\x21\x48\x63\xbb\xf2\xb6\x2b\xf3\xef\x48\x54\x38\xb2\x53\x21\x00\x8a\x91\xc9\x29\x55\xee\xe4\xec\x24\x10\x63\xc1\xf4\x7d\x39\x30\xb4\x80\xc4\x2c\xb2\xb5\xcd\xe2\xe2\xb1\x6d\x84\x8e\x35\xde\x08\x10\x1d\x59\x19\xab\xb2\xcc\x6d\x6c\x03\x6f\xb6\x3b\x09\x00\x71\x21\x3e\xbc\x87\xb2\xf2\x1c\xa8\xab\xbc\xac\xe1\x8a\xcd\x61\x7e\x4f\x02\x4a\x09\x75\x72\x05\x5b\x5b\x3a\xf1\x35\x79\x3d\x81\x08\x64\x90\xf4\xf5\xa2\x9e\x27\xc3\x45\x6f\xb2\x72\xb2\x00\x03\x23\x92\x31\x5f\xff\xe4\xc0\xe8\x03\xbd\x38\x02\x8c\x25\x71\xd2\xd3\xf6\x3b\xf0\x40\x7b\xda\xa9\x5f\x0e\x71\x9a\x0a\xee\x17\xf3\x0c\x11\x9e\x37\xa8\xc1\x36\xbe\x64\x0c\x1a\x97\xd8\xe7\xf5\xfe\x1f\x3e\x2c\x08\x89\x21\x14\x8b\x55\x74\x79\x63\x39\x66\xbf\x4a\x70\x03\xa7\x00\x9d\x06\xf7\x0e\xcd\x76\xdd\x39\x16\x90\x46\x11\x22\x06\x86\xd9\xe3\x41\x88\x05\xd2\x28\xc6\x68\xb0\x85\x60\xce\xa6\x75\x40\x44\x31\x97\x3d\xa4\x05\x81\x07\xf5\x38\xd1\x07\x42\x01\x09\x06\x60\xce\xbe\x3c\xd0\x75\x90\x0c\x10\x2c\x59\xfe\x84\x4a\x57\xc2\x38\x5d\xe3\x51\xa8\x0c\x24\x50\x4c\x41\x49\xb4\xae\x27\x97\x50\x91\xe5\xbd\x39\x17\x3f\xcb\xa9\xdf\x01\x2a\x62\x38\x3c\x4c\x56\xd5\xcd\xe1\x94\xa3\xaa\x55\xd7\x66\x30\x80\x90\x67\xc7\xac\x99\x7f\x44\xc5\x23\x34\x08\x76\xfb\xbd\xd0\xc7\xac\xa0\xdd\xb1\x46\x93\xd8\xd3\x08\x35\x23\x6c\x91\xeb\xa1\x49\xe2\x94\x01\x87\x68\x84\xfb\xc1\xb8\xf4\x1d\x39\xe5\xce\x75\x7a\xbc\xdd\x4f\xcf\x92\xc6\xd2\xaa\xf9\xb9\x5a\xb7\x76\x60\x8d\xaa\xef\x40\x4b\x2d\x5d\x61\xea\x6d\x59\x41\xf6\x5a\x2c\xab\x4c\xbf\xc2\xba\x52\xfb\x72\x5d\xa9\xcd\xf1\x64\x25\xf2\x46\x60\x03\x7f\xb0\x31\x98\x8d\xcc\x34\x14\xad\xbf\x03\xd5\xa6\x7e\xaa\xb2\xd7\xac\x98\xe8\xfa\x11\x80\x90\xe3\x66\xa0\x5d\x3d\x6b\xcf\x16\x34\x39\x27\x44\x21\x58\x8f\xd1\xc2\x87\x7a\xd3\x10\x40\x71\x1c\x0e\xed\xdc\x13\xa7\xac\x11\xb9\xa7\xe2\x9e\x5c\x4b\x29\xaf\xef\x77\x3e\x2d\x5b\x63\xfe\xaa\xa6\xfc\xbf\xfd\xdb\x9e\xd1\x90\x30\x0c\x6d\x05\x57\x9e\xc1\x4f\x40\x61\xc4\x49\x0f\x23\x90\xd9\x72\xfb\xf4\x7d\x3a\x4a\x0d\x35\x04\x39\x52\x9a\xec\xd8\xe1\x91\x91\x56\xb4\xc9\x7c\x3c\xca\x84\xb1\xd5\x5d\xf5\xb1\x96\xb2\x6e\xf6\xe5\x76\x30\x52\x4d\x28\x12\x69\x19\xb3\xb3\xe2\x36\xcf\x4e\xdd\xef\x32\xb2\xda\x0e\x56\x52\xe5\x16\xe0\x13\xfa\x07\x13\xc5\x5c\xf9\xf7\x97\x8b\xec\x38\x33\xf0\x4c\x04\x8a\xb9\x3e\x3f\x5a\x4f\xbc\xda\xf4\x46\xec\xc8\x32\x31\x8c\x44\xb6\x26\xd7\x72\x99\x6d\xc5\x05\xe0\x33\x7c\xc0\xf8\x1a\x8c\x05\xe8\xc3\x6c\x54\x39\xca\xca\x1a\x96\x6a\xe9\x85\x3d\x0f\x58\x0f\x6a\xb7\xd2\x03\x12\x18\xdc\x02\xbe\xf8\x43\x51\xda\x12\x0f\x55\xf6\x88\x57\x13\x73\x5b\x43\xd0\x6d\x3a\xf7\xcf\x2b\x2b\xa3\x3c\xe1\xde\x19\xdf\x4a\xac\xb9\x72\x61\x90\x29\xea\xa9\x67\xac\x9a\xee\xdf\x26\x36\x3c\xe9\xe5\x3c\x1e\x32\x55\x95\x0f\x25\xd6\xf4\x8d\xcf\xce\x83\x04\xb7\xba\x9b\x3f\x96\xc3\xdd\xdb\xa4\x24\xb0\x52\x78\xe2\xb5\xfb\x29\xa4\x56\xe4\xa2\x2c\xae\x02\x7c\xbe\x4b\xac\x71\x39\xb1\x92\x52\x9d\xda\xfe\x97\x49\x32\x3e\x4f\x7a\x68\x52\x63\xd0\x02\xc8\x45\xdd\x95\x98\x63\x72\x50\xd4\x30\x80\x56\x1b\xc1\xb8\x4f\xd6\xac\x8b\xd7\xac\x80\x7a\xd3\xa5\x37\x8c\x48\xc0\xe8\xce\x71\xb0\xef\x79\x5f\xb6\x5b\x93\x4f\x2b\x8d\x1f\x40\xc8\x04\xbd\x76\xef\xda\x4d\x98\x5b\x89\x11\x10\x21\x3f\xab\x68\x37\xa8\xcd\x4d\xaf\x3f\x4a\x8c\x30\x32\xf1\xd2\x79\x9d\x7e\x7f\xd7\xa6\x31\xc8\xa4\x44\xfd\x96\xd9\xe2\x33\xdf\x24\x03\x82\x00\x97\x2e\xfa\x31\x26\x76\x31\x32\xb4\x8a\x5f\x8d\x47\x49\x3b\x33\x80\x76\x1d\xa2\x20\xf0\xa6\xda\x46\x95\x7e\xdf\xed\x9a\x05\x43\x70\xc5\xe3\xf3\xf2\x60\xeb\xa2\x7c\x83\x4e\xb1\x72\x44\x3b\x08\x40\x6d\xe5\xf9\xa1\x3a\x74\x3d\x0c\xa4\xba\x2b\xa8\xc9\xca\x62\x65\x25\xa7\x2d\x7b\xba\xef\xa5\x62\x83\xa6\xb5\x25\xf5\xb3\x68\xc8\xf5\x80\xeb\x99\x18\x4d\x15\x42\xb9\xfe\xed\x38\xa0\xbf\x43\xae\x37\x05\x02\x8b\xf4\xe5\xc9\x78\xc7\x75\xbc\xcc\x1a\x2d\x3c\xb5\x0a\xa8\x77\xac\xc3\x02\xcc\xef\x76\x0f\x60\x88\xc0\x3d\x7e\x2b\x4e\xa2\x12\xff\xf9\xcf\xa8\x4a\xc1\x98\x88\x47\x1e\x7b\x60\x47\xa1\x6f\x50\x02\xeb\x1b\xa5\x73\x45\xbb\x11\x67\xb4\xad\xbe\x47\xfe\x9f\x06\xb6\x50\xb5\x4b\xe4\x4b\xf1\x99\x68\x0d\x0d\x82\x38\xf0\x4b\xd1\xb2\x75\x4c\xcb\x21\xbb\xfd\xb4\xaf\x8e\xf1\x3b\x3e\x6d\xd7\x8f\x9b\xc7\xbb\xc3\x7e\xf3\xe0\xa2\x4e\x34\x20\x61\xc4\x23\x4b\x1c\xa2\x6c\x05\x4f\xbd\x68\xbd\x29\x24\x5d\x9c\xcf\x95\xd1\x80\xa4\x1a\xf1\x1c\x27\x71\x19\x1a\xc1\x34\x20\x60\x4c\x47\x18\x82\xdf\x0a\xf3\x89\x93\xe0\x13\x0d\x28\xa7\x3e\x04\xb7\x54\xe5\xf9\x54\x16\x3d\x3c\x7e\x08\x65\xa4\x01\x95\x31\x4e\x7d\xaf\x74\x62\x2d\xd8\x81\x9c\x38\x0d\xc2\x80\x3b\x92\x36\xb4\xb3\x90\x17\xd7\xca\x27\xf9\x1e\x91\x32\xe8\x27\x3e\x9d\xa0\x78\x06\xbd\x2e\xac\xa3\x3e\x8c\x60\xd1\x80\x45\x21\xe2\x7c\xc1\x71\x07\x52\x7f\x34\xe3\x9a\x8b\x0e\x84\x81\x6b\x72\xc7\x2b\x48\x03\x26\xb9\xcf\x43\xb6\xce\xf2\x60\x20\xd0\x20\x0e\x53\x67\x3f\xe5\x23\xb5\x2c\x1a\xc4\x06\xb0\x28\xb4\x4b\x21\x7e\xe1\xa8\xd1\x20\x51\x1e\x67\xd4\xcb\x39\x80\xfe\x84\x22\xde\x1d\xc3\x05\xf1\x32\xfb\x2b\x51\xe9\xfa\xb6\x2a\x8f\x58\x99\xf3\xd5\x66\x4e\x03\xae\x00\xf5\xbf\x76\xfb\xbf\x6f\x2b\xd8\xac\x9e\xf6\x50\x37\xdf\x21\x3f\x5d\xe3\xd4\xdc\x11\x29\x09\xa2\x1e\xc8\x68\x45\x9f\x9f\xcf\xf9\x35\xfa\x6f\x72\xa5\x94\xa6\x12\x65\xf3\xf2\x57\xa8\x32\x31\x7a\x71\x02\xac\xc1\x50\x83\x0d\x35\x8e\x92\x67\x7e\xbd\xa6\xc1\xdf\x46\x1f\x50\x12\x89\xb1\xe0\x76\x83\xbc\xc3\xf4\xea\x0a\x39\x0b\x7c\xb3\x20\xac\xc7\x6c\x2c\x94\x6a\xe8\xb7\xf1\x93\x48\x29\x5d\xa5\xae\x4d\x1b\x3b\xb4\xfe\xa2\x69\xcf\x88\x63\x73\xa7\xde\xe0\x28\xf0\x35\x7e\xb6\xb1\x4c\xb6\xa7\xff\xfd\xe7\x68\x73\xa1\x81\x34\x11\x2a\xe5\xee\x8e\x22\xcf\x37\x5d\xf0\x87\x06\x2a\x4c\xa4\x7b\xe6\xa7\xd5\xdd\x80\x42\xa7\x6b\xb7\x0a\xbe\x15\xe4\xe2\xe2\xc3\x1d\xae\xa4\xe7\x4b\x0c\x08\x71\x7f\x51\xfe\xc5\xae\x47\x03\xc5\xac\x78\xf1\xc7\x50\x30\xc4\xb7\x25\x8a\xab\x41\x89\x6e\x3f\x5b\xfb\x1e\x1a\x53\x1f\xdb\xc5\x9f\x4f\x2f\xfb\xc3\x62\xbf\x5f\x3f\x6c\xf7\x87\xcd\xe3\x7e\xfd\xfc\xfb\xe2\xbe\xeb\x06\x21\x92\x2e\x61\xe1\x93\x28\x06\x3f\x63\x76\xe0\x46\x1c\x8b\xe7\x52\xbd\x77\x2f\x05\x48\x47\xff\xb7\x82\xaa\x93\x99\xbd\x6c\x6e\xc6\x93\x17\x12\x89\xe0\xb1\xb2\x75\xea\x0f\xed\xf7\x7b\xbd\xf8\xac\xe7\xe0\xaf\x31\x38\x85\x06\xc0\x49\x14\x8e\x95\xf8\xc7\x4c\x50\x34\x00\x19\x7b\x8a\xae\x3d\x1c\x4f\xad\xf5\xb4\xbc\x78\x7f\x7a\x34\xc4\xb9\x3f\x02\x12\x9c\x79\x8f\xf0\xb1\x13\x85\xfe\xc8\xbc\x7a\xdc\x97\x94\xb8\xee\x60\x23\x28\x32\xd2\x2f\xa1\xc9\xe1\x32\x9a\x14\x46\x27\xb8\xce\x3d\xb6\xbe\x96\xfb\x91\x04\x5c\x47\xae\x14\xad\xab\xa4\x0b\x83\xd1\xcb\x21\x01\x48\x16\x77\x85\x44\x23\x1f\x8f\x12\x22\x14\x1d\xc2\xee\xba\xd2\x53\x4a\x08\xd8\x6d\x7a\xb5\xdb\x0f\x6f\x84\x10\xc3\xf1\xad\x49\xf9\x08\xcd\x47\x59\xbd\xdf\x55\xe5\x47\xf3\x36\x7a\x6f\x84\x52\x21\xdb\x01\xf1\x3f\x42\xbd\x9f\xca\xe6\x7b\xd6\x8d\x74\x42\x99\xc4\xc2\x2d\xf8\x09\x45\x33\x90\xb9\xa4\x84\x42\x8c\x62\xd4\xe8\x53\x7a\x5a\x63\xc4\xbf\x60\xc1\xc3\xba\xdb\x82\x29\x09\x95\x42\x7f\x7f\xa1\x91\xef\xa6\x35\x87\x26\x4f\x16\xc5\x49\xd4\x4e\xf8\x45\x03\xe2\xb8\x9c\x2a\x24\x53\xc2\x52\x5b\xf3\x62\xb3\x6e\xab\xac\xb9\x20\x32\xf4\xcb\x55\x8b\x30\xa1\x51\xc3\x78\x04\x8e\xfd\x1c\x5c\xe0\x8f\x52\x12\x1d\xd1\xb2\xd8\x7a\x12\x8a\xa1\x25\x43\x49\xcc\x02\xc4\x1e\x14\xe7\xe3\x4a\x14\x1a\x35\x59\xba\x07\x89\xc5\x20\xde\x60\xd3\x0a\xde\x48\xa3\x24\x91\x89\xe5\xbc\x01\x0d\x70\x3c\x4c\x63\xf9\xb3\x5e\x06\x25\x89\xd2\x36\x47\x54\x8d\x07\x19\xe1\x01\xc5\x72\xd6\x46\xbc\xcf\xf3\xb8\x53\xc2\x99\xc1\xb9\x96\xd5\x3f\xb2\xe6\x2d\x1b\x6c\xdd\x9f\x1d\x20\x8d\x74\xd1\x0c\x0c\xba\xcd\xa2\xe5\x29\xe1\x2a\x44\x2f\x58\x9e\xf3\xf7\xe7\x5e\x6b\xce\x78\x00\xc3\x1c\x16\x89\x12\x6e\x2c\xdd\x4b\xeb\xf9\x61\x8e\xa6\xdb\xf6\x49\x1a\x09\xe5\x62\xf3\x98\x11\xfc\xfa\x95\xa4\x31\x27\xd4\xc7\xe7\x45\xb1\x1a\x8e\xcb\x94\xd3\x50\xb8\x1a\x2e\x2f\x5e\xde\xc7\xb5\x29\x49\xd3\x20\x8d\x7a\x6b\x2c\x2b\x5e\x1d\x5a\x69\xaa\x72\x4e\x49\x2a\x12\x4c\x25\x1e\xd5\x6b\x05\xaf\x65\xd5\x0c\xdf\x7e\x6a\x0c\x66\x08\x3b\x1d\x3b\x6b\x7a\x1f\xcc\x24\xdc\x45\x89\x30\x29\xe2\x88\xda\x21\xbb\xac\xca\x77\xa8\x6e\xc4\x8c\x08\x11\x25\x92\x06\x36\xc5\x9e\xbd\xbe\x41\xdd\x2c\x33\x3d\x99\x26\x32\xee\xd4\x13\xda\x93\x1d\x68\x3c\x5e\x3d\x64\x12\xa5\x69\xc7\x43\xd6\xee\xf0\xf9\xf9\x08\x38\x29\xe1\xca\xe2\x74\x1f\x88\x77\x9f\x47\x82\x15\x93\x44\x58\xd5\x17\x51\x35\x4a\x14\xa7\x72\x5a\x13\x4c\x12\x7f\x97\x4a\xc7\xb8\x86\xd9\x38\x93\x43\xfb\xd7\x93\x67\x55\x20\x91\x33\xeb\x74\xae\xdf\xa0\xda\x57\xa2\x1d\x0d\x07\x7f\x0a\xcd\x62\x65\x45\x71\xdd\x06\xdf\x6f\x5f\x44\xf3\x00\x51\x33\x68\xe5\xfb\x61\xd7\x4f\x32\x60\x96\x0d\xd4\x80\x7a\xf3\x55\xc5\x5e\xaf\xa7\x35\xed\x36\x3d\xad\x01\x25\x20\x29\x62\x38\x3f\x46\xeb\x21\xa8\x10\x91\x55\x0f\x77\xf7\xe3\xd5\x14\x80\x60\x8c\xfc\xe4\xa0\xc8\xb7\xd7\xb2\x99\xae\xa7\x89\x08\xba\x72\x59\xfd\xf4\x31\x9e\x6b\x7e\x43\x6b\x7d\xae\x88\x0d\x98\xce\x31\x57\x39\xd9\x76\x26\x27\x95\x22\xf1\x1c\xbe\x98\x07\xa6\x2c\xfe\xd6\xb5\xe9\xd0\x0a\x7d\x9f\xf2\xf2\xd2\x74\x51\x1b\x4a\x8c\x66\xfe\x63\xed\xb2\xe2\x35\x07\xcf\xc1\xd0\xed\xb7\xb6\x23\x0d\x02\xe1\xb9\x91\x1f\xcf\xc7\xef\x88\xf3\x98\x2c\xc4\x94\x04\xa1\xe9\x89\x59\xbd\xa0\xcc\x5c\x98\x86\x52\xaa\xac\x31\x7e\x83\x7c\x74\x1e\x96\xe3\xb6\x5e\x1a\x46\x09\x17\x9e\x40\x79\x5b\x96\xa7\x1e\x19\x4a\x69\xc8\x8d\xd6\xc3\x28\xc8\x30\x1a\xe4\xfa\x44\x09\x31\xca\xbf\xbf\x46\xe4\x57\x89\x91\xe9\xee\x30\x06\x79\x0d\xd6\x04\x1a\x69\x83\xaf\xa8\x75\xe3\xed\xc0\xdf\x42\x75\x53\xe6\xb9\xf0\x0b\x14\x65\x84\xf3\xa8\x8b\x2f\xb6\x2e\x97\xc7\xa3\xb7\xb7\xb6\x2f\xc7\xc3\x9b\xb2\x90\x21\xe5\x6c\x3b\x07\xec\x5b\xbf\xc9\x14\x0c\xd8\x2f\xc6\x33\x8a\x32\x46\x39\x78\x7e\x0d\xdd\xb3\x8e\xfb\xe6\x38\x41\xa9\x86\xa6\x1b\xee\x4e\x51\x7a\x7a\xd9\x58\xe3\x3e\xfa\x70\xae\x44\xd3\xe7\xd5\x29\x65\x49\x02\x69\xbf\x2f\xa9\xb2\x1b\x1f\x34\x0e\x13\x74\x68\x57\x0f\xab\xfb\xd9\x54\xe6\x0c\x72\x81\xd2\x24\xa5\x76\x80\x0f\x88\xb3\xb6\x50\xad\x2e\x2a\xef\xce\xcc\xb9\x9d\x04\xc8\xa8\x3c\x7e\xde\x54\x31\x5f\x27\x7b\x03\x36\x5c\x83\x29\x3e\x51\x28\xd8\x56\xb0\xcb\x5e\x0b\xd0\xb3\xc6\xfb\x97\x3e\x11\x15\xb1\x15\xf2\x74\xc1\xbc\x87\x2c\x7f\x6f\xaf\x3e\xc8\x2d\x51\x2a\x8c\xad\x97\xcf\x5c\x9c\x68\x7e\x91\xa3\x52\x26\x16\x36\x77\x9e\xac\xd3\x54\xf1\x08\x63\x29\x32\xd3\x4f\xc5\x2e\x6b\xdf\xce\xd7\xae\x1a\xd5\x52\x60\x15\xdb\x9d\x57\x82\x1c\x4a\xe0\x51\xaa\x55\x80\x42\x49\x76\x19\x42\xff\xaf\x97\x31\xa0\x54\x6b\x16\x59\x3a\x3f\xb4\x9f\xc2\x9d\x4f\x24\x52\xaa\x21\xd1\x83\x58\xda\x3c\xcf\xd7\x27\x37\x05\x84\x24\x89\x7b\x57\x03\x03\x87\x02\xd5\x21\x82\xa2\x33\xd1\xbc\xe5\x65\x31\xcf\x25\x3b\x5f\x12\x31\x7e\x51\x10\x5a\xdd\x54\xbb\x5a\x60\x21\x81\x2f\x84\x9d\x74\x8c\x14\x77\x35\xbe\xbb\x46\x98\xe9\xb0\x36\x31\x27\xc3\x9a\x6e\x5b\x4e\x3d\xff\xd9\x4c\x6a\xc1\x7e\x4e\x61\x08\xdf\xe8\xc4\x7b\x0c\x83\xd8\x20\x6e\x35\xab\x57\xcb\xf5\xa4\x8d\x44\x0c\xad\x2a\x8f\x96\x74\x62\x37\x73\xe0\x6d\x1a\x52\x6d\xe9\x7a\xb6\x48\xec\x31\x26\x97\x9e\xbd\xbd\x30\x4c\x04\x56\x73\xe1\xf7\xef\x90\xe8\x34\x8c\x62\xcb\xaf\xdd\x74\x76\xd4\x67\x69\x57\x1a\xb2\xd0\x92\x63\x09\x94\xa9\x78\x2a\x46\x70\x39\x1a\xb2\x24\x41\x01\x7a\x17\x82\x7f\xde\x68\xbf\xaf\x86\x31\x61\x58\xd9\xb4\xd0\xda\xd3\x04\x7c\x25\x8c\x4b\xc3\x24\x12\x36\xe7\x94\x35\x0e\xf6\x3a\xdc\x10\xc3\x84\x05\x98\xb7\x3a\x1e\x30\x00\xdb\xf9\x3a\x61\xa2\xad\x3c\x49\xbb\x55\x65\x08\x49\x19\x1e\x05\x21\x75\x8d\x0b\xbd\xd1\xcb\xcb\x4a\x7c\xb2\x2e\x86\x3c\x00\x24\x59\x82\xa2\xc9\x9a\x2e\xde\xd9\xfe\x6e\x30\x80\xf0\x50\x16\x70\x59\x68\x0d\x1a\x75\x01\xe6\x54\xff\xa6\x67\xe4\x0a\x75\xf2\x16\x85\xae\x20\xab\x47\x37\xc6\x53\x6e\x30\xee\x50\x96\x48\x17\x91\xfd\x04\x0c\x62\x8d\x7d\xc7\x31\x3e\x78\xb8\x91\x84\x69\x18\x49\x39\x18\x3c\x6b\x84\xe7\x59\xfb\xd3\x39\xf3\x7c\x72\x3f\x69\x68\xc1\x0c\xbb\xbb\x9b\xbd\xbf\x0f\x11\x48\xac\x3c\x70\xe4\x09\x0f\xe2\x17\x8e\xf8\x3e\x94\x15\x8a\xd0\x52\xd9\xf8\x19\x31\x8e\x02\xfa\x4e\x3a\xc5\x98\xab\x3c\xe7\xf9\x90\xed\x92\x86\x02\x00\x63\xad\x76\x62\x8e\x39\x91\xc7\x03\x40\x18\x7b\x2b\x12\x06\xf5\x7b\x34\x94\xb1\xc0\x52\x91\x87\x8b\xea\xc4\x1c\xe7\x47\x90\x0a\xa8\xc7\xd2\x3c\x5b\xa1\x9a\xb5\x23\xf6\x1a\xd9\xae\xa1\x52\x96\x7d\x20\xab\x7f\x2b\xca\x8f\x62\x25\x26\x90\x0e\x1a\x6a\x9e\x22\xdc\xe8\xa3\x3e\xcb\x6f\xc3\x30\x89\x97\x1f\xa3\xa1\x16\x51\x44\x47\xc0\x0b\x34\x7e\x91\xb7\xd8\x77\x01\xcb\xac\xfb\x3a\x25\x84\x19\x5f\x0c\x68\x82\xb0\x7c\x37\x89\x3a\x0a\x49\xdf\xcc\x12\x6b\x31\x64\x45\x6b\x0f\x78\x63\xe9\xf3\x39\x0b\x8e\x03\xd2\x6f\x3a\xab\x5e\x68\xc9\xf5\x30\x84\x04\x3d\x00\xc3\x52\x37\x74\x27\x24\xf1\x15\xef\xef\x30\x6c\xd5\x1a\x57\xbd\x85\xf5\xbf\x84\x72\xf7\xe3\xf8\xa1\x0c\xa3\x3e\x4b\xb4\x77\xeb\xf1\x64\x25\x0e\x0d\x0b\x11\xf4\xb0\x29\x9a\xec\xb5\xdc\x77\x74\x38\x34\x34\x3c\x25\x9d\x6b\xbb\xce\xb3\xd7\x4c\xe6\x88\x29\xa9\xbb\x1e\x52\x20\x48\xa5\x19\x70\xfc\x4e\xec\xfe\x28\x08\x23\x2c\x91\xdf\xff\xfe\xcd\xff\xc2\x0c\xf3\xdc\x26\x59\xde\xbe\xe5\x02\x29\xf1\xab\xe3\x75\x4e\x94\x46\x84\xf0\xd4\xe9\x57\x77\x9e\x26\xfd\xa7\x6f\x64\x1c\x11\x60\x0d\xd4\xcd\x83\xdf\xcf\x22\xc2\xd2\x40\xfb\xf2\x4c\x1f\x96\x72\x77\x37\x02\x08\x4e\xae\x14\x87\x91\x5d\xdb\x2b\x71\x04\x94\xe5\x99\xe3\xea\xa2\x11\x91\x61\x6a\xd3\x47\x05\x74\x64\x00\x34\x0a\x13\xc2\x2d\x0d\x63\x9e\xdf\x67\x72\xf2\x1c\x11\xa1\xb8\xe3\xd9\xf4\xa0\x90\xf9\xa4\xf8\xa1\xeb\xa6\x93\x31\xe1\x56\x6b\x18\x60\x36\x71\x50\xc5\x4a\xa3\x28\x11\x88\x2d\xd3\xe5\xc3\x40\x6d\x63\x72\xc9\x44\xa7\x1e\xf1\x78\x30\x83\x42\xff\xf9\xad\x2a\x8a\xb4\x85\x69\xd8\x22\x8b\x4d\x97\x1b\x1f\x21\xbb\x68\x14\x81\xc6\xe7\xfc\x17\x2e\x04\xe8\xc9\x4d\x9e\x95\xb1\x14\x83\xb5\x56\x19\xc6\xc6\xaa\xfd\x8d\x33\x6e\xa9\xb7\x1c\x16\xc7\x27\xdf\xbc\x5f\xb7\x2f\xfb\xe4\x19\x8d\x62\x61\x45\x6e\xbb\xcc\xe1\xd0\x8f\xb9\x96\x2c\x98\x8b\x44\xcf\x94\x1b\x8c\xc0\xcc\xe3\x19\x13\x25\xb1\x42\x61\x2e\x24\x64\xd9\x67\x47\xb8\xeb\xd6\xe0\x28\x49\x42\xa4\x0f\x69\xdf\xe7\x30\x04\x11\x25\x32\x45\x63\x1b\x43\x63\xed\xf7\x40\xf5\x87\x60\xe0\x2d\x0e\x17\x08\x9c\xa8\x7e\x9d\x88\xb8\xb1\xa2\x6c\xf6\xa5\x2f\x45\xf1\x5e\x95\x79\xf7\x02\xd2\x48\x20\x97\xf9\x01\xfd\xca\x6e\x51\x8b\x52\x09\xb8\xa3\x36\x1d\x0a\xf3\xa5\xf6\x7b\x65\x24\x28\x68\x17\x15\x58\x2e\x5e\x5e\x3e\xc3\xc1\x4d\xbe\xbe\xe0\x04\x51\x54\x1d\x4f\xe1\x62\xb7\x5b\xef\x0f\xcb\xc5\x6e\xdd\x9d\x58\x44\xe8\x30\x7a\x65\xe2\x1f\x65\x95\x6b\xef\x6c\x4f\xc6\x80\x10\x90\xf2\x4e\xe5\xf9\x58\xde\x3f\xed\xd7\xa2\x2a\xa6\xdd\x24\xb3\x74\xb8\x0e\xd7\xd7\xbe\xbc\x1b\xc8\xe1\x75\x48\x13\x33\x3e\x40\x27\x1d\x86\x51\xde\xc0\x51\x14\xba\x5b\x90\x22\xcd\xac\xa4\xf9\x47\x6b\x72\xb6\x03\x89\x75\x2d\x89\x16\xfd\x48\xba\x9b\x62\xae\x69\xa4\xb9\x65\xea\x2e\xce\xc7\x1e\x1f\xe6\xdb\x94\xc6\xf1\xfc\xb0\x79\xdc\xdb\x42\xbd\x9b\x97\xe7\xc5\x7e\xf3\xf4\x78\xd8\x3c\x1e\x7e\xac\xd7\xbf\xed\x7c\x57\x20\x96\xd1\xbc\x9d\x1c\x36\x78\x89\xd7\xf2\xad\x34\x8a\x9c\x53\xb9\xdd\xb8\x80\x30\x1d\x6d\x8b\x11\x44\x80\xc8\xde\x76\x49\xeb\xe4\x60\xfa\x68\x48\x04\x31\xb3\x05\x6e\x1d\x67\xe9\x12\x1a\xaf\x54\x37\xf1\xf0\x23\x48\x09\xe6\xa5\x6d\x64\x26\xea\x18\x72\xba\x93\x49\x2b\x26\x84\xd4\x41\x98\x50\x59\x9e\xab\x19\x1e\x18\xdf\x1d\xac\x38\x52\x0d\xcd\xee\x24\x14\x6c\x8e\xa7\x73\x3e\x61\x06\xa1\x91\x09\x39\x4f\xfd\x97\x6f\xdd\xb0\xd1\xf3\x19\x61\x0b\xf4\xba\x54\xc6\x42\x8f\xeb\xc4\x28\x0b\x92\x24\x0d\x86\x55\x13\xa6\x81\xea\x06\x84\xce\xb3\xc2\xbf\x4a\x94\x81\xc1\x32\x7e\xd1\x9c\x86\x36\x1d\x23\x22\x8c\x7c\x41\xfb\x48\x6b\xd8\x7f\x4e\x46\x53\x8e\x3c\x95\x3f\x82\xf7\x6c\x1f\x0c\x0e\xa5\x4a\x52\x33\x48\x32\xbd\x0c\x94\xfc\xc7\xc3\x85\x45\x24\x31\x2e\x34\xf3\x08\xbf\x9a\xdf\xe0\xd2\x03\x67\xda\x56\x19\xfb\x48\xed\xe2\xee\xec\x19\x65\xb9\x6f\xa6\x31\xe2\x0f\xbc\x6d\xf0\xb2\xbb\xb1\x70\xb4\xe9\x45\x58\x80\x2c\x62\x8b\xf7\xfa\xcd\xa5\x73\xbf\x20\xd1\xa5\x2c\xe2\x29\xc2\x36\xb2\x7a\x97\xb5\x2e\x5e\x77\x3b\x22\xc4\x14\x51\x59\xac\x9f\x57\x09\x25\x2e\xa5\xaf\xaf\x5c\x97\x81\x69\xcb\x22\xc9\xd0\x99\xdf\x77\x1a\xdd\x7d\x1c\x8d\x45\x32\xb6\xea\x24\xa2\xb8\xc1\x80\x79\x6b\x34\x8f\xef\x45\xf1\xc8\xed\xf2\x0b\xd5\xed\xeb\xfe\x0d\x30\x16\x80\xad\xe7\xab\xd5\x19\xc6\x51\x4f\xc6\xe2\x88\xba\x77\xeb\x4c\x96\xae\x41\xe0\x39\x47\xb2\xfe\x7e\x25\x65\x8c\x2b\xd4\x59\x5d\xed\xb6\xa3\x28\x1e\x63\x22\x40\xa5\x84\xef\x50\xd9\x30\xac\x27\x63\x18\xbf\xed\x58\x84\x48\x56\xf3\xb0\xf8\x03\xc9\x7b\xef\x9e\xba\xdc\x18\x8b\x8d\x72\x55\xb3\xd9\x4f\x78\x7e\xbc\x9b\xf7\x5e\x58\x12\x5a\xd9\x4a\x04\x70\x6d\x61\xbe\x82\x9f\xb2\x84\x07\x4e\x5b\x09\x15\x4c\xa0\xfa\x39\x9d\x26\x2c\x51\xd4\x32\xa5\xfb\x01\xb8\xf1\xe9\x89\x6f\x5d\x0f\xeb\xb7\x66\xaa\x24\xbd\xa3\xc0\x12\xc5\x29\x1b\x78\x24\x8f\xe2\x08\x7f\x6c\x6e\x6e\xab\xf2\x78\x23\x4e\x57\x2c\x10\xd7\x65\x74\xbc\x3b\x91\xc6\x59\x68\x35\x77\x6c\xd2\x7e\x3a\x0b\xd2\x30\x4a\x06\x32\xaf\x87\x37\x9b\x8c\xf6\xad\x4c\x05\xbd\x08\xe7\x2d\x74\xb7\x9e\x1a\x4b\x59\xab\xa0\x68\x6a\x37\xf2\x5d\x93\x08\x04\x6e\x87\x56\x1e\x6c\xba\x63\xe1\x4d\x8e\xde\x93\xe0\x0a\xc9\x10\x84\xd6\x5e\x73\xe8\x2a\x0a\xf2\x5f\x72\x47\x52\x26\x29\xf3\xfa\xd5\x37\x18\x56\x3d\xf6\x22\x97\xbe\x4b\x68\x89\xc0\x1d\x61\xf9\x80\xf6\x9d\x32\x15\xda\x2a\xa1\xbb\x87\xd5\xd2\xff\xa6\x03\x16\x26\x43\x86\xe9\xdb\x21\x18\xa4\x1b\xbb\x86\x0b\xe6\x16\xe2\x8e\xfc\xf5\x1a\x9b\xc1\x8c\x91\x58\xd4\x81\xbc\x7f\xf5\x56\x5c\xba\x17\x17\x07\x5c\x73\xaf\x40\xd5\x71\x73\xd0\x38\xd0\x80\x01\x0b\x8f\xd1\xe8\xa2\x9d\x83\x78\x53\x4c\xc2\x08\x71\x87\x4f\xf7\x4f\xbf\xaf\xbf\x5a\x61\x62\x92\xd0\x01\xb9\x02\x62\x82\x47\xe0\xe1\xf1\x7c\x88\x09\x00\x92\x02\x8a\xa3\x65\x54\xb6\x35\xd5\xfe\xb2\x54\x71\x0c\xc6\x2b\x91\xab\xbb\x8e\xf8\x87\xc6\x21\x11\xd2\xcb\xd2\xdb\x3a\x05\xdf\xc0\x35\x82\x96\xec\xbc\xf9\xb2\xec\xef\xbf\x85\x48\xd2\x38\x94\xc2\x2b\xee\xdd\x8b\x76\xd7\xdd\xda\xf4\x21\xc0\x08\xce\x36\xd9\x5a\xe3\x50\x4b\x0c\x3c\x3e\x97\x43\x80\x11\x8d\x23\x1a\x60\x3a\xe2\x26\x2b\x44\xb5\xde\x7f\xb7\x65\xa2\x5d\x6b\x44\x30\x5e\xb0\xfe\x05\xea\xec\x75\xd6\xcf\xd5\xe4\x3b\xc7\x91\x31\x48\xd1\x8c\x78\x42\x53\x56\x8b\x57\x91\x15\x9d\x67\x16\xb3\x28\xc2\xa2\x5c\xc4\x40\x6d\x6a\xe4\x80\x7d\x9b\xee\x1e\x31\x63\x31\xd2\x5f\x1f\x40\x95\xf5\xa5\x1e\x22\x16\x69\xdc\xae\x89\xdc\x13\x4c\x1e\xcb\xea\xf2\xa3\xac\x74\x8d\xd4\x28\xbe\x87\x96\x3c\x18\x28\xd6\x63\xc0\xb7\xdd\x4c\xc9\xe4\x3a\x71\x10\xab\xb4\xd7\xa2\xfc\xcf\xd4\xc5\x8c\xe3\x38\x0a\x3c\x59\xaa\x9d\x4d\x33\xc9\xb0\x38\x56\x2a\xb1\xec\xaf\xd7\x42\x15\xd7\x22\x38\xf3\xb5\x9e\x33\x41\x4a\xde\xd7\x3c\xd0\x38\x61\x12\x5c\xc6\x63\x9d\xdb\xfa\xcf\xc7\x2b\x53\x30\x4e\xa4\xc6\xd7\xeb\x5c\x14\x17\x65\xf2\x8d\x10\x23\xaf\x94\x9d\x48\x87\x2d\x54\x07\x9b\x38\x38\xf4\x32\x12\xae\x2b\xa7\x0c\x37\x0d\xeb\xe0\xdf\xaa\xce\xac\x1c\x5f\x2e\x0d\x39\xe6\xb7\x72\x30\x4d\xc8\xa6\x8d\x71\x6c\x3f\x35\x0e\x79\x1b\x95\xe8\x54\x50\xbb\x54\x5e\x2c\x62\x19\x0d\xf3\x05\xfb\x2b\x27\xf7\x3a\x78\x15\x8b\x34\x55\x6e\x0c\x38\x24\xc0\x7d\x59\xc3\x2e\xd3\xf3\x95\x7d\x34\x16\x42\x2b\xea\x82\x20\xcb\x4e\x6d\x7c\x3e\x73\xf8\xc9\x6c\x93\x09\xc1\x88\x9b\x7d\x12\x59\xfe\x1a\x4d\x1e\xc9\xa3\xb8\xab\x98\xaa\xea\x4c\x58\x62\x30\x58\x8a\xa6\xc9\xc1\x64\x90\x4f\x6c\xc5\x58\xa6\x0e\xa2\xec\x1e\x7c\x77\xa9\x17\xfa\x98\x4d\x07\x97\x14\x29\xa6\xb1\xf6\xbb\x65\x77\x2d\x95\x18\x47\x17\x74\x07\xc5\xaa\xd4\xdd\x32\xa3\x24\xf7\xdc\xe7\x8b\x3c\xc7\xb4\x38\x0a\xea\x58\x5c\xc9\xc4\x63\x8f\x35\x30\x70\xa1\xec\xd5\xdb\xb9\x78\xa7\xfb\x12\x81\x60\x3d\x1b\x20\x8d\x21\xd2\x18\xa1\xad\xac\x91\xdd\xe1\x47\x47\x76\x69\x0c\x89\xc1\x94\xde\xe2\xc7\x8d\xff\xc9\xc4\x8c\x6a\x47\x41\x08\x55\x73\xd9\xe8\x7d\x69\x1d\xc1\xf1\x6b\x35\x86\xe0\x36\xb8\xbf\xf7\xcf\x97\x04\x01\xe0\x4f\x4e\xe5\x63\x95\x97\x75\x7b\xc5\xde\x4a\x4d\x82\x28\x46\x6f\x64\x58\xb1\x88\xa5\xed\x85\xc8\xeb\x46\x18\xa3\xb3\x5a\x9e\xab\x1a\x61\xf4\x73\x91\x56\x7f\x9e\x34\x41\x93\x03\x77\x25\xda\x9d\x5d\x08\xb4\x0d\x30\x92\x79\x37\x5a\x24\x93\x40\x27\x81\x8d\xa0\x08\xbd\xb4\x8b\x6c\x3d\x91\xee\xa3\x09\x09\xa8\x13\xb8\x2a\x9a\xdb\x5c\x34\x37\x22\xeb\x35\xd6\x7c\x9f\x30\x40\x76\xa2\x0e\x8b\xba\x29\x4c\xb9\x6b\x1d\x22\x3f\x0b\x93\x30\xb6\x5a\xbc\xfa\xdc\xa8\x37\x67\xf9\xed\xcb\xe5\xd9\x2f\x85\x49\xc4\x95\x71\xe5\xcf\x37\xa2\x11\xcf\x50\x9f\xca\xa2\xf5\x19\xbe\xd6\x6f\xf5\x22\x96\xfd\x84\x4a\x58\x18\xbb\x82\x44\x6b\x7b\xfd\x81\x6b\x66\x55\xfe\xcc\xf4\x74\x51\x4c\x58\x42\x3d\xfb\x11\xa6\x11\x6c\xd5\xf7\xe4\xf1\x58\x1a\x4b\x33\x34\x48\x40\xaf\xde\xb2\x5c\x4f\x3d\xd4\xa4\x9d\x07\x98\xc2\xc9\x85\x7a\xff\x3e\x7a\xd7\x09\xa5\x58\x9b\x36\xe5\x43\xf4\xcd\x91\xad\xd2\x6e\x37\x82\xcb\x40\xa3\xac\x3b\x3c\x4a\x85\xab\x6b\x3e\xc8\x71\x49\xc2\xe4\x44\x46\x0b\x0b\x04\x2f\xdf\x7f\x64\xcd\xdb\x50\xd0\x7e\xbc\x06\x8d\x33\x2b\x53\x14\x5e\xc2\x69\x8c\x6b\x19\x1c\xb3\x66\xf7\x8e\xb5\x98\x20\xea\x1d\xcc\x57\x36\x51\xa4\x11\x56\x1d\xc9\xef\x0f\x80\x77\x1b\x71\xc2\x78\xd9\xba\x6e\xb2\x63\x87\x0b\xa7\x49\xca\xb5\x25\x96\x1a\x28\xef\x0b\x44\x85\x5c\xe1\x25\x46\x96\x4f\x92\x0a\xe6\x56\xe9\x9f\x90\xef\xdf\x2a\xb0\x4e\x65\x57\x36\x48\x13\x01\x22\x10\x5d\x41\xd4\x27\x15\x05\xae\xaf\x14\x04\x1c\x6a\x74\xf3\xfb\x61\x37\xf9\xec\x2a\xe0\x98\xb0\x7c\x10\xbf\x0e\xab\xc5\xd6\x5f\x40\x73\x83\x6e\xc3\x69\x98\x7f\xec\x77\xb7\xc4\x38\x6a\x9d\x4d\xa1\xb6\x36\x91\x30\x28\x53\xee\xcf\x6e\x22\x63\xdc\xb5\xbd\x6f\xe7\x1c\xb0\x21\xa1\xec\xf8\x86\x79\x40\xad\x88\xbf\xe3\x0a\x1e\x25\xe4\x7c\x17\x16\xa0\xb8\x48\x6b\x17\x6f\x2b\xc8\x4a\xbd\xc2\x95\x67\x32\xa8\x79\x20\xb9\xd7\xe6\xb7\xd1\xbf\x65\x79\x9e\x16\xe4\x53\x1e\xa8\x10\x2c\xc9\xfe\x88\x01\x94\x72\x12\x68\x34\x6b\x5e\x8a\xac\xf9\x4b\x97\x98\x13\x1a\xa0\x25\x55\x9e\x9b\xba\x11\x58\x84\xeb\xa4\xe8\xeb\xee\x84\xa9\x75\x62\xac\x7c\xce\x42\x97\xa7\x76\x89\x18\xa0\xa1\x98\xef\x28\x25\x86\xf9\xfc\x46\xde\xab\x80\x0c\x56\x55\x4e\x4d\x8c\x11\x20\x64\xc0\x79\xd9\xf9\xa5\x9c\x87\x26\x0c\x53\x9f\x04\x1b\xa7\xe0\x46\x77\x1c\x1a\x1b\x5e\x45\x4f\x73\x8c\xf5\x8e\xfe\xd9\xbb\x69\x21\xfd\xdf\xc8\xad\x94\x3c\xe2\x1a\x0b\x84\xdf\x95\x7a\xa7\x2c\xae\x9b\xaa\x6e\xaa\xb9\xd0\x35\x8f\x84\x65\x8f\xe9\x49\x63\x0d\x54\x22\xb7\xa1\xe5\xf1\xe7\x8c\x64\x80\xbb\xc3\xd6\x7a\x55\xdd\xeb\x8a\x20\x44\x90\xec\x73\x29\x4b\x2f\xf5\xb6\x51\xe5\xf4\x68\xb0\x01\x82\x03\x16\x60\xe8\x27\x73\x2f\x30\x34\x9a\x15\xaf\x7d\xd6\x90\x33\xc6\x39\xed\x05\xb3\xfd\x7b\x19\x92\xe1\x53\x1e\x07\x56\x67\x6c\x71\x73\xb3\xd9\x6f\x9e\x1e\x17\xf7\x56\xa4\xfc\x70\xb3\x7e\x7c\x7a\xf0\xa7\x8a\x69\x8c\xe8\x10\x6b\x6c\x3d\xc2\xaf\x06\xc9\xbb\x90\xa9\xeb\xd2\x91\xc1\x0f\x4d\x78\x9e\xa4\x61\x18\xb9\x5d\x39\xab\xe0\xb1\x6c\xfe\x01\xd5\xf4\x41\x92\x54\x62\x7e\xa4\x2a\x73\x58\xb5\xf6\xf6\x97\x90\x1d\x9e\x28\xf0\x48\x35\x97\xa5\x1d\x66\x1c\x5c\x27\x1e\x1a\x15\x0f\xf8\x23\xff\x9b\xea\x23\xca\x53\x1a\xa1\xc9\xee\x77\x65\xc7\xb3\xf4\x1f\xd0\x73\xca\xf8\x6d\x7f\x89\xe6\x67\xfb\xa5\xf3\x55\xd9\xfb\x0f\x3c\x8d\xa2\x28\x75\x0e\x16\x62\xa4\x0e\x86\x24\xdf\x45\xfd\x76\x70\x67\xe8\x3a\x26\xb1\xb6\x70\xc2\xfa\x0c\xd6\x0e\xae\xa7\x71\x17\x2e\x62\x8e\xf0\x81\x77\xb8\xa0\xce\x6f\x3d\x3b\xf2\x24\x23\xa8\x75\xf0\x9f\x57\x68\x9e\x30\xb9\x39\xa2\x66\xa3\x5c\x72\xc0\x71\xf5\x20\x7e\x2d\xcf\x75\x56\xf4\x01\x21\xae\x20\xd1\x43\x1c\xec\xf2\xf2\x5c\xe8\xc7\x72\xf2\xbc\x3a\x22\x98\x57\x12\xdd\x7b\x59\xf5\xf2\x1e\x9f\x20\xdb\xb8\xe6\x09\xa2\xd9\x1f\x4a\x9d\x59\x01\xe5\xe7\x15\x0d\xbe\x5c\x52\x74\x1a\xa1\x31\x77\x0b\x4e\x86\xed\x13\xef\x97\x83\x8c\x90\xe1\xf6\x06\x8e\x3d\xfc\x86\x83\xd4\x58\x30\x57\x94\x88\x9b\xed\x7e\x06\xad\xa4\xd3\x52\xda\x09\xf3\x57\x83\x01\x0c\x43\xfe\x9e\x97\xc7\xcd\xe3\xa2\x27\x8e\xa0\xdc\x08\x82\x89\x78\xe7\xa1\x8f\x02\x09\x1e\x8a\xc6\x8d\xb6\xc2\xea\x47\x54\xae\xdd\x8a\x8b\x2b\xa4\xb9\x39\x7b\xa2\x29\x9a\x06\xa9\x41\x63\x5f\x5b\xa1\x3a\x5f\x8e\x83\x73\xa0\xfe\x36\x22\xce\xf2\x47\xe8\x24\xe9\xbd\x7d\x8c\x24\x7b\xb7\x29\x25\x44\xe2\xd7\xd5\x25\xd4\x4f\x1f\xc5\xba\x79\xfb\x2e\x0a\x9d\x5f\x15\xe9\xfb\xee\x71\xcc\x1d\xe0\x7e\x71\xd6\x59\xe3\x58\x7a\xc4\x3c\x3d\x3d\x4d\x69\x2a\xd0\x4d\x72\xea\x88\x07\x24\x57\xeb\x41\xf2\x29\x15\x86\x18\xf7\x76\xe7\x48\x18\x68\x4a\x15\xb1\xd2\x58\x50\x37\x7b\xa4\x66\x73\x02\xff\xeb\x02\x55\x30\x9f\xe1\x67\x56\x67\x65\x67\xad\xa7\x54\x71\xdc\x46\x7f\x8a\x3c\xd3\xc3\x92\xea\xaf\xbf\x5c\x1a\x8a\x08\xab\x38\xd6\xb5\x12\x27\xf8\x2e\x1a\xf5\x86\xa4\x42\x95\xdf\x2d\xc7\xf7\x15\x1a\x8a\x31\xe9\xf5\xd3\xce\xbf\x84\x01\x91\xac\xeb\x14\x11\x96\xf8\xc7\x6b\x6d\xaf\xd6\x6d\x39\x57\x77\xa2\x5e\xff\x52\x70\x6a\xd6\xbf\xae\xc5\xb4\xc6\x37\x15\x11\x8e\x45\xcd\x36\xd8\x97\xfd\x07\x2a\xcf\x82\x3f\xff\x7d\xa2\xc8\xda\xdd\x0f\x59\x01\x58\x0b\xeb\x7f\x4f\xa9\xd7\x0b\x7a\xb8\xb4\x4b\xfe\x6d\x05\x5e\xff\x7a\x9a\x7d\x48\x23\x29\x31\x60\x7b\x2e\x4e\xe2\xb2\x2d\xcb\x7c\xf0\xc1\x22\x1d\x40\x4f\x9d\x6d\x0b\x22\x87\x45\xb7\x63\x9b\x31\x65\x11\x30\xe1\x78\xb7\xaa\xce\xaa\xa9\xeb\xcf\x8c\xc6\x94\xa5\xb6\x92\x59\x1c\x65\xb6\xf2\x17\x8d\x03\x8e\xa6\x85\x12\x79\xbe\x83\xea\xe7\x67\x98\xa3\x94\xc7\x4c\xb9\xb2\xa6\xe5\xf9\xe2\x5d\x9e\x34\x55\x56\x90\x3d\xab\x77\x67\xf9\x2f\x50\x4d\x27\xcd\xe1\x3a\x88\x44\xa3\xc0\x7b\x3b\x37\xbc\x3f\x89\x60\x96\xaf\x41\x44\xa9\x80\x00\xfd\x80\x23\x02\x43\xb6\x30\x2e\x06\xa7\xa9\x30\xa1\x85\x77\xe0\x82\xb7\x28\xf4\x0e\xf2\x7c\xe1\x41\x20\xed\xfc\x6e\x3e\xaf\x8a\x99\xbf\xa4\xe4\x80\x1b\x38\x54\xaf\x20\x8b\xac\xbb\x94\x26\x4c\x59\x6b\xfb\xdf\x67\xe8\x63\x73\xa9\x8e\x3a\x3d\x55\xeb\x45\x58\x24\xd6\x5d\x55\x9e\x4f\x93\x21\xad\x65\x80\xa9\x9b\x9f\x19\x7c\x2c\xf2\xdc\x29\x14\xd4\x03\xb8\x49\xaa\xa5\x96\xde\x2b\x99\x58\x86\x29\xc4\x0c\x6d\x67\x9b\x31\xdd\xbd\x95\xa7\x87\x52\xc3\x35\x93\x76\xdb\x33\x21\x5e\x92\xc8\x96\x15\xda\x02\xb6\xcb\xa4\x9f\x09\x2c\xb4\xdb\x2a\x91\xd0\xf1\xf5\x44\x10\x58\x78\x95\xf5\x7e\x6e\x20\xcf\x7e\x0e\xf0\xc7\x22\xe0\x0a\x63\xfe\xff\xb2\x21\x94\x2d\x54\x75\xc7\xf6\x48\x45\x20\x19\x3a\x27\xde\x25\x5c\x8a\xfa\x1d\xae\x45\x46\x66\x91\x97\xd7\xa8\x12\x11\x28\x83\x7c\xac\x27\x7a\xb2\x73\x62\x6a\x85\x0b\xe2\xd8\xc3\xed\x22\xdc\xf3\x12\x53\x41\xe3\x14\x63\xcc\x59\xfd\x0c\x18\x2f\xbc\x2b\x3b\xf0\x82\xa0\x09\xc5\x05\x14\x95\x5a\xec\x8e\x39\x64\xee\xeb\x7a\x59\x93\xa2\xf5\xdb\x0f\xe7\x1a\xaa\x83\x6e\x9d\xf2\x03\x72\x09\x4c\x6e\x24\x8c\x53\xbc\xd5\xac\xc8\x9a\x1b\xbb\x2c\x77\xe7\x61\x2c\xc2\xdd\xeb\x67\xd9\x00\xf2\x0d\x75\x45\x3b\x57\x19\xa9\x6e\x4c\x08\x26\x03\x64\x93\x6e\xad\x16\x2f\xdf\x3a\x84\x9f\x8a\xd8\xa4\x18\x7a\xfd\xc7\xf7\xf5\x9f\xfe\xb7\x24\x92\xbc\xb3\xc7\xe4\xf9\x75\x54\x7c\x28\x12\x25\xb0\x66\x7f\x99\x35\x8b\xfc\xf4\x26\x26\x84\xc5\xdd\x6b\xe7\x01\xc1\x6f\x7c\x2e\xf2\xac\x6e\xfe\x7e\x16\x79\x66\xb2\xd6\xee\xaa\x9a\xe2\xea\x0b\x70\x6a\x6b\xdd\x74\xf6\xda\xa3\x69\x04\x17\x80\x25\x8c\xaa\xd3\x6f\x21\x5d\x93\xb1\x64\x10\xef\xb5\x6a\x17\x86\x1f\x6f\x50\xbc\xd4\xb0\x29\x76\x99\x06\x85\x8c\xf8\xd3\xc5\x7b\xb8\xf8\x8b\x34\x08\x53\xd5\xdb\xf4\xb8\x47\x8d\xef\x28\x8d\x2c\x04\x6a\xff\xfc\x30\xe1\x2d\xa3\x22\xe5\x14\xf3\xde\x53\x52\x4e\x14\x5f\x9e\x37\x6c\x44\x2a\x42\x66\x59\x05\x9a\xac\x82\x99\x78\x9b\x48\x95\xd5\x69\xb2\x36\x03\x46\xac\x7e\x17\xe7\x7c\x3a\x46\x04\x15\x60\x79\x1e\x1a\xa8\x46\x5c\x1c\x54\x08\x6d\x42\x39\x48\xc6\xde\x9f\xd5\xbb\xab\x3f\x1d\x61\xc0\x84\x00\x81\xa6\xc5\xa9\xca\x14\xdc\x23\xfd\x8d\xb5\xca\x5c\xbb\x0a\x2d\x34\xd1\x27\x21\xfe\x7e\x2e\x1b\xf7\x9a\x7c\x0f\xce\xa9\xea\x9e\xa7\x35\xa5\x47\xf2\x2d\x54\x68\x2a\x10\x19\x73\x38\xbc\x7a\x96\xb9\xf1\x1b\xd1\x11\xe9\x88\x31\xfc\x1b\xb6\xbc\xef\x85\x5e\x5b\x1e\xff\x7a\x7e\xeb\x12\x3a\x8e\x30\x57\xbc\xfb\xbe\x78\x5e\x1f\x6e\x9f\x5e\x1e\x6f\x10\x5a\xe0\xaf\x0d\x31\x37\xb1\xa7\xc1\x3f\x17\xb6\xe4\x6a\x3b\xc5\x5b\x08\x43\x14\xa2\x97\x4f\xa2\xaa\x61\xa6\x0e\x46\x98\x84\xe0\x96\x9d\x21\xb7\x2c\xb2\x7f\x4f\x26\x5b\x4f\x1c\xe0\x0f\xe1\xa9\x70\xe1\xa7\xfa\x7c\x9c\x26\xad\x84\x91\x0a\xeb\xfa\x6b\x27\x0c\x3c\x84\xf0\x39\x7e\xa4\xab\x34\xe3\xf9\x8a\x38\x9c\x4a\x02\x96\x55\xd6\xea\xbe\x8d\x82\x10\x73\x20\x5c\x19\x86\x56\x34\x49\xe5\x19\x14\xcd\xd1\x7e\x2a\x84\x48\xb9\x77\x26\x23\x09\xbc\x43\xbf\x2f\xcf\x97\x95\xa8\xf4\x68\xe6\x4b\x16\xc7\x80\x51\xb1\xac\xc9\x9c\x14\x73\x3d\xc0\xcf\x4b\x06\x1c\x17\x4b\x84\xf4\x60\xda\xc3\x7d\xc6\xae\x83\x31\xe8\xce\x3f\x2f\x17\xde\x7e\x90\x09\xa3\xc8\xf2\xe4\x14\xfc\xbe\xa2\x4b\xf5\x47\x18\x3d\x90\x9c\x78\x00\xf5\xf6\xfb\xf3\x6a\xde\xc6\x95\xad\x23\x2c\x3b\xb4\x5d\x3b\x0a\x6e\xcb\xea\x36\x33\x5d\xb2\x4f\x0a\x00\x5f\x0f\xb9\xc8\xf3\xef\x27\x89\x4c\x84\xc8\xc8\xf9\x0a\x8f\xe7\xb1\x4a\x61\xeb\x1d\x4a\x8c\x80\xff\x04\x2c\x28\x5d\x42\x01\x26\x53\x99\xa8\x2e\xb7\xa5\x4b\xf7\xcf\xda\x06\x52\x18\x8d\xd3\xd6\x15\xfc\x58\xf0\xfe\x8b\xb7\xeb\xa4\xd4\x96\x81\x7d\x99\x69\x9d\x15\xaf\xcf\x33\x14\x9d\xae\xa7\x12\x91\x2d\x56\x6f\x5f\xf0\x53\x01\x7d\x1e\x5b\xea\x38\x75\xd5\x32\x79\xfe\x0c\x83\x28\xd6\x27\x6f\x52\xa7\x29\x86\x79\xdb\x6f\xd4\x31\x52\x51\xa9\x35\x40\x3b\x7b\xda\xce\x2b\xc8\xf2\xf9\x15\x4d\x9a\xc4\xaa\x1b\x0b\x2b\x3f\x7c\x45\x70\x4e\x55\xc0\x94\x70\x30\x73\x4b\x77\x84\x8e\xf3\xb4\x93\x4c\x4d\xeb\xb6\x38\xed\xdf\xe7\xbd\x13\xfa\xa2\x8a\xa8\x20\xec\x09\x8c\xdd\xde\xfd\x35\x16\x5b\x11\x1d\xa2\xa7\xf8\x0f\x28\xca\xe3\x94\x71\x92\x2a\x1a\x58\xae\xcc\xcd\xea\xe9\x01\xa0\x39\x8f\x60\x30\x8a\x52\x81\xbc\x13\x36\xaa\x75\x25\xec\xf4\xd5\x8e\xa2\x5a\x2f\xd2\xe9\x5b\x7c\x72\x6b\x61\x04\x31\xef\x38\x11\x0b\x2d\x2a\x8d\xf1\x20\x7f\x75\x16\x2a\x99\xf8\x0c\xe5\xb6\x9c\x40\x14\xf9\xdf\x06\xff\xf0\x71\x1e\xc5\x12\x8e\x28\xf7\xd3\x08\xb4\x33\xa7\x83\x4c\x15\x93\x91\xb3\x42\x1b\x1f\x06\x19\xef\x7c\x13\x65\x57\xaa\x98\xe6\x18\x6f\xf7\x31\x04\x9b\x8a\x1e\x86\xba\x55\x12\x58\x50\x8a\xea\x57\xf0\xf2\xd4\x35\x46\xa1\xa6\xce\x37\xb8\xc1\x09\x33\x2c\x52\x53\x49\x2c\xb1\x9e\x07\x6f\xfa\x1a\x5e\xa6\x92\xd8\x4e\x19\xa1\xf5\x4d\x56\x63\x61\xad\x65\xd3\x9a\xd5\x1b\x1d\x1f\xcb\xb5\xf1\xec\x72\xc8\x47\x36\x6e\x4d\x89\xf6\x4a\x53\xf7\x59\xd1\x1a\xde\xeb\xfd\xf7\xb1\x7f\xa0\xd2\x28\x92\x74\x24\x37\x81\xf7\x39\x96\xf7\xef\x5e\x55\xca\xc1\x71\xa6\x82\x7a\x9f\x07\x62\x4c\x6e\x41\xa6\x48\xb9\x61\x90\x3f\xdc\xb2\x6a\xfa\xea\xac\xc2\xe5\x8c\x5d\x57\x49\x45\xe2\xa5\xea\xbb\x12\xdd\xf1\xd9\x64\x18\x23\xfb\x69\xbb\xd7\xbe\xd8\x52\xaf\xee\xe8\x24\xc6\x5a\xdd\xfa\x5c\x9f\x30\x4e\x32\xd4\x17\xa0\x4a\x1a\x40\x3d\x98\xfa\x7c\x3c\x7a\x53\xce\x35\x29\x66\xb4\xdb\xe2\xab\x0c\x7e\xc2\x03\xba\x44\xa3\x51\xaf\xd3\x84\xea\x5e\x79\x1b\x0b\x01\x06\x2b\xbe\x02\xa1\x70\x59\xc3\x2d\x6d\x5f\xbe\xb4\x83\xda\x86\x41\x86\xd9\x0d\xd7\xd9\x44\x36\xbf\xee\x73\x6b\xcd\x0f\xff\xd9\xe7\x97\x42\x65\xa2\x58\x47\x63\xaa\xe0\xf2\xe3\x13\x51\x47\xaa\x8c\x8e\x88\xe9\x2b\x84\x7a\x6c\x8d\x0e\x02\xa6\xf1\x5b\x64\x85\x7e\x84\x8f\x2e\x6c\x33\x8e\xb6\xe9\x80\x27\x28\xa8\x70\x53\xb6\x6d\xdd\xbe\xa7\x03\x69\x48\xd4\x57\x9c\xae\xca\x3c\x17\x87\xc5\xe2\x10\xd0\xb9\xa8\x9e\xa6\x24\x12\xc9\x60\x59\xcb\xbc\xc4\x50\x36\x94\xda\xfe\x72\xe5\xd6\x34\x8c\xc3\xbe\x0c\xd1\x93\xfa\xf8\xb1\xab\x29\x17\x18\x45\x3b\x9e\x6b\x75\xc5\x15\x4d\x35\xd5\x3c\x74\x64\x8d\xcb\xb2\xcc\x2d\x11\x7a\x87\x00\xee\xc6\x86\x0e\x19\xc1\x40\xdf\xff\xdc\x7b\x50\x97\x0e\x59\x8a\xe5\xbe\xbf\x97\x0d\x58\x40\xc6\x34\x57\xa1\xc3\x38\xa2\xba\xa3\x3f\x9f\xbe\xc4\x50\xa4\xda\x01\xc1\xbd\xc0\xcf\xb4\x4b\x94\x50\x90\x9d\x04\xce\xa0\xf2\xb8\x6b\x8f\x30\x72\xb3\xf4\x1c\x07\xf5\x50\x91\x6d\xf2\xa6\x22\x2e\x52\xe7\x15\xff\xb1\x3d\xcb\xf1\x9a\xa8\x23\x48\x30\xb8\xd0\x2b\x44\x3e\xa3\x3d\xab\x6f\x4b\x94\x72\x9b\x74\x67\x41\x84\xf8\xb1\x1a\xe9\xba\x47\x01\x2c\xdf\x43\x68\x3a\xa0\xf6\x7a\x06\x55\x56\xfd\x77\x89\x43\x69\xc9\x60\x2d\x02\xf2\x7a\x91\xd6\x31\x0f\x22\x4b\x14\x34\xe0\xc2\xa4\x3a\x21\x11\x86\x76\x06\x90\xdf\xac\x78\x9d\xad\x13\xd3\x89\xe6\x88\x86\x6d\xd7\x33\x1f\x1f\x9b\x8d\x48\x69\xce\x02\x0b\x04\x68\x97\x66\x8f\x53\xd4\x5c\xda\x20\x66\x05\xaa\xfc\x09\xd5\x40\x96\x93\x6a\x29\x03\x64\x6a\x2c\xe0\xe3\xa1\xd4\x90\xef\xde\xb2\x93\x4b\x76\xf8\x2e\x2a\x48\x85\xa7\x2d\x39\x44\x07\x51\xb7\x06\xea\x9d\xa8\x5f\x5a\xeb\x3a\x09\x02\xf4\x5d\xbb\x37\xa2\x04\x45\x68\x72\xd3\x38\x26\x80\x21\x48\x5c\xeb\xd0\xd2\x6b\xd8\xba\x71\x57\x98\x3f\x94\x3c\xa5\x10\x50\xa2\x2c\x57\x94\x3a\x57\x59\x73\x79\xee\x11\x84\xbe\x87\x0e\xa8\x53\x25\x68\xed\x64\x1f\xf8\xef\x5b\xd1\xa0\x5b\x6e\xb6\x4f\x4f\xdf\x0f\x37\x8b\xa7\x43\x48\x0f\xc2\x37\x13\xa2\x89\xad\x4b\x2f\x06\x53\x1e\x08\x08\xee\x40\x8b\xa8\xfb\x34\x0d\xa3\x00\x65\x14\x79\x74\x31\xbf\xbf\xc3\x18\xc9\x78\x9a\x00\x35\x29\xee\x9c\x0f\x50\xa9\x73\x0e\x93\xbc\xdc\x0c\x34\xc7\x1d\x17\x52\xc1\x58\x17\x5a\x09\x46\x60\x10\x08\x23\xea\x59\x5f\x4f\xad\x5b\xfa\xc7\xe4\xa2\xa1\xb6\x41\x2f\xcb\xd9\x50\xfc\xb4\x82\x18\xbd\x18\x0b\x85\x28\xd0\x28\x38\xb1\xdd\xfe\x36\x3a\x73\x14\xc6\x18\x17\x72\x23\x70\x6f\x6b\x28\xc6\x67\x67\x61\x8c\x59\xca\x4c\x95\xf7\x60\x9a\x11\x7a\x0a\x58\x62\x53\x98\xf7\x4f\x77\x87\xb5\x57\x67\x5c\x9c\x9b\x72\x60\x31\x00\x4b\x34\x31\x2e\x26\x79\x5f\xbe\xae\xab\xca\xb9\xae\x9f\xec\xf3\x10\x07\x32\x75\x88\xab\xbd\xc8\xa1\x40\x72\xa0\x39\x86\x46\x0a\x31\x8f\x45\xdb\xd5\xb2\x82\x3d\x23\x45\xca\xd0\x96\x81\x98\x2b\x84\xca\xe6\x59\xdd\xd8\x11\x77\x10\xf5\xfb\xe4\x2c\xdc\x50\x34\xbf\x35\xe4\xd0\x80\x9d\xdf\x9f\x14\x03\x8f\x7c\x56\x48\x23\x09\x72\x80\x0d\x9b\xc9\x46\x43\x9a\x84\x34\x1e\x94\x9c\x8d\x59\xb3\xfb\xa7\x16\x2c\xf6\x3c\xa2\x0f\xdb\x39\x29\x33\x0a\x82\xdb\x3a\xf8\x5e\x53\xf8\x94\xfd\x06\x97\xd1\xf6\x0d\x02\x38\xb2\x7f\xe8\xd2\x21\x2e\x10\x25\xfc\x5c\x96\x03\x9e\xae\x49\x65\x88\xb7\x78\x40\x52\x86\x58\xb7\xbd\x15\x1f\xd2\x53\xff\x73\x46\x3a\x63\xe2\xd3\x4e\x6d\x68\x90\x2c\xc1\xfa\xaf\x07\xd0\x99\x2a\xbf\x83\xc8\x9b\xb7\xc9\xe6\x00\x8a\x0b\xe4\xfe\x3e\x66\x45\x73\x10\x85\xee\x19\xa7\x66\xd7\x7f\x50\x90\x62\x11\x9a\xa3\x27\xf5\xf5\xd3\x93\xb7\xa5\x4c\xa2\x30\x12\x90\xa9\x77\x8b\x39\x1d\x7d\x9e\x4f\xff\x70\x87\x1b\x1d\xe2\x6c\xdf\x3c\xae\xd6\x8f\xfb\xc3\xed\xcb\xe3\xcd\xe1\xf7\xf5\x6e\xbf\x79\xbc\xf3\xf7\x6d\x40\x20\x52\x5a\xe5\xd0\x15\xcc\x83\x31\x40\x86\x48\x2c\x6b\x60\xbf\x65\xa7\x69\xad\xbc\x21\x89\xb2\xee\x63\x79\xd4\x7e\x71\x32\x84\x07\x58\xc9\x27\x74\x3b\xe4\xb3\x76\x1f\x72\x79\xe9\x07\x40\xc7\x7d\x72\x0e\xb0\x98\x6e\x40\x75\x9f\x73\xa1\x67\x34\x26\xa9\x21\x26\xe2\xca\x8b\x3e\xfc\x0c\x27\xe7\xa0\xa9\xa0\x5e\xa0\x60\x7b\x2e\x2c\x53\xc4\xbe\x5c\xd4\x75\xf6\xea\xd7\x0a\x13\x26\x0a\x31\x3d\x59\xfd\xbd\xd4\xf9\xd5\x7d\x44\x11\x53\x9e\x7f\xbf\xae\x4b\x85\xaa\x3d\xf3\xe5\x13\x26\x8a\x13\x5c\xb0\x36\x5d\x04\x46\x63\xa1\xe2\x7f\x03\x6d\xec\x9f\x89\x05\x96\x6b\x2a\x73\x1a\x41\xe3\xc1\x4d\x83\xaf\xe3\xfa\x86\xa5\x80\x55\x87\x8b\xcd\xea\xbb\x7f\xc6\x98\xda\xba\xfd\x53\xa6\xca\x53\x7d\x80\x21\xd5\x20\x35\x71\x4c\xa5\xcf\x4c\xba\xc8\x70\xe9\xcb\x23\x27\xeb\x92\x89\x93\x28\x41\x37\xf7\xdc\xa7\x36\x4d\xac\x04\xa6\x7e\x35\x08\x7d\xf3\xff\x73\xf6\x66\xdd\x8d\xea\xd8\xfb\xf0\xd7\xa9\x8b\xbe\x00\x24\x01\xba\x74\x1c\xa7\xca\x7d\x92\xd8\x1d\xbb\xaa\x7a\x58\xbf\xe5\xa5\x61\x2b\xa1\x83\xc1\x0d\x38\x29\x9f\x4f\xff\x2e\xb6\x24\x26\x93\x9c\xfa\xbf\x37\x27\x75\x8c\x98\x84\x86\x3d\x3c\xfb\x79\x2a\xf1\xdc\x47\xde\x4c\x0c\xc0\xbc\xac\x45\xd1\xef\x64\x26\x49\x18\x42\x13\x7f\x64\xf0\xbe\x03\x55\x41\x73\x03\xd3\xee\x4c\x14\x4f\xfb\xa8\xfd\xbc\x63\x6f\xd2\x80\x8a\xd4\xd5\x6c\x6d\xcb\x3c\xdf\x8d\xc8\x73\x46\xab\x9a\x49\xa9\xc4\x4a\xe1\x9b\x5c\x14\xcf\xb5\x78\x1d\xee\x19\x26\x15\x09\x82\xbb\x3b\x49\xce\xdd\x59\xd6\x4d\x75\x56\xcd\xa6\x80\x1e\xd2\x60\x78\xc0\x3c\x3d\xf0\x5d\x05\xf0\x94\xa1\x46\xff\x43\x59\x35\x7d\x93\xd0\x72\xdf\x38\x91\xa8\x5b\xbb\xbf\x75\x47\x93\x10\xed\x5d\x1b\x12\xea\x51\x5b\x53\xe8\xbb\x11\xa1\x50\x7d\x15\x81\xa3\xe6\xb8\x2b\xab\xa5\x28\x74\x77\x2f\x11\xc5\xc8\x45\xd8\x09\x12\x59\x0b\xb4\x1e\xe5\x83\x8d\x20\x56\x21\x02\x65\x6b\xae\x73\x66\x93\x7e\x92\x01\x8b\xaf\x29\xef\x3a\x66\x96\xb1\xe4\xbe\x3f\x47\x44\x18\x4f\x13\x4d\x23\xd4\xeb\xfc\xfa\x66\x64\xbb\x6a\x8e\x50\xac\xfe\xf5\x5b\x6f\xd2\x4a\xce\xde\x89\x3c\x97\x33\x97\x18\x61\xcb\xdc\xf5\x54\x10\x1a\x6e\x99\x63\xd4\x21\xfc\x60\x84\xe8\x48\x85\x96\xb4\x02\xcb\x30\x76\xcd\xd0\xaf\x37\x5a\x29\x0c\xe6\x7f\x5d\x3c\xac\x0e\xbb\xef\xdb\xed\xfd\xbf\xba\x43\x00\x58\xe8\x7c\x40\x18\x47\xbb\xfb\x7e\xfb\xb9\x9c\x2c\x40\x90\x86\x31\xe9\xf2\xaa\xb7\xbb\x43\x0d\x48\xd7\xb0\x3d\xcb\x3f\xe0\x52\x23\xe1\x85\x6f\x2a\x22\x84\x51\x34\x20\x8e\xce\x3a\xec\xa0\xc4\x06\xb4\x2d\x4b\x7c\xf6\x72\x08\xcb\xd2\x11\x3f\x3c\xb5\x8f\xdb\x37\x03\x63\x49\x61\x9c\x5c\xe2\x6f\x21\x4b\x8c\x01\x89\xce\x60\xcf\x43\x34\xf0\x7b\x8d\x31\x86\xbb\xd0\x05\x6e\x39\xfe\x9b\x5c\x91\x3a\x93\x20\x10\x24\x18\xec\xf9\xbd\xf0\xd6\xd4\x64\x24\x41\x68\x04\x8b\xbc\x09\x51\x1e\x4b\x04\xe0\x8e\xaf\x16\xd1\xc4\x6a\x9b\x9c\xe5\x31\x6b\xb6\xb9\xc8\x8a\x06\x7e\x35\x33\xdc\x71\xd3\xaf\x4a\x82\x28\x8e\x95\x57\x07\x81\x3c\x47\x28\xe7\x87\xe2\x20\x24\x88\x44\x48\x5c\x04\xa3\x6a\x5e\xd0\xa6\xe9\xbb\x80\x04\x24\xd0\xdc\x16\x73\x7b\xfc\xf5\x28\xc0\x42\x02\x22\x18\x72\xe1\x3d\xad\x76\xab\xc5\xd3\xf2\xdb\xe1\x76\xf5\x63\x75\xbf\xd9\x3e\xac\x1e\xf7\xbe\x0d\x25\x14\xcd\x3b\x34\xa3\xf7\x03\xcc\xed\xa7\x5f\x87\x04\x34\x71\xe4\x88\x38\xcf\xb1\xb3\x1e\xca\xb7\x0c\x3e\x0b\x92\x93\x80\xb1\x08\xa1\xd4\xa2\xf5\x3b\x1f\x44\x25\xf3\xab\x78\x7f\xd7\x92\xa6\x1d\x7d\xbe\xf3\xae\x27\x30\x04\x12\xb0\x98\xa0\x39\x73\xbb\xfe\xba\xde\xde\x2f\x96\xab\xdb\x9d\x7f\xaf\x38\xe1\x18\x0b\xfc\x6a\xbb\xda\xc3\x9a\xfd\x30\x99\xf4\x54\xcc\x75\x97\xce\x80\x93\xc8\xf4\x90\xa8\x80\x04\xb1\xb0\x98\xf9\xfb\xf2\xf9\xa9\xb4\x33\xfd\x23\x26\xb7\xc9\x0b\x27\xdc\x72\x8f\xb4\xfb\xe2\x63\x59\x1d\x7d\xd4\x88\x04\xa9\x96\x28\xe0\x62\xb2\x02\x77\xdd\x9b\x73\xa1\x73\x58\x6f\xef\x76\x13\x99\x93\xd1\x3a\x47\x02\xae\xc0\x8a\x5f\x56\x59\xd1\x60\xa5\xcf\x27\x70\xe0\xf1\xc3\x08\x69\x90\x79\x74\x9a\x55\x73\x2b\x9a\x63\xc9\x9f\x1f\xba\x32\x84\x50\x38\x9f\xb5\xd2\x1f\x05\xcf\x49\xa0\xa8\x35\xd4\xde\x5f\x44\x0e\x3f\x45\xd1\x60\x4c\xcb\xfb\xb7\xed\x71\xe5\x95\xb2\x2c\x27\xeb\xf8\x8b\xaa\x38\xf5\x21\xdc\xc1\x33\xad\xf6\xdf\x26\xed\x74\x14\x63\x42\xf9\x41\x34\x0d\xbc\xff\x2c\xa7\x52\xef\x1f\x4c\x40\x4d\x29\x02\xfd\x0b\xfc\x14\xbd\x57\x46\x02\x6d\x84\x76\x72\x33\xeb\x06\x8e\xfb\xb2\xf5\x64\x6f\x41\x36\xb3\xdb\x32\x09\x80\x30\xea\xda\x5b\x53\x70\x5f\x8e\x50\x05\x93\x1b\x43\x92\x52\x33\xf0\x4d\x50\xeb\x76\xb2\xb4\x84\x01\x33\x52\xf9\x5c\x4a\xef\x3c\x0e\xf9\x6d\x49\x18\x98\x00\x5f\x01\x13\x8b\xeb\xa2\xab\xb0\x26\x61\x18\x13\x64\x82\x44\xed\xce\xc3\xc3\x62\xfd\xd8\xe3\x74\x49\x18\x25\x96\x51\x10\xac\xd4\xa2\x5b\xaf\xfe\x13\x39\x4a\x87\x1e\xb9\x49\xc2\x88\x87\x68\x2d\xfc\xb0\x29\x98\x15\x72\x2a\x5e\xc6\x3c\x15\xb3\xfd\x1b\x46\x42\x44\x36\xc9\xf2\x8c\x39\xe2\x01\x57\x5d\x7b\xd0\xca\xfc\x7f\x2b\xdf\xb2\xac\x23\x52\xf6\x07\xa5\xe5\x2c\x39\x5d\x2a\xb7\x3d\x4c\x68\xa5\x48\x48\x98\x42\xf7\xd2\x55\xb9\xa1\xde\x62\x77\x3e\xd1\x29\xae\x63\x87\xa3\xa8\x5e\x9d\xbe\xc2\xec\xa7\x08\x69\xa2\xf1\x53\xd8\xf5\xa0\xcb\x5f\x4c\xed\xdb\xe9\x8b\xce\x2e\xd1\x21\x4b\x2c\x40\x4b\x95\x45\x01\xaa\x99\x97\x6e\xf2\x6d\xd3\xd0\xd1\x20\xee\x4e\x65\x51\x77\xc0\xcf\xbf\x8d\x1c\x38\xd7\x38\x89\xad\xf5\xfb\x9e\x35\xc5\x80\x84\x8b\x84\x09\xb7\xe5\xee\x1d\x45\xcf\x8d\xcd\xda\x74\xc7\xc1\x56\x73\xbb\xe0\x67\x0d\x15\x52\xa7\xe2\xb6\x3c\xc9\x83\xba\x33\x38\x0d\x2d\x5d\xb1\xbb\xa2\x0d\xc0\xcf\x01\xd2\x48\xc8\x05\x84\x43\xa1\xd4\x75\x51\x37\xc3\x66\xff\x89\xfe\x6f\x58\xd3\xd3\x0e\xb0\x1e\x2f\x42\x3a\x50\x7d\xf7\xcf\x41\x78\x9a\x84\x22\x31\x08\x68\xd0\x76\x47\xd1\x67\xd5\x11\x78\x77\xaf\x27\x63\x8d\x15\xfc\xf7\xe5\x73\xeb\xfa\xec\x30\xd5\xf3\xfa\xb9\x2d\x41\x42\xc9\x13\xdc\x09\xcb\x02\x96\x50\x34\x1b\xd3\x91\x96\x92\x50\x85\xd2\x47\x7a\x2d\x22\x37\x2b\x9e\x6f\xce\xfa\xd9\x33\xf1\x91\x50\x45\x71\xe2\x68\xd1\xda\x35\xeb\x09\xea\x32\x7f\x83\x0a\xc9\x3f\xc7\xf7\x51\x69\x8c\x94\xb8\x36\xab\x7f\xb0\x3a\x3d\x22\x3f\xd8\x2d\xba\xbb\x1e\x17\x88\x09\xcd\xb6\xe2\xb2\x6b\x44\x37\xb5\x95\xb0\x58\xda\x1f\x02\xa3\xb1\x1f\x8f\xcd\x8f\xfe\x8e\xbf\x95\x02\xbb\xd9\x4a\x51\xbc\xfe\x9c\xb2\x7c\x8e\x9f\x5b\x87\x1c\x39\x41\x3b\x9c\xe1\x13\x58\x6b\x0a\x6b\x0f\x3d\xca\x70\x1e\x74\x48\x50\x3f\x06\xe3\x3e\xa2\xca\x2f\xbe\xba\x7d\x5d\xbc\x39\x42\x06\x3d\xe9\x24\xa0\x29\x86\x38\x4f\x65\x89\x48\x68\x07\xc2\x1e\x7c\x64\x90\x56\xf5\x09\xb7\x63\x4b\xf4\x3e\xde\xb0\x43\x30\x41\xe2\xd9\x24\xde\xf6\xe5\xcd\xe9\xca\x96\x0b\xc1\x58\x6d\xac\x43\xad\xca\x0a\x46\x05\x26\x24\x34\xd4\x3a\xd0\x02\xc5\xe5\x67\x35\x19\x48\x68\x0c\x27\x2e\xa0\xf4\x50\xbd\xce\xfa\xcf\x24\x0a\x1d\xc8\xef\x35\xcb\x9d\xc5\x4b\xa2\x30\x8e\xb0\x74\x75\x5f\x89\x37\xc8\xfb\xb0\x26\x89\x42\x03\x08\x88\xa8\xcf\xb2\x35\xb2\x7e\xc7\x12\x26\x51\x64\x02\xe5\xe5\xc0\x5f\x44\x51\x80\x95\x01\x1e\x00\x29\xda\x36\x1c\x23\xcd\xf5\x7b\xd6\xa8\x97\x1e\xb2\x42\x22\xc2\xb9\x27\xde\x40\xa3\xa5\xb3\x94\xed\xb2\xd1\xb9\x43\x24\x22\x2a\x46\x17\x50\x89\x5c\x2d\xcb\xba\xa9\x6f\xce\x97\x76\xa7\x1f\xeb\xd1\x76\x80\x8b\x19\xd8\x04\x89\x88\x36\xdc\xf3\x3c\xbe\x64\xa7\x5b\x68\x44\x96\xd7\x43\x88\x3b\x89\x68\x10\x26\xb6\x62\x4f\x3b\x51\xdf\x31\xcd\x32\x89\x58\x48\x52\x67\xdd\x5b\x01\x95\x47\xa4\xc1\xba\x03\xf0\xe3\x61\x8c\xbf\x23\x11\xd3\x0a\xb1\x2e\x18\x14\xc7\x91\xb7\x7b\x29\xcf\xb9\xbe\x01\xe2\x3b\x22\xe6\x34\xb1\x5a\x28\x4e\x32\xb4\x3b\x20\x05\x49\xfa\x3a\x67\x97\x34\x41\xcc\xf5\x67\xb9\x70\x12\x25\x01\x0f\xad\xe4\x32\x68\x57\x47\x7c\x73\xf9\x18\xa3\x40\xa2\xc4\x70\x8c\x51\x6d\x86\xd6\xf6\x07\x17\x4f\x63\x8e\x7e\xe7\xf2\x2c\xcb\x6b\x81\x3c\x12\xf1\x40\x92\x4e\x62\x52\x34\x70\x5f\x62\xd5\xc3\x97\xfe\x30\xa5\x9e\xcb\x71\xb2\xa1\x4e\xee\xc4\x03\x8d\x75\x5a\x2e\x53\xfa\xb5\x12\xd7\x09\xc1\xf9\xd2\x56\x7f\x01\x06\x78\xaf\x4d\xa3\x9e\x3d\xb6\xfd\xb3\x40\xfb\xf4\xfe\x89\xc4\x48\xaa\xa7\x00\x74\x5c\xe5\x73\x84\x08\x24\xe2\xca\x96\xba\x62\x1e\xb8\x5d\x3e\xca\x73\x33\x69\x22\x4c\xe2\xb3\xe2\x96\xb7\xf3\x09\xea\x73\x3e\x4f\xee\x46\x22\xc9\x52\x7c\x7b\xd4\x99\x8e\xbe\x74\xbf\x1a\xa4\x9c\xb6\xfe\x8d\x2b\x07\x9c\x5f\x27\x22\x45\x34\xce\xcf\x02\x51\xe1\xa5\x2f\xe2\x21\x91\x16\xa9\xe1\x1e\xe7\x97\x8b\xcb\xad\xb8\x4c\xc7\x2d\xd0\x94\xf2\x01\xff\xea\xf7\x2a\xdb\x56\x60\xb2\x5f\xc3\x38\x32\x89\x20\x01\xcc\xd3\xb4\xaf\xe4\x4b\xc3\x9c\x5f\xf3\xff\x34\x3d\x21\x4d\xc0\x65\x52\xdb\xbe\xbb\x2b\xab\x6e\x97\xb1\x35\xf3\xdd\xb3\x83\x8c\xad\x74\x5d\x27\xb2\xec\xe8\x42\x26\x1f\xcf\x84\x01\x0d\x3b\x4a\xd2\xa3\x68\x86\x2b\x8a\x09\x43\x57\x62\x8a\x55\x1a\x23\xb9\x10\x12\x19\x19\x70\xa7\xaf\x67\x73\x1e\x4b\x5b\x71\x33\xe9\x22\x63\x48\x90\xfa\x64\xaa\x53\xb6\xff\x98\xe0\xb9\x6d\xcf\xd0\x87\xd8\x9f\x5b\xd3\xa4\x5f\x7c\x49\x10\x72\xac\x66\x78\xbd\xc8\x4e\x3b\xb8\x3b\x26\x28\xa2\xa4\xe5\xf9\x82\x0a\x34\x7f\xc0\xa5\x1e\x7d\x02\x12\x48\x85\x01\x26\x9d\xd5\x58\x83\x7d\x35\x7d\xfb\xf7\x26\x61\x92\xfa\x0d\xec\x50\xf5\x5e\x06\x89\x22\x86\x5b\xdf\xaa\x79\xc1\x29\xf9\x23\x83\xf7\x89\x0b\xd4\x2e\x7e\x98\x32\x40\xb7\xa9\x10\xe7\xa6\xbe\x2f\x9f\x33\xd5\x5d\x22\x66\x88\x1d\x6a\xad\x0f\xd9\x29\x9f\x11\x12\xf1\x94\xc5\x5d\xc1\xe1\xcd\xf9\x32\x60\x1b\x25\x84\x28\x16\xf8\x12\xab\xee\xc9\x87\xc4\xc1\x83\x87\x27\x00\xd4\xd2\x6a\x5f\x56\xcf\x57\x9c\xa2\xae\x11\x8d\x18\x26\x21\x33\x55\x0e\x25\xb0\x08\xa1\x84\xa7\x8e\x43\xdb\xe6\x6e\xde\x51\xeb\xfe\xfd\x5a\xbf\x73\x76\x31\x20\x94\x5a\xc7\x3f\xab\xd7\xc5\x3e\x83\x2a\x9c\x74\x0f\x55\x11\x32\x42\xb9\xfc\xef\xee\x5d\x9c\x06\x7e\x1c\x61\x09\x55\xc2\x13\x27\xf4\x6a\x3c\x93\x69\x47\x58\x6a\x30\x1d\xa1\x44\xdd\x5c\x89\x0f\x13\x12\x2b\x0b\xc4\x77\x85\x62\xb8\xa4\xff\x01\x97\xc9\x45\x12\x1a\xa1\x4f\xbc\xaf\xce\xc7\xd3\x4d\x56\x3c\x7b\x03\x80\x24\x94\x22\xf0\xe6\x24\x2e\x4e\x23\xa5\x3b\x12\xdb\xfc\x5b\x05\x6f\xe5\x2b\x56\x4b\x41\xd1\x64\xea\x5a\x0f\x8c\x90\xc4\x08\xdc\x5d\x30\x58\x32\x82\x2b\x8d\x96\x1f\x92\x4a\x82\x73\xfa\xd8\x57\x6f\xdf\x83\x69\xd6\x85\xe3\x6a\xf3\xb7\xe6\x94\x21\x6f\x59\xeb\x1b\x3d\xc0\x11\xbc\x3a\xc1\x07\xc9\xb5\xeb\xd4\x28\x21\x3c\xb1\x54\x05\xb9\xa8\x5b\xff\xbc\x2e\x73\x7c\xf0\x6d\x35\x00\x6e\xfa\xa6\x4e\x5c\x12\x7c\x26\x72\xb0\x2e\x10\x11\x53\x0c\xbc\x1e\xb3\x62\xff\xcb\x3f\x9f\x00\x3b\x69\xb2\x62\x9f\x9d\x4e\x50\xfd\xe3\x0c\xe7\x0f\xc2\x43\x44\x86\x29\xfa\x52\xf7\x8b\xe1\x04\x57\x41\xe4\xd0\xb9\x16\xe2\x8f\xa4\x9f\x33\x10\x11\x42\x34\x8d\x10\x95\xbd\xcc\xf1\x56\x43\x68\xdd\x87\x99\x61\x42\xb4\x63\x7e\x7b\x86\x66\x51\x81\xb0\x56\xd8\xb8\x05\x70\x70\x12\x88\xbb\xa3\xa8\x3a\x05\xf2\x9b\xcb\x5c\xca\x94\x10\x08\x2c\xd9\xba\x57\x10\x2d\xf4\xed\x35\x49\xc2\x24\x02\x31\x7e\x26\x13\x5b\xcc\x0c\xa6\xbd\xd6\xc5\x1b\x14\x58\x4b\x30\xfa\x18\x34\x08\x00\x01\x1d\x1a\xd1\xe6\x5e\xc3\x94\xd0\x30\xa0\xf8\x42\xdf\x8b\x2c\x2f\x9b\xbd\xc8\x72\x1b\xac\x99\xed\x74\x1a\xf2\x00\xbb\xf7\x6c\x95\x3c\x1f\x26\xb3\x86\x86\x3a\x0e\xd3\x2b\x98\xce\xcd\x3c\x4c\x87\xd0\x48\x0b\xea\x49\xc5\x6e\xe0\x52\x7a\x7c\x24\xa1\x04\x62\xab\xd7\x27\x1a\xb8\xcb\x0a\x91\x23\x56\x34\xec\x0e\x9b\x50\x04\x1d\x8a\x10\xa3\xa8\xad\x7f\xf3\x00\xad\xe7\x51\x4c\x55\x33\xdc\x49\x94\x58\xfa\xbf\xa3\x45\x76\xdc\x82\x5f\x51\x29\x4d\x09\x4e\xf6\x87\xf5\xe3\x61\xb7\xb8\x5f\x1d\x16\x0f\x9b\xef\x5d\x84\x94\x52\xae\x31\x65\xbc\x2f\xcf\x55\x4f\x03\x48\x28\x0b\x29\xd8\x0a\xfd\x63\x56\x2c\x5f\x44\xf5\x0c\x87\x13\xe9\x8e\xa6\x86\x41\x4f\x42\xb4\xaf\x00\x86\x64\x79\x84\x32\x45\x31\xc2\x7f\x5f\x3e\xe3\xef\xb6\xe2\x66\xfc\xcc\x71\x90\xb8\xe8\xa1\x29\x0f\xd8\x6a\x63\xc6\xe9\x5a\x42\xe3\x48\xc7\xd2\xfb\x4a\x68\x37\x0d\x62\xc4\x34\x8e\x0c\xc2\xd0\x1f\x97\x5b\x5c\x18\x46\x38\x25\x42\x63\xad\x14\x1b\x8b\x8b\xb6\x1b\xbd\xdb\xa7\x4d\x59\x5d\xd5\x1e\x8c\xb7\x01\x9a\x68\x86\xb9\xcc\xad\xa8\x84\xce\x8e\x10\x74\x1f\x29\xa5\x54\x0c\xa1\x8d\xa3\x88\x2a\x4d\x93\xd4\x58\x04\xd2\x29\xbf\x5c\xb9\x3f\xb3\x66\x16\x4d\x53\x83\x91\x77\xa1\x1a\xac\x23\x9f\xb5\x0f\x69\x2a\x14\x67\x2e\x6b\x34\x2e\x19\xe9\x4b\xc2\x08\xe5\x81\xc2\xfc\x3e\xb4\x2e\xeb\xee\xac\x14\xd4\x36\x90\xd2\x37\xb0\x12\x14\xab\xed\x53\xf7\x53\x92\xa0\x66\xc3\x93\x53\x6c\x6f\x37\x84\x31\x4a\x91\x50\xce\x2d\x71\x62\xfd\x52\xbe\xcf\x55\xd1\xfa\x66\x82\x10\xcf\xba\xff\x92\x55\xfa\xba\x5a\x81\x50\xae\x34\xca\x1d\xed\xa1\x6e\x06\x8b\x1c\xe5\x60\x41\x83\x3e\x04\xd3\x5c\xfb\x06\x54\x44\x06\x29\x99\x7e\xee\x41\xbd\x0c\xfc\x4f\x2a\x03\x2b\x0c\xf5\x0c\xcd\x0f\xa8\xb0\x5e\x64\x2e\x01\x31\x9e\xa8\x2a\x8a\x03\xee\x4d\xee\x9b\x46\x39\x56\xbe\x5e\x33\x6f\x28\xc7\x7f\xbe\xc2\x1d\x12\xaa\x99\x50\xb2\x47\xf9\xdf\xec\xf6\x43\xe4\x4a\x7b\x5c\x81\xa5\x2d\x92\x43\x59\x27\x42\xb5\x36\xa1\xb5\x1f\x91\xa0\x74\x88\x07\xbb\xb5\x13\x6b\xd2\x69\x10\x30\x8c\x81\x1e\x9e\xcb\xdc\x11\xff\x4c\xba\x06\xa2\x98\x7a\x55\xed\xb3\xea\x1e\x01\x88\x41\xb3\xc3\x64\x45\x56\xbf\x6c\x7f\x6c\xbb\x03\x32\x44\x08\x24\x0a\x05\xdd\x5c\x89\xf4\x13\x6a\x62\x81\x68\xbc\xfb\xf2\x19\x3d\x27\xc4\xa6\xc2\xbc\xec\x20\x61\x41\x18\x60\x86\x69\x50\xd2\xe4\xb2\x9f\xee\x86\x2c\x0c\x53\x7c\x67\x97\x88\x5d\x20\xbc\xcb\xe2\x74\x7c\x0b\x16\x45\x2e\x5b\x81\xcb\xf5\xb6\x2a\x15\x80\xae\xbd\x4e\xa0\x6f\x26\x34\xbe\xd2\x5d\x05\x79\x3e\x14\x6d\x21\x58\xc8\x32\xd0\x1e\xbe\xf1\xa4\x07\xdd\x71\x69\xd9\x12\xb3\xfa\x11\xde\xb1\xc0\xc3\x1f\x21\x09\x41\x1a\x1a\xe9\x2d\x71\x6b\xfd\x6d\x3c\x07\x22\x61\x44\x44\xb8\xe4\xd8\xf8\x2e\x32\x19\x0d\x47\x13\x23\x10\xa2\x79\x5e\xe5\xea\xd0\x80\x38\xfa\xf3\x68\xa2\x89\xf1\x3c\x3e\x65\xe9\x33\xd3\x84\x31\x1a\x58\x45\x37\x78\xff\x37\x9c\x6b\x97\x07\xc3\x2a\xb3\xd1\x85\x59\xcc\x90\x68\x1a\x7c\x68\x79\xdc\xf3\x0c\x20\xb2\xea\x3d\x97\x53\x53\xee\x0a\x10\xaf\x50\x0d\xca\x2b\x08\x4b\x12\x0e\x66\x04\x48\xee\x25\x10\x46\xc3\x8c\x25\x92\x63\xff\x0c\x95\x21\x3e\x2d\x05\x20\x2c\xa5\x1c\x4b\x33\x1c\x50\x77\xe4\x51\x4e\x9b\xc6\x09\xce\xde\x9b\xc5\xf2\x8f\xef\xdb\xc3\xdd\xe6\xbb\x5f\x83\x58\xaa\xac\x55\xf5\x0c\xcd\x9d\x38\x2b\x68\x6e\x2e\x58\x4f\xde\x0f\x0e\xce\xb9\x70\x06\xb0\xa8\x9e\x0f\xe4\x90\x15\xa7\x73\xf7\x61\x05\xb7\x15\x75\x35\x34\xf7\x8b\xc7\x5b\x57\xbc\x7b\x99\xbc\x9e\x8c\x12\x84\x90\xde\x64\xcd\xfa\x28\x1c\x35\xf7\x20\xa6\xc4\x24\xb5\x08\x09\xdc\xfb\x5a\x4f\xaa\xf1\x95\xb9\xbe\x81\x09\x02\x07\x66\xfb\x61\xb3\x18\x98\x98\x1d\x2d\xe8\x4c\xc5\x56\xd0\xad\xc6\x71\xec\x97\xf3\xf1\xa3\xe8\xd0\x2a\x20\xe2\xfc\xff\x59\x56\xaf\x7f\xd1\xcd\x9a\x18\x94\xe8\x7f\x12\xc5\xab\xd5\xb6\xcf\x3b\xb9\x83\xe9\xa5\x5d\x69\xfe\x6b\x96\xa3\x6c\x87\x2d\x35\xf1\x9c\x12\x84\x69\x1e\xe1\x47\x7e\xba\xdd\xb6\xc3\xad\xff\x5d\x45\x98\x7b\x3a\xc8\x70\xc2\xc7\x3f\x5a\x36\x19\xd0\x20\xec\x08\xd1\xa6\xa1\x83\xe1\xfa\xc8\x4c\x44\x10\xb9\x77\x74\x7a\x98\x58\xa4\xd5\x0b\x87\x92\x38\x08\x01\xf7\xe9\x0e\x8b\x35\xd2\xa5\xbd\x72\x85\xfd\x59\x4a\x63\x99\xe1\x57\xe8\xec\xd0\x81\xbc\x8b\x6b\x14\x12\x2b\x3e\xd3\x6e\x45\x17\x8b\xc0\xaf\x9d\x30\xd7\xa8\xbb\xe2\x90\x58\xa0\x50\x6b\xdd\xf9\x04\x62\x59\xb9\x75\x63\xe8\x46\x4e\x9e\x22\x24\xda\x2a\xdb\xda\x71\x7a\x07\x30\x5e\xf0\xe2\x88\x11\xc1\x87\x82\x32\x77\x65\xc7\xc3\xb0\xcc\x45\xf1\x2e\x3e\x48\x4a\xc6\x24\x8e\xa2\xa0\xe7\x7f\xd9\x97\xab\xc9\xd4\x9f\xb4\xa7\x4c\x09\xd1\xe1\x9e\x6f\x3b\xb5\x76\x12\x53\xa7\x95\x6a\x83\x69\x55\x07\x51\x98\x9c\x6f\x12\xcf\x01\xba\xa8\x24\xf6\xe5\xb8\x01\x8b\x2c\xf6\xfa\xa7\xa8\x4e\xbb\x13\x74\xa1\x8e\x98\x71\x5b\x0e\x79\x76\x35\x36\xb6\x9f\x3d\xaf\xd5\xa4\xa7\x99\x52\x58\xb0\xb3\x5c\x7e\x3b\x3c\xac\x1e\x17\x07\x6f\x54\xc5\x31\x51\x16\x4e\xd8\x65\x70\x17\xeb\xe5\x47\xc6\x59\x1c\x27\xc6\xcb\xcd\x5e\xa9\xcb\x7f\xa0\x3c\x46\xe2\x58\x07\x48\x03\xeb\xb4\x07\xca\x42\xe4\xab\x5f\x27\x28\x6a\xa8\x87\x7a\x6d\x24\x8e\x0d\xb1\x55\xbf\xad\x31\x54\xbf\xdc\x95\x2e\x20\x1d\x8e\x41\xd0\x24\x4e\x1c\x54\xe0\x94\x0b\x05\x8b\xa2\x7e\x1f\x38\x18\xa3\xa1\x98\x2a\xc5\x98\x0f\x59\xaa\x57\x1f\x8b\x8b\x39\x8d\x64\x3c\x48\x95\xa3\xde\x28\xd2\x20\xf8\x16\x82\x68\xb4\x89\x5c\x50\xe0\xab\x38\xc2\xba\xeb\x7b\x21\x14\x38\xb7\x04\x69\xcb\xb3\xe7\xc2\x95\x25\x4d\xb6\xf2\x58\x6a\x8e\x21\xd5\x1d\x34\x0b\x34\x09\xcb\xea\x62\x3d\x99\xa2\xb9\x8a\xfc\xc7\x2a\xd4\xf8\xb1\x77\xe2\x78\xca\x61\xf5\xb4\x8c\xc8\x6c\x75\x9d\x6f\x1e\xc5\xe8\x1a\x3e\x64\x45\xf6\x00\xeb\xaa\x82\xb7\x52\xb5\x36\xe9\x0f\x94\x67\x9b\xd7\x37\x99\xb8\xe6\x23\xd7\xb4\xf7\xa7\x63\x15\x01\x15\x0e\x0d\xb7\x3a\x8a\x2c\x9f\xc2\x30\xe6\x5c\xc7\x58\xa5\x16\x64\xf4\xdf\x73\x75\xd9\xb5\x1e\xbc\xff\x9d\x5b\x06\x7d\xaf\x2e\x7e\x77\x2e\xc6\x1a\x60\x24\x56\x32\x21\xb1\xcf\x67\xc3\xf7\x2a\x8b\xc6\xab\x8a\x32\xca\x95\x05\x6a\x31\x66\x79\x24\xb1\x4e\x2d\xad\x43\x56\x3b\x74\xd3\x20\x9b\x41\xa6\x83\x47\xf3\xc4\xa1\xcf\xfb\x58\x8e\x5f\x3f\xe6\x27\xb9\x96\x16\x5c\xf7\x0c\x4d\x47\x9a\x5f\x0f\x85\x4c\xff\x13\xfa\x4c\x77\xac\xb5\x0d\xd0\x1e\xc5\x2f\x0f\x85\xe8\x8b\xd3\x49\x0c\x41\x2a\x95\x93\x72\xc4\xc3\xf3\xcb\x02\x44\x96\x65\x40\x9e\x2f\x77\x65\xd5\x6e\x52\x96\xa4\xed\x83\xd4\xf1\xb4\xbe\x7e\x36\x28\x1f\x03\x31\xb1\xe8\x78\x6a\x55\x0e\xd7\xe9\xc6\x24\x20\x29\x42\xa5\x6f\x5a\x7f\xf5\x5f\x87\xed\xea\x69\xd9\x43\x7b\x92\x40\x04\x18\x5a\x6e\x5e\x40\x8a\xe2\xb5\xfb\x19\x08\x1a\xb4\x9b\x3f\x2b\xe8\xe0\x28\x49\x98\xb2\x98\x0f\xa5\x4c\x71\x25\xde\x35\xa2\x19\x87\x41\x93\x30\x4d\xc4\x30\xff\x8c\x9e\x77\x7d\x05\x07\xf9\xdb\xf8\x24\x2e\x31\xef\x91\x7f\xc2\xcd\xe8\x9b\x82\x05\x24\x39\x62\xe1\x3f\xb3\x3c\xef\x90\x6f\x24\x89\xb8\xdd\xad\x5a\xeb\xfd\xfe\x87\x25\x2b\xe7\xdd\x41\xc1\x95\xe3\xcc\xf3\xf4\xc5\xa3\x3e\x4d\x22\x15\xa2\xd9\x6b\x6d\xd6\x4c\xe1\x83\x38\x94\xc3\x6f\x25\x3c\x46\x68\x72\x92\x10\x6a\x03\xff\x36\xbc\x7d\x5d\xad\x42\x12\x92\x0a\xaa\x46\x0b\x76\x3b\xd8\x75\x5f\x54\x33\x62\x1d\xba\x5a\x9d\x27\x7d\x43\x39\xc1\xdc\xff\xb6\xac\x86\x5a\x36\x24\xa1\x00\x38\x10\x5e\xb2\xff\x0e\x84\x0f\x26\x67\x33\x61\xf5\x5a\x6d\x4a\xe3\x3e\x93\x95\xa8\x2e\xed\xe7\xbb\xb3\x79\x9f\x2f\x9f\x84\x65\x13\x66\x42\xb4\x25\xd6\x55\x59\x7c\x13\x85\x1e\x1a\xce\x49\x2c\x02\xa2\x3b\x5a\x7d\x93\x35\x9b\xea\xbe\xbc\xce\x9a\xcd\x9b\x6c\x49\x12\x18\x6e\x75\x90\x30\x8f\x95\xf7\xcb\x4c\x92\x30\x86\x99\x42\xab\x4f\xb1\xa9\xda\xa5\x7f\x89\xf8\xee\x01\xce\x2e\xf5\x8d\xb9\x42\xac\x37\xb6\xf5\x8b\xc5\xa7\xf9\xb8\x24\x31\x56\x8a\xd8\xf9\x41\x58\x26\xf6\x06\xf5\x44\x27\x90\x24\x3c\x08\xb0\x4e\x6b\xf5\xeb\x25\x93\xd9\xf0\x03\x73\x0e\xc8\xd3\x66\xaa\xf2\x4f\x28\xf6\x97\xb1\x48\x34\x49\x44\x60\xab\xf8\x7d\x18\xa4\x35\xef\x9c\xff\x3c\x99\xcc\x82\x47\xd4\x86\x52\xfc\x4a\x99\x08\x03\x18\x71\x00\x51\x37\x42\xd7\x0a\x61\x2d\xb5\x0f\x98\x26\x92\x2b\xa4\x68\x78\x2c\x9b\xbb\xf2\x58\x92\xdb\xee\x80\xb1\xb1\x2e\x4b\x3b\xd6\xe3\x3f\xd0\x19\x9b\xc5\x33\x25\x4a\x38\x6a\xb4\x76\x45\x87\x06\x2b\xd6\x42\x32\x79\x44\x2d\x2d\xfb\x2e\xf6\x70\xbb\x97\xce\x98\xd5\x89\x36\x44\xc6\x23\x2f\x0a\xf9\x1f\xf3\x2b\x60\x66\x62\x18\x41\x80\xaf\x7d\xcc\xdd\xe5\x28\xcb\x7c\xdc\x7b\x26\xa1\xc8\x9f\x76\x18\xb2\x81\x1e\xe4\x65\x5b\x95\xbf\xae\xc3\x46\xb3\xe0\x5b\x7f\x25\x65\xc3\x64\x07\xa7\xc9\x86\x74\x34\xc8\x17\xdb\x6f\x12\x61\x7c\x08\xd3\x43\x14\x4d\xde\xda\x68\x2b\x1a\x8f\xd4\x22\x56\x35\xd5\x75\x74\x1a\xa4\x11\x02\x03\xbf\xff\xf1\x15\x6b\x12\xfc\xef\x61\xc8\x18\xe9\x55\x88\x33\x93\x61\x59\xd5\xac\x0f\xe0\x3f\x41\x1a\x12\x61\xdc\xc6\x75\x9c\x78\x64\x69\x48\x63\x3b\x38\x9e\x56\x36\x46\x89\x85\xdc\x03\x61\x76\x92\x86\x1c\x52\xe6\x37\xab\x46\xe4\x1d\x18\x77\x72\xa9\x28\x52\x5a\xf4\x3c\xef\x2f\x65\xd5\xac\xf5\xd8\x33\x4b\x29\x65\xcc\xd5\x3d\x6c\xc5\x05\xe0\x63\x4d\x21\x92\x52\x16\x25\x9d\xda\x79\xeb\x0b\x76\xc1\x82\x94\xc6\x81\x25\xdc\xa8\x04\x34\xe0\x88\x49\xd0\xf3\x9d\xcf\x44\xa7\x34\x21\xd4\x42\xa4\x5c\x2a\x10\xf4\xae\x11\xea\xf5\x05\x95\x8d\xc6\xdf\x25\x65\x81\x96\xa4\xdb\xe8\x9b\x4c\x65\x27\x51\x34\x37\x97\xb5\x9e\x36\xa4\xa9\x5b\xa6\x15\xbc\x81\x5e\x35\x2f\xed\x30\x5a\xbd\x09\x59\x7e\x00\x12\x4b\x59\x4c\x91\xdc\x4d\xd4\x35\x3c\x17\xe2\xa0\xb3\x2a\x6b\x9a\xf2\xa0\xb3\xc3\x5b\xd9\x94\x93\x2e\x65\x49\x14\x83\x33\x23\xd6\xdb\x91\xb5\x93\xc6\x8c\x21\x0a\x67\x79\xbf\xd9\x8d\xb5\xf4\x49\x1a\xcb\x04\xfd\x3e\xdd\xec\xa1\x6e\x3e\x16\x2e\x21\x69\x42\x2c\x55\x70\xe9\x38\x03\x27\x85\x89\x3e\xdb\xeb\x5b\xd3\xd0\x03\x46\x5c\xc5\xee\x84\x9b\x95\xa4\x89\x88\x10\xf5\x64\x3a\x26\x2c\x7f\x24\x0d\x43\x44\x81\xbc\x08\xaf\xda\xdd\xb9\x31\x69\x9a\xd2\xc8\xe5\x6d\x1a\x27\x51\x3d\x17\x31\x4c\x79\x44\xb9\xb3\xd8\x0b\xb8\x44\xf7\x70\x2c\x07\x49\xba\x54\x44\x29\x77\xb6\x8d\x17\xbc\xbe\x76\xa6\x52\x41\x9c\x6c\x70\x57\x99\x32\x47\x94\x44\x52\x91\x52\xf4\xad\x0a\x1f\xaa\xfa\x5d\xb8\xd4\x6c\x84\x2e\x15\xa9\xb2\x4e\x5e\xf6\x06\xe2\x5d\x5c\xc6\x89\xe2\x54\x72\x9b\xe4\xb0\xd3\xc7\x13\x76\x63\x30\xf5\x32\x9d\xe0\xdd\x1c\x51\x3c\xc4\x52\x77\x4b\xcb\xe6\xf5\x9a\x47\x6b\x5d\xaa\xc3\x08\x43\xd2\x8b\xa2\x28\xcf\x85\x82\xbe\x86\x92\xa4\xda\xc4\x26\xf2\x0b\x2f\xe8\x6d\x85\x20\xe5\xef\x45\x1f\xad\x48\xb5\x51\xc8\xe9\xa4\x06\x56\x88\x15\x45\xee\x3f\x1f\x04\x09\x73\xe9\xf8\xcc\xcb\xf9\xb4\xbf\x1a\x44\x94\x36\x25\xfa\x47\xdd\x15\x21\x15\x08\xeb\xb2\x05\xa6\xab\xff\x85\xdc\x39\x78\xfc\x6f\xa3\xbf\xdd\xaa\x01\x02\x10\x68\xff\xef\xf3\xc9\x6f\x0d\xee\x88\x61\x9c\x27\x23\x30\xca\xc0\xdf\x48\x8d\xe4\xa9\x33\xb3\x97\xa2\xf2\xc8\x3f\xeb\xca\xf5\x95\x7c\xfe\x36\x3c\x08\xa4\x76\x42\x25\x59\x85\xe1\xb7\x7e\x3f\xe6\x51\x94\xa0\x0c\x96\x8d\xf2\xfd\x5c\x0e\x88\x4b\x86\x06\xdc\xbc\xd1\xcd\x69\x90\x20\x0e\x5c\x95\xc7\x63\xd6\x34\x00\xf5\x90\xa0\x85\x70\x1a\x8a\xc4\xf1\x0e\xaf\x8b\xb7\xac\x81\xe9\x5a\xc3\x69\x62\xd5\x9a\x1f\xd6\x8f\x87\x9b\xd5\xfe\xf0\x63\x71\xff\x7d\xd5\x9d\x0e\xd4\x83\xa3\xac\x7d\xbd\x2d\xeb\xac\x97\x21\x19\xce\x61\xce\x28\xc3\x5b\xb5\x86\xc3\x6d\x25\xde\x5b\x8f\xd8\x5f\x87\x69\x89\x92\x10\x6e\x09\x77\x4c\x37\xbf\x6d\xc1\x8e\x9f\x38\x51\x96\x29\x13\x4d\xd4\x60\x7e\x3d\xe4\x9c\x6a\x44\xda\x23\xc7\xf0\xed\xdf\x77\x33\x80\x24\xce\x79\x40\x9d\x1b\x74\x2f\x0a\xdd\x15\xfd\x4c\x5b\x59\xc6\xd9\x53\x3b\x86\x2b\xb8\xcf\xfe\x77\xce\x34\x96\x15\x0f\xa7\x19\x17\x86\x5b\x12\xd6\x9e\x31\xf2\x76\x3a\x65\xb8\xe4\x96\x94\x39\x53\x25\x66\x5b\xd5\x38\x37\xc6\x55\x60\x79\x03\x5c\x7c\xc8\x07\x14\x38\x44\xd2\xc8\x0e\x2b\xb1\x7c\x11\x59\x01\x7a\xe9\x6b\x78\xc6\xcf\x6b\x92\x40\xbb\xe8\xc1\xc6\x87\x44\xac\xd4\xcb\xf0\x6b\x19\x43\x11\x0a\xb0\xb8\xfd\xb1\xde\x6d\x9e\x76\x87\x9f\x8b\xfb\xfb\x95\x77\xc5\xb8\x31\xd2\x8a\x9c\x62\xc6\xf2\xc9\xda\x10\x93\xfb\x18\x83\xec\x7d\x1e\xa9\x69\x73\xea\xf6\xa0\x08\x42\x13\xf7\x8b\xce\xcf\xec\xcf\x3f\xb7\xa2\xd0\x9d\x3b\x38\x00\xd9\x8e\x07\xb4\x08\x22\x82\xb0\xc0\xd5\xf7\xdd\xcd\x70\x46\x8a\x80\xca\x80\x39\xb6\x9c\xe1\x9b\x88\x20\xb6\xc9\x9e\x03\xea\x00\x1d\x9d\xea\xe0\x28\xa9\x3c\x1e\x1b\x22\x54\x2c\x74\xa3\xba\x2f\x22\xb4\x05\x41\x96\xf8\xc0\xb5\x23\x32\xc1\x76\x4d\x59\xd7\xeb\xa2\x29\xf7\x2f\x70\x97\x55\xdd\x61\x1a\xa4\x58\x14\xd6\x9a\x59\xdf\x44\xbd\x15\xed\xae\x34\x31\x5e\x04\x65\x14\xd7\xa4\xdd\x59\xda\x3a\x8e\xeb\x02\x4b\x22\x68\x22\xb1\x18\xb1\x28\x8f\x59\xd1\x6e\x5f\xc3\xc4\xab\xa0\x2a\x15\x16\x9c\x99\x3d\x3f\x1f\xb3\x02\x46\x12\x36\xed\x71\x01\xe0\xab\x9a\xfe\x5b\x56\xed\x90\xaf\x5b\x03\x64\xf2\x28\x2c\xb0\xd5\x14\x42\x6b\xd4\x96\x9e\xce\xb2\xf9\x2a\xdd\xd1\x8a\x29\x18\x44\x9a\xbb\xf2\x2a\x4c\x1e\xd5\xa3\x3c\x8c\x60\x10\x23\x98\x66\xd9\x2e\x74\xf5\x8c\xb5\x2d\x62\x12\xe3\x62\xe8\x4c\xfd\x51\xdd\xf3\x9c\x2b\x2e\x62\x88\x70\x9c\x3d\x88\xa2\x11\xa7\xff\x76\xe8\x63\x91\x10\x13\x43\xa7\x64\x7d\x3e\x4e\x6e\x94\x4a\x12\xb8\x25\x7c\x83\x34\x92\x3d\xf8\x5e\x70\x2a\xb0\xa8\xc3\x1b\xd7\x48\xbd\x00\xed\x3e\x35\xf3\x38\xfe\x9c\x98\xa7\xd6\xeb\xf3\x5c\xf4\x77\xe5\x07\xc0\x03\xc1\x93\xd4\x7b\xfd\xf6\x92\x76\xff\x09\xfc\x61\xa3\xd0\x00\x58\xdd\xff\x18\x8d\x71\x41\x6c\x0e\xfe\x19\x9a\xef\xeb\xe2\x03\x94\xaf\x10\x89\x56\x2e\xf4\x6b\x29\x4f\xaf\xa0\xc4\x42\x88\x18\x53\x53\xaa\xcc\xdb\xfd\x7e\x18\x9c\x14\x42\x06\x3c\x75\xa6\x72\xfb\x6c\x77\x70\x4d\xbd\x3b\x6f\x79\x74\x17\xa0\x96\xc1\xe5\x7c\x59\xf7\x8f\x0e\x06\xdd\xca\x77\xc8\xf6\xe5\x5c\xac\x52\x08\x93\x60\x2d\x99\x67\x91\xee\x01\xf3\xce\xec\x9f\xe3\x39\x27\x42\x9a\xc4\x74\x8c\x6c\xfb\x4a\xe8\x21\x1f\x1b\x11\x8a\xc4\x78\xf8\xb6\x2a\x4f\x43\x8d\x21\x22\x94\xb0\x21\xc6\xa7\xc5\xe3\xd7\x95\xf5\x3e\x68\x77\x4c\x46\xd8\x3f\x36\xba\x8d\xdd\xb0\x1c\x56\x77\x08\xad\xc0\x07\xce\xaf\xb9\x37\x89\x80\x54\x23\xa6\xed\x58\xea\xcc\x5c\x0e\x6e\x42\x86\xfd\xaa\x3f\x7e\x07\xc3\x74\x68\xdd\x50\x54\x8f\x18\x87\x26\x85\xd1\x82\x07\x3d\xc5\xa3\xb2\xba\xff\x1f\xc2\x05\x65\x20\x63\x4c\x22\x78\xf6\xf1\x9b\x4c\x87\xf3\x4e\xb2\x0c\x99\x21\xee\x35\x90\x76\xa3\x39\x68\x87\x6f\x9e\xb4\x93\x94\xa3\xb6\xd7\xf9\x28\xfc\x27\x95\x11\xe1\xca\xa1\x8c\xb7\xe5\xcf\xc6\xcc\xe3\xc9\x65\xa4\x35\xa2\x62\x7e\x7e\x5d\x0e\x07\xb3\x24\x69\x04\xa2\x63\x47\xce\x2f\x58\x95\xe3\x0f\xb2\x20\x64\xde\x82\x42\xfe\x39\xe7\x83\x8c\x2f\xcd\x48\xe0\xa1\x22\xdf\x0b\x2c\xd7\x47\x05\x91\x6c\x1a\xd0\x94\x8c\xda\x89\x33\x8c\xf1\x95\xe7\xe6\x16\x54\x76\x1c\x68\x8d\xfc\x6d\x72\x96\xa4\x08\x6e\x6c\x17\x33\x7a\x5f\xaa\xd7\x11\x39\x1d\x91\x31\x95\x81\x83\xd3\x3f\x9e\x8f\x0e\x89\xe2\x78\xda\xe6\xb3\xe5\x32\x36\xb6\xbe\x19\x8b\x59\x51\x33\x1e\x63\xd2\x67\x91\xff\x84\x6c\x92\x7a\x1a\x9f\x99\x08\x86\x9f\x40\xf7\xac\x58\xa3\xf4\x85\x4c\x64\x64\x79\xf3\x31\x85\x0e\xe7\x63\x6e\xdd\xa0\x47\x68\x86\x33\x42\xa6\x31\xa1\xd7\x14\x5d\xa8\xf8\xec\x2f\x95\x42\x84\x75\x1b\x0e\x17\xa5\x27\x10\x1d\xc9\x03\xc9\x1c\x73\x99\x7d\x86\xb9\x10\xbd\x6f\x4b\x08\x66\x56\x0f\xed\x5a\x57\xee\x26\x5f\x50\x84\x21\xb2\xab\x65\xaa\xb4\x57\x1a\x8f\x7d\x29\xa4\x30\xd6\xb8\x2a\x15\xd4\xf5\xae\x81\x3c\x17\xd5\x68\x22\x4b\xa1\x03\x69\x99\x63\x6b\xf5\x32\x00\x96\x48\x19\x81\x74\x10\x58\xab\x33\x30\x5d\xb5\xe6\x27\x85\x0a\x29\x56\xc7\xe4\xa2\x6e\xfe\xc8\xd4\x6b\x69\x4c\x3b\x67\x6f\xce\x78\x8d\xae\x91\xf2\x0c\xf4\x7f\x2f\x65\x6f\x3f\xf5\x1f\x4c\x85\x1a\x3f\xd8\xe6\x71\xbf\xd9\xfe\x95\x84\x02\x91\x8a\x24\x18\x72\xdc\xad\xf7\x93\x3e\x52\x09\xe1\x9e\x07\xf0\x80\x3a\xbe\xdd\x43\x24\x3a\x8e\x3a\xe2\x85\xd6\x15\xfb\x89\xd8\xd4\xe6\x5c\x75\x9d\xa0\x09\x43\x8c\x1b\xd6\xb2\xf4\x79\xef\x8f\xba\x62\x7c\x6b\x9d\x30\xac\x05\x39\x1c\x3c\x9c\x7b\x6e\x76\xe9\x54\x6a\xe9\x28\x6f\x31\x10\x68\x69\x9e\x84\x2f\x86\xed\x7a\x16\x64\x68\x52\x9f\x40\xfe\x26\x72\x73\x9f\x99\xee\x65\x8c\x26\xda\x25\xf7\x30\x12\x07\xa2\x5a\xe0\x67\xfe\x34\xd8\xaa\x02\x9a\x62\x8c\x7c\xbf\x1e\x2d\x2f\x2a\x88\xad\x4c\x1c\xa6\xd5\xac\x24\xc2\xb8\x5f\x55\xc8\x29\xc6\xba\x9c\xe8\x93\x2a\xff\xff\x95\x25\xa9\x50\x12\x44\xc0\x3e\x94\xe5\x5f\x7e\x66\x15\xd1\x00\x59\xe6\x56\xa2\xbe\x3c\x64\x85\x45\x22\x8c\x26\xb2\x8a\xd2\x28\x35\x8e\xef\x4a\xe4\xce\xbd\xec\xc4\x8c\xba\x56\x90\x22\x7b\xe0\x9d\x50\x20\xcb\xf2\x75\x10\xbe\x56\x84\x86\x38\xf4\x24\x5c\xcb\xf4\xfd\x96\x0f\xa5\x48\x12\x21\x99\x84\x8d\x02\xdf\x8a\x4b\x7d\xd7\xee\xc8\xbd\xc4\x30\x51\x44\xb0\xc4\xd2\x72\x29\x91\xab\xbb\x5c\x3c\xd7\xdd\x21\xa5\xb0\x47\x9e\xa0\x3e\x1f\xa1\xa3\xee\xe9\x69\x7b\x88\x22\x06\xd0\x5a\x7a\x11\xf5\x7a\xb9\x41\x16\x38\x3f\xa1\x15\x15\x60\x3d\xff\xaa\x7c\x47\x82\xc0\xbc\x9c\xc8\x79\x11\xc5\x28\xc7\xa0\xdf\x3d\x1c\xa7\x74\x60\x44\xc5\xd4\xd6\x9d\x9e\x00\x5e\x2d\xe8\xd6\x1f\x88\xad\xda\xe2\xbf\x56\xab\xd1\x60\x49\xc2\x34\x56\xbe\xd8\xc6\xf2\xf8\xe0\xa8\xe8\xfd\x70\x95\xa4\x16\xfc\x60\x5d\xac\x03\x16\x57\x1c\x86\x39\x5b\x95\x92\x34\xed\x95\xc6\x1f\xa0\x11\x7a\x90\xe1\x1a\x0f\x83\x94\xb2\xc8\xa5\x1b\xd1\xd1\x5b\x18\x93\xe5\xd9\x90\x89\x62\x3c\xc6\xd2\x58\x61\xdc\xf8\xfb\x5b\xb9\xec\xd8\x0c\x88\xe2\x29\x45\x3b\xe5\x54\xb5\xe3\xb7\x3d\x02\x7a\xd3\x81\x63\x94\x08\x2d\xa1\xee\xd7\xcd\xfd\xed\x61\xbf\x39\x2c\x37\xf7\xf7\xab\xe5\xfe\x10\xee\x7e\x6e\x9e\x6e\xbb\x56\x90\xc8\x74\x9c\x83\xb7\x20\x49\xcc\x1e\x78\x67\x62\x26\x5e\x3a\xb5\x3c\x94\x30\x0c\x7d\xdc\xae\xea\x6e\x07\xcd\x63\x69\x99\x82\xdb\xd5\xe0\xb1\x6c\x86\x9e\x8b\x92\x51\x8c\x35\x0a\xa7\x0a\x54\x56\x83\xdb\x8e\xf7\xa5\xfb\xc7\xe4\x93\x4b\x4a\x02\x57\x72\x5c\xe6\xba\xb9\xf6\x1d\x94\x8a\x0c\xca\x0e\x9d\x0b\x8b\x94\xf3\xf8\xb1\x49\x2b\x02\x18\xdf\xad\x2f\xf5\xb0\xa4\x40\x41\x60\xf9\x8f\xbe\xef\x16\xc3\xc9\x04\x89\xa3\x61\xed\x43\xb2\x03\x91\x56\xa2\x80\xdb\x2a\x58\x8c\xfd\x19\xb8\x42\xd5\x2b\x10\x21\xeb\x10\x3f\x6d\x37\x60\x1f\x0c\x84\x9b\x7c\x3b\x00\x1c\x84\x99\xea\x75\xb3\x88\x32\x54\x47\x16\x6a\xa8\xe1\x57\xfd\x52\xbe\x4f\xde\xc6\xb0\x50\xaa\x0e\x02\xb2\xeb\x63\x6c\xca\x68\xab\xa7\x5c\x43\xf3\x50\x16\xcd\x4b\x7e\x99\x59\xbc\x75\x60\x22\xc4\x28\xec\xf6\x2b\x0f\x11\xd4\x21\x8d\x44\x32\xa8\xe1\xe9\x62\x99\x61\x3c\xcd\xf1\x9e\xfb\x62\xb7\xfe\x9a\x04\x52\x0c\x63\x08\x59\x56\x4d\xbf\x64\x68\x02\x3a\xb6\x2c\x3f\x37\x65\xb3\x18\x5b\x3a\xbe\x54\x4e\x13\x00\x74\x57\x4f\x98\x78\xf3\x90\xbc\x01\xbe\x46\xd3\x90\xb8\xf0\xf7\xb1\x7c\xc3\x0e\x9f\x35\xb6\x34\xe3\x01\x76\x4d\x5d\x9a\xe6\x7b\x61\xe9\xb7\xc6\x86\xad\x8e\xb9\x0c\x92\x2e\xed\xbf\xbb\xe6\x93\x9e\x77\xf6\x74\x6c\x34\xe3\x13\x72\x96\x99\xd2\x13\x9d\x04\x49\xe0\xc8\xc6\x7e\x94\x4d\x6b\x9d\x8a\x4a\x1c\xaf\x45\xb0\xfe\x7f\xfe\xf5\x77\x21\x31\xd8\x18\x21\x92\xd9\x88\x0f\xf9\xc5\x66\x76\x24\x9d\x90\x04\xe3\xbf\x6f\xf8\x7c\x87\xac\xfd\xd6\xfe\x10\x35\x88\xa6\x47\xce\x8a\x6f\x98\xb2\xa8\xbb\x63\x3c\x41\xb7\xfb\x2b\x34\x5f\xcb\x52\xd7\xdd\x18\xe9\xfa\x36\x01\x8d\xdd\x7f\xe8\x98\x5e\xb7\xe2\xdc\x2f\xf3\x3a\x25\xa9\x8c\x7d\x5c\xa2\x51\x2f\x8b\x77\x71\xd9\x5a\xae\xe3\xc9\x18\xe5\x09\xc4\xac\x23\x1b\xf8\x13\x7c\xf9\xa5\x5f\x78\x34\xe7\x2a\xea\x52\x36\xfb\x72\xd5\xbc\x0c\xa2\xf3\x9a\x6b\x5b\xd5\x38\x16\x34\xbd\x56\xbb\x74\xcd\x45\xa0\xd0\xfe\x43\x44\x28\xb4\x1b\x9f\x35\xcc\xeb\x01\xd1\x20\xd1\x82\xa6\x38\x02\x16\xcb\x7d\xf7\x93\xe6\x98\x7c\x2d\x2b\xa1\xf2\xec\xcf\x09\x1b\x28\xd1\x32\xd4\x88\x21\xb9\xad\x40\x3f\x57\xbb\x77\x4f\xc3\x4c\xb4\x64\x46\x4b\x4f\x6c\x8e\xa8\xb2\xfd\x62\xb3\x83\xc6\x02\xfb\xdb\xe5\xd1\xee\x45\xe3\xc1\x2b\x63\x69\x85\xab\xbf\x3f\x0c\x77\x33\x2d\x45\x8a\xb6\xe9\xb7\xb2\xca\xfe\x2c\x8b\xc0\x2f\x55\x5a\x51\x85\x62\x2a\x5f\x2b\x00\x4f\x5e\x44\xb4\x0e\x39\x32\xfe\xd7\x4d\xa5\x84\x27\x5b\x1d\xc2\x6c\xc6\xe3\x45\xa7\xa9\x25\x32\x79\x07\xf1\x8a\x6a\x81\x57\x35\x49\x93\x0e\x85\x98\x20\x1a\x3a\xab\x1f\x44\xdd\x40\x35\x87\xc6\x83\x40\x26\x68\xf5\xdc\x8b\x42\x2f\x3b\x6c\xb4\x50\xcd\xee\xba\xa9\xa2\xb1\x46\xb5\xdd\xf2\xd2\xee\x9a\x57\x16\xd7\x79\x80\x2a\x72\xe7\x84\x2c\xb0\xf4\xfd\x5a\x7b\x4c\x9d\x4b\xdf\xed\x45\x75\x2d\x16\xe6\xcf\x12\x21\x82\x48\x74\xe9\x39\x20\x27\xc7\x41\x68\xee\x0a\x3d\x45\x71\x19\x3b\x2f\x10\x85\xcc\xb8\x8a\xd5\xc7\x52\xc3\x75\x46\x08\x08\x8f\x62\xe5\xcf\xaf\xe0\xf1\x7c\xec\x4e\xa6\x3a\x05\xe3\x11\xa9\xad\xf9\x7d\xf0\x0e\x1b\xda\xd5\xfd\x1a\x03\x14\x62\x1f\xc8\x3a\x9c\xba\xdc\xaf\xbf\x0e\x63\xa1\x31\x57\x44\x57\xeb\x06\x8e\x5f\x26\x50\xaa\x59\x17\x00\xe2\x34\xc4\x41\x0d\x2e\x0a\xd3\x41\xfc\xc6\x6f\x12\xa7\x49\x14\x74\xf4\x65\x03\x92\x73\xff\x1c\x49\x18\xa7\xce\x59\x9e\x8b\x5d\x8d\x87\x0c\x24\x5a\x60\x7e\xe8\x11\xde\x3d\xf3\xf5\xac\x6d\x3d\xf3\xa5\xd3\x58\x20\x2f\x88\xea\xe9\x56\xea\x01\xbd\x31\x81\x54\xd9\xb0\xfe\xcf\xac\xf0\x53\x06\x38\x4b\x30\x18\x84\xc2\x00\xab\xa7\xdd\x01\x39\x47\x76\x13\x04\x12\x70\xad\xd0\xc0\x10\x8d\xe7\x9b\xb9\x9c\x26\x1b\x2a\x88\x80\xa2\xd0\xe5\x02\x6d\xde\xfb\xb2\x0f\xad\x81\x34\xb1\xf4\x91\xb9\x41\xd1\xfa\xf0\x63\x2a\xa9\xb5\xf3\x2b\xf7\xa2\x78\x9d\xb9\xbe\x66\x21\xed\x75\x53\xbf\x74\xbf\xa6\x68\xf2\xdf\x97\xcf\x8f\xf0\x3e\x55\xc3\x9c\x65\xde\x01\xe0\x21\x66\x13\xb6\xa2\xae\x6f\x85\x5f\xf5\x01\x5a\x43\xcb\xc6\x8f\x3c\xf7\x81\xde\x9d\xaa\x6c\x50\xa4\xea\x5a\x1a\x06\x41\x2f\x45\xc5\xfc\x05\x4c\x9c\xe0\x0a\x31\x32\x8f\xc1\xc8\x90\x98\xf1\xcb\xdf\x9e\xbd\x9c\x68\x57\x48\xec\x78\xca\x89\x09\x92\x08\x17\x8d\xe2\x7c\x5c\x9c\xbc\x30\x0e\x31\x61\xa8\x2c\x85\x7c\x7d\x3c\xa8\x1c\x44\x31\xbf\xe6\x98\x88\x5a\x76\xed\xac\xfe\x6e\x83\x18\x38\x6e\x8d\xe8\xcc\x3d\x13\x31\x4b\xdc\x93\xd5\x8f\xa2\x75\x52\x4e\x1d\x40\xdf\x90\x34\x40\xbc\xfa\x6e\xbf\xd8\xaf\x0e\xdb\xfb\xc5\xbf\x3a\x5a\x46\x62\xa8\x60\x88\x58\xff\xdf\x19\xaa\xcb\x13\xd4\xe5\xb9\xea\x2f\x4a\x25\x89\x3d\xe3\xc0\x5d\x67\x43\x1a\xaa\x65\xd0\x91\x3f\xfd\x84\x6c\xa8\xc6\x4e\x4c\x4c\xa4\x24\x23\x23\xe4\x0e\x8b\x36\xae\x23\x85\x26\x66\x16\x49\xeb\x78\x2b\x90\x6e\x17\xcb\xd2\x1a\xa8\x44\x3e\x0f\x39\x34\x71\x42\x03\x37\xec\xfe\x38\x95\xa7\x76\xee\x4f\x69\xa3\x66\xe7\xbe\x89\xc1\x20\xc0\x6a\xf5\xfd\x6e\x94\x6c\x31\xb1\x09\xd0\xc1\x73\xd9\xa1\xc3\x6e\xbf\xf8\x63\x75\xd8\xff\xf4\x96\x9e\x49\x5c\x5a\xc3\x0a\x4b\xdd\x9e\xa7\xef\x91\x86\xa9\x8e\xbb\x0a\x9c\x71\x5e\xc5\xa4\x21\x78\xdc\xc8\xee\x2c\x6b\x55\x65\x27\x2b\x27\x3b\xde\xff\x4c\x0a\xd4\x71\xca\x59\x4a\x5d\xd8\x35\x70\x9a\xdc\x88\x47\x80\x98\xc1\xef\x58\x01\xb6\x2f\x6d\x06\x79\xb2\x9a\xdb\x79\x31\x29\x2d\x37\x9c\x59\x9d\xa9\xfd\xb7\xf5\xd3\xed\x61\xbf\x5e\x3d\x1d\x6e\xd7\xbb\xe5\xa0\x94\xce\x70\x25\x10\x16\xb0\x5c\x2e\x3f\xf3\xfa\x0d\x07\x5b\x9d\x55\x43\xb3\xae\x5d\xa8\x66\x30\xeb\x8d\x10\xdc\xb2\xee\xe0\xc6\xe4\xbe\xeb\x15\x1e\xc8\x37\x36\x3a\xec\x0a\xc2\xe6\xc8\xdd\x89\x91\x3c\xea\xb9\xe5\x6f\x4b\x75\xc6\xb7\x1d\x3d\x92\x22\x1c\x29\x3d\x6a\x61\x60\xa1\x35\xb5\x6a\x7c\x34\xf8\x9b\xfd\xe3\x5b\x25\x8e\x85\xa3\x5d\x8e\xda\x7d\xd2\x07\xa0\xf1\x83\xb1\xc9\x6d\x75\x10\x27\x81\xe3\xf1\x5e\x54\xcd\x7b\x59\xbd\x4e\x4d\x35\x03\x61\xca\xbd\xa6\xc0\x2a\x37\xe8\x63\xd6\xd9\x24\x36\x63\x20\x11\x68\x5d\x6d\xbf\x3f\x2d\xbf\x2d\x76\xab\xa7\xc3\xc3\xe2\x9f\x76\x51\x3e\x2c\x17\xdb\xc3\xed\xe2\x5f\x1e\x43\x6e\xc0\xe8\xa4\x57\xc1\x79\x10\xbf\x7c\x4d\xe0\xf8\xe1\x4c\x62\x43\xaf\x07\xa8\x5b\x83\x74\xff\x02\x8b\x8d\x1b\x07\x8e\x80\x60\xea\x46\xcc\xdb\x87\xc6\x08\x19\xea\x5e\x05\x4f\x95\x85\x65\xa8\xec\x83\x05\xc6\x80\xa5\x44\xac\xa1\x79\xc2\x28\x0e\x7a\x5e\x5b\xa8\x66\xf4\x87\x69\x10\x08\x4e\x5c\x71\x75\x79\xb6\xb6\xf0\xa4\x76\xb7\x1b\x2a\x34\x08\x39\xa7\xdc\xf3\x91\x94\x27\xf4\x25\x97\xa2\x81\x67\x27\x52\xe9\x75\x44\xaf\x87\x21\x0d\xa2\x84\x60\x0d\xa0\xed\xa9\xff\x9e\xc6\xa5\xe8\x34\x20\x51\x8a\xf1\xc4\x7f\x8b\xd3\x32\x2f\xcf\x6e\x81\xa2\x01\x11\x81\xaf\xfe\xdf\x83\x38\x0e\x96\x02\x1a\x50\x29\x8d\xb3\x3e\x56\x45\x53\x95\xa7\x8b\x3f\xc2\x12\x21\xe2\x01\x45\x98\xd5\x38\x18\xbf\x3a\x03\xcb\x5f\xb6\x7b\x58\xdf\xaf\xfc\x89\x31\x31\x14\x3c\xf8\x7b\xff\xcd\x54\xe5\x71\x6c\x4a\xd3\x20\x09\x4c\x4a\x3c\x36\xec\x5c\x15\xc2\xb2\x05\x3a\x1b\x65\x50\xf8\x48\x03\x1e\x8a\x28\x18\xab\x32\xf4\x8c\x89\xb7\x8e\xfb\x00\xf4\x15\xcf\x22\x0d\x04\x03\x7c\x0e\x55\xfb\x6b\x09\xde\x21\xb4\x1c\xca\x76\x2e\xc4\x40\x03\x01\x11\x6e\x03\x0f\xa2\xae\x91\x76\x65\x07\xc5\x54\x9c\x9a\x06\x32\xb2\xae\xb7\x67\x53\x9a\x9b\xee\x34\x90\x84\x62\x71\x70\xeb\x62\x3e\x6c\x96\xfe\x51\x54\xc2\x90\x97\x0e\x9a\x97\x8e\x0b\xc9\x1f\xe2\x89\x57\x9c\x5f\xe4\xb9\x67\x37\x5a\x9f\x0c\xa2\xc6\xc1\x25\x77\xa2\xc0\x37\x17\x06\xd7\xea\xba\x29\x2b\xf8\x06\xc2\x55\x1f\xdf\x01\x8c\x85\x17\xc6\x8f\xa5\x14\x4d\xa9\x4f\x61\xe2\xa6\x65\xb3\x7a\x3d\xdc\x9c\x06\xca\x24\x3e\x5f\xb9\x05\x54\x05\x76\xd1\xa4\x31\x60\xda\xb5\x6e\x1d\x0b\xc0\xe5\xbc\xd0\x7b\xf1\xab\xbd\xff\x5f\x00\x22\xfd\x89\x3c\x64\x76\xbc\x20\x46\x1a\x13\x72\x2e\x5d\x37\x3c\x21\x75\xcd\x21\x32\x98\xbd\x50\xc8\x74\xea\xaa\x88\x4d\x55\x8e\x50\xd3\x6e\xbd\xa2\x01\x88\xd8\xbb\x66\xe7\x1a\x2a\x77\x78\x32\x8c\x0d\xd1\xe8\x91\x18\x80\xad\xcd\x54\xf8\x2e\x30\x2c\x26\x96\xfd\xe1\x7b\x3b\x02\xde\xab\xac\x13\x4d\xa7\x81\xd1\xb6\x5a\xdd\x5d\xf4\xee\x5c\x68\x84\x2e\x0f\x02\x8f\x34\x0c\x98\xa5\xb2\x5a\xe8\x6f\xd9\xdb\x44\xee\xe8\x63\xe2\xec\xee\xd9\xc2\x20\xa1\x81\xd5\x94\x56\xb9\xa8\xe0\xbe\x7c\x83\xb9\xc5\x21\x0c\x84\x42\xb8\x42\xd5\xda\x26\x4b\x31\xde\x48\x69\x18\x06\x11\xe2\x90\x1c\x17\x51\x57\x2a\x3b\x17\x9d\x4f\xa7\x80\xd0\xf9\x5f\xfd\x95\xa9\xc6\x80\xcf\x52\x9c\x7c\xb7\x85\x91\x30\x48\xcf\xfb\x53\x34\x75\x59\xe8\xf2\xd9\x1f\x20\x84\x9a\xd8\xf5\x27\x52\xf1\xce\x06\x4c\x69\x48\xb4\xcd\xfb\xae\x8f\xc7\x5c\x5c\xe3\x0c\x68\x48\x13\xc0\x12\x5e\xef\x55\xdd\x95\xd5\xdc\xa8\x0c\x29\x4f\x12\xb7\xbe\x2d\xac\x6c\x11\xe8\x7d\xa9\x3d\xa6\xb9\x6d\xc0\x91\x85\xe9\x16\xe3\x4b\xc3\xb5\x31\x64\xa1\x54\xa4\xe7\x14\x2d\xeb\x46\x96\x17\xbf\x62\xcc\xa6\xd0\x43\xdf\xdd\xad\xd1\xd0\x55\x66\x55\xeb\xa2\xb9\xcb\x20\xd7\x61\x77\x65\x99\x9a\xb4\x23\xc4\x46\x6a\xe6\x7a\xb8\x82\x7d\x12\xa6\xa5\x21\x33\x04\xc3\x7b\xf2\x7c\xd9\x35\x67\x9d\x95\x63\xc6\xb9\xf1\x77\x8f\x13\x6b\x0b\xdb\xda\x5c\xcc\xa3\xcd\x60\x54\x68\x18\x73\x8e\x93\x70\x3f\x4a\xf3\xd2\x30\x8d\x25\xe6\x29\x76\x65\x2e\xaa\x5b\x51\x8e\x0f\x26\x1c\xfd\xdf\x13\x12\xf5\x62\xe0\x06\x53\x97\x23\x89\x6a\xdf\x56\x82\xaf\xaa\xc3\x40\xcc\x13\x08\xed\xe2\x45\x37\x97\x7d\x25\xd4\xeb\x04\xbb\x46\xc3\x14\x94\xd6\x83\x38\xe6\xb0\x68\x66\xf2\x9a\x3c\x0a\x68\xec\xa5\x8e\x94\xc3\x44\x55\x1f\x2a\x39\xb9\xb3\x44\x10\x62\xe0\xed\x34\x58\xd6\xac\x02\x9f\x6f\x40\x62\x2c\xc9\x74\x6a\xe7\x95\x6e\x37\xeb\x42\x41\x9e\xc3\x18\xa2\x4c\x43\xa1\x22\xdc\x5b\x6c\x49\xc9\xa1\xce\x3a\xd9\x4f\x1a\x0a\x10\x18\xfa\x3e\x9d\xe7\x8b\x84\x68\x28\x8c\xf0\x84\xaf\x3f\x45\x55\x65\x65\xd5\xd5\x34\x82\xb6\xd8\xbc\x49\xe7\xc8\x28\x44\x0c\xca\xfa\x8f\xfd\x5f\x7a\xd5\x34\x94\xd2\xa6\x71\x51\x1c\xa0\xca\x9a\x8b\x35\x07\xad\xdd\x7e\xbe\x22\x66\xa2\xa1\x0a\x19\xf4\xb6\x06\xba\xb9\x9f\x25\xf2\x68\xa8\x5d\x25\xaf\x85\x2a\x7e\xb9\x8a\x3c\xd1\x50\x2b\x2e\x6d\xb5\xa3\x06\x38\x4e\x24\xab\xc6\xdb\x53\x08\x91\x45\x17\xb4\x36\xc4\x13\x98\x1b\x1b\xcb\xf3\xfd\x09\xc4\x0a\xea\xfc\xe3\x2c\x8a\xe6\x7c\xdc\xf6\xb3\x19\x20\xc0\x55\x10\x83\x7f\xab\x42\x87\x81\x3f\x62\x62\x12\x0e\x59\x25\xa7\xb5\x8e\xe3\xd7\x89\x02\x12\xe2\xb2\xbb\xdc\x23\x0c\xfa\x8b\xff\x99\x0a\x27\x40\x94\x9d\x3c\x44\x8b\x46\x21\x4b\xd0\x3f\x70\x09\x77\x84\xb1\x60\xe1\x49\x0e\xeb\xe3\x29\x47\xd4\xda\x35\xa3\x0e\x8d\xc2\xc4\x42\x7b\xff\x11\x4d\x0e\x44\xd4\xe6\xd5\x4d\x66\x9a\x97\xd5\xaf\x06\x90\xf2\xb4\x7d\x27\x94\xc3\x5e\x75\x1a\x16\x34\x8a\x94\x21\xd4\x19\xed\xdb\xf2\x34\x3f\xbe\x22\x92\x5a\x96\x01\x95\x97\x75\x9f\x05\xa4\x11\x11\x01\xd6\x99\x7e\x2d\xe7\xeb\xfd\x3e\x9d\x3f\x11\xa5\xcc\x62\x8f\xcb\xac\x58\xd7\xf5\x19\xb4\x4d\xed\xf7\xb4\x24\x34\x8a\x03\xe5\xc3\xc4\x37\x16\x88\x39\x22\x78\x18\x5f\x30\x49\xac\x77\xf1\xb0\x7e\xdc\x8f\x68\x4f\x68\x94\x70\x8b\xb2\x75\xea\xbd\x63\xae\x8d\xd9\xd4\x2e\x8d\x12\xa0\x28\x82\xbb\xd8\xee\xbe\xcc\xee\xb5\x5d\xbb\xd4\x38\xfc\xb7\x45\x91\xaf\xeb\xad\xc8\x26\xcb\x51\x94\x06\x11\xa6\x3f\xa4\x4d\xe9\xd6\xf7\x03\x9e\x53\x1a\xf1\x20\x88\x3d\xc6\xbd\x7e\x1d\x06\x9b\x69\xc4\x23\x85\x29\x24\x9b\xe4\x59\xbc\x89\x2c\x6f\x5d\x0f\x07\x29\xee\x66\x7a\x6f\x35\x44\x5c\x58\x55\x74\x04\x28\xd7\x99\xba\x69\xcd\xdc\xa6\xde\x42\x45\x82\xbe\x4e\x98\x46\x5c\x53\x94\x00\x3e\x66\x8d\x79\xd7\xc3\xc5\x39\x12\x84\x58\x5e\x03\x5c\x3d\xf2\xcb\xa1\x86\x1c\x54\x73\xc8\x86\xda\x21\x7e\x53\x89\x04\x0f\xa4\xee\xcc\xec\xc3\xff\xce\xe5\x75\x7d\x88\x6f\x2a\x38\x6a\x64\xd6\x4d\x79\xda\x41\x73\x3e\x75\x77\x04\x20\xc9\xa0\xe2\x63\x5f\x16\xb5\x67\x9f\x70\x4d\x24\x0b\xb1\x26\xea\x61\xf1\xf8\x4f\x2b\x22\xef\x0f\x70\x41\x6d\x99\x5d\xd9\x7a\xf8\xe8\x17\x1d\x9c\x22\xae\xfb\xed\xcb\xe8\x6b\x48\x2d\x91\x15\xac\x81\xba\xf5\xb9\x5e\x36\x6f\x50\xe5\xa5\xd0\x83\x7b\x01\xa4\xae\x68\xe4\x6b\x5e\x4a\x91\xa3\x5f\x81\x4b\xde\x5c\xdd\x24\x8d\x54\x6a\xf0\xf9\xb3\x7a\x53\xec\x20\xcf\xa7\x87\x85\x26\x5d\xf8\xef\x24\x96\x65\x05\x73\x61\xe7\xb6\x21\xf0\x0e\x27\xf1\x55\x1c\xa1\x7d\xb6\x9b\x0b\x6a\x76\xfa\x26\xca\x49\x5a\xb6\xdd\x83\x55\x02\x0e\x14\xe3\xd2\x74\x93\x0b\x82\xc0\xba\x0c\x65\x37\x4e\x5b\xad\xe5\x8f\x19\x6d\x02\x4b\xe0\x01\x05\x72\x45\x7f\x30\xb7\x34\xe1\x49\xc7\xe6\x3c\x66\xe9\x6d\x0f\x5a\x35\xca\x47\x78\x47\x86\x85\x89\x03\x7b\xfd\xdf\x0f\x33\x52\x34\xd2\xa9\x56\x96\x0b\xfb\x99\x75\xdf\x57\x03\xc3\xed\xea\x66\xbd\xff\xb6\xb8\x5f\xdc\x8f\x86\xaa\x76\xd8\x41\x47\x68\xbb\x2c\x91\xc5\xb7\xe9\x46\x39\xa4\xdc\xba\x16\x7b\xef\x3f\x45\xc6\x21\xf8\xfe\x80\xea\xf9\xf7\x42\xcb\x34\x32\x9a\xb1\x2e\x63\xf5\x8a\x3c\x25\xed\xb8\x9a\x7c\x3e\x12\x86\x14\x29\x1b\x9e\xbd\xbd\x3e\x71\x17\x48\x48\x24\x36\x68\xca\x02\x7e\x35\x55\x4f\x47\x42\x49\xa8\x9d\x48\x76\x23\x9e\x81\xf4\x14\x15\x94\x44\x51\x10\x89\x61\x95\xf1\x88\x1d\x85\x12\x46\x0c\xd2\x81\xc0\x2f\x2c\xdf\xee\x7e\x4e\x12\x43\x5c\x5e\xc5\x16\xd9\x5c\xe5\x31\x28\x61\x9c\xe2\x5d\xdf\xb0\xea\xa3\x37\xee\xe7\x8d\xf9\x39\xd8\x14\x25\x4c\x24\xe8\xa7\xf4\xd5\x79\xdd\xe8\x20\x4c\x0a\xf4\x48\xb3\x06\x8e\xf5\x5d\x59\xb5\xef\x85\x54\xef\xf3\xbb\x0d\x61\x5a\xe2\x2e\xb9\xdc\xde\xf9\x4b\xc4\xad\x85\x39\x90\xf8\x1e\xb0\xa9\xe3\x6e\x31\x35\x2e\x46\xd7\x8b\x13\x4b\xdb\x68\xa1\x19\x4f\x20\x72\xdc\x94\xad\xf5\x38\x2c\xbd\x0c\xa3\x74\x98\xd2\x76\xe2\x76\x83\xf8\x0b\x89\x95\xd5\x9a\xb0\xdb\xc8\x8f\x2c\xcf\x45\x56\x4c\x69\x33\xe6\xdf\x2a\x06\x26\x1c\xc2\xc9\x2e\x22\x17\x34\x48\xc7\xdd\x98\x04\x22\xd5\x68\x9a\x40\x75\x79\xb8\x58\x82\x9e\xf1\xd7\x4a\x78\x9a\xba\x75\xc4\x71\x1e\x55\xd3\x16\x92\x60\x36\xe0\x45\xd4\xdf\x0b\x87\x9d\x03\xdd\xe7\xe9\x26\xad\xc1\x7a\x88\xef\x53\x4e\xe5\xc1\x6b\x27\x26\xe0\xe9\xb8\x7c\xe1\x5a\x9a\x95\x92\x94\xf5\xb8\x16\x54\xbc\xfb\x72\x3d\xe7\x7d\x53\x11\x53\x18\x93\x39\x20\x74\xb2\xaa\x27\x3d\x92\x2a\x86\x29\x91\x17\x81\x2e\x0e\x74\x00\x12\x4a\x78\x64\xe3\xaf\x75\x76\xc4\x0d\x63\x23\xf3\xec\x79\x90\x2a\xf5\xcd\x84\x09\x5d\xd8\x66\xad\x41\xdc\x42\x17\x53\x9e\x3c\x3e\x57\x31\x2a\xa6\x17\x65\x71\x77\x2e\x9e\x33\x99\xc3\xcd\x58\x2b\xcb\x8f\x12\x7f\x02\x84\x58\xa3\x28\xcf\x97\x7d\x05\xf0\x49\x21\x38\x25\xdc\xd8\xf7\xd8\x67\x47\xf8\xcd\x15\x87\x08\x62\x11\x7e\x0e\x93\x24\x7c\xc2\x87\x12\x91\xc6\x68\xf0\x6b\x99\xef\x5e\xc4\x5d\x9e\x9d\x46\xaf\x2c\xb8\xf2\xbc\xa8\x0b\x2b\xa5\x3d\x53\x05\x4d\x89\xd0\x21\x46\x20\x1e\xd6\x8f\x58\xc8\xb7\xf9\xee\xed\x25\x22\xa9\xc1\x18\x16\x58\x20\xc4\xfe\xbd\xec\x8e\x08\x86\xbc\x65\x28\x85\x76\x25\x65\x31\x79\x6b\x08\xac\x14\xa9\xbd\x7d\xbd\xfa\xdf\x59\x8c\x6a\x62\x29\x81\x30\x90\x74\x98\xb0\x83\xfd\x07\xe6\x1d\x01\x6a\xa1\xed\xed\x9e\x7d\x27\xb2\xfc\x7b\xd1\x54\xe7\xa1\x2c\x0e\x0a\x7d\xf8\xc6\x9c\x23\x4d\x87\xa9\x00\xe6\x29\xf8\xdb\x36\xca\x42\x03\xca\xa2\x11\x59\x51\x5f\xf3\x96\x51\x62\x52\x6b\xc9\x7b\x9a\xb6\x0d\xca\x18\x3c\xbf\xcc\xe6\x8c\x29\x0d\x02\x85\x56\x5e\xd5\x36\x09\xf9\x78\x84\xd1\x20\x8d\x2c\x9f\x22\xea\xe9\x0e\xe4\xb4\x29\x0d\x38\xc3\x15\x6e\xf7\x6d\x3d\x84\xfd\x53\x1a\x12\x8d\x34\xf2\x1d\xf3\x5c\x9e\xdf\x95\xd5\x24\xf2\x38\x91\xe2\xa5\x94\xd2\x04\x83\xbd\x67\x1b\x27\x19\x5d\x91\x29\x69\x88\xab\x84\x6b\x6a\x57\xd1\xdb\x2d\xd7\x94\x01\xc1\xfa\xb5\x43\x56\xa3\xf4\xff\x0f\xcc\x57\x8c\x5f\x24\x96\x31\x12\x7f\x5b\x88\xfc\x43\x56\x20\xb0\x3d\xf2\x97\x88\x75\x8c\x99\xf3\xdd\x4b\xd6\x8c\x6e\x9d\x90\x18\x62\x5f\x1c\x5f\x35\xfd\x4d\x13\x4a\x74\xdc\x91\x82\x57\x8b\x49\x80\x81\x26\x42\x23\x3c\xab\x80\x77\x54\xfe\x1d\x2d\x12\x34\x91\x29\x8e\xd6\xec\xd4\x7a\xed\xe3\x13\x95\x75\x51\xec\xe2\xef\x49\x42\x9f\xe0\x74\x1e\xfb\x54\xc3\x20\x21\x4d\x8c\x90\x41\x1f\x53\xec\xd5\x3e\xfd\xe3\xa6\x2a\xc6\xed\x6e\x7d\xb3\x5c\xf8\xdf\x44\x10\x21\x1e\xfd\x54\x95\x0d\x28\x7c\x0d\xa1\x1a\x98\x29\xee\xa7\x54\x88\x08\xab\x52\xef\x37\x5f\x0f\x37\xd0\xdc\x97\xf5\x87\x14\xd5\xee\x0c\x19\x4a\xd4\xa2\x28\x8b\xfc\xf2\x4d\x54\x6f\xd3\x8a\x7b\x4a\x25\x8f\xb1\x5e\x71\xbd\xdc\x1c\x6e\x36\x8f\xdf\x77\xd1\x61\x77\xff\xf5\xf1\x70\xbf\xda\xed\xfc\x33\x4a\xb0\xa0\xf6\x5e\xa6\xa5\x2a\xbe\x37\x59\x9e\x35\x97\xf9\x49\x47\x15\x8d\x11\x8b\xaf\x44\xae\x06\x46\xe6\xa0\x81\x96\xda\xfb\xda\x87\xa6\x3c\x94\x1f\x0a\x6b\x74\x9f\x4b\x19\x10\xd6\x5b\xc8\x9e\x6d\xb8\xde\xdb\x6a\x54\xc7\x8c\x0e\x25\x7a\xb7\x15\xce\xba\x91\xaf\x3f\xbe\xbf\x4e\x95\x88\x06\xa6\xc1\x7d\xf9\xfc\x99\xb7\x46\x35\x4f\x30\xf5\xd5\x5a\x23\x57\xc3\xcc\x84\xa1\xe5\xc8\x6f\x47\x67\x56\x3c\x0f\xeb\x97\x28\x35\xd4\x42\x59\xb0\xe0\xb1\x81\x6d\x2e\x8a\x7a\x63\x7e\x40\xa1\xaf\x85\x66\x46\xf5\x99\xfe\x7c\x57\xd9\x73\xaa\xca\x53\x59\x8b\xfc\x47\x39\xcd\xaa\x53\x16\x52\x82\xc1\xe4\x55\xf3\x72\x7f\xf1\x28\x26\xca\xc2\x44\x5b\x30\xd6\x60\xa9\xbb\xb9\xf4\x9a\x0a\x9f\x7a\xda\x2c\x14\x21\x7a\xb2\x3e\xd4\x6c\x19\x32\xea\xee\xe2\x4a\xa2\xd2\xf7\xbf\x87\xb8\x58\xca\x42\x23\x71\x3b\xc7\xd2\x39\x51\xc3\x7d\x29\x8a\x4d\x71\x03\x2f\x22\x37\x03\xf6\xf5\x0f\xf2\x66\xee\x22\x51\x4c\x69\xef\x78\x3f\xc2\xfb\xed\xa5\x10\xc7\x4c\xb9\xe4\xdb\x62\x1c\x51\x1f\x6f\x50\x2c\x92\x89\xa6\x9e\x0d\x14\x0b\x2a\xf5\x9c\x49\xcd\x48\x60\x75\x89\xfc\xb0\xee\xfa\x65\x51\x8c\xbc\x5a\x46\x02\x8e\xd1\x7f\x79\xbe\x3c\x3c\x2e\x47\x3b\x11\x23\x34\x42\x03\xed\xdf\x22\xfb\xb7\xc8\x7a\x10\x28\x65\xc4\x50\xe8\xe5\xe2\x3c\xb1\xf9\x5f\x46\x3b\x7e\x2b\x0a\xc2\x68\x4c\x11\xa2\xd3\xba\x2d\x50\x34\xbe\x28\x7c\x6e\xc3\x66\xd4\xc8\xc4\x81\x44\xc3\x41\xaa\x85\xb1\x24\x62\xce\xb6\x5c\x3c\x43\xd1\xac\xf5\xcd\xc5\x17\xe3\xde\xc0\x64\x90\x33\xc6\x39\xde\x71\xf5\x78\x7b\xb8\x5d\xec\x57\xdd\x55\x20\x94\x3e\xac\x6c\x6f\x0b\xf5\xfe\x45\x34\x4b\xe1\xe8\xee\x06\x95\xc6\x7e\xa3\x61\x71\x62\x33\xc9\x3d\x4b\xcd\xdc\x2a\xc1\x62\x2e\x90\x80\xfe\x11\x50\xcb\xc6\xff\xaa\x53\xdd\x6b\xa6\xef\x4e\xa0\x32\x27\x48\xb9\x2c\x0b\x2b\x50\x39\xd9\x60\x59\x42\x52\xc2\x06\xdb\x21\x06\x8d\xaf\xa2\x71\xf3\x5d\x9d\x10\x8b\xa3\xae\xa1\x79\x3a\xff\xb5\x10\x89\x3b\x2b\xa5\x91\x31\x5d\xe0\xf1\x1e\xde\x16\x85\xbe\x6b\xad\x3d\x0c\x9c\x57\xf5\x34\x69\xc4\x78\x14\x6a\x57\xb6\x82\x38\x9c\x8e\x96\xd0\x1d\x17\x21\x23\xc2\x1b\xa4\x93\x7e\x12\x2c\xe5\xbd\xba\xdb\xae\xcc\x33\x8d\x4a\x88\xf3\x89\x0e\x26\x20\x30\xb1\x57\xff\x69\x2d\xb2\x59\x48\x00\x65\x32\x32\x81\xa3\xb4\x71\x88\x98\xc5\x71\x3a\x2c\x14\x0b\x30\x14\x70\x2a\xb3\xa2\x79\x2a\x4b\x84\xad\x7d\x99\x9d\x97\x8a\x89\x20\xf2\x86\x3e\x9c\xf6\xef\xe5\xb0\x40\x6a\x7a\x59\xcd\x6c\xd5\x72\x9e\xbd\x41\x75\xf1\x5c\x46\x9f\x77\xba\x8e\x00\xad\x9e\xac\xd3\x5d\x59\xe8\xb7\xd6\x52\xa9\xdb\xfe\x34\x53\x89\x7e\xca\x34\xb3\x4a\x95\x96\x59\xf5\x05\x5c\xe1\xde\xb0\x58\x88\x32\x9d\x4a\x66\xe3\x5d\xc5\x52\x9c\x5a\x1b\xd2\x1f\x81\x98\xa0\xa9\xbd\x7d\x5a\x1d\xba\x0d\x14\x8d\x62\x4f\x57\x47\x19\x24\x8e\x32\x1f\x4e\x79\x39\x8f\xcf\xa0\xcc\xc4\x29\xb1\x6a\xed\xcd\xb9\x2a\x6c\xe6\xd7\xc7\x8b\x6c\x93\x38\xa0\x80\x2c\xd9\x75\x53\x9e\x86\x42\xa8\x34\x0e\x18\xf3\xf2\x09\xed\xfa\x33\xd5\x53\xf9\x08\x16\x10\x07\x71\x9a\x74\x15\x0c\x28\x55\x15\x1d\x48\x77\x51\xb0\xbc\x79\xed\x06\xfd\x33\xc3\x80\x70\x25\xbe\x8a\x0f\xa5\xe3\xdd\x69\x61\xa0\x5c\x0c\xbd\xb9\x02\x94\x7d\x70\x46\x04\xd6\xb8\xb0\x44\xb5\x1f\x60\xfc\x06\xd5\xa2\xb4\x75\xeb\x31\xa0\x27\xcf\x55\xb1\x5e\x6e\xdc\xe2\xee\x0f\x72\x89\x56\x24\x58\xf6\x3a\xc4\x7f\xf8\x63\x51\x18\x1b\xeb\xb5\x16\x45\x56\x3c\xef\x50\x14\xc7\x1f\x8b\x14\x82\x27\x8f\xe7\xbc\xc9\x5a\xdb\x74\x8b\x05\x12\x1f\x92\xbe\xd0\x38\x4a\x13\x9c\x1e\x47\x87\x47\x19\x41\x39\x69\x4c\x44\x04\x56\x84\x4a\xd4\x25\x42\x89\x6e\x33\x63\xd6\xc5\xcd\x69\xb2\x3a\xc5\x94\x50\xb4\x10\xf6\xef\x25\x92\x7c\xa3\xdd\xf2\x17\xc0\x92\xdf\x2d\x38\xfa\x7c\x99\x8a\x29\x63\x18\xcb\xb5\xfc\x16\x63\xae\x23\x1a\x33\x42\x90\x02\x47\xa2\x48\x83\x7f\x31\x96\x58\x0e\xea\x1a\x9a\x6f\x99\xd6\x50\x2c\xcf\xad\x65\xf9\x65\x4c\xf8\x41\x63\xc6\xe3\x8e\x8c\x07\x23\xdc\x2e\x40\x3d\x7e\x79\xc6\xb5\x75\x61\xb6\xeb\xc7\xbb\x3e\xaa\x15\xc7\x84\xa3\xb1\xfb\x77\xa1\x5e\xeb\x6b\xaa\x05\x1a\xc7\x71\x6a\x91\x29\x65\x81\xc1\xc9\xae\xd0\x89\xc6\x49\x94\x60\x18\x7a\x8d\x30\x9b\x9e\x44\x84\xc6\x09\x05\x04\x98\x7f\x13\xea\xd5\xa2\xbb\xfa\x7d\x3e\x4e\x18\x41\xd8\xc7\xea\x0d\x49\x37\xac\xe0\xbc\xb3\xc3\x07\x56\xe1\x87\x0a\x97\x1f\xf4\x71\xd2\xfa\xb3\x6e\x2b\x38\x9e\x06\x11\xf7\x38\x31\x0c\x55\x3d\xb2\x42\x3b\x94\xc3\x88\x9b\x9c\xc6\xa9\x4b\x26\x38\xa5\x40\xac\x19\xbc\x3b\x23\xa1\xd1\x60\x22\x73\x11\xfa\xd2\xf0\xbb\xcc\x34\x2f\x2e\xb6\x3b\x21\x42\x6f\xdb\x09\xec\xb1\x83\xce\xde\xb2\xdd\x29\x1f\xc4\xd2\x3e\xdd\x02\x63\x19\x25\x7e\x23\x68\x17\xe2\xe9\x46\x11\x4b\x9a\x22\x17\xc7\x51\xbc\xc2\x2e\x3b\x9e\x72\xa7\xe4\x78\x75\xf9\xd9\xe0\x7e\xac\x22\x89\x1c\x5e\xa7\x41\xfe\x63\x3c\xf1\xbb\xa6\x3a\x48\x11\x29\xeb\x69\x19\x27\x73\x4e\xab\xc0\x11\xc0\x60\x91\x3a\xe6\xb9\xe7\x3d\x80\x58\xab\x24\x1c\xa8\x0e\x78\x40\xcc\x07\xe8\xc6\xe1\xba\xa9\x75\x8a\x40\xa2\x93\xf5\x32\x46\xd6\x7e\x0c\x21\x67\x3d\x2c\x0f\x53\x0a\xa3\xac\xb0\x6f\x46\x23\x74\x97\x6d\xb5\xf7\x18\xea\x33\xbc\x17\x88\x28\x1d\x28\x7d\x2c\xd4\x70\xf8\x80\xb1\x3a\x70\x59\xa1\x33\xe4\xa7\x2c\xf4\xae\x6c\x8d\xa1\x61\x3e\x39\x09\x62\x2e\x8d\x2b\x8d\x43\xf3\x76\x02\x26\xa5\x49\x20\x43\x2f\x19\xe1\x70\xf6\xa3\xae\x4a\x02\x63\xf1\x2c\x35\x34\x0f\xe2\xd7\xee\xea\x78\x98\x10\x74\xe6\xa0\x1f\xc6\x5d\x29\x45\x7b\xb4\x4b\xc2\xdb\x10\x66\x6b\xa9\x8d\x0d\xf2\xbf\x4d\xae\x97\x72\x4c\x44\x69\x68\xa0\x3a\x66\x05\x38\xb1\xf4\xa1\xe1\x9d\x84\x9a\x21\x27\xc9\x0f\x68\xee\xb3\x66\xbe\xe8\xa6\x6d\xa5\x91\x33\xec\x0e\xe5\x63\xdd\xc7\x1d\xef\xac\x49\x14\x51\xac\x7d\x40\xa0\xc2\xbf\xbb\x5a\x59\x9a\x10\x6a\x09\x08\x50\x74\xc7\x2a\xfe\x8f\x3f\x63\x42\xd2\x10\xf5\xa9\x2c\xa4\x2e\x2f\xeb\x49\x01\x07\x4d\x88\xa4\xe0\xde\x7e\x80\x21\x73\xcc\x5e\x76\x3d\x9c\x83\xb3\xd3\x84\xa8\x24\xf0\xca\x10\x87\xb2\xf0\x5a\x72\x77\x22\xaf\x61\xf5\xbf\xfb\x0e\xde\x92\xd0\x90\x45\x6c\xe6\x0e\x78\xe9\x71\x24\x3a\xa1\xa1\x49\xdd\x44\x7e\x80\xe3\x0d\xd4\x56\xe2\xf7\xdc\x03\x8c\x12\xaa\x29\xca\x04\x76\x74\x73\x37\xe2\xf9\x73\x0b\x39\xa1\x46\x6a\x0b\x9c\xbe\x15\x97\xfd\x4b\x56\x35\x17\xb4\xa5\xfa\x11\xc6\x02\x86\x3b\x1c\xc6\x24\x31\x60\xd6\xda\xb6\x3d\x65\x37\x4d\x98\x8a\x22\xac\xa0\xc9\x0a\x8d\x98\x07\x8c\x14\x8e\x39\x95\x47\x37\x8d\xa5\x4e\x22\x5f\x16\x3f\x93\x46\xf6\xcd\x40\x20\xdd\x90\xb0\xc9\xdb\xf1\x7a\x91\xc4\x86\x22\x42\xe9\x78\x40\x98\xf5\xe2\x74\x1a\xe6\x50\x93\x44\x13\x57\x2b\x99\x29\x38\x28\x97\x22\x0a\xbb\xc3\xc0\x30\xbc\xf4\x22\xda\xc5\x0e\x61\xa9\xa7\x1c\xd6\x0d\x1c\x3f\x34\x93\x3e\xdf\x2a\x92\x34\x96\x3e\xc0\x7d\xbb\xdb\x3b\x36\x40\x7f\x2c\xb1\x05\xa7\xeb\xdb\x0e\xf6\x98\xa4\xda\xb2\xbc\x74\x0c\x36\x56\x62\xd2\x1f\x35\x01\x06\xb8\x5c\x75\xe9\xed\xde\xda\xb5\x73\x58\x9c\x24\x35\xd4\x8b\xce\x7e\xcb\xea\xd6\x99\xbc\x87\xe2\xb9\x79\xf1\x77\xe2\x81\xc4\xb9\x90\xd5\x1b\xb4\xa8\xbb\x5d\x25\xe1\x61\x8c\x26\x9f\x55\x0d\x18\x10\xe5\xb7\x87\x0c\x32\xe4\x1e\x86\x24\x0a\x4f\x60\xa0\x82\x39\x0b\x75\xce\x7b\x4d\xb8\xe6\x4e\xe6\xdf\xfa\x20\xbd\x82\x05\x4d\x04\xb3\x34\xfa\xfb\xf2\x58\xaa\x32\x2b\x46\x96\x60\x22\x98\xad\x0a\x1c\x16\xdc\xed\xa0\x69\xa6\xa9\x8f\x44\xa8\x80\x59\x5c\xf3\x1b\x38\xf6\x9e\x9e\x10\xb1\xf5\xd8\xca\x6a\x9a\x9e\xfc\x30\xff\x9f\xa8\x30\x66\x5e\x1f\xe7\x74\xaa\x50\xd9\x08\x96\x2f\x50\x37\x5d\x0e\xfe\x4b\xd7\x54\x22\xbd\xed\x80\xcc\x70\xe0\x59\x27\x8a\x86\x5e\x92\xaf\xe3\x79\x25\xd1\x78\x15\x54\x69\x80\xa6\xf0\x2d\x1c\x4b\x55\x89\x26\x53\x5b\x91\xb7\xef\xd8\x5d\x44\x58\x97\xa8\x7d\xd8\xf6\x55\xda\x73\x87\x55\x13\x34\x51\x52\x08\x27\xd7\x73\x87\xa5\xdb\x1f\x8e\xdd\xc1\x42\xa2\x75\x88\x9e\xcf\xa1\x80\xf7\xc5\xb3\x4b\x8a\x74\x0a\x86\x1f\xac\x13\xda\x08\xd4\x65\xff\xd9\xc5\xa4\xf7\xe5\x88\xb9\x9f\x26\x40\xcc\x40\xa7\xdc\x0b\x1d\x4e\xbe\x17\xc4\x02\xe3\x31\x75\x76\x3c\x8f\xc4\x9b\xce\x1f\x24\x8e\x07\xff\xfd\x4f\x98\xc4\x7e\x7e\x00\x08\x15\x76\x02\x98\x9d\x13\xec\x8e\x1a\xcd\x7d\x78\x04\x13\x45\xb6\x73\xc6\x7b\x47\x1a\x46\x1a\xb7\xaa\x9e\x9f\xef\xaf\x08\x5f\xe7\xfb\x26\x0d\x13\x12\x78\x09\x39\xf4\x84\x56\x53\x67\x35\x0d\x55\xe8\x42\x0a\xed\xaa\x6c\x89\xfa\xfb\x9a\x45\x9a\x86\x86\x12\xe8\x18\x68\xd1\xf7\xda\x67\xcd\x44\x61\x99\xa6\x11\x81\xd8\x05\xcd\xd1\x9e\x1c\x22\xdc\x7c\x93\x14\xfc\xb2\xa2\xe0\x06\x9a\xd6\x20\x9e\x36\xe1\xca\xd2\x36\x9e\x65\xe6\x1f\x20\xd2\x09\x71\xb8\xbf\xae\x80\xc0\x41\x14\x27\x6f\x1b\x69\x8b\xdb\x6d\x20\xef\xd9\x37\x68\x4a\x02\xed\x81\xe1\x4e\x0d\x4f\x3b\xc5\xf2\x7e\x51\x4e\x69\xa0\x62\x47\xcc\x32\x5c\x0c\x52\x2a\x19\xda\x39\xcd\x0b\x20\x89\x4d\x6f\x28\xa5\x2c\x8d\x91\x39\x00\xd3\xe6\x3e\x56\xe6\x8f\x49\x89\x88\x8d\xf7\xc3\xbe\x13\xe2\xa0\x69\xac\x0d\x22\xeb\xfa\x02\xf7\x21\xa3\x25\x4d\x93\x20\xc1\xac\xd2\x41\x3a\x93\xd5\x55\x41\x74\x69\xbe\x34\x89\x79\x34\xcc\x90\x5a\xb6\x94\x71\x37\x24\x10\x60\x64\x61\xfb\xb4\x5e\xae\x0e\x0f\xeb\x5b\x7f\xf9\x54\x29\x4b\x32\x6b\xcd\x3e\xdc\x4d\x31\xc2\xe2\x19\xdd\x69\xca\x69\x84\xae\xc1\x77\x09\x08\x85\xea\xf0\x55\xa9\xd0\x14\xb7\x52\xf5\x62\x76\xaa\x47\x03\xa4\x32\x4a\x30\x82\x54\x9e\x9b\x76\x1f\xd3\x59\xf1\x3c\x90\x25\xa7\xa9\x64\x10\x4b\x9f\x54\x13\xaa\xe9\xa8\x87\x0e\xbe\x85\x0a\xc0\x57\x27\x3e\x89\xe2\x75\x32\xb0\x54\x14\x48\x4f\x1a\x76\x79\xbc\xca\xb7\xa4\x9a\x0a\x8c\xe9\xb8\xa4\x4a\xaf\xe2\xf0\x34\x2d\x5a\xa2\xa9\xe6\xa1\x0c\x3d\xaf\x69\xbf\xf6\x5e\x17\xe0\x0e\x16\xa5\x54\xcb\x30\xa1\x23\xd8\xfe\x55\xa1\xb5\x77\x4e\x53\xad\x2d\x61\x5b\x01\xef\xd3\x28\xd9\x07\x33\x14\x82\x14\xe1\x9e\xa8\xfb\x26\x72\x8b\xec\x99\x74\x81\x49\x2d\x38\xb5\x75\x8d\xcb\x73\x0d\x2b\xfd\x0c\x0f\x59\x91\x1d\xcf\xc7\xb9\x5d\x37\x35\x10\xe2\x06\xa9\xcb\x9f\x65\xf5\xba\x28\xf4\x56\x5c\xf6\x1b\x9f\x4f\xe5\x41\x1c\xa0\xc3\xb6\x2c\x8f\x27\x68\xb2\x51\xe6\xe9\xaf\x96\x99\x4f\x0d\x0d\x1e\x72\xe1\x1e\xd4\xc5\xba\xeb\x5d\x56\x3c\x63\xda\xee\x3c\x53\xee\xec\xce\x8a\x42\x26\x6c\xf1\x1e\x14\x7a\x75\x2a\xd5\x64\xe1\xe0\x11\x15\x56\xca\xad\x35\xf1\x6a\x07\xa5\xd2\x77\x65\x05\x6f\xdd\x38\xe3\x51\x1c\x21\x26\xb3\x93\x64\xa1\x9c\x08\xcb\xc8\x95\x1d\x4f\x65\xe5\x08\xed\xee\xca\xea\x83\x38\xff\x78\xc7\xe5\x34\xb0\x30\xb2\xb7\xf6\xd9\x27\x03\x89\xb3\x80\x60\xf2\x14\x90\x5f\x06\x10\x62\x35\xfb\x7d\x39\x8b\x2d\xc4\xac\x01\x71\x1c\x04\x22\x38\x4b\x38\x1d\x08\x37\x75\xaa\xd9\x94\x33\x25\xf0\xeb\x3d\xdc\x2e\xf9\x6f\x66\xe7\x79\x42\x12\x70\x85\x7b\x6b\xb7\x97\x90\xcf\xa3\x9a\x3c\x89\x2d\x52\xc9\x61\x00\x77\xa7\x72\xe2\x4d\xf2\xd4\x29\xee\x2d\x8e\x50\x65\x4a\x14\x8b\xac\xca\xb3\x02\x06\xfc\xe4\x6d\x1b\x81\xe1\xa8\xed\xe2\x5f\x3e\xf9\xc8\x79\x20\x43\xe6\x47\x41\x25\x0a\xf5\x02\xd3\x7a\xc0\xb9\x00\x1c\xe7\xdc\xc4\xda\x75\xc9\xc8\xfd\xe5\x5c\xa5\xb6\xfe\x05\xf7\xef\x91\x54\xd4\x38\x10\xe9\xdb\x6b\x25\x98\x5f\x33\x2c\xa6\xdc\x1d\x11\xdc\x98\xbe\x44\x6b\x9b\x55\xa2\x78\x11\xb8\xaa\x8c\x3b\xd9\x37\x17\x21\xb7\xb9\xe5\xca\x06\x3e\xf4\xf8\xc1\xa4\x0a\x39\xe9\x43\xe4\xa8\x10\x7d\x1d\x77\xe6\xd2\x50\xdc\x44\xee\x33\x09\x95\xaf\xee\x6c\x7f\xe6\xc8\x17\xb5\xbb\x5b\x8a\x53\x86\x30\xc3\xf6\x73\x5f\x67\x0c\x27\x90\x66\xae\x68\x1c\x25\x3d\xfb\x66\xbd\x39\x75\xe1\x26\xae\x62\x29\x65\xc7\x9c\xff\x19\x0e\x84\xab\x44\x32\x5f\x9e\xf3\x3c\x85\xa0\x70\x25\x0c\x66\x37\xca\x5f\xaa\x73\xb9\xb8\x92\xca\x52\x96\xb4\xab\xf8\x2c\x7f\xd3\xac\xfd\xca\x35\x03\xd2\xa1\x04\xaf\x24\x1b\xa7\x8d\x93\x04\x2d\x58\x07\x42\xee\x56\xd2\x0f\x2e\xad\x95\xaf\x65\xb6\x36\xce\xb7\x8b\xac\x32\x9d\xfd\x89\x9b\xb5\x8b\x0e\xce\xcf\x01\x6d\x42\x6e\x6d\x9f\x1a\x2b\x94\x6c\x9c\xc2\x9b\xfa\x1c\x94\xe5\xa4\x35\xa7\x5b\xa7\xa6\x7d\x75\x09\x11\x84\x1c\xa2\xbe\x5e\x1b\xb9\xca\x0f\x1e\x7c\x20\x02\xc2\x50\x16\xe7\x00\xed\x32\x82\x94\x18\x58\x20\x37\xce\x70\xa7\xf3\x53\x54\x04\x54\x47\xae\x50\xf9\x21\x7b\xae\x44\x03\x98\x51\x1b\x4f\x53\x11\x80\x44\xfb\xd7\x6e\x80\xab\xa2\xc9\x9a\xcb\x68\x44\x8f\xf6\x4b\x11\x4a\xea\x99\xf6\x7e\x94\x0d\x0c\x65\xc4\xfb\x3b\x87\x10\x11\x9f\x54\x81\xdc\x0a\x41\xd6\xf3\x79\x1f\x11\xa5\x1a\x4b\x0f\xe4\x0b\x1a\x14\xfe\xd5\x49\xc4\x7c\xd1\xdd\x1f\x17\x09\xd5\x23\x60\x19\xe6\xe4\x64\x1a\x47\xe8\x69\x1c\xec\xee\xba\xc6\xfa\xb3\x72\x62\x9a\x0b\xc6\x53\xc4\x40\x3c\x23\xf8\x15\xc7\xb4\xdf\xe8\xef\xfb\x02\x3b\x11\xab\x54\x59\xba\xe5\xdd\x51\xe4\x79\xd5\xa8\xc9\x6b\xc5\xc6\x92\xbd\x66\xb5\x97\xce\xea\xf5\x7f\xa9\x48\x13\x8a\xf0\x9f\xac\xde\x95\xf9\xdb\x44\x32\x92\x8a\x54\x46\x68\x94\xff\xaf\xba\x3c\x94\xfa\x9c\x77\x20\x7e\x91\x2a\x11\xf3\x41\x42\x7c\x51\x5c\x1e\x56\xdb\x8f\x15\x6b\xa8\x48\x41\x23\x16\xe9\xfb\xee\xf6\xb0\x5c\x3d\xee\x0f\xdb\xd5\xd3\xe1\xeb\xbf\xbd\x93\x26\x38\x0d\xb8\x5b\xf0\xaa\xe7\x0f\xe9\x87\x7d\x63\x0d\x56\x66\xbb\xb5\xe0\x2b\x2f\xa5\x37\x7e\x78\x11\x30\x34\x33\x1e\x96\x8f\x1e\x78\x2a\x04\xb5\xda\xe2\x56\x76\xaa\xdd\x53\xad\x2a\xfd\xf5\x02\x26\x84\x4a\x90\x2c\xac\xf5\x29\xa3\xc3\x72\xb1\xf5\xd7\x90\x8c\xc5\xce\xc1\xb0\xca\xeb\xef\xe5\xe4\xce\x2a\xb2\xba\x6a\xab\x87\xbf\x2f\x96\x7b\xa8\x47\x20\x1c\xa1\x44\x84\x94\x11\x59\xc7\x29\x31\xc1\x2a\x0b\x25\x21\x91\xbd\x84\xbc\x05\x2a\x0d\xcd\xb4\x79\xc3\x4a\x28\xa5\x30\x09\xb7\xd9\x3c\xad\x6e\x37\x9b\xe5\xb7\xc5\xda\x67\x6c\x84\x8e\x34\xc2\x5e\x6f\x32\xd4\x7f\x5c\x56\xe5\x7b\xf7\x44\x3a\x01\x47\xaf\xd5\xc9\xe2\x0c\x61\xed\x43\x88\xa7\x3f\x83\x5b\xde\x1a\xac\xb9\xeb\x68\x9c\xa8\xd0\x32\x41\x6b\x53\x97\x8f\x65\xb3\xe8\x39\x30\xc7\x06\xac\xd0\x2a\xb6\x7a\xe8\x08\xa0\xc6\x58\xca\x20\xeb\x31\xcd\x0f\x09\x48\x29\x4a\x7b\x2f\xcf\x75\x53\xea\x4c\xe4\x77\x65\x35\xc8\x2b\x0a\x80\x14\x59\x19\x1e\x16\x8f\xdf\x16\xfb\xfd\xe2\x71\xfb\xb4\xf9\xe7\xbf\x1e\x16\x8f\x8b\x1f\xdd\xf0\x32\x81\x8d\x5f\x62\xec\x6f\x61\xae\x62\x17\xed\xca\x4f\x7d\xe1\x3b\x42\x21\xaf\x86\xe0\xec\x46\x3e\xad\xb3\xf3\x57\x53\xb6\xa8\xfc\xe1\x72\x97\x55\xe3\x01\x20\x83\x88\x21\x85\x92\x25\x45\x7a\x2a\xa7\x8e\xa5\x0c\x22\x89\x8a\xb5\xea\xdc\x94\xc6\xf8\xd3\x22\x11\xa0\x2b\x83\xd6\xd9\xc2\xf2\x60\x7d\x13\xf5\x23\xfc\x9a\x18\xc3\x92\x04\x91\xb2\x45\xea\xbf\x5a\x83\x79\x9c\x0a\x91\xc4\x08\xdc\x02\x5d\x26\x78\x2f\xea\xd7\x51\x28\x44\xd2\x94\x22\xf3\x40\x6b\xcb\x7c\xf5\x1d\x28\x29\xb7\x9c\x3b\xa6\xcf\x86\x8f\x63\x80\x92\x85\x46\xf9\x34\xa8\x65\x3a\xdf\x98\x95\xad\x9f\xe9\xda\xc4\xa1\x85\xff\xa0\x03\x49\x96\x9e\x85\x87\xca\x38\x09\x98\xa7\xbd\xaa\x44\x61\xca\xea\xe8\xe8\x66\xbb\x60\x88\x6f\x29\x18\x26\x97\xd6\xcb\x8d\xa5\x6a\xe8\xb6\x6a\x19\x4b\x81\x72\xad\x7a\xcc\x6d\xe1\x8f\x82\xc6\x34\xda\x42\xeb\x47\x78\xb7\xf5\x1b\xea\xf2\xe5\xaf\x58\x9a\xa8\x4c\x62\x12\x5b\x21\x89\x3f\xfe\xb5\xf4\x4a\xa7\x93\x6f\x96\x52\xcb\x73\x54\x40\xeb\x6a\x8f\xf8\xc7\xa9\x4c\x55\x80\xe8\x31\x93\x41\x6e\x83\xb2\xdd\x11\xcd\x3c\xa6\xe9\xda\xd1\x93\xa9\xd6\x71\xec\x4b\x07\xaa\x8b\x0d\x88\x7e\x6a\xe3\xca\x54\x1b\xe5\xd6\x8e\x06\x57\xb7\xeb\x81\xec\x5a\x72\x49\xb1\x6e\xe6\xfb\xe3\xfd\x66\xf9\xc7\x61\xbf\x5a\x3c\x74\xc9\x76\x29\x88\x2d\x4d\x11\x3e\xd4\x76\xa8\x91\x08\xd0\x1f\x4e\xb4\xb0\x89\x8a\xc6\x8b\x6d\x0d\xed\x5a\x29\x35\x49\x5c\x68\xa4\x1d\x9f\x1d\x99\x46\xf7\x66\x2a\xb4\x1a\x04\x9e\x0f\xa8\xbb\xb2\x96\x9a\x0e\x08\x05\xb2\xc2\x09\xc2\x8f\xce\x06\x16\xa0\xb1\xdb\x7a\x90\xdf\xca\xbc\x75\xc0\xf7\xe2\x97\xbf\x04\xc8\x08\x7d\x20\xab\x1e\xd4\xae\x9e\x53\xfe\x49\x2a\x41\xc5\x71\x0f\x7d\xf9\x61\x41\x0e\x43\xaf\x70\xfc\x21\xc0\x10\xe9\x0b\xae\x11\xb7\x8e\x89\xa1\xfa\x1b\xe4\xa7\x19\x6a\xd3\xcf\xbf\x90\x21\x02\x93\x8c\x27\xbc\xd0\xbe\xbc\x3d\x17\xcf\x50\x16\xeb\xdb\xf1\x23\xaa\x20\x49\x30\xfe\xf9\x15\x9a\x51\x24\xdc\x1d\x0e\x59\x10\x75\x82\xee\x18\x0a\x76\xd8\x9d\x2f\x5d\x03\x1b\x8f\xc9\xea\xaf\x50\xc0\x4e\x65\xd0\x87\xdb\x54\xc4\x15\x22\x41\x6d\xba\xba\xe3\xa2\x5f\xb7\x16\x4f\x8d\x40\xef\xb1\xbe\x26\x55\x84\x09\xe2\x36\x89\x9e\x72\xf9\x23\x90\x95\x3f\x47\x06\x68\x9d\x64\xaa\xdc\xbe\x88\x1a\xc8\x88\xc4\x97\x2a\x1a\x1a\xf4\x06\xde\x32\x78\x7f\x80\xea\x35\xef\x63\x68\xe1\x28\x08\xe9\xda\xb3\x30\x0d\x49\x6f\xf7\xa2\x17\x57\xd9\xdc\xcc\x4c\x11\x40\xfa\xb7\xab\x60\xc7\x7f\xfe\x6f\x34\xb3\x15\x63\x91\xee\x59\x84\xe5\x40\x38\x6e\xf4\xcd\x14\x13\x80\x31\x22\x97\x0e\x1d\xc1\x5a\x14\x93\x31\x82\x86\x8e\xe2\xd7\xe8\x03\x30\x63\x39\xe8\xfd\x3e\xdf\xeb\x74\x2d\x0a\x94\xca\xba\x2e\xe4\xfe\x7f\x8d\x45\x0c\xe6\x9c\x4a\x22\x0b\xeb\x3c\x3c\x43\xf3\x4d\x54\xba\x5f\x5c\x55\x1a\xc7\x76\x45\x6f\xea\x49\x5a\x4d\xf1\x30\xe2\xce\x6f\x5c\xe5\xa5\x05\x72\x8c\x3f\x22\x0f\x2d\x2e\xbf\xb5\x77\x9c\xf0\xf7\xbc\x59\xac\x38\x11\xd4\x0b\xb3\x75\x5c\x15\x5d\x77\x70\x1e\x20\x0e\xe1\x84\x13\xba\x1d\x06\x77\x95\x98\x9a\x5d\x8a\x2b\x85\x16\x9a\xf3\x56\x2d\x25\xdd\x54\xf7\x97\x2a\x41\x09\x4e\x8e\xed\xd3\x6a\xb7\x3b\x3c\x2c\x9e\xfe\x58\xed\x3b\x9e\x20\xaa\x04\x0f\xb8\x53\xf9\xb5\xde\xc1\x87\x70\x98\xf1\xdd\x85\x12\x18\x51\xf9\xc7\x59\x54\xaf\x28\xe5\xd0\x5d\xd1\x58\x20\xba\xbc\xf2\xc4\xfd\xe0\x94\x2c\x48\xc3\x2e\x6a\x7c\x2c\xdb\xb5\xcb\x51\x38\xad\xba\xf4\x8f\x92\x10\xe2\xc4\x7b\x16\x47\xd8\x22\xe7\xc8\x13\xd4\xad\xed\xfd\xc1\x32\xad\xa4\x31\x38\x87\xb0\x64\x67\x63\x1e\xb2\xe2\xdc\x74\xcb\xa5\x52\x34\x46\x27\xd3\xd2\xc3\x0e\x6d\x31\xa5\x62\x4b\x4e\xf9\x07\x9a\x7a\x9f\x04\x54\x26\x93\x56\x69\xe9\x18\x8b\xaa\x0c\xea\xe5\x28\x5c\xab\x20\x48\x51\xba\x03\xf7\x6f\x66\x3f\xf0\x13\x1c\x45\xcf\x8e\x4b\x15\x24\x71\xe8\xb5\xc6\xf7\x22\x7f\xed\x7e\x57\x8e\x32\xef\xdc\xbc\x38\x4a\x8a\xc9\x00\x32\x91\xc0\xba\xe5\xfa\x5d\x9c\xee\xa0\x7b\x13\x13\xc7\xb1\x43\x46\x22\x93\xb2\x77\x99\xfc\xe6\x71\x1d\xf6\x54\x46\xe9\x10\xe9\xfe\x56\x8b\x9f\xcb\x4d\x67\x06\x2b\x03\x89\xb6\xdb\xf4\xaf\xe6\xae\xac\x5e\x71\x64\xd9\x63\x3a\x20\xd2\x62\xad\xf1\xa2\x77\x00\x0f\xe2\x75\x72\x5d\x1d\x30\xa1\x7b\x25\x91\xfc\x14\x06\xe3\x57\xd0\x41\x1c\xa0\xe2\xc5\xfb\x4b\xd6\xc0\x7d\x56\x4f\x8c\x24\x1d\xb2\x00\xa5\x32\xb2\xfa\x16\xea\xa6\x2a\x2f\xa0\x47\x23\x5b\x87\x8c\x58\x15\x39\x7d\xcc\x8a\xdd\xb9\x3e\xb5\xd6\xb8\xb3\xe0\xfa\x10\xad\x0e\xd3\x34\xa6\x9e\xd5\xca\xd5\xc2\x0d\xad\x4c\x1d\x4a\x82\xf5\x72\x5f\xa1\xb9\x11\x85\x2d\x98\x33\x0e\xa8\x92\xfa\x36\xc6\x6a\x43\x7f\x2f\x4e\x22\xd3\xb7\xd9\xdb\xba\x8b\xf3\xe8\x88\x1a\xa4\x31\xb2\xbc\x3f\xed\x3c\x5b\xdc\xaf\x0e\xf7\xeb\x87\xf5\xbe\x6b\x92\x84\xc6\x56\x39\x9c\xc4\xb9\x86\xce\x7a\xd0\x11\x97\x28\xc9\x24\x33\xad\xa1\xea\x63\xc7\xe3\xbe\x8c\x04\xa1\x0e\x88\x89\x31\xde\xfe\x8b\x6b\x12\xa8\xd4\x22\x7d\x30\x04\xf5\xe5\x3a\x46\xad\x89\x21\x40\x7d\x56\xe9\xb4\x2e\x4c\x69\xfd\xfa\xc9\xf7\xa0\xa1\xc4\x50\xc9\xb9\xf0\x08\xf5\x99\x32\x13\x4d\x65\x82\x92\x4a\xad\xa1\xb2\x31\xb7\x20\xba\x09\xab\xa9\x16\x68\x98\xa2\xc6\xba\x6a\xd6\xc5\x5b\x99\x29\xd0\xa3\xa4\xae\x66\x01\x41\xd2\xf6\x77\xc4\x57\x1c\x4e\x65\x99\x1f\xc4\x30\x6c\xa6\x19\x84\x18\xbf\xea\xa4\xfb\xd0\x3e\x9b\x2f\xd2\xd5\x71\x4a\x71\x90\xdc\x97\xcf\x16\x8e\x52\xbf\xb7\x3e\xee\xb9\x68\xae\xe8\x56\xe7\x83\x4f\x3a\x16\x91\xec\x35\x62\x90\xee\x72\xdc\xf9\x09\xa1\x18\xc4\x71\xaa\x3f\x03\xaa\xaf\x6b\xba\xf6\xf0\xf7\xc1\x72\x83\x0d\x49\x27\x3c\xf5\x99\xf0\x0e\x0d\xed\x92\x7e\xe3\xd7\x4d\x14\xb1\xd5\xc0\x3e\x98\x90\xe9\xca\xb3\x55\x53\x9d\x26\x81\x45\xbb\xbe\x94\xef\x5d\xe1\x61\x67\xf3\xeb\x94\x2b\x74\x0e\x0b\xdc\xbf\x07\xda\x6d\xdd\x94\xe3\x91\xec\xc8\x2b\xce\x55\xe5\xaa\xcf\xad\xf2\xbb\x28\x5e\xd7\xb7\x93\xae\xe1\x3a\x46\x7e\x0f\x93\x15\xda\x5a\xaf\x97\x2f\x73\xef\x27\x28\x45\xe3\xe1\xab\x25\x4d\xbf\x81\xa6\x5e\x17\x4f\xe2\xcf\xf9\x85\x5c\x0b\x46\x30\x70\xfa\xbd\xc9\xf2\xee\xd9\x44\x1a\x20\x93\xeb\x56\x34\x9d\x06\x00\xd5\x42\x49\xb4\x28\x8a\x73\x9f\x78\xe9\xdf\x58\x80\x56\x43\xd1\xd4\x65\x99\x4d\x71\xda\x5a\x52\x66\x99\x23\x9b\x17\x79\x9e\x64\xcb\xb4\x52\x56\x51\xe2\x70\x55\x74\x38\x0a\x32\x4c\x4e\x32\xd2\x92\x1c\x66\xc5\xeb\x27\x54\xeb\x93\x71\xa8\x43\x2d\x68\x3f\x91\x07\xea\xc4\x5d\x17\x68\xcd\xb4\x95\x78\x6c\xaa\x0c\xde\xc0\xe1\x8b\xdd\x51\x10\x41\x20\x06\xaa\xb9\x4f\x03\x16\x59\xd7\xc4\x48\x25\xfc\xf6\xd0\x4e\xd2\xf9\xa0\xa9\x36\x60\xd0\x86\xbf\x5d\xad\xb6\xdb\xc5\xbf\x1e\x3a\x6a\x49\x0a\x01\x09\x70\xb6\xe0\xe6\x3e\x0c\x7d\x8c\x17\x6f\x08\x48\xe8\x9d\xab\xfb\x52\xbd\x2e\x94\x1a\xd1\x21\x0c\xd7\x71\x08\x52\x83\x2e\x50\xf3\xd2\x87\xf8\xfc\x21\x49\x59\x38\x0e\x7f\xcc\xdb\x9d\x6d\x4b\x5c\xe5\xd7\xcb\xcd\x61\x71\x7b\xfb\xe4\xaf\x10\xc6\x09\x02\x2d\x6e\xee\xbf\xaf\x06\xb9\x09\x88\x94\x89\xbc\x0d\xd8\x4e\x85\x7b\x78\x03\xc7\x4c\x38\xb9\x72\xa4\x95\x07\x30\x2d\xb4\xc5\xfa\x8b\xfc\x3a\x0c\x06\x24\x50\x88\x9d\x80\x76\xe3\xbd\xc9\x2a\x3d\xb4\x31\x80\x10\x65\x02\x5f\x21\x82\x61\x9c\x01\x3d\x37\x05\xc2\x02\xe6\xd3\x9c\x16\x4a\x59\x9f\x73\x94\x8d\x47\xfc\x4a\xfb\xd3\x74\xf6\x01\x61\x52\x58\xb7\xa5\x3e\xc3\x67\xe8\x36\xa0\xda\x60\x81\x0c\x02\xbb\x82\x43\xfb\xe7\xab\x13\x1c\x1e\x8d\x30\x48\x82\x04\x4b\x4b\x2c\x32\xe4\xe7\x6a\xf5\x47\x17\xae\x86\x24\xd6\x18\xf0\x3e\xda\xe4\xe2\xb6\x2c\x3b\xe2\xcd\xae\x89\x00\x04\xc8\x59\xdc\x02\x66\xca\x47\x23\x0b\x12\xb0\x92\x73\xdb\x0c\x7e\xfd\x06\x9f\x0b\xa4\x2c\x46\xe3\xe4\xe9\x76\xf3\x61\x09\x91\x6f\x0a\x14\x77\xb9\xd6\x96\x3a\x58\x75\x93\x75\xd1\xc0\x33\x54\x07\xff\xd9\x36\x6f\x50\x99\xbc\x7c\x1f\x15\xde\x01\x8f\xba\xa1\x6a\x53\x04\x0f\x67\xcc\xb6\xaa\x31\xd0\xa3\xdf\x50\x81\x47\x14\xad\xf7\x12\x41\x63\x59\xde\x2d\x52\xc0\xdb\xdd\xab\xcb\xaf\x20\xdd\xe3\x15\x1d\x0a\x12\xad\xa7\x8e\xca\xe4\xb6\x12\xcf\xe5\xe4\xbb\x8a\xd0\xaa\x89\x98\xfc\x72\xdb\xae\xee\x1f\xc2\xc1\x41\xd0\x00\x79\xbb\x33\x0d\x45\x93\x99\xcb\x34\xe5\x0c\x02\x08\x58\x79\x89\x0a\xc4\x71\xd5\x2d\x16\x20\x89\x49\xdc\x78\xdb\x9c\x7a\x6d\x35\x7f\x7e\x2f\x6c\xf6\x9f\xc4\x5f\x4b\x72\xc0\x98\xe9\xe1\x54\xf9\x30\x00\x5a\xd2\x7e\x0c\xcc\xae\xe5\xa0\x98\xd5\x17\x79\xf7\x08\xd0\x21\x5a\x0b\x54\x2c\x30\x1e\xd9\x88\x5f\xc8\x44\xe2\x7f\x16\x36\xac\xb7\xdc\x3c\x6c\x57\xfb\xf5\x7e\xbd\x79\x3c\xfc\x58\x3d\xed\xd6\x9b\xc7\xae\x89\xe6\x98\x7c\x5b\xdc\xdf\x6f\x96\x07\x54\xe2\x5e\xaf\x7c\xf9\x20\xe8\x20\xf5\xdc\x72\x1d\x39\xec\x1c\x6f\x16\x68\x4a\x1d\xfc\xc3\x4e\x87\x65\x59\x37\xe8\x77\x7a\xea\x5c\x57\x1a\xde\x89\x97\x53\xd0\x89\x15\xd5\x16\x5a\xf7\x85\xf1\xee\x18\xb4\x06\x92\x3d\xb6\x2c\x8f\xc7\x73\x91\x35\x17\x14\x18\xfb\xa0\x77\x40\x24\xdc\xe5\x41\x30\xb7\xed\x6c\xa5\x71\x23\x43\x98\x2d\x1a\xad\xdb\xcd\xb3\x35\xca\x9a\x66\x1a\x55\x03\xc3\x95\x07\xc2\xac\x4e\x59\x5d\x6a\xb8\xc1\xec\xea\x50\xbe\x7c\x7c\x73\x13\x06\x80\x16\xfe\xfa\xb5\x80\xf7\xa1\x45\x6c\xc2\x30\x62\xc3\x8d\x66\x29\xf4\x5b\x7d\x0f\xa6\x59\x17\x76\xcf\xe9\x7d\x18\x13\x46\x02\xb5\x49\xb3\xda\x69\x9e\xce\xd1\xb6\x99\x90\xc6\x96\x4f\xf3\xe5\x6c\x4c\x0e\x53\x5e\x16\x13\x4a\x89\x1d\x87\xe8\x10\x81\x4d\x7e\x2b\x70\x62\x48\x4c\x84\x2b\xeb\xca\xe6\xa8\x72\x5c\x33\x9a\x90\x0e\x49\x81\x28\x8a\x83\x09\xfd\xca\x66\x68\x22\xb1\x6c\xce\x9a\x09\x65\x75\x74\x9c\xe6\x93\x08\x80\xa1\x69\x84\xd6\xd7\xf1\x72\x2f\xea\xe6\x09\x26\x65\xda\x86\x05\x06\x57\xab\x22\x53\xaf\x85\x38\xc2\xc6\x8c\xbf\xa4\x61\x61\x6c\xf3\xfa\x9e\x54\x67\x76\x2f\x33\x2c\xd4\x98\x60\xdb\x41\xb3\xcc\x9a\x4b\xa7\x4d\xfb\x99\xed\xf1\x79\x28\xcd\xb0\x38\x41\x8f\x0d\x4d\x56\x84\x47\x0c\xf3\xb3\x5d\x23\x8d\xb5\x2a\xbb\x97\xf2\x34\x79\xb5\x38\x10\x88\xb8\xdc\x3c\xae\x0e\xab\x87\x4d\x67\x10\x98\x38\x8c\x12\x87\x3d\xc4\xa1\x36\xb2\x57\x4d\x4c\xc2\xc0\xc5\xd7\x1f\xb2\x02\x95\x05\xca\xf7\x2e\xa6\x6b\x62\x02\x60\x25\x12\xea\xf3\x71\x2c\x08\x48\x4d\x12\x10\x6b\x5c\x22\x78\xaa\xfb\x35\xd5\xc2\x03\xa4\x1d\x38\xe1\x05\x26\xdc\xeb\xd4\x24\x92\x72\x17\x2c\x76\x58\x18\xc4\xf6\xae\x8b\xd5\xb9\x2a\x97\x83\x30\xbb\x49\xb4\xc6\x1d\x29\x2f\x9b\x8d\xc1\x2c\xd5\x67\xd2\xe5\xd4\xa4\x61\x92\x76\x82\x3d\x96\x49\xad\x1c\x08\x2b\xff\x27\x0c\xfc\x90\x4e\x09\x45\xcc\x7e\x01\xa0\xeb\x7d\xd6\x65\x22\x4d\xaa\x22\x6d\x3c\x37\x6a\x76\xea\xd2\xb1\x5d\xaf\x71\x1e\x47\xce\x92\xeb\x14\x57\xac\x7d\xe2\x1b\x28\x4b\xc5\x5c\xc0\x7b\x7b\xf7\x59\x78\x82\x11\x69\xe0\x32\x78\x85\xfe\xa3\xfa\x20\xcd\x6f\x84\xe2\x98\x81\xd3\xa0\x3a\x7a\x31\x23\xb5\x55\x32\xf8\xbe\xbb\xfd\xb9\x5a\x77\xbf\x82\x46\x03\x07\x11\xd5\xeb\xfa\x06\xb2\xe2\xd9\x67\x5a\xab\x01\xb3\xc2\xfc\x8d\x54\xca\xb0\x4e\xe2\x28\x7e\xf5\x41\x1e\xa3\x5b\x8f\xd0\x52\xba\xd4\x3d\x7a\xce\x80\x49\xf1\xa9\x9a\x97\xaa\x7c\xaf\x7f\xbe\x40\xf1\x04\xb6\x9a\x2d\x2b\x9e\x17\xfd\xe8\x33\x92\x60\x92\xe4\x41\xfc\xda\xf4\xba\x57\xd4\x18\x88\xd1\xe0\x69\xad\xbb\x1e\xfc\x3f\xc6\x43\x8d\x9e\x8f\x05\x01\x8b\x30\x8e\x9f\x89\x4d\x61\xcd\xd0\x6b\xb2\x88\xde\x08\x60\x41\x14\xda\x2c\xac\x50\xcd\x59\xe4\x5d\x08\x91\x05\x51\x12\xa2\xa3\xb2\x44\x88\x76\xf7\xab\x04\x4f\x05\x8b\xee\x69\x06\xf5\xcd\x65\xe0\x83\x8d\x06\x30\x0b\x48\x1c\x21\xe9\x39\xc2\xc0\x71\xcb\x8c\xfc\x95\x88\x88\xad\xa8\xc7\x51\xe4\xf9\xa9\x2c\xfe\xcc\xba\x23\xda\x32\xcf\x15\x2e\xa5\xb4\xcd\x41\x3f\x03\x7a\xf1\xb5\x6f\x43\x23\x1b\x21\xfa\x2f\xca\x81\x21\xb3\x81\xc7\x4b\xfe\x45\x48\xd5\x5f\x80\x06\x28\xcc\x66\x55\x3c\xbe\x7e\x7f\xdc\xcd\x8e\x2c\x16\x50\x69\x10\xaa\x2e\x9a\x46\x28\x8c\xaa\x64\x7f\xc2\x8d\x15\xf7\xba\x82\xfc\x8c\xdf\x9e\x1a\xea\x19\x59\xef\xaa\xb2\x68\x56\x0e\xab\x32\x23\xaf\xc7\x02\x16\x24\x08\xcd\xb5\xf9\xca\x4a\x7e\xf0\x38\x8c\xa4\x9e\x7a\x70\x53\x60\x8d\x52\xbb\xd7\x77\xfd\xc2\x62\x82\x7d\xb7\xae\xd5\x71\xde\x5f\x73\x0d\xe3\x50\x29\x17\xdd\x47\x0a\xa9\x9b\xfc\xdc\x8e\xfe\xc5\x47\xe3\x2a\xa6\x36\x97\x06\xbf\xb2\xba\xf9\x3c\x27\xc5\x82\x58\x58\x8c\xdc\x3b\x64\x0f\x36\x25\xf9\xb5\xf4\x92\x00\x2c\x48\x22\x03\x36\x94\xbb\xfe\xd1\x81\xb6\x59\x90\x88\x34\x82\x4e\x49\x13\xcd\xd6\x1e\xc7\x36\xee\xab\x04\x38\x72\x56\xb5\x3b\xe0\x5d\x59\x2d\xf2\xfc\xcb\x60\x48\x73\x19\x22\x27\xc8\x3b\x64\xcf\x2f\xc8\xf5\x80\x9e\x11\x32\x20\xf9\x26\x26\x40\x4a\x8e\x63\x1f\xb2\x1d\xea\x6d\xb1\x40\x86\x06\x93\xc3\x78\x89\x97\x3e\x85\xc1\x02\x49\x13\x5f\xb5\xdd\x3a\x62\xd7\x2a\x3f\x2c\x90\x4a\xa7\x7a\xa8\xcc\x84\x9a\x4c\x70\x2f\xda\x1f\x3c\x43\xf0\xaa\x70\xb4\xf2\xf6\x7f\xbb\x2f\xa8\x38\x57\x56\x0d\xd5\x6a\x48\x9c\x9b\x0c\x86\x38\x59\x0f\x97\xbd\x8a\xd4\x0c\xc7\x8b\xa3\x14\x67\x81\x4e\xb5\x12\x9d\x90\x96\x4d\xad\x0d\x03\xbc\x2c\xd0\x3a\xb0\xb8\x71\x91\x2b\x1c\x4a\x16\x20\xf1\x21\x32\xbc\x7f\x4d\xa0\x26\x1a\x92\xba\x76\xaa\x69\xeb\xed\x90\x95\x94\x05\xa0\x43\xef\x34\x3e\x88\x5f\x37\x30\x42\xbe\xb5\x87\xad\x77\xf4\xdf\xd3\xc5\xe1\x54\x58\x18\x24\x1c\x43\xca\x3d\x8a\xd8\x4a\x02\x67\xc5\x33\xa2\x23\xea\xae\xa1\x49\x91\x19\xc5\x21\xd1\x07\xb7\x6d\x0f\x69\x47\xdf\xff\xea\x40\xd1\x7f\x95\x77\x71\x67\x86\x5c\x22\xfb\xa4\xd0\x7a\x28\xae\xf1\x9b\x49\x1a\x77\x91\x28\xa4\xdc\x19\xef\xf7\xa3\xb2\xe4\x49\xb3\x58\xa3\x00\xc4\x7d\xf9\x8c\xd5\x93\x1f\xde\x65\x38\x7d\xc3\x48\x10\x1b\x0f\xd8\x3c\x7e\xdf\x3d\x6d\xee\xef\xbf\x74\x07\x52\xf4\x5d\x8f\x97\xf2\xa5\xdc\x77\xcc\x73\x2c\x24\x24\x46\x8c\xc0\xa9\x2a\x4f\x2f\xa8\x00\x36\x1b\x8b\x64\x21\x49\x19\x92\xcb\x0d\x4a\xa2\xba\x6b\xa4\x9a\x27\xce\x2f\x10\x5d\xfe\xe2\x3f\x74\x5e\xdc\x87\x85\x84\x5b\xfa\x2e\x44\xed\x00\xa0\xbc\xd4\x20\x63\xc6\x42\x22\x22\x5b\x75\x68\x21\x73\xdb\xaa\x2c\xaf\x88\x2e\xfe\xf3\x7f\x7f\xbb\x42\x8a\x74\xa7\x13\xda\xe3\xf6\xf5\x59\xf9\x0a\x9c\x81\xce\x6f\xf7\x5e\x34\x21\xa8\x79\x73\x38\x09\xf5\xea\x68\x5b\xb7\x6f\xa7\x39\xcf\xe2\x2f\xbe\x2c\x8b\x24\xd6\x3e\xdd\xfe\xc2\x8c\xd1\x68\xd0\xc5\x21\x0f\x49\x8f\x6a\xf2\xbf\x4a\xdb\xf9\xbb\xd5\xb2\x5d\x34\x7a\x2e\x09\x16\x26\xc4\xaa\xb1\x2f\x4b\x47\x9d\x3c\xba\x5c\x12\x1b\x8c\x1c\x21\xf4\x6e\x81\x1e\xe4\x76\xb3\xb9\xf7\x8a\x29\x3f\x56\xbb\xfd\xea\xb6\x6b\x9c\x80\x19\xd0\x8e\x2c\xcb\x6a\x84\xbd\x67\x61\x1a\x1a\xdc\x1d\xf6\xab\x7f\xde\x8c\x6e\x93\xc6\x0a\x4b\x89\xc5\x59\x67\x0d\x2a\xaf\xfb\xaa\x4e\x8b\x2c\x9d\x0b\xb0\xb1\x30\xe5\x21\xfa\xed\x27\x71\xf1\x98\x9e\xf9\xf9\x24\xa8\xe5\xb0\xb2\x26\x97\xde\x97\xf7\x99\xad\x3a\xc6\x2f\xc4\x5c\x2b\x25\x14\xe2\x56\x5d\xe0\xdd\x22\xec\xc7\x77\xd4\xca\x92\xa7\xa1\x9b\x3f\x94\x28\x4e\x5d\x03\x88\x80\xf4\x45\xa4\xb7\x60\x30\x6d\xff\x97\xdf\xb7\xdf\x3d\x42\xa0\x14\x57\xcc\x51\x12\xf7\xae\xac\x90\x0f\x72\xfc\x5a\x40\x55\xe4\xf5\xcc\xe0\xf9\x39\x87\x9b\x72\xa4\xfb\xc0\x42\x88\x25\x02\x04\xb1\x08\xf2\xa9\x2c\x8f\x93\xf7\x01\x93\xc6\x36\x3b\xf5\x8e\xb0\xa0\x89\x3d\xe1\xfc\x4a\x16\x1a\x12\x06\x69\x6f\x5f\xee\x90\x1b\xb4\xec\xc9\xdb\xa6\x6c\x81\xfe\xb4\x14\x22\xb7\x8e\x7d\x6a\xd6\xb2\x28\x08\x2c\xdf\xe1\x5b\x06\xef\x76\x81\x1d\x8c\xd1\x28\x20\x04\x53\x92\x4f\x8b\x7f\x75\x3f\x25\x5c\x2b\x74\x6b\x9c\xee\x7d\xf7\xbb\x40\xb0\x9b\x83\x73\x94\xe5\x28\xdb\xc5\xa2\x30\x52\xa9\xa5\x5c\x80\x51\x0d\x39\x8b\x42\xae\x59\x37\x48\xbc\x13\x3e\x7a\x9f\x28\xd4\x61\xe2\xa4\x36\x37\xc5\xb2\xcc\xcb\x6a\xb0\xef\x47\x51\x10\x20\x48\x14\x89\x3c\x0f\x27\x51\x35\x87\xae\x9c\x65\xfc\xb6\x84\x82\x72\x2a\x05\x43\x9d\x4f\x16\x11\x50\x48\x04\x6e\x9e\x07\xda\xb6\x2c\xa2\x01\x93\xc1\x40\xd6\xc9\x85\x44\x3e\x43\x12\xfd\x75\xe2\xe4\x13\xaf\xd7\xdf\x36\x0c\x12\x37\xbe\x7a\xea\xe7\xc1\xe1\x44\x20\xc7\xc0\xbb\x28\x9a\x7d\x79\x03\x3f\x5f\x3a\xb7\x93\x45\x54\x03\x4e\xa6\xb2\xb0\x49\xe7\x3b\x91\xe5\x33\x0c\xf2\xae\x35\xd6\xb0\x74\x75\xca\x5e\x76\x04\xc9\x25\xf3\x7c\x7a\x5f\x96\x0a\xc4\xb3\x5a\x30\xee\x22\xcf\x11\x44\xe0\xd7\xf4\x88\xe9\x34\x71\x88\xde\x4d\x25\x54\x0e\x48\xae\x88\xda\x4a\xa3\x91\x10\x33\x4b\x5a\x56\xbf\x94\xef\xa3\x65\x2a\x4a\x28\x71\x8a\xc8\x18\x9c\x2b\x1a\xa8\x96\xd5\xe5\xd4\x94\xbe\x01\x0f\x35\xe6\xf8\x70\xdb\x18\x54\xe2\xb0\x88\xa7\xd4\xaa\xfb\x34\x42\x66\x58\x54\xe6\x0e\x08\x1a\x0a\xcf\x25\xe5\xbf\xba\x4d\xb0\x0d\x43\xc7\x2c\x12\x31\x0f\x1d\x3c\xe2\x6b\x59\xea\xc9\xab\x0b\x45\x42\x27\x97\xa8\x67\x09\x99\x7c\x15\x13\x8b\x64\x12\x5a\xc4\x94\x2d\x9f\xe8\x09\xc2\x1d\x0e\x7e\x72\x65\x15\x72\x14\xb6\x3c\xdc\x96\x67\x99\xc3\x6d\x87\xd6\x64\x91\x8e\xb4\x97\xe7\xde\x42\x55\x4f\x02\xb1\x2c\x02\x92\x62\x81\xe9\x3f\x6f\x7e\x7c\x43\x67\x6d\x1e\x59\xc0\x22\x90\x16\xc7\xbd\xda\xb7\x3e\xd3\x44\x6b\xf4\x83\x31\x68\xc2\xc8\xaa\xcc\xb4\x5e\xd6\x4f\x80\xd7\x19\x02\x37\x16\x99\x28\x31\xcc\x63\x85\xd0\x8c\x99\x21\xf7\x63\x91\x49\x23\x0b\x8b\x03\xf5\x62\x79\xf5\x5a\xef\x12\x43\xb0\xfe\x65\x0d\x00\xee\xad\xc2\xaa\xa2\xce\x63\xfb\xc7\xcf\x48\x82\x08\x70\x38\x20\x01\x67\x56\x16\xeb\x31\xfc\x94\x91\x40\x59\x15\x29\xcf\x6d\x73\x38\xbd\x96\x57\x9f\xaf\x0f\x80\x32\x12\xc6\x29\xd2\xa3\xfb\x8c\x1b\x02\x87\x7b\x9d\x13\x46\x70\x94\x5b\xc7\xf6\x4f\x57\x64\x3f\xc6\x97\x33\x12\xc5\x29\xf7\x42\x53\xed\x96\x8d\x55\xa8\x11\x1d\x4d\x02\x12\x81\x46\x58\x9c\x38\x37\x65\x95\xfd\x29\x74\x59\x89\xc7\x73\xa1\xc4\xc2\xfe\x50\x9e\x7d\x0f\x89\xd9\x84\x01\x23\x24\x26\xe8\xc0\x37\xe5\x0d\x89\xc6\x99\x9f\xd9\x57\x23\xc6\xf8\xc8\x53\xbb\xa5\x3d\x96\x4d\x66\x32\xbb\x4a\xd6\xb8\x9a\xb6\xf6\x96\x5f\x9b\x52\x67\x72\xb9\xef\x4c\x68\x64\x81\x91\x4e\x9c\x01\x61\x2f\x33\x81\x52\x46\x68\xa2\x94\x95\x17\x69\xce\xa7\xd6\xe0\x12\xcf\x76\xb4\xcd\x7f\x41\x9a\xda\xf0\xfa\xd8\xe0\xfe\x31\xc2\xc9\xff\x9e\x71\x46\x58\x14\x93\x7e\xf1\x70\x83\xfc\x41\xfc\xfa\x09\xd9\xe4\x03\x31\x6a\x95\x4d\x71\xc3\x69\xb7\x3b\x4f\x72\xef\x8f\x73\xea\x01\x07\x96\x3d\xc2\x19\x97\xbb\x7e\x59\x21\x4c\x75\xe5\x0b\xfd\x47\x0e\xc7\xdf\x98\x41\x62\x85\x81\xc5\x11\x6c\xb8\xe1\xc3\xdd\x78\xfa\xe5\xdc\x15\xe2\xc4\x26\xb4\x11\x75\x31\x7c\xc4\x38\xa5\xb4\x47\x35\x7a\x15\xe4\x8d\x44\x02\xee\xd1\x43\xc4\xda\xca\xb3\x7b\xca\xb6\x6d\x9f\xf0\x62\x24\x86\x08\x33\xb2\x9b\xe5\x7e\x31\x5a\x69\x49\x62\x02\xf4\xd5\x25\x34\x77\xee\xcc\x19\x2c\x14\x23\x69\x60\x53\x66\x5f\x37\x9b\xaf\xc3\x5d\x9d\xa4\x91\x15\xec\xb5\x9d\xfc\x0e\x70\x05\x25\xf4\x0d\x63\x4b\x26\x3f\x92\x8b\x24\x5f\x26\x8d\x14\x8f\x3d\x2c\xd3\xb6\xb8\xd2\x79\x64\x84\x07\x16\xcf\xd4\x7e\xfb\xa6\x1c\x3d\x0d\x17\x5c\xd9\xfe\x32\x15\xd4\x2f\xdb\xb3\xcc\x33\x75\x67\x33\x01\x76\x6d\x15\xf9\xaa\x79\x19\xb1\x25\xfb\x53\x35\x45\x63\xd7\x72\x89\x66\x7f\xc2\x98\x41\x85\x11\x41\x53\x63\xeb\xfc\xef\xce\x05\x8e\x97\x27\xfc\x2a\x8b\xab\x13\x86\xd3\x51\x30\x95\x3a\x8a\x2c\x4c\x94\x37\x22\xef\x36\x42\x22\x78\x20\xfb\xb1\xbc\x6b\xca\x13\xf2\x93\x17\x8f\xf0\xcb\xe6\x57\x07\xe6\x0f\x11\x42\x20\xc1\xcb\xc3\x6e\xbb\xcd\x85\x02\x2b\x21\xfb\x5b\xf9\x07\x46\x64\xc8\x63\x3f\x8e\x6d\x40\x04\xe5\x73\x51\x41\x76\x70\x0f\x19\x5b\xf9\x95\xba\xf5\xe1\xa5\xa8\xeb\x76\xc1\x9a\x7c\x23\x19\x5b\xb5\xa8\x5c\xd4\xce\x00\xe8\x70\x3e\x8c\xc8\x84\x0a\x17\x13\xb6\xf8\xcb\x51\x39\x12\x23\xd2\x30\xac\x8f\xb3\xee\xfc\x5c\x6a\xb5\xff\x22\x2a\x88\x40\x0d\x34\x4a\xaa\xcb\x94\x7b\x8f\x11\x15\x6b\x4f\x22\x62\x59\xa9\xba\xd4\xfc\xa4\x9d\xa2\x18\xb2\x71\x24\xd5\xa3\xa9\xa3\xb4\x8d\xc8\x3c\xdc\x2f\xfd\x63\xea\x40\x23\xf1\x89\xdf\x1f\xec\x36\xb5\x7f\xa9\xca\xf3\xf3\xcb\xb6\x2a\x7f\x5d\xd1\x95\x4d\x9e\x5d\x9b\x20\xb2\xdc\x66\x5d\x5c\x8c\x80\xb4\xf0\x12\x8f\x5b\x9a\xf8\x54\x73\x2a\x33\xfe\x4c\x15\x63\xfd\xb0\x14\x8d\x7a\xb1\x92\x27\xc3\xbc\x88\x77\x23\x88\xa1\xb6\x36\xbb\xb2\xa4\xf4\x4f\xc2\xa7\x30\x51\x00\x07\x51\x4f\xaa\x3c\x9e\x72\x70\x0c\xa0\xf3\x2b\xac\xd1\x01\xed\xa5\xae\xe1\xf2\x84\xe2\x4f\xd3\x36\x29\x32\x48\xd8\xbc\x66\xef\xbd\xba\xdb\xd1\x00\x62\x24\x10\xc8\x1e\x1e\x10\xcd\x02\x79\x3e\xc0\x19\x30\x1a\xc6\x80\x51\xa9\xb7\xb2\x81\x45\xf7\xa3\x4c\xb1\x3a\xe9\x90\x83\x69\x96\x2f\x59\x3e\xf2\xfd\x68\x44\xb9\xad\x3c\x87\x1c\x9e\xd1\x70\xb4\x3c\x9a\x36\xf6\x73\xad\x1d\x32\x9e\x02\x34\x8a\xa5\xb0\xf2\x32\xc8\xe0\xed\x76\x8e\x4d\x85\x08\xc4\x01\x01\xfa\xec\x07\xf1\xd7\x48\x24\x8d\xbc\x10\x04\x46\x7b\x4a\xf3\x50\x6a\xac\x1f\xf8\x09\x3e\x5f\xc0\x68\x64\xe2\x34\x18\x64\x26\xaf\x59\xba\x18\x25\x54\x62\x00\x7e\x5f\xb6\xae\xa5\xcd\xe9\xef\x20\xcf\x7b\x77\x85\xb2\xd8\x60\x65\xc7\x51\xfc\x52\x5d\xe4\x9e\xb2\x24\xc4\x71\x64\x57\x8d\x47\x51\xa9\xf2\xb3\x50\x30\x65\x26\xc4\x38\xde\xa6\xc0\x70\x06\x96\x2b\xdc\x94\xe5\xeb\x8f\x20\x24\x72\x54\xf3\xdf\xb6\x65\x28\x44\x56\x97\xb9\xbe\x2b\xab\xbb\xb2\xea\x5f\x2a\x0e\x02\x23\x06\x86\x7f\xf6\x27\x58\xf6\xed\x1c\xaa\xeb\xc0\x17\x8d\x29\xd5\xac\x2f\x8b\x73\xb0\x7e\x17\xc6\x8f\x7c\x23\x16\xa1\x1d\x31\x34\x07\x3f\xe9\xff\x38\x0d\xd0\x9c\x72\xae\x89\xe5\x90\xee\x03\x58\x34\x16\x61\xe4\xa3\xde\x58\x72\x62\x8f\xce\xf5\x4a\x0c\xa1\x90\xbe\xbe\x76\x08\x51\x62\x34\x0d\x08\x96\x15\x3f\xed\x97\xcb\xcd\xfa\xd1\x12\xe5\x7d\xd6\xc3\x29\x4b\x90\x11\xff\x98\x15\x5f\x45\x4d\x17\x4a\x75\x2b\x1e\x4d\x95\x25\x30\xf4\x90\xcf\x4f\xd7\x0d\xca\x43\x6b\x68\xbb\x41\x3a\x7d\x32\x1e\x6a\x34\x35\xfa\xb0\xe9\xdf\x77\xfb\xeb\xfe\x9a\x5e\x94\x6a\xf4\x6a\x4c\x96\xe7\x37\xe7\x8b\xad\x57\xf9\x4d\x64\xba\xbf\x04\x8b\x49\x17\xc8\x7b\x10\xc5\xc5\x87\x4d\x26\x58\x0e\x46\xb9\x02\x4c\x8a\xb8\x08\xdc\x4e\x14\xaa\x39\x4f\xa3\xab\x1d\x17\x1e\xb6\xc7\x1d\xa1\x41\x22\x3c\x9f\xa8\xab\xb7\xb3\xca\x58\x8c\x72\x43\x31\xf5\x80\xa5\x63\xc7\xd6\x3e\xa8\xa1\x6a\x26\xf4\xae\xfe\x23\x8d\xce\x14\x29\xc3\x60\xa2\xbf\x05\x1a\x42\x99\xcc\xe1\x83\xa8\x16\x15\x3a\x41\x56\x11\xd4\xa6\x7d\xdc\xff\xf8\x3e\x8f\x5b\x62\x54\x0a\x89\x9d\xe3\x4c\xd2\x76\x57\x9d\x6c\x9a\x54\x07\x34\xe2\x9d\x02\xd9\x4d\x59\xe6\x28\x41\xe6\xb3\x65\x54\x87\x29\x95\x7e\x1f\xcb\x14\x5c\x95\x15\xff\xe7\xff\xa6\x41\x23\xaa\xa3\x04\x23\x59\x36\x6a\x61\x13\x8b\x1f\xda\x9b\x53\xfc\x1f\xa3\x9a\x25\x1e\x30\xd6\xa7\x05\xa9\x4e\x18\xf2\x8f\xbc\x94\xad\x29\xda\x88\xa6\x9e\xd0\xbc\x33\xaa\xa5\x41\x23\x6b\xf5\xb0\xde\xed\xd6\x9b\xc7\xc3\xdd\xe6\xe9\xb0\x5b\xdc\xaf\x76\xfb\xc5\xd7\x55\xec\xaf\x04\xb1\xa5\xf7\x7c\xf6\x6a\xa7\x37\xae\x22\xc3\x1f\xd7\x56\xb1\xde\x29\x88\xfa\x5a\xd8\x29\xac\xd8\x26\x22\xda\x75\x5f\xe6\x42\xbd\xde\x94\xbf\xc6\x76\x19\x0b\x65\x2c\x63\x07\xc0\xb6\x1b\xc3\xaa\xe8\xd9\x4f\x18\x0b\x75\x28\x93\x1e\xf9\xb1\x2f\x51\x1b\xc9\x1f\x8d\x84\x4f\x7f\xbf\xcf\xf7\xe0\x27\x72\x80\xad\xef\x6e\x41\x59\xe8\x26\xb6\xfb\x91\xbf\x2c\x89\x38\xc6\xef\xef\x37\xcb\x3f\x56\xb7\x08\xf5\xeb\x68\xc3\x5b\xf3\x40\xe1\x84\xdc\x7f\x1b\x5a\xaf\x8c\x06\x01\xe6\x3a\x5c\x18\x4a\x1c\x4f\x22\x7b\xbe\x26\x1d\x1a\x2e\x3d\x8c\xe9\x18\x4d\x7b\xcc\xdb\xcd\xc7\x71\x59\x1c\x18\x5c\x89\x8f\xf7\xa5\xd0\x8b\x42\x3f\x21\x97\xea\x97\x49\xa3\x38\x20\x71\xaf\xfa\x82\x35\xa2\xe3\x97\x8d\xb5\x8c\x99\x47\xa8\x3f\x64\x9d\x22\x09\x63\xb1\x21\x98\xb4\x7c\x12\x15\x2c\xd1\xa6\x71\x07\x12\xa6\x7d\x39\xce\x13\xbc\x95\xaf\xb3\x12\x3d\x8c\xa5\xdc\x4a\xcb\xb9\x5f\x07\x64\xd8\xa3\x77\x4d\x21\x54\xde\x30\xf1\x61\xf9\xf1\x23\xf2\x94\x5a\x6a\x04\xb4\x91\x1e\xb2\x5e\x9f\x67\xb6\xf3\xb8\x4e\xb5\x07\x12\xe7\xe2\xd8\x95\x9c\x31\x26\x84\x31\x3e\x6b\x86\x00\xbb\x43\xd5\x5a\x41\x07\xd1\x34\x70\x3c\x7d\x90\x44\x65\x42\x86\x98\xd5\x5a\xbc\x94\x65\xee\x04\x2c\x7e\x87\x60\xe0\xf7\x16\x61\x26\x20\x42\x43\x75\xb7\xff\x87\xcd\x66\xde\x0c\x00\x6d\xbe\x8d\x49\xb1\x56\xce\xfd\xda\xfa\x3e\xce\x51\x70\x0d\x64\x6c\xf9\xa9\x44\x9e\x3b\x13\xa6\xfb\x5a\x12\x18\xc6\x59\x04\x92\xe8\x3e\xc2\xfb\x36\x17\xc5\x35\x4d\xe4\x07\x99\xab\xb9\x9d\x91\x49\x30\x1e\xca\x1b\xa2\x47\x73\x85\x48\x65\x4c\xd1\x84\x8d\x37\xb5\xb6\x91\x55\x44\x1a\xc7\x87\xe6\x85\x18\xa7\x56\x02\xd3\x29\xe0\x7a\x7c\x38\x55\x59\xd1\x2c\x96\xe5\xb9\xaa\xa7\x37\xd5\xd2\x8a\xc4\x21\xd6\x34\x3a\x08\xa4\xc4\x7d\x82\xf6\x09\xd0\xb7\x3b\x14\x28\xfc\x8e\xbc\xf2\x87\xfa\xa5\x3c\xe7\x1a\x53\xbd\xbe\xaf\x20\x66\x58\x8c\xe7\xc2\x7f\x96\x16\xd7\x36\x9f\xdc\x09\x04\x45\xe8\x8e\x04\x55\x1e\xe1\x5b\x59\x8f\x79\x0d\xaf\x15\x81\x3e\xe9\x4e\x43\x22\x22\xfc\x14\xbc\x39\x57\xc5\x18\x7b\xcd\x98\xa1\x3c\xf5\x5c\xd8\xce\x13\xaa\x3f\xe1\xcf\x60\xcc\x00\xc5\x13\xd0\xb5\x18\x09\x7f\xcc\x8d\xcd\x7e\xdf\x8e\x03\xc7\x21\x87\x16\x81\x45\x72\xdb\x1a\xd9\x95\xea\xec\xb1\x38\x10\xd6\x5e\x41\xde\x87\xf1\xd4\x1f\x3f\x47\x1c\x68\x82\x8b\xcb\x4b\x59\xd5\xb0\x7b\x29\x61\x82\xfd\x9a\x34\x0f\xe3\x30\x70\xa1\xf3\xe5\x66\xf3\x19\x15\x07\x8b\x43\x6e\x49\x91\xe1\x08\xd5\x33\x14\xea\x32\x25\xf5\x9e\xb6\x57\x01\x0c\x15\x10\x6c\xd9\xd8\x8c\xaa\x39\x8b\x89\xb6\xb0\x24\xbb\xde\x2c\x2b\x61\x50\xe5\x60\x2c\x87\xe7\xda\xd2\xc8\xc2\xf7\x3c\x76\xfa\x06\x9a\x91\x4a\x7f\xdb\x42\x19\x0b\xc9\x39\x9d\x06\x02\x83\x57\xd7\x01\xd6\x6d\x87\x58\x85\x33\x0a\x26\xc5\x54\x04\x29\xf4\xcc\xb8\xfe\x53\x30\x25\x30\xf0\x2a\xcf\x97\xdd\x4b\x76\x1a\xd6\x64\x76\xa5\x99\xe3\x0b\x31\x80\xc4\x46\xb8\x5d\xcc\xa6\x44\xa6\x3c\x84\xa7\x7f\xb6\x27\xc5\x71\xcc\x70\xd5\x87\x5f\xa7\xac\xc2\xc9\x3c\x04\x67\xc4\x09\x0d\xfa\x4a\x27\x9b\x19\xf8\x99\x35\x2f\xe5\xb9\xb9\x05\x95\x1d\x85\xc7\x29\xb7\x2d\x01\x43\x1e\x37\x65\xa1\x5f\x33\xf5\xfa\x97\xdc\x32\x23\x8b\x2f\x4e\xa9\xd5\xcc\x2e\xab\xec\x39\x2b\xda\xe9\x32\xe9\xca\x34\xb5\xc0\x64\xa4\xcb\x2e\x34\xfc\x02\x6d\x85\x20\x3e\xe2\xba\x9d\x9c\x6e\x34\x6a\xa1\xf8\x6a\xd8\xa8\x43\x2e\xb3\x98\x03\xc3\x59\xef\x45\x58\xb7\xed\x72\xd6\x75\x01\x37\x0c\x31\xad\x27\x1b\x91\x1c\x97\xbd\xb7\x87\x55\x20\x3b\xf0\xd2\xa7\x3b\xc8\x79\x44\x2b\xe8\xce\x17\x24\x4e\x9d\x3f\xd2\x1c\xae\x10\xe9\xae\x91\x8c\x22\xe5\xec\xb3\x43\x05\xaa\xac\xf4\x61\x20\x81\xc6\x62\x19\x93\xb4\xe7\x0c\xbb\xf1\xa3\xcd\x57\xb9\x55\xd3\xcb\x29\x40\x4f\xae\x02\x2b\xc0\x7d\x50\x98\xbf\xfb\xad\x9d\x2d\x56\x52\x05\x6e\x67\x77\x39\xdd\xae\x4c\xc6\x49\x83\xf7\xb4\x93\xff\x6f\xc9\xfc\x58\xb3\x90\x78\xcb\xfb\x0d\x2a\xf1\x6c\xb7\x65\x1b\x8d\x18\xbf\x82\x96\x21\x72\xf6\xf8\x34\xc2\xa7\x98\x71\x16\x43\x04\x58\xec\xbc\xbf\xb9\xa7\xfd\x56\xef\x0f\xb2\x18\xb5\xfe\xdb\x51\x77\xc6\xb0\xde\x5d\x56\x0c\xd9\xe7\x7d\xbb\x18\x30\xcf\x9a\x15\xba\x0f\x8f\xc4\xa0\x09\x46\x55\x35\x78\x9d\xa4\x6e\x6c\x98\x40\x5b\x75\xbe\x4a\x14\xe7\x1c\xd5\x63\xbb\x43\xc0\x70\x6b\x2f\xca\xc6\x2a\x43\xcd\xef\x2c\xb6\x75\x12\x06\x16\x6b\x3c\x50\xe1\xc0\x5a\xe6\xcd\x30\x2f\x3f\x1f\x4b\x49\xc2\x90\xeb\x89\xde\xf3\xf2\xc5\x3e\xcb\xa4\x21\x67\x88\x45\x3e\xf4\x9b\xbb\x93\x6f\x40\xcf\xfc\x9a\xe6\x85\x25\x51\xaa\x03\x47\xe9\x82\x96\xfa\x07\xd9\xae\x24\x32\x36\x6c\xe7\x97\x27\x9b\x27\x1c\xb7\x21\x09\xc1\x7c\xef\xfd\xcd\xd3\x0e\x59\x68\x7d\x40\x6f\x7e\xab\x48\x88\x20\x96\x14\x79\x7b\xd8\x2d\x17\x9e\x4d\x96\x25\x44\xd9\xdd\xfe\x1d\xa3\x99\xfb\x0f\x2e\x32\x79\x40\xaa\x0c\xfa\xf2\xf7\x9b\x1f\xab\x7f\x6d\xbe\xdf\x6d\x9e\x56\x3f\x56\x4f\xfe\x92\x31\x55\x69\x9f\x65\x75\xdb\xf8\x16\xaa\xd5\x04\x58\xcf\x92\x98\x01\xef\xfd\xbc\x07\xe8\x4a\xa7\x27\xf7\x8b\x85\x25\x65\xbe\x66\x53\x06\x4b\x90\x72\x9b\xd5\xa7\xf3\x07\x84\xd0\x2c\x89\x65\x82\x7d\x35\x64\xa4\x75\x93\xef\x83\x2f\x90\x40\xea\x78\xe1\x6a\x3b\xe0\xb2\xe6\xf2\x3d\xeb\x56\x90\x24\x95\x96\x49\x70\x59\x56\x90\xe7\x56\x02\xe6\x93\x30\x4a\x92\xea\x88\xba\x92\x85\x0d\x66\x6b\x6a\xac\x18\xa9\x07\x1c\x87\x13\x1f\x38\xe1\x9c\x63\xf4\x60\xf9\xed\xa7\xbf\x2b\x17\x0a\x6b\x46\x74\x21\xc8\xa4\x27\xb9\x31\xb8\x35\xda\xcf\x78\x93\x97\xcf\x7e\xab\x49\x64\xa0\x31\x1a\xe7\xa0\x4f\x1f\xa6\xfc\xc3\xf1\x5e\x97\x48\xd0\x48\xc2\x6b\xe9\xc5\x1f\x40\x67\x62\x2b\x2e\x43\xb7\x2e\xd1\x41\x88\xb5\xeb\xbb\x73\x79\x84\xe2\x41\x54\xaf\xaf\xa2\x3f\x46\x31\x72\x24\x6c\x85\xe4\x95\x9d\xeb\x9b\x29\x5b\x80\x01\x85\x2d\x4c\xd9\x41\xb7\x20\x24\xa0\x43\xd9\xc9\xe5\x76\xfb\x7d\x62\x5c\x78\xd1\x4e\x0e\x5f\x23\x80\xd0\xf1\xba\xdd\xff\xc7\x03\xdf\x70\xc0\xad\x52\xf8\x30\xd5\xfc\x18\x31\x00\x9e\x75\xbf\x9d\xc6\x65\xe1\x44\x73\x11\x62\xba\xbe\xa2\xa8\xb7\x67\xa5\x61\x10\x0c\x34\x8b\x5a\x33\xba\x80\x49\x26\xf3\xd3\x35\x3c\x0d\x03\x8d\x16\x9c\x38\x9d\x7a\xfe\x41\x96\x86\x69\x10\xd8\x9a\x0e\x6b\x31\xad\x8b\x21\x56\x20\x0d\x25\xa4\xba\x67\xa3\x77\x01\xdf\x11\x14\x21\x8d\x22\xe6\x25\x6c\x16\x4d\x79\xdc\x95\x93\xe2\x34\x6f\x0c\xa5\x11\xa1\x88\x71\xfc\xbe\xbb\x3d\x6c\xbf\x3f\x2d\xbf\x2d\x76\x2b\xa7\x89\x7c\x78\x5a\xfd\xe3\xfb\xfa\x69\xfd\xf8\xf5\xe0\x79\x4a\x59\x1a\xa9\xc0\xca\x4a\x36\xa2\x6a\x1e\xca\x42\x54\xea\xe5\xd2\x6e\x03\x43\xaa\x09\x96\x46\xda\x16\x65\x9f\xa0\x32\x65\x75\x74\x1c\xcb\x8e\x68\x69\x00\x1b\x4d\x49\xc0\xd0\x36\xcc\x6a\x4f\x82\x8b\x04\x92\xdd\xe1\xc8\x18\xab\xfd\x6e\xb7\x2c\x04\x4d\x0f\x86\x43\x4a\x48\x88\x76\xfe\x7e\x73\xdf\xfd\x94\xa6\xb8\x02\x61\xd8\xe6\xb0\x79\x5c\x1d\x6e\x56\xfb\x61\x41\x38\x4b\x29\x31\xda\x43\xfc\x35\x8e\x9d\xf1\x8c\x4a\xa9\xa2\x86\xf7\x39\xd4\x37\xf0\x4e\x50\xf7\xe0\x8c\x73\x2c\xc9\xd8\xfd\xe3\xc9\xa2\xda\x0e\xb7\xab\xe5\xfa\x61\x71\xef\xa3\x21\x69\x1c\xdb\xca\xc5\xac\xb6\xc1\x4e\x98\xa0\x32\xd2\x98\x0b\xc4\xbd\x99\xaa\x3c\xfe\x18\x22\xf0\x59\x9a\xf0\x00\xf3\x92\xed\x12\xe4\x3a\x0f\xe7\x5e\x57\x74\xd1\x3a\x6e\x37\xf0\x6f\xa8\x7c\xca\x33\x4d\xa3\x28\xb1\x86\x4a\xdd\xa0\x6d\xd4\x6e\xdb\xb3\x71\x89\x34\xe5\xda\x53\x0f\x3f\x88\x5f\xf7\xa5\x7a\x1d\x90\xd7\xf4\xcf\x97\x4a\x8e\xc1\x3d\x5b\xbe\xe6\xd4\x54\xbb\x82\x1c\x96\x8a\xd4\xd0\xc4\x95\x38\xdc\x9d\x9b\xb3\x87\xed\x7d\xcc\xae\xc6\x52\xc9\x84\x90\x3d\x7b\x5d\x56\x3c\xcf\xb6\x9e\x9c\xa5\x45\x04\xa4\xb7\x2b\x4f\x83\x94\x4b\x0a\x51\x84\x94\xed\x07\x79\xbe\x6c\xcf\xcd\xbe\x44\xc6\xc5\xbf\x32\xa6\xc6\x1d\x02\x94\x6a\x4b\xcc\xf5\xcf\xc3\xdd\x6a\x75\xd8\xae\x9e\x96\xab\xc7\x76\xfc\xf8\xbb\x98\x28\x45\x1e\x8f\x73\xd1\x76\xda\x65\x8d\x25\x7f\xcd\x65\xd2\x63\x86\xc6\xbe\xf0\xed\xdf\xfb\x3f\x90\x73\xcf\x0f\x18\x1e\x70\x8d\x48\x9e\xfa\x54\x81\x18\xbb\xb7\x3c\x00\xaa\xad\x82\xe7\x8d\x35\x69\x06\xc9\x4b\x1e\x32\xc9\x07\x8c\xd3\x6d\x1f\xfb\x79\xce\x23\x42\x11\xe5\x6f\xb2\x37\xf8\x56\x9e\xab\x3e\xe2\xc9\x23\xa2\x10\x26\xe0\x98\xad\x3e\xf2\x31\x26\x19\x71\x1e\xe9\x38\x4d\x7a\x5e\x26\x5b\xcb\x7f\x1e\x42\x84\x78\x64\x54\xe2\x2c\xec\xfb\xb2\x69\xa0\xba\x78\x24\x89\x6b\x40\x13\x8d\xf1\xa2\x7f\xfe\xfd\xef\xdd\x4f\x90\xa2\xdf\xe0\x93\x5c\x1f\x33\xf8\x33\xce\x42\x3b\xf8\x73\x30\x0d\x9b\xec\x75\x9c\x85\x80\x40\x27\x5d\xe6\xb9\xa8\xf6\xe5\x7d\xf9\x06\x97\x9e\x14\x9b\x71\xa4\x00\x73\xdd\xf5\xe9\x3e\xcf\x63\xc6\x3b\x41\xf6\xd6\x67\x1b\xe5\x24\x78\x12\xcb\x80\xf5\x44\x9e\x43\xc0\xc9\xe4\x91\x92\x34\xf0\xb0\xeb\xf7\xbe\x0a\xfe\x46\x34\xea\xe5\xcb\x55\x98\xdb\x9f\x03\x5c\x77\x32\xdf\xc7\x53\x03\x07\x12\x8f\xd2\xb7\x3c\x31\x04\xb9\xa3\xec\xee\xf2\x84\x9e\xcc\x54\x42\x78\x92\x17\x98\x31\x3e\x78\xaa\x58\x62\x8b\x09\xdf\x40\xe4\x87\xd6\xe7\xf9\x3c\x4e\xe3\xcf\x33\xa9\xf2\x59\x6a\x1f\xb1\x1d\xbf\xb6\x50\x01\x77\x49\xc3\x85\x4d\x73\xad\x75\x7d\x73\x99\x92\xae\x8d\xdf\x5b\x06\x14\x8b\xeb\x2e\x20\x86\x83\x55\x06\x80\xa1\xdc\xe7\xec\x0d\x6e\x84\x7a\xfd\x60\x3f\xe7\x32\xd4\x18\x06\xb4\x7e\x49\x53\x56\x60\x6b\x14\xae\x90\x29\xbe\x7d\x9c\xe0\xb0\x5b\xd7\xe8\xaa\x6f\x45\xe5\x88\x45\x26\x43\x01\x98\xcd\xdb\x3a\xa6\x6a\x84\x72\x76\x30\x68\x0e\x2a\x75\x4c\x33\xed\x9c\x18\xd1\xd4\x31\x0e\x9a\x10\x27\xc6\x35\x9e\xd4\x26\x60\xda\x4a\x62\x16\xfb\x4a\xe8\x89\x87\xc4\x8d\x8c\x4d\x2f\xc4\xd4\x4b\x05\x8c\x1f\xcc\xe8\xc4\x4b\x1a\xfc\x0b\x44\xb5\x29\xbc\xea\x44\x36\xdd\xb3\x44\x10\xa6\x94\xd9\xba\x01\x35\x75\xbd\x45\xc0\x08\xe9\x82\xdc\x58\xf6\x5c\xb8\xb9\x3b\xca\x5e\x88\x30\xe2\x18\x2b\xdd\x67\xbf\xcf\x17\x36\xee\x4b\x41\xe2\x04\x1d\xb0\x02\xde\x6f\xb3\xe7\xac\x11\x79\xb7\x71\x8c\xd3\x59\xde\xda\x15\x24\xb1\xaa\xae\xcd\x88\xb3\xc9\x1f\xe4\x16\x6b\xbf\xfa\xff\x48\xfb\xb3\xe6\xc6\x71\x6c\x5b\x1c\xff\x2e\xf7\xa9\x1e\xfa\x81\x20\x89\x81\xff\x37\x59\x96\x33\x75\xd2\x53\x5b\x72\x66\xd5\xed\xe8\x50\x60\xd8\x90\x79\x4c\x91\x3a\x24\x65\xa7\xfb\xd3\xff\x83\x1b\x00\x27\xc9\x99\x75\x7e\x37\xa2\xa3\x9d\x25\x82\x33\xb8\xb1\x87\xb5\xd7\xfa\x09\xb5\xce\x1b\x98\x50\x73\x51\x99\xd8\x34\x88\xa1\xe0\xe2\x28\xcf\x04\x7c\xa9\xa4\x89\x6b\xb5\x45\x37\x6a\xd3\x02\x1c\xc2\xde\x54\x0a\x54\x8e\xbc\xfe\xfa\x7c\xb5\x85\xa6\x8d\xe2\x7e\x8b\x71\x1d\xbd\x9b\x23\xec\xcb\x7c\x29\x9b\x06\xb1\x6d\x07\xd9\xe6\x5a\xf6\x83\x2c\x47\xca\x0f\x94\xf1\x4d\xe9\xec\x85\x30\x25\x7a\x9c\xb5\x2b\x7e\x9d\xc6\x62\x52\x7e\x94\xa0\x31\x7a\xda\xb5\x2c\x4d\x75\x98\x7c\x9b\xb3\xd6\x54\x2a\x33\x96\xa2\xb0\xd4\x10\x75\x2e\x6e\x6f\xff\xfa\x5d\xa1\x54\x66\x3c\x4b\xe5\x80\x50\x9f\xbf\xd7\xfe\x3d\x64\xd2\xe9\xc3\xd9\xee\x76\xee\xaa\xb2\x09\xb2\xb4\x17\x48\xce\xa8\x94\x42\xe2\xb3\xbb\xc9\x0b\x68\x3e\x9a\x76\x78\xaa\x2a\x21\x29\x84\x8a\xba\xe9\x73\x1b\x71\x3a\xbe\xab\x71\x73\xce\xa0\x23\x71\x1a\x18\x14\xa9\x34\x3c\x13\xb6\x4f\xd5\x3c\x55\x6a\xc6\x83\x4d\x25\xb0\x28\x01\xdf\xcc\x7f\x31\xf5\x77\xd1\xf2\x4b\x90\x2e\x4b\xee\x80\x27\x85\xcc\x0f\xb3\x57\x07\x86\xa1\xeb\xb3\x39\xba\x95\xed\x3c\x75\x36\x1d\x6f\xa9\xc6\xae\x40\x30\x79\x7b\x26\x23\x3d\x1f\xab\x48\x6c\xbc\xb8\xb1\xba\x43\xfc\xd4\x4d\x55\x6f\x5a\xb9\x0a\x65\x1a\x69\x01\x10\xaa\x12\x32\x36\xdf\xfe\x5a\x0e\xb8\xcf\xde\x33\x90\xd6\x52\x0c\x91\x0e\x58\x35\xea\xdb\x19\xfb\xb5\x50\x5a\xcb\x31\xff\xe4\x83\xf1\x33\x9c\x91\x8a\x32\xed\x90\x18\x1f\xa7\xe6\xec\xbb\x51\x84\x08\x07\x3b\x68\xe5\x2b\xbc\x60\xb9\xa5\x79\xac\xaa\x62\x5a\xa9\x54\x24\xa6\x88\xb5\x0d\xf9\x83\x55\x5d\x9f\x67\xc8\xc2\x58\x29\xb1\x65\xd4\x91\x9b\x6c\x02\x46\x46\xc5\x89\xc5\x0c\x05\xe8\xaa\xf4\xab\x36\x2a\xe3\xf5\x27\x89\x95\x8a\x82\x08\xf9\xcd\xf3\x7d\x08\x48\x54\x12\x6b\x91\x04\x27\xb4\x8b\x21\xc7\xc0\x09\x95\x70\xa7\x48\xe7\x99\xd4\x3d\x52\x32\x09\x9b\x53\xdf\xf7\xfe\x15\xe4\xdb\xc7\x6d\xde\xc2\x08\x3d\xaf\x52\x1b\x23\x1b\xf3\x5b\x20\xc6\x6d\xa6\xc4\x4d\x9f\x9a\xc3\xf3\xa2\xb4\xa2\xa0\x59\x1a\xf0\x0f\xd0\x17\x12\x15\x8b\x8d\xf6\xcd\xc8\xdb\x97\x1a\x9a\xaa\x98\x39\xe1\x8a\x81\xc6\x48\x1a\x4a\xb3\x94\x45\x71\x91\x56\xe9\x93\x35\x5c\x31\x70\x08\x6c\x59\x14\xd5\xbb\x2b\x89\x5d\x5c\x26\x15\x8f\x22\x19\x58\xea\x16\xb7\xab\xa7\xa1\xbd\x51\x71\x92\x60\x1f\xf3\x4d\x01\x3f\xf3\x5e\x3f\xef\x77\x3c\xe8\x54\xf1\x98\x29\x27\x0c\xf0\xdf\xa7\xa6\x3d\x63\x3e\xeb\x06\xd8\x24\xf4\x99\x55\xe5\x3e\x6f\x4f\x06\xfa\x93\x72\x1a\x44\x25\x6f\x60\xde\x4e\xa1\x44\x4a\x28\x0c\x60\x92\x49\xe4\xa9\x04\x8b\x30\x94\xdf\xb9\x39\x1f\x7a\x02\x2e\x87\xf0\x4a\x80\xc5\x43\x3d\x37\x1e\x92\xe9\x7f\xcf\x92\x08\xdf\xfd\x21\x2f\x27\xeb\xa3\xca\x68\x2a\x4d\x2f\x35\xdc\x8e\x83\xb2\x7e\x88\x72\x3a\x86\x8f\x7f\xde\x4e\xf9\x87\x3e\x89\x41\x66\xef\x22\xd3\x32\x1d\xb3\x31\x2e\x83\x69\x1b\xae\x5a\x12\x27\xbf\xf6\x5d\xde\xcf\x1e\x8d\x4c\xd2\xc4\x86\x96\xc5\xfa\x15\xda\x31\x68\x53\xa9\x24\x75\xd2\x08\x18\x64\xaf\x0e\x79\x33\x15\x16\xa4\x4a\x47\x36\x1a\x64\x49\xbb\xf7\x32\x6e\xdd\x0e\xeb\x4c\xf2\xef\xd9\x44\xd3\x82\xc7\xee\x33\x2b\xcb\x1e\x2f\x0a\x33\xdf\x4f\x69\xe9\xa4\x7e\x5e\x64\x61\x47\x5e\x8c\xdf\x6a\x4c\x8a\xeb\x7c\x65\x2d\xd4\x4b\xd9\xfa\x42\xd9\xb6\x9a\x6b\x42\x5c\x0c\xe1\x14\x10\xa7\x0c\xf5\x96\xc3\x7b\x1a\x56\x71\x65\x13\x83\x8c\xfb\x0f\x58\xe6\x1e\xa7\xaf\x94\xa5\x8c\xb2\xa0\x92\xd7\x39\xfe\xbd\xfa\x49\x3f\x02\x28\xb6\xb8\xe9\x17\x3b\x0a\x30\x74\x44\x12\xf4\xb3\x74\x75\x3a\xf6\x96\x46\x47\x82\x18\x9f\xde\x45\xdf\x69\x72\x75\x3a\x92\xd4\x95\xaf\x8f\x47\x28\xcd\xa6\x3a\xd5\xfa\x82\xe8\x46\x58\x88\x35\xe1\x69\x62\xb0\xef\xee\x61\x33\x7d\xf7\x9a\x00\xc3\x9c\x91\x2b\xcd\x5d\x0d\x18\x54\x1d\x47\x42\x3a\xd7\xed\x00\xd7\xa0\xe5\x47\x08\xae\xaf\xd0\x2c\xd6\x53\xc0\xe3\xdf\x8b\x8c\x75\x2c\x9c\xeb\xf4\x1f\x38\x35\x23\xe3\xa8\x63\xe9\x74\x17\xa5\x31\xff\x3c\x49\x17\x0b\xff\xa6\xea\xef\xf7\x4c\x12\x86\xcd\x14\x87\x4a\xbf\xee\xc6\x6a\x8d\xbf\xd9\x2d\x73\x72\x0e\xbe\x6c\x53\xc9\xda\x3c\x94\xcf\xcd\x67\x29\x6f\x9d\x72\xc1\xf8\x39\xa9\x69\x55\x2f\x8b\xea\x64\x42\x72\x1d\x15\x80\x66\x77\xde\xbf\x85\x54\x0a\x94\x86\x78\xcb\x03\x72\x51\xa7\x2a\x46\x66\x83\xe3\xa9\x79\x71\x91\x47\xbf\x45\x53\x44\x71\x2e\x65\xdd\x7e\xe8\xdf\xa4\x84\x75\x0a\x1c\x8b\x01\xee\x4b\x5c\x60\xf9\x76\x36\x65\x58\x44\xa3\x28\xe4\x24\x0f\x32\x2f\x7d\x90\x35\x9b\x0f\x2c\x4e\xb0\x5c\xa0\x72\x73\x96\x62\xd7\x2c\xd5\x9e\x10\xa9\x81\x09\x19\x2c\xd5\x3c\xe3\x1a\x82\xd4\x61\x79\x6a\xbc\x0e\xe4\xf4\x1a\x78\x66\x53\x07\xe0\xff\xd8\x56\x2b\xa7\x93\x70\xae\x61\xef\x07\x0b\x42\x31\x1f\xec\x08\x64\x1c\xa3\x51\xbf\x49\x22\x9c\xb9\x06\x9d\x1f\x73\x28\xdb\xce\xc9\x97\x79\xd9\x7f\xfd\x5a\x68\x86\x08\x97\xd6\x49\xd3\x9c\x8e\x9d\x6d\xe8\x2f\x36\x4b\xad\x43\x10\x15\x55\x03\x81\xa3\xef\x6c\x29\x9c\x4f\xa4\x91\xe9\xd3\x19\xc4\x59\xf7\x34\xaf\x1f\xd6\xe1\xa0\x32\x8b\x91\xe1\xc4\x05\xd8\x57\xdd\x22\x79\xb6\x4c\xfc\xe3\x12\x60\x47\x4b\x6d\x24\x1d\xb8\xb8\x90\x3b\x08\xdb\xbd\xde\x7a\x54\xb4\x56\x84\x62\x5b\xe0\x0f\x50\xbd\x50\xdd\xa7\x33\x4d\x31\x82\x90\xb7\x55\xdb\x63\x15\x2e\x52\xd7\x52\xad\x53\x08\xf4\xe3\xd3\x2a\x92\xdf\x6e\x88\xeb\x03\xfb\xb2\x70\x02\xcf\xe1\x72\x80\x38\x03\xd4\x53\x17\x4e\x2c\xfa\x27\xdf\x1c\x24\x8e\x1e\xb3\x5b\x86\x4f\xa5\xb9\x38\x45\x80\x66\xa8\x21\x65\x8b\xea\x3d\x2f\xf7\x5f\x65\x5e\x4f\xdd\x43\x0d\x9c\x21\x0b\x96\x05\xaf\x9c\x8a\x9e\xce\xcb\xd0\xa7\xa9\x2d\x89\xb0\x4d\x34\x30\x67\x20\xbf\x95\x6f\x94\xf8\x04\x9c\xa8\x6d\xc6\xb2\x31\x17\xe3\x13\xbc\x41\xdd\xc0\x2f\x41\xec\x7f\xc7\x69\xd2\x56\x0a\x4c\x5d\xeb\xa2\x9b\xa8\x07\x59\xca\x7d\x3f\x4d\x4d\x14\x39\xdf\xbd\xc9\xf7\xe5\xe9\xd8\x99\x9f\x0b\x82\x53\x73\x73\x6e\xa2\x54\x60\x43\xe4\x0e\x3b\x8e\x31\xc9\x34\x39\xa7\x21\x89\x03\x04\x34\x2f\x72\x67\x64\x2b\x77\xfb\xba\x3a\x1d\xff\xe8\xcb\x43\xe3\x3b\x37\x84\xc7\x98\xbd\x7d\xf8\xba\x1c\x15\xc1\xff\x96\x39\xef\xf6\xc5\xbe\xec\xe5\xd3\xc3\x8f\x6b\x24\x4a\xed\x05\x23\xa8\x21\xca\x65\x41\x9b\xca\xb6\x4b\x79\x1c\x03\xdb\x0d\xd1\x54\x7b\x94\x07\x92\xf8\x38\x7e\xe9\xfe\x0b\x35\xc4\xf2\xcc\xe9\x6c\xe4\xfb\x3d\xd4\x9b\xd7\xdc\x7b\x2d\x49\xfc\x2f\x42\xfe\xfd\xaf\xc4\x73\x9a\x89\xd1\xbf\xd2\x7f\xff\x2b\x21\xfd\xcf\xff\xc6\xff\xf5\xff\x4d\xff\x3d\xd9\x8f\xb0\xc9\x7f\x26\x71\x37\xda\xff\xe2\x2f\x21\x16\x16\x89\xc6\x75\x55\xda\x7c\xff\x0b\xb6\x6a\x3f\x3e\xe1\x4e\xa8\x75\x1a\x9e\xff\x2f\xf2\x1d\xff\x5f\xff\x86\xf3\x67\x4a\x7b\x03\xbf\xda\x7e\xc5\x4b\x78\x3e\x1e\x1d\x7f\xea\x2c\x0a\x30\x69\x46\x43\x9f\xcb\xaa\xc4\xcc\xfe\xf5\x99\x47\x6d\x28\x95\xdc\x21\x46\x5d\xdf\xd7\x42\xeb\x33\xf9\x6d\x6a\x28\x33\x98\x79\xdc\x49\x53\x1d\xdb\xc5\xcf\x7c\x06\x14\x16\x9f\x4c\x1d\x9a\x51\xe3\x18\x95\x5d\xe7\xf4\x2f\xa5\x7f\xa8\x61\x4c\x07\x6d\x42\xe7\x89\x62\x26\xe0\x47\x55\xbf\x42\x7d\xac\xaa\xe2\x42\xd5\xc5\x30\xae\x90\xff\xf0\x0a\xf6\x79\x39\xc9\x86\x1a\x66\x22\xec\xe0\xfb\x73\x7d\x3d\xf6\xe2\x0c\xb3\x09\x3e\xc4\x2d\x14\x70\x7c\xe9\xa5\x7c\xa9\xe1\xb1\xc4\xaa\xb1\x7b\x14\x9d\x6f\xf7\x3c\x4b\x26\x1a\x4e\x33\xfc\x98\x7b\x00\xd5\x6a\xfb\xf5\xba\x1e\x8c\xa6\xe1\x59\x8c\x6c\x2a\x07\x6c\xbb\xdd\x42\xf9\x58\xc8\xb6\xdf\x68\x01\xdb\x0f\xba\x60\x69\x80\x09\xd3\xb0\x59\x28\x85\x19\x4d\xd5\xdd\x0b\x8a\x90\xf9\x0d\x59\xcc\x5d\xf4\x22\x3f\xb0\x0d\xa5\xad\x5c\xa7\xd5\xec\xe2\xa4\x8e\xb8\x53\xbf\xd0\xa7\x1a\xcc\x7d\xd5\x93\x69\x53\x23\xad\xb3\xa8\xd8\x0e\x80\x45\x01\x97\x2f\xfd\x35\x9e\xd0\xef\xac\x52\x97\xb6\xed\x1c\xd5\x87\xcd\x85\xb4\x82\xd1\x89\x03\xc4\x5e\x2f\xbe\x0f\x9c\x9d\xd4\x18\xc2\x50\x01\xb1\xb7\x39\x08\x0e\x22\xb3\x77\x68\x28\x4f\x75\x28\x10\x4e\x3b\x13\x8d\x11\x04\x0b\x07\x4a\x61\xa4\xde\x2d\x72\x75\xe7\x28\x58\xeb\x97\x96\x30\x4e\x67\x58\x94\xec\xbc\x1e\x87\x23\xaa\x9b\x76\xee\x9e\x1b\x88\x85\x04\x8f\x72\xba\x92\x66\xde\xcb\x63\x80\xca\xc0\x42\xe6\xcb\xb9\x2b\x4f\x52\x17\x06\x64\x1c\x7d\xd8\x87\xab\xa7\xdd\xb5\x57\xe2\xe8\xb7\x29\x61\x9d\x46\xc8\x3c\xfa\x32\x36\x49\xb1\x59\xa3\x00\xdb\x3e\xbc\x85\x26\xaa\xb0\xa3\x55\x69\x12\x79\x22\x4c\xf2\xc7\x74\x47\x9d\x61\x7a\xad\xc8\x0f\x79\xeb\x4a\x65\x8f\x50\xff\x05\x32\x2c\x2f\x10\x49\x07\x36\xea\x62\x62\x47\x35\xe1\xc5\x4f\xc6\x0d\x43\x40\x78\x8c\xbd\x02\xb7\xd5\x7e\x83\x92\x9e\xfb\x51\x5d\xf4\x12\xa7\x5d\xb7\x0b\xc5\x28\x7e\x2b\x6b\x93\x87\x6b\x85\x98\xa4\x4e\x44\xab\x7b\xbe\x58\x80\x5f\x56\xcd\xa1\xf2\xc8\xca\x31\xb8\x0d\xe2\x24\xf2\x31\x37\xf4\x9d\x84\xd3\x19\x0b\x09\xd7\xd8\xd7\x66\x7c\xc8\xfd\xe4\x8a\xd3\x6b\x1d\xa2\x6a\x48\x84\xc5\x76\x59\x2d\x4b\xaf\x6d\x82\x6b\xec\xfc\x38\x36\x1a\x38\xde\x46\x7c\x95\x14\xd2\xc8\xc9\x9f\xfb\x06\xfb\x16\xce\xb8\xa2\xc2\x64\xf7\x8a\xaf\x14\xd2\x94\x63\xe3\x1e\x36\x3b\x9c\x65\xe6\xc2\x20\x96\xf2\x01\x32\x14\x72\x52\xc0\x88\xc1\x09\x5f\x05\xd5\x89\x66\x5d\xfe\xf3\x04\x73\x42\x03\x60\x8a\x20\xfc\xe2\x2d\xd7\x6d\x55\xe7\x70\x3a\x74\xce\x6f\xae\xc7\x86\x0a\x98\xd5\x48\xb5\xe6\xcb\x49\x3b\xdb\x37\x17\x02\xcf\x4c\xec\xbc\xe3\x7d\xa0\xa4\xa5\xc0\x25\x63\x49\xa0\xf0\x7d\x47\xfe\x2e\x0d\x8f\x50\x6b\x28\x5b\x39\x9f\xeb\xc0\x8d\x42\x3e\xce\x2f\x57\x13\x0a\x23\xc8\x38\x38\x11\xbc\xce\x71\xfe\x02\x25\x34\xc3\xdb\xcf\x74\x82\xb9\xbf\x77\x80\xd7\x31\x4b\x78\xb7\x45\xa2\x92\x42\x51\xed\xb1\x60\xd4\x5d\xec\x6f\x40\x83\x20\x89\xfb\x2a\x64\x5b\x1d\x72\xfd\x73\x02\x47\x00\x19\x6b\x6c\x75\xf8\x22\x0f\x70\x35\x4c\x2a\x15\xf3\x50\x2e\x5d\x20\x8f\x5b\xe7\x50\x4d\x52\x2a\xd3\xf7\xa4\xb4\xcb\xf5\x8d\x53\x1b\xb3\xcb\xd0\xa9\xc1\x96\x63\xd4\x3d\xb9\xcb\xcf\x26\x97\x66\x1c\x6b\x75\x5a\x96\x57\xbd\xc1\x01\x60\x22\x0d\xf2\x86\xb7\xd5\xbe\x1a\x7e\x97\x48\x1c\x3f\xf5\x7c\xa7\x2b\x1d\x80\xc9\x8c\x03\xb5\xbd\x41\xd1\xcd\x15\x27\x64\xee\xb7\xda\xd8\x11\xeb\xe4\x8d\x13\x2f\xa9\xea\xa1\xb1\x76\xd4\x67\x34\x3b\xa6\x05\x8a\x26\x78\x29\x8b\x7c\x7f\x2a\x42\xc1\xc1\x46\x89\x20\x2c\x70\xdf\x3e\xa0\x71\x9c\xa1\x72\xa7\xcf\xc3\x46\x2c\x8b\x26\x94\xe5\xa5\xb9\xad\xf4\x2b\xa6\x5f\xfe\xce\x72\x61\x23\x13\x61\x0e\xf8\x09\x9a\xdc\x9c\x64\x31\x61\xf4\xb8\x14\xdb\x5a\x92\xc4\xb8\x72\x1d\x1d\x30\xc5\x09\x71\x74\x5f\x56\x5e\x95\x43\xc9\xcf\x92\x54\xa3\xa1\xc4\x0e\xe2\x3a\xee\x7f\xa6\x91\x75\x1d\xa6\x8d\xee\x7f\x93\x89\xf6\x48\x7a\x19\x52\x90\xa3\x75\xc5\xc6\xc4\xa9\x17\x8f\x74\x90\xa7\xaf\xdd\xc6\x9d\x59\xf1\x86\x55\xbe\xc9\xed\xc7\x11\xcc\xb5\x6c\xe5\x40\x21\xfb\x59\xa3\xf1\xdf\x73\xe6\x6c\x2c\x62\xe6\xb9\xc2\x70\x2d\x5e\xcc\x32\xed\xdd\x34\x70\x12\x49\x98\xb7\x71\xca\xe6\xc3\x0d\x18\x8d\xb4\xfe\x5f\xaa\xd3\x55\x3e\xfc\x08\x98\x08\x94\x2a\xaf\x46\xac\x36\x36\xc9\x18\x46\x13\x47\xc4\xe6\xfe\x08\xcc\xbe\xfd\x66\x9d\x62\x43\xba\xaa\xaa\xd7\x7a\xda\x25\xe2\x47\xa4\x24\x41\x08\x95\x7f\x41\xc9\x0e\x2d\xed\x28\x99\x61\x53\x21\xb1\x84\xb7\x7c\xde\x6c\x1f\xee\x76\xab\xa7\x65\x1c\xed\xae\x9e\x9f\xee\x77\x9b\xd5\xd3\xf7\xf5\x72\xb5\xbb\x5f\xdc\x85\x14\xb1\xa5\x29\xa5\xde\xa3\x78\x94\x8e\x66\x60\x7a\x42\xca\x29\x6a\x4e\x1d\x7d\xe4\x3e\x4b\x0c\x5a\x2a\x9c\x77\x3b\xb4\x25\xe3\xda\xf3\x1b\xbe\x01\xbf\x1c\x5a\x26\x53\x6c\x6a\x3e\x54\x26\xb7\x1f\xbb\xfb\xea\xed\x74\xb8\x58\x7c\xb6\x5c\x48\xdb\xa7\x9c\xf5\xeb\x45\x23\x63\x45\xe4\xa9\x58\xa0\xbd\x92\x0d\x3c\x3f\xad\x27\x9e\xa8\x15\x31\x15\x2e\xd2\xf9\x58\xfd\x04\x7d\xb9\xce\x61\x05\xa3\x18\xa4\x41\x37\x64\x94\x88\xb0\x59\x6c\xe2\x64\x40\x6f\x75\xd3\xb8\x6f\xd2\x1d\xeb\x3a\x4d\x0f\x97\x51\xc7\x24\x1d\xd8\xe5\x9d\x74\xe6\x83\x7d\x3e\x6b\xc9\xb3\x92\x24\xbd\xd3\x7a\x38\x1d\x76\x26\xd0\x60\xfb\xed\x4a\x68\xac\x28\x9f\x9a\xce\xff\x3a\x95\x6d\xb3\xee\x23\x85\xe9\x49\x55\xc6\x1d\x0f\x69\x99\x77\xb1\xb5\x2c\xbe\xc8\x03\xf2\xf2\xe6\xc3\xc1\xb4\xc0\x9e\x39\x97\x0b\x5b\xb5\x2f\x33\xb2\xb8\xd9\x6d\x28\xeb\x58\x15\x1e\x65\xf7\xcd\xff\x79\x69\xf5\x16\x53\x63\x02\x24\x09\x95\x00\x47\xf0\xb7\xc2\xb6\xba\xcb\xef\x17\xb4\x42\x7c\xf9\x51\x7e\x6c\x5f\x3c\xbd\x49\xb8\x52\x9b\xa6\x91\x33\xfc\x9d\x2b\x59\x63\x6e\xf4\x79\x5d\x4e\xe9\x26\xac\x15\x54\x27\x7d\xfe\x3b\xd4\xcb\x7c\x9c\xce\xa2\x28\x92\x4e\x1a\xc8\xf7\x5a\xcb\x8f\xc3\x25\xea\xbb\xde\x97\x66\x51\x94\x58\x2c\x5b\x79\x8c\x20\x1c\x8e\x55\x2d\xeb\x8f\x49\xfc\xcf\xa2\x08\x5c\xa5\x18\x0a\x79\x6c\xc0\xdc\x55\x65\xfb\x82\xa0\xe5\xf5\xf2\x01\x5d\xbb\x3f\xc2\x40\x1b\xa5\x08\x43\xaa\x8b\xf0\x13\x49\x39\xf7\x1c\x24\x77\x79\x01\x4d\xdb\x05\x41\x97\x1e\x3f\x8b\x88\x91\x89\x5b\xe6\x4a\xa8\x7f\x87\xf6\x9d\xef\x0b\x8e\x82\xd8\x37\x06\x7d\x72\x86\x98\x6a\x64\x75\xe9\x6c\x6b\x0d\xa7\xc3\x65\x90\x3e\x8b\x62\x29\xf0\x9b\x6d\x4e\xfe\x16\xf7\x40\x9f\x37\xd7\xe1\x9e\x62\x1d\x21\xda\x6a\xf1\xb4\xba\x09\xbf\x25\x49\x8a\x89\x4e\xd4\xb3\xc1\x36\xbe\xb0\x41\xd2\xc8\x04\xfe\xac\x80\xf8\xb9\x7c\x79\x89\xd4\x88\x82\xb8\x87\xf7\xab\x93\xd9\x9f\xf7\x80\x85\x71\x2a\xb3\xd9\x84\xd2\xc0\x42\x5d\x8f\x5a\xf1\xa7\x77\x93\x0a\x07\x76\x1f\x57\xf1\xc2\xa6\x4c\xa2\x33\x5b\xe7\xa6\xa7\xa3\x65\x51\x2a\x5d\x5e\x55\xc9\xb6\x2d\xa0\x5f\xb3\xfc\x56\xc6\xb8\xf5\xf0\xbc\xeb\x4a\x0f\x05\x90\xf3\xbc\x26\x8b\x38\x95\xe8\x12\xbb\x2e\x2c\x4f\x03\x11\xb6\x89\x14\xbb\xf5\xbf\x54\x25\x6c\xeb\xfc\x78\x9c\x70\xfe\xb1\x88\x67\x44\x66\xfd\x64\xf7\xed\x74\xd3\x07\xc1\xa5\x13\x9b\x3c\xec\xaa\x77\x64\x2d\xe9\x45\x13\x58\xc4\x6d\x12\xa7\xe1\xb9\xdf\xe6\x1a\xca\xe6\xb2\x3a\x40\x37\x34\xc5\x04\x9f\x45\x8c\xe7\x05\x2a\x78\x16\x89\x34\x71\x15\xf7\xc5\x62\x3b\x58\x18\x16\x09\xc5\xcc\x80\xf7\xf5\x56\x73\x22\x6e\xe5\x07\x66\x22\xf6\x71\x75\xdd\x7e\x3c\xbc\x97\xcd\xa2\xb9\x54\x5d\x18\x7d\xee\xb8\x4f\x10\x15\xeb\x19\x9d\x90\x50\x3a\xb0\x50\x4f\x4f\x21\x19\xc3\x9c\xae\x3a\x79\xf6\xad\xab\x8f\x27\x2f\xec\xfa\xc9\x8d\x2b\xc5\x70\x9e\xf7\x0a\x6a\x9e\xba\x7f\x16\xee\xb3\x48\x99\xc4\xeb\xa8\x9b\x65\x55\x14\x52\x55\xf5\x58\xfe\x60\xf2\xea\x67\xd1\x1d\x8b\xb4\x72\x32\x83\x9b\xfc\xb5\x52\xb2\x5b\x4e\xf2\xf2\x54\x5d\xe8\xb2\x62\x91\x49\x9c\xfc\x76\x5b\xad\xfe\xdc\xbe\xcf\xb8\x85\x58\x04\x5a\x06\x42\xb5\x0d\x14\xc5\x12\xf2\x62\xf4\x35\x85\x41\xc6\x09\xad\x39\x99\x85\x11\x36\x99\x45\x60\x89\xb2\xc3\x0a\xeb\xf1\xff\xb3\x7b\xb5\xd4\xd1\xf4\x6b\x17\x95\x63\xa5\xa0\xbb\x54\xef\x33\x33\x12\x11\x0a\x93\x86\x8f\xb9\xef\x35\x7e\x89\x24\x4a\x05\xf3\xf4\x91\xab\xff\x96\x75\xfe\x74\x2a\xe0\x17\x40\xc7\xfe\x3e\x48\x44\x25\xce\xca\xeb\xfd\x4f\x14\x1e\xf2\x3f\x13\xc2\xa9\x2f\x9a\x1c\xab\xf2\x0c\xfc\x3d\x49\x17\x33\x42\x04\xc7\x2c\x44\x7d\x6a\x9a\x5c\x96\x1e\x30\x19\x36\x2a\x8b\x49\xb0\x45\x01\x35\x2a\x3a\x99\x91\x4f\x33\xac\x12\xa4\x8b\x11\x86\x0e\x69\xa4\xa7\xfa\x96\xb7\x03\xbc\x74\x3a\xab\x48\x9c\x31\x64\x78\xfa\x02\x6d\xb0\x4c\x9d\xc1\x7d\xb0\x97\x96\x45\x46\x62\xa9\x8d\x4f\x84\x6c\x34\x94\xb2\xce\xab\x06\x8b\xdd\xd3\x3b\x89\xa1\xef\x28\xfa\x01\xaa\xc9\xdb\xcb\x0d\x42\x8c\x24\x84\x63\x4b\xf5\xbb\xbe\x0c\x71\x61\x24\x49\x38\xea\xa3\x69\x9f\x23\xbc\x83\xa6\x91\x01\x4f\xc7\x48\xc2\x04\xae\xc5\x3d\x5a\xb2\xef\xe9\x9c\xd1\x2e\x30\x92\x08\x27\xd4\x1b\x92\xb4\x9f\x77\x30\x0c\x67\x4f\x3d\xe8\xaf\x6f\x72\xbe\x96\x1f\xe8\x94\x2f\x4f\xed\x6e\x3a\x97\x49\xe7\x0d\x77\x13\xfe\x7f\xe2\x70\x71\x8c\x30\xc4\x7d\x6e\xa1\x69\xbf\x3c\x2c\xb6\x63\x93\x49\x98\x96\xd6\x84\x26\x44\xac\x26\xde\xae\x67\x47\x64\x96\x07\x7e\xf9\xaf\x08\x2f\xaa\xaa\xc2\x8c\x94\xed\xfc\x30\x6e\x1d\xdb\xd3\xf6\xdb\xf5\xe4\x0c\x22\xd3\xca\x57\x8a\x6b\x54\xdd\x6e\xa1\x2e\xcf\x57\x9e\xd9\x2d\x67\x2c\x72\x32\xa8\xbe\xad\x0a\x9d\x06\x64\x7e\x9b\x25\x3b\xba\xa1\x9e\x02\x2e\xd7\xaf\xbe\x24\x38\x3f\x96\x6b\x19\x41\x82\x83\xfd\x95\x57\xd4\x46\x22\xc4\xc1\xed\x66\x44\x46\x86\x39\x53\x81\x19\x2a\x44\x51\x0d\xb0\xcd\x30\x28\x16\xf8\x30\x0e\x18\xb1\xc7\x11\x11\x43\x38\x18\x42\x16\x46\x64\x2a\x50\x69\x54\x9d\x3e\x16\xe6\x97\x6f\x78\x8a\xea\xf2\xbb\x2b\x62\x38\x2a\xf1\x5c\xf7\xac\x44\x8c\x28\x05\xc4\xa7\xd2\x8a\x93\x7e\xfd\x40\x2a\x83\xb0\x51\x6b\xc0\x09\x78\xfb\x10\xa4\x18\x19\xd1\x26\xc5\x2e\x33\x15\x92\x44\xab\xed\xd7\xd9\xa3\x83\x8c\xa0\xe1\x3b\xc8\x57\xe8\xb3\x07\x8c\x80\xa5\x8e\xa3\xac\xaa\x77\x83\x84\x02\x23\x96\x28\x2f\x48\x59\x9a\x8b\x78\xe7\x4f\xec\x92\x4d\x1c\x4d\xb8\xa7\x2c\xb8\x93\xaf\xbd\x81\x25\x16\x62\x47\x37\x86\x4f\x70\x46\xbe\xe2\xc6\xc4\x51\xe4\xe8\xfb\x03\x6f\xc7\x47\x75\xba\x88\xc6\x65\x71\x64\x08\x52\x4d\x17\xb2\x41\x18\x72\x01\x2d\x60\x35\xd3\x9f\x2e\x26\xcc\xf1\x59\x7b\xa9\x41\x04\x95\x9e\xaf\x2a\x31\x31\x16\xab\x3f\xab\xcd\xdd\xd5\x68\xf1\x8e\x63\xe3\x5b\x84\xde\x56\x65\xe3\x1b\xe4\x82\x71\x8c\x93\x58\x80\x4f\x63\x5e\xe5\xa6\x6f\xe9\x3a\x23\xa7\x9f\x58\xa9\x38\xe1\x84\x0e\x2c\x41\x3e\x8e\x7e\xac\x8a\x62\x76\x6b\x89\x50\x51\x3c\x86\xe5\x5e\xe8\x41\x63\x71\x1a\x29\x04\x21\x3d\x76\xcb\x4f\x9b\x97\xf0\x38\xe4\x1b\x59\x9c\xc6\xe0\x48\x61\x3d\x29\xcb\x04\xf9\xcb\xe2\x94\x3b\x8a\x17\xf7\x2e\xbe\xe5\xe5\xde\x8c\xfa\xcb\x2f\xcf\xdf\xc1\xe8\xc7\x29\xb8\x7e\xe1\x6e\x36\x5d\x6c\xc9\xec\xef\x99\x52\x8e\x32\x39\xd2\x85\x69\xcd\x73\x03\x97\x7b\x92\x58\x4c\xb9\x04\x8f\xcd\xbf\x79\xde\x6e\x87\x56\xe4\x70\xd1\x2c\xa2\x76\x58\xbc\x1f\xfa\x57\xc5\x52\xc3\x74\xdf\x13\xb2\x45\xd6\x9a\x99\x8b\x15\x33\x88\x31\x2d\x80\xfe\x7a\x3c\x74\xf3\x84\x63\x70\xce\x88\xaf\xa8\xdd\xe4\xb2\x75\x79\x89\x65\x55\xbe\x75\xab\x9f\xd9\x56\x73\x2e\x43\x16\x0b\x93\x22\xd0\xf1\x6a\xfb\xd7\xf2\x4c\x91\x6a\xbc\xca\xc7\xc2\xea\x28\x1b\xba\x20\x46\xe9\xe7\xbf\x2d\x42\xfb\x19\x4e\xe0\x57\x65\x42\x16\x67\x09\xc3\x09\xe7\x64\x90\x03\xbf\xf4\xec\x3e\x32\xcd\x30\xee\x59\xd4\xed\xd5\xf2\xb7\x61\x2d\x8e\x47\xaf\xd6\x54\x2b\x8c\xa7\xe6\x32\x55\x2c\xce\x80\x63\x2c\x7b\x5f\x29\x59\xff\x42\xc7\xce\x0f\x57\x31\x20\xdc\x0e\x13\x83\x4b\x59\x14\x46\xb6\x72\x29\xcb\x3b\xec\x42\x18\x09\x5f\xff\x63\x2e\x82\xcd\x62\x65\x00\x55\x77\x43\xfa\xe5\xee\x03\x45\x51\xa6\xd7\xa3\xac\xca\xfc\xb2\xb6\x28\x0a\x64\x43\xf1\x0c\x61\xc1\x36\xc5\x3a\xa5\x66\x4c\x41\xed\x60\xe6\xcd\x63\xdd\xc3\xb5\xbb\x31\x1c\xbb\xaf\x5b\xa4\xce\x99\xdb\x23\x2d\x1c\x35\x9e\x54\xd5\x1b\x6c\xe0\x0d\xca\x01\xe0\xc4\x62\x9d\x19\xec\xd7\x68\xa1\x69\xe3\xdd\x1b\xd4\x85\xec\x62\x9a\x7d\x80\x5e\xdc\xc3\xfb\x7d\x65\x86\x53\x49\x97\x69\xc1\xec\xd6\xf2\x43\x17\xc3\x16\xc5\x62\x6f\x1b\x66\x0a\x2f\xd3\xb7\xaa\x35\xc7\x46\xbc\x43\x5e\xfe\x80\xfc\xc7\xd4\x5b\xc1\xc8\xdf\x0f\x34\xa9\x43\xc0\xba\x8f\xca\x45\xec\xf3\x59\x39\xbd\x53\x63\x13\x2c\x0f\x2e\x1f\xee\x3c\xdd\x50\x38\x16\x64\xc6\x66\x03\xd3\x09\x22\x94\xc2\x26\x29\xf0\xe1\xad\x7e\x1e\x0b\x39\x58\x59\x2b\x23\x5c\x64\xcd\x65\x2a\xae\xb3\xa4\x2e\x4b\xa2\x14\x12\x2f\xdb\xe4\x13\x36\xe8\x2b\xcc\x5e\x47\x42\x44\x62\x9d\x68\x4c\xf3\x0a\xf5\xdc\x93\x48\x88\x10\x71\x34\x32\xb1\x9b\x77\x59\x1f\x30\xa3\x7a\x21\x52\x4d\xe2\x44\x21\xab\xc0\x15\xb8\xca\x5f\x7f\xfd\x49\xac\x08\xbe\xd7\xa3\xfc\xa8\xab\xa2\x98\x59\x9d\x24\x89\xd2\xc8\xbb\xaf\xd7\x95\x76\x99\xaf\x71\xd6\x86\x25\x89\xb4\x98\x7c\xfd\x0a\x45\x7e\x3a\xdc\x43\xfb\x5e\xd5\xaf\x13\x14\x0a\x4b\x12\xed\x28\x47\x1d\xff\xca\xf3\x71\x79\x56\x1a\x67\x49\x9a\x24\xc6\x83\x6b\x36\x6d\xa5\x5f\xe7\x9b\x19\xc5\xf4\xc9\x1b\x2a\xeb\x3b\xd3\x87\x87\xe9\xd5\x68\x59\x92\x6a\xd7\xe7\xd4\x9c\x0e\x0f\xf6\xfe\x0b\x54\x87\xcf\x50\x05\x7e\x07\x9a\x46\x28\x23\x88\xb3\x14\xab\x4b\x3d\x51\x1e\x4b\x18\x4d\x11\x00\xef\x60\x62\xc1\xf6\xc8\x91\x6c\x08\x4b\xb8\xc8\x44\x8f\x15\xbf\x20\xb4\xe3\x87\x09\x6e\xb1\xfd\xac\xad\xaa\x7d\x01\x5e\x0e\x2a\x9c\x27\x4b\x53\xea\xe3\xe0\xa1\x9c\x38\xd4\x5a\x59\x92\x71\x97\x38\x41\x49\x9b\xba\xff\x55\x39\x82\x30\x75\x72\xca\x05\xbd\xb2\x10\x4b\x32\x43\x30\x27\x7c\x0f\xef\x4f\xcb\xd9\x73\xcc\x40\x39\xb1\xc8\x72\x5f\xe7\x66\xdd\x2c\xbe\x56\x75\x9d\xab\x02\xbe\x9e\x0e\xb2\xbc\xd4\x4e\x7d\x6e\x41\x13\x69\x18\x96\xdf\x3b\xbf\x61\xec\x40\x27\x8a\xb8\xb2\x96\x77\xa0\x1f\xe5\xd9\x7b\x54\x34\x55\xde\xc1\xc5\x07\xde\x8c\xab\x5f\x2c\x51\x52\xa3\xdb\xd6\x7d\xca\x37\x55\x3d\x89\xe8\x12\x65\x22\xcc\xeb\xb6\x3d\xd9\xc2\x4d\x55\x8f\x35\x58\x58\xa2\xc0\x62\x2d\x6e\xf3\x92\x1f\xbb\x20\xfa\x4e\x62\x1f\x45\xd8\x6a\x63\xbc\xf9\xa6\x18\x7f\x28\x17\x97\x9e\x44\xc7\x09\xe2\x21\xda\xfc\x00\x9e\xd4\x34\x6c\xe1\x02\x99\xdd\x37\x50\x9a\xc7\x1a\x3c\x45\x8d\x49\xc3\x76\x30\xcc\xb8\x6a\x63\x81\x84\xd6\xbf\x62\x92\x61\x89\xd5\x80\x6b\xcd\xc1\xd9\xd3\xf0\xcd\xa4\x24\x62\x89\x17\x67\xed\x82\x90\x53\xdb\x6c\xda\xaa\x1e\x02\xb9\x94\x10\x89\xd9\xcd\xe5\x4b\x9d\xff\xe7\x3f\x3f\xc7\xef\x21\x25\xb1\x53\xde\xd9\x43\x3b\x51\xc9\x1a\x7b\x36\x29\x61\x24\xf5\x95\x9b\xea\x08\xe5\xb5\x91\x28\x45\xdd\x34\x83\xd9\x4f\xe3\x24\xc3\x14\xda\x35\x38\x5e\xcc\xed\x0b\x2c\x02\xa0\xfd\x72\xfc\x99\x26\x91\x83\x48\x0d\x96\xfa\x6e\xd4\x80\x75\xe6\x10\xf8\x59\x36\xb2\x56\x69\x22\x39\xc2\x6c\x73\x4f\xc6\xe9\xbb\x61\x56\x3f\x1d\xfe\x92\xa5\xd3\xfb\x48\x63\xc1\x9c\x8e\x17\xb2\x88\x0c\x69\xcf\xb0\x9d\x53\x34\x95\xa6\x05\x79\xc0\xda\x64\xf7\x46\xc2\xeb\x4a\x29\x51\x7a\xe0\x43\xee\xf9\xab\x3e\x35\xe0\x29\x65\x0c\x09\x88\x72\xcc\xf1\xb8\x16\xe5\x70\x30\x96\x26\xe8\xb0\xa8\x53\x5d\xce\x38\x92\x7e\x19\x44\xa6\x19\x8d\x71\x4d\x6a\xeb\x5c\xbf\x16\xb0\x39\x85\x85\x27\xcd\xc0\x2a\x67\xd5\x8e\x50\xdf\xf4\x4d\xfa\x2c\x95\x44\x04\xfd\xb9\xc7\xea\xd8\x33\xd4\x2f\x9a\x9b\xfc\x27\x18\x64\xd6\xb9\xa9\xea\x2e\x8a\x59\xcf\xc2\xcc\x54\x52\x86\xeb\x81\x71\xec\x0d\xcd\x7c\x33\x73\x15\x6d\x5d\x4d\xd8\x84\x58\x2a\x0d\x41\x43\xde\x79\x01\x9b\x93\x42\x14\xc0\x79\x25\x98\xa5\x5a\xd2\x24\x09\xf8\xd9\xce\x77\x33\x3e\x0b\x31\x52\x9f\xe8\xad\x68\x0a\x69\x84\x25\x28\x17\xe8\x38\x40\xae\x83\x28\x4d\x3e\x95\x14\x6c\x46\x90\x70\xf7\xa9\x8f\x1c\x53\x2b\x9c\xa3\x81\x5d\x60\x87\xaa\x69\x77\x05\x48\x3b\xbb\x1f\x9b\xf1\x58\x04\x5a\x9a\xea\xfd\xb2\xfb\x4e\x23\xa0\x10\xa1\x55\x3b\x39\xf8\xe6\x2f\x7c\x3e\x4a\x88\xc0\xb0\xa0\x5b\xd2\x9e\x9c\x6e\x71\x67\xb3\xe3\x8f\x1e\x51\xc2\x28\x49\xa8\xa7\xaf\xe9\x66\xd6\x73\x03\x75\xd3\xfb\x31\x57\xf3\x6c\x0b\x25\x1a\x12\x11\x74\xcf\x36\x2d\x1c\xa7\xb0\x18\x46\xe3\x38\x41\x18\xad\x34\x66\x65\x72\xb7\xec\xdf\x00\xcc\x58\xa4\x66\x37\x15\x0b\x8e\x09\x85\xb7\xaa\x95\x03\x78\x78\x12\xd6\xd1\x58\x3b\x9c\xf9\xc3\xb1\xbc\xcb\xfb\x08\x8c\xc6\xa0\xb1\xa9\xfd\x4b\x59\x35\x79\x83\x88\xd7\x7e\x5b\x62\xc0\xf3\x2d\x79\x1e\xf4\xe9\x13\xa7\x69\x2a\x11\x45\xd4\x76\xe1\x4c\x51\xdc\x07\x92\x33\x46\x53\x99\xa4\x18\x24\x75\xf3\x72\x94\xd2\xa6\xa9\xa2\x08\xef\x6e\x4e\x87\xaf\xb2\x36\x4b\x79\x0c\xd5\x09\xd1\x0f\x01\x83\xdc\xd6\xaa\xd5\xae\xe8\x35\x9b\xb8\x48\x7f\x4d\x47\xde\xb4\xa3\x65\xbc\xf8\xc5\x51\xaa\xd3\x2c\x0a\xd9\x2d\x57\x04\xf0\x50\xa5\x71\xc3\xcc\xa8\xda\xc9\x10\x67\x83\xeb\xde\xc3\xfd\xf6\x69\x7d\xf5\x8c\xda\x3a\x77\x8b\x3f\x77\xf7\x0f\xbb\x1f\x5f\xd7\xdb\xd5\xed\x7a\xb3\x0d\x17\xcb\x23\x86\x80\xab\x2f\xd0\x06\xb8\x1e\xde\xcd\x6d\xfe\x36\xac\xfe\x94\x47\x8e\xe8\xbd\x73\xb0\x56\xb5\x8e\xa3\x69\x62\x90\x72\xaa\x82\x5b\x34\xea\x31\xbb\x96\x79\xf1\x71\x5b\x55\xed\xa4\x7c\x39\xbd\x3f\x61\x62\xe2\x5b\x84\x3d\x21\xef\x4d\x55\x7b\xd2\xeb\x89\x0b\x47\x33\xee\xb0\xa7\x06\x5b\xac\x82\xed\xa7\x19\x77\x52\x88\x3a\xaf\x31\x95\x37\x86\x10\x30\x9a\x09\xca\x7c\xd2\xdc\x0b\x65\x9d\xf7\x9e\x4c\x94\x00\x18\x95\x31\xc4\xbe\x54\x33\x96\xc8\x1a\xb6\x62\x7d\x4f\x17\xb2\x69\x72\x3d\x2f\x91\x85\x51\x5c\xbb\x5e\xb5\xe3\x61\x37\x6e\x7c\x64\x54\x5a\x67\x96\x6b\x9f\x95\x1d\x73\x02\x5d\x5e\x7b\xa9\x4a\x5c\x15\x25\x2f\xdb\xbb\xde\x25\xa6\x1a\x00\xeb\x2e\x8e\x87\x7a\x7d\x7b\xbb\xfe\xe7\xf3\xfa\x7a\xb7\x5d\x2d\xee\xc2\x10\x88\x63\x5c\x52\xde\x72\x78\x8f\xd3\xfe\xd7\xd4\xba\x9c\xd3\x49\xb9\xd7\xad\x65\x21\xeb\x8b\x48\x62\x46\x41\x2a\x31\xa6\x8e\xbd\xfb\xf8\xf2\x65\x8c\x66\x63\x14\x0c\x45\xef\xf4\xb6\xda\xdf\xe5\x7b\x77\x23\x81\x50\xff\xbc\x3a\x3f\xbd\x33\x1b\x3b\x28\x4e\x67\x9e\xfa\xee\x8b\x2e\x9c\x41\xaa\x4e\x74\x58\x66\x0f\xd6\xfa\xd6\x90\xce\xb4\x2f\xea\xfd\xc3\xa9\x7d\xb0\x88\x86\x6d\x6e\x64\x1e\x32\x7b\xd4\x9a\x58\xf2\x31\x8f\x5d\x95\x97\xd7\x63\xa1\x89\x8b\x56\x88\x45\x51\x34\x88\x39\xb9\xc4\xe7\xd0\xd5\xc3\x58\x94\x08\xab\x7a\x7c\x46\x78\x22\x4f\x9d\x49\x9f\x5e\x25\x8b\x68\x82\x46\xe2\x7a\x7b\x33\x06\x5b\x31\x46\x22\x47\xb5\x3f\xe3\x0a\x61\x8c\xd0\x08\x7d\xef\x89\xea\xf7\xb4\xcf\x99\x31\xa2\x24\xf1\xa5\x97\xeb\x53\xb9\x87\xaa\x9c\x0e\x9b\x5e\x04\x51\x1a\x39\x12\x1a\x59\x35\xb2\x4a\xc2\x41\xe2\x54\x23\x4e\xe0\x90\xa3\x30\xea\x0f\xd4\x01\xfc\x16\xb6\x26\x91\xc2\xc5\xe0\xdb\x87\xfe\x8e\x31\xcc\xc5\x6a\x04\x4b\x62\xe7\xf6\x95\x95\x81\x9d\x39\x1d\xe7\x26\x8e\x25\x22\x63\x10\xaa\x44\xba\x2a\x4d\xf3\x08\xb5\xd3\x19\x99\x0d\xcc\xa4\x70\x0c\xcd\x3f\x9f\x37\xd7\xe8\x2e\x0f\xbd\xdb\xdd\x66\x40\x36\xd2\xc7\xfc\x15\xde\xab\xca\x0c\x24\x38\x8c\xa5\x91\x93\x05\x18\xf1\x0f\x5c\x90\x67\x66\x9d\x1f\x81\xcf\xd6\x3b\x68\x98\x59\xae\x6a\x4c\x09\x58\xa9\xfb\x53\xb1\x34\x43\x0e\xb4\x9d\x3c\x1e\x0b\xb4\x42\x50\xb7\xb9\x9d\xf0\x68\x8f\x73\x74\xbf\x2a\x30\x30\x66\x24\x52\x15\x3e\xfd\xf5\xe7\xea\xcf\xdf\x39\x57\x9f\x4c\x47\x9e\x50\x7c\x81\x8f\x35\x7c\xbf\xff\x76\x79\x9d\x1f\x5b\x2e\x96\xe9\x2c\xb5\x13\xbd\xf9\x3f\x2e\xd5\x34\x99\x4c\xb4\xa2\x63\xa8\xc8\x98\x27\x95\x31\x15\x0b\x87\xad\xdd\xe1\x87\x10\xfa\x23\x67\x3d\x19\x8c\x29\x05\x48\xeb\x88\xaa\x38\xa8\xd9\xfb\xe8\xb1\x79\x63\xfd\xb2\xf3\xfb\x52\x86\x21\x82\x02\xdb\xf8\x50\x08\xbe\x3f\xb5\x8e\x23\x4c\x27\xbc\xd7\x79\x0b\xa1\x24\xf4\x0b\x2d\xaa\x7e\xb7\x24\x28\xbf\xdc\x76\x53\xec\x02\xeb\x1b\x63\x3a\xe1\x08\xc2\xeb\xfc\x6b\xbc\xca\xe9\x5d\x6b\x01\x48\xb0\xb2\x5d\xae\x77\xae\xb1\xe3\x97\x1a\xa8\xdd\x1b\x66\xb8\xb4\x3c\xbc\x63\xe8\x3d\xff\x58\x8d\xd6\x76\xe8\xdf\x42\x1f\x7c\x3f\x47\xb2\x32\x66\x8c\xa3\x07\x70\xa2\x7a\x0b\xf3\xd6\xcd\xb9\xe6\x17\x74\xd6\xd3\xdd\x81\x25\xf8\xf5\x04\xde\xe4\x7a\xaa\x88\x4b\xd8\xbf\x68\x68\x8e\x08\x7b\x70\x81\x1f\xcd\xd6\xbf\xda\x7e\x5d\xbe\x3b\xff\x36\x01\x54\x4f\x31\xb4\x43\xb6\x53\x27\xa0\xb6\x83\xc3\xb1\xf5\xc2\x78\x8f\x55\x55\xec\xca\xca\x31\xc3\xe9\x6a\xf4\x40\x6d\x2a\x9d\x2c\xa3\xfc\x70\xf1\x6d\x6f\xec\xac\x66\x66\x10\x37\xb4\x79\xeb\x41\xab\xc3\x76\x89\xf5\xa7\x2f\xf2\x3f\xc7\xba\x3a\x8c\x12\x41\x3c\x32\xcc\x01\x1f\xda\xea\x18\xba\xdd\x06\xbb\xc4\x23\xb0\x3c\x0e\x9c\x29\xa5\xcd\xf7\xbd\x27\x7f\x1e\x21\x71\x42\x39\xf3\x1d\xbc\x33\x27\x96\x13\x21\xcc\x98\xf7\xe5\xea\xf4\x71\xf5\xb1\x79\x3d\xcd\x90\xde\x8c\x13\x70\x10\x45\x24\xcd\xe8\x9e\xff\x72\x20\x92\x64\x3c\xb6\x0e\x1b\x71\x7c\xf9\x68\x72\x2d\x0b\x87\x2a\x0a\x5b\x53\x99\x80\xc1\xba\x70\x20\xda\x08\x5b\x28\x75\x9a\xdd\x58\x38\x5f\xeb\xea\xd7\xeb\x16\xa7\x46\x65\x3e\x31\xef\x68\x9f\xc2\x2a\x72\x5d\xca\xf1\xd3\xa1\x60\x33\x97\x5f\x6b\x51\x47\xc5\xcc\x68\x5e\xc6\x86\xbe\x3f\xd5\x28\x86\xe5\x8c\x6a\xac\x7b\xff\x58\x6f\xbf\x5e\x3f\x2d\x7e\x2c\x6e\x77\x3f\xd6\xf7\xd7\x0f\x3f\xc2\x85\x33\x41\x13\x31\x5a\x78\x6f\xaa\x1a\xf2\xfd\x3c\xb7\x10\x06\x9b\x08\x25\x57\x5e\x9c\x1f\xbd\xda\x7e\x5d\x97\x3f\x20\x77\xf0\x51\x3f\x46\x44\x11\xa6\x08\x26\xfc\x59\xbb\xbb\xe7\xdb\xed\xfa\xf1\x76\x1d\x38\x05\x19\x17\x31\x60\x44\xfb\x72\x2c\x4e\x97\xfb\xc1\x18\x17\xa9\x33\x8f\x8f\x98\xf4\xa9\xf3\xb7\x6f\xf0\xf1\x1b\x42\xe2\x4f\x44\x08\xe7\x07\xa6\x31\x1e\xb8\x84\x9f\xed\xd5\xe9\xa3\x3a\xb5\xe7\xda\xb9\x8c\x67\x2c\x4e\xd4\xb8\x3c\x81\x33\xee\xba\x0b\x3c\xc3\x5d\x64\x59\x84\x48\x81\xdb\x6a\x7f\x5f\xb5\xb9\x86\xbb\xe6\x8c\x99\x68\x62\xd4\xb8\x8c\x12\x19\x38\x31\x5b\xa4\x45\xae\x2f\xac\xd7\x5c\x46\xd6\x71\xbb\x40\xd3\x7e\xcd\xdb\x4d\x68\xdf\x1a\x89\xb7\x85\x6b\x90\x99\x63\x13\xc0\xef\x1d\xcc\x44\x49\x6e\xfa\xfe\x74\x24\xc0\x7f\x6c\xbb\x43\xde\x39\x7d\x25\x7c\x6c\xab\x6f\x00\xc7\xd9\xad\xeb\x84\x60\x18\xda\xca\x9f\x2b\x59\x77\xe1\x7f\x33\xb0\xd9\x84\x31\x54\xf1\x28\x90\xf9\xe9\xd7\x51\x20\x31\x4f\x54\x72\xad\x63\xc5\xfa\x98\xc8\x5c\xe0\x1c\x66\xdc\x28\x4b\xba\x99\xb8\xdb\xd9\xaa\x7e\x9f\x1b\xc6\x33\xb0\x86\xdf\x0b\x38\xd5\x69\x00\xa7\xc8\xd2\x75\xa8\x4e\x0e\x2c\x22\xe9\xd6\x1a\xfd\x92\x17\x66\xe5\x34\xa3\x2f\x4e\x0b\x41\x12\x9a\xb8\x2e\xf0\x12\x49\x61\xdd\xfa\xb0\x83\xf6\x65\xf7\x36\x9a\xe3\x82\xa4\x09\x71\x89\xd0\xd7\xb1\xa6\x13\x13\x04\xa2\x48\x05\x19\xa0\x00\x93\x68\xeb\x5c\x07\x4b\x2a\xe2\x28\x43\xf3\x13\xc8\xef\xee\xe4\xab\x5b\x05\xa6\x57\x12\x33\x00\xc7\xf0\xa4\x21\x7f\x3b\x97\x8d\x39\x43\x27\x0e\x8f\x44\xc4\xc2\xd1\x0b\x6d\x5e\xaa\xe3\x11\xea\xe2\xe3\x4b\x51\x29\xcf\x35\xd7\x5f\x86\x71\xcd\xe8\x88\xf3\x0a\x39\xe8\x8b\x98\xb4\x99\x90\x27\x13\x49\xa2\x1c\x71\xfc\x5f\x8b\x70\xb4\x44\x66\x98\xe1\xb8\x5d\x6c\xb6\xdb\xa7\xf5\xe2\x36\xa5\x2c\x6c\x4b\x89\x42\x60\x09\xb6\x1b\x23\xb2\xe5\x53\xe1\x82\xb0\x07\xd5\x98\x21\x0d\xaa\x69\xce\xf1\x9e\xf4\x96\xcd\x2e\x29\x15\x1a\xe1\x1d\xb2\x9b\x36\x77\xeb\xdb\x66\x7b\x66\x80\xc3\x48\x1d\x93\x2c\x50\x3d\x1c\xab\xba\x75\x62\x5b\x79\x65\xc2\x82\xb2\x2e\xbd\xfb\x1b\x6e\x80\x26\x04\x49\xb3\x7c\xa1\x36\x54\xbc\x6f\xab\x7d\xae\xfb\x31\x96\x21\xc3\xd2\xf5\xea\x76\xbb\xd8\x4d\x9e\x34\x8b\x0c\xe2\x08\xbf\x6c\xaf\xef\xa7\x1b\x48\x82\x05\xab\x27\xd0\x39\xbc\x81\xd9\x0e\xc4\x58\xb3\x8b\x66\x24\xc5\x36\x93\xbc\x59\xb4\xb7\x20\x9b\xf6\x8f\xc1\xd2\x9f\x3d\x3d\xa6\x68\x3a\xc4\x3c\x8b\x7d\x0d\x48\x15\x37\x9b\x5f\xdc\xc6\x98\xf1\x80\x43\xde\xfe\x6e\x72\xf9\x5d\x04\x75\xd1\x49\xcf\xad\x30\x2c\x8c\x22\x23\x0e\xae\x8d\x8b\xaa\x03\x89\x85\x4d\x32\xd6\xd4\x87\x40\xf7\xf0\xee\xca\x68\xd3\x03\x4b\xe1\xa4\x45\xf7\xc8\x38\xd9\x9c\x8a\xcb\xed\x87\x4c\x48\x15\x23\xfc\x03\xba\x40\x60\x9a\xcf\x10\x8a\xba\x1e\xe9\xb7\xaa\x85\xe6\x4e\x36\xaf\x57\x1f\x0f\xa1\xc5\x67\x36\x54\xc7\x4e\x09\x7a\x75\x7f\xbd\x7b\xb8\xd9\xdd\xad\xef\xb7\xbb\xeb\x9e\x1d\x85\x09\x43\x12\x07\x74\x0a\x50\x23\x47\x1f\xea\xbb\xf2\x3a\xbf\xf0\x31\xff\x09\xc5\x85\x15\x43\x98\x24\x8b\xbc\x49\x44\xdf\x71\x6d\xce\x48\x86\xfc\x48\x4b\xb9\xef\xe2\x3f\x54\x6f\x70\x53\x57\x07\x9f\xed\xb8\x1d\xb5\x1d\x87\xb1\x5c\xa0\xcd\xd8\xac\x7e\x43\x4b\xcb\x84\xcd\x48\x34\xc0\x17\x1e\xab\xe6\x1c\x2c\xf9\xbb\x15\xf3\x7f\xf9\xb7\x3f\xb1\x63\x25\x08\x60\xa5\x6b\x78\x9b\xcb\x5e\xb3\x2c\x32\x2e\xca\xfe\x1b\xf5\xfe\x21\xd3\xf3\x77\x43\xb1\xc9\x33\xcb\x62\x15\x23\xfc\x08\x35\x06\xb7\x43\x41\x3b\x8b\x21\x41\x0e\x09\x03\x9d\xef\x6b\x56\x3f\x8f\xf9\xc4\x93\xcc\x62\x70\xda\x3b\xe8\x43\x47\x3b\x28\x9b\x53\x1d\x88\xa0\x3f\x82\x9c\x5e\xb0\x0e\x59\x12\x71\x24\x9e\xef\x13\x17\x33\x5e\xbd\xd9\x65\x25\x91\xa2\xbd\xce\x63\x3f\x41\x9b\x29\xb3\x1b\xcb\x92\x2c\x4a\x7d\x73\x0c\x72\x15\x4f\xa2\xfa\xc9\x94\xcb\xa8\x31\x58\x9c\xbc\xc9\x4b\xf3\x67\xd8\x9f\x5a\x49\xc5\xc8\x1b\x1e\x9c\x86\xfe\x14\x2c\xd1\x49\x00\x24\x0f\xcc\x63\xe3\x80\x67\xe4\x8e\x64\x3c\x33\xe8\xb5\x38\xb9\x8d\xce\xa0\x34\xcb\xa2\x1a\x8a\x57\x99\x20\x9c\x79\xff\xdb\x01\x96\x1b\x2c\x14\xcc\xa6\x7d\x26\x62\x57\xf7\x29\x64\xe3\xa0\x6c\x3b\x49\x48\x7f\x0c\xab\xd2\x74\x14\xe5\x8e\xe4\xd9\x59\x96\x45\x09\x96\x7f\x7c\x97\x69\x33\xa7\x81\x9c\x9e\x27\x63\x16\x19\x0c\xb6\xd7\x2b\x07\x95\x79\x9a\xca\x2b\xb3\x2c\xe3\x16\x31\x79\xc7\xaa\x0d\x89\xab\xb0\x45\x3b\x78\x22\x6a\xdc\xa2\x99\x1b\x15\x69\x2f\x9f\x4e\x72\xc7\x80\x9a\x37\xd8\xd7\xa7\x65\x33\x9f\xfa\x52\x3a\xfe\xcb\xfe\xf9\x6c\x4e\xca\x73\xf5\xdc\x60\xc4\x74\x38\x42\x9b\xcf\x33\x17\x33\x54\x5c\xa6\xac\xc0\xc5\xf4\xcb\x5f\xdb\x8b\xf0\x91\xf3\x9a\x6a\xa6\xa9\x65\x9e\xdc\x68\x28\xfe\x64\x5a\x66\xe8\xe9\xec\x1a\x68\x9f\xaa\x02\x50\x5e\x19\xaf\xe6\x93\x7a\x62\x66\x98\xa3\x64\x6d\xa0\x5d\x35\x6d\x7e\x90\x2d\x18\x97\x8a\x9a\xda\xc0\x0c\xa4\xc5\x20\x2d\x6f\x1e\x65\x6e\x1e\x4e\xf3\xed\x96\x33\xb4\x14\x5d\x54\xff\x50\xc2\x75\xfe\xd6\xe0\x1c\x0d\x97\x66\x65\xc0\xe9\x63\xf5\xc3\x91\x64\x36\xe3\x28\x4d\x46\x29\xc1\xa4\x03\xfc\xd4\x70\xfc\x3c\x0f\x2b\x23\xe6\xea\xf0\x79\xb3\xad\x65\xf7\x22\x91\x46\xd6\x6f\x8c\x53\x05\x51\x28\x73\xb9\x1e\xa6\xa5\x2c\x8a\x6d\x7e\x80\xa6\x95\x87\xe3\xf4\x05\xca\x24\x22\xc8\xbb\xe5\x23\xb5\xc1\x60\xc8\xc4\xa6\xa8\x4b\xaa\x1d\x7f\xc2\xdd\x87\xd7\x2c\xf2\x9b\xd3\x4c\x71\xd9\xd7\xe1\x5f\xc1\x2d\x8f\x9d\xa3\x3a\xa3\x93\x67\x32\x05\x8e\xb7\xfe\x05\x5a\xe7\xb3\x8d\x9c\x65\x3f\x84\x11\x8b\xfe\xee\xae\xad\x65\x5e\x76\x1e\x77\xfc\xff\x4a\x71\x10\x8e\x1c\x47\xd8\x55\x6b\x7c\x49\x16\x69\xd8\xaf\x46\xe2\x4b\x97\xfd\x02\xc9\x4c\x06\xe3\x46\xaf\x59\x07\xd6\x6c\x34\x8f\x18\xc2\xcd\x02\x29\x28\x06\xcc\xe1\x23\x97\x9c\x32\xb4\xbd\x9d\x77\xd1\x5b\xac\x49\xf6\x5a\x76\x21\x6d\x3a\xc6\x19\xa3\x95\xf0\xf0\x88\x30\x46\x45\x88\x58\x9f\x85\x57\xd3\x87\x2d\x22\x6e\x82\xf0\xc4\x1b\x34\xed\x5c\xc0\x67\x76\xe1\x42\x3a\xf1\x69\x3d\x7c\xa9\x53\x34\x8a\xcc\x92\x0c\x83\xf5\xbf\x9e\xef\xff\x5c\xdf\x27\x7f\xf3\x03\x95\x99\x64\x42\x8d\x25\xcc\x03\xad\x9b\xdf\x2e\x13\x81\xbd\xfd\x37\x55\x75\x39\x6f\x2c\x25\xe7\x28\xfc\xfb\xdc\xc0\x6e\x15\x78\x0f\x96\x95\x99\x79\x27\x52\x72\x8d\x6f\xca\xb7\x38\xcd\x16\x1d\xa9\x52\x07\xe6\x71\x9a\x13\x3e\x3e\xf9\x3c\x0a\xfb\xf5\x6c\x52\x36\xc2\xbe\xf8\x7d\x6e\xb1\xcb\xff\xf2\x7a\x28\x35\x01\x84\x09\x2d\x50\x63\xb5\x79\xac\xab\x6a\x86\x48\x92\x26\xce\x70\xa1\xc2\xae\xe5\x5f\x43\x6e\x3d\x0c\xae\x5f\xb6\xa4\x49\x09\x36\x99\xfe\x29\x4b\x53\xcb\x09\x68\x52\x1a\x16\x39\x78\x9f\x31\x35\xe9\x7f\xcc\x2c\x52\xf1\x0c\x5c\x2a\x9b\xe7\xc7\xc7\xdb\xbf\xc2\x76\x10\x19\x66\xa6\x5d\x99\xf0\xb9\x81\xfa\x2a\x6f\x6f\x0a\x79\x99\x8e\x98\x49\x9b\x58\x44\xb4\x3c\xd6\xd0\xed\xf0\x73\x9b\xef\x65\x38\x96\x4d\x0d\x4e\xf6\x85\x2c\x9b\x97\xd3\x38\x36\x90\xd6\x30\xe4\xc6\x7e\xa9\xde\xef\x4e\x28\xa3\xba\xee\x2b\x72\x30\x14\x3d\xa5\x05\x40\x92\xd5\xcd\x3f\x9f\xd7\x4f\x4f\xab\xdb\xdd\xd5\xc3\x43\x5f\x29\x54\x51\xe4\xb2\xc6\x5f\x51\xbd\xbb\x8c\x7e\xfe\xca\x75\x54\x51\x3a\xa3\x99\x1b\x1c\x5c\x11\x86\x64\x09\x4a\x4b\xe8\x1a\x4c\xde\x5e\xcb\x6a\xfa\x05\x28\x42\x13\x6c\xbe\x30\x50\x40\x0b\x17\xdb\x76\x99\x22\xc6\xd1\xb7\x7d\xbd\xee\x2f\x34\xd6\x14\x7f\x32\xd5\xe6\xa4\x35\x40\x67\xaa\xfb\x3a\x9d\x1f\x93\x44\x12\xf4\xc5\x55\xb9\xe8\x5c\xe6\xf1\xfa\xa0\x92\xc8\x31\xd5\x1f\x72\x8f\x9b\xba\xa9\xea\x11\x8e\x5c\x25\xb1\x91\xa1\x56\x8c\x11\xc9\x70\x9a\x34\x03\x4c\xa5\x2f\x4e\xba\x3d\x0d\x65\xf5\xcb\x09\x2a\x95\x1a\x1e\x3a\x84\xbf\x42\x5d\x9d\xf3\x9f\x60\x34\xe6\x18\x2d\x5c\x45\xff\x1d\x33\x8e\x93\xc4\xb3\xa2\x54\x60\x9d\xf4\x15\x1b\x31\x67\xdb\x4c\x84\xc1\xc8\xae\x86\x63\x21\x35\x38\xe0\xfe\x4c\x5b\xdf\x8f\x65\x31\xc7\xd0\x0f\xb1\x6c\x1f\xab\xc3\x98\xd7\x72\xf2\xaa\x59\x0c\x48\x92\xf2\x5f\xd0\x8e\x52\xb5\x8a\x25\xc6\x25\x7d\xba\xa9\x78\x7b\x8e\x1d\x54\x2c\x4d\x11\xa1\xe4\x00\x15\x4f\xf2\x75\x66\x61\x14\xd3\x2e\x25\x64\xbd\x93\xe6\x2c\xaa\xeb\xb4\xdf\x14\xb2\xf7\xb1\x14\x33\x0a\x79\x7a\x16\xa7\xa6\xad\x65\x91\xcb\xb7\xe6\x11\xea\x53\xd8\xcc\x69\x82\x36\xb1\x0c\xe2\xd2\xd7\x93\x86\x57\xa6\x38\x73\xe2\xaa\xe5\xe9\x70\x23\xd5\x28\xc1\xa2\x44\x62\x30\x89\x9d\x97\xb6\xda\x6d\x3e\x0e\xaa\x6f\x2a\x54\x82\x39\x44\x0e\xae\x39\xd7\xd5\x7e\x59\xd5\xfd\x05\x09\x4d\x82\x9a\xb7\x2f\x37\x6d\x17\x0f\x1b\x68\xdb\x5e\x07\x36\x78\x02\x4a\x68\x1e\x8f\x69\xb7\x7e\x99\xcd\x50\x02\x8c\x9d\x10\xa9\x9e\x49\xbf\x30\x95\x49\x81\xee\x63\x1b\x9a\xe0\xfb\xbb\xc9\x20\x0b\x89\xf7\xab\x1a\x5e\xaa\xa1\x74\x38\xbd\x26\x95\x1a\x64\x03\x5e\x2f\x1f\x52\xcf\xfb\x1f\xb6\x64\x2a\xf5\x48\xcb\xc5\xf1\x88\xab\xc2\xf4\xa5\xea\x48\xf7\x74\x99\x77\x63\x66\x2c\xa6\xb4\xb6\x19\x19\x40\xa8\x97\x72\x8a\xca\x10\x11\x8f\x94\x2b\x26\x36\x56\x99\x2c\x46\x25\x87\x63\x21\x5b\x5b\xd5\x87\x5b\x79\x2a\xf5\xcb\x08\x84\xa8\x8c\x72\xcb\x79\xde\xdc\x79\x62\x18\x5c\xcf\x47\x15\x45\x65\x74\x2a\xfb\x02\xc8\x6d\x55\x9d\x87\xb4\xff\x8f\x7f\xdd\x79\x34\x21\x4a\x26\x3d\x50\x06\x3a\x5f\xee\xa6\xf3\x6f\xe3\x6b\x90\x3d\x92\x50\x93\x2c\x42\x3b\xd4\x13\x95\x0e\xfd\x72\x17\x97\x00\x1d\x13\x81\x54\xff\x8f\x5d\x64\xf0\xbb\x00\x5e\xc7\x89\xf3\xf0\xc3\xe4\xba\xce\x6b\xd0\x9f\xb4\xb4\xea\x98\xd9\xc0\x93\xed\x82\x8a\x0b\x06\x48\xc7\x5e\xb8\xbd\xdd\xbd\x8f\x08\x79\x98\x8e\x35\xc1\x42\xed\xf7\xd5\x66\xbb\xbe\xff\x82\x38\x84\xdd\xf2\x76\x7d\x13\xba\x73\x75\x22\x54\x0c\x9e\x2c\x37\x2f\xf7\x5f\x6a\x59\xfe\x3d\x66\x47\xa6\x13\x48\x88\x67\x31\x6e\xe7\x5e\xcb\x6c\x68\x9a\x24\x99\xed\x67\xc0\x55\x9d\x9b\xfd\xbc\x34\xa7\x53\x26\x75\x3c\x6e\x41\x3c\x3b\xe6\xf4\x55\xa6\x99\x8e\xe5\xa8\x57\xed\x06\xe0\x2e\xac\x05\xfd\x31\x95\x6b\x7c\xf8\x51\xcb\xe3\x11\xea\xdb\x11\x36\xf8\x93\x3e\x8f\xd9\x39\x20\xc2\xc6\xd1\x9d\x1a\x53\xc5\x32\x4d\x09\xc8\x78\x60\x93\xf5\x1a\x8d\xde\xdf\x9f\xde\x3a\x35\x16\xfb\x63\x1f\x97\xc3\x43\x67\x82\x7d\x12\x7d\x16\xfd\x10\xc9\x70\x99\xfd\x01\x57\xa7\x8f\x45\xf9\xf1\xb5\x3a\x35\xfd\xe9\x39\x73\x92\x21\xce\x88\x0f\x74\x3f\x4c\x73\x50\xe8\x92\xed\x3c\xa0\xf1\x57\xee\xae\xe6\x36\x65\x43\x4b\xc9\x44\x72\xdc\x8f\x10\xb1\x04\xea\x3b\xa1\xbc\xcf\x8f\xcb\x2c\x12\xa6\xcc\x6e\x54\x08\x8b\xbd\xdf\xdd\x74\x58\xcc\xdb\x7a\xb4\xd0\x89\x83\xe4\xcb\x9f\x8f\x55\xd3\xe4\x53\x58\x74\x18\x04\x24\x86\xfe\x82\x2e\xd1\x3c\x74\x63\x24\x72\x67\x7f\x7b\x5a\x05\x6c\x97\x96\x34\x76\x7c\xe3\xdd\xa7\x4c\xc4\xec\xc2\x24\x8b\x13\xf7\xb4\x7c\xa5\x6f\x7a\x40\xc9\x09\x1a\xcf\xf5\xfd\x7a\xbb\x5e\xdc\x22\x49\xf5\xee\x6a\x71\xbb\xb8\x5f\xae\xfa\x13\x08\xc3\xe9\x98\xcd\xc0\x4d\x33\x24\x66\x1d\xc9\x41\x85\xd1\x3a\xc6\xa8\xb3\x80\x76\xdd\x3e\x05\x34\xa0\x98\x3d\x7d\xc5\x98\x4b\x9a\xb6\x5e\x67\x7c\x8a\xed\xd6\x4a\x3a\x72\xc5\x6e\xfb\x78\xbd\xd0\xda\x48\x14\x3b\x2b\x64\xd3\xee\xea\xaa\xe8\x1f\x9f\xb6\x09\x66\x26\xb7\xd5\xb1\x9d\xd6\x02\xb4\x89\x19\xba\x18\xd7\xf9\x3e\x47\x2f\x25\x6c\x80\x08\xd8\xa0\x15\x7d\x07\xad\x34\xb2\x95\x17\x14\xca\x99\x86\xc4\x62\x74\x6c\x50\x41\xff\x5d\x1e\x27\x67\x80\x54\xe1\x9a\xec\xab\x19\x68\x2d\x6f\xea\xea\x70\x53\xd5\xb0\xaf\xbb\xf5\xfd\x37\x22\x86\xb3\x4f\x0f\x58\x82\x19\xe3\x1f\xf2\x0d\x5b\xbb\x83\x35\x78\xf2\x49\xb8\x8f\xfe\xc4\x32\x45\x0e\x16\xbf\x7b\xc8\x1d\x05\x77\x5f\x5b\x9b\xa1\xed\xd1\xb2\xd0\x5f\xe4\x9b\xff\xd9\x44\xd2\x20\x89\x98\xad\x01\xb6\xd5\xea\x67\x5b\xcb\xe9\x0b\x30\x91\xd2\xc8\xa2\xd9\xd7\x28\x6c\x5e\x80\xf3\xb8\xc6\xcf\xc5\x90\x04\x02\xaa\xe6\x4e\xfe\x0c\x8d\xe5\x57\xe7\xad\xee\x86\x68\xc1\x3c\x1b\xc8\x5d\xb3\x9f\x1d\xc5\xa4\xd2\xd7\xed\x56\x81\xe4\xb6\xc7\x76\x4c\x0f\x13\xb3\x94\x79\xa4\xfc\xd5\x28\x0b\x35\x7d\x80\x26\xe6\x04\x2b\x0a\xdb\x17\xb8\xbb\x7b\x78\x7a\xfc\x32\x7e\x5d\x26\x06\x4d\x5c\xdd\xd3\xf5\xa9\x9e\xa9\x51\x32\x93\x64\x19\x08\xcf\x22\x9f\x97\xfb\x27\xf8\x9f\x53\x5e\xc3\xa8\x7d\xc6\x24\x40\x91\xab\x6f\xb7\xf7\xa5\xed\x27\xd4\x42\x18\x33\x6f\x33\x93\x46\x91\x24\x03\xae\x7f\x26\xfa\xd6\x0f\x72\xb7\xd4\x4d\xcd\x49\x71\x73\x36\x39\xfe\x31\xdb\x2d\x65\x08\x36\x7e\x7c\x5a\x2f\x57\xbb\x00\xa6\x33\x54\xa4\xd8\xc4\xa0\x1d\x5b\x6d\xb3\xc1\xd6\x95\x7e\x6b\xc6\xb9\x87\x45\x22\xc6\xde\x21\xfd\xce\xa4\xe3\x99\xa1\x96\x22\xdc\x74\xe7\xfc\xaa\x31\x4e\x71\x76\xf9\x4c\x4b\x44\xc1\xe6\x37\x01\x92\x6a\x78\x22\x8d\xb7\xf1\x0e\xb2\x94\x43\x7d\xad\xfa\xad\x4a\x53\xec\x16\x2e\x9c\x2b\x0a\xbf\x32\xd4\x86\xeb\x08\x81\x0f\xcb\x97\xaa\x6a\x60\xf1\x0e\xb2\x3f\x8e\x8e\xf5\xb8\x05\x0c\x19\x7f\x2e\xf4\xee\x1b\x21\x00\x99\x4a\x8a\x61\x0a\x88\x4c\x11\xdb\x87\x41\x38\x5f\xc7\xd0\x93\x30\x2c\x8b\x98\xe6\x81\x70\x18\x5b\x2a\x3e\x85\xb7\x9b\x8c\x66\x49\x3c\x26\x06\x1b\xb7\x70\x0e\x6f\x20\x53\x8e\x9f\xf6\x2d\x87\xf7\x45\x51\xf8\xe7\xa3\x65\x3b\x33\xf6\x26\xd3\x11\x38\x5a\x17\xe4\x43\x7a\x02\xcc\xf0\xcd\x06\x49\xce\x83\xf7\x7b\x05\x6d\x73\x7f\x3a\x7c\xf6\x1c\x65\x96\x04\x41\xbf\x6d\xd5\x45\x69\x8d\x53\x82\xbf\x1c\xf9\x19\x69\x9d\x22\xe9\xd1\xe5\x52\x7e\x40\xfe\xf0\x0e\xf3\x8f\x51\xda\x0c\xc9\xd1\xb7\x5f\x17\x3f\x76\xcb\xbf\x96\xb7\xab\xdd\xed\xea\xfe\xcb\xf6\x6b\xb8\x59\x95\xb8\xe0\xe0\x1d\xf2\x9b\xaa\x3e\x57\x09\x67\x46\xe9\x28\x72\x8a\xf0\xcb\x97\xbc\xb8\x2c\x89\xc3\x8c\x36\xb1\xf5\xee\xff\xee\x76\xf5\x7d\x75\xbb\x0b\xe8\x41\x63\x94\x53\xc6\x6d\xa0\xfd\x3e\x74\xed\x7c\xf2\xcd\x18\xe8\x7d\x97\xb5\xae\x02\x8e\x6c\xc4\x50\x17\xc6\xd9\x34\x72\x4d\x6b\x48\x1c\x63\xa6\xe6\x0a\x32\x57\x64\x5d\xd4\x79\x29\x77\x72\xec\x75\x19\xc8\x58\x50\x59\x1f\x6a\xf5\x3e\xbf\x60\x2c\xb0\x38\xf0\xbd\xcb\x78\xfa\x2a\x81\x64\xce\x94\x5e\x87\x3a\xea\x6f\x53\x6b\x40\x74\x1a\x19\xdf\x35\x71\x03\x70\x7f\x3a\x38\xb6\x36\x7f\x31\x10\x73\x87\xac\xbc\x3d\x4d\xda\x5c\x20\x06\x89\x2e\x73\x17\xf9\x7f\xa2\x11\x32\x7d\x70\x90\x78\xcd\x8d\xc7\xba\x6a\x91\x43\xf7\xb7\x4c\x3c\x93\xf8\x0d\x12\x63\x33\xdf\x33\x33\x4a\x30\x4f\xcf\x91\x46\x12\x3f\x20\xe9\x32\xc2\xab\xf6\x65\x55\xfe\x2d\x90\x04\xa4\xb1\x23\xbe\xbc\xad\xf6\x0b\x14\x0f\x0f\x70\xbf\xcf\x6a\x83\xe3\x83\x8e\x05\x62\x18\xa4\x69\x46\xd3\xe9\x52\xf4\x84\x80\xf9\xe9\xcb\x4a\xb3\x18\x01\x61\xfe\x5a\x9b\x89\xc0\x0f\x83\x54\xb9\x9c\x27\xf6\x9e\xbc\xe5\xcd\xf0\x4a\x52\xa5\xd1\xf0\x1c\xe5\x47\x9f\x99\x84\x14\x22\x2c\xe6\x6d\xa1\x69\x57\xdb\xaf\x93\x77\x45\xe3\x04\x31\x2d\x0f\x47\x28\x1d\x07\x3f\x6a\x60\x5f\xb0\x73\x40\x63\xad\x3c\x3a\xe3\x0e\xbb\x3f\x3b\x7f\x75\x5d\xf6\x1e\x32\x50\xc6\x81\x8e\xe9\x02\xe4\xfc\x08\xda\xc6\x81\x60\xbd\x7b\x54\x8b\xba\x96\x1f\x73\xe9\xda\x60\xf1\x80\x02\xc1\xe4\x9f\x45\xaa\xfe\x5c\x9e\xc9\xac\x30\x60\x91\xc4\xe4\x26\x5e\x6e\x78\xa0\x37\x32\x2f\x3e\xab\xf7\x01\x8b\x5d\x0d\xd5\x2b\xac\x3a\xc9\x05\x18\xfc\xcc\x7f\x5c\xfa\xd7\xf4\x2e\x78\x4c\x90\x0d\x6d\x87\x21\x8a\xbd\xe0\x8d\x00\x17\x99\xab\x81\xbf\x80\x7e\x75\x1d\xe7\x03\x8e\x14\xb8\xd2\xb8\x7e\x1d\x4f\xed\x73\xd3\xb9\x08\xbd\xcc\x6b\x18\x60\xdd\xba\x80\x41\xe9\x38\x35\x07\x22\x01\x14\x72\xac\x65\x69\x64\xd5\xff\x4a\x33\xec\xd4\x41\x50\xd4\x28\xd8\xb8\x94\x71\x00\xa1\x12\xf4\xce\x1e\xa5\x2a\xaa\xc7\xe2\xd4\x4c\xe6\x83\x00\x8b\x9a\x0d\x88\x71\xbd\xaf\x5a\x59\xe7\xa3\x16\xfc\xb3\x46\x69\x10\x96\x62\x04\xb0\xd3\x75\xf5\x5e\x9e\x37\xd7\x43\xc6\x19\x41\x5d\xa1\x53\x51\xe8\x7a\xea\xd9\x42\x26\x01\x9b\x31\x1e\x96\xdb\xe5\xc3\xfa\xbe\xff\xd9\x10\xeb\x3a\x1f\x6e\xe7\xa2\xe7\x0c\x32\xd0\x02\xb1\x17\xff\x73\xca\x8f\xdd\xe2\x31\x26\x3d\xbd\xf4\x02\xfd\x7e\xd2\x12\xed\x2b\x10\xbe\x56\xe7\x4b\xac\x7e\xbb\xa2\x12\x71\x60\x57\x72\x3f\xfc\xa6\x92\xc8\x2d\x92\x7d\xe2\x31\x84\x71\x9f\xae\xd4\xa0\x0c\xc5\x94\xce\x66\xfb\xb4\x58\x4c\x6e\xd7\x08\x86\xd9\x89\x03\x74\x5e\x5c\xf3\x92\x1f\x2f\xd5\xb1\x00\x54\x82\x79\x42\xec\x7f\x5d\xb8\x42\xef\xc4\xf1\x03\x9b\xc5\x59\xf0\x76\xbb\x29\xfc\xe4\x16\x71\x24\x05\xf6\xff\x9e\x37\x97\x59\x12\x65\xf8\xdc\xbe\x5c\x2f\xdd\xc1\x82\x4f\x67\x09\xcd\x70\xed\x76\x59\x79\x64\x60\x5e\xcc\x8a\x24\x96\x64\xdc\x3f\x89\xff\x46\x03\x7d\x55\x55\x9d\xe7\x6a\xf5\xfc\x2c\x26\xf6\x22\xd7\xae\x0c\xb6\xc1\x66\x10\x4f\x6e\x32\x9e\xca\x96\x18\x83\x35\xe6\xdc\x56\x95\xb9\x86\x10\x3d\xd8\x58\xb9\x2c\x78\x7f\x9d\x71\xbf\x05\x14\xb6\x06\x1d\x5d\x60\xef\xb2\xc1\xcd\xb6\xba\xcb\x87\xa3\xc6\x56\x0b\xd7\x75\x78\x2c\xaa\x8f\xb5\x01\x39\x7b\xba\x36\xc9\x32\xc9\xa7\x20\xb3\x75\xf9\x56\x9d\xb1\x9d\x7b\x93\x6d\xd3\x24\x41\x8f\xb7\x75\x35\xd0\x9b\x40\x52\xcb\x6c\xca\x52\x90\x43\xa9\x15\x39\x4e\x7f\xbc\x40\x79\x55\xb5\x2f\x08\xf3\x0e\x5f\xbc\xa5\x51\x8a\x16\xd8\x54\xef\x65\x60\xc8\xf3\x9b\x18\x73\x2a\x4f\x35\xe2\xa9\x46\x00\x1e\x84\xf0\x22\xef\x7b\xe0\x77\xbf\xfc\x67\xf2\x75\x58\x06\x04\xfb\xe1\xd1\x0f\x9b\xe6\xdf\x67\xd5\x70\xcb\xb5\x6b\x27\xa8\x3d\x38\x63\x07\x3f\x41\xef\xf2\xfe\xa2\x33\x92\x78\xfe\xfa\xe5\xa9\xbf\xdc\x2c\xb3\x5a\xf5\xb4\x65\x01\xc6\x1b\x2e\xa5\x2f\x1d\x59\x99\x72\x74\xcd\x9a\x63\x31\x27\x63\xb1\x32\x73\xe8\x02\xd4\x60\x7a\x92\x97\x70\x08\xd3\x6f\xd7\x4a\x63\x47\xb0\x6f\xfc\xe0\x2f\xd3\x58\xcd\xf7\x0f\xac\xc7\xcc\xaa\x94\x61\xc7\xd6\xf2\xe1\xe1\x11\xd5\x9c\x76\x4f\xab\x1f\x8b\xa7\xc0\xaf\x67\x95\x90\x89\xcf\x60\x3f\xe6\x6f\x17\x64\x2f\xa6\x57\xa4\x4c\xe4\xb8\xd9\xa4\x2d\xaa\xd7\x33\xf9\xf5\x8b\x28\x1f\xab\x8c\xc6\x14\xe9\x19\xc9\xd3\xec\x23\x52\x36\xc5\x4f\xd5\x31\x3c\xfd\xbc\xec\x43\x5b\x9d\x50\xac\x7b\x5c\x9d\xca\xff\x54\x85\x1c\x5b\x1a\xab\x99\x91\x3e\xf1\xfd\x7c\x2c\xf2\xb2\x9f\xb3\x5a\xc5\x99\xc3\x21\x14\xd6\xd1\xe0\x84\x2d\x36\x4e\x10\x40\x7a\xc2\x86\x48\x4c\x20\xc1\xfb\xec\xcd\x59\xea\x08\xef\x77\x79\xb3\xd1\x2f\x70\x80\x90\x32\xf8\x44\x6d\x92\x59\x2b\x1c\x4f\xad\x0e\xed\xbf\x63\x5a\x73\x66\x6d\x46\x84\x87\x57\xdc\xc3\xcf\xf6\x5b\x8e\xfa\xb7\x58\x3b\x77\x43\x78\x14\x31\xc1\x7a\x4e\xbd\x2b\x84\xc9\x06\x95\x59\x11\x86\x68\x45\xa2\x50\x7b\xcb\x4b\x07\x56\xc1\x54\x4a\x38\x08\x49\x2d\x82\x3a\x4d\xd5\x6d\x72\x79\xde\xf3\x44\x0c\x8f\x08\x33\x30\xe6\x06\xde\xb5\xd5\xae\x76\xf8\x96\x5f\xfb\xb0\x3c\x22\x99\x4a\x78\x0f\xc5\x6f\xeb\xaa\x28\xa0\xfe\x55\x93\x39\x8f\x88\x74\x12\x79\x23\xa8\x9c\x6b\x92\xeb\x8c\xcc\x27\x67\x01\x47\x84\xb4\xad\x4f\x4d\x5b\x40\xd3\x8c\x24\xe0\x77\x73\x51\xe5\xd9\xbe\x71\x14\x05\x75\x05\x5f\xb6\x43\x26\x80\xf1\x60\xd2\x8f\x55\x14\x41\x73\xdd\x04\xde\x86\xec\x1e\xce\x66\xe2\x47\x24\x54\x61\xf1\x6e\xf3\x63\xfd\x7f\x57\x4f\x9b\xb6\xf3\x48\x6a\xf3\xf7\x62\x0b\x1e\xa5\xcc\xf5\xdc\x74\xce\x02\xda\xbd\x43\xf5\x36\x53\x35\xe3\x51\xaa\x32\x8c\xac\x17\x9b\x3f\xcf\x18\x64\x26\x47\xa3\x2c\x76\xa0\x99\xb2\x81\x01\x20\x39\xf3\x28\x79\x44\x3d\xf5\x60\xf7\x55\x34\x50\xaf\x2f\x4f\x5a\x1e\x31\x93\x61\x10\x8d\xf2\x05\x9b\x30\x87\xb8\x70\x29\x54\x34\xad\xb7\x13\x1c\x34\x36\x10\x4c\xff\xcf\xef\x94\x45\x04\xfd\x23\x9f\x76\xaa\x36\x3d\x53\x79\x98\xbc\x19\xc9\xa4\xc3\x2a\xb7\xf5\xa9\x74\x42\x81\x61\x93\xe1\x0e\x17\x0b\x6f\x48\x80\x87\xb1\x80\xab\x2e\xe7\xe5\x7e\xfc\x25\xf1\x48\xc6\x92\xb0\x90\xa8\x9d\x49\x04\xf3\x48\x8a\x34\x73\x62\xae\x45\x25\x91\xe6\xf9\x8f\xf9\xc3\x51\x8c\x50\xd7\x0c\x78\x42\x97\xb4\x6c\xbb\x61\xeb\xc7\x9b\x0d\xf2\x97\x84\x51\x3a\x76\xa9\x68\xf9\x0a\x28\x5f\x71\x46\xad\x42\x07\x8f\x48\xfc\xfb\x1f\xbf\xd7\xd5\xe5\x91\x96\x1c\xd1\x54\xd5\x71\x1c\x5f\xf2\xc8\xc4\x56\x38\x68\xcc\xa9\x69\xc1\x4c\xef\xd7\x24\x04\x09\xae\x97\x55\xd9\x2d\x99\xd2\x43\x0c\xa7\x0c\x7e\x3c\x82\xc8\x38\x16\x38\x63\xae\xb1\x0e\x73\x0e\x69\xe5\x11\x30\x1e\x7b\x58\xf3\x03\x02\xa2\xc6\x8c\x2d\xff\x4a\x86\x1b\x4a\xc2\xc3\x82\x2c\xe3\xde\x6e\xb5\xe5\xbc\x28\xc8\x23\xcb\x7a\x58\xfd\x63\x5d\x75\x1e\xd3\xa2\x56\xb9\xef\x7a\xbd\x81\xa1\xdf\x3e\x8c\xd7\xa0\x06\xcc\x76\x77\xf6\x5a\x7e\xc2\x35\xc8\x23\x0b\x02\xdb\xc9\x1c\x44\x79\xe7\x53\x28\xd3\x17\x4e\x22\x11\x85\x05\xe0\xee\xe3\xb6\x52\x03\xdf\x06\x27\x91\xd4\xe8\x8d\x9c\xca\x62\x5c\xb5\xf9\xcc\xa3\xe5\x24\x32\x40\x52\x27\x5f\xeb\x20\x26\xe1\x77\x30\x19\x1d\xd5\x89\xae\x86\xf4\x37\x27\x44\x25\x84\x0c\xec\xb8\xee\x0b\x1f\x88\xde\x2f\x65\xfb\x38\x89\x89\x70\xbc\x37\x75\x8e\xc5\x7a\x28\xc2\xe1\x62\x01\x98\x31\xea\x96\xa7\x2f\x75\xf5\x7e\x16\x0d\x72\x92\x50\x81\xe6\xf4\xea\xea\xea\x77\xec\x50\x9c\x24\x82\x60\x72\xc9\x55\xfb\xbf\x7d\xe8\xe9\x2b\x24\x89\xd5\x38\xbf\x74\x75\x38\xca\x36\x57\x05\xc4\x51\x38\x51\x6a\x14\xb2\x1b\x2c\x0c\x06\xdf\x1f\x48\xbd\x7b\xd1\x94\x90\x14\x22\x0c\xc8\xab\xf7\xb2\x09\x97\x3b\x95\xfc\x9d\xef\x60\x1d\x93\x68\xc0\x9e\xf6\x7d\x23\xc8\xd8\xd0\xdf\x2b\xe5\x44\x64\x83\x2c\x86\x33\x0a\x97\x93\x73\x9c\x50\x6f\xcc\xb1\xc5\x25\x10\xa3\xf8\xe0\x70\x76\x31\x17\x8a\xf0\x9c\x50\x4d\x03\x99\xbc\x63\xd3\x71\x83\x2f\x31\xc2\x72\xc2\x12\x8d\xd3\x33\x2f\xf3\x76\xd1\xfe\xfc\x5b\x44\x1b\x9c\x88\x84\x21\x69\xaf\x34\xc6\x7f\x31\x7f\xcc\x07\x68\x04\xcf\xe4\x65\xd3\xca\xb2\xcd\xe5\x84\x35\x7d\x7e\x34\xe5\x80\x25\x81\x76\x6b\x33\x97\xe6\xe8\x86\x64\x59\xef\x56\x60\xb4\x7b\x29\xca\x9d\x1d\x37\xa3\x59\x00\x3d\x7a\x15\x92\x29\x51\x31\x27\x59\x96\x24\x69\xbf\x12\x4d\xc4\xf8\x3e\xf3\x11\x67\xa7\x90\x4e\xe6\xc0\xf5\x89\xce\x32\x4d\x61\x8c\x31\x71\x3c\x7a\x1f\xdd\x0c\x18\x13\xf6\x70\x22\xa3\x94\x9a\x7e\xd9\xd9\xed\xe5\x01\x76\x4d\x9b\xeb\x3f\x26\xef\x55\x46\x0e\x19\x1f\x1e\xd3\xa2\x34\x9d\x07\xd6\x1f\x84\x58\xac\xa9\x40\xad\x09\xa3\x2e\x3a\x5c\x4a\xfd\x32\xcb\x07\xa4\x61\x78\xcc\xb0\xf1\x24\x24\xad\x66\x2f\x50\x5a\x82\xed\x60\xce\xea\x90\xc8\xa7\x45\xdd\x34\x5c\x97\x4e\x1b\xde\x8f\x55\x51\x8c\x0b\xbf\xf3\xf7\xbb\xa7\x38\x8b\x34\x4e\x43\x97\x1e\x27\x2a\x31\x34\x1e\x9a\x42\xf3\x36\xff\x0f\x94\xb3\xbe\xd0\xf1\x9f\x4f\xdb\xde\xfc\xf1\x74\x4a\x91\xf5\x55\x36\xaf\xff\xec\x42\xe9\x0b\x1c\xf4\xff\xb8\x28\xdb\xcd\x09\xa4\x12\xe1\xc2\xd2\x98\x55\xb9\xcf\x4b\xf8\xbc\xb3\x35\xec\xa1\x85\xf1\xdc\x66\xa8\xe0\xb8\xd1\x55\x0d\x67\xf1\xc4\x74\x1f\x0b\x11\xae\xf5\x77\x8b\x3f\x77\x67\x28\x3b\x1e\x47\xa9\x44\x42\x16\xf7\xa4\x83\x3c\x13\x8f\x23\xee\x62\xf8\xee\xcb\xbc\x92\xe5\xb4\xfb\x95\xc7\x51\x26\x30\xab\xf8\xcf\x51\x7d\x96\xc7\x84\xc8\xc0\xbc\x19\x00\xc9\x93\xc9\x18\x13\x25\xb2\x31\xc5\xdd\x7d\x85\x19\x84\x8b\xa5\x33\x1e\x13\x48\x43\x07\xd1\xd5\xe9\x63\x86\xc1\xe2\x71\x0c\x71\x2a\x43\x63\xf3\x7e\x7f\xb6\x3d\x89\xec\x48\xa0\x70\x99\x0f\x7c\xc0\x7e\x40\x1a\x39\x6d\x91\xb7\xea\xa4\x5f\x66\x0d\x9f\xa3\x51\xc4\xc5\x93\x4e\x5a\xf1\x61\xa4\x9c\xc1\xe3\x94\xb9\x72\xfa\x75\xde\xa8\x53\x7d\x01\xc2\xd9\x8f\xd3\x24\x20\xea\x9c\x2e\xdf\xb2\xf3\x1a\xfc\x04\xeb\x3d\xc0\x38\x65\x8e\x0a\xe7\xbf\xa5\x7e\x3d\x56\xed\xa6\xe7\x5c\xe5\x31\xe5\x12\x9b\x29\xbc\x30\x54\xaf\x7e\xd0\xf4\x03\x94\xc0\xca\xef\xae\x7b\x65\xae\x02\x18\x36\xb1\xc4\x75\x8c\xec\xf2\x26\xd8\x20\x24\xd2\x9e\x3d\x0f\xc6\x44\xe4\x9c\x85\x26\x2f\xab\x8b\x54\x8d\x3c\xe6\xc4\xc9\x42\x29\x2c\x42\x3d\x86\x53\x70\xae\x9c\x2c\x56\x5b\xd5\x03\x91\x19\x8f\xb9\xd1\x58\xad\xbe\xba\xea\x7f\x81\x98\x9a\x89\xae\x14\xc2\xce\xd6\x66\x18\x90\x78\x3a\xad\xce\x6d\x94\xba\xc8\xff\x03\xff\x3c\x85\x0f\xfa\x72\x97\xff\xe8\xfa\x00\x5c\xe0\x72\x04\x30\xbb\x62\x40\x65\xf0\x58\x10\x86\xa0\x5c\x79\x32\x79\x3b\x02\x03\x88\xd9\x21\x44\xac\xd0\x01\x56\x95\xba\x93\xaf\xd0\x20\xa9\x4b\x20\x2f\xfd\x4c\x35\x13\x7f\x8f\xa3\xfe\xef\x78\x22\x78\x45\x76\x1e\x67\xb1\x53\xd0\x40\x02\xf6\x27\xd9\xc2\x43\x39\x7e\x58\x8a\x24\xc8\x07\x26\x8d\x99\xa8\x33\xfd\x2a\xbd\xc0\x63\xc5\x65\x94\x0c\x8a\x15\x37\x00\x8f\xc5\xa9\xb9\xce\xbb\xf7\xec\xb8\x25\x26\x25\x25\x1e\x2b\xad\xbc\xea\xbb\xd3\xf1\xf8\x78\x94\xcd\x38\x49\x39\x9a\x90\x4a\x5b\x70\xb0\xb4\x22\x7f\x83\xda\xa5\xd1\x3e\x83\x6f\x4f\x1c\x81\x58\x13\x8a\xc9\xdc\x1e\xbb\x37\x7b\x7b\x43\x66\x98\xc7\x9a\xc5\x28\xe0\x79\xac\xaa\x62\xfc\x7d\x19\x1a\x67\x62\xd2\xcc\x3a\x59\x94\x62\x10\x34\x20\x55\xfd\x5c\x42\x51\xb5\xd9\x94\xb5\x09\xc7\xfe\x93\xb2\x42\x45\xad\xe3\x25\xb2\xd8\xb3\xc7\x9a\x10\x93\x22\xb2\xd5\x57\x28\xd6\xe5\x6c\x59\x99\x18\x9b\x84\x98\x4c\xbb\x62\x5b\x9d\xc3\x39\x3d\x38\x0e\xc0\x1a\x6a\x55\x82\xed\xd9\xc6\x78\x42\x6c\x82\x28\xe8\xca\x4f\xf4\xdd\xff\xfc\x62\xa6\x8f\xef\x3d\x89\xb9\x40\xc0\x5f\x10\xb9\x5f\x76\xce\x67\xe9\xb8\x47\xa7\xa7\x8e\xb3\x34\x0e\x11\x46\x55\x37\xfa\x05\xae\x2e\x90\x73\xf1\x24\x96\xae\x91\x4b\x49\xfd\x7a\x3a\xee\xba\x8f\xdf\x54\xef\x65\x28\x2b\x4e\x1f\x4f\x12\x0b\xf7\x31\x79\x5a\x86\x1e\xb1\xd1\x6d\xb2\x98\x95\xbd\x85\x9f\x83\xe6\x31\x4f\xd2\x14\x98\xed\x71\x9f\x66\x96\xea\xe3\x49\xca\x2d\x5e\xe6\xc0\x14\x7b\x7d\x66\x7e\x12\x46\x04\xa6\xfb\xe1\x4f\xe7\xae\xfc\xf3\x24\x8b\xbc\xfd\x58\x8e\xce\xc3\x74\x66\xd2\x11\x1b\x23\xae\x1d\xcd\xe8\x7b\x27\xe3\xa4\x2d\x4f\x04\x89\x63\xa7\x01\xd1\xae\x4b\xdc\x03\x19\x76\xda\x53\x5d\xae\x7e\xea\x0b\xd2\xd9\xfd\x7e\x00\xe9\x98\x9f\xfa\xd3\xac\xcf\xd4\x67\x48\x04\x73\x90\xb9\xe6\x20\x8b\xa2\xb7\x7b\x89\xb0\x92\x3a\x7d\xef\xa6\x8b\xa6\x37\x6d\x0d\xf2\x30\x7b\x95\x59\xc2\x50\x72\x0e\x7e\xbe\xc8\x53\xd3\xde\x9c\x9a\x79\xf1\xb2\x1b\xe3\x80\xac\x98\x8c\x6a\x6f\xea\xea\x3f\x50\xe2\x84\x9c\x3e\x6e\x1d\x29\x4c\x09\xba\x38\x72\xa2\x4b\xe5\x47\x98\x38\xc5\xa8\xec\x3b\xd4\xb2\x7b\xc0\x41\x8e\xf0\xb3\x3c\xea\x67\x77\x7f\xf9\xf1\x99\x44\xe2\x5a\xd7\x99\xf9\xed\xdc\x46\xfc\xfa\x01\x1a\x4a\x31\x31\xb9\x7b\x41\x70\xf6\xb2\xaa\x8a\xeb\x39\x45\x3c\x4f\x4c\x67\x1a\xff\xcf\xff\xef\xff\x3c\xae\x9e\xd6\x0f\xd7\xbb\xc5\xcd\x76\xf5\x84\x1e\xd0\xfd\xc3\x76\xb7\x7d\x5a\xdc\x6f\x6e\x56\x4f\x8b\xab\xdb\xd5\x6e\x7d\xbf\xdb\xac\x96\xe1\x3d\x18\x90\x68\xfe\x5b\x24\x5c\xf6\x3f\x5a\x96\x62\xa1\x66\x77\x74\x76\xe8\x3a\xdf\x43\xd3\xf6\x5b\xb9\xb4\x5e\xd1\xb8\xbd\xbf\xd9\x36\x5e\x7c\x7d\x54\x69\xfa\x8c\x69\x83\xa7\x51\xe4\xc4\xdd\xbc\x9c\xc3\x7f\x49\xfd\xfa\x58\x85\x23\xa7\x11\x75\xbd\x78\xda\x21\xa5\xa5\xe9\x37\x08\xa7\x5c\xb2\x87\x16\x59\x7b\xc7\xb7\x9e\x46\x32\x55\xdd\x14\x70\x90\x8e\x8f\x6b\x28\x60\xff\x69\x92\x20\x8d\x4c\x9a\x78\x8a\x8c\x6b\x38\xd6\xa0\x65\x7b\x89\xd9\x88\xa7\x84\x03\x4a\x93\x75\x01\x4b\xeb\x3c\xb7\xb0\xc5\x3a\x6a\xa4\xce\xc1\x80\x06\x8a\x62\x68\xff\xe2\x69\x42\x19\xda\xdf\xef\xcf\xb7\xcb\xc5\xfd\xee\xf1\xe9\xe1\x6e\xb5\xfd\xba\x7a\xde\xf4\x03\x34\x60\xa8\x74\xf5\xfe\x3e\xca\x4c\xf3\x34\x65\xae\x06\xe6\x3d\x38\x9f\x39\x78\xb0\x8b\xf6\xa5\x80\x16\x3e\x8b\x47\x2f\xce\xb7\x34\xe5\x19\x22\x10\xfc\x73\x1e\x3d\xe3\x34\x8b\x50\xa8\x70\xf5\xb4\xe4\x31\x99\x26\x0a\x52\x4a\x08\xe2\x2f\x70\xc9\xde\xd9\xaa\xde\x49\x63\x76\xcd\x68\x3d\x4d\xb9\x70\xb4\x7f\x37\x35\xc0\x0e\x11\x36\xbb\xc5\xee\x5a\x7e\xec\xb0\xca\xb3\x1b\xf7\xa8\xf1\x94\x2b\x37\x55\x9e\xaa\xc1\x77\x4b\x45\x9a\x22\x1f\xce\xd5\xed\xdd\x40\xe2\xc4\x53\x49\x01\x4b\xd6\xef\x90\x3f\x42\xbd\x68\x7b\x8f\x2e\x95\x22\x43\x50\xff\x97\x87\x87\x2f\xb7\xc1\xff\x4e\x15\x48\x74\xc2\xf0\x5a\x71\x25\x7c\x28\xe1\x1a\xa4\x19\xb2\xfa\x3c\xd5\x49\x82\x3e\xf8\x57\xa9\x5f\xa1\xde\x1c\xa5\x86\x2b\x59\x97\xf0\xd1\x4c\x9e\xbd\x16\x1c\x45\x1d\xa5\x19\x48\xe1\xb6\x55\x77\xd5\x23\x4f\x61\xbc\x20\xa5\x5a\x47\xd6\xe7\x3c\xef\x64\xf9\x31\x2e\x29\x4d\xd3\x45\x64\xfe\x6a\x0c\xa3\x01\xe9\xd0\xe7\x10\x2f\x2c\x79\x29\x64\x11\xb6\x93\xf7\x7d\xf1\xde\xb7\x79\xb0\xe3\xc6\x35\x9e\x82\x31\xb1\x98\xd0\x1a\x40\xdd\x7e\x60\x26\xf3\x92\xab\x92\xda\x4c\x0a\xdf\xa0\xbb\x68\xdb\x3a\x9a\x1a\x12\x1a\xb1\x34\x04\x1a\xc1\x7d\x7e\x94\xb5\x3c\xc0\xa8\x37\x7e\xec\xce\xd0\x48\x2a\xcc\x4c\x5d\x3d\xdc\x3f\x6f\x76\xdb\xf5\xdd\x6a\x33\x3f\xa4\x91\x18\xff\x7e\x91\x07\x18\x3f\x76\x4a\x44\x9c\x26\xe7\x35\xb9\x8b\xf9\x1f\x4a\x04\x85\xa1\x05\xfd\x0b\x8a\x5e\xf7\x9b\x32\x6c\x54\x0b\xb5\x55\x9f\x28\x09\x2a\x05\x8e\xae\xdb\x8f\x4d\xa2\x88\xf0\x40\xf5\x39\x4e\xf8\x5c\x50\x2c\xe7\x34\x61\x8e\x37\xf2\xcb\x09\x9a\x66\xfb\x32\x01\x1b\x2e\x5f\xba\x3d\xca\xfe\xd3\xa0\x89\x64\x2a\x0e\x34\x1f\xf5\x69\x68\xa6\x98\x78\x81\x33\x18\x0c\x89\xa7\x54\x98\x9e\x2d\xd6\xff\x19\x1e\x62\x2a\x2c\xa2\x74\x1c\x15\xd7\x79\x1b\xdd\x45\x6b\x47\x53\x19\xa5\x4e\x69\xb3\x85\xc3\x31\xd4\xf4\xbb\xdf\x65\x50\xa1\x5a\x95\x6d\xfd\x71\x75\xc1\x95\xa2\x34\x21\x68\x8e\xdd\xcc\xba\xf6\x6c\x8b\x9f\x7b\x69\x94\x75\x5e\xaa\x63\x08\x79\xdf\xb5\x2f\xb0\x2b\xe5\x01\x76\x95\xdd\xb9\xe4\xf1\x2e\x84\x45\x5d\x78\xe7\x18\xd6\x5c\x35\xda\xe9\xe9\x2f\x5f\x40\xbf\x36\x93\x98\x23\xc4\x12\x94\x1b\x1d\x84\x52\x82\x46\x0a\xa6\xd8\x6e\xea\xea\x30\x03\x36\x85\x4a\x0d\x15\xd4\xb1\x5f\x1e\xe5\x87\xeb\xe5\x0c\xf4\xed\x97\x57\x06\x9a\x25\x1a\xd7\x68\x37\x1d\xc2\x32\x72\x8e\x84\x9a\xce\x90\x8c\x42\xec\xdb\x70\x77\xc7\x1a\xde\xf2\xea\xd4\xec\xf6\xd8\x65\xbb\xc3\xd8\x6b\x67\x2a\x7d\x3a\x8c\x58\xc4\xc2\x8e\x3c\x89\x31\x4e\xb5\x79\x69\x8e\xd5\x27\x8e\x17\xcd\x32\x63\xad\xb3\xe4\x28\x08\xea\x4e\xfe\x60\x67\xdf\x98\x4c\x89\x08\xc5\xfb\x42\xe6\x07\xa4\x1a\x6b\xe5\x6b\x3f\x39\x25\xe7\x81\xc7\xfe\xf1\xe1\xe1\x76\xd7\xf9\xa4\xbb\x38\x9b\x84\x18\x54\x2a\x81\xfc\x00\x77\xb2\xed\x62\xf6\xc9\xc7\xaa\xd2\x08\x21\x29\x61\x49\xc1\x6e\x20\x8f\xbf\x72\x8d\xcd\x61\x20\x73\x02\xf5\xab\xc5\xd3\xed\x5f\xbb\xf5\xfd\xf7\xd5\x66\xfb\xf0\xb4\xf1\xb9\x98\xdd\xed\xfa\x6e\xbd\xed\xc7\x0a\x8d\x55\xd0\x57\xad\x5f\x63\xca\x9a\xb6\x9e\x5e\x90\x56\x11\x36\x93\x8c\xf0\xe3\x9c\x6a\x90\x4c\x0d\xd5\xaa\x50\x1b\x6c\x66\xdf\xae\x49\x19\xbe\x19\xd4\xbe\x24\xab\xd2\x8c\xb3\xf0\xd4\x58\x8d\x76\xee\xa2\x93\xf7\xff\xe8\xf4\x7d\xca\xcc\xc7\x29\x48\x9b\x39\x75\x33\x57\x9a\x9c\xb0\x55\x84\x31\x26\x41\x9f\xf6\x7b\x0e\xef\x5f\x7a\x78\x14\xa7\x96\x0b\x34\x01\x48\x58\x88\xa8\x96\x0b\x62\x3f\x6e\x2c\x8b\x88\x43\xc2\xad\x0a\x70\x3c\x4b\x7f\x8b\x2a\x9d\xb3\x88\x73\x70\xec\xd2\xb2\x98\x37\xa2\x9d\xfb\x73\x2c\xe2\x4e\x20\xfe\xf1\xf9\xea\x76\xbd\x74\x39\xb7\xd5\xbd\xc7\x0e\x70\x16\x5a\x9f\x90\xe0\x6f\xe9\xfa\xd8\x73\x55\x80\x77\x19\x07\xb9\xba\xdf\x3c\xf8\x70\xb8\xd4\xc5\x12\xe8\xeb\xdf\x0e\x4c\xc6\x08\x01\xbc\xf8\x51\x33\xc2\x1c\x44\xf1\xe8\x32\x51\x53\x7f\x87\xc5\x89\xc1\xc2\xc8\xa2\x6d\xa5\x7e\x71\x22\x70\xd3\xfd\x63\x29\x84\x87\x1c\x95\xe6\x06\xe0\x0a\x6c\x55\x03\x8d\xa2\xfe\x10\xd6\xd5\xfd\x90\xd6\x83\xec\x30\x40\x75\xdc\x6b\x57\x40\xc3\xa0\x84\x1a\xac\xd1\x84\xf0\xf5\x8f\x51\x4d\x70\x0e\xcc\x20\xf1\xbf\x67\x8d\xc7\xd3\x2b\x4a\x80\x60\x06\xe4\x88\x8c\x10\x93\x86\x26\xce\x52\x66\x30\xdf\xf4\xf0\xfa\x2a\x0f\xf9\xf8\xfb\x65\x34\xa2\x59\x3c\x6e\xea\xba\x92\xfa\xb5\x73\x13\x6e\xaa\xda\x37\xe6\x16\x52\x23\x69\xd4\x2c\x43\xcd\x28\x51\x9e\x35\x0a\x7b\x45\xcf\x84\x44\x39\xa3\xb1\xc5\xec\xa2\x6c\xba\xd8\x18\x21\xee\x28\xed\x34\x01\x7c\x86\xb1\x92\x67\xde\xd9\x3a\x47\x49\x84\x31\xda\x47\x8d\xd0\x1e\xa0\x69\xf2\x6b\x78\xbb\xc4\x77\xc3\x19\x35\x06\x1b\xc2\xee\xb6\xe7\x18\xe4\xbf\xf9\xd7\x1f\x89\x47\x49\x68\x94\x70\x08\x6d\x47\xe4\xd4\x3c\x76\x16\xa6\xfb\x57\x5f\xcb\x60\x3c\xca\x10\xce\x6c\xb1\xd3\x7d\xd4\x4a\x35\xe4\x05\x18\x57\x19\xf6\x5e\xd6\xd0\xd6\x39\xbc\xc1\xf7\xd9\x33\x15\xca\xd9\x9f\x9d\x17\x12\xaf\x0f\x1f\xbf\x16\xa2\x9b\x4d\x03\x61\x1d\x64\xc6\x57\x39\xc7\x35\x5c\x3f\x22\x4b\x00\x7d\xdf\xfb\x3e\x1d\xc9\x94\x50\xd8\xc8\xb4\x01\x30\x77\x88\xb5\x5b\xca\x12\x13\x0f\x61\x80\x26\xe8\xdd\xdf\x7f\x5b\x4e\x26\x8f\x4e\x0c\x84\x42\x57\xee\x43\xd7\xb0\xd0\x32\x4d\x09\x32\xbe\x6b\xa7\x33\xfb\x78\x52\x45\xae\xbf\xf5\xf1\x12\xd3\xa0\xd1\xd9\xc0\x8a\xd2\xa6\x3d\xa9\xe6\x2c\x8d\x3f\x7d\x15\xda\x1a\x84\x24\xbd\xe7\xa5\xa9\xde\xe3\x09\xc8\x97\x33\x13\x31\x5c\xd7\x31\x7b\x81\x4c\x1f\xcd\x40\x1f\xc7\x99\x21\x2e\xff\x1b\xba\x4c\x90\xbd\xf6\xa3\x0b\x0e\x7f\x73\x56\x93\x02\xce\x61\xff\x46\x6e\xf3\x72\x5f\x54\xe5\x7e\x29\x3f\x85\x3c\x7d\x62\xa6\x80\xb9\x06\xfc\x9d\x3a\x7d\xfc\xd9\x6d\x3a\x73\x21\x26\x9e\x00\x03\xa9\x99\x67\xb1\xbb\x71\xfc\x57\x5f\x2a\x59\xcc\xe6\x8b\x4d\x28\xf4\x52\xc3\xad\x7e\x39\x93\x4e\xe6\xcc\x72\x17\x41\x8d\x5a\x47\x30\x1d\x74\xe7\xa4\x1a\xce\x55\x4c\x38\xb3\x99\xc6\x09\x91\x37\xeb\xd2\xb5\x84\x56\xf5\xc7\x74\x0c\x8f\x22\xc7\x48\x5c\x95\xc5\x87\x4f\xe8\x37\x0f\x35\x7e\xe3\xb3\x91\x24\xb6\x88\xf4\x59\xca\xe3\xb1\x3b\xb7\xd7\x14\x98\x5e\x26\x27\x09\x41\x9c\xad\x92\xe5\x6b\x7d\x3a\xb6\xb3\x1e\x18\xce\x09\x8f\x10\xce\x18\xd6\x9f\x1f\x79\x89\x4c\x81\x17\xb9\x1e\x38\x27\xc6\x29\x1c\xd6\x20\xcd\x94\x29\xd6\x0f\x88\xb9\xc4\xa8\xf6\xff\xfe\xdf\x6e\x11\x1c\xcf\x6b\x1e\x4b\xe0\x51\xc8\x0e\xcb\x32\xf4\x29\x4f\x4f\x90\x58\x89\xf4\x29\x4e\x34\xfa\xbb\xac\x73\x9c\x6f\xff\xab\x0c\x10\x4f\x35\xa4\x26\xb4\x35\x22\x32\xfa\x97\x9e\x3b\xa7\x8a\xfa\x7e\x4b\xc7\x3a\x8a\x98\x92\x66\xa6\xab\xc3\x39\x4b\xa3\xcc\xe7\xff\x9e\xe6\x14\x85\x9c\x73\xe2\xd2\x4e\x66\x26\x57\xc4\xb9\x48\x79\x70\x5b\x1d\x5a\x65\x32\x25\xb9\x60\x09\x1e\xd6\x02\x32\x09\x86\xc7\x25\x04\xc7\xfa\x9a\xa9\xbe\x81\xd6\xb2\x73\xd9\xe6\xc7\xcd\x9c\xc3\xe6\xf5\xc2\x6f\x64\x51\x74\xeb\xcc\xb2\x0b\x95\x4c\x7f\x18\x05\xd8\x76\x3b\x70\x27\x70\x9e\x31\x20\x3e\x2f\x73\x26\x01\x32\x1c\x5e\x72\x8a\xa1\xe4\xf2\x69\xe1\x79\x34\x56\xf7\xd7\xbb\xeb\x45\x28\xf1\x71\x65\x12\x47\x0b\x58\x57\xfb\xd1\x4a\xcf\x35\x17\x48\x17\xbb\xc9\x5b\x5d\x1d\x26\x73\x40\x6b\x0b\x51\xa8\x79\xb9\x0c\xe2\x73\xd9\xe6\x85\x23\xde\x0c\xa3\x40\x53\xc4\x8d\xe8\xaa\x7a\xcd\x61\x20\xd0\xf1\x48\xf9\x9e\x09\x8c\x73\xb0\x4e\xfa\x67\x03\xed\x62\xf6\x74\x2c\x27\x98\x66\x7f\xfc\xfa\xb0\xba\x5f\xff\xb9\x5b\x3e\x3c\x6d\x16\x6b\xcf\x5d\xca\x45\xc4\x78\xe4\x31\x39\x47\xd9\xe6\x23\xf0\xca\xc5\xaa\x83\x20\x26\x03\xd7\xc4\x33\x2c\xa4\x4f\x18\xa6\x7d\xc2\x4e\xc3\x45\x1c\x09\x44\xf4\x3c\x3f\xee\x50\xa9\xe5\x47\x9f\x4a\x16\x71\x1a\x23\x3e\xa1\x0b\x9b\xab\x26\x6f\xa1\xfb\x5a\x06\x75\x92\xc9\x9d\x88\x84\x08\x94\x58\x3b\x22\x54\x72\x84\x5f\xe6\x22\xa1\x3c\x48\x3d\x6d\xa0\x3d\x1d\x43\x18\x1e\x5e\xbf\x48\x13\x26\x1d\x42\x29\x2f\xaf\xf3\xe6\x58\xc8\x0f\xaf\xc3\x14\x46\xd0\xc8\xea\x20\xd2\x5f\xb5\x50\xb6\xb9\x2c\x7c\x97\xf5\xf4\x76\x28\x25\x48\x2e\xb4\xaf\x2a\xef\xb5\x84\x29\x2c\xa8\x4a\xf0\xab\xfd\xbe\x7e\x5a\xdc\x22\x6b\x6c\x38\x3a\x23\x4e\x28\xe0\xfb\xf7\xeb\xab\x33\xd1\xe9\xd9\xf3\x62\xd2\xe9\xd5\x07\x1e\xb6\xd5\xa1\x0b\x58\x61\xe6\xb2\x0b\xa6\x95\xd1\x7d\xd3\xb2\x7e\xdd\x9c\xea\x63\x71\x6a\x86\x72\x97\x60\x36\x16\xda\x1f\xa8\x2a\x9b\x75\x33\x84\xf0\xd3\x27\xcb\xac\x49\xa3\x1e\x22\xd5\xcd\xb2\x66\xf2\x78\x39\x65\x81\x60\xcd\x35\xdd\x3c\x56\x45\xae\x3f\x3e\xb9\x7e\x9e\x65\xd8\x93\xf1\xcf\xa7\x6d\xd5\x3f\x5e\x11\xb9\xac\x80\x3a\x15\xaf\xee\x32\xf6\xb0\xda\xef\x87\xcd\x3a\x4a\x47\xf0\xed\xaa\x3e\xa7\x5d\x3a\x8f\x05\x84\xa0\x09\xba\xca\xcb\x17\x59\x96\x50\x2c\xba\xe0\xf7\xec\xee\x84\x8c\x30\xfb\x84\x12\xd1\xde\xa5\xbb\x93\xc7\xd9\xe3\xcc\x52\xd7\x29\xea\x73\xa1\x45\x55\xce\x1f\x78\x46\x75\x68\x5d\xf5\x46\xfb\x22\x89\x11\x17\x99\x74\x71\xef\x6d\xa5\x27\x1d\x1d\x5c\x64\x8a\xe8\x31\xa4\x15\x57\xb4\xb0\x80\x5c\x7e\x9a\x99\x92\xa8\x88\x9c\x37\xcf\xa5\x13\x07\xbb\xaa\xda\x97\xd9\x19\x25\x77\xb2\x2f\xa3\x56\xa6\x1b\x80\x73\xeb\x2c\xa4\x64\x38\x0f\xbd\xc3\xe1\x2e\xee\x72\x9a\x37\xec\x61\x1d\xb9\x9c\x87\x00\x84\xb4\x52\x9f\xb4\x16\xca\x33\xf1\x7e\x79\x7c\xfe\x39\xb9\x59\x15\x1b\x74\x47\xe1\x54\x57\x5b\x90\x87\x99\x8b\x2f\x54\xe2\xea\x31\x65\x55\x1f\x64\x91\x37\x18\x07\xac\x4b\x33\x46\xff\xf7\x6f\x5a\x29\x17\xce\x38\x45\xa1\x4f\x1e\xbc\xd2\x3a\x76\x3a\x77\xe6\xa4\xe1\x1a\xd4\xa7\x1c\x0f\xfd\x0e\x8e\x9a\x78\x44\xd1\x75\x76\x48\x8b\x95\x53\xd4\x46\xde\x56\x9e\xb6\xfd\xd2\x3a\x3c\xab\x72\x0b\x9d\xa4\xc8\x1e\x9d\xff\x90\x65\xbb\xad\xbe\xe5\x45\x71\xf7\xd1\x40\x11\x10\x7b\x42\x33\x86\x9f\x84\xcb\x62\x5e\x2d\xb6\xcb\xaf\xfd\x26\x9b\xa2\x36\x45\x17\xe1\x6d\xe1\x70\x24\x61\x83\xa1\x8e\x7d\xf8\x0b\xb4\xd7\xb9\x79\x94\x1f\x0f\xa7\x59\x92\x47\x18\x48\x11\x9c\xf5\xd0\xe3\x46\x84\x01\x81\x26\xcb\x5f\xf6\xb6\x5a\x34\x3a\xcf\xa7\x34\x01\xb3\x69\x07\xb1\xe5\x83\x98\x1c\xb2\x6f\xf6\x9e\xe4\xf0\xee\x21\x13\xc8\xda\xa1\x4e\x75\xb9\x6a\xf4\x48\x38\x28\x0c\x80\xbe\x15\xdc\x17\x90\x3b\xb7\xfa\x2a\x94\xe7\xc3\x05\xda\x8c\x61\xcf\x61\xf3\x52\x1d\xb7\xd5\x61\xf8\xdd\x32\xec\xf8\x2c\xe1\x7d\xf7\x22\x9b\x97\xe9\xad\x66\x11\x51\x1e\xc0\x52\xba\x2c\xa9\x6b\x62\xfb\xa5\x57\x94\x45\xb1\x44\x92\x03\x54\xba\xc8\xfb\x96\x16\x9e\x45\xdd\x73\xf7\xad\x79\x8b\xf2\x03\x7b\xef\xfa\x6d\xc6\xe9\xb2\x04\x0a\x5f\x27\x95\x3d\xcf\xd5\x8c\x9f\xd0\x64\xd9\xcc\x48\x1a\x61\x93\xf9\xd5\x7a\xbb\x59\x2d\xba\x55\x68\xd4\xc2\xfc\x79\x0a\x67\xb8\x6a\x92\x46\xb6\x57\x13\x5a\xf7\xa4\xa3\x61\x81\xcb\x08\x75\xd4\x2c\x56\x9e\xf4\x3c\xa3\x90\x11\x11\xd1\x78\xa4\x52\xbd\x76\x49\xeb\xbc\xdc\x3f\x75\xe1\xdb\x24\xb4\xca\x62\x45\x11\x98\x7d\x05\x6d\xb7\xba\x07\xa2\x45\x9e\xc5\x40\x30\x47\x84\x49\xd3\x65\x50\xfd\xec\x37\xc6\x6c\x58\xb4\x5c\x6e\x74\x67\x43\x7f\x0e\xcf\x92\x98\xa3\x32\xf5\xf6\x61\xbb\xb8\xdd\xad\xb6\x5f\x57\x4f\xbb\xaf\x8b\xa7\xeb\xdd\x72\xf1\xd8\x8f\xa1\xc4\x35\x4c\x3a\xd6\x4d\xec\x37\x0b\x9b\x84\xf2\x69\x18\x6c\xa8\x5a\x22\xdc\xd6\x09\xee\xdc\x39\x58\xc6\x28\x5c\xcb\x12\x65\xcd\xa0\x42\xbc\xb9\xfe\xb4\x57\x78\xf6\x90\xd3\x38\x45\xe7\xe6\xeb\xc3\x8f\xdb\xc9\xdd\xa5\xb1\x03\x5d\x5a\x00\x47\xc4\x37\x65\x75\xe1\x59\x4a\x01\x21\x1f\xb2\xfc\xc0\x94\xce\x57\xe9\x1b\x53\x9b\xd1\x08\x6c\xd7\xb8\xc9\x4b\x73\xf7\x71\x93\x37\x2f\xbb\x55\x17\x2e\x5e\xc9\x5a\x57\xc6\xe7\xc1\xb3\x30\x98\xb9\xb7\xd9\x4d\xc5\x40\x2a\xda\xfd\x2a\x91\x71\x74\xf3\xb8\xfa\x36\xb9\x3c\x1a\x31\x1c\x8e\x9a\x63\xed\xf0\x5d\x65\x94\x5a\xc4\xf9\xad\x7e\xca\xce\x21\x0a\x4a\xa4\xdb\x7a\x78\x31\x34\xcb\x10\xd7\xae\xa5\x97\xbd\x5e\x99\x7c\xdc\xb1\x3b\xce\xa3\x64\xdd\x4a\x43\xfb\xf4\xfc\xba\x7c\xcb\xbb\xff\xb7\xd5\xa5\xa4\x4b\xc6\xb5\x83\x02\x6e\xa0\x6d\xbd\x33\x37\x43\x0b\x66\x82\x1b\xa7\x6f\xbc\x59\x06\x57\x29\x13\x42\x22\x61\x88\x96\xb5\xd9\xed\xab\xc2\xec\x6c\x5e\x0f\x33\x41\x64\x0a\x7b\xb4\xd6\xcd\x32\x6f\xb1\x84\x80\x3c\xe8\x33\xcb\x20\x0c\xc5\xfc\x40\x8d\x1e\xf1\xc4\xb4\x65\x19\x8d\x31\x3f\x17\x16\xe1\x9b\xba\xf3\xce\x7f\xbd\x52\x64\x2a\x4b\xb1\x01\x0b\x3c\x61\x68\x70\xa5\x1e\xa7\x88\xef\xf9\x5e\xd2\x60\x68\xf2\x5c\xe6\x6f\x50\x37\xb2\x08\xa4\xbb\x01\x9a\xf6\xbf\x20\x26\xe6\x99\x36\x89\xf6\x54\x40\xdd\xd1\x1c\x7c\xfd\x8f\x7e\xa3\x25\xde\x7f\x45\xaf\xe2\x4c\x23\x97\x67\x26\xb5\x68\x4d\x9d\x83\x80\x54\x3b\x37\x00\x41\xff\x62\x7a\xe5\x86\x5a\xe5\x28\x34\xd5\x69\x8f\xb6\x37\x59\x9f\x0f\x92\x2e\x6a\x2e\x01\x8c\x83\xa4\x86\xab\x31\x8a\x33\x0f\x2d\x5c\x9f\x0c\xfc\x9c\x5d\x09\x44\x4a\x0c\x1c\xbc\x8b\xb2\xea\xe2\x02\x84\xcc\xc4\xb3\x91\x36\xe2\x88\xad\xbe\xba\xbf\xdf\xa1\xda\xd4\x62\xdb\x8b\xd1\xf2\xcc\xc6\x8e\x8a\xb6\x39\xa9\x43\xde\xf9\xae\x3f\x3f\x30\x92\x0b\x68\x00\xfa\xef\x71\xdd\x30\xb3\x8c\xe0\x70\x64\xc0\xbf\x86\x51\x8d\x3b\x0c\xd0\x31\x85\x31\xd9\x92\x2c\x0a\x35\x52\xe8\x9c\x66\x53\xc2\x4e\xe0\xa4\x3c\xde\x42\x0c\x29\x22\xf7\x1d\x44\xfd\x00\xc9\xbd\x77\x76\x5d\x15\xe7\x5e\x99\x8c\x98\x70\x1a\xce\x03\xec\xf0\x2e\x2f\x07\x4f\x5e\x12\xaa\x51\xe4\xc1\x19\xb4\x07\x6b\x9b\xe3\x64\xed\xbe\x9c\xbe\x0b\x3b\x4b\x2a\x3c\x1c\x0d\x65\x86\x9f\xa0\x01\x5c\x86\x67\x57\x11\x13\x81\x29\xd7\x1f\xe0\x9a\xcf\xa7\x9f\x94\x8c\xb9\xe4\x2c\xa4\xd4\xfa\x00\x6b\x26\x25\xc9\x65\x0c\x0c\x21\x9b\xdf\xab\x5c\xc3\x08\x36\x24\x13\x9e\x20\x98\xbe\x3b\xe9\xba\xbc\xbc\x52\x4f\xff\x73\xd6\x36\xcc\x25\x4d\x12\x70\x92\x5d\xfb\xc7\xba\x3a\x74\x2e\xa3\x57\xea\xff\x6c\x25\x9e\xee\xcf\x29\x43\x48\x8e\x63\x0f\x0b\x80\x14\x29\x12\xc7\x3d\xb6\xfd\xf6\x34\x36\xab\x52\x50\x97\xc8\x6f\x50\x78\x66\xf6\xb4\x84\x76\xcd\x04\x21\x4a\x7b\xfe\x95\x70\xce\xe5\xcb\xc9\x18\xc7\xef\xf9\x5d\xe6\x6d\x5e\xee\x6f\xaa\x1a\xeb\x68\x93\x5a\xbb\xcc\x98\x41\xce\x95\x63\x37\xb9\xb7\x7d\x7a\xaa\x7d\x71\x02\x04\x17\xe8\x69\xff\x31\x2b\x01\x4f\x3e\x28\x99\x89\x04\x61\x6d\xdb\xba\x2a\xa1\xce\xfb\xe5\x5d\x4a\x69\xc1\x11\xdf\xef\xf7\x05\x2c\x6a\x8c\x8e\xbf\xe7\x4d\xae\xf2\xe2\x0c\xdb\x2b\xa5\x8d\x84\x0a\x7a\xdb\xfb\xaa\xb9\xfa\xf0\x5c\x83\xd3\xef\x57\x2a\xc3\xb1\x3a\xb0\x7b\x87\x7c\x5b\xdd\xcd\xf4\xb1\xb8\xd4\x9a\x10\x8f\x40\xbc\x99\x6a\x65\xf8\x01\x86\x65\xb8\x84\xdd\xad\xef\x77\xcf\x8f\x48\x6e\x7f\x11\x47\x2c\x8d\x16\x09\x3a\xb9\xe5\x1e\x8a\x91\x37\x20\x41\x51\xd7\xf6\xe8\x94\xde\xb1\x47\x39\x5f\xde\x6c\x67\x57\x02\x20\xb0\xd1\x73\x07\xb5\x6c\xe0\xbe\x32\xf0\x35\x87\x5a\xd6\xfa\xe5\xe3\xbc\x89\x6d\x6a\x99\x25\x80\x72\x7e\x30\xe8\xea\x00\x9b\xff\x39\xe5\x75\x0d\xc5\x61\xa4\xac\xcb\xa5\x4d\x00\xb1\x94\x9b\xed\xe2\x09\x59\xea\xbe\xae\x1f\x37\xdb\xa0\x22\xc3\xa5\x55\x22\x8b\x06\xee\xe5\x19\xcb\x37\x57\x51\x44\x30\xb9\x70\x2a\x8f\xf2\xd4\xcc\x6c\xbb\x8a\xb8\x36\xbd\x1a\x04\xc6\xd0\x5f\x03\x02\xba\xbf\x45\x45\x98\x20\x24\x24\xf8\x1c\x88\xd2\x6f\x49\x52\x85\x9e\x0f\x32\xd3\x6e\x46\xe0\x1b\x95\x64\x29\x12\x10\xbb\x6f\xe6\x02\x7d\xf8\xc5\xb9\xad\x52\x9a\x08\xd6\x8b\x02\x20\x57\xe3\xd8\xd2\xaa\x94\x3b\xae\x8b\xea\x55\x1e\xf2\xbb\xbc\x47\x17\xec\xc2\x79\x69\xea\x06\xec\xa1\xc5\x85\x61\xa2\x82\xcc\x15\xcb\x00\xc5\x96\x76\xaf\x79\xdb\xce\xd5\xea\xb8\xe2\x11\xc5\x2e\xd4\xa3\xac\x9b\xa0\xc4\x30\xb2\xd9\x8a\xc7\x29\x0f\x4c\x91\x53\x14\xc6\xf4\x73\x51\x5c\x46\x18\x70\x3d\xca\x8f\xfe\x91\x08\xdf\xf4\x65\xe0\x4d\x57\x65\x3c\xb6\x19\x4a\x0a\x46\x03\x65\x9e\x2c\x5f\xa3\xb8\xdf\xa0\x20\x86\xe1\xf5\x82\xb9\xd2\xa1\x5a\xa1\x94\xcd\xb0\x2e\xdf\xd9\xd1\xc6\x8b\x73\x84\x6d\x5a\x6b\xe5\x1e\xe4\x5b\xf5\x8a\xe4\xe6\xb2\x84\xf2\x4c\xe9\x22\x8c\x06\x27\xbc\xdc\x40\x69\x06\x74\x5d\x17\xc4\x62\xea\xec\x6b\x75\x80\x71\x5c\xa3\x4c\x2c\x31\x1f\x20\x8b\xa2\x42\x58\x5a\xf2\x57\xaf\xce\xca\x55\xe7\x30\xa8\x50\x82\x39\x00\x99\x9d\xcc\x46\x0e\x05\xe7\xfc\x89\xee\x2d\x19\xf7\xaa\x5e\xf2\x63\x5b\xcd\x07\x33\x86\xa8\x51\x7f\x7b\x37\x55\xed\xa3\x90\x4f\xf2\xae\xca\x4a\x95\x25\xbd\xa2\xff\xe2\x4a\x4e\xea\xa8\x3a\xe2\x91\xe3\x95\xd3\x2f\x60\x4e\x05\x2c\x65\x71\x2e\xfb\xe1\x7a\x62\xe6\x9d\x1b\x97\xc2\x75\x4d\x32\x85\x4b\xec\xb1\x6a\xda\x1b\x6c\xa8\x3f\xaf\x6f\x69\x22\x79\xe4\xda\xf0\xe5\x1b\x14\xcf\x65\xde\x0e\x1e\x98\x26\x36\x83\x41\x25\xb9\xe7\x98\x9a\x9b\x44\x4d\x2c\xa0\xd9\xc7\x28\xf8\x13\xb5\xba\xb1\x23\xad\x93\x2c\x41\xb8\x53\x70\x58\x37\xa7\x23\xd4\xa7\xb3\x8a\xa8\x4e\x54\xc2\x59\xef\x9d\x77\x11\xf1\xe5\x3c\x89\x4e\x6c\x96\x85\x24\xae\xc3\x23\xcd\x06\xd0\xc8\xd1\xf8\xae\x9b\xed\x4b\xde\xac\x7e\xba\xb2\x56\xb8\x51\x16\x65\x8e\x3b\x59\x16\xda\x69\xa8\xcd\x76\x67\xdc\x91\x82\x3d\x55\x0a\xc5\xd9\x4c\x5e\xee\xd7\xba\xea\xf7\xd7\x2e\xf1\x81\x79\x6c\x5c\xd2\x7a\x2b\xa9\x05\xe5\xe8\x19\x2a\xd9\xea\x17\x24\x93\xb8\x80\x04\x08\x28\xa6\x90\x1d\xd2\x42\x39\x1e\x5b\xec\x58\x43\xf7\xe6\x13\x42\x5b\x3f\x5e\x66\xa9\x75\x72\x8b\xc6\x9c\x97\x96\xb5\x8a\x6d\x68\x19\x5d\x97\xad\x08\xd7\xa6\x52\x81\x42\xc1\x28\x71\xe8\xc2\x5f\xf4\xb2\xfb\xcd\x19\x8a\x85\x1f\xf2\x32\x10\x7f\xfc\xda\x48\x6a\x1d\xbb\x08\xc9\xc5\x6d\x55\x0d\xcd\xa3\xac\xa1\x6c\xe7\x30\x2f\xad\x69\x96\x86\x46\xc4\xbc\x00\x74\x13\xa0\x5e\x78\x7c\xc9\x80\x2d\x26\xfd\x91\x15\xc4\x22\xe0\x45\xd7\xcb\x07\xdf\xd0\xf2\x70\x84\x9e\x09\x83\x6b\xad\x45\x04\x8e\xfb\x66\x73\x90\x75\x4f\xc1\xe1\x7b\x70\x86\x3c\x8f\x36\x71\x82\x7d\xd1\x5b\x90\x87\xdb\x4a\xbf\xf6\x52\x43\x71\x7a\x57\x95\xed\x4b\xff\x55\x1a\x46\x23\xe7\xea\xca\x62\x04\xb2\xfe\x2c\xfc\x9e\x7f\x98\x93\x55\x55\x1b\x13\x39\x38\x6c\xb3\xd6\xd5\xba\x7c\x9c\xd6\x57\xb4\xb1\x1c\x43\xb2\x29\x7a\x75\x4c\x48\x31\x3d\x1c\x44\xae\x73\xa5\xf3\x24\x1e\x9f\x56\xbb\xf5\xf2\x61\xb7\xb9\x7d\xf8\x72\xbf\x5b\x3e\xdc\xde\xae\x96\xdb\x55\x00\x91\x68\x90\x54\x3b\x32\x33\x79\xf4\x42\xa7\x6b\xb3\xad\xae\xe5\x41\xee\xe1\xa6\xaa\x57\x25\x1a\xb1\x73\x40\xb5\xdf\xdf\x66\x12\x31\x2a\xcd\x4b\xf5\x8e\x26\x71\xb6\x3e\x69\x6b\x7a\xd2\x98\x9b\x53\x5d\xca\x19\xff\x27\xd7\x16\x00\x49\x12\x3e\x65\x66\x9e\xde\x9b\xb5\xa9\x33\x4c\xc7\xe1\x14\x36\x4d\x7c\x40\xf8\xed\x54\x36\x17\x5b\x12\x4c\x94\x38\x89\xa5\xfb\xaa\x7d\xc9\xcb\xfd\xb6\x72\x99\x95\xf9\x28\x91\x60\xe3\xf6\x0e\xba\xc8\xa9\x8b\x50\x5e\xf3\x62\xea\x01\x9c\x89\x6b\x4f\x9f\x88\x21\x49\x46\x7a\xa6\x17\x6c\xa4\xf8\x63\x36\x80\x6a\x87\xcf\x6b\x07\xd7\xcd\x10\x2e\xa2\x89\x58\xe8\x99\x8e\x36\x37\x44\x53\xb4\x46\x4e\x54\xf2\x92\xd0\xee\xf4\x66\x62\x2a\x23\x3b\x42\x49\x78\x35\xff\xe9\xa0\x34\x8a\x49\x60\xed\x76\xd4\x1c\x3f\x5e\xa0\x7c\xfc\xa8\xe5\x21\x0f\x8c\xad\xd8\x12\xdc\xe0\x42\xfc\x13\x73\x02\x81\x68\x89\x9b\x34\x4d\x31\xdb\x65\xa0\x95\xfa\x65\xa0\xa0\xe8\xb7\x33\xc2\x7b\xef\xd9\xaf\xbc\xe3\x6e\xde\x5f\x27\x23\x4c\x6a\x13\x44\x74\x9d\x4a\x47\xfd\x72\x89\x42\x96\x1b\x4a\x09\x56\x4e\x77\x8d\xb4\x5e\x76\xed\x13\xc8\x92\xa1\xd4\x29\x09\x1d\x4f\xaa\xc8\x9b\x97\x09\xf3\xcd\x24\x91\x69\x28\x8b\x99\x7f\x8f\x8e\xbf\x7d\x5c\x28\x32\x34\x73\xda\x91\xb7\xd5\x3e\x74\x96\xe1\xba\xfc\x49\x64\x32\xbb\x88\x2c\xc9\x5c\x66\xe7\xbb\xc7\x2c\x4d\xc8\xf8\xb8\x61\xc4\x22\x8e\x7e\x34\x15\x2e\xdf\x0e\x8b\x25\xf6\xd2\x06\x5f\x03\xe0\xae\x32\x48\x4d\x39\x7f\xcf\xcc\x52\xeb\x96\xb2\xf2\xb6\xda\xaf\x67\xe8\x02\xc3\x23\x1d\x44\xf0\xd6\xba\x7a\x3a\x15\x30\x4a\x4a\x1a\x4e\x12\x43\x27\xfc\xc6\xdd\x5a\x32\x79\x20\x9c\x53\x6c\x48\x83\x63\xa5\x5f\x26\x1e\xac\xe1\x82\x19\x87\xc6\xe9\x02\x6a\x57\x51\x5b\xa1\x5e\xab\x19\x73\x52\x98\x2c\x49\xb0\x7c\x0a\xe5\x10\x6c\x23\xf6\x3c\x19\xc8\xc7\xb9\xc9\xac\xc1\x15\xa2\xaa\x0d\xd4\xb7\xb2\x69\xc7\x1b\x25\xb1\xca\x89\xc7\x04\x19\xe2\x17\x79\x38\xe6\x95\x03\x4c\x85\x41\x19\xc1\x54\xfd\x75\x65\x02\xcf\x3c\x37\x4a\x44\x7e\x61\x3d\xe4\x65\x68\xd1\x9b\x3e\x23\x05\xd6\x84\x36\xdb\x9f\xba\x38\x99\x4f\xf8\x67\xb8\xd1\xb1\xcf\xf2\x43\xdb\x5d\xe1\x59\x1d\x34\x0c\xa3\x0c\x23\x6b\x97\x1c\x72\xc6\xf7\xbf\xbe\x7d\xf2\xaa\x35\x35\x99\x09\x17\x38\x7c\x60\x3a\x73\x4d\xe7\xd7\xb2\x9a\x2f\xa6\xc6\xc4\x16\x69\xe7\x16\x65\x67\x00\x7e\xfe\x96\x9e\xc0\x18\xe1\x60\x5a\xbe\x6b\xf4\xcb\x49\xd6\xb2\x6c\xa1\x5f\x48\x8d\xb1\x31\x09\xb2\x6f\xd5\x1b\xd4\x5f\xa0\xfd\xeb\xf9\x6e\x66\xa7\x20\x66\x32\x60\x46\xc2\x8e\x56\xa4\xa9\x1a\xd9\xb7\x33\xce\x36\x0e\x11\x27\x58\x9b\xc5\x52\xd0\x28\x63\xb9\xac\xea\x1a\x74\x5b\x7c\xa0\xcc\x4a\xc0\x0e\xe7\x55\xe9\xc1\xfa\xbd\x27\xde\x1f\x48\xc5\x58\x95\xc4\xc2\x03\x7a\x1b\xd3\xe7\x0e\x44\x08\x1f\xb2\xa1\x4f\xf8\x9b\x96\xab\xc9\xcd\x01\xb1\x12\xe2\xd1\x72\x75\x91\xe1\x73\xb6\x4f\x9c\xb8\x08\xef\x45\xd6\x46\xcb\xe3\xf3\x26\x2c\xbf\x10\x7b\xfa\xb7\xc7\x53\x51\xf8\x04\xeb\x52\x1e\x47\x88\x2b\x88\x85\x70\x7e\x86\xf7\xfe\x47\xcc\x3b\x97\x97\x64\x48\x33\x2d\x9d\x22\xb9\xed\xdb\xa1\xfe\xce\x55\xa6\x90\xd1\x40\xbc\x19\x38\x00\xc6\x57\x42\x13\x87\xbc\xf2\x18\x65\x8c\x9d\x57\xdb\xaf\x3d\x3f\xdd\xa0\xb0\xc6\x81\x2a\xc0\xe5\xcc\x8f\xdd\x1d\x4e\x45\xbf\x09\x40\xd2\x49\xa1\x6c\x24\x19\xc6\x81\x45\x3a\xe6\x7d\x6c\xb1\x08\xfa\x8d\x72\xae\x49\xc2\x81\x49\x86\xf9\xf1\x6e\x25\xf1\x2a\xc9\x85\x2c\xff\x18\xb6\xca\xee\xdb\xba\x5b\x6d\x37\xac\xff\x51\xc7\xd6\x09\x17\x0c\x94\x20\x61\x1b\x27\xda\xf0\x50\x3a\x82\xb5\xae\xbe\x3a\xc1\xdc\xe9\xe4\x06\x2e\x2d\x66\xa9\xa4\x31\xeb\xc7\x9b\xcd\x4d\x5e\xc0\x9c\x15\x6c\xd6\x90\x30\xdd\x5f\x70\x82\xf9\x07\x35\xe7\xd7\xe3\x20\x6c\x1a\x91\x01\x7a\x7d\x2b\x4b\xe3\xb8\xe0\xa7\xf7\x9d\x89\x14\xab\x77\x2e\x18\x45\xaf\xb4\xf8\xc0\x5c\xeb\xe5\x33\x4a\xca\x92\x5e\x6f\xbf\xb9\xfa\xb8\x6d\xf5\xf6\xe7\x64\xbd\x01\x29\x32\x0c\xbd\xfb\x4e\xed\xf0\xbb\x92\x58\x12\x37\x60\xe5\xa9\x68\x3d\x9f\xf6\x14\xe7\x0b\x12\x0c\xb6\x0f\xec\xf2\x66\xe6\xfc\x81\x4a\xd2\xc4\x11\xd2\xeb\xaa\xc6\x80\xa5\x33\xe9\x9f\x74\xcd\x86\x7d\x32\x2a\x7d\xb7\x6f\x5e\x6e\x8e\xa0\xf3\x01\xae\x37\xff\x26\xff\x15\xff\x3b\xec\xa5\x63\xfc\xa4\x3d\x29\xf5\xce\xe6\x3f\x3f\x97\x41\xea\xf7\xe1\xd2\x71\x54\xef\x6f\x65\xed\x05\x0c\x02\x59\xf2\xaf\xbf\x15\x88\x53\xe9\x5b\x26\xee\x4f\x87\x4f\x1e\xbc\xa5\x02\x2b\xf9\x5a\x96\xd7\x60\xeb\xaa\x69\x3d\x75\x4b\x78\x74\x36\x22\x04\x9f\xbb\xe9\x4c\x1e\xbe\x9e\x95\xac\x8b\x8f\x40\xd0\x36\x8c\x4b\x62\x9c\x34\xee\x95\x9f\x2b\x9c\x73\x1b\xa5\x26\x1e\x04\xa9\x6e\xc1\xec\xcf\x85\x57\xff\x75\x8e\x87\x3e\x03\x9a\x58\x92\x25\xd4\xf6\x94\xfd\x33\xd3\x38\x3d\x27\xc9\x18\xc6\x96\xa8\x0b\x98\x9b\x75\xb0\x6a\x96\x58\x86\x71\x7f\x2d\x6b\x27\xd5\x73\x2e\xbb\xc9\x6d\x9c\xc4\x08\x25\x55\xa7\x8f\x9b\x93\x7e\xed\xef\x35\xd6\x4c\xf1\x11\xb3\xc3\x83\xb5\xa8\x70\x3d\x42\xb8\x7f\x92\x4d\x0f\x07\x30\x1c\x7b\xbb\x6e\xab\x72\xbf\x85\x3a\xa4\x7d\x6d\x12\x53\x14\x46\x71\x0f\x11\x2f\xc9\x19\x39\x0c\x6d\xa7\x17\x97\x32\xad\x46\x39\xac\x39\x48\xc3\xa6\x5c\x61\x8a\xb2\x79\xd9\x99\x0a\xf5\x5a\xc3\x59\x52\x43\xc7\x52\x23\x7d\xf3\xfc\xe5\xd9\x6e\xa9\x54\x5e\x90\xa1\xf5\x75\xf2\x16\x15\xe4\x0e\xd5\x65\xeb\x6e\x59\xec\x42\xd9\x9b\x53\x69\x26\xca\x2f\xdc\x32\x0a\xb1\x6f\x7e\x9b\x72\xdc\xba\x6f\xbd\xbf\x78\xc6\x52\x30\x41\xed\x7b\x13\x8a\x4d\xab\xeb\xdd\xf6\x61\xf7\xf8\xf4\xf0\x70\x13\x0e\xc8\x23\x85\xd9\xba\x1f\x55\x5d\xfc\x5d\x8e\x35\xcb\x55\x16\x8d\xf8\x78\xd1\xb8\xcf\x91\x95\x56\x30\x85\x31\x50\xfb\x02\x4f\xf9\xdb\x70\x0b\x19\x49\x9d\xe3\x24\x75\xed\x03\x85\x7e\x53\xea\xa8\x78\x64\x5e\x5f\xd7\x5e\x61\x61\xdd\x34\xa7\x6e\x58\xaf\x44\xc8\xad\xe4\x11\xea\x51\xee\xdc\x6b\xc6\x3a\xd0\xa4\x25\x79\xf6\x3c\xa5\x24\xac\x27\xf3\xc5\x8b\xfd\x92\xbf\xc1\x19\xf5\x8a\x1f\xad\xa4\x8e\x3c\x9a\x18\xbd\x91\x5e\x20\x28\x24\x8e\x86\x54\x82\x55\x2a\x43\xbb\x18\x26\x72\x30\x8e\x17\x63\x18\xab\x93\x2c\x73\xa6\xb2\x0d\xd0\xde\xdf\x04\x47\x56\x0b\x89\x20\x20\x7d\x6a\xda\xea\x30\xa5\xc7\x09\x43\xb2\x0c\x43\xc0\x00\x84\x3f\x5d\x74\x1c\x7e\x0d\xb9\xb6\xc6\xc6\x6a\xec\xf2\xd4\x9d\x57\xf0\x2b\xc5\x40\x6e\x81\x4a\xb4\x22\x37\x4f\xab\x95\x63\xbc\x7c\x7c\x7c\x58\xdf\x87\xd6\x24\x6b\x0d\xd7\x03\x6e\xe1\x1e\xfa\x87\x73\x56\xdf\xba\x6c\x7a\xac\x11\x2c\xe9\x45\xcb\xbe\xe6\xc6\x40\x19\x04\x21\x27\xd5\x3c\x11\x45\x22\x46\x05\x95\x43\x5e\xb6\xa8\x0a\xe1\x9f\xed\x85\xd9\x20\x22\x12\x39\xed\x39\xe4\x46\xc9\xcb\xfd\xa6\x94\x79\x31\x96\xa0\x11\x51\x4c\xe8\xb4\xa8\x9e\xf7\x09\x43\x11\xc5\x31\x35\xd4\xa7\x9f\x9d\x2a\xce\xb9\x11\xee\x87\x1a\x8f\xac\xd6\x9d\x27\xed\x98\x97\x3e\xa5\xf4\x1c\xe2\xa4\x6e\x4f\x40\xd1\xb7\xc5\xab\x3a\x15\x27\xb7\x70\xac\x97\x0f\xfd\x35\x68\x96\x79\x93\xe2\x83\xb5\xe9\xfc\xef\xa7\xa8\x88\x62\x1b\x39\xd2\x60\xf9\x86\x6a\xf1\xe3\x84\xbc\x88\x52\xee\x58\x6d\xf6\xd0\x3a\xbd\x9d\x99\x08\x9a\x88\x28\x4b\xb2\x78\xc4\xff\x71\x61\x66\x8b\x88\x72\x27\x05\xa1\xab\xd2\xe6\xf5\x21\x7c\x32\x2e\x49\xd3\x8f\x31\x88\x5c\xec\x15\x94\x90\x31\x73\x5b\x39\xb6\x9e\xd3\xd0\xad\x28\x22\x2a\x12\x04\x50\xea\x02\x64\x8d\x3d\xce\xd3\x57\x48\x85\xc0\xea\xeb\x8b\x7c\x03\xb3\x70\xc6\x22\x9c\x86\xc5\x80\xf1\xcd\xf7\xf5\xd3\xf6\x7b\xc0\xac\x8a\x88\x29\x89\x3a\xd4\xeb\x52\x55\xed\x04\x29\x78\xd6\x64\x26\x22\x1e\x39\x7e\x0e\x53\xbd\x97\xdb\x17\xb8\xee\xdc\x94\xf5\xe1\x00\x26\xef\xe3\x50\x11\xf1\xd4\x60\xd1\xf0\x15\x3c\x5b\x59\xf8\x9d\x39\x5e\x96\x76\x10\x16\xdb\x56\x0f\xe5\xfb\xf0\x24\x38\x8f\x12\x33\xb0\x8a\x7e\x91\x8d\x5b\x3c\x87\xaf\x5a\x44\x5c\x30\xed\xbd\x0f\x64\xbc\xc1\x16\xf9\xe9\x53\xe0\x42\xd2\x21\xe6\x5e\xa0\x58\xcb\x7c\x72\x85\xa1\x19\x70\x35\x22\xe8\x7c\xb0\xde\x51\x9b\x1d\x52\xc4\xb1\x13\xad\xa8\xf2\xf2\xb6\x0a\xa4\x9b\xd3\x77\x2d\x80\x20\xf8\x5c\x41\xfb\x50\x7a\xef\x76\x76\x14\x00\x42\x03\x45\x00\x3a\x45\x33\xc7\x5e\x44\x19\x48\x4c\x77\xbe\xe4\xde\x71\xf0\xbf\x2b\xee\x3c\x06\xef\xe3\xfd\x3a\x6c\x0b\xfb\x98\x0c\xb5\x41\x06\xdc\x23\xb6\xd2\xff\x31\x7e\xa3\xca\xb8\x6c\x8b\x71\xbd\x2e\x57\x4e\x40\x6e\x57\x95\xc5\xc7\xae\xa7\x88\x16\x91\x8e\x2c\x62\x2a\x96\x0f\x77\xeb\x6f\xab\x11\x75\xb8\x88\x74\x2c\xb1\x5c\x5f\xe2\x1d\x3f\xd8\xe0\xe2\x06\x0f\x4e\x44\x9a\x46\x58\xc5\x5b\x37\x8f\x35\x1c\x64\x7b\xaa\xe7\x8f\x57\x5b\xc7\x84\x8b\x6e\xba\x27\x93\x95\xfd\xcc\x05\xce\xb1\xa8\x84\x86\x29\xa8\xae\xf5\x1b\x65\x8a\x6b\xc7\xa3\x6c\xeb\xaa\x73\x09\x82\xf2\xf5\xec\xc1\x82\x75\xe4\xd7\x58\x15\xfd\xd1\xb9\x0e\x60\x6e\xaa\x5f\xd2\xc5\x8a\xc8\xc6\x29\x06\x64\xb7\x00\x9b\x93\x6f\x75\x0c\x9b\x92\xcc\x63\x99\xb1\x06\x70\x81\xf8\x5d\x10\x92\x11\xd4\x27\xbc\xbe\x5f\x6c\xd7\x7f\x8e\x56\x74\x41\x62\xcb\xb1\x40\xbf\x88\x9f\x27\xbf\xa7\xa9\x75\x40\xad\xea\xed\x20\xa7\x82\xad\x82\xd0\x48\xe3\x97\xf5\x45\x1e\x86\xdb\x0c\xdb\x08\xc5\x64\xe4\x4b\xf5\x7e\x27\xcb\x0f\x24\x50\x58\x97\x3f\x20\xdf\x56\x57\x58\xaf\x1e\xdb\x1c\x42\xa9\x03\x8d\x37\xd0\x3a\x7c\x57\xbd\x1a\xd9\x6b\x3f\x88\xc5\x1c\xe1\x55\x08\xa9\x1e\x44\xbd\x66\x83\x7c\x73\xb3\x96\x85\x9e\x10\xf3\x8f\x6c\x2d\x61\x4a\x66\x8e\x1f\xcd\xb5\x41\xcc\x9e\x13\xf7\xf2\x96\x47\xf9\x71\x25\xcb\xd7\x41\x06\x4a\x10\x9e\xc4\x1e\xff\xde\xde\xc2\x1b\x99\x9d\x9c\xa7\x0c\x79\xb1\x9e\xba\xd5\x66\xf2\x1c\xb9\x20\x68\x78\x8f\xa7\xf2\x15\xad\xd0\x59\x4b\xa8\x1f\x28\x52\x6e\x58\xef\x19\x7b\x35\x30\xa8\x37\x37\xdb\x51\x65\xf0\x52\x8b\xa0\x20\x22\x8b\xb1\xc9\x73\xd9\xb9\x05\xa6\x9a\x9c\x3f\x33\x26\x14\xb6\x9d\x29\x68\x6e\xea\xea\x80\x1a\x0c\xde\x14\xf9\x81\x32\x91\xe0\x04\x65\xdb\xfc\x0d\x36\xcb\x07\x74\xa3\xa6\x5f\x32\x91\x82\x68\x0f\xcd\xbf\xcb\x4b\x27\x9f\x36\x1b\x21\x05\xf6\x52\x6d\x9e\xbe\x6f\xbe\x8d\x3e\x4f\xa2\x8c\x23\x43\xf3\xf5\x13\xaf\xf6\xbe\x28\x8d\x47\xd3\x7f\xc6\x3f\x75\x1e\x38\x4d\xfe\x35\x04\x51\x33\x74\xd2\xd0\x59\xda\x33\xdd\x76\x17\x6f\x53\x57\x8a\x74\x45\xd7\x8b\x9e\x93\x20\x3a\x16\x81\xe0\xed\x7b\x85\x2e\x88\x23\xeb\x0f\x9b\xa9\x04\xa7\xc6\xff\x36\xaf\xba\x89\x30\x84\x13\xa7\x5d\x64\x5d\xf5\xcc\xdc\x57\xef\xae\x6d\xb0\x3f\x88\x14\xa8\xa9\x21\xcd\x7f\x9f\x1a\x6c\x46\xef\x0f\x84\xa5\xb5\x68\xec\xd1\x0b\x62\x48\x84\x26\x1b\x73\xe6\x1a\x4b\xf7\x4e\x6e\xd8\x21\x6c\xfb\xea\x7b\x37\xd2\x44\x2e\x5f\xf0\xe6\x19\x16\x75\x95\xf4\x1b\x53\x82\x3e\xff\xa3\x9c\xf1\xc5\x09\x02\xcc\x11\x0d\x21\xde\xc3\x69\x87\x86\xbd\x2c\x21\x31\xed\xfd\xe2\xe7\xb2\xa9\x0a\xb3\x91\x16\x36\x07\x39\x7c\x21\x36\xd1\x28\x8d\xe5\xbd\x5c\xbf\x22\x5e\xb4\x67\xc4\xea\x58\x8e\xc8\xbf\x47\x5d\xce\x43\x94\x32\xdf\xc5\x32\x9c\xc8\xae\xdb\xf1\xd1\x95\x0e\xc0\xb8\xe2\x41\x33\xae\x47\x8a\x38\xd2\x19\xb6\x32\xa1\x42\x9a\x17\x3b\x10\x71\x64\x34\x86\x79\x52\xa9\x93\x7e\x99\xaf\xd6\x31\xd1\x02\xf3\x24\x0b\xad\xa1\x70\x74\xc4\xb8\x14\x87\xdd\x63\xe6\x10\x69\x79\xb3\x2e\x07\xc0\x8f\x88\xe3\xcc\xa0\xe1\xbf\x93\xe3\xee\x0b\x11\xa7\x91\x41\xf7\xbb\xc8\x9b\xf6\xb1\xfe\xd0\x6d\xd5\x5f\x49\x1a\x47\xf8\xee\x7b\xf6\xef\x3b\xd9\xea\x17\x7c\x95\xbb\xbe\x02\x4d\xd2\x61\x76\x87\x7f\x8b\x7f\xb1\x7f\x4f\x48\x4a\x3f\xf9\x7f\x7f\x1e\x4a\x84\x1c\x74\xe8\x74\xa0\x4d\xb8\xb0\x68\xf7\x8f\x8e\xc6\xdc\xfa\xac\xf9\x3d\xbc\x8f\x49\x56\xc2\x00\x21\x52\x2f\x67\x7f\x01\x42\x29\x62\x96\xb8\x24\xb3\x45\x03\x3b\xf5\x66\x63\x26\x88\x89\x03\xb5\x6e\x0d\xd7\x08\x8a\x3f\x40\x83\xa9\x85\x59\xf0\x31\x3d\x2d\x52\xed\x74\x13\xf7\x76\xb9\x9c\x3c\x66\x4e\x05\x62\x3f\x57\xdb\xaf\x4f\x4e\x25\xcf\xf4\x9b\x44\x82\x1d\xc8\xd7\xa0\xa1\x6c\x4f\x75\x5e\x5d\x68\xd7\x14\x31\x57\x31\x0d\x02\xe5\x5d\x24\xd3\xe3\xdd\x47\x60\x8c\x2e\x7e\x89\x30\x2a\xd9\x6c\x56\xe1\x27\x61\x25\x5a\x93\xed\x8b\x74\x4c\x47\xc1\xad\x6e\xce\xe9\x96\x44\x9c\xc5\x12\x9d\x4a\xf0\x1a\x24\xb3\xab\xc8\x52\x3a\x02\x3b\x23\xe2\x31\xef\x1c\xf9\x8b\x26\x3f\xce\x4c\x82\x88\x23\xc0\xaa\x42\xf3\xc7\xe4\x50\x32\x75\xe4\x23\xea\x54\x77\xbe\xeb\xa2\x34\x9d\xb5\xfb\xac\x50\x39\x32\xa6\xe3\xb9\x23\xa9\x16\x9d\xbd\xfe\xfa\xe3\xcb\xf4\x81\x4b\x15\x29\x9f\xe1\x38\x1d\x7f\x07\x85\xfc\xdf\xfe\xf5\xe7\x50\x69\x84\xad\x16\xfe\x61\x74\xee\xf3\xd7\xea\x54\x17\x1f\x7f\x8c\x1e\xa8\x62\xae\xec\x9d\x3b\x82\x35\x27\x61\x14\x20\xb4\xfd\x18\x8b\x01\x5e\x2f\x42\xf0\x5c\x6a\x8c\xa2\xc6\x5f\xb0\x32\x4e\x73\xa9\x29\xe5\xb1\x79\xa9\x5a\x5f\xdd\xa8\xea\xcb\x0d\xb9\x22\xd6\x92\x86\x82\xea\x4e\x36\x4d\xa5\x03\x27\x71\xd8\xae\x25\x66\x28\x3a\x1b\x39\xf2\xd5\x62\x43\x52\x3b\x30\x19\x7d\x3d\xaa\xfb\xca\xa0\x62\xe7\xac\x39\xe6\xbc\x2c\x24\x62\x13\x9b\x64\xc0\xfb\x74\x2f\xf4\xa9\x0a\x0c\x52\x22\x36\x2c\xc2\xbe\xcb\xce\xd8\x5c\x9b\xf3\xa2\xf4\xf4\xf1\x9a\xcc\xa9\x60\xbe\xe7\x45\xf1\x81\x0d\x43\xb2\x78\x9d\xbc\x64\x80\x18\x35\xc3\x7c\xf0\x8a\xc4\xe5\xd3\x67\x60\x69\x14\x4d\x14\x0c\x9c\xfc\xf0\xf9\xf7\x95\x44\x8c\xf3\xa0\x5f\x77\x70\x1d\xf4\xe8\x15\x6e\xa0\x28\xe6\x43\x8d\xc4\xa2\xac\xef\xee\xf9\x6c\x52\xa1\x67\x32\xb9\x9c\x24\xb2\x31\xba\x2f\xcd\x49\x8d\xe8\x54\x67\x87\x27\x9c\x09\xda\x53\xd0\x7e\x96\xe6\x08\x83\x7d\x29\x66\xd7\x7d\x46\xbf\xc6\x94\x8c\x3f\x9c\x24\xc9\x24\x96\xd0\x96\xf5\xc7\xb1\xad\x36\x5a\x16\xc7\xde\xdf\x4d\x52\x92\xc5\x71\xf0\xfe\x5d\xe9\xcd\xe9\xf2\x86\x01\x54\x6a\xc4\xa1\xc1\xcf\x8b\xd6\x70\xfa\x22\x13\xc6\x53\x66\x7a\xcd\x9b\x4d\x0b\x21\x56\x49\x38\xd1\xd8\xfb\x07\xa5\x41\x22\x92\x61\xba\x27\x5c\x29\xc4\x65\x62\xce\x71\x77\xf3\xf0\x7c\x7f\x1d\x70\xa1\x22\xe1\x10\xe1\x67\xdf\x4d\xb2\xdd\x4b\xde\x60\xbb\xfc\xf4\xa4\x59\x2c\xa5\xa7\xae\xd8\xe4\xaa\x98\x6b\x07\x8a\x44\x82\x4b\xa3\x5d\xe5\xed\xf2\x05\x35\x3b\xc6\x73\x2b\x51\x29\x47\x57\xc6\x37\x05\xe6\x6d\x7b\xc6\x90\x39\x7f\x33\xe3\x2f\x21\x51\x92\x53\x0f\x0a\xa8\xbd\x4e\xf0\x98\x1f\x25\x8c\x02\x92\x3a\x0e\xbb\xe0\x6b\x8e\xb8\x38\xa6\x37\xa4\x53\xa7\xa9\x1e\x22\xc6\xd0\xfa\x18\x2e\xd8\x10\x8e\x2b\xb9\x2e\x72\x28\x1d\xfb\xd0\x64\x6a\x86\xb4\x48\x62\x68\x8a\x0d\x7e\xc8\xfa\xe9\x56\xd9\x59\xd6\x55\x24\x46\x49\xcc\xba\x35\xae\xaa\xf2\x2d\x6f\xdb\x7c\x06\xf7\xee\x06\x39\x04\xa5\x33\x14\xf8\x65\xc1\xa5\x45\x25\x01\x13\x61\x4b\xea\xaa\x34\x3c\x5c\xae\x8d\x9c\x7b\x1a\x98\x51\xef\x7a\xcd\xa9\xcb\xae\x55\x62\x89\x40\x06\x26\x9c\x94\x3d\x12\x78\x0c\x0c\x17\x89\x05\x67\x23\x9f\xe0\xd4\x34\x79\x0b\x3f\x47\x76\x2d\x8d\x44\x8a\x70\xe0\x1d\xa6\x2f\xea\x91\xf2\xfb\xe4\xcd\xa5\x91\x8a\xac\x08\x4a\x3b\x3f\xa1\x38\x77\x2f\xd2\xc8\xa6\x98\xba\x97\xdd\xa7\x31\x6e\x5e\x98\xce\xfc\x94\x44\x2e\xe6\xa9\xca\xee\x4b\xfe\x8c\xc6\xf7\x93\x9c\xea\xa7\xbf\xff\xd2\x6c\xa6\x24\x21\xc8\x19\x50\x1c\x8c\x0c\xb7\x4e\x54\x86\x80\xe5\x57\xe4\x9f\x08\x68\x0d\x91\xc6\x22\x71\x44\xed\xb5\x2c\x7d\x1b\xf3\x35\x7e\xa4\xd3\xe9\x90\x26\x99\x42\xf2\x4b\xb4\x88\xd2\xda\x02\x6e\x1f\xb6\xae\xf6\x70\xf1\x65\xa5\x89\x72\xa8\xea\xdd\x90\x5a\x7c\x3e\xee\x6b\x69\x40\x3a\xe8\xfc\x39\xf0\x4a\xa4\x29\x91\x98\xd2\xf7\xa4\xc2\x57\xf9\x04\xeb\x22\x52\x4a\x9c\x8a\x22\xce\x00\xef\xb3\x85\x57\x9f\xd2\x84\xa2\x87\x95\xf7\x7d\x80\x9b\x23\x84\xb2\xe8\xf4\x09\xd1\xc4\x22\x8d\xac\x9f\xb7\x3e\x15\x79\xf9\x69\x52\x43\x30\xe3\x73\x2f\x0f\xd3\x98\x35\x65\xb1\x72\x44\x91\x55\x89\x76\xfa\x62\x90\x96\xb2\x04\xf0\x41\xdc\x00\x60\x47\x3a\x98\xe5\x10\x8d\xa4\x2c\xd3\x5e\x29\xd6\x89\xe8\x22\x55\x18\xca\x6c\x07\xe4\x02\xca\x18\xc9\xb1\xde\xc7\x19\x50\x70\x36\xad\xfe\xf5\xef\x8b\xf5\x64\x91\x72\x26\x79\x10\x6d\x0f\x64\xa1\x97\x2f\x5a\x44\x0e\x38\xe3\x49\x20\x9a\x47\xa8\x43\x93\xe7\xec\x51\x0a\x4a\x9d\x8c\xd6\x4b\x75\xdc\xbc\x54\xd0\xbf\x0e\xc1\x15\xc0\x90\xf0\xf1\xbd\x5d\x33\x0c\xf2\xec\x4e\x42\x00\x9c\x0a\xc9\xad\x1c\xe1\xdc\x1f\xab\x56\xb6\xd5\x7c\x71\x4f\x33\x22\xf1\x83\x5e\x2f\xef\xff\x79\x46\x90\xf0\xdb\xaf\x6a\x7e\x2c\xc0\x5c\xad\x76\x40\x3c\x87\xe4\x6c\x56\x85\x3c\x36\xbd\x89\x4d\x33\x6d\x39\x1f\xf5\xb7\x5c\xaf\xef\x5d\xd7\x49\x53\x15\x6f\x9f\x70\x3d\x88\x34\xb3\x0c\x73\x69\x18\xd9\xec\xf2\x80\xf9\x15\xa9\xb4\x8e\xe9\xc1\x67\x29\xf1\x56\x7b\x90\xee\x24\xf3\x9a\x1a\xeb\x92\x93\x38\x9d\x1f\x5d\x67\xcd\xea\x6a\x19\x8e\x04\x69\x86\xad\xa0\xb2\xbe\x8c\xee\x15\x29\x08\x86\xb1\x6c\x73\xda\xef\xa1\x69\x9f\xeb\xe2\x72\x8e\x37\x05\x13\x31\x8f\xf3\xbd\x92\x6d\x5b\x60\x07\xfa\xed\x88\x0f\xd2\x8d\xa3\x84\x30\x54\x0f\x87\xd2\x3c\x58\x0c\xc4\xff\x08\x5b\x18\xc3\x3a\x99\xdc\xc3\xf0\x7d\x52\xa2\x5c\xbb\xd6\xcd\x7f\x7d\xed\x7f\xb2\xc4\x03\x64\xe0\xa7\x81\xb7\x6e\x0e\x85\x4d\x31\xb5\xa6\x47\x22\x78\x38\xe0\x10\xe6\xd0\xd8\x52\xed\x2a\xc2\x79\x61\x70\x15\x78\x2e\xf3\xf6\x32\x77\x9f\xa0\x29\x71\xba\xf1\x1e\xab\x74\x2b\x9b\x76\x2c\x2d\x26\x68\x9a\xb8\x34\x22\x66\xc9\xab\xc3\xda\xfc\x74\x44\x8c\xab\xa2\x01\xac\xf7\x37\x13\x0e\x70\x41\x69\xcc\x33\x18\x0b\xa5\xf5\xd6\x68\x56\xbb\xa1\xd4\xf8\x78\xca\x79\x4a\x21\x4e\x3a\x67\x14\x13\x94\x19\x85\x34\x9c\x08\xed\x5d\x16\xd5\x30\xf1\x28\x17\x19\xfa\x49\x9e\x88\x1f\x26\x62\xcd\xbf\x5b\x26\xa6\xef\x8d\x2b\x11\x18\xb1\x7d\x8d\xef\xea\xc3\xff\xc3\x4b\x32\x06\x47\x81\x0a\xe0\x98\x1e\x52\xf9\xfe\x0a\x64\x3d\x5a\x4b\xa9\x00\x4b\x02\x02\x0b\x25\xa1\xee\x2b\x87\xae\x5a\xca\xb2\xbd\xaa\x41\x06\xad\x0c\x41\xb3\x84\x72\x97\xad\xee\xee\xbb\x77\x0a\xa8\x14\xee\xad\x9c\x51\x73\xcf\x2e\x58\x66\x89\xe3\x0c\xd0\xd5\x63\x5d\x69\x00\xd3\x37\x00\x09\x2a\x75\x82\x3d\xe4\xb9\xae\x56\xa8\x2c\xe6\x7f\x57\x91\xc5\xd2\xf2\x55\xde\xea\x2a\x2f\xef\xe4\xcf\x7e\x0b\x49\x13\x7f\xda\x40\x21\xe4\x12\x3b\xdd\xbf\x2e\x90\x9b\x08\xaa\x38\x0f\x9d\xe2\x01\xc0\xe9\xdd\x87\x4b\x1c\x9c\x13\x5f\x82\x2a\x1d\x63\x17\xe3\x3b\xe4\x4f\x32\x6f\xc0\x5c\x9f\xba\xad\xee\x7b\x19\xa5\xe2\xa8\xd2\xd4\x25\x1e\xab\x6a\x61\xcc\x25\x02\x24\x41\x95\x4d\x20\x0d\xeb\xdf\xed\xa9\xbf\x25\xcd\x2c\x62\xf0\x71\x75\xfe\x0a\xb2\x68\xfb\x87\xaf\xc1\x39\x20\xdf\xf3\x76\xbc\x78\x51\x13\x3b\x06\x9c\x12\xde\xaf\x1d\xcd\xfe\xff\x9f\xb3\x37\xdb\x6e\x1c\x47\xb6\x40\x7f\xa7\x1f\xfa\x81\x13\x48\xe0\x51\x96\xe5\x4c\x57\x79\x3a\x92\x32\xb3\xfa\x9e\x75\x96\x56\x00\x08\x58\x2c\x4b\xa4\x9a\xa4\x32\xad\xfa\xfa\xbb\x18\x00\x38\x89\x76\xd5\xbd\x2f\x9d\x5d\x26\x48\x71\x00\x02\x31\xec\xd8\x1b\xe4\x34\x10\x69\xa7\x2e\x73\xdb\xc0\x37\x12\xcb\x69\x40\xbd\x0d\x88\x76\xfe\xc6\x1f\x19\x78\x80\x0c\x43\x30\xa9\xc3\xb5\xed\x54\x57\xac\x60\x28\x05\x75\x46\xfe\x72\xcc\xeb\x8b\x6b\xda\x77\xce\x8c\x90\x99\xa3\x6a\x68\xb7\x23\xcb\x62\x3a\xc7\xaa\xcb\xd3\x30\x66\x94\xc8\xf6\x2d\xc9\x4f\x78\x3e\x42\xf5\x66\x41\x5f\xe3\xcb\xa6\xa1\x08\x28\x55\x46\xf3\x76\x4e\xe0\x8d\xa7\x51\xa0\x09\xbc\xe3\xcb\x07\xe3\x0a\x43\x1a\xc5\xb6\x69\xe3\x98\x17\x94\x84\xbb\xc5\x03\x5c\xba\x83\x46\x53\xa6\x0e\x9b\xfd\xa4\x21\x94\xa7\x71\x18\x32\xf4\xad\x58\xf7\xd3\x1b\x8b\xd3\x80\x88\xad\x07\x0c\x1c\x23\x37\x37\x4d\x14\x23\xdb\xeb\x8b\x48\x9b\x33\xb9\x6e\xe6\x7c\x78\x21\x82\x2e\x37\x8c\x29\xdb\x76\x4a\xb2\x61\x58\x5d\x75\x22\xf2\x34\x15\x9a\x22\x33\xeb\x09\x11\x6b\xc0\x74\x8b\x4f\x21\xd2\x41\x44\xd0\x50\xa8\x9b\xf2\x58\x76\x97\x87\x48\x13\x22\x71\xa7\xd1\x36\x2d\x7d\x56\xe8\xe7\x29\x24\x16\xbf\x72\x93\x37\xf5\xb9\x7a\xed\xde\x05\xb0\x88\x78\x9f\x7a\xfe\xd8\x21\xd8\x93\xa7\x90\x0a\xef\x0c\x3c\xc2\x7b\xeb\x18\x6e\xda\x79\x48\xe9\x96\x6e\x8c\x48\xc8\x96\x3c\x42\x5d\xe7\x3f\xf1\x70\x71\xb3\x14\x2e\x58\x3d\x17\x87\xbc\xc0\x09\xe9\x31\x4f\x41\x66\x44\x27\xf2\xf8\x9f\xcd\x7f\x1e\x6f\x9e\x1f\xba\xbf\xab\x88\x1a\x93\x49\x48\xec\xd9\xbc\xd8\x2b\xf6\xe0\x1c\x37\x4c\x86\x8a\xb4\xdf\x6e\x89\xbe\x69\x59\x56\xdd\xf3\x28\x65\x08\x95\xa6\x11\x9a\x7d\x1b\x3b\xec\x8c\xa7\x2b\xe0\xa9\x32\x19\x41\xc5\x1f\xf3\xa2\x41\xbd\x6a\xf6\x96\xa3\xed\x43\xfa\xa3\x7f\x96\x89\x4a\x95\xe1\x89\x2b\x95\x6e\x73\xac\x46\x4c\x7d\x3c\xd5\x3a\x24\xa8\xc1\x72\x69\xab\x6a\x04\x1f\xf2\x07\x31\x09\x29\x87\xe2\xa6\x00\xbc\xff\xc0\x7c\x32\x03\x90\x47\x3c\xee\x05\x39\xe8\xbe\xfd\xe9\x06\x94\xec\xc0\xd0\x1b\x74\x42\x5f\xf3\x6d\x10\xfe\x14\xc5\xa8\x73\xe2\x00\x75\xd3\x4b\xe3\xf2\x2c\xe0\x09\xcd\xa7\x1a\x1b\x47\x35\xb7\xdc\x0f\x3d\x73\x3f\x4c\x64\x44\xa1\x43\x4c\x9f\x77\xb9\x69\x2e\x9b\xfc\xdd\x37\xec\xbb\x31\x61\x94\x92\x79\xfb\x42\x9d\x15\x3e\x95\xe9\x0f\xf2\xd0\x39\xdd\xcd\x77\x38\x1f\x08\x8f\x30\x5e\x17\x59\x14\x71\x42\x3b\xe4\xaa\xf4\xb4\xb6\x14\xde\xde\x17\x53\x65\x13\x9e\x45\x06\x13\x97\xae\x71\x5e\xc0\x6c\x32\x34\x8b\x59\x4c\x9e\x40\x3b\x2b\xbf\x4c\x71\x64\x3c\x8b\x33\x4e\x50\x68\xfb\x1d\x48\x62\xc2\xe4\xa8\x3b\xe9\x9e\xd3\x78\x6f\xfa\xf7\xe4\x6c\x65\xa9\x41\x6b\x6c\x86\x38\xd3\xf9\x44\x85\x3b\x27\x09\x05\x4d\x0b\x6d\x21\xec\x64\xc1\x06\xd3\x26\x63\x41\xc6\x9d\x27\xf8\xad\xc8\xff\x7b\xc6\xdf\x71\x8e\x1b\xd3\x7b\x8e\x19\x53\x40\xc6\xb2\x94\x7f\xa2\x6a\x7e\x2f\x72\xd3\x5d\x2a\x8d\x43\xd2\x1b\x7f\x39\xc0\xe5\x0f\xd6\xfd\x55\x30\xcb\xfc\xd4\x4e\xca\x2f\xf9\x4f\x5c\xfc\xea\xcc\x67\x96\x0a\x31\xc2\x79\x74\x64\xa6\xe1\xe4\xbd\xa6\x3a\xa2\x68\xae\xfa\xf5\x05\xfc\xf2\xcc\x44\x1c\x50\xb6\x9c\x98\xcf\xfa\x3f\x82\xad\x8c\x13\x33\xc2\xd7\xdf\xbf\x4c\x83\x9a\xd1\x5e\x92\x09\x93\x91\xcb\x7c\xbc\xdc\x56\x65\x81\x43\x1f\x78\xf2\xf6\x41\x25\x99\xa7\x1d\xbb\xab\xca\xa3\x03\x6f\x4e\x9a\x68\x27\xe7\x18\x41\xca\xb2\x34\x45\x09\xee\x62\x9d\x82\x19\x18\x4f\x26\x83\x94\x90\x7c\x6d\x34\xed\xc2\xe8\x69\x17\xe3\xe4\xdb\xaa\x48\x76\xfc\x06\x03\xac\xea\x2d\x69\xf9\x9f\x87\xfc\xe6\xfe\x04\x8d\x21\x3a\x98\xd4\xeb\x95\xe2\x3f\xcf\x74\x6a\x11\x64\xf7\xcb\x67\xa0\xda\xab\x7f\xa9\x26\x42\x7a\xd3\xa7\x33\x29\x99\x9c\xe7\xdb\x36\xfb\xe7\x36\xc0\x2d\x0f\x4d\xeb\xe0\xda\xda\x6c\x77\x04\x45\xdc\xf3\x9d\x8d\x43\x46\x3b\x86\x07\x91\x05\x2e\xde\x40\xa1\xa0\x9a\xee\xab\x3c\x90\x99\x05\x9e\x2c\x16\x6a\x88\xcd\x75\x87\xc3\x20\xa0\x09\x70\x7b\xff\xb2\xdb\x7e\xf1\x15\x12\x1e\x0a\xee\x5b\x1b\x69\x95\xdf\x5c\x56\xdb\xaf\xe3\xe5\xc9\xa3\x30\xe2\x8e\xa5\x4c\xe3\x62\xf8\x06\x78\x94\x72\xe8\xe0\x18\x54\x24\xb2\x5d\xff\x7e\x32\xf2\x98\x33\xca\xc8\x40\x01\xaa\x9c\x00\xa3\xda\x28\x10\x9d\x93\x75\x83\xcd\x28\x5d\x31\x7e\x73\x3c\x31\x11\xa9\x38\xd8\x8d\xf2\xe0\xc8\x45\x3e\x7d\xdb\xad\x6f\x48\x7d\x1d\xbe\x97\xd9\xfa\x11\xdb\xf2\x11\x8a\xcb\x5c\x17\xa9\x3b\x2d\x4d\x6c\x75\xb6\x8d\x42\x9a\x7f\xc0\xc5\xc4\x79\x9a\xda\xc2\xa7\x97\x3f\xc8\x15\x3e\x42\x71\x86\xc3\x24\x2f\xcb\x53\xc5\x42\x37\x33\x0b\xcb\xec\x38\xe3\x37\x73\x1e\xa7\x5e\x61\xba\x13\x98\x1c\x6e\xdf\x9c\x73\x49\xf9\xeb\x5d\x97\xd9\xf7\xf9\x50\xe7\x2a\x7d\xb6\x71\x4e\x76\x24\x2e\x22\x93\x3a\x52\xd7\x6e\x4a\x59\x87\x6e\xca\x4b\xc2\x39\x08\x2b\xd8\xda\x6e\xf9\x37\xe7\xcb\x66\x0f\xd5\xfc\xae\x3d\xe9\xad\x1e\xe8\x0d\x8c\x27\xa5\x0c\x6d\x7c\xe4\xf9\x55\xfa\xcd\x95\x4b\xa6\xa8\x82\xe3\x12\x04\x9e\xc6\x6e\x7e\xcd\x73\x69\x22\x2e\xbd\x52\x5f\x71\x6e\x67\xe2\x73\x81\xf3\xec\x6c\xdd\x29\x22\x8a\xbb\x72\xcd\xea\x08\xf9\xe1\x8a\x22\x81\x73\x15\x59\xd1\x40\x0f\x6a\x71\x0d\xd2\x93\xc5\xa5\xa4\xc4\x9e\x49\x67\x63\xa1\x51\x23\x63\xc3\xaf\xff\xd7\x9f\x6b\xac\xc8\x3c\x1e\xf3\xc6\x02\x10\xa8\xb7\x85\x32\x85\x13\xcf\x7c\xa8\xe9\xc8\xb9\x8e\x33\x8a\x66\x6f\xca\x03\x56\xa3\xfc\x1c\xd7\x29\x50\x03\x92\xc9\x0b\xbd\xc1\x63\x6e\xd9\xd0\x5a\xcf\x62\x4c\x9c\xcc\xb9\x06\xad\x7c\x26\x0f\xeb\xc6\x37\x82\x4d\xde\x02\xa6\x92\xbc\xa0\xd7\xfc\x27\x6e\x09\x78\xdb\xee\x66\x93\x97\x80\x99\x15\xe7\x2b\xce\xc7\x67\xf3\x78\x69\xf6\xb9\xea\x20\x9f\x1c\x55\x48\x9d\x80\xc7\xbc\x18\x1a\xe5\xfb\xe2\x5b\xad\x97\x83\x5c\x09\x47\x8c\x84\xf4\x44\x43\xfe\x8f\x26\xca\x68\x8b\x5f\x1e\xca\xb3\x76\x11\xb3\x3f\x94\x21\xd1\x93\x1d\xac\x5a\x98\x25\x30\xf3\xc7\x38\x23\xe6\xc9\xfb\xaf\x2f\x8f\xdd\xdf\x84\xcd\xee\x5b\x5a\x93\xf1\x23\x88\x20\x52\x2a\x1d\x6c\x66\x5f\x4c\xf3\xd9\x46\x26\xc2\x28\x64\xaa\xeb\xdb\xec\xf7\x60\x11\x8a\x90\xd8\x08\x6e\x9f\x3b\x53\x2b\x42\x65\x59\xf7\xdc\x84\x7b\x57\x78\x9a\xba\x4b\xe3\x59\x2d\xa2\x44\xf2\x70\xa0\xa8\xf0\xaf\xb9\x6a\x8b\x88\xc3\x94\xe2\xcb\x03\xfe\xc4\xc3\x2e\xf2\xf2\x61\xdd\x51\x4b\xf2\x24\xcf\x17\x92\x37\x99\x91\xd9\xe0\x22\x8e\x0c\x6d\x64\xb2\x51\x0e\xe1\x7d\x7e\xdd\x37\xe3\x88\x4f\xc4\xb1\x96\xca\x87\xe0\xd6\xd2\xac\xf1\x98\x77\xc9\x2f\x11\xeb\x84\x6e\xb7\x2a\xf4\xf6\xb8\x6a\xf6\xbb\x79\x63\x2e\x58\x10\x52\x71\xf3\xe6\xac\xde\xea\x41\x66\x45\x30\x2e\x89\x60\x7a\xf7\x8a\xcd\xf6\xbd\x8d\x1f\x6e\x06\xfd\x3f\xa3\x45\xd0\xdd\x7a\x1a\x2b\xee\xdc\xff\x9b\xbc\xb5\x85\x15\x0c\xd2\x7b\x23\xc5\x6f\x2e\x52\x66\xdb\x78\x07\xf4\x83\xed\xc3\xdc\x9d\x0b\xdd\xa3\x10\x45\x9a\x25\xc2\x45\x5d\xd4\x0c\xbc\x1e\xd0\xe5\xfb\x21\x26\xce\x5c\x26\xc9\xe6\xa3\x9a\x2e\x36\x14\x59\x98\x12\xa8\x61\x71\x7b\xbb\xde\x3d\x2e\xfe\xb3\xd8\x3d\xaf\xbf\x74\x07\xe3\xcc\xc8\x2e\xbd\xeb\x3c\x5c\xcf\xf8\x39\x7e\x4d\x19\x84\x2a\xf5\xbe\xfa\xe1\x8c\xdb\xd2\x76\xbc\x74\x97\x02\x4b\x44\x4c\x65\x7e\x07\x89\x18\xb0\xbd\x71\x91\xa1\xcd\x99\xd4\xa7\x43\xde\x6c\xf7\x78\x33\xd1\x96\xe1\x82\x9b\x24\xe8\xd0\x1e\xe7\x42\xdf\x17\x54\xb0\x1b\xf7\xe7\xb2\xf9\xfd\x55\x88\x20\xa6\xaa\xb1\x6b\x21\x28\x0f\x65\x75\x73\x38\x77\xbf\x0e\x61\x96\xc4\xbd\x92\xd6\x44\x2e\x84\x0b\xc9\x39\x25\x1e\x7b\x34\x93\x4f\xe9\x0a\x95\x4a\x72\x99\x77\x16\xb8\x7e\x8b\x06\xdb\x0f\x34\xa4\x8c\x73\xd6\x53\xe8\x0c\xbc\x96\xd6\xf9\xf4\x3d\x07\xd7\xb1\xd6\x4c\xbd\xf5\xf1\x3f\xe3\x10\xed\x33\x41\x57\x2e\xb4\x82\xc4\x36\xbb\x1f\xf3\x66\xe5\xe3\xa9\x39\x1d\x9d\xfe\x1c\x64\x48\xc0\x87\xae\x45\xe9\x7f\x1a\xef\xdc\x0b\xcc\x2c\x4b\x4a\x6b\x4b\x37\x4d\xae\xde\x3e\xda\xa1\x84\x89\x03\xa2\x20\xbe\x5b\xbc\xb4\x33\xd4\xb5\xdb\xfa\x10\x42\x18\x6d\xf9\xb3\x7f\xe2\x3e\x57\x07\xb4\xfe\xad\x3d\x06\x81\x54\x5a\x7b\x72\x2e\x97\xf0\x1d\x6f\xd0\x6e\x60\x18\x45\x10\x75\x82\xe5\x8e\xa6\xe2\x9b\xa3\x14\xf2\x63\x44\x68\x45\xcd\x2d\x91\x2c\x10\x43\x3b\x45\x17\x77\x38\x99\xb4\x10\x2a\xa0\x6a\xdb\xa1\x4b\x34\x0f\xc2\x2a\x88\x04\x8f\xa0\xff\xb0\x84\x4e\x43\x6a\x8b\xea\x64\x9a\x39\xc4\x2c\xd5\x9e\xb3\xc6\x8a\x9e\x8d\xee\x38\xe6\x31\xc1\x57\xff\xac\x4b\xcb\x1a\xe6\xda\xa8\x67\x5c\x29\x88\x75\xe8\x05\xbb\xbf\x15\xca\xe2\xfc\x6c\x5f\xfd\x38\xa0\x1c\xad\x0a\x48\x44\x40\x9d\x03\x8a\x74\x28\xdc\x1f\x59\xa0\xd0\x79\x65\x94\x6b\x9c\x0d\x74\x81\xc5\x61\xec\x98\x93\x7b\x86\x9a\xf1\x1b\x62\x4e\x4f\xa6\xd7\xf2\x9f\x46\x9f\x90\xf2\x8c\x4a\xac\x26\xb7\xe2\x2c\x03\x14\x33\x64\x81\x45\xe1\x83\x6a\xf7\x0f\xab\x75\x96\x17\xaf\x93\x1f\xc9\x92\x98\x92\x00\x75\x5e\xbc\x9e\x0f\x50\xdd\x6e\xbf\xf7\x42\x67\x1c\x32\x11\x13\x7a\xe7\x0b\x36\x3f\xf2\x83\x5e\x42\x65\x99\x7a\x26\x57\xe1\x99\xa4\xba\xa2\xef\xcd\xd9\x3a\x7a\xf2\xe3\x7c\xab\x36\x07\x08\x8c\xa5\x49\x68\x5d\x80\x35\x74\x89\x21\x00\xa9\x8d\x55\xf5\x79\x7f\xcc\x0b\xac\xea\x3f\x06\x72\x3a\x1c\xc0\x24\x84\x71\x7e\x05\x92\xf2\xdb\x9f\x8d\xe9\x9f\x58\x06\x61\x60\x3b\x6e\x89\xfb\x3f\x57\xf9\x89\x52\x65\x63\x67\xd7\x0f\x86\x20\x30\x83\x94\xce\x4c\x2e\x19\x94\x89\xe9\x2e\x5b\xef\xe8\xb7\x52\x4e\xae\xa0\x93\x94\x54\x39\x1f\x56\x36\x63\x34\x69\xd7\xe4\x80\x69\x44\x99\xcf\xc5\xf3\xfd\xa6\xfb\x1b\x97\xd4\x6b\xf0\xb3\x6c\xf0\xbe\x78\x24\xa2\xaf\xdf\x71\xe2\x21\x81\xc9\x32\xab\x6b\x4e\xb8\x8a\xdd\x69\x9e\x2b\xf2\x23\x7b\xf4\xef\xd9\x0d\x50\x06\x22\xa2\x8e\x5c\xd0\x9a\xd2\xec\x5b\x38\x75\xb1\xfd\x5c\xb8\x22\x03\x88\xa0\x93\x57\xcb\xc9\x58\xbe\x40\x5d\xcf\x72\x03\x71\x19\xa2\xa1\x0d\x4b\xe6\xfa\xd9\xb8\x85\x3a\x6b\xae\x64\x68\x22\xa1\xba\x9e\xc8\x1b\xd2\x2b\x1e\xbf\x5b\x19\x31\x46\x7e\xb2\x41\xb5\xff\x5e\x36\xf8\x74\x3e\xb6\x31\x23\x14\x7a\xa4\x49\xe3\x46\x27\x31\xa3\x9f\x7e\xc4\x2a\x6f\xfa\xd6\x1d\x99\xc4\x19\xb1\x30\x10\x78\x74\x04\xac\x93\x09\xc4\x14\xce\xb6\xbe\x6c\xbb\x25\xc2\xc1\x27\x66\xfd\x00\x15\xc4\x6c\xd8\x52\xf5\xa5\x24\x69\xef\xc9\x8d\x32\x66\x45\x93\x5d\x7e\x68\xb9\x87\x3e\x6b\x2b\x19\x66\x19\xf3\x9c\x44\x9e\xaf\x63\xf5\x7e\xfa\x90\x9a\x68\x10\x5e\x4a\xae\x15\x55\x08\x4f\x55\x79\x2c\x29\x5a\xce\xcb\xc2\xaa\xe1\x0c\x98\x22\xb8\x14\x91\x26\x0c\xcd\xb7\x1a\xab\x41\x1b\xf6\xac\xc5\x92\x42\x2b\x1c\x92\x0f\x5a\x4c\xf4\x4b\x85\x27\xa8\xf0\x0e\xf2\xc3\xb9\x5b\x8a\x12\x74\x8c\xae\x91\x85\xda\x68\xbb\x35\x55\x34\xd7\xfa\x77\xbd\xef\x24\xc1\x68\x27\xb1\xe2\xdc\xf7\x8f\xe5\x27\x06\x60\x2b\x29\x33\x4d\xf2\x16\x56\xcb\xbf\xd9\x6f\x3a\x35\x29\x2e\x55\x9c\x30\x27\xc3\x63\x13\x08\x3f\x1e\x3e\xc7\xc5\x49\xa5\x25\x1b\x74\x9c\xda\x50\x60\x62\x84\x25\x3a\xe9\xfc\x5d\x85\x66\x73\xa9\x1b\x3c\x4e\x07\x08\x4e\xbb\xe3\x31\x7f\xad\xa0\x41\x72\x32\xff\xec\x31\x89\x12\x51\x11\xe4\xa3\x3e\x1f\x8f\x6e\x1e\xbb\x23\x26\x0b\x52\xd7\xfe\x7e\x63\x43\x6e\x8f\x9f\xbd\x7e\x63\x2a\x90\x9a\xb2\xfb\x06\xdb\x89\xb6\xdd\xf7\x4c\x0f\x5c\x85\x2a\x26\x42\xa6\x9d\xd7\x63\xba\xd7\x63\x9f\x5c\x45\x71\xe6\x7f\x6a\xf9\xc7\x83\x8f\x7f\xaf\xd8\x42\xb9\x8a\xd2\xc4\xeb\x5d\xe4\xaa\xdc\xed\x29\xe8\xad\xed\x0e\x67\x1d\x90\x36\x78\x1d\xd0\x07\x70\x15\x87\x29\x09\x38\x1d\x4a\x28\x7c\xc7\x70\x59\x3c\x95\x4d\x6e\x72\x05\xcd\x55\x00\xa8\x62\x19\x60\xdf\x38\x6d\xed\xa2\x17\x78\xe9\x2e\x2a\x39\x7d\xe9\x23\x1e\xcb\xee\x6f\x2a\x14\xae\xd6\x46\x92\x31\x93\x67\x64\xa9\xa1\x84\x48\x47\x7d\xed\xfe\x9e\x06\x9a\x3e\xf3\x6b\x05\x0a\x2d\x1e\xa1\xef\xf2\x51\x69\x24\x29\xe4\xdb\xf4\x9b\xdb\x8f\xb2\x7a\xab\xf7\xe5\xa9\xa3\x5f\xe3\x2a\x95\x76\xc3\x26\x5f\xbf\x6e\xca\x23\x75\xc9\x11\xcf\xdc\x80\x80\x76\x3c\xbf\x54\xea\x68\x2c\x1b\x78\x73\x4f\x79\xd3\xcf\x0b\x95\x45\x21\x15\xa7\x8e\xf0\x67\x59\xad\x7e\x52\xd8\x3a\x3e\x3f\x63\x61\x3c\x14\x3d\xad\xf0\x98\x9f\x8f\x83\xfd\x5b\x65\xcc\xc2\xa4\x3d\x2a\xd5\xa2\x4b\xf3\xd7\x8f\x94\x81\xe6\x17\xd7\x7c\xcf\xa3\xe2\x2a\x80\xac\x6b\x8b\x40\x1b\x38\xf5\x14\x35\xed\x00\xa0\x18\x7d\x47\x7d\x81\xed\xec\x28\xae\xf1\x83\x4a\x60\x42\xd9\xef\x76\xc7\x2d\xf3\xeb\xa7\x04\x96\x90\xfb\x40\x75\xa8\x9b\x61\xc0\x30\x5a\x67\x4a\x66\x31\xa5\x58\x1e\x21\x2f\x0a\x6c\x56\xdb\xe5\xe6\x5c\xfd\xf4\xaa\x4c\x5c\xa9\x30\x36\x4e\xb2\x0b\xab\x66\x58\x21\x57\x1a\x02\xa7\x5d\x45\x1e\xe9\x88\xc7\x69\xfe\xd3\x69\xad\x8d\x18\xb4\xfb\xdd\xe6\xc6\xe4\xea\x7c\x68\x2e\x56\x74\x6f\xe8\x44\x2a\x4c\x64\xc2\x47\x7a\x47\xbd\x13\x36\x6b\x79\x14\x82\xa5\x03\x7d\xa5\x0a\xcd\xf3\xb9\x51\xa5\x0f\xa3\x7d\x32\x45\x99\x4c\x91\x3e\xa1\xe7\x61\x1a\xf6\xe5\x29\x23\x58\x36\x94\x14\xf2\x82\x0c\xa3\x57\xa6\x83\x58\x04\xe3\x08\xf5\x7e\xf9\x6c\x05\xfb\x3b\x7a\x4e\xae\xc3\x00\xa8\x7d\xe2\xe6\x00\xea\xed\xb7\x7e\x86\xea\x30\xb5\xdd\x87\xa7\xb2\xd9\xb4\x51\xdf\xae\x3f\xc0\x65\x36\x40\x5b\xbd\x60\x75\x3c\x37\xb4\xd4\x7f\x77\x1e\x36\xff\xdf\xe4\xff\xfc\x68\x40\xdb\x5b\x46\x59\x87\xd9\x10\xea\x5a\x87\x95\xeb\x28\x8c\xe9\xb6\xee\x87\x0a\x47\x5c\x47\xcc\x32\x37\x3e\x94\xaf\x1b\x2c\xb4\x6d\x2d\xfc\xa4\x4a\xa6\x23\x90\x14\x72\x75\x8d\x82\xf9\x3b\x1e\xbc\xf1\xd2\x71\xa6\xd5\xb0\x86\x96\x17\xaf\xa3\xde\x63\x1d\xf3\x88\xaa\xcf\xb2\xa2\x34\xc6\xe6\x54\xe5\xcd\x14\xc0\xa9\x63\x19\x51\xb7\x80\x04\x79\xb9\x29\xab\x62\x55\x68\xbb\x6b\xce\x3a\x4d\x3a\x96\x29\x65\xd4\xac\x8d\xc4\x91\x46\x24\xd7\xb1\x42\x6e\x1b\xf5\xf3\x4a\x8f\x4c\xb5\x1b\x90\x04\x86\xf8\x45\xf1\x3d\xaf\x9b\xba\xdd\xd3\x6f\x2e\x94\x72\x1c\x1b\x44\x9d\x60\x40\xb0\x83\xff\x6c\x36\x9f\xa4\x9e\x27\x95\x01\x9d\xc6\x11\x65\x9b\xbe\x40\xa1\xf7\xf9\x6f\xbe\xd1\x48\xa7\x20\x08\xaa\xb3\xdc\x2e\xf7\x79\x01\x83\x54\x8b\xce\x58\x68\x61\xa9\xa3\xd6\x01\x9d\xf1\xc8\x06\xa7\xd8\x38\xf9\x7d\xaf\xb9\x3a\xcc\x1a\xea\x4c\x1a\x1e\xf4\xd4\x40\xc3\x27\xe5\x01\x50\xbf\xa0\x2e\x37\x24\xbe\x73\x95\x09\x9d\xc8\xca\x72\xcd\x53\x16\x39\x1d\x63\x62\x2a\x18\xbf\x5a\x6e\x32\x8f\xd9\x71\x9a\x81\x78\xed\x31\x8f\x5f\x87\x70\xf9\xa5\xe5\xf3\xc3\xf3\x7a\xb7\xf6\x34\x7e\x5c\x0b\xcc\x08\x64\x69\xa9\xbe\xed\x57\xb8\xbf\x1d\x59\x06\x2d\x8c\x05\x95\x7f\xbf\x5f\x6d\x9f\x16\x8f\xc4\xfe\xb0\x5d\x6d\xb6\xdd\x35\x8c\x55\xf2\xf2\x4c\x91\xf3\xb7\x00\xb1\xa2\x0a\xfb\x9f\x1a\x15\x69\x19\xfd\x4d\xb1\x42\x83\x90\x52\x0d\x72\x4e\x2f\x4e\x19\x71\x32\x6b\x65\x1c\xd1\x13\xf8\x1e\x83\xf2\xe8\xb0\xf4\x57\xae\x9b\x3b\x41\x05\x56\x82\x68\x9b\xbf\x62\x35\x11\x54\xe5\x5a\x45\x40\xdb\xdd\x7a\xb5\x59\x2d\xd6\xcb\xaf\xbb\xc5\xd3\xed\xee\x76\xf5\x7d\xf5\xf0\xfc\xf2\xb8\x7a\xda\xee\x7e\x2c\x1e\x1e\x56\xdd\xb3\xeb\x00\xa5\xf3\x5d\xe9\x91\x66\xbb\x21\xe6\x4b\x25\x9f\x17\xf1\xb5\x4e\x4d\xe4\xaa\x10\xa3\x3e\x9d\xc1\x96\xa0\x4d\x10\x53\x12\x5a\x9e\xab\xe2\x8e\x64\x0f\xfd\x7d\x19\x8e\xd4\x73\x4c\x85\xf8\x2f\xd8\x78\xda\x34\x7f\x58\x06\xf4\xd2\x1e\x9e\xbc\xa2\x0a\xc7\x20\xb6\x32\x07\xed\x2b\xeb\x28\x27\x2e\x8f\xa5\xde\xe2\x7b\xb3\x28\xf4\xb2\x69\x28\x4f\xfa\xe9\xc3\xf8\x6b\x81\xa0\x08\xec\x3f\x30\xb2\x7b\x18\xaa\x30\x6b\xa7\xca\x7a\x7b\xef\xff\x14\x09\x24\x33\x62\x91\xba\xa4\x95\x5d\x9a\xee\xa0\xd2\x04\xca\xf9\x45\x9e\xd2\xe8\x3b\x62\xcc\x6d\xa6\xf9\x66\xd1\x3a\x13\xf5\x70\x67\xc1\x18\x45\xe8\xfa\x09\xcf\x78\xf8\x89\x4f\xe5\x51\x56\xb8\x38\x9d\x26\xd7\x48\xd2\x28\x63\xc3\x86\x90\xed\x1e\x57\x85\xbe\xa6\x9d\xe1\xc8\x58\x4c\x3c\xc0\x47\x82\x34\xe4\xc5\xeb\x38\x8c\x42\x26\x54\xec\x3a\x46\x76\x58\x34\xd5\xe7\x22\x2b\x1c\x99\x66\x44\x67\xf5\x72\x2e\xde\x6c\x72\xf9\xef\xa0\x7b\xee\xc4\x34\xb4\xe9\xfd\x41\xd4\xd1\xc7\x56\xd7\xfd\xaf\x98\xa6\x8c\x50\xdd\xcb\xb2\x3c\x6c\xcb\x73\x35\xfa\x20\xa9\x50\xd4\xee\xbf\x87\x7a\x9f\x1f\xcb\xa6\x1c\x3b\x5d\x57\x9c\x95\x73\x81\xdc\xe4\xf7\xb2\x50\x52\x3a\xe6\xb9\x7a\x85\x62\xdc\x90\x86\x19\x4b\x89\xb7\xe8\x09\x7f\xfd\xcf\x1c\x05\x29\xc7\x2c\x03\xcf\x0c\xb1\xc1\x83\x79\xa9\xb0\x29\xab\x1c\xae\x9b\x59\xc6\x2f\x85\x33\x0c\xdc\x86\xea\x9c\x54\xfb\x4a\x67\x1d\x23\xe4\xa9\xa5\xa9\x75\x22\x95\xb6\xd9\x60\x32\x35\x78\x26\x4c\xec\xf8\x2d\xb7\x7b\x4f\x6d\xc5\x91\x8b\x28\x72\x02\xd6\xf7\xc7\x53\x59\x35\x5b\xf8\xc0\x75\x46\x11\x19\x47\x35\xed\xf8\x92\xef\xca\xea\x65\xd5\x93\x34\x4d\xbf\xf3\xe4\x6c\xc8\x82\x4e\x4d\xe0\x8a\x67\xaa\x1e\xe2\x54\x3e\xba\x82\x8c\xac\xd5\xf7\xec\x9a\x7e\xfd\x23\xf0\xc0\xb3\x07\x6d\xf7\x55\x59\x60\x17\x76\xcf\xcc\x7c\xc0\xc0\xda\xf7\x5f\x50\x59\xed\xca\xba\xbb\x8e\x51\xb1\xcb\xb4\x7c\xcf\xab\x73\x4d\x79\xe9\xab\x0b\x48\x8d\x49\xec\x3d\xad\x5c\xb9\x78\xcc\x5f\x43\xa5\xb1\x54\x9d\x74\x5a\xeb\xb5\x3c\xe6\x87\xf6\x0d\x15\x38\xd7\xa6\x8c\x0a\x6c\xf6\x79\xd3\xbc\xb6\x01\x24\xca\x36\x8c\x5b\xf5\x60\x2c\xd4\x59\x4a\x05\xca\x53\xfb\x2c\xab\xed\xd7\x8e\x36\x8f\xa3\x06\xab\x96\xd4\x2e\x52\x5b\x0a\x9d\x38\x41\xa8\xc1\x76\x73\xbd\x3a\xa8\x84\x25\x25\x9d\x8c\x91\x8a\x82\x81\xe3\x5b\x8f\xcc\xbf\x0a\x56\xc6\xa7\x18\x1e\xf9\xca\xc4\x63\x7e\xb8\x1b\x10\x73\xfa\x01\x10\xd0\xa6\x4e\xa7\x6f\x4b\x6a\x76\x67\x43\xf2\x0e\x34\x18\x2b\xdd\xe5\x9c\x1f\xf2\xe2\xcd\xe1\x86\x47\x17\x32\x81\x92\xaa\xa7\xfc\xda\xe6\xc7\x41\x2a\xf4\xff\x5f\x67\xa3\x09\x03\x46\x91\x39\xbe\xbe\x92\x92\xcc\xe4\x9d\x99\x30\x64\xc4\x8e\xe2\x2a\xc1\xe3\xfe\x59\x13\x26\x96\x4a\x08\xb4\x1e\x72\x10\x7e\xd2\x94\x36\xf9\xf9\x28\x31\xb1\x9e\xa8\xd1\x7c\xe9\xfd\x2b\x13\xc7\x28\x2c\x09\xf2\x16\xde\xa6\xeb\xd8\xc4\xcc\x62\x93\x5d\xe7\x16\x0b\xe3\x79\x07\xc5\xc4\x10\x92\xdd\xa2\xbc\xcb\x08\x52\x3d\x41\x71\x9b\x58\x03\xd1\x5b\xf9\xcd\x75\x4a\xd0\xe4\x86\x25\xd2\x82\x68\x2c\x47\x36\x16\xd7\x49\x04\x93\x98\x90\x48\x38\xbf\xc2\xa1\x8c\xfd\x2c\x35\x2c\xe6\x91\x63\x8d\x77\xbc\x9c\x43\xff\xcf\xa4\x2c\xb6\xc9\x1c\x5b\xca\x68\x23\x81\x6f\x85\xc6\xea\x01\xcd\x04\x2b\x6b\x52\x61\x45\xcb\xad\x8a\x66\x59\x6d\x5e\xfc\x6f\x64\x26\xa5\xae\xe6\x9b\xa7\x1b\xff\x27\x1e\xa6\xd2\xa6\xcc\x6c\x6b\x9e\x13\x3a\x1c\xfb\xe3\x86\xa3\xf5\xa0\xdb\x18\xeb\x72\x2a\xbb\xcf\x2c\x12\x2b\x36\xbd\x84\xea\x05\xaa\xb7\x81\x67\x6d\x20\xcd\xcc\xa8\xed\xb2\x8d\x51\x2c\xf9\xd6\x74\xe2\x8d\xee\x1e\x78\x48\xa6\x76\xbb\x5e\x3c\x6d\xee\x56\xeb\xcd\xee\x65\xb5\xde\xd1\x7f\x2d\x96\xbd\xc8\x0d\x37\x52\x18\xca\x31\xec\x3c\xd8\x61\xf2\x1a\x54\x10\xb2\xd0\x4b\x3f\xfc\xf7\x9c\x57\x33\x14\x7f\xd7\x3b\xa7\xd1\x29\xa0\x1a\xe4\x10\x27\x0d\x62\xa3\xc2\x8a\xd1\xa9\xf1\xa4\x15\x74\x0b\x03\x64\xf4\xe4\xaa\x82\x91\xdf\xd2\xc6\x9c\x23\xeb\x64\xb4\xe0\x42\xfa\x50\x43\xbd\xa1\xde\x34\xd5\x59\x35\x2f\xe7\x43\x8d\xed\x1f\x46\x7d\x3f\xb3\x26\xdf\x20\x4b\xa8\xbc\xf3\xa5\xbd\x8b\xfc\x80\xd5\x95\xf6\xd4\x60\x2c\xe7\xd4\x0a\x7e\x73\xbf\xf6\x75\x46\x83\x32\x21\x2a\x0c\x84\xea\x70\x59\x96\xc7\xe3\xb9\xc8\x9b\x09\xd0\xd9\x98\x2c\xa5\x4f\xbd\x7e\x5f\x2d\x1e\x86\x62\x83\xab\xf7\x06\x7b\xdc\xbd\x08\x82\x24\xcb\x5c\x5e\x9d\x5a\x47\x88\x38\x7b\xda\x7d\x2a\x82\x00\x02\xb2\xb9\xa0\xb5\xad\x3b\xff\x1d\xee\xd5\x9d\x17\x86\x49\x10\x90\xdd\x69\x77\xa6\xdb\xc5\xf3\xa7\x4e\x82\x08\x42\x86\x7a\x8c\xcd\xec\x49\x8f\xfd\x90\x54\x65\xa2\x37\xff\x1d\x88\x54\x04\x71\x14\xc5\x5e\x21\x8e\xbc\xd1\xf3\x15\x84\x88\x77\x43\x53\xf2\x3e\xef\xf2\x53\x3d\xee\xe0\x89\x82\x0f\x6e\x2d\x46\x43\x2c\xcb\x55\x59\x36\xbb\x30\xf8\xd7\xf8\x41\x63\x13\xd8\x22\x7d\xfe\x13\x57\xcd\xfe\x06\x8a\xb7\x75\x79\x38\x8c\x3e\x8b\x08\x12\x91\xd0\xa8\x76\xe9\xa1\xc3\x23\xf8\x63\x2c\xe2\x60\xd1\xb4\x87\xc3\x66\x24\xd6\x33\x4e\x37\x4c\xde\x30\xd5\x54\x07\x58\x9f\x6d\x39\xf6\x95\xa6\xc3\x65\x98\x85\x3d\x45\xc6\x82\xe8\x89\x51\xaf\x07\x5d\x5f\x83\xc1\x3a\xa6\xb7\x64\x85\x02\x87\x46\x46\x04\x0c\x43\x4a\x68\x40\xfd\x66\x3d\x92\xf1\xdb\xca\xe2\x50\xda\x44\xb0\x2a\x0b\x0d\xd5\x85\x26\xe1\xb9\xfb\x56\x99\x08\xcd\x50\x19\x65\x64\x98\x45\xc0\x13\x04\x0f\x2d\xf6\x41\x22\xea\x09\xac\xa5\x0b\xb3\x44\xc0\x05\xb7\xf4\x10\x65\x85\xf9\x6b\xf1\x29\x0f\xa9\x08\x44\xa4\x88\x8d\xfa\x8f\xa6\xc2\x63\x6f\x06\x45\x20\xd0\x4a\xd6\xc9\xf3\xc7\x4d\xa2\x22\x80\x50\x11\x00\xec\xa1\x7c\xbd\xc9\xf5\x1d\xe4\x87\xbf\xe1\x23\x15\x01\x24\x4c\x8c\x2a\x38\x56\xc0\x64\xb8\xc4\x24\x64\xb1\x47\xef\xe6\x45\xf3\xaf\xd1\xf9\x3a\x89\x43\xab\xb2\xf4\x13\xeb\xfb\x6e\xf5\x6a\x06\x94\x6e\x3f\x5a\x4b\x66\xb3\xbf\xdd\xc6\x88\x93\xcf\xa9\xc1\x1a\x4b\x1f\xaf\xde\x62\xfb\xed\xca\xf7\xcb\xe4\xdb\x69\x34\xf4\x7c\xf7\x85\x2e\x0b\xac\x73\x58\x9f\x4f\x39\xec\xfd\x8f\x62\x08\x18\x77\x25\xb3\xee\xaf\x06\x98\x18\x00\x58\x17\x43\xfd\xf6\xf1\xf5\xd1\xa0\x55\x9a\xaf\x57\xef\xa8\xfc\x05\x8c\x40\xe5\xf6\xe2\xcd\x7e\xa2\xc1\x29\x02\xa3\x14\xeb\x10\x56\xdf\xe1\xe0\x24\x69\x44\x18\x84\xa9\xcb\x41\xd8\x1c\x61\x5f\x92\x18\xff\x6a\x18\x88\x80\x1a\x1c\x57\x0f\xf7\x7f\xb8\x65\xb9\xc1\xa6\xbb\x0c\x84\x1e\x8b\xb7\xa2\xd0\x70\x34\xdb\xc3\x40\x61\x4c\xad\x13\xc7\xf6\xd3\xcc\x25\xb7\x3e\xdc\xa4\x44\x18\x06\x1c\x9c\x2b\x7f\xaf\x4a\xcb\xfe\x32\x19\x11\x6a\xca\x12\x80\xd6\x71\x34\x44\x8c\x74\x37\x10\x46\x98\x39\xdd\xe8\x65\xf9\xcb\xdf\x75\x98\x49\xc0\x41\x1f\xdc\xed\xf4\xba\x3c\x8a\xc2\xe1\x17\x1f\x24\x67\x26\x4d\x9c\xed\x60\x6b\xe0\x2c\x14\x2b\xe9\x7e\xc3\x48\xe1\x76\x88\x61\xea\x77\x76\x77\x13\x61\xc4\x62\xab\xca\x52\x68\x7c\x47\x7d\x5b\xaa\x7a\x72\x4f\x71\xc6\xac\x96\x77\x7e\x38\x94\xbf\x06\xab\x2f\x8c\x95\x45\xb9\x9d\x09\x18\x4a\x5b\x34\x31\xfc\xcd\xff\x52\x92\x48\x5f\x11\x6e\xb7\xa4\xd9\x4a\xb0\x08\x13\x16\x1a\x87\x5e\xfd\x5a\xd6\xb6\xc0\x58\x9a\x7c\x16\xf2\x4f\x0c\xa5\xb4\xcd\xad\x1f\x96\xfe\xa6\x58\x98\x11\x73\x33\x11\x04\xe5\x68\xf3\x67\xf3\x33\x8c\x31\x9b\xc7\x76\x75\x94\xbb\x89\xda\x75\x3b\x80\x93\x63\xd6\x7e\x86\x7a\x60\xc8\x66\x49\xa6\xdd\x39\x69\x88\x2c\x73\x20\xeb\x1a\xaf\x89\xf9\x44\x98\x66\x52\xe8\xc1\x47\xfe\x90\x6f\xd3\xe6\xcb\xff\xef\x5a\x00\xac\x9b\x02\x69\x66\x94\xea\x69\xaa\xdd\x16\xdc\x27\xf1\x45\x98\x0a\xed\x59\x52\x6d\x91\xd1\xc6\xf2\x73\xfa\x8b\x22\x4c\x55\x44\x41\xfc\x13\x9e\xab\xf2\x47\xee\xcb\xb9\x22\xcc\x84\xb6\xa9\x7a\xab\x6d\x0a\x87\x7f\x4c\x5f\x3a\x6b\x5e\x43\x9e\x29\x74\xf7\xbd\x02\x82\x96\x0c\x93\xeb\x22\xe4\x52\x65\x3e\xc0\xc1\xea\x58\xcf\xe0\x6e\x44\xc8\x4d\x10\x58\x00\xcb\xe1\x60\xb5\xfd\x3f\xf2\x71\xe6\x27\x24\x37\x31\x95\x67\xf6\x47\x35\xde\xf6\x43\x11\xbb\xd6\x88\xf6\x5d\xed\x6a\x38\xe0\x0e\x0b\xbd\x1b\xa0\x49\x44\x28\x12\x1d\x74\x40\x45\xf2\x20\x86\x1b\x62\x28\x32\xc3\x5c\x73\xda\xaa\x49\xfa\xdc\xb5\x08\x05\xe7\xd1\x30\x3b\x77\x5b\xaa\xf3\x11\x0b\xaa\xa5\xcd\x25\x70\xda\x33\x04\x05\xb2\x5b\xa8\x40\x0d\xd6\x9f\x10\x19\xef\xd5\xc3\x49\x71\xe3\x13\xee\x18\x11\x42\xa0\x89\xbc\xc1\x94\x16\x8a\x68\xb7\xe7\xce\x32\x43\x8a\x16\xd6\x50\xde\xf4\xfd\xaf\x68\x49\x83\xfc\x10\x2e\x88\x7e\xb6\xbd\x57\x3d\xda\xd7\x27\xef\x56\xb6\x8e\x0b\x25\xe8\x8f\x90\x17\x5f\x9b\xe3\x61\x62\xa0\x65\x62\x71\x87\xe4\xd3\xd7\xd8\xed\x4b\xa1\x44\x24\xb0\xff\xeb\x99\x84\xb9\xad\x76\xac\xcd\xc4\x76\x5e\x70\xa8\x58\x48\x54\x1c\x70\x3a\xb5\xa7\xce\x3d\xac\x66\x51\x9c\x7a\xf0\xa4\xf1\xaa\x85\xd7\x31\x91\x08\x35\x97\xda\x12\x3f\x15\x75\x03\x45\x73\x57\x4c\x96\x05\x82\xa6\x4b\x51\xb1\xeb\x23\x91\xa7\xc9\x0b\x30\x71\x0a\xe9\x00\xae\x8f\xf7\xcb\xe7\x47\xb0\xba\x0f\xae\xfd\x6e\x74\x42\x14\xc4\x19\xc5\x30\x4d\x97\x18\x13\x51\xc0\x25\x55\x7c\xce\x35\x56\x6b\xda\xbd\x5b\xaf\xb1\x3c\xf7\x6a\x10\x84\x12\xf3\xc3\xc3\x24\x4b\x99\x17\xe7\xa7\x98\x6d\x76\xe2\x47\x91\xe4\x8e\x0a\xbe\xbd\xa4\x2d\x78\x4c\xac\x7e\x14\x87\x21\x11\x53\x9b\x31\x41\xde\xb5\x2b\x17\xc5\x49\x68\xb9\x95\xf7\xd0\xd4\x8f\x97\xdf\xce\xd5\x65\xcc\x36\x3a\xb6\xba\x51\xac\x6c\xe8\x7a\x84\x77\xa2\xa4\x19\xf8\xd4\x51\x12\x69\x22\x73\x20\x65\xa8\xfb\x42\x9f\xdb\x4f\x3a\xf6\xbb\xa3\x84\x19\xca\x22\xb6\xf7\xbe\x28\xea\x5f\x58\x39\xf4\xc4\x68\x82\x45\x89\x50\x09\xf1\xb9\x9f\x4f\xfd\x1b\x4a\x8c\xd3\x22\xcc\xb1\x8a\xd6\x08\xaa\x9f\x53\x11\xcb\x22\x1f\x6d\x3e\x94\x50\xd8\xd0\x0a\xb5\x33\x4c\xe3\x8b\x33\x65\xd0\xd1\xf1\x2e\x97\x5f\x77\xa8\xf3\x66\x97\xf9\x0b\xa5\x29\x0b\x9d\x36\xc9\x0d\x16\x68\x72\x95\xc3\x84\xff\x53\x44\x29\x67\x3e\x70\xfa\x91\x17\xba\xfc\x65\xdd\x8c\x59\x07\x2c\x4a\x25\x63\x70\xc5\x26\x1e\xfa\x0d\x61\xbc\x47\xcc\x64\x95\xdb\xaf\xe5\xf7\x8c\x28\x55\x9c\x3a\x56\x1e\xf3\xa6\x2a\x0b\xcf\x87\xdb\xfe\xdd\x66\x1b\x6a\x6c\xbe\xc0\x71\xda\x34\x2b\xa2\x8c\xb9\x14\x5d\x5e\xf4\xc0\x44\x7f\x2c\x4d\x59\xec\xa5\xc2\xd4\x5b\xeb\x52\x0e\xe1\x2a\xc3\x85\x19\xb5\xb6\xdf\x39\x9e\x2f\xf2\x7c\xc8\x15\xb1\xca\xd3\x46\x9f\x7f\xc0\x12\x22\x22\x0e\xe8\x79\x37\x57\x85\x26\xbd\x8b\x68\x72\x7f\x5c\x6a\x32\x5f\x0f\xd0\xe4\x67\x12\x0c\xeb\xbf\x3b\x57\x99\x96\x3d\xab\xa6\xeb\x35\x1d\x87\x27\x7e\x28\xf2\xa0\x27\xcb\x7b\x2a\x89\x9a\xc8\x75\x6e\xa7\x4e\xd5\x2f\xf4\xf3\x40\x84\x18\x19\xdb\x6d\x8a\x56\x16\xad\x7b\x25\x22\x42\x9a\xa6\xaf\x50\x53\xcf\x91\x03\xd6\xae\xfb\x0e\x66\x11\x89\x34\x21\xf5\x4d\x47\x8f\xb4\x2c\x8f\xc7\xb2\xf8\x85\x57\xfd\x72\xce\x65\x1d\xbd\x46\x91\xa2\x27\x1f\x1b\xf6\x2a\x88\x48\x48\x4e\x09\xe4\x9d\x77\x00\xdd\xdf\x81\x19\x4a\x85\x90\xce\xd1\x68\x45\x81\xc8\x28\xa5\x85\x85\x2a\x35\x7e\xf3\x92\xcb\x7c\xf2\x0d\xc0\x84\x04\x4e\xf8\x02\x65\x31\x3a\x5f\x32\x4d\xf5\xa6\x3d\x1c\x9a\xbb\x3f\xba\xbf\x66\x41\x00\xbd\x30\xa0\x93\x68\xaf\x26\xaf\x5b\x66\x21\x41\x30\xf2\xda\x85\xb4\x79\xf1\xba\xaa\x15\x9c\x70\x5b\x7a\xc7\x7a\x30\x23\xba\x15\x28\x75\x16\x38\x1f\xbd\xbc\x62\xba\x11\x91\x0a\x4c\x60\x79\x81\x5c\x85\xf9\xce\xa1\x5c\xf5\xbf\x46\x97\x51\x2c\xa4\x2e\x63\x82\xd1\x6f\x7f\xff\xb2\x5b\x7e\x5d\xac\xef\xb7\xff\xf1\x0f\xa1\x13\x45\x25\xf5\xe5\xe2\x76\xf7\x7c\x2c\x72\x5d\x1e\x0e\xd0\x4d\x2b\xad\x02\xf0\x14\xf4\x17\x28\x9a\xdb\xaa\xcc\x9b\x95\x2a\x8b\xf2\x98\xff\xf7\x8c\xbb\x65\x79\x3c\x35\xb8\x9b\xce\x54\x4c\x0d\x1b\x32\xe9\xd4\xdd\x37\x42\x48\x89\xc3\xe3\xe1\xe1\xfb\xee\x67\x1c\xec\xc2\xa8\x3b\x82\x86\x81\x53\x8a\x24\x55\xb8\xd2\x51\xc1\x7e\xdc\xb4\xda\xce\x40\x0d\x56\xe2\x99\x48\xa4\xbb\xc8\xdc\xfa\x80\xb6\x15\xce\x0e\x8d\x83\x50\xd1\xce\xbe\x53\x70\x38\xac\x51\xe5\xa7\x1c\x7b\xb3\xf7\x11\xe5\xc5\x6c\xaa\xb9\xdf\x1b\xe2\x00\x22\x1b\x46\xd3\xba\xf3\xed\x77\xf3\x34\x22\x22\x0e\x23\xdb\x5f\x85\xb6\xbb\xfa\xb6\x5b\x28\x71\x98\x21\x01\xc8\xe5\xf9\x72\x7f\x3c\x1d\xb0\xf5\x97\xe0\x2a\xe7\xdd\x17\xfd\xe7\x31\xf7\xfe\x62\x5c\x46\x6a\xc0\xfe\xeb\x3c\xb7\x1b\x47\x0f\x3e\xbe\xa7\x88\x77\x42\x30\x76\xa3\x1c\x66\xff\xfc\x18\x15\x44\xca\xb7\x2e\xd6\x03\x80\xa5\x88\xe3\xc0\xb6\x89\xee\xa1\xde\x0f\x41\x0e\x1f\xb1\x50\xb9\x7c\x57\xcc\x58\x46\x2e\x87\x85\xff\xb9\x3b\x9c\x90\x88\x89\x98\x65\x81\xef\x8c\xbe\x3d\xe3\x95\xba\xb6\x88\x99\x91\x14\xc9\x82\xee\xe2\xad\xf2\x83\x4c\x53\x9c\x46\x8c\x62\xa9\x9b\xf3\xe1\x50\xdf\x41\x75\xec\xcc\x67\x9c\x46\x9c\xf0\xac\xbf\xbd\x0c\xc2\xbf\x38\x8d\x39\x35\xe5\x52\xce\xfc\xf9\x44\xe6\x6d\x20\x2a\x3a\x98\x06\x69\x1a\xd1\x7d\x4a\xd7\xe2\xbd\x87\x1a\x59\x77\x19\x97\x92\x76\x45\x98\xe1\x03\xdb\x06\xc7\xc3\x3c\xf5\x93\x88\x33\x8d\x94\xee\xda\x6c\x17\xdb\x6f\x9b\xdd\xed\x6a\xf1\xb0\x5b\xaf\x1e\x56\x0b\xcf\xcd\x29\xe2\x0c\x19\x25\x69\x5a\x47\x11\x0e\x9b\x37\xaf\x4c\xd5\x1e\xe1\x29\x0c\xa2\xb0\xfa\x7f\xce\x50\x34\x03\xcd\x69\xbf\x83\x26\x5e\xf1\x53\xc4\x3c\x4b\x78\xaf\x3d\x6b\x91\x3c\xeb\xf3\x01\x3f\x54\x87\x98\x77\x0e\x63\xce\x35\x25\x6c\x3c\xaf\x83\xd7\xd5\x7d\xa9\x90\xb4\x07\xf4\x57\xa8\xf7\x43\x26\xc8\x7f\x76\xd9\xd6\x85\xcf\x7c\xa6\xd9\x71\x26\x5d\x71\xa2\x0d\x52\x58\xb1\x00\xee\xc8\xf1\x1e\xe0\xd7\x65\x6a\x44\x63\xa1\x2d\xc1\x86\xed\x46\x80\xaa\x59\xe3\x4f\x2c\xce\x38\x43\xf6\x21\x62\x81\xe8\x08\xc8\xad\xa1\xa7\xd2\x27\x81\x2a\xfd\x1b\x07\x26\x89\x5f\xee\xf7\x6f\xf7\x9b\xe1\xfe\x11\x43\x1a\x89\x6c\xb8\xc6\x1e\xc0\x98\xc9\xe5\x01\x2c\x45\x42\x8d\xcd\x23\x36\xa0\x87\x89\x91\xe1\xbe\x18\x83\x09\x84\xe9\xe0\x7e\xab\xff\x46\x41\x97\x27\x76\xff\x76\x03\x13\x43\x0c\x6a\xe6\x3f\xe5\xf9\xca\x9b\x9f\x09\x29\x62\x30\x8c\xa6\x4c\xbb\xdb\xe6\x65\xb1\xbd\x9c\xa6\xeb\x4d\x26\x2c\xee\x74\xd3\x1f\xb1\x7a\xa5\xba\xcc\x34\x83\x33\xd1\x9f\x10\xb1\xcc\x84\xb1\x35\x25\xcb\xc8\x3d\xfe\x0c\x12\x43\x6a\x6b\xd8\x39\x1d\x2e\x1b\x79\xcf\x75\x1d\x88\x58\x09\x11\xab\x81\xc5\xc7\xbc\xab\x70\x77\x9e\x6e\xac\x14\xb0\xae\x0c\xbe\x7a\x3f\x1d\xca\xea\x03\xbf\x2b\xd6\x91\x95\x3c\xfb\x7d\xf4\xc1\x10\x62\xd2\x40\xfa\xbe\x5a\xdf\xde\x2f\xb7\xdd\x9f\x8d\x36\x6e\xbe\x38\x58\xe1\x0b\xd4\xf5\xa9\xac\x9a\x87\xf2\x35\x57\xff\x1a\xbd\x4c\x13\x03\x51\xac\x2c\x0e\x87\x47\xa8\xde\xf2\xe2\xb5\x7e\xb1\x3a\x3d\x1f\x27\x67\xc7\x37\x97\x04\xc6\x96\x7d\xc8\x29\x54\xd5\x85\x68\x6b\x6c\x77\x6b\xcf\xa4\xe0\xc6\x86\x2c\x24\x98\xf4\x6d\x07\x69\x11\x49\x28\x25\x0f\x26\x55\xd0\x9b\x21\x2c\xe6\x0a\x59\x2f\x92\x50\x73\xea\x70\x5f\x37\x72\x43\x25\x18\xd2\x89\xfb\x80\x2b\x60\x3e\xf1\x90\x84\xc6\x10\xdf\x51\x7e\x3c\x1d\x76\x97\x1c\x0f\x3a\xeb\xf7\xba\x24\x8a\x81\x72\x1f\x37\xe7\x0b\x49\x9e\x8c\xbf\x70\x12\x25\x92\x6c\x87\x6b\x59\x5e\x54\xcd\x14\x8f\x25\x92\x38\xb6\xd4\x2b\xb9\xc7\x45\x0c\x45\x20\x45\x92\x24\x91\x77\x1d\x9d\xd3\x35\xd0\xde\xec\x6f\x33\x91\x99\xf6\x19\x62\x1f\xe4\x84\xe3\xb7\xca\x12\x4e\x51\x4c\x81\xbf\x88\x59\xaf\x26\x25\x9e\x6e\xa6\x25\x2c\x13\x5e\x41\xc3\x49\x07\x3a\x89\xa0\x9b\x97\x67\xf3\x59\x5b\xaa\x48\x88\x54\x71\x9c\xfe\xed\xae\x2a\x2d\x36\x93\xd2\x33\xd1\x17\x3f\xff\x92\x34\xb2\xde\x06\xf9\x39\xad\x73\x3f\x9c\xb4\x49\x8a\x19\xa1\xcb\xb7\x39\x56\xbb\x35\xe4\xc5\x11\xde\xda\xff\x37\xb0\x57\x7e\x68\x16\xc7\xbe\x29\xd2\x43\x4b\xee\xe7\xbb\x22\x44\x92\x25\x36\x89\x68\xca\x0a\x15\xd4\x8d\x53\x42\x9c\xbc\xcb\x8c\x71\xe2\x42\xf5\xd9\x03\xaa\x3b\x7e\x86\x6f\x10\x49\xc6\x13\x8a\x55\x8f\xa5\xce\x8d\xaf\x1c\x0f\x04\x48\x26\xed\xef\x83\x13\x95\x15\xb5\xf5\xad\xba\xa7\x21\x75\x8b\x48\x32\x9d\x86\x7d\x66\x62\x51\xbf\x5d\x85\x5e\xa3\x4f\xcc\x59\x46\x31\x0a\x75\x26\xd2\xb8\xda\x12\x23\x5c\xf1\x50\xf8\x13\x4c\x16\x7b\x09\x75\xfb\xa6\x46\x0a\x58\x6e\x94\x00\x4e\x5a\x14\x45\xd9\xe4\xe6\xe2\x45\x3e\xc7\x57\x12\xc8\x88\x6f\xde\x58\xf0\xb4\xe5\x1f\xb8\xab\x2c\xda\xa1\xfd\x30\x55\xf7\x50\x00\x69\xea\x71\xf8\xe5\xb9\xaa\x2d\x99\xc8\xe8\x41\xc0\x28\x4b\x6f\xfa\x5a\x0d\x6c\xe2\x28\xef\x98\xc8\x90\x5b\xcd\x61\x6f\x12\xb6\xe5\x08\x14\x34\xfb\x86\xa4\x44\x8a\x21\x96\x65\x55\x1e\xf0\x7d\x90\xa1\x4b\x34\x72\xcf\x51\x7b\x8b\x70\x18\xf9\x86\x09\x6a\xe8\x89\x00\xd5\x5b\x9f\x03\x4b\x8c\x91\x89\x4b\x82\x7b\x76\x1c\xdf\x04\xe9\x1c\x44\x16\x28\xe9\x15\x33\x96\x50\xe7\x45\xd9\x29\xa7\x85\xb3\x9b\x17\x0b\x14\x5a\x0a\x6c\x42\x38\x54\x65\x1b\x02\x57\x9b\xf3\xa9\x35\xcf\x1f\xb4\xfc\x08\x16\xe8\x58\x58\xc6\xff\x36\x2c\x18\x71\x00\x09\x16\xc6\x21\x95\xa2\x75\x79\x77\xd5\x42\x28\x58\x98\x30\xe1\x4a\x24\x84\xd4\x22\xf6\x37\x7b\x71\x9c\xb2\xf8\x09\x16\x85\x01\x51\xc1\x94\x27\xaa\x87\x9d\xce\xcd\x08\xa1\x21\x58\xac\xb8\xcf\x63\x6f\xb0\xd0\xcb\x72\x5a\xfc\x64\x89\xe2\xca\xa2\x09\x5b\xa7\xd1\x97\x57\x87\x09\x32\x96\x20\x32\xf2\x06\x55\x73\x6e\xbd\x2d\xd2\x4c\x18\x10\x03\x08\xc6\x62\xcb\x03\x78\x2c\x35\xbe\x9f\x76\x05\xe4\xde\x85\x9a\x73\xa0\x58\x2a\x39\xe5\x3d\xea\xf2\xa0\xaf\x1e\xce\x8d\xc9\x50\x52\x74\xfc\x82\x0d\x0e\x91\x82\xed\x11\x4c\x5c\x65\xfc\xa5\x2a\xff\x44\xd5\x7c\xab\xc7\x4c\x64\x82\xf1\x90\x13\x2d\x0a\xe5\x49\x37\xf9\xab\xcd\x59\xb4\x4f\xd7\xba\xfb\xed\xe4\xb4\x3d\xfe\x6b\xe7\x1b\xf8\x1e\xae\x89\x71\xbd\x86\x16\x4e\xbe\x34\x4f\x43\x42\xd6\x18\xca\xb4\xf6\x7d\xa2\xed\x91\x28\xec\x26\x63\xeb\xf8\xcd\xa5\x4d\x18\xe7\x11\xb1\x20\x1c\xf3\xa2\x59\x78\xfe\x55\xc1\xb8\xc8\x2c\x50\x1b\x2e\x36\x7d\xde\x3d\x18\x84\x29\xd9\x77\x70\x5c\xe0\xff\x0f\x56\xe5\x07\x81\x21\x83\x38\x20\xc7\x62\x4d\x2c\xf0\xad\xef\x3d\xf1\x3e\x19\x24\x46\x45\x4e\xc1\xeb\xd8\xce\x1e\x57\x0a\x79\x80\xba\x59\xfc\xc4\x0a\x5e\x67\xf5\xaa\x05\x83\x54\xa0\x45\xf5\xea\x1d\x7c\xb6\x21\x31\xc8\x22\x6a\xd9\xfc\x1f\x09\x35\x5a\xb5\xbb\xee\x59\x50\x53\xe2\x75\xd7\x9a\x9f\x91\xbc\xeb\xa7\x15\x08\x26\x43\x88\xb1\x2f\xdf\x8c\xb7\x69\x26\x63\x46\x34\x5a\x4f\xdf\x1e\x6f\x56\xeb\xdd\xf3\xdd\x6e\xf9\xfc\xed\x69\xbb\xbe\x5f\x6d\xfc\x10\x15\x1b\xea\xf3\xa3\x76\xe9\xe3\x16\x0e\x6f\xdd\x11\x99\x41\x3c\x56\x58\x9c\x72\x1b\x4c\x6e\x46\x07\x56\x40\xcc\x9b\xbe\xaf\xe5\x81\xe8\x29\x3e\x2f\x20\x32\x9d\x85\x14\x62\xb6\x8e\x6e\x97\xa6\x9f\x0c\x01\x91\x68\x1b\x04\xef\x28\x59\x53\x4f\x07\x28\x49\xd6\xfb\xe6\xfe\x6e\x31\x5a\x21\x18\x22\x91\x22\x9d\x0e\xa0\x70\x7c\x24\xb5\x15\x00\x89\xcd\x4b\x59\x4e\x9c\x24\x86\x4a\x5a\x4e\x0e\xfa\x95\xc9\xaf\x21\x66\x44\x04\xf6\x08\x7f\xb6\xbb\xc4\x77\xe8\x66\xab\x09\x90\x3a\xc2\x88\xf9\x6c\x79\x26\x42\x3f\x1b\xdf\xf9\x01\x49\xa0\x7d\x51\xc1\x4b\xf3\xd4\x5d\x3b\x98\x48\x03\x99\x25\xb6\x6e\x45\xfc\x54\xed\x32\x1a\xd4\x8c\xd2\x28\x02\xca\x17\x1d\xe1\xdd\xee\x3b\x8e\x25\x98\x88\x9e\x07\x0e\x48\x1a\x31\x1e\xa2\x13\x19\xb1\xb2\x62\x05\x0e\x58\x17\x44\x1a\xa5\x9c\xe8\x6a\x17\xf9\x8c\xb7\x91\x46\x99\xf4\xc4\x62\x6b\xd4\xe7\x8f\xb2\xaa\x69\x04\x22\x09\x7d\x0d\xcb\x63\x30\xea\xee\x37\x40\x53\x30\xa3\xdf\x36\x37\x23\x63\x9c\x26\x99\xe0\x56\xbb\x97\x92\x89\xf3\xe1\x79\xca\x30\xa3\x8e\xfe\x4d\xeb\xe7\x62\xd7\xcd\x7d\x33\xc0\x79\xb8\x91\x69\xa6\x88\x74\xca\xb7\x80\xf7\xec\x9d\xfd\xd5\x32\x21\xad\x7c\x62\x3e\x4e\x00\xf9\xc3\x1a\x69\x1d\xfb\xd9\xfb\xf0\xec\xdd\xc2\x94\xab\x08\xdc\xdb\xa0\x32\xe1\x76\x4c\x79\xeb\x44\x7d\xc6\xbf\x26\x22\x46\x1f\x1a\xdf\x4f\x37\x97\x6d\x47\xdd\xc9\xfd\xe1\x58\x18\x97\x57\x19\x29\xc0\x4e\xde\x80\x60\x09\xd5\x8f\xad\x0b\x37\x2c\x06\xcc\x16\xa4\x53\xc1\x32\x96\x74\xba\x4a\xf9\xf1\x7c\x74\xac\x0a\x93\xcb\xaa\x00\x43\xd7\x18\xd3\x6c\xf2\xd7\xc2\x6a\x98\x8d\x1c\xac\x14\x82\x2c\x52\x1d\xa9\xea\x17\x97\x85\x1e\x65\x3f\x53\x88\x32\xca\xeb\xdc\xde\x2f\x57\xbb\xf5\xe2\xc9\xd3\xc8\x88\x14\xc0\xf2\x72\x0e\x43\xa3\xee\x0b\x6e\x4b\x2a\x36\xeb\xd2\x06\x5c\xa5\x57\x6e\x17\xa9\x14\x19\x65\x29\x8f\xf0\xee\x3a\xde\xba\x23\x1a\x28\x57\xb3\xab\xb1\x11\xfe\x8f\x2a\x88\xa8\xf7\xba\x8b\xd5\x23\x17\xab\x3b\x9f\x38\x9a\xa4\xee\x52\x15\x30\xdb\x74\xe5\xd9\x6f\x45\xaa\x12\xdb\x63\xd1\xae\xb5\x29\x2a\x5b\xa4\x8a\x0b\xea\x76\x20\x32\xb4\x0f\x56\x81\x4e\x8d\x65\x8a\x39\xe4\x7f\xfd\x35\x48\x6c\xcc\xb9\x51\x29\x42\x4c\x95\x04\x18\x4a\x8e\x0e\xb6\xcb\xd4\xc4\x49\x16\x7b\xe6\xfa\x6d\x79\x83\x8b\x35\xfe\xcc\xb1\x93\x15\x14\xa9\x01\x49\x91\x6f\x87\xdd\x6c\x77\xf1\x19\x5e\x56\x91\x05\x49\xe0\x4b\x32\xdf\xa1\x9a\x2b\x73\x66\x81\x4a\x02\x47\xdd\x7a\xe7\x22\x90\xd9\xf0\xc0\xcd\xdc\x2c\x4c\x91\xea\x7a\x36\xb1\xd8\xd7\xad\xa7\xb9\xc5\x2c\x4a\x2c\x21\xf6\x2b\x36\xbf\xf2\x22\x08\xc3\x80\x05\xf3\xd3\x3c\x8b\x32\xe4\x71\x9f\xfa\xb9\x5c\x95\x48\x3f\xdd\x78\xb2\x08\x83\x34\xea\x04\x44\x9f\x4a\x8d\x5f\xaa\x72\xa0\x29\x73\xee\x9b\xc2\x44\x16\x07\x21\x71\x7d\x93\x3f\xf4\xb3\xdb\x0f\xb2\x84\x2b\x42\x2c\x9f\x0e\x90\xf7\x7f\x44\xab\x45\xe5\x0a\xde\xb4\xf0\x6d\x14\x41\x29\xc8\xd8\x8f\x63\x29\x8b\x9c\x59\xff\xad\x94\x7d\x6c\x16\xfe\x33\x49\x00\x91\x31\x8e\xd2\x92\xb1\x9f\xe0\xf2\x50\xc2\x35\x16\x7b\xf4\xd1\x98\x42\x4a\x3c\x90\xb3\x64\xe3\xf8\x35\x0e\x01\x26\xe3\x4f\x91\x86\x46\x79\x42\xce\xce\xa1\x63\x7d\x6e\x82\xfd\x9f\x1f\x98\x64\xb4\xc8\x1e\x2f\xb7\x77\xa3\x14\x5b\x96\x8a\x80\x66\x25\x59\x7a\xfb\xc9\x27\xda\x0e\x22\x4b\xb5\xd6\x8e\x56\x64\xa3\xb0\x80\x2a\xa7\xa0\xa2\x5e\x14\x9a\xda\x90\x9d\xa1\x1c\xad\xc8\x2c\x0b\x92\xd8\x05\x5e\x33\x58\x97\x8c\x07\x11\x59\xf6\x3f\xcb\xbc\xf8\x02\x47\xea\x43\x76\x0a\x7f\xf7\xb7\x03\xbd\xc3\xa9\x9f\x34\xbe\x8a\x08\x2c\xa6\xc7\x86\xac\x77\x88\x1b\xa7\xc0\xff\x69\x43\x90\xc8\x44\x2c\x89\x8a\x5a\x23\xf5\xaf\xe5\x9d\x50\xe5\x78\x98\x8a\x98\xd3\xd9\x26\xe1\xa8\xff\x0f\x1e\x5c\xa6\x52\x61\x65\x3c\xa0\xbd\xf6\xb2\x3c\x78\xef\x78\x32\x0c\x90\xbb\x3c\xc8\x1d\xa2\x2d\xf8\xde\x9c\x2b\x57\xbd\xb1\x9a\xb0\x6e\xa8\x4e\x52\x7a\xd6\x4e\xaa\xa8\xaf\x5c\xf9\x11\x4c\x11\xa1\xec\x4d\xbe\x81\x7c\xf4\xd2\x27\x37\xa7\xd3\x34\x71\x1f\xb4\x0d\xc1\xee\x20\xf7\xfa\x8c\x22\xd3\x26\x23\x97\x4b\x9e\x2f\x04\x77\x77\xc5\xcb\xf3\x4c\xf5\x78\x50\x47\x1e\xc3\x8f\x32\x6d\x24\xed\x12\x4e\x4e\xb6\x5d\xba\x93\x07\xc7\xd0\x50\x40\xad\x06\x6c\xeb\x22\x43\x60\x1d\x6c\xa9\xb5\x4d\x5e\x8b\x30\x8e\xfe\x35\xaa\xdb\x0c\x0d\x17\x1a\x4d\x14\x5c\xdf\xe4\x01\xea\x26\x9f\x95\xc0\x1e\x2d\x32\x93\x29\xda\xdc\xba\x50\x1e\xd5\xde\xc5\xbb\x1f\xac\x33\x83\x86\x30\x7b\x86\xac\x85\x33\x8c\xae\xb9\x59\xf0\x20\xb2\x6a\xa9\x47\x78\xc3\x11\xba\xe2\x3a\x4b\xc8\x03\x16\x91\xf7\xfd\x2b\xa7\xed\xb1\xdf\x07\x79\x90\x65\x52\x78\x11\xcb\x97\x4e\x57\x4e\xf0\x40\x07\xd4\xdf\xb7\xa3\x0f\xdf\x7a\x85\x43\x96\x66\xc1\x03\xcc\x22\x37\x85\x36\x88\xba\xa7\xc9\xbd\x2b\xab\xb9\x7a\x3d\x0f\x83\x80\x96\xde\xf7\xfb\xe5\x8a\x1a\x4c\x77\xf7\xcb\xe7\xdd\xfd\x66\xb7\xd8\x6d\x96\x8b\x47\x7f\xdd\x30\x06\xa2\x3e\xb5\x1b\xda\x68\x36\xcd\xe1\xf9\xfd\x59\x26\x24\x28\x91\x2c\xcb\xb7\xbe\x71\xef\x03\xd5\x3e\xc1\xa3\x94\x73\xbb\xc2\xa8\x80\x40\x70\xe9\x2b\xc9\x03\xc1\x23\xae\x48\x6d\xf6\xee\xe1\xfe\xe5\xe5\xfe\x69\xb5\xd9\xac\x9f\xbf\x3d\xdd\xde\x3c\x3f\x7d\xf3\x21\x0f\x8f\xc0\xca\xf6\x52\x07\x58\x8e\x85\xae\xef\xf2\xe2\x15\xab\xba\x0d\x0e\x89\x1b\x74\xca\xf4\x3c\x7e\x2d\x11\xa4\x24\xba\x77\x9b\xe7\xa7\x41\x35\x8b\xc7\x81\x34\x49\x07\x12\x5e\x3a\x11\xb8\x2b\xa1\xde\xb1\x43\xc2\x63\xc0\xc4\xd7\xf7\xae\xd9\xe3\x26\x3f\x9d\x84\xc6\x4a\xd3\xe2\xaf\xf5\xf9\x9a\xdd\x6b\x38\x7b\x79\x22\xac\xf3\x7d\x84\x77\xc7\x76\xea\x33\x1a\xfe\x86\x13\x6d\xd9\x73\xe5\xf9\xf2\x15\x07\xd8\x11\x77\x98\x45\x29\x4f\xc7\xf2\xc6\xfe\x4c\x06\x8a\xec\x02\x18\x93\x1f\x72\xc2\x37\x37\xbf\xca\xca\x87\x29\x3c\x4d\xac\xf8\x9f\xcc\x3f\xc8\xf1\xf1\xd6\x53\x6d\x2f\xbe\xc5\xda\x6b\xe5\x7f\xa6\xd4\x2c\x78\xaa\xd0\xb7\xde\xea\x06\xe1\x48\xbc\xd0\xad\xf1\x0f\x27\xb7\x9d\x6a\x69\xd3\x54\xaa\xf5\x31\x87\xf9\x32\x9e\x61\x6c\x49\x5e\xa0\xf8\xad\xfd\x70\xe3\x5b\xca\x0c\xf7\x78\xe6\xfb\xe2\x74\x6e\xea\x59\x46\x01\x37\x98\x73\x41\xb5\x4e\xcf\x62\x7f\x0b\xb9\x8b\xc3\x14\xa2\x9e\xec\x0f\x5c\x04\x86\x1a\x7b\x8e\xa5\xde\x9d\x5c\x07\xcf\x74\xe3\xf9\xac\x3b\x79\xf4\xd3\x42\xd9\x42\x96\x13\x40\xb5\xaa\xa7\x96\x30\x7c\x38\x61\x43\xe1\xa7\x18\x40\x68\xba\x32\xeb\xaa\xd0\x65\x55\x53\xf8\xf3\xd1\x0e\xe5\x4f\x93\x16\xcb\x59\x93\x15\x59\x77\x94\x7e\xed\x11\xe5\xfb\xf1\xda\x35\xb8\x45\x38\x4e\x1e\x18\x14\x27\x64\xf1\x09\xab\x63\x7e\x98\xc8\x16\x08\x0e\x1a\x8d\x63\xd4\x71\x89\xdb\xb2\xea\x2e\x6e\x04\x95\x86\xc8\x9c\x8c\xc8\xea\xe7\x97\xa3\xcc\x32\x02\x4b\xdd\x3f\x7f\x1f\x53\x60\x09\xae\xe3\x44\x8e\xf5\xa2\x6f\xb6\xeb\x69\xe6\x90\xeb\xcc\x12\xd4\xd9\x44\x07\xa5\xfb\x68\x72\x4d\xe6\x95\x96\x61\xd7\x6b\xe2\x92\x9f\xf7\xf5\x5d\x59\xad\x87\xdc\x58\x03\x03\x87\x71\xc8\x1d\xa7\xcc\x47\x73\xfb\x43\xaf\x80\x63\x16\x11\x6e\x6f\x7b\xff\xc7\xfd\xd0\x0d\xe3\x28\x90\x6a\x10\x7e\x51\xe6\x1f\x80\xe4\xb8\x61\xae\x4f\x6b\x6e\x9b\x3b\x0f\xd0\x40\xc3\x7b\x36\xa9\x76\xcd\x55\xd4\x34\xe8\x13\x84\xee\xc7\x45\x80\x29\x65\xa9\xdc\x6a\xdf\x94\x2a\xc7\x91\x26\x9b\x10\x61\x64\x2b\x78\x03\xf6\xcd\x5b\xac\x9b\xaa\xbc\x74\x9b\xb7\x08\x99\xd1\xb1\xe7\x65\xb1\xa8\xc4\xfb\xba\xf5\x2d\xba\x01\x2a\x20\xe2\xa3\xed\x66\xbb\xda\x6c\xe3\xee\xcf\x06\x28\x66\xee\x9a\xac\xcb\xaa\xde\x51\x92\x4e\x97\xbf\x88\x38\x7b\xfc\xc9\x44\x14\x47\x59\x32\xe0\x49\xb5\x30\xbf\x4f\xa8\x52\x85\x88\xb2\x20\xb1\xcc\x5c\x70\x74\x03\xfd\x11\x13\x51\x17\xd7\xce\xae\xbb\xef\x65\x33\xa6\xd7\x10\x22\x0e\x23\xff\xf6\xd4\x19\x97\xd0\xb4\x71\x80\x15\x41\x18\xd9\x7c\x11\xa7\x11\xf9\xc9\x6d\x28\x7b\x03\xea\xed\x95\x28\xc2\xc8\x89\x0b\xd9\x78\xa9\x88\x58\x60\xe4\xe0\x23\xce\xd1\x1f\xe6\x11\x44\x92\xa6\x54\xf8\x05\x59\x56\x96\x19\x79\xd0\xa2\x21\x12\x6d\xd3\x2c\xdb\xf5\x37\x1f\x98\x0b\x16\x67\x49\xcf\xee\xf6\xdd\x02\xa6\x26\x2b\x47\xa4\x51\xc4\xad\xe4\x00\x51\x99\xaf\xb1\xce\xeb\xe6\x8a\xe9\x5f\x88\x94\x85\x26\x1e\xc8\xcd\xbb\xd2\xf2\x94\x70\x51\x88\x34\x4b\x29\x91\xb1\xa3\xc4\x97\x69\xd7\x97\x17\xbc\x18\x10\xea\x08\x91\x05\x40\xa1\xf4\x73\x81\xbf\xe3\xe5\x6f\x27\xaf\x3f\x2b\x41\x8a\x21\xfa\x85\x6e\x13\xcd\x13\x3b\x2c\x32\xd4\x44\x62\x7c\x8b\x3f\xfb\x9c\x9b\xe0\x5c\x53\x1f\x4a\x81\xbf\xfe\x87\x00\x64\xe5\x15\x1c\x4c\x70\x4c\x13\xf7\x19\x36\x4d\x05\x0d\xbe\xda\x9b\x9b\x60\x7e\x26\xb3\x49\x88\x30\x73\x86\xb2\xf5\xca\xea\x7a\xa7\xf6\x90\x17\xbb\xa2\xec\x81\xde\x42\x68\xab\x9e\xf3\x8b\xa6\x5b\x47\x20\x27\x84\x8c\xed\xa7\x97\xe7\x8b\xe5\x1d\x8b\xba\x23\x29\x0f\x2c\x2b\x0c\x79\x4d\xe4\x08\x8d\x7f\x59\xf1\x8c\xf2\xba\x1a\x55\xa9\xf1\x05\x2a\x38\xd6\x33\xc3\xb4\x4c\xa5\xd5\x31\xaf\xa9\xea\x3a\x7e\x68\xad\x52\xe9\x12\xf7\xf7\x0d\x1e\x37\x4d\x79\x3a\xa1\xf6\x51\x5c\xff\xd1\xd0\x40\x2a\x3b\x38\xf0\xbc\xe6\xa6\x1d\x0a\x41\xc4\xb8\xb0\xb2\x0d\xbb\x97\xf5\xfd\xd2\x4f\x4b\x08\xa2\x94\x39\xa1\x96\xbc\x78\xfd\x01\x9d\x8e\xef\xb8\x74\x0b\x81\x14\x54\x50\x5a\xe4\x15\x90\xad\x1e\xf3\xf4\xcc\x6c\x98\x10\x20\x23\x4b\xdc\xba\xfd\x14\xa5\xec\x7e\xfa\x04\x12\x84\xb1\x15\xb8\x5a\x56\x50\xbc\x5d\x6a\x87\xf5\xf3\x47\xa3\x38\xa2\x66\x46\xf0\x55\x91\x61\xb3\xf4\xac\xdd\x85\x48\x28\x82\xda\x17\xe5\xae\x34\xbb\x66\x18\x1f\x43\xa4\xac\xb0\x93\x63\x8b\x1a\xa7\xe6\xe6\x23\x57\x88\x91\x51\x16\xc5\xed\xf6\x43\x7e\xe5\x41\x49\x66\x7c\x4e\x92\xa6\x84\x60\xc9\x0b\x8b\x0e\xfa\xcd\xaa\x6a\x8d\xac\x15\xb0\x38\x95\xc1\x08\xe8\xe1\x6f\x93\x25\x99\x0c\x5c\x29\xa4\xd2\x03\x75\x8e\xf1\xa7\x64\xad\x9b\xe7\x72\x8d\xf0\xbe\xbc\x5e\x6e\x40\x60\xfc\x09\x69\x3b\xc9\x34\x7f\x1e\x75\x03\x33\x61\xe4\x75\x38\xb0\xf2\xb3\x1e\x52\x91\x44\x69\x67\x6c\x9a\xf3\x55\xa5\x0c\xb2\x94\x19\xe1\x0c\xfe\x7d\xf1\xb3\xbc\xe2\xae\x9f\x9d\x1f\x19\x57\x21\x8c\xe4\x60\x7e\x72\xff\x9b\x99\x8c\xc9\xbe\xee\x49\x35\x78\x80\x86\x85\xcc\x64\xae\x14\x48\xcd\xcb\x3f\xf2\x83\x56\x3e\xf7\xe7\x93\x4d\xc0\x03\xe3\x63\x8d\xe5\x79\x5a\xb5\x00\x1e\x07\x6e\x7f\x6a\x76\xa7\x9e\xdf\x70\x57\x9c\x8f\xed\xe4\x39\x55\xe5\xae\x6a\x6f\xc7\xce\xa2\x5d\xeb\x11\x35\xd7\xd8\x16\x7f\xb1\x4c\x3a\xc1\xb5\x6b\x96\x93\xf1\x5b\xe2\x32\xa5\xd8\xf2\xf9\xd4\xc0\x70\xf3\x06\x91\x84\x1d\x1a\xf5\x74\x9a\x7f\x73\xe3\x1f\x15\x90\x12\x07\x6d\x5e\x7f\x3f\x1f\x8a\x81\x44\x55\x9a\xfc\xbb\xdf\xa5\x40\x80\xa0\x74\x55\x5e\x2f\xcb\x5a\x8f\xe7\x21\xf0\x40\xfa\xfc\x8f\x4f\xfb\xcd\xfe\x16\x80\xa5\x61\x6c\xaa\xcb\xe2\x60\x75\xbe\xb0\xfe\x08\xc9\xf0\xef\x29\x62\x6a\x26\x23\x00\x00\x86\xa7\x3d\xb8\xf4\x50\xaa\x17\x1b\xe6\x8c\x7f\x58\x06\x31\x55\x8e\x6f\xce\x17\x8b\x4d\x9f\x7e\x47\x19\x68\xaa\xb3\xfd\xb6\x58\xfe\xfe\xf2\xbc\xdd\x51\xb0\x4c\x8d\xf1\xcb\xd5\x93\xaf\x22\x80\x62\x92\x1c\x48\xbb\x92\x5d\xbd\x36\xea\x8f\x2a\x22\xc8\xd8\xd5\xfb\xdc\x51\x06\xf8\xdb\x54\x59\x00\xd8\xf9\x54\xf9\x11\xd7\x24\x31\xe0\x8f\xca\x84\xd2\xf4\xf6\xb2\x7a\x61\x4d\x5c\x7f\x54\x49\x9f\x0c\x2a\x3e\xea\x3c\x71\x63\xb5\x8c\xb4\xe9\xd5\xf9\xf3\x99\xd2\x17\x68\x0d\x42\x76\x90\xcd\x5f\x05\x56\xb6\x1b\x76\x5b\x6e\x90\x78\xe9\x9e\x8b\x47\x24\x2a\x1e\x7f\x07\x18\xd9\xc4\xe1\x17\x38\xe2\x53\x1b\x1b\xb5\xef\xf0\x53\x9a\x15\x01\x18\x27\x81\xcd\x86\xd6\xe7\x23\x3a\xf6\xb4\xee\x82\x29\x12\x22\x93\x4a\x7a\xf7\x47\xcf\x48\x3e\x23\x5d\xf0\xd9\xa2\x47\x13\x8a\xd4\xf3\x7a\x2f\xcf\x4d\x69\xcc\x20\x09\x0f\x26\x4c\x08\x77\x24\xf1\x06\x8a\xbe\x0f\x40\x06\x42\x46\x3e\x87\x33\x8c\x2d\x65\x00\x96\x45\xa9\x2b\x1f\x95\xea\xed\x5b\xd1\x4c\xd1\x57\x32\xd0\xc2\xb5\xce\x1c\xcb\x9f\x96\xd3\xf3\x3a\x8f\x21\xc3\x30\xd2\xdc\xe7\x6a\xaa\x9f\xb9\x22\x69\xfb\xc5\xe9\x74\xf0\xc4\x97\xd3\xf1\x82\xba\x1b\x96\xe5\x71\x20\x14\xde\xfe\x5d\xa7\xaa\x93\x2e\xb1\x35\x8c\x7e\xe3\x96\x61\x26\x13\xdf\x75\x81\x87\x43\xdf\x94\x3d\xbe\x7a\xc4\x32\x2a\xa2\x9a\xfc\x70\xf8\x76\xda\x96\x83\x14\xf2\x20\x75\x95\x0e\xfe\xa3\xef\xe8\xfa\xb4\xfd\x50\x46\xda\x6a\xd6\xac\x49\xb1\x56\x7f\x3e\x2d\x64\xcc\x02\xaa\xf6\x34\xf9\x11\xbb\xdd\x75\x57\xff\x82\xd3\x8e\x64\x17\xfd\x53\xc7\x29\xc6\x4e\xbb\xad\x29\x90\x0a\xa4\xed\xf6\x36\x7e\xa8\x38\x8b\x7d\x3f\xba\x25\x50\x99\x2b\xe3\xc9\xc4\xc1\x21\xcf\x75\xd7\xb2\x32\xe3\xd1\xcb\x04\x91\xdc\x1a\xd0\xfa\xfb\xc9\xfc\xad\x51\x9a\xe7\xe9\xea\xde\x0a\x0b\x25\xd9\x13\x87\xd0\x5b\x62\x35\x60\x3c\xf5\x63\xd2\x58\xba\x02\xe2\xba\x94\xe5\x74\x02\xb1\xd4\x36\x67\x7f\xfd\xcf\xfd\xcb\x38\x27\xf7\xf7\x54\x61\x42\x32\xae\x89\xfd\xd3\x3b\x1d\x65\x81\xb3\x69\xe2\xb9\x95\x25\xd3\x28\x25\x1e\xb3\x85\xd6\x77\x79\xbd\xbf\xb9\x7c\x92\x61\x96\x29\x04\xca\xf5\x72\x2d\xe1\x04\x2a\xf7\x24\xb6\x42\xa6\x26\x26\xcf\x67\x54\x41\x9c\xe2\x24\xe7\xef\x3f\x13\x69\xe8\xb9\xd9\xbf\x15\x75\x79\xd0\xdb\xdb\x95\x17\xd6\x79\x39\x40\x63\xca\xea\xe8\x7f\x87\xeb\x8c\x32\x70\x8b\x25\xd4\xa0\xf3\xc5\x31\x57\xf9\x70\x5b\x94\x22\xb4\x35\x7b\xf2\x3b\xca\x0a\x5e\x71\xb6\x97\x58\x0a\x16\x52\x25\x2d\xaf\x3d\x6c\xcd\x62\x19\xef\x8b\x17\xeb\x63\x5d\x8d\xb7\x1d\x19\xf2\x7c\x19\x24\xcf\x3f\x92\x60\x11\x52\x40\x28\x22\x2f\xa9\xda\x87\x46\xa1\x88\xfe\x3d\xfa\x37\x0d\x46\x9d\x2e\x12\x42\x4d\x18\xcb\x9d\x39\x1f\xda\x25\xfc\x52\xa1\x9b\x59\xfa\xc5\x71\x7b\x7f\x94\xb0\x1d\xdf\x30\x44\x69\x34\x2c\x91\x7b\x41\x74\x97\x5f\x9c\x3c\x1e\x30\x41\xa9\x80\xd5\xf6\xeb\x40\x17\xc0\xbf\x54\xd0\x92\x82\x65\x5a\x4d\x2f\x7b\x8b\x41\x1a\x72\x36\x8d\x1f\x01\x4d\xe2\xa8\x9a\x9e\xf0\xd7\x80\x04\x6a\xfc\x93\x32\x95\x54\x87\xd9\x56\xd8\x8c\x58\xee\x84\x94\x19\xf7\x3c\xc5\xdb\x8e\xd2\x7e\xd5\xce\xa6\x42\xe1\x1d\x12\x53\xc5\x78\x12\xa9\x58\x93\x7f\xbb\x78\xad\xd0\xe6\xcb\xdc\x01\x64\x9d\x9c\x1c\x41\x51\x37\xe5\x61\x8c\xb9\x92\x98\xa1\x70\xb8\xac\x49\x9b\x8d\x1f\x20\x94\x0a\x2c\x17\x9e\x3d\xf3\xeb\x80\x7e\x4b\x48\xd4\x82\xda\x6e\x7c\xb8\x71\x0d\xaf\xfb\x90\x7f\x77\x00\x2e\x93\x68\xb4\xa3\x61\x24\xb9\xae\x76\x7f\xf3\xfe\x86\x34\x21\x78\x0a\x4d\xa2\x67\x6d\x37\x21\x67\x01\xc7\xef\xd4\x30\x1d\x7b\xc2\x5a\xa7\x2a\xe4\x8f\x64\x99\x1e\x14\x6f\xe8\x31\x97\xd7\xbd\x8e\xd2\xe8\xd8\x2b\x45\x9d\x4f\x16\xd1\x7f\x57\x56\x1b\xe2\x09\xd9\x34\x78\x9a\x0f\x9e\x55\x18\x27\x44\x1f\x77\xb7\x5a\xed\x1e\xef\x1d\xaf\x90\x50\x61\x12\xd0\x8d\xe7\x45\x8d\x55\xd3\x33\x0b\x7d\x40\x97\xa2\xc2\x44\xd1\x34\x3c\x12\xdb\xfd\xa4\x8b\x52\x45\xa1\xa1\x8d\x36\x2f\xa8\xc1\xae\x4b\x71\xab\x28\x13\x04\xba\xfb\x82\xc5\x72\x9f\x9f\x1e\x08\x0a\xbb\x7a\x6f\x2a\xf8\x3c\x78\x51\x11\x0f\x09\xce\x5b\x9e\xb0\xb8\xcb\xab\xba\x19\x61\x51\xc6\xd9\x7f\x15\x01\x50\x26\xe8\x5c\xe4\x4d\xdd\xfa\x50\x1d\xf0\x4d\x45\x60\x98\xa5\x54\x83\xd7\xa1\xfc\xa4\x3f\x2c\x19\x4f\xfa\x54\xdd\x6e\x90\xf6\x51\x11\x6a\x22\xbe\xe8\x4e\x1a\x92\xd4\x7d\x6e\x3a\x55\x1c\x1b\x22\xff\x27\xc0\xd7\x44\xc0\x6c\xfc\xea\x62\x11\x88\x21\xe6\xe6\xb6\x0f\x8e\x54\x6c\x62\x74\xeb\xf5\xa5\x2c\x0f\xf3\x54\x0d\x2a\x36\x99\xe9\x69\xc0\x6c\xba\x6d\xb2\x01\xab\x24\x32\xc4\x06\x79\x2e\xdc\x2c\xd6\x43\xb7\x4b\x25\x09\xa3\xd9\xf9\xa5\x6c\x50\x95\xf9\x68\xcd\xab\x04\x53\x62\x65\xcc\x55\xb9\x29\x4d\xd3\x89\xda\x0a\xc5\x58\x42\x7c\x30\x5e\x04\x60\x0a\x16\x52\x69\x9c\xc8\x60\x40\x39\x67\xd3\x8d\xa3\x45\xac\x52\x96\xd2\xfc\xa7\x4c\xb5\xcd\x63\x7a\x0b\xa0\xb2\xcc\xaa\xf7\x76\xf4\x2f\x5f\x4b\x7d\x98\xfc\x46\x06\x9c\x00\xae\x83\xd0\xaf\x76\xfa\x33\xdd\x04\xe1\x8e\x97\xde\x8b\xb4\x8f\xa7\x0f\xe7\x31\x99\xa8\xbc\x5e\x1d\xf3\x66\xe0\x24\x2b\x2e\x6c\xbe\xcd\x7f\x9c\x79\x6a\x37\xf2\xc9\x66\xaa\xb3\x93\x39\xc1\xa5\xa1\x7c\xff\x73\x75\xda\xe3\xb9\x7e\x84\x2a\x2f\xe0\x06\x8a\xd7\xb7\xf2\xad\xfb\x41\x6d\xb3\x01\x6d\xf8\x39\x5b\xe9\x52\xd2\x84\x91\x15\xc7\x6b\x56\xdb\xaf\xf3\xfe\x80\x52\x71\x9c\x38\x32\xc0\xfb\x06\x8f\x1f\x98\x06\xa2\x38\x6f\x23\xb2\xe7\xa7\x6f\x9b\xdd\xf6\x7e\xb5\x0e\xfd\x7d\x60\x00\x54\x28\x5c\x9f\x0f\xd8\xbc\xc1\x7d\xd9\x1f\x90\x14\x67\xee\x6a\xf8\xe9\x12\x62\xff\x9a\x38\x5e\x0a\x65\x9c\x7a\x59\x98\x9d\xc6\xe3\xb9\x6a\x77\xfb\x36\xa8\xdd\xc9\x11\x3b\x83\x32\x71\x48\x51\xcd\x1a\x2d\xf9\xf4\xf8\xfe\x8c\x08\x28\xa3\x70\xaa\xf0\x5e\x95\x2e\x0d\xde\x13\x22\x74\x17\x01\x43\x75\xf8\x57\x87\x6b\xa0\x0f\x35\xba\x92\x0e\x75\x42\xfe\x67\x83\xef\xcd\x84\xea\xcc\x8d\x88\x02\xc9\x6c\x56\xfc\xd8\xce\x01\xd4\xdf\x2d\x55\x7f\x39\x4d\x37\xe8\x28\xb4\xb9\x8c\x9e\xa4\xf4\xa5\x1a\x22\xae\x75\x94\x49\x82\xc0\x61\xa1\x57\xcd\xfe\x0b\x0e\x05\xa9\x85\x8e\xc0\xd0\x52\x6b\xb0\x6e\xee\xca\x72\xd3\xc3\xcd\x75\x1c\x5a\x4a\xbb\x47\x68\xd4\x9e\x80\x28\xb7\x08\xfa\x90\x17\x1f\x20\xa6\x74\x1c\x6b\x7a\x7d\x92\x32\xf2\x6e\x5f\x19\xed\xa1\x3a\x56\x68\xb7\x5f\xd5\x10\x75\x70\xf7\x77\xcd\xb2\x2e\x1a\xfe\x56\xb7\x91\x56\x57\x99\xd2\xb1\x4e\x29\xc6\xfe\x69\xb9\x5b\xaa\xa9\x2e\x7d\x3b\x02\xa8\x27\xe5\x98\xd7\xea\xa9\x74\x9c\x6e\xfe\x60\x92\x24\x04\x48\x7f\xf4\xd0\x16\x7f\x80\x45\x48\xd5\x94\x3f\x8e\x65\x81\x0d\x0c\x5f\x1a\x8b\x63\xe6\x92\x9f\x63\x78\xbb\x66\x2c\x14\x0e\x36\xf8\x32\x05\x74\x68\xa6\x03\xaa\x3a\x0d\x78\xd6\x3f\x2f\x74\x69\xa6\x15\xb5\x73\xbc\xec\xa1\xd2\xe7\x7a\x5c\x72\xd5\x69\x9a\x11\x8a\x56\x7e\x84\xa6\xd4\xa9\xb4\x37\x4a\x9a\x47\x3d\xa1\xaf\xd0\x99\x4e\x68\xd6\x6b\xaf\xdc\xf5\xa9\x17\xa8\xb9\x08\x33\xd6\xb1\xc1\x1e\xfa\xfc\xe0\xcd\x69\x3a\xe3\x44\xa0\x42\x17\x16\xd9\x17\x3d\x07\x52\xd3\x22\xb5\x7a\x8d\x0d\x56\xc7\xbc\x18\x6e\x38\xa3\x89\x2e\x04\xc7\x61\x84\xfd\x15\xea\x3d\x65\x20\xea\x7d\x7e\x9a\xdf\xa3\xb4\x90\x91\xe3\x93\xb7\x73\xb9\x1f\xef\x06\x80\xb2\x80\xa7\x3d\x71\x4e\x47\x2c\x1d\x32\x74\x69\xc9\x24\x28\xd2\x66\xaf\xf3\x66\xb8\xef\x68\x29\x50\x5a\x07\xce\xeb\x76\x7e\xf0\xd6\x55\xaa\x7d\x8b\xd9\x2d\xb5\x7e\x4f\x25\xb8\xad\xc7\xee\x47\x67\xb1\x57\xea\x5b\x1e\xf2\xc1\x5c\xd2\x31\x23\xaf\xe2\x7e\xf9\x3c\x20\x55\x16\x5a\x67\x56\x30\x97\x44\x5e\xb6\x83\x48\xe9\x0a\x84\x7e\x0d\x32\xd1\x9a\x1b\xca\xa4\x3c\xad\x6f\x76\xe3\xc5\x67\x34\x2a\xde\xe1\x7a\x0f\x70\x19\x3e\x3c\x06\x51\x6a\x2c\x01\x4d\x83\x55\x01\x87\x0f\xe1\x7a\xa3\x57\x81\x41\xa4\x09\xa0\x72\x42\x7c\xeb\x2e\xc5\x14\x79\xec\x1a\x0f\x70\xd9\x9d\xca\xf2\xb0\xd3\x15\xe4\x85\xa3\xca\x99\x5c\x80\x1b\x47\x23\xd6\x2e\xc0\xe7\x9f\x9d\xc3\x8c\x81\x30\x9e\x0e\x68\x38\xd1\x76\x1a\xde\x70\x3f\x75\x69\x31\x90\x82\xcc\xf3\xc3\xe3\xf3\x08\x22\x83\x81\xea\xf8\xbd\x29\xbf\x98\xff\x35\x89\xd9\x30\x4c\xb8\xf1\x3f\x44\xbd\x5a\x06\xab\x8e\x9d\x0d\xc3\x34\x25\x65\x72\xd2\xa8\xb4\x41\xca\xd2\xfa\x36\x79\xb3\xbf\x73\x4c\x75\x50\x61\xd1\x3c\x95\xcd\x7d\xf1\xad\xeb\xdb\xc7\x28\x30\xa9\x5b\x29\xbf\x95\x92\x00\x6e\x30\x57\x65\x18\x2d\x09\x8c\x62\xa5\x8c\x13\xc6\x3b\x3b\x85\x98\x59\x12\x8c\xc9\x97\x88\x74\x1c\x78\x98\xfa\x76\x5f\x95\xbf\x6e\x0e\xa5\x6c\x63\x5b\x7c\x2a\x9b\xb5\x63\xd6\xec\xcc\x22\xc6\x41\xe4\xd1\x8d\xdb\x0a\x34\xd2\x53\x6f\x48\xec\xae\xdd\xa4\x27\xab\x1e\xe3\x18\x09\x37\x45\x8c\x60\xba\x37\xdd\x18\x63\x48\xba\x4a\xed\xcf\xde\xe6\x3f\x17\xfa\x43\x25\xe2\xc9\xfd\x26\x21\xd3\xb1\x87\xb4\xad\xb6\x5f\x2d\x4f\xa9\x3f\xa8\x12\xd5\x27\x2b\x1e\xca\x9f\x58\x7d\x82\xdc\xc0\x04\xd1\xc2\x1a\x1a\xa8\xbc\x16\xfa\x79\x24\x06\xeb\x06\xb2\xc8\x22\xf3\xb0\x75\xfa\x77\xb2\x17\xa6\x11\xc8\x92\x40\x30\x1f\x13\x19\x5f\xbb\xed\x8f\x86\x60\x06\x46\xe7\xbe\x30\xe5\x23\xbc\xbf\x60\x45\x1f\xe8\xfe\x38\x2c\xdb\xf9\x73\x74\x42\x36\x70\x9f\xab\x7a\xb8\xf3\x60\xca\x2d\x47\x95\x93\x78\xba\xce\xa5\x4c\x48\x36\x30\xcb\x32\xc2\x56\x14\xf8\xeb\x2b\xe6\x1f\xe4\x7a\x91\xa7\x09\xc5\x64\xfb\x36\x2a\x82\x23\xe8\x3f\x41\x61\xa1\x2e\xbe\x01\x6c\x58\xc5\x40\x91\xf0\xd4\xa7\xca\x9a\xfd\xd6\x3a\x34\xcf\xe7\xe6\x74\x6e\xae\xb9\xa9\x05\x0a\x61\x3f\x88\x63\x61\x20\x3d\xae\xee\xd5\x09\xa1\x2d\x4d\x04\xf1\xea\xcd\xf6\x96\x4f\x51\xed\x28\x8c\xa4\x4e\x9f\xfb\x97\xbb\x4d\x6b\xa8\x47\x05\x04\x84\xc8\x7a\x9e\x17\x84\x6a\xfb\xab\x1c\x70\xbc\x76\x03\x78\x66\xb9\xa7\xbb\x4f\x04\xa9\xe6\x5d\x3e\xe1\x95\x80\x9d\xb6\xc7\xd0\xdd\xc7\xe8\x79\x24\xb7\x10\x54\xca\x15\xec\x47\x69\x5f\x94\x32\x8e\xac\x49\xb2\xed\xd4\x47\x92\xd3\x29\xdf\x2f\x13\xea\x91\xf1\x03\x49\x69\x57\x88\x95\x33\xb4\x4d\x2f\x2e\xcb\xed\x79\x39\xfd\x48\x94\xd4\x3c\xf9\x7c\xea\xa7\x84\x8a\x6c\xb3\x77\x7d\x56\x0a\xeb\xba\xaf\x18\xa3\x82\x98\xaa\x99\x47\x28\xf2\x13\x21\xc3\x37\xa8\xaa\x0e\xc3\x80\x5a\x1b\xcf\x38\xb9\x51\xfb\xb2\x3c\xcc\x6f\x9b\x88\x4a\x52\x1d\xcd\xc2\xea\xc3\x41\xca\x18\x11\x19\x51\x59\xef\x2d\xb7\xde\xe4\xd3\x1b\x65\x79\xe6\xf1\x1d\xd5\x80\x8e\x72\x98\x95\x30\x41\xa4\x12\xed\xbb\x29\xac\x91\x7d\x29\x0f\xb9\xba\x4c\xb4\xa5\x84\x09\xa3\x10\xb8\xaf\x1f\xda\x14\x53\x77\x84\x53\xb5\xe4\xbf\x67\xac\x2e\x8e\xbd\x66\xf4\x08\x26\xc9\x58\xe4\xe0\x37\xa4\xa0\xd1\x2e\xdf\x25\x54\xba\x35\x60\x54\xa5\xf2\xe3\xa4\x24\x68\x16\x19\xab\x17\xc8\xf5\xc2\x63\xda\xfc\x08\x96\x72\xe9\x70\x61\x0e\xb9\x60\xd9\xa9\x7e\x3b\x57\xe5\x48\xa6\x58\x18\x86\x01\x21\x09\x4e\x9e\x8d\x74\x38\x51\x4d\x1a\x2a\x2a\x11\x14\xf8\xde\x78\x35\x9b\xee\xd5\x99\x34\x52\x94\xc2\x97\xe7\xcb\x12\x0e\x6a\x51\xe8\x19\x41\xcc\xbf\x35\x95\x26\x15\x40\x6c\xfe\x58\x98\xb2\x52\x03\xc1\x8d\xfe\x1b\x9a\x2c\x15\xd4\xdd\x6d\x65\xe2\x3f\xc0\xef\x1b\x9e\x85\x49\x4f\xab\xd1\xc9\x7b\x0f\xa7\xbf\x11\x69\x46\x54\x41\xaa\xa4\x66\xda\xc7\xd6\xe2\x0d\x0a\x68\xdd\x3d\x8e\x6e\x51\xa4\x40\x44\xf7\xa7\xb2\x26\x0f\xf2\x73\xea\xbd\xf1\xe3\x89\x2c\x51\xe8\xeb\x4f\xae\x43\xe4\x4b\x09\x87\x31\x15\x97\x11\xc0\x28\x0a\xdc\xfd\x2c\xcf\x6a\x8f\x55\x7d\x5f\x10\x64\x54\xbf\xf8\x49\xdf\x7d\xb3\x76\x55\x90\x29\x38\x1f\x1a\x28\x9a\x81\xed\x35\x10\xa4\x5e\x74\xbc\x7b\x8f\xcf\xe7\x39\x3a\x5a\x03\x71\x42\xb9\x00\x93\x17\xda\x2b\x22\x0d\x05\xbc\xfc\x30\x63\x3b\x15\x64\xae\x47\x8d\xd8\xee\xb0\x8c\x13\x82\x63\x38\x8c\xd1\x3a\xd7\x63\x42\xbf\x6c\xde\xb3\x32\x2a\x92\xd4\xa0\x74\xbb\x7e\x7e\x5a\xfd\x41\xe5\x47\xff\x0c\xda\x25\xa5\x69\x17\x73\x9f\xfa\x09\x51\x4f\x7b\xec\x8c\x16\xcc\x8a\x35\x6d\x97\x43\xb1\x1d\x61\x34\x5a\xe2\x83\x21\xb8\x86\x40\xb8\x93\x0b\x60\x64\xab\x44\x8e\xb0\xae\x3c\x1c\x6e\xb1\x56\x55\x7e\x1a\xf9\x31\x7d\x2b\x2c\xf7\xe7\x65\x11\x81\xa6\x17\xb7\x8f\xf7\x4f\xf7\x9b\xed\x7a\xb1\x7d\x5e\xfb\x1f\x37\xcc\x46\xb7\xaf\xd8\x3c\xc2\x6b\xae\x1c\x31\x9c\x3f\x9a\xda\x56\x99\xd6\x00\xf8\x9b\xbb\xc3\x89\x88\x12\x04\x41\x94\xd0\xa3\x11\xa3\xe7\x65\xb9\x6f\x4d\xec\x4c\x2f\x0c\x04\x01\x17\xda\xb3\xb2\xed\xf3\x83\x9e\x62\x50\xfa\xdb\x86\x20\x8c\x6c\x57\xee\x01\x0a\x5d\xf7\x72\x81\x10\x84\x19\x87\x5e\xdb\xf3\x6a\x29\x0c\xbf\x38\x04\x21\x47\x02\xeb\xaf\x57\x9b\xd5\xfa\xfb\x6a\xb3\xdb\x6c\x17\xbf\xaf\xfc\xa5\x22\xad\x28\xae\x96\x67\xfd\x8a\xcd\x10\x8f\x06\x41\x84\x36\xb6\x72\x8e\x81\x85\x2c\x8e\x9f\x3b\x76\x94\xcb\x37\xe7\xcb\x5d\x59\x11\x5a\xe6\x33\xb6\xff\xcf\x0c\x0b\x04\x89\x42\x26\xbb\xd6\x32\x1f\xc5\x0c\x92\x55\x10\xb0\x50\xd1\x4e\xbc\xf3\xf6\xef\xa1\x2c\x4f\x77\xb9\x29\x67\xb3\x00\x10\xb0\x48\x53\x43\xbd\x6f\x21\x18\xe3\x57\xdd\xe8\x64\xfc\x89\x18\x03\x4a\xac\xad\xda\xd8\xe3\x54\x75\xd4\x57\x10\x30\x01\x16\xd8\x66\x95\x8c\x7e\xcb\x8b\xd7\x6b\x0c\xf7\xb8\xeb\x65\xc6\x41\x84\x80\x19\x43\x59\x49\x9f\x9b\xb0\x40\xb2\xe1\x3a\x86\x20\x4d\x52\xda\x68\xef\x8b\xdc\x31\x6a\x2f\xb7\x4b\x7f\x23\xa9\x09\x89\xdb\x6f\xfb\xb8\xba\xe2\x1d\x86\x20\x0b\x19\xcd\x1b\xd2\xd8\xea\xb9\x46\xc6\xd7\xcf\x42\x4e\x46\xe9\x7e\xf9\xec\x3a\x41\xc3\xee\x7c\x16\x83\x75\x08\x7f\xde\x21\x8e\x48\x43\x21\xc8\x44\x14\xb4\x17\xff\x7a\xd1\x55\xe9\xff\xc8\x63\xc3\x92\x69\x21\x8d\x8a\x98\x9f\xc5\x6b\x10\x08\x13\x99\xc4\x33\xe9\x9e\x6b\x9c\xa2\xfa\x20\x00\xb4\xec\x1d\x78\xcc\x9b\xcd\x5b\x7e\x38\xac\xa1\x75\x0a\xbe\x50\x5f\xd5\xdc\xc5\xaf\x92\xf4\x1f\x4c\x36\x99\x59\xcb\x4b\xcb\xfe\x7d\x8d\xf5\xa9\x2c\x6a\xdb\xc0\x3a\x5d\xdc\x0a\xd3\x2c\xf5\x1c\xf0\xc3\xac\xde\x07\x97\xd6\x22\x25\xf6\x54\x67\xa6\x08\x62\xf4\x08\xf5\xdb\xdf\x85\x22\x93\xcb\xa0\xb4\x79\x72\xaf\x30\x4f\x8d\x3f\xf3\xa9\x17\x08\x4c\xcc\x19\xb8\xee\x85\xaa\xc6\x4f\x71\x18\xed\x68\x8b\xae\xdf\x51\xd7\x99\x6d\x31\x1d\x84\xa9\x10\x06\x51\xa2\x7d\x06\xa6\xf5\x1d\x9b\x6a\xf2\x61\xc2\x40\x73\x6a\xce\xb9\xcd\x2f\xe6\xe0\x19\x1a\x21\x0c\x05\x5a\xc2\x67\xad\xef\x55\x39\x57\xc5\x84\x30\x8a\x03\x39\x88\x29\x97\x70\x38\x0c\xe6\xe7\xb8\xfe\x94\x5c\x89\xff\x5e\x47\x24\x10\x46\x22\x24\x9a\x8a\x9f\x16\x6b\x3a\xec\x62\xed\x46\xa0\x65\x61\xa7\x16\x9e\x6d\xb9\xa1\xf5\xe8\x49\x2a\xe3\xe8\xff\xfc\x38\xc9\xb8\x53\x52\x20\x56\xe6\xe1\xba\x0d\xe3\x38\x21\xac\xd5\x17\x42\x2f\x1d\x72\x05\x93\x4a\x14\x84\x49\xa0\x4d\xd0\x13\x21\x4d\x5e\x5a\x12\x71\x6a\x49\x79\xad\xa0\x68\x16\xe4\x5b\xfb\xa2\xe5\xf8\x15\x25\xc2\xf6\x7b\x7a\xe1\xeb\x27\x7c\x6f\xbe\x59\xa4\xac\x7f\x22\x96\xb2\xd4\xad\x52\xdb\xe4\xdd\xa7\xc9\xae\x96\x51\xc8\x54\x6c\x7b\xeb\xdc\xbc\xb8\xb9\x3c\x0f\x19\x09\xe7\x97\x67\x98\x71\x2b\xe4\xf0\xb0\xbc\x9d\xef\xba\xf9\x9b\x7f\xfd\x65\x00\x3c\xb2\xd5\xa9\x2b\x6c\xf3\xd3\x6c\x7b\x31\x84\x3c\x4c\x32\xee\xd7\x5a\xeb\x9c\x2e\xcf\xc7\x36\xcc\xc8\x7f\xa2\x27\xda\x9d\x3c\x1a\x8f\x24\x31\xf2\xb5\x7e\x1e\xb5\x35\xce\xae\xa6\x90\xa7\x2a\xf3\x94\xc6\xff\x74\x5f\x9a\x61\xa4\x18\xec\xcf\x21\x07\x24\x04\x0f\xb5\xd1\x8e\x67\x0a\x37\xc2\x58\xd4\x9a\xf3\x20\x9d\x43\x34\xff\x82\x20\x94\x54\x39\xfe\xcb\x2f\xdb\x1f\x79\x51\xd0\x3c\xf6\xac\x1f\x10\x02\xb7\x5c\x25\x32\xd7\x37\x43\x21\x8a\xff\xfd\xbf\xc9\xc5\x64\xa0\x48\x38\xd3\x35\x09\x39\x8a\xd8\xc9\x4b\x93\x89\xed\xbc\x7e\xc5\xe6\x78\x79\xc3\x4b\xae\x27\x13\x50\x8a\x94\xd8\x0c\xef\x72\x7d\x7e\x27\xc1\xc4\xbe\x3e\xf8\x0f\xcd\xd8\xf4\xbe\x34\x80\xc5\x0b\x9f\xeb\xd5\xf6\xab\x7f\x2e\xa5\x62\xe6\x59\x71\x6c\xa3\xc9\x1a\x8a\x2b\x36\x1b\x37\x18\x03\x20\xc2\x5c\x1b\xd5\x12\x1b\xf5\xf0\x83\x60\xaa\xe8\x27\xb0\xd0\xd7\xed\xf9\xed\x61\xa3\x9c\x1d\x5f\x1d\x4f\x87\xf2\x82\xf8\x4f\x7a\x3b\x21\x44\x11\x85\x96\x00\x94\x92\x53\x1f\x32\xd2\x4c\xef\x56\x58\x55\x11\x4a\x85\x3f\x9b\xdf\xb1\x28\x2e\x3d\x74\x0a\x42\x13\xab\xa8\x23\x04\xf2\xda\xc3\x93\x7b\x36\x5c\x44\x4e\x24\xc5\x41\x3c\x06\xc5\xc2\x29\x47\x0d\x44\x01\x4b\xa5\xdd\x06\xfe\x44\xd5\x38\xec\x85\x9f\x43\x51\x18\x59\xd0\x80\x9d\xaa\x50\x68\x5a\x83\x83\x7c\x34\x44\x91\xe6\xa1\x43\x8c\x2c\x57\xcf\xfe\xc4\x38\x8d\xb9\xab\xd0\xdf\xe5\x07\x7c\x28\xd5\xf8\x36\xa3\x38\x4b\x88\x3b\xaa\x0d\x3c\x7f\x74\xd5\xda\x0b\xf5\xed\xf8\x21\x22\xb6\x1c\x8a\xd5\xe5\xd4\xc0\xb9\x3a\x77\xb7\x95\xb0\x80\x48\x18\xa8\x83\xf7\xeb\x59\x8e\xa7\x62\x94\xa8\x94\x62\x49\xb5\x87\xaa\x21\xee\x4f\x7f\x62\x16\xd9\xfa\xfd\x06\x9b\x85\x3e\xe6\xc5\xe4\xc4\x8c\x71\x7a\xff\x4d\xf9\x75\x12\x26\x41\x94\x09\xcb\x1d\x4d\x49\xe0\x28\xd9\xfb\x4b\xf2\xd8\xf5\xaa\x93\x71\xb6\x0d\x04\xed\x4a\x24\xf7\x78\xf2\xd0\xd4\x33\xeb\xc5\x61\x17\xa7\x7c\xb2\xcf\x45\x02\x2d\xfd\x6d\xdd\xce\x47\x3c\x42\xd1\x77\x21\x6e\xcb\xe7\x2b\x46\x58\x88\x20\x0e\x62\xe1\x11\x24\xa7\xd6\x08\x60\xf5\x52\xe5\x7f\x61\xf7\xaa\x20\x49\x08\xc3\xbe\x23\x50\xd6\x61\xca\xa5\xee\x47\x31\xe6\x30\xb3\xed\xbc\x82\x06\x2b\x4b\x36\x94\x17\x8f\x50\xbd\xe6\xf3\x8c\xf8\x7e\x0b\x8b\x20\x63\x20\x06\x70\x59\x55\x6a\xac\xda\xa8\xf6\x11\xde\x37\xf9\x5f\x7e\x03\x8a\x64\x1c\x52\x9d\xeb\x26\x4a\x06\xd1\x1c\x44\x32\xe1\x96\x81\xd2\x73\x07\xd8\x04\x26\x75\xf2\xcf\x1b\xe7\x48\x2a\x15\x72\xdf\x6c\x3e\xa8\x80\x43\x24\x4d\xd4\xd1\x4a\xdb\x47\xb5\x89\xd0\xd9\xdd\x23\x52\x81\x55\x19\x69\xaf\x63\x13\xaf\x8f\xf0\x86\x95\xe7\xae\xfc\x7c\xbd\x46\x1a\x43\x62\x4a\x5e\xee\xf3\xd3\xb6\x42\xa8\xcf\x9d\xff\x10\x61\x1c\x92\x09\x50\x70\x72\x29\x9a\xee\x48\x02\x54\x34\xab\x20\xaf\x51\xfb\xc9\x0f\xdd\x24\x45\x0c\x28\x8a\xea\x16\x82\xc9\x42\xed\x9c\xde\xd5\x7f\xcf\xf9\xa9\x5d\xa2\xdb\x0a\xa8\x2b\xe1\x0e\xf1\x03\x05\x29\x88\x0c\xa6\x31\x38\xc2\x95\x47\xc8\x8b\xbe\x44\x08\x71\x20\x6d\x21\x70\xe7\x09\x82\x82\xdd\xce\x1f\x0b\x33\x45\x44\x33\x9b\xaf\x8b\x88\xa5\x5f\xa1\xde\xfb\xfc\x7b\x37\x02\x24\x3d\xb8\xb7\x30\xb6\x11\xba\xcb\x3d\x40\x1c\x31\x43\x97\xd8\xd5\x44\x7f\x49\xe0\x36\x2f\xdb\x4c\x91\x54\xc4\xfd\x48\x1d\x38\x71\xe7\x5c\xbd\x1d\xf0\xb6\xfc\x55\x50\x62\x0c\xeb\xb5\x03\x57\xf8\x1f\x8d\xa3\xc0\x6d\x91\xdd\xce\xd2\xa7\x20\x21\x8e\x39\x23\x48\x34\xe4\x95\xae\xca\xd3\xb6\x9c\x21\xe6\x1a\x7f\xbf\x38\x61\x56\xb3\x5c\x53\x1a\x65\xd6\xf7\x8c\x13\x85\x04\x7c\xd4\x56\x03\xd2\xed\xce\x1e\x18\x32\x6b\xfe\x63\x16\x5b\xed\xf6\xdf\x2b\x78\x43\xab\x95\x48\x28\xed\xee\xfd\xb1\xd8\x10\xb1\xc3\x36\x0a\x7a\x66\x35\x88\x59\x62\xe9\x46\x29\x5b\x4b\xde\xe4\xe4\xba\x28\xa9\x77\x27\xaf\x7f\xe4\xc5\xe6\x50\x5e\x75\x6c\xba\x71\xa9\x8a\xe9\xe3\xba\x94\xa7\x4d\x66\x7d\xb0\x63\xfd\xb3\xd8\x22\x4e\x31\xd0\x30\xa2\xf5\xf2\xe9\xcf\xc9\x38\x93\xf8\xee\xab\xc7\xbc\x68\xda\x57\xf6\x52\xb5\xce\x66\xcf\x41\x3b\xdb\x75\x0c\x71\x06\x48\xfb\xfa\x66\x5f\xfe\xda\x35\x7b\xdc\x15\x60\x21\xb5\xcf\x94\xad\xd9\x2d\xfc\x5b\xe2\x1c\x08\x21\xfc\xf8\xfd\xd1\xff\x49\x04\x60\x89\x93\x2a\xc4\xf6\xf3\xb8\x1a\x8a\x3b\x0a\x01\xa3\x14\x56\x7d\x96\x3d\x63\xf7\xf8\xc7\x21\x45\xea\x0e\xde\xfe\xf1\xe0\xcf\x92\x19\x26\x91\x2d\xca\x14\x1a\xaa\x6e\x1a\xaa\x20\x22\x97\x9c\x8c\xb8\x0d\xb5\xda\xe8\xd5\x12\xf0\xe4\xae\x04\x7e\x4d\x1b\x01\xb1\xe2\x96\xa3\x5e\x5f\x0a\x38\xe6\x6a\x89\x79\xdf\x43\x0f\xb1\xd6\x61\x6c\x7c\x1e\xbc\xac\x70\x50\x4f\x82\x18\x23\x16\x1a\x4b\x46\xfe\x33\x2f\x5e\x87\x14\xb4\x10\x9b\x28\xcd\x22\xcf\x1c\x59\x4f\x72\xa6\x10\x1b\xce\x2d\xa2\x89\x72\xa6\x5f\xac\x42\x91\xf7\x1b\x92\x60\x58\x56\x81\x24\xc8\xac\x52\x0d\x15\x85\x5c\x29\xd5\xeb\x34\x0e\x53\x8c\xe3\xd9\x91\x04\x52\x72\xd7\x53\xb2\x38\x1c\xb0\x7a\xcd\x71\xd0\x8d\x05\x49\x80\x96\x71\x9c\x30\x10\x1f\x2a\xde\x4e\x04\xd2\xff\x37\xfa\xbf\x7f\x4f\x45\xe0\x20\x09\xa3\x90\x2e\x45\x74\x06\xad\x55\x6b\xb0\x18\xa4\x1b\x92\x30\x31\xc6\x15\x06\x7b\xe2\x38\x5b\x63\xef\x86\xa4\x82\xb2\x82\xf5\x2f\x38\xdd\x5d\x53\x47\xff\xa3\x15\x32\xcf\xc3\x0d\x49\xa8\x59\xe0\xe5\xf1\x0f\xf9\xeb\x7e\xa6\x1a\x05\x49\x84\x9c\xa6\xeb\xe6\x7e\xf9\x87\xbf\xa9\x38\x8d\xb0\x23\x95\x68\xad\x60\x77\xc0\x80\x08\x06\xa5\xbb\x17\x92\x90\x86\xc3\x84\x79\xdb\x8d\x4e\x22\xab\x44\xe5\x84\xa6\x1f\x9e\x97\x3e\xab\xf8\x01\x4e\x7a\x72\x7a\x12\xc6\x56\x82\xb1\xb8\x39\x57\x05\xa5\x98\xfb\x9a\x20\x24\x49\x1a\x85\x2e\xcc\x7f\x82\x23\x2e\x0a\xbd\xb9\x1c\x65\x79\x98\x4b\x5d\x26\x2c\xe2\xc4\x5f\xa7\x07\x22\x99\xe3\xae\x4e\x48\x58\x6c\x1b\xbb\x7c\x20\x43\x3a\xbb\xe7\x43\x53\xe7\xaf\x53\x8b\xe5\x7d\xd6\x24\x95\x92\x1c\xc3\x36\x32\x1b\x48\x98\x8d\x9c\x92\x24\xd5\x16\x8c\xde\xce\xe4\xe9\x9a\x48\x52\x13\xa4\x56\x13\xfa\x69\xf9\xbc\xde\x2d\x9f\x9f\xbe\xaf\xd6\xdb\xd5\x7a\x77\xb7\x58\x6e\x9f\xd7\xff\xf1\x77\x97\x05\x60\xdc\xbc\x7e\x6a\xf6\x37\x97\x99\xdc\xe9\x20\x9c\x48\xb2\x40\x52\x33\xf2\x2b\x1c\x6d\x16\xc7\x37\x26\xfa\xe3\x29\x7a\x74\x35\xd9\x64\xe7\xdb\x8d\xe9\x67\x20\xe1\x21\xd0\x14\x5f\xac\x6f\xee\xb7\xeb\xc5\x97\xd5\x8c\x35\x49\x78\x96\x11\x5c\xb7\x71\x0d\xd1\x38\xd0\xe5\xc8\xb1\xbe\xcd\x6b\x79\xae\x88\x79\xd1\xff\x3a\x04\x09\xb4\x86\xeb\xf9\xc7\xd3\x6a\xbd\x5b\x3e\x2c\x7e\xdc\x2c\x96\xbf\xef\x6e\x17\x5b\x9f\xdc\x4d\xa4\x31\x92\x7b\x53\xe2\xb9\xd3\xc6\x6c\xfc\x6e\xa4\x0a\x32\xf0\xfd\x17\x37\x87\x36\x00\xf3\x07\x78\x14\x69\xef\x7f\x1d\xf3\x62\x22\xca\x34\x99\x6f\x4a\x59\x0c\xc9\xed\xb9\xd8\xe7\xde\xdc\x25\x9a\x23\x73\x0e\xe5\xcd\xe2\x5b\xe4\x18\x04\x67\x3d\xb8\x44\xa3\x66\x9d\xac\xd1\x8d\x2d\x54\x4d\xd6\x04\xa6\x82\x2c\xe0\xef\x17\x89\xd4\xc3\x99\x57\x14\x0d\xf5\x05\x94\x53\x93\x1f\x7b\x36\x1a\x48\x8c\x12\xca\x4e\x9e\xf2\xed\x7c\x1a\xaa\xe0\x01\x0b\x82\x80\x54\x6c\x7f\x6c\xfe\x18\x7a\xb1\x2c\x8c\x23\x02\x01\xc3\x51\xe6\xef\xdd\x1f\xb5\xd5\x91\xb1\x1e\xfd\x90\x61\xdc\xcf\x66\x16\x31\x1b\x09\xd5\x60\x90\xea\x33\xcf\x66\x0b\xf5\xdb\x84\xfa\x04\x58\x94\x81\x91\x3d\xd6\x6d\xd8\x79\x3d\x18\xa4\xc1\xd2\xdb\xe5\xba\x0d\x76\xef\xca\x8a\x28\x54\xe7\x9c\x7e\x16\xa1\xf2\x96\xd2\x12\xb4\x2f\xcb\xc2\xe4\xaf\xe7\x21\x6d\x30\xb0\x38\x0c\x42\xe6\x61\x2c\xd4\x89\xba\x68\xae\x35\x05\x80\xc5\xdc\xe6\x80\x15\x14\xab\xf7\xbc\xe9\x09\xd4\x80\xc5\xc6\x12\x1e\x92\x40\xe0\xe4\xbe\xbb\xd7\x90\xc4\x29\x75\xc4\x92\x70\xb4\xfb\x25\xdb\x98\x39\xfa\xde\x2c\x51\x9a\x22\xfa\x93\xa5\xb5\xa0\x0a\x02\xd1\xd0\x4e\xee\x27\xc1\x8c\xaa\x34\x7b\xa8\xf7\x8f\xa0\xf6\x79\xe1\xb7\x08\xc6\x54\x68\x9c\x45\xed\x32\x02\xfd\x89\x69\xcc\xa9\xe8\x79\xa2\x02\xb0\xed\xa8\xb6\xeb\xb4\xdd\xe6\x07\xd4\xab\xc0\x52\x88\x09\xf3\x79\x87\x48\xe9\x3d\xd4\x1f\x18\x5b\x37\x3e\x03\x61\x65\xdc\xee\x5f\x36\xa3\xb9\xc3\x83\x44\x7a\x7a\xe1\x1e\x1e\x38\x3e\x99\x0b\x43\x20\x11\x38\x37\xfb\xab\x4c\x23\xe3\xca\xb6\x91\x5b\xbe\xb1\x89\x95\x65\x22\x04\xea\x27\x39\x79\x4e\xc6\x5b\x68\x60\x4d\xbd\xb4\xf3\x89\x13\x26\xa2\x98\xd0\x08\x2e\x41\xfa\x72\x80\x62\xfa\x86\x45\xeb\x35\x79\x40\x96\x43\x42\x4b\x67\xd0\xfc\x90\x14\xa8\x08\x48\xa9\xfd\x29\xca\x6c\xfc\x5d\x65\x6c\x61\x71\x6d\xc4\xf0\x15\x2c\x7d\xd4\x44\xe0\x14\x98\xe2\x01\xe5\x90\x4b\x57\xa4\xdf\x11\x58\x82\x3c\xae\xc5\xb9\xf1\x96\x8e\xe9\x40\xa4\xd6\x4f\xb6\x41\xf3\x6c\x7e\x89\xe9\x38\x26\x22\xb5\xdf\x7f\x1f\x7d\x0b\xad\xed\xb2\x20\x30\xce\xa6\x29\x4f\xf7\xcb\xe7\x81\x2f\xc3\xd0\x51\x10\xd9\x66\x01\x9a\x0f\x03\xd1\x11\x3a\x4e\x25\x75\xa4\x4e\xf0\xb2\xb2\xb7\xe0\x0f\xf2\x94\x38\x30\x95\xa7\x92\xbf\xf4\x5d\x1c\xc0\x50\x22\xe5\xb9\x3b\xca\x48\x9c\xda\x5d\x86\x8a\x11\x18\xb9\xc0\xd7\x03\xaa\x66\x78\xf1\x34\x10\x92\xfa\x07\x3b\x86\xf4\xfb\x3e\x64\x4b\x43\xc7\xa9\x57\x63\xd3\x5e\xbe\xb9\xde\x52\xd2\x88\xc5\x14\xb6\xd0\xbb\x77\x13\xbf\x9e\x22\x1f\xaf\x89\x70\x20\x8d\xb8\xe5\xb4\xae\xf0\x27\x0e\x82\xe6\xd1\xae\x96\x46\x1c\xc3\xcc\x8b\x43\xd5\xfb\x7b\xfd\xbe\x98\x67\xbc\x80\x34\x56\x12\x02\x5f\x51\x6f\xa3\xd6\x9e\xe6\x71\x30\xc8\xa0\x05\x4f\xef\x1a\xa8\xa8\x63\xce\x7a\xb8\xad\x4f\x72\xc2\x42\x2f\xe1\x70\x90\x70\xcd\x73\xed\x4e\x4f\xb8\x24\x13\xef\xe3\xef\x8e\xdf\x17\xd2\x04\x34\x41\xa9\x8e\x16\xfe\xd2\xd1\x32\x40\x9a\xc8\x8c\xba\x73\x5d\x81\x73\xa7\x9d\xe8\x92\x9f\xf0\x29\x0b\x0c\xf5\xe1\x14\x67\xc7\xec\x61\x81\x20\xfd\xf1\x98\x19\x47\x93\x78\x18\xa6\xd1\x52\x96\xd9\x3c\xcd\xf2\xf9\xb6\x1b\xcb\x0d\x51\x18\xe8\xbc\x42\xd5\x94\x15\x31\x91\xf9\x63\xc6\x6a\xed\xe7\xf5\xe6\x52\x34\x7b\xac\xf3\xbf\x70\x44\x53\x0f\x69\x06\x11\xa9\x1c\x20\x05\xac\x03\x84\x26\xa4\x99\xb1\xd9\xb9\xd6\x77\xf8\x52\x16\x13\x0b\x98\xf2\x30\x41\xab\xda\x96\xd7\x79\x6d\x7a\xcb\x99\xf2\x34\xa5\x7c\xe0\xc9\x33\x55\x87\x11\x77\x6e\xd7\x78\x71\xa5\xc2\x20\xc1\xf9\x68\x1a\x8d\x98\x80\xdc\x00\xd0\x21\x01\x27\x8f\x96\xf3\xb0\x6e\x6e\xce\x97\x09\x88\x6c\xd6\xc3\x4e\xc1\xc4\xb1\xb4\xd1\x5c\x73\x85\x5c\x1d\x3f\x88\x8c\x6c\x72\xf3\x57\x9f\x63\xf9\x60\x60\x0c\x99\x03\x17\xe5\xaf\x85\x93\x5e\x9b\x1f\xaa\xd2\x84\x1c\xfc\x0e\x52\x90\xab\x2b\xe6\x53\xff\x4a\xce\x23\x0c\x5f\x5f\x6e\xef\x8c\x49\xaa\x32\x6e\xa3\x19\xba\x5a\x3b\x17\x1f\x5f\x7c\x12\x35\x55\x3a\x8a\x6d\x39\x9f\x40\x91\x83\x9d\xc8\x8f\xd0\x69\x4a\x50\x7c\x4b\x38\xff\x8f\x30\xaf\x90\x6a\xd0\xb1\xf2\x64\x63\x88\x74\xc1\x6a\xbe\x4e\xe9\xce\x40\x6e\x7b\xe5\xdb\xa9\x7c\xae\xb1\x81\x49\x12\x7c\xb8\x13\xa5\x26\x03\x24\x96\xd5\x5f\x08\x6f\xb6\x04\xd5\x87\xb9\x19\xe9\x63\xdb\x8a\xd8\xc7\x3d\x98\x90\x05\xa9\x15\xb2\x69\x97\xe0\x72\xdf\x17\x7f\xfc\x61\x83\x14\xf2\x7e\xf1\x5a\x06\x63\xce\x7b\xc8\x42\x69\x79\x4a\xb0\xd9\xaf\xce\xde\x06\x66\x71\x64\xbb\x0e\x97\x4b\x5b\x2a\x5a\x54\xd2\x1f\x4a\x20\xf3\x81\xcd\x0f\xcc\xef\xca\xea\x51\x4d\x52\x1b\x59\xa2\x91\x22\x34\xeb\xc6\x50\xba\xd7\x12\x94\x93\x11\xbe\x9d\xdf\xd7\x32\x16\x86\x54\x36\x3f\x0d\x68\x35\x86\xef\x2b\x63\xb1\x65\x3e\x24\x34\x45\x75\x28\x2b\x3d\x68\xcb\x58\x43\xa1\xcb\xe3\xe4\x46\x18\x40\x68\xfb\x14\x5b\x7b\x37\xd4\x88\xf6\x03\xa4\xad\x81\xbb\x5d\xe6\x6b\xa9\x0f\x3d\x24\x18\xb2\x34\x49\xbd\x04\x0e\x55\xc8\x3b\x96\xfd\x2b\x2c\x48\x96\xa6\x29\xb9\x6e\x6e\xbb\xf9\x72\x6e\x3f\xfb\xe8\xb7\x52\x8e\xb4\x21\xad\x96\xcf\x4f\xcf\x8f\xff\xd9\xdd\x3c\x3f\x6f\xb6\xbb\xed\x7a\x71\xbb\xea\x7e\x4f\xc4\xe4\x31\xd7\xa0\x27\x81\x58\x96\x62\xe6\xc9\xc2\x9f\x4a\xa7\x32\xf1\xc1\x2c\xcc\x32\xae\x08\x01\x48\xb8\xf2\x49\xfb\xea\x15\x92\x1c\x32\xce\x85\x4b\xa6\x37\x77\xe7\x82\x4a\x25\x9b\xfc\x7d\x26\x1c\xcf\x20\x51\xb4\x29\xef\xa8\x2e\xf7\x72\x4d\x84\xe6\xc7\x71\x4e\x0e\x43\x55\x1e\x28\x3b\xbe\xc1\x89\x20\x39\x64\xa0\x0d\xe9\x9c\x9c\x86\x5d\x2c\x90\xc9\x24\xa0\x62\x32\x75\x76\x7d\x4a\x2b\x08\x99\x64\x19\x15\xc4\x1f\x41\x97\xc6\x0c\xca\x3f\x99\x92\x31\x65\x59\x68\xef\xf6\x8b\x7d\xc4\x45\x03\x99\x86\x94\xc2\x5e\x79\xae\x0a\xdb\x2a\x47\xef\x74\xc4\x79\x3e\x7e\x2a\x2d\x99\x97\xb6\x58\xe3\xe4\xfb\xf0\x20\x4e\x29\x57\x4d\xac\x68\x70\x20\x87\xc6\xa2\xac\x47\xee\x27\x0f\x83\x90\xc3\xb0\x49\x60\x00\xc9\x03\x1e\x86\x19\x4d\x80\x0a\x89\x20\x61\x54\x7a\x19\x3f\x3d\x0f\x63\xa3\x99\x67\x2b\xb7\xfd\x94\x3b\x93\x5b\x8d\xd0\xaf\x79\xd1\xbc\x54\xf8\x73\xd1\xbc\xb4\xbb\x6f\xeb\x22\x0f\x9f\x84\x87\x22\xd1\x0e\x13\xfc\x1d\xab\x9a\xf4\x34\xda\x40\xe5\x33\xb6\x43\xe0\xa1\x64\x84\xa5\x54\xb6\xa2\xf6\x88\xaf\xe0\xc9\x69\x46\x2f\x8a\x47\x4c\x49\xa7\x30\xe3\xfd\xb6\xd9\x79\xc2\x59\x68\x8c\x1c\xd6\x33\x6e\x73\x85\xb6\x38\xf3\xa9\x3c\x0a\x70\x96\xb1\xd4\x7e\x3d\x27\x69\xec\x73\x70\xf3\xdf\x8e\x33\x1d\x19\xe8\x58\x69\xda\x28\xee\xdb\x69\xf2\x05\xd3\x90\xc7\x4e\x0b\xe0\xeb\x49\xb6\x3e\xc4\x54\x0d\xe8\x23\x2a\x04\xe0\x29\x4b\x88\x8d\x71\x55\xe8\xd4\x7f\xcb\x54\x89\xd0\xd3\xb0\x43\x83\xf7\xaa\x6c\x3f\x0d\xa5\xec\x6f\x2e\xb7\x57\xb6\x88\x67\x01\xb3\xc4\x07\xc4\x56\xeb\x48\x46\xfd\x31\x65\x83\x8c\x57\xaf\xc2\xf0\x90\xd7\xcd\x50\x2f\x00\x38\x8f\x03\x42\x35\x51\x43\x22\x1c\x76\xb6\x3b\x72\x77\xbc\xec\x70\x10\x89\x71\x2e\x2d\x73\xfe\x57\x38\x94\xf1\xed\x66\x5f\xe5\xc7\x93\x93\x7b\x1b\xbf\x0e\x21\x63\xcb\x9d\xed\x22\xa4\x5b\x54\xf9\x11\x0e\xf5\xa4\xad\xb4\xdf\xa2\x39\xa8\xc0\x25\x34\x5a\x7f\xdf\xff\xa0\x0c\x41\x98\x9e\x8d\x6c\x5b\x4e\x22\x3f\x3f\x8c\x31\x0b\xca\xaa\x7f\xe4\x07\xbd\x84\x4a\xdb\xe6\x0b\x7d\x57\x56\x4b\x68\xf0\xb5\xac\xc6\x40\x00\x2e\xa5\xb4\xc5\x4b\xdf\xa5\xe9\xe0\xd2\xe3\xdc\xe8\xf0\x06\xa5\xb4\x4a\xf6\x44\x30\xbd\x4b\xfc\x1d\x2a\xd0\x44\xb3\x72\xcc\x5f\x2b\x68\x5a\xef\x70\xf2\x2a\x94\x61\x59\xd8\x25\x86\x5d\x6f\xc8\x8c\x0e\x06\x70\xcd\x38\x39\x73\x04\xdf\x7d\xda\xdc\xfd\x98\x7c\x63\x9d\x2a\x1c\x36\x8e\x59\x7e\x83\xae\xcd\xd0\xdf\x91\xd6\x99\x30\x5e\x68\xa0\x26\x8a\x77\x24\x37\xfd\x23\xd8\x11\x47\xa1\x53\x57\x80\x6f\x26\xc0\xb9\x6e\xfd\xa2\xb1\xbc\x84\x5f\x6e\x5e\xc6\xb7\x25\x02\xb0\x4c\xf5\xf8\x8e\xc7\x53\xd3\x9a\x40\x02\x62\x8e\x9e\x4d\x84\x2c\xa5\x64\xc0\x43\xf9\xba\xd0\xfa\xba\xe8\x22\x42\x64\x28\x3a\x76\x94\x3b\x90\x55\xae\xe6\x8d\x97\x88\xa5\xc9\x2c\x62\xe1\xe0\x25\x6e\x3e\x1a\xa9\x14\x77\x5a\xe0\x1f\x8b\x1a\x83\x88\x4d\x68\x09\xfe\x7c\x58\x7f\x3c\x41\x31\x56\x1d\x02\x91\x24\xdc\x22\xec\x49\x75\x3a\x7f\xbd\xeb\x9b\x7e\x41\x24\xca\x2a\x7a\xbb\x66\x5d\xeb\x32\x6c\x1a\x78\xb3\x81\x8d\xc3\x8f\xda\x2a\x40\xff\xcf\x30\xb7\x39\xfa\xaf\x1e\x38\xfd\xef\xeb\x13\xfb\xfb\x66\xa8\xa9\xd2\xfb\xbc\xfd\xba\x5a\x2f\xd7\xdf\xee\x37\xab\xf5\xee\x6e\xfb\xb0\xdb\xbc\xac\x56\x3e\xc0\x11\x69\x10\x91\x68\x13\x36\xfb\x6f\xb5\xee\xfe\x2a\x2c\x8a\xcd\x99\xbe\xd6\xcc\xc3\xe1\xb1\xd4\x78\xb0\xb9\x5e\x37\x2c\x63\x61\xe4\x2a\xb7\x5f\xe0\xd8\xa1\xe7\x41\x64\x02\xa8\x5f\xed\xa1\x54\x6f\x3e\x0f\x32\x53\x3b\x17\x99\xe4\xe4\xb8\x58\x71\x98\xf6\xc3\xdf\x0e\xf2\xd4\xfe\x6a\x3c\x4e\xd8\x98\x3c\xf2\x31\x2f\x5a\x77\xb3\x78\x45\x1f\x30\x0a\x11\x59\x11\x59\x27\x79\x72\x83\x1f\xec\x0c\x42\x64\xa1\x40\x8f\x21\x1c\x14\x54\x85\xe0\x10\x08\xff\x33\xeb\xf2\x02\x07\x4f\x3a\x02\x42\x48\x1b\x5d\x9f\xc8\x67\xb5\x07\xf3\x2e\xc7\x22\x84\x0e\xc9\xa3\x3e\x17\x75\xeb\x44\x35\x90\x97\x93\x27\x85\x44\x50\x7f\x84\xab\xbe\x5c\xd9\xfb\xf1\x86\x28\x00\x18\x71\x7a\x38\xef\x71\x04\xf1\x15\x32\x90\x1e\xd8\xd1\x2b\xf2\x83\x90\x32\xe8\x8b\x62\xfe\xad\xbb\xd5\x3f\xbe\x19\xd5\xae\x4a\x47\xff\x03\x35\x8e\xfc\xb1\xff\x8d\x82\x79\x00\xd5\xf5\x9b\x54\x51\x16\xf5\x94\x91\x93\xe6\xaa\xc9\x2f\xc6\x56\x24\xea\xe8\x4a\xe0\x5d\x1f\xb0\x3f\xce\x6d\xc9\xf2\x08\xef\xf9\xf1\xec\x4b\x7a\x9e\x0d\xa2\x1b\x65\x40\xb9\xee\xa4\x97\xb2\xee\x22\x7a\xa1\xa3\x4c\xf7\x5c\x57\xae\x66\x6d\x8b\x81\x96\x78\xf2\x5f\xf3\xb4\x36\x93\xe7\xd1\x4c\x51\x50\xf6\xb2\x7c\x79\xf1\x97\xc6\x20\x56\xae\x7e\x4f\xca\x3c\x37\x68\xca\xea\x4a\x28\xcd\x0f\x4e\xa2\x01\xe1\xe1\x63\xf7\x74\x98\x31\xb0\xfd\x37\xef\x37\x65\x55\x95\xbf\xe6\xd2\xf9\x02\x85\xcd\x53\xff\x75\x28\x9b\xda\xbb\x3f\xee\x98\x89\x34\x05\x74\xb5\xe3\xa7\x5f\x76\xb9\x8b\xe4\xdf\x63\x15\xa9\xf1\x1d\x19\x91\x51\xe5\xdc\xcd\x23\x7a\xf5\xd0\xcd\x6a\x63\x2c\x93\xb9\xca\x2b\x72\x92\x5a\x7b\x04\x9e\xec\x0a\x20\x08\x14\x09\x5f\x93\x42\xdb\x6f\xa5\x9c\x87\xa5\x41\x10\xdb\xb7\xef\xd1\xdd\x7a\x18\x25\x4f\xcb\x3e\x10\xa2\x4c\xfa\x6f\xb5\xd0\x7f\x9e\x75\xae\xfa\x1e\x1e\x80\x28\x06\x16\x8d\xd2\xf5\x37\xf7\x0f\x0f\xf3\xc6\x19\x62\xc1\xa8\x5d\xfa\xcb\x6a\xfd\xcf\xe0\x6e\xe3\x9b\x89\x75\x64\xc9\x0e\xfd\xad\xdb\x0f\x73\x33\xc1\x5d\x43\x92\x64\x9e\xaf\x8f\x14\x27\x67\x89\x2b\x00\x12\x16\xd2\x36\x65\x33\x09\x5e\x7e\x7c\x8d\xa7\xf3\x8c\xa8\x30\xf7\x27\x29\x0e\xae\xc5\x73\x5b\x3e\xc2\x3c\xed\x09\x00\x93\x82\xbe\xe4\x43\xf9\xfa\x82\x55\x5d\x16\x4f\x78\xcd\xde\x30\x3e\x25\x0d\xd1\xab\x0d\xfa\xc4\x5c\xeb\x2e\x8e\xd4\xa0\x00\xd2\xd8\x9a\x9a\x76\x49\x3e\x42\x51\x6f\x7e\xe5\x03\xdf\x74\x3e\x7f\x01\x69\xeb\x92\x79\x3f\xbc\xa7\xa9\xe8\xae\x29\x6d\x76\xbf\x22\x91\xa0\xbb\x1c\x9c\x6e\xa7\xba\xac\x09\x70\x33\x99\x41\xa9\x32\x14\x9a\x9d\xc6\xcc\x97\xe3\x41\x59\x64\x01\x67\x87\xbc\x78\xdb\x42\xfd\x66\xc5\x62\xe6\xf7\x76\xc8\x32\x9b\x5f\x39\xd9\xcc\xdb\x78\x0f\x72\x63\x78\x1c\x46\x16\x58\xd7\xad\xe8\xbf\x99\x2e\x3c\x8d\xb9\x7b\xa1\x8f\x79\xf1\x84\xef\xcd\x0d\x8e\xe8\x33\x01\x38\x58\xda\x3d\x37\x05\x46\xa2\x54\xd3\x22\x2a\x70\x8c\x08\xb7\x6c\x2a\xc4\xbf\xbc\xb2\x18\x45\x9b\xf3\x6f\x5d\x24\x40\xa9\x77\x87\xc1\xb6\xe2\x9a\xdf\xcb\x06\x89\x80\xc6\x66\x61\x5a\x87\xa2\xe7\xa3\x04\x10\x19\x50\xaa\x0e\x5e\x2b\xc4\x27\x7c\x9d\x23\x51\x6c\x47\x21\xb9\x01\x37\x37\xcb\x97\x2a\x3f\xe2\xea\xbd\x3f\xdf\x32\x4b\xd3\x76\x59\x11\xcb\x61\xbf\x79\x8d\x5f\x0f\x44\x8c\xd2\xdb\xd6\x7a\x2f\xe1\x74\x1a\x10\xd4\xdc\x1f\x4f\x87\xbf\x5b\x95\x93\x9b\x02\x15\xd2\x94\x77\x32\x8d\xc4\x26\x7a\xfa\xb6\xf1\xbe\x0b\xc8\x90\x47\x0e\x1d\xd2\xe0\xaa\xd0\xb7\x83\xc7\x96\x11\xa3\x7e\xb7\xbc\x5e\xa3\xc6\xa2\xb4\x0c\x02\xba\x3b\x9c\xd8\x9d\xe4\x58\x36\xdd\xdf\x14\x07\x8a\xb4\xee\x97\xcf\xb6\xed\x7d\xd0\xbd\x0b\xa0\x83\x84\x12\x0f\xa0\xb5\x23\x47\x1e\x54\x89\xe6\xef\x5f\xb3\x80\xb2\x1f\xe7\x1a\x2b\x82\x92\xcc\x74\x24\x02\xe8\x4c\x59\xd1\x5c\x1f\xa9\xbe\x3c\x2e\xc8\x4f\xce\x61\x3e\x5b\x05\x98\x58\xb9\xe0\x53\xd9\x40\x53\x5a\xae\xa9\x61\x23\x00\x20\x4f\x28\xde\xd3\xe5\x4b\x85\xfd\x6d\x76\xcb\x13\x55\x24\x6d\x77\x6a\xeb\xd3\xbe\x92\xe1\x3f\xe4\x75\x33\x61\xfa\x05\x19\x84\x01\x39\x55\x7f\x96\x79\xe1\x49\x41\x66\x9f\x55\x06\x91\xc5\x10\x58\x3a\x25\x97\x10\x71\xac\x52\x20\x03\x4c\x32\xaf\x00\xb3\x2f\xab\x2e\x77\x30\x90\x1e\x03\x19\x26\x96\xf0\xb8\xbd\xeb\xf2\xfd\xe2\x96\xc3\x50\xad\x7a\xd6\x30\xc8\x10\x6c\x78\xfa\xdb\xb9\x78\x3d\xe0\x46\x55\x14\x5b\xfb\x83\x52\xb3\x2e\xb3\x62\x55\x84\xfc\xa1\xc8\x58\x8d\xbb\x0a\x41\xef\xce\x69\xb2\x03\x6a\xf5\x75\x47\xe3\xc0\x16\x20\x64\x29\x1f\xe1\x0d\xeb\x55\xb3\xf7\x19\x87\x69\xa6\xd9\xcb\x40\x9f\x89\xe0\xd4\x9f\x1f\x42\x4a\x55\xe0\x0a\x7e\xb9\xee\xb4\xb9\x8f\x29\x63\x16\x07\x91\xc7\x1b\x97\xe6\xeb\xf9\x08\x45\xc7\x76\x07\x32\x06\x9b\x44\x75\xa1\xbb\x55\xc9\x1a\x04\x74\x32\xd6\xa8\x7b\x3d\x3e\x4f\x2b\x36\x17\x42\xca\xd8\x48\xaa\x5e\xde\x7c\x71\xbc\x0e\xfe\x1a\x49\xc6\xac\x9c\x51\x5e\xd5\xcd\x2d\x5c\x96\x9e\x11\x09\x64\x62\x42\xdf\xe3\x4d\x75\xda\x59\x73\x2b\x59\x20\x48\x4f\x6a\x47\x7a\x9e\x76\x1a\x2f\x2c\x06\x70\x72\x0f\x8c\x6b\x6a\xfa\x20\x27\xdb\x62\x26\xbe\xc2\xcf\x9f\x58\xd4\xbb\x43\x7e\xcc\x1b\xd4\x9b\xb3\x07\x5d\x4a\x26\x18\xa5\x65\xa9\x0c\x78\xbf\x7c\x26\xce\xab\xb4\x3b\xaa\x03\xea\xdf\x5e\xae\x9f\x7f\xdc\x6e\x16\x0f\xab\xdd\xe3\xe2\x8f\xdd\x62\xe9\x55\x0c\x41\xa6\x3c\xa0\x14\xb5\x82\x6a\x0b\xef\xf9\x84\x2c\x0b\x64\x8a\x92\x5a\x25\xb6\x20\xa5\x77\xa3\x65\x96\x06\x84\xd8\x9c\x2d\x8a\xcc\x15\xf1\x65\x66\x6c\x3f\xb2\x2e\xc9\xc6\x8c\xb2\xe0\x92\x87\x51\xe2\xfa\xee\x47\xcc\x45\x33\x60\x1d\xc9\x23\xdb\xa3\x4f\x1e\x3c\xc8\x83\x03\xe1\x76\x97\x12\x51\x42\x0c\x8a\x8b\x21\xd5\xbd\x3f\x2a\xa2\x80\xac\xa1\xa9\xca\xbf\xf0\x43\x4e\xd7\x99\x02\x88\x14\x5c\x92\x88\xd0\x6d\x05\xaf\x65\xe1\xdc\xe7\xae\xb1\x77\xf2\x01\x85\x94\xd1\x80\x1c\xb7\xe7\x59\x73\xc7\x01\xc0\x4a\x2a\x15\xb9\x2a\x2b\x4b\xbc\x35\xce\x8f\x4a\x50\x8a\xe2\x17\x12\x86\xdb\x6c\x17\xeb\xed\x4e\xf8\x63\x32\xce\x74\xdf\x2c\xf0\x65\x00\x9c\x70\x03\x54\x1c\xc7\x7d\x6e\xe6\xf3\xbc\xa2\x54\x2c\x22\xd4\x6e\x3b\x3b\xa2\xdd\xba\x47\xd9\x48\xa5\x92\x70\xc0\x9f\x0d\xf5\x34\xb7\x31\x81\x67\xa5\xc9\x3f\xf8\xc7\x5d\x5b\x67\x59\xc4\x3b\xfc\x65\xeb\xab\xd8\x9d\x64\x6c\xb6\x50\x83\x8c\x3a\xbc\xc1\x76\x8f\xc3\x9c\x81\x34\x60\xc8\xa8\xed\x7b\x01\xd8\xb8\x3b\xa6\x18\x59\x65\x97\xc6\xba\x45\x79\xc5\x16\x6e\x47\xaa\x20\x91\x04\x98\xb7\x23\x1f\xbf\x6d\x96\xf3\xe6\x5b\x05\x8e\x44\x48\x97\xdb\xfc\x88\xe5\xb9\xb9\x2b\x2b\x92\xaa\x81\xbc\x80\x09\x33\x0f\xa8\x30\x11\x71\x97\x20\x0e\x5c\x57\xf2\xf3\x09\x8b\x9e\x81\x71\x47\xc7\x8e\xd8\xec\xcb\xee\xa1\x54\xa8\x80\x6a\xca\x24\x67\x6a\x23\x92\x99\x96\x0f\x15\x05\x99\x15\x54\xb6\x36\xa2\xae\x47\x2b\x4a\x45\x2c\x8a\x5d\x5d\x2a\x3f\x7a\x35\x89\xee\x60\x8a\x84\x33\xd5\xf8\xf3\x8c\x87\x9f\xb8\x2d\x35\xd4\xab\x42\x9d\xb1\x6e\xa0\x1b\x15\x87\xe8\x55\x9d\x09\x04\xd6\x86\x9a\x6d\xd8\x3e\xe1\x01\x04\x15\xa7\x96\x67\xad\x46\x92\x33\xf9\x58\x9a\x09\x54\xcc\x63\xa6\xbb\x08\xdf\xaf\xbf\x5e\x45\x71\xce\xa1\xfe\xa0\xbe\xaa\x92\x24\xe0\x2e\x40\xff\x0a\x95\x5e\xc2\xc9\xcb\x09\x8f\xdf\x54\xc2\x03\x82\xe1\xd6\x87\x61\x04\x7f\x15\xbf\xfb\xd1\x42\x52\x26\x6b\xf9\xbc\x5e\xed\xb6\xab\xc5\xa3\x63\xa4\xf6\x6f\x85\xa9\x84\xf8\x7b\x9e\xcf\xd3\x0f\xce\x50\x51\x4e\xfc\x5b\xdd\x9b\x85\x99\x45\x32\x92\x5f\x00\xc5\x0c\xb7\x14\xd4\x8e\x86\xa6\xb3\x15\xfd\x85\xb3\x28\x23\xe6\x89\xe6\xad\xfb\xbc\x59\x06\xda\x3a\x27\x76\x7b\x18\xe0\xcb\x55\x06\xb6\xff\xf5\xdb\xf6\xe6\xef\x74\xba\x40\x65\x52\x18\xdb\x05\x0e\x94\x87\xf6\x17\xe1\x81\xc5\xd7\x3a\xfc\xe4\x38\x93\xa7\x78\x22\xa8\x80\x71\xc8\x1d\x0d\x73\x3d\xec\x2d\x07\x62\xde\x4b\x7d\xb8\xd6\x63\x33\xe7\x97\x95\x48\x22\x70\x78\x8b\x7b\x8d\x45\x43\xe4\x63\x5e\x1b\xe2\x83\x53\x50\x04\xc6\x79\x25\x0f\xb9\xaf\x8d\x2a\x48\x43\xe6\x30\xdd\xc3\xca\x08\xff\xdf\xc4\xcf\x3f\x19\x30\x72\xf4\x9b\xf2\xf5\xd5\x26\x58\xfc\xb9\x32\xcd\x78\x36\x48\x8f\xbc\x0e\x1b\xef\x3f\x4d\x89\x28\x09\x91\x15\x8d\x83\xe2\xf9\x27\x56\x55\xae\xaf\x27\xf2\xfc\x73\x48\xcd\x29\x23\x4e\xbe\x9c\xe3\xc7\x9d\x2c\x2e\x85\x71\xea\x42\x8b\x55\xa1\xcb\x5f\xad\x73\x35\x2e\xae\x2b\x74\x19\x46\x4a\x41\xdc\x94\xed\x5a\xb0\x7d\x0e\xd7\xdb\x98\x42\x1e\x13\x8f\x94\x23\xb1\x75\xc5\x1e\x7f\x10\x63\x2f\xb0\x7b\x77\x6e\xd7\x23\x2d\xd0\x51\x24\xac\x4c\x90\x52\x1b\xd5\x4f\xcb\x94\x87\xf3\x51\xbe\x32\x8e\xd3\x81\x90\x31\x3b\x0d\x0d\x4c\xa6\x90\x89\x53\xca\x19\x99\x01\xe6\x61\xfe\xf5\x1a\x34\x88\x2e\xd7\xf1\x52\x95\xa6\x47\xa9\xe8\x90\x33\xa2\xd9\xa0\x3e\x6f\xac\x6a\x8b\x37\x1f\x59\x42\x1d\x45\x48\x90\x35\x05\x45\x59\xe4\x7f\xa1\x7e\x79\x58\xae\xfd\xc1\x98\xd9\x10\xbd\xa0\xe9\xeb\xeb\xba\x2e\x1a\xe8\x22\x21\xcd\x58\x20\x95\xb3\xe5\x0b\x59\x3f\xc2\x7b\x7f\x04\x80\x75\x22\x05\x94\x3e\x52\x7b\x3c\x1c\xf2\xe2\x75\xc6\x6a\x6b\xa6\x20\xeb\xb3\x81\x7f\x3c\x3e\xfc\x87\xfa\xee\xfe\x35\x84\xaa\x8f\x1f\x5f\xa7\x89\x26\xfc\x8f\xcd\xac\xbf\xe4\x13\x66\x2f\xd0\xa9\x84\x24\xf3\x7d\x86\xd5\xa0\x6c\xa5\xb3\x20\x54\x6e\xf7\xdc\x76\x9c\x3e\xa0\xb3\x24\xa3\x86\x81\x36\x86\x9b\x00\xf0\x74\xa6\x02\x4f\xa2\xf6\xad\xc6\xca\x31\xea\x74\x57\xe4\x51\x98\x0c\x12\xc8\xd3\xe6\x4a\xcd\xb3\xd0\x02\x17\x5a\x2f\xf2\x47\xde\xec\xbf\x4d\xc1\x17\xf3\x2b\x41\x73\x1e\x50\xc7\x29\xf5\x49\x59\x4c\xd4\x95\xa7\x71\x85\xb1\xd7\x82\x09\xba\x9d\x5f\x47\xd7\xfa\xe5\x61\x3e\x5d\xdb\x8e\x16\x0a\xc2\x60\xce\x15\xfb\xe0\x75\x43\x60\x98\xc3\x1c\x6c\xdf\xa6\x1c\x16\xb3\x8e\xbd\x86\x4c\x62\x8f\x8d\xf9\xee\xe8\x13\x27\x5f\x09\x34\xf0\x6c\x54\x94\xad\xbf\xe2\x61\xfa\xfe\x24\xe3\xa1\x6f\x47\xb2\x82\xa9\xeb\xfb\x9b\x09\x19\x0e\x68\x99\x6a\x92\xc1\x3d\x17\x36\x29\xf2\xc1\x7d\xa9\x20\x22\x26\x64\xc7\x31\xdc\xa1\x88\x17\x5a\xe7\x43\xba\xe8\x6e\xb8\xf2\xfb\xfd\x42\xdb\xfc\x24\x81\x6d\xb0\xe9\x5b\x12\xb4\x92\x56\xb0\x90\xcc\x51\x53\x5d\xc6\xb4\xc7\xa3\x82\x97\x56\x26\xc9\x2c\x38\x39\x7f\xcb\xdf\x74\xae\x3b\x6b\xab\xb5\x62\x49\xe0\x0b\x75\xc3\x30\x4b\x6b\x57\x70\xb2\xd5\x8e\x36\xc6\xbf\x3d\x37\x6a\xef\x73\xd4\x6e\x14\xc6\x86\x46\x3d\xa1\x6a\xa0\x5a\xee\xf3\x02\xba\x43\x99\xf2\x15\xfe\xc7\xcb\x72\x8f\x13\x7d\x00\xd0\x28\x54\x0c\x5d\x9d\xec\x05\xea\x7a\x1e\xb1\xad\x4d\x24\xa2\x9e\x8c\xe4\xf7\xbc\x69\x5a\xe7\x2d\x2f\xea\x35\x1e\x6d\x53\xdb\xb6\xbc\x6d\xa3\x37\x3f\x1e\x8c\xee\xc7\xdb\xb4\x6c\xaf\x14\xf9\x99\xda\x11\x60\x18\x6a\x72\x8c\xca\x11\x9f\xcf\x07\xa9\x9f\xe9\xb9\x99\x08\x32\x8f\x7c\xae\xeb\xe5\x75\xda\x1c\xa3\x58\x43\xe4\x98\xa7\x76\x14\x39\xed\x10\xaa\xf6\x11\xea\xab\x91\xc6\xab\x97\x77\x72\x19\x83\x02\x0a\x46\x59\x00\x94\x4c\x1e\x7e\x35\x8c\xb8\xc5\xfc\x5a\x3d\x9b\xc5\xeb\xc4\x8f\xc7\x24\x45\x42\x6c\x5a\xad\x82\x5b\x38\x9d\x6e\xca\xf2\x6d\x36\xcd\x86\x89\x0a\xa8\xde\xf5\x33\xc7\x5f\xa7\x01\x1a\x10\x99\xb0\x2a\x72\x7b\x1b\x0b\x7b\xde\x08\x72\x4b\x8f\xf9\x14\xf6\x8b\x4c\x46\x24\x07\x8f\x65\xfd\x92\xff\xf5\x17\x6c\x5a\xff\x6f\x03\xa6\xbf\x9e\xb6\x93\xc8\x5a\xd6\x35\x9a\xd1\x2a\xc3\x34\x8c\xbd\x06\xf3\x23\xbc\xdf\x9c\xeb\xbc\xa0\x2e\xbd\x17\xac\x96\x79\x73\x99\xfc\x5a\x1a\x0b\xf2\x46\x7f\x40\x05\x03\x2c\x0c\x66\x60\x95\x4b\x2a\xfc\x59\xbe\xe1\x15\x5b\x09\xf2\x30\xb1\x45\x2c\x8a\xe5\x4a\x63\x3a\x3b\x8d\x3c\xd2\x86\xba\xf0\xab\xbc\xc6\x1f\x50\x55\x79\x79\xdd\x1d\x37\xbe\x0b\x0e\x96\x6f\xc8\x4e\xc1\xd6\x44\x7b\xe0\x5f\xbb\xc1\x8c\xff\xc7\x9f\xa2\x01\xdd\x7a\xa1\x1d\xab\xf5\x9c\x5e\xa6\x98\x12\x14\x2a\xf1\xa2\x1a\x0f\x79\x81\xb7\xd0\x40\x34\x19\x02\x4c\x10\x90\xfd\xd0\x28\xff\x04\x20\x22\x52\x9d\x7b\xc8\x8b\xd7\xff\x8c\x48\xe5\xdb\x63\x22\x60\x24\xa4\xdb\x54\xe7\xba\xf9\x9c\x86\x61\xfc\x4b\x32\x61\x54\x4c\xd9\x12\xb4\x62\x74\x55\xa9\x43\x25\x5d\x4a\xd3\x9c\x0b\x4b\x57\x36\x7e\xe3\xd2\x44\x61\xdf\x21\x48\x62\x84\x33\x3d\xd6\x28\x8d\x0e\xfb\xad\xfa\x2e\x3f\xe0\x10\x07\x8b\x2a\xb4\xbd\xae\x0a\x8a\x6f\x45\xbd\xc7\xc3\x64\xf6\xa8\x28\xb2\x9c\xce\xbe\xc4\x33\x49\x0d\xfa\x61\x2c\xa3\xf7\xfa\x84\x63\xdd\xfd\x0f\x96\xba\x4a\x23\xdf\x70\xf2\xed\x7e\x4a\xd1\x81\x3a\xce\xa8\x00\x76\x84\xe2\x6c\xfb\xa2\x5b\xc7\x8a\x90\xdf\xde\xe6\xc3\xe1\xb9\xe8\x72\xa0\xa8\x13\x43\xb1\x66\x0d\x06\x9b\x8b\xe5\xb5\x19\xff\x20\x86\x92\x1c\x24\x97\xa8\xba\xc1\xd7\x57\xa8\xea\x65\x79\x3c\x9e\x07\x19\x38\x44\x91\x10\x52\xcf\xc6\xb2\x61\xf7\x67\x14\x84\x84\xcb\x0b\x75\x97\xbf\xee\x5b\xf3\x34\xb5\x0c\x26\x4a\x3a\xef\xe5\x8a\x0d\x1a\xd0\x24\x49\xa6\x7a\xa5\x2d\xda\xbf\x47\xc1\x2c\x9a\x4c\x23\xc5\x1a\x3f\xa1\x81\x6e\xed\x18\xcd\x45\xbb\x76\xee\xda\x0d\xb2\x87\x75\x9a\x20\xb5\x50\x0b\x2f\x9a\x8c\xbf\xe6\x42\x5a\x13\x68\x2b\x68\x4e\x4d\xf4\x84\x3d\xbc\x42\x3e\xf8\x98\xd6\x04\x18\x52\xb3\xfc\xe3\xe5\x47\x7e\x38\x8c\xab\x6b\x1f\x62\x6b\xfd\xb9\x26\x60\x71\xef\x8e\x3f\x96\x3f\xf1\x9a\x21\x0d\x4c\x18\xc5\xc4\x26\x44\x44\x9a\x83\xc2\x85\x09\x93\x34\x70\x28\xd5\x0d\x36\x1d\xa9\xe0\x50\xfb\x02\x4c\xa8\x0c\xb1\xf6\x38\x21\xf6\xda\xe6\x3d\xfd\x47\x32\x11\x4b\x09\x0c\xf2\xf5\xfc\xfa\x08\xcd\xbe\x3c\x77\x07\x0c\x8f\x3a\x76\x93\x73\xd1\x60\xe5\x5b\xfa\xfc\xcb\x37\x5e\x2d\xc6\x16\x73\xe7\xf7\x36\x13\x6b\x46\xdd\x02\xcb\x1f\x4b\xf3\x01\xd6\x7d\xe8\xd5\x99\x18\x85\xce\xfc\xd3\x3e\x3c\x6f\xfd\x8f\x25\x81\xcc\x32\xaf\xe1\xf1\x52\xa1\x4f\x76\x76\xc7\x95\x16\x83\x9e\xc0\x71\x42\xcd\x30\x93\x49\x98\x10\xd2\x11\x51\x4e\xff\x9a\xd3\x38\x8e\x1d\xbb\xe2\x97\xf2\xa0\xdb\x6d\x6f\x83\x55\x0e\x13\x40\x92\xc9\x62\xe3\x5b\x60\x1f\x6d\x7e\x65\x48\xe9\x75\x95\x61\x32\x59\x66\x28\x57\x33\x71\xb6\x0d\x8f\x80\x5e\x8c\x07\xce\x77\x7f\x4f\x03\x22\x0d\xf8\xfe\xb2\x1a\xe5\xa0\x0d\x77\xb2\x01\xad\xe9\x7a\x3c\x7b\x58\x87\x11\x2c\x20\x1f\xf7\x81\x00\x8f\x93\x1d\xdd\x08\x93\x72\x4f\xa9\xfa\xee\x7c\xcf\xc7\xe5\x8f\xb1\xed\x30\xc2\x08\xf2\xdc\xb7\x7b\xdc\xa8\xfd\x11\xd5\x5b\x97\x02\x36\xc0\x82\xd8\xd6\x89\x9c\x9c\xce\xb4\x06\x62\x80\x49\xaa\x24\x1d\x73\x5b\x10\xf2\x45\x0d\x23\x93\x80\xbc\xb1\x17\x2c\x5a\x0f\xbc\x7b\x74\xc9\x92\x40\x0d\x9a\x45\x47\xda\x17\xa3\x14\x85\x91\x46\x27\xee\xfe\x2d\xe5\xd7\x0d\x34\xcd\x01\x5f\xca\x37\x3c\x96\x45\xf7\x4b\x2a\x14\x81\x4b\xd0\xfe\x22\xca\xad\xee\x40\xc4\x02\x8f\xe6\x82\xe9\x8d\xab\xcc\x76\xf0\xe5\x75\x7d\xc6\xbb\xea\xba\x53\xfe\x43\x98\xc7\xf8\x3a\x3a\xb3\xcc\x58\x43\xb9\xbe\x5e\xc6\xda\x0f\x52\x01\xe5\x7a\x76\x82\x22\xe2\xcd\xb1\x7d\x9b\xfe\x20\x86\x36\x20\xfe\x42\xdb\x92\xc9\x27\xc2\xbf\x60\x90\x59\x7e\x32\x1f\x1a\xb4\xbb\xc9\x2c\x15\x80\x41\x19\x12\xc3\xc0\xe6\xbf\x55\xf7\xc2\x51\x01\x40\x97\x49\x5d\x54\xd4\x8b\x54\x7b\xb6\x24\x37\xc8\x24\x8c\x50\xc1\x0e\x77\xe0\x04\x49\xab\xf2\x68\x09\x5e\xaf\x2c\xe0\x07\x56\xcd\x30\x41\x24\x6e\xed\xf8\x25\x74\xfd\x99\x93\xbb\x34\x19\xb2\xa4\x93\x4c\x9b\x36\x48\x8c\x67\xa7\x51\x52\x06\x9d\x97\x44\x8e\x34\x92\x4c\xfb\xcd\x65\xee\x15\xc8\x20\xc8\x52\x32\x4c\x8e\xa1\x66\xdb\xba\x5f\xc5\x6f\x70\x44\x5f\x6f\x93\x41\xc0\xb9\x71\xb8\xeb\x97\x43\xd9\xb4\x2e\xcd\x07\x2d\x44\xd7\x89\x33\x19\x84\x92\x51\x5a\xa1\x41\x38\xae\x8e\xe0\x7b\x42\x65\x10\x62\xe4\x61\xca\x17\xac\x9b\x52\xc3\xe5\xd5\xc3\x92\x64\x10\xc9\x2c\x12\x1e\x24\xa1\xde\xbe\x39\x4d\x97\xd1\xa7\x96\x41\xa2\xa4\x1c\xe0\xe2\x77\x75\x5f\x02\x94\x41\x82\x8c\x94\x39\xb4\x65\xeb\x68\x2f\xf3\x41\x31\x5c\x06\x2c\x40\xcb\x0d\x55\xdf\x17\x5f\x3a\xd4\x8a\x0c\x58\xac\x02\x0b\x35\x7a\x77\x7e\x49\x38\x30\x34\x32\x60\x89\x71\x52\x75\x90\x17\xa4\x4e\xdb\x0b\xbc\xc9\x20\x0d\x58\xdc\x6b\x8f\x7c\xa2\xd0\xec\xc7\x27\x56\xee\xf1\xa1\x7c\x5d\xee\xf3\x0f\x0b\xa4\x32\x48\x33\xa5\x3c\xb7\xb6\x4d\xc7\x2f\xcb\xba\x79\xec\xd0\x74\x32\x48\x8d\x22\x54\xd6\xd7\xc5\xe6\xeb\xcb\x6a\xdd\xd1\x2d\xc9\x20\x8b\xb3\xd0\x45\xa6\x8b\xa6\x01\xf5\xb6\x86\xe2\xad\xdb\xf9\x65\x90\xf1\xd8\x13\x3e\x2c\xe1\xb4\x46\x75\x9d\x0a\x9e\xf0\x6e\xc8\x20\xd3\xb6\xd0\xb2\x7b\xb5\x6c\x04\xc4\x4a\xe0\x2f\x28\x80\x91\x95\xa6\x06\xcf\x41\x10\x49\xff\x3a\xef\x40\x06\x10\x73\xca\x3e\xe3\x11\xab\x57\x2c\xd4\x65\xca\xa3\x22\x03\x48\x15\x11\x4a\xac\xa0\xbe\x3c\xe6\x05\xde\xab\x72\x32\x9b\x41\x67\x3e\x79\x40\x1e\x50\xbb\xd7\xfb\x55\x2b\x03\x19\x58\xed\xe4\x5e\x83\xd3\x24\xdd\xb1\x4c\x51\x0d\xff\x04\x17\x0d\x97\xc9\x34\x53\xa1\x95\x65\xbe\xc5\xd3\xa1\xa4\x7d\xa1\x8f\xf4\x64\xa0\x8c\x22\xd7\xf4\xf7\xd6\xab\x19\xed\x5c\x32\xd0\x09\xd2\x8e\x76\xcc\xdb\xf7\xd2\x3d\x89\xee\x19\x47\xb7\x50\xbc\xad\x6c\x88\x39\x24\xba\x94\x81\xe6\x91\x0b\xbf\x4d\x7b\xea\x5d\xdf\x69\xf0\x08\xa7\xc9\x73\x6b\xd0\x44\xb8\x23\x95\x56\x8f\x0e\x35\xea\x7f\x0b\x43\x88\x4c\x2f\xd0\xf4\x78\x19\xba\x85\x32\x40\x66\x51\x4b\xe7\xa2\x75\xe1\x56\xef\x13\xb6\x7d\x3f\x2a\xb3\x54\x2d\x6b\x6c\xf2\x0a\xaf\x74\x66\x64\x80\x5c\x72\xcb\xfa\x77\xcc\x8b\xdd\xa1\x63\x18\x90\x01\x2a\xdb\x11\xf2\xf8\xb4\x1c\x2d\x1d\x34\x09\x24\x1d\xe1\x37\x56\x56\xf6\xb2\x3f\x2a\xc9\x61\x7b\xb4\x79\xae\x0f\x2b\x90\x43\xf3\x27\x03\xa3\x84\xf2\xdc\xfa\xbf\x86\xe8\xfc\xd1\xeb\x0a\x03\x16\x99\xce\x61\xcb\x8b\x9b\xcb\xe6\x50\x36\xae\x3f\xdb\x15\xde\x64\x18\xc8\x8c\x9a\x2f\x1d\x8f\x1f\x21\x50\xc6\x90\x53\x19\x06\x3a\xa0\x6c\x84\x2e\x8b\xb2\xb9\xfd\xfd\xf7\x36\x60\x1f\x3e\x64\x18\xc6\x09\x05\x47\xc7\xf3\x61\xec\xe7\x76\xc7\x39\x6d\xc6\xab\xf7\xf6\xb4\x1b\x7f\x5a\x14\x26\x9e\xa7\xec\x6f\x51\x68\xfe\x14\xc1\xa8\xd4\xf0\xf0\x74\x3b\xba\x83\xc8\x84\x72\x4a\x9f\xf1\xff\x72\x76\x65\xdd\x89\x23\x59\xfa\xef\xd4\xc3\x3c\x28\x42\xa1\xed\x11\x30\x76\xd2\xe9\x85\x36\x64\x65\x55\xf7\xe9\xc3\x89\xe5\x06\x56\x25\x48\xb4\x24\x6c\x53\xbf\x7e\x8e\x6e\x2c\x5a\x10\x59\x35\x33\x0f\x95\xd3\x56\x20\x90\x14\x8a\xb8\xcb\xb7\xb8\x59\xba\x52\xd3\xd4\x1c\x41\xc2\x28\xc5\x9d\x11\x1b\x6f\x82\xd7\xb9\x6c\x5f\xc7\xed\x47\x39\x43\xb5\xee\x99\x6e\xa0\x42\x51\x7f\xf7\x35\x4c\x1b\x27\xfa\xbc\x5e\xf3\x73\x3d\x8a\x7b\x04\x89\x88\xc6\x5f\xa7\x73\xdd\x5c\x76\xf8\x5f\xf7\xc9\x88\x19\x6d\x9b\x87\xd9\xf3\xcc\xff\x8d\x6b\x0b\xb8\x79\x39\xbf\xe7\xaa\xac\x72\xbe\xe0\x8a\xd7\x4d\xc5\x15\x1f\x9d\x3a\x06\x21\xcc\xd2\x8d\x14\xf5\xe1\xc1\x84\x69\x94\xc2\xc3\x19\xd6\x86\x41\x66\x22\x95\xd5\xf1\x66\x0a\x3d\x55\x23\x14\x24\x11\x04\x45\x3b\xca\xe2\x71\xf9\xdb\x89\x8f\xde\x73\x92\x06\x51\x2c\xfa\xb6\x37\xde\xa6\xcc\x0e\xc8\xa2\xc8\xd9\x1b\x3c\x5d\x16\x50\x74\xcb\x12\xc9\x22\x99\xc6\x3d\xb0\xfd\x70\x8e\xbb\xe9\x98\xc5\x8a\xdb\x65\xdb\xdf\x93\xe7\x72\xd4\xd1\x16\x24\xe3\x29\xae\xde\xa7\xaa\xac\xeb\xef\x79\xf1\x52\x3d\x96\xf5\xb0\xe2\x23\x08\x4f\x12\xdb\xb4\x2a\x1a\xe7\x58\x68\x38\x92\xbd\x28\x47\x10\xce\x33\x44\xf6\xc0\x79\x3f\x98\x52\x22\x52\x5e\xc0\xc4\xfd\xe6\x29\x0c\xab\x20\x22\x0b\x11\x09\xa6\xbd\x47\xd9\xa2\xac\x8f\x65\xbd\xe9\x9c\x34\x05\x91\x24\x36\x70\xe8\x0a\x4e\xbc\xb2\xf6\xd3\x83\xf7\x9a\xc8\x34\xc3\xb5\xf0\xdb\x7c\xe1\x3e\xa5\x02\xe5\xb6\x31\xfc\xd1\x86\xbf\x57\x56\x97\xeb\xb2\x9e\x20\x8a\xcb\xd8\x43\x86\x78\x05\x3d\xf2\x6c\x7b\x50\x21\x9a\x1a\xad\xc2\x77\xeb\xd7\x25\xc2\x3f\xbe\x2f\x97\x5f\x5d\x08\x44\x80\xa7\xb8\xf3\xd4\x28\xab\xd0\x6b\xc7\xfa\x01\x92\x87\x69\xcf\xae\xef\x0e\xde\xdd\x0a\x4b\x34\x04\xd2\x89\xc0\x3d\x38\xdf\xdd\x71\x64\xdc\x0e\xd3\xc4\x52\x20\xd7\xbf\xae\x31\xca\x1a\x0c\xa0\x41\x0c\xca\xa9\xa4\x58\xeb\x91\x5f\xdc\xa1\x54\x63\x1f\x71\x7d\xe0\x97\xdf\xa8\xff\x6b\x16\x1b\xa1\x7c\x59\x81\x2c\xdf\xa1\x22\x83\xc7\x34\xdd\x2f\x16\x94\xf0\x14\x77\x84\xe7\xd5\xe3\xf2\x37\x77\x2e\x22\x38\xfa\xf7\x74\xc0\x32\xec\x30\x0d\x27\x16\x25\x60\x9c\xd2\x14\xc8\x81\x31\xd3\xe0\x8b\xec\x58\x6a\xdf\x88\x13\x54\x56\xb4\xb4\x9e\x0c\x6a\xdb\x91\x8a\x3a\xc5\x0a\x64\xce\x3e\xf1\x22\xd7\x50\x37\xf3\xcb\x40\x0c\x63\xf4\xa9\x54\x1b\x60\xc3\xe3\x60\xdf\xa1\x34\x4b\xe3\xcc\xd9\xde\xb6\x79\xe0\xac\x3a\xf6\xad\x67\x70\x84\x74\xc6\xb8\xe7\xa3\xb9\xd5\x2f\xfa\x2e\xaf\x4f\x67\x44\x48\xf0\x43\xbd\xae\xca\x35\x6f\x3a\xf3\x1c\x41\xa9\xd5\xf8\x3f\xf2\x4f\x84\xa5\xf6\x9b\x6b\x82\x86\x34\x33\x55\xb0\x37\x90\x3f\xfa\x5a\xf2\xc3\xfb\x17\x0a\x8d\x59\x20\x96\xfb\xad\x34\xbf\x3d\xc4\xb4\x31\x98\xe0\x4a\x3d\xf1\xe2\xb2\x2d\x3b\x28\x5e\xbf\x67\x7c\x85\x25\x10\x34\x0a\x18\xa2\xae\xfe\x28\xf3\x62\x67\xa1\x5f\xbb\xaa\x2c\x47\x2f\x19\x8d\x48\x88\xed\xae\xaf\xb3\xa2\xe6\x55\xde\x15\x67\x05\x8d\x24\x41\xe2\xf2\x8f\x8b\xb4\x6d\x1b\xc3\x72\x99\x9f\x6a\x3f\x04\x14\xe2\x08\x8d\x68\x55\x4f\x40\x41\xd0\x94\x81\x44\x2c\x24\xb2\xff\x50\xdc\xf3\xa7\x7b\x19\x4d\x33\x92\x49\xf7\xba\xe6\xa7\xed\xe5\x04\xa3\x1b\x95\x72\x85\x53\x5b\x15\x3c\x1e\x1d\xca\x02\x49\x94\x5d\x8a\xf3\xe2\x0c\xaf\xa0\x00\x8e\x63\x1b\x09\x41\x33\x4d\x91\x45\x80\xc6\x7d\x4e\x59\x5d\x50\x1e\x00\x6e\xfb\x88\xd8\x42\xff\xb1\xd1\x86\x30\x0e\x7e\x29\x0f\x13\x27\x90\xb3\xfd\x6c\xdf\x5b\xec\xf4\xdb\x46\xff\xd4\xcc\xe7\x9c\x71\x4f\x1a\x69\xe4\x5b\x1b\x4c\xb6\xcf\x30\x20\xee\x47\x88\x80\x60\x8b\xc9\xb2\xe3\xcc\x1a\x3d\x4e\x0f\x47\x3f\x43\x50\x23\x00\xc8\x95\x32\xde\xdd\xc3\xd5\x43\x84\x0c\x1b\x96\xd6\x37\x7c\xb6\x58\xbc\x7c\x7b\xde\xee\x9e\x66\xfe\x15\x97\x8c\x61\x93\xdd\x52\xd7\x5d\xed\xe7\x8a\xb1\x78\x8d\x3b\x17\x54\x4a\x85\xa1\xf5\x5b\x5e\x41\x65\xa0\xfd\x56\x59\xf9\x2f\xd5\xb7\xdc\x19\x94\xe2\xa1\xcf\x72\x4d\xe9\x6d\x50\x99\x12\x54\x59\x30\x87\x5f\x83\x76\x75\xbb\x98\xd7\x3b\x5e\xa8\x9d\xf9\xdc\xdf\x56\xa6\x1d\x7e\x39\x10\x10\xd6\x46\x76\x5d\x16\x7f\xe6\xee\x1b\x81\x66\x38\x11\xbf\x5c\x4e\x50\xc9\xde\x0b\x01\x61\x06\x41\x17\x54\x2f\x65\x59\x5f\xea\x06\x8e\xff\x78\x1a\xdd\x76\xc8\x38\xa2\xb2\x0d\x1d\x71\x03\x87\xc3\x6c\x0f\x45\xb3\xc9\x11\x3b\x31\x1e\x2c\x43\x6c\x92\x9b\x7c\xd1\xcb\xb5\xd9\x96\xde\x0d\xa6\xe9\xd5\xbf\xfd\xf4\x9b\xea\x88\xa0\xa2\x3e\xaf\x9a\xbc\x36\x10\x15\x77\x24\x4d\x90\x1a\x81\x5d\x2e\x0c\x12\xcc\x81\x30\x08\x0d\x7c\x1b\x78\xf3\xcd\xe0\xee\x46\xf1\x43\x18\x44\x06\x9d\x64\x66\xca\x3d\x97\x4d\x59\x59\x31\x24\x37\x82\x1b\xbf\x1c\x5c\xef\xb8\x13\xdf\x1c\xf7\x64\x7c\x49\x51\x84\x24\x30\xa7\xf4\xcc\xd1\x41\x30\x1e\xd2\x08\x70\x72\xcf\x94\xea\xb9\x0b\xcc\xf6\x3c\x2f\x6a\x63\xad\x9d\x17\xfb\x65\xd1\xe4\xd7\x32\x0f\x63\x00\x5e\xff\xf6\x84\x34\x0b\x70\x63\xbf\xdb\x20\xd9\xf2\x7a\x15\x1d\x4e\x94\x30\xa4\x46\xab\x22\x2f\xda\x67\x54\x83\xf7\x7a\xeb\x15\xe7\x26\x03\xc8\x90\x89\x2c\x8e\xdd\x27\x8f\x8e\x50\xed\x83\xad\x90\x69\x86\x18\x3d\xeb\x25\xe3\x34\xfa\x6e\x40\x12\x6f\xfd\x6b\x4f\x16\x85\x12\x69\xc4\xeb\x27\x17\x2f\x85\x91\xce\xa4\x61\x3d\xa2\xd7\x40\x9f\x04\x26\xc2\x98\xe9\xd0\x94\x31\x7e\xc0\x08\x8b\x21\xc2\x38\x0e\xb2\x0e\xa4\xf9\xe5\xee\x37\x39\x05\x65\x11\x61\xac\x81\xf7\xe3\xd8\x6d\xb9\x5a\xcc\xd6\x6d\xde\x80\xdc\x49\x28\x24\x32\x8d\x1e\xb8\x9f\x69\x09\x8d\xb0\xe7\x77\xea\xbd\xe5\x61\x92\x1a\x2f\x60\x17\x62\x97\x95\x85\x26\xfe\x55\xc4\xee\x3e\x9f\x05\x68\xd1\x80\x54\xf9\x1c\xaa\xd0\x9f\x18\x48\x14\xdc\x00\x7b\xda\x21\x69\x42\x51\x24\x1d\xdd\x56\x47\x5a\x79\x22\x4c\x53\x23\xbf\x2a\x1a\xf9\xca\x1b\xf0\xe8\x16\x11\xa6\x59\x8c\x0f\xf7\xdb\xe6\x6e\x51\x5d\x4e\x4d\xd9\x8f\x38\xc2\x34\x53\xc8\x33\x3f\x95\x1f\x50\x7d\x3b\x8d\x72\x87\x30\xe5\x29\x36\x66\xcc\xdb\xd4\x26\x58\xbd\xea\xea\xe0\x49\x70\x96\x22\x8c\x1c\xb1\x8c\x4e\x27\xc3\xb3\xb5\xc1\xdf\x42\x1e\x6b\x6c\xde\xdc\x95\xc7\x73\x3d\xf8\x29\x82\x84\xb1\x6f\xfa\x0f\x0a\x01\xa1\xa0\x01\x2e\xff\x8b\xc7\xe7\xdd\x7a\xf9\xba\xeb\x4a\x46\xa1\x60\x0c\x79\xbe\x79\x21\xa1\x68\x72\xe7\xa2\xd9\xdf\xe4\x43\xc1\x05\x22\x76\x9e\x61\x81\x36\x87\xb6\xf0\xea\x0f\x03\xc3\x5e\x05\xe2\x56\xf2\xea\x0e\x05\x5d\x07\xda\x10\x43\x3e\x8b\x08\x85\x0e\x12\xdf\x7e\xcc\xff\x04\xb3\xa1\xfa\x9f\xab\xc2\x14\x33\x2e\x37\xdb\x66\xc5\x65\xc1\xa1\x72\xd7\x3b\xb9\x47\x86\x8a\x09\x5c\xda\x36\x8b\x6f\x77\x2f\xfe\x4c\x4a\x68\xea\x92\x14\xbb\xd8\x2e\xca\x42\x1e\xce\x0a\xfc\x82\xa6\x80\xb8\x98\x70\xce\x8b\x1f\xcb\x66\x60\x10\x26\x42\xe0\x19\xe2\xff\x2d\x1f\x17\x7d\x80\x96\x9f\x27\x28\xea\xbf\x48\xdc\x43\xcd\x14\x35\x1a\xb1\x70\xc8\xe1\xbd\x5c\x57\xe5\xa9\xca\xa1\xe1\x55\x3e\xed\x69\x22\x58\x10\x31\xac\xa8\xb5\xaf\xd3\xe6\x54\x79\x74\x9e\x60\x41\x92\xa2\x99\x8b\x02\x59\x2a\x93\xe6\xdc\xc3\x38\xcc\x64\x01\x37\xbe\xce\xf2\xec\x45\x44\x04\x0b\x54\xa4\x94\x2f\x04\xad\x0a\x54\x15\x80\xb1\xc0\xb8\x60\x24\xe3\x08\xdf\x6c\xc3\xc9\x49\x17\x5e\xc1\x28\x09\x32\xbb\x98\x3f\xf3\x4a\x96\x8f\x53\x02\x68\x82\x51\x16\x63\x50\x8c\xd2\x96\x55\x07\x5b\x11\x8c\x05\x51\x16\x3b\x69\x29\x53\x06\x34\xa8\xe7\xc1\xab\xce\xa2\x30\xed\x61\x96\x30\xc7\x77\x6f\xc2\xff\x2b\x0e\x60\x11\x4b\x43\x6a\xf3\x17\x5e\x81\xd5\x79\x9e\xd5\x86\x68\x39\xc2\x2a\x09\x16\x89\x2c\xcb\x3c\x36\x3b\x7f\x9a\xc0\xb8\x0b\x16\x07\x04\x79\x07\x5f\x73\xf9\x63\xfb\x06\x6d\x58\x6d\x76\x4c\x57\x01\x61\x71\xc2\x02\xd6\xeb\x1f\x8e\x6a\xf4\x2c\xa1\x09\x36\x1e\x0f\xe8\x0f\x9e\xee\x78\x3f\xb5\x60\x49\x04\x08\xd5\x47\xec\xfb\xea\xf9\x61\x37\x7b\xde\x7e\x59\x3d\x3e\xfa\xe3\x89\xc4\xd6\xe9\xf9\xa4\xca\x11\x5c\x41\xb0\x24\x8d\x1d\xa8\xa1\xbd\xc1\xe6\xe5\x59\xd5\xf5\x79\xd0\xa5\x1b\x7e\x26\x25\x71\xe4\x0c\x8c\x31\xd4\xdd\xbd\x93\xe4\x0b\xaf\xdf\x76\x76\x9c\xfb\xe6\x94\x82\xb4\x4a\xcb\xb2\x2c\x0a\x90\xcd\x53\xa9\xce\x7e\x4d\x60\x69\x14\x62\x71\x6c\xb5\xbc\x9f\xbf\x12\xe6\xff\x1c\xa7\xa8\x6d\x57\x9e\x9a\x95\x9f\x11\xa9\x34\xea\xdb\x15\xec\x5f\x41\xb7\x93\x7b\x98\xbd\xb0\x14\x62\x5c\xd9\xac\xf8\x41\x55\x4e\x20\xae\x6c\xb4\xca\x32\x10\x08\x40\x7a\xc8\x79\xd1\x7c\x07\x50\x5f\x73\xd4\x2c\xb0\x87\x79\xc4\x78\x36\xd2\xa5\x7e\xef\x0e\x0b\x22\x11\xda\x55\x56\x6d\xfe\xc7\xfb\xf3\x56\x24\x21\x77\x36\x6e\xbd\x36\x89\x3b\x0a\x46\xff\xde\x9a\xda\xda\x1f\xd8\x05\x41\x4c\x06\x86\xc1\x6e\x76\x02\xab\xee\x31\x4e\x6f\x47\xef\x9a\x0c\x23\xac\x9b\x97\x27\xc3\xca\x1a\x1d\x8d\xb3\xcc\x2a\x8d\xcf\x2a\x91\x37\x15\x6f\xca\x6a\x35\x9a\x5f\x52\x52\xec\x15\x14\xf0\x31\xd5\x73\x18\x3d\x7e\x29\x43\x6a\x2a\x61\x5d\xf0\xf3\xd3\xea\xac\xff\x9c\xcc\x6c\x02\x3b\x60\x79\x8e\xd7\x17\x45\x03\x45\xad\xc0\x41\x5e\x75\x79\x08\xa8\x61\x3a\xc0\x94\x26\xd8\x08\x7c\x7d\x79\x5c\xee\x16\x2f\xcf\xdb\xd7\x97\xc7\xc7\xe5\xab\x3b\x0c\x3a\xc1\xd2\x1f\x74\x9a\xf3\xf6\x88\x66\x89\xb3\x45\x56\x79\xb1\xc7\x62\x94\x5f\xe9\x99\x8e\x34\x72\x14\x8d\x74\xd8\x82\x57\x6a\x68\x94\xd2\x8f\x4b\xa3\x20\xc8\x70\xa1\x12\xed\x56\x70\x5e\x97\xd5\x28\x28\x8a\x82\x54\xf6\xec\xe7\x5f\x61\xdf\x26\x2e\x65\x65\xec\x1b\x87\x43\x09\x09\xb0\x5b\xc4\xad\x19\xb5\xa1\xab\xaf\xd1\xde\xfb\x17\x37\xc6\x42\xbb\x90\xad\x9f\x37\xed\x5b\x37\x7c\xe2\x11\xe1\xb1\x03\x20\x3d\xe5\x45\x73\x67\x38\x79\x3e\x36\x88\x08\x97\xb6\x23\xb1\x37\xba\xa0\x5b\x14\xdb\x73\x87\x69\x9b\x8a\xf9\xd7\x68\xd5\xc0\x71\x20\x26\xd5\xdf\xf3\x22\x9a\x72\x34\x21\xfb\xca\xf3\xaf\x67\x5e\xec\x8d\x9c\xc3\x4f\xc2\xed\x88\xa6\x86\x34\x80\x88\x85\xf5\x78\x3d\x8d\xa8\xc8\xb0\xc2\xf5\xfd\xf1\x69\xab\xf3\xa2\x80\x8b\xff\x59\x32\xc1\x1e\xe4\xc3\xeb\xcb\xf7\xed\x97\xdd\xe6\xdb\x7a\xfd\xf8\xbb\x3b\x18\x06\x04\x1f\x82\xd3\xcb\xfe\x91\x37\xcd\x65\xd0\x4c\x89\x42\x45\x33\xd2\x03\x40\xf7\xc4\xb8\x45\xc4\x6c\x47\xd9\xc1\x44\x51\xa5\xb4\xe1\xc7\x93\x1f\x90\x72\x81\x55\xfc\xfc\x13\x55\x29\x27\x5f\x8c\x88\xe9\x00\x7b\x88\xa7\xaa\x3c\xe6\x58\x8a\xfc\x56\x78\x0c\xb6\x88\x22\x12\x63\x2e\x79\xcc\x0b\x6b\xe0\x31\x28\x11\x45\x51\x2c\x70\xa6\xfc\x0b\xaa\x72\xf9\xf9\x85\x17\xea\x70\x83\x91\x2c\xa2\x58\x00\xea\xdc\x9f\x2a\x78\x5f\x1a\x07\x54\x77\x9a\x58\x99\xd6\xf4\x1e\x9a\x07\x7e\x04\x9c\xdc\xf3\x2b\x9f\x63\x11\xa5\xa9\x36\xd4\x2b\x5d\x4e\xda\xc2\x8b\x28\xe3\xd6\x91\xdf\xbd\xe6\x33\x75\xcb\xc0\x46\x44\x1c\x32\x24\x9e\xce\x51\x46\x60\x5b\xb6\xff\x62\x33\xbc\x3d\xb9\x41\xc6\xbb\x05\x1e\x01\x58\x28\x83\x80\x2c\x86\xe6\x82\xf9\xdb\x28\xc7\x6c\x77\x57\xd0\x1d\x57\xd1\xf1\xdf\xfb\xdc\x73\x77\x3e\x21\x44\xd8\xe9\xde\x58\x7c\x4f\x6d\x13\xc8\x3e\xa9\x2a\xed\xfd\x97\xb8\x2f\x92\x49\x82\xf8\x3a\x87\xaf\x37\x6e\x5d\xee\xdc\x52\xa7\xe8\x7e\xbc\xe6\x12\xaa\xfa\xbd\x5e\xf0\x77\x7e\xc8\xa1\xaa\x19\x0d\xdc\x18\x45\x14\x56\x1a\xb7\x4f\xaf\xfd\x60\x3b\x52\xd4\x40\x74\x2d\xde\x79\xe0\x5a\x31\x3d\x85\x94\x12\x19\xb3\x7c\x8d\x69\x12\xb9\x1d\x08\x2c\xc2\xc5\xcd\x30\x64\xbf\xc2\xe5\x5a\xc1\x57\x44\x90\xc4\x03\xec\xc8\x77\x0b\x3a\xb9\x1a\x26\x84\xa5\xb0\x98\xe4\xe3\xa5\x70\x96\x54\xa3\x81\x52\xa3\x8f\x85\x49\x71\x36\x7c\xcf\x67\x15\x14\x53\xb2\xb3\xbe\xc2\xdc\xdb\x75\x23\x9d\x0a\xbc\x4d\x18\xb1\x1b\x87\xb8\x9f\x0a\x03\x88\x48\x73\x23\xf7\x58\xb6\x33\x70\x0b\xfe\x85\x8c\x83\xf6\x48\xd7\x58\x07\x7e\x9c\x7e\x27\x63\x42\x33\x54\xd6\xe3\xf0\x63\xe3\x3e\x4c\x89\x59\xe2\x76\xff\x57\x4b\x03\x11\x53\x26\x62\x7b\xab\xf2\x42\x97\xb7\x2d\xa0\x45\x1c\x06\x0a\x01\x33\xcb\xfb\x2f\x7f\xc9\x6e\x12\x71\x18\x4a\xed\xd6\xf5\x06\x8e\xf5\x4a\xd5\xf3\xcb\xf6\x72\x82\x59\x61\xb7\x9f\x09\x25\x14\x11\x87\x69\xe8\x20\x9a\x08\xb0\x3a\x1f\x5d\x91\xf0\xd7\x7f\x6d\xfb\xe9\x59\xcc\x68\x82\x3a\xa5\x05\x7c\x5a\x6b\xd9\x17\xfd\x9d\xef\x71\x29\xb4\x1f\xb5\x64\x3d\xf7\x89\x48\x64\xdc\xc9\xed\xc1\x5f\x24\x31\x71\xa4\x78\xec\x00\x57\xed\xd7\x5b\x0a\xf9\x70\x50\x9c\x52\x6e\x28\xfd\x57\xcc\xd5\x89\x5b\x12\x4b\x99\xf6\x1d\x05\x1f\xcb\x6b\xee\xf6\xe0\x03\x69\xc0\xb1\xfe\x50\x9f\xa0\x40\xd5\xe5\x8f\x8e\xfc\x23\xe2\x94\x33\x0c\x3f\x3a\xe3\x28\x54\xec\x2a\x14\xb2\x73\xa6\xf3\xc5\x38\x85\x00\xe1\x1d\xfc\x74\xb2\x05\x99\xd1\x32\x15\xa7\x3a\xc4\x2f\x7d\x2c\xf7\xfb\xce\xf2\x57\xc4\x9c\x51\x91\x3a\xf3\xe7\x8f\xa7\xb2\x40\x71\xa0\xfe\xcd\xeb\x71\xbe\xa7\xe6\x0f\x8f\x98\x30\xb6\x4f\x7f\x9c\xeb\xa6\x57\xf4\x1a\x5b\xbb\x89\x98\x67\x60\xb7\xa7\x62\x51\xfa\x72\x45\xcc\x79\x88\xac\x96\xbc\x7e\xca\x0b\x67\x21\xd8\x73\xb0\x15\x31\x97\x52\x50\x8f\x83\x9d\xf7\xed\xfd\x07\x8c\xb8\x4e\x9c\xc1\x45\x69\xb1\x60\x21\x56\xd9\xa7\xf7\x8e\x58\x00\x08\xdb\x64\xf9\x32\x32\xd3\x16\xb1\x6c\xa3\x22\xe3\x4e\xd9\x78\x95\x5e\x11\x4b\x9e\x65\x16\x78\xf8\x25\x2f\x9a\xe1\x67\x80\x1a\xf8\xf7\x40\x6a\xec\x15\xd0\x85\xcb\x2d\xd6\x31\x24\x02\x6b\x68\xe7\x4e\x27\x71\x40\x01\x13\x31\x28\x63\x0f\x74\xb7\xda\x98\xfa\x37\x96\xc3\x77\xb3\x27\xf3\x3f\x5c\x01\x3e\x21\x94\xe8\x5e\x14\x35\x8e\x54\x12\xc2\x62\x6c\x81\xbe\xb7\xeb\xa9\x91\xf1\xb9\x07\xa8\xbf\x43\x05\xaf\x28\x53\xa2\xc6\x1f\x88\xb8\x2d\x18\x1b\x19\xb1\x75\x55\xee\x2b\x7e\x3c\xc2\xa0\x10\x97\x50\xc2\x0c\x3e\x70\xb7\xdc\x7e\xc1\xf4\xfd\xdb\xe9\xd4\x66\xb5\x9e\xb9\x2d\x12\x2a\x43\x6c\x78\x43\xc5\xdb\x35\xf4\xa9\xbd\xcc\xeb\x6c\x23\xa1\xd2\x78\x0e\x43\xdd\xe4\x47\xde\xdc\xb0\x60\x16\x49\x18\x50\x4c\x3a\xca\x76\x7f\x77\xb7\x32\x09\x45\x88\x81\x26\x7c\x36\x50\xa8\xed\x88\xa8\x20\x12\x16\x05\xda\x2a\x72\x9f\x8c\xc9\xc3\xe8\xb4\x11\x55\xae\xa0\xfb\x47\x5f\x7e\x48\x24\x11\x33\xfa\xf8\x7d\xab\xd0\xed\xe7\xdf\x82\xb4\x8b\x24\x52\x2a\x55\xae\x37\x27\x3a\xeb\xdf\xc9\xa8\x24\x89\xc3\xd0\xf8\x2e\xe7\xfb\x62\xa4\xac\x29\x92\x98\xa5\x48\x53\xde\xfd\xf1\x74\xbe\xad\x26\x32\xfc\xfa\x38\x36\x5c\xda\x36\x35\x04\x95\x7b\x2c\x6a\x7b\xc4\x04\xa1\x6f\xbc\xfe\x7e\x43\xc4\x43\x24\x71\x02\x4e\xf3\x05\xd3\xb1\x31\xa0\x24\xc9\x08\xc3\xe4\x2a\xaf\x31\x43\xe8\xc4\x39\xa7\xaf\x2f\xcb\x08\x76\xd6\xf0\x29\x61\x0b\xb5\xdf\xc8\x4c\x32\x41\x91\x58\xb4\x93\x56\x30\xc7\xda\xea\xff\x2c\x4f\x4b\x32\x25\xc0\x68\x7f\xd7\x50\xbd\xb7\xab\x24\xee\xaf\x7f\xab\x8b\x93\xf0\x28\xd0\x16\x7b\xf9\x72\x50\x13\xe5\x90\x84\x27\xa6\xb9\xda\x40\xdd\x90\x5d\xf9\x0e\xd5\x81\x9f\x4e\x79\xb1\x77\xe6\x8e\x1b\x7e\x84\x4e\x19\x5b\x24\x5c\xa4\x38\x5d\xe6\xb3\xad\xfb\x93\x48\x08\xca\xc1\x37\xfb\xca\x45\x7b\x4f\xfc\x13\x31\xce\x75\x37\x86\x62\xf1\xc1\x72\xf2\x0f\x65\x01\xd3\xd7\x3e\xb1\x03\xf5\x1a\x13\x89\xe0\x1a\x77\x36\x6c\x93\xbc\x0e\xe0\xdb\x76\x84\xa4\x8a\xab\x8e\xeb\xe7\xa5\x4c\x87\xd7\x2d\xc3\xd4\x8d\x7a\x7c\xfc\x75\xd7\x4e\x9e\x1d\x75\xad\xfa\x44\xf2\x4c\xc6\xce\xe4\x0f\xcd\xea\xcb\x11\xc2\x2a\x51\x2c\xc1\xda\x82\x80\xe6\xa5\x58\x94\x87\xb2\xfa\x65\x48\x51\x11\x89\xca\x0c\x83\x5b\xe2\xdc\x1c\xdb\xfc\x8c\x4e\xc7\x43\x44\x2c\xec\x3c\xf1\x62\x52\x31\x58\x24\x4a\x50\x66\xf3\x76\xa3\x8e\x8c\x53\xcc\xab\x5c\x4e\xdc\x32\x25\x8d\xa4\x8c\x59\x86\x1f\xcf\xf2\xc7\xc5\xf0\x03\x4e\x50\xa8\x31\x24\xeb\x36\xaa\x30\x01\x50\xd8\x3b\xdb\x92\x34\x4b\xfb\x91\x75\xa2\x19\xe9\x9a\x99\xbb\xbb\xe5\x62\xf5\x34\x7b\xdc\xf8\xa3\x92\xba\x14\xa8\x4d\x92\x73\x7e\xc8\xff\x5c\xf3\x0a\x8a\xe6\x5b\x91\xa3\x39\x6e\x4f\x8c\x47\x24\x5a\x65\x46\x61\xb7\xe2\xc5\xc8\x84\x59\xa4\x41\x1c\xa3\xfe\xbb\xe0\x6a\x0f\xfd\x97\x2b\x0d\x34\xcb\x2c\xd6\x70\xf6\xce\xf3\x43\xbb\x06\xae\x9c\x3c\x81\x48\x09\x33\x5d\x34\x3d\x20\x56\x88\x94\x32\x8a\x72\xe3\x26\x59\xe9\x85\x5e\x66\x17\x19\xca\x96\xba\xcf\xa8\x38\x33\x0e\x05\x86\xfb\x31\x11\x8f\xd9\x91\x21\x89\xc0\x3b\x06\x6f\x16\xb3\xbb\x99\x6d\x8a\xb9\xe3\xa1\x46\xd4\x4c\x1b\x06\xe2\x98\x3e\xe0\x27\x0d\x33\x85\xa5\x97\xbc\xc8\x2d\x7e\x12\x9b\x9a\xfe\xb0\x48\x10\x36\xe7\xec\x08\x6c\xde\x36\xbc\x61\x4c\x08\x04\x78\x3f\xfd\x8e\x0f\xe7\x79\xf6\xb4\x74\x9f\x8f\x02\x85\x7b\xf8\xba\x3c\x1c\x6e\xf4\x74\xdc\xc8\xcc\x60\xc2\xd6\xe7\xe2\xc7\x3c\x57\xe8\xc3\x0d\xd7\x9c\x9f\xf1\x87\xa2\x20\xc0\x15\xb8\x52\x92\x9f\x56\x45\xcf\xda\x43\xa4\x71\x28\xd0\xaa\xe7\x5f\x50\x94\xc7\xa1\xf8\xd0\xe4\x0b\x92\xc6\x19\xc1\x79\x2f\xa0\xd9\xbd\xf7\xe6\x4b\x1a\x67\x46\xef\xe1\x0e\xde\x73\x09\xbd\x4d\x33\x8d\xa5\xb5\x18\x3e\x5f\x96\xfb\x3d\x22\xe6\xae\x57\xc0\x34\xd6\x51\x96\xf5\x7a\x88\x3f\x93\xbc\x17\x69\x42\x02\x63\x23\xf5\x06\xf2\x87\x8b\xce\x5e\x4d\x6d\xcc\x58\x7b\xfe\xfc\x32\x12\x4e\x31\xb3\xb0\x44\x9e\xaa\xdf\xa6\x4d\xd3\x20\x41\x59\x4f\xbb\xb8\xe1\x82\x3f\xe8\x0a\xa5\x69\x68\xc3\x66\x74\xb8\xb4\x2a\x3c\xee\x58\xc6\x31\xc6\xe5\xc7\x7e\x21\x23\xcd\x58\xa8\xad\x14\xea\x4c\xeb\xfc\x90\xf3\x1b\x52\x3f\x22\xcd\x38\x43\xbc\x0b\x42\x4f\x4f\xa5\x7c\xab\x7b\xd8\xd6\xd1\x85\x70\x6e\xb6\xeb\x1a\x1a\x7b\xf9\x5d\x1d\xf1\xba\xb9\x90\x72\x15\x21\x42\x24\xaf\xbf\x35\xf9\x21\x6f\x2e\x5f\xca\x83\x1a\xef\xb7\xa9\x60\x3a\x23\x2e\x2c\x83\xca\x39\x2e\xfc\xb4\xc3\x98\x0a\x29\xb0\xa2\x6e\x44\xc9\x36\xfc\x30\x7e\x5f\x05\x84\x98\x78\xdb\x72\x7f\xaf\x0f\x96\xca\x58\x60\xc3\x19\xc1\x70\x73\xab\xc7\xe1\x0e\xaa\x80\xaa\x4e\xba\x6e\x18\xae\xa4\xc0\x52\xe3\x3c\xf4\x71\x39\xc1\xf8\xad\xd3\x3c\x35\x26\x3a\xfc\x72\xe7\x2d\x2c\xfa\x01\x74\xaa\x85\x01\x9d\x2c\x9b\xb7\xaf\xdd\x72\x94\x05\x6d\xe0\x6d\x6a\xbf\x8e\xb4\x74\xa5\x4c\x3c\xfa\x77\x5a\xfe\xd2\x9d\x0f\x4c\xf7\x16\x8e\x79\xb3\xac\x65\x55\x7e\x98\x15\x6d\x04\x08\xcd\x08\x37\x19\x3c\x32\xad\xfa\xa2\x18\x22\x23\x5a\x21\x58\xef\x04\x95\x2e\xab\xe3\xf6\x0d\x9e\xf8\x3e\x97\xdb\x2a\x97\x3f\xdc\x18\xca\x52\x4c\x25\x65\x59\x55\x20\x1b\x23\x5e\xf7\x4b\x57\x6c\xc8\x68\x1a\x82\x03\xf4\xa3\x04\xc3\x92\x57\x87\x8b\x87\xd0\x0c\x7f\x34\x95\x0a\x89\xe9\xc6\x8d\xdf\x4f\xda\x41\x68\x9e\x51\x88\x58\x27\x94\xb3\x98\x6f\xa7\xe7\x69\x16\x4a\x2a\xa4\xeb\x5d\x15\x5d\xd8\xd9\xeb\x24\x67\x2c\x08\x52\xe2\xe1\x23\xed\xce\x31\xa8\x05\x66\x2c\x92\x8e\x3d\xfe\xd8\x1e\x1d\x7c\x36\xd1\x48\x32\x5a\x35\x7c\xd0\xdb\xcd\x98\x32\x2b\xaf\xd3\xa7\xbb\xd6\xc8\x15\x59\xa4\xe3\x08\x3c\x77\xbd\x42\x9e\xee\xfc\x72\x57\xca\xae\x92\x6c\x47\xc6\x21\x95\xbc\xc7\x54\x72\xa9\x51\x16\x4b\x82\x77\x16\x2d\x7b\xc0\xa8\xde\x2e\xca\x93\xdb\x62\xb2\x34\x88\x69\xda\xc9\xaf\xf7\x84\x88\x44\x96\x5a\x2f\x3f\x28\xda\xab\xf2\xb9\xa3\x3d\x9a\x05\x81\x74\xc6\x09\x90\xeb\xb2\x9a\x76\x0f\xf8\x9f\x61\x16\xed\x3e\x2c\x8d\x87\xdc\x1f\x65\x6e\x18\x1c\xe3\xd1\x83\xa8\x26\xcb\xac\xae\x7f\xe3\xfd\xb6\x9b\xb7\x76\x5b\xbd\x15\xe6\xfe\x74\x91\xcd\xb8\x4d\x07\x65\x59\xbc\x43\xd5\x98\x92\xca\xeb\xef\x8b\xd1\x3c\xe3\x9a\x50\x61\x65\xff\xae\x0b\x71\x99\x08\x62\xd4\x0c\x3e\xf2\xcf\xa9\x0a\x71\x26\x18\x43\x1a\x1c\x2a\x98\xdd\x81\xce\x0b\x50\xfd\x4b\xb5\xc3\x40\xa4\x58\xb8\x31\x26\x78\x9b\xd5\xcb\xf3\xee\xf9\xdb\xd3\xea\x79\xb6\x7d\x71\xcd\x91\x4c\x27\x12\x6b\x7e\x56\x94\xbc\xd7\x4e\xbb\x7a\xdd\x87\x13\x48\x2b\x19\x3a\x24\xad\xd1\x31\x37\x07\x78\x10\x19\x17\x25\x0c\xba\xea\x73\xd5\x6e\x69\x37\x48\x47\x3c\x90\x0a\xb3\xf0\x79\xde\xc8\x32\x2f\xfe\xe5\xce\x41\x42\xc3\xf3\x33\xbf\x0a\x89\x0c\xb7\xe0\x01\x9c\x24\x02\x51\x77\xcf\xf0\xd1\x94\xc5\xb6\x72\x9e\x3e\x82\x13\x6e\x18\xc7\xef\x39\x7c\x7c\xe5\xd5\x91\xff\x5a\x36\xed\x2c\x1f\x1a\x1b\x0e\x7f\x11\x55\x8a\xba\x5d\xf2\x90\xe3\x82\xe2\x4e\x17\xd2\x00\x03\xb6\xfb\xbb\xbe\xad\x94\xe0\x61\x96\xa4\xd4\x75\x6d\x8f\xed\x56\xec\x4b\x44\x6e\x04\x18\x6e\x15\x5e\xc8\x26\xdf\xbf\x9e\x0f\xd7\xfd\x74\x1e\xa5\x86\x0e\x2e\xbc\xdb\xdf\x65\x14\x11\xb8\x81\x82\x08\x6a\xdb\x87\x25\x12\x3b\x37\x9d\x80\xdf\x60\x0a\xf0\x38\x09\xf1\x29\xb5\xc9\xe3\x5d\xee\xa1\xc8\x3c\x96\x01\xf1\xd4\xb8\x86\x1f\xda\x88\xbc\x59\x43\x75\xc7\xaf\x3c\x3c\xed\x27\xd2\x50\x06\x36\x6d\x79\x5a\xce\x7a\x8d\x06\x9e\x26\x9c\xa9\x61\x8f\xde\xaa\xf5\xfa\x11\x29\xc3\xb7\xe2\x54\xe5\xef\x88\x55\x3d\x1f\x57\x8b\x97\xee\xa8\xf1\x3e\x57\x20\xce\x7b\xea\xff\x2a\x63\xbc\xdb\xd8\x04\x83\x36\x52\xf4\x47\x40\x30\x77\xbf\x0f\xc0\xab\x9b\xd6\x63\x82\x67\x24\x30\xbc\xbe\x53\x59\x35\x75\x78\xe7\x4e\x91\x51\x85\x18\xda\xdd\x48\x0e\xa4\x57\xa5\xe6\x19\xb0\xd4\x45\xc8\x58\x80\xe9\x12\x23\x3b\x42\x10\x1e\x87\x0e\x85\xb3\x6c\xde\x3e\x5f\x41\xe6\xf0\xee\xcb\x6a\x5c\x88\x24\x72\x29\xee\x06\x9a\x6f\x27\x7f\x00\x02\x22\xfa\xfe\x99\xa0\x0c\xec\x7e\xd3\xf0\x1f\xdd\x8c\x93\x04\x30\xd2\x79\x05\x8c\xba\xe6\xb0\x3f\xfb\x7b\xaa\xac\xf5\xed\x1b\x46\x0e\x85\x84\x43\xcf\x0c\xd8\x91\x05\xb8\xca\x34\x4a\x45\x7d\xe0\x0e\xf6\x72\x6e\xfc\xfd\x55\x02\x58\x5f\x3e\xbe\xb7\xbe\x70\x25\x15\xde\x7b\x63\x30\x72\x3e\xe8\xfc\x70\x38\xf6\x1c\xcb\xfe\x4d\xbb\x5c\x2d\xf9\xcf\x10\x43\xde\x3b\xe6\xce\xa6\x49\x60\x75\x20\xe1\xa5\x30\xb8\x98\xa1\xbb\x8a\xe0\x40\x09\x96\x3b\x90\x66\xa2\xca\xb3\x38\xc0\xaf\x25\x2a\x47\xfb\xc2\x0a\x87\x50\x63\x11\xc3\xb9\x2b\x98\x2e\xd4\x54\x05\x98\x03\x83\x2c\xed\x71\x02\x5e\x51\x8c\xd4\x9f\x28\x22\x81\xea\xbc\xbe\xea\x41\x87\x90\x43\x2a\x2d\x77\xf7\x19\x3e\x4c\xb6\x38\x7a\xff\x20\x93\x28\xc8\x2c\x0e\x5c\xfe\xb0\x0a\xa7\xee\x90\x35\x49\x5e\x3d\x2f\x5e\x97\x4f\xcb\xe7\x6d\x4f\x1e\x50\x70\x1d\x84\x99\x0d\x88\xff\x1e\x86\x8d\x6b\x66\xd4\xe3\xf9\xb9\xde\x57\xe5\xf9\x66\x83\xdd\x0d\x07\x89\xf2\x11\x1e\x18\x7b\x7f\x28\xf1\xd2\x07\xbb\xcc\xff\x0d\x0b\x23\x02\xcd\x31\xa4\x7c\x5d\x6e\x96\xaf\xbf\x2e\x77\xcb\xdf\x16\x5f\x66\xcf\x0f\xcb\xdd\xe6\xcb\xec\xd5\x5d\x9b\x20\x69\x18\x53\xab\x23\xc1\xd5\x65\x5b\xce\x81\x8f\x8a\xa5\x82\x0a\x12\x98\x8e\xbe\x31\x1d\x7f\xe6\x47\x58\x94\xd5\x15\x0b\x7c\xbc\x55\xf7\x74\x38\x7a\x6f\xa8\x08\x09\x0b\xfb\x38\xc3\xaf\x45\xbe\x7f\x6b\x7c\x97\x72\xf8\xd4\x44\x08\x91\x36\x14\x94\xcf\xe7\xd2\x5b\xc8\x0d\xa6\xa1\x60\x84\x06\xa1\x9b\x86\x65\x01\x86\xe4\xe4\x2e\x91\xb1\x04\x15\x39\x9f\x5f\xb6\x4d\x6f\x79\x13\x2c\x49\xbd\x33\xb0\x05\xf4\x0c\xbf\x9a\x29\x8d\xba\xd1\x06\x49\x30\xd5\xef\xb2\x03\xa3\x2c\x25\x91\x4b\xb2\xbe\xf3\xaa\xe2\x45\x73\x19\xcb\xcc\xf7\x67\xba\x68\xc3\x64\x0c\x6f\xdb\xad\x16\x8c\x43\xcf\x64\xec\xe2\x90\x0a\x22\x12\xc2\x38\xdd\x35\x0f\xd0\xcc\xcf\xf9\x41\xe5\xc5\xbe\xcf\x32\x19\x3d\xfe\x44\x6a\x5c\x84\x06\x56\x6f\x3f\x2b\x9a\xd9\xcf\x71\x42\x70\x81\xc2\x16\xbf\xe1\xf4\xd5\x9d\xb8\x8f\xbb\x77\x3c\x0c\x0d\x47\xfb\xe4\xa9\x86\x3f\xeb\x07\x8e\x7e\x1b\x8f\x79\xe2\x3c\x91\xf9\x1e\x71\x15\xb8\x9a\xdd\x62\x07\x0e\x63\x3f\xc1\x13\xa3\x45\xb6\xb3\xee\x70\x28\xcc\xe7\xe1\xea\xee\xdf\xab\x06\x66\x7b\x4f\x70\x07\x5a\xac\x17\xcb\xfb\xae\x20\x2f\x94\x4c\x50\x79\x8c\x4b\x59\x9d\xb1\x1b\x39\xc8\xa1\x05\xc4\x31\x4f\x06\x80\x29\x4e\xa2\x09\xc0\x94\x80\x38\xc1\x0d\x73\xd9\x06\xce\x55\x59\x40\x55\xfa\x43\x29\x47\xb6\xf4\xf2\xe1\xf7\xf5\x76\xbb\xdc\x6c\xfd\x01\x30\xec\x5a\x53\x94\x69\x97\xeb\x0e\xb8\x29\x74\x26\x0d\x27\xa0\x12\x46\xff\x70\x34\x43\xb5\x0a\x3c\x2a\x13\xd4\xc3\xdc\x9f\x55\x43\x86\x7d\x88\xdd\xf1\x82\xc0\xe8\x2f\x70\x38\xf9\x0c\x4d\x06\x41\xca\x6d\x10\x68\x68\x57\x8f\xf0\x0e\x23\xea\x9d\x0c\xa8\xc2\x1a\xdd\x43\x59\x3e\xe0\x0b\x5f\x68\xcf\x97\x92\x41\x42\x88\xd5\x93\x9b\xb5\x39\xfc\x01\x6a\xd4\x2c\xa8\xbb\xee\x94\x0c\x04\x43\x34\xc8\xcb\xf3\x72\x33\xdb\xbe\x6c\xbe\xac\xfa\xd1\x85\xa4\x54\x11\x2b\xf8\x67\xe8\x64\x83\x39\x22\x43\x66\xac\x5b\x9c\x59\x41\x03\x6e\x1b\x96\x0c\x08\x6e\xe0\xaa\xe2\x79\xd1\xd3\xa8\xba\x89\x1b\x95\x51\x14\x20\x61\xee\x88\x23\xfb\x79\x92\x8c\xa4\xd1\xeb\x75\xb2\x40\x2e\xfd\x5e\x43\x35\x9f\x6f\xed\x7d\x1b\x9d\x4d\x6a\x9c\x47\xc7\x36\x26\xea\x5f\x52\x1c\x48\x6c\xaa\x7c\xe4\xa3\x6a\x86\x8c\x15\x23\x86\x68\x7a\x97\x63\xbe\xb8\x81\xc3\xe1\xff\xc4\xb4\xb0\x33\xda\x09\xbe\x09\x19\x03\xc1\x57\xf0\x01\x6c\xa2\x8e\x89\xad\xb1\x92\x75\xef\xa9\x4c\x28\xc3\x5c\x9c\x1f\x1a\xa8\xe6\xbc\x28\xbc\x03\xf6\x35\x86\x5f\x26\xd4\xb8\xa0\xd7\x18\xe7\x61\x39\x3e\xf4\x0a\xeb\x42\x26\x69\xa6\x32\x07\xd3\xf9\x95\xb7\x09\xbb\x3b\x02\x46\xad\xc7\x09\x82\x21\xa7\x62\x42\x17\xc6\xbd\xc9\xfd\x2f\x4d\xb9\x31\xcb\xaf\xa1\xb9\x83\x86\xcb\xb7\xf6\x15\xc0\x38\x75\x78\x07\x33\x22\x68\x97\x5b\xfc\x54\x43\x68\xf4\xf0\xb3\x44\x21\x28\xfc\x16\xff\xe6\xc6\xc7\x78\xa2\x43\xbb\x3d\xec\x4e\x15\xec\x7e\x5c\xe4\x2e\x97\x65\x91\xff\x77\x87\x6b\xe3\xae\x38\x1f\x01\xf1\x78\x37\x26\x1d\x17\x1a\x61\xa1\x82\xd7\xf0\xad\x72\x71\xb0\xe4\x5a\x62\xac\x61\x08\x78\xf3\xcb\x82\x5f\x81\x2f\xec\x48\x41\xb5\x61\x11\x9f\x45\x87\x04\x90\x42\x06\xa8\x35\x64\xe8\x8e\x77\xab\x5f\x57\x77\x1e\x34\x27\x25\x31\x22\xd7\xdc\x15\x07\xb6\xe5\xe2\x8d\x37\x4f\x50\xd7\x7c\x0f\xf5\x23\xe8\x51\x54\x24\x25\xf5\x58\x5f\x23\xcf\x8c\x29\xeb\x7d\x59\x99\xea\xeb\xf0\x92\x24\x35\x8a\x35\xf8\xb0\x10\x5b\xfb\xed\x75\x65\xde\xde\xfe\x26\x22\x25\x0b\x13\xe9\xc5\xc0\xd6\xbc\x76\x38\xb6\x4e\x78\x5e\x48\x99\x64\x46\x19\xb9\xcd\x82\x2e\x27\x3f\x67\x65\x4a\x32\xef\x79\xde\xa6\x66\x86\x5d\x68\x65\xd0\xfc\x22\xa6\x42\x85\xe0\x92\xd9\x62\x36\x94\x7f\x9d\xdc\xa3\xa5\x8e\xe3\x84\x75\x58\xdf\xe3\xf9\x68\x8b\x85\xdf\x21\x1f\x5e\xa5\x22\x22\xc5\xfd\xc0\x38\x30\x70\x8f\x59\x57\x44\x07\x31\x6a\xe2\xbe\x3c\xbb\x00\x4a\xd1\x38\x8c\xc9\x88\x8b\xbb\xe6\x55\xd3\x95\xe5\x15\x95\x12\xe3\xc7\xe7\x72\xa8\x29\x33\x9c\x2f\x8a\x85\x2c\x13\x3d\x0e\x6a\xbb\xea\xfa\xaf\x66\x49\xa4\x4d\xf0\x6b\x25\xc4\xea\x1e\x45\x55\xb1\x24\x43\xaf\xef\x4d\x29\xa5\xb1\x3b\xea\x3f\x0e\xc5\xd2\x0c\xa9\x01\x66\x35\x5b\x0f\xb0\xda\x2a\x62\x9a\x3b\xbd\x08\x0f\x0c\x6a\x27\xe5\xe6\x83\x9f\x26\x55\x4f\x85\x8a\x20\xcd\x8c\x12\x83\x29\x81\xcf\xaa\x2a\x7f\xe7\x87\xfe\x6b\x3b\xba\xb8\x38\x61\x88\x4e\xdf\xa3\xbb\xd8\x65\x03\xef\x7e\xd9\x54\x09\x33\x79\x66\x05\xfb\x01\xae\x72\xf8\x04\x55\x22\x32\xbc\x05\xaf\xc2\xbb\xdb\x0b\x95\x48\x53\x73\x71\x2a\x04\x77\xb9\x9c\xa4\xb6\xaa\x04\x8c\xbd\xb0\xef\xdb\x18\xfe\xc5\x68\x54\x46\x28\xea\x52\xba\xa0\xe6\xeb\xcb\xcf\xcb\xf3\x2a\xa3\x09\xde\x09\xf4\x51\x9c\x9f\x2f\xcf\xe5\x07\x42\xdd\x6e\xdc\x86\x8c\xa5\x48\x54\x3b\xd7\xb0\x5c\xad\x13\xe2\xf2\x3a\x95\x25\x0c\xcf\x93\x9b\x86\xd7\xaf\x46\x75\xb6\xec\xe6\x5e\xc6\x05\x22\x28\x17\x16\x32\x55\x37\x3d\x82\xa7\xca\x20\x0e\x6d\xe7\xe2\x71\xd1\xfd\x91\x53\x04\x3a\x9f\x9b\xe8\xae\xf4\x82\x1e\x8a\x13\x8e\x48\x45\xac\x43\x21\x44\xfa\xa7\x2b\xe9\x20\x88\x52\x3c\xd5\x9c\x39\x10\xb4\x2c\x2d\x78\x71\x78\x95\x9c\xc7\xf8\xb0\x71\xa2\xee\xfa\x64\x6d\xc5\x41\xa0\x40\xe3\x9a\x9f\x3b\xf9\xe8\xa7\xf2\x86\x2b\xb4\x50\x82\xa6\x28\x6a\x64\xb3\x98\xcd\x20\x7b\x51\x22\x53\x56\x7d\xd7\xb8\xa8\xc1\x09\xbf\xcc\x30\x5b\x6e\x16\x1e\xed\x87\x65\x28\x9d\x8a\xf2\xea\xe8\xe1\xb4\x8b\xa6\x1a\x45\x42\x4a\x4a\x62\x4c\x20\x2d\xc0\xa6\x9d\x18\xf3\xcb\x80\xd0\x70\x4d\xdb\x6d\x93\x71\xa4\x61\x1f\x72\x0d\x4d\x7e\xb4\x74\x60\xff\x3c\x75\x22\x98\x76\x0f\x7c\x60\xd9\x21\x94\xe6\x1c\x3b\x30\xb3\xcd\x6a\x36\x5f\x6d\x37\x03\xe5\x99\xeb\x98\x5d\x69\x9d\x3a\x39\x12\x2c\x6a\xb4\x6f\x2f\x96\x8d\x06\x17\x0c\x01\xcb\x12\x5f\x3c\xfe\x83\xb7\x21\xfd\x02\x0e\x87\xbe\x64\xbf\x00\xa2\x22\x94\xe0\x10\xe7\xcb\xfc\x70\x46\xfc\xe9\x72\x3f\xed\xba\xe1\x20\x98\x40\xb9\xc4\x78\x12\x57\x6c\xe7\xac\x31\x6c\x7f\x00\x53\x8c\xd9\x7d\x7e\x5b\x9d\xdb\xe4\x7b\xbc\xb6\xf4\xa2\x02\x88\x42\x8a\xe0\xb1\x87\x43\x29\xf8\x01\x29\x49\xee\x44\x11\x33\x8d\xa1\x9e\x35\x74\x75\xd9\x96\xaf\x46\x66\x65\xda\xb8\x4f\x40\xa4\x8c\x54\xd3\x6f\x8a\xcb\xc1\x76\xe1\x8e\x43\x08\xc6\x07\xbc\x36\xde\x16\x3f\x9d\x3b\x10\x07\x31\x63\x56\x13\x40\xaa\xab\x15\x7d\xb8\x72\x41\x4c\x59\xd0\x61\x19\xbe\xd5\xa6\x5c\x6d\x8c\x4d\x0a\xf5\x6a\xc8\xfd\xd7\xbe\x12\xf8\x58\xae\xa9\x8c\xd7\x73\x0d\x62\xae\x31\xf0\x5c\x1c\xda\x33\xf5\x4d\x83\xdc\x00\x45\x11\x14\x0f\x9f\x79\xb3\xf6\x50\x1e\x48\x52\x8a\x8c\xdc\xef\x2f\xaf\x8f\x77\x4f\x2f\xf3\xd5\xe3\x6a\xfb\xbb\x3f\xd8\xce\xfb\x3e\x43\x4b\x1d\xf3\xe2\x3a\x43\x87\x44\x2b\x48\x3b\x2e\x6d\x87\x08\x83\x34\x00\x34\x71\x39\xf2\xea\xc7\xa2\x3c\x1a\x60\xb5\x4f\x10\x20\xcd\x34\xee\x5a\x6a\xd6\x46\xa7\xeb\xf3\xc1\x40\x26\x32\x77\x93\xb3\xd4\xb8\x5c\x2d\x5e\x7f\x5f\x6f\x5f\xe6\xab\xed\x72\xf1\xb2\x7a\xfe\x19\x40\x1d\x78\x10\x09\xab\x0c\xf3\x6d\x73\x37\x77\x0a\x9d\xed\x01\x20\x72\x68\x01\x6b\xe2\xfc\x69\x35\x07\xe0\x34\x63\xe8\xb0\xf5\xfb\x7c\x1b\xfe\x3d\x8d\x7b\x01\x3c\x66\xa4\xe3\xb0\xec\x8c\x96\x8e\xf4\x11\xcc\x68\xca\x09\xa2\x10\x5e\x6c\x33\x9c\x95\x2c\x11\x7a\x69\xa3\x13\xf7\xc3\x45\x68\x8c\x69\x7a\x3c\x0a\x13\xc1\x8f\xfa\x72\xa3\x09\x2a\x80\x3a\xbb\x2f\x54\x4a\x0a\xa9\x3f\x21\x68\xe3\x8f\xf7\x06\xf2\xc7\x7d\x59\x21\x6e\xa7\xb7\x13\xf6\x5f\x43\x49\x18\x82\xa2\x4c\xf5\xef\x9f\xe7\x72\x8c\x52\x03\x99\x41\x6c\x0a\x19\xba\x5d\xc9\xdc\x3a\x0f\x52\x53\xe3\xec\x66\xda\xd6\xed\x09\x0a\x18\x41\x62\x00\x68\x86\x48\xb8\x0a\x9a\x2a\x87\x77\xb8\x46\xc1\xe1\x10\x8b\xd8\xdd\xf0\x03\xaf\xae\xea\xdc\xa3\xeb\xd6\xc4\xc0\x33\xf6\x60\xc9\x4a\xab\xbb\xf9\xe5\x9a\x66\x01\x3a\x33\x2e\x7c\x35\x34\xf7\x79\x2d\xf9\xe1\x57\xe3\xc5\xf8\xd3\xae\x13\x68\x21\x32\x67\x24\x7c\xc5\x4b\xd1\x01\xa3\x10\xb9\x25\x8e\xab\xb1\x68\xdd\x70\x86\xe9\x40\x0a\x82\x1b\x40\xed\x9d\xa3\x4d\x40\xca\xd5\xbb\xbd\x8b\x9a\x68\x8a\x30\x46\x27\xdb\x3e\x13\xf9\x21\x6f\x72\xa8\x51\xf1\x60\xf8\xed\x94\x33\xc8\xac\x6e\x02\xcf\x8b\x7a\x9a\xdb\xa7\xc3\xd0\x88\xc2\xdc\x95\x7b\xac\xe1\xb9\x3f\xf3\xd0\xb6\xdb\x6f\xac\xce\x76\x1c\x0b\x62\xa7\x5f\xbe\x6c\xde\xfa\x38\x1c\xcd\x12\x85\x5a\xd7\xa2\x68\x2e\x9d\xf7\x87\x3b\x1a\x49\x8a\x01\x8e\x35\x08\xf9\x02\x55\x39\xfd\xea\xe9\x48\x45\x66\xea\xb8\xcc\xbf\xab\x3b\xe9\x38\x48\x85\xa3\x71\x9e\x2f\xe3\xfc\x44\x27\x54\xb8\xf0\xca\x78\x8e\xa0\x20\xbf\x3d\x98\x46\xa6\x61\x61\xa2\xdc\x63\x91\x9f\x8f\x3d\x03\x53\xa1\xd3\x38\x44\x5a\x43\xa1\x47\xad\x7b\x9d\x45\x60\x9c\x35\x9a\x8a\x37\xb0\xcf\xe5\x48\x38\x5f\xe8\x2c\x89\x22\x3b\x4d\xbf\xd9\x9a\xd0\xe4\xfc\xd4\x82\x28\x6c\xee\x2d\x57\x6b\x1a\xfc\xcd\x75\x45\x8b\x54\x3b\x74\xb9\xdd\x5d\xfb\xac\x35\x2d\x04\x60\xcf\x7e\xe7\x56\xea\x5d\xfe\x33\xcd\x07\xf7\x8e\xf7\x51\x83\x5a\xc6\x04\xf5\x6f\xb1\x84\xb9\x3e\x8c\x89\x86\x5a\x11\x83\x15\x39\x9b\x72\xdb\x64\x5f\x50\xab\x14\xb0\xcc\x62\xd0\x62\x68\x11\xdc\x66\xf3\xf8\xfa\x9d\xaf\xbc\x71\x84\x56\xdc\xd8\x07\xfd\xf7\x0c\xd5\xa5\x6b\x42\x8d\xbf\x5a\xa4\xd8\x37\x93\x8e\xcc\x87\x09\x67\x5e\xec\x0d\x2d\xc6\x8d\x92\x49\x10\xf4\x8a\xd4\x83\xd2\x68\xff\x65\x1e\xcd\x36\x4d\x38\xd6\x7f\x96\x2f\x9b\x81\xce\x8c\xd6\x5c\x82\x0d\x74\xe7\xe7\xcb\xa2\x9c\x5a\xc4\x65\x10\x84\x1c\xb3\x71\x83\x64\xfb\xbe\xda\x7e\xb9\x7b\x9d\x7d\x9f\x3d\xee\x96\xcf\x77\xbb\x3b\xdf\x44\x90\x41\xc0\x84\x94\x36\x62\xf8\x4b\xea\x84\x0c\x82\xd8\x74\x4d\x2c\x69\xbf\x3c\x28\xdf\x8c\x9d\x34\x0c\x99\x5c\x0e\x65\x10\x70\x85\xf3\x72\xf3\x56\x7e\xd8\x2a\xee\xe0\x99\xc9\x80\x84\x21\x56\x75\x74\x7e\x38\xb8\xf9\x2c\x03\x12\x0b\xc4\xd5\x20\x73\xc3\x96\xac\xd6\xfc\x72\xdd\x60\x77\xe3\x33\x66\xa8\xf5\xe8\xd2\x06\xf5\x00\xb6\x2d\x03\x1a\x51\xe7\xb2\xf2\x52\x1c\xf2\x02\xba\x46\x64\x7b\x10\xb0\x7a\xcf\x9d\xbc\x19\x22\x92\x9b\xb2\x9a\xa3\x71\x8e\x7c\x83\x49\x19\x38\x19\xd0\x34\x96\x1d\x7d\xf8\xf1\x65\x3b\x7a\x36\x61\x10\x61\x4c\xb7\xf4\x0e\x31\xf6\x00\xa3\x0a\x93\x8a\x79\xfe\x4f\x4c\x7f\xb0\x18\xfc\xb3\x8e\x8e\x0c\x18\x33\xe5\xf7\xaa\x3c\x17\x6a\xfb\x56\xc1\xe0\x12\x18\x64\xb8\x4e\x23\x05\xfd\xb7\x57\xb3\x5d\xf6\xa6\xa7\x0c\x62\xaa\xe2\xde\xa2\x76\x97\x6b\x9d\xcb\xb3\x37\x15\x96\x41\xac\x52\x6f\xbd\xce\x1b\xc4\x56\x94\xe7\xa6\xe7\xce\x2e\x83\xc4\x4a\xa8\x9b\xde\xe1\xe9\xd1\xa9\xb7\xc9\x20\xc9\x62\x4c\x8d\xe1\x98\x23\x86\xf5\x6f\x2a\x2e\xfc\xed\x08\xb3\xfd\x86\xcc\x0a\x67\x18\xec\xa0\x8f\x1a\xdc\x71\x6e\x2a\xd5\x9e\xbe\x6b\x5e\xd5\xd7\x31\x18\x12\x29\xb2\x4e\x0d\x6a\x77\x7a\x2f\x76\x98\x34\x38\x14\xeb\x68\x72\xf2\x94\x24\xde\xc5\xf8\x65\xe1\x63\x36\x77\x38\x33\x5e\x65\x9d\x62\x45\xdf\xc8\x62\x32\x32\x92\x81\x88\x08\x26\xd2\xcd\xdb\xc0\xac\xc7\x1d\xe5\x04\xdb\xc7\xf3\xbc\x99\x97\x75\x27\x19\x23\x03\x29\x8d\x9e\xc1\x76\xf6\x5b\x6f\xdb\x90\x01\xc4\x04\xb5\x23\xe6\x79\xcf\xca\x63\x0a\x94\xfc\x7f\x69\xdf\xb5\xa7\x15\xd2\xca\x1b\x19\x8b\x8a\x2e\x8b\x96\x81\x4e\xa9\xb0\xb5\xdf\x95\x5d\x18\x46\xd7\xa1\x33\x1e\x82\xab\xae\x57\xbc\x50\x0f\x50\x40\x9d\xd7\x38\x29\xfd\x82\xdc\x7d\x9d\x96\x21\x6e\xba\xba\x02\x50\xe5\x51\xe2\x1e\xd9\xfc\x85\xad\x92\x0c\x34\x18\xe1\xca\x65\x1b\x9e\xf7\x5e\x31\x12\x04\x52\xda\xf8\xca\x30\x60\xef\xf2\xda\xc0\x99\x07\xdf\x4b\x02\x6a\xaa\x99\x5c\xa9\xf5\x1b\x42\x3b\x8b\x72\x2c\xb2\x7a\x2d\xb9\x9a\xfa\x4f\x1b\x0c\x87\x45\x45\x4e\x77\xb9\xfc\xd8\x14\x51\xcd\xdc\x28\x44\xd4\x4b\xc4\x30\x29\xff\x83\xb3\x54\x86\x6e\x97\xd9\x58\xca\xf8\x88\x49\xda\x8e\xe2\xbd\x4a\xf7\xa8\x94\x3e\x39\xdf\x48\x20\x28\xa4\x23\x69\xc1\x7a\x10\x60\x48\x12\x48\xb3\xbb\x5a\xcc\x15\xa8\x1d\xfe\x8c\xdd\x07\xe4\x7e\x08\xc8\xd4\xb0\x53\x11\x36\x72\x67\x10\x3a\xfe\xa8\x86\xc0\x6a\xb4\x96\xfa\x45\x7f\x2f\xab\x1f\xa3\x1b\x4d\x79\x80\x3f\xe3\xae\x2a\x0b\xd8\xbc\x95\xfe\x92\xa8\x54\xcc\x96\x1d\x2d\x75\x72\x30\x93\x08\xd5\x01\x86\x75\x57\xc2\xae\x1d\xf3\x5d\x92\x90\x18\x6b\x34\x71\xae\x0a\xaf\xab\x22\x49\x18\x45\xe8\x0d\xb7\x2f\xcb\x69\xfa\x8a\x24\x61\x96\xa0\xe2\x45\x9b\xcc\x9f\x4f\x83\x28\x5d\x92\x90\x33\xe3\xef\xd7\xe6\x2a\x0e\x0f\xef\x8e\xa9\x20\xf6\xce\x4b\xa6\x3b\x36\x98\x81\x21\x50\x84\x85\x43\xa1\x76\xab\xc5\x8b\xbf\xd7\x8c\x6a\x04\x71\x0d\x7c\x76\xaf\xb0\xbe\xa3\x87\xc8\x62\x81\xab\xf3\x0e\x3e\xf3\xba\x59\x60\x11\x73\x74\x21\x2c\x15\x46\x32\x89\x1f\xe4\xc2\x79\x36\xf6\x1b\x89\x92\x44\xcc\x28\x31\x23\xe4\xe8\xd0\x66\xa1\x5e\x53\x56\x92\x98\xc5\x08\xc0\x52\x20\xf3\x36\xd0\x78\xd1\xa3\x9b\x11\x27\x84\x5b\x86\xca\x86\x1f\x0d\x3b\xd7\x7a\x56\xdd\xaa\x42\x49\x12\x43\x88\x66\xf4\xbb\x1d\x7c\x82\x3c\x37\x80\x70\x93\x55\x71\x3a\x37\xab\x1a\xab\x8c\xbb\x9d\xff\x38\xeb\x3e\x9f\xfe\x67\x7a\x23\x24\x89\xce\x50\xa2\xdf\x2a\xf9\xff\x84\x8a\x22\x49\xc6\xb3\x48\x5a\xe3\x91\x7d\x0f\x45\x6c\x0f\x8b\xd0\x38\x18\xe3\x1a\xf1\xae\x26\x6c\x4a\xdb\x31\x92\x7b\xa9\xd7\x42\xe7\xfb\x36\xbc\xfe\x65\x22\x39\x93\x44\x64\xc6\xc7\x64\x0b\x75\x33\x7f\x9e\xff\x65\x5c\xdd\x7e\x82\x61\x81\xe1\x84\x72\xeb\x0f\xb6\x03\xe8\x1e\x88\x90\x31\xaa\xf5\x70\xa5\x36\x67\xd1\xee\x3d\xf5\x98\x16\x22\x89\xa2\x14\xf3\xa6\x63\xee\xca\xff\xc3\x46\xed\x68\x1e\xe9\x84\x70\xeb\x1d\x8e\xd9\xde\xfc\x5c\x15\x3d\x09\x09\x49\x83\x58\x22\xae\xf6\xbe\x8d\x30\xf0\x7c\xc6\x6a\xfe\xe7\x8b\x0c\x0d\x62\x8d\xe5\x0a\x9d\x17\x58\x3c\x76\x59\x99\xa4\x41\x12\x31\x03\x25\x2a\x9a\xda\x99\xbb\x5c\x81\x05\x07\x17\x45\x03\xae\x50\x7f\x08\x35\xf4\xf0\x6c\x03\x6e\xe1\xed\xe9\x46\x03\x49\xb0\xb8\xd0\x21\xa4\xd6\xe7\xd3\xe9\x82\x28\xea\x63\xcf\xeb\xaa\xfb\x00\x18\x5b\xf2\xe6\x03\x8a\xe6\xb2\x7d\xcb\xab\x66\xa0\x6b\x24\x29\x25\xc6\x09\xf8\x54\x81\xcc\xcb\x0f\xe0\xdd\x81\x14\xeb\x53\xed\x9a\x63\x5f\xe3\xa7\x12\x8a\x2b\x01\x31\x37\x9c\x0a\x47\xe0\x41\x9a\xb4\x3f\x0d\xe7\xdc\xc6\xa6\x0f\xfc\x08\x1e\xce\x70\xe0\xfb\xeb\xca\xa4\xa4\x21\x35\xc0\x64\x1f\xad\xaa\x6d\x39\xbe\x31\x6e\x68\x06\x88\x23\xb3\x72\x70\x0d\x1c\xdb\x95\xdb\x19\x67\x4f\x6e\xfb\x34\x14\x4a\x5b\xf6\x56\x79\x78\x1f\x8a\xa4\x48\xca\xa8\xc4\xed\x07\x13\x26\x32\xbd\x33\x8f\x4e\xc8\x42\xed\x9c\x33\xcc\x62\x51\xea\x0e\x8d\x2c\x69\x44\xa4\xe8\xa9\x4b\x23\x90\xed\x4a\xb1\xe4\x56\xc4\xd2\xbb\x2d\x51\xa8\x51\x8d\xae\xdc\x15\xe5\x7b\xb9\x3b\x55\xa5\x38\xc0\x71\x58\xcd\x91\x34\x82\x0c\x7f\xcc\x0e\x15\x16\xf3\xe2\x0f\xfe\xcb\x44\x41\x59\xd2\x98\x44\x51\x6c\x8b\xe3\xf7\xc6\xc2\x16\xfb\x04\x0e\x6a\x2f\x69\xcc\x03\xec\x7e\xaf\xec\x3e\xee\xfe\x9e\x50\x8d\xc9\xe2\xb7\x02\x93\xd0\x11\x62\x42\xd2\x44\x08\x84\x13\x99\x22\xc0\xa2\x3c\x9e\x78\xd5\x7d\x58\x2a\x8c\x01\xf0\x65\xee\x60\x20\xc3\x6b\x48\x65\x02\x41\x27\x6c\xd0\x3e\xd2\xfe\x0d\xcd\xc2\x00\xa7\x19\x4a\x1b\xbe\x21\x67\xa1\x1e\xfd\x06\x9e\x26\x88\x5f\x38\x79\x58\xcd\xb6\x7c\x05\x13\x59\x8f\x86\x8a\x80\xe2\xae\x3f\x7f\xf9\x6d\xd3\xdf\xdd\xa8\x20\x84\x64\xae\x59\x78\xea\xfe\x9a\x62\x0d\xc8\x9a\x92\x0f\xf2\x9a\xf1\xc3\x1b\x7d\x91\x32\x3d\xca\x07\x9e\xa3\x66\x0a\x9d\x6a\x49\x4b\x2a\x69\x10\x44\xce\x46\xa2\x1f\x92\x52\x99\x2a\x0c\x49\x9d\x0c\xc3\xb6\xfc\x59\xf9\x4b\x52\x29\x59\xac\xcc\x8a\xa5\x5e\xa1\x7e\xe6\xc7\x1b\x70\xe3\x76\x28\xc7\x4e\xef\x43\x7d\xd8\x34\xbc\x50\xbc\x52\x7f\xaf\x72\x22\xa9\x0a\x00\x7b\x3c\x5f\xbf\x3d\xcf\xea\xc1\x0d\x84\x84\x07\x41\xcf\x65\xa2\x5d\x89\xef\x01\x85\x04\xfe\x62\xad\x85\x84\x63\x8f\xf0\x9f\xe7\xf6\x2e\x97\xc5\xa6\x29\xab\xd1\xd6\x46\x21\x35\xba\x05\xcb\xc5\x6c\xed\xbf\x51\x10\x54\xc4\x78\x2b\x8b\xf6\x83\xf5\x7d\x59\x35\x82\xcb\x1f\x67\xff\xf8\x00\x32\x8c\xe2\xac\x82\x27\xb2\x0f\xc6\x80\x63\x19\x06\x01\x53\x4e\x58\xed\x74\x18\xc0\x20\x65\x18\x08\xc0\x80\x5c\xf2\xc3\xe1\x05\x11\xfe\xd3\xcb\x61\x48\x98\xc2\x26\xe0\xd3\xea\x79\xf9\xba\xdb\x6c\x67\x5f\x5d\xa9\x22\x24\xda\xe4\x7a\xe7\xe2\x64\x30\x3d\xee\x00\x0d\x22\xd2\x29\x09\x5a\x70\xfb\xf0\xb4\x94\xc5\x81\xf1\xa5\x9a\x7c\x96\x21\x4d\xc1\x59\xcf\x3c\x5d\x66\x52\xc2\xa9\xb9\x49\x9e\x92\x61\x24\x8c\xa4\x29\x58\xd5\x90\xf1\xab\x14\x46\x9a\x21\xbb\x73\x77\x2c\x95\xdd\x03\x5c\xe9\x61\x4a\xd1\x5a\x86\x31\x09\xb0\xb0\xb1\x06\xec\x93\x77\xf8\x52\x19\xc6\x59\x40\x0c\x25\x7a\x86\xe0\xe5\xe1\xda\x1b\xc6\x3c\x10\xa2\x8b\xd1\x7f\x31\x78\x96\xfe\xbd\x8f\x05\xc1\x1a\xc1\xa9\x7f\x52\x20\xe6\xa4\xce\xf1\xf5\x7a\x27\x1f\x7e\x4d\xc2\x09\x42\x27\x6a\x7e\xd9\x94\x47\x68\xde\x86\x80\x25\x19\x66\x6d\xf6\xe7\x9a\x6d\xcb\xff\x9e\xf3\x77\x7e\x80\xee\x39\x8c\xae\x37\x13\xc6\xf4\xa8\x06\x2b\x44\xd1\x01\x2a\xdc\x4f\xcc\x24\xe1\xa2\x9f\x7c\x78\x66\x49\x0f\x5d\x2c\xc3\x0c\x8c\x7b\x03\x57\xca\x48\x7c\xdf\x5a\x58\x7a\xf6\x95\x83\x97\x31\xe4\x4c\xe2\xb3\xc7\xbe\xf3\xab\x67\x03\xc9\x50\xa6\x36\xb7\x39\x37\x5f\xc0\x2f\xc7\xa1\x54\x29\x12\x62\xda\xa9\x6c\xe5\x63\xfa\x7d\xd2\x76\x00\xc8\xbe\x6a\xf7\x3d\xd8\x0d\xcc\x1e\x57\x81\x95\xf7\x87\x63\x39\x8e\x3e\x43\x15\xf3\x44\xf9\xce\x82\x33\x81\x99\x5e\xad\x42\x25\x35\x66\x29\xa6\x01\x63\xdd\x53\x6b\x14\xcb\xb9\x71\xe3\x21\x4c\x7b\x66\x99\x4f\x79\x61\xd8\xb3\xa3\x41\x8c\xc6\xd2\xb9\x2e\xbc\xba\x2e\x88\xb5\xed\x1f\xcf\x75\x9d\x25\xb1\x4d\x68\xee\x0c\x25\xba\xf6\x57\xaa\x35\xf7\x6b\x02\x26\x71\xed\x1a\xbe\x52\xb5\x63\x7f\x0f\xbe\x96\x05\x21\xcd\xc0\x27\xe7\x88\xbf\xb9\x85\xdc\x90\x2c\x48\x0d\xfa\xf9\x01\x0a\x78\x5f\x7e\xca\xb7\xbf\x62\xfa\x4f\x17\x34\x58\xa0\x63\xed\x80\x03\x23\xe5\x34\xc9\x48\x1c\x22\xe2\x1f\x3e\x4d\xf9\xc6\x24\x17\x0a\x4b\x9d\x7d\x5f\x5e\xc9\x48\x62\xa2\x72\x93\x69\x16\xa3\x08\x83\xd1\x84\x48\xef\x73\xe4\xea\x45\x46\x91\x76\x9e\x3b\xb5\x6b\xc9\xa8\x0a\x92\x6c\xe8\x8d\x37\x3a\x51\x18\x10\xac\xb9\x63\x0c\xbc\x34\xb9\xd3\x75\xe0\xeb\x06\x47\x21\xf6\xc9\xea\xb7\xf2\x63\xd7\xbc\xc1\xae\xe0\x47\xd8\x95\x7a\xf7\x82\xea\x06\xbb\x3b\xf7\xbd\xa1\x96\xd8\x86\x6e\x07\x36\x3d\x5a\xbe\x3d\xcc\x78\x8a\x30\x8e\x21\xa8\x71\xd3\x94\xd8\xa9\xeb\x78\x88\x92\x31\x19\x82\x4d\x4e\x66\xea\x7d\x54\x77\xb2\x63\xa2\x20\x41\x41\x0e\xe5\xc4\x3a\xc7\x4f\xee\x3a\x80\x67\x51\x9a\x20\x66\x64\xd7\xbe\xe6\x16\xb1\x7f\xeb\x4d\xb7\x1f\x89\xc3\x10\x11\x21\xbb\x0a\xde\x81\x1f\x2c\x19\x70\x78\x61\x71\x16\x61\x7d\xe0\x15\xf2\xbb\xb2\xcd\x06\xfa\x7b\x31\x4b\xc2\x04\x57\x71\x07\x55\xbf\xff\xf6\xec\xef\x58\xc2\x8c\x16\xaa\x2f\xfc\xfb\x92\x0d\x4b\xa2\x38\x89\xfd\x43\x34\xdc\xc7\xa9\xbe\x9d\x64\x09\x98\xe9\x85\xf2\x61\x65\x65\x9d\xf5\x5c\x41\xdc\x0f\xe2\xca\x3b\xd7\x7a\x81\xbb\x2b\x21\x7f\xc9\x52\xa2\x52\xd1\x67\x8b\x7d\x87\x7c\x7a\xbb\x61\x19\x25\x34\x73\x5c\x13\x04\x74\xe1\xeb\xe9\x2f\x21\x8b\xe3\x80\x77\xc1\xe4\xca\x16\xfb\x6a\x8f\xbf\x73\xe3\x92\x14\x6c\x75\xd8\xda\x2f\xff\x0e\xbc\x6a\x4f\xf8\xd4\xcd\x93\x05\x3f\x8d\x26\x71\xa6\x32\xc3\x0e\xb5\x40\x6e\x77\x3a\x1e\x1b\x86\x3d\xfe\x2c\xe3\x30\xd7\xa7\xaa\x49\x26\x98\x44\x33\x03\x57\x59\x5d\x57\xb0\x41\xef\x84\x2f\xbc\xc6\x1d\xe9\xef\x00\xbd\x25\x13\x5c\x41\x5f\x2a\xc4\x18\xc5\x94\xa3\xfb\x29\xb4\xb1\x2e\x16\xe7\x4e\x30\x5f\x32\x99\x69\xac\xef\x7c\xf7\x01\xe5\x98\x8a\x2d\x99\x0a\x3d\xfa\xcb\xc8\xe0\x8d\xb5\x65\x9e\xcb\xcd\x5b\xf9\x51\x63\xf2\x5e\xfa\xbb\x09\xc4\xd4\xc2\xda\x4d\x11\xa1\x42\x0e\xb8\x77\x6f\x9c\x03\x6f\xac\x84\x9a\x19\x8a\x5c\x53\x5d\xb0\x50\xb0\x1c\xaf\xe7\x4c\x0b\x62\x91\x83\x47\x2c\x16\x3c\xf4\xfc\x8b\x64\x14\xd0\x00\x2c\x7a\xd2\xe3\xbb\xcc\x7e\x35\x39\x79\xa2\x40\x86\x51\xdc\xdb\xde\xe6\x65\xe1\x15\x6d\xdb\xa3\x46\xcd\x38\x37\xb3\x79\xeb\x65\x96\x30\xeb\xb1\x83\x08\xe1\x28\x95\xf8\x52\x9d\xde\x78\xf1\x9d\x1f\x40\xf3\xaa\x6f\x44\x2c\x23\x1a\x30\xd5\x05\x75\x18\x23\x8c\x9f\x50\x44\x05\x43\x67\xfe\x79\xf9\x99\xf7\x6a\xe2\x11\x15\x02\x91\xf1\x18\x78\x0d\x54\x21\xdd\x00\x49\x5d\x3a\x0b\x0d\xb2\xd5\xb6\xa5\xe2\x17\x7f\x18\x22\x94\x33\xb0\xd6\x52\x7d\xc7\x04\x19\x85\x60\x92\x5d\x24\x8c\xf3\xba\xc4\x3c\xef\x2e\xd7\xfa\x76\xfd\x21\x62\x61\x80\xfd\xae\x55\x51\x9f\xb5\xce\x65\x0e\x85\x65\xb0\xfe\x74\xa2\x46\x11\x4d\x71\x3f\xc0\x07\x61\xd4\xef\xea\xb4\x1f\x76\x45\x11\xd5\xdc\xd6\xee\x9e\xa0\xe1\x8a\x37\xfc\x5b\x3d\x5e\xe7\xa2\x28\x4a\xdc\x23\xfe\xfa\xfd\xcb\x7d\x59\x3d\xf0\x51\xfe\x18\xc5\xc4\x98\x24\x1a\x5b\x22\xdb\xf3\x77\xfa\x50\xe5\xf8\x84\x31\x37\xe8\xcc\x53\x95\x3b\x3e\xed\xa6\x5b\xb3\xa2\xd4\x1a\x47\xd9\x1b\x78\x97\x4b\x98\xc3\x55\x2c\xf8\x3f\xc3\x45\x71\xb8\x38\x46\x59\x10\xa3\xf5\x4f\x1b\x6e\xbe\xda\xee\xa9\x3b\x7f\x96\x19\x2e\xa6\x69\xd2\x60\xdb\xd9\x1d\xe2\x29\x47\x23\xc5\xc7\x72\x3f\xcf\x6f\xd6\xa7\x6e\xdc\x6f\x91\x39\x4b\x62\xe4\x72\xd9\x44\xfb\xe7\xcf\x48\x82\x11\xe2\x7d\xfe\xcd\x8a\xb5\x77\xf3\x50\xc5\xd4\xd1\xa2\xd1\x08\xcf\xff\x5d\x66\xdc\xd4\xae\x05\xb7\x15\x71\x32\x80\xd3\x77\x67\x57\xda\xe8\xcf\xf6\xe4\x09\x96\x9f\xa7\x95\xd5\x78\x30\x04\xa1\x41\xaa\x15\x41\xc0\xa5\xfd\xc4\x43\x55\x7e\xe4\xc5\xfe\x89\x7f\x0e\xc9\x98\x6e\x24\x0d\x90\x8d\xd1\x6e\x90\x95\x93\xa8\xbe\x1a\x93\xa0\x6a\xee\xf1\x89\x7f\x62\x7f\x69\xe1\x35\x74\x64\x04\x11\xc3\xa8\xe6\x8d\xd7\xf3\xb2\x79\x9b\x35\xb6\xb8\x76\xe5\xb8\x32\x7a\xb4\x3a\x49\x8d\xde\x1d\xb3\x1c\x03\xff\x77\x19\x59\x6d\xb8\xd9\xe4\x96\x38\xf8\x6d\x71\xa0\x38\x52\x35\xf2\xe3\xc9\x74\xf4\x7b\xf0\x03\x19\x07\x9a\x62\x17\xdf\xd8\x4b\x5f\xbf\x14\x31\xa1\x04\x31\x42\x05\x7c\x18\x2a\x2d\x54\xef\xb9\x84\x71\x62\x1b\x93\x90\x63\x75\xc8\xd0\xf8\xad\x9c\x85\xba\xd1\x38\x88\x49\x42\x93\xac\xd7\xf0\x07\x35\x3b\xf9\x00\x2f\x26\x32\x8d\xc2\x61\x6c\x70\x2d\xb1\x28\x63\xa2\x2c\xd9\x1d\x17\xbf\x76\xa5\xc8\x8b\xbd\x11\xde\x9b\x9c\x84\x31\xd1\x99\xb0\x34\x69\x6c\xa5\x59\xe5\x82\xe1\x20\x4a\xcd\xe3\x32\x8d\x6c\x74\x23\x1e\xfd\x78\x4a\xbd\xbd\xbc\x0d\x86\xc7\x67\x90\x6e\x63\x5b\xb5\x2f\x3c\xfe\xac\x89\x7a\x56\x4c\xb3\xc4\x88\x32\xb6\x1b\x84\xa1\xf1\x8c\xd6\xc4\x38\x64\x14\x6b\xc3\x0b\x5e\xf0\xea\xf2\x6b\xec\x6e\x11\x13\x22\xa1\x83\x98\xa2\x17\x60\xc6\x51\x6a\x40\xaf\x7c\x5a\x52\xc3\x8d\xca\x04\x72\x7c\xac\xe0\xf6\x17\x43\x12\x1d\xbd\xc7\xfe\x97\xc4\x91\x4e\xed\x55\x0d\x17\xe5\x2e\x13\x88\x63\xa1\x5c\x9a\xf9\x1d\xf8\x69\x5c\x70\x8f\x13\x1e\x29\xe1\xfb\x0f\xfc\xf0\xda\x5b\x93\xe2\x84\x83\xf1\x51\x7a\x5d\xee\x16\x2f\x2b\x2f\x84\xbf\x7c\xdd\x79\xe6\xb2\x8c\x13\xe5\xad\xa7\xcc\x33\xec\xe9\x6a\x8f\x1e\x77\xa2\x13\x04\xf1\x0e\xb4\xce\xf6\x46\x45\x6a\xb2\x64\x11\xa7\x59\x80\xc1\xa1\x0b\x9e\x17\xbc\xe1\x87\xd2\xd5\x03\xe2\x2c\x8c\xa3\xc4\x1b\xc8\xaf\xaf\x44\xc9\x65\x9c\xa9\xc8\xec\xc7\xd6\x55\xd5\xf0\x83\x27\x23\x84\x98\x07\x14\x39\x9e\xed\xef\xa9\x31\x2b\xf7\x5b\x7f\xcc\x63\x40\x10\xb6\x38\x94\xff\x3d\x03\xaf\x76\xc6\xf6\xa1\xf1\x37\x8b\x43\x18\x45\xdd\x46\xe4\xeb\xd9\xe7\xeb\x37\x58\x70\x8d\x99\xbb\xa9\x64\x1b\xe0\xaa\x19\x70\x3f\xde\xb1\x62\x21\xb9\x62\xa3\x5b\xf6\x52\xe5\xfb\x1b\xde\x9d\x32\x16\x2a\x33\x2e\x9b\x0e\x9a\xd9\x99\x5f\x1b\x64\xf2\x68\xbc\x4c\x4d\x11\x79\x7e\xbe\x8c\xbe\x5a\x72\x85\x42\xb2\x75\x53\x56\x60\x2a\xbc\xcf\x48\xa2\xe8\xa7\x45\xb1\x84\x10\xed\x9e\x5f\xef\xb6\xee\x56\x40\x00\xc2\x2a\x4e\x6d\x24\x14\xbc\xca\xcb\x1a\x2d\x22\x47\x9a\x29\x83\xf3\x80\xa0\xa8\xb6\xc4\x9b\x83\x3f\x8f\x48\xb0\x97\xe0\x8a\xa0\x98\xb9\xd9\x83\x49\x90\x68\xe7\x6b\x8b\x9a\xcc\x13\xe7\x4c\x08\x83\xcc\x43\xf3\xa1\x5a\x73\xf9\xa3\x5f\x65\x4d\x08\x07\x0c\x95\x97\xcb\x7f\xbd\xf4\xa3\xb8\x84\xd8\x52\xc8\xbd\xe9\x6a\xa2\xcf\xbb\x3d\x44\x05\x41\x0e\x58\x6e\x84\x54\xda\x07\x68\x16\x14\x17\x59\x0f\x61\x99\x32\xa1\x0a\x70\xf1\x99\xbf\x3c\x7f\xdb\xb4\x2f\xce\xee\xf5\xe5\xdb\xf3\x5d\xe8\x4e\xc8\xe2\x00\x67\x68\x3b\x51\x1c\xda\xdb\x1d\x8b\xa8\x8e\xad\xc1\xca\x03\x14\x41\xbf\x82\x94\x44\x29\x13\x26\x37\x47\x31\x97\x95\x85\x92\xd4\xfe\xb8\xd2\x66\x22\xbc\x9d\x2b\xff\xeb\x63\xc9\x51\x27\xe2\xc4\x73\xf5\xe2\x83\xc3\x24\x09\x68\x6c\x32\xe5\x76\xee\xf7\xd8\x68\x32\x49\x48\x88\x13\x10\xbf\x7b\x51\x7e\x0c\x27\x49\x92\x44\x29\xed\x38\x03\x5b\xe0\xc7\x45\xd9\x93\x2f\x76\x8b\x55\x92\xea\x0c\xbc\x62\x25\x46\x29\x7e\x97\x74\xdf\x94\xc5\x09\xd2\xdf\x17\x0e\xc1\x0b\x77\x70\x70\x80\x43\x99\x70\x9a\x22\xe9\xef\xcb\x79\x5f\xcf\x2f\x7d\xcf\x71\x99\x70\x88\xb1\x10\x00\xcd\xdb\x5d\xfe\x5e\xbf\x7c\xf4\x92\x2a\x3b\x44\x04\x34\x35\xd5\xad\xa3\x31\x7a\x5d\x60\xbe\xd9\x2b\xdd\x25\x22\x8c\x74\xea\xc2\x6b\xa3\x07\xa6\xc7\x65\xf7\xe1\xb3\x15\x49\x66\xa9\xe6\xf5\x5b\x7b\x3b\x47\x47\x33\x89\x6a\xc9\xf3\xd9\x66\xb9\x5b\xbf\x6c\xdc\xf7\x48\x16\xa2\x1f\xcd\x91\x7f\xe6\xc7\xf3\x71\x7e\xbe\xcc\x79\x37\xb1\x25\x33\xd6\x34\x6e\x7a\x7d\x85\xcb\xb0\x76\x9a\xc8\x8c\x73\x36\xea\xe3\x6f\x9a\xab\x8e\x70\x22\x85\x40\x60\xd6\xce\xf8\x5f\x4c\x42\x58\x65\xa2\x62\x46\x2d\xce\x76\xfd\xeb\x7a\xd9\xae\x6a\x05\xfa\x64\x8c\xae\x46\x87\x0a\xeb\x1f\x6f\xbc\x91\x6f\x4f\x65\xd5\xe4\x23\xdd\x25\x99\xe8\x44\xc7\x36\x4c\x78\xa8\x78\xd1\x00\xf8\x87\xab\x21\xc0\xd0\x7a\xfd\xed\x75\xf1\xa5\xbd\x1f\x56\x64\xb4\xab\xe8\xa7\x41\x68\x04\x95\xf9\x81\x57\x47\x74\x8d\x1b\x25\x84\xed\x08\xe4\xba\xc3\xf1\x74\xfd\xed\x69\xc0\x62\xdc\x88\xf2\x7a\x55\x20\xcc\x95\xf8\x33\x0b\xc6\x52\xb7\x4d\x34\x79\xb1\xdf\x60\x06\xd4\x2b\x99\xa5\x24\xd0\xf8\x96\xaa\xff\x37\xa1\xd4\x9d\x88\x26\x61\xa7\x5a\x85\x11\xda\xe9\x90\xfb\x1c\x20\x25\x61\x2c\x69\x0f\xa5\xad\x06\x2f\x41\x4a\xe2\x18\x2b\x46\x0e\x73\xfa\x94\xdb\xf8\x31\x9d\xee\x9f\xa4\x44\xa4\x08\xf9\x79\x5a\xbd\x2e\x5e\x06\xab\x58\x1a\x51\x1a\x76\x16\x66\x9b\xfc\x4f\xb3\x17\x8c\x6e\x6a\x44\xe3\x44\x20\x87\x08\xbd\x7c\x1d\xb6\x7c\xfa\xdb\xa2\x2c\x61\xda\xb9\xbb\x0d\x22\x3b\x3b\x20\x61\x89\x74\x8a\xa4\xa5\x6e\x3e\x78\x05\xbf\x9a\xb7\xcc\x08\x63\x0f\x1b\x2c\x69\x02\x0c\xa7\xe8\x06\xeb\x0c\xe7\x0a\x16\xed\x9c\x86\xca\x09\x64\x0c\x9f\x70\xaa\x8c\xed\xa2\xe1\x23\xb8\xcb\xcc\x18\x73\x16\x86\xa6\x5a\x5b\x23\xd4\x51\xfe\x58\x0d\x05\x36\x64\x9a\x49\xa3\x79\x51\xa3\x6d\x4d\x01\x6a\x71\x91\x07\xb8\x5a\xac\x52\x4e\x02\x0c\x77\x8d\xdc\xeb\x60\xbf\x4b\x79\x9c\x61\x66\xd1\x86\x5c\x1e\x93\xe2\x7e\x0a\x4f\x0c\xe8\x59\x84\xb4\x29\x37\xf8\xb1\xd1\x4f\x10\x19\x33\x0d\xef\xd3\xe9\xd0\x61\x7f\x7e\x9a\xaa\xa5\x32\xa0\x22\xec\x6b\x68\xcd\x2f\xab\xf1\xab\x21\x45\x8a\xe8\xcd\xbb\xf9\x6a\x7d\xcd\xc8\x91\xa9\xd4\x49\xd4\x59\xa1\xf7\x04\x94\xdd\x4f\x57\xc4\x48\x90\xb5\x49\x4c\x53\x1e\x9f\xca\x0e\x90\xdf\x87\x19\xcb\x14\x92\x10\xa3\xc2\xba\x7d\xc5\x96\xce\x8c\x41\xa6\x1a\x18\x32\x7c\x45\x59\xfe\x70\xd3\x39\x0b\x52\xc0\xc2\xea\x1d\xff\x28\x7e\xf3\x7f\x14\x19\x4f\x7b\x2e\x10\x03\xb5\x82\x7f\x87\xff\x19\xcf\xf4\x7f\x93\x4e\x4e\xa5\x8f\x88\xc9\x48\xc6\x79\xe8\x36\x95\xe3\xb9\xaa\xf8\x1e\xda\x67\x32\xc4\xcb\x66\x44\x2a\x5c\x6f\x6d\xbc\x05\xc5\xfe\x9c\x17\x63\x41\x89\xc1\xed\xca\x88\xe6\xb8\x21\x22\xec\x3d\xdc\x71\x94\xc0\x78\xe0\xf5\xb7\x9a\xef\x81\x06\xc1\xbc\xe4\x95\xf2\x57\x49\xb9\x40\xc0\xe8\x03\x3f\x82\x73\x84\x1c\x3e\xf7\x2c\x0c\x28\xae\xea\x0e\xb1\xea\xab\x36\x19\x63\xc6\x4e\x1b\x6b\xcf\xc7\x7c\xe4\x5f\x69\x07\x25\x2c\x40\x59\x62\x55\x1e\x79\x3e\x40\x2f\x66\x49\xc4\x8d\x9f\x96\x71\x1a\x76\x7f\x4d\x59\xe6\xb1\x5e\x58\x1f\xcb\x9b\xcb\x8b\x1e\xdd\x99\x24\xd3\x0e\x95\xed\xa0\xf0\xd5\x24\x8f\x40\x66\x09\x68\xd5\xf9\x72\xad\x64\xd9\xf9\xbb\x0f\x6f\x5d\x62\x9b\x88\xdf\x9f\xb7\x83\xe5\x28\xcb\xa8\x11\x49\x7e\x6f\xc3\x0b\xec\xb7\xf8\x5f\xcb\x13\x9e\x3a\x28\x17\xaf\xae\x1c\x2e\x65\x26\x62\x8a\x89\x62\x1b\xc6\x57\xbc\xda\xf0\x83\x8b\x0b\x32\x19\xf1\x0e\xb9\xd6\x3e\x01\x93\x99\xba\xa3\x32\x25\xba\x4b\x92\xee\xa0\xe1\xf9\x61\xb4\x73\x64\x2a\xd0\xc2\x50\xa3\x5e\xbe\xdf\xa1\xdf\xed\xec\xf1\xf1\xe5\xfb\xec\x79\xe1\xba\xb8\x99\x62\x11\xa6\xb6\x47\xec\xe8\x9f\x56\xc5\x77\x0f\x26\xcc\x34\x8f\x11\xa4\x20\x72\x65\xfd\xa7\x06\x92\x2d\xbd\xf5\x8e\x13\x22\x43\x2b\x4e\xde\xa6\x87\xfd\x07\xc9\x49\x92\xa0\x33\xee\xe3\xea\xf9\xeb\xf0\xf2\x39\x11\xa6\x3a\x84\x16\x57\xf2\x0d\xd4\xf9\x30\x9e\x61\x9c\xc8\xc8\xc9\x50\x3c\x97\xaa\x6f\xb0\xe0\x07\x70\x29\xfb\x9c\xdd\xe5\x88\x73\x23\x39\x01\x93\xa6\xa2\x7c\x83\x23\xb6\x49\x4e\x03\x23\x59\xb3\xc3\x7b\xbc\xce\x3f\xe1\xf0\xad\x50\x50\xbd\xe6\xfb\xb7\xd1\x06\xc0\x29\x31\xf4\xe3\x79\xde\x3c\xe5\x87\x43\x07\x5e\xf6\x27\x8b\xb5\xee\x40\x9f\x0f\xe7\xf5\x5b\xc5\x7d\xeb\x8d\x87\x2c\x40\xb1\x48\xf4\x71\xeb\x34\xc0\x86\x0f\x8c\x87\xc2\x38\xfc\xd6\xc6\xb5\x76\x59\x55\x65\x35\x60\x90\x0e\x5f\x67\xce\x52\x85\x1a\xeb\xcd\x14\xa6\x6c\x78\x1b\x99\x62\x42\xf4\x02\x01\xd4\xd4\x36\x1d\xab\x72\x94\x5c\xf2\x48\x04\x11\x3e\x4d\x30\x95\xf8\x6e\xb2\xf3\x48\x84\xf8\xa0\x8d\xb6\xdf\x13\x2f\xf8\x7e\x9c\x07\xf2\x58\x73\x7c\xa9\x9f\x4b\x63\xe5\x7d\xf4\xe0\x74\x9e\x68\x8a\x78\x82\xc7\xfc\x1d\x4e\x00\x95\x5d\x55\xae\x94\xaf\xff\xfd\x9f\x41\xc6\xc3\x53\x42\x0c\xc4\x13\x97\xba\x97\xe2\xaa\x7a\xc6\xd3\x98\x31\xdb\x1d\xfe\x2b\xd6\xc3\xe8\x26\xa6\x42\x46\xd4\x7b\x92\xae\xfc\xec\x48\x81\xe2\xf4\x47\x86\x58\x7b\x21\xb0\x69\xca\xca\xd3\x8c\x24\xcf\x88\xc2\xfe\x88\xe6\x53\x20\x06\xce\x03\xe3\x96\xea\x18\x4a\x50\xe5\x3e\x6e\xe4\x9c\x47\x61\xdc\x31\xdf\xbc\x77\xe2\xcf\xb7\x4c\xce\x05\x48\x3d\x4a\x9b\x8d\xf7\x62\x0d\xd5\x7b\x5e\xec\x9f\x61\x5a\x21\xa8\x3b\x85\x0c\x08\xce\xb1\xa7\x7f\xb8\xc4\x96\xcb\x24\x43\x38\x94\x99\x40\x0b\x87\x6d\x1e\x5d\x8f\x4c\x8d\xf2\x24\x3f\xf2\x4e\xea\x58\x72\xa9\xb4\x69\x5e\x41\xdd\x2c\xde\x72\xf9\x03\x8a\x85\xcf\xe6\xb8\xa2\xcc\x99\xfc\x3e\xf2\xba\xdd\xe7\xfb\x32\xa0\x92\xab\x44\x7a\xb0\x6b\x8f\xb9\xd3\x74\x53\x46\x41\x88\x05\xa8\x13\xbf\xcc\x0e\x87\x2e\xb9\xe3\x90\x24\x71\xe2\x2b\x13\x96\x90\xe6\x44\x15\x86\x3f\x1d\x54\x40\xbd\x28\xc9\x1d\xc8\xfc\xe8\x11\xb5\x5c\x0b\x8e\xbf\xa0\x80\x8f\x27\xb8\x6e\x4a\x72\xad\x09\x76\x2f\x16\xed\x0b\x53\x1e\xf2\xca\xad\xd0\x22\x60\x09\x98\xaa\xda\xca\x79\x78\x5e\x51\xe1\xa5\x08\xd2\x34\x91\x0e\xd9\xcd\x65\x33\xd4\x53\x1e\xee\x46\x22\x90\x24\xd6\x9d\xf7\xe3\x22\xaf\xb0\xd8\xd1\xc5\x33\x82\x04\x01\xa2\x6b\x4a\xad\xe5\x1b\xb7\xb2\xb3\x93\x4f\x5a\x10\x96\x60\xf9\xd0\x92\xe9\x5e\xb9\x10\x79\xb3\x2a\x1e\xda\xa9\x3c\xa9\xca\xe5\x7e\x32\x49\xb9\x45\x5d\x9d\xea\x47\xd8\x73\x79\x71\x15\x7f\xa3\xd6\x88\x97\x4a\x83\xce\x30\xa2\x1f\xbd\x08\xca\x12\x6c\x48\x9d\x8b\xbc\x59\x36\x6f\xdd\x86\x22\xa8\x32\x85\x66\xbc\x3a\x2c\xaa\x2d\x7a\x70\xf7\xe1\x0b\x2d\xa8\xd6\x88\xcc\xf6\xd0\x88\x05\x3f\x2d\x9b\xb7\x97\x9e\x65\x9d\x1d\x19\x92\x14\xeb\x32\xe7\xc2\x55\x79\xfb\xe5\xe5\xd1\x1d\x0e\x25\x90\x81\x8a\xda\x13\x1c\xcb\xea\x62\xf2\xcc\xe1\x79\x59\x14\xa0\x85\xcc\x66\xf1\xf2\xba\xdc\x6d\x5f\x76\xdf\x57\xcf\xee\x52\x98\x36\x3a\xb1\x27\x33\xdf\xb0\x0c\x34\xfc\xa2\x48\x41\x6c\xac\x8e\x65\xcf\xeb\xf6\xea\x95\x16\x71\x10\x62\x05\x6e\xb7\x07\x6c\xd7\x0e\x0a\xd0\xd3\xcb\x80\x48\x28\xc5\x07\x74\xaa\xc0\xf0\x26\x30\x68\x99\xb9\x57\x43\x24\x21\x45\x3e\x6c\xcf\x58\xda\x1f\x52\x0a\x75\x53\xe6\x87\x33\x2c\xde\xf2\xd3\x83\x37\x0b\x96\x22\x8d\x24\xd6\xaa\x2c\x3d\xa7\x1c\x09\x5f\x48\x91\x2a\x15\x98\xda\xcc\x58\x43\x79\xb0\xd9\x88\x8c\x1a\xb3\xfd\x9d\xd9\x26\x4c\xf9\xc5\xbd\xd1\x22\x93\x80\xb2\xbe\xe5\x98\x20\x38\x7a\x54\x3c\x8e\x52\xdd\x61\x41\x26\x65\x14\xa6\x17\x39\xc1\x63\x89\x5f\x51\x94\x0d\xaf\xf2\x3f\xa1\xcf\x65\x19\x01\x61\x27\x8b\x77\x83\xdd\x47\x70\x9e\x30\x43\xe8\x2d\x4c\x8d\x65\xf4\xa8\xb9\x0a\x70\xaa\xd6\xe7\xa3\xd5\x7a\x76\xca\x48\x2e\x55\x17\x82\x50\x9c\x4b\x6e\xe1\x9e\xcb\xe6\x27\x4c\x02\x21\x28\x47\x8c\xe9\xc9\xaa\x11\x19\x72\x4f\x99\x77\x5e\xc2\x52\x88\xc4\x5c\x63\x1b\x02\x56\x39\x8c\x55\xed\xa5\x10\x4a\xf7\x63\xf3\xd9\xe9\x74\xc8\x8d\x45\xa7\x91\x8b\x1f\xd2\x4b\x84\x8c\x23\x61\x4b\x59\x27\x93\x6f\x9e\xab\xd3\xe1\xdc\x1d\x4f\x23\x15\xf8\x7d\xd2\x48\x5a\x8e\xe6\x87\x14\x61\x60\xad\x7e\x77\xb9\x2c\x77\xdc\xbb\xd7\xbb\x93\x28\x6d\xb8\x5a\x70\xe4\xf9\xc1\xe7\x14\xf6\x20\x44\xa6\xdf\x77\xb7\xfa\x75\x77\xb7\x72\xea\x67\x52\x00\x64\x08\xed\xb4\xf0\xe3\x1e\x8d\x63\x7c\xc9\x3a\x48\x31\x1d\x9c\x6f\xfd\x9b\xaa\xad\x97\xc8\xa9\x82\x5e\x2d\x78\x02\x9d\x2c\x49\x14\x04\x1d\x8b\xa0\x81\xce\x98\xd9\x0d\x48\x13\xe4\x77\x6c\x1a\x2e\xf2\x43\xfe\x27\x5e\x59\xa7\x11\x27\x25\xe1\xca\x22\x26\xb6\xf9\x01\x6c\x32\x3b\xd8\x0e\x24\x85\xd8\x3f\xb5\x9e\x15\x6d\xed\xc1\x3c\x77\xe7\x3e\x6f\x57\x4a\xaa\x8d\xd5\xdf\xce\xb5\xbf\xed\x94\x30\xa1\xfa\xe4\xf4\x91\x61\x4c\x31\x5f\xf7\xa1\x47\x3f\x25\x96\x61\x12\x4a\x47\x81\xf8\x87\xff\x63\x16\x63\x1f\xdd\x32\x87\xb0\xa2\x42\x07\x70\x0f\x19\xca\x2c\x22\xbd\x49\xb9\xfb\xc8\x9b\xb7\x9d\xe2\x57\xf2\xbd\x37\x03\xaf\x89\xed\x42\x86\x3a\x42\x40\xcd\x1d\x38\xb0\x3c\xbf\x0d\xb1\x93\x8c\x18\x1b\x0e\xa3\x80\xd3\xc0\x02\xaa\x26\xd7\xed\xb4\x06\x63\x94\xf1\xf7\x68\x74\xee\x6c\xd4\xe4\xa8\xf5\xf9\x58\xea\xfa\xbf\x67\x5e\xdd\x42\xea\xc9\x28\x20\x28\x5b\xdd\x86\x39\xf7\x3c\x3f\x6c\xda\x74\xa4\x71\x78\x8a\x76\x95\x7b\x2e\x9b\x9e\xcf\x82\x94\x11\xd5\x38\x6b\x91\x96\x68\x66\xeb\x7c\xf1\x4b\x7f\x2e\x44\x49\x84\x13\x6e\xd7\xa6\x7f\xe7\x06\xbe\x40\x3f\xf1\xb8\xf1\x9b\x23\x19\x61\x08\x68\xfd\x76\xae\x38\xa2\xb2\x8d\xd2\x51\x92\xb5\xac\x8e\xe7\x03\x1f\x1a\x51\x4b\x99\xf2\x18\x94\xed\x7e\x61\x4e\xc8\xbe\x2f\x97\x5f\x77\x58\xc6\xf7\x63\x24\xa0\x0e\xa1\x82\xf7\x5d\x8d\x0c\x6d\x35\xcc\xb0\x65\x16\x31\x6a\x17\x0b\x0b\x23\xb7\x82\x6e\xca\xce\x99\xe9\xc7\xc7\xc3\x2c\x88\x5c\x65\xe3\x1d\x0e\xe5\x09\x2a\x83\x4d\xc2\x26\x17\x42\x21\x8e\x30\xae\x02\xb5\xdb\x2d\x2e\x0c\xdf\x8e\xa2\x82\x43\x7b\x4d\xbe\x71\x21\x45\x64\xc4\xeb\xa0\x79\x73\x66\xd9\x77\xe7\x76\x0e\x74\xbd\xbc\x76\x0c\xd2\x24\xe7\x0f\x77\xfe\x4f\x4a\xa1\xd6\xc9\x4a\xc2\x81\x17\xea\xbd\x5e\x54\x25\x6f\x72\x17\xdc\x49\x19\x9a\x4d\x0a\xa9\xbc\x4f\x65\x01\x97\x6f\xa7\x6d\xf9\xfd\xad\x3c\xc0\xbd\x31\xad\x1c\xfe\x44\x45\x35\x8a\x3e\xec\x4c\x83\x7b\x76\x38\xac\x79\xbb\x4c\xbd\x82\x61\x04\x61\xb8\xe3\xdc\xad\x6d\x00\x65\x3f\x0a\x89\x71\x0e\x37\x81\xac\x71\x30\x70\x6b\xf3\x88\x7a\x33\xba\x9d\x00\x44\x19\x19\xe3\x8f\x0e\x2b\xe4\x49\x2b\x52\xb3\x0c\x1f\x75\x5e\x3f\x20\x69\xd2\xff\x3d\xd3\xa8\x54\x80\x2f\xb9\x0f\xbb\x9f\xba\x2e\x94\xd4\x40\xa2\xa4\x13\x06\xf1\x85\x39\x3b\x73\x55\x10\xc6\xd8\x1d\x3b\x41\x95\x97\xaa\x4f\x88\x52\x41\xc8\xc3\x0e\xb9\xb2\x52\xc8\x40\x5b\x35\x70\x05\x05\xf6\x39\xde\xf0\xa2\x14\x09\x13\xac\x89\x3c\x96\x7b\x07\x72\x9d\x44\x2e\x2a\x9a\x40\xea\xd6\x82\xf0\x17\x7f\xd2\xfe\x63\x51\x54\x33\x15\x4e\x10\xd1\x06\x0b\xbb\x0a\x49\x82\x70\xd1\x2f\xfc\x1d\x06\xa0\x43\x15\x12\x40\xd8\x8b\x49\x5e\x0e\x87\x2b\x39\xa2\x61\x4c\x92\xba\xca\x96\x0a\xad\x76\xab\x13\xe5\xb8\x83\xd3\xa1\xbc\x8c\xca\xe2\x2a\xd4\x21\x2e\x40\x0a\xb0\x02\xe4\x9f\xb8\x3d\xcc\xa8\x31\xb3\xff\xfa\x7b\x1a\x04\xc1\xe0\x87\xb1\x08\x62\xa7\x61\x73\xce\x55\xbd\xc9\xff\x04\x7f\x2c\x35\x91\x81\xe8\x40\x3e\x5d\xa4\x64\xc7\x44\x81\xc0\xc7\xf4\xdf\x33\x6f\xa0\xa2\xee\xa3\x71\x60\xd6\xd7\xbe\x8a\xf1\xe0\x86\xc6\x69\x06\xa6\x44\x71\x38\xec\x0e\x5c\xdc\x2a\xa9\xab\x58\x28\x07\x5e\x30\xe5\x6b\x87\xb3\x9d\x5f\x8c\x58\xc7\x8d\xcd\xc1\x7e\x3c\xa1\x21\x33\xe2\xe6\x0d\x7a\x86\x4c\x89\xd8\x8e\xbe\x31\xa1\x82\x44\x3d\xda\x1c\x28\x4c\x57\xae\x09\x33\x2a\x49\x09\x22\x5b\xda\xc5\x7c\x65\x3b\x12\x0b\xee\x24\x89\xa4\x4a\x64\x8a\xee\x0e\x26\x71\x6a\x9f\x7d\x57\xd8\x54\x89\x62\xa8\x6b\x9f\xd7\xbf\x43\xfd\x3d\x2f\x8a\x2e\x19\x56\x29\x35\x75\xe1\x99\x5f\x6f\x55\x1a\x11\x84\xad\x3f\xad\x9e\x0d\xc8\xc0\x1f\x48\xa4\x01\xdd\x9f\x4f\xa8\x60\xbe\x35\x46\xc5\x6b\x9e\xdf\xc8\x5d\x54\xaa\x4c\x45\x42\x9c\x2f\xb3\x42\x79\x3e\xd9\x78\x77\x1d\x7e\x28\xa3\x11\x76\x2e\x78\xdd\xc6\xd1\xbd\x59\x92\xc5\x86\xe4\x60\x62\xf4\x5d\x35\x08\xd2\x55\x96\x12\xec\x88\x3c\x5d\xc4\x60\xe5\x57\x3c\x24\x98\xaf\x3c\xf8\x10\x4b\x71\x26\x18\xf1\x8d\x3b\x0b\xb9\xb8\x71\x0d\x9c\x0b\x93\x38\x55\xf0\x9e\x97\xe7\x1a\x1f\xae\x3b\x91\x08\x12\x4c\x4e\x10\xb6\x8d\xc9\xf8\x04\x9e\x53\x09\x22\x9c\xbe\xa4\xc9\x2c\x26\xf1\x48\x4a\xa4\xa9\xf5\x56\xb4\x54\x84\x49\x02\xdc\x70\x49\x11\xca\x48\x5d\x2d\xca\xa2\x6e\xaa\x33\xc2\xb9\x06\x03\x64\x06\x08\xa1\x3f\xc1\x7e\x0f\x6a\xb9\xfd\xd2\x35\x6c\x94\xd4\xa1\x55\xbd\x39\xe4\x70\xae\xea\xdd\x09\xaa\x1d\x78\x50\xba\x52\x49\x84\x3b\xd5\x66\xbb\x1c\xbc\xca\x2a\x8b\xb0\xcb\xeb\x6c\x4a\xa7\x85\x2a\xbb\x40\x55\x29\x61\xf2\x11\xd1\xae\x1a\xb0\x79\xcb\x1b\x74\x3e\x3b\x94\x95\x5f\x85\x95\xca\xf0\xb7\x54\x56\xf0\xcc\x4b\x19\xf6\xfc\x42\xa5\x02\x12\x61\xaf\x7d\xd7\xcb\x0d\xae\xcc\x6b\x07\xd7\xaf\x43\x16\x75\x6a\x1a\x03\x6b\x9e\x69\x39\x3d\xf7\xb9\x24\xd6\xa9\xab\x6c\x22\xb0\xeb\xaa\x13\xab\xb4\x32\x8e\x91\x47\xac\x2a\x1e\xa1\x68\xee\xbb\x4e\xab\xd2\x90\x60\x4c\xa2\x79\xdd\xcc\xcf\x97\xbe\xe6\x05\x10\x95\x22\xe0\x61\x73\xe4\x55\xe3\xa6\x25\x50\x1a\x90\xbe\xea\xe3\xaa\x18\xc5\x42\x40\x35\xe0\xf2\xbb\x38\x40\x59\x8f\x0f\x86\x41\x8a\x85\x1f\xae\xd4\xf2\xda\x0a\xcd\x0d\xa2\x06\xde\xb7\x87\xc6\xf9\x26\x0d\xb6\x16\x08\xb3\x14\x43\x8f\xd7\x5c\x29\x5f\x2c\x86\x50\x19\xd3\xfc\x1a\x0e\x7a\xa7\xc0\xcc\x35\x77\x90\x65\x1a\xeb\x19\x1c\x23\xa9\x79\x87\xc8\x06\xa6\x53\x24\xce\xae\xcb\xef\x5f\xaa\x87\x03\xf7\xc9\x1b\x44\x89\x88\x2c\x51\x6d\x0d\x05\x3f\xe4\x7f\x7a\x0d\xdf\xdb\x13\x09\x22\xc1\x31\x68\x41\xa6\xa8\x95\xc3\xb7\x87\x62\xda\x6b\xc6\x23\x79\x4d\xdd\xe7\xe3\x9a\x20\x24\x11\xc1\xae\x21\xe2\xbf\x50\xdb\x59\x0e\xfd\x5e\xda\x21\x12\xeb\x5f\xeb\xd7\x25\x86\x9b\x9b\xe5\xe2\x05\x55\x6f\x7e\xdf\x6d\xb6\xb3\xd7\xad\x1f\x67\x19\x93\x58\xa3\xdb\xf4\xca\x81\xa3\x22\xf3\x70\x3d\x81\x34\x08\x50\x1e\xee\x5c\x43\xb5\x2b\xb5\x76\xae\x0f\xfe\x70\x64\x44\x5c\xce\xf9\x41\xb5\x61\xa3\xf5\x89\xea\xbf\x80\x90\x86\x1a\x79\x07\xa6\xd4\xb4\x2c\x54\x3d\x1b\x2d\x26\x90\xa6\x11\x40\xa7\xbc\xb9\x73\xd8\x1d\x3e\x82\xc5\x40\xc6\x42\x6c\xa8\x0c\x0d\xf7\x48\xe4\xe6\x43\x66\x83\x3d\xac\x81\x0d\xac\xb6\x24\x70\x1e\xe0\x83\x3f\x96\x2a\xd7\x17\x8b\x17\x71\xee\x51\xc3\xaf\x11\xa9\x90\xa9\xb3\x90\x3c\x96\x6b\x7e\xf6\xbd\x06\x10\xd2\x78\x8c\x1b\xf4\x58\x1b\x50\xaf\xa1\xba\x76\x07\x97\x20\xa9\xa9\xf3\xab\x06\xf8\x11\xd1\x31\x6d\xd8\xe9\x6a\x16\x20\x99\xc4\xd5\x01\xf7\x05\x13\xb7\xb4\x01\xd2\x1c\xa0\x40\xbb\x54\xe5\x07\x46\x0a\xe3\x4c\x7b\xcd\x0b\x8b\x6b\x1f\x83\x31\xa1\xdd\xa2\xed\x22\xe0\x62\xa9\x81\xb7\x59\x2f\xf4\x01\xa5\x35\x5a\x93\x36\xfc\x07\x78\xb6\xc3\x9c\xcb\x1f\x7d\x5e\xc1\xf0\x72\x20\x03\x6e\xe5\x4d\x9f\xe1\xe3\xe7\x69\x14\xe8\xc8\xe8\x24\xcc\xd5\xa9\x0d\x2d\x5c\x69\x1f\x7f\x82\x8d\x72\x75\x10\x18\x83\x3a\x54\xd4\xaa\xcb\x35\x06\xbb\xbf\xb8\x83\x11\xc3\x15\x6d\xd3\x1e\xfc\xb8\x16\x57\xd1\x41\x62\xac\xe0\x71\xd3\x47\x4d\x42\x7b\x80\x5a\x71\xd4\x63\x5e\xdc\xf1\xdc\xff\x35\x33\xa5\x7d\x5d\x56\xfd\x34\x52\x53\x01\x5a\xfa\x55\xcc\xb3\xee\x06\x7c\x27\x4d\x35\xc5\x68\x70\x6d\x94\x3d\xd0\x72\xa7\x28\xc0\xaf\x29\x3a\x24\x14\x45\x16\x9e\x67\x9b\xbb\xd9\x3f\xfd\x5f\x99\x90\xda\x1b\xe0\xde\x3b\x77\x1d\xa9\xc3\x28\x40\xcb\xb6\x8f\xb7\xbc\x41\xe2\x72\x27\xd5\x36\xac\x1a\xe9\x30\xd5\x86\xee\x50\xee\xf7\x07\x58\x1f\x4a\x83\x96\x04\xb5\xe5\xfb\x6b\xb1\x40\xa9\xc3\x36\xf0\x30\xe5\xfc\x29\x43\x22\x37\x4a\x85\x08\x59\x2c\x10\x98\x37\xbc\xaf\x2c\xce\x70\xc9\x6d\x8c\xe0\x0d\x96\x2b\xbc\xbd\x9a\xd4\x0c\x20\x23\x0e\xd3\x9b\xcb\x1b\x84\x35\x1d\x71\x45\xe1\xff\x6b\x57\xe1\xce\x01\xa1\x31\x7a\x3d\xf3\x4a\xe5\xbc\x70\x51\xb4\x8e\x03\x86\xfc\x56\xb4\x55\x18\x6e\xe7\xe7\xbe\xd8\x4f\x7f\x2b\xd1\x31\x35\xf7\x1c\x2d\xb7\xf2\x3f\x91\x6d\xb7\x2d\x0f\xd0\x97\x70\xd1\x31\x8d\xf0\xdd\x7e\xd1\x1a\xf1\xdf\x76\x71\x5c\x1d\x4f\x37\x02\x2e\x1d\xdb\x4e\x93\x89\x73\xa1\xf9\xde\xc5\xb9\x3a\xe6\x89\xab\x51\x43\xfe\x0e\x57\xa1\xdb\xed\xb2\x8d\x4e\x23\xe3\xcd\x66\x24\xcd\x96\x9b\xc5\xec\xd1\x35\x95\x75\x9a\x19\xff\xc9\x1a\xb3\xc7\x81\xd4\x7b\xf7\x00\x52\xc9\x0d\xe0\xb0\x5e\x5c\x1f\xe4\x61\x14\xf2\x9e\xc7\x33\xf2\xa2\xea\xeb\x8a\xb4\xe6\x10\x62\x91\xe5\xdb\xf3\x7a\xe1\xbe\x9e\x6b\x0a\xba\x83\x50\x6e\x67\x2f\xce\xad\x75\x92\x6d\xac\x05\x33\x5b\x1d\x92\x36\x50\x02\xbd\x53\xf4\x19\x7e\x9b\x90\xca\xb2\x7b\x8f\xc7\xbc\x69\x40\xf5\xe9\x57\x5a\x12\x8e\xf5\x31\xc9\x4f\x5c\x7a\x3b\x4e\xa9\x65\x14\x1a\x93\x5a\x6f\xdc\xe2\xba\xba\xc3\xb3\xcb\x98\xe1\x92\xb7\x94\x65\x8d\x96\x9c\x6d\x78\xe5\x4e\xa2\x2c\x2a\xfa\x54\x95\xea\x2c\x1b\xb6\xf3\x5e\xcb\x52\xab\x54\xe2\x3b\xf8\x0a\xed\xf6\x5f\x16\x7f\xfa\x45\x05\x68\x68\xe4\xa8\x16\x0f\x8b\xd1\x55\x03\x8f\xb1\xef\xe5\x21\xfd\x5d\xa3\x46\xeb\x34\x31\xce\xfb\xbc\xaa\xca\xa6\x5e\xf0\xf3\xfe\xcd\x7e\x9b\x0a\x82\x40\x06\x89\xab\x3b\x03\xdc\x9f\x5d\xd9\x40\x05\x01\x33\x52\xae\x9d\x5b\x96\x61\x07\xcf\x2f\xb3\x61\x49\x47\x05\x24\x26\x91\x76\xa1\xc7\xfd\xb9\x36\x96\x04\x7c\x3c\x4a\x98\x75\x6d\x67\x94\xb3\x7b\xa4\x95\xfe\xc5\xa8\x80\x92\x10\x1d\x89\x9b\xbe\xb1\x39\x2e\xa3\x9b\xb7\xfc\x34\xe5\x06\xa6\x02\x9a\x19\x80\x77\x5e\x28\xf8\x04\x35\xbf\xb4\x2b\xd6\x14\x82\x5a\x05\x54\x50\x3c\xfd\x1b\xaf\x2d\x15\x76\xd9\x91\xac\x54\x10\x12\x86\x77\xb9\xf4\xee\x34\xee\x00\x23\x38\x3b\x1d\x0c\x7d\x38\xf3\x54\x10\xc6\x32\x35\x18\x97\x8b\x99\x49\xb7\x38\x4b\x2a\x60\x24\x54\x83\x49\xd4\x2e\xb5\x3d\x9c\x85\x0a\x18\xd7\x46\x1c\xfc\xe9\xa9\x0d\x74\xc4\xf9\x32\x38\x1c\x33\x81\xd4\xa4\xa7\xb2\x02\xd4\x6f\x28\xf3\x9f\xa9\x76\xa9\x20\x4e\x83\xc8\x91\xc2\x31\x10\x1f\xfe\xf6\x98\x07\xb8\xa3\xb4\xab\xfd\xb9\x33\xce\xbf\xba\x82\xd1\xad\x4c\x32\x23\x4a\x76\x34\x02\xb6\x13\xfa\xea\x2a\x48\x83\x14\x59\xb5\x86\x47\xfd\xd4\x26\x19\xfc\x30\xd8\xf1\x54\x90\x52\x4f\xe6\x79\xc8\xd5\x8b\xb6\x05\x2a\x0b\xe7\x52\x41\x9a\x1a\x5b\x04\x93\xa8\xbc\xf2\x42\x95\xc7\xfb\x7c\xff\xd6\xd0\x3b\xe0\xcd\xdb\xa4\x70\x69\x9b\x7f\x10\xee\x78\xa4\xeb\x1e\xf0\x48\x05\x19\xc4\x0e\x4e\xfa\x74\xae\x9b\xcd\x8f\xfc\x34\xe5\x24\xe8\x77\x07\x15\xf0\x84\x21\x6b\xf3\x01\x06\xbd\xff\xf6\x80\xa1\x93\xb4\x77\xce\x4e\x27\x5b\x5d\xed\x86\xa8\x54\x05\xbd\x6a\xf3\xae\x86\x66\x87\xd3\x6b\x77\x2e\xf8\xb9\xbb\x0d\x22\x4e\x12\xe6\xb8\x75\x58\x40\x1d\x5d\x91\x80\xcc\x28\x67\x95\xda\x3b\xb8\xbd\xc2\x3b\x14\x67\xb8\x1e\x2c\xdb\xd7\xb2\xdd\x2b\x7e\x5b\xcc\x36\x5f\x7a\x31\xb2\x0a\xa4\x20\xc8\x92\x37\xeb\xbd\x89\xe4\xbf\xad\xd7\x8f\xbf\xbb\x01\x4a\x25\x48\x06\x15\xd0\xec\x78\xaf\x6f\xa0\x02\x88\x22\xbc\x11\x35\xd7\xd0\x5c\x9e\x4a\x05\x2f\xfe\xb4\xa0\x03\x9f\xf1\x7f\x2b\xea\xd2\x04\xe9\xfe\x3e\xb4\xbb\xb9\xdd\x24\xde\xf8\xf1\xd4\x2e\xe1\x43\xbf\x6b\x33\x8e\x04\xa9\x44\xa1\x5e\xc3\xf9\x9a\x00\x59\x2a\x12\x64\x1c\x2c\x3a\xd9\xd2\x71\xdc\x01\x1e\x07\x3d\xda\x42\xbb\xc7\x4c\x76\x08\xed\x70\x12\x0a\x24\x16\xac\xf9\xc5\x69\x6f\x4c\xae\x49\x84\x12\x9a\x3a\xd1\x3a\x13\xa5\x2c\x0d\x27\x7f\x38\xdb\x09\x0d\x03\xc2\x7a\xd2\x42\xfc\xb3\x57\x6a\x55\x84\x5a\x85\xd1\xd3\x81\x5f\x26\x2d\x2f\x47\x67\xd3\x12\x81\x46\x2f\xcf\xcb\xdd\x7c\xf5\xf8\xb8\x7a\x79\x76\x17\xca\x82\x24\x36\x6f\xec\x07\x54\x12\x75\x7c\x10\xc9\xd9\x7f\xeb\x09\x8b\x3c\xe9\x6b\x25\xcb\x76\x23\xc4\xde\xf2\xf2\xda\x48\xc5\x7d\x40\x67\xf8\x62\xb8\xe2\xfb\x4d\xf4\xcd\xe0\x6b\xa2\x20\xc0\xc5\xd7\x48\x35\xbc\x9c\xfe\xe2\xaa\x22\xc1\x90\x77\x07\xc7\xbc\x7d\xf5\x0e\x07\x4b\x9c\xc9\xa1\xde\xc0\x4d\xc0\x8f\xfd\x70\x4c\x42\xac\x0e\xb4\xfb\x8b\x69\x36\xfc\xe2\x8f\x48\x2c\x82\x9e\x6b\x30\xa2\xc9\x97\xd1\xb3\x89\x79\x8c\xa0\x2e\x13\xd2\xfa\xb7\x74\x2a\xff\x50\x24\x16\x29\xbe\x6a\x6d\xca\xb2\x13\x5c\xfe\xd8\x1d\xcb\x02\x2e\xee\xcb\xd2\x50\x60\xc0\x53\xe3\x25\x63\xcd\x9c\xfa\x63\xcc\xd8\xf4\xcc\x7a\x7c\xfa\xc1\xfd\xca\x28\xc1\x70\xf5\xc8\xab\x1f\xdf\x6a\xa8\x66\xb5\x63\x21\x0f\x27\x5d\x16\x07\x06\x62\x61\x37\x42\xd4\x05\x9b\xc6\x3e\x2a\x92\xf1\x2c\x33\xe2\xd2\x58\xbb\x79\x05\x2e\xbd\x33\x93\x22\x3c\x14\xce\xfa\xf2\xe5\xdc\xc8\xf2\x38\xd4\x3a\x51\x44\xb0\x48\xd8\xdd\xde\x34\x94\x7b\x3c\x0e\x45\x44\x14\x63\xe1\x63\x0b\x75\x33\x85\xc7\x98\x54\x36\x51\x44\xa8\x2c\xb6\xdf\x8a\x9d\x83\xeb\x40\x49\x11\x01\x0c\xab\xac\xaa\x5d\xc9\x51\xb8\x5c\x13\xe6\xbf\x17\x22\x43\x76\x05\x79\x2e\xf2\xb2\xbf\x88\x11\x19\x10\x5c\x4e\x6a\x64\xa9\x5b\xfd\x88\x59\xa1\x16\xfc\x70\x40\x84\xf6\x4d\x82\xea\x2d\x91\xab\x29\x69\x34\x45\x64\x48\xb0\xb4\x7b\xe8\x62\x23\x22\xb3\xd4\xbd\x58\xce\xa4\xe6\x5a\x14\x72\x74\x1a\x1e\x87\x36\x95\x59\xf9\xc7\x22\x21\x08\xb5\xc7\xfc\x19\x3e\x81\x69\x78\x75\x76\x47\x6e\xed\x00\xeb\x9e\x55\x9f\x0e\xf9\xd5\x5b\xe2\xc6\x28\xcd\x03\x57\xe8\xf1\x78\x1c\xac\x6d\x8e\xe6\x96\x4e\xcd\x5a\xfd\x5a\xd6\x6f\x9c\xf7\xa8\xb5\x8a\x06\x81\x36\x4e\x0c\x5e\x1e\x72\xf0\x25\x34\x20\x51\x16\x3b\x20\xac\x99\xdf\x7d\xc8\xcc\xf4\x8b\x4b\x03\x4a\x99\xd7\x45\x58\x38\xe1\x19\xef\x7c\xa6\x68\xc0\x52\x84\xc8\xd7\x87\xdc\x69\xf9\xfc\x4f\x87\xc3\x9a\x38\x61\x9a\x3a\x1b\x29\x0c\xf1\x9d\xba\xa7\x49\xca\xba\xbd\x9b\x92\x38\x8a\x3b\x24\xcc\x63\xd9\x99\xb2\xff\xd2\x1f\x95\x45\x4a\x3a\xea\xbd\x6b\x90\x0e\xbf\x91\x86\xc6\x7b\xad\x38\x1f\x35\x22\x74\xdd\xdf\x59\x82\xee\x74\x75\xbb\x58\xb8\x32\xd0\xf9\x0a\x0b\xae\x28\x4d\x41\x04\x43\x0d\x12\x03\xf6\xbd\xcf\xe1\xa0\xea\xf1\xd7\xf1\x10\xb1\x8c\x47\x5e\x9c\xf9\x61\x28\x8a\x30\x1a\x09\x14\x1b\xb8\xf3\xed\x62\x96\x57\xee\x67\x85\x19\x45\x34\xf4\x81\x37\xf2\x6d\x58\x10\x6d\x0f\x2a\xaf\x16\x7b\xb8\x95\x59\x2b\xca\x02\x2f\x01\xb4\xfc\x3c\xb5\x91\x4f\x71\x7b\x6c\xc8\x40\x8e\x99\x93\xbc\xd8\xe7\xa2\x4d\x19\x6b\x68\x54\x5e\x8b\x73\x55\x63\x35\xf8\x26\x9f\x52\x51\x4c\x01\x7a\x94\xba\xfb\xb2\x82\x7c\x6f\x5a\x79\xb5\x25\xab\x5c\x05\x6b\x23\x81\x16\x45\xe3\x24\x40\xf7\x11\x04\xda\x1c\xa0\xee\x6b\x81\x29\x1a\xa7\x31\x82\x08\x4d\xcf\xc1\xff\x35\x33\x3a\x5b\xf3\x03\x97\x3f\xd6\xc0\xab\x43\x6f\x7e\x26\x81\x54\x46\xce\xbb\x69\x6f\x45\x3b\x7b\x5f\xc7\x7c\x26\x45\x13\xca\xe2\xd4\x2e\xc3\xff\x3d\xe7\xfe\xd4\x49\x96\xe0\xa6\x77\x9f\x17\x9d\x5f\xfb\x95\xbe\xad\xa2\x89\xd0\x3a\xec\x95\x32\xda\xc7\xbe\x2c\x50\x9c\x37\x1f\xcb\xe4\xba\x8f\x40\x86\xd5\xaf\xcd\x72\x3d\x7b\xed\x2c\xa3\x15\x4d\x49\x88\x2f\xf2\x2e\x37\xba\x9f\x9e\xc0\x32\x2b\xd4\x13\x34\x6f\xe5\x0d\x65\x2a\xf7\xf1\x08\xa4\x51\x2a\x81\xd5\xe2\xa5\x3e\x81\xcc\x1d\xd2\x52\xd1\x8c\x06\x26\xab\x34\xe6\x44\xa8\x4c\x85\x9e\x74\x57\xcb\xc0\xf0\xfe\x64\x61\x84\x3e\xea\xb3\x76\xdf\xbc\x2f\xab\x0e\xf3\x71\x75\x79\x3f\x11\x39\x54\x34\x63\x31\xb2\xda\xf4\xb9\xb9\x83\x77\xac\xd8\xb9\x23\x91\x46\x28\xe9\x91\x7f\xde\x3d\xcc\x9e\x96\xfe\xef\x49\x68\x7a\x67\xed\x37\xff\xba\x5a\x0f\x1c\x10\xc7\x67\x17\xc6\xd8\xa0\x2a\x0f\x07\x94\xfe\x1e\x8c\x4b\xaf\x90\xa1\x8a\xf2\x48\x19\xa5\x2b\x28\x9a\xa1\xcf\xb3\x1b\x90\x04\xce\x75\x70\x26\x9b\x33\x4a\x57\xf9\x63\x99\xc0\xc9\xb1\xab\x30\xb5\xb9\x46\x0d\x4e\x7e\x23\x4f\x5c\x5b\x7f\x93\x2b\x4f\x79\x1d\x5d\x89\x48\x09\x51\x1d\x66\xf7\xb5\xd3\xca\xf7\xdf\x2e\xb8\x06\x33\xc4\xff\x49\x06\x1c\x93\xb6\xd5\x40\xa1\xb0\x33\x76\xbd\x19\xdc\x51\x19\x85\xbc\x2f\x0a\xb8\x33\x8d\xc8\xd1\x20\x09\x18\x8d\x3c\xc2\xb1\x2c\xea\xbb\xaa\x3c\x9d\x50\x54\xf3\x0d\xbe\x97\xd5\xc1\xbf\x33\x2a\x92\x61\x32\xe0\xfb\x0f\xe2\x28\xaa\x64\x84\x9c\x99\xfb\x0a\x41\x24\xb3\xb3\x6c\xc6\x8c\x99\xe1\xe4\x53\x56\x51\x79\xfd\xfa\xfc\x30\x7a\x6f\x35\xf0\xcc\xf4\xd8\x50\x47\x4a\xf5\xd8\x47\xa3\x5f\x1f\x06\x54\x60\xa3\xe9\xdb\x69\x8f\x9e\x1f\x7b\x28\x1a\xbb\xf9\x5c\x77\x38\x55\x18\xc4\x3a\xf4\x85\xe7\xf6\x6e\x0c\x41\x35\x6e\x54\x22\x0d\x6d\x2c\x7f\x87\x6d\xf9\x6b\xd9\xdc\xd0\xa4\x51\x6d\x34\x62\x4c\x19\x7b\xcb\xec\xba\xca\xdf\xf3\x03\xec\xff\x42\x35\x56\x85\x44\x86\xc2\xea\xf3\xb6\x41\xcb\x65\x36\x84\x52\xd8\x51\x34\x34\x96\xd5\xcf\xe7\xa6\xca\xcb\x5e\x6c\x10\xd2\x24\x35\x98\xff\xb2\x8d\x86\xef\x73\xed\x2a\x63\x2a\x0c\x13\x81\x00\xa8\x03\xaf\xf6\xd0\xf5\xa6\x55\xc8\xa2\x14\x93\xb5\xbb\xf2\xd0\x5f\x83\x43\x16\x0b\x15\x5b\xb5\x5d\x7e\x30\x3a\x34\xa3\x1f\xc2\x44\x82\x09\xd0\x23\x7f\xe7\x96\x92\x3b\x1a\x11\x31\x81\x9e\xe6\xba\x34\x4a\x0e\x9d\x46\xbf\x0a\xa3\x28\x0d\x0c\xbf\x41\xad\x9b\xf2\x34\x3a\xc1\x74\xcc\x1a\x46\x99\x16\x7d\x85\xf9\xc1\x9b\xef\x2a\x12\x61\xc4\x8d\x87\x82\x83\xa2\x4c\x3f\xaa\x38\x20\x88\xc1\xdd\xe5\xf5\x2b\xec\xcf\x07\x5e\x4d\x15\x2d\x55\x18\xf3\xc4\x48\x14\xf2\x6a\xd0\xcd\x52\x61\xac\x88\x95\x3b\x97\x97\x5b\xca\x8e\x2a\x4c\x64\x8a\xcb\xd5\xa1\x5d\xd2\x76\x6c\x98\xb2\x87\xa9\x43\x3f\xd9\xd7\xc8\xe0\x4f\x0d\x93\xf2\xc6\x09\xd3\x28\x70\xc1\xea\xe2\x5c\x37\xe5\x11\xaa\xed\xe7\x4b\x95\xef\x9f\xe4\xc7\x95\xb3\xf5\xf0\xfe\xa5\x59\x86\x7a\xc7\x58\xe4\xdb\x35\xe5\xee\x74\xee\xc1\x75\x87\x63\x33\x8b\xfa\x37\x6a\xcc\x73\xde\x34\x07\x38\x1d\x89\xfb\xe1\x3c\x48\x1d\x36\xe0\xb9\x54\x80\x5e\x49\xe3\x5b\xc7\x89\xce\x2c\x5d\x72\x0b\x9f\x03\x17\x44\x15\xf2\x08\x42\x03\x0d\xb1\xca\xae\x83\x7e\x87\x0a\x79\x62\xa4\xe8\x7f\xe7\x97\xcb\xf0\xbe\x73\x2e\x31\x5a\xb5\x16\xb7\x58\x6f\xd7\xbc\x2b\xea\x84\x5c\x0b\xec\x47\x2f\x9e\x7f\x9f\xbb\xbf\x09\xaa\x43\xbb\x22\x3f\xc3\x67\x63\xd1\x6f\xc3\xdf\x2b\x04\x41\x71\xb3\xdf\xec\xff\x05\x99\xfb\xb4\x24\x0a\xf5\xf8\x77\x7b\xa3\x47\x73\x55\x4a\x0b\x65\x22\xb1\xc3\x3b\x7b\x98\x6d\x46\x94\x25\x15\xca\x94\x60\x10\xaa\x01\x06\xa1\xe2\x08\xc2\x37\x3a\x23\x67\x58\x47\x3c\x94\x4d\x03\xd5\xc5\x4b\xd2\x4e\x6d\x25\xa1\x54\x09\x66\x98\xed\xeb\x64\xc5\xcb\x1c\x2a\x4f\x85\x2a\x48\x0d\x5f\x12\xb9\x9b\x4b\xab\xde\x39\xba\x00\x88\x19\xf6\x44\x9b\xe6\x60\x59\xb0\xee\xe3\x9a\x19\x92\x9f\xdb\x36\x9e\x06\x92\xd0\x2a\xd4\x4a\x91\x8e\x90\x35\xe9\x2c\xa0\x58\x40\x28\x36\xb0\x7f\x3f\x17\xff\xc8\xf9\x53\x7e\x33\x4b\xfd\xe9\x16\xc6\x82\x28\xc4\xa4\x6c\x56\xc0\xb1\xcc\xfb\xd3\x82\x05\x32\xc0\x92\xa2\x89\x7a\x8c\x93\x72\x59\x5d\x6c\x49\xb0\xdb\xa3\xc7\x45\x67\x46\xc2\xd8\x00\xe9\x9c\x93\xad\x9b\xe4\x8c\xc4\xde\x36\x61\x55\x5b\x51\xb7\x62\x8e\xf0\xe6\x2e\x3b\x61\x44\x29\xdc\x1e\x96\x9f\xfc\x78\x72\xa8\x12\x1f\xfa\xda\x41\x34\x22\xa1\x43\x42\xf9\xa6\xb6\xfb\x1e\x9a\x1a\xbf\x00\xae\x14\x5a\x55\x8d\x96\x5a\x46\xb3\x10\x53\x47\xa4\xce\xaf\xcb\xf2\x6d\xf4\xa6\xb1\x30\x33\x2e\xb6\x5e\xd9\xed\xfd\x96\x83\x79\x77\xd9\x21\x24\x98\xd3\x89\x81\x98\xf8\xe8\xb6\xfb\xdf\xcf\x98\xc6\x2e\xc6\x31\xc7\x9e\xb4\x03\x92\xba\x2b\x60\x91\x69\x0f\xed\xa1\x79\x38\x8f\xf5\x0e\x52\x37\x28\x53\x89\xc7\xca\x40\x75\x0f\x30\xd0\xfc\x53\x8c\x89\x28\x48\xfb\xb5\x77\x43\xe8\xd8\x96\x1e\xeb\x60\x1f\xe0\x64\x1a\xcf\xa2\xc0\x54\xde\x6b\x68\xfe\x51\x8a\x57\x64\xea\x4f\x04\x87\xdd\x2d\x88\x08\x47\x49\x02\xa3\x75\x9f\xba\x9f\x11\x51\x83\xbc\xb2\xc2\xbf\xd0\xc6\x0e\x4d\x4f\xcd\xf0\xdc\xf1\xf5\xdb\xc1\x14\xb7\xd6\xdc\x31\x99\x15\x8b\xa2\xcc\x61\x55\x76\xb2\xcc\x8b\x7a\xd7\xb3\x4a\x50\x2c\x12\x8c\x1b\x93\x36\xa3\x66\xf5\x54\x16\xcd\xdb\xe1\xd2\x8b\x6a\x7e\x2d\x0f\xe7\x23\x58\xa1\xa1\xd1\x8b\x14\x13\x65\x6d\xcd\xc6\xd1\xca\xe8\xe2\x62\x1a\x6b\x5b\x0a\x58\x15\xef\x65\x2e\x1d\xdf\x6b\xb0\xce\xb3\x38\x55\x61\xdf\x2f\xd0\xc0\xe4\x4d\xdb\x65\x78\xc2\x24\x89\x51\xfb\xc3\x00\xc6\x76\xb3\xba\x76\x52\x87\xf5\xb6\x5c\x57\xe5\x1f\x20\xa7\x85\x7b\x14\x4b\x34\xc3\x98\x75\xc1\x8b\x2f\xbc\x50\x07\xd4\xb7\x19\xcd\xe1\x94\x01\x02\x39\xdb\x5f\x99\xcb\x65\xf3\x36\x7b\xe7\xf9\xa1\x0d\xdd\xdc\x4a\xc3\xd2\x08\xb0\x36\xbe\x7b\x2b\x6b\x4f\x1d\x18\x6d\x75\xb7\xf9\x25\x8a\x65\x91\x29\x4d\x9f\x72\xf9\xc3\xd4\x94\xdd\x99\xb3\x24\x88\x2c\x3d\x6e\x79\x44\x00\xe9\xb4\x61\x4d\x3b\x92\xe0\xa6\xb6\xf9\x32\x0b\x77\x91\xb3\x8c\x55\x2c\x93\x24\x33\xce\x4d\x45\x5e\xbf\xd9\x34\xc3\x1f\xe5\xa9\xc6\xf6\xc1\x6c\xbb\x7d\x1d\xac\x5a\x9c\x6b\x22\x47\x39\x25\xd6\x1d\xf7\x15\xc0\x71\xe2\xfa\xec\xe7\x04\x68\x19\xb8\x42\xed\xa5\x40\xc0\x82\xa3\xf4\xb2\xd1\x7b\x21\x23\x69\x92\xc5\x9e\x24\xe0\x7d\x59\xd9\xdf\x38\x7a\x0c\x2a\x30\x2a\x18\x3f\xc0\x94\x04\x07\x5c\x4c\xc5\x94\xe2\x58\xd9\xb9\xcb\x2b\x90\x0d\x3a\x57\xb8\x43\x40\x00\x1b\x55\xf5\x59\xd4\xa6\x9e\x31\x3d\x19\x74\x40\xd0\xf2\xa3\xd9\xc3\xe2\xca\x54\x4e\x31\x1d\x1a\x5d\xc6\xf6\xed\xe1\x53\x21\x59\x14\xc4\x81\xf3\xaa\xaf\xcf\x47\xc5\x1b\x4e\x86\x93\x3a\x0a\x62\xe3\xb5\x7b\xcc\x8b\x75\xd9\x6c\x9c\x7f\xa3\x8a\x88\x88\x22\xb3\x92\x1e\x9a\xf1\x36\x1d\x51\x0d\xc8\x3c\x17\xe7\x8b\x67\x89\x8c\xbe\x9a\x85\x14\xdf\x01\xc9\x8b\x5b\x06\xe6\x6e\x64\x1a\xa2\xe8\xc2\xf7\x76\x79\x45\xd8\x1f\xa8\x6e\xc5\xeb\xae\x37\x62\xde\x79\xb0\x73\x8c\x73\x32\x5f\x6e\x08\xc4\xd8\xf2\xf9\x70\xae\x93\xde\xd5\x53\x45\x11\x95\xf8\x40\xe6\xbc\xce\x65\x7f\x6a\x45\x91\x85\x02\x56\x50\x94\xe7\x42\xc2\x82\x9f\x4e\x7e\xc6\x47\xb1\x6d\x16\x89\xf3\x65\xd1\x53\x4c\x9f\xec\x22\xb4\x83\x71\x45\x9c\xbf\xbc\x7c\x5d\x2d\xfd\x29\x12\x63\x34\x2f\x4a\xf1\xc4\x7f\x40\xbd\xac\x24\x0d\x5c\x24\x3f\x2e\xe4\x0e\xa6\x31\x0d\xfe\x67\x2a\x74\x8f\x62\x08\xb8\x71\x5d\xb9\xe6\x2c\xb8\x6f\x4d\x48\x18\xb5\x3f\xfc\xeb\x72\x3e\x9b\x2f\x5f\x77\xdb\x97\xdd\xd3\xec\xeb\x72\x47\xf0\x0f\x6e\x54\x4a\xd3\xc4\x90\xa8\x30\x5a\x33\xc9\xf2\x71\x42\x99\x7b\xf8\xae\x44\x69\x64\x58\xbb\x0f\xe5\x01\x8e\x7d\x7d\x6b\x15\xa5\xb1\xb0\xa6\xdf\xe6\x0a\x87\xcd\xee\xe9\x1b\x97\x05\x89\x51\xfc\xbc\xbf\x5f\x2d\x66\x8f\xbb\x5f\x5f\xb6\xab\xe7\x07\x04\xe5\xbd\xdc\xef\x9e\x5e\x9e\x7d\x0d\x2b\xca\x42\x86\xa5\xd0\xbc\x98\xc8\x83\xa6\x21\xb5\xc3\x19\xc7\x49\x8c\xfd\xad\xcd\xf6\x9f\x7e\x6a\x6f\xa1\x6e\x8c\xcf\x78\xaf\x61\xfc\xd3\x62\x78\xc4\x39\x45\xe6\x98\xc1\x07\xf2\x03\x8c\xca\x93\x91\x08\x23\x0c\x36\x94\xc5\x99\xd7\x66\x77\x74\x47\x53\x8a\x77\x09\xd1\x49\x7f\xf0\xeb\x52\xbf\x1b\x97\x99\x4a\x22\x47\xd5\x79\x0c\x7b\x06\x56\xdd\x7e\x18\x45\x69\x85\x36\x4d\x78\x29\x60\xf3\xc6\xab\xbe\xea\x81\x8a\x84\x64\xa8\x7a\x30\x87\xe6\xa5\x78\xed\xde\x19\x19\x06\x04\xfb\xf8\xcd\xa5\x97\x24\x47\x32\x36\x3e\x45\x77\xb3\x97\x75\x79\xa8\x7f\x70\x7c\x65\x56\x8b\x97\x0a\x93\xc0\x9e\x25\xbe\x6a\xd7\x22\x8c\x27\xb6\xb3\xc5\xb6\x7d\x7a\x8b\xd7\x6f\xab\xcd\xf2\x75\xb7\xfc\x6d\xfb\xda\xfe\xe9\xe5\x79\x37\x9f\x6d\xfc\xeb\x00\x94\x4a\x35\xc1\x19\x6f\xf7\xf1\x9f\xb4\x65\x86\xd7\x0b\x51\x90\x74\xb5\xbb\xdd\xa9\x77\xa9\x31\x51\x2a\xe2\x9e\xf1\xb1\xc9\x8b\xfd\xc1\xb9\x9a\xe2\x77\xb9\xd5\x61\xb8\x66\xc5\x34\x23\x78\xca\x6e\xd7\xab\x47\x8a\x40\x53\x3f\x69\xa2\xac\x15\x87\x22\xc1\x8a\xf3\x31\x2f\x8c\x59\x40\xbf\x49\xd0\x1e\x4d\xa4\x9f\x17\x1b\xae\xe1\x70\xe5\xe0\x6a\x87\x32\x16\xc4\x59\xf7\x76\xee\xda\xf4\x6d\x87\x6e\x59\x93\x10\x92\x98\x25\x66\x5d\xd8\x6c\x67\x0f\xcb\x1d\xd9\x6d\x57\xbe\x76\x18\x33\x6e\x7c\x8b\x54\xc5\xf7\x65\x81\xf5\xb9\x6d\x69\x0a\x16\xc3\x2f\x8d\x88\xc0\x17\x6c\x9b\x1f\xb1\xd3\xd0\x3e\x97\x5b\xd6\x7c\x93\x8b\x43\x1c\x31\x8a\xf9\xf3\x87\x23\x29\xb4\x7f\x0a\x71\x43\x58\x15\xaa\xac\x6a\x70\x7b\xaa\x3b\x2a\x43\xbc\xf5\xb3\xba\x86\xba\x9e\x4a\xea\x7f\x9e\xef\xc4\x71\xac\x42\xdb\xf9\x78\x3d\x57\xe7\x81\x76\x9e\x8a\xe3\xc4\x48\xa5\x9c\xf1\x8b\x65\x79\x3c\xe5\x87\xce\x2b\xb6\x1e\xac\xc1\xe9\xa4\x28\xa9\x8a\x63\x29\x75\x87\xc9\x5d\x43\xb5\x01\xeb\xfc\x4c\x26\xac\x65\x54\x1c\xab\x04\xb3\xa5\xbf\xc1\xf8\x9d\x2c\x2c\xc4\x09\x31\x91\x4b\xfd\x91\x37\xf2\x6d\x77\xea\x81\x3d\x55\x9c\xd0\xc0\x09\x7a\xde\x57\x00\x4f\x79\x81\xa6\x5c\xc3\xc7\x90\xa4\x61\x60\xc4\x6c\x1e\xcb\x3d\x62\x4d\xc0\x89\xc1\xde\xb8\x8d\x69\x44\x8c\x6b\x11\x7e\xd9\x6a\xfb\xb2\xab\x4b\xdd\x0c\x75\x58\xda\x51\x31\xe6\xa8\xff\x2a\x8b\x66\xd0\xcf\x8c\xb3\x88\x62\xb5\xc3\x3a\xdb\x3b\xf1\xf3\x6b\xac\xaf\x8a\xb3\xd4\x9c\x64\x9e\x37\xb5\xf4\x72\x7a\x2a\xce\x54\x1c\x18\xa3\x1a\xa8\x4b\x5f\x47\x8d\x33\x6d\x84\x08\xca\x76\xed\x9b\xd5\x1b\x2e\xab\x5c\xf7\xde\xf9\x4c\xc7\xa9\x9d\x00\x58\x78\x44\x6b\x16\x77\x90\x6b\x33\x1f\xf7\xd0\x38\x9c\xe2\x6b\x59\x0e\xfd\x72\x55\x2c\xa8\xb6\x8a\xb0\x75\x53\x95\x97\xd9\xe1\x30\xc8\xdf\x63\x91\x98\xc4\x19\x8b\xd5\xfb\x02\xd4\xb6\xb3\xf0\x69\x8f\x1a\xaa\xc8\x7c\xf1\x4f\xf7\x27\x19\x1a\xfc\xef\x31\x2f\x40\x61\x86\xb3\xab\xfb\x3b\x65\x2c\x53\xa3\x8b\xb8\x87\xe6\xae\x73\x7b\x26\xa1\x3b\x2c\x62\x74\xbe\x07\x87\xbf\x33\xba\xfa\xc3\x53\x28\x8d\x3f\x0a\xe1\x5a\x70\x3e\x7a\x9b\x74\x15\x4b\x00\x11\x79\x7e\x34\x52\x06\xb7\x25\xfa\x0f\xfb\x4b\x52\x34\x43\x6f\xce\xf2\xa3\xb8\xcf\x0f\x3d\x20\xc1\x44\x56\x90\x04\x91\x46\x69\xc1\xa7\xf9\x82\xd7\x6f\x83\x9f\x91\x10\xa2\x9c\x83\xf9\x4e\xf2\x42\xa1\xa2\x5e\xed\x8f\xa6\x29\xb1\x7d\x03\xc3\x26\x5c\x18\xff\xfb\x45\x0f\x70\xeb\x86\x4a\x8d\x40\xdb\xfa\x04\x46\xf7\x0b\x99\x53\x03\xb3\x95\xc1\x24\x4f\x68\x48\xf1\xbe\xaf\x0d\x2a\x6b\x5c\x13\x9c\xdc\x3d\x12\x9a\x46\xa9\xf1\x24\xad\xad\x82\x68\x73\x31\xcf\x74\x93\x2b\xd8\x96\x4f\xbc\xa7\xfb\xd9\xeb\x27\x25\x54\x84\x06\x9b\x63\xe8\x26\x58\x00\x7a\xee\x83\x60\x06\x77\x2c\x04\x8a\xb5\x22\xd4\xc5\x6c\x07\xff\x9d\x95\x26\x61\x81\xc2\xf5\xf7\xf7\xfb\x7f\xf4\x5f\xae\x24\x22\x0c\x59\x92\x2e\xdd\x16\xfc\x74\x7a\xca\x8b\xc9\x3e\x6f\x12\x07\x82\x45\x06\xbd\x2d\x7d\x31\xcd\xde\x9c\x51\x9e\x90\xb4\x8b\x27\x22\x66\x9e\x57\xdb\xd5\xec\x71\xf7\xf0\xf8\x32\x9f\x3d\xee\xee\x66\xab\xc7\xdf\x87\xa0\xaa\x24\xe6\x01\xea\xde\x58\x98\xd8\xeb\xd0\xdc\x40\x25\x09\xc9\x90\x14\x33\x7f\xf9\xf6\xbc\x1d\x7f\x38\x49\xd2\x2c\xec\x37\xe5\xeb\x3e\x38\x20\x49\xb8\x11\x03\xb5\xe0\xdf\x2a\xf4\x9f\xb3\xe0\x33\x54\xbe\xe5\xf2\xc7\xf5\xde\x9d\xa4\x71\xe4\xc8\x7d\x16\x90\x75\xe5\x80\xa0\x92\x2c\x96\x81\x73\xbd\x9b\x9d\x55\xde\x58\xdd\xc1\xe9\x89\x95\x81\xc2\xb7\xf7\x2e\xdf\xe7\x9f\xa2\x1c\x7f\x23\x8f\x05\xbe\xbb\x05\x7c\x36\x77\x80\xb5\x44\x6c\x7b\xb4\x6f\xa8\x57\x8e\xb2\x63\x45\x60\xe2\x01\xe9\x41\xeb\x28\x37\x38\x3d\x37\x65\xc8\xb1\xe0\xbe\x5a\xbc\xdc\xdc\x6e\x27\x57\xef\x44\x86\x22\x31\x5f\xe3\xb9\x62\xee\x48\x4a\x31\x19\xdf\x1d\x2d\x9e\xb8\x7c\x05\x59\xbe\xdf\x4a\xde\x13\xa9\x43\xf3\xaa\xc3\xa1\x51\xe5\xc7\xa8\x57\x9f\x40\x6c\x1c\x6c\xdb\x0b\x2d\xf6\x50\x74\xe2\xfa\x2a\x81\x84\x12\xab\x7f\x7f\x0f\x7d\x48\x9f\x29\x07\xd1\xf4\xdf\xf4\x3f\x6e\x68\x2a\x91\x1f\x09\xcd\xdb\xb6\x5c\x80\x17\xe0\x57\x09\x64\x19\x2a\x36\x99\xba\x16\xce\x31\x7b\x28\x0d\x08\x20\x8c\x67\x03\xcd\x91\x7f\x4e\x78\x9d\xa9\x34\x00\x8d\x0c\x85\x36\x80\x41\x5a\x56\x1b\x08\xf7\x2a\x44\xae\x58\x97\x06\x3a\xc6\x37\xea\xeb\xf9\x0f\x2f\xa3\xa3\x52\x92\x42\x6c\xe8\xcf\xb2\xac\xd4\x1d\xf4\x2a\x5a\xfd\x4b\xb1\x6f\xb1\x53\x1f\x1b\xfe\x04\x22\x28\x5a\x77\xac\xc3\xe7\x87\xc5\x76\xf7\x7e\xc3\xf5\xce\x8e\xa6\x84\xa1\x3a\xf4\x81\xd7\xcd\x3d\x97\x8d\x01\x0c\xf6\x0c\x11\x55\x4a\x69\x82\x34\x57\x23\xe9\x7e\x99\xb7\x09\xf5\xed\x0a\x4e\x4a\x95\xc2\x77\xc9\x90\x8f\x06\xa6\xb1\x2a\x0d\x03\x6a\xaa\x4c\xd5\xe5\xb4\x2d\x0f\x87\x79\x59\x3a\x1f\xd1\xd1\xaf\x3c\x8f\xbd\xc9\x54\x1a\x12\x63\x6d\x79\xff\x6d\x1b\xb9\x13\x26\x96\xd7\xfd\x51\x56\x3f\xb0\x46\x31\x7e\x22\x49\x2a\x98\xb6\x92\xa1\x5d\xf8\x3d\x19\x3c\xa6\x69\x98\x86\xd0\x13\xee\x5c\x76\x15\xb0\xd1\x4d\xce\x88\xc2\x74\x5f\x1b\xe4\x99\xa5\x04\x99\x22\xe5\x13\xef\x0c\x01\x54\x9a\x45\x0a\x49\x59\x27\x5e\x75\xf7\x6d\x74\x32\x19\x10\xee\x11\x41\x2b\x47\x3c\x55\x29\x4f\x12\x44\xb0\xf1\x29\xb3\x5e\x37\x06\x34\xb6\x15\x76\xbe\x22\xfb\xd8\x07\xe8\x4d\x55\x79\x53\x21\x29\x76\x1b\x8c\xe6\xe1\xf2\xbf\x84\xda\xed\xdf\xee\x07\x64\xb4\x2f\xa4\x32\x12\xd8\xf9\x2d\x2b\x05\xd5\xfa\xc0\x7b\xe7\x9d\x6a\x6a\xbb\x4f\x71\xca\x6d\x60\xe4\xe8\x14\x57\xf2\xd7\x2a\x55\x24\x72\x40\xf9\x6f\xb5\x95\x0f\x72\x87\x68\x16\x58\x38\xe8\x57\xb8\xac\xa1\xb2\x46\x5c\xf5\x50\x7d\xcf\xff\xc7\x7d\x8c\x31\x7c\xb9\x2b\xfe\xf1\xad\x06\xdc\x23\x87\x97\xa3\x54\x88\xe7\xb5\x4f\xcf\xba\x53\xb9\x5a\xa6\xfb\x76\x08\x24\x35\xf6\x66\x4f\x08\x21\xb2\xa4\xe4\xd9\xa0\xf0\xe3\xb5\x32\xef\x66\x2f\xf6\x96\x6f\x0a\x7e\xda\xbc\xf9\x60\x28\x85\x24\x41\xfd\xe4\xfd\x98\x56\x33\xfe\x77\xf8\x23\x35\x8d\x59\xe0\xb4\xb9\xaf\xfc\x47\x47\x63\x43\x81\x3f\xc2\xc9\x5f\xba\x02\xd6\x64\x23\x2c\x0b\x94\xe1\x93\x6d\x5f\x5f\x9e\x57\x56\xb2\x53\x65\x24\xce\x30\xcb\x98\x5a\xfc\x27\xb7\xa9\x8c\x00\xc5\xd4\xe9\xe9\xd7\x27\xca\x0c\x23\xac\x5e\xf0\x93\xa7\x01\xab\x8c\x42\x84\x1b\x4a\x7e\xba\x38\x98\x76\xc6\x62\x8e\xb0\x83\xa6\xe2\xf5\xdb\x18\x9a\x9c\x31\x08\xa3\xbe\x44\x98\xe9\xf9\x0f\xb7\xfa\x8c\x69\x62\xcc\x9b\x0f\xbc\xd1\x65\x75\x7c\x2c\xf7\xe5\xb5\xd6\x9d\x1d\x1c\xc5\x02\x5f\x6a\x13\x37\x3d\x20\xcc\x71\xaa\x66\x99\x45\x49\x88\x0c\x84\xf7\x2f\xbc\x6e\x03\x79\x35\xbd\x4a\x64\x11\x37\x82\xf5\x4f\xf9\x9f\xe7\x5e\xdd\x22\x8b\xad\x45\x87\x09\x92\x5c\xe3\x77\xb6\x58\xfc\x1c\xda\x98\xc5\x20\x63\xc7\xd5\x57\xc7\xbc\x40\x8d\xce\x9e\xb1\x89\xc7\x5e\xfb\x19\x9e\x25\x91\x71\x8f\x3e\x7e\x0e\x67\x76\x96\x24\x12\x55\x87\x3a\x4e\xe6\x7d\x79\x03\x09\x91\x25\x59\x8c\xb2\x1f\xdf\x97\x8f\xdb\x8e\x93\xa7\xb2\x34\xe3\x88\x1a\x78\xbe\x54\x65\x81\x19\xcb\x6e\x5c\x87\xcd\x52\x95\x21\x07\xd4\x4a\x09\xbb\x1c\x7d\xaa\x32\x90\xa5\x5a\xe1\x0a\x65\x03\xb7\xe9\x98\x27\xcb\x82\xc4\x71\xd5\xee\xa0\x28\x8f\xb9\x91\xbb\x98\x5f\xae\x5d\x28\x54\x96\x41\x80\xaf\xd4\xf1\xb2\xce\x0b\xfb\x02\x6f\xa1\x6e\x5c\x5b\x30\xe3\xca\xb8\xeb\xbb\xfb\x60\x05\xdc\x07\xb0\x14\x3b\x54\x32\x1d\x38\xf9\x50\x80\x57\x90\xf9\x29\x87\x31\xc0\x24\x53\x91\x71\x66\xae\xa1\x50\xdf\xf3\x62\x5f\x9b\xf8\xa0\x7e\xf1\x84\xb4\x76\x8c\xc0\x5e\x95\xbd\x1b\x8b\xd9\xf6\xc6\x94\x6c\x57\xa0\x0c\x31\x56\x3f\xe0\x7c\xda\xbc\xe5\xc5\x08\x6c\x9d\x81\xa4\xc4\xa1\x73\xfb\x4a\xbe\xc3\x51\x9a\xc7\x8e\x0f\xe9\x2a\x0a\x73\x5f\xe6\xcb\xb4\x4a\x11\x2e\xd9\x6e\x78\x6b\xa8\xea\xee\x9a\x79\x40\x78\x24\x9c\xe4\xe2\xfe\x3c\xb1\xbe\xdc\x5a\xa3\x06\x77\x85\x07\xa1\xc6\xfa\x35\xa6\x80\xfb\xb2\x91\x6f\xf9\x8b\x23\xfe\xfc\x4a\x7f\x19\x0d\x8e\x80\x5a\x2a\x5c\xfb\xda\x74\xd2\xd2\x6e\xf6\xf2\x20\x95\x08\x3a\x34\xcb\xd8\x06\x40\x79\x2f\x3e\xdf\x17\xfc\x77\xf6\x9f\xde\xff\xeb\x3e\xc8\x33\xdc\x9f\x5e\xcf\xee\x6d\xe4\x84\x2a\x6c\x23\xbc\xa8\xf3\x07\xef\x45\x89\x9c\x32\x8d\xea\xa5\xf2\x50\xd6\xc8\x6e\x73\x5b\x35\x0f\x59\x90\x19\x3b\x95\xe2\x6c\x45\xa8\xfc\x21\x15\xe2\x42\x76\xcc\x8b\x2f\xcb\xdf\x3c\xc5\x52\x71\x96\x24\xd4\x4e\xdb\x31\x28\xce\x8d\xe0\x04\x65\x57\x90\x8e\xee\x3b\x0b\x83\x07\xc9\x23\x26\xf1\x75\xba\xc3\x02\xd9\xf8\x6d\xe3\x11\xcf\x30\xc5\x45\xd6\xcb\x37\x27\x02\xf8\xc4\x3f\xad\x80\xe4\xe4\xfb\xcd\x23\x1d\x61\x6d\xf4\xce\x59\x4b\x7b\xdd\x2b\xc5\xe3\x98\xa6\xbc\xdf\x8d\xfe\xbc\xb1\x7c\xf2\x58\x58\x3c\x60\xf9\x0e\x3d\x3c\x73\xfa\x6f\x92\xc4\xff\xb9\x55\x86\xe4\xb1\x64\xc4\xab\x57\xe4\x45\x73\x5f\x95\x57\xa2\x37\x6e\x28\x04\x98\x02\xee\xca\x13\x14\xb3\x42\xfd\xa3\xcc\x8b\xc5\xdd\xfa\xfb\x72\xfb\xe5\x97\xf1\x48\xc3\xc7\x68\x52\xf8\xec\xa7\xa7\x3c\x8d\x38\xb1\x5a\xb1\x8b\xe5\xe7\xe8\xfe\xa7\x19\xc7\x62\xd6\x07\xe4\x66\x33\xf1\xfb\x08\xcf\xe2\x88\xf6\xcd\x4a\xda\xd9\x46\xa7\xad\x95\xdc\x27\x92\x94\x98\x00\x9d\xab\x6f\xe6\x88\x0f\x46\x5c\x6c\xcf\xb3\x4c\x47\xc6\xc9\x12\x11\x6e\x0b\x5e\xa9\x3b\x7e\xbc\x7e\xea\x3c\x70\x00\x3d\x0d\x55\x05\xd5\x63\x5e\xfc\x00\x04\x73\x8d\x3a\xc0\x9c\xa7\x09\xa2\x0b\x56\x86\x72\x9f\xff\xd9\x5d\x03\x17\x14\x39\xad\xd5\xb9\x58\xf9\xfe\x36\x17\x14\x70\x51\x3b\x80\x6e\x52\x3a\xfa\x5e\x49\x62\xec\x87\x6f\xd0\x9e\x68\x83\x42\x1b\xfd\x37\x44\xb2\x54\x74\x8e\x31\xf0\xff\xb2\xb2\x53\x5c\x46\xb1\xc5\x5e\xf5\xdd\x52\x6e\x0b\x9a\x29\x2e\x93\x80\x79\x9d\x85\x29\xae\xbf\xe2\x52\x07\x88\xc9\xdd\x7e\x99\x2d\x5e\x5c\xeb\x96\xb7\x4f\x12\x91\x6a\x3d\x60\xf1\xa8\x25\xc2\x95\x66\x18\x66\x36\xfc\x07\x38\x0e\xec\xe8\xe4\xc0\x00\x97\x8c\x76\x59\x5e\x35\xaf\xbd\xd7\x5f\x07\x29\xb6\x67\x8f\x60\x44\xab\x86\x9f\xd3\x49\x84\x5d\x9d\x0a\x14\xc0\xc8\x03\x7b\x1c\xdc\xf9\x49\xa2\x53\x8e\xbc\x88\x3b\x53\xf2\x9b\xc0\xa5\x8b\x20\xe1\x60\x5b\xa4\xed\xd6\xe4\xb7\x45\x9f\x5c\x8b\x20\x53\x8e\x76\xb2\x39\x1d\xf2\x66\x5d\x36\xb3\xfa\x3e\xff\x04\x85\xb8\xed\x2b\x0d\xb1\x5e\x0c\x21\x48\xa2\x70\x79\x58\xdc\x6d\xa7\xbe\x9c\x72\x8a\xe5\x14\xfe\x61\xc3\x62\xa7\x59\x34\x0a\x9b\x44\x18\x08\x57\x7f\x7b\x6a\xb3\xe2\x86\x1f\x06\x05\x3a\x11\xa6\x12\x99\xd5\xc5\x1d\x1c\x4b\x59\xfb\x3f\x67\x9c\x78\x05\xd4\xfb\x1e\x21\x40\x84\x99\xc2\x4e\xfc\x17\x7e\xe9\xc9\x9b\x29\x11\xea\x2c\xee\x83\xbb\xcd\xfc\xed\x8e\x6a\xee\xf2\x88\x39\x34\x93\x1c\x16\x3b\x94\xd1\xd4\x88\xf4\xe0\x3e\xe3\x66\x0a\xde\xaa\x06\x8e\x93\x49\x9a\x60\x71\x86\x7c\xc0\x53\x55\x7e\x5e\x3c\x40\x6b\xba\xb3\x38\x8c\xce\x05\x93\x0a\xf7\x08\xcf\x2d\x10\x11\x65\x5c\x79\x24\x42\x77\x67\xdd\xe1\x30\x20\x46\xc5\xb5\x3e\x0b\x59\xe5\x62\x84\x00\x10\x91\x22\x08\xf5\xa9\x9d\x40\xfb\xf6\x71\x4d\xfd\xa7\xb5\xa1\x40\xf3\x43\xd3\xa6\x53\xb8\x62\x60\x3f\x6e\x0d\x15\x36\xe7\x46\x4f\x3a\xa6\xca\x19\xf5\xd9\x0c\xe6\xbe\x34\xb2\xb1\xc3\xcb\x88\xe3\x14\xc3\xfd\x3b\x78\xdf\xe1\x8c\x71\x32\x77\xee\x8b\x63\x1e\x92\xbe\x22\xf3\xbc\x2a\x7f\x5c\xd7\x79\x46\xf7\x35\x01\xe3\x94\x94\x17\x4d\xf9\x0e\x95\x3e\x94\x1f\xbb\xe3\xf9\x30\xfa\x8d\x29\x50\x8c\x6b\xe1\x9d\x1f\xce\xc6\x51\x09\x2d\xca\x66\x13\x61\x91\x48\xed\x22\x81\x40\xc2\x7c\xff\x26\xca\x73\x65\x75\x67\xed\x08\x11\x00\xc6\x2d\xdb\xf3\xbf\x78\x3e\xc5\xfe\xbd\xae\x3e\x08\xa1\x8c\xee\xf6\x02\xda\xe9\xd2\x6b\x21\x09\xa1\x25\x4b\xfc\x1b\xf0\x58\x8e\x33\x0b\x21\x43\x63\xa9\xf1\x6d\xde\x9f\xce\x60\x35\x93\xdb\x54\x87\xe7\x23\xfd\x4e\x25\x49\xc0\xb1\x8c\xea\x11\x05\xc8\xdd\xb8\x2f\xab\x6d\x7e\xcd\x62\x1b\xe8\xc0\x8e\x6a\x4d\x92\x10\x9e\xda\xba\xd8\xf3\xf9\xb8\xcd\xe5\x8f\xd1\x0a\x26\x89\x30\x7e\x75\x18\x13\x3d\x1a\x34\xe3\xac\x50\xeb\x31\x08\x47\x12\x21\xa2\x6e\x51\x1f\xa9\xac\x8f\xce\x29\x13\x2c\xfc\x7d\x9d\x3d\xff\xee\x3a\x81\x92\x92\x28\x51\x83\xb9\x56\x5f\x19\xf0\xb8\xa1\x54\xa2\xca\x24\x47\x99\x59\x1b\x7a\x8c\x86\x64\x0c\x6b\x75\x15\x6f\xa0\xbe\x2f\x2b\x83\x55\x91\xb9\xdb\x3f\x99\xbf\x05\xa1\x0a\xb0\x07\x58\x49\x57\x39\x92\x2c\xd4\x58\x5c\x99\x29\xe5\x0b\xf1\xfe\x58\x26\xac\xa0\xc9\xe1\xb0\x7c\xde\x8c\x5a\x90\x6e\x90\x4a\x91\x38\x72\xb2\x73\xd1\x18\xaa\x8e\xee\x2c\x53\x12\xb9\xea\xc6\x4f\xd6\x01\x52\x6e\x33\x43\x27\x5f\x12\xb4\xe9\x6c\x7f\xcf\xd7\x5c\xfe\xd8\xa0\x42\x9a\x53\x02\x72\x03\x38\x68\x70\x0b\xc2\xaa\x68\xa3\xcc\xfc\x1d\x26\x22\x3f\x19\x0b\x03\x15\x55\xee\x18\x3c\xbe\x3e\x5f\x53\xd5\xdd\x68\x1d\x2a\xfd\x77\xa4\x41\xae\x0a\x32\xf6\x04\x49\x20\x91\x13\xb4\xab\xdf\xd0\x47\x75\x6d\xb5\xce\x06\x70\xf5\x1b\x57\x9d\x24\xcc\xc8\xa1\x56\xfc\x23\x2f\xf6\xeb\x2a\x2f\x9a\x6d\xe9\x66\xcb\x78\x2c\x60\x07\x8d\x17\x6a\xfb\x06\xc5\x64\x26\x2a\x53\x6a\xfc\xb4\xde\xcb\x06\x9e\xcb\x76\xf6\xde\x98\xbb\x69\x2c\xd2\xc8\xd9\x8c\x3f\x40\x63\x50\x7c\xf6\x9b\xef\xf2\x1b\x8a\x6e\x6d\xce\xc9\xb5\x37\xa0\x35\xa8\xbb\x0e\x77\x21\xb3\x58\x61\x98\xda\x06\xc5\xc3\xba\xa8\xe4\x51\x88\x49\x42\x95\xef\xdf\x9a\x30\x18\x5d\x9c\x63\xb6\x5b\xf5\xf2\xbe\x7b\xe8\xf8\x39\xfc\xad\xd8\x4c\x8a\xc4\x78\x75\x5f\xca\xfa\xad\xe7\x4f\xab\xa4\xb0\x12\x5d\x8b\xf5\x8b\xff\x13\x97\x49\x1f\xff\x6e\x3c\xdc\x27\x3a\x54\x52\x48\x43\x64\xe6\x4a\xb5\x2f\x8e\xb9\x03\xae\x04\x35\x51\x2a\x96\x42\x99\x40\xb3\x86\xa6\xcb\x06\xc9\xc0\x8c\x46\x49\x19\x2b\xe4\x5c\xd4\x27\xfe\x51\xcc\x3e\xf3\xab\xb9\x67\xc7\xa9\x2c\xc6\xa5\xa5\x50\xd2\xfd\x74\xa5\x94\x22\x16\xd1\xbb\xe1\x1a\x70\xf2\xdc\xe7\x9f\xee\x38\xb0\x10\x97\x3d\xae\x14\xd2\xc9\xa7\x27\x03\x64\x19\x73\xa6\xf9\xed\xce\x26\xcb\x2b\xf8\xaf\xd4\x44\x20\x22\x47\xe7\x07\x78\x82\xea\xc7\x01\xba\xac\xe0\xc6\x33\xd0\x2c\xc2\x2f\x6f\xb7\x84\xbb\x72\xdf\x4f\x68\xa4\x4e\x24\xb6\x94\xdb\x60\x23\xbf\x45\xb2\x56\x24\xe5\xd4\x61\x9f\x1b\x38\xd6\xcf\x65\xe3\x4c\xcf\x47\x5b\x80\x22\x19\xc3\xd0\xa9\x0d\x5a\x0e\x48\x97\xe6\x7d\x11\x18\x3b\x8a\xfe\x2f\x69\x6f\xd2\xdd\x38\xae\x65\x0b\xff\x97\x1a\xc5\xe0\x0e\x08\x36\x00\xf9\x66\xb2\x24\x3b\x5c\xe9\xae\x2c\x39\x22\xb3\xee\xaa\xa5\x85\xe6\xc0\xe2\x35\x45\xaa\x48\xca\x0e\xdd\x5f\xff\x2d\x1e\x34\x6c\x44\x3b\xe3\x7d\x2f\x07\xe9\x58\x02\xd8\xa3\x39\xcd\x3e\x7b\xa7\x91\x74\x30\x94\xcd\x81\x17\xc5\x68\xf1\x57\x61\x1a\x83\xd5\xe2\x59\x14\xc5\x4d\x55\x8c\xca\x7c\x86\x15\xcf\x2a\xca\x8c\x1c\xf6\xe6\xd1\xc5\x02\x55\x9c\x64\x18\x1d\x39\x35\x50\x37\x4b\x5e\x22\x9e\xc8\x37\xa6\x02\x23\xb2\x5e\x3b\xec\xe9\x79\x7d\x7f\xfb\x72\xbf\x7b\x5e\x6c\xd7\xbe\x13\xa7\xc8\x93\x52\x54\xd5\xdb\xe9\x38\x8f\xba\x54\x49\x9a\x2a\x13\xef\xef\x05\x1a\xb7\xd5\x76\x00\xf8\xf9\x3a\x1c\xa7\x28\x0b\xb1\x0e\xb3\xe8\x36\x95\xf6\xca\xd7\x20\x2a\x9a\x72\xa9\x5c\x9c\x0e\x8f\x80\x4f\xab\x96\x3f\x3b\x77\x6a\xd4\xcd\x9c\x40\xb5\x2d\x10\xb3\xad\x29\x23\xa8\x75\x24\x79\xe9\x35\xc1\xfa\xaf\x9d\x02\x41\x81\x98\x37\x78\xf3\x07\x80\x61\xba\xeb\xf6\x3f\x57\xf4\xad\x78\x1a\x21\xf1\xf6\x21\x2f\xc7\x2a\x49\x4a\x71\x08\xd3\x21\x06\xdd\x0b\x02\x4d\xfc\xcd\xce\xe1\xc1\x73\x6c\x5a\x5e\x0b\xc7\xb9\xfe\x37\xef\x4d\x84\x26\x8e\x9f\x0f\x74\x83\x90\x38\x08\xd3\x32\xfe\xf6\x84\xa4\x91\x1d\xb4\xd6\xc5\x9b\xf1\x3e\x94\xcc\x52\xd1\x93\x1e\xfd\xf1\xd7\xd2\xa4\x56\xc6\xb3\x4e\xa9\x94\x60\x84\x4b\xe7\x35\x86\xb8\xf2\x4a\xf5\xa1\x19\xa5\xd2\xd0\x49\xc2\x5d\x9d\xea\x12\xea\xf1\x9e\x33\x39\x15\x70\xda\x6b\x1f\x8d\x24\x10\xe6\x70\xe9\x0a\xc2\x80\xda\xea\x2b\x84\x98\x34\xe3\x1a\x9d\xa9\x0d\xa6\x74\x98\x65\xf6\x66\xf0\x36\x3c\x47\xf1\xac\xf1\x03\x01\x89\x33\xe6\x22\x3e\x2e\x87\x3e\xa0\xd0\x9a\x5d\x10\x20\x88\x99\x32\xa2\x66\x79\xd3\x3e\xd9\xe0\xf8\xf8\xd3\x42\x00\xd4\x18\x83\x08\x0c\xa8\xab\x43\x35\xb0\x0e\x20\x64\x81\xf4\x1b\xdf\x75\xfe\x6b\x79\xaa\x6d\x79\x96\x3f\x41\x98\x72\xa7\xac\x3f\x87\x56\x87\x90\x87\xb8\xae\x55\xa5\xd3\x82\xfe\x8c\x06\x75\x72\xf7\x91\xe0\x19\xf3\xcb\xcb\xad\xea\x6c\x18\x9d\xf7\x90\x11\x88\x03\x23\x77\x89\x8b\xd2\xc4\xbf\x87\x38\x32\x91\x99\x1d\x57\xea\x16\x01\x2b\x96\xc4\x71\x36\x63\x02\xb1\x34\xa1\xd3\x62\x68\x04\x0c\x73\x59\x97\x76\x34\xc4\x52\x8a\xa0\x8f\xeb\x60\xe5\xa2\xbb\x7c\x12\x6a\xe4\xf2\xd9\xf2\x37\xb8\x37\x0c\x46\x5b\xe0\x87\xf1\x02\x0b\x54\xc9\x24\x19\xda\x07\x8f\x7a\xa6\x6e\x0f\xa8\x0e\x30\xf5\x73\x2a\xbb\xdb\xbb\x3e\x95\xaa\xbe\xe2\xc5\xa0\xa0\x05\x18\x44\x49\x30\x3c\x51\xb7\xb0\xd9\x8b\xad\x91\x7b\x74\x76\x98\x43\x4a\x12\x57\x4d\xb9\x56\xf9\x60\xdd\x1e\x7f\x8a\x8c\x04\xc2\xe2\xc4\x37\xf0\xda\x0b\x58\xff\x16\x18\x00\xb2\xd0\xd4\x29\xad\x00\x8e\xdd\xee\x36\xdc\xda\x20\x63\x32\xb5\xab\x28\x96\x85\xbd\xf3\xa2\x5b\x29\x16\xea\x5f\x27\x9b\xa8\xb2\x31\x44\xe0\xc4\x28\x6f\x7a\xe8\xce\xfa\x97\xa1\x27\xbe\x55\x57\xe7\xaf\xe4\x32\x14\x70\x11\xe0\x1a\xfe\x5a\xf3\xb2\xbd\xab\x78\xe9\xa3\xd2\x5f\xb2\x88\x2b\x10\x22\x45\x61\x9f\xcd\xf2\x7a\x74\xd7\x42\x32\x07\xe3\xda\x21\xea\x76\x50\x28\x09\x92\xa4\xa8\x9f\x7a\xa8\x5a\x27\x16\xac\x40\x32\xc3\x89\xb8\x33\x3e\xfe\x76\x0f\xa6\x40\xef\xd3\xec\xdf\xf0\xd1\x25\x53\x58\x3f\x37\x0c\xfd\x4f\x23\xf4\xa3\xed\x6f\x9a\x17\xfc\xa4\x75\x36\x28\x65\xaf\xa9\x82\x10\xe3\xb0\xf9\x73\xee\xf7\x65\x50\x24\x75\x6a\x61\x8e\xac\xe2\xc9\xb0\xae\x7d\x2a\x3e\xff\xe9\xdf\xc1\xf0\x55\x2a\x93\xd2\xc9\xb0\x4e\xa8\x83\x6c\x17\x08\x63\xc4\x87\x2d\x6e\x9f\x77\xe1\x18\xcd\x03\xc0\x05\xba\xe2\xba\x06\x5b\x26\x8e\xdc\x2e\xca\xb7\x6b\xed\xe4\x3b\x36\x95\x6e\x25\x3f\x8e\xf9\x5c\x40\x27\x29\x71\xa2\xe4\x67\xe3\x25\xc9\xe9\x1c\xd0\x1c\x64\x9f\x53\xfd\x91\xd7\xed\x89\x17\x93\xf9\xac\xc1\xd4\xb1\xe2\x38\x33\xf5\x6c\x9f\x94\xc9\xba\x03\x74\xe6\xde\x27\xae\x11\xbe\xec\x41\x87\x69\x22\xad\x95\xd9\xcb\x39\x5f\x86\x11\x47\xf7\xa8\xc3\x4c\x38\xad\xce\xb6\x80\x2b\x68\x5f\x4a\xe9\x0c\x50\xa3\xeb\xef\xb0\xfc\xee\x6f\x77\x7c\x1c\xb8\xc3\x95\x36\x69\x34\x23\x32\x6f\xe5\x71\x96\x56\x47\xdb\xdd\x59\x14\x6b\x74\x16\xc4\xe9\x6c\xeb\xca\x26\x2e\xd8\xe4\xa6\x22\xa1\xd0\xcb\x5a\x5c\x3d\x2f\x90\x22\xcb\x9f\x48\xa5\x08\x2a\x14\xe0\x13\x75\x3a\x49\x0d\x4b\x87\x47\x2f\x6c\x64\x55\x43\x73\xab\x97\x50\x14\xb7\xcd\x55\x85\x74\x7b\x5f\x6e\x1c\x3a\xd1\x19\x02\x34\x73\x1f\x1d\xff\xed\xb1\x39\xfa\x3a\x9a\x06\x4c\xdb\x55\xf5\xfe\x6c\x88\x8e\x7d\x4b\x86\xf6\xbd\x31\x0f\xae\xeb\xea\xdf\x30\xcb\xa0\xa8\x34\x8d\x29\x32\x06\xdc\x3d\x6e\xb7\xeb\xe7\xbf\x76\xd7\x2f\x0f\xab\xdd\xe6\xfb\xe2\x79\xed\xcf\xc5\x29\x2e\xae\xa7\x52\x54\x9e\x3c\x43\xb3\xc0\x60\x1d\x5e\x1d\x94\xeb\xe2\x19\xfa\xf9\xa3\x59\x14\x65\x86\x36\x8d\xab\x7b\x68\x38\xaa\xc7\x9c\xa7\x4b\xc4\x84\x88\x5f\x69\x96\x08\xe5\x25\xb5\xec\xc4\xe9\xc3\xe8\x3a\x25\x61\xa8\x1d\x59\xee\xe7\x44\xc3\x4a\xa7\x54\x21\xfd\x07\xcc\x51\x49\x2b\x9d\x2a\x86\xf8\x5a\xbc\x8d\x25\xba\x11\xed\x1e\x19\x8c\xbe\x8d\x96\xa3\x7f\xc6\xee\xc6\x52\x4d\x06\x90\xfa\x1f\x55\x7b\xe1\xe4\xf9\x67\xc8\x22\x9d\x19\x31\xdc\xe5\x9d\xbb\x60\x96\x84\xb8\xad\x4e\xea\x09\xdd\xdf\xd1\x60\x11\x59\x8c\x3c\xaf\x25\xfc\x42\xb3\xf0\x1a\x30\x98\x38\x9e\xfc\x5a\x06\x99\xe3\xc1\xb4\x41\xa5\xf3\xe6\x7c\x10\x95\xf3\xe5\xb5\x0c\x19\xa2\xbe\x97\x45\x75\x52\xa2\xce\xe5\x64\x18\xc8\x10\x62\xa3\xba\xe4\x38\x8d\x95\x96\x51\x9c\x98\xb4\xef\x2f\x67\x1a\xb9\x26\x45\x84\x46\x8a\x79\x80\xd6\x96\xe1\x6f\x00\xe9\xee\x4e\x75\xdf\x29\x0a\x11\x64\xf7\xe3\x71\xbb\xde\x2d\x6e\x16\xb7\x0f\x4e\x17\x48\x69\xdc\xb3\x0d\xa1\xfa\xdd\xdd\xe2\xf9\xe6\xf1\xce\x39\x5e\x1a\x54\xe8\xbc\xec\x6e\x6a\xb7\xb0\x23\xf1\x08\xa4\xae\x01\x32\xab\xba\xe1\x35\xb2\x26\xcb\xb1\xd6\x9d\xed\xe2\x70\x19\x4e\x41\x7a\xf4\xcc\x10\x04\x49\x82\x65\x61\x48\xf9\xd1\xf9\x00\x83\x2d\x14\x82\x80\x31\xc3\x28\x53\x57\x47\x68\xf7\x67\xff\x3b\x37\x32\x48\x35\xbc\x57\x6f\x60\x15\x54\x26\xd8\x07\xd7\x55\x64\x3c\x33\x65\x99\x76\x8d\x9a\xd0\xdd\xff\x33\xfa\x1f\xdf\xd5\x70\xeb\xae\xaa\x07\xa4\xe1\xad\xd4\xd9\xc8\x4e\x6c\xf7\x79\x73\x03\xed\x76\x0f\x28\x6d\xf9\x58\x82\xbf\x11\x60\x6e\xd7\x78\xa8\x3c\xfb\x93\xc7\x87\x43\x40\x44\x08\xa6\xf0\x48\xe4\xfe\x37\x15\x65\x7e\x83\x3c\x2e\x7a\xb5\x54\x6b\x69\x42\x40\x40\x24\x16\xdd\x65\xcb\x4c\x7c\x83\x42\x5b\x8c\x37\x4d\x25\x73\xde\x82\xea\xdd\xca\xe1\xcb\x87\x20\x14\x29\xb2\x34\xfc\xa8\xf2\x63\x3b\x7c\xa7\x11\xa1\x88\xf5\x43\x65\x96\xd0\x05\x5c\x0e\xbc\x27\x76\x83\x20\x52\x81\x74\x7c\x53\xdd\xf4\x32\xec\xa2\xf0\xa8\xbf\xe7\x4d\x5b\xd5\xb9\xe4\xc5\x3d\xb4\x5c\xf1\x96\xcf\x65\x3e\xba\x13\x44\x99\x4d\x60\x5b\x80\xab\x59\xff\xac\xf5\x3f\x34\x9e\xed\x11\x31\x65\xe1\x20\x81\x88\xc5\x8f\xd0\xe4\xff\xfe\x22\x79\xe8\x8e\x64\x29\x86\x34\xba\x71\x38\xe1\xcc\xee\x1a\x33\x96\x58\x74\xe4\x3b\xd4\x98\x94\xb4\x49\x8a\xdf\x82\xa9\x42\x90\x08\x85\x62\x71\xad\xf3\x4d\x3b\xb3\xb9\x7b\x1b\x43\x91\xdb\xdf\x35\x68\xdc\x39\xc1\x7c\x1c\x71\x3a\x77\x7b\x96\x1f\x2d\x34\x55\x98\x8f\xc2\x84\xd1\x8f\xa1\x0c\x3d\x04\x34\x23\x86\xf2\xcf\xb0\x02\x6d\x6b\x9e\x97\x70\xc1\x2a\x38\xfd\xeb\xe0\xab\x10\xb0\x8c\x9b\x5c\x57\x8e\x20\xc5\xce\x43\x18\x59\x26\x10\x30\x19\x21\x9f\xf9\xbb\x99\x4f\xc3\x72\x02\x08\x98\x0e\x0d\xb4\x6c\x9f\xeb\xf6\x2a\x6f\x9b\x3b\xd0\x43\xd5\xc6\xfe\xe1\xd2\xd8\x54\x55\xfc\x58\xcf\x82\x34\x47\xb3\x33\xd5\x86\x4f\xa6\x5b\x67\x6e\x1e\x27\xdf\x8e\xd3\x00\x2d\xda\xbb\xc7\x9b\x5d\x09\x1f\x37\xbc\xb9\x94\x16\x87\x40\x10\x53\xae\x08\xa5\xda\x89\xc2\x8b\xf0\x74\x0d\x09\xfa\x86\xbb\x53\x79\xe4\xf2\xcd\x2c\xf4\x97\x7c\x78\x10\x88\x58\x0a\xea\xf9\x96\xf9\x2e\x9c\xb6\x27\x0a\x49\x20\x6c\x99\x08\x6a\x05\x96\x6a\x5d\xaa\xb9\x11\xe0\x8e\x01\x8a\x8c\x84\xc6\x1d\x9b\x14\x67\x74\xcd\xcc\x42\x83\x5a\x97\xc9\x7b\x42\x65\xf8\x4f\x4e\x27\x53\x99\x7a\xd4\xce\xa9\x6c\x4d\xc2\xff\x93\xbe\x99\x51\x2f\x7b\xee\x6c\xe4\x57\x5e\x8e\x56\x54\x65\xfd\xe1\xb7\xba\x79\x69\x94\xfb\x15\x42\x42\xd2\x41\x09\x9a\x25\xad\x72\x73\x7b\x74\x7a\x08\x33\x24\x41\x52\xa7\xc3\xd1\xcb\x89\x42\xa0\xb9\x44\xa4\x8e\x79\xe0\x0b\x2c\xa9\xeb\x05\x12\x69\x97\xde\xca\xea\xa3\x34\xaa\xab\xe0\xef\x42\x6b\xc3\x17\x6f\x37\x1d\x68\x2d\xe9\xf4\x21\x1f\x13\xfc\x00\x09\x08\x63\xa2\x97\x7f\x5d\x59\x6a\x9d\x6f\xbe\x19\x90\x7a\x17\x8c\xbb\xda\x93\xaf\x8f\x3f\x2c\x09\xe2\x04\xac\xc4\xc9\x4f\xc7\xd4\x3e\xa1\x78\x00\x42\x92\x38\xb6\x02\xa7\x43\x06\x7b\x20\x44\x49\x64\x29\xaf\x8e\x50\x5e\x66\x4d\x80\x84\x91\x61\x1e\x7d\xe5\x87\x71\xdd\x01\x90\x88\x68\x3e\x49\x89\xcd\xdb\x4d\x40\x22\x16\xea\xd8\xf3\x04\x7f\x99\xfd\x00\x92\x64\x52\x59\xed\x27\xf4\x5e\x9f\xf1\xfc\x97\x75\x70\xe3\x4b\x24\x8a\xe2\x2e\x8b\x26\xde\x83\x15\x5c\xf2\xa2\x01\x7d\xd6\x12\x08\xa5\xa6\x46\x14\x85\x42\x9e\x78\xfd\xb6\x38\x1e\x5d\x1b\x0b\x35\x46\x22\xb1\xc8\xd9\x45\x0b\xf9\x8c\xbd\x0b\x84\x25\x69\xc0\x7b\x1e\xc1\x64\x36\x34\x85\xdd\x70\x71\xe0\x4a\xf5\x38\xde\xd9\x10\x2e\x10\x26\x28\x8e\x9d\x63\x5d\x1d\xf2\x66\xac\x13\x05\x24\x23\x21\x6e\x47\x70\xc8\x5b\xd4\x68\x37\x8b\xc1\x4d\xfe\x3e\x63\x33\xf7\x4e\x35\x90\x2c\xa2\xf8\x42\x5b\x68\xda\xed\xbe\xae\x3e\xfe\x4e\xb7\x0e\x48\x96\x19\xed\xaf\xc6\x70\xc5\x23\xfb\x27\x99\xbc\x80\x2c\x4b\x33\x03\x05\xaf\x3f\x78\xad\x06\x5a\x2e\x93\x4f\x93\x89\x08\x6b\x40\xf2\x66\x21\xdb\x7c\x1c\x56\x03\x92\xa9\x08\x93\x43\xb2\x00\x5e\xdf\x2e\x1f\xc5\x34\xc4\xe1\xfb\x59\xd5\x9d\xba\x67\xfa\x07\xc2\x03\x82\x22\x99\x96\x59\xc5\xa3\xa8\x16\x45\xe1\x75\x15\x80\x70\x2a\x09\xeb\x6b\x3a\xa7\x4e\x37\x10\xa1\x22\x47\x6b\x68\x55\x42\x9a\xf6\x9b\xa9\x34\xb0\xf5\x06\x08\x0f\x77\xdd\x65\x6a\x88\xd8\x9b\xce\x67\xeb\xb7\xeb\xc9\x73\x4b\x48\x30\x6c\x76\xdc\x73\x2c\x82\x6c\x78\x01\xbb\x6d\xe5\x6e\x4a\x25\x31\xe2\x84\xb8\xa8\xfc\x0a\x44\x14\xe3\x10\xfb\x65\x1a\x71\x99\x62\x4a\x17\x0c\x44\xa5\xa6\xb2\xb3\xdb\x06\x91\x14\xf9\x93\xc1\xa7\x52\x69\x82\x73\xf0\xab\x75\x8c\xc8\xc3\xad\x8b\xa8\x8c\x0b\x43\xcb\x5c\x5a\xbe\x83\x41\xe2\x0e\x88\x92\xdc\xe0\xd0\xf7\xbc\x86\x3d\xc6\xa2\x88\x6b\x03\x12\x38\x8c\xba\xad\x71\x9a\xff\x6e\x90\xc4\x98\x9e\x3a\x95\x4d\xfe\x5a\x4e\x1e\x04\x12\x99\xa6\xc6\x33\xbe\x3a\xb7\x7e\x8a\x02\x17\x88\x3a\x6c\xaa\xa2\x9b\x35\xf6\xd6\x06\x12\x73\x40\x74\xa4\x11\xca\xbf\x7c\x5e\x2f\xb6\xeb\xdd\xf3\xfa\xe9\x71\xf7\xfc\xe8\xf4\x07\x80\xe8\x84\x62\x84\xc2\xbc\x48\x3b\x88\x2f\x42\x8e\x40\xb4\x4c\x30\x1b\x8e\x08\x00\x4b\x1f\x3e\xc5\x2e\x8d\xff\x9a\x03\x43\xc2\x08\x96\x8c\x71\x07\x9f\xdf\x6c\x97\xab\x67\x1b\xdd\xbc\x1e\x5f\x25\x24\x9a\xa6\x1e\x29\x51\xbf\x41\x7b\x6b\xbd\x14\x08\x43\x1e\x3a\xf5\x6b\x53\xef\xad\xae\xce\x58\x98\x38\xfc\x50\x61\x28\x18\x12\x07\x8b\xd3\x79\xb5\xfe\xe1\x8e\x8d\x62\x53\xd0\xb9\x7d\xdc\x2e\xee\x76\xcf\xeb\xff\x7a\x59\x6f\xb6\x3b\x4b\xcf\x3d\x88\x1c\x41\x18\x2b\x20\x1e\x49\x39\x54\xd6\x59\x76\xcf\xad\xfa\x10\x2b\x84\x49\x9c\x39\x56\x75\xc7\x36\x6a\x71\x4d\xa3\x6f\x17\x26\x3a\xa3\x36\xa0\xf9\x97\x94\xce\x17\x9e\x1d\x04\x21\x8d\x43\x99\xd9\x62\x14\x8c\x55\xe0\x19\xbd\xec\x2b\x84\x69\x00\xf8\x24\xef\x26\x3d\x00\xc3\x00\xa0\xef\xa2\x89\xd1\x2a\x53\xc7\x2a\x77\x11\x68\x08\x33\x19\x63\x6d\xf7\x07\x7e\x63\x0b\x59\xe8\xd5\x1b\xc6\x37\xc2\x99\xd1\x40\x31\x82\x67\xeb\x03\xd4\xaf\x9d\x8f\x7b\x35\xb0\xb9\x42\x29\x62\x4d\x8c\x3c\xf2\xd0\xec\x08\x15\x89\x30\x16\xca\x95\x7a\x7c\xb8\xd9\x2d\x5e\x56\xb7\xdb\x6f\xf3\xd4\x2e\x83\xd7\xa9\x88\xc6\xf2\x45\x87\xc8\x5e\xe8\x16\xea\x3e\x8a\x0a\xa1\x0a\x53\xf4\x93\x6e\x6e\x97\xdb\xb9\xd4\xfc\xfc\x36\x19\xaa\xc8\x14\xbf\xa2\xb4\x8c\x80\xda\x5b\x0e\xa1\xd2\x1a\x13\xd7\xe3\x1a\x1d\x83\x59\x19\xed\xfe\x21\x24\x09\x26\x16\x9f\x2b\x47\xf1\xf6\xa3\x6a\xe1\xb1\x9c\x72\xb5\xb9\xee\xdc\xf0\xfb\x5d\xdf\x3e\x6f\xb6\xbb\x27\xcc\x57\xde\x2f\xfe\xdc\x6d\x9e\x16\x0f\xfe\x94\x9c\x65\x03\xc1\xe1\x6b\x24\x1a\x1f\xb0\x22\x40\xa8\xad\x98\xbb\xa5\x96\x7c\xac\x15\x58\xc1\x6b\xd3\x21\x0a\x48\x84\xef\xff\xa9\xe0\xe7\x3f\xa3\xc0\xff\x1c\xfb\x40\xe1\xed\xe1\xc8\xa5\x59\xaa\x8c\x2d\x3c\x9c\x2b\x51\x20\x0c\x3e\xc5\x78\xf5\xf3\x8b\x73\x14\x48\x07\x6b\x83\x43\x7e\xba\xc8\x8d\xda\x5e\x24\x08\x90\xd5\x07\x17\xfa\xce\xbd\x6f\xba\x55\xf0\x89\xd7\xfc\x30\x19\xe2\x11\x09\x28\x96\x26\x18\x26\x33\x83\xcc\xaf\xd6\xed\x1e\x9f\x6f\xb4\xe5\x45\x84\x48\x74\x2e\x90\xf2\xb0\x69\x57\x55\xe9\x90\x8d\x10\x91\x14\x82\x21\x11\x26\xaa\x2e\x8c\xbe\x7c\x14\x52\x91\xd9\x4c\xa2\xad\xe9\x77\xf9\x28\x3f\xea\xa2\x88\x80\x61\xec\x68\xa1\xe6\x2d\xec\xa6\x00\x1d\x88\x22\x9d\xa1\xfb\xb6\x38\x56\x45\x51\x6d\xe0\xd8\xc2\x01\x69\x58\xd4\x04\x86\x0d\x51\x12\x25\x48\x3e\xf7\x31\x24\x88\xbb\x4c\x01\x8f\xcf\x9f\x24\x0a\x43\xdd\x4f\xff\x39\x64\x15\x82\x28\xa1\xa9\x30\x09\xc1\x66\xe0\x19\x46\x8c\x09\x34\x77\xff\xd3\x48\xda\xba\x9f\xd3\xc8\x40\x08\xdf\xbb\xcf\x3c\x7d\x11\x29\x17\x48\x7d\x77\xc5\xc5\xf9\x6f\xa4\x2c\x20\x4a\x25\x73\x08\x2c\x1b\xc9\x37\x71\x80\x33\x72\x9a\x8e\x0c\xb1\x28\x8b\x32\x16\x79\x96\x2c\x0c\x88\xec\x78\x2d\xf2\xb6\xd9\x1d\xb8\x1f\xa7\x22\x4e\xa8\x57\x88\x1c\xd9\x6a\x91\xe0\xa9\x57\x24\x6b\x6e\xa0\xf5\x75\x71\x10\x09\x11\xe3\x7b\x41\xf1\x8b\x6e\x21\xc4\xe8\xf9\xe4\x70\xc9\x51\x6b\x64\xa0\x2e\xd1\x2b\xa5\x5e\x40\xf4\x20\x92\x82\x09\xab\xf6\x85\x93\xe2\xa5\x71\xfc\x5b\xe3\x17\x86\x82\xe1\x9d\xdb\xc3\xcf\x63\x89\x36\x88\x24\x18\xec\xa9\xe4\x45\xb1\x19\x8a\x7e\x43\xa4\x22\x81\x98\xf9\xbc\x79\x7a\x5e\x7b\xee\x3e\x88\x94\x00\x35\xdc\xb9\x56\xd0\xc8\x3a\x3f\x9a\x22\x93\xc9\xa0\x70\x9e\x48\xa4\x74\x1a\xd9\x58\xeb\xb5\xa1\xde\x6c\x2f\xc3\x6e\x10\x41\x68\x36\xcc\x11\x5b\xa9\xc9\x6b\x7e\x86\x00\xba\xcc\xed\x40\x04\x11\x43\x20\xcc\x9f\x3a\x2f\xf3\x16\x16\x4d\x03\x7e\x68\x01\x0d\x70\x1a\x95\xf0\x61\xe5\x08\x7d\x4b\x46\x4c\xed\x30\xee\x25\x3f\xf3\x72\xbe\xee\x73\xfe\xcf\x78\x24\x69\x9e\xc6\x43\xe8\xae\x0f\x19\x0f\x7b\x9b\xbe\x71\x10\x72\x08\x87\xb1\xd7\xd6\xeb\xf2\x0c\x34\x86\xba\x7e\x42\x24\x2e\x93\xa8\x0d\x1b\xc4\x26\x2f\xde\xa1\xee\x3c\x82\x6a\xb4\x18\xc6\x41\xc4\x51\x11\x06\x8d\x50\x36\x5c\x88\xe3\x20\x56\x10\x79\x8d\xb8\xfc\x70\x3a\x2c\xeb\xce\xdb\x1c\x7f\x8a\x38\xcc\x0c\x7f\x5e\xbe\xe3\x87\xdd\x2b\x94\x50\x57\x7e\x6c\xc4\x11\x61\x81\x81\x58\xf2\x02\xd4\x55\xae\x9a\x79\xdf\x26\x8e\x08\xc7\x5c\x85\x31\x86\x91\xb8\xb3\x5b\xb9\x48\x6f\x10\xc7\x51\xa6\x69\x2f\xd7\xb2\x98\x94\x0d\x40\x1c\x69\x46\x32\xbf\x77\x9b\x73\xb8\x9d\xca\xdf\x50\x1c\x87\x26\x3e\x6d\xd8\x02\xcc\xfa\xb8\x42\x66\x84\xd9\x7d\x34\x8e\x15\x47\x77\xf0\x7d\x18\x7c\x1f\xf7\xb0\xcc\x4f\x46\x92\xef\x7b\x55\x37\x70\x1e\x61\x51\x07\xce\x56\x4c\x75\x8c\x37\x59\x80\x37\x6e\x62\x96\x08\xd1\x67\xd4\xfe\xd8\x8e\xbf\x50\x1a\x31\xc4\x07\x59\x7e\x83\xee\x0b\xcd\x2a\xd3\x40\x9c\xa6\x49\x1c\x38\x35\xf1\xe7\xf1\xee\x36\x7e\xdb\x69\xca\x84\x1a\x65\x86\x06\x16\x47\x9c\x4a\x53\x24\xa1\x3a\x77\xe8\x34\x59\xfc\xe2\x54\x27\x58\xce\xe7\xc4\x1a\x9f\xd6\xcf\xcb\xf5\x03\xb2\xdb\x84\xee\x0c\x99\x12\x2e\x94\xf3\xd2\x2d\x71\xd7\x27\x28\x1a\x5f\xc0\x6b\xd4\x2b\xbb\xf6\x9f\x8f\x1b\xf7\x13\x27\xca\x41\x80\x36\xfc\x3d\x2f\x5f\x9b\xd9\xe8\x4a\xcc\x53\x1e\xda\xb5\x6c\x71\x3c\x0e\xe9\x2a\xc6\x7b\x73\x2c\x12\x03\xcb\xde\x5d\xdd\x3d\x2e\xff\xd8\x3d\xaf\x7f\x2e\x9e\x9d\x55\x1d\x8b\x44\x33\xe5\xc2\x30\x85\x9a\xb5\x4a\x63\xc1\x09\x93\x3e\x82\x31\x0d\x9a\xc4\xc0\xa4\x90\xbe\x28\x7d\x7e\x09\xb8\x0c\x02\xc7\x9a\x46\x18\x90\x81\x5f\x2d\x94\xaa\x33\xbb\x6c\x89\xe8\x65\x31\x02\x24\x41\x96\x3a\x1a\xcf\x43\xf7\xf9\x6b\x8c\x3c\xcc\xbb\x73\x49\xa0\x03\x5b\x37\x33\xaa\x8b\xfe\x2d\x7b\x31\x21\x84\xdb\x28\xa5\xcb\x74\x5c\x71\xf9\xb6\xad\x2c\xc0\xc8\xf5\x8a\x63\xe8\xc3\x84\xbf\x55\xf1\x02\x49\x18\xc8\x30\xf3\x72\x14\x46\x46\x8c\x38\xbb\x2d\x09\xb3\x18\x9d\x50\xf0\x44\xcb\xc6\x30\x77\xcd\x3c\x08\x84\xe7\xb9\xc6\x7a\x20\xd7\x14\x41\x88\x3c\xbb\xeb\x3f\x17\x58\xa7\xf9\xc5\xf6\x9e\x24\x94\x63\xde\x49\xf3\x93\xec\xf6\xa3\x4f\x5e\x61\xc2\x88\xad\x4a\x3f\x5f\xe6\x19\x87\xd3\x20\xa1\x49\x00\xda\x21\x82\x50\x7b\x09\xb9\xe7\x77\xa8\x83\xba\xbb\x55\xbb\x19\xe9\x27\x7b\x28\x23\x71\xec\xf8\x74\x78\x01\x66\x73\xc7\x89\x3d\xe0\xf4\x81\x84\x65\x94\x5a\x9d\xed\x1a\x4d\x00\xab\xc5\x33\x3e\x59\x1a\x12\x1c\xc9\x7b\x03\x1a\xf3\xb5\x4e\x90\xa4\x51\x84\xfc\x8c\x9b\xc5\xcd\xc2\xff\x96\xa4\x18\x99\xc0\x25\x62\xc2\x77\xe7\xba\x68\x82\x45\x20\xe8\xd4\x4f\x96\xeb\xd1\xc2\x97\x64\x91\x44\x58\x95\xdd\xa8\x77\x1b\x68\xdb\xee\xaf\xe4\xcd\x1e\xb5\x6d\xd4\xa9\xe6\x03\x17\x2d\xe1\xcc\x30\x26\xbc\x42\xfb\x5f\x27\x68\x30\xf2\x59\x36\x1f\x9f\x54\xea\x75\xfd\x8d\xb0\x85\xad\x47\x19\x68\x00\x7e\x49\x45\x06\x09\x07\xa2\x8d\x6e\x9b\x73\x18\x17\x45\x61\x6b\x5d\xef\x73\xcf\x6a\x01\x89\x20\x46\x22\xdd\x14\x3d\xe2\xf8\xec\x0d\xdb\x44\x72\x03\x60\x41\x86\x9e\x0d\x60\x74\xd5\x36\xa9\x90\xa3\x71\xf3\xfd\xe5\xea\x65\x68\xbf\x26\x2a\x8e\x70\x7d\x32\x1a\xff\x17\xe5\x22\x90\x28\x16\xe1\xf6\x8c\x9e\x75\xb7\xfb\x5c\xf7\x61\x8b\x44\x65\x21\x95\xb6\xd4\x6a\xc5\xf3\xcf\x1e\xd7\xf5\x86\xd0\x21\xc3\x5e\x72\xb5\x68\x6e\xcb\x16\x3e\xcb\x4e\x43\xe7\xd4\xa0\xe3\x2e\x84\x15\x13\x19\x4f\x6d\x88\x25\x42\xdc\x30\x04\xb0\xad\x16\xf5\xe1\x3c\x19\x6a\x3a\xb4\x58\x72\x53\xe9\x3f\x93\x0f\xc5\x3e\xb8\x06\x35\x26\x18\xfc\x00\x1f\x98\xb5\x9e\xce\xa5\xb9\x84\x5a\xa2\x75\x18\x5b\xd8\x31\xee\x1a\xdb\xea\xa6\xae\x4e\x17\xd0\x24\xb7\x00\xd3\x80\x18\x85\x01\x27\x34\x3d\x17\x65\x1a\x5f\x82\x06\xb1\x11\x58\x1a\x46\xc3\x87\xb4\x63\xa3\x07\xa6\x41\x46\xa5\x13\x74\x33\x5a\x74\xc6\x98\x72\x34\x63\x83\xf3\xaa\x18\xa9\x68\xef\x72\xd9\x2d\xe6\xc3\x11\x41\x49\xc2\xa9\x5d\xc1\xac\x67\x68\x1b\xc2\x98\x62\x12\xc3\x19\x29\x98\xf9\x71\x6c\xff\x9f\x7c\xf9\x89\x48\x3f\xd0\x90\x6b\xf4\xd3\x5e\x6b\x5e\x2a\xe7\x1d\xcd\x4e\x27\x1a\xeb\x08\x2d\xda\x9d\xcb\x12\x6f\x79\xf3\x36\x79\x90\x24\x49\xc1\x00\x1d\xd5\xa2\xb5\xd5\x25\x38\x57\x27\xaf\x26\x51\x82\x69\x3f\xcc\xb7\xfb\x7c\x32\x10\x28\x55\x1a\xac\x78\xea\xa9\xe0\xb5\x23\x81\x72\xad\x20\x10\x95\x88\xe6\x9e\x91\x5e\xb7\x2d\x2c\x31\x0a\x42\x5c\xa9\x1e\x8f\xfd\x7b\x31\x0f\x9a\x72\xc3\x4c\xf1\x47\x5e\xbe\xaa\xea\x30\xa5\xb9\xfc\xcd\x0d\xf1\xb3\x93\x2b\x83\x52\x40\x22\xf5\x87\x9b\x99\x24\x1b\xcd\xba\x4d\xd4\xae\xc5\x53\x70\x15\xd0\x2c\xa2\xb8\xb7\x7c\xcf\xdb\xdf\x63\x76\x01\x9a\x65\x21\x9a\xe0\xb5\x2c\xbb\x55\xc2\x2d\xd8\xb6\x95\x33\xc6\xd8\x08\xc0\x10\x65\x23\xdb\x91\x72\x15\x1b\x92\x21\xec\x82\x92\x56\xb3\xc0\x5a\xa0\x22\x06\xfc\xee\x8e\xd9\xf9\x99\x5f\x62\x4d\x5c\x57\xc6\x13\x67\xdc\x95\x79\xdb\xac\x40\x43\x79\x49\x26\x3b\x79\x7d\x32\x51\xcc\xaa\x1c\x09\x94\xe1\xde\x29\xe0\x3e\x2b\x4c\xa5\xcd\x40\xe3\xdb\x45\xb9\x92\x4f\xae\xae\x04\xc1\x34\xc7\x55\xde\xee\xa1\xf4\xcb\x17\x85\xcc\xec\xdc\x43\x84\xf8\x3f\xe6\xd0\x12\x14\x44\x84\xd3\x6e\xc9\x0f\x47\x9e\xbf\x96\x36\xc4\x39\xbe\x5d\x4d\x03\xac\x32\xb3\x79\xe2\x31\x94\x07\xa8\xe6\x09\xd2\x31\xe7\xa5\x2c\x50\x98\x74\x5d\xfa\xda\x47\xd7\x45\x92\xd0\xc4\x34\x9f\x87\x06\xa2\x6f\x4d\x1d\x5b\xe0\x72\x9f\x17\xaa\x86\x72\x50\x28\x00\x2c\x88\x98\x0a\xfa\x6c\xe5\xb1\xce\x11\x5e\x75\x18\x56\x31\xb8\xae\x09\x71\xf8\xfb\xff\x3a\xe5\xf2\x0d\xc1\xcb\x0e\x43\x6a\x4a\x47\xc2\xd4\xf5\xe5\x06\xae\xe2\x3e\xf3\xdd\x80\x05\x70\xfc\xc1\x18\x49\x24\x26\x5e\x6e\x97\x8f\xbb\xe5\xe3\x03\xf2\x86\xba\xbb\x23\x0c\x4c\xd9\x18\x70\xc3\xc6\x34\x53\x56\x04\x8c\xa4\x21\x12\xc7\x97\xa7\x83\xab\x2c\x6e\xfc\x19\x24\x33\x6c\x27\xd0\x98\x92\xd4\xe7\xea\x6d\xe3\xc9\x05\x81\x45\x91\x40\x75\x89\xea\x08\xe5\xfa\xf5\x75\x18\x79\x77\x69\x16\x16\xc5\x3a\x31\x06\xf8\x3b\xf0\xe2\x2a\x57\x5f\x33\xf7\x7e\xce\xe2\xe0\xce\xa7\x54\xe4\xe9\x63\x97\xfc\x88\xca\x10\x3d\x10\x86\x25\x19\x81\x70\xe0\xac\x7f\x86\x99\x9d\x25\xa3\x01\x46\xa3\x08\x67\xc0\x3d\xfa\x89\xf7\xbc\x46\x9d\xf2\xaf\x6f\x89\x46\x59\x6c\xd3\xf6\x5b\xfe\x0b\xd7\x42\x1b\xa2\x9d\xf4\xe3\x04\x4b\xd7\xab\xb2\x38\x3f\xda\x18\xfe\x16\xf8\x61\xa6\x3c\x00\x58\x9a\x19\x2a\xb1\x66\x5f\x7d\x1c\x6b\x2f\xa9\xd2\x35\x64\xa8\x8b\x77\xc5\x4d\xdd\xd1\xa2\x71\x41\x6f\xc6\x79\x3a\xa0\xa0\x30\x24\xfd\x97\xb0\xba\xd9\x4d\x97\x89\x2c\xc5\xd2\x06\x03\x12\xc4\x52\xe2\x91\x6b\x3c\x2e\x24\xf8\x2d\xbc\xec\xc0\x47\x62\x02\xe2\xc0\xd5\x4e\x42\x09\x3a\x97\x39\xaf\xf3\xcb\x1a\x14\xdb\x5d\xa6\x89\xa1\xe5\x35\x8a\x71\x18\xbd\x9b\xbc\x20\xc9\x8d\xfa\xba\xa9\x05\x70\x0c\x7d\xf3\x5f\x48\x51\x8d\x13\x95\x1b\x9b\xea\x3b\x6f\xd6\xbf\x8e\x79\xfd\x49\xf9\x27\x30\x1d\x64\xb8\x47\xd9\x9a\xb5\x87\xeb\xad\x55\xad\xcb\x85\x9d\xd9\xe9\xa7\xa1\x2b\x17\x2c\x4b\xfe\xc7\x9d\x2c\x0c\xd1\x3d\x3c\x56\x4d\x7b\x75\x3a\x9b\x58\xf2\x6f\x39\x65\x4c\x47\x21\x62\x91\xc0\x2e\x5b\xeb\x76\xbf\xad\xd6\xa7\x09\x7c\x20\x0d\x42\xa7\x29\xdc\x48\xae\xa6\x21\xd6\x34\x88\x0c\x48\x41\x9c\xce\x1b\x24\x1f\x44\x0f\x4d\x8d\x49\x7a\x6d\x5f\x92\x18\xcb\xd8\x26\x84\x77\x47\xde\x34\x61\x5f\x91\xf5\x8f\xff\x9b\x7f\xb8\x53\x52\xe6\x05\xb5\x56\x43\xb9\xb9\xc9\x95\x45\x96\x18\xf5\xb4\x87\xaa\xdb\x48\x51\x3b\x6e\x38\x0e\x7d\x3f\x6e\xc0\x71\x86\x7b\x00\xd4\xd5\xf9\x93\x33\x86\x49\x42\x6d\x76\xd3\xd2\xbf\xcd\x8f\xb6\x34\x12\xa6\xc0\xec\x42\x9c\xfa\xd3\xd1\x3d\xb7\x76\xa4\xb1\x62\x61\xe4\x25\x6d\x86\x3c\x02\x90\x26\x41\x88\xea\xaa\xe8\xc3\x8c\x57\x87\xf9\x6f\x9f\x26\x01\x43\x0c\xbe\x82\xc6\xc6\x10\x17\xe5\x2b\x14\xfe\x84\x89\x46\x14\xf8\x6a\x46\xc0\xef\xff\xf6\xaf\x3b\xa5\x12\x81\x05\xfb\xdd\xe7\x25\xca\xb3\x4e\x87\x12\x23\x31\xd6\x71\xf5\x44\xb5\xa6\x90\x64\xfc\x3e\x19\xd1\x81\x1c\x30\x78\x0f\x41\x29\xab\xb1\xbb\x99\xa6\x89\x21\x58\x40\xc3\xdb\xee\x73\x66\x72\xf9\x0d\x31\xcd\x54\x16\x5a\x6e\x22\x2c\xac\xe9\x4c\x92\x0b\x19\x7f\x48\x39\x35\x14\x1c\x2e\x67\xd6\x59\x63\xdb\xfc\x00\x45\x25\xdf\xa2\x31\xc4\x2c\xe5\x2c\x03\xe2\x54\x3c\xb5\xff\x15\x94\x34\x6a\xb6\x82\xff\x6b\xe8\x1f\xa4\x5c\x33\x2c\x30\xb8\x18\x22\x43\x83\x21\x15\x40\xb2\xc0\x01\x2a\xa7\xb3\x54\xd2\x08\x81\xaa\xef\xb0\xcf\x65\x01\x3b\xde\x34\x70\xf0\xb2\x95\x7d\x3f\xc8\x12\x74\xff\x77\x8e\x10\xad\x7c\x3d\xe5\xe5\x54\xdd\x6c\x7c\x8c\xee\xc6\x17\x4e\x9e\xe6\x64\x5d\xe4\x9f\x79\xbb\x37\x53\x9d\xcf\x4b\xdd\x41\xaa\xa9\x01\xa6\xf5\xe5\xd4\xa6\xa6\xaf\x72\xf9\xc6\xf9\xe3\xb2\x20\x4d\xd0\xb2\x30\xc5\xe3\xa3\x3c\xef\x17\x81\xfc\x2c\xe0\x19\xe2\x84\x3b\xf3\xd1\xd6\xe9\x3f\x9c\x0e\xf3\x4b\x76\x46\xa8\xc0\x4d\xb5\xce\xcb\x37\x10\x67\x17\xb5\xcc\x88\xe0\x98\x4c\x42\x9e\x95\x0d\xc8\x7a\x20\x1b\x3c\x17\xbd\xcf\x88\x8c\x30\xf6\x62\x02\x5b\x9d\xf9\x72\x5b\x3a\x36\x2f\xdf\x25\x41\x1f\xb5\xf1\x88\xc6\x4b\xf9\xaf\xc1\x9d\xa9\x14\x63\x83\x66\xa7\xb4\x72\x1e\xf3\xf5\xb7\x90\xc5\x11\x8f\x82\xb1\xe4\x8c\xf9\x24\x58\x27\xf1\x6d\xd2\x39\x73\x12\xae\xdd\xec\x5a\xa1\x55\x3b\x72\xad\x6c\xbf\x84\x72\xac\x51\x32\x03\xe4\x1e\x9a\x3d\x32\xa6\x8c\x8c\xd7\x2c\xc9\xc2\x94\xf5\xb4\xcb\x43\x1c\x9d\xeb\xa1\x35\x7a\x71\xae\x2e\x00\xe0\xdf\x93\x40\x6e\x46\x53\x8e\xc8\x47\x07\x39\xb8\xe7\xbf\x9e\xea\x4a\x77\x56\x87\x45\x2f\x3f\xea\xef\xd5\xa9\x99\x98\xbb\x19\x4b\x0d\x11\xe9\xf6\xe1\x69\xe9\xde\x72\x1a\x91\xc4\x06\x96\xfe\xf3\xa4\x5e\xe1\x73\x9a\xba\xae\xaf\x0a\x52\x97\x1e\xcd\xbd\xf6\x16\x64\x29\x05\x89\x32\x7e\x15\xfc\x1b\xca\x1f\x55\x3b\xe0\x27\x9d\xbc\xfa\x94\x29\xb4\x68\x0a\xde\xb4\xbb\xa6\xf0\xf9\xc8\x2c\x85\x18\xcf\xc1\x45\xd3\x7a\x9e\x1c\xc8\x38\x49\xf1\x59\xcb\xd3\x61\x55\x95\x43\xaa\x7e\xc8\x78\x64\x38\x4b\xee\x6f\x1f\xae\xd6\xdb\xdd\x11\xea\xcd\x93\x23\x9d\x83\x8c\x27\x26\x5f\x81\x4a\xa7\xf6\x7e\xc7\xcf\xc3\x2d\x39\xd8\x2b\xb4\xe8\x52\xed\x9a\xf6\x02\x11\x94\x71\x2d\x91\x8c\x77\xfd\xbc\x0c\xc3\x68\xeb\xd6\xfd\x39\xc5\xd0\xd9\x1a\x10\xc8\x54\x68\xb4\x3e\x10\x52\xdd\xeb\xf0\x75\x0d\xc0\x86\x86\x44\x33\x0a\x2b\x65\x4a\x18\x8c\xd1\xae\xe5\xaf\x33\xc5\xee\x90\x41\x18\x86\xd6\xc4\x7d\xac\xb9\x2c\xf2\x7f\x83\xa9\x7c\xba\xe1\xcd\x00\x34\x66\x7b\xeb\x8c\x92\x68\x08\xab\xb1\x00\x4b\x7b\x39\x1e\x24\xa6\xc2\xcd\xe0\x48\x5a\xe8\x1c\x63\x5e\x7a\x65\x7d\xe0\x24\x08\x31\xa6\x78\xe5\xab\x0c\x80\x93\x94\x21\xfc\x04\xb1\x5d\x57\xe7\x16\x06\x45\x19\xae\x4b\x16\xf3\x1e\x48\xb6\x91\xbc\xe0\x9f\x48\x55\xcd\xa4\x88\x38\x11\x82\x98\xac\x7d\x89\x8e\x59\x39\x58\x37\x47\x4b\x0a\x27\xca\x28\x9f\xc8\xea\x60\xc1\x80\xcf\x5e\x53\x13\x38\xd1\x06\x5a\xfa\xb0\xb8\x5f\xef\x36\x8b\xed\xe3\xe6\xfb\xad\x6b\x0b\x19\xa0\x2d\xe4\xf2\x32\xeb\x87\xd5\x40\x6c\x00\x78\x64\x75\x11\x91\x2e\xc5\x14\x0e\xfe\xe0\xa7\x62\x9e\xdf\x0c\x78\x94\xd1\xd0\xc9\xfe\xec\x36\xeb\xf5\x6a\xbd\xf2\x67\xe2\xca\x92\xd8\xff\xf4\x74\x8a\xe3\xcf\xc4\xe3\x20\xc3\x8a\x6a\xae\x94\xd1\x5c\x9a\xad\xda\x19\x0d\x04\x1e\x4b\x8d\xb5\x9b\x8b\xfb\xa7\xed\x70\x83\xe4\x09\xcd\x10\xb9\x7b\x75\xbb\x18\xfd\x4e\xa3\x8c\x44\x5e\x26\x0a\x37\x97\xd9\x9c\x11\xa7\x31\x8b\x5d\x6e\xff\xc7\x93\xa9\x37\xb4\x02\xff\x5f\x9a\x2d\x9c\xb2\x0c\xd7\x15\x84\x3c\xb4\xd0\xf4\xd9\x6d\x9e\x92\x30\xf2\x88\xa9\x85\x52\xcf\xd5\x80\xc2\x71\xf4\x5c\x29\x31\x90\x0d\x50\xf9\x1c\x13\xf6\x3f\x2e\x53\xbd\x3c\x0d\xc1\xac\x09\xbc\xce\xf9\xe8\x99\x53\x69\x08\x76\x4d\x48\xd2\xe4\x6b\xc7\xf7\x9c\x4a\x8d\x6c\xfd\x4f\xbc\x56\xf9\xe0\x86\xb3\x58\xc8\x9e\x86\xf3\xa5\x81\x7a\x5b\x9f\x9a\xf6\x99\x97\x6f\xd7\x55\xed\x04\x90\x2d\x71\xe5\x24\xee\x4f\xc2\x0b\xdb\x9b\x67\x49\x88\x6c\xb2\x9b\x23\x97\xf0\xe7\xe8\x26\xb3\xd4\xf0\xc7\x99\x05\xe1\x01\x3e\xa6\xbc\x50\xae\x9f\xe4\xb8\x6b\x9b\xba\x89\xeb\x51\xbe\xd2\xdb\x5e\x9c\x53\xc9\x0d\xcb\x07\x42\x67\x0c\x40\x6e\xb2\xbf\x71\xce\x29\xe2\x8a\xba\xa1\xbf\x19\x83\xdb\x38\x57\xa6\x82\xf3\xd5\x60\xdf\xaf\xce\x2b\x78\xcf\xa5\xa3\xff\x1a\x12\xf4\x01\x17\x24\x01\x2b\xe3\x73\x82\xe2\x1d\x16\xc7\xe3\xb8\x90\x1b\xb8\x90\x14\x69\x94\xac\x3b\xdb\x34\xa7\xee\xbe\x46\x9f\x74\x7e\x34\x09\x30\x3c\x20\x9d\x7d\x60\x71\x1d\xfa\xe4\xac\x6e\x2e\x49\x8c\x56\xf7\xcb\xc3\xed\x7f\x7d\x95\xca\xe2\x92\x86\x51\xd6\xa7\x79\x91\x6e\x73\x42\x6c\x01\x5c\xa6\x09\x5a\xd3\xe2\x54\x97\x37\xbc\x59\x94\xaa\xdb\x84\xe7\xe8\x06\x67\x22\xcc\xc3\xa1\xa8\xa2\x28\xb0\xd1\xbe\xd5\xa9\x7c\x85\xaa\xbc\x2e\xaa\xca\x0a\x8c\x4f\xbf\x82\x4a\xd3\xb8\x67\x0b\xe8\x3e\xa8\x25\xb4\x99\xf5\x6a\xb8\x52\xa6\x80\x40\x81\x38\xbd\x76\x0b\x79\xbb\x39\x09\xcf\x65\x6c\x3b\x01\x31\xda\x2c\x79\xe3\x8c\x27\xc7\x34\x3c\xbf\x70\x81\xe6\x92\xd8\x1a\xda\xfa\x1d\x1c\xd1\xb8\x6f\x15\x38\x6d\x97\x8b\xe7\xd5\x6e\xbb\xf8\x63\x3d\xac\x41\x04\xae\x21\xc1\x41\x5d\xc2\xc7\xca\x09\x39\xcd\xce\x6a\x11\xa4\x2a\xe5\x3d\x8b\x82\x8f\x97\xda\x81\x24\x88\x43\x1e\x23\x66\xea\x9b\xfb\x95\x49\x65\x6b\xce\xae\xe0\x35\x2f\x87\xd5\x15\xae\x4b\xc6\x95\xb9\xff\xce\xb0\x33\x38\x9d\x6e\x9d\x1d\x22\xbd\x06\xd3\x43\x90\xcc\x00\x9f\xdd\x8e\xf7\x54\xf0\x12\x7c\x86\x4b\x10\x9d\x61\x5e\xfd\x3f\xaf\x86\x53\x54\x84\xa9\x29\x05\x7e\xae\x84\xb7\x5e\x44\x14\x85\xaa\x67\x97\x58\x60\x16\x79\x7c\x73\x51\x2a\xc0\xc2\x73\xfa\x1d\xea\x69\x5a\x74\x20\x22\x4d\x71\x88\x1a\x22\xed\x6d\x7d\x82\x6f\x26\x6a\xd3\x0f\x2c\x44\x47\x21\x3f\x5e\x67\x36\x77\xbe\x85\xad\x3a\x74\x37\x93\x10\xa3\x1f\xd3\x18\x7a\x19\xb9\x87\xfb\xbc\xdc\xfe\x9a\x5c\x29\x89\x84\x8f\x23\x76\x96\x4f\xa9\x30\x0f\x6a\x23\xbb\x55\x69\x68\xf7\xf3\xaa\xc4\x78\x7d\x83\x7c\x7a\xab\xce\x8f\x79\xa8\x30\x19\x03\xad\xe7\x9c\xe8\x3d\x47\x41\x83\x18\x53\xfb\x37\x55\xf9\xba\xdc\x9f\x78\xf9\x3a\x7a\x79\x94\x70\xac\xb7\x83\x5f\x20\x4f\xad\x65\x81\x5c\xf2\xe2\xc2\x19\x1a\xfb\x2a\xa3\xc7\xa7\x21\x61\xa9\xf7\x88\x67\xc4\x9b\xbb\x2e\x8a\x39\xbd\x44\x2b\x8d\x3a\x10\x00\x9f\x1d\xfd\x82\x72\x96\x3a\x52\x6d\x43\x61\xe0\x73\x96\x82\xc5\x04\x03\xdf\xa6\x78\x65\x7c\x1a\xdb\x25\x13\x02\x91\x65\x43\x06\xf0\x17\xac\x76\xc1\x60\x68\xec\x4e\xc5\xc3\x18\x41\x9a\xf7\xf9\xab\xf1\xb9\x9b\xc8\x37\xa9\x10\x69\xf3\x6e\xea\xea\xa3\xdd\x3f\x55\x55\xb1\x1b\xc5\x2b\x04\xd7\x44\x59\x92\xbe\xb7\xfe\xe6\x04\x0b\x30\x3a\x7a\x78\x5b\x55\xc8\x30\x3b\x8b\xea\x10\x92\x28\x84\x07\x1e\x6d\x40\x79\x83\xfb\x29\x99\x8f\xbe\x08\xc9\x52\xb4\x2d\x97\xbc\xe9\x19\xe6\x40\xc8\xce\xe2\xb3\x83\xa6\x1b\x11\x6e\x61\xf9\xb9\x87\x72\xd3\x56\xc3\x09\x2b\xb9\x66\x60\xbf\xc1\xd5\xe9\x6c\x42\x12\x23\x13\x6f\xce\xe0\x13\x52\xd2\xd0\x82\x91\x91\xa6\x82\xe7\x4d\xbf\x08\x09\xa9\x0d\xa1\x66\xcb\x7f\x5d\x38\x84\xf3\x9f\x55\x85\x24\xa3\xae\x02\xdb\x1a\x39\xab\x07\x17\x8f\x17\x2a\xe3\xce\xdc\xfa\x92\xc8\x01\x84\x52\x24\xf1\x58\x8c\x09\xb5\x3b\x08\x88\x19\xae\xdf\xcb\xe5\xd3\xdd\xcb\xe6\xab\x5d\x48\x00\x33\xe2\x7d\x35\x74\x9f\x76\xd4\xa4\x41\xb1\xd4\x89\x11\xbe\x0e\x78\x08\x2f\xa6\xc5\xf0\x30\x19\x10\x40\x2b\xcd\xa8\xd5\x7f\x73\xbf\x4a\x66\x01\xaf\x9d\x4f\xd0\x6d\x60\x37\x7c\xb2\xed\x48\x42\x42\x3e\x46\xbc\x3e\x1e\xa1\x1c\xc1\xd6\x25\x11\x31\x1a\x08\x8b\xf2\xdc\xee\xf3\xf2\x75\x71\x3c\x5a\xdc\xc5\x48\x4a\xf2\xff\x2d\x49\x28\x89\x96\x08\xef\x92\x55\xf9\x0e\x75\xfb\xa9\xa6\x08\xc8\x90\x10\x6e\x45\xe4\xba\x11\xfc\xa8\x1f\xc6\x53\x51\x86\x92\xa1\x27\xce\xcd\xfa\x05\x7e\xaa\xc8\x50\x19\xaa\x10\xab\xe6\x37\xa4\x70\x04\x19\x05\x02\x83\xfb\xbc\x69\xf2\xd7\xf2\x2e\xc7\xf4\xd5\xea\x6a\x72\xf2\x6e\x1d\x97\xa3\x8d\x7a\x2e\x53\x20\x23\x4d\xa8\x01\x5b\xc9\xaa\x54\xcd\x6d\xb9\x72\xf2\x61\x20\x63\x10\x58\xe1\x7b\x53\x15\xea\x42\xbf\x6d\xb0\x41\xc9\x44\x48\xcc\x2a\x1c\x4f\x8d\x41\x3b\x4f\xc8\x5d\x2e\x0b\xf9\xbb\x63\x00\x9d\x15\x59\x9d\x8e\x93\xf1\xe3\xd2\x05\xb3\x26\x05\xf2\xea\x85\x36\x10\xe4\xca\x13\xba\xb5\x73\x32\x62\x58\xc8\x33\x43\x69\xfb\x6b\x79\x3a\x38\x45\x38\x9b\x5f\x75\x7b\xa7\x4c\x09\xf1\x11\x16\x0c\xaa\x0c\x7c\x31\x99\xa6\x92\x65\x23\x7d\x9b\xbb\xfc\x7f\x4f\xb9\xca\xdb\x09\x6e\x42\x66\x91\x14\x63\xf2\xf9\xdd\x2b\xf7\x17\xc9\x62\x86\xc0\xf0\xe7\x7d\x5e\xc2\xaf\xee\x53\x0c\x96\x2a\xc9\x43\x0e\x8e\x84\xb4\x7b\x50\xf4\x4c\x0d\x1c\x7e\x92\x39\xb2\x07\x08\x42\xa5\xfa\x14\x8c\xed\xec\x43\x29\x68\x82\xb5\x64\x79\xb3\xac\xea\x09\x29\x30\x48\xc1\x94\x21\x80\x86\xa6\xbd\x81\x76\xc9\x1b\x18\x66\x27\xa5\x8c\x22\x4c\xb6\x76\xed\xb8\x33\x49\x3f\x2c\xa4\x2d\x46\xfe\xeb\xe5\x69\x5a\xb3\xfe\xf5\xd4\x51\x34\x44\x7a\x0c\x95\xbf\x2f\x7d\xc1\x93\xd4\x11\xc5\x0d\x09\x49\x0e\x67\xeb\xb0\xa5\x66\x04\x51\x1a\x0a\x4c\x4e\xd3\x48\x6e\x4e\xfa\x28\x89\x80\xc3\x3f\xca\xea\xa3\xfc\x04\x9f\x3e\xfe\x68\x5a\xa7\x08\x38\x3f\xee\x1a\x68\x57\xf0\x3e\x9b\x36\x57\x81\x8e\x74\x0f\x41\xf9\xd1\xb9\x6b\x62\x20\xda\x35\xa2\x1f\xfd\xff\xb9\xb2\x8c\x9f\x56\x11\x1a\xe2\x87\x2b\xb9\x1c\xb1\x98\x81\x22\x69\x8a\x51\x8c\xfb\x87\xed\x88\x28\xc3\x37\x2b\x9c\xaf\xcb\xaa\x28\x78\x7b\x67\x15\x9a\x6d\x63\x44\x32\x54\x19\x28\x78\xd3\xde\x55\xf2\xcd\x22\xf1\x5c\x73\x4c\x88\x55\x6e\x6e\x1f\xe0\x63\xee\xec\x71\x94\x22\x47\x86\xae\x4e\x75\xbb\x47\x6a\x33\x4b\x8a\xe2\xcf\x91\x81\x91\x99\x5f\xfd\xb8\xdd\xac\x9f\x37\xbb\xc5\xc3\x6a\x77\xfd\x7c\xbb\x7e\x58\x6d\x76\x3f\x17\x77\x77\xeb\xad\xef\xaa\x18\x2a\xa8\xed\x1c\x74\xdc\x9a\x47\xb6\x39\x09\x02\xa4\x60\x3e\x9c\x91\x68\xe3\xc8\xcf\x5f\xed\x54\x2a\xa1\x29\x96\x01\x7c\x5f\x7e\xff\xdb\x62\x6d\x95\xb0\xc0\xc8\x91\x57\xaf\xaf\x05\x2c\x79\x69\x0a\x86\x6e\x3a\x73\xca\x5f\x1f\x78\x98\x3a\x06\xda\x6e\x85\x9d\x4c\x1f\x45\x93\x10\x3b\x34\xc7\xaa\x6c\xaa\x1a\x1c\x2e\xe7\xde\xcf\x6b\x45\x29\x71\x55\x2e\x4b\xa8\xdb\x5c\xe7\xb2\x5b\x88\xab\x7a\xbc\x0e\xcf\x0f\x4e\x45\xa9\x61\x4d\x3b\x75\x56\x45\xcf\xe1\xe4\x5a\x79\x0a\x6c\x50\xeb\x4d\xa2\xd1\xfe\xac\x58\x24\xe4\x38\x36\xff\x99\x4f\x38\x47\x9f\xeb\x4e\x92\x44\x88\xc6\x5e\xad\x7f\xac\xef\x1e\x9f\xd6\xcf\xbb\xeb\xf5\x7a\x77\xfd\xbc\x58\xee\xb6\x8f\x4f\xee\x56\x98\x34\x82\x0a\x7b\x5e\xf8\xb7\x93\x12\x10\xe0\xc2\x36\xcd\x31\xaf\xa7\x16\xed\xec\x86\xa9\xd2\x98\x73\x6b\x02\x3d\x9c\x0f\x4b\xe8\x2c\xdb\xc5\xd3\xed\xcb\xf3\x9d\x3f\x71\xc2\x12\xac\x80\xad\x5f\x2b\x7e\xf8\xf2\x33\x67\x60\x00\xc8\x4d\x55\x8c\xcb\x68\x15\x27\x0c\x4d\xff\x5d\x7b\x2a\xe1\x8e\x1f\x44\x35\x1f\x03\x56\x3c\xb4\x45\x96\x76\x8c\x6e\x3a\x73\x76\x4e\x96\x03\x14\xb7\x02\x18\x79\x77\xcf\xd0\x8d\x17\xcc\xf8\x7a\x2b\x53\x71\x21\xb3\xcc\x15\x9f\x60\xfe\xc0\x55\xde\xdb\x0e\x22\xd4\x28\xc9\x6c\xcf\xbb\xad\xae\xcc\xe2\x3f\xb9\x90\x24\x1c\x6b\xa0\x54\xde\x98\x38\x13\xc8\xfc\xe0\xeb\x35\x95\xcc\x0c\x9b\x8a\x25\x6a\x7b\x29\xf3\xd6\xc6\x7d\x90\x4e\xee\xb7\xd6\x69\x25\x79\x88\xc8\x95\x53\xd9\xf8\x18\xc6\x20\x0e\x68\x7b\xa9\x38\x46\xb7\xb3\x84\x0f\xa3\x8d\x3b\x2e\x84\x73\xbd\x94\xa9\x23\xc6\x50\xc6\x85\x95\x38\x70\x97\x94\x8e\x62\x84\x62\x7e\x6a\x2f\xcf\x4f\x14\x1d\x13\x2c\xdc\x15\xa7\xfa\xc2\xa3\x98\xbf\x4e\x6a\xbc\xce\x0d\xb4\x0b\x35\x92\x62\xfd\xec\x0a\x9c\xe8\x91\xf0\x3f\xfa\xe9\xae\x51\xb1\xd4\x46\x73\x11\x70\xa7\x86\xeb\x08\x90\x40\x23\x3e\x26\xb7\x5e\xaa\xc7\xcf\x43\xc8\x03\x62\x12\xb4\xc7\xa2\x3a\xe3\x37\x1a\x3a\xa0\x10\x4a\x90\x3e\x27\x57\xaf\x8c\xee\xc5\xa9\xed\x4f\x1d\xc5\x26\x8c\xd5\x5d\xf8\xd4\x76\xa3\xa9\xfa\x98\x95\x90\xfe\xad\x4d\x07\x62\x88\xf0\x21\xbb\xad\x01\x45\xbc\xcd\x2b\xc8\x1b\x83\x9f\x1c\xef\x05\x90\xa4\xa0\xe5\x70\x7d\xe9\x3d\x6b\x48\xc0\x08\xe4\x78\x21\xd2\xcf\xe9\x3d\xec\x11\x94\x65\x3a\xf3\x48\xa8\xa7\xaa\xc8\xe5\x79\x18\xc7\x72\xdd\xa4\x8c\xac\xd3\x31\xcb\xca\x69\xbb\x31\x12\xe3\x66\xb0\x33\xa7\xdb\x56\xc7\x5c\x8e\x56\x47\x60\x49\x86\xf4\xe3\x50\xca\x4a\x81\x63\x39\x9a\xf4\xa1\x01\xf2\x8c\xec\x79\xb3\x9f\x08\x32\x4c\xee\x9e\x89\xc8\x16\xe3\x59\x58\xfd\x2e\x9f\x26\x00\x26\x07\x48\x85\x99\xfe\xbc\xb9\x5a\x5e\x5f\x9d\xce\x26\xdc\xe9\x5e\x1f\x03\x53\x54\x8b\xc4\x6a\xbf\xcd\xe6\xd5\x1b\xd6\x90\x26\xcc\x53\xff\xee\xf2\xb2\x81\xba\xdd\xe9\xbc\x54\xdd\x0c\xfe\x9e\x97\xdd\xf2\xf3\x6e\x94\x54\xb6\x3c\x2f\xbe\x8d\x6e\x4d\x64\x5a\x67\x8e\xec\xcf\x61\x56\xfb\xc2\x58\x10\x32\xc0\xd8\x5a\x09\x1f\xcf\xc0\xb1\xa8\xc2\x37\x81\xa9\xda\x38\x5a\xb3\x63\xfc\x51\x24\x8b\x71\x22\x1c\xf2\xd2\xf3\x0b\xe5\x55\x79\xcf\xf3\x72\xc0\xcc\x00\x32\x53\x48\x43\x66\x05\x70\x7b\xa8\x3c\x48\xc1\x95\x0d\xa6\x5c\x63\xe0\xe2\x6a\x62\x23\xcf\x19\x8e\x20\x15\x48\x43\x27\x79\x67\x88\x27\xec\xef\x8a\x68\xc2\x07\xe5\x72\xb7\x25\xa2\x0d\x4e\xbc\xf8\x09\xf9\x38\x52\x33\x39\xa3\x8a\x14\x12\x05\xab\xaa\xac\xea\xbb\x7c\xa2\x30\x06\xa0\xd2\x94\x0a\x57\xdc\x77\x3a\x3c\x41\x7d\x59\xc8\x0c\x4a\x48\x34\xf9\xe1\x90\x7b\x12\x86\x6b\x00\xf3\x55\x26\x01\x39\x80\x20\xa0\xdc\x7b\x68\x68\x77\xe1\xb4\x6a\x16\x7e\xcc\x00\x0b\x58\x6a\x87\xe0\x54\x3c\x06\xba\xff\x1c\x59\xf2\x3d\xff\xf5\xd3\x56\x49\xda\x28\xa6\x0e\x48\x84\xe8\xa6\xbe\xac\x40\x13\x06\x5a\x3b\xde\xa6\xd6\xf3\xcd\x34\x57\xe7\xdb\xc9\xcd\x69\x22\xb4\x15\x51\xc4\x00\x96\x84\xfe\x93\xe9\x90\x29\x7c\xc9\x7b\xde\x3c\xf3\x7f\x3b\x6e\xbd\xe9\x19\x42\x1e\x69\xc7\xfe\xb6\xf8\xe8\x3c\x9f\xa7\xba\x7a\x1d\xa0\x2d\x74\x28\x4d\x79\x14\x46\x46\x1e\x0e\x33\x10\x1b\xdb\x31\xd2\x06\xc9\xf4\x5e\xb5\x60\x15\x1a\xbe\xf9\x26\x83\xd8\xb8\x5a\x6f\x37\xbb\xe5\xdd\xe3\xe6\xf6\xe1\x66\x98\x3b\xd3\xb1\x32\x6a\xc5\xbd\x98\xe0\xd0\x2c\x1d\x5f\x27\x06\x15\xdb\x17\x6a\x32\x4d\xa6\xeb\x04\x96\x3e\x9a\x00\x3a\x09\x12\x1c\x89\xb8\x6f\xbf\x43\x6d\x0a\xce\x9b\x97\xb2\xcd\x0b\x17\xed\x1e\x5f\x25\x61\x21\x2a\x65\x34\x68\x69\xbf\x1e\xda\x0d\xca\x11\xbb\x1b\x4e\xa4\x42\x97\x53\x55\xd7\x3c\x2f\x40\x5d\xea\xd3\x83\xa6\x61\x88\x45\x5a\x38\x47\x0c\x7f\xfc\x30\xe5\xa9\x69\x62\x2e\x81\xc5\x85\xd7\xbc\x3e\xac\xe0\x7d\xe3\x81\xda\x9a\x26\x31\xee\x94\x7f\xad\xee\x41\x8d\xb3\x54\x9a\x72\x85\xfb\xfa\x84\xb4\x46\xb3\xd8\x00\xb1\xd6\x47\xee\xcf\xc3\xd2\x84\x5a\x84\xd9\x7e\x2e\x08\xa1\x59\x16\x23\x1f\xd8\x6a\xb1\x45\xfe\x6b\x97\xdd\xf4\x27\xe0\x32\x56\x0e\xad\xf7\x8c\x5a\x33\x33\x71\x72\xcd\x44\x14\x38\x34\xd0\xed\x0e\x54\xde\xee\x88\x8b\x67\xea\x34\x90\x18\x11\x34\xe9\xdd\x30\x70\x16\xfd\xb6\xf2\xf7\x9e\x86\xb1\xa9\x62\xca\x7f\x21\xc2\xd6\xff\xae\x38\x06\x2e\x17\x45\x5b\x9f\xf2\xc6\x3f\x57\xc6\x08\x22\x88\xaf\xaa\xb7\xb7\xf3\x53\x55\x5d\xf1\x7d\xb3\x38\xb5\x55\x59\x1d\xaa\x53\x63\xca\xf3\x78\xbb\xaf\xca\x6b\x2e\xf3\xc2\x8b\x2c\x80\xce\x94\x82\x9e\xa8\xc8\x90\x04\xc3\x88\x88\xdd\x76\xe4\x12\x30\x63\x54\x9e\x0e\x68\x7c\xd6\xcd\x75\x55\x3f\x55\x45\x31\x4e\x58\x69\x11\x2b\xeb\x20\xf3\x76\x8f\x1e\x01\x67\xee\x62\x22\x0d\xa9\xcd\xbe\xdf\x54\x85\xfa\x92\xa6\x41\x0b\xc1\xd0\xaf\x71\x8b\x7f\x55\x7c\x92\x84\xd1\x42\x6a\x2c\x0a\x3d\xe4\xe5\x4f\xc8\x51\xe3\xda\x5f\x51\x19\x55\x90\xc6\xd4\xf7\x5f\xe5\xea\x56\x4d\x6e\x58\x92\x84\x1a\xde\x81\x02\x9a\xf0\x2e\x17\x35\xaf\xcf\x0b\xc5\x8f\xed\x94\x73\x40\x2b\x62\xd4\x94\xdc\x2d\x79\x51\xa6\xdf\x2d\x7f\xfb\x84\x27\x76\xb8\x08\xaa\x48\x62\x45\x94\xf7\xf7\xd6\xa5\x1a\x32\x42\x68\x25\x08\x5a\x5b\x47\x83\x5b\xd9\x56\x5b\xfe\x06\x8b\x66\xd3\xd7\x78\x6a\x08\xb5\x34\x82\x11\x46\x1b\xc6\xd0\x2d\x8c\xfc\x5a\xad\x99\xe2\xbd\x63\x64\xf5\x82\xfd\x42\xa7\x53\x81\xb4\xdd\x4f\x35\x7f\xe3\xcd\xbe\x57\x27\x00\xad\x55\x38\xe2\x90\xb8\xbe\xa0\xcf\x1e\x7d\x1e\x1d\x10\x11\xa3\xb7\x6e\x2a\x79\x6c\xa9\xa8\x6d\x0b\x89\x91\x75\x9f\x4f\x2f\xfe\x63\x9c\x68\xd4\x41\x18\x43\x46\x86\x40\xee\x75\xbb\x1f\x05\x26\x74\x10\x31\x43\x58\x6c\xe8\xc8\xb1\x80\x75\x80\x94\xd7\x41\x94\x0a\x6a\xd0\xe4\x3a\x2f\x0a\xcc\x1a\xba\xa6\x44\x44\x60\x24\x8f\x8e\xc7\xf3\xef\x55\x4d\x74\x07\x65\x56\x9c\x03\x4d\xbc\x8b\xe0\xa4\xed\x46\x93\x08\x83\xdd\x73\xb5\x7e\xe3\xd7\x45\x93\x98\x28\x47\xcb\x3b\x20\x42\xea\x5a\x44\xcc\x1d\x64\x0c\x11\xa5\xc3\x91\xac\x03\x9a\x99\xea\x45\x13\x1f\x32\xfb\xc1\x14\xd4\xa2\x03\x16\x69\x84\x07\xbd\xf2\x6e\xa9\x1d\xa6\x56\x69\xec\x5f\x34\xe3\x91\xaf\xcc\x29\x8a\x07\xf8\x30\xd2\x29\xdf\x46\xe3\x78\xa8\xab\xf0\x85\xf6\x8d\x0e\x98\x50\xc4\xc9\x7e\xed\x34\x40\xb3\x83\x76\xbf\xab\x86\xcf\x96\x65\x09\xb2\x9d\x75\x1b\x26\x6e\x42\x23\x95\x48\xbf\xb2\xea\x40\x44\x0c\x3f\xd2\x0f\xa8\x73\x43\x02\xdd\xef\x05\x3a\x50\x49\x98\xd1\x3e\x1f\xdb\x8b\xc7\xbb\xf6\x2c\xc3\x10\x81\x72\xf9\xd6\x9d\xf9\x98\x3b\x27\x75\xba\x7b\x87\x3a\xd7\x39\xa8\x19\xf8\x90\x0e\x14\x0f\x13\x61\xad\x1b\x57\x1f\x33\xf5\xd8\x26\xaf\xc8\x1f\x99\x60\xbc\xcc\xac\xf9\x7f\x57\x2c\x74\x11\xd8\xd6\x01\x44\x69\xe2\x2b\xe6\xcc\x24\x1a\xd6\xfb\x7d\x09\xc0\xd6\x01\x28\x2d\x7a\x16\x81\x6f\x33\xcb\x10\xb1\x3d\x35\xd1\x46\xa2\xcd\xaf\x71\x46\x58\x67\xdd\x4f\x5a\xcd\x58\x8a\xc5\x1a\xc8\xf7\x3c\x72\x80\xe6\x86\xc1\x45\xee\xff\xf3\xc9\xa4\x65\x88\xbb\xd1\x33\xf0\xe2\xbe\x2a\xe1\x3c\xfc\xb8\x24\x88\x25\x32\xc4\x20\x57\x1f\x26\xc7\x06\x6a\xc4\xce\x78\xad\x2f\x57\x63\x7b\x38\x21\x01\xb2\x4a\x1c\x73\x59\x1d\x1b\x1b\x08\xf3\x23\x90\x90\x50\x52\xb3\x13\x96\xd5\xa9\x94\x18\x51\x9c\xec\x00\x9a\x90\x28\x20\x36\xa5\x6e\x79\x1a\x5e\x9e\x6f\x87\xee\x9a\x26\x61\x44\xc0\xd9\x88\x88\x46\x42\x31\xe5\xf1\x69\x62\xc2\xb1\xe8\xdd\xd2\xed\xfd\xac\xf3\x76\xbe\xb2\x5c\x93\x98\x6b\xac\x8c\xd9\x9c\x44\x33\x52\x21\xfb\xad\x52\x6b\x4d\x62\x30\x32\xbd\xd5\xd1\x4e\x95\xa1\xfc\xab\xed\x93\x64\x80\x99\x17\x23\x98\xde\x99\x0a\xf5\x79\x4c\xd1\x35\x39\x29\x65\x21\x73\xe1\xb1\xd3\x61\x5d\xc0\xa1\x57\x6f\xd7\x84\x11\x62\x98\xa0\xf2\x03\x8c\xaa\xc8\x34\x61\x34\xc5\x3c\xbc\x38\x9d\xa1\xb6\x9c\x27\xae\x2d\x8d\x13\xd4\xed\x71\x23\xcf\xc6\x93\xcc\xb6\x35\xab\x19\x32\xbe\xa9\x34\x36\xd8\x04\xbf\x31\x19\xac\xfc\x33\x34\xd5\xa9\x96\x5e\x86\xe3\xd4\x57\xf5\x68\x92\x26\x11\xda\x59\xcd\x49\x1c\x72\x43\xff\x33\x30\x4b\x35\x49\x19\x43\x66\xaf\xa3\x61\x69\x31\x10\xa8\xd1\xe7\x4e\xb9\x11\xea\x55\xe6\x6e\xc7\xf8\x1d\x4d\x32\x9a\x32\x5b\xc6\xea\x75\x1e\xc6\x19\x45\x4d\x32\xc9\xac\xfd\xbc\xf1\x6e\xce\xb4\x0f\xa7\x1a\xcb\x55\xaf\x16\x2e\x04\xa9\x89\x88\xc0\x55\x38\x2f\x9e\xec\x1e\xdc\x83\x25\x35\x11\x31\xe5\x26\xe4\xa3\xbd\x17\x31\xbf\x47\x13\xc9\x43\x8c\xa2\x38\x54\xef\xb3\xad\x3a\xfa\x74\x32\x29\x12\x23\x55\x19\x0c\xff\x73\x17\x56\xcc\x70\x03\xfc\xb1\x5e\x8d\x26\xb0\x4a\x03\x64\x4a\xc7\x0d\x6c\xfb\x6b\x40\x8e\xee\x56\xa1\xc1\xea\x31\x45\x31\x68\xa2\xb2\xc0\x99\x2c\x96\x93\xe4\xf1\x98\x97\xde\x99\xd5\x04\x88\x44\x93\x71\xe7\x23\x06\x9f\x4e\x96\xe1\x79\x21\x49\xd1\xa2\x59\x6f\x5f\x46\xb7\x0b\xa9\xc4\xc9\x7e\xbf\xf8\x73\x77\xff\xb8\x7a\xb9\x5b\x6f\x5c\x93\xa6\x12\xcb\x9b\x15\x14\xdd\xc8\xbc\x9b\x91\xb3\x77\xbb\x1f\xd1\x32\x61\x16\xa2\xbf\x3b\x1a\x50\xed\xd7\x53\x56\xeb\x24\xce\x5c\xc0\xcd\xad\xba\x61\x18\x2a\x4e\xbc\x24\xce\x7d\x75\x40\xd0\xf2\x2c\xee\x58\x87\x21\x33\x21\x67\xac\x3b\x32\x85\xb5\x96\x56\xde\x15\x1f\xbb\x8e\xd2\x18\x67\x48\x36\x78\xee\x76\x16\x09\xf9\x71\x62\xbd\x84\x51\x1a\x07\x0e\x82\xec\xf7\x54\x5b\xab\x34\x21\x51\xd0\x61\x4c\x4c\x0a\xd6\x25\xbf\x2f\xa5\x65\x74\x18\x6b\xaa\xad\x0c\xf1\x8b\x89\x0f\xcf\xd2\x62\xe8\x30\xb1\x29\x39\xef\x0b\xdf\xf3\x5f\xc3\xb0\xcd\xa4\x3b\x03\x43\xf0\x77\xe3\x14\x0d\x16\xed\xe4\xca\x4c\x53\xa7\x9f\x64\xde\xcb\x0d\x94\x50\xf3\xce\xf3\x1d\x12\x63\x75\x1d\x4d\x35\xdc\x9e\x97\xea\x02\x07\x33\x3b\x8b\xc2\x34\x24\x18\x5a\xda\x2c\xb7\xcb\x2f\x32\x02\x3a\x4c\x45\x84\x10\x8a\x43\x5e\x3e\x81\x91\x79\x74\x2d\x52\x30\x5b\xaa\x69\x57\xfc\xe3\x48\x78\x62\xfc\xb8\x19\x25\x18\x4b\x30\x74\x73\xd7\x06\x47\x43\xdc\xb9\x78\xa6\xd1\x95\xe8\xc6\xef\xcd\x62\xe3\x7f\x06\x0e\x03\x40\x11\xe6\x9c\xaa\x7a\xf2\x9a\xb8\x4e\x91\xb2\xf0\xae\x7a\xad\x7a\xeb\x5f\x87\xc2\x0a\xf9\x9a\x6a\xb5\x3d\x6f\x20\xf2\x4d\x82\x52\x5b\xd0\x27\xf7\xb3\xac\x6d\x3a\x14\xa0\x31\xef\xba\xe7\xcd\xb6\xdb\xbb\x4b\xde\xf6\x23\x5c\xe8\x18\xa3\x2b\x57\x79\xdb\x5d\xf2\x99\xb7\xd3\x38\xd4\xe4\x7d\x2b\xce\xc0\x8c\x72\xc5\xcf\x2b\x7e\xf6\xa3\x1a\x02\x89\x11\x40\xe4\xa4\xac\xca\xc6\x05\xa3\xe7\x13\xf9\x3a\x84\x50\xa0\xfb\xac\x3f\x81\x2d\xba\x6e\xb1\xc1\xf3\x75\x13\x70\x95\x37\xc7\x53\x0b\xea\xd6\xb0\x3e\x6c\xe0\x7f\x4f\x50\x4a\xf8\x59\x57\xe5\x2b\xee\xe7\xa3\x42\x1d\x1d\x02\x4d\xa9\x0f\x70\xc0\xe9\xb0\x83\xfc\x75\xdf\xee\x04\x7f\x7d\xed\xbf\x3e\xa4\x71\x66\xa1\x35\x87\xce\xfc\xf9\xec\x3e\x84\x44\x31\x88\x9b\xfb\x21\x9d\x99\x0e\x41\x93\xd0\x97\x88\xb8\x52\xb1\xf1\xa1\x3a\x35\x04\x4a\x9d\x75\x32\x11\xf8\xd4\xa1\x16\x41\x0a\xde\x97\xb1\xdb\xfa\xf8\x0b\x46\x41\x1c\x08\xbb\x60\xdc\xdf\x3e\x2f\xae\x16\x77\x8b\x87\xa5\x8d\x5d\x75\xad\x14\x2d\x7d\xe0\x75\x71\xee\x56\x0a\x39\x80\xba\xe9\x28\xc8\x08\xc6\x9b\x3b\x1b\x24\x9c\x7f\xb8\x28\x00\x15\x0e\xb7\xf1\x7e\xff\x1f\xbb\x64\xe3\xa3\x08\x70\x74\xcd\xf7\x2e\xc7\xe6\x2b\x80\xc6\xcf\x18\x85\x8c\x60\x00\xc7\x62\x8f\x37\x28\xda\x31\xef\xc0\x5b\xcf\x9c\x64\xfe\xaf\x3b\x47\x66\x08\xb9\x57\xf7\xcb\x6d\x8f\x9f\xd0\x51\x14\x50\x8a\xa8\x82\x6e\x9d\xaa\xde\x27\x9e\x57\x14\x71\x13\xa1\x3c\xd6\xd0\xf9\xc2\xb2\x3b\xb4\xf1\xc7\xca\x04\xa7\xb2\x65\xad\xfe\x0a\x58\xa5\xa3\x98\x50\xa4\x02\xcc\x1b\xe4\xcf\xbf\x42\xc8\xa2\x3b\x13\x25\xd4\xa1\x38\x1e\xe0\x57\xfb\x38\x80\xa8\x7f\x6d\x2b\x46\x94\x64\x4e\x45\xd8\x54\xc7\x60\x11\xf8\x80\x2f\x5f\x47\x2c\x92\x2e\x82\xfb\xfd\xac\xea\xea\xab\x18\x8e\x8e\x98\x88\x23\x57\x29\xb5\x3d\x1f\xe7\xb9\xbd\x75\x94\x66\x11\x68\x47\xbb\x33\xa2\x13\x9a\xdd\xdd\xa2\x2c\x53\xb8\xcf\x9b\x0f\x2d\xe1\xaa\xfa\x35\xb9\x70\xa6\x15\x92\xe6\x59\xf2\x7b\xb3\x8c\x5c\xb8\x6a\xbd\x7b\x15\x71\x6e\xf4\x19\x8c\x6f\xad\xcd\x6d\x80\x1a\xf3\xb1\x5f\xda\x24\x91\x90\x41\x2c\x7b\xde\x9c\xeb\x53\xa9\xcc\xc8\xeb\x09\x28\x74\x24\x89\xa9\xcb\xaa\xb9\xc2\xa9\x39\x84\x28\xea\x48\x86\x11\xa6\xa8\xf3\xc6\xf9\x5a\x0f\x55\xeb\xea\x7a\xe7\x70\x37\x3a\x92\x94\xa6\x96\x9d\xac\x28\xa0\x73\xf6\xab\x6a\x5e\x67\x59\x47\x32\x23\x18\x59\xe5\x52\xd6\x27\x18\x90\xb7\xe9\x48\x72\x42\x4d\x20\xb2\xfa\x40\xc9\xf3\x0b\x69\x73\x1d\x49\x10\x52\xb9\x22\x7e\x14\xa1\x42\xc1\xbc\xba\xf9\xec\x63\x2a\x1a\xa1\x91\xa7\xb1\x0e\x0b\xd3\x89\x5f\x79\x87\x97\xe1\x82\x48\x31\x8d\x96\xce\x81\xff\x5a\xb4\x6d\x37\xfc\xc0\x4f\x13\x88\x94\x08\x06\x9c\x02\x3f\x01\xde\x8a\xf3\x20\x58\xf0\xa3\x2a\x4e\x07\xd8\xd8\xd4\xcf\xf8\xd6\x34\x0b\x30\x8a\xfc\x9a\x6b\x8f\x54\xd5\x71\x10\x81\xb2\x9f\x70\xbb\xef\x3e\x8e\xf8\xda\x3e\x8b\x3b\x37\x75\x48\x8b\x79\x53\x15\x0a\xbd\x55\x77\x46\x12\xaa\x78\x10\x7f\x33\xfc\x9b\x6e\x43\xf4\x7d\xb4\xf6\x25\x1d\x46\x88\xf4\x89\x9f\x3f\xa1\x71\xd2\x31\x91\x12\x9c\x4a\xd0\x10\xe8\x77\xf9\xfa\xe2\x90\x30\x74\x39\x9a\x8f\xbc\x95\xfb\xc7\x07\xdc\xd4\xaa\xba\x33\x70\x5c\x8f\x4c\x60\x46\xf1\x39\x77\x35\xf7\x3a\x8e\x18\x38\xa1\x3e\xf4\x3f\x8c\xfa\x9e\x6b\x84\x38\x33\xb0\xf8\x15\x6f\xf9\x5f\x4e\xda\xd7\xb6\xc6\x41\x68\x42\xbe\x1e\xe2\x61\x19\x47\xbd\x94\xc6\xa2\xb4\xd1\xc7\x4f\x81\x50\x33\xcf\x91\x10\x8a\x45\x60\x47\x7e\xde\x56\xb7\xe5\x7b\xde\x4e\xb2\x0a\x3a\x4e\xc2\xd0\xc6\xca\xda\x3a\x87\x77\xb8\xed\x35\x49\x86\xbe\x85\xef\xad\xf0\x95\xdb\x45\xa1\xa7\x16\x1d\xbf\xea\x84\x4a\xbc\xae\x01\x35\xba\xb8\xe9\xb6\x5a\xcb\x6a\x88\x7e\xd4\x71\x22\x09\x33\x1a\x4b\x7f\x6d\x36\xd3\x07\x9b\x70\xe7\xe8\x98\x2a\x86\x38\x5c\x7e\x30\x10\x4c\x2f\x38\x6e\x56\x7c\x37\xc2\x63\x96\xc6\xf8\x71\x78\x51\x4c\xc4\x37\xba\x36\x8d\xd6\xe1\x7d\x5e\x74\x9b\x5b\xcf\x05\xd9\x47\x90\x75\xcc\x04\x37\x1a\x2f\x45\x37\x09\x9c\x18\x9a\x8e\xd3\x90\x18\xad\x79\xbb\x64\x3b\x03\xc1\x35\xb3\x18\x03\x6b\xa8\x43\x35\x35\xdf\xfa\xa7\x19\xcd\xdc\xa1\x51\x1b\xa7\xda\x48\x94\x74\xd3\x76\x10\x6a\xd6\x71\x16\x69\x2c\x8d\xb6\x38\xd5\x6d\x75\x9f\x97\xf9\xe4\x4b\x66\x49\x9c\x11\x17\x08\x6e\x9c\xd6\xb3\x6b\xa4\x31\x04\x2e\x6d\x58\xbf\x21\x03\x8d\xaf\x57\xcb\xab\xe9\xa9\x18\x47\x1a\x48\x24\x4b\x5b\xee\x79\xfd\x0a\xbb\x23\xf1\xe7\x52\x09\x92\xd1\xfe\xd7\x66\x6b\xb8\x2c\x5d\x03\x8f\x19\xd6\x50\xd8\x92\x25\xfc\xff\x6c\x39\x86\x8e\x05\x31\x61\xc0\x57\xf4\xe8\x60\xf7\x76\x96\x3b\x51\x95\xa7\x66\x57\x9e\x0e\x50\xa3\x39\xed\xba\x86\xa9\x63\x6f\xb5\xa1\x10\x50\x86\xcd\x67\xfc\x65\x85\x15\x11\xeb\xb6\x5e\x44\x1d\x2c\x2f\x30\xfa\x3a\x96\x8c\x68\x32\x50\x2e\x5d\x6f\xbf\xbb\xeb\x28\x15\x62\x52\xfa\x60\xd2\xea\xb9\x9c\x27\x9d\xd3\x31\x70\x41\x2d\x9a\xc0\x8a\x0f\x0e\xd2\x9c\x93\xae\x2a\x10\xa6\x38\x44\x98\xd8\xc9\xd5\x49\xbe\x41\xdb\xf8\xaa\x42\xdb\x4f\x47\xa6\xfc\x07\x69\x54\x8b\xe2\x81\x1f\xc6\x31\x92\x24\x88\x8d\x71\x86\x6b\xdd\x92\x97\x0a\x59\xd2\xbe\xb9\xd6\x34\x54\xaa\xcf\xd1\xcc\x7b\xb4\x09\x09\xc2\x54\xf9\x0d\xba\xb1\x49\x55\xc3\x76\xb3\xfe\x35\xcd\x7e\xeb\x84\x24\xa6\xd2\x13\xfb\xcf\x55\xea\xe9\x6e\x7d\x41\x73\xde\x56\x75\xbe\x94\x28\xa2\xf1\xcd\x0b\x50\x7e\x42\x94\xa2\x13\xa2\x12\x3c\xb7\x7d\x2d\xf7\xfc\xf8\x54\x35\xd3\x93\x2b\x81\x2e\xf3\x3d\x78\x10\x8e\x4e\x42\xc8\x10\xc1\xe9\x20\x4c\x4b\xde\xec\xaf\xab\xfa\x3b\xaf\xd5\x07\xaf\xe1\x19\xda\x53\x3d\x71\x95\x93\x28\xd5\x08\x46\xaa\x8e\x50\xfa\x0a\x08\xf4\xbc\xdc\x59\xa3\x4c\x51\x33\xe0\xd5\x2c\x59\xa7\x4e\x22\x08\x1c\x79\xd3\x13\x3f\x35\xa0\x7a\xaa\xd2\xde\x06\x4a\xe2\x20\xc6\xc4\x33\x46\xb9\x1c\x9e\x79\xfc\x25\xe3\x50\x22\x20\x14\x0e\x79\xbb\xa8\x81\xaf\xdf\x79\x71\x1a\xca\xb2\x8f\x0c\xe8\x74\xf2\xde\x62\x4e\xe4\x40\xfa\x60\x5d\x9a\x3a\x16\xdf\x0a\x58\xb7\x2a\x4e\xe7\x24\x18\x90\xc3\xea\x24\xd6\x3c\x4b\xdd\x02\x52\xe2\x98\x75\x6b\x43\x42\x23\x82\x73\xd1\x10\xb1\x22\x5b\x9a\x6b\x11\x36\xc6\xc0\x35\x7c\x52\x3b\xaa\x13\x0a\xc4\xe8\x3f\xbd\x43\xcd\x5f\x61\x51\xb7\x1f\x55\xfd\xd6\xd9\x42\xa3\x3b\x48\x49\x80\x41\xdd\x97\xab\xdb\x6d\x18\x90\x34\xa0\x99\x6f\xa2\x29\x5a\xf5\xc6\xde\xb1\x93\xdb\xb5\x65\x49\x66\xe0\x44\xcd\xa9\x68\x1b\xa4\x89\x6d\x3c\x4b\x97\x4e\x52\xeb\xeb\xa8\xbc\xe9\xee\xfe\xaa\x1a\x63\x3d\xac\xfc\xb6\x4e\x32\x4a\x53\x1b\x42\xda\xec\x8f\xae\xc0\xf1\x79\x5a\x7a\xad\x93\x2c\x4d\x50\x81\xec\x8f\x1f\xf7\x43\xcf\x30\xc9\xb2\x38\x90\x23\x7a\xc7\x23\x94\x46\xfd\x70\x32\x54\x78\x96\x22\x66\x4a\xd5\xfc\xb5\x2a\x6f\xf2\xba\xb0\x14\x07\xa3\xf7\x21\x04\xa1\xf6\x86\xbe\x0d\x55\x0d\xfb\x3b\x51\x29\xc5\x4a\xed\x65\x7d\x3e\xb6\xd5\x53\x55\x35\xa3\x1b\x52\x22\x51\xb6\xe0\xaa\x07\x32\x4f\xb2\x22\x6e\xf2\x0d\xd2\xeb\x53\x69\xcd\x7f\x86\xfd\x76\x14\xfe\xcf\x3f\xc6\x77\xa0\x19\x09\xfc\x82\xde\xc7\xfb\xc7\xcf\x0b\x51\xea\xb4\x8a\xae\x4e\xe7\xbe\xc6\xd5\x2a\xa0\x13\x57\x07\x30\xbb\x9a\x26\x3a\x8c\x1c\xd3\x41\x9d\xb7\x67\xb3\xa5\x7e\xf3\x8d\xdc\xb0\x76\x1e\xa0\x54\xcf\xd0\x9a\xa1\x7b\x51\x07\xaa\x13\x4d\x0d\xb7\x28\x12\xa7\xa1\xb4\xce\xc5\x6d\x6a\xce\xd2\x70\xac\x85\x87\x22\x15\xf3\x0b\x94\x96\x3c\xb3\xa0\xa2\x75\xa9\xab\x5a\xba\x68\xc4\x3d\x6f\xe5\x7e\x30\xe7\x69\xc0\x28\xba\xf3\x46\x37\xf3\x9b\xfb\x95\x27\xb8\xe6\x38\xa4\xcc\xcf\xbc\x50\x72\x50\xa0\x37\x5e\x9b\x69\x00\x3a\xb6\x14\x0d\xbb\x3d\xf0\xe3\x64\x23\xa1\x81\x8e\x31\xa7\xd4\xeb\x3a\x9f\xfc\xa5\x08\x0f\x31\x6a\xe4\xb1\x16\xdb\xef\xeb\xe7\xdd\xfd\xed\x83\xe1\x01\xbb\xbd\xf2\x1d\x85\xd1\x1c\x44\x0b\xe1\xc6\xfd\x1a\x46\x40\x12\x4b\xd1\xd2\xe4\xa2\x80\xdd\xa9\xf4\x45\x15\x9a\xc6\x89\xc9\x9e\x20\x3d\xf5\xf1\xd4\x5e\xe7\x03\xf1\xd7\x91\x75\x48\x63\xa6\x50\xfa\x00\xda\xbd\x49\xea\xdf\x43\xd3\x70\xa4\x6d\xd6\x4e\xad\x5e\xd3\x58\x24\xb8\xdc\xa0\x1f\xe7\xef\x2d\x49\x62\xf4\xc7\x9f\xb9\xd6\x05\xec\x9e\x7a\x9e\x2b\x4d\x13\x65\xaa\xb3\xba\xb9\xfb\x96\xf7\x64\x8e\xf3\xd8\x00\x7f\x3b\x89\x62\x41\xd4\x13\x6b\xcf\x3b\x82\x34\xd1\x1c\x2d\x02\xf4\x1d\xd5\x49\x8e\xf9\x55\x35\x65\x2c\x46\x61\x94\xdb\x87\xdb\xed\xed\xe2\x6e\xf7\x63\x71\xf7\xe2\x82\x35\x34\xa5\x29\x96\xef\x41\xa9\xae\xf3\xba\x31\x92\xa7\xbe\x31\x0d\x30\x89\xb3\xc9\xbb\x21\x70\xd7\xab\xea\x6a\x9a\x66\x86\x0a\xd3\xc4\x00\x7f\xac\x27\x5f\x9b\x93\x28\x20\x4e\x44\xe7\x69\x08\xfd\xd7\x94\xc7\x09\x06\x55\x9f\x1f\xef\xd6\xbb\xe7\xf5\x8f\xdb\xf5\xcf\xf5\xb3\x6f\x94\x1a\x03\x93\x3b\x33\x4e\x9e\xa7\xf2\xdf\xfd\x25\x54\xa0\xf0\x0e\xcc\xce\x8d\x3b\xe2\xb0\xa0\xdb\xf5\x52\x9e\xb1\xf4\xa9\xae\xfe\x05\xb2\xdb\x71\x2e\x18\xf6\x35\x85\x28\xc5\xea\x5a\xf4\x19\x1e\xf5\xb2\xa8\x4a\xf8\xc9\x6b\xff\x2a\x80\x47\x86\xf8\x09\xc5\x11\xed\x4c\x99\x75\xd3\x28\x48\xc0\xf5\xe0\x1d\x9a\xb6\xdf\x65\xbf\xce\xf8\x53\x50\x1a\x01\xaf\xbc\x69\x4e\x35\xac\x16\xc7\x63\x67\xdf\x70\xe5\x4c\x73\xaa\x53\x91\xd8\x42\xd8\xf5\x2f\x59\x9c\xd4\xc4\x92\x61\x41\x64\xd2\xf5\x7d\x66\xc4\xab\xbf\x7f\x73\x5d\x62\x8d\xe0\x64\xf3\x6e\xcd\x3a\x37\x3b\xa6\x58\xa0\x32\x2e\x9d\x08\xee\xc4\xac\x62\x84\xa4\x92\x39\xbe\xa1\x77\xe0\xc5\xe3\x71\x1a\xdc\x67\x24\x34\xde\xa2\xd9\xa5\x1e\xeb\x57\x5e\xe6\x0d\x7e\xa4\x0b\xd3\x90\x85\x61\x8a\x25\x82\xe6\xb6\xbe\xf3\x66\x6f\x36\xd0\xd9\x38\x2d\x0b\x23\xe1\x14\xb7\x6d\xa8\xe2\x19\x8e\x15\x96\xbe\x0d\xf7\x5d\x16\xf2\x04\x93\x9e\x47\x8c\xf0\x3f\x55\xc7\xce\xe3\x18\x10\xac\xf4\x0b\x20\x0b\x75\x9c\x04\xce\x4e\x9c\x3c\x48\xa4\xa8\x0c\xa6\x1a\x58\x63\xbc\x09\x8b\x69\x88\xf5\x21\x2a\x6f\x8e\x43\x66\x4a\xd7\xcc\x8d\x22\xda\x11\xe4\xa9\xcc\x47\x04\xd7\x9a\xc5\x42\x28\x07\x7a\x98\x37\xd7\x59\x2c\x09\x95\x6e\x0c\xe7\xff\x86\xa7\xca\x1f\x9d\x88\x04\xb7\x97\x0f\x07\x39\xf9\x0a\xf6\xa7\x59\x22\x85\x63\x86\x45\xdf\xc2\x0d\xce\xdb\xb2\xf9\x1c\xc3\xac\x19\x25\x46\x84\xb5\xe5\x6f\x97\x60\x12\x46\xa9\xd1\xb9\x6b\x78\x71\x6a\xf9\xa2\x54\x55\x99\xbb\x75\x82\x51\x30\xf1\x7c\x23\x37\xd6\xcc\xc8\x67\x7f\x46\x95\x38\x9b\xed\x60\x2c\x50\xb8\xcd\x7c\x3f\x1f\x61\xa0\xa2\xa6\x19\xe3\xd2\xf8\x87\x6d\x75\x34\xca\xe0\xbb\x76\x30\xf4\xd3\x80\x99\x47\xb0\x4f\xbc\xad\x30\xe3\x32\xff\xc2\xd3\x34\x89\x6c\x86\x3a\x19\x9a\x3c\x2c\x23\x12\xa9\x01\xfe\xfb\x79\x33\xb4\x64\x18\x67\x46\x01\xa1\x46\xe3\xfd\x19\x5e\x71\x85\x19\xdf\xb9\xa0\x29\x86\xf8\xb8\x52\x7f\xc0\x79\xda\xc8\x22\x27\x79\xea\x82\xd6\x56\xfb\xc0\x77\xa0\xb1\xe7\x9b\x3a\xc9\xb7\x33\xb2\x60\x34\xfb\xfc\x68\xa2\x4e\xb3\xab\x0a\x13\x82\x69\xe2\xb1\xb6\x26\x9e\x3b\x22\xe8\xd4\x4c\x66\x31\x9e\xb8\x73\x1a\x6d\x59\xe1\xec\xee\x44\xe8\xf4\x0b\xb9\x13\x08\x19\x65\xbd\x59\x69\x45\xee\x5e\x1a\x50\x8b\xc6\xc4\x4a\x42\xf7\x10\x52\x83\x49\x6a\x5a\xe7\x71\xc3\x8b\xc9\x66\xc5\x54\x9a\x61\xf9\x33\x4e\xc5\x1f\x50\x2a\x6f\x4a\x31\xa5\x55\xe4\x45\x93\x9f\x78\xae\xb6\x95\xc1\x5e\x4f\xf2\xed\x0c\x28\xc1\x12\x7d\x23\xa4\x3d\x79\xd3\xc0\x48\x64\x63\x5c\xab\x76\x3f\x6d\x04\xe2\xc0\x89\xa7\xe3\xe3\x54\x82\xf0\x33\x2c\xcb\xf4\x1c\x0a\xed\x80\x3b\xe0\xff\xaa\x60\x34\x4c\x74\x66\x14\xd6\x1a\xb4\x7e\xfe\xeb\xe4\x81\xaa\x3a\x0d\x82\x08\x43\x6f\xd6\x9d\x6c\x6e\x0f\xdd\x9a\xd6\x27\xf2\x52\x42\x4d\x70\xba\x1f\xc0\x83\x54\x6e\x5f\x91\x35\xba\x17\x44\x90\xa2\x8a\x3e\x14\x05\x02\x1b\x9e\x0a\x2e\x6d\x2a\x6d\x3a\xb5\xd2\x58\x05\xda\x57\x6a\x3f\x07\xee\xc2\x31\x44\xa8\x18\xb2\xa8\x5b\x38\xe4\x8e\x9c\x54\xa7\xb1\x8e\x82\xd0\x19\x27\xa6\xcc\xe8\xd2\x19\x49\x93\xd0\x4a\xc5\x62\x8d\x75\x0b\x8d\xb7\xcb\xd2\x24\x8a\x39\x4c\xa9\xe1\x27\x47\x53\x85\x96\xa9\x29\x64\xe8\x31\x61\x7d\x0c\x35\x4d\xb8\xf0\x7a\xc8\x3c\x2f\x9b\x71\xad\xbc\xed\x44\x93\x0c\x49\x6c\x66\xbc\xe3\x0b\x4f\x63\xaa\x98\xa5\x53\xc6\x48\x90\xfa\x92\x0a\x13\x4d\x9a\x44\x21\xd3\x54\x68\x3d\xa0\xd8\xb7\x0c\xf5\x37\x95\x8f\x90\xa4\x29\xa4\x91\x0f\x5e\x2c\x8c\xdb\xfb\x77\xc5\xf8\xc3\x34\x43\x9a\x02\xc7\x9d\xa2\x32\xa5\xe6\xee\x57\x6d\x0c\x31\x93\xfe\x25\xfe\xb3\x65\x41\x86\x8a\x1b\x22\x57\xdd\x9d\x0c\x75\xb6\x74\xca\xa3\x00\x21\x2f\x1b\xcb\x5f\xb1\x8b\x7d\x0b\x03\xee\xd5\x0f\x30\xbc\x32\x8a\xe3\xa5\xc8\x7b\x83\x25\x11\xa7\x5a\x8e\x46\x77\xca\x39\x98\x34\xbd\x7d\xc3\x08\x11\x1e\xf7\xd0\x41\x12\x3b\x58\x14\x1a\xd6\x77\x50\xbe\xb6\x23\x69\x39\x9d\x8a\x2c\xc2\x8a\xea\x4d\x5e\x22\x93\x77\xde\x9e\xb7\xd0\xb4\xc4\x25\x99\x53\xc1\x95\x23\x20\x5b\x56\x87\x43\x67\xec\x9f\xaf\x78\x51\x54\xed\x4f\xc8\x87\xeb\x75\x2a\x89\x46\x0e\x44\xd4\x18\xaf\xb9\xf4\x85\x2d\x3a\x95\x71\x86\xeb\xde\x6d\xd9\xde\xae\xcc\x54\x1c\x4f\x07\x29\x22\x84\x22\x89\xee\xf1\xcf\xbb\x23\xcf\xfd\xeb\x93\x9a\xca\xee\x39\x36\xf7\xb7\x77\x8f\x3b\xc3\x00\xb4\xb8\x7f\x7c\x71\xfc\x08\x5d\x0f\x86\xe1\xf0\x1e\x9c\x86\xcc\xf2\x7e\xec\xab\x8c\x2a\x70\x21\x41\xae\x8a\xc1\xbc\x82\x28\xc5\x24\xa0\x2d\xb6\x5f\x3f\x2f\xc3\x00\x49\xc5\x0c\x61\xeb\x6f\x65\xf1\x52\x10\x86\x16\xee\x5f\xcd\xe7\x99\x8c\xbf\x39\x85\x0e\x62\xc4\x27\x88\xd3\xf9\x8a\x97\x6f\x50\x2f\x5e\x6b\xc0\xec\xcf\x75\x5d\x1d\xdc\xfa\xd4\x35\xd9\x3b\xcf\x82\x2c\x46\xd8\xed\x0d\xaa\xde\xa9\xbc\x6d\x46\xd1\xd5\x8c\xc4\xc6\x58\x31\xc8\x45\x44\x99\xbc\x4f\xea\x0c\x74\x46\x52\x81\xe2\x9c\x16\x5a\xe7\x42\x50\x2b\x13\x1d\x99\xe8\xcb\xb8\x63\xb8\xc6\x2d\x68\xe7\x32\x42\x06\xd5\xb1\xea\xfc\xc1\xf9\x2d\x3e\x0b\x83\x8c\x3b\x86\x2e\xcb\xec\xe1\x8a\x25\xed\x54\x19\xed\x29\x59\xa8\x00\x52\x17\x50\xbe\x81\xf6\x67\x55\x17\x6a\x53\xf2\x63\xb3\x9f\xda\xc7\x59\x14\x2a\xd6\x23\x32\x36\x86\xb3\x70\xea\xcd\x67\x71\xc2\xa2\x68\x10\xc8\x35\xfb\xbe\x9f\xd8\x59\x0c\x91\x02\x07\x33\x94\x15\x02\xf2\x1e\x8f\x36\xb2\x3c\x39\x15\xa4\xa1\x0d\xa4\x5c\xd5\xb9\x7a\x05\x4b\x30\x53\xd5\x9d\x4b\xf8\xeb\x7c\xa9\x33\xa9\xb3\x84\x86\xb1\xa9\x6f\xcc\x45\xf7\xbe\x5a\x5d\xd5\x07\x77\xed\x24\x0b\x10\x3a\xb4\xcb\x1b\x3c\xd5\x8a\xb7\x1c\x35\x20\x2f\x85\x27\x75\x96\x70\x85\x1b\xc4\x77\xde\x3c\x54\x18\x4e\xea\xa6\xab\x3b\x15\x0d\x0c\x9c\xf3\x08\xf5\x80\x76\x5f\x67\x54\x65\xda\x80\x10\x0e\x9b\x23\xa0\x24\xc2\xfb\x50\x9b\x5b\x67\x2c\x54\xe8\x12\xed\xfe\xb5\xea\xe9\x14\xbe\x1e\xb4\x59\xc6\x22\xc4\x96\x60\x0d\x40\xbf\xf2\x64\x99\x24\x68\x5f\xed\x0a\x5e\x2a\x23\x1c\x3a\x91\x2e\xb0\x1d\x79\x28\x11\x9d\xd0\xf9\xc3\x58\x59\xfe\x13\xc0\x0f\x70\xce\xcd\x9a\xb1\x39\xe6\x12\x5d\xd3\xcf\x46\x17\x57\x3a\x8d\x7b\x39\xa2\x0d\xa0\xa9\xad\x00\xab\x62\x6e\x3f\xc1\xd3\x65\x82\x11\x5c\xad\x04\x7c\x12\x00\xcf\x04\x37\x49\xef\x6e\x8b\x19\x7a\xea\x99\x4c\x63\x31\x44\xec\xe6\x9d\x6d\x7c\x41\x0f\xe6\x3a\x8b\x04\xb1\x6e\xc6\xdf\xba\xe7\xcd\xdb\xa7\x68\xb4\x4f\x5e\xb3\xd2\x86\x8a\xe2\x90\x97\x57\xb6\xfc\x71\xb4\x4d\x64\x40\x82\xd4\x66\x6b\xda\x62\xc4\x31\x3b\x7f\x4b\x3a\xd2\x18\x13\xb8\xe7\x6f\xb0\x41\x1d\x98\x6e\x91\x99\x29\x77\xd2\x99\x8e\x19\x46\x6b\x45\x5e\xb7\x7b\xe5\xe8\x41\x34\x27\x91\x40\xe3\xb2\xd9\x7f\x40\xcb\xdd\xaf\x21\xd1\x44\xfb\xd0\xf0\x95\x49\x6c\xfa\x46\xc6\x71\xd3\xbe\xb9\xdd\x2e\xdd\x6f\x51\x1a\x3a\xe8\xee\x53\xfe\x0b\x0a\xe4\x13\x9b\x44\x15\x78\xa4\x0c\xdb\xa8\xf1\x6e\xff\xf8\x6b\xf9\x99\x04\xbf\xe6\x31\x89\x30\x59\x6d\x58\x47\xbb\x47\xbb\x2d\x2d\xdd\xa8\xbb\x64\x1c\xd3\x20\xf4\x34\xf0\x35\xa0\x9b\xbc\xea\xb3\x23\x3c\x4e\x52\x61\xa3\xe2\x4d\x55\xa8\x7c\xaa\x17\xac\x79\x42\x42\x0c\xee\x83\x13\x10\x5d\xff\x1a\x10\x04\x74\xed\x91\x32\x15\x11\xa5\x7a\x6a\x2f\xe4\x6f\xe6\x3f\x33\x4f\xd2\x10\xe1\xd0\x36\x59\xfa\x6c\x42\xf6\x98\x3d\x70\x27\xa6\x81\xc6\x02\xf0\xd5\xd2\x68\xd9\x8d\xdf\x13\x65\x12\xa9\x01\xad\x2f\x33\x3b\xec\x39\x63\x0a\x63\x0d\xbc\x28\x30\x2a\xf9\x4f\xfa\x3f\xae\x45\x24\x38\x8d\x5c\xe9\xec\x94\x05\x42\x73\xa6\xa4\xe3\x61\x75\xa2\xbc\xa8\x90\xd7\xee\x87\xd3\x83\x33\xa5\xa9\x85\x6c\xaf\xa0\x80\x57\x23\xcd\x7c\x57\xc9\xb7\xb1\xa6\xcc\xe4\xce\x52\x46\x30\x69\xf9\x9e\xc3\x47\x61\x88\x6d\xe6\x1d\x2d\x9e\xca\x94\x66\x23\x35\x89\x27\x5e\xb7\x9b\x93\x68\xa7\x88\x97\xd4\xe5\xb6\xb9\x20\x04\x93\xbc\x18\x42\xbb\x5d\x3e\x7e\x8d\x38\xe0\x32\xce\xb0\xac\xa1\xfb\x84\x26\x38\xe9\xe1\xe0\x56\xae\x74\x7c\xf3\x8a\xa4\xa6\x48\x22\x6f\x4e\xbc\xa8\x2b\xf9\x36\xc0\xf0\x71\x15\x09\xc2\x07\x82\x6c\xcd\x85\xc6\xdb\xe4\xf2\x8a\x52\x8c\x1d\xc1\xaf\x23\x32\x09\xf8\xd4\xf5\xe4\xb2\x10\x24\x88\x3c\xc8\x1b\x5f\x06\xf3\x09\xae\x93\x83\xc8\xe2\x78\x40\x1b\x11\x86\x23\x43\x90\x83\x04\xd5\x0b\xba\x77\x0b\x42\xb7\x98\x3a\x8e\xb1\xf1\xed\xe9\x30\x4d\x07\x74\xc3\x25\xff\xe4\x43\x69\x4a\xd1\x1f\xd1\x55\x0d\x92\x37\x26\xae\x3a\xea\x22\x82\x50\xf7\xe5\x7d\x63\xa6\x0d\x2d\x02\xc6\xa9\xb5\x3d\x57\xf5\xe9\xb5\xf1\xbf\x73\x89\x41\x10\x5c\x95\x56\x98\x37\x99\x9c\x96\x44\x01\xd7\x16\xa7\x30\xb1\x35\x05\x89\x12\x9d\x8d\xd0\x13\x0b\xad\x7f\x6f\x92\x0a\x92\x24\xb8\xf9\xdf\xf0\x92\x7f\x21\x7a\xaf\x05\x01\x9d\x7a\xd7\x7a\xc4\xdc\xef\x3a\x68\xa2\x1c\xcb\xf2\x1b\xb4\x72\x0f\xcd\x63\x69\x0a\x39\x6d\x8f\xc8\x7e\xb1\x63\x4f\x0e\xb7\x99\x10\x5a\x68\x11\x01\x41\x4a\xaa\xc5\x69\x50\x65\xac\x45\x1c\x4a\x8c\xf2\xbd\x56\x85\xba\xcb\xbd\x99\xe5\x5a\x23\xa6\xad\x37\x69\xf2\x74\xd5\xc7\xe7\xb1\x5f\x11\x6b\x86\x95\xa4\x3a\x2f\xf3\x66\xbf\xac\x4a\x9d\xbf\x8e\xb8\xd8\xb5\x48\x02\x53\x31\xbf\xde\x6e\xff\xbe\x82\x4b\xd0\x58\x2b\x9f\x29\x36\x25\x1b\x97\xee\xb4\xa0\x42\x22\xed\x97\xce\x5f\xf7\xa8\x9d\x59\xbb\x75\x50\x30\x26\xb2\x81\x34\x88\xf5\x35\xd0\x4c\x4a\x47\x62\xed\x5a\x30\x4e\xe3\x68\x90\xad\x1c\xd9\xb9\x73\xf6\xad\x48\x03\x8d\x50\xd6\x0f\xc8\x9f\xa0\x5e\x94\x3d\xc5\x86\x16\xa9\x92\xa9\x61\x6e\x6d\x5a\xa8\xcb\x4a\xc1\xdf\x56\xc1\x88\x54\x1b\xb2\xab\xa7\xff\x74\x71\x77\x91\x45\x42\x0c\xf5\x4d\xbb\x09\xb9\x2e\xdb\xfa\xbc\x2c\xa0\x7e\x9b\xbc\x07\x1e\x52\xc7\x8c\x72\x55\xd5\x75\xf5\x01\xea\xaa\xaa\xde\x0c\xfd\xdf\x64\xd8\x73\x1e\x21\xf1\xd5\x9e\x17\xed\x20\x5e\x27\xb8\x90\x71\x36\x4d\x89\xb8\x3a\xc8\x61\xea\xfd\x93\x3f\xf6\x34\x4a\x49\x6d\xd8\x0b\xee\xf2\xf7\xbc\x7c\xbd\xaf\x4a\x5e\x7b\x1c\xa4\x80\x58\x11\x8f\x86\xed\xf9\x01\xb4\xd0\x84\x71\x0f\x8e\x7f\xb9\x02\x53\x4a\xe8\x00\x4a\xae\x13\xcb\xf0\x7b\x7b\x59\xee\x4d\x5b\x1d\x31\xbd\xdc\x6f\xf0\x42\xab\x4c\x53\x07\xa0\x43\x05\x73\x93\xbe\x2b\xfa\x69\xa3\xb5\xd1\x3f\x39\xd6\xa0\xa1\x36\xac\xff\x3d\xb3\x17\xb6\x1b\xb2\xa8\x13\x2f\x5f\xff\x33\x2f\xef\x72\xee\xc6\xb1\x0c\x42\x85\xd8\x3b\x93\x5a\xb6\x11\xba\xeb\xaa\x1e\x33\x9a\xf5\xf7\x23\x49\x64\xc4\x34\xbb\x95\xfd\xf7\xd8\xec\xb5\x24\x3c\x16\xa6\xce\x16\x78\x73\xaa\xcf\x23\x70\xa2\x24\x5c\xe3\xbb\xb2\x3a\x1a\x50\x37\x3b\x39\x30\xf6\x64\x28\x62\xb4\x06\x4f\xc8\xdb\x38\xeb\xa1\xa6\xae\xab\x14\xe8\xa9\x39\xd2\x0c\x64\xf6\x7f\xaa\xab\x23\x4c\xc8\xad\x87\x07\x45\xc4\x50\x92\xed\x6a\xfe\x71\xe3\xb5\x7d\x71\x1b\x1f\x3e\xd8\x68\x8c\xca\x88\xa5\x58\x93\xd9\xf0\x8f\xc1\xbe\x27\x23\xe0\x58\x1f\xe9\x70\x7b\xe8\x5e\x7f\x0d\x35\x95\x71\x08\x18\x85\xfa\x63\xfb\xdf\xee\x34\x71\x1a\xa1\x7f\xff\xe8\xe4\x6f\x7c\x03\xa7\x3a\x1a\x19\x24\x68\x88\x0c\x8b\xe5\xb5\x4c\x54\x9c\x0a\x4b\x12\xf3\x52\x36\x58\x06\x9d\x4f\xa8\x31\xb5\x4c\x80\x21\xc4\x30\xb7\x8e\xe1\xe6\x74\x78\x2c\x3d\x2f\x82\x96\x54\x28\xc4\x4a\x58\x8a\x8b\x27\x5e\x37\x20\xdd\xd8\x95\x8c\x84\xc8\x04\x73\xf3\xb8\x7d\x5a\xfc\xe5\x7f\x4d\x04\x2e\xb3\x9d\x45\xb3\xb4\x92\x0c\x2d\x7a\xbf\x9e\x08\x55\xcb\x54\x1a\x21\x26\x13\xcd\x5e\x58\xac\xda\xfa\xee\xf6\x4f\xbb\x8f\x2f\x79\x69\x52\x8d\x93\x18\xb7\xcc\xa2\x00\x57\xc1\xa1\x4a\xf2\xa7\xb1\xad\xe9\xa1\x80\x9b\xcf\x95\x35\xeb\xaf\xaa\xf3\xb2\xc8\xe5\xdb\x77\xf0\x8b\xac\xcc\x94\xe3\x36\x71\xf1\xa3\xa9\xd0\xb8\x96\x19\x30\xac\xca\xd9\x9b\xc2\xb2\xa5\xb9\x79\x77\x06\x9e\x70\x77\x86\x81\x80\xb6\xd3\xd4\x3e\xcd\x4d\x14\x7b\xa4\x48\x68\x2a\x7b\x3c\xe7\x10\x74\x77\xb1\x42\xcd\x29\xb3\xba\xd3\xf0\x0c\x83\x9e\xab\x97\xe7\xdb\xc5\xc3\x9f\xee\xbe\x84\x4a\x84\xa5\x1f\x2c\xdb\x55\xf5\xe1\xc7\xab\x0c\x8d\xa6\x75\x4f\x09\x92\xb7\x66\xea\x3c\x57\xd5\xc4\xdc\x96\x92\x1a\x2f\xc0\x18\x41\xf7\x95\x3a\x15\x70\x75\x52\x4e\x6b\x3d\x9d\x03\xe4\x48\xc9\x80\x13\x1b\x23\xdb\xc8\x3d\x74\x07\xa9\x61\x6c\x5a\xca\x4c\x05\xba\x57\xfc\x7c\xaa\x61\x30\x0a\x25\x84\x38\xf9\x79\x69\x4a\x26\xb1\x1c\xa8\x33\x7a\x5d\xbb\x8e\x91\xbb\xbd\x46\x9e\x04\x9c\x0c\x77\x3e\x7f\x25\xa5\x56\x98\x96\x39\x56\x4d\x67\x02\x0f\x36\x08\xa9\x98\xc6\xca\xb6\xc7\x9f\x0f\xeb\xe7\xdd\xf6\xf1\x8f\xf5\x83\x2b\x5f\x91\x40\x43\xcc\x12\xec\x79\xb3\xa8\xe1\x13\x3f\x57\x42\x67\x62\x1b\x9c\x70\x75\xc8\xcb\xd7\xe1\x6a\x38\xe9\x09\x0c\x53\xb6\xcb\xf5\xe3\xb8\x64\x43\xea\x20\x4e\x92\x01\x93\xd6\x9a\xd7\x25\x28\x97\x28\x71\x9d\xb2\x10\x8c\x69\x67\x42\x5a\xbb\x76\x68\x10\xa9\x20\x0a\xa4\x75\x86\xef\x72\x09\x65\x03\x0f\xd7\xdb\xf1\xa7\x53\x41\x62\x20\x10\x3e\xee\x6a\xb0\x40\xe5\xa9\x19\x3b\xc1\xff\x98\x1c\xa6\x53\x8c\x6b\x34\x87\x81\xad\xba\x31\x74\x5e\x3e\x94\xa4\x88\x10\x18\xaf\xb4\x62\x3e\x93\xb4\xb0\x0a\x23\x86\xac\x93\x77\xd5\xeb\xe6\x83\x1f\xbf\xa8\x11\x54\x51\x64\x64\x14\xcd\x6e\xb4\xad\xf9\x20\xb1\xaf\xa2\x84\xe1\x36\xf6\x54\xd5\xad\xae\x8a\x1c\x0b\x03\xbe\xe0\x80\xb2\x87\xc5\x22\x48\xad\xc7\xfd\x30\xe5\x9c\xd0\x2a\xa1\x0a\x4f\xba\x28\x8a\xdb\xd2\x6b\xa3\x75\xbf\x43\x66\x38\xf1\xaa\xef\x5c\x6d\xf7\x70\x95\xbf\xbe\x62\x4d\xce\x34\x85\xab\x50\x1a\xdf\xd0\x04\x99\x4d\x66\xf2\x2e\x2f\xcb\x94\xed\x81\x34\xd1\x38\xf0\x9b\x0f\x7e\xdc\xb4\x55\xcd\x3d\x85\x80\x62\xa1\xc2\x35\xd2\x14\xc7\xdb\x02\xf3\x4f\x56\x3a\x77\x08\xcb\x22\x0b\xc8\xd9\x74\x1b\xed\x61\xa0\xbe\x3e\x7f\x44\x2a\x0d\x7a\xc9\x6d\x56\xe3\xb4\xb3\x4a\x95\x21\x98\x39\xf0\x5f\x3e\x69\xc8\x5d\x09\x9e\xca\x14\x25\x06\x86\x50\xe7\xfa\x7c\xc3\x0f\x4e\x81\x60\x14\xd8\x54\x99\xd2\xda\x6b\xac\xce\x3e\xc5\xc0\x50\x50\x19\x10\x14\x69\xe8\x5e\xc7\x71\x40\x49\xd1\xb5\x50\x44\xfe\x76\xbb\x4a\xbd\xab\x73\xcd\x3f\x19\xb2\x3c\x50\xd2\xc0\x55\x1e\x7b\x09\xc3\xf1\x73\xf3\xd4\x84\xde\x47\xa0\xf9\x55\xde\xf0\x31\x33\xcd\xe4\xc4\x82\x13\x17\x30\xbd\xb5\x6f\x2a\xf9\x9b\xa1\x27\x04\x0f\x0c\xf9\xbe\xc0\xad\xb0\xf3\x48\xfa\x7a\x4a\xdb\x49\x12\x9e\x19\xbe\x95\x62\x73\xac\xea\x76\xc0\xec\xac\x95\xcc\xc0\x48\x53\xd4\xd5\x71\x64\x35\x29\xa9\xa2\xc0\xbb\x14\xbb\x66\x08\x78\x52\x10\x80\x4a\x06\x79\xf8\xab\xb3\x15\xfb\x1d\x3f\x11\x30\x23\xa8\xfc\xa1\x2e\x03\xa0\xb6\x8b\x0e\x12\xdc\x36\xdb\x0f\xb7\x22\x2b\x9d\x44\xc8\x85\xd3\x54\x75\xbb\x82\x46\xf6\x9a\x62\x97\x00\x7b\xa5\x69\x80\xc2\x0f\x32\xaf\xb1\xb6\xb2\xf7\xa0\x20\x60\x01\xaa\x5d\x18\xc8\x4b\x9f\xc9\x18\xbb\x28\x6e\x20\x41\x00\x41\x4a\x7a\x71\xdc\x59\x59\x30\xdb\x95\xd0\x18\xf3\x40\xd7\x35\x7f\x1d\xd4\xc8\x40\x18\x1a\x5f\xe6\x82\x26\x3b\x6f\xf7\xd5\xa9\x35\xcc\x34\xde\xf5\x81\x90\xf1\x81\x5a\xf3\xf7\x3f\x6e\xc6\xaf\x0f\x42\x45\xd3\xcc\x25\xd5\xcd\xf2\x3d\xfe\xb4\x10\xd1\x0c\x55\xd5\xb6\xeb\xc5\xfd\x66\xb7\x7d\xdc\x2e\x5c\x61\x35\x44\x69\x82\xd8\x27\x5f\x74\x3a\x92\xbe\x18\x18\xdc\x10\x89\xc4\x54\xd0\x54\x87\xe3\xd8\xf0\x87\x38\x36\xd2\xd6\xb8\xaa\xbf\x76\xce\xfd\xb9\x73\xac\x06\x95\xd5\xae\xa3\x34\x2c\xa0\xef\x9e\x19\x7e\xb0\x40\x43\x92\x89\xcc\xa2\xa3\xef\xab\x76\x24\xec\xa9\x21\x11\x29\xaa\xb1\x2d\x4e\xed\xde\x61\xf5\xe6\x6d\x62\xa0\x5a\xa0\x67\xbe\xac\xca\x6e\x25\xe0\x9d\xd3\xc9\xc7\x67\x63\x11\x85\x9e\xa3\xc2\xad\x4f\x26\x9f\x32\xcb\x03\x00\x2c\x36\xca\xa4\xc6\xfa\x7f\xfc\x28\x87\x7c\x2a\xc0\x12\x66\x74\xeb\x8c\x1c\x95\xdd\x38\x27\xa6\x2e\x30\x16\x4a\x6a\x55\xfd\x5a\xfe\xf6\x89\x94\xa2\x06\x96\x0a\xa4\x74\xdd\x4d\xcc\x6b\x77\xb5\x34\x4c\xb4\xa5\x65\xfb\x5e\xa9\x62\x44\xa7\xe8\xba\x00\x93\xd2\x75\x29\x10\x3d\x60\x5b\xb2\x90\x20\x54\xa5\xcf\xb0\xdf\xf3\xbc\xfc\x91\xf3\x67\x28\xfe\x8e\xb1\x05\xb2\xd4\x20\x13\x91\x06\x9a\x9f\x1f\x4f\x7e\x50\x73\x62\xa8\x0c\x27\x95\x31\x7f\x73\x3e\x1e\x29\xc8\x9c\x0a\x86\x8d\x6c\xcc\xf7\x94\xb1\x00\x5f\x29\xfe\x69\x95\x15\xf1\x53\x1e\x64\xa2\xd0\x05\xca\x1b\x17\x0b\xfd\xe4\x6d\xab\x30\xc0\x7a\x0c\xae\xd4\x5d\xf5\x3e\xc0\x59\xcc\x59\xb6\xa0\xc2\xd0\x98\x72\xfc\xfc\xa8\xf5\xb2\xc8\xa1\x6c\x57\x20\xe6\xd9\xd1\xba\xee\x80\x88\xff\xe3\xa9\xd9\x0f\xd4\x8f\xa6\x70\x2f\x80\x80\x1b\x24\x5a\xfe\x6e\xe9\x6c\xcc\x17\x9f\xdd\x31\x01\x68\x64\x45\x30\xec\xac\x55\x5b\xb7\x2e\x02\xa4\x3c\x16\x7d\xda\x38\x6f\xb7\xfb\x1a\x9a\xbd\xd7\x80\xd5\xa0\xc3\x00\x91\xed\xff\x5b\x9f\x8d\xf1\x6c\x98\x71\xc6\x33\x44\xc7\x2a\xb2\x51\xcb\xb1\x0f\x7e\xe9\x8b\x6b\x12\x67\x58\x69\x6b\x2a\x49\x06\x44\x45\xbf\x15\xda\xd3\x24\xa1\x19\xf4\x4c\x35\x07\xc3\x76\x32\x48\x1d\x68\x92\x59\x8f\xa8\xad\xb7\xd5\x4b\xa9\xa0\x2e\x72\xa8\xd1\xfe\x1e\xbd\x46\x4d\x78\xe6\x6c\xd0\xa7\x62\xb1\x98\x09\xc7\xea\x48\x64\xa9\x13\xfc\xab\xaa\xa2\xd2\x7a\x14\xa2\xc3\xa2\x28\x61\x58\x93\x4e\xa5\xda\x56\x63\xb2\xd2\xf1\x9d\xc7\x34\x4d\x6c\x28\x11\x75\x3e\x71\xc8\xdf\xf3\x37\xa8\x31\xf0\x78\x3b\x0d\x1b\xeb\x38\x0b\x32\x1b\xa1\x5f\x08\x28\xa6\xad\x1c\x22\xeb\xb6\xdd\xf0\xe6\xba\xaa\x57\xcb\x87\x6f\x93\x2b\x6a\x43\xb2\xf1\x70\xbd\xb5\x2f\x79\x5a\x39\xa5\x69\xc4\x91\x69\x77\x8d\x74\x05\xcb\xbd\xd7\x4b\xd3\x9a\x26\x80\x75\x02\xf7\xfc\xd7\x53\xb5\xf9\x53\x0c\x2c\x1b\x4d\x45\xe4\xe0\x06\x26\x19\x6a\xe7\xe3\x43\xd5\xdb\x62\x9a\x4a\xe1\xfc\x7e\xeb\x9a\x36\xbe\x09\x32\x15\x78\x3f\x7e\xe4\x1a\x68\xc6\x04\x96\xd2\x1a\x36\x0c\xe0\x07\x2c\x98\xb3\x4c\x4c\xff\x18\xfd\x71\x47\x64\x32\x30\x4c\x77\xe5\x81\xd7\x6f\xef\xcd\x75\x3d\xb0\x09\x35\x03\x89\x5c\x0e\x7d\x58\xb6\xf3\xc1\x97\x75\x75\x3a\xe6\x7f\x07\x42\x45\x80\x92\x05\x76\x6e\xf2\xb2\x5b\xaf\x60\x07\x5a\x83\x6c\xf3\x89\x51\xa4\xd3\x44\xe2\x78\xd2\x80\xac\xbe\xee\xf2\xa9\x60\x48\xfd\x68\x18\x3e\xcb\xb2\x5f\x5e\x75\xc6\x52\x92\x3a\xe7\xbd\xe5\x8a\xb7\x3c\x18\xcd\x2c\xcd\x85\xc0\xfc\x67\x0b\xfc\x60\xeb\x71\xba\x2f\x75\x37\xf8\x16\x82\x24\x78\x7e\xbf\x6a\x5c\xaa\xa2\x6b\x2d\x04\x8f\x6c\xe9\x25\x6f\xf3\x77\x58\x61\xa8\xfa\xdd\xbf\x23\xc9\xa4\x64\x63\x7a\x23\x9d\x7f\xb2\x4e\x69\x29\x98\x9b\xee\xe6\x7d\xda\xf0\x1e\x26\x0e\x7c\x1f\x40\x07\xea\xbd\x42\x46\x6d\x5f\xdd\xf4\x23\xe7\x98\x7f\x9f\x37\x58\xb5\x04\x12\xfa\x52\xae\xa3\x11\x8e\x3b\x0f\x68\xef\xb5\x56\x89\x01\xf1\xdc\x40\xeb\x06\x75\x37\xe9\xae\xab\xda\x23\x87\xc6\x77\xab\x80\x21\xc8\x10\x39\x46\xcc\xaa\xe3\x85\xb9\x6d\x17\xcd\x0d\xc6\xbd\x81\xb6\x81\x42\x77\x86\xeb\xfb\xcc\x4b\xd4\x82\xc9\x3e\x96\x30\x4b\x29\x79\xf9\x50\x34\x08\x82\x20\x41\xe2\xe8\xcb\x00\x9d\xeb\x10\x19\x71\xb5\x45\x51\xfc\xac\xea\xb7\x41\x49\x48\xd7\x08\x22\xb3\x25\x70\xdd\x6c\x30\x6e\xcd\xdc\x97\xa1\x41\x40\x42\x86\x7d\x1d\x0d\xbf\x33\x0f\xaf\xce\x77\xf0\xca\xe5\x85\x40\xee\xf4\x70\x1a\xa0\xc0\x9e\x80\x76\x57\xb8\x8c\x66\xf7\xbb\x08\x23\xcf\x30\xd3\xb4\xd5\x01\xea\xed\xaf\x45\x3b\x4a\xb1\x4d\x4e\x15\x32\x89\x26\x98\xe0\xe5\x5b\x67\x00\x1a\xae\x3d\x24\xd3\x74\x67\x8d\x12\x19\x19\x57\x32\x3f\xc2\x77\x5f\x28\x4c\x83\x20\x8e\x03\x5c\x56\x2d\x47\xb6\x89\xe3\xfb\xc6\x34\xc4\xe8\xf9\x1f\xbc\xfc\x77\xf7\x21\xdc\xef\x34\x4a\xd3\x51\xb8\xbe\xdb\x68\xa7\xcf\x3b\x7f\xb3\x14\x8c\x0d\xb5\x82\x43\xcf\xf8\x71\xb9\xa3\x77\x3d\xb5\x51\x0c\xfa\x99\xb7\x9d\xf7\x79\x87\x24\x00\x76\xb2\xd8\x2e\x2c\x0c\x90\x17\x7a\x4a\x3c\x3f\x40\x03\x74\xbd\x64\xac\x8d\x1c\xb2\x21\x2e\xe7\x05\x3c\x96\xaf\x55\xde\x3f\x0f\x93\x69\xe4\x6b\x34\x5c\xa4\xeb\x9e\xff\x1a\xf0\x1c\xdb\x9e\x69\x1c\x04\xb1\x33\xa9\x65\xcb\xcb\xd7\x02\x30\x06\x34\x3f\x48\x52\x2d\x70\xb9\x44\x5c\xca\x4d\xde\x4e\x06\x63\x96\x18\xfe\xdc\xa6\xad\x8e\x08\xec\x1b\xdc\x53\x96\x06\xa9\xe1\xc4\xee\x4c\xea\x89\x06\x6e\xd7\x0e\xa0\xa2\x61\xe5\x3c\xc2\xe0\x6d\x23\xa7\x29\x05\x87\x91\xc7\xb7\x33\x27\xd6\x47\x83\x40\x10\xed\x12\x5f\x57\x05\x97\x6f\x13\x1e\x03\x1a\x04\x32\x0c\x50\x4a\x73\xf1\x70\xfb\x37\x72\x02\x5d\xe7\xc4\x48\xe0\xdf\x55\xaf\xb7\x43\x83\x70\xf2\x5a\xa4\x0e\x94\x35\x2f\x71\x43\x6e\x3e\x93\x48\x99\xfa\x3b\x34\x08\x54\x90\xa0\x45\xf6\xe7\x7f\x2f\x9e\x47\x93\x57\x05\x02\x8c\x61\x79\x5b\x9a\x2a\x98\x39\xc3\xb2\xeb\xc8\x82\x20\x1a\x94\x6c\x0f\xf2\x87\x5d\x2b\x0f\x23\x4f\x71\x68\xe8\xc8\xca\x93\x93\x68\x75\x21\x98\xae\x1f\x84\xd4\xc6\x8d\x56\xf9\xab\x21\xaa\x78\xc9\x7b\xb5\xa4\x39\xdb\x2a\xb5\xc7\x42\x00\xc0\x1c\x89\xef\x06\x40\xf9\xab\x43\x9a\x08\xaf\xc9\x7f\x33\xc7\x7a\x6d\x3b\xea\xd4\x28\x7c\x38\x71\xfe\xab\xf3\xdd\x80\xf2\xd1\x58\xdb\x34\x20\x41\x6c\x8a\xf6\xa5\x97\x75\x98\x1f\xa9\x84\xd0\x08\xc3\x0c\xd6\x51\xe4\xf5\xd4\xcf\x9e\xf4\x0f\x83\xd8\xb0\x25\x62\x7c\xc7\x12\x31\x7d\xa6\xee\x6f\x23\xbf\x33\x26\x36\x0d\x48\x44\x0d\x23\xcb\xc3\x76\xf8\x39\x49\xc4\x39\x26\x7b\x91\x68\xd3\x6c\x7a\x26\x65\xb0\xe1\x07\xe8\x8d\x1f\x8a\x94\xcd\x99\x07\xb0\x74\x33\x01\xc5\xfc\x5d\x6b\x0c\x11\xb3\x1e\xd7\xdd\xdd\x0f\x4b\x84\x9b\xb8\xd6\x24\x06\xac\x0b\x3b\xf2\x33\x56\x74\xbb\x00\x44\xd7\x94\x50\xac\x9b\xde\xae\x97\xbb\xce\x43\x1f\x8a\x76\x74\xcd\x2c\x70\x48\x1d\x37\xc5\x36\x38\x15\xe6\x8a\xbb\x68\x40\xa8\x12\xcc\xda\xb7\x88\x55\x99\x55\x41\xc3\x7e\xca\x50\x6c\x0e\x14\xba\xc7\x3d\x58\x04\x18\x69\xba\xae\x4a\x55\x3d\x00\x96\x8b\xba\xbb\x62\x89\xc0\x15\x65\x21\xdb\xfc\x3d\x6f\xcf\x98\x24\x9e\x9d\x06\x84\x09\x81\x05\x94\x2b\xe0\x16\x24\xd9\xfd\xa8\x12\x93\xb1\x84\xa6\xbd\xf5\x83\xd9\x36\x66\x01\xc5\xf0\xab\x15\x85\xe5\xc5\x67\x83\x29\x0b\x19\xba\xa3\x4d\x0b\x47\x37\xb4\x49\xd6\xad\x87\x56\x41\x8b\x4b\xb8\xeb\xbc\x8a\xaf\x02\x64\x34\x20\x3c\x00\xcc\x28\x1c\x1b\x38\xa9\xca\x20\x5b\xba\x39\x96\x7e\x1b\xcc\x26\xc2\x85\xd9\xd2\x97\xbc\xd9\x5f\x75\xde\x43\x5e\x8e\xd7\x4a\x22\xa2\xd8\xa6\xc7\x0f\xd5\x3b\xa0\x22\x8c\xa8\xea\x21\xe7\xd4\xe4\xdd\x08\xce\x5c\xb0\xd4\xb3\xb2\x8f\x4f\x29\x95\xd1\x8b\x75\x5b\x60\xb3\xa8\xc1\x6c\xbc\xee\x79\x55\x94\x11\x53\xb3\x25\xab\x52\xe6\xc5\xd0\x3b\x1e\x39\xc7\xa9\xa3\x9a\x43\x36\x53\xff\x2f\x77\x9a\x24\xc6\x65\xed\xbf\xb7\x17\x6c\x11\x5f\x6f\xb5\x04\x6c\x2e\x6a\xf3\x74\xfb\x30\x5b\x5f\xf3\xc9\x5b\xd7\x82\x23\x20\x8c\x77\x63\x88\xb7\x70\x75\x3a\x0b\xde\x87\xb5\xa7\xbd\x65\x1a\x59\xff\xe4\x51\xa0\xd5\x5c\x3b\x73\x65\xd4\x31\x0c\x44\x86\xb1\x4a\xaf\x08\xf0\xfb\xf0\xf3\xee\x68\x65\x18\x3e\x76\x25\x7c\x6c\xb8\x52\x97\x63\x6f\xb4\x59\x8c\xbf\x67\x48\x22\x91\xa6\xa3\xaa\xad\x89\x84\x47\xd7\x27\x96\x48\x04\x8c\x52\x01\x07\x68\xf7\x95\xf2\x4d\x2c\xc4\x18\x1b\x4a\xf8\xa9\x99\x52\xfe\xae\x4f\x26\x99\x70\x29\x7d\xeb\xfb\x54\x7d\x8d\x10\x0d\xc2\x10\xac\xd6\xb1\xc9\x7c\x5a\xa6\x9d\x8b\x3d\x6f\xaa\x8f\x4b\x83\x30\x4e\x0c\xa1\x67\xb3\xaf\x3e\x16\xa7\x76\x5f\xd5\xf9\xbf\xa1\x7e\x2c\x61\x64\xe8\x84\x31\x95\xee\x29\x9f\xaa\x81\x8f\x40\x83\x30\x09\x8c\xfc\xda\xe6\x66\xb5\x7b\x3c\x94\xb9\xea\xe6\x40\xed\x5b\x49\xe8\x24\xfc\x57\xb9\xd6\xb9\x3c\x15\xed\x79\xf2\xf9\x12\x65\x0a\xfc\x74\x5e\x22\x3d\x8f\x23\x73\xa1\x41\x48\x89\xc4\x5c\x99\xb2\x58\x72\x93\xa2\x73\xd9\x92\xae\x83\x10\xa9\x61\x2b\x68\xdb\x02\x3d\xb6\x5b\xf5\xec\x29\x91\xbb\x0e\x92\xa0\xfa\x54\xa5\x35\xd4\x37\xdc\xd0\x84\xba\xd7\x37\x3b\xee\x42\x16\x47\x19\xf5\x6f\x73\x75\x6a\xe5\xde\x42\x7e\x0c\xfd\xf6\x6f\xc4\x38\x68\x10\xa6\x16\x29\xfa\xfd\xea\xc7\x70\xf7\x09\x33\x96\x24\x56\x92\xa9\x84\xda\x44\xe7\x9b\xaa\xe4\xc5\xc3\x09\xe5\x9d\x2f\x63\x91\xdd\x41\x59\x1a\x47\x9e\x05\xfc\x75\xdf\xae\x00\x0b\x62\x5d\xb3\x20\x91\xa1\x5c\x45\x39\x9c\xaf\x87\xfd\x1c\x37\x37\x9e\x43\x1b\xaf\xc3\x87\xf3\x86\x3a\xa9\xae\x93\xa2\x54\x3b\xeb\xcf\x10\xec\xcf\xb1\x32\x74\x3d\x75\x12\xe9\x81\x21\xb6\xe5\x6f\xb6\xb6\x67\x3c\xb2\x78\xa4\xc1\xc9\x42\x9a\x42\x46\x6b\x88\x5f\x04\xfc\xdc\x01\x52\xe2\x78\xbb\x2d\xe5\x9e\xe7\xe5\xed\xf2\xf1\xd3\xae\x82\x05\x58\xac\x6b\x4b\x6e\x31\xbc\xb3\x38\x1e\x8b\x5c\x5a\xe1\xf8\x8b\xf7\xe3\x8d\xc1\x50\x48\x1a\xda\xa0\x9a\x91\xed\xf4\x71\x6b\x1a\x84\x52\x19\xfe\x8d\x15\x14\xfc\x0c\xca\xd9\x28\x5f\x00\x01\xba\x83\x74\x84\x38\xb1\xdb\xc7\x3f\x47\x03\x42\x31\x45\x5d\xf1\x14\x5c\xf3\xbc\x98\xbc\x73\x08\x13\xc4\xd3\xef\x34\xc0\xb4\x29\xce\xb0\x80\xb2\x7b\x30\x59\x9f\x50\x85\xfc\x6e\x72\xaf\x40\x69\x68\x87\x0e\x74\x73\xd7\xff\xce\x0d\xb0\x70\x51\x1c\xf7\x95\xd7\xb1\xf7\x29\x20\x1a\x84\x5a\x28\x93\x01\xd7\x2d\xd4\x4b\xe7\x0c\xd8\xd6\x28\xa0\x14\xc3\xa2\x28\x70\x8a\xef\x73\x28\x20\x4f\x83\x88\x84\x12\x03\xa1\x77\xfc\xdf\xe7\xe1\x03\x47\x84\xa6\x01\x19\xe8\x3d\xb9\xa8\xc9\xf8\xe1\x22\xc2\xcc\xd6\x6a\x8b\x7a\x79\xd3\x1c\xab\xfa\xf2\x25\xfb\x31\xed\xbf\x5d\x44\x32\x8d\x75\x0a\xeb\xc7\xf5\xe8\xc2\xa1\x8e\x11\xde\xa5\x4f\x85\xce\xfd\x22\x13\x45\x24\x75\x25\x13\x43\xf6\xcd\x0b\xf0\xec\xf8\x7b\x46\x91\x5d\x96\x91\xcb\xfc\xa5\x41\x0f\xf2\x50\x8d\x83\xb8\x93\x23\xb8\xc0\xec\xd8\x92\x6b\xe4\xc3\x52\xfe\x0e\xa4\xc2\x34\xc1\x7b\xd5\xc2\xb6\x7a\xb1\xf0\xf5\x3a\x6f\x79\x31\x20\x14\xa0\x41\x14\xc7\x59\xd4\xe3\xb3\x97\x55\xf9\x3a\x8d\x77\xd2\x20\x4a\x88\x71\xbc\x5f\x36\xab\xbf\x46\xcf\x9f\x10\x16\x9b\x55\xbc\x84\x3a\x97\x0b\x39\x64\xdf\x1c\x73\x3a\x75\xbd\x63\x8a\x25\x07\x2f\xe5\x67\xe2\x9b\x5d\xa7\x24\x52\xa6\xf4\x05\x14\xd4\x70\xb8\x04\x3b\x7d\xba\x42\x46\x68\x82\xfc\xc7\xff\xf9\x8f\x6e\xd8\xc8\xbc\xe5\xbb\x63\xd5\x42\x0d\xbb\xe3\x49\x88\x22\x97\x6e\x87\x89\x68\xca\xa3\xc8\xed\x7f\x57\x88\x0b\x3e\xf7\x6d\x1a\x23\x54\x7f\xde\x81\x7a\xf5\xe1\x85\x88\x05\x99\x23\x42\x25\x41\xe7\xff\x72\xd9\x3a\x70\x39\x71\xd7\xcf\x22\x9e\x24\xbe\x84\xf7\x93\xac\x5e\xd7\x4f\xd2\xc0\x80\x32\x4d\xdc\x6e\x36\x46\xdf\xf5\xd3\x02\x21\x2d\x5c\xa9\xcf\x95\x85\x69\xd0\x5d\x15\x1d\x1c\x28\x5f\x73\xaf\x46\x4a\x83\x48\x92\x08\xed\xf8\xaa\x7c\x80\x8f\xbb\x8a\x97\x5f\xd5\x16\x74\xfd\x13\x48\x42\xa3\xb0\x35\x2e\x4b\x9a\x74\x93\x1a\x37\x9c\xc5\xfd\xd5\x62\xb3\x59\xac\x1e\x9f\x77\x9b\xf5\x8f\xf5\x83\xbb\xac\x22\x02\x01\x07\xaf\x27\x5e\xab\x9c\x97\xa4\x6f\x50\x44\xba\x42\x9d\xc2\x14\xc3\x0f\x66\x99\x22\xa0\xfa\x8c\x9a\x7a\x9c\x98\xc6\x91\xe2\xda\xe9\xc9\x20\xfb\xae\x3b\x2d\x44\x1c\x19\x07\xc4\xa9\x78\x73\xdb\xa9\x37\x54\x9d\xe5\xea\xe9\xf7\x7b\x7b\x35\xd2\xb1\xc2\xe7\x6d\x8c\xe2\x55\xeb\x56\x9a\x38\x4c\x64\xec\x29\x13\xbb\x5b\xbd\xf0\xa9\xe3\x90\x66\xca\x24\xe7\xef\xb9\x5f\xe1\xe2\x90\x33\xe4\x06\xcf\x25\x3f\x7a\x9b\x71\xca\x4e\x39\xeb\xa5\xc6\xa1\x16\x60\x31\x0a\x28\x93\xb9\x73\xe7\x8c\x62\x25\xed\xc6\x77\x93\xb7\xdf\x4f\xc2\x35\xc4\x09\xc1\x70\xbb\xad\x7f\x5b\x96\x6d\xed\x9b\x32\x86\x78\xcc\xdd\x6f\xe1\xcb\x2c\x51\xa3\xff\x12\x71\x2c\x81\x9a\x94\x6e\x29\xa1\x58\xbc\x56\x9d\x81\x63\x93\x31\x26\xbe\x4e\x83\x38\xa1\x81\xaf\x79\x00\x99\xe3\x8a\xbd\x69\xe1\xe8\xee\x21\x61\x81\x8b\x07\xff\x40\x99\x00\x69\xbb\x18\x20\xda\xc5\x2a\x1b\x27\x96\xf0\x5a\x41\x71\xcf\x4b\xde\xcf\xbe\x98\xc6\x34\x64\x6e\xc2\xf6\xe6\x70\xe3\xdb\x65\xc4\xf4\xc0\x0d\xf0\x30\xd4\xa7\xba\x6a\x11\x84\x7f\x5f\x29\xff\xe9\xa8\x62\xe8\x84\x15\xd5\xeb\xeb\x80\x76\x62\xba\xfe\xcf\x2e\xb9\x31\xd5\x8c\x28\x4f\x93\x61\xc8\xfe\xdb\xbd\xa5\xba\x9b\xa9\xc4\xa7\x41\xcc\xb8\x09\x4b\x21\xe9\x99\x99\xc8\x83\x7d\x33\x66\x9a\xe9\x64\x50\xde\x76\x75\x90\x2b\x7e\x6e\x2e\x4b\x7a\x68\x10\xa7\x91\x09\xd8\x1b\x06\x76\x0c\xd5\x79\xe3\x7c\x6c\x94\xbb\x03\x20\xcd\x6c\x74\x0d\xd3\x4b\x57\x80\xb5\x65\x7e\xa7\x88\xb3\x08\x70\xd7\xcd\x65\x15\x3f\xf3\xdc\x47\x77\x63\x1e\x0b\xd9\xbb\x00\xdb\x9a\xcb\xb7\x6e\x10\x5d\x75\xee\xd5\xfc\x08\xe6\xb1\xce\x0c\xbf\x20\x56\xa3\x1a\x11\x8c\xbe\xca\xb4\xeb\x41\x35\xaa\xb3\x3f\xf7\x3a\xd2\xdd\xaf\x3c\xc4\xed\xa5\xf3\xdc\x9e\xa1\xc9\x8b\xfc\x74\xe8\xa1\xa2\x34\x88\x45\x18\x99\x94\xf1\x9e\x37\xd7\x05\x9f\x2d\x2d\xe9\xba\xe9\xd0\xa4\xf8\xb8\x86\xcd\x49\xb4\xf5\xc3\xf2\xe9\x93\xae\x32\x10\x38\x4f\xdd\xf4\x30\xeb\xc9\xec\xaa\x18\x4b\x06\x28\x74\x75\xb5\xbc\x6a\x4f\x03\x73\x26\x96\x3c\xa6\x36\xeb\xbb\x41\x6e\x40\x83\x5e\x77\x12\x11\xb3\x7c\x68\xdd\x61\x72\x50\xcd\x72\x93\xbf\x03\xff\xb0\x32\xa9\x17\x6f\x54\x42\x82\xe6\xd8\xfd\xe2\xcf\xdd\x62\xb9\xbd\xfd\xb1\xde\x2d\x17\x0f\x3f\x2c\x3b\x35\x0d\x62\x15\x65\x68\xc6\x1f\xab\xaa\x70\xd2\xbc\x34\x88\x21\x4a\xd0\xbb\xda\x1c\x78\xdd\xae\x86\xfe\x53\x0c\x31\x8b\x8c\x2a\xcf\xf9\x3a\x2f\x0d\x7d\xe9\x1d\x6f\xfc\x60\xf6\xfd\x12\xa3\x81\x61\xc4\x6e\x4e\x06\xc9\x38\xbe\x3b\x60\xdc\x48\x10\x74\xa3\x76\x55\x57\xc7\x91\x0a\x89\xed\xa4\x53\xa6\xd2\x09\xd0\x75\xc9\x8b\xe2\x86\xf7\x5d\xb2\x80\x5b\x5f\xf0\xa6\xe0\x2a\xe7\x6d\x55\x2f\xf7\xd0\xb4\x63\x11\xf4\xae\xa7\x8c\x63\xc7\xe1\xaf\xd4\x63\xf9\xd0\x19\x09\x6a\xb4\x09\x27\x41\xe7\x83\x0e\xa2\x8d\x03\x16\x95\xc1\x62\x93\x04\x94\x6b\xdd\x97\xf5\xb8\xaa\xfa\xd1\xcc\x4d\x02\x00\xc4\xc3\xed\xcc\x24\xb0\x72\x47\x63\xb1\x93\xbf\x13\x0f\xb6\xa7\x22\x92\x49\x43\x2c\xfb\xbf\xa7\x5e\x57\x75\x6a\xcf\x7c\x69\xf0\x27\x21\x21\x86\x9f\x69\x5f\x7d\x78\xaf\x79\x7c\x99\x30\x05\x66\x58\x93\xab\x5f\x67\xb7\x52\x4e\x9e\x2a\xe4\x69\x9c\xf9\x94\x73\xe7\x44\x0d\x9d\xd0\xc1\x3b\x8a\xac\x12\x6e\xcb\xdf\x60\x2c\x65\x4b\x83\x24\x0e\x13\x4c\x5c\xe3\x18\xf3\xf0\xb4\xf1\xab\x39\x4d\x51\xb4\xdd\x71\xd4\xd4\xf0\xe5\xcd\x42\x34\x83\x40\xac\x6b\x56\x06\x76\xde\x18\x3e\xe6\x65\x75\x38\x54\xe5\x76\x6b\x08\xda\x6e\x55\x3a\xda\x83\x12\x6a\x8b\x94\xee\xa0\x1a\xcc\xcc\x84\x66\x14\x33\x37\x0e\x6a\x3b\xb9\x06\x8b\x28\x31\x75\x4b\x55\x3d\xf1\x80\x12\xc6\x02\x9c\x51\x6d\x8e\x82\xdf\xee\x8c\x4c\x87\xd2\xb2\xb3\xac\x80\x17\xbd\x5b\x3d\xbb\x66\x24\x69\x14\xbb\xf0\xc6\x2e\xef\x63\x1b\x49\x9a\x44\x49\xda\x6b\x86\xfb\x9f\x33\x82\x12\x10\x56\x13\x7e\x89\xdb\x6e\x31\x4f\x68\x4c\x83\x24\x4b\x62\xb4\x5f\x3b\x17\xc6\x9d\x22\x4b\x23\x83\x08\xcb\xa1\xde\x7e\x54\x4f\xa7\x5a\x7a\xd6\x43\x1a\x24\x9c\xa4\x32\x1c\x24\x67\x07\xea\x85\xdd\xcc\xff\x3a\x03\x98\xf0\x38\x44\x43\xb4\x39\x1d\xa1\xbe\xac\xd9\xea\x7a\xa4\x80\x39\x42\x3f\x65\x11\x38\xd2\x0c\x82\xd4\x09\x07\x82\xd9\xfd\xab\xdb\xd5\xa5\x0a\x36\x0d\x12\x11\xc6\x46\x7c\xf8\x33\xee\x34\x1a\x24\x32\x08\x91\xad\xf4\xbf\xab\x5a\xeb\xa1\x2b\x92\xc8\xd0\x10\x60\x58\xcb\xc1\x09\xb2\xcc\x6e\xe2\x89\x8c\x23\x47\x2a\x70\xd5\x7d\x89\xb1\x3c\x62\xd7\x01\x80\x19\x6a\x81\xc2\x92\x10\x8d\xdb\x15\x24\x44\x0d\xf6\xec\x8d\xc9\xea\xe1\xfc\x18\xf7\x84\x04\xc0\x9d\xc9\x89\x94\x4d\x1e\xbc\x1b\x5a\xf1\x25\xee\xa9\xd9\x56\xde\x7b\xac\xea\x19\xf9\xe2\xee\x50\x1d\x1a\xe5\x70\x28\x40\xd4\x0e\xf0\x6e\xdf\x09\x0d\xd2\xd8\x31\xb8\x58\x0c\xd8\xa2\x54\xdd\xac\x72\xe5\xf8\x93\xf0\xe0\xfc\xd2\x45\x09\xe5\x58\x94\x73\x55\x14\x55\xb7\x4f\x7c\x9b\xc4\x7d\x29\x51\x14\x37\xde\x43\x55\xb6\xfb\x28\x30\xe1\x0d\x77\x13\x21\xc9\x52\xc3\xc2\x5b\xe6\xe5\x6b\x18\xcf\xef\xc8\x34\x0c\x4d\xe6\xb3\x81\x52\x59\x1a\x34\x57\x63\xf4\xc9\x22\x69\x0f\x8c\x23\x8a\x46\xfc\x81\xff\x5a\x97\xdd\x2e\xd3\xba\x39\x41\x63\x95\xd2\xc8\x97\x9a\x81\x5a\x42\x5e\xa0\x5a\x8c\x6d\x4f\x48\xec\xd6\x9a\x3f\xfe\x5a\x0e\x8d\xd4\xf9\x18\x14\x4d\xba\xed\xd3\x26\x68\x0c\xcf\xe3\x10\x68\xdc\x75\xc8\x78\x9f\xdf\x69\xa6\xfb\x17\x4d\xb4\xb0\x4c\x06\x25\x34\x79\x33\x44\xd0\xd3\x80\xd2\x50\xe3\x7b\x36\x08\x7e\x03\xb2\xdc\x6d\x5e\x9e\x9e\xee\xfe\xf2\x5d\x52\x70\xeb\x07\x16\x82\x26\xbe\x41\x04\xd4\x14\x93\x6e\x78\x01\x03\x65\xda\xae\x0d\x14\x21\x1e\xce\x25\x78\xdb\x2c\x07\x01\x33\xca\x04\xb0\x6c\xc8\xa8\x84\x05\x34\xdb\xea\xb9\xea\xd6\xbf\xf1\x57\x4a\x33\xb3\xe8\x3f\x0f\x3e\x70\x16\xb2\xd0\x66\xad\x16\x45\xb1\x2e\xdb\xbc\x3d\xdf\xfa\x34\x21\xcd\x62\xa3\xcf\xe2\xa0\xd9\x26\xb0\xe1\x28\xff\xba\x0e\x59\x80\xb1\xaf\xc3\xa9\xd8\x70\xfd\x49\x0c\x95\x66\x99\xc2\x37\x6b\x23\xd2\x36\xc4\x89\x71\xa9\xd9\x35\x8b\x72\xa2\x19\xf7\x12\x12\xdd\x26\x52\x73\xf5\x79\x3e\x62\xfc\xa1\x79\x1c\x24\xe0\x0d\x8d\xae\xe1\xa9\xe0\x67\x1b\x50\xfd\x32\x08\x41\x39\xd3\x18\x8c\xea\x8e\x8b\xdd\x33\xf2\xcc\xd4\x67\xef\x6c\x65\xd8\x53\x55\xfc\x0d\xea\x82\x72\x50\xd1\x10\xd2\xfe\xf8\xe1\xd4\xc3\xbe\xbe\xbe\xe0\x86\x1f\xef\x90\x97\x3e\x0b\x33\xd1\x96\xe8\x7a\xc9\x8c\x27\x03\x6c\xde\xf7\xea\x1d\xea\x2d\xfc\xba\x08\xb5\xfc\x33\x74\xb3\x5c\x42\x24\x6c\xa8\xf6\xf7\x22\xd6\x54\x05\x0a\x55\x30\xad\x76\xca\x48\xe9\x74\x98\x34\xa0\x2a\x49\x9c\x94\xc2\x5f\x33\x86\x08\x55\xdc\x40\x8c\xff\xbc\xba\x73\x33\x73\xc7\x5d\x8d\x62\xd7\x2e\x49\xe0\x58\x7f\x9f\xb9\x84\xd1\xf8\x56\x00\x52\xf5\x3c\xba\xdd\xbc\x71\x4d\x20\x8d\x32\x84\xdb\x0d\x9d\x80\xca\xec\x17\x61\x41\x18\x63\x19\xd9\x3d\x7f\x03\x53\x0d\x37\x7d\xfc\x19\x9c\x01\x0b\x62\xc3\x89\xe4\x92\xa9\x06\xe7\x84\x4f\x1f\xbb\x2e\x29\x87\xc8\x01\x53\x17\xa5\x32\xa0\xcb\xdf\x4b\x81\xb1\x40\x13\xdc\x36\x1f\x2a\x05\xf7\xcb\x97\xdd\xba\x54\xc7\x2a\xf7\x8f\xcf\x08\x09\xdc\x92\xd1\x4d\xbd\x89\xa1\x3b\x39\x19\x01\x91\x74\x73\x19\x64\xd5\x60\x21\xde\x38\x04\xcb\x42\x22\x98\xd1\xef\x12\x79\xeb\xa8\xde\x07\x22\x95\x5d\x17\xca\xd4\x48\x32\x08\xd7\x11\x57\x04\xff\xc9\x75\x43\xca\x8d\xa0\x44\x75\x3c\xfb\x13\xb1\x98\x58\x9d\xfa\xee\xc6\x47\x11\x8c\xb9\x17\x1d\x82\x44\x00\x35\x3f\xa9\x7c\xf8\x95\x59\x14\x25\xcc\xda\x3e\x2f\x65\x2e\xab\xba\x9c\x31\x3f\x58\x14\x1b\x6e\x45\x63\xc8\x76\xab\x28\xf6\x32\x09\xfa\xf9\x57\x1f\x51\x8a\x69\x42\x9d\x9b\x6d\x75\xc5\xcf\xe3\xe1\x1d\xba\x8e\x8c\xe3\x6b\xbb\xe6\x27\x69\x0d\xb0\x39\x4b\xd9\xf5\x56\x01\x7a\x30\xa7\xfe\x73\x81\xfa\x09\xf9\xbc\x31\xc3\x62\x12\xa2\x4e\xc3\xa2\xdd\x23\xa4\x75\x60\x01\xb0\x38\x4d\x10\xad\x89\xfa\x9e\x7f\x01\xaf\xef\xf3\xd2\x2e\x23\xae\x00\xa6\xeb\x25\x52\x2c\xc0\x30\x81\x71\xcc\xae\x88\x81\x44\x86\xed\x95\x44\x04\x2b\xef\x44\xde\x56\x1f\xe5\xe8\x32\x09\x08\x14\x92\xea\xe6\x1f\x7a\x6e\xe3\x6d\x83\x51\x1e\x39\xce\xf3\x35\xaf\x8b\xf3\x13\xaf\xf9\xa1\xe9\xb9\xc3\x2f\x5f\x2d\x23\xa1\xa1\x4c\x96\xbc\xe0\xf5\x15\x6f\x50\x1b\x63\x72\x5a\xc6\x12\x0c\xe8\x8b\x93\x10\x05\x6c\xaa\xba\xdb\x80\x90\xb4\x17\xdc\xf6\xc3\xd2\x90\xa6\x26\x86\xfa\x9e\x77\x16\xda\x08\x41\xc3\xd2\x44\x60\x14\x0f\x78\x73\x76\x51\xf2\xb6\xce\xb1\x30\x7a\xfc\xf4\xa9\x48\x0d\xdd\x9e\xe3\xd1\x32\x11\x5e\x4b\xcb\x65\x3b\x65\x89\x4a\x83\x7e\xa9\x19\x0b\x6a\xd2\x80\x71\x12\xc6\x76\x09\x5d\xb4\x6d\xfd\xa9\xbe\xc3\xd8\x71\x9a\xbc\x1a\xae\x43\x42\x1d\x9a\xe3\x58\x43\xe7\x44\x81\x5a\x6d\xbf\x4f\xee\x58\xc4\x34\xb2\xe1\xd2\x25\x6f\xa6\xcf\x23\x32\x42\x0d\x87\xdd\x30\xd4\xc2\x44\xa6\x11\x5b\xd3\x70\x0d\xed\x79\x40\xc0\x49\x03\x26\x85\x71\x99\xdf\x73\xf8\x70\xc5\xb0\xc8\xd3\x62\x68\x82\x26\x1f\x47\x45\x09\x96\xd2\x75\xbf\x26\xdb\x6a\xd3\x73\xa9\xfc\x33\xf9\x1f\xd7\x47\x50\x42\x7d\xd1\xb9\xd9\xa4\xfc\xcb\x52\x82\x63\x16\xd7\x12\xcd\xde\xaa\xa2\xb3\x9a\xfc\xa7\x53\x92\xa8\x3e\xa9\xfa\x00\x1f\xcb\xcd\xd2\xa9\x17\xce\x4c\xae\xfe\xc6\x80\x6b\xd6\xa3\x8c\x2b\x24\xe6\xaa\x2b\x9f\xbd\x61\x20\x55\xe6\xcb\x91\x16\x52\x8e\x4d\x3c\xa6\x79\x82\xd6\xba\xcb\x01\xa2\x3b\x3f\xb1\x93\xd2\xce\xee\xef\x4b\x3d\xa6\x70\xd0\x7e\x67\x4b\x83\xd4\x88\xff\x95\xa7\x83\x4f\xc4\x0f\xac\xfe\xe9\x69\xb9\x0e\xec\x3c\xfa\x51\xb5\x50\x9b\x12\x90\x79\x63\x35\x25\x3a\xc1\xb0\x9a\x47\xf8\x9b\x4c\xd2\xf8\x8c\x61\xa0\x1c\x94\x1d\xe9\x7b\x46\xd3\x23\x0d\x99\x40\x4a\xaa\xdb\x55\x8f\x01\xef\x7e\xce\x74\x6a\x9e\x0e\x51\x06\x5f\x1b\x32\x69\xc8\x83\xb0\x27\x65\x95\x70\xab\xde\xc7\xfe\x78\x1a\x72\x8a\xf9\xb2\xa7\x53\xc9\xcb\xdc\x5d\x05\x73\x53\xa8\x5d\x0b\xed\xa9\x9c\xf8\xe9\x69\x44\x39\x7e\x06\x4b\x63\x02\xef\xcb\x53\x3b\xed\x02\x09\xe6\x0b\x0e\xfc\xd7\x50\x58\xb3\x73\x8b\x42\x86\x28\x80\xc5\xb1\x2a\x8a\x6a\x03\xc7\x16\xcc\xeb\xf7\x6e\xf3\x6f\xed\xbd\x69\x9c\xa4\x08\x78\x41\x8b\x7d\x77\xfd\xf8\x8c\x14\x77\xfe\x2a\x2c\xc6\xa8\xf4\xa1\x6a\xda\x67\x90\x50\xb6\x57\x03\xc7\x28\x4d\x88\x46\x8a\xaa\x6e\x3a\x6d\xf7\x79\xad\xee\xaa\xf6\x51\x2f\x0b\x7e\x6a\xfc\xf2\x95\x26\x40\xb9\xf6\x80\x31\x28\x8a\xc1\xc6\x96\x52\x08\x11\xc2\xee\xbf\xb0\x05\x8c\x3c\x21\xa7\xdb\x25\x4f\x24\x0d\x52\x46\xcc\xab\x36\x44\xf3\xf7\xd5\x7b\x0e\x23\x5c\x71\xca\x62\x81\xa1\xf6\xcd\x91\x97\x6f\xb7\xcb\x47\xf7\x7b\xca\x4c\xd1\xda\xed\xfa\x11\xcb\x62\x7d\x04\x39\x4d\x79\x86\x66\x11\x37\x6a\x00\xae\x64\xcb\x37\x4b\xae\x23\x1b\x98\x88\x07\x79\xe4\x34\x4b\x03\x03\x82\xb4\xb0\xeb\x66\x71\x69\x57\x8e\xee\x3d\x83\x08\x57\x94\xab\x1c\x17\xb4\x11\x15\x1b\x0d\x52\x21\x03\xac\x3b\xe7\x79\xbd\x9a\x0b\x69\x5c\x24\xf5\x67\xd0\x37\xa9\x50\x4c\xdb\xa4\xc5\x5d\x55\xbe\x4e\xa6\x94\x80\x04\xbf\xe8\x0e\x63\xb7\xdd\x96\x6f\xcb\xb4\xc6\xbc\x91\x34\x48\x25\x57\x18\x3e\xbd\xa9\x0a\x75\x18\x66\x3b\x7f\xcb\xff\x48\xa5\x88\x4d\x70\xed\x6e\xb1\xfc\x63\xf7\xb4\x7e\xbe\x7d\x5c\xf9\x53\x4b\x53\x27\x6e\x16\xbe\xe7\x53\x71\x59\x04\xe6\x3c\xf3\x54\x05\x11\xf1\x08\x51\xe3\x81\x23\xdc\xce\x7f\x04\x95\x30\xc7\x73\x8c\xe2\x53\x96\xb9\xaa\x87\x56\x8e\x87\x8f\xa2\x0c\xaf\xfd\xa7\x76\x84\x98\xbf\xa5\xfc\x4d\x83\x14\x98\xe6\xbe\x0c\x38\xe7\xcd\x7c\xae\x24\x85\x8c\x60\x99\xc7\x6d\x29\x1c\x82\xc0\xdd\x2a\x70\x4e\x2d\xd0\xed\x3a\xef\xec\x02\x74\xd8\xcf\x5f\x02\x39\xfb\x3b\x07\xc1\x71\x55\xb7\xa1\xdc\xe5\x30\xc6\xf4\x65\x5a\x3e\xd5\x24\xc0\xec\xaa\x61\xb8\x95\x6d\x30\x2b\xa9\xf9\x77\x1f\xd6\x7f\x12\x4d\x34\x1a\x12\xab\x9b\xd5\x96\x17\x7e\x35\xd0\x32\x40\x77\xd5\xb2\xfe\xf3\x02\x1a\xbb\xfb\x8e\xee\x26\x0b\x02\x03\x9c\x92\x55\x5e\x1e\x07\xb9\x95\x2c\xc8\x64\x62\x88\xe4\xab\x06\x4c\xed\xe4\x04\x4d\x3d\xdc\x7e\x06\xfa\x10\xee\x78\x01\x4e\x64\xd4\x16\x58\x98\xeb\xcf\x30\x52\xd1\x20\x23\x91\x21\x45\x14\x55\xfb\x58\x7e\x0e\x7d\xca\xc2\xc0\x94\x0a\xde\x2f\xfe\xdc\x5d\xbf\x3c\xac\x6e\x1f\x6e\xdc\x0d\x87\x60\xc4\x01\xec\x07\x59\x3d\xdd\x81\x91\x15\x51\x2b\x9e\x8f\xc7\x5d\x16\xa5\x34\x18\x88\x51\x3d\x96\x85\x73\x13\xb2\x58\x73\x48\x3d\xc3\xd1\x5c\xb5\x07\x0d\xb2\x24\xa4\x32\x74\x40\x05\x64\xcb\x2f\x55\x75\x98\xf7\xe7\xdd\x21\x11\xc3\x27\x1c\x08\x3f\x4e\x7b\xa4\x24\x0b\xc7\xa9\xc0\xed\xf6\xce\xdd\x57\x22\x43\x6f\xf3\xfe\x72\xf0\x0a\x17\x13\x9d\x7f\xa9\x94\x64\x0e\x3f\x70\xcd\xdf\xe0\x47\xde\xe4\xa8\xc9\xd8\x37\x63\x36\x62\x03\xf2\x54\xe7\xed\xd9\xae\xf0\xae\x5e\xf6\xd9\x80\x55\x3f\x89\x79\x66\x34\x51\xa6\x0e\xa9\x73\x05\xd0\x27\xfb\x79\x8f\x2b\xb9\x3f\x3d\xcd\x70\x3d\xde\xb4\xd5\xf1\x56\x56\xf7\xbc\x3c\xf1\xa2\x7f\xcf\xd4\xd2\xaf\xef\x5e\xa1\xbd\xe1\x07\xb0\x08\xb6\x1b\xef\x46\x64\x2c\x4c\x9c\x30\xa1\x0d\x37\x3a\x8c\xcd\x5d\xf5\x9a\xcb\xbe\x1b\xb7\x5c\x75\x46\xb2\x77\x26\x6b\x94\xb1\x24\xc3\x51\xfe\x74\xfb\x70\xb3\x7b\x7c\x5e\x2c\xef\xd6\xbb\xdb\x87\xed\xfa\xf9\xc7\xc2\xbf\x60\xd6\xf5\xfa\x8f\xff\xf3\x1f\xc7\xdd\xb4\xc0\xd0\x75\x10\x12\xb3\x8d\xbc\x2d\x37\xe0\x1d\xe2\x2c\x8b\x05\x16\x43\xdb\x95\xe0\xb9\x92\x73\xcb\xd7\x45\xa0\x31\xcb\xb8\x8e\x03\xaf\x3b\xa2\xf3\xd7\xab\xaa\x2a\xbe\x4d\x73\xe7\x59\x06\x12\x89\x26\x2c\xd9\x8c\xc9\x0c\x7f\x82\xdc\xc8\x78\x12\x0b\x6b\x7e\xed\x78\x51\xec\x1a\x28\x30\x60\x68\x78\x31\xdc\x1d\x73\x91\x60\x1c\xb7\x84\x8f\x8d\xdc\x43\x51\x74\xe7\xed\xbe\xe0\x98\xa4\x61\x72\x6a\xc5\x91\x51\xb0\xa8\x5e\xd7\x65\x5b\x57\xc7\xf3\xf6\x97\xa9\xd2\x6c\x66\x21\x81\x99\x48\x18\xe2\xcb\x77\x07\x9e\xa3\xee\xf9\xa0\x4a\xbf\x6b\x4e\xa3\xcc\xee\x8c\xc8\xab\x35\x21\x57\xed\x7a\x70\xf3\xd1\xec\x24\x5d\xa8\x77\xa8\xdb\xbc\xc1\x60\x7c\xfd\xea\x6d\x9a\x4c\x28\x89\xc1\xf5\xfb\xbc\x6c\xbb\x87\xc5\x8d\xa7\xf2\xd6\xe7\x16\x9a\xf6\x3b\x14\xc7\x91\x9e\xda\xfc\x27\x11\x20\xa9\x21\xf6\xe9\xf6\xde\x68\x05\x65\x85\x2a\xb9\x55\xed\xaf\xa5\xa3\xd0\x18\x91\x28\x31\x81\xe8\xb0\x19\xea\x25\xdf\x9b\x62\x15\xea\x0d\xb4\x37\x27\x04\xf3\xf7\x71\xa4\x4c\x85\x02\x61\xbd\x55\xcd\x65\x91\xff\x1b\x76\x7e\x20\x7c\x1b\xae\xa3\x8a\xa7\x19\x73\xcc\xe8\xae\xcc\x5c\xf9\x93\xe8\x08\x4d\xb6\x22\x6f\xda\x87\x1e\x93\x90\x41\x62\x72\x00\x98\x50\x38\xd5\x25\x3f\x40\xd9\x2e\x0e\xfe\xe2\x20\x29\x5a\xfe\x6d\x75\xd5\x5d\x6b\x14\x3f\xca\x74\x6a\x02\xc7\xa6\xc0\x61\xa4\x72\x37\x5f\xc8\x90\xe9\x8c\xa7\x96\x40\xf5\xba\xae\x0e\xbe\xd8\xe2\xb2\xa3\x36\xac\x07\xb6\xb0\x16\xea\xe6\x19\x64\x7e\xcc\x07\xf3\x49\x6b\xf2\xff\x71\xf6\x27\xdd\x8d\xe3\x58\xfa\x38\xfc\x5d\x7e\xab\x5c\xd4\x82\x00\x48\x90\x7c\x77\xb2\x24\x3b\x54\xe5\xa9\x24\x39\x22\xb3\xfb\xf4\xd1\xc1\x70\x61\xb3\x2c\x91\x6a\x92\xb2\x43\xf9\xe9\xdf\xc3\x8b\x81\x83\xe4\xc8\xec\xff\xa6\x22\xcb\x84\x38\x80\xe0\xc5\x1d\x9e\xfb\x3c\xd8\x7a\xf7\x59\x94\x0e\x6d\x39\x2c\x24\x0b\x12\x19\x91\x0e\x29\x77\xbf\x21\xde\x74\x6c\xa0\x05\x21\x3c\xf5\xb5\xfb\xed\xa0\x54\xfc\xa3\x68\xdf\xd0\xe5\xfd\x1b\xc0\x6b\x41\x38\xb5\x02\xaa\x3e\x67\x3a\x89\x03\xfb\xaf\x54\x10\x63\x7b\x48\x76\xe0\x34\xb9\x2e\xd8\x71\x26\x75\x4b\x41\x69\x6e\x0b\xe7\x58\xef\x11\x7b\x9f\x8d\x0d\x87\x0d\xc4\x8e\x1c\xa8\x73\xb4\x0e\xa7\xc3\x4d\x15\xb2\x62\x82\x91\x1c\x3b\x18\xb5\x27\x83\xec\x7b\x6e\xc7\x6b\x5a\xc4\x22\x47\xc6\xf1\x99\x13\x54\xfc\x75\x71\x46\xc4\xda\xa6\x3e\x75\x0b\xe2\x80\x78\xcd\x6e\x6f\xa1\xbf\xf5\x87\x31\xcf\x3b\xd3\xba\x0b\x91\xbd\xd7\x33\x26\x62\xb2\x8f\x3a\xd6\x70\x1a\xff\xd3\x17\x7b\x44\xac\xad\x4a\x17\xee\x7a\xb0\x9a\x3f\x8d\x52\x20\x22\xc9\x2d\x66\xcd\xd2\xd8\xef\x4a\xbb\xc5\xba\x83\x3c\x32\x16\x0c\x00\x8d\xcd\x83\xce\xc5\x1e\xf1\x3c\xbd\x1e\x49\x37\x2a\xce\x7d\x95\x65\xa6\x3f\xc6\x46\x46\xa4\x11\x43\x7c\xb9\x27\xc5\xbe\x4a\xe8\xdf\x8d\xa3\x8a\xba\xdb\x9c\x1d\x8f\xc3\x25\xe4\x06\x88\x08\x10\x8c\xb6\x9a\x3f\x39\x15\x8c\x06\xed\x5d\x9f\x17\x13\x82\xcb\x1c\xfa\x18\xf3\x84\xfd\xb1\x93\x85\x2b\x93\x2c\xa1\x3e\x77\x3b\x8a\x9e\x85\x32\x19\xda\x43\xa7\xb1\xf1\x17\x2d\x04\xee\x47\x9a\xb2\x9c\x04\x3e\xe0\x03\x4c\x21\x40\x42\x27\x52\x47\x03\x46\x94\xfa\xbc\x39\x56\xed\x18\x89\x28\x74\x9e\x46\xda\x17\xaa\x04\x66\x15\xa6\x49\x88\xc9\x59\x73\x9d\x7a\xa2\xb5\x9b\xf3\xaf\xc7\x02\x01\xa4\x50\x96\xa7\x73\xf7\x1d\x74\x8b\x0a\xa5\x8f\xcf\xe1\xc9\xc1\x71\x7c\x96\x9d\x47\xf7\x2c\xce\x08\x1a\xf2\xc7\x0c\xf3\x92\x21\x76\xba\x46\x00\x57\x37\xc8\xe4\x26\xb7\x60\xb8\x2e\x94\x5c\x83\xaa\x4f\x45\x2f\x12\xcc\x23\x19\xc9\x08\x09\x89\x03\x1f\xd9\x85\x5e\xb1\x1b\x48\x20\xc2\x48\x6a\xf9\xfd\x61\x33\x5f\xaf\x9e\xb7\xbb\xf5\xf2\x6e\xb5\xd9\xae\xff\xd8\xcd\x9e\x9f\x77\x2b\x1f\x56\x49\x02\xc4\x6b\x4f\x5a\x39\xd4\x5f\x46\x05\x92\x8a\x84\x5b\x3a\x1b\xf1\x69\xfb\xb7\xc7\xef\x49\xb2\x24\xb5\x54\xeb\x28\x11\x3a\x56\xa1\xf5\x43\x32\x8b\x98\xde\xc2\x01\xe9\xca\x4f\x35\x3c\x20\xad\x20\xbe\xf7\xd9\xb0\x7d\x38\xfb\xc7\xf0\x3b\x1d\x46\x56\x32\x66\x44\xf8\xee\xb3\x3b\xa4\x50\xf7\x8f\x14\x8b\xcc\xf8\x55\x20\x9a\xf6\xa6\xd0\x2b\x6f\x90\x24\x17\xb6\x52\xe9\x08\x4a\x57\xaa\x5a\x96\x7a\x10\x9e\x4b\x6e\x0c\x96\x02\x8a\xea\xa4\x7a\x68\x85\x4c\x19\xa5\x2c\x70\x1b\x3c\x8c\x74\xd7\xc7\x33\x94\x3a\x59\x00\xeb\x0e\xde\x57\xae\xd3\xc6\x1d\xcd\x28\x50\x4f\xe3\x35\x70\xc6\xb1\x3c\xee\x87\x30\x82\x09\x40\x8b\x42\x44\xf1\xc3\xd1\xe6\x24\xf3\x44\xa3\x71\xfb\x43\xed\x17\x95\x25\x06\xfc\xcb\x40\x54\x76\x7e\x9c\x8b\x78\x57\xaa\x2a\x8b\xff\x7d\xf0\xa4\x50\x53\xfd\x76\x1e\x49\x21\x2c\x59\x41\x59\xfc\xf9\xbe\xc3\x1d\xdd\xdf\x9c\x14\x11\x73\x4c\x33\x5b\x10\x07\xcb\x84\x7a\x25\xc3\x27\x55\x92\x63\x9b\xe4\x6e\xe7\x0e\x62\x2e\xb4\xe8\x73\x0b\x93\x69\x53\x89\xc0\x64\xbc\x28\x6a\x5d\x57\xc7\xe0\x86\x5f\xfd\x16\xa5\x02\x8a\xf9\x8a\x53\xa3\x07\x12\x02\x3c\x92\x3a\x8e\x3c\xf0\x0f\xd3\xd0\x1b\xd8\xef\xef\x45\xa9\xc7\x86\x42\xea\x54\xe4\x3a\x08\xad\x04\x1f\x4d\x6a\xad\x42\xf3\x70\x17\x8f\xaa\x0b\xa4\x8c\x04\x96\xa0\x99\x2e\xe1\xd3\x15\xc3\xaf\x7b\xa2\x12\x12\x9b\x70\x75\x85\x9c\x71\xb7\xa6\x93\x42\xf4\x88\x1e\x09\xc2\x3a\x02\xae\xce\x5b\xd5\x8d\x7a\x03\x0b\x25\xfc\x62\x0a\x40\x5a\x7e\x33\x34\xb0\x7b\xd1\xc2\xb6\xd8\xc3\xb6\xfa\x51\x68\x87\x5c\x0e\x0f\x6b\x88\x46\xe7\xab\xfa\x2c\x9b\x6f\xc5\xc7\xa4\x2d\x4a\x9a\x98\x83\x4b\x30\xfc\xfb\x54\x21\x8f\x51\xd5\xc5\x59\x5f\x5c\xd7\xc4\x1a\x03\xbc\xe7\xbb\x27\x1b\x9b\x3c\xce\xee\x77\xeb\xe5\x66\xb9\x46\x98\xde\xb3\x9f\xca\xce\xd7\x72\x53\x29\x6d\xd9\xfe\xd7\x88\x06\x69\xc0\x8a\xc9\x35\x5e\xe0\x7d\xaa\x1a\xd6\x8d\x31\x31\x7e\x9d\xdd\xa2\xb2\xec\x3c\xe3\x87\x51\x24\xb6\x7a\xd0\x88\xa3\xfa\x5c\xcd\x9f\xf0\xdb\xfe\x8b\xba\xed\x5f\xfd\xeb\xcf\x9d\x5a\xae\x58\x53\x03\xe8\x1f\x15\xa2\x59\x6f\xab\xda\x8a\x2f\x6c\x06\x28\x69\x45\x52\x40\x41\x2f\xf8\xc0\x68\xb0\xf8\xd2\x9b\x99\x5c\x81\x46\xca\x93\xc6\xd9\xaa\xf1\xaf\x22\x33\x45\xb5\xc4\x82\x99\x95\x91\xd8\x7e\x16\x6d\x9f\x7f\x54\xd4\x70\x6e\xc1\xfe\x2f\xab\xc7\x2d\xa1\xd9\x78\x26\x15\x23\x04\x8d\xa4\xae\x6e\x4e\x75\x89\xf0\xc4\x5f\x70\xcd\xe1\x0f\x92\xd8\x56\xb5\xad\xb0\x87\xf7\x44\x7c\xd3\x8e\x1f\x46\xc3\x6a\x7a\xa8\xf4\x98\xa8\x85\x47\x2a\xe6\x19\x3a\x84\x9d\x15\x0d\x1a\xd3\x55\x3d\xaa\xa5\xaa\x44\x29\x2c\xe1\x08\xa5\xe0\xd8\x4e\x91\xbe\x6e\x10\x27\x29\x3a\x32\x21\x0b\x7c\x57\xed\xf5\xcd\xe9\x6c\xb5\x08\xa7\x83\xb9\xc2\x75\x73\x10\x3f\x1f\x4f\x87\x27\x63\xe5\xb4\xe7\x67\xb5\x0f\xdf\xbe\xe2\x92\xa1\x59\x45\xb9\x21\x17\xe0\x5e\x7b\x6d\xd9\x54\xe1\xbf\xfb\xad\xb2\xd1\xaf\x6d\x5f\x7d\xa8\xca\x6e\xff\x5e\xe9\x07\x71\x3c\x0e\x4d\xde\xf0\x93\x57\x1c\x6c\x37\x23\x52\x7a\x0d\x71\xf8\x2a\x25\x56\x00\xd1\x12\x40\xfb\xb8\x60\x29\x90\xbb\x27\x0c\xa2\x14\xe3\x56\x8b\x89\x5e\xe3\x85\xd1\x2b\xbc\xc2\xe9\xeb\x7f\x92\xeb\xc8\x85\xf2\x8f\xa7\x03\x8e\x53\x95\x9e\x88\x05\x74\xe3\xa4\xc4\x32\xce\x5b\xd5\xb4\xbb\xbd\x33\x72\xa3\x3d\x48\xa5\xda\x22\xb0\x94\x50\x6f\xe1\xbe\x33\xaa\xf1\x89\x84\xf6\x84\xee\xdb\xea\x02\xfd\x35\x59\xc4\x22\xe6\xca\x12\x30\x8f\xb1\xa1\xfe\x30\xcf\x90\xdf\x62\x67\x1f\xf3\x2f\xf9\x8a\xff\x71\xf5\xbd\xb9\x93\x49\xce\xd1\x87\x6c\x4e\x07\xd7\x36\xed\x7d\x12\x25\xb3\x0c\xad\x95\x53\xef\x2b\xbd\xdf\xa6\x64\xce\x11\x67\x30\xb7\x2d\x81\x85\xdc\x03\x6e\xe8\x91\x1f\xa0\x28\x64\x6e\x69\xdd\x55\x62\xbf\x86\x6e\x46\x26\x85\x31\xa5\x20\x13\x49\xa0\x08\x3a\xe1\x6b\xbd\xe8\xe1\x53\x3a\x96\x21\x1a\x2e\x0e\x70\x23\x1a\xd0\x57\xaa\x57\x0a\x22\x5b\x57\xee\x1b\x59\x91\xca\x21\x7c\x3f\x26\x25\xb6\xd1\x07\x9a\x76\x03\x6d\xcf\xcc\x17\xd6\xba\x51\xb6\x37\xba\x19\xb4\xdc\x53\xfe\xdb\xd0\x63\x50\x46\xdb\x3e\xbb\x83\x6f\xaf\xb6\x7f\xd7\x84\x1a\xe1\x3c\xf1\x25\x22\x5c\xfa\xbc\xba\x26\x2a\x42\xb9\x85\x53\x13\x0c\xc3\x28\x9d\xa2\x89\x02\xc6\xfb\x0e\xcb\x30\x9d\xdb\xca\xb2\xb3\x4c\x67\x4e\x53\x6e\x71\x45\x55\x58\xda\x06\xea\x21\x2a\x60\x32\x5c\x02\x38\xb1\xb9\x59\xdd\x16\x0d\x4a\xeb\xa0\x8b\x79\x0d\x81\xa3\x99\xb4\x89\x28\x53\x7f\xfa\xd9\xd3\x0c\x62\x4c\x78\x14\xcd\x50\xdc\x6d\x20\x80\xee\xc6\xc5\x2a\xcd\x7d\xec\xf0\x54\xc2\x4d\x5d\xdd\xed\x2b\x39\xb5\x53\x3a\x89\x08\x02\x9a\x6e\x8b\x12\x66\x75\xdb\xfc\x25\x45\x87\x4e\x32\xee\x49\xea\x30\x40\xf4\x8d\x44\xba\x7b\x3e\xf0\x24\xc0\xaa\x3a\x1c\x07\x07\xb0\xbc\xe5\x5f\x15\x2a\xb5\x7a\x1d\x53\x3f\x86\xc5\xc8\x41\x83\xc5\x53\x6c\xc4\xf8\x05\x68\x79\x32\xab\x69\x14\x6b\xe7\x3c\x0e\xbe\x0d\x9d\x29\x8a\xfa\x0b\x55\x69\x57\x73\xf7\x5a\xdc\xa1\x9c\x65\xa8\xba\x56\x34\xcf\x56\xf0\x6c\x54\x7f\xd1\x79\x9a\xa8\xee\x35\xdd\xdd\x85\xbf\xa8\xcc\x39\xd8\x48\x00\x80\xec\x70\xae\x91\xba\x3d\x8f\xed\x98\xce\x8d\x45\xce\x77\x76\xac\x6a\x45\x5d\x4c\x03\x29\x2d\xa4\xfd\x6a\x6d\x6b\xde\xec\x35\x20\xc0\xb4\x52\xda\x73\x3e\x3a\xf6\xd9\x89\xa8\xa1\x1b\xa7\x13\x93\x47\x43\xad\xfd\xd1\xc7\xa1\xb5\xce\x30\xfd\xde\x9c\x0e\xab\xf9\x13\x6e\xfe\xf4\x65\xe3\xa3\x2a\xad\xb5\x41\x64\xd7\x47\xd5\x16\xe5\xab\x6d\x35\x1e\xa4\x3e\x26\x97\x82\x18\xb3\xf4\xff\x7b\x82\x13\xdc\xd6\x55\x30\x08\x1a\xf2\x58\xfb\xdc\xeb\xfc\x9b\x63\xc6\x20\xa3\x3b\x81\x88\x71\xfc\x1c\x03\xe0\x6f\xa6\x3b\xaf\xe3\x54\x83\x9b\xf9\xff\xb3\xf7\x33\x9a\x4a\x88\x72\x4b\xbd\x68\xc3\x91\x91\x2c\xc4\x64\x24\x21\x80\xde\xcb\x7d\x51\xfb\x5a\x2d\x50\x46\x45\x0f\x2f\xc2\x44\xcd\xf8\x55\x01\x35\x1c\x46\x3d\xf7\x3f\xcf\x4e\xfc\x6e\x98\x5f\x04\x16\x59\xca\x83\xf9\x5b\x51\x8a\x3e\x70\xf1\x35\x86\xbf\x59\x8f\x03\x96\x33\x7c\x9a\xc5\xf2\xfb\xf2\xfe\xe9\x79\xb9\xf6\x29\x23\x60\xb9\xc1\x40\xf8\xb9\x6a\x85\xdb\x8c\xfc\xa1\x38\x31\x18\x15\xbc\xdc\x6c\x3a\x4b\x35\x3c\x92\xc6\x08\x61\xdb\x15\x5f\x73\xe9\x40\xac\x08\xf2\xe1\xdc\x57\xaf\x41\xd3\xec\xfa\xc8\x84\x58\x12\xbe\xee\xdb\x3e\x61\xeb\xea\x6b\x31\xde\x23\x20\xc9\x52\xe3\x55\x32\x5c\xfb\x95\x3f\x02\xc6\x03\x5f\x7a\x2a\xd2\x6c\x08\xb1\x02\x9e\x48\xd7\xdd\x22\xea\xd6\x93\x33\xf7\x41\x1b\xf0\x4c\xa0\x8d\xd0\xa2\xf1\x11\x15\x70\x65\x93\x57\x4e\x96\x74\xe4\x06\x00\x37\x92\x72\xa7\x5d\x7f\x00\x0f\x23\xf0\x26\x12\xd2\x28\x43\xae\x2f\xe9\x09\xf7\x5c\x0b\xf8\xa8\xab\xd3\x8f\xcd\x63\xcb\xce\xdb\x7d\x4b\x5d\xb8\xb0\xb9\x6c\x53\x80\x54\x30\x2c\xc7\x57\x3b\x71\xac\xa1\xd4\xc5\x9f\x93\x01\x59\x94\xa0\xf1\xbe\xaf\x5e\x1f\x8a\x57\xcb\xc3\x67\xfb\x0a\x2e\x2b\x44\x93\xe5\x9b\x25\x3c\x8d\x7d\xd1\xf8\xbe\x7a\x2d\x26\xee\x13\xe4\xb9\x4c\xd3\x71\xe1\xcb\xba\x6d\x57\x93\xcd\x90\xab\x34\xb3\x6c\x47\x8f\x00\x7a\x6e\xc9\x8a\xba\x80\x2e\x4c\x4f\x6e\x08\xd6\x44\xe7\xeb\xc5\x68\x55\x09\x42\x22\x4b\xa2\x5d\x1d\xfe\x06\xf6\x15\x84\x04\xa9\x1d\xb5\x72\x0b\xb3\xe7\xe7\x2f\x96\x97\xa4\x19\xbe\xad\x1b\xa1\x43\xac\x02\x52\xc6\x79\x10\xae\xb3\x53\x35\x60\xde\x18\x9e\x88\xf0\x68\xfc\x31\x69\x15\x23\x32\xa1\x2d\x0e\x30\x66\x45\xe6\x11\x00\xe7\xca\xeb\x77\x9c\xa4\xaa\xca\xb6\x28\xa1\x6c\x17\x45\x63\xf9\x0e\xbe\xa3\x69\xbc\x0e\xe2\x01\xc3\x2d\x3e\x08\x73\x6d\x5a\xef\x61\xf3\x56\x4d\x5a\x0c\x4c\x44\x62\x4c\x41\xda\xd2\xf1\xf2\x35\x00\xdc\x0d\x89\x13\x6c\x97\x78\xab\xf4\x3e\xfc\x2d\xcd\x91\x69\xd7\x42\xd4\x91\xb7\x29\x38\x4c\x86\x68\xe2\x1a\xba\xdb\x07\xf1\x13\x93\xd8\xd0\xce\x3e\x85\x77\x5b\x0c\x8d\x53\xcc\xfd\xa9\xaa\x34\x45\x7d\xb8\x42\x14\x3f\x5e\x4c\x86\xca\x5c\xb8\x38\x74\x51\xa9\x53\x67\xaa\x30\x04\xbe\xc6\xfc\x7f\xcd\x09\x30\x14\x88\xb2\xdd\xbd\x68\x0e\x6b\xf1\x01\xbf\x8d\x07\x18\x4b\x7e\xd4\x40\xab\xaa\xc9\x77\x62\x58\xa6\x31\x91\x08\xa5\x46\xe4\x21\x6e\x50\xde\x8f\x30\x89\x50\x99\x35\xe9\x87\xa3\x28\x5e\xcb\x01\x2f\x99\x49\x74\x84\x9f\xfb\x1a\xf6\x95\xe8\xbe\xf8\x2f\xa5\xdf\xdc\x0f\x38\x11\xb1\x45\x23\x9e\x5f\xca\xa2\xb5\xbc\x5e\x2e\x73\x31\x19\xc9\x53\x4b\x23\xd1\xc0\xbc\x3a\x1d\xab\x72\xfc\x40\x3c\xb7\x95\xda\xa3\xa8\xdb\xb2\x8b\x2f\x11\x82\xab\x37\x27\x0f\x75\x31\x1c\x6c\x13\xea\xbf\x4e\x50\x6a\x18\x7e\x32\xa6\x33\x44\x36\x67\x7d\x2a\xdf\x11\x36\x8a\xe5\xb5\x63\x70\x5b\x4d\x9a\x24\x2c\xf2\xce\xd3\x1a\x3a\x57\xa9\xe7\x72\x33\x69\x62\x90\x16\x0d\x61\x04\xb6\x8f\xc0\x6e\x75\xe3\x47\xc8\x84\xf5\x0a\x6c\x1a\xd0\xb6\x0a\xf8\x43\xd2\xd9\x56\x68\x9f\x4f\xc7\xe3\xd9\x52\x81\x5f\xdf\x2a\x4d\xa6\x05\x66\xc7\x4e\x0d\x8c\x63\x5f\x93\x75\x1b\x3a\xba\x72\x65\x2f\x5f\xe1\x8e\xe5\x5c\xa0\x16\xff\x51\xd4\x7d\xc4\x6d\x64\x2c\xd0\x01\x40\x02\x09\xa8\xe3\x11\x7a\xd1\xe8\x88\x63\xbb\xf2\x8f\xd9\xf7\x41\x3e\xd3\xe8\x08\x6c\xa6\xb9\x28\xdb\xfd\x88\x96\x2c\x20\xe0\xff\xc7\x0f\x25\x80\x3d\x16\xbb\xce\x31\x73\x3d\x2a\xdb\x6a\xe3\x94\xf2\x46\x91\xb1\xff\x45\xee\xa0\x6f\x65\xd5\x14\x23\x9c\x95\xd1\x9a\x04\xab\xd0\x39\xa2\xeb\xa1\xfd\x1c\xcf\xb5\x36\x19\xe2\x2e\xef\xc4\xc1\xa9\x15\xfc\x7a\x21\x02\x61\xd8\xbd\x7d\x53\xbd\x6a\x51\x56\xc6\x0c\x5a\xe3\x0c\xc4\xa9\x24\x63\x14\xbf\x3f\xa2\xc0\xf6\x92\xda\x5e\xf7\xdb\xaa\xde\x82\x08\x4b\xce\xa4\x96\x0d\x7a\x8f\xb4\x08\x6b\x50\x55\xad\x3d\x01\xeb\xb0\x6b\xfa\x8b\x52\xfa\xb5\x27\x23\x51\x44\x94\xf6\xf1\xd9\xaa\x19\xe1\xca\x48\x14\xc5\x8c\xc7\x7d\x7b\xbb\xad\x0d\x57\x7f\x0b\x99\x47\x22\xcc\xe7\x7b\x2e\x0d\x34\xb5\x41\xae\x88\x93\x88\x44\x4c\xf7\xce\xd8\xf6\xe7\x44\xaa\xbd\x1b\x41\x81\x20\xd9\x5a\xb7\x8d\x0f\x2b\x5c\x24\x22\x82\xa0\x7a\xef\xa9\x2c\xda\x4d\x0b\x62\x8f\x1d\x7b\x47\xa1\x8a\x09\x11\x11\x89\x88\x26\x1e\x5d\x65\xd3\xdb\x4f\xc6\x69\x36\xf6\xf5\x98\x6b\x66\xb3\xfb\xa5\x55\x88\x3d\x8a\xf3\xf6\x0d\x1e\x44\x39\x3d\xb3\xb1\xcc\x1b\x48\x21\xee\x11\x20\x76\xc1\xcf\xab\xb2\x04\x35\x28\xcf\x4f\x68\x6c\x48\x44\x93\x84\x59\x88\x42\x7d\x28\xda\x9b\x53\x5d\x8e\xdc\x1f\x12\xd1\xd4\x58\xf2\x58\x71\x0e\xa6\x81\x44\x34\x4b\x30\xca\x19\xd0\xdc\xad\x01\x37\xad\x7b\xd1\x22\x68\xec\x03\x59\xe9\x16\x15\x34\x65\xfb\x4d\x7c\xc0\x4c\x6b\x44\x09\x8b\xbd\x3f\x16\x5e\x01\x55\x91\x6f\x42\xbd\x11\xad\x7a\x73\x58\x9c\xf1\x2c\x50\x1d\x93\xbe\x53\xf5\xb6\xaa\x1f\x90\xc1\x6e\x8a\x04\x27\x11\x85\x18\xab\xaf\x8e\xe2\x6f\x58\xbf\xf9\x6f\xfa\x3f\xff\xb8\xfa\x9f\x5f\x1e\xf8\xfb\xff\x49\xc8\xff\xb8\x1b\x60\x49\x86\x6a\x35\x36\x6a\x7b\xae\x8b\x0f\xd8\xc3\x2b\xe8\x31\x86\x6b\xf2\x92\x59\x2e\x9d\x1a\x0a\x2a\xe5\x38\x4e\xb6\xc9\x18\x01\xd8\xe1\x3a\xbb\x5b\x3e\xce\xff\xd8\xcd\x16\x8b\xb5\x9f\x42\xa6\xd3\x91\x42\x93\xcb\x33\x34\xfd\xf1\x1c\xd7\xb0\xa7\x17\x1e\x4f\x19\xd3\x5a\xd8\xb6\xab\x2f\x5d\x37\x12\xc5\xb1\x15\xd3\x3f\xd6\xf0\x51\x54\xa7\xe6\xf9\x24\xf7\x45\xf3\x06\xfa\xfb\x40\x81\xb6\x1b\xc7\x75\xe6\x3a\xe9\xd6\xf7\xf3\x67\xa8\x97\xdb\x6f\x93\xeb\xc5\xa9\xc1\x4a\x85\x29\x64\x55\x0a\xa5\x8a\xe9\x71\x9d\x62\xae\x4d\x83\xb0\x25\xff\x9d\x71\x42\xd6\x9c\x44\x49\x64\x45\xd7\x76\x06\x5a\xf5\xf6\x2c\x0a\x6d\xc9\x38\x6f\xab\x1a\xc1\xae\x93\x49\x4b\x98\xb3\x2b\xb6\xc0\x78\x7e\x69\xf4\xf6\xe7\x70\x93\x25\x51\x22\x63\x2c\x63\xa3\x1a\xcc\xf1\x5c\x23\x26\xc1\x1f\x53\x99\xf5\x59\xda\x93\xbc\x3d\x95\x57\xb3\x6c\x6e\x28\x8f\x25\x7e\x87\x77\xbe\x79\xae\xff\xb0\xfb\x11\xf8\x5c\xc7\xba\x52\xd0\x34\xdd\x96\x8a\x3d\x88\x5f\x9c\x8f\x6b\x75\x21\x79\xd7\x93\x57\x90\x28\x4d\x52\x5c\xe9\xbb\xcf\xc1\xee\x46\xa2\x4c\x26\xb8\x47\x74\x16\xad\x84\xfd\xce\x19\xcd\x9d\x3c\xbd\x3a\x59\xee\x7d\xcf\x34\xd9\x0d\xd7\x48\x49\xd1\x54\x9f\xf3\xaa\x1e\x3f\x5c\xe6\xc6\xe4\x3c\xa3\x56\xea\x67\xfb\xcd\xff\x2e\x07\x8a\x08\x35\x8c\xb1\x37\x57\x98\x79\xfc\x38\x63\x30\xf1\x76\x53\xbc\x9d\xc4\x60\xdf\x23\x91\x24\x1c\x65\xd3\xab\xd0\x82\xbc\x69\xc5\x17\x5a\x68\xbf\xfa\x77\xbc\x4e\x25\x11\xe8\xf8\xef\x7f\x51\x88\x22\x91\x14\x46\x88\x21\xd3\xc6\xf3\x93\xb9\x86\xc4\x23\x91\x74\x81\xc4\x06\xca\xc6\x83\x89\x48\x24\x81\xa3\x1a\x07\xfa\x46\x23\xbd\x4b\x4e\x22\x45\x34\x77\xe1\xe1\x63\x6b\x2e\x50\xa9\xe3\xf3\x2b\x16\xa1\x63\x2e\xbb\x00\x04\x19\x0a\xfc\x01\x69\x19\xb7\xf7\xd5\x2b\xca\x48\x8f\x1f\x40\x47\x11\x77\x50\xfa\x0d\x36\x3a\xcc\xab\xb2\x69\x6b\xf1\x17\x5c\xae\x83\x13\x24\x1a\x73\x0c\x4e\x3d\xa3\x73\x27\xaa\xcf\xc3\x2f\x94\x87\xbe\x3a\x8f\xc8\x72\xdb\xd5\x2c\x4f\xaf\xe1\x2b\x85\x1c\x30\x4b\x73\xac\x9a\x6e\xcf\xed\x22\xf7\x65\xbf\x6f\x82\xb1\xce\xb6\x07\x88\x3f\x14\x25\x5c\x43\xa2\x11\x12\x11\x09\xbe\xbb\x7a\x22\xea\x34\x19\xc8\x53\xa4\x6e\xeb\x9c\xa7\xd4\x5d\x87\x10\x6e\xab\x53\x87\xa0\xf3\xb8\x80\x7a\x04\x4a\x27\x84\x48\x1b\x16\xa8\xb3\x84\x1a\xd5\x1b\xe9\x94\x44\xd6\x8f\x54\x82\xda\x00\x02\x7b\x44\xae\x2e\x77\x42\xb4\xc6\x9c\x8c\x12\x7b\x35\xaf\x9a\xb6\xd9\x58\x90\xde\xd8\x29\xbc\x02\x2b\x22\x84\xe6\xc2\x37\x60\x60\x80\xb2\x2a\x55\x75\x80\x01\xe8\xd4\x8f\x53\x54\xd8\x16\xfc\x03\x2a\xe6\x3a\xd4\x8b\x37\x33\x84\xaa\x14\xfd\xc9\x35\xe8\xa2\x06\xd5\x4e\x1b\xe0\x27\x67\x83\x0c\x33\x31\x87\x2b\x44\x5c\x43\x23\x40\x18\x27\xb6\x8c\xd8\xf9\xa8\xdf\xab\x16\xf4\xae\x7f\xa5\x24\x8e\xac\x67\xba\x77\xfb\x3f\x6e\x63\x2f\xf5\x3e\x1c\xd7\x2a\xb2\xc7\x9b\xf6\x76\x8f\x26\x76\xf4\x1d\x90\x24\x12\xb8\x6d\x42\xfb\x76\x6a\xbc\xe7\x47\x38\xb1\x7f\x95\x27\xcf\xcb\x45\x08\xa7\x24\xa3\x9e\xb3\x61\x51\xa9\x91\x35\x27\x1c\xac\x46\xa6\x8d\xa5\x6f\x11\x0a\x3c\x94\xc0\x0f\xae\x0d\x49\x13\x9a\xc8\x9e\xf7\x63\xbe\x17\xd0\x60\x89\xb1\x77\x74\x48\x2a\xb3\xc8\x7d\x66\xb7\xc5\x4f\xd0\xb3\x52\xa3\xdb\x86\xfc\x85\x7e\x8c\xca\x2d\xce\x09\x5a\x11\x7a\xea\x1a\x9b\xd7\x73\x43\x32\x0e\x94\x0d\x90\x3a\xba\xfa\xec\xc5\xaa\x39\x21\x82\x46\xf8\x98\xab\xaa\x55\x7f\x2f\x6d\x47\x88\x8c\xa3\x3c\x99\x8a\x06\xfb\x13\xaa\x98\x73\x3a\x48\x7c\xdd\x9c\x17\x62\x40\x1b\x40\xfc\xdb\x57\xa9\x49\xd0\xb2\x7b\x59\xd6\xee\x6f\x92\x26\xdd\xab\x32\xa2\xd8\x0f\x4a\xb8\xdd\x01\x8e\x46\x73\x94\xb2\xfc\xb5\x79\x20\x5a\x08\xcc\xe7\x04\x1e\x26\xd7\x43\xd5\x85\xb2\x13\xd7\x8d\x80\x8c\x11\x1d\x70\xb0\xf9\x86\xd5\xfc\x29\x20\xb0\x08\x01\x63\x53\x1b\x36\xe7\xba\x80\x7d\xf1\x01\xf5\x79\xfc\xee\xc1\x28\xb4\xa5\x23\xba\xd9\xf1\x35\x0c\x31\x98\x05\x2f\xda\xe6\xbe\x78\x87\xf9\x5b\xa1\xc4\x6b\xe5\x2f\x62\x78\x6c\xf2\x01\x37\x46\x9f\x34\x24\x34\x0b\x63\x72\x8b\x7e\xde\x21\xb3\xca\xee\x50\x5d\x2d\xbd\x5d\x96\x56\x08\x31\xda\xf6\xb7\x23\x23\xaa\xad\xed\x5c\xf6\x9f\x12\x1a\x31\xca\x2d\xbc\xf4\x55\x94\xc5\x9f\xc1\x56\xd1\x48\x68\x0f\xa0\x9c\x9d\xda\x31\xe1\x0b\xa1\x11\x10\xcc\x54\x6e\x5f\x1e\x56\x7f\xbc\x3c\x62\x27\xd2\x5f\xaf\x23\x1a\x19\x83\x0a\x1f\xc2\xc9\x0c\x3d\x8b\x73\xe7\x70\x7c\x83\xbd\x5f\x4d\x94\x90\x08\x99\xf3\x11\x30\xee\xd0\xde\xcd\xb7\xe2\xf5\x0d\x10\x4a\xa4\xfb\x3b\x24\x90\x50\x1b\x18\xec\xa1\x0b\xf6\x07\x9c\x4f\x84\xd2\x38\xb7\xba\x59\xbe\x71\x72\xd8\x3d\x31\xac\x89\x11\xca\x28\xc9\xe4\x80\xba\x27\x74\x63\x4d\x29\xb9\xc6\x53\xc0\x12\x8e\x48\xab\x99\xaa\xe1\x2a\x79\xb0\x1f\xa7\xb8\x53\xbb\xe8\x7c\xf4\xe5\x41\x8a\xa6\x39\x4f\xde\x02\xd3\x06\xfd\xaf\xc7\xca\x81\xba\x46\xb3\xc6\x4c\x8a\xf8\xe0\xaa\xdc\x9f\x1d\x6c\xb1\xd0\xa1\xb0\x36\x2b\xf5\x83\xe5\xe2\x1d\xbc\x7e\x1a\x13\x45\xb3\xc1\xea\x5a\x4f\x31\x84\x84\xc6\x29\xc5\xd6\x8b\xb6\xfa\xaf\xed\xf4\x90\x48\x30\xd5\xfa\xe9\xbf\xf6\x89\x66\x6e\x37\x04\x62\x64\x68\xf7\xd0\xd2\x89\x63\x42\x93\x38\x96\x2c\xb0\x7f\x63\x2a\xe9\x4a\xde\x99\xd0\xc4\x68\x3a\xd0\xe6\x70\xd9\x98\xde\x74\x52\xae\x24\xba\xcc\xfe\xf5\x8c\x74\xec\xc7\x40\xe3\x6c\x9a\x07\x18\xb3\xe5\x0c\x63\x28\xc7\xd3\x17\xbb\x34\x0b\xa1\x69\x4c\x7b\x25\xe2\x10\xd3\x8c\xef\x35\x15\x04\xeb\x7c\xbb\x2e\xe0\x10\x75\xd1\x9e\x5d\x81\x70\x3c\x7b\xa9\x32\x18\xe7\xdb\xb0\xb0\x87\x05\xfb\xc3\x86\x06\x3a\x29\xac\xca\x6d\x45\xf3\xee\x2d\x3c\xcd\x28\x67\x21\x51\xfa\x50\x94\xc8\x8b\x31\x5c\xae\x59\x9c\x20\xaf\x3d\xe2\x24\xfe\x7d\x02\x67\xc0\x33\x7f\x98\xa7\xca\x3b\x05\x7e\x32\x87\xae\x05\xcd\x44\x6c\x15\x99\x5d\xe0\xd0\xdc\x57\x4d\xa8\x19\x10\x9a\xf3\x24\xb6\x29\x36\xd4\x12\xd6\xbb\x1a\x4c\x0d\xbe\x1e\x41\x68\x6e\xac\xc5\x46\x98\x90\x81\xba\x16\x9e\xa6\x70\x32\x0b\x22\xb5\x7b\xb8\x05\x84\x20\x73\xc1\x78\xbb\x19\xcf\xad\x48\x13\xee\x75\x16\x30\x74\xf0\xe9\x85\xc9\x3b\x10\x92\x62\x57\x42\xa8\x69\x3c\x95\xb7\x55\x7d\x05\x8c\x44\xa8\x50\x80\xc9\x23\x53\x57\x7f\x22\x59\x32\x7c\xf4\xeb\x57\x1a\x4b\x2f\xa3\xa1\x51\x75\x71\xec\xcc\x42\xec\x8f\xa9\x2e\x0a\x19\xcb\xa8\xaf\xfb\x1d\x94\xaa\x84\x1b\x11\xa0\x1f\x9d\x7b\x72\xc9\x1e\x41\xa8\xca\xb5\xd3\x5d\xab\xed\xfa\xbf\xad\xa6\x37\xa8\x79\xc4\x89\x2f\xe5\x5b\xd9\xfe\x87\xa2\x5c\xa3\xac\xef\x2f\x01\xbb\xdd\x4f\xb9\x07\xda\x3d\x14\xe5\xa6\x15\xef\x81\xba\x66\xf2\x1e\x20\x4e\x90\x23\xa9\x84\xcf\xbf\xc5\xa8\xfd\x8f\x2b\xcf\x02\x29\xc3\x8f\x63\xfb\x06\x77\x35\x08\x4b\xe0\xb5\x16\x0a\xc6\x86\x0a\x64\x82\x36\xe1\x42\x91\xd0\x6e\x05\xe3\x87\x07\x65\xd9\x2e\x1f\x56\x8f\xab\x87\x97\x87\xf9\xd3\xe3\x76\x75\xe3\xa7\x18\xb4\xed\x0a\x71\xe8\x7e\xab\x35\x13\x70\x9c\x84\x02\xa4\x94\x3b\x91\xca\x6b\xa4\xd6\x7e\x98\x89\x53\xa7\x21\xb3\x76\x6c\x3c\x17\x23\xb8\x53\x67\x1b\xf0\x2a\x5f\x8c\x32\xd4\xb0\xb4\x67\xbb\x6f\xa1\xc4\xde\xec\xc1\x0c\x19\x43\xf0\x7d\xd8\x62\x35\xd6\xf7\x47\x8f\xcb\x22\x12\xa3\xbf\x70\x28\x4a\xa8\xc1\x27\xd5\x09\x8b\x14\x60\x7a\xeb\xa5\x2c\x86\xbc\xfc\x57\x8a\x12\x84\x45\x3a\xc1\xdb\x70\xb5\x5a\xeb\x8f\x3b\xed\xbf\xbf\x53\x4d\x26\x8c\xc4\x80\x05\x53\x9b\xde\xf6\x49\x83\x07\x71\x9c\xdc\x2d\x55\x82\xf4\xda\x0d\x3e\xf3\xc5\xe8\x3f\x7a\x4b\xc3\x98\xb0\x9d\xb4\xcf\xeb\x25\x36\x20\xef\x58\x14\xed\xfa\xa8\x9d\x25\x10\x21\xa6\xe7\x70\xf6\x34\x1c\x43\xa0\x3a\x61\x89\xb1\x94\x6c\xca\x8b\x18\x8a\xba\xdd\x7e\x4e\x3c\x0d\xc6\xa9\xe4\x56\x14\xc1\xb5\x19\x17\x7f\x5e\xd7\x6b\x20\x8c\xe7\x1c\x3c\x22\x64\x2e\xf4\x47\x73\x0f\xa6\x5d\x95\xf6\xc5\xf6\x8e\x36\x4b\x63\x82\xf9\xf1\x43\x55\x42\xfb\x26\xee\x44\x0b\xa1\xd6\x44\x58\xaa\x79\x1a\x85\xaf\x3b\xf8\xbb\x88\xf0\xea\x3f\x1d\xbf\x6f\xb0\x2c\xcb\x10\x86\xd2\xd3\x68\x5d\x0e\xc9\x21\x93\x03\xa2\xe8\xc6\xa2\x6b\x27\x53\x9e\x0b\xab\xfe\x10\x7a\xf2\x07\x22\x1d\x84\xe5\x46\x78\x49\xff\xd9\x7e\x6f\xe9\x7b\xdd\x21\xc1\x29\xa6\x7b\x37\x65\x71\xec\x73\xee\x84\x49\x65\x7b\xa7\x97\x3f\xad\x9a\x80\x03\x5a\x7c\x91\xae\x75\x3f\x52\x8c\x0b\xcf\x63\xbe\xad\x36\x6d\xa5\xc2\xd6\xc4\x74\x66\xd0\x9e\x62\x2b\xd2\x90\xed\x86\x30\x0d\xa9\xd5\xe9\x39\xc9\x1f\xc5\x9f\xa1\x2a\x8e\x5a\xf7\x32\x73\x19\xf1\xfa\x03\xeb\xc1\xc3\x02\x09\x61\x40\x35\xd0\x01\x6b\xb5\x50\x2d\x12\x0c\x8e\x36\x2d\x66\xe2\x04\xdb\xc0\x2c\x77\x32\x8c\xf4\x8b\x08\x33\x89\x55\xa5\x72\xd4\xdf\xf6\x2c\xd3\x6e\x82\xf1\x73\x9a\xc4\x60\x4a\xe2\x61\xf6\xfb\xee\x65\x13\x04\xac\x77\x37\xb3\xfb\xd9\xe3\x7c\x19\xce\x9c\x72\xee\x85\x60\xf7\x55\x03\x48\x1d\x3e\x7e\x00\x93\x69\x61\xe9\x85\xf7\xfb\xcd\x5b\xd1\x8d\x2b\xfb\x97\x63\x74\x86\x0d\xb6\xdd\x76\x7c\x53\xbc\x0e\xb8\xb5\xc7\xcb\xdc\xe8\x1c\xcb\xc0\x07\xa7\x9b\x6e\xe5\x38\xc3\x59\x4c\xcc\x4d\xd8\x94\x9f\xa1\xee\x9b\xb8\x48\x1c\x11\x9a\x79\x4d\xae\xd3\xd1\x8b\x22\x36\xe1\x30\x4d\xf2\x20\xdd\x84\x5f\x90\xf3\x27\x46\x37\x10\x47\xc2\xd8\x3a\x0c\x76\xd7\x38\x7c\x58\x08\xf2\xe2\x48\x25\x58\x66\x1c\xc0\x44\xc6\x2b\x27\x8e\x94\x48\x9d\xc7\xb9\x6a\x6c\xd3\xf7\x98\x6a\x99\xc4\x44\x26\xa8\xf0\x88\xe5\x03\x5f\xe5\xfe\xc2\x21\x88\x89\x4e\xb4\x0d\x17\x8d\x81\x6b\xb1\x4b\x4c\x49\x84\x46\xaa\x8b\xf3\x77\xb2\xe7\x66\x26\x31\x4d\x2c\xe5\x7b\x79\x3a\xb8\xd6\x72\x2f\x74\xd7\x1d\xe4\x1a\x53\xc2\x9b\xed\xdc\x31\x1f\x86\x23\x90\xe2\x4c\x3a\x1d\x63\xc7\x34\xe4\x12\x86\x9d\xff\xda\xd9\x75\xcc\xe1\x85\x5f\x18\x0b\x32\x77\x82\x2f\x6f\xc5\x71\xc4\xa0\x3f\x76\x43\xdd\x63\xfe\x2a\x86\x8d\x19\x05\xfc\x68\x51\x02\xf6\x00\x77\x62\xb2\x50\x62\x26\x32\xec\x85\x2f\x9a\xbe\x30\x37\xfa\x56\x62\x26\x24\x86\x0b\xf8\xad\xcc\x1d\xab\xb5\x41\xcd\xc9\xf1\xa9\x62\x91\x61\x1e\xeb\xbf\xfe\x79\xfb\x6c\x3d\x1d\xff\x58\x9c\xe4\xc9\x80\x42\x2b\xfc\x99\x65\xcc\xd7\xe9\xcf\xcf\x7b\xac\x9d\x34\xfd\x41\x89\x85\xb3\xdd\x9b\x68\xde\xb6\xd5\xac\x51\x45\x31\xb9\x33\x9e\x08\xac\x00\x0d\x6c\xe5\xdf\x4a\xfc\x75\x91\x8a\xee\xce\x3d\xdf\xdc\x3d\xdd\x04\x04\x07\x89\x53\xae\x31\x31\x7c\xe7\x52\xab\xf6\x8d\xdd\x56\xb5\xab\x3e\x17\xaa\xef\xca\x24\x71\x9a\x11\x63\x3b\x73\xdf\x6f\xaa\x66\x3a\xb1\xa9\x48\x10\xa3\xbc\xf9\x14\xc7\x67\x71\x6a\xa6\x4e\x40\x9c\x4a\x25\x7d\x0b\xda\xf7\xe7\x01\x62\x98\xc4\x99\xb1\x7a\xd1\xc7\x6a\xbf\x7f\x98\x48\xa2\x91\x38\x67\x39\xa2\x93\x85\xa3\x9a\x09\x94\x2b\x7d\xa5\xb3\x1b\x24\x7d\x03\xe7\xee\x60\x3b\xf9\x76\x47\x87\xed\x9e\x9c\x2e\x4e\xc9\x80\x1e\xf6\x11\x3e\x43\x23\xa5\x03\x37\x93\x38\xe7\x32\xb3\x09\x7d\xbd\x39\xee\x8b\x76\xf6\x5a\x03\xf4\x38\x71\x12\xe7\x59\xac\x89\xd7\x85\x40\x76\xaa\x3b\x28\x91\x1c\xf4\xfa\x1b\x10\x8c\x78\x1a\xb6\xd5\x6a\xb7\xa6\x93\x7b\x12\x26\xb7\xf7\x74\xf2\xa4\xff\xaf\x45\xd8\xe9\x63\xc9\x00\x09\x2c\x6e\xe6\x9b\x61\x56\x3e\x96\xc2\x36\xfb\xf8\x08\x69\x66\x4c\xb1\x2f\x90\xdf\xc6\xb6\x2f\xfb\x71\x52\x31\xd6\xfb\xe3\x57\x89\x10\xc6\xf7\x23\x21\x52\x41\x85\x0e\x61\x99\x6f\xa2\x76\x62\x30\x2b\xa7\xae\x33\xb1\x26\x4a\xe6\x88\x32\x2b\x9a\x5b\x2f\xe0\xf2\x3a\x98\x30\x1d\x65\x88\x0a\xed\xfc\xd4\xf5\x6c\xbe\xdd\x3d\xce\x1e\x96\xe1\x60\x62\xa2\xd4\xc9\x39\xdd\x56\xf5\x30\x13\x11\xeb\x2c\xc1\x9a\x30\xa2\x74\x4e\xe1\x7c\x86\x4a\x84\x8b\xed\x74\x61\xcc\x17\x93\x6e\x58\x8e\xbb\xde\xe6\x08\xa0\xcf\x23\x21\x2b\x92\x90\x24\xd1\x2e\x5d\xfd\x1d\x9a\x21\x18\xc0\x0d\xa0\xcc\xd0\xbe\x8f\xb0\xa7\x0b\x1f\x8f\x62\x69\x84\x22\x4c\xc3\xc4\xde\xb5\xfc\x92\xff\x88\x13\x26\x33\xa4\x6a\xb9\x11\xa5\xaa\xea\x6f\xa2\xd4\xfb\x69\xe4\x95\xc4\x34\x8d\x75\x90\xe6\x0b\x61\xc7\xd0\x99\x4d\x62\x66\xe5\x33\x94\x6b\xda\xc7\x66\xea\xa1\x93\x9f\xc4\x8a\xe0\xae\xf7\x50\x94\x70\x21\x15\xdd\x1d\xd7\x12\x11\x07\x2f\xf5\x10\x2f\x48\x92\x24\x63\x98\x96\xbd\x29\x5a\x2b\xd9\x3a\x38\xc6\x79\x8c\xc6\x71\xc8\x55\x49\x12\x0e\x59\x1e\x64\x5e\x9f\xca\x7d\x50\x83\x19\xb0\x54\x91\x24\x25\x1a\x67\x5c\x0f\x70\xc9\x36\xe9\xdb\xef\x21\x49\xaa\x12\x70\x59\xdc\xbb\x6a\xaf\x3b\x5f\x66\xf3\x7e\x9a\xcc\x4f\x46\x12\x93\xf4\x25\x58\xdb\xc2\x32\x24\x30\x25\x49\x16\xe7\x4e\x71\xb1\x8b\x5a\x6e\x0a\xdd\x8c\x8d\x69\x92\xa5\x19\x32\xa5\x6f\xde\xeb\xd3\x41\xee\x61\x2e\x4a\x7d\x1e\x3d\x6b\x4e\x2c\xff\xdb\x11\x69\x2b\x2d\xd1\xd8\xe2\xe9\x26\x2c\xb6\xd1\x64\xe6\x54\x66\xc9\x40\xe8\xc6\x7b\x11\xa3\x77\x2f\x62\xc0\xcc\xba\x4d\xf3\x77\xa1\x90\x47\xef\x8e\x9f\x4f\xf0\xc8\x33\x8e\xd9\x89\xbe\x58\x21\x42\x49\xf4\x33\x6f\x6b\x00\x4f\xca\x49\x12\x61\x12\xcc\xda\x09\x4f\x55\xbd\x01\xdc\xe0\xdc\x61\x45\x73\x6c\xe1\xef\xec\x5d\x0b\x4d\x78\x7d\x5a\x82\x94\x81\x23\x61\xdc\x45\xf3\x2b\xd0\x21\x49\xb4\xc9\xf0\x2b\xac\xd1\x48\x68\xf0\x89\x84\x70\x58\x24\x96\x78\xd0\x88\xd3\xbe\x75\x04\x72\xee\x20\x88\x2c\xef\xe1\x1c\xdf\x60\xbf\xaf\xc6\x2b\x1c\x8c\xcd\x10\xda\x7a\xb0\x63\xc0\x9f\xd9\x06\x3b\x7f\x12\x93\x1b\x62\xae\x48\xea\x3f\x56\xed\x12\x8b\xb1\xe1\xe1\x8d\x88\x49\xe0\x3d\x9f\xb5\x9e\xc8\x9e\x70\xc2\x2d\x01\xfd\x66\x3b\x1f\x79\x96\x63\x63\xc2\x09\x48\xec\x8e\xdd\xc9\x53\xfd\x85\xd9\xe4\x34\x51\x5e\xd5\xed\xbe\x52\xef\x37\x67\xe4\x7a\xbe\xac\x67\x70\x46\x35\x7e\xe0\x45\xd9\xb4\x45\x7b\x72\x0a\x0b\xaf\xe0\x61\x49\x7e\x18\x27\xc2\xf7\x54\xd7\xf5\x4b\x51\xb6\xb7\x05\xec\xb5\x2f\xdd\xf1\x98\x48\x84\xa9\x0b\x7d\x5d\xc5\x80\x60\x53\x36\xed\x15\xbb\xec\x72\x19\x92\x1e\x11\x9e\x50\x16\x3b\x7d\x8f\x61\xab\xc5\x95\xbb\xe6\x09\x60\x6e\x6b\x77\xb4\xc9\xd8\x1b\x27\x4f\x3c\xbe\x24\xcf\xb5\x71\x93\xe0\xdc\xf0\x2f\x15\xcd\x39\xe1\x69\xce\xa9\x95\x97\x29\x3e\xa0\x6e\xc4\xde\x5a\xd9\xe7\xba\x6a\x2b\x55\xed\x87\x1f\x24\xcf\x12\x8a\xc9\x06\x6c\x95\xaa\x4e\x03\x3e\x82\x0b\x95\x8e\x09\x85\xc0\xf5\xbf\xf6\x4f\x96\x65\x02\xbf\xde\xfb\xcf\x1e\x65\x46\x78\x26\x05\x73\xb6\xe8\x07\x14\xb3\xd7\xd7\x1a\xe5\xe4\x1f\xc4\xd9\x09\xf7\xfa\x71\x2a\x57\x16\xb8\xd0\x05\x31\x17\xe6\xff\xaf\xfe\xff\x78\x42\x72\x91\x62\x19\x75\x2e\x9a\xb7\xdb\x6e\x83\xa8\xf5\xa7\xa8\xc1\x65\xb5\xdc\x20\x11\xe5\xe8\xed\xfc\x35\xfd\xd9\x45\x4f\xc4\x17\x97\x15\x2c\xb6\x79\x64\x4c\xba\x6e\x3c\x3d\x86\x4f\x0d\x0f\x6b\x23\x5c\x70\x86\x76\x64\x53\xa0\x3a\xad\x35\x61\x23\x4a\x2b\x37\x50\xc6\x11\x04\xc9\x9e\xf1\x9c\xc9\x24\x37\x3c\x6c\x71\x03\x7a\x0c\x6f\x2c\xb9\xcc\x28\x36\xb9\x76\x0e\xe5\x71\x9a\xfd\xfe\xe2\x29\x54\x1e\x23\x3f\xa2\x77\x41\x7e\xcd\xc3\x40\xb8\x82\x50\xa5\xf9\xe7\xd3\x1f\x57\x55\xa0\xc7\x4f\xa4\x89\x11\x72\xc2\xfa\x3d\xdb\xa3\x43\xd4\xc2\x5f\xfc\x34\xb1\x94\xae\xa7\x06\x6a\x37\x67\x13\x1f\xba\x1b\x82\x0b\xe9\x6e\x3e\x5a\xf7\x5a\x99\x68\xd4\x2b\x68\xd9\xcb\xaf\x84\xa1\x1c\xa8\xc1\xa8\xef\xb6\xaa\xdb\x11\x84\x83\x83\x14\xb1\xf0\xe4\x02\xea\xbd\xa9\xab\xaa\x5d\xa1\x00\xa8\x29\xae\xa9\xfc\x8f\xde\x85\x49\xa5\xca\x47\xad\x71\xd0\x6c\x26\x2c\x57\x84\x1b\x69\x55\x67\xad\x45\xf7\x7c\x1a\xd3\xda\x21\x37\x4a\x58\x9e\x7f\x5d\x1d\x2f\x4e\x01\x39\xed\xee\x12\x0e\x45\x7b\x0b\xd8\xe8\x33\xa1\xf7\xf5\x03\x0d\x64\xb6\xe1\x46\xe8\xd1\xb6\x91\x46\x59\x1e\xd9\xec\x33\x1c\x45\x0d\x0e\xd2\x80\x45\x9f\xdf\xfc\x10\x61\x35\xb0\x3d\xbb\xc3\x16\x26\xcc\xa1\x24\x8d\x24\xc1\x7c\xfa\x7f\x3a\x7b\x30\x58\xfc\x69\x64\xc0\x3b\x28\x3f\x8a\xf2\x6b\xd9\x6c\x92\x12\x42\x10\xc9\xe5\x69\xd9\x7a\x1d\x9d\x69\x99\xbf\xb7\x44\x29\xc9\x88\x03\x7a\x87\x57\xbc\x6a\x86\xba\x9f\x24\x25\xb9\x4d\xee\xaa\xce\xdf\x39\x88\xf7\xb0\xdf\xa6\x44\xa7\xc6\xee\x07\xff\x39\x35\x36\xa4\xb3\x0d\xf6\x03\x27\x24\xa5\x49\x9a\x3b\x8a\xab\xd9\xff\x9e\xc4\x41\x4c\xf2\x02\x29\x55\x11\x8a\x79\xd9\x58\xe4\x0b\xea\xe1\xc9\xb3\x52\x13\xa5\xc4\x67\x2f\x66\xfb\xb0\x0f\xfb\x5b\x1f\x3c\x21\x13\x29\xae\xe6\x02\xe1\xd6\x28\x29\x33\xbe\x3e\x83\x38\x71\x19\x97\xd9\xc3\xfd\xc0\xb1\xbe\x39\xed\xdf\x07\xf0\xc8\xee\x9c\x3e\x49\x98\xc6\xd4\x22\x73\x95\xd8\x6f\xeb\xe2\xb8\x87\x75\x55\x1d\xbe\x0c\x8f\x47\xab\x3b\x4d\x88\x2d\xd7\x09\xad\xe7\xcb\x2d\x1f\x72\xad\xf0\xf8\xca\x3f\x63\x96\x95\x21\x42\x24\xf3\x67\x14\x1a\xe5\x0c\x0b\x55\x79\xca\xbd\x61\x50\x93\x26\x52\x21\x07\xee\xb1\x06\xc4\xcf\x0e\x28\x26\x49\x9a\x98\xdc\x96\x56\x50\xb2\xc1\x47\x08\xe3\xf9\x46\x71\x88\xff\xf7\xff\xfb\x7f\xff\x55\xec\xf7\x3d\xa2\x2f\xe5\xb1\x49\x9c\xeb\xbe\x98\x6d\x67\x43\x03\x90\x72\x25\x70\x63\xf9\x06\x75\xb5\xad\x11\xfe\x70\xb1\x7d\xfe\x15\x9e\x68\xc8\xfd\xeb\x4e\x9b\x46\x99\x8f\xa3\x96\x8d\x12\x47\x70\x19\xa3\x41\xc6\x7b\x30\x38\x4e\xa3\x1e\xf1\x79\x53\xe8\xeb\x08\xc6\x34\x75\xfa\x0b\x55\xb9\x3f\xdf\xa0\x18\x48\x6d\x5b\x84\x97\x3f\x5b\x28\x9b\x69\x6f\x30\x49\x53\x41\x70\x43\xbc\xab\xee\xaa\xe7\x90\x8c\x4e\x53\x23\x22\xd7\x28\x7a\xe7\x48\xe4\x3a\xfb\x35\xf9\x71\x26\x32\x8b\xae\xee\x42\xfd\xee\x7d\x60\x82\xed\xb7\x70\x54\xe5\x03\xe6\x31\x4b\xb3\x57\xf4\xdb\xd5\x85\xa4\x2e\x49\x33\xb0\x6a\x96\x35\x6e\xda\xa3\xb2\x9d\x1b\x91\x13\x2b\x9b\x31\x7b\xd9\x7e\xdb\xcd\xbf\xcd\x1e\xef\x96\x4f\x3f\x1e\x97\x8b\xee\x7f\x3c\x54\x34\xcd\x63\xab\x0a\x5b\xed\xb5\x6d\x55\x85\x05\x28\x71\x0e\xe0\xc6\x71\x20\xf2\xcb\xc4\x58\x9a\x67\x34\xf3\x14\xc1\xdb\xea\x11\x7e\xb6\x2b\xfd\x33\x5c\x08\x34\x7a\x89\x8e\xb4\x77\x03\xaa\x0e\xc1\x5d\x2a\xa2\x1c\x29\x0a\x0d\xc0\x43\xa5\x71\xb7\x08\x73\x23\xa8\x40\x13\x67\xd7\x79\xdd\x3e\xd3\x70\x44\xe5\x56\x0f\xf6\x69\xb3\xee\x7c\xaa\xd1\x52\x94\x34\x67\x30\x14\x2f\x70\x8d\x02\xe3\x5b\x96\x2c\x47\xa4\xac\x63\x26\x7b\xae\x61\x63\xb9\x95\xbe\x6e\x6e\xbf\x7c\x6e\x29\x33\x17\x2a\xfe\x07\x54\x3b\xa6\x51\x72\x43\x14\x75\xa2\x49\xb0\xdf\xef\x96\x3f\xd5\xdb\xeb\x6e\x0d\x17\x72\x55\xe3\xdd\x3c\xd5\x54\x61\x75\xe6\x79\xbd\x7a\x58\x86\x89\xd4\x4c\xc5\x56\xe4\x1c\xab\x1d\xf8\xcd\x6f\xa6\x1b\x60\xaa\xb9\x94\x63\xe9\x90\xa5\x40\x34\x77\x83\x3d\xd3\x4f\xa5\x87\x9d\xcf\x61\xbf\xff\xc2\x9d\x48\x21\x8b\x64\x3c\x64\x6c\xdf\xbc\x15\x47\xe4\x2c\xf0\xa2\x23\xd7\x77\x25\x00\x86\x2e\xcf\x43\x55\x95\xab\x52\xf9\x3b\x37\x24\x25\x36\x45\x5e\x1d\xa1\x5c\x3c\x85\xbf\xc7\xc0\x5c\xa1\x74\xf7\x5a\xb5\x3b\xdb\x3a\xd2\x6f\x46\x26\xe3\xd8\x5e\xe1\x03\xb0\x35\x58\x96\xd5\x6a\x14\xfb\xa7\x46\x8a\xc0\x4c\x82\x5d\x08\x93\x4f\xd0\xa8\xc4\x13\xdb\x28\xc0\x50\xc8\xaf\xb1\x2c\xe2\x16\xb5\x58\xe8\xa1\xd6\xc7\xaf\xeb\xbb\x59\x04\xb1\xf0\xf2\x16\x5e\xcf\xc3\xce\x6a\x73\x5b\xd5\x6b\x31\x6e\xbc\x23\x19\xd1\x89\x2f\x54\xd8\x52\xf2\x75\x04\xe3\xe4\x2a\xc4\x48\x4c\x26\x8f\x74\x05\xdc\x31\x9a\x33\xcc\x94\xb8\x94\x9e\xcd\x77\x5e\x3f\x0d\xcd\x39\xee\x3f\x08\x49\xd0\xc5\x47\x78\x74\xc6\x25\x02\x7e\xf7\xa2\x69\xad\x1b\xe4\xc4\xe3\xfa\xad\x24\x63\x29\xc4\x2e\x13\xb9\x6b\x5a\xd1\xf6\x3f\x56\x09\x52\x6d\xdb\xce\xda\xd3\x61\xb6\x1a\xcf\x79\x16\x47\x29\x24\x3e\xbe\x5e\xd4\x81\x2a\xba\x3b\xa2\xb8\x4b\xd5\x6e\xc4\x1e\x36\xd5\x7e\x92\xf6\xca\x12\x62\xa3\xe9\x43\x67\x11\xce\x8e\x38\xf2\x7b\xa1\xa1\xba\x13\x07\xe8\xb1\x58\x97\x0f\x9b\x74\x31\x9f\xb5\x35\x2d\xa8\xf6\x2d\xe4\x97\xb3\x44\x4a\x04\xb8\xcd\x9e\xe6\x3b\x31\x16\x61\x21\x19\x97\x0c\x43\x89\xe6\xad\xfa\x44\xfe\xa2\xab\x9c\xa1\x24\xe3\xc6\x6a\x00\x61\xb9\xe9\xb6\xaa\x41\x89\x3e\xb9\xe7\xb1\x74\x59\xaa\x00\x55\x0e\x5f\xc5\xc1\xb2\x8a\x96\xde\x70\x65\x19\x8f\x30\x15\xab\xaa\x83\x2c\x4a\x58\x5c\x6b\x45\x25\x59\x96\x49\x17\x0a\x5b\xf0\xc6\x06\x73\x55\x96\x5a\xcd\x9f\x29\x8f\x19\x7a\xf3\xc1\x83\x59\xb5\x70\xb8\xe6\xfa\x7d\xb1\xba\x72\x69\xbb\x59\x54\xb5\x3f\x1d\xca\x7a\x28\xec\x32\x19\x29\xa2\x04\xab\x64\x3b\x59\x68\x6c\x9e\xdf\x0c\x24\x8d\xae\xa7\x6e\x32\x41\xc0\x91\xab\x62\xa2\xcd\xb9\x79\x17\xd0\xea\xc9\xaf\x64\x96\x46\x9e\x0b\x1f\xbf\x10\x8a\x79\x99\xc9\x4b\x50\x49\x9a\xf6\x7c\x22\xfe\x4d\x75\xaf\x33\x44\x0f\xd3\x2a\x6f\xa6\x64\x86\x10\xcf\xbb\x02\x05\xf6\x7b\x2d\xfa\x2f\xec\xf0\xe4\xc6\x14\x70\xed\x22\xb9\x81\xc7\x18\x0a\xf4\x7d\x37\xac\x73\x1c\xdd\xcf\x34\xd0\xcc\x51\xd6\x04\xaa\x0f\x2c\x7e\x5c\xdc\x1f\x08\x62\xbb\x45\xa1\xf6\xfd\xe1\x24\x33\x22\x57\x5e\x92\xaa\x6a\x6f\x0a\xc4\x0f\x8f\x24\x9f\x26\x6f\xca\x48\x82\x75\xe8\x53\xd9\x54\xfb\x29\xe8\x2b\x8f\x98\x4d\xd0\x3d\x88\xff\x74\x37\x12\x14\xd0\x49\x1e\xa9\x1c\x61\x4d\xa7\x52\xd9\x3c\x98\x93\x7a\xed\xab\x80\xfd\x40\x2c\xa5\xa8\xb3\x0a\x1f\x4f\x1e\x41\x6e\x75\xd0\xbc\xb4\xbb\x8d\xa6\x5f\x1a\xb8\x54\x33\x70\x3f\x21\xb9\xf0\x02\x28\x3f\xaa\xfa\x7d\x12\x9c\xe7\xc4\x00\x06\xe7\xb7\xb7\x73\x7f\x11\x9a\x0a\xed\xb2\x88\x0b\xd8\x63\xa6\x44\x0f\xe5\x3f\xdc\x30\x16\x71\x6c\x64\xb4\xdc\xe8\x6d\x0f\x66\xcd\x19\x31\x98\xef\xfb\xf3\x0e\x67\xf3\xcd\xcf\x8e\x83\xa1\x36\x61\x1c\xd7\x68\x75\x7f\x8c\x3a\x32\x7e\x99\xa8\xcc\x59\x96\x60\x6b\x40\x09\x9f\x58\xca\xb8\xbe\x39\xe6\x31\xc9\x75\x80\xfd\x1d\x8b\x29\xc7\xac\x1f\x15\x87\x06\x31\xdb\xb4\xf4\x65\x23\x2c\xc9\x63\xa1\x50\x7f\x63\xe7\xc1\xfb\xa3\xbe\xcc\x8b\x4e\xbb\xbf\xe9\x88\xbb\x93\x27\x2a\x25\x9d\x85\x11\xaf\xa2\x28\x9b\x76\x77\x1c\xb1\x78\x92\x9c\x53\x8b\x4e\x7d\x5e\x2f\x11\x61\xf2\x30\xfb\x7d\xf5\xf0\xf2\x30\xe6\x74\x26\x39\x17\x0a\x3f\xbd\xf5\x49\x16\x63\xb4\x5c\x9e\xe6\x14\x77\xb1\x40\xd8\xe8\x5b\x8f\xaf\x4f\x73\x2a\x04\x06\x03\xff\x9c\x3d\x2e\x66\xe1\x1c\x52\x8a\x9e\x32\x7a\x2d\x6a\xcf\x42\x7c\x7d\x76\x33\x66\xf5\xbf\x2c\x78\xcf\xab\x9e\x1c\xbb\x25\xef\x4d\xc2\x17\x7b\xff\x5f\xcc\x56\x06\x0c\xd7\x97\x95\x77\x18\x9b\xac\x3c\x8f\x52\x47\x17\xf3\xd3\x05\xa5\x57\xfd\xbe\x3c\x57\x02\x91\x53\xb3\x83\xac\xab\xe6\xd4\xf4\xd4\x32\x24\x17\x69\x1e\x6b\x2f\x14\x52\x1d\x56\xcd\x1a\x84\x1e\xb7\xb5\x84\x0f\x48\x65\x0c\xa3\x31\xe5\xb8\x66\xaf\x6f\x67\xb9\xca\x72\xd3\x17\xa1\xba\xfd\xac\x78\x2d\x2d\x23\xeb\xe4\xbb\x52\x42\x18\x4b\xb1\x89\x55\xaa\xeb\xeb\x5b\x81\x42\x40\xd7\x62\xf3\x6d\xa6\xde\x07\x68\x97\x5c\x99\xc4\xd8\xde\x96\x56\xbd\x4d\x59\x2f\x2f\xda\x6a\x49\xae\x29\x47\x53\x65\x49\xae\xa6\x86\x4c\x77\x5f\xb9\x6b\xa1\x34\xed\xea\xcb\x40\x33\x0c\xe7\xd8\x52\xb7\x58\xcf\x7e\x84\x53\x24\x24\x8f\xfb\x5c\xfa\x20\x83\x90\x03\x07\x2c\xcc\x9c\x1a\xa8\x2d\x98\xc4\xf1\x1e\x39\x3b\x31\x9e\x18\x90\x0a\x8b\x29\x77\x96\x96\xc8\xb2\x99\x80\xbe\xb9\x14\xc4\x72\x3f\x30\x09\x04\x01\xcd\xe5\x4f\xd5\x77\x85\xe5\x46\x48\x64\x1d\x13\x5a\xfb\xfe\x6c\xec\xad\x53\xc8\xfc\xee\xb2\xdd\x43\xb6\xbc\x30\x5d\x46\x71\xf4\xd2\xa4\x50\xef\xa7\xe3\x0e\x1c\xef\xc7\xa6\x15\x9b\x56\x5e\xbf\x0f\x11\x45\x86\x6b\xac\x14\xee\xf7\x55\x3b\xd1\xef\x23\x82\x50\xc2\x3d\xc5\x8b\x93\xde\xd3\xda\x61\x85\x7b\xbd\x09\x22\x88\xce\x70\x61\x6c\xd4\xdb\x01\xd4\xfb\x7e\xd8\x79\x4e\x04\x25\x09\x76\xa6\x0d\x10\xca\x7f\xcb\xa2\x0a\x4a\x53\x34\x6c\x87\x56\x8f\xd0\x44\x82\x32\x83\x02\xd7\xfb\x4a\x68\x0b\x71\x05\xed\xbb\xec\x9a\x4b\x99\xf9\xf0\x3c\x34\xce\xb1\x78\xf2\x4f\x51\xaa\xea\x3d\x9c\x2d\x49\x90\xba\xe0\xa3\x6a\xbf\x10\x88\x19\x6c\xe7\x82\xba\x42\xb2\xeb\x28\x0b\x2d\x25\xfe\xb0\x8e\x52\x3e\xee\xc3\x78\x2a\xf7\xe7\xbe\xec\xb1\x09\x61\xaf\x60\x82\x66\xb6\x59\xea\xb8\xaf\xce\x0b\x5b\xc1\x72\x95\xe2\x5f\x72\xcd\x11\x91\xa8\x18\x37\x1b\xeb\xf9\x0f\x99\xb2\xc6\xe3\xb8\x53\x04\x3d\x56\xed\xae\x1d\xc0\x62\x04\x4f\x00\xb3\xa0\xda\xb5\x40\x77\xcb\x6b\x59\x86\xc7\x48\x09\x8b\x58\x0f\xa7\x44\xd5\xab\xfb\x3f\x8e\x57\xfa\x37\x45\xca\x73\xe4\x4c\xd3\xa0\x2a\x0d\xd3\x83\x92\x62\x6c\x3c\x54\xf9\x5d\xa9\xea\x8b\xa7\xca\x73\x85\xe8\x23\x68\xdf\x9c\xb3\xe8\xbf\x0b\x21\xba\x4f\xd8\xa6\x01\xec\x83\x62\xc5\x87\x84\xc3\x99\xce\x59\xdf\x4c\x79\x0b\xde\x62\x0a\x99\x59\xd0\x40\x1f\x23\xfd\x9a\xaf\x81\x08\x1d\x65\x32\xf1\xbc\x1c\x47\xa8\x51\x1f\xea\xfa\x6e\x24\x74\x9c\xa1\x9d\xf0\xdb\xdf\xf3\x72\x3d\x5f\x3e\x6e\x67\x77\xcb\x9d\x2f\xa1\x09\x0d\xe0\xa5\x43\x5e\x5e\x56\x8b\x78\x50\x89\xf0\xd1\x82\x00\x09\xb8\x37\x34\x6d\x75\xdc\x40\x70\xca\x84\x71\xfd\x8b\x45\xd9\x6d\x6d\x8d\x0d\x7b\x66\xa5\x5e\x14\xc6\x14\xea\xb4\x6f\xcf\x61\xa4\x4e\x84\x2d\x84\x96\xe7\x99\x52\x17\xad\x8b\x92\x50\x82\xaf\xe2\xa9\x84\xce\x2a\x3f\x95\x70\x03\x23\x55\x30\x22\x89\xd4\x38\x57\xdf\x4e\x07\x51\x5a\x0e\xf9\xaf\x2a\x4b\xe3\x73\xd3\x48\x23\xc5\x5b\x0d\x6d\x5d\xc0\x07\x0c\xb3\x5b\x92\x4a\xe9\xa1\xb9\xdf\xc4\xde\xdc\x17\x06\x86\x9c\x93\x6e\x14\x4b\x08\x42\x05\x1e\xce\x36\x9f\xec\xff\x2c\x33\x0c\xca\x90\xcc\xdf\x7f\xe3\xdd\xe9\x1d\xa4\x7d\x57\x9d\xbe\x30\xb2\x32\xe6\x9a\x3b\x42\xe1\x6f\xa7\xb2\x85\xfa\xbe\x50\x10\x04\x9b\x88\xe4\x89\x6d\xfe\xb1\x61\xef\x5a\x94\x5f\x36\x9b\xfa\x1f\xf0\x8c\xd9\x29\x6e\xda\xba\x3a\x83\xbe\xa9\xc2\x02\x95\x3c\xb7\x6f\xea\x0a\xfc\x6e\x58\xd9\x92\xdc\x64\x48\xaf\xf5\x86\x49\xd7\x27\x63\xd4\x9b\x28\xca\x6b\xd8\x8e\xe1\xaf\xd2\x24\xa6\xb8\x2d\xc8\xe6\x41\xfc\xfc\xed\x0a\x3c\x40\xa6\xb9\x13\x6c\x2f\xbb\x79\x29\x3e\x60\x48\xce\x36\x20\xe2\x20\x32\x75\x5a\x36\xb7\xc5\x07\xb8\x1d\x6d\xb4\x0c\xb2\xd4\x44\x7a\x80\x86\x75\x21\xce\x28\xe5\xe3\x87\x2a\xcb\xed\x57\x62\xb6\xcf\x9f\x20\x67\xae\x81\x6d\xfe\x64\x2c\x0f\x01\x92\x3a\x4d\x3a\xa0\x65\x1e\x4b\x65\xd5\x8d\x3f\xa0\x3e\x56\xd5\xfe\xa3\x59\x57\x07\x11\x0e\xa7\x2c\x77\x55\xde\x67\x71\xee\x19\x1e\xc2\xe1\x98\x25\x83\xb6\xd1\xf1\xbc\xc5\x4e\x6c\x3d\xf3\xa3\x33\x65\x89\x96\x4e\xe7\x0d\xb6\x47\x5e\xcb\x3b\xfb\xb1\x8a\x23\x1e\xff\xd4\xc0\x4d\xd5\xb6\x5f\x75\x8f\xc9\x5c\xe5\x38\x8f\xdd\x39\x41\xb4\xbf\xf0\xd1\xa5\xa0\x14\x01\xc6\xf7\xa7\xf7\x0d\x7c\xc0\x28\x57\x29\x05\x63\x98\x9c\xf9\xd1\x39\x46\xf7\xa2\x69\x7b\xba\x65\x22\x45\x96\x23\xb0\xee\x71\x33\x1f\xbe\xd0\x89\x3b\x24\x25\x8d\xb9\x2d\xb1\xab\xaa\x74\x9c\x88\xfe\x50\xae\xb0\x57\x4e\x8a\x06\x06\x7c\xea\x44\x2a\x22\x10\x85\xe3\x7a\xc2\x47\x7a\x66\x44\x2a\x4a\xad\x44\x50\x85\x1f\x4f\xf8\x33\x57\x89\x65\xb9\x70\xa1\x5e\x33\x2d\x4a\xfa\x81\x12\x10\x1b\xf4\x5a\x55\x7a\x7f\x9a\x7a\xc3\x52\x13\x0a\x58\x46\x9c\xad\xee\x97\x8b\xdd\x66\x3b\xdb\xbe\x6c\xfc\x45\xb4\xca\x11\xa9\x7a\x2a\x0d\xc2\x09\x46\x1a\x8f\xe3\xf3\x40\x66\x4b\x39\x01\xd6\xf6\xee\xb8\x74\xff\xa6\x07\xef\x4f\x23\x89\xee\x81\xfb\x3e\x7a\xf8\x9b\xbf\x55\xd4\x57\x93\x02\xb4\xd9\x92\xf9\x05\x45\x9d\x30\x32\x46\xef\xee\xdf\x08\x61\xbe\xf3\x79\x1c\x09\x5a\x69\x35\xe8\xa0\x5a\x1e\x3a\x8f\x00\xbe\x80\xd1\x4b\x43\x33\x9a\xff\xed\xb2\xdf\xdf\x8b\x5d\xa4\x89\x73\xac\x28\x1c\xf7\xd5\xb4\x6a\x2c\x4d\x6a\x85\x9c\x3d\x0c\xf0\xb6\x33\x27\x78\xd9\x91\xa5\x37\xb9\xa2\xbd\x56\xd1\x73\x55\xed\xa7\xcb\xd4\x68\x85\xc2\xaa\xcf\xa2\x85\x12\xb3\x30\x2e\xa1\xf5\xc5\x83\x02\x27\xd2\xa5\x7e\x67\x5a\x8f\x58\xa2\x27\x77\x68\xc0\x0a\x01\x69\x6d\x4b\xce\xed\x2f\xeb\x27\x2a\x8a\x6c\x8e\x1a\x41\xc9\x8f\xa7\xc3\x02\x44\x00\x64\xab\x88\x66\x90\x0e\x0c\xe0\xcb\x7a\x92\xd8\x54\x51\xc6\x10\x69\x6a\x9f\x74\x55\x9a\x3d\xce\xc6\xa0\x07\x49\x11\x43\x91\x41\xf4\xdf\xd9\x72\xfe\xb4\x7a\xf4\x7f\xa6\xca\x32\xd8\xbd\x42\xfb\xad\xfa\x7c\x38\xa9\xb7\x97\xb2\x2d\xf6\xdf\x44\xad\xfb\xfe\x56\x45\xc1\x02\xe4\xec\x72\xdc\x89\x5d\x09\x9f\xbb\x83\x45\xc4\xfd\x9f\x16\xb6\x62\x32\x35\xae\x6c\x3a\x7f\xc3\x8e\xb8\x1b\x28\xc1\x14\xaa\x10\xd3\xce\x2d\x95\x50\x8e\xfe\xfe\x66\x48\xc8\x3c\xd8\x86\x54\xc2\x29\x92\x9b\x7f\x17\xa5\xd0\x45\x68\x91\x51\x9c\xb0\x68\xd8\x29\xfb\xb5\xab\xef\x7f\x90\x10\x9c\xbf\xaa\x84\x7f\x9f\x44\xdd\x42\xbd\x2a\x2d\xc6\x2e\xbc\x04\x2e\x32\x0c\x1b\x30\x12\x6a\xc5\x2b\x94\xb7\xe2\xab\x94\xaf\xe2\x52\x65\x3d\x3b\xf8\x55\xe2\xce\xf1\x0d\xa4\x71\x86\x7b\xcf\x16\x73\x85\x43\xce\x42\xa2\x52\x4e\x59\xe0\x08\x1a\xcc\x56\xcf\x41\x4f\x54\x0a\x32\xb3\x5a\x35\x58\x1d\x15\x45\x48\x32\xa9\x9c\xd8\xd4\xf6\x27\xc8\xbb\xc2\xb4\xf7\x45\x09\x03\x83\xae\xf2\x24\xc9\xa5\x97\xf6\xa9\x65\xd1\x36\xbb\xa3\xe5\xa1\xdc\x55\xc7\xfe\x26\xf2\x5c\x5a\xed\xf4\xe6\xb5\x81\xb2\x47\xbc\x29\xa1\x08\x22\xf0\x1c\x0b\x58\x33\xe4\x38\x24\x4a\x26\x02\xbf\x03\x64\xb6\xb5\x74\xf2\xc3\x8d\x48\xa9\x24\xc5\x88\xcf\xcb\x9b\x3c\xe9\x7e\xc6\x75\xc2\x33\xcf\xba\xb4\x45\x3d\x99\x21\x2c\x41\xe9\x34\x41\x0f\xed\x58\xc3\x47\x68\xfd\xf3\xc7\xf2\x48\x46\x41\x51\xfd\x8f\x2f\xde\x92\x76\x46\xf6\x15\xda\x9b\xf3\x03\x34\x97\x84\xe7\x93\xf1\x9a\x5a\xb3\xd8\xc5\xd3\xb3\x52\xaf\xab\xc0\x46\x4d\x14\xa8\x94\xf4\x50\x10\x57\x1f\x98\x17\x35\xe2\x57\x2e\xb0\xb6\xca\x70\x4d\x54\x68\xaa\x84\xf6\x8d\x46\x24\x73\xe7\xd2\x11\x4d\xd1\x3b\x68\x6b\x94\x59\x38\x87\xbf\x0b\x8d\x3d\x63\x41\x79\xe6\xe4\x89\xf2\x2f\x6e\x56\x13\xc2\x88\xe5\x85\xd3\xcb\xd2\x8a\xe2\xf8\xd3\x10\x4e\x5c\xa3\x61\xd1\x36\xcf\x63\x02\x6a\x37\x84\x49\x81\xd2\x99\x3e\x4b\xdc\xf9\x82\x76\x5f\x9d\xd5\xb5\x38\x4f\xa3\x7d\xcd\x74\x2a\x6c\x9c\xf9\x72\x7c\xad\x85\x1e\x41\xa1\x35\xd3\x79\x44\x47\x5a\xcb\x36\x4a\xae\x57\x8b\xf1\xb4\xe8\xd8\xe5\x83\xad\x21\xbb\x13\xcd\xbc\x0a\x8b\x5c\xc7\x39\x88\x2c\xbc\xd5\xaf\x32\x8a\x6e\x70\x42\x34\xc2\xaf\x37\xff\xfa\x63\xf3\xc3\xb3\xdc\x13\x9d\x24\x39\x1b\x21\x8b\x9e\xab\xea\x0d\x43\x9c\xf1\x8d\x24\x59\xa2\x85\x13\x1c\x80\xdf\x26\xa7\x36\x14\x7b\xd9\x0f\x45\x79\x03\xed\x26\x68\xc4\x13\xcd\xa3\x88\x06\x09\xfb\x53\xdd\xc0\x6a\x71\xdd\xe2\x68\x4e\x6c\xfb\x0e\xf6\xba\x62\xeb\xf0\x72\x3d\x4f\x29\xf9\x63\x1e\xce\x95\xe5\x46\x0c\x36\xe1\x61\xd3\xae\xe6\x99\x4c\xe2\x5e\xc1\x77\x5e\x95\x0d\x5c\x51\x6f\x1c\x3f\x13\xd7\xcc\xf5\x48\x3a\x89\x7b\x4c\xc9\xfb\xeb\xa5\x2e\xb5\x8a\x69\xdb\x67\x71\x5e\xf4\xd8\x35\x9d\x11\x8b\xa4\x80\x9f\x45\x7b\x73\x3a\x0f\x01\x0f\xfd\xe9\xf3\x98\x62\x9f\xf0\xce\x16\x41\x30\xbc\x69\x60\x0b\xf5\xa1\xb9\x0e\x7a\xd0\x79\xaa\x30\x47\x74\x07\xd8\xcb\x77\xee\x3e\xa8\x2f\xe6\x4b\x90\x98\xe5\x1e\xfd\x34\x3e\x8b\x88\x39\xd6\x29\xfe\x53\x15\xe5\xa2\x16\x9f\x93\xdb\x92\x24\xc5\x64\x6c\xc8\x47\x07\xf4\xe0\x64\x9c\x54\xc8\x70\x72\x3f\x5b\xdf\x2d\x77\xcf\x2f\xeb\xf9\xb7\xd9\xc6\x03\xf6\xb5\x34\x8a\x99\xfe\xf3\xb6\x7a\x5a\x83\xda\xfa\x84\x90\x44\x2b\x1e\x63\x67\xd0\x7d\xf5\xea\xdb\xe9\xbe\x82\x6e\xfa\x5f\xe8\x74\x90\x34\x1e\x98\x68\xad\x33\x8d\x6f\x66\x01\x3f\x67\xfb\xe3\x9b\x08\x7f\x37\x39\x12\x77\xec\x42\x64\x74\x18\x42\xab\x27\x6f\xdf\xc4\x1c\xf1\x87\x0b\xd1\x0e\xd2\xa0\xda\x24\x2a\xf6\x68\x96\xd2\x39\xd7\xb6\x83\xf3\x0b\xce\x37\x6d\x84\x32\x7d\xad\xeb\xe6\x54\xec\x75\x51\xbe\xa2\xb4\x0e\xd4\x1f\x93\x54\x7f\xf6\xdf\x24\xfa\x9f\xe9\x7f\xf9\x13\x69\x01\xce\x51\xbd\x10\x3e\x22\x10\x11\x86\x6e\x6c\x2d\x4a\xfd\x58\xf5\x91\x00\x44\x9c\x62\x64\xb9\x83\x43\xd1\x76\x8e\x8a\x12\x47\x9f\xf7\x1a\xab\x01\x12\x88\x4c\x6a\x99\xa7\x3f\xcf\x47\x98\x57\x7a\x92\x43\x06\x12\xa5\xa9\xed\x3b\xb0\x09\x0d\x4b\x7c\x21\x90\x51\x75\x63\xf7\xb9\x5f\x7e\x53\x40\x0c\x78\x1d\xa4\xdb\x1a\x60\x51\x94\xd5\xa8\xf0\x0a\x94\xc4\x58\x60\x29\x1a\x04\xe4\x5d\x5f\x7c\x40\x13\x8d\xaf\xb2\x3c\x1d\x5c\x8b\xff\x80\xec\xdf\x8d\x61\x89\x25\x39\xf3\xba\x75\x63\x20\xfd\xc0\xaf\x07\xc6\x23\xa4\x21\xf3\x5c\x25\x25\x72\x2e\x9c\xc4\xbe\x77\xe9\x80\xa9\x3c\xf6\x69\xa0\xe2\x2b\xe6\x22\x60\x26\x12\x6e\xd4\x75\x86\xfb\x61\xa2\x7c\x9a\x32\x87\x98\x46\xf8\xd1\x3a\x8c\xc3\x80\xbb\x06\xe2\x9c\xc5\x2e\x58\x9d\x36\xb0\xfb\x11\x82\x62\x76\x14\x7e\x1e\x8b\x1a\x42\xc7\x52\x7f\x6f\xb1\xd1\x74\x80\x96\x59\x36\xaa\xae\x3e\xaf\x2f\x7e\x48\x58\x8e\xe6\xdc\x83\x36\x7e\xd4\x55\xf9\xea\x66\x30\x20\xf7\xfc\xbd\x25\x26\x31\x36\x42\xdd\xf7\x24\x42\xc0\xa3\x04\x8b\xf5\x83\xdd\xd2\x21\x2d\x27\x50\x01\xe0\xc0\xb1\x5a\xb6\x08\x89\x99\xbd\x50\xef\x76\xb3\xbe\x7e\x7b\x29\xb7\x34\xfc\x1a\xca\xf3\xcd\xd9\x17\x13\x7f\x73\x1c\x15\xf6\x9f\x30\x94\x53\xe9\xc9\x20\x6c\xae\xd4\x49\x38\xda\xf6\xdf\xf1\x24\x66\x99\xc9\xfd\x73\xef\x22\x6b\x02\xb1\xb2\xb5\x53\x48\xc9\x75\x1a\xee\xfa\x90\x01\x60\xc2\x6d\xfb\xf4\xfb\x76\xe8\x82\x42\x4e\x40\xb8\x7d\xad\xfb\x52\xa7\x1d\xb3\x6e\x94\xe0\x80\xfe\xd4\x30\xbb\xda\xad\x18\x7f\x5c\x52\xc0\x10\xfe\xe5\x71\xb5\xb5\x88\x97\x07\xdb\x55\xfe\xdb\x85\xc2\x31\x01\xc9\x32\xc6\x43\xc9\xf1\x3f\xa0\x3c\x64\x6a\x32\x2c\x25\xca\x7d\x7f\x1b\x27\x4a\x39\x28\x9c\x80\x14\x49\xe2\x3c\x8f\x07\x68\xc5\x50\xd5\xc6\x8d\x50\xca\xa6\x57\x8b\xe6\xbe\x7a\x9d\x24\x75\x40\xd3\x28\xb7\xdc\x9e\x87\x42\xf5\x11\x19\x68\x96\x32\x4f\x16\x33\x64\x25\xbb\xba\xcd\x81\xce\x22\x84\xea\x6d\x96\x4f\xa3\x59\xd5\xc2\xb2\x46\x58\xd6\xa0\x59\xd3\x40\xd3\x0c\x5a\xee\x40\x1b\xb0\x1e\xee\xae\xb1\x3c\xfe\x4f\x66\xd9\xbe\x3d\xd7\x95\x29\xda\x09\x85\xc6\x64\x3d\x19\xca\xb1\xbe\xd9\x1c\x85\x82\x99\x41\x93\xde\x7d\x62\xe1\x01\x0c\xe7\xb6\x09\x1d\xb7\x1a\xf0\x42\x7c\x04\x8c\x23\x22\x6e\xa0\x5d\xd6\x8a\x46\xeb\x41\xfc\x32\xb9\x86\x4a\x1d\xb3\x54\x53\xed\x3f\xc0\x2d\xda\x2b\x40\xa5\x30\x3e\x8b\x86\xab\x03\xeb\x6e\x5f\xd7\xdb\x4c\x14\x69\xd1\xbd\xba\xa7\x87\xd5\xf7\xd5\x08\xd8\x69\x08\x4d\xb1\xe8\xba\x43\xc3\xb2\x6b\xab\xf7\xfe\x10\x8b\xd1\x6b\x7a\xfa\xaf\x35\x88\x3d\xa0\xfb\xd6\x8c\x7f\x9c\x50\xe6\x00\x10\x63\x12\x90\xf1\xf3\x19\x92\x5a\xf6\xd1\xa1\xa8\xfb\x74\x48\x96\x21\xdb\x92\xdb\xb2\x6b\x98\x84\x7a\x7e\x98\x4a\xb0\xa4\xfc\x21\x4e\xfb\x76\xd4\x0b\x6e\x88\xb6\xe9\xd7\x6e\xfb\xd8\x8b\x0b\x08\x9e\x1b\x45\x55\x66\xa5\x60\x85\xb6\x0c\x5f\xdb\xea\x11\x3e\x47\x5a\xb2\xd7\x43\x16\x43\x35\xa0\xd1\x6a\x8e\x5f\xf6\x4d\x1b\x16\xc5\x08\x7c\xe8\xb6\xd3\xce\xc8\xcf\xf4\x15\xee\x5e\x3f\x36\xd5\x66\x2c\xe5\xae\xaa\x2f\xcb\x3d\x86\xa9\x28\x72\x1b\x3c\x66\x7c\x1f\xc4\xcf\x67\xa8\x31\x6d\xf2\xc5\xe9\x15\xa7\x10\xba\xab\x7e\x0b\x7f\xb5\xe2\x0c\x8e\x38\xfc\xa7\xed\xc1\x1e\x40\xda\xfe\x12\xc5\x3b\x7a\x1d\x31\xb3\x42\x3c\xaf\x27\x29\xa1\x1e\x7c\x70\x26\xa1\x96\x04\xbc\x28\x8b\x76\xd9\xbe\x8d\x7b\x82\xc7\x93\x96\xc4\x22\x75\x80\xb1\x47\xf8\xd9\x76\xae\x74\x8d\x6d\xd3\x17\x15\x6d\xc3\x49\xc6\x1d\xd8\xda\x75\x3b\x2d\xe0\x58\x83\x43\xf5\x4d\x6f\xf5\x97\x35\x48\xc3\xb9\x56\x7d\xf9\xa8\x9b\x49\x8b\x46\xba\xbe\x84\xb9\x8c\x31\x31\x77\x38\x07\x48\xe0\x30\x41\x66\xd2\x88\x60\x49\x02\x05\x99\x2d\x4c\xc3\xd5\x81\x2e\x6e\x63\x7c\xe2\x34\x72\x2c\x6c\xd0\xaa\x37\x97\xa8\xbd\x90\x63\x0c\x5f\x72\x4a\x09\x52\x27\x7c\xbb\xbb\x1d\xb5\x79\x98\x94\x6b\x9c\x19\x1f\x90\x20\x70\x6f\x5b\x0d\x71\x94\x26\xa3\xc4\xba\x81\x36\x69\x3f\x17\xcd\x9b\x14\x7d\xfa\x76\x32\x3f\x99\xd2\x08\x01\xf4\x46\x66\xb9\xfd\xb6\xad\x26\x59\x3f\x93\x41\x4e\x7c\xfc\xbb\x85\xa6\x45\x90\xef\x19\xe9\xad\xbf\x5a\x98\xb9\x12\xe8\x25\x5b\xf4\xdf\x5d\x5d\x9d\x8e\xd7\x89\x57\xa6\xa5\xda\xbf\xfa\xf7\x12\x5f\x6e\x72\x88\xbc\x47\x7e\x41\x79\xe0\x86\x08\x00\x4c\x04\x94\xd5\x76\x02\x5c\x70\x03\xa4\x60\xa9\x1e\x70\x36\xdd\x78\xf2\xa3\xe9\x38\x6d\x50\xc3\xed\x55\x1c\x60\xd5\xcc\xfd\x57\x3d\xf1\x68\x8c\x62\x29\x22\xc2\x1f\xaa\xb2\x7d\x3b\xe2\x06\x04\xa1\x80\x63\x14\x4f\x90\xd0\x1c\x9b\x61\x6f\x8a\xba\x7d\x9b\xfe\x3c\x8d\x30\xe8\x5e\x88\xf2\xfd\xb4\xd3\x70\xf0\x9c\x76\x46\xa7\xc4\x53\x51\xe0\xfa\x9b\xb9\x8e\x77\xbd\xad\xb0\xaa\x56\x55\x93\xc0\xdc\xe8\xcc\x10\x19\xf8\x46\xde\xa1\x6c\xba\x17\x8c\x42\xf0\xe1\xa4\x82\x23\x54\x11\x25\x88\x6c\x39\x6d\x82\xac\xfa\xe2\x2d\x6b\x63\xfb\x74\x2c\x8a\x7d\x01\xa1\x8e\x6e\x20\x21\xe8\x00\xd5\x55\x35\x50\xb9\xf1\x07\x15\x13\x96\x6f\x15\x44\xbd\x39\x56\x9d\x2d\xe8\xbe\xb5\x7f\x56\xd2\xc7\x13\x97\x6d\x5c\xd3\x8f\xc4\xa4\x04\x3f\x29\x5b\x7d\x1f\x7b\x14\x7e\x48\x46\x70\x6f\x0e\x59\xa5\xaa\x1c\xb5\x7c\xd2\x28\xca\x53\x5c\x17\xb3\xf2\x15\xf6\xbd\xe8\x0a\x76\x00\xb8\x21\x84\x50\x8c\x22\xc0\xe5\xf4\x17\x50\x9e\x97\x3f\xa1\x56\x45\x03\x4f\xc7\x81\xba\x39\x8d\x48\x42\xa2\x20\x50\xe2\x48\xad\x2e\xab\x92\x7e\x30\x8f\xb2\x5e\x0f\x68\x81\xb0\x01\xab\xe6\xf1\x26\x7c\x43\x51\xe6\xc7\xa6\x20\x2d\x49\xbb\x69\x63\xfe\xdb\xe4\x44\xda\xa6\xfd\xdc\xa6\x8a\x09\xef\xba\x18\xa6\x0d\x69\x44\x63\x8d\x28\x44\x53\xd5\x0a\x02\x4a\x6a\x48\xcc\x4f\x23\xca\x29\x1a\x3f\x1f\xf6\xdf\x8b\xb2\xcf\x22\x87\x90\x65\xe4\x74\xd0\x88\xa6\x8a\xf4\xe8\xa3\xf9\x3f\xb7\x20\x0e\x63\x6e\x6c\x37\x90\xc5\x5c\x71\xcf\x8b\x5f\x1d\x5d\x49\xb1\x77\x3d\x69\xc4\x4c\x84\x1c\x33\x0f\xb3\xdf\x77\xab\xc7\xef\xcb\xcd\xf6\x61\xf9\xb8\xdd\xec\x6e\x96\xb7\x4f\xeb\xe5\xee\xe1\xe5\x7e\xbb\xda\xac\xee\x5c\x2f\x84\xbf\xeb\x38\xd2\xe0\x02\x41\x04\xc4\xdf\x54\xa2\xd6\x0f\x00\x2d\x42\xff\xc2\x20\xbb\xab\xdf\x14\x6d\xa3\x6a\x80\x72\x44\xe3\x9b\x5d\xf9\xdf\xd1\xec\xc5\x4c\x62\x48\xba\x58\x7d\x5f\x2d\x7c\xf3\x05\x8d\x92\x3c\xb3\x4a\xb0\x41\xa7\xfe\x9a\x8d\xa5\x11\xe7\xe0\x89\xfa\x5c\xc7\xdb\x10\x0e\x43\x23\x9e\x65\x91\x1c\x6a\xde\x56\xb6\x29\x4a\x57\x1e\xb4\x49\xa3\x34\x56\x8c\x8c\xbc\xfb\x07\xb4\xbe\x43\xc7\x99\x46\x69\x22\xb0\xa2\xf9\xea\x19\x0f\x26\xdd\xbe\x34\x4a\x55\xe6\x33\x8b\x9b\x93\xec\xce\x83\xe5\x96\x9b\xf3\x4a\x4f\x96\x55\xaa\xa9\x8f\x45\x3f\x50\x16\xdb\xdf\x4a\x96\x53\xac\x94\x3f\xae\x6f\xbc\xf4\xa9\x3f\x24\x72\x85\x8d\x63\x37\xab\xed\xe6\xef\x31\x9f\xd2\x48\x46\xc6\xb3\xa9\x3e\x9c\x67\x65\xfb\x56\x78\xf8\x04\x8d\x24\x4d\xf1\xa9\x77\xc8\x0e\x54\x40\xd9\x3d\xfc\x47\xa1\xa1\x7e\xe9\x13\x85\x7e\x6c\xa2\x90\xe6\x6b\x5e\x9f\x8f\x6d\x15\xce\x90\x26\xd8\xa9\x76\xac\xea\xd6\x54\xfb\xa2\xf2\x11\x94\x3b\xae\x23\x8a\xfd\xe7\x88\x9d\x1e\xec\xf5\x34\xd2\x92\x63\x4d\xa4\x3e\xc9\x61\xd3\x3f\x8d\x40\x66\xe0\xfa\x1d\x16\x45\x23\x4f\x75\x83\xf9\x48\x2f\xb3\x3b\x9e\x45\xd0\x92\x0d\x99\x49\x1c\x0d\xcc\x88\x6c\xe7\xc2\x97\xa7\x91\x31\x80\x9d\xef\x18\x7e\x57\xd5\x8b\x9e\x92\x4b\x52\x42\xb4\xa4\x4e\x54\xab\x3e\x3b\xae\x3e\x87\xa7\xa1\x84\xa6\x96\x2d\xea\xcd\x96\xa5\x9a\xc9\x6f\x19\x13\x9e\x6f\xfa\x79\x2f\x4a\x68\x1f\xa7\xd9\x02\x4a\x58\x12\x5b\x2a\xe8\x41\x1f\xab\xdd\x3d\xac\x26\xee\xf5\x3c\x3a\x25\x49\x24\x31\xf1\xf7\x2f\x51\x3d\x9f\xc6\xb4\x9d\x93\x81\x12\xb0\x6c\x3e\xd4\x81\x98\xdc\x43\x62\x6c\xe3\xbd\xf5\xde\x6e\x3c\x80\x66\x7a\xe5\x8b\x9c\x0a\xf1\x27\x40\x16\xd1\x4b\x35\x62\x97\x71\xba\x52\x59\xa2\x84\x4b\x8d\x3d\x0f\xf6\x69\xd7\x8e\xa4\xf1\xcb\xaa\xdd\xaf\xc2\x09\x4a\x52\x4a\x73\xe9\x1a\x87\xfa\xe2\x22\x25\x29\xa3\x59\xff\x60\x0f\xdf\x1f\x2f\xd8\x43\x29\x49\xf3\x08\x27\xf2\xe6\xf1\xc6\x72\x67\xed\x9e\xd7\xab\xf9\x72\xf7\xf8\xf2\xe0\x4f\x93\x51\xee\x28\x2c\x3c\x73\xc2\x57\xb9\x25\x4a\x32\x48\x94\x83\x9e\xde\x9d\x44\xad\x0b\x51\x7e\x87\x2f\xfa\x05\x28\xc9\x8c\x25\xfe\x2f\x50\x3f\xba\x99\x79\x63\x45\xf2\x28\xf2\x08\xd6\xe7\xaa\x69\xdb\xd7\xab\xf0\x01\x8a\x40\xbb\xcc\xd7\x7e\xf8\x64\xcf\x22\x82\x5b\xc5\xb0\xcd\x76\xb6\x5d\xee\x1e\x9f\xb6\xbb\xdb\xd5\xe3\x6a\xf3\x6d\xb9\xf0\xd7\x11\x92\xa0\xcf\x29\xab\xf2\xd4\xf4\x01\x2b\x25\x92\x32\x4f\x67\xd6\x1b\x5d\x6f\x01\x89\xec\x3c\x2f\x4f\x9e\xf9\x01\x75\x63\x79\x25\x07\xdb\x58\x58\x1b\x52\x67\x3a\xa8\x5d\x59\x19\x84\x35\xd2\xdc\x16\xe5\xeb\x8f\xa2\xd4\xd5\xa7\xbf\xa4\x62\x14\xb5\x1a\x74\xd1\xc0\x41\x8a\xfa\x7d\xb8\x7e\xc8\x74\xea\x34\xcb\x32\xe5\x1c\x2e\xa8\x57\xcd\x4c\x1f\x8a\x70\xf7\x1a\x2c\xcc\x6b\xf6\xb2\xb9\x19\x5a\x15\xa2\xc1\x4e\xb8\x4d\xcc\x76\x0e\x1a\xb4\xa8\xb1\x61\x71\x5c\xa3\x87\xd4\xc6\xb6\x06\x5a\x05\xee\xba\x33\x3e\xa8\x35\x59\x95\x28\xf8\x3a\x68\x15\xa5\x04\x72\x81\x1a\xba\x37\xb3\x7f\x8f\xae\x67\x52\x88\x93\xc0\xe9\x50\x54\x4e\xeb\x67\xfc\x28\x46\xe6\x9e\x48\xb5\x57\xd1\x74\x84\xec\x94\x46\x89\xdd\x16\x1d\x69\x50\x83\xba\x8c\xbe\xab\xde\x8d\x21\x51\x8c\x4c\xad\x45\xd9\x82\x53\x2b\x0b\x87\xf2\x8c\xfb\x84\xd5\x2f\x92\x33\x94\x12\x95\x45\x56\x08\xf6\x78\xdc\x9f\xf1\x3e\x59\x38\x89\x56\x48\x4a\xf0\x4d\xa8\xf7\xce\xb3\x0b\xec\x88\x94\x12\x48\x51\xfa\xfe\xbe\xba\x54\x65\x98\x5c\x81\xb2\x04\xfc\xad\x88\x57\xb8\x34\xcc\x97\x30\x23\x4a\x69\xa6\xb0\x80\x39\xdf\xce\x16\xf0\x51\xec\x47\xb0\x59\x4a\x63\x6e\x6b\x35\x0d\xb4\x8f\x85\x7a\x47\x0b\x3b\xda\xad\x69\x42\x2c\xf5\x79\xe0\xaf\xb5\xea\xb6\x03\x0a\x47\x4a\x93\x9c\x62\xbc\xb1\x43\x46\xf7\xc9\xef\x45\x86\x64\xb9\x77\x57\xc5\x53\x28\x4d\xa4\x05\xac\x37\xd0\xde\x76\x7e\x9f\xeb\x10\x7d\x32\xb6\xab\x63\xf0\x28\x5c\x6a\xdd\xb7\x2b\xe8\x93\x6a\x37\x98\xea\xbc\x74\x0b\x28\xd7\xb1\xa5\xda\x1a\x48\xe0\xda\x15\x3e\xfa\xfe\x69\x0a\x9a\xf7\xa9\x9e\x67\x24\xc8\xf9\x02\x9d\x7b\xfd\x9d\xa4\x46\x63\x3a\x1b\x69\xaa\x57\x2d\x1c\x30\x05\xed\xe7\x45\x44\x02\x15\x64\x8e\x58\x1e\xbd\x39\xe9\x57\x9f\x23\xa2\x54\x90\x08\x51\x3a\xf3\xa7\xf5\xb2\xaf\xdc\x50\x2a\xa8\x66\x24\x6c\xdc\x6d\xb7\x61\xce\x4a\x3d\x60\x05\xe7\xa3\xcd\x83\x0a\x95\x39\x00\xfe\xa9\x6c\x7f\x14\xcd\x1b\x74\x76\x70\xfc\x98\x02\x52\x2f\x3d\xb1\xc0\x40\x04\xf4\xf8\x05\x0a\x93\x79\x68\xc5\x43\x51\x22\xc0\xe8\x92\x3a\xd1\x8d\x95\x91\x44\x0f\x1c\x23\xeb\xeb\xf8\xcd\xeb\x73\x25\xa9\xa5\x21\x41\xd7\x3d\x64\xc3\x27\x65\xb3\x7f\x4c\x2e\xc6\x39\xae\x0e\x5d\xdd\x14\xaf\x8b\xba\x57\x9f\xfb\x8b\x6b\xa9\x34\x75\xa4\xd6\x81\x7e\xc0\x76\xf0\xd3\x3f\xfc\x33\x6b\xae\x30\x7f\xeb\xd4\x73\xab\x72\x59\xd7\xd5\x88\x72\x9b\x52\x9d\x51\x74\xcc\x6e\x4e\x5a\xfb\x0a\x1d\xa5\x5a\x0b\xa4\x52\x54\x6f\x55\xd5\xc0\x68\xcb\xee\x47\x48\x37\xe1\x77\x50\xa2\xe2\x52\xe7\x9d\xde\x9c\x37\xb0\x9f\xd2\x64\x51\x0a\x89\xe5\x68\x5f\x95\xcd\xa9\xee\xd1\x71\x94\x42\x96\x29\x8f\x4c\xea\xa2\x82\xdf\xab\x7a\x73\x52\x3d\x92\x9f\x52\x93\xa7\xcc\xaa\x8e\xd5\x08\xd0\x18\xb7\x14\x4f\xdf\xcb\xd7\xaa\xcc\x94\x1a\x60\xb9\xf1\xbc\x1a\xa2\xbc\xc8\xa9\x53\x16\x81\xd4\x56\x23\xc7\xd4\x55\xd3\xde\x22\x9d\xf2\x68\x1d\x31\x92\xa6\x98\xa1\x3e\x14\x65\x71\x27\x0e\xe0\xd1\x9a\x94\x91\x3c\x91\x4e\x43\x75\x76\xb3\xba\x10\x28\xe9\x03\x62\xca\xe2\x88\x6b\xea\x77\x47\x55\xd5\xfa\x2b\x32\x27\x37\x3e\x01\x26\xdc\x5e\xeb\x56\x2c\xb2\x1d\x56\x35\x1a\x86\x91\x35\x62\x09\x80\x61\xa3\x4d\xe9\xfa\x6e\xca\x38\x55\xd8\x56\x38\x7f\x5a\x3d\xee\x36\x2f\xcf\xcf\xf7\x7f\xec\xb6\x4f\xdb\xd9\x7d\x18\x90\xe4\xb6\xf9\xf9\x22\x59\xf3\x6b\x6f\x8b\xf1\x34\x92\x74\x92\xea\x70\x1c\xbe\xfe\xdc\x29\x73\x04\xbf\xf6\x16\x77\xd8\x8a\xbc\xd3\xc5\xc7\xdb\x80\x96\x8a\xb2\x34\xe1\xb1\x55\xf7\x5d\x54\x47\x58\x8b\x2e\xe4\xb0\xf0\x4d\xd5\x36\xbd\xbc\x02\x65\xb9\x21\x88\xa8\x6a\xeb\xe2\xf5\x15\xea\x4d\x65\xda\x50\x33\xa4\x4c\x8a\xc4\x53\x4e\xec\x6f\x84\x7a\xbf\x13\xcd\x28\xf4\x63\x9a\x5a\x95\xf1\x87\xa2\x14\xfa\x42\x03\x2d\x0c\x92\x5e\xfe\x61\x0d\xff\x7b\x2a\x6a\x6c\x4d\xb9\x92\x40\xa6\x4c\x27\x3c\xb1\x4d\xd2\x18\x23\x62\xea\x77\x62\x65\x98\x4e\xc0\xd5\xce\x3e\xaa\xfd\x07\xd4\x37\x85\x2a\xc2\xfd\xe4\x1c\x4d\xde\xb1\x86\xc5\x69\xb4\x5d\x33\x0d\x4a\x88\xd0\x1b\xe5\xcd\xdc\x24\x41\x46\x19\xc4\xb6\x55\xfe\xe6\x66\x98\xba\xa4\x0c\x8c\x49\x42\x2b\x71\xe3\x5f\x6c\x1d\x3c\x85\x38\x8a\xc0\x92\x4c\xa1\x49\x99\x9e\x37\x8e\x68\x86\x94\xc2\xf7\xc5\xff\x9e\x3a\x1b\x77\xa8\x54\x2d\xd4\xb9\x47\xaa\xdd\x0a\xd5\x56\x13\x48\x1c\x8d\x23\x65\xed\xf3\xfc\x69\xf9\xf8\xfb\xf0\x86\x62\x22\x0d\xf2\x33\x5e\x89\x3b\xe2\x98\x51\x44\x59\xbd\x9d\x0e\xa2\x2c\xda\xf3\x6d\x9f\x26\x89\x63\x69\xd9\x97\x4e\x65\x68\x07\xf5\xb8\xf6\xc9\xb5\x93\xce\x88\xf4\x5a\x0c\xf6\xab\x9e\x8e\x11\xb6\x3e\xb0\x40\x71\x97\xfd\xd9\xf5\x4d\x7c\x21\xf0\x42\xe3\x04\x64\xe4\xc0\xf8\x5d\x28\xec\x68\xb2\xaf\x8f\xe5\x2c\x42\x5f\xb8\x2d\xa0\xa6\xcb\xfe\x09\x78\x9c\x60\x8f\x0b\x0a\xd1\xee\x68\x17\xc4\x87\x43\x89\xc1\x0c\x16\x9a\xd6\x22\x94\x1b\xff\xa2\xdf\x67\x7a\xdd\x9c\x25\xcc\xef\xdc\xee\x81\x90\x4f\xb9\x15\x5e\xd1\x9b\xc6\xa9\x62\x59\x4f\x21\x33\x7f\x43\x3e\xcb\xd7\xcb\x30\x28\xf6\x5c\xff\x58\xba\xba\xad\xea\x6b\x8a\x9d\x7e\xa8\xe1\x58\x87\x0e\xa2\x0a\x97\x9c\xb6\x34\xce\xb8\x8e\xe9\x90\x2b\x7a\xf4\x45\xc6\x99\x32\x88\xdc\xdc\xe9\xca\xa6\xe3\x86\xdd\x8e\x34\xce\x34\x97\x21\xff\x2a\xd4\x1e\x42\x95\x74\x72\x15\xa3\x91\xf4\x71\x73\x3f\xf7\x3f\xcd\x09\x63\xb6\xeb\x49\xbd\x07\x54\x83\x3f\x46\x6d\xb3\xec\xb1\x86\x95\xaa\x06\xf0\x6f\x1a\xe7\x3c\x56\x2c\x48\x93\xab\xaa\xbe\x5a\x4c\xa6\x71\x2e\x12\x44\x44\xbe\x94\x47\x71\x6a\x9c\xfb\xe0\x8e\x89\x4c\xe2\x39\x1e\xce\xc8\xf8\x63\xb3\xe4\xf0\x19\x0e\x4b\xab\x85\xb4\xb3\x8c\x45\xc8\x3b\x6d\x9b\xe0\x26\xef\x42\x68\x85\xdf\x68\xe8\xf5\xf4\xdf\xf1\xdc\xf5\x28\xea\xc9\x34\x08\x48\x10\x2d\x5b\xaf\x16\x3b\x7f\x35\x29\x2c\x44\xe2\x20\x7e\xae\x0e\x56\x43\xd4\x1f\x91\x09\xae\x09\x0b\x94\x2d\xca\xd7\xf1\xdc\x4b\x69\xc5\x96\x1b\x68\xe7\x37\x62\xec\x41\x5d\x2d\xff\xd0\x58\x6a\x0b\x75\x1a\xe5\x18\x86\xab\x76\x1a\xbd\xc5\x8a\x69\xdb\xb1\x73\x10\xaf\xf0\x72\xdc\x57\x42\xfb\x87\x9b\x4c\x86\x4a\xac\x3e\xed\xcb\x66\x51\xed\xf7\xa2\x0e\x8f\xa1\x54\x24\xd0\xd4\x81\x38\xd8\x5c\xc9\xac\x1d\x75\x7c\xbb\x71\x3a\xb6\xa8\xdb\x97\xcd\x4d\xcf\x29\x47\x63\xad\xb9\xc8\x87\xd4\x27\x88\x76\xbb\x39\xe3\x6b\x71\x1a\x68\x24\x9c\x03\xac\xe2\x25\x52\xae\x1a\xa1\x20\xa8\x96\xec\x2c\x3e\xce\xa6\xa8\x7d\xe3\x58\xf7\x03\xdb\x19\xb9\x73\xcc\x98\xbf\x84\xeb\xd0\x18\x98\x64\x81\x13\x11\x44\x5d\x42\xff\x9c\xa0\x34\xde\xe8\x66\x0f\x10\xbe\x6b\x13\x11\x14\x32\xd0\xd5\xa6\xf5\x24\x8c\x34\x89\x28\xe1\xb9\xdb\x99\xe7\xdd\x6c\xb5\x50\x5f\xaa\x24\x84\xc1\xc6\xc3\xb7\xbb\xa8\x69\x51\xbc\x42\xd3\x8e\xbc\xc7\x24\x92\x46\xf4\x39\xef\x41\x25\xae\xc7\x12\x8c\x57\x42\x42\x22\xa2\x93\x41\xda\x00\x19\x22\xfc\xed\x11\x6a\xb7\xbd\xe6\xad\x30\xed\x6e\x0f\xe6\x1a\x0d\x0c\x4d\x88\x00\x0c\x13\x0b\x55\x3d\x77\x5f\x2f\xeb\x8d\x6a\x42\xf3\xc4\x8c\xa8\x4b\x61\x6e\x19\xbe\x0b\xb9\x87\x66\xd2\xfd\x42\x13\xaa\x08\x72\xbc\x56\x3d\x8d\xc1\xf0\x64\x9a\x27\x24\x44\x6e\xf0\x8a\xd9\xc9\x79\xb5\xef\xdb\x23\x7d\x5a\x27\x61\x24\xf5\x08\x4a\x2b\xb8\x37\x9e\x4b\xc6\x38\xf2\x3e\x60\x96\x70\xfe\x26\xf6\x7b\x28\x5f\x27\x81\x68\x12\x0b\x8d\x5b\xe1\xf3\x7a\xf5\x7d\xb6\x75\x5a\x03\xcf\x4f\x4f\xde\x23\x4b\x62\x65\x32\xe7\x62\x76\xbe\xe7\xb7\xaa\xb9\x1e\xc1\x74\x5e\x93\xd7\x99\xf6\x9c\xb4\x7e\xb9\x24\x3c\xd3\x58\xa7\x38\x14\xe5\x4e\x9e\xce\x3b\x39\x48\x53\x24\x29\x51\x9e\x8d\x65\x5b\x69\x71\xc6\x77\xd4\x0b\xe8\xd1\x24\xcd\x12\x64\x20\x3d\xda\xf8\x14\x55\xcf\x6b\xbd\xd2\x6b\x51\xbe\x86\x41\x19\x91\xb8\xe3\xcd\x4f\x52\x88\x3f\x07\xb1\x5f\x92\xf1\x0c\x49\x6a\x34\x7c\x58\xe6\x74\x9b\xd8\xbb\x70\x30\xc7\xb3\x97\xe9\x04\x7b\x00\x1a\xf1\x61\x79\x55\xfc\xe9\xf2\xcc\x22\xf1\x9c\x8c\x8d\xd7\x16\x19\x55\x6d\x92\x3c\xcf\x91\xaf\xfb\xd4\x40\xb3\x7d\x83\x83\xff\xb1\xe0\x56\x5a\xc3\x14\x3f\xe7\x38\x07\x43\x97\xdd\x11\x4c\xd3\x44\x68\x61\xe8\x00\x93\x3f\x2d\x13\xd3\x44\x72\x8e\x59\xdc\xfb\xd3\xcf\x80\x79\xa6\x89\xcc\x00\x9b\x00\x76\x35\x68\x80\xc3\xcd\xb9\xf3\x80\x31\x93\x74\x21\xb7\x74\x3d\x88\x19\x04\x0c\x89\x54\x2c\x95\x3d\x8d\x6e\x20\xfb\x6d\x10\x23\x43\x28\xd6\x37\xc3\x1b\x96\xa0\xb0\x4c\xd5\xbc\x55\x9f\x5d\x4c\x68\x19\x6d\xc6\x2b\x44\x49\x49\xd9\x80\x85\xe3\x3e\x00\xa5\x1b\x98\xae\x26\xa5\x62\x24\x27\x90\xa2\x81\x85\xdb\x8e\xfd\xb5\x94\x51\x31\x1f\x64\x56\xff\x0b\xea\xea\xdf\x27\x51\xb6\x53\xb5\x5e\x9a\x18\xa5\xac\x90\x12\x88\x3d\xd4\x3b\xe5\x29\xa2\x69\x62\x20\x47\xa6\x3e\xe7\x84\x7c\x49\x28\xf2\xcb\x88\x98\x47\x26\xc1\xd0\x6c\xb9\xfd\xb6\x7b\xd9\xf8\x0c\x26\x27\x54\x71\xd7\x2b\x53\x57\xe5\xf6\xb3\x1a\xa8\xce\xfb\x21\xb1\x5d\x46\x37\x8f\xdb\xdd\xfc\xe9\xf1\xfb\x72\xbd\x0d\xe5\x25\x4e\x94\x55\x7d\xc3\x0c\x28\x72\x67\xf9\x23\x94\x33\x95\x0c\x41\x25\xcb\xf6\x6d\x5b\xa1\x0f\xa5\x06\x0a\x27\x6e\x34\x8b\x6d\x54\x84\xdf\x5b\xe4\xcf\x11\x27\x36\xfe\x46\xa0\x9b\xb1\x3c\x8a\x08\x95\xd9\x95\x15\x42\x24\x50\xa7\xb4\x15\xef\xfe\xe3\xe2\x1c\x08\xe6\xd2\xef\x0e\xe1\x46\xd2\x18\x72\xe6\x8d\x0f\x1c\x3d\xed\xd8\xa8\x7f\xeb\xfa\x9c\xa5\x5c\x63\x87\xd8\x7a\xf6\x78\xb7\x5c\x3e\x2e\x76\x59\x38\x67\xce\x71\xc9\x21\xdc\x69\x24\x6c\xe5\x6a\xdd\x03\xc4\xd4\x65\x9a\x9b\xa7\xca\xf6\x93\x05\xb9\x35\x9f\xae\xe4\x99\x88\x6c\x02\xbc\x7b\xa8\xcd\x62\xfe\xeb\x9d\x8f\x67\x90\xd3\x9e\xbe\xe0\xae\x37\x45\x3c\x8f\xa9\x15\x59\x05\x94\x10\x7c\xb6\xdd\x1f\x78\x8b\xab\xa6\x39\x75\x77\xdb\xf6\xef\x38\x8f\xad\xbc\xca\x5e\x34\xad\x65\x27\xc3\xfc\xec\x28\xab\xc1\xf3\x04\xb0\xe3\xd2\xe9\x22\x5c\x05\x29\x50\x9e\xa7\xc6\x93\x2e\x85\x74\x2c\x09\xcf\x97\x0b\x40\xdb\xdb\x5a\x41\xed\x79\x5f\x4d\x0c\x23\x4c\x6e\x3c\x73\xb6\x4d\x21\x5c\x26\xe4\x9c\x43\xe4\xcd\x10\x17\x11\x10\x47\x20\xbc\xe9\x76\xa1\xa5\x31\x9e\x25\x6d\x54\x81\xf1\xc3\x63\x82\x59\x3b\xa1\x5a\x4c\x0a\x5b\xa5\xa9\xeb\xfe\x3a\x97\x24\x42\x6d\x07\xd9\xf7\xe8\x78\x2e\xc9\xc9\x40\x48\x10\xf7\x82\x5e\xc8\x30\x8a\xe3\x2a\xb2\xe9\xed\xa6\xf5\x84\x1d\x7d\x5a\xfe\xfa\x7b\x55\x5c\x62\x21\x7a\xb9\x7d\xf2\x27\xd1\x11\x4b\x86\x52\x6e\x8b\x40\x46\x6d\x0d\x67\x33\x61\x56\xa0\x5c\xc7\x02\xdd\x22\xac\x6e\x24\xc9\xe4\x76\xb5\x33\xcc\xed\x1b\x2c\x84\x2f\x45\x72\x88\xb9\xab\x22\xd4\xa8\x0b\xd3\x59\xc8\x85\x38\x37\xe1\x78\x66\x34\xf3\xfa\x5c\xe5\xa9\x59\x88\x76\x22\x7c\x46\x39\x48\x70\x84\xd7\xaf\xaf\x7b\x70\x45\xf4\x80\xb9\xa5\xdc\xe4\x80\xe9\xf0\x60\x19\x1e\xc4\xcf\x65\xfb\x66\x97\x65\x18\xa4\x62\x7c\x5c\xe3\x92\xf5\xdb\x5a\xe8\x8b\x18\xf2\xd7\xa9\x16\x6e\xb4\x8d\xf1\x5e\x11\x46\x0a\x23\xb2\x16\x3b\x24\x8d\xe2\x44\xf6\x1d\x00\x16\xa5\xdd\xed\xe8\xe8\x0a\x6f\xab\xe9\x68\x99\xa2\x8b\xb1\x00\x59\xb8\x5a\xef\x78\xf5\xa7\x24\x16\xc4\xd3\xd9\xbd\x55\x25\x4c\x0f\x27\x09\x12\xeb\x29\xd1\x58\xc5\xb0\xc9\x3b\x4b\x29\x21\xd4\x7d\x3d\x08\x54\xdb\x14\xaf\x43\x6c\x21\x4d\x19\x89\xb8\xb0\xea\xe8\xd5\x09\xc9\xb0\xfb\x23\xc6\x58\xb2\xc9\x29\xd7\xe9\x2f\x67\x29\x65\x09\x27\xc3\x99\xd6\x73\x71\x2c\x7a\xdb\x90\xb2\xcc\x36\xb5\xa0\xab\x1f\xee\x23\x8e\x2d\x37\xe4\xb3\xd8\xef\xcf\x03\x27\x26\x8d\x05\xc3\x62\x75\x17\x58\x58\x3a\x88\x5d\x67\x4a\x76\xba\x5f\x45\x69\xac\x44\xec\x38\x96\x7e\x40\xf1\x0c\xf5\xcb\x66\x51\x94\xdb\xbb\xe5\x64\xbe\x13\x22\x10\x6a\xb8\xb9\xdd\xee\x9e\x97\xeb\x5d\xb7\x79\xdd\xae\xd6\x9b\xed\x6e\x39\x5b\xdf\xff\xb1\xbb\x59\xad\x17\xbb\xf5\x6c\xeb\x81\x16\x69\x12\xc7\x19\x78\xbb\xec\xf4\x2e\x47\x8b\x66\x30\xd5\x49\x9c\x20\xb9\xcb\x1c\xf6\x20\x1b\x6c\x55\xf1\xa7\xe1\x09\xc8\xb4\x87\xa7\x79\xbc\xcf\x97\xcb\x6f\xe8\xf6\xa7\x5c\x32\x2b\x55\xd5\x39\xfd\xc6\x27\x0d\x26\x0b\x21\x8d\x28\xe6\xc0\x4a\x00\xdd\xdc\x9e\x4a\x8c\x34\xc6\x0f\x9f\x32\x4b\x58\xb9\xad\x4f\x4d\xbb\x86\x26\x2c\xc6\xff\x66\xff\xf3\x55\x92\x23\x3c\x5c\x1a\xe7\xb8\x69\xa3\x5a\x74\xdf\x76\x42\xd3\x34\xb7\x6c\x6c\x47\x71\xee\x15\x65\x69\x9a\xa7\x80\xc4\x0d\x5a\x9c\x9f\xab\xf6\x5b\xf1\xfa\xd6\xa8\x3e\x83\x98\xe6\x39\xc5\xb8\xfd\xfb\xcb\xfd\x7c\xf6\xb8\x7b\x7e\x5a\xec\x1e\x66\xbf\xef\xe6\xb3\xb5\xef\x2f\xa6\xa9\x60\xd4\xd3\x49\xdd\xd8\x55\xbd\xd9\x17\xca\x2d\xf1\xc9\x9a\x13\x8c\x91\xee\xd9\xfe\xfd\x51\xed\x3d\xc1\xf3\x78\x82\x84\xb0\x59\x60\x79\x3a\xcf\xca\x4b\x17\x78\x54\x36\x18\xf4\x9f\xd0\x54\x68\x2b\x91\x65\xfb\xc9\x2c\x09\xda\x57\x25\x78\x27\x01\x89\x04\xbc\xff\x98\x7e\x8a\x92\x69\x44\xd9\xdf\x6c\xe7\xb3\x17\x9f\x20\x49\x15\x4d\x90\x31\xd0\xea\x5b\x35\x1f\xcd\x1c\xf6\x6d\xa1\x9a\xfe\xb8\x26\xae\xec\xb9\xfd\x3d\xfc\x91\xc5\x58\x04\xb3\x30\xaa\xcd\x49\x36\xaa\x2e\xe4\x74\xeb\x4c\x55\x46\x30\xcf\x06\xb5\xa2\x51\x00\xb7\x9d\xbf\x26\x62\xa3\xa9\xe6\xc6\xa7\xed\x77\x07\xc7\xe5\xf3\xc5\x50\xe0\xb1\x76\x39\xa5\x7f\x9f\xaa\x76\xfc\x5d\xf8\xad\x34\x05\x6e\x3d\x1b\xcf\xf7\xfb\x0b\x70\x44\x0a\x32\x71\x7c\x00\xed\x83\xf8\x39\xd4\x63\xc1\xc8\x73\xb2\x2f\xa4\x26\xb2\xfc\xf2\xb6\x85\xdd\x14\xaf\x3e\x79\x3b\x9e\x05\x43\xad\x20\xe9\x5d\x61\x10\xde\xaf\x2f\x4a\x11\xa9\x89\x53\x35\x04\x84\x76\x4e\x2b\xb2\x2b\x7d\x61\xe9\xc2\x3b\x35\x9a\x49\xe9\x28\x92\xe5\x94\x22\xd0\xa2\x64\xed\xc8\x2c\x62\x19\x15\x01\xc6\xff\xff\x61\xf7\xc9\x22\x4e\xf3\xe1\x4d\xee\x14\x72\x8e\x5c\x9d\xca\x2c\x92\x91\x1c\x38\x94\xaf\xa7\xbd\xa8\xc3\xa2\xff\xaa\xc3\x9c\x66\x2c\x4a\x88\xe3\x31\xc4\x4c\x5f\xf1\x27\xfc\xfb\x34\x11\x29\xa6\x19\x8b\x63\xc4\x6e\x7d\x16\xe5\x6b\xe3\x21\x23\x9d\xcf\xfa\x9b\x1f\x90\x69\x2f\x4d\x77\x2f\xfa\xb0\x79\x14\x80\x67\xcc\x41\xaa\xd0\xd5\x77\x2f\xd8\x1d\x8a\x33\xe3\x12\x30\x4e\x63\x96\x45\xe1\x90\xb0\xbc\x9e\xf0\x13\x99\xd0\xc3\x9f\x8d\xa6\x34\x68\x48\x9d\xe4\xbf\xe0\x3c\xb9\x5c\x12\x51\xc6\x26\xef\xd8\x2b\x08\x7e\x35\x8b\x89\xa0\x49\x3e\x66\x98\xef\x1e\xd6\xe1\x29\x9f\xca\x2f\x92\xd0\x59\xa2\x53\x64\x22\x7a\x5c\xae\xbd\x39\xcb\xb2\x88\x22\x45\x24\x94\x7a\xfb\x56\xd4\xfa\x07\xc0\x7b\x60\xc5\xa4\x59\x26\x38\x56\x33\x1f\xab\x56\x60\xd2\x62\x1a\xd2\x64\x99\xc8\x85\x15\x59\xfc\x89\x90\xee\xa1\x5c\x91\x1b\x92\x47\x96\x5f\x0c\x83\xcc\xe7\xba\xf8\x28\xf6\xf0\x3a\xaa\xd0\x67\x39\x91\x48\x66\x80\x1f\xb7\xe5\xdc\xb1\xfc\x0b\xae\xca\x72\xa1\x0c\x45\x33\x11\x11\xc4\x51\x36\x56\x0e\xf4\xa1\x28\xdb\x01\xac\x27\x93\xa9\x75\x79\x9a\xbd\x68\xde\x16\xd5\x67\x39\x69\xfc\xbc\x1e\x71\x87\xf7\xa2\xa8\x07\xa3\x55\x87\xc7\xcb\xf4\x6b\xa6\x68\x8a\x41\xd3\x62\x39\x2a\x65\x64\x2a\xe3\xdc\x21\xd2\x5c\xe9\xcd\x7a\x5b\xe8\xe4\x2f\x26\x27\xd1\x09\x78\x42\x81\x1f\x50\xbc\x34\xfa\x32\xe7\x9e\x69\xc1\x12\x67\x69\x77\x2d\xd4\x87\x6b\xb5\xa6\x4c\x6b\x91\x21\x99\xc0\xe2\x6e\x74\x37\x90\x44\xd8\x20\x24\xeb\xea\x1d\xea\xc1\xc2\x84\x54\xa0\xb8\xd9\xae\x08\x3a\x93\x5e\x57\xe9\x62\x5e\x02\x36\x21\x03\x21\xb2\x0c\x4b\x12\x95\x42\xdd\xb3\x21\xac\x70\xfa\xef\xc8\xdc\x65\x00\x59\x6c\xdb\x13\x76\xda\x76\x9e\xed\x8e\x83\xac\x7b\x1e\x89\x08\x13\xb0\xb2\xd0\xcd\xce\xf6\x23\xec\xd4\xa0\x18\x90\x33\xca\xb0\x1b\xbf\xc0\x3c\x75\x08\xd7\x72\x96\x08\xef\xb7\xf9\xbd\xa4\x8b\x79\x37\xff\x0a\x03\x44\x8e\x6d\x2a\xdb\xf5\xd3\xe3\xf7\x51\x16\x3b\x67\xd2\x27\xb2\x30\x6c\xb4\x0e\x3a\xd4\x7d\xd5\x30\x67\xc6\xee\x73\x47\x71\xbe\x11\xbd\xe5\x75\x47\x63\x93\xa1\xf7\xde\x27\x1a\x6f\x8b\x52\x94\xaa\x10\xfb\xd9\x90\xd7\xef\x32\x36\xce\x13\xc5\x11\x53\xe5\xbf\xfb\x55\x0b\x87\x5f\x47\xc1\x79\xaa\x08\x57\x41\x84\xe3\x4a\xad\x2c\x4f\xb5\x34\x56\xc9\xae\x68\xda\x66\xc8\x0a\xe0\x06\x64\xc4\xca\xe2\x58\xa0\xf6\x98\xaa\x6e\xda\x00\xe6\x36\xcc\xff\xa6\xce\x75\xa0\xfe\xd6\xb3\x24\x43\xac\xcc\xf7\xcd\x76\x76\x95\x1e\x62\x72\xcd\x44\x22\x97\xf9\x23\xc8\xd3\xbe\x18\x2e\xcf\x3c\xe3\x80\x99\xd7\xb9\x28\x07\x0c\x1a\x23\xe4\x47\x9e\xa5\x4c\xf6\x74\x14\xee\x23\x9e\x35\xcf\xe2\x0c\x18\xc8\x8c\x32\x10\xfd\x7f\x05\xb7\x67\x3a\xa7\xc3\x2d\x23\xcf\x94\x65\xb1\x3b\x35\x7a\xf0\xd2\x73\x61\x09\x0e\x6d\x2a\xea\xb7\xd1\xd3\xe4\x26\x53\xc6\xb1\x8b\x4d\x26\x57\xe4\x36\xb7\xd5\x79\x94\x5b\x10\x87\x17\x57\x9d\x0d\x80\xbd\x5c\x68\x82\x39\xcc\x2e\x0c\x53\xd0\x38\x55\x1c\x7f\x10\x0c\x66\x4b\xfe\xdd\x9d\xf5\x8a\xaf\x98\x4b\x6e\x49\x23\x9e\xeb\xf3\x9f\x23\xeb\x99\xcb\x5c\x61\x93\x51\x2b\xde\xc1\x41\x92\xbf\x56\xf1\xa1\xb9\x54\x13\x32\xf2\x67\x8c\xb2\x26\x8f\x23\x4d\x8e\xed\xc7\x0e\x17\x59\x94\x0f\xe2\xe7\x0d\xb4\x5f\xb3\x45\xd3\x5c\x11\x89\xb9\x01\x57\x7a\x5f\x83\x50\x81\xcf\x8f\xe6\x8a\x59\xb1\xee\x6f\x9b\xcd\x5b\x75\xdc\x88\x3d\xf4\x06\x29\x57\x8e\x84\xdf\x89\x61\x14\x87\x01\xed\xc4\xe4\x2a\x3a\x32\xd4\xb8\xd0\x2b\x9c\x5c\xe7\xcc\x75\xf4\x1d\x90\x7d\xbe\x3a\x8c\x55\x55\x69\x0e\x59\x2e\xa2\x80\xfe\x59\x88\x62\xf2\xbc\x86\xc4\x48\x2e\xfc\x47\x35\xa5\x84\xa2\xb9\x89\x23\xea\x8c\x4c\x17\xcf\x3e\x9e\x0e\x93\x77\x63\x62\xc9\x9c\x3f\xd9\x36\xc3\x9c\x53\x6e\x64\xc2\xf4\xa0\x4b\x44\x56\xd5\xfb\x3d\x94\xaf\x21\x51\x20\xa2\x3c\x4e\x7b\xf6\x8d\x41\x03\x11\x15\x91\x4c\xb8\x87\xc6\xbc\x94\x4d\x88\x8f\x05\x89\x28\x4a\x52\xfc\xf1\xf2\xbc\x5a\x86\xa0\xd1\x8b\x13\x87\x51\xb1\x45\xfc\x35\xc2\xc0\x43\xf5\x05\xbe\x54\x30\xa2\x50\x6b\x46\x9f\x4b\x71\x28\x94\xbb\xb9\x21\xf5\x97\x1f\xc8\x05\x12\x37\xa0\x6c\xb4\x1a\xa6\x80\x05\xcb\x8d\x71\xb5\x70\xcc\x5c\x5e\x91\x28\xa7\xa2\x0b\xa6\x2d\x5f\x5b\xb3\xfb\xa8\x82\xde\x2a\x15\x71\x2e\xb0\x71\x60\x58\x1a\x6c\x06\x0a\xe2\xd7\xf7\x14\x11\x4b\xca\xa2\x9e\x74\x14\xba\xed\xb3\x98\x24\x33\x44\x2c\x81\x39\xea\x3a\x7b\xde\x9b\xf3\xa5\xa0\x2b\x15\xb1\xd2\x98\xd1\x00\x0b\x3d\x9f\x92\x9e\x50\x91\x10\xc0\x05\xda\x2d\x2f\x4b\x67\x11\x59\x73\x17\xf9\x01\x14\xb4\x03\x00\xdb\xde\x4e\xd7\x8f\x46\x27\xd3\x9d\xe4\x02\x1b\x2f\xfb\x4d\xe3\xf9\x74\x3c\x62\x72\x61\x7e\x2f\xea\xd7\xa9\xa4\x32\x15\x89\x30\xb8\xb8\xcc\x40\x3e\x8e\x8a\x94\x2b\x70\x49\xd1\xfa\x04\x33\x8d\xdc\x8a\xcd\x44\x78\xe9\xaa\x01\x10\xa9\x4a\x30\x78\x2c\xe1\x67\x68\xd3\x5a\x88\x73\x4f\x45\xe5\xaf\x91\x45\x32\xb6\xf1\xfb\xa7\x35\x38\xce\xce\x8f\xe7\x2e\x4b\x63\x44\x8f\x5a\x04\xf1\xe2\xe9\x71\xb6\x5d\x3d\x3d\xee\xd6\x4f\x2f\x8f\x8b\x9d\xf7\x9e\x45\x9e\xc6\x48\x41\xda\xbd\xf9\x88\x3c\x56\x03\x49\x65\x2a\x44\x2e\x90\xf9\x12\x4a\x78\x6b\x07\xa6\x4d\x08\x29\xb1\x2b\x68\x83\x4a\x18\xc3\x03\x2a\xf3\xe0\xe7\x6f\x62\x8f\xa4\x9b\x03\x18\xa5\x10\x26\xca\x72\x2f\x11\x60\xbf\xac\x4b\xe7\x4a\x48\x42\x49\xcf\x78\xd6\x4d\x85\x45\x12\xf8\x8b\xc8\x4c\x61\x87\xf6\x5b\xf5\xf9\x10\x9a\xb4\xa8\x90\x32\xc1\xba\x8e\xdf\xbc\x91\xdb\x32\x14\xe2\x27\x2b\x4b\x6a\xc1\xf3\x20\xab\xd5\x34\xa7\xce\xf6\x2f\x40\x86\x67\x57\xdc\x2a\x0f\xd9\x9b\x70\x0e\xef\xbf\xfe\x98\x0f\x1f\x47\x89\x8c\xba\x0a\xd4\xe3\x95\x68\x52\x68\x62\x25\x50\xab\x23\xd4\xa2\xad\xea\x0d\x94\x5f\xe3\xe4\x2f\x6a\x4b\x42\xe7\x16\xf4\x66\x65\xf3\xb1\xab\xe3\xb7\xf1\x86\xf9\x8f\x09\x96\xcd\xff\x50\x83\x95\xa9\x39\x1d\x44\xe9\x13\x01\x02\x62\x8d\xe9\xbd\xa7\x9b\xd5\xc3\xd3\xfd\xd3\xdd\x6a\x16\x8e\x28\x2b\xb9\x61\xa5\xad\xab\xd2\x11\x58\xef\x6e\x5e\xee\xef\xc3\x18\x48\x90\x5e\x61\xb6\xf8\xbe\xda\x3c\xad\x77\x9b\x6f\xb3\x75\x30\x69\x46\xf3\xd8\x42\x9f\x8e\xa2\xf0\xcc\x95\x62\x5a\x46\x15\xc6\xc4\x96\x58\xbd\x3a\x1c\x0a\x87\xaa\xc6\xba\x0d\xe8\x1e\xfe\x32\xfa\x89\x8c\x32\x48\x9d\x35\xf9\x5e\x0d\x79\x63\xaf\x96\x57\x65\x24\x00\xdd\x9a\xa3\xf0\x55\x43\x77\x80\xc6\x04\x57\x9e\x47\xdb\x54\x37\xa2\x7c\x9f\x05\xdc\xd1\x61\x51\x18\x03\xb5\xeb\x6c\x83\x66\x24\x3a\x49\x25\xe5\x26\x4f\xfc\x04\xdd\x16\x8d\xdf\x25\x24\x93\x19\xeb\xcb\xec\xf3\xea\x74\x0c\x20\x5e\x37\x22\x8e\x62\xbc\xb0\x3c\x35\x45\x09\x4d\xf3\xbc\x17\x65\x09\xda\x3e\xbc\x6b\x89\x19\xe2\x7e\x64\x1c\xe5\xe8\x0d\x0a\xad\x2d\x28\x18\x49\x36\x9a\x4b\xaf\x35\x8c\xb7\x59\x18\x47\xda\x79\x1d\x22\x27\xe3\xc4\x92\x37\x79\xd6\x64\x74\xa9\x6f\xab\xfa\xb1\x3a\x14\x65\x33\x6b\x2f\x3f\x43\x19\x1b\x81\x0c\x72\x4b\x7d\xfa\x8f\x28\xab\xbf\xee\x54\x92\x09\x95\x08\x0d\xba\x9f\x2d\x46\xd8\x36\xc9\x85\xed\xe6\xc0\xf6\x3c\x3a\xb9\x0e\x17\x39\x06\xa2\x3b\xcc\x3f\xd0\x5d\xa1\x2a\x57\xed\xbf\x98\x1b\xae\x15\xa6\x58\xd7\xf0\xde\x8e\x2e\x90\x66\xd2\x29\x0b\x88\x83\xcb\x75\xb8\x23\x19\x53\xdc\x26\x37\xb0\x01\x68\xe6\x01\x9a\xfe\x78\xce\x05\x4e\x4c\x8b\xbe\x21\x52\x67\xf9\x1d\x50\x0a\xc2\x63\x4f\x5a\x7b\x6f\xe9\x90\x07\x9f\xbf\x14\xb1\x40\x8f\xf4\x88\x62\x86\x55\xd8\x5c\xa6\xdf\xa3\x14\x39\xcf\xec\xf7\xd5\x3f\xd1\xe9\x0b\xf5\xab\x61\x3e\x51\xca\x34\x61\x6c\x00\xc5\xda\x56\xcb\xce\x18\x6a\xa8\x7b\xaa\x36\x1c\x65\x91\x62\x0d\xd4\x1b\x50\x27\xec\x24\x1d\xbf\x7e\x95\x70\x8f\xdf\xf7\xad\xad\x93\x01\x9c\x79\xb5\xe2\x79\xf5\xe7\x79\xf6\x7a\x91\x53\x90\x4a\xd8\xe0\xfa\x33\x54\x69\x6f\x7f\x9f\x0c\xd1\x3c\xcb\xd5\xa0\x42\x33\x69\x5b\x70\xa3\x80\x11\x24\x07\x7f\xb0\x42\xf3\x5f\x82\xe7\x46\x6b\xab\x8b\x72\x91\x3c\xa1\xea\x89\xb9\xa9\x34\xdc\xe0\x1a\x3d\x80\x16\xfb\x05\xa8\xe2\xd0\xe3\x29\x54\x44\xa4\xe5\x94\x45\x63\xa6\xaa\xc3\x11\xca\xa6\xef\x91\xf7\x3e\x82\x8a\x78\x8a\x0e\x72\xf3\x09\x70\xfc\xf5\x26\xad\x22\x60\x98\x9d\xdf\x1c\xab\x13\xe2\xd5\x85\x1c\xb7\x35\xa8\xc8\x18\xe1\xbc\xd2\x05\xee\xa6\xa0\x6f\x44\x53\x28\x1b\xd7\xad\x16\xd7\xd7\x88\x22\xcc\x20\x3a\xb8\x0b\xfd\x37\x57\x4a\xec\x7e\x58\x1e\x71\x87\x66\xf9\x03\x44\xbd\x10\x93\x5a\xbe\x22\x42\x23\xd8\xf9\x5f\x45\xdb\x42\x39\x28\x8e\x28\x62\x98\x65\x86\xf8\x14\xc7\x29\xd2\xe1\xbf\x93\x3e\x18\xe6\x8e\x53\xe9\x2a\xf7\x08\x55\x34\x8e\x70\xb6\xb0\x5a\x3e\xe2\x8b\xf3\x03\x64\xaa\xdc\x04\x6c\xb7\x5b\x6f\x4f\x87\x2f\x53\x31\x96\xe0\x0e\x8e\xfd\xdd\x73\xb1\xdf\x4b\x71\x25\x81\x7a\xb1\x23\x2a\x96\x26\xf8\xba\xf7\x85\xac\x45\x7d\x26\x89\xf1\x3a\x5e\x7e\x80\xd6\x89\xe8\x85\x0b\x6f\xab\x7a\xd4\xc2\xab\x98\xd1\xd2\xa5\xfe\xf0\xd6\xad\x5f\x3f\x7e\xc0\x38\x8d\xb8\x63\x28\x9a\xd5\xb2\x68\x71\xeb\x26\xa2\xd4\xf4\xba\x6d\x55\x71\xe6\x6b\x8a\xc7\xdb\x42\xb4\xb3\x52\xf7\x4d\x36\x2a\xce\x2d\x77\x6a\x80\x5c\xde\x88\xe6\x1d\xda\xab\x60\x5c\x15\xab\x2c\x07\xdf\x08\xfb\x13\xcb\xab\xaa\x38\x8a\xb2\xbd\xf1\x79\xca\xf1\x54\x27\x2e\xab\xfd\xfb\x1f\xdb\x57\x11\xd6\x7d\xd2\x6d\xe8\xce\xcb\x6a\xdf\xb6\x95\xe7\x38\x46\xc3\xf1\xcd\x53\x33\x11\x6a\x6d\x0d\xa1\x99\xff\x9d\x8a\x98\xeb\x1c\x90\xe3\xae\xf6\x30\x80\x26\xf1\x40\x49\xe1\x54\x6a\xa8\x7d\xa9\xf0\xea\x86\xac\x38\xb3\x8e\xfe\x63\xd5\xf6\xad\x4f\xd7\x17\x16\x4f\xbc\x22\x75\xe7\xcd\x77\x11\x5d\x3d\x68\xd7\xf3\x83\x24\x80\x95\xe9\x39\x9d\xbf\x4a\x1a\xba\xa1\x69\x66\x51\x27\xaf\x3e\xe5\x7f\xa9\x90\x4a\x55\x0a\xb9\x4b\xdf\x88\xf6\xad\xb3\x2c\x3b\x43\xb8\x9f\xc8\xd4\x08\xc4\x01\xef\x2d\x54\xa7\x1e\xf0\x16\x53\x95\x27\xc2\x33\x18\x3d\x88\x9f\xdb\x42\xbd\x43\x00\x6a\xaa\x3c\x07\x94\x36\xdb\x5d\x94\xef\x26\x3d\x27\x7e\xbc\x16\x9c\xfa\xf2\xc4\xe1\xd8\xc2\x8e\x8c\xbf\x18\x61\x62\x3c\xe1\xdd\x62\x3e\x53\x2a\xf2\xed\x5d\x4a\x12\x81\xe1\xfb\x48\x1a\xe5\x9b\x68\xde\x2e\xb0\x4c\xbf\xfa\xa6\xb5\xce\xd0\x22\x07\xe5\x5a\x8b\x90\xb4\xd3\x9f\x0d\x73\xff\x97\xff\xe5\x4e\x01\x51\x8a\x30\x88\x23\x8a\x39\x78\xc9\x11\x7f\x9b\x90\x46\xb1\xed\xe5\xdf\x57\x42\x7b\xa9\xb6\x2f\x6c\x1c\x40\x2a\x1c\x0e\xc5\x98\x55\x69\x3c\x40\x40\x99\xc8\x2a\x14\x76\x01\xbf\x23\xf0\x09\x33\x6e\x92\x58\x65\x5e\x3a\xc7\x51\xeb\xdb\x5c\xd9\x3f\xae\xc0\x59\x7d\xc9\x49\x47\x34\xd2\x4e\x95\xf5\x3b\xd4\x43\x55\xc4\x2b\x34\xd7\x14\x79\x34\x51\x08\xe3\xf7\xef\xf3\x0d\xb6\x85\x8f\xd3\xad\x57\x57\xa2\x8e\x12\x95\xf6\xb4\x4c\x96\xd1\xc5\x1f\x12\x26\x75\x1c\xe0\xbb\x9b\xf9\xe2\x66\xa7\xc6\x49\x0e\x1d\x29\xdb\x86\x68\x1b\x5c\xd7\x5d\x2c\x17\x25\x9e\x86\x7f\x77\xf3\xf4\xe8\x49\xa5\xa9\x26\x29\xc7\x96\x9d\x10\x54\x5f\x15\xb4\xa6\x9a\x68\xbb\x66\x1a\x68\x5f\xca\xca\x20\xb0\x64\x3f\x48\x1f\x74\xef\xff\xe5\x78\x0b\x93\xcf\x5f\x13\x03\x98\x10\x10\x5a\xdf\xc3\x6b\xd1\x2e\xe0\xe3\xea\x47\xaf\x29\xe1\xd8\x43\x2f\xdf\xc5\x08\x82\xad\x69\xcc\x85\xf3\x32\x6e\xa0\x6d\x1e\xc4\xd8\xcf\xd6\x54\x31\x84\x4b\xdd\x41\xf9\x5e\xb8\x9c\x59\xf8\x2d\x28\x99\x87\x82\x1f\x52\x94\x4d\xee\x8f\xa5\xf6\x83\x37\xa7\xbd\xc5\xc0\x8c\xd0\x0b\x9a\xc9\x04\x41\x61\x07\xf1\x73\x76\x18\x42\xda\x75\x92\x48\x04\xa2\x7d\x7f\xda\xae\x1e\xef\x76\xdb\xd5\xc3\x72\xf3\x3c\x7b\x0c\x87\x53\x8e\xc5\xa7\x23\xfa\xec\xab\xed\xd3\xee\x20\x8a\x6e\x75\xaf\xca\x1e\xcd\xa6\x93\x3c\x42\x80\x26\xaa\xfb\x5c\xad\x5c\x8e\x97\x52\x22\x6c\x7a\xb0\x06\xd9\x7d\xb7\x25\xdc\x42\xf9\x67\xe1\x41\xe0\x9a\xcb\xd4\xb2\xe0\x86\x60\xea\xc9\xac\x45\xd1\x80\x93\x0a\xd9\xbe\x89\x76\x8d\xa4\x46\xcd\x6a\x9a\x19\xd3\x29\xb5\x49\xe9\x53\x39\xe2\xfa\x9c\x74\x3b\xe9\x94\x2a\xe4\x69\x5a\x57\x7f\x56\x9f\xef\x62\x3e\x80\xc6\x5d\x5d\xfd\x29\x03\xab\xf2\xd8\xd9\x42\xdf\x51\xeb\xaf\x99\x93\x0c\xfb\x57\x34\xec\xaf\xb4\x3b\xea\x9c\x25\xd4\xe5\xa2\x6e\x42\xdd\x63\xfc\xfe\x72\xce\x55\xaf\x66\x3f\xa5\x08\xf7\x83\x94\x15\xf4\x5c\xcd\x9f\x96\xbd\x88\x22\xd5\x52\x25\x58\x1a\x5a\xc0\x87\x5d\xfc\x13\x2a\xae\xab\x5b\xb7\x96\xda\xa0\x0b\xef\x9c\xe2\xa1\x23\xa7\xa5\xa1\xde\xd5\x0a\xb9\x2f\x8b\x71\x1d\xdf\xb6\x8a\x08\x3a\xe9\xdf\x56\x77\xdf\x96\x6b\xd7\x83\xbe\x5e\x6e\x96\xdb\x81\x5a\x86\x3f\xa9\xe2\x40\xc9\x50\x4f\xa3\x1b\x1d\x0e\xe6\x0a\xe3\xf6\x75\x75\xda\x43\x3b\x0d\xc8\xb4\x4e\x63\xec\x9b\x6e\xab\x97\xe3\x11\xc6\xed\x82\x5a\xe7\x2a\x0d\x2e\xd5\x8f\xa2\x7c\xac\x64\xe5\x84\x93\xc2\xe7\x05\x59\x4a\xc0\xbf\xbf\x1b\x81\xcc\xff\xa3\x93\x98\x44\x22\xc9\xcf\xcd\x22\x1a\x4e\x05\x44\x09\x49\x5d\x2f\xf4\x43\x85\x00\xc6\x9b\xf1\x6b\x01\xa2\x01\x53\x45\x88\x96\x3c\x56\x7b\x51\x23\xcf\xc8\xaa\xb4\x6d\xa4\xfe\x44\x94\x59\x9a\xa1\xc7\xd9\x83\xed\x6a\x9f\x7d\x9f\xad\xee\x67\x37\x21\x3b\x0a\x94\x5b\x7b\xb7\xaf\x44\xd9\x37\x4d\x5c\xdd\x28\x80\x66\x06\x6f\xb7\x5b\x30\x25\xec\x1f\x2a\x7d\x72\x8e\xb3\xb7\xef\x40\x85\x4d\x61\xc9\x53\x7d\x95\x6b\x63\x70\x32\x1d\x69\x5f\xd2\x33\x95\xdf\x73\x20\x16\x76\xcd\xab\x53\xd3\x56\x07\x9f\xb5\xfa\x75\x94\x00\x09\x8b\x7d\x1b\x21\x62\x19\xd1\x99\xaa\xaf\x94\x0f\x20\x91\x04\x41\xcc\xbb\xea\xf3\xaf\x12\x84\xc0\xf3\x0c\x73\xe1\x6b\x50\xc5\xb1\x80\xb2\x9d\xc8\x7a\x8f\xd7\x36\x2a\x3c\xa5\x36\xa5\x89\x30\x9e\x05\xa2\x7b\x27\xd7\x4f\x79\x44\x6c\xa1\xb8\x14\xaf\x57\x0a\xba\x90\xa6\x51\x0a\x43\xff\xf5\x8a\xfc\xe0\xa0\x1a\x09\xa9\x14\x96\xd6\xb6\x2a\x9b\xd3\x01\x7b\x2b\x9e\xab\xa2\x17\x58\xa0\x90\xb1\x0c\x4c\xe0\x44\xba\x09\x06\x1a\xb2\x8c\xe0\xee\x50\xc2\xcf\x76\x5b\x9d\xea\x52\x74\xf7\x33\x50\xf6\xe8\x86\x64\x58\x1b\xdc\x6c\xd7\xab\x7f\x8d\xbf\x1e\xc8\x64\x1e\x5b\xeb\x04\xc7\xa7\x12\xee\x2b\xf5\xee\x29\x47\xfc\x08\xc8\xd0\x44\xdb\x77\x68\x85\xff\xbf\x2e\x9c\x80\xc8\x28\x56\x2f\x64\xa1\x27\x3b\x1c\xc8\x28\xb2\x38\xab\x2f\x21\xe4\x57\xec\x2d\x48\x66\x05\x38\x55\x98\x0b\xd9\x79\xfc\xd8\x46\x69\x1b\x2d\x41\xef\x2c\xb8\xae\x09\x23\x92\xd4\xf3\xf9\x05\x48\x2b\x63\xa3\xcf\x16\x24\xd7\x96\x4b\xca\x19\x7b\x07\x07\x0e\xa7\x10\x09\x36\x25\xe9\x0a\x9a\x97\x06\x73\xa2\xa3\xc2\xe6\xf8\xa9\xa5\xd2\xca\xc1\x3a\xd6\xed\x61\xda\xff\xea\x06\xa9\x0c\x12\xeb\x0a\x1c\x8a\x2e\xb4\x70\x45\xcb\xeb\x7d\xeb\xee\x37\x3a\x36\xc8\x05\xba\x19\x13\x3b\x00\x44\x51\x46\xa7\xdc\xfa\x42\xb5\xcd\x55\xe7\x02\x80\xd9\x86\xc5\x55\x69\xf6\xa7\xf1\x89\x62\x69\x75\xe5\x5e\x9e\xd6\xb3\xc7\xe5\xef\xe1\xef\xdc\x26\x3e\xed\x6b\xef\x9c\xe3\xb6\xba\xaf\x3e\x9f\xea\x6f\xc5\xeb\xdb\x64\xb9\x43\x2a\xad\x2e\x14\xba\xfb\xe2\x1d\xc6\x57\xc8\x29\x52\xa5\x9e\x7e\xed\x36\xb9\xd1\x26\x02\x3e\x64\xc7\x76\x38\xe8\x69\x25\x01\x0c\x31\x48\xb5\xaf\xba\x28\xa5\x3e\xb8\x96\x89\x70\x96\x34\x65\x99\xcf\x3d\xee\x0e\x55\x09\xe7\x1d\x86\xcb\xf6\xb8\x89\x18\x45\x26\xb5\xa3\x38\xbb\x58\xf7\x6a\x82\xc1\x50\x9a\x63\xa1\x72\x37\x55\xa6\xbb\xc8\x44\x0f\xd7\x96\x61\xa0\x91\x61\xe6\xb9\xfa\x84\x1a\xfb\x07\x4e\x87\x41\x56\xc1\x30\x03\xe8\x11\x17\xb8\xb4\x6e\x6c\x71\xf5\xe6\x7c\x7d\xdd\x98\x38\xd6\xc8\x02\xbf\x10\xfa\x1c\x20\x99\x26\x06\x8d\x8f\x50\x34\xb3\xa0\xae\x39\x8e\xd3\x3a\xef\x9e\x64\x21\x38\x9c\x39\x14\x38\x22\xca\x4b\x47\x86\x3d\xbe\x52\x92\x1a\x24\xa7\xbe\x3b\xe9\x2d\x34\x9e\xaf\xad\xad\x6e\xfd\x45\x13\x41\xd1\x50\xf9\xe9\x70\x71\xf2\xf4\xed\x98\x44\x88\xd8\xcb\x20\x17\xb5\xae\xab\xe3\x2a\x70\x20\x99\x44\x51\x70\x38\x9b\x2b\x10\x34\x3f\x08\xac\x4e\x93\xd0\x7a\xd7\x56\x3b\x69\x11\xdf\xee\x20\x8f\x72\x8c\xa9\x77\x35\xcc\xb0\xca\x3a\x55\xbe\xa2\x86\x33\x85\x6f\x6e\x29\xea\xf6\xed\x01\xf4\x9f\xe1\x40\x1e\x0d\xd4\x18\xbf\x8b\xd3\xbe\x0d\x87\x94\x49\x8d\x6f\x89\xf6\x56\xc1\x6e\x90\xb3\x89\x89\x37\x39\x01\x84\xfe\xcd\xca\x73\xfb\x56\x94\xaf\xb3\xe3\x71\xb8\xea\x4d\x4e\x53\x1d\x7b\x0a\x07\x04\x7e\x87\xc6\xf5\x5b\x80\x45\x61\xf5\xc3\xfc\x60\x6e\x54\x10\x82\x77\xe4\x78\x33\xa5\xaa\x5a\x17\xe5\xeb\xb6\x5a\x0b\xcb\x3b\xe6\x96\xda\xe8\x1f\x77\x06\x19\xe5\x32\x74\x73\x9b\x05\x34\x6a\xe2\x71\x19\x19\x19\xa4\xce\x39\x74\x37\x01\xcd\x6e\xfb\xb4\xfb\x36\xdb\xce\xbf\xed\xc8\xba\x50\xef\xb3\x52\x3f\x54\x3d\xa0\xd6\x48\x6e\xc0\x07\xea\x55\x39\x74\x86\xfd\x80\x9c\xe7\x76\xa3\x34\xc6\x6b\x74\x5c\x35\x61\x46\x91\xd4\x62\xd5\x44\x83\x1b\x87\xc7\xbd\xf9\x4b\x29\xc1\x90\x2b\xf6\xe0\xc1\x02\x37\xa7\xfd\xfb\xd7\x78\x13\xa3\x85\x21\x3d\x36\xd3\xb2\x1b\xa3\x57\x36\xf4\x61\x8c\x86\x18\x3f\x9a\xfb\xea\xf5\x2f\xba\x9f\x0d\x30\xe9\xeb\x6f\xcb\x52\x3f\x19\x6f\x72\x26\xa3\x54\x42\x7a\xee\xa2\x90\x93\x46\x06\x65\xea\x9f\x05\x8c\x61\x96\x72\xc1\x6a\x3d\xd4\x83\xee\x12\x37\xc4\x48\x82\x65\x91\xf5\xf2\x76\xb9\x5e\xcf\xee\x77\xeb\xe5\x8f\xd9\x7a\x71\xe9\xf6\x1a\x23\x99\xb4\x1f\xdb\x09\x42\xcc\xc4\xa2\x88\x13\x33\xcc\x6f\x37\x41\x01\x0a\xfc\x37\xc6\xa2\x48\xa5\xb8\xd7\x22\xe7\x07\xfa\xdf\xd7\x9e\x9d\x45\x24\xb3\x64\xd0\x07\xa7\x94\xdf\x6c\xab\x5e\x59\x94\x45\x8c\x9b\x8c\x0f\x2b\x7e\xa0\x97\xa2\xde\x9f\x47\x63\x52\x19\x29\x6b\x4b\x01\xc6\x79\x4d\x16\xc5\x8c\x61\x78\x29\xa1\x6d\x50\x1a\xdb\x43\x48\x58\x14\x1b\x81\x73\xb5\x1d\x42\xd9\xbe\xaa\x93\xb0\x28\xa1\x3a\x1b\x32\x34\x5d\x51\x1e\x63\x51\x92\x68\x6c\xd5\x43\x46\xd4\x1e\x43\xc7\xa2\x44\x47\x24\x1a\xec\xf6\x5b\x10\x87\x49\x09\x38\x94\x07\xbd\x5f\xc6\x22\xce\x63\x36\x82\x97\xa0\xb9\x98\x3e\x23\xcf\x05\xb6\x30\x89\xa6\x29\x5e\x4b\xfa\xc5\x4c\xa7\x39\xc3\xda\xe8\x1e\x41\x09\x4f\x66\x5e\x1d\x0e\x55\xf9\x5c\x83\x29\x7e\xfe\x36\xcd\xda\xb2\x28\xe3\x12\xc1\x72\xc2\xb4\x81\x00\x62\x4c\x9e\xc0\xa2\x2c\xe5\x18\x18\xdc\x57\xaf\x96\xe0\x69\xa0\x99\xe4\x87\x08\xbb\x9d\x5a\x57\xb5\x6e\x06\xa5\x6a\x16\xe5\x34\xa6\xae\xf2\xd0\xed\x43\xdf\xc4\x64\xd2\x44\x6e\x90\x77\xfb\xa3\x80\xcf\x07\x38\x54\xf5\x79\xf2\xe4\x52\x48\xf4\x0d\x83\x38\xc9\x20\xfb\x3a\xb9\x11\x29\x2c\xf7\x9c\xf5\xd4\x7e\x14\xed\xdb\x34\x96\x65\x91\x54\x1a\xc7\x74\xfb\xbe\x65\x69\x41\x97\xeb\x4a\xe4\xc1\x22\x15\x91\xc8\x45\x1e\x4b\x27\xdd\x31\xc9\x7b\xb2\x48\x69\x82\x28\x8d\xba\xa7\xc8\x43\x59\x79\xac\xb2\xfa\x31\x20\xb0\x3a\xd6\x9c\xe4\xa1\x68\x43\x16\xef\xca\x1b\xd1\x91\x25\x31\xc7\x8e\x59\xdf\x6a\xff\x75\x69\x7a\x7c\xbb\x3a\x66\x98\x5e\x5e\x54\x75\xb5\x28\xc4\xa1\xf2\xee\x39\x8b\xb4\xb4\x12\x5b\x68\xba\x3b\x93\x66\xe5\xca\xe6\x62\x1f\xe8\x11\xbb\x41\x90\xe6\x03\x94\x37\x2a\xff\x8f\x80\x0c\xc3\x2f\xc7\xff\x48\x91\xdc\x12\x74\xe3\xa4\xff\x53\xa8\xf7\x63\x15\xde\xbe\xd6\x09\x82\x8f\x6c\x92\x6c\xbb\x5e\xce\x36\x2f\xeb\x3f\xfc\x51\x88\xac\x42\x54\x17\x93\xaf\xbf\x2f\x17\x96\x2c\x6e\xb3\xbb\x7d\x5a\xef\x02\xaa\xb6\x1b\x66\x7b\x0d\x87\x84\x4c\x77\x50\x46\x57\xee\x8a\xc7\xc3\x4f\x0b\x24\xa1\xae\x73\x7a\x76\xd2\x45\x3b\xc3\x8f\x67\xd8\xc4\x36\x9e\x40\x43\x00\xb3\x33\xde\x2f\x9c\x35\x0d\xb4\x57\x5a\x15\x58\x64\x62\xcb\xbe\x7a\x84\x1a\xdf\xf4\xe3\x4f\xe5\xef\xd6\x70\x83\x35\x7b\x69\x39\x7d\x67\xc6\x4c\x56\xa9\xd1\x36\x1f\xd5\xd3\x10\x15\xe1\x1d\x90\x48\xa5\x88\x5c\x50\x55\xf9\x01\xf5\x97\x2c\x4a\x7e\x74\xaf\xb6\xe3\x7c\x72\x0b\x92\x9b\x07\xd0\x2b\x19\xa3\x80\x18\x21\x94\xa0\x5c\xfa\x6a\x33\xac\x04\x33\x42\x09\xe7\x89\xa7\x8c\xb2\x45\xf0\x31\x06\x3e\x71\x03\x99\xd4\x08\x23\x5a\x2c\x9f\xfd\x6f\xe3\x28\x15\xc3\x40\xc1\x3d\x54\x7d\x2d\x4e\x60\x24\x49\x72\xf4\xd5\xab\x5a\x43\x6d\x09\x99\xbf\x42\xc5\x86\x5f\x58\xf9\x07\x55\x0b\xe3\x1f\xeb\xbf\x09\xf7\x8c\x89\x5f\xff\xa7\xff\x7d\x0a\xf8\xfb\xa2\xdb\x5c\x86\xfd\xf1\xd9\x25\x6c\x97\x11\x6e\xb8\x76\x6e\xc9\x63\x85\x7a\x3b\xad\x08\xf6\x8c\xa4\x49\x8e\x71\xb9\xff\x48\x2c\x92\x66\x12\x5b\xfe\x5f\xff\x1d\x4f\x50\xca\x85\xee\xc3\xa2\x05\x88\xfd\x62\x00\x02\x98\xcc\x4d\xaa\xac\xbe\x79\xeb\x12\xfb\xb7\x55\x8d\xc8\x74\x14\xcf\x1d\x18\x21\x92\x25\xb9\x8e\xc6\x72\x48\x2d\x94\x6d\x21\xf6\x57\xf0\x8c\x8c\xe4\x9a\xe1\x97\xbb\x78\xfa\xe7\xca\x9f\x42\xc4\x56\x9e\xcc\x83\x2a\x5c\x24\x71\x99\x91\x64\x44\xe4\x16\x10\xfe\x03\xe0\xfd\xdc\x73\x44\x30\x22\xa3\x84\x7a\x65\x67\x51\x74\x36\x15\x13\x01\x57\xf7\x33\x22\x19\xc7\xf2\x07\xb2\x08\x6c\xa0\x7d\x39\x86\xd3\xa4\x80\x08\x9e\xfb\xea\xd5\x31\xc8\xfd\x5d\x95\xf9\x8b\xf0\x9f\x11\xa9\x25\x02\x1d\x2c\x25\x9b\x03\xa2\xef\xcf\xbd\x7f\x3e\x59\xc1\x2a\x4a\x8d\x7b\x06\xac\xa6\xdf\x9c\x17\xfd\x8e\x46\x54\x4c\xb1\x23\x16\xda\x37\x9f\x95\x1a\xe6\xbb\x19\x51\x89\x05\xcc\x6a\x38\x7a\x58\x23\x23\x4a\x49\xa2\x7d\x43\x9d\xa9\xac\x7d\xc6\xad\x69\xa8\xd7\xcb\x88\x66\x16\xdd\xb6\x2f\x3e\x60\x51\x8b\xd7\x40\xe2\xcc\x88\x4e\xac\xf7\x78\x3b\x7b\x58\x8e\xbe\x6d\x9d\x4b\x6c\x08\xb9\x3f\xfd\x1c\xe5\xee\x19\xd1\x2a\xc3\x74\xc1\xf2\x7f\x4f\x45\x7b\xde\xbc\x89\xee\x15\x6e\xce\x4d\xeb\x7b\xfe\x19\xd1\x9a\xe0\xc7\xdd\x4b\x7d\x20\xac\xee\xfa\x0b\xd3\x10\x6b\xdb\x67\x85\x44\xf3\x57\x13\x60\x8c\x40\x64\x75\xea\x84\xd6\x1e\x6a\x70\x6d\x0d\x99\x48\x73\x0b\x37\xb3\x3a\x63\xc3\x92\x05\x23\x86\x33\x0c\xa4\x8e\x96\xaf\xfa\x41\xfc\xc4\xc4\xff\x0f\x28\xc2\x88\x3c\xc3\xcd\xb4\x68\x36\xd0\xd3\x00\x33\x1a\x51\x42\x2d\xf8\xd5\xd4\xd0\xbc\xad\xe1\x78\x6a\xc5\x35\x9a\x01\xbf\xc9\xd3\x28\xe6\xb1\xab\x61\x61\x55\xf5\x0a\x4f\x34\xa3\xc4\x50\x84\xd6\x3f\x40\x2d\x86\xd3\x4f\x29\x27\xaa\xe7\xcb\xfe\x0e\xa5\xae\x26\x3b\x0f\xa5\x99\x44\x6d\xd3\x7f\x89\xfa\x20\xfe\x1e\xff\x30\xa3\x54\x4a\xdb\x52\xdb\xcd\x0e\x3a\xe0\x0b\xd8\x5f\xe9\x5f\xff\xab\x2f\xe2\x97\x85\xc8\xeb\x26\x99\x32\x99\x50\x3e\x11\x80\xb1\xb6\x1f\xf6\x97\x35\xd5\xc9\x6f\xb5\xc2\xdf\xde\xcd\xd7\xf8\x13\xf4\x33\xfc\x64\xc5\x71\xaa\xf2\x01\xbc\x6f\xd8\x18\xe0\x87\xa4\x0c\xe1\x77\xf3\xc7\x79\xf8\x55\x96\x61\xa4\xfc\xfc\xf4\xf4\x2d\xfc\x4d\x18\x5c\xf5\xc2\x61\x3d\x47\x2a\xb3\x8c\xc6\x90\x62\xff\x53\x65\x30\xc7\x70\x7f\x85\x51\x76\x72\xdf\x49\x16\xfb\x5a\xf0\xb7\xea\x00\x56\xe2\x62\xfb\x73\xf2\x2a\x39\xb3\x5d\x0e\xd0\xbe\x89\xba\x9d\xd5\xed\x50\x26\x91\x51\xae\x24\xda\xeb\xdd\xd1\x79\x77\x1e\xf6\x33\x3e\x4b\x26\x0c\x36\x2d\xfd\x01\x3e\x67\x38\x3e\x9e\xe7\xd4\xce\x3f\x88\xc3\x53\x19\x38\xf5\x18\xcd\x95\x11\xae\x22\xd0\xee\x01\x9f\xca\x57\x86\xb3\xff\xb9\x4e\xf6\x37\xc4\x73\x5c\x60\x3b\x18\x15\x0c\x12\x5b\x83\x6e\x26\x7c\x1e\x93\xf9\x11\x19\x41\x24\xe2\xa1\xd0\xa2\x71\x20\x84\xf1\x47\x4b\x45\x2e\xec\xb9\xaa\x60\x2f\xa9\x72\x54\x73\x9d\x13\x13\x28\x95\x18\x55\x0a\x90\xf4\x60\xf5\x7e\xaa\xc5\xac\x69\x2a\x55\x0c\x03\x13\xaa\x20\xc2\x5c\xc3\xe7\x5b\x35\x62\xaa\x65\x14\x22\xdb\xa5\x57\x34\xdd\x26\x78\x8b\x5c\x5e\xe2\x1c\x8e\x12\x8d\x9d\x84\x4f\x3f\x1e\x97\xeb\xdd\x6c\xb1\x58\x87\x23\x54\x62\xd4\x2c\xb4\xfe\x51\xd4\x97\x9d\x7d\xe3\xa7\x85\x38\x46\x05\x91\x1e\x98\x8c\x7b\x81\x47\x4d\x23\x0e\x6c\x6a\x47\x40\x6a\xc4\xbc\xd9\x5d\x61\xd5\x3c\x1d\xa1\x44\x31\x98\xde\xfd\xa0\x26\x92\xc2\x92\xdc\x35\xaa\x2e\x30\x4f\xff\x4d\x34\x6f\x1e\x20\xe1\x47\x65\x0c\xac\x0d\x13\xfb\x1f\x55\xbd\xd7\x36\x76\x44\x95\xfb\xd0\x19\xea\x11\x24\x8c\x1a\xa9\x45\xdc\xdb\xe5\x4b\x95\x54\x3b\x8e\x45\x84\xa0\x0d\x9b\x01\x76\xf6\x84\x66\x5f\xc6\x22\x6a\xd3\xdd\xd6\x93\xbf\x7d\x7a\x79\x5c\x2c\xd7\x9b\x70\x34\xb6\x34\x5d\x87\xdd\x5e\x34\x16\xc1\x33\x24\x27\x63\x2c\x12\x2a\x72\x2f\xd9\xc1\xbd\x87\xa6\x8c\x11\xb0\x99\x2c\x09\xa6\xaa\x61\x29\x94\xdf\x17\x19\x01\x81\x6a\xcd\x8d\xf8\xb0\x29\x5f\x14\x92\xf6\xab\x84\xb1\x58\xe1\xd7\xd6\xab\x80\xcc\x27\x8f\x14\x47\x0c\xd3\xb4\xc6\xfa\x7d\xc3\xc2\x1b\x63\x31\x65\xd2\x35\x2c\x1d\x06\x18\x53\x77\x34\x89\x88\x97\x23\x77\xed\x5e\x6b\xf8\xa8\xde\x61\x31\xe4\x28\x1d\x5f\x8d\x27\x96\xff\x28\xb0\x5a\xad\xb4\xa3\xb3\x5a\x96\xa7\x03\xa0\x58\x84\x3f\x3d\x4f\x0d\xe6\x84\x5a\xf1\xba\x2f\xca\xfe\xcf\x42\x11\x2f\x69\xbb\xbd\xc3\x94\xee\xf8\x1a\x59\x22\xb4\x4b\x5b\x3e\xc2\xe7\x54\x1c\xee\xea\x6a\x65\x59\x22\x11\x3b\x75\x03\x75\x3d\xac\xa6\x32\x96\xe5\x44\x8d\xf2\x0f\x33\xc7\xc0\x3f\xf8\x71\x9e\xa6\xae\x4b\xcf\xf7\xde\xa2\xb2\xcf\xe8\x15\x66\x86\x23\x44\xc0\xe5\x62\x8f\x5f\x87\xad\xee\x07\x39\xe1\xb8\xa2\x7a\x69\xe7\xfa\xb6\x3a\xd5\x9b\xd6\x53\x72\x31\x96\xd3\x2c\x66\x03\xcd\xbe\x51\xee\x99\xb1\x9c\x93\xa8\xd7\x2a\xee\x42\xc2\xcb\x4a\x1e\x63\x79\x9a\x61\x14\x68\x3f\xba\x07\xe8\xcc\x6e\xd9\x4e\xa6\xcd\x8f\xcd\x28\x42\x11\x3e\x0a\xf8\xbc\x17\x2d\x34\x08\xd4\xea\x65\xe0\x7c\x57\xa4\x1f\x2e\x13\xcc\x65\x6f\x5e\x36\xab\xab\xbb\xf6\x68\x86\xf2\x40\x81\xd1\x05\x7e\xad\xa8\x2d\x9a\xdb\x82\x05\x7c\x0b\x45\xe6\x07\x1b\x89\x98\x11\x83\x49\x97\xa0\x89\x37\x41\x08\x31\x26\xb8\xb6\xfd\x11\x01\x27\x25\x72\x7f\x7b\x22\x4d\xd2\x18\xb3\x09\x9f\x63\xdc\xc3\xf5\x17\x22\x64\x02\x2e\x42\xd8\x63\xb5\x3a\xb8\x4c\x4c\x12\x9b\x0c\xf7\x74\x10\x0f\xc5\xeb\x95\x36\x6d\xc6\x64\xac\xb0\x94\x54\xed\x3e\x60\xff\x56\xed\x8e\x75\x25\xf7\x70\xb8\x90\xdb\xf5\xc3\x13\xeb\x98\x1e\x3d\x11\x4d\x2b\xf6\xbd\x03\xc7\x54\x6a\x05\xdb\x9c\xb6\x72\x48\xbd\x4c\xd2\xb5\x8c\x29\x20\xda\x92\x87\xc2\xa1\x38\x1d\x16\x55\x37\xa3\xff\xf2\xa7\xd1\x24\x05\x1b\x22\xcd\x1a\x55\x84\xb3\x6b\xe0\x42\xf4\x82\x87\x74\x3d\xcc\x11\x8e\xef\x53\x1b\x85\x60\x77\xdc\xb6\x2e\x14\xec\x18\x33\xa9\xc5\xc0\x22\x57\xd9\xf6\xec\xf5\x77\x59\x4c\x24\x33\x2e\xf3\x63\xc1\x15\x8f\x5e\xba\x9a\xc5\xe4\xff\xcf\xd9\xb7\x75\x39\x8a\x63\x59\xff\x9d\x7a\xe8\x07\x40\x12\x88\x47\xdf\x22\xd2\x5d\x11\x61\x77\xd8\x99\x59\x35\xb3\x66\x79\xe9\x72\xe4\x60\x12\x83\x1b\x70\x46\x46\xff\xfa\x6f\x71\x24\x71\xb3\x1d\x55\xf3\xcd\x3c\x64\x75\x48\x60\x10\xba\x9c\xcb\x3e\x7b\x2b\x11\x38\x09\x9a\x2a\x03\xb7\xbb\x5d\xa5\x9a\x5d\x67\x12\x13\x0c\xc8\x0a\xdc\x55\x37\xc6\xdf\x84\x92\x38\xf1\xe1\x27\xa7\xc7\x3b\x5e\xbc\x94\x0a\x9e\xf2\xae\x6a\x16\x91\x2a\x56\x3e\x70\xdc\x8d\x11\x01\x63\xd1\x84\xf1\xa7\xa5\x2c\x36\x9e\xdc\xcf\x46\xd0\x3d\xc3\xb6\x9b\xb1\x34\x8e\x89\xb7\x3c\x30\x06\xff\xda\xfa\x98\xad\x85\x13\x4d\x7e\x2a\x8e\x13\x5b\xa3\x98\x8b\xec\x74\x83\xc7\xc1\x75\x4b\xc2\x00\xfd\xa8\xf9\x9f\x7b\x6f\xe7\xd1\x24\x32\x42\x77\x55\x07\x30\x85\x84\x4d\x2d\xda\xfe\x58\xa5\x09\xe3\x4e\x1c\x41\x8b\x17\x68\xde\xcb\xea\x47\x77\x53\x41\xb0\xa2\xac\x80\x5f\xcd\x6c\x28\x93\x48\x68\x22\x6d\x45\xcf\xee\x71\xd6\xe7\xd6\x08\xe5\x91\x42\x07\x10\x84\x7a\xb3\x75\x8b\x18\x71\xa9\xbb\x76\x9e\xa0\xdf\xfa\x5d\x14\x50\xd5\xd9\x53\x56\xfc\xf8\xcb\xed\x81\x72\x45\x31\xbf\x6b\xf9\xfd\xc6\x63\xc1\xc1\x86\xc0\x0a\xf8\x09\xd5\x56\x5c\x6a\xb0\x40\x70\xd7\x9c\xc6\x4e\xc2\x18\x0a\x3d\x42\xc2\xdc\x44\xd7\x10\x9a\xa6\x44\x59\x37\xcd\x64\x79\x3e\xde\x55\x69\xaa\x04\xe6\x4a\xec\x7e\x79\x45\x32\xde\x7f\x47\x49\x34\xb2\xc4\x9e\x32\x9b\xad\x47\xe7\xeb\xa1\xac\xb6\x9d\xd5\x40\x25\x15\xdc\x53\x11\x60\xad\xcd\xd5\x57\x96\xcc\x02\x10\x95\xe5\x1c\xfc\x9e\x15\x45\xaf\x7f\x43\xa8\xe4\x1a\x0d\x8b\x59\xde\x74\x6f\x2b\x9d\x1c\xa1\xdb\x16\x6e\x21\x27\x5b\xb3\x40\xe1\x41\x2c\xba\xc4\xe5\xc1\x33\x1d\x37\xad\x39\xa5\x6d\xd4\xa3\x9b\x7b\xe3\x57\x53\x31\xc7\xcc\x8e\xbc\x54\x85\xcb\x69\xfa\x5f\xd7\x51\xe2\x59\x4d\x7d\xf1\xcf\xba\x46\x3c\x73\x31\x5d\x53\x3a\x06\xf4\xea\xbc\x34\xd7\xc3\x25\xcf\x11\x36\x39\x1e\x02\x6d\x38\x86\x87\x57\x2f\xfb\x99\xff\x15\x88\x63\xa1\x7c\x1e\xff\x90\xd5\x1d\x03\xdb\x48\xf5\x92\x50\x10\x96\xdf\x67\xb5\x5f\xbd\xbe\xcc\x9e\x0e\xb3\xed\xf6\x75\xf3\x6d\xf6\x74\xf8\x36\x7b\xfa\xba\xea\xee\xa6\x52\x63\x6b\x5d\x3e\x7e\x2f\xca\xf7\x1c\x74\x17\x17\xa2\x60\x08\x12\x03\x3c\xff\xbb\x9d\x38\x70\x39\x7d\x3a\x49\xc1\x70\x9c\x69\x07\x54\xe1\x44\x89\xbb\x9b\xb1\x73\x6a\x12\x66\xa3\x7c\x68\xc1\x3e\x59\x5c\xb8\xff\x4d\xa3\x24\x77\x06\xc5\xe5\xdc\x93\xd7\xdd\x58\xb6\x06\x22\xb4\x86\xcb\xf6\xe1\xea\xd6\x74\xf4\x49\x3d\xc2\x02\x26\xc0\xe1\xd9\xe7\x99\x1e\xa5\x1d\x58\x10\xab\x70\xe8\x9f\x9a\xaa\x3c\xdd\x54\x51\xf4\xfd\x65\x84\xd0\xcb\x53\x56\x4c\x73\x2f\x2c\x00\x15\xf7\x74\x50\x7f\x5e\x4e\x53\x8e\x90\xd1\xe7\x64\x21\xa3\xb1\xee\x3c\xb0\x81\xf1\x30\xff\x78\x06\x9d\x89\x76\x22\xc0\x9d\x70\x1e\x0b\x93\x54\xb9\x43\xe9\x4b\xa6\x35\x14\x0b\xc8\x72\x5c\x10\x63\x96\x0f\xc2\xa2\x28\x44\xcc\x18\x4a\x9f\x6d\x26\x26\x1b\x8b\x18\xc7\xf8\xdb\xea\x65\xf1\x37\xc3\x09\x2c\x52\x0c\x0d\x65\x7b\x0e\xf5\x7a\x74\xb7\x07\x8c\x50\xad\xb9\xa3\x92\x1b\xa3\x1c\x09\x23\x8c\xc7\xf6\x64\xbb\xf6\xde\x19\x8d\xac\xf7\xef\xb4\x7c\x6f\x73\xc9\x0c\x1d\x50\x46\x49\x2a\x06\x5c\x87\x36\x3c\xd7\x5a\x44\x96\x47\xf3\xce\x48\x32\x16\xe0\xcc\xc1\x72\x08\xf5\x26\xb2\xc2\x47\xe3\x5a\x27\xe9\x9e\xb9\x3c\xde\x45\x18\xe3\xc6\xf2\x56\x79\xf7\x02\x95\x87\xaf\xca\x16\x09\x63\xd2\x56\x59\xdb\xe9\x5e\xef\xba\x68\x1f\x8b\x89\xe5\x84\x3f\x5c\x8a\xb3\x50\x3f\xac\x8d\x7d\xc5\xa4\x4f\x58\x4c\x29\xf2\x7c\x3a\xf4\x13\x06\xb5\xfe\x8a\x45\xde\x5f\x9a\x10\xcc\xc1\xec\x3e\xd1\x5d\xe8\xba\x5a\xea\x5f\xbb\x77\xce\xe1\x2f\xf9\xc0\xfe\x31\x9d\x77\x71\xaa\x9c\x34\x7f\xfb\x71\x5d\x3c\xd1\x01\x02\xa7\x54\x6a\x84\xc5\x4a\xe3\xb7\x1b\x29\x49\xbb\xb6\x44\xa9\x30\xf2\x90\x1e\x0b\x4f\x1f\x64\xd9\xaf\x9f\x3d\xd1\xda\x2b\x56\xd8\xcc\xdd\x95\x6a\x15\x61\x3c\xb4\x06\x68\xdd\x55\x72\xd8\x24\xce\xf0\x8e\x61\xd7\x39\xd6\x48\x9b\x86\x86\xc8\xbc\x2c\xf4\x28\x54\xc3\x78\xc2\x06\x71\x78\x27\x80\xb6\x28\x4f\xa7\xac\xae\x6f\xe8\x79\xfa\xab\x84\x50\x16\x33\x83\x3e\x20\xd4\x4e\xcd\xd8\x63\x02\x5d\xb7\x34\x20\x6e\x8d\x68\x80\xd3\x52\x94\x8e\x6f\xf0\x16\x32\x9c\xb0\x34\xd4\xe8\xe9\x9c\xcb\x32\x7f\x16\xbf\x46\xbe\x35\x4b\x53\x8a\x04\xbe\xee\x3c\x9c\x14\x32\x4c\x0b\x1b\x6e\x16\x3a\x10\x96\x8a\x18\xcb\x61\x56\x8e\x85\xfb\xb7\x1b\xc5\x5e\x6d\xaf\x34\xb1\xb2\xd1\xfb\xd9\x93\x4f\xd7\xed\x37\x87\xe5\x7a\xb7\x7f\x5d\xcf\xbf\x7a\xd2\x35\xc2\xd2\xd6\xb6\x1f\x66\xf5\xb1\x44\xd4\xf3\x27\x1f\xf2\xd6\x04\x05\xbd\xeb\xcc\x61\x26\x98\x4e\x1c\xfd\xdb\x17\x10\x55\x23\x41\xa0\x5d\x7e\x95\x9a\x60\x32\x0d\xa8\x15\xe9\x38\x8b\x42\x0f\xec\x32\x26\x05\x47\xbc\xdd\xec\x0c\xbf\xf6\x22\xf7\x16\x1e\x53\x22\xf6\x01\x67\x44\xbf\x6e\x0a\xf4\x5f\x6f\xef\xdf\xca\x58\x35\xe2\x75\xa1\x2c\x93\x8e\x47\x48\x12\xa6\x83\xc8\x79\x70\x5f\x3b\x51\x9b\xab\xea\x40\xc2\xb4\x88\xd0\xa6\x11\x97\xa6\x35\x3d\xc4\xc4\xe6\x61\x10\x09\x04\x5d\x1c\x64\xa3\x6e\x78\xac\x0c\x40\x81\xe8\xe5\x89\x90\x10\x7d\x58\x54\x41\x98\x89\xad\x26\xed\x09\x9a\xb7\x52\x8f\x50\x87\x24\x0e\x40\x2b\x97\xc0\x9a\xe5\x79\x6b\x90\x61\x89\xd2\x1c\x9a\xf7\xa9\x80\xe0\xd5\xf4\x8d\x03\xa3\x10\x7d\x25\x31\x91\x78\x68\x86\x3f\x1b\x87\x2c\xa4\x43\x97\xfd\xb6\xed\x15\xa3\x48\x98\xfd\x94\x2e\x1f\xdc\x03\x86\x7d\x17\x4d\xd0\xd7\xbc\xd8\xd9\x86\xac\x3f\x9e\xff\xd6\xaf\xcf\x38\xd4\x29\x78\x2d\xb9\x85\x17\x31\x2f\xab\xaf\xb5\x15\xd6\x45\xcd\x9a\xc9\xd9\x13\x47\x61\x10\x69\x87\xde\xc7\x78\xef\xfd\xc0\x78\x77\x85\x55\x7f\x46\x8a\xe8\x1a\x11\xdc\xf3\x2b\x45\x29\x12\x47\xc6\x92\x5c\x56\x20\x2f\x1f\xad\x15\x57\x9d\x86\x99\x2b\xd7\x8b\x24\x0a\x2b\x4a\xed\x5a\x7c\x81\x77\xbb\xdf\x8f\x3f\x10\xa3\x56\x05\xcb\x6e\x2c\xdf\xa0\x02\x9d\xa9\x66\xc2\x92\x41\x62\xc6\x00\x31\xb5\xcb\x4c\x54\x1f\x4f\xe5\xf1\x46\xa9\x00\x89\x59\x62\xd1\xfd\x87\x1e\xaa\xb4\x04\xd9\x61\xcb\x3c\x31\xc5\xf8\x5d\x98\xb6\xca\x04\xad\x37\x58\x0d\xa3\x41\x71\xcc\x4c\x04\x4e\x24\xc9\x06\x72\xee\x8c\x5a\x9c\x52\x24\x67\x59\x35\x6f\xf3\xac\xdb\x33\xe3\x58\xa6\x48\xfa\x65\x2a\x80\xaf\xe7\x09\x57\x26\x89\x93\x00\xd0\x9f\xb2\x9b\xe1\x0e\xf2\x7c\x76\x84\xa2\xd9\x65\x0d\xbc\xc2\xf1\xf6\x82\x8c\x93\x38\xc0\x05\xb9\xf8\x28\x54\x55\xbe\x15\x59\x37\x1f\x79\x14\xa1\xab\xf2\x00\xa2\xda\x98\xe7\x76\x5f\x2e\x8e\x9b\x4b\x37\x19\x78\x2a\xb1\xfc\xbd\x1d\x99\xb1\x7b\xed\x3a\x08\x12\x23\x4c\x70\xff\xd6\xda\x58\xb2\x2c\x7f\x58\xd2\x2e\xdf\x0c\x21\xf2\x6c\xcd\x5f\x37\x7f\xce\x9e\x16\x9b\xf5\x8b\x6f\x91\x91\x50\xfd\x39\xea\xd0\x77\x8f\x50\x04\x4f\x59\x71\xcc\xcb\xe2\xb8\x10\xf7\xb9\xb3\xc6\x63\x22\x13\xab\x6a\xe2\xb4\xfd\x3d\x9f\x86\x6f\x95\x0c\xbd\xe0\x4e\xb0\x17\x93\xba\x18\x04\xed\xba\xe8\x54\x23\x7a\xba\x2c\x9d\x65\x4a\x7c\x93\x8a\x2d\x0d\x38\x52\x2e\x9c\x3b\x70\x2a\x89\x95\x88\xd1\xde\x5d\xcd\x66\xbb\xee\x6f\x40\x51\x56\x6e\xbe\x7f\x3a\xec\xb6\xb3\xd7\xfd\xac\x7b\x5d\x4d\x12\xdc\xcd\xcf\x15\x28\x6f\xae\x9f\xab\x4c\xdd\x60\xc0\xf2\x57\xa4\xdc\x55\xd1\xa0\x58\x4a\xe5\x2b\x8e\x5d\xb3\x09\x2d\x9f\x9f\x8c\x6a\x34\xed\xef\xec\x24\x26\x0e\x59\xea\xb3\xdb\x1d\xc6\xdf\x37\x0a\xeb\xc5\x5a\xe9\x89\xd1\x34\x36\x86\xa2\xf8\xd8\x7c\x36\x64\xf8\x22\x49\xd0\xd3\x3e\x2f\x4b\x35\xf4\x18\x92\x20\xb5\xdc\xc8\xc7\x4a\x5c\x5b\x51\xbe\x0f\x98\xb0\x4f\x4e\xd9\x30\xd3\xb6\xba\x57\x5f\x4e\x92\x28\xd2\x80\xdc\x0c\xad\x0b\xb9\x2b\x4f\x50\x16\xb0\x2f\xbf\x65\xf0\xfe\xfc\x81\x6a\x20\xb7\x0e\xd9\x24\x22\xc4\xda\x68\x6f\xa0\x7e\xf4\x68\xa1\xcf\xd3\x74\xa3\x71\x4b\xa2\x84\x52\xcf\x18\x6b\x8e\x4b\x68\x44\x96\x8f\x4a\x7d\x49\x12\x49\x81\xa8\x3c\x14\x5a\x2f\x74\x8f\xb7\x49\x88\x8b\x6e\xbc\x2e\x5e\xba\x3f\x31\x96\x76\xec\xf8\x99\x82\x8d\x59\x88\xd3\x59\x64\xc7\x62\x1c\x3c\x48\x48\xc2\xd1\xa4\xda\xb5\xcf\x5c\x4c\x80\xd5\xb7\xcd\xd7\x84\x92\x10\xa7\x38\x6e\xf3\x16\xe3\xd3\xfe\x46\x0e\x3f\x21\xc7\xbd\xfe\x05\xde\x27\xdb\x7c\x42\xe3\x30\xb4\xbb\x71\x0d\x0d\x7a\x90\xad\xbd\x7c\x13\x70\x92\xd0\xd8\x42\xc7\xc7\xb0\x85\xd7\x4c\x77\x69\x67\x7c\x87\xc4\x77\x4f\x23\x8f\x1a\xda\x7e\xdb\xae\xda\xde\x85\x82\x2b\x24\x59\xc2\x02\x6d\xfa\x64\xce\x53\xeb\x53\x4f\x0e\xfa\x84\x31\xeb\x85\xfa\xf3\x72\xc4\x9f\x39\x7d\xcc\x38\x8e\x15\x8c\x31\xa7\xb9\x50\x3f\x30\x91\x74\x83\x48\x86\x24\xb1\x4a\xad\x52\x4b\xbb\x23\xec\xdf\x2a\x00\xcb\x69\xe8\xc7\x28\x89\x8c\x25\x29\xa8\xca\xf7\xc6\xd2\xcf\xd5\xe3\x65\x98\x24\xc2\xf2\xa2\xd6\xd0\xcc\x5a\x0f\xfa\x3e\x85\x07\x49\x12\x90\x4a\x78\xf6\xd8\x43\xd3\x95\x6f\x90\x24\x31\x06\x31\x1d\xd6\xd6\x2b\x90\x41\xbb\x6b\xe4\x24\xc1\x50\xca\xcb\x2f\xf1\x36\xb0\xd5\x12\x4e\xad\xc4\xb5\x41\x71\xa1\x87\xd2\xc2\x25\x5d\x63\x1a\x02\x51\x83\x58\xe2\x0e\x9a\xab\xd0\x51\x92\xf2\xd8\x6a\xda\x8b\x8f\x2d\xa2\x0d\xc6\xdf\x27\x15\x36\xfd\x8f\x24\x89\x9b\x4f\x98\x5e\xc6\xbc\xaf\xd3\xfc\x67\x92\x82\x4e\xc7\xfa\x18\x0f\x5f\x97\xd7\xd8\xe1\xc9\xa4\x16\x86\x85\xbd\xd3\x6a\xcf\xbb\xe9\x0b\xc8\x88\x21\x0d\xe6\xc1\x6b\xec\x7e\x96\x5e\x4d\x64\x6b\x0f\x4c\x99\x42\xf6\xa3\x7d\x2f\x91\x29\x81\x0e\x45\xe2\x84\xe3\x7c\xde\x7b\xf2\xdb\x4a\x47\xc2\x71\x53\xac\xeb\x0e\x5c\x39\xc5\xba\x24\x8a\xa4\xd6\xcf\x47\x50\xc8\x55\x8d\xd1\x64\x4a\x2a\xc5\x70\x4b\xfe\x03\x41\x76\xa3\x47\x6b\x0d\xbe\x00\xf9\xd8\xd0\x63\xc4\x60\xcc\xc1\x4e\x58\x0f\x4a\x19\xbd\xae\xd6\xb6\x5e\x09\xd5\x83\xf0\x0d\xa6\xa4\xb7\xe3\x9f\x86\x30\x32\xae\x06\x19\x7f\xbc\x5e\x42\xad\x6e\xfb\x68\x09\xf0\xd8\x65\x04\x9a\xf9\x66\xef\xcd\x89\x04\x04\x01\x17\xc1\xce\xcb\x63\x7b\xfb\xc9\x60\x80\xb2\x4c\x0d\x9e\x23\x5e\xe3\x32\x38\xf8\xeb\x8d\xb2\x6c\x34\x88\x0b\x42\x31\xef\xd3\x94\xcf\x97\xf0\x80\x27\xb8\xbb\x5b\x76\xfe\x11\x01\xe8\x68\x2b\xe5\x41\x9a\x32\xcb\x8c\x8b\xc8\xf7\x2d\x54\x7d\x16\x9b\x87\x4a\x44\x2e\x82\x7b\x71\x11\xf4\x69\x90\x69\xbc\x1c\x78\x14\x30\x54\x12\xc7\x81\x47\x97\x62\x3c\xd1\xb8\xef\x17\x19\xed\x68\xf3\x5b\x9b\xbb\x75\x3d\xe0\x74\x6e\x2d\x8f\x69\x15\xd1\x18\x7e\x39\x3c\x5c\x78\x94\x70\x5c\x33\x4e\xac\xee\xa9\x7c\x47\x13\xbe\x3f\x6e\x39\x49\x93\x24\xf1\x88\xd4\xf6\xac\xb8\x33\xa5\x38\xa5\x02\x83\xa8\xa7\x4b\xde\x65\x6f\xff\x31\x4c\xe2\x72\x16\x07\xca\x0c\x70\xd7\xf3\xb2\xcc\x6f\xc4\x12\x39\x53\x12\xcd\xee\x53\xeb\xc9\x8b\xfc\xb1\xf4\xb4\x73\x84\x33\x13\xe1\x5e\xbe\x9c\xfd\x97\xff\x53\x1c\x84\xe8\xeb\x15\xf0\xab\xdd\x83\xfe\x03\x3d\xad\x3a\xe1\x71\x64\x90\x30\x29\xab\x77\xa8\x95\xbb\xa9\xb2\x63\x56\x88\x7c\x40\x47\x47\x78\xac\x42\xe5\x5e\xb1\x75\x37\xaf\x23\xbf\x3c\x61\x91\xdb\xc1\x72\xa1\xb1\x5e\x6b\x90\x7e\xe6\xdc\xd8\x40\x7c\x91\x29\x38\x5e\x3e\x42\xff\xf7\x34\x0c\xc2\x4e\x62\x5b\x64\xb9\x65\x40\x28\x4b\x44\xcd\x77\x9d\x22\x5b\x08\xe7\x82\x02\xe3\x6f\x35\x18\x94\x34\x66\xb4\xf7\x45\x96\x22\xcb\x3f\x7a\xb5\x8f\x1b\x89\x22\x9e\x26\x2a\xe9\x2f\x70\x31\xe0\xfa\x2f\x04\x52\xa7\x06\xc0\xa7\x06\x01\x4f\xc1\xbe\xe0\xb1\x12\xea\x3a\x06\x36\xee\x2b\x52\x05\x69\x27\x2b\xd7\x13\xd5\x8d\x0d\x22\x2e\x43\x19\xd2\xbe\x68\xe2\x3a\xd9\xcf\x25\xa5\xb1\x4d\x44\x58\x57\x15\x2b\x09\x74\xd7\x9a\x86\x36\x29\x5f\xe6\x7a\x21\x2a\xdd\x5f\xa6\x94\x2d\x34\x6a\x4f\x19\x34\x59\x26\xe3\xa5\x98\xd6\x5d\x04\xac\x3d\xcc\x3f\x2b\x0e\x25\x5c\xd3\x04\x49\x63\xd1\xbd\xbe\x0a\x2d\x70\xad\x59\xec\x62\x60\x16\xc2\xbc\x31\xab\x3c\x3b\x66\x32\x07\x2f\x6e\xee\x7a\x42\x08\xe8\xbb\x9c\xc5\xc7\x3e\x3b\x77\x7f\x25\x09\x3a\x04\xc8\x00\x78\x97\x31\xf0\x3a\xc5\xca\x01\x2c\x67\xee\xf6\x69\xb6\x7f\xd8\xbc\x3e\x1f\x9e\x37\x2f\xfb\x2f\x4f\x1e\xcb\xcd\x4d\xcc\xb0\x12\xb9\xdd\x10\x1d\x75\x58\xd7\xc4\x2d\xf8\x44\x89\xba\x41\xa0\xde\x53\x3b\x4c\x8f\xa2\x7b\x28\x23\xb4\x17\xc6\xf6\xe9\xf9\x2d\x86\x03\x7f\xf7\x42\x57\x24\x0d\x58\x84\x5e\xba\xa7\x8b\xea\x51\x66\xfe\x11\xd3\x20\x09\x79\xe0\xcb\xa1\x64\x95\xd5\x2f\x97\xd3\x78\x4f\x4d\x03\xc3\xc2\xb4\x1b\xbe\xd6\xe2\xa8\x47\x84\x4f\xae\x5b\xa8\x6c\x1d\x05\x02\x59\xba\x48\xf8\xcc\x69\x73\xb6\xaf\x77\xa5\x18\x47\xd2\x50\x13\x5f\x1e\x85\x3b\x9d\xdd\x19\x9e\x44\x31\x29\x52\x25\x69\x14\x8a\xc4\x0e\x48\xe1\x84\x30\xda\x79\xd1\xfa\x52\x57\x45\xaa\x83\x5c\xf3\x6d\x43\x23\x8d\x52\x4d\xc0\x8b\x51\xa3\xeb\xf8\xfb\xcb\xe2\x55\x34\x30\xd0\x97\x22\x69\x24\x2c\x27\xb8\x1b\xbe\xa9\xfa\x25\x49\x49\x62\x81\x2b\xc8\xf5\xe5\xd7\xdc\x32\xeb\xd1\xeb\xd7\x73\x22\x25\x92\x3a\x8b\xe4\x0c\xea\x3a\xf2\x3c\x30\xa5\xba\x0f\x40\x19\x89\xad\x32\x71\xdd\x3a\x0f\xb7\x5f\x89\x26\x0c\x2d\xcd\xfd\xeb\x7a\xf6\xf2\xe8\x4b\xd0\x49\xca\xb8\x64\xc6\x29\x27\xed\xce\xa0\x32\x27\xa9\x52\xdb\x18\x57\x9e\xa9\xdd\xd0\xdb\x18\xdf\x94\x87\xd2\x32\xc2\xe1\xbe\xe5\xb8\x33\x27\x1b\x72\xdb\x09\x75\xa0\x10\x89\x80\x54\x16\xfd\x8a\x4a\xd3\xd0\x4a\xa7\x58\x01\xdf\xf2\x04\x8b\xb7\x2c\xd7\x95\x4b\xae\x4c\x4e\xa5\x34\x25\x09\x7a\xd3\x27\xf1\x6b\x77\xce\x8a\x62\x70\x23\x91\x0a\xcb\x6b\x25\x72\xd8\x9c\xa1\xe8\x96\x4a\x2a\x24\x47\x4c\xc0\x9f\xfb\xbd\xaf\xc5\x4a\xa5\x94\x28\xfc\x8a\xb2\x8e\x7d\x57\xa9\x03\x69\xb1\x13\xe5\xb9\xac\x9d\x5c\xcd\xe7\x9b\x65\x2a\xc1\x78\x65\xef\x57\x50\xe5\xe9\x84\x2f\x78\x7b\x27\x4a\x95\x14\x31\xf8\xe5\x84\x0e\xa4\x8d\xce\x4f\xc2\xf8\xa9\xd2\x2c\xed\xea\x19\x1e\x00\xea\xd9\x4f\x91\xe5\x36\x51\x89\xc1\x27\xd7\x4f\x13\xc0\x20\x6c\x6b\x66\xee\x2e\x72\x28\x2b\x7e\x0f\x6c\x3a\x79\x7c\xcd\x12\xac\xc9\x6f\x0f\xbe\x47\x68\xe6\x59\x33\x52\x3e\x26\xed\xb9\xa1\x35\x96\x7b\x75\xae\x44\x0a\xca\x96\xfc\xa3\x37\xbd\x2f\x7f\x2c\xc1\x31\xdc\x13\x11\x30\x96\x48\x07\xa2\xec\x1f\x7a\x34\x0a\x22\x88\x83\xc4\x71\xb7\xbc\x96\x13\x91\x3a\x22\xc2\x20\xc0\x78\x96\x4b\x66\x2d\xca\xd3\xb9\x2c\xa0\x47\x02\x88\x90\x85\x91\xcb\x74\x6e\xb6\xcf\x93\x7b\x87\xb1\x7d\x1f\x97\xfb\x2e\xab\xef\x90\x75\xdc\x3c\x44\x44\x34\xc4\x6d\xe2\xf1\x57\xeb\x37\xe1\x94\x9c\xec\x24\xc2\xf3\xb2\x20\x65\xed\x25\x1f\x10\x3c\xde\x1c\x41\x11\x69\x88\x3c\x62\xaa\xfa\xe7\x05\x8e\x65\xf7\xa4\x91\xd1\x56\xf4\x26\x17\xd9\xe9\xbf\xa0\x2a\x8b\xcc\xe5\x82\x63\xfa\x8f\xbf\xfe\xc7\xdd\xa5\x75\x8b\x89\xa7\x9b\x70\x29\xa2\xbf\xd0\xe7\x22\x82\x28\xca\xdc\xce\xf9\xb5\x68\x4f\xd8\xbe\x41\xe1\x8e\xee\xcc\xc8\x7d\x27\xa2\x84\x54\x3d\x7d\x94\x4c\x10\x4d\xb0\x1c\x00\xb4\xf5\x87\xbc\x49\x2e\x68\x18\x62\x36\x46\x68\xbd\xac\xb2\x9f\x53\x6b\x5c\x50\x19\xfb\xac\xc3\xac\xaa\xc4\xc7\x74\x07\xf6\x7b\x9d\x60\x69\x8a\x87\x18\x9c\xa0\x3a\x42\xa1\x3e\x7a\x91\x48\x22\x98\xb4\x1c\x1f\x90\xb5\x3e\x19\x82\x51\x37\x95\xe3\x98\x5d\x88\x62\x59\xee\xdf\xba\xa0\xa5\x88\x59\xcc\x4d\xaf\x34\x08\x55\xf3\xf1\x24\xbc\x59\x50\xcd\xdb\x75\x09\x76\x37\x1b\x45\xc3\x45\x1c\x6b\x8c\x85\xd9\x32\x65\x2f\xe7\xe3\x1b\x95\x4a\x9c\xe3\x37\xbf\x7c\x78\x82\xae\xf1\xb1\x26\x38\x8d\x0d\xf7\xa0\x82\xc9\x40\x70\x99\xd2\x9e\xe4\xcb\xf2\xe3\x8d\xb7\x11\xbf\xb3\x09\xee\x68\x8a\x26\x16\xe0\x9d\xb5\x3b\x29\xb4\xb9\xfe\xab\x7f\xba\x34\x4d\xb1\x7c\xed\xd2\xfa\x5d\xfe\x6f\x8a\xe0\x26\x6a\xf9\xaf\x26\x8f\x2c\xc2\xc0\x92\x1a\x5e\x4e\x27\x07\x37\xee\x22\x9f\x42\x44\x3c\x95\x3e\x3d\xbe\xaf\x00\xea\xf5\x1d\x85\x08\x22\x64\x22\x2c\x42\x30\x07\x51\x7d\x17\x59\xb3\x15\x59\x35\x87\x7e\x15\x4b\x11\x07\x16\x85\x72\x7e\x13\x37\x2a\xe2\x7c\x37\x45\x90\x2f\x40\xe4\x15\x08\xfd\xd1\x15\x2a\x5e\xd9\x0a\x42\x1a\x89\xa9\x4c\xa7\x29\x5d\x5e\xd3\xf5\xb5\x7d\x34\xd6\xc5\x2e\x16\x18\x93\x1e\x3a\xd3\x42\x05\xc6\x56\x31\xda\x59\x70\x9f\xbe\x9c\x08\x1d\x58\xaf\xa7\x71\x5e\x5c\xaf\x6e\x79\xa7\x3f\x0f\xd0\xef\x5e\xe9\xac\xd9\x67\x37\x24\x05\x6f\xb9\x7d\x93\x7b\x40\x18\x18\x77\x74\x58\x41\x2c\x8f\x94\xf9\xba\x5e\x4e\x46\x02\x22\x89\xc1\x3f\x17\x27\xa9\xa1\x5a\x40\xd5\x64\xc6\x33\x66\xdf\xfc\xb5\x91\xea\x9b\xbf\x51\x62\x0b\xdb\x84\x31\x59\x9e\xd9\x17\x3d\x56\xe2\x64\x6b\x35\xc6\xc6\xbe\x00\xae\xbd\x48\xcd\xfc\xf2\x31\xe2\x1a\xf1\x3d\x84\x4d\x50\xd9\xfc\x0d\xfa\x6e\x93\x0e\x8a\x29\xf7\x8e\x56\xb3\xa2\x7d\xf6\x27\x54\x2d\x77\x3d\x0c\x67\x49\x30\xf8\xc8\x8f\x50\x20\x04\x6a\x7c\x23\x19\xb4\x4e\x58\x7b\x23\xa5\xc7\xd5\xf7\xbe\x9d\x51\x66\x26\x50\x96\xcf\x23\xaa\x32\x10\x0c\xb3\x13\x6b\x0d\x28\x2b\x69\xb3\x41\x1d\xfe\x46\x06\x10\xa3\x17\xf1\x06\xf9\xb9\xf3\x57\x65\x18\x32\x0c\x09\x39\xc9\xcc\x01\x6d\x01\x91\x21\x0f\x10\x03\xf3\x02\xef\xaf\x18\xd1\x17\xf9\xdf\x03\x27\xc8\x28\x08\xc3\xb1\x02\x5e\xbd\xeb\xb7\x78\x19\xa9\x48\xf4\x54\x09\xed\xc1\x3d\x9f\xef\x27\x68\x15\xd7\x95\xa8\x20\xb0\x3a\x69\xc5\x12\x4c\x55\x76\x38\x5c\x49\x0c\x05\xab\xbf\xd4\xda\x59\x5b\xf1\x01\xda\xf2\xfe\x39\xcd\x80\x9b\x06\x8e\xa4\xcc\x3a\xfd\xeb\xc5\x06\xf9\xdb\xe8\x6f\x5d\x83\xb4\x44\xf0\xa5\x2a\x2b\x58\xb4\x86\x43\xd7\x64\x12\x5c\x94\x42\x96\x97\x3b\x59\x02\xc9\x62\x4a\x2c\x95\xd4\x62\x1f\x06\x01\x72\xcd\x6f\x7c\xb1\xa4\x64\x09\x10\x0b\xc5\x77\x64\x65\xbe\x21\x8e\x68\xa0\x9d\x03\x7a\xc1\x98\x7c\xf9\x3e\xe4\xfd\xf9\xab\x2a\x42\x7f\x1b\x1e\xd0\xc0\xa9\x36\x62\x20\xec\xf0\x33\xa4\x5f\x44\xfd\x76\x70\xfd\xba\xdf\x93\x24\x1c\xce\xab\x9b\x71\x42\x99\x04\x81\x31\x5e\x28\xb3\xac\x3e\x56\xbf\xce\x59\xf5\x81\x99\x4f\x47\xd8\xee\x3b\x32\xc9\x9c\x23\x8e\x90\x0b\x9b\xa2\x1a\x1a\x07\x32\x31\x41\x20\x46\x25\x88\xd6\x5e\x19\x92\xd7\xbb\xae\x3c\x20\x98\xe0\x9e\x61\x94\x6c\x99\xd5\x2a\x3b\xe7\x60\x19\xfa\xc6\xef\xcb\x23\x9b\xe2\x82\xe6\xcd\x39\x53\x9d\xae\xe5\x7b\xe9\xdf\x95\xb3\x50\xa6\x43\x75\x86\xec\x74\x39\xad\xce\xa5\x7a\x43\x90\xc6\xcf\x89\xce\x1a\x91\x3c\x91\xc8\x2e\x55\x9e\xa1\xb8\xc5\xfa\x7a\x67\xf0\xb9\xd4\x94\x8e\x82\x96\xa5\x59\x35\x6f\x98\xe4\xec\x9e\xc5\x24\x18\xa8\xfc\x4e\xf7\xfe\x4f\x22\x8a\x31\xd2\xf3\xaf\x77\x51\x6b\x18\x65\x64\xa5\x88\x54\x12\x77\x98\x83\xfd\x5b\x55\xbe\x77\x4d\x0c\xf0\xd7\x4c\x7b\xf6\x9d\xba\xbf\x26\x04\x7d\xdc\xf9\xd7\xf5\xd3\x72\xfd\xf2\x38\x24\x63\x22\x52\x18\x89\xbb\xcd\x53\x79\x0c\xaf\xa0\x22\xb7\xb7\xf8\x91\x3f\x17\xde\x79\x73\xc9\x42\x91\x7a\x82\xf9\xfa\xed\x2f\x51\x28\x77\xee\x02\x21\x22\xbe\xfd\x9c\xf4\xb4\x33\xc2\x8a\x59\xba\x5e\x0a\x28\x4a\x87\xd4\x96\xb2\xe0\x6b\xdd\xed\x26\x3a\xd4\xb4\x17\x42\xf4\x7f\x05\x6e\x14\x1f\x26\xe5\x27\x93\x0d\x40\x48\x2b\x47\x05\x0a\xe5\xaf\x47\x25\xbf\xd2\x84\x0c\xed\x9d\x83\xbc\x64\xb9\xde\x67\x27\x09\xd5\x42\x9c\xae\x32\xe3\xc3\xac\x81\x34\x3c\x4c\x6d\x31\x54\x01\x43\x6d\x86\x4f\xb3\x78\xfd\xb5\x18\xd0\x74\xc9\x65\x37\xf9\xff\xce\x34\x9c\x0c\xa7\xe1\x16\xe0\x64\x8d\xba\x1e\x08\xc8\x7d\x3b\x10\x0c\xee\xef\x7e\x64\x79\x3e\x07\xd1\xd4\x4f\x97\x7e\xaf\x33\x60\xcf\x03\xa1\xb5\x3b\x3e\xf7\xe5\xa2\x12\x05\xdc\xaa\x6d\x52\x01\x8b\x59\x30\xea\x7d\x7b\x7b\x54\x41\x6c\x75\x2d\x4e\x59\xd1\x3c\x94\x55\xeb\x22\x4c\x69\x10\x87\x25\x98\xa3\xc3\x50\x85\x29\x45\xbc\xeb\xcb\xbe\x97\x5f\x68\x7f\xce\x1b\xfc\x2a\x94\x89\x97\xf7\x74\x8f\x71\x2d\x60\x4f\x54\xc4\x43\x04\x0a\xbd\x65\x4d\x7f\x9f\x71\x81\xa0\x22\x71\x80\xbe\xf8\xe1\x60\xd7\xc1\xde\x82\x7e\x86\x47\x92\x22\x31\xc3\x3c\xeb\xbf\x2e\x70\x81\x75\xbd\x3a\x9d\x3d\xbd\x0d\x51\x24\x49\x91\x19\xb6\x79\xcb\x2a\x3d\x54\x55\x70\xd5\xf5\xbe\x1b\x58\xa6\x22\x34\x3e\xfd\x99\xda\x6f\x9e\xfd\x33\x53\x42\x43\x5f\x9b\x12\xfb\x7a\x49\x45\x49\xea\x32\x78\xaa\x2c\x74\x97\x09\x1d\x14\x24\x2b\xca\x28\x5a\x46\x99\x19\xd7\xee\xfa\x66\x13\xe0\x71\x85\x1a\x3d\xa3\x89\xa8\xe2\x80\x23\xaa\x51\x5e\x30\x28\xbc\x40\xaa\x3d\xa8\xd6\x1a\xff\x57\x7b\x2e\xd6\xce\x47\x0c\x23\x3e\x94\xca\x23\x2a\x66\x01\xa2\x1a\xf6\xae\x38\x75\xf7\x36\x51\x00\x22\x2a\x4e\x4d\xc0\xfb\xf8\x38\x32\xe4\x4e\x1c\x5c\x15\x1b\x40\x3c\x9f\xd0\x7a\x91\x35\x19\x0c\x70\xb0\x83\xa4\xdd\xc4\x59\x53\x09\xb7\x6a\x03\x3e\xef\x6a\x49\xf5\xab\xf2\xb4\xbf\x2e\x90\x50\x89\xa6\x98\x90\x79\x2c\x73\x47\xe1\xf9\x0c\x79\x1f\x68\x51\x29\xe7\xc6\x52\xc1\xcd\xf2\xcc\xab\x99\xfc\x77\x98\x78\x3a\x6e\xd7\x4d\x24\x02\xeb\x01\x1f\x00\xee\x44\x78\x6f\x2f\x52\x25\x23\x61\xa4\x4b\x65\x57\x3f\x21\x1c\x9b\xaa\x4a\x12\x0b\x65\xa8\xa1\x79\x51\xcd\xaa\x2f\x2a\xbf\x52\x06\x20\x4a\x0a\x89\x44\x94\xbb\xd5\xd3\xd3\xea\xf5\xb0\xdb\xaf\xb6\x87\xf0\xb0\xd9\xae\x7c\x22\x5f\xa9\x88\xa0\xb9\xfd\x04\x75\x5d\x16\x07\x7a\x67\x8d\x2a\x2a\x46\x45\xdf\x5d\x8d\xd2\x08\x86\xa6\x14\xd8\x5a\xca\x67\x28\x6a\x51\x65\xd9\x20\xbf\xab\x74\x68\x01\xf8\x07\xbb\x8b\x79\x9a\xfe\xae\x55\x23\x61\xb8\xae\xcf\x6a\x78\x11\xa5\x58\x0b\xfa\x08\x0d\x96\xd1\x8c\xa7\xa3\x4e\x53\xac\x89\x3a\x79\x16\x48\xa2\xb4\x52\x36\x3b\x84\xec\x97\x0b\x4b\xd4\x36\x95\xa3\x21\x0a\x04\xc5\xcd\x09\x73\xd7\x1e\x95\xe0\xdb\x64\x8c\x76\x57\x7d\x2e\x8b\xba\xbc\x2a\x9d\x70\xbd\x4c\x48\x31\xd2\xf3\xcf\xd9\xe2\x77\x84\x3b\xfa\xcb\x4d\x04\x58\x99\x83\x88\xc6\x76\x58\xf7\x6f\xe2\x4e\x60\x53\x99\xd8\x18\xe1\x02\x98\xa8\x56\x71\x19\xc9\x3e\xdb\x33\xe1\xe6\x17\xd1\x41\xac\xb1\x42\x72\x0c\x62\xd8\x96\xef\x9f\x71\xfb\x11\x1d\x70\x61\xcb\x5e\xb2\x13\x48\x51\xfc\x50\x9f\xa1\xfb\x75\x18\x58\xae\x56\x17\x53\xc4\xaa\xb3\x4f\x6c\x01\x7f\x55\x92\xa0\xf5\xed\xb0\x7c\x3d\x92\x44\x87\x09\x47\xa9\x5e\xab\xb3\xe2\xc0\x4d\x5d\x23\x24\x08\xb8\xd9\x7e\xf9\xa3\x2a\x73\x9f\x5a\xd3\x11\xf3\x30\x88\x9f\x65\x5f\x81\xa6\xa3\xd4\x6a\xb8\xef\xa0\xc1\xe4\xe5\x10\x41\x7d\xf3\x5d\xa2\x34\xc2\xd0\xc1\x6e\xff\xaf\xab\x0a\x83\x1b\x42\x67\xa3\xaf\xad\x23\x09\x98\xbf\xb4\x4f\xed\xd0\xf5\xde\xd5\xd4\x24\x56\x78\x32\x74\x76\x2c\x32\xa8\xf7\x5e\x24\xff\x24\xe6\x71\xfd\x89\x68\x4a\x11\xed\x29\x31\xf2\x83\xf4\xea\xfe\xa5\xa9\xa6\x22\xf5\xea\x9a\xed\x7a\x5f\x17\xce\x64\xf6\xfb\xbf\x66\x11\xf5\xdc\xf0\x4b\xf1\x51\x6f\x45\x5d\x83\xde\x65\x85\x82\x27\x51\x37\xad\x3f\x85\xb1\x05\xc7\x03\xe9\x2f\x62\x41\x34\xa8\xbb\xeb\x9d\x10\xcd\x12\x8e\x05\x90\xb3\x73\x99\xe7\xe5\x0e\xce\x0d\xb8\xba\x7e\x1b\x6f\xf7\x9c\x44\x9f\x3b\x7d\x3a\x0e\x12\x3a\xb4\xe3\x16\x15\xe8\xac\xa9\x3d\x25\x60\xfe\x71\x6b\xd6\x8e\xeb\x11\x74\x4c\x2d\xf6\xeb\x24\x7e\x5d\x27\xc2\x74\xcc\x42\x14\xe2\x5d\x6c\x17\x2b\xc7\xbb\xe4\xdf\x21\x4e\x22\x4f\xdd\x8d\x99\x28\xc4\xc7\x90\xf1\x8e\xa0\x13\x6a\x0b\xe8\x85\xd6\x23\xe2\x3f\xa2\x13\xd0\xe8\x2b\x7c\x7b\x5d\x6c\xd6\x2f\x87\xe5\x6a\xb1\x7e\x9e\x3d\x79\x94\x9c\xe6\x8a\xa1\xd0\x84\xe5\x74\x44\x27\x19\x4f\xc3\x1e\x17\x7e\x7b\x4a\xa5\x21\xc7\xfd\x70\xfb\x75\xfe\xb4\x5e\x1c\x16\xaf\x9b\xef\x4b\x64\x1a\x5e\xcc\xbc\x6f\xa8\x53\x49\x65\xe8\xea\xb8\x1e\x33\x73\xc7\xc1\xd4\xa9\x4c\x30\xb0\x00\xbf\xce\x79\xd9\xc5\x00\x75\xaa\x0d\x67\x83\xaf\x3a\x86\x4c\x69\xc1\x18\x09\x7d\x38\x62\x0b\xd5\xd7\x5a\xbf\x60\x49\x72\x27\xba\x42\xb4\x48\x15\x46\x08\xeb\xec\x58\xcc\x1a\x5f\x08\x78\x7b\xde\x4a\x12\x60\xf9\xcd\x29\x2b\xd6\x4e\x9f\x65\x84\x4b\xd7\x92\x00\x66\x54\xd7\xdb\x6e\xb7\xd4\x8a\x51\x44\x81\x60\xa5\xa4\x2b\xe5\xf0\x0f\x6a\x83\x60\xbe\xa3\x21\xe8\xf6\x94\xc6\x60\xf8\xeb\x6a\xe2\xdd\x7e\x28\x65\x04\x12\x33\x89\xe6\x2d\x87\x06\x66\x36\x12\x87\x61\xe7\x7e\x2f\xd1\x52\x62\xf4\xec\xfb\x90\xef\x94\xe8\xf6\xe1\x50\x55\xf5\xf4\x94\x49\xff\x47\x60\x24\x22\x4e\xab\x24\x53\xe2\xaa\x3a\x48\x43\x2c\x90\xf2\xa4\xe3\x73\x10\x95\x1e\xb9\xbd\x1a\x38\xc7\x52\xa8\xf7\x7c\xd7\x94\x67\xf4\xc9\xbb\xbb\x4b\x5b\x6f\xec\x6b\x93\x5b\xd7\xe2\x26\xfa\x4a\x83\x61\xa9\x05\x4c\x37\xd5\xa5\xbe\xa5\x33\x4f\xb4\x49\x93\x38\xf5\xe9\x1d\x2b\x26\xd8\x67\xfa\x21\x50\x91\x23\x4c\xf0\x84\xc1\xb7\x4a\xa0\x21\x30\x5c\x79\x82\xa3\x1c\x3e\x5e\x32\xf5\x03\xbc\x74\x8b\x6d\x4d\x3c\xac\x13\x35\xa9\x2e\x5d\x5b\x18\xa9\x0e\x39\xb2\x40\x80\xfd\xe8\xf8\x86\x30\x36\x18\x4a\x28\xe0\x57\xf3\xd8\x0d\x3b\x84\x9a\x25\xaa\xd3\x6b\xd8\xf5\x05\x5e\x10\x25\x02\x27\x50\x1f\x1b\xba\x05\x9c\x83\x48\x11\x9a\x8e\x08\x43\x7f\x40\x31\x2b\xf4\x2d\xf1\x67\x77\x09\x89\x42\x03\x5e\x94\x00\xb1\xbb\x8e\x63\xe1\x6a\xa3\x01\x42\x20\x8d\x47\x74\x5d\x1f\x5f\x8b\xac\x8b\xf2\x01\xe1\x4e\x1f\x46\x1f\x4c\x59\x1d\x8a\x8f\xd3\x6f\x93\xdf\x32\x12\x59\xea\xdb\x8f\xff\xaf\x4b\xf6\x1f\x7f\x21\x4d\x8d\xd2\xbe\xfc\x65\xdb\x94\xe7\x7b\x0a\xfd\x9f\xba\xcc\x40\xa5\x41\x15\xd3\x63\xd6\x7a\x78\x93\xa1\xa1\xc0\x30\xa6\x6e\x77\xb8\x41\x7a\xc8\xb5\xb3\x38\x44\x95\x39\x4c\x8e\x6d\x3a\x47\xac\x2f\xf7\x81\x38\xd0\x28\xfe\xf1\x58\xe6\x70\x72\x85\xb3\x9f\x16\x93\x4f\x1e\xcf\x53\x12\x0e\x98\x5e\x3e\x8d\x32\xb8\xcb\xb8\xd6\xa9\xd7\x45\xb2\xbb\x84\x25\x64\xf4\x0f\x9e\x52\xe5\x09\xed\x70\x7b\x0f\x56\x9d\x61\x01\x29\x13\x08\x1e\xcc\xea\x17\x38\xe6\xd9\x11\xb3\x7a\xb7\x9f\x4e\x04\x21\x25\x9e\xb9\xac\x11\xb9\xff\x04\x13\x1b\x70\x8a\x8f\xf0\x57\xc7\x36\xfe\xf2\x02\xef\xbf\xdf\x45\x42\x83\x10\x21\xd5\x4e\x62\xe3\xbe\x1a\xf9\x3f\xc6\xd7\xa8\xc8\x33\xbb\x3e\x7f\x3c\x88\x5c\x75\x25\xc9\x20\xd3\x98\x38\xdc\x6e\xf7\x27\x49\x94\xa5\xfa\xfd\x26\xf2\x4c\xef\x90\x66\x70\x98\xbe\x19\xaf\x43\xa9\xa9\x0f\xe9\x3d\x38\x99\x9e\x01\xbd\xef\xf4\xb3\x8e\x05\xed\xfc\x2d\x0c\x47\x79\xe1\xc5\x1b\xe4\x23\x99\x25\x02\x8a\x00\x86\x70\xbe\x7f\x59\xbd\xdc\x22\x0f\xfc\xd4\xf0\x02\x95\xc6\x78\xba\x3e\x95\xc7\x6f\x99\x55\xe2\x19\x99\x08\xae\x9b\x8e\x35\x82\x5b\x9e\xca\x63\x07\x5d\xb4\xc4\x86\x93\x05\xa0\x45\x84\x86\xdc\xb9\x82\x9f\x3b\xa8\x32\xa8\x77\x90\xe7\xe5\xa5\xf9\x52\x5e\xfa\xd9\x04\x89\x42\x70\x0b\xae\x71\x57\xe3\xd7\xb5\x71\x89\x80\x9c\x4c\x95\xd1\x20\x70\x0d\x20\x93\x54\x74\x02\xa9\xab\xba\x01\xb8\xa5\x36\x4d\x00\x74\x88\x86\xe8\x2c\xcf\xa6\xd1\x55\x30\x5c\xa7\xe0\x61\xcc\xad\x8b\xe4\x1d\x1b\x13\x84\x29\x52\x4b\x28\x51\xcc\x2f\x55\x31\x95\x0f\x1b\xcf\x31\x13\x24\x02\xb3\x93\x8e\x0c\xcb\x6d\x93\x37\xe7\xbc\x09\x04\x44\x56\x18\xb7\x34\x59\xb3\x84\xd6\xa9\xad\xee\x10\xd7\x12\x13\x28\x81\xc2\x4d\xf3\xcd\xd7\x97\xfd\x9f\xae\xe4\xcb\x3f\x64\x18\x52\x13\xf5\xda\x06\xd6\xd9\xc6\xd8\xc5\x43\x39\x3d\xc7\x26\xf7\x0d\xe3\x00\x6c\xdc\xa2\x68\x5e\xe1\x27\xf4\x11\xd8\xf1\x8c\x30\xa1\xb0\xd2\x94\x87\x53\x76\x3f\x16\xde\xf5\xb5\x95\x10\x4f\xe5\x71\xed\x6a\xae\x2d\x53\xc5\xf5\xeb\xdd\xbb\x83\x86\xd0\xa9\x58\xbc\xec\x36\xaf\xde\x6e\x31\x51\x64\x05\xae\x84\xd6\x4f\x9b\x45\x53\x3e\x7d\xd9\xdf\xb6\xf3\x4c\x14\x29\xa7\x5a\x0c\xea\xc7\x12\x72\x38\xde\x20\xca\x30\x11\x4d\x89\xe9\x8a\x84\x57\xfb\x2f\x73\xd1\xa8\xb7\xdf\xa6\x51\xaf\x7b\xf0\x62\x43\x22\x83\x47\xe3\x8d\xd4\x95\x21\x5a\xa2\xcf\xf7\x6d\xb5\x43\xd9\x94\xc5\xd3\xfa\xe1\xc1\xbf\x08\x63\x46\x05\x9e\xc4\x2a\xd7\x50\x3d\x56\xe5\xe5\x4e\x91\x8f\x61\xb1\xa5\xb9\x74\xe0\x40\x4b\x37\x87\xa2\xbd\x37\x69\xc4\x89\x89\xc3\x00\x7d\x69\x79\xf9\xd8\x95\xa7\xbf\x19\x35\x37\x71\x94\x58\x7e\xba\xd5\xe3\xd3\x70\x2f\x31\x09\x23\x7e\x7b\x7e\x88\x3e\x2f\xbb\x36\x3c\xd0\x18\x47\x43\x92\xc7\x21\x6b\xce\x9d\x1f\xe5\x22\x0a\x43\xe7\x8b\x6f\x0a\x40\xda\x99\xe9\x63\x8e\x7f\x21\x55\x12\x1d\xd6\x2f\x4f\xdf\x07\xa5\x40\x46\x90\x08\x43\x92\x05\xbc\xdb\xfc\xd3\xbd\xdb\x4c\x1e\x40\xa4\x1c\x37\x96\x6d\x05\x5a\x34\xf0\x6b\x79\x11\xfe\x96\x92\xd9\xda\x8c\xf3\xa5\x99\x5f\x3e\xec\xb9\xfc\xf7\xe6\xaf\x54\x09\x02\x98\x2c\x24\xcb\x33\xd6\xe3\xe6\xcd\xc7\x7b\xb8\x51\x29\xc7\x01\xfb\xdf\x8b\x3e\xba\xca\x81\x87\xb2\xfa\x1c\x41\x64\x94\xb0\xb4\x34\xf3\x2c\x17\x85\xca\x4a\x4c\xa5\x94\xde\x92\x9c\xf4\x35\x4c\xbb\x5a\xb2\xa6\xec\x80\xce\x65\x7d\x25\xd7\x76\xe7\x5d\x34\x8d\x3c\xe9\xb3\xd5\xf4\xbb\x8a\xeb\x18\x9d\x58\xbe\xdc\xf2\x1d\x85\xc3\xa7\x8d\x80\x8a\x7b\xea\xad\xb5\x61\x8b\x29\xe4\xcd\xe8\x34\xc4\xdd\xa2\xb6\xfa\x00\x65\xd5\x6b\x5b\x4c\x69\x7e\x8d\x4e\x81\x8c\x9c\x1d\xff\xa9\xb4\x12\x88\xce\xfa\x92\x35\x0b\xe1\xf5\x47\x89\x01\xb0\xd1\xc0\xfa\x24\xaa\xce\xc1\x41\x6f\x74\x10\x99\x35\x26\x4c\x99\x33\x01\x7f\xc0\xa6\x98\xc3\x9b\xc8\xcd\xed\xb4\xc2\x5f\x81\xa3\x8c\x89\x2d\xd9\xad\x85\x89\xed\xcb\x07\xb0\x88\xe5\x61\x2f\x1a\x04\x14\x04\xeb\x63\xae\x68\xf4\xa0\xfc\xf7\x08\x42\xe0\x3b\x27\xcc\x9a\xb6\xf5\xb6\xb5\x8a\xb2\xb2\x70\xa0\xd8\xe1\x44\xa2\x41\x90\x86\x2e\xd0\x5d\x01\x7c\x29\xed\xd1\xda\xd9\x63\x34\x08\x13\xc0\xbd\xd3\xd2\x1f\xaf\x7e\x39\xfb\x6a\x22\x00\x76\x6f\xa1\xd0\x20\x4c\x43\x88\x06\x6a\x32\x96\x66\xba\x2f\x45\x70\xdd\xa2\x80\x53\x4b\xf7\xb8\xcc\x6a\xf1\xb3\xe7\xec\xa0\x41\x44\x43\xcc\xe6\x59\xcc\xfd\xa6\x78\x77\xd2\xc3\xbe\x39\x31\x58\x68\x79\xca\x0a\xe9\x0b\xf7\x69\x10\x09\xe5\x09\x6f\x66\x79\xde\xba\x75\xdd\x4f\xba\x1a\xa8\x11\xa1\x84\xbf\x0a\x6c\x99\x68\x93\x41\x15\xf5\x44\xd7\x34\x20\x01\xa5\x8e\xb5\x0b\x01\xc4\x98\x25\xbb\x5c\xe7\xb9\x69\x40\x44\xea\x8b\x38\xbe\x95\x8d\xc5\xe2\x3c\x94\xd5\xe6\xdc\x2b\x64\xba\x9e\x94\xc7\x48\xe0\xbd\x29\x60\xf3\x26\x0a\xe1\x7f\x2b\x8e\x03\x24\x19\xec\xd8\xba\x5c\x40\x7a\x3a\xce\xa3\x9f\x4d\x02\x8e\x8e\xec\xf6\x75\xbd\x79\x5d\xef\xff\x44\x6d\xf4\xc3\x6e\x3f\xf3\xa7\x60\xdb\x45\x22\x0a\xe0\x7c\xa8\xa1\x79\x81\x5f\x56\x03\x66\x07\xa0\x27\x82\xa2\x93\x2f\x98\x00\x25\xd1\x90\x7e\xbf\xfe\x94\xa0\x86\x06\x9c\x11\xfc\x22\x96\xee\xa8\x35\xbb\xb6\x58\x42\xd8\xe5\x4d\x68\x90\xb2\x54\x3a\xb7\xf1\x5f\x17\xab\x49\xe8\x5b\x04\xc5\x8d\xcd\x7a\x44\xb7\x2a\x6a\xc6\x2f\x2e\x68\x40\x5d\x08\xed\x28\x4e\xa0\x44\xa5\xcf\x65\x3d\x59\x38\x82\x6a\xdc\x8c\x0e\xfa\x8a\xe9\xff\xf6\xac\x95\x5a\x7b\x81\xe4\x65\xf6\x33\xd3\x50\xe8\x69\x0d\x19\x0d\x14\xd1\xe8\x1b\x66\xf5\xe2\x2d\x3b\x6f\x45\x5d\xbf\x97\x95\xbe\x3d\x2d\x34\x09\xd0\x34\xd9\xa1\xc1\xb9\xbb\x9c\x26\xf7\xd2\x9c\x4a\x17\x21\x9d\xf9\x60\x45\xe7\xcd\x39\x94\x9e\xfb\x8f\xf1\x5f\x06\x9f\xac\xfd\xdf\xee\x76\xa0\x28\x46\xd1\x44\x5d\x43\xd5\xec\xab\x8b\x63\xbe\x1a\xaf\x7d\x30\x32\x70\x64\x27\xfb\x4a\xfc\x84\xfc\xda\x20\xa1\x81\x89\x28\x75\x5c\x66\x7a\x77\xc9\x50\x9a\xb5\x0b\x00\xd0\xc0\x80\xa5\x50\x17\x1e\x82\xf9\x50\x56\xde\x98\x1c\xaf\xae\x30\x08\x02\xdc\x86\x35\xe4\xe0\xd0\x42\xb9\xc8\x4e\xd3\x5e\x29\xa7\xdc\x45\xba\x4e\x65\xe1\xc9\x45\xdb\x06\x4b\x26\xf8\x3c\x5b\xbf\xec\x87\x79\x71\x1a\x06\x8a\x86\xbe\xe6\x3e\x43\x82\x1c\xbf\xdc\x5b\xf3\xdb\xc2\x12\x17\xbd\x7e\x31\x0d\xc3\x28\xb1\x32\x25\xe2\xfc\x20\xa4\xff\x6b\x24\xc0\x45\xf0\x1a\x87\xc8\x1d\x4d\x77\xd7\x8b\x25\x3e\x69\x67\xf9\x64\x91\x2d\x7b\xd2\x27\x8e\x6c\xd5\xb3\x0d\xf8\x63\xb7\xdb\xab\x2b\x8c\x41\x21\x23\xf7\x23\x74\x9b\x57\x98\xa4\x0a\xb9\x80\x67\xbe\x52\xa9\x33\xd8\xc6\xd7\x26\x2a\x40\xe1\x8c\xec\x74\x76\x0c\xf7\x96\xad\x50\x77\x37\xd2\xa0\x9c\x09\xf6\x65\xb7\x7b\x2b\xcf\xad\x7f\x71\x35\x91\x43\x4e\x28\x83\x29\xc0\xc2\x9e\x94\x57\xda\x55\x34\xe4\x32\xb5\x28\xd1\x2e\xbd\xe4\x81\xa2\xfe\x67\xb9\x89\xd1\xf2\xc3\xcf\x3b\xcf\x01\x2b\xbb\xbb\xb1\x17\xcc\xc4\x2e\x3a\xb0\x83\x21\x05\x04\x0d\x05\x57\x92\xe0\x27\x7e\xf9\x32\xdb\xef\x67\x2f\xdb\xd7\xcd\x1f\x7f\xce\x5f\x97\xdf\xff\xec\xba\x68\x2e\x3c\x99\x46\x6b\xcc\xfa\x2d\x3a\x94\x8c\xab\xce\x9d\x99\x43\x73\x8b\x71\xee\xfa\xbf\x26\x5f\x43\x4a\x9b\x13\x43\x1c\xed\xd8\x79\xbd\xc9\xad\xeb\xf6\xf2\x50\x39\xd9\x9b\x6e\x15\x74\x79\x14\x1a\x6a\x66\x99\xf9\xe4\xe5\x63\x91\x67\xbf\x06\x36\x32\x0d\x75\x1c\x24\xcc\x27\x00\xb0\x7a\x67\x80\x35\xa7\x21\x10\x83\xf1\x97\xa2\x6c\x32\x63\x67\xa3\xd5\xd8\xf8\xd4\x95\xa2\x21\xc4\x32\xd5\x4e\x39\x23\x2b\x8e\xd6\x3e\xec\x66\x05\x70\x85\x29\x65\xfb\xb9\x1f\xc5\x09\x61\x85\x55\x06\x8d\xa8\x3e\x6e\xa4\x66\xfc\x65\xa9\x95\x72\x43\x06\x50\xe6\x6f\x66\x88\xa4\x31\x6e\x82\xfb\xeb\x32\x6f\x1a\x1a\x4e\x30\x57\xaf\x44\xae\x56\xc5\xcf\xa1\x86\xaa\xed\x11\x05\x60\x25\x4e\x5b\x47\xef\xa1\xac\x86\x22\x3f\x34\x0a\x13\xa9\x6d\x75\x18\x52\x37\x7a\x52\x96\xdb\x6b\x29\x0a\x8d\xe5\x8f\xc1\xfa\x18\xfd\x3c\x7b\x99\x8d\xa7\x6e\x14\x91\x10\x97\x6e\x0e\x47\x28\x74\x8d\xa9\xa5\x5e\xc8\x98\x46\x11\x0f\x63\x27\x46\x32\x7f\x82\xe2\xf8\xd6\xf4\x2d\x9c\x75\x15\x6f\x3f\xb3\x1a\xf3\x95\x97\xa2\x99\xbc\x4c\xc4\x53\xf4\xa9\x2d\x03\xb8\x1f\xf7\xcf\xa2\x26\x34\x22\x71\x1a\xb4\xef\xb8\x6b\xad\xcd\x65\xe6\x31\x0c\x34\x22\xa9\xc2\x64\x9a\x0f\x4e\x7f\x3d\xcf\x0a\x3d\x92\xe8\x9c\x5a\x99\xfe\x42\xc9\xb0\x06\xfc\x94\x15\xd9\xf3\x30\xc0\x43\x23\xa2\x25\x02\xd8\x5e\xa1\xee\xf6\x9b\xf6\x8f\xc2\xd9\x2c\x8f\x15\x40\x97\xc3\xa2\x11\x65\x0c\x35\x0a\x76\x7b\x87\x42\x14\x7d\x93\xd4\x98\xae\x76\x91\x1b\xff\x57\x1d\x73\xb7\xb8\x57\xc5\x31\x2b\xa0\xa3\x64\xff\x96\x55\x53\x1b\x35\x62\x44\x63\x2a\xab\x9d\x16\x45\xa9\x61\xdf\xd9\xe6\x34\x62\x71\x1c\x86\x3d\xbe\x1e\xf4\x20\xc3\x40\x23\x66\xa4\x37\xb3\xfe\x59\x4a\x4b\xd2\xe3\xc9\xd6\xef\x15\xa8\x4d\x66\x4b\xcc\x24\x1e\x1a\x35\xc2\xdb\xfd\x6e\x06\x7a\x08\x12\xa1\x11\x27\x16\x6d\x79\x16\x1f\xfb\xf2\xb1\xac\x8e\x65\x67\xa9\x45\x3c\x8d\x98\x8d\x3c\xb5\x86\xd6\x64\xae\x71\x11\x33\xc7\x4c\xb2\x2d\xab\xa2\x6e\x44\x75\xaf\x46\x7b\x32\x21\xb8\x01\x8c\x1f\x3a\x4e\x09\xc7\xc2\x82\xe7\x6a\x51\xf4\xdf\x26\x0d\xe3\xb0\x67\xd2\xdb\x89\xec\xc9\xd2\xf2\xac\x74\x36\xe4\x72\x9a\xdc\x5c\xb8\x2c\x15\x22\x0c\xb3\x81\x90\x1f\x8d\x64\x98\xb0\xb4\xab\xe4\xfa\x91\xc3\x13\x88\x9f\x93\xb3\x22\x92\x54\xd8\x3c\x8b\xc8\x8a\x17\x68\x9e\xc4\xa5\x50\x6f\xeb\xa2\xb5\x1f\xb3\x9f\xf0\x6a\x61\x10\x43\xca\x7c\x1a\x49\xad\x71\x17\xeb\x32\xae\x2f\xf0\x6e\x2d\x0d\xd7\x41\x31\x82\x3e\xc2\x23\xd8\xcc\xb0\xdf\x61\x6f\x44\x2f\x69\xa4\x12\x8b\x6e\xa8\x0b\xd1\xa8\xb7\x2f\x50\x95\x93\x27\xd4\x84\x62\x1e\x5c\x7e\x3c\x8b\x5f\xed\x49\x76\x93\xdf\x81\x46\x3a\x26\x82\xd8\x7d\xd9\xe3\x1b\x06\x5b\x7a\xa4\x0d\x20\x37\xcb\x3c\x6b\x4e\xbd\x41\x79\x97\x82\x8d\x46\xc0\x23\xac\x23\x78\xc9\x8e\x50\x65\xe2\x67\x3d\xab\x8e\xed\xa8\xf4\xf3\xc5\x84\xb6\x9a\xb0\x28\x4f\x70\x50\xa2\xd0\x99\x16\x4d\x79\xd0\xe2\x90\x15\xfa\xca\xf2\x8a\x4c\x04\xa2\xc3\x78\xda\x02\xe1\x7a\xb2\xdf\x98\x24\x42\x81\x1e\x3b\x07\x5e\x41\x95\x55\xb7\x99\x19\x1e\x61\xf0\xaf\x42\xba\xad\x2d\x34\xb3\x4b\x25\xe6\x65\x59\x37\xc3\xc2\x10\xff\xba\x46\x07\xc6\x2d\xdc\x6d\xf6\x0b\xf2\x45\x99\x97\x97\x89\x59\x43\x02\x2e\x70\x31\x1c\x50\x00\xa2\x6a\x10\x7a\x86\x72\x37\x63\xa1\x95\xf1\x48\x93\x30\xb2\xe4\x98\xeb\x97\xff\x5a\x39\x3d\x0a\x4a\xc2\xd4\xb2\x62\xf6\xd8\xf1\xd5\x49\x64\xf9\x2d\x56\x0d\x4a\xa2\x48\x61\xb5\x40\x6b\x55\x66\xc5\x71\xad\xf7\xe5\xc2\xee\x0b\x99\x9c\x16\x35\x51\x12\x31\x6d\x39\x26\x5d\x8a\xb2\x3d\xcc\x87\x13\x8e\x44\x71\x92\x9a\xde\x91\xee\xb4\x07\x46\x4b\x85\x44\xb1\x2d\x0c\x39\xba\xfc\xc2\xa3\x17\x83\xa7\x24\x4a\x6d\x26\x14\x01\x93\x95\xee\x8b\x05\xda\x73\x41\x9c\xa7\xcf\xa3\x95\x43\x01\xe5\xf9\xe1\x7c\x56\xdd\x5d\x80\x60\x12\x69\x21\xda\x69\x3f\x4e\xf9\xb6\xad\x29\x8c\x35\x3f\xc4\x47\x55\xe6\xf9\xeb\xa5\x78\xf7\xb5\xe4\x94\x10\x30\xb6\x88\x09\x65\xee\xbc\xe5\xdd\xc1\x8b\xba\xc2\xb6\xff\xf3\x3f\xee\xfe\x34\x54\x81\xf3\xd4\xd6\xdb\x87\xdd\xa2\xd4\x63\x60\x0f\x25\xcc\x49\x47\x1e\xa1\x99\x3f\xac\xfe\x98\x0c\x62\x1c\x31\xee\x1c\x1f\x1b\x29\xb6\x29\xd4\xe1\x92\xec\xee\xd4\xfe\x1c\x8c\xe0\x7f\xcb\x42\xac\x27\x15\x98\x94\xc4\xd2\xe2\x81\x5b\x03\xf2\x2c\xde\x8b\xac\x38\x3e\x94\xd5\xe2\x2a\x1d\x4a\x49\x12\x24\xac\xaf\x8b\xe9\x64\xd0\xb2\xb2\xd8\x95\x97\x4a\x0d\xd5\x56\xfd\x15\x61\x9a\x38\x41\xe5\x9b\x56\x10\x49\xd2\x90\xb9\x2f\x6f\x6b\x78\x71\x76\x5d\xb3\xfc\x53\x92\x08\x69\x81\x26\xad\x41\x8a\x08\x03\x2f\xcd\x33\x1e\x3f\xce\xb8\x27\xdc\xb2\xd3\x20\xcf\xc5\x61\x36\x3f\x04\xe1\x8d\x3a\x15\x4a\xb8\xa2\xbe\x64\xd4\x9d\xac\x3b\xf5\x06\x79\x9e\x15\xc7\x81\xa8\x2b\x25\xdc\x58\x16\x99\xa2\xfc\x99\x29\x58\x5e\x8a\x23\x94\xc5\xba\x6b\x4e\x23\x81\xd5\x59\xae\xa6\xd4\xc5\x43\xd6\x85\x2d\x1c\xb8\x79\x30\x91\x94\x12\x5b\x3d\x9e\x97\x05\xac\xbb\x89\x2a\x92\x18\x99\x13\x6c\x9d\xcf\x3d\x85\x2f\x4a\x84\x0a\xd0\x5f\x3e\xf4\x02\xda\xb3\xa6\x11\xfd\x6c\xf0\xfd\x8c\x41\x83\xc8\x33\xaf\x8e\x4e\x13\x22\x43\x2e\xbd\x78\x82\x6d\x39\x78\x73\x91\xa8\x58\x63\x2c\x7a\x7b\xa9\x60\x5a\x77\x43\x89\x02\x86\x41\xb6\xf6\x4a\x5b\x1c\xef\x1a\x74\x28\x3d\x75\x04\x2a\xef\x58\x09\xb0\x6a\xe2\xf8\x10\x1d\x6b\x15\xf4\x2a\x2f\xdd\x66\xa0\x13\x2b\xb2\xf2\xfb\x66\x22\xe0\x4c\x09\x84\x42\x38\xb7\xde\x16\xfa\x67\x27\xd8\x3f\x6d\xa3\xc9\x9d\x21\x21\xa8\xdf\x94\x15\x59\x93\x89\x7c\x77\x05\x00\x69\xbb\x24\x9a\x8f\x76\x03\xcc\x00\x0d\x72\xde\xd7\xfb\xae\x49\x14\x56\x54\x2e\x67\x9b\xb3\xc8\xf4\xe6\x32\xfd\x22\x26\x95\x48\x75\xbc\x7b\x83\xaa\xcc\x61\xe4\x9b\x10\xa3\x74\xe4\xb2\x26\x19\x54\x70\x1b\x16\x47\x69\x14\x01\xba\x05\x4e\xe0\xab\x2c\xf3\x7a\x6d\x5e\x00\x3a\x15\xf1\xb6\x8b\xc1\x9c\x2e\x96\xd9\x23\x9b\x9b\x43\xeb\xd6\xf7\x31\x5d\x7e\x45\xd2\x88\x05\x6e\x0d\x37\x97\xaa\x00\xdd\xae\x91\x25\xa8\x72\x78\x7f\x1e\xa0\xfd\xd0\xf8\x7a\xe2\xf9\x00\x13\x44\x69\x24\x0c\x26\x08\x0f\x98\x21\xec\x19\xdb\x5d\x33\xa5\x96\x76\xc5\x72\x66\x58\x7a\xa1\x72\xa0\x0b\x35\x5c\x7d\x94\x32\x9b\xf3\xc3\x2a\xbc\xd6\xd2\xb2\xd8\xac\x41\x78\xaf\xdf\x47\xc7\x17\x8a\x88\xf3\x2e\xe3\x88\x03\xfd\x50\x56\xbb\xed\x78\x26\xd0\x38\x8c\x53\xe9\xab\xa4\x1b\x71\x95\x8e\xe8\xba\x09\x1c\x94\xdd\x47\x01\xd5\x71\x5c\x5b\x47\x69\x2c\x08\x49\x27\xd8\x6f\x5b\x94\x88\xe5\x85\x43\x04\x78\x77\x85\xf1\x32\xdd\xcf\xe2\x7c\x6e\x7d\xc6\xfc\x5a\xb7\x9a\xd2\x18\xa4\xee\x43\x38\xaf\x50\x8f\xb7\xd1\x01\xf0\xdb\x56\x0f\x77\x5f\x91\x53\x4b\x81\xfe\x54\x1e\x5f\x4a\xcf\xfb\x4c\xaf\x50\x12\xf7\x75\x9e\x29\xe5\x42\x23\x3d\x4d\x93\x41\x85\x24\x04\xfe\x03\x72\x49\x6d\x60\xf3\x52\xbf\x5d\x1d\xbe\x94\xcb\x18\x93\x1e\x88\x1e\xc5\xdd\x6d\x36\x28\x3b\xa6\x34\x4d\x39\x82\x6a\xdb\x59\xd1\x88\xac\xf8\xed\x33\xcf\x9a\x0a\xa2\xf1\xb8\x9d\xbd\xfc\xfe\xea\xef\x20\x78\x40\x90\x68\xce\xd2\xe6\x1c\xe1\x96\x9c\xe6\xbd\xfb\xa5\x5a\x7a\xcc\xd6\x3d\xe0\x82\xeb\x2a\x43\x8d\xfe\xca\xa2\x3c\x9d\xc1\xea\x62\x23\x33\x63\x76\x55\xf8\x43\xa9\x4c\x04\x25\x63\xbe\xf7\x2b\x20\x7d\xdb\xcb\x8e\xe8\x21\xab\x3d\xc5\xd2\x8d\x6a\x07\xd7\x59\x19\x82\x05\x5c\x2e\x4b\x8d\x29\x87\x68\xc4\x48\x45\xa9\xe6\x61\xdc\x69\xda\xd6\xaa\xff\xb3\x75\x64\xe5\xa5\x2a\x9e\x45\x7d\x8b\x94\x60\xf2\xae\xd0\xfe\xbf\x43\x12\x94\xcd\x08\xda\x33\xe8\xc4\x65\x44\x07\xbc\x66\x77\xab\x58\xaf\x6e\x6f\x84\x4c\x68\xaf\x1e\x70\x17\x6b\x44\x59\x10\x13\x74\x80\xcb\x1f\xe2\x94\xb9\xf3\xd6\xa3\xd9\x5c\xd9\x02\x65\x21\xa5\x89\x4b\x9c\x96\x97\xe6\x01\x60\x8a\xd5\xa1\x2c\x14\x92\x71\x4f\x3e\x04\x97\xba\x73\xe3\x58\x24\x42\x3c\xed\xba\xda\x64\x09\x05\xa0\x0c\xb6\x07\x5c\x53\x16\x19\x82\x58\x95\x5a\x7c\x3c\x96\xa5\x96\x1f\xdd\x7d\x09\x63\x48\xc6\x6d\x6c\x09\x2d\x7e\xec\x8e\xf3\x02\x63\x29\xc4\x77\x65\x81\xed\x6a\x51\x37\x3f\x40\xa3\xac\xe2\xc4\xb8\x62\x2c\xe1\x9d\xbd\x77\x72\x7a\xc4\xed\x91\xde\x3d\x0b\x53\x12\x75\x7d\x57\xdb\x81\xb7\xce\xe2\x90\x60\xc0\xbc\x74\xda\xbd\x07\xc4\x08\x4e\xbd\x26\x5c\xce\xff\xcd\x26\x9f\x83\xc5\x3a\x48\x5c\x76\x65\x2b\x9a\x0c\x41\x05\xe7\xfc\x63\xe2\x0a\xfc\xe3\x06\x8f\x1a\x65\x49\x18\xd1\xa1\x1c\xf8\x6c\xff\x32\x79\xa3\x24\x22\x58\x25\x9e\xb5\x2b\xa0\xe7\xda\x9e\x4e\x0a\xc6\xa9\x65\x99\x71\x85\x44\xe3\x8a\x06\x27\xc7\x7f\x27\x98\x78\x75\x8a\x0d\xfe\x8b\xff\xcf\xa0\x6b\xfc\x3f\x57\x77\xe0\x7e\xb3\xc4\xb8\xfe\x55\x81\x44\xf7\x70\x1a\xc9\xe8\x16\xa2\xd2\x0f\x65\xd9\xc8\xd6\xf2\xe9\x02\x85\x8c\x6b\x40\x3e\x71\x28\x6a\xb4\xe3\xb6\xbf\x7c\x4b\x4a\xe2\x50\x7b\xb0\x5c\xd3\x3a\x58\xc3\x63\x89\xa5\x82\xa3\x4b\xba\x85\xaa\x86\x6c\x78\xfe\x33\xe1\x2b\x60\x41\x9c\x66\x85\x76\x15\xf1\xf5\x54\xb0\x98\x32\xa1\x6c\xad\x8d\x0f\xa1\xec\xb2\x63\xe1\x72\x74\xe3\x2f\x21\xb9\xc4\x88\x45\x6d\xc3\x35\x93\x46\xa5\x89\xe8\xe2\xb7\xa2\xfe\x01\xcd\xea\x17\x56\xe4\x4e\xfa\x69\x8a\x44\x1e\x58\x72\xe3\x20\x1a\x30\x2b\xb4\x95\x72\x18\x96\x38\x50\xa6\x68\xec\xd9\x00\x0f\xa8\x58\x79\x27\xf0\xf2\xf9\x26\xcd\x54\x6c\x04\x0c\x38\xaa\x3a\xdb\xec\x16\xdf\x33\x65\x2a\x4d\x11\xab\xbb\xfb\xb2\x1d\x0d\xa8\x4a\x85\xe2\x9d\x25\xf3\x9c\xfd\xea\xc5\x46\x28\x53\x3a\xc0\x38\xaa\xbc\x14\x3a\x87\x1b\xfe\x04\xd3\x29\xd3\x36\xba\x79\x9c\x67\xda\xd6\x56\xde\x48\x0b\xde\x4b\x3c\x8f\x6c\x6c\xa6\xa5\xc1\x9b\x39\xa5\x36\x0c\x11\xf8\x47\xd1\x0a\xd0\x2a\xf4\x2a\x6e\x58\x50\x7c\xdb\x9b\xc4\x9b\x46\x41\xcf\x49\x45\x99\x36\x42\x27\xce\x82\x99\xed\x27\x51\x31\x06\x61\x62\x8b\x14\xd0\x1c\x79\x44\x95\x4e\x5f\x68\xea\xee\xe6\x7b\xc6\x36\x58\x22\xcb\xf2\x47\x56\x1c\xe7\xde\x4f\x99\x4c\x07\x13\xe8\xd0\x02\xa3\x8f\xc7\x1c\x1c\x6d\x38\xca\xea\xfb\xd7\x31\x09\xc3\x0c\xe1\xe6\xbf\xf6\xc3\xcf\x11\x07\x8a\x60\xb1\xd9\xb6\xfc\xfe\x9c\xcd\xfd\x5f\xc3\x40\x61\x41\xd1\x6c\x39\xfb\xa4\x42\x81\xc6\x21\xb3\x02\x34\xaa\x7d\xaa\x7c\x00\x3e\xf0\xed\xa0\x31\x42\x30\x22\xdb\xde\x7d\xdd\x6e\x3d\xeb\x12\x8d\x43\x03\x24\x9d\xc8\xf0\xb5\x7b\x37\xd6\x68\x43\x71\xad\xc0\x78\x33\x03\x1a\x93\x50\x5a\x30\x96\x27\x1b\xed\xf7\xb8\xf1\x3c\x8e\x89\x8e\x65\x0f\xd6\x9d\x67\x5a\x4f\x13\x57\xad\x93\x27\x88\x97\x25\xdc\x35\x55\xc7\xc5\x42\x63\xca\x19\x62\xb9\xcc\x65\x40\x38\x4a\x63\x2a\x43\xb4\x0b\xf6\xaf\xeb\xaf\xcf\x9f\x0e\x19\xd3\x36\x20\x35\xcb\x33\x28\xfa\xc2\x21\x1a\x23\x1a\x73\xb8\x87\x17\x7a\x44\xf5\x38\x7e\xc4\x38\xb6\x0e\xa0\x7b\x8b\xce\x33\x8c\xe3\x54\xe3\xf6\x32\x17\x7a\x9e\x35\x6a\x40\x58\x49\xe3\x58\x19\x9b\x87\x70\xb4\x17\x79\x7e\x95\x06\x8b\x93\x94\x60\xd5\xdb\x40\x60\xad\x6b\xb1\xa5\x30\xb9\xa8\x9b\x43\x61\xd5\x87\x5d\x13\x27\x11\x9e\xaa\xee\xd4\xb8\x87\xc0\x19\x5a\xb2\x31\x57\x41\xea\xed\x73\x64\xb3\xc3\x8d\xe0\x32\x10\x7d\xa3\x71\xaa\x08\xa6\x41\x3b\xb3\xb4\xfb\xbb\xa5\xc6\x38\x42\xf3\x92\x29\x40\xa2\x8b\xf1\x6b\xa4\xc0\x13\x0b\x28\xfd\x3d\x53\x3f\x4a\x63\xc6\xe9\x9f\x58\x69\xeb\x62\x9c\xcb\xba\x39\x97\x05\x2c\x2f\x70\x57\xa2\x96\xc6\xca\x44\x18\xef\xb5\xda\xe5\xb8\x80\x6e\xc2\xc7\x68\xac\xa9\xb1\xeb\x29\x17\x1f\x7f\x84\x81\xcf\xdb\xc6\x9a\xd9\xcf\xfe\x02\xcd\xa2\x67\xd7\xa1\xb1\x4e\x9d\xec\x3f\x34\xbf\x5f\x74\x59\x77\x9a\x44\xfd\x8f\x43\x1a\x40\xd2\x05\x84\xe6\x9e\xf2\xaf\x75\x43\x04\xe5\x3d\xdb\x81\xdb\xf5\xfb\x5d\x28\x36\x91\xc5\xe6\xb7\x06\x30\x92\x09\xd4\x4f\x60\xba\x99\x62\xa2\x14\xad\xf8\x45\xf5\x71\x6e\xca\x7f\x0a\x0d\x5d\x4b\xc2\x31\x3f\xd2\xc9\x02\x65\xc5\x11\x6b\x0f\xfb\x38\x79\x6c\x80\x21\x7c\xd9\x82\x9a\xdf\xb2\xb3\xff\xe8\xae\x82\xed\x0e\x3d\x5c\x7b\xa1\x42\x63\xd2\xb3\x78\xcc\xb4\xfe\x64\x03\x1f\xae\x9d\x24\xd0\x32\x32\x5d\x24\xcb\xab\xda\x8c\x6e\x9f\x84\xcc\xd6\x5f\xb7\x3b\xef\xd7\x22\x53\x65\x75\xc7\x67\x4f\x48\xc0\xf1\x0d\x6c\xc4\xc6\xdb\x8b\x1d\x5b\x71\x7d\xa5\xc7\x7b\x73\x36\x0f\xe7\x74\x42\xb8\xc2\x52\x8b\x93\xf8\x01\x63\xcc\xdb\xdf\xca\xc6\x24\x44\x12\xdc\xa5\x91\xc2\xcc\xd9\x18\x70\x97\xbe\x8c\x26\x54\x6b\x8a\x68\xd1\x8b\xfa\xf1\x81\x22\x8a\x8b\xcb\x79\xb8\xbf\x27\x0c\x08\x82\x79\x9e\xd7\x2f\x87\xf9\x6a\x7f\x98\x3d\x6f\xbe\xbe\xec\xfb\x56\x6b\xb3\x2f\x1f\xf7\x07\x35\x8e\xb5\x24\x09\xa1\xd2\xa5\x6e\x10\x93\xdd\x15\x2a\x4f\x2b\x3b\x68\x92\xa4\xf6\xb4\xc3\xe2\x39\x8d\x33\x62\x20\x67\x49\x13\x4e\x63\x0c\x00\x19\x18\xe5\xe1\x92\x94\xd2\x80\x78\xee\x5e\xbc\xe1\xc6\x38\xc9\x76\x75\x03\x9f\xef\xae\x12\xc2\x06\x63\x2b\x4f\x98\xeb\xcf\xf3\x44\x32\x85\x41\x8c\xf3\x45\x8e\x8a\xc2\x68\x22\xe3\x00\x63\x4b\x18\x1c\x59\xeb\x7d\x69\x1f\xb2\xaa\xc4\x2d\x9f\x30\xd1\x41\x64\x19\xb7\x5a\x77\xf9\xa1\xb5\x17\x7d\x03\x33\x96\x84\xd1\xe1\x61\xb2\xc2\x94\x5d\x9b\x0e\x30\x17\xa8\x44\x9e\xef\x6e\xd2\x92\xfd\x8d\x19\x04\x71\x68\x1c\xfa\xe2\x49\x54\x47\xf0\x20\xe0\x19\xd2\x73\x89\xfc\xf6\x71\x90\x98\x24\x40\xcf\xca\x46\x58\x07\x47\x30\x0f\x42\x2d\x2c\x8b\x79\x9e\x81\x79\x6d\xbf\x62\xd7\x14\xa5\x21\xb7\x2f\x33\x2e\xe3\xf4\xed\x3a\x08\x1d\x24\x3b\x53\x65\x3d\xa4\x44\xa4\x3c\x8c\x12\x2c\x06\xb3\x7a\x7a\x35\x0c\x61\x08\x3c\x34\x01\xf7\xc8\xd4\x6f\xe5\x45\xbd\x79\x3a\xa7\xee\x89\x79\x14\x5a\x51\xcb\x37\x51\xb7\xce\x6d\x77\xdf\xc8\xf1\xd9\x5b\xa0\xdb\x3c\xd3\x0f\x65\xb5\xfb\x01\x8d\x7a\xbb\xbd\x8c\x79\x14\xcb\x44\x74\xc6\xd4\x6e\xf4\xdd\x79\xa4\x18\xd6\x5c\x56\xa2\x81\x8d\xd9\x8a\xea\xc7\xa0\xca\xc1\xf5\x21\x91\xc2\x45\xf4\x06\xa2\xf9\x7a\x1b\x47\x4c\x39\xa1\x4c\xf9\xc8\x95\x13\x7c\xbe\xb5\x45\x71\xe2\x68\x3a\x9e\x45\x25\x21\xcf\x05\x1e\xbf\x7f\x99\x36\xe3\x24\x8e\x30\xcc\x68\x31\x0e\xdf\xdb\xe5\xdf\x9d\xae\x9c\x08\x42\xbc\xe0\x38\xc6\xce\xd7\xc5\x32\xab\xcf\x97\x49\xf1\x34\xe5\x04\x14\x5a\xfa\xe2\x7c\x1e\xa8\xe6\xba\x46\x2a\x00\x63\xdd\x07\xa1\xf5\xe2\x4d\xb4\x4b\x7d\xe0\xda\x0d\xd3\x60\x9c\x71\x22\x7b\xbb\x78\xe1\x72\x74\xd7\xba\x2c\xa3\x57\x60\x4a\x61\xaa\xf7\x71\xbe\x3d\x6c\x4e\x45\xa6\xcb\x3c\xef\x12\xe5\x9c\xe9\x38\x71\xe3\x67\xb9\x86\x7a\xe2\xbc\xee\xbc\xe2\x0c\x22\x18\x28\x41\xdc\xd1\x78\xa5\x3c\x0e\x09\x72\xc0\x2d\x33\x71\x2a\x0b\xaf\xe0\x33\xdc\x5a\x78\x1c\x5a\x1c\x7d\x0d\xd5\xcf\x4c\x81\x97\x84\xf1\xad\x51\x08\x6d\xeb\x2f\x3b\xde\x23\x6f\x90\xc7\x54\xa1\x21\x66\xc5\x59\xa6\x3f\xcd\x0d\x3a\xfe\xa8\xe7\x8e\xbf\x88\x47\xea\xf8\x3b\xc4\x42\xe0\xda\xc8\xea\xfe\x30\x1c\x7f\x0c\x9e\x10\xe2\x62\x2f\xa8\x9e\xac\x06\x39\xdf\x90\x7a\x17\x38\xa4\xd7\x18\x1d\xbf\xf7\x73\xae\x2c\xdb\xbf\x3f\x77\x5b\xf3\x66\x61\x99\x21\x07\x36\x00\x4f\x89\x51\xd2\x17\x86\x7c\xbb\xaa\x71\xa4\x5c\x04\x0a\x59\xcc\xed\xc7\xee\xa0\x2b\xe3\xd7\x16\xcc\xc2\x9d\xb2\x7a\xf7\x56\x56\x8d\x07\xd3\x22\x95\x4e\xbf\x76\x85\x20\x32\xf4\xfc\xa1\x8e\x47\x70\xfe\xf1\xd2\xd7\x60\xfb\x7e\x3a\x4d\x4c\x9f\x6a\xf8\x3f\x51\x82\x50\x2e\x09\xc3\x6d\x09\xd9\x1b\xce\xa5\x07\x64\xde\x2e\xf3\xf6\xd7\x24\x0a\x2b\x3d\x3b\x45\x1c\xff\xc8\xd2\x24\x89\xe5\x32\x52\xe5\xcf\x3b\x44\x92\x94\x2b\x16\x22\x4d\x68\x56\x3f\x7f\x6c\x73\x51\xc0\xf4\x8b\xab\x34\x42\xf0\x98\x14\xad\xf7\x3d\xcb\xf3\xd1\xc1\xc4\x75\x4c\x90\x2e\x73\x59\xaa\x4b\xfb\xeb\xa2\xfa\x98\xa4\x36\xb8\x4e\x22\xaf\x99\xbb\x59\x3c\x4e\x86\x5f\xa7\x80\xa5\xbe\xb6\xd0\x0e\x37\xba\xb5\x2a\x27\x9d\x80\xa6\xe8\x02\xe9\xdd\x6a\x7f\xf8\x63\xfe\x84\xca\xd0\xab\xdd\x6e\xda\x2d\xb6\x96\xa8\xb2\x53\x73\x40\xbc\xfd\x79\xe8\x95\x9b\x40\x62\x78\xbc\x35\x6d\xc7\xdf\xd3\x50\x9b\xab\x6a\x2c\xb7\x6c\x59\x8d\x95\xee\x29\x37\xd2\x72\x6f\x9d\xb2\xc2\xc3\x05\x6f\x98\x35\xbe\xb3\x63\xb3\x58\xcd\x5f\x9d\x00\x2a\x4d\x03\x95\x08\xee\x15\xb6\x61\x2c\x3c\x46\xd3\x90\x50\x9f\xaf\xc4\xbb\xd7\xd9\xf1\x86\xbe\x3d\x4d\xc3\xd8\x60\x0a\x7e\xc0\x15\xef\x68\x02\xa7\xf0\xe2\xc9\xfd\x4d\x20\xdd\xfd\x9f\x9e\xbe\x1d\x40\x67\xcd\x21\x1e\x0d\x41\x1a\x85\xdc\xd3\x26\xb5\x56\xb2\x2d\x62\xf7\x4f\x1f\x71\x8d\x31\xda\x77\x51\xb7\xe7\xd3\xaa\xe8\xd3\x36\x29\x49\x42\xe8\x62\x86\x5e\x1a\x6e\xdd\x4d\xd0\x94\x24\x56\x18\x53\x68\xbd\x12\x55\x01\x13\xef\x20\x25\x3a\x31\xed\x56\xb6\xc8\x2a\x75\xc9\x9a\x79\x05\xe2\xc7\x7d\x46\xb3\xc9\x8b\x11\x88\xa9\xa5\xf8\x47\xdd\xd5\x7d\x39\x7e\x29\x2a\x19\x82\xb0\x15\x94\x33\xad\x17\xe5\x64\xc6\xa5\x54\x69\x54\x5c\x85\x81\x02\xaa\x6f\xd2\xee\x93\x08\x5b\x98\xea\xff\xce\x62\x2a\x5d\x4c\x7e\x63\x05\xba\x1d\x0d\xc4\x75\xc2\xf4\x66\x0d\x0b\x4d\xe3\x24\x71\x3f\xda\xcb\x5a\xf8\x26\x6e\x98\x3b\x64\x0e\xae\x84\xfc\x90\xa9\xb2\xc8\xfe\x7d\x10\x95\xcc\x9a\xfa\x70\x86\xea\x00\x43\x79\x51\x77\x65\x12\x46\xa9\x0b\x0a\x60\xfe\xd8\x66\xb5\xa7\x9d\x62\x49\x5d\x14\xf1\xe5\xdc\x2e\x82\xf1\x83\x25\x5c\xe1\xae\xf6\xbf\x70\x92\xe0\x43\x8f\x69\x22\x2d\x48\xe2\x70\x84\xe6\x41\xd4\x6f\x59\x59\x6c\x45\x25\x4e\xd3\x7b\x4b\x1b\xf8\x2b\x1c\x2a\x08\xfd\xb5\x6a\xfc\x39\x12\x4d\x3c\x13\xeb\x62\xf1\xc5\x4e\xc3\x90\x8f\xfb\xf0\x90\xc5\xe0\x14\x65\x16\x9b\xf9\xc5\x47\xac\xd3\xb4\x7d\x40\x57\x88\x64\xc3\xe4\x5d\x4b\x6c\xd3\x24\x07\x47\xdb\xb6\xf8\x50\x39\xec\x7e\x74\xc5\x05\x69\x0a\x11\x92\xc9\xad\x5e\x17\x49\x92\x2c\xe1\x54\xfe\xe5\x86\x9b\x0a\x48\x31\xab\xd2\xba\x90\x7d\xbd\x08\x4d\x55\x90\x38\xda\xf9\xde\xe1\x18\x0f\xa3\x0a\x64\xe4\xe2\xe0\xd6\x23\x78\xde\x3d\xf8\xab\x35\x8b\xb5\xf4\x07\x8c\x9b\x38\x55\x79\xf6\xfb\x4c\x0a\x44\x61\xfc\xd0\xd1\x4e\x95\xea\x33\xf2\x45\x7f\x0d\x08\xfc\x6c\x1d\xf8\x6d\x21\x6e\x04\x2e\xba\x03\x35\x05\xa3\x63\xe8\xc9\x9f\x56\x3f\xa1\xfa\x90\xa5\xee\x06\xda\x04\x21\x46\x00\x4c\x26\x9a\x11\x1f\x13\x15\x01\xd5\x81\x25\x5e\x50\x65\xd1\x7a\x20\xba\x6b\xe1\x51\x1c\xf8\x8c\xaa\x05\x13\x62\xfa\xf5\xd3\x1d\x59\x44\x01\x44\xba\x4b\x53\xb4\x46\x44\x59\x94\xd5\x2d\x35\x53\x2a\x22\x92\x60\x91\xf5\xb7\xd5\xe3\xec\x65\x68\x2a\x09\x12\x4a\x4f\x3a\xfe\x0a\xff\xbe\xb4\x07\xfa\x2b\x9c\xcb\xaa\xa9\xb7\x50\xd9\xff\x82\xea\xa1\xac\x9c\xe0\x9d\xff\x8b\x45\x77\xfa\xa1\x17\x34\x24\x18\xce\x51\xbe\x4a\x0a\xd6\x85\xe3\xcc\x18\xfd\x1a\xe5\x34\x4d\x3d\x7e\xa0\x81\xa3\x67\x8a\xf2\xcd\x82\xa1\x2b\xd9\x40\xdd\xcc\xb3\xa6\x5e\xfd\xfb\x22\xf2\x11\x47\x32\x15\x4c\xc4\x24\xea\xcd\x0c\x51\x7c\x38\x23\x63\x64\x63\x09\xc4\xf6\x23\x6d\x7d\x5d\x0f\x02\x6d\x22\x8e\x63\xe3\x2e\xef\x8b\x86\xd7\x45\x0d\x55\x83\x2c\x77\xdd\xef\xc4\x3c\xb5\xda\xed\xd6\xd9\x6b\x76\xc3\xf2\x90\xdb\x5f\x24\x51\x0a\xeb\x04\x3c\x5a\x75\x1c\xcf\x12\x89\x4e\x90\x7b\x40\x66\xda\xcb\x34\x8f\xaf\xe7\x81\xf5\x6d\x91\xb4\xcf\x06\x1e\x6f\xff\x10\x27\x1a\xe3\x46\x87\x01\x31\x9a\xa3\x87\x2a\xd4\xdb\xb5\xa9\x3e\xbe\x5a\x48\x48\x2d\x39\xd2\xc7\xea\x17\xa8\x71\xef\x49\x5f\x19\x11\x24\x34\xf2\xc2\xe9\xd6\xc6\xdc\x35\xa2\x75\xa5\x1e\xa0\xab\x5e\x12\x92\x24\x54\x7a\x0e\xe4\x0a\x84\x76\x8e\x52\x8d\x6e\x76\xbb\x5e\xaf\x52\xe9\x42\xd2\x04\x83\x41\x3f\xcb\x06\xbe\x43\x76\x7c\x6b\xbe\x16\xd9\x55\x27\x11\xc5\x2e\x4c\xe0\xe9\x57\x86\x4a\x14\x7f\xcf\x6c\x14\x2a\x8c\xd0\x38\x3d\x39\x0b\xe1\x9e\xfd\x21\x54\xa4\x30\x08\xf3\x5d\xfc\x84\x7a\xc4\xb4\x44\x85\xd2\x12\x8f\x35\x9d\xd5\x28\xfb\x62\x3f\x73\x8f\xa3\x10\x0a\x0c\x46\x54\x0a\x78\x9f\x6f\x7f\xfb\x8c\xfc\xfe\xd6\x66\x24\x74\x1c\xa0\x1f\x68\x8d\x71\x0c\x21\xd9\xa3\x88\x4c\xc6\x44\x2b\x1b\x3a\x71\xe0\x3d\x57\x7e\x80\x65\x86\x77\x10\xb5\x02\x28\x65\xa1\x4b\x3c\xc1\xba\x1e\xe2\x3c\x05\x08\x86\x6d\x95\x28\x74\xe1\x15\x2d\xa9\x30\xc2\x42\x63\xaa\x51\x61\xfa\x38\x8b\x22\x8c\xb2\x82\x7b\xa7\xac\xd8\x59\xa1\x17\xa7\xd3\x88\x86\x6a\xfd\xd6\x8f\x8e\x0c\x52\x1a\x44\xde\x8b\xb6\x85\x5d\x9e\x57\x77\x7c\x0a\xc8\x90\x44\x98\x77\xf3\xd9\xa6\x25\x74\x98\xe4\xd1\x88\xc9\x08\x64\xd4\xe7\x52\x3c\xab\xf6\x88\x61\xcc\xf5\x24\xc4\xea\x2a\x3a\xa6\xf1\x3b\xf8\x79\x49\x64\x67\xc9\xb5\xc6\xda\x15\x6f\x2e\x95\xad\x75\x93\x76\x91\xb1\xf5\x74\x52\x4b\x0a\x56\x9b\xe7\x2c\x3e\x5e\xe1\xaa\x18\xd2\x75\x62\x0c\x70\x01\xef\xbe\x3e\xed\x67\x5d\x44\x4e\x26\xcc\x16\x12\xf7\x52\x4d\xbe\xf4\xea\x76\x19\x3a\x95\x89\x09\x31\xc2\xf7\x7a\xc9\xbb\xb5\x28\x39\x49\x84\x74\x8c\x78\x88\xc8\xf8\xdf\x4e\x39\x8f\xca\x54\x09\x64\xad\x2b\xca\x99\xfe\x09\x95\x37\x35\xa5\x8a\xad\xa8\xc3\x2c\xcf\x5b\x73\xac\x80\x0a\x55\x80\xc7\x3f\xa7\x78\x84\xd5\x34\xda\x27\x1d\xed\x43\x4d\xe1\xa7\x52\x93\x00\x0b\x5c\xb4\x8b\x54\x74\x73\xa7\x3b\x49\xa5\x4e\x02\x54\x40\x7b\x17\x1d\x0a\x4d\x6a\x9e\x60\x09\x5f\xad\xde\x40\x5f\x72\x58\x88\x3c\x9f\x6c\x4f\x9f\x80\x6c\x25\x70\x8a\x87\xef\x0b\xbc\xb7\xcb\xc2\xc6\x96\x6f\x2e\x07\x09\xd2\x12\x3c\xb5\xa3\xd3\x05\xb1\x27\x2f\x01\x12\xb0\x26\xe0\xf0\x50\x01\x2c\xbb\xe4\xa0\x34\x2a\xc5\x80\x26\x0e\x2f\xc2\xac\x9e\xb3\xce\x64\x57\x61\x62\xbf\x7f\x0d\x0d\x96\x33\x5c\x0b\xa4\x52\x15\x31\xc6\x1c\x5a\x62\x29\x3e\x86\xe1\xb7\x69\x48\x49\x45\x89\x41\x12\xcb\xcc\x66\xb5\x37\xd5\xe6\x7c\x67\x89\xab\x48\x26\x28\x99\x73\x2e\xdf\xa1\x02\x7d\xb8\x78\x1b\x4e\x11\xa2\x08\x19\xc8\x91\x8d\x03\x7e\x2e\x24\x75\x73\x82\x29\x42\x09\xe2\x59\xde\x4a\x9d\x7f\x5e\x72\xa3\x48\x62\xa5\xf0\xe5\xe5\xe3\x55\x54\xb0\x6e\xe0\xae\x4c\xb5\xbb\x82\x06\xc4\xd3\x84\xac\xf6\x5f\x7e\x4d\x30\x81\x8a\x06\x56\xcd\x62\x39\x48\x63\x29\x1a\x45\x3a\xc0\xf5\xd5\xf9\x0c\xfb\xf2\xeb\x7c\x23\x47\x54\xc9\xbe\x33\x4f\xc0\x26\x82\x76\x4d\x89\xa0\xae\xb5\x2a\x37\xc5\x17\x51\xe9\x45\x17\x27\x54\x31\xe1\x7a\x08\xa0\xc0\x4f\xb6\x2f\x2d\x47\x91\xaf\x0d\x9f\xe2\xb3\x6e\x0f\x57\x1c\x13\x2f\xa1\xf5\x75\x5d\x34\xd7\x3c\x98\x54\x25\xb1\x25\x94\x86\x42\x0f\xe1\xb8\xfe\x61\x12\x49\x50\xc7\xe0\x9f\x98\x4f\xcd\xa7\x17\xcb\x84\x3b\x8e\xa2\x4d\x75\xfc\x94\x5d\xfc\xc6\x7e\xa9\x78\x92\x60\x80\xd9\x15\x81\x3e\x65\xff\xbe\x60\x70\x6f\xff\x76\xa3\xd8\x5a\x71\xae\xe3\xc8\x01\x2e\x97\x70\xba\x54\xd5\x20\xf2\xe9\xfb\x28\x5b\x03\x63\x39\x8e\x9e\xb3\x02\x74\x87\x6c\x9c\xf4\x04\x8e\xf1\xc9\x6d\x59\x0e\xbf\x67\x1a\x93\xc8\x9d\x0a\x3d\xae\x62\x73\x9e\xe6\xfe\x55\x1a\x33\x3c\x8d\x6c\xd8\xed\x79\xbf\xf8\xeb\xc0\xaa\x12\x31\x4d\x7a\xe2\xdc\xf5\x69\xf0\xf8\xd7\xb1\xb5\x01\xf0\xe4\x93\x11\x14\x32\x00\xb7\x94\x3c\x16\xaa\x13\xd7\x1a\xc8\x85\x50\x25\x4c\x14\xba\x20\x9f\xd3\x4c\x87\x06\x54\x33\xa6\xab\x18\xc5\x5f\x47\x48\x70\x25\x99\x0d\x91\x3f\xb4\xee\x9a\xbe\xc1\xcc\x42\x95\x94\x1a\xe3\x88\x36\xdc\xe1\xc3\x7f\xb7\x37\x07\x29\xb5\x72\x50\xd6\xee\x4c\xb9\x41\x72\x32\xb9\xc8\x68\xcb\x0d\x76\xb0\x26\xc9\xe1\x8c\xe1\x2f\x9b\x33\xfc\xda\x64\x79\x7d\x33\x25\xa4\x54\x42\x22\xcb\xb2\xd5\x54\x19\xfc\x1c\x07\x00\x95\x4a\x12\x2f\x62\xd4\x6e\xd3\x4b\xd1\x88\x4d\xb1\xba\xf6\xcb\x95\xd2\x89\x08\x3a\x5b\xbd\x3c\x89\x81\x03\xe2\x62\xe0\xf3\xd2\x05\x62\xfd\x74\xd2\xa1\x41\x0e\xb1\xae\x5c\x6e\x5a\xc2\x79\xc3\xab\x53\x9a\x5a\xbe\x0a\x8c\xeb\x52\x9b\x4a\x7d\x85\x93\x18\x60\x64\x15\x84\x56\x90\xac\x9d\xe6\x18\xf9\x1c\x02\x80\x14\x80\x46\xc7\xc6\x81\xd0\xea\x7d\x76\x82\x9e\x28\x8d\x2a\x30\x0a\xe9\xcf\x4c\x9e\xfd\x7b\xf4\xbc\x26\xd6\x89\x05\x6f\xcc\x31\xe8\xfb\xdb\x8d\x63\xce\x77\x4d\x43\x8c\x23\xbe\x5c\x4e\x59\x7d\xf2\x25\x35\x3a\x20\x81\xdf\x72\x90\xe4\xd0\x64\x6a\x18\xd6\xfb\x74\x07\xd6\x01\x09\xd1\xde\xd9\xe6\x42\x8c\xc5\x61\xa8\x0e\x98\x15\x9b\x72\x04\xa8\xa2\x6e\xbe\x67\xf9\xb4\x3a\xe5\xd6\x22\xd1\xed\xbe\x4d\x11\x6f\xd6\x5e\x5b\x83\x53\x0e\xe8\x2a\x06\x87\xcf\xc2\xfd\x35\xda\x46\xa3\x9c\x58\x76\x53\x95\xb9\x15\x53\xfd\x9e\x35\x6f\x5b\xd1\xae\xb4\x97\xb2\x59\x17\x5f\xbb\x40\xbe\x0e\x80\x93\xf6\xa8\xfd\x5f\x5b\x1e\xf6\x3d\x2b\x06\x12\x7d\x54\x87\x11\xa8\x78\x5c\xb0\xb8\x3e\x9b\xba\x2f\xc0\x8c\x82\xc9\x68\x60\x39\xb1\x3b\xbb\x6d\xea\xc0\x72\xb1\xdd\x9a\xe4\x9a\xd0\x80\xb2\x49\x40\x26\x0a\x46\x53\x5d\x13\x48\xd0\x7d\x72\x45\x61\xf7\xa4\x37\xa8\xa6\x01\x61\xd4\xb3\xb0\x8e\x17\xfb\xe4\x19\x5b\x9f\xc9\x15\xee\xbc\xc0\xaf\xe6\x77\xb8\x21\xff\x40\x35\x55\x1c\xbf\xdd\xfe\xcf\xed\xea\xf0\x65\xb6\xfb\xe2\x07\x85\x11\xae\x1d\x3d\x5e\xd5\xac\x55\xd9\xfd\x3d\x26\xf6\x64\x28\x2f\x32\x07\xac\xe8\xd8\xc1\xb1\x5d\x38\xbb\x7c\xc8\xf4\xf0\xa9\x09\xa0\x59\x22\xd0\x31\x79\x14\x59\xb1\x87\xd3\x79\xd7\x5c\xcc\xd8\x06\x9e\x7a\xa3\x9a\xf1\x08\x4b\x0a\x32\x5f\x40\x37\x3c\x14\x3b\x76\x7b\xdf\x39\x8d\x2c\xf1\x67\x56\x1c\x07\x44\x84\x54\x33\x1d\x60\x90\xd5\x51\x88\xcd\xcb\x11\xe7\xe6\x28\xb3\xa9\x63\x91\xa2\x20\x85\x75\x12\xb0\xf8\x57\x54\xe2\x04\xcd\x20\x4f\x39\x79\xc8\x84\x71\x4c\x93\xfc\xe1\xfe\x2f\x98\x78\x64\x3a\x49\xad\x84\x6c\xe6\x5c\x54\xaf\x5f\xbe\x80\x0a\x2b\x92\xd6\xcb\xb1\x01\xf1\x39\x36\x4d\x73\x66\xa1\x2f\x16\x64\x6e\x65\x03\x6e\x6e\xd1\x3a\x0d\x98\x15\x08\x6a\xed\x68\x07\x54\x75\x66\x91\xf7\x07\x74\xca\x25\x7e\x73\xa7\x25\x63\x03\x5d\xae\xa6\x72\xcc\x85\x37\x7e\xa9\x94\x1b\x0c\x76\x65\xf5\xae\xcc\x7f\x76\xf1\x2a\x9d\x0a\xab\x6b\x3f\xcb\xaa\x65\x55\x9e\xef\xc5\x03\xf9\xed\xf8\x83\x16\x5c\x68\xd2\x71\x47\xed\x60\x98\xe3\x9b\x76\x95\x01\x1a\xae\xb9\x28\xf4\x49\x54\x3f\xac\x98\x6e\x03\xe7\x25\x14\xe5\x29\x2b\x7a\xee\xcf\xb6\x6f\xc4\x9d\x53\xfc\xfd\xcb\xe3\xb2\x2c\x46\x98\x05\xdf\x49\x93\xc8\xf4\xb5\xda\xc8\xf2\x38\x1e\x50\xc9\x04\x26\x1b\x66\xaf\xcb\xf9\x50\x4b\xce\xdf\x41\xc5\x1c\xe1\xea\xeb\xa7\xf2\x27\x04\xbf\xe6\xfb\xc5\x78\xc9\x2b\x1e\x60\x46\x5a\x22\xed\x42\xef\xc9\xe9\x5b\x4c\x0a\x5a\xf3\x14\x4f\x1e\x61\xab\x80\x26\x8d\x2a\x0e\xbc\x93\x72\x39\x3b\x43\xf4\x26\x76\xdc\x5f\x00\x34\xf0\x6f\x37\x41\xe3\xb5\xbe\x90\xb2\x84\xe6\x99\x28\x8e\xf9\x74\xc3\xd0\x46\x44\x9e\x2d\x46\x9f\x3a\x2d\xcf\xce\xa9\xd4\x40\x95\x47\xd1\xee\xc5\xe7\xe5\xbb\xda\x04\x34\xb5\x71\xe8\xb2\x29\x55\x99\x3f\x00\xbc\x82\xca\xce\xd9\xe0\x79\x4c\x98\xea\x9e\xdb\xdf\x52\xb3\x77\x48\xf4\xd1\x88\x1a\xe0\x98\x5e\x5b\x22\x47\x9d\xbb\x1e\x02\x1e\x5b\x40\x78\x23\x7e\xc0\x80\xdf\xfb\x5b\xd9\xc0\x61\xd5\xbc\x75\xfd\xa4\x74\x14\xa5\xa0\x7e\x3c\x7f\xec\x87\x95\xa4\xae\x4b\x98\x4a\x2c\x12\xc2\xf5\x31\xcb\x2a\x5d\x95\x77\x90\x00\x10\x1a\x82\x8e\xfb\x5b\xf9\xfe\x2c\x0a\x14\x41\x5f\x88\x62\x7e\xf9\x18\x0f\x27\x44\xa1\xc2\x11\x58\x66\x15\x58\x66\xd8\x76\x6d\x56\xa5\x82\x41\x6a\x08\x22\x6a\x30\x68\x66\x13\x50\xd6\xdf\xb0\x27\xce\x0d\x6a\x53\x0a\x11\x0f\x71\x57\x40\xdc\xef\xe7\x07\x3b\x44\x3c\xf6\x62\x7f\x4f\xa2\xc1\x3c\xc9\xe4\x66\xa0\x2c\xa5\xb8\x2d\x22\xdd\x58\x35\xe6\x2b\x7a\x52\x0a\x91\xd1\x48\xfa\xbd\x2f\x2f\xe8\x16\xf5\xc6\x0b\x90\x50\x63\xcc\xe0\x55\x18\x93\x7b\x09\xf1\x5b\x01\x68\x20\xb1\x46\x5e\x82\x37\xeb\x79\xad\x9d\xbd\xe7\x5b\x53\xc9\x5d\x8a\xcd\x4a\x56\xde\xc8\xdf\x01\x0d\x00\xc1\x15\x23\x2f\xed\x1a\xc7\x7c\x73\x46\x02\x65\x29\x6e\x65\x07\xab\x8a\x6e\xe3\x91\xad\xa1\xb6\xb8\x4c\xac\x6a\xa0\xdc\xf2\x9a\xb6\x86\x08\x72\x04\xf4\xf8\xca\xb6\x0d\xb3\xa0\x26\x2b\xf4\xb6\xac\xeb\x4c\xe6\xe0\x00\xd8\x65\x55\x6f\xcc\xab\x78\x1f\xc7\xa1\x81\x0a\x8e\xec\xf8\xbf\xc4\xa5\x6a\xdd\x9e\xfe\xe3\xb3\xc0\x48\x17\x48\xea\xcf\x61\x60\x29\xf1\xfc\x76\x5d\xb9\x5c\xdb\x3c\x7e\x46\xa6\xb8\x84\x41\xc6\x0a\x7d\x10\x14\xa9\xf3\xf7\x89\x23\x61\x94\x37\x65\xf0\x1c\xb7\x6c\x4f\x83\xaf\x33\x2d\xd3\x1a\x59\x24\x90\xd0\xd4\xb3\x6c\xfa\x84\xff\x48\x31\x87\x42\x92\xa4\x18\x53\xbd\x14\x43\x6a\x43\xdf\x08\x14\x19\x1d\x7d\x5e\xe5\xa5\x1c\x88\x62\x7d\x3e\x75\x79\x6c\xd1\x9b\xdd\x87\x16\xb9\x98\x0e\x00\xd7\x31\x8f\x6c\xa6\xeb\x80\x79\x71\xdd\xc7\xfa\x40\x08\xca\x2c\xd7\xbc\xe3\x4d\xb7\x06\xd5\x00\xfe\x08\xc2\x18\xe6\xe3\x7c\xff\xbe\x64\x55\x05\xf9\x49\xb4\x07\xf6\x2b\xfc\xdb\xf7\x91\xce\x8b\x39\xb8\x84\x13\x4c\xb9\x2e\x40\xea\x04\xd9\x83\x9a\x37\x20\x31\x13\xa3\xa3\x06\x14\x97\xba\x23\x27\x18\x30\x02\xb9\x66\x4d\x2c\x85\xaf\xb8\x34\x6f\xb6\xc0\x67\x3c\x63\xb5\xb0\x01\xf5\x76\x7a\xd4\x0f\x28\x32\x3f\x40\x76\x80\x06\x1d\xf9\xcc\xa2\xdd\x32\xf0\x1d\xdb\x5f\xb1\x54\x68\xe3\xf1\xd2\x46\x22\x1f\x46\x97\x9a\x70\x7f\x07\x9a\x5a\x22\xe1\x5b\x11\xb7\x91\x6d\x42\x6f\x9a\x7e\xce\x7a\x07\x13\x59\x9d\xc8\x73\x55\xfe\xea\x54\x3c\x6f\x23\xb9\x27\x16\xcf\x78\xd6\x19\x16\x63\x9d\x64\x85\x85\xd2\x87\xca\x51\x6e\xdc\x04\x28\x8c\xc6\xcb\x04\x21\xc7\xba\x3c\xe4\x4f\xbc\x43\x98\x35\xfa\x2d\x13\x30\xa3\x93\x61\x3d\x69\x27\x1c\x2d\xfd\x94\xf9\xcd\x77\x8d\x25\xf1\x2a\xcd\x8b\xf1\xd0\x9a\x30\x08\x4d\xa7\xcd\x30\x88\x04\x9a\x90\x51\x44\x6e\x21\xcf\xba\xa5\xa1\xb9\x7d\xaa\x98\x90\x27\xc4\x29\x79\xe1\x64\x6e\x7a\xa8\xad\x21\xa9\xa4\x49\x57\x32\x71\x30\x03\x0a\x10\x43\x03\xcb\x14\xfc\xba\xda\xad\x5e\xbf\xad\x96\x1e\x64\xff\xf0\x75\xff\xf5\x75\x75\xd8\x6c\x57\xaf\xb3\xfd\x7a\xe3\x09\x4f\xa9\xa1\x91\xf0\xb0\xeb\xa1\xe9\x33\xb6\x3e\x0d\x86\xea\xdd\xd9\x81\xca\xe7\xf3\x4c\x0f\x13\x06\x86\x51\x11\x26\xfd\xe1\x52\x37\xeb\x06\x4e\xf6\x10\x58\xf7\x98\x48\x13\x33\xe5\xf7\xb2\x87\xac\xc8\xea\xb7\x6e\xf3\x33\x71\x62\xd0\xb0\x5b\xae\x47\x05\x22\x26\x36\x89\xdf\x14\xaf\x59\x3d\x27\xa3\xc6\x85\x2d\x75\x3e\x42\x73\xd0\x96\x05\xfb\x20\x1c\x52\xf2\xa0\x2f\x23\x07\xdd\xa4\x2c\x74\x3a\xdb\x48\x72\x8f\xce\x43\xcf\xd5\x4d\x8d\x20\x41\xe2\x62\x0d\x96\x40\xf7\xea\xc4\x34\xc2\x58\xa6\x89\x1c\x4c\x13\xf2\xc9\x2c\x90\x89\xb6\x7a\xe5\x65\x56\x3c\xa3\x17\x70\xdb\x95\x30\x2a\xd2\xa9\x2d\xc5\xad\x3e\xac\x83\x8b\x47\xe1\x73\x59\xd4\xf7\x2f\x02\xa6\xf0\xdc\x79\x9e\xfd\x71\xf8\xba\x7e\xd9\x53\xee\x9f\xdb\x48\x9a\xc8\x01\x43\xc3\x73\xa6\xaa\xb2\x35\x4b\x6c\x07\x16\x84\x61\x82\xc9\xe5\xe5\x66\x31\x18\x69\x16\x44\x49\x88\x28\xd7\x93\xf8\x01\xcf\xa5\xd7\x85\x71\x8d\x24\x10\xb8\x77\x4d\x27\x56\x57\xf4\xd0\x76\x81\x84\xf9\x03\x46\x55\x7d\x4e\xfe\xe6\x1c\x67\x01\x09\x13\xde\xf3\x0d\x7f\x83\x2a\x1b\xb8\xb9\x6e\xea\xb1\x80\x10\x8e\x4e\xf5\x1f\x99\x28\xeb\xb7\x6c\xf4\xc4\x24\xb6\x84\x86\xff\x81\xe6\xad\x9a\x5f\x3e\xd6\x7d\x8b\x48\x90\xce\x79\x8d\xc5\xe3\x48\x13\x31\x94\xb7\xbb\x5e\xfc\x2c\x20\xc0\xf0\x78\x3b\x3d\x7c\x7d\x41\x95\xb1\xf9\xe6\xe5\xeb\xce\xdf\x90\x32\x81\x94\xf7\xb2\x6c\x9a\xf2\x84\xe9\x65\xdf\x12\x47\x42\x76\x85\xd6\xcf\x78\x66\xbc\x94\x1a\xba\xf1\x66\x41\xa0\x42\xa4\xa9\x17\xcd\xba\xde\xbf\xc1\x33\x60\x1c\x69\x63\x9e\x32\x03\x7d\x2f\xc0\xb3\xc5\x32\x23\x88\x42\x8f\xf1\x24\x2c\x60\xd4\x72\xaf\x28\xeb\x89\xb7\x3e\x92\x65\xff\xf9\x0b\x54\xb1\xbf\x9c\x1b\xaa\xfa\x30\xd8\x76\xa0\x27\xc6\x82\x38\x4c\x91\xc9\x69\xf5\xbc\xdd\xff\x79\x78\x5d\xed\x36\x5f\x5f\x17\xab\xc3\x6e\xb5\x3f\xac\x97\x5d\xa7\x98\x87\x01\xf2\x60\xaf\xf7\xab\xa7\xf5\x6e\x6f\xf9\x14\x9f\xd6\xcf\xeb\x7d\xdf\x27\xd5\x83\x5c\x7c\x03\x9e\x87\x80\x05\xb1\x0c\x74\xdc\x53\x3a\xfc\x1f\x23\xd5\xed\xf5\x31\x82\xe9\xab\xb2\x11\x0d\xcc\x33\x57\xbd\x70\x1d\x17\x63\x01\xa7\x12\xa5\x16\x36\x67\x28\xbc\x52\xa4\xcd\x87\x8d\x87\x94\xbb\x6a\x0b\x1b\xcb\xb4\x1b\x97\x23\x3a\x68\xba\x0f\xc3\x53\x8d\xc7\x88\x41\xa9\x29\xe4\x0a\xde\x5d\x4e\x96\x6d\x7b\xfc\xb3\x29\x89\x63\xc7\x9b\xbb\x28\x4f\xa7\x4b\x31\xa0\xb7\xf6\x5d\x28\x45\x30\xe9\xa0\x9e\x75\xd7\x0c\xd4\xe5\x7c\x37\x66\xcb\xda\xbe\x88\xfa\x6d\x34\xe3\x53\x2e\x11\x2f\xd5\x9d\x50\x8b\xaa\xac\xeb\x45\x59\x14\x28\xb7\xfc\x8a\x47\xc2\x68\xcb\x98\xd0\xac\x4e\x7c\x6f\x16\xa4\x2a\x4c\xdd\xaa\x75\x59\xbe\x61\xdc\x7f\xda\x19\x92\xc4\x2a\xb8\xfa\x07\x92\xa1\x2d\x19\x38\x8b\x4c\xef\x4b\x9f\x27\xf4\xad\x2a\x92\x11\xef\xd6\xc6\x16\xaa\xe5\x00\x05\xcc\x02\xe5\x24\x4b\x6c\xdc\x05\xc1\x03\x7f\x27\xaa\xc4\x02\x05\xa1\x9b\xcc\x36\xa8\xe2\x52\xcb\xd7\xe7\xd7\x7f\xb3\xff\x71\x97\xe8\x40\x60\x11\xd7\xc2\xff\xd6\x6f\x83\x10\x10\x0b\x74\x14\x81\xdd\xad\x2f\x45\x63\xe5\x20\x9f\xba\x68\x12\x0b\x34\xd3\xb1\xdb\x54\x0f\xae\x52\x73\xfc\x44\x3a\x4d\x89\x87\x22\x39\x51\xb1\xee\x5a\x4d\xd1\xe0\x3f\x78\xa5\x23\xfc\x85\x5b\x5e\x11\x0b\x20\x64\xe8\xe0\x7b\x89\xa9\xfb\xf4\xfa\xfe\x02\xce\x84\xc3\xce\x62\xe2\xbf\x1c\xcc\xf2\x69\x57\x08\xb1\xc0\xe5\x05\xde\x47\xca\x7b\x37\x7b\x87\x41\x10\x7b\x62\x0f\x7b\x28\x59\x80\x4f\x17\x66\xc9\x4a\xeb\xf9\x0d\xe0\x3a\xed\x45\x09\x02\x3b\x7b\xa2\xd2\x4d\x71\x5b\xbe\x9e\x85\x01\xb1\xb1\xa4\x37\x51\xf7\xb0\x11\x16\x06\x94\x22\x71\xc8\x3c\x6b\xda\x93\xf3\x8c\x8e\xdf\x70\x0d\x84\x81\x52\x96\xd1\xfc\x65\xbd\x5f\xcf\x9e\x0e\xa7\x4b\x6e\x4b\x1c\xbb\x0e\x60\x10\x98\xf7\x79\xdd\xb5\xfd\xa7\x9b\x20\x61\x48\x58\xe4\x30\xa5\x48\x08\x05\x55\x57\x81\xd6\x3f\x74\x48\xa9\xa7\x03\x6b\x37\x97\xad\x50\x3f\xc4\x11\x3c\x83\x0c\x0b\x43\x91\x72\xd9\xb9\x8a\x6e\x72\x56\xa5\xbe\x78\x64\x2f\x0b\x43\xb0\x27\xe9\x09\xc7\xd3\x06\x01\x4c\x36\xd6\xf3\x65\x61\x14\x46\xc1\x88\x1f\x6c\x09\x3f\xa7\x9e\x69\xdb\xcb\xc4\x56\xff\x5a\x87\x7f\xde\x19\xe7\x48\xa5\x58\x01\x65\x93\xda\xee\x61\x7a\x71\x1f\x9f\x24\x1a\x5f\x44\x42\xcb\xc6\x8e\xb4\x67\x27\x09\xad\x2b\xbb\x9f\x52\x7a\xb2\x90\x44\x36\x70\xb7\x2d\xf3\x4c\xc1\x81\xf8\xa7\x27\x29\x47\xec\xb1\x70\x35\x4b\x9e\xda\xc3\xd5\x4b\xdf\x79\x52\x62\x84\x71\xda\x01\x59\xdd\x20\x2a\xf7\x8a\x96\x83\x85\x34\x54\x51\xe0\x35\x61\x4e\xd9\xaf\xeb\x04\x42\x7f\x47\x9a\x24\x48\xe4\xbc\x15\xb5\x14\x45\xf7\x95\x68\x2a\x92\x78\x6c\xe7\x17\x05\xd2\x71\xde\x2a\x5e\x66\x21\x15\x02\xc9\x21\x4f\x96\x05\x74\xa0\x8c\xe4\x3a\x30\x62\x21\x68\x96\x5a\x76\xf5\xef\xd0\x65\x6d\xc2\xf0\x1f\xa3\x7f\xbd\x55\x13\x32\x2e\x71\xbb\xe8\xe0\x71\xe5\x74\x68\x99\x0a\x31\xc8\xa2\xc1\x64\x05\x3c\x83\x82\x42\x4c\xce\xaf\x90\xa9\xd8\xf2\x7e\x62\xa1\x55\xd4\x3d\x8d\x8e\xb8\xf2\xd6\xba\xfa\x91\x15\xc7\x76\x26\x0f\x32\x21\x2c\x8c\x49\x8a\xa8\x6f\x2c\xe9\xf3\xfb\xd5\xf8\xe6\x31\x0f\xec\xce\xd2\x88\x23\xb0\x25\x08\x9d\x67\x45\xb7\xd2\x13\xc2\x05\xe9\x8c\xb7\x9d\x12\x39\xa0\xd8\x33\xf7\xed\x60\xcd\xf9\xa3\xa7\x84\xda\x18\x47\x1e\x30\x7e\x4d\x1e\xda\x19\xf4\xb8\xda\x1f\x9e\x57\xfb\xd9\x72\xb6\x9f\xf9\xdf\xe0\x24\xc6\x02\xfe\xdd\x62\xaa\x9f\x7c\x9d\xda\x65\x21\xe7\x04\xcd\x2c\x2c\x96\x43\x0e\x2c\x54\xed\x45\x29\x2b\xeb\x70\x7f\xc6\xb1\x71\x9b\xba\xc0\xdf\x5a\x68\xcc\x48\x9f\x73\xa1\x50\xda\x60\xe4\xfd\xb0\x30\x65\x12\x53\xa9\xcb\xed\xcb\x36\xbf\xd4\xa3\xdd\x2a\x35\x56\x5b\xfe\x52\x43\x85\xb5\xfb\x93\x12\x45\x16\x4a\x19\x3b\x3d\xe9\x1f\x50\xe4\x50\x1c\x7d\xa8\x92\x85\x52\x45\x43\x25\xc5\x97\xf5\xf3\xc3\x6c\xb2\x51\x48\xa3\x11\xc6\x94\x35\xe0\xf8\xdc\x3e\x3d\x30\x42\x15\x19\x14\x7f\x3c\x57\xb0\x3f\x76\x9f\x53\x31\x85\x0b\xc5\x72\x65\xe0\x9e\x6b\xc5\x14\xfa\x0e\xda\x63\x4b\x1f\xb3\x9f\x83\xbf\xa7\x80\xfe\xe3\xe3\xe6\xf1\xf5\xa5\xfb\xa3\x0e\x90\x5c\xe8\xa7\x2d\x14\x74\xc4\x51\xb7\xbc\x74\x16\x6a\x6d\x19\x54\x7f\xb6\xe7\x48\x3d\x0a\x28\xb1\x10\x74\xea\x43\xba\x55\xb3\x45\x0c\xf3\xae\x67\x10\x61\xa1\x09\x1c\x11\x25\xe6\xd3\x47\xf0\x5a\x16\x05\x49\x88\x73\xdc\x7a\x80\x36\x83\x75\x8b\xc0\xa8\xed\x19\xe3\xf3\x9e\x4a\x3d\xad\x4e\x61\x51\xc0\xa9\xf5\x59\x9b\xb2\x82\xdf\xe1\xa3\xbb\xbd\x12\x18\xea\xc9\xe1\x27\xe4\x5f\xcf\x37\xd8\xfc\x59\x14\x18\x8d\x15\x4c\xc2\xa2\x3b\xb7\xb8\x4e\xfd\x0d\xc2\x20\xd6\x9d\x71\xb4\xaf\x32\x39\x39\x6c\xa2\x90\x70\x14\xbe\x3e\x57\xd9\x7f\xe0\xb9\x2c\xfa\xdf\x0e\x49\x0a\x1e\x22\x51\x1c\x21\xb7\xce\xf4\x72\xaa\x9f\xc9\xa2\x30\x16\x96\xa3\xdd\x26\x66\xee\x66\x0a\x58\x14\xaa\x80\xa8\xb1\x1c\xa3\xc7\xa1\xdc\xdc\xad\xa3\x88\xc5\xb1\xcb\x32\x5b\x38\x83\x9f\x98\x93\x6e\x89\x42\x03\xf1\x15\x7a\x69\x70\x16\x45\x3c\xf5\x05\x4f\x96\x65\x27\x2b\x8b\x7a\x21\x72\xe4\x13\xfc\x0b\x1b\xf0\xff\xf7\x5f\xff\xd3\xd2\x98\xbe\xc0\xe9\xb6\x55\x30\x9e\x1e\x94\x18\x0c\x46\x9b\xac\xd0\x2f\xf0\xab\xf9\x0e\xf0\x43\x8b\xde\xa0\x18\x50\x34\xb0\x88\x1a\x5b\xfa\x3f\xcf\x4b\x89\xb5\x2f\xfe\x95\x99\x88\x70\x47\xdc\xbc\xce\x16\x4f\xeb\xff\x5a\x1d\x16\x9b\xe7\xe7\xf5\x6e\xb7\xde\xbc\x74\x5d\x94\xd5\xf6\xa9\xe0\x7f\x41\x35\x16\x8d\x97\xd5\x50\x2d\xde\x44\x75\xec\x4c\xa4\x28\xd6\xb6\xc4\xd1\xc1\x30\x6f\xbf\x66\x0c\x56\x4f\xea\x77\xf4\x34\xf7\x6f\xb0\x6a\xde\x32\x2f\x4a\xc9\xa2\x84\x06\x28\x61\x80\x91\xb9\xb3\xa8\xa0\x50\x1f\xaf\x80\xdf\x71\xbc\x3d\x45\x1c\x0c\x82\xe8\xe7\xf3\x3f\x3f\x61\x32\x60\x51\xeb\x5f\x3a\x0b\x78\x99\xfd\xbc\xd2\x72\x65\x51\x1a\x72\xa9\xba\x81\x1f\x50\xb5\x0d\xba\x08\x29\xbd\xd0\x21\xe4\xf9\xa2\xf4\xe7\xec\xa4\x9b\x0e\x55\xea\x59\x97\xeb\x8d\xb9\x55\xaa\x7f\xbd\xb1\xbb\x8b\xa5\x2b\xde\xb2\x72\x87\x9e\x07\x60\xd2\x87\x87\x81\x1a\x43\x8c\x1d\xc2\xf9\x56\xe6\x9f\x45\x4a\x70\x44\xd3\xab\xd2\xc3\x3d\xac\xae\xda\xb2\x4f\xf6\xf9\x81\xd7\x84\x1b\x35\x08\xcf\xac\x8b\xc9\xbd\xb4\xb0\x71\x08\xd9\x07\x77\xdb\x3f\x6a\x0c\xea\xe0\xe1\xb6\x04\x0b\xa2\x98\x16\x01\xdf\x58\xd5\x5a\xa6\x18\x9c\x38\xf4\x69\xc7\x3b\xcb\x59\x03\x13\xda\x3b\x40\x5b\xa8\x8c\x53\xa5\xe8\x66\x1d\x48\x69\xe1\x18\xa8\xb6\xd8\x8e\xfc\xba\x58\xed\xbf\x74\xcd\x5a\xe3\x4e\xe3\xe3\xc9\xed\x37\xa9\x27\xb4\xbb\xae\xab\x09\x4d\xe8\x94\x2a\xbb\xf2\xfa\xf1\x9e\x6b\x62\x9a\xda\x5c\x01\x88\xfa\x52\x7d\x6c\x0c\x3a\xcb\xf9\x74\x73\x31\x09\x47\x35\x38\x6f\x67\x76\x6e\xf7\x28\x89\x7d\x3d\x2e\x24\x90\x09\x9e\x82\xce\x27\x5b\x56\x59\xe1\x73\x8c\xb7\xfd\x21\x12\x40\x80\x48\x90\xdd\x7e\xf6\xb8\x8a\x0e\xfb\xf5\xf3\xea\xb0\x7a\xf1\xc1\x11\x12\x06\x34\xec\x43\x09\xcf\xeb\x97\xc3\x62\xf3\xb2\x7f\x5d\xcf\xbf\xee\xdb\x05\x3e\xbe\x57\x28\x12\xaf\x13\x6d\x4f\x59\x37\x4e\x93\x69\x45\x42\x2d\x8d\xf1\xc5\x9a\x16\xf6\x35\xc8\x92\x31\x12\x31\x6e\xa1\x42\x83\x9a\x4f\xe7\x76\x99\xc9\xad\x22\x19\xe3\x2a\xde\x3d\xac\xfd\xd5\xd4\x95\x82\xee\xab\x4b\xdd\x74\xf9\x51\x46\xa8\xa4\x78\xb8\xac\x6b\x1b\x24\x7a\x05\xa1\x3f\x0e\x87\x75\x61\x4a\xaf\xae\x36\xca\x7a\x30\x42\xc1\xc6\x5b\x2a\x50\x1f\x2a\xbf\x3a\x06\x49\x12\x58\x7e\xe5\x83\x75\xf4\x07\x67\xec\x64\x90\x93\x28\x74\xa1\xed\xfa\x92\x7b\x63\x95\x24\xcc\x20\xf0\xcd\xd5\x1f\x3b\x73\xf5\xf7\x3f\x17\xf7\x42\x5f\xfe\x3a\xa0\x81\x2b\x9e\x5f\xaf\xd7\x87\xdd\xe4\xa9\x38\xb3\x89\xb5\xd9\xf3\x50\xa3\x89\x91\x94\x10\xb4\x1b\x9a\x72\x9f\x9d\xcb\x55\xd1\x8c\x22\xa1\x24\x65\x11\xb5\x74\xe6\xcd\x5b\x56\xef\xa1\x6e\xc6\x57\x27\x9a\x59\x27\xa6\xdd\x5e\x36\xeb\x25\x12\x0a\x1c\x7c\xb3\xe0\x96\x31\xc0\xda\xc5\xfb\x2c\x87\xfa\xa1\x2a\x4f\xf3\xd2\x8b\x6c\xfa\x88\x04\x11\xd2\x90\xc4\x93\x54\x29\x04\x2b\xdd\xa3\xa0\x70\x57\x28\x12\x26\x74\xc0\x11\x5a\xbf\x0c\x58\x59\x18\x51\x29\x93\x7c\x50\x2d\xf5\xe9\xf1\x4e\x54\x1a\x63\x74\x76\x0e\xcd\x5b\x79\xce\xc4\x6d\xf3\x8d\xa8\x14\xc0\xa2\x91\xe7\xbb\xc9\x94\x53\xc6\x12\x99\xb7\xbe\xf0\x1e\x4e\x67\xea\x1f\x44\x87\x4a\x78\x8e\xba\xb5\x83\x49\xf9\x30\x21\x81\x08\xbc\xfe\xc6\x93\xa8\xbb\x4c\xa3\xdf\x86\x88\x89\x88\xe1\x83\xd0\xcf\x3f\x2f\xd5\x87\x75\x51\x7f\xbb\xc1\x85\xc6\x88\x71\x85\xb4\x33\xad\xbf\x41\x95\x99\x0c\x34\x66\x24\xc6\x33\xd8\x48\x85\xb4\x08\x67\xf1\xd1\x2e\x22\x5c\x65\xaf\xa0\x20\xeb\x40\x2e\x8c\x18\x65\x23\xa8\x67\x78\xd7\x19\x9c\x33\x7f\xb2\xd3\x20\xe4\xdc\x59\x63\x13\xb2\x53\x46\x83\x84\xe2\x20\x38\xc2\x8d\xee\x12\xad\xd0\x4a\x38\x68\xa8\x9b\xaa\xfc\x58\x9f\xce\x79\xd7\x66\x14\x7a\x0c\xa8\xe6\x71\xd8\xbe\xae\x30\xcc\xfa\x7d\xb5\xfa\xdd\x0f\x12\x0d\x69\xa4\x92\x2e\x56\x91\x3f\x64\x90\x77\xee\x1f\x0d\x53\x16\xda\x18\x63\xd3\x64\xc5\xd1\x1a\xdf\xae\x2d\x62\x29\x02\x1b\x3a\x4d\x06\x17\x72\x1f\x3f\x74\xc4\x63\xdd\x13\x03\xd9\x54\xa3\x33\xae\x7d\x2d\x33\xf7\x5d\x0d\x60\xca\x0c\x5a\xfb\xbd\x35\xf5\xdf\x44\x05\x6f\xb8\xa9\xdd\xc6\x82\x30\x4a\x08\x60\x36\x77\x56\x60\x6e\xff\xb5\x94\xe5\x68\x09\x51\x9a\x04\xa3\x23\x72\x67\x99\x7c\x11\x3e\xee\xbb\xa4\x96\xf0\xcc\x02\x4f\x17\x65\x51\x43\x96\xef\x2e\x59\x5d\x77\x5f\x85\x05\x02\x01\x96\xb3\xc5\x6a\x00\x0c\x63\x94\x49\x40\x8f\x73\x39\xc0\xc8\xfd\xff\x99\x92\x34\x89\x12\xd2\xf1\xc6\xb7\xbf\x71\x10\xcc\xff\x4c\xa2\x02\x2c\xa3\x7b\x85\xe2\xf4\x37\x38\x1f\x18\xe5\xc4\xe2\x54\xdb\x6f\xfa\xb2\xf7\xbe\xcc\x78\xe8\x38\x67\x78\xc8\x7e\x11\x55\x76\xca\x26\x56\x0b\xe5\x92\xe2\xd2\x71\x58\xee\x55\xa5\xa2\xe0\xf6\xea\xa6\x1c\xac\xd6\x10\x06\x51\x6e\x58\x7d\x34\x4d\x14\x7a\xff\x08\x3f\x5c\x22\x97\x7e\xde\x0d\xad\x08\x39\xa6\x22\x16\x1e\x9d\xf2\x37\x5e\x4f\xa4\xcc\x44\xc3\x98\xcb\xea\x78\x6c\x3f\xec\x34\x0c\xd9\x75\xb7\xa3\xb1\x10\xe7\x33\xe8\x5e\xef\xfc\xaf\x3e\xd0\xe4\x2e\x86\xa6\x2e\xd0\x93\x7b\x90\xf3\xe4\x45\x25\x09\x31\xab\xd1\x9a\x10\xef\xeb\xba\xf6\x9a\x75\x8c\xca\x38\xc4\x10\xdc\x12\xea\x26\x7b\x01\xd0\xa3\x49\xaa\xa2\x10\x39\xd6\x16\xa2\x7e\x23\x61\xb7\x32\x55\xac\x45\x77\x64\xef\x41\x9c\xea\xae\x25\x21\x48\x82\x92\x67\x36\x3b\x7a\xf5\x2a\xb7\x52\xaf\x8c\x2a\x9e\x50\x87\x40\x9d\x67\xcd\x6e\xbf\xbc\xb3\xaa\x94\xe1\x18\xf4\x41\x37\x75\xbc\xbb\x51\x1d\xd2\xd8\xd6\xf8\xd7\xcd\xac\xd0\xf3\xcb\xc7\x27\x7a\x9a\x8c\x42\x64\x8d\xa3\x76\xd4\xe6\x4d\xf9\x3d\x6b\xde\x76\x4d\x79\x0d\x97\xfe\x5c\xc5\xed\xaa\xdf\xb5\x46\x0c\xa3\xc0\x42\x48\xfc\x3c\x7c\x17\x95\xbe\xf7\x4c\x26\xe4\x68\x42\x58\xc9\x46\x34\x3f\x7d\x91\x7e\xd7\x43\x79\xff\xe3\x51\x9c\xa0\x7e\x1a\x46\x52\xa8\xa1\xcc\x8b\xca\xec\xcb\xf3\xc4\x20\xa3\xa6\xfd\xd8\xb6\x10\xb3\xaf\x4e\x67\xd4\x24\x1a\x1d\xf0\xd5\xfe\xcb\xea\xf5\x75\xb5\xec\xfe\x9e\x26\x3e\xf8\x65\x71\xb1\x4e\x6a\xa3\xb3\xd7\x59\x10\x46\x18\x99\xab\x2f\x43\x92\x7d\xc6\x02\x1a\x59\x9a\xac\xdd\xa2\x1c\x31\x71\x33\x16\xb0\xb4\x47\x87\xc0\xb4\xba\xc4\x5b\xae\x2c\xe4\x09\xf2\x30\xcd\x70\x20\xfc\xc5\xa1\x91\x38\x1b\x5b\x33\x38\xaf\xad\xdf\x79\x73\x9e\xb0\x76\xda\x5a\x32\x92\x99\xcc\xe1\x06\xdf\x0b\x63\x91\x60\xb1\xe3\x3a\x7c\x2e\xf5\x25\x1f\x1b\xe7\x2c\xd2\x5c\xd2\xce\xfd\x74\xa7\xe4\x64\xff\x60\x84\x04\xe8\x11\xbd\x3c\x95\x13\x6b\x90\x91\x58\x60\x0e\x6b\xfe\xb0\xfa\x63\x34\x02\x84\x5b\x0c\xd3\xbb\xc8\x7f\xec\x4b\x9c\x0d\xc3\x9d\x9b\x11\x6e\x69\x08\x4d\x56\xc1\xea\x27\x14\xcd\x53\x79\x0c\xfa\x46\x2d\x82\x9e\x8a\x77\x73\x86\x0e\x59\xc5\x18\x49\xad\xc3\x68\x2d\xc8\xb9\x67\x47\xfb\xfa\xba\x1e\xbf\x1a\x91\x2e\x08\x92\x97\x45\xc7\x36\x7e\x2f\x5e\xcd\x68\x90\x52\x5f\x78\x54\x40\xe5\x09\xba\x5e\xdb\x23\x3d\x53\x1e\xe0\xb9\x2f\xaf\x2a\x85\x26\xb7\xd1\x61\x92\x7a\xc4\xe7\x1b\xe8\xdd\x47\xdd\xc0\xc9\xd1\xe2\xb8\x3e\x2c\x00\x0f\x46\x78\x81\x5f\xcd\xcc\x1f\xdf\xa8\xcd\xee\xfb\x90\x94\xca\x81\x7f\x3d\x8c\x05\x5e\x51\xa8\x4e\xdd\x62\xc6\x38\xc5\xf4\xac\xcd\x07\x2c\x7b\xad\x04\xd7\x1e\x9b\x24\xf6\x26\xc7\xc7\x00\x9c\x34\xde\xae\x58\x22\x28\x6a\x9f\xef\x33\xa8\x0e\xdf\xb3\x5c\x2b\xaf\xea\xcc\x58\x22\x63\xac\x96\xcd\x4b\x07\xd5\xdb\x97\xed\x09\xf0\x58\x7a\x38\x37\x63\x89\x36\xc8\xab\x34\x2b\xb2\x13\x8c\x26\x07\x0f\x93\x14\x61\xea\x51\xf7\x17\xca\x2d\x7e\xc0\x21\x95\x76\xd6\x18\xba\x5f\xac\xcf\x58\x2a\x40\x46\x43\x61\x75\x57\x94\x71\x47\x2c\x98\xb1\x54\xd9\x48\x26\x66\xe5\xb7\x55\x29\x73\x38\x8d\xb0\xcf\x8c\x09\x0a\xd2\xb2\xd0\xfd\x2c\x7f\xc0\xac\x99\xba\xd9\x93\x71\x1a\xd0\x7b\x31\x26\x03\x0e\x6e\xcf\x72\x74\xa3\x37\x77\x3f\x26\x49\x8c\x83\x8f\xa0\x0b\xc7\x98\x79\x98\xad\x5f\x97\xaf\x9b\xed\x28\x01\xcf\x64\x9a\xe0\x2e\x52\xfa\x12\xc6\xa7\xb2\xfc\x71\x47\x0e\x97\x31\x29\x03\xcc\x7a\x76\x2c\xb5\x17\xe9\x69\x18\xea\xbe\x08\x72\xbc\xb2\xa5\x64\x31\x1b\x80\xe5\xeb\xeb\x6a\x03\xc6\x54\x42\xbc\x04\xbe\xb7\xe0\x37\xef\xfe\x04\x1d\xcf\x18\xa5\x08\x56\x86\x3e\x95\xc7\x76\x26\x78\x9d\xff\xdb\x0f\xac\x03\x1e\xf7\x1a\x72\x48\xaa\xeb\xeb\xca\x37\xc8\x98\x32\x12\xd1\xb8\xd2\x27\xf3\x77\x89\x22\xc4\xfb\x9f\x3e\x7a\x0a\x43\xc6\x74\xcc\x54\x57\x71\x31\x34\x4d\x7c\xbb\xa2\x2a\xf2\x18\xa7\xf7\x0f\xa8\x86\x19\x15\x06\x81\x46\x27\xd5\x0e\xcb\xbc\x2a\x7f\x5c\xed\x89\x40\x23\x2c\x49\x10\x5a\xaf\x8a\xa6\xfa\x58\xfb\x02\x69\x4b\xe3\x75\x2d\xea\x88\xf5\xe2\xb7\x67\x04\xb0\xd0\x8a\x6a\xad\x5f\x0e\x8f\x9b\xd9\xd3\x61\x35\x5f\x74\x8f\xa2\x08\x0c\x91\x96\xbb\xf2\x92\xdf\x39\x0d\x0c\x8f\x30\xd0\xb2\xad\xe0\x67\x56\x5e\xea\xe1\x78\x18\x45\x71\x2a\xfd\x44\x1c\x95\x63\x95\xf4\x7a\xf2\x5d\x1f\x61\x1c\x95\x9f\x3f\x08\x86\xca\x14\x2c\x0e\xa8\xc0\xe3\xc6\x4b\x37\x7f\x9f\x3d\x3d\x75\x6e\x50\x1c\x08\xcb\x9f\x5e\x5f\x8e\x47\xe4\xa2\xea\xe4\x64\x58\x1c\x06\x14\x6f\x7d\xa8\xa1\xd9\x54\x47\x51\x64\x53\x68\x3e\x8b\x43\x88\x31\x5e\x68\x00\xc6\x68\xca\xb6\x29\x45\xde\x10\x09\xaa\x3c\xc1\x2b\x14\xe5\xfb\x64\xe6\xc5\xa1\xb1\x78\xdb\xa7\xcd\x7e\xbf\x5a\x7c\x99\x79\x05\x64\x16\x47\x81\xad\x1c\xe8\xf6\x89\x11\xb2\xf8\x3a\x9e\x14\x47\x91\x32\x7a\x48\x5b\x5b\x4e\x1f\x95\x04\x14\xf7\x2f\x24\x34\x44\x77\xef\xef\xe0\x94\x59\x4c\xe2\x48\x5a\xa9\x87\xa3\x23\xf2\xf5\x0f\x49\x64\x64\xba\x80\x1c\x82\x61\xd6\x96\xdd\x7c\x90\x87\x8b\xa9\x48\xd0\x1e\x5d\xc2\x39\x2f\x3f\x3a\xa5\xf3\xb6\x41\x63\xba\x7b\xfd\xf0\x32\xae\xf8\xb8\x03\x94\xbc\x36\xe9\x63\x16\xca\xd8\xc9\x21\xa3\xe8\x11\xc6\x75\xa6\xdb\xdd\xf8\x6d\x92\x40\x68\xe5\xf8\xb3\x6d\x88\x34\xe4\xcf\x65\xd1\xbc\x75\x9f\x3d\x61\x41\x42\x3b\x91\x5a\x1f\xcd\xba\x2a\xcb\x60\x71\x12\x5b\x40\xbd\x14\x35\x5c\xd7\xf7\xb3\x38\x49\x19\xba\x88\xa7\xf6\xf6\x11\xb5\x54\xd8\xbe\x91\x27\x36\x9a\x67\x2e\x85\xae\x44\x56\xf7\xd9\x0b\xdf\x81\x87\x3c\x72\x44\x60\x48\x83\xf3\x24\xea\x66\xf6\x13\x2a\x71\x84\x9b\xbe\x59\xcc\xb9\x42\x1b\xa3\x80\xf7\xc7\x4b\x7f\x2c\xc7\x5c\x44\xc9\x10\xa5\x3e\xcb\x07\x01\x5b\xd7\x47\x18\x0d\x43\x32\xed\xdf\x6e\xa8\x7c\xb1\x58\x46\x96\x27\x1a\x90\x89\xee\x4f\xff\x03\x32\x4d\x99\x45\x3e\x97\xfa\xd2\x99\x9a\xb1\x12\x21\x96\x67\x2c\x36\x2f\x0f\xeb\xc7\xc3\xc3\x6a\xb5\x3b\x3c\x7f\x7d\xf2\xcd\xda\xe9\xad\xdb\x30\xaf\xbe\x55\x5f\xc0\x62\x4d\x02\xac\x72\x52\x1e\x96\xd8\x9a\x56\x13\xaa\x92\xf1\xc6\x14\xeb\x38\x49\x60\xc8\x42\xdb\x74\xa7\x7b\x0c\x5c\xc7\x0e\x9f\xb9\xbf\x34\x65\x95\x89\x7c\x2e\xe4\xc7\xa3\x73\x20\x7d\xe8\x2b\x06\x11\xa2\xee\x56\x5d\x64\x3f\xa0\x6a\xba\x8f\x62\x68\x18\x6b\xb4\x70\xca\x62\x3f\x20\x88\xfe\x7b\x10\xb8\xd8\xc4\x76\x47\x71\x1a\x72\x8f\xcb\xad\x3b\x33\xba\x76\x6e\x69\xae\x55\x73\x41\x6e\x13\x3c\xd9\xe6\x60\xca\x6a\xac\x7d\xf3\x79\x58\x20\x09\x28\x43\x66\x64\x27\xb5\xf5\x38\x58\x16\xae\x47\x18\x71\x04\xb9\x88\xdc\xfa\xcf\x7d\xb8\xf6\x1f\x93\x8e\x2c\x01\x0b\x03\x69\x5f\x58\xdf\x31\xea\x93\x28\x88\xc1\x0d\xac\x3d\x13\x27\xc5\x3a\x2c\x89\x84\x44\xee\x2e\x14\xf6\x43\x4a\x27\x4b\x74\xda\x35\x43\x48\xa6\x88\x88\x3b\xe0\x53\x96\x10\xb0\xcc\xfa\xba\x7c\x10\x59\x9e\x15\x47\x9b\x89\xf0\x03\x99\x50\xa9\x11\x05\x58\xc0\xfb\x72\x44\x5a\x73\x23\x6f\x94\xb0\x04\x40\x0e\xf5\xa8\x5c\x51\xd3\x64\x8b\x4d\xe2\x58\xc6\xd4\xe3\x11\xe6\x70\xf4\x05\xe3\x2c\x49\x84\x65\x61\x39\xa0\x95\xb6\x03\x71\x7f\x6f\x1d\xbf\x07\x0f\x53\x3c\xfd\x76\xab\xdd\x6c\x3b\x1b\xa1\x61\x13\x4e\x54\x1c\x7b\xcb\xcf\xd2\x25\x8f\x0c\xe2\x84\xeb\xd4\xe2\xed\x95\x28\x76\x50\xe8\xf6\x33\x3f\x66\xbe\xa0\x80\x25\x69\x08\x34\xee\xf5\x34\xfc\x7c\x45\x9a\x62\xdc\x3e\xc6\xcf\x92\x52\xed\xca\xc8\x5b\x93\x00\xb3\xdc\xcb\x11\x62\x99\x25\x22\x32\x08\x09\xf1\xc0\xa2\xdf\xae\xf7\xe4\x44\x90\x44\x0c\x62\x40\xc8\x1a\x9e\x5f\x8f\xc7\xf8\xb7\x85\x0e\xb0\x2a\xbe\xfd\x00\xb6\x28\xc4\x0f\x3e\xe9\x8f\x3a\xea\xa5\x19\xc2\x24\xfe\x9f\xcf\x9c\xfa\x44\x68\x9a\x38\x88\x41\x2d\x72\xd8\x42\xd5\x67\x17\x12\x29\x58\x62\x27\x62\xf9\x7e\xd8\xbf\xc1\xa1\x10\x27\x38\x94\xe6\x50\xa2\x5c\xd0\xc1\x5b\x31\x89\x62\x1a\x05\x06\xdc\xdc\xda\x67\x4d\x3e\x1d\x33\x4d\x6c\xe5\x1d\x20\xf9\xfa\xd9\xc3\x8f\x12\x2d\x09\xb7\x05\x3b\xc5\xe1\x7d\x68\x8e\x24\xa0\x55\x18\x76\x93\xed\xa9\x2c\x1b\x59\xfe\x9a\x2c\x4e\x43\x84\x0c\x06\x12\x2a\xdb\x72\x5a\xcc\xc2\x12\x43\x13\x5f\x5a\xf8\x0a\x22\x7f\x2c\x73\x3d\xb7\x74\x13\xb6\x03\x0f\x48\x80\x4e\xae\x65\x18\x2e\xea\x66\x80\x4c\xe0\x51\x1c\xe3\xdc\x72\xfc\xe8\xdb\x4b\x9e\x6f\xc5\x07\xd6\xe6\x8d\x57\x4a\xd7\x9f\x23\xb4\x65\x87\x42\xd3\x96\x65\x40\x7d\xdc\x8c\xbc\xdd\x4a\xab\x70\x12\x86\x62\x50\x16\x3d\x10\x0a\x62\x9c\xf0\x54\x59\x2e\xcb\x76\x27\xf5\xe0\xc4\x4f\xe7\x0b\x27\x10\x61\xf1\xc3\x6e\x3f\xdb\x7f\xdd\x1d\x96\xab\xd9\xd3\x61\xb6\xdd\xbe\x6e\xbe\xad\xfc\x6d\xa9\x60\x92\x0d\x06\xba\x07\x32\xfa\x05\xcd\xa9\x02\x1c\x67\xdc\x5a\x5f\xe0\x7d\x75\x2e\xd5\x5b\x77\xbd\xb1\xf2\x38\xb3\xfd\xc2\x95\x4a\xa3\x80\xad\x4f\x66\x70\x16\x11\x24\xdd\xd9\x35\x95\x68\xe0\x98\xa9\xe1\xe2\xe5\x8c\x05\x18\xd4\xab\xc6\x81\x4b\xce\x92\x04\x31\xff\xf2\xf2\xf1\x47\xa6\xfb\xbf\x0a\x4c\xd9\x9c\x2d\x1f\xf0\xe6\x4e\x4a\x84\xb3\xd4\x3a\x1f\x42\x6b\x47\x20\xf8\x17\xe3\xc4\x54\xe4\xbd\x20\x2b\x38\x59\x77\x3f\xa9\x55\x18\xe1\xcc\x6d\xbf\xa8\x4d\x45\x0f\xd5\xe0\x19\x8f\xc3\x08\x1f\xf5\x88\xf0\xc8\xee\xaf\x91\xe5\xfe\xdd\x43\x8d\x73\x61\xd7\x88\x42\x63\x05\xdd\xe9\x2c\xb2\x63\x31\x49\xab\x5d\xc5\x16\x47\x33\x9d\xb7\x26\x24\x1d\x04\xda\x17\x5e\x56\x76\x5b\x95\xa7\xd2\x56\x0d\xf9\xae\x52\x22\x57\xc7\xf3\xec\x8f\xf5\xf3\xd7\xe7\xc3\x76\xf6\xba\x5f\x2f\xd6\x5b\xac\x26\x19\xd1\x88\xb7\x7d\x35\x73\xbc\xaf\x2f\xa5\x16\xb9\xc4\xd2\x0a\x4b\x81\x3d\x9a\xd7\x49\x6a\x45\x35\xfe\xd9\x85\xd6\x78\x22\x24\xd1\x9d\x74\xc5\x4e\x18\x68\x3e\x9e\x4b\xdd\x0d\x00\xe7\x09\x7e\xab\xdd\xdb\xa5\x69\x9c\x61\xde\xb5\xa9\x10\x55\x93\x6d\xfd\xd7\xee\xbd\x83\x9b\x70\xc1\x62\x24\x38\xb3\x6a\x67\xab\xe6\xad\x7b\x53\xdf\x43\xa6\x5e\x42\xbb\xe7\x24\xcd\xfa\xe9\x26\x55\x80\xeb\x3d\x2b\xb2\x66\xc4\xd1\xf2\xf9\x04\x90\xc6\xe6\x33\xeb\x31\x4f\xe9\xd8\xae\xe3\x8a\x31\xb0\x4c\x54\x39\x60\x45\x28\xe8\xfa\x21\x13\x93\x3d\x87\x2b\x45\x12\x57\xc0\xb9\x80\xa2\xbe\xb4\x03\xd9\x83\x1f\xbd\xf1\xc4\x35\xa1\x11\xe9\xe3\xa0\xcf\x99\x2b\x04\x9b\x7f\xcc\x61\x7a\x4b\xad\x2c\x5e\x17\x39\xa0\x2f\xc5\x0f\xba\x2f\x7b\xd8\xa5\xef\x63\x88\x49\x06\x30\xaa\xf2\x74\xce\xa1\x01\xfd\x9c\xe5\x50\x37\x65\x31\xd9\x94\x39\x30\x5b\xac\x77\x84\x4e\x79\xd3\xd1\x1e\x5f\xf3\x3d\xf8\x4b\xc0\x60\xbe\xc9\xd2\x2f\xdb\xd5\x30\xde\xdd\xc6\xf3\xd6\x44\xc2\xc6\xaa\xaa\xf2\x5d\xb7\xeb\xfb\xf0\x0a\xf5\xa5\xf3\x5c\xb9\x91\x06\xb3\x1b\xde\x1b\xdb\x14\xab\xaa\xba\x17\xc6\x4b\x83\xd0\x0a\x2a\x9c\x0e\xf5\x19\x13\x1a\xda\x2b\x89\xb2\x34\x48\x2d\x73\xf9\xbc\x2a\x9b\x37\xc8\xc7\x27\x45\x1a\x98\x00\x3f\xdc\xf2\xeb\xef\x3d\x81\x0d\x4b\xa3\xd0\x20\xad\xd9\x59\xe4\x42\x67\xc5\xea\xdf\x97\xac\xe9\xee\x18\xc5\x02\xcd\x06\x27\xba\x21\x72\xd8\x4c\xf0\x11\x29\x89\x29\x46\x21\x2d\xee\x7a\xfd\xb2\xbc\xf3\xe0\x24\x11\xe8\xbf\x66\xb5\x0d\x85\xf7\xf4\x85\xf7\x2e\xe0\x16\x4e\x78\xc6\xbc\x7e\x0f\xde\x48\x29\xb5\xda\xaf\x4f\xfb\x3f\xb7\xdd\xdf\x74\x9a\xda\x83\x61\x29\x1a\xf1\xe2\xa2\x98\xbe\x11\x44\xdc\x3e\xe2\xea\xf1\x71\x77\xd8\x6f\x0e\x5f\x66\xfb\xc5\x97\x43\xb8\xfb\xd7\xd7\xf5\xeb\xeb\xca\x3b\x19\x29\x4b\xa4\xf1\x4c\x24\xad\xe1\x79\x2d\xe1\xc3\x52\xa6\x52\x94\x35\xeb\x4c\xcf\x7d\x06\xd5\x70\xef\x49\xe3\x28\x44\x93\xe1\xcb\xec\xcf\xd9\x7e\x73\x78\xd8\x3f\x1d\x76\xdb\x55\xb7\x67\xb4\xed\xf6\xac\x09\xba\xbf\xf0\x04\x8b\x69\xb2\xa2\x28\xd5\x24\xd0\x9e\xc6\xca\x18\x1f\xbd\xf7\x79\xa5\x9b\xf2\x1d\x2c\x4d\x58\x9c\x86\x1d\xa6\xc9\xf1\xae\xdd\xb4\x89\xd3\x44\x04\x7e\x75\xe2\xc3\x77\xa6\x77\xca\x85\x0d\x33\x7c\x80\xa8\xf2\x8f\x79\xa7\xa2\xe1\xdb\x53\x96\x78\xa8\xec\x4e\xe4\xa2\xfa\x18\xe0\xea\x3f\x8d\x0d\xa4\x29\x53\xca\x02\x23\xf2\x52\xe8\x0e\x2f\x36\x22\xb7\xf9\x0c\xd4\x92\x0a\x1a\x83\xaf\x51\x6b\xcf\xd7\xd7\xf6\xb0\xbe\x66\x64\xf6\xbd\x13\x8a\x3a\xe6\x19\xfa\x22\x59\x71\x1c\x44\x8b\x52\x91\x2a\x5c\x73\xed\xad\xea\x2b\xd6\x46\x96\x0a\x88\x50\xf0\xba\x1d\xed\xa5\x68\xc0\x42\x16\xfd\xd5\x92\xf1\xd8\x7a\x8d\x42\xff\xeb\x22\x8a\x26\x6b\x3e\x86\xd8\xef\xdb\x9e\x56\x2a\x53\x85\x07\xc8\xd7\x1a\x26\x68\x87\x54\x6a\x0b\x86\xf0\x76\x77\x05\xba\x8f\xf6\xde\xa9\x14\x1f\xdf\x5c\x87\x21\x47\xf0\x66\x71\x84\x7c\x52\x10\x92\xea\x28\xf0\x91\x5b\xc7\x9f\x5b\x63\xd6\x69\x32\x81\x74\x2c\x75\xe8\xde\x6b\x20\xc0\xc4\x52\x9d\x08\x61\x91\x6e\x85\xc5\xf4\x3c\x8b\xe2\x22\xf2\x81\xc0\xdb\xe4\x61\x20\x46\xc0\x78\x8f\xe3\xfa\x0b\x88\x53\x0a\x41\xe2\xf9\x1b\x1e\xb2\xaa\xf6\x1c\x32\x37\x23\xa2\x29\x44\x89\x74\xa0\xfa\x8e\x0d\xfb\x1a\xed\x36\x99\x7e\x10\xa7\xae\x82\xb2\xe9\x34\xc7\x50\xe7\x63\x3a\xae\x3e\x9a\xd1\x05\xe2\x53\x00\x21\xfb\xd8\x55\x7b\x4e\x0c\xcb\x6b\xdb\x76\x40\x90\xa6\xe7\x0b\x72\xe6\x71\x3d\x09\xbd\x4c\x06\xc9\xa4\x80\x1b\x67\x2e\xea\x06\xad\x49\x5c\x6c\x5f\x90\x48\xd4\xdf\xd9\xc8\x34\x76\x28\x18\xeb\xfd\x6f\x2e\x8d\x2a\x4f\xbd\xbe\xcb\x35\xfe\x5b\x04\x69\x8c\x51\x2b\xbb\x67\x0f\x8b\x82\xad\xba\xf0\xe8\x29\x44\x18\x52\x13\x3a\xd0\x76\x33\x58\x22\x22\x4c\xb8\x2f\xa9\xd9\x5b\x9c\x77\xe0\xf3\xc6\x22\x0a\x00\x73\xae\x6f\xa2\xfe\x4b\xa6\x5f\x26\x48\xc8\xb0\x28\x52\x97\x3e\x1e\x7b\xa7\x9f\xe6\xc6\x7d\x56\x9c\x64\x0b\xcb\x4e\x36\x75\x3e\x05\x55\xb6\xfe\xcf\xe2\xae\xea\x25\xe4\xdd\x11\x28\xa8\x36\xe8\xc9\xfc\x9d\x6a\x9a\x9b\xee\x87\x60\x49\xa4\xed\x61\xf1\xba\x2a\x8e\x95\xf8\x39\x4e\xa5\x0b\x06\x16\x0e\xf7\xd5\xd2\x8e\x4f\xc7\x93\x99\x50\xe9\x1e\x8d\xd2\x8e\xf8\x88\x34\xc0\x75\x8b\x43\x81\x69\xc9\xd7\xef\x3b\xef\x43\x8a\xd6\x6a\x4d\xbb\x60\xa2\xfd\xde\x7e\x5f\x16\x49\x90\x60\xe2\x66\x59\x5d\x8e\x4b\x10\x9d\xb4\x15\x13\x89\x56\xe0\x38\xf5\x6c\x1c\xa4\xbb\x86\x0b\xca\xfd\xd9\x51\xe6\xda\xc6\xba\xa3\xc9\x93\xa4\xa1\x46\xc6\x58\x1b\x35\xb3\x13\x1b\xc9\x78\x4f\xa0\x07\x0c\x6b\x37\x6d\x1b\x21\xd2\x18\x05\xa1\xcf\x65\xdd\xfc\xb3\x94\x96\xe9\xe7\xce\x6c\xb8\xbd\x2b\x0a\xa1\x21\x74\xe2\xe3\xab\xd3\x39\x2f\x3f\x00\xd6\x13\xd8\x83\x90\x42\x42\x4f\xe5\xe5\x54\x76\x06\xac\x3d\xc3\xd0\xc2\xe4\xf6\x2a\xb0\x5c\xc3\x7e\x1d\xdc\x16\xa1\x61\x42\x45\x04\x2d\x1d\x4c\x45\x0d\x2a\x66\x85\xa2\x84\x0e\x35\xe4\x47\x4b\x5f\x28\xae\x22\xf7\xf4\x3b\x68\x3f\x5a\xbb\xb7\xf6\x45\xe4\x4c\xe8\xd4\x78\xec\xb8\xa7\x6d\xbc\x3d\x0e\x10\xd1\x04\x3c\x01\xc0\xd3\x60\xe3\xb7\x10\xc2\xd1\x55\x31\xf5\x17\x49\xf0\xca\x98\xb7\xb7\x3d\x01\x2a\x46\x5a\x79\x5f\xcf\x97\x35\xd9\x7f\xba\x08\xe6\x3f\x2e\x43\x06\xcd\x69\x94\x64\xb4\xe9\x0a\x13\x09\x84\xc6\x5b\xbc\x1e\xe8\xe5\x72\x3f\xf9\x4a\x46\x30\x0c\x50\x59\x80\xdb\xe1\x11\x9a\xe7\x8f\xa1\x9a\x23\x93\x01\x0d\xbc\x10\x0d\x2e\xec\xdb\x74\x0f\x4c\x06\x2c\xc4\x50\xc9\xf3\xea\xfb\x6e\xb8\xf8\x64\x10\x87\x36\x4c\x2e\x7e\x80\x27\x0c\xf6\x4d\x52\xf1\xbe\x18\xb1\xfd\x82\xb3\x42\xdb\x68\xc8\xcd\xe8\xbe\x0c\x74\x12\xf6\xd0\x7a\x0f\x4f\xde\x98\xe9\x51\xd5\x1f\x04\x32\x00\x26\xdd\x82\x82\xe6\xad\xba\x42\x8d\xcb\x50\xa5\x3c\xf1\xbb\xe9\xfc\x52\x39\xc4\x51\xf7\x90\xa1\xd1\x08\x34\xf0\x59\xe0\x75\xfb\xb1\xb7\x9b\x75\xd7\x21\x4a\x6c\x25\x5d\x03\x75\xf3\x20\xb2\xfc\x39\x2b\x9a\xef\x6f\x28\x4c\x71\x3e\x77\x0e\xa0\x8c\x04\xc7\x78\xb8\x4d\xe3\x8e\xfc\x54\x49\x12\x8d\xd9\xf7\x2f\x65\xf3\x2c\x0a\x14\x51\xff\x6b\xc4\x93\x24\x22\x51\x16\x1a\xd9\x5a\x06\x5e\x1b\x65\xfc\x76\x31\x8f\xf1\xdc\x95\x97\xaa\xb0\x94\x45\x2e\x1e\x6c\x79\x8b\xfd\xc3\xc5\x4a\xc7\x71\x5f\xe5\x39\xa2\x2c\x1a\xfd\x66\xac\x6d\x61\x88\x98\x3c\x9f\x6b\x4e\x02\xc0\x73\x03\xcb\x55\xe0\xe9\xdb\xd3\xe4\x71\x12\xc1\xb1\x00\x61\x09\xcb\x2b\x93\xf8\xaf\x34\xcb\x3e\x8f\xb5\xca\x44\x12\xe6\xf0\x03\xdf\xca\x06\xaa\x7a\x56\xd4\xbd\x3d\x24\x79\x1a\x21\x00\xd3\x67\x49\x1e\xca\x6a\x53\x20\xb1\x97\xef\x91\xf2\x00\x83\x58\x67\xa8\x4c\x39\x16\x2a\xb9\x09\x45\x90\x29\x10\x5c\x5e\x6f\x48\x85\xed\x48\xd0\xd0\x05\xed\x02\x03\x52\x84\x11\x2e\x8b\xb3\x15\x27\xfe\x0e\x99\x63\x41\xeb\x3a\x10\x82\xb8\xee\xb5\x2a\x31\x26\xeb\x82\x34\xe3\x77\x13\x24\x56\xa1\xe7\x7a\x33\x42\x01\x82\x88\x46\x23\x2f\x0c\xc3\x64\x6a\x93\x41\x15\x0d\x21\x99\x52\x86\x29\xe9\xb5\xe2\xd7\xad\x63\x8f\x26\xce\x2d\x34\xab\x94\x32\x42\x24\xd7\x53\x56\x88\xd3\x47\x37\x79\x15\x61\x18\x19\xde\x35\x15\x0c\x90\x65\x37\x18\xd8\xfc\x05\xc2\xe0\x11\xf5\x55\x66\xe5\xe5\xb3\xb2\x0e\xa9\x8c\x84\xa4\xf3\x19\x27\xf6\xad\xd4\x42\x63\xa6\xa6\xc8\x8a\xe6\x6d\x60\xeb\x48\x13\x1a\x4c\x4e\x8a\xce\x27\xb5\xe4\x45\xd6\x71\xe8\x7a\x69\x19\x38\xda\x7a\x4c\x1e\x2f\xde\xb2\xfc\xca\x79\xbd\x3d\xa1\x54\x40\x0d\x66\x36\xab\x1e\x38\x31\x85\xd6\xa8\x20\xe5\x64\xe0\x6c\x23\x4c\x0b\xd3\x31\x83\xb1\x50\x01\x00\xca\xc0\xb8\x8a\xe3\xa7\xec\x3f\x1e\x02\xa8\x42\x62\x2c\x26\x6b\x84\x75\x78\xca\x4e\x53\xf7\x46\x85\xa9\x30\x81\x17\x92\x6e\x87\xcf\xc1\xcf\x86\x63\xa9\x22\x9a\x78\xb1\x83\x3f\xc5\xc7\xcb\xe5\x34\xb9\x49\xa4\xe2\xc0\xf8\x9c\xc3\x95\x84\x01\x53\x91\x26\x88\x71\xaa\xca\xd3\xb9\x5b\x3a\x2a\x02\x8e\x4b\x47\x96\x75\x3d\xd0\xd9\x63\x2a\x32\x02\xd1\x2e\x2f\x80\xc0\xc6\xbf\xa8\x0c\x54\x24\xb0\x51\xe2\xd6\xd9\xad\xae\x21\x5d\x8a\x06\x12\x93\xf5\xd2\xba\xb7\x58\xe0\x31\x79\x01\x2a\x38\xe2\xe8\x54\x59\xe9\x3f\xa7\x6d\x92\xe2\x06\x7b\x68\xc4\xd1\x32\xe1\x8f\xc6\x86\xf1\x08\x43\x51\xab\x17\x6f\xbd\x29\x06\x31\x1a\x5b\xa7\x6c\x52\x44\x7e\x07\xd7\xa1\x62\x4e\xf0\x4b\x9e\x1c\x99\xbc\x3f\x79\xc6\x0f\x92\x44\x14\xed\x49\x2f\xda\x57\x4f\x83\x81\x2a\x89\x6c\xe1\x5d\x3b\x12\xe2\x63\x7a\xb9\xb4\x87\xdc\xb3\x57\x56\xf6\x57\xa5\xa1\x9d\xcc\xfe\xa0\xd9\x77\xd1\xa7\xfc\x03\x6b\x2c\x40\x2f\x44\xaf\xa0\xca\x54\xda\x1a\xa8\x6e\x57\x9f\x2a\xaf\x32\x95\x02\x0b\xc1\x7b\x57\x68\xe4\x8f\xf7\x9e\xc9\xd7\x13\x4a\x78\x50\xbd\x15\xf4\x1f\xe5\xb3\x95\x92\x31\x1e\xa3\xdb\xaf\x4f\xa3\xf3\x5f\xe9\x80\x72\xf7\x10\x3e\xc4\xe1\x9f\xc5\x2f\x10\x1d\x4a\xc4\xf8\x6f\xc5\xc7\xa7\x50\x01\xdf\x9d\xc4\x3c\xf6\x3c\x55\x3b\x9b\x6b\x7d\x1a\x83\xac\x7a\x03\x40\x01\x4d\x2c\x3b\xc2\xe9\x63\x09\x2a\x3b\x75\xd9\x62\x05\x2c\xb2\x3c\xd0\x43\x0e\xdb\x7b\x19\xdf\xf1\x23\x40\x42\x3c\xa9\xc5\x73\x56\x7c\x2b\xa7\x56\x85\x32\xc4\x6a\xa5\xe2\x5c\x1e\x22\x34\x75\x20\x38\xc2\xc6\x97\x22\x1b\x53\x8c\x31\x1d\x00\x15\x8e\x31\x79\x5e\xde\xa9\x67\xd5\x61\x1a\x61\x8e\x5a\x57\xe5\x79\xfc\x0d\x74\xa8\x0d\x86\xdb\xeb\xa8\xfb\x53\x94\x44\x94\xf7\x05\x6f\xff\x37\x2e\x76\xa6\x49\x10\xe0\x97\xb1\x91\xc2\xd9\x1d\x51\x00\xa6\x29\xe1\x96\x27\xc0\x6a\xa4\x5a\x47\xc8\x22\xfd\x9c\x2c\xbf\x7f\x20\xca\x35\x4e\x62\xcb\x76\xe2\x89\xbb\xa7\xe5\x44\x9a\x4a\x6d\x49\x6f\x44\x75\x84\x41\xf1\x90\x66\xa1\x46\xe6\xf4\xc3\xf9\x4d\xd4\x10\x59\x8c\x47\xd7\x28\x29\xe6\xe5\xb6\xaf\x2b\x2c\x7e\xdc\x3f\xaf\x5e\xf6\x07\x0f\x0d\xda\xad\x16\x9b\x97\xa5\x07\xa8\xe8\x38\xb4\x41\xde\xed\xbb\xfe\x22\xea\x39\x40\xb1\x83\x31\xdd\x1a\xd3\x71\xc2\x52\xe7\x2b\x3c\x42\x51\x9e\x26\x9f\x59\xc7\x9c\x04\xb6\x58\x04\x8f\x17\xcb\x14\x5e\x96\x7f\x99\xc8\xbf\xf9\xef\x9d\x5d\x47\xc7\x5a\xa2\xc7\x76\x29\xb6\x55\x79\xca\x6a\xd0\xdb\xf2\xdc\xbd\x05\xc4\xb8\x2c\x5d\xea\xed\xff\xd1\xf6\x6e\xcd\x8d\xe3\x4a\xd6\xe8\xdf\xe9\x87\xfd\x40\x12\x24\x00\x3e\xca\xb2\x5c\xd6\xb4\x6d\x79\x4b\xaa\xaa\xee\x3d\x31\xa1\xc0\x25\x61\x71\x4c\x91\x6a\x92\x2a\x97\xfb\xd7\x9f\x60\x02\xe0\x4d\xb4\xbb\xe6\x9c\x38\x5f\xc4\x37\xd5\xdb\x84\x78\x05\x12\x79\x59\xb9\xd6\xa3\xf8\x39\xd8\x25\x35\x23\x1c\x2b\x25\x5d\xee\x13\x69\xfb\xae\x78\x1e\x34\xd3\x04\x29\xee\x1f\xe0\x45\xa8\xf7\x2d\x9c\x2f\x4d\xcf\xc0\xe1\x4f\xc6\x83\xd0\x73\x70\x6d\xa1\x2e\x2f\x95\x1a\xbb\xb1\x9a\x8b\x28\x10\x9d\x7b\x3e\x70\xa0\xee\xc0\x4f\x03\xcf\x87\xce\xfd\x4f\xa0\xd3\x98\xc2\x86\xcd\xfc\xda\xb5\xd1\x29\xb5\xb9\xa3\xd5\xfe\xfe\x70\xbf\xd8\xde\x1e\x96\x0b\x9f\x44\xd6\xa9\xe6\xe8\x8f\xfa\x96\x84\xe6\x88\xd8\xa8\x6b\x38\x8f\x4e\xb5\x49\x95\x07\xce\xe7\xef\x07\xed\x9a\x1c\x0f\xcd\x11\x0e\xb5\x9d\x46\xe3\x97\x92\x1a\x12\x42\xaf\x0c\xe5\xd3\x70\xa4\xbb\xb6\x49\x92\xbe\x4d\xb6\x17\xad\x7d\xae\x1c\x70\xf0\x0a\xab\xf4\x0b\x41\x9b\x16\xa1\x42\xc7\x06\x77\x5a\x44\x7f\x7f\xc0\xb0\x9e\x68\x91\x50\xe4\x3e\xf6\xc0\x9c\xf1\xed\x4b\x6a\xbf\xe9\x6b\xd6\x34\x50\xd4\xb7\x15\x86\x23\xfb\x72\x7f\x04\x94\xee\xfd\xad\x1b\xa7\x10\xd8\xbf\x79\xde\xaf\x37\x4f\x8b\x87\xc3\xf3\x66\xf3\xd0\x1d\x14\x91\x24\xdd\x33\xee\x41\x9c\x5c\x2f\xd4\xac\x4b\xac\x55\x68\x85\xb9\xcf\x87\x1a\x1a\xc7\x6b\xea\x0d\xc0\xec\xb6\xa2\x55\x0c\xc4\xe9\xcd\xb5\xdb\xa4\x68\xa0\x12\xb9\xa5\x82\x99\x7c\x40\x6d\x08\x66\x28\xed\xd3\x36\xf5\xee\x98\x0d\xe2\x2b\x0d\x21\x78\xa5\xb7\x6f\x50\xe8\x29\xdf\x85\x36\x49\x88\xc1\xfa\x72\x7f\x3f\x9a\xd5\x86\xa5\x84\xf8\x79\x71\x0b\x3f\x20\x2f\xcf\x7d\x42\x46\x1b\x15\x05\x8e\xff\xc6\x26\x63\x90\x4b\x66\xd6\x0a\x42\x10\x48\xe8\x11\xf6\x77\xad\x29\xac\x3e\x00\x33\xcd\xbb\x48\x10\x28\x86\x12\xb9\x8e\x6b\xbe\x5d\x66\x08\x05\x1e\xbd\x65\x08\xa0\x5b\x88\x3b\xc7\x29\x2a\x72\x35\x43\xa5\xda\x0e\x4d\x85\x63\xad\xb4\x11\x46\x87\x5f\x83\x30\xb6\xcd\x45\x07\x3b\x41\x2c\x2e\xc3\x1f\xa3\xf6\xa5\xc8\xcb\xfb\xf3\x76\xb5\xbf\x5d\xed\xbb\x3c\xaa\x2b\xec\x7c\xea\xea\x41\x48\x45\x30\x54\xd9\x17\xb3\x69\xdb\xc9\x6f\x98\xc2\xd8\xd0\x00\x78\xb0\x98\x3f\xa2\x6c\x9e\xc0\xf7\x3e\x8f\xb7\x14\x88\x42\x85\xf6\xa1\x23\xfe\x84\xb7\x9b\x4b\x51\x8c\x33\xdd\x1f\xf4\x91\x74\x8c\xa4\xfe\x5c\x44\x01\xe9\x99\x58\x86\xdd\xb0\x10\xc5\x01\xc6\x46\x8d\x78\x85\x55\x73\xbc\x2b\xab\x4e\xbd\x74\xfc\x24\x51\x1c\x78\xb9\x78\xcb\x5c\xb0\x2a\xa0\x7a\x79\xbf\x79\x9f\x6d\xee\x86\x98\xc4\x68\x99\x9e\xe0\x6d\xd7\x0c\x95\x7e\xc7\x67\x8d\x63\x8d\xa8\xaf\x9b\xf5\x7e\x33\x9c\xc1\x10\xb3\x08\x37\xa1\x5c\x8d\x09\x2a\x20\x16\x3a\xb5\xf9\xa9\x99\xca\xdd\xf8\x1e\x68\x00\x26\x72\x75\x84\xf9\x14\x3e\xd0\x08\x80\x7a\x25\x35\xdb\x00\xfa\xfb\xbb\xb2\xb1\xca\x0c\x4a\x07\x58\x90\xa2\xa3\x22\xf2\xfc\x51\xd4\xaf\x5f\x2e\xbe\x47\x15\x18\x00\x12\x01\x6f\x97\x4b\x9f\x04\xd8\x43\x57\x10\x06\x1e\x30\xd1\x11\x0c\xe2\x86\x5a\xd7\xd7\xb2\x26\x09\x70\x22\xc0\xcb\xbf\xfa\x3a\xdb\x28\x77\x03\xdc\x08\x8c\x1e\x1d\x47\xfb\x48\x7a\x7b\xf2\x76\x53\x22\x89\xe9\x25\x22\x2c\x3f\xaa\x3f\xa6\x94\xad\x20\x0e\xba\x5a\x9f\xad\xdf\xe9\x87\x88\x30\x15\x5e\x0a\xb2\x28\x1b\x51\x4d\x88\xd9\x40\x44\x16\x43\x06\xcd\xb1\x3d\xa0\xba\x1f\xd2\x08\x5b\xb0\xb3\x22\x6b\x3a\xe2\xef\xcf\x17\x97\x0c\x34\xf4\xd5\x02\x27\x4b\xbf\x17\xaf\x50\xdd\x00\x8a\xe8\x3d\xba\xff\xfe\xe0\x51\x75\x48\x31\xb0\x3d\xb4\x7e\x66\x95\xe9\x17\x78\x12\x4d\xf6\x03\x06\x21\xc2\xf4\x17\x14\x7c\xc9\xbf\x57\x4c\xe9\x5e\x8f\xe6\x02\x63\xfd\x33\x2a\xec\xb7\x5b\x4c\x0f\xc9\x04\x50\x09\xc7\x46\xf8\x93\xa8\x5e\x3b\x0c\xf5\xbc\x05\x30\xa1\x20\xce\xd6\xde\x97\xce\xdc\x7e\x5a\x21\x02\x43\x43\x4c\xc1\xe0\x66\x69\x7f\xe0\xbb\xb6\x26\x03\x99\xec\x24\x2b\x06\x82\xb1\x37\xef\xeb\x49\xae\x05\x8c\x26\xd8\x7b\xd5\x6e\x48\x50\x35\xe3\x82\xd3\x68\x45\x98\x40\x04\xe8\xcb\x6e\x9e\x56\xfb\xf5\xad\x0f\x2b\x4d\xc8\x52\xc4\x3a\x9e\xca\x42\x54\xea\x58\xdf\xbc\xcf\xc8\x7b\x26\x26\x62\x36\xea\x41\x52\xc0\x8b\x74\x6b\xb7\x0d\xec\xea\x1b\xc8\xcb\xb7\xff\x40\xe5\x53\xd2\x26\x92\x0a\xdd\xa4\x4b\x91\x35\xf5\xa6\x68\xcd\x8f\x23\x01\x77\x03\x88\x22\x98\x92\x7f\x9e\xba\x76\x26\x0e\x23\x0c\x27\x91\x2b\x07\x9f\xfd\xb6\x5f\x6b\x26\x8e\x00\xa9\x3e\x16\xcf\xfb\x6f\xdd\xdf\x74\x8a\xab\xc6\x88\x2c\xb7\x2b\xdd\x19\x5c\xff\xc5\x4d\x12\x59\x72\x8f\x76\xe7\x78\x47\xb2\x45\x7f\x20\xa6\x98\x6b\x5a\x3e\xac\x9f\xbb\xbf\xa5\x36\xaa\xb1\x04\xbb\xcb\x4b\x75\x4d\x29\x32\x6e\x48\x18\xbf\x64\x4a\x14\x26\xc8\xb0\x2a\x34\x13\x6e\x1b\x2a\x82\x38\x75\xe2\xef\x5f\xaa\xec\xb4\x05\xd1\x6e\xe0\x8b\x17\x91\x15\x75\x73\xad\xf2\x92\x18\xaa\x42\xc4\xf8\x94\x98\xfa\xdf\x98\xf9\x59\x6f\xa8\xa6\xb8\x77\xde\x6d\xbe\x3e\xdd\xae\xb6\x3b\x47\x49\xea\x9f\x8b\x31\xe5\x29\xcc\xec\x44\xf1\x33\xea\x76\x16\x5d\x6d\x98\x10\xb8\xd2\xa1\xd0\x58\xd5\xeb\x9a\xee\xdd\x71\x1e\x2b\xec\x4e\x73\x69\x7f\x2b\x4f\x08\xba\xc7\x0a\x3d\x94\xff\x50\xae\x36\x9c\xab\x40\x77\xcd\xff\x58\xb4\xf6\x67\x4f\x23\xea\xc9\xb5\xd7\x1a\x15\x12\xd7\x0d\x9c\xea\xe5\x10\x94\xfd\xaf\x39\x70\xa0\x49\x09\xb3\xe8\xa1\xcb\x69\x63\xba\xc6\xb0\xb5\x42\x4d\xa5\xfe\xfc\x2c\xb0\x3d\xea\x4e\xe5\x23\xfa\xff\x97\x65\xc7\x88\x48\xa6\x23\x2a\xe5\xc3\x5b\xd6\x1c\x0f\x06\xa6\x39\x23\x23\x22\xe3\xf1\x42\xd8\xf0\x7f\x5d\x9e\x34\x42\x19\x4c\xae\x1d\xb2\xda\xb9\xb7\xfe\x00\x50\x24\xed\x7e\x7c\x57\x47\xd1\xf4\xaa\x9e\x89\x91\x69\x6a\x3b\x43\xb2\x42\x7f\x2d\x96\x65\xe1\x49\xa7\x47\xef\x4e\x0a\x8a\x1f\xa4\xe7\x05\xef\xd0\xb9\x7e\x84\x4a\xd3\xb1\x00\x9f\x76\x0c\xa1\xaf\xdd\x06\x64\x54\x42\x10\x5c\xed\x93\xd7\x37\xc8\xee\xf9\x41\x51\xd6\x28\xc6\x89\xea\x66\xc1\xc6\xd8\x74\x78\x77\x2e\x69\x95\x12\x4e\xe2\xa7\xdf\x7c\xc7\x6e\x83\x51\xc6\xc1\x5d\x2c\xc2\x1e\x8b\xfb\xa3\xee\x06\xa3\xb5\xe2\xb6\x02\xdd\xc6\x1d\xdd\xdb\x32\x81\xc1\x80\x08\x91\xe4\x0f\xd9\x98\x7f\xfa\x9f\xb2\xfb\x63\x13\xd0\xe5\x6f\x8c\xe1\x91\xa5\xe3\x13\xa7\xf3\x00\x47\xe3\x8f\x42\x8c\x70\xbe\x5c\xd4\xd8\xec\x6f\xff\x4e\x83\x80\x58\x04\xac\x44\xb5\xbc\x09\x1c\x63\xa6\x74\x41\x83\x20\x01\xcb\x13\xa6\x42\xbb\x91\xc4\xcf\xfe\x32\x34\x08\xb8\x45\xfe\x59\xc5\x71\xd1\x46\xa9\x79\x97\xcf\xa3\x41\xa0\x23\xd7\xcc\x81\x6f\xcc\x51\x66\x55\x75\x63\x05\xf0\xfd\xb0\x90\xc4\x49\xbf\x71\xef\x33\x27\x47\x5d\x0e\xe5\x48\xba\xa1\x56\x20\x62\x24\x3d\xf0\x61\x0b\xcd\x3f\x54\x4c\xfc\x39\x95\x66\x2e\x6c\xf0\x8e\xeb\x2d\x34\xed\x7e\xe3\x6f\x30\x4a\x02\x84\x13\x66\xf5\x52\x34\xf0\x52\x0e\xca\xf0\xbd\x67\x47\x03\x92\x30\xd3\xcb\x74\x76\x80\x3e\xd0\xfe\xeb\xd4\x93\xa7\x21\x8e\x96\x5b\x68\x5c\x7d\xf7\x22\x37\xb7\x1e\x00\x40\x83\x38\x88\xad\x8c\xb6\xed\x2c\xb0\x30\xc0\x45\xa1\x47\xcc\xf0\xd3\x47\xfc\xa8\x39\x7c\xae\x70\x48\x03\xbf\xcd\x81\xd5\x9c\x68\xa3\xa6\xe1\x6c\x89\x95\x4d\x94\xee\xf6\x9b\xc3\xef\xab\x3f\xfd\x9f\x13\x6a\x35\x33\x91\x43\xe3\xa2\x9a\x1e\xe9\x4b\x83\x44\x1a\xed\x98\xa4\xf6\x8e\x44\x68\xce\xbb\xa7\x41\x62\x0c\xce\x44\x8c\x2f\xdb\x33\x74\x6f\x9b\x72\x8a\x33\x4e\x5d\x9a\x9b\xc5\xd7\xc8\x25\xf4\x3f\x53\xfb\x6b\x7f\x63\x79\xdb\x51\xd1\x74\x9c\xde\xa7\x01\x95\x0c\x59\x7d\x35\x9c\x4a\xd5\x81\x7a\x69\x40\x8d\x6d\xa7\x58\x2e\x6e\x7a\xa2\x03\x77\x8c\x87\x80\xa5\xa5\xff\x5a\x2c\x7f\x7f\xde\xec\x47\xfd\x73\x34\x48\x23\x40\xb7\x36\x7b\x29\xb2\xc1\x44\x4e\xb9\x8e\x51\x14\x29\xbf\xcc\xc3\xd5\x68\x90\xa6\x2c\xf0\x60\xd2\xa3\x28\x0a\xc8\x97\xd5\x07\xb8\x41\x1a\x08\x42\xd0\x6d\x10\x75\x0d\x56\x35\xc2\x2a\x69\x7e\x46\x47\x43\x03\x21\x24\x77\x0a\x00\x26\xcb\x61\xd0\xe3\x32\xdc\x78\x69\x20\xa3\x18\x81\x1b\x70\x82\xea\xa5\x03\xb6\xdf\x56\x83\x2a\xab\x1f\xc9\x84\xb6\x96\xaf\x68\x6e\x2f\x30\x47\xe6\x47\x03\x29\x18\x46\x03\x87\x8e\xe3\xe4\xc6\x12\xa1\x8c\xd7\xca\xe4\x11\x15\x89\xd0\xe7\x80\x1f\xcf\xe2\x7d\x73\xf9\x50\x75\x7e\xfa\x33\xca\x6d\xdf\x8c\xff\x6e\xbb\xa6\x3c\xf7\x02\xe7\x34\xd0\x81\xc6\xce\x5d\x2d\x1a\x31\xa0\x83\xa3\x81\x4e\xb8\xab\x6b\xdb\x66\x0e\xd0\x03\x7f\x80\x06\x1a\x80\x3b\xac\xf9\x5e\xd4\xaf\x57\x2d\xe4\xff\x1f\xff\x75\x57\x01\xc3\x91\xd5\x51\xe8\x1f\x59\x7b\xf5\x3e\x7a\xf0\xf7\x61\x18\x43\x9c\xda\xf2\xdb\xed\x20\xa8\xa5\x61\x20\x08\x36\x5f\x23\x74\x63\x99\x35\x42\xc3\x7c\x8f\x29\x0d\x03\xc3\x70\x92\x9e\x5d\x8f\xe9\xcd\xa5\x2a\x06\xec\x30\x6e\x54\x48\xad\x09\x7f\x5c\x3f\x1d\xd6\x4f\xdf\x56\xbb\xfd\xea\x71\xe5\x31\xe5\x34\x0c\x8d\xa5\x0f\xf9\xcf\x7e\x7b\x58\xed\xef\x0f\xf0\xb3\xa9\xc4\xe1\xdc\x67\xee\x69\x18\x45\x9c\x58\x47\x48\xea\xcc\xaa\xbb\x79\x76\x37\x3f\x22\xb1\x20\xf6\x76\xfb\xba\xbb\x14\xea\xb7\xf1\x66\x46\x43\x12\xa4\x42\xf5\x79\x72\x1f\xf0\x4d\xef\x95\x44\x11\xea\x0c\xc8\x4b\x55\x3c\x88\x09\x00\x8c\x86\x24\x66\x88\xda\x80\x9f\xe7\xbc\xac\x86\xc4\xab\x34\x24\x00\x98\x4c\x38\x64\xf5\x24\x09\xf9\x4b\xc9\x48\x77\x16\x64\x82\xf1\xb1\xbe\x2a\x4f\x59\xf1\x82\x11\xf8\xa2\xee\x52\xf1\x34\x4c\x78\x84\x48\x96\x87\xf2\xc5\x0a\x18\xac\x9a\xe3\x16\xfe\x9a\xdc\x6c\xa2\xb5\x47\x34\xed\x00\xf4\x0e\xf3\xc6\x37\x93\x07\x4e\xc0\x16\xef\x6b\x68\x9e\xcb\xaa\x31\x65\x9e\x5d\xb1\x1a\x5c\x41\x10\x69\x48\x43\xd0\xb1\x97\xae\x29\xcf\x9d\x73\x30\x78\xe3\x94\x59\xf2\x53\x09\xcd\xe1\x87\xa8\xda\xf9\xf1\x5b\x7f\xc8\xea\x7c\x5f\xa4\x2e\x11\x1a\x81\xc5\x86\x59\xe2\x78\xff\x13\x2e\x91\x8d\xc8\xa5\x9b\xe7\xfd\x0a\x3f\x56\x71\x6e\xb9\x61\x8a\x1d\x34\x37\xa2\xe8\xba\x4b\x68\xc8\x20\xc4\x70\xed\x29\x53\xf0\xe5\xf2\xbe\x17\x3f\xfd\x11\x1e\x58\xaa\x57\x24\xb5\xf2\xdd\xc1\x6f\xa5\xbd\xd2\xa2\xd0\x96\x81\xfd\xae\xd7\xe4\xa0\x21\xe7\xb6\xf0\xa9\x3f\xa0\xed\x9b\xdc\x17\xe7\x02\x49\xd1\x4d\x59\xbd\x89\x4a\x8b\x01\x4b\x87\x1f\x21\x6d\xf3\xaa\x6a\xbd\xc2\xbc\x03\x49\x4d\x46\xa5\xb1\x46\x6c\xac\x3a\x66\xb9\xfe\x58\xd4\x8d\x86\x69\x42\x8d\xec\x5f\xda\x40\x20\xd3\x0f\x48\x03\x04\x6b\x22\x7e\xd9\xe7\x96\x86\x6d\xde\x34\x14\x52\x78\xd6\xae\xc7\xa2\x39\x3f\x66\x2f\xd5\x30\xca\xff\xd7\xb4\xde\x4b\x43\xa1\xe3\xc8\x4d\xa9\x8d\x43\x16\x7e\xad\xf2\xdf\x46\x63\x24\xb5\x2d\x60\xd0\x1c\xa3\xbf\xb2\x4b\xdf\xdd\x4b\x43\x99\x06\x9e\x7d\x74\x0b\x39\x9a\xac\xef\x59\x73\x9c\xbc\x03\x09\x21\xce\x5b\x61\x13\x96\x07\x31\x2c\xc8\xd1\x50\x71\x4a\x07\x9a\x08\x4f\xf0\xe6\x88\xbf\x44\xde\x47\x89\xe3\x7f\x06\x53\x57\x93\x18\x51\x41\x0f\x5f\xff\xd8\xae\xbe\x3e\xfa\x93\x02\xb1\x1a\x6d\xcb\xb2\xb0\x6e\x49\x59\x75\x13\x7f\xfc\xe2\x21\x01\x4f\x28\x60\xf3\x90\xdf\x2c\x07\x2e\xae\xfc\xff\xf6\xed\x76\xdd\xbf\xfe\x57\xda\xb8\x5e\xe1\x76\x7a\x4c\x1b\xcd\x69\x14\x88\x94\x24\x0e\x59\xbc\x2f\x07\x69\x63\x1a\x05\x4a\x61\xe4\xf1\x45\x14\x4f\x77\xfb\xee\xaf\xc6\xe8\x9e\xaa\x79\x51\x64\x27\x91\xd7\x7f\x74\xe4\xe7\xce\xab\x8c\xc2\x20\x21\x8e\xe5\xcc\x69\xd7\x58\xad\x8b\x59\xb7\x2a\x0a\x25\x93\x56\x17\x4b\x58\xcd\xe3\x69\x4f\x0d\x8d\x48\x6c\x85\xf5\xb7\xd6\x2b\x77\x7c\x93\xbb\x49\x61\x81\x46\xc4\x28\x6c\xa4\xbc\x14\xb6\x28\x39\x7e\x8b\x51\x9c\x30\x94\xb1\x2b\xe0\x67\xf3\x8c\x29\x2e\xfc\x7a\xee\x68\x12\x46\xe8\x90\x2d\x37\xeb\xa7\x9b\xf5\x97\xc1\x9f\x11\xa3\x8b\xcb\xf8\x58\x95\x6f\xed\x5a\x36\x50\xfd\x07\xaa\x72\x98\xa3\xa4\x51\x22\x09\xa6\x2f\x9c\xf0\xc9\x61\xf1\xf0\xb0\xf9\xbe\x78\x5a\xae\xfc\x00\x2a\x6d\xc1\xb7\x34\xc6\xff\x89\x45\x84\x39\xbb\xe7\x53\x6a\x57\x7c\xa8\x38\x4a\x22\xa7\xe7\x25\x7f\xed\x52\x8b\x36\xdb\x3d\xc4\x20\x4f\xad\x6a\xc4\x88\x51\x93\xd8\x69\x58\x66\xa5\x11\x13\x0a\xdc\xda\xb8\x5d\x96\xa7\xd3\x4d\xbb\x9d\x35\xb5\xdf\x0c\x47\x5b\x49\x94\x26\x29\x52\x68\xd6\xe5\xa5\x39\x0a\xc7\xcf\xee\x8e\x09\x22\x79\xe8\x79\x2a\x2f\xb5\xcf\xca\xed\xdf\xca\x6e\x04\x0d\x89\x35\xb8\x58\x98\x39\x79\x42\xb0\x7a\x64\x1e\x22\xc1\xc2\xd4\x72\xae\xb6\x73\xf6\x5e\xe4\x3f\x5c\xf7\xc0\xb0\xe7\x8d\x46\x42\x27\x38\xec\x9c\xfd\x84\x2e\xea\x89\xa4\x12\x98\x4a\xd8\xb5\x9b\xdd\xcc\x7b\x54\x34\x42\x90\xcf\x43\xf9\xb2\x45\xfc\xf2\x53\x39\xdf\xbd\x3c\xa0\x5e\xa1\x91\x8e\x40\xf5\xb2\x1e\x53\xd3\x38\x5d\x75\x91\x4e\x04\xf6\x87\xad\xf4\xe5\x11\x9a\x2a\xf3\x1b\x42\xa4\x85\x55\x04\x40\xd1\x8f\xba\xb9\xce\x80\xd1\x48\x4b\x48\x69\xd7\x0f\x07\x0e\x8f\x3e\xba\x19\x20\x2c\x1d\x38\x83\x7e\x4d\xcd\x46\x4b\x11\x44\x96\xd9\x40\x95\x95\xfe\xcf\xe4\x5a\xe0\x8c\x12\xd6\x9e\x94\x55\x4c\xd5\xf0\xf3\xae\x2a\x4f\x5b\xf1\x36\x1f\x0c\x44\x10\x6b\xac\xd0\xa8\xc3\x19\x39\xb6\x11\x40\x3a\xaa\xe2\xb4\x63\x00\x49\x45\x6c\x60\x8a\x98\xde\xc9\x3a\x35\x01\xb3\xfb\x35\xb8\xee\x2d\xfb\xb5\xe7\x77\x9d\xc8\xa4\x96\x56\xdb\xb5\x95\xdd\xe4\x42\xbd\xe6\x18\xa5\xba\x87\xdf\x9d\x6d\xc7\xe0\xe4\x22\xc2\xb6\x30\x3d\x57\x65\x69\x36\x66\x2b\x2a\x78\x86\xb3\xdf\x16\x22\x23\x14\x76\xa6\x9e\xb2\x5e\xa9\x99\x46\x06\x1c\x18\x4d\xdb\x0c\xeb\x68\x97\x21\x01\x27\xc6\x11\x45\xc0\xfb\x20\x39\x4e\x49\x98\x44\xd8\xbd\x81\x58\x86\x4d\x01\xab\x2e\x24\x25\xa1\x31\xc8\xae\xf0\x52\x89\x62\x5e\x32\xf5\xd3\x04\x19\x25\x91\x48\x02\xef\x48\xec\xa0\xb9\x9c\x9f\x2b\xec\xfc\xce\x06\xde\x37\x21\x22\x42\x13\x71\x28\xe0\xed\xb9\x3d\x39\x54\x53\xa0\x10\x25\x71\xa8\x6c\xaa\x0d\xbf\x4c\x7e\x0e\xe3\xf1\x3b\x23\xb1\xb2\xb2\xc7\xa8\x51\x68\xab\xb3\x8b\xc2\x56\x5b\xae\x12\xec\x94\xc4\x3a\x45\x8f\x0c\x33\x85\xab\x76\xcb\xc7\xaa\x57\xe4\xef\x29\x61\x26\xb1\x4b\xbe\x56\x55\x86\x4d\xdb\x36\xa7\x3f\x7e\xab\x89\x16\xe8\x6b\x7f\x2b\x31\xf6\xea\xf7\x4d\x92\x80\x05\xad\x60\x73\x46\x2e\xa4\x6d\x77\x0a\xbb\xf3\x43\x82\x09\xf1\x2e\x7c\xbb\x2b\xab\x2b\x9f\x84\xd0\xc4\xe6\x33\x35\x88\x7c\x0b\x3f\xa0\x9a\x6c\xae\x84\x1a\x25\x2c\xf4\xa3\x11\xd9\x75\xbc\x41\x18\x89\x70\xf7\xb1\xc4\x28\xb3\x1f\x6f\x02\x27\xa4\x84\xc9\x9e\xe8\x53\x94\x93\x13\xf2\x34\x40\x86\xba\xbb\xac\x10\x79\xf6\x37\x76\x6a\xfb\xa8\x10\xf9\x5e\x3e\x9a\x17\xd3\xd3\x18\x8c\x2d\x70\xe3\x7e\xae\x4a\x65\x21\x06\xb7\x20\xae\x43\x85\xf1\xdd\x71\x15\x60\x44\xe9\x60\xe9\x79\x59\xc0\x3f\x42\xfa\x07\xfe\x0c\xe1\x9a\x23\x55\xa9\xb5\x88\xfb\x72\x7e\xe1\x92\x34\x08\xa9\xec\x93\x69\x5d\x17\x21\x25\x29\x0d\x10\x58\xf7\x04\x6f\xce\x00\x8f\x40\x7b\x7e\x94\x56\x98\x16\x00\xc7\xed\x6d\x2b\x94\xee\xa0\x08\x40\xf6\x62\x5a\xc3\xc6\x00\x4a\x04\x21\x58\x80\x5e\xd7\xbb\xd6\xe9\xc3\x9e\x2e\xbf\x55\x11\x19\x24\xd8\x14\xa0\xb3\xba\x7d\xf3\xcf\x96\xc7\xb5\x3b\x4a\x0c\x76\x6e\x4b\x87\x67\x5a\x9f\xac\x66\x3c\xed\x06\x70\x85\xa9\xd1\x76\xa1\xed\x2f\x05\x6c\xce\x1d\x2a\xa0\x17\xc5\xbc\x4a\x81\x5a\x88\x56\xc4\x87\x1d\x04\x94\x48\x95\x22\x82\xac\x5d\xd9\x87\x6e\x5a\xab\x20\x14\xa6\xab\xd1\xb9\x65\xb8\xee\xa2\x04\xa2\x22\xb0\x50\xd5\xf6\x7b\x23\x0c\xc8\x5a\x7f\x7f\x56\x95\x5a\xf0\x4e\x05\x1a\x25\x78\x06\xba\x3b\x94\x28\x90\x68\xe0\xbe\x41\x26\x5e\xfe\xcf\x64\x99\x9f\x32\x10\x51\xa2\x43\xe0\x71\x37\xaf\xbe\x95\x8d\x50\x43\x2e\xe2\x0f\xc3\x3f\xa2\xdb\x90\xdb\x4a\x98\x88\x4b\xee\x88\xfe\xcb\xaa\x6e\x9d\x1d\x75\x1c\x83\x5b\x29\x81\xc0\x70\x3e\x52\xad\x07\x3d\x42\x04\x52\x02\x69\xa0\x5d\xc3\xd9\xcd\xe5\xfd\xa9\x7c\xf3\x49\xec\x2b\xed\xec\x7e\x56\x9b\x88\xe2\x86\xe8\x30\x0b\x0f\x59\xf1\xfa\x41\x95\x9d\x12\xc3\x02\x35\x62\x41\xb9\x41\x17\x6b\x62\x59\x0c\x4f\x62\xb7\xc7\x34\x8e\x9b\xe0\x1a\xb3\x3c\xf9\x49\x6a\x0b\x3f\x79\xf9\x92\x15\x16\xe5\x31\xb9\xb2\x62\xd0\xde\xe5\x31\x7b\x39\x6e\xcb\x1e\x24\x4a\x89\x31\x89\x48\xaf\x69\x21\x47\x3f\x8f\x03\x25\xf0\x13\x2d\x5e\x2a\xc0\xf6\xcf\x67\x18\xb7\x47\xd1\x38\x0c\x19\xd6\x15\x44\xd5\x64\x75\x53\xcf\x32\x8e\xd3\x38\x64\x21\x76\x69\x9e\x3d\x69\x9b\xf9\xaf\xec\x4a\x1b\x9a\xc6\xa1\x52\x18\xbc\x41\x9e\x9d\xb2\x42\x54\xd3\x49\xd1\x0f\x43\xca\x96\xd7\x77\xe5\xd2\xc6\x7a\x7a\x3d\x10\x18\xca\x6e\x37\x5f\x9f\x6e\x0f\xb7\x5f\xad\x3a\xa5\x7b\xf6\x38\x52\x2e\xf0\xb4\x3c\x19\xab\x9f\xe7\xbc\xcc\xe6\x81\x97\x34\x26\x89\x90\xbe\xef\x7c\xe0\x61\x75\x37\x43\x94\x90\x16\x2b\x58\x40\x55\x5e\x6a\xaf\x07\xee\x2f\x96\x84\x14\x6b\xd5\x7f\x96\x97\xaa\x6b\x2c\xef\x0f\xa6\x88\xf1\x7b\x7b\x13\xa7\xf5\x72\xe3\x49\xf2\x46\x00\x4f\x1a\x27\x2a\xd0\xc3\xbe\xf3\x91\x8a\xeb\x78\x4a\xc4\x8c\x1a\xf4\xbb\x4d\x9e\x9d\x87\xde\x92\x3f\x9c\x2a\x7c\x31\x67\xf1\xee\xc3\xe3\xc9\x37\xe0\x4a\x26\x6e\x33\x7a\x76\x9c\xfb\x33\xcd\x09\x34\x4e\x63\x21\x51\xe6\xfb\x7e\xf1\xfd\xb0\xfc\x73\xf9\xb0\x3a\xdc\x61\xc1\xd4\x5f\x2a\xd5\x06\xb3\xaa\xe7\xaa\xdf\xb0\x36\xdd\x6b\x11\x0e\x86\x69\x2e\x85\x1e\x39\xf5\xb1\x90\x0a\xa1\x57\x67\x61\x3b\xab\x56\x05\x76\xd8\x4e\x2e\x2f\x09\xb1\xaa\xd2\x38\x7f\x3f\x84\x50\x0c\xbc\xe1\x58\x72\x2b\xef\xbd\xd0\xfa\xc9\xfa\x3d\x4d\x76\x0d\xbb\x99\xbc\x4f\xc5\xa4\x71\x00\x8e\xd5\xa5\xba\xab\x5c\x6b\x88\x3b\xaa\x39\x8d\x46\x24\x5c\x16\xf6\x75\xfb\x9a\x8f\x8a\x6b\x34\xd6\x4a\xa6\x5e\xf8\xea\x7e\x6f\xe9\xa7\x87\xc1\x55\xac\x75\x14\x0f\x80\x28\x03\x14\x25\x3a\x54\x30\x5d\x51\x90\x32\xd4\xb9\xde\x2e\xf6\x3e\x64\x8c\x41\x5a\x6d\x5c\x47\x68\x5f\x9e\xce\xa2\x78\x1f\x15\x3e\x27\x0f\x67\xe2\x34\xb0\x01\xa5\xc8\x9d\x96\xe8\x68\x72\x27\x41\xa2\xd1\x1d\x75\x3d\x0c\x59\x7d\x7b\x39\x49\x77\xb9\x24\xe2\x56\x94\x51\xe8\xff\xbd\xb8\x02\xeb\xa2\xd0\xe8\x60\x6c\x8c\xcd\x3c\xdc\x22\x9b\xc4\xb3\x25\xec\xf9\xb4\xf9\x94\x26\x84\x04\x48\x61\x5f\x5f\xce\xed\x2e\xea\xe8\x17\x7f\x9b\x0c\x92\x5d\x0f\xe2\x17\x71\x42\x9e\xd2\xa9\xa7\x99\x24\x41\x84\x40\x99\x0e\x64\x34\x72\xa3\x3f\xee\x28\x6d\x7f\x49\x11\x49\xbd\xc4\x36\x71\x03\x13\xd5\x25\x9a\x24\x11\xa0\x1d\x13\xda\x0b\xed\xde\x95\xd5\x4d\x27\xba\x98\xc1\xc7\x64\x7e\x34\x49\x34\xd3\x56\xb2\x46\x03\x9c\x66\x54\xfa\x69\x92\x18\x83\xb9\xe6\xef\x20\xeb\xac\x81\xfb\x12\xaf\x31\xba\x05\x4a\x53\x2c\xd6\x89\xba\x2e\x55\xe6\xc4\x84\xf7\x20\x4e\x93\x4f\x47\xa9\x40\xd3\x72\xba\xe4\x0e\x2e\xf8\xc9\xad\x31\x9a\xe0\xbb\x6f\xf7\x9e\xdb\xed\xae\x67\x9d\xa0\x09\xe3\x1c\x89\xf1\x4d\x56\xd5\x4d\x67\xc0\x06\xb5\x88\x84\xc9\x08\x43\xae\x0a\xf2\x52\x68\xcb\x69\xf5\x41\x7d\x28\xe1\x61\x8c\xe2\x44\x07\x47\xe2\xd4\x49\x8f\xd7\x8d\x38\x9d\xfd\x19\x79\x44\x10\x9b\xfa\x0c\xea\x92\x67\x97\x53\xf7\xf7\x24\x44\x37\xee\x4d\x14\x2f\x3f\xb3\xa3\x28\x67\xeb\xa3\x6e\x70\x1a\x24\xca\x76\x20\xda\x0e\x78\x94\x58\xff\xd2\xf5\x8b\xd2\x24\x25\x2e\x45\xd1\x86\x49\x4e\x39\xff\x3a\x0f\x90\xa4\xdc\x36\xaf\x59\xac\xf2\xa9\x9c\xd1\x8c\xa7\x49\x9a\x8a\x78\xd8\x11\xed\x84\x4c\x9e\x51\x33\x1d\x5a\xdf\x70\xc8\xf2\x85\xdd\xdc\xd8\xc4\x97\x67\x7f\x5d\x32\x9d\x35\xef\xa8\x8e\xe9\x0e\xca\x40\x63\xdd\xff\xd0\x88\xfa\xd5\x52\x8c\x0c\x63\xa0\x44\x86\x12\x5f\xf8\x01\xe5\xd0\x67\x67\xb2\x4c\x42\xe5\x74\xdb\x2f\x35\xe8\xc5\xf3\xba\x3b\xb9\x52\x98\x6f\x43\x46\x98\xda\xb1\x0b\xf4\xe9\x89\xde\xc5\x49\x24\x08\x6c\xd1\x5a\xe1\x36\x89\x15\x2f\x51\xc3\x30\xc1\x90\xa8\xc0\xd5\xe2\xdc\x4e\xe1\x44\xfd\xa6\xec\xae\x34\x51\x22\x46\x9e\xec\x6f\x5f\x47\x93\x59\x73\x91\x20\x5b\xe0\x62\xfd\x64\x65\x5f\x57\x4f\xb7\x28\x82\xd2\x8d\x00\x9b\xe2\x39\x5d\x9a\xac\x9d\xc6\xed\xd4\x6c\x67\xfc\x6d\x66\x10\x7a\xd1\xcc\x12\x5a\xcc\x4c\x71\x6d\x62\x94\x27\xae\xff\xaa\x9a\xdf\x46\xef\x0a\x02\x8a\xd5\x99\xcd\x62\xff\x49\x3e\x3b\x01\x29\xd0\xd6\x5b\x51\xb0\xbb\xb2\x52\x80\x0d\x98\xd3\x3a\x4d\x62\x82\xd4\x74\xd8\x66\x4f\x93\x33\x41\xa5\xfa\xa1\x49\x88\x3e\xdf\x7f\x6d\xfe\xe3\x1f\xd8\x48\xab\x3d\xf6\xe7\xcd\xaf\x51\xe0\x63\x51\x5a\x58\xe2\xec\x62\xa2\x32\xd6\x1e\x53\x68\x2d\xbe\xb4\xae\x6d\x96\xb7\x53\x1c\x81\x5b\xa3\x3b\xa6\x81\x8c\x90\xd7\xea\xf5\x11\xdd\xc8\x57\xbf\x44\x68\xa0\x05\x73\xad\x29\x9e\x41\x6f\x87\xc9\xe7\x2b\xd7\xd8\xbf\xee\xe8\x1f\x44\xf0\xfc\x89\x41\x60\x0a\x64\xbb\x78\xfa\xb2\x6a\xbf\xb9\xa7\xba\x6f\x7d\x7b\x5b\x39\x7f\x5c\xfc\x71\xb8\x5d\xac\x1f\xfe\x3c\x2c\x37\xbb\xf5\x97\xa7\xc3\xae\xd3\xc5\xa1\x34\x4c\x23\x24\x3f\x39\x1c\x0e\x17\xdb\xde\xbf\x2f\xa7\xd8\x81\xc1\x44\xa5\x51\x62\x9b\x29\x6c\x1b\xee\x18\x4e\x82\x59\x28\x69\x11\xb3\x4e\xb1\x71\x4a\x69\x44\x29\x89\x45\xe8\x92\x6d\x36\x95\x3d\x2c\xbf\x51\xc2\x12\x70\x8d\x41\x07\x2c\xf2\x1d\x86\xa0\xd1\x01\x85\x7b\x1b\xc7\x49\xdc\x9d\x10\x85\xf6\x28\x1a\x75\xbc\xf2\x40\xfe\x21\xac\x1a\x54\xf0\xdc\xff\x1d\xdd\x69\xcc\xb5\x76\x95\xb7\xd6\x9a\xad\x55\x39\x79\x94\x04\x02\x4f\x2a\xab\xc1\xf1\x81\x8f\x56\x6b\x1b\x63\x21\x71\xdf\x1f\xcf\x0b\x14\x3b\xbc\x22\x15\x98\x0f\xe9\x5a\xa7\x2f\x50\xc3\xca\xc3\xee\x2c\x14\xb4\xe6\xe0\x46\x34\x4d\x0e\x0f\x65\x5d\xc3\x35\xfa\xb2\xfd\x7f\x36\x0d\x6a\x8b\x0f\x03\x5b\x48\xa9\xb6\x5a\xe8\x4d\x76\x82\x1b\x68\xde\x00\x0a\x84\xd1\x79\xe7\x98\xb2\x50\x61\x80\x7b\x77\xf3\xe0\x5a\x35\x06\x10\x8f\xf6\x28\x4a\x19\xb5\x96\x6b\xe7\x5a\xb9\xab\xf9\x0d\x83\xb2\x44\x61\x06\xca\xba\x4f\x2e\x46\x9c\xec\xd0\x94\xa5\x42\xb1\x61\x4f\xee\x95\xeb\x39\x6b\x3d\x28\xd7\x16\x8e\x56\x5f\x24\x1a\x85\x0e\x10\xf6\x0f\x3f\x33\x36\x29\x9f\xd5\x8b\x8b\xce\x86\x9c\xf1\xe3\x7b\x4f\x23\x82\xc9\xaf\x5e\x32\xe4\x47\x98\xdc\x8b\xfa\x78\x70\xe7\xf3\x2f\x24\x65\x31\x02\xcf\xee\xc5\xe9\x6f\x31\xd8\xe7\xa9\x20\xb6\x70\x66\xd1\x3d\xf3\x2c\xdd\x94\x0a\x63\x89\x76\xcf\x15\x9c\x45\x05\xcf\xd5\x58\xd2\xef\x53\x5f\x9a\x4a\xa6\x71\xeb\x71\xc9\x94\x4e\xe3\x9d\x52\x99\x86\x76\x53\x6a\xc3\xc8\x76\x6d\xf5\xf7\x25\x81\x7a\x39\xf7\xb5\x2a\x87\x65\x89\xf1\xc9\x15\x03\xec\x7b\xf9\xbe\xfe\x8f\xdf\x3c\xa8\xd2\x31\xae\xfa\x36\xf0\x76\x73\x2e\x8c\xf8\x3f\xe5\x27\x46\x77\x4f\xe3\x91\x1d\x51\x5a\x88\xa0\x37\x03\x13\x5f\x81\x6a\x41\xd1\x8b\xb7\x62\xea\x47\xd1\xe1\x32\xa8\x06\xae\x47\x2a\xf6\x98\x0c\x77\x02\xc3\xe3\x93\x40\x28\x31\xd9\x3c\x93\x0c\xa7\x90\x70\x8c\x26\xdb\xb0\xa9\x7d\x7f\x97\x6b\x9c\x16\x05\x23\x30\xa5\xf3\xd6\x37\xae\xb8\x23\x26\x20\x89\x6b\xe6\x44\x76\xe4\x2d\xb4\x9b\x68\x3b\xc9\xc7\x57\x31\xb1\x12\xda\x83\x97\xbe\x43\xf6\x5d\xbc\x40\xd5\xe1\x1d\xa8\xa1\x3c\x26\xbd\x7c\xa8\x1e\x87\xab\xd4\xa8\x58\xc7\x5d\x33\x45\x81\xfe\x10\x5c\x4e\xfb\xd2\xa6\x5b\xdd\x30\x16\x48\x2b\x80\xfe\x02\xcd\xad\x2d\x27\x8e\x1c\x58\x46\x42\x40\xec\xf6\x43\xf9\xf2\x04\x6f\x1d\x7d\xd0\xb0\xc7\x6b\x7e\x9e\x31\x42\xac\x02\x66\x97\xea\x45\x90\x68\x79\x69\x0e\xb2\xe7\xff\xa2\x8c\xc4\x96\x28\xf2\x51\x64\xc5\x35\x22\x6f\xbc\xc0\x18\x49\x8c\x85\xff\x9c\x33\xf5\xea\xd2\x90\xfe\x50\x1a\x28\x5b\x48\x2a\xb4\x4d\xf6\x0f\xab\x6e\x83\xdb\x52\x10\xd9\x6a\x15\xb2\xe1\x1c\x4a\x83\x4d\x68\xed\x92\x3d\x54\x65\x6f\xb4\x18\xd1\xd6\x73\xb5\xd8\xb1\xd2\x95\xd9\x87\x1b\x0e\x8b\xa5\xed\x52\x57\x79\x59\xfb\xac\xa2\xf7\x7d\x06\xe4\xaa\xc4\xed\xb7\x8c\x72\x16\xea\xc1\x27\x3b\x98\x81\x0d\x65\x54\x08\x84\x3c\x3f\x9e\xf3\x4b\xdd\x05\xeb\x37\x1f\xbc\x0a\x16\xc5\x96\x92\xde\x32\x58\x6f\xa1\x3e\x97\x45\x3d\x12\x3e\xa7\x8c\x29\xcb\xb4\x34\xec\xd2\x70\xa5\x58\x7f\x55\x66\x40\x3a\x1f\xb5\xdd\x34\x0f\x42\x29\x38\xf7\x70\x33\xc6\xc3\x44\x78\xd1\x7f\x51\xec\x20\x9f\x04\xd5\x8c\x73\x4b\x09\x58\x01\x2a\xe8\xd6\x9b\x5c\x4f\x76\x76\x96\x46\x52\x84\xae\x78\x34\xf2\x8c\x98\x88\x0c\xc2\x0f\x9d\x52\x9f\xe3\xb5\x1d\xcd\x64\x26\x49\x8a\x5e\x46\xeb\x57\xcd\x35\x7d\x53\xa6\x24\x43\xa4\x53\x5d\xe6\x7a\xad\x41\x7c\x87\xec\x19\x7b\xae\xfc\x29\x74\x62\x35\x7e\xdf\x86\x4f\x0e\x2a\xa6\xca\xab\xba\x23\x99\xf3\x3e\x83\x6a\xd7\x88\xa6\xbb\xb4\x09\x69\x42\x7b\xdd\x91\x9b\xd2\xe7\x04\xbb\x01\x69\x12\x3a\x4b\x74\x83\xb1\xcb\x51\x74\x87\x14\xc5\xdb\x5e\xab\x63\xf6\x52\x0e\x1d\x6e\x1e\x84\x04\x33\x7a\x28\x37\x78\x88\xba\x3f\x47\x1c\xf3\xd4\x7d\xc3\x90\x6d\xfd\xdd\x97\xcf\x55\xf6\x43\x7c\xa0\xee\xd8\xfe\x4e\x20\x01\x26\xe6\xd5\xbf\x40\xe1\x24\x57\x07\x0d\x67\x94\x07\x84\x43\x97\x81\xee\xe9\xee\xfc\xd1\xc4\x4a\xd9\xe2\x44\x1e\x6c\xfc\xbc\x0d\xc5\xc1\x12\x95\x62\x30\xf5\x28\x7e\x66\xa7\x2e\x14\xe4\x21\x85\xc8\x6d\x0b\xb8\xb7\x37\x95\xc5\x51\x8e\xef\x2f\x94\xa9\xf1\xe6\xb2\xde\x8a\xac\x93\xc9\xa5\x3c\x4a\x65\x48\x7b\x54\xee\xd0\xf1\xf7\x23\x40\x18\xa7\xf3\x57\x83\xba\x54\x13\x63\xcf\x09\xe1\x61\xd7\xe2\x6e\x9d\xe3\x4f\x2b\x76\xfe\x67\x54\x20\x9b\x80\x13\x8d\x41\x80\xf5\x6c\x45\xf9\x9f\x60\x76\x9c\x00\x60\xf4\x80\xe7\x78\xce\x45\xd1\x25\xd1\x38\x31\xa9\xb0\x1e\xed\x0e\x9a\x26\x1f\x24\xb3\xdd\x80\xd8\x18\x2c\xaa\x48\x44\xcd\xed\xfa\x5f\x26\x89\x56\xaa\xf3\x03\xd6\x78\x3f\x03\x12\x33\x37\x8a\x82\xa5\xc1\xb3\x05\x15\x07\xb5\xd0\xa3\xc2\x0a\x67\xb1\x52\x08\x8b\x43\xd1\x8a\xc9\x1e\xc3\x59\x92\x24\xb1\xe3\x06\x73\x9a\x2c\x83\xcc\x28\x67\x89\xc0\x36\x45\xd7\x85\x71\xd8\x7f\xdf\x74\x87\x28\x93\x23\x51\x84\xaa\x3c\x0d\xbb\xf2\x3e\xda\xce\x87\xcb\x9f\x73\x20\x08\xa7\x59\xad\x9f\xa3\xe0\x9f\x83\x2c\x9e\xc6\xda\x69\x51\x5a\xfe\xf9\x63\x05\x70\x5f\x36\xf7\xe5\xa5\x9a\xe9\xc0\xa4\x3c\x85\x88\x8f\x88\xf5\xbc\x7b\xc4\xe7\x62\xd4\x69\x7c\xc4\x45\x60\xb9\x3e\x73\x81\x92\xff\x83\xdd\x81\x8b\x28\x08\x7a\xae\xe9\x8e\x81\x66\x42\xb2\xdf\x8e\x33\xd4\xf2\x6a\xf4\xbc\x06\xfe\x90\xe0\x98\xe7\x42\xee\x35\x18\xf0\x14\x50\x2e\xa4\xc1\x7c\x67\xbb\x2b\xe1\x65\x2d\x3e\xd9\x96\x62\x31\x5b\x33\xd0\x4e\xa2\x5c\xe8\x18\x25\x4f\x1e\xe7\x69\xa3\x47\xb5\xc1\xd1\xfb\x94\xa1\xc4\xbe\xdc\xc5\x66\x89\x7d\x03\xde\x36\x72\xa9\x6d\x9d\xf6\x26\x6b\x8e\x90\xe7\x63\xf3\xa5\x42\x11\xd3\x4e\x05\xf3\xe6\xe9\x66\x39\x10\xba\xf7\x63\x78\x82\x74\xfb\xb7\x8b\xfd\xfa\xe9\x4b\xf7\x57\xc5\xf4\x50\xdf\xb1\xfd\x61\xef\x8c\x70\x65\x52\x4c\xbc\x3d\x6c\x76\xab\xed\xe1\x61\xb3\xfc\x7d\x98\x85\xe0\x3a\x31\xc8\xa7\x60\x5b\xe7\x06\x0b\xf6\x3a\x9b\xd8\xe1\x86\xaf\x2b\x58\xee\x64\x10\x18\x2a\x06\x7a\x2d\xf3\x88\xb0\x19\x9e\x1e\xca\x21\x4c\x70\xc7\xf3\xfc\xcc\xff\xbe\x64\xea\x75\x59\x16\x3f\xa0\x6a\xfa\x57\x08\x60\x12\xcf\x18\x72\x88\x0e\x27\x68\x8e\x1d\x18\x86\x1b\x21\x90\x9b\xd3\xb1\x93\x64\xd2\x51\xf6\x93\x6e\x80\xb6\x64\x4e\x42\xff\xd8\x0d\x74\xed\xe6\x52\xea\x69\x10\x2a\xbc\x92\xca\x41\xa0\xea\xd1\xa3\xe7\x40\x6a\x8f\x81\x71\xfd\x9c\xe8\xde\xad\x0b\x53\xde\xbc\x8f\x9a\x31\xfd\xc8\x44\xa2\x53\x5d\xfe\x80\xea\xad\xca\xba\x92\xff\x68\xc6\xa4\x01\xd3\xa1\x8b\x6b\x9f\xe0\x67\x83\xd8\x44\xe7\xd4\xf3\xc0\x8f\xe1\x34\x76\xbc\x02\x7b\x10\xa7\x59\x0c\x59\x1a\x18\x12\x38\xbb\x7d\x98\xea\xb2\xd3\x34\x8c\xa9\x57\x52\x75\x9c\x4d\x98\xad\x1f\xd6\x45\x71\xcc\x80\xf1\xa0\x9d\xa1\xf3\x97\x22\x92\x22\x64\xd7\x63\xcc\x46\x39\xff\x34\x4e\x52\xc1\x06\x8a\x67\xed\xcc\xac\xde\x5b\x73\xe6\x5e\x58\xfb\xaa\xc6\x27\x8c\x53\x89\x6e\x01\x14\x7a\x9c\x3b\x18\xfd\xe3\x07\x03\xc7\x2f\x59\x5c\x4e\xb6\x0a\x04\x7a\xf1\x33\x1b\x6a\x6c\x75\x69\x89\x34\x89\x52\x6d\xba\x7b\x69\xef\xa1\xf3\xb8\x3f\x20\x6e\xa5\x69\x12\x87\xda\x31\xb2\x7c\x11\xf5\xb2\xac\x1b\x1f\x62\xf9\x01\x8c\x60\xfa\x48\x8a\xe6\x24\xfc\x22\x4e\x13\x9e\x60\xbe\xea\x60\xb2\x97\xe6\x68\xb3\x8b\x53\xb8\x61\x9a\xc8\x24\xb5\x8d\x65\x70\x72\xc9\xd4\xef\x90\x75\xa7\x30\xa9\xad\x6a\xfb\x8a\x2a\x0a\x12\x34\xd7\xd9\xdb\x94\x2a\x81\x54\x18\xa6\xac\x14\xdc\x5c\xaa\x62\x44\xf3\x32\x1e\xcb\x42\xe5\x43\x4d\xe7\x96\xf9\xac\xf0\x15\x1d\x27\x4d\x19\x09\x31\x1d\xf8\x7c\xbf\x7a\x1e\xda\xa8\x94\x09\x5b\x34\x45\x08\xe9\x5f\x97\xac\x02\xfd\x98\x15\x9d\x7d\x4a\xb9\xb4\x14\xad\xd6\x05\xdb\x7f\xdf\x4c\x44\x9f\x69\xca\x4d\x18\x87\x83\xbd\x06\x84\xab\x16\x2c\x4c\x03\xd5\x58\xd9\x86\xa6\xa9\x4e\x71\x27\xdf\xb5\x3e\x4a\xd6\x64\x50\x77\x7e\x5d\x9a\x42\x6c\xb3\x15\x35\xaa\x2d\xdf\x95\xd5\xb2\xf5\xb3\x26\x8f\x22\x92\x04\x53\x52\x59\x91\xb5\xd1\x37\xa2\x04\x6e\xca\x1f\xfe\x24\x82\xdb\xad\x0c\x85\x0b\xca\x97\x4a\x9c\xea\xd1\x6a\x90\x0c\x3a\x85\xd1\x76\x6f\x70\x4b\xe1\x9a\x91\x9b\xa6\x4a\xd8\xd0\xd6\x42\x8c\x6f\xa0\xb9\x79\x1f\x09\x43\xb8\x61\x9a\x6b\xec\x5a\x5c\x68\x5d\x56\x8f\xa5\xce\xcc\xfb\x36\x7b\xf9\x25\x32\x05\x9a\x6a\x61\xac\xf8\x58\xd9\x4e\x98\xf1\x31\x88\xb9\x70\xe5\xa3\xf9\x02\x45\x0a\xad\x6f\x64\xa9\xc3\x1c\xaa\x63\x5f\xc1\x04\x53\x90\x82\x64\x74\xb8\x99\x74\x35\xdf\x61\x72\x37\x05\xe0\x98\x51\xf1\xba\x1a\xb7\xf0\xa3\xdf\x68\x53\x30\x9c\xea\x81\x1c\xc4\xcd\xfb\xad\x98\xb5\x8e\x86\x6a\x54\x7c\xb5\xb8\x4c\xbb\x90\xc7\x20\x3a\x11\x90\x20\x1d\xf0\xd1\xe8\xe1\x1c\xf7\x43\x24\xb7\xb4\x4f\xc2\x00\x12\xdf\x5b\x14\x88\xb5\xe6\xe1\x78\x9b\x11\x61\x48\xc3\xa4\xcb\x96\x3e\x66\x85\x85\xe5\xda\xe8\x6d\x32\x34\x8d\x30\x56\x75\x0b\x66\x80\xa5\x6e\xfd\x14\xac\x8c\xdb\xbe\x1b\x38\x95\x9f\x7a\x07\xbf\x04\x1a\x11\x11\x51\xe8\xfc\xac\xb0\x29\x37\xea\x2e\x45\xe3\xb0\x9f\x57\x1f\x36\xd9\xfc\x43\xf3\xcd\xe8\xdf\x0f\x7a\x24\x04\x49\x6d\xe1\xf9\x6e\xb1\x7e\x38\xdc\x3d\x2c\xbc\x87\x21\x88\xb6\x11\xc9\xa1\x7d\xc5\xbf\x42\x2a\x35\xdc\x49\x45\x2c\x29\xd6\x74\x2e\xb5\xee\x32\x8f\xee\x50\x12\xda\x22\xec\x57\xb5\x2c\xb3\xe2\xd1\x52\x54\x38\xf1\x62\x4b\xb6\x34\x4f\xde\x45\x05\x4d\x52\x47\xe3\x22\xb4\x2a\xf3\xb2\xfa\xa3\x01\xe1\x43\x28\x41\x13\xe5\x69\xe3\x2c\x01\xd0\x30\xc3\x20\xa8\x32\xb8\xc7\x9d\x5c\x89\x71\x71\x99\xd1\x6a\x1d\xbc\x28\xf7\x33\xc6\x25\x16\xc2\xbc\x50\xcc\xcb\x0c\x07\xcc\x67\x35\x58\xc1\x38\x60\x6c\x7c\x12\x3f\x47\xd0\x05\xc1\x13\x86\x8c\x9c\xcb\x3e\x60\xdb\xbd\x9f\x64\x99\x4f\x66\x24\x57\x31\xfa\x24\xad\xb3\x7a\xca\x34\x36\xe4\xb8\x43\x69\xc0\xc5\x90\x51\xc4\x5a\x55\xdb\xe4\xda\xf3\x27\x51\x91\x46\x24\x76\xc0\x4e\xab\x7c\xf6\xa9\xc5\x11\x69\xa4\xb4\xe8\xed\xf5\xa6\x4f\x51\x88\x54\x5a\x84\x4e\xe3\x6d\xb8\x2b\x1b\xfb\xe3\x22\xb0\x75\xc0\x33\x54\xa7\xac\x69\x86\x0a\x4b\xe3\xa7\x12\x09\xc5\x60\xca\xda\xe8\x7e\x91\x09\x6a\xb0\xad\xe3\x2c\xde\xef\x60\x54\x9c\x13\x22\xb5\x9d\xe7\xc8\xc2\x32\x12\xd8\xa3\x42\xc6\x80\x7e\xfb\x97\x2a\xbb\x9a\x3c\x93\xa7\x93\x49\x94\x0e\x79\x56\x76\x2f\x62\x5f\xee\x5e\x8a\x7b\x54\xe3\x9e\xdf\x4a\x85\x62\x4e\xae\xab\x6c\x44\x03\x87\x0a\x81\x33\x97\x2b\xe6\x15\x2a\x14\x0f\xb0\x30\x68\x79\x20\x71\xeb\xa9\xa7\x8e\x86\xd0\xc4\x02\x6d\xa5\x2b\x61\x8d\x2d\xa4\xd0\x31\xc7\xcf\x55\xc0\x1b\x56\xa9\x0f\xe7\x6b\xe9\x69\x2a\x34\x48\xa4\x1c\xda\x9d\x44\x35\x14\x06\xc7\x23\x7c\x88\xaf\x19\xa7\x99\x84\x36\x9c\x78\xc5\xc0\x81\xe4\xe5\xd5\x6a\xee\x9c\x29\xa1\x8d\xad\x36\xd5\x2f\x6a\x72\xab\x90\x46\xb1\x05\x22\x7e\xc5\x6c\x19\x36\x09\xfc\xd6\x1d\x24\xf8\x51\xdc\xc6\xb3\xfa\xeb\x72\xdd\xcd\x33\xf2\x89\x05\x28\x23\xac\x83\x55\xbc\xee\xcb\xe5\x51\x54\xa7\xd9\x7a\xb0\x00\xb0\xda\xe7\x9d\x86\x3f\xd2\x6e\x75\xd3\x01\x4c\x9a\xc8\x01\x2f\x7a\xbb\x18\xd6\xe6\x26\xd3\x56\xa5\xac\x07\x28\x0b\x43\x52\xef\x1e\x63\xdc\xb6\xae\x37\xe7\xfe\x4d\x1a\x66\xb9\x69\x31\x73\xf9\x28\xaa\x57\x6f\xc4\x64\x10\x24\xd8\x5e\xf2\xef\x0b\x54\xef\x83\x15\x37\xfa\x46\x32\x10\x16\x82\xfe\x58\x9e\x86\xc5\x09\x19\x06\x06\xd1\x76\x6d\x98\x51\x3c\x96\xd7\x54\x12\x6e\x1c\x81\x18\x33\x5f\x28\xe6\x65\xe9\xa4\xfa\xc5\x26\x89\xa1\xd2\x0c\x88\x91\x27\x17\x27\x06\xe8\x40\x59\x6b\xa7\xc4\x14\xa0\x26\xe3\x48\x2b\x39\x14\xd4\x9b\xa0\x4a\xe6\x3e\x92\x8c\x89\x46\xab\xe3\xf2\xa5\xbb\xa3\x20\x5d\xc1\x9d\xff\x8f\x1f\x44\x6d\x25\xd8\xd8\x9f\xfe\x36\x3e\x03\x8d\xb1\x65\xf8\x05\xf5\xa0\x7e\x0e\x03\x76\x19\x0b\x8d\x99\x98\xdf\x2f\x5a\x14\x59\x3e\x9c\xd8\x32\x89\x2c\xea\x48\x68\xfd\x08\x37\xef\xdb\x65\x77\x80\x32\x2d\xba\xde\x9c\xc7\xf7\xfb\x36\x96\xc8\x8a\x97\xaf\x45\xd6\xa5\x20\x65\x02\x91\x4f\xd0\xe3\xce\xe0\x8a\xfb\xfe\x30\x8d\x12\x4c\xf3\xa3\x5f\x92\x81\x6d\xf2\x1c\x27\x50\x25\x8d\xa4\xee\xd2\x50\xad\x1f\x3b\x82\x7a\xc9\x36\xb2\x6e\x0f\x6f\xef\xbe\x8e\xda\x40\x25\xe5\x09\x26\xe7\x1c\xe8\xf9\xa3\x0e\x62\xc9\x22\x5b\x55\x71\xec\xbf\x36\x11\xde\x57\x17\xc7\xdf\x81\x09\x23\x3d\xe7\xce\x21\xef\xc5\xaa\xa8\x64\x2e\xe1\xee\xfd\xa7\xef\x22\xeb\x1e\x81\xc7\x56\x2a\x4f\xd4\x35\x54\x8d\x17\x91\x98\xcc\x0b\xe1\xd0\xa0\xd8\x75\x96\xbd\xb4\x77\x8d\x1f\xe9\x0b\x14\x81\x3f\x91\x60\x01\xc6\xee\xcb\xb2\xa8\x2f\x79\x23\x5c\xbc\x57\x8e\x3f\xb5\x90\x81\xdf\x94\x9d\x4b\x65\x63\x46\x24\x9b\xf4\x63\xb4\x41\x23\x72\xb3\xde\x2f\x37\xeb\xa7\x2f\x0b\xdf\x24\x26\x65\x64\xa5\xae\x0f\xde\x94\x4d\x63\xb7\x8f\x01\x12\x52\x72\x82\x80\x3e\xd9\xce\x05\x14\xab\xed\xde\x81\x0a\x34\x1d\xd2\x12\x60\x1f\xe2\xa2\x70\xdc\xbb\xc3\x0f\xa7\x14\x47\x94\x85\xf7\x7f\x76\x59\xd3\x06\xb6\x1f\x7c\x3e\x4d\x0d\xb6\x48\xdc\x42\xeb\xcd\x56\xf6\x53\xfb\x3c\xde\x7d\xd9\x3c\xb7\xbb\x87\x4f\xa5\x4b\xcd\xb8\x71\x1e\xb3\xb3\xd0\x93\x6c\xbf\x84\x28\x46\x8f\x13\x95\xa1\xbe\x16\x4d\xd6\x7d\x61\x10\x3c\xf2\x75\x00\xfb\x42\x3f\x6b\xe2\x54\x41\xc4\x50\x37\x64\x59\xbd\x9f\x9b\xb2\x80\xb7\x7a\x5d\xe8\xb2\x80\x3a\x13\xf3\x96\x47\x05\x90\x40\xd0\xd1\xdd\xa0\xd7\xf0\x98\x79\x21\xde\xef\x22\x6b\xee\xca\x6a\x8b\xc7\xfc\x5b\x55\x61\x0c\x58\xa7\xd3\x55\x79\x1e\xba\x5e\x2a\x22\x49\x32\xec\x1f\x14\x27\x47\xaa\x39\x97\x17\x51\x91\x10\x01\x78\x8e\x23\xa1\x5e\x8f\xb8\x2f\x0f\x00\x84\xf6\xdc\x93\x9e\x64\x15\x09\xf0\x5c\xa6\xf7\x2f\xe8\xb7\x5f\x61\xb6\x7e\xad\xe5\x44\x45\x9a\x46\x41\xc7\xbb\xff\xdb\xd5\x41\xcc\xed\xb8\x66\xf9\xe1\x64\x51\x24\x24\xb8\xec\x50\x07\xff\xb0\xbf\xdf\xae\x76\xf7\x9b\x87\xdb\xfe\xb0\xb1\x62\x66\xa7\x0c\xab\x7e\x37\x59\x31\x50\x71\xf8\xd7\x75\x12\x43\x11\x46\x5d\xb5\xa7\xb1\x45\x36\xef\x72\xa0\x9b\xda\x97\x48\x55\x1c\x25\x21\xeb\xf2\x88\x03\xf9\xe8\x79\x46\x54\xaa\x12\x15\xe3\x63\xf8\x44\xce\x22\xf7\x53\x4b\x25\x4a\x1b\x3e\x48\x06\x35\x22\x9f\xbc\x03\x1a\x72\xdb\xaf\x2c\x4e\x3d\x6d\xc6\x7c\x71\x4d\x51\x62\xb1\xc9\xc7\xb2\x28\x2f\x55\x97\x83\xe9\x77\x60\xc5\xc2\xd4\x03\x74\x7d\xd9\xe1\x33\xae\x45\xaa\x18\xb5\xa9\x94\x43\x25\x8c\xc9\xe1\xb6\x53\x33\xa6\x8a\xe9\x10\x49\x7e\xb6\xe5\xdf\x60\xab\xee\xb3\x2e\xba\x1f\x6d\xa4\x63\x12\xc1\x42\x0f\xdc\x02\xe8\x11\xe9\x91\x1b\xc7\x23\xed\x52\x8c\x5d\x72\xf6\x79\x4e\x41\x7d\x16\xf6\xe2\xcf\x91\x8a\xd0\x73\x8f\xd5\x35\x34\xab\xd3\x29\x6b\xa6\x89\x02\x95\x86\x01\xe2\xc7\x74\x79\x91\xf9\xc7\x50\x8c\x4f\x0b\x32\x2a\x4d\x43\xd2\xb1\x16\x4e\x2f\x20\x15\xd6\x3a\x91\x41\xc4\x5b\xa6\x87\xec\x15\x06\xde\x89\x4a\x35\xc5\x4e\x29\x87\x27\xff\x06\x95\xce\x46\xed\xe8\x4a\x44\x16\xb1\x87\xe6\x27\x7b\x29\x44\x3e\xce\x28\x28\x21\x43\x14\x8f\xca\xea\xdd\xb9\x2c\xea\x12\xb1\x17\x56\xb1\xec\xa3\xcd\x4f\x29\x1a\x50\xe7\x8a\x59\x85\x85\xcf\x1d\x79\xa5\x03\xd7\xf8\x3e\x28\xc9\x5a\xb9\xa4\xae\x2a\xa6\x20\x0c\x24\xd2\xb2\x5f\x64\x9e\xa9\xdf\xe1\xfd\x1b\x54\x99\x79\xff\x87\x33\x03\x91\x3a\xea\x10\x07\xce\x38\x4f\xc8\x7d\xa9\x82\x44\xe1\xc4\x3d\x65\xc5\x77\xc8\xf6\xa5\x87\x97\xfb\x6b\x9b\x20\xc1\xf4\x1b\x14\x7a\xad\xca\x9d\x70\x32\x38\x3e\xc8\xd7\x41\x40\x84\x35\x8b\x2a\x3b\x67\x7d\xfa\x43\x87\x01\xf5\x2d\x1e\x56\x2d\xd3\x62\x50\x87\x36\x55\x87\xa1\xc2\x70\x76\x39\x0b\xb1\xd7\x61\x64\x84\xee\x8c\xe8\x2b\xac\x0b\xa7\xdf\x33\xfe\x4e\x3a\xa4\x4a\x11\x4f\x3e\xd2\x9f\x5c\x09\xd4\x68\xb6\x26\xe0\xd9\x27\x42\x3f\x58\x47\x3a\x4a\x49\x64\x09\x5b\x4c\x55\x0e\xc3\x41\x1d\x69\x11\x46\xbd\x20\xc3\x07\x0c\x5d\x93\x02\xc3\x47\xe6\xf9\xbf\xff\x67\xf6\xea\x84\x47\x01\xf1\xb0\xd7\xf1\x27\xd2\x24\x0d\x48\xe2\x5d\xbe\x01\xae\x67\x36\x15\xa2\xe3\xc8\x92\x27\xce\x11\xa1\x74\x93\x43\xc7\xa9\x44\x5e\xc7\x81\x7d\x9c\x03\xf0\xe8\x24\xb5\xa2\x42\xab\x90\xfb\xd7\x91\x28\x8e\xe6\xa9\x28\x35\x1c\x72\x30\xcd\x01\x59\x07\xa6\x3f\x04\x89\x10\xd1\xf2\x0c\xc5\x7f\xca\x02\x76\xc7\xf2\x6c\xef\xd8\xdf\x28\x6b\x3d\x23\xa7\xdb\xb9\xda\xdf\x1f\xb6\x9b\xdf\xfd\x25\x98\x31\xe8\x82\xb6\x67\x8f\xe2\xc9\x99\xb9\x8a\xbd\x78\x07\xf4\x4b\x76\xfc\x3a\xb9\x0e\x6c\xc2\xc3\x57\xb6\xb7\x6d\xac\x5b\xdf\x65\x3f\x6d\xcd\xec\xf0\x39\xc2\x4b\x0b\xa5\x6c\x69\xc9\x34\x50\x21\x7b\x94\x5d\xf6\x38\xf7\xd1\xd1\xda\x7a\x89\xfc\xa2\x3c\x65\x85\xe8\x4b\x5d\x5a\x86\x21\x22\x74\xdb\xf7\xb3\xfa\x99\xd5\x4d\xfd\xc1\x97\x92\x91\xc0\x6e\xe2\x36\x04\x81\x26\x6b\x0d\xf2\xe2\xcf\xc9\xc3\xb6\x9e\x9b\x8b\x09\x6e\x2a\x80\x36\xce\xf6\x4d\xa1\x71\xf0\x2f\xfb\x8f\x1b\xaa\x89\x35\x67\x0d\x54\x78\x47\x63\xe6\x56\xaa\x21\x11\x16\x06\x65\x29\xed\xca\xea\x15\xec\x0e\xf0\x81\x8c\xe8\xf8\x46\x80\x1a\xac\x0f\x60\xd2\x5a\x1d\x41\x0f\x5b\xf9\x34\xf0\x18\x93\xd5\x1d\x29\xda\x00\xd2\xa3\x0d\x37\x40\xc7\x6a\xc7\xd7\xbd\x16\x10\x12\x8d\x51\x66\xdd\xae\xf4\xbb\xb2\xfa\x9e\x35\xc7\x87\x52\xbd\x7e\x16\xdc\xf7\xdb\x1b\x84\x71\x8c\x9a\x5a\x77\x97\xe6\x52\x41\xdd\xd3\xc3\x51\x08\x93\x14\x75\x3f\x2c\x7a\x42\x3f\xad\x1f\xef\x16\xf3\xd6\x1b\x42\x6a\xb3\x33\x27\x2d\x87\x4e\x11\x84\x42\x60\x00\x20\xea\x3a\x7b\x29\x96\x50\x35\x99\xc9\xd4\x10\x82\xf1\x49\xb9\xd0\x9f\x43\x81\x1c\x58\xb3\xac\x78\xf9\x22\xb2\xe9\xde\x06\x51\x20\x2d\x4b\x38\x6e\x06\x48\xd0\xd2\x45\x77\x10\x05\x80\x7b\x3d\x52\xe1\x3c\x5d\x4e\xb6\xc7\xae\x3b\x4a\x22\xac\x86\x2f\x6e\xbf\xad\x77\xab\xed\xee\xb0\xfb\xfa\xfc\xfc\xf0\x67\x77\x98\x5a\x3c\xed\x39\xea\x59\x16\xdd\x21\x12\x24\xe8\xc4\x67\xf5\x2a\xcf\x5e\xb2\x2b\x16\x12\x20\xb1\x76\xb1\x98\x0d\xb1\x5b\x3b\x58\x4c\x35\x2b\x28\x10\x15\xf9\x0a\x50\xfe\x90\xc9\x1d\x34\xd1\xf4\x4a\x4a\x52\xeb\x97\x59\xf9\xaf\xeb\xa4\x38\x10\x48\x6c\xf3\xf9\xb0\x53\x64\x4e\x86\x9f\x42\x1c\x2a\xe9\xfb\xaa\xfd\x8e\xd4\xfe\x51\x3b\x74\x75\xd7\xa2\xc4\xfd\x31\xc3\x15\xef\xf9\x07\x77\xe7\xac\xdd\x52\xce\x97\x49\x99\x1e\x12\x25\x31\x9f\x5c\x37\xe5\x79\x1e\x38\x06\x34\xb4\x58\x08\x4c\x90\x95\xff\x0b\xaa\x69\x5d\xe1\xa1\xc5\x9d\xf5\x25\x81\x26\x80\xad\xc3\xa8\xfb\x31\x91\x4a\x98\x5c\x41\x71\x84\x93\x39\x59\x95\x7a\xfa\xf4\x2c\x0c\x30\x9d\xb7\x5b\x2e\xb6\x8b\x9b\xd1\x7c\x65\x51\x64\xe5\x96\x6d\xf9\xe9\x7d\xd4\x1b\x3c\xb3\xde\xaf\x3c\xec\x0f\x8e\xce\x3f\x12\x8b\x24\x16\x70\x7c\x7c\xeb\x97\xee\xa7\x5d\xf2\xdd\xa4\x61\x20\x02\x9b\x01\x50\x9f\x29\xfe\x51\xe0\x31\x4d\x22\xaf\x0e\x35\xda\x09\xfd\x00\x11\x6b\x3f\x1d\xbe\x38\x30\x67\x77\x4c\x69\xa4\xb7\x10\x1d\x60\xed\x8a\xc7\xd6\x07\xdd\x90\x72\x45\xc2\xbe\xb9\xba\x35\x25\x1f\xd8\xc8\x4f\x60\x01\x90\xa6\x02\x31\x13\xf9\xcf\x63\x6b\x8d\x62\x7f\x27\xa9\x24\x84\x0e\x0a\xcc\xcd\xa5\x42\xb2\x8e\x19\xb4\x13\xc8\x98\x12\xd3\xe1\xa1\xb6\x65\x39\xe6\xc0\xf5\xa3\x92\x40\x76\x7c\x9f\x0f\x20\x34\x54\xb2\x14\x95\xdd\x92\x69\xfc\xaf\xd1\x3f\xfe\x37\x22\x44\x4e\x9d\xe7\x5c\x28\xb8\xb9\x7c\xa8\x02\x3e\xbf\x1d\x80\xa2\x16\x5e\x89\x82\x93\x05\xa0\xca\xf8\xc6\x74\x66\x61\x64\xf8\x94\xb2\x3a\x55\x95\x2d\xbc\x1e\x30\x8d\x01\xfa\x30\xc3\xd7\xdd\x0e\xb6\xf9\x20\xc4\x30\x1d\x30\xed\xf1\x51\x04\x71\x9d\x2e\x01\xa5\x3b\x12\x2a\xcb\x14\xf4\x03\x66\x31\x00\x00\xca\x12\xdc\x38\xe1\x39\xa8\xee\x2e\x79\x8e\xc2\x73\xa3\x71\x26\x10\x96\x2f\xc2\xf3\x5f\x5b\xdd\x2e\xf7\x29\x4d\x08\x16\x74\xf9\x82\xd2\x23\x59\xbb\x9b\xae\x74\xd6\x1c\x98\x1f\x10\x69\x9e\xa4\xbd\xe4\xc7\x56\x34\x13\xa1\x11\x6a\x08\x95\xd8\xcc\x7e\x93\x55\x3d\x52\x6e\x5a\x7f\x1b\x99\x59\x43\xb8\x6d\xde\xb7\xe8\xeb\xd9\x62\x88\x1f\x29\xac\xe4\x15\xa6\x7e\x9f\xab\xf6\x43\xf7\xdb\x89\x89\x21\xc4\x8f\xf8\xb8\xf8\xe3\xf0\x65\xbb\x78\xda\xaf\x56\x8e\x57\xd7\x32\xdf\x78\xd5\x5d\x6a\x92\x90\x1a\x18\xb0\x65\xa2\x3a\xdc\xa3\x98\x27\xf0\xa6\x26\x31\x04\xdf\xee\x43\xf9\x12\x1e\x4c\xa1\xa6\x64\x80\x9f\xd7\x9c\x7c\xf9\x73\x7c\x4e\xa6\x19\xee\x2d\x9d\x22\x67\x3e\x26\x7c\x33\x4c\xa7\x98\x3e\x15\x4a\x5d\x4e\x88\x3f\xd0\xf7\xe5\xa5\x7f\x5a\x4e\xc0\xeb\xfb\x6e\xad\x8c\xd4\xf8\x53\xf3\x58\x13\x97\x2e\x7c\x16\xd5\xb5\xac\xae\x1f\x26\x25\xe6\x94\x6e\x6d\x26\xfb\xff\x05\x1d\x88\xe1\xc0\x51\xfe\xe8\xf1\xe1\xdf\xdd\x1b\x4e\x23\x8e\x0d\x22\xd6\x21\x47\x94\xfa\xf6\x92\xc3\x97\xaa\xbc\x5c\x49\x1e\xfe\xc3\xe9\x53\x66\x71\xa3\x88\xf1\xde\x1d\x2f\xc6\x5c\xc3\x44\x8c\xb7\x4e\x35\x34\x9b\xb3\x53\x20\xfe\x22\xea\x6b\xb9\x2b\x6a\x52\x95\xa6\x0e\xbf\xe3\x54\x3b\x67\xd7\x94\x11\x91\x95\x99\x6c\x5c\xb3\xa1\x2b\x66\x8f\x4f\x26\xa8\x05\x20\x5d\x8a\x1f\x36\x88\x9d\xdd\x52\x8c\x24\x1c\x4d\xf0\xb7\xc5\xc3\xd7\xd5\xcd\x62\xe9\x43\x03\x23\x55\x88\x08\x45\x10\xd5\x80\x5f\xca\xa8\x40\xa3\xe9\xb7\xc1\xae\x85\x19\x21\xbd\x51\xf7\xf9\x15\x4d\x89\xc7\xd0\x2d\x8f\xa2\x7a\x99\x6c\xa7\x46\x99\x08\x79\xf6\x7a\xf6\x5f\xcc\xd3\x7e\xdc\xa0\x69\x34\x51\xda\x61\xae\x3b\xe2\x7d\x7f\x28\x49\x12\x9b\x57\x76\xcc\x17\x1f\x2d\x01\x3f\x5e\x24\x81\xec\x1b\x3d\x9c\x78\xe9\xc4\x93\xe8\x2e\x0c\x21\xc5\x37\x0d\xa7\xac\x41\xb5\xaf\x0f\x5c\x08\x03\x51\x82\x19\xb2\xb5\x2a\x57\x85\x1e\xf4\x87\x1a\xe0\x11\x4e\x92\x2f\xd5\xe5\xdc\xc0\xc0\x5d\x36\x86\x47\x58\xcd\xff\x02\xcd\xf2\x98\x9d\x9f\x2e\xa7\xd9\x36\x39\x63\x40\xa2\x6d\xf1\x89\xe1\x5c\x43\x35\x51\x96\xf1\x37\xc2\x82\x90\x30\xc4\x02\x00\xae\x59\x07\xec\xef\x93\x31\x2c\x08\xa9\x0a\x63\xaf\xdf\x69\xd3\xc0\xfb\x12\xcd\xd5\xe4\x4c\x51\x1c\x52\xa7\x04\x73\x5b\xaa\xa6\xac\x06\xe4\x25\x1f\xea\xd3\xf2\x5f\xf8\xbf\xe3\x22\x28\x0b\xa2\x44\x23\x24\xd8\x7b\x35\x8b\xfc\x2a\x59\xe6\x3e\x08\x0b\x48\x4a\x31\xe6\x5b\x8a\xfa\x38\x70\xc4\x58\x40\x54\x8c\x80\xa4\xd5\x7e\x69\x77\xfa\xd9\x0f\xc5\x82\x98\x58\xfc\x68\x56\x23\xf6\x75\x74\x8e\x98\x28\x01\x03\xe7\x7b\x63\x0c\xca\x52\x76\x00\x97\x8f\xac\xcf\x0c\xf5\x39\x0b\x68\x28\x92\xc4\x15\xbf\xd1\xcc\x8c\x60\x2b\x2c\xa0\x69\x12\x77\x1f\x02\xb3\x7c\xfb\x72\x4a\x51\xf5\xb1\xf9\xe6\x96\x2b\x65\xb8\xb2\xda\x53\xa6\x58\x38\xea\xfa\x97\xfc\x8e\xbe\x44\x64\x88\x37\xe1\x2c\x60\x84\x48\x97\xfe\xbe\xc9\x9a\xb7\xb2\xd2\x75\x27\x3c\x3b\x67\x73\x58\xc0\xe2\x18\x3f\x92\xd7\x67\x2d\x25\xdc\x55\x19\x14\x1f\xd6\xcf\xa7\x30\x13\x7f\x1e\x69\x31\x48\x37\xe0\x68\xea\x87\xc1\x29\x0b\x78\x60\x70\xd2\x75\x14\x72\xf5\x0e\x9a\x55\x81\xf8\xb5\x2d\x58\xfe\xd1\xfa\xa9\x6c\x06\x0c\x7c\x2c\xe0\xb1\x55\xc1\x39\x96\x97\x1a\x46\xe5\x6b\x16\xf0\x84\x7a\x1d\xf8\xc7\xf7\x2f\x50\xf8\x76\xa0\xf6\x88\x55\xdb\x92\xc5\xb2\x8d\x10\xba\x3f\x2b\xcb\x70\x2f\x41\x95\x27\xf8\xbd\x4b\x4f\xb1\x80\x9b\x14\x91\x28\x5b\x9f\xb9\xfb\x2c\xb1\xca\x82\xd6\xfd\x64\x1e\x00\xf4\x41\x48\xd0\x93\xde\x7c\x1c\x32\x44\x13\x9e\x70\x77\x7a\x11\x02\x75\x94\x09\x3e\x96\x9c\xe9\xb5\xed\x6f\x47\x42\x1c\xf7\x10\x8a\x7c\xf5\xfc\xc7\xf8\xcd\xab\x20\xd0\x81\xef\x8e\x72\x84\xf1\xe3\x09\xad\xc2\x24\x08\xd0\xd4\x66\xc5\xb2\xeb\x55\x60\x81\x22\x21\xc2\x4e\x5b\x6f\x65\x28\x40\xdf\x1e\x11\x2a\xf2\x61\xb4\x4d\x08\xa1\x5c\x7c\x56\x74\xdf\x47\x71\xee\x31\xab\x83\x04\xc4\xaf\xcd\x25\x25\x28\x92\x71\x3e\xed\xbf\x8d\xd6\xb1\x0e\x63\x74\xd3\x5f\xe1\x7d\x3a\x8d\xb5\xa0\x86\x0f\x60\xb9\xcf\x3e\x51\x3a\x1e\x06\x11\x60\xb5\xf2\x56\x34\x97\x13\xce\x9a\xac\x1e\x5d\x02\x68\xec\x15\x82\x47\xd2\xee\x08\xf8\x99\x7a\xf8\x83\xaf\x06\xa0\xb1\x46\x57\x37\xd5\xb2\x2c\x94\x98\x27\x5e\xfd\xc7\x24\x07\x0b\x4c\x2c\x75\xdc\xa3\x6e\x6e\xb3\x1f\x43\x86\x45\x16\x18\xce\xd0\xfa\x1c\x82\x9f\xff\xc9\x64\xd6\x8c\xee\xde\x40\x80\xd9\x97\x7d\x59\x36\xd5\xa4\xf9\x80\x85\x01\x70\x34\x91\x6e\xa9\x6f\x85\x94\xd9\xaf\x8b\xbb\x0d\x3f\x21\x77\x67\x8c\x20\xc0\x8c\xc8\xa4\x51\xe6\xd1\xef\x85\x2c\x24\x01\x70\xd5\xf1\xcc\x6c\xde\x26\xf0\x04\x16\x92\x88\x92\x91\xa8\xc0\xe8\x71\x43\x42\x63\x44\x1a\xb9\x4e\xa2\xaa\x81\xca\x37\xdb\xcc\xda\xb3\x90\x80\xcd\xa0\x64\xb5\x53\x91\x9c\xf5\x8f\x58\x18\x87\x34\x75\xcb\xc2\xb9\xc1\xf6\xc2\x6d\x08\x53\x9d\x06\x5c\x37\xed\x50\x86\xce\xb8\xb7\x90\x36\xab\xb2\xcc\x9a\xf7\x61\x98\xc6\xc2\x58\x19\x0c\xd3\xbe\x40\xf3\x70\x51\xaf\xef\x5f\xc4\x49\xe6\x6d\xb4\x30\x5a\xb0\x61\x12\xd9\xba\x59\x56\x2f\x45\xaf\xf9\xc5\x42\x2a\x68\xea\x2b\x60\xdf\xd6\xcf\x93\xe7\xe2\x31\x1f\x24\x1f\xaf\x52\x24\x33\x53\x29\x4c\x63\x89\xe0\x14\x27\x5d\x86\xf2\x6b\xfe\x62\x29\x8f\x90\x50\x6f\xb5\xd8\x62\x2b\xfa\xd3\x7e\xbb\xbe\xf9\xba\x5f\x6f\x9e\x26\xbc\x42\x2c\x94\x42\xa0\x8a\xd4\x0e\xce\xe7\x7f\x6c\x29\x61\xa1\xd4\x56\x85\x1b\xb7\xa0\x97\x6b\x81\x8a\x76\x84\xc2\x4f\xfe\x5c\x65\x27\x90\xa2\x78\x1d\x95\xe8\xc6\x8f\xad\x98\xc6\x74\x57\xbb\x6f\x04\x91\xbf\x25\x4d\x48\xe8\xa8\xa9\x5f\x11\x3d\x5c\x94\x65\xf1\x2d\xab\x27\x9e\x37\x0b\x35\xb5\xde\x43\x4f\x6c\x3f\x01\x50\xb1\x50\x0b\x85\xbd\xbf\x4b\x0f\xba\xde\xfd\x55\x5d\x9d\x06\x6c\x57\xcf\x29\x2b\x9a\x67\x24\x7d\xfc\x3f\x45\xfb\x2c\x84\x38\xc6\xbe\x9c\xac\xf6\xd8\x0f\xff\x28\xa0\x2c\xab\x6e\xfb\xd5\x91\xb7\x79\xd4\x34\x3a\x79\x1b\x46\x04\xd6\x1b\x2d\x3a\x36\xc1\xd1\x14\x8c\x02\x65\x73\x63\x35\x14\xfa\x59\xbc\xf7\x1c\x80\x2c\x0a\x41\x5a\xb1\x6b\x3b\x1b\xda\x4d\xf8\xf2\x72\x3c\x5f\xba\x01\x51\x60\x34\xf3\xc0\x3a\x9c\x2c\x6e\xe2\x5c\x23\xe5\xc7\x4f\x17\x45\xa1\x36\x76\xcd\x39\x21\xa9\xc5\xf8\x1d\x47\x24\x8a\xb1\xc6\xa5\x44\x7d\x74\xac\xa4\xfe\x48\x12\xf8\x9c\xee\x5d\x05\xb0\xfa\xd9\x40\x51\x4f\xb9\xb1\x58\x44\x54\xe4\x00\x87\x75\xb3\xaf\xb2\x6e\x1e\xfa\x56\x50\x16\x11\x10\xe8\xf9\x60\xc2\xc3\x26\xaa\x57\xfb\xfb\xa5\xa8\x34\xba\x60\x36\x89\x39\xdf\x9c\x34\xf8\xaf\x71\x9c\xc0\xa2\x98\xc4\x7c\xf0\xd2\x3e\x0c\x65\x58\x14\xa7\x51\x37\x45\x7e\x29\x7d\xd7\xbf\xbe\x84\x5a\x30\x81\x8b\x0d\x7b\x2a\x3e\x16\x25\x12\xb0\x17\x61\xb9\xbc\x3f\x6c\xbb\xce\x46\x16\x51\x2e\x65\xdf\xce\x36\x9b\x60\x65\x11\x8b\x52\xcc\xb9\x63\x8b\x62\xc7\x3c\xc8\x22\xc6\x6d\x79\x1c\x77\xef\xa1\x55\x88\x98\x52\x91\xbe\xd6\xc2\x98\x58\xda\xee\x99\x39\x15\xdc\xf9\x60\x5f\xca\x5c\x5b\xc5\x68\xec\xe8\x57\xd7\x7b\x6f\xc4\x9d\x14\xf0\x16\x44\xee\xdc\xe2\x7e\xeb\x8a\x84\x02\x9c\x43\xe7\xbe\xf3\x6b\x29\xce\xad\xd9\xef\x1e\x5a\x71\x8d\x30\x3c\xec\x20\xdf\x8b\x57\x04\x67\x3d\x95\x8d\xd3\x95\x1c\xd0\x88\xb3\x48\x41\x88\xa9\xce\xfb\x52\xe7\x37\xe5\xcf\xc9\x9b\xd1\x51\x8a\xb8\x99\xbf\x45\xfd\xb3\xfd\xff\x7f\x89\xbf\xfc\x0f\x21\xa0\xe8\x2e\x8d\xa5\xd5\xff\x04\x51\x75\x23\xa2\x00\x53\x39\xc2\xd2\xff\x83\xcd\x68\x79\x14\xc8\x64\x3f\x8a\x4c\x1c\x46\x6e\x7d\x23\x3b\xc2\x6d\x56\xcb\x4b\x55\x83\x5b\x9d\xdf\x8f\x50\x3c\x8b\x4b\x0d\x7a\x10\xcb\x45\x46\x69\xde\xef\x38\x43\xf1\xb3\x7e\x10\x09\x42\x8d\x35\xbe\xf5\xf7\xef\x2b\xd7\xd2\xc5\x48\x48\x6d\xf1\x52\x68\xfd\x4f\x9f\x8f\x10\xa6\x43\x4b\x29\x6d\xf9\x1d\xa7\x0e\x03\x89\xe3\x10\x05\xbd\x6d\x2b\x50\xde\x31\xa7\xfd\xaa\xf1\x9b\xdb\x95\x48\x1c\x73\x6d\x4b\x25\xb3\x2c\x77\x8c\xc4\x8c\xab\x21\x46\x62\xad\x07\x7d\x43\xa3\xef\x48\x12\x11\x2a\x35\x10\x4b\xb0\x8a\x83\xee\x20\x8b\x0d\xf1\xa2\x26\xc8\x85\x3f\x43\x71\xc4\x08\x4b\x6c\x57\xfd\x6e\x73\xb7\x3f\x2c\x17\xcf\x87\xd5\xd7\x6d\x77\x06\xc5\x99\x63\x5d\x5f\x34\x2e\xa5\x51\x0f\xb2\x14\x8c\xf0\x38\x42\xeb\x6d\xa3\xf2\xba\x97\x40\xf0\xc7\x99\xa6\x72\x18\xf6\x58\xcb\xd4\x1a\x88\xa7\xb2\x50\xb6\xbc\x99\x15\x2f\xf8\x3f\xba\x1f\xa5\x29\x06\x90\x3f\xca\x06\x6e\x26\x4f\xcc\x53\x8d\x10\x1f\xf4\xf1\xb3\xd6\x69\x99\x0f\x0b\x48\x2a\x0c\x2e\x96\x02\xda\x30\xd0\x47\x41\x24\x35\xc4\x0b\x5f\x7b\x56\xb7\x4b\x25\x86\x2c\x17\xdd\x40\x0b\x6b\x68\xef\x7c\xe3\xe1\xea\x8c\x88\x48\x84\x2e\x3a\x79\x2e\xcb\xbc\x7b\x50\x11\x27\x5e\x9d\xfb\xe9\x72\xb2\xf4\x2b\xf8\x36\x54\xa9\xaf\x5c\x20\x22\x12\xe7\x52\x88\x6b\x0c\xdf\x74\xf2\x5c\xe6\x88\x58\xff\x2f\xf9\x3c\x46\x04\x83\xa8\xc7\x32\x0d\x70\xa6\x8c\xc8\x84\x61\x22\x48\x43\xa7\xbd\xff\x5c\x95\xad\x83\x39\xf1\x13\x88\x0a\x20\xf1\x5d\x07\x8b\x3c\xbf\xab\xfe\x5e\x28\xe5\x4f\xa3\x74\xca\xc1\xa7\x89\x0f\x62\xd0\x30\xcc\x88\x36\x81\x65\xab\x2c\xab\x1a\x2c\x0b\xbc\x3f\x64\x08\x0f\x98\x53\x7b\x9b\x21\xbd\x60\xc4\x08\x8e\x10\x8c\x85\x33\x17\xd7\xcd\xfa\x2c\x0e\x03\x3b\x83\xb1\x1e\x76\x5b\x89\x97\xe9\xb7\x8c\xc3\x28\x88\x93\x1e\x81\x3d\xd0\x96\x19\x5c\x2b\x0e\x69\x84\x62\x1b\x6f\xa2\x5e\x79\x71\x19\x9b\x5f\xe8\x13\x0c\x71\x98\x26\xc4\xc1\xf2\x9e\x37\x9b\x87\x03\xe8\xac\x39\x84\x49\x7f\x98\xf9\x30\xec\xe6\xf2\xbe\xb5\x48\xbf\x01\x62\x85\xc5\x11\xb5\xb4\x4e\x4a\xe4\xf9\xcb\x6d\xaf\x13\xe6\x8f\xc7\xa1\xc1\x79\xf7\xb0\xd9\x3c\xae\x17\x61\xf7\x67\x10\x08\x24\xfe\x02\x8d\x95\xe7\x18\x76\x4a\xb8\x31\x09\x0b\x90\x94\xa0\x3a\x5d\xae\xf8\x83\xdd\x10\x1a\x28\xe4\x59\x76\x25\xfc\xec\x35\x7b\x16\x53\x00\xe2\x5c\x03\x47\xfb\x4b\x9d\x70\xdf\x15\xd8\x8c\xcb\x05\x61\x37\x28\xd1\xc2\x36\xb2\x96\x95\x78\x81\xd5\x4f\x94\xf9\xf2\xf7\xc7\x38\x09\xf4\xb0\xbd\xcf\x37\xd2\xdd\x65\xd8\xf5\xe2\xc2\xfc\xf1\x75\x99\x20\xd6\xa0\x2b\x55\x5d\x44\xee\x1a\x1e\xea\xee\x9c\x26\xc0\xd4\x72\xeb\x59\x6d\x2e\xcd\x9d\xc8\x73\x29\xd4\xeb\xb0\x65\x9d\xc5\x5c\x04\x8a\x0e\x35\xd0\x2c\xe7\x32\xae\xfe\xde\x17\x8b\xb9\x08\x51\xe5\xe8\x5c\xbe\x0d\xb0\x09\x2c\x4e\xe3\x08\x95\x80\xbf\x6d\x50\x79\xfc\x79\xbb\x7a\x5e\x6c\x57\xd8\xdf\xb7\x7b\x5e\x3c\x75\xc3\xc0\x42\x3e\x30\xef\xf5\x90\x29\x28\x6a\x78\xba\xdb\x8f\x3d\xb9\x58\x84\x09\x02\xbb\x1d\x53\xf3\x5a\x83\x98\x6c\x99\xb1\xa0\x11\x6e\xc1\xaa\xcc\x0a\x9b\x9c\x7d\x7c\xed\x6e\x46\x08\x81\xc6\xd1\x27\x15\xf7\xe5\xa2\x28\x9b\xa3\x65\x81\xff\x1c\xe8\xd0\xdd\x83\x24\x12\xf1\xd5\xa5\x03\x35\x2f\x2a\x6b\x23\x67\x9d\xee\x58\x45\x81\xf0\xea\x07\xc1\x01\x5b\x31\xd6\x45\x03\xd5\x0f\xd1\xcd\x3c\x95\x80\x30\xbe\x6a\x86\x60\xeb\x8a\x4c\x1e\x4a\xf1\x04\x7b\x1a\x4e\x3a\xfb\xd1\x51\xf6\x5c\x06\x7d\xa5\x2c\x56\x2a\x34\x0e\xa6\x64\x4b\x23\xf7\xa2\x3e\xc2\x94\xa5\x80\xc5\x3a\xa6\x58\x87\x39\xd8\xa0\x1a\x2b\x0f\x8e\xc7\xa3\x9e\x71\x14\x62\x88\x01\xa1\xb4\xd0\x3a\xd7\xda\x76\x29\xdc\x4e\x7b\x4a\x59\x0c\x82\x28\xe9\x39\x2b\x3a\x6e\x5c\x7b\x75\x6b\x28\xfe\x3b\xfa\x9f\xae\xfd\x7b\xf4\x9f\xfe\x0c\x52\x12\xe8\xfa\xd5\x7e\xcf\x4e\x13\xbd\x68\x3f\x4c\x07\xd8\x91\x70\xca\x8a\x7f\x5f\xca\xea\x82\xf4\x19\x9d\x90\x02\x8b\xc1\x50\x74\x00\x5c\x46\x2b\xfb\x1b\xd5\xe5\xe6\x03\xc4\xd8\x44\x56\xd2\xda\xbb\x00\xc3\x04\x62\x12\x52\x46\x8d\x43\xc0\x17\x8d\xab\xdd\x8d\x6e\x26\x09\x85\xc6\x60\xf4\x90\x15\x35\x54\xed\x3e\x2f\xd4\xeb\x43\x39\xdf\x96\x19\x8e\xa8\xce\xbb\xac\x77\xff\xae\x93\x28\xd6\xd4\x05\xf1\xbe\xcf\xfa\x58\x41\x7d\x2c\x27\xf8\x2e\x96\x90\xc8\x32\x7b\x63\xa8\x36\xc2\x0c\xb2\x84\x24\x22\x8e\x3a\xde\xc5\xd6\xbd\xfc\x4c\x39\x96\x25\x44\x10\xe5\x6a\x51\x8f\xe2\x7f\xcb\x6a\xf5\x03\x8a\x4f\xa4\x7f\x58\x42\x8c\xc2\xb2\xaa\xbf\xb0\x2d\x8a\xbb\x83\x71\x08\xc8\xf4\xb7\xc8\xcd\xa0\x5d\x85\x25\x31\x4d\x91\x7a\x61\xd5\x1c\x6f\x1a\x65\xcd\x70\x77\xcc\x18\xaf\x7c\xae\xaa\xb2\x68\xa6\x4d\x30\x2c\x49\x02\x81\x20\xbc\x1f\xe5\x4f\xff\xa3\x24\xe4\x48\x4d\x86\x7d\xf6\x8b\x3c\x77\xfb\xc5\xe0\x30\xd6\x47\xda\x90\x6a\x51\x38\xee\x16\xcb\x43\x73\x93\x35\x7d\x13\xf9\xe4\x65\x24\xdc\x76\x44\x2d\xfe\xce\xc5\x50\xf3\x9f\x25\x34\xd4\xb6\x71\xc4\x6f\xf5\x1d\xd2\x7e\x7c\x06\x1a\xa5\xd6\xc3\x3f\x9f\xa1\xd0\x9b\xa2\x4b\xa6\x26\x54\x86\x58\x49\xf8\x22\x4e\xb0\x1f\x04\x6a\x09\x0b\x0d\xe6\x29\x8e\xa2\xd0\x48\xa8\x5e\x5e\x9a\xfa\xf0\x61\x72\xed\x33\x38\x08\x4b\x18\x37\x08\x2d\xb8\xa0\xc6\x99\xc5\xfc\x05\xc3\xbd\x3a\x61\xa9\xc0\x1c\x92\xb2\xcd\x14\x6f\x20\x72\x2f\x65\xc5\x12\xce\x52\x34\x6f\x5f\x2a\x51\x34\xa0\x37\xd5\x8b\x28\x9c\xb9\x1f\x04\x19\x49\x6a\x04\xc2\xdd\x96\xa2\xa9\xaf\xa1\x13\x2c\x11\xb1\xcd\xb0\xeb\x42\x3c\x66\x3f\xfb\x45\x25\x12\xdb\x8d\xf4\xd2\x1a\x28\xd4\x26\x99\x60\x62\x59\x22\xa8\x65\xcc\xab\xa1\xb9\xc9\x41\xa8\xe3\xad\xc8\xf2\xf7\xeb\xd2\x28\x4b\x84\x54\xa9\x53\xe7\x38\x97\x95\x68\x46\x5c\x02\x2c\x11\x8a\x5a\xa9\x43\x9c\x6c\x43\x47\x22\x91\x81\x6d\x10\x7f\xca\x4a\xd9\x91\xa9\xb2\x44\x91\x20\x76\x1e\xc8\xfe\x67\x47\xc1\xea\xdc\xa7\xc7\xe5\xf7\xf1\x76\x94\x28\x30\x58\x35\x43\x24\xb4\x6b\x42\xf5\xa7\xd2\x31\x51\xc6\xe9\xc6\x67\x3f\x21\xff\x6d\x60\x02\xdc\x3f\x51\xec\xc7\xa6\x0a\x67\xf7\x1f\xdb\x7d\xf7\x73\x13\xd2\x9e\x11\x67\x77\x91\xae\x90\xf9\xc5\x51\xff\xcc\xbd\x0e\x50\x21\x5e\x12\x49\xc6\x44\xfe\x75\x77\xeb\xcf\x66\x68\x42\x5c\x2c\xd2\xa0\x48\xdf\xe4\x41\x0c\xd5\x21\x38\xbf\xea\x46\xa8\xd7\x6f\xa2\xca\x86\xca\xd6\x2c\x31\x3c\x44\x83\xa3\xb3\xda\xc9\x88\x78\x75\xaa\xc9\xd7\x33\xa9\x40\xe2\xf8\xd6\xfe\x62\x44\xe5\x4f\x41\x83\x30\xc4\x9a\x27\x5a\xd2\x9e\x90\x90\xd1\x20\xb2\xf6\x44\x5e\xaa\x62\xd7\xae\xe2\x3e\x9c\xa1\x01\xd7\x88\xf1\x58\x2f\x37\x16\x1c\x71\xf0\xb1\x56\x37\x22\x4d\x64\xd4\xc1\x8f\x23\x78\x79\xe9\xae\x48\x02\x13\x3b\xed\xfe\x27\x71\x7e\xed\x34\x7a\x19\x25\x61\x12\xb8\x02\xc3\xef\xef\x72\x5e\x59\x89\x51\x42\x9d\xbb\x51\x16\xf5\xe5\xd4\xb9\x99\x94\x68\x81\x8c\x13\x3a\xab\x8f\xbf\xcd\xa0\x8f\x18\x8d\x23\xab\x4b\x77\x78\xfb\x40\xe7\x7b\x60\xf6\x69\x9c\x44\xd8\xc5\xdb\x10\x4c\x85\x7b\x48\xfd\x20\xd3\x45\x63\x46\x13\x4f\x4d\xf4\xf8\x3e\xc3\x93\xcc\x68\x42\x0c\xe9\x18\x4e\x9a\x63\x05\xed\x17\x12\x79\xa6\x57\x7f\x7d\xcd\xba\x99\x4f\x13\x19\x77\x8a\xfc\x97\x22\xab\x8f\x7f\x3c\x4f\x12\x6e\x94\xa6\x80\x79\xcf\xaa\x54\xaf\xd0\xac\xeb\x07\x71\x29\xd4\x11\x26\x7b\x10\xa5\x3a\x74\x2c\xef\x88\xf4\xc3\xde\x22\xcc\xb2\xfb\x4b\x51\x23\x0c\xf4\xdc\x86\x3e\xbe\xed\x4a\x23\x7e\x1c\x4b\xa9\x1c\x7a\x98\xb6\x13\x79\xa0\xa9\xcc\x28\x03\x82\x16\x12\xdd\x95\x21\x39\x0e\xa3\x3c\x8a\x91\x19\xe2\x6b\x0d\x95\x53\x47\x99\x35\x8c\x94\xf3\x14\x25\xb9\x16\xe7\xf3\xfd\x45\xfa\x9f\xa7\x3a\x44\xe4\x6a\xed\x39\xe5\xba\x03\x20\x91\x57\xc7\x7a\xfb\x8f\xa2\x7e\xed\xaf\x29\x08\xd7\x0e\x7f\x75\x70\x56\x74\x28\x90\xc8\xa8\x68\xcd\x4f\x57\x9d\xff\xaf\xf2\x28\x8a\xa7\xf7\x97\x0a\x8a\x7a\x7e\xa6\x09\x11\xa3\x25\x5b\xcb\xe2\xef\x55\xa3\xa2\x60\x0f\xf5\x28\xc5\x45\x65\x60\x69\x5c\x44\x9e\xdf\x95\xd5\x73\x79\xc6\x20\x60\xf2\x49\x64\xc2\x3c\x64\xff\x49\xbc\x4f\x67\x88\x0a\xac\xea\xed\x80\xa2\x65\x26\xc3\x4e\x55\x1a\x20\xbe\xa9\x9d\xb6\x56\xae\xbd\xfb\x0c\x4a\xda\x7a\x8b\x45\x5c\x21\xd7\xf7\xa8\x59\x82\x51\xa5\x15\xe6\x1c\x6f\x2e\x55\x61\x69\x4c\x66\xda\x93\x26\xd7\x33\x56\x33\xa7\x9d\x6e\xd3\x5b\xd6\xa1\xc6\xb0\xf2\xfb\x6a\x7d\xd8\x6f\x0e\xcb\xcd\x97\x9d\xbf\x92\x8e\x2c\x95\x82\x85\x52\xff\x1a\x31\x70\xfb\x2b\x22\x6c\x2e\xdd\xb6\x8f\x59\x63\x6a\x71\xa0\xdd\x10\xa0\xb6\x27\xe3\xc5\x55\xa4\x86\x61\x37\xd5\x8c\x21\xb5\x07\xae\x33\x75\x41\x0c\xf0\x6d\x09\xf5\x53\xd9\x7c\x03\xdf\x99\xc7\x28\x44\x36\x99\x7e\x10\x5a\xdf\xc2\xa9\x54\x1f\x49\xb8\x0e\x2d\x81\x51\x04\xe9\x10\x4f\x96\xd8\xcd\xae\xf3\xbb\xb2\xda\x1f\xb3\x2e\x8b\xc2\x82\x30\xe4\xfd\x67\xbc\x43\x6d\xf4\xb1\x00\xd7\x3f\x60\x2c\x1c\x18\x31\xa4\x33\xff\xcb\x47\xa3\x2c\x88\x28\x5a\xc8\x21\xd2\xf3\x51\xe8\x79\x74\x28\x43\xf0\x00\xeb\xba\x03\x95\xa8\x86\x93\x17\x2b\xac\xd8\x6e\x55\x37\x20\xf2\xa5\xa8\xf4\xf7\xac\x39\xee\x4a\x95\x89\x7c\xad\x61\xd4\x3e\x3a\x39\x71\x48\x05\x26\xab\xb1\xcd\xb9\x53\xf2\x65\x2c\x64\x01\xe0\xfb\xad\xcf\x62\x9e\xee\x9c\x31\x12\x47\xc8\xf8\x5d\x5f\x15\x65\x18\x91\x2c\xb1\x9e\x7f\x79\x86\xaa\xb1\x2c\x23\xfb\xb2\xcb\x2a\x8e\x47\xc7\x86\x43\xd8\x91\x84\x8a\x4a\x1d\xdf\x07\xec\x98\x6e\x50\x42\x8d\xcb\x06\x61\x94\xed\x2b\x28\xe3\x5b\xa2\x5a\xdb\xf0\xd4\x5a\x8d\xfb\x52\x0f\xce\x40\x21\x41\x16\x2c\x34\xdb\xe8\xae\x96\xe7\xb2\x06\xfd\x7b\x56\xbc\xe8\xf2\x34\x25\x66\x62\x8c\xe9\x10\x57\x74\xa6\x4a\x44\x9f\x76\x93\x98\x31\x88\x31\xec\xd6\x65\x9e\x8b\x6a\xaa\x08\xc8\x18\xe7\x09\x02\xde\x6e\xd6\xfb\xf5\xdd\xea\x0f\xff\xe7\x34\x24\xe0\x4a\x5e\x2e\x0b\x30\xc0\xe4\xb0\x94\x71\x47\x8a\xe3\x5a\xe2\x91\x83\x53\x9c\x27\x6f\x2b\xd5\x22\x76\xdd\x34\x8b\x37\x51\xb9\xda\xe8\xc0\x7b\x64\x82\xc5\x18\x87\x7b\x31\x93\x3e\x4e\xed\x06\x30\xf4\x88\x10\x22\x33\xe9\xe0\xe0\xf3\x89\x3a\x26\x38\xc7\x86\xe3\x69\x4f\x35\x63\x42\x86\xa9\x05\xee\x23\xbf\xfb\x35\x78\xb9\x1d\x42\x31\x3c\x59\x3f\xad\xf7\xeb\xc5\xc3\x61\xb7\x5f\x6c\xf7\x3d\xdd\x19\x63\x32\x34\x98\x7f\x39\xc8\x8b\xdb\x7f\xef\xaa\xf2\xb4\x7b\xaf\x9b\x89\xf8\x34\x63\x52\x10\x7c\xb7\xa5\x0d\x20\x7e\x89\x0d\x99\x31\xa9\x24\x77\xc2\x74\x97\xf6\x93\x65\xc5\x33\x22\xba\xea\xfe\x26\x55\x18\x44\xda\x8b\x04\xd6\x96\xee\xeb\x83\xa8\x8e\x29\x00\x2c\x29\xed\x84\x69\x23\x15\xab\x41\x23\xf2\xfb\xbb\xee\x76\xdc\x40\x88\xb4\x8a\xbd\xd2\x56\x96\xbf\xcf\x6c\x09\x0c\x22\x30\x91\xe7\x6f\x3a\xe7\xef\x53\x65\x34\xc6\x7c\x83\x8a\x84\x66\x53\x2c\xcb\xfc\x72\x2a\xa6\x23\xa4\xc1\x5a\x46\x2f\x30\x66\x6b\x6b\x1f\x44\x33\xbf\x88\x7d\x19\x3f\xb4\x61\x94\xdb\xf2\xc0\xa6\x7d\xed\x57\xbc\x18\x8c\x19\x23\xf1\x33\xc2\x4f\xa8\x54\x56\xc3\x43\xd9\x0b\xf3\x0f\x89\xda\xf9\xff\x78\x40\xd5\x24\x4f\xc1\x03\x41\xb0\x12\xd5\x71\x7f\x34\xa5\xe3\x77\x63\x3c\x90\x04\xd5\x46\x4e\xe5\x8f\xae\xff\x67\x34\xb1\x79\x18\x87\x41\xea\x75\x0a\x10\xf6\x32\xdb\x83\x30\x9e\x1b\x3c\x54\x0a\x45\x49\x84\xd6\xcf\x65\x9e\xa9\xf7\xdf\x2e\x43\x61\xed\x89\x84\x22\xe3\x51\x18\xa1\x13\xee\xb4\xbd\x6c\x22\xa5\x33\x0e\x3c\x0a\x29\x77\xac\x0e\xab\xfd\xfd\xd7\xdd\xed\x15\x49\x18\xe3\x11\x11\xb1\x55\x63\x38\x65\xcd\xad\x68\xac\x60\xcd\x77\x80\x57\x5f\x52\xe3\x84\x31\x6c\x71\x54\x65\x75\x0d\x7b\x1a\x7d\x18\x1e\x27\x96\x2f\x64\x5d\x89\x73\xd6\xdd\x47\xec\x32\x9e\x98\xce\xb3\x8b\x6a\xb5\x5d\x32\xc6\x7e\xb5\x5b\xf5\x5f\x83\xfc\xd2\x2c\x37\x11\xe3\x31\xb7\x1e\xc4\xb3\x78\x47\x64\xd9\x3f\xbc\xe9\x58\x5a\xee\x15\x5b\xc4\xfc\xd6\x1a\xe2\xf9\x38\x9f\xc7\xca\x76\xbf\xdc\x82\x82\x2e\xec\xe3\x49\x4c\x63\x5f\xd5\xec\x21\x2d\xc8\x12\xf1\x70\xcd\xc6\xca\x78\xc2\xe2\x58\x7b\xdd\xc3\x70\x58\x5d\xe0\x89\xe0\x1e\xfc\xbe\x14\x85\xc6\x1d\x01\xb7\xa9\x45\x55\x89\xf7\x6e\x94\xb4\xf8\xab\x5e\x5d\xbe\xee\xf9\x72\xdc\x18\x4a\x14\x56\x0a\x50\x55\x58\xf6\xae\x04\xa7\xa0\x7d\x18\x84\x97\x9e\x99\x07\x2c\x0e\x91\xe7\xe0\x69\xfb\xe8\x7f\xc5\x49\x88\x71\xf5\xd7\x22\x6b\xde\x47\x55\x98\x4e\xa9\xed\xff\x50\x66\xe9\x26\x2d\xe7\x14\xc5\xe9\x07\xee\x69\x1d\x3d\x43\xb5\xba\x7a\x69\x3c\x75\xea\x2a\xa2\xd0\x87\xa2\x7f\xf9\x69\x1a\xc5\xbc\xb7\xf3\xbf\x67\x1d\x80\x8f\x8b\x30\xc0\xde\xe9\x53\x59\xb4\xce\x5c\xa7\xc9\xcb\xb8\xa0\x12\x27\xa1\xd5\xc5\x22\x87\xe7\xed\x0a\x55\x37\x6e\x36\x4f\x5f\x77\xdd\x20\x66\xab\xc7\x35\x34\xb8\x25\x79\x03\xc8\xfd\x71\xb0\x5d\xf6\xbe\xdb\xb5\xcc\xaf\xe0\x9a\x6e\xa4\x94\x26\x72\x35\xb4\x95\xa8\x8a\xac\x78\x71\xda\x7b\x37\xef\x5f\xca\x52\xd7\x33\x95\x4a\xae\xa3\xc8\x6a\x12\x1d\xcb\x4b\xae\xef\x84\xe7\x70\x60\x5c\x53\x30\x3d\xb0\xe7\xee\x02\xf9\xf4\xa7\x29\xf3\x95\x87\x7d\x36\xd0\x1b\xfa\xa4\x5a\xc1\xb5\x4e\x69\xd8\x91\xdb\x61\x39\x0b\x29\xf2\x26\x5e\x11\x07\x60\xa9\x95\x5f\x3e\x9d\x2f\x8d\x65\x39\x86\xea\xc7\x60\x0a\x9b\x38\xc6\x5d\xd5\x57\xbb\xf1\xa3\xb6\xfe\x2c\x88\x79\xc2\x41\xc6\x0d\x0b\x88\x73\x1e\x0e\x67\x8b\x8d\x3d\x54\xa0\xe7\x72\xc1\x69\x10\xa6\x18\x02\x58\xfe\x81\x5b\xc8\xb3\x1f\x8e\xde\xc3\x92\x81\xe6\x65\x31\x83\x3b\x99\xfb\xaf\x7f\x4d\x4e\xcc\xe2\xc0\xe2\xe8\x54\x75\xc9\x9a\x27\x51\xa9\x2b\xa6\xb6\xa1\x23\x96\x06\x3a\x92\x5e\x23\xbb\x2c\x4f\xd8\xca\x32\x39\xa5\x21\xc6\xd5\xbe\x16\x7d\x8b\xc4\xed\x80\x0a\x77\x80\xde\x76\xbf\x89\x48\x84\x7d\xb4\x47\xd1\xa8\x63\x7d\x91\xb5\xaa\x32\x39\xa5\x0d\x66\x29\x51\xd6\x3b\x75\x3e\xe5\x63\x96\x43\xdd\xb4\x8f\x3e\xbe\x03\xa2\x09\x27\x1d\x90\xb9\x7a\x9f\x6d\xfb\x66\x69\x4c\xc1\x17\x79\xd7\xd8\x64\xe2\xfe\x9e\x24\xc6\x58\xf2\xb3\x9f\x5f\xd6\xdb\x87\xee\xcf\x8c\x09\xf7\xe4\xab\xd3\x39\x2f\xdf\x51\x37\x55\x4b\xa1\x5e\x37\x1f\xc0\xad\xd3\x44\x4b\xe5\xfc\x98\x29\xb6\x79\xf4\x56\x59\x12\xe1\xa2\x5d\x68\xbd\xfb\xbe\x28\xb4\x85\x9b\xcc\x37\x7c\x4f\xff\xfd\xe0\xf0\x0c\x96\x9e\xa5\x4c\xda\xda\x55\xfb\x9b\x57\x1b\x12\x3e\xab\xe6\x8f\x30\xf0\x0f\x99\x2a\x5b\x85\xfd\x71\x86\x76\x52\x1e\x7e\x87\xb2\x7b\x5f\xa9\x66\x84\x0d\xb3\x17\xd5\x4a\x95\xb5\xf5\x0b\xdd\x10\xc1\x2c\x45\xef\xf7\x63\x99\x8d\x6a\x0c\xa9\x00\xe3\x35\x89\x06\xe9\x9e\x54\xc6\x09\xb5\x0e\x2b\x64\xaa\xc4\xa4\xca\xed\xf0\x70\x1a\x23\xfb\x64\xfd\x96\x35\xea\xb8\x3b\xe7\x99\xed\xb6\x1b\xeb\xfe\xf4\xfe\x76\x2a\x53\x2f\x54\xde\x3c\x80\x78\xb9\xc0\xb6\xf4\x84\xbf\xc3\x19\x30\xeb\x49\xa6\x2a\xd0\x38\x0b\xb3\xe2\x87\xa8\x32\x51\x34\x37\xd5\x20\xb6\x4b\x75\x00\xca\x25\x94\x1e\xa1\x69\x1f\xbf\x39\x0e\x98\x46\xfa\xaf\xae\x1d\xe9\x79\x0d\xb9\xd1\x60\x05\xdb\xbb\x93\x18\x23\xe3\xce\xe4\x74\x34\x02\x2c\x85\xd0\x72\x40\x2d\x54\x59\x89\x4c\x8b\xc7\xb2\xc8\x94\xf8\x2e\x8a\xa6\xde\x97\xbf\x17\xe5\xdb\xfe\x08\x4f\xf0\xb6\x28\xea\x37\xa8\xee\x45\x7d\x1c\xfb\x5b\x29\x24\x29\x46\x48\x58\xd4\xd8\xe2\xa6\x3e\xea\xe1\x9b\x3c\x2b\x48\xcb\xf0\xd7\x15\x08\xb1\x99\x66\xbe\x7a\x94\x9a\x58\x23\x28\x7c\xb9\x5a\xdd\x2e\x37\x6b\x5f\xcb\x4c\x0d\xb5\x1d\x3b\xab\xcd\x6e\xb5\x5d\x5e\x53\x69\x8f\xe6\xb8\x01\x9b\x30\xa9\xc0\x64\x79\x6e\xb7\xf6\x0f\x81\x62\x22\x48\x55\x44\x2c\x35\xdc\x30\xb8\x1c\xaf\x2f\x11\x88\x04\xfb\x67\x0f\xb6\x96\x86\x71\x42\x1b\x70\x3f\x42\xa5\x8e\xa2\x2f\xee\x8c\x1e\x47\x84\xa9\x8c\x86\xe0\xa5\x55\x73\x7c\x14\xaf\x1f\xd5\xce\x44\x28\xad\x74\x9b\xd0\x7a\xf2\x96\x66\x6d\xaa\x08\xa5\x46\xec\xb1\x3f\xfd\xae\xb9\x74\xdb\xb3\x08\x35\x45\x7c\xc4\x9f\x9b\xcd\xe1\xeb\xd3\x7a\xdf\xfd\xdd\x24\x48\xe5\xe7\xf2\x2c\xdf\x91\x09\x79\x52\x97\xed\x5e\x4e\x14\x30\x8f\x96\x42\x57\x6f\xcc\xc6\xe7\x07\x25\x24\xf6\x69\xd2\xee\x45\x27\xdd\x29\xa8\xc2\x6c\xc3\xed\xe5\xaf\x0b\xdc\x54\xf0\x96\x15\x2f\x4e\x34\xd0\xdf\x52\xc4\xb8\x25\xe3\x6e\x57\x9c\xab\x92\x7c\xf0\x1d\x08\x48\x2c\xc5\x20\xb0\xe3\x5e\x54\x7a\xe9\xa9\xa0\x99\x88\x63\xdb\x16\xef\x7a\xa1\x91\xda\x00\x65\xa8\xfc\x71\x60\xca\x02\x7d\x2d\x13\xd4\xcd\x18\xf2\x26\x92\xc8\x20\xbc\xca\xcb\x8c\x7d\x29\x73\xdd\x1d\x4b\x35\xd6\x78\x6b\xa7\xee\x73\x2d\x01\x35\x70\x9c\xaf\xda\x8d\xfd\x49\x94\x46\xa3\xa8\xab\x89\xe2\x0d\x13\x54\xd8\x0c\x99\x4d\xc8\x6f\x17\xfb\xd5\x21\x4a\x0e\xcf\xab\xed\x72\xf5\xb4\x1f\x39\x4e\x82\x91\x34\xf0\x6a\x03\x3e\xf2\xec\x64\x53\x98\x60\x3c\x88\x2d\xc9\x9e\xc9\x31\xef\x7f\xf3\x3e\x83\x52\x11\x9c\xc7\x48\x38\x66\xa9\xdf\x6f\x32\xdd\xe7\x7f\x05\xe7\x86\xf5\xa2\x15\x4e\x95\xd1\x59\xb4\xe7\x76\x55\xfd\xdc\x8b\xfa\xf5\xb7\xf1\x03\x4f\x9e\x7b\x76\x82\xa7\x2a\x45\x9d\xa4\xe6\xa5\xda\x59\x36\x8f\x91\x4a\x32\x13\x22\x22\x10\xf9\x04\x38\x36\xdd\x79\xea\xde\xf1\x89\x44\x12\x88\x5e\x83\x12\xad\x67\x85\x1c\x32\x59\x6f\x82\xa7\x3f\xe1\xb6\xf3\xb8\x86\xe6\x8f\xa6\xf4\x11\x97\x90\x11\xc5\xea\x64\x73\xcc\xea\x75\xbd\x3f\x22\x0b\xe1\xf8\x97\x32\x26\xd8\x69\xfd\xb5\x58\x96\x85\x99\x5f\xe9\x32\x89\x31\xfe\xfb\xb2\xda\x1f\x1e\x17\x7f\x1c\xbe\xae\x9f\xf6\x9d\x1e\x12\x13\x52\x44\x51\xe2\x80\x45\x7d\x6b\xb4\x3b\xa8\x34\x47\x30\x72\x5e\xbe\x61\xcd\x0b\x75\x70\x26\x9f\x0b\x52\xe0\xed\xdd\x1f\xdf\x65\x95\x69\x57\x3d\x44\x82\xa7\xf1\x38\x13\x2a\xee\x7b\x42\xdb\xf9\x6f\x7d\xdf\xfe\x20\xba\xb6\xd0\x6e\x27\x6a\x3e\x3b\x28\x4c\x44\xb1\x9f\xd1\xdb\xeb\x4d\xbb\xee\x67\x09\x66\xe7\x57\xa8\x31\x31\x8f\x7b\x72\x99\x6d\x99\x8f\x23\x59\x3e\xd8\x45\x85\x31\x29\x76\xd1\x89\x4b\x53\xba\xdd\x7e\x82\xe5\x90\x01\xd3\x18\x81\xb4\x7e\x5c\xf1\x92\x83\xe5\xc6\x53\xcb\xbc\xbc\xe8\xf5\x66\x7f\xa5\x33\xc7\x64\x00\x01\x66\xad\xee\x84\x82\x3d\x28\x5f\x87\x95\x61\x2c\xa2\xde\x09\x3f\x97\xb5\x98\x94\x10\xfd\x38\x1a\x63\x6c\x27\x2f\xef\xcb\xcb\xb9\xfb\x35\xb5\xbb\x0a\x26\x6c\x44\xbe\xc5\x76\xe1\x2b\xc9\x58\x26\x43\x16\x29\x27\x97\xf1\xf3\xe7\xb5\x92\xd6\xaf\x01\xd4\x65\x68\x12\xed\x66\xeb\x54\x71\xc2\x8d\x88\xc2\x04\x8d\x49\x1f\xe9\x3b\xe9\x96\x5b\xf8\x01\x79\x97\x40\x91\x51\x14\xa0\x37\x79\x29\x90\xaf\x6e\x7a\x16\xaa\x84\xec\x6d\xe6\xa3\xf8\xd9\x27\x93\xbc\x3f\x26\x49\xc4\xd0\x4f\x3d\xdb\xe4\x69\xe7\x0d\x8f\xb0\x97\x32\x0e\x28\x12\x5c\xdd\x76\xfd\xe4\x4c\x26\x81\xc0\x52\xd0\x8b\x18\x2f\x74\x99\xc4\x29\xe6\x65\xdb\x20\x68\x66\xbe\xcb\x24\x91\xc6\x13\x14\xe6\x99\x7a\x7d\x84\x46\xe8\xeb\x4f\x4d\x13\xab\x5f\x53\x23\x05\x49\xd3\x0b\x7d\xce\x87\x8a\x92\x71\x8d\xa1\xbd\xa9\xca\xd3\x3d\xfc\x5c\x1e\x85\x83\xf6\x87\x7e\x80\x88\x3d\x6d\xfa\x76\x7f\x78\xde\xae\x97\xab\xc3\xfa\xe9\xd0\x5a\x61\x6f\x80\x25\x53\x01\x36\xb8\x77\x59\x44\xc9\x74\x12\x25\x03\x6e\xf2\xe7\xd2\xca\xdc\xba\xc3\x9c\x04\x58\x43\x6a\xdd\x11\xf4\x1c\x26\x4f\xc1\x39\x45\x26\xb3\x1c\x4c\x93\xb2\xc9\x41\x19\x33\x6c\x34\x41\xc1\xbf\x9b\x4b\xa1\xf3\xbe\x55\x4e\x4a\x6a\xfd\xa5\x93\xf8\xf9\xdd\x33\xbe\xb9\x43\x2a\xe6\x98\x88\x78\xfc\x73\xb7\x5f\x6d\xff\x5c\x3e\x2c\x76\xbb\xf5\x72\xe0\x54\x49\x1d\x26\x88\xfa\xf4\xbc\x24\x6b\x8f\xef\x41\xe3\xd2\x33\x15\x33\xa9\x69\x2a\x68\x3f\x4b\x6e\x2f\x90\x7b\x03\x2a\x21\xe0\x98\x15\x3d\x8b\xaa\x79\x47\x77\xf1\xa3\x19\x3f\x9e\x79\x90\x80\xed\x41\x68\xe7\xef\x03\x98\x66\xd4\x68\x24\x21\xb5\x41\xd0\xcd\x9f\x43\x5b\x29\x41\xc4\x08\x19\x79\xf3\x15\x4f\xd0\x36\x35\x30\x39\xb9\x50\xe8\x41\x8f\xb6\xeb\xe1\x64\x35\xca\x76\xe9\x59\x95\xe6\xe5\x51\xe4\x39\x14\x1f\xcb\x34\xcf\x36\x08\x8e\xbc\x4e\x15\x85\xc6\x8b\x33\xde\x65\xb5\x12\xf9\x84\xd3\x6c\xe4\x44\xab\x28\x11\x88\x73\x68\xc3\x76\x47\xe3\x33\xbd\xb6\x77\xc2\x54\xc4\x43\x94\x2d\xf4\x35\x0c\x14\x15\x29\x9a\xd1\xbb\xfe\xe0\x2a\x82\x20\x4f\x66\x07\xb0\x19\xd2\x7d\xb9\x31\x84\x28\xee\xb2\x5d\xeb\xa2\xe1\xad\xa5\xbf\x79\xf7\x5a\xed\xe1\xb8\xdb\x9d\x29\x92\x10\x6c\x01\x7d\xf8\x7d\x79\x45\x79\xc4\x14\xa1\x0c\x01\x44\xeb\x6a\x8c\xf4\x51\x44\x50\xcc\x9e\xfe\x7e\x14\x8d\x38\x75\xd0\x32\x45\x84\x46\x0c\x04\xe2\x14\x50\x12\x74\xd6\x33\x56\x04\xa2\x04\x3a\xaa\xf8\x85\x52\x50\xd7\xb7\xd0\xc6\xc6\xf3\x51\x87\x8a\x13\x8e\x2d\x8b\xff\xf9\xdb\x8b\x98\xfc\x62\x39\x53\x25\xa1\xc4\xce\xe7\x1f\x19\x58\x50\x6b\xbd\xeb\xfd\x40\x95\x68\x8a\x35\xc8\xd3\x25\x6f\xb2\xe3\x20\x38\x1a\x9f\x84\x46\x16\xaa\xe2\x59\x36\x5a\xf3\x75\xbd\x53\x29\x0a\x04\x33\xa9\xca\x6a\xab\xcc\xfb\xbc\x8a\x19\x22\x5c\xc2\xe9\xe6\xcd\xe6\x4f\xc5\x50\x43\xce\x0d\xe3\xb1\xdd\x4b\x11\xef\x79\xf3\x8e\x92\x3d\x23\x5a\xb5\xd9\xb9\xe2\x7e\x9c\xca\x20\x74\xe5\xf7\x55\x73\x1c\x26\x4d\x55\xaa\x23\x84\x07\xda\x94\x90\xe5\x3b\xbd\x0e\x88\x95\x08\x0d\xee\x58\x27\x84\x4a\x1e\x54\x79\x3a\x5d\x30\x9b\x69\xb1\xb7\xdf\x44\x1b\xbe\xfa\xb1\x51\x94\xf2\x71\x5e\x12\x2b\x71\xe3\xaf\xe3\x07\xcb\x28\xd5\x3d\x09\xce\x42\x66\xdf\xa0\xaa\xfb\x42\x93\x92\x61\x80\x2e\x5c\xfb\xc4\x05\x54\x5f\xab\xbc\x3b\x42\x43\xe9\xf3\xbd\xc7\x72\xf0\x4c\x32\x25\x5e\x67\xf5\x70\x44\x7e\x99\xc9\x97\x51\x31\xc7\x8e\x0f\xbc\x37\x17\xf5\xb8\x43\x9a\x18\x24\x44\xfc\xfa\xf4\xb0\x59\xfe\x8e\x1b\x45\x77\x28\x21\x18\x4b\x3e\x7f\xbd\x79\x58\x2f\x51\x6a\x78\x77\xd8\x3d\xaf\x96\xeb\xc5\xc3\xe1\x2b\x52\x58\xf5\x4a\xea\x4c\x69\x1a\x63\xab\xdb\xc3\xea\xe9\xf6\x8f\x81\x65\x56\x5a\x5a\x6f\xaf\x80\xb7\xdd\xd1\x75\x57\x85\x1f\xb8\x0a\x4a\xab\xd0\x36\xff\x76\xc9\xae\x7d\xd9\x9a\x95\x55\x73\x1c\x33\xd7\x32\x05\x84\xa3\x6f\xf7\x0d\xaa\x06\x7e\x1e\xc6\x4b\x62\x3c\x9b\x20\xb5\x8d\x9e\x2f\xd0\x6c\x7e\x40\xd5\xbe\x24\x7f\x16\x13\x32\xbc\xa0\xf7\x10\x9f\xab\xec\x54\x56\x3a\x13\x96\x16\xfa\x33\x31\x02\x7f\x06\x66\x2b\x08\x4e\x56\xbf\x53\x1e\xe9\xae\x90\x86\xe8\x43\xe5\xa2\x6e\x7e\xcf\xd4\x6b\x69\xcc\x20\x59\xa3\x8c\x36\xca\x4b\x81\xa0\xeb\xbf\x2e\x54\x79\xca\xfa\xb2\x93\x1d\xa7\x03\x4a\xb1\x91\x5c\x97\xd8\xd2\xe3\x7e\xae\x43\x62\x9c\x06\x29\x42\x83\xdb\xfb\xfd\x06\x85\x1e\xf8\x6a\x23\x2b\xaa\xc3\x84\x61\x01\xe3\xb9\x2a\x4f\x43\xab\xa6\xa3\xc8\x02\x30\x6b\x68\x0e\x99\x2a\x8b\xec\xaf\xc3\xb9\x82\xc3\xeb\xbb\xb2\x12\x90\x87\xa2\x63\x34\x1b\x3d\xbf\x26\x11\x05\x83\x0e\x81\x6d\x3e\xbc\xbb\x7c\xd0\x3e\xab\x89\x0e\xb0\x3e\x6c\x5d\xc0\x55\x73\xfc\x8c\x51\x8a\x69\x02\xc6\xc4\xbd\x32\xd1\xb8\xc3\x66\xfc\x85\x75\x1c\x46\x09\xe9\x58\xec\xb0\x37\xff\x5c\xf6\xb0\x26\x1d\x47\x82\xcb\x3e\x0b\x37\xce\x02\xe9\x38\x4d\x83\xb4\xfb\xb5\x95\xaa\x9c\x28\xac\x33\x1d\x43\x8a\xdd\xc6\x36\x4b\x64\x95\x4a\x3f\x2d\x16\xe9\xd8\x24\x08\x3d\x7a\xcb\x0a\x5d\xbe\x85\xd7\x7b\x8c\x4e\x8c\x80\xce\x8b\x87\x53\x76\x39\x0d\x61\x88\x9a\x4a\x85\x74\x4b\x3d\xe9\x09\x66\x15\xe6\x7a\xc1\x34\xd5\x61\xec\xa2\xcd\xe7\xb5\x6b\x9d\x48\xfd\x89\x52\xaa\xa2\xd8\x93\x19\x16\xb5\x85\xba\xee\x44\xde\xa1\xf4\xae\x1a\xb8\xb4\x88\x2c\xc7\x8b\x25\x72\xbc\x6f\x63\xea\xe2\xb9\xac\xb3\x81\x68\xcb\xbf\x06\x62\xaf\x3e\xe0\xd0\x22\x4a\xad\xfa\xb8\xaa\x16\x27\x74\x93\xef\xca\xea\x8b\xf0\xcb\x41\x8b\xd6\x2f\x6d\xed\x84\x90\xc3\xd6\x5c\x77\x54\x0a\x93\xf6\x44\x3b\x98\xb0\x5c\x14\xfa\xe6\x52\x5d\x09\xe5\xfa\x1f\x98\x04\xd1\x2e\x37\x55\xa6\x67\x5c\x9e\xf9\xd9\xa2\x40\x61\xb8\xf1\x1d\xa1\xad\x18\xa4\x15\x13\xf9\x6a\xa6\x75\x68\x29\x8d\x34\xd4\xed\xc7\x51\xd9\x90\x28\xc6\x8f\x61\x31\xd6\x7d\xe4\xe5\x7d\x9c\xe4\xea\x8e\x4b\xe9\x1a\x0a\x74\x56\xbc\x8c\x80\x44\x1a\x68\xca\x6d\x86\xec\x7f\x2f\x75\xd3\xe7\x7e\x34\xf0\x00\x73\x37\x0e\x5a\xe6\x3b\x64\x3f\xa9\x4f\x0c\xbb\x4b\xc7\xb5\x5e\x0d\x3c\x44\x7f\xdc\x5c\x0a\xbd\xbb\x28\x05\xa0\x07\xb7\xa0\xc0\x96\x68\xdb\x05\xb3\x9e\x7a\x14\x6e\x90\x71\x80\x22\x79\x79\x1f\x16\x19\xfc\xd1\x24\x44\x5c\x82\xa8\xd4\x31\xfb\x01\x1d\x4d\xee\xe4\x4d\x18\x88\xb4\xe3\xd5\x5f\x35\xc7\xbb\xb2\xda\x81\xe7\x83\x66\x10\xc4\x02\x9b\x6b\xb2\x22\x6b\xd6\xc5\x8f\xac\x81\x51\xc3\xc5\xe8\x4c\x10\x50\x8e\x25\xab\x85\xd6\xdd\xef\xa5\xd0\xb2\xe3\xe6\xef\xfe\xaa\x19\x37\x0e\x04\xdf\x1a\xa5\xfb\xf2\x04\x8b\xd3\xe4\x13\x41\x48\x00\x9c\xcb\xe8\x82\xcd\xa9\x33\x02\xa1\x00\x8f\x7a\x41\xc8\xaa\x6f\x1c\x82\x50\x59\xab\x83\x3c\x21\xf6\xc6\x97\xa5\xf6\xb6\x19\xa2\x88\x23\xc9\xae\xcc\x5e\x1e\xcb\x02\xde\xbb\xbf\x0b\x8a\x0a\xf3\xf6\xfb\x0e\x31\x30\x7e\x80\x8e\x84\x25\x8f\xaf\xa0\x0f\x61\x3f\xb7\x36\x40\x88\xc6\x0e\x8f\xdd\x9b\x69\xe6\x78\xa9\xaf\xdd\x43\x88\x83\x58\xf9\x36\x81\xce\x27\x80\x98\x30\x4c\x2e\x2d\x17\xdb\xf5\x70\x8b\x80\x38\x4e\xd0\xf1\xbd\xdb\x3c\x6e\xba\xbf\x31\xea\xa1\x8e\xcf\x48\x80\x6c\xad\xca\x84\xaa\x8d\x41\x2c\x54\xa4\x06\x8d\x97\xdd\xb3\xc6\x3a\x0e\x6d\xc3\x7e\xa9\x17\xa3\xcb\x25\x11\x91\x98\xfc\x7b\x86\xba\xec\xfe\x48\xc2\xd4\x8b\xca\x5f\x9a\xe3\xcd\x3b\xbe\xf0\xd1\x53\x25\x31\xa1\x4e\x42\xad\xc9\x61\xbe\x8c\x05\x89\x09\xf9\xb5\x9e\xec\xb6\xb5\x8c\xd3\x3a\x1b\x50\x4e\xd1\x69\xf3\x6c\x37\x87\xb8\x3b\x22\x15\x02\x3a\xd0\x79\xfe\x05\xa6\xd6\xf6\x17\x06\x4d\x4f\x63\xad\x4a\xbb\x52\x2c\x79\xad\x3f\x25\x0b\x20\x4d\xbd\x84\x6a\x6e\xb0\x35\x3c\x1f\x90\x9f\xfb\x85\x0d\x8c\xc6\xb4\x97\x9f\xbb\x85\x1c\x5e\x06\xe0\x56\x37\x88\x87\x56\x01\xe8\x8f\xcd\x37\x7f\x01\x1e\x71\xdc\x54\x2c\x7d\x69\xf7\x57\x16\x3b\x7e\xda\xba\x69\x1d\xfc\xc9\x2a\xe1\x4a\x63\x27\x8c\xcc\xf4\xc6\xcc\xe7\x23\x80\x6b\x82\xc6\x04\xdd\x85\xa8\x3b\xb1\xa1\x16\x88\x77\x72\x76\xec\x97\x09\x03\x19\xa4\x41\x84\x14\x78\xa8\x85\x93\x46\x93\x7b\x4a\x03\x8b\x62\x79\xb0\x6d\xae\x96\xc7\xfa\x9f\xba\x22\xfc\x6f\x89\x65\x0e\x44\xc3\xb7\xbc\xd4\x4d\x79\xfa\x40\xc7\x9a\x41\x1a\x0b\xb4\x10\x8e\xae\xe5\x0e\x86\xc2\x7a\x0c\x52\xce\x81\x75\x62\x63\x0b\x2b\xa0\x9d\xe5\x59\xf3\x3e\xc8\x3a\x40\x2a\xad\xca\x83\x8d\x8f\x77\x6f\xe2\x9a\x37\xee\x9a\x9b\x09\x44\x64\xb0\x7b\xbf\x11\xf5\x6b\xbd\xeb\x99\x1d\x40\xc4\x44\xda\x36\xfb\x52\x5f\x14\xe8\x9b\xaa\x2c\xfe\x86\xa5\x38\x77\x13\x5c\x80\xe5\xb9\x69\xd7\x76\x6b\x0e\xe6\x44\xfc\x26\x57\x93\x89\xe9\xa4\x30\xb2\x0f\x95\xe9\x27\x5f\x5d\x3a\xae\x6a\x6b\xcc\xb0\xa5\xae\xcf\x5a\x7f\xd6\xfb\x38\x39\x8f\x0a\x02\x35\x50\xc1\xc2\xdb\x9d\xf0\x2c\x4e\x7e\x40\x39\x56\x40\xde\xb2\xa2\xc8\x8a\x17\x07\x45\xbe\x9b\xfa\xa7\xa0\x24\x8f\x86\xda\xb7\x8b\x42\xff\x0a\x7f\xc2\xf4\x6a\x4a\x21\xcd\xb8\xd3\xc1\x42\x43\xe5\xed\x41\x81\x24\x8f\xdd\x8c\xd7\x09\xf7\x6d\xf2\x6e\x85\xcf\x55\x9a\x40\x0b\x1d\x88\x5e\xae\xda\xea\x5e\x60\x61\xaa\x77\x05\x00\x12\x13\xa4\x9d\x50\x84\xc8\x27\x62\xd0\x0c\x40\x0a\xec\x86\xd1\x7d\x13\x8c\x3b\x62\x12\x81\x85\x67\x0d\xf2\xf2\xb2\x6b\x2e\xc6\xf4\x47\x94\x4c\x07\xb0\x1e\xef\xce\x0d\x8b\xde\x60\xa4\x70\x4c\xb8\xad\xb3\xbe\x40\x6a\x65\xd0\xe3\xe2\xe8\x9c\xbb\x60\x82\xd0\x82\xd1\x56\xfb\xfb\xf1\x97\x30\x41\x6c\x49\xe7\x1f\xd6\x8f\xeb\xfd\x61\xbf\x5d\x3c\xed\xee\xda\x30\xf2\x79\xb5\x5d\x6f\x7c\x33\x8a\x09\xa8\x2d\xd8\x1c\x70\x6d\x62\x73\xcc\x42\x96\x3f\x60\x9b\x0d\x96\xb7\x1b\x1b\x46\x80\xa9\x09\x9f\x4d\xfa\xe8\xa3\xfe\x77\x18\x84\xff\xe3\xcd\x8a\x09\x99\x25\x4c\x39\xf5\xed\x6c\x23\x1c\xc0\xf8\xd3\x9b\x38\x8a\x30\x69\x09\xed\x48\x1b\x7c\xf5\xa9\x02\x43\xd3\x00\xa1\x1d\x47\x51\xbb\x16\x33\xd0\x77\x65\xf5\xe8\xd1\xe1\xfe\xb1\xa8\x88\xd0\x6d\xb1\xc4\x8a\x4b\xa8\x9a\x29\xf1\xf8\x78\x35\x1a\x16\x72\x91\x0e\xd2\x2e\xeb\xee\xa3\x1b\x46\x39\x66\x4a\x57\x45\x56\x1f\x33\xdc\xec\x27\xbb\x83\xe1\x41\x8a\x3e\xcb\xed\x7b\x21\x4e\x99\x7a\x7e\xaf\xc4\xa9\x43\xd6\x19\x4e\x62\x6e\x09\xed\x5c\x37\x05\xe6\xd2\xfc\x41\x61\x5b\xe3\xc0\x37\x6a\xbb\x0d\x6a\x76\x19\x1a\xae\x6c\x3b\xe1\xa5\xce\x8a\x97\xa5\x28\x7e\x88\xfa\xa6\x3d\xa7\xa8\xb2\x0e\x61\x66\xb8\x36\x58\x47\xb1\x2a\x63\xeb\x09\x52\xc8\x08\x1d\xa1\x27\xbc\x5d\x3e\x60\xcd\xf0\xb3\x8a\xb8\x91\x92\xc9\x8e\xa9\x63\xa1\xf5\x4e\x14\xbb\xbc\x6c\x6e\x50\xdb\xf5\xc3\xbd\xc4\x48\x1d\xf1\xd4\xb9\xf3\x55\x39\xdb\x23\x63\x54\xa8\x66\x01\xd6\x0e\xd4\x7d\x05\xb0\x36\x3a\xd5\x82\xf8\x0c\x9a\x12\x75\x33\xdd\xdc\x3e\x51\xac\x66\x46\xab\xc8\x58\xc9\x1c\x8c\x1d\x86\xce\x8f\xd1\x3a\x71\x21\x69\xb3\xd6\x5b\x31\x93\xce\xf5\x03\x8d\x55\xb3\xdb\xae\xfe\xfd\x75\xbd\x5d\x75\xcb\x08\x12\x6b\x18\x84\x52\x70\xee\x91\xdf\x06\xa8\xb4\xce\xa7\x4f\x94\xd7\xcb\xf2\x74\xce\xa1\x01\x3d\x7e\x36\xa0\x26\x00\xbf\x45\x6e\x7e\xa0\x96\x07\x4c\x08\x35\x78\x10\xa6\x1a\xf3\x09\xcb\xcd\xd2\x51\x81\xd7\x9f\xa1\xc8\xb8\xff\x99\x96\x98\x34\xd3\xf0\xa3\x6c\x60\x5f\x2e\x45\x35\xbc\x3a\x0f\x22\xc5\x11\x31\x77\x57\xc1\x40\x38\x84\x07\x91\x31\x8e\x36\x03\x9c\x2a\xd1\xc1\x1f\x22\x34\x0e\xbb\x24\xfc\x22\xcf\xbb\xf6\x88\xd9\x56\x34\x1e\xc4\x8c\xa3\x85\x2b\x4d\xbb\x2b\xd4\x3b\xa1\xaa\xcc\x64\x13\x1a\x73\x1e\xc4\x29\xa1\xa1\xa3\x64\xb4\x39\x08\xef\xff\xf1\x20\x91\x3c\xf6\xdd\x52\x96\x68\xc5\x1d\xa0\x34\xb0\x4a\x5f\x97\xfc\x75\xa1\xb5\xc7\x08\x7c\x34\x3d\x79\x40\x8d\x46\x57\xdc\x72\xd8\x3b\xf6\xb8\x2b\x65\xc3\x6e\x38\x93\x3c\xd6\x8e\x3e\x4f\x0e\xa5\x76\x67\x93\xe7\x3c\x60\x86\x21\xf3\x81\x86\xf6\x4b\xf7\xf4\x09\x36\xf6\x9d\xc8\xef\xf0\x80\x87\x29\x38\xc6\x0d\xc4\x1d\xcd\x39\x7c\x3c\x10\x49\x60\x0b\x13\xc7\xb2\x6a\xa0\xb8\x05\xa1\x91\xa5\x6f\x32\xaa\x8d\x82\xdd\x3e\x57\xe6\xda\x42\xf6\xaf\xc8\x19\x78\x20\x03\x95\x58\x49\x41\xdb\xd2\x5c\x4f\xce\x23\x89\xb4\x39\x59\xb4\xac\x30\x20\xfc\xec\xde\x8a\x4c\x40\x3a\x18\xe6\x7d\x79\xa9\x3d\x13\xee\xfe\xad\x9c\x7c\x53\x99\xea\x38\x1d\x68\x97\xe8\x09\x26\x96\x07\x52\xdb\xa6\xbb\x6d\x56\xe3\xfc\x1b\x2c\x4e\x1e\xa8\x88\x22\x0c\x64\xb1\x7f\x9e\xf5\x19\x79\xa0\x84\x0d\xac\x67\xeb\xf7\x3c\xd0\x60\x70\x4e\xd9\xfc\x72\x14\x84\xa9\xed\x95\x70\xc5\x13\x37\x0a\x48\x12\x7b\x54\xa9\xc8\xe1\x3b\xa6\x91\x66\xcd\x00\x0f\x80\xaa\x54\xf6\x79\xc0\x61\x3c\xc9\x03\x90\x02\x93\x84\x5f\x56\x4f\xc1\x61\xb9\x5d\x21\x05\xdb\x01\xb7\x61\x3f\xc4\x04\xcc\x23\xac\xfa\xd6\xf8\x3b\x70\x17\x5d\xeb\x81\x7c\x71\x3b\x38\xc5\xae\xcb\xb3\x78\x3f\x78\x11\x8f\xf1\xf2\x35\x01\x68\x77\xeb\x87\xa3\xa8\xda\xf5\xe7\x99\x4b\xc6\xf7\x6d\x24\x45\x5e\xdf\xcd\x19\x0a\x2b\xb4\xdc\xed\xad\x3c\x0c\xc0\xca\x0c\xd5\xc7\xf2\xbc\x13\x1e\x0e\xc4\xc3\x30\x54\x1e\x16\xf7\x8c\x0e\x70\x33\xba\x7a\x18\xc6\x71\x2c\xfa\x12\xdf\xb2\x3c\x5d\xb5\xda\xf0\x30\xa4\xa1\x93\x66\x6a\xe4\x8c\x7e\x01\x0f\x43\x9e\xa0\x67\x7b\x80\x9f\xf8\x0d\xb7\xe2\x6d\x0b\x2e\x6a\xfa\xb8\xfc\xd0\xfe\xce\xca\x84\x15\xe8\x91\x6e\x0c\x56\x51\xeb\x7d\xb9\x2a\xac\x2c\x87\x70\x68\xce\xcc\x2b\xcc\xf3\x30\x54\x96\x92\xbb\x4f\xf4\x0d\xf2\xc8\x73\xfb\x2e\x0f\x23\x62\x73\x04\xaa\x44\xcf\xac\xf2\xa7\x8a\x12\x11\x4a\xbb\xb5\x5b\xaa\xd5\xf1\x43\x91\x30\x32\xae\xb2\x87\x98\x8a\x19\xd4\x39\x0f\x49\x1a\x23\x93\xa5\x1a\x74\xc2\xf4\xb2\x14\xe3\xa9\x1e\xc6\x8c\xe3\x6b\xb2\x82\xb8\x5b\x38\xcf\x93\x6e\x8f\x7f\x94\x24\xa0\xc2\x11\xd3\xc6\xe8\x51\x3f\xcb\xb8\xf3\x30\x51\x21\x66\xdc\x6f\xab\xf2\xac\x07\x9b\x43\x98\xa8\x14\x59\x0e\x5f\x2a\x81\x0a\x5f\xae\x29\xfa\x6a\x91\x4e\x69\x9e\xbd\x01\x69\xa7\x04\x06\x9c\x2e\x43\x5d\x2b\x71\x86\x99\xfa\x14\x0f\x29\xb1\x65\x73\x0d\x46\x5c\x72\xac\xd2\x97\x97\xc6\xbd\x4c\x3f\x26\x89\x2c\x58\x10\xc4\x69\x61\x11\xce\x9d\x3f\xc8\x43\xaa\x53\x2b\x01\x77\x11\x08\x12\x03\x6d\x29\x24\x06\x3e\x3c\x0f\xa9\xb1\x38\x0d\xf8\xf1\xf8\x72\x6a\x86\x46\xf3\xc3\x8e\x87\x7e\xf5\xb0\x80\x84\xce\x88\xdb\x82\xd5\xf8\x11\x58\x68\x05\x23\x45\x5d\x23\x34\xf3\x58\xea\x35\x2a\x52\x0e\x78\x34\xed\x8b\x8a\xfd\x2f\x18\x43\xec\xf5\x63\xf6\x73\x6c\x10\xdb\xb7\x66\x15\x88\x91\xc3\xb0\xab\x4d\xf1\x90\x13\x82\x31\xba\xcc\x6c\x51\x60\x7c\x62\x3f\x48\x5b\xda\x95\x36\x1e\xc9\x45\x63\xca\xea\x34\xa7\x9c\xcd\xc3\x94\xd9\x12\xb0\xd3\xae\xbc\xa2\xe0\x76\xc3\x64\x44\x10\x7a\x68\xd3\x5a\x1d\x39\x1d\x0f\x25\x21\x5e\x89\xb5\x2b\x6e\xb8\x5a\xc7\xb4\xc6\xe1\x7f\x91\xd0\x24\xec\x30\x83\xfb\x72\xae\x19\x86\x87\x92\xc5\x51\x2f\x04\x71\x77\xb9\x5a\x75\x2a\x12\x9e\x27\x77\xff\x5a\x6c\x8c\x2d\x34\xa9\xe9\x79\x14\x89\xf0\x6a\x42\x6b\x5f\x2c\x98\x68\x3e\xf1\x50\x31\x1e\xb8\x02\xea\x63\x56\x74\x98\x1d\x27\x34\xd4\x1e\x07\xec\x11\xfd\xb6\x58\x8c\x3e\x91\x92\x31\x6e\x79\xdf\xd6\x6a\xb0\x62\x14\xa4\xdc\xab\x9a\xc2\xcf\xf1\xb7\xd3\x49\xa4\x3b\x02\xd6\xf5\xc9\xf2\xb8\x75\x07\x39\x89\x1d\x4a\x64\xb1\x7f\xbc\x2a\x6d\xf0\x10\x22\xc2\xb4\x45\xff\x9f\xca\xf1\x6c\x01\x42\x10\xe8\xd2\x8b\x07\x17\xaf\x1d\xfb\xf4\xe4\xcd\x99\x20\xc4\xd6\xb2\x75\xbd\x5e\x6e\x5a\x2f\xd4\x9f\xc4\x10\xf0\x62\xf0\x9d\xb0\x85\x3f\x44\x2d\x7e\x6d\x97\xb5\x8e\xed\x4d\xf6\x79\xfb\x14\x0f\x4d\xbb\x19\xe0\x6e\xfc\x6a\x9b\xc7\x91\x7c\x63\xe0\xae\x86\x46\x87\xd8\xf2\x2e\xb4\xb6\xce\xe4\xfc\xbe\x1e\x1a\x60\xe8\x74\x67\xf5\xea\x74\x6e\xfc\xbb\x88\x02\x12\x63\x41\xba\x39\x66\x95\x1e\xf0\xc8\xf1\x28\x30\x5c\x3b\x32\x96\x4d\xd1\x53\x86\x8c\xee\x2f\x0a\x49\x94\xd8\x56\x73\xff\xf4\x51\x48\x95\xb0\x7c\x9a\xfa\x09\xde\x6e\x2a\x51\xa8\xe3\xba\x58\x9d\xb3\xba\xd4\xf3\x91\x02\x8f\xc2\x34\xc2\x1a\xd8\x42\xeb\x85\xc5\x50\x34\xef\xe3\xfb\x8f\x22\x21\x05\xf4\x92\x19\xa7\xcb\xa9\xb5\x7e\xcb\xb2\x9e\xde\x12\x89\xad\x47\x61\x35\x8d\xbd\x6c\xe6\x2d\xf4\xd4\xa1\xe3\xf1\x71\x10\x63\xfa\xa4\xa3\xa7\xfa\x0e\xd9\x5d\x59\xd9\x77\x31\x1a\x99\x04\x29\xb5\x72\x71\xb0\x5e\x6e\x3a\x9f\xd2\x1f\x4d\x63\x2d\x3d\x64\xd6\x19\xab\x3b\xac\xe5\xf7\x23\x38\x42\x40\x6c\xff\xf6\xc6\x6c\x2f\xf9\x8c\x4c\xe7\xf8\xb1\x13\xc5\xb1\x2b\xeb\xe0\xfe\x3c\xb9\x79\xca\x18\x96\x50\xf6\x97\xe2\xb6\x7a\x14\x47\xd1\x7e\xc7\xc7\xf2\x28\x4e\x27\x5f\x48\xe6\x11\x05\x89\xec\x64\xd5\x00\x9a\xc3\x23\x26\x53\x5f\x99\x78\xb4\xad\x45\x5f\x06\xb9\x76\x1e\x61\x1a\xd7\xc6\x41\x5d\xf3\x32\x8f\x78\x60\x49\x3b\xd7\xcb\xcd\xb8\xea\xcd\xa3\xd6\xac\x73\x2b\xb3\xd3\x54\xd9\x74\x02\x46\x9c\x18\x8c\x0b\x30\x06\xba\xe9\xd2\xec\x3c\xe2\x3a\x89\x6d\xfb\xe8\xff\x82\x9a\x55\xaa\x73\x03\x53\x1a\x30\xd7\x60\xb3\x2b\xca\x37\x93\x8b\xd7\xa9\xa2\xc4\xe4\xed\x89\x04\x5c\x67\x6a\x73\xa9\xe6\x29\xff\x78\x24\xd2\x00\x27\xfa\xae\x29\x2b\xeb\xe3\xfd\x6b\x3a\xc0\xda\xa7\x1a\x1a\x9f\x8f\xf5\xdd\x42\x57\xbb\x77\xb7\xc7\x45\x42\x32\x5c\x1a\x0f\xe5\xcb\xba\x81\xd3\xd6\x91\xf0\x7f\xb6\x41\xce\x37\x84\xb8\xf3\x49\xca\x30\x3d\x7f\x38\x1c\x7e\xcf\x7c\x81\x8a\x47\x92\x85\x41\xd0\x85\x4f\xdb\xb2\x3c\x4d\x1e\x4f\x0a\x81\xb0\x8d\xfb\xc5\x7e\x79\x7f\x58\x6e\x36\x0f\xb7\x9b\xef\x4f\xdd\xcf\x95\x95\x76\xb7\x05\xa4\xd6\x8c\x3e\x63\xff\x0b\x36\xc7\x0d\x9e\x46\x82\x48\x1c\x42\xbd\x5d\x77\xfb\xce\x0e\x5d\x2f\x66\x1d\x86\xe8\x82\x1b\x91\xe5\x8e\x48\xc1\x5f\x4d\x13\x89\xf2\x52\x67\x6d\x06\x5a\x68\xcf\x55\x59\x9a\xd1\xdc\x84\xd0\x8e\xcb\xea\xdd\x7e\xe3\x53\x1d\xfe\x24\x40\x03\xcc\x3e\x9d\x47\x61\x51\x04\x3a\x05\xf4\xeb\x45\xf1\x28\x7e\x0e\x61\x90\x3c\x32\x4e\x23\x0e\x51\x81\x8f\xc3\x74\xcc\x04\x40\x3d\x85\x57\x8f\x9e\x8c\x04\x91\x6d\x0a\x3b\x8b\x77\x2b\xfe\xf3\xdb\xe4\x38\x05\x5c\xac\x9d\x7a\xe0\x78\x09\x90\x40\xd9\x86\xe5\x17\x68\xfe\xab\x94\xd7\x44\xed\x9c\x84\x2a\xb4\x14\x0d\xa8\xbb\x23\xde\x41\x6f\x3c\x53\x31\x27\x21\x44\xcc\x49\x6e\x36\xf3\x0e\xf8\xe4\x7e\x89\xab\xa7\xb4\x71\xe4\xb3\xab\x00\x3b\x21\x27\x4e\x08\xb3\x3c\x3d\xf8\xf6\x77\xc7\x2a\x3b\x9d\xef\x44\x75\x9a\x7a\x36\x84\xe8\x24\xf6\x1e\x37\xea\xce\x0d\xe3\x19\x42\x0c\xb5\x0c\xc5\x55\xf6\xf2\xd2\x4e\x9e\x0e\x00\xc2\x49\x1c\x49\x74\xca\x4a\xcb\x63\x6a\xca\x89\x7e\x1c\x27\x71\xfb\x4c\xc8\xb1\x9d\x9b\xd6\x42\x63\x67\x4d\xef\x89\x92\x98\x59\xb0\xd3\x7a\xb9\x39\x3c\xae\x9f\x0e\xb7\xab\xe7\xcd\xae\x8b\x0c\x49\xcc\x35\x66\xa9\x0e\x05\xbc\x7d\x99\xaa\xca\x71\x92\x68\x83\xbc\x6c\xbb\xbb\xfd\xe1\x79\xb5\x3d\xac\xf6\xf7\x87\x9b\xc5\x6e\x35\x00\x07\x71\x92\x18\x82\xd5\x3f\x79\xc9\x72\x3d\x9c\x84\x84\x26\x80\x6d\xb2\x4f\xf0\xe6\x84\xda\x26\x6f\x86\x32\x8b\x2b\xd2\x59\xad\xca\xa2\x00\x65\xfb\xda\x67\xb5\x3e\x67\xad\x3b\x61\x69\xea\x14\x0e\x9b\x47\x4b\x9c\xe1\x99\xc9\xee\x2a\x71\xdd\x37\xc8\x09\x33\x06\xe9\x8e\x0a\x78\x9b\xdf\xe7\x09\x0f\x39\x32\xff\xa0\xb7\xf0\x51\xa8\xf3\x11\x08\x61\x6c\x72\x08\x0f\xa5\xaf\x68\xde\x67\x2f\x47\xa8\x9b\xaf\x45\x66\x3d\xb1\xb5\xfe\x89\x2c\x02\x5d\xa9\x9c\x13\xce\x25\x6e\x6f\x52\x14\xae\x83\xfc\x2a\x39\x44\x38\x30\x65\x31\x3e\x59\xf1\xf7\x10\x9e\xcf\x49\x4a\x44\xac\xbc\xee\x6b\x71\xa9\x6f\xde\xaf\x50\xdf\x9c\x08\x57\x61\xdf\x82\x2a\x7f\x40\xd5\x53\x91\x71\x22\x34\xf3\xfb\x3e\x4a\x19\x8f\x7f\x28\xe3\x10\xd3\xbc\x59\x61\x72\xdc\x04\x0e\xca\xe5\x16\xfd\xef\x95\x86\x38\xed\x15\x06\xe7\x75\x6f\x39\x51\xa0\x10\x95\xe5\xfe\x7a\x77\xe9\x55\xaa\xdc\x08\x1d\x0b\xcc\xbc\x9d\xb2\xa2\xd7\x9c\x5a\x96\x65\x9e\x15\x2f\xa3\xd8\x9a\x68\x9a\x5a\xc5\xc2\x23\xa8\x57\xab\x7a\x81\xd5\xb9\x8f\x08\x57\xfc\xcf\x20\x40\x1a\x78\xdb\x44\x67\xe9\xb3\xf1\x4d\xf4\xf6\x9a\x40\x60\x1b\x15\xc1\xa1\x0c\xd7\xc5\xd7\xba\xbb\x2e\x44\x69\xe4\x72\x4c\xcf\xbb\xbc\xf4\xc1\xe1\xf8\x2a\x40\x62\xf4\xf8\x97\x59\xd9\x06\xb2\xd8\x0f\x36\x0b\xee\x9c\xe9\xc4\xe5\x04\x58\x20\x7b\x0e\xa2\xef\xc7\x5e\xe1\x60\x36\x70\x26\x86\x79\xb0\xd8\xa9\xfc\x01\xcf\x3d\x1b\xf6\xf8\x3b\xc6\xad\x09\x0e\x3e\x6d\x10\x8a\xe7\x7b\x83\xfe\x35\x39\x4f\xac\x74\xea\x23\xd0\xfc\x02\xbb\xf2\xf4\xc1\x7e\x16\x07\x2c\x0a\x6d\xcc\x26\x2a\x75\xb4\xac\xd1\x23\x23\x18\x07\x8a\x62\x40\xd1\xba\xdf\x0e\x1d\xb9\xfa\xeb\x92\x35\xef\xae\x55\xe0\x37\x3f\xce\x70\xe0\x9d\x3b\xb2\x6a\xae\x70\xc5\x6e\x5c\x18\x05\x09\xef\x14\xc7\x5e\x03\xfa\x5b\x7f\x80\x92\x71\x32\xe6\xe3\x7d\xa0\x17\xf0\x1b\xab\xc5\xf3\x38\x34\x16\x1c\xe2\xda\x6e\x6d\xb6\x65\x00\x00\x6a\x47\x68\xff\x39\x90\xe3\x7b\xf2\x15\x22\x6e\x33\x39\xb5\xc8\xc1\x92\x1e\xfb\x1f\x12\x26\xf1\xd6\x65\x1b\xc7\x3a\x5b\x36\x09\x39\x63\x22\xc0\xa4\x03\x32\x96\xf6\xd2\x5b\x78\xf3\xc2\x83\xfd\x65\xe2\x44\x61\x81\xde\x72\x54\x3e\x95\x1a\x6e\xc0\xb4\x4e\xda\xa7\x3e\x73\x1c\x33\xab\x54\x64\xa0\x51\xc7\x01\x3d\x7a\x7b\x44\xa5\xb6\x91\x18\x9b\xb9\xaa\xee\xef\x42\xe2\xc6\xdd\xf8\xf8\xa9\xcc\x5d\x35\x5c\x9c\xa0\xf5\xde\xd6\xdd\x9b\x49\xb8\xc1\xba\x9e\xcd\x86\x3b\x2c\xff\x4c\x36\x7c\x72\x4f\x49\x9a\x04\x0e\xa9\xbc\xc3\x40\x64\x81\xe6\xbd\x5e\xf6\x4c\x1b\x6e\x24\x0d\x39\x66\xb8\x8c\xa8\x4e\xed\xa5\xeb\x8f\x53\xf3\x31\x8d\x43\x69\xf9\x10\xb1\x2b\x3b\xb3\xdc\x76\xd5\xb5\xac\xdf\x64\x82\xd1\xd8\x36\x1a\x28\xc7\x2d\x59\xfe\xf4\x01\x61\x4c\x0d\xa0\xdb\x7f\xa8\x21\xcf\xd1\xd5\x2b\x6d\xf2\xf3\x1f\x8a\xd1\x93\xe7\xe5\x4e\xbc\xdf\xa5\xc4\x9f\xb1\xba\x86\x13\xad\x1e\x02\xb4\x7f\xa9\xc4\xcd\xe3\x54\xc9\x74\x58\x28\xb7\xb5\xfc\xc9\xb4\x92\x84\x62\xf3\x2a\xfc\x80\x2a\xab\x2f\x43\x0c\x29\x8f\x65\x9c\x1a\xb7\xf1\x38\x39\xf2\xe8\x43\x3f\x7c\xd6\xea\xc6\x52\xa7\x7d\x63\xd2\x49\x64\xc5\x8c\xff\x16\x6b\x4a\xa4\xf1\xdc\x9d\x17\x9d\x35\x96\x96\xc9\xb7\x59\xf1\x58\xa7\x02\x4b\xd0\x7f\x5d\xd0\xd9\xb6\xa5\x75\x7f\x10\x22\x9b\xb9\x58\x64\xf5\x71\x40\x41\xca\x63\x50\x3a\x71\x06\xbb\x7d\x7b\x87\xb4\x3b\xa0\x01\x31\xeb\xe7\xb2\xf8\x3b\x73\x86\xbe\x03\x80\xf0\x18\x8c\xc2\x06\xe8\x7d\x25\x7e\x40\xfe\x84\x1b\xdf\x2f\x01\xb0\x78\x6c\xc2\x14\xc1\xbf\xdf\xcb\x2a\xd7\xcb\xcb\xf9\x4e\xa8\xa6\xac\x26\x29\x9f\xd8\x88\x18\x4b\x76\x8b\xf3\x79\xa1\x87\xe2\xf6\xf3\xf8\x88\xa1\x11\x32\xd2\xb6\x81\xd6\x59\xf1\x60\x85\x3d\x5d\xb4\x8d\x3e\xb8\x03\x6d\xf2\x24\x20\x4a\xbb\x85\xe3\x00\x2c\xb9\xdf\x9b\x6f\xde\x3f\x8d\xfe\x92\x20\x0e\x13\x2b\x62\xf9\xf2\xd2\x83\x7b\x06\x74\x4e\x3c\x09\x98\xed\xa4\x30\xe2\xa2\xa0\xb9\xb9\x71\x7d\xf3\x3c\x09\x8c\xc0\x1c\x4e\x59\x94\x1e\x9d\xc0\x13\x42\x28\x2e\x4d\xdf\x08\xdc\xa1\xf2\xea\x65\xe7\xa5\x27\x84\x88\x50\x7b\x3e\xe1\xaf\x6d\x44\xad\xca\x3c\x17\x0d\x54\xd9\xdf\xa0\x3b\x9c\xaa\x1f\x4d\x09\x02\x71\x2b\x0b\xef\xda\x14\x60\xb9\x5e\xfc\xe1\x34\x0a\xa0\xd7\x7c\x1d\x36\xf9\x8d\x5c\xb5\x84\x80\x25\xb8\x47\x7d\x89\xdf\x8b\xf2\x6d\x8c\x07\xe5\x49\xcc\x13\xc4\xa4\x43\x73\x3c\xd4\x9d\x3e\x0a\x4f\x62\x6d\xd0\x58\xd6\x4a\x14\x05\xe8\xdb\x4c\x9c\xca\x42\xf7\x70\x1d\x9e\xc4\x86\x22\x83\xa1\xbc\xbc\x23\xcd\xfa\xa6\xb8\x81\xa3\xc8\x27\x8e\x51\x92\x68\x40\x18\xe5\xf7\xfb\xf5\x7e\xf5\xb0\xde\xed\x0f\xab\xa7\xdb\xc3\x6d\xef\x6a\x27\x2c\x48\x7c\x0a\xc7\xf3\x37\x77\x87\x48\x18\x30\x2f\x63\xf2\x98\x15\xcd\xc7\x46\x2f\x61\x42\xc6\xb6\x1b\xff\xaf\xee\xe7\x4a\x06\x36\x4d\x56\x5c\x44\x7e\x05\xe3\x1a\xcd\xd9\x84\x87\x9d\x9e\xf6\x7f\x95\xb2\x7b\x4c\xee\x64\xd0\xef\x96\xe1\xd0\x72\x24\x9c\x42\xe2\xd0\xe7\x3e\x86\xe2\x53\xaa\xa7\xde\xc3\x18\xf3\xa4\x76\xb3\x38\x8d\x18\xfa\x84\xe8\xe9\x59\x52\x1d\xcc\x28\x0e\xb3\xfd\x1e\xaf\xec\x7f\xa2\x03\x6e\x7c\xc6\xd5\x6e\xb2\x56\xd4\x73\xfc\xda\x53\xad\xc2\xa0\xcb\x9e\x78\x2a\xe1\xf9\x27\x17\x8c\x20\x5c\x0c\x53\x30\xf7\xa5\xce\xed\xae\x8b\xc8\xa4\x89\xa7\x9e\x08\x6d\xb0\x15\x68\xf1\x70\xbb\xfa\xb5\x9e\x1e\x9e\x08\x88\x30\x32\xcf\x9a\x72\x55\xe8\x1e\x63\xc6\x13\x19\x69\x3e\xd4\x44\xec\x2b\x20\x93\x18\x39\x91\xb1\xad\x73\x78\xd1\x02\x44\x29\x8d\xc8\x1c\x79\xa2\x22\x12\x0b\xff\x36\x5d\xc2\xf0\xef\xb1\xa4\xe1\xf8\xa4\x8a\x06\x36\x5f\xec\x2e\xdf\x3a\xb3\xe4\xb3\x4a\x59\xa2\x44\x98\xc6\x83\xa5\xde\xa5\xf4\x26\xb7\xab\xc3\x90\x58\xd6\x25\xf5\xae\x5a\x0f\xdf\xee\x0d\xa3\x19\x04\x91\x4d\xfa\x76\xb4\x8c\x93\x73\x00\xb3\xed\x22\x76\x33\x40\x2b\xee\x19\xc4\x3f\xaa\x3a\x7d\x14\x5e\x8e\xbf\xb7\x31\x7a\xc0\x9b\x02\xd5\x93\x38\xc1\x1f\x03\x9d\xe5\x3e\xd3\xd4\x59\x44\x1a\x68\x85\x4a\x17\x59\xbd\x05\xd3\x59\xdc\xdf\xfc\x51\x63\xe5\x00\xee\x00\x26\xa9\x48\x1a\x32\x2b\xe5\xff\xef\x7f\xff\xbb\x87\x5b\xf8\x63\x9a\x20\x6e\x07\x59\xe4\x31\xb3\x8a\xc9\xa6\x7a\xe1\xcd\x10\x8d\x42\xab\x92\xe3\x4b\x3e\xa2\x3b\x10\x4b\x44\xf1\x5a\xb6\x31\x47\xfa\x3e\x7e\x81\x94\xa4\xc2\xcb\x5d\xe1\x42\x99\x79\xc9\x94\x68\xa2\x58\x2f\xe6\xbf\xde\x2e\xe7\x17\x09\x8d\x53\xc5\xbd\x7e\x4a\x06\x55\xdd\x31\xe2\x4c\x49\xcb\xe6\xfe\x8b\xff\x37\xf9\x9f\xff\x8e\xdd\x1a\xa2\x49\x0c\x98\x78\xc5\x0a\xce\x07\x01\x25\xa5\x81\x1c\xf4\x15\xa0\x36\xa7\xf5\xea\xa7\x9b\xdb\xf8\x36\x69\x1c\x5b\xd5\x61\x2c\x6d\xdc\x2e\xd6\xcb\x8d\x7f\x65\x34\xb1\xf5\x0d\xa4\xdf\xaa\xf4\x4c\x39\x87\xd2\x84\x22\x9c\x08\x8f\xe9\xe9\x41\x2d\xd0\xdb\x38\xb4\xef\x7c\x53\x59\xe6\xfc\xa1\x4a\xc3\x7c\x88\xf5\xd1\xbf\xae\x52\x41\x59\x1a\x60\xe7\xa6\x6d\x70\xdb\x65\x2f\x85\x68\x2e\x15\x60\x47\x4c\xb7\xe3\x51\x06\x1a\x64\x27\xa5\x81\x09\x15\xbc\x49\xbf\xf8\x69\x1a\x58\x1e\xca\x27\x00\xbd\x05\x53\x41\x3d\xa9\x11\xd3\x34\x8d\xb0\xa5\xa4\x34\x26\xcf\x0a\x58\x60\x13\xc3\x7c\x70\x47\x53\x69\x37\xd8\x5a\x38\x64\xc2\xf4\x5c\x46\xe2\x6b\x3e\x89\x9f\xdf\x21\x6b\x27\x84\x77\x11\xa8\x8c\x78\x18\x0d\x34\x87\xf2\xac\xc6\x7a\xcf\x55\xd6\x83\x4a\xce\xd5\x48\x01\xc3\xf6\xf1\x20\x9b\xfa\xfb\x19\xc2\x0f\xee\x4d\x09\x83\xbe\x62\x2e\x6a\xdb\xef\x7c\x10\xa1\xbf\xb8\x8e\x74\x32\x06\x89\x63\xd2\xe4\x79\x5a\xa1\xa1\x3a\x01\xcc\x0f\x5f\x0a\x9f\x81\x5e\x8a\xd3\x59\x64\x2f\xd3\x27\xd5\xc2\x16\xcb\x2d\x13\xf1\x16\x54\x59\x7d\xc8\x7f\x3b\x34\x18\x10\x45\xdc\xe9\xfa\x95\xf5\xa9\xac\x7b\x25\x25\x4e\x81\x0b\x6c\xf3\xfe\x82\x35\x06\xdf\x66\xc0\xa9\x89\x1c\x01\xb3\xc8\x8a\xdf\x45\x75\x12\xa3\x42\x0b\x35\x91\x4a\xad\x12\x46\x9e\x83\x6a\x16\x79\x8e\xf6\xc6\x1f\x8d\x13\x6a\x29\xae\x34\xc0\x09\x74\x3b\xc7\xfb\x83\x82\x18\x97\x05\x6a\x5f\xef\xfa\xca\x23\x1d\xec\x5e\x1d\x8d\xac\xfd\x2d\x0b\x02\x8e\xe4\x23\xdb\x87\xe7\x2d\x36\x2b\xee\x3b\x56\x7e\xce\x02\x45\x91\x17\xd9\x45\x7c\x5b\xd1\xc0\xf2\x38\x07\x7e\x1b\x7f\x44\x16\x80\xe1\x74\x8c\xe6\xc7\xee\xbd\xae\xa4\xc2\xc2\x44\x20\x4e\xed\xcb\x72\x79\x3f\xdc\x37\x58\xc8\x43\x4f\x78\xdd\xce\xab\x65\xfb\x36\x5e\x60\xa5\x2f\xb6\x5c\x7f\x0b\x8d\xc8\xf2\x71\x3e\x96\x85\x3a\x42\x41\x22\xa1\xf5\x23\x34\x50\x61\x8b\xfc\x6f\xb3\x49\x6e\xf7\x8b\x08\x88\x95\x41\xdd\x3c\x3f\xaf\xb6\x87\xc5\xe3\xe6\xeb\xd3\xfe\xb0\xfb\xfd\xc1\xdf\x46\x1c\x69\x0c\x16\x3b\x69\xb0\xcb\x55\x66\x9b\x25\x81\x15\x66\xab\xa1\xd0\x2e\xe9\x31\xc2\xf9\xb0\x44\x52\x90\x5d\x1d\x7a\xeb\x4a\x44\x3d\x4f\x7b\x3b\x82\x21\xd5\xd4\xff\x43\xd9\x97\x6c\x37\x8e\x23\x6b\xbf\x4e\x2d\x7a\xc1\x99\xc0\x52\x92\xe5\x4c\xff\x69\xd9\x6a\x4b\xce\xac\xea\x7b\xee\xd1\x09\x00\x01\x9b\x6d\x89\x54\x93\x94\x6d\xf5\xd3\xff\x87\x01\x80\x93\x28\x67\xdd\x4d\x65\xb7\x09\x52\x1c\x30\x04\x22\xbe\xe1\x64\xfb\x9f\x61\xc3\x0d\x5f\x66\x2c\x43\xe3\x06\x5d\x49\x68\xc6\xd1\x4d\x56\x1d\x29\x09\xb2\x42\x95\x5d\x10\x00\x59\x9a\xfa\x3e\xad\x49\x55\x10\xf7\xf5\x07\x58\x9a\x2a\x53\xa4\xa4\x9b\xf4\x77\x7f\x4b\xe8\x94\x91\xd0\x9f\x81\x06\xca\x42\xa1\x1a\xd4\x18\x52\x06\x92\x66\x5d\x38\x1e\xf7\x99\x6c\x16\xcd\x4e\x17\x8b\xa5\x3c\x12\x2c\xed\x29\x28\x0c\xbf\x1a\x67\x3e\xd8\xd1\xfc\xd3\x00\x3c\x8b\x9e\xf1\x57\x12\x0d\xc3\x99\x14\xa2\x44\x46\x5d\xaa\xf2\x9f\x27\xd8\x9b\x52\x4a\x56\xe4\x73\x2b\x16\x39\xbc\x73\x88\x0c\x66\x91\x66\xd5\x32\xa7\x41\xb3\xe8\xdf\xbd\xd0\x21\x11\x71\x77\xa7\x0a\x09\x4c\x3a\xb9\xcd\x48\x65\xe8\xa7\xd2\x6d\x33\x9a\xef\xfb\x5c\x11\xa6\xf8\x09\xb3\x8e\x0c\x34\xfc\x69\x29\x03\xad\x3a\x30\xb9\x39\x6d\x1c\x58\xa4\x52\xa1\x41\xa4\x90\xbf\x51\xcf\x7b\x89\xa5\x2a\x32\xea\xe7\xcb\x77\x2c\x1f\x3f\x72\xe7\x58\x3a\xea\x81\x2a\x06\xb0\x31\xc0\xfc\x74\x76\xc1\x5a\x37\x4f\xa5\x4a\x30\x9a\x36\x9a\x5d\x09\x69\xf2\xdf\xad\x96\x9b\xed\x6c\xb5\x76\xbf\x83\x89\x20\x61\xe5\x15\xbc\x63\xde\xdb\x7d\xa7\x98\xe8\x28\x1a\xca\x4b\x75\xc1\x68\xaa\x59\x14\x18\x30\xfb\xfb\x62\xb6\xbd\xc1\xaa\xce\xf2\x3e\x9c\x86\x79\x41\xea\x07\x2d\x09\x5a\xb5\x15\x76\xe6\xc5\xa9\x96\xbd\xf0\xcc\x40\x38\x6f\x8b\xf2\x16\x89\xc4\x39\x66\xda\x32\xe6\x31\xa3\xe0\x2d\xa0\x59\x32\xaf\x84\x06\xcc\xd3\x3a\x16\x2d\x67\xd4\x0e\xc7\xbe\xae\x30\x63\x7e\xc8\xa8\xc9\x11\xce\xca\x29\x72\x32\xe6\xeb\x44\x9b\xa4\x8d\xd3\xa0\xed\x84\x3e\x6c\x93\x20\x88\x29\x0b\x52\xe4\x78\x28\xf2\x16\x51\xc4\x82\x38\xa5\xad\xc5\xe6\x00\x65\x0b\x41\xf8\x55\x94\x6f\xd5\x6b\x71\x1c\x74\x76\x16\x24\xa1\x89\xe8\xa0\x7c\xc1\xaa\x5e\x63\x3e\x90\x96\x63\x2c\x50\x06\x02\x4e\xba\xf4\xcd\x1d\x38\x50\x2b\x0b\x03\x45\x28\x99\xdd\x6e\x77\x2c\x8b\xcf\xb3\x31\xb8\x6b\x8f\x46\xa9\xc1\x86\x41\x3e\x47\x57\x48\x51\xf3\xf3\x72\xf5\xf8\xb0\xfd\xa3\xbf\x1f\x63\xb1\xef\x13\x81\xab\x36\xe8\x28\x5a\x5d\xdd\x65\xe2\xc0\x26\xd5\x8a\x2c\xaf\x8c\x11\x13\x81\x48\xda\xe3\x32\xa6\x32\x9c\x51\x0a\x39\xb7\xf4\x26\x2b\xf1\x6c\xfe\x71\x6d\x51\xd1\xca\xaf\xb0\xca\x4a\x9c\x0a\xc5\x58\xac\x13\x72\x3f\x20\xdf\xde\xfe\xfc\xcf\x12\xa1\x09\x35\x7c\x28\xaa\x7a\xd3\x6d\xd9\x59\x22\x91\x64\x50\x6e\x8b\xf2\x8d\xfa\x62\xab\xe2\xca\x58\x1a\x86\x06\xf4\x3c\x7f\xfa\x22\x59\xdf\x36\x36\x34\xcf\x66\x6d\x2a\x72\x32\xeb\x43\xb0\x3c\xdf\x53\xc7\xb8\x60\x2c\xe5\x48\x43\xc3\x96\x5d\xce\x9b\x57\xb8\xdc\x3e\x5d\x4b\xa7\x0d\xd3\xf0\x93\xc5\x6d\xc6\x02\x13\x66\x89\xd3\x79\x51\x82\x18\xbd\x22\xc6\xcc\x12\x65\x96\x86\x59\xfe\x82\xa4\xc4\xbe\x41\x02\xf2\xf7\x62\x4c\xc6\xb8\x12\x16\x82\x44\xd8\x8b\xae\xe4\xd2\xaf\xd0\x8f\xc6\x0b\x8f\xc0\x4f\xda\xb5\x69\x05\x9f\x03\x0c\xc2\xa8\x6d\xcc\x53\x9b\x89\x7b\x36\x07\xdc\x9b\xe7\xd2\x2c\xf4\x99\x2c\x1e\xdf\xb1\x8c\xdb\xbf\xab\x24\xea\x43\x8a\x28\x10\xda\x16\x83\x1e\x0f\xb1\xa9\x24\xce\xb6\x9f\x46\x5a\xda\xfd\x3d\xf5\x68\xe6\x31\xda\xf4\x4f\xc5\x69\x8f\x75\xbb\xa6\x30\x10\x82\x62\x9d\xc3\xb9\xe3\xde\x74\x13\x1e\x03\x1d\xd2\x70\xf8\xe7\xd3\xfd\x6e\xd0\xaf\x44\xe4\x7b\x8e\x7d\x4a\x07\x46\xe6\x13\xc3\x27\x16\xb1\x0c\x0c\x6a\x73\x45\xa5\x80\x5f\x50\x8e\x90\x1f\x4c\x40\x42\xe5\xf5\x0f\x9a\x63\x48\x22\xd5\x1d\xd1\x1e\x6d\x8f\xdb\xc8\xf7\x79\x73\x23\x4d\xe6\x67\xf8\x2b\x52\x09\x4a\x64\x52\xad\xb8\xb7\x70\x32\xa9\x8d\xa0\x69\xb3\xb7\x3b\x43\x5e\xdf\x94\x45\x56\x2f\x65\x91\x17\x87\xec\x3f\x27\xdc\x2d\x8a\xc3\xb1\xc6\x5d\x34\xba\x9e\x0a\xb9\xe1\xed\x56\x56\xbd\xee\x09\x41\xb6\x6e\x0f\x8c\xa9\x38\x12\x36\x4e\xbc\xbf\xff\x69\x48\xe9\x61\x3b\xcf\x28\x69\x3c\x81\x89\x86\x54\x14\xba\x89\xd2\x07\x01\x04\x53\xa8\x29\x61\xb5\x5a\x3d\x0e\xde\x2d\x26\x5c\xb5\xcf\xb1\x2e\x3e\xb0\x7c\x3e\x8e\x5f\x97\x8e\x0d\x02\xfb\xa5\x04\x89\xa6\x7b\x92\x9b\x33\xa5\xc7\xfd\xe1\x9c\xa6\x41\x91\x7d\x8a\xe9\xfa\xce\x71\xc0\xf8\x0f\x3c\x3f\xdd\x4f\x2f\xd3\xdc\xb3\x68\x44\x32\x66\xa3\x14\x8f\xbb\x87\x81\x9a\xcd\xf0\x24\x3f\x96\x7e\x64\xf9\x0b\x1d\xf9\xde\x1d\x4c\xe2\xc4\x28\xc8\x9c\x7f\x65\xf5\xab\xc3\xc1\xdc\x5d\x47\xb3\x9c\x7a\x66\x6f\xc3\x2d\x03\x0f\x52\xa9\xcc\xc7\xa1\x68\x67\xfe\x30\xbf\x14\xb6\x67\x3c\x8c\x8c\x0e\xbc\x75\xed\x69\xe2\x96\x49\x2a\x29\xe3\xa1\x94\xf4\xb1\xeb\x82\xfc\x62\x86\x8f\x15\xa2\xc1\xb1\xed\x2a\xac\x29\xd1\x7c\x01\xb9\x72\x0d\xb5\x51\xae\x73\xac\xa6\xca\x2a\x38\xdb\xc3\x11\x37\x26\xd4\x3d\x49\xa4\x31\x34\x9f\xc7\xb1\x26\xde\x46\x26\x8b\x75\x67\x6c\xc6\x78\x0c\x8a\x96\x9b\x5d\x13\x96\x17\xea\x34\x4e\xe3\x4e\xef\x1d\x78\x12\x2a\x72\x32\xbf\x5b\x3c\xae\x9a\x25\xd9\xb0\x0f\x5c\x4f\x1e\xb5\x65\x66\x57\xb4\x81\x77\xfc\xab\x38\xcd\x72\xb5\x1a\xd4\xd7\x79\x02\x21\xb1\xa1\x66\x37\x3f\xef\x36\x8f\x4f\xbb\xcd\x76\xf6\x63\xb9\x7b\x7c\x58\xb6\x0d\x84\xf1\x4d\x6e\xa6\xbf\x77\x2c\xeb\x75\x99\x15\x65\x56\x67\xff\xed\x92\x5e\x97\xb2\xc3\x17\xa0\xa5\xff\xc3\xac\xcf\x13\xd4\x26\x2b\xda\xab\x43\xf6\x94\xf4\x18\x4f\x34\x08\xdd\x4a\x0f\x93\xd6\xb4\xc5\xc3\xdb\x06\xa9\x07\x22\xea\xb2\x3a\x57\x61\x17\x03\x79\xef\xfe\x1a\xc8\x53\x66\x8c\x8f\xc9\x14\xa5\xc8\x8d\x70\xfa\xf2\x3f\x73\x73\xa3\x2b\xac\xaa\x0e\x13\xc9\x53\xf0\x81\x30\x91\x4d\x58\x44\x02\x9b\xcd\x92\xbd\x2e\x5b\xf6\x36\xe3\xa9\x34\x5a\x38\xeb\x12\x8f\x50\xe2\xd6\x68\xe0\xfe\x86\x81\x3d\x5d\x72\xe2\x29\xf2\x34\x1a\xfa\x52\xef\xc9\xd8\xb8\xc7\x74\xb4\x4d\x59\x90\x12\x62\xea\x50\x28\x57\x02\xec\x55\x53\xda\x5e\xc2\xd2\x90\xa6\x7e\xcc\x8e\x81\xf7\xf7\x76\x3d\x9c\x69\x3f\x32\x25\x5d\x5d\x98\x18\xfe\x8f\xf6\x08\xa3\xa5\xe1\xb8\x87\x51\x61\x88\x73\xae\x52\x82\x87\x7f\x1e\x8b\xb2\xde\x42\x3e\x64\xb5\xb6\x5d\x80\x2b\x46\x70\x8a\xd2\x44\x16\xb3\x16\x4e\xc2\xb9\x02\x82\x8a\x68\xf2\xe9\xf9\x59\x34\xef\x9b\x96\x96\xe1\x0f\x41\x94\x10\xea\xb0\xd9\xab\x07\x2e\x37\xc3\x21\x36\x35\x7b\xb3\xa4\xbb\xc9\xcf\xec\xbc\x7a\x13\x91\x08\x14\x65\x8a\x66\xc4\x44\xab\x96\xfb\xf3\xe7\xa8\xaa\xc8\x45\x88\xc4\xd1\x5d\x15\x45\x5e\x92\xa8\xec\xf4\xb7\x12\xa9\xc1\x11\x35\xbb\xe3\xc1\x02\xf7\x75\x69\x93\x2b\xf0\x8c\x3d\x59\x8b\xd7\xe4\x4a\x0a\x2f\x30\x76\x63\x13\x8c\xd6\xe1\xe9\xc8\x52\x62\x2b\x7c\xbb\x7b\xba\x9f\x3f\xdf\xde\x2e\x9f\x36\x77\xff\x6a\x87\x34\x6a\x4d\x4c\x8c\x79\x51\xbc\x35\xaf\x2f\x3b\xe0\x73\x9d\x8d\x64\xdc\x18\xd7\x41\x44\x50\x45\x32\x21\x87\xfd\xae\xec\xd1\xfe\x19\xd7\xa1\xa6\x79\xe1\x94\x5b\xf3\xd2\xf5\xbe\x18\xc0\xb1\xb9\xd6\xc6\xb7\xdb\x5e\xb5\xe9\x22\xd5\x00\x72\x0d\x3e\x7a\x14\x8b\x58\xcf\x29\x79\xde\x16\x66\x72\xea\x69\xba\xda\xa6\x01\x4b\x95\x73\xb2\x43\x38\x4c\xf0\x03\x20\xe0\x40\x02\x30\x96\x1c\x63\x94\xb4\xde\x2f\xd6\x05\x88\x83\xd8\x51\x94\xef\xc1\xba\x8e\xb4\x95\x7c\x88\x03\xe6\x00\xf4\x66\xbe\x9f\x46\x54\x41\xcc\x13\xca\x1c\x1b\xff\xf5\xa2\x65\xbc\x4e\x8e\x16\x88\xb9\x51\x19\x6d\x42\x07\xb2\x43\xec\x0b\xa5\x5f\xc8\x3c\x33\x48\x52\x8f\x22\x5f\xa7\x51\xd4\xbc\x3c\x97\xe5\x83\x44\x04\xce\x5e\xfa\x17\x66\x4f\x90\x55\xcd\xd2\x6c\x8b\x22\xc3\x81\x00\x09\x9a\x12\x93\x41\x27\xbb\x2b\xa4\x81\xa6\x4c\x9b\x2c\x8b\x0f\x35\x08\x2d\x20\x55\x29\xda\x44\xf7\xec\xa5\xcc\x16\xaf\x90\xe5\x54\x9b\x1f\x3e\x7e\x8a\x7e\xeb\xb2\x42\xcb\xaf\x2a\x6e\x70\x59\xc9\x13\xee\x61\xf4\x2c\x29\x6a\x6d\xd3\x18\x8f\xa5\x99\x92\x6d\xce\xab\xa5\x6b\xb5\x3f\xae\x13\xda\x47\x1a\xda\xed\x2d\x54\xf5\xed\x3e\x1b\x8b\x24\xb8\xed\x1a\xb0\x24\xa6\xfa\xff\x06\xad\xb2\x63\x35\x32\x73\xee\x5e\x03\x93\x31\x25\x9a\x7e\x9d\xdf\xb1\xcc\x6f\x66\x8f\x7d\x74\x03\xf0\x98\x51\x9e\xea\x08\xe7\xb2\xd8\xef\x37\x3d\xb1\x73\x06\x3c\x49\x23\x35\xe2\xf9\x7f\x39\x35\x02\x57\x48\x32\xef\x96\x94\x93\xab\xfa\x02\xb2\x06\x5c\x87\xbe\x6c\x77\xe3\xfd\xb0\x1f\x40\xb7\x20\xa4\xe7\x66\x99\x31\xd8\xa2\x2c\x7f\x99\x12\xa9\x62\x20\x42\x25\x3a\x7b\xfc\x1b\xc3\xef\xf9\x86\xb9\x47\x9b\xc0\x9b\x9e\x79\xeb\x97\x73\x06\x88\x38\x91\x96\x59\xb1\x33\xd2\x10\x3b\x79\xc9\x7f\x03\xa1\x03\x9a\xdd\xe7\xb3\xc5\xe8\x88\x14\x29\x05\xcf\xdb\xc7\xed\xec\x7e\xb7\x78\x5c\xad\x9e\x1f\xee\xb6\x7f\xed\x66\xf7\xf7\x8f\x0b\x62\xf0\xb9\x27\x94\x5a\x8a\x2e\xed\x77\x9f\xe5\x1d\xa1\x71\x7a\x1e\x05\xe5\x1b\x38\xbe\x4b\x8a\x0c\xd0\x94\x63\x5c\xdc\x64\x58\x01\x2a\x49\x7d\x2b\xe4\x78\xb2\x49\x5a\xf5\xc7\xc4\xfe\x17\x10\x39\xe1\xb1\x3e\xda\x7d\x01\x68\x3f\x24\x8a\xbf\xe9\x97\xdf\x4e\xcd\x8d\x76\xfb\x4b\xd0\x91\x51\x56\x76\x77\x77\xdf\xfc\x37\x6f\x95\x42\x19\x68\x69\xc4\xaf\x29\x9c\x28\x29\xf6\x5e\x17\xc5\x9e\xa8\xa5\xbb\xac\xea\xbc\xe1\xed\x09\xc2\xf3\x53\x93\xa2\x84\x12\x5e\xeb\x5e\xc0\x26\xbc\x14\x4d\xd0\x48\xc6\xc8\x9f\xb6\x24\x68\x8a\x84\x55\xdb\x48\x31\x92\x79\xe9\x29\x54\x7f\x7b\xd8\x7c\xdd\x6d\x85\x0f\x26\xe6\xf9\x86\xf5\x1c\xab\xda\xa4\x86\xdc\x67\xe9\x6d\xa7\x45\x20\x8d\x02\x91\x09\x40\x8c\x3a\xce\xa5\x4e\x34\x13\x61\x1c\x5a\xa0\xe8\x61\x4d\xda\xca\xdd\xf3\x45\xa1\x36\x84\x4c\x33\x43\xdf\x17\xf2\xad\x97\x4f\x12\x51\xaa\x28\x2f\xba\xd9\x3c\x6e\xbf\x2f\x67\xf7\xdb\xef\xbb\xdb\xe7\x87\x9b\xcd\x6e\x76\x73\xf3\xb4\xdc\x6c\xda\x76\x5c\x18\xad\x6c\xfa\x9c\x3f\x70\x5a\x90\x92\x89\xd8\x07\x4b\x93\x43\xf9\x46\xb1\x5c\x5b\x68\x9a\x22\x78\x89\x58\x86\xb4\x08\xd4\xc6\xef\xea\x84\xad\xf7\x28\x13\x49\xea\x91\xbf\xca\xc7\xe1\xb4\xd7\xfb\xc2\x66\x97\xc7\x06\xd6\x4c\x24\x2a\xa6\x3d\xda\xb1\xa8\x3b\x21\x14\x26\x58\x0c\x60\xb4\x1c\x3e\x2d\x09\xaf\x3d\x22\x63\xca\xc6\x3a\x1a\xa6\x2b\x61\xa3\xb2\xd6\x6b\xed\xe7\xe5\x7e\xe0\xf9\x9d\x84\x89\xdd\x95\x19\x73\xae\xec\x80\x5f\xaa\x85\x0c\x5f\x0c\xf8\x8e\xff\xd3\x31\x11\x7a\xbd\x71\xd4\x38\x8d\x62\xd9\x69\xd2\xd1\x3a\x4c\xf2\x11\xee\xbe\x00\x79\x18\x39\xad\x23\xea\x97\x77\x63\x37\x31\x26\x04\x44\xd4\xcd\xbe\xcf\x9e\x6e\x76\x8b\xd9\x7a\xe7\x80\xdb\x42\x25\xc6\x6a\xd9\x26\x9e\xfa\x8b\xee\xe8\xb6\x31\x65\x2c\x75\x4b\xca\x0b\xe4\x59\x65\xb3\xdc\x93\x53\xa4\x40\xe6\xd1\xb6\x7c\xe7\xaa\x08\x2f\x59\x91\x0f\x7a\xec\xff\xf8\xc9\xff\x5e\x79\x45\xc8\x23\xa6\xdc\xae\xd9\xbc\x23\x8a\xf1\x27\xad\x26\xdc\x39\x98\x52\xf5\xf6\x1e\xdf\x71\xff\xab\xdb\x1a\xde\x35\x6b\xf0\xdf\xad\x92\x4e\x8e\x52\xe9\x47\x40\x4c\xec\x59\x46\x4a\x4b\x0b\x6c\xee\xc3\x85\xc7\xd2\xe7\xc6\xc4\x20\xab\x8c\x8d\x64\x33\xcb\x5c\x72\x4c\x6c\xe3\xd0\x4f\x08\xdb\x4c\xa3\xc2\x81\x92\x6d\xf9\xe2\xcb\xb5\x42\x46\x5c\x12\x0c\xcc\x96\xe2\x48\xa5\x7c\x9a\x11\xeb\x4e\x90\x40\x9e\x98\x75\x6f\x0b\x8d\xa5\x8b\x68\x64\x84\xc2\x18\xd3\xd2\x38\x6e\xd3\x0c\x93\x2f\x57\xc6\xbe\xa6\xd8\x78\xff\xfa\xf6\xef\xed\xc3\xdc\x5d\x23\x89\x12\x12\x1e\x7f\x82\x63\xa6\xac\xe9\xc6\xf0\xc4\x24\x4a\x34\x7d\x95\x4c\xa3\x01\xae\xed\xb2\xf6\x6c\xe1\x53\xa5\xa1\x3a\x89\x61\xc7\x1b\x3e\x78\xa2\x23\xc2\xbf\x90\xcc\xab\x9a\x9f\x37\xb5\x95\x4e\x9a\x17\xe0\x6c\xa8\x98\x64\x51\x60\x94\x7f\x95\xb2\x1e\x32\x17\x9c\xa0\x6e\xcf\x6c\xcf\xe1\x81\xa0\x29\x47\x15\x03\xf0\xf2\x60\x43\x1d\x8d\x2c\x22\x98\x14\x12\x43\x1b\xad\x9a\xea\xf1\x74\x16\x43\x2a\xd0\x98\x74\x13\xda\x57\x48\x28\xa9\x74\xea\x60\x85\x4f\xa8\xf5\x4c\x0d\xa9\xf2\x12\xd3\xd4\x70\x43\x4b\xb8\xde\x51\xfe\xf6\xbf\xdd\xbe\x4b\x22\xf7\xa8\xde\xd5\xda\x86\x5f\xb5\x04\x61\x52\xc7\x52\xdb\x94\xee\x4c\x19\xc3\xfc\xe1\xc7\xd6\xda\xa8\xd1\xe4\x45\xdd\xa7\x36\x2a\x2f\x49\x69\x73\xf7\x81\x59\xb5\x29\x74\x27\x63\xc8\x94\x1f\x18\x95\x80\x26\xa6\x2d\x72\xa8\x8b\xb2\x87\x3f\xbe\x30\xa7\x73\x27\xc5\x31\x74\x8b\xe1\xee\xd8\xc3\xa8\xdb\x16\xa1\x9f\x52\xfd\x84\xb8\x24\xdf\xfa\x55\xb4\xdf\x5b\x02\x0e\x3c\x4f\xdd\xf5\x82\x08\x3b\xce\x37\xe9\x17\xf6\x4d\xcb\xda\x56\x80\x36\x8b\x6f\xbd\x19\x54\xb3\xcf\xb8\xbb\x99\xce\xf3\xa9\x50\x8b\x54\x58\x49\x43\x37\x63\xb8\x27\x88\xc1\xf3\xa3\x56\x5a\x73\xd0\xc5\xd8\xff\xc4\xff\x3b\xba\x52\x2c\x05\x0d\x25\x07\xf4\x9e\x37\xcf\xdd\x43\x8b\x4f\xcf\x29\x2a\x89\x62\xc7\x75\x26\xc5\x52\x10\x7b\xbc\x53\x64\x20\x33\x00\x3c\xff\x63\xb2\x76\x31\x08\xe1\x54\x02\x29\x41\x05\x9a\xc0\xfb\x51\x97\x54\xeb\xb2\xfe\xdf\xc3\xb7\x94\xa6\x21\xc9\x2b\x2f\x8a\x2c\xa7\x5d\x63\xfb\xcc\x29\x46\x24\x93\x44\x76\xb7\xbd\x87\x9e\xfe\x66\x23\xe4\xd4\xe0\x66\x52\xcd\x68\x53\x93\xb7\x7c\xe5\xe9\x17\xc0\x42\xcf\x01\x21\x77\x27\x42\xd7\xec\xea\x2e\x26\x52\x2c\x56\xc4\x5b\x22\xef\x05\xfc\xec\x7d\xfd\xfe\xb6\x6f\x38\xef\x2a\xc6\xa4\xb5\xbe\x20\x66\xe2\x13\xaa\xac\xc4\xcb\x65\x75\x7c\x27\x3c\xe5\x81\xa3\xf5\xd5\xb3\xda\xb2\x0a\xa6\x13\x18\x83\x67\xe5\x89\x59\x7f\xcc\xdd\xdd\x14\x27\xb1\x1f\x0d\x4c\x05\x11\xf3\x44\x8b\x9d\x79\x79\x35\x10\x15\xf7\x94\x10\x23\xc1\x81\x5e\x4e\x3d\x5a\xab\x9b\xee\x14\x60\x42\xc1\x2f\xe5\x04\x2f\x01\xe8\x6c\x9c\x7f\xb4\xa7\x09\x9e\x18\xac\x82\x5b\x89\xe9\x27\x7b\xf5\x04\x25\x64\x42\x09\x13\x5d\x94\xf5\x29\xc7\x9d\xc8\x46\x99\x54\x25\x43\x4e\xb2\x45\xa7\x5c\xda\xbd\xc3\xf0\xb1\x24\x8f\x03\x4a\x50\x74\x62\x26\xd3\x2f\x57\x45\x46\xc9\xef\x00\x9f\x0f\xa7\x03\xe9\xd9\x60\xd5\xc6\x76\x4a\x7b\x8a\x58\x18\x3b\x33\xa1\xb4\xa2\xce\x14\xae\x2c\x2d\xdf\xbf\x0f\x02\x1c\x5e\x5d\x47\x8a\x74\x4c\x46\xc9\x41\x5b\x1e\xef\x2b\x1a\xb8\x13\x62\x09\x6e\x6b\xb2\xca\xf2\x27\x22\xa1\x78\x4d\x34\x50\x9c\x6a\xf3\xff\xec\xad\xa1\x17\x1a\x5b\x08\xa3\x2d\xb0\x3c\x95\x97\xca\x02\xe8\xfb\x86\xef\xbc\xbe\xfd\x76\x65\xc8\x74\x13\x3e\xfa\x81\xa6\xf2\x8e\xbd\xa3\x66\xe1\x6b\x7e\x78\x60\x1a\xd5\x2e\x98\xe1\xff\xba\xb3\xe2\x84\x83\xc9\x4b\xbd\x75\x7b\x2c\xf4\x9b\xc8\xd2\x42\x99\xe9\x15\xb5\x07\xac\xe7\xd2\x2f\x24\x3c\x08\x65\x34\xfa\x39\x70\x0c\xbc\x94\x60\x6f\xad\x8b\x3a\xc3\x90\x03\x2d\x45\x54\x4f\x6e\x42\xa9\xde\x0f\x45\x71\x48\x33\x2b\xb1\x31\x9b\x99\x57\xb5\x47\x52\x4d\x2b\xa7\x91\xb0\x1a\x14\x17\x5d\x0b\xa1\xb8\x33\xdb\xde\x60\x3d\xcf\x6a\x92\xb8\x6d\x13\xc5\x18\x83\x97\xda\x49\x60\xf9\x29\xf7\x27\x75\xc9\x05\x77\x2d\x31\x20\x0d\x07\x71\x3a\xcf\x72\xd8\x9f\xab\x6c\x34\xb9\x61\x92\x46\x94\x31\x7c\x2a\x8a\x83\xa1\x5a\x34\x11\xd5\x08\xab\x7c\xba\xc4\xe4\x61\x1a\xa7\xb4\xa6\x99\xfd\xc5\xee\x48\x3a\xa9\xbb\x66\x9a\xd9\xd5\x53\x5a\x29\xee\xb4\x24\xf2\xc2\x9e\xf6\xdf\x2d\x62\xb5\x30\x11\x22\xaa\x3e\xae\x04\x53\xa1\x28\xff\x64\x9d\xf4\x67\xc7\x6c\x74\xeb\x29\x86\xc6\x56\xb6\x82\x77\x34\xeb\x97\x9c\x84\xf2\x0e\xf2\xc6\x28\x62\x4e\xf9\x6e\xca\xc4\x7f\xdb\x83\x81\xff\x50\x69\xca\xf1\x1b\xdc\x8a\x3a\xfc\x3d\xa1\x22\x72\x18\x13\x59\x71\xdf\x15\xfd\x51\xb2\x88\xaa\xb4\x4f\x98\x37\x57\x2c\xba\x14\x1a\x4a\x6e\x1e\x01\x9b\xe0\x62\x8d\x79\xb3\xc2\x3d\x57\x66\xef\xdf\xb6\x81\x84\x12\x41\xf9\xe9\x40\x5b\xfd\x57\x92\x55\xac\xba\xc3\xc2\x90\x86\xf2\x37\xf9\xa1\xaa\x81\x31\x11\x43\xf4\x43\xea\x09\x04\x13\x5d\x98\x1c\xeb\x00\x3d\x85\x3a\xe5\x74\x77\xff\x85\xff\x0e\xf2\xaa\xa8\x59\x92\xf8\x5d\x25\xad\xcf\x9b\x1b\x4c\x8c\xa8\xc1\xa4\x19\x6f\xa0\xf0\xb9\xe7\xb7\xe7\x0b\x23\x48\x8b\x9f\xce\x62\x73\xe8\xbd\xde\x17\x59\xd1\x5e\x24\x68\x4e\x2e\x8e\x98\xcf\xb2\xf2\xa6\x74\xee\x37\x4c\x7b\x89\x08\x78\x8b\xc9\x33\x64\xc4\xfe\xef\x6b\x4f\x48\x42\x02\x42\x5d\x1c\x32\xd9\xec\x92\x27\x00\xfe\xbd\xff\xd5\xdb\xa3\x6b\x3f\x36\x43\xf4\x66\xd5\x1b\xd1\x13\x02\x6e\xc3\x4e\xaa\xfd\x24\xa0\xad\x99\x2b\xbc\x2f\x8a\x62\xaf\x8a\x0f\xf7\xda\xb5\x9f\x70\xf4\xad\x59\x54\xc7\xdf\xd0\x41\xc2\xa9\xa4\x44\xe6\x60\xcb\xed\xf7\xdd\xf6\xcf\x1f\xed\x31\x10\xb4\x21\x59\xd8\x2c\xf6\x54\x56\x49\x07\x92\x25\xd0\xae\x8c\x4d\x4f\x59\x63\xd9\x8b\x6a\x5a\x36\x5e\x6f\xba\xd0\x81\x4a\x88\x09\x4d\x3a\x58\xab\xbb\x87\xbb\xd5\xec\xde\xf8\xe2\xb8\xdf\x0e\x7d\x4e\xb5\xc5\xe3\x1e\x24\xce\x5b\x26\xc2\xa4\x71\x6d\xbf\x18\x77\xa5\xf8\xa6\x43\xce\x49\x46\x6c\x8e\xcd\xfc\x64\x6c\x08\x87\x53\xbc\x8e\x01\x2c\x50\xa0\xee\xf5\xea\x9b\xf9\x70\x08\xeb\x58\x1a\x8a\x8e\x51\x8a\x58\x83\x13\x73\x64\x3a\x56\x7e\x6a\xa5\xb5\xa9\x68\x65\x62\xcd\xe1\xd9\x49\xac\x69\xee\x32\x89\xba\xcd\x6b\xf1\x91\xdf\x60\x5e\x1c\x1c\x8a\x6a\xf8\xba\xfa\xef\x2c\x49\xc3\x41\xea\x5c\x51\x8c\xa4\x4f\x34\x42\xdd\x2d\x24\x68\xed\xf2\x8d\x76\xb2\xeb\xf9\x3a\x45\x4d\x14\xc6\xf9\xfd\x8f\x81\x2a\x94\x3d\xcc\x18\x04\x16\xb6\x49\x7a\x01\x9b\xd3\xe1\x00\x65\xf6\x5f\xbc\x30\x48\x65\x9a\xf1\x38\x85\xdf\x43\x14\xfc\xf1\x69\xda\x30\x37\x9c\x2d\xfb\xf4\x5c\xab\xb9\xcf\x28\x5a\x3e\x40\x96\x93\xe0\x7a\x95\xbd\xf4\x39\x42\x9a\x2b\xa0\xb4\x70\x67\x93\x32\xa1\x15\xca\x34\x30\x3f\xec\x8a\x89\xee\x73\x18\x49\xa1\xe1\xb3\x03\x40\xa2\x7b\xb3\xfb\xa6\x19\x20\xbd\x49\x5d\x83\x8a\xbd\xc8\xda\xc9\x2c\x3f\xeb\x12\x06\xb3\x95\x06\x94\x14\x19\xd8\x3c\x3a\xaa\xd5\x5f\xe3\x2e\x23\x98\x4f\x19\xe4\x6c\x51\x8c\xcd\x5f\x98\x16\x02\x84\x0b\xb0\x9c\xc4\x3c\x6d\x0c\xb6\x85\xfb\xbf\x4f\x28\xb3\x63\x86\x03\x8a\xf9\x3f\x46\x31\xa4\x16\xca\xa3\xa0\x63\xbb\xde\x6e\x2c\x5d\xb8\xbd\x47\x29\x12\x2a\xad\xbb\xad\xcb\xa2\xc7\x3e\x1d\xbd\x38\xe5\x45\xc4\x90\x72\xb2\x94\x45\xb9\x20\x73\x4a\x0b\x08\xb9\x24\xd1\x5f\xb9\x4c\x60\x64\xe6\x77\x44\xe8\xb9\x1f\xe8\x66\x0f\xd7\x28\x8d\x91\x51\x81\x35\x54\x78\xd5\xf7\x45\x61\x5a\x33\x49\x3c\xf9\xd1\x12\xa4\xb5\x36\x45\x3c\xb1\x07\xf9\xb6\x82\xca\x2e\x6d\xdc\xf3\x98\xa6\x8a\x34\x39\x01\xec\x5b\x6a\xc9\x30\x8c\xee\xdf\x00\xf7\x3c\x08\xc1\xe8\x2b\x6d\x68\x66\x1b\xf4\x5c\xee\xf9\x96\x11\xd6\x6a\xdb\xda\xbf\x07\x71\x20\x6d\x94\xb7\xa9\x5e\x7f\xe0\xb9\x9f\x4e\x68\x0e\x1b\x80\xa5\x79\x03\x6f\x98\x5b\x14\xd4\xef\x62\x5d\xee\x05\x10\x11\x42\x6b\xf6\xbc\xfa\xb3\xb7\x74\x72\x2f\xf4\x42\x6e\xc5\x86\x88\xc0\x3c\x5d\x9d\xe5\x5e\x18\x68\xdf\xe0\x90\xf2\x66\xb6\x7b\x72\xfc\xdf\x61\xab\x28\x64\x24\x8f\x87\x9f\x97\x49\x6e\xee\x45\xd2\xf7\x22\x47\xab\x30\x10\x7a\x5a\x74\x7b\x84\xfd\xb6\x25\x37\x52\x37\x7d\xff\x4d\xee\x45\xa8\xa9\xa2\x3d\x47\xb0\xba\xb9\x16\x26\x12\x1a\xe9\x15\xd5\x36\xd4\x31\xf1\x76\x50\x16\xf9\x4f\x02\x94\xbe\xf4\xa4\x99\xb8\x17\xb3\x34\x05\x17\x97\x3e\x7e\x10\x02\xb7\x89\xac\x86\x2f\x2d\xf1\x43\xd3\x6f\x9b\x88\xa2\x13\xb1\xba\xbe\x26\x70\x2f\x49\x52\x87\x38\xff\x9e\x55\x7d\xbe\xe7\xe8\x83\x24\xe0\x87\x6d\x9a\x7d\xf1\x0a\xe5\xd8\x5a\x8e\x7b\xa9\x97\x12\x4c\x72\x75\x76\x42\xa9\xd5\x6f\x29\x64\xdc\x4b\xfd\xc8\x37\x84\xd6\x62\xbf\xe8\x02\x34\xee\xa5\xc2\xe0\x7b\x5b\xf6\xc2\x78\xd4\x0d\x3f\x16\xf3\x7d\x0a\xbf\x7f\x5d\x05\xad\x73\x8f\x25\x92\x8c\x0a\xe1\x8f\x89\xe5\x85\x7b\x4c\x71\xd2\xf2\x5b\x7e\x5e\xcf\x13\x72\x8f\x21\x78\x5e\xab\x09\x3d\xd4\x7e\x9b\x7e\xc9\x5c\xc7\x16\xd4\x42\x2e\xfb\xd8\x0a\x76\xb7\xdb\xef\x6a\x52\x9d\xdc\x9e\x0e\x3c\x4a\x44\xab\x30\xf9\x6f\x94\xf5\x92\xfc\x57\x71\xf4\xfe\x85\xcf\x68\x68\xcc\x4a\x78\xb1\x2a\x67\x1b\xb8\x14\xed\xf9\x5b\x86\x89\x6c\xf4\x08\xd2\xf7\x95\x9d\xa0\x64\x71\x2a\x2b\xac\xee\x31\x7f\x79\xad\xdd\xc7\x92\xb1\xa2\xc2\xda\xb1\xe9\xdd\x51\x9b\x78\xe3\x9e\xd4\x9e\xf2\x7b\xca\xe2\xc3\x7e\xaf\x3c\x41\xa8\x8d\xcd\x76\xf6\xd4\xe5\x3b\xdc\xc1\x20\x14\x76\xbf\xd4\x2c\x06\x26\x7b\x7d\x45\xfa\x91\x7b\x2a\x4c\x29\xcc\xdf\x17\xf2\xcd\x62\x86\xaa\xf6\x4a\x2c\x1c\xda\x05\x6f\xbf\x8f\x7a\x06\xfa\x8a\x00\x65\xd5\x6b\xf1\xd1\x74\xc2\x87\xd3\x45\x25\xd8\xb5\x4c\x25\x6d\x5f\x9a\x98\x78\xf4\x01\x50\x84\x9a\xf5\x4d\x56\x37\xa7\xc3\xb6\x78\xea\x4b\xe2\xda\x96\x3a\x30\x79\xee\x76\x62\x9c\x4a\x87\x73\x4f\x47\x3e\x85\x2c\x3f\xb3\xf7\x4c\x99\x75\x73\xeb\xe0\xeb\xcd\xd1\x98\xb6\xa4\x96\xd3\x8f\x65\x55\xe4\xb0\xbf\x31\x6b\xb0\xbd\xe0\x6d\x31\x9e\xd4\x34\xc4\x8e\x5e\x6d\x39\xfa\xa8\xe7\xe7\x91\x0c\x36\xf7\xbd\xc0\x37\x8c\x1c\x1a\xef\x17\xc4\x77\xee\xfb\x3e\x23\xc3\xe0\xfb\xbb\x87\x9b\x3e\x22\x92\xfb\x7e\x9c\xd2\x62\xf1\x0a\xd5\x5d\x3d\x47\xcc\x2d\xb5\x63\xfc\x13\x01\x17\xa4\x33\xf4\xa5\x91\x5c\x7f\x24\xf8\x81\x64\xc2\x7a\xca\x96\xcd\xce\x8c\x02\xbc\x66\x20\xf5\xf2\x4c\xdc\x0f\x03\x45\xda\x0e\xa7\xea\x8a\xa6\x4b\xd3\x44\xd3\x54\xb5\x99\xdd\x2f\x83\xdd\xf2\xe1\xa6\x3d\x17\x12\xa2\x1e\x80\x52\xdf\x4e\x4d\x84\x30\x3a\x4f\x19\xfd\x7e\x68\x82\xa9\x8d\x35\xa5\x9c\x9e\x31\xfd\x48\x09\xaa\x14\xd4\xce\xa7\xee\xc2\x66\x93\xfb\x91\x8e\x9c\x48\x84\x33\x4a\x0a\x52\x77\x2f\x89\x2f\x48\xde\x80\x62\x69\xba\x8b\x6d\x41\x26\xce\xc6\xa6\x6f\x7a\x7a\xf2\x53\xad\xa8\x8c\x41\xd6\xc6\xc4\x7b\x30\x92\xf6\x1d\xf0\x8f\xfb\x5c\x79\x94\x66\xf9\xeb\xca\xad\x73\xad\x8d\x46\x20\x56\xf5\xce\x68\x71\xec\x74\x96\xab\x87\xe2\x7b\x96\xd7\xb3\xba\xe5\xb4\x0f\xce\x82\xd0\xf0\xc9\x08\x8d\xdf\x4b\x4f\x0d\xd7\x4a\x1f\xac\xcd\x9b\x38\x9d\xfb\x80\x0b\x77\x34\x66\x51\xe0\x56\x3a\x8a\x7a\x0d\x08\xc6\xdd\x3a\x60\x2a\x9d\x34\x1b\xe4\xea\x4c\x88\xdb\xcb\x78\x9e\xfb\x22\x95\x54\xc9\x6e\x37\x83\xab\xc7\x71\x0b\x48\x49\x27\xad\x04\x07\x6c\xe2\xbe\xd0\x1e\x19\xcd\x51\xd5\x7a\x5a\x69\x65\xd0\x23\x85\x96\xa4\x37\xf7\x52\x14\x56\x24\xda\x1f\xbf\x4c\x99\xc4\x24\xbf\x7d\xc8\x72\x9a\xc7\x46\x77\x21\x53\x9f\xc8\xe9\x68\xf8\xd3\x81\xbb\x13\xa9\x4c\xd1\xa8\x59\x47\x8b\xa2\xec\x66\xc7\x2b\xcb\xe0\x97\x3a\xb5\xdc\x57\xb1\x71\x06\xd9\xc1\xf1\xb8\x77\x2a\xfa\xa3\x26\x3c\x0c\xa1\xd3\x53\xea\x2a\xae\x13\x7a\x3f\xdc\x57\x18\x51\x4e\x0e\xda\x1a\xd2\x70\xc9\xf0\x91\x73\xca\x54\x7c\xe0\x8e\xfa\x51\xdd\x9f\x23\x50\x19\xf6\xd1\xf6\xfb\xdd\xd3\xcd\x6e\x7b\xb7\x7c\x22\x53\xbf\x9d\xb1\x87\xdd\xde\xad\x96\x5d\x4b\x4d\x59\x4f\x85\xef\x16\x11\xea\x8e\xe8\x20\xa0\x18\xb1\x89\x8b\x77\x7e\xfb\xd7\x30\xa2\xb2\x59\x3e\x96\x07\xe3\xbe\x16\x8c\xf0\x4f\xff\x3e\x1d\x8e\x77\xee\x56\x02\x2f\x36\x80\xc4\x16\x85\xda\xfc\x49\x11\xac\x69\xfb\xfc\xb0\xfc\x97\xfb\xa3\x1f\xa4\x0c\xac\x70\x43\x4b\xe6\xe3\x81\x1f\x23\x19\x77\x62\xfd\xba\xca\xf2\xb6\xa3\x06\x3e\x0f\xa5\x24\x72\x51\xf9\x86\x35\xed\xe1\xcd\xb8\x1d\xcf\xc8\x81\x0f\x9a\x5b\x91\xb9\xc7\x53\x3d\x27\x7c\xce\xf4\xe2\x13\x34\x53\x66\xd8\x09\x4a\x36\x21\xde\x24\x86\x8d\x07\x01\x1a\x81\x84\x0a\xf7\xfb\x35\x34\x9d\xb9\x0f\xf7\xe8\x44\x0b\x86\x67\x85\x51\x4c\x9b\x24\xdc\xc3\xb1\x42\x65\xa0\xea\x6e\x62\x0d\x42\x9e\xb6\xf9\x64\xa2\xc9\xf4\x77\x81\x3c\x88\x22\x19\xdb\x18\xe1\x4e\x16\x13\xfa\x3e\x3c\x88\x62\x8f\x16\x4f\xd9\xc5\xb6\x41\x0c\x8a\xb4\xaf\x9d\x27\xcf\xe7\xae\x36\xa8\xb5\xe1\xad\xc5\xc2\x68\x60\xf5\x75\xa0\xe7\xe7\x71\x23\x14\xe4\x26\xa2\xf7\xa7\xcf\xdb\x9e\x26\x58\x2f\xca\x0b\x12\xc6\xbd\xce\x24\xa6\x09\x4a\x42\x77\x2b\x09\x0f\x09\xec\x93\xe3\xc7\xec\x80\xb9\xa2\x22\xe5\x17\x4e\x31\x3c\x48\xa4\xa4\xd2\xda\x4e\x42\x3e\xb1\xcd\x18\xbd\xde\x34\x32\x1a\x59\x3b\x28\x91\xb4\xde\x67\xb9\x6a\x8b\xf3\x96\xc0\xe6\x9a\x0a\x49\x05\xcb\x9d\x4d\xf4\x7d\x05\x6a\xe1\x41\x2a\x0d\x74\xb6\x2e\x4f\xcd\x8c\xbb\xe9\xe9\x7a\xf2\x20\xc5\x88\x88\xac\xc6\x02\x7f\xf3\x7d\xf6\xb4\xdc\x3d\xde\xee\x2c\x2c\x7c\xd3\x36\xd3\x8c\xe2\xda\x2d\xe4\x2f\x45\x5f\x11\x83\x07\x8c\xc5\x56\x80\xa3\xbe\x59\xfe\x1c\xbd\x73\xae\x94\x79\x9f\x45\xae\xb3\xf2\x40\x68\x3d\x6b\xe3\x40\x9f\xe8\xa6\x68\x76\xd0\xed\xde\xb9\xf7\x25\x00\x78\x6a\x2a\xee\x8f\x47\xec\x0d\x1d\x50\x21\x45\xfe\xe5\xa4\x99\xc0\xf4\x87\x10\xa1\xe1\xdc\xdd\xac\xee\x1e\xb6\xee\x42\x42\x33\xda\x5b\x64\x15\xd5\x62\x0e\xa8\x32\x28\xc7\x7d\x46\xaa\x84\xb2\x32\x39\x7e\x5a\xee\x44\x13\x17\x3d\x14\xee\x22\x8a\x9b\xb2\x15\xcd\x4f\xf4\x0e\xdb\x57\xa6\x34\x52\x18\x77\x80\x4f\xfa\x9c\xdf\xfb\x49\x60\x1e\xe8\xd4\x78\x5e\xbf\x60\xfd\x8e\xaf\x25\xfe\x47\x59\x02\xef\x64\x04\x1b\x7a\x89\xa6\xf2\xb5\x03\x09\x2d\x8a\xc3\x21\xab\xeb\x96\x08\xcd\x43\x2f\x35\x96\xc2\x65\x51\x43\x8d\xf3\xac\xb6\x46\xe1\x7d\xc8\x37\x0f\x3d\xf0\x28\xda\x15\xe5\x69\xac\x58\xd9\x1c\x4c\x91\xbb\x08\x66\x55\xa8\x1e\x3a\x9a\x87\x4d\x18\x0f\x5d\x1e\x67\x03\xef\x59\xfe\x52\x4d\xe1\xb8\x79\xe8\x69\x15\x40\xcf\xe1\x62\xf4\x3b\xbe\x17\x82\xc5\x49\xcc\xb4\xce\xf6\x19\xd4\x78\x3d\x75\xc3\x43\x9f\x01\xd1\xac\x0e\xf0\x86\x4e\x23\xbf\xbf\xd2\x86\xbe\x88\xe3\x56\xca\xa4\x4f\xc8\xe4\xa1\x8f\x3e\xd7\xad\x01\x55\x6d\xd5\x03\x06\x73\x7f\x18\x30\x45\xa8\x3b\xb7\x05\xb8\x46\x66\x73\xcd\x41\x13\xc1\xe9\x58\x16\x9f\xd9\xe5\xc5\x24\x97\x76\xa6\x6b\xe6\x0f\x37\x05\x0f\x43\xef\x3f\x46\x57\x94\x9a\x59\x42\xee\xd8\xbb\x85\x87\x61\x6c\xe0\x09\xef\x84\xb9\xea\x2c\x59\x79\x18\x32\xa3\xb0\x42\x1b\x05\x0a\xaa\x28\x05\x34\x65\xd3\xc3\xc3\x90\xfb\x24\x8f\x69\xa6\xb6\x07\xfc\x98\x54\xa6\x1c\xfc\x72\x94\x72\x8a\xf3\x09\xeb\xec\xe6\xa2\xbd\xfb\xf5\x98\x61\x80\x0e\xb6\x45\xa9\x8d\x2e\x01\xc5\xc3\x18\x3c\xe5\xb5\xc2\xcf\x64\x5e\xb4\x2d\xe6\xa7\x2a\xcb\x7b\x05\xde\xb1\x72\xce\x6f\x78\x11\xc3\x5e\x14\x43\x40\x77\xf7\x58\x66\x2f\x59\x5e\x6d\x9b\x50\xad\x57\x12\x18\x3e\x7d\xe2\x2b\xb2\x5d\xbf\x0b\x06\xb3\x57\x98\xf8\x9a\x32\xed\xb7\x88\x0b\xc7\x4a\xfb\xed\xb4\x32\xba\x91\x24\xe2\x34\x94\x9b\x20\xce\x4c\x12\x8b\xe2\xba\xe7\xea\xef\x2e\x26\x7d\x2a\x0e\xfd\x59\xec\x0b\x7a\x1a\x77\xa7\x8c\x4b\x90\xad\xf8\xfc\x19\xcb\xdb\xa2\x3c\xfc\x71\x59\xc6\xe3\x21\x53\xa6\x1a\x06\x46\xcb\xdf\xc9\xe6\xfc\x0d\x91\x58\x1e\x72\x96\x10\x6e\x7c\x5f\xd4\x35\x96\x67\xc3\x91\xb0\xc7\x40\x46\xba\xcb\x35\x0c\x44\x7a\x79\x28\x02\x41\x7c\xa9\xda\x58\x04\xd9\xc0\x1a\xcb\x6a\x08\x2c\x73\xad\x55\x40\xbd\x43\xd2\xcb\xea\x13\xe2\x78\x28\x35\x33\x0e\x33\x74\xe2\xb6\xd8\x20\xaa\x87\x66\xfe\xbd\xdc\x2b\x87\xca\xf3\x8d\x60\x16\xd6\x59\x89\xbf\xb2\xbd\x5a\x42\x75\x76\x3c\xf9\xdf\xff\xd3\x5e\x46\x91\x78\x3b\xcd\x1f\x13\xc9\xa1\x50\x29\x74\x02\x1b\xb3\xe3\xd1\xb1\x06\x78\x88\x41\x40\x33\x93\x38\x95\x79\x6d\x2d\xaa\xba\x63\x89\xc1\x44\xd0\x80\xfb\x99\x95\xf5\x09\xf6\x4b\x62\xec\xb5\x4d\x24\x8b\xed\x10\x1a\x8c\xf9\xc8\xf3\x0c\x33\xc7\x16\x4a\x8d\x7c\xab\x3b\xe6\x7b\x44\x31\x37\xd5\xe6\x45\xb3\xcb\x3c\x40\xab\x99\xc2\x23\x8f\x47\x44\xb1\x5f\xc5\xfd\x9e\x1e\xf9\x11\x52\x34\xb2\x81\x77\x34\x0c\xd2\x07\xac\x3f\x8a\xf2\xad\x6d\x00\x1e\xc5\xe4\x77\xea\xb3\xe3\xbb\xf3\x28\x08\x38\xad\x3c\xaf\x50\xfd\x2c\x6a\x54\x8f\xf9\x4d\x21\x4f\xcd\x1c\xbc\x2e\xec\xcc\x3e\x4a\x08\x45\x41\x18\x39\x45\xd1\x55\xcb\x46\xed\xeb\x23\xf0\x28\x88\x22\x4a\x87\xac\x7b\xa9\x9f\xf6\x58\xca\x94\x01\x12\x89\x7d\x26\x7f\xe0\xf9\xaf\xdb\xa2\xfc\x73\xf8\xe5\xa3\x80\x29\x0a\x8c\x1f\x3f\xf2\xe6\x0d\x19\x09\xfd\xf6\x0a\x4a\x7a\xc6\x77\xec\x3d\x2b\x07\xa2\xfe\x3c\x0a\xd0\x60\x82\xdb\xaa\x5d\xfb\x77\xad\x0d\x58\x34\x37\xd6\x67\x93\x53\x75\x14\xfa\x40\x61\x5a\xe7\x83\xd3\xa3\x05\x5f\xa4\xd1\xae\x19\x4b\xf1\x28\x0c\xd1\xb7\x58\x9b\xa5\x05\xf5\x8c\x9e\x30\xe4\x21\x75\x8e\x9b\xf5\xa3\x0b\x2a\xa2\x28\x14\x54\xa6\x5b\x6c\xaf\x68\x42\xb9\x76\x49\x08\xdd\x4e\xb9\x19\x5f\x2d\x8c\x98\x47\x71\x24\x98\x21\xf8\x64\xe5\x34\x70\x93\x47\xb1\x8c\x1d\x1d\xc4\x59\x5d\x8c\x5e\x44\x82\x21\x31\xd5\xbf\xfd\xf9\x73\xf1\x50\x5c\x77\x35\xe7\x51\xea\x05\xb4\xbc\xf6\x1c\x16\xfe\xd6\x66\x75\x72\x86\x8a\x52\xdf\x70\x6a\x57\x77\x0f\xbb\xa7\xe5\xed\xf3\xc3\x0d\x29\x38\xef\x6e\x96\xe4\x13\xb4\x7c\x72\x8f\xc9\x58\x40\x01\xfb\x6c\x38\x0d\x4e\xa7\x46\x22\x0e\x46\x65\xb5\x42\x4b\xcb\xe8\x55\xd5\x78\xc4\xd1\xa7\x7d\xfa\x2c\x7f\x19\x94\xeb\x9b\x23\x8a\x6a\xe6\xc5\x01\xe5\x57\xf9\xa9\x08\x98\x4f\x13\xa4\xc0\xda\x57\xb8\xaf\x61\xa4\x7f\xcd\x23\xe1\x1b\xcd\x62\x50\x6a\x83\xe5\x3b\x96\x7f\x4c\xd5\xb3\x47\xf7\x2d\x3d\x93\x43\x2d\xd1\x48\xe9\x9f\x6d\x7c\x3f\x7e\x99\xc3\x11\x2a\x7d\x9f\x78\x31\xe2\x74\x1e\xac\x55\xc3\x0f\xa7\x42\xa3\x87\x98\x55\xb3\x53\xfd\x7a\x63\xe6\xa2\xd1\x14\x1c\x29\x89\xd2\x40\x66\x3a\x54\xda\x48\x28\x82\x47\x4a\xc7\xe4\x21\x69\xd4\x9e\xc6\x9c\x8f\x2e\xca\x8c\xd0\x53\x24\x45\x61\x2a\x4d\x6b\xa8\x2a\x1b\xa5\x3a\xa3\x68\x1e\x61\x14\xa4\x76\x4b\xdc\x17\x18\xb9\xae\x4a\xc4\x23\x64\x9e\xec\x98\x39\xdb\x57\xcb\x9d\x1d\x3d\x09\x0a\xa4\x42\x9b\x99\xb0\x97\x95\x2c\x8b\xab\xa1\xe0\xe8\x2b\xe8\x18\x3c\xe3\x05\xb9\x47\x28\xa9\x4e\xfa\x50\x94\x07\x6b\xce\x5f\x4d\x03\xd4\x79\xa4\x93\x20\x4d\x6c\xe2\xa5\x2c\xde\xa9\x74\x33\xf8\x45\xeb\x96\xc2\x63\x5f\x70\x2a\x46\x11\xf8\xd6\x86\x5b\xa6\x8a\x32\x79\x43\x71\x18\x32\xda\xec\x2e\x5e\xb3\xfd\xde\xc8\x56\xfc\xe1\x0e\x81\x24\x9d\x69\x2a\x94\xd3\xfd\xb9\x09\xa8\x43\xc6\xf1\x38\x14\x40\x69\xc0\x66\xe7\xd3\x7c\x4e\x62\xe2\x6e\x0b\xe3\xaf\xe9\x1a\x45\xbe\xa0\xcc\xbe\x65\x1f\x3d\x21\x71\x4d\x9f\xb0\x2a\xf6\xad\x03\x0a\x8f\x23\x10\x94\x38\xa0\x30\x72\x47\x12\x65\x19\xaa\x1d\x3a\x36\x35\x8f\xe3\x34\x49\xf8\x05\x41\xf3\xba\xcd\xd2\x64\x77\x8d\x63\xc9\x1c\xe1\x6c\x7e\x3a\x1b\xe5\xbc\x5c\xad\x4b\x7c\xcf\x8a\x53\x65\x35\xac\x06\xe3\x20\x4e\x38\x38\xd6\xdf\x6d\x59\xe4\xf5\xd8\x87\x8a\xc7\x89\x0e\xa9\xb8\xb1\xa3\xa9\x74\x90\xd4\x88\xd3\x30\x89\x58\x5b\x44\xbf\x60\x2f\xf2\x38\x8d\x7c\x5a\xe5\x3e\x20\xa3\xe1\x60\x1c\xb6\xdc\xe9\xcc\xd3\x89\x75\xb0\xf8\x89\xb9\x2a\xca\xab\x52\x3b\x3c\x66\x51\x40\x1b\x69\x28\xc5\x5f\x97\x7e\x42\x63\x3c\xea\xb0\x2f\xf0\x48\x12\xbf\xa2\xee\x0c\x50\xee\x8b\x51\x15\x37\xe6\x0c\x35\x76\x5e\x03\x65\x9d\xf5\xf4\x98\x78\xcc\xb9\x4f\x79\xfb\x22\x5f\x3a\xb7\x4d\xc7\xa5\xea\xc6\x59\xcc\x55\x2c\x2d\x3f\x63\x61\xfd\xc3\xec\x6b\x9f\xbc\x31\x88\x24\x11\x52\x0d\xa9\xd7\xc5\x8c\x84\x1a\x31\x43\xdb\xb5\x4b\x91\x08\x7f\x24\x0e\x37\x3b\x88\x0c\xf3\xfa\x3e\x7b\x79\x6d\x56\x4e\x3c\xf6\xbd\x41\x06\xdb\xd0\x18\x94\xa2\x7c\x70\x4e\x9a\xfd\xc7\xa2\x82\xfd\x85\x98\xfa\xa0\x3a\x67\xcf\x13\x51\xea\xf5\xd3\xc3\x26\x3d\xb9\xd3\xbf\xa3\x00\xf2\x58\xc6\x2d\x50\xc4\x72\x1d\xa9\xa4\x4b\x90\xd5\xde\x7c\x18\x4b\x60\x54\x1b\x7f\x7a\x2d\x54\xe6\xf4\x5a\x78\xac\xbc\x80\x62\xb4\xa5\xd1\x47\xfb\x62\x39\x89\x55\x1a\xf0\xb4\x27\x90\xd5\x6c\x3b\x6e\x8b\xf2\xa6\x84\x8f\x8b\x12\x7d\xac\xd2\x94\x1a\x37\x71\xa2\x95\xfe\x19\x35\x90\x9a\xb2\x77\x66\xea\x6b\x23\xf2\xfe\x5b\xf5\x93\x49\x56\x7f\x12\xfd\x63\x4a\xb6\xb4\xfb\xbf\xfd\x40\x3b\x46\xdf\x08\xdc\x3e\x3f\x7c\x73\x89\x98\x18\x03\x20\xe0\xce\x6a\xb9\x9d\xfd\xd9\xc1\xda\xdd\xd1\x38\x92\x76\x90\x50\xa5\xc9\xd0\x1d\xd6\x7b\x18\x49\xe7\xf0\x18\xa5\x21\xdf\x38\xa1\x23\x23\x19\x66\x0f\x6a\xae\x28\x13\x6b\x1e\xf0\xa9\x20\xfb\x77\x93\x7e\x9d\x06\x5a\xf2\xc4\x4b\x64\x62\x92\xec\x87\x23\xec\xb7\x24\x06\x9e\xe5\xfe\x04\xd6\x6c\xe2\x5c\x1e\x91\xfc\x57\x55\x17\xf2\xad\xa3\x81\xf1\xc4\x03\xcf\xc1\xf3\x67\x25\x49\x22\x99\x61\x74\x8b\xa3\xc7\x49\xfc\x58\x12\x45\xcb\x0d\x8b\x0d\x59\x80\x7c\xdd\xff\x92\x20\x04\xb4\xdc\xeb\xf5\xfe\xf4\x92\x5d\x89\x0f\x93\x40\x78\x94\xd7\x32\xeb\xf1\x32\x57\xad\xf8\x26\x4f\xc2\x40\xc7\x06\xf1\x9c\xd5\xb3\xba\x86\xae\x88\xe5\x1a\xf0\xd4\x99\x52\x1a\xf1\xda\xbe\x12\xb1\x6d\x13\xfb\x9c\xa2\x9d\xdd\xb1\x2c\x24\x56\x55\xcf\x7c\xe9\x16\xaf\xc4\x60\x49\x1c\x18\x35\xf5\x12\x7b\x8b\x4c\x12\x33\xa9\xc3\x56\x2d\xf7\x3c\x98\x82\x93\x24\x61\xa4\x14\xda\x89\x03\x1a\xec\xf2\x7c\xc2\x29\x91\x27\xa9\x9f\x04\x41\x97\xc3\xba\x04\x5a\x5d\x89\xb2\x12\x16\x7a\xcc\x73\xb3\xa3\xd3\xab\x43\x65\x56\xc3\x1e\x47\x8f\x27\x4c\xa2\xc5\x3e\xea\x53\xae\x1e\x8a\xfc\xc7\x5f\x8b\xd6\xd7\xd5\xb6\xe1\xca\x14\x27\xea\xe2\x48\x4c\xb1\x9b\xe2\x00\x99\x25\xa6\xf5\x07\x79\xc2\x55\x4c\xb1\x2e\x1c\x8f\x45\x96\xd7\xd7\x61\x5a\x3c\x81\xd4\xa8\xf8\xd3\x38\xc9\x2b\x72\x46\xef\x39\x37\x0f\xd1\x0c\x89\xf0\x0d\x00\x14\x69\xf3\xd4\xb3\xf2\xe3\x89\x88\xb5\xd3\xc2\x21\x8a\xe7\xdd\x4d\x7b\x44\x01\xed\x1b\xaa\x93\x38\x64\x75\x3b\xa3\x4e\xcc\xa0\x89\x8c\x99\x6c\x49\x1d\x7a\xec\x33\xc7\x13\xc9\xa5\x07\xed\x70\x9c\x66\x3d\xd9\xa6\x2a\x30\x52\xd5\x12\xf6\xf2\x27\x56\x35\xed\x87\x2f\x33\x3c\x89\x4a\xd1\x24\x2f\x0d\x41\x6e\x5d\xf6\x60\xa5\xae\x09\xf3\x09\x8b\x89\xb9\xea\xac\x4a\x78\xa2\xb4\x11\x5d\xb8\x7d\xbe\xbf\x37\x49\xdc\xdd\xaf\xd9\xfd\xfd\xd2\xcd\x50\x09\x26\x40\xe7\x3d\xca\xba\xd9\x4e\xb6\x7f\x4e\x81\x2c\x41\xf7\x59\x55\xaf\xcb\xb3\xac\x8b\xb0\x3d\x24\x4d\xb9\xa3\xa6\x8d\x7b\xbf\x4f\xf9\x2d\x91\x68\x1a\x10\x92\xe8\xd8\xb8\x03\x1b\x8e\xe3\xb0\x3f\x68\x06\x14\x05\xd2\x2c\xd9\xcc\x46\x77\x8b\xc7\xaf\xa1\x2f\x89\x96\x92\x34\xfa\x40\x14\x83\x90\x3c\xd1\x2a\xa0\x92\xd5\x66\xbe\xe9\x6f\x68\x12\xad\x12\x26\x3b\x93\x39\x9a\x7b\x3a\x6d\x3e\x9e\x7a\x41\x2c\xfa\x0a\x56\xcb\xa6\x0b\x65\xf9\x4b\x2f\x31\x99\x7a\x91\x47\xf2\x17\x50\x62\xeb\x6f\x7c\x49\x47\x1c\x21\xdd\x78\xea\x25\x8a\xd6\xf9\x53\x4f\x63\x76\x28\x2c\xcc\x53\x4f\x1b\xc0\xcb\x3c\xab\x6f\x3f\x54\xff\xce\x53\x3f\xd0\xba\xe3\x40\xd0\xa1\x1e\x66\x28\xf5\xb9\xb1\xcc\xfa\x7e\x82\xfc\x45\x41\xf5\x9a\xfd\x1e\x81\x94\xfa\x2a\x21\x7c\x9d\x3e\xe5\x72\xe7\xcd\xe6\xdc\x5d\x2d\x0c\x14\x25\xca\x2c\xea\xe6\xcf\xf6\xef\x60\x12\x1b\x02\xe4\xdb\x97\x84\x3b\x9e\x86\x52\xd3\x96\xd3\xee\x37\xea\xd7\x4d\xd6\xfc\x72\x1f\x92\x77\x31\x13\xa5\x21\x26\x04\xa7\x24\xaf\xd7\x1b\xa8\x61\x5b\x3c\x88\xff\x77\x2a\x8b\xb2\xea\xe7\xe3\xd2\x48\x26\x61\xd0\x01\x64\x28\x1a\x26\x28\xc7\x54\x24\x96\xc6\x00\xdc\x3a\x15\x7c\x2b\x9a\x19\xae\x27\x8f\xc5\xd3\x24\xf1\x6c\x96\xeb\xdc\xe6\x85\xd2\xd4\x63\xc4\x4b\x32\x01\xc8\xa6\x99\x94\xf0\xa5\xdd\xe7\x98\x8a\x4e\x3c\xfa\xc0\x69\x24\x03\x43\xa1\x38\x9e\x8e\xed\x85\x12\x41\x40\x96\x9a\xcc\x01\xad\x04\xd6\x5d\x7e\x03\xe7\xaa\x6d\x02\x90\x38\xaf\xab\xe7\xdc\xf2\x90\xd5\xa2\xe3\xe8\x8d\x7e\x46\x71\x85\x03\x1e\xa6\xd9\x92\xdd\xe5\xef\x05\x29\x1c\x7f\xb9\x88\xa6\x3c\x8c\x89\x51\xba\x33\x2e\x6a\x8f\x47\x07\x47\xbc\x10\xc8\xe6\x29\x8f\x03\x62\x85\x9b\xb7\x60\xb1\x99\xa7\x69\xc4\xd7\xf4\x80\x4f\x21\xe0\x04\x79\xfe\x7e\xf3\x7a\xca\xd5\xa9\x7d\xc1\x10\x7a\x84\xfb\xb3\x46\xf0\xba\x28\x2b\x94\xa7\x32\xab\x33\x1c\x0f\x0a\x48\x3c\xd1\xa9\x46\xb7\xe1\xdb\xd0\x76\xc1\xb5\x45\x93\xf1\x96\xad\xe5\x5a\x31\x98\x64\x52\xe1\x87\x1c\xdb\xcd\xd8\xb7\x4c\x8f\x82\xc5\x54\x86\xc6\xb6\x49\x2a\x7f\x38\xc1\xa6\x12\x98\x53\x68\x6a\x35\xbc\x0a\x32\xfb\xfa\x63\xaa\xc0\x90\x4a\x09\x44\xc3\xab\x40\xe3\x30\x60\x4b\x95\x8f\x60\x2f\x45\x42\xf7\x5b\x84\x83\x59\x47\xaf\x0c\x0c\x15\xa0\xef\x5c\x31\xac\x10\xac\xe1\xd9\x9b\x1c\xf6\xb0\x31\xa2\x4f\x05\x97\x1b\x3c\x60\x8d\x1d\x80\xe2\x2e\xaf\xea\x4e\x51\x8a\xa7\x1a\x42\xe2\xcf\xea\xa2\x5c\x14\x87\x03\xe4\xaa\x3b\x12\x85\x86\x71\x4d\x86\xfe\x0b\x12\xe1\x30\xc1\x77\xdb\x6d\xb5\x08\x02\xaf\xc3\xa3\xda\xb1\xd1\x5a\x99\x4f\xf7\x3e\x2d\x93\xb4\xd5\xf5\x28\xca\x85\x4b\x49\xb7\x93\xc9\xa8\xb9\x32\x5f\xab\x84\x5c\x15\x07\x23\x8d\x7f\x97\xcb\xa2\x9d\xe8\x99\xa7\x4d\xda\xfe\x15\xcb\x62\x7b\x3e\xe2\xdd\x15\x30\x0a\xf3\x3d\x65\x22\x4e\x12\xf2\xd8\x7c\xbf\x73\x68\x32\xe6\xc7\x11\x09\xf7\x65\xd5\x4c\x34\x3b\xdd\x71\xba\xb3\xff\x51\x99\x9f\x46\x14\x5b\x1a\x0d\xd8\xef\x70\x34\xf5\xdb\xc9\xa7\x65\x7e\xaa\x28\xb1\xb6\x2e\x8b\xea\x88\xb2\x2e\xca\xea\x06\xdf\x7b\x2e\xc4\x83\x0e\xc6\x7c\x11\x6b\x1b\x57\x58\x9b\xaa\xe1\x4f\x4b\x96\xf2\x4e\x3d\x7d\xac\x01\xc4\x59\xe0\x81\x71\x25\xcb\xca\xfa\xd5\xa8\x68\xbb\x67\x0c\xc2\x80\x36\xc0\x56\x46\xa8\x1a\x02\xf4\x39\x0b\x64\x42\x3f\x6d\x0a\x1c\x95\xef\x79\xc7\x4e\xf5\x88\xb3\x40\x9b\x42\xfa\xec\x54\x17\x87\x42\x64\x7b\x5c\x9c\x05\x96\x72\xc4\x3a\xe3\x2c\x0c\x0d\x5c\xda\x55\x67\x96\xb9\xea\x09\x8e\x72\x16\xa6\xa9\xc1\xa1\x4a\x79\x5b\x94\x16\xf1\xe1\x8e\x69\xee\x99\x9a\xb5\x45\x04\x6c\x8b\xf9\xe9\x7c\x25\xbb\xc4\xa2\x90\x47\x5e\xab\x23\x7c\x1a\x21\x5e\x58\xa4\x22\xb0\x88\xc4\x79\xf6\xb2\x2e\x8b\x43\x61\x51\x73\xee\xe7\x62\xf0\x28\x5c\xee\xf9\xf8\x35\x7f\xf4\x85\x09\x1d\x55\x3b\x5a\x26\x43\x0f\x92\x46\xed\x2a\x8e\x4f\x50\xe2\xe4\xe2\xc3\x62\x8c\x92\xb6\x90\x98\xeb\x7d\x26\xeb\x51\x0a\x89\x25\x20\x58\xe0\xec\x7f\x91\x46\x13\x95\x69\x6e\xcb\xe2\x60\x25\x3d\x27\x67\x05\x96\x28\x03\x9e\xb7\xa0\x95\xde\xa2\xc2\x18\x72\x4a\x5c\x1a\x6e\x7c\xcf\x18\x78\xf8\x14\x9c\xa9\xa4\x63\x4a\x5c\x4e\x87\x0c\xb8\xe9\x38\x8b\x87\x1f\xdb\xdf\xc2\x14\x19\x68\xc5\x59\x5f\x3f\xbb\x2c\x0e\x7f\x4c\xfb\xe3\xd8\x33\x84\x52\x44\xc0\xf8\x99\xe1\x47\xbd\x3a\x77\x66\xa9\x9c\x49\x5f\x11\x16\xaf\x09\x05\xe7\x7f\x8e\x6e\x5c\x25\x29\x40\x4f\x9d\x66\x0e\xa5\xa4\x9a\x7e\xd3\x0b\xb8\x5d\x84\xc6\x24\x4d\x5a\xb6\xb9\xbb\x02\x03\xf2\x17\x74\xe6\x78\xeb\xb2\x78\xcf\xaa\x31\x30\xff\x52\xe6\xcf\x9e\x8e\x4a\xa6\x89\x13\xdc\xfa\x38\x8f\x21\xf4\x4c\xfb\x09\x18\x42\xe7\xa9\xc2\x81\xda\x0a\x67\x3a\x40\x66\x75\xa6\x5c\xe5\xcc\x55\x49\x46\x17\x11\xe8\x38\xcb\x7d\x58\xe1\x60\x53\x67\x9a\x72\x2f\xd0\xda\x26\xbd\xd7\x58\x3e\xe7\xd9\x15\x14\x37\xf7\x58\x64\xaa\x2c\x0f\xf3\xbf\xe5\x8f\xc4\xb9\xcf\x8d\xf3\x51\x25\xf7\xfd\xc1\xce\x7d\x61\xfc\xb4\x0d\x6c\x63\x57\xe8\x01\xd2\x8d\xfb\x52\x10\x51\x70\x59\xbf\xd2\xa4\xb3\x39\x16\x79\x55\x94\x7d\x75\x66\xce\x03\x5f\x06\x49\xeb\x6f\x62\x61\x6e\x83\x97\xc0\x43\xdf\x30\x59\x2b\xac\x57\xb5\xea\x9b\x33\xb4\xcf\x14\x46\x48\x18\x3f\x81\xcd\xda\xf0\x94\xc9\xd7\x56\xce\x9e\xf3\x50\xc4\x9e\x73\x4b\x2c\x4e\x62\x8f\x7d\x67\x42\xce\x23\x4f\xa5\xad\x32\xc4\x47\x8b\xc6\x75\x47\xa3\x90\x86\xef\xe6\x15\x75\xd1\xfe\x31\xf6\x28\x33\x5c\xd5\x27\xd5\xcd\x28\x3c\x62\xa9\x0c\xdc\x95\x64\x51\xaa\x07\x38\x60\x4f\xfb\xcd\x4d\x4e\x3c\xe2\x32\x4d\x5d\x43\xb7\xdd\x6e\xaf\x02\x49\x20\xdc\x41\x85\x07\x4a\x01\x36\xcb\xfc\xa9\x1a\x5f\x06\x0c\xa3\xb5\x05\x34\x0f\xdf\xcd\x34\xc0\x83\xc7\x9e\x20\xe6\xbe\xc1\x2e\x98\xdc\xec\xe8\x8d\xc7\x61\xec\xd9\xc4\xf1\xa5\x86\x1e\xe7\x31\x03\x61\xb0\x6c\xb9\xc4\x3d\x89\x3f\x0c\x3f\x47\x1a\x20\xbd\xf1\x53\xfe\x5e\x9c\xe4\xeb\x1f\xa3\xd4\x9a\x6b\x15\x47\xc4\x91\xd9\x60\xdd\x23\x73\xda\x27\x1d\xfe\x62\x2a\x24\xb4\x86\xd3\x9b\x23\xf6\x68\x6f\xbc\x89\xa6\x28\xce\x7a\xde\x2c\x9f\x76\x3f\x1f\xb7\xcb\xe9\xd9\x92\xa7\xda\x14\x6e\x57\x20\xcb\x82\xa4\xd2\x46\xc5\x79\xce\xac\xeb\xf2\x01\x32\x22\x10\x58\x1a\xb3\x3e\xb5\xdb\x69\xce\x80\x59\xc1\x71\xda\x6f\x6e\x8b\x79\x51\x8e\xd0\xf0\x9c\xc7\x3e\xb1\xe6\xad\x86\xf3\x00\xbb\xc9\x79\x9c\x72\xeb\x31\x5b\x15\x7b\x9b\x45\x36\xba\xb5\x4d\x30\x34\x5c\xa4\x38\x4f\x13\xde\x39\x05\xdc\x17\xef\xb8\xa9\x8b\x92\x74\x69\x49\xbf\xae\xc5\x96\x8d\x82\xf0\xc1\xf8\xe5\x29\x27\x61\xa1\xce\x4a\xf1\xee\x9f\xdb\x41\x2f\xe7\x2a\x64\xba\xfd\xa2\x73\xac\xe7\xe7\xf9\xe8\xa1\xc0\xe7\xb1\xb2\xdb\x8e\xd9\x24\x69\xc3\xcd\x97\x5f\xa1\x6e\x38\x84\x40\xea\x88\x58\xbf\x62\xb9\xc9\x72\x89\xbe\xe7\xb9\xdb\x00\x21\x42\x27\xb9\x0f\x9f\xf6\x55\xc0\xb8\x76\xcc\x41\x46\x89\x73\x9e\x6b\x03\xc7\x71\xfa\x76\x12\x27\xc4\x45\x18\x58\x28\x6b\x13\x50\x76\xa9\x4b\x2e\xd0\xa8\xa4\x77\x06\x24\xef\xfc\x3b\x54\xaf\x3b\x7b\x3d\xd7\x4e\xfa\x89\x13\x69\x5a\x1b\xd0\xd5\xfc\x74\x1e\xc7\xad\x5c\xfa\xcc\xac\x2d\x3d\x1b\x8c\x35\x96\xcb\xed\xf7\xf6\x3a\x41\x42\xbc\xa6\xff\x97\x65\xee\x4f\x4a\x32\xad\x1d\x3d\x7f\x75\xdd\xf8\x78\x38\x09\x28\x85\x89\xb1\xd9\xcf\x33\x9a\xcf\x27\x52\xb7\xa3\xf9\x1c\x75\x44\xa1\xb0\xf3\x9d\x2a\x74\xb6\xc7\x99\x28\x4e\xf5\x6a\x88\xce\xe2\xda\x93\xa9\x9d\xd1\x1e\xb5\xb6\xf6\x34\xcb\xfa\x75\xf4\xb8\xda\xd7\x04\xd5\xaa\x5f\xb3\xea\xae\xba\xed\x60\x17\x5c\x07\x9e\xa7\x3b\x31\x84\x31\x9e\x8c\xe4\x34\x6d\x98\xb6\x53\x50\x83\x80\x0a\x77\x8e\x54\xcb\xc1\xf3\x99\x33\x28\x6a\x3e\xc6\xb6\xb8\x85\x7d\x35\x0a\xf5\xc0\x8b\x12\xc2\xb7\x7c\x80\xd5\x01\x18\xcb\x96\x71\xf0\x44\x2c\xad\xc9\x76\x13\x79\xd9\x8d\xf5\xff\xf0\xff\xfd\x9f\xc4\x16\x5e\xc1\x07\x93\x7d\x12\xa7\xfd\x9b\x11\xd4\x7f\xc1\xfb\x6e\x4b\xd4\xc4\x85\xd8\xa2\x68\xe6\x7e\xf7\x67\x09\x5d\x46\xb4\x97\xdb\x87\x20\xd1\x44\xed\x9c\x9f\xce\x76\x4e\x1b\xbc\x34\x08\x3d\x4f\x27\xad\xf3\xe9\x0b\xde\xdd\x8c\x1b\x80\xb1\x61\xf9\x3e\xff\x73\x22\x25\x08\x51\xca\xe9\x86\xee\xd6\xcb\xc1\x60\x86\x48\x46\x14\x47\x53\x42\xb5\xcf\xa1\xe7\x10\xa1\x82\x81\x46\xb9\xe3\x33\x58\x69\xa9\xe1\x0d\xc4\x89\xd2\x0e\xf5\xfc\x80\x1f\x54\xa1\xc0\x92\xa2\x6d\x12\xf1\x9e\xdd\x59\x57\x53\x77\xf9\x18\xcd\x66\x9f\x00\xcd\x06\xf3\x7d\x5d\xf7\xc9\x9e\x93\xb0\x90\x84\x84\x8e\xc5\x7e\x6f\xc1\xb3\xed\x5a\x08\x09\xd3\xb1\x65\x65\x53\xa9\xc9\xb7\x93\xa9\x19\x19\x2b\xf8\x1c\xdd\x31\x25\xd4\x7b\x95\x9e\x12\xad\x4b\xdc\xc5\xb6\xb4\xcb\xd2\x39\x38\xe6\x60\x8c\x40\x1a\x1b\xff\x13\xb2\xf1\xfa\x0b\x81\x1c\x8c\x8c\x2a\xbc\x01\xc7\xb4\x44\x2f\x60\xd2\x18\x61\xda\x9a\x98\xf5\xe2\xb1\x07\x39\x26\xa2\x33\x66\x5c\x8f\xaa\xfa\x83\x9f\x84\x40\x72\x6d\xe1\x56\xab\xd3\xbe\x7e\x28\x5c\xe9\x0c\x00\x42\xd6\x49\x02\x12\x33\xb8\x85\x45\xdb\x78\x6a\xd8\x39\x40\xa4\x84\x08\x74\x81\xf8\xc3\x48\xd8\x92\x03\xa8\xd0\x11\x6f\x9b\x28\xdd\x95\x14\x86\x8d\x84\xe7\x39\x85\xd7\x0b\x5c\xc1\x74\x5c\x0c\x22\x34\x22\xf6\xee\x97\xd7\x46\x68\x77\xe8\x1f\x39\x3a\x25\x35\x5c\xd4\x66\x12\xb0\xb8\x87\x9d\x38\xef\xb2\x2b\xdb\x1e\x10\xcc\x84\xde\x0e\xc7\xbd\x5b\x3d\x3e\x6c\xbf\xdf\xff\xf5\x47\x7b\x1c\x63\x1a\x19\xd5\xdd\xe2\xf1\xa1\xa8\x87\xd4\x3b\x10\x9c\x11\x74\xed\xc3\xda\x7d\x3e\x61\x75\xda\x53\x08\x12\xb5\x4d\xd0\x78\xf8\xb9\xfa\xa3\xc6\xb2\x84\xbd\xe1\x5a\x0d\xef\x45\xc6\x66\x43\x6b\xb2\xba\xbd\x34\x31\xa8\x38\x51\xd6\xb1\xfd\xb3\xbe\xcd\x74\xd1\xac\xdc\x60\x04\x1d\x87\xd7\x50\xca\xf7\x43\x97\x4f\x9f\x43\x2e\xfb\x1e\x85\x17\x88\xca\xe1\x87\x56\x4a\x50\x7c\xda\xb1\x12\xfe\x96\x32\x2a\x07\xb4\x76\xa0\x6e\x03\x35\xcb\xeb\xec\x3f\xe3\x6d\x34\x68\x2f\x21\x26\xbd\x09\x0c\x66\xfb\xbd\x33\x2a\xfb\x0d\xd4\x52\x78\x91\x59\x4f\xab\x0f\x28\x29\xc3\xe3\x76\xf1\xee\x38\x08\xb4\xe9\x6c\xa0\x51\xe5\x4c\x4c\x06\x48\x3a\xe1\x47\x11\x41\x79\xc8\xb0\xe3\xb5\x2c\x3e\xaa\x85\x43\xf8\x3e\xa1\xd9\xae\x3d\x14\x75\x4f\x69\x96\x8b\x80\x1b\xfa\x50\x05\xb6\xf6\x63\xf3\xbd\xb7\x45\x69\x47\x68\x9f\x60\x2c\x42\x3f\x26\x98\xc3\x6d\x51\x36\x51\x18\x96\x37\x8e\xca\xff\xd5\xb4\x25\x22\xdf\xa7\x34\xea\xcd\xf2\x7e\xe6\x3a\x9e\x88\x78\x40\x5a\x42\x1f\x48\x0e\x12\x77\x9d\x4f\x90\x6b\x00\x3e\x36\xfd\xea\xe1\x79\xb5\xdb\x6c\x67\xdf\x96\x0e\xfb\x26\x62\x8e\x69\xdc\x95\xfa\x7a\x65\x44\xd7\x40\x8b\xd8\x69\xc3\x91\x86\xe6\x05\x96\x5a\x24\x51\x68\x4b\x3d\x0f\x37\x9b\x61\x95\x47\xa4\x3e\x7a\xa6\xee\x29\xf6\x2e\xbf\x30\xec\x86\x22\x0d\x7c\x8a\xf0\x54\x81\x15\x41\x60\x97\x9f\x3d\xc0\xb5\x6b\x24\x4d\x59\x88\x98\xe1\xc7\x1a\x9a\xa7\x1c\xa9\x44\x70\xc1\x74\x48\xea\x92\x96\x83\xb7\x58\x3e\x34\xcf\xba\x73\x0c\x2f\xc1\x23\xa9\x29\x07\xed\xca\x2c\xc3\x78\x76\x22\x86\x9c\xfc\x14\xee\xbf\x6d\xc2\x5a\x70\x91\x9a\x48\xd7\x7c\xc3\x60\x3a\x77\x23\x38\x72\xa7\x35\x3d\x3f\x19\xe1\x6a\x03\xe3\xbc\x16\x72\x0a\xf0\x34\xda\x4d\xa2\x01\x6f\xd1\x2a\x38\x8a\x66\x04\x84\x92\x5e\xb2\x31\x28\x5d\x96\x9f\x56\x78\xde\x94\x86\x9d\x61\xa9\x6b\xcc\x9c\xdf\x6d\x5d\x66\xe8\x5c\x8b\x6e\x8b\xf2\x27\xe4\x59\x3d\xd4\x13\x10\x00\x11\xf1\x3f\x7b\xda\xb7\xd7\x85\x34\xb8\x10\x91\x32\xce\xfd\xce\x7b\x6a\x50\x57\x16\x02\xd2\xc0\x79\x0d\x98\x82\x62\x13\xa1\x8c\x36\x5d\x42\xfa\xc6\x5b\xbc\x19\x7b\xb7\x90\xed\x77\x8a\x76\xcf\x46\x9e\xde\x5d\x4a\xc6\x7e\x68\x23\xb4\x6f\xdf\x96\x93\xa9\x3a\x21\x95\x68\x4d\x1a\x89\xd9\x71\x61\x9d\xc5\x85\xf2\x7c\x57\x53\x7d\xef\xdc\x72\xb9\x50\x61\x44\x74\x04\x85\x02\xea\xd6\xe2\xe6\x2e\x5f\x65\x39\xb1\xc7\x5d\xb3\x08\x29\x6b\x6f\x0b\xf2\x1b\xdc\xef\xdd\xeb\xbe\x62\xcf\x3c\xfa\x79\x15\x2b\xeb\x68\xb6\x69\x93\x13\x42\x69\x15\x1a\xf1\x81\x96\xe8\x90\xe1\x55\xdd\x11\x2e\x30\x36\x93\x9e\xe1\xca\xec\x96\xb3\xa7\xfb\xbf\x76\xf3\xd9\xe2\xc7\xb2\x25\x1b\x09\xc4\xd6\x9e\xac\x53\x33\xad\x26\x78\xc6\x02\x75\xec\xa7\x5d\xce\xf6\x51\x3f\xe6\xb7\x45\x69\xaa\x30\x5f\xd8\xd8\x70\xe9\x73\x15\xb9\x22\xeb\xa9\x96\x85\x4d\x42\xf4\xd5\xd9\x87\x3f\x25\x7d\x30\x1c\xa2\x66\xf7\xf3\x1d\xa1\xac\x05\x82\x7b\x0b\xd2\x57\x40\x45\xd6\x6f\x58\xaf\x20\xcf\x34\x56\x75\x31\x3f\x2f\xa0\xc6\x97\xa2\x1c\xf6\x53\x19\xf8\x81\x0b\x6a\x9f\x2b\x2c\xaf\x24\x6f\x65\x10\x47\xc2\x0d\xa7\xcd\xda\x14\x4f\x4b\x17\xa5\xca\x20\xf1\x51\x75\xce\x46\x46\xc2\xd0\xfe\x5e\x86\x97\xc0\xb9\x93\x0b\xe1\xec\xf9\x61\x68\x36\x52\x9b\xe2\x80\xa3\x2d\xbe\x8c\x7c\x3f\xb4\xd7\x7e\xc0\x8f\xf9\x49\xbd\xe0\x65\xc2\x64\xb2\x8f\xc8\x28\x61\xb4\xd4\x53\xaa\x6a\x5a\x56\x43\xc6\x32\x08\xf8\xd0\x5d\xdf\x7c\xaa\x7b\x68\xfe\xd4\x5b\xb3\xe8\xcf\xbd\xd2\xb3\x8c\x75\xe8\x12\xc5\x66\xb4\x36\x0b\xd6\x35\x77\x26\x2e\x93\x30\xa2\x95\xf9\x09\xb4\xde\xa3\x89\x6f\xb1\x9e\x17\xc5\xdb\x64\x1e\x5a\x26\x10\x2b\x83\x0e\x29\xb3\x77\xdc\x55\xaf\xd0\xec\x6a\xa7\x9b\x6a\x9f\xa6\xef\x76\x7a\xee\x93\x77\xa7\xf3\xb8\x32\x8d\xbc\xb0\x1f\x70\x6e\xf2\xe2\x43\xef\xe1\xcd\x11\xd1\x7f\x9b\x09\x96\xa9\xf4\xa9\x7a\x71\xd8\x15\x86\x48\xd7\x85\x01\x32\xc5\x90\x99\x59\xc0\x6c\x38\xee\x16\x8f\x1d\x0a\x77\x78\x19\x96\x32\x1a\x35\x87\x2c\xcf\x0e\xa7\x83\x23\xf6\xb8\x2b\x31\x9e\x4e\xf9\x8c\xa0\x1a\x97\xb3\xdb\xde\xc4\x44\x48\xc6\x54\x45\xeb\xc7\x37\xfa\xe6\x4c\xa6\xb4\xa8\x93\xca\xae\x8b\x15\x6d\x14\x71\x65\x84\xf2\x40\xc6\xd0\x13\x28\xa2\x36\x26\x0c\x97\x6f\x17\x30\x4d\x09\x5e\x40\xb3\xd3\xd7\x25\x77\x09\x7e\x42\x10\x01\x7c\xc7\xbc\xbe\x2f\x5e\xbe\x77\xdb\x57\x29\x22\x9f\x76\xd2\x4f\xc6\xf6\xac\xad\x74\x4b\x21\xbc\xc8\x6e\xf1\x97\xb9\x5c\x9f\xc4\x1b\xb6\x03\x51\x28\x8f\x92\xff\xab\x2c\xaf\x8d\x19\x7d\x85\x17\x74\x6c\xdb\x56\x82\x54\x91\xf3\x0e\xa7\x55\x34\xba\x72\x9b\x2a\x56\xda\x3a\x07\xd9\x65\xe9\xeb\x71\xa7\x12\x9f\xd4\x30\xc8\xa2\xb7\x17\xe9\x49\x65\x51\xbc\x16\x5f\xdc\xa3\x06\x8f\xfa\x04\xea\x28\x31\x09\x8f\x7d\x01\xaa\x0b\x34\xec\x61\x9d\x02\xa1\xf0\x0e\xdd\xf6\xce\xfe\x84\xf2\xfc\x80\xb6\x81\xb2\xc8\x25\xd4\xcf\x77\xe3\x75\x4b\x79\x01\xb7\xba\x08\xea\x0a\x04\xff\x1f\xa3\x13\xc2\xd4\xe9\xf1\x3e\xdc\x6e\x27\xa7\x47\xe5\x89\x98\xb6\xf6\xe2\x74\xbe\xcb\x0d\x8e\x6f\x7a\x2b\xa4\x3c\x0c\x43\xd9\x4f\x01\xd3\x7f\x89\x4f\x5f\x8d\xef\x14\x35\x33\xa1\xfc\x7e\x3f\xcb\x55\xb3\xa2\x53\xd8\x95\x99\x29\x69\x7e\xfe\x17\x96\x2e\xc3\xad\x7c\x9e\x90\x60\x9c\x84\xdc\x18\xc6\x8c\x76\xae\x6d\x33\x49\x65\xe9\xf9\xcd\x66\xd5\x9e\xaa\x7c\xb2\x5c\x38\x16\x55\xfd\x8d\xc4\x01\x86\xe9\xc1\xa9\x29\x47\x05\x5e\x4a\x18\x88\x15\x54\x55\xf6\x8e\xfb\xb3\xe5\x44\x37\x8f\x54\xe4\xfb\x2c\xc7\x9f\x99\xc2\xa2\xd9\x5b\xbb\x35\x5f\x05\x91\x41\x18\xef\x33\x8d\x9d\xa6\x2c\x57\x41\xac\x29\x1f\x64\xf1\x02\x64\xdf\xd5\x43\x20\xfe\x3d\xbc\xb5\x0a\x38\x0b\x5b\xff\x23\xda\xf9\xf5\x7e\xd9\xc2\xe0\x28\x17\x31\xb8\xa7\x90\x19\xbf\xb3\xdb\xbb\x87\xd9\xfd\x6e\xb6\xba\xdf\xdd\xcc\xb6\xcb\xf6\xa8\x08\x68\x63\x9a\xe3\xc7\xcf\xe2\xb3\xfd\x2b\x9a\x40\xf0\x90\xd9\xf7\xdb\xe6\xad\x54\x84\x01\x51\x3f\x77\x15\x68\xdc\x38\x15\xef\xe9\xae\x10\xe9\x80\xa2\xff\x42\xeb\x4c\x66\xb0\xef\x64\xc6\xb8\x8a\xfd\x84\x20\x14\x86\x55\xb5\xfc\x44\x79\xaa\x8b\xb2\x13\x4a\x72\xcd\x92\x98\x92\x59\x72\x5f\x54\x68\xd5\x52\x6d\xd6\xe7\x08\x65\xa7\xfd\x34\xbd\x17\x55\x31\x53\x91\xdf\x4d\xbd\xfd\xc5\x8b\xb2\x37\x71\xfb\x3b\x3a\x74\x69\x3d\x83\xb1\x6c\x6e\xe2\xd2\x30\x92\xab\x24\x30\x8c\xa0\x12\xdf\xb1\xac\xc7\x20\x81\xff\x1b\xf9\x50\x25\x82\x99\x05\x26\xcb\x6b\xb3\xcb\x74\x59\x3c\x95\xfa\x06\x87\x4b\xc5\xbc\xb2\x13\x6b\x9f\xd1\xcc\xd2\xa5\x8d\x5c\xf3\x34\xa5\xda\xf3\x1e\x75\xcd\x83\xd1\x3d\xa7\xcd\xd6\x9f\xec\xa9\x72\x3c\x6f\x4e\x87\x59\xbd\xc1\xba\xde\xe3\x94\xee\x77\xfb\xef\x97\x37\xce\x52\x10\xb6\x1c\xb3\xdc\x7e\x7f\xde\xdc\x4c\xbd\x2a\xc6\xe3\x34\xee\x7c\x0c\xcc\x06\xcf\x1e\x03\xdf\x88\x27\x3c\x14\xb9\xc4\x6d\x36\xc6\xbc\x2a\x48\x12\xbb\x19\x37\x8b\xd7\xba\x2c\x0e\xd9\xbe\x0d\x4d\x14\x20\x13\x5e\x37\x75\x98\x7a\xc5\x2e\x9c\x06\x0b\xdb\x73\x84\x17\x53\x10\x7a\x22\x3b\xe7\xc3\xc4\xe4\x21\x30\xa4\x39\x66\x53\xe3\xf1\xf6\x94\x4f\xe2\xc2\x46\x17\x95\x28\x92\xd6\x4c\x21\xcb\x67\x2f\x97\x3c\xab\xe1\x09\x2a\xf4\x03\x57\x2a\xe8\xc7\x53\x05\x85\xdd\xa3\x1b\x52\x51\x1c\x44\xce\x40\x88\x48\xa5\x5f\xae\xb7\x4a\x01\x58\x76\x52\x85\xf5\x3f\x4f\x45\x9b\xfb\x51\x0a\x15\x0d\x69\xa7\x1a\xb7\xf9\x7d\x90\xf9\x7f\xec\xcc\x18\x1a\x03\x1f\x53\x87\x20\xac\xea\x73\x76\xf1\x8a\x31\x32\x85\xe6\x87\xac\xbf\xe6\x2b\x54\x46\x2e\xd4\x68\x88\xa3\x81\x61\xb4\x3a\x83\xae\x95\x0e\x13\xa2\x98\xe9\x32\xc3\x5c\x55\xcd\x7c\x30\x1a\x07\x1a\x90\x42\x56\x4b\x3f\xb7\xab\x79\x7f\x43\xa0\xb4\x4c\xa8\xc9\xd6\x82\x5b\x9d\xe4\x11\x65\xca\xbf\x32\xd2\xfb\x3b\xff\x0e\xee\x06\x3d\x3f\x75\xb6\x01\x37\x84\xb1\x86\x1a\x95\xf1\x19\xb2\x98\xa9\x9b\x13\xc1\xa6\xaa\x1a\x0e\xc7\xe1\x9b\x42\xcf\x47\x8a\x79\x95\xb3\x17\x7d\xfc\xe8\x76\xb9\xe8\x61\x48\xa2\xb4\x59\xde\x11\xd1\x87\x3f\xee\xfb\xc6\xe6\x3d\x27\xab\xfe\x3e\xd8\x0b\xfd\xd8\x64\x44\x35\x0e\x93\x5b\xe8\x8b\x98\xb8\xc0\x0f\xf8\xd1\x4f\x49\x61\x10\x08\x87\xac\x72\x9b\xd8\x61\x2d\xed\x1f\x53\xd8\x37\x0c\x22\x11\xd9\x5a\xca\xa2\x04\x61\xb6\xf4\xc3\xa7\x0c\xe2\x58\xf2\x36\xee\xfc\x5e\x94\x15\x3e\xfe\x7a\x18\x37\x92\x9c\x98\x7a\x12\xf2\x27\x94\xef\xcb\x26\x46\x20\x7d\x75\x7b\x3c\x11\x46\x03\xb5\x3a\x40\x59\x3f\xe7\x54\x2d\x9b\x8c\x63\x30\xc1\x84\x7e\x0e\xac\x80\xd9\xba\x38\xb6\x79\xe0\xcd\x6b\x71\xda\xab\x55\x96\x8f\x26\x32\x4c\x59\xc4\xbb\x7b\xec\xd9\xdf\xb8\xe3\x3c\xa6\x70\xb0\x46\x38\x58\x33\xb3\x36\x17\x8f\x29\x20\xa5\xa7\xb2\xa3\xae\x5a\x8d\xb9\xfb\xa2\x78\x6b\x11\x99\xc8\x82\x98\xf8\x2f\x9b\xe2\x94\x2b\x91\xf5\x7d\x88\x39\x32\xc5\x8c\x69\xa0\xea\x1b\x5b\x73\xe4\x3e\xe7\x2d\xe4\xbb\x3e\x95\xf9\xa5\xb1\x2b\x47\x1e\x26\xda\x54\x99\xac\x76\xe7\xb9\x3d\x5d\x02\x2d\x78\x5d\xdd\x85\xfc\xd2\x6e\x8b\x72\xfa\xc5\x81\x9f\xd2\xd0\xb3\xf9\xe7\x0b\x88\x1f\x02\xf3\x68\x91\xf9\xbe\xbc\xfb\xf6\xdd\x25\xf9\x10\x24\xa3\x7c\xc5\x0e\x0f\x59\xfd\x58\x82\xdc\x37\x7b\x0b\xa7\x43\x15\x8d\xfa\x0b\x28\xe3\x5b\xd8\xc6\x78\xe6\x6d\x3a\xcc\x18\x8a\x44\x51\x04\x34\xcb\xf3\xec\x35\xdb\xc3\x54\x4a\x74\x78\x57\x42\xa4\x2e\x4b\xb6\xe8\xf9\x5c\x0e\x83\x1a\x94\x32\x24\x22\x44\x96\xb7\xa2\x9a\x83\x34\x1a\x2a\x5f\x10\x36\xb4\x59\x6e\x9a\x3d\xbc\x5b\x1c\x7e\x66\x70\x97\xe7\x58\xba\x3c\x22\x2a\x66\x9c\x20\x49\x93\xfb\xaa\xc0\x41\xdb\x18\x68\xa3\x73\xff\xf4\x63\x98\x27\x1f\x35\x53\x91\x51\x92\x80\xfd\x7e\xb9\x47\x79\xb9\xf5\x46\x8d\x01\x15\x7c\xaa\x66\xd0\x1a\x87\xca\xf6\x48\x44\xdf\xcd\x6d\x9c\xad\x09\xeb\xe0\xbd\x6b\x8f\x45\xc4\x30\x39\xec\x7a\x9a\x7f\xda\x83\xd8\xfc\x35\xcb\x8d\xf5\xcc\xf4\xa2\xa3\x7d\x4f\xa2\xef\xcc\x5a\x9e\xee\x9e\xaf\x35\x0b\x62\xaa\x91\x9b\x4a\x98\x4d\x28\x94\xc5\xa1\x4f\xfc\xd5\x7e\x1a\x92\x17\xf3\x07\xbc\xe3\x02\x8e\x51\xfb\x77\xc6\x93\x74\x20\xe8\xde\xec\x16\x88\x24\xf9\xf8\x38\xef\x5a\x09\xc2\xd2\x3f\x75\x7f\x0a\xbd\x88\x80\x23\x22\xbb\xe8\x2a\x97\xca\x27\x3a\x0c\x43\xd2\x40\xcc\xf1\x73\x90\xc2\xd7\x61\xcc\x58\x87\xf8\x9d\xef\x8b\xe2\x70\x9b\xed\x6b\x57\xe5\x1f\xd3\x7e\xbb\x0b\xda\xc5\x66\x55\xbc\x67\xad\x51\x38\xd7\x91\x87\xe4\x84\xa7\x4d\x8a\xbf\xb5\x96\xea\x52\xb3\x53\xd2\x42\x3a\x4a\x8c\xdf\xe4\x29\xcf\x64\x51\xe6\xa3\xb9\x54\x47\x80\x44\xc8\xbc\x9f\x6d\xd7\xfd\x4b\x7d\xb9\x6e\xeb\x24\xe1\x14\xd1\x1b\x7d\x69\xb3\xf2\x0e\x92\xb3\x3a\x11\x69\x62\x53\x68\x9b\xd3\xe1\x2e\x9f\x9f\xef\x8d\x5c\xc5\x1f\xa7\x1e\xfd\x4f\x33\x4f\x44\x30\xd0\xc8\xbb\x16\x0a\x0d\x87\xbd\x66\x9e\x4c\xed\x89\xb6\xf4\xdb\x01\x3d\x35\x8b\x3c\x9a\xa8\x56\xd9\x4b\x09\x3d\x36\x8a\x3b\x8c\x9a\x90\x03\x7a\x7f\xaa\x5e\x3b\x34\x83\xe6\x51\x40\xea\x56\x0f\xf8\x71\x53\xc2\xc7\x13\x82\x3a\x6f\x8b\x75\xcf\x2b\xf5\x9a\x69\xae\xbb\x40\x6c\x7a\xdc\xfb\x21\xcb\xa9\x8b\xae\xb1\x74\x15\xa1\xf6\x47\xb8\x47\x9d\xeb\x15\x2a\x2a\x16\x18\x60\x69\x3f\xda\xd0\x1c\x14\x85\x7b\xf2\x15\xca\xbe\x89\x35\xd7\x10\x48\xe8\xe0\x9a\x2e\xa1\x31\xa9\x12\x3a\xbc\x33\x01\x8a\xd4\x1e\x77\xb6\xa6\xf0\xb8\x57\x57\x70\x19\xc3\xd7\x2c\x00\x29\xe7\xb0\x33\xd6\xe3\x17\x76\xae\x5c\x0b\x2d\x29\xe5\x7d\x3a\xbe\x94\xa0\x70\x53\x97\x27\x49\x3a\x57\xc3\x66\x32\x8c\x08\xcd\xad\x9b\x88\xde\x48\x02\xde\x3a\x15\x70\xf7\x6a\x64\x1c\xfb\x5f\x30\x8e\x06\xef\x48\x0a\x9d\x7a\xce\xf0\x9b\xde\x80\xe3\xa2\xd8\x06\x2a\x8d\x69\xbb\xf1\xed\x79\xfd\x45\x8d\x41\xa3\x67\xdc\x62\x2b\xac\x2f\xf8\x7d\x5a\x07\x8a\x98\x6b\xdb\x47\xb7\x38\x69\x0d\xa6\x6b\x11\x80\xe2\x0b\x5f\xad\xa6\xa5\x61\xb6\x6e\x6f\xfe\xfb\x5b\x74\x22\x78\x9e\x02\x96\x5a\xbd\x37\xc2\xe2\x0c\x93\x4a\xb6\x95\xef\x03\x69\x59\x1d\xb2\xfc\x89\xb0\x3f\xeb\x32\x7b\xcf\xf6\xf8\x62\x0d\x60\x5c\x33\x16\x3a\x04\x43\x40\x84\xef\x7a\x7c\x1d\x91\x10\x66\xbe\x37\xaf\xfe\xad\xc8\x7e\x5a\x7e\x1a\x3c\x5f\x7b\xa4\xbc\x5b\x7d\xc0\xb1\xc7\x54\x03\x2f\x08\xcc\x01\xe3\x88\xd8\x03\xc8\x55\x6d\x0b\x96\xf0\x56\x06\x63\xe6\x2a\x3d\x4b\x33\xaa\x47\xb7\x1d\x06\x21\x09\xa7\xaf\x4e\x55\x66\xd4\xda\x7b\xe3\xba\x39\x1c\xd1\x42\xba\x23\x19\xee\x62\x3f\xc9\xd3\x6e\x9a\x41\x68\xfc\xf1\x9b\x30\xba\x19\x7e\x97\x74\x93\xae\x69\x1a\x8e\x95\x7f\xab\x15\xe4\x27\xd8\xef\xcf\x93\x5a\x1a\xe0\x85\x08\x54\x3f\x75\x2a\xf7\x1d\xa3\x0b\xbc\x88\x29\x25\x2e\x48\xbc\x8b\x66\xa0\x4f\xec\x3f\xc1\x8b\xb8\xa0\x8c\xd2\x4e\x9c\xce\x14\x8e\x5d\x79\xa6\x38\x32\x29\x16\xb3\xd6\x7c\x39\x19\x80\x97\x24\x31\x44\xfd\x38\xee\x5b\xb1\x37\x6c\xbb\x51\x3b\xa1\xe9\xd3\x60\xfe\xef\x2c\x6f\x86\x7e\x0f\xf3\x6f\x9b\xa4\x1e\x23\xb4\xc7\x82\x88\xf9\xdd\x57\x65\xc2\xf8\x8d\x34\xc3\xca\x05\xc7\xbe\xbb\x2e\x0f\x90\xb0\xaa\x2e\xbe\xf8\x62\x18\x81\x07\xd6\x52\x8e\x06\x1c\xc9\xa7\x8e\xee\x12\xa4\xef\x1b\x8a\x9f\x38\x16\x1f\xc1\xe4\x38\x07\x4f\xc4\x1e\x29\x2a\x1c\x33\xf9\x76\x5b\xf4\xb0\xe8\xd7\x77\xff\xe0\x09\x9e\x10\xcf\xf2\xee\xed\x54\x42\x8f\xfb\x7e\x55\xf4\x60\x78\xba\x0c\x19\xad\x27\xfb\xec\x0d\x67\x65\x3d\xde\x6e\x81\x27\x63\x2f\xb1\x7b\x9d\xde\xd0\xc0\x6a\xf6\x47\xdb\x20\x0d\x6c\x46\xe7\xbb\xd5\xf6\xb9\xd2\xe9\x24\x4b\x43\x8b\xa2\xed\x2d\xe3\xbd\x55\x11\x3c\xa9\xe2\x00\x9d\x74\xdc\x4e\x16\x87\x43\x56\x55\x59\x91\xef\x9a\xb6\xef\xd0\x62\x4b\xc0\x53\x9e\x4f\xb5\xb2\x2c\x7f\xcf\x2c\x70\xe4\xf2\xa1\x5d\xdb\xd0\xd8\xb3\x54\x0e\x21\x58\x6d\x0b\xab\xb2\xd4\xf6\x06\x95\x32\xca\xef\x76\x59\xf7\xbf\xa7\x22\x76\x6d\xab\x3c\xba\x05\x4c\x3c\xc2\x57\x59\xe2\xf1\x57\xb3\xed\xf8\xcc\x54\x06\x91\xdd\x85\x59\xdd\xf6\xab\x1a\x77\xe0\xe9\x54\xa4\x72\x80\x9a\x6c\x07\xf0\x7e\x60\x6d\xe0\xda\xab\xc8\x29\x52\xad\xb0\x1e\x12\x87\xc1\xf7\x3c\x4d\x8a\xec\x94\x9a\xb5\x84\xc2\x56\x97\x14\x7c\x0f\x0c\xa7\x81\xc0\xe8\x34\xf0\xb6\xc5\x48\x62\x1b\x7c\x4f\xa6\x3d\xab\xe2\xea\x1e\xf5\xa8\x8b\xf9\x9e\x8a\xd4\x78\xa6\x9f\xec\xad\xbe\xef\x87\x14\x08\xab\xc2\x2c\x2d\x56\xa1\xcb\x1e\x75\x13\x39\x59\x6d\xd2\x6e\xde\xcc\xf3\xc3\x6b\x04\x82\x51\xb8\x20\x8b\xbc\xce\xf2\x13\x7e\x33\xf3\x66\x37\x61\xf8\x61\x1c\x3a\xfd\xdf\x26\x7c\x31\x3b\xc8\x69\xb5\x17\xf0\x43\x30\x32\xcf\x2f\xd9\x3b\x3e\x65\xd5\xdb\x57\xb7\x1f\x79\x82\xf6\xfb\xbb\x6e\x56\xb9\xe6\x54\x3a\x01\x85\x01\x3f\x0a\x8c\x3e\x29\x10\x5f\xbc\xb9\xf1\x2a\x23\xdc\x1f\x4e\xee\x6e\xc1\x8f\x12\x8f\xfa\xce\xaf\xd9\x8d\x7b\xb8\x48\xf9\xa1\xdf\xf1\xc2\x2c\xca\xa7\xef\xaf\x04\x7e\x0c\x86\xa6\xde\xc1\x98\x77\x0f\x4f\xdb\xd1\x83\x27\x80\x94\x9a\xfd\x90\x75\xe0\x4e\x4c\x83\x98\x30\x04\x84\xe5\xb3\x31\xcf\x0d\xd4\xce\x7b\xbc\x69\xc0\x2d\x57\x83\x8a\x1c\xad\x6c\xe3\xe8\xbe\xb9\x48\x22\x27\x61\x74\x3a\xda\x5a\xcb\xa5\x63\xf3\xa9\x65\x65\x80\x0f\x9a\x09\x5b\xed\xf9\x8e\x65\x71\xd3\x13\xc2\x36\x10\xd5\xc1\x3f\xad\xc4\x47\xff\x9f\xa1\xca\x04\xf8\x22\x0e\x68\x03\x88\x9f\xc7\xcc\xf4\x10\x52\x0e\x71\xcf\x22\x30\x25\x53\x52\x57\x14\x2b\xf6\xcd\x3a\x55\x5e\x61\xe4\x81\x2f\xb4\x09\xdd\x2b\xac\x17\x8b\xef\x46\x89\x9b\x0d\xc7\x9b\x0c\xc1\xe1\x09\xee\xa1\xaa\x67\xeb\x3e\x81\x02\x7c\x99\x68\x02\xd7\xca\xa2\xaa\x27\x25\x93\xc1\x97\x8a\x11\x65\xba\xcd\xac\xf6\xa5\xad\xc1\x57\x2c\xf5\xed\x9a\xb7\x82\x4f\x57\x42\x1d\x85\x70\xbe\x12\xbe\xd0\x2d\x08\x72\x1c\x73\x36\xc7\x75\xe7\xd4\xf5\x86\x79\x33\x4a\xba\xdf\x40\xc1\x48\xb3\x61\x85\x37\x50\xfc\x5d\xed\x9d\xd1\x63\xa0\x14\x74\x07\x07\xf8\xfc\x5e\x1c\x51\x9f\xf6\x95\xe1\x24\xba\x1f\xd1\xdc\xd0\x34\x45\x89\xf0\x76\xe7\x7a\x6e\xe0\x25\xd6\x42\x82\x50\x74\x84\x9f\x9b\xfe\x1a\x81\x1f\x70\x65\x0a\xdd\x7b\x7c\x21\xe8\xa1\x2c\x4a\x45\x40\x2c\xb7\x26\x04\x3e\x8b\x53\x73\x17\x4d\x30\xb5\xe9\x95\x8b\x4d\x17\x8c\x6d\xbb\xc0\x4f\x08\x34\xda\xfa\x21\xfc\xf3\x84\xa7\xff\xb3\x30\xd9\xe8\x06\x83\xc4\x23\xea\x8a\xc8\xd4\x63\x3e\x2f\x11\xd5\x6f\x48\xdd\xcd\x29\x10\x59\x21\xcf\x15\x56\x15\xbc\x0c\x60\x6b\x10\x04\xc2\x68\xb2\xef\x9b\xbe\x45\x73\x48\xfb\xd5\x82\x50\x70\x93\x6b\x3c\x1d\x4c\xcd\xff\xc5\xe9\x84\x43\x10\x62\xe8\xd9\x18\xe0\x2e\x97\x27\xd1\x4c\x1c\xdf\xa1\x7a\xed\x2d\x45\xc3\xd0\xbb\x3d\x2f\x95\xba\xdd\xb8\xf4\x51\x31\xb3\x5c\x19\xa8\xf6\x70\x5a\xb5\x0e\x61\xff\x13\xff\xef\xe8\x4a\x91\x8a\x09\xb8\xba\x2a\x54\xa6\xcf\x3f\xb3\x17\xcc\x65\x36\x54\xba\x87\x20\xf6\x3c\xaf\x65\xe2\xed\x8e\x58\xee\x3e\x30\x73\xcf\x10\x47\x3e\x11\xe6\x16\xdd\xa6\x88\xd4\x44\xff\xae\xbe\xa6\xbb\x8c\xf5\x24\xab\xa8\xd2\x34\x9c\xb6\x82\xa4\x59\x3a\xc8\xb7\xb9\xaa\x8a\x7c\x17\x5f\xe9\x7a\x49\x68\xcc\xa9\x76\xd5\x7f\xc6\xbb\x9e\x20\x11\x29\x25\xc5\x9a\x49\xa2\xb9\xd3\x69\x99\x0a\x08\xd2\x20\x4a\x02\xbb\x17\xfb\x32\x57\x08\x41\x2a\x23\x4a\xfe\x18\xfb\xd5\x26\x40\xbb\x98\x48\xaf\xa9\x19\x0d\x2f\xc4\xbc\xd0\x77\x3a\x6e\xd4\x0d\x57\x90\xc3\xcb\x08\x99\x03\x01\x4b\x63\xca\xe6\x64\xb9\x2c\xa9\x16\x77\x73\x77\x73\x5b\x16\x83\x2a\xe5\xb4\xde\x18\x04\x4c\x19\x26\xdb\x0b\xd6\xff\x2c\x2d\x35\xd7\x1d\xd2\x1e\x65\x93\x4f\xb9\x51\x9b\xe9\xfe\xce\x02\xe6\xd2\x74\x94\x39\x73\x47\xb8\x1f\x7b\xad\x16\x15\x95\xe9\x1c\x46\x25\x6f\x9b\x84\xca\xb3\x58\x8a\xd9\x3e\x83\x6a\x38\x5e\x78\x64\x68\xbe\x07\xf8\x9c\xb9\xf8\xb3\x19\xde\x15\xd1\x3c\xfb\x4b\x66\xc0\x6d\x7c\x37\x7f\xfc\xfe\x6c\xb2\x0c\xd7\xbe\x1c\x44\x06\xba\xf8\x82\xf5\xce\x49\x10\xec\xc4\x79\x77\xb0\x2f\xd3\x35\x4b\x12\x42\x0d\xbb\xcc\xed\x64\x5c\x71\xe5\x43\x01\x48\x22\xb6\xe9\x7d\xf1\x81\x65\xeb\x54\x32\xba\x0f\x61\x4c\x6e\xd7\x4f\x77\x3f\x67\xdb\xa5\x41\xc9\xee\x56\xb3\x3f\x77\x8b\xd9\xda\xdd\x85\xf0\x53\xdf\x02\x3f\xf6\xe7\x9b\xac\x92\x53\xee\xde\xae\x6d\x9c\xc4\x49\xa7\x8e\x37\x50\xea\xe9\x4a\x5e\xc3\x9b\x10\xdc\x48\x72\x2d\x9f\x16\x01\xb9\x86\xb6\x26\x16\x83\x0f\x21\x7d\x90\xe8\x40\xa1\x50\xe3\xf7\xce\x95\x6c\x78\x0f\xca\x97\xc2\xa9\x3a\xde\x3d\xfc\x5c\x6e\xb6\xbb\xe5\xf6\xbb\x13\x73\x84\x40\xc5\x5e\xc0\x1c\x15\xa4\x59\x18\xad\xe3\xcb\x84\xd8\x2f\x04\xca\xe6\x3b\x36\x58\xd7\x34\xf7\xd6\x04\x8b\xd8\xcd\xcd\xff\x7f\x82\xfc\xed\xa9\x2f\xb8\x79\xe5\x6b\x28\xa5\xe9\xe6\x15\x79\xe6\x54\x54\x2d\x1a\x82\xe5\x20\x40\xc6\x1c\x15\x91\x92\x6d\xfd\x04\x45\xa0\x53\x06\x9d\x60\x0e\xa9\x80\x9b\xa4\xe6\x64\x5e\xd5\x61\x74\x21\xd0\xdc\x44\x63\xed\x1e\xfa\xb6\xfc\x1b\x99\x53\x08\x3d\x14\x46\xaa\xb5\x78\xa9\x0e\x44\x06\xea\x12\x18\xa1\xef\x09\xd2\x0f\x16\xd9\x7f\x8f\xee\x6f\x41\xda\xc2\x4e\x37\xa7\xe3\xb1\x28\xeb\xd5\xa0\x33\x87\x61\x14\x91\x4e\xcf\x6a\xf6\xf0\x7d\xb6\xdd\xce\x1e\xd6\x4f\x8f\x7f\xfe\xe5\x07\xdb\xef\xb3\x9f\xcb\xb6\x51\xec\x91\x98\x99\xad\x56\x38\x33\xc8\xc1\x37\x09\x43\xe6\x51\x62\xe4\x90\xe5\xa4\x8b\x3d\x95\x82\x0a\xa3\x50\x91\xd4\x13\xec\xf7\xc5\x47\x7f\x7f\x19\x46\xd6\x3d\xb8\xe9\xe6\xa6\x7f\xb4\xea\xf4\x10\xc6\x69\x44\x09\xc8\x23\x9c\xbf\x17\xa7\x4b\xe0\xbd\x6d\x96\xb0\x88\x20\x72\xcb\xfa\xb5\x24\x48\xa0\x3b\x3f\xe1\x26\xf8\x20\xca\xce\xa6\x57\xd5\xa6\xa9\xa0\xcb\xb0\x84\x2c\x8a\x69\x92\x87\xd2\xc4\x4f\xfd\xf7\xcb\x62\x8f\x10\x04\x36\xaa\xb4\x96\x66\xd3\x3b\xea\x90\xc5\xe0\xca\x40\xe3\x51\xfe\x8f\x21\xba\x0e\x42\x26\x3d\xc2\xac\xdd\x50\x37\xec\x14\x6d\x20\x84\xc0\xa7\x58\x2a\xcb\x09\x4c\xdd\xd5\x2d\x20\x14\x31\x38\xfd\xd6\x45\x74\xeb\x7a\x2d\x11\xb8\x15\x96\x74\x91\xcb\x8e\x17\x0a\x30\x67\xe5\xf8\x71\x5b\x94\x2f\x5d\xf9\x79\x8a\x2a\x08\xa1\x10\x4c\x4a\x97\x88\xa9\xe4\x58\x0b\xca\x25\x90\x42\xe9\x9b\x25\x7c\x77\x34\x62\x39\xc6\x31\xef\x01\x3f\xfe\x68\x1b\x24\xa9\x45\x9b\xdf\xe5\x59\x9d\x51\x6a\xeb\x8f\xde\x8d\xc9\x24\x00\xc3\x5e\x7e\xc9\xf2\x27\x23\x75\xda\x9e\x9c\xf2\x28\x26\xb3\x56\xda\x3a\x1a\x30\xe9\x68\xb7\x17\xaa\x00\x68\x07\x66\x4d\xe3\xab\x7e\x99\x19\x42\x15\x05\x84\x4f\x9c\x3d\x6c\x47\xdd\x56\xc5\x40\x3c\x5d\xbb\x70\x9a\x3b\xdf\x5f\x66\x4a\x46\x5d\x4d\x87\x82\x04\xf7\x0c\x14\x79\x0e\xd5\x28\x12\x0f\x75\xec\x53\xb9\x1c\xcc\x75\x97\xcd\x4e\xa5\x8d\xe9\x42\x9d\x1a\x37\x4e\x8b\x5c\x35\xf2\x9d\x5f\x8f\x7d\xcd\xcc\x29\x95\x15\xe7\xbe\x3b\x1c\x87\x98\x1c\x88\xbc\xd8\x8f\x8d\xfc\xd5\x6b\xcf\xf2\x1c\x22\x4f\x19\xba\x33\x99\xd0\x38\xa9\xb2\xc9\xe7\x8a\x7c\x3f\x94\x69\x07\xa1\x21\x1d\x06\x9b\x8f\x71\x41\x67\xe4\x83\x91\x5a\xff\x20\xb4\xfe\xa2\x28\x91\x32\xfb\xf6\x68\x13\xe9\x47\x1d\x72\x79\x71\x41\x55\x6f\x9a\x08\x21\x1d\xa5\x71\x5f\xb7\x45\x8e\xae\x3f\x44\x81\x60\xa4\xb2\xa4\x70\x0f\x67\x77\xe9\x30\xe2\xe0\x74\xe9\x32\x59\x16\xab\x82\x4c\x1e\xef\x1c\xca\x07\xa2\x10\x00\xd3\xb6\x70\x3e\xa6\x87\x40\x14\x2a\xc9\x5b\x2b\x3d\xc3\x0b\x9c\x9f\xef\xf1\x05\x64\xfb\x23\xb1\xc7\xa9\x82\x6d\x37\xc2\x2b\xf8\x6c\x8f\x38\x01\x32\x2b\xec\xa1\x7a\xc6\x53\x10\xa5\x1e\x77\x34\xce\xb7\x65\xfd\xba\x7e\xcd\x3a\xb5\x55\x88\xd2\xc8\xa3\xc8\xd2\x61\x83\x1d\xdb\xa2\x3d\x0e\x40\xb1\xc7\x2b\xec\xdf\xb3\xfc\x85\xb0\xcc\xef\xb0\x77\x87\x99\xf4\x08\xea\xf2\x0d\xf3\xe5\x67\x6d\xec\xd5\x09\x81\xf1\x65\x9f\x89\x78\x92\x3a\x9e\xbb\xf5\x0f\xd8\xf7\xf2\x88\x13\xc9\x79\xe6\x4e\x64\x29\x55\x45\x57\xb3\xa7\x1f\xcb\xed\xdd\xc3\xb7\xdd\xfa\xf1\xf1\x7e\x37\xbb\xb9\x71\x0b\x76\x04\x21\xa7\xb7\x71\x34\x90\xcf\xbe\xc4\x20\x44\x90\x18\x4a\xd6\xee\xe0\xd0\xef\xdf\x71\x7f\xec\x7a\x24\x28\x1e\xb1\x56\xcc\xee\x1d\x4b\x97\xbf\x1a\xde\x3f\xa0\xa6\x20\x44\x97\xc5\xe1\x09\x61\xff\xc7\xe0\xa8\xf0\x85\xdf\x55\x71\xaa\xe6\x7d\xd6\x78\x83\x2b\xac\x80\x9c\xa5\x87\x3e\x8d\x10\x89\x20\x50\x9d\x53\xef\x2d\xec\xf7\x02\xa6\x05\x17\x9a\xb6\xa9\x6e\xc1\x0e\xf9\xd8\xc6\x16\x22\x11\xa2\x04\x07\x84\x9f\x43\xee\x5c\xe7\xdc\x03\x8a\x04\x88\x65\x7a\xca\xad\x2b\xcb\xe2\x35\xdb\xab\x21\x12\x1b\x22\xc1\x80\x90\xf8\xf3\xe2\xf3\xb3\xbf\x96\x47\x82\x27\x84\x6d\x58\xef\x51\xbd\xe0\x1a\xce\xe3\xf9\x2e\x92\x89\x99\xd1\x9a\x95\x9d\xf2\x77\xcf\x79\x56\xe4\xcd\x50\x18\x3e\xb4\x8a\x84\x68\x77\x88\x66\xe8\xb7\x06\x5e\xc3\x2b\xea\x38\xe2\x8e\xeb\xb2\xf3\x76\x98\x57\xa7\x12\x37\x58\xbe\x67\x12\x1d\x3d\xc1\xc1\x10\xda\x5e\xaf\xa5\x29\x49\x3c\xe1\xe1\xec\xbe\x7e\xec\x05\x71\xca\xda\x51\x56\xec\xd5\x63\xee\x80\xc1\xae\x05\x86\xb4\xa7\x5d\xc3\xd9\xe8\x7d\x5e\x95\x02\xb6\x27\xf8\x91\xa2\x64\xfa\xd3\xb2\x6f\x37\x07\xb1\x2f\x38\x99\xbc\xc8\x4b\xd5\x2c\x88\x83\x50\x92\xc0\xba\x2d\x5b\xde\x16\x65\xdf\x12\xc3\x36\x0a\x53\x9f\x5e\x50\x8e\x9f\xf5\x36\x6b\xbb\x68\x1c\xa6\xe8\xc4\x75\xac\xd7\x79\x26\xf6\x38\x80\x1d\x0e\x47\x5b\x1c\xf2\x40\xa5\xbd\x7a\x8f\xfa\xd6\xee\x85\xe2\x10\x04\x25\x64\x9b\xa9\x94\xd4\xbe\x3a\xda\x03\xc4\xa1\xe6\x54\x16\xb4\xa2\x0e\xdb\xcf\xf1\x83\x44\x3c\x0c\x64\x47\xed\x99\x8a\x2e\x87\x27\x24\xbe\xa4\xda\x23\x29\x32\x3f\x61\x75\x3a\x20\x69\x54\x74\x87\x0d\x23\x97\xc0\x0d\x9d\xa7\x01\xc4\x09\x37\x8c\xec\xbb\xc5\xe3\xee\xdb\xe3\xec\xbe\xfd\x3b\x44\x4c\xd8\xea\x98\xc9\xf0\xae\xb2\xe6\x29\xf7\x8e\xe6\x0b\x71\xea\x09\x0a\x02\xee\xf2\x6f\x4f\xa8\x32\x97\xd1\x77\x87\x59\xac\x21\x74\x39\x80\x6a\x8d\xe5\x2f\xcc\x02\xcf\x1d\xe5\x49\xe4\xec\xa3\xe6\x50\xef\x8b\x52\x3d\xe1\x7f\xda\x83\xca\x33\xd6\x53\x36\x6a\x9b\xe5\x46\x20\xa8\x20\x4c\xec\x95\x57\xc0\x95\xa4\x8c\xf4\xee\x94\x1f\x9b\x61\xfe\x92\xed\xb3\xfa\x7c\x89\x59\x82\x18\xc2\x24\x88\x7b\x06\xc8\x4f\xf8\x9f\xd9\xa1\x9d\x5a\x2f\x53\xf9\x64\x46\x65\x51\x76\xdf\xa0\xba\x2d\xca\x1f\xbf\xbe\x8f\xae\x29\xa2\x98\x32\xde\x25\x4a\xcc\xde\x51\xfd\xc2\x6c\x95\xb5\xef\x42\x08\x49\x1b\x7f\xb7\x1a\x58\x67\xdc\xd1\x35\x64\x20\x75\xd0\xbb\x2f\xb7\x66\x5c\x51\x1b\x87\x58\x46\x11\xad\x8f\x9b\xed\x96\xca\x34\x2e\xb9\x1b\x4b\x6d\xdc\x38\x7e\x65\x3a\xa3\x45\xab\x43\x42\x42\xac\xd2\x80\x96\x1e\x55\x6c\x40\x63\xd3\x1d\x7e\x51\x8e\x76\x90\x8a\x18\xbd\x5c\x05\x09\x95\x92\x75\xd1\x04\xf2\xad\x49\xeb\xb0\x11\x06\x89\x29\x2b\xe6\xb6\x4c\x6a\xff\xae\x55\x68\x32\x24\xaf\x59\xdd\x6c\xfe\xed\xdf\x13\x1f\x63\xed\xa4\x2f\x48\x2d\xe2\x02\xe2\x0b\x49\x10\x0b\xd9\xe6\x14\xb6\xc5\x0a\xf2\xf3\xf5\x9a\x4b\x12\xa4\xc6\x4f\x90\x60\xe5\x83\x77\x95\x04\x3c\x24\xfe\xe3\xfa\xfe\x79\xfb\xbc\x21\xb6\x9a\xbb\x8f\xd0\x33\xd6\x9a\xb5\x13\x98\x6c\x6f\x3d\x09\x3d\x23\xb2\xb3\x1b\xd0\x36\x4d\x8d\xab\xaf\x93\x35\x2a\x22\x0d\x7f\x3a\x4c\xbc\xc4\x3e\xa7\x51\x0b\xaa\x8c\xf6\xf8\xe8\x51\x43\x65\x98\xb4\x36\xe5\x4c\xd4\x29\x0a\x80\x9b\x77\xe6\x44\x5b\x21\x89\x42\x89\x89\x25\x72\xce\x87\xf1\xbc\x6b\x91\x72\x9b\x7d\xfb\xf5\x5a\xec\x91\xbc\xdd\x49\x1c\x69\xf8\x7b\x49\x22\x59\xd2\xe9\x54\x6c\x8b\xf5\x29\x7f\xeb\xa7\x6d\x92\x04\x12\xc2\xcc\x0a\xcc\x91\x00\xf6\xe5\x48\x3e\x06\x92\x14\xa4\x33\x47\xb2\x11\x35\xf5\x25\x77\x14\x65\x12\x76\xe8\xf8\x9d\x38\x9d\x77\x3d\xaa\x23\x24\x4c\x05\xb4\xee\x35\x93\x71\x33\x61\xad\x8b\x7a\x73\xdc\xb7\x1b\x6e\xf2\x15\x11\x66\xdd\x68\x82\xb3\x66\xeb\xe6\xa6\xae\x04\xd0\xd8\x41\x90\xa5\x40\xdd\x93\x34\x83\x44\x30\x93\xb1\x25\xc2\xd4\xdd\xe2\xb1\xfd\x7b\xd3\xfb\xbb\x47\xbe\xab\xae\x1a\x2d\xda\x13\x64\x1c\x50\x5c\x63\xc0\x82\xd5\xfd\x5f\x0f\x77\xb3\x51\xc7\x52\xa1\xef\xf4\x3b\x49\x6e\x61\x49\xd1\x83\x3d\x88\x29\x27\x76\xe4\xaf\x56\x19\x80\x9e\xe3\xb6\x28\xb7\x78\x19\x98\xb9\x93\x98\x31\x3e\x35\xb2\xf7\x48\x72\x8b\xb3\xf1\xd7\xd3\xd6\x72\xab\x24\x68\x66\x5d\x9e\x30\xd3\x56\x7a\xc5\x50\x48\x3e\xb2\xbc\x32\x9e\x6a\xe6\x8c\xd4\x8b\x14\xed\xc9\x08\x1e\xb9\x2d\x7a\xd5\xb6\xc9\xdb\x48\xfd\x88\xeb\x2e\x8b\x34\x23\x89\xf8\xe1\xb3\xa7\x64\xe0\xe9\x04\x15\x10\x49\xc3\xae\x17\x15\xa5\xbe\xd2\x66\x0b\x6d\xc1\xb0\x26\x47\xb0\x2e\x8a\xfd\xdc\x35\x09\xa2\x18\xbb\x0a\xc7\xfc\x54\xe6\xf3\xe6\xa6\xab\x4e\xa4\xd3\x35\x8c\x23\x5a\x4f\xaa\x23\xca\xe7\xbe\xa0\x16\xa4\x01\x0b\x4d\x26\xc4\x5a\xed\xdf\x96\xc5\xe1\x5b\x5f\x7a\x7f\xf2\xe3\xa6\xa1\xe7\xbb\x42\xd5\x8d\x59\xa4\xc7\xc1\x42\x1a\x26\x9e\xea\x64\x8d\x1e\xe0\x7d\xf8\x15\xd2\x90\x19\x3f\x4f\xeb\x0a\x51\x9c\x5e\x5e\xff\x76\x1e\x7b\xf4\xba\x43\x0e\xce\x9c\xdb\x5c\xed\xd9\x4e\xa3\x3d\x82\x76\xdb\x54\x12\x3d\xcf\xb2\x32\x5f\x8c\x82\x74\x27\x99\x35\x7a\x06\x85\x14\x4c\xfc\xeb\x5f\xff\xfa\x6d\xc5\xdb\x9e\x12\xc5\x92\x62\xfd\xf5\xd3\x92\x8c\xf0\x96\xdb\xef\xbb\xa7\xd9\xdd\xc6\x65\x88\xd2\x88\xa1\x34\x62\x11\xfd\xfc\x58\x1a\x71\x4e\x53\x0a\xcd\xd6\x6b\xa2\x56\xa0\x9a\x26\xbc\xd9\x33\x62\x3f\xf5\xfb\xca\xfc\x64\x8c\x54\x8e\xc4\xbe\x47\xdf\x2d\xd6\x1e\x45\xd1\x47\x28\xeb\x26\x94\x1c\xc8\x2c\x34\x87\x81\x6a\x73\xc7\xd3\x7e\x3f\x87\x2e\x2f\x62\x0f\x27\x41\x2c\xc1\xd5\xa6\x5f\x9a\x6d\x48\x51\xfe\x16\x13\x07\x69\x33\x15\xb4\xc8\x23\x37\x0b\xae\xb2\x3c\xeb\xc5\x59\x69\xca\x19\x19\x63\x2c\x73\xe5\xea\x43\xee\x08\xfa\x84\x40\xcc\x4c\x36\x64\x83\xa8\x6e\xa1\x3c\x64\xf9\xcb\x6c\x70\xf3\x2c\xf6\xb9\xdf\xa3\xa5\x4c\xe3\xee\x5c\x63\x16\x50\xc0\x50\xe2\x7f\x4e\x59\x89\xea\x5b\xb1\x57\x4e\x9f\xe6\x16\x64\x2b\x50\x0e\x29\x30\x46\xd5\xde\xab\xfe\x92\x97\x60\x50\x48\x45\xc0\xc0\xd9\x64\xef\xea\x57\xdc\xb9\x69\x7c\x57\x1a\x36\xcc\xb1\x5f\x13\x4d\x05\x67\x14\x80\xbd\x17\x35\xae\x8b\xe3\x69\x0f\xe5\xd8\x3b\x1f\x52\xa1\x8d\xb0\x9d\x41\x18\xec\x5e\x7a\xbe\xad\x13\x75\x60\xd6\xaf\x14\xb3\xeb\x86\x30\x90\x4a\x8f\xdb\xe9\x90\x3c\x1d\x4b\x2a\x11\xfc\xd1\x1e\x14\x04\x84\x7c\xfc\xf5\xb0\x13\xa7\x72\xec\xbf\x3d\x7a\xab\xd2\x43\x66\xa3\x3d\x52\x82\xed\xa0\x0b\xed\x53\xc8\xc8\xd0\x01\xbe\x07\xdf\x82\xf6\x47\x62\x1e\x91\x6a\xe4\xf6\xe7\xdf\x1d\x66\xca\x87\x14\xfb\x4c\xc6\xaa\x59\xa6\x8d\x9b\xf8\x78\x14\xab\x50\x12\x78\xe3\x36\xab\x5e\x05\xe4\x6f\x8b\x57\xac\x2e\x1b\x25\x22\xee\x68\x80\x8f\x7b\x63\x7c\x34\x21\x74\x04\xa9\x02\x63\x9e\x7a\xb3\xfc\xb9\xb8\x9f\x6d\x36\xb6\xde\xf0\xf4\xcd\x2d\x96\x29\x82\x26\x41\x98\x77\x03\x75\x79\x3a\xed\xb1\xed\xa6\x3a\x0a\x08\x20\x45\xac\x39\xd2\x4e\x33\x89\xb4\xb1\x53\x05\xa4\x5a\x32\x91\xda\x49\x16\xb2\xfd\xd9\xad\x84\xdd\x5b\x75\x28\x79\x60\x7e\xe4\x93\x4e\xc0\x1a\xca\xb2\xa8\x7b\x31\x2b\xf3\x13\xa3\x58\xd2\xaf\x26\xbb\x43\x60\xec\xab\x4d\x6a\x41\x67\x2f\x8b\x3d\x58\x43\xc2\x41\x2f\xea\xff\xd7\x7d\x48\x16\x04\x29\xd9\x76\x0b\xac\xdd\x8a\xc4\x82\x84\x8b\xc8\x24\x21\xfe\x8b\xf9\x05\xef\x05\x58\xc0\x13\x8a\x22\x76\x94\x88\xc8\xfe\x8b\xcd\x82\x36\x19\xa1\xb3\x30\x84\xc4\x3a\x8c\xdf\xd8\xf2\xf6\xc6\x14\x7b\x87\xd5\xda\x69\x2d\xbb\xe9\x5c\x24\x0b\x93\xc4\xf9\x34\xfe\xb5\xdc\xfc\x2c\x6a\xac\xe6\x67\xeb\x43\x37\x6a\x29\x8c\xd5\x9b\xa8\xcf\x92\xb6\x86\x85\x76\x4f\x19\xa1\x1f\xf5\xc4\xa8\x9f\xf3\xaa\x68\x51\xbe\xb6\x49\x0c\x92\x32\x5c\x90\x57\x1f\xc6\xe5\x15\x3a\xa4\xee\x30\x23\xcc\x62\xe5\x07\x9d\xc6\xf4\xe3\x69\xdc\x35\x59\x8c\x86\x07\xba\x34\xac\xc0\x9e\xa8\xc7\x55\x2c\xe9\xdf\x2a\xb1\xb1\x84\x85\x14\x63\x5a\xf8\xcc\xcf\xe7\xf5\xf4\xb8\x66\x09\x78\x94\xe8\xbb\x59\x2c\x66\xea\xbd\xe9\x48\xbf\x35\xa1\x07\x96\xfa\x68\x2c\xbc\x4c\x0d\xe4\x3b\x65\xe2\xdc\x0b\x4a\x75\x92\x28\x1b\x92\x64\xb0\xb7\xa5\x96\x47\xad\x47\xcf\xce\x78\x22\x6c\xa1\x71\x5d\xb4\xa0\x06\xc6\x43\xa0\x09\xb3\xaa\x8b\xe3\xaf\xa2\x7c\x6b\x05\xbb\xdc\xf1\x94\x13\x2b\x48\x95\x90\x35\x4b\xbb\x7c\x1b\xa7\xef\x5d\x43\x88\x49\x7a\xcf\xea\x9b\xef\xdc\x05\x00\x42\xfa\xc6\x87\xdd\x01\x3e\xfb\x82\xb8\xee\x38\xfa\x61\xd2\x53\xf7\x06\x59\x7f\xb9\xf2\x32\xc1\x35\x85\x90\x73\xd2\x1c\xdd\x1c\x33\x85\xe5\x3f\x4f\xd8\x6e\xfa\x99\x00\x53\xda\x30\xd3\xbb\x95\x20\xbe\xee\xe8\xf5\xf5\x97\x15\xe8\xf9\x9d\xe6\xa6\xb5\xef\xfa\x4d\x27\xb1\xa7\xca\x20\xa2\x02\x90\xb3\xf7\x90\xa7\x76\xee\x62\x92\x4b\xaa\x02\xce\xef\xb6\xab\xe7\x7f\x2d\xdb\x3f\x2b\x33\x77\x36\xd3\x7e\x91\x8f\x09\x06\xb6\x91\xf2\x0c\x39\xf7\xc9\x6c\xf3\x4b\x67\x99\x34\xbe\x9b\xd1\x59\xa1\xe1\xa9\x3e\xe7\xcd\x39\x95\x5d\xd5\xbf\x0e\x38\x98\x4a\x8d\xd5\x78\x56\xdd\x6f\x1e\x6e\xb7\xee\x36\x15\x33\x76\x01\x25\x7c\x5c\x50\x35\xa7\xdf\x05\xb2\x94\x72\x43\x07\xf8\xdc\x89\x36\x68\x66\xa8\x03\x15\x3a\x4f\xc7\xcd\x6b\x56\x2f\xf6\x45\xee\x96\x4c\xa6\xb9\xaf\x3b\x2e\x8d\xcb\x99\x5e\x43\x29\x0c\x1e\x97\x7b\x29\x50\x3a\xf0\xb9\x22\x34\x9c\x59\xcf\xcc\xb9\xb1\xdb\xaa\x73\x0f\xcc\xd6\xd0\x24\x0b\xdc\xaa\x70\x81\x80\xe2\x7e\xe0\x59\xd9\x88\xbc\x26\x6d\xc2\xfe\xe2\xff\x8f\x51\xdb\x28\xa4\x71\x60\x1c\x4a\x40\xec\x7b\xca\x0d\x93\x2f\x99\xfb\x11\xf7\xfd\xfe\x0a\x3c\x3f\xcf\x0b\xe8\x5c\xc5\xfa\x49\x72\x1e\x80\x01\xb6\xd9\xe7\x6a\x9e\xf8\xbe\x80\x96\x6b\x36\x94\x20\x05\x1e\x68\xa9\x93\xae\xb0\x40\xb6\x1a\xee\xfd\xf2\xd0\x07\x60\x2e\xe7\x60\x04\x69\x83\xf6\x58\xe8\x27\x72\x98\xc2\x9d\x0a\xec\x79\xc8\xe2\x24\xed\x82\xba\x61\xa4\xc5\x23\x3f\x10\xaa\x55\x69\x6c\xb1\xf2\xa3\x6b\xc4\x4a\x53\x87\x7e\x78\x1c\xb8\x86\x00\x4f\x64\x12\x3a\x0d\x6f\xea\x03\xcf\x86\x12\x74\x7b\xda\xef\xfb\x85\x5c\xce\x3c\x16\xb7\x25\x96\x99\xb5\x78\xfd\xf5\xda\x25\x7f\x39\xf3\xdb\xc4\xc6\xba\xd8\x67\xf2\x3c\x3f\x6f\xe1\x73\x51\xa8\x49\xf9\x70\xe0\x3c\xf4\x09\x9d\x6c\x9d\x40\xdd\xc0\xe5\x22\x52\xe4\x20\xb0\xac\xcb\xa2\xfb\x63\x6c\x14\xbc\xe8\xe6\x5d\x51\xcf\x2c\x05\x5f\x97\xf4\x48\xba\xca\xfa\x79\x2f\xe0\xf8\x50\xd4\x03\x93\x0c\xe0\x92\x9b\x62\x8a\x95\xb9\x1c\xba\x30\x0e\x2f\x25\x55\x64\x01\xf5\x04\x38\xf9\x81\x65\x8e\xa3\x62\x1d\x57\x5e\x80\x6d\x96\xe9\x96\x62\x0b\xd2\x82\x7d\x28\xea\xde\xdb\x54\x01\x90\xd7\x6b\xb3\x87\xdf\x16\xbf\xb2\x7c\xdb\x33\x48\x70\x6d\x12\x0e\xa9\x1d\x12\xcd\x5c\xd2\xfc\xa7\xab\x69\x73\x95\x26\xce\xac\xf5\xf1\x88\x39\xad\x2a\x24\x07\x39\xab\xeb\x62\xd9\xc2\x78\xb8\x12\x31\x6d\x49\x8e\x3d\x1d\xe5\x47\x3d\xbf\x08\x3d\xb9\x92\x9c\xfa\x2a\xe6\x65\xb1\xdf\x5f\xa6\xd4\x39\xb2\x88\xd0\x39\xc4\xd1\x71\xcc\xad\x71\x13\x1d\xa4\xce\x3f\xeb\x1a\xc7\x7c\xf4\x56\x51\x2a\x12\x1f\x9a\x67\xa4\xdc\x81\x6a\x1a\x26\xd6\x1f\x74\xe0\xb1\xc8\xe6\xe4\x6b\x1a\xc8\x13\x32\xa4\x00\x9e\x36\x2c\xcf\x23\x96\xba\x28\x0f\x4f\x68\xe5\xa6\xa8\x20\x39\xb9\xcb\xb8\x1a\x9b\xf4\xf6\x4b\xe0\xa7\x5c\x71\x13\x17\x92\x61\x59\x71\xca\xd5\x7d\x51\x61\x59\xdd\xf6\xa2\x06\x08\xfd\xc8\xd7\x6d\xcd\x92\xb4\x3a\xd4\x79\xba\x63\x41\xe8\x0b\xdf\xd2\x2e\xcb\xce\xe1\x08\x20\x14\x9a\xd2\xf3\xc6\x68\x6f\x6e\xf4\x2c\x87\xaf\x1c\x42\x4c\xa8\x86\x88\x87\x63\x7d\xde\x16\xa3\xa3\x91\x08\xa9\xd4\xdf\x42\x52\xee\xd4\x34\x5b\x04\xe2\x20\xa0\x30\xf0\x36\xab\xca\x7a\xa8\xa8\x3f\xba\xdb\x58\x84\x16\xa5\xf9\x39\x3f\x9d\xfb\x99\x01\x88\xa5\xd2\x76\xd7\x6d\x64\xa1\xfa\x9c\x1d\x3b\xc1\x42\x12\x86\xc2\xa4\x0f\xcc\x64\xe9\x86\x22\x24\x89\x11\xda\xa9\xa1\x34\x6e\x20\xb4\x1c\x51\x6e\xdf\xf7\xda\x46\xcc\x20\x02\x8e\xaf\x50\x61\x30\x74\x61\x00\x48\xc3\x14\x3b\x83\xac\xe6\x5d\xf6\xa7\x3b\x60\x68\x9c\x3d\x7e\x21\x1c\x8b\x7c\xa8\xce\x05\xd0\x04\xfc\x92\xf2\x89\x45\x79\x96\x9d\x89\x37\x00\x97\x31\x65\x6d\x76\xa0\xd4\x2a\xcb\xa9\x54\x76\xb1\xf5\x70\x38\x66\xe0\xd2\x80\x8b\x5c\x1d\xc0\xca\x65\xb9\x8b\x01\x60\xd2\x2e\x0a\xd5\x6d\x51\xba\x52\xfc\x2c\x57\xbd\x92\x3b\x80\x48\x7a\x6a\x2f\xdb\x66\xbf\x7f\x2a\xaf\x7d\x14\x90\xc6\xc7\xdb\x4c\x8a\x56\xc0\xf0\x3a\x86\x6d\x72\x1f\x3e\xfc\xa7\xbb\xb6\x08\x02\xca\xc4\x88\x22\x3f\x55\xab\x66\xb3\x6c\x20\xfa\x77\xf9\x40\xd3\x1b\x40\x80\x47\x62\x6b\xcb\xb2\x2c\x4a\x9b\x79\x6c\xb3\x13\x20\x54\x48\x6e\xa1\xc6\xa6\xb9\x2f\xae\xde\xdb\xe2\x83\xf2\x81\x32\xf8\x54\xea\xd8\x50\x29\x66\x82\x55\x00\x2a\xf5\x5c\xb0\xdd\x04\x1f\x04\x04\x76\xe9\x0e\xb7\x6a\x00\x62\xa8\x0d\xa4\xd7\x6e\x05\xfa\x1f\x2d\x89\xfe\x27\xf8\xdf\xde\xff\x1a\xfd\xc9\x5e\x42\x7b\xe0\x29\x63\x9b\xe1\x9c\xb0\x7a\xb3\x30\x68\xc1\x9c\x68\xf6\x03\x7e\xac\xe0\x73\xb8\x0b\x1f\xbd\x48\xad\x7c\xe2\xda\xdf\x16\xd5\x2b\xfc\x5d\xd9\x0c\x73\xae\xf0\xac\xbc\xf8\xe3\xb7\x75\xbf\x4b\x0b\x8f\x03\x55\x43\xf7\x59\x45\xc2\x74\x55\x67\x34\x01\xc2\x8f\x8d\xc6\xa0\xb1\x3c\xe9\xde\xb2\x08\x2c\x71\x60\xb3\x5a\xfe\x2d\xa6\x9f\x3b\x8d\x99\x3a\x8d\x49\x59\x0e\xc0\x38\x22\x4c\x0c\xb6\x63\x7e\x2a\xf3\xdf\x78\x35\x81\x08\x99\xb1\x03\x33\x7d\x7b\x99\xab\x0b\xbd\x33\x10\xa1\x8c\x29\xb4\xf9\x71\xf7\xf0\x6d\xf7\xeb\xee\x61\xb7\x7a\xbe\xdf\xde\xad\xef\x97\xbb\x75\x0b\x30\x14\x11\x0f\x69\x73\x66\xf1\x0a\xcd\x0a\xe2\x0e\xc5\x42\x52\x79\xcc\x0d\x43\x1c\x6e\x7c\x45\xea\x07\xce\xe7\xc2\xe8\x05\x4d\x0f\x2d\x91\x26\x31\x25\x2f\xc5\x69\xdf\xae\x69\x34\x11\x9b\xce\xd4\xd9\xa1\xfd\xe3\x6a\xc9\x4a\xb0\x34\xd0\x5e\xcb\x03\x98\xf7\x44\x87\xd7\x72\xd4\xb5\x05\x13\x8a\xa6\x8f\xf5\xe3\xe3\xf7\xdd\xf6\x71\xb7\x98\xdd\xdf\xef\xfc\xf5\xfd\xf3\x6a\xde\x3d\x37\x0f\x04\x45\x07\xeb\xe5\xfa\xbe\xfd\x1b\x00\xad\xa4\xab\xd9\x9f\xbb\xa7\xe5\xcf\xe5\xc3\xf3\xb2\x3d\x84\x22\x8a\x3b\x5b\xb1\x36\x85\x3f\x2c\x7c\x4f\x06\xfa\x02\x02\x33\x04\x54\x91\x37\xc3\xf9\x52\x2b\x18\x04\x30\x4e\xf3\xa3\x0d\xa2\x86\x36\xd2\x20\x1c\x1d\xaf\x19\xac\xb2\xce\xde\xd1\x78\x3b\xb5\x47\x8d\x89\x29\x09\xe7\xaf\xa0\x19\x62\x83\xc4\xbf\x10\x11\xc4\x5e\x47\x89\x6b\xe9\xf4\x20\x44\xec\x13\x1e\x63\xe7\xac\x4e\xb6\x50\xbd\x4d\x0f\x3e\x21\x43\x4d\xc9\x2c\x45\x92\x1f\xab\x2c\xaf\x67\x2f\xdd\xdc\x25\x54\x28\x1c\xd0\xe7\x57\xf6\x1b\xe5\x36\x10\x3a\x34\x46\xdc\xb2\xc8\x75\x56\x1e\xbe\x28\xdd\x8f\x4f\x14\x9a\xd4\x0b\x08\x2a\x69\xf4\xb6\x47\x8c\x24\xd3\x50\x7a\xcc\xa8\x35\x50\x16\xec\x36\x23\xf0\xda\x64\xff\x94\x9e\xd0\x54\x94\xae\x7b\xe8\xc7\xcd\x39\xaf\x5f\xb1\xce\x3e\xc7\x57\xd5\x48\x45\xf1\xf9\xf3\x5f\xcb\xa7\xdd\x66\xbb\x5c\xef\xe2\xdd\x62\xf6\xb0\x58\xde\x0f\x37\x16\x32\x48\x14\x4d\xfa\x48\x92\x5a\x38\x53\xca\x08\x5a\x8d\xfd\x23\x5d\x73\xee\xa1\x9d\x08\x6f\xb3\xb2\xaa\x5b\x15\xc9\xf6\xb8\xa0\x40\xe4\x76\xee\xba\xb0\x0c\xc1\x27\x80\xf9\xf7\xfb\x85\x2b\xd2\xca\x28\x55\x82\x9c\x12\xf7\xc5\x49\x89\x32\x23\xbf\xd7\xe9\x34\x85\x8c\x54\xcc\x82\x56\xe7\xd9\x58\xe5\x0f\x6f\x2a\x52\x3c\x95\xed\xf6\xd6\x42\x14\x17\x50\xaa\xc1\xea\xdd\x32\x95\xdc\x59\xe8\x51\xd4\xa5\xce\xf9\xac\x2c\x81\xd0\x31\x7f\x0c\xc7\xb3\x8c\x34\xa3\xce\xb4\x69\x02\xdd\x51\x69\x42\xc6\x9e\x97\x38\xd4\x43\x66\xea\xfa\xa7\xfc\xda\xa2\x20\x63\x4f\x13\xb3\xbf\xca\xfe\x8b\x8f\xba\xb7\xeb\xc4\xee\x82\x91\x32\xa5\xf5\xba\x38\xae\x4b\xbc\x93\xc5\x2c\x57\xcd\x3c\xdb\x35\x40\x62\x39\x1f\x8b\xaa\xe9\xd8\xed\x9f\xb9\x52\x56\xe4\xfc\x4e\x16\x6b\x28\x81\x6c\xd3\xaa\x4d\xb3\x51\x6f\x17\x03\x19\x2b\x41\x19\x98\x43\x0b\x8a\x93\x89\xe7\x53\x37\x3d\xe2\xf1\x16\xca\x4b\x89\xcc\x2f\x67\x77\x99\x04\x5e\xec\xf2\xa1\x50\xc3\xba\x68\xee\x69\x34\x9e\x28\xde\xee\x07\xf5\x32\x61\x3a\xb5\xd8\xa7\x39\x56\xcd\xab\x53\x63\xf0\x84\x4c\xd3\x94\xd2\x19\xcb\xe5\xed\x49\xbe\x55\xfd\x95\x50\xb2\x94\x11\x0a\x99\x04\xf6\xdc\x44\x7d\x83\x32\x3b\x40\x67\xf4\x72\x39\x37\x4b\x9e\x28\xcd\xc6\x92\x95\x48\x9a\x22\x7d\x87\xdc\xa1\x8e\x3e\x48\xce\x18\x21\x89\x36\xdf\x16\x0b\x77\x0b\x24\x14\x47\x40\xe3\x12\xce\x46\x55\x44\xf7\xce\x9f\xee\xc7\x8a\x99\x0a\x6c\xb3\x07\xc4\xb2\x1d\x31\x8a\x61\x04\x6d\x84\x83\x83\x15\x72\xf4\xbe\x95\x8e\x02\xe1\x7e\xf6\x51\x3f\x14\xf9\xb6\xcc\xde\x33\xd8\xdb\x8c\xce\x78\x5c\x60\xa2\xa4\x53\xdc\xb6\x0e\xf6\xc6\xeb\xe3\xa2\x4e\xd4\x75\x12\x4c\x95\x8b\x74\xee\xa1\xaa\x17\x90\x2b\xe2\x49\xb4\x9d\x54\xc7\xd2\x66\xb2\x9a\x3e\xfc\xe3\xaf\x05\xa1\xf5\x32\x54\xa3\x29\x48\x0b\x46\x19\xb8\x7f\x65\x2f\x2f\x03\x11\x0e\x50\x9e\x67\xa6\xf3\x03\xd6\xb0\xff\x28\xca\xb7\x6a\x31\x01\x00\x53\x5e\xa8\x69\xf2\xfd\x36\xdf\x0e\x47\x9e\xf2\x54\x42\x9b\xfd\x1d\x11\x68\x1f\xf0\xc3\xa8\xf4\x0c\x6e\x40\xf9\x81\xf1\x2d\x93\x86\x9f\x7e\x8d\x77\xfc\xe5\x3c\xde\x44\xa9\x06\xca\x67\x4c\xb0\x40\xf5\xd2\x3e\xca\xd7\x48\xb0\xd0\x1e\x36\x4e\x05\x49\xe2\xfb\x6d\x2f\x1b\xab\xa0\x83\x0a\xc0\x78\x41\x8a\x53\xb6\x57\xd3\x6b\x82\x0a\x23\xa0\xbd\xfc\x7c\x76\x77\xbf\x19\xc4\x6d\x6d\x03\x05\xb6\xba\x6c\xd4\x1d\x9b\x40\x6d\x40\xe4\x53\x61\xac\x88\x61\xb2\x58\x3d\xb6\x7f\x62\x98\xb4\xda\x3e\x87\xec\x2a\x37\xd6\x35\xd7\x2d\x01\xdd\x52\xfc\x47\x5f\x21\x0a\x21\xb6\x58\xe1\xa7\x66\xde\x5d\x3c\x8e\x6e\x33\x8a\xfc\xd4\x02\x0a\x7e\x16\xfb\xd3\x01\x05\x54\x16\x77\x7b\xa1\x08\x05\x2a\xe2\x01\xc5\x2e\xb7\x27\xc2\xd1\xd9\xfc\xbb\xad\x84\xd8\x36\xb1\x87\x34\xf0\xb2\x56\x98\x7e\x99\xd7\xe5\xf9\x2e\xd7\x6d\x0e\x49\xc5\x22\x24\x94\xbc\x01\x38\x8f\xee\x39\xf1\xd0\x60\x36\x4f\x82\x78\x44\xf9\x14\x97\x48\x25\x2a\x72\x1e\x49\xf7\xb4\x17\x18\x1d\x4f\xad\x09\xf0\x8f\xe2\xad\xfb\xdd\x14\x90\xd6\xb4\x79\x56\x57\xa7\xc3\x02\x2a\x97\x9b\x51\xcc\x0b\xc9\x22\xec\xc3\x0a\xa4\xd3\x36\x30\x74\x47\x79\x1c\x5a\x95\xec\x5a\xbe\x9a\x14\xe1\x17\xd3\x98\xe2\x31\xa3\x32\x40\x26\x8b\xe7\x3c\xab\xfb\xd9\x3b\x05\x3c\x42\xcf\x95\xe7\x6a\xb8\xeb\x7a\x7d\x7f\x4a\x53\x20\x8d\xce\x1a\x6d\x17\x36\x35\x3a\xdd\x24\x50\x32\x49\xa9\xec\xf9\x0b\xf6\x75\x36\x00\xb5\x2a\x89\x9a\x42\xf9\x23\x9c\x5b\x28\xdb\xe8\x0b\x2a\x91\x24\x2d\x48\x90\x54\xf5\xdd\x01\x99\x44\xc6\x56\x00\xdf\x9c\x12\x69\x2f\x55\xa0\x30\x91\xf4\xc9\x2c\xe4\x85\x64\xa9\x4c\x22\xcb\xa5\x51\x15\x32\xa0\xf2\x35\xe5\x3f\x26\x1c\x43\x40\x21\x17\x24\x66\xd8\xee\xb7\xeb\xa2\x94\xed\x37\xd0\x61\x40\xc2\x13\x7b\xc4\xb7\x4d\x8d\xb0\x7f\xcc\x5d\x65\x05\x3d\x4f\x46\x24\xb7\xfd\x0a\x25\x3e\x15\xc5\xe1\x66\xb6\x6d\x81\x41\x83\x57\x87\x5e\x12\x51\xc5\x9b\x22\xd1\x53\x8d\x4f\xc5\x7e\x7f\x81\x7c\x46\x3f\x0d\x48\xfe\x89\x08\xbc\xa5\x51\x30\x1b\xdc\x2c\x06\x81\x11\xe0\x34\x15\xee\xd4\xdd\x49\xc8\x62\x82\x3a\x81\x94\x4d\x00\xd0\x62\x9d\x30\xf2\x43\xe8\x36\x52\xbf\x50\xc0\xf1\x78\x45\x35\xc9\x9d\x11\x73\xda\x56\x35\xdb\x99\x55\x0f\x41\x77\xd9\xa5\x30\xd2\x68\xe4\xca\x9d\x3e\xeb\x97\x13\x03\x26\xbe\x29\x50\x19\x2d\x56\xb2\x55\xba\xb0\x3d\x18\x9d\xc1\x03\x4a\x7c\xed\x40\xa9\x35\x9c\xaf\x38\xcc\x03\x26\x22\x8a\x2d\x0b\xf4\xbe\x90\x6f\xa7\xe3\xe8\xbd\xa6\x49\x9a\xf6\x10\x5f\x7d\xf7\x4d\x40\xe6\x03\x5a\x55\x66\x12\x6b\x0d\x9b\x95\x94\x7a\x5b\x9b\xc0\xe8\x50\x37\xc8\x62\x63\xf2\x4e\x0b\x27\x39\xa9\x8f\x7a\x33\xb2\x18\x3d\x63\x21\x6b\x5f\xf4\x43\x51\x1b\x19\x8e\xe9\x17\xce\x74\x44\xec\x84\x5f\x28\x7a\xc5\x6e\x64\x1a\x29\x57\xf6\x80\x35\x94\x78\x3a\xf4\x07\x15\x72\x44\x4a\xc6\x56\x21\xef\xab\x3d\x01\x42\xac\xc9\x75\xd9\x8e\x88\x5d\xd5\x2f\xf5\x21\x24\xa6\xe8\x45\x2c\x6d\xe7\x39\x94\x63\x75\xb9\x9d\x19\xde\x22\xa0\x26\xde\x4b\x96\xbf\x62\x99\xd5\xa8\x7e\x66\x2d\xcb\x07\x85\x2f\x29\xb4\x3f\x38\x0b\x9b\xc5\x2b\xe4\x39\x8e\x6b\x38\x28\x84\xa0\xc4\x68\x75\x12\xcf\x77\xf9\xd0\xbb\x74\xf4\x3d\x85\x4c\x88\xd0\xfe\x33\xdb\xef\xff\xdd\xfe\x8e\xd6\x94\xe3\xdf\x4b\xf9\x49\xca\x32\x83\x19\x1a\x65\x94\x8a\x68\xc8\xbd\x32\x1b\xb8\xe1\xa5\x25\x0b\x84\x65\xdc\x13\x75\x74\x9d\x1d\x47\x4b\x2d\x4a\x1e\x4b\x39\x70\xd8\x34\x42\xee\x45\x79\x01\xf9\xb4\x67\x28\x19\x30\x23\xe2\x5c\x96\x19\xbc\xe0\x6f\x55\x24\x06\x73\x83\xc2\x58\x12\x5d\x6f\x5f\x08\x93\xc4\xff\x09\xa7\xbd\x8b\xd2\x51\x69\x9f\xe6\x27\x4b\xe5\x9b\x9a\x15\x10\x25\x85\xc6\xbb\x8a\x08\x99\x6f\x59\xfe\xb2\x3c\x16\xf2\xf5\xe6\x64\xd1\x73\xc3\x77\xa0\xd1\x80\x25\x6a\xac\x6a\xcf\xef\xb9\x24\xb7\x99\x5a\xed\x45\x40\x74\xd7\x1c\x3f\xdc\xc3\x0c\xdf\xb7\xf6\xb5\xd2\x69\x8f\xb0\x3f\x81\x51\xe2\xf6\x07\x75\xa0\x80\xf6\x30\xcd\x0f\xfe\xc0\x33\xaa\xef\xdd\x2a\xa7\x23\x3f\x0e\x9d\x6f\xd2\xab\x83\x1f\xb4\x07\x83\x80\xd0\xc1\x4f\x9b\xf5\xfd\x76\xf7\xdd\xfd\x39\x0e\xcd\xa6\x68\x05\x26\xdb\x15\xb4\x07\x98\x62\xae\x9e\x99\x8d\x9e\x5b\x27\xa1\x47\x6f\xf2\x66\xf6\xf4\xe3\xe1\xf1\x66\xb9\xbb\x5d\x2e\x37\xbb\x9b\xe5\xc3\xe3\xea\xee\x61\xb6\x7d\x74\x5b\x4f\x9d\x08\x2f\xd1\xce\x2b\xe1\xb3\xb6\xc5\x8c\xed\x76\x45\x3f\x76\xa7\xf8\x40\xe8\x44\x27\x98\x50\x28\x6e\x2a\x78\x6d\xda\x78\xf0\x8d\x74\xca\xac\x96\x71\x13\x78\xfd\x42\x7c\xbb\x2d\x4e\x2e\xea\xd2\x29\xf7\x29\x33\x4a\x2b\xeb\x5d\xfe\x0b\xb3\xd1\xad\xa7\x4a\x08\xc3\x43\xcf\x15\x2d\xdd\x16\x15\xbc\x2d\x8c\xda\x65\xeb\x87\x38\x3c\x8d\xf9\xc6\x64\x76\x77\xc8\xf2\x7a\xca\xb8\x02\x34\xf7\x53\xce\x5d\xe5\xae\x55\x4c\x70\x49\x77\x0d\x5e\xc8\xac\xb4\x75\xe7\xea\xd3\x4f\xea\x6b\x48\x05\xd5\x7d\xea\xa2\xd5\xc5\x03\x2d\xa2\x30\xd2\x4e\xf7\xa6\xd9\x91\xf6\x2c\x81\x86\xef\x45\xf0\x80\xe0\x3e\x2b\xc4\x63\x6f\xfe\xd3\x42\x79\x74\x05\xa7\x58\xe7\xfe\x2e\xc3\x88\x82\x43\x12\xd3\x20\x90\x68\xeb\x5b\x02\x1a\xd3\x48\x3a\x17\x8a\x5d\x91\x23\x95\x44\x97\xcd\xd2\x3f\xea\xbd\x08\x8a\x70\xa4\xb6\x74\x42\x0b\x42\x4b\x64\xd2\xda\x07\xe2\x6d\x6c\xef\x96\x4f\xc1\x6e\xfd\x74\xb7\x58\xb6\x87\x94\x0c\xb9\xfd\xf9\x65\xae\x3a\xdf\x2b\xd0\x1a\x3d\xc2\x45\x2c\xb2\x52\x12\x29\xfd\x0d\x73\x5a\xe5\xc6\xba\x0c\xff\x57\x85\x5f\xe1\x79\x01\x13\xbc\x07\x1c\xa4\x59\xfd\x2e\xbf\x2d\x41\xfe\xe1\x9a\xa4\x48\xef\x6b\x5f\xbc\x18\xe1\xfc\x56\x2b\x8f\x14\x69\x94\x6b\xe7\xc7\x8c\xf7\x6c\x22\x8c\xa4\x75\x57\x79\xef\x7d\x5a\xe1\xf9\xcd\xb6\xcd\x2d\x76\x58\x6e\x8b\x09\x7a\xaf\xf0\x82\x30\x26\xd4\x5d\xbd\x07\x77\x62\xc8\x52\x82\xe0\xcf\x4a\xf9\x8a\xf5\xf9\xe8\xe0\x2c\xc2\x0b\x51\x11\x31\x5f\xee\x11\x8c\x0b\xba\x3b\x12\xf9\x8a\x22\xb5\xcd\xf2\xe7\xf2\x61\xfb\xe0\x1c\x9c\x84\x17\x69\xdf\x77\xf2\xe5\x3b\x7d\x85\xc4\x28\xbc\xc4\x57\x69\x47\xf4\x7a\xc2\x66\xa0\xb5\x9b\x62\x9b\xb7\x12\x5e\x12\x47\x04\xb7\x59\x42\xd9\xbc\x41\x53\x58\x37\xdf\xaa\xb2\x3e\xff\x5f\xe1\x85\x85\x97\x30\x24\x31\x46\xeb\x57\xf5\xab\xd9\x86\x4e\x22\x72\x84\x97\x70\x03\x6b\xad\xe4\x2b\xaa\xd3\x1e\x07\x96\x80\x03\x82\xc5\x90\x94\xe7\x4e\x6f\xfa\xb3\x35\xa8\x90\xc5\xe6\x5c\xd5\x78\xe8\x67\x3e\x85\x97\xc8\x90\xb6\x35\x4e\x0d\xe1\x0a\x3a\xe6\xeb\xbe\x95\x20\x50\x66\xd3\x61\xb2\x7e\x83\x86\x12\x5e\x1a\x19\xf2\x6c\x56\x39\xe2\xf1\x1f\xc3\x2b\x32\x60\x64\x89\xb2\xbc\x79\xde\x3e\x3f\x3d\xb8\xbb\x65\xda\x90\xd7\xa4\xe1\xfe\xdd\x16\xe5\xba\xcc\x8a\x32\xab\x9b\x4e\x1a\x5c\xc6\x99\x5f\x6e\xb5\x2f\xd0\x72\xf6\x47\xb8\x9f\x38\x4b\x3d\xd3\xb5\x27\xa3\x2e\xe1\xf1\xd4\x64\xff\x7f\xfc\x78\xfc\xd6\x5b\x71\x84\x27\xb4\xa4\xe9\xac\x89\x6d\x67\xb9\x6a\x05\x8d\xc7\x37\x35\x78\x25\x32\x0e\x53\xd1\x23\x81\x39\xf3\xc5\x76\xd4\x49\x1e\x92\x66\xe4\x1e\xaa\xfa\xc6\x71\x5b\x9b\x3f\x2b\xda\x16\x74\xca\x4e\xb3\xf6\x90\x00\x27\x83\xf8\x9c\x67\xff\xe9\x56\x4c\xe1\x49\x19\x93\x2a\xc7\xee\x26\xd3\x3a\x93\xa7\x7d\x7d\x5e\xc0\x9e\xea\xb7\x7f\x5c\x66\x2c\x85\xa7\xbc\xd0\x61\x01\x0c\x0c\xa7\xef\x5c\x36\x1a\x45\x4a\x71\x4f\xbb\xbd\xf7\x15\xa3\x25\xe1\x29\x2d\x3a\x0f\xf0\x5c\xdd\xa0\x36\xc0\x88\xd3\x18\x5c\x29\x3c\x04\xf3\x88\xd9\x49\xe1\xe7\x9d\xda\x16\xc6\x46\xec\x8f\xe1\x67\xd3\x5e\x80\xad\x52\x95\xf3\x04\xef\xa8\xb4\xc2\xd3\x3e\xeb\x41\x0b\x17\x85\x36\xbb\xe1\xd9\xa8\xeb\xe9\xc4\x70\x3b\xb2\x5c\x6d\x10\x95\x33\xa3\x31\x47\x7d\x8f\x1b\xa8\xf4\xec\xe6\xe7\x6e\xbe\xfd\x6b\xb7\x79\x5e\xaf\x9d\x7b\xa2\xf0\x7d\xc9\x68\x02\x79\x42\xd8\x2f\xab\x1a\x6a\x5c\x94\xe7\x63\x5d\xdc\x9e\x72\x65\xb7\x0c\x83\x1f\xf3\x7d\x05\xb4\x55\x5a\x6d\xff\xea\x77\x21\x3f\x60\x22\xd0\x1d\x10\xa4\x99\x88\xc7\x31\xa3\xf0\x03\x48\x85\x31\xbd\x3c\x37\x3f\x78\xf8\xb2\xa2\x20\xfc\x50\x03\x35\xdf\x40\x13\xb5\x0f\x7e\x2e\xf2\x58\x1c\xb9\x15\xfc\x57\x96\xf7\x74\x3d\x85\x1f\x05\x09\x44\x6d\xdd\x82\xca\x58\xc3\x0b\x47\x1c\xc0\x08\xed\x9d\x8f\x35\x54\x55\x56\xb5\xaf\x2b\x52\xda\xf8\x14\xac\x97\xcb\x9b\xdd\x66\x3b\xdb\xee\x56\xb3\x3f\xdb\xa3\x08\x54\x23\x9c\x6d\x7e\x34\xc7\x7e\x2c\x77\x4f\xb3\xed\xdd\xa3\x3b\x1c\x87\x21\x41\xe5\x9d\x52\x60\x4b\x17\x9b\x40\xfb\x08\x3f\x96\x51\xda\x6a\x05\xb5\x8a\xd6\xd3\x7d\xd4\x4f\x99\x4f\xc5\xdd\xe5\x01\x4b\x43\x48\x69\x0f\x24\x91\x91\x96\x3c\x1c\x4e\x79\x56\x9f\xd7\x7d\x49\xcf\xe1\xfb\x4f\x59\x42\xa4\x1c\x49\xfe\x2a\x8b\xa2\x7b\xec\x94\x09\x52\x62\x79\x98\xcf\xba\x80\xa4\xf9\xb3\x26\x11\xb4\x63\x51\xec\x89\xbb\xef\x0e\x70\x0f\xd1\x44\x30\x07\x7c\xc0\xfa\xa3\x28\xbf\x50\x9d\x13\x3e\x8f\x80\xa2\xc5\xd9\xfd\xfd\xe3\xa2\x79\x63\x0f\xbb\xfb\xc7\xc5\x8f\xdd\xf2\xe1\x66\xb7\xbd\x5b\x2d\x37\xdb\xd9\x6a\xdd\x5e\x3b\xf5\x68\xff\xbe\x7d\xc5\xfe\xbd\x70\x1e\xf5\x64\xd2\x57\x50\xbd\x7d\x5d\x91\x12\x3e\x47\xa3\x99\x4a\x45\x32\xda\xa6\xf5\x51\xa0\xc2\x07\xc9\x3d\x47\xab\xfe\xf3\x7e\x5d\x16\x47\x2c\xeb\xf3\x64\xa2\x51\xf8\xa0\xd3\xd8\x45\xa3\xd3\xb3\xec\xe8\xd7\x45\xc8\x29\xe8\x58\xbc\x96\x45\x5e\x18\xc9\x8b\x75\x41\x78\xe2\xee\xa1\x44\xc2\xa0\x19\x4e\xcf\x4f\xab\xf9\x17\xab\xd0\xe8\x3b\x0a\xad\x42\x27\x1b\x7a\xca\xd5\x14\xb1\x5b\xf8\x92\x25\xda\xdd\xf0\xbc\xd9\xfc\x9e\x8e\xe3\x16\xc2\xa8\x90\x93\x05\x17\x81\x18\xae\x2e\xa3\x5f\xaf\xaa\x57\xb0\xdc\x83\xd7\xa1\x2c\xaf\x19\xeb\x57\x1b\x53\x6d\x3e\xe0\xf8\x78\xaa\x8f\xa7\xe9\x32\x90\xf0\x15\x84\xc9\x60\x1c\x5f\xb8\x4f\x0a\x1f\xbd\x88\xe0\x2b\x64\x74\xb9\x76\xb4\xe2\x71\xa3\xd8\x6c\x56\xe4\x6b\x13\x4a\xe4\x2f\xd8\x5c\x2e\xcb\x5f\xac\x61\xde\x60\x47\xee\x56\x10\x5f\xc7\xbe\x91\x79\x81\x37\x24\x00\xbf\x89\x9c\x46\x97\xd6\x29\xa3\xba\xc1\xbf\x8b\x2c\xdf\xfc\xa7\x1c\x1f\x15\x5a\x09\xfb\x0d\x9a\x78\xf3\x92\x7e\x32\x7e\xa3\xc3\x10\xa9\x03\x59\x09\x5f\x23\xa2\x4d\x64\xef\x0e\xe7\x5d\x95\x59\xc3\x0a\x11\xf8\x01\x27\x2c\x7f\xa1\xaf\xd9\x97\x88\xc0\x8f\x18\x99\x44\xde\xe0\xfe\xf4\x59\xb4\x67\x42\x42\xf3\x19\x6d\xd0\x6e\xb2\x4a\x9c\xca\x0a\x3b\x0f\x53\x11\x04\x29\x10\x15\x82\x4a\xae\xae\x30\xb2\x86\xb2\xde\x7e\x14\xc3\x08\x70\x08\x0c\xfb\xbb\x80\xe7\x41\xed\xcb\xfe\x66\x18\xa4\xca\x6c\x0c\xf1\x3d\xb3\x6e\x19\x0e\x0e\xe1\x9a\xc4\x3e\xb1\x7a\x1c\x82\x96\xe4\x6e\xbe\x2c\x33\x37\xe7\x08\x52\x7a\x30\xc8\xe5\x79\xc7\xec\x1c\x8e\x8a\x20\x4c\x8c\x44\x6c\x55\xec\xc9\x66\xcc\xf4\x98\xe1\xda\x1d\x44\x8a\x11\xaa\xcf\xc4\xa6\x36\x88\xb6\xc7\xe2\x40\x58\xe5\x48\x23\xd0\x32\x88\x5f\x83\x38\xd1\x94\x65\xb8\x99\x3d\x6e\x50\x9e\x88\x29\x74\x51\x63\xba\x1a\x27\x3b\xca\x88\x08\x62\x9e\x70\x1b\xb3\x11\xaf\xd0\x5d\x3f\x09\x4d\x0e\x8d\x4a\x7e\x16\x48\xba\x30\x42\x9b\xae\x49\xea\x79\xa4\x92\xb5\x28\xca\x63\xd1\xe7\x1a\x8a\x20\xe5\x1e\x77\x32\x4a\x75\x71\xbc\x2f\xe4\x5b\xff\xbd\xa7\x02\xb9\xc1\xb9\x9d\x8b\x52\x76\xf3\x58\xd0\xac\x4e\xed\x7a\x6c\x93\x47\xcf\xc7\xf6\xa8\x4a\x69\x9b\x43\x83\xb4\xc5\x40\xba\x83\x9a\x85\x76\x94\xaf\xf1\xe5\xc5\x42\x52\x06\x1e\x99\xc3\xe9\x2f\xe0\x4c\x69\xab\x0d\xda\x76\xd8\x6a\xf4\x15\x21\x48\x88\x4e\xf6\x91\xe5\xf3\x32\x93\x6f\xc6\xc8\xc3\xfd\x26\xa4\x29\x65\x71\x97\xb9\x8a\xdb\xbf\xb1\x44\x18\x8d\xac\xe2\x38\x58\xcb\x6c\xee\x57\x04\x20\x25\x98\x05\xfb\xe6\x69\x3d\x1c\xe9\x01\x60\x40\x8b\xd6\x43\x51\x67\xfa\xbc\xb3\x01\xdf\xc4\x56\x22\x10\xcd\xee\xbf\xdd\x86\x6f\x8b\x53\x99\x43\x7f\xc8\x49\x4f\xc7\x71\x5b\x15\xa3\x62\xda\x68\xb3\x11\x48\xdf\xe0\xa4\x67\x07\xa8\xf1\x54\xae\xf7\x50\x67\xf9\x20\x5d\x2a\x02\xa9\xd2\xd8\x2e\x7e\xdf\x8e\x2f\x3f\x9c\xcf\x9f\x08\x24\x46\x94\x10\xad\x6a\x78\xc3\xdb\xa2\x6c\x13\x66\x5f\x4e\x49\xed\xc9\xa9\xf6\x3b\x87\x73\xab\x75\xd1\x1b\xbc\x8a\xc7\xca\x7e\x4d\x43\x28\x1f\xe6\xc8\x6c\x2b\xfc\xff\xa4\xfd\x59\x73\xa3\x48\xf6\x3e\x8e\xbf\x9d\xbe\x98\x0b\x48\x20\x49\x2e\x65\x59\xb6\x35\x6d\x5b\x1e\x49\xd5\xd5\xfd\xfb\xc4\x84\x22\x97\x93\x16\x63\x04\x1a\x40\xb6\x35\xaf\xfe\x1f\x9c\x5c\x58\x24\xbb\xfa\x1b\xff\xe8\x88\xae\x2a\x91\x6c\x49\x2e\x67\x79\xce\xf3\x44\xd4\x6a\x4c\x95\x86\xe4\xc8\xc1\xa7\xb7\xfc\x0d\x66\xcd\x9a\xbf\xf9\x21\x07\xd2\x18\xe7\xbb\x6e\xf1\x05\x75\x5b\x7d\xfc\x3d\x64\x96\x20\xa0\x42\x19\x58\x7e\xc2\x3b\x99\x7f\xb1\x30\xea\x98\x46\xbe\xbc\x11\x89\xa7\xe0\x74\x18\x71\x9c\x08\xa2\x69\x22\x8c\xd6\xcb\x15\x7e\xea\xee\x30\xd3\x89\xaf\xc7\x5e\xfc\x97\x10\xb3\x5a\x10\xbb\x34\x12\xb7\x6a\xe8\x34\x92\x76\x65\x5b\xce\x57\x8f\xa0\x5e\xfb\x69\xa0\x39\xc5\x08\x6c\xe7\x2d\x61\x8e\x72\xf7\x9e\x76\x0e\xd0\xce\x3e\x6e\xdf\x4e\x3b\x6a\x20\xf4\x8f\x26\x6f\xa3\x0c\xe6\x44\xf2\x16\xb9\x79\xc7\x87\xa3\x20\x22\xd2\xc9\x4d\xe4\xe5\x6b\x01\xf7\x27\x68\x9a\xcb\x6d\x35\x0a\x98\x29\xff\x6f\x4e\xa2\x1b\xa1\x77\x35\xc0\xff\xf2\xf2\x75\x90\x41\x13\x51\xa0\x09\x66\xd7\xfe\x98\xcf\xf7\x1e\x59\x69\x8f\x85\x8c\xa4\x56\xd5\xe8\x2e\x2f\x26\xab\x67\x14\x66\x1a\xb7\x1d\xb4\x7c\x7f\x58\x32\xc5\xc1\x3a\x13\x85\x60\x02\x0e\xff\xe1\xf2\xed\x58\xb9\xa9\x11\x11\x21\x48\x62\xd3\xd4\x3c\x2f\x1b\x63\xf5\x5f\x0f\x34\x1b\x9b\xc4\xcd\xdd\x88\xc8\x04\xd7\x03\x54\x28\x2b\x78\x7e\x98\x1d\xfc\x65\xa3\x18\xe2\xcc\xee\xd2\x50\x1b\x82\xdd\xab\x2b\x4f\x14\x25\x46\x05\x45\x9c\xce\x7f\x96\x43\xb4\xe6\x70\x86\x47\x11\x07\x2c\x97\xf8\x6b\xf3\xe0\x6f\x01\x71\x62\xf5\x13\x7e\x7a\x2a\x8c\xf1\x30\x8a\xe2\x90\x62\x52\xb4\xfd\xff\x47\xf9\x4e\x44\x31\x31\x77\x77\x45\xab\x37\x27\x37\xf5\xa3\x24\xc9\x20\x74\xa2\x78\x9d\xb7\xd8\x8e\xf8\x2f\xc6\xd7\x49\x52\x86\x8e\xe3\xa8\x8a\x43\xf9\x4b\x09\xa3\x7d\xc8\x95\xb2\xaa\xd2\x23\xd5\x82\xc9\xd2\x19\x25\xda\xc8\xab\x98\x3a\x2d\x7f\x15\x1a\x18\x19\x43\x2c\x49\xb6\x79\x86\xed\xf9\x08\xd7\xea\x4a\x44\x44\x43\x13\xa6\xe8\x39\x33\xae\x31\xa4\x89\x88\xf2\xd4\x28\xc3\x2c\x5f\x06\xb6\x76\xc4\x28\x53\xc2\xf1\x8c\x1f\x04\xd4\x37\xe7\xa5\x9a\x98\x8a\x51\x16\x24\x4e\x9a\xfa\x19\x3e\x5b\xcb\x76\x8e\x63\x73\xfc\xb5\x32\x42\x59\xe0\x89\x65\x2d\xee\x73\x7c\x2d\xce\x8c\x21\xf3\xb3\x33\xad\xad\xc9\xf9\xd2\x8f\x66\xce\x20\x33\x41\x64\xb7\x05\xfc\x73\x3c\xdc\xb9\x8c\xd1\x12\xf1\x44\xca\x8f\xf9\xbb\x9f\x22\x5c\xc5\xda\x13\x4b\x15\x55\x8d\xa4\x57\xee\xa0\x08\x95\xc9\x76\x3c\xf0\xe6\x06\xa0\x7c\x01\xa7\x21\x72\x35\x1e\x16\x09\x42\x43\x8b\x4e\xda\x1c\xb9\x84\x66\x9f\x1f\x9f\xaa\x12\xce\x93\x37\x12\x32\x46\x2f\xb4\x7a\x97\x2f\x50\x0f\x68\xfa\x44\x24\xb3\x34\x19\x58\x3d\x86\xaa\x69\x62\x3f\x44\x12\x62\x57\xea\xbf\xae\x2a\xbf\xcc\x5e\x1f\xc8\x12\x94\x27\x73\xeb\x45\x92\x5d\x5f\x5c\x1f\x6e\x93\x7c\xad\x88\x54\x96\xe1\x8c\x9d\x1d\x8f\xa7\x76\xb8\x42\x01\x31\xf9\x3d\xe3\x4e\xde\xe6\xfc\x50\x95\x6a\x22\x72\x78\xf5\x8f\xef\x82\x62\x11\x30\xc9\x7b\xa6\x2e\xbb\x3f\x5e\x8b\x20\x47\x20\x03\x34\x26\x6c\x91\xb1\x65\x7d\x1e\x7f\x16\x9d\x18\x15\xd7\x95\x21\x37\x32\x5c\x81\xd7\x67\xab\xce\x62\xb4\x3f\xee\x2b\xd4\x59\x6b\x47\xab\xb1\x16\x14\xf3\x07\x65\x35\x08\xa9\x45\x5a\x19\x5d\xe2\xaa\xe6\xb2\x1b\x1c\x3b\x4c\xfd\xa0\x2f\x3f\x40\x1c\x74\xed\x34\xa6\x7f\x17\x7f\x6e\x77\xf3\xd5\xd3\xcb\xec\xf9\xaf\xdd\xf6\x61\xbd\x58\xf8\x0b\x69\x91\x85\x3e\x4e\xf5\x3e\x54\xb4\x1f\x8f\xb3\x38\x88\x33\xb4\x6d\x2c\x4f\xd5\x2d\x14\x8e\x32\x45\xc4\x41\xca\x22\x27\xed\xd2\xbd\x2d\x46\x13\x4d\x71\xb5\xcf\xf4\x7c\x95\x5b\x1c\x3a\x6e\x71\x90\xa5\x28\x7f\xb2\xab\x4f\xa5\x05\xb9\xcf\xb1\x20\xe2\xff\x71\x3d\xbd\xbe\xbe\xc6\x81\x10\x3c\x1c\x70\x0f\x18\x7e\x74\x33\xde\x1b\xf7\x32\x24\x56\xe8\x03\xec\xc9\x2b\xf1\xbf\x25\x01\x92\xca\x34\x55\xdd\x6e\xab\xe3\x4b\xe5\x69\xbe\x45\x1c\x45\x12\x69\x25\x0c\x3f\xce\x23\x2f\x95\xa5\x57\xe5\x93\x05\x2a\x8e\x03\xc8\xb8\x93\x4d\x99\x2a\x8d\x88\x38\x0e\x39\x32\x0e\xfe\xb1\x5c\x6f\x7f\xcc\x1e\xb7\xb3\xc7\xdf\xdd\xa1\x24\xd2\x38\xe2\xf6\xbc\x56\x3f\x21\xf7\x42\x7a\x22\x4e\x62\xa3\x21\x5f\xc2\x67\xbb\xcb\x5b\x38\xec\xf2\x9e\x0d\x47\xc4\x09\x37\x5c\xa6\x12\x8a\xa2\x59\x8d\x6b\x7c\x45\x9c\xc8\xcc\x91\x37\xbd\xe4\x30\xe1\x31\x12\x31\xf2\x0f\x0d\x76\xb5\x11\x2f\xf9\xe5\x84\x8d\x29\x0d\x34\xf3\x1e\x88\x7c\x1b\x32\x30\x8b\x98\x4a\x86\xda\xad\x47\xac\xb6\x18\xa2\xed\x45\x9c\x26\x26\x3b\x6b\x19\x1d\xa9\xcb\xb2\xc4\x8c\x32\xa4\x4e\xdb\xf3\x66\x8f\x48\x5c\x7f\x20\x33\x54\xbc\x8e\x0a\xc0\xfd\xce\xa9\x42\xf7\xc0\x4a\xfb\xbf\x2c\xd6\x43\x0a\x5f\x11\x73\x26\x52\x5f\xae\xb2\xe3\x9e\xfc\xe5\xaa\xd1\x10\x8b\x50\xa3\x50\x9f\x99\x11\xdb\xca\xa5\xe5\xae\xce\x10\x41\x23\x74\xdf\x6e\x78\xf9\xb6\xeb\x4c\x85\x9d\x2b\x63\x73\x37\x17\x1a\x8c\xb8\x55\x67\xa7\xa0\x29\x83\x94\x9b\x6e\x93\x8f\x65\x90\x32\xd4\xd5\x41\xab\xca\x47\xb3\x7a\x1b\x3d\x96\x09\x43\xff\xef\xe7\x79\xa2\x98\x2f\x62\xc9\x09\x67\x4e\x88\xa8\x95\xfb\x9e\xd3\x48\xc4\x4a\x85\x89\x93\x61\x31\xc5\x13\xbd\x63\x10\x2b\xad\x11\xb6\xe2\xb8\xa2\xef\x79\x73\xc9\x6a\x25\x62\x20\x31\x62\xca\x24\x2f\x0a\x43\x74\x53\x7d\x99\x7c\x9a\xc4\x44\xec\xff\xfb\xd7\x00\x26\xd0\x2a\xef\x2c\xe6\x65\xa9\x0b\x9c\x07\xc6\x22\x70\x8f\x0c\x8a\x20\x34\xc4\x4c\xa6\x66\x3e\x1c\x2e\x3a\x31\x22\xe9\xc6\x18\xc7\xf5\xd2\xc6\xf5\x5c\x03\xca\x68\xe2\x0b\x75\xef\xaa\xfa\x67\xb7\x32\x7e\x1b\xf4\x4b\x02\x61\xb4\x97\x77\xe8\x7e\x6f\xf2\xd7\x91\xf3\x9f\x84\x24\x32\xea\x1b\xc6\x0e\x5a\xbe\xdc\x6d\x7a\x1e\x69\x67\x1e\x27\x24\x12\x58\x0d\x65\x58\x46\x26\x6a\x26\x22\x21\x3c\xc0\x40\x28\x12\xd4\xdc\xfd\x78\xbe\xdd\x0c\xe8\x2a\xbb\xc3\x0c\xf3\xdf\xb7\x36\x1d\xfb\x25\x5c\x5c\x24\x51\x46\x31\x24\x82\x70\x3a\xbb\x59\x7d\xa3\xef\xf2\x77\xff\x66\xaf\x1e\x93\x18\xfb\xe2\x61\x36\x7f\x58\xfe\xee\x82\xe4\x49\xcc\x0c\xc0\xa9\x81\xf6\x74\x9c\x9d\xda\x3d\x94\x6d\x2e\xf9\x75\x06\x69\x91\x24\x81\x52\x36\xd6\x39\x7b\xad\x73\x74\x35\x6e\x2b\x79\xba\xe2\xf4\x27\x09\x31\x85\x7f\x9e\xe1\xe6\xd9\xd9\xe8\xe1\x78\x9f\x4e\x12\xa5\x94\xad\x9f\xf8\x67\x25\x16\x87\x63\x51\x9d\xa1\x7e\xe6\x93\x8a\x1b\x91\x24\x90\x65\x43\x91\xc7\xc5\x50\xad\xd1\xb6\xa1\x71\x4a\x45\xef\xb1\x57\xcd\x17\x81\x8b\x84\xc6\xc6\x51\x34\xa5\x78\xaa\xc7\xa5\x8b\x84\x26\x11\x22\x3a\xe7\xb3\xe7\xd9\x70\xef\x4e\x52\x46\x9c\x3a\x8e\x95\xd9\xfc\xd1\x40\x8d\xb5\xaf\xc8\x32\x30\xa0\x66\x15\x49\x2a\x05\xc6\x52\x4c\x31\x12\x46\xce\x9a\xe7\xd3\x61\xf2\xbc\x2c\x36\x74\xa2\x2d\x34\xc8\x5e\x85\x26\x9f\xbb\x04\x63\xa9\x91\x96\xe6\x2d\xac\xf4\xe6\x08\x32\xd7\xb9\x44\xbe\xc8\x71\xcf\x30\x41\xc4\xb8\x8e\xd2\xb2\x38\x18\x73\x67\x6c\x11\x5f\xdf\x4b\x93\x2c\x20\x4e\xc5\xf6\x36\x7f\xf5\x49\xab\x24\x0b\x18\x7e\xc8\xee\x09\x43\xff\xa3\xb6\xb4\x9d\xdd\xf5\x7b\x41\x3c\x91\x70\x1a\xe2\xc6\x66\x59\xdf\x81\x1f\x9e\x97\x4f\x77\xb3\x6b\x44\x06\x22\xe1\x60\xf0\xa8\xb6\x88\x23\xb8\x70\x1f\x07\xab\x5a\xc2\x41\xe1\x96\x6d\x1b\xfb\xd0\xd5\xb7\x16\xa1\x3d\x57\x50\x82\xea\xb4\x2f\x37\xbf\x0f\x0d\xcf\x44\x08\x9d\x68\x67\xb8\xdb\x9c\x0d\x66\x5c\x9b\xfc\x75\xf2\xac\x32\x16\x68\x79\xa1\x2e\xac\xd9\xd5\x42\x67\x4e\x24\x32\xd1\x88\xca\x90\x75\x75\x3a\x7a\x3a\x4f\x91\x48\xa6\x91\x44\xcd\xd6\xe1\xa0\x9d\x0c\x7e\x84\x48\x4e\x90\x27\xdd\xa9\xae\x5d\x65\x34\xec\x9a\x81\x8c\x1d\x27\x44\x3b\x7d\x2c\xc5\xdc\xe4\x31\x55\xa3\xb7\xfc\xc0\x5f\xe1\xae\xae\x0e\x16\x2c\x74\xdd\xa2\x4f\x54\xc8\xf4\x48\xc7\x1a\xd4\xf2\xa8\x9b\xc9\xf2\xa7\x22\xe2\x35\xfe\xbc\xdd\xff\xa3\x51\xbf\x5d\xe7\x86\x99\xde\x03\x02\x5b\x95\x6f\xcf\xbc\x88\xb0\x25\x10\x72\xb4\x07\x8e\x13\x55\x25\x77\x38\x92\xdc\x14\xb2\x70\xad\xc7\xeb\x37\xa4\xc2\x09\x27\xbc\x40\x89\xc9\x06\x4f\x7a\x6e\x9a\xd0\x20\x62\x58\x7d\x97\x5f\x29\x6f\xf9\xdb\x32\x2c\x17\x63\xd2\xaf\x87\x34\xc8\x4c\x0c\x09\x43\x32\x70\x55\x58\x41\xd0\x50\x1a\x72\x6b\x03\x3b\xbd\x81\x4b\x02\x0b\xff\x67\x7f\x65\xc2\x58\x68\x5f\xee\xaf\xd3\x01\xea\x7c\xba\x70\x50\x92\x11\x03\x67\xb4\x81\xeb\xad\x63\x38\xed\x2b\x5e\x05\x25\x52\x84\xbd\x76\xdf\xf3\x90\xe7\x6a\x72\x35\x69\xc4\x36\x05\x2f\xdf\xa0\x9e\x15\xc5\x38\x73\x4d\xa3\x38\x8e\x83\xe1\x97\xb4\x95\x6e\xbe\xab\x23\x15\xe2\x9a\xb9\xfa\xf9\xbc\x58\xef\x7a\x63\x6d\xbe\x78\x76\x40\x1a\x1a\x47\x86\xd8\xdd\x7c\xeb\xf9\xa9\x6e\xaa\x7a\xb7\x54\x3b\x7f\x5c\xa6\x58\x81\x3b\x94\x17\x73\xc7\x92\x04\x5c\x85\xe0\x3f\x4f\xf5\xd9\x04\x0d\x26\x7e\x1c\x4d\xa8\xd1\x81\xbe\xcd\x25\xac\xb4\x2e\x72\x47\x25\x22\x68\xc2\x4d\x64\xbb\x5b\x4a\x5f\x0a\x5e\x2e\x1b\xf4\xf2\xae\x4f\x0e\x9a\x08\xc0\x2c\xce\xa9\x01\xe5\x88\x8b\xfd\xab\x52\x46\x31\x20\x76\x34\x82\x56\x86\x4a\xba\xc9\xab\x72\x80\x17\xa0\x29\xcd\xa8\x0f\xab\x3d\x03\xa8\x3b\x5b\x9a\xf8\x08\xef\x50\xb8\x75\x94\xb2\x88\x65\xf6\x3b\x2f\x0f\x47\x83\x80\x31\xdb\xef\x70\x8b\xa4\x2c\x25\x38\x86\x56\xb0\xed\x1c\xb1\x3e\x90\x42\x99\x32\xc2\xfc\x77\xf9\xb1\x41\x03\xd1\x44\x39\x83\x2b\xdc\x00\x5d\x63\x85\x44\x96\xe6\x2b\xae\x34\xfa\xb2\x9d\x61\x8b\xda\x9c\xaf\x5f\x66\xc2\xec\xe9\x59\x14\x18\x7d\x72\x2f\x6d\x95\xff\x8f\x7f\x2d\xdf\x22\x68\xc6\x22\xc4\x3d\xdf\x56\xaf\x20\xab\xbc\x1c\x31\xa2\x09\x9a\x71\x99\xb0\x1e\xa7\xf0\x00\xbc\x68\x2f\xd2\x9e\xb6\x2d\x0f\x98\x92\xd6\x6f\x58\xa3\x72\xcd\xf0\xcb\x18\xc4\x87\xad\x91\xfe\xb7\x3b\x25\x31\xe6\x7b\xb7\x71\x6d\xf7\x75\xf5\xd1\x18\x50\x56\xfb\x5c\x0d\x55\x8f\x05\x15\x16\xd4\xbe\x86\x96\xe7\xc5\x63\x75\xe6\x45\x7b\x36\x78\xa7\x21\xc7\xfe\x95\xd8\x83\x75\xcb\xa9\x4c\x3c\x87\xda\x4d\xcd\xe5\x9b\x0d\xe6\xb9\xa3\x92\xe0\xee\x90\x37\x4f\x3c\x2f\x5b\x40\x38\xc6\x53\xa5\x7c\x47\x28\x62\x58\xdb\x3e\xaa\xba\x50\xf3\xd3\x71\x0d\xcd\xa9\xc0\x62\xd2\xc8\x37\x49\x24\x33\xc2\x96\xb2\x3e\x1f\x5b\x50\x37\x9d\xab\xd3\x4e\x67\x00\xa4\xa1\xc8\x6c\xa2\xf4\xef\x56\x7d\x0a\x0a\x12\xb0\xd0\x43\xf0\x72\x7a\x3d\x60\xa9\xdf\xe7\x37\x5d\xaf\xd7\xd3\x16\x3a\x40\xff\xcc\x19\x65\x17\x9b\xb8\x6d\xa7\x63\x46\xe8\x14\xc8\xe9\x2b\x05\xba\xe3\x1c\xb3\x5d\xca\xa9\xca\x98\xdf\xd3\x20\x30\x3c\x67\x9d\x19\xf5\xc4\xcb\x2f\x22\xa4\x69\x90\x19\x34\x08\x66\x21\xab\xfa\xed\x12\x47\x67\x1b\x86\x84\x81\x74\x65\x7c\xed\xa5\x50\x80\x48\x43\x95\x61\xb2\xd9\x15\x88\xbd\xd4\xd5\xe7\x24\xf8\x96\x92\x34\x42\xc0\x2c\xf0\xe6\xdc\x59\x0e\x57\xf6\x97\xc9\x09\xcc\x00\x83\x5c\x37\xbd\x90\x97\xeb\xf1\xbf\x34\x8e\x03\xac\x80\xba\xb1\x3c\xa2\xcd\x2d\x56\x04\x8f\xde\x3b\xb5\xc4\x0e\x96\x4e\x8e\xb9\x53\x65\xa4\xac\x09\xb7\xfd\xfc\xc5\x47\x4f\x93\xc4\x54\xa6\xd4\xd0\xbd\x00\x94\x16\xaf\x36\xc8\x5f\xa6\xd4\xe6\x63\x7e\xaf\x3a\x5f\xb9\xb7\x9b\x52\x1a\x33\x1c\xb0\xcd\x07\x3f\x7e\xd1\xcf\x54\x28\x24\x13\xb0\xbc\x3d\xcd\x58\x4b\x52\xa4\x8c\x73\x14\x11\x33\x60\xd1\x87\x93\x98\xf4\x70\x16\x08\x70\x80\x03\xe4\x3b\x7b\xca\xcb\x53\x73\x07\x7e\x77\x4f\x33\x22\x71\x35\x03\x07\xc3\x71\xd1\xfc\xc5\xf6\x61\x7a\xb1\x94\x4a\x36\xb4\x8f\x57\xa2\xe5\x79\x09\x6a\xf9\x3c\x9b\x34\xe5\x24\x4e\x6d\x18\xbc\x78\x2f\x36\x3d\x62\xc8\x1d\x07\xb3\x10\x21\x00\x0c\x57\xbf\x91\x59\xd2\x1d\x47\x24\x59\x01\xba\x4d\xe3\xc9\xc5\x45\x10\xa7\xa4\xaf\x52\xec\xfd\xcd\x30\xb0\x2d\x64\x10\x61\xbd\xcf\xc3\xea\xe5\x65\xd4\xe5\x52\xc6\x88\x2d\x52\xb8\x48\xb9\x5f\x55\x42\x82\x04\x77\x3c\x13\x33\xf5\x3f\x2b\x6d\x9d\xaf\x2d\x2f\x5f\x73\x51\x00\xd6\x8a\x0c\x61\x05\x57\x4d\xf2\x54\x65\x01\x52\x6e\x9d\x4a\xa3\x66\xf0\xfb\x59\x5e\xb4\xe0\x89\x9c\xb0\xab\x9d\x8e\xc7\x0b\x69\x61\x1b\x08\xbc\xfa\x87\xbb\x94\x60\x96\x7b\xbb\x54\x5e\x9b\xe2\xfa\xfc\x86\x38\xc4\x85\x68\x71\xdc\xd7\x55\xb9\x2c\x55\xce\xbb\x6d\xb0\x5b\x40\xbe\xc5\xcb\xa6\x20\x78\x6a\x6c\xc0\xa6\xe5\x3d\xe5\x9f\xeb\x29\x1d\x71\x1c\xe2\xff\xac\xfe\x53\xfd\x92\x2c\x53\xa4\x9a\x2b\x34\xa8\x10\x39\xe3\xeb\xc9\xba\xfd\xdd\x0f\x4b\xad\x45\x66\xe6\xd5\x7b\xe5\xf7\x3a\x16\x90\x10\x87\x3b\x46\x8a\xc6\xf4\xa7\xb3\x52\x3d\x41\xbb\xaf\x26\xd4\x37\xf6\xc4\x90\xc5\xd0\x5d\x6e\x79\x38\x02\x97\x7b\xfc\x72\x68\x49\x4e\xaa\x30\x04\x23\x34\x02\xc3\xb5\xd5\x9c\x0e\xe0\x91\xdf\xee\x28\x4b\xb9\xb5\x34\x90\xc9\x00\xa1\xfe\x79\xf9\x63\x73\x7b\xbd\xc7\x59\x94\x45\xca\xc1\x0f\x3a\x8b\xfc\x7a\xab\x38\x55\xd2\x97\xee\xf9\x19\xf8\xdb\xa4\x11\x4b\x31\x9d\x7f\x9f\xdb\x65\xa4\xb7\x74\x59\xac\xb4\x74\x43\xd5\x7e\x9b\x75\x3e\x20\x30\xee\xeb\x92\xdd\xc6\xce\x68\x64\x94\x1e\xca\xea\x8f\xaa\x85\xcd\xc9\x05\x17\x59\x4a\x22\x94\xd4\xfc\xbc\x58\xfa\xae\x3a\x96\x53\xf0\x2e\x4b\x55\x86\x51\xcb\x9b\x1f\x37\x37\x8f\x8b\xe1\xf4\x63\x2c\x4c\x91\xc4\x92\x77\xd3\x68\x34\xe3\x19\xa3\x8c\x19\x76\xf8\x2d\x1c\x8e\x55\xcd\x6b\xcb\x37\xcb\x5c\x83\x34\xc4\x30\xf1\xcb\xc3\x6a\xf1\xbc\xfc\x73\x37\x5f\xad\x37\xb3\xe5\x7a\x77\xb7\x7d\xdc\x21\xb6\xd1\x5f\xc9\x92\x02\x4a\x5e\x14\xbb\xb6\x8f\x33\x32\xa6\x63\x8c\x33\xd6\x80\x5a\x46\x0a\x26\x91\x68\x96\x09\x70\x12\x9c\x96\xc2\x62\xcf\x6b\x2b\x0b\xd6\x20\x4d\xc0\x28\x76\xcb\x32\xa1\x65\xda\x2b\xa8\x9d\x2e\x42\xc9\x8c\x8b\x2c\x55\xee\x96\x93\x63\x22\x22\x18\x14\xc3\xaa\x8e\x7a\x80\x02\xb0\xc7\x25\xa1\x58\x69\x77\xac\xf3\xff\xc1\xcd\xf9\xb9\xfa\x70\xf7\x95\xb1\x74\x12\x2c\xb7\xfc\x73\x59\xde\xb4\x72\xc3\xdb\xaa\xd9\xe7\xd3\x4b\xa4\xa1\x4b\xe9\x9d\x8e\x26\xac\x8f\x80\x6d\xb8\xc6\x92\xec\xce\x91\x0c\x4d\x08\xa3\xe4\xf5\xb4\x78\xde\xee\x7e\x6c\x16\x6b\xe2\x6f\x0e\x11\x0a\x00\x5a\xca\xe6\x65\xa9\xab\x9d\xae\xea\x9d\x31\x06\x47\x93\xcf\x33\x27\x5d\x1f\x28\x8a\x67\xb8\x77\xb6\xaf\xf5\x20\x0f\xc8\x74\x98\xa0\xbf\x5b\x62\x49\xb3\x97\xbe\xf1\xd1\x11\xa6\x33\x19\xdb\x00\x9a\xe1\x28\xba\x52\x11\x2a\x98\x56\x14\xb1\x90\x38\x45\x57\xda\x02\xe3\xbd\xa9\xe7\xe7\x81\x06\xc3\x25\xfa\x0c\x1f\x13\x45\xdc\x71\xbf\x68\x9d\xb8\x7a\xe6\xcb\xa8\x5a\x16\x48\x30\xa9\x90\xfc\x80\x5b\xa3\xda\x35\xde\xfa\xca\xc2\x44\x19\xf2\x4e\x28\xaa\x11\xaa\x20\x0b\xa9\xd9\xe7\xb0\x90\x62\x56\xbe\x42\x81\x94\x04\x86\xb8\x70\xb8\xca\x67\x61\x16\xb3\x9e\xc0\xe0\x52\x73\x42\x64\x51\x90\xa1\x63\x71\xac\x61\xfb\x6a\x52\x74\x23\x74\x68\x16\x85\x92\x9b\xc1\x78\x2c\xb8\x84\x99\x3a\xe4\xa5\xe1\x1b\xbf\x0c\x59\xdb\x53\xe2\xd8\xc8\x4f\xdd\x57\x03\x06\x2e\x91\xc5\xd4\xa4\x8a\x8f\xbc\x86\xb2\xfd\x3d\x57\xcd\x63\x5e\xbe\x7d\x57\x6f\x90\xc5\xd4\x80\x84\xf2\xc6\x86\x65\x47\x64\x04\xb6\x51\x92\x52\xa3\x79\x97\xeb\xd6\xa7\x6d\x5d\xb8\x73\xdc\x94\x12\x49\xbc\x29\x68\xec\xf3\x5d\xee\x58\x57\xdd\x37\x26\x7d\x0c\x77\xf4\xd7\x2f\x0f\xfc\xfd\xbf\xc6\xff\x76\x0f\x12\x69\xc4\x6b\x5a\xba\xdc\x3f\x96\x9b\x35\x34\x50\xbf\x4f\x29\x69\x47\xdf\x8a\x52\xca\x74\x5f\x3d\x7f\x1d\xa1\x9b\xa5\x02\x30\xb0\xec\xcd\x5d\x6e\xb4\x67\xc6\xdf\x3d\x95\x96\xc3\xd8\x35\x33\x44\x47\xfb\xfc\xb8\xd2\xcb\x16\x0e\xcd\xa6\xad\x6a\xfe\x0a\xd3\x8b\x43\x82\xe8\xcb\x1f\x65\x2e\xeb\xc9\xb0\x64\x01\xc3\x8c\xa0\x38\x9d\x7f\xf6\xee\x7f\xc6\x62\xb3\x04\xef\xac\x8e\xde\xdd\x57\x65\x3c\x19\xcb\x28\x86\xec\x66\xca\x61\x79\x0d\x26\xe7\x8b\xd6\x92\xa1\x31\x24\x8a\xd6\x50\x03\x6d\xab\x4d\x9f\x1e\xc8\x98\x4a\x99\x74\x84\x73\xa5\xda\x14\xd5\x2b\x9f\xc2\x8a\x6d\xd3\x8c\x87\x48\x75\x09\x2a\x6f\x2d\x25\xc2\xf8\x56\x3c\x54\xe8\xda\x7d\xf0\xf2\x87\xaf\x94\x14\x99\x08\x03\x0c\x83\x0d\xbc\x3d\xa3\x5d\xec\x6d\x9c\x4c\x10\x9a\x66\x2e\x14\x8f\x1f\x78\xc0\xea\x66\x92\x70\xe3\x0e\x96\xa1\x42\xec\xbc\xd1\x20\x45\xad\x08\x80\xd1\xa6\x97\x49\x1a\x62\x80\xea\xe5\xc7\xe3\x66\x9a\x15\xc9\x24\x57\x46\xf2\xd5\x70\x82\x3e\x35\xaf\x97\x0a\x38\x22\x93\xda\x14\x5e\x0e\xc0\x31\xa3\x24\x62\xa6\xb8\xd1\x3c\xed\xcc\xc3\x67\xf8\x40\xca\x84\x91\x31\x9e\x29\x11\x03\xed\x11\x6e\x93\xd7\xd0\x19\xc5\xf2\x7c\x5d\x9c\x7c\xa6\x9d\x07\x22\xc6\x14\x69\xde\xfc\x5e\x56\x1f\xe5\x06\x0a\x40\x8e\x7a\x5c\xe0\x63\xdf\x88\x09\xe7\x24\x56\xe5\xc9\x87\xd5\xae\xee\x3b\x3c\xd0\x21\x8a\xcf\x61\x3e\x62\xde\x13\xf3\x09\x1e\x26\x0c\x4b\x95\xe0\xbd\xb4\x04\xa6\x5f\x96\xe6\x7e\x15\x86\x1c\xbe\x2f\x27\x81\x51\x7c\x3f\xf0\x4f\xc3\x33\xe0\xac\x4e\x4e\x62\x46\x8c\x56\x1b\xe6\x24\x9e\x73\xf9\xf6\xcc\xa7\x40\x19\x4e\x38\xe8\x21\x17\xd3\x34\xd6\x7d\x3d\x93\xc6\x63\xc2\x2d\x71\xff\xef\x00\xc7\xe9\xda\xc7\xe3\x58\x45\xb6\xb7\x76\x7c\x94\x50\x75\x0d\x52\x82\x35\x9e\xe2\xe4\x45\x63\xb7\xdb\x9f\x37\xe7\x81\xa3\xf6\x8f\xc9\x25\x25\x41\x3c\xce\x01\x05\x9e\x4d\x5d\xd9\x55\x15\xac\xe9\x93\x6a\x43\x28\xbe\x6b\xa0\x9d\x9d\x6a\x8e\xe3\x8e\x44\xbf\x4d\x5b\x71\x44\x1f\x99\x85\x0f\xab\xee\xb7\x95\x21\x2e\x70\xc6\x02\x4f\x12\x89\xb1\x63\xd9\x79\x19\x28\x95\x78\xe7\x3d\x3e\xdf\x06\x74\x60\x6d\x57\x57\xed\x9b\xb9\x7b\xd0\x8c\xc5\x4e\x6e\xf0\x66\x3b\x79\x00\x0a\x04\x09\x2f\xb6\xf7\xf3\x4b\x1e\x0f\xc1\xd3\x84\x1a\x67\x01\xc1\x71\x0d\x5a\x0b\x3d\x66\xc2\x35\x52\x84\x79\x31\x38\x9b\x29\xec\xec\x6f\xc3\xea\x3a\xbd\x22\x44\x98\x69\xc1\x3e\xdc\xc0\x88\x55\xc6\xea\xdc\x33\xd7\x54\x6b\x95\x58\x4c\x05\x34\xed\xdc\xcf\x47\xce\x54\x4c\x86\xf9\xb7\x07\x2e\xdf\x2a\x0b\x36\xf4\x2b\xf7\xe4\xc6\x59\x12\x4a\x3f\x37\x50\xae\x3b\x87\x7a\x9b\xbf\xd6\x0e\xf7\xce\x33\x1e\x07\x8e\x8e\xf2\xb6\xe6\x1f\x13\x20\x92\x6b\xa5\x55\xd4\x75\x49\x75\x34\xfa\xf2\xbd\x67\xc3\x79\xa0\x11\xb8\x66\x1c\x52\x13\xb7\x9b\x08\xa3\xbb\x96\x44\xeb\xb4\x8f\xdc\x5e\x5f\xd3\x79\xe7\xc1\x27\x46\x57\x74\x40\xf5\x6c\x0f\x4a\x2b\x9b\xba\xe7\xcd\xc6\x94\xe0\x7a\xeb\x8e\x4b\x25\x31\x59\xe2\x50\x02\x77\x35\xc0\xa3\x29\x83\xf8\xb2\x12\x7f\x72\x75\x0d\xb1\xe3\xae\x99\x3f\xec\xba\xbd\x60\x17\x3a\xb8\x29\x57\x69\x0a\x96\x27\xfa\xf9\x74\x78\xa9\x2b\x75\x92\x1e\xb6\xc2\x15\x03\x0c\xfe\x68\x87\x0f\x9d\x70\x47\x08\x0e\x41\x82\xc0\x96\x63\x0d\x8e\x2c\x72\xf2\xb5\x20\x34\xbc\x5a\x6e\xdd\x33\xd5\x87\x79\x67\x2b\xdb\xcb\x4d\x02\x8e\x22\xe0\x10\x5a\x5b\x75\x1a\x48\x13\x61\x92\x79\x31\x3b\x93\x2e\xed\xba\x6c\x10\x25\x17\x21\x0d\x12\xc3\x20\x5b\xc0\xbe\x87\x43\x89\x90\x9a\x3a\xea\xbc\x99\xf3\xb2\xad\x4a\x9b\x14\x9e\x2c\x67\x82\x04\x3a\x33\x25\x1d\xbc\x96\xfb\x4b\xa9\xc9\x49\xeb\xd4\xe8\x04\x49\x7e\xc4\xc2\x6d\x17\x84\x17\x44\x86\xa4\xa7\x19\xb7\x68\x27\xef\x7f\xc6\xff\x9e\x7e\xb4\xff\x0b\x7b\x6b\x6a\xe8\xab\x8b\x28\x34\x0e\xc6\x10\x0c\xff\xd3\x69\xce\x0b\x11\x25\x86\x92\x0b\x2b\x8f\xee\xf3\xd7\xd7\xc6\x1f\x91\x86\x92\x0d\xa5\x92\xe2\x4d\x9f\x00\x13\xb1\xd4\x58\xe9\x68\x9e\xcd\x2c\x16\x57\xe2\xd0\xd7\xb8\x1d\xa7\x20\x00\x11\xab\x24\xc5\x0c\xea\xfb\x93\x9d\xb5\x8d\x63\x9b\xfe\x76\x58\x8a\x24\xd0\xb8\x96\xed\xba\xd9\x87\x0a\x59\x05\x3f\x3f\x4f\x70\xca\x22\x89\xa4\xc1\x50\x1a\xaa\xf5\x2f\x16\xea\xaf\x6e\x41\x81\x89\x21\xbe\xd2\x73\x44\x0b\x41\x83\x18\x63\x3f\xbb\xbc\x6c\xa0\x6e\x37\x55\xdd\x3e\xc1\xa1\xaa\xcf\x8e\xe2\x32\x0c\xdd\x2b\xd2\xd0\x48\x65\xc1\x27\x4c\xe2\x56\x82\x02\xb7\x08\x4e\x70\x09\x72\x09\xc7\xbe\x14\x43\xa4\x44\x22\x0a\xd1\xa1\xf7\x9b\x65\xe9\x68\xa4\x5d\x0b\x91\x72\x93\x44\xaa\xfd\x10\x4e\x75\x84\x81\x67\x83\x5d\xbc\x54\xb0\xe8\x5a\x64\xcc\x26\x07\x1e\xf2\xd7\x3d\x34\xed\x53\x5e\x40\x83\x2b\xe6\x6c\x3a\x67\x58\xc0\x31\x47\xb6\x93\xd6\x5c\x78\xd7\xa0\xe1\xca\x27\x0f\xaf\x33\x8a\x77\x57\x50\xa8\x13\xa8\x6c\x74\xea\x62\x1d\x10\x8c\x00\x23\xbf\x16\x68\xed\x83\x34\x22\x13\x19\xf7\xb2\x50\x6a\xc0\xa4\x74\x5d\x14\x50\x08\x6e\x09\x32\xde\xf8\xf1\xe8\xf2\x20\x82\x27\x12\xad\x17\xbb\xed\x7a\xbe\xbf\xd1\x50\x61\xbf\x18\x28\x5c\x69\x8c\xf1\x70\xa5\x5e\xaa\x37\x38\x54\xe5\x2d\x46\x44\x9b\x2f\x88\xd2\xdc\x69\xc0\x90\x15\xec\x71\xf9\xb4\xdc\xee\x36\xdb\xd9\x3a\x76\x8f\x25\x64\xe8\xba\x63\xca\x09\xe7\xa7\x8e\x00\x89\x00\x02\xf3\x95\xbb\x29\xf0\x04\x2d\xff\xce\x6d\x14\x32\x49\x31\xd4\x71\x07\x30\x11\x68\xb0\x0d\x20\x88\x43\xeb\xbe\x0f\x53\x35\xe3\x9d\xf9\xcb\x7d\x5a\x00\x89\xb1\xba\x43\xf1\x96\x6f\xaa\x53\x2d\xe1\x1e\xda\x7f\x9d\x78\xdd\x1a\xf1\xcd\x62\x3a\xb4\x80\x1a\x02\x43\x71\x3a\xcf\xab\xbc\xec\xbc\xd9\xf7\x1c\x3e\xa6\xad\x78\xca\xec\x26\x63\x6b\xcc\xd0\x86\x1a\x38\x4c\xae\xa1\xc8\x14\x18\xc2\x87\xbc\xbc\xe0\x63\xef\x8e\x73\x66\xc9\xb6\xad\x9e\xeb\x6f\xa3\x72\x34\xdb\x4c\x27\x31\xce\xa9\x97\xf9\xdd\x6f\xfe\xa7\x0c\x6d\x59\x6c\x3e\xe7\x45\x81\x65\x65\x75\xcd\xbd\x8e\x93\xf7\x61\x65\x40\x4c\x85\x98\xf5\xeb\x6e\x6a\x00\x75\x85\xef\xc2\xb5\x16\x11\x3a\x77\xb6\x96\x61\x44\xca\x21\x64\xa0\x53\x2d\x1c\xb1\xc0\xe7\xf9\x11\x5e\x2f\xc9\xe6\x6c\xd3\x50\x87\x98\x9d\x30\xe3\x01\xad\xaa\x59\xa9\x96\xe5\x3b\x94\x6d\x55\x0f\x38\x01\xff\x16\xa0\xd5\x85\x4a\x24\x09\x19\x1a\x7e\x8e\x2a\xc5\x99\x31\xe3\x9b\x13\x16\x24\xca\x4b\x92\xcc\x8a\xa1\xda\x9f\x90\x51\x18\x21\x93\xdf\xe2\xee\x0e\x13\xc5\xe3\x73\x23\x22\x53\x57\xb9\xd8\xd6\x3c\x2f\x77\xdd\xf8\xd9\x15\xc3\xe8\xa0\x8c\x18\x43\xd4\xae\xe4\xa5\x81\x36\x4c\x2f\x22\x8c\xb0\x49\x09\x1f\xee\xd3\x5e\x99\x01\x32\xb2\xf1\x29\xc3\xa8\x6d\x50\xb9\x0f\xbc\xd0\xbf\xf5\x91\x88\x7f\x5c\xfd\xab\x3f\x3f\xe6\xde\x0c\xb6\x44\x08\x5f\x18\x6d\x32\xa6\x5a\xf8\xd2\xa1\x07\xde\xca\x3d\xd4\xe7\xcd\xbe\xce\x0f\x0e\x59\x2b\x93\x80\xa2\x9b\xf2\x07\x16\x2f\xb9\xfd\x0f\x91\x3c\x5f\x44\xb7\x65\x12\xa4\xc2\x4e\x86\x9b\x82\xcb\x37\x5d\xf0\xd7\xeb\x1e\x8b\x4c\x44\xe6\x0a\x64\x0d\x38\xe1\xe7\x3e\x6f\x2e\x7c\x25\x99\xc8\x40\xaa\x1e\x18\x3b\x44\x8c\x49\x1a\x9a\xd4\x93\x01\x39\x3e\xf1\x1c\xf1\x82\xc3\xf0\x86\xa4\x31\x04\xba\xb7\x60\x17\x3e\xe5\x23\x69\x92\xa6\x36\xf7\x37\x2b\x0a\x6b\x1c\x3e\xf6\xd5\xf4\x32\x65\x99\xb4\xf1\xfc\xd5\xf3\xfd\x6e\xf6\xe3\x76\xb9\x1d\xa3\x7d\x24\x4b\x42\xcb\xac\x61\x5e\x61\x59\xde\x42\x23\xa1\x54\x7c\x50\xff\x37\x39\x85\x13\x6a\x6d\xbc\x6e\x0d\xf8\x99\x97\xcb\x72\x80\xf2\x19\x77\x67\x96\x31\x0c\xa2\xff\x51\x15\x23\x50\xbc\xcc\x44\xe0\x04\x13\x5e\xea\xea\x90\x37\xb0\x54\x5f\x92\x82\x0d\x36\x26\xc9\x59\x88\x8b\x60\x8d\x90\x80\x9b\x5e\x7f\xe4\xc2\xd0\x9e\x1a\xe0\x13\xe6\xaf\xc9\x87\xe7\x1c\x10\x5d\xf3\x02\xed\x81\x97\xb2\x1a\x97\x54\x49\x2e\x52\x27\xa6\x7a\x3b\x3b\x4e\x7c\x1e\x29\x83\x28\xe1\xc3\xe0\xfa\xac\x54\xae\xbc\xd9\x35\x21\x0c\x2b\xc7\xde\xf2\xb6\xc5\x61\x78\xe0\x79\x89\x88\xe4\xdb\xba\xf2\x23\x56\x46\x61\x28\x87\xa8\x9b\xd1\x70\x91\x29\x89\xc3\x01\x06\x78\xca\xda\x24\x24\x90\xc8\xb2\x36\xb5\x27\x53\x47\x79\xc1\x5f\x29\x24\xd0\x04\x51\x37\xb5\x8d\xfd\x59\x7b\x01\x51\x8d\xee\x56\xc0\x38\xc2\x54\x3e\xfa\x90\xb6\x5d\x3b\x87\x30\x5e\x09\xc0\x95\x55\x41\xdb\xfc\xf7\xc4\x6b\xf8\x25\x55\xb5\x50\x41\x40\xf0\x1d\x91\xbd\x1f\x5d\x71\x7b\x35\x15\x85\x3c\xa1\x16\x23\x3f\xe7\xc7\xc7\xea\xe3\x47\xa3\xfc\xc1\x94\x60\x4c\xfb\x25\xff\xcc\x4f\xbb\x1b\xf0\x68\x0b\x15\xf1\x10\x61\xe9\xa8\xce\xce\x0f\x83\xfe\x54\x91\x8a\x03\xea\x16\x89\x91\x38\xb8\x50\x31\x15\x8a\x0c\x74\x80\x6f\x4e\x75\x79\x07\xe0\x34\x96\x7e\x15\xaf\x71\x57\x61\x31\xba\xbb\x58\xc7\x81\x84\x3b\x82\xcb\x37\x2f\x12\xe0\x5a\x29\x2d\xed\x77\x41\x32\x72\x2c\x83\x9b\xb0\xe0\xb9\x19\xa6\x92\x80\xc5\x7d\x52\x61\x57\xe9\x1d\xae\x87\x6e\x18\xa8\x24\x90\x4e\x93\xdd\x48\xcf\x9d\x46\x65\xc4\x2a\x61\x86\xb3\x1a\x3f\xe8\xee\x85\xb7\xf9\xc5\xc4\x54\x09\x10\xea\x6a\xb8\xfb\x5a\xb8\xd1\x6a\xae\x68\xc8\x11\xd1\x54\x56\xa5\x35\x63\x0d\x05\xb2\xd1\x39\x72\x77\xa3\x69\x8a\x88\x4a\xd7\xbb\x7f\x37\xcc\x35\x7e\x1e\xca\x4c\xa9\xbb\x13\xa0\x1c\xc5\x05\x55\x1a\x70\x0c\x2e\x3f\x2d\x9f\x77\x4b\x97\xea\xf1\x07\x21\xc5\xb4\xe5\x9c\xb7\x56\x09\xf5\xab\x65\x64\xfc\xe5\x52\x5b\xd2\x7f\xe0\x9f\xf9\xc1\x79\x00\x77\x55\x3d\x2c\x52\x50\x2c\x35\x6a\xc5\xdb\xfa\x4c\x08\x21\xfe\x67\xad\x10\x0d\x62\x59\x0f\x9f\xf2\xb2\x5b\x89\xec\xc1\x8c\x68\xa4\x16\x71\x44\x24\x9e\xdc\xde\x84\x69\xaf\x1b\x18\x0a\x75\x86\x7c\x68\x69\xb1\x7d\x98\xb0\xc9\x09\xc5\xa3\x18\x83\xb4\xbf\x24\x4c\x52\x9c\x27\x18\xe7\xd7\x55\x2d\x73\x51\x9c\xad\x87\xbb\x93\x76\x78\xba\x27\x15\xd2\xc8\xda\xdf\xf0\x66\x08\x1e\x72\x5b\xfc\xf5\x07\x15\xda\xe6\x81\xaa\x52\x72\xdf\x51\x32\xa0\x86\xb9\x0b\x4d\x94\xa1\x3a\xec\x78\xad\x54\x32\x54\x98\x5c\xb9\xaf\x0a\xb5\xf6\x65\x2e\x4a\x52\x82\xc1\x6e\x59\x1d\x8e\x55\x03\xff\xc4\x02\xd9\x89\x85\xff\x7f\xc9\xbf\x5d\xeb\x2c\x89\xe9\x08\xc6\x6b\x30\xec\x3f\xea\x7c\xbc\xc3\x29\xa9\x04\x51\x4e\x29\xba\xad\x0e\xbc\x05\xb5\x86\x63\x55\xb7\xb7\x27\xac\x7a\x6d\x5a\xee\x2d\x06\x25\x15\x70\xf7\x11\xf8\x6b\x2e\x37\x6d\x75\xa9\x56\x6a\xdb\x02\x01\xcf\x81\x78\x53\xa9\x33\x16\x02\xa2\xe9\x3c\x89\x3e\x2a\xe0\x29\x58\x09\xe4\x4b\xb1\x02\xa1\x40\x48\x8c\x7d\x28\xa4\x06\x73\xbe\xa7\x02\x20\x41\x2f\x1d\x83\x3c\x4a\xf5\xe0\x58\xd4\xf5\xf6\xff\x07\x75\x05\x96\xbc\xc8\x1d\xd3\xca\xd3\x21\x63\x0c\xfd\xb5\xe0\xa5\xba\xd0\x57\x12\x10\x04\x04\x49\x9a\xe0\x33\x9f\xd8\xc5\x10\x44\x66\x69\x44\x14\x33\xd6\x5f\x2e\x4b\xe9\x0f\x26\x01\x1e\xbc\xcb\x05\x56\x10\x37\xd6\xcf\xb9\x10\x4a\x75\xed\x25\x4d\x4d\xd2\x29\x3f\x6e\xf2\xff\xb9\xe7\x84\x30\x92\x99\xb9\x49\xa1\x46\xa9\x06\x20\x01\xc1\xb0\x15\x57\x6a\x53\x1d\xe0\x76\xb1\x6d\xb6\x5f\xe4\x63\x80\xc4\x1c\x6b\xbd\x8c\xf7\xfc\xcb\xd5\xe7\xab\x3f\xaf\x15\x1b\xba\x3b\x68\x53\x26\x3b\x50\x1a\x5b\xe9\x9f\x90\xcf\x0d\x1f\x9b\x8f\x06\x42\x44\x20\x8d\x06\x94\x42\x66\xaa\x5d\x05\x22\xb8\x33\x62\xa3\x86\xd4\x58\xb2\xe5\x99\x9c\xc4\x30\x20\xca\x84\xb2\x96\xc5\x16\xea\xc3\x04\xad\x0d\x71\x60\x05\x05\xcc\x3a\x64\xa3\x17\x9e\x05\x0c\x62\x42\xd0\x48\x56\x9d\xdb\x7d\xc8\x4b\xaf\x82\x30\xbe\x4b\x9c\xc6\xb8\x0e\x14\x9d\x19\x7d\x27\xf3\xce\xb0\xb3\x22\x41\x03\xfc\xdf\x3f\xa6\x27\x51\x3c\xc9\x54\xd3\xf8\x34\xc7\xc9\x54\x7e\x3b\x73\x6b\xf8\x37\x77\xa2\x34\xd5\x4a\x4e\x37\xbb\xb9\x70\x35\x21\x56\x99\x08\x86\xd4\x7a\x55\xf1\x8e\x28\x65\xb3\x90\x7e\x53\x73\x0a\x49\x90\x68\xa3\x31\x80\x6c\x79\x48\x5d\x33\xe9\xb5\x24\x63\xc8\xdc\xba\x59\xde\x6f\x87\x56\x1e\x24\x3a\xe6\xd4\x47\xd8\x73\xd9\x4d\xc7\x9b\xf3\x46\x56\xf5\xc4\x86\x02\x1a\x18\x25\x2c\x4c\xa9\x7d\xd4\xf9\xd4\xc8\x02\x9a\x2a\xac\xbf\x91\xb6\x5f\x9e\xf9\xc1\x16\x4c\xbb\x45\xad\x37\x6a\x81\x6a\x1e\x5a\x57\x62\x28\xe8\x82\x8b\xc9\x90\x5c\x0b\x58\xa0\x20\xf5\xb4\xe2\x55\xbd\xbc\x9d\xce\x6a\x46\x42\x44\x6a\x3c\xc3\x79\x6a\xc4\x02\xa3\x1a\xc3\xf9\x68\x79\x75\x9b\xf5\xae\x3b\xdc\x0c\xa2\x8f\x90\x59\xb2\x9e\xce\x8f\xc8\xcb\x57\xbb\xa1\x1a\x11\xc5\xaf\x80\xf2\xee\xd4\x2c\xcd\x26\x2f\xb1\xad\x46\x4f\x9f\x71\x86\xfa\xc5\xf7\xd0\xde\x77\xfb\x11\x56\x23\x0e\xd9\xe0\x05\x64\x3a\xc5\x12\x5e\x38\xe4\xad\x45\xa4\x5f\x09\x56\x8e\x6f\xcc\x03\x91\x66\x0e\x0a\x83\xb9\xa6\x51\x61\xfd\x68\x32\x73\x46\x4c\x44\x0a\x97\x8b\x5e\x12\xea\x74\x09\x04\xfb\xd2\x82\x05\x9e\x19\xd8\xc9\xec\xc7\xf6\x61\x77\xb7\x5e\x2c\xfe\xbf\xc5\x6c\x3e\x5f\xfd\xf0\x36\x09\xf0\x4c\x61\x4c\xe5\xe6\x71\x35\xff\xfd\x65\xf9\xe7\x6e\x80\xe0\x06\x2e\x01\x6d\x1d\x5b\x3f\x0a\x36\x31\xfb\x8d\xe6\xb6\x00\xae\x0c\x7c\xc7\x46\x3d\x78\xa9\xe4\x90\xdb\x71\xdc\x58\x24\x86\x47\xc6\xc4\x2a\xe6\xbc\xb4\x16\xdb\x60\xc4\xc9\x88\xe0\xba\xe2\xcb\xbb\xbf\x4f\x08\x82\x8c\x13\x1c\x17\xe2\x74\x9e\x4f\x05\x7f\x05\xc8\x24\x94\x72\xc0\x46\xf8\xab\x8b\x41\x62\x69\xdd\xd1\xa7\xc5\x3d\x31\x1c\x54\xaa\x83\x0a\x32\x74\x63\xfc\x0a\x61\x66\xce\x40\xa5\x47\x80\xa2\x0a\x12\x9b\x2b\x5e\x89\xff\xe0\x5c\x6f\xf7\x26\x82\xd5\xc3\x2a\x26\x43\x45\x09\x86\x45\x05\x4f\xb6\x40\xd0\x5d\x0c\x88\x44\x17\xc2\x31\x30\xbb\x30\xf0\xf8\xb9\x21\x09\xa3\xee\xab\xde\xfd\xfc\x35\x70\x10\x20\x8d\x30\xe5\xd8\x42\xd3\xfa\x85\xcb\xdf\x2f\x35\x89\x6a\x27\x05\x75\x53\x5d\xe2\x20\x27\x9d\x06\x99\xc4\x3c\x54\xa5\xb5\x61\x3d\x18\xa4\x55\x40\x13\x8e\x73\x0f\x78\x5d\x9c\x5f\x4e\xb5\x34\x19\xce\x37\x28\x47\x86\x34\xe8\xcc\xd4\xf7\xfe\xf1\xe3\xc5\x15\xd6\xee\x6e\x66\x1b\x64\xd2\x5b\xf8\x46\x9c\x60\x58\xfc\xe7\x7c\x1b\x8e\x57\x17\x1d\x04\x0e\x56\x7b\x74\x89\x84\xd1\x53\xea\x80\x6a\x8c\x11\x7a\x61\xfd\xea\xb9\x27\x74\x1e\xbd\xe1\x25\x63\x59\x3f\x3c\x75\xc0\x52\xac\xda\x15\x79\x3d\x29\x10\xe8\xe1\xfe\x3a\xe0\x11\x32\x14\x3e\x2e\xff\xf5\x63\x79\xbb\x1b\xd0\xdb\xbd\xbc\x3c\xfd\xe6\x1a\xc9\xd4\x55\x3d\x59\xa0\xfe\xf4\x95\x74\x6c\x2a\xca\xab\xa2\x18\x56\xde\xeb\x30\xca\x90\xe3\x1d\x4a\x35\x6b\x0d\x2f\xc9\xf8\x5d\x49\xc0\xb1\xd8\xe1\x54\x1a\xcd\xee\xd9\x76\xc2\x05\x37\x1e\x7c\x9a\xd0\x00\x7d\xae\x97\xd9\x76\xfe\xb0\xfb\x63\xb1\xde\x2c\x57\x8e\xab\x54\x47\x01\xc1\xbb\xe1\xd6\xb3\x2c\x3b\x87\x3c\x7f\xcf\x9b\xbe\xc6\xc9\x37\x24\x49\x10\xa3\xdb\x52\xbf\xcd\x1a\xa3\x50\x39\x4a\xbe\xeb\x28\x0e\x71\x93\xd8\x75\x93\xbe\x1a\xd4\x3d\xe8\x98\x90\xc8\x33\x40\x9c\x4a\xb5\x98\x66\x3b\x75\x4c\x28\x1a\xd6\x9e\x17\xdb\x33\xd6\x0e\xfd\x7e\x1d\x13\xe0\x89\x73\x45\x1a\xbb\x4b\x7c\x31\x7e\xff\x5e\x3e\x48\xc7\x51\xc6\x30\xb5\xce\xcb\xfc\x63\x68\x0e\xea\xc4\x56\x8c\x35\x2d\x20\x27\x96\xf9\x16\xee\x20\xd1\x38\x2d\xfe\xe8\xa1\xb7\x3a\x49\x32\x0c\x97\x22\x4c\xe5\x1a\x7c\xf0\xfa\x46\xa2\xa9\x32\xe4\xd5\xbc\x69\x2a\x99\x77\xd3\x6b\x32\x44\x2f\xa1\xa9\x9a\x05\x29\x02\x2c\x4c\x08\x0f\x1d\x8a\xc9\x00\x63\x44\xa5\x56\x4e\xec\xee\x54\xaa\xa7\x1e\x2d\xa2\x99\x30\x71\x6f\x63\xe6\x6c\xc0\x4e\x27\x67\xa8\x68\x26\x34\x66\x61\x6e\x4f\xad\xdc\x4f\x42\xc3\x5f\x74\x23\xd3\x46\x17\xb7\x73\xfd\xe0\x0e\x59\xae\xdc\xdd\xb2\xd0\x68\x1f\x1b\xab\x7e\x65\xa2\xb2\x96\x53\x5c\xe8\x2c\x13\x38\x9b\x96\xf3\xd5\x1a\xf1\xc4\x5f\x2b\xa4\x5f\xbf\x73\x26\x22\x18\x6c\x51\x1e\x19\xfc\xed\x5e\xa0\x33\x91\xe2\x9a\x8a\x21\x8e\xbb\xaf\xeb\xd1\x5d\x73\xa0\x48\xbe\xf8\x61\x28\x09\x1b\xc7\x5e\xab\x79\x94\x66\x06\x30\xcb\xd5\xf9\x1a\xed\x95\xe6\x09\x20\x8e\xbf\xc2\xca\xf7\xbc\x7c\x5d\x69\x9d\x4b\xaf\x6e\xe5\x2f\xc4\x33\x04\xd6\xe6\x65\x67\x23\x34\xe0\x71\x0e\x97\xcc\x68\xee\x0c\xc8\x88\xab\x35\xb0\x70\xab\xef\x43\x60\x5a\x04\x0a\x0b\xca\xf2\x16\x0e\xa3\x79\x25\x84\x42\xe3\x75\xf8\xc1\xb7\xd5\xbc\xe6\xfa\x4b\xfc\x90\x3b\x53\x1a\x24\xf3\x83\xaf\xdc\xf8\xe5\x16\xa5\x85\x4e\x6c\xe5\xc2\x3b\x14\x26\x65\xe5\x97\x0a\xc9\x84\x70\x52\x5d\x93\x42\xf9\xf1\x45\x64\x96\xa0\x58\x4f\x03\x45\xb1\x69\x7b\xee\x30\xad\xb2\x14\x01\x63\x18\xd2\xc6\xa5\xb7\x1e\x58\x20\x5a\x89\xd4\x31\x2a\x5e\xa1\x03\x9c\xbc\x9d\x52\x06\x9a\xbe\x6b\x38\x82\x41\x2e\x4a\x0f\xae\x38\x6e\x1a\xa8\x70\x48\xf5\x45\xbb\x7f\xa9\x73\x99\x8f\xe4\x5c\x84\x06\x60\x46\xc4\x3f\x3f\xee\xad\x01\xf6\x5d\x5c\x45\xeb\x30\xb3\x54\xdc\x35\x56\x3a\x0f\x31\xab\x32\x08\x42\x1a\x8e\xb9\x95\xbb\x39\x80\xa9\xdf\xb6\x2a\xaf\xd7\xda\x31\x77\xae\x10\x31\x12\x6b\x9b\x6f\xbe\x39\x49\x09\x4d\xa3\x4f\x17\x26\xde\xd5\xa5\x4b\x06\x21\xc9\xd0\xe9\xd7\x00\x77\x55\xbd\x39\x16\x79\x67\xc0\x20\x02\xcd\x47\x06\x65\x40\xc2\x0c\x9d\x03\x63\x0f\x6e\x7f\x45\x75\x35\xbe\x05\xa1\x1a\x77\xa8\x3c\xf7\x97\xe3\x59\xe4\x85\x6c\x10\x7c\x66\x0f\x44\x34\xc0\x6f\x2b\x78\x03\x3f\xd6\x4b\xff\xb3\x54\x71\xe6\x15\xc6\xf3\x76\x60\xc2\xc8\x20\x0e\x28\x2e\xbe\x08\xde\xed\x96\xf9\x0d\x8c\x83\x96\x32\x88\x09\x65\x76\x47\xc6\xea\xfa\xd0\x9f\x1b\xa5\x69\xe4\xc4\x0a\x46\x9b\xfc\xc0\xdd\x96\x41\x9c\x4a\xcc\xdc\xc3\x3b\x2f\x4e\xa6\x94\x05\xa5\x03\x9f\xa0\xad\x73\x89\x81\xd9\xe9\x1d\x33\xc1\x32\xcf\xb8\x37\xaf\xab\xa6\x73\x56\xdf\x3c\x16\x49\x06\xb1\x0c\x31\x78\xf3\x78\x92\x6f\x67\xc7\x60\xe7\xf4\x1b\x7a\xe7\x4b\x06\x49\x60\x98\x43\x8a\xaa\x7a\xf3\xbf\x11\xe9\xca\xb7\xee\xeb\xea\x74\x74\x45\xae\x43\x77\x55\x06\x49\x1c\x86\x0e\x43\xde\xd9\x75\xdf\xed\x68\xfe\x14\xae\x7a\xe8\x83\xb3\xbf\xae\xac\xae\x23\xe9\xe9\x71\x10\xc4\xcf\x55\x19\x24\x89\xc4\x92\x94\x0f\xcf\x9e\xe6\x74\x2f\xaf\x2d\xea\x32\xa0\x81\xd1\x05\xdb\x19\x6e\x8b\xea\x78\x2a\x78\x9d\xb7\xe7\x0d\xb4\x88\xe3\x3a\x8d\x10\x2b\x8e\x27\x4e\x06\x94\x30\x0c\xd7\x73\xa5\x10\xf1\xfd\x9d\x70\x50\xd7\x5a\xa2\x4f\x74\x57\xd5\xaf\x7e\x18\xd1\x58\x51\x87\x07\x9c\x63\x2c\x11\x2b\x46\xaf\x42\x09\xed\x29\x2c\x25\xb8\x75\xf4\x5e\xeb\x66\xb6\xad\x16\x5f\xbc\x1b\xd3\x5c\xdb\xcc\xd5\x9c\x37\x30\x58\xbe\x65\x90\xd1\x10\x43\x5a\x1a\x5a\xb9\xb7\x72\xf0\x48\xde\x6a\x0a\xa8\xa7\x20\x72\x19\xf0\x30\x44\xaa\x30\x55\xcd\x5d\x6a\xf7\x37\x7f\x88\x62\xa1\xd7\xa2\xdd\x6f\x4f\x75\xf9\x73\x7e\x3f\x19\x9b\x22\x04\x84\x1a\xff\xb1\xd8\x6c\x97\xcf\xf7\x08\x71\xd8\x22\xa1\xb3\xbb\x84\xa0\x14\x63\xaa\x2f\xf7\xab\xdd\x8f\xe7\xce\x15\x5d\xdc\xee\x8c\xb5\xbc\xdc\xfe\xb5\x9b\xcf\x5e\x5c\x4b\x49\x0c\xd0\xac\x2f\x59\x1f\xdf\x4b\x11\xc9\xec\x62\xfd\x00\x75\x85\x78\xa6\x2f\x7a\x53\x71\x70\x63\x7a\xdd\x47\x3b\xdc\x41\x41\x11\x2f\x35\xe7\x2d\x7c\x8e\xa6\x07\x88\x04\xa7\xff\xe3\xea\x7e\xb7\x98\xd6\xf7\x21\xdb\x06\x32\x16\xf4\xcd\x25\xe6\xe3\xac\x96\xfa\xee\xc3\xb7\x9c\xf4\xb0\x4e\x0d\x97\x22\x52\xc2\xcc\x94\xba\x35\xc8\x89\xdf\x7a\x8b\x6e\x1c\x40\x92\x61\xa0\xa4\x32\x09\x0d\xd4\x1a\x28\x25\xcc\x79\x93\x97\xd5\xf0\x71\xc3\x90\x69\xb4\x93\x3b\x83\xef\x67\xde\x99\xd9\x13\x36\xbc\x71\xaf\x84\xa1\x90\x96\x48\xc5\xd1\x2a\x8c\x7b\x38\x24\x71\x8a\xee\xac\xe2\x2d\x17\x38\xae\x86\xdc\x40\x32\x8c\x42\x85\x2e\x31\xbe\xc7\xd3\xa5\x7e\xa5\x7f\xfc\x28\x8a\x0d\x6f\x3b\xb4\xb7\xd0\xc8\x3a\x3f\x5e\xd3\x56\x93\x61\x24\x12\xed\xf3\xe7\x36\xe9\xe5\x6e\x16\xa7\x09\x37\x25\xbe\x67\x27\x54\xed\x8e\x08\x81\x3a\x1b\xe2\x74\x9e\x9d\xda\x6a\xfa\x16\xb1\x26\x28\x78\x73\xe8\x3c\x4b\x9c\x73\x8f\xbc\x69\x4d\xd7\x38\x98\x9d\x6d\x9a\x04\x1a\xaf\x94\x97\x79\xfb\x08\xba\x75\x34\x40\x8d\x6f\x60\xeb\x2a\xef\x51\xa5\x68\x5e\x95\x0d\xc2\x17\x5a\x97\x5b\xa8\x7f\x1b\xdd\x9a\x66\x86\x67\x2a\x6f\x0c\x82\xe1\x1a\x2f\xb7\x0c\xa9\x34\x95\xdf\xb8\xd8\x67\xee\x56\x29\x09\x8c\x86\x03\x3f\xc0\x1c\x7a\x6c\x85\x0c\xd3\x94\x20\xe0\xf0\x9f\xd5\xf9\xb5\x5a\xac\x36\xdf\x93\x8f\xfc\x2d\x4b\x59\x86\x8c\x00\xa2\xa3\x0b\xde\x98\xe0\xcb\xb2\xd9\x0e\xb4\x72\x6f\x07\x11\x14\x77\x06\x4b\xb2\xc8\x27\x87\x6e\xa0\xbd\x42\x79\x28\x43\x96\x49\x1c\x94\x16\x6a\x30\x3b\xe4\xcd\x68\xd0\x32\x29\xb1\x4a\x0b\x35\x0f\x36\x50\x14\x0f\x9b\xcd\xbe\x3a\x7e\xbf\x97\x84\x59\x2c\x12\xff\xb4\xa3\x9a\x03\x77\xdd\x2c\xd5\x2e\xe4\x7a\x3d\x24\x25\xc3\x0c\x52\xe6\x54\xb0\xf2\xd7\x72\xba\x10\x86\xdc\x72\x7b\x22\x8f\xc4\x6e\x3b\x5b\xdf\x3b\x39\x16\x19\x4a\xaa\xdc\xcb\xff\x91\x7f\x2b\x26\x27\x91\x77\x1d\x65\xa8\x0b\x5e\x2e\xfe\x74\x57\x50\x41\x88\x75\x05\xbd\x65\x66\xf8\x15\xbf\x73\x4d\x64\xa8\x62\xad\xb2\x01\x95\xb4\x19\x9e\xdb\x7d\x5e\x2b\x8b\x22\xe9\x63\x56\x32\x84\x20\xc2\x82\x13\x03\xd3\x5f\xfb\x68\xc2\x18\xae\x69\x1b\xeb\x20\xc1\x1c\x0a\xea\xa2\x2d\xd5\x80\x25\xe0\x37\xc3\x33\x3d\x6d\x4f\x52\xa4\x93\xcf\xa5\xa1\x1c\x4a\x7e\xf3\x07\xb4\xb0\x22\x8b\x51\x1f\xc7\x95\xa1\xd6\x21\x5a\xaa\xe8\x02\xdb\x1f\x49\x10\x6b\xcc\xd6\x4b\xa8\xdb\x5c\x9f\x9f\x78\xd9\xe3\xab\xfe\xed\xda\x50\x8a\xcb\xc7\xd3\xec\x4f\x47\xea\x31\xbb\xfd\x63\xb9\x59\xad\x37\xbb\x97\xd9\x7a\xfb\xbc\x58\x6f\xfc\xf5\x24\x60\x1c\x1d\x99\x04\xa7\x34\xb4\x92\x04\x2a\x4d\x06\x1a\xdf\x6b\xae\x75\x01\x2f\xb6\x8a\x61\xd4\xd5\x24\xd0\x12\xed\xfb\x27\xa8\xdf\x3a\x6f\x01\x60\x5d\x55\x56\x79\x6c\x10\x2c\xb2\xad\x43\x96\xe2\x9a\x7e\xcf\x0f\x16\x8f\x3d\x75\x07\xae\x8d\x68\x36\x34\xb8\x09\x89\x63\x84\x6e\xdf\x2e\x1e\xdc\x40\x23\x84\x02\x26\xd6\x77\xc7\xba\xea\xcc\x6f\x7b\x7d\x77\x38\x0a\x03\x1a\xd8\x18\x28\xaf\x27\x6f\x10\xa5\xd2\x92\x78\x1e\xf2\x72\x67\xb8\xe9\xc4\xa9\x2e\xa7\xcd\x64\xea\xb8\x97\x1d\x03\x9b\x9b\xfa\x37\x67\x64\x0b\x42\x7b\x7d\x8a\x69\xb9\x9a\x44\x1a\xf5\x49\x1c\x12\x34\x2f\xef\xa1\x9d\xef\xf3\xa3\x67\x15\x76\x56\x24\x89\x43\xe1\x90\x4d\xf3\xbc\x3d\x63\x88\x7c\xfc\x6c\x31\x4f\x1d\x16\x7c\xf6\xce\xf3\xa2\x5b\x8b\x5c\xf0\x69\x34\x1c\x49\x2c\x59\x6a\xc4\x65\x5a\xe8\x56\x92\x52\x41\xbd\xd2\xd3\xcb\x01\x51\x26\xbf\xde\xf4\xbc\xaa\x92\xd0\x38\x43\x50\xd6\xd3\x79\x0b\x76\xf9\x0b\xfd\xb1\x44\x61\x18\xb6\xf3\xa4\xef\x00\x16\xcc\x86\x28\xae\x7b\x24\x84\xf6\xc8\xd0\xbb\xaa\x6a\x05\x2f\x8a\x91\x90\x82\x6d\x96\x0a\x62\x95\x6e\x7f\x29\xaf\x37\x5e\x01\x08\xd3\x1c\x70\xd3\xcd\x5f\xbf\xa0\xe9\xee\x8d\x64\x92\x25\x86\x6b\xd1\x16\xd7\x1d\xbb\xf6\x36\x10\x1d\x07\xff\x18\xc4\x5a\xba\xa6\x80\x85\x50\x33\xa5\x76\xb7\x95\x1c\x26\x20\xae\xba\x9f\xa3\x9d\x9b\x64\x2a\x0d\x3d\xdd\xbb\x61\x53\xc0\x22\x49\xb7\x73\x12\xae\x63\xb4\x25\x9e\xf2\x76\x5f\xe7\xc5\xec\xd3\x2d\x52\x44\x48\x6d\xe6\xd9\xec\xcf\xcd\xec\x71\xb1\xe9\x4d\x40\x22\x13\x1e\xda\xce\x9c\xf3\x1a\x17\xe9\x2f\x18\x59\x4f\x43\x4a\xb7\x0b\x78\xd5\xa8\x9a\xd6\x5e\x5b\x25\x0a\xa9\x40\x9a\xf3\x41\x54\xc5\x55\x60\x99\x24\x20\x33\x03\x6b\x39\x41\xd3\xec\xda\xcf\xb1\x17\x44\x34\x35\xfa\xf3\xa6\xa8\x74\xaa\x11\x78\x75\x37\x88\x82\x08\xb0\x78\xff\x26\x6f\xa1\x91\xb9\x45\x0c\xc9\x28\x48\x8c\xd3\xd6\x40\xfb\xb3\x2a\x3b\x4f\x7e\x3c\x64\xa2\x40\xf0\xc4\x6e\x39\xdb\xbc\x3d\x15\x3c\xaf\x61\xd7\xb9\x13\x2d\xec\xe2\x69\x5b\x15\xa6\x46\x21\xb5\xac\x4e\xa5\x84\x65\xd3\x9c\x06\x26\x53\x14\xe8\x14\xa1\xfe\xad\xe5\xf6\x1b\x9f\x4d\x28\xc7\x3d\x1b\x2b\xa7\xef\x4e\xa5\x7a\xf8\x39\x77\x67\x12\x19\x98\x0a\x7e\x47\x16\x2a\x23\x02\x41\xe8\x08\x14\x1c\x61\xf1\xd5\xb1\x1b\x45\x60\xe2\x2b\x9d\xc9\x50\xc9\x37\xd7\x51\xa6\xea\x6d\xd2\x4f\x71\xc8\xac\x9b\xfb\xa3\xb3\x2c\x87\x94\x8f\xe3\x8b\xc6\x11\xc7\x68\xa7\x72\x53\x77\x1c\x64\xeb\x1a\x68\xfc\x4a\xce\x1e\xd7\x27\xcf\xcb\x2a\xa3\x38\x83\xc4\xa9\xa2\x9e\xca\xc3\x68\x0b\xfe\xd6\x06\x89\x62\x99\xa5\x16\x97\x71\xb7\x5c\x6f\xb6\xbb\xcd\x76\xf1\xb2\x43\x68\xf7\xa4\x3f\x53\x2a\xa5\x29\x98\xeb\xb7\x54\x77\x28\x25\x98\x0a\xc0\x79\x73\xe4\xb9\xaa\x4e\x6e\x55\x8a\x18\x89\x41\xfb\xd1\x35\x7e\x35\xb7\x37\x46\x4c\xc5\x88\x01\x3e\xf2\x53\x03\x4f\xd3\xf2\x17\x19\x65\x61\xa6\xa5\x07\x35\xa2\x50\x99\x2d\x83\xb9\x40\xe1\xc9\x28\x13\x29\xae\x2d\x9d\xcd\xd9\xe0\xae\xe8\x36\x9a\x88\x93\x00\x43\xe1\x7f\xe4\x4d\xcb\x87\x5b\x6a\xc4\x39\x47\x1d\x97\xa6\xe4\x79\xe1\xd9\xac\xbb\xdf\xa5\x76\x82\x5b\x5d\xfb\x6d\xb5\x68\xf7\xe8\x79\x8e\x36\x81\x48\x50\x43\xc4\x5e\xe7\xaf\xfb\x96\x45\x93\x47\x92\xc4\x10\x76\x1a\x65\x1b\x13\x7c\xfc\xa8\x2e\x99\x44\x65\x04\x94\x63\x81\x06\x46\x99\x6f\x90\x7b\x77\x3c\x0e\x80\x42\x20\x8d\x5d\x52\x56\x87\xfc\xa2\xc2\x5b\x46\xc0\x00\xd7\x1b\x2b\x2d\x60\x0d\xda\xc9\x55\x78\x8a\x09\xeb\x03\xc6\x45\x1e\x78\x33\x22\x8a\x18\xad\x8a\x71\x10\x66\x3a\x1e\x85\x3c\x3a\x67\xe3\x0a\x6b\x9d\x5d\x9b\xec\xae\x62\xff\xe8\x4c\xae\xe1\x9f\xb6\x91\x67\x05\x30\xff\x70\x23\x21\x0e\xe2\x00\x47\x99\xb1\xa4\x79\x01\x9b\x23\x6e\x82\xdb\x4f\x57\x9b\x30\xea\xaf\x38\xcc\x8c\xb0\xf6\x66\x3b\xff\x7b\x23\x3e\x8e\x38\x91\x7c\x10\x86\x9e\x7d\xc5\x73\x3b\x39\x2f\x4e\x03\x2d\x2c\xe5\x81\x67\xe8\xb6\xc7\x12\xaa\x9c\xd4\xda\x62\x3d\xbf\x2a\xb3\x2a\xe3\x24\x4d\x4c\x34\xdb\xd3\xf8\x20\xd7\xfe\xa8\xaf\x69\x44\xa3\xc4\x31\x47\x36\x46\x59\xb7\x99\x34\x89\x65\x64\x60\xcf\x32\x87\x77\x58\x83\xe7\x4a\xbe\xfe\xdc\x94\x13\xec\x51\xae\x94\x89\xb8\x4f\x67\x5f\x8c\x62\xd4\xdd\x9b\xed\x79\x03\x2f\x27\x51\xe4\xb2\xeb\xf9\x68\xb7\xad\xdc\xb3\x33\x12\x18\x89\xad\xce\x12\x30\xa5\x87\xea\x2a\x43\x89\x8c\x19\x0f\x30\xc9\xc9\x71\xdc\xed\x7a\x9d\x76\xdf\x11\x59\x6c\xf4\xcb\x4d\xe4\x00\xe3\xb1\x26\x46\x8e\xcf\x77\xfb\x6d\x3c\x5e\xc6\x22\x0a\x33\xc7\xb7\x01\xf2\x54\x43\x4f\x64\x24\x63\x01\x29\x4e\xc3\x3d\x6f\x2c\x7f\xff\x6f\x93\xb3\x75\x88\xa4\xa6\xb9\xac\x06\xc4\x65\x32\x96\x61\x8a\x9c\x40\x7b\x3e\xa9\x7d\x96\xb1\x04\xae\xb5\x63\x6f\x39\xd5\x12\x86\x02\x15\x5f\x0c\x32\x15\x44\xa8\x71\xb7\x59\xdd\x6d\xe7\xb3\x97\x61\xf0\x28\x56\x81\x44\xf8\xd9\x07\x6f\xee\x2b\x5e\xb8\x74\xaf\x3b\x1a\x1b\x28\x49\x83\xaa\x7d\x28\x4e\x51\x7d\x9e\x27\x8f\xa4\x52\x99\x64\x9e\x79\xeb\xa5\xae\x8e\x93\xd0\x66\xac\x44\x2a\xdd\x76\xe6\xea\xd3\x27\x26\xe7\x65\x84\x26\x56\xda\x6c\x32\x37\xcb\xdf\x37\xbf\x4c\x73\xc8\x18\x12\x83\xe1\x54\x60\xa6\xd2\x63\x25\xdf\x26\x37\x99\xf4\x0b\xb0\x88\x19\x65\xfe\xb2\x7d\x86\x8f\x71\xc0\xc6\x3f\x06\x30\xca\x91\xa0\x89\xe7\xc5\xf9\xbe\xae\x3e\xda\xfd\xee\x78\x3c\xb8\x2e\x02\xc9\x0d\xeb\x03\x2e\xc8\x23\x16\x22\x19\x83\x26\x21\x58\x0d\x96\x12\xc5\x60\xd0\xf8\xe7\x5f\xc7\xfb\x0d\xc1\xcc\xdf\x8b\x30\xc4\x3a\x01\x2c\x09\xb3\x36\x87\x9b\xea\x0d\x19\x4f\x52\xcd\x24\x9a\x26\xb7\xf0\x9e\x77\x86\x8b\x93\xf5\x54\x93\x0f\xa9\x05\x37\x65\x70\xb6\x42\xb8\x72\xd5\x70\x32\xd6\x40\xd0\xc9\x3b\xee\x10\x33\xf9\x39\x90\xdd\x1d\x3d\x52\x12\xa4\xa6\xb2\xa2\xdb\x37\x51\x57\x67\x80\x47\x91\x49\x90\x85\x10\xf9\xa5\x29\x25\x61\xb7\x2a\xbd\xf0\x81\xdc\xcc\xe8\x89\x92\x40\x48\x62\x4b\xec\x0c\x88\xa7\x18\xd2\xdd\xc8\x24\x0c\x0c\x11\xa1\xe7\x99\x38\xb5\xb3\xc2\x28\xcc\x34\xbe\x0d\xd7\xd4\x82\xd7\x5f\x56\xab\x47\x5b\x7c\x9b\x8e\xba\x28\x21\x89\xc0\xe0\xfb\xa9\x74\xee\xc3\x06\x8a\x31\x75\x4e\xd7\x48\x61\x4e\x1e\x4a\xf5\xe4\x5d\x05\x77\x8c\x26\x98\x4f\x34\x1b\xdc\x9a\xe7\x7d\x14\x33\x21\x94\x06\xca\x27\xfd\xf5\x33\x3f\x18\x01\xe1\xf1\x23\x44\x01\x60\xdf\x7c\x40\x6e\x74\x1f\xdc\xe9\x9d\xb1\xe3\x2a\xe3\x78\xd3\x7c\x54\xf5\x75\x8b\xdd\x36\x8f\x23\x89\xb5\x46\x3b\x38\xe4\xed\xe6\x2d\x2f\x0a\x5b\x75\x94\x03\x4a\x1a\x7f\x97\x58\x96\x49\xac\x42\xa4\x78\xf8\x7d\xfd\xd7\xcb\x66\xbb\x5e\x3d\xdf\xff\xe6\x8f\x68\x27\x76\x64\xcd\x1d\x63\x32\x5c\x9d\x5b\x49\x12\x87\xa2\xaf\x09\xb4\xfb\xe6\xa4\x3f\x13\xca\x0c\x18\xc2\xa0\xb4\xfa\xfd\xe7\x7b\x19\x88\x6f\x9c\xa6\x24\x81\x08\xeb\xf9\x90\x7a\x82\x17\xb6\xca\xc9\x1e\xa4\x71\xa6\xd8\x84\x15\xd8\xd0\x2d\xce\xbb\x1d\xe1\x8a\x05\x94\x50\x1e\x69\xaf\xae\x6d\xc3\x41\xfe\x72\x42\x23\xb3\x87\xc9\x00\xcc\xd6\xf3\xeb\x8c\x5b\xd8\x10\x33\x94\x4b\x54\x59\xb6\x6f\x6a\x8f\xa5\x24\xc4\x31\x85\x28\xfe\x0d\x2f\x5b\xa4\x3f\x6b\xee\xf3\x77\x28\x6f\xce\xcf\x55\xdd\xee\x5f\xaa\xa2\x6f\x2e\x83\xd0\xc6\x6d\x96\x4f\x3f\x9e\x76\xf3\xd5\xf3\x76\xbd\xbc\xf9\xb1\xf5\x18\x13\x99\xa4\x4a\x20\xba\x79\x77\xe8\x85\x0d\x06\xf6\x4d\xff\x5c\xa9\x4e\xb8\xa9\xc6\xbe\xcd\x9b\x81\xf2\x8c\x4c\x58\x1a\xe3\xce\x75\x2c\xf8\xf9\x7e\x40\x37\x31\xb9\x40\x96\xc4\xb8\xfe\x70\xa5\x66\xc7\xe3\x17\xdc\xc1\xae\x6d\x0a\xae\xaa\x65\x5e\x77\x73\xf0\x66\x82\x47\x96\x49\xa6\x05\x42\x95\xb9\x45\xcc\x0d\x6d\xe2\x84\xa7\x2a\xb4\xb5\x15\xfe\x69\x07\x2b\x0b\xe7\x0a\x0b\x84\x31\x27\x83\x26\xf1\xcd\x79\x89\x56\xc1\x13\xd4\xdd\x20\x6c\x6f\xce\x98\x6c\xba\x26\x09\xd0\x9d\xae\x13\x5b\xee\x74\x6b\x85\xe7\x9d\x89\x37\x69\xa8\xd3\xd0\x49\x43\x55\x85\x5a\xf0\xba\xcc\xcb\xd7\x69\x2b\x41\x19\x56\x4b\xe4\x12\x53\x68\xee\x1d\x84\x02\x04\xc5\xcf\xab\x65\xd9\x9c\x6a\xb8\x31\x75\x19\x83\xb7\x94\x34\xc5\xef\x6b\xf0\xf5\xcb\xb2\x2d\xfc\x11\x1e\x22\x02\x06\x06\x22\xb6\x88\xee\x59\x95\x7e\x74\x48\xa9\x81\x8d\x02\xa0\x9d\xab\xd9\x2c\x4b\x2b\xe0\xfc\x55\x9c\x69\xfc\xf0\x8a\xa4\x96\x1b\xba\xdd\x9e\x0f\x63\xfe\xe1\xf1\x37\x55\x34\xc4\x4a\x1e\x8c\x80\x4d\x0c\xb9\x44\xc9\x94\x59\x37\xa3\x37\xe3\x0c\x54\xe5\xf6\xc2\x4f\x4a\x14\x40\x68\x0d\xa9\xbb\xbc\x80\xd9\xf4\x56\x90\x71\x5c\x97\xe4\xe1\xb8\xf8\xef\x85\xbd\x33\x18\x08\x90\x01\x26\x08\x76\x68\x40\x86\x23\x6f\x24\xd1\x69\x28\x53\x5f\x73\xb3\xd2\x2f\xdd\xb7\xb3\x59\x11\x3f\xf8\x35\x8b\x32\x13\xef\x2c\x61\x24\xf8\x26\x69\x90\x65\x8e\x9b\x7a\xeb\x75\xed\x9b\xd9\x2b\xcf\xcb\xe6\x2a\xf1\xa2\xa4\x61\x10\xa2\x3b\xea\x36\xe7\x27\xcf\xbd\x33\xc6\x09\x5f\x4b\xd9\xfa\x4b\xe8\xc4\xee\x9a\x4f\x39\x92\x04\xf5\x4b\x15\x73\x6d\xd2\x20\x36\x64\x5c\xc6\xc6\x9d\x82\xad\x25\x25\x8c\xa1\x5b\xbb\xdd\x83\xdc\xf3\xc3\xb1\x97\x16\x94\x94\x64\x89\xb0\x2b\x23\xee\x4c\xdd\xe0\x72\x9a\x75\xcb\x12\x87\xe9\xc4\xd7\xa1\x31\xa7\x58\x97\x78\x72\xd2\x62\xc3\x7e\x4a\x18\x27\x9d\xc1\x67\x5e\x71\x39\x5f\x99\x02\xb0\x6f\xb7\x1e\x9a\xc8\x18\x6d\x8c\xe6\x83\x1f\x17\xdb\x87\xa7\xdf\xd7\xd7\xb3\x6c\x34\xd1\x56\xfa\xd9\xe6\x80\xa6\x6f\x9a\x26\x1c\x3c\x47\x73\xb3\x13\x4e\x9c\x4b\xd2\x34\x55\x58\x12\xde\xed\x47\x93\xc8\xc6\xf5\x65\x8b\x32\x69\x14\x73\x4c\xad\xab\xb5\x27\x5f\xea\xaa\xd2\xbf\x5d\xf1\x36\xc3\x8c\x0c\xc3\xb5\x34\x63\x8c\x11\x4f\xdf\x77\xe2\xc5\xf3\x69\x12\x83\xa2\x59\x96\x05\x89\xaf\x74\xb4\x40\x76\x77\x8c\x0b\xac\xab\x44\xdf\xc4\xbc\xcd\x30\x11\x4d\x05\x89\x30\xbf\x60\x10\xc0\x53\x9e\xf2\xf1\xb4\x46\x4d\x47\xee\x46\x51\x67\xbd\xc0\xb2\xc4\x2c\xc3\x52\x2f\xcb\xbb\xaa\x7e\x33\x09\xce\x01\x94\x5b\x52\x91\x31\x0c\x7a\x9d\x8e\x6a\x96\xd7\xb7\x4e\xb5\xd1\xe9\x94\x0d\xc6\xa8\x24\x21\x5a\xc9\x73\x7e\x3c\xc2\x40\x4f\xe3\x5b\x03\x96\xca\x28\x43\x37\xf6\xbd\x6a\xa1\x6e\x46\xb6\x1d\x95\x29\x60\xc7\x18\xd7\xcd\x08\x1d\xfa\x63\x40\x42\x1b\x28\x5a\x96\xef\x55\x2e\xc7\xfa\xb2\x6e\x49\xf8\xb5\xc1\x40\x15\xa1\x38\xb7\xfc\x13\xbb\x9a\xfe\xeb\x9d\x08\x89\xa1\xfb\xdc\xb4\x55\x9d\xff\x97\xcf\x3d\xb7\x89\xa4\x20\x32\x4c\x8a\x8a\x01\xb5\xb4\x3d\xa4\x43\x93\xda\x32\xa5\x7c\xb8\x0c\x38\xcc\xce\xa8\xbb\x75\x14\x62\xb2\x16\xd5\x6e\xae\xef\xb9\x54\x47\x26\xb7\x7e\x6a\xa0\xf6\x6c\x2f\xee\x98\x50\xf8\xb9\x16\x25\xd4\xaf\xf9\x70\x46\xa6\x41\xc8\xb0\xd8\xa6\xc1\x8a\xab\x9d\xf4\x1a\x2c\x32\x0d\xa8\xd1\x4c\x2a\xaa\xd7\x1f\x65\xfe\x0e\x75\x03\x16\xd4\x30\xe7\x45\x6f\x14\xa4\x01\x37\x45\x2a\x27\xfb\x7e\xec\x1f\x17\xff\xff\xbf\x30\xa5\xff\xf6\xcd\x15\x5a\xbd\x66\xf1\x7f\xca\x4b\x2c\x9b\x1c\x0d\xe0\x34\x0c\x23\x47\x06\x6c\x40\x93\xdd\xda\x58\xfb\xa3\xc4\xa8\x51\xb7\xe8\x8c\x60\x9d\xca\x1a\xb0\xf7\x1e\x31\x23\xb1\x86\xf7\xbc\xc9\xab\x72\x51\x62\x80\xca\xfd\xb3\xf1\xe7\x8b\xd0\x95\x79\xdd\xf3\x66\x0d\xff\x1d\x7f\x96\x34\x54\x41\xa8\x0c\x77\x3c\xee\xe1\x23\xa7\x35\x25\x41\x8c\x21\xdb\xbc\x71\xae\x2f\x1c\x3d\x3f\x88\x4c\x49\x4a\x24\x0c\xd2\x0d\x7f\x40\xa9\xbe\x20\x2d\x94\x69\xa4\x08\xb2\x19\x14\xd5\xab\xa5\x70\x18\x0e\xc2\x34\x0e\xb3\xc4\x42\xd8\xb6\xdb\xc7\xc9\x53\xc6\x99\x24\x46\x1a\x6c\xe6\xee\x1d\x43\x14\x87\x83\x82\xa2\xbc\x7c\x1d\x46\xb7\x2f\xf0\xab\x32\x4d\x42\x8a\x51\x95\x27\x2e\xff\x75\x02\x18\x65\xf0\xd2\x84\x84\x52\xf8\x65\x64\x0d\xc7\x93\xe1\xaa\xc7\x8a\x98\x65\x79\x73\x2a\xde\xbe\x76\xd3\x53\x9a\x1a\xb6\x41\x93\x11\x5d\x95\x60\x68\xdc\xa7\xa0\x5a\xd7\x9a\x99\x72\xb7\xce\x64\xb8\x39\x8f\x18\x3a\x5d\x0b\xc1\x30\xc2\xb7\x73\x55\x41\x1f\x8e\x79\xb2\xef\x93\x34\x53\x18\x62\x46\x48\x23\xc2\xe0\x9a\x69\x0b\x9d\x61\xac\xfb\x3f\x55\x3e\x66\x7b\x91\x29\x0b\x18\xb5\xd0\x95\x9b\x53\x5d\x3e\x7a\x3a\x41\x99\xb2\x38\xcb\x92\x0b\xb4\xa2\x49\xbe\xf8\x36\x54\x18\x49\x85\x6e\xed\xb4\xf0\x83\xd1\xa0\x66\xa9\xa9\xb8\xe3\x2e\xbb\xe6\xe9\xf8\x31\x40\xe5\x5a\x31\x8e\xd3\x43\x54\xd5\x5b\x5e\xbe\xde\x41\xff\x10\x59\x80\xf0\xa2\x35\x34\x23\x10\xcb\x45\xee\x65\xdc\x6f\x4c\x0a\x2c\x46\x59\x6c\xaf\x70\x8f\xc9\x94\x29\x4e\x9c\x84\x58\x0d\x3a\xff\x34\x36\xc4\x68\x1c\x66\x10\x39\x42\xc1\xfb\x6e\xea\xd7\xe7\x0d\xbc\x43\x79\xc5\x31\x4a\xb9\xe6\xc8\xb8\x51\xc3\xeb\xe6\xe8\xf8\xea\x7b\x3a\xe8\xf1\x47\x17\x32\x0b\x2c\xad\xaa\x73\x1d\x79\xdd\x3a\xcc\xb9\x7b\xef\xee\xbf\x6e\x1d\x12\xf0\x72\xaa\xbf\x40\x71\xa5\x32\x0b\x50\x1d\xf9\xae\x86\x66\xff\x93\xb7\x50\xdf\x15\x95\xef\x54\xc9\x33\x3c\x6a\x41\x28\x37\xbc\x7c\xab\xab\xa2\xb0\xca\xf4\xdf\xdb\x1f\xa9\x94\xd4\xba\x87\xc5\x45\x61\xc9\xc0\x1c\x4b\x55\x2c\x63\x83\x05\xf7\x65\xf3\xdf\xe6\xa7\x52\xa5\x00\xab\x91\x50\xb7\xeb\x85\x9f\x6f\x4e\x5a\xbb\x27\x56\x60\xaa\x7d\x6d\x64\xb2\xaa\xa1\x1d\xc2\x63\x52\x08\x48\x64\x56\xa1\xe7\xaa\xe5\xf5\xf9\x0f\xe8\x9c\x27\x69\xcc\xb4\x2f\xeb\x20\x71\xf3\x33\xff\xeb\xad\x91\x14\xd2\x00\xad\x91\xea\x1d\x6a\x5d\x54\x1f\xc3\xa2\x11\x99\xea\x30\x31\x98\x1f\x63\x46\xac\xf4\x64\x3d\xd4\x91\x36\x7a\x97\x28\x3f\x7d\x3a\xbb\x47\x64\x61\xb7\x4e\x77\xfd\xb6\xaf\x2c\x5f\xed\x86\x6b\xb8\x60\x10\x1a\xf7\x36\x0b\xe3\x24\xb0\x63\x6d\x76\x55\x5d\x5f\xb2\x50\x2b\xa4\xea\x9b\x29\xf5\x54\xa9\xb1\x90\x99\x6d\x42\xa2\x28\x35\xd4\xbf\x67\x9b\x27\x8b\xdd\x63\x91\x24\xc0\xe8\xb5\xcb\x51\x3d\xae\x5d\xc6\x8d\x45\x81\x8e\x85\xdb\x8f\x0f\x47\x94\x4b\xdd\xf2\xe6\xcd\xbf\x52\x14\xc7\xa8\x8d\x74\xf7\xb8\xfa\xd7\xd2\xff\xc8\x42\x6d\x00\xe0\xa5\xca\x7b\x05\x34\xc9\x62\x92\xa1\x89\xff\x9f\xa3\x41\xed\xf8\xdf\x23\x83\xed\xbb\xa9\xab\x8f\x32\x87\xbe\x38\x4c\xb2\x98\x1b\xf8\x96\x29\x22\xed\xf6\xb6\xce\x5d\xcb\xab\xd2\x2b\x06\x76\x6d\x20\xb0\xfa\x40\x58\xac\xfe\x17\xf0\xbe\x36\x72\xc0\xfe\x34\x70\x03\x58\xd2\x6d\x4c\x3e\xc1\xe5\xc6\xff\x24\x7a\xea\xdb\x9a\xc0\x98\xe4\x7d\xdc\xf2\xea\x00\x46\x22\x6c\x57\xe4\xb4\xad\xb9\xba\xb4\xe4\x7f\x55\x14\x32\x3c\x7e\x59\x12\x74\xd5\x0f\x65\x94\x4b\x47\xb7\x61\x6c\x88\x4b\x30\x03\x4b\x43\x33\x67\x91\xfa\xfc\xb1\xfa\x18\xd0\x31\x48\x96\x52\x30\x82\xc0\x56\x2b\x3a\xb4\xbf\xb3\xc8\xa4\x75\x76\x07\xfe\x89\xa3\x79\xe4\x24\x32\x9e\x18\xb1\x45\xfb\x34\xd0\xd0\xc9\x4d\x39\x44\x88\x62\x72\x2b\x17\x13\x41\x42\x2c\x95\x03\x62\xe3\x7d\xf0\x91\x89\xc8\xa4\x67\x9f\xb6\xeb\xf1\xaa\xfc\xbd\xe0\xa9\x3b\x3b\x36\x72\x35\xd2\x45\xab\x1e\x3d\xe3\xb1\x64\x2a\x10\xa1\x8d\x8d\x6e\x4e\xa2\x91\x75\x2e\xa0\x36\xbc\x24\x83\x26\x52\xf7\x24\x2e\xb7\xb3\x55\xb3\xbc\x4e\x89\x23\x99\xa2\x09\xd6\x4d\x1c\xf7\x70\x1c\xe1\xc9\x98\x02\x8e\xe5\x44\x58\xbb\xb1\x5b\x3c\x6f\x76\x65\x1f\xc0\x62\x10\xc7\x96\x96\x03\x99\x69\xf2\x0a\x1d\xd4\xf1\xbb\x5e\xb7\x16\x7f\x19\xdf\x66\x90\x44\x48\xa7\xe9\xe8\xc1\xed\xcf\x3a\xc8\x30\xe9\xf4\xc2\xcf\x77\x55\x6d\x69\x0c\xe6\x0f\x8f\x8b\xf7\x2b\x8b\xbc\x3b\x27\x4e\x8c\xba\xc1\x1e\xe4\x9b\x05\x60\xef\xf3\xe3\xa5\xdb\x30\x1c\x9a\xe6\xdc\x2c\x90\x91\x72\x6a\x62\xbc\x44\x39\xc8\xdf\xfc\x0a\xeb\xda\x68\xc0\xe5\x6c\xde\xb9\xd5\x0a\x85\xd6\x1c\xcd\x8a\xcc\x42\x12\x20\x39\xf5\x21\x2f\x6d\xc5\xed\x48\xca\x54\x66\x84\x04\xc8\x82\x39\x7f\x9a\x0d\xd5\x21\x64\x46\xa2\xc0\xe9\x29\xdb\x9d\x73\x42\x66\x20\xb3\x58\x05\x68\x43\x2f\x9f\x6f\x16\xdb\xd1\xc9\x49\x64\x62\x55\xf3\xf9\x6c\xf3\xf0\x4d\xc5\x83\xcc\x12\xa6\xd3\x78\x20\x20\xa4\xbb\x5d\x66\xe5\x36\xa9\x8c\x46\xa6\x2c\xf5\xa5\xfa\x39\x53\xef\xf3\x71\xc1\xb1\xcc\x68\xc2\x99\x2f\xee\x99\xc2\x3e\x86\x38\xf3\x8b\x5e\x1e\xfd\xdb\x5e\x2d\x8d\xbc\x5e\xdd\x1f\x55\x0b\xf3\x5f\x4a\xdc\xc9\x2c\x65\x31\x26\x1d\x76\x2e\x31\x6e\xe3\xef\xd3\x56\xa6\xda\xdc\xc9\xb2\x0d\xdc\xd7\x2c\xe5\x0c\x99\x3e\x7e\x6c\x17\x83\xf8\x9a\x7b\xc1\xd4\x56\x2f\x75\x7d\xbf\x28\x95\x73\x11\xc7\x73\xd7\xb5\x95\x04\x03\x06\x1e\x7d\xb9\xe1\x4a\x15\xf0\x6b\x04\x66\xc6\x42\xc3\xa7\x6e\xc5\xc0\x0d\x39\xbe\x1f\x22\x19\x15\xc2\xea\xe8\x1c\x4f\x2d\xac\x8e\x50\x4e\x13\x38\x59\x26\x02\x47\x2e\x72\xf7\xf3\xb6\x3b\xb6\xd8\x3e\x4c\xda\xf0\xd0\xc4\x20\xc7\xe9\x90\x71\xc6\x28\xe3\x89\xa4\x06\x4b\x85\x25\xf9\x28\x7e\x0a\x86\x5d\x62\xfc\xcc\x32\x54\x71\xe8\xa6\x95\x9d\x89\x77\x13\x3e\x4f\x99\x49\xa2\xb9\x4b\x5a\x0e\x97\xda\x4c\x26\x19\xd6\xc3\xe8\x11\x1b\xd9\xf7\xab\x42\x26\xb3\x54\x99\x50\x97\x3e\x95\xea\xe6\x3c\x2a\xe8\x71\x6d\x04\x43\x9e\xc2\xee\xc2\x03\x27\x3d\x53\x59\xa6\x8c\x76\x14\xb7\x91\xcd\x21\x27\x85\xcc\x80\xa4\xc8\x2e\x8f\x55\xa6\xbb\x9f\xcb\xe7\xfb\x8d\x3f\xc4\x32\x41\x1d\x9d\xe0\xdf\xd0\xef\x74\xa7\x71\x6d\x54\xfe\xdb\xbc\x40\x2d\xe1\x0f\xef\x51\x67\x9a\x26\xd2\xb9\x1b\xb9\xba\x00\xf3\x65\x9a\x27\x58\xb2\xd0\xec\x79\x3d\x0a\xb0\x65\x5a\x72\x74\x6f\x8c\xcb\x36\x3b\x1e\x97\x28\x83\xd2\x3b\x0b\xa6\x1d\x0f\xc2\x20\x34\xd4\x63\x15\x0e\x98\x9d\x70\x04\x36\x92\x07\x34\x70\xa2\x35\xb3\xd6\xc6\x8b\x7d\x3d\xc6\x75\xf4\x16\x0f\x74\xe4\x13\xc2\xbc\x38\x41\x38\xee\x77\x1e\x06\x06\x97\x80\xa3\xff\x27\x00\xb2\x9d\x2d\xe7\x2b\x0c\x34\x2d\x9a\x36\x3f\xf4\xd3\x8a\x87\x91\xd2\xe1\x20\x63\xfb\x4d\x0d\xde\xd8\x34\xe0\xa1\xce\x22\x07\xdc\x82\x66\x12\x2b\xe6\x11\x21\x46\x0b\xc0\xdb\x48\x37\xa7\xf3\x0d\x97\x6f\x77\x9e\xd0\x48\xf2\x28\x06\x3e\x30\x77\x9b\xdd\x78\xcc\xf2\x28\xe1\xb8\xac\x72\xa5\x06\xd8\xbd\x7e\x3d\xbb\x46\xd6\xfa\xdd\xff\x43\x3a\xc6\xa3\xb8\xdb\x88\x44\x5b\x8a\x9b\xce\x1c\x79\xe5\xcd\xf1\xd2\xdb\xe2\x91\xe2\x68\x92\xec\xde\xab\x93\xdc\x43\xdd\xdc\xfa\x08\xff\x48\x94\x41\xf2\x48\x4b\xdc\xac\xfb\x14\xc0\x4b\x9d\xff\x0f\x26\xf3\x96\x27\x94\xe0\x38\x6f\x3e\xf2\x56\xee\x3b\x23\x98\xb7\xb9\x28\x80\x90\x08\x3e\x07\x0b\x23\x4f\x32\xaa\xbd\x48\xc2\x72\xbe\x9a\x17\x83\xfa\x0c\x9e\x88\x04\x97\xd4\x3a\xec\x7f\x51\xa6\xde\x00\x9a\x76\x59\xb6\xb7\xe7\xd2\x10\x3c\x8e\x67\x05\xa7\x24\x14\x96\x61\x7b\x71\x10\xbc\x69\x26\xa0\x02\x9e\x32\x6e\x80\xb6\xa5\xa3\x35\xf2\x60\xd5\xdf\x06\x4d\xc0\xe9\x67\xd6\x75\xf5\x01\xf5\x1a\xda\x53\x5d\x2e\xda\xfd\x0b\xd4\x77\x39\xbf\x02\xc8\xe2\xa9\xc8\x9c\x3c\xbe\x11\xe0\x1a\xd0\x49\xff\x63\xd2\x54\x12\x23\xd6\xc8\xdd\x2a\xcc\x39\x31\x31\xb0\xd5\xe7\xa8\xec\x8b\xf3\x34\x42\x24\x47\xb7\x22\x8d\x24\x16\x25\xe7\x42\x52\x4b\x73\x83\xfd\x5c\x4e\x75\xdb\x27\x77\x95\x9c\x62\x51\x3c\x12\xb8\x6e\xf3\x57\x57\xb1\x68\x0f\xab\x48\x8b\xc0\xcf\xfc\x3b\x98\x7a\x02\xfd\x85\x94\x0a\xb0\x08\x02\xd3\xe1\x23\xd9\xc5\xee\x98\x08\x0c\x9f\x99\x1a\x12\xb5\x8e\xbf\x01\x30\x9f\x39\xef\x36\x32\xe4\x27\xba\x8c\x2c\x70\x50\x51\xd0\xa7\x7a\x47\xd4\x47\x93\x57\xd3\x24\x91\xe0\x04\x50\xfc\x90\xd1\x11\x4d\x6d\x74\xd4\xba\x8f\x4e\x67\xe3\x86\xb7\x6d\x01\x68\x52\xdf\x9c\x97\x93\xfd\x5c\x04\x71\x86\x71\x4b\x0c\xfe\x3d\xc3\xa9\xae\x10\x9c\x3e\x75\x3b\x87\x1b\x9b\x08\x20\x43\xea\xca\xed\x9f\x57\xde\x44\x84\x91\xd1\x88\xc8\x0d\x44\x02\x46\x53\x4b\x84\x34\x42\x5c\x95\x71\x28\xab\x8f\x51\x1d\x8b\x20\x71\x88\xd5\x1e\xce\xdd\xbc\xb0\x2c\xbf\x4d\xba\x89\x28\xd0\x88\x13\x2c\x4d\xed\x9c\x87\x72\x5c\x27\xe2\x95\x22\x0a\x43\x8c\x8d\xee\x2c\x27\xd0\x03\x2f\x74\xe7\x20\xba\xc7\x89\xb2\x38\xf6\x22\xe3\xf5\x1b\xb4\x50\xff\x0e\x67\x7f\x54\x1a\x61\xc2\xbb\x1c\x99\x7f\xdc\xaf\x2a\x0a\x70\x73\xac\xf3\xd7\x6e\xd8\xd5\xe7\xd9\xc9\xc7\xe3\x45\x04\xcc\xf1\xd1\x59\x02\x59\xef\xe6\x88\x38\xa1\x98\x32\x7b\xac\x5e\x87\x52\x64\xd7\x6d\x71\x91\x90\x40\x52\x4c\xd1\x15\xfc\x7c\xd5\x8a\x12\x09\xc9\x70\x6e\x2f\xe7\xab\xdd\xcb\x7a\x39\x5f\xb8\xd1\x22\x92\x34\x34\x9c\xd5\x0d\xe0\xe6\x5f\xf3\x52\xee\x2f\xe4\x4f\xff\x3e\xa4\x5e\x24\x2a\x48\x1d\x9b\x79\x95\x97\xcd\x26\x2f\x4d\x3d\x13\xb2\x8d\x4e\xba\x9d\x66\x92\x38\x82\x48\x78\x1f\x59\x10\xd3\x86\xa6\xee\xa9\x33\x79\x90\xb9\x1e\x77\x77\x77\x10\x38\x06\x62\xe6\x37\x4b\xb3\xd5\xfd\x2a\x5d\xf2\x95\x3f\x6d\xaf\x97\x12\x82\x60\xfb\x03\xff\x74\xac\x20\xab\x1e\x11\x2b\x52\x1a\x07\xc6\x60\xea\x56\x47\xbf\x7a\x8b\x94\x65\x58\xad\x73\xb4\xe7\x3c\x2d\xb7\x93\xb7\xc8\x02\x93\xc7\x3b\xd6\xb0\xcb\xa5\x7f\xfe\x2c\x26\x48\x58\x70\xcf\x0f\xb0\x6c\xe1\xf0\x0c\x2e\x02\x27\x78\xec\x33\x89\xb7\xfc\x3c\x20\xd9\x93\x82\x2b\x13\xce\x5f\xf3\xe3\xd1\x5f\x8a\x43\x12\x7a\x83\xc1\xfa\x79\xb7\xbc\x05\xd2\x37\x90\xb8\x53\x94\x55\x7d\xe0\xc5\xba\xaa\x0e\x4f\x3e\x8c\x22\x44\xc8\x35\x1f\x92\x3b\xf2\xd7\xc9\x1b\x88\x4c\x85\x59\x5f\x2c\x65\x13\xe1\x13\x31\x55\xdb\x56\x12\x85\x42\x6b\x50\xaa\x01\x44\x43\xc8\x4c\x22\x59\xd1\xec\xf6\x76\xbd\x43\x1d\x5c\x7f\x04\x00\x35\x27\xdb\x3d\x8c\xa1\x0c\x42\x89\x14\x2b\x73\x6d\x34\x60\x3c\xb8\x41\x1a\x74\xf7\xa6\x05\x70\x3e\xa2\x00\x9d\x70\x5c\x6c\x4f\x87\x9e\xe4\x42\x0a\x1d\x49\x8c\x35\xe0\x44\x58\xad\x1e\xfd\xef\x99\x4c\xc0\x86\x06\x72\x74\x94\x7e\xfb\xca\xb9\x1a\xdd\x5c\x06\x51\x14\x5a\x9b\xd3\x86\x45\x1f\xab\x57\x87\x1d\x91\x41\x16\x78\x96\x68\x4c\x58\x9a\xd8\xaf\x3d\x4a\x22\xc3\x0f\xdc\x40\xbb\x6c\xba\x25\x8a\xe7\x25\xd4\x77\x55\x7d\x07\xb6\x3c\x72\x60\x3a\x48\x92\x28\x44\x31\x5b\xde\x78\xf7\xab\xa4\xd4\xe4\xe7\x0d\x93\xe4\xa2\x54\x53\x97\x56\x46\x81\x81\x89\x1d\xa1\x3e\xe4\xed\x05\x50\x4d\x46\x71\xa8\x43\x57\x61\xae\xe0\x13\xf1\x1e\x13\x53\x54\xc6\xcc\x90\x33\x21\x0e\xea\x01\x78\xdd\xde\x00\xef\x45\x9a\x6d\xe7\x8c\x4e\x49\x6c\xbe\x55\x75\xee\xfb\xbe\x6a\xf7\xc3\x9d\x57\x26\x3a\xe2\x96\x63\xa6\x1b\x1e\x17\x48\x41\x99\x68\xe5\xf2\x4d\x37\xe6\x2e\xbf\x5d\x2c\x37\x92\x86\x8a\x51\x57\x22\x57\xbe\x16\x9e\x41\xe3\x69\xc2\x04\x29\x25\x4d\x39\x4f\x9c\x54\xdb\xe2\xf3\x58\xe4\x32\x6f\x0d\x3b\xd2\x69\x28\x8c\x4b\xfe\xfd\x8f\xc1\xa7\xa6\xf1\x3f\xfa\x80\xa0\xa4\x59\xea\xc0\xde\xcf\xf0\x81\xf5\x90\x97\xe8\x0b\x49\xa5\x32\x85\xc1\xb5\xc8\xad\xfa\x96\x3d\x92\x52\xa2\x98\x2d\x0b\xfc\x09\x39\x0e\x87\x17\xa8\xe7\xbe\x7c\x41\xa6\x8a\x21\x92\xd8\x44\xb0\x6d\x12\xfa\xde\x83\xd6\x65\x16\x66\x92\xf5\x34\x55\xc8\x4a\x32\xf9\x9e\x59\xa2\x11\x09\x3f\x7b\x9c\xb9\x62\x3e\xc9\x13\x23\x9d\xf0\xaf\x3a\x3f\x1e\x8b\x71\x19\xb1\xe4\x34\xc0\x8d\xfa\xb5\xce\x8f\x23\x07\x4e\xf2\x34\x40\x86\x84\xdb\xea\x24\x0a\xd8\x0c\x85\x27\xaf\x6e\x46\x92\x67\x31\x6e\x7a\xeb\x53\xf3\xca\x9b\x89\xe4\x91\x94\x5c\x84\x1a\x51\x79\x1f\xbc\x19\x04\x70\x71\xdb\x70\xeb\x7b\x2f\xc9\x37\xe9\x56\x21\x02\x2e\x86\xfc\x4f\x23\x1d\x73\xd9\x2d\x13\xda\x83\x89\x54\x71\xad\xda\x53\xca\x48\x60\x2d\x8f\xcf\x35\x0c\x85\x8b\x3c\xf9\xbf\x94\x12\x52\xce\x5c\xc1\xfa\x11\xa9\x0b\xdd\x21\x95\x50\x8c\x97\xfd\xf7\x04\x27\x98\x9d\x54\xde\xba\x22\xdd\xeb\x4b\x84\x4a\xa4\xb0\x91\x45\xe4\xaf\xbd\x70\x4c\xa5\xca\x32\xc7\x30\x74\x0b\x4d\x5b\x57\x67\xec\x84\xe6\xee\xf3\x38\x65\xb3\x93\x52\x01\x75\x72\x21\xf7\x55\xa5\x5e\x8c\xf2\xe0\xc8\xaf\x94\x10\x26\x38\xcc\x96\xf3\xd5\x1d\xa2\xae\xec\xef\x3a\x8b\xb0\xa0\xfa\x01\xce\x27\xb8\x0c\x2a\xfa\x67\x56\x01\x31\x6c\x56\xb6\xa6\xcf\xaa\x84\xbb\xdd\xf0\xab\x93\x12\x83\x49\xeb\x56\xe9\x59\x51\x6c\xf7\xe3\x82\x51\xd7\x4a\x87\x81\x65\x10\x7e\xa8\x4e\x0d\x2c\xd4\xd4\xd4\x56\x21\xa3\x8e\xf8\xf7\x47\x29\x0b\xd8\x70\x0d\xcf\xf5\xb4\x91\x20\x8e\x5c\x1a\x29\xf1\x26\x87\x09\x01\x0c\x92\x58\x97\xfe\xd4\xee\xab\x3a\x6f\xfb\xd2\x99\x7e\x65\x55\x84\x2b\xc4\x5d\xf5\x4e\x5e\x4f\x9c\xe9\x9a\x88\x18\x35\xb8\x1b\x4c\x8e\x1a\xd2\xe7\xab\x5f\x5b\x11\x6d\x82\x5b\x58\x04\x75\xe8\x26\xb7\x89\x3c\xf9\xe5\xcd\xd2\xb1\x4a\x15\x31\xe0\x46\xd8\x40\x9c\x0a\xde\x7c\xf7\x39\x22\x65\x2a\x21\x1c\x50\x6a\xbe\xcf\x8b\x2f\x30\x15\x2a\x0e\x32\x57\xf8\xfb\x0c\x79\x5d\x95\xf9\xe7\x4b\x5d\xe9\xfc\x3a\xa0\x4a\xc5\xb1\x32\x50\xe4\x53\x63\x80\x7e\x2b\x3d\xc9\xbd\x9f\x2e\x50\x61\x2a\xce\x32\x92\x0c\x19\x34\xe5\x10\xbd\xab\x92\x90\x45\x91\xad\x52\xcf\x79\x0b\xa3\x6a\x82\x30\xa5\x23\x9f\x5d\x25\x84\x68\x32\x80\x73\xd8\xd4\xcd\xfa\x79\x7b\x33\x79\xd6\x84\x52\x1c\x60\x8b\xbf\xea\x5c\xbe\x0d\xd6\x0f\x95\x50\x96\x32\x6f\x48\x42\x51\x1d\xa1\xbe\x66\x48\xaa\x44\x46\xe8\xaf\x2a\x38\x16\xd5\x79\xc2\x17\xa0\x68\x10\xa3\xb3\xd8\xed\x71\xb3\x52\x19\x22\x5b\x77\x2c\x4c\x23\xbb\xba\x88\xd3\xf9\x38\xd8\xc8\x55\xaa\x18\xb5\xe3\x15\xc3\xd9\x6b\xe3\xb2\x56\xf5\x74\xec\xb3\x20\x4c\xac\x9f\x3e\x90\xa2\xba\x05\xcd\x4f\x45\xbb\x91\x7b\x50\xa7\x2f\xa8\xfb\xa5\x62\x3a\x8e\x4c\x99\x67\xb9\xf8\x3c\x56\x1e\x06\xa9\x98\x4e\x31\xf0\xa4\xf3\xd7\xbd\x2f\xc4\x50\x4c\x73\x84\xee\x8a\x53\x5d\x6e\xeb\x53\x73\x85\x11\xd2\xb6\xcc\x02\x82\xc6\xd5\x9c\x37\xae\xd6\x4f\x65\x29\xa3\xdc\xc5\xe8\x8f\x53\xa5\x68\xa9\x32\xa6\x23\xbb\x08\xad\xa1\x39\x56\x65\x03\xff\x3a\x41\x7d\xde\x9e\x8f\xd3\x89\x98\x29\x03\x43\x6d\x4e\x62\x77\xe0\x6d\x9d\xcb\xaa\xe0\x57\xdd\x14\xc5\xa5\x46\x5a\x70\x84\x07\x6f\x86\x3e\xf8\x75\xeb\x4b\x71\x88\x11\xf2\xfc\xd7\x89\x97\x37\xbc\x1a\x8e\x08\x11\x45\xcc\x7e\xae\x45\x37\xa8\xc0\x40\x65\xee\xaa\x7a\x5e\x1d\x8e\x60\x4b\x86\xc7\x97\x13\x69\x88\x6e\x92\xa3\xb8\xe9\x4b\xa9\xbf\x4b\xca\x7d\x9b\x06\x57\x92\x9a\xdc\xe7\xfc\x69\xeb\xf6\x78\x25\x45\x88\x65\x4a\xb7\x8b\x3f\x16\x8f\xab\x97\xc5\x7a\xd7\x0c\xe3\xb8\x0a\x22\x69\x0a\xc5\x0c\x43\x9e\xc9\xe6\x7a\x11\xf8\x6e\x07\x88\x9c\xea\xeb\xa8\x5e\x65\xb4\x09\x28\x48\x43\xf4\x81\x91\x9a\x01\xd4\xb6\x67\xe2\xf5\xd7\xc9\x12\x80\x11\x07\xe8\x45\xc1\x94\x6d\xa9\x63\x23\x5a\x84\xc4\x78\x1b\xc7\xa7\x30\xe9\x3e\x9d\x1a\x0e\x90\xbb\xb5\x7f\x52\x2d\x25\x85\x41\x89\xdd\xe3\x54\x41\xe7\x22\x77\xe5\x4e\xd4\x02\x7d\x30\x04\x20\xff\xf3\xf4\xca\x95\x8f\x1a\x41\x40\x4d\x09\xc9\x7d\xfe\x3e\x09\xd0\x42\x90\x66\x1a\xbc\xf6\x97\xb1\x2b\xfd\x21\xd0\x56\xb1\x72\xc4\x05\xf4\x65\x00\xd2\x3f\x0c\x04\x9c\x62\x25\x07\x26\xe2\xab\xcf\xc1\x30\x83\x90\xa4\x68\xc3\xaf\x6c\xe1\xbf\xff\x3d\x0e\x31\x93\x3e\x88\x91\x42\x98\xf0\x24\x76\x84\x9f\xb9\x9c\x8d\x99\xe9\x26\x9c\x02\x40\x52\x23\x41\x72\xbb\x98\x2f\x9f\x66\x8f\xbb\xe5\xf3\xad\xe7\x66\x80\x28\x8d\x10\x54\xfc\x7b\x5e\xaa\x99\x1a\x25\x18\x21\xd2\x32\xa0\x8e\xd7\xa9\xf6\xdc\xd1\x12\xe2\x90\x23\xf3\xc0\x3d\xaf\x4f\x8a\xfb\x5f\xe3\x2c\x33\x35\xf8\xff\x39\x35\xc6\x67\xf7\xcf\x34\x0c\xd1\xba\xe6\x3c\x43\xc3\x68\x3d\x7b\x1a\xbd\x70\x22\x22\xa9\x7b\xcf\xf0\x01\x0a\x65\xae\x65\x8f\x53\x62\x72\x20\x26\xac\xf5\x37\x48\x89\x25\x50\x16\xa1\xa1\xd5\x42\xd3\xee\xcc\x3e\xfe\x3b\x9c\x77\xae\xb8\xef\xb9\x7a\xc8\xfd\x58\x86\x94\x32\x65\x95\x1d\x31\x48\x3e\x46\xc3\x40\x4a\x39\xfa\x40\xd5\x11\xca\x55\xa1\xe6\x35\x6f\xfb\xa1\x91\x82\x5f\xda\xd1\x1c\x1c\xc6\x39\x27\x43\x21\x0b\x8d\xaf\xfe\x58\x95\xaf\xf0\x9e\xb7\xa3\xb8\x25\xf0\x24\x40\x5a\x4c\xe9\x38\x14\x8d\x6e\x81\x1f\x01\x5c\x52\x74\x0c\xb6\xbc\x7c\x1b\xc7\x35\x41\xf0\xc4\x78\xa0\xd8\x3f\x3b\x0d\x93\x75\x14\x04\x57\x19\x33\x6a\x32\x28\x23\xe4\x7e\x56\x0c\xd7\xf9\x0f\x5e\x63\xad\xc3\x05\xf6\x60\x7c\x15\x19\x48\x57\xe0\x7c\x0b\x65\x75\xc8\xcb\x21\x93\xaf\x6b\x94\xea\xcc\x0a\xdb\x18\x0c\xe1\xc0\x41\xba\x08\x97\x80\x94\x12\xc3\x2f\xe6\xc9\x97\xf3\xd5\x55\x43\x03\xa4\xe2\x48\x0c\x62\x40\xcc\x3e\x45\x72\x09\x0d\xba\x06\x74\x03\x25\x0d\xf7\x6b\xb7\xe0\x6d\x4e\xc2\xfa\xb1\x57\xe3\x37\x00\x81\x32\x22\x69\xa6\x40\x68\x56\x14\xcb\x7f\x6d\x87\x21\x7e\xd7\x8e\x28\xe4\xb5\xdd\x6c\xb7\xeb\xef\x2a\xe2\xae\x17\x2b\x02\xc8\x34\x18\xb9\x12\x33\xe5\x2f\xad\x13\x8d\xa8\xbb\x3b\x03\x27\x44\x71\xca\x71\x4c\x43\x87\x24\x96\x06\x56\xfd\x4f\x2e\xdf\x5e\xaa\x56\xd7\xd5\x61\xf1\xde\x6d\xa2\x43\x0f\x5f\x87\x3c\x4e\x4c\xf7\xbe\x8e\x92\xa9\xa3\x4f\xa6\x43\x69\x77\x59\x2c\xed\x0a\x36\x50\x14\x3d\x49\xe3\xe8\xb9\x35\x49\x8d\xf2\x51\xcd\x4b\x55\x1d\x0c\x93\xf4\xb4\x4d\x44\x94\xb2\xeb\xe8\xd3\xf9\xbe\x2a\x7c\xe2\x54\x47\x51\xa6\x8d\xf6\x52\xad\xf2\x31\x9e\x5f\x47\x49\x8a\x23\xe1\xb0\x1b\x56\xb0\xeb\x48\x64\xe0\x59\x5a\x27\xba\x95\x6e\xb2\xeb\x48\x12\x1c\xff\xcd\x81\x7b\x3a\x2f\x1d\xa9\x00\xa3\xc0\xaa\xae\x8e\x3d\xa7\x48\x67\x08\xc5\xa9\x8f\xc0\x6d\xda\x5e\xc0\x5f\xea\x38\x33\xb1\xd3\xf6\x03\xf8\xdb\x2d\xcf\x8b\x5e\x85\x6d\xd2\x65\xb1\x64\xac\xaf\x5e\x77\x41\xd8\x49\x47\xd0\x8c\x85\x56\xcc\xf3\x1b\x9c\xce\xd7\xa6\xb2\xa6\x8a\xe2\x5e\x7e\x2a\x45\x85\x63\xc1\xba\x03\xf6\x70\x1a\x18\xd1\x61\xf3\x10\x58\xee\x3a\x7e\xca\x94\x98\xf7\x59\xcd\x46\x5d\x9d\x26\x86\x3f\xc1\x54\xb6\x60\xc0\xea\x5b\x3b\x44\xa7\xd4\x48\x00\x99\xaa\x07\x8c\x1b\xd4\x07\xb4\xda\x6d\x50\x7c\xf2\xe2\xa9\xd4\x98\x49\xcb\x65\xb5\xd8\x3e\x0c\x0d\xf3\x21\x28\x48\xa7\xca\x73\x3e\x3c\xe5\x25\xd4\x57\xc0\x8d\x9a\xc5\x11\x97\x8e\xed\x6f\xf4\x16\x99\x10\xda\x9a\xed\x16\x6f\x76\xc7\xe5\xc5\x7a\xa4\x33\x29\x13\x36\x00\x07\x8f\xa1\x9c\x93\x60\xf4\x70\xb7\xd2\x19\x70\x1c\x40\xeb\x7d\x5e\x3a\xd9\x0c\xa9\xb9\x30\x7c\x56\x9d\xdf\x8e\x99\xf8\xaa\x54\xeb\x53\x01\xd3\x59\x20\x02\x1e\x73\xb7\x01\x55\xa5\x29\x33\x5c\xfc\x17\xa3\x51\xee\x5a\x82\x48\xdc\x3e\x8f\x28\x54\xbf\xad\x26\x73\xce\x8f\x6f\x91\x1a\x6e\x21\x8c\x9f\x3d\x55\x65\xbb\xc7\x7e\x74\xe0\x87\x6f\xa3\x8c\x5a\xa4\x26\xff\xbe\x85\xa6\x9d\x20\x5f\xb5\x8c\x13\xc4\x5a\x70\x74\x71\x37\xf9\x6b\xf9\x63\x52\x18\xad\x65\xcc\x5d\x62\x7c\xcc\xce\xa3\x25\x23\xa0\x6c\xc5\xa7\xdc\x43\xaf\x34\x21\xb5\x92\xc4\x50\x8d\xa1\x82\x6b\x33\x06\x93\x6b\x48\xb2\x38\x1d\x21\x69\x5c\x59\xca\x40\x7c\x49\x6a\x50\x5c\x81\x07\x17\x6c\x3d\x4c\xc0\x1d\xd7\x54\x23\xe9\xba\xe9\xbd\x55\x2f\xc7\x2d\xb5\x66\x04\xc1\x0c\xd2\x4b\x2a\x20\xbf\x27\x78\x25\x59\xa9\x35\x37\x2a\x61\x46\x18\xbd\x9d\x06\x8c\xb4\x56\x0c\x31\x96\x06\x1d\x7d\x2d\x1e\xa4\xb5\xa6\xb6\x5e\xc4\x70\x53\xed\x6b\x80\x87\xaa\x7d\xa8\x4e\xf5\xf0\x49\x55\x10\x86\x1c\xbb\xd9\x20\xc3\x9a\xdd\x3e\x6f\xaa\x09\xd7\xb9\x0a\xc2\xc8\xa8\x3b\x1c\xf2\xaf\xe1\xb1\x57\x10\x43\x2a\x08\x55\x48\xba\x2d\xeb\xcf\x21\x2e\x41\x05\x84\x04\xa6\x0c\x16\xf1\x13\x9b\xd9\xe3\x62\xf7\xb2\x5e\xfe\xe1\x69\xc7\x55\x40\x32\x8d\x8e\x1a\x02\xef\xfe\xfa\xf1\xb2\x5c\x6c\x1c\x43\xbe\xf2\x6d\x78\x82\x30\xec\x9d\x99\xa4\xed\x1d\xc0\x4c\x34\x93\x47\x8f\x54\x84\xc1\xf7\x07\x8c\xbc\x19\xcf\xe7\xef\x00\x48\x54\x10\x69\xce\x52\xe7\x0b\x6a\x98\x0a\x65\xa8\x20\xd6\x09\x6e\x94\x87\x16\xa3\x11\xee\xb1\x92\x20\xc4\x15\xe6\x00\x2a\xef\x63\xa4\x2a\x48\x88\x88\xfc\xf5\x0c\xf0\xf8\x8c\x71\xe9\xc9\x13\x27\x44\x63\xd8\xa6\x45\x8d\xa5\xb6\xd9\x40\x6b\x19\x60\xfd\x95\x24\x89\x95\x65\x46\xfa\x99\xab\x76\xdf\x4d\x9b\x2b\x16\x7e\xd7\x12\x74\xec\xb5\xc8\x5e\xc1\xe0\x6a\x06\x2b\x9d\x0a\x12\xc5\x53\xe8\xa7\xca\xb0\xf2\x42\x05\x34\x14\xd4\xa8\xd1\xf0\x76\x7f\xcb\x5b\xbe\xe3\x91\x3f\x16\x33\xdc\x01\x5c\x55\xf5\x42\x9d\xf0\xf3\x7c\x23\x08\xdd\x9d\x94\x51\x1b\x14\xc1\x26\x37\xe7\xcd\x3e\x3f\x4e\x92\xb6\x2a\xa0\x99\x44\x71\x4c\x6b\x1e\xaf\xb9\x04\x5b\xf3\x74\xfd\x5b\x51\x61\xa4\xb8\x25\x14\x20\x26\xe4\x53\x2a\xa0\x0a\x90\x59\x7b\xcf\xdf\x7b\x03\xad\xb9\x80\xa0\x5d\xc3\xb2\xa8\x20\xa5\x19\x0a\x5f\x39\x66\xcd\x70\x37\x7b\xea\xd5\x1d\x54\x90\x66\x86\xf3\x7b\x97\x37\x4f\x58\x21\xf2\xe2\xd3\x11\xd7\x9f\x35\x85\x48\x99\xa8\xca\xe7\x68\x52\xa4\x9a\x64\xb6\x28\x79\xc1\xdb\x1e\xc2\xa0\x02\x16\x2a\xcc\xc0\xfd\x0f\xea\xaa\xb3\xa0\xcd\xba\xc0\xc7\x7e\xd6\x35\xbb\x58\x05\x8c\x08\x24\xc1\x30\xa1\x87\x63\x0d\xbc\xdb\xab\xb1\x54\xcf\x5f\x3d\x0a\x31\xd9\x7d\xf3\xfc\x3c\x7a\x1e\x26\xb8\xea\x65\xad\xe4\x79\x5b\xa1\x53\x3e\x9a\xdf\x0c\x18\x86\xa6\x5d\x44\x6c\xbe\xe7\x45\x01\xe5\x2b\x86\xc6\x5e\x78\xd3\xce\x4f\x4d\x5b\xa9\x4b\x66\x9f\x2b\x8c\x9b\x13\x4f\x51\x05\x19\x10\x9c\xba\x26\x79\x35\xb7\x8f\xf1\xad\x3d\xa0\x02\x9e\x31\x24\x91\x10\xdd\x2b\x5a\xad\x98\x5b\x03\x86\xfb\x6d\x84\xac\x19\xa4\x5b\x54\x20\x12\x40\x4e\xdb\x6e\x25\xc7\x62\xd8\xf1\x22\x29\x79\x48\xb8\x07\x3e\xde\xf0\xbe\xf3\xa4\x64\xae\x14\xe4\x0f\xa8\x07\x75\x45\x2a\x50\xa0\x31\x90\xbb\xc9\x0f\xc7\x02\x9c\xb5\x36\xea\x62\x48\x24\xae\x83\x98\xd6\x1a\x33\x4e\x5f\x7f\x3b\x90\x02\xc1\x7f\x9b\x6a\xcf\x73\xd1\x3b\xec\x2a\xd0\x61\x84\xb5\x6e\xb7\x35\xff\x30\x08\xd7\xe1\x15\xfe\xdf\x61\xb5\xdd\x15\x93\xd4\x06\xf5\x66\x85\xab\x91\xff\xa2\x29\xe1\x46\x5b\x1b\x77\xfd\x5b\xd0\x50\xaa\xbb\x89\xa7\xa7\x02\xcd\x0c\xa1\xaf\xd9\x34\x67\xea\x1d\xea\xbc\x99\x6c\x6e\x2a\x0c\x88\x4e\x7b\xf6\x59\xb3\x75\x1a\x5c\xb6\x6f\x41\x8d\x6b\x78\x2a\x73\x04\x2c\x5b\xd3\x7b\xb8\xaa\x85\x61\x12\x28\x13\x24\x52\xae\x96\xa4\xdb\xc4\x97\xe5\xe4\x6e\x61\x67\x89\x62\x35\x49\x5d\x9f\xfb\x5a\x57\x15\x86\xda\xa8\x24\xef\xba\xa1\x3d\xfb\xe0\xb5\xea\x53\xf3\x2a\x24\xa1\xc8\x42\x87\x9b\xf8\x9c\xf3\x63\x18\xfc\xe9\x8f\x45\x26\x6f\x6b\x88\x4e\x4c\x8e\xe3\x92\x07\x4d\x85\x44\x8b\x44\x8c\x71\x33\xce\x1f\xf5\x76\xb6\x0a\xe3\x94\xa1\x93\xb1\x43\xb9\xe6\x5b\x10\xed\x54\xbc\x7d\xfc\x2d\xc2\x58\x10\x0c\x64\x58\xc3\x73\x18\x19\x53\x61\x42\x39\x46\x13\x1c\xb8\xf5\x65\xbd\xd8\xde\x2e\xfc\x51\x4e\x31\xec\xe8\x7d\xca\x6f\xd6\x97\xc9\x5d\x93\xce\x11\x1e\x04\xc4\x86\xd4\x16\x2a\x4c\x94\xc1\xe8\xdf\x60\x36\xd9\x33\x6d\xa9\x30\xd1\xc4\x62\x0e\xfe\x03\xb2\xbd\xa6\xe1\xfc\x85\xd0\xb5\x0a\x69\xa0\x8d\x56\x80\x31\xf9\x2d\xd7\xbe\xfa\x46\x38\x47\x85\x34\x14\xd2\x26\x31\x54\x35\x0e\xa1\xab\x90\xd2\xcc\x64\x37\x8d\xc7\x34\x2b\xb1\xb0\xf1\xcb\xf7\x1f\x2c\x1f\x21\xd5\x29\x1a\xcb\xbb\x9d\xdb\x0c\xbb\xf5\xef\x4b\x42\xc1\x91\x8d\x14\x52\xcd\xe3\x70\xb0\x8f\xda\x1a\xc6\xc9\xd3\xa5\xa1\x0e\x60\x20\x82\x65\x15\x43\x2d\x50\x76\xfc\x9a\x29\xd7\xe8\x5b\x0d\xbd\x9b\xce\x40\xfa\x85\xd2\xbb\x0a\x59\xc8\xd1\x36\xbe\xdb\xfe\xf1\x65\xd1\xd0\xb5\xa0\x81\x0a\x19\x31\x45\x94\xab\x1a\xca\xc1\xb2\x14\x32\x16\x83\x0d\xa8\x8f\x56\x25\x77\x38\x33\x75\x4d\x08\x3e\xbb\x2b\xf2\xa3\xe1\x05\x1d\x2e\x92\x21\x93\x46\xda\xf6\x65\xb3\x1c\xff\xae\x8c\x82\xc5\x6c\xbb\x5d\xef\xb6\xeb\xd9\xed\xec\xe6\xd1\x0f\xe5\x2c\x30\xec\x6b\xae\x53\x97\xb7\x9e\xe2\xea\x0b\xd3\x24\xcc\xc2\x54\x24\x63\x78\xcc\x73\x55\x22\xbe\xee\x11\x35\x4f\xfd\xb5\xa5\xa9\xb8\x41\x8e\xed\xce\x24\xb8\xad\xf9\x6b\xe5\x9f\x8b\x07\x0a\xf9\x1c\x37\xfb\xea\xa3\xe7\x84\x55\x21\xd7\x41\xe8\x24\x7a\x2f\xe8\x5f\x54\x28\x08\x41\x97\x01\x13\x1b\x97\xa4\xd0\x2a\x54\x69\x88\xde\xce\xf3\xd0\x29\x1e\x8d\x24\xc5\x33\x74\x5a\x0d\x53\x4a\x37\x04\x9f\xab\x72\x5a\x19\x68\xdb\x42\x68\x92\xe9\xc6\xc0\xfa\x25\x8b\xbc\x0a\x81\x84\x38\xa8\x90\x2a\xf2\xaa\xbe\x8e\x0a\x81\x19\xea\x64\xd7\xeb\x9d\x57\xf6\x55\x77\x03\x8b\x32\xe9\x07\xb4\x59\x45\x27\x6f\x0c\x3c\xc2\xd0\xb6\x9d\x91\xea\x0a\xc9\x60\xd7\x48\xa4\xca\x99\xd5\x48\x06\x7d\xb6\x3b\xb1\x7b\x2a\x1d\x18\xe6\xc4\xed\xbe\xae\x4a\x78\xe2\x6f\x17\x7b\x8e\x8e\x0d\xbc\xe8\x60\x95\xa0\x4c\x8a\x6d\x14\xd8\x52\x24\x08\xcd\xcb\x21\xd0\x6c\xf7\xb2\x5e\xa0\xdf\x82\x83\xc0\x35\x09\x63\x89\xb6\xe2\xd3\xcd\x26\x47\x9a\x6a\x3f\x11\x48\xa8\x29\xd6\x6e\x6c\x0e\xbc\x6e\x11\xa9\xbd\x69\x79\xa9\x78\xad\xfe\x9e\x40\x87\x22\x24\x16\x18\x38\x37\xcc\x3f\xb3\x9b\xe5\xca\x5d\x3b\xa2\x69\xd0\x7f\xf7\x27\x38\x54\xf5\xd9\xe0\x69\x47\xaf\x49\x22\x16\x22\x3f\xb0\xed\xc0\x59\xa9\x46\x72\x42\x8a\x44\x42\x07\xc8\x34\x56\xbe\xd6\xd0\xf0\xfa\xae\x2a\x55\xe5\x3b\x20\x92\x09\x02\x5d\x1b\x36\x2c\x94\xea\x7e\x57\x3c\x32\x99\xb0\x71\x7d\xa7\x3d\x1e\x27\x06\x0d\xdb\x59\x64\x3f\x50\x19\xe7\x9e\x1f\x44\xd1\x99\xca\xbc\x6e\xcf\x77\x55\x7d\x33\x96\x02\x18\xec\x7f\x24\x49\x03\x43\xef\x05\x7a\x20\xbc\x37\xb6\xd1\x49\x92\x19\x87\xa8\x81\xf6\x17\x16\x14\x49\x04\x0f\x95\xc3\x84\xcb\xbd\x91\x1b\xbb\x56\xf9\xa6\x08\xb5\x8c\xf9\xdd\x13\x2f\xcb\x47\xde\xb4\x9b\xfc\xb3\x05\xac\x74\xfd\x9f\xef\xb3\x34\x01\x44\xdf\xf7\x59\xf6\x45\xf7\x70\x83\xf8\xff\xdf\x72\x37\x49\x9a\x12\x2f\x5c\x67\x50\xb8\x8d\xad\xaf\x1f\x0f\x78\x92\x32\x1f\x12\xed\x9c\xda\x27\x3e\x71\x20\x49\xca\x4d\x56\xbd\x3d\xd5\xe5\xaa\xbc\x3b\xd5\x25\x97\x0e\xa4\xfa\x7f\x89\xb1\xb8\x43\x62\xcd\x10\xc2\x80\x05\x8e\x98\xb9\x6c\x4e\xf5\xb0\x3c\x60\xf2\x88\x99\x5d\xd9\x8c\x45\xf8\x05\x85\xdf\x2f\x5e\x33\x4b\x00\xc1\x53\x92\x17\x85\x4d\x10\xcf\x06\x98\x63\x45\x32\x16\xa0\xfb\xbc\x5d\xcc\x9e\x76\x8f\xab\xf9\xef\xbb\xdb\x1f\x6b\xbb\xd2\xcc\xd6\xdb\xd0\xb5\xe3\xa9\x51\x21\x30\x83\xde\x01\x97\x7f\xf1\x10\xa3\x6f\x61\x33\xf5\x8a\x70\x91\xa1\xad\x67\xb1\x66\x77\x70\xe0\x9d\xc1\xde\xc8\x81\xe9\x44\x84\x36\xf9\x24\xab\xf9\x6f\x90\x35\x37\x03\x16\x87\x2f\x5e\x58\x26\x21\x22\xf6\xf0\x62\xf5\xf9\xda\x86\x4d\xa4\x30\x6a\x89\x3c\xaf\xf9\x57\x45\x96\x93\xcb\xaa\x18\x30\x7c\xde\x0d\x4e\xbc\x66\x0e\xf5\xac\x54\x8f\x95\x7c\x7b\xb1\x32\x17\xe1\x55\x24\x85\x22\x2a\x21\x98\xad\xbf\xbb\xfb\xb1\x78\xf4\x65\x5a\xbf\xd6\xc7\xfa\xaa\x2f\x7f\xf5\xe7\xe4\xc1\x55\xc8\x33\x87\xac\xb7\x11\xec\xbb\xaa\x5e\x95\x30\x06\x94\xfc\x62\x1c\x69\x6d\x20\x3f\xf7\x50\xe6\x55\x5f\xf0\xf9\xf5\xfa\x19\x05\xa1\xc6\x15\xf8\x69\x79\xeb\x56\xce\x28\x88\x28\x7e\x9c\xa7\xd9\xfd\xf3\x72\xfb\xc3\x9b\xc2\x51\xc0\x64\xdc\x6b\x8e\xee\x73\xa5\x6c\x4c\x63\x3c\x19\xa3\x20\x33\xfa\xe5\x08\x28\x02\x75\x3d\x26\xaf\xa2\xa0\x73\xef\x7d\x94\x3a\x7f\xa9\xaa\x62\xa1\xf2\x76\x47\xdd\xfd\x42\x42\x99\x95\xec\x59\x96\xf3\xbc\x96\xa7\x62\x00\x3d\x51\x11\x09\x04\x86\xfc\x90\xb1\xec\x74\x58\x74\x43\x69\xbb\xaf\xa1\xd9\x7b\x9e\x77\x15\x11\x6e\x14\x4b\x35\xd2\x27\x21\xed\xd3\xad\x3f\xa6\x64\xec\x03\x01\x8b\x62\x5c\xd1\x60\xdb\x44\x4c\x28\x9b\x7f\x9f\xcf\x1f\x4c\xcd\x17\x19\xd5\x7c\xa9\x28\xca\x34\xc2\x9c\x76\x55\xa1\x2c\x4a\xcf\x1d\x11\x31\x11\xbe\xcb\x8c\x37\x36\xb9\xbe\x4e\xf0\xf9\xcc\x14\x7a\xae\x2c\x33\xab\xb5\x0a\xc7\x2e\x79\x14\xf3\x34\x75\xb4\xa2\xbc\x75\x59\x72\x15\x25\x22\x54\xd6\xbd\x5a\x7c\xb6\x35\xbf\xe5\x67\x7f\x8c\x86\xd4\xa9\x8e\x3e\x55\x0a\x8a\xc9\xfd\x29\x98\xb0\x3c\x57\xca\x94\x10\x5c\x2d\x5f\x52\x51\xca\x33\xbc\xc5\xe3\xdc\xed\xec\x11\x0b\x13\xea\x65\xd6\x51\xf4\x77\x59\xb6\xf0\x0a\xf5\xf6\x7c\x74\x3a\x52\x2e\x70\x11\x65\x19\x88\xd4\xd2\xe6\xcf\x96\xeb\xdb\xf5\xea\x65\xf7\xc7\xea\xf1\xc7\x93\x1f\x5e\x22\xd1\xce\x16\x44\x0f\xf6\xbc\xbc\x9d\x3c\xab\x4c\x41\x26\x2e\xa1\x89\xcb\xe4\x65\x0a\x42\x45\x2a\x30\x4a\xe9\x2a\x6f\xf8\x6b\xed\xc8\x21\x54\xa4\x20\xc5\xb4\xa2\x00\x1b\xdf\xee\x97\x76\xdb\x02\xc2\xd8\xc8\x3f\x58\x6e\xdf\x4b\xb2\x49\xdf\x90\x5b\xa9\xfd\x1b\x18\x11\x10\xab\x08\xe2\x04\xc7\xc2\x2d\x6f\xb7\xd5\x6d\x5b\xcb\x61\xea\xd5\xb6\xd1\x41\x80\x7c\x42\x77\xd6\xe3\x54\xdb\xfc\xab\x28\x5e\xa4\x43\x82\x3c\x8d\xba\xe0\xaf\xb3\x52\xb9\x53\xc6\xef\x1c\x07\x71\x82\x0e\xee\xe2\xcf\xd5\xc6\x4d\xe4\x38\x00\x83\xd1\xc3\xc2\xa3\xdb\xaa\x1c\x4e\x9e\x38\xd0\x11\x16\xc3\xbc\x3c\xcc\x36\x8b\xdd\xea\xc5\x65\xf7\x55\x1c\xa6\x01\x45\xae\xc6\xcf\x63\x6e\x78\xac\x86\xa1\xb1\x38\xe4\x51\x5f\xa7\xe6\x76\xe5\xc5\x67\x0b\xa5\x02\x35\xdf\x9f\xca\xb7\xdb\x91\xdc\xbe\x8a\x49\x42\x50\xd5\xea\x90\x97\x50\x3f\x9f\x0e\xee\xf7\x28\x89\xc9\xd0\xc9\xbb\xb0\x8a\xc7\x6b\x74\x1c\x89\x18\x61\x3e\xba\x06\xf8\x1b\x0c\x54\x2a\x8e\xc3\x0c\x69\xde\x8b\xbc\x69\xb7\xd5\x31\x97\x6e\x52\xc4\x31\xcf\x10\xc1\xf0\xfb\x49\x55\x8d\x15\xe6\x37\xa0\x95\x4a\xbe\x9d\xbe\x7a\x80\x24\xa6\xbc\xcf\x7e\x6f\x1b\xfe\x98\x97\x6f\xa3\xa5\x20\xa6\x51\x86\x3b\x70\x09\x1f\xf3\x3d\x2f\x4b\x28\xbe\xac\xaf\xb8\x96\xd0\x1a\x4c\xf6\x98\xa6\x3a\x88\x07\xf4\x67\xbf\xda\x04\xc7\x27\x4b\xa3\x36\x5f\x5b\x3d\xeb\xd0\xd1\xd0\xd9\xe3\x69\x68\xf4\x32\xca\xea\x0e\xa0\x41\xa8\x8e\x3b\xc2\x45\x4a\x2c\x97\xc7\x34\x59\xac\xe2\x54\x8b\x34\x1c\x02\x00\x2e\x8e\x4b\xac\xbb\x37\xb9\xae\x63\xed\xa2\x43\x31\xcb\x22\xc3\xc9\x8f\x32\xdb\xbc\xc5\x3a\x91\x5e\xfa\xed\x1a\x31\x8b\x8a\x19\x07\xc4\x1e\x0a\x68\xda\x5d\x73\x12\x87\xbc\xe9\x9c\x98\x1d\x97\xf2\x54\x73\x79\x76\x17\xcf\x88\x4e\x62\xc7\x92\x7b\x2e\x2e\x29\xa0\x47\xdf\x28\x8b\x0c\x76\x78\xb3\x7a\x9c\xad\xe7\x0f\xb3\xa5\x8d\xf1\x7e\x55\x97\xd8\x0f\xa8\x8c\x19\xbe\x27\x67\x14\xb9\xf9\xeb\x9f\x83\x85\xe8\x8e\x98\x68\xde\x84\x3b\xc5\xb6\xe1\x51\x0a\x3d\x4f\xe1\xb0\xaa\x22\xfc\x32\xc9\x6c\x4f\x15\x11\xe3\x86\xf1\x44\xd7\x1c\xd3\x24\x5b\xcb\x7e\x3c\x69\xc7\x01\x3f\xe1\xce\x25\x51\xc9\xf5\x45\x3d\x16\x90\x62\x5d\x16\x58\x59\xb6\xcd\xc3\x2c\xf2\x15\x1e\x78\x4d\x13\x19\xf6\x27\x48\x16\x00\xf7\x29\xec\x67\x7e\x80\xe6\xc8\x25\x18\x56\x80\x6b\xfc\x90\x2a\x96\x40\x23\xbb\x37\xb9\x6e\x52\x59\x90\xda\xa2\x9b\x67\x53\xb3\xd1\x74\xde\x9b\x1c\xda\x96\x31\x00\x65\x46\xa6\xa9\x54\x37\x95\x18\x40\xc8\x55\xac\x55\x80\xf5\x04\x79\xf3\x7c\xea\xc3\x51\x6e\xaf\x89\x75\xb7\x6d\x77\x6b\xdb\x90\x11\x40\xc5\x1a\x62\xa4\x35\xc1\xdb\x40\xbd\xf3\xd7\x4b\x82\x44\xe0\x0a\x55\xf3\x52\xbd\x42\xf9\x0c\x1f\x0f\xdc\x25\x4e\x55\x12\x70\x82\x41\x10\xa3\xe3\x3e\x2b\x8a\x1b\x2e\xdf\x5e\xeb\xce\x94\x58\x1e\xf8\xab\xcb\x0f\xab\x24\x00\x6d\x42\xe2\xf9\x01\x0a\x64\x5d\x33\xcb\x94\x2b\xec\xf2\x57\x0c\x03\x8e\x4b\x6c\x75\xaa\x3b\x93\xbe\xff\xd9\x44\xc7\xad\x39\x6d\x14\xe4\x26\x33\x30\x21\x61\x80\xd8\x9a\x66\x5f\x7d\xa0\x26\xc2\xf4\x38\x11\x58\xb6\x73\xc1\xca\x6d\x33\xe0\xdd\x90\xbc\xbd\x8a\xa6\x51\x09\xd1\x99\x32\xe1\x9e\x23\xea\x12\xaf\xbb\xf3\xae\x6f\x4c\x49\x14\x79\x20\xbb\x61\x67\xed\x66\x02\x7a\x67\x55\x3d\x00\xb1\xab\x24\x62\x84\xc6\x0e\x36\x80\xec\x79\xd7\xb0\x2a\x2a\x89\x83\x28\x34\x71\xcf\xf7\xea\x0d\x56\x35\x97\x5f\xe0\x63\x55\x12\x47\x11\xd2\x14\x4e\x69\x5a\x87\x2d\x4c\x6d\x02\x6e\x5d\xa2\xff\xd2\x71\x0c\x0e\xbe\xbb\x69\xb9\x7c\xdb\x5c\xec\xa5\x49\x0c\x32\x1b\xaa\xa1\xcc\x4a\xe5\x68\x9f\x0d\x0d\xf4\x57\xac\x52\xf6\x7c\xca\x64\x6c\xd9\x88\xb7\x15\xd2\xe3\x4e\x6e\x40\x95\x21\xe2\x6f\xbc\x57\xfb\xbd\xbb\x94\xa4\x2c\x65\xfd\xa2\x8b\x49\xcb\x9b\x42\x56\x6f\x93\xeb\xa6\x82\x08\xaf\x36\x69\xbf\x89\xa3\x62\x75\x4d\x14\x80\x5b\x28\x8d\xfa\xf5\xf7\xf2\xb3\x2a\x49\x81\x38\xd7\x64\xf6\x5a\x95\x4b\x65\x82\x28\xe3\x4f\xc7\x82\x08\x89\xcc\xee\xc9\x8f\xbb\x69\x19\x6f\x77\x54\x20\x49\xda\xdd\xea\xc7\xf3\xed\x62\xbd\xe9\x75\xf5\x54\xc2\x62\x42\xe9\x38\xeb\x7d\xbf\x78\x5e\xac\x67\x8f\xbb\xc8\xb7\xa1\x81\x8a\x2d\xcf\x63\x3d\xe2\x7f\x53\x09\xb3\xc0\x1e\x97\x65\xc1\x1b\x5f\x1f\x5f\x59\x16\x22\x1f\xd4\x11\xea\xa6\xb3\xed\xbc\x24\xde\xa4\x1b\x33\x19\x39\x6d\xf5\x1f\x77\xdb\xc9\x45\x44\xa0\xd1\xe6\xf5\x81\x69\xcc\xe5\xe5\xfc\x22\x27\xe0\xda\x67\x31\xb2\x0a\x55\x65\x81\x62\x7d\x08\x2b\xd9\xe4\xaf\x25\x6f\x4f\xb5\x1d\x49\xb6\xa9\x0c\x29\x9a\x43\x8f\xd5\xeb\xb2\x6c\xba\x37\xbd\xfe\x45\x24\x37\x5e\xee\xbf\xf2\xaa\x7c\xbd\xf9\xb5\x93\x97\x28\x62\xbc\x4b\x1c\xf3\x27\x81\x30\xd5\xeb\x4f\xab\x52\x8a\xc0\x87\xce\x48\xff\xb9\xdc\x3e\xdc\xae\x67\x3f\x77\x2f\xf3\xed\xee\x76\xb6\x7c\xfc\xcb\x7d\x0f\xc5\x03\x14\xf2\x32\x52\xd3\xbc\x9f\x5c\x10\x46\xc8\x3a\xb5\xeb\x0b\x5d\x27\x49\xec\x04\xa2\x04\x01\x04\x25\x80\x6a\x30\xc2\x3d\xfe\x9e\x90\x44\x18\xe9\x30\x11\x8c\x25\x9e\x3a\x29\x3c\x73\x2d\x53\x93\x66\x55\x0e\x80\x3f\xcc\x75\x25\x3a\x32\xc4\x61\x0d\xb4\x6d\x01\x37\x93\xda\x00\x95\x68\x4a\x11\x06\x5a\xa1\x30\xbe\x03\x81\x8f\x10\xc6\x8a\x06\x2c\xb6\xe5\x2b\xa5\xba\x79\x59\x6c\x56\x5f\xd7\x6d\x28\x1a\x08\xed\x80\xa5\x2f\x35\x74\xce\x28\x6a\x28\xd5\x95\xb3\x77\x69\x00\x14\x31\xb9\x6d\x7d\x6a\x26\x81\x54\x1a\x66\xb6\x00\xae\xad\x6a\x50\xc3\xf5\x93\x92\x18\xb0\xec\x6d\x93\x2b\xf8\x67\x35\x4c\x70\x52\xc2\x8d\xe4\xcf\x37\x3c\x54\xd7\xa7\x35\x8d\x34\x8f\x1c\xa7\x5d\xfe\x09\x85\x81\x06\x5a\x3b\xe4\x1f\xc3\x50\x26\x8d\x03\x8a\x18\x0d\xc4\x5e\x40\xbb\x74\xbb\x18\x8d\xa3\x08\x13\x55\xb9\xac\x6e\x81\xab\x9e\x0d\x50\xd1\x98\x66\xb1\x37\x2c\x14\x14\x2d\xf7\x47\x78\x8c\xb6\x09\x32\xde\x20\xda\x68\xf6\xda\xdb\xa5\x34\xe6\x02\xd9\x15\x5a\xfe\x06\x66\x78\x8c\xbe\x1b\x4d\x02\x81\xb0\x05\xa4\x2f\xdc\xa5\xbb\xe3\xc8\xac\xa5\x94\x50\xbc\x6f\x73\x04\x99\xeb\xf3\xdc\xe3\x89\x26\x97\x49\x43\x53\x9b\xb7\xe7\x0d\x42\x13\xd0\xac\xbc\xe8\xba\xf1\x68\x48\x13\xe3\xa9\xbf\xbe\x1f\xa1\xbb\xef\x0e\x7c\x18\x98\x66\x01\xc3\x52\xdb\x43\xee\xc8\x71\x6f\x86\x3a\x5b\x13\x52\x49\x45\x33\x2d\xb9\x65\x36\xd8\x9c\x8e\xc7\xaa\x76\x18\x91\xc9\x73\x72\x8b\x9b\x69\x90\xf4\x68\x77\x34\x26\xc1\x8e\x8f\x07\x0f\x27\x86\x0d\x9e\x37\x0d\xb4\xcb\x5b\xff\x73\x6c\x44\x8b\x4a\xf8\x6c\x2f\xf4\xf8\x14\xe5\x94\x63\x80\x58\x81\x44\xc2\x77\x83\xc6\x73\x07\x53\xea\x18\x22\xe6\xd5\xe9\x58\x95\xd7\x9e\x4e\xc8\x04\x9d\x8c\x5c\x41\xd9\xe6\x3a\x87\x7a\x5b\xcd\xab\xaa\x56\x68\xe0\x8f\x67\x3e\x95\x01\x60\xc1\x47\xd7\x45\x23\x2d\x8c\xc9\xc8\x94\x24\x48\xbd\x78\x97\xe9\xcb\xbb\xaa\xc6\xe2\xe6\x53\xb7\x50\x2c\xe7\x2b\xb7\x33\x50\xc9\x41\x60\x90\xb2\xaa\x8a\x39\x3f\xfe\xd8\xf8\x77\x57\xd4\x52\xce\x18\xda\x98\x6d\xb5\x01\x07\x35\x55\x54\xa5\xc6\x84\x92\x55\x59\x82\x6c\x9f\x2a\x2c\xc5\x71\x07\xa5\x40\xd6\x19\x63\xed\xb9\x8a\x97\xc9\xcb\x00\x49\x11\x8b\x23\x0b\xe0\xb5\xaf\x7c\x5c\x1d\xa1\xec\x7a\xd8\xf7\x22\xb0\x28\xb4\x7c\x68\x4e\xef\xc8\x30\xa9\x8f\xfb\x11\xb8\x4a\x93\x3e\xe3\x7b\x2d\x2e\xfb\x55\x05\xbb\xa2\x20\x04\x82\x0d\xdb\x3d\xff\xd8\x54\x87\xa9\x67\x3c\x7e\x6e\x1d\x31\xe4\xf2\x32\x40\x3f\x43\x29\xee\xcd\x52\xaa\x39\x45\x03\xe2\xee\xf9\xf7\xd5\x66\x68\x3a\x53\x2d\x28\x96\x94\xce\x7f\x6c\xb6\xab\xa7\xdd\x62\x3d\x27\xc1\xee\x69\xf9\xbc\xdd\x6d\x16\xeb\x3f\x96\xf3\xc5\xee\x79\xe6\x23\x39\x69\x10\x6a\x34\xbe\x16\x7e\x82\xa4\x41\x1c\xe2\x10\xfd\x50\x36\x69\xe1\x7e\x4f\x40\x88\x81\xb1\x75\xfd\xb9\xd3\x40\xa7\x28\xde\x97\x37\x4e\x14\x70\xdc\x85\x69\x98\x2a\x9c\x50\xb3\x42\xf0\xda\x6f\x03\x69\x28\x00\x29\x0f\x5c\x1d\xc1\x17\xea\xf3\xb6\x35\x21\x21\x9a\xbf\x0a\x2b\x60\xb1\xbc\x6b\x03\xaf\x9d\xc1\xbc\x29\x78\xb3\x1f\xc1\x06\x52\xa2\x78\x6c\xb5\xba\x7c\xe8\xf0\xfa\xc3\x47\x41\x8c\x29\x48\x2b\x8f\x69\x17\xea\x6e\x50\x8e\xa2\xa7\xd3\xb3\xa8\xe6\xa6\x2a\xc6\x29\xb5\x12\x77\x6b\x1a\x71\x57\x69\xf3\x08\x5c\x41\x2d\x2a\x4f\x4a\xac\xd2\x34\xd4\xa9\x31\x39\x60\x77\xa8\x4a\x47\x43\xa1\xd2\x34\x92\x18\xca\xb4\xbc\x3d\xbb\x1e\x73\x90\xa6\x92\x2b\x3a\xea\x5f\xd4\x63\xfe\x85\xda\xa2\x3b\x19\xc2\x38\xee\x99\x13\x0b\x2e\xdf\x8a\xbc\x41\x49\xcb\xc9\x57\x62\xd4\x80\x71\x45\x5e\x14\x13\x78\xb4\x4a\x19\x33\xcc\x44\x3b\x75\x05\x6a\x71\x51\x32\xa2\x52\xc6\x63\xcc\xbc\x60\xd0\xb1\xe6\x6d\xfe\x0e\x26\x47\xf9\x2d\x68\x68\xf2\xec\x0c\x62\x0c\xc5\x79\x66\xca\x6d\x5e\x14\x7f\xbe\xcc\x10\xc5\xef\x47\x6f\x46\x8c\xc3\x8a\xf6\xa9\x4b\xbd\xf8\x83\x94\x98\x0c\x33\x46\x7e\x31\xc2\xec\xf9\x42\x54\xca\x03\x8d\x8b\xf0\xe2\x70\x6c\xf3\xee\x9b\x5f\x29\x55\x54\x29\x27\xd4\x51\x7a\x5a\xc1\x8f\xab\x36\x6c\xca\xa3\x14\x97\xb5\xd5\xdc\x06\xad\xbe\xb7\xde\x53\x2e\x42\x34\xb7\x66\x08\x1c\x6a\xee\x9f\x56\xab\xe7\xc9\x25\x45\x94\xda\x12\xa2\x56\x0f\x20\xe9\xdf\xa7\x1a\x52\x21\x8d\x3a\xe8\x7a\xd1\x2d\x00\x8b\x5b\x27\x85\x7a\xb7\x5a\xef\xbc\x9d\x3f\x7b\xbe\x35\xff\x18\xf5\x97\x50\x11\xc2\x10\x6e\x66\xcf\x73\x6c\xbd\x7e\xfa\xf1\x38\x73\x47\xa5\x08\x50\x17\xad\x33\x73\x9e\x78\xfd\x76\x9d\x61\x47\xa5\x2a\x60\x91\x11\x7a\x2a\x55\x61\xc4\x1a\xdc\x25\x14\x0f\x8c\x90\xce\xa4\xe6\x53\xa5\x9a\x87\x48\xde\x32\xff\xd7\xfc\xd7\x76\x73\xaa\x55\x28\x6c\x7c\x7b\x79\xd4\x13\x2f\x2e\xd5\x8a\x61\x86\x17\xb5\xee\xd6\x18\xf0\xb1\xb7\x61\x01\x31\x75\x80\x56\x21\xac\xcc\xdb\xd5\xa1\xcc\x1d\x90\x69\xf4\x1e\x2c\x48\x8c\x41\xe3\x9c\x91\x27\x5e\x8e\x99\x3a\x15\x0b\x23\x40\x50\x07\x16\xe4\xed\xde\x73\xf8\x58\x95\x77\x05\x0a\xbd\xb9\x16\x69\x9a\x09\xcb\xcd\xe6\x69\x50\x15\x8b\xa8\x44\xc0\xd7\xe9\xa8\xcc\x26\x6e\xb8\xc4\xa6\x14\xf4\x8a\x45\x69\x00\x86\x13\xed\xb5\xe6\x0a\xb6\xa7\x46\xe1\x16\xbd\x3c\x1c\x8b\x49\x7d\xb4\x62\x31\xe1\xb8\x4a\x3e\xc3\xc7\xcd\xea\xe5\x57\x58\xa8\x6b\x10\x68\x16\x47\x12\x31\xee\x5e\x83\xad\x05\xb5\x2c\xaf\x29\x7d\x29\x16\x2b\x81\x81\xea\x1b\xc8\xff\x83\xf4\x3e\xde\xfc\x65\x49\xc4\x85\x59\xb5\x36\x27\x81\x85\x52\xe3\x53\x69\x64\xe4\x7c\xb9\x21\xe0\x37\xa4\x11\x63\x1d\xbd\x7e\x5d\x71\xe7\x70\x23\xc9\x75\xfb\xe3\xe9\x65\x33\x9b\xff\xee\xee\x95\x26\x0c\x89\x1c\x41\xe5\xed\xfc\xd4\xfb\xf4\xff\x67\x59\xdb\x15\x4b\x53\x8d\x71\x83\x9b\x4a\xf8\x93\x04\x4d\x6c\xdd\x7a\xe7\x62\x40\xdd\x9e\xbb\x7d\xb7\xcf\x5a\x84\x93\x79\xc5\x18\x63\xa6\x34\x46\xee\xab\xaa\x40\xa4\x9f\x2f\x78\x51\x2c\x23\x1a\x71\xc9\x0a\x4c\x05\xc0\x20\xfa\x33\x19\x56\x59\xc4\x11\x5d\x36\x00\x29\x33\x7f\x95\xd8\x90\x96\x63\xf9\xcd\x90\x13\xc1\x35\xe0\x11\x45\x52\x75\x05\x0a\x3e\x7f\xe5\x50\x5c\x5f\x20\x18\x4f\x34\x3a\xe6\xf3\xd9\xcb\xce\x97\xb3\x2a\xc6\xd3\x58\xda\xa8\xd1\xba\xaa\x0e\x93\x91\xce\x33\x53\x8c\xd6\x2d\x83\xfc\x1d\xd4\xa2\xdd\x7f\xa7\x43\xa6\x18\x17\x21\x71\x85\x03\x3c\x2f\x1b\x97\xe6\x1d\x3b\x72\x4c\x24\x04\x3d\x56\x03\xaf\xf6\x42\x44\x8a\xc9\x28\x43\x03\x6d\x96\xcb\xa1\xbd\xc3\x54\x68\xc0\x2f\x0a\x4c\xbc\x7a\xcc\xcd\xe5\x1b\x19\x2c\xc4\x18\xb4\xf2\xcb\x28\x32\xd3\x41\x88\x72\x07\xf3\xc5\xaa\x8f\x04\xb8\x63\x31\x31\x82\x8e\xbc\xb3\x86\xca\x4a\xf5\x47\x98\x29\xba\xdc\xb9\xca\xc5\x2b\x35\x0e\x2a\x0b\x42\x1a\x5b\x95\xe3\x01\xff\x8c\xca\x42\x2e\x91\xf6\xe3\x68\x3d\xdd\x2d\x7c\x4e\x4f\x25\x21\x03\x87\xa5\xba\xce\xc7\xad\x32\x92\x2a\x9c\x8c\x13\x5a\x8e\x27\xfe\xb9\x69\xe1\x38\xe9\xa0\x2c\x8e\x09\x0e\xff\xdd\x81\x7f\x9a\xbd\x1e\x1d\xbe\xa1\xa3\x9e\xc5\x4a\x42\xd8\x43\x16\x4a\x75\x53\x55\x6f\x73\x5e\xbe\xf3\xc9\xde\x97\x25\x24\x34\xe9\x5e\xfe\x79\x73\x3a\x8f\xde\x8e\x46\xb1\x48\x07\x95\x1d\xd7\xd4\x49\xbb\x56\x86\x6c\x55\x9c\xce\xc7\x68\x12\x98\xc8\x28\x27\x9c\x5b\xb3\xff\x75\x10\xa3\x74\x87\x45\x82\x4e\xf0\x4e\x56\x87\xe3\xa9\x85\x65\xd9\x4d\x98\xfc\x7d\x42\xb2\x3f\xfe\xd2\x59\x1a\x1b\x08\xb5\xd9\x7e\xd7\xc0\x8b\x03\x32\xc4\x4e\xee\x9d\x26\x11\x8a\xb7\x6e\xa1\x69\xd7\xa7\x66\x3f\x58\xe3\xb2\x34\x75\x7c\x03\x97\xd2\xf1\xa3\x45\x35\x4b\xa5\xb1\xd1\x31\xfc\x87\x23\x04\x29\x7e\x3b\xc7\xd1\x5d\x8c\x85\x31\x76\xf6\xcd\x70\xb0\x67\x2c\x49\x43\xee\x6a\x95\x9d\xcf\xe5\x0f\xd2\x00\x8d\xc6\x03\x7f\xb3\xf9\x8e\xf6\x7c\xe1\xa1\x4c\x1c\xe6\x6f\x79\x94\x54\xc6\x64\x82\x1e\xd6\xec\x78\x74\xb0\xc6\xab\x9b\xc5\x00\xf2\x94\x31\xb0\xd8\xc5\xce\x2b\xf4\x04\x2d\xdd\xef\x10\xc3\x28\x0a\x6d\x58\x7e\xec\xe1\x2c\x94\xc8\x2e\x52\x1d\xa1\xbc\xaf\xab\xd3\xd1\xc6\x39\xdc\x61\xce\xad\xc2\x50\xd1\x99\xf0\xa0\x76\x26\xe6\xe0\x0e\x6b\x8a\x91\x36\xa4\x5d\x31\x28\x4c\x77\x88\xf3\xc0\xc1\x7e\x9e\xf9\xc1\xaa\x6d\xfe\x0e\x57\x29\xe7\x54\xc6\x35\x33\x1a\x79\x18\xd8\x1f\xd1\x54\x4e\xfa\x46\x04\x14\x58\xbf\x63\x74\x53\xd5\x45\x53\xc7\x0d\xa5\xa5\x53\x9c\xdd\xfe\xb1\xeb\x61\x41\xbd\x3e\xa5\xca\x24\x33\x71\xa3\xbe\x6c\xcb\xf0\xe9\x5e\xc9\x99\x67\x52\x44\x06\x30\x58\xbd\xb7\xe3\x3c\x4c\x26\x95\xc0\xda\xd5\x9f\xb3\xc7\xc7\xc5\xd6\xff\x0a\x42\x10\xaf\x29\x26\xfd\x4a\x64\x11\x54\x99\x8a\x32\xbb\x35\x2f\xdb\xce\x2d\x76\xe7\xa9\x38\x43\x79\xaf\x43\x5e\x3e\xbd\x4d\x75\x84\xc6\xcf\xa4\xa4\xc2\xe5\xb5\x7d\xad\x9f\xe1\x13\x75\x0f\x3c\x78\xd7\x07\x2a\x32\x1d\x03\x16\x39\x77\x96\x04\x52\xac\xcb\xb7\xf9\x05\x21\xbe\xca\x34\x28\x66\x51\x10\xb6\x04\x77\x00\x5d\xe7\x41\x22\xa5\x61\xe7\x42\x3f\xae\xe7\xcb\x1c\x3d\x11\x0f\x12\x8d\xe9\xb2\x9d\x95\x79\x5c\x63\x55\xed\xa4\x51\x18\x19\x0c\xe7\xce\x06\x26\xaf\xbf\x1d\x0f\x59\xe4\xd2\x62\xcb\xb2\x69\xf3\x16\xdd\x9d\x9b\xf3\xf3\x44\x4b\x56\xf1\x50\x99\xd5\xa1\x39\x1d\xfa\x81\xcf\x49\x4c\xd1\x3d\xb4\x38\x50\x9b\x2c\xba\x84\xa0\xb9\xe6\x2c\x36\x6b\x9f\x93\x28\x18\x27\xba\x6d\xab\x88\x1a\x3a\x01\x69\xed\xe6\x1d\x8a\xf5\xbb\x5b\x46\x52\xe1\x3a\x81\x82\x4e\x39\xa8\xce\xe2\x6a\x56\x65\x71\x7e\xea\xb7\x29\x1e\xc7\x0a\x6b\xff\x37\xc7\xaa\x6e\xff\xf4\xbf\x66\x02\xa1\x3c\xdd\x86\x36\x2c\xa6\xe2\x31\x28\x27\xca\x8a\xe3\x72\x73\x04\x50\x63\x73\x84\xc7\x5a\xe1\x36\xb2\xdd\xc3\x0d\xf8\x7d\xd6\x1f\x04\x04\xf6\x99\x20\xd7\x47\xef\x07\xf3\x24\x48\xd1\x0f\xbe\xab\x41\xa9\xfc\x0a\xff\xa6\xe2\x34\x34\xca\x78\xb6\x24\x51\x4f\x0f\xd3\xc8\xf0\xe5\x74\x26\xfe\xf8\xa3\xa4\x81\x0d\x7d\x35\x68\x53\xac\xf4\x3f\x2b\x31\x4e\xb2\xba\x86\x04\x52\x93\x31\xc5\x88\xe7\xcd\xd9\x6a\xa6\xd5\x5f\x15\xc3\xbb\xf3\x58\x86\xf8\xd5\xcd\x07\x3f\x4e\x30\x8f\x93\x91\x94\x66\x1c\x93\xd2\x22\xff\x1a\x27\x36\x7e\x2f\x16\x83\x0c\x6c\xad\x9c\xa1\xb8\xbc\x83\x2f\xf0\x8d\x3c\xe3\x19\x35\xca\xe7\x37\xeb\xbb\x9f\x8b\xe5\x64\xb4\x73\x12\xa2\x25\xcf\x8f\xc7\xe2\xfc\xc2\xcf\x62\xa0\xbb\xfb\x8f\x69\x53\x65\xc2\x04\x3c\x6f\x7c\xf9\x91\x3b\x96\x99\xfa\x3e\x64\x6b\xdb\xf3\x53\x83\xd2\xda\xf9\x61\x3a\x03\xb9\xa6\x98\x60\x5f\x2f\xee\x16\xeb\xf5\xec\x71\xf7\xb2\x5e\xdd\xaf\x67\x4f\x1b\x77\x21\x21\xa5\x13\xae\x3f\x34\xaf\x93\xef\x29\x54\x80\xef\x02\xd3\x80\xef\x08\x41\x71\xd1\x05\x92\x09\x4c\x7a\xbf\xac\x17\x4f\xcb\x1f\x4f\xbb\xf9\x6c\xbb\xb8\x5f\xad\x5d\x3e\x84\x4b\x65\xe8\x77\xba\x15\xf8\x65\xb1\x5e\xae\x5c\x14\x92\x2b\xc2\x5d\x49\xcc\xcf\xbc\x2c\xf3\xf2\x75\x14\x43\xe2\x10\x18\x46\x4e\x2c\x3a\x16\xbc\xc9\xe5\xae\xe1\x65\xb7\xc3\xfa\x06\x04\xbb\xd7\x68\xa8\x6d\x5d\x3d\x25\xd7\x01\xc3\xb4\xd9\xc3\xa9\x7c\xed\x8e\xf8\xdf\x25\x15\xa9\x95\x9f\xaf\x4f\xb2\x5d\x95\x63\xd6\x14\x25\x42\x12\x32\x0b\x0d\x9f\xbd\x78\x1a\x22\x77\x30\x36\xd4\xc1\x2f\xfc\x54\xe0\x04\x1e\x66\xdd\x45\x98\x1a\x78\xfc\xef\x75\x7e\x6c\xab\x67\x18\x54\xf3\x7d\xe9\x44\x8b\x30\x03\xc3\x6a\x79\x04\x99\xf3\xe2\xfe\xec\xd2\x21\x22\x0a\x25\x31\xb3\xeb\x2b\x5a\xdf\xa9\x0e\x8b\x12\x11\x4f\x59\xaf\xbd\xfd\x00\x75\x75\xad\x3e\xe6\x4b\xaf\x44\xc4\x82\x27\xa1\xd5\xe9\xcd\x6b\x78\xae\xda\xc5\xe1\xd8\x5e\xdf\xb5\x45\x2c\x04\x16\x01\xaa\xaa\xac\xda\xbf\xfe\xfa\xeb\x96\x1f\x8f\xc3\xb5\x47\x24\x92\xa1\xf9\x70\xe0\x9f\x13\xcc\x93\x48\x54\x84\x1f\xe2\x50\x29\xcc\x43\x1c\xdc\x90\xbb\xfe\x5c\x94\x12\x6a\x72\xdf\xb6\x86\xc5\x6b\x47\x8e\x62\x64\x22\x8d\x28\xd2\xee\xfc\xac\xf3\xf6\x02\x1a\x20\xd2\x24\xcd\xec\xe0\xdf\xf1\xc3\x35\xf6\x7f\xd7\x90\x82\x56\x03\xfa\xf0\x3b\x24\x1f\xba\x50\xc1\x9b\x9c\xa4\x53\x0c\x82\xd9\xcd\x6f\xc1\xeb\xe2\xbc\xc1\xf4\xda\xa1\x5f\xac\x45\x16\x64\xa8\x52\x65\xf8\x1a\x66\x05\xf2\x8e\x36\x63\x4c\xbd\xc8\x40\xe2\x52\xb0\xfc\xb9\x1d\xc4\x4d\x44\x06\x80\x71\x93\xa7\xfc\x73\x54\x31\x23\xb8\xdf\xec\xea\xa7\xbc\x6c\x67\x48\x5f\x33\xbc\xab\x48\x85\x2b\xb5\x5a\x7c\x82\xec\x0c\x04\x57\xf8\xe0\x9a\x28\x4a\x0d\x49\xd4\xe9\xb8\xe9\xf1\xa1\x02\x02\xa3\x30\xbc\xe7\xcd\x7e\xdb\x0b\xe2\xbb\xa3\x24\x74\x9c\xac\x37\x5d\x7f\xfa\xab\x01\x01\x21\xed\x12\x8a\x02\x21\xf9\xbb\xa5\x8a\x1b\x7f\x12\x88\x42\x70\xfa\x2f\x9b\x93\x98\xf4\x03\xc4\x02\x49\x99\x9e\x2a\x97\x60\xf9\x26\x6a\xf2\xff\xe3\xec\xcf\x9a\x1b\xc7\xb1\xf4\x71\xf8\xbb\xfc\xae\xea\x62\x2e\x40\x70\x01\xf9\xde\xc9\x92\x9c\xa9\x2e\xdb\x52\x4b\x72\x66\xd5\x4c\x4c\x28\xb0\x1c\x48\x1c\x53\xa4\x9a\xa4\xec\x54\x7f\xfa\x37\x78\x00\x70\x13\xed\xaa\xfe\x4f\xc4\x74\x76\x9b\x20\xc5\x05\x38\x38\xcb\x73\x9e\x47\xe8\xd8\x28\xe8\xb5\xc1\x97\xb9\xa3\xc1\x0f\x4a\x12\xf8\x98\xf3\x68\x06\x1c\xf2\xbe\xb7\x2b\x09\x4f\x0c\xd1\xdf\xb5\x3a\x7d\x8e\x55\xb7\x83\x3d\xaa\xd1\x14\x2c\xdf\x3b\xc1\xe6\x4f\x22\x7f\x77\x06\x27\xcc\x96\x5c\x9f\xf9\xaf\xc6\xe9\x9b\xd5\x35\x1f\xcb\x5f\x2a\xe9\x69\x1f\x21\x62\xb6\x23\xc5\xb5\x76\xd9\xa3\xd4\x0b\x30\x91\x2f\xd2\x7a\x5e\xde\xaa\x9a\x3b\x88\x94\x3d\xee\x07\x01\x36\x4b\x37\x9b\xc3\xf4\x7e\x17\xbb\x91\x4c\x41\xbf\x3b\xec\x3d\x85\x0f\xc3\xfc\x30\xbc\x1f\x1f\x12\x4c\xaa\x70\x65\xb8\x6b\x3f\xc3\xeb\x8d\xcf\x52\x18\x8e\x03\x4e\x37\x30\xb3\xae\xef\x33\x8e\xc6\x07\x61\x88\xbc\x52\xa6\x65\xdb\x10\x3b\xc0\x9d\x52\xe1\xf8\x24\xcd\x71\xe7\x71\x5f\x3c\x47\xad\x3a\x7b\x30\xf4\xb4\x67\xee\xfb\x1d\xf9\x09\x1e\x0a\x5e\xaa\x3b\x2d\x40\x25\xc3\xd0\x24\x8d\xb6\xb3\x97\x6f\xcb\xe5\xcb\xe2\xc0\xda\x23\x91\x9f\x18\x19\xa3\x12\xa0\x3c\x5c\x78\x5b\x2b\x90\x21\x53\xdc\xb1\x10\x3a\x8e\xd9\xb5\x5e\xf0\x1b\xb2\x1c\x8d\xde\x60\x18\x87\xc2\xd0\xdb\x6c\x57\xf3\xef\xa3\x83\x8c\x47\xd4\x6a\x25\x19\xfd\x17\xf7\x77\xe5\x45\x56\x25\xa0\xcb\x82\x7c\xe9\xb7\xc8\x38\x06\xcf\x56\x4d\x67\xf9\x11\xb2\x95\x7a\xe6\x97\x4b\x4f\x4e\x62\xd0\xc2\x20\x63\x25\x94\x6d\xab\x40\xe8\x38\x3c\x73\xd3\x5d\x5e\xad\xaa\xea\xda\x96\xbd\x64\x42\x03\x1a\xd9\x10\x77\x07\x99\xc9\xba\xfd\xc5\x97\x49\x82\x00\x0b\xb3\xee\xcb\xe0\xda\x5f\xc0\xfb\x92\x77\x34\xd1\x4a\x26\x5c\x38\x62\xba\x03\xf2\xc5\x7f\xa2\x76\xf6\xf7\x76\x2f\xc9\xfd\x10\x63\xbe\x1c\x3e\xe6\xfc\x7c\xe1\xe9\xf1\x4e\xfd\x7d\x74\x86\x20\x12\xd1\xdd\xf5\xed\x02\x63\xf7\x56\x8a\x88\x21\x38\x7d\xf9\xc0\xf3\xb7\x6e\xbe\x08\x4e\x30\x03\x7a\x2c\xf6\x45\x13\x78\xed\x6a\x70\x19\x65\xa9\xbc\x48\x99\xc6\x0d\xcc\x82\x3c\xa4\x63\x54\xbf\x54\x11\x88\x3e\x99\xfb\x06\x0c\x2b\x12\x6e\x47\x2e\xab\x20\xc1\x0b\xd0\x5e\x3f\x99\x4c\xc4\x5f\xb7\xda\x49\xe0\x46\x17\xba\x72\xac\xec\xc3\x87\x51\xc4\xf3\xbc\xc8\xb9\x5a\xd5\xa9\x0f\xa2\x6f\x2f\xa2\x88\xf4\x9d\x8c\xf9\xf2\xe5\xdb\x02\xde\x27\x37\x7e\x45\x64\x88\x2b\xab\x2d\x6e\xec\xf6\xb3\xc7\xc7\xc3\xb7\xed\xfa\xd5\x01\x97\x14\x51\xc4\xa2\xc4\x6a\x9e\xa5\x5d\xca\x41\x79\x3e\xc7\x56\xa4\xd5\x7c\xed\x18\xc1\xfe\xd6\xd7\x45\x26\xd4\x66\xba\xfe\x09\x7f\xa6\xf9\x71\x9d\x66\xed\x15\x35\x43\x53\xbc\xc5\x77\xf5\xcc\xd3\xcf\xf2\x25\xc6\xfd\x1a\x3e\x0b\xa5\xd2\xed\x8c\xcf\xe9\xaf\x8d\x4b\xb8\xe7\xf5\x97\x34\x34\x4a\x51\xdf\x74\x62\xcb\x22\x37\xae\xe4\xbd\x42\xe7\xf8\x97\x62\x1a\x18\x4d\x92\x4b\x09\xc8\x7a\x81\x7c\xf0\xee\x29\xa8\xd0\x92\xb7\xb4\x9d\x63\xce\x33\xa5\xfc\xd0\x70\xe0\xd5\xc5\xe5\xcb\x9c\xaf\xf2\x79\x8c\x3c\xc5\x2f\x70\xa9\xaf\xce\x45\x50\x01\xf1\xd0\x83\xba\x18\x22\xf4\x67\xd3\x13\xd2\x05\xcc\x2a\x20\x89\xeb\xe9\xfa\x67\xe3\xbf\xa4\x45\x8e\xc8\xd3\x59\x96\x99\x88\xb4\xbf\xd7\xaa\xc0\x57\xc6\xd4\x34\x5b\xd8\xc9\xaa\x84\x5d\xb0\x69\xb8\xe8\x13\x77\xba\xe1\x09\xb5\xc0\xdf\x97\x3b\x2d\x7e\x37\x44\x7a\x18\xf0\x23\x22\xa1\x6a\x4c\xde\xd5\x2d\x2b\x15\x8a\x28\x51\x2d\x2d\xaa\x4e\x8f\x43\xa7\x5d\x85\x42\x20\x33\x55\x51\x72\x99\xa5\xff\x86\xc3\xbf\xae\x50\xde\x86\x77\x1c\x81\xd1\x82\x10\xd7\xdb\x8e\xe7\xbb\xac\xf8\x24\xf3\xa0\x22\x88\x59\x4b\x99\xb6\xbe\xd6\xbf\x0d\x8e\xb2\x20\x11\x56\x3a\x0e\xc5\x24\xee\xd4\x23\x94\x62\x4c\x62\xaf\x14\x82\x7b\xf6\xc5\xeb\x6e\xb1\xed\xcd\x7f\xa6\x62\xdc\xb3\xde\x7b\x2d\xb9\xf6\x50\xac\x7c\x2c\xa8\x89\xeb\xed\x00\x39\x94\xc7\x21\x06\xc4\xce\x45\xfb\x4f\x14\x0c\xff\x97\xbd\x46\xa2\x15\x96\xaa\x1c\x00\xcf\x16\xd5\x8b\x97\x22\x5f\xd6\xa7\x87\xeb\xed\xb3\x82\xba\xe2\x1e\xc5\x15\x7b\x2a\xea\x4d\x51\xf3\xba\xe8\xb7\x2c\x2a\x9e\x18\x02\x73\xf1\xce\x3f\xa3\xfe\xb2\x23\x25\x03\xcc\xb3\x1e\x4b\x2e\x6d\x7f\xd6\x4c\xd7\x50\x62\xe5\x97\xec\x79\xd9\x21\x9d\x95\x22\x4c\xc7\x8e\x99\xf4\x98\xe6\x53\xaf\x53\x31\xd3\x07\xb5\x5f\xf4\x35\xc8\x94\x02\xdf\x87\x51\x09\xc7\xf3\xdb\x83\xb1\xb0\x60\xd9\x73\xf1\x0e\x3f\x1d\x2d\x1d\xa8\x2f\xf5\x08\x95\xd2\x24\x41\x23\xb3\x9a\x0f\x7e\x4b\x7b\x14\xf1\x15\x20\x0d\xf6\xa1\xad\x6e\xf9\x36\x79\x0e\x84\x24\xb8\x8d\x7f\x33\xdd\x39\x5b\x9e\x1b\xf8\xe9\xc8\xde\x00\x49\x00\x39\xcd\xb9\xd6\x29\xda\xc5\x0a\x5d\xcd\x61\x3a\x1d\x88\xf0\xd1\x57\x2c\x2e\x70\x47\x2e\xaa\xc0\xa3\x66\xa9\x9a\x74\xe9\x33\xd4\x7c\x6a\x45\x81\x1f\xf8\x68\xda\x76\x2f\xfb\x4d\xc6\x25\x18\x3a\xa3\xbf\x6a\xd2\x77\x27\x73\x8d\x89\x82\xa5\xba\xf6\x22\x0d\x08\x7d\x42\x3c\x07\xec\x31\x18\xc6\xcf\xba\x80\x20\x8c\x13\x0c\x88\x96\xf3\xf5\x33\xea\xc4\xd9\xbf\x47\x84\x13\x66\x1b\x37\xd2\xfc\x0a\xbb\x6b\x85\x35\x7d\xb5\x3c\x5f\xb2\xe2\x06\x30\x3d\xeb\xdd\xd9\x94\x62\xbf\xb1\xc9\x2b\xb5\xd7\x0c\x09\xba\x6a\xf8\xd7\x2d\x7e\x74\x35\x0d\xea\x87\x28\x36\xba\x48\xd8\x85\x8d\x19\x61\xc4\xd5\xba\x2b\xb1\x40\x08\x8b\xec\x2a\x79\x0d\x4e\x20\x70\xf8\x68\x2c\x8c\x91\xdc\x72\xf3\xf3\xdb\xd3\x10\xf4\x38\x7c\x8b\x2c\x51\x58\x93\xd9\xaf\x66\x2f\x7f\x2e\xfb\x2f\x92\x71\xdf\x73\x11\xd9\x7b\x61\x32\xbd\xa3\x49\x10\x07\x1c\xc1\x7a\x82\xe7\x6f\xcf\xd7\xac\x4e\xab\xb6\x71\x0e\x92\xc4\x60\x25\xef\x95\x6d\x2c\x64\x1a\xb3\x85\xf7\xab\x09\x12\x10\xc2\xd2\x59\x3c\xa0\x66\xb4\x8d\x02\x87\xf7\x9d\x68\x9f\x8a\x96\xbc\xc6\xf2\x40\xd8\x63\x9c\x12\xcc\x31\x3c\xcf\xfe\x38\x3c\xbe\xbe\x2c\x76\x87\xed\x6c\xb5\x5b\x2e\x0e\x8b\xd7\xed\xea\xe5\x9b\xeb\x72\x6f\x87\xeb\x88\xfa\x7d\x2f\x73\x59\x9f\xf6\xc5\x8f\x54\x7c\x12\x09\x80\x08\x0d\x31\xb4\x4a\x2b\x9b\xbc\x75\x04\xa6\xd5\x58\x31\xda\x9e\x21\xa3\x08\x8b\xc2\xe7\xa2\x79\xf2\x9f\x3c\xed\x37\x86\xbb\x31\x8c\x3b\x2a\x70\xcc\x6c\x7f\x2a\xdc\xae\x40\xc5\x14\x8d\x52\x5a\x6d\x78\x3a\xea\xa4\x06\xa0\xc4\x01\x43\x9b\x10\x0e\x7d\xe1\x6a\xec\x3a\x02\x50\x86\xe5\x65\x79\xd8\xed\xff\x79\x01\x14\xcb\x73\x87\x84\x61\x5f\xad\xae\xa2\x8f\xbd\x00\xd0\xd2\xa4\xb1\x1d\xaf\x8b\xfd\xbb\xf6\x40\xcb\x16\x37\xfb\x9e\x16\xd7\xaa\xd3\xc4\x70\x63\x84\x8e\x4d\x52\x81\xab\x5b\xfb\x47\x15\x3a\x9a\xa1\x79\xf1\xae\x41\x8f\x27\xb1\x06\x82\xae\x68\x5a\x35\x21\xcc\xfa\xbd\x75\x71\x41\x43\x8c\x9f\x78\x8e\x99\xac\x33\xa8\x54\xa6\xb9\x83\xa8\x6a\x42\x22\x14\x2e\x30\x94\xcc\x7d\x3b\xa9\x89\xef\x45\x61\xc7\xf8\xbe\xbe\xd6\xb3\x6b\x7d\x82\xbc\x4e\x6d\x30\x3d\xb8\x03\x4d\xe2\x58\x18\xdd\xa3\x26\xe8\x5b\x80\x4c\xbf\x20\x99\x76\xe7\x70\x06\xcc\x21\x2f\x2d\x7c\x65\xe2\x2b\x6a\x22\xc2\x90\x7d\xb5\x42\xee\x17\x87\xf6\x42\x23\x6b\xb9\xdb\xff\x74\xd9\x4b\xed\x45\x11\x5a\xb1\xea\x13\xc7\x45\xd3\xc8\xa7\x16\xe8\x96\x9a\xae\xc8\xa5\x4b\x66\xb5\x23\x94\xd7\x72\x79\x9b\xbc\x50\xcd\x8f\x4e\xa6\x4a\x69\x1f\x94\xd3\x3f\xc2\xb2\x7e\x8f\x54\x51\xe9\x30\x24\xd4\x0a\x20\x3d\x5c\x6f\xd3\x15\xa1\xe1\x0d\x85\x00\xb4\xaf\x0d\xe1\xa0\x50\xf6\x70\x24\x39\xe3\x6d\x33\x75\x35\x76\x26\x07\x13\x59\x33\xed\xc7\xda\xce\xca\xc7\xa2\x7c\x48\x6b\x24\x3c\x9a\xfe\x34\xb1\x4f\x0c\x2f\x60\xf3\x9c\x4f\x85\x7c\x7b\xbd\xec\x40\xfe\xd6\x1e\x0d\x51\x41\xfb\x67\x51\xbe\xe1\xb2\xe9\xbb\xff\x2d\xb7\x80\x8e\xa3\x18\x03\x15\xd3\xe1\x3f\x3b\x16\xf9\x26\xe3\xa3\x68\x46\x27\x89\x51\x60\x99\xcf\xbf\x1f\xf6\xcb\xa7\xc3\xec\xc7\xea\xc7\x81\xb4\x2f\x94\xc7\x2a\x49\x5c\x35\x74\x10\x72\x6a\xae\x38\x56\xfd\x5a\x24\xf2\xd7\xde\x8c\x96\x9e\xc9\x4b\x98\x2c\x49\x76\x89\x46\x77\x22\xa9\xe6\xc6\x58\xac\xf2\x4d\x59\x1c\x7b\x06\x5c\x43\xe8\x51\xb0\x4c\x67\x9b\x6f\x6b\x64\xba\xcc\x6e\xab\xbc\x86\x32\xe7\xd9\x0f\x7e\xcd\x26\x70\x36\xce\xaa\x69\x88\x23\x04\x2d\x6d\x4a\xe0\x7f\x91\x8d\xd2\x10\x73\x57\x6e\xdd\xbd\xa5\x59\x86\x5e\xf6\x27\xd9\x7b\x7b\x8a\x8e\x8d\x04\x9d\x14\x76\xdb\x71\x53\x0e\x08\x89\x85\x69\x04\x73\x26\x7b\x0b\x55\x73\xaf\xf6\xb0\x1f\x68\x4c\x43\x9a\xcd\x81\x67\xd0\xcd\x4b\x37\x22\x96\xb8\x73\x61\x0f\xec\x7e\xac\x83\x0c\x24\xf4\x14\x3a\xd1\x16\x6e\x6a\x4e\x36\xee\xc9\x73\xd1\x2b\x90\x4c\xcd\x49\x20\x61\x48\x10\x88\x51\xd5\x70\x59\xe7\x4e\xe6\xa7\xbd\x76\x44\x50\x35\x58\x15\x2f\x45\x63\x7d\x0a\x8b\x3d\x1b\x5d\x43\xf9\x18\x6d\xfd\xb7\xd7\x6c\xca\xdf\x20\x87\x2a\xad\x46\x63\xa2\xc0\xf0\x49\x7e\x07\x75\xc4\x25\xfb\xe6\x12\xcf\xee\xb7\x22\x9e\xc8\x2e\x85\x86\x16\x2f\x87\x1d\x0c\x32\xd9\xed\x50\x89\x21\xcc\xeb\xcb\x6e\x33\x7b\x9e\x40\xc1\xf4\x03\xdf\xb6\xb0\x0f\x84\x79\xd4\xed\xd7\x2b\x59\x6c\x78\xc9\xcf\x7f\x89\x41\xec\x89\xb4\xdf\xc7\x0d\xdd\x2d\xb1\x10\x7c\xb3\x6b\x18\x81\x9d\x09\xc0\x0c\x10\x16\xf9\x68\xec\xb7\x9b\x97\xce\x7d\x01\xc2\x12\x96\xb4\x73\xa0\x71\x24\xda\x6f\x1f\x13\xa3\x42\xd4\x22\x96\xef\x31\x0b\x63\x2e\xe9\x29\x3f\x00\x48\xec\x0b\x2c\x3a\xcb\x12\x54\xb1\xac\x4f\xf7\xf2\xb9\x40\x92\x40\xa0\x8e\xe0\x7e\xb3\x6b\xff\xc4\x03\x6e\x64\x2a\x75\xcb\xe9\x78\xb7\xba\x80\x08\x22\x71\xcb\x7c\x5e\x0d\xbe\xa8\x68\xc2\x74\x57\x20\x2a\x6e\x83\x38\x13\x88\x64\x71\xc4\xda\xf2\x4a\x13\x73\xac\xb1\x3f\xe6\x2e\x27\xfa\x15\x3d\x24\x10\xa9\x02\xcf\x14\x47\x1d\x1e\x6b\xce\xb3\xac\x63\xbe\xb5\xc3\x54\x12\x6b\x68\xb1\x0e\x82\x8b\x34\x4b\xeb\xd4\xe6\x67\x5b\xce\x43\x20\x8a\xfb\x98\xc8\xfd\x59\x14\xd3\xc4\x40\xbd\xdd\xa1\x19\x9d\xb0\xb6\x0b\xae\xda\x15\x99\x5a\x39\xf9\x35\x20\x4a\x25\x71\xd0\x6a\x5d\xbc\x56\x6a\x34\x1b\x80\x41\xdc\x57\xbe\x47\xa0\x7b\xa7\xf1\xf9\x59\xce\xe4\xee\xed\xeb\x58\x61\x36\xa2\x6a\xf6\xc1\x83\x77\xe8\x49\x88\x00\xd1\xc2\x90\x56\x59\x9c\x2c\x3d\xec\xf6\xb3\xdf\xad\x3f\x09\x1e\xf1\x12\x27\x1d\x79\x48\x65\x91\xa7\xff\x3a\x5c\x4a\x38\xbc\xdd\xe4\x41\x14\xf9\xb5\x3a\xa8\x4f\xb8\xdc\xc1\x23\x51\x44\xe3\x41\xb9\x71\x0b\x97\xa2\xac\x2d\xab\x90\x4b\xfc\xd8\xd1\x5e\x10\x7a\x7d\x0d\xd9\xbe\x1d\x1b\x5e\xd7\x8b\x89\xa3\x6e\x6e\xbc\xa8\x2a\x3d\x9e\xc6\x3d\x76\xbd\x25\xed\x51\x62\x84\xa4\xda\xc4\xb1\x2b\x33\x7e\x9d\x41\x02\x8f\x86\x84\x24\x3d\xf8\x81\xb1\x9b\x23\xf5\x52\xf0\x68\x1c\x39\x8f\x71\x88\xbe\x72\xaf\xdf\xa3\x22\x88\xa0\x2b\xf3\xa9\x4d\x91\xb6\xc9\x47\xf0\x7c\xa9\x4c\xd7\x54\xc6\xd3\xf3\x77\xea\xfe\x1c\x10\xc0\xee\xdb\xbd\xcd\x6b\x7c\x8e\x4b\xea\xaa\x0c\xe0\x05\x2c\xc1\x5a\x7a\x0d\x55\x6d\x4b\x19\xa6\x5c\xff\x02\x1f\x5b\x78\x4f\x1b\x53\xf9\x52\x18\x82\xb5\xf6\x97\x84\x51\x16\xdb\x40\xbf\xc0\x0a\x5e\x48\x23\x34\xc8\x3a\xd5\xf5\xed\x50\x7f\x14\x87\x0f\x80\xb7\xf6\xbe\xa3\x00\x4c\xa4\xd1\xdc\xf7\x90\x0e\x6d\xf4\x22\x23\x9d\x20\xd5\x73\xfa\x90\x3a\x3c\x04\x78\xcc\xe7\x98\x67\xc0\x16\x33\xec\x8b\xfd\x8e\xcd\x03\x77\x4a\x6b\xe0\x31\x60\x92\x5a\x50\xc5\x63\x0a\x99\x32\x9c\xbc\xf6\x68\x9c\xc4\x56\xec\xd2\xa4\x1a\x1e\x6e\x4f\x70\xe4\x3d\x16\xd2\xa9\x3d\x1c\xbc\x18\x04\x6a\xb2\x41\x7d\x7a\xdd\x2d\x7a\xf8\x3d\xf0\x62\xad\x5d\x6e\x6e\x0b\x1a\xe3\x97\xe9\x19\x92\x10\x26\x5d\xc1\x9c\x7a\xa3\x69\xca\x3d\xdf\x77\xfa\x70\x86\x27\x7e\xc2\x3e\x78\x22\x12\xb2\x93\xb3\xbf\x8d\x5b\x03\xc1\x13\xca\xc7\xd7\xdc\xc4\x7f\x3d\xd9\x0b\xf0\xa4\x36\x52\xf3\x46\x70\xe4\xa5\x89\x3f\xc7\xb2\xde\xe0\x29\x5f\x62\x3d\xb1\xba\xaa\xe2\xed\xea\x4e\x55\x4c\x61\x04\x87\xf0\xb2\x95\x68\x1f\x1c\x48\x84\x28\x76\xfc\xa4\xcd\x1c\x9f\xda\xcc\x3d\xf0\x03\xdc\x29\x6c\x67\x59\x71\x45\xf1\x9f\xe1\xef\x82\x34\x54\x09\xe8\x12\x3e\x02\x54\xbd\x1e\x42\xf0\x34\x63\xac\x43\xa4\xe3\x75\xf6\x45\x57\x4c\x02\xea\x79\x4c\x33\xa3\x08\xfb\x68\xd9\x4f\xda\x43\x4c\xf9\x96\x01\xe7\xe1\x7a\x9b\x17\xd7\x72\xd4\x0e\x05\xd4\x4b\x22\xb4\x59\x17\xbf\x3d\x49\x4b\xec\x0f\x38\xf0\x09\x50\x37\x50\xea\x9b\xfe\x29\x84\x01\xcb\xb7\x56\x26\xad\xbb\x24\x0d\x0c\xc0\x0e\x9f\x07\x3b\xac\x7a\x2b\x85\x52\x6e\xf4\xb4\x66\xab\x9f\x5f\x6d\x06\x94\x2a\xdf\xb7\xf0\x40\x0c\x3a\xcc\x4b\x19\x0e\x01\x93\x0a\xa8\xa0\x7e\x2e\x72\xa8\x4f\xfc\xb3\x22\x4d\x67\xe2\xa8\xef\x27\x98\x7e\x13\xd7\xdb\xde\x65\xc2\xdc\xbe\x46\x03\x4f\x1a\xd8\xab\x79\xdb\xcb\x5f\xc5\x25\xe3\x39\xd4\x9f\xa1\x1c\xae\x03\x75\xec\x9e\x2b\x13\x0f\x1f\x26\x60\x1a\x2b\x0b\x2e\xc5\x77\x28\xf4\x81\x3b\xb1\xb3\x43\x56\x1c\x53\x39\x7a\xcd\x51\x68\xbc\xc0\x59\x5a\xee\x3e\xf8\xe5\x3b\xf6\x4a\xfc\x85\x15\xa6\x2c\x14\xc8\x71\xec\x96\x37\xb6\xb0\xfe\x45\x52\x6d\xb8\xd4\x29\x53\xa6\xf3\xb0\x31\x32\x13\xbc\x8d\x40\xe3\x90\x69\x0b\x1f\xb4\xe5\xdd\xe9\x7b\x89\x99\x67\x89\x3d\x50\x78\x2c\xdb\xc2\x3b\xe4\x57\x87\x0f\x1b\x5e\x33\xf1\x0d\x03\xfc\xdf\xa3\x1b\x75\x3b\xf9\xe0\x0d\x73\xaa\x88\x01\x6b\x35\xf1\x80\xc3\x50\xb8\x83\x0a\xd0\x0d\xd9\x7d\x80\xeb\x31\x1a\x6e\x0b\xc3\x5b\x17\xda\x77\x32\xc2\x0e\x21\x39\xc9\x4b\x0f\x54\x7a\x46\x49\xe6\x9a\xa7\x35\xa8\x17\x23\xd4\xe0\x7e\x55\x32\x1f\xfb\x43\xb8\x52\xbf\x5d\xef\x54\xd0\x81\x4a\x65\x3c\x16\x0c\x84\x8b\xa9\x54\x01\x50\x15\xfa\x86\xec\xb1\xd9\xe7\xaf\x25\xf4\x57\x92\x8a\x88\xd1\x3d\x38\x95\xad\xd8\x3f\x50\xc5\x03\xe1\xb7\x70\x71\x18\xca\x17\xb9\x31\x22\x56\x36\x2f\xd0\x12\x82\x4e\x86\x6f\x40\x81\x1a\x60\x47\x75\x2a\x3e\x9e\xa1\xaa\xf8\xf1\xde\x95\x1a\xdc\x31\x24\x46\x8b\x5d\x3a\xc0\x27\xa8\xc6\x59\x6b\x8f\x02\xd8\x98\xe1\xf7\x3f\xe7\x4e\xd9\x61\x5f\x58\x68\x9d\x69\x06\xea\xad\x56\x50\x40\x7c\x97\x29\xca\x9a\x80\xaf\xe4\x99\xa9\x22\x56\x4f\x90\x1f\xeb\xf6\xb9\x41\x19\xad\xb3\xe5\x7e\xbe\xbb\x96\xef\x23\x41\x43\xa0\x9a\x08\x61\x85\x79\x0c\x98\xb6\xbc\xcd\xef\x5e\x8c\xf6\x08\x36\x03\x5b\x16\x4f\x28\x9b\xff\x52\x3f\x40\x0e\x3a\x95\x29\x2f\x5b\xb8\xd1\xe4\xe6\x4d\x75\xa8\x3d\xda\x72\x34\x3c\xf2\xab\x84\xf1\x8c\xd1\x2a\x40\x45\x10\xe4\xcc\x54\xcb\x5f\x17\xc8\xab\x56\x79\xcf\x7d\x5a\x9f\x04\x5e\x2c\x9c\x09\x35\x39\xa2\x01\xfe\x04\x7c\xa2\x02\x74\x01\x9b\xef\xb2\x80\xf7\xd1\x51\x8f\x29\xc3\xd2\x67\x01\x14\x0a\xe0\x3c\xea\xb1\x01\x9f\x7a\x1e\x6e\xdd\x59\x51\xc1\x00\xb7\x09\x3e\xa5\x89\x49\x5b\x5a\xa1\xcb\x2f\xd0\xbe\xe0\xd3\x84\x3b\x9e\x09\x53\x9d\x69\xaf\x22\x75\x6c\x60\x0e\xe7\x34\x6f\xb9\x84\x0f\x35\x9c\x2f\x4f\x85\x7c\x1b\x1b\xeb\xc9\x58\xcb\xf7\x85\x44\x00\xf6\x7c\xbd\x7a\xd9\x1d\xf6\xeb\xc3\xf7\xd9\x7e\xfe\xfd\xe0\xed\xf6\xdb\xd5\x66\xb3\xdc\xba\xe8\xca\x0f\x12\xcf\x25\x7f\x77\xeb\xa7\xc5\x61\xf7\xba\xd9\x38\xe6\x03\xf0\x43\x9f\x6a\x57\x1c\xeb\x95\x04\x1f\x01\xba\x11\x86\x63\x26\xcd\x2f\xd7\x9a\x7f\xc2\xee\xd1\x9f\xea\x7e\xe8\x1b\xf2\xcd\xe6\xdd\x1e\x21\x97\x37\xf7\x1d\x47\x58\x22\xf0\xc3\xc4\x48\x36\xdb\x68\xbc\xbc\xc2\xeb\x6e\x61\xfa\x35\xbb\xed\xda\x8f\xe2\x04\x75\x0d\x57\xf3\xb5\xc9\x2b\x4f\xc9\x89\x4f\x00\x66\xc0\x67\x24\x42\xb9\xd9\xcd\x76\xdc\xe4\x08\x3e\x63\x94\x18\x85\x10\x4c\x78\x4e\x13\x48\x80\x1f\xd3\xd0\xf0\xe3\x1b\xe7\xca\xaa\x1b\xf5\x77\x47\x3f\x89\x13\xac\x66\x5b\x3d\x49\xc7\x0e\xd8\x07\x46\x82\x9f\x80\x88\x5b\xfd\x5e\x83\xd9\x5f\xeb\xb9\xeb\xd1\x74\xc6\xd1\xe7\xcd\xeb\x6b\xdf\xc8\xba\x4c\x8f\x0b\x78\x1f\xbd\x35\xae\x75\x62\x5d\x0d\x9b\x95\xeb\x3a\xaa\xc0\x17\x02\x70\xad\xfe\xf7\x3f\x9e\xfa\xd5\x37\xf0\x65\xc8\x10\x05\x81\x9e\x99\x6b\xbc\xdf\x94\xb0\x9a\xaf\x27\x28\x77\xc1\x57\x21\x4f\x5a\xb2\xef\x0b\x86\x8c\xf9\x0d\xbd\xec\x6a\x95\x3f\x40\xfd\x01\xdd\xb5\x15\x30\x6c\x3a\x7d\x7d\x79\x5c\x3f\xaf\xff\x76\xae\xc4\x07\xcf\x30\xe4\xd4\xfc\x0d\x1c\x95\x7c\xfb\x5e\x21\xa6\xc8\x87\xe1\x3a\x54\xe6\xd7\x69\xf4\x1f\xf8\xda\xd7\x5e\xbf\x17\xe8\xcb\x0c\x21\xf8\x9a\x09\xf4\xb5\xf0\xb1\x0d\x52\x70\x8a\x1b\x16\x7c\x1d\x87\xd8\x36\xf6\x81\x1d\xae\xae\xd5\xda\x1c\x0c\x88\x2f\x15\x73\x5c\x1a\x25\xf0\x69\x34\x33\x04\x24\x61\x58\x1d\x71\xef\xd9\x9d\xef\x85\x0a\x1b\x70\x34\x2f\xe1\x03\xb2\x71\x5b\x22\x04\x1e\x93\x06\xdc\x6b\x00\x59\x23\x9d\x5e\x37\x88\x33\x4c\xf7\x2e\xb6\xf3\xf6\xc2\xc2\x43\x2e\xa9\x9c\x9f\x61\xcf\x7b\x41\x9f\x3b\x0e\x1a\x3b\x1d\xf6\x27\xfe\xe1\x3c\xaf\xa9\xb0\x37\xa0\x51\x20\xa1\xa7\xfb\x30\x60\xc1\x81\xc0\xa7\x01\xf6\x8b\xce\xcb\xdb\xa5\x2e\x2e\x4e\x37\x07\x02\x3f\x21\xc8\xe5\x7d\xe6\x6f\xf0\x54\x1c\xe7\xc8\x0b\xf6\x77\x1d\xae\x69\x7b\x17\x04\x1e\xc3\xce\x95\xda\xa9\xf0\x50\xe2\x25\xee\x07\x03\x2d\xb1\xb0\x9c\x62\x4a\x72\x90\xd9\x0c\xc2\x44\xa2\x3e\x78\xc7\x7c\x3a\xfd\x99\x22\x42\xd1\x56\x20\xdd\x01\x5c\xcf\x7f\xb8\x0b\x44\x01\x41\x90\x70\x8a\xea\xe2\xda\x70\xfa\x4d\x5b\x8b\x20\x0a\x18\x76\x9d\xbf\x1b\x8c\x90\x89\x9b\x6d\x2f\x4e\xda\x87\xd2\x8d\x4e\x8b\x39\x2e\x9f\x39\x64\x75\x2a\xfb\x11\x74\x10\x47\x86\xd0\xec\xdf\x50\x16\x3b\x4b\xbd\x7c\xff\x76\x62\x4e\x4c\xfe\xb7\xd9\xb4\xfa\x02\xf0\xf6\x78\x22\x3c\xf4\x2f\x66\xf9\xad\x3e\xa5\xf9\x71\x66\x71\xbf\xae\x56\xfa\x1f\x7e\x93\xbf\xfb\xaf\xfd\x75\xce\x04\xc2\xd1\xd2\x8e\x55\xab\x13\x57\x84\x80\x27\x26\x3b\xfd\x72\xbc\x76\xab\x83\x4b\x8a\xe8\x28\xbc\xcd\x05\xaf\xf9\x27\x6f\x5c\x10\x4a\xad\xdf\xcd\x65\x9d\xbe\x03\xf2\xa8\x8c\x1e\x5f\x68\x23\xca\xf3\x0d\x72\x5e\x16\x9f\x03\xb4\xbe\xca\xbf\x43\x20\x03\xca\x49\x27\x44\xb5\x4b\x55\x6b\xb7\x03\x99\xc4\x18\xc9\x18\x07\x7b\x5c\x5e\x84\x40\x72\xe6\x45\x6d\x7d\xa3\x71\xe3\x65\x0a\xef\xae\xc8\x01\x81\x52\x09\xea\x1c\x7c\x43\x67\xa1\xeb\xe4\x81\x40\xe9\x04\x33\x3f\x97\xb2\x50\x57\x14\xc8\x69\x2d\x10\x84\x12\x37\xda\x12\xde\x81\x67\xa0\xe6\x8d\x83\xd7\xde\x12\xc4\x0c\x88\xb5\x4f\xff\xbc\xa6\xf2\x6d\x53\x16\xe7\xa2\x27\x70\x05\x01\x88\xc4\xf5\xae\xee\x00\x54\x85\xf0\xa6\x27\x5e\x59\x16\xff\xe1\x23\x80\x62\x49\xe4\x34\x57\xaa\x8d\x85\x87\xb8\x4b\x69\xdf\xb0\x6f\x5a\x05\x48\x05\xd9\x88\x98\x1c\x02\x1d\xc5\xc8\x3a\xb7\x59\xbf\xac\xdb\xd3\x58\x80\xbc\xda\x1a\x85\x47\x9e\xa1\x3e\x15\x6a\xc2\x14\x85\x84\xf8\xd8\xc7\xf3\xe0\x68\x1d\x21\x24\x51\x80\x7d\xf5\x3f\xd3\x3c\x7d\xeb\x5b\xd6\x90\x44\x86\x13\xec\x8c\xb0\xd1\xc6\x5b\x30\xc5\xfa\xae\x26\xe3\x06\x4a\xd3\xd9\x54\x41\x69\xe6\x65\x27\xa8\xdf\x7c\x7e\x9b\x83\xa3\x5d\x2e\xba\x53\xd7\x1f\xe7\x8b\x27\x67\x7e\x48\x40\xf8\x16\xe3\xb7\xcc\x55\x35\x1b\x59\xef\xd0\x13\x80\x22\xa1\xaf\xe7\x33\x3f\x2d\xd2\x9c\xbb\x8c\x5a\x48\x95\x44\x4b\x82\x9d\x3a\x96\x78\xd3\x7d\xb7\xd0\xa7\x44\x75\xf4\x69\x7b\xc3\x8e\xa6\x0b\x2b\x89\x37\x15\x31\x85\x7e\x62\x28\xae\x4c\xdc\xf9\x36\x20\x6d\xe9\xbf\x68\x3f\x21\xe8\xef\x7c\x14\x85\x1a\xa0\x1b\x20\x0c\x48\x84\x75\xf0\x03\xf9\xf5\x94\xd6\x20\x1d\xa7\x74\x7b\xdc\x8b\x11\x64\x58\xa6\xc7\x53\xcd\xc2\xd1\xa3\x06\x21\xc5\x1c\xe5\xfa\x75\x3f\x5f\x3f\x2f\x0f\x08\xde\x75\xa7\x86\xbe\x8e\xc2\x8e\xfa\x6a\xda\x4c\x86\x61\xc8\x8d\xb7\x00\x55\xed\x4c\xab\xad\x27\xf7\x63\x2f\xef\xae\xed\xc5\xc1\xaf\xfa\x7f\xbe\xff\x9f\xfd\x28\x34\x0c\x23\x46\xc3\xce\x66\x2d\x51\x8d\xb6\x8d\x24\xc2\x48\x49\x30\xcc\x8b\x68\xdb\x31\x0b\xd6\x29\x06\x41\x18\x41\x88\x28\x79\x14\xcc\x43\xf2\xdf\x66\xfb\xb8\xaf\x94\xf7\xde\x7c\x04\x46\x64\x08\x5b\x67\x94\x65\x03\x6e\xa9\x9c\xda\xaf\xc0\x42\xd3\xb7\xfb\x3c\xfb\xe3\xb0\xfe\xf9\xb2\xdc\x1e\x1a\x6f\xff\xb0\x5b\xed\xdb\xb7\xc9\xc0\xac\xfc\x0b\xbf\xad\xaf\x43\x4f\xd9\xa3\xf1\x7f\x0d\x3e\x4b\xec\xb5\x20\xbb\x0d\x97\x6f\x8d\xab\x8e\x25\x82\x5e\x92\x23\x1e\x7d\x86\xc4\xa7\x2e\xd5\x85\x34\x82\x1d\xc4\x78\x94\x14\x09\x93\x88\x63\x99\xfc\x5c\xbc\xc3\x1c\xd2\x6c\x0c\xf2\x80\x30\x81\x90\x91\x36\x34\x5c\xe3\x6b\x6c\xec\x8b\x3c\xf1\x34\xa7\x5f\xa5\x23\xc2\x44\x9b\x3a\x97\xc9\x49\x39\x6e\xda\xe1\x18\x2e\x63\x2c\x0e\x95\xc5\x48\x08\x06\x42\x0e\x66\xd7\xb1\x7d\xb6\x77\xad\x59\x10\x0a\x12\x61\x2f\x13\xb6\x31\xe1\xd7\xdf\x40\xb9\x6c\x43\xeb\x50\x81\xc4\x42\xf3\x9f\xbc\x58\x5c\xdb\x55\x00\xd2\xf4\xff\x19\xa8\xd7\x02\x10\x28\x95\xcb\xb4\x35\xcc\xa1\xf6\x59\x68\xab\x44\xb8\x8f\x98\xa2\xba\x0b\x1b\x6c\xc8\xd9\x93\x0f\x77\xa7\x29\x3f\x56\xbd\x32\x1d\x02\x8c\x2e\x59\x5f\x83\xa0\x9b\x4d\x11\x49\x38\xe6\xa3\x1e\xaf\x99\x4e\xb3\xac\x31\x82\x46\xbb\x76\xba\xb3\x1b\x22\x22\x35\xb6\x39\x36\x96\x58\xfd\x4c\xf3\x4d\x51\x64\x83\x8c\x6a\x44\x23\xa2\x6d\x62\xc5\x30\x92\xbf\xc0\x87\xf1\x22\x78\x5a\xb6\x83\x62\x8a\x38\x9a\xdd\x7c\x61\x00\x79\x5e\x7b\x44\x2a\x2e\x5c\x5f\x63\xb3\x75\x58\xad\x37\x77\x58\x01\x22\x39\xf4\x35\x57\x8f\x3c\xcd\xda\xbd\x31\xf2\x89\x17\xda\xea\xc8\x1c\x4a\x43\xcb\xd5\x17\xb0\x6b\x46\x44\x41\xd2\xa7\x93\x1c\x29\x20\xc7\x6e\x5c\x68\x26\xbb\x61\xc2\xda\x5c\xb3\xcc\x31\xda\x9a\x79\x3e\xee\xf6\xfe\x42\x41\x17\x22\x3f\x56\x26\xa3\xd3\xc4\x53\xab\xc7\x9d\xad\xdc\x0c\x07\x05\x44\x07\xb2\xc7\xc6\xe3\xee\x38\x8c\x35\x62\xd6\xce\x37\xcc\xed\x2c\x7f\x5d\xd2\x72\xac\x5b\x05\x51\x14\x46\x0e\xdd\x3d\xe7\x59\x36\xcd\xef\x09\x51\x64\x55\xda\xdb\xc7\x7f\x4b\xf3\xe3\x23\x40\x35\x0e\xa5\xa3\x88\x49\x4b\x18\x8b\x60\xf2\xd7\xed\x6a\x7c\x29\x29\xb1\x22\xb0\x2f\xb9\x84\x7d\x31\x8d\xb7\x98\xb4\xce\x51\xa4\x23\x83\x63\x45\x65\xa8\x5e\xe3\x2a\x44\x2c\x32\x02\x83\xe6\x06\x7f\x14\x75\x9a\x1f\x07\x8d\x2b\xd3\xdb\x67\xc4\x44\x4c\x6c\x23\xa8\x3f\xbe\x8b\xfb\x0a\x71\x14\x13\x40\xa0\xd1\x7c\xbb\x9c\xed\xd7\xdb\xdd\xc1\x74\x78\x1f\x66\x8b\xc5\x76\xb9\x73\x19\x91\x28\x66\xa1\x27\x5b\x5a\xd6\x1f\x50\x39\xaa\xba\xea\x71\xc4\xc2\x05\x51\x0c\x86\x3c\xa5\xf1\x90\x8a\x34\xfb\x7e\x3d\xab\xfa\xb6\xfc\x25\xe1\x72\x47\xca\x01\x51\x02\x4c\x59\x3e\x87\xf4\x7c\x3d\xbb\x28\xff\xa9\x28\x2e\x77\x4f\x6a\x4f\xe1\x9e\x92\x96\x5a\xf5\x78\xaa\x41\xfd\x40\xba\x7c\xeb\x42\x7e\x72\x4a\x60\x04\xf3\x4a\xa8\x4b\x9e\xd6\x8e\xab\xe3\xd0\x2e\x34\x11\x08\x70\x0d\x91\x43\x76\x51\x88\x44\x4c\x90\x82\xdb\xf2\xe2\x7c\x83\x73\xb5\x33\x7d\x8c\xed\xd9\x20\x10\xeb\x69\x43\x83\x87\xeb\xad\x3d\xa2\x25\xef\x54\x7b\xff\x51\x88\x87\x9b\xe3\x80\x1b\xbd\x08\x19\x18\xc9\x5b\x8c\xb9\xf6\xe7\x22\x87\x9b\x2b\x4a\x46\x92\x07\xd8\x00\x6a\xea\x42\xcb\xb2\x2c\xa6\xe1\xcd\xcd\x48\xc3\xf8\x7d\x84\xba\xf1\x49\x5d\xa8\x5a\xc2\x78\x91\xa9\xd8\x57\xb4\xbd\xb1\xa7\x82\xe7\x36\x56\x9e\xd5\x58\xe6\x7b\xb8\x3d\x21\x03\xd5\x68\xae\xab\x84\x9b\xf2\x68\x7f\x92\x4f\x4c\x2b\x88\x39\xa1\xbd\xb4\x70\xd6\x4f\x0b\x0f\x91\x8d\x10\x81\xf2\x11\xc8\x84\xf5\x71\xc3\x8d\x8a\x84\x15\xce\xfa\x47\x9a\x6a\xf4\x1c\x16\x8d\x91\x1f\xfb\x50\x91\x06\x1f\xdd\x3e\x6c\x2c\x7a\xde\xbf\xf6\x92\xbe\x91\xd6\x31\x77\x35\x88\x4e\x0f\x01\x18\x21\x26\x42\x68\x4b\xfc\xbc\xcc\xd3\xfc\x38\xda\x8c\x19\x91\xe6\xc3\x36\xd3\xa2\xb2\xb2\x32\xcd\x96\xed\x0e\x2b\x23\x85\x87\xf9\x48\x84\x38\xf4\x78\x27\x80\x51\x12\x21\x1a\x73\x8b\x8b\x66\x10\x1f\xfc\xd7\x10\xfc\xeb\x4e\xa0\xda\xc5\x16\xab\x0a\xa3\x0e\x7c\xa6\x4f\x74\xcf\x81\xd1\xd0\x27\x16\xa6\xb9\x6d\x6c\xd6\xd7\xa6\x81\xf9\x84\x3b\x50\x81\x79\xc1\x08\xd0\x9b\x72\xb2\x99\xef\xeb\xd0\xfa\x2b\x73\x7e\x19\xac\x07\x16\xf8\x1a\xdf\xe9\xe5\x9a\xbf\xdd\xf5\xfe\x00\x0b\x18\xc3\x5a\xc2\xf3\x77\xb3\x99\x61\x9b\xd5\x70\xf6\xb1\x90\x86\x58\x16\x71\x6a\x7b\xb8\x9f\xf7\xf0\x4d\x2c\x0c\x00\xf5\x05\x14\xbf\x55\xfd\xfe\x45\x60\x91\xc7\x59\x5b\xff\x5e\xc0\xfb\xd4\x16\xc2\x22\x1e\x23\x0a\xef\xbd\x99\x4c\x06\xda\x05\xbd\x38\x8f\x45\x5a\xe0\x16\x63\x28\xcb\x47\x48\x6a\x3b\x86\x25\x86\x2c\x61\xb6\xf8\xb1\xda\xad\xfb\x84\xc5\xc0\x98\x0a\x90\xb0\xd0\xa4\x71\x9e\x1b\xe3\xc3\xd3\xbc\xea\x4f\x4b\x16\x33\x8e\xcf\x28\x8b\xb2\x04\x59\xaf\xcb\xf4\xd8\x3c\xed\x00\x23\xc6\x62\x30\x4c\x18\xe6\x42\x86\xc7\xaf\xbd\xcb\x84\x03\xf6\xc3\x9b\xad\x17\x7b\x29\xe5\x7d\xb0\x32\xf9\x8f\xbd\x02\x8f\x69\xe0\x64\xa4\x31\x43\xf2\x45\x99\x94\x89\x28\x31\x92\x19\x65\x63\x7b\xef\xd6\xb6\x1b\x25\x7d\x5c\x8b\x5c\xa9\x81\x6e\xdc\xe8\xed\x49\x8f\x11\x3b\x81\xfe\x51\x08\x44\xea\x0d\xaf\x23\x3d\x49\x85\x83\xa9\x98\x45\xb8\x48\x8f\x50\xdd\xc3\x8c\x86\x01\x89\x3b\x9d\x19\x0e\x3c\x8c\x6b\x7a\x50\x08\x7b\x58\x25\xca\x68\xed\x3b\x86\xe6\xc6\xe1\xbd\x96\x9f\x68\xae\x01\x03\x5f\xd0\x41\xa9\xa9\xe8\x3e\x83\xa6\x91\xc5\x5a\x39\x1d\xab\x21\x2c\x64\x64\xce\x62\xc2\xe3\x28\x71\x8a\x34\x3c\xeb\xf2\xef\xab\xbc\xed\x44\x82\x98\xfa\x22\x60\x7d\xb5\x6b\xf5\x70\x2d\xa7\x91\x8f\x10\x53\x88\x23\x5b\x72\x40\xa9\xd9\x91\xb9\x8d\x03\xdf\x48\x91\xcc\x8e\x25\x60\xf0\xfe\x5a\x66\x5b\x87\x3b\x88\x83\x98\x40\x9b\xbb\x7d\x86\x9a\x2b\xde\x35\x53\xf4\x4b\xcc\x83\xf9\x10\x87\x89\x61\xb7\x98\x9f\xa0\xad\xb0\xfc\xb0\xac\x1f\xc3\xd7\x17\x47\x9e\x24\x23\x4a\xb2\x36\xcc\x1c\x8e\x8c\x89\x29\x02\x6e\x4a\x38\xa7\x39\x28\x34\xab\xee\x46\x63\x2f\x70\x8a\xcb\x0a\x0c\x6a\xa9\x3d\x44\x19\xaa\xf4\x7c\x43\xed\xd0\x61\x8d\x2a\x8e\x43\xc3\x6d\xdd\x04\x9e\xcd\x06\x4c\xbb\x03\x02\xbd\x8b\x8f\xa2\x7c\x83\xb2\x71\xcf\xbf\x5f\x45\x7b\x30\x8e\x42\x6e\xd3\xa3\xf6\xf1\x8c\x96\x6b\xcf\x10\xc5\x31\x67\x42\xf5\x24\x34\xba\x2a\x4f\x1c\x8b\x00\x23\xb5\xba\x65\x63\x2f\xe4\xdb\x13\xe8\xee\x9e\x55\x88\xce\xff\xff\x5d\xd5\x11\x1e\xf9\x9b\x99\x37\xb3\xbc\x6b\xcf\x99\x34\xeb\x71\x92\x98\x14\x7a\x07\x61\x99\xaa\x53\xc7\x89\x0a\xb1\xd4\x6d\x53\xcc\x13\x1a\x96\x3d\x34\x4f\xcc\xfd\xc0\x79\xa9\xf8\xdb\xcd\x4e\x75\xad\x5a\x35\xfa\x76\xcb\x8c\xb9\xaf\xf0\x4d\xef\xa0\xbc\x34\x93\xb6\xda\x5e\x11\x45\xe6\x9e\x8a\x47\x0a\x2b\x93\x56\x9f\xa0\xd9\xb3\xa7\x1a\x28\x21\xe6\x22\xc2\x56\xc0\x59\x29\xd2\xba\xe4\x47\x10\x6d\x1e\x3c\xe6\x92\x60\xe6\x58\xc1\x3b\x64\xc5\x05\xca\xea\x2e\xd3\x14\x73\xa5\x2c\xf1\x76\xfd\xdc\x58\x57\x3e\x6a\xb8\x83\x58\x30\x89\x20\x9d\xfc\x7a\x96\x3c\x6b\x73\x3d\xb1\xa4\x86\x58\xf9\xc8\xcf\x30\xba\x7b\x19\x32\xb0\xc8\x68\x3b\x89\xf6\x45\xf3\xd3\x1f\x6e\xbe\xa2\xa5\xe8\xdd\x85\xf2\x89\xe9\xe3\xe1\x97\xb4\xe6\xd9\x1e\xe4\xa9\xa5\xfa\xfd\x1a\x43\x11\xab\x98\xe2\x6d\x54\x1f\xfc\x72\x4f\x3c\x03\xb1\xe2\x8a\x05\xd6\x2b\x4d\xe1\xdd\x31\xbc\xba\xc9\x7d\x87\xc8\x8a\x95\x68\x99\x44\x1c\xb3\x3f\x77\xa4\xda\x10\x2b\xe9\x61\xa0\x62\x62\xc4\x1d\x18\x32\xab\x2f\x8b\x7e\x9d\x85\x51\xca\x34\x66\x3c\x5d\x7f\xb5\xdf\xab\xbf\x9d\xc5\x0a\x4c\xa3\x05\x92\x20\xf0\x52\x59\xb5\x8f\xaf\xaf\x0a\x7e\x82\x49\xb7\x7f\x6e\xbf\x7d\xb5\xf5\xc4\x9a\x79\x28\xaf\x7a\xe9\xa5\x5e\x26\xc7\xc5\x2a\x4a\xdc\x0b\xb0\xed\x32\xf3\x7b\x30\x45\x42\x08\xc5\x9d\x93\x2b\x85\x6f\xe8\x13\xad\x86\x49\xb1\xed\x2f\xff\x9b\xbb\x7e\xc4\x74\x4b\x60\x98\x0d\xb1\x44\x09\xe1\x21\xd6\x1a\xe1\xd7\x05\xbf\xc0\x3d\x34\x3c\xf1\x02\x95\xb0\x8e\x45\x03\x33\x8b\x06\x8f\xf5\x57\xf2\x3e\x83\x5f\xa2\x49\x6c\x24\x4e\x66\x7f\x4c\xf6\x67\x4d\xa4\xcc\x12\x9a\xa8\x40\xda\xec\xd1\xea\x61\x3f\xb7\x30\x30\xcc\x8c\x34\xeb\xf8\x73\xa7\x3e\xf1\x29\x65\x86\x11\xf2\x63\xec\xd3\xbb\x11\x89\x42\x1c\x40\xe3\x4f\x3d\x96\xc5\xd9\xb8\xc3\x3d\xe6\xfe\xf8\x7f\x3c\x1a\xff\xef\x7d\x79\xb3\x9b\xe4\x89\xaf\x04\x6a\x8c\xbd\x15\x1d\x61\xca\x80\x8d\x0c\x92\x80\x98\xee\x6a\x13\x1b\x7f\x2f\xee\xee\x23\xa0\x3e\x7e\x82\x53\xf1\xf1\xcc\xf3\xdb\x74\x54\x98\x04\x54\xa3\xfb\x2e\xae\x69\x86\xa5\xa7\xa2\xaa\xbb\x1d\x3a\x09\x18\x4d\x5c\xdb\xe6\xfe\xfb\x70\xcb\x49\x02\x45\x59\x6c\x45\x69\xb7\x70\xb9\xd6\x83\xce\x9f\x69\x83\x90\x84\x9c\x20\x61\xcf\xaa\xb8\x6e\x8b\xa2\x1e\x68\x4e\x4d\x51\x46\xda\xd3\xa2\xc0\xc7\x8c\x38\x8a\xb9\xa0\x32\xe8\xfe\x0b\x54\xd6\xc4\x87\x8b\x02\x03\x30\xc4\x90\x02\x2a\x97\xd4\x9a\x98\x1d\x51\xc8\x11\xb3\xd5\x36\x45\xfc\x04\x78\xcb\x2c\x68\x63\x38\x87\xa3\x58\x48\x07\x83\x48\x15\x54\xf7\xba\xaa\x90\x44\x42\x80\x91\xa2\xb4\x16\xd3\xe9\x07\x57\x4f\x05\x57\x6d\xba\x2a\x89\x94\xe1\x68\x3d\x54\x50\x5b\xae\x80\x09\xa7\x32\x61\xc4\x48\xb3\xed\xe6\x9b\x9d\xd7\xb7\x4e\x09\x23\x4a\x9b\x6d\xba\x4e\x4b\x78\xe6\x7d\x16\x71\x37\x24\xd0\x18\x26\xda\x76\x3b\xc3\xc0\xfc\x08\x08\x70\x1f\xdd\x36\x63\xb1\x49\xad\x73\xf5\xc8\x45\xfb\x1b\xb1\x32\xcd\xfe\xe9\xf1\x54\x27\x64\x74\x4e\xcc\x13\xf4\x20\x75\xcb\xbd\xd1\xf8\x61\xc3\x72\x40\x92\x84\x42\x25\xed\xde\x69\xf3\xaf\xf7\xb9\xb7\xcf\xfe\xbd\xcb\xb6\xb9\xcb\xda\x6e\x90\x26\x4c\xed\xb8\xda\x20\x49\x58\x82\x32\x0b\xe7\x42\xed\x6e\x67\x51\x64\x43\x43\x95\xa8\x10\xd3\x0a\xf3\xf5\xfa\x69\xb1\xfe\xf9\x72\xe8\xf3\x56\x41\xc2\x03\x0f\xaf\xba\x28\xb9\xae\xbb\x3d\xef\x4b\x8b\x9f\x70\xed\x23\x84\xf4\x98\xbe\xc3\x63\x51\xca\xd1\x96\x9d\x08\xcf\x47\xaa\xc6\xb6\xc6\xbd\x80\x2c\x7d\x87\xae\x37\x73\x68\xe1\x44\xe0\x59\xd5\x17\xe4\xf4\x7c\x2c\xca\x6f\x45\x91\xf1\x5e\x8a\x35\x91\xbe\x11\x88\xc4\x3d\x01\x33\x17\x8e\x33\x71\x35\xea\x35\x48\x64\x60\x28\x6d\x2f\x25\x5c\x78\xaa\x5e\xf3\xb4\xc5\x83\x27\x32\xb0\xa8\x3f\x5e\xc3\x1e\x72\x7e\xb7\xa7\xc8\xc4\xc7\x14\x58\x55\xf3\xb7\xbb\xa2\xf4\xe8\x2d\x48\x2d\x50\xb2\x36\xad\xe1\xbc\x45\x0e\x24\xf7\x33\xca\x17\x88\x10\x99\xd5\xc5\x3a\x87\xa9\x98\xec\x7a\x87\xf9\x4c\x20\x88\x8d\xa7\x89\xf1\xb4\x9a\xd2\xfb\x82\x44\x6b\xd3\x10\x67\xe6\x96\xb3\x10\x5b\x68\xae\x84\x61\xa3\xf5\xdd\x47\xeb\x82\x13\xc2\x10\xe5\xa7\x78\x9a\xdd\x90\x95\xb5\xe7\xc3\x72\x12\x46\x46\x36\xe6\x03\xe0\x32\x1d\x9d\x70\xc2\xb8\x6f\x9a\x61\x64\xf1\x0e\xe5\x2e\x3d\x5f\x46\x5d\x12\xf1\xf4\x6c\xe1\x9e\xa7\x2d\x5b\xe9\xf1\x98\x59\xfe\xcc\x67\x5e\xcb\x53\x1b\xaa\x73\xcf\xf2\x14\xcf\x94\x42\xf3\xb5\x2f\x10\x62\xf8\x15\x6f\x05\x70\x2f\x24\xd0\x69\xf4\xb9\xf8\xb2\xf1\xeb\x3f\x17\xb3\x02\xee\x45\xda\x37\x90\xf6\x5b\x9f\xca\x1b\x0f\xc4\x86\x34\xe0\x5a\x35\x6f\x36\xad\x3f\xc9\x4d\x72\x3f\x90\xe0\x3a\x96\x79\x59\xdf\x75\x5f\x02\xf7\x63\x2f\x49\x9c\x12\x67\xe9\xe4\x79\x9d\x42\xd3\x68\xac\x88\xd0\x7d\x5a\xcd\xd7\x87\xa1\x4c\x03\x70\x5f\x9b\xf7\xf2\x0d\xea\x26\x6a\x11\xa9\xdb\x9a\x78\x40\x42\x14\x80\xdd\xf3\x5f\xed\x9f\x6c\x7f\x95\xeb\x2e\xfa\x04\x77\xc3\x03\x1a\x5a\xae\x43\xf9\x36\xba\x97\x20\xf4\xc0\x35\xdf\xf1\xac\xa7\x62\x6a\x77\x29\x1e\x7a\x31\xc2\x08\x53\x59\x60\x3a\x67\x13\xb8\x5f\x0f\xa9\x87\x56\xef\xf0\x5e\xd4\x30\xfb\x14\xa5\x37\xe9\xe3\xf0\x28\x36\x44\x51\x39\x7c\x18\xb3\x3e\x2f\x2e\x6e\x0f\xe2\x51\x62\x54\xba\x10\xc3\xe1\xda\x8c\xd6\xf9\x03\x9c\x78\xa6\xd7\x7a\x0b\x12\x71\xea\x9f\xba\x45\x13\x4c\x7f\xc0\x23\xdb\x98\x61\x7a\x87\xfa\x5a\xf4\xc0\x23\xc5\x22\x65\x23\xcd\x6f\xbd\x5e\xd9\xb6\x0d\xad\x77\x19\x25\x7c\xe9\x2e\xf3\xd5\x22\x9f\xb6\x21\x3c\xd2\xc6\xa8\x77\x08\x90\x7d\x71\x79\xbd\xdc\xcb\xc7\x02\x67\x24\x0a\x44\xaf\x65\xa6\x28\x5b\x2d\xa3\xcf\x60\x1a\xee\xbe\xbf\x2e\xc9\x8f\x6e\x89\x25\x21\x9a\xda\x26\x62\x3e\x18\x80\x97\x7b\x31\x31\x68\xe0\x1d\xd0\xa3\x15\xf8\x04\x9e\xd0\x58\xb9\x72\x00\x6e\x42\xdf\x3b\x88\x31\x4f\x22\x43\xd9\x66\x6b\xb7\xc8\xdc\xf1\xc4\xab\x7a\xc3\x53\x35\x6b\x2f\xce\x89\x46\x24\xc8\x7c\xde\x6f\xc5\xe0\x42\x50\xdd\xb2\xfd\xe4\x50\xde\xba\xda\xcd\x97\x6f\x56\x48\x13\x45\x1c\x0e\x5c\x14\x65\xfd\x78\xad\xda\xb5\x23\xe3\x48\x05\xad\x62\x14\x1a\x51\x2e\xef\xcb\x16\x5c\x4a\x53\xa3\xba\x94\xe9\x7b\x9a\xc1\xf1\x73\xca\x8d\xd1\x6f\x4b\x65\xa4\x26\x90\xc6\x7f\xc3\xaf\x15\x18\xba\xb1\xd6\x05\xe3\x4a\x9a\xa6\x09\x9c\x37\x3b\xa8\xef\x85\x48\xbf\x24\xb5\x00\xae\x14\x57\xb4\xe5\xd8\x99\x84\xc9\x73\x05\x06\xce\x57\x42\x55\x64\xef\x70\x40\x80\xca\xe1\xd4\xcb\x2d\xd9\x81\x40\xe2\xc0\xee\xae\xb8\xe9\x5e\x3b\xbe\x7a\xb7\xf0\x41\xf7\x6e\xb8\xdf\xbf\xd8\x71\xac\x03\xd7\x02\x4c\xb3\xbd\x81\x5f\x00\x3f\x4f\x13\x75\x98\xe1\x82\x44\x46\x62\x12\xe5\x02\xf3\x87\xeb\xcd\xec\x0d\xbf\xb9\xc3\x89\x44\xfb\x0e\xf5\x49\x0c\x3b\xbb\xed\x00\x2f\x0c\x8c\x08\x99\x95\x23\x49\x47\x66\x58\x78\x60\xb0\x1d\x1a\xe4\xe9\x47\x51\xc3\x33\x4f\x11\x0f\xf2\x60\xba\xd6\x47\xa3\xa9\x97\x18\x65\xf9\x42\xd7\x92\x5f\xb6\xc0\x65\x67\x8a\x05\xa5\x4c\xc2\x80\x63\xb9\xf1\x9a\xdb\xa3\x21\x60\x41\xb2\x2f\x68\xb2\xce\xc7\x37\x4c\x23\x86\x49\xc6\xf9\xaf\x97\xfa\x3e\x55\x20\x28\x67\x81\x61\x31\x78\xe6\xa8\x1e\xd0\x5e\x5d\x13\x6c\x64\xba\xf0\xdb\xee\xc4\x4b\x38\xd9\x0a\xc5\xf0\xfe\x7d\x12\x72\x3e\x22\x72\x5b\xe5\xc3\x2a\x8b\x08\x18\x20\xd2\x3b\x4b\xf3\xb7\x3d\x42\x06\xfb\x6a\x0a\x43\x97\x53\x84\x5e\xc2\x6c\xc1\xec\x11\x35\x80\x7b\x7e\xa7\x08\x63\x6a\xa5\xec\xab\x7a\x51\xc8\x6b\xe3\x09\xb7\x08\xbb\x9e\x13\xdb\x4e\x7a\x11\x72\x85\x89\xea\x66\x1a\x62\x4a\xc9\xcc\x93\xf6\x82\x02\x90\x84\xd3\xde\x8b\x53\xcb\x6a\x73\xb4\x22\x04\x81\xd4\x35\x8f\xa9\x3a\x2e\xf7\xdf\x77\x97\x7e\x9d\x5c\x44\x5a\xe3\x93\x59\x53\xfa\xcf\x6b\x51\x5e\xcf\x43\x9c\xba\x60\x51\x62\x1a\x5e\x4c\x3c\xdc\x84\xec\x2d\x41\x24\x08\x26\x02\xec\x85\xbb\xe6\x0a\x4a\x55\x1c\xef\x7b\x95\x04\x93\x86\x95\xf6\xd0\xc4\x8b\xf5\xa9\x0f\x7d\x11\x71\x68\xe8\xef\x76\x35\xcf\xd2\x5c\x76\x58\x45\x11\x47\x06\x9a\xd2\xb8\xee\x59\xb6\xe1\xf2\x8d\x77\x8f\x9d\x78\xc6\xb5\x55\x45\xce\xeb\xc6\xf9\x75\x49\xaa\xef\xc0\xb3\x16\x54\x21\x38\x15\x9e\xdf\x03\x37\x8f\xe6\x0e\x8f\x8c\x46\xde\x6a\xbe\x36\xf2\x5e\x37\x4b\xba\xe8\xce\x17\x91\xc2\x2e\x61\xa4\xb9\x1a\x12\xf7\xc6\x6e\x08\xc4\x51\xc7\x5d\x8e\x8b\xd1\xd0\xab\xdd\xa7\x78\x85\xd0\x0a\xf3\xaa\x5c\xa9\x55\x0d\xe7\x0e\xa3\xfb\xff\x0d\x0a\x29\x24\xe1\xda\x29\x44\xcb\x53\xfb\x72\x64\x44\xb1\xc2\x30\x7f\xdd\x6e\x97\x2f\xbb\xe5\xf2\xeb\x6c\x9c\x90\xb1\x6c\x99\xd0\xdd\x8d\x8f\x7e\x48\x47\x98\xea\x3b\x88\x11\x07\xaa\x3d\xae\x12\xc5\x2c\x32\x6d\x76\x49\x1d\xa9\x8c\xbb\xd8\x64\x12\x54\x28\x2e\x3d\xda\x52\x34\x6d\x10\x90\x58\x37\x61\xfb\x7c\xcc\xa0\x08\x02\x68\x92\x18\x66\xc3\x77\xc8\xeb\x6b\x89\xa1\xe9\x50\xbd\x06\x84\xf6\x88\xe9\x97\xae\x8b\x12\x06\xbd\x9b\xc3\x1f\xd6\x21\xc5\xdc\xe8\xa6\x2c\x0a\xbd\xd6\xbb\x13\xc0\xc5\x6a\xcc\x82\x24\x1e\x35\xf4\x22\x3c\x83\x7e\x57\xa7\x24\xbe\x66\x9d\xb4\xef\xbc\xbc\xa9\xf2\x47\x0a\x1f\x83\xb8\x51\x92\x50\xe3\x7c\x5b\xbe\x6e\x7f\x2e\x57\xed\xa9\x51\x62\x58\x06\x81\x9f\xd7\x39\x2c\xd2\xf7\xea\x35\x97\xb6\x7e\xe9\xc6\x48\x23\xbc\x7a\x48\xab\x4f\x54\xf9\x40\x52\x9f\xa2\xfb\x7a\xe4\x55\xbf\x61\x5a\x52\x3f\xc2\x12\x7d\x9b\x9a\xd8\xf3\xea\x6d\x8a\x16\xbf\x19\x0a\xd8\x11\xb0\xde\xec\x07\x8d\xef\x92\x86\x9c\x44\x6e\x91\x7f\x42\xa8\x3d\x70\x3f\x25\x85\x04\x23\x39\x51\xd4\xa7\xef\xfc\x1d\x66\xb5\xad\x01\xdd\x37\x06\xf6\xed\xa3\xf4\xa9\x4e\xda\xf6\xe4\x0b\x9f\xec\xf9\x92\x7e\x1c\xe1\xa3\xce\xae\x75\x81\x1a\x9a\x78\xb3\x73\x9e\x3b\x7e\x1b\x90\x3e\xd7\xd4\x66\x32\xf7\xe5\xb5\xaa\x41\x61\x3d\x75\x64\x96\xed\xe0\x80\x68\x44\x86\x7e\x9b\x3d\x2f\x0f\x9b\xf5\xfa\xe9\xb0\x7a\x59\xed\xdd\xa5\x02\x99\x84\x9e\xab\x9c\xba\x98\x68\x3a\x10\x90\x01\x84\xd8\xe2\x24\x79\x96\x2d\xb7\x73\x2f\x0a\xad\xcd\xad\x90\xd8\x43\xf3\x5e\x33\x1d\xde\x81\xad\xcb\xc9\x90\xfa\x89\x5b\x23\xef\xbc\xe6\xe5\x70\xea\x44\xd4\x74\x2f\xf2\xaa\x82\xb2\x5e\xfe\x8b\xc6\x56\x69\xda\xee\x0a\x96\x20\x05\x64\xa4\x02\x1e\xb5\x0e\xc0\x84\xd3\x2b\x19\x0b\x7c\xd5\xb6\xe1\xfc\x1f\xc8\xda\x6a\xb5\xd5\xcb\xbc\x2e\x6f\xb3\xaf\xdb\x5d\xba\xeb\xc4\x01\xb3\xb4\x7a\x47\x9e\xa7\xff\x86\x32\x72\x2f\x2c\x49\x94\x72\x5d\xdd\xdf\x90\x49\x4a\xec\xea\x56\xb6\x0e\x64\x22\x3c\xc4\x3b\x22\x92\x71\x77\x39\x41\x77\x88\x13\x8f\xc1\x20\x6f\xf1\x67\x51\x88\x7e\xde\x42\xf2\x80\x63\x32\xe2\xf5\x77\xd3\x73\xd2\x5b\x10\x93\x59\x1e\xc9\x23\x9e\x40\x6b\x83\xb7\x20\x8b\x52\xf5\x0b\xab\xc3\x89\x2b\x12\x26\xd5\x58\x99\xf9\xe5\x7a\x5e\x5f\x6b\x59\x9c\x87\x9d\xc1\x52\x88\x10\xf3\xe5\xaf\xb3\xcd\x5f\x26\x7a\xa6\xcd\xab\x94\x09\x57\x49\x27\x65\xc0\x0d\x7e\x6e\xe4\x88\x48\xe5\x79\xd4\xa9\x51\xb6\x2d\xfd\x4f\x08\x3f\x77\x23\x98\xc0\x24\xb3\xc9\x0e\xdd\xb1\x92\x81\x84\x30\xc1\x1d\x13\x72\xc3\xd4\x3b\x8a\x68\x86\x77\x05\x4c\xa1\xdb\xa9\x8a\x3e\xc2\x7f\x34\x03\x40\x11\xea\x42\xf2\xea\xf8\x8d\x57\xc8\xe4\xe7\x6e\x48\x27\x1a\xf7\xf5\xd3\xed\xe2\xde\x97\x22\x22\x51\x6c\xa8\xc5\xfc\xdb\x17\x79\x0e\x45\x63\xc0\x99\x84\x46\x7b\xfa\x2e\x14\x55\x31\x96\xac\x8f\x29\xcf\xeb\xc7\x3f\x8b\xeb\xf4\xd2\x54\x54\x9b\xc6\x62\xcb\x40\x76\xe8\x4c\xb0\xf2\x7d\x1f\x9d\x75\x55\x5d\xba\x3f\x09\x4c\x62\x7f\xaa\x31\xfa\xf7\x42\x3f\xe5\x07\x7e\xd2\x76\x62\x3f\x19\x2f\x2d\x97\xe9\xa5\x05\x41\x29\x5f\x07\x86\xed\x02\x72\x55\x0d\x15\x8d\x40\x35\x96\xc9\x68\xb5\x23\xbe\xe7\xeb\x6e\x27\x77\x8e\x0f\x82\x0c\x8b\x3d\x98\xfa\x19\x8d\x52\x04\xdb\xe2\x55\xb3\x57\x42\x63\x9c\xbe\x61\xdb\xd1\x35\xab\x87\x31\x9b\x0a\x3d\x85\x8f\x60\xef\xe1\xe1\x7a\x1b\x72\xfc\x0e\x66\x8e\x0a\x43\x10\xb6\xde\x65\xa8\x0e\xeb\x31\xc5\x70\xec\x46\x32\x86\x6b\xfd\xe1\x7a\xfb\xbe\xde\xee\x96\x75\x1f\x89\xa0\x42\x1d\xc7\x7d\xb1\xa4\x6f\xfb\xd9\xe8\x09\xa2\x50\x71\xb0\x2f\xae\x0f\xd1\x54\x91\x32\x0b\xfe\x68\x6e\xe1\x3e\x99\xa4\x22\xf0\x70\xbb\xb6\xf9\xe4\x6b\xd9\xac\x08\x64\xb4\x6c\x1c\xd4\xc6\xc6\x2f\x7a\xd2\xd6\xd3\x21\xa9\x62\x2c\xc2\xde\xa6\x1e\x2d\xc0\x27\xef\x84\x49\x82\x1b\x7f\xe3\x1b\x1c\xce\x45\x5e\xf5\x5c\x70\x15\x07\x14\xdb\x31\xf6\xeb\xd7\xed\xcb\xec\x79\xf9\xb2\x3f\x3c\xcc\xf6\x7b\xc7\x91\x07\x2a\x4e\x34\xb2\xa5\x9b\xf6\x4d\x2c\xee\x4f\x7f\xf8\x24\x32\xb4\xf9\x68\x57\xe1\x7a\xde\x97\xfc\x1d\xb2\x7b\xc3\x34\x7d\x93\x89\xf4\x70\x07\xea\x11\x3e\x57\x6f\x9f\x65\xbc\x54\xa2\x15\x16\x3c\xf8\x7b\xb3\xf0\x87\xae\x88\x12\x14\x62\xc7\x56\xe7\xa4\xdb\x66\xb9\x32\xb1\xc9\x27\x50\x12\x25\x02\xa9\x1d\x32\x65\x7f\x2a\x8b\x8f\x2d\xa0\x03\xf7\xc4\x9b\xbf\x38\x36\x90\x45\x01\x55\x5e\xa3\x47\xd1\x32\xaa\xb9\x63\xed\x2b\x15\x09\x17\x46\xab\xb3\x96\x27\xeb\xea\xec\xef\x58\x31\xee\x0b\x3e\x4a\x08\x8e\x9c\x5c\xf9\xf5\xfc\x58\xb6\x88\x05\x25\x94\x87\x74\x0a\x27\x5e\xf5\x92\x30\x4a\x80\xc0\xcc\xb6\x91\x74\x31\x45\x78\x8b\x74\x6b\xa3\xc5\x67\x3e\x7e\x4e\xc9\x04\x67\x8e\x6d\xdf\x18\x42\x47\x1a\xd1\x52\x79\x8f\x5f\x28\x50\x0f\xfd\x2f\xc3\x80\xf1\x09\xda\x45\x41\x94\x44\xc8\x8c\x62\x80\xc6\x9b\xb2\x90\x50\x55\x63\x9c\xa9\xd2\x9e\x94\xc1\x10\x41\xc4\xb3\xc7\xe2\xaf\xe8\xb5\xcd\xd9\x40\x02\x42\x6c\x8b\x61\x5f\xfd\xce\xfb\xe8\x42\x77\xf0\xe2\x00\x8b\x15\xbf\xe7\xc5\x47\x6e\x00\x5c\x8b\xf4\x98\xd6\x3c\x33\xb0\x95\xc1\xfd\x80\x17\x87\x88\x4c\xeb\x63\x1e\x27\x85\x6a\x01\x68\x64\x98\x82\xcf\xfc\xd7\xe3\x35\x57\x3d\x2d\x34\x00\x0a\x3e\x72\xdb\xcf\x33\xe0\xb9\xcd\x27\x6c\x8b\xe2\x3c\xcb\x95\xe9\x1e\x1a\x5d\x0a\x54\xa8\x9c\x61\xb6\x71\xaf\x9b\x40\xe0\x7b\xa6\xfb\xc3\x49\x3a\xde\x67\x16\xc0\x57\x46\x97\xd6\x68\x54\x34\xf6\xa3\x09\xda\x36\x9f\xaa\x53\x01\x04\x22\x40\xda\x56\xeb\x56\x20\xec\xa5\x6f\xb7\x20\x54\x11\x8b\x9c\x67\x76\xb6\x5c\x21\xf6\x58\xe4\x05\x71\xd7\xac\xfb\x70\xbd\xa5\x23\x00\x37\x44\xbe\x46\xd2\xe5\xe7\x34\x87\xc6\x3b\xe8\x3b\xf0\x10\x05\x7e\x10\x9a\xcd\xff\x99\xa7\x79\x2f\x13\x02\x11\x8b\xd1\x8c\x1e\x44\x1f\x47\x35\xfd\xf1\x59\x60\x72\xb3\x7b\xa8\xea\xd0\x5d\x80\xc5\x34\x72\xda\x7a\xf8\xa6\x41\xdd\xab\x64\x35\xc3\xb8\x6d\x9c\x6c\xbb\x09\x46\x03\x38\x89\xfc\x9e\x7a\x7d\x55\x0f\xa8\x07\x3f\x63\xd1\xea\x39\xf2\x10\x93\x08\x23\xcd\xb6\xce\x6e\xd9\xfc\xb1\x40\xef\xc6\x04\x02\xad\xe4\x6e\xb1\x38\x2c\x4b\x49\xa9\x3f\x78\x53\x71\xec\x13\xaf\xd3\x58\x9c\xa8\x18\x01\x0f\x62\xda\x98\x97\x7f\x3e\xb8\x18\x01\x44\x18\x62\xa5\xf8\x52\x64\xd9\xc3\xb5\xcc\xe7\xc5\xf9\x92\x41\xcb\x8b\x0a\x20\x6c\xad\xa7\x02\x83\x94\xe9\x21\x91\xbb\x74\x0e\x08\x1e\xa2\x2f\x53\x9d\x8a\xb2\xc6\xbe\xe9\x5b\x7b\x01\xae\x70\x53\xfb\x47\x5a\x43\x4f\x1b\xfd\xd3\xe2\x17\x08\xc1\xf0\x96\xb0\x55\x91\xd7\xf0\xdf\x45\x0e\xbf\x59\x6e\xb0\xff\x72\xff\xe2\x79\xdd\xbf\xf6\x54\x49\x3d\xd3\x5a\xca\xaf\x59\xfd\xa5\x14\x57\x33\x56\x61\xfe\xc7\x6a\xa4\x8f\x4a\x87\x20\x7d\xd5\x4a\x89\x4b\x54\x06\x44\xbd\x85\x01\xea\x10\xa4\x30\x8c\x49\x47\xa8\x17\xc5\xb9\x89\xe7\x6e\x17\x38\x75\x96\x16\xa4\x8e\xb1\xe9\x7a\x07\xf5\xa6\x94\x79\xbd\x1d\x2b\xa4\x03\x28\x69\x32\x97\xe8\x45\x98\x22\xb5\xcd\x85\x0d\xd7\x2d\x50\xc5\x9d\xd8\xbc\xc1\xc0\x7e\xc5\xac\x00\x4d\x48\xe2\xf7\x11\xb7\x3d\x98\x1c\x68\xe2\x63\x90\x79\xc9\x38\xd2\x19\xad\xd5\xc8\xd1\x00\x4d\x25\x4e\x36\x6d\x2d\xfc\xfe\xa3\x68\x4f\x66\x1c\x31\x1f\xf8\xbe\xf6\xc5\x10\xb1\xe6\xc6\x24\xc4\x10\x6c\xd6\xbc\xac\x2d\x41\x87\xa5\x05\x30\x23\x34\xe1\x21\x2a\x69\x54\x28\xcf\xba\xef\xf3\x7a\x4f\x3f\x91\x26\x32\x46\xe9\x88\x1d\xd4\x0b\x5e\x8f\xf9\x7a\xdc\x20\xed\xbb\x94\xcd\xf7\xe2\x3c\x7a\x87\xda\x8b\x3d\x6e\x7b\x45\xb6\xbc\x4c\xeb\x9b\x5d\xd1\xa9\x5d\x2a\xb1\x1b\xc7\x3d\xa4\x36\x75\x68\xd2\x6a\xeb\x14\x7a\xdc\xed\x7b\xda\x90\xab\x64\x57\xf9\x76\x5b\xe7\xa3\x8f\xaa\x29\x23\x88\x6f\x6a\x1c\xd4\x92\xf7\xd7\xa9\xf6\x7d\x11\x3b\x7d\xe1\x5c\x17\xfe\xb4\xeb\xa5\x7d\xcb\x00\xa3\xd3\x5f\xae\xeb\xe9\x4e\xa9\xa7\x5b\x80\xda\x07\x23\xf7\x61\xc1\x0e\x83\x66\xe0\xeb\x3d\xe8\x46\x07\x10\x2b\xe1\xf0\xde\x99\x1c\xdc\x61\xe4\x11\xd4\x63\x6d\xf5\x47\x46\x6f\x91\x51\x8e\xc9\xe5\x07\x5e\xd7\x99\x63\xd1\xfc\xc4\xfe\x0e\x50\x55\x6d\xd1\xcc\x1b\x46\x1d\x43\x32\x6c\xd0\x2c\xf1\x10\x6d\xfd\xf3\x96\xed\xd2\xaa\x1e\x65\xc4\x74\x2c\x23\xec\xc2\xe2\x4a\x35\x6f\xf0\xc9\xa9\x8e\xe3\xe5\xff\x0e\x8e\x4a\xc7\x2a\x8a\x0c\x7a\x24\x2f\xae\xb9\x04\xac\xcb\x38\x43\xab\x93\x30\x46\xb9\x25\x1b\xec\x15\xd7\x52\xc2\x74\x00\xe3\x4e\x88\x05\xca\xb7\xba\x17\x36\x61\x7b\x75\x22\x24\xc6\x9c\x97\x13\xaf\xc0\x5f\x1a\x79\x8c\xf6\x91\x12\xf0\x70\x9b\xfb\x80\x74\xfc\x95\xed\x08\x4e\x22\xfc\x8d\xdd\x66\xb3\x83\x32\x85\xea\xe1\xaf\x4d\xa9\xe6\x11\x4d\x54\x2f\x2b\x01\x6d\x99\x5d\xf3\xc8\xf4\x06\x6c\x66\x7f\xae\x5f\xf7\x87\xcd\x7c\xdf\x1e\x11\x31\x76\xc5\x15\xef\x50\x66\x88\xda\x19\xb6\x1c\xbb\x61\xda\xc3\xce\x10\x95\x56\xcd\xae\x3d\xbb\xd6\xc5\x0e\x30\x9b\x61\x07\x08\x11\x11\x9b\x16\x5e\xbf\x7c\x1b\x41\x5a\x87\xf7\x29\x54\x84\xdd\x92\xb2\x30\x65\xb2\x5e\x1a\x50\x2b\x8f\xe3\xd7\xd8\xce\xf6\xcb\xc3\xf2\x8f\xcd\xfa\x65\xf9\xd2\xde\xab\x0a\x13\x44\x54\x36\xf1\x27\x28\xc3\xdc\x0e\xe8\xea\x7e\x56\x3a\xfb\x32\xea\xd5\xe0\x27\xdc\x77\xcc\xfd\xb2\xbc\x5d\x6a\x50\xbf\xc3\xed\xb1\x2c\xce\x23\x6a\x89\xf1\x89\x9a\x18\xae\x23\xa8\x31\xbb\xb1\xcc\xd5\x62\x02\xe5\x63\x47\xeb\x24\xc2\x57\x5c\xa2\xba\xe8\xa5\x68\xe7\x81\x16\xd4\xeb\x80\x6e\xf3\x12\x54\x5a\x37\x0e\xe3\xcb\xea\xf9\x71\x36\x6d\xf1\xb4\x08\x31\x61\x59\xd5\xc5\xe5\x80\x7a\xb1\xa3\xdf\x52\x86\xcf\x67\xdf\x38\x84\x9f\x91\x7e\x7c\x9d\xeb\xd1\x1a\x3c\xa3\x94\xd9\x98\x73\xdc\x49\x36\xa7\xae\xd6\xa7\x35\x48\xcc\x6c\xe9\xa2\x6c\xf6\xa5\x39\x9f\x10\xad\xed\x8c\x8f\x26\x84\x1b\x51\xe3\xc5\xf5\x7c\x59\xa4\xef\x76\x4e\x36\x7f\x57\x18\x7e\x65\xbc\xaa\xb1\x21\xaa\x3d\xa0\x0d\x7c\xb2\x4f\x64\xd7\x2b\xd5\xfe\xdd\x72\xc3\xd4\xbe\xa2\x89\x17\x1a\xda\xb2\x99\xf5\x37\xbe\xca\x0f\x6b\xe2\x45\x46\xaf\xe5\x1b\x14\xdf\xe0\x3c\xfc\x18\x9a\x78\x2a\xf1\x6c\xb3\xc4\x77\x50\xc7\xfb\x6b\x0d\x5e\x87\xef\xfe\xb9\x0e\x7b\xad\xfb\x7b\xa9\x26\x94\x30\xd6\x72\xfc\xcd\x8b\x34\x7f\x2a\x5c\x0f\xb5\x26\x94\x72\x19\xb4\x6d\x5d\x77\xa2\x5d\x6e\x54\x60\x64\xf3\x31\x0c\xfb\xc6\xdd\x36\x86\x07\x10\x9c\xb2\xb0\xca\x81\x69\x4b\xb8\xa9\x09\x0d\x39\xf6\xd0\x3d\x17\xd9\x80\x3b\xa0\x39\x22\x91\x4f\xf5\x39\xad\x4f\x65\x9a\x2d\xe0\x5c\xb8\x43\x3e\xf8\x84\x39\xaa\x74\x28\xab\xb6\x6e\x16\xff\x5d\xc4\xed\xc0\xa5\x6b\x2e\x18\x68\x9b\xab\x9b\x67\x29\xb4\x68\xe9\xf1\x9b\x0f\x18\xc1\x4d\x49\x8e\xe8\x82\x34\x09\xb4\xf6\x0d\xae\xc2\x30\x9e\xa2\x1a\xf5\x57\x62\x33\x9a\x84\xc4\xe7\xca\x55\xd4\xcb\xf4\x1d\x36\x28\x15\xba\xe8\x55\x74\xd1\xc8\x0c\x3f\x54\x98\x24\x81\x95\x14\xb3\x97\x7f\xfc\xa4\x6f\x4f\x93\x28\xf2\xb1\xc0\xb9\xe5\x2a\x2d\x3a\x2e\x13\x4d\xa2\x44\x62\xb9\xa7\x71\x96\xf3\xb4\xfd\xce\x91\x56\x08\xda\x3a\xf1\xaa\xed\xf9\xf8\x6d\x78\x49\x96\xb4\x94\x47\x8d\x01\x4d\xf3\xa3\xed\xf4\xb2\xc7\xe3\xc8\x43\x16\x90\x4b\x09\x3b\x34\x97\xcd\x23\xb4\xae\x5b\xfc\x1f\xf1\x9a\xc4\xee\x9a\xa0\xb1\xe3\xe1\xcc\xf3\x2b\xcf\x7a\xbc\x19\x9a\x24\x34\x40\x52\x96\xf2\x9a\xef\x90\x32\xab\x8f\x6f\x1f\xf5\xd0\x68\x92\x44\x86\x1a\x23\xad\x0c\xce\x1c\x83\xcc\x51\xdb\x49\x33\x4a\x33\x43\x38\x60\xd2\x83\xae\x33\x79\xfa\x1d\x73\x2f\x34\x77\x00\xc6\x0d\xc5\x60\xba\x25\x91\x76\x83\x58\xa0\x9a\x4b\x1e\xe2\xc3\xa5\xc8\xae\xf2\xc4\x1b\x0b\x5e\x9d\xb8\x7b\x0e\x2e\x4d\x22\xb4\x99\x80\x9b\xd1\xfd\x88\xd0\xc3\x5c\x9f\xb8\xde\xc6\x6d\xb1\x9a\x48\x65\x5c\xc4\xf3\xc1\x90\xae\xb8\x0b\x4a\xcd\x31\xb2\x58\xbc\xec\xb6\x06\x8d\x51\xba\x43\x8a\x70\xdf\xf6\x84\xca\xea\x91\x97\xe7\xee\x90\x0e\x0c\xc7\xd6\x7a\xb3\x34\x1c\x5d\xbb\x61\xcb\xae\x26\x5a\x4a\x2e\x1c\x17\xd5\x1b\xe4\x7d\xb6\x74\x37\x44\x49\xd4\x99\xde\xf3\xea\x6d\x78\xc8\x23\xc4\x47\x43\x72\x4e\xf3\x65\x55\x03\x9c\xfb\xd4\x5c\xda\x23\x49\x6c\x00\x8e\xe7\x4b\xd6\xd2\xb1\x3d\xef\x9e\xbf\x8c\xbb\xb5\x47\x94\xc7\x6d\x1d\xdf\x35\xc2\x7f\xa6\xb4\xe7\xce\xd0\x4a\xa8\x3e\x7d\x9d\xbb\x03\x8f\x79\x09\x19\xd4\x37\xf6\x50\x96\x7d\x59\xac\xe1\x4f\x7b\x3c\x0e\x4d\xa2\xcf\x56\x1d\x66\x13\x9c\xa4\xda\xa3\x7e\x84\xac\x3f\xcb\xfd\x77\x43\x5f\xe0\xba\x75\xfb\x56\xdf\xf3\x45\x62\xc4\x8f\x54\x5a\xb7\x6d\xd0\xdf\x8b\xeb\xd0\xcb\xd3\x9e\x0f\x04\xa1\x64\xcb\xfa\xf4\xc3\x94\x74\x37\xd9\xf5\xd8\xae\x6e\xcf\x07\x81\x5c\xc7\x26\x87\x72\xe2\x69\xfe\xdf\x77\x7e\xdc\xe0\x87\x03\xca\x30\x57\x9b\xca\x62\xcc\xc4\xaf\xbd\x80\x69\xac\x0c\xf4\xb9\x18\xbb\x35\xf3\x45\x43\x83\xf6\x02\x25\x23\xea\x0a\x14\x08\x73\x1c\x1a\x33\x2f\xa4\x11\x33\x0a\xf0\xbf\x0e\xfa\x8a\xee\xea\xb7\xc2\x25\xff\xb5\x17\xc6\x01\xd3\x16\x02\x5a\xa2\x1b\xfe\x15\xb5\xa3\xf6\xc2\xc4\x72\xe7\x63\x9e\xa5\x3c\xd4\xbd\xfd\xc4\x8b\xb8\x69\x35\xd9\x6c\x57\xf3\xe5\xe1\x79\xf5\xe2\x0e\x30\x1e\x22\x0e\x2c\xcb\x0f\x3a\xfd\x05\xca\x3f\x64\xf9\x5d\x0b\x8a\x1d\x1b\x7b\xbe\x91\x4e\x46\x63\xd3\xf8\x20\x1d\x7b\xb4\xf6\x62\xdf\x48\x9d\xaf\xbe\x3f\x4e\x5b\x0b\x2f\x56\x3e\x76\xbf\x61\x2f\x9a\x32\x37\x78\x48\xab\x43\x05\xd0\x02\xd7\xb5\xc7\x43\xc1\xba\x66\x28\x9c\x0a\x43\x5c\x93\x1b\xc7\x62\x84\xe9\x98\x56\xce\x9f\x20\xaa\x74\x24\x8c\xa5\x3d\xce\x3d\x1d\x76\x4d\x21\xf7\xcd\xb3\xd3\xaf\x92\x43\xa8\x4c\x4d\x1d\xc1\xc6\xe7\xe2\x1d\x2c\xab\xe5\x68\x32\xca\xd8\xc8\xde\x1e\x5c\x17\xe1\x54\xe5\x5a\x7b\x92\x13\x69\xf7\x85\x54\x16\x7d\xcc\xbf\xf6\x24\x48\xc4\x32\x5d\xf3\x12\xb8\xb2\x24\x9e\xd3\x29\x07\xed\x29\x41\x44\xe7\xa5\xbd\xc0\xc7\x43\x57\xf8\x19\x8e\x84\x30\x90\xbe\xcd\xb3\x3f\xdb\x66\x83\x5e\xc1\x3c\x1e\x0f\x8f\x02\xf4\x8a\x9f\x67\x2f\xdf\x67\xfb\xfd\xec\x65\xb3\x5d\xff\xf1\xe7\x9f\xeb\xed\xef\xb3\x1f\x4b\x77\xab\xc0\xfc\x58\xb6\x5f\x66\xb5\x5b\xbd\x0c\x97\xb0\x16\x2c\x32\x89\x2c\x9e\x81\xc2\x3e\x66\x73\x84\x12\x22\x91\xb3\xa7\x65\xb6\xce\xa6\xd4\x1a\x06\xb7\x44\x49\xa0\xa9\xeb\x97\x36\xa8\xfe\x29\xfe\xea\xfe\x5e\x49\x3d\x9f\x60\xf1\xdf\xd0\x5f\xad\xf5\x7c\x3b\xf2\x61\x28\xa5\xbe\xec\x08\xb1\xa1\x84\xc9\x46\x3b\x4d\x29\x8b\xf1\xc3\xbe\xee\x16\xbd\xaa\xae\xa6\x34\xf1\x71\x07\xf8\x92\xc3\xb7\xf5\x40\xdb\x3d\x90\xd2\x24\xc1\xec\x68\x33\x95\x46\x49\xa5\xe9\xa7\xa7\x2a\xe2\x96\xfe\xb3\x15\xd8\xd0\x34\xd0\x46\x79\x21\x2f\xea\x54\xdf\x36\x59\xe3\x00\xbf\x14\xf5\x86\xdf\x60\x98\x5e\xd2\x34\xf4\x7d\xfc\xa2\x36\xdd\xfd\xad\xc8\xfa\xd4\x41\x9a\x86\x09\x41\x15\xf7\xdd\x7e\xf6\x6d\x79\x58\xbf\x2c\x8d\xa2\xd5\xf2\x65\xd1\x8d\x08\x70\x67\x39\xa3\x30\x1f\xe6\x71\xee\x3b\x48\x34\x8d\x02\x86\xa9\x69\x71\xbd\x79\xa4\xc6\x0c\x54\x7b\xbf\x51\x20\x68\x9f\x2f\xfe\x5e\xad\x4a\xd3\x48\x85\x38\x6b\x0c\x58\xbe\xa8\x6b\x70\xda\xc2\x9a\xc6\x3c\xc6\x4c\xba\xc1\x36\xbc\x14\xf5\xee\xd2\xf3\xca\xc6\x24\x58\x83\x45\x47\x63\x00\x92\xb4\xa8\x9e\x66\x71\x4e\x58\x7f\x9a\x90\xd8\x12\x0a\xf4\xf9\xc1\xef\x3c\xb2\xc1\xab\x4d\x64\x8c\x41\x14\x38\xe8\x77\x0b\xcd\xd5\x54\x78\x14\xf3\x7e\xb6\x3c\xf0\xc0\xf3\x91\x1b\x40\x35\x49\x90\x3d\x76\x9e\xd6\xa3\x1d\x81\x6a\xc6\x9d\xf4\xd0\xcf\x34\x7f\xe9\x35\xe9\x6b\xaa\x25\xc1\x0a\xce\xa5\x2c\x7e\xdd\xac\x57\x36\x9e\xb5\x1a\x84\xc9\x07\x98\x28\x7d\x96\xab\x5d\x2f\x5a\x1d\xce\x30\x9f\x30\xc3\xf9\x81\xbb\x45\x76\x6b\x33\x6f\xda\x27\xe0\x21\x21\xf3\xc6\xb0\x11\x74\xfc\xb7\x9f\x44\x7b\xf6\x34\x2f\x32\x20\xf9\x57\xf3\xe8\xdb\xf4\x38\x65\x6a\x7c\x4a\x12\xdc\xf6\xde\xa1\xcc\xf9\xb9\xe3\x43\x74\x87\xa9\xc6\xc6\x8c\x59\x5d\xf2\xf6\x6f\x11\xc7\xdc\x37\xb2\x9f\xee\xea\xa2\xe4\x47\x40\x10\xd6\x6f\x5d\xb7\xe1\xf0\x5e\x28\x37\x88\x86\x73\x9a\xd3\x30\xfa\xb2\xc1\x46\xfb\x54\x50\x2e\x6d\xce\x72\xb7\xd9\xc9\x14\xf2\xe9\x06\xdc\x66\x68\x20\x4d\x95\x29\xcd\x57\xf3\xb5\x81\x7b\xfe\x04\x78\x1b\x88\xc9\x68\xdf\x0f\x43\xec\x53\x4d\xab\x87\x12\x90\x08\x67\xce\x2f\x9f\x7c\x08\x3f\x8c\x2d\xf9\x94\xec\x31\x54\x6b\xdf\x4f\x42\x74\x4c\x0e\xb8\x5f\x62\x60\xb9\x80\x6c\x22\xeb\xf8\x57\xe1\xc4\xc0\x54\xde\x35\x6c\x8e\x6e\x86\x03\x42\x0e\xbe\x37\x0e\xcb\x23\x80\x69\x6c\x1b\xda\x16\x3f\xf0\x62\xa4\x6f\x31\x5e\x77\x0d\xab\xf9\x7a\x3c\x82\x33\xa4\x9f\xaa\x78\x2e\xeb\x2b\x6f\x57\xb4\x1f\x4a\x83\xba\xdd\x2d\xe7\xeb\x97\xc5\xee\xb0\x7e\x3c\x2c\x66\x7f\xba\xa3\x11\x35\x0c\x06\x19\x16\x76\x77\x17\xc3\x97\xe2\x0e\x06\x44\x33\x67\xbb\x79\xf6\x5a\x0d\xb8\x6d\xb5\x1f\x49\x30\x0e\x74\xde\x18\x8b\x83\x02\x7e\xcf\xf6\x79\xed\x38\xd6\x3c\x1a\xf7\x73\xa2\xda\x67\x44\xe0\x86\x33\xbb\x36\x16\x82\x23\xf7\x97\xbb\x36\xf3\x4d\xb2\x7e\x73\xcd\x32\x9b\xa6\x1a\xf3\x88\x0c\x5f\x00\x0b\xb8\x25\x9b\xae\x1f\x0a\xa7\xc2\xad\x7d\xa6\x03\x5c\xfc\x56\xe0\x68\x5c\x3b\xd4\x7e\x0c\x81\x67\x9d\x42\xcc\x72\xb5\xb3\x21\xa1\x66\x51\xc2\xaf\x1a\x35\x0f\xdd\xdf\x39\x0b\x31\x55\x6b\x5a\x84\x6c\xef\xcb\xe8\xa2\x5c\xf9\x81\x6b\x7a\x59\xbf\xb8\xfd\xdc\x17\x34\xf6\x8c\xac\x7d\x33\x8b\xd1\x57\xfe\xfe\xf2\x41\xdb\xc3\x81\x61\xea\x6d\xf6\xea\x7b\x96\x2f\x37\x28\x22\x58\x0f\x32\x5f\x0c\xd1\x1f\xab\xf6\xde\x44\xa4\x10\x4f\xda\xea\xfd\xee\x97\xb3\xe7\xc3\x6e\xb5\xe8\x6e\x21\x36\xa8\x73\x24\x09\x2a\x79\xcb\xe0\x3d\xb0\x8b\xbe\x48\x18\x52\x9c\x2d\xc0\x55\xac\xd4\x24\xde\x54\xfb\x42\x24\xe8\x34\x5f\xf3\x0a\xea\x1f\xe9\xe5\x93\xc2\xb5\x1b\x0d\x1e\xea\x3e\x67\xa9\xae\x0f\x82\xb7\x5f\x5b\x40\x64\xd0\x12\x4f\xcb\x3f\xf6\xdb\xf5\x7c\xdd\xfa\xcb\xbe\xd0\x11\x96\x2a\xbf\x3d\xcf\xdd\x9f\x64\x6c\x36\xb0\x12\x89\xbc\x7f\xf2\xb2\x4c\x5b\xaa\x0b\xed\xab\x98\x20\x80\xe8\xbd\x71\x23\x8c\x9e\x29\xa8\xab\x34\xd4\x58\xa3\xbb\xd7\x91\xb1\x04\x73\x28\x0d\xfa\x7b\x6c\x7e\x34\x04\x96\x37\x49\x61\x33\x80\xcd\xd3\x98\xa3\x81\x17\x68\x4c\xea\x57\x3c\x03\xcf\x89\xa4\xd9\x63\xd4\x0b\x9d\x1c\xd4\xb2\x3e\xdd\x15\xc9\x74\x40\x63\x86\x18\x8f\x0f\x9e\xd7\xd5\xbe\x78\x4c\x8f\xa7\xe9\x4c\xac\x0e\x68\xe2\x3b\xce\xba\xc6\xe6\xb9\x06\xd4\xf6\xa7\x64\x82\x65\xd2\x1e\x09\xc4\x38\x97\x14\xf8\xd4\xf7\x2d\x7a\x7e\x96\xbb\xaf\x8e\xeb\xe1\x2b\x59\x39\x1d\x04\x32\x50\xa6\xcb\x5b\xa6\x97\x14\xf2\xfa\xc7\x6a\xe3\x7e\x37\xf2\x62\x15\xbb\xb5\x65\xe9\x69\xc6\x14\x08\x3a\x88\x62\x8a\xb9\xc8\xf9\xfa\x65\xbf\x5d\x3d\xd8\x06\xcd\x81\x56\x90\x0e\x58\x08\xac\x4f\x76\xf3\xa5\xf8\xab\x0e\x58\x24\x11\x86\x53\x5c\xfa\x8a\x97\x3a\x60\x89\x0e\x7b\x98\x36\xc8\xb2\x34\x3f\xde\xe3\x00\x9c\x86\x9d\x0e\x98\x30\x52\xff\x48\xbe\x58\x41\xdd\xc4\x15\x87\x4d\x91\xa5\xf2\xd6\x5e\x13\x28\xe2\x0f\x90\xa2\x7e\xd0\x4a\xa5\x83\xd8\xa3\x40\xed\xe9\x8f\x3c\xcd\x3a\xfc\xe3\x2a\xaf\xae\x5a\xa7\xcd\xd6\x86\xd9\xee\xaa\x7d\x22\x77\x6a\x10\x86\xd0\x12\x8c\xa7\xf9\x33\xff\xd5\x63\x39\x1f\x7e\xff\x38\x36\xd5\xf8\x23\xd4\x88\x88\x6d\x42\x76\x27\x7e\xaf\x83\x24\x20\x68\xe1\x1d\x41\xa0\x69\x33\xf9\x1d\xa6\x5b\xc6\x75\x90\x70\x1f\x85\x7e\x8a\x0b\xe4\xf3\x13\x38\x66\x55\x1d\x70\x2a\x11\xe1\xd7\x91\xc4\x98\xa2\x6c\x3b\xdf\x85\xef\x61\x04\xf8\xc0\xab\xba\xc8\xa1\x3d\x51\x28\x8e\x2c\x1e\xb9\x65\x3e\x33\x14\xfd\xdd\x69\x40\x11\xb2\xb3\x7c\xfe\xc7\xcc\x2d\xe2\x40\x46\x41\x60\x52\x98\xef\xe9\x3d\x12\xd9\x0d\xe2\x3e\x62\xad\xf7\xd8\x11\xd6\x9e\x0a\x21\x32\xc9\x58\x66\xe6\xa1\xed\x0a\x54\x60\xd4\xf8\xb8\xb2\xfc\x0e\xd5\xd8\x86\x06\x2a\xd2\x98\xfa\xd8\x9d\xd2\xa9\x3d\x21\x50\xb1\xd1\xad\x3b\x1f\xaa\x8e\x0b\x4b\x07\x4a\x44\x58\x76\x38\xf1\x6a\x0b\x17\xe0\x36\xb2\xfb\x9f\xa0\xbd\xae\x8a\x12\x27\xea\xb3\x6b\x19\x5e\xcc\x8e\x3e\xe8\x3c\xd7\x81\xd2\x80\x11\xef\x37\xa8\x0d\x09\x60\xcf\x99\x09\x40\xc4\x86\x43\xa6\x99\x95\x06\xc6\x6e\xca\x35\x56\x02\xb6\x1d\x66\x60\xa6\x2d\x4a\xec\x50\x0e\x54\xa4\xa6\x23\x9d\x00\xb4\x42\x1f\x7f\xb3\xde\xff\xc3\x5d\x4a\x53\x40\xdf\xd4\x70\x80\xc2\xf9\xd2\x5c\x6e\xaa\x9d\x7f\xda\x15\x0d\x09\x51\x3a\x74\xb8\xec\x79\x81\x29\x11\x97\x56\xfa\x6d\x34\xd4\x67\x58\x59\x79\x2a\x8e\x48\x73\x5a\x7f\xc6\x6c\xd1\x8e\x07\xac\xea\x35\x6b\x23\xcd\x8f\x1d\xc5\xf2\xf0\xb1\x42\x8f\x42\x64\x0d\xee\xee\xa8\xf6\xc5\xa4\xd5\x0d\x3d\x45\x3c\xdd\xc3\x23\x36\x7b\xad\xf5\xfb\x87\x3f\x4b\xbd\x08\xb3\x2b\x17\x7e\x5b\x5c\x7b\x34\xe6\xa3\xae\xbc\x7e\x6c\x13\xfa\xdc\x34\xc6\x3d\xa4\xf5\xa5\x93\xe4\xd6\xa1\xaf\x38\xd6\xc7\x05\x2a\x67\x18\x7b\xd0\x1d\xd3\x58\x73\x44\x77\x13\x6b\x67\x4f\xeb\x3d\x52\x36\xbb\x11\x01\xd1\x96\xd0\xb9\x9e\xf3\xf3\x85\xa7\xc7\xd1\x7c\x0d\x03\x08\x4c\x75\x97\xe7\xea\x76\x69\x6d\x4c\x18\x40\xec\xc0\x97\xcf\x86\x9b\x70\xf0\xd3\xcc\x8f\xa4\xc5\x38\x3d\x96\x00\x8f\x3c\x93\xad\xd9\x0e\x63\xdf\xf4\xe6\x62\x9e\xd9\x72\x27\x4c\xb0\xa8\x7f\x59\x7c\xd4\x61\x1c\x08\xdc\x22\x7e\xa4\xf0\x71\x40\xf0\x7f\xd6\xec\x3b\x5d\xa1\xeb\x70\xd7\x85\xa4\xc3\x38\x0a\x93\x56\xee\xc3\x98\x20\xcc\x21\xa9\x1e\xab\xad\x1d\x9a\xf0\x50\x5a\x0d\x86\x87\xab\x10\x19\x0c\x62\xb8\x50\xd0\xb8\x03\xa2\xbc\xe6\x55\xdb\x0d\xa5\x43\x29\x39\x82\xb8\x5c\x81\x1b\x3b\x93\x50\xeb\xc0\x8d\x50\x91\x87\x01\x20\xfc\x02\xd9\x27\xe4\x1d\xde\x81\x8a\x02\x2c\x17\x3c\xee\x5e\x66\xbb\x61\xa4\x1d\x2a\x66\x64\x45\xf7\xeb\xfd\xec\xc9\x48\x70\x75\x0c\x6c\x3a\x54\x3c\xf6\x93\x96\x88\x70\x32\x65\xda\xcf\xb6\x84\x8a\x27\x91\xd7\xcb\x85\x2c\xf3\x3a\xad\x6f\x98\x22\x68\xdc\xe4\xd1\x8d\x01\xf3\x11\x35\xad\x78\x9f\xd3\x4d\x87\x20\x02\x04\x05\x5f\x70\x9b\x68\xe3\x55\xcf\xbd\x7d\x4d\x09\x76\x02\xae\x5e\x56\xfb\xd5\xec\xc9\x9d\xa6\x99\xe0\x08\xff\x30\x1d\x27\x7f\xbe\x6e\x56\xcb\x4f\x56\xa2\x8e\x35\x56\xb0\x0d\x21\x5c\x56\xf0\x36\xc4\x0a\x75\x12\xe0\x4d\x75\x70\x7e\x4b\x34\x31\x4a\x72\x44\x84\x30\x74\xad\xd0\xab\x32\x24\x4d\x3d\x6d\x5c\x1d\x91\x84\x21\x9c\xe5\xb1\xe4\x67\xf8\x28\xca\x41\x35\x2f\xa2\x61\x88\x36\xa3\x2c\xb2\x26\xae\x9c\xe2\x65\xd0\x11\x95\x02\x0b\xe3\x28\xcd\x81\xf8\x68\xd0\x0f\x13\x9d\x98\x3a\xa2\xc0\xb0\xa5\xdc\xb8\x15\xdf\x78\x0d\x1f\xc6\x73\xfe\xcd\x42\x3d\x26\xaf\xef\x2b\x43\xd8\x99\x81\xae\xa3\x68\x38\xc7\xa3\x80\x1a\x0e\x89\x0a\x72\x65\x16\xe5\xe4\xbb\x8c\x82\x98\x06\x56\xd4\x6b\x59\xca\x88\xb1\xfb\xce\x4a\x1d\x05\x52\x1a\xeb\xdb\xf8\x12\x3f\x8c\x9d\x6c\x51\xaf\xa3\xb1\x21\x05\x84\x6f\x99\x8c\xe6\x10\x3d\xfe\xe5\x5a\x8e\xc2\xc0\x43\x3b\xb4\x83\xfa\xa9\x18\xb9\x28\x51\x14\x10\x69\x94\x06\xea\x53\x9a\x65\x83\x42\x4f\x14\x29\xea\x0b\xa7\x7c\xf3\x0d\xea\x9f\x45\x99\xa9\x8e\xf6\x49\x47\x2c\xf6\x94\x73\x70\x6c\x07\x7c\x0f\xbc\xa4\xa3\x58\x45\xbe\x89\x7f\x25\x5c\x6a\xd3\x44\xd4\x03\x2f\xbb\x51\x5a\x6b\xd5\xb2\xae\x37\xd6\xea\x8e\xdd\x59\x47\x89\x17\x3a\x52\xbf\xe7\x9b\x49\x27\x0c\xa2\xda\x28\x89\xb5\x03\xcd\x3f\xa7\x79\x63\x34\x4d\xaf\xe5\xe8\x3a\x9c\x2b\xa4\x4f\xda\xe5\xc5\xfb\x68\x6e\x0a\x9f\x62\xa9\x75\xf3\xe3\x8f\xc1\xac\x14\x51\x82\x6e\x9c\xfd\x42\xe3\xde\xad\xff\xa4\x58\x79\xff\x75\x84\x12\x46\xad\xdc\xd0\xba\x36\xf3\xd9\xad\xba\x48\x12\x1a\x98\x7a\x5f\x0e\x25\xaf\x61\x77\x2a\xca\xfa\x29\xcd\xdf\xba\x01\x26\xf2\x2c\xf2\xec\xb6\xe1\xb7\xc7\xa2\x7c\xbc\xba\x76\x16\x1d\x49\x46\x9d\x66\xf1\xec\x52\x28\x28\xb9\x2a\x90\x88\xe3\xf6\xf5\xd6\x1d\x49\x95\x68\x23\x9f\xba\xcc\x4c\xae\x65\x03\x65\x5a\xa8\x71\x67\xbf\x1d\xae\xfc\x28\x09\xda\xc6\x3d\x53\xdb\x9c\x7e\x58\xe0\x12\x63\x73\x2c\x84\x0d\xf1\xb5\x3a\xd2\x31\x8d\xa1\xbd\xcc\x2c\xcb\xf6\xc5\xb5\xcc\x79\xe3\x57\xcf\x91\xff\x58\xf5\x5e\x8d\x4e\x84\x53\xf4\x7e\xe2\xb9\xba\xdf\x8d\x22\xad\x7d\x61\x93\x55\xf6\xc3\x0d\x57\x14\x23\x3e\x41\xb0\x7c\xeb\x86\xcd\xaf\xe3\xba\x05\x23\x01\x1f\x08\x97\x7d\xde\xa1\xa0\x19\xe1\x14\x29\x6d\x14\x70\x95\xa5\x39\xec\x4f\x2d\xfc\x5d\x33\xd2\x49\x37\x58\x65\xd4\xf9\x29\xcd\xd4\x6b\x9e\xbe\x43\x0b\x51\xd6\xcc\x0b\x03\x19\x3b\x16\xd6\x5d\x5d\x5c\x1e\x4d\xbd\xab\x3d\xae\x03\xc4\x34\x18\xfd\x85\x89\x96\x10\xcd\xa8\x56\x74\xe0\x5d\x9a\x52\xf8\xe4\x07\x61\x81\xc7\x02\xd5\x83\x66\xae\x46\x1b\x35\x0b\x3c\xa9\xb5\x23\x15\xb9\x56\x60\xda\x60\xdc\x41\x9a\x60\x92\xdf\xe0\xb7\x17\xd0\xea\x51\x3d\x63\x0d\xfe\xce\x9f\xed\x9b\x59\x16\x24\x21\xbe\x91\x6b\x6e\xa5\x32\xd4\x9c\x5f\xaa\xf6\xd2\x8a\x6b\xeb\x02\x7d\x1b\x29\x1b\x68\x16\x52\x8d\x19\x6b\xc1\xe5\x1b\x36\xae\xf4\x41\x79\x9a\x85\x82\x10\xd9\x4e\x24\xe4\x75\x18\x3d\x55\x28\x8d\x5e\xfc\x82\x5b\x61\x15\x77\x6a\x14\x99\x5a\x4a\x89\x59\xee\xfd\x76\xe6\x0e\x30\x12\x62\x65\x4a\x80\x2c\xce\xb0\x4d\x25\x06\x60\x83\x07\x62\x09\x8d\x44\xe7\xa2\x8e\x7e\x32\x0e\x64\xd8\x3a\x47\xc6\x72\xad\xf3\xd5\x7c\xed\x7e\x20\x06\xc0\x9e\x80\x92\x5f\x86\x1e\x2d\x4b\x28\xd1\x6a\xd0\x38\x8a\x7a\xc6\xce\x7c\xb2\xc4\x27\x9e\xcd\x32\xb8\xa3\x68\x3f\x47\x57\x89\x8c\x6a\xf4\x3f\x66\xf3\xdf\xbf\x0a\x10\xdc\xf0\x44\x1a\x31\x27\x53\x22\x1a\x84\xcf\x4c\x84\x3c\xb4\x0e\xe8\x62\xa9\xd2\xba\x28\x2d\x6f\x5f\x79\xbb\xa7\xbc\xb3\xe7\xa8\x84\x4b\x8b\x86\xbd\x5e\xac\x1b\x31\x08\xad\x98\x0e\x22\x7c\x0e\x23\x03\x52\x7a\xed\xdf\x65\x82\x89\x88\x1a\xf8\x79\xb2\x26\x69\xc6\xc5\x24\x22\x98\x13\x7d\x81\x8f\x75\x99\x01\xcf\x7b\xc2\x3c\x3a\x26\xca\xf0\x35\x16\x42\x5f\x2b\xd9\x18\xf0\xef\xbc\x3a\x35\xb7\x6b\x6a\x6c\x13\x35\x8f\xd8\x63\x4c\x23\xb8\x08\xf2\x9a\x67\x27\x6c\x7c\xef\x4f\x97\xd8\xe3\x0a\x4d\xc8\x16\xaa\x34\x4b\xdb\xe2\x46\xec\x09\xa5\x5a\x70\x6f\x0f\x7a\xd7\x15\xba\x62\x1a\x71\x8c\x53\x9a\x58\x71\x55\x2d\xcf\x97\xda\x5a\x65\x77\x1c\x08\xe6\x97\xd3\xfe\xab\xda\x40\x89\x66\x63\xb8\x1e\x62\x3f\xe6\x68\x39\xf7\xcb\xdd\x7e\xbe\x5e\xbd\xb8\x57\x17\x07\x71\xc2\x75\xeb\xfc\x7d\x7b\xde\x7f\xf2\xea\x02\x10\x91\xb5\x95\x1b\x5e\x97\x45\x3e\x94\x35\xb6\xa3\x42\x3f\x89\x02\x27\x97\x9d\x4a\x98\x17\xd0\x29\x80\xbb\x31\x81\x41\x9a\xcc\x8b\xb6\xcb\xd7\x1d\x91\x0c\x49\x7c\x7e\xce\x56\xfb\xd5\xcb\xb7\x01\xe1\x97\x8e\x43\x88\xa8\xb4\x7a\xa6\x26\xfa\x1c\x7c\x89\xc8\x97\x08\x39\x35\x59\x87\x55\x0d\xe5\xc1\x9d\xc9\x28\x71\x8a\x42\x3b\xb3\x59\x3d\x16\x25\x3a\x11\xc5\x58\xe6\x70\x32\x06\x8e\x59\xc0\x85\x75\xd5\x8e\xbc\x7a\xad\xc6\x15\xc2\x98\x29\xa5\xec\x02\x33\x19\x12\x6c\xba\xfc\x1d\x6e\xed\x07\x88\x29\xc1\xc5\xf5\xfb\xcb\x7c\xc0\xd5\xa7\xe3\xc4\x37\xcb\xfa\x09\xa0\x2c\x6e\xc8\x3c\x7b\x3d\x0f\xe6\x90\x08\x02\x41\x1c\xd5\xe8\xaf\x09\xf9\x6b\x1d\x0b\x16\xa2\x63\x6e\x31\x87\x13\x70\xc3\xe9\x2a\xfd\xb4\xcb\x11\x4b\xdf\x7c\x23\xb4\xad\x99\xb2\xcd\x5d\x6b\x3d\x59\xc9\x89\xa5\x6f\xf8\x75\x9d\x8e\xfb\xc4\x4f\xc4\xc3\x65\x23\x7d\x40\x82\x9a\x1d\x2f\xf9\x2c\x57\xcf\xfc\x6a\x45\x9c\xdc\x23\xcb\x24\xc4\xec\xdd\x0d\x78\xf9\x38\x12\x11\xd7\xb1\xb2\xbd\x97\x2e\xc2\xdb\xcc\xfe\xd8\x6f\xc7\x63\x92\x24\xb6\x88\xdf\x4f\x92\xaf\xb1\x92\x3c\x36\x22\x52\xf5\xbc\xb8\x1f\x35\x1a\x0d\x84\x13\xbb\xf1\x96\x3d\x2d\x04\x1d\x83\xa7\x5b\xb2\xe7\xf5\x3b\x94\x3a\x2b\x3e\x9a\xe5\x5e\xd5\x3c\xaf\x1f\x4b\xde\x53\x2a\xd6\x31\x80\x91\x16\x44\x51\xab\x43\x34\xd0\x6f\xd5\xb1\xf6\x94\x49\x4f\x15\xf2\xed\x80\xd1\x8b\xe9\xcb\xdb\xf0\x9b\xe2\x77\xe2\xd5\xee\x24\x41\x31\xc3\x33\xdf\xae\x7f\x2e\x5c\xd3\xed\xe1\xdb\xba\x8d\xf0\x62\x2d\x8d\xb0\xdd\x43\x6a\x1a\xf9\x7b\x56\x2f\x21\x09\x51\x76\x6e\x7f\xa4\x79\x9f\x8f\xc7\x6d\x0c\x09\x11\x40\x6c\x03\x06\x82\x8b\x87\x13\x38\xf1\x88\x34\xfc\x4e\x4d\x8c\xe2\x10\x49\xe8\xc2\x0f\xa7\x6a\xcf\xb6\x25\x1e\x0d\xb1\x26\x7f\xb9\x65\x45\x8e\x48\x6c\xd5\x5e\x8e\x19\xa7\x2b\xad\x26\x60\x42\x6e\x4c\x62\x4c\xdf\x53\x71\x7c\xcd\xd1\xeb\x18\xee\x65\x89\x27\x01\x33\xa1\xf6\x76\x7e\x16\xe5\xdb\x64\x3b\xed\x60\x59\xb4\xc9\xe3\x84\x12\xd3\xe3\x87\x82\x2e\xd5\xa3\x41\x0a\x8f\xee\x81\xfa\x9c\x49\xbc\x07\xf9\xb6\x9b\xed\x0b\x97\xf1\x4e\x68\x18\xfa\x61\xab\x46\x31\x93\x72\xac\xfd\xd9\xfe\x8a\xf6\xd0\x26\x9c\x4d\x45\xe8\x36\xfa\x01\x3f\xf2\xd1\x66\xa7\xd5\xae\xc8\xde\xfb\xc5\xfa\xc1\xc4\x4c\x02\x8f\x26\x26\x7a\xcb\xf4\xa2\x2c\x2e\x5f\x74\xda\xe8\x24\x60\x0c\x5f\xcc\x03\x6f\x69\x4b\x5b\xa0\x4d\xf7\x79\x02\xa6\x0c\x41\x11\x9c\xd3\xda\x64\x9d\xe7\xfc\xc2\x45\x9a\xa5\x75\x13\x1e\xf7\xe9\x39\x3b\x7e\x05\x9d\x04\x40\x23\x0b\x31\x6c\x3c\x2f\xdc\x03\xd6\xa3\x0d\x20\x09\x20\x74\xba\x00\x3f\x8a\xfa\x9e\xa5\xd7\x0e\x0b\x03\x2f\xea\x24\xb1\x36\x25\xfc\x83\xcb\xb7\x4b\x51\x3f\xa4\xea\x9e\x70\x41\x27\xa1\x52\x44\x38\xe4\xfd\x62\xf6\xe7\x81\xba\x3d\x2e\x89\x08\xb3\xd2\x4e\xd7\xbc\xfe\x13\x78\x1b\x23\x24\x51\x10\x61\x74\x64\x9b\xaf\x9e\xd3\xcf\x65\x48\xdd\x19\x89\xa4\xd6\xd2\xbf\x14\xf9\xe3\x35\x3f\xa6\x22\x43\x2e\xa9\xfd\xed\x32\x8a\x48\x93\x48\x53\xa4\xf2\x7a\x86\x53\xc9\x7b\xc4\x3a\x3a\x61\x2c\xf0\x2c\xff\x09\xf6\xed\x4e\x39\x17\x49\x62\x79\xd3\xcb\x22\xcb\x1e\x8b\xeb\x30\x9a\x8f\xef\xff\xd3\x9e\xc6\x09\x35\xd4\x6e\x27\x68\x26\xd6\x99\xd7\x70\xb9\x95\xfc\x9c\xb6\x4b\x8c\x87\xc0\x45\xb7\x5b\xfc\xfa\x3a\xad\x9c\x08\x22\x1c\x9b\x92\x83\xc0\x18\x95\xa3\x31\xea\x22\x11\x81\xd1\xaf\xb3\x0a\x4e\xbc\xaa\x33\x98\xd4\xe5\xfb\xd2\xd4\x26\x82\x27\x48\x5f\xeb\xb2\xde\xc3\x75\x21\x7d\x89\x39\xd7\xc6\xff\x1e\x28\x78\xea\x44\x46\x1e\xc6\x99\x1b\xda\xae\x46\xa9\x0c\x26\xf1\x9c\x96\xb5\xc3\xad\x75\xc7\xa4\x54\x6e\x63\x2d\xdf\x9a\xff\x7c\xfb\xac\x32\x95\x28\x1a\xe2\x5b\x98\xaf\x5f\x1e\x9f\x56\xf3\xfd\x61\xf9\xb2\x38\x3c\xae\xda\x1a\x70\xa2\x98\x8f\x96\xf4\xe1\x7a\xdb\x16\xf2\x0d\x6a\xeb\x65\xfc\xa5\xb4\x86\x4e\x74\x68\x5a\x16\x0c\x74\xa6\x5a\x98\x2e\x95\xf6\x7b\x69\x91\xc4\x7c\x48\x0e\x34\xb2\xc1\x5a\x28\x26\x7b\x79\x80\x79\xc9\xc5\x77\xe0\x8e\xa1\x5e\x27\x5a\xa9\xc8\x48\x0e\x5c\xab\xee\x8f\xda\xe8\x3f\x7d\x83\x7a\x71\xcb\xf9\xb9\x59\xe5\x25\x42\x70\xae\x5d\xa3\x53\xfb\x59\x38\x21\x1a\x43\x4b\xee\x30\xdd\x06\x99\x3d\xab\x07\x18\x34\x37\xd8\x93\xb1\x93\x1a\x1d\x36\x3b\xf5\x11\x03\xcd\xbf\x23\x40\xc1\xe4\x1c\xe4\x84\x29\xf4\x92\x8a\x92\xcb\x26\x0c\x3d\xfc\xeb\x0a\xe5\x6d\xec\x6a\xe0\x6c\xfc\x9f\xf0\x7f\xdd\x49\x42\xfb\x89\x53\x20\xc9\xdf\xec\x33\x0e\x17\x29\xf7\x42\x1f\x53\xb9\xaf\xfd\x42\xf0\x7d\x47\x48\xef\x09\xda\x13\x8d\xc7\x89\xce\x2e\xac\x64\x31\x6a\xa3\xb1\xc3\xa8\x0f\x08\x89\xd9\x9d\x8a\xeb\x4f\x9e\x1f\xff\x48\xf3\xe3\x6c\xf5\x6d\xfd\xd7\x6e\x12\xa7\xbe\x66\xbe\x75\x5c\x71\x2b\xed\x0c\x9f\x6d\x4a\xf3\xda\x5f\x09\x15\x32\xc6\x3d\x15\x47\x7a\xd0\xb9\xbc\x6b\xe8\x9d\x4e\x42\x8f\xbc\x40\x1c\xec\x8d\x5e\x3d\x8d\x69\xd0\x36\x35\xf0\xf4\x5c\xad\xd4\xc3\xed\xde\xda\xf1\x80\x18\x2d\xed\x66\xcf\xf8\xce\xdf\xdf\x21\x1f\x51\x39\xbb\x71\x94\x61\xbb\x21\x37\x11\x61\x5d\x94\x07\x44\x81\xa4\x45\x7e\xd0\x30\xae\x6f\xf3\x40\x32\x8b\x09\x78\x87\xb2\x1e\x66\x54\xa7\xe7\x4a\xa0\x43\x6d\xdb\x3a\xb6\xa0\xa7\x28\x06\x35\x0f\x63\x1f\x37\xe9\xfa\x08\x8b\x6b\x5f\x52\x4b\xf3\x28\x30\x42\x8d\x67\xec\xa1\x5c\xe5\xcd\xd9\x69\x8b\x35\x74\x83\x42\x03\x11\x7e\x5e\xcd\xb7\xeb\xc5\xfa\xe9\x69\xb6\xdd\x35\x01\xcb\xc1\xfc\xf7\x76\x58\x14\x6b\xab\x06\xf5\xd8\x75\x00\xb8\x83\x5c\x51\xdb\x04\xbd\x80\x4b\x09\x18\x73\x0e\x2d\x2a\x8f\xa4\x21\x18\x1d\x94\xcf\x31\x89\x32\x00\xc9\x5e\x87\xf8\x3d\x7b\x72\xec\x71\xa3\xb3\x2d\x8b\x96\x5d\x76\x3e\x4d\xb1\x3a\x7a\x85\x31\xd3\xf8\xd2\x9f\x8b\x22\x3f\xf2\x4e\xe4\xef\xb3\xe1\x31\xc7\x84\xfb\x43\xc9\xff\x9d\x66\xef\x55\xe3\x4e\xf3\x6d\x2a\x5d\x1a\x98\xc7\x0a\x12\xd2\xd3\x9b\xe7\xf5\x86\x97\xfc\x0c\x75\x8f\x0d\x70\x74\xcd\x44\x70\xb4\x36\xbb\x53\xf1\xf1\x5c\x1d\xfb\xa1\x2f\x4f\x80\x62\xda\xfe\x29\xd5\xf5\xeb\xe5\x07\xd4\xd5\x5f\x27\x2c\x38\xa7\xd4\xf8\x9c\x85\xa5\x0c\x77\x37\xc7\x43\x2a\x1c\x43\x5d\xe3\xb6\x7e\x4f\xab\xba\x40\x8e\xa6\x49\x60\x17\xe7\x20\xb1\x60\xa2\x91\xf4\xf6\x81\x67\x59\x51\x8f\x3e\x9b\x08\x15\xd6\xed\x1e\x79\xe6\x15\xd7\xf6\x8b\x8b\x24\xc0\x5c\xfa\x43\x5a\x5f\xb2\xeb\xa0\x7a\xc3\x65\x10\xa1\x97\xe2\x4a\xed\x5b\xfe\xef\x7f\xb7\x80\x14\xae\x08\xc7\x34\xdc\xef\x9b\xf5\xe6\x30\x5f\x3e\x2d\x1f\x0e\x08\xbb\x98\xcd\x47\x6a\x68\x9a\x83\xaf\x10\x45\xca\x07\x9e\xa7\x3b\xa8\x4c\x01\xbc\x82\xfa\x70\x46\xc6\xda\x83\xc3\x5e\x1e\xca\x7b\xe3\xa5\x03\xa3\xd7\xf6\x90\xd6\x8d\xfb\xb2\x48\xf9\xb9\xc8\xd5\xbe\x83\x16\x70\x9d\xf8\x98\x35\x31\xcb\xc3\x01\x58\xee\x73\xdf\x93\x1f\x59\x78\x20\x30\x11\x27\x5b\x32\xfd\x56\xc2\xa4\x39\xa8\xec\xf6\x9c\x65\xb3\x2c\x73\xdc\x50\xc3\x5b\x14\x54\x11\xa4\x5d\x1f\x66\x33\x6d\xc7\xc3\x78\xb0\xcf\x24\x42\x3e\xf6\x1d\xa1\x99\xfb\x35\x5f\x18\x3e\x9b\x0a\xab\x18\x6f\xd8\x6b\xd4\x7a\xc4\x22\xf0\x63\x25\x5d\xbf\x4a\xdd\x65\x2e\x1d\xf2\x40\x04\x31\xd3\x76\x00\x86\x2c\x77\xe8\x5e\x11\x70\xa3\x23\xd9\xb2\x91\x28\xd3\x40\x3f\x1a\x16\x05\x54\xd9\xfb\x30\x82\x4a\x63\x22\xc3\x9e\xa3\x2e\xa2\x50\x22\xba\xe6\x58\xf2\xdc\x01\x75\x06\x4f\x15\x45\x46\x09\xa0\x34\x85\xb6\x2e\x9d\x28\x22\xad\x50\x6b\x64\x76\xad\x4f\xf7\xe2\xb1\xa3\xef\xc4\x3c\x0f\xbb\x93\x1e\xae\xf2\xed\xb6\xe3\x59\x07\x43\x14\x4c\x84\xd4\x36\x92\xa1\x16\xcf\xdf\xc0\x70\x0b\x06\x21\x12\x5f\x41\x2e\x0b\x4b\xfc\xb1\x52\xbf\xd9\x71\xc3\x1f\xd6\x5e\x60\x91\x8a\x96\x7a\x7f\xf9\xeb\x92\x15\xe5\xa8\x90\x27\x98\x96\x88\x06\x54\x90\xd5\xfc\xae\xf7\x7c\xf4\x6f\xfb\xd1\x62\xce\x4c\x4a\x15\xaa\x4b\x91\x57\x56\xa8\x6f\x34\x67\x62\x11\xa3\xd0\x7f\x07\xbd\x5b\xff\xbe\x7c\xd9\x1d\x1e\xd7\xdb\xc3\x76\xbd\x3a\xac\xb1\xf4\xbb\xda\xb7\xf1\xb6\x48\x7c\xc0\xc6\xca\x87\xeb\x6d\xb6\xfd\xa3\xcf\xb8\xa4\x45\x92\x98\xea\x12\x7a\x85\xae\x21\x62\x50\x27\x1d\xba\x19\x22\xe1\x54\x04\x86\x62\xba\x23\x19\xb2\xc7\x78\xc0\x91\xff\xfc\xdb\xeb\xba\x17\x5d\x08\xce\xc2\x20\x68\x0b\x5d\x58\x68\x1d\xa3\xa5\xdc\x48\xce\xcd\xe2\x31\x7e\x7d\x8f\x61\xc0\x0e\x10\x94\x52\x4b\x75\xbb\xb4\x70\x49\x93\xe1\x6a\xa9\x06\x9b\xa5\x66\xfe\x34\x30\xe4\x6d\x53\xa4\x10\x81\x8f\x0b\x8b\x57\x55\x7a\xcc\x07\x59\x3b\x21\xbd\x10\x92\x3e\x05\xcc\xd0\x6f\x71\xa3\xe2\x20\xb4\xb4\x1e\xaf\xab\xc5\xe0\x67\x9c\xc5\x15\x52\x99\xb4\xc1\x2c\x4f\xeb\xf4\x4b\x95\xcb\xf6\x04\x4f\x3b\x46\xd4\x59\x56\xf3\xd2\x70\xd6\x8d\x5e\x90\x8a\x34\x66\x02\x4c\x7d\xb2\x59\x8a\x5c\xd6\xae\xbb\x7a\xf8\xa1\x14\x07\x37\x55\x11\x80\xb9\xca\x75\xf1\x58\x94\x36\x79\xd6\xe3\xa0\xd1\x42\x41\x40\x54\x47\x57\x6e\xa1\xa6\x93\xd9\x35\x01\x2c\x4a\x0c\xb3\x64\xa9\xaa\x83\xc8\xb8\x7c\x3b\x60\x89\xc0\x5d\x4c\x07\x11\xa6\x66\xaf\x79\x25\x79\x9e\x0f\xaa\x24\xd2\x0b\x2c\x2e\x93\xbb\x2c\xd2\x7e\xd7\x1d\x8b\x7d\xd6\xe5\x15\xfb\xca\x01\x6e\x84\x14\xd8\xdf\xb6\x85\x5f\x7d\xab\x22\xa9\x17\x18\xc6\x61\xa8\x8f\xfc\x0c\xcd\xad\xa5\x79\x5d\x16\x53\x64\x7f\x5a\xfa\xa1\x87\x95\x91\x65\x56\xc1\x7b\xfa\x59\xc0\x2f\xfd\xc4\xc3\xd4\x98\xad\x75\x77\x6c\x4f\x46\x0c\x6a\xf8\x5a\xa4\x9f\x98\xee\x43\x63\x4d\x67\x47\xc8\xe5\xcd\x72\x77\x94\xe3\xa1\x82\x88\xa8\x03\x59\x06\xe3\xc3\x32\xf6\xac\xd6\x99\x4e\x7b\xc5\x6d\x19\x68\x8a\xf7\x9d\x56\xeb\x7c\xd3\x92\xe1\x8f\x5e\x51\x18\x26\xa2\xe5\x63\xff\xd6\x98\xe1\x91\xfd\x90\x51\xe8\xe9\x76\x87\x9c\x7d\x9b\x7f\xd5\x42\x27\xa3\x30\xa1\xb6\x81\x73\x91\x56\x97\x6b\x0d\x43\x38\xbc\x8c\x94\x46\x8a\x1b\xdd\xe7\xe0\x9b\xba\x52\x0c\x09\x16\xaa\x52\x69\x24\xe2\x03\x17\x9e\xd8\xe3\x09\xe1\x58\x8c\xac\xae\xe2\x9c\xd6\xbb\x22\xbb\x0e\x34\x62\xfa\x11\x95\x3b\x23\x06\xec\x3e\x3c\xa7\x79\xfd\x77\x3a\x6f\x64\x92\x84\x31\xb7\x31\xe0\xc3\x35\x57\x19\x4c\xb5\x31\xc8\x44\x85\x98\xf7\xb7\x3c\x02\xc5\xf9\xc2\xcb\xc6\x14\x0c\x47\x71\x4a\xa8\xf5\xd2\x90\x4b\x5a\xd9\xfc\x55\xf5\x04\xf9\xd1\xd1\x0d\x6b\xc9\xa5\xd1\xb7\x7b\x58\xbf\xbc\xee\x0e\xc1\x61\x31\xfb\xb3\x9d\xf0\x1c\x38\xb1\x45\x8c\x43\x2a\x8b\x3c\xfd\xd7\xe1\x62\x0a\xfc\x87\xe2\x02\x79\x6f\xbf\x97\x82\x78\x08\xa5\x4b\xab\xea\xca\xad\x86\xfe\xec\x1d\x4a\x7e\x1c\x87\x88\xee\x04\x8b\x3e\xb0\x5c\xf1\xbb\x0f\x80\x0e\xaf\x25\x45\x10\x20\x40\xa0\xb1\x80\xaf\x97\x75\xbb\x90\x84\x08\x83\xc8\x40\xd1\x51\xab\xb0\x1c\xa8\x35\x69\x29\x43\x43\x85\x7b\xbc\xfe\x1f\x2f\x9d\xd8\xb0\x96\x4a\x0a\xdf\xfa\x08\xe8\xb1\x62\xc5\x7f\xf4\x0d\xfe\x87\x5a\x03\x2c\x81\x2a\xd4\xb1\x30\x50\x67\x97\xf6\xeb\x2f\xc2\x91\xc0\xba\x37\x0a\x24\x24\x70\x40\x8f\x57\x16\x79\x13\x84\xed\x8b\xe7\x34\x4f\xbf\x75\x53\xd9\x0d\x13\x1a\x49\x76\xe7\x38\xac\xf1\xe6\x76\x28\xd5\xbf\x3b\xf1\x0b\xec\x4e\xa9\xbe\xd3\x81\xff\x64\xe2\x20\x17\x51\x2f\xc1\xdf\xd3\x09\x19\xbd\x76\x2d\x00\x37\xe7\xc7\xd9\xe3\x6c\x78\x48\x11\x16\x6a\xdb\x70\x6a\xf7\xa7\xc9\x1f\x53\x24\x61\x46\x42\x19\x93\x56\xa6\x6d\xbe\x2e\xc6\x77\x6a\x07\x7b\x42\x39\xea\x77\x4b\x97\x3c\x7c\x07\x8a\x42\x84\x50\xdb\xfd\xe3\xa3\x43\xc4\x2a\x9f\x11\xcc\x43\xfc\x04\xb1\xe1\x69\xc5\xdb\xbf\x27\x91\x45\xfc\x57\x2d\x4b\x52\x7b\x8c\x53\x04\x27\xf4\x58\x24\x2a\x53\x34\xef\x12\xc5\xa3\x07\x09\xa8\xf0\xb1\xce\xc5\x35\x74\x9c\x73\xa3\xb7\x12\x04\xa6\x10\xc5\xd5\x7b\x5a\xb5\x29\x7a\x77\x30\xf2\x91\xc5\xd8\x9e\xb2\xd6\xf8\xbb\xaf\x15\xa8\x59\x65\x6e\xd0\x25\x55\x55\x48\x7c\x4c\x11\x5f\x2b\x28\x6d\x53\xa1\x15\x3b\x1b\xfe\x5e\x48\x18\xb2\x87\xec\xaf\x02\xda\x73\x59\x42\xda\x84\x62\x31\x12\x38\xd2\x2a\x4c\x04\xa2\xde\x11\x6b\x8a\x3b\x40\xe3\x2c\xa3\x6f\x52\xa5\xc7\xf6\x22\x5c\x84\xb1\xe3\xfe\xff\x55\x3f\x34\x13\x36\x89\xba\xa3\xc6\x05\xcb\x3a\xf6\x56\xad\x22\x9f\x51\x84\xb5\x03\xf4\xe1\x92\x8a\x49\x82\x33\xc0\xfa\x64\x0a\x00\xb5\xc1\x52\xf9\xdb\x54\xce\xea\x6e\xe7\x52\x4c\xfa\x56\xb5\xac\x76\x9a\xad\x16\xcf\x3b\x7c\x17\x31\x8d\xd1\xe4\x22\x73\x74\x63\x51\x5e\x2d\x59\xae\x71\x27\xdc\xa8\x48\xa1\xf7\x06\xe7\xb4\xb6\x8b\xf5\x35\xd7\x65\xf1\xef\x31\x3a\x4c\x25\x84\x82\x37\x48\xcc\xf6\x51\xaf\x6e\x90\x67\x70\xb1\xb3\xf9\x6c\x52\x19\xd4\x0d\xa3\x14\x91\xc9\x38\x06\xc9\xe5\x3f\x43\x2b\x75\x56\x52\x25\xb1\x80\x8e\xf4\x17\x81\x69\xd3\x9b\xbb\xe2\x61\xe8\x9b\x5c\xb6\x7c\x5b\x7f\xe4\x69\x7e\xb4\x51\xf6\xe8\x91\xb8\xe2\x28\x66\x73\x31\xc4\xe0\xdb\x54\x4e\x36\x1b\x2a\x11\xe8\x80\xb6\x45\x16\x83\x89\x1a\x79\xf7\x4a\x48\x23\x75\x37\xb7\x0b\x7b\x20\x30\xa5\x95\xa4\x04\xbf\x06\xb2\xf8\x38\x10\xff\x1d\x65\xa6\x56\x32\x08\x4d\x72\x83\xe7\x47\x95\x4e\xa0\xca\x95\xe4\xa1\xc3\xf1\xae\x87\xfb\x88\x92\xd2\x4a\x3c\xa7\xcd\x12\x6f\x1c\xcc\x76\xd6\x29\xca\x45\x57\xb3\xfd\x82\xa6\xf7\x93\x59\xa7\x42\x8d\x0b\x60\x77\x2a\x2e\xbf\x9b\xdd\x66\x78\x5b\xe0\x2b\x69\x01\x71\xdb\x6b\xee\x48\x95\x87\x17\x81\x98\x12\xda\x39\xe0\xb6\xc4\x63\x9a\x53\xdd\x90\x84\x38\x98\xd4\x7c\xfe\xdd\xb4\x28\xd0\xe1\xab\xd4\x09\xf7\xb5\xc5\x3c\xee\x8b\x6d\x55\xdf\x13\x5d\xb6\x23\x35\xb5\xb8\x87\x87\x85\xd1\x0a\x1f\xe4\xae\xcc\x30\x20\xc4\x47\x8f\xdf\x71\x67\xac\x16\xee\xb5\x01\xa1\x80\x40\xd3\x3a\x85\xd2\xdf\x76\x0e\x0d\x10\xf0\x93\x70\x20\x49\xf3\x37\x88\x7c\x35\x78\x5e\x64\x4e\xab\x9e\xf9\xff\x15\x65\x5a\x8f\x6a\xeb\xe0\x51\x93\xf6\xc6\x46\xd0\xf2\x8d\x3b\x1b\x03\x9e\x12\xe0\xc4\x0a\x2d\x7d\xf1\x72\xff\x7d\xda\x38\x83\xa7\x23\xfc\xda\x0f\xb3\xc5\x01\xb1\xf8\xee\x2a\xbe\xcf\xd0\x4f\xfb\x73\xdd\x93\x8f\xd1\xe0\x87\xa6\x3b\xca\xb4\x0c\xaf\xaa\xe5\xaf\x74\x04\x27\x02\x9f\x1b\x2c\x2c\xba\x9e\x86\x4d\xa7\xad\x19\x80\x0f\x9a\xc9\x4e\x43\xc5\x20\x8a\x27\xbf\x09\x04\x09\x43\x7a\x97\xc6\x76\x0c\x7d\xed\xde\x5a\x87\x40\x7a\x49\x68\x47\xfd\x1d\x12\x53\x0d\x21\x49\x4c\x70\x59\x64\x19\xc8\xda\xd0\xd2\x8c\x5e\x6e\x28\x42\x3f\xea\xf5\xd9\x20\x41\xba\x2e\x4a\x09\x2d\xdf\xec\x4b\x51\xf7\xe7\x23\x44\x81\x69\x3b\xda\xc2\xe5\xda\x8f\x4a\x20\x8a\x4c\x30\xb9\xcb\x8a\xfa\x99\xcb\x53\x9a\xb7\x73\x23\x4a\x3c\x97\xbe\x69\x6c\x45\x0f\x20\x51\x75\x43\x14\xda\xb2\x2d\xf0\xac\xbe\xcd\x79\x35\x00\xf2\x00\x0b\xad\x80\x46\x75\x15\x6d\x96\x6b\xd0\xb3\x3e\x7c\x30\xa6\x43\x23\xc8\xc6\x33\xf8\xc9\xab\x5d\xdb\x53\x03\xb1\x4f\xfd\xa8\x15\xd5\x98\xf3\x52\xb5\xad\x5d\x73\xd3\x6c\x3f\xd1\x1b\x0e\xb1\xa4\x86\x99\x72\xf9\x67\x7b\x21\x9d\x60\x07\xbe\x2e\x61\x98\x9d\x86\x04\x98\xea\x40\x80\xcd\x13\x7f\x99\x37\x1f\xdd\x7a\xa2\x23\xdf\x72\x2c\xac\xe6\xeb\x12\xe9\x89\x86\x23\x84\x56\xae\x84\xbb\x4b\xbb\x66\xa2\xe1\x20\x08\xc3\xd8\xbe\xf3\xef\x45\xf1\xe6\xc8\x66\xc7\x8a\x14\x6e\x74\x1c\x84\x4e\xb2\x72\xf9\x4b\xf6\x8f\x68\x2a\x74\xcb\x1a\xb5\x7f\xcb\xd7\xba\xeb\xb6\x02\x1d\x18\xbd\xf7\x0a\xdf\x66\xf1\x01\x6a\x8f\xd4\x6e\x3d\x23\xac\x09\x8d\xd0\x8b\xbe\xb8\xef\x76\xa8\xda\x58\x5c\x13\x5f\x63\x94\x67\xdb\x71\x26\xd4\x19\xb5\x26\xb1\x52\x0e\x08\x8a\xa8\x04\x14\x0f\x1a\x3c\xae\xf6\x88\x52\x86\xba\x2c\x2d\x0c\x18\x36\x95\xe3\x66\x37\x37\x54\x26\x68\x51\xe1\x0c\x25\x06\xae\x63\xbd\x03\x37\x0e\x14\xc3\xcd\x30\x95\x6f\xaf\x97\xf1\xef\x69\x8a\x22\x08\xa8\xfd\x0c\xe5\x40\x30\x46\x6b\x1a\x01\x86\xa5\x59\x91\x1f\x1f\xae\xb7\xf6\xcf\xb1\x87\x56\xc1\x72\x36\xd7\x5c\x9e\x90\x2c\xb8\x1a\xe7\x33\x35\x8d\x23\x6c\xb8\xfb\x47\x51\xc1\xe5\xd4\x67\x40\xd1\x54\x7a\xb4\x93\x3f\x4a\x37\x45\x91\x2d\x9b\x4d\x21\x1a\x98\x27\xed\x47\x7e\x80\x4a\xb3\xe8\x17\xcc\x7b\x3d\xc0\x3a\x88\x0c\x3b\xb3\x02\x5e\x23\xc2\xee\xc0\x3d\x67\x10\x75\xc8\x0d\x99\xcb\xa6\x28\x6b\x9e\xf5\x17\xa1\x8e\x64\x20\xe2\x01\xbf\xeb\x23\xc0\x64\x81\x47\x33\x9f\x12\x5b\x9d\x9b\x17\x45\xa6\x8a\x8f\xfc\x1e\x33\xae\x59\x62\x7a\x84\x5d\xd2\xbd\x09\x3e\x8b\xfc\x9e\x0f\x40\xc7\x89\x17\x26\xad\xbf\xd1\x35\x8d\x4c\x36\x20\xe8\x98\x1b\x67\xaa\xc3\xaa\x0d\x1c\xc9\x91\xef\xa5\x63\xf0\x71\xc1\x71\x33\x81\x67\x69\xd9\xc3\x71\xd8\x31\x89\x1f\xb0\x56\x1c\xc4\xe9\x51\x83\x7a\x2c\xca\xc7\x4f\x7a\x72\x75\x12\xc5\x86\xb8\xe4\x2a\x2d\x45\xb5\x3b\xc0\x34\x96\xe9\x79\x96\x8d\x7e\x44\x09\x84\xa0\x9e\xab\x63\x47\x19\x66\x8f\x71\x8f\xe2\x84\x00\xd4\x93\x28\x74\xdd\x01\x4c\x35\xf7\x24\xf2\x99\xa9\xe2\x2a\x32\xf8\x6d\xf0\x8a\xb9\xa7\x02\x8b\xd5\x31\x8e\xd8\x6a\xbe\xfe\x7a\xe3\xd0\xdc\x03\xde\xb6\xa7\x1f\xaf\x19\x37\x9a\x71\xbf\x46\x3b\xb3\x16\x7e\x30\x4c\xfd\xff\x0e\x82\x8b\x66\xba\x4f\x1a\x36\x2d\xb4\x91\x3d\x49\xcf\xcd\x5e\xfd\xbc\xdc\x3b\x36\xb1\x21\xa9\xd8\xff\xfc\xef\x7f\xf5\xd8\xbf\x3e\x15\x60\xee\xbf\x1c\x49\xe2\xa4\xa5\x55\x58\xe9\x9d\x79\xe3\xc3\xa2\x90\x96\x9e\x61\x3c\xd9\xac\x9f\x37\xb3\xe7\x5e\x2b\xb4\x96\xd4\xac\x65\x07\xb2\xb6\x99\x7c\x35\xb9\x5f\x6b\x29\x19\x36\x9b\x0b\xf8\x04\x12\xa4\x21\x32\x41\x17\xbf\xd6\x85\x63\xcb\x73\xbf\x05\x56\x33\xfe\x52\x0e\x2a\x05\x5a\x93\x28\xec\x54\x29\x4d\xc4\xdc\x8a\xaa\xdd\xff\x84\xf6\x42\xdc\x2e\x2f\x50\xca\x4d\x91\xe6\x9f\x88\x4e\x6a\xf3\x7f\xff\xef\xff\xf7\xff\xbe\x2f\x7e\x3f\x0c\x13\xd8\x8c\x10\xcf\x33\x6d\xda\xb2\x04\x05\xbf\x7e\xfd\xa7\x1d\x13\xee\x2a\x9c\x62\x7a\x02\xb2\x36\x0b\xde\xfc\x55\x4b\x34\xec\x28\xbf\xb8\xc2\x4f\x5e\xb9\x63\xd4\x0b\x95\xc5\x4c\x65\x4e\xbb\x72\x76\xad\x8b\xde\x00\x86\xbc\xc1\x1f\x8d\xa1\xfc\x91\x2a\x28\xe6\xfd\xaf\xd0\x8c\xe0\x81\x73\xfa\x37\xbc\x34\xea\xae\xe3\x57\x60\xac\x29\x23\xc4\x0f\x4c\x93\x76\x65\x08\x17\xd2\xfa\x36\xa8\x95\xb8\x51\x8c\xb3\x0e\x51\x80\x9e\xc3\x58\xca\xba\xf5\xc8\x9a\xe1\xdc\xc3\xc0\x64\x59\x54\x06\x81\xe1\xfe\x2e\x01\xa9\xc2\x5f\x7b\xa2\x2d\xf6\x50\x90\x48\xf4\x4a\x2c\xf9\xe5\xf2\x04\xa5\xd3\x6b\x75\x23\x78\x82\xc0\xf7\x16\xaf\xfd\x54\xc8\xb7\xbf\xee\x24\x1a\x7d\x91\x48\x85\x98\x9d\x75\xa4\xfd\x73\x28\x6b\x93\xcf\x2d\x7e\x1b\x8a\x3b\xda\x13\x18\x57\x32\x71\x2b\x60\x1c\xc5\x32\x42\x62\x1e\x70\xdf\x75\xa4\xff\xe4\xef\xd0\x31\xf0\x30\x42\x12\xe2\x21\xee\x78\xb3\x5d\xfd\x98\xed\x97\x83\x8a\x68\x73\x98\x19\x62\x7f\xae\x94\xe9\x13\xa9\x3f\x67\xc8\x65\x84\x70\xa6\x5c\x83\xff\xbc\x4c\xeb\x66\x2f\x37\x7b\xc7\x84\xb5\x62\x84\x08\x46\x3a\xa1\x1d\xb8\x9e\xbf\x17\xf5\xbc\x37\x0d\x65\x12\x20\x8a\x8b\x2b\x35\x11\xa6\x32\x42\x94\x4f\x7d\xc3\x26\xb8\x49\x77\xbd\xb5\xa1\x54\x88\xf2\xd4\xb3\x6b\x7d\xc2\xb8\xe4\xa5\x68\xde\x21\xa8\xfb\x80\xb8\x19\xad\x3d\xdd\x4a\x12\x59\x62\xcd\x5d\xcd\x85\x29\xdc\x3a\x43\x32\x38\x05\x3c\xe6\xfa\xa1\xfa\x32\xd3\x93\x9f\x36\x6e\x6f\x17\xe2\x08\x11\x09\xcf\xbc\x2c\xd3\x26\x66\xbd\x97\xb6\x69\x46\x69\x53\x38\xde\x71\x0d\x0f\xc5\x2f\xf7\x4c\xda\xe7\x9e\x4d\x30\x0d\x74\xc5\xc7\x21\x60\x33\x34\x80\xc0\xe9\x1b\x1d\xd2\x1c\x01\x10\xb8\x09\xb4\xdd\x61\x83\xc6\xfb\xe6\x8c\xd0\xb0\xbc\x34\x17\xbf\x37\x25\xd3\x13\x55\x27\x0a\xef\x33\x2b\x8e\x4b\x24\xad\xb6\x17\xf3\x88\x47\x11\x50\x53\xf7\x85\xef\x7f\xac\x36\xd3\x93\xc0\x23\x1e\xb3\xa0\x4f\x24\x2f\x76\x06\xbc\xb7\xbd\x36\x83\x7c\xb3\xaf\xa1\xc9\xb8\x40\xe9\x68\x2b\x2c\xf0\xb4\x19\xc1\x24\xf6\xce\x1f\xfe\xed\xfa\x08\x06\xaf\xd5\xf3\x12\x45\x4c\x5c\x2c\x1f\x06\xbb\x21\x23\x9e\xef\x03\x42\x52\xfe\x80\xd2\x35\x1a\x30\xe2\x05\x81\x8e\xfb\x04\xf5\x87\xb7\x34\xcb\x0e\xd5\x47\x5a\xcb\x93\x1b\x13\x12\x8a\x52\xf3\x8f\xcf\xd8\xbf\xf7\x99\x15\x76\xa3\x3d\xc3\x32\xc0\x95\x7a\x28\x0a\x2c\x94\xdf\x65\xf5\x9b\x61\x54\x49\xdd\x32\x7c\xbe\x73\x79\x6b\x56\x45\xfb\x2e\xc2\xc4\x43\x94\x22\xe4\x03\xc8\x0b\x23\x5e\x14\x06\xb8\x27\xa0\x22\x60\x9a\x4d\xf3\xc2\x30\xe2\xc5\xbe\x81\x44\x54\x35\xb2\x02\x61\xb3\x3d\x1f\xab\xa1\x36\xe3\x42\xc1\xba\x24\x15\x4e\x48\x9b\xc1\x1f\x5d\x2f\x8a\xc2\x3e\x21\xd9\xf3\xee\x93\x6f\x1d\x2b\x29\x1c\x20\x0a\x21\x8e\x2f\xdd\xeb\x8e\x21\xc1\x1e\x78\xae\x75\x9a\xa5\x4d\xe8\x34\xe2\xcd\x60\xc4\x4b\xa2\x04\x31\x18\x1b\xc8\x6d\x4f\x32\x23\x1e\x57\xe0\xb6\x93\xad\xa1\xf8\x6a\x6d\x7f\xe7\x07\x8c\x51\x68\x8c\x78\x22\x30\x0c\x12\x56\x15\x70\xad\x47\x70\xbc\xd1\xbd\x8b\x20\x42\x1d\x9c\x13\xaf\x36\xfc\xd6\x6c\x0e\xa3\x19\x26\xe2\x18\x59\xb7\xec\x0e\x71\x2f\xe8\x72\x5f\xd7\xef\x16\xad\xa7\x12\x09\xb6\xb0\xe9\xd6\xcc\x7a\xbe\x1c\xf2\x98\x36\xc3\xb4\x40\xd2\xf6\xef\xfb\x27\xf7\xfc\xe0\x29\xcc\xd6\x67\xbc\x6a\x05\x95\xaa\x4d\x59\x68\xab\x3d\xd2\x0c\x09\x19\x35\xf2\xff\xb9\x19\xf1\x55\x85\x17\xc7\x03\x6e\xa7\x07\x17\xf7\xcd\x79\x39\xfa\xe6\x5a\x11\x54\x6f\x2c\xe1\x1d\x78\x36\x9c\x38\x94\x84\x11\x22\x31\xb6\xcb\xdf\xf7\x5d\x00\xd4\x1c\x88\x04\x3a\x07\x5b\xb8\x14\xdf\x79\xae\x46\x32\x81\xcd\x88\x24\x40\xfa\xb0\x17\xf8\xf8\x5e\x5c\x9c\x49\xa7\x1e\xf5\x51\x05\xe4\x9a\xa7\xb8\x47\xd8\x12\xc2\xa8\xaa\x88\x03\x99\xa1\x3c\xe0\x19\x3c\x5a\xa7\xb0\xbd\x88\xe6\x18\x68\xa2\x07\x51\x5c\xeb\xa7\xf4\xbc\xe0\x93\x35\x01\x46\x28\x25\xa6\x6a\x76\xe1\x65\x9d\xca\xf4\xc2\xf3\xba\x7a\x2c\x4a\xbf\x54\xfd\x9e\x7f\x37\x38\x0e\x88\xd9\x89\x16\xa8\xe9\xa9\x96\xf5\xc9\x7d\xc6\xd2\xa6\x96\x9a\x61\x22\x8c\xa1\x2b\x98\xba\x3f\xfb\x54\x1b\xc9\xcb\x8c\xa7\xe7\xe5\x6e\xfe\xc9\x1d\xf9\x09\xa5\x8e\x59\x65\xf7\x7d\x46\xc3\xa8\xbd\x40\xa2\x89\x41\xdd\x97\xef\x50\x2e\x8d\x82\xda\xbc\xc8\x75\x96\xca\x7a\x75\xbe\x64\x7d\x58\xea\x7d\x96\x74\x08\x81\xfb\xf4\xdf\x89\xf4\x37\x23\x34\xf0\x29\x46\x29\x1b\x38\x1e\x33\xe8\xed\xdf\x34\x08\x85\x32\x65\xa4\xe2\x52\xcf\x79\xdd\xfe\x5d\x02\x26\x84\x4c\xa1\x71\x35\x5f\x1f\xb6\xeb\xd7\x97\x85\xe7\x8e\x87\x1e\x11\x60\x68\x26\x8a\x6b\xbd\x83\x4c\xb7\x47\x84\x8f\x88\xd0\xed\xfa\x69\x79\xf8\xfd\xcf\xf9\xe1\xc7\x72\xbb\x7a\x5c\x2d\x17\x87\xd5\xcb\x8f\xe5\x6e\xbf\xde\xba\x91\x11\xf1\x23\x07\x00\xed\x54\x8b\xee\x9a\xe7\x9a\x91\x1e\xc3\x14\x87\x49\x2d\x7e\xc2\x34\xd0\x8c\x63\x31\xe6\x0c\x0f\x8d\xf5\x2e\x53\x75\x34\x41\x40\x8f\x40\x69\xf4\xb9\xa2\x84\xb1\xae\x38\x8b\x7b\xef\x5a\x3f\x17\x39\xd4\x27\x8e\xfe\x8c\xd1\x35\x34\x4c\x72\xa3\xf9\x14\x71\x4e\x9c\xde\xfc\x1d\xd7\xfd\x88\x62\xbf\x0f\x3a\x9a\x22\x54\x63\x84\xb2\x24\x0c\x03\x8c\xaa\x95\xc9\x9d\x0d\xed\x2a\x8d\x2d\xd0\x44\xa0\x62\x12\x42\x72\xbb\x43\x0a\x43\x26\xc4\x49\x8d\xee\x32\x8e\x99\xe5\xeb\x31\x72\x79\x65\xfa\x06\x77\x58\x99\x66\x9c\xf0\xd1\xec\x63\xbb\x50\x5e\x41\x5e\x1b\x05\x54\x87\xeb\x60\x84\x26\x5e\x80\x85\x20\x04\x3d\x4f\x78\x69\x34\xa1\x86\x45\xf5\x5c\xe4\xf5\xa9\x3d\x2b\x62\x06\x1c\x99\xc1\x7b\xeb\xcd\x50\xee\x83\xd6\xae\x50\x57\x34\xef\x39\xd5\xed\x14\xe2\xa1\x0e\x6c\xaf\xe4\xd3\xd3\x0f\x93\x93\xf7\xbd\x81\x7b\x47\x45\x68\x96\x53\x13\x1d\x7f\x77\xda\xd9\x83\xd5\xe3\xfd\xe5\xe2\x99\x5e\x2c\x82\x09\x2b\xfe\x5e\x41\x59\x63\x59\xa1\x6b\x21\x9e\x2c\x92\x31\x42\x25\x35\x01\x63\x0e\xbf\x5c\xfb\xfd\xa6\x50\xbb\x9e\x61\x93\xcc\xb4\x77\x5b\x1c\x40\x56\x5c\x55\xb5\x81\x72\x59\x9f\x46\x5f\x42\xb2\xd8\x42\xf5\x32\x90\xf5\x41\x5c\xf9\xe1\xd2\x27\x17\xe8\x8d\x14\x46\x79\x39\x35\x58\xcb\x56\xd4\x71\x34\x4c\x85\x86\xef\xea\x1f\xe9\x3f\x52\xf8\xce\x8b\x21\x92\xe9\x1e\x5e\xc1\x08\x05\xad\xb4\x49\xae\x54\x97\x8e\x45\x8e\x11\xaa\xa9\xe9\x9d\x73\x6e\xc4\x2c\x57\x8f\x98\x86\xc5\x02\xe6\x6f\xa3\x1c\x43\x9f\x70\xf1\x4b\x39\x92\x51\x44\x49\x75\x42\x70\x46\x23\xba\xeb\xf0\xaf\x6b\x7a\xf8\xd7\xbf\x27\xa7\x9c\x96\x0c\x11\x40\x5b\x78\x4f\xe1\xe3\xb9\x50\xe0\x7c\x5c\xdf\x8b\xb4\x63\x4c\x68\x96\x32\x72\x9f\xae\x3a\x55\xaf\x91\x9c\x17\x23\x3e\x25\x1e\x3a\x07\x39\x7c\xfc\x4c\xeb\x7c\x94\x9a\xc0\x01\x86\x50\xa0\x99\x73\x38\x25\xac\x03\x3c\x78\xdd\x3e\x0d\x04\x33\xaa\x88\xe5\x5b\x5e\x28\xf8\x0c\xaf\xe7\x86\xc7\x8c\x99\xfa\xc4\x71\xd2\x73\xf3\xa9\x62\xa6\x12\x06\xef\x69\x96\xf1\xf7\xea\x81\xdf\xa0\x74\x76\xa1\xf1\x8b\x8d\x5a\xab\x15\x89\x75\x95\x47\x77\x58\x7b\x68\x8e\xf7\x2f\xfb\x9e\xdd\xf7\x03\x99\xf8\x89\x8b\x3f\xe8\x41\x41\x55\x97\xc5\x6d\xe0\xd0\xfb\x8d\x55\x31\xb1\x90\x51\xfb\x72\x99\x56\x46\xfc\x30\x20\x08\x20\x79\x9d\x37\x17\x6d\x0e\xae\xaa\xf5\xb0\x19\xb6\x19\xc5\x0c\xd1\xa2\xbe\xe6\xf2\x40\xe2\x85\xdf\x9e\x9e\x08\x2c\x12\x9c\xf9\x1b\xec\xae\x17\x28\x7f\xa4\x23\x8d\x39\x46\xfc\x48\x27\xa8\x6a\x8a\xf5\x12\x14\xb2\x4a\x79\x76\x28\x07\xfc\xab\x76\x28\x8b\x88\xcb\xd9\xda\x9a\xf2\xa4\xea\xce\xf0\xee\x18\x48\x4c\x24\x5c\xf8\x0d\x55\x6b\x1d\x36\x97\x11\x3f\x0e\xb5\xe9\x5a\x2d\x8e\x86\x54\x6d\x86\x00\xb9\x7b\x67\xfd\xef\xfe\xeb\xae\xcb\x24\xe6\x59\x4f\xbc\x3a\xf5\x31\x60\x43\xd7\xcc\x4f\xfc\xa8\x95\xcb\x5e\xaf\x9d\x36\xc0\xa4\xc3\xe1\x27\x21\x41\x43\xda\x4c\xff\xdf\x79\x79\xe6\x3f\x8a\x51\x45\xa3\x19\xa4\xa4\xb2\x45\xce\x87\xe5\x9f\xa3\x97\xc7\x23\x01\xae\x6f\x3f\x4f\xeb\xc6\x28\x99\x0c\xbf\x7b\x1b\x5c\x72\xe3\x99\x16\xe7\x0b\xd4\x69\x5d\x94\x58\xae\x6b\xe7\x09\x57\x0a\xbd\x6e\x9e\xa7\x67\x5e\x77\xb5\x51\x7b\x58\x78\x81\xe7\x75\xdc\xda\x3b\xc8\x32\x5d\x94\x8f\x7f\x8c\xee\x51\xe8\xc4\x33\x64\x53\xf5\x0e\x85\xa8\x46\xc7\x65\xcc\x51\x1f\x03\xc1\x4c\x2d\x35\x3c\x6e\xac\xd3\x85\xd0\x01\x58\xfe\x3e\xb6\xf0\x95\x50\xb1\xcb\x47\xad\xcc\x26\x13\x0f\xf6\x18\x5f\x69\x96\x74\xca\xeb\xdf\x51\x4f\xe5\x32\xba\x2d\x48\x48\x28\x1c\x17\xbe\x82\x5f\x0f\xb7\x1e\x85\xb0\x1b\x23\x18\xb5\x49\x12\x04\x77\x8d\x3e\x00\x80\x69\x6f\x6e\x96\x12\x2e\xf1\x1e\x6c\x85\x11\x5f\x87\x46\x09\x73\xce\xfb\x5a\x5b\xee\x20\x8f\x31\xe5\xb5\x58\xef\xf6\xfb\x9e\x17\x1f\x10\x21\x31\xe5\x64\xea\xef\x13\x10\xd6\x4f\xdb\x65\x26\xff\x99\x9c\x7c\x01\xd1\x3e\xc6\x7a\x58\x9b\x6a\x3b\xb6\x18\x09\xbc\xc8\x68\x60\x75\xd8\x8d\x65\x7d\xea\x16\x58\xe0\xa9\x04\xb3\x4a\xc5\xb5\xae\x9a\x3d\xd2\xf4\x59\xf6\x7d\xbe\x80\x06\x31\xd6\x9f\x4d\x49\xa0\xcb\x1c\x05\xbe\x34\xdd\xfe\xae\xa1\xe1\x25\x95\x6f\x63\x81\x05\x46\x82\xc6\x83\xb5\xf9\x9f\xfd\xef\xa3\xf4\x66\x10\x26\xc2\x10\x20\xda\x6d\xec\x09\x74\x5d\x74\xee\x49\x10\x8a\x20\x32\x14\x57\x75\xd6\xb8\x4b\x67\x3e\xc4\x72\x30\x12\x44\x89\x87\xf0\x94\xa7\xab\x7c\x1b\xbc\x79\xc6\x00\x79\x18\xb6\xc5\xbf\xbb\x4c\x45\x10\x13\xca\xac\x1c\xcd\x00\x8f\x6e\x0f\x27\x3c\xc0\x17\x62\x3a\xf5\x44\xc1\x4b\xf5\x94\x22\x6b\xcb\xc2\x98\xe6\x76\x0b\x0e\x12\xa9\x10\x22\xf0\xd4\xac\x92\x22\x3f\xce\x79\x3d\x77\xca\xd8\x8c\x04\x3c\x32\x41\x9f\xe6\x69\x66\xd9\xa1\x7a\x84\x34\x76\x90\xf0\xa2\xa0\x8b\x64\x55\x63\xbd\xfb\xd0\x8e\x66\x44\x24\x89\xa5\x15\x98\xba\x5f\x15\x10\xe4\x3d\xbf\xa0\xa5\x40\x1d\x97\x4e\x49\x13\x8f\x73\x61\xc1\x3b\x4f\x45\x55\x37\x6e\x42\xb3\xe3\xda\xfa\x63\x3b\x48\x61\xa7\xfb\xa5\x28\xb2\x7d\x0b\xfa\x6d\x0e\x48\x40\xc6\x81\xa7\xdd\x27\x78\xd2\xbe\xd7\x1f\x28\x45\x7a\x4a\x4d\x8f\x00\xf3\x6b\x9f\xbc\xde\x0d\x03\x5f\xa1\xab\x60\x30\x40\x3c\x33\x52\x63\xaa\xff\xd0\xc0\x02\xc4\x0c\x8b\x66\x0b\xb9\x6d\x5c\x87\x21\x23\x81\xf6\x84\xe5\xf8\x31\x64\x95\xc8\x70\xd2\x5f\xe4\x81\xa6\x3e\x02\x95\x4d\x55\x7a\xdc\x7e\x7c\x9f\xe0\x0e\x09\x95\x21\xb7\x5b\xf0\x02\xb5\x09\x50\x3a\xcd\x1d\x0d\x23\xc3\x68\x6e\xfb\xc8\x7a\x08\x6a\x37\x22\x49\x44\xd2\x71\xb5\x18\x49\xbf\xc9\x75\x1a\x12\xee\x21\xdc\x62\x9f\x9e\xa1\x06\x79\xea\xcf\xd7\xd0\xe3\xb1\x6f\xed\xe0\xaa\x42\x0c\x78\x9a\x43\xf9\x58\x94\x5b\x68\x1c\x8a\x34\x3f\x6e\xba\xf0\xba\xf7\xb6\x42\xcf\x92\x90\x76\x8a\x81\x03\xae\x99\xcf\x04\xad\xec\xd9\xd4\xf3\x90\x5c\xc4\x71\x90\xdf\xf5\xf3\x34\x63\x94\x11\x36\xef\x90\x92\x56\xfb\x6f\xca\xf1\x0a\x7d\x0d\x71\x9f\xcc\xe7\x20\xfb\xc4\x38\x8c\x84\x41\x20\x58\xd0\xaf\x4c\x2f\xfa\xa2\x25\xed\x20\xc0\xd7\x7a\x4a\xff\xcf\x35\x79\xbb\xf3\x43\xe2\xa1\xa4\x08\x54\xb2\x2c\x3e\x46\x10\xaf\xaf\x53\xb1\x61\x48\x22\xec\x31\x11\xd7\x0c\x99\xc9\xe1\x3b\x70\xe5\xd8\x1b\xdd\x98\xc0\xc3\x98\xa6\x84\xba\xe4\x69\x7d\x08\xdb\x1f\x66\xd4\xa0\x82\xa0\x6a\x33\x4f\x88\xce\x70\xc7\x95\x8f\x8c\x01\xef\x13\x42\xeb\xce\xa7\x0e\x23\x61\x34\x78\x44\x56\xc8\xb7\xaa\x4e\xb3\xcc\xbd\x9f\x13\x97\x6f\xad\x42\x47\x33\x52\x99\x4f\x23\xae\x65\xfe\x54\xd4\x2b\x55\x3d\x4c\x81\x6b\x18\x09\x59\x2c\x70\x4d\xed\x36\xcf\xfb\x4f\x05\x23\x9b\x71\x89\x67\x70\x92\xc8\x25\xb8\xdb\xcf\xb6\xfb\xe5\xc2\xfd\x1c\x93\x14\xbd\xad\xf9\xe3\x62\x74\xf9\x38\xa6\xda\x1a\xa1\x8e\x40\x96\xd2\xc1\xc2\x0b\xe3\xc4\xb4\x48\x9d\x6b\xb9\x40\x69\x80\x9e\x1d\x0a\x13\x62\xba\xd9\x10\x12\xd0\xc1\x00\xfe\x6b\x54\xa6\x08\x13\xcf\x08\x46\x19\x91\x90\xe1\x76\xe9\x86\x30\x69\x0a\x27\x4d\x4c\x62\x39\x17\x11\x8b\xe1\x8e\x5b\x16\x9a\xea\x2a\x26\x09\x8a\x87\x57\xe3\x7e\x84\x38\x48\xfc\x1a\xce\x31\x0e\xb9\xcd\xac\x59\x25\xbf\x87\x02\x9b\x82\xe6\x57\xd7\x05\xce\x48\xd8\x98\x6e\x93\xf2\xc6\x3c\x6a\x13\x7d\x2d\x8f\xc7\xf6\xa8\x6f\x28\x7b\x5c\x27\xd7\xa3\xd7\x1e\x09\x25\x65\xbd\x2d\xcf\x92\x82\x3d\x37\xb1\x7a\x76\xb3\x5c\x72\xc3\xd7\x2f\x18\x68\x5b\x4c\x6d\xec\x25\x16\xdc\xac\xe6\x56\x6b\x85\x44\x1c\xa3\x5c\x22\xaf\xde\xfe\x69\xfb\x5c\xa7\x02\xb5\x50\x08\xd3\x6a\x62\x7c\xa9\x4d\x09\xf9\xf5\xf2\xdb\x78\x04\xb6\x6c\x01\xaf\x6a\xae\x2a\x89\x8a\x7b\xdd\xef\x28\x1f\x5d\xfc\xc6\xd6\x2d\xe0\x1d\xb2\xe2\x72\xee\x4a\x5d\x76\x90\xe4\xa1\xb4\xd0\x5b\x8c\x47\x2d\xf6\x74\xa5\xbe\xa5\xef\x90\xb7\xff\x6b\xf4\x61\x55\x48\xd1\x6e\x1c\xb8\x52\xcf\xa8\x75\x37\xfd\xc9\x14\x07\x74\x64\x0d\x54\x67\x5e\x72\x5d\x8f\xba\x26\x46\x26\x0e\x58\xe2\x3c\x95\x27\x5e\x99\x98\x13\x99\xda\xdc\x71\x10\x26\xc0\xb2\xa4\xe9\xf3\x22\x37\xd5\xec\xa2\xc4\x26\xc4\x9e\xad\xd5\x41\xe4\x9b\x16\x53\x3d\x87\xbc\x76\x99\x03\x77\x34\xf1\xb0\xf0\xf4\xc8\xcb\x0e\xbc\x33\x68\xa2\x6e\x06\x09\xed\x2b\xbb\xaa\xad\xce\x4b\xae\x46\x72\x16\xc3\xfb\xd7\xc0\xa4\x83\xaf\x2d\xff\x75\xc5\xca\x2e\x22\x91\xed\xef\x46\x84\x84\xe8\x46\xa8\x5b\xce\xab\xfa\xd6\xfe\x39\x92\x68\x15\x6c\x48\x6a\x12\x04\x96\x8d\xd0\x0d\x11\x1a\x8c\x89\xa9\x6e\x3f\x8b\xf2\x93\x84\x7e\xe4\x25\x01\x1a\x63\xc8\x20\x97\x03\xf9\xd6\xe6\x20\x30\x66\xb4\xea\x79\x5d\x1d\x1a\xab\x9f\xcb\x14\xca\xea\xe0\x11\xcf\x6b\xfe\xdf\x0d\xa4\xc4\x43\xf3\x68\x7c\xe1\x87\xb2\x78\x6b\x7d\x90\x88\x06\x8c\x7b\x86\x1d\xf2\x47\x61\xfd\x2d\x59\xa6\x97\x6e\x1e\xbb\x81\x91\x59\x9a\x39\x7c\x2c\xa6\x14\x03\xfe\x66\x51\xff\x3f\x8b\x18\x23\xdf\xa7\x0a\x83\xa7\xf4\x78\xaa\x83\xe8\xb7\xd1\xd1\x20\xa2\x36\x50\x7c\xd8\xcf\x91\xd9\xd3\xe5\xb6\x46\x29\xaf\xc1\x69\x41\x64\xf0\x1c\x8b\xf5\xcf\x97\x03\x22\x5e\x7e\xb6\x99\x81\x28\x88\x14\xd8\x3a\xc4\x0e\xac\xe3\x38\x50\x85\x6d\xc6\x70\x8e\x17\x98\x6d\x36\xdb\xf5\x8f\x65\xdb\xac\xdb\x5e\x43\x84\x9c\x4f\xf5\x35\xa2\x87\x33\x98\x64\x51\xa0\x42\x24\xb3\x43\x3f\xbf\x93\xad\x6b\x8e\x40\x48\xda\x08\xc0\x30\xe9\xba\x54\x44\x97\xfc\x8c\x02\x4d\x0c\xc7\xd7\xfa\x79\x33\x7b\xf9\xf3\x30\x7b\x7a\x5a\xcf\x51\x96\xcd\x8d\x08\xff\xff\xac\xfd\xd9\x72\xe3\xb8\x96\x3d\x0e\xbf\x4e\x5d\xf4\x05\x01\x0e\x00\x2f\x65\x59\x76\xba\xd3\xb6\xdc\x92\x9c\x59\xd5\x27\x3a\x14\x18\x36\x64\x1e\x53\xa4\x9a\xa4\xec\x74\x3d\xfd\x17\xdc\x00\x38\x89\x76\x56\x7f\xbf\xff\xc5\xa9\x3c\x61\x80\x14\x09\x62\xd8\xc3\xda\x6b\x49\xf0\xf0\xc8\x2d\x34\xed\x37\xc6\xa0\x5e\x7d\xf5\xb1\x5b\xac\x87\x9e\xc3\x68\xc7\x4a\x62\x25\x31\x68\x2e\xb4\xbe\x80\x2c\xb2\x20\x49\x82\x58\x0e\x6d\x93\xbd\xf0\x98\x82\xfd\x05\xd7\x29\x76\xb7\x88\xd5\xba\x11\xaf\x80\xfe\x73\xbb\xb1\xbb\x7c\xfd\x34\x20\x39\x8a\x14\x4f\x52\x8f\x09\x0b\x04\x42\x6a\x57\xcd\xcb\x20\xe2\xfc\xaf\xf0\x7f\x7c\x3b\x70\xf4\x6b\x91\x2b\xe6\x66\xb1\xec\x23\xee\x09\x33\x56\x13\xb3\xdb\x68\x2e\x4b\xe5\x5d\xcf\x94\xd8\xb0\x82\x1c\xc0\x8d\xbe\x34\x70\x92\x14\x18\x16\xfb\xf8\x84\xe5\xa9\x54\x2f\x18\xbe\x1b\xa2\x37\x12\x11\x26\x81\x2b\xde\x7c\x11\x95\x56\x53\x7f\x3a\x11\x69\x8a\x85\x8b\xaa\xd4\xb0\xfa\x85\xa8\xe3\xa2\xa7\x0b\x69\x3b\x48\x11\x61\xc4\xef\xf1\xda\x67\xd2\x7c\x93\x8c\x2d\x1d\xe8\xc6\x19\xe9\x56\x08\x7c\xee\x38\x4a\xb4\xe1\xda\x53\xf8\x95\x05\x9a\xd7\x53\x0e\x4d\xec\x05\x71\xe4\xe9\x28\xeb\xb3\x63\x85\x99\xc4\xf1\x5d\x5f\x20\x04\x61\x8f\x5b\xab\xb3\x2d\xbb\x60\x59\x02\xb1\x4c\xbc\xc3\xba\x5b\xe2\xb1\x3c\xf2\xf0\x13\x90\x16\x3a\x05\xcd\xcb\xf3\xf6\x7a\x5d\x09\xd5\xd9\x62\x09\x68\x86\x36\xe7\x55\x79\xf4\x38\x83\xc4\x24\x11\x2e\xbf\x43\x99\xeb\x0e\x23\x8e\x7f\xb7\x62\x36\xc2\xca\xeb\x8d\xc1\x79\x97\x51\xd6\xc4\x70\x8e\x38\xf4\x7f\x67\xb7\xe5\x19\x9f\x6b\x48\xbc\xd2\x76\x30\x09\x71\xea\x38\x97\x04\x62\xb3\x13\x87\x05\x5c\x84\x8e\x38\x6a\x08\x6f\x64\x01\x23\xd4\x86\x1c\x1d\xbf\xa9\xc5\x7d\xfc\x3d\x0b\x03\x6b\x7b\x87\x14\xb7\x85\xdd\x7f\x0e\xc2\x96\x8c\x24\xdc\x73\xc5\xfc\xb0\x9c\x11\x65\x35\xcc\x51\x30\xc2\xb9\xea\x79\x95\x86\x98\xc8\xc9\x73\xd2\xc0\x1e\x40\xfb\xa3\xf8\xd5\x55\x85\xf8\x02\xf2\xb6\x5d\xa4\x78\xb8\x1c\x90\x21\x6b\xed\x88\x59\xfa\x56\x4b\x09\x51\xc0\xfb\xf6\x2c\xb5\x9d\x67\x9f\xe5\xe4\x66\x0f\x57\x46\x55\x22\x89\x93\xc4\xac\x32\xd5\x74\x33\x9c\x85\x94\x70\x3e\x80\x73\x8b\xfa\x75\xe1\x10\x58\xf3\x63\x1e\xaa\x80\xd1\x0e\x51\x88\x53\x1f\x74\xcf\xa4\xcb\x02\x16\x05\x02\x67\xd8\xe9\x5c\x9d\xca\x1a\x06\x7f\xb6\x41\xa2\x5c\x64\xc7\xa7\x6a\xf0\x82\x11\x8d\x8c\xcb\x82\x5a\x9b\xaf\xac\x6a\xfb\x08\xbe\x43\xc8\x3a\x97\xc3\x16\xd7\xce\xa6\xb5\x58\xe4\xaa\xb5\x5d\x0d\xf6\x52\x9c\xee\xbb\xa2\xa5\xb6\x59\x05\x29\xe9\x4d\x4c\xdc\xff\xc9\x10\xed\xcb\x02\x16\x4b\x82\xf9\x0b\x2b\x1d\xf3\x50\x16\xa2\x52\x2f\x77\x45\x03\x55\xd1\x85\x0c\x58\xc2\x42\x2c\x91\x47\x52\xaf\xd6\xa2\x70\xde\xfd\xfc\xd7\x4f\x98\x65\xaf\x37\x59\x9e\x5f\x65\xfa\x13\xf7\x86\x25\x40\xad\xb4\x62\x56\xbf\x2a\xc4\x77\x8c\x6f\xc3\x62\x81\x1b\xce\x1e\x99\x89\x32\xe5\x74\x55\x67\xad\x41\xc6\xb8\x05\xb4\x63\x1d\x4d\x3d\xff\x83\x4c\x11\x0c\x82\x6e\xcf\x72\x8d\x6a\x86\x23\x7a\xb9\xc9\x0d\x79\x20\x98\xf0\x0a\x1f\x2f\x28\x7d\x48\xfd\x70\x70\x6e\xe1\xc9\x0f\xa2\x52\x90\x97\xdd\x9f\x4d\xe4\x0b\x70\xbf\xb5\x6b\x7a\x76\x70\x52\x62\x05\x71\x17\x5a\xdb\x5a\x6c\x27\xb6\xd6\x0b\xdc\xb1\x80\x89\x08\xd2\xc4\x7b\x43\xbf\x0b\x8b\xfb\x6b\x98\x40\x2a\x12\x5b\x6e\xbe\x1e\x56\x26\x75\xb7\x4d\x2d\x56\xf4\xa6\x2c\x75\xbb\xf0\xff\x11\xe7\x62\x7b\x9d\x91\x96\x9b\x2b\x2f\xeb\x19\x69\xf0\xc9\xc8\xc9\x38\x0a\x7b\x26\x2f\x87\xc5\x1b\x3f\xab\x14\x36\xdd\xfa\x23\xcb\xff\x1e\x6d\x63\x52\x53\x9c\x68\x50\x78\x28\x73\xdf\x62\xbf\xc7\xad\x37\xf7\xcb\x63\x6b\x61\x5f\x66\x9a\x98\xd4\xb6\xb8\xe9\xc1\xed\x3d\xdd\x3a\x55\x91\x09\x62\x57\x74\xb3\xc8\xf3\xbe\x8e\xaf\x6d\x4b\x24\x1a\xdb\xd6\x7f\xbf\x2b\x2c\x09\xf8\x52\x9c\x46\xd1\x7a\xa6\x58\x8c\x7c\x95\x75\xf6\xab\x79\xe9\x6a\xab\x59\xc0\x74\x14\x46\x83\x88\x70\x55\x1e\xcb\x65\xd6\x7c\x4c\xcb\xac\xc7\xc3\xa0\x63\x83\x51\x4e\x9b\xe7\xc7\xe5\xd9\x99\xff\x4c\x6b\x8e\x93\x6c\xb7\xb8\x5d\x2e\xb6\xdf\xfc\x9f\x81\x13\xac\x82\x12\x39\xa6\x6b\xa0\xaa\x44\x5e\xef\x31\x1e\xb6\x97\x1f\x7b\x31\x3b\xf3\x4d\x04\xca\x7e\x92\xf2\xdd\x01\xcb\x76\xf7\x4f\xdd\x7c\x36\x10\xe1\x49\xfc\xb0\xbe\xfe\xb3\xc3\x16\xb3\x80\x07\x29\x43\xdc\xb6\xb6\xe5\xe4\x17\xdf\x7d\x74\x46\x73\x42\x62\xb4\xe1\x33\x55\x16\xc3\x8f\xca\x89\x8e\xb5\x37\x58\xcb\x32\x5f\xbc\x1d\xbe\x89\x46\xbd\x0c\xa3\x3f\x9c\x86\xdc\xca\x1c\x3a\x1b\xf4\x26\xab\xea\x66\x68\xb0\x72\x9a\x04\x58\x05\xd5\x80\xb0\x1c\xa7\x34\x20\xbc\x6b\x94\x11\xb5\x23\x59\xd5\x80\x36\x91\x8b\x00\xf9\x76\x4d\x2d\x56\x0f\x3e\x97\x17\x74\x5d\xc3\xd8\x46\x80\xdb\x05\x32\x00\x0a\xf8\x8b\x2c\xd3\x18\xfe\xb7\xbb\xc0\xf1\x3c\xb8\x58\x9b\xc3\x27\x0e\x71\x91\xae\x67\x14\x19\xbb\xa7\x40\xa1\xaf\xc4\x8c\x6c\xba\xef\xc7\x23\xa4\x83\x93\x79\xf6\x0a\xfa\xb9\x68\xb2\x09\xd4\x8a\xc7\x11\xc3\x14\x72\xbb\x67\xdb\x4a\xd0\x7b\xf1\xfe\xd1\xbf\x6f\xcc\x13\x4c\x0e\xfe\x75\xfd\xcd\x46\x85\x1e\xbe\x82\xad\xf2\x38\xd5\x82\xfb\xe8\xed\x06\x9a\x73\xf5\x29\xfb\xab\xbf\xc2\xa9\xf1\x4b\x5a\x8f\xf3\x6b\x3c\xa1\x31\x2a\xee\xf6\x82\x41\xbf\x2f\xf8\x6f\x2f\x8b\x6d\x06\xff\x1a\x8e\xa5\xaa\x84\xfa\xf8\x51\x76\xb6\x17\x67\x89\xc2\x6f\xe2\xd1\x58\xf3\x07\x0f\x67\x92\xe2\x51\xbd\x2c\x0b\xe8\x27\x0e\x03\x4d\xd5\x80\x84\x6c\x0b\x30\xd9\x32\x38\x67\x36\x2c\x89\x1b\x72\x6b\xab\xd8\x47\xfe\x99\x35\x2f\xa3\x39\xc8\x85\xc4\xcd\xbb\xa3\x17\xed\x51\xe9\xe3\x27\x49\x21\x32\x4e\xcf\xe6\xea\xfc\xe1\x8d\xec\x3e\xe4\xc0\x45\x94\x7a\xc6\x8f\xf5\xc9\x33\x55\xc0\xc0\xdf\xe8\xec\x49\xef\x7a\x70\x49\x83\x14\xab\x84\xbe\x2f\xbf\x20\x82\x68\x3b\x86\xd6\xbc\xb0\xf4\x0c\x4e\xcc\xf6\x8f\x71\x97\x54\x63\x89\x4b\xbb\x52\x76\x2f\x15\xd4\x2f\x5e\x05\xa5\x6d\x34\x0c\xf1\xab\x36\x9a\x64\xcb\x92\x7f\x17\x88\x9d\x9f\x57\x8a\xa6\x68\x03\xff\x55\x9e\x6f\xb3\xb7\xcb\x0d\x64\x3e\x0d\x36\xfe\x36\xca\x48\xea\x53\x4d\x7e\xe9\xd7\x97\x5a\xc4\x2c\xe0\x3a\x50\xb8\x5d\x9d\x5d\x69\xf4\x40\x73\xbc\x6d\x4d\x8d\x95\x93\xa8\xca\xf3\x69\xff\x0a\x1f\x7b\xcf\xda\xd1\xbd\xb8\x16\x29\x26\xa6\x10\x7a\x3e\xb5\x5a\xc6\x63\xac\xb5\x41\x08\x97\x1d\xe3\xde\xbe\xe4\x10\x84\x18\x55\xd7\x03\x0d\x7d\x57\x0c\xdf\x4d\x23\x00\x5b\x81\xec\xa3\x85\x1d\x2c\xb9\x9d\x70\xdf\xca\xf7\x07\x51\x7c\x0c\x3c\x8b\xf9\x05\x63\x68\xea\x89\x96\xd1\xbb\xe8\xd4\x48\x7d\x3b\x4f\x23\x87\xd0\x58\xfd\xb9\x5a\x3e\xb7\x4e\xfb\xfe\x76\xb1\xdd\xaf\x7f\xac\x36\xdf\x56\x0b\x1f\x21\x4e\x83\x58\x2b\x18\x06\xee\x6d\x4a\xca\xb5\x12\x08\xbc\x61\xf5\x08\xef\x23\x5f\x7d\xfc\x40\x29\x4d\x42\xc4\x5a\xac\x6e\x6f\xb7\xfb\xdd\x7a\xff\x6d\xb1\x5b\x7e\xdb\x93\xab\xc5\xe3\xf7\x95\x77\x92\xd3\x30\xe1\x7c\xc0\x75\xf1\x53\x64\xcd\xe0\x18\x4d\xc3\x44\xa0\x37\x67\xf3\x3c\x6b\xd3\xfd\x5d\x48\x62\x2d\x59\x44\x22\x6f\x21\xcf\xe9\x7d\xa9\x46\x82\x9f\x2c\x48\x23\x6e\xe7\x9b\xc5\x15\x3c\x89\xfc\x11\x9a\x5e\x07\x66\xd6\x5c\x49\x23\x4d\x89\xe3\xca\xb5\xa5\x37\xeb\x7e\xd2\xa4\x09\xb1\x10\xb6\x03\x58\x4f\xdb\xc9\x73\xac\xbb\xe1\x49\x64\xa2\x6c\x56\xc1\xf2\xc7\xcc\x95\x28\xb2\x20\x65\x81\x15\x81\x42\x5f\xe0\x1a\xf0\x2d\xc6\xc4\x80\x2c\x48\x79\x08\x69\x17\x03\xbf\x2a\x45\x75\xa1\x89\x31\x79\x74\x1e\x01\xee\x08\x32\x3b\x5c\xe5\x59\xa1\xbb\x1b\xc5\x20\x13\x5f\x85\xe0\x36\xa8\x0b\x2a\xb0\xc9\xad\x84\x1e\xb1\xca\x0e\xfc\xc2\x94\x83\xad\xaa\x3b\x40\x73\x93\x15\x3e\xaf\x31\xd4\x42\x77\x1d\xd3\x48\x86\x9e\x54\xc0\x16\xee\x66\x32\x87\x6b\x68\x44\x96\x4f\xac\xfb\x54\x84\x09\xb8\xe9\xfb\x80\x59\xa7\x07\x98\x9e\x97\xa9\x88\xc3\x38\xed\x16\xb4\xe3\x5b\x99\xea\x77\xb1\x20\x95\xca\xc6\x53\x16\x45\x93\x35\x9d\xc2\xf1\xef\x0d\xdb\x54\x02\x0d\x92\x41\xe2\xd1\x55\x06\xd6\xad\x99\x32\xe3\xdb\x8f\x02\x7d\xa9\x52\x04\xe7\xea\x23\xbc\x2f\xcf\xa7\x4f\x16\x85\x32\x1c\x11\xef\xb5\x70\x82\x24\xf5\x8f\x76\xde\xfb\xa1\xd5\x5c\x61\x66\xe4\x7a\xfb\x74\xbf\xdb\x2f\xfc\x9f\x21\x01\x1d\xf5\xa5\xf5\x77\x1a\xf9\x17\xbb\x56\x21\x10\x39\x71\xcc\x0a\xf7\xc8\xa0\x87\x7e\x7a\x0a\x4a\x86\xae\x22\x46\x23\x05\x73\xfd\x32\xdd\x2c\x53\x30\xd4\x25\x26\xbb\x4a\xbe\x2f\xfd\x8b\xd4\xc4\x4a\x39\x98\xcb\x75\x86\xb8\xc2\xc9\x57\x30\x89\xa1\x83\x9a\x90\x3d\x49\x47\x67\x4e\x6a\x78\x84\xfa\xa1\x68\xf7\x6d\x9b\x4a\x34\x70\xf0\x51\x1a\x11\x04\x04\x07\xe2\x54\x95\xff\x06\xd5\x38\x65\x92\x1b\x91\xe5\x5d\x0f\x22\x43\x57\xff\xd1\x85\xa6\x2e\x13\xbf\x22\xa0\x51\x62\x8b\x2f\x9e\xca\x62\x52\xe7\x20\x82\xc4\x06\xb5\xdb\x3d\x53\x14\xaf\x2e\xc1\x60\x0b\xdc\xff\x18\x06\x61\x45\x6b\x91\x92\x21\x36\x7e\x3c\x7c\x22\x50\x91\xa7\x10\xb9\xca\x0a\x4f\x28\x34\x57\x2b\x23\x02\x43\xf0\x38\x2e\xce\xc7\xe5\x8b\x38\x42\xf3\xb7\x63\xf7\xf5\x6f\x46\x22\xcb\x06\x8b\xc6\xc2\xf1\x74\x11\xea\xf8\x2a\x08\x3e\x64\xc3\x3d\x0f\xac\x52\x41\x25\x8f\xec\x38\x1c\x0e\x39\x38\xf4\x22\x32\x34\xf8\x9f\x8d\x8c\xc2\x3d\xd5\xf6\x68\x3f\xd9\x8f\x0c\xde\x7f\x66\x85\x2e\xdf\x27\xe3\x96\xa8\x48\x0e\x77\xb9\x91\xfc\x02\x0b\x04\x93\x21\x20\xeb\x32\x96\xda\xac\x6a\x4b\x1d\xfd\xf5\x84\x12\x0c\xa8\x57\x3e\xb8\x3a\x17\xc5\xe4\x03\xf0\x24\x48\x3b\xb9\xc3\xba\x3c\xc2\xba\x79\x81\xaa\xa3\x8f\x6c\x7b\xa4\x29\x1f\x94\x66\xf9\xc3\xf6\x6b\xf3\x5e\xa4\x31\x51\x56\x3d\x32\x3b\x2d\x45\xed\xb3\x3c\x42\xa8\x20\xee\xc2\x3c\x98\xca\x02\xed\x30\xf6\xf5\xd5\x04\x9e\x22\x24\xb5\x1b\xd3\xc3\xe2\xcf\x7d\xcf\x9d\xef\x55\xdc\xb0\x03\x47\xa4\xba\x95\x4c\x5f\xfd\x2f\x25\xf6\xab\x52\xf2\x1f\xa3\x7f\xbb\xd7\x95\x5c\x0a\x97\x45\xd1\x99\x33\xe9\xfd\xcd\xda\xc1\x4f\x7d\x9a\x22\xa4\x93\x6f\xa3\x12\xab\x28\x76\x70\x75\x13\x39\xfa\x2b\xf7\xa2\x38\x9c\xc5\x01\x3a\x45\x9d\xb6\x67\xca\x30\x03\x6e\x61\x89\xd1\xde\x3e\xdc\xad\xa8\x9f\x5b\x03\x91\x05\x01\x9e\x39\x75\xd7\x5d\x24\x68\x06\xb6\xe7\xde\xf3\x69\xd5\x1d\x2f\x42\x49\x40\x27\xb8\x5d\xc1\x7b\x1b\x0b\x9c\x3e\x13\x08\x9c\x0f\xe7\xd3\x04\x88\x26\x74\xa0\x30\xeb\xa5\x21\xef\xb4\xd2\x06\xad\x3c\x46\xf7\x3f\x2b\x4c\x27\xf1\x41\x7c\xfe\x56\x00\xb7\x1c\x38\x96\x3c\xf5\x11\x7e\x21\x99\x78\xd7\x9a\x52\x4d\x51\x95\x7f\xc2\xb0\x85\x6d\x29\xe6\x37\x4f\x67\xf9\x1d\x3e\x7a\xed\x8e\x01\x3e\x40\x80\x32\x09\x19\x33\x65\xcf\x91\xc2\xb1\x40\x06\x3a\x42\xd4\xe7\x6d\x07\x88\xbc\xab\x1f\xcb\xe6\x06\x79\x76\x10\xda\xd1\x3a\x50\xc3\x1d\x59\x12\x9d\xea\xa8\x87\xe9\x2d\x45\x51\x16\x99\x12\xf9\x4d\x59\x1d\x45\x33\x7c\x0e\x49\x63\x2b\xb3\x7c\x3a\xd7\x2f\xcb\x3c\x1b\x12\x80\x8f\xa6\x8c\xa4\x22\x44\xc8\x81\x2d\x33\x2b\x2f\xb0\xce\x92\x82\x41\x6b\x68\x55\x34\x55\x79\xfa\xd8\x8d\x38\xcc\xdb\x76\x63\x6b\x51\xa4\xcd\xdb\xf4\x5f\x58\x86\x32\xe8\x69\xef\xab\x0c\x6a\x47\x37\xea\x9b\x15\xc3\xea\x16\xd4\xf2\x83\xbc\xb4\x34\xff\x23\x25\xc8\x2f\xeb\xc0\x64\xa8\x13\xe4\x77\xa8\xb3\x43\xd1\xe1\xcb\xfb\x07\x0f\xb5\x4c\x8c\xff\x14\x59\xb1\xf8\xcc\x51\x96\x51\xac\x30\x6a\x80\xfc\xb3\x37\x55\x89\xd5\x2c\xe3\x2e\x31\x8b\x30\x2b\x63\x75\xa0\x1a\xba\x3f\x95\xdd\x7b\xc4\x9c\x88\x21\xa6\x65\xb4\x6f\xcb\x24\x60\x49\xe0\xf9\xfa\xdb\x43\x78\x48\x17\xc7\x02\xc9\xe2\x34\x19\xab\x6e\xd5\x5d\x93\x49\x4d\xd8\x23\xc0\xb2\xe2\xe0\x08\x26\x66\x4e\x2c\xc9\x03\x8d\x87\xd2\xcf\xe5\xc3\xca\xdf\x80\xd3\x20\x71\x8b\x1a\x43\x5c\x1b\x30\x77\x85\x2a\x8f\x97\x03\x3c\x7e\x5b\xae\x6d\xe9\x61\x2d\xde\xe0\xa1\x3e\x5c\x39\x5b\x7e\xc6\x4b\x94\x82\x10\xb4\xf8\x4e\xa3\x78\xb0\x14\x61\x18\xa6\x3d\x65\xc6\x40\x0e\x66\x3c\xfb\x84\x0c\x51\x2e\xb7\xfe\xa8\x1b\xe4\xbc\xea\x89\x42\x1f\x3a\xd3\x51\x0a\x6d\x45\x6b\x2d\xf7\x81\x15\x00\xec\x0b\x7a\x27\xcb\x54\xca\x88\x61\xc1\xe1\x51\xbc\x02\x22\xe7\x7e\xeb\x75\xce\xee\xf1\x52\xc5\x14\xd3\x5c\xa7\xaa\x6c\xa0\xb7\xc5\x67\xc6\x5e\x6b\x82\x6c\xd0\xc8\x0d\x0f\x7b\x64\xd7\xda\x6b\x50\xd9\x51\xe4\xf5\xde\x08\xd5\x27\xc0\x24\x44\xc6\x78\x48\x19\xd2\x0f\x3d\x17\xa2\xcb\xb3\x6c\xa1\x79\x12\xea\x55\x74\x56\x9a\x84\x38\x41\x6d\x93\x5d\xd5\x9e\xe9\xfe\x8f\x09\xc1\x8c\xf3\xe2\x74\xca\x1d\x3c\xf9\xae\x70\xc6\xce\xba\x1a\x42\x2f\xfc\x05\x3c\xc5\x94\x0b\x22\x1b\xf1\xf1\xa1\xde\x95\x17\xb5\xdd\xbd\x8d\xda\x5d\x27\xf0\x70\x2c\xdf\x0b\xc0\x58\xef\x27\x2b\xc8\x30\x89\x91\xe6\xbd\x63\xda\xd9\x1b\xf8\xcd\x1c\x53\x81\x4c\xba\xd0\xc5\xfb\x34\x94\xa2\x02\x15\x13\xdc\xe0\xb3\x0a\x14\xca\x62\x0c\x21\x43\x2a\x30\x09\x77\x05\x90\x83\x31\xd8\x36\xfd\x71\xa7\x48\x10\x23\xef\x70\x23\x5e\x61\x54\xc5\xa7\x08\x27\xa9\x27\xe5\x77\xb4\xbb\xe3\xd5\xae\x08\x8f\xd1\x8c\xbc\xb9\x5f\x2f\xbf\xfb\xcb\x42\x22\x4c\x9f\xea\x3e\x9e\xaa\x6c\x4c\xf9\xd1\x76\x09\xad\xe7\xe2\xc5\x3c\x6b\x57\x48\xa9\xa7\xfd\xe2\x34\x26\x9e\x39\xa5\x12\xb9\x4b\xa6\xb4\x0e\x7e\x8f\xb0\x54\x51\xc0\xd1\xbf\xdf\xb7\xeb\xbf\xfd\xd1\x2f\xdc\x66\x15\x45\x1c\x01\x32\x68\x3a\x3d\x66\x9d\x5a\x98\x6f\x4e\x23\x7c\xf8\xc5\x6e\xd9\xdd\x5e\x01\x75\xb4\xbe\x0e\xc6\xfa\xc7\x2c\x3a\xdb\x77\x37\x96\xea\xed\xe1\xee\x71\xbf\xfd\xb6\xd8\xac\xf6\xeb\x9b\xfd\xd3\xfa\x67\xe7\x94\xab\x38\x06\xaf\x7f\xec\xb6\xab\x27\x91\x55\xcb\x73\x53\x1a\xf3\x29\x13\xb2\xbf\xd6\x30\x9c\x68\xbb\xd5\xe2\x61\xbf\x5c\x3c\xee\x97\xf7\x8b\xbb\x87\xfd\xe2\x66\x37\xb8\xbf\x51\x96\x87\x36\x07\x51\x59\x2c\xa5\xdf\x2a\x55\x92\x06\x56\x06\xed\x9c\x37\xd9\xfa\x1d\x23\x65\x9f\xcd\x6a\x95\x08\x69\x62\xaf\xce\xba\xc8\xf3\x4e\x2e\xb4\x6d\x93\x14\x01\x0d\x05\xbc\x0f\x0c\xfa\x8b\xcd\x41\x31\xa0\x61\xcf\x27\x8f\x62\xde\xe7\xb1\xc5\xae\x78\x90\xb8\xb2\x7a\xfb\xe1\x1c\x4a\x63\x92\x9a\x1d\x8f\x03\xa7\x31\xe6\x48\x7a\x72\xe3\xed\x67\x88\x51\xc5\xc3\x10\x89\x12\xc4\x80\xad\xe5\xb3\xae\x91\x45\xc0\xdf\x66\xa6\xb9\x75\x0a\x1d\xff\x5c\x1d\x74\xfc\x56\x49\xec\xd3\xbb\x8f\xf0\x3e\xd2\x0d\x6f\x5b\x0d\x17\x7d\xd6\x06\xc3\xef\x36\xb9\xe2\xda\x53\xd0\x12\x85\xa0\x76\xcb\x0d\xe4\xe2\x63\x37\x74\x91\x5d\x1f\x11\x29\x8f\x98\xb9\xcf\x8a\xd7\x8b\xec\xf3\x64\xc8\x44\x12\x45\x96\x77\xb9\x6c\x6d\xfb\x07\x68\x5e\xca\x4f\x8b\x40\xdc\x35\x12\x34\x6e\x0e\x76\xc3\x5e\x8a\x3c\x97\x42\xbd\xde\x8a\x7a\x98\x4d\x50\x2a\x06\xc4\xcd\xbd\x1e\x1a\x1b\x29\x5c\xb6\xce\x66\x5f\xb8\xa3\x94\x4e\x31\x8b\xf2\x22\xea\x17\x18\x9f\xeb\x4a\xf3\x14\x4b\x36\x96\x9b\xfb\x13\x54\x0f\x99\xaa\x4a\xe4\x67\xe8\xda\x53\x89\xc0\xbd\xdb\xa7\xcd\xf5\xf6\xbf\x86\x16\x95\xd2\x22\x0e\xfb\x9a\x06\x2b\x61\x37\xfc\x36\x63\x5f\xad\x7f\x2b\xad\x8d\x27\x7a\x58\x60\x16\x61\x06\x02\x35\x3f\x1e\x10\xb0\x24\x1e\xe7\x9d\xfc\x9e\xf0\xf5\x40\x42\x1a\x68\x87\x56\x31\x59\x75\xf4\x44\xe2\xbe\xd5\x31\x44\x1d\xa0\xf9\x91\xd5\xc2\x0e\xee\xd7\x4f\x62\x58\x8c\x22\x67\x59\x8d\xe0\x01\x97\xbe\xbb\x29\xab\xbb\x42\x67\x6f\x99\x3e\xf7\xfb\xa3\x11\x82\x5b\x5e\xea\x3c\x07\xed\x9c\x9d\xf9\x39\x62\x84\xc4\x32\x56\xf5\x22\x2a\x84\x9f\x2f\x0a\x8d\x81\xbf\xe6\xe5\x4b\x08\xa8\x0e\x08\x4f\x88\x97\x17\xde\x42\x33\xcc\xc6\xf9\x2e\x34\x49\x9d\xc5\x8f\x4c\x56\xd3\x5a\x32\xdf\x8d\x59\x41\x39\x61\x8b\xda\x07\x11\x3b\x1d\xf0\x08\xa3\x3b\xdb\xac\x38\x9c\x73\x51\x5d\xef\x7e\x60\xc0\xcd\x0c\x84\x55\xdb\x6e\x2a\xc6\x1c\xfb\x6a\xfd\xfc\xb8\x5c\xf5\x7f\x55\xbe\x10\x69\x95\xa3\x28\x4e\xeb\x7f\x8f\x0f\x1c\x4d\xa8\x0a\x89\xdf\xf1\x9e\x00\xaa\x91\x25\xae\x49\xc8\x07\xb9\xd6\x95\xc6\x42\xc6\xcb\x48\x9a\x26\x4c\x60\x46\x29\xab\xaf\x2b\xf1\x7e\x11\x0a\x9d\x8c\x1d\x49\x05\x52\x49\x64\x0d\x1c\x97\x68\x07\xda\xca\x89\xfa\xe7\x0b\x14\xe3\xd4\xbf\xbf\x42\x69\x04\x7c\x54\xa2\xd0\xe5\x71\xe8\xfa\x68\x02\x96\xbd\xf0\x98\x15\xad\x55\xf5\x13\xb2\x41\xea\x51\x53\x6a\x88\x9b\xf9\xc3\x12\x5f\xdf\x1a\x8b\xd4\x74\x2e\xa8\x85\xd1\x6e\x9b\x6a\x1a\x8d\xd1\x94\x11\xd1\x09\x83\x77\x7a\xf8\xbe\x31\x0d\x90\xab\xc4\xa2\x91\xa0\x33\xa3\x7c\x7b\xc8\x38\x09\x9c\xd5\x59\xd5\xa3\x67\x6f\x47\xb7\x67\xd2\x7d\x10\xc5\xc7\x53\x55\xfe\xca\x06\x54\xa5\xb3\xb3\x56\x47\x9a\xd8\x9a\xe1\xcc\x34\xad\x5f\x36\x5d\x39\xc3\x7d\x59\x47\x9a\xe1\x00\x9d\xda\xc5\x7b\x0b\x45\xe0\x7f\x3d\x0e\x25\x7a\x61\xa6\x0f\xed\xea\x38\xa2\x28\x3c\xf8\x43\x14\x8d\x38\xc0\x70\xf7\xd1\xb1\x00\xeb\xcf\x9d\xab\x49\x39\x83\x4e\x02\xa1\x4d\x07\x0e\xb8\xca\xf4\xd0\x62\xf0\x31\x23\x9d\x24\x09\x06\x16\x75\x35\x52\xb8\x68\x5b\x52\xab\x8b\x63\x15\x9e\x57\x9a\xc6\x31\x49\x5b\x83\xd7\xab\xce\xb8\x7e\x2c\x80\x54\x7a\xcf\x0d\x49\x78\x7b\x9c\x8c\x66\x54\x27\x61\xc7\x5e\xf8\x94\xfd\x82\xbc\x6f\x4b\x2c\x61\xba\x14\x75\xa6\xae\xc5\xc7\x18\xa5\xa2\x99\x08\xb0\x46\xbd\x33\xb8\xbf\x7f\xa8\x29\x1b\x8e\xe6\x24\x41\xe5\x99\xfb\xf2\xb0\x1d\x1d\xe8\x9a\xa7\x24\x16\x17\x56\xe7\x64\x8c\xd2\x08\x74\xe0\x49\x07\x73\x3d\x06\x6d\x4f\x56\x48\x6a\x98\xad\xec\x6f\xf7\x84\xbb\x06\x8e\x1b\x61\x0c\x16\x33\xfd\xfd\xd9\x86\x24\x93\xd4\x6a\x03\x89\x5f\x7d\xad\xa7\x96\x92\xf1\x76\x4c\x16\x0f\x57\x8b\xed\x76\x71\xbd\xde\xec\x77\x3f\x3d\x4e\x4a\xab\xc8\x8a\x3a\x7a\x18\xe4\xf7\xcd\xdd\x64\xe1\xb5\x76\x47\x97\xb9\xbc\xee\x52\xae\x3a\xeb\x6e\xc1\x13\x4c\xfd\xaf\x16\x9b\xfb\xbf\xf6\x37\xeb\xe7\xc7\xeb\xd5\x66\x3b\x88\x55\x69\x4d\xad\x46\xa3\xe5\xe4\x5b\x38\xb2\x97\x71\x0c\xdd\x77\x05\x19\x58\xbd\xc8\x87\x51\x41\x9c\x06\x02\xa1\x1b\xbb\x76\x34\xf0\x7f\xd3\x3d\x02\xb8\xc2\x78\xb9\x05\xb5\x8c\xe6\xdf\xe0\x70\xf4\x0e\xa6\x06\x61\xb3\x90\x4d\x76\x04\xaf\x83\xc3\x02\x6d\x22\x6b\xcd\x5a\xf3\xed\xea\x5c\x15\x57\x25\x02\x39\x66\x4f\x25\x08\x84\x74\x40\xb0\xe6\x5c\x39\xee\x8f\x23\x52\x35\xab\x73\x55\x0f\x72\x92\xbe\xbf\xd4\x09\xf1\x9e\xfb\xb9\x6e\x40\xb7\x2e\x0c\x60\xd9\xe5\x78\xd3\x01\xc2\x13\x64\x22\xb1\x9e\x32\xba\xe7\xa7\x1c\x9c\x7c\xbe\x9f\x55\x10\x52\x81\x33\xd7\x74\x80\x06\xf4\x87\xc6\xf3\x1b\x42\xa5\x70\x7d\x65\x45\xd6\x3c\x64\xa2\x6c\xff\x37\x0b\x62\x82\x28\x52\x18\xdf\x1e\xb0\x74\xfb\x16\xc9\x11\xd4\xd7\x7a\x1d\x57\xe7\x8f\x0b\x78\x9e\x1f\x59\x88\xa5\x41\xac\x0b\xea\xa0\xfd\x28\xa7\xe9\x14\x48\x24\xc5\x78\x63\xbb\x21\x3e\x89\x8f\xd6\x22\x77\xd6\xe2\x4c\x3d\x2d\x24\x3a\xc4\x1d\x09\xde\xca\xfc\x0d\x30\x24\x54\x2e\xde\x44\x23\x2e\x2b\x22\xbf\xb4\x48\x80\x11\x40\xd8\x1f\x62\xa6\xf1\x1c\xd9\x02\xe8\xf6\x3d\x6f\x45\x7d\xa1\xdb\xd8\x5e\xc0\x42\x2f\xa8\xb8\x3d\x81\xca\x4c\xa6\x50\x0f\xb4\xfa\x07\x22\xb6\xee\x16\x9c\x09\xc4\x37\x1f\x4b\x37\x13\xb8\x6f\x50\x44\x7a\x80\xc5\xde\x7e\xd9\x5f\x8f\xf0\xee\x13\x72\x8b\x42\x5b\x40\xbb\x1f\x7c\xae\x6d\x70\x00\x57\xc5\xb7\x19\x0e\x6c\xd7\x2f\x15\x09\xa1\xc8\x08\x5d\x65\x83\x1c\x1b\xa4\xc6\x24\x41\x37\x99\xae\xce\x1f\x63\xcd\xd1\xf1\x4d\x84\x20\x78\x62\xf4\x24\xc8\xdd\xd7\x10\x90\xa0\x45\xd2\x54\xe2\x0d\x6c\xdd\xdf\x4a\x54\xc5\xe0\x49\x65\x62\x51\x6a\x35\x34\xdb\x63\xdd\x07\x63\xb2\xb2\xe8\x9c\xde\x3e\x42\x02\xd2\x70\x7f\x40\x3f\x17\x8d\x5d\x12\x28\x17\x0a\x39\x1c\x46\xf3\x61\x0a\xcd\x74\x2a\x02\x2c\x00\x1d\x08\x0f\x00\x1a\xd8\x6d\xbe\x91\x24\x48\xc0\x56\x56\x07\x51\x64\x7f\x43\xe5\xe3\xbd\x00\x71\x1c\xab\x6e\xed\x7a\xbf\x71\x3c\x14\x90\xda\x62\x46\x1b\x82\xb4\x99\xc4\x4d\xaf\xb1\xcb\x02\x30\x24\xc2\x60\x65\x6b\x8d\x4e\xae\x36\xad\x43\x4f\x2c\xae\xa4\x0b\xdc\x98\x40\x1b\x64\x9b\xf0\xac\xf1\xd6\xe2\xfa\x6f\x38\x9d\x20\xef\xe3\x28\x83\xac\xe0\xf8\x9e\x84\x53\x24\x3b\xc6\x99\xf0\xb4\xea\xdd\x60\x43\xb8\xc4\xad\xf8\xb9\x40\xd8\xc5\x60\xff\x34\x24\x4d\x31\x78\x9d\x15\x7a\x7c\x2a\x99\x90\x69\xac\x2c\x6a\x4d\xca\xa7\xb2\xf4\xab\xdd\x44\x8a\x60\x08\xd5\x3a\x42\xff\xd5\x2e\x65\x14\xd6\x73\xcd\xb1\x64\xa4\xb7\x5c\x06\x6c\x7e\xb3\x06\x8b\x89\x75\x88\x83\xf4\xd3\x6e\x2a\xbb\xd2\x65\x42\x27\xe3\x95\x44\x96\x3d\xe3\xe7\xb7\xf5\xdd\x76\xbc\x31\x99\x24\xb6\x98\xde\xfd\xd1\xd2\x49\x8f\xbd\xda\x49\x5f\xa1\x48\xdc\x61\xc9\xed\xb6\xe2\xc4\x6e\x3e\x71\x16\x4d\xa2\x52\x3c\xa5\x1c\x47\xc1\xcf\xd5\xdd\xf2\x5c\x37\xe5\x71\x5e\x13\x86\x05\x86\x05\xb1\xc4\xca\x6e\xf4\x1c\xc6\x86\x9d\x61\x11\xa5\x1d\xe0\x69\xb1\xbb\xc0\xd3\x5c\xe6\x8a\x0d\x4b\x25\x6f\xe7\xe9\x76\xe5\x8f\x67\xc3\x03\x4e\x2d\x8f\xae\x27\x84\x1e\x3f\x02\x8f\x99\x2f\xfe\x7c\x7a\x11\x35\xac\x6c\xc1\x99\x25\x06\xfc\x9a\x34\x6f\x70\x13\x6d\x83\x33\x5d\x68\x6a\x40\xb8\xe3\xba\xa4\x2a\xa0\xc4\x93\x39\x3c\x89\x4f\x22\x1f\x46\x24\x89\xb6\x42\x57\x9d\x19\xb5\x14\x75\x56\x5c\xf2\x74\xd9\xd7\x9f\xac\x67\x77\x17\x69\xac\xd8\x5c\x79\x82\xe2\x56\x1c\xb1\x9c\xef\xb1\x9c\xb0\x00\xb3\xc0\xe8\x90\x29\xe3\x2d\x93\xfe\xe0\xed\x26\xb6\x86\x10\x61\x59\xc7\xb3\x85\x37\xa4\xf6\x71\x53\xff\xb4\x40\x52\x3c\x0e\x10\x91\xd9\x9c\x25\x46\x8f\xfb\x7d\xcc\x98\x24\xa4\x43\xdb\x68\x77\x2e\x7a\x36\x10\xdf\x07\x62\x74\x8f\x8e\xa5\x87\x70\x92\x20\x60\xb6\x24\xc6\x55\xf6\x0e\xfc\x39\x12\x04\x22\x02\x97\x52\x5c\x38\xe2\xdb\x0b\xa1\xd0\xb9\xb1\x25\x01\x4d\x04\x66\xc7\x57\x7f\x3e\xad\x96\xbb\xd5\xb5\x2d\xc3\xf4\xf7\xa5\xd2\xaa\x47\xbc\xc1\x54\x91\xba\x6d\x54\x04\x09\x2f\xb7\x8d\x28\xb4\xa8\xf4\xfe\xd2\xf2\x22\x01\x35\x2c\xb2\x72\x63\x4a\xe4\xca\xee\x2d\x7d\xc4\x83\x04\x21\x93\x88\x62\x31\xb9\x38\x3c\x6f\xa7\x09\x72\xdf\x29\xa5\x98\x10\xba\x7a\x5e\x0e\x76\x1f\x12\x44\x82\x44\x2e\xf7\xf9\xe8\xd8\x8c\x2d\x81\x46\x67\xc7\x90\x20\x4e\x04\x06\x5e\xac\x08\x24\x06\x44\x30\xea\xe2\xa8\x22\xc6\x3f\x94\x90\x30\xe5\x3e\x7d\x91\x43\x77\x93\x24\x24\x54\x8d\xa1\x46\xba\xea\x1a\xa5\x8e\x9c\x78\x66\xaf\x55\xfb\x31\x22\x47\xf5\x3d\x95\x46\x7c\x0b\xf2\xfc\x78\x0d\xc2\x0b\x28\xde\xc5\xba\x1a\x3f\x23\xa3\x1c\x85\x07\xec\x0e\xb9\x6f\x5a\x33\x67\xa4\xc5\xd8\xf6\xd1\x4c\xb8\x47\xea\x6c\x76\x12\xa4\x01\x47\x60\x3f\x0a\x84\xec\x5e\x2a\x80\x01\x48\x90\x04\x29\x17\xc8\xe7\x88\x76\xee\xb6\xf1\x10\xe6\xb6\xc1\x0a\x8b\x58\x94\xe1\x60\xd3\x19\xbf\x9d\xd0\x16\xe1\xdb\xfa\x21\xa2\x51\x2f\x59\x71\x58\x1d\x0e\x43\xce\x15\xd7\x51\x52\xed\x59\xd2\xdd\xa1\xb1\x69\x77\xd2\x69\x2f\x13\x52\x4b\xc9\xde\x9a\x2e\xd0\x61\xcd\x26\xdd\x54\x62\x59\x6b\x5d\xe8\x4a\x9c\x6e\x72\x37\xee\xdd\x68\x28\x29\x6c\x76\xb6\x76\xd9\xac\xf5\x1b\x54\x55\xa6\x61\xce\x52\x25\x81\x4e\x04\x9a\xd2\x67\x1b\x32\xe8\x64\x32\xfc\x70\x68\x63\x51\x70\x59\x8d\x76\xac\x3e\x4e\xae\x87\x58\x53\xd3\x69\x8c\x4d\x77\x3d\x12\x80\x96\xd6\x6f\x77\xe7\x74\x31\x0c\x8d\x90\x00\x20\xb1\x80\xd2\xf5\xed\x6a\x34\xdb\x4d\x98\xda\xe2\x7f\xad\xf7\x60\x23\xc5\x83\x8d\x9e\x04\x06\x12\xc3\x7d\x5e\xcf\xee\x2d\x23\x93\x85\x04\xc6\x28\xd6\xf3\x1d\xef\xaa\x4c\xc2\x80\x08\x97\x90\x80\x70\x0c\x2c\x5d\xbf\x88\xea\xd8\x5b\x79\x84\x04\xdc\xd1\x8c\x56\xbf\x07\x54\x8e\x5e\x96\x04\x0a\x2c\x85\xc5\xc7\x06\xcc\xd0\xc0\x21\xed\x9b\x22\xa9\x9f\x9d\xc8\x3e\xae\x7b\x57\xd4\xcd\x28\x3c\x36\x1a\x5c\x42\x84\xc4\xe2\xef\x2d\x20\x17\x39\x12\x54\xcc\xff\x32\x01\x6d\x61\xa7\xe5\xe9\x49\x7c\x0c\xdf\x26\x8c\x0d\x77\x52\xf7\xed\x34\x3f\x41\xf7\x48\xa1\xb6\xc9\xc1\x53\xa6\x5e\x6f\xca\x41\x50\xf7\xb7\xaa\x1a\xed\xc5\x10\x83\xd3\x48\xd5\xdf\x2f\xeb\x85\x3f\xb9\x2a\x0a\x52\x9c\x4d\x0f\x77\x8f\xfb\xd5\xee\xdb\xfe\xe6\xf9\xf1\xda\x3f\x4e\x14\x47\xdc\xc2\xbc\xe4\x39\xcb\xb5\x8b\x75\xf6\xd0\x08\x42\x22\xa6\x91\x46\x7d\xbb\xdb\x2c\x91\x02\xb8\x6b\x10\x29\x3a\xad\x1e\xaa\xb9\x71\x89\x9f\xf1\x5c\x25\x91\x22\xa1\x47\x76\xef\x2e\x64\x00\x18\x21\x71\xa2\x50\x8f\x79\xf7\x82\xfa\x41\xfe\xf6\xb1\xe2\xc8\xa8\xfd\x4b\x8b\xa9\x02\xde\xd0\xfa\x68\x3b\xa6\x58\xb6\x74\x85\xa5\xf6\xe3\x7b\x27\x24\xf5\xb2\x9f\x4f\x67\xb9\x9a\xf0\x91\x10\xc2\x22\x8e\x27\xa9\x53\x29\x40\x55\x90\x45\x33\xb3\xb1\x12\x16\x5b\xbd\xe6\xbb\xc7\xd5\x9f\xc3\x35\x43\xb8\xe1\x58\x21\x90\xa9\xd2\x13\x94\xbb\x96\x34\x0e\xc1\xad\xd2\xd6\x1a\x98\xdd\x0a\x48\x2a\xa2\xd4\x31\x94\x5e\x35\x0a\x0f\xae\xf9\x93\x83\xa4\x8a\xe3\x38\xf9\xf1\xde\x6e\x9f\x9c\xb8\xe2\xfc\x3c\x96\x11\x67\x64\x88\xa3\xf6\xae\xd3\x7c\x40\x80\x10\x69\x52\xe9\xa9\x57\xba\xec\xed\x65\x6a\xb8\xed\x28\x30\x53\x89\x7c\x7b\x84\x2a\xcb\x49\x60\x6d\x77\xff\xf2\x8a\x5a\xe2\x12\xc4\x26\xd7\x4e\x09\xbe\xf7\x87\xfa\x9b\x29\x61\xa2\x60\xf8\x5a\x0d\x9c\xc2\xc9\xab\x2b\x69\xb3\x27\x4f\xa2\x6a\x3e\xc6\xe9\x19\x42\x74\xfb\x40\xe8\x65\xff\xf1\x05\x69\x10\x21\x3a\x8a\x82\x1e\x03\xed\x4b\x4a\xa6\x7b\xcd\xe0\xc9\x74\x12\x75\x11\x3b\xd1\x3c\x8a\x63\x77\x5a\x13\x93\x84\xd2\x5a\x70\x57\xf6\x8d\xfe\x18\x70\xdb\x8f\x7f\x97\x06\x3a\xe4\xee\x3b\xd8\x78\xbe\xb5\xac\x0f\x5f\x27\x93\x09\x0d\x8c\x55\x32\xd2\x59\x8d\x60\x13\x87\x1b\x75\x8f\x40\x49\x2c\x90\x9a\xfa\x7a\xf1\xd7\x76\x4f\x79\xf7\x67\x16\x3a\x00\x8a\x3b\xf3\x31\xf0\x3b\x89\x4a\x13\x4a\x09\xa0\x65\xb5\x11\x15\xf2\x72\xce\xc8\x30\xb6\xbd\x80\xc7\xac\x67\x63\x77\x5c\x2c\xf3\xf4\xe9\x93\xa7\x0f\x13\x2b\x53\x63\x57\xd6\x76\xb5\x59\x3c\x7d\xbb\x7b\x18\x7f\x57\x1a\x26\x96\xb1\xf6\xf3\x24\x30\xa1\x61\x1a\x49\xcb\x8e\xf7\xeb\x7c\x1c\xae\x3c\x1a\xc5\x06\x37\xa0\xab\xdd\x72\x50\x22\x46\x68\x24\xa4\x09\x7b\xfa\x03\xab\x90\x53\x77\xad\x2a\xe1\x0e\x80\x62\x3f\x07\x56\xf4\xbd\xf5\x48\x62\xdf\x4f\x27\x24\xec\x99\xfb\x2d\x84\x7c\x76\x0d\xd3\x38\xd2\xa9\xdb\xed\x6f\x00\xea\xeb\x01\xbe\xdd\x05\xb3\xc4\xe1\x52\xc3\x6b\xf2\x9e\x89\xe0\x71\xec\xf9\x5f\x0f\xe7\xea\x73\x63\xed\x93\xeb\x65\x82\x48\xdf\x3d\xb2\x71\x5e\x72\x27\x11\xca\x02\x19\x25\x2e\x92\xb6\x9c\x4a\xcb\x30\x42\xb9\xd0\xb8\xc1\xb8\x77\x75\x10\x2f\xbf\x21\x53\xae\xc1\xc8\xfe\x8b\x9e\x4f\x50\xbd\x5d\xd0\xe7\x11\x9a\xf2\xc0\x31\x9f\x14\x48\x56\xe4\xfe\x2c\x5a\x73\x0b\xcb\xe5\xef\x1e\xf7\xdb\xe7\xa7\xa7\xfb\xbf\x90\xde\xf5\xe9\xdb\x62\xbb\xda\xd3\xae\x5b\x1c\xe0\xb6\xd1\x81\x4b\x77\x2f\x3d\x3e\xdb\xf7\x11\x04\x6d\x08\x97\x4e\xf3\xce\xee\xee\x97\x7b\xf0\x9b\xb2\xfa\xfe\xf3\x82\x12\xd5\x5f\xac\x12\x44\xe8\x95\x05\xca\x04\x8b\x7c\x64\xe1\x50\x49\x6c\xa4\xbb\xa9\xb2\xc3\x01\xaa\xbb\xe2\x74\xee\x7e\x57\x4a\xe2\x33\x7f\x96\xa3\x34\xcf\xc5\x7e\xb1\xd8\x07\x64\x7c\x0f\x15\x58\x82\x25\xef\x7e\x5d\x23\xde\xe3\x1a\x64\x36\x04\xa5\xf4\x1b\x0d\x55\xa1\x2d\x7e\x72\x8d\xed\x52\x73\x96\x68\xbd\x28\xf4\xca\x59\xf1\xdd\x0c\x56\x22\xf0\x56\x98\x0d\x85\x8d\x7e\x5d\x6b\x9b\x93\xab\x44\x56\x63\x35\x00\xf6\xb1\xb9\xaa\xfc\x73\x89\xfa\x4f\xff\x45\x2a\x8f\xc0\xdd\xdc\x50\x2a\x5c\x30\xfb\x47\x99\x9f\x8f\x03\x86\xd2\x7e\x1e\x99\x48\x23\x28\xde\x56\xa7\x8a\x06\xb6\x2f\x65\x85\x69\x6f\xff\x06\x26\x06\x66\x4d\x2c\x9b\x49\x9f\x6a\xc8\xb4\x5d\x98\xa5\x6f\x3d\x61\xf4\xea\xb6\xb5\xa3\x10\x8d\x60\x9b\xc3\x80\x13\x1d\x74\x8a\x91\xc7\xf2\xc2\xac\x08\x03\xcd\x94\xab\x7e\x47\x38\x67\xb3\x87\x37\x28\x9a\xbd\x76\x98\xfb\xb9\xb2\x61\x12\x52\x1d\x62\x29\xbb\xca\x1a\xa1\x1d\xc8\xcb\x7c\xb6\x37\x85\x14\x6c\xd8\xca\x12\xbf\x4f\x79\xbd\x48\x18\xaa\x40\x05\x8e\xb8\xd3\x25\x4d\x66\x17\x6f\x18\xa5\x91\x66\x9e\xa7\xdc\x9a\x51\x17\x56\x7d\x98\xa4\x9c\xca\x3e\x0b\x03\xc3\x0a\x74\x12\x26\x8e\xcf\xe2\x94\x8b\x8f\xe5\x6a\x75\xbf\x9e\xbe\xe1\xbf\x92\xff\x71\x5d\x59\x10\xb9\x62\xbb\xe6\x1a\x44\x6e\xe7\xc6\x45\xf1\x00\x09\x99\x0c\x30\x1e\x7a\x25\x8a\x3c\x13\x3e\xbe\x40\x42\x06\x5d\xdd\xf7\x22\xcf\x77\x70\x3c\xe5\x36\xc3\x8e\x01\xe0\xc9\xee\x18\x32\xd0\x11\xeb\x3e\xd5\xaf\x8f\x69\xb9\x85\xeb\xc6\x43\x0b\x0a\x13\xba\xfd\x4c\xe7\x6a\xc0\x4a\x46\x42\x2e\x55\x3a\x2c\x0b\xfa\x12\x79\x43\x42\x0e\x81\xb2\x95\x46\x6f\x37\x65\xd5\x2e\x82\x2b\xd1\x99\x26\x21\x07\x83\x78\x66\x04\x0d\xa7\x93\x77\x4e\x43\x85\xd1\xe6\xba\x29\x2b\xb8\x07\x7d\x80\xaa\xbe\x2b\xee\x4e\xa6\x9b\x7a\x69\x44\x0d\xeb\xcb\xe4\x5d\x38\x60\x12\xba\x08\xd3\x38\x46\x9c\x6f\xa6\x4a\x0a\xc3\x52\x9c\xb6\x89\xa3\x5c\x7e\xfb\x82\xb5\x33\x8c\x7c\x13\x4f\x2c\x11\x5c\x6b\xcb\xee\xca\xc5\xe9\x94\x7f\x3c\x64\x39\xd4\x4d\x59\x78\x1d\xc3\x71\x6e\x8f\x84\xa9\x24\x4a\x0c\xb7\xcc\x4d\x79\xb6\x24\x1f\x1a\xc6\x4e\x7b\x98\xca\x38\x1d\x06\x86\xae\x9b\x97\xed\x4b\x79\x1a\x0b\xd5\x8f\xdf\x43\x30\x40\x23\xf6\xcf\xac\x38\xfc\x6f\x76\x96\xfe\x49\x65\x9c\x60\x8c\x40\x8b\x46\x48\x51\x77\x2f\x27\x21\x08\x02\xaf\xd9\x53\x9e\xdb\x83\xa6\xe9\xdb\x2c\xd1\xad\xdd\xcf\x36\x58\xad\xd4\x5c\xae\x5c\x1d\x06\x08\x84\x76\xd2\x02\x08\x80\x9b\xc1\xf3\xcf\x47\xe1\x48\x08\x52\xc4\x9d\x51\xd1\x6e\xa2\x1d\x68\xfd\xd2\xd8\x1b\x5f\xa8\xd2\xc0\x42\xa8\x5a\xab\x7a\x14\x6c\x26\xa1\x89\xc1\x31\x17\x16\x48\xe0\x5e\x4e\x4e\xa5\xd0\x68\x8a\xbe\x33\xa6\x63\xf6\x6e\xb5\xfb\x36\xa3\x42\xe9\x2b\xc5\x2c\x36\xdb\x31\xc2\x7c\x6a\x15\xfc\x7f\xfd\xaf\x7d\x92\x28\x48\x22\xb4\x8d\xae\x2a\x10\xaf\x9e\xea\xeb\x6b\x43\x34\x0a\xa4\xf6\xf6\xd4\x5e\xe4\xf9\x5e\x42\xdd\xec\x4b\x33\x08\x58\x44\x84\xc7\x89\xee\xc2\x64\x4f\x98\x4f\xf0\x4d\xc2\x86\x46\x50\x27\xbc\x39\xe7\x22\xab\x60\xbf\x2c\x8f\xa7\x06\xf6\xa1\xef\x44\x03\x8e\x2c\x35\xa8\xd5\xe5\x37\xdd\xdb\xbc\x94\x3e\x87\x47\x22\xca\x04\xc2\x3d\xd1\xf0\xb8\xcf\x1a\xe8\x55\x89\x48\x44\x25\x61\xda\xcd\xc6\x9b\xb2\xba\xe4\xcd\xc1\x2e\x68\x35\x78\xd2\xab\xd6\x36\x5e\x58\xc2\x92\x4f\xa9\x4a\x48\x14\x06\x71\xea\xf5\x36\x06\x6c\x84\xe3\x5b\x87\x3c\x44\x80\xd8\xb7\xbf\x9e\x46\xf1\x94\x28\x0a\x95\x9d\x34\x65\xae\xaf\x2b\x71\xe8\xf8\xcb\x48\x14\xa5\x01\xe2\x32\x7c\x1c\x65\x57\x5e\x89\xe2\x15\xa5\x23\x7c\x0f\xe0\xc4\x5a\xf2\xd0\xa1\x44\x49\x14\x07\x36\x9d\xdc\x64\xad\x75\x82\xc4\xaf\x3f\x21\x1b\x1f\x2e\xbe\x6b\x62\x79\xd3\x3b\x21\xaf\x2b\xa7\x52\xcf\x48\x94\x10\x09\xe9\x88\x28\xb5\xdb\x66\x9e\xaa\xb2\xf5\x62\x3b\xc3\x2f\x4a\xa4\x46\xf8\xd2\xc3\xe2\xcf\xfd\xd3\xf3\x66\xd9\x5a\x6c\xbe\x8d\x25\xc6\xca\x3c\xe7\x20\x2e\x77\xe5\xd1\xe3\x30\x6e\x90\x35\x7c\x7f\x70\xd0\xcf\x3b\x54\x7a\xb4\xc4\x5e\x3d\x52\x82\x44\x3c\x65\x88\xc8\x68\x7f\xef\xc7\xe2\xfe\xee\x7a\xb1\x5b\x6f\xba\x27\xe7\x29\x0f\xad\xb2\xe8\xa6\x7f\x44\x2e\x45\x68\xb1\xba\x36\xa9\x23\x2a\xfd\xc7\x4c\xd9\x2d\x89\x52\x9a\xf0\xd8\x97\x86\xfa\xab\x05\x35\x68\xea\xfb\x92\x94\x3f\x7a\xd3\x67\x02\x49\x21\x91\x6c\xbf\x2a\xb2\xe2\x8e\xb2\x91\xd3\x82\xa4\xd9\xc0\x6a\x24\xa3\x28\xb1\x6c\xab\xaf\x3d\x05\x45\x85\x8a\x10\x9f\xd9\x18\x91\x8a\x35\x22\x44\xaf\x1e\x76\xf3\xa9\x98\xf3\xdc\x63\x2a\x61\x01\x84\xa8\xaf\x30\x46\x69\xfa\x1e\xca\x95\xe9\x42\x63\xeb\xee\x66\xf7\xff\x48\x47\x29\xda\x0a\x47\xf1\xeb\x09\x2a\x6f\x8b\x5e\x3d\xf9\xb1\xd3\x31\xa7\x18\x61\xd1\x6a\xb2\x2a\x74\x6c\xbf\xb7\xcd\xdb\xa2\xb5\x6d\x63\x81\x6e\x3f\xa6\xdd\x2d\xd2\xd8\xda\x5c\xd8\x11\xe5\xa2\xed\x78\x12\xff\xac\xda\x31\x35\xa2\xa8\xb0\x0d\xb3\x7f\xad\xa7\x43\x22\xa0\x80\x26\xc0\x9b\x28\xb2\x7c\x10\x9a\x8b\x20\xa2\xc2\xb9\xe3\xdb\xb9\x9a\x49\x12\x07\x84\x0b\x1b\x13\x2b\xca\x73\x7b\xa2\x76\x71\x61\xdf\x21\xb1\xf9\xbc\xd5\x9f\xcb\x6f\x8b\xc7\xdb\xd5\x1e\x29\xaf\xae\x57\xcb\xbb\x87\xc5\xfd\xb6\xeb\xc5\x18\x66\x58\x34\xaa\x7e\x0c\x28\x35\x48\x1c\x68\x2e\x9c\x92\x61\xe7\x21\xc5\x24\x84\xd4\xe6\x31\xb6\x9d\x41\x10\x93\xd8\x4e\xec\xed\x9f\xdb\xbf\x06\x6f\x11\x53\xc3\x2d\xc9\xbc\x38\xc2\x06\xea\xae\x6e\x92\xc4\xa1\xe3\x10\x6f\xa0\x18\xf2\x70\x90\x38\x0a\x15\xc2\xa5\xcf\x45\xe7\xc0\xcf\x49\x67\xb5\x1d\x0d\xd6\x39\xac\xa0\x39\x28\xdc\x65\xbf\x08\xbf\xc5\x51\x92\x6a\xc7\x23\x5f\xfe\xd9\xfd\x96\x00\x0c\x70\xa3\x9a\x8a\x4d\x9c\x38\x1d\x83\x7f\xc5\xdd\xcf\x48\x96\x3a\x9e\x33\xc7\xd2\xf6\x15\x79\xfa\x3f\x3b\xdf\xe2\x48\x72\xaf\xbe\x35\xa3\x60\xc9\x48\x1c\x13\xc2\x3c\xa5\xe9\xb5\x25\xef\xd0\x77\x56\x07\x6b\xdb\xce\xcb\x42\xc1\xcf\xaa\x2c\x0e\x1b\x10\x13\x13\x20\x4e\x02\x83\x05\xda\x70\xc4\xdd\xd4\xeb\xd5\xfe\x23\x38\x2a\x89\x79\x4c\xbc\xeb\x84\xa3\x92\x15\x87\x09\x4c\xd3\x77\x4c\x42\x0c\x50\x60\x2e\xc4\x26\xe1\x26\xae\x78\xcc\x99\x0d\x79\xda\xca\xf3\xd9\xa0\x44\xcc\x53\x8d\x35\x38\x05\xbc\x9f\xca\xe2\xef\xac\xbb\x16\x42\xdc\x19\x1e\x05\x56\x10\xfd\x1f\x73\x43\x71\x4a\x19\x82\xb9\xad\x5f\xd6\x5e\x88\xc9\x9c\xe1\x44\x4b\xd3\x94\x5b\xc4\x4e\xbb\x1b\xd7\xe0\xa8\xf8\x7e\x4b\x4e\x4a\xe2\x54\x24\x68\x19\x97\xa8\x6a\xdb\xdf\x50\x4b\x8c\xa0\xe5\xa2\x6e\x76\x59\xbf\x62\x24\x0d\xbc\x69\xb1\xc8\xf3\xc9\xd7\x92\x69\x8a\x5e\xf2\x3e\xab\xb7\xd9\xa1\x00\xfd\x54\x81\xc9\x7e\x7d\x6e\x05\x7e\x65\x54\xc6\x3a\x12\x49\xe4\x6a\x82\xeb\xb3\xac\x55\x95\xc9\xde\xfe\x89\x75\xcc\xb0\xb8\x62\x29\x2a\x59\x16\x30\x0e\x54\xc5\x5a\x5a\xd5\xe9\xdd\x0b\xb4\xe6\xbe\xff\x33\x04\x10\xd9\x10\xd9\x69\x3a\x95\xc6\xc3\x02\x9a\x46\x7e\xab\xbe\x7b\xea\x49\x29\xa6\xbd\x2c\xcf\x74\xfb\x3d\x5a\x8b\x7c\x75\x5a\x1c\xa1\xd0\x7d\xc9\x4c\xdb\x05\x30\xba\x22\xce\x97\x75\x4b\x24\x06\x63\xd9\x89\x0a\x78\xbf\x98\xdb\xe7\x09\xad\x35\xf6\xc6\x78\x53\x05\xad\x49\x6c\x35\xc5\x5c\x00\x66\xf2\x60\x86\xa7\x18\x91\xf8\xcf\xf5\xdd\xe3\x6e\xff\xb4\xda\xec\x57\x3b\x47\xda\x43\x92\x80\x84\xdc\xee\x4a\x79\xa9\x5e\x41\xef\x40\x78\xdd\x9b\x41\x39\x38\x49\x02\xae\x03\x77\x70\xbb\x39\xf4\x50\xea\x1e\x9e\x53\xce\x29\x31\xbb\x4b\x09\x4d\xe8\x30\xc2\x7c\xb3\xdd\xcd\x0f\x74\x42\x12\x0b\x64\xe8\x2c\x26\xfc\x8c\xed\x12\x99\x5b\x21\xfe\x22\x15\x6b\x17\xe6\xbf\xaa\x84\x7a\x45\x65\x36\xf5\x79\xef\x04\x2d\xe5\xcd\xb9\xf0\xc0\xf2\x3e\x60\x90\x50\x12\x68\xb7\x27\x7e\x2b\x87\x0a\x58\x43\x34\x2a\x49\xa8\x21\x9c\x7a\xe8\xf3\xa6\x3b\x98\x92\x30\xb2\xdc\x2a\x27\x94\xe9\x19\x31\x40\x90\x24\x0a\xad\x30\x61\xbb\xf3\x59\x28\x3d\x8c\x59\xb0\x48\x12\xc5\x29\xb3\x75\xcf\x83\x0c\x50\x12\xf3\xd8\xd7\xff\x3e\x67\x9f\xd4\x5c\xb6\xbd\x2c\xb9\x27\x5a\x56\xa7\x4c\x8d\x27\x41\xc2\x22\x40\x6c\xc4\x51\xfc\xca\x8e\xe7\xe3\x9d\x2a\x7b\x06\x41\x92\x70\x88\x91\x81\x04\x0f\xf8\xed\x1c\xf5\x3b\x49\x52\x06\xc6\x41\xa5\xb6\xe7\x63\x0f\xf2\xf3\x8b\x30\x49\x45\x12\xb6\xeb\xe9\x4e\x95\x7d\xb8\xab\x6b\x33\x9e\x12\x64\x9d\x6b\x5b\x8f\x3a\xe1\x4a\xf7\x3d\xb5\xc6\x04\x5d\x56\xa0\xee\x47\x3d\x60\x4c\x24\x89\xd0\x2a\xf4\x80\xd0\x0f\x4b\x98\x48\x27\xd7\x0b\x93\xe0\xe9\x79\xcc\x0a\x78\x2a\xe7\x95\x0d\x49\xa2\x02\x61\xab\xaa\xca\xe3\xc9\x7a\xeb\x88\xc5\x99\x0c\x9a\x0e\x55\x62\x55\xb2\xfe\x7d\xae\x1b\x97\xdb\x1c\x77\x81\xd8\x11\x5b\xb6\xbb\x70\x0f\xb7\xfd\x64\xf6\x19\x17\x85\xcd\xea\xce\x06\xf0\x84\x1d\xa4\x7d\x77\x0c\xb2\xec\x5e\x44\xf1\xfa\x57\x79\x9e\x01\x5b\x30\x9a\x18\xe4\x81\xf9\xb6\xfe\xb9\x5a\x0f\x37\x39\x46\x85\xa5\xda\x6e\xa7\x97\x8d\x9b\x20\x50\xaa\x53\x92\x22\x8c\xea\x14\x67\xe7\xba\x29\x8f\xa2\xc9\xfe\x1e\x5d\x1e\x05\x1a\x8b\xe3\x8a\xf3\xf1\xda\x09\xd8\xd4\x4f\x15\xbc\x65\xe5\xb9\x46\x4e\xcf\xae\x23\xb1\x71\xa2\x3f\x9f\x76\xe3\x1b\x70\xeb\x67\xfe\xdc\x6e\xc6\x5f\x84\x45\x42\x39\x61\xa3\x66\x85\x0c\xea\xa0\x77\xa2\x7e\xed\x10\x31\xb3\x43\xc5\x62\x6a\x45\x21\xbd\xdc\xc3\xd5\x47\x3b\xba\xbb\x8f\x13\x2c\x0a\x7d\x37\xef\x5e\xb0\x58\x33\x0c\xc2\x6d\x9f\x16\x9b\xe5\xf8\x40\x62\x49\x0c\x58\xc9\xf2\x03\x0a\x8d\x4e\xe8\xd6\x03\xe8\x3e\x29\xea\x22\x2c\x49\x04\x84\x3d\x2d\xf7\x83\x28\xce\x22\xcf\x3f\xae\x3a\x26\xe5\xc1\xde\xc1\x98\x93\x5c\x6f\x4f\xc9\x26\x3b\x42\x05\xfa\xdc\x25\xe6\x19\x13\x4c\xdb\xc2\x92\xa2\xe7\xcd\x1f\x00\x7c\x18\x27\x02\x69\xab\x3c\x8d\xf8\xfc\xc4\x65\x3c\x0a\xc9\x98\xc3\xea\x87\xa8\xb2\xa1\xfa\xd3\x7f\x7c\xea\x4d\xb3\x34\x24\x18\x7f\xda\xef\xb3\xfa\x06\x50\x78\xcd\x13\x40\x8d\x7f\x25\xd5\x01\x4b\x1d\xe7\x59\x6b\x39\x8f\x51\x06\x2c\x05\x4d\xbd\x12\xf3\x10\xeb\xc3\x04\x49\x63\x17\xd9\x5c\x9f\x1b\xac\x0a\x1e\xdd\x57\xa4\x11\xb6\x3f\x6f\xaf\xf7\xeb\x63\x91\xe9\x32\xcf\x85\xdf\xfe\x98\x0c\x19\x1d\x8a\x4c\xa1\x7b\x2a\x8a\x79\x92\x68\xc2\x94\xe4\x48\x74\xf1\xdf\xcf\xde\x1d\x66\x0a\x00\xe3\x10\x8e\x6d\x1c\x09\xf2\xae\xcf\x0e\x1c\x3c\xbe\x5a\xc7\x31\x75\x61\xc4\x11\xf9\xb7\x6f\x86\x18\xfd\x2a\xcb\x7a\xb0\x2c\x8f\xc7\x3e\x78\xc0\x80\x44\x68\x27\xfd\x00\x99\x95\xc5\x9f\xdd\x9f\x53\x16\xf5\x84\x44\x3d\xb2\x71\xd6\x40\x64\x86\x46\x18\x66\xfb\x54\x2f\x7f\x74\xe6\x30\x93\x18\xe4\xa4\x7c\xf8\x6b\xb9\x9c\xdb\x19\x0c\x28\x34\x72\xde\x2c\xbf\x3b\xf5\x77\xeb\x16\xa8\x01\x6d\x3a\xae\x9c\xaa\x6e\x10\x4e\x0f\xd7\x67\xc8\x49\xd7\xc5\x58\x9a\x9f\x4e\xe1\x1d\x8b\x8f\xbe\x0e\x4f\xf1\x40\x6b\x2c\xde\xdb\x1f\x3c\x6d\xd0\xfc\x8a\xe6\x24\x61\x2a\xb2\xfc\x92\x96\x88\xf9\x93\x7e\x94\x72\x5b\xcd\x8c\x06\x38\x88\xe3\xb2\x27\x23\xbd\xd3\xbd\x4a\xfc\x1f\xbe\x3f\xb3\x00\x34\x0f\xb7\x1a\x36\xe0\xeb\x14\xf0\xab\x19\xde\xa3\xd0\xf0\x6b\x57\x5e\x01\xb2\xc3\x8f\x56\x21\x0f\xe3\x40\xa4\x16\xcb\x89\x88\x04\x91\x67\xaa\xdd\x02\x3b\xd6\xd9\xc5\x79\x33\x01\x3b\xf1\x30\x21\x78\x4a\x14\x65\x23\xaa\x49\xad\x3e\xe1\x71\x18\xe3\x7e\xe9\xf2\x98\xc8\xdf\xbe\x2b\xaf\xf2\x52\xcd\xf0\x4f\xb6\xdd\x53\xe4\xd1\xb5\x33\x78\x71\x3a\xad\x7e\xc1\xc4\xb3\xe7\x71\x12\x62\xe8\x00\x65\x0f\xae\xb3\xb7\x7a\x2b\xde\xfa\x1a\x7f\xc2\x63\x66\x63\xc0\x35\x34\xf7\xe5\x21\xbb\xb8\x5c\x28\xcc\xa3\xa1\x72\xda\xc7\xb2\x3c\x9e\xca\xe2\xc2\x6a\xe4\xb1\x21\x56\xa5\xb1\x29\x4f\xae\xf4\xd6\xdf\x3f\x09\x83\xd0\x26\x00\x2d\xb6\xf9\x4e\x95\x76\x32\x75\x1d\x78\x10\x3a\xcd\xe2\xb5\x31\xcb\x17\xd1\x69\x35\xc3\x85\xbb\xcb\x59\x68\x8d\x9e\xa7\xcd\x7a\x7d\xb3\xb7\x9c\x80\x3f\x17\xf7\xf7\x2b\x8f\x51\xe4\x9c\x0a\xd4\x8b\xe9\xf7\x3c\x24\xd0\xee\x2c\x24\xce\x15\x17\x96\xc3\xe2\x66\x58\xde\x46\x78\x4a\x21\x74\xe1\xc3\x87\x8f\xef\x45\xf9\x9e\xb7\x27\xa3\x6f\x15\x22\x41\x81\xab\xc7\x95\x5f\xc2\x5c\x06\x02\x9f\xdc\x47\xe8\xaf\xce\x1f\xd7\x70\x14\x53\xe0\x0a\x97\x3a\xd1\xba\x17\xb6\x85\xba\xb1\x5c\x88\x03\x0b\x9d\xab\x80\xe2\x66\x07\xcd\xcb\x53\x05\xa3\x88\x34\x57\x49\x6c\x85\x86\xb2\x23\x58\x42\xcf\x59\x62\xa8\xd1\x4c\x52\x8a\x25\xbe\xf8\xe1\x0a\xa6\xdf\x4b\xb3\x04\x71\x3e\x27\xd4\xb0\x58\x96\xfd\xe8\x68\x61\x2d\x22\xa1\xf5\x23\xbc\x6f\x41\x55\xd0\x60\x45\xdb\xc8\x80\xe4\x5a\x30\x00\xff\x4a\x33\xec\x22\x84\x6b\x93\x6a\xb7\x65\x5a\xa5\x8c\xed\x49\x28\xa8\x5f\xb2\xd3\xb3\x65\x83\xaa\xaf\x3e\xee\xa6\x23\xa5\x8d\x15\x2a\x7e\x11\xa8\x5e\xb9\x5c\x2f\xf3\xb2\x0f\x6e\x72\x48\x42\xd4\x1b\x6a\x1f\x7b\xbc\x70\x20\x51\xc8\x20\x9c\xd5\xd6\x50\x1f\x96\x5f\xfb\x2e\x42\xc4\x7e\xa2\xb7\xcf\xf3\x24\x2a\x98\x1a\x94\x1c\x94\x3d\xcb\x10\xac\x57\xbd\x42\xe3\xed\x22\x1c\xa3\xf1\xc3\x1a\x4e\x94\x33\xb5\x97\xcb\x6f\x56\x77\xc4\xeb\x09\x90\x34\x48\x02\x3e\xe2\xd9\x5e\x5c\xcc\xe9\xf1\x56\x96\x92\x80\x0e\x00\x70\x98\x51\xfb\x2a\x8e\xe2\xbf\x45\x4a\x22\x86\x9b\xc6\xc9\xba\xee\xcf\x37\x7e\x2d\xa4\x34\x8d\x31\x9b\xb7\x56\x20\x8a\xad\x12\x27\x0b\x1f\xd1\x6f\x5f\x4d\x9d\x34\x14\x12\x53\xc2\x2e\x47\xf5\xec\x9c\xbd\x79\x87\x2d\x0d\x25\xb1\x25\x93\x88\x43\x5e\x1a\xfb\x49\xbd\x9e\x37\x49\x43\x43\xf1\x24\x71\x3a\x0f\x30\xd6\xba\x26\x69\x9c\x12\xc5\x06\x94\x32\x68\x63\x8b\x4b\x89\x90\xf9\x48\x4d\x1a\xeb\x14\x3f\xbc\x16\x8d\x58\x9b\xa7\x2f\x78\x86\xfd\x05\x00\x58\xa2\xb0\x6a\x44\x5e\x16\x36\x6d\x31\xb4\x4d\x53\x16\x29\x54\xad\x6d\x4d\xb3\xab\x4c\x0f\x98\xe9\x49\xca\x54\xa2\xa9\xaf\x82\xda\xed\xc4\x2f\xdf\xc0\x59\x84\xfe\xfc\x09\x89\x1e\x5a\x5b\x64\x59\x75\xac\x4c\x24\xe5\x3c\x20\x2e\xe5\xf2\xb3\xac\x5e\x3f\xa5\x1c\x27\x29\x87\x80\xf7\x05\x0f\xf7\xe5\x9b\xa5\x81\xfd\x63\xa0\x11\xeb\x7a\xa6\x24\xc4\x6c\xc7\xee\x05\x16\xf2\xa3\xae\xaf\x17\x77\xcb\xf5\xef\x88\x6b\xfe\x5f\xff\xf5\xbf\x6d\x12\xe4\x01\xaa\x85\x01\x57\xbd\x35\x7e\x0d\x11\x18\xae\x3a\xfc\xc9\xda\x98\x4c\x4d\x77\x88\x54\x52\x08\x98\x67\x62\xc3\xe0\x1e\x46\x06\xbc\x09\xe6\xc9\x8b\x27\x88\x85\x54\x31\x2e\x1c\x81\xdb\xb2\xd4\xa0\x2f\x62\xc2\xa9\xe2\x09\x84\x8e\x62\x77\xdf\x8e\x9e\xe5\x15\xf6\x1f\x43\x41\x18\xdb\xb4\x5a\xfb\xd9\xdf\x7b\x4c\x7d\xaa\x80\x85\x96\xbd\x2d\xfb\x1b\xfa\x2a\x15\x92\x1a\x6a\x90\x35\x60\xaf\xac\x91\xd1\xb1\x23\xfc\x31\x88\xb5\x8c\xaa\xff\xfe\x45\xc8\xff\xf8\x8b\xc3\xc0\x73\x85\xdc\x97\xea\x75\x62\xda\xa5\x86\x6b\xdc\x8b\x31\x09\x7b\x67\x3a\x4e\xd6\x69\x96\x5a\x04\x41\x8a\x99\xab\xab\xcd\x3d\x1e\x7c\x7f\xf8\xbf\x87\x01\x46\x49\x77\x0f\xcb\xdf\x9e\x0b\x22\x88\x02\x74\x7a\x0a\x78\x47\xb5\x02\x6f\x4f\x0b\xc2\x25\x22\x86\x26\xba\x57\xe3\x47\xa0\x10\x61\x40\x64\xfd\xf3\x71\x7f\xc1\xfa\x39\xed\x6b\xd2\xc4\xd1\x7b\x7c\x05\xc8\x12\x91\x56\xb1\x17\xc0\x39\xab\xd7\x0f\x2c\x94\x58\x89\x6a\x12\xf1\x12\x71\x98\x30\x17\xba\x41\xdc\xb6\x27\x0a\x1d\x14\x73\xf7\xab\x43\x24\x09\xd8\x24\xa5\xd6\xeb\xca\x62\xc7\x66\xc8\x56\x89\x48\x98\x10\xee\xe3\xdc\x9c\x0b\x8c\xb4\x79\x3c\x25\xce\xc2\x91\x60\xb3\xff\xd7\x2f\xc6\xd1\xf3\xb1\x28\x41\x27\xc0\x6d\x9b\xfb\xf9\xfd\x52\x30\x15\x85\x23\x62\x55\xa0\xa4\x8f\x71\x4d\x0f\x05\xc1\x03\x29\x1c\x02\xae\xf5\x24\x6f\x00\xa6\xe7\xed\xe4\xfe\x9c\x32\xa4\xaf\x96\xe7\x8f\xb5\xcc\xfe\x56\x9e\x1f\x7d\x3a\xec\x5c\x0a\x1a\x77\xc5\x6c\x50\x5d\x95\xbf\x60\xda\x47\x24\x81\xd1\x17\x21\xb6\xc9\x82\x14\x42\x5b\x02\xbc\x13\x9e\xd8\x02\x4d\x97\xbe\x42\x74\xda\x5b\x06\x10\x2a\x17\x9c\xbd\x16\xd9\x3f\xaa\x1e\x22\x42\xc5\x16\xe9\xf1\x73\x52\x8f\xf5\x0f\x8e\x08\xa1\x43\x40\xa8\x5c\x6b\x1b\xbc\xb6\x46\xb5\x63\xba\xfd\x24\x76\xfe\x75\x6a\x40\x68\x11\x9a\x0e\x68\xda\x53\x7e\x4d\xbe\x02\x70\x83\x96\x8a\x63\x50\x70\x6a\xcf\x3b\x51\xa1\x04\xe8\x4f\xf0\x11\x7e\x01\xa9\xdd\x72\xec\x7e\x7f\x0b\x45\xe0\xd1\x9d\x73\xab\x17\x04\xe0\x69\xf7\x22\xea\x2b\x91\xe7\x65\xb3\x42\xdd\xe5\xa1\x39\x20\x4c\xac\x03\x67\x9a\xd9\x40\xef\x50\x44\x76\x9b\x8b\xfa\x65\x2e\x01\x2d\x8c\x62\x98\x57\x3d\xa2\xd9\xe3\x53\x00\x23\x43\x54\x12\x4d\x31\xf2\xb7\x59\x3c\xde\xae\x56\x8f\xd7\xfb\xa7\xcd\x6a\xbb\xb8\xf7\x1e\xb5\xa4\xd4\x66\x92\x6c\x9c\xc0\xc9\x46\xf9\xb6\xd0\xca\x40\x3d\xdc\x3d\x2e\xfd\xdf\xc2\x24\xc6\x60\x8f\xd3\x7d\xb8\x28\x07\x92\x61\x6a\x8b\xaf\xfa\xcc\xb7\xd5\xc7\xaa\x6f\x90\x3b\xaf\xb3\x0c\x65\x14\x27\x18\xd0\xdc\x36\x6a\x78\x98\xcb\x88\xc5\x98\xf0\xda\xee\xfe\xcb\x1a\x94\xe1\xfc\xb2\x91\x91\x89\x3c\xfe\xfb\x7a\xf5\xe7\x94\xfe\x76\xdc\x37\x0e\x62\xa1\xbd\x25\x59\x1d\x60\x29\x4e\x5d\x84\x6e\x06\x78\x30\x9e\x40\x32\x06\x40\x17\xc6\xc2\x27\x90\xf4\x6e\x1c\xd9\x95\x49\x62\x63\xa3\xad\x99\x4b\x3e\xb9\x4b\x22\x42\xe6\x82\x9b\xbe\xd6\xc9\x9a\xd9\x93\xf5\x26\x13\x1d\xe2\x96\x9d\xd5\x8f\x65\x23\xa6\x65\x35\x32\xd1\x36\xdd\x71\x80\xa6\x3b\xd4\x5a\xf3\xa4\x6e\xc4\xf1\x34\x1f\x3d\x96\x4c\xc7\xca\x32\x3d\x64\x0a\xec\xde\xfa\x53\x64\x38\x67\xfa\x10\xb6\xe4\x41\x04\x6e\x5f\xbf\xb2\xf8\x99\xd1\xa7\xe5\x81\x44\x92\x34\xc7\x0d\xbb\x14\x95\x46\x0e\x97\xc3\xe4\x01\x53\x99\x58\xc9\x20\x91\xc3\x48\xe5\x87\x48\x11\xda\x22\xe4\xa7\x5c\xd4\x47\xd1\xfd\x55\x47\x18\x96\xff\xb7\x50\xaf\xa7\xd2\x0b\xad\x8f\x27\xb2\xa4\x89\xe5\x1b\x71\xdf\xb9\xfd\x6a\x58\x01\x35\x19\x3c\x19\x2a\xc5\x91\xb6\xe8\x0d\x9a\x97\x8e\x91\xe3\x37\xd9\xb7\xc9\xd4\x92\x60\xd0\xc2\x3d\x89\x8f\xa7\x5c\x34\xa6\xac\x8e\xeb\x73\x73\x28\xdb\xf1\xea\x2b\xbc\x97\xe5\xf1\x98\x61\x11\x8b\x7f\x48\x95\x6a\x64\xa0\xef\xa0\x99\x96\x81\x78\xf2\x88\x9a\x18\xb4\xf1\x1f\xb2\x62\x29\x4e\x1b\x10\xea\x65\x1a\xa1\x93\x5a\xa6\x58\xfc\x5c\x97\x06\xc5\x55\x7a\x26\xb3\xb6\x4d\x21\x3f\x81\xe3\x96\xf9\x7f\x4f\xeb\x4a\x0d\x3c\xb6\xb4\x61\x8d\xa8\x10\x43\xb5\x74\xa2\xd0\x83\x6d\xed\x3c\x50\xe2\xbf\xb4\x9f\x9c\x2c\x9d\x63\x54\x98\xa8\xf1\x87\xd4\x87\x03\x24\x04\x56\xaf\xd0\x29\xc3\xc4\xfe\xa5\x80\x70\x2c\x88\xde\xbe\x94\xa7\x6b\x38\xe5\x28\x8d\xfb\xd5\x5b\x75\x73\x1b\x38\x43\xf2\x8d\x59\x2a\xd6\xf9\xa5\x08\xc2\xd2\x57\x7b\xf5\x9a\x32\x2b\x6a\x47\x67\xdc\x23\xca\xfd\x93\x99\x30\x96\xae\x14\xef\x21\x2b\xce\x0d\xd4\x36\xf0\x58\x77\x1d\x22\xab\x29\xb2\x5c\x3c\xfe\x58\x6c\xf7\x3f\xef\xae\xbb\xfc\x9b\x34\xb1\x48\x5d\xcc\x70\xf5\xb8\x9d\x2c\x14\x23\x02\x1f\xbe\xd8\x80\x86\xa3\x2d\x23\x69\x8d\x29\x17\x3b\xea\xfa\x49\x84\x20\x56\x88\x44\x58\x9b\xc9\x5c\x31\x3a\xe2\xd2\x2d\x8d\x5e\x3b\xf1\x3f\x66\x6d\xca\xf1\x40\xa8\x80\x4a\x0c\x35\x5d\x6d\x17\x37\xfe\x4c\x50\x41\xa8\x99\x0b\xcd\xef\x2b\x98\x3a\xd1\x8a\x04\x0c\x8d\xd7\x77\xc8\x76\xe5\x93\xa5\xc6\xae\xea\xd6\x81\xea\x74\x96\x88\x22\x11\x33\xb2\xab\x67\xc5\x85\xfc\x7f\x78\x2c\x12\x33\x4d\x3c\xe3\x72\x7d\xae\x5a\xeb\xcc\x51\xe2\x4e\x4c\x65\x7f\x81\x26\xa9\x4b\x6f\x0c\x22\x81\xf5\xf4\xc9\xb5\x25\x35\x69\x5f\xcc\x71\x7a\x5b\x79\xb7\x7a\x7f\x82\xca\x4a\xe6\xf9\x17\xa0\x3c\x44\x1b\xd7\xe5\xca\xbb\xbf\x87\x69\x82\xe5\xb6\xb6\xd6\x7c\xca\xe5\x42\x54\x44\x99\x0f\x91\xff\x84\xec\xf0\x72\xa1\x02\xe7\xfb\xa5\x3c\x90\x9e\xdf\x5d\x14\xa2\xdb\x66\x55\xcc\x18\xc2\x7f\xe1\xac\xae\xb3\xba\xa1\xd7\xff\xcc\xe0\x52\x31\xb7\x72\x05\x99\x93\x50\xea\xce\xa8\xdf\x5c\x96\x5a\x71\x87\x07\x91\x15\x05\x34\xdb\x73\xf5\x06\x17\xa5\xc7\x9e\x58\xc1\xad\x62\x95\x24\x11\x92\xbf\xdc\x97\x87\x69\x39\xc3\xec\x8a\x53\x89\x8e\x90\xb6\xe6\x04\xa2\xca\x27\xd8\x4e\x95\x68\x85\x71\x9e\xa7\xaa\x2c\xcd\xda\x2c\x2b\x91\x1d\x6e\x2b\x51\xf4\x1d\x20\x88\x5c\x88\x6b\x84\xa9\x99\xfc\x08\xe3\x0a\x19\x4f\x30\xb2\xec\x68\xc0\xfa\xda\x40\xc5\xd2\x98\xdb\xa2\xf9\x1c\x44\x0d\x28\x11\x38\x3a\x26\x15\x83\x94\x62\x42\xe8\xda\x66\x84\x56\x95\xa2\x01\x7a\x4b\xa8\xdf\x31\xe9\xcd\x03\x95\x30\xac\xb9\x58\x3f\xad\x3e\x41\x8f\x8d\x66\x29\xa7\x8a\xb8\xa2\x2d\xaf\x3c\xd6\xf1\xc7\x8d\xdf\x84\x47\x0c\x6b\xc5\x1c\x9a\x7e\x6d\x1c\xc1\xd6\xb4\x5b\xac\xb1\x18\xe4\xbe\x3c\x3c\x4e\x4f\xfe\xe9\x42\x1b\x6b\x58\x59\x00\xd8\x27\x53\x82\x43\x18\x86\x3e\x15\x5c\xe8\xf2\xbd\xb8\xad\x84\x02\x6b\x0b\x0f\xa3\x2b\x2a\x0d\xdd\x41\x69\x41\x8d\xd7\x99\x82\x4d\x99\xe7\x63\x5c\x83\xef\x1b\x07\x58\x89\xb6\xba\xb9\x19\xef\x83\x2a\x8d\x19\x22\xef\x8f\xe2\xd7\x55\xa6\xef\x0a\x2f\x85\x3a\x59\x5a\xa9\x60\x58\x0a\xd8\x94\xa7\x6c\x68\x32\xaa\x14\x08\x02\xc6\xb6\xa7\xb3\xde\x95\xd7\xd9\xdb\x74\xe1\x0b\x4a\x50\xf0\x2e\xab\x17\x67\x9d\x35\x65\xd5\xeb\xa9\x4d\x1e\x45\x84\x21\x66\x98\x70\x6d\xfb\xfb\x0b\x69\x7c\x65\xca\x5f\xe7\x23\x54\xd9\xf9\x38\xef\x44\x28\xa1\x6c\x2e\x54\x68\xed\xd4\xb5\x2c\x31\xd3\xcc\xdc\xb8\x1c\x76\x99\xda\x00\x70\xbb\xeb\x69\x57\x1f\x3c\x0b\x97\x51\x52\x52\xab\x9a\x9b\xfd\x02\xbd\x7f\x1b\x54\x67\x29\x09\x86\x77\xf5\xa0\x36\xc9\x63\x50\x5f\xe0\x13\x1c\x92\xbb\x4c\x45\x16\x68\xba\xc8\x41\x21\x91\x8e\xbf\x9f\xe2\x41\x2c\xba\x60\xe1\xa4\x04\xd0\xf7\x01\xcb\x2a\xf9\xbd\xcc\x45\x37\x35\x20\xa6\xe0\x11\xdd\x50\xdd\xd5\x0b\xfd\x56\xaa\xcf\xe8\xf6\x88\x82\xd4\xea\x3f\x9a\xb2\x7a\x6f\x0d\x4b\x91\xe7\xb7\xa2\xfb\xf4\xa0\x13\x04\xef\x1d\xb3\xa2\x79\x84\xf7\xeb\xc7\xe5\x27\x5b\x80\x89\x39\x12\x38\x2f\x45\x71\xb7\x3d\x5b\x1c\xd1\xae\xca\xa6\xd1\x2e\x65\xe2\xd4\x65\x40\x5b\xdf\x69\xbf\xe8\xd8\xc9\xe6\x87\xc7\xf0\x04\x6b\xe1\xf6\x15\x68\x80\xe3\x9d\xaf\x43\x1f\xdf\x55\x07\x49\xc2\xdc\x01\x83\x65\x6f\x53\xf7\x5c\x07\xca\x04\x8e\x97\xc3\xd7\x55\x6d\xb3\x43\x81\xa9\xda\x0b\x6b\x67\x00\xda\xd5\x01\x68\xcf\x98\x5d\x7f\x87\x8f\xc9\x04\xd7\x24\x22\x06\x43\x14\x65\x27\x69\xd8\x47\x56\x34\x49\x53\x3c\xcb\x6c\x8e\x6a\x75\x44\xeb\x0a\xc8\xe4\xd9\xc2\x40\x10\x7b\x10\x0c\x0a\x7d\x2f\x50\x5c\x9f\x68\x9a\xfa\x7b\x10\x81\x2e\x69\x47\x8d\x81\x33\x30\x9e\x3c\x6d\xa8\x81\x74\xe5\xdb\xa2\xf9\xbc\x76\x6f\x7a\x77\x0d\xb8\x4f\xfc\x67\x56\xa8\xb2\x1a\x6e\x01\x3a\x4a\x53\x2c\xc9\x47\x9d\xc0\x45\x05\x62\xdb\x67\x50\xc6\x8b\x47\x47\x42\x84\x76\xa6\x1d\xcb\xf0\x3a\x82\x37\xd1\xdd\x04\xb4\x70\x1e\x65\x6b\x9b\xde\x97\x4d\xb4\xed\xd0\x77\xe3\x47\x89\x03\xeb\x66\x9c\xc4\xc7\x15\x34\x63\x25\x2a\xa2\x63\x61\xd0\x24\x7d\x3e\x99\xac\xf0\xe2\x8a\xf8\x67\x84\x08\xc1\xaf\x06\x0a\x3d\xaf\xe0\x44\x74\x2c\xe3\x4e\x9d\xa0\x2c\xce\x28\x09\x32\x20\xf9\x25\x3a\xd6\x36\x8b\xe1\x35\xb7\xb3\xa2\xf5\x5e\xf3\x8b\x41\x1c\xcc\x80\xd8\x18\x8c\x90\xe3\xc9\xb8\xda\x7d\xfb\x29\x0e\xb8\xf9\xb9\xe6\x44\x4b\xb0\x19\x3f\xa7\x53\x75\x40\x52\x48\x5f\x7a\xf3\xf5\x57\x49\x80\x62\x9a\x0d\x49\xbd\x36\xa5\x57\x97\x20\x9a\x25\x01\x1a\x65\x77\xcb\xb5\xe3\x78\xee\x7f\x91\xa9\x04\x89\x63\x6c\x10\xe5\xba\x7c\xf7\x32\xde\xf3\xeb\x5a\x33\x88\x30\xe8\xd7\x8c\xc1\x15\xff\x47\x77\x67\x72\x53\xce\x52\x94\x02\xbe\x69\xb7\x51\xab\xdd\x6a\x27\xd5\xe7\x31\x2a\xee\x2f\xd5\x56\xf6\x6d\xef\xaa\x24\xef\x33\x05\x53\x52\xe8\xb6\x17\x13\x3d\x91\xc4\x66\x46\x99\xc2\x75\x4c\x43\x85\x29\x50\xb4\xdd\xce\xf5\x34\xe6\xa9\x53\x63\x14\x78\xff\xdd\x22\xb4\xfd\x48\x8a\x00\x30\x91\xbb\xf7\xe2\xa9\x1b\x64\x30\xbb\x85\xa2\x2b\x69\xd4\x42\x09\x0b\x67\x6e\x8d\xaa\x2b\xa1\x5e\x61\xbc\x7a\x14\x4b\xb0\x16\x02\xd0\x5b\x5f\x6d\x96\x8c\xfa\xac\x98\xd6\x51\x22\x2c\xe7\x88\x69\xc8\xa4\x9c\x4b\x6b\xce\xd1\xe1\xc5\x9c\xbb\x17\x4d\x22\x5a\xa7\x29\x0a\x8f\x5c\x65\x87\x4d\x56\xbf\x76\x7f\xd6\xb6\x90\x03\x79\x33\x8c\x8b\xdd\x0e\xea\x4c\x34\x50\x83\x18\x6a\x14\x2b\x72\xc1\xa8\xf1\xca\x82\x24\xc4\x1f\x54\x3d\x95\x3b\xc2\x4f\xab\xe9\x4e\x6b\xb8\xc6\xa8\xb9\xcc\x0e\x77\xd3\xc8\x99\x36\x8a\x20\x1a\xca\x72\xc6\xe5\x65\xd3\x94\x24\x70\xce\xdd\xef\xf2\x31\xf6\x16\x10\x84\x01\x06\xd6\x9c\xa6\xa1\x9b\x96\xa0\x77\xe5\xa7\x1c\x6c\x04\x02\xc6\x89\x8d\x6b\xd6\x67\xb8\x86\xb7\x7a\x84\x4e\x00\x42\xc2\x38\x1a\xc8\x88\x0d\x98\xef\x66\x42\x8b\x40\x28\xeb\x64\xc2\x5b\xa3\xac\xdd\x4b\xfb\x7b\x19\xeb\x78\x1e\xa0\xf9\xd6\xe4\x6a\x67\xb9\x0c\xad\xf1\x36\x6b\x54\x00\xe5\xae\x7c\x4c\x14\x37\x5e\x96\xc0\x37\x89\x04\x0b\xd5\x85\x76\xa4\x84\x17\x69\x7e\xa0\x3a\x45\xe2\xd1\xbc\x4b\xc1\x40\x18\x30\xfc\xd3\x7f\xaf\x96\xdd\x9f\x92\x18\x51\xda\x8b\xbb\xe5\x7f\x75\x7f\x53\x0c\xcf\x56\xfc\xe8\xd6\xec\x1f\x3f\x58\xa8\x38\xde\xe7\x7a\x3b\x5c\x9d\xbe\xd1\x68\x8c\x6c\x21\x9c\x23\x73\x11\xc9\xaf\x25\xff\x08\x44\xca\x60\xde\x76\xb3\xbe\xf1\x4f\x11\xcb\x14\xc5\x4c\x6a\x25\x2e\xc1\x0c\xbe\x0f\x40\x6c\x1c\x89\xca\xf8\x86\x49\x60\xc0\x4b\xea\xdf\x88\xac\xf3\xbd\x6c\xf8\xeb\xb1\x6c\xfc\x1f\x30\xcb\xed\x2f\xe2\xca\x12\x5f\xb7\x2f\xde\xfa\x35\xc5\x85\x47\x02\x2c\x20\xa1\x9d\x66\x1d\x5a\xdd\x5f\xce\x18\x13\x2e\x5a\xf7\x00\xc7\x2b\xa8\x9b\xb1\x70\x36\x81\x94\x72\x61\xfc\x74\x9b\xbc\x4b\x6a\x02\xbb\x04\xfa\x40\x0f\x02\x39\x3a\xdf\xec\x8b\x94\x14\x08\x9a\x22\x26\x57\xda\x3c\xf3\xc4\x9f\x03\x11\x0a\x7c\x31\x47\xa9\xb0\xda\x2c\x69\xf0\xc9\x8a\x10\x8e\x9d\xe4\xc7\xdd\xd5\x98\xf8\x03\x04\x67\x3e\x18\x69\xe3\x2d\x9b\x0b\xb9\x17\x02\x22\xe5\x81\x4d\x5a\xb6\x46\x63\x7b\x52\x8e\xa8\x78\x40\xa6\x8c\x38\x50\x14\x16\x88\x5f\x67\x87\xf6\x8c\x99\x33\x62\x3c\x12\x0b\x54\xa4\xb0\x12\x4e\x5b\x5a\x38\xcb\x6f\x30\xbf\x6f\x83\x4a\xb9\xd6\x7e\x84\xed\xe7\xb9\xa9\xca\x23\x2a\x06\xd9\xf0\xb7\xba\xa0\x91\x71\x97\xea\xc8\xb2\x0f\x7a\x36\xb0\xc9\xf7\xd1\x06\xd0\x20\x7f\x11\xf5\x0b\x96\xe9\x5f\x97\xea\x3c\x00\x9b\x03\x50\x05\x64\x2c\x49\x30\xb1\x0a\x01\x42\x8a\xf9\xe6\x73\x0d\x4b\x71\x6a\x44\x56\x2c\x9c\x10\xd3\xa4\x1f\x67\xc8\x77\x34\x88\x6d\x6e\xa1\x69\x72\xd0\x57\x1f\x0f\xa0\xb3\x21\x1f\xdf\x3f\x3b\x5a\x01\x80\x20\xb9\x7e\xaf\xaf\x7e\x5f\x0a\xdd\x43\x09\xc6\xf3\xc9\x04\x1a\x05\x65\x4e\x2f\xbf\x06\x55\x38\x60\x98\x3d\x5d\x6a\x2c\x2d\x1f\x56\xdb\x80\x91\x0c\xab\x84\xb7\xd9\xf1\x94\xc3\x56\x98\x19\x68\x1a\x9f\x9d\xbb\x46\x5b\xcd\xab\x73\x0d\x7a\x8e\xd9\x91\x80\x01\x63\xc8\xc0\xd6\x58\x96\xc7\xe3\xb9\xc8\x9a\x0f\x04\x2b\xce\x3a\x7e\x26\xa0\xcc\xf4\xca\x95\x18\x32\x58\x9b\x9f\x20\x4e\xe5\xbc\xfa\x1f\x31\x41\xca\xd1\x82\xbc\x07\x85\xd4\x3a\x93\x94\x82\x09\x84\xc6\xf9\xb1\x83\x19\xb1\xcf\x4f\xe3\xd8\xb3\x5f\xc3\x10\x62\x21\xe6\xd6\x01\xb8\x7e\x7c\x6c\xcf\xa8\xac\x38\x78\xa2\xc9\xf1\xdc\x33\x84\x46\xca\xf3\x56\x57\xe5\xa9\x9e\xb0\x5e\x13\x43\x12\x86\x19\xd1\xfd\x80\xe4\x71\xa8\xf0\x37\x5c\x4f\x86\xa6\x0c\x23\x66\x7f\x8a\x73\xe5\x2b\x37\xc6\xb7\x8b\x54\x8a\x3b\xd9\xad\x38\x82\x83\x0f\x8d\x9f\x3f\x32\x09\x3a\x30\x1f\x20\xaa\xfc\xc3\x2a\x4c\xb7\xf7\x99\x52\xd1\x12\x13\x53\x4b\x4e\xa2\xca\xa2\x00\xd5\x38\x2f\x61\x58\xc9\x6f\xe2\x98\x47\x68\x94\xb5\x6b\xa6\xac\x40\xdf\xa3\x60\xaf\x2c\x45\xa5\x2d\xf1\xc4\x68\x37\x33\x49\x24\x50\x12\x1d\x7e\x81\x42\x4d\xd9\x53\xa6\xba\x36\x23\x31\xa4\xe4\xa7\x4a\xfb\x40\x1b\xa8\xa1\x7a\xcb\x8a\xc3\xe3\x27\x32\x0c\xc4\x30\x21\x30\xa0\xab\xb1\x68\xd5\x01\x16\x5d\xd1\xc0\xf4\xdd\x19\x48\x5c\x49\x7b\x5d\xfe\x23\x65\x1a\x77\x19\x0f\x62\x84\xa2\x17\xe7\xe3\xcd\xe9\x2a\xeb\x0c\x03\xc3\x23\x82\xf3\x6a\x6f\x23\x04\x9f\x3c\x21\x67\x51\x62\x06\xfa\x84\x3d\x09\x9d\x49\x03\x82\x96\xd5\x4b\xa6\xe1\xba\x2c\x84\xe5\x9f\x1c\x7f\xd1\xd4\x9d\x87\x59\x91\x35\x19\x9a\x12\x8b\xab\xbb\x6f\xa2\x7e\xb9\x29\xab\x87\x01\x2b\xd7\xc0\xc5\x35\x69\x42\x51\x15\x0e\xd9\x24\x2e\xa6\x5c\x2a\xad\xee\x70\x6b\x82\xb8\x12\xe3\x81\x2c\x8d\x05\x2a\x5e\x9d\x3f\x1c\xb9\xd6\xc4\x3a\x31\xa9\x31\x08\xe8\xb0\x09\x6f\x25\x7c\x49\x87\x11\x49\x88\x5b\x5f\x01\xef\x3f\xca\x06\xaa\x81\xee\xb2\xef\xc1\x4c\xd8\x63\xbc\x2c\x13\xef\xbf\x41\x7d\xad\x45\x4e\x8c\x52\x09\xa3\x5e\x09\xf3\xe3\xd4\x88\x73\x65\x0b\x0c\xa6\x43\xa5\x75\x82\x86\xe4\x5e\x89\xe2\xaa\x72\xbc\xc3\x3f\x32\x31\xa1\x0c\x9a\x7c\x1f\x10\xc2\x2e\xd1\xf6\xa9\xf0\x3f\xad\x1d\x8d\x27\xed\xf0\x14\x35\x26\x20\xd2\x52\xcc\xff\xb2\x0e\x8e\x4f\x37\xf9\x76\x25\x49\xcf\x19\x70\x03\x30\x57\xb5\x41\x83\x20\x12\x89\xdb\x11\x9e\x2a\x38\x66\xe7\xa3\xe3\x0b\x19\x5a\x2b\x34\x20\x14\x8c\x37\x83\xf6\x65\x01\xae\xf2\x6f\xf5\xbf\x5b\xdc\x81\x5d\x49\x2a\x0d\x48\x62\x7c\x9c\xe4\xb1\xd4\x30\x54\xc1\xa0\x01\x4d\x53\x44\x14\xde\x97\x07\x1b\x96\x99\x2c\x09\xda\x9a\xde\x41\xd8\x13\xba\x40\x4d\x27\x1d\x62\xca\xd0\xaa\xd0\x90\x43\xd3\xfa\x4b\x79\x0e\xad\xf1\x30\x7e\xda\x38\xd2\xb8\xb2\x90\x60\x0b\x05\x43\x29\x0d\xbd\xb7\x4e\x83\x84\xe9\x28\xf5\x7e\xf8\xb9\x68\xb7\xff\x01\x4a\x9e\x06\x2c\xb1\xa2\xbf\xcb\x32\x2f\xab\x2b\xf1\x31\x18\x77\x1a\x30\x0e\x48\x49\xb0\x5c\x6f\x1e\x57\x9b\xed\x6e\xfd\xb8\x5a\x3c\xac\x9f\x1f\x77\x5d\x07\x45\xf0\x6c\x7e\xf8\xb8\x44\x7b\xd3\x80\x69\x86\x6b\xc1\x4e\x99\x6f\x22\xef\xaa\x13\x69\xc0\x4c\xaa\x3a\x62\x38\x7b\x5a\xdf\x00\x3c\x88\xee\xc1\xd3\x20\x44\xa2\x6e\x83\xf2\x5d\xed\x66\xb4\xb4\x14\x62\xbe\x83\x8c\xac\x68\x22\x9a\xf2\x36\xdc\xb7\xb7\xd5\xc1\xcb\xb2\x78\x83\xaa\x9e\x46\x9a\x69\x20\x19\x40\xe4\x31\x14\x55\x5f\xa0\xe1\x9b\x21\xc1\x38\xf0\xb2\x12\x56\x54\x86\x2c\xfc\x8f\x29\x12\x51\x0f\xa5\x7d\xbc\xbd\xd0\x4d\x19\xff\x8c\x8a\x6c\xd1\xea\x7b\x59\xbd\xd6\x2f\x9e\xc0\x92\x06\x2a\x66\x88\xdb\xdd\xc1\xaf\x4e\x56\xda\x35\x69\x88\x63\xd2\x7d\x6b\x5c\xc4\x37\x65\xb5\x14\x85\xce\x2e\x80\x66\x34\x00\x2a\xb0\xec\xe4\x56\xe8\x0c\xf2\xd1\x27\x03\x9d\x78\x2e\x52\xcb\x54\x77\x81\x76\x6d\xfb\x58\xb1\xda\xe6\x05\x44\x51\xbf\xfb\xd3\x9a\x06\x00\x21\x82\x97\x34\xa8\x0a\x15\x35\xbe\xaa\xc4\xa4\x24\x88\xa8\xe3\xc2\x68\xbf\xef\x43\xf6\x09\xf4\x80\x92\x80\x33\xd2\xbb\x84\x43\x58\xef\x34\x12\xe7\x2e\x20\x14\xa4\xc3\xda\xed\x6d\xd4\x68\xd2\xce\x38\x9a\x3f\xb7\x8e\x25\x60\x0e\x2f\x41\x09\x25\x1a\x11\x7b\x37\x65\x39\x1c\x23\x42\x65\xc2\x5c\x7c\x7b\x7f\x2a\xbb\xfd\x89\xf8\xbb\x53\x10\x68\x0f\x3b\x7e\xa7\xfd\x41\x1c\x61\x0f\x13\x78\x35\x25\xa1\xb2\x16\xd6\x8b\xa8\xef\xd1\x83\x78\x3e\x4d\x1e\x20\x84\x10\xcd\xdf\xc3\xb9\x79\x11\x12\x8a\x45\xf1\x37\x64\x87\x89\xe5\x40\x49\x44\x6d\x0a\xe6\x61\xbb\x5a\x7a\x16\xdb\x7f\x26\xc1\x4b\x49\xa4\x13\x65\x9d\xf1\xe7\xbb\xa2\xb1\x27\x88\x7f\xcf\x38\x62\x20\x5d\x81\x4c\x6b\x37\xaf\x7e\xd9\x9c\x9a\xb7\x0d\x7e\x5b\x6c\x4b\x49\x1c\x13\x4c\xee\x0a\xa7\xca\x6f\x33\x48\x5f\x59\xcd\x94\xc4\xa9\x7d\xeb\xb7\xb2\x81\x3b\x3c\x3a\x3f\xd7\x32\xfd\xd2\x00\xa7\x24\x96\x29\x82\x48\xb0\x18\x1a\xa3\xd5\x17\xb5\xd0\x94\x24\x42\x86\x5e\x4b\xf6\xc3\xea\x18\x22\x5f\x04\x89\x1c\x43\x40\x34\x49\x18\xf9\xeb\x64\x8a\xfc\xe8\x08\x80\xf4\xa1\xaf\xdf\xd7\xf9\x52\x92\x40\xe0\x89\xf3\x6d\x79\xdf\xd5\x07\xa6\xe1\x46\x1f\x26\x01\xc0\x68\x95\x2d\x10\xa9\x44\xd6\x11\x9c\x52\xc2\x62\x1a\x3a\x90\xe0\xb5\xf8\x98\x2f\x31\xa1\x84\x27\x1c\x8b\x93\x31\x24\xb9\xcb\x0a\x57\x4b\x38\xa0\xc1\xa0\x24\xe5\xe0\x21\x41\xd7\xdb\x9d\xaf\x18\x9b\x0c\x50\xaa\xad\x9b\xb1\xae\xb2\x83\x38\xda\xac\xd3\x6c\xf1\xee\xef\x3f\x48\xaa\x35\x82\x21\x85\xab\x6f\xc1\x7b\xad\x76\xdf\xec\x96\xfb\xd9\xfa\x4f\x8d\xc0\x83\x60\x75\xf7\x44\x83\x2f\x7c\x72\x4a\x04\x31\x78\x1c\x41\xa1\xcb\xaa\x86\x25\x16\x36\x7d\xf6\x8c\xfe\x9a\x90\x69\xda\x89\x24\x4e\x42\x27\xe3\xae\x32\x61\x48\xa8\xb2\x7c\xfc\xcb\x8e\x42\xee\xd9\xc2\x28\x91\x52\xc4\xa9\xaf\x4d\xc5\x85\x81\x52\x2a\x13\xda\x60\x4a\x54\x1c\xa3\x19\x8f\x9f\xc5\xd6\x0a\xce\x66\x83\x28\xd1\x4c\x73\x18\x02\x34\x86\x26\x39\x25\x5a\xf3\x38\xe8\x8b\x07\xb5\x55\x7d\xe8\x9e\x07\x08\x61\x2e\xb7\xee\x3f\x96\x13\x18\xb0\x3c\xe0\x7d\x20\x97\x12\x48\xad\xf2\xbe\xb5\x6c\xea\x21\x59\x3b\x25\xa0\x6d\x50\x08\xf5\xfb\xea\x0e\xde\x40\xd1\x6e\x74\xf4\x69\xf5\x64\x6f\x33\x60\x2c\xd8\xd9\x42\x69\xde\xaf\x2b\xf1\x3e\xed\x62\x2c\xef\x36\xde\xb6\xdd\xfc\x97\xde\x20\xa5\x34\x88\x28\x1a\xde\x6f\xa8\x77\x33\x08\x73\x3b\x64\x8d\x73\xab\x28\x25\x82\x26\xc2\x33\x69\x59\x82\xc6\xd1\xaf\x50\xa2\x42\x64\x47\xf3\xb9\x98\xff\xb4\xe8\x2a\xbf\x6b\x8d\x3b\xd3\x54\x48\x5f\x65\x8d\x34\x8b\xd3\x76\x03\x18\x21\x7e\x78\xfc\xcb\x3f\x69\xc8\x2c\x3d\x6f\x0d\x8d\xcd\x0c\x5f\x3b\x26\x4d\x7c\x18\x12\x4c\xee\x10\xa6\x21\x09\x47\x88\x10\x1b\x4a\x1c\xcf\x11\x1a\x2a\x4d\x5c\x39\x47\x37\x37\xe6\xe6\x2e\x8d\x68\xe2\xe1\xc2\x8e\xc0\xff\x77\x0b\xd2\x5d\x18\x73\x83\x69\x89\xd6\x28\xac\x0e\xa3\xaa\x14\x4a\xe3\x94\x5b\xc9\x2d\xad\x97\xe5\xb9\xaa\x61\x0a\x5b\x99\xfe\x3b\xb3\x14\x69\x42\x13\x54\x8b\x74\xb9\xcc\x75\x71\x05\x2f\x22\x37\xf3\x09\xbe\x71\x7a\x61\x7e\xdf\xa4\x89\x0e\xe2\x5e\x6c\xed\x33\x74\xf3\xff\x9f\xd9\x90\xc9\xf8\x30\x12\x1a\x36\x12\x20\xf7\x0d\xd2\x18\xda\x69\xcb\xce\x23\xc9\xc7\xeb\x98\x32\x65\x73\x59\xad\x29\x8a\xdc\x0c\x93\x9f\x52\x96\x44\xf0\x45\x58\x55\x65\xff\x4b\x3c\x88\x71\xaf\xcc\xa4\xba\x39\x23\x5e\xd6\x37\xc8\x14\x85\x04\x10\xaa\x33\x58\x35\x5c\x82\x42\x08\x94\x0f\x94\x74\x55\xa1\xae\x43\xca\x25\x77\xcf\xbe\x1a\x10\x22\x76\x03\x2c\x65\x24\xb8\x87\x3c\x9c\xa0\x72\xe4\x01\x53\x54\xa9\xef\xad\x39\x26\xc5\x65\x59\x9c\xeb\x9b\xb2\xba\xbe\x30\x34\xa9\xe2\xb6\x0b\x14\x7a\x0b\xa0\xb7\x3d\xa2\x8c\x52\x4d\x28\x5a\x2d\xa8\x9a\xf0\x73\x94\x2a\xdd\x95\x8b\x79\x93\x8c\x6a\x62\x4d\x4f\xcb\xf3\xa7\xcf\x0a\x31\x7a\x39\xa0\x82\x45\x57\xeb\x4f\xa9\x06\x8d\xac\x82\xf0\x0b\x3c\xe3\xca\xf4\x94\x74\x6e\x31\xa5\x40\x92\x4e\x95\xbe\x3d\x6c\xad\x11\xf4\x1d\x3e\xdc\x36\x38\x7e\x02\x48\x15\x9a\x14\xf7\x67\x0f\x00\xa1\xd4\x04\xbc\xa7\x9c\x7f\xaa\x50\xc0\xc9\xc2\x76\xbb\x1e\xc0\xa9\xd7\xde\x42\x67\xe5\x5b\xd6\x6e\x59\x1f\xc3\x6a\x29\xdb\x35\x0c\x52\xe6\xf1\x31\xed\x5e\x0c\x79\x8e\xec\xe0\x5d\x1e\x93\x86\x81\x54\xe0\x08\x1c\xe6\x80\x60\x34\x0c\x40\xa2\x11\xdf\x55\x91\x76\xa1\xb3\x87\xec\xd7\xa4\x38\xa2\xed\x6d\x8b\x6e\xd1\xd2\xe8\x05\xd0\x68\x48\x18\xe0\x09\x82\x0d\x3f\x21\xdb\x88\xac\x06\x7d\x7d\x6e\x7f\xe9\x6e\xb9\x26\x5d\x3f\x61\xb9\x7c\xfc\x00\xde\x8a\x23\xd4\x9e\x12\xd8\xf5\xa1\xb1\x8a\xa5\x8b\x85\x6c\xb3\x2a\x3b\xd7\x3d\x0f\x37\x0d\x43\x16\xe2\x6e\x74\x2e\x5e\xca\x5c\x0f\x68\x8c\x68\x18\x6a\x8e\x08\xfa\xab\x0c\x9d\xfb\x4d\xe6\xab\xf4\x69\x18\x49\x81\x71\xef\x87\xbb\xc7\x81\x0c\xfc\xee\xce\xeb\x38\xd3\x30\x56\x36\x32\xfd\x04\x50\x6d\xe0\x2d\x83\xf7\x31\x40\xc8\x77\xd3\x14\x55\xaa\xd0\xd0\x85\xc2\x11\x7f\xc0\x70\xcc\x13\x63\x91\x99\xbe\xfe\xd6\x4b\x3b\xcf\xc5\x3d\x68\xc8\x78\x1c\x47\x43\xfc\xc9\x67\xfd\xc0\x16\x99\xf6\x1a\xe2\x7e\x4f\xb1\xa4\xb0\xbf\x09\x74\xba\xbb\x70\x9e\x60\x7c\xff\x24\x3e\x5a\xaf\x72\xe1\xe9\xdd\xda\x16\xc3\x94\x43\x8c\x78\x8d\xa6\xe5\x30\xfc\x32\xc0\xae\x0e\x96\x44\xc8\x95\xd2\xb2\x2f\xfd\xb9\x2b\x4c\x39\x99\x34\x29\xb3\x42\x78\x76\x2f\x5e\x9b\x45\xf3\x82\x51\x86\x01\x29\xda\x68\x4a\x4a\x2a\x63\xde\xe5\x69\xa4\x8d\x50\x0d\xcd\x8c\x50\x85\x01\x02\xab\xc5\x4b\xdd\xff\xc9\x1a\x9e\xe3\xf4\xe2\x20\x7d\x44\x43\x08\x63\x26\x9c\x5c\xbb\x15\x4c\xfd\xdd\x3e\x3f\xf8\xa8\x10\x85\xb1\x3b\xef\xf1\x27\x36\xc8\xd4\x7c\xfb\x0e\xd9\x64\x4d\x82\xa4\x18\xbd\x7d\x39\x57\xc7\x4f\xdd\xd4\xd0\xd0\x94\xe8\x8e\x63\xac\x5d\xb5\x57\x99\x9e\x44\x87\x42\xa3\x0d\xc2\x2f\x9f\x44\x39\x51\x84\xa7\x51\x40\x03\x04\x28\xdc\x6e\x97\xbb\xee\x6f\xb1\xad\x0b\x16\x36\x30\x3a\xbb\xe0\xa3\x20\x65\x58\x9d\xdd\x60\x81\xea\xfc\x31\x14\x05\xa0\xb0\x28\xc1\xdd\xe9\x7e\xa8\x0c\x3b\x7a\x91\x28\x30\x09\x93\x5e\x7f\xde\x56\x3d\xa3\xb8\xd1\xb8\x17\x21\x1c\x43\x43\x36\x13\xbf\x13\xc5\xeb\x16\xf2\xfc\xe1\x92\x7e\x9f\x46\x84\x12\x4b\xd3\x66\xc1\xb9\xab\x5f\x59\x3d\x49\x38\xd0\x88\x84\x02\x83\x45\x3f\xd6\xf7\xcf\x0f\xab\xfd\xd5\xfa\xf1\x79\xeb\x07\x81\x44\x31\x22\x86\xb6\x0f\x77\xf7\xeb\x5e\x45\x6f\x14\x4c\xc2\x4e\x36\xfa\x90\x8f\xea\x8c\x66\x47\x8c\x80\xc4\x42\xbf\xbd\x3c\x35\xe5\x6f\xe7\xcc\xf8\x6d\x28\xb5\x94\xb5\x79\xa9\x5e\x91\x56\x61\x5d\x60\x81\xf9\xb9\xd0\x1d\x1d\xc9\xfc\xc0\x86\x34\xc5\x08\xe2\x42\x23\xab\x75\x3d\x3e\x51\xa3\x50\x19\x29\x3b\x6c\x66\x3b\xcd\x27\x2a\x88\xe3\xe7\x88\x02\x2b\x4e\xea\xf5\xf3\x47\x5c\x3c\x34\x8a\xc3\x88\xd2\x4e\x0a\xbc\xfd\x36\xdb\x01\xcf\x8c\x65\x36\x67\xf6\xd4\x3a\xc0\x54\xb6\x80\x46\x49\xc0\xd1\x27\xc0\x30\x66\xf3\x52\x01\xdc\x88\xbc\x86\x05\xf2\x17\xfa\x7b\x24\x3c\x4c\x1c\x49\x18\x66\xd5\x9d\x0d\x0c\xb9\xf8\x98\xde\x2e\x0d\xd1\xca\xc1\x09\xbf\x9d\xcb\xe2\xcc\x0f\x59\xa2\x01\x4b\x1e\x6a\x51\x64\xcd\x07\x3a\xf2\xfe\xc7\x59\x20\xf0\xa4\xdc\xbe\x94\x27\xcf\x73\x34\x1e\x21\x16\xa6\x88\x2f\x7e\x2b\x1b\xd8\x4b\x28\xc0\x64\x2a\x13\xd5\xd8\xdc\x8d\x58\x4a\x10\x93\x69\xc1\xef\x36\x1d\x36\x47\x4a\x35\xc0\xbe\xb4\x17\xc5\xa9\x18\x48\x91\x4f\x7f\x59\xc4\xc8\x90\xf7\x96\x55\xcd\xd9\x0b\x30\x7d\x32\x2b\x98\x10\x58\xae\xb6\x6c\xbd\xe2\xce\xa1\x8c\xd2\x40\xe1\x07\xb8\xdd\xac\x56\x8f\xab\xce\x96\x88\x52\x16\xa2\xf7\x2f\xcf\x75\x56\x40\x5d\x4f\xc1\xfa\x34\x4a\x8d\x94\x49\x0f\x57\x1c\x6d\x40\x91\x48\x28\x16\xa6\x28\x0b\x72\x12\x75\x59\x8c\x75\x33\x07\x2f\x29\x78\xc4\xbd\x69\xd4\xe3\x5e\xbb\x27\x14\x90\x7a\xc9\xce\x87\x6c\xa0\xee\xe8\xdb\xa5\xb2\x3a\x01\xad\xd5\x63\xcb\xc9\xc7\xf3\xd9\x77\xd3\x12\x33\xf4\xe0\xe2\x4b\xbb\x5f\xce\x3b\x1d\xdb\xff\x91\xe2\x61\xda\xb3\xe5\xb7\x36\xcd\xc4\x94\x89\xb4\x34\x48\x9d\x94\xd5\x8f\xf0\x7e\x25\x9a\x26\x1f\x47\x55\x22\x6d\x08\x56\x19\x8a\xbc\x02\xa1\x3f\x26\xfc\x21\x34\x02\x6d\x2c\xab\x04\x22\xde\xda\xa9\x3a\x24\xda\xf7\xbd\x8c\xd2\x91\xfd\x02\x1f\x8b\xd6\xb2\x6d\xae\xb3\xb7\xc1\x57\x18\x4f\x9d\xe1\xef\xc7\x81\xe3\x76\xea\x8e\x41\x0c\xfc\xcc\x6e\x33\x71\x00\x94\x3a\xe9\xbf\xee\x21\x26\x4c\xf8\x34\x26\xc4\x58\x2d\xc2\xb7\xbe\x50\xd5\x41\xa3\xbe\x42\x7f\xd0\x98\xa4\x31\x6e\x1e\x57\xe2\xf0\x82\x05\xa6\xbd\x16\x14\x8d\x69\x6c\xd5\xed\x6a\x7b\xfe\x43\xa1\x27\xc9\x85\x98\x4a\x2b\x60\x03\x9d\xa0\xe0\x24\x59\x45\xe3\x90\x26\x5a\x0d\x0a\x5f\x41\xdf\x94\xd5\x05\xd9\xf9\xf8\x9a\x88\xa7\x0e\x68\x2b\xb4\x35\x54\x7c\x03\x10\x94\x93\x13\xa6\x81\xca\x29\xb1\x97\xd5\xb7\xb2\xf4\xbb\x41\x1c\x73\xe9\xd2\x1d\x75\x53\x95\x1f\x36\x18\x30\xff\xee\xb1\x66\x08\xd6\x73\xc5\x8b\xa2\xdb\x33\xe3\xd8\x30\xa1\x7b\x59\x87\xbb\xa3\x38\xc0\x9d\x37\x53\xe3\x84\xd0\xd0\x65\x6c\x6c\x64\x49\x66\x13\xa7\x28\x4e\x62\x4b\xc6\x51\x3a\x4a\x90\xcf\xa3\xda\x31\xd3\x96\x6c\xd8\x69\x1d\x94\x47\x78\x5e\xed\x10\x39\xf1\xc9\x05\x5c\xa6\x81\x35\x53\xdb\x23\x76\xe9\x45\x03\x68\x9c\x86\x1c\xbf\xa5\x0d\x72\xf4\xf1\xa4\xae\x59\x46\x56\xab\x50\x43\x55\x2f\x45\x81\xe0\xd6\xae\xd0\xf7\x5f\x24\xea\x59\x94\x08\xb7\xff\x9f\xff\x8b\xff\xcf\x7f\x0c\xf5\x46\x3e\xf9\xaf\xff\x09\x61\xeb\x5c\x37\xad\x4f\x5a\x74\xcf\x25\x15\x16\xb4\xbb\x32\xa7\x69\x9d\x24\x8d\x05\x0b\x89\xf6\x4c\x9a\x58\x71\xfa\xfd\x71\xd9\x5a\x61\x23\x98\xcb\x64\x18\x04\x03\x2c\xfd\x7b\x58\xdd\x2e\xf6\xdf\x56\x9b\xf5\xfe\xe1\xf9\x7e\x77\xf7\x74\x7f\xe7\xb5\x1e\x69\x2c\x74\xc4\x3a\x30\x87\x81\x6a\xb5\x59\x5a\x60\x8d\x0b\x28\x67\x65\x61\x39\x60\xa7\x87\xcf\x44\xdd\x65\xfe\x43\x28\x2e\xd1\xad\xb8\x7f\xb8\x1b\x54\xb4\xd3\x58\x81\xc6\x2c\x66\x57\x77\x3c\x54\x8a\xa2\xb1\xe6\x31\x8d\x86\x62\x39\xe8\x60\x8c\x7e\x63\xc8\x3f\x3e\x83\x23\xa0\xb1\x16\x56\xad\xda\xc7\xb3\x50\x1f\x1f\xc1\xfe\xae\x03\xb0\x40\x38\x4f\xb3\x38\x1f\x3b\x55\x47\xdb\x9a\x04\x04\x18\x1b\x14\x5f\xc0\x20\xc8\x35\x7e\xc9\x24\x20\x46\x08\x84\x87\x3d\x3f\x5e\xef\xaf\x17\xbb\xc5\x7e\x39\x30\xb7\x12\x92\xa6\x88\xe3\xf5\x8c\x40\xdf\x86\x55\xc5\x63\xec\xe8\x4c\xdd\x39\x4d\x08\x44\x78\xbc\xc9\x73\x35\x36\x97\x3c\x07\x07\x4d\x88\x31\x36\x3a\x7d\x82\x42\xb7\xcb\xd4\xe6\x49\x3e\xa7\x0e\xa3\x49\xbb\x48\x2d\xd5\x63\xc7\xa0\x39\x5e\x0d\x09\x05\x89\xb0\xe4\xa7\xcd\xca\x8a\x83\xac\xd7\xf7\xfe\x9d\xc2\x20\x70\xa4\x1e\x58\x1c\xe3\xa2\xb3\xf3\xe3\x13\x06\x02\x03\x01\x5e\xe0\xc5\xab\xec\x0f\x4a\xaf\x96\xe2\xf4\xc9\x63\x46\x8c\x62\x85\xc5\x76\x37\x94\x02\xa4\x49\xac\x6d\x79\x08\x9e\x3f\x8b\x61\x99\x09\x4d\x92\x88\x45\x91\x57\x54\xc8\xe1\x20\x74\x79\x0d\xf6\x64\x68\x4a\xab\x0c\x3e\x5b\x66\x45\x93\x84\x71\xb4\xf4\x50\x31\x8f\x5e\xca\x69\xd0\x24\x31\x11\x92\x0b\xfd\x19\xfa\x5f\x63\x81\xd5\x50\x3f\x89\x0f\xbc\x80\xcc\x06\x64\x12\x16\xc7\x88\x4e\x82\x5f\x4d\x25\xac\x9f\x36\x04\x9f\xd1\x84\x09\x1a\xfb\x24\xd2\x16\x23\x10\x58\xd7\xda\x95\x92\xd3\x84\x19\x8a\x45\x0f\x79\xa5\xc6\x1c\xb4\x34\xe1\x01\x15\xee\x08\x74\x3f\xbf\x2b\x27\xb9\xf9\xcb\x2d\xa9\x9b\x61\x3c\x62\xf8\xd3\x77\xbb\xed\xc3\x68\x94\x53\x11\x52\xe6\x6a\x8b\x8b\x9b\x73\x71\xc8\x64\x0e\x57\xa2\x9e\xf1\x72\x92\x54\x0b\x11\x0f\x78\x5e\xf0\x6c\xdd\x36\xe2\x75\x6a\x6c\x26\x22\x14\xba\xdf\xcf\x6d\xce\x19\xf4\x0c\x89\x01\x4d\x44\x14\x12\x24\x6b\x5d\x6c\x6e\x57\xbb\xfd\xf3\xb6\xdb\xb9\x12\x21\x6d\x41\xb7\x25\x83\x87\x62\xc0\x62\xe4\x7b\x80\x44\xaa\x51\x55\xb6\xee\xe3\x72\x7a\x86\x25\x92\x5a\xdd\x28\x6b\x26\x3d\x64\xc5\xa3\x50\x93\x97\x92\xb1\xc4\x85\x05\x85\xf6\xf4\xf4\xbe\x45\x27\x78\x71\xe9\x2a\x28\x86\xdb\x75\xa2\x08\x55\x16\x2a\x9e\x23\x8f\xf2\x5d\x67\xea\x25\x2a\x09\x31\xb4\x68\x35\x91\xdd\x1f\x75\x20\xbc\x94\xe2\x57\xc0\x76\x9a\xe8\x38\x80\x0e\x99\xef\xcb\x95\xeb\xab\x8f\xc9\xb0\x69\x6e\x95\x61\xb6\xdd\x96\x9b\x68\x93\xa2\x67\x8e\xa0\xee\x2d\x54\x6f\xd9\x27\x9a\x7b\x34\x01\x11\x60\x08\xa7\xdb\x9d\x97\x25\xea\x4a\x5a\xf4\xdc\x64\x84\x00\xa2\x74\x58\xc3\x81\x5f\x7c\x86\x46\x82\x26\x60\x42\xaf\xae\xec\x6a\xfd\x7f\x66\x45\x01\xd5\x43\xf9\x06\xc3\x00\x47\x62\x92\xd0\x24\x83\x68\xc3\xda\x18\x68\xf7\xc5\xf9\x31\x61\x01\x4f\x0d\xf1\x2b\x4b\x35\x5d\xf6\x72\x84\x13\x41\xc5\x20\x8b\xbd\x2a\x4f\x2f\x1f\x63\x63\x84\xd1\xd4\xc6\xaa\x2d\xb7\x85\x0d\xdf\x0d\x58\x1c\x28\xa3\xc2\xa2\x3b\x30\x61\x2f\x6a\xb0\xe8\x2b\x91\x7f\x51\x85\x43\x59\x64\xc2\xd8\x33\x49\x94\x99\x05\x6e\x4d\xb9\xe9\x5d\xd7\xd6\xde\x45\xda\xb3\xc5\xe3\xdd\xf2\x69\xb5\xb9\x5b\x5f\xfb\x9f\x8e\x15\x57\xd2\xcf\x0d\x54\x98\x9b\x01\x45\x52\x96\x10\xc0\xc8\xa0\xc3\x9d\x75\xec\x2d\xf3\x9b\x32\x4b\x9c\xd6\x5e\x7d\x96\xc7\x0c\x39\x8b\x3e\x45\x8a\x8d\x7f\x26\x0e\x52\x65\x95\xa8\x31\x53\x76\x75\xce\xf2\x9e\x63\x8d\x32\x46\xb4\xdd\x97\xa1\xd0\x43\x6c\x95\x6f\xa6\x21\xf2\x60\x67\xaa\x1c\x78\x41\xf3\xdf\x95\xeb\x00\x19\xbe\xaf\x76\xcb\x95\xa8\xfa\x2f\xc9\x75\x82\x21\x62\x37\x89\x56\x58\xfa\x66\x85\x49\x5c\x0f\x11\x04\xb8\x15\xdd\x43\x53\x0f\x63\xa4\x4c\x24\x49\xd2\x91\x09\xde\xb7\x9b\xfc\x40\xab\x8c\x32\xc1\xd3\xd4\x55\xe3\xb6\x9b\x09\x78\xef\x6a\xf6\x90\x1e\x0d\x8b\x24\x4a\x3b\x5d\xb4\x66\x8f\xb4\x8d\x9f\x54\x3e\x7d\x9d\x4d\x61\x32\xb2\x8a\x5b\x43\xfd\xbd\x3f\xba\x36\xea\x19\x21\xae\xb2\xe6\xb6\x1d\xf8\x4b\x78\x24\x65\x8a\x1a\x4b\x3b\xec\xbe\x10\x0a\xd3\xff\x3d\x59\xb6\x4c\x69\xc3\x99\x2f\x2d\x6b\x26\x8d\x3a\x0e\xb0\x2a\x30\xab\xd7\x27\x28\x6e\xca\x6a\x04\x77\x60\x5a\x58\x67\x77\xb7\xbb\x75\x99\x72\xd7\x00\xd4\x06\x52\xb6\xcd\x59\x67\x23\x28\x08\x33\x41\x80\x49\x8c\x76\x80\xbe\x75\xc4\x59\x94\x19\x95\x62\x0d\xc7\x76\xb9\x78\x70\x7f\xe3\x01\x91\xb1\x85\x5a\xdc\x15\xbb\xec\xf8\x95\x8d\xcb\x83\x24\x42\xd1\xa7\x5b\x17\x52\xef\xee\xc1\xe3\x00\xbc\x38\x6d\xa1\x37\x1e\x8b\xeb\xcf\x3c\x4e\xb8\xa5\x2b\xb9\x45\x3d\x41\x38\x94\xd5\x47\x9f\x16\x75\x76\x15\xa7\x2a\xc6\x78\xb7\x77\x7f\x6f\x00\x26\x09\xd1\x79\xc3\x97\x47\x01\x84\x36\x55\x5e\x38\x3c\xba\x7f\xb0\x88\x00\x06\xdf\xb2\xfa\x41\xfc\x1a\x10\x3a\xf8\xe6\xd0\x96\x3c\x6c\xe0\x0d\xaa\xda\xc9\x38\xc1\x6c\x25\x25\xe5\x11\x44\x08\xc7\xd3\xd0\x1a\x70\xa7\x81\xe7\xdd\xbe\xbd\x0d\xf7\xb6\xc7\xd2\x23\x80\xae\xad\xf9\xd5\xb5\x93\xc4\x73\xdb\x39\x84\x22\x12\x86\x97\xe7\xe6\x8f\xa1\x7e\xe0\xe4\xb5\x62\x6a\x63\xb2\xa2\x69\x84\x7a\xdd\x65\xf9\xd8\x71\x24\x73\xc1\x63\x1e\xc7\x76\x1d\x6b\x38\x9e\xab\xf6\x2d\x6e\x00\xae\xa1\x38\x1f\xfd\xb3\xb0\xd4\x86\xe5\x6b\x28\xd4\x37\xac\xe6\xf4\x73\x9e\x73\x1e\xe0\x63\x9e\xc4\xc7\xfa\xdc\x20\x5c\xeb\xea\x63\xd6\xc0\xe2\x5c\x5a\xb2\xce\xc2\xb3\xa5\x64\xc5\xa1\x5e\x34\x0d\x1c\x4f\x7d\x7a\x85\x73\x69\x63\x9f\x50\x1c\x2a\xf1\x86\x55\xdd\xf5\x49\x28\xf8\xe3\x0b\x0b\x9c\xa7\xd4\x44\x0e\xf6\xf9\x94\x5f\xca\x96\xff\x4e\x1a\xf7\x93\xc1\x4c\x0d\xe5\xe0\x59\x66\xea\x66\x14\x94\xef\xba\xa4\x42\x74\x0c\x6a\x68\xce\xa1\x40\xc2\x48\x34\x7b\x38\xd6\xa2\xb5\x33\x6d\xc0\xe5\xaa\x2c\x5f\xef\xcb\xc6\xd7\xe6\x52\x2e\xb4\x96\x1d\x3c\x61\x2f\xe7\x83\x11\x5c\x18\x06\x6a\x54\x94\x3a\x5f\xcd\x40\xb9\x64\x09\x86\xd7\x6c\x7d\xe2\x4e\x4f\xb6\x18\xae\xa4\xa5\x6c\x3c\xd7\x50\x7d\x83\x5c\xef\xb2\x7c\x12\xfc\xe3\x4a\xb3\x08\xc3\xd5\x85\x38\xd5\x2f\x65\xb3\x28\xfa\x08\x0e\x3c\x95\xde\x22\xe0\xca\xc4\x28\x7a\x23\xcb\xf2\x35\x2b\x0e\x0f\xd0\x08\x27\x2e\xf4\x1d\x7c\x98\x96\xeb\xc0\xd6\x7b\x0a\xa5\xaa\x33\x5c\xb7\x5e\x06\x14\x5a\x14\x7a\x59\x9e\x4f\xe5\x65\xf9\x9f\xbf\x2c\xd4\x88\x6a\x29\xe0\x7d\x23\x14\xfa\x09\xcb\x72\xb2\xa9\x72\x1d\x83\x53\x42\xac\x9d\x71\x63\xb9\x5b\x3b\xa8\x11\xd7\x90\xa2\x3f\xe5\x5c\xf8\xaf\x83\x4a\x1c\x94\xb5\x59\xfe\x2a\xcf\x95\x2d\xed\x1d\xee\x96\xdc\x84\x04\xd8\x38\x77\x8e\xb5\x41\x59\x71\xb8\x4c\x1e\x73\x13\x0a\x6a\xeb\x31\x3d\x28\x7c\xcc\x64\x6d\xbb\xa5\x41\x0a\x68\x64\x76\x66\xdd\x9d\x06\xb1\x85\x7c\x82\xf9\x4b\x03\x45\x31\xd6\xe0\x74\x09\x7a\xf6\xf6\xd9\xe8\x5b\x1a\x98\x04\x79\x75\x5f\xca\xaa\x86\xed\x4b\x09\x4f\xd5\xe4\x86\x24\x90\xe0\x88\x39\x77\xd9\x34\xd2\x98\x12\xa1\xb0\x3a\xa8\x1d\xb5\x9f\x59\xa1\xcb\x77\xbb\x53\xcd\x17\x57\xd3\x94\x86\x21\x12\x8a\x6c\x4a\xf5\xfa\x24\x4e\x50\x6d\x55\x56\xd7\x65\xf5\x75\x15\x17\x4d\xa9\x53\x9e\xb7\xc8\xcf\x55\xd1\x54\x1f\x0e\x4e\x36\x5a\xec\x29\x4d\x65\xec\x22\x8f\xdf\xcf\xba\x6c\x3f\xb4\xc7\x70\x8f\x5f\x3c\x62\xdc\x2b\xd2\xfe\x7c\x11\xb9\x4d\xe9\xb9\xb6\x24\xb4\x41\x6f\x53\x1e\xba\x3f\xf1\x00\x01\x84\x70\x9a\x64\x33\xd2\x44\x0b\x84\xbf\xff\xbb\x6e\x47\xbb\x99\x6c\x45\xe3\x1f\x65\x12\x58\xef\xb3\x60\x29\x6a\x4f\x2c\x74\x01\xc4\x49\x39\x8b\x10\xe6\x85\xa5\x57\x98\xf4\xf2\x3f\xca\x25\x45\x2a\xaf\x7d\x3b\x1d\x56\x48\x73\xd0\xae\xa5\x81\xfd\x9a\xa6\x41\x8c\xe1\xb0\x0a\x4b\x44\xbf\x06\x23\xa6\x29\xb7\x18\x2c\x47\x64\x60\x83\x10\x03\xba\xe1\xc9\x7b\xa4\x1c\xc0\x71\xb6\x3c\xd9\x15\xe3\xb1\x57\x5f\xe1\xca\x52\xa1\x2d\x79\x8e\x98\x6a\x85\xf9\x76\x00\x61\xe3\xda\x5b\x68\xce\xa7\xcd\xb9\x28\x7a\xe3\x34\x95\x21\xe7\xa4\xa3\xe4\x9e\xd9\x70\x53\x15\x44\x98\x61\xd8\x7f\x80\xa8\x76\xef\x25\xc2\x30\xbb\xd3\x23\x55\x8a\x87\x30\xe4\xbc\xfd\x0e\x1f\x43\xd7\x25\x85\x10\x10\x4a\xf8\xd7\xfa\xe9\xf7\x14\x1f\x34\x85\xc4\x78\x11\x49\xac\x66\x79\x19\x20\xc6\x53\x00\xeb\x95\x5b\x30\xef\xf3\xf6\xfa\xcf\xdb\xd5\xe4\x71\xc1\xc4\x08\x2c\x13\xda\x12\x7e\x88\x7c\xa0\xf0\x4f\x53\x13\x80\xc5\xc5\x1d\x3b\x30\x5c\x6a\x68\xe4\xf9\x7f\xbf\x8f\xef\x26\x02\x6a\x70\xe1\xfb\x34\xd9\x5d\xe1\x59\xa4\xa8\x08\x12\x19\x59\x3d\xa4\xe6\x5c\x15\x77\x45\xc3\xff\xe8\xed\x24\x11\x28\x62\xd5\xc7\xcf\x79\x76\xfa\xa4\x36\x85\x0a\x22\xac\xd0\xd2\x52\x14\xdb\xec\x50\xdc\xf9\xed\x4e\x10\xc9\x30\x16\x6c\xc3\xcc\xb3\x39\xaf\x2f\x13\x8d\x82\x00\xc5\xa4\xb9\x1b\xaa\x41\x45\xf4\x6f\xc0\x4e\xee\x7a\x1a\x28\xdc\x53\x4e\xe5\x7b\xa7\x23\x43\x05\xa5\x01\xa6\xcd\x90\x0c\xd6\x15\x58\xd4\xdf\xb2\xc3\x0b\x20\x71\x6c\xdf\x4d\xa3\xbb\x6c\x45\x53\xd0\x88\x9c\x9e\xaa\x82\xea\x14\xcd\x8e\xff\x3d\x67\xea\xb5\xa3\x76\x77\x8d\x51\x3b\xf2\xed\xd8\x9e\x8b\xa7\x0a\xcb\x52\xbb\x16\x9d\x46\x7d\x9e\x73\x88\xb3\x10\x71\x10\x4a\xf8\x42\x84\xf3\x82\xf0\x9f\x8a\x98\x5a\x68\x06\xe2\x70\x91\x3d\xe7\x8f\x8e\xa9\x67\x1e\x49\x26\xe2\x44\x53\x65\x8b\xf2\x51\x57\xcb\x43\x59\x44\x92\xc4\xc8\xed\xba\xc7\x0c\x52\xaf\x2d\x4c\x45\x22\x22\x34\xf7\xf6\x6f\xb6\xbc\xbc\x69\x17\xe0\xc0\xa8\x16\x2c\x20\xe8\x42\xd6\x22\x07\x67\xee\x0d\x4f\x52\xc1\x22\x1d\x4b\xaf\xbd\x5c\x1d\xd1\xfb\x9f\xcc\x24\x96\x58\x68\x68\xe3\x89\xec\x86\x83\xc6\x24\xc7\x0c\x08\xd6\x8d\x5f\x7f\xe2\xb0\xcf\x0c\x0f\x53\x96\x99\x00\x95\x48\x23\x32\xfd\x49\xcd\x95\x2d\x6c\x2f\x0e\xcd\xcb\xea\x7f\xcf\x22\x1f\x8c\xde\x9c\xaf\x2c\x98\xb1\x3e\x56\x56\x7f\xff\x6b\xe9\x20\xa5\x7a\x57\x6e\x3b\xae\x15\xff\xc4\xdc\xc9\x86\x1c\xb3\x62\x2f\x06\x3c\x76\x54\xf0\x24\xc1\xe8\x8a\x38\x4a\x51\xd7\x42\x97\x55\x3d\x24\xfb\xa2\x82\xf3\x04\x93\x39\x45\xf3\xb2\x29\xcb\x66\x20\x96\xe7\x87\x3b\xe5\x11\x92\x03\xe1\x11\xf0\x90\x15\xa0\x17\xdd\xed\x53\xa0\xa1\x97\xae\xa9\xde\x86\xb2\x68\x54\x08\xc2\xb1\xea\xd9\xb2\xaf\xef\x57\xcb\xf5\xf6\xaf\xed\x6e\xf5\xd0\xb5\x87\x51\x28\xba\x28\x9e\x9d\x4e\xa3\x50\x63\x37\x89\x44\x1a\x46\x96\x3d\xe5\xd7\x5c\x09\x25\x15\x42\x32\x2f\xb8\x7b\xfb\xb4\x1d\x22\xee\x48\x72\x99\x57\xbe\xcc\x31\x0b\x09\x80\x85\x75\x4f\x28\xb5\xf3\xcf\x12\xe6\x42\x09\x1d\x27\x7e\x39\xec\xab\x61\x06\x42\x68\x4a\x3c\x53\x51\x03\x7d\x65\x55\xf7\x4a\x3a\x54\x58\x8f\xb3\xde\x2d\x31\x7b\xd5\x5d\x17\x4b\x5c\x95\xfb\xac\x5e\x55\x6a\x57\x3e\x8a\x26\x7b\x83\xab\x2a\xd3\x87\x49\x78\x5d\x68\x65\x15\xf0\xdb\xbd\xff\x2c\x2a\x9d\x89\xe2\xc7\x45\xed\x83\xd0\xca\x96\x48\xec\xd6\xbb\xc5\xfd\x7e\xb9\x7e\xdc\x6d\xee\xae\x9e\x77\xeb\xcd\x28\xc7\x20\x80\x45\x9e\x05\x64\x59\x66\xc5\x06\x8e\x22\xeb\xe7\x17\xa4\x80\x28\x2b\x9c\x02\xf5\xb2\x2c\x2b\x9d\x15\x73\x4c\x2a\xae\xbf\x61\x12\x65\x15\xb7\xaf\x1f\x60\x49\x0f\x1c\x56\xef\x2b\x48\xb9\x30\x3c\x88\xc1\x85\x7e\xec\x87\xf8\xea\x28\x97\x81\xdb\x12\x7b\xf2\x97\xf1\x00\x49\xca\xb5\xd7\xe4\x40\xb4\xe7\x3f\xc2\xeb\x4a\xda\x1e\x9b\x88\x9f\xb3\x5e\x52\xbb\x5e\xdc\x38\xc8\x30\xd0\xa1\x43\x0b\xdf\xdf\xff\xb0\x84\xee\x61\x30\x32\x47\x65\xc8\x85\x4c\x3b\x48\xc0\xf3\x94\x5c\x83\xca\x30\xb5\x7c\x9b\xab\x9f\x57\x43\x9b\x5d\x86\x26\x46\x56\x75\x28\x74\x57\xfe\x48\x65\x14\x49\xaa\x06\x02\x87\x78\x7c\x7e\x32\x22\x11\xa4\x08\xec\x5a\x80\xca\xfa\x87\x8e\x0c\x41\x4c\xff\x72\xbd\x7e\x1a\xfd\x60\x1c\x70\x14\x18\x81\x3c\x3b\xe2\xe7\xdc\x5e\x2f\x97\x5f\x1b\xc1\x32\x8e\x6d\xe5\x15\x38\x8b\x71\x63\x0f\x96\x01\x1a\x46\xc6\xa9\x42\xa4\x8a\xab\x60\x2c\x9b\x6e\x25\xe2\xaa\x76\x27\x04\xa1\xc3\x50\xa7\x8c\x21\x40\x88\xfd\xfd\x7a\xf9\x7d\x75\xbd\x5f\xdc\xdf\xaf\x97\x8b\xdd\xdd\xfa\x71\xff\xf4\xe4\x77\x0c\x99\x04\x09\x86\xbe\x91\xff\xb9\xd0\x03\x18\xaa\x4c\x48\x64\xb9\x07\x1a\x38\xa2\xc5\xdd\x83\x34\x24\x0b\xd2\x48\x74\xb0\x7a\xeb\x77\x39\x22\xc1\xae\x4b\x1c\x7b\x21\xd1\x75\x95\x1d\x5a\xfb\x65\x99\x67\x3d\xc0\x42\x32\xc3\x71\x1f\x3d\x42\x23\xee\x8a\x7f\x12\xc3\xfd\x64\x7a\x71\x22\x89\xa5\x10\xa8\xcb\xfc\x0d\x9c\xb5\x7b\xf5\xf1\xcd\xab\x42\x74\x1c\x96\xfe\x02\x11\x23\x98\x0c\xc1\xbf\x4f\x50\xd5\x83\xa7\xe2\x1a\x88\x15\x35\xe8\x8a\x0e\x6d\xb0\x68\xfd\xd6\xed\xf0\x32\x0d\xa8\x70\x9b\xe3\x1b\xaa\xbc\xcb\xf2\x3c\xc8\x4b\x7d\xf2\x9c\x29\xb1\x4c\xbd\x35\x4c\x03\x84\x52\x70\x1a\x7b\xbc\x52\x7b\x6e\xf6\x06\xb2\x14\x82\x20\xc5\xb5\x5f\x93\xff\xb5\x99\x5e\x2b\x98\x97\x4f\xb8\x6b\xca\xd5\x8c\x58\x3c\x95\x2a\x4e\x90\xce\xe5\xae\xc6\x32\x99\x9b\x0a\xe0\xef\x0b\x7f\x78\xa8\xb9\x4f\xa5\xe2\xc6\xaa\xdf\xb4\x76\x00\x6d\x66\xb2\x07\x6d\x17\x0c\xd1\x67\xf5\xfa\xe1\x0e\xd7\xc1\x7d\xa9\x5e\x27\xa5\x1e\x52\xa5\x14\xc3\xcf\x78\xa3\x27\xa8\xb6\x83\x49\x02\x61\x84\xd8\xbf\xff\xde\xa1\xe6\xdd\xde\x55\x1b\xef\x4f\x83\xcc\x8d\x04\xa5\x01\x3a\x4e\xd6\x4c\xd9\x33\x7e\x6c\x6e\x4a\xd0\x0a\x7a\xb6\xc7\xac\x2c\x86\xd1\x67\x69\x02\xe6\x58\xdd\xfe\x7d\xae\x9b\x99\xba\x45\x69\x8c\xe5\x17\x36\x38\x34\xee\x1b\xdc\x94\x13\x2b\x47\x05\xa1\x8d\x7a\xa8\x41\xa2\x14\xcb\xc2\x7c\x3b\x30\xe1\xf2\x9c\xbd\x0c\xe1\x67\x71\xe7\xd1\x1b\x28\x12\xdb\x68\x85\x67\x20\xd9\x4b\x51\x67\x6a\x6f\xb1\x63\xfe\xfe\x84\x45\x08\x6e\x3d\x76\x44\x29\x37\x65\xe5\x11\x79\x5d\x27\x6d\x22\x35\xb0\x43\xaf\x11\x44\x57\x56\x57\xe3\x99\xa3\x28\x93\x8e\x9d\xa1\xb9\x01\xb8\x3a\x4d\xbe\xaf\x0a\x03\x12\x7b\x04\xee\x1f\xb3\x58\x03\xd7\x31\x4a\xac\x0b\xb8\x3d\x1f\x8f\x1b\xf0\x46\xb4\x8a\x04\x60\x66\xe1\x1d\x43\x1f\x37\x65\xcf\xc3\xe0\x7b\xc4\x21\x43\x37\x1b\xf5\x8e\xec\xb1\x36\xa2\x68\x98\x39\xd3\x54\xac\xac\xe9\xf2\x98\x15\xff\x16\xcb\xb2\x82\xee\x66\x4a\x26\x1e\xa7\x8e\x16\xdb\x40\x40\xd8\xf7\x49\x02\x89\xfe\x54\x33\xa8\x9c\xdc\x95\xa8\xa2\x74\x59\xee\xa4\x92\x94\x48\x37\x40\x3f\x45\xd5\x55\x5b\x4e\x7a\xb1\x80\xc5\x1e\x47\x88\x65\xc6\xad\xcd\x36\x0e\xf7\xcc\x6f\xfd\x8a\x29\x5b\x62\x70\xcc\x8a\xb2\x1a\x0c\x0b\x83\x88\xeb\x51\xea\x18\xea\x5d\xd9\xf1\x5d\x0f\x0c\xe6\xd1\xc8\xf0\xf6\x49\xdc\x0c\xc2\xec\xfb\x37\xe4\x45\xb8\x81\xa6\xc3\x9d\xab\x94\x28\xb4\x4a\x5a\xc3\xaf\x7d\x9f\x9b\xb2\x72\xce\x7e\xd7\x43\xc4\x08\x7c\x71\x50\xdb\xcf\xc4\x20\xa9\x4a\x21\xc5\x18\xd2\x29\x17\x0a\x3c\xf3\x9e\x07\x7b\x28\xc1\x2c\xe1\xd5\xae\x3a\xc3\x0f\x38\x88\xa2\xe7\x05\xa1\x4a\x72\x81\xd5\xfc\x23\x0e\x88\x8b\x4d\x7f\x3c\xcc\x8a\x18\x1c\xac\xd7\xa2\x75\x06\xc6\xf1\x1a\xa5\x74\x80\x96\xaf\x86\xfc\x67\x59\x8d\x6b\x9b\x95\x8e\x63\x4f\x87\x7b\x77\x3c\x09\xd5\xdc\x67\xc5\x2b\x4c\x3b\xb1\x20\xe8\x0a\x06\x2c\xd8\x74\xf5\xeb\x24\x8a\xf6\x48\x1e\xb9\x06\x4a\x33\xc9\x6d\x71\xd0\xb9\xd0\xb8\xd7\x58\x7c\x61\xd7\x0e\x61\xe4\x4e\x87\x87\xac\xc8\x9e\xca\x32\x5f\xb5\x66\x4d\x3c\xfe\x41\x00\xee\x59\xc0\x37\x0e\x87\xf9\x84\x4a\x26\xf3\xe1\x19\x05\x26\x8c\xba\xa4\xe3\x5b\xd6\x3e\xd7\xdd\xc9\xd4\xa3\x8a\xe2\xf1\x07\x32\xa1\xc4\x9d\xb7\x02\x65\xc5\x13\xa7\x1b\xd1\xf8\x07\x0c\x88\xc4\x51\x2c\xb4\x07\xf9\x32\x2f\xeb\x11\xbd\x38\xd5\x41\x00\x68\x62\x0b\x84\x55\xfb\x8d\x7e\xb2\x6d\xe8\x80\xb1\x48\xf4\xf7\xb1\xb4\xf1\xa3\xdb\xa4\x0c\x23\x71\x0b\xad\x31\x36\xb2\x43\x35\xcd\x9b\xaa\x3c\x2e\xaa\x4a\x7c\x5c\xfa\x70\x97\x9e\xa1\x26\x49\x88\x8b\x6e\xdd\xee\xf6\x9d\x65\xa6\x69\x90\x9a\xb8\xa7\x33\xf5\x99\xfb\x89\x4f\x1d\x8f\xdf\x5c\xd3\xd4\x38\xf1\xda\xa6\xd3\x11\xc3\x30\xe4\xdc\x6e\xa7\xa9\xe1\xb2\xb7\xc6\x26\x32\xa4\x4e\x97\x7b\x04\x7c\xd2\x21\x8d\x39\x32\xe5\xef\xd6\x9b\xd5\xf5\xdd\xed\x1f\xdd\xdf\x53\xb4\xeb\x3a\x31\xab\x4b\x74\x8b\x0e\x59\x82\x78\xd8\x53\xeb\xcd\x39\x3e\xd0\xb1\xc0\x1a\xd5\x21\xe7\x98\x59\x6b\x3d\x8c\xbe\x70\x47\x87\xa9\x2d\xf9\x5f\x56\xa0\xcb\x7f\xc4\x3a\x42\x75\xc4\x62\x5f\x3d\x81\xc9\xbb\x6f\x20\xaa\xa6\xbe\xfa\xb8\x16\xa7\xd3\xb4\x98\x5e\x47\xd2\x6a\xa1\xfd\xc8\x9a\x07\x51\x0c\x2d\x61\x1d\x27\x21\x06\x45\x17\xbf\x32\x18\x6c\xd2\x3a\x36\x60\x69\x03\xad\xda\x9a\xcd\xa5\x4d\x76\x54\xcd\xa2\x08\x77\x16\x03\x58\xd1\x8c\x0f\x32\x14\x83\x9a\x3c\x33\x57\xd6\x33\xbc\x29\x2b\x54\x33\xea\xf6\x19\xcd\x21\xc2\x62\xa2\x17\x51\x5f\x01\x14\x1b\x78\x03\x91\x7f\x42\x71\x4c\x75\xca\xc2\xd0\xd7\xc6\x2f\x9e\x77\xeb\xfd\xc3\xe2\xf1\xd9\xdf\x2a\x4d\x3b\x66\x50\xc7\x8a\x95\xc9\x29\xf2\x42\xa7\xd2\x92\x97\x9e\x8b\x93\x38\xd7\xd0\xb3\xfe\xf8\x76\x43\x42\xdd\xd1\x09\xae\x44\x55\x64\xc5\xc1\x52\x36\xd6\x4e\xa2\x77\x7c\x43\xa1\x53\xa4\x05\xc5\x92\xb6\xf6\xcd\x7e\x64\xf0\x3e\x1a\x68\x49\x43\x2b\x46\xbe\x59\x26\x8c\x7d\x06\x51\x9d\x03\x43\x68\x4d\x2d\xcd\xc4\x05\xa8\xc3\xb7\xc7\x34\xed\xb6\xc4\xa1\xce\x2b\x36\x81\x65\xe9\x19\x10\x8e\xb9\x36\x80\xd0\x47\x50\x57\x16\xfa\xe6\xa8\x46\x5c\xbb\xe9\xad\x67\xe4\x7b\xf3\x76\xd2\x6f\xec\x67\x6d\x8c\x15\x84\x44\xcf\x14\xaa\x26\x13\xd5\xc7\x95\xc5\xab\x4c\x86\x0d\x82\xd8\xaa\xb7\x21\x45\xce\x50\x13\x83\x42\x90\x6a\xa4\x8c\x3c\x22\xa2\x72\x7c\x08\x40\x00\x29\x77\x2a\x0b\x53\x1b\x1a\x08\x57\x84\xfa\xe3\x6e\x0b\x79\xbe\xae\xf4\xe7\xdc\xdc\xe3\x67\x07\x1a\x70\xa4\x23\x68\xf0\xa4\x18\xc0\x95\x81\x2a\x81\xb8\x24\xac\x19\xd9\xff\xbc\x7b\xbc\x5e\xff\xdc\x47\xfb\xd5\xe3\xf5\xb0\x1a\x0c\xa8\xe1\xb8\xb1\x61\x64\x64\x6c\xbf\xbb\x1e\x21\x0f\x90\x53\xa5\xa9\x00\x8c\x1f\x6c\x08\x55\x8c\xd9\xda\xa6\x3c\x1c\xf2\x8e\x39\x76\x7b\xae\x4f\x80\x47\xdb\x68\x29\x78\x0f\x09\x42\x63\xa1\x7c\x55\xa6\x5e\xc0\xe5\x41\x3b\x28\x31\x44\x41\x88\xf5\x01\x7b\x6b\x2c\x5f\xcc\xb9\xf1\xab\x47\x69\x62\x42\x2f\x5b\xd7\x8e\xb6\x6a\xb0\x9a\xb2\x19\xc6\x4e\x21\x32\x14\x6d\x51\x51\x14\xa5\x95\x22\x1b\x61\x85\x20\x32\x31\x62\xa5\x96\xae\x66\xcb\x40\xb5\xf7\x3c\xe9\x1e\x70\xdf\xdf\x2d\x26\x3c\x51\x3d\x03\xdc\xae\xfc\x1a\x1b\x00\xb1\xb2\x8c\x52\xfb\xae\x00\xfe\x72\x27\x86\x84\x59\xc1\xdb\x1e\xf0\x3b\x5b\xb8\x01\x89\x50\xc2\x62\x25\x5a\xcb\x06\x77\xe4\xf6\xf4\x1b\x28\x40\x50\x48\x80\x22\x88\xce\x97\xe4\x09\x99\xc3\xc8\xca\x00\x9e\x10\x70\x84\xa1\x6f\xa2\x81\x7d\x3b\x7c\x98\xf4\x59\x3c\xdd\x7d\x87\x71\x15\x08\x70\xa6\x2c\xb8\x3b\x7b\x73\x34\xfb\xf3\xc5\x56\xc0\x21\x41\xff\xc4\xa2\x47\x30\xf4\xf8\xc9\x67\x4b\x89\xc1\xdf\x77\x2e\xd9\x93\xa8\x9a\x02\x2a\x0f\x60\x1c\x44\xfa\x20\xe5\x56\x18\xd7\xbb\x1b\x57\xff\xfd\x6b\x5e\x9f\x8a\x82\x20\x20\x83\x9e\xf7\x07\xa9\x2a\x3e\x07\x8d\x83\xa0\x90\xb8\xec\x47\x56\xbf\x58\xf8\x73\xbe\xb2\x43\x96\x15\x07\x87\xe2\x98\x5c\x13\x49\xdc\x62\xfb\x02\xb5\xdf\xe6\x7c\xda\x6b\xb8\x8b\x08\x3d\x9e\x8f\x3e\x99\xdf\x7d\x0a\x91\x10\xac\x59\xd5\x59\xdd\xec\x35\xbc\x41\xde\x7a\x99\x9f\x3d\x33\xa3\x91\xf5\x42\xac\x80\xc8\xbd\xe8\xf7\x1e\xc1\x25\xba\xe1\x0e\x10\x76\x35\xe3\x20\x0c\x91\x1e\xfe\x2a\x49\x30\x50\xb2\x5c\x3f\x3c\xdd\xdf\x2d\x1e\x97\xdd\xa6\x20\x74\x1a\x11\x4f\x8e\x98\xc3\x61\x58\x59\x3e\xfc\x42\x02\xac\x8e\x26\x86\xdf\xdb\x3d\xd7\xfa\x29\x9f\x07\xde\x41\x02\x15\xa2\x23\x31\xf8\xab\x3c\x57\x13\xae\x14\xd7\x4f\x91\x14\x9f\xcd\xf2\xce\xba\x9a\x9d\x59\xfb\x15\x14\x70\xf4\x6f\x1d\xe5\xdc\x3e\xab\x73\xd1\x17\xf8\xfc\x53\xc0\x86\xbb\x99\xa6\xca\x0b\x93\xfd\xd7\x59\xe4\xc8\x72\xfc\x05\x08\x03\xb4\x08\x62\xd3\x05\xac\x3a\x03\x6a\x57\xe2\x11\x3d\x28\xe7\x05\x48\x2d\x37\x33\xa6\x3a\x0e\xdb\xec\x50\xac\xab\x83\x28\xb2\xbf\xfb\x2c\x14\x80\x0a\x05\x1b\x30\x3f\xb6\xb3\x6c\x8c\x00\x9c\xe5\x9c\xa5\x00\x46\x72\x6f\xf3\x8b\x0a\xf5\x26\x6b\x5c\x2b\x93\x49\x6c\x48\x84\x0e\xf5\xbb\x17\xa6\x1b\x52\xc9\x8e\x4b\xe5\xc0\xc4\x51\xcc\xa7\xc4\xca\xeb\xa7\xad\xd7\xbd\x19\x6f\x2b\x26\x11\x18\xc0\xa8\x0e\xd2\x6e\x48\x93\x1f\x4e\x03\xf0\x65\x69\xd3\x7c\xdd\x4c\xda\xae\x3b\x30\x8c\xb0\xc8\xdf\xed\x4b\xf9\xde\xf3\x01\x53\x13\x44\x34\xf2\x88\xe0\x2a\x53\x30\x34\x5d\x0c\xa1\x9c\x38\x22\xbb\xe6\xee\xfa\x7e\x92\x49\x35\x24\x0c\x88\xd5\xa2\x5e\x2e\xc7\xd7\xc5\x29\x2a\x03\x5a\x05\x0f\xb0\x69\xdf\xd6\x7d\xa7\x9f\x6d\xf3\x5f\xcf\x26\x13\xca\x10\x29\x68\x51\x5d\x7f\x21\xdb\x6d\xb6\x58\xbf\x41\x55\x65\x53\x04\x8d\x89\x88\xb1\x1c\x77\x2e\x9f\xba\x41\x99\x81\x49\x9f\xc8\xe6\x01\x2d\xde\xda\xb3\xeb\x5c\xce\x4a\x13\x81\x42\x4a\x96\x4e\x69\xdd\xff\xdd\xc4\x68\xf5\x59\xad\xdd\xcd\xea\x66\xb5\xd9\x2c\x3c\xd0\xdf\xc4\x54\xf8\x8c\xf7\xa2\x69\x5c\x44\xdf\x46\x3c\x9e\xa0\xfa\x09\xd9\xdd\xf0\x5c\xec\x1f\x2b\x66\x86\x98\x81\xb7\xf1\x5c\xd4\x65\x3e\x8b\xf1\x36\xb1\x00\x5f\x5c\xbc\xec\x78\x9a\xb3\xb2\xf0\x07\x9e\xef\x26\x25\xe6\xba\x9f\xbf\x8f\xbe\x4f\x6c\x94\xd2\x7d\x8a\x74\x57\x3e\x1c\x8e\xcd\x0e\xc4\x27\xdb\xbc\x49\x62\x8d\x9e\xf0\x55\xd6\x60\xed\x40\xf6\x3b\x49\x45\x6a\x92\x54\x30\x87\x95\xbb\x3a\x57\x9e\x7a\xbc\x1e\xd9\x0c\x26\x51\x21\x56\x79\xb4\x13\xf2\xa2\xd0\xd0\xb0\x80\x5a\xbb\xa4\x11\xaf\x5e\x7a\xad\x6b\x23\xdc\x61\x8b\xd4\xeb\x6e\xb7\xb4\x4b\xd4\xb7\x45\xc2\x70\xcf\x54\xd1\xae\xff\x71\x28\xc2\x30\x07\x56\x91\x8d\x5a\x35\x2f\x9b\x3e\x0a\x69\x78\x68\x55\x27\x4f\x65\x99\x6f\xcf\x72\xf2\x79\x04\x48\xed\x04\x77\xbc\xb2\x00\xba\xc4\x7d\x02\xc1\x77\x34\xbc\x0f\xbe\x6f\x77\xcb\xeb\x8d\x29\xab\x2b\x84\x00\x38\x49\x73\x1b\x7c\xf2\xc6\x86\x91\x71\x64\xcb\xb6\xbf\x2d\xb6\xab\x3d\xdd\x3f\x6d\xee\xba\x33\xc4\x48\xc7\xe4\xf7\x70\xf7\xb8\xbf\x7b\xfc\xb1\xda\xee\xf6\xdb\xe7\xa7\xa7\xf5\x66\xd7\xf5\x48\x59\xe0\x4a\x17\x1d\x0b\xdf\xf8\x79\x54\x94\xe2\x89\xab\x41\x21\x8c\xd0\x52\xb9\x8c\x5f\x4e\xb1\x58\x5b\x31\x4f\x5b\x70\x5d\x89\x42\xbd\xc0\x9d\x79\x04\xe8\xc9\x41\x8c\x26\x82\xa9\xce\x39\xdc\x4c\x80\x07\xbe\x13\xb7\xea\x3a\x4d\x09\x2e\xfe\x89\x64\xbd\xdd\xf8\x6b\x69\x9c\x8a\x8e\xcd\x29\x78\xd4\x99\xd7\xae\xfc\x64\x12\x82\x32\x3c\xea\xb5\xd1\x9e\x8b\xac\x99\xfa\xbb\xc6\x10\xcb\x4a\x88\x89\x83\xfd\xe9\x62\x4a\x19\xca\x31\xdd\xb6\xef\xf0\x5c\x1e\xbf\x39\x17\x9f\x31\x26\xd4\x16\xf0\x9b\x1d\x0a\xd0\x57\x1f\xdb\x8f\xba\x81\xe3\x98\x1e\x0e\xbb\x86\x41\x48\x23\x5b\xf8\x0a\x45\x5d\x56\x8b\x42\x2f\xcb\xdf\x94\x89\x87\x41\xd8\x2e\x92\xee\xcc\x73\x47\xbe\x6f\x13\xb1\x27\x7c\x42\x8b\xba\xac\x3c\x80\xef\x8f\xf1\x3d\x40\x13\x7b\xb8\x9c\xeb\x06\xf4\x73\x91\x21\x06\xf6\xea\x3c\x4f\x8a\x1c\x06\x11\x03\x34\x08\x10\x06\x90\x9f\xd5\x6b\xf7\x93\x71\x18\x21\xa4\xb4\x80\xf7\x1f\x03\x86\x42\x92\xfc\x2b\xfc\x9f\xb1\x48\x45\x77\x81\x61\x81\x7f\xfe\x09\x43\x90\xef\xa2\x12\xe4\x48\xdf\x63\x79\xe0\x7c\x6e\x73\x36\xda\x15\x06\xb1\xb6\xec\xcb\xd6\x1a\x79\xaa\xca\x63\x39\xf0\xeb\xd1\x74\x7f\xc8\x0a\x0f\x94\xb0\x41\xa8\x19\x7b\xe9\xeb\xff\xe7\x7e\x2b\x49\x0d\x6e\x27\x7b\xac\x5b\x9e\xd9\x71\xc3\x80\xd1\xc0\xd6\x42\x60\x04\x03\x57\x71\x0e\x15\x46\xa3\xbc\x7f\x55\xfb\x91\x64\x61\x82\xb8\x87\x6b\xc8\xb7\xa5\xca\x44\xee\xad\xf2\x29\xb1\xe0\x30\xe7\x1f\x06\x2c\x0a\x70\xe3\xda\x57\x50\x9f\x8f\x80\x05\x06\xe3\x8f\xc7\x24\x47\x52\x43\x9d\xd5\xc7\xac\xb6\xdc\xf6\xeb\x93\x2d\x57\x9d\x3c\x2f\x4f\x00\xad\x8e\xac\xb6\xce\xa8\xa3\xa7\xf7\x8f\x28\x1c\x68\x6b\x51\x15\x65\xae\xfb\x90\x4c\xdb\xa2\x11\x8b\x62\xe9\x52\x26\x77\x15\x44\x20\x7a\x7a\x7f\x04\x2d\xf2\xe7\xc2\x39\xba\xe3\xa7\x14\x21\xc1\x38\xc0\x66\xb5\x5c\x6f\xae\xe7\x04\x98\xff\xc9\xa9\x1f\x06\x22\x35\x68\x90\x3e\x17\x2a\x1f\x1a\x26\x61\x20\x74\x84\xc9\xf9\xb7\xb2\x81\x0b\x03\xb5\x3b\xbf\xc3\x40\x92\x14\x59\x99\x91\x66\x20\x2b\x6a\xa8\x9a\xbd\xe3\x79\x04\xa1\xfd\xdd\xa4\x56\xa9\x0b\x3f\x7f\x83\xaa\xb4\x8a\x82\xf5\xe4\xa5\x94\xab\x58\xbc\x2f\x0f\xcf\x36\x78\xe4\x2f\x57\x49\x88\x71\xef\x3d\xba\xfe\xbb\x32\xcb\xa1\xb9\xc9\xcf\xf5\xcb\x1f\x17\xbe\x42\x18\x68\x4a\x31\xbc\xb6\xfc\xb9\xfd\xe2\xfc\x0c\x03\x2d\x89\xe1\x9d\x94\x65\xd7\x75\x74\x2f\x48\x03\xe9\x34\x03\x76\xd9\xe9\x9f\x80\xec\xc3\x00\x0c\xf5\x64\x6c\x5e\x22\x13\x8d\x5c\xff\x32\x86\x0a\x1c\x8b\xfd\x67\x18\x29\xdb\x8f\x04\x4c\x21\x01\xd7\xdd\xf2\xba\x17\x70\xf1\x6d\x8a\x62\x74\xf0\x5a\x64\x35\x74\x7f\xa5\x91\x02\x3d\x30\x83\xef\xbb\xea\xc3\xb6\x0d\x20\xf5\x02\x83\x42\x35\xd7\xd0\x60\x42\xac\x6b\x17\x02\x51\x70\x75\x56\x1c\xf2\x8e\xcf\xa9\x23\x64\x0d\x09\x55\x01\x72\x5f\x74\x3a\xc0\xee\xef\x21\x93\x48\x22\x20\xcf\x59\xae\xbd\xd9\xb5\x15\xb9\x3d\xfe\x86\x85\xb0\x73\x53\xd3\xc5\x87\x43\x12\x72\x40\x2b\xd9\x49\xbb\xe2\x01\x7c\xff\x57\xf7\x23\xa9\x0a\xf4\x80\x9c\xaf\x3d\xf2\x2c\x1b\xd5\xec\xbc\x26\xa1\x0c\xb1\x42\xe2\xba\x12\xef\x5d\x34\x2f\x24\x21\x40\x6c\x5d\xba\xba\xe9\x9d\x67\xd7\x18\x51\x4a\xa0\x77\xce\xae\x3b\x27\xf7\x0b\xbd\xab\x90\xc4\xc2\x6a\xe8\x1c\xb0\x4a\x7e\xfb\x22\x2a\xb0\xf5\xf8\xf5\xda\x2c\xaa\xe6\xfd\x62\x87\x21\xb1\x30\x18\x20\x6d\xbd\xe2\xa3\xa8\x5e\x07\x3b\x03\x89\x8d\x3d\xe3\xda\x55\xa7\xbf\x67\xea\xb5\x34\xc6\xb7\x25\x51\x1c\x82\x27\x96\xca\x14\x90\xc9\x7d\x99\xe0\x7c\xf8\xf5\xb7\xf8\x25\xbf\x4c\xbf\x85\x84\xa9\x08\x2d\xc0\x0a\x30\xa6\xb7\x28\xb2\x63\x17\x4c\xf2\xf8\x8a\x6e\xb1\x13\x1e\xa7\x88\xd5\x97\xa2\x51\x2f\xed\xec\xb2\xc9\x8a\xcf\x7c\xe8\x90\x70\x19\xc5\x2e\xf0\xf5\xa3\x6c\xa0\x79\x2e\x1a\xa7\x24\xca\x5d\x8f\x54\x46\x9d\xe8\x2c\x54\x35\x16\x67\x8d\x1f\x31\x85\x18\xb7\x85\xce\xa0\xb0\x81\xa9\xf1\x62\x11\x41\x60\x63\x83\xbe\xd3\x0f\xa8\x9b\xae\x7a\x73\x7c\x43\x11\xca\xc0\xb2\x55\xb5\x76\x2f\x7c\x1a\x7c\x09\x89\x50\x0c\x17\x94\x7a\x29\xcb\x1a\x9e\xc0\x7d\x4b\xff\xec\x92\x58\x5b\xe7\xbe\x3c\x6c\x91\xed\x6b\xb8\x11\x0f\xf7\x1a\x22\x43\x8a\x96\x55\x3b\x66\x3d\xfd\x51\x48\x24\x68\x54\xbd\xec\x39\xe0\x3d\xef\xd6\xfc\x03\x29\x6a\x10\x2a\x6c\x00\x36\x20\x3b\xbb\x3a\x24\x8a\x29\x9f\xc7\x76\x55\x94\xce\x5d\xfe\x40\x48\xf9\x2c\x48\x3e\x24\x40\x54\x1a\xf5\xb5\x1e\x23\x50\xc0\xe4\x97\x81\x80\x72\x6a\xdb\x0f\x5e\xaa\x19\x67\x7b\xdd\x97\x46\x74\x4b\xc9\x04\xa1\x51\x7d\xfa\xef\x78\x3e\xb6\xd6\xd2\xf8\x86\x26\xb2\x1e\x6c\x2e\xea\xe6\x4e\xf7\xbc\x65\x21\x31\x69\x88\xb4\xe0\xf6\x18\x19\x39\x5f\x5f\x17\xa8\x9f\x7b\x16\xdf\x90\x18\x19\x22\x68\xe4\x69\xb3\xda\xe3\x8e\x72\xfb\xb0\xd9\x5b\x6f\x72\xb9\x78\x72\xbf\x45\x03\x92\x24\x9d\x81\xf8\x8c\x50\xd9\xcf\x72\xb0\xe3\x01\xa1\x41\x12\x62\x10\xbd\x6a\xb7\xe0\xeb\x32\xcf\x45\xf5\xff\xe3\xec\xcb\xba\x1b\xc5\xb5\xfd\xbf\x4e\x3f\xf4\x03\x68\x00\xf1\x68\x3b\xce\x70\x2b\xd3\xb1\x9d\xaa\xea\xff\x59\xbd\xbc\x84\xb4\x95\x70\x0a\x83\x1b\x70\xaa\x7c\x3e\xfd\x7f\xb1\x25\x31\x99\xa4\xfb\xde\x97\xae\x5e\x41\xc6\x18\x84\xb4\x87\xdf\x50\xdb\xc7\x08\x3f\x27\xf4\xa3\xe0\x77\xfb\x8f\xff\x64\xcc\x51\x29\xc9\xe5\xcf\x2b\xab\xf2\xff\x77\x86\xaf\x94\x84\xb2\x53\x04\xc5\x76\x90\x6b\x1c\x62\x64\x3b\xcb\x3e\xa2\x24\x34\x06\x81\xe7\xbd\xeb\xbb\x05\x53\x7e\xf4\x13\x67\x77\x22\x42\x42\x89\xf4\x9d\x53\x91\x8e\x6e\xd0\x28\xb6\x22\x24\x62\xa9\x57\xd7\x2e\x0f\x87\x0c\x49\x94\x53\xdb\x05\x4a\x88\x88\xc5\x90\x46\x7b\xe1\x53\xf3\xef\xe8\x4f\x3f\x54\xdb\x24\xba\x9d\x22\xd8\xcc\xdf\xcb\x30\xf2\x4f\x8e\x1a\xc0\x0a\x83\x94\xe3\x89\x45\x78\x18\x21\xa1\x44\x97\x8b\x31\x1c\xbf\x3b\x9e\x68\xd7\xc5\xda\x42\x9e\x4b\xdf\xc2\xea\x7e\x08\x27\x14\xf9\x82\xb6\xd6\x8c\x10\x52\xeb\x68\xfe\x11\x8a\xc5\x7f\x2e\x92\xb8\x00\xdb\xd7\x02\x01\x98\x56\x34\xd9\xd7\xd7\x86\x64\xe1\xff\xdd\x13\xe0\x69\x80\xeb\xc7\x8d\x3e\x56\xab\x8e\xa7\x48\x49\x14\x44\x46\xf9\x7b\x5e\xe6\xba\xfc\x69\xf9\xbc\x03\xf4\x3f\x25\x51\x18\xa3\x2c\x55\xfd\x33\x6b\xd4\x9b\xd5\xbd\x1b\x9f\x3e\x72\xca\x24\x96\x76\x77\x84\xaa\x39\x8f\xcf\xe0\x1a\x34\xd0\xbc\xdd\x15\x7b\xff\xd7\x98\x44\x48\x98\xf7\x59\xa6\x55\x77\x98\x48\x5e\x8d\x6f\x51\x2c\xa8\x54\xc3\x7c\xec\xf5\xad\xfb\x12\xa1\x22\x6b\x5e\x84\xdc\xdf\x47\xf8\xd9\x35\xd5\xc6\xf5\xc4\x0e\xf2\x31\x99\x7f\xc2\x58\x45\x1c\x78\x97\xf9\xa9\xcd\x9b\x7f\x64\x53\x13\xcf\xcf\xa3\x61\xe2\x35\xe7\x3b\xa1\xa4\x7b\x30\xcd\x5d\xe1\x18\xbd\xed\x76\xec\xaf\x55\xd2\x18\xd3\x8f\x6d\x51\xfe\xd4\x50\x2c\x8c\xe9\x9a\x7f\x94\xa4\x51\x82\x20\x1c\x38\x64\xcd\xda\x57\x55\x29\x49\x75\x6a\x79\xfd\x39\xc8\xca\xa3\xfc\x16\x85\x9e\xf6\x8e\xfe\x1d\x46\x7f\x7e\x2a\x60\x42\x89\x22\xc4\xd2\x6d\x06\x6e\xd1\x2b\x39\x01\x2f\x51\xa2\x89\xc6\x4e\x47\x1b\x9b\xdf\xca\x7a\x95\x15\x7a\xe4\x99\x46\x89\xe6\x11\x82\xda\x9f\x1e\xd7\xfb\x3f\xd6\x8b\xcd\xfe\xcb\x7a\xfd\x7c\xf7\x78\xe3\x8f\x43\x64\x17\x51\x59\xd7\x70\x48\xf3\xf3\x0e\xea\xee\x67\x42\x1c\x63\xe0\xb7\xbe\xb9\xd9\xee\x77\x4f\xfb\xdb\xc5\x6e\x75\xbb\x0f\xb7\xb7\x9b\xbb\x87\x6e\x7d\x05\x13\x22\xd0\xd4\x00\xec\xab\xa1\x17\x98\x3b\x6e\xb8\x46\xb8\xed\x42\xbf\xa3\x3f\xb2\x3c\x1f\x3b\x4d\x66\x4a\x0c\x10\x63\x2c\x6f\x10\x95\x52\xef\xcb\x9f\x03\x4c\x3e\xa5\x01\x37\x58\x3d\xfd\xd7\x09\x01\xdc\x6f\xdd\xdf\x65\x2a\xc9\x50\xa1\xbb\x5f\x64\xba\x11\x0a\x6f\xcd\x3e\xeb\x74\x09\xbd\x1b\xe6\xec\x1b\x48\x03\x2d\xa5\x25\xc8\x3e\x15\x17\x0c\x72\x4a\xc3\x30\xa2\x8e\x38\xb4\xac\xe4\xa0\x01\x30\x0c\x03\x68\x48\x6c\x4b\xc1\x54\xe5\xe1\x01\x0e\xa5\xdb\x98\x85\x8f\x97\xda\x05\x1b\xeb\x4c\x37\x5e\x5b\xdb\x5f\x2f\x89\xc2\xd4\xe2\x35\x4f\x45\x73\x5e\x0c\xaa\x6d\x94\x92\x94\x93\xc0\xa3\x62\xd0\x9d\x63\xd5\x35\xa8\xba\xc9\x40\xdb\x6f\x6f\xdf\xe1\xf2\xd4\xd0\xab\xb2\xf0\x91\x03\xa5\x3c\xc5\x90\xf3\x26\x2f\x53\x53\x16\xe3\xaf\xa5\x89\xf4\x7a\xad\x8f\x80\xc1\xac\xed\x5a\x4e\x4e\x6d\x34\xaa\x6e\xb5\xef\x0c\xf3\xb5\xa6\xc9\x18\x46\x42\xc4\x79\x2c\xaf\x3f\x72\x27\x14\xbf\x4f\x3e\xc1\x09\x06\x9b\x57\x8e\x46\xec\xaf\x89\x09\x9b\x93\xf5\xc5\xfe\xbb\x76\x43\x9f\xab\x2f\x51\xca\x64\x84\x1c\x9e\x9f\x6f\xb2\xf9\x56\x9e\x72\xed\xf9\x5c\x57\x17\x78\x7c\xff\x89\x94\x68\x4b\x8f\x58\x9e\xaa\x62\x86\xb2\x48\x29\xd3\x1c\x50\x34\x45\x67\x56\x96\x73\xc6\xb7\x72\x18\x8b\x50\x1e\x07\x58\x42\xda\x2c\x76\x6b\xe2\x7f\x47\x4c\x05\xf6\x0c\x37\xa0\xca\x77\xa8\xce\xff\x3a\x95\xd5\xe9\x70\x89\x48\xf5\xc3\x59\x84\xfc\x91\x6d\xd1\xce\xf5\xae\x12\x42\xe3\x44\x61\xa2\xbe\x05\x55\x41\xf3\x58\x36\xe0\x89\x8a\x93\x6d\x7a\x10\xc8\xb7\xab\x17\x96\xa8\xb2\xa9\x3e\xbf\x05\x53\x07\x17\xeb\xcf\x65\x9e\x4d\x05\x15\xc8\xd2\x48\x65\x55\x65\x50\x0d\x94\x46\x28\x15\xcc\x68\xfe\xa1\xd1\xcd\x4b\xa1\xe4\xf1\x08\xfa\x72\xeb\xf7\x3f\x56\x28\x82\xb0\xcb\x37\x59\x2f\x1a\x17\xb9\xcc\x87\x1d\x54\x68\x8d\x5d\x71\xa9\x0e\xdd\xb7\x1b\x99\x76\x82\x09\x03\x26\xcf\xf8\xfa\x93\xc8\x18\xe6\x45\x52\x65\xb1\x2b\x5d\x7d\x6d\xd3\xbb\x26\xb7\xf3\xdf\x9a\x39\xbe\xa4\xd9\x5f\x3b\x99\xfb\x0d\x80\x4a\x1d\x21\xf8\x63\x79\xfb\xb0\xbc\x7f\xf1\x7f\x4d\x23\x8b\xb1\xf5\x49\xec\xfd\xfa\xeb\xfa\x7e\xdf\x3d\xf1\x54\x83\x71\x2f\xaa\x55\xa0\xb9\x10\x66\xa5\x34\x35\xc4\xeb\x53\xf7\xf5\xfa\xa9\x16\x02\xa5\x4a\x75\x3f\x71\x63\x31\xdf\xd5\x1c\x19\x9f\x52\x2d\x02\xee\xbc\xa4\x1a\x99\x15\xf5\xa5\x36\x03\xa5\x5a\xc9\x98\x0f\x7c\x92\x30\x23\xc5\xbb\xcc\x7e\xff\x98\xf5\x49\x29\x84\x16\xfb\x64\x29\x53\xf5\xba\x17\xb9\xa6\x14\x4c\x82\x4a\x79\xba\x92\x59\x31\x60\xf0\xb4\x47\x20\x74\x36\xf7\xdb\x1f\x59\xf1\x64\x5c\xe9\x6e\x12\xbb\x32\x12\x30\x6c\x14\x36\x53\x99\xee\x27\x33\xf5\xea\xf2\x9f\x50\x0c\xa3\x24\x47\xc3\x1c\x24\x26\xc3\x06\x91\xbb\x0e\xc6\x82\x18\x89\x0a\x79\x56\x37\x43\x1d\xe7\x8b\x90\x6c\x4e\x1b\x85\x32\xce\x8c\x6d\x13\x36\x27\xf5\xe3\xa9\xd8\x36\xa7\x63\xa6\x87\x8b\x27\xe3\x92\x4a\xa7\x12\xb0\xfe\xa5\xfa\x05\x9b\x71\x2d\xa9\xb5\x99\x7c\x7d\x6e\xb3\x5e\x5c\x53\x51\x72\x64\xb8\x5b\xb0\x88\x5a\xb5\xd1\xa2\x6c\x32\x73\x7e\xfe\x14\x73\xd3\x7d\x44\x21\x89\xcd\x0b\x31\xad\x77\xb7\xf3\x11\x90\x1f\x0f\xd6\xfe\xa7\x71\xba\xdd\xdf\x26\xd2\xb9\x94\xc5\x9c\xc6\x16\x52\x73\x1e\x92\xb2\x27\xe7\x89\x13\x2b\x21\x6d\xdd\x2e\xc4\xfa\xfb\xb6\xcc\xf5\x7e\xe0\x1b\xe4\x7f\x7a\x2c\x09\xd7\xbd\x1c\xf4\xae\xe7\xfe\x52\x26\xa4\xc2\xe6\x1c\xa8\xd2\x82\x4f\x47\x5d\x25\xca\x12\x6a\x82\xa1\x43\x43\x3d\xc4\xc3\xb9\x31\x92\x28\xec\x8c\x38\x6e\xf4\x44\xa2\x97\x32\xc9\x23\x2b\x43\x62\x01\xbf\xb8\x2e\x3c\x4b\xcf\x9a\xa4\x2c\x65\x22\x72\xfb\xf8\xd3\x11\x0a\x2b\xf6\x3d\x79\xb3\x46\x7b\x3a\x4b\x13\x89\x1d\x8c\x43\xe9\xd1\xbf\xa3\xc2\x16\x4b\x53\xeb\x04\x85\xa5\x4b\x85\x72\xfc\x75\x73\xd2\x50\x4c\x67\xaf\x82\xc8\x3e\x6e\x74\xe7\x3a\x96\xf5\x47\x1c\x90\x69\x55\x9b\x69\x61\xc5\x9c\x4f\x85\xb2\xc4\xe0\x6b\xe8\x22\x1d\x06\x34\x08\xdd\x69\x1f\xe0\x55\xa6\xe5\xaf\x8f\xba\x03\xee\x03\x86\x08\x6a\x55\xa2\x8a\xac\x7e\x1b\x58\x6b\x8e\xb2\x24\x66\x84\x44\xea\xed\x8f\xb3\xc2\x12\xbd\xfb\x3e\x1e\xf0\x08\xa1\x3f\xdb\x63\x59\xe6\xa3\x37\x8e\x93\x40\x92\x0e\xbe\x3b\x90\xd7\xba\xc2\x72\x9c\x45\x3c\x65\x75\x3f\x1c\x58\xea\x0a\xb4\x0b\x63\xb2\x3c\xfb\xc8\x78\x9d\x72\x1a\xc4\x26\xed\x3a\x19\x08\x35\xba\xa0\x61\x50\x4e\xb9\xc4\x6e\xd0\x73\xf6\x0b\x72\x27\x3c\x72\xea\xc9\x31\xc2\x0f\x93\x56\x69\xe0\xaf\x13\x9c\xba\x7c\xc6\x1f\x33\x11\xfe\x84\x36\xa4\xbe\x81\xc6\x87\xf1\x57\xa9\x1f\xc0\xb8\x46\x79\x89\xdc\x55\xf7\xba\x55\xeb\x52\x8c\x9e\x72\x96\x58\x86\xe5\x2b\x34\xe8\x56\x8b\x25\xde\xd1\xb3\xe5\x0c\x52\x1c\x52\x95\x6a\x55\x56\x30\x7e\x25\x38\xa7\x01\x56\xcf\x2c\x5b\xe4\xc9\xcc\xbf\x9e\x3c\xa2\xa1\xd4\xbd\x45\x4a\xef\xb9\xf5\xdb\x64\x9c\x14\xd2\xbf\x61\xd9\xc8\x6a\x86\x72\x11\x58\xb4\x71\xe7\x14\xf6\x11\xb8\x68\xf8\x76\x70\x41\x84\x60\x7d\x1f\xdc\x3a\xe3\xce\x05\x17\x6e\x7c\xc2\x05\x6e\x7f\xdf\x9f\x17\xc8\x48\xf8\xc4\xca\xda\x7f\x22\x52\xb8\x43\xbb\x15\x45\x59\xcb\x18\x7f\x30\xb1\x16\x55\xcf\x55\xa9\xaf\x86\x0b\x01\x4f\x8c\x25\x40\x5d\x4f\xbb\xd7\x94\xcb\x36\xdc\x76\x81\x01\x98\xc6\x93\x43\xfd\x51\x11\x60\x69\x19\x1b\x1e\xef\x65\x03\xdb\xa3\x3c\x1c\xb2\xe2\x75\xf1\xda\xee\xaf\xdd\x57\x4b\x43\x10\xee\xb8\x91\x0d\x84\xbe\xb6\xc5\x53\x42\x89\x33\xfc\xe8\xb8\x0c\x70\x91\x02\x76\x83\x23\xc4\x7e\x65\xaa\xc4\x62\x77\x78\x05\x52\xe7\x59\x17\xbb\xf3\x94\x0a\x2f\x16\xb9\xc2\x40\xa7\x70\x0c\xb4\x61\xf6\xce\x53\x11\x22\xc4\x42\x65\x15\xd6\x46\xb3\xb2\x58\x4c\xd6\x4d\x9e\x4a\x10\xac\xc7\x93\x20\xda\x11\xd9\x20\xd3\x4d\x71\x4e\x86\xe7\x7f\xfb\xaf\xff\xce\x34\x46\x64\x72\xfd\x26\x09\x8f\xae\x4a\x55\x4f\xe6\xbe\x32\x96\x5c\xd5\x26\xf4\xb0\xeb\x49\x09\xfe\x87\x69\x0a\x58\x0d\xb5\x85\x42\x3d\x07\xcf\xa2\x5c\x33\x8e\x4d\xce\xcd\xe2\xea\xee\xe5\xa1\xfb\xa8\x10\x9e\x0f\xe1\x05\xbb\x7e\x1d\x33\x9b\x9b\x0e\x1a\x2d\x5c\x2b\x85\x05\x5a\x0d\xef\x06\xa0\x29\x35\xbc\xfb\x43\x90\x28\x2c\xab\xe8\x0c\xa5\xbe\xad\xdd\xda\x6f\x83\xb9\x6c\xc2\x30\xed\x6d\xcf\x16\x85\xee\x58\x1e\xe3\x5e\xd3\xbf\x49\x5f\x38\x27\x7f\xfe\x3e\x59\xea\xff\xa6\xa1\xf7\x6f\xfa\xa7\xff\xba\x54\x58\xc4\xf8\xa9\xd0\x03\xb4\x06\x8d\x02\x99\xa2\x0c\xc2\x9c\xf4\xfd\xff\xd1\x75\xc5\x9d\x39\x0c\x15\x13\x8e\x5b\x4b\x1f\xb2\xfc\x1b\x64\xbb\xf2\xb9\xec\x1a\x2e\x51\x28\x68\xdc\xde\xfc\x87\x32\x07\x75\xca\x3f\x63\xea\xd2\x88\xd0\x18\xeb\x9b\x1e\x9c\x33\x4c\xf5\x23\x12\x0b\xff\x52\x5e\x90\xfb\x68\x44\x74\xa2\xc4\xe4\xb5\x9a\x29\x74\x45\x54\x0b\xac\x77\xec\x1e\xd6\xdf\xc7\x6f\x7d\xc4\x22\x95\xf4\x93\xe9\x21\xab\xaa\x32\xfb\xa0\x35\x17\x71\x96\xe2\x8b\x79\xaa\xa1\x53\x44\x1e\xb5\x11\x66\xcb\x36\x11\x17\x31\xf2\x6b\x52\x98\xbc\x7e\x11\x4f\x25\x16\x33\x1f\xee\x1e\x5d\x8d\xda\xe2\x50\xfc\xc5\x71\x08\x8d\x1e\xf4\x7e\x56\xa7\xa6\x34\x66\x7a\x12\xb0\x99\x2b\x06\x61\x6e\x21\xb0\x81\x52\x1b\x8d\xf9\x53\x45\x51\x20\x2d\x2e\xb8\x81\xea\x80\xed\x7d\x0b\x20\xef\x06\xc4\x09\x83\x51\xcd\x78\xae\x8b\x12\x45\xc2\x76\x51\xbe\xaf\x56\x3d\xc6\x7f\x7c\x9b\x22\x15\x09\x3d\x56\x6c\xf4\x9a\x30\xa3\x58\x22\x8a\x80\x62\x9d\xa7\x72\x12\x87\x23\x1e\x2d\x8d\xe2\x90\x60\xed\xe0\x1d\xb7\x9c\x49\xa5\xfb\xf7\xd3\x40\x73\x96\x46\x31\x03\x9b\x0e\xb6\x4f\x7f\xaf\x67\x90\x38\x34\x8a\xb5\x41\x1a\xd1\xf6\x5c\x68\x74\xdf\x9f\x1e\x07\x1a\x90\x41\xaf\xd4\xbb\x02\x0c\x37\xce\x59\x36\xee\xec\xcb\x7a\x51\x75\xf4\xdf\x62\x42\xab\xe8\x23\x0f\xb0\x85\xa6\xc9\x8a\xd7\x79\xe6\x3b\x8d\x44\x28\xb0\x7e\xb0\xee\x1c\xe7\x69\x24\x44\x12\x76\x80\xbd\xb0\xfb\xab\x14\x48\x39\x73\x1e\x4b\xa3\xf5\x34\x12\x29\x45\xcd\xc6\xab\x76\x9f\x82\xcc\xd2\xd1\x3e\x7a\xd3\xe7\xde\x50\x19\x84\x78\x63\x10\xfc\xd3\xe6\x16\xfe\xef\x61\xea\xd8\x4c\xff\x39\xd5\x8d\xe5\x38\xbb\xac\xce\x2f\xca\x1f\xe0\x32\xa6\xeb\xcf\xdc\x16\x1f\xa5\x21\x95\xe0\x93\x5d\x93\xe5\xf9\x75\xf9\x79\x57\x36\x52\x84\xa5\xd6\xa8\xa1\xc6\x62\xfc\x58\x72\xf8\xf3\xb7\x54\x51\x40\x3e\x78\x59\x38\xb8\xd4\x27\x6a\x9a\x34\x52\x89\xa0\xd2\x2b\x16\xe2\x46\xe2\x99\x69\x93\x97\x41\x53\xe2\x07\x3e\xcb\x13\x6e\x19\x83\xcd\x22\xd2\xb1\xe2\x96\x48\xbc\xb0\xda\xf6\x1d\x9a\xb9\x1b\x60\x1b\xf8\x36\x86\x5b\x28\x35\x7c\x07\xe6\xba\x7b\x11\x48\xab\x92\x52\xa2\x04\x5f\xbd\x72\x6f\x61\xd7\xf3\x8f\x40\x05\xbc\x6b\xd3\xe1\xbe\x3f\x51\x3b\xa0\x11\x80\xc2\xa8\xaf\x2b\x92\x62\x83\x78\x57\x2e\x8a\xb2\x5d\x9d\x51\x88\x60\xb6\xb7\x18\x19\x69\x74\x67\xf5\x84\xfa\x17\xfe\x00\x70\xcc\x73\xfc\x32\xff\x59\xc3\x20\x0e\x78\x90\x20\x00\x0a\xe4\xe1\xa9\x80\xe7\x0a\x4c\xe6\x21\x09\x71\x20\xa9\xd0\x1d\xd2\xe2\x59\xaa\x1f\xf2\xb5\x4b\x7c\x62\x12\x84\xcc\x6e\x7b\x1a\xe9\x92\xfd\xdf\xb5\xbb\x91\x98\x23\x3f\x94\x45\xf3\x96\x9f\x1f\x3d\xd8\x8f\xc6\x24\x4c\x90\x39\x61\xb1\x82\x6c\x88\x15\xa4\x31\x51\x04\x67\xd6\xf1\x34\x68\x2e\xcc\x5f\x3b\x75\x3e\x23\x59\xed\x2a\x4b\x30\xc1\xfa\xc4\x34\x8e\x0d\x0c\x32\xda\xaf\x96\x49\x2f\x6b\xb0\xac\xc0\x36\x76\xbc\x2e\xab\xe7\x37\x59\xc3\x58\xc1\x9f\xc6\x54\x5a\xb0\x9e\x17\x16\x7c\x94\x95\x2a\xeb\xe5\xd9\x56\x3d\xd4\x90\x9f\x40\x63\x6a\x58\xe8\xee\x14\xee\xaa\x70\x3a\x8c\x8c\x80\x69\xcc\xc2\x30\xee\xb1\x60\x5f\x57\xdf\xbf\xca\x53\x7e\xa1\xaf\xee\x07\x53\x93\x5a\x62\x46\x59\x1f\x11\x46\x52\xef\xdb\x27\xd4\x9d\x2c\x0d\xb0\x6c\x9c\x9e\xce\xbb\xab\xb5\x93\x95\xce\x9a\xb7\xf2\xd4\x4c\x2b\x12\x17\xef\x6e\xcc\xc3\xd8\xf2\x17\xcb\x9f\x50\xbd\xcc\x2b\x70\xd3\x98\x13\xed\xbb\x8d\x5f\xfe\x58\x3d\xcb\x73\x5e\x4a\x3d\x4c\x58\x62\xae\xac\xb2\xd9\x73\x59\x68\xa8\x6e\x3c\xce\xd7\x5f\x23\x87\x00\xef\x7d\x1b\xc7\x5b\x09\xe1\xa7\x14\xe5\xd4\xba\xe3\x1a\x97\x81\xfb\xf2\xf5\xbe\xbc\xb4\xda\x99\x5c\x4e\x14\xc5\x18\x27\x7a\x91\xaa\x11\xa1\x98\xc6\x91\x51\x38\x53\x51\xc4\x27\x8a\x27\x8f\x32\x0e\x14\xb6\xdf\x6c\x4a\xea\x5f\xcf\x38\xa6\x04\xa9\xd7\x57\xeb\xaf\xeb\xfb\xa7\xe7\xf5\x66\x3b\x74\xd5\xa1\x71\x2c\x03\x2c\xb1\xad\xf2\xf2\xa4\x3d\x8b\x66\xa6\xbe\x17\xcb\x38\x4a\x86\xf0\xf8\x45\x8d\x70\xcb\x6a\x3a\x4c\x5a\x91\xcf\x0a\x65\x5a\x3c\x1e\x78\xa4\x07\x4e\x63\x45\xb4\xe8\x5c\x53\x17\xef\x32\xcb\x07\xbc\x9d\xd9\x68\x29\x56\x02\x64\xe8\x98\x45\x7e\x71\xc4\xfe\x9a\xd3\x0c\x9a\xad\xdc\xc7\x9a\xdb\x92\x92\x5d\xe9\x6c\x30\xe7\x0f\x09\x25\x7a\x70\xb9\x25\x50\xe3\x45\x4e\x43\x83\xf1\x75\x00\xb1\x36\x6f\xfb\x43\x56\xdc\x96\xa7\x1a\xd6\xfa\x15\x56\xb9\xac\x6b\x2f\x22\x4b\x63\x88\xb5\x07\xeb\x2f\xcf\x0e\xa3\x39\xc1\xc0\xd2\xd8\x84\x02\xc3\x95\xfd\xcf\x36\xde\xfd\x5a\x9e\xd4\xdb\x94\x7f\x47\x45\x60\x52\x87\xac\x39\x94\xef\x60\xdd\x42\x10\x2e\x33\xbf\x17\x8d\x3f\x1c\x72\x89\x3d\x8e\xc2\xa8\x7d\x8d\x93\xf3\xed\xaf\xdf\xfc\xb1\x44\xe0\xcc\x57\x72\x5a\xfd\x12\x84\x08\x6c\x98\xb7\x73\xfa\xe5\x90\xcb\x0e\x8c\x28\x48\x24\xb1\xe0\x6f\xa3\x5b\x57\x75\xb1\x20\xbc\xe1\x0e\x2f\x48\x12\x84\x76\xab\xad\xde\xa1\xda\x02\xe8\x5e\x16\x97\x0a\xca\x0d\xed\x18\x78\x77\x66\x9d\x67\xaf\xb8\x8f\x8d\xee\xb3\xa0\x3a\x0e\xac\x33\xc0\xc8\x1f\xef\xf7\xe9\x28\x01\x6e\xed\x5b\x4b\xf5\xb6\xcc\xba\x3c\xdc\x43\x39\xdd\x40\xc6\x95\x91\x03\x33\x93\x0f\xb0\x31\x82\x89\x28\xc5\xd2\x22\xb8\x0a\xf6\xf8\x70\x1b\x42\x53\x2f\xa2\xbf\xe7\x23\x45\x2b\x2a\x22\x45\x70\x45\x5b\xff\xca\xf2\x8e\x4b\x4d\x45\x64\x02\xc7\x72\x19\xaa\xc1\x0f\xea\x55\xd3\xa7\x1e\x33\xdb\x01\xa8\x00\x4b\x71\x7b\x59\x35\xfb\x66\xb0\xec\x08\x91\x58\xb7\x42\x0c\xdb\xee\xb3\xf7\x6e\xbf\x12\x22\x31\xcc\x75\x9f\x6f\x2d\x82\x6c\x98\xc5\x0b\x61\x52\xac\x3c\x2d\xf2\x19\x63\x9b\xf1\xad\x4d\x44\x8c\x08\xc3\x5d\x06\xd5\xde\x4d\xf0\xfd\xe6\xb2\xfb\x2a\x24\x89\x62\xab\x1e\x66\x1a\xc1\x27\x3f\x45\x12\x85\xf8\xc8\x02\x7e\x35\x2e\x12\x1a\x64\xc6\x22\x25\xce\x22\x16\x9a\x2d\x82\xb7\x2d\x9f\x6e\x5d\xa8\x09\x35\x8f\x8a\x94\x86\xb8\x67\x1e\x9c\x77\x40\x07\x76\xf2\xe7\x52\x24\xa1\x61\xe7\x24\xbe\xfb\xe9\x63\x05\xa1\x85\x5d\x84\xed\x26\xf7\x2d\xfb\x91\x3d\x0f\xb6\x78\xa1\xb5\x4d\x9b\x10\xfe\x80\xd6\x64\x88\x7e\x00\x6f\xce\xba\xaa\x2e\xf5\x41\x27\xd3\x10\x22\x8d\x1a\x7b\x38\xa5\x37\x23\xf2\x96\x1b\x61\xa4\xd5\x33\x69\x93\x3d\x14\x6c\xf6\x7f\xd7\x3a\xb4\x4a\x63\x3e\xdd\x4d\x02\x69\x65\xcf\x1e\xce\xb8\xcb\xee\x20\xcf\xa1\xb2\x4a\xe0\x57\xcb\x6e\x90\xb2\x00\x98\x57\xcf\x66\xdc\x40\xdd\x6e\xb5\xee\x70\x18\x12\xd4\xa3\xaf\xa5\x81\xed\x29\x6d\xaa\xd5\xf3\x6a\x3d\x9f\x17\x24\x21\xe5\xd8\xc2\x68\xaf\xfa\xab\xc5\x34\xfe\x36\x19\x11\x25\xa1\x83\x27\x66\x85\x29\x7f\x66\x56\x79\x72\xf6\x0d\x4a\x42\x91\x20\x2e\x19\x39\x72\x9d\xc2\x6b\xf3\xf6\x31\xc0\x2f\x21\x3c\xb2\xca\xe0\xf2\xc7\x05\x2e\xb6\x1f\x94\x30\xed\x7a\x5a\x6e\xeb\xd1\x77\x57\x1f\x22\x61\x86\x53\x27\x21\x0a\xf0\x92\xdc\x8a\x85\xd4\x5d\x9f\xca\x26\x34\x50\xe0\xea\x43\xd9\xb8\x4e\x9b\xd0\xd0\x82\x2d\x9c\x84\xe5\x38\x11\x4a\x28\x49\x31\x9d\x6e\x43\xd0\xab\xe1\x4c\x4c\xa8\xb6\x1c\xdc\xd7\xf6\x0d\x2c\x6c\xe9\xef\xa5\x86\xf9\x7e\x7e\x42\x21\xb0\x3b\xb4\x3c\x63\x27\xc3\x6f\xdd\x09\x53\xa9\xf7\x4d\xbf\x2f\x2d\x74\xcd\xa9\xe4\xff\x83\x34\x2b\x89\x48\x4a\xac\x5c\xa8\x13\xc2\x9a\x6c\x40\x49\x44\x53\xe3\xa4\x6b\xef\xf4\x08\x83\x39\x35\xc2\x19\x67\x49\xdd\x13\x89\x58\x2c\x62\x0f\xe4\x5c\x68\xdd\xa9\xe9\x3e\x55\xd7\x59\x3e\x80\x3a\x75\x9f\x68\xf7\xe3\xb0\xf3\x0a\x6b\xae\xcb\x6a\x03\xc7\xb2\x42\x18\xad\xac\x9a\x4c\x65\x47\x59\x38\xd1\x19\xab\x58\x3e\xba\x62\x11\x68\x04\x45\x6b\x04\xca\x59\x2b\x03\x7f\xb3\x04\x89\x14\xef\x28\x2f\x08\xc3\xe8\x0a\xa2\x7e\x08\x15\xf8\xa2\x5f\x65\xaf\x59\x23\xf3\x75\xd1\xbc\x9d\xea\x4c\xd6\x5d\x59\x36\x11\x2c\x44\xad\x3d\x0d\xb9\x2d\x7e\x8d\x5e\xe2\x44\x24\x01\xde\x31\x9d\xd5\x7f\x21\x59\xf2\x3c\x24\x63\xf9\x41\x32\xf5\x2f\xcb\x73\x1b\xaf\xf7\x2b\x65\x92\x44\xcc\x4a\xf4\xbf\xc1\xe6\xd4\xff\x55\x38\xd9\x9b\xc3\x71\x18\x5b\x26\x32\xa5\xd8\x45\x2a\x00\xb4\x53\x1d\xad\x77\xe5\xca\x2a\x47\xfa\x41\x29\x8b\x95\x5d\x3f\xda\x89\xf1\x6d\x5a\xab\x4a\x52\x6e\x75\x3e\xb7\x45\xfb\x90\x3e\x5f\xc6\x92\x34\x22\x38\x58\x97\xcf\x95\x0d\x37\xca\xea\xfc\xad\xca\xa6\xad\xfd\x3e\xf3\xee\x9e\x6c\x1a\x0b\x04\xb9\x22\x8a\x35\xbf\xec\x39\x8d\xa7\x5e\x2a\x7c\xc9\xaf\x9d\x03\xed\x72\x0d\xfa\xe9\xd4\xa8\xb2\xdb\x19\x92\x54\x2b\x0c\x8f\xb0\x27\xf1\x3c\xc0\xf1\x27\x29\x68\xfc\x2a\xf4\x33\xed\xf5\x26\x47\x5f\xa0\x52\x1e\xeb\xce\xe4\xb8\xb9\x10\x96\xa6\x89\xa6\x14\x25\x0a\xb7\xd0\x7c\x7b\x9b\x24\xac\x89\x4e\xac\x0e\x88\x9c\xa9\x12\xf5\xa7\x00\x66\x31\x24\xed\x6c\x3e\x3f\x9f\x0a\xf5\x36\x70\x2b\xa3\x09\xc4\x06\x7f\x64\x3b\x47\x56\x6f\xe5\xd0\x93\x64\x7c\x1e\x43\xac\xc7\xdb\x16\x9c\xcf\xe6\x20\xa5\x4f\x4c\x1c\x79\x92\xe2\x7d\x66\x17\x67\x2b\xbd\xe2\x8f\x0b\xe1\x5d\xda\x1e\xe1\xe7\xba\x6e\xb2\x43\xfb\x63\x47\xb5\x61\x3f\x34\x21\x58\x78\xd1\xf0\xbe\xc7\x8a\x86\xbb\x52\x19\xc4\x41\xaa\xfa\x9f\xbb\xe9\x15\x33\xfb\x11\x4e\x8e\xeb\x94\x86\xd1\x6f\x16\xd2\x3d\xc0\xa6\xc8\x30\xb6\x04\xf3\x1a\x61\x9b\xc7\x06\xf6\x34\x1c\x6d\xdf\x32\x4c\xac\x14\xf9\x45\x16\x3b\x3f\x45\x64\x08\x36\x81\x93\x79\xde\xf5\xa1\x3b\x6c\x96\x0c\x0d\x45\xff\x26\x94\x0e\x72\x70\xb4\x61\xa0\x23\x09\x01\x5c\x82\x0d\x34\xea\xed\x59\x66\x1a\x1b\xde\xf5\x75\x59\x3d\x40\xd5\xae\x11\x8d\x37\xef\x1d\x3d\x79\x49\x22\x89\xe2\x14\x56\x43\xeb\x2a\x93\x87\xb2\x18\xd2\x6e\x24\x49\x52\xee\x9e\xc7\xde\x09\xf3\xec\x65\x95\x66\x4d\xbd\xaf\xfb\x02\xa9\x24\x3a\xc4\xe9\xfb\x00\xbf\x32\x55\xbe\xd7\xdb\x9f\xa0\xbb\x57\x5b\x52\x9d\x80\x8d\xbe\x0b\x9b\xae\x39\x94\xc6\xae\xdc\xc9\x1f\xb0\xa8\xdb\x90\xd9\x8f\x65\x01\x60\x57\x72\xaf\xca\xc3\xf1\xd4\xc0\x46\xa2\xc2\xd5\xff\xa9\xd6\x2e\x99\xb2\xb3\x7e\xf5\xf4\xf0\xf0\xf2\x78\xb7\xfb\x63\x4c\x91\x90\x9c\x53\xe1\x34\xf0\x36\xb2\x82\x4f\xb0\xdc\x92\xc7\x21\xb6\xa4\x97\x32\xab\xca\x62\xd4\x53\x91\xdc\x69\xda\xbf\x42\xb3\x38\xa1\xfe\xb6\x07\x92\xfb\x11\x51\x92\x60\x33\x31\xab\x6f\xa0\x80\xda\xa2\xc1\xfd\xc1\x98\xd8\x25\x14\x97\x87\x13\x42\x4e\xae\x3b\x8d\xa8\x99\x85\x59\xc6\xdc\x36\xfd\xa5\xd6\x5f\xb3\x02\xce\x03\x03\xe2\xd3\xc0\xbb\xc1\x36\xd5\x5d\x92\xd8\xcd\xdd\x38\x15\x56\x9c\xac\x29\x2b\xc0\x16\x59\xfd\xdb\x64\xab\x93\xb1\x36\x18\x4f\xfd\xec\xde\x19\x11\x50\x6a\xe5\x84\xb2\xff\xc2\xb7\x6e\x8d\x97\x22\x48\x63\xe6\xf2\xc3\x66\xfb\xd7\x45\x61\xeb\x83\x07\x93\x84\xdc\xfa\x7a\xbd\x95\x3f\x6d\x19\xcd\x4a\xef\xa5\xb6\x21\x39\x0b\xcc\x96\x09\xd7\xda\x76\x64\x35\x1c\xb0\x3e\x87\x0b\x65\x37\x75\x92\xd8\x6e\xd0\xf5\xab\x1a\xee\x2c\x32\x89\x0d\xf6\xcc\x1e\xa0\x91\x9b\x53\x7e\x69\x16\xdc\xfd\x6e\xa9\x99\xa5\x07\x9f\x64\x25\x8b\x06\x40\x2f\x4f\x67\xa8\x3c\xe8\x76\x7c\x39\x69\xcc\x11\x77\x78\x9d\x67\xaf\x6f\xcd\x73\x2e\xa7\x2f\x57\x0a\xb6\xd9\xf5\x23\xcb\x73\x5f\x6c\x96\x8a\xc5\xde\x38\xfc\xa9\x68\xf7\x8e\x76\x11\xbd\xeb\x96\x51\xa9\x52\x65\x1f\x0f\x02\x8f\x97\x39\x48\xf5\xe6\x51\x96\xfd\x3a\x29\x35\x91\x88\x50\x70\x87\x36\xa0\xb2\x63\x06\x85\xf3\xea\xd2\x97\xac\x71\x2a\x35\x8b\x10\x1b\x74\x90\xbf\xc6\x75\x2c\xa9\x23\x45\x3a\x79\xa1\x76\x66\x22\xaf\x65\xf2\x6b\x80\xc4\x1e\x49\xef\x16\x35\xf7\x94\x9c\x0d\x9b\x1f\x66\x08\x02\x79\xaf\xaf\xb6\xa3\x87\x00\x86\xa4\x96\x40\x72\x5d\x95\xff\x05\x4f\x39\x9e\xdf\x23\xa4\x89\x38\x51\x7e\x81\xed\xd8\x95\xeb\x5f\xc7\xb2\x3e\x55\x93\x2b\x4b\xc3\x50\x30\x57\xea\x3e\x1d\xbf\x96\xd3\xbd\x2f\x0d\x59\x90\x88\x01\x07\xc0\xb1\x94\xda\xe4\xac\x5d\xf4\xd7\xb2\x2a\xba\x49\x94\x86\xa0\xb1\x19\xb0\x1f\xa2\xf6\xdd\x31\xc2\x14\x16\x7b\xb2\x42\xdf\x15\x26\x1f\xa6\x85\x29\x51\x54\xb0\xc1\xba\xb5\x2c\x87\x90\x23\x3f\x08\xec\x46\xfb\x26\x6b\x2f\x47\x3f\xfe\x06\xca\x08\x56\x14\xd7\xbb\x5b\x46\x82\xb2\x60\x89\x3f\x3f\x15\x61\x60\xfd\x2e\x8f\x17\x82\x6c\x7e\x88\x56\xda\xca\x79\xfd\xba\xb2\x86\xa0\xbd\x96\xa4\x1b\xc2\x02\x89\xd5\x6b\x63\xc3\x90\xdd\xc7\xf2\x5e\x83\xaa\x60\xca\x98\x95\xb9\xf1\x58\xb7\xc5\x6f\xb3\x54\x92\xf1\x4f\x61\x71\x82\x8b\xa2\x63\x36\xe2\x76\x35\xa8\xf8\x8c\xe1\x38\x29\xd3\x06\x41\x07\x0e\x8c\x32\x44\x30\xcc\xce\x90\x94\x87\x1a\x11\x37\xc8\xfc\x47\x4e\xea\x70\xff\x4d\x79\x68\xb0\x6d\xb8\x77\x2c\x60\xb4\xc7\xbe\x8c\xf8\x67\x57\xa7\x94\x73\x90\xc3\xdf\x3b\x94\x78\xfc\xa0\xd5\xec\x3f\x29\x53\x04\x2b\xbb\x66\x9c\x77\x7a\x19\xa0\x12\x27\xef\xe7\xa0\xe0\x9c\x46\x11\x8f\xec\xd7\xe6\xf2\x3c\x99\x18\x91\x48\x51\x4b\xe6\x58\x41\xa6\xca\x29\x34\x3b\x8d\xa4\xc5\xfd\xdd\x58\x3d\x4a\xaf\x5f\x37\x02\x20\xcc\xb5\x89\xd2\x38\xa1\xd2\xca\x6d\x67\xff\x1d\x86\x40\xa9\x90\x02\x6d\xcc\x1e\xa0\x5d\xa8\xa0\x93\xe0\x1c\xb8\x12\xd0\x34\x09\xa9\xf1\x79\xb7\x4f\x3f\x1e\x64\x71\xfe\xac\xaf\xeb\x17\xdb\x34\x89\x2d\x56\x39\xed\x29\x39\x77\x75\x7d\xea\x5f\xc5\x44\x4a\xec\x2e\xcb\xb1\xfb\xa1\x3b\x2a\xa5\xb5\x45\xfa\x92\x15\xaf\x5f\xca\xe2\x75\x10\xb5\xa4\xa9\x96\xd6\x1d\xa2\x91\x85\xc6\x79\x8e\x93\xc0\x54\xa5\x0d\x29\x27\xeb\x7e\xaa\xc2\x14\x65\xfb\x95\x13\x50\x78\x2e\x4b\x9f\xdd\xa6\x4a\xd8\x63\x3f\xde\xd5\x40\x7c\x61\x72\x1b\x95\x48\xb1\x42\xb5\x7d\xbe\xbb\x5a\x6f\xf6\xcb\xa7\xa7\xae\x0f\x9d\x6a\x69\x23\x87\xaa\x53\xb1\x1a\x4a\xab\xd0\x14\x02\x99\xb8\x1d\xa1\x7d\x76\xfb\xb8\x3b\x10\xd9\xfd\x4e\xb6\x6b\xbc\xf3\xe5\x74\x87\x4c\xca\x31\x20\xf4\xfd\xa0\xf6\x86\x4f\xac\x4d\xc6\x57\xa8\xc2\x20\x4e\xa9\xaf\xd9\x7c\xcb\x2e\x3d\x74\xa6\xe3\xa5\x89\xa3\xce\x63\xc5\x12\xaa\x2f\x31\xfc\x8a\x30\x85\xc8\x9e\x01\x57\xed\x6f\xe9\xd4\x5e\xeb\x70\xb4\x02\x28\x12\x85\x1e\x5a\xdc\x46\x4f\xa5\x0b\x15\xf5\xa2\xf1\xf0\x73\x3d\x45\xe0\x28\x22\xa2\x84\x38\x38\x49\x7b\x93\x3c\x61\xc8\x1f\x06\x85\x5d\xb3\x1a\x0a\x9d\x5e\x22\x03\xdd\x28\x4a\x64\x1c\x76\x21\xae\x65\xf2\x38\x11\xdd\xac\x30\xe5\xe4\x2b\x59\x4c\x22\xa7\xa4\x8b\xf5\xf0\xed\xb0\x8a\xe3\xc7\x24\x8c\xc8\x5e\x46\x6c\xdb\x94\xc7\x41\x15\x50\x45\x92\x81\x45\x5f\xff\x28\xca\x9f\x39\xe8\x57\x58\x95\xc7\x0c\xd6\x28\xef\x54\x66\xd5\xa4\xf4\xa2\x22\x29\x31\xbd\x73\x12\x56\xb0\x36\xbe\x9d\xa7\x62\x16\x06\xd4\x25\xc4\xef\x5e\xca\x60\xb0\xac\x8f\x2f\x4c\x28\x86\x15\x9e\x7b\x78\x87\x6a\x50\x14\x54\x42\x0b\x49\x3a\x81\x41\x57\xb9\xbc\x2b\x66\x20\xe0\x4a\x68\xab\x40\x9f\xb5\xef\xea\xf2\xec\x24\x39\x3e\xd4\x63\x1a\xec\x23\x2a\x09\xac\x18\xbd\x92\xb9\x5a\x66\xda\xc9\x29\x39\xb7\x9b\xf1\x4f\x96\x61\x8a\xcc\x8b\x6f\xb7\x7f\x3c\xdf\xfa\x78\x5d\xa5\x41\x84\xac\x0d\x93\x9f\x8c\x39\xaf\xe4\x58\xce\x95\xaa\x54\xd8\x16\x80\x95\x95\x72\x37\x63\x5c\x16\x51\xa9\xb6\xdd\xfe\x57\x68\x6c\xf5\x75\x14\xcb\x2b\x45\x01\x45\x21\x33\x85\xcb\xa1\xd7\x8f\xf0\x47\x93\x10\x91\xe1\x0f\x50\xbf\x3d\x97\x59\xd1\x8c\x94\x6d\xa8\x52\x10\x61\xc5\xc7\xa5\x4a\x5e\x30\x6a\xf4\xc2\x2b\x1d\x48\xb4\x99\x95\xde\xde\x72\x39\x14\x92\x1f\xbf\x5f\x3a\x64\xd8\xb6\xf9\x2a\xab\xac\xfd\x4d\xab\xb2\xa8\x9b\xea\x84\x2c\xf4\xe1\x86\xa7\xb4\x92\x8a\x75\x75\x98\x06\xe5\xd1\xf0\xf7\xd5\x6f\x1f\x5b\xa8\x5c\x32\x14\x14\x50\x0b\x06\x7e\x39\x6e\x1b\xd9\x7c\xb8\x4a\x4c\x3f\x95\x24\xf8\x60\x8e\xb2\xaa\xc1\x82\xad\x87\x0f\xde\x04\x21\xb5\x44\xa0\x65\x2e\xd5\x8f\xa1\x18\xf1\xe4\xf7\x1a\x61\x92\xb8\xdb\x7a\xab\xb3\xdb\xc9\xb6\x3f\x4e\xee\xee\xe9\x20\xb0\xe5\x83\xfa\xa7\x3c\x8e\xee\xab\x0e\x42\x90\x8e\x6e\x7b\x94\x15\xb4\xc9\xaf\x4f\x2d\xba\x21\x22\x55\x56\xe7\x15\x31\x11\x1f\x17\x69\x75\xa0\xad\x5d\xc7\x16\xc6\x2b\x6a\xaf\x2f\xcb\xfa\xb1\x06\xb0\xf4\x61\xbd\x28\xb1\xdf\x72\x2b\xdf\xdf\x07\x97\x46\x44\x82\x82\x23\x59\xfd\x90\xe9\x1b\x04\x70\x8f\x6e\xa0\xa6\x21\x71\x9a\xbb\x87\xf2\xdd\x5a\xdb\x4e\x07\xc4\xc8\x2a\x7b\xf8\xfe\xc7\x5e\xf5\x3e\x15\x54\x53\xc1\x10\xc6\xf5\x26\xeb\xce\xf9\x7a\x74\x4f\x35\xe3\xa9\xec\x50\x2f\x7b\xac\xb9\xb4\x39\xf8\xd3\x76\x90\x50\x68\x26\x43\xab\x84\xdc\xc6\x3a\xfe\x6f\x2a\xc0\xac\xfe\xb0\x97\x43\x70\x9c\x66\x9a\x23\x77\xc9\xf7\x46\x9f\xe5\x79\xd8\xd2\x9a\x8f\xd8\x34\x73\x9a\xa4\xb8\x03\x3d\x2c\x56\x53\x78\x4b\xef\x5c\xe3\x3e\xc0\x39\xc5\x4e\xcb\x12\x0a\x30\x99\xca\x64\x97\x4f\xeb\x88\x2b\xbc\x82\x9b\xf5\x63\xb0\x7f\x7c\xea\xfe\x9c\xc4\xd6\x26\x18\x37\xb9\x1e\xd4\x66\xf3\x94\x0f\xdd\xf1\x69\x9b\x00\xe1\x92\x9c\x15\x59\xb3\xcf\xd4\xa4\x40\xa6\x93\x20\x44\x4f\x50\x14\x30\xce\x9a\xf3\x2a\x2f\xfb\xbc\x53\x27\x61\x8c\x42\x0b\x37\x5f\x96\x7f\x0b\xee\xd5\x32\xb1\xf8\xae\xf4\x74\xde\xc2\x08\x4f\x3c\x5b\xcc\xd7\x12\x62\x1d\xf9\xe5\xb6\xd3\x71\x70\x26\x1e\x9d\x74\xdd\xf8\xd7\xa4\x81\xc0\xec\x7a\xbd\xbb\x7d\xd9\x5e\xf9\xcb\x4c\x09\xe5\xd6\x43\xf9\x80\x2c\xe3\xa1\xe8\x15\xd5\x2a\x8e\xb0\x4d\x59\x1e\xa1\x58\xa0\x27\x64\x3d\x83\xbe\xd6\x3a\x09\x62\x8b\x50\x51\x65\xa1\xb7\xbd\x8a\x11\xd5\x40\xad\x6b\x46\xbb\xba\xcb\x53\xde\x00\xc6\x94\x1f\xc0\xb3\x34\x50\xc0\x75\x66\x3f\x10\xc3\xeb\x5e\x17\x48\x62\x4c\x53\xa4\x85\xf5\x3c\x64\x45\x03\xfa\xa9\xcf\x58\x75\x9b\x4d\xc6\xb6\x40\x87\xa1\x49\x56\xbc\x0e\xb9\x54\xda\x44\x29\x2e\xb1\xef\x59\x9d\x35\xee\x87\x0e\x42\x6d\x08\x63\xeb\x78\x83\x02\x1c\x57\xdb\x65\xbb\xdb\x2f\x4e\xcd\xdb\x40\x4e\x9d\x42\x28\x78\x98\xf6\xf8\xde\x87\xf3\xe8\x22\x21\x54\x5c\x25\xbe\x1e\xda\x5e\x05\x46\xa0\xa3\xdb\x05\x84\x58\x17\x06\xbb\x6f\xbb\x5d\x21\xbd\x10\x09\xa5\x40\x74\xcc\x7b\x33\xb8\x55\x5e\x4e\x04\x89\x06\x32\xa5\x14\x88\x91\xd2\xd6\xed\xed\x5e\x90\x95\x9d\x98\xee\x78\x43\x04\x1a\x80\xf3\xeb\xf9\x4f\x59\xa1\xfb\xff\xf5\xa9\x50\xe3\x1c\x6c\xb8\x45\x03\x75\xbd\xa3\x01\x37\x17\xa8\x06\x7c\xb0\x2b\x59\xe9\xed\xcf\x4b\x7f\xf7\xf1\x93\x6d\x1f\xac\x74\x75\xe2\x85\x3e\xe5\xcd\x07\x3c\x7b\x60\x01\x68\x86\x7a\x3c\xdf\x16\x9b\xab\x71\x65\x0e\x98\x16\x28\x3d\x69\xf3\x41\x2f\xfb\xf1\x21\xdd\x68\x7c\x05\x9c\x08\xce\x9d\xd4\x5a\xd1\xa9\x01\xf9\x83\x54\x20\xf6\x5d\x8e\x71\x18\x4f\x9e\xb2\x3c\x9c\xd3\xc0\xb9\x44\xae\xcf\xd5\xe2\xa9\x6e\xdf\x89\xe7\x89\x25\xe4\xfc\x1d\xe0\xc2\x72\xc3\x9c\x31\xe7\xae\x47\xf9\x40\x14\x2a\x84\x67\x7b\x2d\x52\xf4\x82\xec\x96\x12\x88\x62\x89\x59\x6d\xbb\x01\x4c\xd1\x37\x10\x19\x85\xf3\x11\x37\xd9\x97\xac\xa3\x3e\x4d\xbe\x3d\x56\x36\xc0\xa9\xa1\x41\x67\xf2\x4d\xa7\x64\x3e\x19\x28\x42\x2d\x2c\x4e\xed\x54\xbb\xc2\xcf\xed\x29\x1d\x7d\xa5\x88\x35\x96\xf7\x9e\x76\x0f\xdd\x9f\x84\xc0\x3e\x60\xc7\xa3\x9e\x94\x63\x40\xa4\x14\x9f\x2b\xfc\xca\x7a\x09\x75\x77\x2c\x31\x14\x8d\x1b\x2e\xd0\xaf\x1f\x26\x0b\xb3\x61\x02\xc8\x34\xb6\x68\xd4\xf2\x94\x7f\xa4\x5d\xed\x87\x6a\x8d\x5d\xac\xa7\x87\x9b\x71\xd9\x0b\x54\x94\x5a\xc0\xe3\xc3\xd3\xcb\xe3\x6e\xff\xbc\xde\xec\x11\xbe\xd6\x1d\x8f\xed\x27\xff\x83\x62\xd5\xde\x82\x62\x7c\x76\x25\x15\xea\x52\xd4\xd0\xdc\x64\xc6\xa9\x33\x1c\x2e\xa9\xc4\xa0\x20\x51\x4e\x36\xc4\xab\x29\x4f\xe2\x8a\xff\xe5\x3f\x7e\x29\xd3\x92\x22\x78\xb7\x43\x51\xd9\xa0\xb6\x07\x52\x01\x28\xab\x0d\x72\x44\x51\x39\xcf\x35\xfe\xa0\xcd\x03\x60\x62\xee\x25\xba\xb7\x50\xe8\xad\x3c\xc0\x68\xeb\xec\x83\x25\xf7\x09\x13\x51\x6e\x85\xb9\x73\x50\x8d\x15\xa5\xf1\xdf\x6d\x54\x44\x9c\x18\xd4\x62\x00\x02\xfe\x18\xcc\xfa\x8f\xb8\x12\xa3\x49\x65\x82\xc0\xa4\x74\xe0\x84\x94\x5b\xc4\x8b\x3f\x1a\x86\x96\x0c\x04\xef\x90\xbd\x8f\xb1\x5e\xe3\x1f\x62\x02\x92\x28\x57\x07\x7d\xaa\x6c\xfa\xe9\x3a\xd0\x9f\xd8\x86\xff\x3e\x59\xa6\xe7\xd8\x66\x26\xa0\xda\xde\xd4\x76\xde\x6f\xad\xbb\x01\x3e\xad\xee\x32\x43\x88\x74\x3c\xe3\x46\x84\x5c\xfc\xec\xbf\x23\xd2\x55\x77\x5a\x22\x18\xda\x00\x5a\x2a\x62\xaf\x19\x49\x0d\x0d\x03\xb4\x62\x45\x58\x82\x85\x83\x6d\x30\xb4\x9c\xe9\x27\x18\x4a\xc3\xae\xfe\x0b\x45\x53\x56\xf5\x08\xc5\x36\x19\x9c\x6a\xcb\x38\x94\x55\x7e\x9e\x68\x1e\x53\xc3\x08\xc7\x2e\x6e\x7a\x1a\x14\x55\x0d\x63\x16\x37\x78\xac\xe0\x1d\x69\x32\xbb\x9f\x00\xcd\x5d\x77\x9c\x0b\x89\x37\xde\x55\xff\x40\x5a\xb1\x3b\xcf\x49\xfb\x70\x91\x18\x5f\x19\x57\x26\xb5\xe6\xb9\x08\xfe\xb4\x0c\xbb\xf1\x13\xe6\xae\xba\xfb\x72\xb4\xea\xaf\x0e\x46\x32\x5f\x69\x9c\x5f\xdd\x0d\x37\x16\x84\xe5\x34\x81\xfd\x36\xb2\xf0\x58\xe6\x5d\xd6\x4d\x7f\x13\x31\x82\xfd\x35\xab\x82\xef\x68\xdd\xc3\xe3\x89\xcd\x47\x76\x56\x27\xf1\xaa\x54\xa7\x43\xe7\x2a\x45\x8d\x00\xad\x68\x27\x2a\x7c\xf2\x32\x42\x17\xcc\xdb\xb1\x9d\xde\x30\x7e\x34\xc2\x68\x6f\xff\xf1\x52\xbb\x02\xc1\x84\xf4\x33\xb9\x8d\x09\x95\xcc\x77\xb3\x1c\x24\xc8\xe2\x84\x76\xd9\x07\xc0\x52\x93\x30\xe2\xa1\xb2\x2f\x56\x07\x13\x5b\xc3\x77\x83\xf2\xc9\xf4\x13\xda\xe2\x26\xa1\x74\xba\x85\x7d\xbc\x61\x12\x63\x08\x45\x16\x98\x31\x39\x3c\xc8\x1f\xd8\x81\x29\x7f\xcc\x6e\x77\x46\x26\x0a\xfc\xe5\x1e\xe6\x7e\x9e\x1f\xa7\x2c\x8b\xd5\x79\x51\xfa\x2e\xab\xff\xd2\x34\x16\xb1\x15\xeb\xb6\xcb\xe3\x75\x59\x85\xc1\x8f\x2b\x99\x75\xa5\x01\x93\xca\x00\xbf\xc9\x51\xa5\x5d\xdf\xd8\x1f\x55\xc2\xd6\x42\x6d\xb9\x1b\xbd\x93\xd4\x50\x9f\xa8\x8f\xdf\x8c\x12\x8c\x58\x1b\x75\x8b\xcd\x79\x2a\xba\x93\x24\x51\x57\x21\x41\xf6\xc7\xf5\xfd\xea\x83\x7b\xae\x8c\x45\x88\xfa\x12\xe0\xf3\xfd\xc2\x97\x1c\x8d\xd6\x1a\xe9\xe2\x36\xb6\x1e\x09\x3f\x53\x03\xa1\x05\x5c\xa9\x63\xf9\x73\x02\x90\x36\x10\x33\x54\x52\xf5\x7b\xaa\x13\xf9\xfc\x60\xaf\x30\x00\x16\x69\x5e\x43\x63\x26\x86\xc5\xd4\x80\xb1\x02\x84\x35\x32\xf7\xad\x16\xdf\x9d\x63\xe5\x4d\xbf\xd7\x30\xed\xe7\x9c\x7d\x31\xaf\xcb\x0a\x4d\x98\x27\xc3\x44\xa8\x9c\x74\x8f\xe5\x88\x0e\x9b\xe0\xc6\x68\x3e\x12\xb9\x98\xa9\x5e\x19\xa3\x93\x28\xf1\x85\xae\xe3\xe7\x35\x50\x63\x40\xe9\x60\x78\x55\xb7\x59\xbb\xd8\x65\x30\x7f\x3f\x58\x10\x80\xa6\xce\xb7\x1c\x8e\xcd\x44\x7b\x74\x36\x58\x65\x41\x98\x58\x6b\xd1\xe5\x62\xb7\x95\x66\x3c\x6b\x59\x10\x4a\xe9\xd9\x8a\x6e\xc5\x6a\x97\x4f\xd7\x8f\x9c\xbb\x6a\x16\x84\x26\x51\xb6\x48\x26\x5f\x67\x71\xa4\x2c\x20\x24\xd6\x61\x0f\xe7\x9f\xd5\xb7\xf2\x43\xa5\xf5\xad\xcf\x6a\x34\xdb\xc2\xa7\x37\xd9\xbc\x58\x40\x03\x2b\x23\x94\xc2\x88\x8e\xcf\x02\xcc\x45\xed\xe5\x63\x9b\x30\x73\xd8\xd8\xf1\x9e\xf9\x77\x31\xe0\x07\xdb\xff\x68\x8f\x65\x01\x05\x8b\xc4\x6b\x73\xf8\xe7\x9b\x27\xc7\x51\x70\x9d\x18\x8b\xcc\xff\xa8\xdc\xc3\x02\x16\x30\x5b\x55\x6a\x67\xaa\x33\x2d\xb8\x10\x11\x6e\x87\x29\x8f\xca\x5b\x66\xfa\x1a\x3c\x92\xa1\x9e\x8e\x0b\xed\x26\x99\x67\x7f\x9d\x32\xfd\x9c\x83\x7e\xed\xea\xd2\x2c\x60\x54\x62\x42\x75\xbd\x79\xee\xf2\x73\x16\x70\x22\x30\x6f\x42\xbe\xef\x06\x19\x2b\xf3\xb0\x5d\x16\x70\x4a\x48\xc7\x8f\x9f\xae\xe6\xa3\x07\xc0\xa3\x34\xee\x02\x8f\xf6\x46\x3c\x64\xc5\xf0\x3b\x95\x53\xb8\xbc\x59\xfd\x5d\xe9\x82\x05\x11\x55\xaa\x8b\x36\x9e\x0c\x2e\xcc\xcb\x33\xa2\x47\x3f\xb8\xce\x48\x58\x03\x61\xcb\x67\x41\x57\x27\x99\xe5\xfe\xcb\x23\x1d\xe2\x0f\x3e\xb9\x48\xcb\x61\x6d\x51\xa5\xb2\x39\xd5\x7d\x75\xaa\x1d\x9a\xe0\xba\xb8\xbc\xbb\xd9\x79\x03\x53\x77\x28\x0e\x62\x24\x25\x2b\x84\xe3\xb5\xcf\xec\xc9\x38\x1f\xbe\x51\x32\xcc\x02\x11\x5b\x77\x12\xf4\x39\xcb\x9a\xfa\xb1\x6c\xd0\xfc\x77\x7b\x52\x6a\x30\x2c\x09\x62\x90\xae\x42\x33\xe5\xe7\xb1\x20\x09\x23\xc1\x3b\x11\x91\x76\x03\xa8\xaf\xcb\x6a\x3d\x64\x12\xd4\x6e\x52\x4c\xe6\x44\x02\x96\xdc\xdc\x15\x2e\x77\xe5\x6c\x30\xfa\xc1\x3a\x21\x89\x4c\x82\x41\x53\xd2\x65\x11\xd5\x24\x36\xfd\xc8\x34\xb0\x9b\xf0\xb3\x41\xac\xff\x8e\x54\x60\x0f\xe6\x28\x2b\x2b\x5f\x30\x95\xa2\x63\x41\x1a\x51\xe3\x16\xd0\xfd\x1b\xe8\x57\x98\x4b\xee\x59\x90\x26\x21\xb6\xfb\xdf\xca\xaa\xb6\x31\xa7\x9d\x27\xe3\xdf\xa4\x03\x19\x19\xbf\x77\xa7\x19\x14\xcd\xed\xe9\x90\xe9\xac\x41\xf1\x8f\xe3\x30\x5f\xf0\x9f\x68\x23\x50\x27\x2e\x6b\x9d\xed\xee\x47\xce\x76\x6e\x18\x10\x49\xdc\x55\xb6\x8b\xdb\xc6\xae\xc4\x65\x75\x9e\x5c\x26\x68\xeb\x18\x25\xb5\x7e\x84\x9f\xd8\xcb\xb9\xca\xd4\x65\xfd\x95\x85\x61\x6a\x89\x25\xbb\x0a\x0a\xed\x74\x9d\x06\xa9\x32\x0b\x49\x4c\xb1\x50\xd7\xce\xae\xdd\x5b\x55\xfe\xdc\x74\xca\x30\xae\x34\xf3\xda\x55\x6d\x59\x48\x14\x21\x74\xc4\xa5\xee\xc3\x46\x16\x52\x1e\x62\x8f\xc5\x9c\x0a\x15\x76\x7f\xd4\x0a\x83\xc1\x2b\x2c\x6a\xee\xb2\x66\xba\x3a\x85\x2c\x24\xd8\x15\x44\x80\x16\x54\x17\xba\xa0\x2c\x64\x34\xc0\x12\xf9\xd7\xbb\xc7\xd5\xe8\xea\x19\x68\x4c\x4f\xd7\x9b\x15\x09\xfe\x56\x6d\x6a\x7e\x8a\x86\x3c\x94\xc4\xa2\x33\x9b\x2a\x83\x77\x18\x39\x05\xf8\x31\x42\xe9\xde\xdf\x1d\x31\x69\xfe\xb5\xff\x02\x17\x0d\x7a\xff\x21\x63\x35\xee\xf7\x0e\x9a\xdc\x06\x96\xed\x22\x4d\x26\x3f\x2f\xa2\x12\x33\x80\x43\x56\xd4\xd9\x6b\x71\x3a\x76\xfa\x66\x2c\x8c\xe2\x58\x22\xa0\x5e\xa2\x9a\x83\xfe\xb0\x5c\x3d\x7a\x25\xda\xb7\x1d\x45\xf0\x31\x98\xb8\x3e\x35\x27\x8f\x23\x64\x61\xbb\x9c\xc0\x80\x4d\x36\xc0\xf4\x76\x3f\x37\xe6\xb6\x92\xb9\x77\x62\x0e\xce\xbb\xeb\x43\x6a\x27\xa6\xbf\x97\xe0\x00\x16\x0a\x12\x20\x41\xc4\x1a\x19\x7d\x2b\xf3\x8b\xac\xc8\x0d\x4c\x08\x19\x29\xbe\xac\x8b\xb7\x76\x65\xd4\x23\x30\x80\x1f\x0b\x71\x2c\x3f\x04\xfe\x8c\x46\x9a\xd0\x46\x7a\xed\x2b\x32\x91\x56\x66\xa1\xa4\xdc\x37\x9f\x76\x1f\xec\x05\xa1\xd4\xb1\xa4\x23\x77\x51\x5f\x87\x70\x03\xd2\xc0\xa2\xe8\xb2\x7a\x7b\xcc\xb3\xa6\x97\x7c\x65\x61\x4a\x08\x82\xa6\x4e\x85\xb5\x8e\xda\x1f\x51\x85\x78\xdf\x0c\xae\x21\xa5\x0a\xc7\xb8\xa6\xeb\xb2\xf4\x58\x06\x16\xa6\x4a\x61\x2f\xc7\x64\x79\xfe\x54\x7d\xc9\xbc\x1e\x90\x5f\x35\x78\x1f\x0f\x44\x7f\xfe\x3e\x4e\xac\x66\x63\x8d\x30\x75\xdc\xf9\xf5\xee\xd6\x46\x79\xdd\xab\x9b\x82\x95\xab\x6f\x43\xd4\x23\x14\x8e\x60\x79\xa7\x9f\xcc\x53\x01\x8b\x57\x28\xd4\x64\x0d\x0a\x53\x30\xa1\xf4\xd0\xdf\xeb\x0e\x0a\xc9\x42\x45\x78\xa8\xbb\x9a\x70\x3b\xef\x0f\xb2\x5d\x50\x26\x9f\x57\x69\xe2\xeb\x7d\xab\x53\x9b\x90\x74\x8f\xcf\x5d\xba\xfb\x3d\xe3\x88\x27\x54\xda\x60\x65\xe6\x3e\x4b\xab\xae\xb3\xc2\x42\x20\x94\x0d\x75\xad\x1e\x64\x71\xa1\xd9\xff\xfb\x5c\x3c\x36\x10\x40\xeb\x0b\xca\x2c\x04\xda\x99\x68\x22\x74\x64\xc6\x11\x98\x85\xa0\x19\x16\x4c\x17\xc5\x8f\xac\xf9\x9a\x29\xe7\x4e\xe2\xaf\xc9\x04\x8c\x32\x1f\xee\xfc\xe6\xbf\xcd\x15\x44\x6c\x2b\x8e\xfd\xd9\xff\x8f\x6b\xd3\xb1\x3f\x27\xb0\x6d\x16\x9a\x38\xa0\x6c\x58\x7e\xfc\x44\x2a\x65\x5a\x76\x67\x24\x64\x0a\xd1\x06\x5b\x87\x2a\x69\xd7\x4a\x42\x47\x71\x93\x1b\x49\x02\x43\xb5\xab\x82\x5c\x78\x53\xcf\xbe\x1e\x84\x24\x34\xb0\xc5\x0b\x3c\xe1\x20\xba\x26\x44\x5a\xe1\xfa\xac\xde\x23\x6b\x63\x0f\xef\x5d\x8d\x80\x11\x2a\x53\xac\xbe\x39\xf8\xc7\xde\x96\x79\xc6\xd1\xdc\xf8\xab\xa8\x4e\x50\xdb\xa2\xf9\x55\xec\xbc\x56\x39\x23\x14\x08\xe1\x3d\x0c\x05\xbb\xdb\xd7\x65\xb5\x3d\x59\x86\xe7\x07\xa1\xf8\xe8\xc4\x2c\xb5\xcb\xaf\xb2\x3b\x9a\x93\x92\x1d\x92\x4c\xda\x31\xd0\xa3\x7e\x96\xb2\x06\xfc\x22\xbf\x08\x90\x28\x8c\x89\xb3\xb0\xf5\xb0\x8f\xeb\xaa\x3c\xa0\x55\xc7\xb6\x3c\x55\x17\x71\xee\x6c\xea\xc6\x48\xe4\x3c\xa6\x2d\x7c\x05\x7d\xdf\x26\xcf\x48\x84\x06\x5b\xb2\xd7\x8f\x8b\xe1\x64\x23\x22\x16\xd8\x98\xb2\xae\xf3\x5e\xcb\xe8\xc9\x74\xc7\x45\x8c\x4d\x51\x7b\xe6\xd9\xe8\x87\x08\xc5\x31\x8e\xba\x91\x87\x7e\x15\x23\x02\x00\xd9\xdd\x77\x85\xce\xf0\x75\xfe\xc7\xfb\xac\x3b\x41\xd2\x46\xbb\xbd\xda\x3a\x96\x81\x3e\x28\x5d\x4d\xe1\x18\x93\x13\xc5\x42\x3b\xda\x1c\x2a\x06\x4d\xaf\x3f\x51\x81\xb0\xf5\x83\x23\xc8\xee\xd1\x25\xda\xf2\x75\xb7\x2f\xab\xd5\x34\x51\xb8\xa8\x3c\x31\x92\x98\x10\xe3\xdd\x41\x09\x72\xdb\x06\xcd\x0e\xa9\x7a\x41\x66\xea\x3e\xa6\x51\x5d\xba\x4d\xe3\x2c\xa7\x0f\x39\x20\x3e\x79\x22\x32\x94\x28\x01\xb1\x5a\xed\xd6\xdd\xdf\x12\xe3\x58\xb8\xea\x54\xd5\x6d\x46\x9b\x97\xe5\x87\x1e\x8b\xfe\x43\x92\x63\xc5\xc7\x3d\x42\x27\x29\xf9\x81\x98\x29\x23\xa9\x48\x13\x74\x2f\x5c\x21\x46\xbf\x7d\x29\x06\xea\xc6\x16\xd3\xc4\xfd\x58\x29\x10\x89\xa9\x41\xe5\x88\x2b\xc7\x57\xf3\xb1\xc4\x60\xb4\x7f\xb1\x53\x63\x10\xb5\xbf\x2d\x4d\x73\x75\xd2\xdd\x44\x51\x22\x44\xbc\xbc\x13\xbb\xee\x5d\xf1\xfc\x71\x1d\x73\x4f\x09\x79\x5e\x5d\xcd\x6f\xb8\x44\x73\xca\xbd\xbc\xbb\xb5\xe4\x68\xcf\x63\xd5\x4e\x27\xef\x82\x4e\x2c\x5a\xb2\x17\x8d\x7e\x8f\x7f\xeb\x8f\xe1\xbe\x7d\xaa\xdb\x18\xc7\x40\xbb\x22\x1c\xb2\x66\x9d\x5b\xf5\xbd\x7f\x9a\xb3\x8f\xbf\xb0\x4d\x85\x74\x0f\x5f\xde\x4e\xaa\xcc\x8c\x00\x67\x18\x6e\xef\x5d\xb1\x6d\x08\xd2\x61\xc4\xc4\x56\x8e\xfa\x58\x41\x5f\xf4\x66\x34\x30\x12\x5f\x3b\x03\xea\x6d\x5b\xc8\x63\xfd\x56\xda\x9f\xe3\xb3\xd4\xd1\x45\x50\xc2\x19\xae\x35\x7b\x4b\xde\x76\x77\xc6\x1d\xa4\x61\x0a\xce\x6d\x74\x92\x02\x52\x46\x02\x5c\x3f\xdf\xad\xe7\x2f\x60\x29\xf1\x38\xed\xc6\x5d\x86\x76\x7d\xb3\x75\x1c\x4d\x50\x46\x85\x65\x07\xe8\xbd\x29\xab\xbd\x9c\x5b\x53\x28\xd3\xa1\xe8\x11\x22\xdb\x83\xac\xba\xc2\xe9\x7c\x87\x95\x51\x06\x11\x02\x13\x6e\xe5\xa1\xdd\xca\x87\xcb\x1c\xe5\x01\x4d\xf4\xd8\x21\xe0\x54\x34\x67\x27\x86\xeb\x7d\x28\xfc\x60\x12\xaa\xa8\xe3\x9a\xda\x91\xc3\xc0\xe0\xb2\xa0\x42\xe3\x48\x84\x0e\x8c\xbc\xf3\x7b\x0c\x15\xc2\x5a\x5c\xdb\xba\x05\x34\x57\xe5\x7f\xdd\x2e\x25\x2e\x94\x23\xc7\xb7\x48\x24\x09\x62\x41\xd3\x0a\xe4\x0f\x8f\xc7\x62\x54\xa4\xb6\xcd\xf1\xed\xee\x71\xbf\x7a\xd9\x3d\x5d\x5f\xfb\x23\x49\x04\x58\xe2\x6a\xc3\xfd\x01\x79\xf6\x9f\x00\x80\x19\x4d\x84\x66\x2e\xc9\xbf\xc9\xcb\x54\xe6\x36\x5f\x1f\x5a\x84\xf4\x71\x01\x4d\x24\xc5\xc9\x6c\x4d\x0f\xad\xaf\xff\xa9\x97\x33\x64\x34\x01\x4b\x4c\x70\x35\x78\xec\xa6\x4d\x9f\x95\xa4\x04\xb5\x4c\x7a\xef\xf6\x45\x8d\xfd\x82\x51\xc3\x66\xb4\xc2\xb6\x3b\x3f\x76\x8b\xfd\x44\x7c\x94\x07\xd8\x66\xaf\x85\xc4\x2c\x65\x32\x1d\x67\xb6\xcd\x0f\xa2\x5b\x9a\x86\x96\x90\xfd\x9a\xbd\xc3\x0c\xbd\x97\xd1\x54\x00\x86\xac\x9b\xa7\xdb\xdb\xcf\x4a\x46\x34\xd5\x11\x02\x71\x9f\xbe\x3d\xae\x37\xdb\xfd\xe2\x65\xb5\xbb\x7b\xc2\x47\xf5\x5b\x37\x42\xa1\x03\xe0\xc3\xe2\xfb\xfe\xdb\xdd\xee\xf6\x6a\xb3\xf8\xb6\x7f\x5e\xed\xf6\xbb\xef\x7e\x88\x0a\x02\x84\x5c\x66\xdf\x64\xd1\x7c\xff\x02\xe7\x79\x4c\x09\xa3\x2a\x8a\x63\xde\x6d\xdd\x65\xd5\x86\x17\x17\x72\xb1\x8c\xaa\xd8\x44\x69\x57\x95\xda\xca\x1c\x2e\x08\x73\x8c\x42\xa0\xd0\xc4\xd8\x95\x48\x67\xe4\x9c\x18\x85\x84\x78\x3a\xfe\x63\xd9\x2d\xdf\xd4\xc4\x02\xb5\xe3\x6c\xfb\xec\x62\x6d\xa3\x26\x89\x85\xa7\xef\x58\x95\xb6\x55\xf9\x6e\xc0\x4c\x2e\x81\x05\x81\xc0\xda\x9d\xb3\xfd\xfc\x47\xd4\x1a\xc6\x82\xd0\x9a\x12\xde\x14\x1d\xbd\x90\xb1\x50\xd0\xc8\x37\x49\xf4\x3b\x54\x4d\x56\xe3\xf2\xbd\x6d\xca\x4a\xbe\x8e\x15\x12\x19\x0b\x53\x81\xc4\x15\x5c\x3a\x67\x9a\x29\x8c\x11\xc3\x88\xc3\xdf\x74\x5d\xa5\xfb\x52\xc9\x7c\x5a\x8c\x1c\x5f\x1b\x4d\x14\x56\xfc\xd4\x50\x40\x82\x31\x96\x58\x61\xf1\x9e\x92\x3e\xa8\xeb\x33\xc6\xd2\x00\x55\xb3\x7c\xe6\xb8\x2a\x8f\x23\x84\x79\x37\x8c\x10\xcf\x4f\xcc\xb4\xef\x42\xd5\xd7\x65\x85\xe0\xc9\x69\x3d\x8e\xf1\x28\x09\x52\xaf\x65\x8c\xdd\x56\xa4\xfd\x3b\x75\xf1\xf8\xcf\xc9\xb5\xf3\xc4\xea\x44\x60\x6f\x31\x74\x9d\x31\x3b\x2d\x1e\xe4\x2f\xaf\x1f\x3d\xf9\x8c\xb4\xa2\x59\x47\x79\xde\xa7\xe7\x7d\x5a\x16\x7a\xaf\x26\x3a\xbc\xd3\xaf\xd1\x11\x3a\xac\x99\xb2\x82\xec\xb5\x58\x56\x99\x7e\xed\x1e\x63\x14\x4b\x5c\x54\xaf\x9f\x36\xe8\xcf\xd1\xfd\x5d\x41\xe8\x18\x8d\xff\x53\xa6\xb3\xf4\x10\xc6\x62\x91\xa6\xd6\x5f\x18\x97\xa8\x41\x7e\xcd\xe2\x44\xa3\xbf\xae\xc1\x8b\xf3\x7f\x15\x9a\x7a\xd2\x3d\x96\xfd\x3b\x6d\x43\x31\x39\x73\x42\x62\xe3\xda\x7f\x56\x16\xad\x5d\x70\x91\xf6\x3f\xa8\x60\x30\x29\x4c\xec\x16\x7f\x33\x00\x6b\x31\x96\x32\x4b\xfc\xb6\x51\xed\x63\x59\x1d\xda\x79\xe4\x45\x03\x18\x4b\x53\x81\x45\xf7\xae\x86\xed\x04\xaa\xbb\xe3\x06\xa2\x61\x27\xec\x7a\x68\x88\x3e\x8e\xe2\x98\x8a\xad\x01\xec\xd1\x3a\xc8\xbb\x42\xf1\xe4\xb1\x29\xa1\x02\x8b\x54\x94\xd5\x6b\x9b\x92\xfb\x6f\xd2\x81\xc4\x0c\xf0\xe1\xee\xf1\x6e\x7f\xb3\x78\x58\x0f\xc5\x65\x18\xd3\x22\x75\x3c\x19\xcf\x4e\x9e\x7f\x45\x0d\x4b\x12\x37\xdf\x97\x55\xa6\x7e\xdc\xe9\x7a\x79\xbe\x6c\xcc\x33\x66\xb8\x2d\x0d\x1c\x4a\x9d\x99\xf3\x4e\xfe\xda\x5c\x2c\x54\xcc\xc4\x0a\xc1\xe1\x4d\xf9\x62\xff\x8e\x5d\xa4\xf1\x10\x49\xb0\x5a\x61\x5d\x22\x5c\xed\x79\xdd\xbc\xf5\xaa\xc8\x21\x71\xd6\x45\x7e\xcb\xe7\x61\x6a\xe2\xb0\xd3\x84\xfb\xc8\x76\x6b\xfc\xc3\x38\xa5\xc4\x6b\x33\x6d\xa0\x6e\x64\x35\x28\x12\x71\x1a\xb1\xc0\x95\x3c\x17\xef\xb2\xea\xfe\x9c\x18\xcf\xce\x42\x80\x9a\x97\xe6\xae\xbb\x01\x92\x85\xe8\x01\xe9\x03\x23\xb6\xdf\x77\xc7\x94\xc1\x26\xa8\xd7\x24\xee\x16\x0d\x4e\x35\xa0\x9e\x87\x8b\xa1\x67\xf4\x5b\x7f\x9f\x49\x61\xfa\x9f\xc2\x82\x40\x59\xc5\x2b\x04\x20\x4f\x65\x28\xfd\x28\x06\x1e\x39\x71\x53\xc9\x42\x5f\x4b\x75\x59\x65\xe6\x0c\x62\xe6\xd8\x6c\xc8\x0f\x9d\xcf\x30\x38\x27\x11\x02\x34\x73\x30\x4d\xc2\x27\xdf\x14\xa5\x10\x5b\xf2\xe3\x74\x21\xe3\x91\x21\xa9\x27\x90\x0c\x04\x4e\x86\xf7\x3e\xa6\x06\x83\xc7\x36\xc0\x7f\xce\xe5\xb9\x3d\x56\x37\xf2\x70\xec\x06\x30\x0b\x54\xdc\xdd\xde\x6d\xae\xf6\xcf\x8b\xcd\xee\x8f\xfd\xfd\xd3\xea\xcb\xcb\xf3\x7e\x71\x75\xb5\xe9\x86\xc9\x04\x85\x41\x57\xe5\xe9\x38\x51\xc2\x65\x5c\x04\x40\x06\x18\x46\xdb\x3a\x9e\xdc\x0a\x41\x04\x6e\xf7\xe8\x10\xf3\x64\xee\xcb\xe2\xf5\xb6\xd4\xf9\x57\xe2\xbf\x41\x50\x6b\xd3\x89\xf3\x6e\xc0\x77\x9f\x9f\x70\x49\x60\x22\x87\xaa\x5a\x1c\x4b\x0d\x95\xd4\xe5\xb8\x63\xc0\x93\x30\xf4\xd6\x35\xb7\x65\x1b\x27\x9d\x5d\x36\xb0\x9f\x5c\x7e\xc2\x98\x76\x41\xdf\x4a\x1e\x8e\x32\x7b\x2d\x10\x42\xb2\x3c\xdf\x0d\xf2\xbc\x2e\xec\xe3\x89\xb4\x22\xa9\x5f\xaa\xec\xd8\x94\xcf\xb2\xf2\x0b\x16\x4f\x0c\x91\x74\xc8\x97\xb3\xf5\xf8\x7f\x9a\x2b\xb9\xb3\x48\x91\xa2\x52\x87\xc9\xb3\x23\x25\x03\x3c\x3d\xe3\x32\x8d\xb1\xbe\xb4\xac\x64\x56\xdc\xd5\xc3\xc0\x9e\x2b\xa0\xb8\x79\x67\xf2\xce\x55\x30\x96\xd3\xf9\xa8\x40\x23\x2a\x74\xf5\xb4\x59\xef\x77\xeb\xc5\xc3\xfe\xf9\x69\xd3\x06\x66\xdd\x39\x8c\xb5\x03\x5c\x54\xff\x39\x15\xb2\x67\x56\x31\xae\x43\x8d\x37\x1c\x9a\x37\x47\xcc\x2c\xbb\x37\x59\x2b\x8d\xea\xd6\x75\x53\x1e\x47\x6d\x60\x0e\x71\x8c\x4d\x23\x57\xb8\x58\x14\xd9\x01\x94\xfc\x1b\x5c\xd5\xec\x02\xce\x21\xd1\xc8\x54\xb9\x91\x87\x36\xaf\x7e\xc5\xb8\xe5\xf3\x1b\x09\x32\x50\xe1\xe0\x71\xb4\x61\xf2\xf7\x42\x1e\xb0\xb2\x74\x25\x8f\xc7\x8b\x8a\xe9\xcc\xd3\x36\x44\x44\x58\x7b\x49\x4f\xe7\x4f\x0c\x43\xdd\xf2\x19\x05\xa1\xa2\x13\x94\xe9\x43\xbf\x3a\x45\x01\x21\xca\xea\x25\xc2\x0d\x34\x0f\x65\x01\xe7\xa5\xf4\x56\x39\x2c\x0a\x62\x8d\xd9\xce\x51\x36\xd9\xc5\xfb\x1e\x05\x89\xf5\x7f\x71\x9e\x7b\x8b\xe3\x71\xb4\xe3\x8f\x53\x4d\xff\x1e\x44\xa1\x93\xac\x00\x24\x92\x5d\xca\x94\xb1\x28\xd4\xa9\x71\xee\xcd\xb8\x19\x2d\xb2\xea\xaa\x2a\x8f\x9b\x5e\xf2\xdb\x0d\x24\x24\xc2\xc8\xe9\xcb\xfa\xc1\x7f\x96\xa4\x80\x00\xfa\x0a\x0a\xf8\xb9\x3d\xa5\xd6\x7e\x24\x2b\x8b\xe5\xf9\x4a\x5e\x06\xec\xe3\x27\x14\x11\x60\x38\x3f\x70\x19\x2f\x8f\x65\x97\xe9\x47\x94\xab\xce\x15\x0d\xe5\xc0\xa6\xbe\x17\x2c\x62\x91\x2d\x56\x6d\x9b\x0a\xe4\x21\x6b\xce\x3b\x59\x65\x66\xd2\xb7\x8c\x98\xe6\xd8\x77\xb2\x29\xec\x70\x9d\xc4\x6e\x86\xff\x3e\x1e\x72\xab\xcd\xf3\xda\xe9\x8b\x5a\xca\xe6\x94\x52\xf9\x7f\xaa\x7b\x44\x5c\x58\xbf\x2f\x6b\xf2\xd6\x9e\x7e\x0a\xdc\x1e\x5f\x35\xd7\x06\x55\x6d\x90\x59\x62\x6b\x68\x16\x7f\x32\x3e\x6d\xc4\x52\xac\x6b\x67\x45\x03\x15\xd4\xcd\x23\xfc\x6a\xee\xbc\x77\xb5\xff\x69\x51\x4a\xf4\x90\xb5\x71\x57\x3f\x97\x75\x9d\xf5\x61\x60\x14\x41\x14\xfb\xba\xd2\xae\xc4\x9a\x6b\xfb\xee\x23\x07\xfe\x62\xb6\x0f\x5f\xf0\x28\x02\xe8\x30\x63\xc7\xa3\xff\x2d\xa3\x49\x13\x33\xc2\x6d\x7f\xf4\x50\x95\xe7\xe1\x92\x15\xc5\x89\x85\x66\xed\x31\x23\x2b\x4d\xd6\x6c\xdf\x64\x65\x55\x72\xe4\x01\x3a\xda\xf0\x45\x94\x12\xc5\xd2\xa0\xc0\xc3\x3a\x97\x7a\x7c\xca\x54\x79\x66\x60\x7a\xaa\x6c\xb2\x73\x2b\x0b\x9d\x77\x4d\xd6\x76\x88\x4e\xec\xaf\x75\x84\xb7\x6f\x90\xf9\x83\x22\x49\x6c\xbf\x4b\xbd\x81\x3e\xe5\xce\x90\xd9\x83\x31\x57\x72\xe0\xea\x30\x1b\x6d\x47\x32\x91\x58\x80\x3e\x56\x59\x31\x30\x43\x87\xf9\x25\xef\x64\x65\x1b\x46\xf7\x54\xa6\x0a\xe9\x2f\xbd\xa6\xf0\x50\x8e\xec\xd2\xd0\x91\x45\x52\x45\xc8\x34\x7d\x5e\x3d\xf6\x00\x6b\x77\x4c\x25\x56\xab\xf2\xb0\x6f\x23\x9a\xac\xea\xaa\x90\x91\xa6\x56\x72\xf3\x38\xf2\xa3\x61\x91\x36\x11\x75\xf1\xda\x0e\xe4\x61\xd9\xae\x15\xd5\xf4\x2b\xc1\x18\xd4\x63\xd9\x5b\xf8\xc5\xa6\xcc\xe1\x19\x2a\x07\xc4\x9d\x17\x15\x64\x91\x89\x13\xbc\xf3\xbb\xbb\xf5\x86\xec\x9f\xd7\x9b\xd5\xfa\xd1\x17\x04\x50\xf5\x31\xf0\xb2\x8f\x6c\x2c\xfb\xc8\xe2\x80\x86\xd8\x37\x3f\x56\xa5\x02\xd0\x5f\xfe\x18\xbb\x9c\xb3\x38\x88\x21\xd0\x5d\x79\x7e\x8c\x60\xfd\x7d\x32\x54\xd8\xb8\xe9\xba\xde\x7d\xe9\xc8\x1f\x13\x82\xb6\x1f\x2a\xad\x0c\xe2\x53\x3e\x6f\x32\x7f\x59\xfe\x8e\x03\x13\xe3\x86\x31\xc1\xb4\x2e\xcf\x53\x4b\x79\x16\x87\x21\x11\xdc\x31\x84\x65\xd5\xf4\xd8\x6d\x16\x87\x9c\xa1\x61\x50\x05\x45\x79\x2a\x14\x2c\x2c\xdd\x63\x44\x3b\x64\x71\x08\x96\xef\x7c\xf7\x2c\xcf\xdf\xbb\x3f\x9a\xc8\x44\x16\xc7\xb2\x4f\xe1\x03\xfb\x13\x16\x93\x84\x1a\xef\x1f\x8f\x8f\x78\xf2\xd3\x99\x60\xf8\x3b\x1c\x99\xe1\xc9\x2c\x1a\xef\x58\x3b\x1f\x94\xc5\x4c\x1b\x7c\x82\xfb\x36\xbf\x01\xa7\x6f\x35\x8e\xca\x62\xce\x08\x8a\xd4\x1d\x64\x71\x32\x52\x35\xa7\xaa\xff\x35\x5c\x44\xde\xc3\xe2\xae\x68\x46\xa9\x4c\xcc\x13\x83\x40\x20\xdf\x73\xb7\x31\x8e\x35\x68\xf7\x43\x52\x89\xfe\x8d\x6e\xfb\x7a\x96\xe7\x65\xd6\x78\x1f\xf3\xc9\xe6\x11\x47\x22\x42\xde\xcd\xae\x7c\x7d\xcd\xe1\xa1\xcd\x20\xa0\xe8\x49\x02\x2c\x8e\x89\x35\xbb\xb4\x41\xed\x43\x66\x99\x36\x59\x3a\x99\x97\x31\x57\xda\xd1\xba\x16\x63\x4f\x50\x37\x40\x04\x61\x18\x3a\x57\xb8\xaa\x59\xff\x15\x46\xbf\x8d\x78\xd0\x61\x37\x90\x53\x6c\x90\x59\xaf\x04\x0c\x40\x4b\x59\xa1\x17\xe2\x98\xca\xca\xe2\x24\x52\x8a\x0c\xc1\x81\xf5\x5d\x71\x09\x5d\x89\x13\x29\xbd\x63\x86\x97\x5b\x2e\x4f\x48\xde\x1a\x75\xf1\xe3\x24\x4d\xa4\x9a\xa8\x0c\xf9\x63\x52\x87\xca\xbb\x1d\x62\xef\xfd\x4e\x4f\xca\xe9\xed\x72\x8a\x91\xfb\x16\xc3\xca\x97\xc7\xbb\xdd\x62\xf3\xc7\x7e\x7b\xbf\xd8\xde\xfa\xb3\xa8\x50\xfb\x42\x68\x87\x1c\x1f\xb5\x07\x63\x95\x06\xb4\x9d\x3b\x68\x05\x45\xbf\xad\xd7\x5f\x46\x29\x76\xac\x23\xdd\xcd\xad\x55\x25\xd3\x67\x59\xd9\xbe\xf2\x74\x4f\x8c\xb5\xb1\xaa\x2f\x93\x5f\x8d\xf5\x40\x37\x04\x82\x08\xfb\x69\x2f\x35\x7c\xcb\xea\xb7\x51\xcc\x1a\x1b\x4a\x31\x65\x3a\xbe\x95\x05\x38\xd5\x55\x7f\x48\x05\xda\x4e\xde\x5f\x1b\x30\x50\x55\x32\xf7\xb3\x4f\x04\x32\x8a\xa3\x4e\x51\xa9\x6e\x97\xda\x0a\x3c\xe4\x4d\x84\x91\xc6\x02\xce\x4f\x48\x6f\x32\xd3\xbc\x14\x9f\x92\x57\x98\x08\x63\x8d\x55\x48\x0b\x4b\xec\x99\x1d\xa3\x9f\x2a\x42\xc1\xf1\xa6\xad\x2a\x00\x0d\xbf\xba\x2f\x93\x02\xa1\x9b\x5d\x43\x19\x71\x15\xcd\x05\x64\x0c\x4f\xc6\xdc\x96\x2a\x08\x70\x5c\xf6\x31\x19\xbf\x3f\xa9\x1f\x67\xfb\xe3\x37\xf0\x0e\x32\xff\x1b\x21\x2b\x26\xa8\x10\x54\x7b\x1b\xc1\x85\xd6\x0f\x08\x59\x98\x61\x12\x30\xc1\xb8\xdd\x78\xda\x58\x31\x85\x7a\xff\x96\xd5\x65\x75\xde\xe7\x03\x5e\x62\xbb\xf8\xc4\xb8\x48\x2b\x99\xe7\xcb\x46\xb5\x79\xf8\xb6\xb9\x40\x95\xff\x1d\xec\xed\xc3\xa6\xcc\x20\x66\x17\x91\x14\x40\xbd\x10\x40\x47\x9d\x1e\xad\x5b\x42\xd0\x38\x75\xb3\xea\xae\xc6\x89\x67\x0d\x70\xd7\xbf\xe0\x70\x9c\x97\x7e\x66\xc2\xcb\xce\xa3\xb7\x5a\xa3\xde\xae\x4e\x76\x0f\xc7\xfa\xfe\xf2\x7c\x03\x05\x54\x72\xe0\x16\xe4\x57\x27\x21\xa4\xa4\x0e\xef\xdc\x86\x74\xf8\x7d\xb6\x93\xd5\x0d\xd0\x88\xd7\x3e\x64\x85\x43\x1b\xdf\x15\xab\xc1\x62\x28\x92\x10\xc2\xd4\x97\x56\xb3\x62\xf1\x0a\x17\x8b\xf7\xec\x22\x2e\x12\x1a\x60\x91\x3a\x3f\xee\x64\x75\x21\xee\xc7\x44\xc2\x62\xc4\x7a\xd5\x0d\x1c\xf7\x47\x79\xee\xff\x9e\x80\x5b\xbc\x6f\x70\x3b\x39\x5f\x97\xa7\x6a\x66\x45\x14\x09\x28\x42\x3b\xe0\xe6\x80\x34\xde\xdd\xec\x34\xe2\xd8\xa3\x42\x5f\x7b\x97\x6e\x0e\x57\x25\x91\x26\x3c\xb5\x22\x15\x2a\x3b\xf4\xef\xa0\x02\x92\x38\x43\x2a\xdb\xcf\x32\x65\xe5\xbd\x51\xdb\x40\xaa\xfc\x3c\x9a\x15\x3a\x88\x43\x5b\xd5\x69\x63\x6d\x8b\xb8\xd2\x93\x6b\xd3\x61\x10\xf7\x38\xb6\xab\xd3\x0f\xb0\xe0\x70\x2f\xe3\x3a\xd2\x5c\xf9\xfc\x95\xd1\x9a\x60\x8e\x83\x05\xc5\xdd\x1f\xcf\xeb\xfd\x55\x27\x9e\xce\x84\xee\x71\x19\x96\xc8\xb8\x98\x91\x43\x69\x87\x71\x04\x17\xbc\x38\x5c\x1d\x1e\x7b\x96\xe7\xeb\xb2\x72\xe6\xd6\x93\x0f\x00\x33\x2c\x70\xe2\x18\x5e\x36\xe2\x42\xdf\x91\x09\xd0\x89\xf4\xe2\x49\x38\x11\xee\x0a\x55\x56\x15\xa8\xe6\x0a\x6a\xec\x35\x81\xb6\xaa\x96\x16\x41\x56\x5f\x65\xef\xed\x7b\xec\x2f\x1f\x8c\x44\x92\xdd\x5e\x95\xc7\xf3\xae\x5c\xb6\x37\x71\xc2\x3f\x1d\xdf\x0d\x13\x08\x04\x50\x79\x3f\xaf\x9d\xcc\xf3\x0c\x2e\x45\x40\x2f\xde\xec\x2e\x57\x17\x26\x26\xa1\xbb\x65\xf6\xed\x1c\xe0\xc4\x84\x91\x1c\xe5\x56\xea\xf2\x00\x2f\x45\x2d\x0d\x2c\xd4\x85\x1e\x30\x13\xc6\x48\x74\x3d\x51\xbd\xbb\xdb\xf8\x42\x93\x20\x50\x5d\x31\xf8\xe1\xe5\x61\xbf\xde\xdd\xae\x37\xfb\xed\xf3\xfa\xd1\xc3\xab\x93\x90\x30\x14\xc3\x42\xd0\xd3\xda\xdb\x78\xf8\x83\x2c\xf6\x48\xb1\x55\x75\xde\x96\xb9\xd5\x52\x9f\x2f\x05\x27\x21\x98\xc8\xde\x16\x50\x9d\x53\xf4\x42\xeb\x8f\x30\xe2\x09\xa1\x02\xa5\x91\x53\xa9\x7e\xec\xb2\x5f\x03\x02\x3f\x4b\x28\xe5\x71\x3a\x90\x68\x1e\x1f\xe4\x14\xf7\x9c\x2f\x4f\x8b\xfb\xc5\xf3\xe6\xe9\x7f\xd6\xab\x5d\x7f\xcc\x60\x14\xf3\x7c\xef\x77\xe4\x84\x11\x11\x59\x4f\xef\x06\xc4\x1e\x0a\xbd\xef\x10\x23\x09\x23\x2a\x30\x1d\x55\x6a\x5f\x8d\x38\x37\x2c\x61\x52\x63\xd8\xfa\x9f\x93\x7e\xbd\x68\x6f\xb9\x31\x3c\x0c\x90\x4d\xba\x7c\x7a\x79\xdc\xfd\xb1\xbf\x7e\xe9\xef\x2e\xe7\xdc\x2a\x77\x63\xec\x76\x57\xdf\x67\x9e\x8d\xc3\x12\x2e\x2d\x84\x22\x3d\x9d\x07\xc6\x17\xe3\x53\xc7\x32\x88\x42\x2f\xdb\xd7\x86\xff\x57\x95\xfc\x39\x74\x14\x71\xe3\x04\xa3\xe0\x5d\x28\x72\xd9\x64\xc5\xe9\xf0\x99\x68\x3a\x4b\x92\x90\x7b\x92\x89\x53\x18\x9e\x35\x5f\x64\x49\x22\x0c\xb5\x88\x20\x93\x15\xde\xa3\x81\x25\x92\xc5\x48\x64\x69\x33\xd3\x0a\xde\x33\xf8\x89\x8b\xf6\xbb\x97\xdc\x65\x89\x94\x04\x33\x28\x28\x34\x46\x35\xfe\xef\x69\x2c\xac\x00\x82\x6c\xb3\xf6\xbf\x25\xd7\xe2\xfb\x27\xfc\x67\x21\x40\xde\xc8\x8d\x93\x49\x7b\x2e\xbb\xe7\xa8\xc2\xae\x55\x76\x2b\xeb\xb7\x91\x74\x00\x4b\x94\xb4\x2a\xe1\xb5\x05\xe7\x3e\x15\x53\x9b\x9d\x76\x48\xca\xdd\x0e\x68\x5d\xa2\x3f\x78\xa7\x74\x4a\x30\x67\x99\xda\x58\xcf\x3e\x3f\xad\x23\x84\xc1\xec\x1d\xde\x0c\x19\x1f\xa4\xd0\x57\xc3\xfa\xf6\xfc\xf7\x80\x48\x91\xfa\xbc\x7c\xf9\x63\xe0\x54\xc1\x12\x48\xac\x09\x7f\x9b\x91\xc8\x1c\x77\xad\xf1\x7a\x96\x80\xe4\xd8\xae\xc8\x41\xea\x8b\x74\x38\x31\x61\x8a\x18\x6d\xf9\x0a\x85\x96\x53\xf0\x7c\x62\x12\x21\x92\xb1\x6a\xef\x40\xbb\xaf\x9e\x01\xde\x26\x06\xe2\x4e\xd7\x05\x63\xfc\x75\x01\xd5\xeb\x79\x54\x5b\x91\x01\xb3\x06\x1b\xd8\xd8\xc3\x22\x5a\x8d\xe1\xdb\xdf\x4e\x80\xd1\x5d\x91\x81\xb2\x3e\x05\xd6\x8d\x3e\xcd\x0a\xd0\xdf\x64\x55\x65\x1d\xbf\x93\x49\x12\x70\x9c\x78\xff\xef\xee\x61\xf9\xb4\x7a\xba\x7b\xec\x0e\x70\x8d\x89\x19\x46\xaa\x2e\x4b\xfd\x74\xcd\xf6\xe8\x08\x49\x89\x46\xe6\x2b\x4e\xba\x85\xe7\xd6\x61\xb5\xad\xfb\x5a\x1a\x83\x2f\x03\x6e\x65\x2e\xab\x0b\x41\x50\x3f\x4e\x71\x5f\xec\x77\x6f\x9e\x4d\x2f\x96\xe7\xc7\xf2\xe7\xf8\x61\x48\x16\x05\xd8\x6e\x29\x8d\x99\x29\x6f\x8d\xcf\x1b\x47\x11\x56\xcc\x8f\xf2\xbc\x7b\x03\xe7\xfd\x34\x19\xa2\x23\x0c\x54\xb3\x02\x8d\xd8\xed\xc3\xfa\x6d\x06\x12\x2b\x63\x1d\xc7\xf6\xc7\xe4\x16\x58\x52\xb7\x17\x37\x3e\x9b\x08\x99\xef\xa4\xd9\xf0\x30\x1f\x3f\x71\xc1\xb9\x6b\xcf\xe9\x49\x3c\x30\xb3\x21\x4a\x61\xbc\x4a\xd4\x7b\xf9\x63\x12\x08\xc8\x84\x42\xe4\xee\x2d\x5e\x8d\x05\xdd\xcd\x2f\x6d\x32\x61\x0c\xb1\x4f\x7b\x0b\x43\x5a\xe4\xb9\xd5\xf0\xdd\xc9\xfa\x07\xda\x95\xdc\x96\xf9\x07\x9a\x1f\x4c\x26\x0a\x74\x2f\xea\xf0\x5c\xe6\xf9\x28\xe5\x92\x09\x30\xd6\x97\x4c\x3a\x43\xcf\xd9\x8d\x41\xca\x04\x50\x22\xd2\xfb\x06\x6f\xd6\xdb\xf5\xe6\xeb\x7a\xb3\xbe\xda\x5b\x42\xbf\x9f\x3b\x52\x05\xa8\xcc\xf8\x9f\xb2\x0d\x92\x73\x2f\x6f\xc3\x64\x4a\x01\xbb\xf3\x4e\xa0\x50\x56\x6d\x4a\xdc\x64\x75\x93\xa9\xc9\x7b\x2d\x15\x4f\xb1\x6e\x0b\x95\x22\xc1\x97\x9b\xed\xb0\xb1\x2d\x55\x14\x22\xc9\xf7\xf6\xe9\xd9\x2f\x24\x52\xa5\xdc\xc9\xb6\xb8\x19\x3d\x3d\xa1\xb1\x8e\x88\xca\xeb\x0a\x0c\x44\x29\x47\x55\x79\xa9\x63\x06\x49\x27\x22\x6e\xd5\x85\xc6\xf6\x3f\x6e\x20\x90\xc8\xc4\xbd\x2a\x3f\xd2\x0d\x66\x07\x9a\x30\x50\xc6\x6b\x28\x83\xde\x95\x37\x36\xb4\x9c\x4c\x41\x43\x01\x42\x4f\x24\x38\x55\x85\xb4\x80\x91\x1e\x6f\x97\x06\x81\xc4\x99\xa3\xca\xe2\x1d\xaa\xe6\xf1\x74\x98\x4a\xc9\xb2\x34\x60\x46\x3a\x1c\xdd\xa2\x6a\x6f\xae\x9f\xae\xbe\xfa\x31\xba\xb6\x34\x0c\x24\xf0\x5e\xc1\xe7\x22\xd7\x4d\x49\x64\x3b\xbe\xda\x59\x3d\xf9\x04\xdc\xbe\x48\xcb\x53\xcf\x8b\x70\xa0\x34\x21\xba\x6b\x21\x71\x8a\x91\x4d\x86\x86\x07\xbf\x1a\x98\x02\x9b\x52\x2a\x2c\x91\xb1\x6e\xca\xe3\xb2\x7b\x06\x29\x4d\x42\x3e\x04\x5a\x59\x81\x9c\xf9\x57\x24\x6d\x6f\x9b\x8b\x98\xaf\x73\xf9\x3a\x9a\xe2\x29\xa3\x16\x2b\x66\x0d\xeb\xac\xe6\xc9\xfe\xe1\x8b\x9f\xac\x29\x4b\xac\x90\xb2\x83\x3d\x7a\x6e\x50\xbb\x34\xfa\x21\x9c\xc4\x69\xd0\xab\xca\x83\x5e\x59\x27\x68\x7f\x98\x33\x6e\xc5\xe7\xf2\x15\x54\x63\x47\xbf\x71\x4b\x28\xe5\x6d\xd2\x8b\x8c\xa2\xf4\xf4\x3a\x66\x61\xb3\x94\x0b\xe6\xb5\x91\xbf\x41\xd6\x17\xbe\x4e\x17\x1e\xa8\xed\x58\xe9\xc1\x92\xab\xd5\xed\x1e\x74\xd6\xec\xc3\x60\xfc\xcb\xb9\xb1\xde\x77\x7b\x2b\x43\xe1\xbf\x26\x8a\x53\x44\xed\xb4\x91\xc3\xa0\xd1\x98\xc6\xc2\xea\xf9\x1f\xe5\x19\x9a\xb7\x70\x3e\xc8\x4d\xe3\x24\x41\xa5\x4e\xe7\x27\xb9\xd6\xd9\xcc\xd5\x89\x98\x61\x41\xd0\x92\x31\x3b\xbb\xca\x61\xff\x3b\x4d\xb4\x42\x4c\x98\x2f\xcf\x25\x76\x7e\x26\xbf\x0f\xff\xe9\x6e\x5c\x62\x08\x71\x6e\x2d\x8e\xf1\x37\xb4\x2e\x62\x69\x4a\x95\x37\x5a\xc2\xbc\x76\x81\xe1\x04\x3e\x45\x8b\xa7\xbb\x85\xfc\xf8\x51\x45\x36\xd5\x11\xc1\xb8\x74\xa1\xeb\xaf\x50\x0c\x18\x47\xa9\x4e\x63\xe8\x9d\xea\x3c\xb3\xc0\x6e\xf5\x23\xe6\xd0\xfc\xdd\xd2\x40\x31\x7a\xf7\x4d\x8d\x47\xf8\x79\x05\xc8\xa6\xfc\x54\x18\x83\xa5\x40\x2d\x6a\x66\xb7\x79\x7a\xfc\xea\x2f\xc6\xa4\xd6\x6a\xdb\x72\xe7\x9e\xab\xf2\xd7\xa4\xcf\x9c\x1a\x43\x78\xdc\x59\xad\xa2\x6c\xc1\x10\x8e\x37\xfe\x12\x15\x44\x06\xc3\x39\xe7\x8c\x6e\xad\x94\xbb\x64\x41\x85\x94\xa0\xc4\x29\x3e\x89\x5d\xf9\x72\xe7\xd7\x90\xee\xb8\xd5\xac\xd6\x60\xe4\x29\x1f\xd5\x09\x54\xc8\x28\x06\x36\x57\x00\xc7\x9b\x4e\x0e\x97\xa9\x30\x8a\x70\x6d\x3d\x22\xa6\xeb\x41\xfe\xc2\x4f\xb5\x29\x73\xff\x30\x55\x18\xa5\x84\x0e\x24\xe9\x06\xb6\x4a\x4c\x85\x69\xe8\x60\x22\x68\x21\x7a\x1c\x7c\xa7\x8e\x31\x21\xdf\xa7\xf0\x81\xda\x1d\x53\x24\x0c\x78\x67\x01\xee\xdb\xf5\xe3\xd9\xab\x48\x6c\xa5\xae\x96\xf0\x9a\x4d\xc8\x02\x6e\x04\x0b\x0c\xb1\x68\xf3\x5f\x68\x30\xfc\x99\xb9\xe6\xfc\xad\x67\x04\xb8\x83\xb1\x9c\x6a\xa8\xd0\xee\x67\xfc\x2c\x15\xa3\xb6\x13\xe9\x18\x95\xb2\xca\x24\x96\xa3\x86\x5e\xc0\xe3\x4f\xf0\xd8\xae\xd4\xf7\xe5\x6b\xd7\xfd\xa8\x9d\x12\xef\x47\x59\xab\x8a\x38\xc1\x55\x62\x79\x3a\xef\x47\xac\x8d\xf9\xc0\x4c\x45\xa9\x15\x28\x3a\x5a\x52\x70\xfb\xdc\xda\x2d\x72\x24\x79\xc0\x54\x1c\xa7\x08\xae\xdd\x42\x73\x3a\xfe\x1d\xe7\xe7\x13\xf5\xa1\xc9\x97\x8b\x80\xd9\xde\x80\x05\xae\xc1\xcf\x75\x6e\x25\xdd\xfc\x62\xac\x04\xe7\x58\x89\x32\xbd\x94\xe4\x18\x6b\xa9\x92\x40\x07\xda\x05\x83\x8b\x3c\x5f\x95\xe5\x8f\x0c\xfa\xa3\x3c\xc0\xe6\x8c\xdd\x2e\x76\x4f\xbb\xc5\xfd\x50\x27\x8b\xa9\x24\x56\x89\x15\xf8\x2a\xe4\x68\xca\x4b\x6d\xdd\x1a\xae\xcb\xaa\x9d\x14\x5d\x7a\xaf\x52\xce\xf1\x94\xed\x25\xd5\x5d\x1f\xbc\x4b\x70\x94\x4a\x92\xd0\x25\x01\x4b\x70\xb6\x24\xa3\x6a\xe9\xb0\x66\xaa\x94\x8e\x51\x91\xe1\x27\xc6\x2c\xb3\x62\x2d\xb8\x30\xf5\xc1\xa8\x52\x26\x88\x1c\xfc\xf5\x59\x56\x35\x5c\xf8\xe3\x4f\x64\xd9\x99\xd2\x5c\xe2\xae\x7c\xfb\x7d\xd7\x0c\x7f\xa3\xe6\xca\xa7\xa5\x4f\x45\x87\xf2\xde\x80\x9a\xbc\x42\xc0\x09\x32\xe4\xbe\x64\xb9\x2e\x0b\xf0\x56\x55\x4c\x41\x12\x58\xae\x49\x8d\x2e\xab\x0d\x62\x3b\xfb\x83\xd6\x68\xf0\x0c\xb2\xa2\xed\x2f\x9b\x3c\x39\x13\x19\xcc\x09\x3c\xec\xf0\xb1\xbc\xcf\x0e\xd9\x07\xb8\x4e\x65\x24\xc5\x46\x93\x3c\xa4\xb2\xae\xa5\x2e\x2b\x77\xba\x69\x92\xa8\x03\x66\x84\xa3\x38\x37\xe5\x73\x3f\xaf\xff\x19\x76\x5d\x07\x6e\xca\x28\x59\x69\x5b\xb9\xaf\x9f\x26\xe9\xb8\x0e\xb9\x55\x6c\x7a\xcf\xaa\x76\x63\xf2\x40\x5c\x1d\x46\x8a\xc6\x43\x5e\x90\x7d\xfc\xfe\x28\x58\x9c\xe6\xc3\xe2\xf1\x1f\xbc\x43\xee\x43\x24\x94\xc8\xb0\x3e\x15\x79\x36\x11\xca\x65\x9a\x3a\x5d\xc5\x3a\xfb\x2f\x0c\x84\xa5\x99\xa6\x34\x46\x00\xfe\x66\xbd\x78\x5e\x6f\xf6\x77\x8f\xbb\xcd\xfa\xf9\xee\x6a\x7f\xbd\xbb\xdf\x6f\x9f\xd7\xeb\xab\x6e\x20\xb3\xfc\xda\xe7\xf2\x27\x54\xa5\x59\x9e\xd2\x1e\xcf\xa0\x69\x42\xbd\xe5\x0f\xfe\x10\x32\xfd\xfa\x34\xc6\x02\xd2\xfd\x6e\x43\x87\x2f\x8f\x66\x24\x41\xfd\x94\xbb\xbb\xc7\xf5\xf8\x80\xb4\xd1\x8a\xc9\x8e\xb5\xe7\x77\xfb\x63\x3c\x50\xf8\xe2\xec\x9e\x9e\x97\xdd\xdf\xa8\xed\xd0\xd5\x50\x68\x1f\xa9\xce\x4f\x10\xcd\xb9\xb2\xde\xe7\x6f\x70\x90\xbf\x54\x1f\x0a\x69\x0e\xa1\xaf\x3f\x35\x83\x02\xed\xf4\xf3\x86\x60\xb7\x67\x59\xfe\xb2\xf4\x66\xf7\xf7\x28\x14\xca\xa1\xdd\x3b\x43\xd2\x89\xed\x0a\xd3\x51\x92\x60\x21\x1d\xe7\xd9\x67\xf8\x2b\x1d\x49\x19\x1a\x1f\xda\xd8\xd2\xf8\x35\xb4\x19\xb1\x2e\x7f\x5e\x97\xd5\x75\x59\x4d\x16\x5f\x1d\x47\x29\x56\x30\xa6\xe4\x6d\xfa\xc1\x0f\x11\x42\x61\x5e\x6e\xd1\xaa\xeb\xe6\xcd\xe9\x24\x7c\x82\x56\xd5\x22\x51\x48\x2c\x41\x13\xbf\xa3\xe7\x42\x5c\xa5\xfe\x1a\xda\x60\xd2\xc5\xe4\x37\xa7\x62\x79\xbe\x6b\x97\x9e\x26\x9c\xcc\x87\x44\x11\xe8\xca\x95\xbb\x72\x00\x9f\xd0\x92\x47\x23\x09\xfc\x07\x78\x2a\x9c\x0d\x4b\xf5\xcf\x98\xe4\x5a\x2a\x85\x64\xeb\xc3\x5e\xb6\xe9\xc3\x5b\x56\xbc\xee\x61\x28\xff\xc7\xb4\x34\x5c\xa9\x6e\xc2\x66\xda\x16\xa0\x5c\xb7\xe8\xae\x18\x97\xce\xdc\x67\x52\xe0\x28\xa9\x77\x03\xcd\xf6\x78\x9a\x24\x34\x5a\x85\x80\xbd\xdf\xde\x84\xaf\x42\x37\xb0\xf9\x5b\xaf\x8c\xc6\xf7\xff\xb1\x6c\xe4\x0f\x38\x3b\xc9\x96\xf6\xa1\xde\xad\x9e\x9e\xe7\x83\x18\xad\xe3\x14\x92\x91\x19\x0e\x23\xa3\xd0\x5f\x03\x03\x9c\x01\x5d\x3f\x66\xf2\x13\x40\x28\x8c\xe2\x51\x7c\xe0\x02\x6a\x3c\x2a\x56\xfa\x4f\x24\x80\x20\xc7\x36\x01\xb2\xe1\xef\xfc\x6c\x35\x4a\xa6\xaa\x2b\xb8\xd9\xfe\xc9\x10\x0a\x3c\xba\x4c\x63\x12\x2d\x5c\xf2\xb7\x3a\xab\xee\xe1\x43\x10\xc4\xd8\x5f\xbd\xba\xdb\xee\x36\x77\xcb\x17\xcb\x61\xf1\x9e\x32\xdd\x28\x26\x3c\x7e\xb4\xc9\x61\x09\xcd\x4b\xa1\x72\x78\x80\xea\x47\x0e\x08\x77\x1d\xed\x73\x2c\xf0\x1f\x4b\xa2\x20\xea\x3d\x01\x91\xbb\xd3\xbe\x3e\x6d\x8e\x34\xba\x4d\x10\x06\x4c\x5b\x11\x94\xdd\xb7\xa7\xcd\x97\x41\xf5\x0d\x48\x02\xd0\xab\xb5\xfb\x86\xcf\xf8\xe3\x8c\xd9\x1d\xc8\xb1\x90\x86\x20\xad\xa9\xa6\x1e\x03\x66\x28\xb6\xc0\xfe\xdf\xff\xdc\x0f\x17\x40\xe0\x9c\x06\xde\x2d\xf3\x56\xd6\x9b\xb2\xbf\x4b\x3c\xa6\x28\xdd\xbc\xac\x64\xa1\x3d\x1f\x62\xfa\x66\x0c\x9a\x63\xfe\x63\x09\x41\xa0\xf6\xc3\x1f\xeb\xee\x4c\x69\x48\x48\x4f\x7c\xb7\xed\xd1\x29\x94\xb8\x1d\x85\xd9\x2b\x5a\xcf\xcc\x56\xf8\x21\x0a\xac\x94\xd9\xb0\xc5\x38\x9d\x56\x7f\x57\x22\x1d\x1e\xff\x80\x30\x05\x31\x4b\x50\xf7\xc9\x5e\xf0\x25\x48\x1f\x62\x66\xb0\xd5\x5d\x9d\x72\xa8\x2f\x0a\x5b\xff\xc7\x7f\xdd\xb9\x05\xb1\x96\x58\x5b\x99\x21\x7b\xa6\x6e\xf6\x37\x32\xf3\x55\x2e\x48\xb8\x40\x25\xf5\x7d\x8f\x23\xb3\xf5\xcb\x45\xa1\xef\x65\xa1\xdf\xb0\xdc\xf7\x3f\x52\xfd\x38\x96\x1f\x48\x4a\x41\xe2\x34\xaa\x16\x77\xdf\xd6\xcb\xd1\x7c\x48\xc0\xba\x9b\xdf\x40\xb3\x83\xc3\x71\xdb\x9c\x8c\xb9\xb0\x09\x60\x20\x13\x46\x87\xd2\x5c\x77\xab\xa7\x4f\xf2\x4d\x90\x8a\xe0\x74\x5e\x42\x75\xfa\x6b\x18\xf2\x81\xd4\xb6\x35\x72\x2a\x50\x89\xe2\xb9\xca\x0e\x65\xa5\x33\x57\xff\x19\xa5\x3c\xf3\x3f\x25\x8d\x15\x02\xfb\x7c\xd4\xd6\xee\x78\x0e\x4d\xe5\xb8\x4b\x3e\x08\x81\x34\xa1\x58\x13\x80\xe6\xed\x5f\x27\x89\x8e\x94\xfd\xa1\x34\xb2\x5a\x15\xae\x9c\x35\x76\x59\xf5\xa3\x80\x5a\x55\xe9\xfa\x82\x04\x06\x4a\x44\x08\x80\xb2\x81\xf3\x75\x59\x75\xd6\xf0\xed\xb1\x04\xb7\xec\x5b\x32\x12\x69\x01\x65\xac\x43\xbb\xe3\xd9\x64\xc5\xab\xc3\xa5\x8c\x7f\x22\x48\x8d\x32\x30\xdb\x6b\x2b\x6a\xba\xde\xdd\xee\xb7\xeb\xd5\xd3\xe3\xd5\x7e\xbd\xd8\xdc\xff\xb1\x5f\xde\x6d\xae\xf6\x9b\x45\xc7\x9f\x06\xd0\x9a\x45\x2e\x27\x40\x51\xda\xe1\x06\x0e\x26\x0c\xb0\x6c\xb6\x7a\xcb\x0a\x79\x9f\x19\x18\x79\xe0\x7f\x88\x80\x33\x01\x0d\x71\xcf\xb4\xdf\xbd\xc5\x6b\xb9\x5a\xf8\xf5\xd2\x04\xdc\x7a\x62\x61\xff\xdc\x7a\x73\x74\x87\xe2\x08\x6b\x58\xd6\xf3\xee\xaf\x29\x6a\xcb\x04\x71\x82\x08\xb1\xe6\x97\xb3\x95\xf1\x1f\x0c\x49\x82\x0d\x35\x0d\xef\xcf\x32\xd3\xdd\x9f\x75\x84\x09\xc0\x0f\x50\x4a\x5e\xd4\xed\xc6\x33\xc4\x10\x61\xdd\x5f\xf6\x35\x34\xa1\x57\xdf\x31\x2c\x96\xb8\x7b\x17\xf0\xab\xb9\xaa\xe4\xcf\xc1\x0d\x32\x3c\x4c\xb4\x0b\xb1\xee\x65\xdd\xfc\x4d\xf3\xc9\xf0\x28\xc1\x6a\xd9\xba\xca\x06\x15\x2f\x13\x85\x11\x23\x1d\x42\xb9\xde\x80\x06\x38\x74\xb1\x81\x89\xa3\x00\x3b\x9a\x3e\xcd\x71\x33\x60\x12\x0e\x98\x58\xb0\xd0\x62\x93\xaa\x1f\xd0\xec\xaf\x2c\x03\x7d\x39\x51\xc2\xc4\x71\xf8\x46\x5e\x5f\xfd\x83\x27\x19\x27\xd6\x3c\xfa\x6a\x7d\xbd\x79\xda\xee\xf6\x77\x8f\x77\xbb\xbb\xc5\xfd\x04\xba\x69\x84\x13\x96\xf8\xcc\xb3\xda\x09\x77\xf4\x17\x22\x4c\x2c\xad\xf4\x7a\x9b\x46\xd7\x60\x77\x8e\x07\x68\xa4\x96\x8d\xf4\xcf\x77\xfc\x99\x24\x4c\xb9\xdb\x33\xbf\xef\xbe\x3a\x35\xa6\x4f\x91\xd4\x46\x06\xb6\x50\xf3\x90\xe5\x43\x77\x30\x66\x24\x13\x71\xe7\x3b\x52\x9f\xf2\xc6\xa9\x8f\x8d\xbf\x51\x26\xc2\x70\x8f\x49\x7c\xcf\x1a\x58\x95\x1a\xe3\x89\x51\x08\x61\x52\x2a\x90\xb0\x95\x15\x23\x2b\x96\xf1\xa5\xa4\xa9\xb2\xea\x0a\x83\x7d\x62\x36\x64\x34\x8a\xc4\x88\xba\xfb\x65\xac\x2f\x9a\xbf\x66\xa5\x93\x30\xf1\x81\xea\x43\xed\xb5\x11\x8c\x0e\x2c\x47\xf1\xe7\x9b\x6c\xb6\xb2\x29\xeb\xb7\x6c\x2b\xcf\x75\x77\x38\x0a\xe3\xa8\xa3\x90\x8f\x6b\xe5\x6e\x08\x44\x1a\x73\x8d\x42\x1e\x60\x25\x5d\x85\x8d\x8f\xb7\x3b\x03\x09\xc1\x68\x7b\xd1\xc6\x73\xef\xce\xc3\xc3\x01\x2c\x27\x23\x8d\x24\x4e\x9c\x58\xaf\x0b\x7d\x2c\xb3\x62\xc0\x56\x9f\x0b\xd9\x8c\x21\xd4\x6e\x95\xb6\x05\xf8\x60\xfd\x8f\xfd\x4f\x30\x49\x90\x4a\x34\x35\xed\x71\xdd\x9f\xaf\xf8\xc6\x68\xab\xe2\xf8\x6d\x7d\xe7\x97\x43\x7b\x36\x1e\x84\x44\x51\xf7\x54\x97\x9d\x0b\xd1\x5d\x81\x8c\x85\xcf\x4e\xca\x83\x90\xd9\x1d\xaa\xb1\x35\xdd\x5e\x39\x80\x07\xa1\x89\x99\x65\x9e\xff\xea\x29\x1f\x3c\x20\x84\x6b\x27\xbf\x7f\xc4\x20\x6d\xda\xdb\xe0\x01\x61\xc1\xc0\x85\xc5\x11\xe1\xf4\xe2\x15\xed\xd4\xdd\x18\x1a\x24\x89\x27\x65\xda\x30\xaf\xcd\x74\x46\x93\x9d\x07\x54\x1a\x8c\x29\x77\x50\x37\xc9\xff\x74\x1f\x55\xda\x0b\xb3\xdf\x97\xaf\x96\xe2\xa1\x75\x35\x3c\x8c\x93\xea\x2d\x2b\x7e\x0c\x3b\xfc\x3c\xa0\x10\x5a\x65\xcd\xae\x0f\x54\x4f\x2e\x9d\xb1\x08\x29\x4f\x6f\xe5\xcf\x07\x59\xb8\xaa\xf8\xa2\x02\xa7\x91\xa7\xaf\xcb\xf9\x8e\x22\x0f\x98\x20\xf8\x44\xd1\x9d\xa2\x1e\x49\x74\xb7\x07\xad\x4e\x04\x1a\x83\x5b\x39\xb1\xc9\x4f\x65\x52\xe2\x6a\xed\x4c\xda\x11\xa2\x04\x1a\x19\x35\x93\x4b\xe4\x44\x58\xc8\x31\x92\x29\x9f\xab\x52\x9f\x94\x83\xea\xce\x41\xf8\x79\xc0\x23\x11\x0e\xfc\xa7\x9c\x63\x9b\x7b\xd8\xe3\xab\x88\x62\x82\x2f\xe4\xc3\xe2\xfb\xfe\x65\xd5\x46\xe6\x23\x3d\x7b\x1e\xc4\xa1\x62\x03\x6c\x6d\xef\xb4\xc5\x83\x98\x5a\xef\x89\x81\x9b\xe3\xf2\xbc\x81\xd7\x53\x2e\x7b\x97\x97\xdf\xff\xa1\xbf\x23\x0f\xe2\x94\x60\x07\xed\xe9\xeb\xd3\x60\x9d\x6b\xff\x2e\xa9\xad\x54\x1f\xb2\x6e\x52\x0a\x4e\x90\x13\x8c\x51\x63\x56\x60\x7f\x0b\xc5\xeb\xda\x5d\x66\x81\xbd\x90\xba\x1b\x6b\x42\xe6\x9a\x3c\x4f\x47\x07\x58\x6c\xe7\x3e\x3e\xe0\xb9\x45\x97\x07\x49\x00\x69\xcf\x08\xbc\x2a\x0f\xf2\x92\x13\x3b\x5b\x67\xe0\x81\x8c\x04\x36\xc9\x6f\x70\x2f\x01\x99\xe3\x4e\x32\x5a\x5e\x78\x20\x93\x48\xaa\x9e\x57\xd6\x33\x0f\x2e\xb6\xf8\x39\xbb\x36\x1e\x28\x16\x63\x89\xda\x96\x57\xdd\xe2\xb0\xde\xf8\x5f\xac\xe2\x18\xe3\x30\x17\xe3\x61\xb7\xad\xb2\xfa\x4a\xf3\x2a\x31\x3c\x50\x12\xd0\xf3\xd8\x26\xf6\x4b\x4b\x21\xda\x97\x45\x7e\xde\x5f\xc1\x7b\x77\x62\x15\x61\x79\x6b\xdf\x81\xef\x3e\x8d\x49\x78\xa0\x35\xef\xe4\x02\xdd\x36\x87\xb5\x97\xac\x2c\x76\xbf\x9e\xaa\xec\x35\xeb\x9e\x33\x84\xc6\xf6\x14\x3e\xcd\xa3\x43\xb7\xe2\xf3\xa0\xcd\x0b\xdb\x2b\x7e\x2f\x1b\x40\x89\xc2\x89\x68\x20\x0f\x20\xb6\xa0\x8a\x3e\x81\x98\x64\x0b\x7e\x1c\x10\x44\x9c\xd9\xa7\x7d\xa7\xca\x75\xa1\xed\x53\x1b\x8f\x33\x81\xb4\x35\xe3\x21\xa7\xd6\xc1\x41\x78\x60\x88\x05\x85\xad\x86\x29\x7b\x76\x98\xf7\x65\xe5\x81\x89\x35\xbe\xff\x6f\xb2\x7e\x5b\x66\xe5\x01\x9a\x2a\x53\x6d\x2a\x92\xcb\x06\x6a\xff\xf6\x8c\x23\x9c\xc1\x1e\xcb\x03\xa3\x43\x1d\x7a\xe0\x4a\xfb\x45\x4e\xf1\xc2\x1e\x0e\x03\x99\x60\x76\xe5\x5d\x0c\x51\x8a\xe8\xd4\x4b\x8f\xf9\x0b\x09\x03\xe5\x14\xad\x0b\x55\xb6\x41\xf4\x5e\x43\x47\x82\xf3\x27\x0b\x59\xaa\xdc\xab\xfe\xfc\x56\xc9\x7a\x14\x3d\xf0\x30\x14\x04\xc3\xac\x7b\xf9\xeb\xbf\xdd\x47\xc0\x38\x0f\xb3\x8e\x83\x8c\x8b\xf6\x68\xda\x85\x24\x88\x11\xe6\xab\x4b\x67\x9d\x3d\x3d\x1e\x2a\xdc\x87\xaf\xdb\xa5\x29\x64\x4c\x7c\xa2\xf6\x3a\xbe\xc1\x21\x0d\xad\x26\x68\x8a\xfb\xbb\x45\x1c\xfa\x43\x20\x71\x43\xb9\x2d\xf3\x73\x1f\xc9\xf2\x90\x51\x40\xee\x53\x1b\xbe\x8f\xdb\x78\x3c\xe4\xa1\x15\xdf\x90\xda\xf6\xad\xab\x73\x1b\x49\x8d\x67\x48\xc8\xb9\x05\x11\x37\x7d\xa9\xc6\x78\x16\x3e\x0f\x79\xca\x85\xd5\xc5\x70\x4c\xe3\x41\x3a\xd2\x0d\xb1\xe0\x47\xa7\xba\xb8\x29\x9b\xf2\x82\xe4\x39\xfe\x44\x14\x48\xe7\x60\x75\xde\x57\xe5\x59\xe6\x4d\xd7\x86\xe1\x61\x44\x19\x02\x57\x1c\x15\xf0\x34\x03\x71\x99\x8f\x13\xc2\x48\x58\x50\xc6\xbe\x5d\xfa\x9a\xbd\xc7\xbf\xd9\x4e\xc1\x78\x68\x4c\xa4\x18\x80\x32\xbb\x2f\x8f\x53\x8e\xac\x2e\xff\xba\xec\xe4\x2f\xaf\x22\xe9\x47\x80\xb4\xb2\x3a\x5e\x26\x7e\x18\x5b\x7c\x58\xe8\xf8\xa8\x35\x38\x9e\x39\x82\xd0\xde\xb0\x04\x9c\x32\x72\x7b\xc7\x07\x34\xa6\xf1\xef\x10\xc4\x06\xf4\xce\x54\xf9\x33\xa8\x24\x0f\x85\xb4\x32\x03\x5f\x6f\xbe\x8d\xd6\x41\x7f\xb8\x0d\xbc\x3b\x00\xe9\x18\xa2\xd0\x66\x5d\x1a\xdf\x97\xf6\xd5\x9d\x36\x39\x78\x28\x03\x0b\x9c\x96\x5a\x7b\xb1\xaa\x39\x18\x04\x0f\x25\xd1\x36\x5a\x6a\xbf\x64\xcf\xfc\xd9\x65\x12\xa2\x1e\xa5\x23\x3e\xd5\xa5\x99\x5c\x9c\x62\x3a\x0e\x46\x4e\x28\x57\x0e\x94\x32\x5f\x5f\xe5\xa1\x02\x61\xd2\xae\x1d\x80\x5a\x4a\xed\x6c\x58\x5d\x3d\x7e\xf0\x01\x9d\x00\xbe\xfd\xdf\x16\xf7\xf7\xeb\xdd\xfe\xfa\xe9\xe5\xf1\xaa\xdb\x9f\x42\x08\x03\x64\x08\xb6\x21\x65\x7b\xa7\x0b\x3d\x79\xfb\x3f\x98\x94\xa0\x00\x97\xaa\xeb\x97\xdd\xcb\x66\xbd\xbf\x5a\x7f\x5d\xdf\x3f\x3d\x3f\xac\x1f\x77\xfb\xe7\xa7\xa7\xfb\xee\xf4\xce\x09\xc4\xe2\x6b\x27\x77\xd7\x74\xeb\x52\x9e\xbf\x14\xd9\x7c\xe5\x88\x93\x80\x92\x60\x58\x37\x5f\x39\x87\xcd\xf1\xad\x24\x41\x1c\xc5\x66\xd8\x49\x1d\x2d\x8c\x24\x48\x2d\xf8\xf9\x55\xd6\x7b\x94\xc9\xdc\x1f\xbc\x70\x21\x27\xa1\x90\x9c\xf5\x75\xcd\x0d\x48\xe7\x88\xd4\xd1\x8a\x38\x09\x13\x40\x8b\xe0\xbf\xd3\xb1\xe8\x0b\x93\x9c\x90\x04\xb0\x70\xd6\x3e\x21\xab\x3c\x39\xfe\x69\x44\x1a\x63\x59\x7b\x6d\xae\xd7\xcd\xcd\xd1\xdc\x22\x94\x24\x8e\x17\xdd\xc8\xac\x00\x3d\x7e\x73\x09\x95\x16\x4e\x77\xbb\xd8\xdc\xed\xd6\x7d\x45\x97\x13\x16\x2b\x65\x7d\xd0\xbd\x40\xd7\x4c\xe9\x9c\x13\x1e\x00\x52\x07\xf3\x76\x41\xb9\x6a\x77\xa8\xaa\xfc\xa9\xbf\x01\xfc\x08\xfd\x99\x38\xb7\x99\xef\x7e\xfd\x78\xb5\xbf\xea\xaa\x3e\x9c\xf0\x38\x08\xa9\x95\xc8\xc0\x30\x64\x48\x8a\xc6\x1a\xde\x27\xec\x05\xe1\xce\x11\x99\xc4\x43\x46\x1f\xdc\x2a\x1c\x7a\xf0\x17\x27\x31\x0d\xa9\x23\x14\xc3\x5c\x28\x40\x44\x44\x30\xc4\xf6\xe6\x35\x76\x81\xf5\x17\x28\x84\x46\x89\xc6\x76\x2f\x37\x65\x75\x18\x8a\xc0\x71\x22\x64\x84\x32\x4b\x99\x2a\xb1\x6f\xcb\x06\x44\x6e\x4e\x12\x11\x53\x37\x2b\xb6\xbd\xf9\x3f\x27\x49\x1a\xe2\x52\x7e\xb2\x3e\x15\xb7\xb2\x5e\xc2\xeb\xc9\x6f\x5d\x44\x52\x6d\x86\x5a\x43\x77\xe6\x56\x56\x6d\xf6\x32\xad\xee\x71\x92\x06\x61\xa4\xad\x1e\x33\x34\xf0\xec\xa8\xfa\xfe\xa0\x54\xde\x65\x72\xfd\x0b\xd4\x80\x58\xcb\x49\x0a\xd6\xb1\xe2\x21\x1b\xf8\x80\x4d\xde\x9b\xd4\x44\x46\x38\x30\xcc\x1e\xf9\x2f\xfe\xd3\x8a\x47\x44\x38\x42\xd4\x76\x80\x60\x9b\x9c\x40\x89\x38\xee\x70\x77\x50\x48\xb4\xb4\x1d\xff\x00\x4d\x52\xcf\xfc\xf4\x62\xbc\x93\xc7\xa3\x29\x4b\x94\xd5\xd4\x6d\xde\x56\xf8\x0e\xb8\xab\x1d\x0f\x93\x82\xdb\xa0\x57\x8f\x40\x62\xfe\xb0\x0e\xb4\x1a\xa8\xf7\x7a\xbe\x5e\x77\xd8\x3a\xcf\xad\x77\xb7\xcb\x53\xd3\xf4\x9f\x03\x23\x11\xf4\xbb\xbb\x5b\x6f\xf8\xa0\x5e\xc9\x89\xa1\x4a\xd8\xb7\x2a\xcf\x8a\xbf\x4e\x59\xfd\xd6\x69\x24\x8e\x9a\xf4\x9c\x18\x29\xd1\x21\xa7\x06\x57\xa2\xbd\xa9\xca\xd3\xd1\xa9\x18\x0d\x5e\x76\xa3\x62\xeb\xcc\x6d\xf3\x57\x8b\xa1\xde\x95\x76\x3e\x6e\xcf\x87\xb4\xcc\x31\xcf\xb6\xc3\x69\x90\x72\x94\xba\xf0\xe0\xd3\xfb\x76\x09\xdd\xd3\xee\xb0\x4e\x12\xa7\x62\x7a\x5d\x56\xaf\xd9\x3b\xe8\xd5\x9b\x1c\x39\x76\x72\x1a\x18\xf0\xa6\x29\x7e\xf1\x78\x80\xba\x1e\x1a\xf2\xbb\x91\x61\x68\x25\x47\xeb\x06\x64\xbe\x7b\x83\x7b\x80\x1f\xfe\xab\x42\x08\x1c\x41\x18\xab\x05\x5e\x88\x7e\x7c\x1b\x28\x09\x6d\xa1\xa3\xeb\x00\xbf\x42\x31\x54\x26\x1b\xdc\x8a\x76\x2c\x93\xbd\x82\xf1\xe4\x5a\x08\x01\xd6\xf3\x61\xa7\x07\x53\x86\x5b\xff\x71\x46\x00\x9f\x53\x02\xd2\x06\x06\xd9\x6b\x01\xfa\x23\xe6\xe3\xe7\x64\x85\x71\xf8\x40\x09\x18\x2b\x7c\xa5\xd4\x06\x54\xc7\xff\xe0\x94\xf2\xd8\xf6\x25\xb6\x57\xc3\x2c\x98\x52\xc1\xd0\xa5\xc5\x66\x7c\x48\x2d\x1d\xce\x2c\xca\x64\x1c\x76\x52\xc3\xeb\x5f\x47\x18\xf8\x35\x8f\x71\xa5\x56\x4c\x7f\xfc\x0b\x39\x07\xbb\xe8\x64\xfd\x93\xd8\x20\x1d\xeb\xa2\x1f\xc7\x29\x8f\xe2\x44\xa2\xd5\xde\x49\x7d\xc0\x51\xe7\x94\x27\x04\xcb\xce\xd9\xe1\x58\x56\x8e\x4a\x7d\x5d\x5e\x34\xef\x26\x1f\x52\x09\xf6\x2b\x8f\x55\x66\x39\xed\x5e\x2b\x8b\xd3\x28\xb6\x74\x2c\xab\x9f\x8f\x7d\xa0\x79\x6d\x1d\x4e\x05\x25\xb8\xc3\xef\xbc\x2e\x0c\xa7\x22\xb2\x0c\x49\x0c\x5a\xc6\xc1\x18\x15\x49\x02\xd6\xd5\x76\xf0\x18\x92\x50\x24\x6a\xe0\x6d\xdd\xbd\x21\x09\x97\x88\xa8\xf5\x0b\xbf\xdd\x1c\xdc\x41\x69\x08\x3e\xbc\xed\x11\xaa\xc3\xe8\xf1\xa5\x81\xc6\x82\xa8\x8d\x13\xae\x65\xfd\x36\x4c\xf6\xdd\xee\x93\xfc\xe9\x47\x0b\x85\xe7\xc1\xb7\xb9\x90\xa7\xa6\xb6\x1c\xb5\xc9\x83\x50\x51\x88\x17\x09\x87\xac\x83\x48\x60\x53\xf9\x22\x68\xbd\xd0\xb9\xe4\x54\x49\x82\xe9\xf6\x73\xf6\x7d\xeb\xaf\x52\xa5\x0c\xa1\x1c\x06\x1a\xf5\xf6\xb5\x6c\xe0\xf1\x74\x40\x43\x9b\x42\x23\x7c\x78\xbc\x0e\x53\x95\xca\xc4\x0a\xb3\x79\x7a\xd1\xfd\x10\x80\x37\x4a\x57\xa9\x8e\x23\xa6\x1c\x9e\xa6\x6e\xb6\xa7\x14\x97\xa5\xb9\xb6\x24\xa7\x3a\xa1\xc0\xfa\xd8\xdd\xed\xa2\x93\x6f\xd7\xa0\x91\x2c\x67\x64\x96\x4f\xc1\x48\x9c\x82\x10\x58\x4d\x72\xdb\xe5\x5c\x83\xcd\x8f\x94\x61\x8a\xcc\x80\x5e\xa6\x2f\xbb\x54\x80\x98\xaf\x6f\x50\xd0\xa1\xad\xf3\x41\x96\xf7\xe1\x11\x35\x34\xa4\x0e\xa9\xde\x06\xa6\x16\x58\x4c\xa2\xf1\x3a\x6a\x58\x18\x49\x17\x54\x87\xe3\xcb\x67\x41\x08\xb6\x40\x94\xd5\x6d\x4e\x34\x99\xb3\x2c\x48\x83\xc4\x6a\x0d\x9b\x1c\xb3\xfb\x3e\x64\x64\x24\x04\x7c\x2a\xe9\xe9\x7c\xa7\xca\xa1\x89\x01\x67\x84\x11\x8c\x8c\xad\x0f\xcf\xc7\x9d\x4c\xce\x48\x04\xaa\x4b\x60\xae\x4f\xb9\xc9\xf2\xbc\x4d\x45\x26\xde\x40\xff\x26\x7f\x4e\xd7\xbb\x7f\x8b\x3f\xc7\x3d\xe7\x7f\x93\x3f\xfd\x49\x45\xe4\xf9\x8d\x2b\x99\xe7\xa8\xcb\x37\x7a\xf2\x8c\x88\x04\xdb\xf4\xed\x0d\xbb\x6b\x46\xa0\x99\x88\x0d\x0c\x77\x3f\xf4\x02\xe1\x8c\x12\xf0\x86\x85\x4e\x25\xf2\x1a\x3e\xd4\xa0\xf4\x9f\x11\xd6\x6e\xb4\xfd\x95\x37\xb2\xbb\x5d\x54\x1a\x7c\xc1\x24\x2e\x5f\xb4\xfb\x33\x74\xf0\xac\x0b\x6c\xd4\xf8\x31\x32\xa9\x10\x74\xb4\xda\x2e\xfe\xce\xa6\x86\x33\x1e\xa5\xdd\x45\x20\x59\x1a\xf4\x32\xd3\x17\x1a\xb9\x93\x4b\xe7\xb1\x2d\x2a\x6c\xa0\x99\x71\xe3\x9e\x0e\x56\x8c\x25\xbd\x97\x18\x02\x0b\x56\xb6\xae\x8f\x92\x47\x3e\x18\xec\x14\x1e\xba\xdd\x95\x71\x93\xc8\xd0\x0b\x98\xd4\xf5\x2e\x53\x3f\xa0\x59\x9e\xce\xed\xac\xff\x04\x78\xc5\x59\xe4\x54\x50\xbb\xfa\x9f\xcc\xe7\xa1\x64\x9c\x45\xc4\x4a\xa8\x58\xd8\xc3\xae\x3c\xbe\x1c\x67\x0a\x0e\x2c\x4e\x14\xee\x56\x45\xc7\x56\xf2\x07\x94\xb5\x6a\xc0\x16\xfb\x8c\xf2\x29\x67\x22\x08\x99\xee\x6d\xe7\x9f\x8a\xfc\xfc\x54\xac\xde\x64\x56\x58\xf1\x45\x3f\xcc\x44\x48\xa2\x6d\x33\x8f\x21\x29\x87\x33\x49\x19\xee\x6b\x7e\xb1\xf8\x9a\x95\x39\x26\xce\xa3\x47\x29\xe3\x18\x53\x2c\xa3\x54\xf7\x41\x9d\x60\x79\xf0\xa1\x7c\x87\xeb\xac\x7e\x9b\x8f\x9f\x99\x0a\x63\xee\xe2\xef\x9d\x17\xce\xe6\x4c\xd1\xc0\x12\xbb\x4f\x87\x27\xe3\x8d\x83\x27\x4b\x86\xa2\x09\x62\x23\x53\x28\x40\x65\xa6\x77\x9d\xe6\x4c\x45\xb1\xd4\x3d\x53\x4a\x97\x33\x25\x0b\xa6\xe3\x10\xe2\x91\xee\xc4\xf2\x74\xee\xa1\xcc\xdd\x2b\xaa\x53\x81\x5d\xf5\x57\x79\x80\xf5\xaf\xac\x6e\xea\xc9\x3b\xac\x41\x3a\x82\x76\xb3\x94\xea\x07\x14\xfa\x92\x17\xcc\x19\x84\x31\x0a\xb2\x5d\x65\x0a\x36\x65\x9e\xff\xd6\xfd\x1d\xb0\x36\xe2\x8a\xfa\xb2\x81\xb5\xac\xf2\xb3\x17\xd5\x9f\x3c\x4f\x30\xca\xd6\x59\xde\xaa\xf2\xe7\x53\x71\x23\x6b\x5b\x05\xed\xed\x9a\x38\x33\x3c\xc6\xa0\x16\x1b\x35\x5b\x8b\xe5\xc3\xcd\x67\xf4\xc8\x4c\x92\x62\x5f\xd9\x5a\x2a\xa3\x62\x15\xce\xd8\xb2\x3f\x8f\xa6\x5e\xe9\x18\x7f\x50\xbb\xa7\x38\xf1\xf5\x0b\xff\x97\xf1\x3b\xc0\x03\x96\xfa\x06\xf3\xa2\x4d\x86\x57\xe5\xb4\x58\xcd\x09\x33\xc6\x6b\x58\x2d\x3b\x34\x2f\xe7\x24\x02\x8f\xce\x72\x7d\xb3\x29\x6f\xee\x32\x14\xe6\x34\x60\xcc\x35\xf6\x5f\x6a\x40\x22\x3d\x54\x33\x5d\x86\xe1\x1d\xe0\x8c\x06\x71\x47\xfe\x78\x95\x45\x56\xcb\x0b\x52\x0a\xe7\x8c\x27\x6e\x09\x39\x15\xcd\x43\xbb\xf7\xfe\xd6\x1d\x51\x29\xe9\x57\x88\x87\xb3\x63\x32\xda\xb2\xa3\x1f\x94\x30\x84\xb1\x64\x35\x3e\xd6\x65\x36\x6d\x49\x71\x66\xec\x8d\xa8\xad\xbb\x55\xa7\x62\xca\x39\x8f\x00\x53\x06\xec\x5d\x3e\xc8\x5f\xb8\xfa\x74\x07\x53\x83\x6c\x4c\x5f\x5c\x5d\x14\xda\xd7\x9d\x2f\x9d\x2e\x38\x8f\x94\x8d\xfa\xb6\x59\x0e\x45\xf3\x58\x36\xb2\x1a\x6a\x7b\xb5\xdf\x15\xc4\xae\x3e\xdf\x4b\xb5\x73\x1e\x07\xe0\x94\x80\xcb\x1a\x96\x30\xed\x27\xf2\x38\x25\x12\xb0\xc5\x3c\x50\x2b\xf6\x1f\x16\xda\x6a\x8b\x7b\x29\xdd\x4e\x07\xb0\x3b\x9e\x20\xe1\xc7\x62\x6b\xf6\x0f\x59\x91\xed\xc7\x09\x11\x4f\xa8\xed\x86\x99\xec\xd7\x30\x37\xe7\x32\x0c\xb5\xed\x4d\x60\x68\xdc\x71\xa0\x39\x97\x24\x31\x6e\x3f\xdc\x1f\xb2\x62\xf5\x6d\x55\x3f\x5b\x8f\xb8\x87\xb2\x82\xdd\x9b\x9c\xde\x1a\x29\x34\x75\xfc\xb9\xa5\x6c\x9a\x1c\x35\xa0\xb6\xd9\x7f\xbb\xef\x4a\x79\x1a\xbb\x29\xf9\x78\x3a\xbc\x14\x59\xf3\x41\x35\x80\xa7\x89\x46\x1d\x81\x7d\xfb\xce\x5c\xa0\xd8\x7c\xeb\x84\xa7\xda\x1a\xb4\xf9\x16\xf3\xc8\xe6\xc8\x8d\x51\x01\x09\x86\xd5\xe4\x85\xc5\xf7\x4d\x5b\x77\x5c\xd1\x00\x35\x99\xc7\x36\xaf\x03\x90\x36\xe7\x4a\x31\x2b\xf1\x9e\x15\x16\xf3\xe2\x0f\x68\x46\xf5\xc8\xc5\xd2\xe6\x2d\x9d\xe5\xe6\xf8\xc7\xe9\x38\xb2\xfc\x53\x12\xbb\x0d\xd3\x1f\x10\x81\xf4\x20\xcf\x2b\x59\x65\x6e\xb9\x9d\x44\x20\xb3\x37\x4c\x27\xc2\xdb\x26\x22\xeb\xca\xd7\x37\xb0\x0a\xe2\xc7\xa4\x71\xe4\xd6\x21\xcf\x15\xfe\x2c\x42\xe0\x5a\x05\xc8\xeb\xbb\x5e\x3c\x2e\x17\xdb\xf5\x68\x96\x03\xb5\xb5\x42\xe7\x09\x9b\xe7\xa5\xc2\xdd\xcc\x1d\x36\x01\x43\xbd\x85\xa3\x35\x82\xb8\xba\xe8\x0c\x71\x13\x12\x84\x10\xe1\x3b\x69\x9f\xc8\xb6\xcc\xf5\x5d\xb1\x7b\xb3\xa1\x6b\x37\x30\x49\x10\x51\xbe\xb0\x8e\x65\x07\x99\xe7\xb3\xe2\x02\x9c\x1b\x29\x7c\x94\xb8\xf0\x91\x50\x3d\x6f\x15\xc0\xb9\xd1\x84\x3b\x21\x99\xc6\xb1\xe8\xd0\xc2\xf5\xb7\x31\xfc\x71\x50\xfa\x8b\x02\x41\x22\xb7\xce\xed\xdf\xa4\xdb\x89\xc5\x38\x05\x89\x02\x29\xb0\xdc\xb6\xd7\xf0\x3e\x8a\xa1\xa3\x40\xd9\x4c\xd4\x39\xbc\x67\xf8\x04\x3c\xde\x64\xf6\x35\x88\xc2\xc4\x7e\xa4\x1e\x08\xdd\x4e\x60\xa1\x3c\x22\xa9\x65\xb7\xba\xe5\x73\xfe\x61\x46\x34\x0c\x69\xea\x2d\x34\xaa\xf2\x50\x62\x8e\xb8\xac\xca\xdf\x86\xcd\xf4\x88\x2a\x81\x81\xe7\xb7\xb2\xca\xf5\x12\x86\xac\x32\x1e\xb1\x00\xcc\x68\x9a\xe3\x54\x7b\xc8\x0a\x78\x96\xf3\x04\x75\x1e\x31\x0a\xa1\xf1\x31\x6f\x57\xcf\xf5\x40\x76\x1e\xf1\xc4\x9a\x60\xbd\xc9\xfa\x59\x9e\xab\x32\xff\x20\x24\x8e\xb8\x24\xe9\xb0\x50\x39\xd1\x24\xfd\x9b\x62\x8a\x3f\x89\xb6\x96\x84\xaa\xcc\x0a\x23\xd3\x2a\x1b\x73\x5c\x78\xc4\xc1\x44\x91\x7f\x8f\xb4\x3c\x3b\xa1\xf4\xa1\x1c\x16\x8f\xa2\xd0\x60\x4a\xda\xde\x07\x1b\x48\xde\xad\x9e\xb0\x24\xfb\xa1\x56\x3f\x8f\xda\xe7\x04\xb6\xa5\x96\x15\xdb\xec\xb5\xbb\xab\x51\x42\x70\xfb\xfc\xfe\xfd\xfb\xe8\x6e\xc7\x82\x21\x95\x6a\xf1\xb0\x5d\x8e\x0e\x08\xca\xa9\x45\x59\x7e\xc9\xf2\x7c\xa2\x14\xe3\xef\xab\x90\x96\x28\x8a\x40\x92\x36\x6a\x69\xe4\xeb\x38\x6f\x1b\xcf\x5b\xa1\x39\x2e\x0e\x48\x83\xf9\xbb\x66\xa9\x98\x3c\x9b\x44\x70\x84\x30\x59\x28\xdb\xcb\xf6\x6a\xbd\xbb\xc5\x5d\x66\x61\xa6\x58\x36\x1e\x25\x29\x8d\x92\xae\xc1\xfc\x52\x28\x0b\x33\xe9\x2a\xb2\xfd\x30\x1d\x0f\x9b\x4d\xe5\xc8\xfd\x96\x47\x92\x08\x01\x03\xb5\xf6\x7e\x11\xf9\x6d\x78\x23\x24\x0f\x11\x05\xee\x10\x1f\x35\x54\xcd\xde\x64\x85\x7e\x2c\x6f\xb3\xc2\x71\x27\x76\x7d\xd4\x17\xc9\x34\xb5\x91\x61\x76\x80\x6d\x9e\x29\x98\x7c\xab\x61\x78\x3a\xbf\x9d\xcc\xd9\x05\xb4\xa3\x94\x5d\xc9\x65\x95\xf9\x4f\xa6\x61\x88\xe1\xed\x06\xa4\x46\x1c\xa3\xff\x3b\x4d\x30\x33\xb8\x91\x59\x71\x80\xaa\x46\x9d\xfb\xf9\x39\x94\x4a\xe0\x0e\x5d\xd6\x66\x02\xb3\x45\x90\x28\x35\x96\xe3\xf9\x5c\x1e\x55\x59\xc1\xdf\xa2\x1d\x79\xa4\xb9\x95\x90\x5c\xbf\x63\xb1\x78\xa2\x08\x39\xb3\x12\x6a\x45\xb1\x62\xfa\x7c\xbb\xd8\xae\xf7\x8f\x2f\x0f\xcb\xae\x47\x17\x41\x68\xfd\x03\xf1\x7e\xd7\x47\x79\x70\x2d\xba\x45\xa1\x2d\xb6\xa1\x1b\x28\xac\x3b\x14\x06\x1e\x37\xa7\x5e\x3f\x75\x88\xf9\x99\x22\x58\x22\x13\x05\xbd\x94\xf3\xe3\xe2\x61\xbd\x7d\x5e\x78\x39\x13\x1e\x99\xd8\x76\x1a\x8c\x63\x6c\xa2\xc1\x65\x7d\x5d\xa1\xed\x8a\x1f\x93\x0a\x95\xf8\x72\x2f\xae\xfb\x6f\x9d\x4f\x25\x8f\x0c\x00\xc6\x43\x5f\xb2\xe2\xf5\x3b\x1e\x19\xbe\x7b\x71\x10\x58\x14\xe9\x5f\x27\xa8\xce\xe1\xbe\x9d\x05\x37\xb2\x1e\x25\x9b\x9f\x81\x0b\xe2\x20\x88\xad\xde\xcb\xd3\xe3\xf5\xdd\xcd\xfe\xe1\xee\x71\xff\x75\x71\xff\xb2\xee\xce\x2f\x38\x16\x1c\xb1\x92\xb6\xc8\xf3\xaf\x65\x03\x16\xa5\x79\x5d\x56\x2e\xbd\xea\xc6\x4a\xa5\xad\x08\xae\xdf\xcf\xfd\x91\x50\x58\xa9\x88\xbd\xc7\x98\x76\x31\xc1\x07\xab\x53\x1c\x2a\x49\xfd\xba\xd7\x86\xfb\xc5\x60\x37\x8f\x09\xb3\xda\xb0\x52\x6b\x6c\x2d\xbd\x8d\x05\x33\xc6\x67\x22\x20\x31\x17\x7f\x93\xb9\x39\x83\xac\x90\xc1\xe5\x8f\x19\x8a\x48\xc1\xfa\x94\xe2\x06\xfe\x0d\x3e\x40\xb9\xc4\x54\xc4\x78\x96\x02\x85\x7d\xdb\xcd\x72\x57\xba\x4a\x85\x1b\xc1\x12\x83\x59\xd5\xfd\xd3\xea\xcb\xfa\x6a\xbf\x7c\x5a\x6c\xae\x5c\x7d\x1b\x6b\xdd\xbe\x38\x19\xf3\x20\x54\x3d\x9a\x47\x35\x35\x32\x98\xfc\x41\x9e\x60\xc2\x93\x9e\xce\xdb\xb7\xec\x38\xda\x0c\x63\x9e\x50\x04\xb9\xfd\x74\xb0\x9d\xf9\x1f\xcc\x75\x1a\xc8\x51\xe2\xb9\x92\xea\x0d\xc6\xc9\x6d\xcc\x41\xe1\x83\xef\x14\x15\x0a\x7d\x5f\xfe\x84\x71\x8b\x24\x8e\x38\xc1\xd9\x5d\xcb\x77\x70\x5b\xcf\xf0\xa5\xb8\xbc\x4f\x51\x44\xac\x7c\x33\xc8\x83\xd5\xa9\x1c\xca\x4b\xf2\x38\x8e\xb8\x11\x1d\xc2\x72\x79\x3a\xcf\xd4\x45\xe2\x38\x32\x18\xfa\x76\x32\x24\x87\xf2\xb9\x2c\xce\xf3\xc5\xf6\x38\x8e\x29\xe9\x39\xf9\x2e\xd7\xcd\x2f\xfb\x1a\xd3\x66\x41\x2c\x02\x6b\xeb\xd7\xae\x0c\x6b\x6b\xf1\xb2\x05\x67\x4d\xb9\x7d\x2b\x4f\x6d\xf4\x67\xa7\x2b\x0a\x30\x8f\xa2\xa7\x58\x70\xdb\x1b\x73\x1a\xe0\x96\xf3\x7e\x03\x45\xb0\x2a\x53\xb8\xae\xb2\x41\x2f\xef\x53\xbe\x28\x8f\x45\x64\x6d\xda\x10\xff\xb4\x3f\xe6\xf2\xbc\x97\x85\xde\xa3\x59\xed\x4c\x79\x2d\x4e\x82\xce\xcc\xe8\x1a\xbc\x2a\x1f\xe8\xe5\x19\xb7\xca\xf1\xc2\x1f\x27\xc4\xe0\x52\xba\xef\xc3\x94\xbb\xd5\xe2\x19\xfd\x41\xc0\x40\x05\xc5\x25\xfa\x72\x4e\xec\x89\xc7\x09\xb3\x52\x88\xed\x1b\x60\x61\xba\xdd\xfb\x98\x44\x26\x8e\xc6\x10\x29\x99\xcf\x28\x4e\xf2\x38\x31\x04\xd7\xba\x45\xfb\x88\xe4\x68\x25\x4b\x8c\x42\x24\x24\x06\x84\x52\xfd\xc0\x72\xb1\x8f\xcf\x26\x1b\x7c\x2c\x19\x43\x83\x24\x67\x2e\xd1\x7e\xeb\xac\x0d\xf6\xe4\x56\x4b\xce\x3b\x5e\x53\x01\xf9\xb3\x03\x9c\x79\xa6\x97\xcf\xe3\x62\x19\x85\xa9\x93\x97\xc0\x9b\xfa\x2c\x2f\x69\xd5\x6e\x68\xaa\x69\x48\x3a\x11\xb9\xba\x91\xf9\xb7\x4a\x1e\x8f\x1f\x2e\x47\x29\xc4\x18\x25\x38\xbd\x58\x57\xd9\xf5\x37\x41\x29\xeb\x5f\xaf\x64\x61\xa9\x9d\xfe\x80\x4e\xd2\xc4\x3d\x74\x4c\x2a\x37\x83\x2e\xc6\xe4\xde\x68\xe0\x31\x1d\xa8\xc8\xaf\x4e\xd3\xf7\x4b\x1b\xad\x2c\x61\xc9\x38\x81\xe6\x01\x78\x2c\x06\x0e\xf8\xf9\xfd\x6b\xf6\x0e\xb8\xbe\x7e\x10\xc3\xc7\x26\xb6\x4c\xe7\xed\xe2\xe1\xf9\x7e\x94\x8f\xc5\x26\xa6\xd8\xf9\xb1\x41\x15\x8a\xd6\xd8\x6d\x1c\x1b\x9f\x33\x5d\x4f\x11\x44\x10\x39\x17\xd5\xbb\xba\x3e\x41\xe5\xb1\x3c\xe3\x29\x24\xc2\x50\x61\x56\x85\x55\xb0\xd5\xa8\x09\xfa\xfb\x64\x24\x09\x42\xb7\xb1\x2e\x4f\x88\xfa\x98\x43\x70\x88\x50\x0a\x44\x92\x3b\xc4\xe8\x69\x88\x0f\x11\xa1\x94\xdc\xa5\x0b\x48\xda\xcd\x9a\xb3\x55\xe0\x19\x5c\x79\xa8\x23\x62\x79\x7d\x05\xd4\x59\xfd\x5c\x95\x4d\xa9\xba\x34\x57\x90\x50\xa3\x97\xc3\xc0\xa0\x7c\xee\xdd\x10\x24\xd1\x96\xfc\xea\x5b\xc4\x43\xe1\x18\x37\x86\x06\x56\xcf\xd0\xfb\xb7\xdd\x97\x3f\xdf\xb2\xd7\xb7\xf1\x3b\x32\xcb\x91\xe3\x82\xf2\x18\x39\x3b\xa6\x6e\x86\x15\x17\x41\x93\xc0\x5d\x7e\x9b\x88\xb5\x41\x6f\x75\xe1\xd9\xc5\x05\x95\x16\x00\x7b\x40\xf0\x5b\x67\xeb\xbf\xbe\x7a\x19\x81\x42\x04\x8b\x24\xd6\x7d\xff\x5f\x79\x82\xe1\x8c\x10\xed\x9e\x4d\xac\xaf\x52\xfb\x10\x3a\x73\x51\x80\x7a\x57\xfa\x41\x9c\x19\x6c\x43\xa5\xbf\x8d\x45\x0b\xb8\x88\x88\x36\x1d\x8f\xb6\x7d\xdf\xd7\xdb\x66\x22\xea\xc4\x45\xc4\x18\xd2\xc6\x1f\xa0\xca\x9a\x99\x6a\x99\x88\x94\xf5\x95\x43\x3d\xd5\x1f\x70\x28\x0b\x17\xc3\x5c\xea\xa3\x72\x11\x19\x85\x1b\xf5\xe2\xd4\x94\xf8\x82\x7c\x66\x14\x3a\xfe\x68\x4c\xa4\x05\x64\xbc\x97\xf9\x3b\x3c\x94\x45\x3d\xb5\x1f\x09\xbb\xa1\xcc\x50\xa4\xf6\x64\xef\x19\x4a\x23\xfc\x6d\x7c\x2c\x04\xb1\xdc\x07\x9c\x05\x68\xaf\x95\xa3\x67\xfb\x6f\xe3\x51\xdc\x60\x5b\x4e\x76\xf1\xee\x5c\xc7\xe2\xf7\x61\xc5\x47\x88\xc8\x1a\x01\xec\x9e\xb6\xa3\x87\x27\x8c\x20\x69\x6f\x2c\xfb\x75\x60\xcc\xea\x87\x24\x44\x99\xb0\xd7\xa2\xfa\x47\x62\x09\x5c\x24\x0c\x3c\x7c\x69\x6d\x09\x7e\xe3\x27\x9a\xc4\x21\x06\xd0\xf8\xb6\xef\x90\x70\x58\x9a\xac\x19\xbe\x7e\x89\xb2\x65\xfa\xe5\xea\xab\xbf\x96\x94\x86\xda\x96\x20\xe0\x90\x9d\x0e\x0f\xa5\xee\x8e\xf0\x30\x26\x9d\x94\x64\xbb\x02\x3f\x43\x65\x15\x1c\xc7\x17\x96\x82\xc1\xfa\x27\x16\x94\xdc\x64\xef\xdb\xf8\x02\x02\xdb\xe1\x71\xb2\xf5\xff\x95\x17\x0a\xa6\x5c\x80\x16\xa8\xd8\x22\xb5\xbe\x5a\x1c\x8f\xf3\x55\x22\x61\xa8\xa5\xd2\x59\xf3\x42\x67\xcb\x83\x79\xc2\x2c\x60\x36\x62\xe3\x27\x87\x5d\xc4\x0b\x38\xc4\xe4\x2e\x1b\x99\x22\x2d\xe9\x61\xf1\x7d\xbf\x7a\x7a\xec\x39\xd4\xdb\xfb\xa7\x9d\x0f\x4c\x93\x20\x64\xc6\xeb\xa1\xbe\xb5\x2b\x54\x8f\x04\x4b\x42\x6d\x0d\x5e\xf5\x21\x1f\x4e\x8c\x84\x50\x86\xf0\xba\xe7\x27\x6f\x86\xc6\x13\xc2\x08\x16\xbe\xb1\x66\xe3\xe8\x09\xf6\x35\x53\xe7\x7e\x4c\x9a\xf0\x6e\x51\xfc\x86\xe2\x56\x1e\xd8\x2d\xbc\x70\x98\xef\xf1\x27\x84\x73\xd4\x19\xf1\x4b\xe3\x6d\x79\x80\xaf\x99\xdc\x40\x2e\x3f\xd4\xd8\x74\x1f\xa5\x8c\x6a\xd6\xa9\xec\x8e\x6f\xe9\xc5\xd0\x98\x3a\xdc\xec\x3e\xad\xe4\x74\xf1\x4d\xa8\x92\xb1\x83\x32\x79\x6c\x49\x27\x0b\x3a\x3e\x13\x4b\x54\x48\xdd\x97\xde\xca\x7c\xd2\xd3\x4f\xa2\x98\xe2\x8a\xfb\x50\x56\xff\x85\x6b\x7f\x4b\x62\x00\xf4\xac\xcd\x6a\x67\x93\x34\x39\x69\x6c\xb4\x65\xc3\xd6\x4a\x1e\x61\x0c\x81\xff\x7d\xd8\xd9\x4a\x92\x28\x48\xf4\xc0\xd1\xeb\xba\xac\x6e\xcb\x53\x0d\xcf\xb9\x54\xb0\x9c\xc2\x2f\x92\xc4\xd8\x12\xa1\x93\xf0\xd9\x23\x6e\xb8\xd0\xe5\x61\xf1\x7c\xf7\xb2\xb9\x1f\xad\x2a\x89\x24\x16\x93\x8a\x33\xd4\xc7\xc7\xfa\x33\xa4\x62\xff\x45\x29\x91\x8a\x75\xf4\x37\xa4\xae\x7f\xda\xce\x4e\x52\x25\x91\xa8\xb7\x5b\x3f\x0c\x35\xf9\x78\xa2\x02\xdb\x25\xd8\x96\xc5\x15\x1c\x77\x95\xcc\xba\x23\x51\x1c\xe9\xee\x3b\x5c\x35\x6d\x57\x7e\x7b\xcb\x1a\xc8\xa7\xbc\x68\x9e\xa8\xd8\xc2\x60\xda\xfd\xdd\xb5\xf7\x66\x83\x89\x04\x22\x8e\x03\xed\x73\xcf\x8f\xc9\xe4\x44\x26\xb0\x12\xe3\x36\x1f\xb0\x4a\xc2\xe3\x3b\x67\x44\x8c\x91\x62\x51\x16\x18\x4a\xe0\x92\xb1\x7d\x2b\xab\xe6\xd2\x1e\x75\x00\x47\xf8\x18\x86\x20\x03\x19\x3b\xdb\x46\x24\xe8\x3b\x91\x7c\x0b\x2a\xfa\xd7\x09\xba\xbe\xa9\x0c\x8c\x41\x28\xc5\x72\xf7\x65\xf8\xf6\x4a\x92\xb2\x20\x1e\x27\x5a\xd7\xd9\xeb\xdb\x74\xaf\x12\x33\xff\x1d\xfd\x7a\x49\x79\x88\xb5\xc1\x5d\x25\xdf\x21\x87\xaa\xe7\x4a\x72\x49\x63\x06\x43\xe8\xef\x43\x56\x7c\x84\xcf\x96\x14\x24\x4a\xe0\x3a\xf4\x57\x56\x37\x75\xfb\x50\xf4\xa2\xbd\xe7\xa3\x18\x5d\x32\x91\xf8\xd6\xe0\x06\xa5\x60\xef\xf4\x7c\x01\x4a\x32\xa0\xd2\x29\xe0\x74\x0c\x26\x7f\x16\x4e\x38\x42\xcf\x75\x56\xb7\x99\xd7\x38\x49\x96\x9c\x4a\xd1\xd3\xa7\x76\xd5\xa9\x6e\x00\x06\x5a\xcd\x5c\x72\x46\x70\xa3\xbf\xda\x41\xfd\xd6\xfd\x91\x4b\x86\x2e\xf7\x9b\xb8\xfb\x53\x1a\xca\x74\x00\xc3\xf6\x9a\x22\xfd\x71\x89\x66\x07\x5e\x55\xf1\xea\x47\xbe\xcd\xda\xc9\xf3\x91\x92\xeb\xcc\x02\x26\xa3\x28\xc6\xca\x2d\x72\x9f\xaf\x4a\x75\x3a\x40\xef\xfb\x31\x1d\x2b\xa9\xed\x41\x42\xdd\x20\xe1\x6c\x03\xb8\x3b\x3d\x96\x8d\xfb\xbf\xde\x9f\x92\xcb\x48\xa7\x4e\xdb\x2d\xc7\xb0\xf4\xa5\x9e\x28\xef\x72\x19\x53\x5b\x3e\xb3\x73\xc9\x01\x29\x27\xf7\x33\x66\x31\xbe\xb6\x56\x31\x62\x36\x12\xe9\xc7\xf2\x14\xd9\x90\xbb\xcd\xe2\x71\x7b\x8d\xe6\xb5\xf7\xf7\x4f\xdf\xbc\xf2\x10\x97\x22\x88\xac\xfa\x74\xe7\x0a\xfc\x11\x1e\x4f\x0a\x91\xaa\x2e\xc4\x05\xe4\x11\xb6\x79\xdf\x16\x39\xe2\xe3\xa1\xed\x2e\xc8\x1c\x1b\xab\x72\xb0\x80\xe9\x08\x08\x2c\xe0\x53\xea\xac\x2e\xe4\x01\xfc\x43\x9d\xa0\x27\x64\xc2\x12\x6c\x82\xf9\x2b\x5c\xe6\xa5\xda\x95\x2f\x75\xe7\xad\xd8\x0e\x91\x08\xb0\xf8\x1f\xa9\xc7\xcd\x0d\x29\x69\x92\xea\xde\xfd\x67\x3b\xac\x9d\xfa\x21\x22\x0e\x38\x22\x25\x5e\xb3\x62\x72\xab\xd3\x24\x16\xa4\x6b\x88\xed\xca\x11\x52\xf9\x43\xf0\x7d\x6f\x5b\xe6\x4e\xa3\x68\x8a\xed\x90\xa3\x0b\xf7\x3d\xa1\xcc\x1f\x06\x46\xdd\xf2\xb9\xd1\x9d\x1f\xdd\x6c\x87\x4b\x6a\x1a\x22\xdc\xf2\x20\x7f\xc0\x3d\x2a\x41\x5e\x0e\xc0\xf7\xf4\xdd\x16\x0f\x43\xbf\x2c\x76\xb7\x44\x33\x5b\xf9\xd8\xbb\xd6\xd2\xd8\x1a\x79\x32\xc1\x75\x12\xa3\x42\xcd\x3e\x2b\xb2\x66\x7b\x94\x0a\x7a\x07\x77\x2e\xb5\xb4\x1d\xd2\x57\x68\xee\x33\x05\x45\x0d\x1b\xc8\x0e\x3d\xa3\xd9\x0d\x03\x62\x0d\xb9\xd0\x92\xb0\xf7\x0a\xe9\xa3\x4f\x09\x3c\x54\xae\x07\x7b\x5d\x56\x0a\x9e\x8c\xa9\x3b\xcb\x1d\x3f\x46\x69\xa1\x3d\x72\xc8\x61\xb3\x2d\x8f\xeb\xd3\xed\x4f\x1a\x1a\x23\x77\xe3\xa2\xec\x2b\x4d\xc4\x91\x33\xa7\xb3\x5a\x0d\xc4\x47\x79\x1a\xd0\x84\x59\xab\xbd\xa6\xca\xe0\x1d\x6e\x64\x56\xf4\x07\x75\xe2\xf4\xda\x1b\x99\xdb\xb4\x6d\x4a\xda\x49\x43\x10\x58\xc0\xf3\x1a\x29\xf7\xe5\xeb\x64\x04\xa1\x02\x2b\x5f\x8b\xab\x87\xbb\xc7\xfd\xa6\x0f\xfc\x52\x2a\x05\xa6\x32\xdb\xdd\x62\xb3\xdb\xdf\xad\x9e\xf6\xbb\xbb\x87\xf5\x76\xb7\x78\x78\xee\x86\x80\xc4\xf2\x47\xd7\xb2\x5b\xff\x42\x14\xd6\x08\xe3\xf4\x79\xd3\x2c\xa5\x26\xc1\x77\xc6\x25\x23\x1b\xd9\x80\xc5\x6b\xba\xe3\x8c\x49\x70\xf8\xe9\x75\xf3\x36\x00\x3d\xa4\x2c\x8a\x2c\xd5\x10\x0a\xdb\xc6\xef\xa0\xc5\x7e\x80\x8e\x31\x1d\x49\x07\x6d\xf6\x94\x13\x46\x3d\x96\x6f\x29\x6b\x98\xc9\x15\x53\x9e\x24\x6e\xe3\x42\xd2\xa4\xc5\xc5\x2e\x9a\x66\x9a\xf4\xfd\x9b\xfd\x79\xf1\x7f\xfe\x14\xa0\xf0\x55\xbb\x52\xb2\x71\x8a\x0a\xfe\x0a\x22\x2e\xd3\xae\x79\xf6\xdb\xa0\x1d\x31\xfd\xc7\x8d\x8f\x63\x85\x7b\x23\x4a\xab\xef\x1f\x16\xdf\xfd\x89\x84\x48\x71\x55\x58\x02\xa4\xd9\x84\x2a\x93\x0a\x23\x51\x17\xd0\xa3\x3a\x9c\x2b\xe2\x90\x0f\x9e\x26\x21\xc5\x25\xc7\xc9\x4f\x3b\x14\xe5\x07\x05\xa2\x34\x61\x21\xaa\x81\xb8\x22\x73\x59\x8d\x88\xfa\x69\xd2\x5e\x2a\x6a\xbe\xfe\x40\x87\xce\x91\xc8\xd0\x78\x3b\x48\x93\xc4\xa0\x5e\xf3\x6d\x59\xb4\xcb\x43\x5d\xd8\x3b\x74\xb7\x7a\x4a\x47\xaa\x31\x3c\x4d\x52\xab\xad\xe7\x8c\x41\xbc\x67\xf2\x07\x68\xc5\x34\x51\x54\xf4\xbd\xc2\x67\x6f\xa4\xc2\xd3\xc4\x68\x04\xda\x2f\x4f\xe7\x85\x2a\xab\x7e\x92\x48\x15\x79\xb7\xe5\x7b\x59\x37\x57\x00\xba\x53\x1c\xe9\xdb\xfb\xa3\x2f\x91\x10\x73\x2c\x25\xc8\x2a\x43\x89\xd0\xc1\xcb\x9c\xa6\x32\xf4\x42\xbf\x0f\x68\xa1\x7a\xd1\x53\x4f\x53\x15\xa2\x3e\x68\x56\x3f\x02\xe8\xab\x4a\xfe\xbc\xb0\x99\x6a\x07\x91\xc0\xa9\x7c\x39\x7e\xf0\xcd\x49\x56\xb2\x68\x60\x0a\xf9\x48\x15\x8d\x70\x2d\xde\x37\x55\xf6\xfa\x0a\xd5\xaa\x2c\x73\x6c\x2b\x5e\x95\x3f\x8b\xe9\x58\x13\x24\x6e\xf3\xbc\xce\xd2\x72\x72\x54\x53\x82\x0d\xa8\xdc\xe2\x07\xe6\x80\x74\x29\x70\x81\xea\x36\x36\x00\xbb\x2e\x2b\x78\xef\x22\xa8\x14\xb4\xc1\xb0\xf8\x5d\xe6\x27\x78\x32\xf3\xfd\x97\xd4\x30\xcb\xa6\x71\x99\xf8\xe7\x49\x5f\x6a\x52\xdb\xda\x6c\x40\x1e\xee\x8a\xba\x91\x45\xb3\xed\x57\x75\x15\x48\x08\xdd\xe2\x6f\xc5\xec\xf1\x71\x7c\xc0\x93\x1c\x9f\x5a\x85\xcc\xc4\xce\x67\xac\x3c\x35\x8b\x42\x6f\x3d\x78\x76\x10\x34\x63\xf1\x6a\xba\x88\x8d\x9e\xa8\x22\x91\x40\xec\x42\x65\xf5\xfb\xea\x2b\x28\x4a\x6c\x73\x79\x21\xd0\x76\x88\xb2\xb6\xdc\x79\x59\x5b\x5a\xd9\x80\x17\xad\x68\x40\x13\x35\x64\x6e\xc9\xe3\x06\xa4\xea\x99\xbe\x8a\x32\x8d\x4b\xf9\xd2\x6a\x97\xac\x73\x28\xa4\x3f\xd6\x46\xcf\x8e\xb5\x82\x4d\x28\xd0\x5f\xe5\x29\xef\xee\x10\x93\xcc\xa9\xa7\xf7\x56\xe5\x7d\xbf\x55\x31\x69\x1d\xde\xa4\xd6\x2f\x85\x86\xea\x6a\xba\x49\x28\x06\x96\x76\x87\xe1\xc7\xbe\x1a\xbe\xf6\x8a\x8b\x44\xf6\xfa\xd9\xd9\xe1\x74\x58\x21\x88\xa6\xee\xbe\x9e\x83\x41\x21\xb8\xf6\xf9\x21\x9e\x75\x8c\x8a\x50\x51\x64\x8d\x8e\xad\x4f\xe6\xec\xd6\x31\xbe\xdb\x51\x02\x88\x36\xdb\x3e\xdd\xbf\x6c\x57\x9b\x51\x71\x4b\xc5\x9a\x41\xe8\x98\x94\x0f\x4e\x39\xe3\x4a\x6a\xed\x57\x02\x25\x42\xdb\x42\x44\x3b\x10\x2c\x3f\xf9\x03\x32\xc2\x9a\xf5\xc3\xe2\xf1\x76\xb1\xdb\x2d\x1e\x9f\x37\x4f\xdf\xff\x88\x77\xb7\xdb\x5d\x37\xc4\x04\xcc\x71\xbc\x76\x50\xc8\x89\x16\x3c\x57\x49\x7b\xaf\xdb\x2b\xfb\xd7\xcb\xdd\x66\xb3\xbe\xdf\x2f\x17\xdb\xf5\x7e\xb3\xfe\x97\x3f\x41\xf2\xff\x59\x7b\xb3\xe5\xc6\x71\x2d\x6b\xf8\x75\xea\xe2\x5c\x90\x20\x09\x80\x97\xb2\x2c\x3b\xd5\xe5\xa9\x2d\x65\x66\xd5\xe9\xe8\x50\x60\xd8\x90\xd8\xa6\x48\x1d\x92\x4a\xa7\xea\xe9\xff\xe0\x06\xc0\x49\x54\x56\x7d\x11\xff\x8d\x1d\x21\x82\x13\x88\x61\x0f\x6b\xaf\x05\x60\xc5\xf7\xdb\xbe\xc0\xc4\xf1\x68\xcb\x52\xa9\x89\x12\xc7\x76\x82\x07\x5e\x3c\x57\x4b\xa2\x44\x68\x3c\x5c\x16\x25\x6b\x10\x33\xf9\xe6\xc6\xa9\xff\x96\x22\x92\xc4\xc1\x16\x7e\xcf\x9a\xe6\x82\xb1\xdf\xf1\xc7\x94\xa1\x74\xdb\xa6\xa3\xc6\xbf\x59\x55\xe0\x4f\x20\x14\xa3\x6c\x5d\x3d\xf4\xe4\xa5\x25\x10\x4b\x85\x31\x64\x63\x9b\x20\x10\x95\x22\xb6\x24\xe1\xa9\xdc\x5b\xf8\x5b\x8d\x65\x84\xf3\xd3\x52\xc5\x29\x2e\x52\x4f\xa5\x45\x95\x74\x30\xdb\x5f\x2e\x14\x4a\xa5\x01\x26\x9d\xd0\x96\xd9\xec\x96\x03\x84\xb4\xd2\x61\x80\x6b\xe4\xdd\xb9\x2a\x50\xb8\x6d\xf2\x7c\x3a\x09\x51\xcf\xd7\xb1\x93\xcc\xf9\x0a\xa8\x83\x85\x6a\x99\x67\x5b\x21\xa7\x7f\x51\xaa\xa0\x80\x45\x68\x1b\x49\x51\xc3\xae\x19\x8e\x50\x93\x50\xd6\x17\x4d\xbd\x2f\xb6\xab\x5d\x98\x78\xf2\xa7\xa1\x3e\x5f\xa2\x0c\x63\xc6\x25\x90\xdf\xca\xf2\xe0\x87\x89\x0e\x62\x5b\xb5\x68\x77\xc5\x67\xd1\xa8\x43\xaf\x3f\x38\x0a\x65\x77\x27\xa4\x68\x3f\x2f\x5a\x33\xd1\x81\x61\x9a\x1a\x15\xd3\x4e\x79\xa6\x06\x0b\x95\x0e\x94\xad\x2f\xf4\x86\xc3\xa0\x50\x4f\x87\x71\x8c\x32\x5d\xcb\x43\xb6\xeb\xb4\x98\xbb\x83\x54\x20\x80\xf1\xbf\xc4\xcf\xbb\xf2\x67\xf7\x2b\x23\x44\xf7\x92\xa6\x68\xa8\xb5\xbe\xc0\x1b\x42\xe4\xe7\x92\x93\x9a\x18\xcd\x5c\x9a\x06\x39\x2c\xb1\x20\xbb\xc9\x64\x96\x67\xcd\x65\x60\xae\xb7\xbb\x15\xa2\xd7\x1f\xc5\x8f\xeb\xe0\xd3\x2f\xc7\x8a\x8e\xa4\xc6\x45\xcf\x11\xd7\xf8\xa7\x8d\x03\x4a\x9d\x35\xf0\x3b\xb2\x9b\x91\x84\xce\xe5\x6d\x75\x1c\x86\x98\x19\x29\x31\xbf\x8c\xdc\xaa\xcd\x44\x71\x2d\xd1\x31\x61\xa8\x39\xbe\x47\x2f\xba\xfa\x22\x6e\xc1\x6a\x74\x12\x09\x16\xf5\xe1\xfd\xe7\xc9\x1c\xd3\x09\x33\xe8\xc8\xde\xd9\xbc\x96\x7f\xdc\x44\x30\x65\x79\x93\x2a\x75\xf0\x21\xe9\xb1\x91\xa7\x69\x20\xb1\x44\xe2\x4d\x5c\xb6\xe5\xa4\x64\x47\xb3\xc0\x92\xf2\xed\xa1\x79\x3d\xff\xc8\x74\x59\x65\x62\x55\x34\xb0\xcd\x4e\x93\x9c\x91\x66\x51\xcc\xbd\xc7\x87\x7b\xa4\xc8\x2d\x7e\x75\xdc\xb1\x2c\x36\x91\xcb\xd3\xed\xba\xf1\xca\xd2\x08\x79\xb5\x9f\xca\xfd\x4b\xd9\x64\xe6\xf2\x6a\xbc\x8d\x98\x95\x85\x17\x83\x9e\x65\x95\xd1\x0c\x62\x5c\x39\x0e\x17\x5d\x95\xa3\xbd\xbd\x6b\xc0\xd1\x43\x50\xbd\x4f\xb7\x36\x63\x06\xc1\xc9\xc7\x4f\x03\x5b\x61\x2b\xcf\x97\xa5\xa8\x34\xaa\x97\x4f\xcc\x4a\xdf\x32\xd4\xb2\xa7\xbc\x74\xe1\x9b\xbb\x8b\x95\x61\x9c\xbc\x79\x9a\x24\x48\x4e\x51\x81\xc8\x31\x5a\x6e\x73\x12\x9e\x7b\xed\xa1\xac\xec\x0f\x3e\xdf\x3e\x8c\xf2\xea\x94\x32\x84\xc3\xbe\xaf\x9e\x56\x8b\x8d\x77\xc2\x74\x2a\x44\x68\xa9\xfb\xf6\x68\x5b\x54\xe5\xf1\x09\xf6\x42\x5d\xde\xe1\x74\x6e\x2c\x63\xcd\x60\x6d\xd1\xc2\x09\x62\x34\xe5\xc7\x09\x2a\xe8\x38\xa7\xb4\x54\x21\xf2\x19\x5b\x5f\xfd\x4b\xd9\xcf\x69\x45\x63\x16\x76\xf6\x13\xd4\xcb\x76\x92\x8d\xdf\x4c\x31\xab\x64\xd4\xfa\x79\x0f\x13\x65\x93\x44\x2b\xc9\x02\x8f\xcc\x46\xda\xaf\xac\x35\x41\x7b\x8f\x19\x1b\x88\x6e\xb5\x72\x78\x58\x7c\xec\xaf\xef\xeb\xf9\x7e\xd7\x11\xc3\x01\xf3\x02\xcd\x77\xf8\x39\x48\x68\x6b\xcd\x89\x97\xb3\x7d\xab\xe0\x39\x2b\xe6\xc9\x92\xb4\x96\x2a\x06\x5f\xef\xe1\xb4\x76\xdf\x00\x09\x19\x7f\xb1\x6c\x6b\x6d\x44\xe8\xf9\x72\x0a\xc8\x6d\x49\xda\x34\x20\x3e\xbe\x13\x08\x6d\x5c\xbd\xf6\x10\xb7\xad\x4d\x68\xc0\x33\x1e\x38\x01\x99\x7b\xd1\x40\x78\x01\xd1\x2d\xb6\x26\x35\x08\x54\x96\x42\x7d\x7c\x5b\x6f\xb6\x8b\xd6\xb6\x1b\xc6\x24\x21\x08\x19\xc6\x12\x11\x50\xe2\x33\x15\xdd\x41\x16\x23\x99\x49\xe5\x6c\x56\xec\x7f\x4f\x55\x00\xc4\xc4\xe8\xde\x9d\xec\x1a\x17\xee\xf2\xb3\xfa\xb8\xc8\xf3\x65\x5b\x09\xf5\xd1\xdf\x82\x98\x8e\x14\xe7\x19\xc7\x59\xeb\xed\x0e\x33\xfb\xae\x5d\x44\x29\x2e\xf0\xe7\x42\xe6\x42\x7d\x5c\x07\xe0\x21\x62\x04\xe9\x4d\x30\xac\x84\x9d\x5e\xb5\x2e\x9b\xd3\x40\xf2\x8d\x52\x82\x55\xc6\xab\xed\x97\xdd\xb7\xed\xa2\xff\xd9\x4a\x22\xec\xa1\xf9\x02\x55\x79\x6d\xb9\x40\x04\x31\x66\x7f\x7a\x9e\xa7\xbf\xb1\xef\x21\x26\x0c\x97\xcd\x4e\x6d\xf9\x2a\x0b\x37\x7e\xfe\x38\xa1\xaa\x73\x71\x7b\x31\x64\xff\x88\x49\x62\xe9\x19\x16\x4b\xcc\xb7\xfd\xbe\xf2\x84\x64\x40\x0d\x65\x96\xbd\x42\xc3\x11\x71\x7f\x3d\xa1\xcb\xab\x19\x52\x41\xf8\x33\x38\xa3\x5e\x50\x17\x33\x96\xbd\xb4\xf3\xec\x86\x05\x9c\x43\xe4\xe2\x20\x83\xd0\xd4\x5d\x59\x7e\x4c\x46\x3e\x70\x19\x8a\x68\x90\x8d\x73\x71\xb7\x21\xeb\x93\x6f\x69\x08\xfa\xaa\xda\x3a\xfe\xd6\x1c\x1c\xaf\xae\xc0\x0d\x43\x07\x1c\x77\xe2\xb7\x0a\xd6\xcb\xd7\xc9\xfd\x52\x9a\x06\xdc\xc3\xca\x32\x03\x96\x41\xfa\x76\x2d\x24\xa4\x2a\x45\xd4\xb6\xae\xca\xd3\x0b\xa8\x46\x54\x73\xc5\xe0\xbe\x31\x44\xb8\x87\x3e\xe9\xee\x33\x88\xd0\xd2\xc5\xfa\xc2\x0c\xa7\x82\x81\x1b\xe3\xe4\xbb\x4e\xbe\xaf\xe2\x29\x5a\x81\x42\xeb\xbb\x52\x5f\xde\x44\xe5\x8a\x44\xba\xec\x24\xe8\x84\x06\x71\x37\xa5\x44\xfe\x94\x15\x1f\xef\x56\xe3\x7d\x38\x14\x34\x37\xd8\x75\xcd\xeb\x66\xd2\x1d\x90\x58\x96\x87\x1a\x10\xac\x3c\x3d\xca\x22\x04\xbc\xac\x55\xf9\x26\xce\x75\xe7\xdf\x01\xf0\x44\x3a\xbd\x96\x5a\x90\x60\xc7\x6f\x8c\x03\x10\x1a\x87\xe8\x41\xd4\xdf\xa7\x65\x50\x26\x10\x96\x7d\xd3\xd2\x95\x66\xc5\x7e\x94\x68\x33\x21\x91\xc4\xeb\x31\x9d\xba\x5b\x1b\x12\x70\xe9\x41\xcc\x0f\x22\xcb\x2d\x58\xc9\x1a\x69\x95\xad\x43\x5a\x17\x5f\xbb\xe2\xaf\x76\xd0\x48\xd5\x15\x0e\xa0\xbd\x3c\x63\x09\x18\x02\x31\x86\x39\xd4\x41\x54\x59\x73\x69\x0d\xbe\xee\x96\x51\x04\xe8\x92\x62\x9d\x80\xad\x64\xb9\x41\xe5\x9f\x98\x38\xb0\xd2\xaa\x48\xf5\xa7\xcb\xfd\x1b\x2a\x1e\x0d\x38\xff\x4c\x1c\x9a\x58\x38\xb1\x38\xbf\x44\x7e\xad\xa7\x1b\xb4\x89\x13\x8e\xd6\xab\x17\xec\x41\x04\xc5\x20\x4a\x3e\xbd\x2f\x4d\xa8\x83\x5e\x7d\x7b\xda\xa2\xad\xbc\xc9\x26\xf5\x8d\x86\xd2\x18\xc7\xf2\x63\x99\x6b\xac\x2b\xd4\x33\x55\x8c\x86\x29\x4b\x02\x61\x41\x94\x68\xaa\xff\x03\x0d\xd6\xd9\x01\x60\x98\xe6\x94\x7a\x67\xdc\x13\x42\x12\x5f\x01\xed\x1b\x81\x85\x7e\xd4\xa2\x80\x75\xf7\x2b\x27\x29\x66\x61\xda\xb5\x46\x29\x38\x4d\x1f\x82\xff\xda\x68\x36\x3c\xb5\x25\x44\x75\xcf\xb1\x31\x79\xd1\x34\xb4\x05\xda\x7b\x97\xff\x18\x85\xce\x4d\x4a\x01\x5d\xd8\x1e\x8f\xdd\x5f\x3b\x15\xc0\x1d\xec\x70\x09\x55\x93\x99\xd6\x2b\x81\x4d\xb6\x2f\x86\xba\x7f\x9d\xed\x6f\x52\xa0\xda\x7f\xf3\x4c\xe4\x88\x32\x7b\xce\x8a\x76\xd0\xdf\xf7\x41\x62\x23\x42\x69\x75\x83\x1c\x0f\xd8\x64\xdb\x18\x3f\x83\xe2\x60\x05\xa2\xcb\x52\xcb\x4b\x77\x0d\xa5\x28\x82\x61\x5e\xbf\xbf\xec\xe4\xb9\x2a\x7e\x61\x3f\x18\x1d\x5b\x19\x66\x04\xa8\x4b\x51\x67\xea\x6b\x91\x35\x5b\xe8\xc2\x21\x46\x33\x86\x48\x9e\xcd\xb6\x75\xfd\x1e\xd7\xcb\xdd\xdb\xe2\x7d\xfb\xb2\x7a\xdf\x20\x5d\x14\x26\xc6\x96\x8b\x76\x83\xe9\xce\x10\x29\xeb\x74\x6f\xbb\xbd\x04\xd6\xc5\xa4\xaa\xc1\x40\x40\x75\xc7\xef\xf9\xc7\x51\xd4\x8f\x99\x99\x7e\x21\x20\xca\xdb\x4f\xf7\x85\x40\x3f\xd7\xa5\x62\x87\xbd\x0b\x04\x22\x17\x54\x73\x78\xa7\x57\xf9\x7f\xeb\x1b\xf6\xb4\x31\x01\xc5\xda\xa5\x76\x8f\x20\x56\xfb\xe3\x79\x46\xbb\x06\x5b\xd3\x20\x48\x14\xb1\xf4\xd8\x58\xbf\x3f\x8a\xe9\x0e\xbd\x22\x1a\x84\xb1\x20\xda\x45\xf8\x01\x29\xbd\x87\xef\x42\x83\x90\x46\xc2\xf4\xb1\xdb\x47\xd1\x59\x5f\x34\x08\x99\xf4\x19\x37\x1b\xa7\xfe\x0e\xd9\xe4\xf4\x48\xd8\xc0\xba\xcf\xf8\x3d\x64\x39\x2c\xf3\xb2\x9e\x29\x1e\xbf\xde\xc6\x68\x10\xc9\x00\x9f\xee\x50\xa2\x9e\xf6\x71\x24\x48\x4c\x83\x38\x8c\x98\x15\x11\xf8\xb1\x05\x71\x1c\x6d\xab\x34\x88\x1d\xa3\x8a\x9d\x87\xb5\xff\x92\x0f\x42\x65\x22\x9f\x3c\x67\x2c\xa9\xf6\xd0\xe6\x47\xa4\xbc\x93\x9b\xa6\xac\xd0\x1b\x78\x38\xe7\x79\xfb\x83\xc7\xef\xd2\x20\x21\xda\x83\xb2\x5d\xdc\xc4\x6e\x8c\xfe\xe3\xd2\x80\x32\x82\x80\xaa\x4f\xc8\x9c\x18\x48\xbd\x68\x6e\x92\x42\xd2\x80\x1a\xc6\x9d\x81\xff\x8c\x84\x90\xdd\x5b\xb0\x98\xa0\x6c\xf9\x72\xb3\xdc\x4c\x1e\x3a\xe5\x11\x8a\x64\x9a\x73\xf3\xb3\xb5\xd2\x2b\x7f\x4e\xaa\x12\x31\x64\xd4\x6c\xdf\xc2\xe2\x98\x27\x05\xc0\x93\xa7\x10\xc4\x9a\x8d\x4f\xaf\xcb\xdf\x77\xef\xab\xa7\xc5\x66\x85\x19\x29\x7f\x5d\x11\x27\x98\x16\x6e\x4d\xcf\x4d\xeb\x59\xc2\xfe\x32\x79\x26\xc1\x43\xac\x5c\x70\x35\x28\x2f\x90\xed\x0f\xb2\x3c\x57\x33\x48\xd2\xb6\xb1\x22\x62\x00\x16\x85\xee\x46\x8a\x20\x3b\xa4\xdf\x2e\xef\x44\xcf\xbe\xe3\x9a\x48\x6e\xb0\xde\x09\x33\x4f\x0b\x5f\x46\x4e\x03\x29\x83\xc0\x46\x62\x71\x7b\x1a\x8f\x76\x15\x1a\x61\xe9\x60\x84\xfe\x63\x84\x9d\x1a\x6e\x06\xa3\x67\x54\x9a\x63\xb0\xb3\x19\x12\x11\xf9\x9b\x29\x23\xd0\x72\x73\x8a\x0f\xa0\xd1\x84\x1b\x47\x00\x68\xa0\x8d\x95\x46\xdd\x65\xf5\x52\x54\xe5\xb9\x9e\xe0\x9f\x68\x00\x44\x19\x47\xdd\xf1\xd5\xf2\x96\x2c\x07\x94\xbd\xb3\x5b\x05\x0d\x40\x48\x74\x5c\xff\x5d\xea\x4c\xa8\xbe\x28\x82\x06\x00\x9d\x7d\xe4\xe0\x9a\x13\x0c\x2e\x0d\x0c\x8b\x30\xb1\x55\x1f\xb2\xd3\x2f\x16\x6c\x1a\x06\x44\x46\xaa\x4b\x8d\x79\xfa\xa8\xef\xab\xd5\xef\x8e\x16\x83\x86\x41\x62\x90\x40\xa0\x11\x55\x66\x26\x84\x2c\x34\x0c\x4d\x82\x88\xfa\x93\xdf\x98\xbd\x6f\x45\x43\x12\x86\xc9\x80\x9e\xa0\x70\x64\x8d\x93\x0b\x90\x58\x23\x25\xca\x8f\xb2\xb9\x86\xde\x5f\x35\xc5\x04\x99\xcd\x4d\xed\x10\x80\x92\x43\x5d\x0f\x15\x54\xc6\xaf\x17\xa5\x01\x22\xd7\xef\x96\x7f\xf8\xa7\x8a\x99\xc0\x42\xbf\xa2\x74\x5b\xe4\x94\xb1\xa7\x3f\x3b\x06\x86\x15\x11\x52\xd4\xe8\x27\x5f\x6d\xc8\x34\x44\xda\x3d\x8b\xf4\xd1\x70\x97\xf9\xcc\x33\x0d\x69\x1c\x70\xeb\x12\xc2\x84\xa4\xac\xdf\x25\x68\x48\x13\x81\x0b\x89\x3c\x5f\x53\x0d\xfc\xca\x88\xa1\x21\x65\x82\x7b\x19\x56\x0b\x2e\xd9\xe0\x1a\xef\xef\xcf\x0c\x47\x00\x56\x7d\x3e\x5a\x9f\x23\xea\x8f\xd8\x75\xfd\xad\x82\x71\xed\xf6\xdf\xfd\x9f\x7e\x9c\x7f\x62\x6d\xd1\x30\x0d\x0c\x82\x86\xb2\xda\x22\x78\x96\xed\xf2\xe2\x61\x3c\xbe\x0d\x21\x41\xd0\x15\xce\x39\x23\x64\x32\x4e\xd2\x28\x74\x1a\xf1\xde\x41\x1c\x9a\xe6\x34\x4c\xa9\xe2\xdd\xb6\x5c\x57\xd5\x38\x4e\xe8\x1b\x31\xa7\x7f\xe7\xb2\x44\xba\x75\xc6\xfc\x31\x4d\x30\xf2\xff\xb4\x7a\x5c\x3c\xed\x56\x7f\xbc\xad\x5e\x36\xab\xcd\x8e\x8c\xea\x95\x68\x28\xb8\x45\x2b\x62\x58\xa4\x76\x2c\x88\xf3\x75\x5b\x34\x14\x60\xd0\x60\xbe\x3b\x5f\x2c\xb3\x8a\xbf\x8a\x4c\x52\x61\xeb\x65\x84\x6c\xe7\x45\xbb\x87\xb7\xeb\x78\xbb\xd4\x4c\xc6\xb0\x14\x16\x82\x60\xd1\x3a\x08\xe0\x75\x51\xe7\xfe\x6b\x4b\x17\x20\x6a\x2a\x91\x15\xd1\x8d\x87\x51\xa1\x32\xa9\x57\x1d\x7c\xfc\xbe\xfd\xff\x41\x73\x90\x86\x2a\xa2\xd8\xed\x15\xb4\x2e\x13\xf1\x0f\xa4\x62\x5b\x72\xba\xf9\xb2\x78\x5f\xed\xb6\xab\xc5\x73\x77\x84\x29\x03\x3d\x41\x5c\x0f\xad\x1d\x5f\x57\xa7\xe0\x15\xb2\xda\x95\xfe\xad\xcc\x33\x35\xd9\x8d\x42\xad\x3c\xbe\x7d\x2f\x9a\x7e\x34\x41\xa0\xd1\xac\xb8\x5f\x3d\x2c\xbe\x3e\x6d\x77\xcf\xeb\x97\xf5\xcb\xe3\xee\x6e\xbd\xed\x5a\xd0\xd8\x73\x09\xbd\xad\x2d\x8b\x53\x14\x0e\x53\xd4\x34\x34\x40\x0d\x78\x70\x88\x9d\xf3\xf5\x9d\x2b\x65\x1d\xeb\x74\x51\x12\x30\x91\xc8\x81\xbc\x2a\x46\x5e\xe6\x92\x9e\xbe\xbd\xb0\x34\x34\x6f\x67\x99\x67\xf5\xa1\xfb\x8c\x24\x30\x31\x26\x19\x4c\x76\xaa\x2d\x77\x85\x8d\x55\x52\x2e\x63\xdf\x86\x30\x13\xd9\x8c\x46\x55\x20\xf8\x6c\x1c\xf4\x70\xad\xa2\xc4\x92\x0e\xb5\xdd\xf7\x75\x7d\xbf\x19\xef\x94\x24\x66\x8c\xb9\x50\xd1\x7d\x56\x21\x4a\xe9\xe2\x6f\x90\x04\x14\x2b\xb9\xf3\xaa\x9e\x5c\x34\x89\x52\xdc\x92\x7a\xe2\xed\xf9\x91\x46\x92\x38\x05\x97\x21\xdc\x1e\x2a\xa8\x0f\x65\xae\x2d\x9f\x84\x6b\x40\xa9\xc2\x22\xd8\xbc\xdc\xbf\x43\x5d\x9e\xab\x0e\xb0\x40\x09\x0b\xa3\xd8\x09\xf3\x56\x9e\xb4\x8f\xfb\x63\x1c\x70\x11\xe8\xe8\x45\x7d\x02\xdc\x1f\x57\x56\xc3\x65\x5f\x89\xa2\xe3\x4e\x7b\xcf\xf6\x87\xb1\x11\x4f\x09\x03\x0b\x0c\xf2\xf5\x7e\xf8\xdd\x76\x5d\x14\x85\xf5\x61\x14\xf6\xbf\x33\x70\xcf\xa1\xcf\xdb\x7b\xbe\xf3\x72\x4c\x94\xf0\x44\x26\x16\x7b\x55\x47\x34\x68\x0e\xf7\xa2\xeb\x6c\x9e\x1a\x0f\xa2\xb6\x21\x71\x67\xe5\x92\xc9\xf3\x72\x60\x98\xaf\x7a\x7b\x5f\x39\x24\xd1\xd3\x93\xbf\x46\xaa\x14\x26\x90\xbd\x61\x72\x6f\xc5\x87\xbd\x3d\x4b\x44\x6c\xa2\xa4\xa7\x0c\xb7\xf6\xf9\x55\x30\x8b\x12\x41\xa9\x70\x01\x35\xbf\x3e\xcf\xce\x79\x22\x54\x88\x80\x6a\x8c\xa8\xfa\xda\xfa\xd7\xa2\xfb\x0a\x2a\xe2\x88\x08\x11\xf5\xc7\x7f\x9f\xa1\x1e\x01\x36\x67\x90\xd1\x6e\x4b\x99\x60\x32\x29\x51\x4c\x48\x5f\x9c\x60\x63\x81\x0f\x65\xf5\x05\xf2\xd3\x15\xc1\x36\x25\x0a\x34\x62\xe1\x4e\x95\xb2\x10\x28\xff\x2c\x9a\x45\x18\xb0\xfa\x91\xed\xa1\x50\x5e\x86\x8a\x12\x88\x38\xae\x1d\xdb\xd7\xaf\xef\x2f\x0b\xe4\x1a\xb6\xa4\xc6\x5d\x03\x0d\x18\xab\x5d\x6d\xbf\x2c\x5f\x5f\x3a\x56\x9b\x41\xb2\x80\x12\xa3\x55\xe0\xca\x35\xda\x7b\xbe\xe5\xe2\x0a\x99\xea\x5b\x1a\x85\xc1\xca\x6f\xa2\xc8\x9a\x8b\x0f\x3a\xcc\x11\xf6\xd0\x28\x48\xec\xd6\xde\xbe\x26\xe2\x1c\x06\x11\xc3\xf9\x15\x25\x0a\x9c\x4c\x77\xeb\xcb\x63\xf0\xa9\x1c\x87\x6e\xda\x16\x80\xe4\xd0\xcb\xad\x7f\xc3\x28\x10\xda\x53\xd2\xb6\x2b\xd6\xfd\xe4\x8c\x30\x0d\xb1\xac\xd8\x42\x9b\x36\xe7\xd3\xa9\xac\x9a\xb9\xe8\x0c\x8d\x48\x64\xf9\xe7\x2c\xd8\x15\xa3\xb1\x93\xb5\x23\x22\x71\x82\x15\x7b\xba\x2a\x4f\x03\x62\x5c\x1a\x91\x24\x40\x0b\xfc\x31\xfb\xcb\x65\x76\xba\x23\x34\xd1\xd0\x15\xc7\x2e\xc5\x69\x7a\x49\x19\x22\x41\xf9\xf7\xf5\x12\xbb\xe9\x57\x48\x98\x5b\xbb\x99\xbb\x54\xc4\x03\xe2\x0a\xd3\x2d\x59\xb3\xc8\xf3\x31\x6c\x87\x46\x71\x14\xa0\xdf\x7f\x7c\xf8\xfa\x72\xdf\x6e\x28\x68\x2a\x4f\x20\x7d\x34\x8a\xb5\x0d\xda\x35\x59\x6b\x9b\x6e\xa6\x0a\x21\x34\x8a\x41\x29\x8b\x6d\x96\x59\xb3\xfa\xcf\x59\xe4\xf9\xe5\x3a\x7c\xdb\x35\xd6\x91\xaf\x38\x7e\x81\xcf\x45\xa1\x0e\xe5\xc4\xed\x89\x92\xd8\xca\xc9\xde\x9d\x1d\x77\xdb\x2d\x33\x7a\x72\xed\xa4\x35\x1c\xec\xf7\x3f\xd7\x30\xa2\x6f\xa0\x51\x02\x21\x76\xfe\xa0\x4c\xcf\xc9\x92\x4d\x5e\x27\x81\x38\x48\xbb\x6f\xff\xef\xf2\x28\x33\x18\x53\xaf\x78\x4c\xde\x50\x11\xdc\x9d\xcc\xa2\x40\x5a\x81\x20\x57\x8f\xe0\x96\x3f\x98\x61\x37\x1d\xd8\xcd\x11\x4b\x14\x32\x2d\xd4\xa7\x1c\xd3\xc6\xd3\x60\xda\xe4\x4d\x19\x0b\x34\x19\x04\xd5\xea\x67\x51\x9c\x6f\xb0\xfb\xd1\x88\x89\x10\x0d\xc1\xc7\x32\x6f\xf7\xd7\x3e\xa5\x73\xab\xbd\x16\xe8\xa8\x3f\xaf\x5f\x56\xef\x3b\x44\x7b\xb6\xc3\x03\x5d\x2a\xdf\x9d\x3c\x31\xa4\x8f\x5f\xbe\x9a\x29\xd9\xd7\xf8\x79\x79\x4a\x90\x5f\x7c\xd5\x1c\x30\xed\xb2\x01\x51\xa9\xc3\x43\x05\x60\x53\x42\xf5\xe4\x1b\x78\x94\x36\x52\xf7\x56\x15\x16\x40\xb7\x3e\xe1\x74\x12\xa6\xa9\x54\xd4\xa7\x40\xce\x85\x76\xc8\xdb\xaa\xdb\x7c\x23\xd1\x5e\xac\x53\xd9\xdf\x1f\x9a\xa7\xb2\x6e\x5a\x03\xb5\x2f\x4c\xe7\x5d\x53\x8a\x61\x38\x4f\xb5\x61\x13\xa3\x59\x73\x79\x2b\xcb\xfc\x57\x4e\x67\x24\x98\x95\x3f\x17\x39\x92\x18\xf7\x37\x57\x09\xef\x87\xd2\xb8\xe8\xeb\xd6\xbc\x1e\x58\xf7\x91\xd0\x1a\x5d\x8d\xdf\xdf\xa6\xc1\x94\x48\x86\x31\x26\x33\x57\xc7\x53\x56\x41\xbf\x5c\xdc\x5a\x1e\x7e\xe9\xd3\x44\x4a\x6a\xb4\x6f\x76\xa8\x19\x5d\xd7\xed\xca\xf8\x54\xee\x33\x35\x07\xc7\xa0\x91\x32\x29\xa6\x8e\x0d\x80\x0e\x83\x60\xf2\x51\x34\x49\x82\x60\xc0\x0d\xf5\x22\x2d\x79\xf4\xa4\x19\x10\x6b\xda\x2c\x0f\x50\x65\xf5\x61\xb4\x52\x9a\x28\x62\x6e\xa5\x5c\xe4\x79\xf9\xd9\xd1\x57\x0e\xa6\x8c\x89\x03\xcc\xcb\xe2\x88\xf6\xd9\x8d\x1b\x1f\xc8\x68\x22\xac\xcc\xf7\x76\xf1\xd4\x45\x05\x46\x7e\x50\x64\x8c\x02\x17\x85\x38\x9f\xfe\xb1\xfc\x15\x8d\x83\x28\x40\xaa\xc6\x5d\x2e\xea\x66\x53\x88\x53\x7d\x28\x9b\xf5\x64\x91\x8c\x83\xc4\x4a\x6e\xca\xf3\x65\x7d\x3c\x59\xb9\x84\xf1\x1c\x9c\xf3\x46\x6f\x18\x60\x71\xc8\x79\x30\x2c\xe9\xea\xd9\x61\x8a\x0f\x4b\x10\x39\xbe\x7b\x28\x38\xce\x93\x0d\x34\x0f\xad\xa7\x78\x4d\x15\x4f\xe3\x10\xa8\x0b\xea\x54\x53\xeb\xc6\xb5\x20\x21\x47\x9b\xe4\xf5\x7b\xbb\x2e\x60\xd4\xed\xae\xfd\xeb\xbb\x30\x26\xc4\x06\x72\xda\x4f\x22\xb4\xee\x7e\x4e\x39\xce\x66\x9b\x30\xe9\x14\x79\xfc\x51\xad\x10\x05\xaf\x44\xae\x3c\xaf\xc8\xf8\xe9\xa3\x20\xc0\x6c\x14\xc6\xc1\x77\xcf\x8b\xf7\xdf\x57\xed\x82\xe4\x2f\x10\x25\xb6\xc0\x3b\x2f\xf7\x9b\x4f\x80\xd3\x2f\x33\xc0\x34\x8e\x49\x84\x88\x3c\x79\xbe\x74\xd6\x69\x17\xad\xbb\xe5\x23\x8e\x1f\x28\x4e\x53\xe4\x9c\x79\x14\x47\x40\x04\xc7\x7c\x69\x12\x8d\x63\x1d\xd1\xd0\x89\xe7\xf8\x92\x99\xb9\x34\xa8\xdf\x51\x46\xdd\x1d\x83\xc2\xd7\xbe\x13\x79\x5e\x36\xaf\x37\x33\xa2\x34\x4e\xa8\xfd\x30\x68\xbf\x6e\x40\x95\x85\x1e\x28\xad\xd3\x98\x52\x1d\x93\xc1\x74\x02\x7d\xb5\xbf\x8c\x5f\x90\xab\x94\x58\x2d\xab\xe6\x5c\x15\xef\x70\x14\x59\x91\x15\x7b\xcc\xcd\xf9\x8b\x72\x93\x22\xbf\xa6\xc7\xf7\x79\xc8\xd3\x75\x16\xeb\xd6\x1a\xf4\x0f\x8a\x0a\x69\x9c\x86\x5e\x33\xda\x13\xb7\x0d\xb7\xf5\x38\x4d\x94\x0d\xe6\xe1\xfa\xfc\x50\x56\xe1\xaa\x39\xbc\xc5\xdd\x61\x6a\x09\xc3\x91\x65\x6f\x59\x1e\x8f\xe7\xd6\x5c\x1d\x96\xb4\xd3\x58\xc8\x10\xcd\x06\x1b\x7e\xf9\x46\x6e\xf4\x89\x0c\x38\xa6\x59\x37\xdb\xc5\x76\xb3\xdb\xac\xff\xed\xf7\xc2\x58\xc5\xb6\x27\x3c\x3e\x6e\xd7\x4c\x28\x6d\x68\xac\xa8\xc6\xa4\xd3\x8f\xb2\x81\x6d\xe9\x88\x89\xc6\xd7\x57\x9c\xca\xae\x7a\xe3\x3e\xab\x9b\x76\x67\x7c\x3f\x77\xf3\x44\x71\x40\x19\x0e\x97\x9a\xbf\x2b\x9b\xc3\x64\x06\xab\xd4\x62\x2d\x1a\x2c\x64\xb3\x15\x10\x7f\xc7\x02\xdf\x9d\xca\x55\xe8\x4d\xe7\x66\x51\x55\xe2\x72\x7f\x29\xc4\x31\x53\xdd\xed\x53\x8d\x05\x65\x75\x0e\x70\x9a\x84\x8c\x63\xed\x54\xb0\xdb\x7d\xb8\xdb\xd4\xdf\x44\x25\x8e\x75\xd7\x24\x4d\x91\x86\xeb\x8f\xb3\xcc\x46\xf3\x1f\x92\x00\x2c\x77\x5f\xa6\xc0\xcb\x1a\xcf\x0f\x95\xee\x0c\xa5\x5d\x2c\x60\xf3\x91\xb5\x86\xed\xfc\x4b\x41\xca\x30\x13\xdb\x2e\x45\xb3\xe9\xa4\x18\x44\x84\x41\x11\x4b\x64\xb9\x3a\xb4\x96\x57\xb7\x95\xba\x36\x26\x12\x62\x98\xc0\xec\x54\x6c\xc7\x9f\xcf\x00\x43\x10\x6d\xe3\x39\xea\x7c\x11\x18\x4d\x48\xc0\x5c\xb9\x30\x6a\x24\xfc\x36\xd5\x68\xa6\x09\x51\x10\x49\x0f\xfd\x28\xfb\xf4\x5b\x6f\x0b\x24\x11\x8b\x03\xf7\x32\x4b\x39\xc5\xb2\xdb\x22\xff\x71\x7b\xce\xc5\x80\x36\xa7\x12\xf2\x6f\xb3\xcb\x83\x07\x8a\x74\x14\x5a\xe1\xb7\x1c\x44\xf5\xdf\x67\x38\xfb\xfe\x48\x22\xc3\xb0\xb4\x7b\x29\xaa\xad\xf8\x99\xad\x55\x39\x3f\x61\x92\x04\x38\xea\x03\x9d\x8b\x5a\x18\xf8\x5e\x65\x0d\x7c\x6d\xf7\xb4\x19\xfe\x38\x9a\xb0\x90\x6b\x36\xc8\xbc\xfd\x36\x63\x0f\x25\x8c\x01\xbe\x53\x1f\xaf\x71\x72\x2f\x5d\x57\x73\x2a\x95\xd5\xe9\xba\x2e\xba\x1d\x8f\x8e\x84\x33\x8e\xf5\x1f\xf2\x7c\xb9\x87\x53\x39\xb5\x2d\x13\xce\x52\x12\x4e\xb2\x52\xed\x45\x5f\x44\xd5\x5a\xcf\x3f\xfe\x91\x2a\x3d\x4d\xb8\x4a\x98\x0b\xcd\x79\x91\xe3\x07\xa1\xae\xfc\xd9\x84\xeb\xa4\x5f\xe7\xfa\x28\x6e\x92\x52\x8b\xf7\x3b\x88\x7a\x0b\xe2\xf8\x0c\xc8\x0c\x38\xee\xe9\x54\x03\xa6\x98\x6b\x67\x7d\xe0\xf6\xfe\x05\xcd\xdd\xee\x32\x46\x63\x5c\xc6\x15\x0b\x8c\x49\x4c\x28\x96\x23\x7a\xa5\xa7\x06\xf7\xe9\xee\x88\xb1\x50\x90\x3d\x92\xa8\x2e\x2a\x2c\xcb\xa9\xff\xd8\x5e\x4e\xdd\x88\x90\x49\xea\xbd\x91\xb1\xb6\xeb\xfc\xf6\x99\x48\xae\x47\x15\xc3\x9b\x06\x4e\x93\xf8\x50\x22\x8d\x50\x2e\xf9\xbf\xaa\xd5\x19\x72\x31\xe9\x2f\x95\x2a\x84\x04\xcb\xac\x2c\xba\x55\x2a\xd1\x9a\x89\xc0\xc3\xf1\xfb\x14\xeb\xf8\xda\x10\x84\x89\x5b\x3f\x5e\xe0\xe7\x24\x92\x96\x98\x20\x35\x4e\x71\xdb\xb3\x1a\xac\x0b\x53\x56\xc7\x6b\x96\x61\x4a\x83\x98\x21\x06\x6b\xa5\xca\xa2\x3c\x5e\xb6\xe2\x67\x5f\x2c\xff\x8b\x7f\xee\xec\x30\x24\xd8\xeb\x36\x90\xe5\x69\x32\x07\x89\xe3\xf1\xcd\x42\x16\xa2\x2a\x2f\x46\x4a\x31\x48\xea\x76\xf3\xf1\x1b\x50\xc2\x6d\x0a\x2b\x9b\x91\x8d\x9a\xdf\x65\x29\x51\xa9\xb0\x99\xc1\x66\x51\x7f\x6c\xa0\xca\xa6\x0b\x1c\x86\x2f\x94\x93\x6d\x6e\x0d\x9f\x8d\xd5\x5e\xf4\x53\x8f\x46\xd4\xf2\x0a\xbd\xbd\xaf\xd6\xcb\xd7\x21\x6a\x9d\xb6\x2e\x25\x56\x26\x7e\x3f\x94\xeb\x7a\x7b\xe8\x74\x02\x1c\x6a\xd6\xb7\x32\xa1\xc7\x9d\x2e\x45\xa5\x91\xf1\xe9\xd5\x8c\x48\xb9\xff\x35\x79\x26\x43\x2c\x2d\x2c\xd4\xc8\x01\xb4\x3d\x64\xfd\xf3\x18\x8e\x16\x37\x8c\x80\xfb\x93\x0b\xc4\x01\x45\x01\xfb\x93\xb8\x98\xb2\x1a\x2a\x13\x52\x9a\x18\x2a\x9c\xc2\x8f\xdf\x45\x3b\x15\x9c\x81\x23\x42\x29\x00\xf7\x2b\xb3\x53\xdf\xda\x96\xef\xb8\x8e\x55\x93\x08\x3f\x65\x21\x47\x64\x9c\xab\x6d\x5c\x9d\x4a\x75\xf8\xad\x3b\x96\x22\x42\xa7\x3c\x35\xeb\xe2\x0f\x03\x55\xc7\xf0\x4f\x69\x9a\xc4\x32\x76\x86\xe4\x06\x87\xd0\x28\xba\x4f\x53\x15\xd8\x04\xc0\xa1\xfc\x44\xd3\x6f\x68\x24\x51\x11\x19\x0c\x00\x6c\x40\x9d\xab\xac\xb9\xec\x96\x65\x51\x80\x6a\x5a\x77\xc1\x39\xee\xdb\xf2\x05\x3e\x3b\xc9\xda\x01\x39\xe2\xe8\x36\x32\xe0\xb8\xd0\x08\xad\x91\x71\x01\xf1\x4d\x55\x7d\x77\x19\x4a\xd2\x7b\xb3\x94\xca\x90\x23\x82\xf9\xed\xcf\xa1\xcc\x3a\xa5\x52\x5b\xf9\x94\xfb\xb3\x28\x3e\xcf\xfe\x57\x1d\x05\xc2\x65\xd7\x1d\xdd\xda\x3b\xa8\xf2\x78\xbc\x52\x63\xa4\x54\x27\x04\x03\xc0\x59\xfd\x7a\x82\x9e\xce\x89\x52\xcd\x23\x9a\x38\x89\x3f\x0b\xa2\x1c\x17\x41\xf4\x03\x1e\xa2\xc8\xc4\xbd\x80\xe1\x30\x82\x47\x21\x36\xc4\x12\x9e\xd6\x8e\xe4\xa8\xb6\x65\xdd\xf3\x3b\x09\x05\xee\x08\x96\x31\xae\xd7\x71\xbb\x4f\xef\xc8\x25\xe9\x2d\x55\x91\xbb\x2b\xbf\x41\x85\x66\xf5\x4b\xf9\xe9\xee\xcf\x82\x08\x10\x5d\xb4\xf8\xb6\xfe\xea\x7f\x0b\x79\x80\x35\x4a\xd9\xf1\x94\xef\x4e\xd3\xea\x97\x31\x9b\x12\x65\x51\x6a\x65\x67\xe1\x3f\x67\xe7\x34\xdb\x26\xc3\x8f\xc9\x22\x23\x70\xbc\x59\xe3\xc7\x9b\xcc\x2c\x0e\x6c\x2c\x00\xd5\x52\x3a\xd1\x02\xca\xe2\x90\x4b\x5c\x5a\xf3\xa6\x93\xf2\x1f\xbf\x22\x8b\x13\x8d\xe9\x9e\x11\x0d\xa4\x0d\x7b\x4c\x1a\x72\x1b\x3d\xd2\xf6\x43\x5b\xcd\xb9\xee\x46\x0a\x90\x93\xf2\x24\x2e\xad\x97\xfc\xec\x91\xde\x14\xf5\x69\xda\x8f\x96\x83\xde\x43\xd5\x7e\x91\x3b\x87\x3b\xf3\x50\xda\xd1\x38\x61\x2c\x51\xa1\xdb\x0d\xba\x1a\xbe\xd9\x4f\xc8\x58\xca\xad\xc3\x83\xc4\x28\x4b\x7f\x43\x1e\x04\x18\x34\x14\x9d\x8c\x33\x65\xdc\xd5\x56\x6a\x71\x19\x96\xa7\xfb\xa3\x31\xc3\x62\xe2\xbb\xed\xf2\xfe\xf5\x71\x35\x79\x6f\x6e\xb8\x74\x76\xde\x5d\xa6\x7f\x1b\x1d\x4b\x23\x83\xf6\xc8\xc7\xe7\xa1\x47\x32\x52\x96\x0a\x1b\xd7\x3f\x88\x42\xe7\x30\x3c\x22\xc2\x50\x09\xcf\x2c\x94\x81\x5e\x34\xce\x28\x9a\xac\xdc\x4c\xa4\x29\xee\xb7\x39\xec\x45\x3e\x31\xdd\x99\xa4\x36\x2a\xae\xca\xa2\x6e\xaa\xf3\xb5\x65\xc2\x24\x4b\x41\x0f\x4d\xb3\x21\x73\x95\x6f\xa3\x42\xe4\xf3\x54\xa2\xd2\xf5\xae\xc9\x1a\x51\x64\xe7\xe3\x0e\x8d\x99\xee\x4e\xaa\x63\x97\xb6\xfc\x33\xd9\x5f\x53\x4b\x86\x29\x47\xf6\x08\x45\x3b\xc8\x32\xfd\x50\x56\x8e\x76\x20\x93\x33\xd1\xad\xd1\x73\xaa\x54\x87\xdc\xd7\x1d\x62\x71\xc4\xba\x58\x34\x8d\xc3\x33\x7d\x13\x79\x67\xc3\x32\x4d\x13\xd4\xc4\x5e\x6c\x56\x03\x36\x56\xca\x40\xd2\x24\xf4\x10\x31\xe7\xf4\xba\x74\xe4\xec\xfe\xc1\x40\x72\x61\x0b\x77\x91\xa4\xab\xd7\x0a\x0a\xfd\x53\x99\x80\x20\xbc\xf7\x79\xb1\x7e\xb1\x11\x76\x4b\x1a\xea\xaa\xbb\x16\x8f\xab\x1d\xd2\xda\x7a\x38\x03\x33\x34\xb4\x1a\x5f\xe7\x66\x9b\x35\x03\x00\xb3\x77\x1b\xc6\x91\x86\x99\x89\x6d\x98\xc4\xf2\x0b\x5c\xb2\xe6\x02\x78\xcc\x08\xe6\xe5\x8e\x5d\xc2\x11\x53\xbc\xfe\xa8\x0c\x71\x33\x71\xa2\x11\x42\xe6\xbf\xa0\xdd\x9c\x37\x28\x78\x90\x5a\x84\xe2\x1d\x14\x60\x32\x95\x89\xea\x32\xe5\xf9\x1d\x3d\x12\x0f\x52\x85\xb3\x5e\x83\xca\x8e\xdd\xa0\xe1\x61\x4c\x53\xac\x1f\x70\xe2\xf1\xfe\x77\x12\xd1\xa8\x0b\x79\xbc\xc0\xe7\xb6\xa3\x6a\xa5\x9c\x24\x09\x4e\x8c\x6d\xf9\x91\x35\xf3\x1b\x31\x27\x40\x8d\xf1\x84\x8b\xe7\xba\x71\xd6\xcc\xa4\x55\x94\x50\x74\x8b\xb7\x5f\xd7\xbb\xc5\xfd\xfd\xfb\x6a\xe3\x4d\x1a\x1e\x47\x91\xb2\x04\x1c\xa7\x07\x21\xbb\x5f\x53\x0b\xf1\x13\x5a\xbf\x94\xfa\x0a\x7c\xee\x5a\x25\xb1\x8d\x9f\xfe\x7e\x2a\x4f\xeb\x06\x8e\xfe\xec\x24\xb1\x5a\x23\xb6\xa4\x6b\x73\xd6\xe5\xc0\xce\xe0\x09\x37\x08\xcd\xf9\x96\x55\x22\x1f\x75\x46\x02\x96\x0f\xed\xe5\x6d\x3b\x93\xcd\xe2\x34\x8c\xa8\x18\x48\x2c\x9f\xab\x7a\x4c\x30\x39\xfe\x74\x34\x01\xac\x9e\x3a\x17\x5f\x84\x2f\x19\xa6\x9c\x2a\x40\x90\x1e\x34\x9e\x25\x8d\x72\x1e\x87\x98\x26\x5b\x64\x57\x71\x86\x41\x9a\x63\xfc\x30\x9c\x0b\x24\x91\xd8\x1e\xec\x06\xf8\xe0\x2f\x96\x06\x2a\xe1\x03\xaf\xe0\xf5\x7c\x23\x9b\xc0\xd3\x58\xa2\xff\xef\xb9\x4f\x70\xff\x1c\x52\xeb\x4d\x9a\x33\x99\x76\x32\x48\x2e\x4f\x79\x9e\x70\x4c\x53\x2e\xa2\x08\x31\xa8\xc7\xcb\xcf\x1e\x9b\xdb\xfe\x2c\xb0\x1e\xfc\x11\x9a\x11\x1e\x89\x0b\x17\x2e\x96\xe7\xcb\x88\x85\x7d\xc6\xce\xe7\x32\x56\xb8\xa5\xda\x0f\x80\x95\x60\x23\xbe\x97\xc9\x03\x4b\x9d\xa0\xb5\xbc\xfd\xf2\xf5\xe9\xcf\x85\xbf\xa1\x8a\x08\x16\x22\xfa\x0c\x3f\x9a\x79\xf7\x28\xc2\x3d\x7f\x19\x95\x0a\x34\x71\x2c\x21\xf6\x75\x76\x68\xb4\x82\xb8\x73\x80\x11\x54\x69\x46\x3e\x3e\x5b\x31\x37\x2a\x1e\xa4\xdc\xa4\x51\xa0\x3d\x85\x93\x05\x63\x0f\x44\x0f\xfe\x06\x52\x65\xaf\x91\x06\x4c\x2a\xe6\x51\xe3\x59\x31\xe1\x34\x9f\x36\x96\x80\x22\x6b\xad\xab\xf6\x08\xc5\x97\x8b\x67\x79\xa1\x69\x00\x56\x20\x78\x67\x93\x7a\xed\xf3\x22\xd2\x7b\x7c\x81\x30\x66\xa1\x72\x50\x83\x3e\xee\xbf\x5b\x2e\x7c\x8a\x33\x0d\x99\x2d\x1f\x71\xc5\xb3\xcb\xe9\x05\xb8\xf1\xb8\xbf\x85\x46\x76\x10\x07\x58\x9a\xde\x89\x10\x8b\x8e\x12\x67\xd5\x9c\xeb\x37\xab\x13\x3d\x86\xf9\xa6\x44\xa8\xb4\x27\x12\xc3\xa1\x3b\xc7\x1f\x79\xdd\x69\x44\x0a\xb4\x3b\x10\xca\xdd\x3b\x22\xbf\xc4\x3c\xf9\x53\x55\xac\xbd\x9b\xb4\x14\x85\xcd\x01\x64\x7f\xc1\x4b\xd9\xac\x0a\x0d\xba\xd7\xbf\xa0\x69\x14\x73\x2e\x07\x88\x32\x9c\xa4\xa3\x06\x4c\x20\x6d\x81\xc8\xaa\xfb\xaa\x3c\x59\x97\xe7\x76\x70\x3a\x8d\xb5\x41\x03\xa6\x56\x22\x07\x6d\xb7\xd5\x7e\x1e\xa5\x49\x2a\xa9\x8b\x6f\x6c\xee\x97\xbf\x0e\x53\xa6\x89\xb4\x92\x9e\xf7\x22\x87\xd7\xf7\xee\x12\x9a\x61\xfc\xb5\x30\xcd\x55\x80\x38\xa5\x71\x24\xad\x94\x29\x76\x1c\x36\xe8\x7b\xcf\x37\x4a\x38\x65\x5d\x04\xe3\x6a\xd0\xa7\x54\x05\x2e\x80\xae\xca\x42\xb7\x36\xfb\x73\x59\xf8\x52\xca\xf6\xb0\xe5\x06\x47\x70\xef\x43\x56\xd5\xcd\x77\x80\x0f\x9b\x1a\xed\xda\x98\x00\xeb\xfa\x0c\xd6\xf8\x2f\x21\xb7\x84\x1c\xe3\xa5\x3a\x65\x69\x8c\x78\xfd\x6d\x96\x6b\xe8\x8b\x1c\xdb\x03\xd4\xa3\xcc\x2c\xfa\x78\x1a\x1d\x48\x53\xa2\x99\xb2\x39\x1e\xf4\xcb\xfd\x76\x3b\x37\xaa\xe6\x18\xdf\xfa\x55\x20\x4d\x39\x47\xf7\xe1\xb4\xb3\x33\x62\x77\xb4\x69\x46\x5c\xb4\x06\x60\xbd\xc9\x03\xa4\x3c\xa5\x8e\xca\xfe\xd5\x6c\x0f\x76\x70\x6f\x0f\x55\xd9\x21\x69\x52\x61\x42\xac\x5d\x5c\x3d\x3e\x6e\x76\xdb\xd7\xdd\x97\xc5\x76\xf9\x65\x17\xde\x2d\x3c\x88\x23\x95\x86\x61\x57\x9f\x0b\x6f\x6f\xb6\x66\x48\xa5\xc7\x18\x81\x54\xa5\x84\xd0\x3e\xa6\xba\xc8\x87\xb9\xc1\x54\x4b\x1a\x3a\x7d\xd8\x17\xf8\x5c\x5e\x41\xb9\x53\xad\x2c\xdd\xed\x23\x34\x4b\xd1\xc0\xbe\xec\x34\x37\x06\xf4\x71\x34\x05\x6e\x39\xc8\x5a\x93\xf2\xe2\x3c\xe5\xc9\xd0\x00\x6d\x69\x58\xed\x7c\xfe\x22\x06\x8a\x69\xe3\x4f\x6b\xc2\x34\x6e\xe7\x8d\xd3\x18\xf7\xb4\xf1\xbb\x6f\xab\xcd\x76\x75\xbf\xf3\x48\xc3\xd4\x18\xe9\x39\xa9\x2c\x94\xed\x39\x2b\x9a\xeb\xe2\x4b\x2a\x02\xc7\x2d\xb6\x2c\x8f\xa7\xd6\xa3\x6c\x60\x79\xc8\x4e\xe3\x60\x78\x44\xfc\x3c\x14\x61\x14\xa1\x55\xf4\xbb\x90\x59\xd5\x91\xd4\xf8\xdb\x0a\x12\x1b\x8c\xd6\x96\x55\xb6\x6f\xa7\xfe\x80\x43\x98\x0a\xe2\xe0\x09\x37\xb4\xb2\xff\x35\x13\xd1\x15\x51\x18\x08\xa7\x84\x3a\x24\xb9\xbb\xb1\x39\x70\xf7\xb8\xfe\x64\xc2\x90\x84\xea\x90\x35\xcf\xa5\x9c\x5b\x1d\x7d\x43\x93\x22\xe3\x78\xa7\xb7\xda\x0e\x7d\xcc\x5f\xcc\x7f\x06\x11\x47\x42\xda\xc8\xb6\x25\x45\x1c\x12\xcf\xdf\xfa\x3f\xec\x51\x6f\xd8\x8b\x58\xc4\x98\xf7\x5d\xd4\x75\xb6\x2f\x1e\x1f\x57\x6f\x65\x99\x5f\x2b\xc8\x51\x91\xc4\x8a\x06\xae\x66\x65\xd5\x1c\xa6\x47\x65\x1c\x85\x1d\x2a\x69\x9b\x9d\x66\x09\x92\xda\x76\x89\x74\x05\xf3\x7f\xab\xec\x3b\x88\x99\x0b\x1a\xfb\x2c\x62\x9d\x29\x6b\x1d\xfe\x83\x2d\x43\x50\x6a\x6b\x92\x2c\x57\xb7\xbf\x63\x75\xcd\x69\xe6\xdb\x33\xab\x03\x6d\xa5\xb4\x27\xc7\x78\x8c\x5e\xb4\x86\xe2\x82\x11\xcb\x76\xfe\xbc\x55\xe5\xcf\x8b\xd5\xaf\x9b\x36\x97\x76\x35\xcd\x6a\xc7\xda\x3f\x99\xbc\x82\x51\x8a\x65\xf5\xf7\xa2\x3e\xec\xcb\xdc\x2f\xb1\x82\x27\x3a\x89\xc7\x04\xae\x76\x14\x8f\xce\xe6\xd2\x06\x05\xb0\xd5\x29\xab\xae\x18\x66\x5d\x3b\x41\x0c\x8b\x07\xc1\x0c\xc7\xb9\xe4\x6f\x26\x34\x75\x2f\x8c\x51\x8a\x51\x4a\x51\xc8\x04\x04\xed\xc0\x46\xf7\x99\x31\x99\x3a\xe7\xcd\x65\x51\xe8\x11\xbb\xd8\xe4\x96\xd2\x89\x23\x57\x18\x3f\x7a\x16\xd7\x43\xd3\x37\x54\x81\xcf\x17\x21\x83\xfb\xa8\x9c\x78\xdc\x54\x91\x08\x57\xba\xef\x59\x81\x9c\xfb\x37\x07\xfb\xf8\x23\x28\x99\xc0\x18\xe8\x3d\xb9\xac\x4c\xd1\x64\xda\xae\x36\x5b\x5c\xc8\x42\xff\xee\x3a\xb2\x64\x66\xfd\x02\x8e\xb5\x04\xd5\x04\x21\xe4\x5a\x43\x3b\x38\x9c\x6c\x60\xbb\xa9\x17\xfb\x12\x65\xaa\xba\xb5\x5c\x80\x26\x10\x0e\xf2\x6f\x98\x79\x18\x3f\x0c\x98\x04\xed\x6b\x5d\x9e\x5b\xbf\x69\x46\x9b\xc1\x35\x34\x8c\xa3\xd7\x88\x5c\x92\xc3\xcf\xce\x27\x1d\x6c\x52\x9b\x75\x71\x65\xe2\xce\x94\xf3\x31\x32\x19\xb0\x90\xdb\xaa\x9d\x37\x31\x1d\xbf\x32\xe0\x1c\x3d\x25\xb4\x90\x77\xf9\xb0\xec\x6d\xdc\x30\x4c\xc2\xd8\xf9\xa0\xcf\xe2\xe7\x43\x05\xa8\x60\xe7\x2d\x45\x19\x26\x3c\xea\x07\x91\xcd\xac\x5c\x11\x88\x0d\xb6\x6d\x19\x72\x1a\xf6\x1c\xb6\x88\x4f\x7e\x2d\xda\x5d\x78\x29\x8a\xbb\xf3\x98\xc2\x81\xca\xd0\x38\x8a\xc4\x4a\x14\x8d\x9d\x88\xdb\x72\x36\x61\x22\xa3\x30\x0a\xfb\x5c\xe2\x8f\x2c\xcf\xfb\xaa\x18\x19\x45\x11\x65\xdd\xa0\xad\x71\xc1\xd0\xdd\xc1\x58\x93\x9e\x61\xb5\xcf\xad\x0e\x9e\x3a\x4a\x2d\x8a\x5f\x58\xd2\x5c\x58\x17\xed\xe6\xd4\xbe\x68\x77\x11\xc5\x7d\x06\xd6\x89\x94\x5c\x51\x01\x50\x99\xc4\x96\xfe\x7e\xd1\x1c\xc4\x9f\xaf\x8f\x8b\x71\x49\xe6\xf8\x7d\x12\x9d\x12\xea\x86\x28\x3a\x84\x93\x6b\x21\x94\xd0\xe1\x58\x10\x57\x36\x56\x07\xa1\x92\xa6\x1a\xe9\xca\xc4\x29\xf3\xf1\x05\x1f\x57\x1b\x9b\xfb\x92\x05\x4c\x32\x1f\x51\xc2\x50\xb3\x3f\x92\x26\x8c\x3a\xa4\xb4\x83\xbd\x60\x10\xba\x75\x60\xae\xe3\xd5\x52\x90\x98\x74\xcc\x85\xe3\x87\x11\x34\x40\x30\x90\x63\x8a\x99\x70\xa7\xf8\x46\x12\x70\xcd\x7c\x3b\xff\xf5\x57\x3e\x08\xc2\xcc\xe2\x56\xa4\x22\xa1\xb6\xea\x8d\x95\x2d\xde\x7f\x2a\xf7\x64\x51\x94\xc5\xc5\xc7\x2a\xa4\x4a\x08\x71\x50\xe1\x7f\x5b\x6d\x8e\xe1\xee\x28\x35\xb1\x69\xc3\xd7\xf7\x97\xd5\x76\xf9\xba\x7e\xf1\xe7\xe9\xd8\x7a\x98\x1e\xc6\x20\x8a\x8f\xfe\x90\xad\x73\xa8\x11\x49\xf2\x56\x95\x32\x87\xe3\xa4\x1f\x74\x62\xb0\xbe\xcb\x0e\xa8\xd6\x34\x02\xbd\x14\xa7\x13\xe8\xb5\xfe\x39\x19\xb6\x10\x48\x84\xdf\x7d\x59\xbf\xbf\xe2\x1a\xe5\x6f\x04\xa1\x0d\xd8\x37\xe5\xa2\x56\x59\xe6\x12\x2a\xfe\x20\x55\x58\xe9\xd1\x7e\xfc\xa7\x6f\xab\x5f\xa3\xbf\x24\x18\x2a\xbd\x18\x69\x01\x77\x97\xd7\x02\xde\xcb\xb2\x19\xda\x81\xae\xa5\x21\x51\x4a\x46\xba\xb5\xf7\x48\x4a\xac\x06\x2c\x02\x54\x1a\x1e\x20\x56\xea\x84\x31\xee\xc9\x47\x34\xa9\xc1\xfa\xbd\xcf\x2c\xd7\x0a\xe5\x59\xcf\x83\x33\x45\x62\x1c\x7f\xd1\x8f\x4c\xe3\x7a\x75\x63\xf8\x1b\x29\x12\xda\x7f\x82\x87\xb2\xea\xca\x86\x47\x8f\xac\xc2\x84\x2b\xc7\xc3\xd6\x7e\x27\x97\xa9\x70\x37\x54\x44\xd9\x84\x4d\x59\x41\xfd\x04\xa6\xe9\x7f\x27\xe8\x07\x6c\xfe\xdc\x6c\x57\xcf\xbb\xe5\xfb\x0a\x6b\x97\x77\x4f\xeb\xe7\xae\x62\x45\x11\x93\x22\x6e\xe7\x8b\x17\x72\xf8\x95\xf8\xc2\x0d\x34\xd6\xf8\xb5\x54\x14\xb0\xd4\x7f\xb8\x60\x7e\x53\x57\x51\x1a\x18\xab\xc6\x60\xf9\xa0\xfd\xcf\x32\x46\xdd\x88\xb1\xd2\xa0\x2d\xf2\x73\x60\xdc\xd9\xdd\x55\xc5\xb1\xe5\x75\x2e\x4f\x50\xac\x57\xaf\xbe\x8e\xdf\x1f\xa5\x82\x05\xa3\x05\x19\x73\x16\x76\x4f\xb9\x56\x46\xa2\x8a\x2a\x8a\x45\x76\xa2\xae\xa1\x6a\xd6\xcd\x7d\x09\x75\x61\xf9\x9b\x47\xf9\x3e\x45\xb5\x42\x2f\x3d\xab\xdf\xca\xfa\x2e\x6b\xc7\xde\xbc\xa9\xa0\xa8\x51\x36\x6c\xd0\xee\x46\x68\x9e\x6e\x86\x3c\x6b\xae\x15\x0b\xac\x15\xba\x7c\x1f\xa5\xea\x14\x4b\x52\xcb\x9f\xde\xbe\xd8\x6d\x94\xe9\xec\x6e\xab\x98\x88\x30\xcc\xf3\xbc\x7e\xd9\x3d\xac\x56\xdd\x35\x65\x1c\x59\x20\xd3\x0f\xc8\xcb\x13\x54\xf5\xf2\xdc\x0d\x1e\x66\x54\x92\x74\xe6\xf0\x5d\x59\x55\xa8\x5a\x35\xbe\x30\x27\x80\x53\xe9\x98\x15\x9e\xb5\xc0\x46\xe9\xc7\xd5\x33\x8a\xb3\x24\xb6\xf4\x0e\x65\x05\x77\x48\x71\x33\xb1\x3f\x94\x08\x08\xba\x3d\x59\x91\x35\xdb\xcf\xf2\xff\x95\x81\xe1\xd7\x81\x2e\x25\x02\x85\xfb\xc4\x88\x5f\x62\xb4\xf4\x8e\x6d\xf6\xe9\xe9\x29\xe0\xf3\x67\xed\xfa\xfa\x26\x32\x3d\x90\x87\xa5\x4a\x52\x2b\x0d\xfc\x7b\xbb\xba\x4e\xc2\x8f\xe7\xa9\xaa\x48\xdb\xdc\xa4\xb2\xeb\xd9\x57\x63\x30\xf3\x71\x83\x15\xd3\x9f\x23\x62\x62\xa9\x86\xd4\x6b\x85\x6e\xe1\x95\x1d\xa1\x54\x68\x7d\xc3\x5c\xa0\xc9\x2a\xf6\xc3\xf5\x4c\x29\x19\x1a\xaf\x9a\x78\xca\x8a\xd7\x73\x73\xea\xf5\x8a\xe6\xa3\x3c\x4a\x41\xe0\x45\x3c\xee\xc6\x91\xc1\x1b\xed\x4d\x40\x9d\x4e\xe8\x26\x3b\x9e\xf2\x76\x05\xbe\x0a\x06\x8f\x3b\xda\x2f\xa9\x4a\x07\x01\xc6\xf6\x74\x56\x37\x59\x9e\x3f\x96\x7a\xc0\xb5\x44\x95\x8e\x99\x2f\x88\x71\x8b\xb6\x33\x63\xb3\x62\x6f\xe3\x3b\x5d\x99\xbd\xd2\x4c\x59\x12\x94\x6c\xef\xd8\xba\xfd\x81\x34\xc6\x0a\x5d\x97\xf4\xbf\x13\x4d\x97\xf4\x57\x5a\x5a\x4b\x5e\xf6\xfb\xa0\x32\x2a\xa2\x83\xf5\xf9\xd5\x18\x75\x18\xc8\x55\xfc\x0a\x32\xae\x03\x2a\xb4\x1e\xe7\xae\xbf\x67\xcd\xc1\x46\xe9\xec\xf0\xf9\x47\x90\x70\x1d\xa4\x29\xa2\x1a\x5e\x75\x56\x4c\xc0\x39\x3a\x64\x91\x70\x4e\x77\xfb\xeb\xa2\xd0\x73\xb2\x94\x54\x87\x3a\x42\x4a\xbc\x02\x43\x2b\x0e\x05\xee\x8e\x11\x1a\x48\xc7\x1c\xb2\xb6\x84\x1d\xdf\x44\x95\xc9\x1c\x6e\x8c\x45\x4d\x34\x0b\x1d\x44\x05\x4d\xe5\xa1\x0d\xa4\xa3\x28\x45\x6f\x4c\x66\x53\xad\x0a\xdf\x80\x07\x08\x0c\x5b\x57\x99\x35\x9f\xde\x10\x3a\x3d\x08\x6c\xea\x38\xb2\x09\xee\xd6\x4f\x9f\x8f\x6f\xf8\x86\x4c\x9a\xa4\xe3\xbb\xfd\xe5\x0c\xd2\x09\x13\x98\x20\x14\xb8\x3e\xad\x8b\xa7\x9b\x2c\x18\x6d\x53\xcf\x59\xfe\x9c\xfd\xf4\x55\x97\x33\xec\xfe\x54\xd3\x40\x58\x3d\x06\x5b\xfc\x81\x56\xd0\xec\x77\xe5\xfe\x04\x6a\x43\xd8\xbb\x9b\xb1\x83\xd1\xb4\xd0\x34\xb5\x5f\xe7\xae\x7d\x6a\x8b\xee\xf0\x47\xdc\xee\xde\xa7\x0e\xc3\xee\x90\x16\xe8\x09\xd8\xe2\x1a\x5b\xf4\xbc\x2a\x6c\xe9\xde\xb5\xbb\xa2\x59\x64\x75\x49\xee\x17\xff\x1e\xee\x39\xba\xdd\x73\x88\xe7\xf0\x90\x90\x0f\xa0\x66\xba\xb5\x9b\x75\x47\x67\xf4\xee\x1c\xcc\x9e\x5b\x96\x6a\x1e\x59\x9d\xb9\x5e\x59\x32\x1f\x9a\x49\x9a\xd3\x44\xbb\xd0\x20\x56\x9b\xba\x51\xe9\x9f\x6f\x26\x7d\xa3\xb9\x09\x22\x18\xd0\xd9\x8d\xae\x97\x92\x98\xb8\x32\xed\x47\xd1\xc0\x07\xc0\x09\x66\x19\xf2\xa9\x16\x09\xc5\xfe\x11\xed\x7d\x77\x1f\x59\xc7\x02\xa1\x85\x26\x16\xc0\x77\x28\x3f\x87\xda\xbf\x54\x4b\x02\x3c\xf6\x4c\x6c\x48\xa6\x8b\x36\xd8\x5c\x8d\xac\x96\x54\x71\x3b\xf7\xdf\x41\x03\x58\x5a\xdf\xf1\x23\x48\x66\x89\x6b\x10\xd6\xf9\x02\x3f\x9b\xb7\x2a\xfb\xcb\xfa\x1b\x5d\x0b\xa3\x27\x41\x94\x87\x5c\x0c\x3d\x72\x2d\x53\x89\x61\x8a\xe5\x1f\xdb\xe5\x04\x4e\xa0\xa5\x0e\x2d\xc0\xc9\x5b\x52\xa8\x78\x34\x32\x5e\xb4\x8a\x95\x55\xb0\xac\x1f\xce\xed\x54\x43\x7f\x65\x34\x04\x14\xa5\x31\xf2\xdb\x1c\x2a\x80\x2f\x65\xf3\xa5\x3c\x57\xf5\x52\x9c\xd6\xc5\x77\xc8\xba\x46\x2c\x56\xd2\xab\xf0\x94\xb9\x5e\x96\xc7\xac\xce\xca\x7e\x51\x50\x8c\x02\xeb\x4b\xae\x6d\xc7\xd6\xaf\xbf\x60\xeb\xa1\x5a\xa5\xcc\xea\x69\xd7\xe2\x47\xa7\x72\x71\x2b\x1e\x38\x7a\x2b\x1d\x1a\x4e\x07\x00\x60\x57\x61\xe4\x8f\x1a\x85\x75\x6f\xad\x2d\xf4\x65\xf1\x7e\x3f\x48\x3f\x69\x08\x22\xc4\xf6\x20\xfb\x4a\x23\x72\x0b\x1f\xea\xcc\x48\x0d\x21\xe5\x43\x1d\x18\x04\x76\xdf\x5d\x9e\xa1\x6a\xbf\x4f\xe3\xb9\x53\xff\x0e\x90\x3a\x3b\xb6\x8d\x11\x58\x47\xf4\xdc\xba\x51\x85\xff\x00\x10\x04\x80\x70\xdc\x9d\xa9\xca\xe3\x8b\x28\xca\x97\xf5\xd3\x78\xb4\x41\x60\x52\x4c\x76\x15\xe2\x87\x95\xb2\x73\xbf\x93\x00\x12\xbf\x8c\x5d\xee\x60\x8a\xab\x05\xc2\x98\xb2\x7c\x8a\x99\xfa\x80\xe2\x41\x54\xc7\xee\xd4\x34\xc4\x81\x55\x98\xfa\xcd\x33\x96\x77\xc7\xa4\xcd\x19\xba\x78\x1b\x2a\x33\x15\x22\x9f\x2e\x90\x3e\xdc\x0d\x71\x10\xd9\xfc\xac\x83\x6b\xdb\x64\x66\xf8\xe7\x78\x42\x40\x1c\x28\x2c\x59\xc9\x6d\x70\xb6\x9b\x78\x10\xc7\xa0\x3d\x57\x63\xcf\xd7\x02\x31\xa5\xde\x20\xd8\x9c\x8f\x76\x1a\x22\x9d\xdf\xe9\x8c\x35\x6a\x70\xaa\xdf\xaa\xf2\x4d\x34\x59\x6f\x04\x41\xac\x04\xe6\x4c\x7f\x94\x0d\xfc\xf7\xb9\xac\x06\xa9\xea\x7e\x5a\x41\x6c\x2c\xe0\xf8\x24\x2a\xa1\x0e\xe7\xae\xe4\x17\x92\x10\x70\xc9\x75\x34\x4a\xad\x21\xe9\x4b\x17\x7d\x8b\x88\xf8\x53\x9b\x4c\x65\x27\x61\x6b\x3e\x4f\x93\x15\x08\x92\x24\x42\x3d\x8f\x63\xdb\x69\xdd\xe3\x25\x4c\x23\xeb\xd1\x67\x07\x99\x76\xeb\xd7\x43\xf6\xb3\x1b\x85\x90\xa8\x00\xf3\x07\xdf\xb3\x02\xaa\xcb\xeb\x09\x6c\x0d\xa1\x9f\x6d\x40\x03\xae\x1c\x9e\x1a\x39\xa4\x2c\xca\x79\x62\x2d\x02\xd5\x04\xfd\xe5\xf3\x68\x27\xec\x0e\xda\x6f\xdc\x58\x9c\xbd\x43\x29\xb8\x83\x2c\x20\xd0\x29\xb6\x39\x82\xbf\xcb\xfd\xb9\x3f\x1e\x6a\xfc\x60\x5e\x62\x67\xdb\xab\x60\x74\x4d\xe2\x08\x0d\x31\xcc\x6d\xe6\x13\x48\x08\xb0\x04\x02\x2f\x1e\xe8\x00\x76\x2e\xf5\x34\x69\x27\x43\xb4\x35\x1e\x5f\x1f\xae\x0b\xb7\x81\x47\x16\x81\x9e\x67\x18\xc4\x3a\x0f\xbc\xa5\x29\x72\x67\x08\xe8\x71\x19\x27\x48\x49\x92\xa4\xdd\x2a\x82\x60\xef\xae\x87\xd3\x48\x23\x80\xca\x1e\x43\x79\xdd\xee\x90\x8e\x91\x16\xfa\xcb\x45\x56\x99\xfe\x7b\x6f\x00\x44\xa8\xa8\x65\xbf\xbe\xbc\x16\xb6\x64\x48\x54\x17\x5b\x47\x37\xe4\xa1\xa5\x20\xe2\x28\xb0\xec\x64\x8b\xc7\x55\x88\xf5\xc1\xbb\xd5\xcb\xbd\xbf\xb3\x48\xad\x18\x59\x56\x0c\xd3\xc8\x20\xc0\x20\x5d\xeb\x52\xb4\xf6\x2b\x54\xb7\xcb\x82\xdc\x09\x32\xb1\x18\x89\xd5\xcb\xfd\xce\x41\x88\xa7\xa5\xc8\xa0\x62\x86\xa9\x31\xcb\xbd\xfb\x78\xcd\xd1\x3b\x5e\xcc\x41\xcb\x10\x3b\xcc\x45\xde\x6c\x71\xc9\x4d\xc7\x60\xd4\x3f\x5a\x11\x7c\xad\x6d\x3b\x9a\x2a\x71\x7c\x3d\x41\x31\x52\xed\xa0\x00\x44\x53\xbb\x42\x7c\x80\x7e\x9e\x53\x3c\x1a\x3f\x0d\x44\x02\xab\xb4\x8e\x22\x2b\xd6\xcb\xd7\x1e\x99\xea\x8e\x9b\x44\xe3\xea\xa7\xb3\x1f\x7f\x8c\x07\x95\x09\x03\xcb\x50\xdf\xae\x3a\x0e\xe3\x3f\x6d\x11\x2b\x94\x91\x6f\xdd\xe9\xd2\x66\xee\x37\xff\x39\x8b\x6a\x32\xfa\xe6\xf6\x00\x13\x72\x86\xd5\x91\x0e\x4f\xd3\xe7\x7a\xb6\xe5\x97\x3e\xbd\x62\x42\x2d\xd1\x32\x58\x9c\x9b\x03\x14\x0d\xb2\xf1\x8d\xa7\x86\x21\x5c\xc4\xc6\x23\x61\xdb\xa1\x14\x4e\x1b\x88\x24\xb5\x1c\x7d\xa8\xda\x30\xd7\x6b\xae\x65\x14\x28\x61\xeb\x69\x5a\x13\xa3\x5d\xf1\xef\xaf\xfa\x77\x38\x81\xfc\x69\x61\x12\x3a\x18\x59\x05\x35\x5c\x61\x5f\x26\x37\x21\x34\x96\x63\x6d\x54\xb7\x62\xcc\x7e\x42\x13\x51\x0d\x8e\xa8\x76\xf9\xf7\x93\xcc\x44\xa9\x44\xdb\x70\x83\x01\x7e\x07\xd6\xbf\x6b\x1d\x9e\xb1\xaa\x81\x6b\x1e\x6b\x0b\x26\x04\x9f\xbc\xea\xc9\xa1\x87\x5b\xa1\xa1\x24\x44\xde\xed\x53\x55\x1e\xcb\x61\x48\xc0\x50\x1a\x60\x0c\x50\xb6\x2e\xe6\x76\x50\xb8\x32\x35\x0d\xa6\x75\xf9\x86\x6a\xc0\xf2\xac\xf7\xed\x72\xf9\xba\x7e\x41\x62\xb0\x5f\x61\x9a\x0c\x0b\x52\xac\xf2\x2d\x2b\xa1\x72\x18\xd9\xc4\x86\x25\x80\xb5\x19\x48\x85\xfe\xe4\xf9\x04\xfb\x9b\x31\x65\x75\x9a\x0f\xa2\x7e\x2d\xa0\xdd\x34\x7d\xb5\x8e\xbf\x02\xa7\x80\xa9\x0c\xbc\xc2\x6e\xc8\x26\x35\xbe\x12\xe7\x96\x88\xee\x54\x7e\x92\x65\x69\x07\x95\xbf\x46\x1a\x31\xee\x92\xf7\xdf\xcb\x6a\x4a\xe0\x60\xd2\xc4\xa2\xd3\xeb\xa6\x3c\xb5\x16\xee\x6b\xd1\x9d\x28\xb9\xaf\x2f\xb3\xcc\xdc\x85\x29\x37\xd9\xbe\x10\xcd\xb9\xaf\x2c\x37\x29\x04\x16\x6e\x5a\x01\xe8\x75\xfd\x58\x96\xf3\x64\x88\xd4\xa4\x46\x47\xd6\x26\xae\x9b\x6f\x65\x03\xbf\x8d\x8a\x3e\x5d\x23\xc9\x14\x1b\xd7\x68\x62\xce\xbf\x7e\x28\xab\xd7\xd6\x2e\xd9\x20\xa9\xcc\x8c\x1f\x65\x54\x12\x21\xff\x02\xfc\x6c\x7a\x2a\xc8\xbb\xb2\xd0\x03\xb0\xb0\xd1\xcc\x3a\xc8\xcf\x42\x95\x5b\xa8\x07\x8a\xd0\xed\x31\x19\xda\x14\x34\x5a\xe2\xdf\x21\xb3\x49\xca\xd1\xf7\x86\x30\x45\xc8\xb6\x29\x2b\x05\xef\x60\x39\x4c\x7a\x7c\x8b\x81\x08\x90\xf3\x3a\x6b\xe0\xf8\x22\x8e\x30\x2c\x23\xe8\xbb\x02\x62\x06\xb2\x2b\x2c\xbd\x2b\xcb\x1c\x44\xb1\x46\x45\x59\xd0\x03\x1f\xc3\x00\xb7\x95\x1d\x7b\x68\xbe\x94\x55\x0d\x1b\x97\x60\x18\x5c\x4a\x03\x73\xf4\xc7\x58\x70\xb9\x73\xe1\x92\x1d\x14\x7a\xa7\xaf\xd7\x26\x00\xab\x9e\x87\x55\x3f\x9f\x6f\xb6\xc6\x64\x48\x00\x60\x00\x38\x6e\x41\xcf\x59\x01\x58\x42\x85\xba\x24\xfe\x05\x4d\xa8\x31\x2f\xf0\x2c\xb2\xfc\x80\x44\x6d\xd3\x52\x41\x63\x38\x43\xe1\xed\x6f\x7f\xbe\x2f\x9e\x76\xef\xab\xef\x8b\xf7\xfb\x4d\x77\x50\xda\x22\x5d\x23\xb2\xfc\xec\xc9\xef\x58\x10\x10\xe3\xb5\xeb\xee\xc4\x34\xe4\xcf\x82\x20\xb5\xd1\xb5\xd5\x9f\xcb\xea\x72\x6a\xca\x6d\x25\x74\x56\xec\x1f\x5f\x9f\xee\xfd\x15\x42\x95\x60\xda\xc4\x9b\x6f\xcf\xa2\xda\x67\xc5\x5b\x65\xa9\x52\xf5\x17\x51\x1f\x86\x95\xf1\x7f\x13\xfe\x19\x8d\x5d\x16\x84\xc6\x56\x30\x23\x7b\x69\x01\x9f\xbe\xda\x77\x51\x68\x44\x8f\x95\xe7\xfd\xa1\x1d\xd3\xb5\x7f\x1a\x22\x39\xc2\xf5\x50\x1b\xa4\x3a\xb6\xf3\x1b\xbc\xf9\xcc\x82\x28\xb6\x46\x9c\x23\x53\x5f\xe6\x65\x7d\x83\x93\x9f\x05\x71\x12\x21\x94\x5e\xf4\xba\x00\x43\x86\x34\x16\xc4\x69\x8c\xe9\x90\x23\xe8\x4c\x14\xfe\xd7\x24\xb0\x98\xdd\xae\x3b\x4a\x99\xe5\x80\x02\xbd\x13\xc9\x57\x16\x24\x92\x22\x44\x12\xa1\x61\x77\xe5\x20\xe4\xf3\x3f\x3c\xfc\x5f\xd7\x88\x46\x29\xaa\xd3\x1e\x44\xa1\xcb\x1f\x37\x14\x44\x59\xc0\xa2\x18\x73\xcb\x22\xcf\x54\x39\xd2\x73\x63\x01\x62\x7b\xd1\xe3\x5d\x17\xad\x25\xf1\x2c\x3e\xc6\x5c\x75\xbe\x5d\x6a\xb0\xdd\x9f\xe5\xa1\x1c\x5f\x40\xd9\xa2\x83\x1a\x9a\x5d\x3b\xe2\x76\xe5\x5c\x55\x54\xbf\x2a\xb0\x80\x01\x41\xb2\x21\xdf\x0d\xed\x4e\x6e\x35\x80\xc6\xbd\xcc\x93\x00\xf9\x79\x9d\xcc\x89\x2b\xba\x9a\x3c\x17\xa7\xb1\x70\x41\x93\xd9\xc7\x9f\x0d\xcc\xb6\xa7\x59\x85\x22\xa1\xb5\x55\xe8\xeb\x7a\x77\xa8\x69\xdc\x6f\xdf\x2c\xe0\x32\x46\x1a\x2b\x63\xb3\xae\x5d\x11\xa7\xcc\x2d\xde\x95\xf8\x0e\xe1\x10\x11\x97\x3d\x15\xbf\x08\xc0\xb5\x0d\x63\x0f\x95\x78\x39\x1f\xaf\xfc\xd1\xb6\x81\x40\xac\xd8\xfb\xeb\xd3\x6a\xb7\x5c\xbd\xfa\x3b\xa4\x4c\xe2\x82\xd6\x8e\x7c\xa8\xde\x01\x8a\xa6\xea\x76\x97\xf6\xb0\xc1\x7e\x43\xa9\xcb\x19\x13\x92\x05\xa9\x54\x8c\x0f\xca\xc2\x67\x14\x64\x58\x90\xaa\x40\x47\x5d\xed\x50\x27\x63\x3b\x7d\x48\x01\x96\x96\xd1\x86\x81\x86\x96\xc4\x6a\x52\x06\xce\x02\x49\x42\x1b\x6e\xc6\xac\xff\x20\x0a\xc1\x02\x99\xc4\x61\x3c\xce\x41\x8a\x46\x74\x47\x79\x80\x44\x69\x6e\x71\x6e\x1d\xe7\x1a\xb6\xe5\x56\x54\xfb\x7e\xd2\x49\x2e\xd0\x58\x74\xc5\x01\x97\xe7\x52\x83\xd3\xbb\xf5\xbe\x22\x0b\xa4\x4c\xb1\x50\xd7\x81\xac\xee\x2b\xf1\x89\xa5\x82\x53\x0f\x68\x26\x90\xc2\x02\x95\x58\xc5\x6c\x5f\xe5\xf4\x26\xaa\xaa\x9c\x0e\x5b\x45\xa5\x86\x2e\x9b\xb1\x6e\xe0\xf8\x64\xa5\x1c\x86\x95\x68\xff\x9a\x9e\xa3\x30\xa8\xd9\x8e\xaa\xf6\x91\xde\x2a\x78\x28\xab\x8f\xe5\x21\xcb\xf5\xfd\xa2\xfb\xf0\x4a\x03\xf2\x01\x2c\xbb\xef\x26\x8e\xa7\x7c\xb4\x1d\xb2\x40\xd3\x18\xeb\x53\x9f\xca\xfd\xd3\x0c\x94\x7e\x72\x67\x4d\x2d\x4d\xe3\xae\xdd\xdd\xab\x23\x4a\xba\x9f\x81\x4f\xde\x49\x73\x60\x29\xaa\x15\xdd\xbf\xef\xb6\xbf\x3f\x0e\x68\x06\x59\x00\x51\x18\xb8\xb8\xab\x4b\x41\x0c\x6d\x2e\x16\x40\x0a\x98\x3a\x6c\xc4\x07\x20\xb6\xbe\x52\x87\xc9\x58\x03\x01\xd2\x96\x01\x16\x7a\x87\x1f\x7e\x06\xd8\xc6\x02\x90\x89\x8f\xcc\xef\x72\x21\xc1\xc5\x58\xc2\x31\x48\x80\x05\xc6\xc9\xfb\x99\xac\x82\x25\x7a\x64\x7e\x73\xb0\x7c\xff\xf3\x1f\xc1\xa4\x06\x2d\x00\x95\x5f\xd4\x47\x03\x55\xe6\xf5\xac\x58\x60\x20\x4c\x62\x2f\x49\x84\x86\x92\x3d\x10\x06\xa9\x44\xcf\xdc\xed\xf0\x36\x4e\xe3\x2d\x59\x32\x43\x6d\x37\x91\x52\x66\x61\x60\x48\x6a\x3c\xb9\x8b\x35\x5c\x1e\xca\x6a\xbd\x7c\x9d\x35\xf4\x59\x18\x26\xca\x32\xc2\x01\x68\xac\x23\x5c\x59\x29\x0f\xff\x44\x84\x13\x34\xb4\x5d\x4a\x67\x18\x66\x60\x21\x49\x19\x16\x1c\x5c\x93\x78\xfd\x93\xd4\x0b\x0b\x89\x50\xbe\x9e\x7a\x71\x57\x4c\x85\x00\x59\x48\x14\xc7\xb4\x72\x9d\x8b\xe3\x11\xaa\xe1\x73\x45\x0e\x4d\xb8\xb7\x75\x71\x42\x35\xf5\x13\x14\x7b\x0f\x55\x6e\x1b\x88\x60\xc2\x14\x19\x8e\x98\x22\x59\x18\x53\x82\x9b\xd0\xae\x80\x9f\xcd\x50\x9a\xa6\x7f\x82\x24\xe6\x28\xc1\x80\x1a\xdc\x0e\xd7\x35\x87\x24\x61\x21\x0d\x88\x61\x13\x0e\x86\xf1\xb5\x68\x6a\x2c\x2d\xb7\xc8\x8a\xfa\xd5\x8c\xf6\xa8\xf1\x5a\x1e\xb2\xd8\x26\xcb\x2c\x11\xcc\xf2\xfd\xf5\xfb\xfd\x66\xe1\xf5\x49\x59\xc8\x49\xe4\x0b\x71\x1f\x60\xbe\x9c\x80\x85\x5c\x01\x6a\x65\x9f\xd0\xb9\x4a\xfc\xb9\xa9\x49\x98\x9d\x1b\xa0\xe1\x67\x7c\xed\xfc\x5c\xb9\x77\x2c\x14\xc4\x16\x58\xb4\x9d\x9d\x35\x4e\xb8\x48\xb5\xae\x86\xeb\xf3\x71\xeb\xc8\xee\x33\x8d\xf8\xd9\x87\xb5\x58\x28\x94\xc1\x2f\x66\xf2\xb3\x31\x97\xa5\x68\xba\x64\x38\x0b\x85\x0e\x3c\xdb\xea\x23\x14\x50\x67\x37\x36\xb9\x50\x68\x1a\x25\xfd\x67\x87\xa2\x59\x56\xb7\xec\xaa\x50\x05\x31\x2e\xce\x0b\x9f\xeb\xff\xe5\xda\x15\x2a\x62\x0b\x02\xda\xd1\xb0\xab\x9b\xb2\x80\x5d\xe6\x17\xfa\x50\x45\xe0\x2b\x39\xbe\xd9\xf5\x77\xd1\x34\xa8\x52\x68\x29\x9c\x6f\x5c\x92\x09\xe4\xca\x38\x94\xcd\xe7\xb5\xc2\x08\x0b\x95\x04\xb4\xfc\x50\x47\xba\x37\xd3\x27\x2f\xad\x20\x49\xbc\x50\x33\x9a\x43\x56\xb5\x69\xd4\xe9\x9a\xc9\x98\x75\x44\xbc\xa0\x7b\xea\x33\xdf\x20\xd5\xb8\xb4\x80\x2a\xeb\x4b\xdd\xc0\xb1\xdd\x5b\xd5\x60\x2f\x0b\x21\xb6\x85\x41\xb8\x83\xad\xb6\x5f\x3c\x41\xae\x3f\x0c\x80\xe5\x0d\x06\x39\x5d\x6c\x87\xf6\x66\x58\x68\x40\xb2\x9e\xec\x56\x65\xe5\x44\x14\x83\x85\xc6\x04\x98\x37\x10\xee\xc6\x45\x59\x2c\x37\xbf\xa0\x1b\x63\x24\x20\x69\x22\xbc\x0e\xef\xfa\xe5\x71\xb7\x7c\x5a\xac\x9f\x2d\x3f\xdb\xee\xfb\x6a\xfd\x9b\x6f\x07\x2c\xee\xb1\x52\x1b\xab\xef\x3c\xff\x49\x48\x98\x28\xef\x2c\xbf\x4a\xc4\xc4\x0d\x15\x9b\x18\x09\xd3\x54\xb8\x85\xe5\xbf\x4a\x79\xe3\xc1\x08\xb5\x62\xa1\x59\x8d\x98\xf4\x06\x65\x9d\xe6\x38\x0a\x18\x21\x9c\x62\x9c\xf3\x3f\x67\xa8\x2e\x64\x3e\xd2\x30\x9a\x6d\x84\xe8\x00\xd9\x5c\x6c\x3c\x04\x5f\x69\x9e\x16\x80\x91\x28\x04\xda\xa9\x53\xd6\xbb\xba\x0b\x62\x31\x12\x45\xe0\x8b\xc1\xb6\xe5\xe4\x99\x22\x20\xc8\x80\xb5\xa8\x86\xd9\x28\x46\xe2\x50\x24\xc6\xe9\x9c\x55\xf7\x62\x22\x99\xc6\x48\xcc\xed\x70\x45\x2f\xc2\x97\x98\x0d\xf3\xd3\x8c\xc4\x52\x4b\xb7\xff\x58\x20\x67\x97\xbf\x18\xa1\x50\x5d\xeb\x24\xa0\xb8\x03\xff\x9f\x85\x1c\x3f\x54\x62\xc0\x2e\xcd\x48\x12\xa5\x98\x0f\xba\x7f\xb3\x8f\x79\x3b\x4c\xc3\x48\x42\x39\x8a\xfe\x36\x07\xf1\xf9\x98\x97\x52\xe4\x3e\x2c\xd4\x3d\x1b\x75\x31\xb9\xef\xeb\x97\x97\xd5\xbb\x15\x49\x7c\xff\x73\xb7\x7c\xbd\x5f\x75\x4d\x24\x78\x2b\xd5\x26\x74\x07\x43\xbc\xe3\xa8\xed\x20\x79\xb6\xe2\x7b\x2e\x73\xcd\x08\x27\x12\xf7\xae\x53\x99\x5f\x8e\xa2\x39\x74\xe5\x99\xfe\x78\xc2\x6c\x80\xb0\x5e\xab\xd2\xd7\x29\x75\x5f\x8f\xb3\xc4\x82\x07\xcb\x42\xf4\x71\x94\x49\xee\x76\x7c\xbf\x54\x26\xee\x7b\x3f\x83\xce\x5c\xe6\xc5\x77\x34\x57\x0c\x67\xd2\x53\x29\x8a\x77\x38\x89\xec\x5a\x43\x7d\xce\xb4\x27\xdc\xc4\xb8\x26\x6a\xa8\x9b\xaa\xbc\xbc\x97\x72\x6a\xa0\x12\x11\xf1\xc8\xaa\x58\x5b\x4a\x88\x2e\x99\x9a\x89\x6b\xfc\xcb\xe8\xe2\x92\x59\xe5\xbf\x3d\x34\xdb\x9f\xaf\x55\xb6\x7f\x56\x9f\xbd\x34\xf9\x70\x77\x25\x52\x29\xb4\x18\xef\xe1\xe7\x62\x0f\x7d\xdd\x22\x23\x2a\xe4\x88\x89\xf1\xe8\xf5\x4d\x03\x79\x2e\x66\xeb\xf6\x19\x51\x34\xe1\xce\x47\xfa\xb6\x7e\xbb\x2b\xcf\xc5\xb9\x7e\x9f\x46\x50\x18\x51\x92\x50\x0b\x3a\xb3\x88\xc9\xd5\x7f\x66\x84\x10\x19\x01\x6a\x02\xc7\x75\x95\x15\x7b\x6f\x13\xfe\x36\x29\x5f\x1e\x3f\x81\xd1\x0a\xe5\x9f\xdb\x95\xc3\x81\xed\xca\x6a\x5d\x3c\x5d\x7b\x4c\x51\x10\x44\x5e\x93\xde\xaa\x30\x58\x89\xb5\x19\xcf\xd2\x9f\x10\x5b\x09\x77\x44\x9a\xfc\x80\x7a\x2a\xbf\xcc\xa2\x90\x28\xed\x09\x1c\xce\x79\x93\x0d\x74\x45\x66\xae\x17\xf2\x08\x9c\xfa\xc1\xea\x78\x6a\x2e\x4f\xa5\xba\xa6\x86\x61\x51\xa8\x34\x06\xcc\x16\x4a\x4d\x6e\x47\x24\x11\x71\xcf\x3f\xb3\xac\x2e\x35\x66\x7d\x3f\xc5\x24\xd7\xd4\x36\x8d\x30\x52\xfa\x96\x15\xcf\x65\x6b\x4f\xfa\x45\x20\x8a\x92\xc4\xae\x28\xaa\xca\x4e\xcd\x00\x6f\xc4\xa2\x88\x69\x5c\x86\x9b\xba\x67\xb5\x60\x51\x64\x08\xc6\xe6\x2b\xcb\x32\xdd\x6e\x07\x03\x75\x03\x16\xc5\x51\x1c\xb8\x7e\xfd\xfa\xfe\x34\xda\x46\xa3\x58\x0b\x44\xdd\xbe\xc0\xe7\x9b\xa8\x6b\xbf\x00\x96\x7f\xcb\xb5\xef\xcf\x87\x28\x75\xd7\xc6\xf2\xb8\x6b\x71\x28\x16\x25\x51\x68\x3a\x4d\x1b\x44\x65\xdc\x9d\xab\x0e\x8a\xc5\x22\x1a\x13\xf4\xa1\x1a\x51\x7f\x5c\xe1\xbf\x59\xc4\x48\x88\xb8\x8f\x0a\xa5\xa3\x40\x2f\xbf\x2f\xad\x1f\x3b\xbf\x57\x45\x8c\x10\x4f\xca\xd5\x57\xed\x8f\xf9\x4e\x58\xc4\xc3\x00\x65\x27\xbe\x65\x55\x53\x16\xe5\x31\xf3\x0f\x93\x06\x06\x67\xcc\x0e\x0a\x0b\x62\xac\xe7\x60\x47\xac\x5d\xa8\x9d\xfe\x4e\x59\x77\xb2\x4b\x2c\x4a\x85\x2d\x5c\x3d\x8a\xea\x63\x51\x6f\x94\x38\x4e\xbe\xbb\x08\xad\x2b\xe4\x53\xfe\x96\x30\x61\x08\x0d\x61\x91\xe0\x96\x81\xf8\x8b\x70\xec\x99\x8b\x11\x66\x69\x66\x6a\x46\x42\x2b\xe6\xf2\x48\x6e\x5b\xde\x34\x70\x1a\x2a\x40\xb0\x48\x26\x12\x41\x5b\x47\xf1\xd3\x26\xcc\xea\xee\x08\x27\xc2\xb1\xbf\xbc\x61\x9a\xe9\xca\x9f\x1f\x77\xb1\x4c\x6d\xc9\xe3\x2e\xb7\xa8\xfd\xd6\x92\x7b\x29\x37\x53\x9c\x31\x8b\x54\x64\x70\x91\xbe\x7f\x7b\x1b\x6e\xbc\x91\x4a\x02\x24\x7d\x47\x62\xfd\x42\x5d\xba\xdf\x79\x8c\x51\x44\xf8\x09\xea\x06\x9c\x72\x7c\x03\x1d\x45\x88\xd8\xea\x54\x51\x0a\xbd\x14\x79\x2e\xc5\x35\x18\x6b\x18\x8e\x8a\xb4\x48\x30\xe1\x78\xff\xf8\xef\x1e\x4b\x87\x79\x8a\xf9\x41\xa5\x95\x4c\x3b\xb8\xec\x74\xa3\x8d\xb4\x91\x68\xe9\xed\xe0\x67\x03\x85\xf5\x2b\xfd\x31\x08\x62\xe1\x08\xe4\xc9\x12\xb2\x3c\x2b\xf6\xbf\x8d\x2e\x0d\xa1\x05\x02\x19\x64\xf5\x3a\xf7\x95\x74\x61\xd7\x82\x58\xe5\x56\x1b\x73\x79\x2a\xd5\x87\x2c\x7f\x4e\xf7\xc8\xf9\xa4\xe7\xe4\x5f\xbf\xf6\x8d\x46\x0f\x70\x19\x78\x55\xb8\x3e\x5e\x12\x01\x24\x38\x2c\xc0\x56\x6b\xed\x9a\x91\xf4\x4d\x7b\xdc\x60\x1d\x4b\xdd\x94\xa7\x21\xc3\x12\x8b\xc0\x84\x18\xfb\xae\xb1\xf2\xa7\xff\xd5\xea\x24\x5b\x7b\x16\xd5\x90\x37\xab\xe5\xab\x4f\x39\xb3\xc8\xc4\x1c\x37\xc8\x95\x2a\x4f\xa2\x1b\x14\x26\x01\x5c\xc4\xf7\x43\x29\xb1\xf1\x0b\x18\x46\xa9\x93\xbf\x54\x50\xd7\xed\x5e\x87\xf4\x14\x37\x62\x15\x91\x31\x09\x4a\x32\x3d\x95\xfb\xe7\xa1\x49\x73\x43\x52\x70\x5c\x27\x48\xf8\xe8\x3f\xb5\x19\x7e\x16\x07\xc6\xa2\xc0\x8e\xcd\x24\x03\xcc\xe2\x30\x50\x41\xe4\x01\x62\xed\x07\xd4\xfd\x82\x1f\x87\x24\xc0\x78\xe4\x11\xaa\xfd\x64\x67\x8e\xc3\x88\xf8\xfa\xe5\x4e\x91\x76\xd6\x73\x8f\xc3\x34\xc0\x05\xa9\x3e\x94\x9f\x56\x87\xa2\xcc\xaf\x38\xaa\x7d\x5b\xa1\x11\x1b\xd4\xba\xca\xbb\xbd\x8f\x43\x70\x7f\x54\xc6\x98\x0b\x1d\x2e\x4d\x0f\x55\x79\x6c\x3d\xe8\xe9\x4d\x8d\x4a\x6c\x3f\x36\x4d\x39\x74\x2b\x62\x02\x1a\xb3\x05\xeb\xe7\xc5\xfb\xef\xfe\xc7\x28\x05\x6b\x5d\x95\x7f\x96\xe7\x6a\x3b\x97\xbd\x70\x2d\x63\xca\xf0\xbd\x35\x16\xd0\xe0\x2e\xfc\x6a\xe6\x3d\x9c\x38\x89\x34\x46\x22\x56\x3f\xfd\x7d\x12\x1d\xc9\xb0\xc7\x87\xa1\xf7\x38\x7f\x1f\x1a\x52\x4c\x68\xfa\xa1\x8d\xd9\x21\x8c\xe1\x6d\xcb\x3b\xd1\x34\x39\x58\x7a\x19\x3b\x1f\x27\x37\xa6\x91\x35\x41\xf7\xd0\xac\xf6\xfb\x7a\x5b\x7e\x11\x8d\x3a\xdc\x57\x62\xdf\x99\xf4\x31\x65\x61\xda\x93\x43\x7d\x83\xba\x77\x40\x63\xca\x13\xf4\xb1\x97\x6f\xaf\x3b\x94\x1f\xe9\x0e\xa4\x84\x39\xaf\xbf\x93\x00\x1e\xae\x9f\x31\x23\x92\xba\xfa\x0d\x8c\x99\x2d\x3d\x75\x07\x8b\x99\x4a\x31\x0c\xa2\x7a\x47\x6d\xf2\xd1\x38\x91\x9e\x4e\xe7\xde\x23\xf5\x1f\xa0\x1b\xab\x5c\x06\x18\x30\x41\xa6\xf5\x97\xed\xfd\x64\xec\xa4\x9a\xfa\x11\xb9\xf6\x6c\x50\xd3\xaa\x26\x16\xa7\x40\x53\xb7\x09\xfb\x32\xec\x2b\x78\xc6\xc8\xe2\x8d\x05\x8d\xb0\xaa\x78\x79\xbf\x19\xbd\xaa\x48\x99\x4f\xa3\xb9\xc8\xf6\x56\x8c\x37\xb6\x58\xb2\x50\x77\x30\x2a\xcc\x70\x76\xd4\xb5\x70\x93\x27\xcf\x9f\x2b\x8c\x36\x1d\xe4\xf7\xb9\xeb\x05\x2d\x05\xd6\x47\xb4\x53\xa4\x97\x50\x66\x31\x70\x8e\x8b\xd1\x41\xd4\x5f\xf1\x14\xd4\xf6\x10\x75\xdd\x7f\x56\x70\xa6\x1d\x9a\x06\x73\xd6\xf1\x3c\xf9\x33\x8b\x0d\xe3\x98\xf8\xdc\x1c\xb2\x66\x48\x8a\xc3\x92\x80\xc5\x58\xcc\x80\xd4\xc6\x0f\x16\x43\x78\x45\x52\xcf\x92\x40\x12\x1c\xf7\xbb\x1d\x72\xad\x09\x9d\x67\x13\x91\x1e\x96\x84\xb1\xd5\xbd\xad\x26\x4a\xdc\x93\x56\x8c\xd1\x64\x40\xf5\x6d\x0d\xf2\x6b\xc6\x2f\x96\x90\x90\x13\x0c\xdd\x69\xfd\xee\x75\x17\x3d\x9e\xe6\x3a\x7b\x95\x90\x58\x60\x51\xe0\x27\x34\x87\x2b\xc8\xf2\xe4\xca\x2c\x16\x83\xec\xb5\xdb\x61\x46\x5d\x96\x44\xc4\x60\x05\x21\x3e\xa4\x4d\x3a\x3a\x79\x4c\xbf\x39\x27\x11\x28\xb4\x35\xb2\x62\x67\xeb\x56\x6d\x9c\x68\x77\xea\x89\x94\x59\x12\x93\x30\x8d\x07\x0a\x60\xdb\x8e\xc1\x12\x69\x2f\x07\x2f\x10\x47\x41\xe2\x70\x82\x5f\xdf\xd7\xdd\xf9\xa0\x90\x66\xec\x7b\x56\xf4\x09\x78\x96\x24\x22\x30\x16\xa7\x54\x97\x39\x96\x19\xfd\x73\x52\xe5\x19\x33\x2f\xa1\xca\xea\xef\xfa\xe5\xea\x17\xd2\xe7\x2c\x61\x46\x25\x7a\x84\xfe\x7b\x3d\xf5\x43\x8a\x4b\x8b\x6a\x3d\x8a\x9f\x77\x55\xa6\xf7\xf0\x3d\xd3\x5d\x34\x39\xe1\x2a\x46\x65\xc1\xff\x9c\x33\xf5\x31\x2d\x0d\x61\x09\xd7\x71\xc0\x5c\xe8\x70\x59\x1e\x8f\x65\xb1\xdd\x7e\x77\xfb\x92\xcf\xe4\x25\x69\x98\x58\xf7\xac\x81\xd3\xf6\xb3\x1c\x07\xda\x93\x94\x53\x8c\xbe\x6d\xff\x3d\xec\xb0\x34\x0d\x08\x1d\xa2\x8c\xdb\x8d\x02\x97\x60\x32\x79\x04\x41\x12\x88\x06\x23\xd4\x5f\x41\x70\x93\x58\x34\xe1\xdd\x65\x40\xa1\xe3\x8f\xea\x84\x30\x17\x93\xfb\x9c\xdf\x13\x12\x61\x52\x5c\x12\x9e\x91\x25\xec\x3d\xdb\x3f\x88\xea\xd8\x59\x3d\x89\x4c\x95\xf7\x2f\x30\xab\x37\xc3\x90\xc8\x12\x15\x05\x88\x26\xd5\x70\xca\x4b\x6f\xc9\x24\x2a\xb6\xac\x13\x68\x45\xb6\xd3\xb8\xdd\x00\x67\xd7\xa5\x44\xbb\x51\xfb\x01\x4a\x89\x0f\x7f\x01\x88\x38\x6e\x75\x2f\xaf\xbb\xe7\xd7\x97\xcd\x76\xf5\xde\x1d\x91\x16\xb5\x53\x23\x34\x60\x32\x4b\x00\x22\xa4\xa0\xfd\x91\xc1\x67\x42\xfd\x29\x26\x01\xd5\x6b\x99\xbd\x67\xcd\x79\x22\x47\xc9\x12\xc3\x2c\x5b\xb0\xd0\x7a\x53\x1e\xe1\xeb\x6a\x5b\xf7\xc1\xb5\xc9\x13\x1b\x15\x62\xd7\x96\x1e\x40\xea\xee\x43\x83\x54\x60\xea\x57\x79\x01\xad\xa5\x28\xee\xe0\xdd\xaa\x6a\x4d\x1e\x95\x06\x5a\xe0\x86\x3c\x64\x75\x99\x7c\x44\x1a\x06\x52\x38\x44\xcd\x7d\x99\xe7\xa2\x9a\x1e\x67\x96\xda\xe9\xee\x7c\xd9\x96\x97\xe7\xb2\x00\xff\x05\x68\xc8\x63\xd9\xa1\x1e\xca\x02\x90\xdc\x6d\xf5\x9f\x61\xa1\x28\xca\x64\xe1\x64\x36\x65\x35\xf4\xdc\xe7\xd9\x18\xfe\x75\xad\xde\x86\xb2\x55\x48\xb4\xe6\xa7\xde\xaa\x39\xb4\x16\xd4\x88\x61\x84\x51\xc2\x6c\xe2\xe0\xb1\x3c\x37\x3d\x0a\xe6\x76\x5e\x82\x12\x6d\x70\xe7\xfe\xf6\xed\xfe\x6e\xfc\xa5\xda\x43\xb8\x43\x9c\xca\x06\x8a\x26\x13\xf9\xa0\xda\x89\x51\x62\x82\x98\x8e\xd5\x7c\xed\xa4\x9f\xab\x67\x60\x34\x0e\x4c\xa7\xdb\xd8\x7e\x85\xf9\xa2\x62\xdf\x58\x5b\xa9\x65\xac\x43\xac\xed\x7a\xe9\x0f\x19\xe6\x79\x5f\xef\x84\xfa\xb8\x7b\xb9\xf3\x47\x92\x88\x60\x96\xf7\xe5\x7c\x14\xdd\x6f\x2a\xf1\x85\xc7\xce\xd6\x1d\x93\x0e\xbb\x66\x94\x51\xdc\xed\x0b\xf8\x7c\x5f\xce\xcf\x1e\x4a\x53\xe9\xd4\x64\xdb\xe5\xe9\xd4\xc0\x2e\x8a\x46\x81\x0f\xca\x40\x29\x1b\x46\xdb\x68\xf5\x50\x56\x16\xe9\xfe\x37\xe9\x3c\x77\x2e\xd7\x76\xe2\xb8\x82\xa3\x1e\x1d\x8b\x94\x45\x91\x43\x98\xdd\xcb\xc9\x83\xa7\xa9\x08\x68\x3f\xb4\x91\xa3\x02\xf4\xe6\x53\x9c\xe6\x53\x6c\x34\xd5\x11\xb7\xac\x11\x3f\xca\x0f\x58\x14\xda\xc9\xb0\xdd\xaa\xf1\x1e\xaf\x63\x34\x05\x11\x38\x05\xf4\xd6\x19\x98\x3c\x8d\x08\x9c\x33\xe6\x92\xf1\x43\x7b\x83\x0a\x49\x23\x0b\xe6\x46\xda\x8f\x51\x34\xda\x35\x91\x11\xc3\x4c\x21\xe8\x6c\xa8\xe2\x3c\x1b\x2d\xa1\x92\x5a\x8a\x54\x24\x6f\xad\x95\x98\x1f\x76\xd2\x11\x90\x9f\x32\x50\xe0\x77\xe0\x6b\x62\x92\xc9\xb5\x55\x64\x03\xcf\x35\xc2\xbf\xda\x8f\x51\xcf\xe9\xff\x30\xaa\x43\x11\x38\x64\x89\x43\x3e\x4c\x8e\x53\x97\xfa\x2d\xeb\xce\x7a\xa0\x9a\xa7\xd2\x12\x9a\xe6\x56\x79\x61\xdc\x0b\x5a\xda\xca\xa8\x6f\x59\x69\xc3\x7c\x88\xaf\x1c\xf5\xa5\x36\x01\x61\x03\x0d\xd9\xfb\xac\x2e\x3f\x8b\x97\xb2\x19\xcd\x50\x60\x46\x85\x7e\x16\xbd\x83\x96\xe7\x3c\x47\x49\xb2\xc9\x43\x9a\x48\x22\xfc\x5a\x9e\xab\xe2\xee\xe2\xd4\xc6\x7c\x29\xcb\x90\xf8\x8e\x51\x93\x52\x8c\x14\xbf\x01\xd2\xa9\xfa\x3b\x19\xcd\x7c\xd4\x74\x55\xab\xaa\xfc\xbc\x65\x86\xf5\xeb\x5c\x67\xfd\xb0\x20\xd2\xc4\x8d\xef\xbb\xf3\xc5\x42\x85\xf0\x9e\x81\x6f\x20\x35\xb2\x62\xb6\x17\x1e\xe0\xc6\x31\x61\x81\x4b\xe2\x63\x05\xd0\x51\x43\xb7\x3f\x4b\xee\x90\xb4\x0f\x0f\x1d\xf3\xf4\x3f\x9a\x87\x18\x8a\x0f\x1c\xf8\xca\x29\xdf\xde\x92\x82\x63\x8c\x48\x11\x30\xcf\x42\x9c\x8b\xcb\x3c\xb9\x1e\x63\x11\xb7\xba\x13\xad\xb1\x79\x43\xfb\x68\x72\x46\xac\x22\xb4\x1d\xb3\xfa\x05\x54\x55\x1e\x51\x23\xe1\xb7\x49\x1b\x4d\x31\x63\x87\x44\x6d\x18\xc6\xb1\x7d\xe7\x0f\x43\x8a\x9e\xa4\x8d\xf0\x7c\x2d\x26\xf5\xe3\xb8\x85\xab\xd4\xe7\x81\x71\x41\x23\xa9\x3f\x99\xc6\x96\xf4\xe0\x64\x63\xbf\xc3\xc1\xc7\x28\x4d\xe4\xd0\x60\x44\xb6\x84\xa6\xf4\x98\xe8\xdb\x3d\x3d\xdf\x89\x2c\xd2\x98\x64\x13\xae\x3c\x66\xcc\x74\xec\x6f\xca\x18\x47\x4c\x06\x66\x79\x6f\x75\x9e\x37\x95\x18\xd3\x01\xb7\x68\x7b\x8c\x25\x76\x97\x54\x5d\x9d\x0d\x63\x3c\x09\xd0\x6b\x38\x89\xcb\xc2\x34\xb7\x3c\x06\x96\x06\x01\x82\x86\x1d\xdd\x9f\xa8\x32\x4b\x53\xdc\x6e\x22\xc3\xd5\x9f\xa5\x49\x22\xfb\x86\x5e\x84\xe8\xf1\x3c\xe9\xf5\x54\x06\x18\xc4\xd8\xc9\xf3\x65\x6c\x89\xfc\x6b\x94\xb7\x1e\xaf\x48\x4c\x24\x5a\x61\xea\xf9\xe7\x29\x2f\x35\xbc\x1d\x4a\x28\xb2\x9f\x93\x6b\x0b\x69\xd9\x55\x8e\x1f\xbb\x4e\x5e\x64\x0a\x78\x9b\x9c\xa1\xa2\xb8\xab\x20\xf9\x9e\x75\x39\x48\x26\x1c\xea\xda\x81\xb2\xb6\x15\x4c\xc5\x68\x26\x17\x32\x06\xed\x23\xfb\xf6\x5f\xb2\x1a\xcb\x79\xe6\x6f\x2a\xe3\x04\xf3\xec\x43\x65\xbf\xf9\xb7\x56\xa1\x44\x5c\x22\x94\xf5\xd3\x7a\xbb\xba\x31\xbd\x14\x4d\xb8\x19\x98\xed\xf7\x65\x31\xac\x36\x62\x4c\x1b\x13\x8b\xc1\x88\x5d\x6e\x5f\xc7\x4b\x20\x83\x98\xa5\x5e\xee\xbd\x3c\x17\x1a\x63\x36\x2e\x82\x3e\xbe\x19\x50\x19\x3a\x8b\x62\x55\xa0\xcc\x9d\xb6\x22\x4a\xfe\x38\x27\x58\xf9\x74\x57\x96\x1f\xb8\x70\xaf\x9a\xc3\xb7\xf0\x14\x76\xc7\xd3\x18\xad\x78\xf8\xa9\xa0\xf6\xe4\xdf\xf3\xfd\x04\xca\xc2\x01\x9e\xca\xfd\x5b\xbb\x65\xea\xee\x1a\x0a\xec\x0c\xf4\x3a\x36\x96\xb9\xa7\x9f\x2d\x26\x8d\xc9\x4c\x96\x75\xba\xc7\x8f\x6f\x67\xc0\x18\x8f\x0b\xe9\x36\xdf\xac\x2c\xee\xe5\xa2\xe9\x49\x5b\xba\xf6\x3c\x10\x16\x44\xa6\xa1\xce\x8e\xb9\xef\x00\x1e\x06\x76\x05\xdd\xfb\x92\x5b\xbb\x84\x0e\x97\x10\x1e\x72\xcb\x6c\xbf\xca\x41\x35\x03\x54\x17\x0f\x41\x60\xdc\x52\x95\x45\xdd\x2e\x26\x6f\x50\xd5\x30\x35\xd7\x38\xa1\x32\xe8\x39\xd4\xdf\x6d\x12\xc7\x76\xc0\xb8\x61\x14\x32\x2f\x75\xfb\x3d\x2b\x9e\xca\xba\x1e\xd7\xc2\xfe\x6b\xd2\x9c\x2b\xdc\xdd\x7a\xc9\x10\xbd\x2d\xed\x96\x3a\x69\xa8\x02\x6a\x61\x2e\x9f\x8b\xaa\x99\x4b\x6c\xf2\x84\x27\xb8\x60\x89\xbc\x59\x8a\x53\xbb\x68\x64\x7f\x0d\x5d\x18\x9e\xa4\x49\x6c\xa5\x6c\x4a\x7d\x56\x2e\x69\x33\xb9\x0f\x8d\x52\xac\x0f\xc3\x1d\x1c\xfd\x8a\x87\x6c\x7f\x68\x6e\x61\x19\x38\x8d\x24\x02\xb0\x97\x55\x59\xd7\xe8\x49\x1e\x44\xd3\xa5\x21\xce\x73\x38\x29\x4e\x25\xc1\xb1\xb2\x7a\x7a\xff\xfa\xe2\x1f\x8e\x05\xd2\xaa\x2a\x82\x68\x5e\xab\xbd\x8d\x82\x95\x75\x33\x24\x8a\xf1\x4d\xb5\x65\x1a\x46\xf7\x27\x15\x5d\x44\x7f\x73\x28\xcf\xb9\xbe\x83\x07\x91\x77\x31\x11\xce\x69\xe0\x0b\xa0\xed\xe2\x37\x65\x42\x9a\x7f\x2f\xae\x43\x74\xe1\xdf\x57\x0f\xab\xf7\xf7\xc5\x93\xa3\xc5\x7e\x5a\x7d\x5b\x3d\x45\xfe\xda\x69\x02\x88\xb0\xca\xb3\xba\x01\xfd\x5c\x16\x0f\x65\xb5\xcc\x85\x8b\xef\xfb\x90\x3a\x4f\x8d\x15\x18\x93\x42\x7d\xf4\x04\x9f\xdd\x45\x8c\x4a\xfb\x5d\xb3\x35\x71\x6e\xa4\xad\xfe\xd5\x1b\x47\x2e\x88\x3b\xfe\xc7\x67\x4a\xeb\x19\x17\x09\x55\x36\x92\xb0\xdf\xe7\x70\xd7\xf1\x50\xb7\x47\x6c\x85\x2c\x66\x24\x06\x2b\x8f\xcf\xd8\x70\x99\x08\x70\x85\xe5\x16\xd9\x3e\x82\x74\x72\x45\x14\x12\x31\x97\x45\x7e\x79\x2a\xd5\x87\xed\x85\xa5\x28\xee\x4b\xdf\x44\x07\x01\x72\xf8\x9f\xce\xf5\xc1\x32\x1a\x80\xcd\x71\x1f\xe1\x7a\x4a\x4c\xbe\x80\x8e\x53\x64\xf5\xfa\x9c\x84\xeb\x39\x44\x1c\x6d\xfe\x93\xa8\x6a\x58\x17\xcd\x6e\x7c\x3c\x0d\x44\x82\xf8\x44\xec\xea\x9d\x87\xd0\xa5\x61\x64\xa4\x5b\x46\x6d\xe1\xe3\x5a\x8f\xb6\xd3\x34\xd4\x0a\x11\x3c\x8b\x73\x73\x58\x75\x59\xa0\x94\x84\xb6\xde\x5f\xf5\x99\x7f\xec\x86\xee\x0b\xa6\x84\x58\xce\x28\xb7\xfe\x60\x78\x4c\x9f\x55\xf3\xb7\x5c\x16\xbf\xb0\x51\x53\x42\x20\x61\xbe\x56\xca\xe2\x57\xe7\x92\xfe\xe3\xf5\x24\x8d\x38\x45\xa9\xc7\xf7\x72\x54\xb2\xce\xd2\x38\x89\x91\x50\x5c\x96\xa2\xd2\x63\x3c\x5b\x9a\x90\x10\xe7\xb0\xce\x7c\xd8\x71\x59\xe6\xb9\x68\xa0\x1a\x14\x30\xcf\x6e\x18\x69\xc2\x49\x47\x40\x52\x1e\x8f\x99\xfd\xb0\x23\x07\x30\xa5\x46\xa6\x8e\x58\x7f\x93\x15\xe3\xa2\x5a\x96\x72\x48\xd0\xe5\x47\x1b\xf5\xeb\x1d\x34\x4b\xf4\xc0\xfd\xb3\xa5\x8c\x68\xd1\x13\xa9\xba\xa2\x9e\xf1\x43\xa4\x29\x53\x16\xf1\x70\x3c\x4d\xee\x2d\x22\x6a\x55\x18\xc5\x07\x4e\xad\x5f\x86\xd1\x53\x91\xd8\xb0\xcd\x7e\x20\xdb\x50\x56\x3d\x7d\xf4\xf8\xc9\x85\x8e\x88\xd7\xf3\x5d\xbd\xae\xbb\x01\x23\x09\x84\x61\x17\xeb\x7f\x82\x1f\x90\xff\x0e\x97\x97\x6e\xcb\x49\x25\xd7\xe8\x79\xe7\xa5\x18\x07\xc0\xff\x11\x93\x14\x4b\x25\x58\x01\x6a\x5b\x33\xf0\x6a\xd0\x5b\x6c\xd7\xdc\x8d\x38\xb6\xa3\x7a\x10\xd7\x48\x25\x80\x36\x03\x75\x04\x57\xa2\x32\xbe\xa0\x8a\x05\xa1\x7d\xa6\x69\x73\x2a\x8b\xba\x44\x06\xe2\xe9\x3b\xab\x54\x86\xc8\x3f\x00\xc7\xac\xcb\x89\xcc\xe5\x27\xc6\x9f\x41\x41\x88\x73\xe8\xfb\xfa\xc5\x2b\x0b\xb4\xff\x77\xf7\xeb\xcd\x76\xf1\xe2\x65\x5b\x59\xaa\x09\x10\xe7\x05\x3f\x89\x4f\xa7\x81\xfc\x56\x95\x26\x9b\x2e\xd7\xfe\x04\x48\x30\x3a\xec\xca\xee\xeb\xbb\x0b\xa6\x4c\x2d\xf8\xa3\x6b\xa3\x50\x0e\x5c\xfe\xfb\xfd\xa7\xab\x56\x1c\x01\xe4\x52\x08\x99\x15\x24\xaa\x37\xc3\x4c\x6f\x0a\x89\xc0\x92\xed\xfd\x8f\xd7\x53\x67\x50\x90\xc0\x1d\x16\x01\x70\xe6\xac\x11\xb7\xb5\x6c\xba\x52\x06\x11\x82\xc2\xbd\xf6\x50\x6a\x4b\x14\x30\xc8\x95\x0a\xc2\x2d\xab\x93\xaf\x05\x7f\xa8\xca\x63\xa7\x21\x8a\x8b\x37\xef\x5a\xc6\x38\x35\x11\x40\xba\x81\xe6\x7c\xba\x13\xc5\x47\x55\xe6\x39\x22\xf4\x8c\x98\x90\xda\xb4\x67\x18\xcc\x7b\xde\x83\xc8\xed\xb2\xf1\x3e\xe5\x1c\x67\x22\x12\x81\x20\x5d\x79\x82\xad\x85\xc5\x3a\x4c\x77\x3c\x8e\x42\x74\x90\x4f\x67\x99\x67\x6a\x03\x79\xde\x4e\xbe\x71\xec\x5b\x24\xb1\x8c\xba\x90\xd9\x43\x59\xbd\xc0\xa7\x83\x71\xcd\x5b\x97\x22\x89\xad\x11\x29\x73\x61\x77\x8b\x19\xf5\x61\xd7\x94\x0a\x65\x64\x5f\x4d\x7f\x2c\x6f\x40\x30\xc7\xef\x4e\x95\x44\x81\x02\xfc\x1a\x36\x2c\xe0\x1f\x96\x85\x16\x55\xbc\x7a\x5f\x32\x12\x0e\x97\x46\xc1\xa2\x24\x76\xd5\x43\xab\x9f\x27\xa8\x32\x28\xc6\xd5\x85\x4c\xb0\x58\x10\x5b\xc3\x78\x6a\x6f\x97\x15\xfb\x6d\x25\xb2\x69\x19\x8c\x60\xda\xb2\x8e\x5a\xd4\xf0\x54\x89\xef\x5f\xd3\x97\x6c\x2d\x7b\xf0\xfb\x86\xb1\xf1\xff\xf1\x05\xb9\x54\xdc\x32\x41\x3a\xd1\x44\x47\x39\xfb\x7e\xce\x07\x41\x77\xd7\x38\x0d\x22\x14\xeb\xb7\x0e\xd1\x93\xab\xe6\xd4\xaf\x05\x2a\x1d\x62\xb8\x62\x36\xc4\x26\x52\x37\x3b\x2b\xa4\x65\x19\x83\x36\xcf\x7d\xad\x3d\x13\x42\x18\xdc\x59\x33\x3f\xf6\x1e\x90\x2d\xfc\x1f\x89\x38\x32\x21\xb4\xc5\x45\x9c\x30\x79\x04\x4f\x42\x96\xd5\x97\xf2\x5c\x5d\x6b\x42\xb4\x4e\xa2\x16\x89\x2f\xdf\xcd\xfe\x82\x1d\x02\x71\xe7\x07\xc1\xff\x84\x93\x5d\x50\x28\x29\xd1\x95\x3c\xda\x08\x9a\xcf\xe5\x08\x4d\x43\xef\x73\xed\x14\x6e\x57\xbb\xc2\xdb\x2a\x02\xa8\x8a\x59\x9f\xa8\x43\x1a\xac\x75\x51\x8b\x46\xe4\xb8\xb4\x3c\x95\x62\xe2\x39\x7b\xec\x44\xb7\xee\xc5\xf8\x2f\x76\x51\x24\x61\x34\x43\xe5\xd7\xfa\x90\x0d\x34\xf2\x99\x0c\x88\x88\x5c\xd2\xe7\x51\x1c\xe1\x8a\x69\x82\xc9\x80\x6b\x63\x4b\x3d\x1d\x1e\xbc\x8e\xbb\x93\x15\xf3\x1a\x30\x48\x90\x23\x2e\xf7\x1d\xc8\x44\x86\xa1\x06\x97\xd5\xb1\xd5\xd9\x5f\x44\xed\x08\xa9\x7e\x51\x8c\x27\x43\xe6\x2c\xaa\xd6\x6a\xa8\x84\xbe\x81\x8e\x95\x61\xaa\xb4\xf7\xd7\x44\x9e\xdf\x89\x1a\x1e\x45\x6d\xab\x71\x47\x0b\xbe\x0c\x25\xc1\x32\x9a\xe7\xc5\x1f\xbb\xe5\xe2\xe5\xdb\x62\x63\x81\xbb\xdd\x83\x4a\x89\x0c\xc4\x16\x28\xed\x34\x74\xa6\xc0\x47\x19\x6a\x61\x51\x00\x3e\x0c\xe7\x0a\x32\xdd\x61\xa2\x13\xb4\x9c\x77\x35\x34\xde\x26\x97\x11\x07\xc4\x35\x5a\xed\xb6\xa2\xd4\x70\x0f\x7e\xf3\xbb\x95\x64\x94\x71\x1c\x20\x57\xdd\xf7\xc5\xd3\xd3\x6a\xbb\x43\x0e\x74\x64\x85\xf4\x57\x8d\x45\xea\x05\x48\x9f\xc5\x47\x2f\x30\x35\x7e\xde\x84\x05\x38\xc2\x6b\xbb\x81\x0e\x73\x6a\xae\x05\xe5\xda\x4a\x44\xc2\x8f\xfb\xec\xc7\x70\x50\xb0\xd0\x7e\xf2\x1a\xfd\xe6\xd1\xd3\x31\x27\x32\x53\x43\xf3\xfb\x9f\xcb\xb1\xf1\x26\x19\x05\x34\x7e\x70\x15\x9e\x4a\x55\x8c\x6f\xde\x2e\xec\xad\x2d\xf0\x96\x8b\xa6\x1c\x71\x11\x32\xc9\x64\x62\xa2\xae\xb8\x0e\x83\x7b\x13\xa5\x25\x26\x53\xa2\x30\xf8\x68\x59\x0b\x26\x7b\x8a\x14\x3a\xc0\x98\xe9\x23\x34\xcf\x97\xd5\xde\xe7\xa1\xa4\x0c\x52\x1c\x0a\x42\x6b\xd4\x3f\xbe\xe5\x4a\x4a\x99\x58\x31\xdc\xe5\x21\xcb\xf3\x41\x3a\x55\x4a\x95\x26\x6c\x20\xf7\x8b\x89\x87\x1b\x54\xdf\x4c\x4a\x43\x78\xcf\x78\x3f\xa5\x0e\xfd\x75\x68\x50\x2a\x62\x69\x63\x77\x50\x89\x1a\x36\x59\xb1\xcf\x61\xa8\x94\xe3\x9b\x25\x0c\xc3\xab\x8b\x3d\x14\x2a\xeb\x20\x88\x52\x87\x12\xe9\x04\xd7\xdb\xed\x24\xc6\x36\xe3\xb0\x4b\x1d\x25\xc8\x22\x8f\xef\xf3\x56\xc1\x31\x3b\x1f\x6f\x0c\x50\xcd\x58\xa2\xba\x02\x4b\x9f\xed\x58\x1c\x27\x11\x56\xa9\x85\xb5\xcf\x5e\x9b\xb2\x18\xea\xd8\x32\xa9\xa5\x52\x6a\x60\x08\x0e\xb3\x1d\xe3\x0e\xd4\x10\x7a\x39\x66\x9b\x61\xb8\x2b\x31\xc7\x7b\x6d\x47\x48\x6d\x94\x0d\x9e\xa0\xae\xd6\x11\x1a\x91\xef\x70\x20\x4e\x2e\x69\xb8\x44\x70\xec\x12\x72\x90\x9b\x32\x9f\xa7\xe6\x27\xd7\xa2\xcb\xd3\xcb\x80\x05\x0c\x5d\x2c\x49\xa8\xff\x39\xa5\x3a\xee\xfb\xb1\xb5\x16\x57\xff\x39\x67\x3f\x44\xde\x07\x5f\xa5\x49\x19\xf3\x30\x3f\xc7\xb4\xe2\x8f\x38\x0a\xd2\xa1\xaa\xd6\xa6\x11\x13\xd5\x7f\xa6\x02\xa6\xb0\x6f\xeb\xa6\xac\xc4\x7e\xa0\x39\x35\x9e\x91\x2a\xe0\x69\xe8\x8a\x29\xbe\x59\x8c\xb9\x55\x1a\xfe\xa7\x4e\xe0\x2f\x7d\x14\x15\x46\x96\x30\x5d\xe5\x65\x6b\x87\xec\xdc\x76\x55\x8f\x47\xa8\x22\x86\xa1\x52\xd9\x13\x46\x6f\x46\xb1\x30\x45\x8c\x4c\x7b\x43\xe1\xb9\x3d\xf4\x72\x4d\x56\xe3\x1a\x47\x31\x0c\x14\xac\xbb\x0e\x5a\x2b\xbf\x71\xaa\x98\x58\x0e\xe9\x2d\x1c\x31\x69\x7e\xae\xe0\x19\x44\x7d\xae\x90\x69\xb3\x4b\xf1\xfe\x0b\xe7\x41\x1f\x99\x50\xb1\xd1\xb8\x9c\x88\x1f\x22\xcb\x85\xcc\x61\x25\xaa\xfc\x62\xf7\x2d\xfc\xbe\x5d\x8f\x52\x42\x3d\x4a\x02\x31\xe1\x0b\x7f\xc6\x5c\x62\x5d\x51\x2e\x50\x18\x73\xfd\xb8\x7d\xfe\xd3\x43\x0b\x14\x0b\xa3\xd4\xd1\x95\x57\x59\x73\x19\x08\x7f\x75\x2d\x68\x8c\x91\xe9\xc5\xb7\xc5\xfa\x69\x71\xf7\xb4\xda\xad\x5f\x76\xcf\x0b\xcf\x0d\xcd\x14\xe3\xda\xa4\x23\x10\x17\x3a\x77\xfe\x30\x27\x31\x8e\xb0\x1f\x19\xf2\x37\xcc\x80\xd6\x14\x8f\xa9\xe8\xf9\xc6\x3b\x54\xdf\xa8\xc3\xb9\x4e\x44\xe0\xa0\x6f\x67\x4b\xb6\x3d\x20\x51\x61\x2a\x0d\x34\x8e\xf6\x6f\xe2\x54\x56\x83\x65\x52\xa5\x11\xa5\xa4\xdf\x7d\xba\x9f\xb5\xa5\xcf\xca\x86\x51\x27\x25\x62\x8d\x4e\x6a\xeb\x83\x22\x41\xc2\x43\x59\xbd\x79\x7a\xae\xeb\x72\xc9\x61\x48\x49\x09\x41\xc3\x5e\xb0\xcb\x57\x8e\xbc\x0f\xb0\xd8\x4a\x08\x6b\xfa\x40\xa1\xd7\xcb\xd7\x13\xe9\x7e\x37\x2c\x1c\xaa\x16\xf7\xb8\xc4\xbe\x93\x24\x95\xe8\x85\x2f\xa4\x52\xcb\x09\x55\x81\x92\x1c\x10\x20\xba\xab\xb0\xa8\xc5\xfd\xaa\xe2\x08\xc5\x65\xb2\xa2\x6e\xb2\xe6\x7c\xc5\xc5\xa0\xb4\x26\x28\x89\x9f\xa9\xf2\xae\x51\xfe\x57\x88\x8d\x0e\xbb\xcf\x61\x39\x35\xb6\xa5\x4d\x69\x4f\x1e\x0a\x12\x62\x78\xa7\x7f\xdc\xa9\xd1\x31\x05\xa9\xb4\x10\x7a\xab\xd7\xe1\xf8\x8d\x5c\x1c\x65\xa2\x3b\xe5\x4f\x91\x1a\x89\xbf\xb3\xda\xa1\xdc\xb7\xe5\xdd\xf9\x32\x6d\xa4\x2d\xc1\xdb\x31\x2b\x9a\xc7\x0a\x2e\xbf\xfd\x6a\xdf\x52\x26\x88\x68\x97\x55\x79\xab\x60\xbd\x7c\xc5\x69\x95\xc9\x1c\xbe\x67\xcd\x61\x34\x82\x0c\x84\x2a\xec\x55\x01\x6f\x60\xb0\x7d\x63\x63\x83\xb5\xa8\xd6\xfb\x8f\x32\x9a\x3a\x34\x29\x3a\xe5\x8b\x62\xc0\xe3\xc2\x34\x21\x91\x24\x3e\x94\xf3\x09\xb5\x43\x65\xcc\x5f\x83\x18\x82\x58\xe3\x02\x26\x6e\x8e\x8e\x42\xa6\x83\xbe\xb8\x69\x76\xd5\xd2\x11\x01\xcc\x66\x82\xaa\x1c\x11\xc0\x6f\x33\xa8\x0f\x1d\x25\x49\x60\xa5\xf1\xbd\xa6\xf1\x38\x65\xa7\xe3\x98\x21\x4c\xa3\x2f\x29\x71\x59\xf9\xcd\x34\x88\xa2\x63\x65\x8b\xae\x44\x55\x4d\x8f\x40\x62\x99\x77\x91\xc7\xac\x9d\xd0\x4f\x99\xd7\x1c\x62\x3a\x49\x6c\x9d\x7a\x3b\x7f\x36\xd0\xb4\x5b\xf3\x2f\x94\x08\xdb\xf6\x2c\x49\x3c\x0f\x2b\x62\xbb\x6c\x65\xce\x68\xf8\xe8\x84\x0a\x2f\x79\xef\x00\x8d\x9d\x3b\xea\x5b\x70\x43\x6c\xd1\xbf\x30\x9d\xe2\xf1\xcd\x82\x99\x51\x5c\xc7\x5d\x81\x46\x01\x1a\xb3\x4e\x1a\x21\x2b\x8b\x1e\x80\xab\xa9\xe0\x98\x94\x41\xf0\x7c\xf5\xd2\xcd\x55\x4d\x95\xad\xb0\xaf\xa1\x79\x2c\x45\xfe\x0e\x58\x8f\xeb\x8f\xb2\x40\xe2\xe6\xe9\x6a\x0b\xbb\xa7\x65\xa9\x0e\x83\xde\x67\x1a\x42\xbd\x35\x27\x21\x46\x33\x1a\xa8\x9b\xd7\x22\xbf\x60\x91\x54\x9d\xed\x97\xa2\xb8\x47\xe4\xda\xa2\x73\x3c\x34\x8f\x24\x26\x57\x1d\xff\x8b\x73\x8e\x66\x30\x0a\x9a\xa7\x71\x40\x1d\xf5\x31\x42\x8b\xef\x45\x23\xc6\x8c\x7b\x37\xc6\x3f\x37\x46\x05\x03\x82\xa6\x1a\x51\x53\xe7\xcb\xe4\x06\x69\x0a\x26\xe9\x03\xff\x88\xd3\x96\xe5\x94\xd7\xd7\xbf\x64\xaa\x43\x8c\x88\x1c\xc5\xcf\x2f\xab\x3f\x7a\xa8\xb4\x16\x81\xa5\x54\xae\x01\x16\x75\x3d\x51\x42\x61\x5a\xa8\x94\x23\x68\x5f\x8a\x42\x97\x2e\x2a\xb2\x81\xea\x47\x36\xad\xb3\xd3\x02\x24\x77\x7a\xb4\xf7\x30\x23\xc8\xf7\x4f\xa3\xd9\xf3\xca\x3d\x03\x87\x53\xcb\x84\x04\xb4\x53\xe9\xb3\xa9\xed\xd9\xe5\x47\x4b\xa9\x71\x53\x6d\xe6\xd8\xc2\xe6\xbb\x5f\x05\xb1\x85\x36\x1e\x45\x9e\xef\x4e\xe2\x52\x9e\xa7\x9d\xa2\x68\xc2\x94\xbf\xff\x9b\xa8\xeb\xcf\x4e\xc2\xab\x6b\x21\x7a\xae\xc7\x7a\x03\x79\xde\x43\xeb\xb4\x92\x31\x1a\x02\xda\x7b\x51\x8e\x4d\xf8\xc6\x3b\x28\x29\x50\x1a\xf1\xb3\xca\x9a\x76\xa6\xfd\x80\x0a\xe5\xd3\x7f\x5d\xfb\xe2\x4e\xd6\xce\xde\xab\xa1\x69\xea\x24\x98\x77\x7a\xb4\xe6\x80\x36\x0f\x34\x87\x87\xe2\xa3\x5d\x4a\x7c\xfa\x57\x9b\x28\x08\xa3\x11\xe5\xad\xf7\x1e\x0a\x4b\xd8\x0e\xb7\xfa\xde\x80\x8a\xd4\x80\xf0\xed\xdd\x69\x7f\xd4\x8d\x38\xfa\xe1\x07\x61\x64\xf5\x8a\x2c\x61\xc1\xf3\x8d\x38\xfb\x3f\x00\x8e\x43\xc8\x82\x28\xf5\xb8\xd2\x76\x25\xcc\x07\x54\xed\xed\xe1\xd0\xfa\x10\xaf\xeb\x97\xdd\xe6\xeb\xdb\xdb\xd3\x9f\xbb\xe7\xc5\xfb\xef\x2b\xac\x31\xdf\xbe\x6e\x17\x4f\x5d\xd3\x94\x63\x64\xbe\x38\x1f\x11\xa1\x5c\x0f\x78\x77\x19\x10\xca\xa8\xe3\xaf\x58\x55\xf2\xdc\x94\xc5\xfe\x8b\x98\xd4\xeb\x01\x49\x69\xd2\xdb\xc8\xb6\x7e\x6d\x7f\xc3\xb1\x06\x22\x28\x4a\x10\x97\x27\x28\x1e\xb3\x1f\xb0\xf8\xec\x42\x32\x40\xc0\xe2\x87\xd7\xcb\xd7\x5d\x0d\x4d\x17\x8b\xfb\xe7\xc9\xa1\xd9\x8f\x03\x51\x10\x61\x2c\x6e\xe7\x4c\x8d\x5b\xda\x96\xae\x79\x9c\x52\x1a\x78\x5e\x69\xbc\xde\x22\xcf\x44\xfd\xb5\x68\x57\xff\x1b\xaf\x15\x1b\xab\x67\xed\x31\x5f\x3d\xa3\x56\x2f\x56\xcc\x20\x91\xc6\xd1\xff\x36\xdb\x9f\x8f\xa2\x1e\x88\x65\x33\x48\x34\x47\xb3\x49\xe8\x1f\x59\x0d\x55\xfd\x15\xb3\x7f\xdd\x72\x0f\x89\xa1\xda\x05\xfc\x1f\xb3\xbf\xa0\x5a\x37\x70\xac\xa7\x9b\x91\x6b\x4b\x03\x13\xdb\xa8\x5e\xb5\xcf\x8a\x87\x76\x2b\xfe\xbf\xb2\xb5\xe5\xfd\xc5\xa8\x94\x61\x32\xb2\xcf\x71\x7c\x8f\xb7\x74\x60\x21\x80\x6b\xf5\x50\x56\x93\xa0\x36\xb0\x44\xa2\x53\xd2\x9a\x5d\x8b\x42\x7b\xba\x85\x7f\x0f\x80\x23\xe3\x8e\x65\x34\x4e\x2c\x1d\x4f\x86\x18\x4a\x5b\x63\xd0\x5d\xce\x18\x44\x0d\x7f\x64\xea\x63\x7b\x18\x48\x26\x32\xe0\x22\xb1\xaa\xf7\xab\xc5\xfb\xf2\x8b\xff\x35\x0d\x8d\x4f\xc5\x2c\x2e\xa2\x68\xee\xab\x32\x6b\x56\x0a\xab\x3b\xff\x73\x86\x9d\xc3\x4d\x85\x3e\x0b\x01\x82\x5b\x62\xbe\xf7\xc7\xa7\x51\xc9\x09\x08\x27\x8e\xb0\x43\x32\xed\xc5\xb9\x39\x94\x95\x07\x04\xcc\x7f\x6f\x21\x6d\xe5\x70\x87\xe1\xc8\x8e\x9e\x43\x78\x32\x3b\x64\xac\x10\xe9\x75\x10\xb5\x4b\x16\xfd\x36\x0c\x14\x83\x74\x45\x0f\xed\xd2\x7a\x2a\xab\xa6\x4b\x56\xac\x7d\x95\x1c\xa8\xc0\x9a\x01\xda\x05\x68\xde\x1c\x95\xa4\x3f\x0e\x51\x18\xaa\x31\xd3\x6c\x77\xc8\x08\x2c\x8b\x3f\x9d\xf3\xfc\x4e\x5c\xeb\x57\x4d\xbe\x90\x21\x0a\x17\x8e\xcf\x43\xd6\xc0\x9b\x38\x61\x54\xd4\xd7\x08\x00\x12\x2d\x62\x71\xc3\x8c\x10\x33\x33\x41\x12\x62\x78\xcd\x0a\x79\x58\xa8\x6c\x34\xa9\x26\x32\x21\x21\x52\x7b\x45\x08\x5f\x7a\x35\x5b\xcb\x6e\x42\x46\x90\xc4\x6a\xf7\x89\xd8\xce\xc9\x41\x1e\x58\x66\x9e\xac\xc9\xfe\xea\xba\xc2\x84\xdc\xd2\x1b\x64\xf5\xfa\x78\x2c\xab\xbe\x4c\xc0\x90\x24\xa1\x0e\x11\xfd\x3a\xad\x91\x31\x84\x11\x2f\x01\x27\x85\xfa\xb8\x87\xbc\xe3\xd2\x32\x44\x07\x28\x26\x70\x12\x55\x53\x58\x2e\xff\x9d\x29\xab\xdd\xb5\x40\x20\x33\x11\x49\x30\x85\x68\x75\x8f\x16\x45\xfd\x39\xc8\x24\xcc\x06\x8a\x4d\x44\xd2\x48\x58\xf7\xcf\x3a\x23\xfe\xbe\x11\x53\xe8\x71\xe5\x67\xf5\x71\x99\x29\xb3\x36\x11\x0f\x70\xe9\xb6\xcc\xfe\x6f\x7d\x81\xb8\x89\x54\x80\x65\x07\xeb\xe2\x47\xf9\x01\xb7\xe0\x9e\xd3\x8c\xb8\x89\x20\xc2\x3b\xda\x0b\xee\x46\x54\x48\x26\x32\x0c\x0b\xa8\x07\xba\x37\x93\xa8\x8f\x89\xc3\x10\x73\x4a\x75\x23\xf6\xb0\xfd\x2c\x47\x21\x68\x13\xd3\x28\xb6\x71\x6c\x50\x1f\x6b\xb3\xae\x67\xe9\x44\x4c\xcc\x8d\x2d\xcc\x39\x65\xc5\xd8\x50\x37\x49\x60\xb0\xb4\x0e\x83\x57\x03\xa6\x72\x66\x92\x90\xc4\xd4\x9b\x20\x6b\xc7\x10\xde\x1d\x8c\x05\x77\xce\xd4\x7a\xf9\x3a\x13\x61\x72\xdf\x64\x46\xcf\xb2\xb7\xc3\x0c\x35\x0c\x65\xf4\xfe\x2c\xf3\x11\xa1\x9f\x61\xb1\xa4\x8e\x72\xa1\xdf\xf1\xaf\xb0\x26\x33\x7f\xdd\xf9\x3c\xb2\x68\x9e\xb7\xea\x0c\x52\x0c\x96\x3d\xc3\x85\xc1\x09\xf5\x90\xfd\x1c\xea\xfd\xb9\xa3\x29\x49\xd1\xca\xed\x4a\xfa\x86\xa7\xa6\x9c\x86\x74\x80\xba\x73\x30\x8b\xee\xb0\xb4\x25\x2d\x7b\x4b\xf6\x53\x56\x8b\xd3\x29\x77\x88\x32\x6b\x63\x6e\xab\x76\xb5\x98\x43\x13\x9a\x54\x85\x81\x2f\xa9\xb0\x4e\xc3\x0b\x7c\x62\x97\xb4\xee\xf3\xf6\x00\x96\x95\xd4\x41\x87\xea\x61\x2c\xc5\xa4\x8a\xa3\x41\x81\x22\xdc\x79\x8e\x98\xd8\x7b\x68\x44\x96\x4f\x07\x53\xaa\x65\xe4\xe0\x5e\x5d\xf8\x6a\x5a\x87\x6d\x44\xa4\x23\xf2\xff\xa8\x4c\xea\xfb\x5d\xc4\x8a\x84\xde\xed\x6b\xdd\xc2\xb7\xce\xf1\x32\x42\x0a\xbf\x58\xb8\x63\x1d\xee\xfa\xf7\xc9\x67\x10\xc6\x60\x0c\xaa\x80\x9f\x4d\x35\xa8\x03\x37\x92\x12\x8c\x33\x1c\x31\x31\x05\x57\x2c\x6d\x13\xaf\xc5\x48\xb0\xf8\x0b\x53\x56\x5b\x10\xc7\xd5\xd6\x6f\x74\x46\x45\x09\x6e\xc3\x3b\x79\xae\x8a\x51\x04\xcc\x28\x99\x62\x45\xc9\xb4\x72\x65\x30\x70\x95\xb4\x5c\x71\xd8\x83\xc8\x21\xe8\xfd\xc8\x59\xf3\xc7\x28\x15\x63\x26\xc9\x6a\x6b\x3f\xaf\x5f\x1c\x1d\xd1\xf6\xcb\xfb\x6a\xf3\xa5\x67\x2b\x35\x4a\x01\xe5\x1e\xac\xe2\x38\x75\xbf\x59\x49\x73\x1c\x50\x63\xba\xe6\xc1\x13\xe9\x28\xc6\xb2\xc7\xa3\xf8\x80\xb7\x0a\x74\xa6\x2c\x20\xd4\xce\x99\xd1\xfb\x01\xb1\x7c\xfb\xe7\x02\xd5\x96\xdf\xa0\xea\x53\x78\x06\x22\x8e\xec\x1b\x1d\xd6\xb9\x5c\x2f\x17\x6f\xed\x20\x44\x84\x00\xe6\xa6\xa7\xa6\xde\xf8\xea\x3a\x54\x8e\xd2\xec\xf5\x47\xeb\xe7\xc1\xe7\xaf\x48\x17\x8c\x21\xb1\xf1\x56\x9e\xb7\x2a\x8c\xd1\x04\x5c\x37\x58\x53\x4a\x5d\x86\x71\xbe\xd9\x58\xb6\xfd\xe6\x3c\x08\x82\x58\x60\xb8\x03\x09\xab\x1e\x90\x78\x6a\xf6\xb3\xf0\x20\x88\xc2\x68\x52\x16\x8b\xfe\xd6\xdd\xa5\x93\xd1\x74\x0b\x25\x0f\x02\x91\x1a\xaf\xec\x12\xdd\xf7\x21\x38\x1e\x84\x11\xc1\xfc\x58\x89\x28\x8d\x51\x34\x9e\x07\x21\xb7\xfb\xfb\x22\xcf\x2f\x75\xc7\xc3\xca\x83\xd0\xa8\x08\xbc\x7d\xe1\x00\x9d\xa8\x7f\xeb\x8e\x93\x30\x74\x10\x09\x73\x2e\xf4\x3c\x9d\xe8\x14\xdd\x3a\x67\x56\xb5\x57\x02\x74\x36\x11\xc3\x51\x3b\xb8\xf9\x6f\xe3\x8e\x20\x71\x8a\x9b\xdb\xfd\xb2\xbb\x3f\x4f\x70\x3c\x59\xdc\xe1\x76\xbd\x7a\xdf\xf1\xa1\x46\x1d\x0f\x88\x92\xc2\x78\x6d\x61\x8f\x2a\x1c\x2b\x03\xf9\x96\x26\x46\x04\x78\x21\xb4\x98\x1c\x8a\x02\x89\xe1\x81\x76\xd8\x7e\xcf\x72\xbd\x14\x95\x9e\x7b\xc0\x38\x4e\xa9\x03\x71\x2d\x96\x4f\xef\x65\x0e\x3c\x65\x24\xe2\x21\x49\x79\x1a\x06\x41\x10\x92\x28\xf8\x6d\xfc\xe2\x71\x2c\x45\x32\x1a\xca\x77\xe7\xcb\x4c\x85\xc6\xe4\x2c\x91\x68\x2b\xe6\x6c\xd3\x90\x30\xb9\x6a\xc2\x29\x6a\x76\x7e\xb5\x55\x3d\xbe\x37\x12\x61\xc5\xd4\x1c\x7c\xbc\x75\x24\xfe\x36\xe3\x32\xb9\xb0\xd6\x68\x71\xee\x70\x48\xb4\x26\x41\x8d\x7c\xac\xee\x30\x03\x3e\x2e\xea\xfc\x0e\xd9\x0b\x80\xbe\x91\x54\xe6\x01\x0f\x2c\x49\x63\xbb\x50\x62\xda\x22\xf4\x97\xe2\x5a\xe1\x2a\x6a\x1f\x75\x56\xf6\xf6\x57\x08\xb0\xd6\x4a\x0c\x6c\x1f\xd9\x0e\x1a\xdf\x37\x25\xb6\xdc\xb1\x67\xdb\x5e\x64\x95\xae\xca\xd3\x8d\xe7\x4c\xb5\x46\x0b\x67\xe7\xb8\x69\x86\x24\x18\x3c\x10\xb1\x46\x48\xf8\x3b\xa8\xec\x94\x41\xd1\xd8\xe4\xd9\x75\x3d\xe1\xf8\x09\x85\x08\x22\xd6\xf3\xdd\xe0\x90\x7a\xa8\xca\x63\xe7\xdb\x8d\x9f\x41\x40\x6a\x0b\x6e\xca\xe3\x29\x87\x06\x7a\x22\xbc\xf9\x67\x16\x00\xcc\x86\x87\x3f\x1f\xfb\x0c\xca\x28\xa0\xc0\x03\x29\x81\xf6\xc8\xda\xe5\xa1\xb5\x61\xc6\x4f\x29\x21\xc1\x6d\x64\xb1\xdf\x67\xe7\x62\x9f\xbd\xc0\xbe\xfc\x2b\x13\xc5\xd5\xa0\x93\x06\x74\xd0\x71\xcb\xb8\x88\x82\x13\x63\xbf\xcd\x0a\xc7\x03\x15\x5b\xb2\x2c\xa1\xb5\x07\x8d\x0e\x5f\xa8\x7b\x54\x95\x44\x68\xda\x9c\xc4\xe5\x39\x2b\xdc\xb6\x3f\x00\xd8\xb7\x2d\x28\x26\x0d\x30\x88\x54\xcf\x22\x79\x78\xa0\xa4\xc1\x59\x6a\xe1\x32\x1d\x87\xcc\x75\xf0\x96\x07\x9a\x44\x88\x8b\xae\x30\xa2\xf9\x2d\xab\x07\xe1\xfd\xd1\x2b\x40\x2c\xd3\xbe\xea\xb2\x2e\x73\xc7\x24\x89\x34\x83\x18\xc2\xf7\x0e\xf6\xf8\x13\x99\x38\x45\x42\x71\xbb\x0d\x78\xad\xa2\xd1\xa5\x8d\xe1\x68\x9b\xb7\x7b\xd4\x93\x68\x37\xa0\x55\xa5\x48\x80\x16\x91\xe5\x94\xf3\x6a\xb1\xf6\x84\x30\xe0\x11\xee\xce\xa2\x19\x90\x54\xf2\x90\x84\x12\x3f\xf4\xef\x70\x01\xed\xc0\x24\x1d\xee\x9d\x87\xc4\xed\x70\xb5\x37\x0c\x67\x40\x90\x6d\x2b\x83\x3e\x8b\x11\x59\x3e\x7a\xcc\x90\x30\x9b\x02\x7d\x7c\x7d\xba\xbf\x5b\xbc\x0f\x0c\x65\x1e\x46\x84\xe9\x5e\x7b\x78\xd3\xb4\x93\x7d\x7f\xf9\xed\x6f\x78\x6b\x7a\x67\x65\x34\x62\xc3\x84\x48\xe9\xaa\xda\x5c\x64\x11\x49\x58\xc6\x3d\x1b\x26\x89\xc4\xf7\x79\xb3\xa0\xc7\xa5\x9b\x33\xbf\x0e\x4b\xf3\x90\x06\xda\x96\x10\x9c\x8f\xa8\xc4\xbf\x74\x30\x0a\x7f\x98\x06\x29\xeb\xb3\x42\x4b\x47\x0c\x37\xe9\x25\x16\x51\x04\xcb\x21\x48\x63\x2b\xf2\x0f\x7f\x3a\x13\x14\xd9\x77\x04\x3a\xca\xce\x61\x9f\x1b\x50\x21\x13\xd2\xc3\xca\xed\x96\x25\x9a\xac\xd8\x6f\xcf\xa7\xbc\xfb\xa0\x0c\x6c\x96\xaf\x12\x9f\xd8\xe4\xd5\xfc\x36\xee\x28\x4e\x0d\xfa\xb6\xd0\x4e\x11\x04\x20\xad\x0b\x5b\x45\xfd\x7a\xee\x46\x4b\xaa\xa3\xa0\xaf\x10\x7a\x11\x47\x5f\xae\x5d\xcd\xd5\x77\xf2\x50\x10\x85\x85\x34\x6f\xe2\x32\xe9\x71\x11\x0b\x4f\x93\x69\x0d\x94\xb5\x2a\x37\x1d\x6d\x23\x0f\x55\xa0\x65\xdc\x15\xa1\xb7\x26\xcf\x23\x74\x8f\xa1\x62\x8d\x04\x84\x4d\x06\xd5\x4b\xd9\xfd\xaa\xac\xbe\xb5\x15\x8b\x59\xd8\x01\x3b\x7e\x49\xa5\x53\xdc\x40\x90\x48\x73\x2a\x37\xc3\x43\x2d\x2d\x85\xdf\xa0\xae\x6b\x76\xb1\x0c\x21\xb6\x9c\xf7\xcf\x7f\x2e\x45\x35\x88\x41\xf1\x10\x52\x8e\x96\x93\x3a\x1f\xdb\x2d\xad\x5d\xfc\xdb\xd9\xed\xf7\xbc\xd0\x24\x82\x47\x03\xd0\xc8\x5a\x43\xd1\x64\xcd\x65\x36\x80\xc4\x49\x10\x31\x6d\x31\x26\x96\x42\x03\xc4\xb1\xdb\x36\x7e\xf3\x6d\x12\x43\x7d\x21\x29\x2a\xc7\x7a\xff\xc7\x32\x37\xbe\x94\x1d\x31\x15\x12\x39\xfa\xb3\x94\xa5\x6a\x37\x39\xfc\xcc\x64\x0e\x76\xf9\xb1\xe9\xf7\xd1\xcb\x92\x50\x24\xa1\x23\x75\x77\x89\xaf\x7a\xd2\x82\xc8\x34\x20\xbd\xa6\xbb\x0d\x70\x2d\xc5\x69\xda\x0c\x34\xc2\x01\xa4\x28\x3e\xc6\x36\x25\x89\x42\x5b\x39\x81\x86\x02\x32\xd5\x0d\xa2\x0a\x9c\x44\xcc\x2e\x6b\xcf\xeb\xbf\x57\x61\xe1\x24\xe2\xca\xb8\x10\xe8\xf2\xa8\x6d\x19\x5d\x39\x7d\xab\x38\x0e\x2c\xc3\x0f\x96\x6a\x8f\xee\x16\x73\x9b\x68\x43\x49\x19\xe4\x23\x77\x50\xe8\x79\x2c\xd8\x78\x6c\x90\x24\x4a\xa9\xf4\x2b\x4e\xe6\x39\xf0\x43\x5f\xd8\xc8\x49\xc2\x15\x46\x30\xff\xfd\xc7\x70\xdd\x23\x34\xb4\xf5\xf2\xed\x1a\xd5\x2f\x40\xfe\x60\x64\x41\xe7\x2e\x90\xd8\x3a\x51\xed\xa0\x19\xdf\x99\x4a\x89\x81\x00\x53\x37\xae\x34\xa4\xed\xc9\xb7\xb2\xc2\x0a\x30\x28\xca\x63\x56\x88\x0e\xc6\xdd\xb6\xb7\x24\x29\x38\xe5\xe1\x7c\x74\x5a\xeb\xdd\x61\x43\xb0\x24\x6f\xe3\xad\x2c\xc2\x24\x21\x96\xfa\xb6\xfc\x0b\xba\xf2\x44\x7f\x94\xc7\xa1\x1a\x15\xac\x39\x89\xf3\x6e\x57\x21\x29\xe5\x48\x72\x57\x56\xd9\xfe\xf9\xa3\x19\x04\xbd\x39\x11\x41\x88\xe5\xda\xc3\xf5\xe7\xeb\xe6\xbe\x3b\x4c\x18\x5a\x3f\x3f\xac\x72\xfa\xb3\x98\x18\x1e\x44\x68\x2d\xb5\x2b\xfa\xfd\x71\xce\x0b\x3b\xda\xef\x2e\x8b\x0a\x26\x16\x3a\x91\x24\x8a\x83\x0e\xfc\x52\x35\x6b\x55\x4e\x92\x30\x9c\xc8\x88\xe2\x90\x6e\xc4\x47\x67\x31\x10\x99\x6a\xcf\x2d\xea\x02\x8a\xbf\x2a\x79\xe2\x44\x51\x30\xbc\xf3\x78\x36\x50\xe8\xdb\xd5\xd4\xfe\x94\xd4\x1a\x25\x4e\xef\x6c\x5b\xda\x3d\xa5\xaa\x6f\xf2\x53\x72\xa2\x80\x21\x2d\x43\xeb\xf7\xdb\x60\x9a\x63\x25\x1e\xae\x7d\x44\x8b\x10\xc4\x24\xef\x77\x45\x4a\x7b\x3b\x39\xcd\x09\x0c\x49\x76\x87\x1a\x01\x9c\x40\x14\x63\x19\xb2\x05\xd5\x0b\x03\x9d\x8e\x43\xde\x35\x51\x01\x66\xdd\xfc\xed\x31\xa5\xec\x65\xe7\x7e\x29\x58\xd4\xbd\xa7\x09\xb8\x70\x7b\xf9\xd7\x2a\x9b\x83\x29\x70\x62\x64\xa2\xdd\xbe\xf2\xad\x6c\x00\x4d\xc4\x31\x5a\x84\x47\x61\x68\x6d\xfd\x01\x55\xaa\xff\xee\x51\x48\x62\xdc\x02\xec\x0e\xb7\xae\xeb\xf3\x74\xc3\x8e\x48\x08\x18\x51\x3b\x9d\xeb\xc3\xca\x65\xd4\x46\x1f\x31\x22\xa9\xc6\x1a\x03\x47\x3b\xe7\xd3\x83\xff\x08\xec\xc1\x23\x22\xa5\xb1\xeb\xf9\xf1\x54\x56\xa2\xba\xac\x6a\x25\x4e\x80\x24\x62\xbf\x20\x2f\xe4\x51\x14\xd8\x88\xdb\x6a\x93\x97\x4d\xbd\x5e\xbe\x6e\x2d\xd6\xff\x94\x97\x97\x49\x00\x95\x47\x11\x0b\xa4\x73\x3f\x57\x1a\x91\x55\x18\xf4\x99\x56\x32\x4f\x03\x62\x3c\x8a\x45\x82\x39\x2c\x79\xbe\x5c\x09\xac\xf0\x28\x09\x2d\x83\xde\x41\xd4\x6f\xa2\x46\x28\xc0\x5f\x7d\x36\x88\x47\x09\xb3\x62\x91\x23\x3d\x43\x1e\x51\x06\xb1\x45\x37\x35\x50\x6d\x8e\xc2\x0b\xc8\xb4\xd6\x69\x80\x79\xd8\x4c\x95\xe4\xb9\xdb\x67\x23\x96\x98\x30\x76\xd8\xf2\xac\x82\xac\x36\x53\x4a\x2b\x6c\x83\x9f\xe1\x0e\x9a\x2d\xd4\x4d\x18\x86\xdd\xd9\x3c\xe6\x36\x0f\x8b\xc0\xa4\x2e\xe8\xc4\x23\x4c\x9a\x3a\x15\xc8\xe9\x7a\x3f\xbe\x3a\x8f\x43\x4c\x53\x3d\x03\xa6\x0a\x86\x6b\x79\xc4\x59\x60\x55\x8f\xce\xf2\x5c\xdf\xe5\x42\x4d\xf6\xbb\x88\x73\x90\x03\x0e\xf0\xac\x2c\xea\xd7\x1f\x8e\xd9\x7f\x7c\x9b\x34\xb2\x14\xdb\xcf\x8b\xed\xee\x6d\xf1\xbe\x7d\x59\xbd\x6f\x7c\xb2\x76\x18\xbc\x88\xbc\xad\x25\x2c\x96\x78\x30\x03\x67\xc7\xcc\x8d\x4c\x03\x8f\x84\x8a\xd0\x98\x2c\x8d\xd9\x1e\x2a\xa8\x0f\xbd\x55\x16\xc9\x38\x41\x37\xbb\x12\x9f\x5e\x8a\x77\x32\xb7\x24\x93\x21\x38\x8d\xd6\xff\xb2\x88\x93\xc9\x08\x51\xc4\xd7\xf5\x97\x1f\xe7\xd3\x3b\xec\x5f\x06\x34\x7c\xbe\x0d\xd7\x98\x4c\x39\xda\x8c\x99\xa3\x44\x1a\xb2\xbb\xf1\x48\xa9\x14\x67\xf1\xf2\xe5\x65\xd4\xf7\x0a\x62\x64\x68\x83\x9f\xa7\x63\x79\x13\x16\xeb\x1a\xeb\xc4\xea\xbb\xed\xf2\x76\xf0\xb7\xe6\xd5\x55\xa5\xed\xdf\xfc\xf7\x17\xd2\x02\xc3\xf3\x98\xe5\x74\xa9\xd9\x5f\x99\x90\x11\x30\xcf\xfa\x72\x2c\x7f\xc0\x37\xa8\x2c\x74\xb8\x9c\x95\x12\xe6\x91\x21\x1c\xe1\x7f\xc8\x14\xf9\xf5\xa4\x9f\xb3\x62\x93\xed\x8b\xf9\x28\x60\x64\xa8\x40\x20\xcc\x09\xca\xde\x07\x88\x0c\x93\x9e\x94\x17\x1d\xe1\xff\x3e\x97\xcd\x64\x6f\x8c\x83\x84\x20\x64\x3c\x73\xb2\x40\x38\xf3\xff\xa7\x93\xd9\xe8\x26\x4a\x1c\x28\x2b\xc4\xb6\xf3\x65\xc0\xa3\x1a\xeb\xf1\x46\x18\x87\x49\x9a\xe0\xd3\x9b\x06\xaa\x1d\x56\x19\x93\xdd\x11\x9a\x83\x97\x13\xe3\x71\x28\x92\xc8\xed\xad\xbb\x21\x8d\xfb\xf8\xf1\x42\xc9\x1c\xb5\x87\x33\xca\x2c\xaa\x61\xda\x8c\x04\x1a\xc9\x02\x7e\xd8\x38\xb3\x2d\x08\xf1\xc7\x58\xaa\x7d\x3c\xda\x96\xc3\x75\xdc\xed\x57\x41\x68\x1e\x13\x11\x61\xf0\xf8\x24\x2e\x2e\x10\xd8\x1d\xd0\xe0\x2a\x5f\x9c\xdd\x34\x20\x94\xe2\x31\xd1\x0a\x6d\x2b\x91\xe7\x83\xe5\x2f\x8e\x42\x1e\xcb\x01\xf1\x34\x26\xec\xc6\x77\xbf\x59\x8b\xca\xe3\x98\x4a\x84\x19\x36\x99\xad\x71\x19\x0a\xb2\xf1\x38\x56\xc0\x43\x57\x20\xd7\x41\x6b\x78\x9c\x84\x36\x18\xb5\x39\xe5\x59\xe3\x7a\xed\xb6\x31\x11\x27\x44\x63\xc0\x63\xb9\xd8\x5e\x41\xd8\x86\x3b\x6d\x9c\xc4\x4c\x78\xee\x7f\x44\x7e\x5d\x7d\x85\x44\x72\x0a\x8e\x32\xc5\xa1\xdd\xfb\x38\xbe\x15\xd6\x6e\x8d\x9b\xef\x59\xa1\x7d\x59\x19\x8f\x13\x25\x91\x93\xec\xf1\xf5\xe9\x7e\xdb\xfd\xa8\x13\xd1\x7e\xcf\xaf\xa7\x7d\x25\x34\xa0\x50\xde\x14\x2f\xd8\xb6\x62\x68\x79\x37\xe7\xe2\xb6\xe8\xe7\xf8\x11\x69\xc8\x51\x05\x61\xb7\x87\x66\x59\x09\x69\x35\x64\x1b\x31\x29\x44\xe3\x31\x55\x91\x57\x7f\x6a\x57\xa4\xae\x98\x15\x6b\x93\x31\xae\x30\x94\xab\xe2\x31\x0b\x89\x21\x38\x03\xf1\xdd\xdf\x10\x33\x35\x99\xd4\x31\x8b\x62\xee\x80\x13\x1b\xc8\xf3\x7b\x38\x8a\x62\xda\x89\x2c\x4a\x88\x2b\xd7\xbd\xb3\x34\x38\xcb\xb2\xd0\x23\x28\xf4\xe4\x9d\x78\x10\x61\x1c\xbe\x67\x40\x58\x7e\x59\xbd\xdc\xaf\x26\x25\x81\x3c\xe6\x61\x04\x41\xb7\x12\xcf\x80\x8c\x7c\xbb\x88\x46\xa4\x43\x5b\x22\xfc\xb0\x23\x0c\xe4\x31\x4f\x41\x53\x17\x68\x14\x15\xac\x0b\x67\xd7\xfb\xdd\x65\xb8\xe9\x84\xee\x9c\x94\x73\x4f\x35\xea\xd2\x13\xe5\x79\x7f\xf0\x4b\x7b\x2c\x22\x40\x03\x5d\xb6\xeb\x7d\x06\x35\x9a\x61\xdd\x38\x17\x82\x69\x5f\x4d\x91\x35\xe7\x5c\x64\x55\x87\xe2\x48\x26\xbd\x27\x1d\xd1\xe2\x05\x44\xd5\x80\x38\xee\x9a\x76\xfc\xec\xfa\x62\x05\x1e\xeb\x90\x21\xf4\xec\x5e\x54\x1f\x15\x14\xb9\x28\xf4\x70\x3f\x89\x4d\xcc\x8c\xad\xf7\xd5\x67\x05\xcb\x76\x00\x37\xf5\x6f\x33\x88\x3c\x3e\x59\xf4\x0c\xa5\xe8\xed\x38\x30\x27\x3c\x8f\x63\x75\xb1\x51\x12\x3d\xf0\xe7\xc5\xfb\x1f\xe3\x3b\x6a\x8b\x58\x41\x67\x78\xf5\xd3\x9a\xe8\x58\x92\xec\x5a\x24\x81\xa0\x08\xfc\xf5\xc6\xf4\x7d\x69\x1a\xb4\xa8\x86\x93\xdb\xb7\x95\x0c\xa3\xfb\x4f\x9b\xfb\x89\x7e\x21\x4f\x02\x45\x30\xb1\xd4\xee\xf1\x50\xd5\x9d\x14\xca\x68\xa7\x4d\x02\x13\x08\x2f\x21\x54\x95\xc7\xb2\x01\x3d\x92\xe2\xc5\x82\xeb\xe1\xab\x25\x61\x90\x60\x66\xa9\x16\x3f\x40\x8f\xd8\xed\x78\x12\x4a\x65\xa1\x1d\xc2\xc0\x1b\x54\x6a\x7e\xd0\x25\x24\x96\x08\xe6\x39\x88\xfc\x47\xeb\x4c\x3a\x19\x6d\x7f\x34\x09\xb0\x88\xfd\xe3\x22\xa1\x72\xb4\xa2\x6f\x55\xf9\xf3\x32\xae\x44\xe6\x49\x14\x59\x86\xbb\x3d\x34\xcf\xd0\x88\x2b\x1e\xf9\xb6\xc5\x40\x20\xe4\x03\x8a\xe7\x6c\x18\x54\xf6\x8d\x98\x25\x3b\x39\x17\x83\x08\xfa\xff\xfc\xef\xa4\x00\x95\x27\x91\x4a\x63\x24\x64\xcd\x1a\x55\x66\xc5\xef\xdd\x86\x90\xc4\x24\xc4\xc5\x49\x9c\x9b\xd2\x65\x0f\xc6\xbd\x1c\x33\x8d\xa2\x23\xb7\x9c\x86\xf1\x53\xc7\x92\xa5\x16\x06\xa6\xc5\x20\xa5\xfd\x4f\xaa\x5f\x66\xa2\xea\x09\xa5\x1c\x9f\xdb\x6b\xd2\x6c\x33\xf5\x01\xbf\x94\xad\xe0\x09\x23\x3c\xa4\x2e\xab\x6e\x4c\x96\x67\x43\x59\xb4\x91\x55\x98\xb0\x54\x33\xc7\x17\xb9\x2a\x9a\x6b\x52\x21\x3b\x84\xe6\x07\x02\x33\x56\xd4\x1f\x93\xec\x3f\xa0\x72\x22\xe1\xfd\x37\xe8\x09\x36\xda\xc6\x0a\xc7\x85\xa8\x6b\xa8\x9a\xd5\x7f\x22\xb7\x0c\xb9\xe7\x71\xad\x78\x28\xfc\xa0\xc0\xa2\xd4\xe5\x48\xb4\x6e\x6c\xaa\x27\x9c\x50\xc1\x9c\x45\x6b\x4b\xca\x27\x28\x23\x9e\xf0\xc8\xf2\x32\xbb\xf2\x1f\x0b\x5b\x9b\xb6\xa1\x49\x08\x1d\x13\x42\xe1\xe2\xe9\x37\xf2\x9e\xfe\x1c\x90\xcc\x59\x0b\x1b\x55\x56\xe3\xf5\x23\xe1\xc6\x42\x82\xdc\xb9\xad\x91\xdc\x1a\xb0\xfe\xb9\xd3\x10\x6c\xce\x3f\x43\xd0\xdd\x32\xcf\x5a\xd3\xf6\xcd\xee\x47\x5b\x51\x7f\x74\x0d\x4d\x8a\xa6\xa5\x97\xdf\x5b\x8a\x6a\xa1\x7f\xfc\x22\xc3\xcd\x13\x19\x82\x74\xf1\xf2\xd5\xfa\xc1\x5f\x48\xf2\x60\x44\xd1\x84\x46\xe6\xba\xc8\x9a\xec\x17\x89\xa7\x44\x2a\x96\x38\x7b\xec\x0e\x9d\x71\xac\x05\xf3\x99\xa0\x39\x27\x3f\x51\x2a\x4d\xd9\xbc\x14\xe3\xd0\x21\x4e\x14\x30\x74\x89\x5c\xf5\x78\xeb\xd3\x4d\x94\x2e\x79\xa2\x05\x0f\x99\x2d\x08\x87\x0a\x03\x64\xe0\x19\x58\x5d\x0b\x48\x01\x4b\xc6\xa1\x52\x9e\xaa\x80\x27\x46\x50\x64\xef\x3b\x55\xd9\x5f\x30\x9e\xc8\x46\xc6\x1d\x15\xdf\x83\x95\xb5\xac\x67\x58\xc2\xba\x1e\xa0\x01\x53\x88\x61\x69\xef\xeb\xdd\x8f\xa9\x31\x45\x03\xd0\x09\xed\x36\xe1\x75\x03\xc7\xef\x55\xd9\x3d\x24\x25\xa9\xc2\x64\x41\xfb\x8e\x6e\x00\x5f\x57\x81\x73\x4a\x84\x71\xe5\x85\x2e\xe5\xda\x17\x43\x8d\x6f\x17\x39\x25\x86\x67\x51\xfd\x35\x88\x6f\xd3\xd6\xb4\x76\x70\x98\x55\xdd\x5c\xa5\x4a\x69\x1c\xd9\x4a\x98\xe7\xc5\x1f\xbb\xd7\xb7\x4d\x77\x5a\x2c\x70\x68\x9c\x6b\xa8\x50\x1e\xde\xa2\xff\x26\xe1\x93\xf9\x15\x80\x26\x26\x46\x4a\xa7\xe3\xf1\x6c\xa3\xb8\x03\xaa\xfd\xae\x89\x45\xc5\x3c\x95\xfb\xbb\xde\x2e\x9c\x5d\x56\x06\xd6\x3d\xa5\xa0\xa9\x9b\x94\x77\x79\x59\x5e\xf3\x62\x73\xca\x02\x82\x01\xb9\xf6\x85\x56\x2f\xf7\xbb\xbb\xa7\xd7\xe5\xef\xbb\x97\xaf\xcf\x77\x9e\x64\xb7\x6d\x43\x31\x2d\xe2\x5c\xef\xd6\x16\x29\x8b\xf6\xbd\x86\xa3\x96\xf2\xc8\xda\x03\x0a\xf1\xea\xcd\xb3\xc8\x0a\x75\x10\x59\xf1\xf8\xf6\xc7\x0c\xfb\x14\xa7\x5c\xf1\x8e\xcf\x4c\x34\x70\x77\xd9\x74\x84\x8e\xfd\xe3\xa5\x1c\x70\xe1\xde\xd9\xb5\x67\x10\x71\x9e\xf6\x67\x48\xaf\xfd\x0a\xbf\x6f\x51\x21\x63\xe9\xd7\x72\x4b\x6e\x88\x35\x4e\x03\xc0\xa5\x5f\x62\xa9\xe4\x71\x2c\x3d\x8d\x39\xda\x01\xfe\x80\xb1\x85\x05\x9b\xec\x78\xca\x01\xc5\xb9\xab\xb3\x6a\xca\xca\xb1\xe8\xce\xbd\xa3\x4a\x02\xf4\x36\xf0\x62\x5d\x7a\xbd\xcf\x34\x52\x25\x0c\x86\x50\x6d\x85\x72\xf5\x6a\x36\xa5\xca\x44\xde\xa5\x4d\xe6\x47\x8c\x32\x36\x86\x71\x7f\xae\xb2\x72\xbb\xda\x78\x47\x82\xea\x80\x78\x5d\xfd\x2f\x65\xde\xce\xf2\x21\x03\x13\xa7\x9a\x0b\xe4\x11\x41\x17\xd5\x88\xbc\x86\xd5\x7f\x5e\xca\xa7\xb2\x9b\x67\x10\x50\x13\xb9\xdd\x60\xb5\xfd\xd2\x94\x23\x11\x61\xdf\x28\x66\xb8\x02\x58\xdf\x1e\xfd\x9e\x5c\xdc\x30\xd7\x29\x28\x83\xdb\xa8\x2e\xdf\x61\xa0\xdf\xc3\x29\x68\x81\xe6\xb9\x4f\x15\xad\x0a\x7d\x2a\xb3\x6e\x54\xfd\x6b\x7c\x15\xc3\x90\xd4\x15\x44\x55\x20\xea\xe6\x3b\x64\xfe\x42\x46\x46\xe1\x80\x87\xe1\xf5\xdc\x9c\xce\x0e\xdd\x6e\x09\xb5\x38\x0b\x78\x8a\x46\xd9\x9b\x28\x74\x59\x89\xbf\x93\x19\xe3\x2c\x48\x43\xac\xef\x5f\x2d\xee\x6c\xe3\xd9\x46\x86\xdb\xb9\x73\xe9\x19\xb1\xdd\xa1\x30\xb0\x92\x45\x35\xfc\xe8\x0c\x5f\x16\x06\x06\x91\xd7\x56\xc8\x76\x28\xa8\xc6\x59\x18\x12\x9f\xc8\x45\x41\x64\xf4\x01\xc7\xab\x1b\x0b\x53\x40\x8c\xd5\xfd\xe2\x74\x7a\x29\x35\xbc\x09\xf5\x21\xf6\x70\x9f\x55\xc8\x85\x70\x23\xc9\xc6\x42\x91\xa2\x85\x8f\x82\xdb\x03\x81\x52\xce\x48\x10\xe0\xca\xb3\xca\xb3\xfd\xf1\xff\xe3\xec\xdd\x96\x1b\xc7\x91\xad\xe1\xd7\x99\x8b\x7d\x41\xf0\x08\x5c\xca\xb6\x5c\xe5\x5d\x96\xad\xdf\x52\x55\x77\xcf\xc4\x84\x22\x01\x24\x6c\x8e\x29\x52\x43\x52\xae\x72\x3f\xfd\x1f\x4c\x00\x3c\x89\x76\xf7\xfe\x6e\xba\x3a\x0c\x90\x22\x41\x1c\xf2\xb0\x72\x2d\xb0\x59\xa2\x8f\x0a\xbb\xfc\x25\x18\x91\x05\xa2\xf3\x46\x9e\xeb\x86\xf6\xb7\x9b\xf3\x98\xf9\x9a\x67\x51\x60\x7d\xec\x12\x7f\xf9\xe0\xc1\x7e\xbf\x71\x3c\xe9\xa2\xef\x15\xc7\x99\x43\x8c\x5a\x56\x10\xb7\x32\xc7\xc3\x18\xf1\xc8\x42\xde\xf3\xf2\xf9\x5c\x40\x7d\xb3\xff\x71\x0f\xe7\x72\x14\x28\xfe\xbf\x96\x1a\x4d\x26\x67\x16\x89\xd8\xb8\x2a\x79\x17\xcd\x23\x71\x87\xcb\x98\x77\x16\x49\x95\xba\x32\xb0\x6e\xf1\xc0\x45\x87\x38\xce\x12\x2f\x9e\x59\x40\xd3\xf4\x05\xd2\xde\xdc\xc9\x62\x99\x52\x31\xba\x27\xee\x19\x54\x86\xa7\x43\x1c\xeb\x88\x28\x05\xce\xa5\xec\x8e\x3b\x8b\xf9\x1c\x82\x2c\x59\x12\x59\xef\x72\xb3\xba\x7b\x38\xec\x56\xf7\xeb\xc3\x8f\xd5\xfd\xf7\xf5\xe1\x7a\xb5\xed\xbb\x48\x49\x2c\xc5\x9e\xcc\x60\x3b\x56\x82\xfb\x7c\x48\x12\x1d\x93\x5a\x70\xbb\x50\x98\xe3\x8e\xa3\x2c\x65\x96\x47\xa3\xb3\xbd\x6c\xa6\xe4\x1a\x8b\x62\x79\x03\xc8\x32\x93\x85\xda\xef\x49\xe7\x7a\x76\x12\x67\x3c\xb4\x3c\xc1\x14\x1a\x5f\x4c\xb3\x67\x5c\x04\x91\x13\x9f\x70\x42\x5f\x6b\x92\x82\xf0\xcd\x32\x4d\xc1\x05\xcd\xce\x0d\xee\xe0\xad\x1f\x2a\x81\x4c\x90\x3c\xbb\x85\x78\xac\x8a\xe2\x16\x7b\x37\x33\x83\x80\x83\x75\xed\xab\x62\x60\x5b\xe2\x19\x68\xed\x10\xc7\x1a\x8b\xfc\x7c\xfc\xeb\xed\x42\x26\x56\x95\xb0\x57\xe5\xdb\xd6\x95\x04\x99\x17\x7e\x0f\xf7\x23\x27\xd3\x8c\x36\x60\xbb\x75\x7a\x3c\xf2\xf4\x75\xa5\x4e\xc9\x63\x6f\xb0\x9d\x1c\x19\xfe\x50\x4b\xdc\xa9\x96\x29\x96\x69\x61\x8d\x34\xca\x86\x62\x51\x8c\x89\x8a\x78\xa6\x42\x1b\x01\xf9\xe9\x65\xb8\x97\x70\x2c\x99\x52\x96\x91\xb1\xc6\x53\x81\x65\xde\xbc\x5c\xd0\x66\xf3\x4c\x07\x21\xa1\x38\x3a\x93\xf4\xfe\xcf\xa9\xcc\xea\xf4\x6e\x3a\xb5\xd0\xc1\xe3\xe1\x78\x2e\x5a\xaa\x21\xd7\x4f\x36\x8b\xd1\x7f\x31\x2d\xc1\x10\xc8\x17\x51\xef\x7f\xe2\x42\xf9\xd7\x64\x74\xb5\x4a\x29\x53\xeb\x2a\xa6\x3b\x1f\x7d\xd5\xbe\x14\x38\xf2\xc7\xfe\x42\x15\x6a\xf6\x32\x4a\x18\x67\xe4\xdd\xa2\x33\xc5\xf9\xac\x0f\x0a\x46\x1b\xb8\xb2\x33\x67\xaa\x7f\xc9\x33\xd4\xcc\xd8\x6c\xf6\x3b\x05\x86\xbf\x62\x51\x54\x13\x7b\x28\x43\x9d\x10\x79\xca\x09\xde\xfd\x32\x6c\x36\x50\x9e\xa1\xe8\x53\xf1\x19\x6a\x20\x33\xd4\xfb\x73\x61\x60\x9f\x26\x0c\xfe\x67\xf2\x6f\xbf\x87\x18\x91\x51\xf1\x5c\x09\x47\x6c\x4e\xa0\x70\x0f\x17\xa9\xd0\xcc\x08\x4b\xf2\x6e\x7f\x8d\x6c\x26\x5b\x21\xfc\xc1\x0a\x35\x9a\x11\xc2\xa2\xb3\x76\xfe\xb7\xca\xcb\x05\xac\xde\xd2\x80\xce\x86\x8c\x07\x61\x64\x86\x24\x3e\x11\x32\x10\x22\xe3\x22\x18\xeb\xfb\x0b\xab\xa2\x54\xdb\x32\xf8\x75\xfb\x42\x31\x46\x9f\xc5\xe2\x2c\x08\x5d\x64\xca\x2a\x90\x12\x87\xed\x16\xea\xd7\x51\xe1\xa4\xeb\x1a\x86\x21\xa0\xcf\xdd\xae\x8f\x90\xfb\xfc\x1a\x8f\x58\x48\x35\x82\x1a\xbb\xf9\xb2\xaf\x4e\xb9\x72\xf2\xdf\x49\xdf\x43\x46\xa9\x5f\x6e\xee\x3b\x2d\xad\x13\x1e\x09\x9e\x38\x5e\x9a\xda\xd2\x6a\xf5\x58\x03\x1e\x47\x40\x94\x85\x79\xb3\xcf\xb1\x66\xb3\x2b\x63\xcc\xb8\x13\x0f\xba\x29\xbd\xdd\xc2\xd3\x10\x53\xfb\x68\xd0\xbe\xdc\x40\x0b\x07\x23\xfa\xb6\x58\x50\x36\xfb\x5c\x5a\x1d\xde\x19\x25\xb7\xef\x25\x93\x30\x1d\xd8\xd3\x49\xaa\xf9\x1f\x33\xdb\x97\x67\xc2\xe2\x31\x25\xb6\xd6\x91\x23\x2a\xe9\x27\x78\xc5\xaf\xd0\x5c\xa1\xad\x57\xe8\x7c\xb2\x72\x55\xea\xad\x8d\xce\xcc\xdd\x33\xce\x03\x4b\x4f\x7c\xaa\x4e\xe7\x62\x7c\xd8\x73\x8e\x96\x6b\xc7\x91\x9c\xec\xab\xef\x9d\x0d\xb7\xb0\x8c\x39\x70\x45\xf5\xee\xab\xa7\xab\x3b\x7f\x35\xa8\x98\xf2\x08\x5b\x6c\xeb\x4a\x0d\x8e\x18\x07\xa5\x49\x8e\x29\x6f\x9a\x33\xda\x52\x9c\x8b\x03\x6c\x16\xa4\x9c\x78\x45\xd3\x81\x92\xa1\x95\xce\xd8\xb5\xd5\x50\xcf\x31\xbb\x7c\xa1\xca\x83\x73\x29\x39\x01\x53\xd6\xdf\x9f\x0e\x8f\xc7\x32\xd7\x56\x78\xc3\xb7\xaa\x8c\x2b\x8f\x13\x1c\x97\xe8\xf6\xed\x9c\xea\xba\x6d\xc2\x67\x5f\x7d\x6f\x96\x4a\xb5\x39\x57\x61\x4a\xf1\x06\xbb\xc1\x3d\xe0\xcf\x1f\x16\x06\xf2\x97\x15\x9f\xb3\x57\x18\x5c\x3f\xae\x62\x8b\x47\xc8\xdd\x5c\xb6\xc5\x40\x07\x87\x5b\x9f\xcd\x23\x95\x08\x21\xdc\xee\xbe\xa9\xb4\x3f\x3e\xb9\xc2\x94\xa2\xfc\xb9\xaa\xa6\x51\x23\xae\x59\x44\x6b\xe1\x4b\x75\x5b\xd5\xce\x24\xeb\x9b\x0c\xa4\x5e\x9e\xb4\xe5\xff\x98\xb2\xb8\x70\xae\x23\x4e\x48\xbc\xb7\xaa\x1d\x07\xda\xb9\x4e\x38\xe5\x77\x8a\x5c\x61\xd9\xe0\x1e\xeb\x63\xf3\x15\x9a\x4d\x5e\x5e\x57\xcd\xb2\x1c\x3b\xe7\x18\x64\x04\xe4\x6c\x5e\x4e\x93\x72\x03\xdf\x1c\xba\xe0\x9a\xad\x39\xf4\x95\xaf\x7d\xab\x2d\x57\xf6\x8c\xda\x3d\x57\x4d\xdf\x21\x62\xd2\x01\xe6\xaf\xaa\xaa\x70\x3c\xfd\x3d\x76\x78\x89\x88\x73\xf2\xfd\x31\x0b\x09\xcf\xee\x43\x4f\xfe\xbc\x5f\xcc\x4c\x73\xcc\x44\x20\x3c\xd0\x6d\x84\x62\xb9\xa9\xb0\x79\xa8\xac\xc0\xa5\xff\xfb\xa3\xd9\x54\x35\xee\x5f\xa0\x5c\xff\xca\x69\xae\xf8\x3a\x88\x1b\x47\x11\xd9\xbf\x83\x91\xc2\xc5\x00\x0e\x84\xf6\x39\x18\xec\x1b\x0d\x24\x94\x89\xb8\x5e\x3d\x3c\x3e\xdc\x5d\xaf\xee\x6d\x95\xcb\xed\x7a\xed\x91\x49\x82\x85\x9a\x7c\xcd\xdb\xbb\x87\xfd\xd3\xf7\xdf\x0f\x4f\xeb\xdd\xfa\xe9\xc7\xfa\x70\xbb\xff\x7d\xe8\x82\xe0\x93\xe2\x23\x28\xee\x87\xb3\x77\x3e\x6b\x87\x90\x96\x60\x69\x4a\xd2\xd3\x5f\x6f\x26\x39\x03\xc1\x38\xf2\x61\x1b\x27\x6b\x73\x32\x85\x45\xa8\x40\x5a\x69\xb8\x5f\x24\x2d\xdf\x6f\x83\xe1\x10\x0d\x18\xfe\x77\xd9\x30\x10\xa1\x0e\x69\xac\x14\x14\x8a\x68\xed\x3a\xf3\xe0\x83\xae\xc6\x2a\x42\x3c\x3d\x7e\x7f\xb8\x21\xa8\xa5\x7f\xd4\x48\x0b\x3a\x4f\xa0\x69\x3a\x5f\xbe\xbd\x90\x59\xf4\xfd\x4c\xac\xc8\x46\xbf\x9a\xbc\x69\x0c\x8e\x5e\xdc\xb3\x91\x91\x5e\xfc\x32\x43\x82\xbf\x44\x33\x1d\xb8\x92\x8c\xeb\xaa\x54\x78\x5a\xcc\x80\x4e\x07\x7c\xba\x43\x0a\xca\x13\xb8\x94\x15\xc2\xd1\x52\xf4\x4d\x7f\x26\x89\x65\x64\xd9\xc0\xf1\x2d\xaf\xce\xcd\x2c\x17\x21\x12\xad\xa9\x94\x6c\xa4\x60\x64\xf5\x13\xdf\xb0\xf3\x76\x6c\x18\xbf\x59\x11\x37\xc2\x90\x81\x18\x67\x19\x46\xcf\x3a\x7b\x3a\xc3\x13\xbb\x9b\x75\x46\xc0\xb8\xb0\x91\x8b\x34\xd0\x94\x8c\x39\x55\x45\xae\xde\xaf\xa1\xd4\xef\xd3\x94\x8c\x48\x45\x40\xba\x8f\x37\x00\x13\x67\xfe\x3c\x26\x5a\x9b\xbe\x6b\xaa\xb4\x48\x46\x4c\x06\x16\x6b\x4a\x1b\x91\xeb\x91\x65\x01\x61\xaa\xb1\x7d\xd9\x57\x93\x2f\xc8\xc3\x8c\xcc\x55\x24\x65\xcb\x52\xbd\xdb\x8a\xa6\x55\x51\xb8\x53\x7c\x24\xac\xc6\x05\x8f\x33\x2f\x19\x48\x08\xa5\x8f\xcc\x25\xc1\x41\x51\xe6\xf8\xec\x48\xa0\xe6\xa1\x5e\xc1\xa5\x60\xce\xca\xf8\x86\xef\x8b\x59\x6d\x21\x82\x94\xc7\x3e\x20\xb5\x2a\x26\x69\x37\x01\x2c\x34\x7d\x44\xce\x98\x02\x2d\xb5\xd6\xcc\x63\x13\x32\xb4\x40\xb9\xd3\x88\x49\x92\x0b\x19\xa7\xe4\x13\xea\xfc\x2d\x1f\x6d\xc1\x42\xa5\xcc\x31\x2d\xb5\x93\xd8\x77\xbf\x0e\x54\x9a\xd1\x1e\x44\x68\xfe\xe3\xa9\x7d\xbf\x1e\x82\x44\x42\x99\x84\x1c\x59\x97\x04\xda\x9d\x8f\xdb\x02\xfa\x56\x6d\x6c\xa1\xf6\x0e\x0c\x3e\xb8\xfc\xd6\xec\x61\x31\xb6\x80\x2c\x57\xd2\xe1\xa6\xec\x08\xf2\x3f\x19\x1e\x04\x8b\x47\x96\xa8\xaa\x23\x5e\x41\x5b\x54\x3d\x24\x42\x18\xad\x28\x88\x78\x53\x6d\xce\x4d\xae\xb6\x97\x3c\x21\x1c\x58\x67\x27\x12\xc4\x1a\x5a\xf5\x12\x1f\x72\x55\x35\xd6\x5f\x9d\x43\x30\x81\xc9\x8c\xd6\xff\x49\x7d\x90\x98\x86\x90\xd9\x8a\x2e\x8a\xcc\xaf\xaf\xf7\x63\x4f\x12\x42\xa1\xa8\x38\xb3\x3b\x46\x9b\x9e\xdf\x6c\x3a\x25\x20\x44\x0b\x99\xa3\x2a\xc6\xdd\xe1\xf6\xf1\xe9\xb0\x7d\x5a\xef\x56\xf7\x7e\xb7\x82\x28\xcc\x62\x27\xc8\xfd\xfc\x51\x61\x12\x24\x92\x11\x5e\x89\xe2\x11\x5f\x11\x48\x42\x65\xf2\x15\x21\x31\x81\xcd\x45\x38\x63\xf2\xa0\xa1\x3a\x8c\x85\x23\x5c\xbf\x34\x44\x61\x71\xac\xab\xd3\xe9\xba\xb3\x35\xc6\x31\x12\x48\x55\x4a\xc9\x6f\x47\x71\x53\x23\x12\x32\x6a\x94\x02\x8c\x83\xff\x39\x2f\xc8\xd1\x3a\x0e\x55\x0e\x59\xa0\xa9\x4c\xb4\x01\x83\x9b\xce\xb0\xce\xdf\x3e\x18\xde\x8c\x69\x8b\x48\xc6\x52\x6f\x3a\x97\xe1\x62\xe5\x5d\x10\xea\x2f\x1e\xdc\x90\x85\x48\xf1\x71\x2c\x55\xa5\x87\x42\xf3\xae\x93\x98\x41\x85\x20\xcb\xe4\xb0\x00\xed\x2a\xf3\x9f\x22\x93\x3c\x70\x79\xe8\x6f\x79\xdb\xbe\x5f\x57\xf5\xa2\x50\x19\x87\x0c\x19\x29\x99\xb8\x50\x3b\x0b\x36\x7b\x6f\x51\x03\x8f\x42\x42\x33\xbc\xe5\x55\x01\xe3\x7d\x09\xb8\x48\xbc\x84\xa9\x63\xb5\x1e\x22\xc3\xc0\xa5\x65\x0b\xfa\xe7\xfe\x5b\xe7\x06\xfa\xe2\x62\x0e\x22\x80\xc4\x06\x19\x5c\x79\x49\x75\x3a\xb0\xe8\x70\x83\x6a\x44\xb1\xc0\x41\x20\x27\x12\x4d\xe2\xd8\xbf\xb2\xe9\xe1\xeb\xea\x78\x8b\x38\x21\xcd\xef\x3a\x22\x01\x8b\x88\xce\xb9\xc7\x41\x02\x04\xdc\xfe\xd9\xc6\x0b\x7b\x5e\x28\x0e\x10\xc5\xb2\x17\x6f\x48\x0f\xd6\x55\xfe\x02\xcd\xf7\x06\x9e\x31\x0c\x82\x80\x42\xd4\xfd\xf3\x4a\xb0\x5a\x0f\x84\x78\x9b\x64\xae\x40\x1a\x8b\xcf\x3e\xc8\xb3\x26\x6d\x14\xbd\x2a\xf5\xa3\x31\xb9\x82\xc2\x12\x2f\x5e\x02\x14\x41\x1a\x49\x58\x47\x93\x97\x33\x7d\x0c\x0e\x8a\x09\x8a\xd4\x7c\xc1\x5f\x5b\x78\xdf\x63\xd3\x86\x93\x11\xd7\x59\x4a\xa9\xc7\x1b\xbc\xca\xa7\x0d\x26\x49\x6c\xb5\x3b\xda\x62\xfc\xfe\x19\x91\x85\x04\xdf\xda\x3e\xad\x6d\x6c\x8f\x05\x41\x70\xe8\xcb\xa0\x39\x20\xb7\xb5\x02\x25\xfe\x24\xce\xa5\xff\x53\xc0\x13\x4c\x12\x58\x7d\xd7\x6e\x63\x1a\x15\xa4\x80\x49\x23\x82\x4a\xc8\x56\x3d\x41\xde\x13\x16\x70\x30\xda\x0a\x48\x99\xbc\x1e\xd5\xb3\x4f\xbc\x01\x19\xc4\x96\x8a\xb6\x3b\x2f\xfe\x2e\x4b\x8d\xbf\x54\xc9\xd0\xd5\xbb\x7d\x39\x3d\x77\xe7\xd6\x78\xb6\x48\x16\x1b\x2f\xe6\x76\x6d\x79\x18\xa7\x4b\x41\xb2\x24\x90\xda\x8b\x2d\x80\x6a\x2d\x84\x6a\x54\x09\x22\x59\x26\x69\xc0\x9a\xf3\x09\x6b\x45\x45\x4a\x2f\xd0\xbc\x8c\xc8\x9b\xba\x3e\x8a\xd4\x76\xaf\x57\x0f\xd7\xeb\xfb\x7b\x62\xf2\x3d\xdc\xae\xfd\x2e\x29\xc3\xd0\xaa\x78\xb9\x0c\x38\xcd\xfc\x4f\xb1\xf1\x32\xcc\x42\x32\x86\x3a\x97\xea\xf6\x5c\x3e\xe7\x72\x54\xb3\xf9\x21\x3c\x4d\x86\xc2\xc2\x96\x1f\xb7\xeb\x27\xfb\x14\x5f\x1f\xef\x6f\xfa\x54\x9c\x0c\x05\x0b\x12\x5b\xe9\xae\x70\xc4\x10\x36\xfb\xf5\x04\x12\xca\x55\xd9\xe7\xbd\xc1\x5f\x2d\xd6\xf3\x74\x92\x3b\x48\x64\x8a\x56\x91\xe1\x4c\x03\xf8\xba\xaf\x89\x8a\xf3\x7d\xe1\x30\x95\x19\x0b\x32\x61\x03\xb1\x96\xd7\xe7\x4b\x0d\xa5\x5f\x64\x8b\x47\x87\xe4\x51\x44\x0e\x1a\x85\x31\xf2\xf2\xd9\x99\x66\x77\xa5\xa9\x06\x03\x66\x7e\x0d\xa4\x74\x32\x92\xef\xef\xca\xa7\xe6\x48\xfe\xd9\x15\x2a\xe1\x6a\xb4\xb5\x75\xb7\x7f\xa0\xc0\x6d\xd9\x9b\x37\x52\x08\x45\x4c\x21\xa7\x3a\x57\x54\xba\xe1\x4a\xef\x5c\x33\x84\xb1\x09\x7d\xe5\xa5\x13\x8b\x9c\x32\xb2\xcc\x7e\x54\x26\x96\xe8\xa3\x8f\xae\xde\x63\xf9\xdc\xd7\x83\x4b\x29\x90\x76\x9b\x32\x57\xf8\x7c\x7e\x8f\xfb\xbf\x3b\x24\xa8\xaa\x8e\xc7\x73\x99\xb7\xef\x5f\x09\x9d\xe4\x9b\x55\x98\xc4\x7d\x7d\x0d\xde\xa9\x6a\x44\x00\xf5\xf7\x96\x94\x4a\xe3\x34\x18\x48\xb7\x17\x09\xb7\xb9\x54\x10\x91\x6b\xfc\x80\xe7\x1a\x0a\x2f\x5d\xec\x1b\x75\x44\x0c\xb7\xe0\x52\x32\x95\x7a\x25\xc2\x92\xd9\x3d\x74\x26\xa2\x64\x22\x5d\x39\x9b\x30\x18\xc4\x54\x0a\xba\xd9\xdf\x7e\x30\x88\xa8\x81\xb4\x32\x47\xb1\xdd\x4d\x5e\x7e\x26\x24\x32\xbf\x01\xda\xd8\xc9\x50\x33\xbe\x2a\xab\xf6\xc5\xae\xcf\x8f\xb0\xe1\xee\x5a\x13\xca\x24\x1a\x61\xa3\x96\x67\x97\x0a\x98\xa0\x00\xf9\xfa\x98\x5b\x41\xad\xf7\x3b\x3d\x57\x20\xe0\x2a\x8c\x51\x48\x0f\x61\xde\x51\x68\xf9\x26\x87\x62\x41\xa1\x8b\xab\x50\xf1\xd8\x63\x28\xbe\x97\xb9\xaa\xea\x3e\xb4\xac\xa2\x0c\x2c\x56\xe9\x88\xa5\x1e\x9f\xd1\x2a\xe2\x90\xb9\xc4\x00\x85\xd5\xa9\xf6\x67\xf9\x91\x23\x69\x65\xc5\xcd\xb9\x3d\xd7\x48\xd1\x8d\x31\xbf\x29\x57\x91\x36\x99\x23\x7d\xb0\x04\xc8\x5b\xc7\xa1\xbb\x0c\x71\x56\x11\x86\x38\x14\x90\x13\xbe\x66\x16\x7b\x5f\xf2\xa3\x54\x84\x19\xd8\xac\x18\xe9\x14\x62\xe7\xcc\x92\x57\x48\xd0\xd8\xdb\xaa\x7e\x3c\x39\x2c\xc1\xe2\x46\xa6\x22\x13\x12\x0e\xec\xf4\xd6\x4e\x02\xf0\x2a\x89\x12\x4f\x89\xbf\xad\xaa\xb1\xec\x2b\x57\x09\xda\x6c\x8c\xf2\x78\x40\x57\x35\x34\xe4\xd0\x54\x1a\x2a\x7a\x2e\xeb\xdd\xdd\x0c\x72\xfb\x8b\x06\x97\x4a\x79\x92\xb9\x5f\xbb\xcf\x4b\xfc\x7e\xb2\xfe\xe0\xe1\x98\xcf\xd9\x8f\xb8\x4a\x75\x4c\x99\x03\xe3\xb0\x31\x24\x6f\xe7\x7f\x37\x0b\x80\x5c\x51\x12\x62\xee\x81\x2c\xbb\xce\x02\x25\x78\xf5\xf2\x28\x64\x89\xcd\xbe\x38\x1e\x40\xab\x74\xf6\x99\x0a\x2a\x57\x3c\x32\x99\x4d\xea\x48\xbb\x89\x1d\xf2\xb2\x33\x9c\x66\x13\x91\x2b\x0d\x59\x9f\x8f\xfa\xcd\xef\x64\xb3\x57\x12\xac\x97\xbf\xbc\xb6\xb5\x8f\xdd\x38\xf9\x77\x12\x46\xd0\xe1\xe9\xf8\x87\xd7\x50\x97\x84\x33\x5b\x94\x31\xfb\x7c\xef\x52\x20\x42\x8a\xff\x94\x08\x35\x36\xed\xb7\xb2\xfa\x59\x12\xb0\xc9\xff\x18\x40\x16\x3a\x68\xed\xfd\xfd\x8f\x03\xea\xbc\x3d\xb0\xb0\x6f\x55\x8c\x0f\x05\xbc\x84\x86\xfc\xb4\x9a\x51\xc9\xd0\x10\xec\xe8\x66\xfd\xd0\x8e\x0c\x34\xa5\x18\x27\x9e\x57\x79\xea\x3c\x64\x02\xe8\x7e\xb0\xd2\x90\xc5\x54\x79\x4c\xd9\xf5\xaa\x85\xe2\x75\xac\x61\xcf\x15\x46\x31\xb3\xcc\x56\xdd\x8c\xd9\xc2\xfb\xc8\x36\x51\x86\x09\x14\xa3\xfa\xd7\x4f\x2a\x2a\x94\x51\x8a\x4c\x83\xa7\xf5\xcd\xcd\xf5\xf5\xa3\x67\x99\xe6\xca\x18\x15\xb8\x6d\xe1\xe0\xcb\x6d\xa6\x9f\x59\x07\x2c\xa4\x98\x2c\x51\xf3\xdc\xf9\x67\xd3\x01\xc4\x9e\xff\xee\xa6\x7d\xd9\x4f\xe2\x32\xae\x0b\xe3\x4c\xf0\x41\x3d\x62\x57\xc2\xa9\x79\xa9\xda\x25\x39\x83\xae\xb3\x05\xb7\x0f\xd2\xeb\x8d\xc3\xc7\xf5\xf6\xa4\x66\x02\xc9\xe1\xdc\xe4\x65\xdb\x53\x1a\xfd\x75\xd5\xab\x0e\x43\x90\xc1\x88\xd2\x7b\x93\x97\xbf\x61\xbe\x40\x36\xc7\x75\x14\x0b\x3e\x58\x3f\x9d\x2f\x35\x26\x22\xbf\xad\xea\x41\xa0\x95\xeb\x28\x8d\x28\xaa\x95\x17\x45\xfe\xdf\x73\xae\x97\xdf\x2c\xe2\x9a\xbe\xe2\x0e\x4b\x7c\x86\xe2\xad\xb9\xae\x8a\xea\x28\x73\xf0\xb7\x89\x13\x5b\xf1\x44\xa9\x98\x95\x52\x63\xcb\x70\x8c\x0d\xd7\x71\xaa\x22\xe3\xfc\x9f\xdd\xa9\xce\x5b\xf4\x0f\xb4\xb8\x22\x74\x8c\x16\x9a\x6b\xb0\x97\xf5\x2a\xd0\xd2\xcb\x58\x0a\xee\x77\x24\xc1\xa9\xe3\xbc\x56\x4d\x27\x09\x58\xac\xda\xd3\xf5\xf5\x5f\xa6\xb0\x75\x82\x8c\x0c\xf1\x73\x49\x82\x12\x76\x2a\xf6\xf9\xca\xe9\x9d\xd3\xc8\xea\xf1\xeb\x6a\x6c\x82\x5e\x66\x21\x74\x1a\x29\x72\x1e\x57\x9b\xdb\x49\x94\x53\xa7\x49\x98\xf4\x4e\x1d\x95\xb1\x50\xe8\x67\xfd\x5f\xfa\xa7\xef\x65\x74\x98\x78\x72\x2a\x35\x0a\x2d\xfb\x63\x40\x67\xb1\x21\x5b\xe7\xfe\xfd\xfa\x6e\x7e\x20\x9d\x3f\xd0\x51\xe0\x3a\x53\x56\x88\xee\xda\xed\x58\xcf\xcf\xcd\x2e\x2f\x15\x49\xe0\x4c\xea\x10\x5d\x7f\x9e\xb2\xc4\xe5\x01\xd6\x6f\xf8\x01\x28\x73\xb4\x15\x2f\x91\x8b\x68\x8e\x2c\x93\x1e\xf6\x4e\x31\xea\xbc\x99\x9c\x69\x9a\x1b\xf4\xa5\x3b\xdf\x4b\xda\xf4\x46\x43\x29\x62\x8b\x73\x27\x21\x5f\x83\xa5\xbe\xaa\xaa\xc6\x56\xd9\x9c\x8a\x7c\x6e\x61\x68\x21\x03\x62\xb7\x69\x11\x8e\xdd\x01\x79\x57\x5a\xd0\x8a\x6f\x56\x11\x65\x24\x4b\xfc\x79\x6d\x11\x2d\x9f\x51\x86\xcd\xfe\xdc\xbf\x12\x44\xb6\x0a\xa4\x7b\xe0\xce\xcf\x61\xb7\xe1\x6d\xf4\x39\xda\x51\x43\x26\x81\x0d\xf1\x84\x85\xc8\x98\x96\x0a\x69\xb8\xbf\xd0\x52\x7f\xcd\xcb\xe7\x87\xbe\x80\x46\x4b\xa3\xc5\x60\x30\xf6\x6a\xcc\x7f\x2b\xf3\xaf\x55\x2a\x29\xab\xe8\x8d\xc5\x7a\x9c\x64\x5b\xdc\x76\xb5\xca\x02\x1f\x55\xfd\x03\xbb\x53\xfb\x7a\x14\x6d\xe8\x5a\x29\xc3\x67\x10\x6d\xb5\x12\x55\x5c\x8f\x2c\x0d\xad\x81\x89\xc8\x5b\xe3\xf5\xb8\x5e\x5c\x9b\xc0\xa0\xc3\x21\x58\x1b\x6c\x66\x76\x68\xa3\x23\x10\xbd\x6e\xdb\x88\x6d\x7f\x16\x92\xc5\x20\x8a\xc8\x3e\xa9\x4e\x4e\x0d\x1a\x8a\xa9\x8b\x8e\x61\x0c\x74\x7a\xec\x56\xf7\x6b\x76\x78\x5a\xed\xd7\x7d\x8b\x36\x01\x65\x6f\x2a\xd3\x1e\x94\xa7\x89\xe6\x18\x2b\x20\x0b\xd1\xc1\xb9\x63\x6c\x2f\x51\x57\xd3\xa7\x88\x75\x46\xf5\xe3\x5b\x2c\xb7\x50\x8c\xd7\x3b\x26\x9a\x13\x29\xc0\x57\x28\x46\xbb\xfe\xe4\x6d\x31\x65\x82\x72\xad\x37\x8f\x8f\x9b\xd1\xf9\x86\x69\xa2\x09\x04\x26\x49\xba\xbf\xe7\x56\x6b\xee\x8e\x27\x8b\xaf\x1d\xc7\x64\x30\x0b\x12\x92\x26\x22\x02\xd9\xca\x43\x93\x27\x3e\x16\x66\x59\x9c\x59\xab\xa7\x40\x68\x50\xaf\x26\x7d\xfb\x5e\x98\xd0\x2e\x71\xbf\x7a\xb8\x39\xac\x6e\x6e\x9e\xd6\x3b\x0f\xf8\x45\x1e\x48\x82\x15\x7c\x6f\xb0\xfe\x42\x4c\x08\x7f\x62\xdf\x16\x25\xa9\xea\x6d\xaa\x2b\x6c\x97\x08\x04\x39\xf2\xd8\xd6\x66\x3d\xc3\x11\xbf\xe4\xa6\xdd\x61\x39\x8d\x57\x21\xcf\x2c\x81\xa5\xb3\xe0\x9a\x43\x2f\x7c\x41\xd4\x9b\x6a\x56\xee\x82\x9c\xf7\xf9\xcc\x0d\x45\xd0\xa6\xe3\xcb\x45\x40\xe5\x58\x37\x79\xd3\xed\x7a\xb3\x29\xc4\x25\x27\x28\x9c\x86\x16\x76\xd5\xb9\x56\xe8\xd9\x80\xbe\xd4\xd5\xf9\xb4\x54\x37\xed\xaf\x54\x76\x6a\x3d\xab\xd3\x71\x76\x53\x11\x30\x4a\x0a\x1c\xbb\x81\xbd\xb2\xdb\xe1\xbc\x4b\x92\x92\xbb\x53\x56\xc4\xb8\x94\x0f\x94\xf0\x1c\x45\x26\x68\xff\x6f\x66\x8b\x0a\x85\x61\x24\x4f\xef\xca\xd5\xae\x70\x36\x72\xc2\x70\x22\x85\x87\xa6\xc9\x9f\xcb\xa7\xca\x6a\x1a\x90\x4e\xc3\x14\xab\xff\x99\x58\x25\x47\xc8\xb8\x87\x28\xde\xa0\x81\x73\x61\x93\xb0\x30\x93\x7b\xe3\x28\xb9\x08\x7a\x11\xdc\x75\x5d\x57\x7d\xfc\x14\x25\xd8\x71\xcd\x55\x45\x2e\xf4\xb9\x5f\x60\x2a\x00\x4b\x93\xaa\xa0\x2c\x51\xef\xf2\xe2\x0d\xeb\x6b\x38\xf5\x97\x2a\x57\x86\xa0\x2c\x57\xe8\xba\xc8\x9f\xc7\x31\xfe\xa9\xc5\x8f\x2a\xe2\x54\x2f\xb1\x79\xba\xee\x6f\x90\x5a\xd2\x88\x2b\xec\xc3\x12\xa8\x38\x83\xc0\x23\x7c\x9d\xa9\x3e\x9b\x28\x4a\xa4\xd4\xe5\xcb\xd3\x7a\xdd\xaf\x42\x05\x61\x98\x4d\x25\xf0\x97\xec\xeb\xbe\xb7\xc4\xb4\xf7\xaf\xfa\xf4\xc4\xee\x84\xf3\x0a\x40\xd4\x21\xa3\x30\x7c\x91\x97\xaf\xb7\x79\xb7\x35\x4c\xbc\xcb\xc9\x21\x8a\x3a\x8e\xc8\xa6\x21\x27\xbb\x17\x6e\xf6\xf1\x1a\x8b\x23\xf5\x4f\xac\xbb\x0d\x74\x54\xf4\xf3\xbd\x6c\xaa\x62\x8a\xe3\x42\x2d\x18\xd9\xff\x9a\x74\x5d\xce\x83\x08\x2f\x47\x4c\x03\x0a\x6e\x58\xbe\x9d\x6d\x81\xfa\xd9\x53\xa5\xcc\xde\x00\x8d\x20\x52\x86\x6e\xb9\x1f\xac\x68\x36\x2d\x50\x79\x9e\x54\x19\x4d\x2f\x32\xc0\xb4\x9c\xb1\x93\xdf\x5d\x3f\x5a\xe2\x3e\x27\x4e\xc6\x4d\xc0\xac\x72\x4a\x83\xa4\xe9\xf1\xa5\x46\x2c\x87\xdc\x2c\xf7\xbd\x78\x98\xf2\x41\x8e\xd3\x61\xbe\x27\x5f\xc4\x04\xdc\x84\x38\xb8\xb0\xdd\x41\x34\x7d\x0d\xc3\xa2\x94\x38\x07\x56\xfb\xfd\xd3\xe1\x7e\xbd\xda\xad\xae\xfa\x3c\x91\x61\x60\x59\xc9\x41\x53\x15\xce\xaa\xf4\x9b\xe6\xbb\x8d\x86\x5e\xc4\x43\x4c\xc8\x2c\x90\xfe\x50\xd5\xf9\x73\x5e\x42\x71\x75\x7e\xdf\x0e\x54\xdf\xdc\x84\xa1\xf2\xaa\x07\xab\xb3\xce\x7b\x29\xee\x99\x29\x63\xa2\x20\x51\xe9\x88\xcf\xe4\x66\x38\x42\x4d\x92\xa4\xa1\x85\x54\x17\x8e\x0f\xf2\x47\x5e\x9f\x67\x13\xda\x24\x89\x26\x4c\x62\xf3\xeb\xe4\xc2\x31\xbe\x41\x58\x59\xf6\x06\x5b\xca\x6d\x35\x5b\xac\x37\x55\xd9\xbe\xcc\x1e\x21\xc1\x80\xa2\x1f\xd7\x70\x3c\x51\x89\x6a\x0f\x54\x32\x09\x5a\x11\x6d\xe2\x93\xf7\x1f\x92\x00\xb9\xbe\x47\x16\x1b\x89\x03\x2d\x6f\x73\x46\xed\xa5\x8d\xbd\x26\x12\x37\x59\x9a\x65\xc2\xab\xf7\xd2\xea\xb2\xba\x7a\xf4\x99\xff\x15\xfe\x7b\x60\xfe\xfa\x57\xfc\xef\x51\xe0\x98\xff\x7b\x94\x40\x4f\xff\xdd\x8f\x7e\x26\x18\x19\x78\x37\x90\x17\xef\xab\x52\x7b\xc7\x0d\xe4\xbc\x74\xcb\x64\x80\xd8\x3f\x5f\x5f\x23\xd9\x3f\x98\x16\xca\x11\xcd\x5d\xe5\x0e\xe4\x3b\x43\xfe\x19\xd0\x99\xb4\xea\x08\x70\x3c\x8d\xcf\x7d\x03\xc6\x50\x00\x30\x6f\x46\xf5\xcc\xd3\xbd\xc2\x48\x65\xb1\x6e\x3f\x31\xdf\x57\x2e\x33\xeb\xaf\x57\x91\x92\x8e\xf4\x6a\x4e\xe0\xec\x7b\x24\xa1\x8c\x86\xba\xc2\x9b\x5c\xe1\x53\x55\x7c\x10\x28\x36\x0a\x22\x4a\x88\x6e\xb0\x3c\x07\xd1\x6c\x20\xb4\xb0\xa9\x15\x07\xb9\xfb\x24\xac\x6d\xb4\xd6\x84\xdd\xdb\xa0\x5e\xdd\xd1\xb1\xf5\xd7\x2e\xac\xc1\x50\x58\x0e\x32\x0a\x05\x2c\x49\x6a\x70\x63\x92\x18\x07\x19\x81\x27\xec\x6e\xa0\x5a\xd4\x3f\xba\xd3\x67\xf2\xea\x22\x08\xe2\x88\x00\x75\xbe\x82\xe2\x06\xdf\x46\x71\xde\x45\xd1\x04\x11\x04\xdc\x0a\x65\x82\xd6\x56\xcf\x7d\x9f\x17\xbe\x04\x66\x74\xac\x8b\x80\x05\x89\x19\x3b\xf3\xeb\xbb\x6d\x18\x5c\xda\x6d\x22\x60\x3c\x09\x7b\x11\xd5\xc5\xf0\xa1\x08\xa2\xd0\x80\x47\x09\xe2\xd7\xaa\x6e\xf0\xd2\x6f\x9c\x9f\xc9\x73\x4b\x43\x04\x51\x66\xd3\xf3\xdd\x1e\x06\x8d\xdd\x35\xee\xf4\xec\x71\x22\xcd\xa9\x94\x5d\x41\xb9\x43\x4f\x4b\x29\x82\x58\xd8\xf3\xab\x5b\xe6\xe7\xd3\xce\xd6\x7a\xf7\x8d\x3a\xe2\x8e\x2a\xea\x09\xd5\xe4\x93\x88\x20\x36\x29\x35\x0e\x05\xe7\x64\xee\x35\xe3\xba\x21\x11\x24\x51\x66\x81\xa6\x70\xf4\x65\x4c\xfc\x5f\x2c\x4b\xff\xbd\xf0\x1e\x09\xcf\x68\xa2\xb9\x30\xd5\xc9\x34\x5f\xa0\xc5\x9f\x30\x49\x7e\x89\x20\x65\x48\x8b\xa7\xcf\xa9\xe3\xc0\xef\x28\x82\x34\x0a\x9c\xe0\x04\x91\x06\xec\xf3\x1e\x3e\xef\x3b\x70\x4b\x18\x47\x49\x91\x53\xae\xae\xde\x1f\x8d\x99\xeb\xbd\x88\x80\x33\xcb\xab\x6f\x1d\x14\x7d\xdf\x59\xc4\x2e\x93\x31\x7e\x66\x6e\x42\x12\x14\x6c\x5f\xf2\x5a\x8f\x99\x44\x3c\x07\x92\x08\x84\x40\x0a\x27\x6d\x56\xbf\x1f\xbe\xef\x6e\x0e\xb7\xdf\x1f\x6e\xfa\x36\x0d\xe9\x80\xe1\xf6\x58\xbd\x4f\x7d\x45\x11\x08\x63\xf9\x58\x9e\xa1\xb9\xad\xea\xdb\xfb\x6f\xfd\xed\x20\xb0\x5a\xef\x14\x3f\xa8\x1d\x71\x75\x55\x50\x04\xfb\x50\x3a\x4a\x38\x55\xe9\x61\xb8\x24\x4b\xe9\xa4\xdf\xbf\xd4\x88\x54\xba\x49\x22\xa7\xbe\x15\x85\x75\x8f\xd6\xfb\x0b\x0a\xb6\xc9\xa0\xaa\x28\x92\xdc\x87\x24\x4e\x55\xdd\x43\xef\x1e\xeb\x7f\x62\x5d\x5d\xbd\x5b\x58\xc8\x18\xb8\xff\xb5\xcf\x36\xf6\x8b\x50\x81\x55\x9c\x29\x08\x39\x39\x58\xb6\x22\x50\xd2\x12\x69\xdb\x71\xda\x60\xf3\xb2\xad\x96\x01\xb5\x22\xd0\x71\xaf\x1b\x7e\x5f\x75\xe7\xfe\x63\x89\x4b\xd4\x9a\x22\xd0\xda\xf2\x04\x18\xf7\xe7\x69\x33\x0b\x02\x9e\xd8\x5a\xda\x53\x73\xd7\x3c\x0d\xe2\xa7\x0e\x84\xee\xbb\x45\x8a\x4c\x88\x27\xfc\x0f\x41\xe2\x47\x74\xe9\x1f\x60\x73\xfd\x85\x3c\x0a\x9c\x15\x73\xed\x95\x59\x9d\x88\x4f\x1f\xe1\xe8\x7a\xa5\x64\x6d\x13\x34\xa4\xae\xde\x66\x20\x64\xc1\x98\xe6\x74\x1b\xc7\x48\xc1\x86\xfc\xb5\x60\xa1\x0c\x08\xd3\xff\xf5\x71\xbb\x1e\x9d\x40\x82\x45\xa1\xf5\x7a\x56\xdb\xdd\xd6\xff\x2d\x66\x86\x3b\xcb\xe3\x0a\xdb\x8b\xa2\x79\xc1\xe2\x24\xd1\x4e\xe1\x79\x9b\xa3\xc2\x55\xa9\xe9\x2b\x7e\xc6\xd2\xe9\x2f\xcd\x2c\x3b\xdf\xa1\xc6\xa6\xdb\xb2\xfb\x3f\x5b\xed\x42\x6b\x84\xae\x8a\x79\xa0\x76\xd1\x03\x11\x2c\xd6\x2c\x70\x06\xca\x31\x2f\xc7\xb4\x1c\xb3\x27\x4e\x32\x9e\xe0\x90\xb1\x6b\xf6\x95\x3f\xc9\xfd\x13\x24\x9c\x29\x57\x03\x39\x86\x39\xcc\x7e\x30\x51\x81\xa5\x40\xf2\xfc\x47\x9f\xe8\x6b\x76\xbd\x05\x15\x98\xbc\x61\x9d\x9b\xf7\xbf\x92\x75\xfe\x9f\xd1\xc7\x4e\x43\xa0\x5d\x87\x28\x99\xd7\x0e\x29\xd7\x3f\x6b\x1a\x67\x8e\xad\xf7\x17\x69\xae\x50\x0a\x60\x6c\xba\x09\x26\xc2\x28\xb2\x28\xbb\xbc\xfd\xad\xaa\x5f\x17\xc3\x40\xbe\x6f\x26\x42\x92\x0e\xa9\x88\x40\xf2\xb1\xbc\xc9\xdf\xae\xde\xbb\xf5\xea\xef\x06\xc6\xaa\x6c\xe8\xd7\xab\xab\xe9\x5a\x65\x60\x2c\x19\xa6\xa7\xab\x70\xe5\x83\xfe\xec\x60\x92\x31\x8a\x7a\x94\x55\x9b\x9b\xf7\x83\x13\x96\x3f\xd4\xb4\x48\x66\x5f\x49\x26\x8c\x66\xe9\x75\x55\x76\x93\x63\x21\xfa\xe4\x3b\x4a\x24\xe7\x63\xff\x82\x37\x08\x7a\xf7\x92\x8f\x94\xf1\x04\x53\x52\x51\x6d\x49\xd3\x56\x27\xab\x0f\xd5\x4e\x1f\x4a\xeb\x98\xf5\x14\xe2\x8f\x6f\x58\xd7\xb9\xc6\xd9\xc3\x98\x20\xa2\x14\x1a\xfe\xf7\x0c\x85\x2d\x62\x6d\x16\xea\x1c\x45\x18\x44\x99\x15\x89\x7e\x39\xb7\x1f\x79\xce\x7d\x57\xad\xfa\xc1\x1a\xcd\x72\xdf\xac\xb9\x17\x99\xfb\xd6\xe3\xac\x45\x18\x98\xcc\x8a\xe8\xb6\xf0\xbc\xb4\xd3\x85\x2c\xb6\xe4\x91\xdd\xac\xac\x2c\xe4\x79\x1a\x02\x13\x21\x4b\x53\xda\x98\xdd\x01\x63\xb5\xdc\xe7\xc7\xcb\xe2\x60\x87\x2c\x05\xb2\xee\x2d\x69\x9b\x5e\xac\x6e\x72\x86\x75\xd7\xd9\xf8\x58\xf0\xe1\x58\x95\xb4\x46\x46\xd6\x53\xff\x8f\xef\x9e\x09\x92\xdd\x38\x51\x2e\x7f\x93\x97\x77\x24\x68\xe4\xdf\x9c\x09\x08\x63\xbf\x85\xfb\x1a\x8e\x51\xd2\x57\x84\xc4\x3b\x39\x5a\x90\x24\xd9\x66\x31\x78\xff\x58\x3a\xa7\x3e\x26\x97\x16\x61\x94\x59\x4e\xb7\xa7\xed\x9a\x5c\x4d\xd2\x36\xb8\x24\x5b\x13\x61\x12\x68\xe5\x68\xf6\xdd\x5e\xbc\xad\x71\x97\x3f\x97\x68\xf7\xc1\xbf\x59\x75\xe9\xef\x16\xc7\xe0\xee\x76\xb8\xb9\x3a\xe4\x17\xfb\x6d\x98\xc4\x92\x3e\x5e\x9d\x3f\xbf\xb4\xa1\x98\xb5\xa6\x89\x85\x1f\xc2\xe9\x74\x70\x65\x26\xfe\x41\xb3\x38\xe6\xe0\x65\x47\x3a\x6f\x9b\xb6\xb6\xc9\x02\x0e\x33\xa9\x08\xe0\x52\xe4\x8d\xe3\xde\x3a\xc8\x7c\x66\x35\x86\xc0\x92\x50\x7b\x16\xd8\x67\xbf\xbf\xb2\xc5\x8a\x34\x11\x82\x8e\xa8\xc2\xb5\x80\xc6\xf2\x2e\x1c\x0c\x4b\xba\x91\x39\xf8\x03\xd6\x75\x94\x61\xa8\xd2\x41\x25\xbb\x3a\x9f\x46\xfc\x2a\xd1\x94\xcd\x59\x84\x32\xce\xbc\x88\xca\xb6\x6a\x72\x1b\xda\x38\x97\x2d\x5b\xde\x25\x42\x15\x84\xe4\x39\x91\xd4\x4c\x33\x86\x9f\x88\x50\x09\xa6\x42\xcf\x2b\xd2\xcd\xaa\xbb\xa1\xf6\x64\xfa\xab\x4a\x26\x71\xec\xa8\xce\x46\x22\xcf\xf4\xb9\xeb\x4b\xd2\x30\x11\x22\x33\x14\xd2\x02\x27\x11\xe5\xac\xdd\x8b\x34\xc8\xf4\x61\x31\x13\xca\x06\xf3\x10\x8a\xce\xd2\x24\x9d\x94\x9f\x79\x4b\x34\xc1\xd3\x4f\x1e\x05\xb1\xad\x4c\xd6\xb6\x62\xa3\xb1\x73\x6f\xfa\x61\xa3\x00\x62\xda\xc0\xbc\x7d\x6c\x05\x8b\x66\x37\x02\xa5\x5d\xf0\xe0\xfa\xfa\xab\xcd\x17\x87\x99\x1b\xa4\x88\x71\x6d\xc5\x1d\x09\x8d\x49\x34\xa6\x4d\xdf\x06\x19\x7d\x63\xc7\xce\xe4\xf2\x20\x93\x77\x8a\xc2\x34\xa3\xc3\xfe\x0d\xf2\xc2\x67\x0e\x6f\x2b\xab\x4b\x45\xac\x2b\x23\xd3\xa8\xbf\x44\x05\x56\x4b\xb5\xb3\x82\x46\xb8\x05\x11\x85\xc6\x72\xf6\x92\x6d\xd9\xcd\x41\x9a\x5a\x8e\x3e\x7f\x35\x3b\x4b\xa2\x88\x71\xab\x98\xbf\xd9\x6c\x47\x67\x43\x14\x85\x8c\x72\x6e\x57\x97\x0e\xf7\xe7\xeb\x34\x8a\x99\x02\x36\xaa\x87\x59\x1d\xdb\x6d\x35\xff\xd9\x58\x26\x64\x91\x1c\xfa\xda\xe4\x79\x07\x13\x13\x92\xd3\x13\xfd\x4c\x43\x66\xa3\x6a\x0f\x11\x25\x51\x98\xba\x8a\x02\x4f\xe7\xd9\xcc\x02\x10\x22\x4a\x43\xe6\x61\xab\x57\x79\x51\x58\xc1\xcb\xe9\x98\x66\xa1\x21\xb8\x12\x81\x4a\xc6\x3c\x76\x22\xca\x4c\x9c\x7a\xa5\xad\xab\xc7\xd9\x75\x9c\x29\xb2\x03\x4f\x58\x9b\xaa\x3e\x3a\x1d\x83\x4b\xff\xf3\x72\xa8\xb8\x52\x94\xc5\xf6\xb1\xc5\x6d\x5d\x55\x66\x41\x5c\x5a\x44\x02\x58\x20\x07\x12\xb4\x4b\xfd\x62\x11\x41\x68\x35\xae\x5c\x01\xb3\xee\xe5\xaf\x44\x04\x5c\x51\x1d\x02\x9d\xe3\x9e\x04\xe3\x12\x78\x2e\x22\x15\x18\x8a\x41\xf6\x6b\x92\x42\xad\x8b\xeb\x37\x52\x10\x19\x17\x0a\xbc\x25\x54\xe7\xbb\x2a\x70\x84\xb2\x10\x91\xd2\x19\xb3\x85\x30\xcd\x4b\xcf\x8f\x2e\x22\x65\x62\x82\xae\x59\xdd\x94\x28\x28\x7b\x7a\x0c\x11\xe9\x38\x8c\x3d\xd7\xc8\xfd\x24\xf9\x24\x22\x9d\x31\x5a\x4a\x66\xf7\xdf\x7a\xfe\xe0\x1a\x90\x85\x3d\x0d\xfc\x5c\xc5\x51\x44\x28\x24\x8d\xdf\xe3\x96\xe0\x90\xdb\xc7\xc7\xfb\xc3\xea\xfe\xfe\xf1\xba\xef\xa0\x2c\x5a\xb0\xdb\x60\x1f\x8d\xb9\x86\xd2\xae\x98\x2b\x50\xaf\x96\x7b\x6f\xa5\xff\x73\x6e\xda\xee\xa6\x44\x56\xee\x2e\x8c\x03\x61\xa5\xef\xd7\xed\x8b\x2d\xcd\x73\x7f\x67\xa1\x86\x74\x82\x62\x98\xe1\x32\x16\x8d\xcc\x98\x41\xe0\x55\x22\xad\x30\xf4\xac\x9c\x4c\xc4\x4c\x67\x72\x60\x90\x1e\x58\x25\x7d\xfa\x7e\x31\x74\x12\x87\x81\x91\xcc\xb1\xc1\x13\x7f\x9f\xbf\x5d\xc8\x93\x2c\x18\x4a\x76\xe6\x7b\x68\x1c\x19\x0b\xd9\xf2\xef\x61\xa5\xb1\x27\x3c\x96\xae\x67\x1c\x03\x45\x0a\x5e\xa0\xd4\x45\xbf\x81\x5d\xdc\x30\xe6\x19\x99\x0f\xbb\xb6\x3a\x0d\x10\x0a\x11\xc7\x32\x96\xb6\x7c\x90\xf0\xe1\xe5\x14\x2a\x93\xc6\xe3\xd8\x47\x9c\xa4\xb6\x8a\x82\x3c\x77\x36\x61\xc9\x14\x71\x22\x80\x2a\x97\xe5\xf9\x9d\x05\x7f\x51\x21\x64\xab\x98\xfe\x9f\xfe\xeb\x7e\x2d\x4b\x42\x2b\x7c\xd4\xbc\xde\x56\xf5\x73\xfe\x86\x65\x37\x69\xc7\x27\x7d\xcc\x03\x88\x5d\xc8\x89\x3c\x0c\x5a\xbf\x84\x60\x23\x29\xab\xf1\xed\x78\x60\xd0\x3b\x2d\x9b\xbc\x6c\x6f\x11\x57\x72\xb6\x1d\xc4\x3c\xd1\x94\x08\xbd\xc1\x61\xa5\xda\x40\xe0\xb6\xae\xde\xf2\x05\xd1\x20\x7f\x21\xd8\xe3\xd3\xce\xc5\x9e\xc6\x75\x79\x2e\x72\x93\x78\x0d\xd8\xd5\x51\xe6\x73\xa8\xf2\xe4\x18\x8d\x05\x8b\x68\x1e\xd1\x21\x48\xdf\x75\xfa\xcb\x22\x34\xb4\xea\x07\x32\xdf\xdb\x6a\x3e\x83\x04\x4f\xa8\x72\xee\xbb\x53\x3f\xc5\x57\xcb\xb7\x7c\x77\x29\x83\x39\x7b\x54\x90\xc1\xc0\xd2\x3e\x11\x66\xf0\x38\x25\x11\xcb\x40\xd1\xd2\xba\x59\x0d\x5b\x63\x2c\x03\x4c\x5d\x39\xf6\xfa\xd7\x09\xeb\x1c\x17\xc8\x8c\x2d\x7f\x5a\x14\x7a\xf3\x3d\x56\x81\xb2\x72\x5d\x16\x58\xb0\x3e\x55\xbe\x72\x55\xc4\x0a\x21\xb6\x26\x13\xd4\x97\x14\x23\xfd\x2d\x74\xa0\x29\x71\xeb\xbf\xc1\x42\x68\x36\xd6\x26\xa5\xa2\x26\xbb\x63\x7f\x6f\xf4\xba\x7d\x79\x9a\xd3\x49\x89\x18\x45\x4c\x74\xb4\xd0\x1d\x59\xbf\x21\xbe\x16\xef\x9e\xa5\x7e\xf9\xc3\x22\x86\xc1\x20\x01\xbd\x81\xba\xce\x47\x15\x55\x1f\xd6\xab\x8c\xa6\x69\x12\x30\x2b\xd1\x90\x37\x57\x79\x75\xc4\xb6\xce\x95\x2b\xa8\x9b\xbc\x42\x12\x84\x2a\x49\xbc\xf0\xb5\xdf\xc3\x92\x40\x25\x44\x7c\x60\x3d\xfe\xbc\x7c\xee\x39\x00\x45\xc2\xa2\x84\xd0\x15\xbb\x73\x43\x87\x8f\xee\x1b\x9c\xea\xa4\x82\x42\x39\xbd\xc3\xdf\x30\x6f\xf6\x95\x73\x86\x26\xef\x98\x84\x10\x90\x01\xb1\xc1\x16\xb6\x75\xf5\x9f\x3e\x1d\x20\x92\x28\x08\x28\xab\x71\x95\x8f\x74\xfe\x44\x12\x71\x8c\x1d\x98\xf5\xc7\xc9\x7c\x24\x6c\x7b\xf1\xaf\x9f\x22\xfe\x2e\x80\x84\x0a\xd8\x80\x65\xb8\xeb\x1c\xef\xa2\xd7\x5d\x17\x49\x84\x01\x48\x9b\x21\xc7\xb5\xaa\x9e\x2c\x78\x20\xf2\xcd\x23\x02\x18\xcb\x38\xf6\xe9\xbc\x4f\x92\x0c\xc9\x85\x27\xc6\x4e\xed\xfd\x92\x71\xe1\xa2\x48\x12\x48\x9d\xaf\x79\xcc\xcb\xf9\x92\xef\xdc\x07\x3f\xcb\xa3\x9e\xc1\x78\x29\xe6\x9f\x24\x5a\x53\x8e\xdd\x4a\x2e\x1f\xfc\x81\xe0\xc9\xf2\x2e\x70\x55\x22\x49\x59\x48\x66\xb3\x3c\xbf\x93\x30\x96\xff\x73\x1c\x10\x83\x91\x76\x94\x43\xdd\xc4\xf9\x5e\xb6\x9e\x6e\x41\x24\xa9\x89\x89\x8b\xc5\xeb\x23\x6d\xeb\xca\x60\xd3\x54\xf5\x6c\x53\x49\x32\x96\x79\xb3\xc8\x79\x98\x4e\x29\x7d\x3a\x4a\x59\xcc\x28\x98\xdf\x27\x21\xc8\xaf\x1f\x48\x5c\x44\xc2\x23\xa4\x0c\xa0\xfc\x0b\x24\x90\xef\x9e\x44\x94\x25\x3f\xe2\xe0\x2a\xcc\x46\x0b\x58\x8a\x51\xef\x39\x39\x31\x92\xf1\xa1\x90\xc8\x00\x89\xd3\xca\x07\xbc\xbc\x86\xa7\x6f\x4e\xac\x44\xda\xa0\xd6\x65\x45\xd2\x6c\x39\xe5\x40\xd0\xb0\x1c\x8e\x48\xa4\xb0\xa1\xf2\x46\xbd\xa0\x3e\x17\x84\xc3\x98\x6e\xdd\xf1\x42\xed\xb4\x48\xa4\xd1\x0e\x60\xf6\xfc\x5c\x74\x0e\xfb\x1b\x96\xed\x4d\x75\x96\x45\xaf\xe0\xdd\x8f\x9a\x62\x19\x05\xa0\x6f\xad\x51\x30\xc4\x4b\x13\x95\x5a\xf8\x72\xde\xfc\x56\xd5\xaf\xa6\xa8\x7e\x8e\x30\x4b\x22\xd1\x60\x8b\x5b\x55\x95\x97\x8e\xb8\xf6\xda\x23\xb7\x44\xa2\x25\x92\xb8\x51\xae\x7f\xf9\x3f\x61\x20\xd0\x38\x92\x9a\xbc\xc0\x67\xf4\x0c\x6c\x63\x66\x32\x91\x60\x9c\xd0\x12\xb6\xb6\xd1\xf5\xac\x9a\xc7\x12\xe9\x0c\x26\x6c\x82\x52\x7a\xd5\x45\x7b\x20\xde\xa0\xca\x8f\x50\xcc\x8e\xdb\xc4\x28\xcb\x80\xd7\x2d\xd6\xb2\x2d\xb0\x69\xae\xab\xb2\x51\x74\x56\xb0\xc9\x7b\x1b\xc3\x89\x83\xb9\x01\x83\xbd\x8c\xa7\xcb\x6f\x4c\xee\x99\x06\x9a\x09\xcb\x8c\xaf\x09\xd9\x3a\x5e\x3f\x87\xfb\xea\x79\xd6\x3d\x8c\xad\xdc\xfe\x66\xf5\xfb\xe1\x66\x75\x77\xff\xc7\x61\xf7\x78\xff\x78\xd8\x6d\xd7\x7d\x76\x24\x0d\x13\x9b\x5c\xf1\x9e\x97\x0d\x75\x3e\x1a\x92\x93\x9b\xde\x2e\x0a\x24\x81\x04\x6b\x68\xd1\x8b\x3a\x8b\x34\x92\x31\x05\xc8\x7a\x22\x19\xee\x62\xf7\x6e\x4b\x08\xf9\x74\x92\xa7\x71\x6c\x2b\x84\x4a\xfc\xb9\xad\xab\x53\xd5\x8c\x4a\xc9\x3e\x8b\xe5\xa7\x31\x02\xef\xe5\x67\x2f\xb6\xda\xd1\x7c\x4c\x93\x44\xea\x31\x62\xd7\x4f\xbe\x34\x91\x92\xf0\xb9\xbb\xfd\xff\x67\x0b\xe0\xc2\x8f\xce\xda\x34\x0d\xa5\x4e\x46\xeb\xff\x23\x09\xfc\xc9\x23\xa6\x59\x4a\x09\xf7\x73\x3d\x9f\x0f\x69\xca\x53\x42\xd4\xc9\xaa\x7a\x1d\x2d\xc4\x59\x27\x15\x47\xb6\x62\x4c\x4e\xb9\xfd\x16\xb7\x94\x34\x8b\x52\x0a\x02\xd0\x4e\x3e\x17\x05\xfe\xd0\xf5\xfe\xac\x32\x45\xa4\x19\x24\x94\xea\x38\xf5\x7c\x57\x03\xea\x41\xa4\x9c\x09\x42\x98\x01\xa5\xa8\x6d\xbd\xde\x5d\xf9\xbd\xd1\xd7\x58\xb6\xcd\xd0\x4b\x09\xa7\x64\x41\x93\xaa\x33\x58\xa7\x9b\xec\xec\x45\x78\x84\x14\x74\xc9\xcb\xb7\xbc\xc5\xbb\x32\x5f\xce\xd8\x8b\x94\x67\x8c\xce\xf3\xee\xf2\x7d\x45\xb8\xae\xdb\x81\xd9\x7f\x7a\x53\x11\x9b\xc0\x4a\x1f\x9d\xbe\x9f\x7a\x72\x8a\xa5\xd1\x71\xd3\x88\x09\x3f\x08\x90\x22\xc9\xae\x58\x52\xea\xbf\x90\x2b\x13\x29\xf0\x60\x54\xf4\xe6\x0a\x92\x70\x06\x18\x10\xa9\xe4\x42\x8a\x91\x9f\x36\x83\x9f\x8a\x54\x05\x2a\xe3\x23\xdf\x7e\x4e\x9f\x3f\xfd\x55\x95\x20\x39\x45\x0d\xbc\xe1\x90\xe9\xe3\xd3\x19\xa9\xb8\x55\x90\x7a\xc6\xd6\x9a\x3c\x9e\x39\x48\xa4\x3a\xcd\x88\x50\xaf\x74\x4b\xde\xaf\xc6\x69\x81\xb5\x48\x35\x17\x94\x66\xd8\xb5\x75\x75\x7c\xad\xca\xb6\x22\x42\xe8\xfe\x36\x4a\x38\x3d\xc0\x73\x83\x4f\xd8\x9c\x8f\xfd\x26\x4a\xfb\xe6\x6c\x7e\x99\x34\xa4\xc0\x57\xeb\x64\x16\xfb\x8d\x38\x0b\x32\x9b\x0b\xfc\x39\x37\x37\x16\xd8\x19\xfc\x32\xcd\x58\x60\x28\xbb\xa5\x6b\xc8\xcb\xf5\xd3\x75\x38\x55\xf6\x14\x19\x4b\x31\x8e\xbc\x31\x59\x1f\xc7\x2c\x21\x93\x07\xcb\x42\x1d\xf8\x1a\xa7\x8d\x79\xb6\xde\xd6\x72\xda\xed\xe3\x38\x77\x16\xb9\x7c\xe3\x33\xb6\x1b\x38\x2d\x84\x5c\xb2\x48\x5a\x9f\x67\x5b\x57\x67\xfd\x68\xfe\xa8\xce\x63\x83\x32\x8b\x54\x42\x91\x38\x83\xea\xe5\x47\xd5\xe2\xc3\xf9\x78\x5b\xd5\xd7\x50\x6a\xd2\x5b\xb8\x7a\xef\xeb\x20\x28\x6a\xb2\x38\x33\xb2\x18\x3c\xf1\xb0\x2c\xf2\xe6\xe5\xf1\xf4\x19\x8d\xb5\xbf\xc6\x70\x0a\xcd\xb8\x10\xc1\xbc\x1c\xb9\xeb\xa0\x9d\x72\xbc\xaa\x4a\x4d\xfb\xea\x58\x7e\x53\x64\x49\x84\x94\x70\xc8\xcb\xbc\xf5\x32\x9e\xbe\xa9\x73\x78\xbb\x29\xa4\x40\x4a\x78\x1e\x6b\xba\x88\x2c\xe1\x3a\xb6\x91\x6a\xe8\x8c\xc2\x83\x82\x5a\x1f\x1c\x46\x8c\xfb\x3e\x2a\xa1\xd3\xb4\xaa\x41\x15\xf9\x9f\x68\x55\x23\x3f\xcb\x97\x67\x89\x4a\xa9\x38\xc5\x57\x12\xe2\x1b\x16\x4d\xff\x9b\x0a\xa9\x98\x67\xd0\xa3\x5b\x1e\x95\x14\x01\xc2\x91\x69\xbd\x14\x68\xcb\xb2\xc0\x12\x8c\x1f\xf3\xf2\x2a\xd7\x37\xb9\x71\xe2\xc7\x77\xe5\xee\x4f\x90\x3e\xea\x93\x65\x26\x0b\x1c\xb3\xf8\x53\xd5\x19\x57\xa7\x09\x4f\xdf\x14\x85\x12\xbb\x8b\x78\xc6\x08\x89\xf1\x9a\x17\x85\xd5\x50\x18\x29\xaa\x89\x8c\xab\x8c\x3c\x16\xfc\x55\xb5\xd5\xcf\x89\x3d\x95\x71\xc3\x88\xcb\xde\xd1\x1a\x5d\x57\x4d\xfb\x70\x3e\x62\x3d\x28\x95\x89\x4c\x70\xa5\x64\x8f\x73\x25\xc5\xb6\x21\xbc\x92\x09\x61\x11\xe4\x96\x46\x44\x5f\x77\x9b\x8c\x6b\x82\x58\xd8\xaa\x13\x5b\x3d\x59\x15\xc5\x84\xdb\xc4\xf7\x32\x96\xcc\xd9\x2d\xbe\xd9\x8a\x93\x09\x27\xb7\xe7\xe1\xfa\xfb\xa7\x5f\x52\x1a\x20\x6a\xd8\x5c\x55\x0c\xcb\x51\x35\x9d\xc8\x54\x6a\x1c\x55\xf7\x1b\xd6\x6d\xde\xe4\xe5\xf3\xf7\xe6\x83\x0c\x73\xa6\x53\xab\xfb\x48\x78\x13\xb7\xa0\xac\xbd\x33\x30\x7f\x8a\x4c\x73\xc9\x93\x31\x93\xb3\xe7\x66\xeb\x3b\x08\x6b\xa7\x16\x55\xe7\x3f\x4d\xd7\x80\x36\x21\x4d\x3a\xeb\xba\x9e\x6b\xf4\x7c\x5a\xcb\x4f\x84\xa1\xcd\xff\xb9\x22\x73\x50\x7d\xb1\xad\x1f\x41\x93\x4a\x8a\xc1\xd5\xdd\x51\x4b\xc0\xbc\xfa\x7b\x59\x0f\x38\x89\xe9\x66\x67\x32\x4b\x84\x07\x45\xb7\x98\xde\x27\xb2\x99\x22\x33\x3c\x23\xec\xb2\x7a\xc1\xa6\x3f\xac\x79\xc0\x93\x24\xec\xd1\xa6\x87\x62\xac\x55\x27\x78\x00\x8c\x5c\x4f\x2f\xe9\xf5\x7f\x91\xec\x13\x9c\x61\xe6\xf8\x0e\x6d\x11\xa6\xa7\x8a\xba\x1f\x55\xfa\x5d\xd4\xa2\x0b\xce\x8c\x4e\xed\x08\xe7\xaf\xf9\xab\x7f\x7e\x1e\x82\x34\xc1\x8c\xa6\xea\x0b\xf4\x2f\x12\xa1\x24\xe3\x69\x40\x4b\xad\xdf\xb0\x2c\xa6\x62\x7e\x82\xc7\x41\x42\x39\xa4\xaf\x55\xf1\x97\x6c\x83\xfe\x92\x28\xb3\x92\xbf\x1e\x42\xb2\x01\xef\x65\xf0\x98\x6b\x00\xef\xb3\x91\x5f\xee\x15\xb8\x26\x9f\x86\xc7\xc2\x12\xca\x3a\xe4\xff\xc3\x42\x8e\xf8\x3c\x92\x04\xfa\x84\x73\x6d\xbc\x36\x78\x12\x29\x8a\x7c\x9c\xe0\x9d\x8a\x5b\xe1\x78\x82\xfc\xb9\xbc\x28\x61\x9e\x3e\x4c\x22\xc0\x11\x90\xb4\x1b\xf8\xb5\x7a\x76\xd9\xbe\xd9\x48\x25\x92\x53\x89\xd3\x4a\x56\xe7\xb6\x87\x60\x8e\xda\x11\xc9\x23\xb3\xd4\x58\x4e\x66\xd7\x8f\x4b\xaa\x32\xca\x2f\x5f\x3d\x7e\x7f\xd8\xff\x71\x70\x3c\x30\xe3\x5c\x2f\x4f\x95\x34\xce\xf7\x20\xa4\xbf\x7c\xb7\xf5\xa5\xd3\x5f\xc9\xd2\x98\xd6\xc8\xee\xa5\xfa\x39\xf7\x19\x79\xc6\x33\xe2\x00\x3c\x81\xa3\x65\x6f\xf6\xd5\xfe\x05\x07\xba\x7e\xc1\x39\x93\x09\x5c\x0a\xd5\x36\xf3\xb4\x16\xe7\x89\xa4\xfa\x9e\xfb\xbb\x2b\x7f\xad\x60\x51\xe2\x2c\xb6\xc7\x92\x48\x89\x46\x67\x35\x17\xa1\xf0\x8c\xc4\x5e\x0f\xa6\xf3\x4d\xff\x56\x45\x90\xe0\x22\xb3\xe5\x9b\xae\xc4\xa6\x37\xbe\x5c\x33\x08\x1b\xa6\xa0\x92\x2c\x8b\xc1\x70\x24\x6e\x54\x87\x6b\x57\xe3\x5f\x1b\xfb\x83\xe7\xca\x25\xe3\x84\x4a\x57\x16\xae\xfc\x04\x2d\x6e\xfc\xaf\xc9\x08\xd5\x48\x23\xe3\xda\xf3\xd2\x4e\x53\xd1\xbe\x73\xe6\x2a\xe7\xa1\x28\x1e\x87\xa0\x11\xef\x5c\x70\x36\x14\xc0\x4c\x4e\x2a\xae\x98\x21\xb9\x1d\x5d\x1d\xe4\x1c\x09\xc8\x55\x8a\xb4\x33\xab\x02\xa9\x52\x69\x70\xd9\xb8\xc2\x9e\xcc\xb4\x3a\xb7\x54\x89\x34\xf7\x8b\xb9\x0e\x12\x03\xa3\x2a\xe1\xee\xf3\xf7\x37\x40\x95\xd2\x76\x3d\x11\x4f\xb0\x95\xcf\xf3\x74\x04\x37\x11\xd2\xde\xbf\xed\x0c\x27\x45\x13\xca\x2d\x6a\x3d\xef\x29\x32\x11\xf8\x8c\x69\x53\xdd\x60\x0b\xf9\xf0\xf1\x8c\xb6\x95\x05\x96\x61\xda\x4f\x45\x11\x84\xa1\xa3\x2f\x1f\x64\x02\xba\x33\x7d\x14\x55\x12\x41\x92\x25\x56\xc7\x96\xfc\xdc\xdb\x73\xa9\x5d\xa9\x1d\xce\x80\xee\x42\x30\x95\xda\xc2\x0b\x6c\xc1\xf2\xac\x5e\x64\xda\xa7\xd6\xb7\x08\x31\xb2\x98\xf1\x1c\xeb\x71\xe1\x8a\x10\x11\x26\x96\x14\x0e\xdf\x54\x55\x5a\x36\x99\xdb\xaa\xde\xbb\xf3\xcb\xf5\x8a\x4d\x92\xb8\x59\xe9\x59\xd3\x89\x25\xa2\x59\x54\x25\x8a\x42\x1b\x05\xef\x87\x4d\x24\x51\x4a\x89\x73\xca\x2a\x36\x6e\x42\xaf\xf4\x82\x32\xfd\x74\xc7\x12\x49\x22\x29\x1b\x52\xe7\xea\x05\x6a\xbd\xea\x2b\xdb\x85\x48\xa4\xc5\x96\x94\xd5\xcf\xbb\x72\x0a\xaf\x15\x89\x04\xfa\x4c\x7d\x14\x8f\x6a\x24\x3e\x66\x11\x16\x22\x41\x4d\x84\x1e\xee\xec\xfc\x0d\xf3\xe9\x97\x17\x29\x97\x99\x25\x58\x2f\x8a\x7b\x6b\x5a\xf9\x5f\xcb\x62\x45\x34\xe9\x1b\x4a\xbe\xad\xda\x16\x8f\xa7\xd6\xd6\x6d\xfe\xc5\x9e\x30\x5d\x61\x22\xe3\xa9\xd7\x6c\x6b\x0b\xa2\xd0\x2d\xf1\x52\x6e\x70\xfe\xa9\xff\xa2\xdd\xdf\x5b\x5a\x8d\x0f\x5d\x6d\xb0\x58\xae\x11\x11\x82\x33\x5b\xa5\xd9\x60\x3b\x30\xcc\x5f\x64\xc5\x68\x77\xe9\x67\x23\x8f\x39\x0f\xfb\xa2\xc2\x5f\xef\xeb\x5f\xa8\xee\x6e\xa6\xc7\xa0\xe0\x99\x15\xb9\x5c\x5f\x3f\x7c\x66\xf3\x09\x0e\x8c\xe0\x5c\x39\xe9\x11\x98\xbc\xc7\x2a\x74\x36\xa9\x18\x68\xbb\x27\xd3\x9c\x4f\x10\x50\x42\x24\x56\xcf\x6a\xbf\xbf\xee\x2f\x56\x56\xb8\xe4\xf8\xfe\xdd\x91\xd9\xf9\x16\x48\xec\x56\x3f\xb0\x79\x0c\xc7\x8c\x00\x0c\x29\xab\x65\x8a\xfc\x34\x3a\x01\x84\x8c\x78\xea\x45\x51\x2d\x43\xc2\x04\x0a\x23\x64\x66\xd1\x45\xdb\xa7\x35\x95\xd8\xac\x6e\x6e\x9e\x7c\x9b\x0a\xe2\x74\x1c\x60\xde\x40\xfd\x8a\xdd\x5a\x5b\x95\xfa\xda\x33\xb4\x3c\x9e\xdb\x1a\xa1\x4f\x14\x09\x95\x49\x02\x49\x1e\x6a\x6c\xb0\xfd\x32\x7a\x7e\xc5\xd1\xb8\x7a\x94\x62\xe7\xe2\xb7\xfd\x98\x29\x6d\x01\x77\xcd\xc8\x34\x70\x4d\x5a\x30\x8f\xfc\x79\x94\xff\x41\x65\x45\xc6\xae\xde\x07\x42\xa4\xe9\x87\xd1\xca\x90\xc1\xd1\xb4\xd0\xe6\x6a\x55\xd7\x96\x7e\xaa\x5f\x71\x68\xd0\x6b\x44\xdb\xe4\x8e\x65\xff\x58\xae\x69\x18\x1d\x4f\xc2\x04\x2a\xd1\x0e\x26\x8f\x9a\x18\xdc\x6c\x31\x53\x8d\x6f\x08\x05\xea\x43\x73\xca\xfb\x3c\x81\x30\xb1\x75\xd7\xcf\xe5\x4b\x55\xe8\xdd\x59\x36\xaa\xce\xc9\xd1\x25\x19\x94\xd9\xa2\x35\x59\x10\xbb\x5d\xb5\xaa\xf5\x15\xba\xd0\xc4\xa4\x13\x04\x98\xc8\xc1\x05\xde\x60\xd3\x78\x3c\x3d\x9b\xc6\xf9\x80\x71\x19\x59\xe2\x77\x8a\x6f\x11\xb2\x9b\x24\xa1\xad\x6e\xe0\xf4\xb6\x4c\x31\x4b\x13\xe9\x8e\x78\x8f\x3f\x1e\x7f\x06\x60\xa8\x29\x8a\x32\xc4\x7e\xff\xbf\x73\x7e\xe9\xe0\xcf\x9e\x38\x94\xd2\xaa\x6c\x5a\x09\x71\x2a\x9e\x1c\xeb\x1d\x5a\x57\xd2\xaf\x50\x08\xa5\xa1\x0a\x8c\x9e\xe2\x6b\x73\xf7\x70\xb8\xfa\xfe\x87\x1b\x53\x88\xe2\x94\x70\x09\x7d\xd5\xe3\x06\xfa\xb9\x0e\x51\xc2\x88\x6b\xae\x7d\xc9\x9b\x1f\x55\x8b\xb5\x03\x43\xfa\xe6\xcc\xc6\x5c\x5b\x1c\x0b\x33\x0a\x88\x99\x95\x99\x95\x9d\xfb\x8c\xcd\x8c\x3b\xb2\x6b\x67\xe4\xb2\xec\x14\xd4\x48\x01\x9c\xf1\xca\x83\x58\xc6\x2e\xea\x50\x14\xf3\xf2\x33\x01\x31\x22\x39\xa8\x9d\x47\x70\x83\xde\x2d\xba\x26\xaa\xad\x7e\xf6\x43\xca\x33\x8a\xa9\xe4\xc4\x08\x51\xe4\x7f\xe2\x05\x19\xe7\xe5\xd0\x66\xca\xa0\x93\xc5\xf0\xe1\xc5\x4f\x51\x66\x90\x69\x9b\x56\x93\xe7\xbc\xd0\x77\x97\xe7\xd9\x30\xd5\x81\xc7\x2c\x45\x5f\x5e\xe9\x61\x4a\x7d\x9b\x2d\x65\x76\x74\x37\xce\xa6\x5d\x0e\xf4\x00\x4f\x2c\x21\xa6\xdd\x72\xbb\xb3\xf4\x12\x52\x0e\x3c\xb3\x68\x93\x63\xfe\x6c\x8b\x16\x47\xa4\x33\xfd\xaf\xf2\x94\x12\x47\xf4\xe5\x7b\x35\x3b\x62\x45\x8f\x46\xf1\x5f\xe0\x22\xa6\x74\x41\xde\xdc\xe0\x1b\x16\xd5\x69\x18\x65\x2e\xa4\xd3\x5d\x25\x83\x89\x4a\x5e\x51\x3b\x38\xec\xe2\x59\x0b\x5c\x42\x3c\xbc\xeb\x93\x55\x51\xf9\x5b\xc9\x00\xe0\x26\x34\x30\x18\xac\x4f\xd5\xb9\xc0\xb6\xbd\xc8\xc2\x2f\xf2\x26\x0a\x10\x09\x27\x63\x47\x55\x1a\x2d\x70\x60\x9c\x6a\x02\xd1\xf9\x26\x8e\x7d\x19\xf4\x33\x2e\x95\x51\x0b\x10\x68\xab\xc7\xee\x5e\xcf\x35\x4c\x26\xad\x30\x2c\x76\xa6\xfd\x95\x22\xe4\xe5\x3c\x38\xdf\x77\x0c\x23\x33\x3a\x74\x5c\x3a\x6f\xa5\xf5\x45\x47\x60\x56\x89\xfc\x5d\x82\x7a\x9d\x7d\x61\x61\x34\x11\xff\xee\xbe\xaf\xb6\xdb\xc9\x93\x40\x60\xb1\x51\xdd\x2c\x76\xda\x78\x63\xbe\x8e\xf1\xa4\x84\x34\xe5\x0e\xaf\x46\x26\x4b\x33\xd7\x63\x71\xfd\x64\x28\x28\xda\x65\xeb\xf9\x7b\xe9\x0f\x01\x52\x86\xc6\xe7\x7a\x0f\x27\x18\x4d\x0d\x05\x31\x81\xf5\x1d\xd2\xea\xe8\x63\x4d\x84\x08\x6a\x5e\x72\x1f\x27\x04\x0c\x14\x85\x4f\x47\x9a\x4b\x93\x44\x8f\xfb\xc7\x01\x7b\xfa\xcd\x13\x99\xf2\x44\xfa\xbb\xb6\x3a\xdd\xa0\xa9\x7b\xbe\x5c\x01\x98\x65\xe4\xdb\x3c\xae\x37\x87\x31\x15\x95\x00\x14\x8a\x4a\x17\xc8\xed\xb8\xf7\x46\x02\x98\x24\xc1\x78\x14\xf3\xb8\x77\xb1\xfa\xd9\xa8\x9b\x34\xf1\xb9\xff\xae\x07\x89\x9d\x9f\x2f\x6a\x14\x05\x18\x1e\x11\xd6\x0f\xb4\xee\x57\xd6\xf2\xd8\xca\x20\x13\x44\x59\xbb\x3a\xde\xd9\x94\xad\x93\x24\x10\x32\x4c\xed\x94\x72\xce\xdb\x26\x2f\xdb\x87\x6a\xf0\xbd\x64\x94\x81\x65\x9e\x69\xf4\xc0\x81\x2b\x64\x9c\x48\xc6\x7b\x46\x80\xf5\x91\x14\xcb\xb1\xe9\x6b\xd2\x51\xef\xf2\xe7\x12\xda\x73\x8d\xcd\xaa\xd4\x4f\x04\x16\xbe\x05\x8d\x55\x8f\xbd\x93\x71\x9a\x12\x08\xda\xd6\x99\xee\xd7\xab\xcd\xae\x6f\x02\x8b\x63\x5a\xd2\x9e\xff\x38\xbe\x23\x13\xc9\x08\x76\xb8\x7e\x03\x5b\x3b\xab\x16\x6d\x0d\x99\xc9\x88\x7c\x60\xcb\xee\x4d\xd2\x71\x36\xa3\xd0\xcf\x5a\xc9\x83\x98\xb0\x22\x15\x09\xd5\x0c\x72\xc4\x42\x0a\x08\x28\x7a\x61\x4f\xf3\x25\xe8\xa2\x84\x24\x20\x53\xd2\xce\xcb\xf9\x6c\xec\x9a\x29\xf6\x76\xbf\xf2\x1c\xdb\x42\x02\x70\x4a\xe3\x5d\x41\x93\xab\xbb\x52\x55\x47\x3c\x5c\x57\xb7\x43\x08\x50\x02\x72\xc2\xb2\x3a\xa5\xab\xbc\xb3\x5c\x7c\x69\x46\xfb\x52\x57\x3f\xf3\xf2\xf9\x30\xa2\x7c\x12\x52\x85\x81\xdd\x06\xa1\x94\xe7\xf7\xd2\xab\x24\x09\xa9\xe2\x94\x2a\x4c\x77\xeb\xfb\xfb\xc3\xd7\xd5\xd3\xcd\x24\x7e\x22\x15\x48\x22\x82\x5e\x59\x3c\x97\x67\xaf\xe9\x1a\x30\x1c\x98\xbc\x6f\xcf\x58\x2c\xd5\x88\x7e\xe8\x7e\x48\x1d\x58\x42\xc2\x83\xcc\xf5\x3d\xb4\x58\xef\xba\x51\xf9\x28\x8f\x38\x9d\xc2\x3a\x0e\x69\xb5\xad\x1f\x6e\x0e\x37\xdf\x1d\x95\xe4\xd5\x7a\xbf\xbf\x7b\xf8\x62\x35\xde\xfc\x53\x62\x10\x82\x55\x25\x82\xd9\x76\x27\x51\x3b\x0e\x99\x19\xb2\xd2\x5a\x91\xfb\x6a\x0f\xaf\xb8\x6a\x9e\xe0\xb5\x9f\xe8\x86\x6b\x8a\x11\x1f\x37\x95\xb6\x21\xee\x6f\xf8\x3e\x0b\xd4\x4b\x03\xb6\xf4\xe7\x2d\x6f\xc0\x19\xea\x8b\xe7\xaa\x0a\x44\xe0\xa9\xeb\x6d\xa9\x6a\xe7\xc5\x53\xc6\x85\x12\x6d\x8b\xa3\xa6\x02\x29\x8c\xcd\xc7\x75\x96\xbb\x65\x2d\x9c\x8f\x59\x2f\x49\x30\xe8\x12\x08\x15\xe8\x64\xd0\x10\x69\x6c\x9a\xae\x8f\xda\xaa\xc0\x44\x81\xa3\x15\xe9\x8e\x10\x3d\xd3\x8e\x17\x8a\x85\x9a\x2a\x08\x69\xd7\x9e\xe9\x8b\x4e\x9f\x30\x0c\x24\x41\x00\x1d\x37\x42\xdd\x92\x54\xd4\xc2\xca\x53\x51\x80\x44\x13\x58\x9d\xb0\xbc\xd6\x97\xdf\xfe\x83\xb9\xe0\xaf\x66\x01\xe1\x58\xfb\xa0\xb1\x65\xf3\xfe\x5f\xd0\x38\xc4\xb0\x3e\x18\xfa\x88\x09\xa1\xfb\xb2\x95\x59\xd9\xbd\x50\x51\x1a\x53\x80\xfd\x26\x37\x7f\x8f\xbf\x4b\xa8\x48\x6b\xe2\x25\xa6\xfa\x51\x4a\x03\x8d\xc8\x00\xa8\x59\x79\x0c\x34\xa9\x9a\x59\x9c\xea\x67\xd5\x67\x2a\x32\x29\x25\xb8\x0f\x9d\xe1\xf5\x63\x7b\x8b\x78\xf5\x4e\x77\x9e\x4e\x38\x15\x87\x69\xec\xc4\xe3\x8a\xf7\xab\xbc\xd6\x9b\xbc\xdc\x62\xbd\xc5\xba\xe9\x6d\x2f\xea\x24\x89\x44\xbf\x55\x2f\x63\x68\x8a\x4a\x84\x55\x48\xc6\x21\xa2\xa1\x12\x09\x83\xfb\x7b\x95\xeb\xdb\xaa\xfe\x02\xe5\x02\x1c\x5e\x25\x2a\xa5\x14\xcd\xe6\xfd\xb7\xdc\xd3\x1d\x77\x7f\x95\x6c\xa0\x53\x24\x88\xd5\xdf\xd9\x13\x54\x1a\x29\xda\xa4\xf4\x2f\x33\x68\x67\x08\x95\x26\x41\xea\xe4\xbb\x3f\x61\xb2\x14\x2a\x4d\xb9\x08\x89\xc9\xb2\xa6\x43\x90\x92\x26\x7f\x23\xc0\xad\x52\xc1\x08\x87\xde\xa0\x8b\x34\x8d\xb3\x60\xb3\xdf\x00\x26\xf9\xb8\x60\x69\x62\xea\x4c\xef\x2a\xd3\x34\x1b\x75\xdd\x56\xab\x7f\xcc\x28\xb5\xac\xa1\xe1\x4e\x2f\xfa\x9f\x79\xac\x75\x7a\x47\xc5\x88\x2f\xa3\x85\x57\x5b\xe4\x3b\x7b\xb8\x8c\x71\x72\x9f\xd6\xb5\x0a\x83\xdd\xf9\x78\x84\xfa\xfd\xbe\x7a\xce\xd5\x74\xeb\x53\x59\x14\x53\x48\xa1\x3c\x1f\x57\xba\xee\x3f\x7b\x16\x0b\xa5\xc7\x74\x96\x55\xd9\x62\xd9\xde\xdd\x4c\xf0\x61\x2a\x8b\x21\xea\x86\xe0\xb6\x3a\x56\x49\xbf\x43\x64\x8a\x07\xce\x03\xad\x8c\x73\xdb\xa6\x97\x99\x88\x82\x5e\x87\x45\xcd\x9f\xd1\x79\xab\x78\xcc\x82\xc0\x47\x36\xbb\xbe\x5f\xab\x73\xfd\x5c\xc0\xa5\x7b\xe4\x2f\xe0\x26\x0c\x1c\xbb\xcf\x20\xb3\x23\x14\x37\xe8\x43\x5c\x1b\xf8\x95\x1f\xcf\xc7\x9e\x2e\x76\x3a\x70\x02\x23\xd1\xc3\xb6\xab\x12\xef\x4a\xcb\xda\xf6\x5f\x42\x7f\x84\xfe\x7e\x10\x64\x34\xc1\x24\x96\x68\x72\x95\x43\xfd\x4e\xd6\xc8\x2e\x7f\xee\xf1\x8b\xd3\x1b\x83\x00\x1d\x8f\x34\x72\xd6\x33\xf2\x0d\xa1\xc0\xa4\x94\xab\xc7\xf6\x05\xa1\x20\x9b\xad\x2a\x86\xb0\x8a\x92\x09\x78\x66\x34\xfa\xe4\x96\x54\x7d\xfa\x3d\x65\x6a\xab\x56\xba\xc7\x5f\x15\xb9\xc2\xdb\xaa\xfa\x36\x5a\x8f\x32\xb5\x54\xfb\x8d\x15\x23\xdd\xb5\x1f\x84\x11\x94\x4a\x6d\xc4\x99\xd4\x6f\xeb\xea\xf8\xc1\x42\x53\x22\xa0\xc0\x59\x8d\xa7\xaa\x69\x86\x52\x08\xa5\x34\x23\xbb\xe4\x8a\xf0\xce\x57\x50\xbe\xf6\x2d\xc8\x54\x4f\x76\x47\xce\x5b\x77\xca\x5d\xaa\x9d\xba\xee\x3a\x0e\x49\xff\x78\xfd\x74\xbd\xc7\xa6\x1d\xfb\x1b\x0a\x83\x84\x0d\x2a\x73\xd7\xdb\x65\xc7\x4f\x61\x94\x51\xa6\x40\x3b\xa0\xeb\xe1\x58\xe9\xdc\x2c\x8b\x8e\x0a\x85\xc2\x10\x43\xb8\xb7\x32\xe7\xc9\x2d\xdf\xcd\xa4\x04\x05\x39\x78\xd1\x1b\x97\xac\x5f\x06\x6e\xb9\x8b\x4c\x04\x34\xfc\x7f\x62\x5d\x0d\xf5\x26\x3a\x08\x32\x93\x79\xb6\x6b\x4b\x5e\x40\x05\xb8\xb7\x38\x52\xf9\xe9\xba\xd9\x98\xd5\x1a\x9a\xf7\x99\x06\xbc\xd0\x2c\x00\x2b\xdb\x8a\x7a\x5b\x8d\xa9\x39\x85\x66\x2c\x45\x3d\x0b\xaf\xe6\xe5\xf3\x25\x97\xa2\xd0\x4c\xc7\xe4\xe8\x5a\xd8\xf3\x3f\x3e\xa8\x2b\xf0\xcb\x4d\x87\x61\xe0\x14\x71\x06\x37\xbe\xdb\xaf\x3b\xeb\xb8\xbe\x40\xcf\xeb\x10\x63\x47\x5b\x4a\x54\x0e\xb7\x96\x6a\xbe\x7f\x85\x28\x88\xe8\x6e\xda\x1e\xc4\xfd\x9f\xb5\xf5\x7c\x9e\x6b\x98\xed\xfa\xae\x43\x1c\x4a\x02\x93\x5c\xdf\x3f\x38\x4e\xf7\x4f\xf3\xc4\x3a\x36\x18\x04\xbe\x78\xd7\xf1\x6e\x5f\x3f\x7a\x80\xb3\x4e\x03\x45\x7c\x55\xf7\x55\xf9\x6c\x29\x4f\x7c\x43\x64\x1f\x9f\xe2\x9a\xe3\x1d\x4d\xa7\xdc\x50\x78\x90\x48\x8e\xb6\xeb\xa7\xc3\x7a\xff\x75\xfd\x74\xb8\x7a\x5c\x3d\x79\xec\xa3\xe6\x5c\x73\xf7\x91\x65\xae\x3f\x67\x2f\xd1\x5c\x29\x2f\x19\x7e\x5b\xe4\xcf\x2f\xad\x67\xe1\x70\x27\x04\x4b\x97\x14\x6f\xbc\xcb\xa3\x45\xa2\x7c\x16\x72\x03\xbf\xae\xe1\xc4\x82\xdf\xff\xb1\x14\xd9\xd0\x02\x45\x26\x06\x86\xb1\x1b\x84\x62\x92\xa9\xd1\x10\xa4\x84\x49\x21\x7b\x74\xf7\x13\x4e\xbf\xd5\x70\x3a\x61\xfd\xa5\x2a\xf0\xe8\xe8\xb4\x27\xb3\x0d\x44\x46\x9f\xab\xf9\x99\x93\x26\xfb\x6c\x9e\xca\x30\xa4\x4a\x56\xcf\xbe\x30\x8b\xf5\x0f\x9b\xbf\x96\x89\x49\x07\xce\xde\xa7\xaa\x58\xa6\xa6\x15\x5a\xa6\x19\xb3\xd3\x0a\xb4\x17\x3f\xc9\xe5\xb9\xad\x3c\x43\xd4\xac\x7b\x96\x41\xd4\xdf\x77\xd7\x82\x31\x17\x84\xc0\xfd\x48\x4a\x2d\x09\x45\x77\xfd\xed\x8f\xcf\xd5\xd4\x85\x56\x41\x4c\x3c\x4f\x57\xd7\xfb\x1f\x7f\xc5\x43\x2a\xb4\x72\x56\x6b\x77\x82\xf7\xbe\xe0\x2d\x7a\x62\x0b\xbf\x91\x6a\x1d\x84\x84\x99\xd9\x62\x6d\x50\x51\x66\xd6\x1d\x0d\x7d\x0f\x1e\x86\xee\x63\xf7\xee\xf5\x13\x7a\x29\xb1\xd9\x58\xa1\xb6\xe1\x01\x3a\x00\xa4\xcc\xdb\x4d\xd5\x9b\x0f\x7d\xd8\xc3\xf5\x35\xa1\xad\x09\x72\x72\xf9\xda\x43\xfa\x56\x5a\xe7\x4b\xb2\xf7\xfe\xb2\xd8\xd0\x8c\xa1\xe8\xde\x44\x8a\x4c\x68\xc3\x05\x95\x29\xee\x14\x94\x3a\x2f\xe1\x2d\x87\x72\xfd\xad\xae\x4a\x47\x30\x2b\x30\x48\x20\x72\x85\xac\xc4\xb5\x99\x63\xa1\xc3\xbe\x51\xd8\x3a\x54\xd0\xfa\x47\xd5\xe2\x16\xf2\x0f\xca\x88\x30\x40\x43\xf2\xae\x3e\xdf\xe1\x42\x62\x0b\x3c\xba\x02\x03\x93\x08\x37\x80\xeb\xce\x74\xde\x42\xed\xf9\x27\x17\x26\x86\x4b\x43\x7d\xbc\xfa\x90\x85\x49\xa0\x3d\x68\xdb\x6f\x31\xb3\xdf\x64\xa1\x4d\x6c\x10\xd4\x0b\x6a\x7d\xf5\x7e\x49\x9f\x82\x4c\x09\xad\x06\x0f\x8a\x9e\x7d\xeb\x72\xca\xf3\xfb\x19\x20\xc0\x87\xf2\x2c\x09\xeb\xf3\xbc\x4b\x18\xc5\x3c\x1a\x22\x48\x16\x2e\xb8\xb8\xa2\x30\x94\x12\xc1\x93\xa8\x19\xfc\xd1\x17\xe3\x61\x94\x68\x0a\x92\x9c\xaa\xaa\x20\x03\xeb\x93\x39\x8e\x71\xca\x71\x20\xc3\xb9\x87\x99\x4a\x8e\xc0\x24\x46\x0a\x4d\xaf\x0a\xfc\x36\x58\x6b\x98\x70\x91\x45\x0e\x7c\xef\x3e\xdc\xa3\x19\x1a\x15\x01\x0b\xfc\xf9\x7c\xa7\x2a\x0a\xa3\x4c\xef\x9c\x09\xab\x0b\xf8\xed\x0c\xf9\x94\x82\x79\xf9\x8d\xb9\xb4\x55\xc6\x05\x34\xed\xee\x2c\x87\xca\xe6\xaa\x7e\x34\xb3\x81\x04\x30\x29\xeb\xcf\x8f\xbc\x17\x91\x11\x08\x2a\x53\x23\xf8\xe7\xa3\x52\xe7\x13\x94\xca\x87\x4a\x50\xb2\x94\x8c\xc0\x3e\x21\x4f\x44\x3e\xeb\xfd\xd7\x0f\x9e\x4a\x86\xa9\xa2\x15\xb8\x7a\xf8\xb2\x3e\xec\xae\x7b\x41\x23\x81\x12\x02\xf2\xb7\x9a\x97\xea\xa7\xa3\x59\xfb\x01\xc3\x93\xa8\x21\x57\xe8\x64\x3c\xda\x25\xca\x77\x81\x2a\x36\x4c\xf8\x68\x26\xd4\xed\xaa\xd4\x8e\xab\x76\xd9\x3e\x42\xcd\x22\x4a\xb1\xf4\x24\x9d\x16\xf0\xd9\xff\xb2\x8e\x2c\x65\x58\x63\x99\xb4\xaf\xab\xe3\xb1\x2a\x07\x5d\x6c\xcb\x8b\xe9\xd8\x07\x05\x6a\x03\x99\xf6\x8a\xc2\x6d\xb7\x7f\xc3\xf7\xba\x58\x8a\x12\x20\x26\xb1\xc9\xbc\xe1\x68\xd1\x3f\xd3\x57\x41\x8c\xc8\x28\xbf\x59\xff\x58\xdf\x3f\x6e\xd7\x4f\x3e\x72\x88\x26\xe5\x89\x03\x43\x76\x3e\xe8\xbe\xda\x60\x79\x5e\x94\x27\x14\x68\x32\xab\xa2\x46\xcb\xe4\xc2\x63\x42\x23\x13\xb2\xfb\xaa\x82\x80\xe6\xee\x17\x4c\x10\x64\x41\xd4\x1b\xe7\xdd\x38\xd6\xee\x29\xa7\x93\xc7\x04\x2c\x91\x61\x4f\x43\xe5\x02\x14\x73\x11\x6d\x61\x02\x19\x3b\x1a\xaf\xe7\x83\xc6\xe3\xb9\xae\xe1\x19\x0f\x06\x3f\x06\xe1\xf8\x0b\x95\x65\x29\xdb\x42\xdd\xa0\xe5\xcf\x98\x57\x70\x9a\x40\x69\xaa\x33\xac\x71\x60\x54\xb9\x7a\xff\xf6\xc7\xf5\xf2\x66\x6a\x02\x93\x51\x64\x90\xb4\xa6\xce\x45\xe7\xe1\x6c\x6b\x6c\xf0\x92\xf6\xde\x5d\xc0\x98\xf5\x1f\xb7\xbf\xfb\x78\xbd\x61\x71\x44\xa4\xad\xa7\xaa\x69\x0f\x9d\x5b\xf9\xfc\xde\x97\x81\x4d\xaf\x4d\x2d\x71\xf2\xee\x05\xca\x9b\x1c\xca\xfb\x1c\xca\xfe\x26\x82\x67\xda\x07\x57\xd6\xbf\x5a\xaa\xbe\x23\xa8\x2c\x09\xbc\xad\x87\xc8\x85\x61\x90\xd2\xde\x73\x28\xab\x0d\xb4\xea\x25\x2f\x9f\xbb\xe3\xa2\x6f\x8f\x64\x4c\xc8\xf0\xd3\xb9\xdd\xd7\x88\x8f\xe5\x87\xdc\xe4\xc2\x24\x19\x7a\xde\xc9\x55\x33\xcb\xcf\xf9\x2e\xc2\x50\xa4\x88\x86\xdd\x62\x79\x2c\x3e\xdc\xb5\xa7\xb1\x25\xd9\x7d\x5a\x3d\xdc\x3c\x6e\xee\xfe\xb9\x7e\x3a\x3c\xad\xf7\x4f\x7f\x1c\xae\x1f\xbf\x3f\xec\x87\x5e\x59\x18\xf4\xe8\x48\x0a\x91\xe7\x13\x4e\xfe\xe9\x77\x49\xb9\xe1\x4e\x25\xa7\x9b\x69\x24\x1c\x3c\xaa\x1e\x32\x59\x6c\xa8\xaa\x64\xf0\x25\x77\x33\xb5\x5f\x61\x32\xe0\x99\x2d\x93\x5c\xb5\xf7\x08\xcd\xa7\x1a\xd5\xc2\x64\x98\x06\xce\x7e\x70\xf5\x6c\x43\xa1\x35\x1f\x59\x6f\x46\x04\x3a\xed\x99\x79\xa8\xde\x7f\xaa\xa3\x28\x8c\x48\xac\xaa\x2c\x81\xab\xdd\x36\xdf\x6d\xd5\xbd\xc7\x6b\x44\x9a\x7a\xf7\xdf\xb1\x5e\xde\x22\xda\x5a\xf7\xbe\x8b\xb4\xb4\x03\x03\x6d\xcc\xfa\x97\xa3\x2b\x1b\x02\xd5\xd3\x37\x16\x4a\x65\x8e\x31\xe4\x0b\x34\x54\xbe\xfb\x81\xf3\x69\x24\xe3\x13\x5f\x70\x29\x99\x34\xbd\xb9\x8a\x52\xee\xd4\x75\xba\xbf\x2e\x67\xe2\x8c\x8a\x53\x6e\x4d\x5b\x92\xa9\xed\xf5\x98\xfd\x5b\x69\x6e\xf7\x7d\xc8\xeb\x9b\xba\x3a\x1d\x2e\xd6\xfc\x45\xb6\xa3\xbf\xd0\x6a\xff\x50\x68\xc3\x46\xb1\xfb\x7b\x9a\x84\xa2\xdc\x67\x57\xba\x4c\xf2\x41\xd6\xa0\x9b\xc3\x6b\xa7\xf7\xc4\xc8\xa6\x5a\x1b\x6c\x9d\x71\xea\xf3\xc4\xe3\x25\xe3\x3b\xeb\x4c\xf5\x0c\xc1\x9b\x19\x95\x97\xeb\x63\x52\x61\xf5\xdc\x6d\x9e\xc2\x72\x21\x4c\xee\x03\x41\x90\x0a\x42\x7b\x1e\x74\xd5\xd7\x6d\xf9\x26\x11\x52\x04\x7a\x45\xba\x23\xc3\x5f\x55\x18\x8e\xa2\xc0\x43\xc8\x01\x82\x40\x99\xd8\xb2\x73\x92\x42\xca\xa0\x4c\x01\x41\x80\x21\x0e\xce\x80\xb3\x74\xa7\x68\x5a\x08\x58\x64\xd5\xa8\x72\x55\x1d\x9a\xc1\x35\x85\x20\x04\x6b\xa8\x10\x3e\xc6\x71\xb8\xf7\x6d\x5a\x05\xa9\xaf\x85\x31\xd5\x64\xbf\x80\x20\x44\x49\x3e\xcb\x06\xb0\x81\x9f\xe0\x2f\x8a\x84\x55\x61\xfb\xf2\xfb\xef\xfe\x4f\x31\x43\xb2\x14\x09\xa2\x72\x5b\x57\xc7\xad\xad\x95\xea\xdb\xe3\xc8\x2a\x8b\x29\x75\x3e\x92\x51\xa1\xfb\xa6\x84\x33\xd5\xf3\xbf\x51\xdd\x7b\xdf\xc4\x13\xf2\x10\xd7\xa7\xe2\xdc\xcc\x80\xae\x10\xc4\x46\x78\xfb\x8f\xb2\xf2\x94\xbd\x7b\xf7\xad\x69\x60\xe5\x84\xbe\x3c\xde\xdf\x1c\x56\x9b\x6e\x03\x3b\xec\xb7\x7b\xdf\x9c\x39\x86\x8c\x53\x5d\x1d\xab\xee\xbb\x8f\xd8\x28\x20\xe0\x51\x24\xdc\x81\x7f\x0b\xaf\x97\xa5\x1f\x10\x08\x66\x28\x06\x4b\x14\xb1\xdb\x73\xa9\x5e\xee\xca\x59\x7a\x2f\xf5\x28\x13\x08\x44\xc2\x89\x1c\x54\x41\xf3\x52\x9d\xdb\xf5\xe3\xee\xca\x7e\x0a\x17\x90\x39\xac\xee\xef\xfd\x6f\x8b\xd4\x24\x9e\x29\xf2\x03\x0e\x37\xdf\x53\xa3\x41\x6f\xe2\x6d\x1c\xfd\x95\x6b\x83\xd0\x86\x0f\x9c\x56\xe7\xda\x72\xe6\x7d\x04\xbb\x87\x40\x06\x40\x69\xf7\xcd\xea\xf7\xc3\x6e\xbf\xfa\xb2\x3e\xb0\x71\x66\x0d\x02\x19\x8a\xd8\xa5\xdb\x1d\x66\x78\x4c\x72\x06\x81\x8a\xac\xd3\xf4\x9c\xbf\xe1\x06\x1f\xee\xee\x87\x16\x60\x56\x36\xb4\x6d\x61\xa6\xe6\x00\x81\xe6\xcc\xa9\xfc\x36\x79\x59\x4d\x1c\x31\x08\x30\x88\xd0\x4d\x8d\xef\x77\x65\xcb\xad\x37\x30\x9d\xa3\x18\x08\xe8\x81\xae\x65\x33\xa7\x5b\x84\x00\x43\xab\x16\xe2\xab\xff\xe7\x08\xb9\xc5\xe0\x06\x04\xa8\x0c\xe1\x21\xee\xab\x67\x47\xfa\x63\xd5\x53\x8a\xa1\x44\x6d\xfa\x3b\x06\x91\x40\xb5\xa4\x98\x65\x53\x64\x0b\x72\x53\xc0\x02\x63\xa5\x27\xb6\x77\x0f\x56\xe0\xd9\xbd\x2d\x63\xa1\x2d\x5d\x7c\xa9\xce\x0d\x2e\x06\x68\x81\x31\x6e\xc8\xd9\xda\x7d\x7d\xf8\x67\x7f\x9d\x36\xd2\x86\x37\x35\xe2\xd1\xc9\xb3\x2f\x65\x2e\x96\x2b\xd2\x81\x79\xb9\xe6\x31\xaf\xcd\x13\x8e\xe5\x03\xfb\x23\xb3\xeb\xac\x2d\xb5\xdb\xbb\x1c\xaf\x46\x16\x89\xc4\x83\xfe\x27\xe5\xbf\xdc\xb7\x6b\x46\xf3\x47\x5b\xc2\xfb\xd5\xb9\xad\x8e\xdd\xa8\x5a\xe2\x4e\x7f\x97\x38\x12\xda\x82\xd7\xdf\x1f\x8d\xb9\x5e\x2a\x6b\xf5\x3d\x4d\x9c\xba\x02\x84\x06\xf2\x7a\x57\x15\x63\xaa\x36\x60\x49\xa8\x88\x8f\xf3\x5c\x52\x15\xde\xf2\xb4\x67\x49\x64\x41\x70\x3a\x6f\xe4\xb9\x6e\x88\xec\x66\xb9\xb8\x10\x58\x22\x22\x2a\xc3\xb7\x09\x81\x59\x12\xe5\xd3\x54\x11\xb0\x04\x25\xf7\x8a\x9a\x95\x85\xf4\xbb\x96\x54\xa5\xda\x6d\x35\x0d\xb6\xa7\xcb\x30\x77\xd7\x45\xfa\x1a\xf8\xce\x4a\x3e\xc4\xb3\xf6\x8c\x67\x31\x9b\xb8\x51\x5a\xcf\x67\x5d\x66\xd0\xb8\xb8\xbc\xdf\x55\xac\xc2\xf1\xb4\x1b\x4f\x91\xa6\xc2\x6f\x5f\xef\xf6\xeb\xfb\xbb\xdd\x7e\x7d\x73\xd8\x3e\xad\x37\x77\xdf\x37\x23\x5d\x6d\x60\x22\x88\x2c\xb4\xb2\x3b\x41\x2d\xc3\xc2\xf4\x46\xdd\x06\x6c\x13\xf1\xaa\x75\x35\x62\x1f\xda\xae\xc0\x20\x43\x0b\x47\x6b\xf1\x68\x65\x75\x2c\xf4\xf3\xe2\xae\x32\x0e\x2c\x72\xae\x9b\xe4\xd6\xbc\x99\x6c\x43\x0c\x94\x65\xb7\xf0\xa6\xd6\x98\x42\x65\xba\x7d\x32\x40\x19\xa9\x0b\x09\xd6\xd1\x54\x97\x61\x4a\x6c\x28\xa3\x02\xc9\x15\xc1\x22\x70\xfe\x85\x64\x1a\x49\xb7\x39\x5e\x6f\xf6\xab\x67\xc8\xcb\xc6\xe6\x3f\xfc\x73\x49\x09\x04\x8f\xdc\x63\xd3\xde\x56\xd5\xf0\x67\x19\x07\x5e\xd1\xe9\x19\xda\xfc\x0d\x09\x3f\xda\xb7\x2b\x20\x4d\x2a\x4b\x16\xd1\x2d\xac\xa6\xb7\x51\x80\x49\x93\x11\x8c\xd2\x6a\x13\x5a\x61\xb5\x5e\x25\xc8\xf5\x51\x81\x25\x6f\xc3\x63\xde\xae\x7f\xa1\x3a\x0f\x47\x2f\x53\x91\x50\x2e\x80\x7b\x77\x77\x77\x78\x0a\x67\xaf\xa5\xe2\x98\xf8\x45\x6e\xe0\x74\x2a\xd0\xa1\xa5\xfa\xa1\x56\xc6\xa6\xd0\xfa\xc2\x2e\x1a\xc5\xbe\x34\x6c\xbc\x77\x4c\x0b\xf9\xdc\xf5\x3a\xb5\x33\x5f\x63\x8b\xf5\x31\x2f\xd1\xd3\xec\x7d\xf0\xbd\xf4\x40\xb1\xb4\xc3\x52\xf7\xf1\x1e\x60\xc8\x52\x1a\xfe\x26\x7f\x2e\xa7\x64\x93\xb6\x43\x18\x70\x41\x89\xa2\x55\xad\xce\xfe\xf9\xc3\xc0\x18\x2f\xb8\xf5\x1b\xe6\x0e\x67\xd6\xd9\x2e\x4b\x31\x08\x08\xc3\x28\x23\xf7\x5c\x5b\xc1\x3f\xff\x65\xc3\x30\x12\x91\x1c\xb1\x1f\xec\x2e\x95\xbb\x20\x8c\x22\x23\xa3\x7e\x8f\x1e\x25\xdb\x21\x4c\x45\x68\xb9\x47\xf2\x23\xee\xab\xdb\xbc\xcc\x9b\x17\x3b\xa7\x47\x06\x54\x98\x25\xa9\x71\x1e\xf9\x6f\x54\x4a\x35\x7d\xc1\x2c\x95\x32\xf5\xe2\x18\x1e\x85\x38\xed\xc2\x23\x61\x25\x11\x3d\x87\xe4\x94\xe1\xc8\xf7\x42\x5b\x10\xb8\xfe\x7d\xff\xb4\xba\x59\x93\xf4\xcb\xc7\x0c\xbb\x10\x72\xc3\x69\xe8\x5d\x49\xe9\x10\x6d\x80\x50\x04\x86\xc4\x9f\xe5\xb9\x2e\x2d\xfd\xd6\xf8\xc0\x08\x45\x14\x11\xc9\xa3\x3c\xbf\xaf\x8a\xe2\xf1\xdc\xaa\xea\xf8\x41\x82\x0d\x42\x11\x07\x84\x69\xfa\x51\x75\x47\x13\xf9\x23\xfa\xb3\x2c\x16\x84\x9d\x61\x49\x0e\xc1\x4f\x38\xb9\xfa\x96\x8f\x43\x6b\x10\x42\x24\xa8\x52\xee\x19\x8a\x02\xa1\x19\x6d\x93\x93\xc4\xe2\x07\x17\x27\x51\xe0\xc0\x8d\xab\xa2\xb0\xcc\xef\xfd\x34\x93\x41\xc2\x2d\x87\xc7\x93\x15\x96\x9b\x8d\xb8\x0c\x35\x1d\x79\x1b\x6c\xc1\x2b\xdc\x7f\xe4\x4a\x7d\x7e\xca\x84\x32\xe3\x34\xe2\x26\x2f\xf5\xa4\x6e\x6c\xde\x4f\x30\xd6\xeb\xa3\x91\x86\xcf\xfe\x75\xf6\x54\x8a\x49\x2a\x68\x22\xcc\x8e\x15\x44\x9a\xf7\xe0\x89\x77\x1d\x3a\xa3\xca\xc5\x91\x2e\x2d\x86\x50\xa9\x94\x48\x32\x0e\xae\x30\xb6\x5b\xec\x4d\x33\xaa\x36\xff\x9f\x0f\xd0\xd9\x10\x22\x53\xa9\x3b\xd9\xfa\x03\xfe\xd1\x38\x50\xca\x6c\x7e\x63\x6c\x11\x74\x5e\xe4\xce\x6a\x00\x8e\xf5\xb3\x21\x44\x65\xb4\x5b\xab\x9b\xaa\x21\x95\x9f\xe9\x5d\xa2\x40\x04\xe4\x45\x69\x7c\xdb\xad\x1f\x76\x17\xb8\x60\x88\x02\x94\x94\xa8\x7c\xa9\x8a\xf7\x5b\x27\x2b\x79\x7b\x2e\xf5\xd4\x76\x8d\x58\x14\xd0\xa1\x6d\x21\xc6\xf8\x61\x7a\x1a\x22\x16\x2b\xb2\x8f\x6f\xbf\x3f\xdc\x1c\xbe\xac\xf6\x5f\xd7\x4f\x77\x0f\x5f\xc6\xc7\x6d\xc4\x44\x22\x06\xe0\x1e\xd5\x46\x7d\x3a\x13\x22\x86\x48\x8a\xc7\x1b\x9b\x31\xeb\x9e\x2f\x2f\x9f\xbf\x54\x50\xcc\x8a\xa2\x5c\xff\x50\x71\xcf\xac\x76\x53\x95\xd0\x7a\x32\x76\x88\x62\x26\x95\x2b\x7b\x71\x6f\x3b\x9d\x07\x51\xac\x90\xc6\xd4\xa7\x98\x3b\xcb\xf5\x6a\x7f\xfd\x29\x4c\x1f\xa2\x24\x60\x64\xb3\x38\xaf\xde\x3f\xd5\xa7\xeb\x2c\x4a\x03\xa4\xc8\xb5\x0b\x25\xfd\x86\xb9\x7f\xca\x34\xb4\x49\x88\xee\xc3\xda\x57\x76\x8e\xee\x13\xfe\xf7\x9c\xd7\x78\x21\x14\xd3\x5d\x62\x05\xbf\xee\xae\x1f\x3b\x8f\xe7\x69\xcf\xfa\x9b\xa5\x9a\xb4\x57\x9a\xca\xb4\xd7\x30\xb3\xf3\x23\x1e\x30\x4a\x62\x58\x7e\x3e\xca\xc5\x74\x1b\xf5\xd5\xf9\x7d\x22\xbc\x32\x4b\xb8\x40\xc4\x63\x6b\xf7\xeb\xce\xb2\x7e\x3c\x61\xb9\x24\x71\x0e\x11\x4f\x91\xbb\x3a\xd4\xf3\x69\x75\x94\x79\x38\x1b\x6f\x9e\x49\x15\xf6\x2c\xb6\x0f\x55\x7b\x71\x07\x23\xd0\x52\xb7\x13\xa9\xf6\xb4\x51\xa4\xa1\xd5\x49\xce\x4b\x9b\xaa\x09\xfd\x5b\x0b\x29\xa9\xfe\x9f\x58\x28\x2d\xdc\xe2\x1a\x4e\xce\xf7\x59\xde\x48\x22\x08\x90\x04\xf4\xcd\x30\xbf\xfc\xed\x00\xb8\x93\xf5\xfb\xfd\xd7\xa6\xfa\xfd\x57\xff\x77\xa9\xc8\xa2\x19\x88\x10\x8f\x57\xbe\x4d\x06\x92\xb0\x03\xb4\x90\xf2\x37\x3c\x74\x86\x41\x73\xa8\xcc\xc1\xeb\x73\xb8\x8e\x2a\x56\xa4\x03\xe7\xa0\xbf\x97\x18\x19\x88\x94\x94\x84\x58\xee\x96\xd1\xd3\x61\xb7\x5f\x6f\xfd\xc5\x3a\xc4\x44\x8d\x21\x7f\x43\x2c\xdf\xf7\x88\x25\x1b\xc0\xa2\xbb\x9f\xc3\x1c\x98\x9e\x7e\x91\x06\x1b\x73\x75\x5b\xdb\xb7\xfd\xec\x3e\x52\xb1\x3e\xba\x42\xce\xe3\xb6\x67\xe8\x1d\x9e\x14\x83\x80\x79\x7e\xc0\x5a\xe6\x2d\x41\x35\x83\xd9\x57\xc7\x90\x53\x4d\x92\x7b\x63\xa7\xcc\x42\xa5\x36\xfe\xbd\x10\x65\xe2\x56\xaa\x6e\x11\x8e\x44\x85\xd7\xd9\x32\xf3\x19\x64\x92\x8c\xa2\xca\x0d\x5a\x09\x2d\xcf\xb5\x7b\x51\xff\x03\x71\x90\x70\xad\x87\x5c\xd1\x0d\x61\x7e\x8e\xa7\x02\xbb\x1d\xf1\xea\x7d\x0b\x2d\x11\x72\x59\x51\xcd\x51\x41\x07\xc4\x41\x6a\xd5\x5f\x3b\xbb\xd3\x07\x55\x9f\x28\x7e\x75\xb1\xca\xfd\x15\x3c\x4e\x62\x67\x2f\x2c\x3b\x7d\x71\x20\xac\xe0\xc3\x6e\xbd\xff\xbe\x3d\xdc\x3c\x3e\xf8\x1d\x32\x0e\x33\x4d\xd2\xa8\x84\x4e\xb1\x98\xed\xbe\x09\x6c\x9c\x9f\x4e\x3b\x6b\xba\x4d\xfc\xdf\x38\x52\x92\x32\x0d\x27\x67\x7f\xfe\x86\xf9\xf3\x4b\x3b\x64\xd4\x66\x0f\xd1\xdd\x50\xba\x40\x1d\xe4\x47\x0a\xd4\x8d\x3f\x7b\x1c\x3b\x62\xb6\x89\x31\xe6\xdb\x74\x46\x18\xaf\xed\x97\xcd\x61\x28\x9b\x83\x38\xc9\x78\x92\xf4\xa5\xcf\x58\x57\x1b\x2c\x1b\xf8\x4f\x6f\x46\xc4\x29\x67\x1e\x78\x75\xed\x75\x01\x21\x4e\x45\x40\x00\x5b\xc7\x1e\x4e\xf5\x07\x0f\x8f\x4f\x9b\x95\x0f\x27\xc5\x59\x6a\x79\x14\x29\x80\xbd\xb5\xec\x27\xd8\x8b\xaa\xef\xf1\x78\x2a\xe6\x54\x88\x10\x67\x82\xa5\x7d\x29\x2f\x95\xa0\xac\xea\xe7\x99\x33\x16\xf3\x30\xd4\x0e\xec\x3f\xa6\x90\x59\xae\x51\x19\x5b\xfe\x31\x8f\x23\xe5\x2a\x55\xf4\x59\xb5\xd1\xa1\x38\xab\xd7\x77\x79\x7e\xdf\xd7\xa0\x5e\x87\xc1\xe2\x32\x26\x7a\x90\xcd\xf5\xdd\xa6\xff\x9b\x49\xec\x79\xd4\x42\xdd\x1e\x4e\xcf\x87\xff\x9e\xf3\x3f\x17\x52\x71\x10\x03\x88\xd0\x15\x70\x77\x96\xee\x1e\xe1\x68\x95\x07\xc7\x66\x68\x2c\xb3\x20\x4b\x3c\x3d\xcd\xeb\x7c\x20\x64\x96\x92\x58\x41\xf3\x5e\xa2\x7a\xa9\xab\x72\x7a\xad\x41\x29\x69\xcb\xfc\x85\xba\xb3\x34\x6c\xeb\x9c\x87\x6b\x3a\xcd\x55\x88\x5e\xce\x1d\x9b\xe6\xf0\x92\x6b\x8d\xe5\xc1\xb2\xd1\x5d\x66\xeb\x67\x73\x4f\x89\x14\x48\x7c\xba\xdb\xf6\x3f\xd6\xfa\x86\x58\x81\x1a\xa1\xce\x3a\x03\x8d\xb8\xea\x97\x4d\x90\x18\xa3\x90\x58\xd9\x37\x77\x0f\x77\x9b\xd5\xfd\xc1\x17\x67\xde\x3d\xfc\x58\xef\xf6\x9b\xb5\x4f\xfe\x74\x3d\xd3\xc4\x3a\x6d\x4d\x5b\x57\xef\x16\xf0\x68\x73\x3a\xd3\xd7\x34\xa1\x21\xf6\x39\x8d\x36\xd4\x4d\xb9\xaf\xbf\x43\x91\x01\xb1\xc9\xa4\x08\x27\xdb\x66\xfe\x27\xea\x59\x56\x05\x62\x23\x53\xaa\x28\x7f\xf4\x3a\x9b\xff\x98\x04\xb9\xfe\xc5\xdd\xc9\x9b\x04\xb1\x42\x57\x33\x31\x20\x7d\x26\x3f\x99\x04\x80\x14\xae\x1f\xa8\xa3\x3f\xa4\x11\x58\x98\x6a\x09\xe3\x9a\x6a\xc8\xf1\x54\xa9\x97\x83\x2b\xf7\x3a\xa8\x51\x3c\x2a\x61\x90\x7a\x7d\x18\x9b\x8b\xbe\xd3\xb7\x55\x4d\x2c\x31\x8b\xdb\x4c\x12\x82\x26\xac\x9c\x35\x8d\x7a\x1e\x4c\x68\x3f\x72\x92\x92\x28\x30\x41\x34\x95\xef\xbf\xed\x9c\xda\x7a\xf9\xf4\x4a\x22\x16\x48\x31\x6c\xee\x21\x31\xd7\xfb\xe7\x8d\xa4\x22\x26\x0a\x0a\x70\xef\x46\x0e\xfd\xa5\x69\x93\xc4\x41\x88\xc2\x53\xe5\x17\xb9\x7a\x27\x37\x70\xfa\x70\x71\x04\x84\x0f\xcf\x9b\x3b\xe5\xbc\xdc\x3e\x10\x91\xc4\x89\xa4\xf9\xe7\x10\xee\x3d\x92\x1f\x92\x44\x21\x49\xdd\x6d\x8b\x73\xb3\xed\xe3\x22\x49\xa2\x6d\x0d\xe4\x90\x74\xbb\xaa\xe1\x79\x90\xb1\x80\x24\x65\x89\x0a\xa6\xfc\xce\xcd\x16\xeb\xef\xbb\x9b\xd9\x83\xf1\xce\x41\x73\x5c\x4b\x87\x23\xfc\x3a\xe8\xe7\x5f\x23\x71\x4f\x0d\x79\x1f\x4c\x49\xb8\x42\xb2\xc3\xad\x6f\x71\x9f\x97\xaf\x0f\xd8\x7f\x61\x91\x65\x54\x2b\xbb\x59\xfd\xee\xb9\x3d\x56\x37\x3f\xee\x76\x8f\x3e\xc5\x0f\x89\xe0\xb1\xea\x8f\xb8\x51\x2a\x1d\x12\x88\x12\x70\x61\xc0\xef\xbb\x9b\x39\xee\x16\x12\x48\x84\xa5\xc5\x29\x9f\xf1\x42\xcb\x03\x12\x19\x1b\xcf\xca\xe1\x11\x0a\x7d\x13\x6a\x1b\xe2\x24\x4a\x12\xc2\x72\x78\xd6\xc7\x4f\xf1\x7d\x90\x28\x1e\x53\x95\x80\x4b\x81\xfd\xf7\x8c\xe7\x7e\x7a\x28\x11\xf4\xd2\xef\x54\x36\x72\x5d\x40\xd3\xb8\xaa\x86\x0f\xe6\xa7\x42\x4d\xde\x1c\x4d\x29\x65\x2d\x98\x16\x7e\x7d\xec\xcc\xfc\xbf\xfe\xeb\x7e\x4f\x27\x11\x31\xad\x36\xf9\x73\x39\x64\x97\xaf\x27\x1e\xb6\xef\x2a\x23\x63\xe3\x33\x65\x75\x26\x9e\xaa\x31\x31\x5c\xd7\xae\xc8\x9f\xca\x4f\xd5\x4f\xaf\xf4\xd1\xfd\xc3\xfa\xdf\x32\x61\x28\x7b\x7e\xc5\x57\x2a\x58\xbc\x0c\x22\x25\xc8\x63\x82\xc1\x95\xf9\x9f\xaf\x07\x8b\x5f\x25\x04\xfa\xdf\x67\x55\x9b\x6e\x3c\x26\x09\xc2\x5e\x33\x81\x08\x2a\x3f\x62\x1f\x9e\x0e\x8d\xc9\x18\xd9\xc0\x3b\x6c\xaf\xf3\xf6\x9d\xa0\x1d\xd3\x8f\x6f\x44\x46\x61\xad\xbb\x87\xbb\xfd\x1d\x89\x29\x5e\xed\xee\x6e\x5c\x5d\x34\xa4\xa1\xcc\xb2\x9e\x82\xe6\x05\x6a\xc7\x8f\xb6\xb8\xa1\xa7\x11\x0b\x49\x66\x81\x32\x90\xb6\x92\xd2\xdf\x27\x4a\xc3\x21\x03\x4f\x31\x8b\x7d\x45\x98\x84\x0f\x8e\x0a\x7f\x99\x0a\xad\x96\x6d\x5e\x76\x2e\xda\x5d\x39\x89\x02\xa7\x49\x90\x1a\xab\x24\xea\x72\xd6\x5b\x78\x47\x3d\x8e\xbb\xa7\x49\x1c\x61\x38\xe8\x3b\x38\xee\xa8\xbe\x51\xd0\xe9\x79\x95\xb7\xaa\xca\xcb\xfd\xd3\xe3\xc3\xdd\xef\x7d\x63\xa6\x28\x41\x67\xa3\x27\x55\xeb\x64\xec\xb1\xec\x1c\x52\xca\x7d\x8e\xcb\x97\x21\x4d\x59\x42\x78\xaa\x07\xfc\xb9\x5d\xdd\x51\xf4\xea\x34\x0b\xa6\xa4\x29\x26\xca\x51\xba\xec\xaa\x82\x12\xd1\x53\x60\xce\x6c\x44\xb3\x80\x31\xe3\x03\x19\x25\xbe\x13\x35\xf2\x68\x5e\xf6\x1d\x79\xc4\xb1\x1f\xdf\x51\xba\x39\x15\x81\xd5\x3f\x3c\x60\xa9\xaf\xb0\x75\x70\xeb\xe9\xae\x93\x0a\x11\x7b\x8d\xbf\xdd\x09\x14\x5e\x2d\xd0\x11\x41\x0a\x41\x40\x66\x90\x43\xca\xac\xdb\x97\x59\x49\x3b\xa4\xc0\x38\xbd\x5f\x7f\xfe\x12\x27\xfb\xf4\x14\x48\x41\x8b\x70\x84\xaa\x5c\xac\x9e\xe8\x7a\x81\x0f\x75\xae\xf4\x44\x67\x05\x52\xc9\x54\xe6\xc5\x50\x9c\xee\xbf\x6f\x09\x81\xe8\xf6\x8a\xaa\x7a\xed\xfc\xea\x6e\xfb\xeb\xac\x22\x1b\xed\xd0\xfb\xaa\xa7\x89\x5a\x9e\xc2\x32\x4e\xac\x64\x5e\x77\xe1\xee\x25\x3f\x35\x63\x22\x20\x36\x4b\xb0\xf9\x8b\x78\x44\x1b\xde\x9f\x24\x46\xd7\xe2\xf0\x34\x20\xb8\x1b\xd7\xaf\xd0\xbc\x7c\xbb\x14\x60\x74\x1d\x55\x96\x11\x1c\xf2\xa0\xaa\xb2\x39\x7f\xb8\xc0\x94\x64\x3e\x09\xea\xa2\xa3\xb5\x67\x59\x5b\x5e\x3f\x0a\x43\xaf\x76\xbe\x69\x9e\x1d\xf1\x8f\x6b\xd3\xa9\x89\xdc\xd9\xda\x56\xf5\xb1\x37\xb8\x52\xcd\x03\xf2\x5d\xa8\x64\x71\x33\xa4\xac\x53\x64\x11\x85\x01\x4e\x35\x15\x73\xd4\x57\xe7\x77\x12\x66\x6d\xda\xb3\x67\x3d\x80\x14\x43\x19\x3b\x40\x85\xf7\xe6\x3f\x60\xe4\x9a\xbd\x1c\x26\x22\x76\x67\x5b\xcf\x59\xd3\xbe\x60\xdd\x56\xf6\x33\xda\xac\xb0\xef\x2c\xb4\xc7\xdf\x0d\x89\xda\x91\xef\x91\xa2\x40\x0a\x3c\xf9\x5b\xed\xb0\x28\x6e\xf0\x08\x33\x29\x64\x48\x11\x23\xca\x60\xdd\xad\x36\xd6\x41\xc6\xce\x60\xfb\x0d\xf3\xe5\x6f\x90\x05\x29\xf8\x40\xd9\xd5\xf9\xdd\xc2\x09\x66\x3d\x40\xea\x21\x13\xbd\x7a\x83\x76\x90\xd7\x9d\xdd\x8c\x05\x49\xe2\xcc\x81\xd5\xdb\xf3\x26\x2f\x51\x6f\xb1\xbe\x81\xf7\xd9\x2d\x59\x64\x11\xa4\xc6\x55\x29\xec\xb0\xed\xbe\xfa\x0d\x9e\x6a\x9c\x6a\xda\xf9\x0b\x34\x52\xdd\x79\x55\xe2\xb6\x6a\x87\x08\x5a\x16\xc6\xcc\x12\x5d\xa3\x3a\xd7\x79\xfb\x7e\x70\x6f\xd9\xb7\x2b\x1b\xe3\x76\x98\x99\xa2\x3b\x1e\xad\x72\x71\x7f\x58\xfe\xa8\x5a\xd4\x0f\x95\xdd\x12\xd7\xdd\x80\x3d\x54\xa3\xcb\xc9\x19\xdb\x42\x0d\xb2\x2a\xaa\xdc\xaf\xfa\x2c\x0e\x80\x62\x28\xca\x13\xbc\xd8\x30\xf9\xd8\xbc\xc9\x62\x99\x92\x47\x4d\x55\xe9\x9e\x65\x69\xc6\xaf\xe4\xba\xa6\x69\xc8\xba\x17\xfc\xfd\x8f\x7f\xae\xfe\xd1\xff\x2d\x4e\x83\xd1\xe1\x3c\xdd\x9c\xb2\x2c\x0a\x45\xe4\x0b\x11\x1c\xe3\xcc\x53\x6f\x67\x3b\xb5\xd0\xff\x19\x25\xb3\x33\x1e\x69\xcb\x8b\x86\x58\x57\xef\xb3\xdb\x71\xa5\x08\x17\x75\xb3\xda\xdc\x5d\x56\x82\x40\xc6\x11\xed\x56\xd4\xeb\x55\x01\x0b\x2f\xf5\xaa\x20\x13\xcc\xa2\x24\x1d\x48\x75\xc0\xdd\xf7\x9a\xa6\xbe\x63\x68\x75\x2a\x9f\xd1\xeb\x6f\xce\xbe\xba\x10\xb1\x4f\x50\x4c\x0c\xc0\xed\xcf\xe5\x4d\x36\x53\xda\x50\x4d\xb7\xa3\xdc\xf8\x3f\x98\x27\xcb\xf3\x59\xc7\x22\xca\x7a\xa6\xd4\xce\x10\x1f\x49\xdc\x40\x86\xd2\xb2\xa5\x2b\x4b\xeb\x34\xc5\x2d\x12\x95\x30\xd5\xfb\xce\xb9\x50\x80\x33\x23\xb2\x70\x60\xd8\xb8\xc6\x02\x65\x9d\xb7\xb3\x65\xc2\xc3\xd8\x02\x99\x54\x55\x59\x67\xf1\x0d\xa7\x80\xae\x0f\x13\x2d\x1f\xfd\x7d\x2e\x60\x02\x3c\xcc\x52\x92\x8f\x38\x8c\x23\x5e\x53\x1e\xaf\xc9\x3c\xe0\x21\xb7\x01\x57\x9b\xfd\xbc\x08\xc2\xf0\x28\x0b\xfb\xb8\xa0\x23\xc1\x98\x16\x21\xfa\x7e\xc8\x09\x42\xe3\x4e\xf2\xf1\xc0\xf2\x38\x00\x62\xb2\xdc\x7e\xbb\x1a\x45\x9b\x78\xac\x59\x84\x7d\xb4\x89\xa8\x8e\x7b\xfa\x4f\xbf\xe2\x79\x12\x5a\x1e\xc5\x09\xfd\x53\xf3\xe1\x06\xc8\x93\x34\xa5\xca\xa8\x3a\x57\x2f\x93\x8f\x94\xa8\x80\x8c\x5e\x5b\x55\xf8\x68\xd6\xae\x32\x63\x76\x39\x06\x94\x81\xf3\x5b\xd9\x5d\xd9\x62\x5d\xf6\x01\x65\x9e\x6a\x0b\xbf\x00\xad\x3d\x38\xe6\xb3\xb0\xd3\xf8\xd3\x64\xa1\x2d\xce\xd2\x68\xe0\x5c\xb4\x77\xe5\xc9\x97\xb5\x01\xcf\x12\xa0\x38\x85\xc9\x9b\x17\x72\x99\xbf\x62\x71\x1a\x45\xf2\x7d\x37\x93\x50\x48\x18\x9d\x3a\xe6\xfb\x01\xdb\x97\x5e\xbc\xc1\xdf\x8c\x73\x05\x3d\x5b\x90\x83\x9c\x77\x07\xcc\xe0\x97\x72\x0e\x20\xbd\xd6\x82\xfd\x85\x47\x1b\x70\xf8\xde\xa0\x5e\x35\x63\xc1\x2c\xe0\x42\x28\xb2\xbf\x0e\x16\xd6\xe8\xf3\x66\xf3\x49\xb9\xb8\x86\x39\x24\x8a\x7c\x1a\x0b\x0f\xb3\x69\x28\x7d\xd7\x7f\x95\x6e\x58\x02\x7a\xf1\xba\x21\x3e\xc5\x9d\xa7\x38\xf2\x3d\x64\xc0\x98\xdb\x7f\x56\x87\xd5\x6e\x33\xfb\x60\x32\xe0\xc2\x26\x34\x5c\x8c\xf3\x32\x0b\xc6\xa5\x0e\x13\x67\x98\x1c\x24\xb6\x87\x39\x15\x4f\xd7\x43\xd0\x54\x34\x45\x7e\xb2\x2f\x3f\x2e\xed\x02\xae\x0d\xf3\x0c\xe1\x2b\x63\xf2\x22\xa7\x03\xc7\x54\xb3\xef\x83\x91\xd5\x81\x19\x59\x08\xa1\x63\x36\x99\xfe\x1e\x72\x7b\x10\x6d\x3c\x9a\xd7\xff\x90\xc9\x24\x31\x44\x7f\x5d\xfd\xb1\xda\x3f\x1e\x28\x01\x7e\x6d\xa9\x1a\x56\xbb\x75\xdf\x0b\xd2\xd4\xcd\xc2\x6d\xf5\x13\xeb\x73\x33\x4f\x88\x71\x83\x91\x64\x13\x06\x22\x9b\x1b\xea\x66\xed\xf7\xd2\x05\x5b\x50\xbb\xc0\xea\x2c\xaa\x2a\x82\x28\xa5\x68\xb5\x07\xb0\x50\x6c\xf1\x6f\xc4\x15\x45\x90\x4a\x1c\x98\x83\x1c\xe3\xfa\xc4\xbc\x60\x21\xf7\x7d\xc1\x56\x97\x19\xc4\xab\x73\x5d\x62\xed\xea\xe5\xa6\xe8\x67\x10\x8c\x05\x84\xcd\x7e\x2d\xf2\xd7\xfe\x6f\x3a\x31\xa4\xad\x9d\x17\xe7\x16\xb7\x93\xf8\xd2\xf4\x55\x18\x26\x64\x48\xe6\xcd\x43\xd5\xee\xb0\x30\xcb\x1b\xa1\x08\x53\xab\x48\x76\x24\x96\x58\xaa\xf8\x6c\x16\x12\xc9\x22\xcc\xe2\x50\x78\xd5\xa5\x09\x91\xf8\x62\x0c\x54\x44\x49\x4a\x5a\x8a\x77\xd1\xe4\xd0\x10\x91\x14\x94\x3d\xba\xcf\xeb\xf3\xaf\xe5\x28\xea\xc4\xcb\x16\x49\xac\xc9\x1a\xcb\x1d\x0f\xc5\x5d\x69\xa5\x12\xfc\x0d\x13\x8c\x28\x69\x8c\x84\x3d\x21\x3b\xd1\x46\x5b\x27\x0b\x52\x24\x86\x65\xdd\xf3\x5c\x7f\xf1\xe1\x54\x91\x06\x2c\x71\xa5\xed\x8f\xc6\x0b\x83\x38\x8e\xfb\xc7\xf2\xba\xb9\x9a\x19\x17\x82\x47\x82\xb2\x7f\xe6\x3c\xdb\x3f\x85\x90\x01\x1b\x93\xe7\x5d\x17\xf9\xe0\x84\x0a\x21\x21\x36\xfd\x2b\x8c\x8a\x79\xfa\x76\x49\x34\x43\x07\x8f\x86\x5a\x28\x42\x03\x01\x41\xe4\x85\x39\x7b\xc0\xf3\x07\xf8\xb7\x85\x68\x85\x90\x31\x4f\xf5\x20\x24\xb9\x14\xb5\x17\x4a\xa4\x84\x95\xbf\x81\xf7\x1b\x78\x5f\xb0\x9f\x84\x8e\x52\x92\xb5\xd1\x28\xcf\xcf\x87\x6e\x7e\x8c\x40\x5b\x42\x4b\x5b\xba\x49\x5b\x26\xf9\x23\xa0\xda\x59\x91\x2f\x08\x6d\xb8\x0a\x1c\x87\xda\xf5\x4b\xae\x5e\xb1\xdc\x42\xfd\x7a\x3d\x2a\x16\x73\x3d\x91\x09\x3a\x1f\x4a\xfc\xd5\xda\xaa\xe7\x71\x18\x41\x60\x82\xb1\x43\x14\x2c\x43\xf9\x41\x20\x86\x16\xb3\x59\x3d\x63\x9b\x8f\x8e\x61\x08\xd2\x18\xed\x47\x69\xb1\x6e\xce\x72\xbc\x99\x4c\xe7\x32\x04\x28\x89\xe3\xe2\xbe\x22\x6f\x6d\x59\x05\x61\x32\x92\xc0\x58\x68\x89\x0f\x8a\x11\xb1\xf2\xc2\x90\x03\x4b\x39\x77\x05\xd2\xdf\xc7\x4f\x30\x5d\x19\x3d\xcd\xd0\x68\x49\x02\x83\x8c\x6a\x5d\x6a\xf8\xf9\x5b\x7e\xc2\x55\xeb\x58\x7f\x2f\xe2\x50\x3e\x56\x0c\x61\x20\x52\xcf\x3d\x7c\x67\x25\x40\x59\x32\xc9\x9f\x41\x28\xad\x4c\x28\xf1\xe3\x5d\x57\xd6\x2f\x1f\x18\x36\x00\x22\x57\xee\xdb\xad\x9a\x9f\x25\xd6\x13\x85\x43\x80\x28\x14\xc4\x7e\xda\xd6\xe7\xa6\xfd\xc8\xfc\x82\x28\x49\x89\x6b\xe7\x44\x75\xf1\x3f\xab\xa1\x88\xbd\x6b\x13\x04\x7c\xb3\xc1\xe3\x23\x1e\xff\x31\x31\x2b\xfc\x8a\x86\x88\x07\x04\x21\xec\x9c\x8a\x27\x9c\x5b\x66\x10\x89\x8c\x7c\xaa\x9b\x1a\x9e\xab\xd2\xaa\xf1\xf9\x26\x19\xd1\xe1\x79\x20\xcd\xad\xe5\x6f\x1e\x99\xd4\xc3\xf3\xbe\xbd\x4b\xac\x89\x42\x74\x31\xae\x08\x91\xb1\x65\xc8\xab\xa2\xc5\xda\x6a\xe1\x54\xb5\x73\x06\xa7\xd3\xa4\x3f\x04\x20\x66\xa8\x87\x94\x23\x49\xab\xf7\x43\x98\x04\x8a\xd0\x53\x4e\x8c\xd3\x13\xf8\x5f\x68\x90\x5c\x26\x03\x20\x01\x06\x0e\xc0\x40\x36\x12\x34\x87\x06\xb1\x17\x20\x03\x48\x23\xcb\xcb\xf5\xec\x2a\x4f\xd7\x85\x83\xdd\xba\x76\x9e\x62\x68\xf5\x1e\x5a\xf5\xe2\xa0\x47\xae\x49\x70\x0b\xa3\x6b\x3d\xb1\xd5\xa7\x20\x13\x10\x90\x19\x31\x36\x73\x89\x95\xd2\xdf\x0c\xa2\xd8\xe3\x09\xc9\xd6\x1c\x7d\x08\xdf\x03\x6d\xf1\x8f\x13\x7e\x21\x9c\x2b\x9b\x98\x27\xa0\x34\xa3\x05\xb0\x79\x9f\x10\x28\x4e\xe6\xb3\x32\x76\x96\x80\x67\xaa\x1e\xf6\x0f\xd0\x90\x46\x96\xe9\xe6\x97\x85\x92\x8c\x72\x30\x80\x71\x48\x9a\x2b\x58\xea\x3b\x55\x4d\xce\x1c\x40\x19\xd9\x00\x6c\x7e\x3c\x15\xb8\xff\xb2\x9e\x9d\xdd\x60\xa2\x88\xe8\xd1\x2a\x63\x6c\x96\xee\xe0\xa0\xe1\xd3\x77\x34\x09\xa7\x2c\x2e\x99\x0d\xdd\xf2\xf7\xa7\xd0\x07\xcb\xc6\x70\xcb\x20\xfb\x8c\x2d\x14\x45\x8d\xcd\xb9\xf5\x26\xba\x0c\x02\xeb\x89\xfc\x91\xdf\xe7\x50\x51\x4d\xdc\x27\xfb\x8e\x0c\x22\x15\x26\x2e\x2c\x5c\xbf\xf9\x1c\x8d\x15\x99\x5b\x95\xda\x83\xab\xfa\xbb\x4b\x41\x29\xfe\x26\x7f\x2e\x9f\x50\x55\x6f\x58\xbf\x2f\x05\xf3\x25\x8b\xe2\x94\x8d\x52\x8f\x0b\xf0\x10\xc9\x22\x49\x96\x7a\xde\xfd\xe0\xf3\x68\xf7\x90\x2c\x06\x72\x63\xac\x1d\x75\x05\xe4\x26\xce\xe6\xd9\xbf\xfe\xbd\xc8\xa2\x08\x32\x64\x29\x8b\x7c\xa4\xa1\x3a\xb9\x60\x9c\xbf\x75\x08\x26\x94\x0e\x0a\xd8\x59\x77\x36\x6d\x39\xda\xd9\x64\xc4\x2d\xfa\x87\x0a\xea\xfc\x80\x50\xb5\xc5\xf2\x1e\x21\xe3\x50\xda\x44\x58\x0d\x65\xfb\xfb\xf6\x13\x75\x1c\x90\x31\x0a\x8a\xb4\x54\x25\xae\x6f\xbe\xf8\x9f\x4c\x42\xae\x2c\x03\xf7\x5b\xf5\x8a\x17\xa2\x40\x4b\xa8\x4f\x99\x20\x43\x36\x7c\x39\x77\x1c\xdd\x9e\x4b\x9a\xe0\x50\xf4\xc4\x6b\x20\x53\x16\x91\x87\x4e\x5e\xc8\xd3\xb9\xec\xe5\xcf\xfc\x7e\x20\x33\x10\x44\xe7\x01\xe7\x1a\xec\x76\xdf\xe6\xd2\xb9\xe6\x13\xbd\xd2\xae\xab\x24\xec\x95\x85\x61\x37\x5f\xa1\xa8\xa2\x9b\xd9\xd7\xcf\xb4\xe5\xe3\xee\xcb\x97\x97\xf8\xc9\x06\x37\x71\x2e\xc7\x03\x32\xc3\x98\xd2\xcf\x54\xcf\x4c\xc8\xb0\x43\xd8\x3f\xab\x01\x4a\xf4\x7e\xbf\x5a\xfb\x7c\x80\x14\xcc\x32\xdf\xbe\xf8\xdf\x49\xe3\x3e\xf7\x2c\x45\x6a\x28\xe6\xd7\x62\xd3\x7a\xac\x1b\x94\xb2\xaf\xef\xe8\xbf\x3c\x84\x21\x45\x39\xbb\x69\x73\x02\x59\xe0\x66\x70\xe3\x25\xc4\x3a\x74\x39\xbc\xb1\x25\x2b\x21\x35\x2e\xac\xd2\xde\x8f\xbb\xf3\x94\xd6\x28\x1d\xa0\xbd\x30\x03\x48\x30\x56\xd7\xa2\xc4\x5f\xb9\xa7\xd4\x03\x29\x03\x0b\x5e\x2f\xab\x36\x57\xf8\x5b\x5e\xf6\xa5\x92\xbe\x03\x0a\x32\x96\x6e\xd6\xb7\xab\xef\xf7\xfb\xc3\x97\xd5\x66\x7d\xb8\x7e\xdc\x79\x2b\x56\xaa\x20\x85\xc1\xc1\xdf\x62\x4d\xd2\x57\x87\xe7\x16\x93\xe0\xb5\x17\xf3\x05\xa9\x14\x28\x31\x42\xdc\x6f\xb0\x05\x4a\x15\x4f\xbf\xa0\x36\x7d\xc0\xd7\x6a\xce\x2d\xae\x60\x0c\x63\x4a\xab\xdc\xe6\x35\x2a\x62\x40\xf9\x6c\xaf\x41\x99\x42\x30\xd6\xea\x7c\xfd\x48\x91\x3b\xf6\x57\xa8\x88\x8e\x40\xef\xd1\xce\x8f\x9a\xc9\xc3\x98\x2c\xa1\x7a\xff\xeb\xdb\x87\x9b\x19\x9b\x08\xa8\x20\x8c\x28\xb2\x81\xed\x0b\xf1\x2f\x35\xf9\xf3\x98\x74\x13\x54\x90\x69\x65\x29\x64\xaf\xe1\x12\x3c\xae\x98\x92\x9e\x17\x4a\xe6\x45\xbe\xec\x6d\xa9\x30\xb5\x4c\x7e\xdd\xe0\xc2\x5c\x25\xcd\xf5\x89\x32\x4d\xb9\x6e\xca\x06\xed\xc7\xec\xff\xcb\x5b\x86\x8a\x54\x10\x3a\x7d\x18\x27\x41\xef\x1a\xe2\x40\x52\x98\xb5\x7d\xc1\xa1\x7e\x13\x54\x2c\x83\x04\x7b\x70\xe2\xe6\x9d\x92\x53\xd3\x0f\xa7\x62\xd4\xbe\xea\xff\x33\x2d\x5c\x50\x89\xb0\x99\x6b\xa7\xd6\x8d\x75\xcf\x1c\x32\xb1\x17\x55\x22\xa5\x17\xfb\xb4\x3c\x34\xd3\xd4\x8c\xef\xa5\x2d\x4d\xe5\x48\xd3\xcf\x3f\x75\x8a\xb6\xd0\xa3\x22\xb6\xef\xaf\x58\x1c\x87\x6f\x93\xa1\x2d\x5f\xde\x34\x3e\x84\xa3\x38\xd3\xc4\x19\x7d\xee\x8e\x96\xea\xd4\x7b\xf0\x73\xda\x1b\xd6\x1b\x45\x8a\x6b\x45\xa9\xad\xe6\x2c\x6f\xcf\xa5\xde\xd6\xa8\x06\xe7\x4c\x09\xa6\xac\x6a\x36\x36\xed\x2d\xe4\x45\x67\xd4\xea\xce\x9d\xe8\x3b\xc4\x96\xe2\xaf\xc9\x7f\xb5\x2f\x9f\x95\x94\x83\x12\xc6\xa2\x09\x2d\xf0\xe7\x07\x14\xf3\xc1\x9d\x6e\xe5\x0a\x78\x4c\x95\xec\x76\x61\x58\xcc\xa0\xcd\x9c\x4d\xbf\x1a\x88\x8c\x10\x32\xd6\x24\xee\xe5\x58\xa7\x9d\x64\x84\x64\x86\xae\xdb\x17\x2b\xcc\x73\xb3\x7a\xfc\xe8\xf7\x17\x79\x04\x41\xc9\x58\x52\x01\x42\xde\x90\x00\xca\x5d\x69\x11\x25\xcb\x71\x6a\x25\x33\x2b\x76\xd2\xb4\x23\xec\xd6\xfc\x8e\x46\xa6\x8e\x2e\x6f\xa2\xb7\x3d\x9b\xea\x2a\x90\x14\x0f\x73\xa0\xb4\xf9\xfb\xab\xd4\x90\xf3\x0e\x5a\xef\xf2\xf2\xb9\x40\x37\x77\xf7\xd5\x05\xfd\x8a\xbf\x82\x5b\x7c\x52\xcf\x64\xac\x8f\x79\x49\x14\xe6\xc5\xcc\x08\x53\x3a\x88\x99\xdd\x98\x7f\x3a\x15\xde\x4f\x0d\x5b\x85\x51\xcc\xe4\x04\xfe\x72\xa9\x24\x0e\x0a\x63\x46\x35\x23\x9d\xcb\xf9\xd6\xd3\x92\xcd\xfa\x24\x5c\x0f\x9e\xce\x55\x0d\xa5\x9a\x1e\x96\xdc\x77\x44\x6e\x6b\x06\x0a\xc8\x8f\x77\xd6\xa9\x0e\x3f\xf8\x2a\x86\xa5\xca\x65\xa5\xf4\x7d\xf5\xb3\x3b\xfa\xb0\x44\x63\x1d\x71\xdf\x27\xb6\xec\x87\x14\x1c\xb2\x52\xfb\xae\x49\x07\x41\xc2\xe7\x21\x3f\x9b\xa2\xdc\x56\xcd\x75\xa5\x67\xb3\x4e\x07\xa9\x74\xe5\xd1\xea\x5d\x15\xb8\x3a\x9d\x10\x6a\x0a\xed\x39\x87\xe7\x5f\xc9\x0c\x47\xa7\x03\x69\xc8\x07\xf1\x05\x17\x4f\xf8\xdc\xd9\x0a\x55\x3d\xd9\x98\x35\x8b\x43\x8a\x2a\x1e\x0f\x96\x25\x7f\xb2\xef\x68\x96\x64\x14\x9a\x94\xe7\xf7\x8b\x3c\xc2\xe0\x23\xeb\x30\x4c\xc9\xff\xaf\x71\xc2\xf0\x38\x99\x01\x3a\xe4\x36\xbf\x9c\x97\xa6\xba\x94\x0d\xeb\xda\x55\xc2\x26\x5a\x74\x74\xe0\x4f\xdf\x2a\x84\x40\x59\x6e\xb2\x95\xad\xc9\x1f\x61\xb6\x3e\x9d\x50\x3a\x52\x8c\x08\x56\xbc\x13\x41\x11\x56\xdf\xa6\xad\x8c\xc2\xa8\x26\x7f\x3a\x7d\x75\x2c\x03\xf0\x81\x62\x1f\x01\xb8\x58\xf6\x97\x44\x4f\xa0\x93\x08\x2d\x35\x1b\x94\x3e\x11\xa9\x13\x81\xb4\x0e\xb1\xd4\x87\x1b\x54\x87\x90\x1d\xc2\x80\x65\x7d\x33\x04\x04\xea\x39\x3c\xe1\x09\x6a\x38\x62\x8b\x75\xfe\x27\x19\xd2\x7d\x48\x6a\x66\xbb\x2e\xfa\xee\x3a\xcb\x0c\x15\xf8\x53\xfc\xfb\x37\x44\x6f\x3d\x69\xce\x03\xda\x81\x76\x96\xb4\x46\x4d\x4f\x1b\x2d\xd2\x98\x8e\x44\x27\x89\x90\x97\xf9\xf9\x78\x35\x0f\x33\x6b\x91\x09\x88\x3c\x8c\x9f\xb8\x90\x3f\x10\x4b\xfd\x28\xd1\x74\xe9\x68\x4f\x5d\xee\x0f\x8a\x79\x35\x40\x44\xa1\x8b\xba\x3b\x08\x23\x31\x7b\x2c\x50\x01\x05\xb9\x9b\xb6\x3a\xf9\xf3\xdf\x1f\x1d\x5a\x66\xca\x2a\xe7\xbd\xbe\x56\x36\x8b\xb4\x10\x5e\x9d\x30\xc9\x82\x96\xc6\x92\x0b\x74\x9b\x6b\x0d\x6a\xc6\xf5\x08\x5a\x85\xa1\xb6\xaa\x82\xff\x81\xf2\xf5\x75\x08\x7e\x69\x1d\xb0\x20\x75\x12\x04\x57\x75\x55\x7a\x8a\x3d\xd0\x5a\x65\x14\x63\x5f\xdd\xdc\x3c\x1d\x36\xab\x3f\x56\x87\xcd\xea\xe9\xdb\x7a\x7f\xf7\xe0\x9d\x16\x8d\x5c\x53\x14\x69\x5f\xb5\x6d\xfe\x41\x08\x77\xfa\xe6\xa8\x18\xd9\x9e\xce\x9c\xf3\x85\x9c\x8b\x52\x34\xfe\x12\x0c\x7c\xdd\xed\xff\x56\x79\x79\x83\xc5\x1c\xd5\xa8\x0d\x2a\x2a\x93\x82\xa2\xd8\x43\xf3\x3a\x96\x51\x06\x6d\x8c\x65\x45\x83\xb3\x83\xf3\x7d\xf0\xcd\x30\x88\x53\x8a\xc4\xfc\xa7\xca\xcb\x2f\x70\xbc\xcc\x4a\x8e\x87\x1c\x03\x65\xc1\x49\xc4\xf3\x71\x55\x95\x7a\x5c\x28\x88\x8c\xc5\xde\x68\x72\x47\x83\xab\x84\x71\x0c\x9a\xbe\x5b\x9c\xd0\xb3\x59\x32\xff\xbf\xfc\xce\xc8\x12\x60\x43\x42\xf8\x5b\x5e\x3e\xeb\xea\xaf\x68\x72\xa7\xc3\x89\x4c\x19\x05\x9e\x4d\xac\x2a\xa6\xc1\x71\x0c\xd3\x24\x4e\x27\x9c\x2d\x7a\x94\x44\x9d\x5a\x89\xfd\xde\x8a\x61\x9a\x39\x6e\x8b\xce\x79\xa5\x34\xe9\xc7\xa8\x31\x0c\xc1\x1a\xe2\xcf\x55\xa1\xb1\xb4\xbc\xd0\x14\x65\xf8\xc7\xbc\x1f\x50\x2a\x97\xaa\x28\x2c\x8e\x66\x1c\x97\xc1\x50\x5a\x0c\xfa\x31\xbf\x90\x10\x75\x3d\x22\x96\x7a\xb9\x65\x2f\x67\xe5\x2f\x8e\x38\x10\x73\x44\xde\xdc\x60\xd3\xd6\x36\x26\x44\xb9\xb7\xfe\x04\xc4\x98\x73\x3a\x40\x09\x50\xf3\x68\xa6\x5a\xe5\xbe\x8f\x34\xa3\x18\xe5\xae\xbd\xa8\x88\xc3\x24\x48\x89\x18\xc6\xd1\x26\x7a\xc7\x7b\x8c\x97\xc1\x44\xdb\x22\xcd\xfd\xfe\xfa\x6f\xcc\x82\x94\x83\xee\x71\x46\x06\xeb\x1a\x0a\x3a\x8f\x7d\xb3\xcc\xa8\xd6\xd8\x69\x15\x40\xdd\x96\x58\xb3\xc3\xcf\xbc\x98\x16\xd8\x60\x16\x84\x54\x6e\x76\xa8\x11\x0a\x4f\x9e\x56\x2e\x1c\x2d\x98\xc5\x16\x83\xba\x7d\xc9\x27\xae\x2f\x66\x99\x95\x67\xab\xca\xe2\xfd\x8a\x30\x9b\x35\x51\xa1\x8d\x94\x76\x87\x0c\x30\x66\xc2\x42\x41\xff\x89\x75\x35\xa2\xcb\xec\x1a\x90\xa7\x5e\xc7\xb0\x3b\x9f\x3b\x5b\x7a\xe5\x97\x30\x72\xc6\x09\xb9\x78\x6e\xb0\x76\xbe\xa8\x0b\x57\x7e\x5e\x80\x87\x5c\x46\xe1\x18\x66\xf4\xe5\x61\x3f\xfb\x3a\x5c\x71\xef\xb5\x6c\x3a\xa7\x86\x44\xd5\x27\x4b\x42\xa8\x38\x72\x93\x68\x93\x97\x16\x64\xdf\x37\xf1\xc4\xc5\x50\xa1\x69\xf2\x67\x87\x7f\x3c\x61\xbd\x7f\x3f\x4d\xc0\x21\x08\x60\x49\xd6\x9a\xb6\xaa\x71\xfb\x52\xb5\xd5\xf4\x5b\x80\x94\x91\x70\x70\x14\x87\x5c\x1c\xd8\xc5\x01\x65\x60\xbf\xe9\x0b\xc8\x5c\xbd\x94\xbd\x6d\x84\x52\x24\x9e\xf7\x68\x75\x6e\x2b\x6b\xb7\x3a\x21\x9f\xe9\x37\x54\x41\x42\x88\xbd\x3d\x1e\xeb\xea\x7d\xf2\x15\x55\x18\x92\x72\x18\xcd\xc9\xeb\x77\x39\x2d\xce\x40\x85\x3c\xe3\x03\x05\x91\x55\x63\x5a\xb6\xa0\xd0\x30\x9b\x2b\x77\x74\x44\xa3\xca\xcd\xf9\xf3\x18\xa6\x63\xdd\x17\x0b\x5e\x12\x15\x02\x9a\x30\x24\x77\x6d\x73\xf7\x6d\xbd\x5f\x3d\x7c\x79\xbc\x7a\x5a\xfd\x78\x64\xfc\xa2\x7c\xe0\xc3\x63\xfc\xf3\xd9\x61\x44\x62\xb5\x4b\xf2\xa9\x49\x89\x06\x15\xb3\x15\x8e\xdd\x56\x66\x7d\xa8\x6d\x8d\xe4\x7b\xf7\x0c\x2e\x1f\xa5\xff\x3f\x78\x06\x7b\x6b\x13\x24\xc9\x60\xc0\xdb\x4c\xfb\x3e\x2f\x0a\x5b\x42\x76\x1e\xe8\xee\xc0\x04\xa8\x09\xf8\xf1\x80\x3f\x77\x24\x69\xe5\x3e\x87\x61\x51\x44\x30\x1d\xbb\xbe\xaf\xeb\xf7\xa6\x1d\xac\x2d\xd7\x27\x0c\x80\x12\x89\xf7\x77\xfb\xf5\xf5\xe3\x93\x4f\x9c\x9b\x10\x42\x3e\x84\x55\xfd\x22\xf5\x8b\x69\x29\x5a\x61\xa2\x20\x8e\xbd\x5b\xbc\xaf\x9e\x9f\x0b\xbc\xca\xc9\x3f\xa6\x08\xfa\xe3\xa3\xaf\x1b\x34\x51\x98\x51\x70\xc7\xe5\x15\xab\xfe\xef\x69\x46\x65\x05\x0f\xf8\x73\x3c\xad\x4c\x12\x5a\xcc\x87\xc3\xa0\xaf\xcb\xb6\x7e\x1f\x76\x68\x93\xf0\xcc\xe6\xc3\xc0\xe0\xb8\xf2\x61\x3a\xe1\x4c\xa2\x95\x0d\xbe\x75\xdd\xce\x72\x09\x7e\x6b\x78\x12\x53\xd5\xc7\x4d\xde\x80\x2c\x5c\x61\xda\x78\x25\x1b\x2e\x2d\x5b\x1c\x81\xc1\x73\x8b\xd9\x1b\xa5\xa2\x0c\x57\xb1\x63\xda\xe8\xeb\x18\xba\xe3\x7e\x31\x0d\x64\x04\x0b\x22\xaf\x37\x57\x55\xc5\x4d\x55\xe2\xd8\x22\x31\x82\x25\x60\xbc\x32\xab\xd3\xc6\xba\x82\xf2\x75\x1e\x72\x32\x10\x28\x32\xc1\xac\xf2\x98\xe3\x16\xea\x26\xc3\xc4\xc2\x31\xc0\x10\x47\x14\xec\xbd\x77\x67\x80\x47\x7c\xec\xfb\xde\xd6\xd5\xf1\xb7\xbc\x7d\xa1\x53\x03\x29\x08\x5a\x14\xbd\x50\x2d\x18\x89\x31\xa9\xe2\xae\xf4\x07\x88\x67\xa3\x78\x4c\x84\xc7\x0f\xdf\xbe\x3e\xde\x4d\xbe\xa6\x92\x16\x26\x67\x5c\xbe\x60\x8a\xeb\x30\x3a\xce\xa8\xba\xcf\x65\x5f\xc8\xa2\xb7\xd4\x27\xbe\x03\x8a\xd4\x46\xe5\x29\xaf\x3f\x32\xa6\x0c\x42\x4c\x59\xf3\xd7\x77\xe5\x25\x6c\x5d\x8b\x49\x02\xca\x31\x9c\xd0\xa2\x95\x1e\x86\x63\xd0\x18\x13\xbb\xbc\x06\xad\xb5\x95\x97\xae\xb7\xed\x32\x60\x2c\xcc\x1c\xfa\x77\xc2\x68\x34\xb1\x0a\x65\xc0\x42\x43\x20\xf6\x3b\x55\xf5\x15\x7f\x32\x60\x89\x31\x99\x3f\xb0\x2c\xd1\xd7\x61\x88\xc0\xc9\x20\x8c\x62\x9a\x4f\x83\x02\xeb\x13\x2e\x57\x32\xca\x20\x94\x36\xbf\xd4\x60\xa9\x37\xcd\xf3\x3f\x16\xcc\xcd\xae\x53\x4a\x8b\xc5\x49\x85\x59\xb0\x7f\xb7\x5a\xa6\xf7\x8a\x78\x24\xc3\x89\xa2\xd8\x8d\x65\xfa\x99\xf7\x13\x49\x96\x7a\x36\x6e\xd4\xb9\x3f\x32\x7a\xa3\xae\xeb\x22\x47\x42\xda\x3f\xa0\xce\x61\x49\xad\xdd\xf7\xc6\x84\x68\x93\x0e\x1e\x36\xbe\x14\x4c\x94\x41\x9c\x85\x56\x84\x6f\x12\x29\x9a\xde\x2a\x86\x50\x5b\x70\xac\x35\x41\xa1\xe8\xb9\x26\x3e\x86\x97\xc9\x20\x96\x8c\x2c\xb1\x53\x8d\x5b\xc8\x75\xbf\x93\xc8\x20\x89\xac\x52\x43\xb7\x83\xdd\xb5\xe8\x35\x41\x7d\xab\xce\x78\xd2\x93\x82\x4c\xa8\xd9\x5d\x8f\x54\xd8\xda\x7a\x3b\x12\x0f\xf8\xf3\xcb\x48\x9d\xe4\x3c\x16\x56\xba\x48\xc4\xca\x20\x45\x41\x64\x39\x9d\x15\xeb\xa1\x66\x65\xff\x68\x59\x66\x93\xfe\x36\x4e\xb8\xad\x09\x98\x79\x89\xcb\x93\x01\x4f\x7b\xa8\xf8\x3d\x74\x2f\xe2\xd2\xca\x77\xfa\xa2\x63\x44\x13\x45\xe2\x73\x5e\x5e\x17\x55\x33\x73\x3a\x64\xc0\x79\x12\x7b\x22\xa3\xaa\x28\xa0\xbe\xad\xea\xc7\xd2\x6a\x43\x3c\xcd\x01\x90\x32\x10\x51\x4c\x42\xdb\xdf\x9e\xf6\x4f\xfe\x16\x10\x46\x44\x98\x43\x09\xb2\xab\xaa\x7a\x1d\xd9\x3a\x32\x80\x08\x6c\xbc\x06\x7e\x3d\x51\xc0\xa6\xe9\xaf\x8b\x33\xb4\xaf\xdb\x1d\x7c\x4f\xa3\x05\x03\x99\xa4\xaf\xa7\xed\x16\xdd\x9d\x4c\xa0\x48\x4d\x6a\xb2\x27\xca\x40\x26\x92\x60\xc2\x1b\x28\x4b\x20\x18\xc7\xd2\xb9\x20\x03\xd5\x2d\xd1\x6e\x2f\x3b\x75\x87\xf8\xae\x73\x33\x8f\x13\xfb\x5e\x06\x1a\x03\x96\xb8\x4f\x63\xbf\xfb\x04\xc2\x20\x03\x93\x1a\x02\xf3\xa0\x65\xec\x71\x75\xe1\xcf\x97\x62\x6e\x93\xc9\xee\x2f\x16\x31\xea\x41\x74\xf8\x7d\xdd\xbe\x8c\xc3\x5a\x92\x05\x91\x70\xa2\xbb\x94\x85\x7c\xef\xff\x0e\x8c\x42\x22\xf6\xac\xb9\x2b\xdf\x72\xaf\x61\x3d\xfd\x32\x2c\x90\x16\x31\x5d\x5b\x0c\x9b\x65\x9d\x1a\x74\xa2\x24\x0b\x30\x63\x23\xee\x48\x7d\xf8\xe9\x91\xe6\x92\x85\x19\xc7\x81\xcc\xf7\x19\x5d\x09\xc7\xf4\x17\x42\xa1\x62\xcb\xbd\x74\xc6\xfd\xd7\xab\xfe\x5a\x6d\xc8\x58\xed\xec\x71\x0b\x0d\x68\xfa\x26\x0c\xb2\xd8\xa7\x2a\xba\x05\xd2\x9d\x37\xf3\x49\xca\xe2\x18\x78\xec\x43\xed\x04\xea\x9f\x77\x48\x8d\x2b\xf4\xe8\x09\xda\xbb\xa3\x74\x50\xd7\x95\x2c\x09\x18\xe5\xf3\xff\x77\x3b\x4e\xc9\x4b\x96\x30\x8b\xc0\x3b\x52\x76\xe9\xe0\x53\x7c\xbf\x0d\xaf\x9e\x2a\x5b\x35\xf7\xf5\x7c\x84\x32\xff\x6f\x77\xed\x67\xd1\x70\xc9\x52\x63\x2d\x9b\x91\x1a\xde\x47\x90\x65\x77\x45\x16\x64\x4e\xa4\xb1\xd4\x24\xae\x71\x35\x67\xd0\x66\xe9\xd2\x2e\xc6\xb2\x34\x20\xdf\x4e\x55\xc7\x6e\xdb\xbe\xc6\x9a\x6a\x53\x96\xb7\x53\x96\xa1\x5d\xca\x04\x59\x3a\x5f\xf0\xb2\x4b\xc6\xa3\x4c\x7b\x46\xc8\xc5\xf8\x8a\x64\x42\xca\xbe\x0b\x1d\x84\xcd\xec\x5b\x40\x2c\x82\xb1\x00\xed\x47\x1c\xd4\x92\x41\x12\x67\x6a\xc2\xb0\xfa\x51\x10\x70\x21\x9f\x2d\x19\x40\x9c\xf4\x0c\x78\x13\x08\xab\x64\x80\x29\xc9\x61\x3c\xd6\xcf\x50\xe6\xea\x7c\x7c\xac\x07\x54\x82\x64\x32\x50\xdc\xea\x9e\xfe\x86\xf8\xaa\xe1\xfd\xae\x6c\x72\x8d\x7d\xf1\xc9\xe7\x4c\x2d\x92\x49\xa6\x31\xf5\xae\xfe\x76\xe2\xff\x48\x26\x55\x44\x88\x47\xcb\x77\x36\xb1\x45\x67\x77\xd1\x8c\x8c\x9c\x07\x4a\x8f\xed\xd0\x43\x46\x5d\xb3\x4a\x22\xca\xfc\x13\xa4\xe6\x47\xd5\x52\x39\xf1\x5d\x69\xaa\x5b\x5b\xb5\x31\x35\xff\x24\x53\xa9\xe2\x6e\xab\x7b\xfe\x72\xae\x16\xa0\x2d\xd3\xd3\xc7\x5f\xc6\xb9\x1c\x23\xc6\xad\x18\xdc\x07\x8f\xac\xa4\xf4\x50\x09\xa7\xe6\x3c\x32\x86\x7c\x1f\xad\xc9\xfe\xf2\x5e\xb4\xdd\xc6\x22\xff\x5a\xe8\xf8\x41\x1b\x6c\x2d\xb6\x65\xbc\x2b\xf7\x7d\x38\x45\xe8\x0e\xfe\xa1\xae\xf2\xa2\xc6\x0b\xf9\xcd\xd9\xc3\x19\x66\x68\x00\x76\xcf\x7a\x5f\xfd\x86\x39\xe9\xd0\xcc\x82\xbc\x92\x99\x28\x22\x5b\x0b\x89\xfd\x64\x04\xbc\x97\x61\x64\x6c\x13\xcd\xa8\x09\x1b\xa4\xeb\x10\x47\x71\x64\x9d\x8c\xe2\x0d\x9e\xf1\xd1\x52\x54\x11\x8c\xa2\xae\x8e\x73\x31\xc4\xe5\xc7\x0c\xe3\x24\xa6\xc4\xa1\x75\xbe\x3b\x4f\x6a\x55\x42\xf1\xde\xe6\xaa\xe9\x7f\x47\x73\x4a\xc9\x39\x09\x91\x23\xb1\x2d\x7e\x96\x0c\x90\x61\x12\x19\x74\xc1\x85\x5e\x7b\x57\x16\x8e\xda\x7f\xb5\x9b\x0e\x70\x98\x70\xa6\x7a\x80\x47\x0f\x1e\xf2\x8d\x80\x0a\x7c\x23\x59\xdd\xdf\x77\x37\x7d\xa3\xc6\xd8\x46\xc2\xa6\x0e\x9a\x0c\x13\x54\x09\xf7\x55\x5c\x7e\x5c\xc6\x27\x7d\x98\xc6\x96\x80\xd0\x1d\x30\x0f\x3f\xf6\xcb\x36\x5d\x98\xa6\x92\x02\x31\xfa\x6c\xd1\x36\x2f\xfe\x37\x52\x6d\x91\x9b\x25\xfe\x74\xf1\xb5\x0f\xce\x56\xdf\xdf\x18\x72\x69\xfe\xf7\x5c\xbf\xf7\x34\x8b\x17\x2c\x64\xae\x73\x16\x03\x55\xcf\x37\x6d\x75\xba\x53\x95\xff\xcd\x2c\x8b\x44\xf7\xe7\xfb\xdd\xf5\xb7\x41\xf9\x49\x86\x3c\xb2\x6c\x5b\x4f\xab\xfd\xfa\xb0\xbf\x5b\x3f\xb1\xbe\x05\xac\xbc\x45\xd5\x6d\x3a\x96\x1a\xf1\x43\x1b\x60\x79\x00\x44\x68\x37\xd1\xe6\xbf\x67\xa8\x67\x26\x56\x28\xe2\x98\x0c\xd4\x02\x9a\x76\xa5\xda\xfc\x0d\xf7\xfd\xcc\x01\x29\x29\x0a\x4a\xe4\xc6\x6f\xb8\xc1\x63\x55\xbf\x93\x32\xe1\x2c\xa1\x32\xc3\x78\xca\x50\x86\x31\x5a\x70\x95\xcf\x4e\xd6\x5b\x68\x26\xe0\x52\xdf\xd3\x18\xe1\x0a\x93\x9e\x2a\x59\xb5\xcd\x6d\x55\x2f\x74\x53\x09\x23\x6b\x40\x81\x97\x63\xda\x57\x03\x26\xc4\x9f\x39\xa1\xe2\x82\x70\xd8\xb7\x24\x31\xb9\xaf\x2c\x7f\xe8\xf2\xd2\x51\x20\xa8\xf0\x78\x5b\x57\xda\x43\xac\x5c\x93\x66\xd2\xc7\xdd\x2c\x72\x93\x7e\xea\xa1\xff\x8a\x3a\x92\x61\xd6\x97\x93\x3d\x77\x8e\x8e\xea\xc1\xd2\x7e\x82\x62\x10\xc4\x83\x13\x33\xd7\x4b\x9e\xbe\x1e\x26\x01\x05\x21\xfd\x36\xe7\x90\x6f\xa3\x38\x81\x0c\x0d\x02\x61\x6c\x24\x49\xdc\x0c\xfc\xce\x32\x0a\x82\x2c\xd6\x03\xdc\xd5\x4e\x12\x3a\xa4\x3e\xe2\x0f\x9e\x0e\x45\x14\x44\x22\x4d\xfa\xf7\x99\x65\xbe\x65\x14\xc4\x2c\x13\x23\xe8\x4c\x5e\x3e\x60\x5f\xe0\xb4\xbc\xea\xa2\x20\x61\xda\x25\xa8\x0f\x2e\xfc\xdc\x6d\xc0\xde\x47\x96\x51\xa0\x31\x74\x49\xf9\x6b\xe2\x8f\x5c\x40\x4e\xca\x88\xa5\x9a\x9c\xca\x91\xb2\x9f\x63\x3e\xea\x11\x62\x97\xbf\xcd\x32\x21\x1d\x17\xd8\x5a\x55\x65\x75\x7c\xdf\xfa\x44\x61\xe3\x33\xc2\xff\xf3\x7f\xfc\xb7\xbf\x35\x5a\xdd\x72\x92\x4e\xdd\xda\x7d\xdf\xef\x91\xc5\x6c\xdc\x98\x96\x64\x03\xe7\x65\xdb\x63\xb0\x64\x14\x66\x2c\x70\x38\x82\xab\x5c\xef\xab\x5d\x0b\xea\x75\xe4\xfd\x46\xa1\x06\x1b\xd7\xf7\x14\x3d\xf9\x71\x90\x9e\x95\x51\x14\xd8\xea\x12\xf2\xfc\xd5\x14\x6a\x24\xa3\x08\x03\x2a\x53\xf2\x04\xe3\xde\x8f\x5d\xf6\x5f\xa7\x83\x1d\x19\xa0\x4f\xe2\x2a\x54\xc6\x24\x4a\x32\x8a\xc3\xc0\x17\x05\xfb\x8a\x31\xe7\xdf\xeb\x5d\x8b\xa7\x66\x5b\x57\x9e\x0c\xca\x5d\x91\x84\x22\xb5\x09\xfe\x69\x9d\xb7\x8c\x12\xce\x84\x8b\x42\xb9\x95\xb7\x2e\xf5\x8d\xf7\xff\xfc\x6a\x8e\xd2\x90\x91\x89\x99\x97\x40\x3b\x53\x5f\x6d\x35\x50\xa3\x77\x9d\x32\x5b\xa4\x96\x63\x1d\x52\xaa\xa5\x6f\xc9\x22\xba\xfc\x6e\xfb\x96\x8d\x0f\x97\x28\x0b\x20\x60\x3e\x82\xd2\xfd\xfa\x4d\x1f\x2a\xd1\xdf\xcb\xc1\xa3\x88\x32\x99\x52\x0e\xf7\x69\xf5\xfb\xe4\x06\xdc\x44\x54\xfd\x79\x62\x87\x9f\x2f\x79\x8b\x07\x7f\xb6\xf8\x0e\x22\x66\x84\xa9\x7d\x22\xc7\x7e\xfa\x56\x22\x89\x89\x0e\xf2\xad\x6a\xb1\xdb\xec\x8a\x36\x3f\x42\x8b\x8e\xff\x72\x52\xe3\xc3\xfc\x4c\x02\x88\xad\x48\xa9\xf7\x49\x08\x3e\xb8\x14\x02\x94\x11\x20\xa3\x48\x1a\x68\x6d\xb7\xbf\xc9\x37\x96\x46\x45\x6e\xd9\x0d\x81\xdf\xbf\xc3\xac\x31\x9a\xa0\x2a\x8c\xff\x7f\xce\xbe\xac\xb9\x71\x1c\xcb\xfa\xef\xd4\xc3\x3c\x70\x01\x40\xf2\x51\x96\x64\x5b\x9d\x5e\xd4\x92\x9c\x59\xd5\x5f\x4c\x28\xb0\x5c\xc8\x6c\x53\xa4\x86\xa4\x6c\xab\x7f\xfd\x17\xbc\x00\xb8\x89\x76\xd6\xcc\x4b\x65\x94\x01\x52\x24\x88\xe5\x2e\xe7\x9e\x83\x69\xa5\xc6\x51\x80\xbc\xea\xf9\xed\xc3\x6d\x2d\x94\xdc\x97\x7d\x2e\xde\x27\x7e\x84\x3f\xf3\x5e\x04\xa3\x7f\x53\x4d\x7c\x27\x6f\xf4\x79\xca\x8a\x2a\x7d\xff\xa6\xb6\x48\x84\x2a\x34\xd4\xfb\x68\x21\xc8\x37\xa8\x0d\xb5\x53\x2f\x3a\x29\x42\x95\x84\x58\x00\x61\xfd\xb1\xb4\xda\x17\xa7\xee\x2b\x42\x20\xd1\x5b\xbb\x39\x5f\xcc\x1d\x5e\x2a\x03\x7f\x6a\xac\xe7\xd1\x52\x06\x0a\x18\xf8\xe6\x68\x02\x59\xfd\x36\xd7\xa6\x62\xaf\x5f\x77\x93\xf5\xd8\x61\x45\xa8\x3d\x2d\xa2\x36\x64\xbe\x41\x2d\x93\xed\xb9\x3a\x21\x82\xcb\x11\x45\xf4\xc6\x41\x2b\xa9\x3a\x75\xea\x9f\x18\x14\xfe\x82\x00\x5e\x90\xc6\x0d\x47\xb3\x01\x0c\xbd\x5a\x71\xae\xd3\xfc\xf0\xb4\xfd\x92\x04\xa4\x67\x5b\x13\x3f\x60\x9a\x58\xce\x62\xa3\x9c\x79\x55\x60\x36\xb8\x2c\x9e\x74\x9d\x88\x1f\x26\x18\xc4\xaa\xdb\xa2\xac\xd5\x44\x4a\x45\x90\x20\xf0\xd1\xf1\x3e\xa4\xef\x70\x93\x96\xf5\xb4\x64\xb0\x20\x01\x91\xb6\xce\xdc\xe0\x72\xf0\xb4\xf7\x83\xe3\x70\x9a\x93\x40\x33\x1d\xb9\xd2\x99\x77\x9e\xcd\xae\x13\x72\x93\xb7\x0f\x6d\x29\xf8\x8f\xb3\x70\x79\x8d\xe6\x8f\x1a\xf1\x2b\x07\x5e\xf2\xbc\x86\xed\xa5\xaa\xe1\x68\xdd\xc0\x55\xfe\x9c\x43\x27\x66\x2d\x48\xc8\x63\x60\xb6\x5e\x3d\xad\x47\xcb\x8f\x84\x5c\xe9\x56\x5a\xc2\x01\x7e\x07\xc8\x7c\x41\x48\x12\x18\xe2\x64\x7c\xc5\x79\xd6\x47\x2b\xfd\xbd\x35\x48\x08\x08\x84\x03\xbd\xac\x9f\x7f\x9b\xb6\x15\x84\x11\x48\x4c\x3a\x19\x2a\x59\xa6\x56\x0a\x69\xe0\xd0\x13\x26\x62\xac\xbb\x3a\xe7\x23\x7e\xf3\xe1\xf8\x45\xa1\x21\xa4\x58\xca\xc2\xe4\xec\x3a\x2b\x96\x44\x84\x22\x8b\xf7\xa3\x13\xbe\x9d\x06\xa2\x0b\x12\x49\x81\xee\x68\x96\x6a\x5b\x9e\xb5\x4f\xd3\xf6\x2e\x20\x71\x27\x10\xe7\x72\x42\xc3\x57\x90\x58\x70\xc4\x07\x61\x56\xe8\xb5\x2c\x3e\x16\x69\x55\x7c\xe4\x4f\x45\x9f\x96\x59\x90\x58\x01\x13\x2d\x12\xb5\x57\x29\x8c\xc6\xdc\xc8\xc6\x21\x49\x68\x12\xee\x48\xe9\x84\x3e\xb4\xd9\x7c\x5c\x33\x18\xd5\xbc\x05\x64\xa7\xd7\x61\x51\xda\x75\xe0\x95\x08\x0a\xa8\x2d\x61\xbe\xef\x5f\x2f\x8f\x63\x00\xc3\x70\xca\x68\xa9\x30\x93\x7d\x07\x0e\x79\x39\x6a\x57\x09\x6b\xb5\xb0\xf7\xa7\x8e\x3b\x5a\x50\xcf\xa3\xd0\x0c\xe4\xbf\x36\x83\x13\x8a\x7a\x9c\x22\x2c\x42\x5b\x44\xfe\x73\xfe\xdb\xd9\x65\xaf\xf4\x3d\x0d\x4e\x45\xc8\x54\x9b\x5f\x15\xdb\x0a\xea\x4b\x62\x73\xc2\xd5\x02\x44\x99\x56\x83\x9d\xc3\x1a\x4b\x34\x08\xcd\x59\x63\x83\x84\xd3\x69\xcb\x21\x2c\x6c\xf4\x30\x61\xe8\x71\x6b\x68\x2f\xf3\x3a\xad\x6d\xb2\xd0\xb6\x12\x4f\x21\xca\xdd\xd4\x80\x34\xfb\xff\x97\x9c\x6d\xfd\xc7\x22\x3c\x41\x22\xb2\x8a\x6b\x98\x48\x37\x7d\xf1\x28\xd4\x0b\x42\x83\xc0\xe7\xf5\x2b\xb2\xf0\xbf\xfb\xb1\x7b\x12\x2a\x63\xc4\xc6\x56\xf2\x15\xd4\x39\xc3\xe4\xd6\x30\x6e\x46\x7a\xef\xd9\xc5\xec\xc9\x7f\xbb\x1b\x68\x86\x9f\xf8\x88\xe4\xed\x73\x4b\xe6\x34\x01\x63\x16\x94\x85\x60\xaa\x0d\x8a\x73\xb9\x2e\xea\x07\x14\xcf\x72\x0f\xc2\x88\x88\x9c\xb2\xee\x3e\xcd\x2b\x28\x6b\xab\xe7\xb0\xe3\x69\xd6\xf6\x8a\x3d\xe4\xff\x34\x06\xf9\xd5\x3c\x1e\xbd\x79\x44\x05\xbe\xb9\x61\x4e\x18\xc4\x67\x68\xec\x07\x9e\xee\x0a\xa4\xb6\x98\x44\x18\x09\x94\x0b\x1a\x07\xd4\x15\x9a\xed\xcd\x09\xba\xef\x41\x26\x5d\x27\x45\x58\xb7\x68\x7e\xa5\x6f\xe9\x6a\xb1\x7f\xea\x83\xa1\xfa\x5b\x1a\x8d\x95\x09\x73\xfe\xa3\x2d\xa1\x10\x34\x49\x04\x56\x7e\xcc\x9f\x9f\x1f\x6e\x76\xf3\xe5\x9f\xf3\xfb\xd9\xd3\xdd\xb2\x6d\xe6\xda\x1f\x9b\x23\x93\xde\x3b\xe5\x5e\x8c\xea\xbf\x98\x7f\x47\xed\xcf\xe1\xb3\x0a\x19\x80\xe1\xb2\x43\xca\x13\xf7\x03\x42\xb5\x3a\x0c\x2b\x05\xcd\x84\xbd\xd8\xb8\xfb\xf0\xf6\x02\x00\xd9\x28\xf6\x4d\xc7\xba\x2b\x2e\xb4\xcd\x32\x12\x68\x6c\x9c\xca\xf4\x3d\xcd\xe0\x00\xea\xca\x8f\x1b\x5d\x20\x23\x2c\x4f\x6e\x9c\x78\x47\xbf\xdf\xd5\xf1\x0b\xaa\xa8\x51\x40\x79\xe5\xd9\xbb\x81\x32\x95\xf5\x00\xdf\x67\xfb\x01\xf1\x3c\x53\x7a\x2e\xd3\x53\x63\xca\x57\x8f\xfc\x34\x3c\x26\x28\x34\x93\xac\x63\x91\x6f\xec\xd0\x7e\x05\xc7\x94\xa5\x41\x41\x8a\xd0\xe5\xf1\xf7\xf5\x47\xf1\xd3\x88\x55\xbf\xa4\x2d\xfb\xb0\xa0\x9a\x68\x57\x1a\xb2\xe7\x59\xb6\xe7\x75\xdd\x23\x25\x12\x54\x47\x01\x8b\x7a\xa5\x23\x46\x3b\x6a\xbb\xf8\xb5\x5c\xd9\x2e\xcc\x17\x86\x65\xec\xd0\x18\x83\xe7\x0a\xe6\x2e\x6f\x11\xbb\x0e\x32\x34\x27\x07\x26\xd1\x2f\x47\xe1\xe4\x49\x05\x0b\xa2\x38\xb2\xf8\x57\x9b\xa0\x76\x2d\x61\x20\xf1\xa3\xb6\x01\xdd\xad\x5d\xe4\x5f\x18\x65\x8c\xf8\x5a\xc8\xbe\x1a\xc7\xe8\xa4\x65\x24\x62\x58\x85\xf3\x90\xd6\x75\x66\x92\x5f\x70\x3e\x2e\x8a\xb3\x68\x75\xb4\x9b\x4e\x0a\xcb\xa6\x6e\x56\xbb\xd5\xdc\xfd\x91\x2a\x0f\xc9\xbc\x6c\x8e\xf5\xe6\x7c\xe9\xde\xf1\x6b\x96\x38\xc1\x58\xa8\x30\xa0\x31\xb7\x06\x07\x4f\x8f\x13\xe5\xdd\x82\x31\x69\xe0\x03\xf7\xbc\x7a\xbd\x39\x7f\x76\xa9\x0d\xc6\xc0\x8f\x74\x8f\x1f\x7c\x54\x50\x2d\x58\xec\x29\xac\x3e\xd9\x9e\x50\xd3\x0b\x79\x8e\xd7\x45\x71\xed\x78\x4e\x20\x3d\x04\x8b\x69\x88\xea\x43\xc0\xcb\xec\x22\xd2\x52\xed\x4f\x1d\xd3\x8d\xeb\xc3\x63\x6d\xa3\x32\xeb\xf4\x13\xb2\x79\x91\x5d\x3d\x45\x12\x33\x0f\xc3\xe0\xcb\x3f\x1f\x97\xdb\x7b\x77\x69\xa2\x04\x95\xce\x2b\xc6\x23\xe4\x1a\xab\xd1\xf8\x7a\x80\x61\x9d\xe2\x5c\x07\x8b\xb6\x54\x57\x30\xce\x34\x69\x96\x4f\xd9\x38\x4c\x2f\xa7\xd1\x4f\xf2\xc4\x47\x36\x1f\x94\x10\x9f\x17\x55\xdd\x5e\x06\x14\x3d\x94\xd9\xe3\xaa\x67\x24\x31\x11\x1a\x99\xaf\x53\x89\xd8\x61\x47\x0c\x22\x98\xf4\x4c\xd9\x19\x77\x20\xc6\xed\x59\xac\xae\x13\xcf\xc3\x5f\x97\xc4\x84\xa2\x6e\x52\xd5\xf8\x16\x3c\x03\x75\xc5\xaa\x35\x71\x08\x32\x49\x14\x22\x18\x67\x87\x32\x45\x3c\x9c\x65\xaa\x48\x8b\x7c\x64\xad\x32\x19\x71\x64\x01\x69\x53\x50\x58\xe6\xde\x57\x95\x1b\xa6\x86\x98\x94\xa6\x62\xe6\xa1\x38\x18\xe2\xac\xaf\x9e\xc8\xf6\x57\x51\x82\x1e\xab\xd1\x13\xbc\x69\xd3\x94\x4c\x45\x1c\x07\xbe\xd9\x64\x57\xe8\xa1\xa4\x45\xde\x8b\xc2\x8f\xaa\xd1\x05\x83\x88\x21\x01\x6a\x06\xef\x90\xa1\x5d\xdd\xdb\x06\x19\xc4\x11\xe9\x18\x41\xe7\xb3\x5d\x0f\x22\x36\xe9\x4b\x33\x4d\xb9\x63\xc5\xb7\x81\x4c\x74\x9a\x2d\xc3\x7c\xff\xde\x5a\xb3\xd8\xe6\x34\x57\xc7\x23\xd6\x5f\x77\x68\xd4\x49\xd6\x26\x11\x79\x81\x97\x98\x4a\x97\x9b\x4e\xa0\xff\x0f\xd7\x48\x89\x44\x66\xf1\xbd\xdd\x69\xbf\x8f\x4e\x47\x5e\x04\x89\x1c\x31\xfa\x60\xbc\x4e\xf5\x99\x11\x45\xe4\x49\x85\xf4\x22\x8a\x5f\x7a\xd2\xe7\xc3\x2f\x12\x79\xa0\xa8\x23\x08\xcf\x0f\x90\x2d\xae\x72\xf3\x91\xcf\x01\x9f\x0f\xea\xd7\x75\x59\x9c\xf8\xa1\x3b\xef\xa3\x30\xf4\xa4\x6c\x4d\xef\x3d\xb8\x3a\x26\x11\x85\x1c\xb4\xad\x0d\x47\xe2\xfa\x49\xe0\x4b\x14\xca\x00\x69\x11\x2c\x5d\x4f\x5b\x6b\x64\x9b\x09\x23\x18\xef\xfc\xf5\xa3\x6f\xf3\x46\x04\x28\x9a\xf0\xe2\x7c\xb9\x69\xab\xe4\xa7\xdf\x8f\xd2\x10\xcd\x63\xee\xc4\x8a\xfb\x9f\x67\xa2\x3b\x0f\x71\x57\x79\xe4\xf5\x68\x71\x44\x14\x78\x24\x5a\x58\xc1\x9a\x5f\xb8\xc8\x60\xc1\x2f\xed\x78\x33\x8f\x86\x9d\xff\x6f\x00\x14\x1b\x78\x4f\x3b\xfd\x8b\xc0\x1b\xbd\x3e\x8b\x3c\x0c\x32\x1e\x78\x75\x5b\x94\x7f\xf2\x33\x6a\xa3\x1a\x22\xfe\x59\x9f\xde\x49\x44\x8c\x4b\x0c\x00\x28\xde\x4e\x9c\x88\x1a\x8d\x84\x0f\xb4\x3c\xe2\xa4\xfd\x7b\x44\xfd\x68\x02\xd3\x5c\x75\x1d\x40\xba\x73\x8b\x7f\x1a\x59\xae\x6a\x6d\x65\xa2\x9c\x4e\x17\x94\xb6\x74\xd2\x5d\x24\x04\x4e\x03\x75\xc9\xf7\xf2\xca\xea\xb5\x9d\xe2\x44\x60\xec\x90\x1f\x4a\x30\xdb\xef\x95\x58\xbf\xed\xc9\x49\x08\x4e\x9f\x63\xf5\xa4\xd3\x7c\x5c\x3d\x28\x22\x1e\x05\x88\x2f\x94\xaf\x65\x5a\x55\x17\x39\x54\x05\x14\x91\x88\x7d\xb4\xdd\xb2\x22\x7d\x4b\xdf\x94\x73\x2b\x23\x19\x92\x50\x39\xe8\x1b\x6a\x42\xa8\xb9\x09\x74\x5a\x8c\xe8\xf0\x67\xa4\x34\x00\xb8\xc6\x0b\xdd\x8e\xc4\xee\x44\xa4\x08\xa3\xb4\xa3\x1d\xb3\xf2\x51\x65\x0e\x65\xd5\x91\x3c\x88\x48\x31\xc9\xe2\x36\xc8\x6d\xf9\x67\xa7\xcd\x86\xe6\xb8\xc7\xe8\xeb\x57\xeb\xdd\x75\x8b\x63\xcc\x42\x9d\xa0\x3c\xf2\x1c\xf2\x3a\xbb\x3c\x7f\xe4\x8f\x17\xac\x9b\xce\x87\x08\x62\x11\x41\x12\xe1\xd6\x9a\x56\xab\x5c\x66\x67\xf5\x85\x90\x83\x88\xbd\x88\x53\x53\x32\xff\xde\xd6\x16\xb9\xa6\xd8\xd0\x3c\x19\x28\xe0\x00\x5c\x27\x62\x8f\x7b\x98\xdf\x83\x5c\x75\xf4\x05\xce\xa8\x8b\x7d\x2f\x96\xcc\xfe\xfc\x35\x73\x84\xeb\x14\x7a\xb8\x75\x36\x13\x93\xf4\x3f\x65\xec\xb3\xc8\x4f\x5a\xfc\xe7\x2a\xef\x43\xba\x9b\xcf\x1c\x1a\x5a\x7f\x2c\x48\x93\xc5\x40\xc4\x73\x30\xb6\x71\xe0\xc5\x22\xea\x48\xcb\x5f\x2a\xc8\xa0\xaa\x46\x6b\x39\x0e\x7c\xe2\x77\x25\xc2\xeb\xac\xa8\x7f\xa6\x39\x5c\x7a\xaa\x36\xae\xa3\x4a\xc0\x68\x16\xe6\xc6\x6a\x1b\xb5\x87\x9e\x41\x76\x9f\xf3\x66\xcc\xf0\x95\x46\xb5\x36\x22\x0e\x7d\x19\x1a\x1c\x13\x1e\x29\xcb\x6b\x24\x4a\x1c\x12\x81\x0b\xd2\x84\x2f\x7b\xa7\x4d\x4c\x7c\x23\xe6\xd6\x6c\xaf\xcf\x5a\xcf\x79\x6e\x76\x87\x56\xf9\x74\xc7\xdf\x60\x56\x61\x20\xd3\x5d\xa2\x4c\x4c\xa2\x31\xfe\x6f\xd3\xea\xb5\x67\x92\xc4\xd4\xd7\x98\xff\x79\xe5\xd5\x4a\x16\xe6\x51\x6c\x13\xf3\xcd\x6a\x73\xd8\x4a\x27\x61\xe4\x9a\x2d\x0a\x72\x3e\x5b\x5f\x83\xf7\x45\x1c\x85\xbe\x21\x7e\x43\x69\xab\xe7\x53\x63\xb6\xa3\x22\x73\x3b\x0c\x11\xe5\x08\xf1\x6a\xae\xeb\x80\x97\x22\x4e\x7c\x89\xe1\xbd\xbf\x6e\xe6\x0f\xa9\xa5\x86\x68\xdb\x62\x53\x73\xb3\xc7\x18\xdb\x43\xc1\xf3\xd1\xa4\x4c\x38\x8d\xcd\x7e\x9d\xf3\x43\x3f\x64\x10\x27\x00\x4e\x45\xeb\xf1\x32\x7b\x87\x12\xb3\x77\xc6\x63\xea\x61\xc2\x62\xee\xc7\x49\xec\x20\x4a\xc5\xb0\xde\x58\xc4\x5c\x32\x66\x95\x5c\xd2\xf7\xaf\x22\xd4\xb1\x88\x42\x66\x9c\x44\x7b\x18\xd9\x60\xee\x34\x9c\x58\xc4\x22\x0e\xb0\x08\xd9\xa5\xd9\xf2\xcb\xba\x2c\x3e\xd3\x1e\x3b\xf6\xc4\xde\x1a\x0b\x4d\xb4\xdd\xd6\xf6\x1a\xbe\x8c\xf2\xd8\xde\xd2\x03\xf4\xd7\x0b\xad\x9b\x13\x75\x39\x96\x9b\x1a\xf5\xd6\x02\x91\x7f\xaf\xc5\x47\xf3\x38\xe8\xa9\xac\xf2\x5f\x90\xee\x8a\x1f\x69\x96\x8d\xd7\x8f\xa2\xcc\x95\x4b\x0d\xc9\xb9\x86\x77\x55\x51\xe4\x23\x5d\xa1\x70\x81\xf7\xe9\xf4\x41\xac\x92\x04\x97\xc8\xec\x33\x85\x05\x60\xc4\xbc\x55\xa9\x17\xb1\x02\x53\x61\x63\x11\x72\x38\x43\x6e\x79\x96\x09\x3e\x41\x0b\xd3\x1f\x31\x08\x29\xda\xb3\xdc\x70\x2a\xa2\x33\xda\x38\x34\x5f\x84\xe7\x62\x88\x12\xfc\x8e\xff\x58\xdf\x0d\xa6\x21\xc4\x02\xa5\x51\x8e\x85\x4a\xf5\x05\x63\x36\x57\x72\x3e\x22\x06\x10\x09\xb3\xeb\x6e\x70\x74\xc6\xda\x8f\x31\xe0\x61\x2c\x83\x95\xfa\x6c\x1b\x02\xf0\xac\xae\x06\x9a\x70\x67\x9b\xb5\x6f\x49\x86\x7b\x46\x64\xac\xb9\x81\x77\xf4\x48\x22\xd5\x78\xbf\xd2\x5c\x22\x8a\x66\x76\x55\xe2\xd3\x9f\xd6\x89\x17\x79\x26\x30\x56\x64\xa9\x4a\x6b\x3c\x52\xd2\x0c\x7e\x42\xd9\x69\x0e\x8a\x24\x60\x12\xd7\xf4\xea\x76\x3b\xa9\x1b\x2d\x92\x20\x91\x41\xd4\xf1\x02\xf6\xd6\x5f\x12\xf0\x00\x11\x5f\x7d\x8a\xd7\xe1\xc5\x61\x40\x11\x5b\xf7\x6e\x3e\x0b\x0c\x53\xf8\x83\xd3\x2d\x09\x69\xcc\xbd\x5e\xaa\xa0\xa3\x54\x31\x98\x62\xe8\xcb\x31\x75\x6e\x42\x12\xb2\x04\x81\x0d\xbc\xac\xd3\xaa\x46\x35\xad\xb6\x85\x4b\xa7\x7b\x7f\xeb\x9c\xdf\x84\xf8\x91\xb4\xc2\xfc\xbf\x29\xfa\x16\x09\xd1\x1a\x43\x81\xc8\xc7\x32\x24\xdc\x71\xe0\xbb\xc1\xa0\x53\x8f\x60\x6c\x6c\x9f\x56\x26\x7c\xdd\xef\x4c\x3c\xdb\x8b\x51\x83\x14\x5e\xfe\x5c\x3a\x24\x6c\xc2\x12\x63\xc9\x9b\x6d\x10\x5d\xe2\x99\x28\xde\xe1\x01\xf4\xc8\xaf\x4f\x22\xcf\x43\x58\xac\x93\xe8\xea\xe1\x69\x7a\x9d\x12\x81\x81\x8e\x0c\xf8\x5b\x4f\xba\x52\x24\x91\x64\x88\xa0\x71\x67\x58\x39\xe1\x63\x0e\x07\x21\xf1\x4d\x08\x5f\xa7\xb9\x5a\x1e\x4f\xf5\x65\x9b\x15\xf5\x20\x0d\x9a\x24\xc4\x13\xae\xfa\x93\x1f\x05\xaf\x2a\xae\x8a\xb2\xda\xbb\x1f\xe5\xa1\x46\xd7\xcb\x54\xcf\xf5\x80\x10\x09\x4f\x0c\x4b\xf8\x66\xb9\xed\xaf\xc7\x44\x24\x12\xed\x08\x7e\x3e\x1c\x5d\x02\xc2\xb5\xc9\x90\x60\xae\xcf\x86\xa2\x37\x4f\xa3\x77\x97\x24\xc2\x72\xaa\x2d\xcf\xe5\x6b\x3a\xba\x96\x46\x89\x43\x8c\xee\xff\xe2\x97\x55\xf5\xfc\x0e\xe5\x36\xfd\xac\x2f\xf6\xbc\x6d\x7b\x46\x04\x6d\xfd\x87\x97\xf9\x44\xe2\x22\x51\x5c\xe0\x06\xef\x84\xb4\x45\xa2\x84\x11\x91\xbe\x3d\x67\x3a\xcd\x32\xc4\x6f\x8d\x04\x46\xa7\x7d\xe6\x44\x49\x0f\xcd\xd3\x7a\x60\x5c\xdc\x96\xc5\x7f\xba\x07\x07\x2a\x9c\x7a\xf2\xac\x32\xf4\xe3\x93\x3b\x72\x02\x89\x17\x59\xcf\x09\x8d\xfd\xed\xf9\x74\xca\x2e\x8f\xad\x81\x90\xe8\x38\x52\xa1\x51\x0b\x38\x9f\xa6\xb7\xc9\x44\x73\x8a\xef\xb2\x6f\xd6\x8e\xcb\xac\x7f\xc5\x24\x28\xb8\x67\x0b\x24\x53\x59\x38\xf8\xcc\x43\xb3\x5f\x38\xdb\x91\x7b\x24\x46\xd8\x12\xaf\x2a\x28\xeb\x5b\x9e\x55\x60\x04\xaa\xfa\xcb\x87\x7b\x10\x80\xad\xc4\x1c\x58\x87\xdc\x0f\x7c\x34\x91\xb0\xbe\x17\x99\x32\xec\xc7\x1a\xe9\xdf\x0d\x87\x82\xfb\x60\x04\x66\x71\x5c\x6f\x7a\x47\xc9\x75\x9a\x87\x07\x9e\xf1\x34\x4c\x5d\xbf\x21\x85\xb8\xc6\x2e\xf1\x20\x00\xbf\x17\xd8\x2e\xca\x37\xf8\x56\xcb\x5e\xf0\x90\xc5\xb1\x67\x28\x0c\x65\x91\x2b\x1c\x97\x65\xeb\x44\xf3\x30\x4e\xfc\x2e\x7d\x88\xac\x12\xb7\x65\x71\xbc\x29\xae\x2c\x55\x1e\xca\xd8\xa8\xf0\xa6\xcb\x41\x82\x88\x87\xda\xec\x08\xb8\x4d\x75\xcc\xb2\xbb\x51\xa6\x87\x13\xe6\xe1\x0d\x5a\xf6\xa6\x11\x6f\x91\xe0\x24\x11\x98\x4c\xc8\x78\x85\xa0\x79\x50\x1d\xef\xfa\xe8\x5e\x9c\x22\x52\x96\xbb\x3d\xb4\xf7\x3c\x54\xfb\x08\x05\x3c\x16\x2a\xa0\xec\x8b\x8f\xc3\x08\x10\xaf\xcd\x8d\xf7\x83\x26\xd3\xe3\x18\x79\xc2\x59\x7b\xf5\xb5\x75\xca\xa3\x24\x26\xa6\x6c\xa3\x90\x50\x55\xae\xa0\xf5\xfb\x88\x1b\x8f\xb8\xc4\x40\x75\xb3\x71\x75\xb2\xc6\xdf\x25\x9e\x7e\x9b\x5c\xe2\x91\x92\xc0\x9d\x6f\xda\x4c\xa6\x1e\xc2\x85\xc7\xd2\x43\xfb\x03\x53\x0d\xa6\x5c\xfd\xca\x20\xec\x09\xb7\x0d\xd7\x47\x2c\x7d\x47\xd8\xd9\x9e\x58\x2f\x5f\xb1\x4c\x8a\x66\x6b\x45\xd8\xa2\x29\xdb\x48\xa5\x61\x5a\x1d\x29\x09\xfc\x9d\x34\xf5\x70\x73\xe0\x9c\x98\x12\x2d\x68\x0e\x03\xa3\x05\x9b\xe6\x87\x6a\x57\x18\x09\x67\xf7\xaa\x3c\x0a\xd1\x5f\xdc\xbb\x02\x43\x50\x69\x0d\x6a\x5d\xa4\xf9\x38\xd1\xce\x05\x4d\x10\xbe\xa0\x61\x22\x3f\x32\xfd\x76\x42\x1b\xb1\x94\xcd\x03\xca\xda\x4e\xda\x42\x3d\x3b\x81\x0b\xad\x71\x34\x5c\xe4\xd3\x72\xa3\x5d\x19\x2d\x5c\x2a\x1a\xf4\xf1\x7b\x7b\xae\x8e\x23\x22\x51\xc1\xa5\x36\x1a\x47\x1d\xe4\xa9\x59\x28\x53\x72\x9c\x82\x2b\x19\x61\x9d\xde\x81\xbf\x43\xf3\xdd\x47\xbf\x07\x1e\x45\x73\xc0\x86\x0a\x1a\xe3\xfc\x9b\x7d\x0a\x42\x8d\xf6\x98\xad\x20\x74\x15\x79\x00\x03\x83\xc3\x75\xa6\x1e\x38\x61\x95\x3b\xc8\xbd\xed\x09\xf9\xc0\xda\x4f\xa4\xa9\x88\x89\x83\x9f\xbd\xe4\xbd\x60\x14\xd7\x91\x8f\x6c\x8b\xe8\x90\x7f\x99\x00\x30\x9d\x85\x47\x3d\x4c\x7a\x5b\x79\x54\x83\xc0\x5d\xbf\x96\xbc\x82\xaa\xaf\x1e\x35\xbd\x62\x84\xc7\xe2\xb8\x75\xfe\x41\x35\x53\xda\x3d\xa2\xf0\x38\x68\x23\xd0\x59\xb5\x94\xac\xa6\x80\xf6\x11\x35\x88\xb7\xa9\xfa\x7a\xc1\x0e\x2c\x4c\xe1\x09\x33\x21\xd1\xc4\x4a\xf5\x9c\x9f\xee\x79\xb5\x01\x2e\x3b\x34\x9b\xf0\x79\x88\xdc\x3d\x1d\x4d\xfa\x0e\xf8\x17\xa8\x53\xe1\x83\x46\xb6\x25\x93\xe8\xed\xd4\xcd\x76\x25\xf0\xea\x3c\x86\xe7\x8a\xc0\x53\xda\x04\x50\x96\x9f\x46\xa0\xc5\xf2\x11\xf6\x17\xb9\x08\xa8\x42\x4c\x8b\x9b\x7e\xab\x7c\xc8\x69\x28\x44\xc0\x38\xf2\x05\x41\xfd\x8a\xd8\xd2\x61\x89\x83\x08\x3d\x0a\xda\x39\x91\x4d\x7b\x33\xc7\x51\x00\x62\x38\x3b\x10\xd3\xe8\xb8\xf5\x6e\xb0\x86\xf4\x9c\xd5\x63\x38\xb0\xeb\x1b\x1a\xbe\xf6\xa5\x29\x30\xed\xd5\xba\xb8\x0e\x84\x23\xa9\x9d\x78\xbf\x4e\x1f\x4e\x7a\x84\x22\xa4\x04\x1d\xef\xd7\x43\xfb\x66\xa1\x34\x64\xa2\x5c\x29\xb7\x81\xdf\xf3\xea\xb5\xec\x53\x18\x0e\xc7\x94\x84\xc0\x3a\x8a\xb2\x97\xbc\x2a\x32\xb5\xe5\x1a\xfe\x7c\xe0\x65\x9b\x6d\x12\x84\x24\xe8\x87\xdc\xde\xac\xda\x3f\x45\x4c\xdb\x34\xf6\xcc\xc9\x83\xf5\xc9\x40\x85\x20\x92\x60\x09\x4d\x3e\x3b\xab\xb4\x71\x29\x67\x19\x2f\x8f\xae\x95\xd2\x00\x91\x7f\xa6\x60\x7f\xc3\xb5\xce\x1c\xdb\xde\xf0\x35\x29\x18\x25\xe3\x79\xf1\x21\x0a\xe7\xf0\x0a\xc6\x09\xce\xc5\x73\x5e\x8c\x66\x09\xd3\x12\x87\xe5\xa1\x70\x91\x92\xdf\x42\x82\x44\xc4\x15\xda\xdf\xaf\xe7\x03\xf4\x23\x67\x37\x9d\xa2\xa8\x10\x31\x63\xd2\x37\xc8\x94\x9b\xa2\xa8\xea\x21\xbe\x4e\xc4\x92\x80\xc3\xf0\x9e\x1d\x5a\xc1\xb6\x25\x8c\x4b\x0b\x00\xc6\x88\xf5\x3d\x6a\x6a\xba\x2b\x93\xd8\x68\x7e\x08\xe7\x41\xba\xbf\xcb\x08\x8b\x43\x6b\x13\x17\xe8\xf6\xe2\xc6\xe2\x75\x62\x08\x28\x62\x29\x9b\x63\x77\x2a\xbb\x2e\xb8\x67\x28\x38\x79\x5d\x73\xf9\x86\x0f\x5c\x5e\xfa\x89\x17\x21\x42\x8e\xeb\xc5\x02\x4b\xd3\xfa\x32\xc4\xd8\x0a\xc1\x13\x04\x95\x9a\x0c\xca\xb2\xaa\xf9\x78\x0b\x16\x42\x45\x88\x35\x68\xcc\xdd\xa7\xe2\xc3\x6b\x2f\x85\x44\xb7\x1b\xd3\x1d\x3f\xc2\x48\x17\x7b\x7a\x3b\x93\xbe\x87\xeb\xb3\x2d\xda\x75\x94\x20\xee\xb6\x32\x0c\x31\xf9\xf9\xde\x63\x2d\xec\x8d\x8e\xa4\xd2\x40\x5a\x79\x26\x6d\xce\x6d\xf8\xb8\x32\xf6\x71\xd2\xbf\xec\xe6\x93\x33\x64\x2a\x2b\x2b\x54\xa8\xfd\xa4\xb5\xb7\x1e\x78\x55\x6f\x78\x1b\x65\x13\x3a\x08\x91\xff\xc1\xd4\x38\x1b\xac\x90\x39\xce\x5f\xd3\xd3\xdf\xa0\xe4\x11\x42\x13\x8e\x59\x5f\x89\xa4\x87\xa3\x03\x5e\x68\xe1\x21\xb3\x29\x9e\x34\x5d\xce\xbf\xab\xa6\x13\x5a\x70\x70\x82\x7b\xdb\x97\xf5\xfa\xe1\xaf\xfd\xcb\x76\xfd\x64\x9b\xa5\x47\x18\xee\x6a\x73\x43\x78\x30\x29\x3d\x3b\x49\xe3\x2a\xa4\x07\x46\x05\xbc\x82\x7a\x91\x96\x20\xeb\x05\x88\xb4\x3f\x1f\xa5\xa7\x75\xe0\x39\x7e\xa7\xe5\xe7\xa9\x28\xeb\x5b\xf8\x62\xcb\x91\x7e\xe0\x49\x03\x85\xfe\x99\xc2\x87\x7b\x3e\x9f\x70\x0c\xdd\xd8\x53\x60\x6f\xdc\x2e\xd7\x1a\xf8\x02\x17\xb5\x10\x33\x53\xc6\x39\x28\xe1\x94\x01\x35\xb4\xaa\xcd\xc9\x37\xef\x61\x0d\x87\x83\x28\x03\xaa\xd0\xe7\x9c\x65\xfc\xbd\x5d\x66\x32\x64\xa1\x36\xd9\x4a\xd4\x61\x72\x26\x41\xf7\xf5\x86\x37\x09\x19\x78\xc4\xe1\xb5\xd3\x77\x5e\x23\xd8\xe7\x9a\x93\x53\x48\x92\x18\x6e\x9b\x53\xd6\x29\x15\x8d\xc6\x82\x08\xb0\x05\xbc\x77\x59\x21\x78\xd6\x4b\x35\x48\xa2\x18\x67\xae\x5c\xda\x8c\x8a\x5f\x68\x57\xee\x25\x69\x1c\xe3\x57\xb1\xbb\xc6\xad\x49\x0f\xb9\x46\xae\x7d\x47\x47\xd2\xac\xb8\xbe\xc5\x3a\x38\x98\x24\x0b\x14\x66\xc8\x66\x0f\xae\x12\x49\xb2\x44\x38\xcc\x06\xfa\x8a\x37\x97\x01\xc6\x57\x32\xee\x21\xef\x6c\xda\x58\x14\x45\x99\x2a\xae\x96\x19\xc8\xba\x28\x5b\xbc\xb9\x64\x9c\xa3\xeb\x58\x1c\xf3\x74\xd7\x95\x5c\xbb\xe6\x88\x98\xfc\x8e\x63\x04\x32\x42\x44\xae\x91\x59\xba\x04\xa8\xea\x7d\x73\x0a\x17\x3d\x28\xa3\x8c\x22\x8a\xc5\x14\x77\x9f\x48\x0c\x39\xfa\x3a\x71\x48\xf1\xd0\x31\x29\x80\xb9\x93\x97\xf8\xde\x16\x96\x31\x23\x98\x7c\x7e\x82\x8f\xdd\x8f\x87\xa7\x89\xe8\xbd\x8c\x13\x0e\xd1\x18\xbe\xfd\x34\x7b\x5c\x4e\x82\xa6\x64\xe2\x33\xdc\x11\x0b\xad\x91\x8e\xd5\x81\x9b\x47\xbd\x48\x8c\xf3\xd6\xd4\x04\x98\xf2\x7a\xd4\x0a\xeb\x8e\xa0\x76\xc8\x12\x45\x04\x92\x7c\xa5\x90\x55\xb0\x84\x5c\x95\x5c\xbe\xd6\xf3\xe2\x28\x30\x6d\xdf\x0e\x5f\x02\xc2\xf0\x74\x37\x63\xb7\x2d\x74\xbd\x57\x36\x67\xdc\x41\xf3\x87\xaf\xcf\x43\x53\xa9\xf8\x0a\xbc\xac\x05\xf0\x51\x95\x85\xe4\xda\x58\xd8\x68\xf8\x8d\x69\x47\xff\xcb\x44\xb2\xc6\x8e\xc3\x04\xe6\xda\x9e\x38\x52\xfa\x86\xca\xa1\xc5\x76\xb4\xe2\x36\x93\xc1\x14\x29\x13\x69\xc5\xb8\x72\x75\xc3\x6d\x0e\xa9\x1d\x17\x15\x69\xae\x5a\xb5\xb7\xa2\x54\xb3\xfa\x5a\x96\x4f\x48\x25\x0d\xe3\xc1\xde\xca\xe5\xcf\xfe\x0e\x90\x40\x2a\x6d\x4a\x2e\x2b\xa8\x97\xa7\x42\xbe\xb6\xc6\xb8\xa5\x62\xb6\xff\x74\x3f\x03\x21\x63\xc6\x92\xcf\xf1\xa4\x1f\x95\x00\x4a\x88\x13\x4c\x63\x59\xe5\x72\x13\x04\xef\x25\x5b\x94\x1f\x6a\xcf\x92\xfc\x14\xef\x2d\x99\x3f\x86\x34\xcc\x42\x47\x51\xde\xab\xa2\xb3\xf1\xff\xf7\xa2\x3f\xca\xe7\x51\xe8\xb7\x9a\xa7\x0e\x8c\x37\x55\x62\xa4\x02\x9f\x49\x36\x64\x49\xe8\xb1\xc4\x0b\x15\xd0\x04\xf3\xc6\x7f\xea\xc6\xe3\x87\x97\x3a\xed\xd8\xad\x85\x0a\x58\xc2\x12\x8b\xac\xca\x21\x7b\x9a\x28\x2c\x9d\x5c\x7f\x2a\x10\x60\xa1\xad\xce\x3e\x54\x21\x0d\x84\x59\x6f\xcd\xee\xe9\x24\xd5\xbf\x8b\x2c\xf8\x6c\x50\xa7\x74\x45\x2f\xd7\xcb\x17\xb4\x35\x4c\x2a\x8c\x12\xe4\xd0\xb7\xeb\x73\x6d\xa2\x1f\x13\x14\x17\xc3\x07\x0e\xb9\x44\xd3\x1f\xa5\xd7\x66\x65\xc9\x2f\x9d\x40\xba\xed\x42\x43\x86\xa4\x05\x3b\x9e\x5e\xce\x3c\xef\xa5\x18\x15\x0b\x0d\x0f\x8e\x85\x74\x0c\x03\xa7\x8a\x49\x0f\x88\x23\x64\x3a\x98\x05\x7b\x5f\x8c\x63\xeb\x2a\xf2\x42\x87\x4d\xb6\x33\x03\x4b\x0d\xc6\xbd\xa4\x87\xe5\x29\xbc\x3c\x5e\x16\x65\x91\x83\xa5\xac\x19\x3e\x6b\x24\x63\x44\x4e\x08\x90\xc5\x11\x6e\x79\x26\x8b\xfc\xc8\x9b\x6d\xce\x3d\x54\x4c\x25\x8e\xd3\xc3\xbf\x1e\x70\xf9\x0d\x7d\x26\x95\x50\x6e\xc9\x3b\x10\xf9\x31\x11\xa2\x50\x49\x24\xf1\x1b\x83\x4a\xeb\x47\x38\xc2\x58\x6c\x7d\x38\x11\x13\x88\x0d\x85\xf4\xee\x79\xbf\xbd\x9f\x39\xe6\x24\xa1\x12\x4d\xb0\x00\xfd\xa6\x39\x1c\x1a\x67\x0a\x0b\xa1\xf6\xad\x66\x81\xed\x26\x22\x9e\x58\x8b\x64\xae\xae\xd9\x34\x94\xe0\x26\xfe\x80\xa1\xb0\xc7\x34\xc7\x13\xd6\x5d\x2c\x3d\x1f\x83\x94\xeb\x92\x5f\xc8\xba\x6c\x8f\x55\x25\x83\x04\x0b\xeb\x1d\x2a\x00\xd4\xd0\xe8\xfe\x62\x7a\x4b\xe6\xa9\x3e\xd3\xf7\xcd\x65\xcc\xc4\xa0\x80\xb2\xc0\x66\x55\x9e\xce\xff\xe6\xa3\xb1\x83\x48\x9b\xf8\x00\xff\x9c\x9d\x20\xdf\x42\xe6\x0e\x5a\x05\x71\x60\x4b\x7f\xdb\xea\xaa\xab\x6d\x4c\x81\x36\x34\x98\x07\x7e\xb4\x38\x3b\x03\xd2\x68\x89\x74\x94\x4e\x14\xc6\xfc\x1f\x67\x4f\xf7\xb3\xdd\x6e\xf6\xb4\xde\x3c\xff\xf9\x17\xdd\xdd\x3b\x5e\x73\xd1\x18\x81\x68\x53\x64\xbc\xb1\x47\xde\xc7\x02\x11\x02\xfc\x20\xc0\x0a\xb1\xb4\xda\xca\xd7\xa2\xc8\x6c\x0a\x6e\xf8\xa6\xe0\x43\x44\x22\x1b\x32\x1c\x5a\x05\x10\x30\xa6\x78\x4f\x11\x00\x4a\xab\x2e\xf4\x9e\x16\xe7\x0a\x37\xe0\xd1\x4f\x06\x09\xc3\x02\x21\x9d\x66\x47\xde\xf7\x3e\x21\x50\x14\x55\x51\x1a\xa3\xb5\x2c\x4e\xb6\xdc\xbc\x77\x0c\x41\x18\x8a\xd0\x16\x76\x6f\x1b\x3f\x4f\x16\xe9\x98\x79\x04\x42\xe2\x7b\x46\xde\x49\xeb\xc7\x22\xaf\x5f\xbf\xc8\x1a\x00\x91\xa6\x7e\xda\x56\x36\xe5\x87\x49\x0c\x1d\x10\x50\x08\x95\xd1\xe9\xe7\x9a\x5f\x66\xc7\xf6\x71\xa9\xa0\x1c\x5a\xbd\x4c\x63\x66\x3f\x16\xca\x46\xf9\x87\x37\x61\x31\x41\x44\x45\x61\x4a\x57\x6c\xaa\xef\x32\x7a\x74\xa6\x4c\x76\xb1\x8b\xc4\x5c\x95\xd1\x0f\x0e\x8d\x9e\x07\x05\xb1\x67\x58\xf0\x74\x51\xca\x36\xc8\xed\x6e\x1c\x87\x34\x80\x01\xf4\xb4\x37\xec\x31\x0b\x31\xa7\xde\x4c\x92\xfb\xa2\x5e\x17\x35\xaf\x0b\x53\x8d\xd6\x76\xd1\xb1\x01\x0c\x14\xf9\xc8\x40\x87\x84\x09\x4c\x95\xcd\x66\xb3\x69\xe7\x01\x78\xe4\x63\x7c\x69\xf7\x0a\xcf\xf9\x00\x09\x01\xc2\xa6\x16\x8e\x69\xde\x7c\xed\x35\x94\xdb\xb3\xa8\x64\xfb\xbb\x52\xaa\xc8\x6b\xd9\x31\x9d\x99\xef\x98\xac\x86\x0f\x22\x15\x25\xdc\x62\x64\x96\xa5\x0c\x9c\x47\x0b\x10\x1a\x52\x61\x83\x4b\xd8\x56\xa7\x59\xae\xe6\x4e\xa7\xf1\x0b\x74\x6f\x17\x8c\x9c\x08\x4b\x8e\x58\x4d\x7b\x95\x11\x5d\x09\x39\x40\xcc\x30\x7a\x84\x4b\xef\xc8\x0f\xb0\x52\xed\x03\x89\xc4\xd2\x06\x6c\x8a\x31\xf6\x06\x74\x90\x68\x03\x88\xad\x6b\x18\xe8\x10\x0a\xed\xc5\x26\x91\x79\xe2\x97\x2e\xd1\x31\x1c\x6d\xed\xf1\x58\x77\xd5\x0e\xcd\x64\x1b\xd8\x5e\xda\x93\xca\x29\x69\xee\x78\xe9\xa2\x1b\x7f\x8c\x6e\x02\x9e\xa3\x76\x7c\x28\xea\x1a\xca\xcb\x02\x6a\x9e\x66\xd5\xcd\x1f\x83\x7e\x3e\x23\x31\xef\xe1\xc3\xf8\x35\xb9\xe1\x70\x21\x68\x9f\x33\x8c\xe5\x42\x3d\x7c\x35\x5f\x72\xd4\x83\xde\xf5\xb5\x1a\x7f\x57\xda\xa1\x03\x3f\xd0\xf6\x40\x9d\x4f\xb3\x3f\xe9\xc0\xe7\xa6\x34\xce\x30\xbc\x81\x8d\x5e\x23\xc0\xbe\x1d\x94\xc0\xe7\x22\xb6\x6a\x5a\xeb\x9b\xdd\x6e\x76\xe0\x69\x5e\xd5\x13\x65\x80\x3a\x60\x3e\x62\x73\x5a\x75\x8e\x9f\xa8\xa8\x66\x07\x79\x90\xc8\xf8\x5f\xe5\x50\x74\x20\x8c\x20\x01\x2f\x45\x5a\x5f\x45\x13\x74\xa8\x13\xc3\x56\xd9\x9c\x07\x66\x01\xac\xcb\xf4\xd8\x21\x6e\x35\x09\x23\xac\xeb\x73\xbb\x47\x63\xbe\x34\xde\xf5\xae\x18\x24\x4c\xa6\xa7\x0d\x89\xa4\x21\xcf\x41\x0c\x73\x73\x5a\x61\x01\xfe\xdf\xcd\x99\xd8\xbb\xd0\x48\xa2\xb7\xbe\x47\x55\xfc\xc5\x79\x34\xb9\x35\x15\x1e\x11\x5d\xc6\xca\x21\x97\xda\xef\x40\x05\x55\x6c\xc0\xfd\x66\x0e\xeb\xe1\x14\x66\x3a\x60\xe0\xe4\x6e\xd3\xbc\x86\xbc\x79\xe8\x76\xeb\xb5\xbd\xa2\xc4\xb0\x96\x23\xcb\xf0\x6c\x84\xdc\x1c\x61\xf8\x74\x12\xb0\xa4\x43\x62\x34\xd6\x61\x7e\xc0\x14\xc3\xe8\xeb\x27\x49\x80\xb6\xd9\x5d\x51\xa8\x1f\xbc\x3c\xf2\xdf\x47\x2a\x75\xa2\x3c\x2c\x97\x40\x9e\xee\x0d\xcf\xdf\x6e\x8b\xf2\xb6\x33\xd0\x35\x67\x80\x3b\x68\xf3\x65\xb7\xaf\xc5\x39\x53\x1b\xa8\x7a\xb1\x33\xcd\xb9\x4a\x6c\x88\x18\x59\xfa\x06\xaf\x60\xfb\x20\xd9\x98\x81\x9d\x9c\x87\x4a\xf8\x42\x0b\xf0\x92\x56\x21\xa1\x28\x37\xf0\x6f\x90\xb5\x55\x6f\xbc\x3d\xe7\x5d\xf6\x69\xf8\xae\x42\x83\x61\x58\x3e\x97\x7d\x53\x58\x43\x42\xd1\x0e\x6b\xb5\x43\x7f\x93\x3b\x6c\x2f\x8b\x70\x1b\x5e\xdd\x3c\xae\xb6\xcf\xb7\xce\x46\xd1\xba\xad\x66\x6f\xb6\x67\xc3\x34\xf3\xaf\xc6\x43\x1e\x26\x09\xb4\x4e\x22\x14\x90\x93\x3c\xdf\x01\x3f\xfe\x00\x38\xf5\xb8\x0b\x06\xcf\x2e\x3d\xcf\x0f\x50\x5b\xe5\x5f\x69\x7a\xea\xed\x33\xd2\xf3\x62\x1f\x63\xe0\x27\xa8\xe7\xbc\x54\x5b\x28\xd3\xc6\xbe\x36\x94\x0c\x76\xf3\x88\x6d\x5f\x3f\x62\xc8\xd8\xd8\x7c\x8c\xae\x6c\xe2\xdb\x25\x20\xbd\xc0\x8b\xa4\x21\x63\xb4\x74\x24\xcd\xe0\xca\x62\x62\x2d\xb9\x0b\x88\x76\x3a\xfe\x4f\xc5\x47\x97\x7b\x76\xcd\x11\xa8\xc4\x49\xe1\x78\x7e\x2f\xa8\x2a\xbd\xe6\xf4\xec\x25\xa4\x4d\x2a\xae\x87\xaf\x96\x5e\xa8\x18\x06\xca\x1c\x8d\xc2\x6d\x86\x55\xa1\xdf\xed\x05\xd2\xa3\xbe\x22\x06\x92\x05\x6a\xcb\x33\x18\xd2\x1f\x48\x8f\x06\x24\x72\xe0\x42\x04\x59\x87\x8b\xb1\x9d\xe2\x7a\x0a\x8e\x96\x3f\x97\x12\x53\xa1\x4e\x68\x7b\x32\x6a\x20\x3d\x2a\xb9\x11\x7c\x85\xaa\x76\x5c\xc8\x55\xdd\xe9\x88\x48\x8f\x51\xc3\x08\xfd\x50\x1c\x70\x73\x9e\x00\x28\x8d\xfc\x12\xe9\x31\x25\x3c\x43\x03\xf3\x88\x49\xab\x5d\xbf\x6a\xf0\x8b\x21\x60\x20\xd0\x6b\x58\xdd\xed\x36\x8f\x37\xee\xd7\x23\x3f\x70\x16\xdf\x4c\x5d\x61\x88\x5c\xa7\x30\xc0\xc0\x94\x4d\xcf\x54\xd7\x60\x09\xb7\xf9\x04\x9d\x4d\x11\x8f\x38\xf1\xff\x5f\xf0\xdf\xee\x76\x71\x84\x49\x26\x4c\xb9\x3a\xb1\x07\x5e\x03\x71\x0f\x15\x73\x53\x34\x78\xb3\xda\x0d\x66\x7a\x12\x0b\x19\xf6\x42\x82\xce\x65\x1d\xbe\x28\x8f\x4d\x74\x00\x59\x59\xa6\xe4\x99\xa5\xc7\x45\x24\x9c\x9d\x9b\x2a\x8c\x4b\x9e\x11\xdb\x35\x1a\x33\x11\x10\xcc\xac\x42\xce\x45\x66\xc9\xf7\x9e\xf5\xf6\xe5\x8f\xc1\xd7\x10\x34\x46\xf5\x81\x5f\xcf\x9b\x87\x85\xdf\xed\x2b\xd2\x13\xb1\xc2\x85\xf0\xe4\xf6\x06\xe9\x49\xdf\xb8\xfa\xff\x29\x65\x71\xad\x8f\x74\xb5\xd7\x4a\x4f\x4a\xcf\x3d\x2b\x2e\x3f\xde\x9b\x6c\xb6\x8b\xf2\x02\xbf\xcb\x8d\xac\xaa\xea\x1a\xe8\x39\x19\x59\x92\x1e\x04\x1c\xd9\xba\xb6\x46\xac\xea\xaa\xa8\x44\x7a\xa0\x45\x2c\x5a\x7b\xd5\x1d\xd3\xd7\xba\xc7\x83\x67\xd6\x4c\x84\x2e\x2d\x97\x65\xae\xe4\xce\x35\xc6\x31\x9e\x98\xdb\x2c\x55\x20\xd2\xba\xda\xb5\x3a\x28\xd7\xc1\x20\xe9\x69\x21\x31\x6e\x54\x61\xba\xd8\x6d\xec\x18\x5f\xff\xdb\x10\x8f\xeb\xe3\x45\x7a\x5a\x7b\xb8\xe7\xb7\xc2\xd5\x78\x20\xef\x8a\xc6\x9b\x2f\x8b\x6c\xc8\x1c\x23\x7d\xcf\x8b\x5d\xc1\xec\x03\xaf\xea\x5d\x7a\x42\x64\xe9\x54\x38\x5b\xfa\x5e\xac\x71\xde\xbc\xdc\xf4\xe7\xaf\xef\x81\xe7\x41\x4b\x72\x7d\x03\xf5\x6d\x51\xa2\x42\x43\xfa\x9f\xd1\xb0\xfb\x3e\x03\xab\x00\x57\x9d\xec\xd1\x96\x96\x8d\x4d\xb6\x01\x59\x9e\x5d\x90\x40\xfa\x3e\xe8\x38\xb2\xb6\xdb\xcb\x76\xf9\x6d\x8a\x5e\xfa\x41\x6c\x8a\xa2\x1b\x63\x64\x76\x68\xa3\x3d\xd2\x0f\x12\x89\xe4\xd7\xef\x45\x0d\x7f\xae\xd4\xa0\x9a\xcb\x75\x11\x0c\x5d\xfc\xfd\x2b\xcf\x15\x66\x49\x27\x9d\x50\xe9\x07\xda\xe7\x96\x4d\xa7\x39\xff\x25\x6f\x35\x5a\xbe\x48\x3d\xfd\xed\x7f\x27\xb7\x58\x3f\x0c\x34\x56\xfb\xc9\xb2\xa8\xaa\xdb\xa2\x7c\xc3\xe3\xa2\xcf\xec\x26\xfd\x90\x70\xa4\x1d\x31\x36\x3f\x28\x54\xad\x6f\x1b\x85\x91\x20\x78\xbe\x20\xa3\xf2\x6b\x1b\xd7\x90\x7e\x08\xca\x55\x8b\xac\xd6\x77\xfd\xb2\xfb\xd1\x43\xd0\x90\x1a\x79\x02\xc4\x3c\x97\xc5\xd1\xdd\x81\x46\x0a\x5d\xc5\x7d\x75\xc9\xeb\x57\xa8\xd2\xff\xa0\x2b\xfb\xc5\xd8\xd1\x84\xea\xa0\x13\x8f\x3b\x9f\xa6\x4f\x21\x9f\xf9\x46\x7c\xea\x06\x6a\xf8\x1c\x66\x0f\x87\x37\x64\xa1\x46\x37\xe0\x78\x79\x28\xde\xcd\x41\xea\x16\xa2\x1f\x79\x01\x62\x23\x31\x6d\x52\x16\x39\x9c\x8f\x77\x45\xa6\xda\x66\xdf\x8a\xb1\x3a\xc9\xdf\xaf\x38\xcd\xbb\x28\xaf\xf4\xa3\x90\x22\xc7\x1e\x82\xd3\x1c\x4a\xc9\xb5\x29\x89\x35\x5b\x33\xa5\x6e\xd3\xca\x1d\x80\x7e\x1c\x0a\x22\xda\xda\xc4\x2f\xc6\x37\xe6\x46\x22\x5c\x81\x2d\x89\x1c\x78\x53\xa3\x97\x4e\x48\x80\x29\xaf\xc6\xcc\x6b\x36\x6e\x23\x6c\x37\xa1\x4d\xea\xfa\x37\x67\x0b\x52\x33\x64\x99\xc9\xf8\x19\x14\x4d\x6b\x1f\xf8\x09\xf8\xda\x78\xed\xa7\x8c\x4b\x58\x35\x9f\x38\x77\x06\xe7\x17\x77\xe5\x21\x35\x8c\x43\xcb\xf9\x5f\xf3\x87\xe5\x7e\xb7\x7a\x5c\xba\xfb\x71\x02\x18\x36\xdd\xae\x76\xee\x04\xbc\x36\x61\x86\x23\x20\x18\xd7\x36\xe0\x71\x57\xf2\xbc\xee\x05\x3c\xa4\x2f\x62\x1f\x33\x04\xc5\x09\x72\x44\x7a\x36\x46\x70\x33\xf4\x53\xde\x9b\xbd\x46\x7a\x14\xc1\xf2\x07\x7e\x5a\xe5\xd6\xf1\x6a\x51\xa2\xb3\x5c\x19\xe6\x80\xfe\x1f\xdd\xaf\xc9\x28\xc6\x64\xfd\xee\x71\xb9\x68\xfe\x5e\x0d\x76\x39\xa0\x46\xb2\xa6\x0d\xf9\x40\x07\x3b\x1c\x3d\x82\x4e\x14\x6d\x69\x34\x6e\x01\x5a\x7c\xab\x0c\x3c\x62\x10\xeb\x8f\x69\x0e\xe5\x9f\xee\xaf\x3e\x07\x5c\x4d\x86\x7d\x6a\xfb\xca\x4b\x78\xc5\xb0\x4e\x85\xe1\x6f\x4b\x5b\xeb\x3a\xcb\xc8\x99\xa1\x86\xaa\xfe\x5a\x90\x4b\x06\x41\x10\x22\x76\xfe\x84\x68\xa7\x6a\x22\x68\x2c\x83\x90\x49\x14\x84\xb5\x2c\x5c\x48\x0f\x66\x7e\xb6\xc7\x61\x32\xba\x6f\xa8\x7c\x29\xba\x44\x3d\xbc\xc3\xe8\x44\x09\x08\x23\x68\x1a\xa2\x63\xb4\x9a\x3f\x77\xd5\x44\x32\x20\xc2\xcc\xe0\x66\x3f\x56\x7f\x39\xaf\x5e\x06\x44\x69\xe1\x21\x3a\x39\xbf\x46\xd8\x4d\x00\x06\x64\x40\x55\x92\xd8\x22\xfd\x0d\x2f\xd3\xfa\x32\xa8\x03\x71\x9d\x74\x80\x1f\xf4\xae\x78\x87\x32\xef\xaa\x03\x64\xc0\xfc\x04\xd9\x4e\xff\xe7\x0c\xe5\x65\x60\xf6\x04\x2c\x08\x98\x61\x14\xfc\x55\x94\x6f\xb7\x3c\xcd\xb6\x75\x9b\x42\x92\x01\xa3\x01\x7a\xf7\x4f\xfc\x08\x03\x01\x9d\xc9\xd9\x18\xb0\x48\x60\xaa\x76\x5e\x5e\x4e\xc8\x9a\xe7\xee\x13\x7b\x9a\xf4\xa3\x1d\xfb\x12\xfd\xa9\xa9\x80\xbd\x0c\x62\xa5\x10\x1d\xa3\x53\x5e\xaf\xc1\x28\xbe\xbf\xb4\x31\x75\x19\x24\x81\x51\x15\x3c\x40\x7d\xbf\x7b\x98\x7f\x2f\x43\x6a\xb7\xbb\xc1\x63\x26\xd2\x54\xaa\xcc\x0e\x65\x01\x86\xc9\xae\x3f\xf9\x83\x04\xe2\x84\x5b\xac\x9e\xd9\x44\x9a\xcf\x7a\xc3\xeb\x2e\x68\x3c\x88\xbb\x0d\x07\x41\x78\x1e\xa2\x1b\xb7\x77\xf3\x87\x3f\xda\xbf\x45\x58\xc2\x83\xce\x41\xbb\x10\x84\xef\x63\xa5\x01\x6f\xa6\xfd\xf6\xdc\x0e\x87\x75\xff\x65\x20\x98\xc7\x78\xbf\xd4\x69\x2a\xc4\x28\x03\x11\x2b\x2c\x26\xc3\x89\x76\x3b\x60\x19\xb2\x3d\xa4\x36\xac\xc2\x9b\xe7\x87\xf9\xe0\x55\x55\x10\x22\xc2\x72\x5d\x54\xf5\xaa\x7d\x5c\x15\x1b\x12\xa8\x73\x05\xeb\xec\x7c\x48\xf3\xae\x2a\xc3\xf5\xe0\x11\xe7\xfd\x9a\xa4\xc9\x79\xab\x84\x61\xec\x36\xb4\x7e\x7f\x4e\x6f\x20\x01\x78\xb1\x0d\xf6\xdb\x02\xf0\xbb\x82\x67\x03\x30\xa0\x0c\x40\xf8\x32\x1e\x44\x60\x06\x41\xb0\xf1\x1d\xb5\xc4\x04\xf7\xbb\xbb\x5c\x6b\x21\xc2\xd6\xf9\xe9\x92\xa4\x32\xf4\x98\x11\x48\xb0\x60\xf3\x0e\x3c\x20\x43\x3f\x14\x86\x19\xf2\x7c\x41\x4c\xc6\x54\x36\x58\x86\x7e\x12\x21\xc5\xf1\xb6\xc8\xe6\xd9\x59\xb8\x8b\x03\x2f\xa6\x61\x47\x29\xd1\xd5\xe0\xc9\x30\xf4\x05\x06\x5e\x8c\xa6\xe6\x02\x32\xee\x02\xee\x1b\xa8\x8a\xec\xbd\xb5\x78\xc2\x30\x32\xfc\x95\xb8\x9e\x8a\x05\x1c\xda\xf0\x4c\xd3\x66\xd8\x29\xe7\xd9\x59\xbe\xf5\xfc\x95\x30\x8c\x5b\x6f\x70\x25\x0d\xc5\x70\xdf\x41\x1b\x3d\x7e\x08\x42\x0f\x36\xfa\xe2\x5b\xd4\xab\x0c\x09\x33\x65\xab\xb3\x39\xa2\x11\xfa\xb3\x29\x24\x11\x0d\x4c\x64\xa2\xc4\xc4\xd0\xb6\xa5\x9f\x74\x1d\xc0\x8c\x0a\x06\x46\x8f\x22\x6d\x9c\x81\xc6\xc8\xb8\x5f\xb7\x5f\x72\xf0\x74\x34\x8c\xf1\x48\xe4\x4a\xa1\x7b\x6c\xd2\xf2\xbf\x25\xf4\x9a\x3c\x7c\x43\x9a\x18\x7c\x8a\xc1\x88\x0e\xca\x47\xa7\x67\x66\x48\x05\x03\xd5\x02\x74\x24\xdc\x80\x2e\x4a\xe8\x4f\xcf\x71\x7f\x88\xcc\x7a\x45\xed\xe9\x81\x3f\x11\x32\x4f\x99\x7a\x05\x17\xa1\x1d\x14\x9f\xb9\x4e\x01\xc5\x8d\x62\xcb\xeb\xa2\xad\x22\x74\x6d\x4c\xa2\xe1\xff\x30\x5b\x0c\x46\x3d\xb2\x5a\x3f\x9b\xbe\xdc\xb7\x4d\x94\x7c\x6b\x8e\x84\x11\xa5\x49\xe7\x73\xde\x3d\x7c\xb1\x42\xc3\x88\x79\x54\xba\x53\x6e\x0b\x59\x96\xe6\x87\x3b\xc8\xaf\x0b\x5f\xc6\xf7\x8f\x94\xa3\x8e\x6f\x6c\xfa\x0d\x9c\xce\x35\x06\xff\x9b\x21\x74\x8f\x1f\x4b\xc0\xec\xb6\x11\x39\x46\xc7\x57\x3d\xf4\x0d\xb7\x30\x06\xc0\x59\xc3\x95\xb2\x2a\x02\x9b\xbe\x6a\xe4\x08\x2f\x32\x3a\x49\xed\x3f\x43\x17\x7d\x34\x4f\x06\x7f\xb5\x3f\x9a\x30\x81\x84\x6c\x9a\xb9\xc7\x48\x22\x8a\x33\xff\xad\x92\x8d\x51\xfa\xeb\xb5\xb1\x47\x9b\xf1\x7e\xe4\x69\x9e\xc3\x75\x32\x6c\x30\xf5\x93\xc4\x47\xd1\x9d\xd5\x6e\x3b\xf8\x7a\xdc\xf3\x70\x01\xa6\x36\xed\xdc\xdf\x9c\xb8\xaf\x42\xeb\x49\x38\x0f\x77\x6e\x82\xa5\xc3\xfd\x3d\xe4\xa0\x3d\x33\xb7\x4a\xb5\xe8\xb8\xe8\xfa\x61\xc3\x50\xf8\xe0\x59\x81\x10\x69\x8b\xda\x27\x29\xdc\x5d\x77\x6e\x34\xe7\x91\x3a\x66\x8f\xdc\x31\x48\x38\xdb\x7d\x38\x01\x54\x5b\x52\x81\x9f\x50\xe6\xfc\xf8\x5c\xa6\x87\x34\xb7\x4b\x6b\xf4\x84\x42\x13\x53\x30\x71\x3a\x65\x56\x8d\x67\x64\xa1\x85\xd2\xd3\x58\x68\x06\xbc\xaa\xb9\xaa\x4c\x95\x82\xb3\x9a\xc2\xc6\x8c\xb1\x9c\x8c\x3c\x1d\xa3\xb5\x64\x28\x89\x61\x56\x9f\x6d\x6e\x56\xbb\xcd\xec\x6e\xd9\x19\xbc\xd3\x73\x5f\x85\x66\xdc\xf7\x22\x9d\x2e\x5a\x92\x21\x50\x0f\x8f\x2f\x8b\x8b\xb3\x93\x72\xfa\x76\x00\x1a\x2b\xb6\x67\xe2\xe2\x4a\x70\xc6\x71\xb5\xff\x1e\x5d\xa2\x21\xc0\x78\x25\x34\xe7\x4e\xe1\xde\x53\x6b\x85\xe0\x4b\xfe\xc1\x4b\x35\x3f\x9f\xfa\xdf\x90\x78\x34\x44\xb0\x5b\xaf\x02\x7e\x58\x6e\xd8\x74\x89\x78\xa7\x3f\xf2\x88\xd0\x8b\xa7\x42\xc1\x34\x67\xa0\x24\xbe\x02\x74\x7a\xf7\x88\xee\x03\xf5\x98\x56\x15\x28\x74\x32\x31\x3e\xf7\x3b\x44\xff\xb4\x29\x48\x82\x50\xbb\x54\xdd\x2c\x83\xb2\xee\x62\x47\x24\x0c\x63\x6e\x39\x8f\x90\xdb\xc0\xb0\xd9\x4f\xe1\x2c\x25\x09\x89\x46\x74\xcc\x6c\xf7\xfb\x28\x1b\x09\x29\x20\x62\xca\x64\xce\x97\xe7\xb2\x5a\xa3\x0a\xf7\x68\x84\x42\xc6\x59\x4b\x21\xbf\xcc\x8d\x7e\x94\xee\x4a\x21\x25\x09\xa3\xc4\xb7\x10\x0a\x2b\x5c\x74\x73\x9e\x20\x32\xb7\xbd\x89\xc7\x90\xf1\xba\x3a\x1f\x8f\x73\x5e\xbd\x7e\x14\x99\x76\x77\x22\xd4\xb0\xaf\x6d\xd3\x2c\x95\x45\xfe\x93\x67\x19\x0c\x8c\x4d\x42\xb4\x6f\xfc\xb0\x14\xca\xbd\x91\x33\x29\xf7\xfd\x9a\x5b\xd7\x91\x82\x36\x3f\x73\x75\xb8\x0e\x47\x81\x71\x8a\xf0\xc2\x97\xfc\x95\x67\x2d\x8b\x9a\x24\x51\x48\xb4\xfd\x22\x6b\x5e\xd6\xa9\x4c\x4f\x3c\xaf\xab\x81\x16\xc5\x70\xf0\x23\x6a\xe4\xbc\x56\xcf\x3f\xdb\x9b\x24\xa1\xe5\x0e\x46\x55\x3a\x27\x76\xdf\x34\x30\x0a\x96\x92\xc2\x72\xfa\xdc\x19\x63\xbf\xf7\x0a\x11\x97\xc4\x3d\x42\x59\xfc\x1b\x64\xfd\xb3\xa7\xce\x35\xfa\x4c\x91\xd2\x81\x6e\x27\xf2\x32\x4b\x0f\xa9\x68\x3e\x44\x39\x06\xf6\x4b\x12\x0b\xa1\xf8\xe8\x08\x71\xbf\x19\xeb\x18\x87\x03\x05\xa5\xea\xcb\x6d\x69\x3d\x3d\xdb\xcc\x3d\x23\xdd\x6f\xc8\x39\x07\xb1\x15\xc2\xa3\x38\xb4\xf4\xc0\x48\xf2\xb1\x05\x5e\x15\xf9\x1f\x7d\xaa\xc1\xd1\x54\xe0\x9c\x60\x75\x6d\xb3\xef\xe0\xb7\x34\x48\x13\xdb\x2a\x88\x8f\x26\x9b\x95\x53\xeb\x67\x0f\x65\xe3\x29\xa3\x85\x9b\x56\xbb\xd7\xb4\x5a\x9f\xcb\xb4\xe6\x79\x2a\x79\x36\xa8\x13\x97\x44\x72\x23\xaf\x6b\xcf\xe2\x2b\xf7\x7e\xf8\x40\xca\x8f\x85\x93\xe4\xc3\x15\xed\xf4\x41\x49\x2f\x2c\x48\x54\x12\x05\xa2\xc7\x5e\xbc\xbc\x26\x30\x76\x3d\x45\x84\xa1\xa1\xaa\xab\x12\x70\x2d\x60\xd2\x72\x88\xec\x6c\x7c\xc5\xe6\xa8\x4e\xf3\x73\xeb\xf7\x12\x88\xcc\x5a\xfe\xe7\x8f\x87\xf6\x4f\x12\x78\x8b\x45\x77\x6c\xf1\xd3\xbf\x0c\x4a\xe1\x77\x6c\xb9\xdc\xcb\xe2\xf8\x95\x79\xe3\x8c\x55\xa2\xe3\x04\xf5\x0e\xb6\xeb\xe5\x7c\x35\x7b\x58\x6d\x77\xfb\xed\x6e\xf6\x63\xb9\x7f\x7e\x72\x61\x1c\xea\x87\x1c\xd1\x0b\xbc\x2c\x57\xea\x33\xc8\x8a\x11\x2d\xa1\xa4\x7e\xa2\xdd\x41\xd7\x58\xa1\x5d\x34\x8c\x36\x3e\xbe\xb5\xb5\xf7\x15\x64\x59\x97\xe8\x95\x34\x10\x26\xf5\xe9\xa0\x5a\x26\x71\x3d\xbc\x73\x48\x35\xc2\x0b\x30\x8b\x36\xac\xe7\x1d\xae\x45\x4a\x38\xf7\x0d\x8c\xe4\x94\x15\x97\x79\x71\x3c\x9e\xf3\xb4\xbe\xdc\xf0\x2c\x2b\xea\x49\x5e\x62\x87\x4c\x94\x94\x26\x8a\xb6\xbf\xb2\xe6\x75\x0d\xe5\x68\xb1\x51\x16\x09\x6d\x96\x6f\xbf\xec\xd2\x35\x8a\x28\x69\xb7\x43\x5c\xb6\xe3\x0e\x8a\x78\x36\xfa\x87\xda\x3f\x65\x57\x80\x75\x8d\x97\x9e\xf2\x14\x69\xc4\x15\x62\x4f\x72\xf8\x40\x7f\x7f\xda\x34\x19\x6c\x74\x34\x52\x09\x89\xfa\xc0\xbb\xab\xe1\x8d\xfd\x08\x89\x36\x52\xd4\x35\xd4\xeb\xb2\x78\x4f\xd5\x78\xf7\xa0\x71\x10\x62\x22\xce\x12\x46\xb4\x92\x1f\x86\xf5\x7c\x72\xcf\xa7\x31\x37\x52\x50\x92\xe7\xeb\x8c\xd7\xba\x28\x8f\x36\x5a\x37\x9d\xf9\xa5\x89\x14\x8e\x26\x69\xbe\x45\x88\xa1\xe6\xe3\xd3\x8e\x26\x3a\x0e\x62\x27\x10\xf2\x9f\xff\xb4\x92\xa3\x8d\xff\xe5\x32\x6f\x54\x10\x1e\x1a\x1a\x8b\x63\x9a\x7f\xf1\x6b\x82\x0a\xcf\xa1\x7c\x5a\x20\x2a\x92\x70\x3b\xb8\x8f\xa4\x42\x03\x16\x18\xaf\x9e\x56\xbb\xd5\xec\x61\xef\x68\x3d\x67\x37\x0f\xcb\xfd\xee\xf9\xc7\xf2\x69\xbb\xff\xf9\xfc\xf0\xd2\x06\x3c\xa9\x0c\x24\x16\x7e\xe4\xeb\x22\xcb\xaa\xf6\xaf\x9c\x62\x71\xc1\x6a\xfe\x7c\xfb\x97\xfb\xa3\x22\x09\x49\xac\xb3\x63\x46\xb4\x57\x37\xe0\xfa\x44\x09\x96\x63\x73\xa5\x36\xf3\x71\x9b\x0e\x12\xd1\x89\x0b\x2e\xe0\x2d\xe3\xcb\x6b\x95\x9e\xa1\x31\x62\xaf\x05\x9f\xa1\x65\xf7\x38\xfb\x73\x3f\x7b\x78\x78\xfe\xb5\x5c\xec\x6f\xfe\x6a\x16\xfe\xdd\x72\x1f\xb8\x27\x84\x20\xc2\xe8\x9c\x7b\xfd\xf5\x66\x35\x6f\xdf\x14\x98\x79\xfc\x0a\xea\xec\x3d\x33\x15\x00\x03\x4f\x96\x42\x1c\x22\xfa\xfa\xe6\x9c\x65\x60\x29\x46\x24\xf3\x92\xd8\x14\x90\x66\x59\xf1\x61\x4a\xd2\xab\x5d\xc7\xa0\x74\x9d\x6b\x1d\xd9\x84\xcc\xd3\xa6\x84\xea\x98\xe6\x1b\xf8\x1f\x77\x5b\x3f\x30\x99\x82\x66\xf2\x64\x69\x5f\x58\x7b\xda\xd9\xe9\x3f\x29\xf3\x05\x31\xc8\xa0\x22\xcd\x67\x07\xeb\x42\xdf\x16\xe5\x17\xe4\xc9\xc3\x89\xce\x7c\x45\xb1\x98\xc6\xc5\x07\x1a\xcb\xe4\x5a\x32\x70\xf4\x16\x41\xc0\x91\xf8\x68\xb7\xbc\x71\x39\x53\x16\x84\x12\x03\xb9\xa2\x38\x1f\x5e\xd1\x9d\x19\x07\x95\x58\x60\x6d\x08\xf8\x6c\x26\x6c\x2b\x4b\xd0\x36\x43\x60\x21\x53\xf5\xa2\x38\x0c\x67\x3c\x0b\x7d\x82\x3c\x4c\xb8\xd5\xbe\x54\xe0\xd8\x3b\x7b\xd6\x33\x23\x54\x06\x96\xc8\xd4\xd4\xc5\x0e\x42\xcd\x8c\x70\x89\xb6\x8d\x9d\xad\xcb\xce\x20\x64\x34\x00\x0c\x93\xcd\x97\x4f\xbb\xfd\x62\x39\x5f\x3d\xce\x1e\xb6\x6d\x23\x09\x3d\x13\xbf\xb2\xc2\x67\xed\xdf\x29\xe6\xb4\x72\xf8\xe8\x49\x43\x4b\x46\x35\xf5\x5c\x68\x08\xd7\xa4\x6b\x60\x1c\x82\xe0\x8b\x2a\x9f\xd1\x08\x47\x84\xe1\xec\x45\xd4\xbf\x9a\x55\x5b\xc9\xaf\x4f\xc3\xe1\x08\x45\x5a\x20\x00\xe0\x71\xf5\xd4\xac\x85\xcd\x6e\xf5\x74\x37\x98\xf5\x2c\xd2\x0a\x41\x28\x22\xc3\x82\x33\x35\x93\xb2\x6b\xd2\x78\xfa\xa2\xcd\xbc\x85\xba\x4d\xb0\x0e\x1f\x2b\x66\xd2\xa7\x4e\x38\xaa\x39\x6c\x3a\x52\x6d\xc9\x62\xf0\xd0\xdf\xd9\x5b\x26\x26\x23\x7e\xfa\xdb\x60\xce\x37\xf9\x5f\x16\x83\x34\x7a\xd7\xe8\xd1\x96\xb0\xc5\x89\x5f\x4d\xd9\xc5\x2c\xa1\x21\xe6\x73\x85\x25\x46\x8a\x47\xe3\x93\x24\xc4\xd1\xdc\xce\xb2\xcc\x71\x09\xae\x4e\x1a\x4d\x64\x18\xb2\xcd\x4a\x96\x08\x8a\xc5\xa4\x4f\xf0\xe1\x10\xec\xa3\xfb\x81\xb6\x9a\x89\xe5\x1b\xd4\x81\x17\x78\x06\x29\x6d\xd8\x23\xdd\xa0\x70\xae\x95\xef\x6a\x4e\x0e\xe7\x8c\x97\x73\x5e\x56\xb7\x45\x89\xf2\x9c\x63\x5c\x04\xe3\x32\xe0\x7d\xe1\x2e\x9e\xed\x1f\x46\x44\xc7\x92\x89\xc0\x88\xf8\x37\x8e\xf9\x7e\xe3\x8f\x5b\xa9\x05\xf4\xa1\xb9\x71\x9b\x96\xdd\x02\x14\xca\x14\x02\x9c\x4a\xc0\xf4\xd4\xf4\xe1\xc7\x84\x4a\xd0\x81\x82\xcf\x1a\x2c\x2d\xf5\xe8\x37\x94\x48\x04\x6d\x71\x6b\x36\xac\xfb\x0b\xd2\x51\x37\xf0\x13\x8c\xe4\x9b\x0d\xd6\x54\x03\xf0\x34\xbb\xb8\xc8\x97\xb5\x88\xbe\x9f\xd7\x40\x62\xa3\xf9\xcc\x73\x59\x94\x73\x9b\x87\x73\x8d\xd4\xb0\x9d\xcc\x96\xff\xaa\x7b\x5e\x17\x03\xe6\xa1\x1d\xbb\x3d\xa7\x32\x55\x23\x25\x01\xc9\x20\x21\x18\x86\x3b\xba\xaa\x89\x81\xce\xa4\x64\x20\x22\x21\x7a\xf9\x8c\x27\xf8\x30\x08\x31\xd7\x41\x73\x8a\x95\x89\xa6\x58\x16\x8b\xf6\x37\xcd\x8d\x46\xeb\x45\x0b\x2f\xb0\xba\xef\xf3\xf2\xa2\xca\x9f\x29\x4a\x43\x37\x26\xbd\x42\x1a\xed\xb6\x1f\x45\x39\xa7\x3e\x7f\xc3\x17\x5c\x27\xa3\xd1\xd1\x0a\x64\xab\x41\xd4\x3c\xea\xe1\xd2\xd5\x7c\x4e\x9b\xda\x4c\x43\xc4\x6d\x91\x81\x3d\x24\x56\x0a\x53\x73\x5f\xc1\x92\xfb\xeb\x2c\xf2\x12\x8d\x58\x97\xe3\x67\xf9\xef\x7f\xf7\x5d\xdd\xc8\x13\x01\xd6\x19\x7e\xa4\xb9\x2a\x3e\x06\x9b\x6f\xe4\x49\x82\xae\xe1\xe2\xf9\xcf\xe1\x35\x10\x25\x7e\xeb\x05\xae\x72\x44\x52\x8c\xe3\x5f\x4d\x2f\x34\x5f\x6d\x2d\x94\xa9\x0d\xb6\x1a\x17\x1d\x0d\xe9\xc6\x50\xf9\xfd\x05\xdc\xcd\x8f\xc8\x97\x1e\xd8\x72\xea\x55\x65\x8d\x5b\x13\xf6\xb0\x1d\x02\x15\x5b\xf0\x40\xae\x5a\x5c\x28\xe6\x1e\xba\x2e\x10\x18\xd6\x53\x63\xab\xdc\xa6\x46\xb9\x78\xb8\x5f\x44\xa1\x8e\x09\x6b\x45\xe7\x9b\xf5\xb0\x6c\x46\xe1\xb7\x92\xf7\x32\x22\x8a\x20\x68\xf0\x1f\xf3\x5e\x98\x3f\xa2\x89\x01\x4c\x67\x13\x29\xf1\xef\xb1\x80\x11\x95\xbe\x20\x43\x38\x6b\x5a\xbf\xae\x8b\x2c\x95\xd7\x9f\xb8\x77\x80\x46\x11\xf1\x31\x06\xf7\x7c\xeb\x9e\x22\x12\x91\x24\xd3\xf2\x45\x0b\xe0\x59\x33\xa4\x8b\x42\xb6\x02\xd6\x32\x8a\x34\x47\x28\xed\x4c\xa9\x47\x4c\xa8\x7d\x5d\x28\x2d\xa3\x58\x1a\x29\x43\x05\x96\x5f\xfa\x9f\x67\x6e\x2a\xce\x86\xfd\x12\x9a\x20\xb9\x86\xc9\x93\x3c\x9d\x8f\x69\x75\xe4\x6e\x31\x47\x09\xe3\xb1\x2d\x71\xbf\xe3\xd5\x4b\xd5\x23\xa4\x75\x3d\x12\x30\x25\x3e\x75\x19\xe0\x57\x1b\xd8\x7a\x51\x22\x7d\xc3\x05\xd7\x4c\xa2\x7b\x5e\x2a\xc9\x07\x61\xb9\x28\x01\x21\x8d\xe1\x72\x4a\x4b\x18\xa8\xbe\xcb\x88\xd3\x40\x68\x63\x06\xcc\x5f\x1b\x97\x39\x3f\x4c\x0b\xfb\xc8\x48\x78\xda\x85\x68\x36\xa9\x1a\x3f\xa5\xf0\x43\xcc\x1b\x37\xb6\xcb\x9f\xd4\x21\x5f\x22\x19\x19\x53\xa0\xa7\x2c\xb1\x18\x2d\x0f\x19\x49\x24\x5d\xd8\xbe\xac\x97\x9b\xfd\x6c\xf1\xb8\x7a\x6a\xaf\x86\x48\xd9\x2a\xc3\x7a\x57\x20\xb1\xc8\xb9\x57\xfa\xd6\x56\xc4\x39\x67\x32\x52\x3e\x91\xda\x85\x91\x3e\xf2\x51\xf9\x91\x8c\x54\xec\xa1\xe5\x6e\xb9\x58\x5e\xf2\xf4\xb3\x97\x14\x8f\x94\xf4\xd0\x97\x34\x61\xe5\xea\x7c\x32\xec\xb7\xd5\xbe\x5f\xa2\xff\xc7\x95\x79\x3c\xbd\xf7\x47\x4a\x19\xc5\x28\x13\x4a\xf9\xf5\x1b\xe4\xaf\xbd\x08\xb8\x61\x61\xfe\x55\x49\x4c\x61\x7d\x43\xde\x27\x23\x50\x06\x3c\xb4\xde\xdc\x0f\x37\x26\x00\x8e\x8c\x23\xaf\x69\x09\x25\xd6\xf0\x43\x55\x94\x75\x9f\x99\xfb\x37\x55\x86\xed\x13\xc5\x9e\x10\xc4\x8e\x69\xb3\xeb\x77\x34\xcb\x83\xcf\x18\x7b\xda\xd0\x93\xba\x88\xc2\x2a\x57\xa9\x4c\xe1\xca\x84\x77\xe1\x8f\xd8\x0f\x8c\x1c\xf2\x3d\xa8\x03\x2a\xca\xcc\xf9\x29\xad\x5d\x80\xde\x75\xd2\x1a\xeb\xb5\x76\x77\x4b\x5b\xed\xef\x5a\x02\x6a\xea\xa3\x9b\xbd\xef\x2e\xd5\x75\x8f\xf6\xcf\xf5\xe0\x3e\x6e\x4d\xa5\x49\x3d\xfd\xe8\x2e\x05\xa3\xa6\x7e\x80\xfa\x5f\x50\x0e\x89\x35\x64\x1c\xfa\x02\x63\x58\x25\x42\x69\x41\xeb\xe6\x35\x5a\xbc\x42\x1c\x8a\x80\xda\xaa\xf1\x3a\x3d\x42\x96\xe6\xc0\x73\x75\xe8\x72\x46\x71\xa8\x95\x15\x6b\x6f\x8c\xa9\xdb\x94\xb7\x10\x5e\x07\xe7\x19\xfe\x20\x09\x80\x76\x9c\x90\x78\xf6\xdd\x96\xc5\x71\x03\x3c\x7b\xc9\x53\x59\x94\x79\xdf\x52\x8d\x89\x20\x9e\x61\x88\x7d\x03\x5b\x99\xdf\x36\x35\x96\x5f\x4b\x9f\xb6\xfc\x9f\x49\xaa\x6d\x19\xd3\x50\x22\x86\xe1\x57\x2f\x5a\xf5\x23\x95\x6f\xbb\xd7\x9e\xb2\x8f\x8c\x69\x44\x91\x6e\x0e\x09\x74\xcf\xb2\x46\x8c\xc5\xf0\xa3\xd3\x18\x10\x70\x55\x1d\x9b\xbd\xa3\xea\x23\x21\x62\xca\x23\xda\x91\x60\xdf\x15\x85\x95\xfc\x1b\xdd\x81\x0b\x54\x36\x11\x05\x2f\x95\xc1\x71\x5a\xc1\x4b\xd7\x41\xe9\xc0\x96\x89\xfe\xba\xe7\x93\x53\x2f\xf2\x55\xe8\xb7\x49\xe5\x05\xff\x8a\xf4\x4e\xc6\x31\x84\xf8\x6d\x9b\x0d\xe5\x4b\xc8\x84\xed\xcb\x75\xe4\xd9\xe9\x53\x64\xef\xb0\xe9\x38\x52\x64\x2c\x7c\x8d\x55\x77\xdb\xd7\xa7\xed\xeb\x60\xc2\xca\x20\xc0\xc0\xda\xe9\x5c\xbd\x3e\xa6\xcd\x98\x14\x79\x9b\x4c\xbd\x3e\x4e\x58\x3f\xd4\x19\x4b\xc6\x8c\xbe\x72\xfe\x9a\x76\xca\x5c\xb6\x51\x51\x86\x40\xbb\xfc\x7c\x84\x92\xa7\xdf\x67\x87\x63\x25\x22\x3c\xf7\xe7\x5b\xe7\x41\xc5\x4a\xd2\xc8\x14\xaf\x36\x86\xc4\xbc\xc8\xab\xde\xb4\x56\x40\x11\x56\xb2\x98\x3f\xfe\x3e\x99\x11\x83\x47\x3c\xdd\xe1\x95\x66\xf5\xdb\x4d\x51\x55\xff\x3c\x8f\x8b\x25\x65\x0c\x7e\x04\x4e\xf4\x1c\x2b\xd9\x6a\x9e\x19\xff\xd6\x99\x28\x31\x10\xa3\x0a\x29\x4b\x50\x85\x23\x1b\x76\xb0\x6a\xd7\x27\x06\x84\x02\x35\x2e\xe5\x03\x34\xae\xd9\x63\x5a\x36\xa6\xa8\xeb\xa0\x23\xc6\x7d\x27\x11\x3f\xd4\xa1\x9a\xf8\xb6\x3a\x0e\x1c\x1a\x1f\x9f\xc8\x70\xba\x19\x2a\x8e\xe1\x38\x6a\x1d\xf3\xb6\x80\x76\x50\x93\x6e\x3a\x24\x1e\x95\x89\x55\xc3\x59\xcd\x9f\x7b\x42\x4d\x32\xf1\x49\x88\x10\xdb\xfd\x6b\x1f\x05\x34\xf8\xaa\x89\x0f\x04\x6d\xbc\xc5\x6a\xbb\xdb\xac\x6e\x5e\x76\xab\x67\x77\xfc\x25\x01\x0f\x90\xbd\x5d\xee\x1f\xd3\xbc\x47\x87\x29\x93\xd0\xe3\xe8\x26\x2d\x77\xf7\xcb\xcd\x72\x3e\xdb\xde\x63\x4c\xec\xbb\xc3\x22\x09\xa9\x1f\xbb\x42\x81\xbd\xea\xd7\x35\xcb\x24\x8c\x22\xaf\xab\x19\x9c\x65\xd9\xcf\x73\xd6\x38\x0f\x2d\x23\x9d\x4c\x48\x14\x6a\x66\xcb\xbd\x9e\x8a\x05\xc8\xf4\xc8\xaf\x6b\x01\x5d\xe7\x38\xc4\x98\xeb\x1b\x4f\xcb\xa2\xea\x49\x74\xc9\x84\x92\x00\x83\xfe\x0f\xc5\xc1\xc4\xe8\x8d\x7f\x35\x4a\x99\x26\x94\x52\x7c\xda\x93\x95\xdb\x74\xe1\x98\x7e\x46\xc8\x7d\xce\x84\x82\x0e\xb5\x15\xcf\x31\xbc\x62\x12\x2d\xb2\x3e\xb9\x8a\x4c\x58\x64\x30\xf9\x3c\xcb\x0a\xd9\xb8\x74\x4e\x87\xbf\xed\x10\x6b\x6a\xcb\xfc\xf6\x46\x77\x4b\xf1\x9a\xef\xc5\x19\x09\xfe\x47\xdf\x9d\x69\x86\x01\xc2\xc7\xcb\x4c\xbd\x37\x3b\x96\xba\xa6\xff\x94\x49\x44\xa2\x44\xd8\xdc\xf7\xf0\x69\x22\xa6\x84\x72\x13\x0b\xfd\xee\xb4\x68\x8e\xc0\xe7\x77\x28\x79\x8b\x0f\x4e\x22\x6d\x2a\x5d\x16\x70\x1e\x80\x20\x93\x38\x12\x2e\xe0\x64\xb6\xcd\x35\xbf\x5c\x8d\x62\x9c\x08\xd2\x0f\x79\xfc\xed\x78\xc6\xf0\x2d\x12\xa6\x30\xdd\xde\x9c\xe9\x7c\x5b\x17\xf2\xad\xea\x1d\x14\x49\x92\x04\x98\x3e\xb7\x7c\xe1\x66\xf5\x99\x12\x3f\xd7\x45\x78\x31\xea\x9c\x64\xf9\xcb\xe9\x64\x4a\x50\xbe\xc8\xe2\x24\x22\x8c\x51\x5d\xe1\xc8\x3f\x1b\x47\x64\x6e\x89\xe5\x7a\x24\x40\x32\x91\xa1\x8a\xdd\x3e\xde\x3c\x49\x75\x5b\x94\xcf\x99\xea\xc9\xc4\x5e\x57\xa9\x0e\x47\x46\x0a\x85\x78\x6d\xcb\x8f\xe7\xa6\xc2\xe8\x68\x49\xa4\x32\x16\xa8\xe9\xb6\x30\xe4\xc6\x50\xee\x8b\x3c\xbb\xec\x17\xf0\x3e\xea\xae\x28\x43\x5b\x69\x7f\x6a\x3c\xee\xd1\x5c\x50\xb1\x70\xf2\xb8\x37\x50\x57\x37\x97\x79\xe3\xf1\x16\xe5\x90\xbf\x5f\x26\x9a\x24\xc8\xc9\xbb\x3d\x65\x69\x3d\x90\x7f\x1f\xfe\x98\x86\x80\xdb\xe8\x67\x9a\x07\xc3\x1f\xe3\x9e\x47\x45\x38\x28\xe1\x6c\xb6\xae\x11\x0a\xa5\x3f\x44\xb1\xbb\xd0\x0f\x9d\x0e\xf8\x06\xe3\x1e\xeb\xcf\x6c\x94\xfc\x19\xfd\x92\x2f\x5c\x98\x60\x07\x55\x7d\x5b\x9c\xdd\x5a\xe7\x3e\x37\xc9\xe7\x12\xaa\xf3\x11\x1e\x8a\xba\x45\x12\x70\x5f\x0a\xe4\xe1\xb4\x6c\x86\x26\x2b\x2b\x8d\xfb\x3f\x0e\xfe\x76\x27\x24\x0f\x7c\x11\x46\x6d\x81\xc3\x1a\xca\xaa\xc8\x79\x36\xe7\xa7\xd1\xeb\x07\x44\x25\x5d\x8c\xc7\xd2\x2e\x0e\x5c\x1f\x1e\x44\x09\x26\x9e\xec\xf2\xfd\xe7\x19\xda\x28\x28\x0f\xfd\x28\x68\xc1\xf6\xab\xd1\xaa\xe2\x94\x04\xf8\xec\x19\xaf\xea\x2d\xcf\x60\x95\xdf\xdf\xb9\x50\x32\xa7\x14\x70\x2b\x45\x69\x20\x0c\xbb\x60\x1a\xf9\x72\x95\x06\xfb\x16\xa2\xc0\xa9\x8a\x35\xea\x0f\x01\x57\xfb\x73\xec\xee\xce\x3c\x03\xb6\x35\x04\x14\xf3\xe2\x78\xc5\xb6\x23\x39\x0b\x0d\x3f\xff\x43\x2a\x4a\x6e\xc2\x31\x4f\x50\x7f\x14\xe5\xdb\xef\x4f\x76\xce\x08\x8b\xad\xca\xdf\x6d\xfa\x0e\xdb\x1a\x4e\xc3\xc2\x78\xc9\xe3\x20\x54\x2d\x25\x1e\xb2\xe9\xa3\x98\xd0\xaf\xe6\x07\xda\x2e\x31\x12\xfd\xee\x25\xcf\x6f\x4a\x00\xf5\x75\x45\x02\x4f\x48\x90\xd8\xf9\xf3\xac\xb5\x63\x9b\x9b\x9c\xf2\x9c\x43\x88\x9c\x3f\x92\x67\xd9\xb9\x82\x92\x4f\xa7\x09\x6c\x6f\x41\x21\x96\x6d\x78\x66\xac\x8a\x6c\x3b\x49\x22\x31\xd8\xf6\x8f\x67\xe7\x1f\x70\x99\x44\xa1\x15\xfb\x3c\x9d\x6b\xb0\x84\x87\xb6\x51\x25\x09\x8a\x62\x39\x5a\xed\x9b\xcb\xf2\xf1\xf9\x69\xb7\x3a\x9e\xb2\x3e\x66\xce\xbd\x27\x23\xa3\x87\x02\x0b\x94\x53\x50\x43\x79\x4c\x73\x58\x4e\x94\x60\x4b\x0e\x31\x35\x8c\x0c\x48\x66\xb3\x17\xa6\x5a\xe0\x3b\x4d\x49\xc9\x75\xe8\xa3\x47\xf5\x58\xbc\xa7\xf0\xab\x28\xdb\x4a\x0b\xae\x69\x82\x76\x2f\x57\x6a\x7d\xce\x32\xe7\x87\x7c\x9b\x99\x15\x1e\x11\x58\xf9\x53\x9e\xf3\x3c\xcd\x0f\xfb\xd4\xdd\x4e\x78\x91\x87\x42\x52\xcf\x6b\x97\x2c\x17\x3e\x21\x98\x4f\xd0\xfe\xf4\x67\x16\xbe\x10\x9e\xcd\x53\xbb\x8a\xa4\x3b\x5e\x2d\x3f\xeb\x92\xcf\xca\x6e\x76\xba\x5d\x50\x04\x54\xe0\x6f\x28\x1b\xd7\xea\x57\x23\x88\x40\x44\x89\x74\xf6\xdb\x1b\xe4\x93\xd0\x63\x11\x48\x9f\xda\x0d\x77\xf7\x67\x73\x94\x8b\xcb\xbc\xad\x05\x6e\x7f\x28\x24\x2a\x50\x3d\xc6\xab\x2f\x17\x6a\x7f\x9d\x08\xc2\x42\x44\x93\x3f\xc1\xc7\x48\x48\xd7\x75\x80\xc0\x50\xe6\x2f\x57\x6b\x9f\xd1\x3f\xda\x3f\x1b\x30\xdc\x01\xd0\x94\x69\xb6\xd8\x67\x3d\x6d\x45\x09\xea\x47\xcc\x77\x35\xdb\x9f\x96\xba\x67\x04\xa9\x12\x94\xb1\xc4\x10\x29\x55\xf2\x0c\x0f\x45\x55\xdf\xa6\x87\xd7\x7e\xee\x62\x38\x28\x54\x79\x98\x27\x9d\xa5\xe5\x64\x80\xe1\x7a\x4f\x10\x8c\x33\x11\xf4\xce\x92\x6f\x65\xe0\xa5\x60\x22\xa4\x86\x7e\xf8\xdf\xe7\xaa\x46\x72\xf1\x1b\xa8\x3f\x00\x72\x04\xbf\xcc\x72\xf5\x54\x94\x47\x9e\x4d\xd4\x80\x09\x26\x75\x08\xc6\xb0\xdd\x6f\x57\x77\x4f\xfb\xf5\x66\x79\xbb\x72\xa0\x74\x11\x73\xa3\x60\x56\x25\x36\x88\x61\xff\x9e\xf8\xca\x10\xd4\x66\x45\x5d\xed\x33\xd0\xed\x4c\x49\x22\xe1\xd0\x23\x96\x5f\x6d\x38\x1c\x89\x34\x50\x30\xb3\x47\x6c\xa1\x2f\xd6\xe3\xba\x28\x1e\xbb\x12\x2d\x83\xb5\xf9\xc2\xbd\x44\x86\x6d\x82\x84\x3a\x68\xae\xc0\x5b\x8f\x54\x4a\x22\x15\x4f\xc7\x9d\xf2\x71\x4d\x63\x29\x05\x07\x2f\xf2\x07\x22\xe9\x53\x20\x31\x21\x98\x43\x6f\x98\x0f\x62\xc2\xfb\x4f\x2d\xe0\x49\x08\x1e\xba\xf2\xc8\x7d\x51\x2a\x28\xf7\xa2\x28\xde\xf6\x99\x89\x6a\x0f\x3e\xae\xd0\x3e\xc2\x93\x4e\x8d\x81\xb0\xbb\x9c\x60\xff\xc4\xeb\xf4\xbd\x7d\x6a\x19\x18\xd9\xac\x11\xf1\xce\xf0\x81\x24\x01\x24\x16\xbd\xc6\xa7\x08\xc9\x12\x4c\x28\x62\xbd\xd6\x4d\x3a\x5c\xc7\x52\x06\x38\xfa\xfb\x7d\x09\xcd\x17\xda\xbb\x06\x15\x52\xa4\x07\xdb\x9f\xf3\x13\x97\x6f\xcb\xcf\xd3\x44\x55\x89\x50\xd4\xc4\xe5\xd3\x6a\x5d\xa6\xef\xed\xb5\x09\xc4\x26\x03\x94\x56\xf5\x9c\x4f\x7c\x51\xf0\x34\x42\x57\xb9\x52\xcf\x27\xc8\x67\x06\x74\x35\x09\xd8\x9d\xf0\xa4\x04\x24\x80\x06\xda\x62\xf6\xf4\xa3\x99\xa4\x5d\xba\x55\xe8\x40\x20\x81\xc2\x9c\x9f\x6e\x33\xf8\xb4\xe1\xd6\x76\x53\xd0\x22\xe6\x74\xcc\xd8\xf1\x85\x13\x25\xbd\x28\x41\x80\xf2\xfd\xed\xee\x0a\x2f\xea\xba\xc4\x0a\xc1\xc7\x27\x44\x28\x59\x00\x89\x6b\x93\x21\x9a\x87\xb2\x15\xa1\xaa\xda\x26\x60\x48\x11\x63\x70\x65\xd6\xd5\xbe\x2d\xca\x2b\xe6\x9c\x6e\x65\x4a\x3f\xf4\x30\x50\x63\xf4\x63\x71\x97\xf8\x7f\xc1\x7f\xb7\xb5\xd7\xa4\x73\xb2\xa3\x8e\x00\x86\xfd\xb7\xbb\x5a\x32\xe2\x88\x1a\x65\x7d\xe6\x19\x2e\x91\x67\x3d\xe7\xa5\x7a\xce\x6f\xce\x97\xd9\x79\xa2\xc6\x49\xfa\x10\xc4\xaa\xad\xe4\x30\x92\x2d\x1b\xcb\xbd\xe5\xc0\x62\x23\x1e\x4f\x29\x7d\x1d\x3b\xd5\x50\xf7\x42\x58\x57\x69\x9b\x03\x0d\x0e\x3e\xb1\x81\xaa\x38\x97\x12\x2a\x5b\x9c\x36\x79\x8c\xc8\x90\xaa\x24\xc1\x60\x6a\x55\x17\xe5\x65\xe5\x66\xaf\x0c\xb9\xb1\x2f\x20\x57\xb3\xee\x8f\x82\xc4\xd0\x4b\x82\xfe\x28\x8b\x8f\x2f\x3f\x71\x28\x40\x98\x6a\x33\x09\xa7\x7a\x66\x58\x4c\xdc\x9d\x48\x1c\x63\xbc\x66\xdb\x6c\x6a\xed\x1f\x13\x12\x18\x3c\x3d\x56\x7d\x7d\x59\x72\x28\x09\x50\x34\x6f\xb3\xe2\x03\xaa\x7a\x56\xbd\xf5\x83\x88\x92\x80\xf6\x49\xcf\x8a\x79\xe0\xd7\xfe\xd8\xe8\x86\x34\x4e\x90\x16\x01\x61\x88\x98\xdd\x2b\x97\xc7\x53\x56\xe0\xa9\xd4\xce\x9c\x09\x96\x48\x29\x99\x25\xbc\x7a\x2c\xca\xe6\x0b\xa6\xe7\x63\x27\x8d\x35\x3a\xa5\xfa\xec\x41\xf6\xea\x04\x88\x2d\x8d\x34\x07\x74\x0f\x20\x3a\xfa\x52\x9c\x27\x9a\x5b\x60\xcf\x23\x94\x6f\x59\x7b\xd6\x7f\xc1\x86\x23\xa5\xa4\x1c\xe9\x20\x16\xdb\xf5\x9a\x97\xfc\xd8\x58\x65\x95\xe3\x67\x1f\xde\x5d\x46\x80\x9a\x20\x69\xfe\xbe\x97\xc3\x9c\xac\x94\x10\x53\x13\x7e\xba\xc9\xb8\x7c\xcb\x9a\x07\x55\x57\xba\x10\x52\x2a\x2f\xc1\x5c\x29\x06\x61\xc2\x60\x6f\x22\xb5\x2e\xf3\xe3\x7b\x1e\x0a\x3a\xb4\x5f\x5b\x85\x3a\xb2\x73\x75\x36\x1b\xad\x0d\x90\x3e\xc6\x80\x1a\xa7\x0b\x8d\xbd\x6d\xce\x4f\xd5\x6b\x51\x8f\xfb\x69\x89\x20\xd2\xa3\x49\xec\x3d\xf2\x37\x28\xd7\x65\x51\x17\xb2\xc8\x6e\xdb\xd3\x49\x6a\x4f\xe1\x5e\xba\x6f\x7e\xcb\x2c\xc6\x67\xf1\xef\xef\x13\xb8\x52\x2b\x42\x79\x77\x7a\x9e\xc5\xf5\x2b\x2b\x2f\x30\xb4\x22\x07\xc8\x3d\x7b\xa8\xa1\x4d\xf0\x87\x6b\x8f\x80\x44\x6d\x3a\xbb\x4d\xc6\xa9\xc0\x8b\x05\xeb\xc9\xb7\x60\xee\xa2\x83\x37\xaa\xd0\xd3\x98\x06\x37\xdc\x92\x69\x7e\x58\x74\xd2\x43\x03\x8e\x30\xa9\xc2\xc0\xb8\x18\x18\x64\x6e\xff\x98\xb0\xc4\x46\x7b\x0c\x1f\xb8\xe1\x25\x9d\x50\x61\x19\xbe\x0f\x21\x41\x14\xb4\xdb\xcb\xbb\x01\xc0\x6e\xf8\x35\x7e\x6a\x7a\xcc\x14\xa1\x14\x6d\xd7\xbd\xf1\xe1\x2c\x41\xe7\x88\xbb\x48\x2a\x92\x68\xc4\x37\xef\x71\x73\x6e\x77\x05\x45\x3d\x1a\x45\x1d\xde\x13\x23\x53\xdd\x36\xad\x18\x91\x38\x63\x5c\x50\xca\xd4\xa1\x7f\x13\x17\x54\x8c\x47\x4e\x4c\x6c\x0b\x75\x8d\x10\x95\xe1\x13\x47\xa1\x09\x48\xb8\x2d\xed\xa6\x03\xbc\xbb\x1e\x32\x70\x48\xde\x19\x96\x61\x3c\x42\x3d\xa6\xf9\xb1\x5d\xe3\x08\x20\x31\xde\x29\x94\x35\x77\xe8\x34\x95\x08\x0f\x69\xa9\x1a\xb7\xee\x9e\x57\xf7\xf8\xd2\x0f\xa9\x84\x2b\xdc\xbd\xe2\x91\xcf\x59\x27\x40\x6e\x98\x75\xfb\xc1\x35\x25\x38\xb0\xd0\x11\xc4\x1b\xda\xb8\x55\x5e\x17\x3b\x7e\xa8\x4c\x99\xdc\xf0\x86\xd2\xd6\x5c\x96\x70\xca\x2e\x8d\xcd\xc6\xd5\xb7\x43\x26\x95\x46\x7e\x91\x0d\xb4\xf1\xae\x2b\x8c\xf3\xdf\xad\xff\x1a\xcd\x2e\xe5\xd1\xd0\xd2\xd3\x20\xef\xf6\xb9\x03\x8a\xf5\xc3\x34\x4a\xc5\xc4\xb7\x30\x08\x4c\xf8\xe3\xee\xae\x8b\x72\xc1\x4f\x8e\x06\x47\x29\xe9\x2b\x70\xa8\x67\x8c\xff\xe1\xa3\xde\x17\x59\xb3\x8e\x8c\xdc\x87\xd1\xe5\x18\xef\x75\x0a\x02\x1e\x81\x23\x29\xfb\x32\xf6\xa3\x00\x18\x82\x8f\xc5\xf9\xb2\x3d\x71\x09\xc8\x23\x7d\xee\x28\xe1\xa5\x02\x1d\x63\x76\x57\x81\xa8\x97\xf9\xa1\x55\x74\x95\x4a\x33\x85\x0e\x21\x1e\x05\x19\xaf\xa1\xc5\x72\x2a\x1d\x73\x4c\x59\x23\x8a\x74\x5e\x1c\x8f\xee\x74\x8a\xa7\xb3\xa6\xe0\xf9\x0a\x91\x47\x8d\x9d\xb3\xbd\x54\xf5\x17\x0c\x91\x12\x7c\xe1\xe3\x1e\xfe\x58\x28\x28\x4d\x7d\xe0\x3a\x6b\x01\x15\xe0\x2b\x81\xf6\xd4\xf6\xb5\xf8\x78\x82\xcf\x7a\x9e\xa5\xfa\x0b\xef\x0c\x7c\x08\x40\x74\x72\xa0\xca\xd0\xea\x0c\x70\xf3\x10\x90\x10\xbd\x8f\x4c\x94\x83\xe8\x2d\x04\xcc\x4f\x7a\x62\x1e\xd7\xa9\x35\x08\x54\x8c\x53\x78\xdf\x1c\x66\x48\x46\x52\x9c\xeb\x2b\xad\x39\x09\x61\x48\x0d\xf3\x29\xc6\xe8\x3e\x5a\x2c\x3e\x84\xc4\xd4\x42\x56\x50\xdf\x02\x4c\x32\xd9\x00\xf5\x08\xae\x6c\xe3\x92\x34\x77\xff\x12\xf2\xe6\xae\x08\x8c\xa5\xdf\xc1\x33\x10\x3f\xd4\xbe\x31\x65\x06\x6f\x68\xa0\xe0\x96\x9f\xe1\xca\xae\xfc\x1d\x24\xa4\xdb\xd0\x80\x8a\x98\xf6\xf9\x1d\x6f\xce\xd3\xca\x3f\x12\xa8\x4e\xd0\xca\x58\xac\xfe\x1a\x8c\x35\x23\x06\x03\x8c\x55\x34\xb3\x12\x5a\x1d\x87\xb6\x03\x8d\x02\x83\x08\x9d\xb7\x7f\x8a\x94\x55\x0b\x48\xeb\x87\x82\x77\xf7\x02\x22\x6d\xb0\x6a\xc1\x6b\xbe\xf7\x5d\x43\x24\x13\x44\x69\xb8\xc7\x0c\xbe\x78\xc8\x48\x31\xbc\xf1\x7c\x76\xeb\x8f\xbe\x78\x4c\x22\x74\x62\x4d\xde\xb8\xbe\xe6\xab\xf9\xbe\x84\x14\x62\x9a\x50\x7b\x32\x2c\xeb\x57\x1b\x0b\x1f\xa3\x91\x20\x06\x3f\x71\x74\xeb\x7b\xa4\xf1\x77\xaf\x90\x78\x3e\xc2\x28\x1b\x83\x62\x9a\x15\x04\xb8\xf4\x30\x07\x79\xad\x81\x34\x3d\x5b\xb8\x0a\x90\x4d\x41\xa5\x15\x26\x51\x15\xee\xbe\xbb\xc2\x1e\x7a\xa3\x08\x39\xc8\x90\x87\x76\x74\x6f\x5e\xb6\xd3\xe6\x3d\xa8\x50\x91\x56\x2c\x70\x56\x8a\x60\xf4\x8c\x8a\x1a\x74\xdb\xe9\xfd\xb4\xe6\xe7\x96\xcf\x5d\x02\xc4\x80\x5e\x4f\x75\x16\xe6\xc8\x38\x15\x79\x55\x94\xbf\x61\x4d\x97\x00\x89\x9f\x0c\x05\xc1\x31\x09\xd5\xb6\x1a\xa2\x0d\xa4\xed\xb8\x81\x2f\xf1\x52\x43\xcc\xd2\x38\xb8\x64\x6f\xa6\x99\x47\x22\x87\xb5\x78\xbf\x37\x0e\xc7\x68\x90\x34\x4b\x98\x65\xb6\x7b\xe0\x67\xac\xb8\x9c\x76\x5d\x47\xb7\x96\xc6\x0c\x14\xe7\x32\x87\x81\x17\x0e\x5a\x25\x78\xf4\x36\x93\xfd\xcb\xca\xc4\xbf\x9b\x32\xfa\xea\xbc\x33\xbf\xa5\x3d\xad\x31\x08\x82\x94\xab\x8b\xf4\xbd\xf1\x4d\xda\x6c\x97\xf6\x03\x81\xab\xe8\x9c\x5b\xa6\x80\xf6\xef\x5a\xc7\xad\x0b\x50\x5e\x6c\x00\x73\x0b\x65\xca\xb3\x01\x11\x8f\xf6\x89\xaf\x55\x6b\x92\x1a\xb9\x01\x94\x4b\x9b\x0e\x9a\xea\x40\x24\xd0\x15\x58\xfc\x2c\xfa\xfb\xd5\x24\xd2\x45\x07\xda\x78\xcf\xeb\x34\xe7\x6f\x7d\x86\xaa\x2f\x00\x88\xfd\x88\x5a\x6f\x67\xd3\x61\x44\x92\xd0\x08\x26\x22\x26\xef\xe9\xf9\x87\x7b\x09\x22\x0d\x25\x82\xd9\x0a\x26\x38\x40\x46\x2f\x41\x03\x1d\x4a\x57\xbb\x06\xef\x88\x55\xb0\x2a\x33\x83\xc9\xa3\xa9\x32\xbc\xed\x79\x51\xa7\xda\x1e\x56\xad\xdd\x3b\x39\xfd\x35\x55\x5c\x98\xad\xd0\xe2\xdc\x46\xb7\x64\x41\x8c\x99\xb4\xe5\x6a\x1d\x78\x37\x97\x1a\x30\xc6\xea\x1a\x05\x47\x7c\xd9\x0d\xaf\x52\xb9\x3d\x95\x2d\xdb\x7e\xd3\x04\x96\x55\xa9\x79\xc7\x9b\xf4\x4b\x7d\xc9\xdf\xcd\x40\x7b\xbf\x48\x18\x6d\xb0\x36\xb0\xbe\xe8\x90\x31\x3a\x02\x0f\xd3\xa8\x3f\x1f\xfa\x38\x45\x1d\x13\x66\x49\xb0\x8c\x6b\xf9\xc8\xf3\x6b\xfa\xe0\xde\x27\x4b\x3c\x8d\x85\x15\x5c\xa9\x55\x63\x64\x0c\xbf\x42\x92\xc8\x30\x74\x78\x4d\xcb\x69\x9e\x1f\x6e\xcb\xe2\xf8\x00\x07\xee\x54\x6c\xa5\xe6\xbe\x8f\xfd\x6e\xf8\xe7\xa1\xa3\x43\xd2\xc2\x07\x5c\xd8\x3b\xe0\xc7\xae\x78\x51\x0b\x66\xa8\x30\x4d\x4c\xf0\x98\x9e\x8f\x7f\x0c\xde\x5b\xc8\x88\xd3\x36\x4a\x7c\x03\xf5\x84\xf4\xa2\xd4\xe0\xc7\xd2\x73\x95\xdc\x98\x32\xb3\x85\xfe\x06\x2e\xfa\x2b\xad\x5f\x07\x19\xe2\xf6\xb2\x04\x0d\xab\xd9\xbe\x59\x90\x7b\xec\xbc\x9f\xed\x17\xbc\x7d\x19\x88\x38\x1e\x9e\x37\x3c\x7f\x7b\xe5\xaa\x3f\xba\x3a\x0c\x65\xd4\x71\x8e\xa2\x7e\x48\xeb\x63\x7f\x6b\x67\x28\xcf\x8b\xb8\x6c\x23\xa1\xc5\xa9\xa8\x78\xb6\x98\x52\x75\x50\x9e\x17\xfb\x18\x85\xe1\xad\x12\x6e\xf3\x49\xa0\xea\xc2\xea\x6d\x47\x43\xbc\x7b\x80\x7a\x9b\xe6\xcd\x3e\x62\xa7\x87\xf2\xfc\xc4\x90\x9c\xa5\x95\x2d\xa9\x45\x65\x5f\xe5\x9a\x03\x61\xc8\xcb\x0e\x50\x3f\x67\xaa\xa5\x5f\x57\x5e\xa0\x04\xfa\x82\x06\xdb\xb9\x79\xb9\x71\x0d\x21\x13\x08\x80\xd5\x48\x03\x89\xc9\xd7\x35\xea\x23\x0c\x9f\x3d\x8c\x7d\x8c\xd1\x99\xe5\x38\x0d\x6f\xbd\xfa\xef\xa4\xa1\xd4\xdc\xcb\x9c\x7b\x56\xc9\xbc\x2c\x8e\x45\x33\x5a\x3c\xdb\x40\x0e\x1f\xbd\x70\xfb\xe8\x11\x64\x88\x16\xf1\x43\x71\xa8\x82\xff\x13\x3e\x40\x79\x21\x30\x34\xfa\xee\x00\x75\x06\x31\xa9\xd3\x98\x47\xc1\xe8\x0b\x84\x9a\x22\x21\x51\x0e\x1f\x77\x2d\x80\x5c\x79\x24\x61\x18\xe8\xd2\x20\x5f\x67\x59\x36\xe7\xb9\x42\x19\xe0\xea\xc6\x48\xcb\x8f\x06\x8d\xa8\x20\x4c\xfa\xc9\x9f\x34\xaf\xad\x41\xb1\x81\x6a\x82\xa5\x7e\x6a\xe3\x57\x1e\xf5\xa5\x0e\x7b\x80\xc5\x6a\x26\x0d\x05\xde\xe8\xa1\x69\xc0\xb1\x8c\xb2\x55\x8c\x6c\x55\x8c\xa7\xc4\xe7\x47\x23\xc3\x3c\x8a\xc4\x4e\x27\x28\xeb\x73\x29\x06\x39\x22\xe5\x31\x2a\x93\xd0\xc1\x55\x2f\xed\xde\xa8\xbc\x88\x02\xfa\x55\x5f\xd2\xc5\xb6\x7b\x53\x5b\x5a\xa6\xbc\x38\x8a\x7c\x1b\xf4\x6f\x2b\x30\x3a\xb5\xb2\xe1\x4b\xc5\x91\x36\x86\x06\x3f\x8a\x0c\x4a\x78\x87\x2f\x0a\x2a\x94\x97\xf8\xc6\x15\x3c\x5d\x27\x7c\xc6\x3d\x09\xc5\x7d\x8d\xe7\x79\x71\xce\x25\xfc\x4c\x25\xda\x2f\x3d\xdf\x59\x79\x49\xec\x23\x29\xd8\x23\x2a\x68\x3f\xa6\x39\x0c\x36\xda\x29\xac\xb5\xf2\x12\x4d\xd1\x6a\x5e\xfe\xcf\x39\x2d\xbe\x42\x31\x7c\x97\x50\x57\x1e\xa7\x80\x5f\x42\xa7\x87\xd7\xfa\xd7\xaa\x7e\x7d\x2c\xc4\x17\x4b\x42\x10\x19\xf7\x47\xbf\xf9\xd5\x0e\xd6\xdd\x5f\x73\x82\x28\x5b\x11\x67\x4b\x31\x7a\x3a\xfa\xca\x13\x32\x31\x2a\x23\x29\x94\xfb\xde\xf9\x7d\xbd\x8c\x27\xff\xea\xee\xa2\x22\x0c\x5e\x9d\x5a\x05\x34\x33\x5d\x9d\xe4\x4a\xfb\x73\x52\x1b\xee\xc5\x2d\x40\xd6\xae\x2d\x60\x1c\xcb\x25\x6e\xd2\xba\x2c\x8a\xba\xdb\x9e\x9b\x26\x61\xf5\x66\xea\xc6\xd7\x75\x8a\xbc\xbb\xdd\xa3\x01\xf0\x2a\xbf\x0f\x98\x50\x1e\x44\xd4\xb1\xa0\x3f\x5e\x3a\xd8\xb4\xf2\x40\x24\x22\x69\x63\xd2\x4e\xf1\x1e\x63\xee\xc3\xf9\xae\xbd\x00\xeb\x4c\xf7\x26\xab\x6d\xe4\x89\x47\x5d\x22\xea\xaa\x4c\xf1\xe0\x4c\xab\x7a\x3f\x51\x11\xa5\x7c\xdf\x8b\x5b\x61\xbe\xaa\x32\xee\xd8\x1f\xa3\x2e\x81\x42\x11\x55\x7e\xae\x5f\x21\xaf\x53\x69\x0c\x3c\x28\x07\x33\xd2\xf7\xa9\x29\x6e\x2f\xf9\xc7\x16\x72\x65\xb8\x9b\x06\x4f\xe5\xfb\x91\x41\xb7\x2f\xee\x66\x8f\xcb\x9e\x73\xa9\x7c\x5f\x7b\x28\x09\x56\x94\x5c\x66\xd0\x95\xc5\x28\x3f\x20\xdc\x0b\x5c\x9e\x01\x23\x7d\xee\x64\xfa\x96\xf8\x46\xf9\x41\xcc\x10\x69\xd7\x16\xe2\xae\xd4\x7e\xb9\x99\x47\x81\x8f\x7a\x90\x55\xfb\x03\xb1\x0a\xda\xf0\x0e\x92\x6d\x6e\xd3\xc3\xb5\x35\x3a\x7c\x93\x40\x30\x44\x4e\x19\xfd\xf0\xa2\xc8\xaa\x45\x91\xb7\xcf\x1c\x32\x63\x99\x6c\xd3\xe3\x29\x83\xd9\xee\xb1\x6d\xe0\x01\xe2\xb0\x5f\xd3\xc3\xab\xad\x25\xbe\x22\xc2\x52\x3e\xa1\x1e\x72\x7d\x6d\xcf\x6f\xe9\x85\xbf\xa5\xed\xdf\x65\xac\xec\x4c\xdb\xd6\xcd\x04\x1e\x87\x31\x94\x4f\x3d\x8a\x34\x70\x38\x05\x55\xf1\x91\xa3\xf6\x48\x9b\xc8\x55\x3e\x25\x3e\x56\xe3\x67\x69\x55\x63\x90\xeb\xcb\x04\x9d\xf2\x23\xdf\x4a\xcb\xf0\xcc\x51\x77\x8c\xad\x01\x3f\x26\x81\x13\xca\x5e\xf3\x0b\xb4\x14\x1f\xd7\x4a\x4e\xca\x8f\xb9\x9f\x18\xd1\x36\x55\xcc\x2a\x68\x9f\x29\xa1\x86\x33\x81\x2b\x65\xe0\x99\x57\xc7\xf3\x84\x07\xab\xfc\x44\x46\x18\xc2\x5d\x8e\x29\x6e\xff\x57\xa7\xae\x9f\x40\x90\x0c\x35\x48\x0d\xbf\xac\x33\x60\xaf\xc9\x08\x9b\x6b\x68\x62\xd1\x5d\xcb\x4a\x96\xc5\xc7\x55\xbb\x6c\x83\xe2\x15\x94\x0e\x85\x3b\x9c\x43\x9c\x81\x91\xf0\x33\x75\x8d\xbb\x62\xa2\xa4\x51\xf9\x22\x60\x68\xce\xea\x54\xf4\x4a\x0b\x7b\x8e\xa7\xf2\x85\x0a\x9d\x04\xb2\x29\x1d\xb6\x51\xdc\xef\x82\x0a\xca\x97\x3c\x71\x01\xeb\x9e\x1c\xf4\xc8\xd6\xf0\x95\x47\x31\x94\x27\x31\x46\x5f\xef\x8a\xc7\x34\x4f\x5f\x56\xa3\xf7\x55\x91\xb6\x22\x06\x75\x9d\xa1\x77\xd3\xa6\x44\x94\x0f\x49\xc4\x7d\x0b\xde\x1c\x00\xd3\x5c\x3b\x67\x98\xd9\x38\xee\xeb\xfe\x96\xa0\x3d\x86\x3c\xd8\xcb\xfa\xb5\x31\x8a\x37\x8e\xea\xd7\x77\x3f\xaa\x29\xf3\x1d\x26\xe1\x54\xc2\xfe\xed\x22\xf7\xa9\x2c\xf2\xf4\x7f\xf6\xc8\x82\xb0\x57\x90\x17\xc7\x34\xc7\x6c\xc8\xe0\x79\x03\x2f\x60\xc8\xca\xd7\xaf\x8e\x42\x74\x8e\x7b\xa8\xc0\x23\x04\x5d\x94\xd9\x59\xd6\xe7\x6a\x5b\xc3\xe9\x6f\x4a\x39\xdb\xeb\x7d\x5f\x46\x96\xec\xfd\xd5\xdd\xd3\x97\x80\xf3\x7c\xdf\x98\x5a\xd3\x66\x42\x10\xf8\xbe\x62\xed\x1a\xaf\xcf\x83\x32\x25\x15\x04\x90\x18\x20\x65\x06\xbc\x9c\x59\x04\xae\x9a\xe5\x6a\xcb\x33\x5e\x5e\x46\x89\xf0\xc1\xa7\x0c\x02\x4d\x5a\x61\xaf\x83\x29\x93\x93\xbf\xab\x4c\x53\x41\xe8\x29\x9c\x26\x1f\xa0\xba\xb4\x91\x0a\x42\x96\xb8\x03\x06\x59\xc2\x4c\xfa\x68\xf8\x65\x03\xe2\x05\xf8\x32\x69\xee\x78\x3f\xda\x06\xe1\x80\x47\x0f\x8e\xe4\xa8\x4b\xbf\xa8\x80\x04\xa6\x68\x34\x2b\xf2\xc3\xfe\xc4\x4b\x27\x1a\xd6\xb4\x70\xa7\x9b\x7a\xc3\xab\xa1\x90\x62\xdf\x8c\x0b\x08\x8f\xb9\xdf\xd2\x01\x7e\xcd\x42\xab\x02\x22\x15\x32\x01\x15\xf9\xf2\x13\xe4\xb9\x86\x47\xa8\xb0\x80\x6c\xba\x3b\x55\x91\x6c\x11\xc7\xd5\xae\x68\x2b\x08\xfe\xae\xdf\x6d\xf5\x73\x7a\xcf\xca\xc2\x00\xf1\xc5\xf3\xe7\xe7\x87\xc5\xf3\xaf\xa7\x1e\x05\xad\x0a\x18\x11\xdc\xec\x8e\xf0\x79\xa5\x8d\xa8\x02\x16\x1b\x0f\xcf\xa2\xbf\xe6\x45\xeb\x8e\x05\x11\x48\x4c\x35\x9f\x1a\xfb\xc6\x37\xc1\xc6\xd6\x51\x56\x41\x1c\x31\xdc\x8e\x6b\xa8\xea\x5d\x79\xb9\xc3\x04\x5e\xbb\x2b\x07\x49\x0c\x98\x18\x14\x48\x88\x67\x87\xe6\x8b\x31\x49\x84\xa9\x5a\xc2\xe8\xdd\xcf\xe2\xd3\x72\xa8\x5e\x3b\x5d\xb1\xbb\x40\x9b\x92\x4b\x93\x22\x7e\xd9\x2e\xea\xc2\x5f\xee\xee\x47\xcb\x94\x7b\xda\x72\xed\x21\x70\xfd\x01\xd3\xc1\x88\x60\x41\x18\xc3\x17\x0f\xc3\x49\x84\x76\x94\x4e\x73\xd5\x63\x9e\x1d\x6e\x6c\x01\x07\x11\xf3\x2e\xef\x30\x90\x52\x19\xde\x4f\x24\x52\x7a\xce\x02\x31\xbe\x4d\xab\x6a\x38\xee\x2b\x93\x10\xb9\x84\xdf\x0d\xcc\x02\x76\x97\x13\xa0\xb6\x32\xe6\xdf\xae\x4d\xdf\x40\x31\xe6\x9b\x7a\xaf\xdc\xa4\x73\x87\xf7\x53\x56\xf4\xc3\xd9\xd0\xbb\x57\x30\x59\xd6\x7e\x82\x44\x05\x4a\xcb\x10\xe9\x66\x8b\x73\xf9\x7f\x4e\xa1\xd9\x7b\x69\x12\x20\x85\xa2\xd5\xa6\xe2\x83\x4d\xaf\x7b\xf2\xd0\x4b\x0c\x1b\xf7\x4d\x5a\x4b\x38\xbb\x6d\x3b\xf4\x69\x24\x7a\x35\x2d\xbd\xa3\x65\xf8\x6a\x61\xe0\x81\x8e\x1d\x62\x6a\x5b\x17\x25\x3f\xc0\x7e\xb5\xbe\xdd\xba\x3b\x05\x8c\x39\xf4\xd5\x83\x29\x5f\x78\x16\xff\x5e\x7d\xf1\xd5\xc3\x00\x22\xd1\x27\xb9\xfc\x63\xd2\x70\x0b\x89\x0c\x20\x74\xc1\x14\x9b\xf1\x9e\xe5\x6a\xf3\xb4\x19\xce\x8f\x90\x68\x93\x10\x52\x3c\xcd\x2e\x18\xe8\x1e\x7d\xeb\x90\x86\x21\x26\x4a\x1c\x5f\x02\x0a\x98\x19\x81\xe5\x16\xeb\xdb\x1b\x2f\xaa\x19\x65\xce\x34\xdb\xcb\x73\x55\x17\x47\x28\x5d\x09\x89\xfb\x94\x21\x0b\x23\xdc\x8d\x9a\x61\x2d\xd2\xfc\xcf\xf9\x88\x81\x13\x7b\x04\xde\x20\x90\x8e\x21\xa7\x5b\xde\xd5\xe0\xaa\x90\xc5\x1a\xd1\x76\x5c\xd7\x50\xf6\xdd\xa9\x90\x81\x91\xd0\xc0\x8a\x80\x2f\x0a\xcc\x6d\xd7\xc8\x72\xac\xe2\x60\xe5\xfc\x00\x7d\x8c\x8a\xdb\x87\xae\x24\xc7\x54\x18\x7b\x01\x72\x83\x20\x30\x0c\x5d\xfc\xaf\x20\x92\x53\x56\x9e\x7b\x16\xf3\x67\x8b\x5f\x51\x61\xcc\x23\x0c\x12\x99\x79\xd9\xd6\x10\x18\x81\xba\x35\x6a\x8b\x0c\x9f\x3e\x21\x3a\xb1\xdc\x33\x86\x22\x2f\x2f\x14\x8c\xbe\x72\x12\x1b\x09\xf4\x2d\x02\x98\x1c\x60\xe5\xeb\x7a\x65\x15\x8a\x40\x21\xa5\xce\x9a\x5f\xfe\xdc\x15\xcd\x96\x74\x5d\x20\xe5\xba\x6a\xa3\xb1\xec\x16\xef\xf6\x5c\x9e\xca\xb4\x82\x75\x81\x56\xe1\xe4\xfa\x9c\x4e\x69\xa8\x50\x92\x40\x05\x8e\x5d\xf8\xa6\x2c\x2a\x04\xa0\xb8\x6f\x2a\x69\x82\x10\xd7\x63\xaa\x94\xf1\x0b\x7a\x42\x2e\x2a\x94\x4c\x61\x6c\xd3\x18\x8f\x0f\x67\x75\x3e\x7e\x03\x99\x53\xa1\x0a\x02\x74\x51\xe7\x69\x9d\xfe\x07\xf2\xe7\xfc\xaa\x98\x79\x7c\x01\xa3\xc8\x6a\x72\xb8\x72\x66\x42\x25\x8d\x16\x48\x05\xf5\x6e\xf3\xe8\xe3\x54\x35\xf2\x34\xfd\xc5\x01\xd0\xb2\xdf\xac\x79\x8d\x85\xa2\x5f\x24\xeb\x7e\x2f\x8e\xad\x42\xcd\x83\x04\x3a\x71\x9a\x5d\x71\x57\x64\xad\x6e\xff\x70\x02\x68\xc9\x5d\xbd\x2d\xd6\xaa\x6f\xe0\x54\x8c\xa8\x2e\x14\xf1\x7c\x43\x16\x5d\xa7\x47\x98\x21\x1c\xb7\xcb\x76\x2b\xe2\xd1\xd8\xd1\x3e\x6d\x8a\x0c\xe6\xfc\xc4\x85\x11\x3a\x3d\x0f\x72\xed\x63\x4e\x36\x45\xbc\x58\x90\x41\xf1\x11\x7e\x15\x83\x25\x18\x3e\x27\xf1\xc0\x94\xbf\x3b\xa4\x99\x32\xf1\xa8\xb1\x3f\x46\x3c\x10\x26\x09\xbb\xda\xcd\x9e\xe6\xcf\x4e\x09\x53\x11\x3f\xf0\x30\x82\x91\xe6\xd5\xd5\x96\x42\x7c\x29\x4d\x00\x06\xa3\x49\xb3\x73\xfd\x5a\x94\xe9\x7f\x40\x0d\x61\x9f\xc3\x55\x4e\x02\x16\x23\x61\xce\xea\x69\xb7\x59\xae\x57\x8b\xfd\xcf\xe7\x97\xf9\xfd\x72\xd3\x27\x9c\x51\x24\xe0\x1a\xad\x8c\x9e\xfa\xb5\xab\x23\xb1\x3d\x42\xa6\x22\xb3\x31\xe6\xd5\xf9\x08\x63\xe0\xb8\xdb\x00\x08\x09\x81\xda\xac\xde\x2a\x4f\x7b\x60\x44\x45\x08\x65\x08\x80\xcd\x78\x55\x3f\xf0\xf2\x00\x55\x7d\xff\xbc\x78\x58\x6e\xdc\xfe\x66\xfb\x51\x8f\xe0\x28\x22\x8a\x76\xb9\xbb\x2f\x7b\x4a\xd5\x8a\x50\x9f\x63\x18\xf9\x3f\x07\xa8\x7b\xc5\x76\x8a\xd0\x88\xe3\x1c\x9e\x17\xc7\x13\xe4\x95\x61\x0b\x81\xbc\x5e\x7e\x1d\xef\x23\x34\x91\x88\x41\x7e\x3c\x67\x75\x0a\x9f\x55\x63\x88\xb4\x53\x86\x45\x1e\x02\x1a\x52\x59\xd8\x04\x73\xf7\x14\x51\xa0\x31\x4a\xfe\x89\xd1\xec\x96\x47\x75\x78\xf7\x88\x4a\x84\xde\x3e\x14\x87\x99\x94\x50\x55\x86\xd9\x61\x84\xb8\x9b\x3e\xe1\x49\x14\x13\xcf\x46\x2d\x61\x99\xcb\xf2\x72\x6a\x4c\x1f\xf8\xac\xdb\x47\x10\x04\x6c\xc6\x61\xb6\xda\x2c\x36\xcf\xeb\x6b\xc1\x72\x45\x62\x42\xd0\x74\xd9\xa7\xd5\x64\x9e\x5b\x91\x38\xa2\x8e\xdb\xd6\xcc\xef\x2b\x1b\xb9\xb7\x18\x62\x25\xd1\x74\x2a\xf2\x56\x05\xf9\x7f\x93\xb9\x52\x24\x09\x3d\x4f\xd9\xfc\x6b\x1f\x09\xf2\xbb\xcb\x80\xfa\xd6\x57\x6f\xc1\x37\x2f\xa7\x43\xc9\x95\xf1\x2e\x6e\x2e\x8f\x85\x82\x41\x55\x8a\xb5\x62\x09\x8f\x13\xdc\x67\xb6\x5c\xc3\x16\x41\x4c\x6e\x04\xb9\xf6\x69\xd2\x12\x03\xe1\x5e\xdd\x79\xc4\x44\xfa\xc4\xb3\x01\xeb\x2f\x58\xbe\x5c\xc7\x80\xc6\x56\xf6\x67\x18\x3c\x20\x92\x70\x8f\xf4\x59\x28\x0d\x4d\xe4\x82\x5f\x96\x79\x3b\x95\xa4\x48\x30\x72\xf7\x38\xfb\x73\xbf\x7c\xda\x6d\x56\xcb\x6d\xdb\x04\x31\xa2\xa2\x8f\xfc\x73\x95\xbf\x2f\x5b\x27\x95\x48\xcd\x3c\x93\xe0\x4e\x33\xb5\xd8\xda\x05\xb4\x70\x29\x19\xa2\x42\x1f\x1d\x3f\xa4\x73\x1c\x4a\x26\xba\x1e\x24\x40\x3a\x9a\x3d\x57\xea\xae\xe4\x5a\xa7\x75\xfa\x0d\x0e\x4c\x11\xc5\x23\x5c\xbd\xf3\x22\x4d\xf3\x6b\x62\x61\x45\x14\x28\x6e\xb3\x58\xb3\xb4\x44\x3b\xb9\x83\x53\xb5\x43\x02\x7e\x88\xa1\x0a\x28\x65\xe0\xed\x36\xb7\xbb\x3f\xfa\xdf\x0a\x7c\x10\x86\xff\xa3\x38\xed\x0f\x5d\x80\x91\x68\x8f\x20\x8f\xde\x7a\xfd\xd7\xb7\x4f\xa9\xfd\x00\xc3\xd9\x26\x31\xd4\xba\xad\x0e\x5d\xf0\x6d\xb0\x85\x68\x3f\xc6\x7a\x30\x99\x15\x15\xa0\x34\x6c\x76\xb1\xaa\xb8\xa6\x07\xf5\x04\x60\x1e\x85\x0f\x85\xb0\xa6\x0f\x5c\x1a\x04\x44\x85\x7d\x7d\x79\xf8\xb8\xc2\x8c\x2a\x1a\x06\x41\xe8\x48\xa2\x4c\xf4\xc2\xf2\xe5\xa8\xbf\xc1\xba\xa4\x68\x48\xbc\xa4\x35\xff\x3e\x45\xd1\x0b\xcd\xb5\x3d\x38\xf7\x4c\x1c\x85\x8b\xac\xb1\x9f\xca\x56\xe0\x5b\x51\x92\x00\x22\xbe\xeb\xb6\x36\xbc\x42\x0a\x47\xd5\x76\xe0\x21\xda\x97\xf3\xcd\xf3\xaf\xc5\xfe\xd7\xec\xe7\xd2\xdf\xaf\x97\x9b\xd5\xf3\xc2\xf5\xa0\x5e\x42\x8c\xb3\x7d\x38\x64\xd0\x5c\xdd\xc5\x20\x28\x8d\x68\x8c\x5c\xc0\xcd\xca\xfb\x3a\xa6\x42\x69\x62\xe2\xe5\x32\x4b\x9d\x3c\x9d\xa2\x54\x33\x62\x52\x8b\x9f\xa0\x6e\x01\x56\x79\x5b\x18\xab\x28\x23\x1e\x65\x5d\xfc\x6e\x5d\x36\x96\x66\xf7\x62\x8c\x68\xdf\xce\xc7\x0a\x61\x72\xa7\xeb\xed\x91\x46\x84\xb9\xe2\xf8\xd5\xfc\x79\x55\x0d\xa5\xec\x14\x8d\x78\x8c\x0c\x18\xa7\x12\x56\xb2\x30\xad\x6d\x1b\x28\x9c\x0c\xf7\xcf\xeb\xe5\x77\x93\x92\xc6\x5e\x82\x49\xbc\xfd\xfd\xf3\xc3\x02\xca\x6a\xcd\x2f\x18\x28\x73\xcd\x20\xf0\x68\x7d\xe5\x9d\xee\xc0\x04\xb4\x5c\xd1\x84\x27\x88\x3e\x38\x36\x53\x93\x59\xee\x70\xa3\x8b\xe1\xee\xc5\x13\x41\x7c\xbb\xbd\x5e\x99\xae\xbf\x0b\xbd\x4e\x7f\x18\x21\x13\xa4\x74\xb2\xf1\xd1\xbd\x25\xe1\xae\x46\xd3\x58\xfa\x89\x6f\xcd\x24\x53\xeb\xde\xd7\x77\xb2\x7d\x94\xa0\x78\xb2\x2f\xf8\x01\x32\xee\x0e\x5a\xaa\x24\x0d\x63\x97\x9d\xfc\x07\x97\x6f\xa7\x62\x1a\x84\xa9\xa8\x02\x89\x95\x66\xc7\xe6\xc0\x3e\x65\xf0\xb9\x37\xd8\x97\xd1\x0f\x69\x66\xe4\xb5\x90\xfb\xa2\x79\xea\xb4\x3d\xd6\xa9\x16\x92\xdb\x88\xe4\xe3\xa5\xaa\x87\x09\x12\xaa\x41\x52\xbb\x9c\xba\x98\xb2\x0b\x8e\x0c\x7e\x84\x79\xcc\xc7\xea\xd7\x1b\xa8\x9f\xdf\xa1\xcc\x9c\xf2\xb6\x62\x9e\x60\xb2\x45\x94\x1e\x6d\xe4\xfb\xd7\x75\x11\x94\x62\x1e\x04\xc8\x9b\x73\xbb\xba\xdd\xfd\xb5\xdf\xdd\x3f\xbf\x6c\x67\x4f\x8b\xed\xfe\x61\xf5\xb8\xda\xb5\xb7\x03\xc3\xf5\x7c\x80\xfa\x36\xcd\x30\xc2\xb2\x4d\x1d\x60\x48\x31\x3f\x51\x08\x7e\x7c\x2d\x32\x03\x49\x98\x34\x28\x98\x2f\xcc\x77\x44\x54\xc4\x3b\xcf\xac\x6a\xfc\xe0\xc4\x62\xbe\x02\xac\x39\xb6\xe5\xed\x95\xc9\xe6\xf4\x0c\x41\x16\x78\x7e\xe8\x1c\x5b\x2c\xcb\xed\x62\xdc\x2c\xa4\xd4\x1e\x4b\x97\xe5\xe1\xd0\xfe\x95\x99\xe7\x2b\x41\x6b\x28\x47\x45\xa9\x8a\x85\x3c\xc1\xfd\x6f\xb3\xfc\xb1\x9b\x84\xfc\x28\x46\x84\x44\x9e\x2c\x83\x30\x18\x6e\x30\x8c\x06\xa6\xfe\xcb\x32\xd5\x55\xcd\x7a\x37\xda\x39\x9d\xdd\xc2\x28\xe3\xe8\x97\x3e\xc1\xc7\xba\xe8\x55\x83\x0e\x66\x17\xa3\x22\x40\x36\x9b\x57\x5e\x35\x56\x64\x06\xdd\x36\xc8\x28\x84\x1a\xdc\x3e\xe9\xa4\xe9\xe7\x17\x99\xb5\x33\x8b\x31\x1f\x0c\x32\x29\xb5\xe2\x0f\x5f\xd0\xb4\xb9\xee\xd4\xc7\x10\x18\x02\x13\x97\xf5\xeb\x4a\xdf\xa2\x9c\x9a\xbb\x5d\x1c\x8a\xc4\x70\xcc\x57\x45\xa6\x9c\x88\xd6\xac\x1d\xed\x98\x70\xcc\x5f\x6c\x96\x4f\xcb\xe5\x8f\xcd\xf3\xe3\x97\x99\xf3\x6f\x6d\x2b\x16\xd3\xd8\xac\x29\x94\xe3\xe8\x48\xff\x9c\xbd\xb8\x2e\x61\x71\xf7\xaf\xba\x58\xdc\xfd\x6b\x7a\xef\x66\xb1\x00\x34\x45\x1f\x8a\xc3\xba\xc8\xb2\x05\x98\x91\x1b\x4e\xad\x24\xd0\x06\xb7\x0c\x5c\x3d\xf2\x34\xbb\xb9\x18\xa8\xda\x20\xb2\xe0\xf2\x06\x2c\x89\x12\xb0\x6a\xae\x37\xad\xcb\x3f\xfc\xd5\x24\x8e\x11\x54\xcd\x95\x72\x1e\xc4\xf7\x2f\x9a\xe8\xfe\x4c\x99\x17\x59\x51\x6e\xba\xe1\xe6\x34\x01\xe5\x3c\x97\xf7\x22\x95\x30\x98\xdb\x9c\xea\x48\xd8\x12\x8d\xb4\x84\xa7\xa2\xee\x23\x2e\x15\xe3\x8a\x98\x88\x73\x99\x1e\x0e\x50\xce\xce\x75\x61\xa3\x96\xae\x87\x20\x86\x88\xa5\x38\xd7\xb2\x38\x82\x99\xa3\xdf\x5a\x24\x4c\x48\x23\x25\x75\xe4\x9f\xbb\xb4\x2d\x6a\x53\x4c\xfa\x1a\xc5\x72\x30\x6a\xf2\xf6\xbb\xbb\xc8\x38\xc4\x30\xd3\xea\xe9\xe7\x72\x7e\xff\xdd\x51\xc5\x64\xcc\x88\x8b\x86\x2c\x2c\xa8\xa2\xfd\x51\x1d\x28\xeb\x85\xef\x0d\xe4\x79\xaf\x5b\x73\x99\xa9\x20\x06\xdd\xee\x79\x86\xb2\x33\x1f\x04\x40\x99\x92\x51\x68\x7d\xc3\x9b\x4b\xc6\x3f\x1a\x43\xa3\xd9\x5a\x56\xf9\xee\x15\x6e\xcf\xf5\xb9\x84\xdb\xa2\x7c\x04\x8c\xf7\x39\x9a\x10\x77\x31\x78\xcc\xe1\x92\xcc\x31\x6c\xb8\x8f\x5c\x6b\x18\x61\x4d\x52\x63\xce\xfe\x2c\xce\xf2\xb5\x57\x64\x32\x1a\x0d\x10\xa6\xb4\xa9\x82\x7a\x51\x9c\x1b\x83\xa8\x59\x7f\x5b\x38\x20\x8b\x4a\xc6\xab\xd7\x09\x50\x99\x62\xda\x33\xdc\xdd\x66\xf2\x60\x0a\x74\x72\x47\xd7\x7e\x44\xcc\x36\xeb\xc2\xcb\x6d\x1c\xfa\x8f\x6f\x62\x47\x4c\x87\x11\x86\xac\xce\x15\x94\x1d\x3d\x9d\x6b\x14\x5e\x6c\x23\x2f\x37\x77\x7f\x5a\xce\xb1\x29\xea\x6a\x15\xf9\x1e\xc3\x4c\xc4\xde\x84\xe0\x9a\x59\x36\x5d\xc2\xab\x22\x9f\xfb\x0e\x35\xef\x08\xeb\xbe\xd2\x64\x54\x51\xe0\x05\x46\x64\x3a\x2d\x07\x5e\x54\x14\x04\x3c\x74\x2a\x6a\x69\x7e\xd8\xdb\xc2\x9a\xbd\xe4\xd5\xab\xe0\xf2\x6d\x6f\x72\x13\x7b\xf4\x45\xf6\x1f\x3c\xad\xf7\xea\xdc\x97\x23\x50\x51\xc0\xb9\x0b\x45\xf6\x15\xef\x07\x53\x33\x0a\x99\xe1\x59\xfc\x00\x78\x5b\x17\xf5\xf2\xf3\x94\x0e\xef\x42\x68\xc0\x4d\x79\xdb\xcf\x1e\xf4\x23\x8a\x7c\xa2\x85\xa3\x5d\xce\xb2\xe2\x63\x4a\x6b\xd7\xf5\x8d\x19\xb7\xe0\xae\xbb\x33\x54\x75\x0f\xe3\x10\x45\x32\xc6\x44\x0d\x62\xef\x9c\x4f\x65\x8b\xbd\x1b\xfb\xd3\xcd\xc5\x28\xf6\x00\xf7\x53\xcb\x63\xb0\x37\xd5\x0a\x23\x7b\x29\x8a\x85\x31\x9a\x71\xf7\x7f\x4a\x5f\xd3\xcc\xc1\x20\x55\x14\x83\x26\xcd\x1d\x6e\x7e\xfc\xe8\x3b\x6d\x51\xe2\xb1\xd0\x1b\xca\xe9\xdf\x96\xc5\x7f\x06\x69\xb9\x28\x09\x18\x32\x01\x6c\x96\x8b\xe5\xf2\x71\xff\xb8\xdc\xdd\xb7\xa6\x7a\x94\x48\x1f\xf3\xe8\xfc\x83\x5f\x76\xc0\xdb\x5f\xe4\x3e\x47\x86\x9f\x97\xf9\x50\xff\x72\x62\x8f\x88\x78\xe8\x63\x59\xc4\x91\x7f\x5a\xd0\xcc\x7f\xf5\xb1\x33\x11\x0f\x0d\x43\xbe\x48\xeb\xba\xe4\xef\x90\x7d\x0e\x5e\x82\x27\x12\xc9\x7c\x1e\xb9\x7c\x4d\x73\x18\xb4\x09\xcf\x43\x67\x64\xb6\x5e\xb5\x7f\x0a\x3c\xea\xf7\x90\xc3\xcb\xcf\xf4\x6a\x2c\x05\x24\x48\xd1\x85\x2c\x32\x75\xe7\x61\xb9\xa8\x54\x24\x03\xee\x1b\x76\x0c\x31\x88\x35\x45\x32\x0a\x68\xec\xaa\x6f\x9a\x79\xfd\x58\xe4\x70\x19\x29\xe2\x0f\x57\x8d\xe4\x46\xea\xf6\x1f\xdb\xe7\xa7\x13\xaf\x5f\xf7\x8d\x4f\x33\x35\x5c\xa3\xeb\x14\xe1\xac\xf5\xc9\xf7\x15\x94\xef\xe9\xd5\xe2\x05\x0a\x2e\x4a\x79\x9b\xf1\xc3\x9a\xa7\xe5\x20\x1f\xd5\x0b\xc5\x44\x00\x40\x3a\xac\x2c\x02\x4e\xaf\x1d\x9c\x48\x7b\x1e\xf5\x4c\xe5\x91\x02\xa3\xb1\xa2\xfa\xb3\x45\xfb\x0c\x47\x5c\x97\x80\x88\xfe\xe1\xf3\x68\x1e\x38\x98\x5d\xf3\x03\x88\x3b\x72\x4d\xa0\x23\x23\x6f\x63\x10\xd5\x18\xf3\xee\x6b\x41\x98\x7e\x98\x65\x30\x1c\x20\x19\xc6\x04\x40\x99\x6d\x73\x0a\x6f\xae\x62\x4f\x19\x07\xbb\x82\x7a\xf9\xb4\x30\x30\x52\xdb\xe4\x2b\x66\x44\x4b\x8b\xbb\xb2\x38\x9f\x4c\x8d\xa4\x81\x12\x56\xdb\x33\xc6\xd7\xc6\xdf\x3d\x0e\x3c\x82\x4e\xc9\x1d\x58\x4e\x7d\x77\xb3\x40\xe8\xa8\x2f\x7e\xdd\xcb\x29\xda\x58\x44\x1c\xb2\x20\xf6\x5b\x0a\xa3\xc1\x69\xed\x7a\x00\xc5\xfa\xe4\x35\xe4\x15\x42\x24\xdb\x4d\x27\xa6\x3e\x47\xc2\x54\xd4\x59\x2e\x57\x55\xcb\xe9\xd5\x99\x45\xfd\xe4\x72\x4c\x7d\x19\x79\x7d\x80\xe6\x0d\x6f\x9d\xba\x98\x12\x82\x24\x13\x4b\x75\x36\x81\xc6\xfe\x9a\x89\xa9\xe6\xb2\x9f\x53\x2b\x5b\x9b\x24\x66\xb6\xb2\xcd\x32\x3a\x9d\x6b\xf9\xba\x52\x9f\xcd\xc8\x8f\xde\x24\x12\x02\x8d\x9b\xfb\xd9\x6e\x7e\xbf\x7a\xba\xdb\xcf\x9f\xb7\xce\xfd\x88\x23\x48\x22\x65\x49\x18\x4d\x84\xf0\x59\xe3\x27\x98\x5e\x20\x71\x1c\x78\x26\x65\xdd\x58\xca\x8b\x61\xe6\x2c\x8e\x03\xb0\xce\x00\x6a\x69\xe5\x5d\x00\x37\x8e\x59\x12\xb9\x6a\x9d\xc6\xc6\xbf\x3b\x63\x90\xfb\x8f\xc1\xcd\x13\xc6\x80\xb4\xb1\x86\x4e\xcd\x4f\xc5\x49\x14\x2b\x6b\x0e\xce\x79\x95\xe6\xc5\x98\xa2\x66\x62\x2f\x8b\x93\x48\xe2\xe0\xfd\x58\xcf\xb7\x68\x8e\x1a\xb5\x9f\x36\x45\x17\x27\xb6\xba\x72\xbf\xd7\x69\xae\x36\xa0\xff\x18\x5e\xaf\x3d\xac\xf5\x9f\x29\x35\x65\x35\xc4\x02\x18\x4e\x11\x6e\xc4\xc6\xe1\x21\xcd\x01\xd1\xf4\xb6\x5d\x7a\x32\x92\xdd\xfe\x53\x6f\x6c\xa8\x68\x3e\x26\x97\x50\xb1\x94\x8a\x1a\x96\x1c\x71\x3e\xec\x9b\xb6\x71\x07\xad\x70\xdf\xd5\x19\x3f\x18\x1a\x3e\xdb\xa0\x48\x8c\x86\xa7\x95\x63\xda\xdd\x2f\x5f\x36\xa3\x6b\x35\x21\x01\xb8\xa2\x0a\xb7\x8b\x10\xcf\xb5\x26\x04\x23\x48\x55\xc6\xe5\x1b\x9e\x75\xf3\xd6\xd9\x8d\xb5\xd4\xe8\x9c\xb9\xf9\xb7\x3d\x9f\xa0\xc4\xb1\x44\x07\x1a\xcb\x24\x87\xb3\x4d\x83\x87\x39\xbf\xcd\xf2\x76\xb9\xd9\xcc\x1e\xf6\x37\xcf\x4f\x2f\xdb\xfd\xc3\xf2\xe7\xf2\xc1\x92\xc7\xa8\xc4\x0b\x42\x0c\xdf\x1c\xf8\x11\xee\x52\x5d\x37\x23\xd7\xf3\x43\x13\x3f\x32\xc5\x35\x6e\xc4\x60\x5a\x6f\x5f\x25\x7e\xc2\x89\x21\xe5\xc0\x31\xf9\x0a\x00\xf2\x37\xf2\x7b\x89\xaf\x38\x42\xe7\xc5\xf9\xb2\x4e\x3f\xc1\x84\xcb\x6e\x1d\x70\x89\x0c\xcd\x6f\x32\x7a\x8e\xc0\xf3\x11\xac\x54\x56\xa7\xfe\xfa\x4d\x02\x9f\xeb\x5e\x78\xae\x79\xc7\x5e\x44\x27\x09\x28\xc3\xc8\xf7\x13\x7c\x4c\x6a\x5f\x0d\x17\x5f\x73\xf8\x13\xcb\xd3\x80\x95\x31\x33\xcb\x0b\xff\x04\x9f\x75\x8f\xd6\x53\x25\x81\x10\xcc\x7e\x71\x34\x80\x7f\xc0\xa5\x6a\xdb\x34\x43\xf6\xc0\x03\x56\x8a\x9b\x32\x24\xd7\x16\x46\x14\x51\x64\xdc\xe5\x9f\xae\x6a\x48\xfa\x0b\x24\x09\xe3\x10\xb3\x32\x68\x0c\x1b\xc1\x81\xc6\x12\x1e\x0e\x4d\x28\x25\x7a\x16\xf7\x3c\x2b\xc2\x05\x5a\xe5\xd3\x94\x3e\x2a\x21\x5e\xe2\x5b\x3a\x93\x59\x09\xfc\x8f\xe1\x67\xc3\xff\xf6\xf8\x0f\x46\x09\xc8\x56\xbf\xb9\xfd\xa2\x24\x4a\x02\x13\xee\x69\x77\xcd\x84\x28\xc2\x4d\x3c\xbf\x3c\x0c\xcc\x93\x84\xda\xec\x47\xaf\xec\xc0\xf1\x39\x5d\x9f\xfc\x57\x13\x91\xf9\x01\x82\x06\x36\xcb\xbb\xdd\xe3\xba\x2c\xa4\xbb\x2d\xd3\xcc\x41\xe3\xed\x76\x69\xf7\x12\xdb\x1e\x51\xb3\x01\x2f\x96\xb7\xb3\x97\x87\xdd\x7e\xf6\x32\xdf\xad\x9e\x9f\xf6\x0f\xcb\xa7\xbb\xdd\x7d\xdb\x4b\xf8\x08\xa5\xb5\x41\xe4\xad\x7c\x85\x6e\xb5\xc4\x20\x10\x28\x01\x4e\xca\xf2\x37\x75\x03\xff\x35\x81\xd6\x4a\x38\x31\x55\x4c\x15\xd7\xb0\x2b\x1e\x4d\x08\xee\x4a\x20\xc3\x75\x4e\x3c\xc2\x3a\x4a\x59\x4b\x46\x6e\xa6\xf0\x60\x86\xf0\xc4\x43\xc7\x22\x75\xf1\xd5\x5e\x8c\x23\x91\x2c\x76\xf4\xc5\xcd\xbe\x73\xc3\xeb\x3a\x03\x43\x8f\x33\x1c\x5c\x45\x84\x55\x08\x95\x05\x4e\x79\x64\xc2\x73\xb7\x51\x49\x84\xbc\x57\x87\x33\x2f\x55\xca\xf3\xf0\x67\x51\xb7\x63\x03\x34\xc0\x0d\xe2\xa6\xd3\x7e\x72\x3c\x9d\xc3\x57\xd2\x41\x12\x43\x07\x88\x03\x35\x0e\x33\x25\x9a\x29\x84\xa5\x5b\x06\x7a\xf7\x0b\x3a\x96\x46\x88\xbe\x59\x89\x28\xf4\x60\x6a\x3d\x5c\xb3\x88\xd0\x92\xd3\xc5\xb9\xac\x5f\x71\x95\x3a\xd8\x9f\xeb\x21\x43\xec\xb1\x46\xe2\xd5\x05\x6f\x97\x2a\xf7\x82\x18\xd1\x7b\x58\xc8\xd3\xc6\xac\xbe\xdd\x23\xb8\x17\xc6\x89\x29\x1b\x6c\xcc\x05\x9e\xad\xcb\xe2\x50\x76\xb2\x25\x5f\x4a\x2a\x37\x57\x26\x98\x6c\xc0\x92\x21\x47\x63\x33\xd8\x23\xb9\x07\x1e\x92\x32\xec\x6d\x16\xe5\xba\x8a\x89\xfb\x2c\x62\x01\x4e\x46\x84\xab\xad\x79\x09\x79\xbd\xe0\x05\x9a\xef\xee\xc5\x02\x2f\xe6\xbc\x25\x85\x43\xd5\x83\x16\xcc\x32\x15\xbc\xe3\x81\x6f\xdc\x8e\x5f\x3c\xab\x87\x26\x12\x0f\xa8\xc1\x41\xba\x62\x0d\x0c\x68\x6e\x7b\xe0\x0b\x1e\x12\x0f\x63\x49\x2d\xd9\x89\x85\x9f\x0f\xdf\x2d\x4c\x7c\x4c\x6e\x9f\x8a\x5f\xb5\x1e\x4a\x55\x28\x1e\xca\x90\x1b\xcb\xe6\x1d\xca\xee\xaf\x10\x20\x77\x41\x63\xd4\x58\x31\x2e\x7c\xb4\x61\xce\x9b\x87\x9a\xa1\xbd\xd8\xec\xfc\x43\xec\x20\x27\x9e\x40\xe7\x38\xad\x9c\xc0\xd5\x73\x73\xc6\x9e\x8a\xb2\x9e\xe2\xf0\x51\x9c\xa8\x80\x88\xce\xe6\x48\x8b\x1c\x45\x70\x6d\x2b\x05\x6d\x04\x9c\xcb\xe2\x34\xde\x05\xae\xd8\x83\x15\x67\xa1\xa4\x49\x6b\x42\xe2\xca\x5b\xbb\x54\xe2\x70\xfc\x23\x4e\x30\xba\x33\xcf\xd2\x3c\x95\x9d\x2d\xcc\x23\x45\x71\x60\x72\xf8\xc4\x94\xef\x86\xbf\xc1\x70\x7e\xf3\xd8\x0f\x59\xa7\x47\x88\x15\x70\xb3\x6b\x8e\x24\xc5\xb9\xef\x49\x70\x65\x19\x3d\x6c\x01\xe7\x89\x46\x3b\x4e\x9c\x2f\x77\x70\x6c\xc7\x4e\x30\xe3\xaa\x56\x50\x23\x57\x4d\x6f\xad\x72\x11\x13\x15\x5b\xfe\x83\x1d\x54\xf5\xcb\x94\x74\xb6\xe2\x42\x10\x65\x4b\x90\x7f\x5c\x64\x57\xf0\x61\x58\xce\x47\x43\x2f\x3d\x8a\xa5\x46\x3f\x57\x9b\xbb\xe7\xc1\x14\x94\x89\x47\x62\x77\x6e\x1d\xce\x46\xd6\xcc\x96\xf6\xbe\xf4\x6c\xb9\x69\x18\x3d\x07\x06\x18\x0b\xce\x8b\x67\x6d\xe0\xd9\x16\x55\xbc\x86\x72\x35\x7f\xee\x3b\x4a\x1c\x40\x23\xba\xa4\x10\xff\x06\x59\xef\x8a\xf6\x14\xe0\xda\x33\x82\x5c\x0e\xeb\xb4\x1e\x0b\xc6\x28\xe1\x45\x09\x52\x3c\x2f\x73\x75\x2e\x9b\x19\xda\x7f\x0b\xe1\x07\x5c\x48\xc7\xb3\x85\x50\xb6\x21\x61\xa6\x12\xbe\x0c\x5d\xa1\xcd\x2d\x80\x6a\xdc\x98\x5b\x98\x54\x25\x57\x22\x90\xa6\xd2\xb9\xc8\xd4\x9e\x0f\x26\xbd\x08\x43\x9d\xd8\x80\xd7\x03\xf0\x0a\xe6\xbc\x54\xd3\xf5\x44\xf6\x02\xe2\x13\x13\x0c\xb7\xe6\x60\xa7\x2a\x6d\x8b\x91\xc6\x5b\xe2\xe0\xc3\x09\x12\x08\x66\x90\xe4\x75\x71\x73\xae\xd2\x1c\xaa\xea\x36\xcd\x7b\x4b\x54\x10\x9a\x58\x4a\x71\xcb\x9d\xf8\x15\x34\x6e\xa2\x24\x5d\x09\x12\x13\xbf\x99\x46\x7b\x2b\x3b\x72\x85\x16\x11\x8c\x27\x68\xe8\x61\xb5\xca\x02\xe4\xdb\x1f\xce\x9a\x99\x34\x46\x05\x93\x02\xe5\xed\x9b\xa1\x5b\x80\xe6\xe7\xac\x7e\x3e\x41\x79\x25\x4a\xac\x44\x14\x10\x5c\x05\x8f\xb3\xd5\xd3\xfe\x9f\x2f\xcb\x6d\x47\xbc\xad\x44\x24\x4d\x85\x61\x63\xbe\xcb\x57\xa8\x90\x5a\xf9\xb9\x2d\xcf\x13\x71\x64\xb2\x03\xf6\x61\x67\xa3\x99\x3a\xfa\x0c\x89\x4f\x13\xda\xa5\xcf\x54\x4f\xc2\x45\x89\x24\x22\x61\x67\xb2\xb7\x26\xa5\x10\x71\xc0\x6d\x12\x16\x49\x70\x2a\xd8\x41\x79\xac\xda\x6e\xc3\xb7\x11\xd2\xc3\xa5\xbe\xcc\xd2\x1a\xb6\xaf\xe9\xe9\x34\x84\x36\x08\xa1\x03\x64\xf5\xdd\x80\xe4\x99\x4d\x69\xdf\x96\xc5\x71\xb4\x61\x0b\xe9\x2b\x9c\xaa\x06\x4f\x65\xa1\x4f\x23\xac\x60\xb7\x5f\x08\x19\x07\xe8\x23\x5b\x55\xb2\x2b\x8d\x8b\xe9\x79\x29\x13\x8d\xd9\x73\x7e\x84\x5c\xa1\xa1\xfd\x3d\xe8\x5a\x28\xcf\x37\x15\x9f\x85\xae\xe7\xfc\xf4\xec\x1c\x01\xa1\xb8\x40\xf3\xd1\x16\x97\xcc\xf2\x83\xc5\xbb\xb8\xc0\x9b\x50\x32\x70\x1a\x3a\xff\x3c\x43\x79\xe9\xb1\xa0\x29\xa1\xb4\x8f\xe1\x27\x83\x4d\x84\x7a\xf5\x3c\x1d\x03\x15\x20\x25\x02\x3d\x96\x8b\x79\x91\xa5\x15\xb4\x61\x49\x01\xd2\xe4\xb7\xce\x95\x72\x1c\xc6\xb7\x7d\x9e\x2a\x25\x40\x71\x45\x5b\x03\xd9\x24\x0f\xa7\xed\x43\xa1\x7d\x8d\x5f\x69\x57\x7c\xf4\x2a\xa4\x5d\x23\x8b\xb8\xc5\x36\x2d\x40\x8c\xf7\x28\xad\x09\x62\x6b\x55\x91\xe3\xf1\x66\x52\x63\x3b\x37\xcf\xa4\xe7\xf9\x18\x2f\x91\xb8\xc9\x76\x33\x43\x7a\x09\x10\xee\x34\xbe\x70\xeb\x05\xb5\x2e\x0b\x75\x96\x75\x77\xb1\xf2\x55\x57\xe4\xd6\xfd\x95\x60\x14\x72\x7e\xbf\x7a\x5a\x6e\x97\xad\x46\xa3\x93\x31\x54\xd2\xf7\x8c\x66\x9b\xcb\x5f\xff\xad\xdc\x9b\x0c\x02\x86\x05\xdd\xc7\x41\x4e\x53\x06\xb1\xe1\xca\x7b\x78\x9e\xff\x98\x3d\x3e\xbf\x3c\xed\x88\x6b\x0a\x23\xc3\xfb\x76\x80\x7a\x97\xca\x37\x18\x0d\x8e\x24\x14\x02\x3b\x74\xa6\x52\x1b\x11\x93\x03\x46\xc9\x81\x87\x26\x89\x06\x11\xb5\x41\xe5\x0a\x19\xb6\xeb\xdf\xb9\xc9\xf6\x5a\x2a\x25\x6b\xa5\x55\x6b\x9e\x2d\xd2\xf7\x74\xf4\x2d\x25\x95\x46\x3b\x7d\x7f\x32\x82\xa7\xbb\xc2\x92\x58\xf4\x5c\x0b\xc9\xa2\xd0\x1c\x2c\x8d\xd1\x78\x2d\xba\xac\x24\x93\x46\xcd\x42\x81\x0b\xa5\xcc\xd4\x36\x2b\xdc\x62\x96\x51\xc8\x42\xab\x7c\xfa\x04\x1f\x3b\x38\x9e\x32\xe3\xa2\xa1\x31\xf1\xbb\xcc\xa8\xbb\x09\x21\x51\xd8\x09\x20\xe0\xcf\x3c\x3a\xda\x2e\x25\xa3\xc6\xf9\x35\x26\xe9\xb3\x99\x1d\x83\x95\x23\x23\x49\x39\x75\x11\x1a\xbf\xbd\x4a\x1b\x65\xa6\x75\x5a\xcb\xd7\x6e\x35\xc9\x58\x46\xa1\x91\x8a\x37\xc6\xaa\x4b\xf0\x8e\x86\x2f\x06\x0f\xd5\x20\xaa\xd7\xa2\xac\x21\xdf\x43\xae\x0c\x43\xf2\xb8\x9f\xf6\x62\x8b\x86\x79\x36\x09\xc6\x7e\xfa\x52\x72\xdd\xe2\xd1\x37\xc0\x55\x6b\x13\x48\x41\x02\xa7\x9c\x6b\xeb\x7f\x30\x5e\x80\x84\x12\x7d\x57\x59\x0a\x26\x4c\x09\x5e\xb3\x6c\x0e\x97\xf6\x7a\x65\xc4\x04\xeb\xd7\xb4\x54\x6b\xde\xfe\x5d\x86\x1a\xc3\xe4\x0f\xe7\x37\x3e\x08\x78\x48\xa9\x88\xab\x9e\x5a\xe5\x48\x79\x7c\xe6\xd9\x1c\x4a\x0b\xa4\x6c\x8d\x85\x2f\xb8\x89\xed\x5d\x94\x1f\x19\xf9\xe5\xf3\xf1\x9e\x97\x6a\xce\x4f\xab\xf9\x73\x3b\xe8\x2a\x88\x70\xb3\x36\xc5\x9d\x3b\xd4\xe9\xee\x3d\x42\x63\x94\x6a\x0b\x93\x49\xcd\x3c\x41\x3e\xd1\xf9\xb9\x7c\xef\xb0\xad\x76\xb5\xb4\xbe\xd0\xf0\x6b\x2b\x2e\xad\x5a\xc1\x00\xb2\x7c\x8d\x98\xef\x2a\xbd\xed\x95\x40\xdc\x21\x99\xab\xdf\xe3\x04\x24\x30\xc3\xa5\xaf\x4b\x80\x79\xc9\x3f\x16\xc0\x55\xd6\x92\x8b\x29\x09\x31\x41\x5c\xf9\xdd\x76\xe9\xb8\xcf\xdb\x16\xa5\x4c\xf8\x3b\x87\xca\x28\x0a\x57\x83\x59\xa1\x45\x8c\x52\x8b\xef\x50\x5e\x66\xf9\xa1\x3d\x92\xa5\x56\x86\xf7\x1c\x67\x5a\x47\x60\x69\x5a\x95\xe7\x85\x98\x7e\x36\xbc\x4a\xaf\x3c\xcd\x83\x3d\x69\x1b\x03\x19\xf7\x49\xac\x96\xbb\xfb\xc1\xe9\x3b\xb9\xf4\x94\x17\xd9\xa0\xf1\x01\x1c\x33\xdf\xda\x10\xbd\xa2\xcc\xb1\xeb\xa5\x4c\x12\x18\x6d\x24\x13\xe3\x1c\x55\x90\x0c\x67\x89\xf2\x3d\x20\x56\xf3\xab\x9f\xa3\x53\x3e\x55\x8e\xa3\xd5\x70\x5b\x85\x6d\x8b\xf6\x11\x30\x5d\x60\x4d\xc4\x0e\x01\xfc\xc3\x7b\x06\x94\x21\x1a\x7d\x3d\xdb\x4d\xe0\x20\x55\xc0\x0c\xeb\x15\xe2\xc5\x0f\x5c\x14\x9f\x86\x86\xcf\x35\xc7\xc6\xc0\xb6\x31\x79\xc3\xf8\x3d\xcd\x41\xa5\x54\x00\x49\x12\xb6\x04\x3f\x3b\xc8\xc7\x42\x94\x4a\x85\x96\xd4\x79\x6e\x41\x0d\x55\x7d\xd3\x72\xbb\x0e\x7b\x12\x9a\xa0\x4d\xdd\x7c\xd2\x45\x71\xe4\xbd\x00\xed\xd5\x17\xa6\x2c\x94\xe1\x04\x9d\xc9\x6f\x55\x35\xda\xeb\x09\x46\x6f\xb1\xec\xe6\x59\x8f\x46\x30\xf1\x23\xe4\x74\x96\xc5\x11\xd7\x0e\x6c\xe0\x74\xae\x79\x8f\x99\xd8\x75\x54\x01\x12\xd0\xc3\x67\x5a\xc3\x32\xaf\x53\xc5\x47\x94\x15\x2a\xb1\x72\x7e\xe2\x7c\x41\x27\x61\x7a\x7a\x25\x5a\x62\x1c\xa9\x39\x14\xaa\xba\xa7\x5c\xa3\x14\x27\x86\xa7\xf8\xd7\x2b\x47\xce\xb9\x55\xf5\x54\x7c\xb4\x8d\x9c\xb2\x56\xd0\xbe\xcf\x81\xf1\xd8\xfa\xb7\x4a\x84\xd2\x6b\xf1\xea\xfb\x13\xbf\x18\xaa\xb1\x36\xa0\xa8\x04\x05\xf4\xe0\xdf\x0b\x83\xee\xfc\x68\x99\x39\x95\x12\xda\xb3\x71\x2b\x1b\x53\x9a\x52\x85\x68\xfb\x1a\x06\x95\x13\xaf\x50\xe1\xb6\xda\x15\xbb\x57\xe8\xa5\x71\x95\xf4\x0c\xff\x68\x6a\x75\x68\x26\x2d\x3c\x25\x85\x51\xae\xdf\x81\xd9\x15\x8d\xd4\xf8\x37\x69\x12\xa5\x3c\x09\x5d\x2e\x0c\x4f\xf9\x71\xb9\xae\x52\x7e\x88\x49\xd8\xf5\xe6\xa6\x97\x09\x53\x2a\xf0\x44\xcf\xe6\xc2\xc2\xbc\x9a\xd7\x60\x8c\x80\x6a\x7c\x13\x61\x38\x9b\xa4\x01\xdc\x3f\x7f\xe4\x1b\x68\x3f\x06\x78\xbe\xc5\x3f\x36\x06\xbb\xa9\x9f\x9e\xa8\xc7\x53\x5a\x6b\xe1\xa4\xf4\xfe\xb7\xf5\xe6\xc3\x79\x03\x1e\x93\xe8\x64\x19\x20\x75\x1b\xb2\x03\x2f\x21\x11\x73\x78\x74\x90\xcd\xc9\x85\xa1\xcd\x29\x8f\x73\x72\x46\x82\x27\x25\x4e\x8a\x53\x09\x8f\xf2\x36\xbb\xf4\x45\xfc\x15\xf8\xc4\x47\x8a\x00\xcb\x99\x38\x1d\x6e\x00\x9f\x33\xac\xee\xb3\x65\x7c\xcb\xdd\xfd\x70\xa1\x41\x90\x50\x2c\x48\xea\x54\x6a\xab\xf9\x6e\xe3\x7e\x24\x50\x34\xb0\x8b\x5c\x4c\x29\xe6\xb8\x6e\x90\x20\x06\xd6\x6d\x12\xf3\xe2\xca\xe9\x71\x3d\xb5\xa9\x9d\xce\xd2\xfc\x6d\x57\x98\x7a\x2e\x07\x06\x35\x54\x4c\xd3\x33\x12\xc2\x40\xa0\xfa\xd3\xfc\x5c\x36\xbe\x4d\xb7\x1d\x5d\x07\xa8\x46\x29\x5e\x08\x99\x99\x14\xc6\x7e\x59\xcd\x9f\x47\x63\x44\x22\x81\x05\xfc\xba\x63\x72\x78\xd9\x3a\x3c\x04\x90\xd8\xf3\xfa\x32\xbe\x96\x28\x60\x38\x8a\x24\xf6\xa4\x81\xbe\x9c\x4b\x07\x8e\x7b\xee\xbb\x07\x40\xa4\xb1\xd7\x17\x8d\xe5\x67\x6c\xed\xa9\x88\x07\x50\x4f\x62\x2d\xd1\x6e\xf5\xb8\xdc\x37\xc6\xfd\x7e\xf9\xd4\x3e\x0b\x25\xb1\x8a\xbb\x62\xd7\x6d\xcd\xdf\xae\x4b\xba\x86\x2f\x47\x23\x53\x22\xff\x5e\xd4\x30\x4a\x77\xba\x1e\x5c\x39\xe4\xd0\x3f\xec\x31\x53\x5c\xb1\xc4\x2b\x60\x32\x41\x45\xd8\x07\xa8\x57\xa8\xc9\x3d\xb4\x4b\xfe\x8f\xff\xda\x9b\x47\x56\x71\xcb\x8e\xea\xae\x18\x90\xa1\x74\x25\x44\xc3\xb3\x1b\x22\xee\x3b\x42\x74\xac\x10\x1e\x3d\x72\x04\x3c\x6a\xf9\x19\xef\x9f\xe6\xdf\x6d\x60\x10\x81\x82\xee\xd4\x35\x33\x73\x5e\x9c\x46\xb1\x05\x88\x85\x60\xb6\x86\xe8\x58\xb4\xc0\x35\x48\x22\xa6\x3a\xde\xd1\x66\xeb\xbd\x37\xd5\xca\xae\x5d\x1b\xea\x47\x59\x64\x45\xa9\xd3\xac\x1e\x9f\xbd\xc0\x13\xdf\x77\x38\xf3\xe6\xbc\x4f\xeb\x0b\x62\x8b\x86\x6f\x2c\x98\x87\x91\x3b\x71\xbe\x4c\xa7\xbf\x40\x88\x84\x3a\x39\x7f\xa4\x34\xb3\xf4\x02\xbd\xfd\xc6\xf6\x94\x41\x90\x24\x4e\x6f\x98\x1f\xa0\xea\x85\x4b\x41\x86\x0a\x91\x90\xb7\xcf\x2f\x4f\x8b\xe5\x66\xbb\xff\x35\x7b\x78\x58\xee\xda\x66\x22\x91\xe7\x71\x8b\x4c\x11\x37\xc5\x48\xde\x49\x81\x0a\x02\xdf\xeb\x16\x9d\x2c\xc6\xaa\x44\x0a\x20\x90\x88\x43\x33\x0a\x87\x8f\xb6\x90\xe2\xd8\x05\x7d\x41\x07\xba\xa7\x37\x85\xd3\x7d\x40\x2d\x3d\x19\x09\x05\x1d\x85\xd4\xb7\x22\x7b\x36\xb6\xf3\xff\x49\x7b\x93\xe6\xc6\x71\x6c\x5f\xfc\xbb\xbc\x55\x2d\xde\x02\xe0\x08\xfe\x77\x92\x2c\xa7\xd5\xe9\xa9\x25\x39\xb3\xea\x76\xdc\x50\x60\x38\x90\xd8\x96\x48\x35\x49\xd9\xe9\xfe\xf4\xff\xe0\xc1\xc0\x41\xb4\xb3\xef\x7d\x9b\xca\x0a\x13\xa2\x28\x12\x04\xce\xf0\x1b\xb0\xa1\x82\x33\xc4\x8c\xd1\x24\x90\xce\x78\xe4\x3e\x2f\xf6\xc7\xb2\xd8\x2f\xf8\x68\x97\xd0\x24\x0a\xd0\xd7\x10\xb7\x6d\x6b\xf9\x6d\xb7\xc3\x8e\x7f\xaf\x69\x66\x66\xd9\x1c\xad\xea\xe5\x27\xbd\x15\xe6\x46\x6b\x03\xe9\x15\x65\x55\x21\xd9\xd5\xfe\x3d\x08\x05\x86\x11\x96\xd9\x31\xcc\x1e\xdd\x52\xa6\x03\x08\xc1\xf6\x01\xd7\x52\xb9\x95\x66\x74\xd9\x21\x93\x08\xef\x7a\xe7\xfe\x1a\x43\x1e\xe0\x66\xf1\x9c\xd7\x7d\xe5\x5d\xa5\xa3\x30\x90\xd6\x3a\x6c\x03\x47\x3d\xbf\x0c\x4a\x42\x3a\x4a\x43\x9b\xfa\xc1\x7f\x95\x27\x91\x63\xe6\x37\xfa\xba\x28\x35\x34\xb4\x4d\xbe\x37\xb6\x5a\xee\xef\x32\xc0\x19\xf4\x5a\x22\xc8\xd1\xfd\x39\x0e\x04\x96\xf2\x50\xde\xbf\xea\x72\x48\xd7\x11\xed\xea\x69\x3a\x8e\x62\x54\xcc\x7b\x30\xde\x67\x1b\x38\xa2\x50\xad\x79\x04\x93\x88\x5f\x1d\x47\x32\x0d\xbd\x23\x56\xfe\x5c\x96\xc7\xa5\xca\x9b\x5d\x34\x88\x1a\x75\xac\x23\x0e\x06\x02\x79\x76\xd1\x3b\xb5\xc7\x92\x98\x3b\x22\xd9\x43\xde\x46\xbf\x57\x1e\xaf\xc3\x37\x4e\x27\x8c\x33\x0b\x2b\x31\x2a\xd2\xa3\x6b\x4a\x43\x53\x6f\xc9\xeb\x0d\x62\x7d\x86\xaf\xa1\x4e\x41\xe2\x8b\x8f\xa9\x92\xc5\x84\x2e\x4f\xe7\xe6\x63\xf9\xaf\x1f\xce\x46\x55\x69\x16\x48\x7c\x50\x6f\xf0\xef\xc6\xe4\x29\xc3\x2f\x61\xa1\x54\x64\xd0\x21\x76\xe5\xc7\x7e\xbd\x72\xdc\xbc\xd1\x2c\xa2\xd2\xae\xa0\xc6\x87\xf2\x47\x5e\x5d\xea\x1b\x98\x96\x79\x56\x9a\xc5\xb1\xb6\x72\xef\xb3\x8b\xca\xc7\x18\xad\xd1\x9d\x61\x2c\x44\xe0\xbe\x29\xf6\x19\x9a\xe5\x04\xe3\xd7\xad\x6e\x3a\x13\x02\xa3\x95\x03\x54\xa0\xb8\x7f\x37\x38\x31\x1b\xb4\xe4\xed\x24\x3d\x0e\x2e\x6d\x50\x1a\xd5\x3c\x55\xa9\x07\xcc\x4f\x28\x2c\x68\x2e\x63\x6e\x2d\x26\x90\xc3\x54\x3d\xf9\x2c\x59\x0b\x22\x78\xec\xe2\x50\x59\x56\x0a\x0d\xb8\x46\x21\xb6\x16\x49\x82\xd9\x9f\x8b\x07\x4c\xb0\x3e\xea\x03\x6a\x21\x8d\x4a\xee\x1d\x3f\x36\x3d\x4c\x8a\x16\x4a\x27\xca\xcb\x99\x60\x88\x7e\x3b\x0e\xda\xb4\x4c\xbc\xac\x32\xd6\xcc\xe6\x17\xb5\xf7\x81\x9f\x96\x10\xa3\x64\xbc\x0f\x48\x7e\x75\x42\x7c\x1e\xee\xac\x25\x24\x08\x44\x78\x98\xfd\xb9\x5b\x3d\x6e\x97\xeb\xe5\x66\xbb\x33\x85\x42\x37\x44\xf1\x08\x81\x20\xb3\xba\xce\xf7\x3e\xa1\x18\x3e\x6f\xa0\x09\xf2\x0b\x17\xdb\xf9\x57\xbb\xa7\x86\x28\x44\x5e\xc7\xb9\xa3\x07\x0f\x45\x38\x46\xf3\x08\xd2\x14\x59\x48\xab\xe2\x2d\x6f\x60\x86\x86\x1f\xd7\x84\x57\x37\x58\x68\x6d\xf5\xeb\x97\x9f\x18\xa7\x01\x21\xa9\xa4\xd0\x19\x3b\xfc\x5c\x5a\x7c\x28\x10\xa2\x12\xac\x26\x01\x62\x1b\x3d\x2b\xd5\x1f\x4d\x51\x9c\xa4\x4d\x05\x96\xbf\x1a\x28\x14\x0c\xe6\x0c\x10\x2a\x09\x63\x3e\xc5\xee\xe1\xf4\xae\x60\x72\x40\x82\x4c\x28\xf0\xaa\xd3\x2f\xf5\x70\x2d\x00\x12\x08\x81\xd1\xa4\xe1\xa9\x7c\x49\xf0\x05\x12\x72\x03\xd7\x2a\x2e\xa7\xd5\xe9\x5c\x56\x8d\xbf\xa4\x38\x15\x58\x41\x59\xfd\xf5\x30\xfb\x6b\xe6\xfe\x9a\x80\x11\x50\x7c\xb8\x79\xda\x4c\x46\x67\x76\x5c\x4a\x14\xe2\x40\xaa\xb2\x34\x14\xa6\x27\xbd\x1b\x5d\x67\xca\xcc\x5d\x39\xf0\xda\x52\x4e\xa6\xd6\x03\x20\x8c\x64\x98\xc5\x6f\xd7\x2f\xcb\xeb\x52\x07\x10\xc6\x4d\xee\x6d\xb3\x63\xcb\x91\x7e\xd2\x93\xc1\x0b\x90\x4c\x19\x47\xf2\xe6\x00\xb7\xc7\x92\x37\x16\x41\x92\x8f\xa2\x25\x20\x99\x26\xdc\xf8\x34\x81\xca\xa5\xd5\x00\x71\xf7\x81\xd3\x44\x50\xa3\xaa\x8c\x4a\x73\xc7\xe3\x1a\x09\xe2\x3d\xd3\x58\x20\x02\x52\x30\xfa\x28\xc8\x11\x46\x47\xe6\x11\xa2\x0e\x88\xa4\x29\x56\x34\x4d\xa9\x7f\xd8\x82\x04\x22\x83\x08\xf1\xe6\xf7\x39\x2f\xfe\x96\xf7\xfb\xa0\x40\xa4\x96\xa1\xc1\x5c\x5e\x0a\xe9\x76\x39\x07\x3c\x62\x76\x90\xa2\x51\x66\xa3\x90\x6f\xfc\x04\x9d\x24\xde\xf0\x2a\x14\x13\xb8\x81\x1c\x01\x5e\x37\x0d\xf0\xe3\xb6\x54\xfc\x63\xe7\xbe\x0a\x6c\xfe\x7c\x97\xef\x0f\xdf\x78\xdd\x47\x06\x01\x81\x28\xa5\xe6\x1a\x25\x14\x75\x7e\x39\x4d\xc9\x77\x0c\x1c\xce\x80\xe8\xd4\x80\xd8\xd0\x0b\xc4\x78\xc2\xf7\xa0\x10\x40\x49\xc0\x30\x97\xd9\xa9\x12\x41\xc3\xed\x4e\xd3\xbe\x98\x9f\x34\x50\x87\x53\x86\x92\x38\x16\x16\xcd\x33\x50\x10\x00\x4a\xa9\x8e\x33\x6b\xaa\xbb\x6b\xca\xb1\xb1\x9a\x1b\xa5\x23\xe4\x07\x2f\xb7\x77\xbb\xb5\x17\x35\x06\x1a\x50\x46\xec\xab\x87\x48\xe4\x29\x7d\x5c\xa0\x61\x18\x63\x3f\x02\x3b\x43\x70\x53\xf0\x2f\xa2\x35\xa0\xa1\x20\xa2\x83\xc7\xe2\x03\xf6\x5e\xbf\xc3\xf3\xc6\x44\x25\x16\xf2\xbe\xfd\xd5\x71\xef\x80\x26\x41\x86\xd8\x06\x63\xa1\x7b\x25\x6b\x33\x89\xa6\x1a\x3c\x0e\x9a\xa4\x14\x3d\xed\x76\xe7\x0a\xac\xef\x13\x5c\x71\xeb\x2f\x57\xa2\x90\x40\x13\x66\x0a\xfe\xe7\x0a\x9c\xcb\xef\xef\xf2\x35\xf7\x49\x69\xec\x56\xec\xc4\x44\x93\x23\xdb\x93\x19\x7d\x05\x48\x4e\x86\xee\x52\x5e\xb6\x64\xb8\x27\x02\x4d\x03\x8a\x3a\x2a\xf7\x0f\xb3\xa7\x9e\x44\x1c\xd0\x34\x63\x34\x71\xca\x4c\xda\xc4\xe9\xc3\xaf\x61\x4a\x05\x28\x8c\x52\x36\xa5\x2a\x2f\xfb\xbe\xcb\x38\xd0\x2c\x8c\x90\x77\x51\xbf\x9f\x6f\x3d\x7e\x11\x68\x96\x09\xa3\x70\xdf\xf0\xca\x28\xb9\x7f\xc9\xfe\x02\xca\x93\x14\x67\xd6\x8d\xb5\x78\x77\x27\xe2\x82\x61\xf2\x76\x69\xaa\xc1\xf7\x8a\x38\xc0\x75\x54\x95\xda\x03\x6d\xec\x21\x49\x12\x9c\xe4\x05\xbc\x5f\x0b\x0f\xb6\x87\x25\x19\x51\xaa\xfd\x27\xa3\x00\xf3\xec\x7f\x5d\xa0\xfa\x08\xa6\x37\xdd\x29\xfa\x00\x50\xc9\x01\x2b\xd6\x66\xb2\x1a\xf4\xfb\xe0\x7a\xa5\x88\x8d\x9a\x01\x98\xc2\xda\x14\x1a\x16\xa8\x54\xc6\x4d\xd2\x88\xbf\xff\x31\x94\xef\x00\xaa\x44\x94\xc5\x2e\xda\x35\x6e\xd4\x36\x10\x39\x5e\x95\x22\x86\x84\x04\xf4\x13\xa1\x89\x6d\xaa\x84\xa6\x47\xb5\x3b\x40\xbe\x3f\xf8\x5b\xdd\x6e\x62\xed\x5a\x86\xb1\xa2\x2b\xf2\xfc\x44\xda\x33\x74\x83\xa8\xc6\xfb\xfe\x2d\x2f\xab\x7d\xee\xff\x1a\x45\xa9\xa7\x5f\xee\xde\xf3\xa2\xde\xf5\x4c\xd3\x81\xea\x40\x20\x2c\xd5\xaa\xc8\x5f\x4b\x84\x01\xd5\x2c\x43\xe4\xd3\xf3\x7a\xb9\xdb\xcc\xee\x97\xbb\xcd\x76\xb6\xb6\xf1\x12\x04\x04\x52\xe9\x1b\x64\x06\x78\x70\xc3\x1b\x6e\xe2\x48\x37\x28\x08\x22\xd4\xaf\x92\xe5\xe9\xdc\x41\xd1\xec\xc1\x50\x5b\xcd\x39\xe0\xa7\xef\x00\xe7\xbc\xd8\xdf\x97\xf2\x75\x59\xa8\x79\x07\xe8\x85\x20\xa2\xbe\x67\xba\x31\x24\x90\xc7\xf6\x25\xbc\x42\xb7\x4d\xbe\xbb\x41\x44\x95\x30\x74\xfa\xf6\x9c\x98\xc2\xf8\x13\xc7\x1a\x31\x9e\xcf\x77\x7f\x6e\xbf\x3f\xfa\xbf\x4a\xc1\xb4\x05\xdc\x57\x6f\x66\x9b\xec\xb4\x46\x21\x88\xb9\xc9\x27\x55\xfb\x5a\x94\x1f\x2e\xe0\x75\x47\x45\x6a\xc4\x01\x4f\x67\x23\x19\x59\x0f\xd3\xf3\xc8\x8e\x4b\x92\x90\xc5\xbe\x20\xa0\xf3\x5f\x3d\x2a\x05\x1e\xc5\x9e\xc7\xc8\x0f\x0b\x82\x94\x86\x18\xfb\x37\x15\x6f\xe7\xda\x43\x59\xb4\xf7\x7c\x08\xd4\x80\x20\x8d\x0c\xd5\x64\x0d\xa0\xa0\x82\x53\x3f\xdb\x83\x80\x31\x86\xb2\x46\xe7\xe1\x7c\x75\xc9\x15\x04\x19\x0b\x9c\x09\x1e\xa6\xbf\x46\x44\x60\x72\x91\x08\x32\x15\x20\x01\xcc\xf8\x1c\x95\x79\x11\xf9\xb3\x28\x8e\x29\x58\x9b\xc8\xcd\x2f\x1f\x6d\x5c\x0e\xea\x8e\x57\x6a\xf0\x83\x32\x1d\x20\x50\xd3\x75\x77\x8c\xcc\xf0\x7f\xd4\x34\x81\x80\x13\x1a\xd1\xae\xdb\xd3\x0f\xb8\xfe\x41\x93\xff\x9e\xde\x71\x03\x9e\x28\x9c\xf9\x4d\x75\xe9\x5c\xc8\x21\xe0\x32\xc2\xbe\x90\xca\x6b\xbe\xaf\xe0\x4a\xb1\x67\xa4\xdc\x03\x81\x90\x0c\x57\xe1\x0d\x6f\x93\x17\xa7\x05\xf9\x15\x4c\xfe\xfa\x17\x08\xd0\xa1\x2d\x4f\x1d\xd5\x58\xa4\x18\x02\xa1\x43\x2c\xa4\x1a\x2f\x46\x63\xd7\xbc\x91\x65\x75\x4d\x60\x1d\x3c\x61\x49\x22\x5c\xd9\xba\xfd\xf5\x13\x5f\x69\x37\x9e\x85\xa6\x68\x0f\x55\x0e\xbd\x04\xdf\x1d\x86\x90\x11\xe7\x36\x84\x45\x34\x5c\xc4\x17\x97\x51\x2c\x12\x40\x98\xc5\xb6\x68\x37\x61\xd1\x32\xbc\x46\x48\x63\x84\xd3\xa3\x4e\x63\xf9\x82\x79\xaf\xfb\x42\x4d\x28\x36\x21\xd1\xa1\xcb\x08\x3c\xd4\x37\x56\xdf\x53\x8d\xa4\x1e\xae\xc0\xb7\x57\x5c\x84\xd1\x8f\xd5\x89\xd1\xfa\xc6\x75\x0b\x5f\xf1\xbe\x3d\x18\x04\x5a\x06\xb8\x57\xed\xae\xdd\x4e\xc6\xcf\x72\xb8\xd2\x68\x25\x88\xd1\xd6\x6b\xf8\x6d\xd9\xf7\x22\x72\x03\x74\xac\xb3\x01\x01\xcd\x7e\x67\x48\x88\xc6\xe7\x2c\xab\xf2\x1d\x11\x05\x5d\x71\x0e\x42\x2a\x8d\xeb\xd7\x5d\xa9\x8e\xee\x65\xbd\xf2\xfa\x18\xfe\xc8\x30\x88\x62\x4c\xac\x37\xdb\xf5\x62\xb7\x79\x79\x7e\xbe\xff\xcb\x9d\x2e\x48\x0d\xae\xc9\xc5\x40\x76\xe2\x8e\xa4\xd3\x46\x75\x89\xfe\xa3\x0b\x03\x1e\x63\x1a\x50\xc1\x99\xe7\xd5\xf6\x00\x0b\x5e\x37\xdd\x8f\x09\x84\x71\x4d\xdc\xae\x57\xcf\xfd\x0d\x37\x0c\xb4\x8c\xd2\x1e\x20\x10\xa5\x07\xfe\x98\x40\xff\x41\x18\x52\xee\xe0\x8c\x2f\x35\x54\x4e\xbb\x74\x70\x19\x21\x84\xce\x01\x79\x5d\xbe\xff\xfd\x82\xf6\x98\xdd\xf6\x1a\x46\x44\x10\xdb\x83\xbb\xc7\x2e\xe6\x33\xff\x50\xfc\x63\x3a\x0b\x0c\xa3\x20\xf6\xf2\x51\xd6\x88\xa8\x7d\x82\xee\x68\x1a\x5b\xe9\x56\xf9\xfa\xf7\xe6\x63\x5b\xce\x2c\xa9\xb5\x03\x73\xb5\x83\x04\x0b\x90\xaf\x30\xbb\xf7\x93\xe7\xa1\xdb\xc9\xc2\x48\x09\x94\xf3\xb0\xea\x88\xff\x03\xa9\x3c\x08\x93\x50\x6b\xab\xb3\x71\x39\x63\x6e\xe6\x0e\x80\x42\x88\xef\x7a\xb6\x5d\xee\x6e\x66\x7f\xed\x02\xe6\x0e\xa5\xa1\xc0\x2d\x5a\x5c\x90\x40\xd8\xcf\x84\x42\x66\x99\xa3\x5c\xa9\xa7\x6a\x7f\x8d\x26\x71\xc3\x44\x14\x44\x0e\xa4\x5d\xc3\x6d\xce\x1b\x1f\x6c\x0f\xa7\x1c\x53\x04\xfb\x73\xb3\x9b\x1f\xab\xcd\xd3\x7a\xb3\x9b\x3d\xde\xec\x16\x4f\x8f\xdb\xf5\x6a\xfe\xb2\x6d\xff\xb0\x7d\xfa\xbe\x7c\xdc\xb8\x0b\xc8\x08\x43\x7a\x22\x60\x07\x09\xd4\xc3\x5f\xf3\xe1\xfb\x12\x0a\x6d\x4a\x8f\x66\x79\x5f\x83\x2c\x11\x76\x31\xd1\xea\x85\x50\xd1\x18\x4b\x98\x05\xfc\x6a\xee\xae\x95\x51\x21\x54\x51\x8c\x0d\x8d\xf6\xf9\x1a\x75\xc5\x0e\x93\x4d\xdd\x6f\x50\x8c\xd1\xd0\xdd\xe4\x2f\x3b\xa1\xcc\x7d\x82\x13\xc3\x57\x33\x7d\xc7\x59\xa1\x16\xa8\x81\xb9\xe0\xa3\xca\xdc\x48\x23\x37\x72\x9f\x17\x3a\xb3\x68\x69\xbb\x4a\xf7\x18\x24\x10\x2a\x9d\x62\x79\x6d\xf9\x5f\x08\x43\x34\x89\x3d\xea\xd1\xba\xdb\x08\x11\x71\x52\xe5\xb6\x5d\x5c\x7f\xf7\x81\xaa\x1b\x93\x0a\xdb\x38\x00\xf9\x6a\xdb\xe9\x5f\xa1\x30\x21\x04\x1b\x9a\x21\x6e\x7c\x24\xa7\xe9\x87\x64\x61\xec\xd2\x14\xac\xd2\x3f\xf4\xfb\x6f\xbd\x17\x51\x07\x22\xb0\x27\xbb\x29\x25\x42\xb9\x37\xf9\xbe\xa8\x17\x57\xfc\x3f\x08\x75\x6c\xb2\x94\xbf\xdd\xce\x07\x6b\x87\xe6\x80\x82\xc0\xdf\xca\xa3\xda\xfe\xba\x05\x40\x8f\xdf\xf1\x66\xdb\xfb\xd1\x11\x09\xac\x34\x16\x58\x15\xb1\x81\xd1\x93\x1d\x44\x89\x71\xcc\xe5\xde\xb4\x06\x22\x4a\x63\x61\x20\x0c\x6e\xaa\xf5\xdf\x88\x28\x88\x28\xd2\xf7\x10\xa9\xb1\x9d\x68\x39\xba\x71\x99\x26\xce\x53\xeb\xe1\x72\x6c\x6e\xfc\x8f\x89\x02\x01\x58\xc9\xfa\xd7\x85\x57\xbc\x68\xf2\x02\x26\x27\x75\x14\x68\x26\x22\x9f\x09\xb6\xb9\x5c\x77\x57\xa3\x40\x1b\x3e\xfc\xa1\xac\x6a\x78\x1e\xa5\x54\x51\x48\x99\x91\xe5\x39\x94\xef\xde\xed\xad\xee\x4a\x2a\x6e\x58\xcc\x8c\x2c\x6e\x0d\x6a\x97\x17\x9e\xcd\xb1\xd3\xd0\x1b\xc4\x02\x2c\xaf\x89\xce\xc4\xf0\x2a\x68\x8c\xda\x5b\xc9\xac\x14\x0c\x6f\x60\xff\x3b\xf5\x30\x88\xa2\xd8\x98\xca\xd6\xd0\x2c\x0b\xb5\x5a\x3c\x8d\x7e\x42\xdc\x26\xec\x86\x30\x6d\xea\xd7\xed\x45\x1a\x34\x6e\x9f\x0b\x02\x51\x9c\x0a\x13\x4b\xb7\x99\xed\x92\x57\x47\xe3\x0c\x13\xfa\xe3\x2c\xca\x2c\x05\x6e\x55\xd4\xe7\x6b\xe3\x3b\x88\x62\x45\xb1\x65\xbf\xdb\xed\x50\xf6\x60\x10\x00\x45\x49\x22\x8c\x9c\x4e\x59\x6d\x81\x9f\x16\x4f\x2e\x09\x8a\x52\xc2\x58\xe0\x84\xcd\xab\x5b\x3a\x9c\x2a\x2c\x08\x53\x9f\xd7\x2e\x9b\x03\x06\xd2\xb7\x65\x65\xe6\xe3\x4a\x96\xee\x34\x59\x90\x21\xe4\x11\x71\x36\xf3\xf2\x57\xe0\x0f\x84\x04\x97\x35\x83\xe0\x18\x37\x0d\x21\xca\x62\xc5\xbb\x8a\x8c\xc9\xbd\xbe\xb6\x90\x80\x28\x63\x31\x2a\xd9\xdd\x97\xe5\xeb\xcb\xd9\x1b\x1e\xde\xe4\x6f\x28\x32\x39\xba\x33\x19\xe7\x98\x80\x37\x68\xa9\x76\xd4\xca\x56\x03\x56\xf5\x1a\x79\x3b\xa0\xda\xb9\xf0\x90\x17\x6b\xac\xe1\xfb\x0b\x57\x31\x2a\x2f\x68\x90\x87\x1f\x65\x03\x0f\x3c\x2f\x56\x85\x2e\xe7\x1f\xce\x89\x78\x7e\x85\xc9\x84\x88\xd3\x34\xec\xe4\xcd\xfb\x08\x0f\x88\x38\x0b\x5c\x19\x13\xf2\x7d\x31\xbf\x7c\x6c\xa1\x9e\x96\xbd\x82\x48\xc4\x20\x6c\xf3\xe2\xf9\x60\x9b\xf8\x98\x77\x8c\xaa\x30\x91\x0c\x45\x00\x3d\x23\xe1\x1e\x9c\xb2\x67\xca\xf6\xc9\x0c\x56\x81\xb9\x93\xe6\xe5\xe4\xe2\xf8\xb1\xcb\xf5\x6e\xcf\x6b\x7c\x8e\xbb\x53\x59\x41\x4c\xf6\xef\x90\xef\x36\x50\xa8\x5d\x7b\x1f\xea\xdd\x6d\x55\x9e\x76\x7f\x95\x97\x6a\xf7\x95\x4c\x31\x44\x2a\x32\x95\x05\x63\xe2\xba\xe0\xe7\x67\xa8\x46\xf3\x52\x45\x89\xd1\x06\x94\x87\xb2\x7f\x33\xdc\xe1\x18\x50\x60\x10\xd3\xf6\x9b\xd9\x76\xe9\x3e\x07\x59\x8c\xdd\x10\x9e\x57\x37\x55\x79\xb6\xdc\xa2\x9d\x3f\x2c\x42\xcc\x70\x8f\xa0\x9b\x28\x1c\x9d\x54\x53\x8e\xa9\xe9\xec\xfb\xc3\xdf\x16\x77\xb3\x95\xcb\x9b\x23\x9d\x18\xf5\xa5\x87\x0f\x67\x2f\xfc\x3b\x65\x0c\x88\x74\x16\x22\x88\x71\x8f\x42\xd3\x03\xf5\x5c\x88\xb4\x32\x1e\xb0\x1b\x68\xdf\x79\x04\xd9\xfa\x6c\x2d\x8e\xe2\x10\xa7\xa5\xce\xab\xba\x99\xdc\xa0\xe2\x28\x31\xeb\xb8\xdd\x9a\xa7\xe3\xbe\x38\xca\x18\x75\xab\x90\x8d\x44\x2c\x86\x12\x9d\x3f\xae\x3c\xc8\xdd\xc7\x04\x43\x30\xeb\x4c\x29\x6f\x49\x35\x78\xf9\xe3\x98\x0a\x04\x3f\x1f\x78\x7d\xe8\x2a\xfc\xee\x20\x37\x00\x88\xbf\x5d\xea\x66\x7b\x80\x6d\x7e\xfe\xbd\xc0\xf9\xf0\x02\x62\x6e\xe9\xde\xe0\x03\x32\xb3\xac\xb8\xd9\x11\xc7\xc2\xb8\xeb\x56\xc0\x15\x16\x4a\x3d\x44\x99\xb9\x11\x20\x83\xd8\x3b\x94\x3d\x97\xaf\x70\x72\x00\x72\x88\x93\xcc\x3a\xce\xdd\x2c\x3d\x8e\xaf\xac\x7a\x68\x58\x88\x13\x15\xa0\xc4\xcf\x1a\xce\xc7\x8f\x41\xa1\x72\xf0\xf2\x0c\x6e\x4b\xa2\x15\x5a\x1d\xf8\x5c\x72\xb9\xdf\xcf\x2f\x1f\x06\x77\x3c\xba\x4b\x29\x35\x18\xf6\xda\xda\x31\xe4\x6e\x03\x43\x76\xe3\x08\x0e\x00\x71\x1a\x11\xac\x0c\x3b\x74\x57\x73\xe8\xa1\xcb\x2c\x7f\xc1\x5d\x7a\x1a\xc7\x18\xd7\x9e\xcb\xf2\x88\x1e\x61\xfd\xe0\x38\x4e\xd3\x00\xfb\x7c\x65\x61\x39\x9b\xcb\x62\xa8\xce\x05\x31\x23\x0a\x17\xb8\xff\xfa\x8f\x1f\xdc\xf4\x22\x12\x33\xcd\x50\x32\xe4\xcc\x2f\x35\x18\x0a\xba\xbb\x8c\x8c\x64\x4e\x64\xe0\x87\xb1\x12\x9f\x7f\xac\x46\x3d\xb4\x38\xa3\x81\x32\x59\x95\x83\x84\xde\xf1\xfa\xb0\xb9\x08\x2b\xa3\x37\x0a\x2a\xe2\x4c\xc5\xd4\x98\xf0\xf2\xe6\x80\x58\x5e\x4d\xdd\x17\xf2\x48\xb9\x42\xf7\x03\xaf\xaa\x7c\xec\xaf\x06\x31\x4f\x12\x65\xca\x69\xf9\xbf\x2e\xb0\x39\xa3\x20\x85\x81\xc5\x8e\x47\x66\x80\x0f\xcf\x88\x28\xdc\x9d\xc5\x63\xa9\x60\xce\x1b\x79\xe8\xd3\x85\xc6\x50\xa6\xfe\xff\xb9\x13\xe9\x00\xa9\x66\xf3\xcb\xbe\xa7\xc9\x6b\x0f\x0a\x2a\xd1\x31\x6c\xc0\x1e\x84\x58\x86\x11\x12\x57\xac\xe4\xed\x97\xd0\x42\x88\x25\x4b\xb0\x0d\xde\xa6\x19\xb7\x58\x26\x9e\xa8\x52\xc7\x52\xc5\x18\x82\x5a\xdd\x81\x81\xaa\x1e\xc4\x40\x33\x62\xe3\xf0\x39\xaf\xd1\x22\x61\x20\x25\x65\x87\x69\x99\xa0\x11\xa5\x9f\xfe\x2b\x59\xce\xa7\xb0\x84\xc3\x4b\x4c\x08\x91\xd8\x84\x52\x65\xbb\x95\xfc\x56\xb8\xae\x97\x49\xf4\x22\xf1\x84\x04\x86\x7b\xc0\xeb\x1a\xaa\x66\x65\xd0\x15\xd7\x4a\x2d\x90\x10\x1e\x09\xed\x53\xaf\xfb\x52\xbe\x9a\x6e\xe1\xe8\x95\x4b\xa8\x4c\xb1\x98\x90\xd7\xc6\xa3\x67\x7a\x91\x4d\x28\x24\x98\x7c\x7d\xe3\xf5\x4f\x07\x64\x80\x24\xa0\x49\x92\x5a\x58\x7f\xbb\x2b\x3e\xbd\x4f\x9b\x99\x40\x12\x24\x10\x33\xd7\x82\xf3\xde\x66\x43\x26\x12\x24\x01\x70\x2c\xec\x79\x63\xbc\xc1\x39\x42\x96\x99\xde\xbd\xbb\xf3\xb7\x79\xc1\x8f\x37\x79\xdd\x0c\xac\x9d\xbe\x22\x51\x40\x12\x2a\xc5\x12\x2b\x7f\xb0\xe3\x4a\xe5\xc6\x45\xd1\x7a\xfc\x0c\x2f\x3a\x26\xa1\xb0\x85\x26\x23\x0d\xff\x54\x29\x30\x0b\xa8\xbf\xe4\x38\x56\xaa\xb3\x5d\xd9\x94\x47\xb5\x2a\xb6\x87\xbc\xee\x29\x4f\x40\x92\x24\x29\x82\x5d\x56\xc5\x5b\xf9\xda\xeb\x3d\xf7\x23\x13\x37\x94\x31\x9c\xc9\x47\x5e\x37\x96\x58\xd5\x37\x0f\x6c\x07\x48\x04\xb8\xea\xcd\xbf\x46\xf3\x3b\x49\x34\x8d\x8d\xfd\xeb\xfb\xa0\x22\x96\xa4\x6d\x2e\x83\x0d\xa5\xbc\x91\x87\x6d\xd9\xad\x78\xfd\x95\x3d\x61\xa9\x01\xfe\x38\x9c\x86\x15\x05\xb4\x69\xde\x34\xe4\x06\x92\x2c\x49\x31\x17\xea\x4c\x8b\x6e\xfb\xbb\xee\xf0\x12\x33\xc1\xb1\x74\x0d\xcd\xe1\xb6\xac\xa6\x9a\x16\x49\x06\x04\x6b\x99\xcb\xed\x5d\x14\x90\xb2\x88\x02\xe2\x7e\x07\x27\x86\xd2\x63\x26\x75\xc7\x2d\xec\x98\x2b\x13\x31\x4a\x22\x58\x92\x1a\xea\x4b\xfb\xce\xd8\x39\xb7\x2a\x9a\x72\x31\x26\x03\x23\xef\xc4\xc5\x6c\xbd\xad\xa7\x5d\x8f\xaf\x7f\xd2\xb8\x1d\x94\x08\xe0\xe0\x80\x7a\x01\xa1\x6c\xdb\x73\xc6\x72\x3f\x41\x66\x11\xe6\x29\xb7\xf9\x11\xda\xd3\xae\xfc\x9e\x95\x28\xa2\xb1\xf7\x98\xd7\x2e\x39\x9b\x19\xd3\x53\x3f\xc0\x9a\x1b\x6d\x4e\xbc\x6a\x1c\x67\xb7\xbf\x6a\x26\x8a\x19\xa2\xc6\xfc\xe9\xe5\x71\xbb\x5a\x6e\x76\x9b\xbb\x99\xd3\xda\x87\x44\x49\xc0\x4e\x58\x73\xa8\xca\xf7\x95\xff\x10\x24\xb1\x93\x78\x86\x73\x9b\x22\x1c\x11\x28\xd4\xe7\x42\x41\x02\x00\xc6\x09\xef\xf8\x71\x3a\x5f\xea\x6d\xb7\x13\x27\x3a\xc9\xa2\xb4\xe7\xd8\x39\xbf\x54\xc5\x2d\xc0\x4c\x5c\xe7\x31\x83\x9b\x9d\xd2\x28\x4b\x04\xd6\x19\x7f\xab\xc1\x06\x29\x8d\xd3\xc0\xe8\x15\x1c\x40\xbe\xf6\x12\xa9\xf1\x49\xa5\x44\x4c\xf1\xdd\xe6\x50\xc2\xae\xdf\xaa\x48\xa9\x16\x24\xeb\xf1\x74\x3c\x19\x64\x75\x3a\x81\xca\x79\x03\xc7\x51\xc5\x37\x0d\xb4\xb0\xbe\xda\x1f\x13\x70\x90\x34\x24\x29\xe6\x0f\x3e\xbe\x32\xf1\x6f\xbf\xc0\x94\x86\x69\x1c\x53\x2f\x57\xed\xe1\x36\xf7\x50\xec\x3b\xf0\x8f\x1b\xcb\x18\xa6\x48\x8f\xf0\xbe\xce\xeb\xd7\xd9\x18\x8f\x93\x46\x41\x14\xda\x4c\xf8\x11\xde\x6f\x00\xfb\x1c\x53\x05\xd8\x34\x0a\x4d\x68\x87\x39\xdd\xe8\x24\x9c\x22\x03\xc3\x56\x31\x7b\xa0\x83\x34\x8e\x68\x94\x0c\x4c\x5c\x56\xa7\x33\x70\x79\x38\x41\xd1\xbc\x54\xc7\x1b\x68\x78\x7e\x74\xab\x5f\x9a\xd0\x20\x22\x4e\x59\xb8\x0f\xef\x1d\x5d\x4c\x92\x00\x6a\xf2\xaf\xca\x22\xff\xf5\xeb\xf7\x0f\x3b\x11\x2c\x4c\x2c\x88\x09\x2a\x17\xdd\xa4\x29\x0d\x9c\xaa\x48\xa1\x78\xa5\x6c\xd9\x6a\x10\xfa\xa5\x69\xa8\x32\xe5\xfa\x12\x43\xcb\x11\x48\xd3\x98\x20\x42\xc5\x2e\xd0\x79\xb1\x5f\x56\x55\x59\xdd\x1e\xcb\x72\xda\xf8\xa4\x7b\x36\x69\x96\x31\xa3\x4a\xd1\x5b\x19\xac\x0c\x9b\xbe\x1c\x07\xaf\x4b\x9a\xca\x18\xa5\xf4\x0d\xdd\xee\x98\xff\x7b\x9c\x94\x8e\x43\xcb\xe1\x13\x62\xc4\xc8\x6e\x3c\x2f\xd7\x8b\xe5\xe3\x76\x47\x89\x5b\x03\x53\x96\x45\x28\x07\x66\x9b\xd5\xcb\xed\x9d\x7f\x1a\x19\x8f\x51\x65\x64\x5b\xe5\xe7\x67\xfe\xf1\xe5\x1d\xce\x80\x39\x92\xca\xf2\xc4\x73\x57\x05\x4a\x79\xa0\x9d\x4f\x92\x9d\xd1\xbb\xa6\xdc\x1e\xa0\x73\xf4\x85\x94\xeb\x30\xb2\x8a\x07\xcf\x65\xdd\xac\x16\x4f\xd8\x0a\xe9\x56\xc2\x54\x00\xc5\xed\xfe\x6d\x04\xef\x98\x15\xea\xa6\xdb\x26\x3a\x53\xc5\xc8\x35\x81\xa2\x2b\x41\x0e\x48\x25\x4d\x2c\x06\x4d\xd6\xcf\x50\xf5\x5b\xcb\xa9\x8c\x02\x27\x14\xbd\x3d\x5c\xc9\xf9\x41\x2a\x99\x4c\x0c\xe5\xb4\xcf\x8b\x86\x54\xc5\xc6\x28\xd3\x6a\xdb\x6e\xfb\x31\xa6\x1b\x92\x1a\x59\xd1\xcd\xf3\xd3\x7a\xfb\x7b\x94\x51\xaa\x44\x60\x50\x4d\xbc\x76\xe2\xa2\x8f\x8e\xfb\x0a\xa9\x52\x31\x6a\xeb\x95\x47\x75\x33\x1f\x56\x01\x52\x88\x44\x94\x0e\x88\xac\xfe\x48\xcc\xd3\x4e\xbf\xb7\xc3\xd1\x57\xb2\x5c\x03\x16\xc2\xdc\x48\x4d\x85\x56\x1e\x2d\x50\x61\x3d\xc3\xef\x1c\xa9\x66\x80\x60\xc2\x99\x75\x36\x1f\xcc\x6c\x46\xb2\x0c\x41\xc6\x7d\x76\xa1\x3d\x44\x63\x23\x75\xb6\x91\x65\x89\x04\x02\x47\x73\x02\x46\x53\x82\xfb\x7e\x9d\x37\x0e\xb8\x5d\xf9\x63\x22\x41\x38\xdb\xf7\xbc\xd8\xab\xf2\x64\x3c\xa0\x5c\x38\xc2\x82\x50\xa8\xf6\x5e\x3c\x3d\x7c\xeb\x3f\x14\x16\x28\x82\x04\x79\x25\x5e\x87\x22\x1b\xc0\x42\x62\x68\x71\xb5\xc1\x2a\x94\xc5\x6d\x59\x19\x50\xe6\x08\xe7\xf9\x75\xd2\xcd\x42\x92\x70\x6b\xf7\xac\x2d\x5c\xdb\x1d\xa1\x0c\x6b\x26\x26\xdb\x59\x9d\xf8\x1e\xa6\xaa\xc7\x2c\x8c\x81\xd9\xa5\x09\x90\x08\x2a\xcb\x76\x91\xea\x15\xb2\x3e\x9d\x22\x2c\x4c\x25\x0a\xa2\x29\x23\x0d\xb5\xb3\x79\xae\x7f\x4e\x2c\xe2\x4a\xd9\x1e\x51\xfb\xc2\x59\xb5\xa5\x8e\x9c\xcb\xfe\x41\x03\xf6\xdf\xa3\xdf\x14\x47\x29\xde\x9b\xd3\xc7\xaa\xcd\xe5\xdc\x6a\xc9\x12\x20\xb8\x5a\xce\xbf\xdf\x0e\x6e\x73\xa2\x19\xc4\x9d\x5a\xeb\x0d\x70\x75\xdf\x33\x6a\xb6\xa3\xd2\x50\xa2\xf4\x55\x9b\x27\xfe\x31\x7a\x25\x59\x2a\x75\x48\x5c\xd4\xdb\x69\xed\x00\x63\x2c\x4d\xec\x54\x7e\xbc\x9c\x10\xd8\xbd\x2d\x6d\x00\x3b\xd8\x12\x18\xd3\xc6\x55\xdc\x54\x0a\x1d\xa5\xd8\x1e\xcc\x42\xda\xd3\xe0\x59\xd5\xf5\x65\xdc\x0e\x62\x3c\x53\x48\x3c\x98\xf3\xfa\xd5\xdb\x9d\x7e\x19\x6f\x30\x2e\x32\x44\x1b\xec\xce\x47\x3e\x2d\xe2\x05\x4c\x48\x8e\x74\xbc\x2d\x14\x0d\x14\xb9\x9f\xb3\x42\x1b\x60\xb9\x4f\xfb\xec\xf6\x68\x1a\x3a\xa8\x8d\xd7\x63\x1a\x00\x93\x21\xc7\x26\x74\x17\x15\x3f\xf3\xaa\x29\x9c\x8f\xab\x1f\xc6\x63\x84\xfe\x18\x70\xcb\x4c\x21\xcd\x70\x38\x44\x51\x1e\x66\x1e\x62\xdb\xde\x8b\x2e\x69\x65\x2a\x90\x34\xeb\xb0\x2e\xb7\x65\xe5\xd4\x18\xec\x00\xa0\x21\x6e\x17\xf7\x50\xd7\x65\xb1\x4b\xa7\xf3\x33\x06\x61\x1c\x5a\xe7\x4b\x0b\xc9\x2b\xab\xdb\xb2\x7a\xbc\xf9\xcf\x80\x1c\x0c\x12\x15\xd9\x5e\xd2\x46\xa2\x30\xd7\xd0\x8d\x6d\xf8\xec\x40\x6a\xdc\x40\x84\x73\xef\x9d\x64\xfb\x01\xd3\x9a\x60\x18\x50\x5f\x44\x1b\xc6\x8d\xea\x0a\x19\x89\x78\xc4\xfc\x64\x6b\xbf\x12\xe1\x3a\x83\x2b\xcb\x48\x64\x54\xcc\xeb\x86\xbf\xc2\x73\x95\x9f\xca\x4a\x39\x49\xaa\xbe\x78\xeb\xf4\x0f\xcb\x08\xa3\xa8\xff\x75\x29\x4a\x8d\x86\x81\xc7\xd9\xf9\x7c\xb4\xf6\x47\x9b\x7c\x5f\xbc\x9c\x07\xeb\x43\x16\x24\x09\x26\x8d\x5e\xd1\xba\xff\xee\x65\x41\x22\x22\x23\x99\x65\x74\xb9\x3a\xc1\xc8\x6e\xf7\xcc\x02\x9e\x02\x73\x95\x41\x71\xcc\xa5\x11\x81\xb3\xe5\x3d\xf7\x7e\xb7\xef\x88\x51\xf0\x72\xf1\xec\x1d\x1c\xcf\xe3\xa2\x47\x16\x52\x23\x13\xd1\xb4\xdf\x31\x15\x9c\x65\x61\xa0\x9c\x1d\xd2\x58\x5b\x19\xb2\x90\x51\xfc\x92\xf6\x95\x01\x3a\xcf\x95\xff\x76\x88\x90\xa3\xff\xfd\xc0\x45\x2e\xde\xea\x07\xf9\xad\x82\xbd\x93\x11\x85\x2c\x8a\x52\xe7\x55\x62\x98\x18\xb5\xed\x62\x8d\x89\x5b\x90\x45\xb1\x69\x44\x96\x56\x1b\x79\x55\x2c\xa0\x4b\xb1\xb3\x28\x0d\x71\x7b\x34\x8b\xc1\x4f\xc8\x17\x65\xdd\x58\x51\xa8\xd1\x8f\x8d\xa4\x76\x35\x1c\x9c\xc6\x79\xf3\x31\x2f\x0b\x35\x6b\x9a\xd2\x1b\xde\x42\x16\x53\x81\x60\x0d\xb3\xd4\xef\x64\x09\x5a\xfb\x63\xa1\xb1\x3f\xa9\xa1\x19\xe9\x9a\xb8\x01\x52\x05\xc6\x2f\xa2\x12\xb9\x1a\x1f\x54\x0e\x41\x39\x59\xe4\x19\x16\x77\x06\x3d\xcf\x5e\x1e\x99\x25\x8c\x62\x12\x2a\x78\x9b\xad\x77\xa2\x02\xe3\xe2\x4d\x96\x64\x49\x66\xdd\xf7\xda\x20\x7e\x71\xcd\x9e\x82\x2c\x95\x3c\xc8\x7a\x98\x0d\x50\xab\xe2\x86\x8f\xf2\x9c\x8c\x09\x89\x98\xb9\x99\x94\x97\x13\xae\x6f\xd3\x0b\x45\x96\x11\xae\x4c\xbd\x68\x0d\x05\xba\x4f\xba\x03\x99\x54\xe6\x7b\xde\xca\x57\xac\xad\x39\xc0\x8f\x3f\xd3\xe0\x44\x9c\x25\x2c\x76\xee\x29\x63\x49\x37\xc8\xb8\x10\x31\x71\x05\x23\xee\x5a\x5c\x28\x4e\x60\xf8\xe2\xa7\x2b\x2f\x0f\xc8\xb8\x32\x0a\x8c\x86\x05\x35\x78\x2d\x39\x68\xd3\x69\xb1\xa0\xbe\x59\x05\x1b\xdf\x9a\xca\x44\xc6\x78\x5f\xc1\xa1\x5d\x18\xbc\xb7\xeb\xe8\xca\x04\x0f\x1d\x2a\xa5\x8d\xc1\xca\xa2\x86\x61\x3c\x97\x49\x15\x12\x53\xb7\xaf\xe5\x05\xee\xcb\xba\xb9\x83\xaa\x9c\xee\x43\x64\x2a\x30\x46\xb9\xe2\x52\x15\xb3\xe3\x71\xf4\x65\x2a\xd5\x58\x9e\x2b\xf8\x29\xc7\xaa\x4d\x1b\xf4\x20\x4f\xc3\x0d\x00\x82\x32\x32\x6d\x82\x9a\x1f\x61\xa4\x18\x36\x3c\x19\xd0\x38\xa1\x9e\x20\xf9\x6a\x7e\xa6\x7b\x4a\xdf\x61\x3c\x27\x80\x26\xce\xbc\x60\xd3\xa0\xaf\x54\xc3\xc7\xd7\x07\x54\xe2\x36\x67\x7c\x78\xc7\xda\x88\x90\x41\x28\x8c\x00\xd6\x72\xb3\x5c\xff\x58\xde\x58\x08\xc9\x0e\x0b\x14\x0e\xd1\x94\x41\xa8\x30\x45\xc6\x27\xbb\x5c\x2f\x02\x32\x91\x2d\xb1\xe9\x5d\x3d\x83\x48\xc4\xca\x35\x92\xb0\x6f\x3c\xe6\x34\x42\x06\x31\x45\x20\x4a\xde\x46\x12\xb3\x42\xcd\xac\xa2\x0e\x3a\xe5\x5c\xb7\xb9\x3f\xc9\xd1\xfa\x96\xa2\xe3\x8b\xc8\x22\xc2\x9d\x7b\xe9\x4d\x5e\x8b\x4b\x55\xe3\x44\x9b\x7e\x8d\x38\xa1\x12\xa9\x16\xd2\x44\x11\xf7\xe5\x7b\x57\x50\xe1\x24\x8d\x84\xd5\xe4\xb7\x6b\x90\x9b\x5a\x9c\x52\x86\x48\x3e\xe3\x0b\xfc\xcc\x3f\x4e\x5f\x58\x65\x7f\x1d\x0b\x73\x1a\x1b\xfb\x32\xec\x75\x1a\xfd\xcf\x99\xbf\x06\x9a\x1a\xe8\xce\xd3\x7a\xb6\xb8\x5f\xfd\xd7\xf2\xef\x2f\xcb\xf5\x5f\x0f\xb3\x3f\x3b\x0b\x68\xe0\x94\x33\xf4\x12\x74\x22\x93\x5f\x27\xd0\x9c\x8a\x14\x53\x4e\xa3\x93\xd9\x43\xcf\x71\x0a\x01\xae\x1d\xd0\x1c\xb0\x89\xe2\xfe\x1e\x84\x9a\x77\xd1\x11\x3a\xae\x7f\xd1\x70\xe5\x81\x30\x92\xaf\xce\x27\xf1\x1b\x14\x05\xfc\x3b\xaf\x47\xa1\x2d\x0f\x04\x60\x29\xe9\x58\xee\xc3\x60\x90\xb7\xf3\x40\x29\x14\x14\xab\x78\xa1\xca\x93\xa5\x08\x7c\x19\x21\xf0\x00\x42\x54\x68\x59\x1e\xf3\xfd\x89\xdb\xa6\xc2\xa8\xcb\xc1\x03\x2d\x99\x81\x89\x16\x12\x8e\x73\x68\xe6\x1f\x66\x57\x1c\xae\xd6\x3c\x24\x0a\x27\xf3\xfc\xf2\x61\xc0\xa2\xf5\xfc\x63\x39\x2e\x13\xf1\x90\x12\x15\x0d\xaa\x34\x57\x12\xd6\xed\xa0\x30\x0e\x3a\xfd\xa3\x76\xf9\x34\xfd\x0c\x7f\x5c\x81\x79\x27\xe6\x97\x8f\x39\x97\xaf\x9e\x3a\x08\x3c\x4a\x9c\x0a\x0b\x2e\xe6\xd6\x7a\xea\x19\xaa\x71\x4b\x6a\xdc\xeb\xe1\x71\x48\xd1\xc5\x66\xb7\x87\x02\xda\xfc\xea\x11\xde\xef\xca\xaa\x86\xcd\xa1\xbc\x9e\x20\xc3\xe7\x12\xab\x98\x80\xcb\x2a\x7e\xe6\xc5\xba\x0d\xb2\xdc\x25\xc5\x90\x5a\x6b\x39\x8c\x74\x6f\xd0\x8e\x65\xf0\x86\x8d\x61\xe4\x97\xdf\x83\xf2\x78\x42\x00\x3b\x0e\x55\x79\x84\xa5\xca\x9b\x72\xd4\xa1\xe7\x09\x05\x6c\xce\xb9\x96\xc4\x58\xd6\xc1\x0d\x93\x09\xce\xed\x07\x38\x95\xf7\xbc\x50\xbd\x44\x99\x33\x62\xa4\x12\x76\xd6\x38\x60\x7e\xf9\x68\x87\xdc\x96\xd5\x82\x17\xea\x6a\xf5\x71\x9f\x0a\x59\x62\x8c\x51\x65\x05\x68\x29\x8f\xaf\x8c\x2d\xec\x8f\xc6\x46\xa9\x93\xda\x34\xb3\x0a\x1b\x15\xff\x4f\x42\x20\xd0\xee\xcf\x58\xcd\x3e\xf1\x57\xab\xc6\x31\xd4\x41\x8c\xdd\x38\x1d\xc4\xa6\x6c\xbd\xbe\x14\x68\x7a\x8c\xfc\xf8\xd1\x25\x66\x91\xa9\x9e\xb5\xf9\x53\xaf\x9c\xee\x79\xd2\x6e\x58\x9c\x86\xb8\x4d\xdb\x89\x66\x2b\x7c\xdb\x43\x05\xf5\xa1\x5b\xd0\x79\x26\x02\xdc\xf6\xd6\x4b\x54\x77\xdc\xbd\xac\xef\xdd\x21\x4e\x24\x06\x3c\xf7\xe5\xbe\x57\xa8\xb3\xac\xbf\x49\x8a\x08\xe7\x51\xc8\xba\x14\xeb\x5a\xae\xd0\x0e\x13\x11\xe0\x6d\x2e\xcf\x50\x7c\xcb\x75\x1b\x2d\x9f\x36\xbc\x68\xf8\x68\x32\xc8\x34\x64\xf6\xcd\x5b\xcc\x9e\xcc\x84\x72\x57\x07\xd4\xd0\x6d\xb1\xcb\xe8\xeb\x58\x1c\x92\xd4\x00\xbe\x6b\x18\x83\x21\x3e\x79\x3c\x60\x01\xad\x16\x56\x58\xec\xfd\x9b\x02\x3a\xc6\xf0\xa3\x7c\xf3\x05\x19\xae\xa3\x18\x85\x47\x37\xfc\x0d\x6c\x71\x6a\x7e\xf9\x40\x75\x10\xf5\xef\x4f\x66\xa0\x96\x0a\x8b\xd1\x26\x4c\x46\xff\x83\xc7\xbe\x7f\xe9\xe8\xbd\x33\x9f\x12\x34\x54\xe8\x0d\xba\xdb\x40\xe3\xed\x1b\xfe\x7e\xe1\x47\x6f\x1a\x3b\xc6\x52\x08\x1a\x65\x19\x71\x2b\xd1\x27\x2e\x24\x20\xa8\xd0\xc6\x3f\x1f\xc0\x55\x87\x96\xcd\x61\xe6\x5c\x05\x41\x84\xc4\x50\xc6\xb1\x41\xb0\xad\x00\x36\x88\x73\xea\x89\xaf\x0f\x1f\xbb\x08\xa9\x01\x24\x6d\x5e\x16\x8b\xe5\x66\x63\x44\xf9\xdd\xd9\x22\x2a\xb1\x4a\x62\x81\x5b\x23\x67\x3f\x10\x91\x08\x51\x0f\xc7\x36\xa8\xd1\xa3\xb5\x8d\xd1\x2f\xd7\xc4\x35\x11\x07\x14\xb3\xe3\x3e\xe3\xed\xd6\xb8\xbb\xf4\x24\xff\x40\xc4\xca\x90\x09\xe0\x5f\x17\x7e\xec\x8a\x2e\x3d\x7c\x7c\x3f\xa6\x15\x09\x89\xd1\x4a\xef\xf1\xc7\x6a\xb3\x7a\x7a\x5c\xcc\x36\x77\x18\x5e\xb9\xd3\x25\x49\x88\x84\xe8\xf3\xc1\xac\x1f\x35\x3f\x02\xa2\x97\xfc\x80\x4c\x60\x04\x70\xe8\x19\xba\x4c\x69\xba\x06\x76\x4f\x11\x2c\x48\x5c\xec\x7b\x97\xef\x0f\x50\x37\x9f\x52\xe9\x44\x96\x70\x6e\xa1\xb8\x76\x93\xfa\x89\x3e\x46\xe5\x71\x3c\x50\x13\x6c\xf5\x9b\x79\xf6\x3b\xc2\x8a\xe0\xa9\xe0\x4e\x88\xe8\x58\x8e\x1a\x78\x82\x73\x8e\x5a\x64\xc6\xb6\x63\x5e\x5e\xf6\x87\x66\x5a\x71\xee\x3f\x5a\x05\x05\x57\xa6\x9d\x64\x9a\x63\x36\xe0\xaa\x7b\x19\xb2\x50\x24\xc0\x57\xab\xf9\x38\x83\x03\x7e\x08\xc5\x32\xe4\x06\xe2\x57\x6f\xf8\x48\x38\x11\x84\xe2\x22\x8e\x3c\x4e\xf9\x7f\xb8\x40\xff\xee\xdf\x29\x39\xf3\xe9\xff\x73\x57\x23\x23\xe7\x09\xda\x18\x3f\x86\xae\xe1\x2c\x94\x8e\xb8\xf4\xfd\x2b\xdb\x92\x9c\x43\xb3\x2a\xae\x02\x13\xa1\x74\x8c\xba\xfd\xb9\x2c\xdb\xb3\x20\x2e\x02\x95\x9a\xa9\x97\xa6\x07\x01\xa9\x59\x02\x6f\x91\x13\x63\x82\x75\xb7\xce\x77\xec\x59\x01\x4a\xa2\x64\xda\x81\xd7\xcb\x42\x41\x0f\x6d\x29\x74\x12\x6b\xe5\x2b\x02\xdf\x78\x8d\x6d\xbe\x27\xed\x0c\x8f\x07\x31\x9d\x24\x32\xc4\xb6\xe7\xbb\x6b\xbd\x3d\x57\x79\x21\xdb\x80\xe6\xbe\x94\xaf\x16\x3b\xe7\xc5\xe9\x41\x12\x1d\x62\x6c\xde\x2e\xcf\xfd\xf7\x4d\xd2\x30\xcb\xdc\xda\x6d\xde\x92\xbe\xf0\x91\x1b\x24\x29\x96\xbe\xed\x84\x99\xad\xd6\xed\xae\x7f\x6e\xba\x4a\x8f\x1d\x18\x10\x1a\xf4\xac\x15\xca\xf2\xb8\xd2\x8f\x00\x5d\xd5\x5e\x06\x11\x41\x80\xbd\x21\x0f\x0d\x5a\xfa\x32\x48\x09\x2a\x0c\xcd\x72\xa3\xfb\xdc\x2b\x32\xc9\x80\x43\x64\xf9\xa7\x9b\x33\xaf\x5e\xad\xe4\x9e\x1a\x95\xe1\x64\x00\x01\xf2\xf2\x7c\xac\xb6\x28\xd5\x27\xb1\xb5\x0c\xb4\xc2\x52\x9c\xe4\xe7\xde\xb3\xea\xf7\xd6\xda\x21\x58\xb6\xb8\xa9\xf8\xfb\xc2\x2f\x32\x32\x4c\x22\x74\x9f\x2b\xeb\x53\x2f\x2a\x92\x21\x24\xa1\x45\x2a\xd5\x17\x51\xcb\x2a\x17\x50\xd5\x9b\xbc\x90\x70\xcf\xeb\xe6\xae\x8f\x33\xb2\x1f\x89\x78\xcc\x93\x1e\xd4\x13\xae\x7b\x9b\x32\x02\x85\x0c\xe7\x52\xeb\xfa\xda\xc6\xda\x0e\x8a\x89\x41\xeb\xc2\x2f\x13\xcc\xed\xe4\x14\xd8\x7f\x10\xed\xb8\x4f\x46\x02\x75\x91\xa0\xac\x11\x2e\x77\x53\x95\xfe\xf7\x27\x81\x51\xdc\x7b\x68\x77\x64\xb8\x9c\x06\xcf\x24\x89\x09\x96\xcb\x76\xbb\xd3\xe5\x78\xcd\x13\x90\x49\x26\xe3\x8e\xec\xea\xbb\xc4\x79\xb1\x6f\x83\x76\xa7\x28\x0d\x32\x0d\x94\x2b\xd4\x6e\xde\xf9\xb4\x21\x11\x48\x46\x24\xce\x2d\x4c\xed\x36\x0d\x9c\x13\xf7\x79\xa6\x4d\xe9\x55\x56\x65\xcd\xf3\xca\x3a\x07\x6e\xd0\x48\xb5\x6b\xa2\xca\x8c\x30\xc4\xa6\xaf\xd7\xfd\x67\x96\x05\x19\x11\x4e\x38\xf7\x72\x54\xa6\x6d\x36\xfc\xea\x4c\x86\x18\x51\x9f\x7d\xf0\x21\xb9\x30\xcc\x1c\x57\x82\x1a\x33\xed\xa6\x70\x15\xee\xa3\xd2\xe0\x31\x96\xbf\xf8\xe9\x7c\x84\xd4\x9f\x52\x27\x59\xe2\x5f\x1e\x97\xa0\x4c\x6e\x99\xdd\xff\x8d\xca\x67\x52\x24\x11\x76\xd7\xf8\x7e\x9f\x5f\x8a\x7d\x7e\x5b\xf1\x7a\xf4\x36\xcb\x40\x60\x15\xd3\x57\xa0\x86\x6f\xa1\x94\x26\xed\x97\x65\xd1\xf0\xbc\xf8\x04\x6b\x2a\x95\x30\xca\x54\x1b\x44\x02\x7f\x99\xc4\x4a\x25\x34\x16\x69\x36\xcf\xcf\x1b\x64\xf3\xcd\x7e\xdf\x58\x92\x90\xc6\x88\x42\x3a\x9a\x05\x2d\x2f\x8d\x05\x8e\xbb\x4c\x50\x5c\x5a\x23\x3f\xeb\xc8\x60\x56\x23\xa3\x94\xd2\x2d\x38\xa0\x63\xec\xa6\xee\xf6\xd0\x60\x99\x1b\xd4\x73\x79\xcc\xe5\x87\xd1\xf3\xec\x5f\xb0\x8d\x89\xa5\xce\x28\xd2\x3f\x2d\x96\x60\x48\xe1\x0c\xba\xbb\x9f\x8e\xb8\x7d\xff\x08\xdc\x53\xd0\x9c\x61\x20\x9b\xcb\x2b\x23\xc6\xcf\x0a\x18\xd7\x5b\x98\xd4\xdc\x28\x4e\xe6\x08\xb1\x1a\x6b\xd0\x80\xd4\x22\x49\x0d\xc5\x40\x0d\xc9\x07\x8a\x04\xdc\xb8\x1c\xe2\x82\xfd\x08\xfb\xb2\xc9\x8d\xe7\x98\x11\x1f\xf5\xc3\x24\x2e\x2c\x3a\xaf\xe0\xbe\x6c\x1a\xa8\x3e\xfa\x50\x5c\x45\x22\xd3\x6d\x3b\x57\xa5\x1a\x10\x27\x69\xd0\x0d\x91\x4e\x6c\x08\xef\x53\x1b\x4d\x5f\x79\x76\xba\x5f\xa4\x48\x1c\x22\xac\xb4\x80\xf7\x6f\x17\x21\xa0\xea\x94\xc4\x40\x91\x44\x22\x66\xa7\xe0\x4d\xfe\x06\xa8\x53\xb5\x7b\x83\x2a\xd7\x1f\x03\x34\x48\x7f\x89\x51\x44\x86\x98\x87\xbe\x57\xb9\xeb\x2a\xba\x23\x9a\x4a\x83\xda\x57\x00\xa7\x91\x08\x15\x28\xca\xb8\xd5\x0b\xb5\xab\x92\x33\x8b\x99\x98\x10\x8a\x66\xe6\x76\xa2\x5f\xf5\x4c\x1a\x2d\x9f\xf6\x99\x0c\x2b\x83\x8a\x4a\x8e\x02\x61\x73\x68\x4c\xf1\xb0\xfb\xda\xe9\x1a\x9b\x0a\xd2\x10\x85\x82\x76\xa7\xdc\xa9\x9c\x8f\xde\x8c\xc1\x23\x57\x61\x60\x64\x61\xc4\xe5\x63\xdd\x48\x77\xe7\xc2\x54\x38\x8d\xbd\xe7\xb2\xe1\x4d\x39\x78\xe1\x55\x44\x12\x24\xfd\xac\xea\xd5\xe2\xa9\x1e\x40\xd6\x55\x04\x21\xf2\x85\x17\xfc\x75\xd0\xd5\x51\x31\xf5\x0d\xfc\x35\xd4\x97\xe3\x7f\x5c\x91\x73\x9f\x4f\x0d\xf2\xeb\x5c\xc1\xbe\x9d\x73\x58\x30\xa9\xfd\xd9\x79\x82\xd5\x9e\xed\x5f\xcf\xcb\xdd\xf2\xcf\xe7\xfb\xa7\xf5\x72\xbd\xbb\x5d\x2f\x57\xdf\xee\xb6\xcb\xb5\x1f\xa6\x12\x73\x75\x57\xac\xd7\xdf\xbd\x55\xc3\x8b\x49\x62\x03\x54\xc5\x2a\x9d\x93\x89\x76\x5f\x92\x52\x42\x8d\x33\x5e\x5e\xac\x64\x89\xab\x4c\x1f\x90\xa1\xd2\x54\x66\x72\x68\xd8\x39\x9d\x74\xab\x94\x31\x14\x27\x38\x5f\xea\x6b\xa9\x95\xe1\x25\xb1\x50\xe1\xe6\xb8\x7a\x5c\x3c\xb9\x2f\x62\x3c\xa5\x96\xfe\x88\x90\x86\x09\x90\x8b\x62\x22\x08\x3a\x71\xfe\x07\xa8\xf9\x0f\xf3\x8e\x8c\xaa\x56\x2a\x93\x46\x9e\x57\x5c\xaa\x62\x0d\xed\x8f\x1b\xd0\x0b\xbb\x2b\xc9\x54\x88\x49\xcd\x0e\xaa\xaa\x87\x18\x1a\x4e\x6d\x4e\x32\xf0\x0a\x68\x27\x70\x99\xd5\xe0\x1f\x37\x94\x0b\xc5\x2c\x82\x76\x66\x68\x0e\x56\xad\x69\x5b\x8e\x9b\xa2\xe3\xf2\xf4\xe0\xa7\x72\xc9\xb1\x84\x71\x33\x9b\x7c\x33\xae\xf7\x0c\x25\x78\x82\xf7\xbf\x76\x62\xba\xa0\x54\x46\x30\x79\xda\x15\xe5\x29\x2f\xbc\xe3\x1d\x28\x05\x3c\xb0\x44\x94\xef\xcb\xbb\xa7\x7b\x54\x50\x7c\x7e\x7a\x72\x45\x17\x05\x24\x44\xba\xb2\x55\xab\x1a\xec\x92\x0a\x38\xc1\xb4\xd6\x8a\x69\xed\x8c\xb0\xdc\x29\x6f\x1a\x50\xeb\xf2\x38\xca\x07\x15\x08\xae\x4d\x47\xe4\xe3\xcf\x82\x9f\x86\x3b\xb2\x02\x48\x48\xdc\xb9\x70\x7e\x56\x02\xef\x2d\x6f\x40\xa4\x42\xff\x55\x87\x46\x9a\x52\x2a\x05\x20\x2a\xc3\x3a\x6e\x5e\x7f\xff\x90\x4e\xb8\x77\xb8\x8b\x40\x40\x03\x61\xbb\xa1\x05\x6a\xb9\xc3\xaf\x6d\xe9\x9e\xdb\xf0\x67\x40\x90\x18\x62\x52\x1b\x5b\x7e\x2f\xf3\x57\x98\x16\x18\x1d\x7f\xc8\x9a\x2f\xf2\x63\x05\x5c\x7d\xac\x8a\xeb\x0e\x14\x04\xc0\xb1\xf4\x90\xd7\x6d\xc2\x73\xc7\xdf\x86\xf1\x3f\x44\x01\xe0\xc3\xd8\xf5\xa4\x41\x06\xdb\x42\xfc\xc9\xb7\xc7\x91\xe1\x3f\x6f\xff\x7a\xf9\xfd\x04\x82\x38\x02\x24\xae\x96\x85\xb1\x65\x18\xd0\x8a\x47\x75\x58\xea\xf7\x35\x88\x63\x99\x19\xf9\xc0\x95\x7f\x9b\xa1\xfd\x1b\xf7\x68\x90\xb5\xb5\xe9\x1a\xfd\xee\x18\x40\x07\x3d\xf5\x22\xd3\x1c\xef\x35\x12\x20\x09\x22\xc4\x23\x1e\xf2\xfd\xc1\x10\x0d\xdb\x0c\xb4\x0f\x02\x85\x24\x4e\x42\x47\x9e\x9b\x39\x6d\xc1\x7a\x5b\x3e\x1f\x3d\x81\x14\x12\x11\x60\x25\xc9\x2a\xe8\x3e\xe0\xbb\x60\x6a\x12\x76\x44\xaa\x23\xf4\x88\x79\x58\x3d\xee\xd6\xcb\xfb\xe5\x6c\xb3\xdc\xf5\x08\x5a\xc0\x88\xa2\x56\x23\x51\x1e\x40\x5d\xbc\xc9\x3d\x00\xa3\x19\xee\x30\x37\xbc\x29\x6f\x96\x7f\xfe\xef\x56\x69\x60\x29\x09\xb9\xf7\x8f\xda\xb7\x9f\x78\xd2\x8e\x5c\x53\xa8\xd5\x74\xf3\xd9\x2d\x51\x90\x25\x46\xb7\x6f\x8f\xd4\xcd\xd1\xcc\x15\x71\x46\xba\xe0\x1a\xf3\x82\xea\x63\x1a\xbf\x68\x3f\x21\x03\x82\x31\x9c\x69\x6f\x6c\x79\x3d\xe2\x05\x82\x0a\x0c\x49\xcb\x35\x58\x67\x37\xee\x76\x00\x35\x40\x99\x3b\x7e\xe0\xbd\x5c\x03\x20\x60\xb8\x4f\x9b\xde\xcf\x74\xb0\x0c\x10\x27\x18\x6c\x60\x5f\x6f\x25\xcb\xf6\x04\xd3\x2e\xe8\x00\x90\x28\xaa\x3b\x63\xbd\xbf\x5f\x72\xf9\x8a\x86\x86\x86\xbd\x31\x99\x29\xb6\xbf\x4c\x22\xef\x21\xdf\xf3\x9f\xbc\x19\x80\x08\x41\x83\x51\xe8\x01\x95\x37\x98\x3a\x0f\xdf\x19\x33\x4a\x13\x6a\xea\x96\x88\xcc\x33\x8a\xe7\x3d\x8f\x20\xd0\x24\x34\x82\xeb\xc7\xbc\x69\xb8\xce\xdb\xb4\x7a\xc1\xcf\xf5\xe5\xd8\x21\xbf\x26\xc5\x92\xa6\x1e\x84\x26\x61\xa6\xed\x83\x50\x1f\x1b\x18\xd1\xa2\xb4\x13\xf1\xf6\xb2\x22\x17\xe3\x66\x3d\xf8\xd1\x9a\x66\x41\x6c\x79\x00\x98\xe4\xae\xfb\xb0\x82\x7e\xb0\xa7\x29\x0f\x31\x0d\xfb\xeb\xe9\x25\x5b\x3c\xad\x1e\x07\x4b\xcd\x60\xe5\x18\x5e\x26\xe5\x02\xc1\x65\x67\x44\x86\x99\xf3\xdb\x43\x41\x10\x01\x0c\x15\xb8\x9e\xaa\xc7\xb2\x3a\x8d\x97\x03\x1d\x24\x0a\x53\x0f\x6b\x86\xb1\xb4\x69\xb7\x3f\x91\x50\xd8\xff\x92\x97\xaa\x7a\xbc\x9c\x9e\xb4\xad\xd4\xfa\x1b\x1f\x5a\xe9\x63\x33\xcd\xbf\xe7\x4d\x93\xf7\x0e\x82\x11\x74\x74\xcc\x5f\xa8\xd6\xd6\xf6\xd9\x8d\x88\x24\x17\xce\xe4\xcd\xec\x77\x33\xdd\x0c\xe1\xa9\x3a\x26\x41\xc6\x7c\xe6\x5b\x7d\x0c\x63\x60\x1d\x33\x63\x90\xea\x2b\x53\xc8\x70\xf7\xd7\x10\x33\xb0\xe6\x2c\x0d\x3f\x7e\x2b\x4b\x4b\x5d\xe8\x0a\xc6\x3a\xce\x14\xb1\xd8\x72\xcc\xc5\xab\x01\xb5\xc4\x0d\x12\x46\x83\xaa\x02\x9d\x3b\x77\xa8\xe1\xeb\xa9\x63\x30\xfc\xa9\x0a\x6a\xd9\x2e\xa7\xfd\xb4\x45\x27\x14\x90\x76\xa0\xf8\x07\x52\xa0\x71\x39\x75\x5c\x53\x9d\x06\x86\xa8\x3b\x3b\x9e\x0f\xdc\xa0\xe1\xf0\x35\x1e\x3e\xab\x54\x82\x55\x1c\x71\xe8\x90\xd1\x15\x30\xca\x31\x02\xdb\x42\xdd\x20\xd2\xe3\xbd\xc4\x5e\xbe\x41\x16\x8f\x74\x68\xfe\xa7\xff\xfe\x47\x4b\xaa\xce\x08\x45\xac\x30\x56\x13\x1c\xec\x66\xe0\xbc\x39\x72\x87\x04\x9d\x05\x0c\xe1\x8e\xb7\xfc\x22\xc7\xd8\x63\x9d\xc5\x32\x31\x56\x0e\x06\x0a\x67\xda\x2e\xde\x90\xdf\x68\xb2\x5a\x1a\xc0\xf0\x93\x92\x18\x2d\x8c\xed\xcb\x7c\xd9\xbe\x56\xee\x5e\xcb\xc0\xa4\x84\xa7\xbc\xb0\x71\xcf\x6d\x59\xcd\x8a\xda\xeb\x2e\x83\x96\x42\x84\xa1\x27\xb0\x28\xfb\x2d\xa3\x9b\x2d\x21\x42\x9a\xc8\x80\x5d\x69\x11\xc3\xd3\xf7\x46\x82\x69\x35\xe0\xec\x59\xdf\x3c\x8e\x4e\xa8\xc2\x08\xdf\x96\x9b\x8f\x82\x9f\x72\xb9\xf9\xfe\x2b\x18\x8f\xc8\x28\x35\x75\x02\x59\x2a\x0b\xf3\x1a\x5f\x16\x10\xc0\xd5\xe9\xf9\x50\x42\x91\xff\xba\xbd\x14\x6a\x88\x0b\xd5\x10\x64\x91\xf4\x04\xa0\xdb\xaa\x3c\x99\x22\xb2\xba\x8e\x92\x34\x24\x11\xb6\x64\x57\x85\xce\x8b\xbc\xf9\xb8\x2b\x2f\xd5\xfe\xc8\x7d\x6b\x57\x6b\x1a\x25\x16\xb3\x38\x7e\x36\x5f\x47\x69\x5a\x07\x69\xdc\x91\xf6\x9f\xab\xf2\xd7\xc7\x40\x9b\x62\xb4\x9e\x6a\x61\x34\x2a\xb6\xdb\x6d\x7f\xff\xd0\x5a\x33\x66\x6c\xc3\xcf\x2f\xe7\x41\x55\x42\x13\x12\x68\x0d\xbd\x37\xbb\x7d\x27\xba\xae\x83\x26\x24\xe2\xa8\x26\x73\xe6\x55\x93\xcb\xfc\xcc\x0b\x63\x76\xbc\x98\x36\xbb\xed\x5f\xbf\x26\x24\x31\xe6\x16\x6d\x88\x99\x17\xfb\x9d\xe4\x95\xda\x5d\xce\x55\xbe\x3f\x34\x3b\x2b\x1b\xce\xdc\x58\xc6\x4d\x89\x0b\xb7\x76\xd4\x2b\xb6\x47\xa8\x10\x21\x73\xe4\xd6\xda\x18\x7d\xbc\x95\x12\xaf\x74\xea\x46\x68\x12\x87\x46\x10\xa2\xd3\x5a\x71\x8e\xaa\xff\x49\x9e\xac\x49\x1c\x1b\x21\xe1\xd3\xc0\xe5\x4c\x93\x38\x31\x48\xa5\x36\xe1\xb2\xc5\x04\xa4\x31\x55\x3e\x73\xd5\x24\x96\x21\x37\x58\x52\x34\x12\xb5\x4f\x7c\x58\x12\xd7\x24\x49\x35\xd6\x70\xe7\x79\x23\xdb\x58\xe2\x72\xf2\xa1\xa3\x26\x49\x96\xe1\x86\xe3\x76\xcf\x6d\x39\x87\x02\x10\x15\xea\xc0\xed\x9a\xa4\x84\xa3\xe4\xeb\x7b\xde\x1c\x72\xfb\x5a\x59\x19\x6d\x3b\x82\x65\x99\xb6\xcc\x73\xeb\x67\x66\x82\x72\x1b\x21\x6b\xc2\xb8\xe9\xa8\xa3\xe4\x51\xd9\x5b\x2b\xff\x11\xfa\x21\xe0\xa9\x7a\x73\x68\xfa\x4d\xb5\xd1\x2d\x6b\x07\xea\x1e\xa7\xcf\x2c\xff\xcf\x50\x19\x06\xf6\xb0\xe8\xa4\x49\x46\x53\x6a\xb5\xbf\x67\x9f\x4a\xcc\x7c\x91\x88\x6a\x92\xc5\x42\x0b\x57\xff\xd9\x40\xa1\xe6\x9f\x5c\x59\xc6\x95\x51\x2e\xad\x78\x5e\x3c\x0c\xcb\xc8\x9a\x64\x42\x51\xe5\x85\x87\x9f\x2b\x98\x30\x9b\x6f\x47\x81\x99\x10\xa8\x1e\xf7\x93\xbf\x41\x3d\x95\xdc\x69\xc2\xa9\x31\x4b\x16\xb9\x52\x50\xa1\xae\xbd\xc7\xb2\x6a\x22\x12\x6a\x2a\xf7\x46\xf4\x72\x89\xc2\xca\xca\xe8\x7b\x0f\xe7\x87\x50\x0c\x69\x1c\xef\xbc\x68\x67\x91\x3b\x81\xcc\x22\x57\xf5\xf8\xdb\xa5\xca\x6b\x65\x5b\xdd\x7f\x0c\x6e\x8d\x54\x21\xd6\xee\x67\x7e\xfa\x5f\xc9\xa7\x0e\xaf\x5a\x85\x31\x78\xc1\xfe\x2e\xdb\xf1\x79\x88\x26\x8a\x67\x11\xae\x44\x65\x79\x2c\xb5\x5e\x15\xb2\x82\xae\x4e\xa8\x09\x28\x12\x5a\x6e\xde\xf7\x5c\xbe\x3e\x69\x3d\xd1\xa0\xd6\x44\x93\x08\xe3\xf7\x4b\xe1\xbd\x3e\xbf\x42\xd3\x5c\x3f\xcc\xf6\x71\x6a\x87\x46\x50\xd0\x05\xf2\x9a\x92\x40\xa2\x48\xa6\x85\xba\x39\x5e\x83\x0b\x80\x35\x25\x3c\x94\xb6\xfa\x55\xf3\xa3\x69\x1a\x0e\x50\x38\x9a\xd2\xc4\x30\xb7\x51\x41\xb2\x90\xc3\xb5\x92\x46\x56\x58\xa4\x6a\x17\xc0\xb0\x17\x5c\x6b\x1a\xf3\x00\x93\x7a\xd3\xc5\xff\x7a\x59\xa4\x31\x4f\x7c\xc7\x7a\x71\xb7\x6b\xc3\xfa\x5d\x38\x50\x84\xd1\x34\xe1\x06\x97\x5a\x01\x8a\x38\xcd\x8c\x27\x7c\xfd\x89\xd6\xb7\xa6\x69\x68\xfc\x78\x2f\x45\xed\x65\x36\xf9\xb4\xd5\xbb\xa6\xa9\x20\x88\xfe\xc2\xea\xfc\xe8\x16\xa4\x22\xcd\x54\x47\x0d\xb9\x12\x77\xd6\xb4\x8d\xb1\xda\x37\xef\x66\xf5\x6d\xf5\x7c\x3f\x5b\x2c\x6f\xdc\x67\x19\x51\x68\x78\xf8\x7a\x51\x65\x3d\xfa\x14\x4b\x15\x6a\x3b\xd5\xa8\x4a\x38\xcc\x38\xdc\x10\x11\x27\x56\xc5\xe1\x7b\x21\x9f\xa1\xc2\x26\x46\x0d\x1d\x71\x50\x53\xa6\x29\x91\x9d\xd2\xc3\x27\xf8\xff\xd1\xef\xcd\x68\x10\xa3\x72\xc2\xa5\x90\x87\xa7\xcb\x10\x2c\x69\x4d\x3e\xdb\x6c\x24\x41\xdb\x84\x6f\x7c\xcf\xab\xbc\x5f\xea\xd0\x94\x07\x3c\x0d\x1d\x8d\xed\x7c\x2c\x3f\xa0\x9a\xbd\xed\xd7\x1c\x89\xfd\xd3\x5f\xca\x23\x49\xfb\x06\x38\x3d\x6d\x8c\x7a\xa4\xa1\x37\xbc\x53\x9c\xa5\xa8\xaa\x79\xb6\x75\x8e\x07\xfe\x0a\x33\xf5\xf6\x05\xcd\x4e\x53\x41\x21\xa6\x5e\x24\xb1\xbc\x85\xf7\x3e\xb9\x43\x53\xc1\xa4\x0c\xbb\xa4\xb4\x9e\x7f\x8c\xe6\xb6\x10\xc6\xa0\x51\xf1\x0f\xb4\x74\x1d\x3d\x3d\xa1\x35\xbe\x18\xbb\xbe\x82\xe6\x70\x88\x0c\x62\x2c\x66\xdc\x95\x47\xfe\x70\x29\x54\xe9\x4e\x2d\x21\xb2\x35\x8a\xd5\xf6\xc9\x19\xd1\xbb\x83\x20\x64\x64\xa4\xdb\xa0\x7d\x92\x45\xf3\xed\xe2\x3d\xbc\x34\x05\xa9\x81\x0c\x00\x88\xdd\x6a\x4a\x35\x31\xed\xbe\x33\x2e\x58\xbd\x49\x12\x90\x98\x23\x83\x1f\xb5\x68\x9f\xd7\xab\xc5\xb2\x3b\x22\x99\x83\x6e\x56\x5c\x1e\xf3\x7f\xc3\x82\x1f\x8f\x02\x1d\xac\x7b\x39\x53\x3b\xd2\xa8\x72\x99\xd8\x6b\x5e\x96\x47\xe0\x6e\x3a\x04\x54\x45\x19\xf3\x5e\x17\xed\x35\x0d\xee\x45\x10\x6a\xe3\xe8\x68\x66\x69\x05\x03\x6e\x97\x0e\xa2\x90\x49\x61\x05\xbb\x6f\xaf\x0b\xaf\x76\x54\x2c\x29\x52\x6a\x50\xd5\xc6\x28\xb1\xcf\x3f\x0c\x55\x6b\x38\x30\x21\x19\x58\x87\x4e\x8b\xf6\x01\xb4\x26\x9d\x48\xa5\x75\x90\x68\x99\x76\x5a\x79\xc8\x1a\x77\x64\x0a\x1d\xa4\x99\x99\xe6\x0b\x5e\x1f\xfa\x33\x7b\xf8\x7d\x2c\x4e\x71\xad\x79\xcb\xe1\xfd\xf6\x52\x48\xf7\x69\x26\x23\xec\xf9\xe6\xf5\x4a\x96\x3d\xc6\xaa\x3d\x9c\x11\xb3\x02\x2c\x7f\x9d\xf3\xf6\x66\x58\xf1\xf9\xfe\x3b\x18\x64\x21\xe0\x5d\x77\x9e\x7b\x79\xd1\xb5\x19\xdc\x90\x48\x78\x87\x9c\x95\x59\x3c\x83\x64\x78\x7f\x33\xa6\xb3\xd0\xaa\x64\xe2\x67\x87\x4a\xc1\x3a\xe0\x51\xca\xda\x5b\xfb\xfd\xaf\xc5\xee\xc7\x72\xbd\xba\x5d\x2d\x66\xdb\xd5\xd3\xe3\x6e\xf9\x78\xb3\xeb\xa0\xc7\x3a\xe0\x00\xdc\xd9\xb0\x7e\x9c\x61\x34\x47\x04\x49\xcc\x6e\xef\xab\x7f\xa1\xfb\xa0\x60\x0c\x9c\x17\x05\xfa\x77\x1e\xd0\x6b\xfb\xec\x8e\x4b\x9a\x60\xfe\x74\xae\x50\xaf\xe6\x7b\xf9\xf6\x69\xaf\x56\x07\x32\x92\x9c\x39\x81\xca\xba\x19\xfc\x14\x20\x14\xe3\xa0\x36\x33\x71\x98\x2f\xd5\x1d\x04\x69\xd2\xe1\x13\x6f\x83\xc4\x9e\x02\xb1\x0e\x20\x63\x48\x3c\x7d\x2e\xf3\xba\x36\xfa\xc0\xee\x90\x8e\x09\x32\xe6\x17\xf7\xb3\xd5\x83\xf1\xc1\xf8\x31\xbb\xdf\xdd\xcc\xfe\xb2\xb8\x35\x1d\x12\x12\x63\x12\x65\xfc\xdb\x0e\x55\xf9\xee\xe9\x62\x3a\x24\x54\x30\x67\x27\x03\x0d\x57\xbc\xe1\x77\xbc\x3e\x0c\x9e\x52\x48\x45\xc4\xc8\xc8\x39\xea\xcb\x75\x3c\xa4\x52\x60\x32\x82\x84\x15\x2c\x19\xd9\x68\x6d\xa2\x5f\xfb\x75\x20\x11\x06\xda\x90\x7d\xf3\x7a\x63\xec\xa0\x17\xe5\xe9\x7c\x84\xee\xde\x85\x61\x98\xc6\x5e\xfe\xb5\xb9\x54\x05\xa8\xde\x2d\x0a\xc3\xc8\x90\x4b\x3d\xa8\x65\x8d\x50\xee\x95\x1a\xfe\xc8\x50\x52\x4c\x81\x96\xcd\xe1\x52\xc1\xc9\x7d\x3a\x0a\x8d\xce\x89\x11\xd5\xe4\x45\x5e\x0f\x9c\xa6\x26\x4b\x70\xee\xa3\x59\x88\xb8\x53\x1b\xe7\x60\x36\xd6\xef\x83\xe8\x30\x61\x54\x5b\x5c\xce\xf7\xc7\x45\x6f\x61\x0c\xd3\x28\xc6\x47\x0e\x26\x79\xf1\x8c\xae\x1d\x1f\x75\x47\x70\xa8\x12\x3e\xc1\x97\xaf\xf5\xfc\x63\x56\x35\x13\x9e\x38\xa3\x1b\x9b\x0a\xe3\x77\x56\x7b\x4b\x54\x9f\x1b\x85\xa9\x36\x35\xd8\x36\xea\xc7\x7c\x6c\x5b\xae\xcb\xe3\x98\xb2\x3e\xf8\xb5\x8c\x18\x93\x86\x76\x26\xb5\x91\x3e\x72\x87\xa7\xb0\x83\x6e\x7c\x62\xec\xe6\x6d\x83\xa8\xc7\x95\xd4\x21\xe3\x11\xba\x3c\x1a\x00\xe0\xcb\xe6\xc6\xe1\x28\xbb\xab\x67\x22\x63\xa4\xa7\x31\xe1\x59\xe4\x79\x59\xf4\x85\x24\xdd\x70\x88\x11\x62\x66\x15\xb2\x3d\x6c\x6f\x38\x2a\x23\xc6\x08\xe5\xef\x7f\x2d\x16\xee\x5a\x78\x10\xa5\x41\x07\x33\x47\xea\xe9\xf4\xdb\x1f\xf2\x8c\x61\x54\x85\xfa\x90\xa3\x7d\x3b\xe4\x2a\xc1\x8d\xff\x3b\xff\x28\xbf\x6c\xfc\x4c\x35\x58\xba\xea\x9d\x0e\x85\x32\x32\xcb\xca\x92\x4a\x3e\xb9\x18\x19\x18\x8f\x90\x0a\xfe\x09\xb2\xb9\x2b\x2f\xce\xd9\xb4\x3d\x24\x03\xd6\x83\xdf\xf8\xbe\xec\x44\xd7\x5c\x87\x52\x44\xc8\x97\xb4\x0f\xca\xbc\xc8\x5d\xc6\x11\x4a\x65\xb4\x24\x1b\x87\x6c\xac\xe7\x1f\x43\xeb\xcd\xe1\x85\xa9\x58\x62\xc9\x66\xb5\x78\x7a\xe6\x97\xba\x7b\x8f\x15\x28\xdc\x0c\xde\xca\x5f\xb7\x5c\xf8\xbf\xea\x48\xd8\x04\xb4\x53\x55\x42\x55\x29\xb3\x1f\xb9\x4c\x35\x04\xca\xb0\xe4\x04\x85\x32\xb2\x69\x26\xc9\x1e\xa1\xd2\x74\x08\x91\xa2\x16\xb3\x34\x6b\x5e\x1f\xcb\xf7\xdb\xb2\xb2\xd4\x8b\xe1\x0f\xd7\x61\x98\xb1\x7e\x8b\xa2\x50\x6d\x08\xb2\xfc\x75\xe6\x58\x18\x1b\x3f\xb7\x21\x89\x6f\x74\x2e\x46\x31\xa5\xb1\x04\x6f\x6f\xca\xfd\x49\x52\x65\x3e\x15\x91\x48\x20\x91\xdb\x52\xd0\xf1\xd0\xc8\x9a\xd9\x8d\x54\x19\xb6\x8d\x15\x1c\xf9\xc7\x4d\x59\x3c\xf7\xe5\x7c\x47\x67\x0d\x69\xe2\xf4\x65\x6f\x40\x43\x61\x29\x02\x58\x31\x73\x43\x98\x49\xff\xd6\xb9\x3c\x3c\xe6\xfb\x3d\x77\x73\x27\x8a\x88\x8a\x53\xdf\x66\x6a\xa7\xd6\x1a\x30\xf1\x1d\x7e\x47\x14\x4b\x14\x63\xab\x2f\xa2\xcb\x71\xfa\xeb\x45\x14\x69\x89\x5b\xc4\xae\x3d\x53\x99\x8f\x79\xba\x3a\x8a\xc3\xcc\xf8\xcd\xcf\x1f\x6e\xfa\x21\x7e\x14\x0b\x16\x3a\x25\xc8\x2a\x3f\xf1\xea\xc3\xd6\x34\x07\xe7\x8f\x41\x62\x81\x12\x4e\x79\xd3\xbe\xb4\xbc\xc7\x47\xb2\x43\x12\x92\xe0\x84\x43\xdd\xd7\xe7\x4b\xbb\xb9\xe4\x8d\xd3\x3f\xd5\x51\x12\xc7\x68\x65\xd4\x06\x36\x47\xf8\x18\x5c\x43\x9a\x44\xa9\x53\xaa\x5e\x7c\xc5\x6d\xd6\x11\x23\x1a\xf3\xb4\x73\x55\xb6\x71\xd6\x34\xf6\x52\x47\x2c\x91\x3c\xf1\x65\xb5\xc5\x21\x17\xf9\x6d\x59\xdd\x5e\xea\xb1\xc5\x8b\x8e\xb2\x50\x42\xd2\xc9\x96\x19\xbc\xa7\x9d\xa4\x5c\xe4\xc7\xbc\x71\x3b\x4c\x94\xa5\x31\x66\xa7\xb5\x6d\x3a\x6e\x3f\xa9\x2f\x8c\xa6\x48\xc6\xb4\x95\x8f\xbf\xea\x06\xea\x88\x53\x19\xdb\x98\xd9\x58\x00\x8c\x8f\x67\x09\xde\xf9\x3e\x02\x6c\x5b\xfe\xe0\x97\xe3\x6f\xb6\xa4\x88\x0b\x8a\xa8\xb5\x93\x11\x07\xbf\x2d\x2b\x77\xbd\x6b\x68\x1f\x6e\x57\x1a\x64\xee\x13\x90\x30\x13\x24\x9b\xe3\xc6\xb3\xaa\xcb\x92\x23\xae\xcd\x2c\x3a\x77\x84\xfc\xe9\xef\x16\x3a\x55\xc6\xb0\x0b\x2a\xf8\x35\x8c\x1f\x23\x99\x12\x2c\x4d\x2d\x37\x8b\xf5\xd3\x4f\xc7\x59\xb4\x62\x2c\xee\xab\x54\x4c\xf1\x5e\x2f\x0e\x20\x5f\x57\x0d\x9c\x96\xbf\xf2\xfa\x6a\x5a\xab\x84\x63\xa0\x7a\x5f\xee\xd7\x50\x5f\xbc\xd6\x83\x8e\x14\xa7\x48\xbb\xde\x97\x47\x75\x0b\xe0\xff\x2c\x52\x8c\x1b\xb1\xf8\x67\x00\x13\xa3\x53\x42\x94\x60\x3a\x5e\xb5\xa9\x87\xc5\xf3\x4d\xd0\x82\xda\x81\x2c\xca\x86\xad\x34\x93\xa6\xb8\xe3\x32\xe6\x69\x5f\x27\x19\xc3\x45\x7f\x54\x05\x98\x76\x73\xa5\xb6\xa5\x87\x7e\xe1\x66\x3f\x22\x22\xb7\x63\x63\x83\x11\xef\x5b\xd3\x63\xff\x26\xe8\x4e\xa7\x52\xe7\xb4\x77\x3c\xce\xd4\x4a\xd5\xf3\x8f\x36\xe7\x1d\xbd\x18\xa0\x33\xc7\x6d\xdb\xc2\xaf\xf1\x42\xa3\x55\x8a\xbb\xcf\x7c\xbb\xf0\xee\x5b\xf6\x1b\x62\x22\x53\xe4\xd6\xdf\xae\xfe\xf4\xa5\x8f\x98\x0a\x41\xbb\x35\x75\x5b\x01\xaf\x2f\xd5\x90\xe9\xaa\xe3\x40\x4b\xee\xf7\x34\xb3\xe3\x3d\x43\x85\x17\x67\x47\x84\x11\x35\xc2\x1c\x18\x55\xe7\x27\xec\x4b\x85\xfe\x68\x92\x21\x62\xe5\x66\x79\x3b\x7b\xb9\xdf\xee\xd6\xcb\x1f\x4f\x8b\xd9\xfc\x7e\xe9\x07\xa4\xbe\x7e\xd5\x26\x0a\x3f\x7d\x75\x2c\x0e\x05\xc5\x92\xcf\xce\xa9\xe8\x4c\x6e\x0d\x71\x1c\x0b\x54\xcb\x80\x4a\x06\x04\x1b\x0e\xee\x04\xb1\x30\xdc\x49\xd9\xe6\xc1\xc3\x20\x24\x8e\x05\x4b\xf5\x27\x8d\x7c\x3b\x24\x89\xba\x78\xc7\x36\x8b\x71\xdf\x75\x9d\x50\x1d\x27\x31\x55\xb6\x84\xf8\xc8\x4f\x70\xe8\xf2\x85\x01\xec\x49\xc7\x89\x24\x78\xaa\xcd\x6a\xb9\x38\xf0\xee\x27\x26\x92\x38\x11\xec\x2d\xf0\xd3\xed\xa5\x50\x56\x18\xf8\xcb\x72\x5c\x9c\x48\x93\xf4\xfe\x28\x8f\xaf\x75\xfb\x3a\xb8\xb9\x14\xa7\x21\xc7\x84\xf6\xe5\x71\xf3\x74\x7f\xb3\xc3\xff\xac\xdb\x44\xd1\x0d\x60\x81\x01\xe4\x1d\xca\xf7\x87\x8b\x3c\x38\xbe\x50\x37\x57\x98\x30\xfc\x0c\x7e\x3c\xfe\xfd\x02\xd5\xc7\xca\xa7\x5f\x71\x16\x08\x4c\xef\xb7\xeb\xd9\xe3\xe2\x6e\x19\xec\x66\x8b\x45\x67\x33\xd8\x1e\x97\xae\x33\x73\x7f\xff\xc3\x24\xba\x34\x18\xde\x55\x1e\xc4\x28\xb8\x87\x53\xb1\xbd\x34\x3f\x13\x78\x60\x64\xbd\x8b\xb2\x59\x15\xfe\xad\xc2\xc6\x93\x1f\x12\x45\x58\x0b\x71\x6a\x7d\x3f\x0f\xe8\x42\xa0\xfa\xfd\x9f\x98\x43\x18\x1a\xe4\x03\x76\x9e\x4c\xcd\x76\x38\xab\x45\x64\x24\xe0\xe1\x0d\x8a\xc6\xd4\x9c\xaf\xed\xa8\x47\xf7\x5c\xc4\x04\x4b\xd4\x4d\x39\x0f\x03\x0b\x53\x9f\xac\x55\xc6\x82\x87\xd2\x30\xf0\xbe\xbd\xdc\xcf\xd6\xbb\xed\x5f\xcf\x4b\xff\x80\x04\x4f\x33\xdd\x0b\x39\x1f\xe1\xdd\x36\xaf\xa7\xab\x65\x83\xdc\x22\x16\x1a\x50\x5d\xc6\x86\xed\xff\x11\x3c\x54\xc7\x8a\x19\x8a\x9b\xb1\xab\xa9\x8a\x6f\x97\x8f\xf6\xb9\x6f\xab\x8b\x0f\x74\x62\xa5\x15\xd6\xa2\x6d\x03\xca\xbc\x48\x5f\x01\x6f\xa6\x79\xa3\x3a\x46\xe1\x6e\xdc\xf4\x74\xbb\xd1\x59\x65\x6a\x7b\x50\x13\x95\x98\x86\x7b\xbb\xe0\x7b\xde\x8a\x8e\x35\x4d\x05\x75\x0b\xf2\xe9\xdc\xc0\x8e\xf9\x43\x19\x0d\x8c\xa9\x07\xe2\xbe\xd6\xce\xbb\xc8\x08\x96\xdb\x51\x09\xa1\xdc\xa9\x22\xdc\x95\x97\x1a\x16\xbc\x52\xb5\x65\x5f\xb9\x21\x41\x80\x0a\xdc\x7d\xbd\x8f\xc9\x1b\x96\x10\x11\x10\xee\x88\x54\x13\x3b\xe5\xe0\xa1\x24\x44\x88\x54\x9a\x5b\x77\xfc\x30\x35\xfa\xd3\x94\x2e\xe4\xf0\x46\x25\x34\x26\xd2\x65\xeb\xd8\x9f\xbc\x54\xdf\xe1\xe3\x71\x48\x0f\xd5\x49\x90\x68\xca\x9d\x0c\x7b\x39\xf2\x4b\xd3\x49\x48\x82\xd8\x59\x3b\x5f\xce\x6d\x7c\xa0\xa1\xaa\xa0\x5a\x8f\x85\x4f\xdb\xa1\x11\x72\x14\xda\x1b\x2c\xcb\xbc\x58\xb4\xeb\x95\x3f\x26\x30\x17\xa9\x51\xe9\x78\xf0\xf3\x42\xae\x1d\x8e\xfd\x58\x7e\x2c\xca\xa2\x2e\xab\x26\xbf\x9c\x46\x67\x8f\xd2\x20\xf5\xd9\x37\x40\xfd\x54\x74\xf0\x33\x9d\x44\x59\xca\xc2\xab\x2d\x73\xbc\x5b\x26\x91\x0c\xb1\x69\xa3\x80\xab\x63\x5e\x40\x98\xc4\xfe\x0c\x2a\x40\x96\xf3\xe3\x62\x36\x5b\x1c\xf8\xe9\x9c\x97\x45\x47\x1a\xd2\x49\x1c\x09\x6a\x23\xb5\xaf\x2c\x51\x46\x4f\x3a\x4e\x19\x9e\x75\xbd\xbc\x7d\x79\xbc\x69\x03\x99\xd5\xd3\x8d\x3f\x65\x96\x62\x2d\x77\xd6\xbe\x64\x0e\x44\xb3\x38\x96\x17\x65\x5c\x36\x2e\x85\x07\x9c\xe8\x24\xb1\x96\x2c\xb7\xcb\xe5\x6e\xf1\x74\x7f\xbf\x5c\x6c\x9f\xd6\xfe\x20\xd7\xc4\x90\xdc\x2b\xb5\x6b\xf2\x86\x17\xf9\xe5\xb4\x43\x5d\x06\x3f\x44\x1a\x14\xbd\xfb\x9e\x1f\x50\xed\xfd\xed\x4b\x14\xc5\x37\xf8\xf4\x54\xcc\xa6\x25\xbf\x47\xbf\x2b\xa5\x12\x73\x3b\xa3\xec\xd9\x47\xad\xe8\x84\x25\x66\xca\x9c\xf2\x7d\xc5\x1b\xb0\x3b\x23\xd6\xd0\xef\x61\xcf\xe5\xc7\x1a\xce\x57\x4f\x26\x8b\x75\x60\xd4\x4d\x6e\x8f\x1f\x5d\xdd\x2c\xe1\xa9\xe1\xf8\xa3\xcb\x62\x5e\xda\x18\xa1\x87\x08\xd4\x09\x07\x62\x52\x3e\x5e\x18\x78\xfc\x0d\xbc\xc1\xb1\x3c\x43\x65\x6e\xe3\x73\xe7\x8e\xad\x13\xc5\xb2\xd8\xe8\xce\x9b\xf5\xf1\xa9\xb8\x42\x4d\x0e\xe7\x1d\x48\x86\x41\xb6\x6b\x5a\x3c\x96\xc5\xb6\x3c\xbb\xd5\x61\xf2\xee\xa4\x24\x4a\x30\x77\xf3\xda\x1b\xb7\x4f\xeb\xdd\x76\x39\x7b\xb0\x57\x91\x52\x4d\x11\x3d\x27\xbd\x47\xfe\x7f\xb6\x4b\xa4\x41\xcc\x50\x68\x70\xd7\xc6\x04\xf0\xbe\xac\x9b\xfc\xd4\x8b\x53\x2d\xe2\xd3\x0e\x0e\xd3\x04\xd1\xd0\x47\x7e\x29\xe4\xa1\xf7\xba\xa4\x11\x97\x08\x67\xc1\x84\x6c\xa8\x98\xa0\xd3\x38\x8d\x91\xb3\x72\x9b\xff\x02\x5b\x47\xbb\x16\xea\xfe\xfa\x32\x13\x12\x62\xe6\xe8\x80\xa9\x23\x07\xdf\xc1\x1d\x4e\x13\x6a\x02\x21\xc9\x8b\x35\xd2\x20\x5e\xb6\x7f\x3e\xdd\xf5\xab\x5a\x43\xd0\xb8\x4e\x93\x20\xc2\xc6\xca\xc3\x3f\xcb\x63\x91\x8f\xfa\x75\x69\x12\x1a\xf8\xc9\x3b\x0a\x6c\x2f\x86\x4a\x6f\x3a\x4d\x84\x42\xfc\xe6\xd1\xd5\x8d\x77\x6f\x94\xf9\x83\x2a\x75\x68\xea\x36\x94\xf6\x1b\x48\xca\x22\xc5\x53\x2f\xff\x39\xec\x5e\xa4\x2c\x09\x0d\xa3\x62\xb6\x59\x76\x84\x78\x9d\x66\x44\xb8\x35\xcb\x88\xd1\xbe\x14\x39\x7a\x01\x3d\x73\x94\x8e\x40\x0c\x5e\xbf\xa0\xd6\xfe\x6a\x83\x7b\x72\x67\xa0\x29\x12\xb4\x2b\x07\xd6\xa6\xae\x90\xeb\x9f\x72\x46\x59\x68\xb0\x6a\x5d\x05\xc6\x0c\xe8\x01\x00\xfb\x74\x7a\x9d\x66\x41\xe6\x1a\x06\x4e\x40\x70\x84\x72\x49\xb3\xd4\x64\x69\x79\xdd\x46\x8d\x98\xf0\x8c\xa2\x9c\x34\x63\xb1\xd4\x9d\x43\xf1\xe6\x66\x7c\x5c\x0a\x0c\xd7\x1e\x66\x8f\x77\xb3\xed\x76\xf6\xf8\xbc\x7e\xfa\xf3\xaf\xfb\xe5\x9f\xab\xc7\x6f\xdb\xa7\xc7\xd9\x0f\x17\x9a\xa5\x82\x86\x99\xed\xc5\xdd\x97\xf2\xda\x6c\xb5\x1d\x91\x22\x4f\x63\x03\xcd\xe5\xec\x1c\xc0\x7a\x97\x2b\x69\x94\x75\x76\x76\xd3\xc5\xf2\x54\x85\x26\xeb\xad\x2f\xc2\xab\x8f\xf4\xc1\xb9\x3a\x55\x29\xa5\xe0\xc4\x0e\x11\x87\x6e\x2c\x89\xa0\x5a\xa9\xfe\xd7\x29\x69\x9c\x11\x3b\x51\x75\x53\x88\x73\x87\x81\x32\xe3\x5f\x50\xa8\x23\x74\xe0\xc1\x1b\x30\x8a\x12\x9f\x2c\x1b\x5a\x01\x03\xdb\x04\x43\x83\xaf\x7a\xaa\x8c\x6f\x06\x33\xaa\x89\xc8\x3c\x4c\x09\x73\xf7\xfb\xb1\x2b\x88\x66\x21\x8f\x5c\xb1\xc3\xda\xe0\xb8\x03\x6d\x1a\xde\xd9\xdb\x9f\x2e\xa7\x11\x9e\xdf\x8e\x8b\x08\xc5\x44\x66\xb3\xbc\xbf\xdf\x6d\x9e\x6e\xb7\xbb\xfb\xd5\xc3\xca\x85\xe4\x2c\x62\x12\x83\x8c\xdd\x99\xcb\xd7\x07\xfe\x0a\xd8\x10\xf8\xb2\xf8\xc0\x62\x92\x24\xc6\x62\x51\x1f\xe1\x97\x3b\x53\x1c\x02\x42\x7a\x1f\xee\x17\xfd\x02\x10\x8b\x65\xdc\x99\x6d\xa9\xdf\xc3\x23\xec\xc7\xda\x15\x88\xb8\xc6\x88\xe9\x56\x2c\x9b\xc3\x4a\x5b\x35\x8a\xd1\xe0\x50\xa2\xb3\xee\x3c\xbf\x2e\x36\x4e\x3e\x2a\x96\x24\x14\xf9\xfb\xf0\x2b\x1f\xdf\xb1\x24\x53\x58\xcd\xac\x1b\x38\xdf\x96\x97\xea\x8f\xe1\x51\xa9\xd0\x85\xf2\xcc\xab\x1a\xee\x4b\x5e\xa0\xe2\x73\x1b\x4d\xf9\xe5\xf1\x1f\x94\xfc\xb7\x9d\x96\xff\x88\xdc\xe3\x4e\x94\x51\xf1\x50\xd5\xa5\x78\x2d\xba\xd5\x8e\x25\x3a\x45\x55\xfc\x77\x4c\xec\x9e\x8f\xbc\xd1\x65\xe5\xc2\x56\x96\xa6\x29\x35\xa0\x09\x74\x00\x7b\x29\xf8\x3b\xaf\x14\xa8\x87\xd5\xbd\x3f\x43\x9a\x05\x41\xd6\xd9\x1d\xd7\xd7\xa5\x01\xc6\x12\x8a\x80\xca\xb2\x38\x1a\xbc\xdd\xac\x50\x8f\x6d\x1e\xe5\x21\x5a\x2c\x93\x46\xa2\x23\x2f\xf2\x66\x9b\xf7\x3c\x0d\x26\xe6\xae\x60\x1a\xc7\xde\x83\x1a\xeb\x8f\x69\x26\x32\x43\x89\xdf\x43\xb3\x3a\x21\x13\x72\x5d\x96\x4d\x9f\xb8\x3b\x0e\x78\xfd\x79\x65\x90\xe0\xcd\x55\x15\xdf\x97\xc5\x94\xb5\x89\x66\x2a\x0a\xac\x0e\xb1\xeb\x0c\x0f\xed\x29\x34\x53\xb1\x71\x8e\x3c\x5f\xa6\x35\xa4\x34\x53\x5c\x83\x71\x72\xa8\xcb\xa3\x9a\x19\x37\xc0\xbc\x2c\x7a\x44\x5e\xcd\xb4\x92\x58\x4e\xaa\x2f\xf5\x19\x46\x78\x4a\x9d\xd1\x28\x92\xbe\xf0\xb1\x33\x3e\xba\xbb\xb2\x9d\xe0\xbb\x73\x79\xfe\x8a\x42\xa0\x33\xaa\x85\xe1\xfa\xd7\x1b\x24\x91\xce\x47\x55\x95\x2c\x88\x0c\xf0\x60\x27\x8f\xc0\xad\x6a\x9b\x8b\x2f\x06\xbf\x24\x0b\x22\x19\x39\x2b\xc9\xd1\x15\x06\xb1\xf1\x80\x77\x81\xcf\x06\xda\x38\xe5\x7f\xc2\x30\xd5\x59\x18\xc6\x91\x87\xa4\xfd\x28\x1b\x78\x2c\xef\x7b\x9c\x82\xeb\xa9\x91\x85\x51\x88\xfd\xb8\xf3\x91\x7f\x98\xf4\x6a\x73\xe9\x5e\xb1\x6e\x98\x02\x64\x27\xdb\xd2\x27\x25\xc4\xaa\x09\xb8\xab\x8f\xac\x55\x63\xbb\x27\xba\xf5\x71\x20\xea\xae\xb3\x28\x0b\x59\x27\x46\xe8\x7c\x12\xa7\x52\xb0\x2c\xca\x38\x86\x98\xd0\x1c\x78\x7d\x18\x05\x4c\x59\xc4\x99\xb6\xe9\xdc\xcf\x2a\x6f\xe0\xda\xb7\xda\x5f\x77\xac\x12\x6c\x44\x72\xab\x04\x63\x63\xe3\xd1\x53\x89\x55\x86\x0c\x3b\x0c\x0d\x46\xf8\x90\x2c\x49\x39\x16\x29\x56\xb5\xdb\xbb\xd5\xa8\x49\x6a\x07\xa6\x2c\x46\x17\xb7\x1d\x56\x98\x7a\x5d\x87\x2c\x05\x23\xf2\xad\x72\xb5\x28\x11\x67\x39\x39\xcf\x33\x16\x19\xf8\x82\xd1\xe4\xf2\x42\x12\x3a\xcb\x80\x62\xd2\x98\xd7\x26\xc4\xee\x84\x68\x75\x96\xe9\x10\x29\xfe\x0f\xfc\x43\xc0\x33\x54\xed\x72\xd4\x3f\xce\x25\xe9\x4b\x90\xd6\x9b\x86\x37\xb9\xec\x60\x6b\x99\x88\x98\xf0\x44\x46\xcc\xd5\xb3\x41\xb8\x95\x09\x9d\x61\x9d\x08\x4b\x82\xce\x4b\x64\x30\x42\x06\x21\x66\x56\x3b\x05\x0d\x54\xa7\xbc\x80\xbb\x7c\xb2\xf9\x91\x49\x6b\x6d\xb1\x87\x06\xb7\x5c\x5f\xdb\x7c\xaa\xda\xcc\xc5\x5c\xe2\x00\xb1\xe9\x3e\x28\x0c\xfe\x07\x35\x6f\x7c\x9b\xd3\x1e\x54\x34\x44\xed\x52\x9c\x9c\x79\x59\x6c\x64\x3f\x61\x77\x83\x02\x82\x26\x6e\x2f\x45\x3e\x2f\xdf\xfb\x9b\x5e\xa6\x42\x8a\xaf\x25\xbf\x34\xe5\x3c\xaf\x46\x6a\x1f\x3a\x53\x9a\x20\xa6\xbb\x7d\xa5\xd6\xf0\x06\xfc\x38\xd1\x26\x9b\xdc\x18\x33\x1d\x1b\x6f\xac\x63\x9b\x24\x0d\x20\x51\x9c\x48\x8a\x7d\x98\x1b\x38\x42\x03\xed\x36\x60\xfc\x6c\x87\xd7\xcd\x89\xcc\x10\x4b\x5c\xc0\xfb\xe2\xd0\x49\xff\xda\xa3\x41\x40\x30\x4f\x35\x3e\x29\xcb\x7f\x91\xc1\xca\xdd\x6b\x4c\xf3\x20\x62\x28\x96\xb1\x81\x66\x33\xdb\x96\x4b\xff\x5a\x8d\x4e\xc8\x14\xf2\xc7\x5d\x77\x70\x9d\xef\x0f\xcd\x4a\x7b\xee\x9f\xe7\x5d\xf4\x17\x71\x1e\x46\x86\xf6\x70\x46\x49\xac\x4e\xb7\x51\xf3\x30\x33\x4e\xbb\xed\x9e\x3b\x53\x6a\xf4\x6d\xa1\x0e\x71\xe9\xe4\x4a\x5d\x87\x53\x3c\x22\x04\x67\x5e\xcf\x6d\xdd\x9b\xc0\x59\x5d\xec\x3f\xfc\x50\x8e\x65\x8d\xfa\x72\x72\x15\x79\xe6\x8f\x45\x59\x90\xf8\xe0\xeb\x81\xff\x32\x84\x53\x13\xf9\x4f\x3e\x36\x1e\x49\x6e\x01\x52\xcd\x0d\x42\xbe\x4d\x36\x3c\xd5\x08\xe3\x31\xe7\x99\x1a\xaa\x3e\x98\x8d\xe2\x6e\x04\x62\xfa\x5f\xb2\x3b\xec\xd7\x24\x32\x44\x14\x3f\x8a\x1c\x85\x0f\xdc\xb8\x0b\x8c\x6e\x43\x22\x53\x23\xc0\x64\x12\xd6\x8d\xab\xe2\xbb\xe3\x69\x92\xe2\xcb\x6e\x0a\xe5\xf3\xf2\x97\x3f\xc0\x53\x24\xc9\x8a\xcb\xc7\x0a\x3d\x13\x67\xc7\xe3\xb0\xc8\xce\x53\x2e\x75\xe7\xc3\xde\xf9\xb0\x4e\xc0\xda\xed\x27\x58\x9a\x61\x5f\xe6\x52\xa0\x04\xb7\x85\xa2\x0f\xfc\x79\xc6\x9f\x90\x46\x4f\x1f\xd7\x1a\x4f\x9b\xd4\x3c\xe3\x86\x09\x8a\x19\xf4\xce\x6c\x21\x73\x5e\xc3\x2d\x8c\x2a\x68\x5c\xc4\x11\x56\x30\xe0\x17\xc8\x61\x46\xeb\x06\x24\x01\x6e\x92\x0e\xdd\x88\x7e\x5d\xd7\xb4\x5a\x9f\x7d\x70\x21\x14\xa6\x95\x97\x22\x3f\xf2\x06\x2a\x7e\x74\x16\x97\x83\x57\x40\x00\x45\xf1\x00\x7e\x3c\x5a\xcb\x82\x35\x68\xff\xb2\xab\xd8\xb8\x19\x74\x32\xd9\x68\x34\x70\xb9\xc6\x28\x73\x95\x09\x54\x70\xc5\xf4\xb6\x57\xc6\xe0\xca\x86\x38\x16\x78\xd3\xcf\x64\xfb\xec\x37\xcd\xb5\x66\x69\xb7\xd5\x62\x80\x39\xb8\x56\x41\x88\xd9\xae\xd1\x4e\x0d\x5e\xff\xeb\x0f\xf7\x77\x1e\x19\x75\xeb\x8f\xba\x81\x93\x93\x60\xed\xc2\x5f\x41\x34\x20\xbd\xf1\xad\x6c\xc0\xbb\xc9\x6d\xdf\x5d\xde\x2e\x68\xcc\x8c\x4f\xc8\x81\x17\x05\x1c\x37\xa8\xb3\xf4\x19\x45\xd3\x24\xd6\x99\xbb\x28\xca\x8c\x38\x43\xfd\xce\xcf\xbd\x39\x2b\x68\x66\x6e\x2c\xce\x77\x4b\xc0\x18\x2f\x5e\x43\xe9\xd2\xee\x3f\x83\x37\x55\x50\x1e\x23\x5c\x6e\x96\x57\xaa\x2a\xcf\x0b\x5f\x0e\x72\x5f\x15\x86\x14\x3d\x5d\x3d\x34\x62\x40\x76\x19\x3c\x26\x11\x2a\x63\x5d\xfe\x0d\x9a\xc5\x21\x3f\xd7\xab\x62\x24\x9d\xa6\x45\x44\x33\x84\x1b\x99\x2e\xd0\xbc\xec\xee\x63\xac\x18\xf6\x6d\x14\x1c\x5d\xb8\x34\x2d\xc3\xab\x45\xac\x35\xea\x07\x3d\x3c\x6e\x9f\xdd\xc7\x53\x61\x7e\x08\x20\x80\x7f\x0b\xfc\x34\xf4\x11\xd0\x22\x83\x88\x38\x7f\x9f\xbc\xb9\x1c\x79\x5e\xc1\xce\xee\xef\x94\xb8\x51\x22\x8c\x62\xcb\x41\x74\x24\xfc\x31\x34\x78\x78\x31\x92\x48\x4c\x25\x50\x9a\xe2\xaa\x3a\x35\xd1\xe3\x10\x32\x93\xf1\xc0\x45\xcf\x6a\xd8\xe4\x50\x21\x8d\x70\x51\x16\x6f\xc6\x31\xee\x4b\x55\x55\x2d\x24\x68\x5c\xff\xe6\x7d\x7d\xe8\xff\x11\xf3\x4d\x0b\x95\xa6\x8c\xf7\x48\x22\x1b\x99\x43\xd1\x60\x37\xdb\x8e\x00\x92\x20\xfe\xea\x61\xf5\xb8\x7b\x7e\x59\x2f\xee\xda\x97\xf0\x69\x7b\xb7\x5c\x6f\x66\xf7\xcb\x8d\x1f\xc6\x4d\x5d\x73\x0f\xcd\x82\x17\x6f\xbc\xee\x03\x63\x6d\xdd\x47\xe8\x80\x21\xdb\x62\xe7\x62\xfa\x9b\xfc\x2d\x1f\xed\x1e\x32\xc8\xb4\x91\xac\xf1\x00\x7b\xe3\x8d\x6a\xbf\x49\x86\x41\x86\xb5\x43\x6c\x59\x0b\x2e\x5f\xb7\x87\x4b\x55\x2b\x3e\xc0\x6d\xc8\x90\x01\x41\xc0\xf1\x19\x0b\xfa\xf5\x21\x3f\x7b\x1a\xe7\x6f\xd9\xb4\x5a\x86\x42\xe0\x0e\x09\x85\xb2\x46\x27\xfe\xc4\x3a\xca\xc0\x81\x10\x73\x9c\x23\x1e\x9b\x31\xec\x8b\xd8\x0f\x44\x51\xd2\xe3\xae\x9b\x7a\xce\x0d\xe8\xaa\x34\xc4\xa9\xb1\xe0\x36\x73\x1f\x53\x09\xe2\xc3\x73\x23\xa3\x86\x10\x83\xd1\x99\xe3\x50\x8b\xd8\x53\xe7\xcd\x7c\xc5\x30\x70\x5b\x4e\x8a\x95\x6a\x19\x47\x21\x22\x82\x76\xae\x9c\x3d\x0a\x47\x65\x1c\x03\x76\x6c\x3d\x34\x3e\x2f\x8b\xe9\x96\xad\xfb\x40\xc2\x50\x26\x69\xf5\xf4\x67\x7f\xf9\x1d\x7f\x2f\xd7\xce\x5c\xeb\x27\x56\x45\x7b\xd9\x80\x8c\x35\x41\xe1\x75\x73\x83\xda\x90\xb2\xaa\xaf\xaa\x2c\xfd\x57\x48\x26\x94\x6a\xe2\xd2\x3a\xb4\xeb\xb6\x07\xd2\x20\x43\x74\xed\x4e\x5c\xae\xb5\x9d\x7b\x7b\x9e\x4c\x21\x41\xbd\xa3\x0d\x34\x2f\x9f\xab\xf0\x0d\x7f\x04\x63\xda\x70\x72\xf2\x13\xb4\xbb\xf7\x18\x0d\xe4\x86\x89\x04\x63\x63\x9c\xb4\x5c\xa9\x4b\xfd\x19\x42\x4e\x32\xad\x70\x2e\x99\xb6\xc1\xee\xc1\x58\x51\xa9\x1e\x39\x73\xf4\x78\x32\x42\x51\xa6\xe1\x4a\x4b\xb1\x3d\xc4\xf1\x2e\x62\xc1\xc9\xc8\x3b\x0d\x17\xae\x2f\x74\x00\xb5\xcc\x92\x84\xda\x36\x9b\x75\xab\x18\x9d\x9e\x47\x21\x6a\x5a\xdc\xde\xdd\x5a\x73\xb3\x91\xd6\x8c\x1b\x27\x09\x6e\xc9\x2f\x9b\x9b\x79\x8f\x0b\x24\x39\x44\xa6\xb3\x6b\x22\x81\x9e\x95\xc2\x27\x22\x27\xee\x73\x3a\x49\x12\xef\xd2\x3c\x4e\xb4\xa4\x20\x41\x64\xba\x87\xb2\x2c\x30\x62\xee\x6d\x94\x52\x04\x26\xc3\x7e\x28\xab\x6a\x98\xe1\x48\x29\x4c\x91\xde\x6f\x6c\xe7\xb3\x29\xa1\xe2\x2c\x61\xa3\x47\xaf\x42\x89\x8f\xfe\xc4\x7f\xcd\xa1\xe9\x43\x58\xa5\x52\x66\x2e\x1a\xd9\x1b\x9d\x57\x23\xa2\x86\xd4\x21\x47\x2d\x3f\xf4\x5e\xbb\x2d\xcb\x39\xf7\x4b\x99\x8e\x22\xd7\x87\xc5\x2f\x9f\xac\x18\x49\x1d\x87\x48\x99\xef\x19\x77\x4f\x4f\x27\x9d\x44\x28\xf3\x64\xa2\x9c\x25\xaf\x4c\x6d\x66\x72\xe5\x97\x5a\x44\x41\xd0\x53\x19\x76\x05\x9a\xf6\x5b\x26\x8b\xa8\xfd\xd7\x47\xcb\x08\xcb\xe1\xb3\x73\xde\xb7\xa1\xd3\x8a\x90\x08\x4b\x11\xc6\xb7\xa3\x43\x39\x58\xbb\xc5\x71\xdb\x4d\xd1\x30\x46\x28\x94\xe7\xc1\x3f\xf0\xe2\x63\x62\x37\xeb\xff\xeb\x82\x36\x45\x93\x4c\x75\x6a\x15\x28\x53\x3b\xe2\x00\xfe\x6f\xff\x75\x5f\x60\x5d\x16\x6a\xec\x0b\xbc\x8e\xa1\xf0\x5d\x48\xac\x82\xd0\x14\x15\x76\x27\xfe\x2b\x3f\x5d\x4e\xf3\x8b\x83\xe9\xa8\x20\x34\x7e\x5b\x0a\x35\x2a\xf8\x7e\x82\x53\xfe\x3b\x6c\xbc\x0a\x12\xa5\xa8\xab\xd6\x21\x5d\xe8\x8f\xd1\x00\xad\xb1\x3d\xe4\x82\x16\x1f\x3b\x8d\xef\xbc\x1d\x1f\x12\x65\x56\xd0\xbc\x68\xe6\x97\xe3\x17\x15\x31\x15\x66\x81\x33\xf9\x1b\x58\xab\x0e\x5f\x11\x15\x05\x09\x72\x8a\x6a\xae\x61\x14\x7b\xa9\x58\x88\xd0\xe8\xcd\x97\xe7\xb2\xd7\x7e\x18\x2d\xf2\x57\x06\xb2\x5a\xc5\x4a\xe1\x36\x3e\x7b\x7e\x5e\x3f\xfd\x58\xee\x9e\x7e\x3e\x3a\xdd\x2b\xad\x12\x6d\x9c\xdf\x35\xc0\xb0\xfa\xa6\xd2\x98\x22\xac\x15\x99\x46\xbb\xd5\xe2\xc9\xe1\x53\x14\x8b\x12\x92\xf5\x7e\xcd\xf6\x50\xc1\xe8\x85\x53\x2c\x21\x14\x06\x36\xbb\x6f\xb1\xff\xbc\x32\xe8\x1b\xb3\x59\xe5\xb2\x9c\x73\xf9\xda\x73\xfc\xf0\xc3\x62\x43\x62\x6d\xf8\x2b\x7c\xbb\xff\xf3\xb6\xac\xfa\x6c\x33\x7f\x36\x80\xc4\xd8\x1e\x9f\xce\x97\x06\x1e\xf9\x09\xad\x21\x97\xbf\x9a\x9e\x4a\x9b\x56\x9c\x19\x41\x8b\xdc\xee\xea\x86\xa6\x6a\x92\x2e\x7f\x2e\x2e\x13\x4d\x07\xcc\x2c\xab\x23\xdf\x95\xe9\xdc\x48\x6d\x18\xe4\xa6\x8a\x50\x01\xf4\x3b\xd4\x4a\xc4\xc4\xc0\x48\x3c\xd0\xf4\x08\x5f\xb1\xe3\x94\x88\x01\x97\xfc\x6f\x37\x8b\x99\x94\x84\xfa\x13\x25\xc6\xb3\xb3\xb1\xd0\xaf\xe1\x3e\xa9\x84\x32\xb2\x79\xcb\xf5\x22\x0d\xe8\xcd\xa5\xdd\xb6\x2e\x72\x6a\x47\xb0\x1f\x90\xb1\xc0\xd7\xfd\x7e\xf6\x38\x73\x27\x91\x2c\xb0\x02\xd2\x2f\x85\x82\xaa\x47\x65\xa4\x76\x84\x8a\x62\x04\x8e\x9a\x45\xa2\x9d\x99\xa6\xf9\x59\x7f\x66\x1b\xeb\xe7\x9e\x8a\x23\x44\xde\x61\x11\x7b\xba\x7e\xad\x54\x92\x39\x62\x47\x27\x91\x6b\x20\x3c\x79\xb1\xef\x29\xcc\x8e\x3e\x26\x89\x33\x6b\x9e\xe7\xaa\xdd\x10\x31\x59\xb2\x6d\xd3\xe1\x54\x02\x2a\x31\x44\xe7\x4a\x21\x35\x63\xfa\xe6\x40\x10\x75\x98\x4d\x8b\x1e\xbd\xc2\xa1\xb8\xb1\xdc\xa8\xbc\x14\xf0\xfe\xa3\xc4\xe2\x65\x2f\xf0\x54\x3a\xc9\xa8\x2f\x2c\x1a\x53\xeb\x42\xdd\xb4\x6f\xf3\xf0\x2c\x5a\x00\x15\x3d\x4d\xdc\x4f\x96\x5e\x33\x1a\x48\xa0\x51\x0b\x56\xe7\x15\xdc\xe6\xfb\x83\x95\xcb\xab\x91\x6a\x6d\x56\x33\xe6\xbb\x4d\x40\x62\x6a\x7e\x73\xfd\x51\xc8\x81\xa1\xce\xe8\xac\x19\xc1\x47\xf4\x08\xef\x86\x82\x35\x3a\x2c\x43\xe4\xca\xff\xed\x69\xf1\x7d\xf9\xd7\xa0\x73\x08\x44\x6b\x7c\xa7\x36\x4d\x59\xf1\x3d\xd6\x4d\xa6\xbf\x83\x52\xa3\x51\xee\xf3\x91\x76\x8b\x1a\x8b\x08\xb8\x49\x03\x94\x72\x25\x1d\xaa\x72\xe3\x1f\x3d\x73\x87\x99\x51\x8a\xdd\x61\x82\x89\xc7\x8d\xc2\xa6\x3b\xce\x99\x93\x75\x31\x0e\x25\x0b\x7e\x3a\xf3\x7c\x3f\x5a\xbf\x81\x2a\x99\x42\x4f\x50\xb2\xbf\x5c\x00\xd5\x80\x85\xf7\xbc\xc8\x1d\x37\x16\xdc\x5b\x09\x41\xa8\x11\xc1\xf1\x9e\x1b\xfa\x8c\xfb\x73\x1a\x23\xf8\x56\x5e\x8e\xe8\x02\x94\xbf\xc1\x4e\xc1\xe9\x52\xb5\x37\x67\x27\x47\x88\x5b\x08\x03\x82\x1d\xcb\xd3\xdb\xd9\x82\x9f\xdd\x01\xa6\x31\x6d\x41\x8a\xe4\xbb\x87\x36\x42\xa8\xa4\xf3\x43\xff\xc6\x6b\xe4\x30\xdb\x23\x71\x4c\x8d\xa4\x73\xfb\x9a\xa1\x89\x40\x2e\x47\xb4\x3e\x88\x99\x35\xbc\x32\x3a\x95\xf3\x8f\x1b\x83\xbe\x6b\x63\xd5\xbc\x19\xd8\x52\x4c\x93\x35\xfa\xb7\x27\x21\x09\x4a\x85\xd9\xa2\x59\x53\x1b\xa5\x85\x01\x82\xe5\xff\x4e\xe0\x59\x20\x89\x09\x82\xf8\xb4\x6d\xdc\xad\x16\x4f\xfd\xb6\x3b\x5a\xe5\xf6\xc4\xc3\x7a\xe2\x63\x1a\x58\x64\x6c\x22\xf2\x7a\x73\x11\xff\x04\x89\x55\xd4\xea\x32\x11\xe4\x03\x4b\x22\xd4\xd1\x7d\x98\xfd\x69\x00\xe8\xbb\xc5\xec\xd9\x9f\x87\x31\x66\xd4\x4c\xcb\x0a\xfa\x20\x15\x77\x5c\x72\x1b\x2f\x17\x6a\x55\x9c\x2f\xcd\x50\x83\xd0\x8e\xca\x52\x21\x6d\x3e\xb6\xf9\x57\xf5\xd7\xe8\x02\x32\xc6\xa1\xbb\x41\xcb\xe6\xb0\x5a\x3c\x79\x1f\x86\xcf\xfd\x16\x47\x27\x51\x46\x7b\xdb\xec\x3d\x02\xf6\x98\xf7\x9d\xab\xb2\x81\xa9\x1f\xcd\x49\x82\x1d\x9d\xab\x7e\x59\x1b\x10\x2f\xec\xfe\x35\x95\xaa\x03\x27\x0a\xcb\x97\x02\x74\x59\x81\x77\x05\xd0\x20\x22\xe3\x33\xb5\x38\x40\xa1\xc0\xff\x55\xa5\x01\xed\x34\x07\x4c\xca\xee\x95\x1f\xdd\x28\x49\x05\xaa\xd2\xfd\x9c\xfb\x05\x43\xc6\x0a\x71\x2e\xcb\x76\xf5\x7a\xf5\x7f\x65\x2a\x34\xdc\xa1\x7c\xbf\xef\xa6\x82\x54\x71\x68\xe0\x64\x3f\x79\xde\xf4\x4e\xac\x78\x9c\x71\x2f\x87\x34\x6b\x9c\x79\xf0\xa8\x62\xd4\x9f\xaf\x10\x01\x96\xde\xbf\xcd\x90\x89\xb0\xbb\x59\x3e\x6f\xef\xdc\xf9\x40\x66\x08\xab\xab\xf9\xa9\xfe\x8a\x8f\x0e\xa0\x62\x2c\xbd\xa1\x30\xf4\x0e\x7e\x9d\xcb\x02\x8a\xc6\x2f\x0b\x9a\x84\x09\x78\xd5\xab\x36\x52\xf1\x38\x70\x40\x76\xb5\x5d\xe9\xad\x77\xee\xbc\xfc\x35\x7a\x80\x3a\x30\x37\xc2\x76\x33\xdb\x2c\xd4\xef\x69\x23\xb2\x5b\x12\xd9\x7f\xdc\x47\x15\x60\x7d\xf7\x67\x7e\x3c\xae\x9d\x5e\x96\x39\xa6\x49\x40\x31\xde\x32\xa7\x5d\x54\x1f\x63\x27\x2a\xad\x49\x18\x25\xa2\x23\x3b\xf4\xf7\x76\xb7\x2c\xeb\x20\x4d\x84\xea\x89\x7a\xb5\xf1\xc8\x98\x46\xa0\x03\x2e\x85\xa5\x3c\x61\xd4\x17\xf8\x03\x32\xc5\x3c\x2d\x3f\x97\xbb\x73\x2f\xf9\xd3\x81\xd4\x0e\x38\x24\x4d\xf9\x1f\x94\xe2\x0d\x97\xbd\xe2\xb3\x0e\xa9\x0a\x5c\xeb\x04\x4f\xcb\x06\x39\xac\x0e\xc3\xc4\x1a\x4f\xf2\xd3\x30\x46\xd2\x51\x14\x63\x8b\xee\x9b\x8f\xe9\x36\xfc\x08\x03\x76\x8b\x1f\xc9\x33\xea\x49\x16\xdf\xe1\xc3\x3b\xd0\x6a\x1d\x89\x04\x73\x6f\x5b\x52\x18\xdf\x9b\x04\x38\x36\x08\x7e\x96\xc7\x57\xe7\x59\x3e\xb9\x15\xea\x44\x33\x84\xae\xed\xba\xa2\xfd\x96\xff\x9a\x4e\x08\x74\x4a\x0c\xda\x09\xb9\xaa\xd6\xbb\xed\x0f\x7f\xcc\x68\x96\xda\xc4\xd7\x08\x9f\x5e\x97\x7a\x75\x1a\x64\x48\x4f\xd2\xf9\xf1\xf8\x72\xb6\x3c\xb4\xe9\x84\x56\xb3\x84\x18\xd1\xdf\x76\xea\x99\xdf\x81\x1d\xd5\x0d\xff\xad\x3c\xf8\x28\xe5\xd1\x2c\xe1\x08\x1f\xbc\xe3\xe7\xf3\x07\xf6\x3f\xfb\x48\xdb\xe1\xd7\x66\x34\x30\xd6\xec\x6d\xa4\xdf\x4b\xa3\x3e\xdb\x8f\x86\x3f\x30\x0b\x54\x62\x01\x5f\x3b\x7b\x64\xb7\x9b\x55\x79\xc1\xa7\xeb\x6d\x3a\x0b\x29\x4e\xe4\xa3\x21\x93\xb4\x6b\xd6\x00\x05\xae\x33\x66\x1a\x0e\x35\x34\xdf\x1b\x39\xd9\xa0\xd3\x99\x88\x51\xbc\x0f\xd3\xc9\x7e\x35\x43\x73\x0e\x58\x5b\xb7\xcd\xf1\x65\x27\x50\x36\xba\x0e\xc1\xe2\x34\xf5\x0a\x75\xdc\x6b\xd7\x69\x2d\x49\x4a\x2d\xdd\xe7\x3e\xd7\x46\x2a\x64\x78\xcb\x24\x23\x08\xdc\xfb\xd7\x05\xaa\x0f\x43\xd2\xde\x56\x1f\xed\xca\xbf\xf3\x27\x11\x24\xb3\x78\x6a\x2c\x08\x8e\x53\x46\xff\xa8\x24\xc4\xac\x1f\x08\xdd\x96\x95\xc9\x81\x3f\x2b\xba\x69\xa5\xe3\xd0\x08\xe7\xb8\x3a\x7b\x8f\x8f\xad\x81\x09\xb0\x01\xd8\xf7\x8f\x4f\x6e\x9f\xce\x0c\x64\xdd\x50\x23\x91\xdf\xd9\x5e\xe4\xa2\x2f\x53\x34\xfa\x52\x2d\x52\x7c\x6c\x77\x70\x3c\x96\x3f\xcb\xca\xfa\x19\x31\x42\x48\x0a\xcc\xd4\x79\x51\xa1\x38\x87\xee\x08\x4b\x31\x64\x46\x71\x1b\xba\xe5\xd5\xde\xda\x16\xb6\xc7\x32\xf3\x4a\x63\xd5\xa9\x1a\x24\xb0\x8c\x10\x1a\xc7\xf8\x9e\x62\x74\xb2\x86\x53\x1f\xd8\xeb\x86\xa4\xd2\xf4\x3d\x91\x85\x88\x2e\xc0\xd7\xf5\x37\x46\x48\x18\x46\xd8\x6c\x5f\xcc\x1e\x7d\x5b\xb5\xfd\x73\x1c\x44\x56\xe2\x56\xde\x94\x77\xd3\xcc\xa0\x76\x5c\x12\x20\xbf\xea\x58\xbe\x41\x1b\x69\xe7\x96\x81\xee\xce\x13\x47\x12\xd9\x14\xb7\x15\x40\x3b\x0d\xfc\x22\xd1\x1e\x4b\x04\xa6\x29\x26\x82\xc0\xce\x53\x9b\xd8\xe4\x47\xe8\xc9\x9c\xb9\x1a\x4c\x3b\x3e\x15\x19\x77\xfb\xc0\xb1\x1c\x54\x30\xdb\xc3\x59\x8c\x53\xaa\xc0\xd7\xc5\x07\xf0\xfe\x68\xe6\x4c\x29\x9e\xab\x52\xe7\x47\x13\x5c\x4d\x4c\x7e\x46\x48\x12\x24\x88\x6a\x9c\xad\xd6\x3b\xba\xdb\xbc\x3c\x3f\xdf\xff\xe5\x4e\x94\x24\x19\x96\xfb\xea\x36\xb6\x0f\x6f\x2c\xd0\xdf\x1f\x4d\x23\x27\x61\x60\xbd\x91\x47\x67\xe6\x31\xe2\xf5\x95\xf5\x66\xb4\x13\x10\xfc\x75\x26\x9a\xa1\xc4\xca\xe2\x69\x3e\xb3\xf2\x80\x8c\x90\x34\x21\x18\x03\x61\x42\x41\xc7\x5f\x9a\x32\x8e\xb8\x8a\xdb\xb2\xba\x2d\x4b\x3f\xbf\x52\x2e\x85\x15\x08\x43\x57\x44\x40\xfd\x86\x36\xc6\x83\xca\x42\x4e\xec\x48\x96\x9a\x26\x3a\x0a\x83\x5b\x47\xb0\xce\x09\xac\x1d\xa0\x62\x9c\x4d\x79\xd1\x9f\x24\x59\xc4\x22\xfb\x63\x1f\xb0\x70\xda\x53\xf2\x62\x6e\x4c\x1a\xb1\xbe\x3c\xec\x1f\xd7\x88\x33\x1c\xc5\xf1\x2d\xe7\xea\x9f\x17\xb4\x3f\x2c\x9b\x7e\x2f\x9e\x11\xc2\x43\x43\x69\xc1\x19\xf4\x8d\x9f\x3e\x25\xc0\xba\xf1\xc2\xe8\x8d\x18\xe9\xfc\x07\xa8\x5e\x8f\x46\x4c\x7f\xea\x05\x66\x84\x08\xe1\x35\x64\x71\x02\x7f\x5e\x11\x61\x84\xc8\x98\x60\xdd\x79\x9f\xbf\x01\x9a\x5a\xfa\x48\x76\x5b\x7e\xff\xe8\x19\x0b\x9a\x65\xac\xfd\x44\x0a\x4e\x51\xcf\xf9\xfa\xf1\x3d\x0c\x5e\x15\x45\x34\x82\xbc\x1d\x3e\x75\x22\xb0\x62\xc3\x77\x57\x45\x14\x55\xad\x0a\x78\x5f\xfe\xca\x9b\x61\x1f\xc7\x8d\x69\x23\xd2\xff\xf3\xff\xfd\x9f\x8f\xf2\xa3\xdc\xf6\xb5\x61\x27\xe3\x48\x46\x08\xa8\x18\xe7\xc2\xc3\xcf\xcd\xe0\x6d\x05\x25\xb2\xce\x99\x67\xc1\xcf\xa3\xd7\x4f\x33\xc0\x7c\x1b\xc5\xb3\xe6\xd0\xfc\xcc\x9b\xc3\xaa\x78\xcb\x9b\xe9\x8a\x22\x23\x94\xc4\x01\x36\x8d\x4e\xfc\xd7\x4b\x0d\x55\x57\xa4\x62\x84\xd2\x30\x85\xd4\xc1\x51\x10\xe5\x64\x6b\x2d\xf5\xf0\x6b\x29\x0d\x19\x16\x98\x9f\xd6\x37\xcb\xf5\xee\xe1\xe9\x66\x75\xfb\xd7\x97\xbc\xaf\xab\x47\x4f\x69\x14\xe3\xda\x5d\xe7\xfb\x5d\x53\xb6\xdb\xb4\xad\x30\xf9\x01\x09\x15\xc4\x15\x81\x86\x02\xa8\xed\xd1\x94\x18\xd3\xa3\xf5\x6c\xb1\x9b\x3f\x6d\xdd\x4f\x08\x32\x83\xda\xb3\x52\x92\x56\xd5\xf3\xc8\xf7\x23\x48\x2a\x23\x34\x24\x21\xee\x11\xf7\xdf\x16\x6e\x9d\xa1\x61\x98\x60\x56\xb0\xd9\xce\xd6\xdb\xd5\xe3\xb7\xdd\x3a\x97\xaf\xb3\x42\x3d\x94\x55\xf3\xe1\x07\xe9\x00\x55\x4a\xdb\x65\xfa\xa5\x78\xe0\xf5\x2b\xa8\x6f\x97\x25\xaf\xda\xb8\x61\x7c\xab\x42\x1d\x72\xd3\x82\x7f\x0b\xdc\x09\x22\x1d\xe0\xbc\x44\xa1\x63\x6e\xe5\x44\xd9\xa7\x14\x3e\x46\x68\x4c\x03\xd4\x83\xdb\xbc\xe5\x05\x92\x41\xfb\xb3\x84\xc6\x3c\x43\x7e\xc3\x6d\x59\xed\x38\x62\x09\xdc\x01\x48\xb4\x8d\xa4\x6f\x2e\xc5\x1e\xca\xc2\x3c\xef\xe1\x25\x26\xc2\xc8\xfb\xec\xa1\xf9\x0e\x1f\x03\x85\xd6\xe1\x55\xa4\x21\xb7\xfd\xac\x02\xac\xb6\x9f\xfb\xa6\x34\x0d\x51\xf4\xe8\xfe\xc6\x3f\x0a\x4e\x0d\x15\xd7\x2d\x42\xcd\xa2\x3c\xe7\x60\xd8\x87\x65\x5e\x0d\xaa\x11\x38\x3c\xc2\xbb\x5a\xbf\xf3\xf3\xc8\x6f\xa4\x3d\x2a\x38\x76\x44\xb1\x02\xf2\x5c\x95\x12\x40\xb9\xe5\x9b\x8a\x88\x1a\x37\xd0\x23\xcf\x4f\xc6\x47\xd9\x1d\x92\x61\x68\x31\x77\x18\xa6\xaf\x6c\x5f\x66\x9e\xab\xd1\xd7\x2b\x91\x21\xff\xf2\x61\xd5\x55\x06\x18\xa1\x10\x98\xfd\xed\xe4\xeb\x90\xd7\xed\x68\x46\xa8\x8e\x13\x5c\x4a\x37\xe7\x36\x2b\xae\xac\x8c\xdd\xbf\x87\xad\xb8\x6e\x57\x0d\x08\x01\x6a\x70\x64\xa2\xdd\xa4\x71\xd1\xad\x10\x2b\xb0\x2a\xde\xca\x5c\x7e\x02\x66\xf1\xcf\x2c\x20\x01\xc3\x7e\xbe\x29\xc0\xde\x00\xd6\x26\xf3\x37\x43\x9f\xf8\xbf\x03\xbc\xcf\xb0\x68\x43\x3f\x79\x21\x03\x12\x65\xce\x97\xcc\x2a\x3b\x1b\x87\x68\x0c\x90\x06\xbf\x36\x20\x3a\x36\x37\x55\x29\x4c\x06\xb6\xe5\x23\x34\xef\x65\xf5\x7a\x35\x4e\xa4\xa9\x5f\x7f\x9f\xf9\xc7\x16\x09\x29\xfe\xa8\x11\x8e\xcb\xeb\x1b\xe8\xdc\xb4\x47\xa7\xa0\xd4\x48\x69\x58\x41\xb6\x41\xad\xb6\x3f\x37\x03\xca\x00\xc5\xc1\x30\xfa\xae\x51\x67\x46\x6d\xf3\xe3\xf1\xd1\x56\xcb\x18\x09\x82\x2c\x94\x41\xdf\x56\x04\xe1\x62\xe3\x72\x4f\x3b\x50\x9b\x3a\x85\x77\x70\xc7\x9e\x6b\xef\xf1\x85\x69\x92\xd9\x7d\xeb\x79\xd1\xcf\x2e\xdb\x63\x5a\x0b\xfb\x36\x3d\xbd\x41\xc5\x8f\xc7\x4d\xfe\x6f\xff\xa3\xa3\x2c\x4a\x58\x27\x50\x77\xb7\x59\x80\x33\x75\xbc\x81\x86\xe7\xc7\x3e\x09\xa9\x1d\x2f\x23\xf4\x25\x3b\xe6\x27\x5c\x8d\x6f\x86\x90\x55\x46\x82\x18\x42\xac\xd6\xfe\x58\xae\x37\xab\xa7\xc7\xdd\xe3\xcb\xc3\xdc\x76\x73\x18\x09\x12\xc2\xb8\x57\x9b\x38\xe7\x95\xf9\xa6\x11\xcd\xb3\x1d\x17\x45\xa8\xab\x60\xab\x6c\xcb\x42\xbd\x14\xf9\xaf\xa1\xfa\x4b\x3b\x0c\x34\xe7\xee\x2e\x53\xf6\xbd\x6e\xe0\xdc\xbd\x2d\x41\xa2\x01\x75\x4b\x6e\x2f\x85\xfa\x9d\x56\x46\xff\x75\x48\x89\x51\x59\x5e\x6c\x16\x6b\xa8\xcb\x4b\x25\xc7\x62\x49\xc3\xdf\x9c\x2a\x40\x9c\xbd\xa9\x5f\x60\x84\xf5\x59\xaf\x8d\x91\x80\x09\x85\xd8\xe5\xca\xca\x5b\x2d\x7e\x2e\xa6\x43\x8c\x80\x49\xc0\xa2\x87\x5d\x48\xb0\x13\xd4\x5b\x8b\xfc\x19\xb3\x44\x21\xe2\x03\x17\xdb\x1d\xd6\xf4\x47\xf7\x93\x87\x46\xfd\x84\x2b\xe5\xc8\x46\x1b\xa8\xde\x72\x39\xbe\xf1\x82\x1a\xd9\x9e\x52\xa3\xf0\xad\x8f\x4c\x02\x11\x19\xb1\xd2\xd5\xa6\x6b\xf9\xb7\x7f\x66\x51\x6c\x25\xc7\x9e\xa1\x7a\x83\x62\x08\x30\x75\xa3\x04\x17\x56\x5f\x2e\x2f\x36\x0d\xaf\xe6\x7d\x41\x9b\x09\x41\x79\xfb\x39\xc9\xa4\x32\x9e\xd2\x98\xc1\x2c\x6b\x59\x75\x58\xe0\xd1\xcd\x92\x8a\xc6\xda\x6f\xb5\x1e\xa7\x32\x5e\xba\x03\x45\x59\x64\xdd\x10\xb1\x78\x3b\x84\xc8\x7c\xb2\x1a\x29\xce\xb1\xa0\x7e\xe4\x4d\x5e\x94\xcd\x7f\x16\x9b\x05\x0a\x98\x13\x5e\x79\xae\xe0\x94\x5f\x4e\xb7\x5c\x62\x6b\xf0\x13\x50\xac\xff\x9c\xc0\xb6\xbd\xd3\x82\xf9\xca\xed\xb7\x37\x6d\x81\x9b\x5e\x9c\xc3\x79\x75\xfd\x82\xf6\xa0\x60\x58\xaa\xdd\xed\xa1\xf9\x09\xf9\xfe\xd0\x8c\x9e\x91\x0e\xb4\x91\xf0\xe1\xca\x3b\x8f\x7f\x15\x3b\xb9\x67\xa4\x63\x81\xd9\xdf\xec\xe6\x66\xb5\x5d\x3d\x3d\xce\xee\x77\xcf\x4f\xeb\xf6\xff\xec\x1c\x09\x29\x15\x48\x44\x15\x97\x8f\x45\x8f\xfc\xfd\x75\x44\x16\xd2\xc0\xc8\xe9\xe6\x85\x3e\x5a\xe2\xcb\xe9\x3c\x7f\xde\xf8\xb3\x32\x01\x7d\x41\xa7\x76\x75\xab\x72\xf5\x25\xa9\xb8\xfd\x18\x30\x03\x44\x72\xc8\x3c\xfb\x64\x7e\x77\x55\x5f\x84\x43\x61\x10\x48\x61\xb8\x32\x8f\xe5\xbb\xc7\x8c\xbb\x83\xb1\xc0\x50\x04\x0b\x21\x8f\xe3\x59\x33\xe0\x1a\xb9\x4f\xa4\x31\x36\xdd\xae\x20\x5f\x7f\x8c\xc6\xb1\x14\x1b\x8c\x3b\x8d\xbb\x42\x0f\x67\xcf\x48\x18\x92\x8c\x05\xb6\x47\x80\x74\xec\xe9\x34\x37\x0c\x23\x81\x0a\xd2\xdb\xf2\x34\xcf\xaf\xf4\x1b\xae\x27\x75\x18\x4a\x83\xaa\x5a\x3f\x6d\x16\xb3\x37\xda\xa7\x81\xd2\x80\x8d\x4b\x60\x03\x22\x29\x7e\x5a\x22\xd6\x74\xd3\x00\x3f\x36\x87\x7e\xdc\x18\x86\x1a\x10\x38\x5d\x19\x07\x4a\x47\x05\x61\x24\x8c\x68\x8a\x25\x52\x34\xe2\x93\x4d\xdd\x65\xcc\xc3\x3b\x12\x85\xb1\x11\x33\x69\x78\xd5\xdc\x80\xce\x0b\x50\x6d\x9e\xf8\xc0\x8b\x0b\x3f\x1e\x47\x7b\x55\x18\xc7\x69\x66\x0a\xf8\x33\xa3\xcb\xf0\x52\x0f\x69\x7b\xed\x18\x96\xe2\xf4\xce\x0b\xe7\x2f\xd4\x61\xc0\x47\x31\x63\x98\x08\x23\xde\x67\xde\xf7\x3a\x57\x50\xb4\xc1\xd0\x03\xd4\xfc\x53\x93\x83\xd1\x19\x54\xea\x04\xb9\xd6\xbc\xb1\xb6\xfd\xf3\xbe\x45\x8a\x1d\x98\x86\x51\xe8\x20\x53\x08\x8b\xe2\xd5\x87\xfd\xa5\xfc\x2a\xb7\x08\x53\x26\x9c\x03\xec\xe6\x50\x9e\xad\x93\xf7\x44\x24\x18\xa6\xc2\x48\xbf\x5e\x2c\x4d\x1a\xd4\xc3\xf6\xc5\x3d\x86\x2c\x89\x71\xe7\xe2\x18\x73\x22\x75\xdb\x1d\xe2\x49\x80\xc2\x9b\x8e\xf2\xfe\x19\x87\xdb\x0e\x17\x91\xc4\xfe\x33\x16\xaf\xcc\xaf\x1c\x5d\xb2\x4c\x22\xec\x31\x7e\x03\xcc\x49\xc6\x75\x63\x1c\xa1\xb9\xad\x2f\xff\x04\xe3\x93\x5a\x3f\xbd\x8f\x43\xb6\x50\x32\x93\x57\x99\x74\xe2\x0b\xd2\x5b\x3b\x56\x12\x24\x66\xbc\xd6\xf2\xd3\x78\x61\xf0\x32\xa8\x24\x46\xab\x85\x5d\xfb\x9a\x35\xbf\x73\x80\x62\x24\x04\x1e\xa0\x32\xcd\x43\x59\xc0\x87\xfb\x8e\xe9\x5a\x3c\x23\xa1\x16\x80\x95\xa4\xb3\x59\x8f\xd7\xb0\xbf\x1c\x2d\xd7\xee\x6a\xc7\x72\x1f\x91\x0a\x5f\xcf\x41\x14\x70\x55\xa8\x9e\xfc\xba\x88\x04\x31\x0a\x63\xb5\x47\xf1\x86\x8f\x0e\x4b\x8e\x8f\xbf\x81\x1a\x63\x49\x7d\xf4\xc1\x6c\x44\x03\x62\x05\x36\xac\x44\x79\x57\xf2\xaf\xaf\x4d\x30\xda\x0f\x68\x89\x27\x9b\xfd\x78\xe8\x2f\x02\x51\x20\x02\x6a\x48\x77\x56\x5f\xe1\x59\x36\x7f\x52\xf2\xdd\x1f\xd7\x82\x5b\xdf\xc4\x51\x38\xf0\x65\x73\x38\x0c\x7a\xb3\x3c\x0a\x69\x8c\xf2\xc7\xe7\xb2\x27\xac\x39\x21\x05\xd3\x0e\x0d\x52\x54\x2c\x14\x97\x0f\xe3\x7c\x7f\xed\xb0\xd2\x8e\x92\x99\xe1\xee\xb5\x11\x10\xda\xa8\xfb\x03\x3a\x50\x0e\x83\xe5\xfe\x18\xc9\x24\x85\xbe\x25\xf6\xbf\x7b\xc4\x5c\x1b\xd4\x45\x31\x35\xc6\x99\x45\x2e\xdd\xe7\x52\xc1\x53\xd2\xab\x83\x5b\x8d\x16\x44\xc5\x5c\x15\x63\xa2\x54\x8a\xac\x33\xc0\x41\xe2\xc5\x78\x11\x1a\x3e\x92\x54\x6a\xd4\x5c\xcc\x8b\xaf\x37\x82\xd1\xc7\xb2\x44\x23\x64\x67\xc1\xbd\x50\x2b\x23\x11\xb7\xb0\xd7\xb7\x7c\x3f\xcc\x48\x22\xae\xb5\xf6\xa9\x91\x35\x59\xbb\xea\x76\x31\x12\x89\x38\x56\xb1\xef\xc4\xd7\x30\xab\x47\x53\x48\x70\xe3\x2a\xd6\x54\x1f\xdf\xa0\xe9\x47\x3b\x91\x4c\x98\xb1\x69\x36\xb4\x59\xd8\x2e\xee\xd7\x79\xb1\x05\x7e\x1a\xec\x92\x91\xb4\xd6\x8c\x3b\xab\x23\xb2\xfc\x55\x1a\xf3\xb7\xa9\xdf\xdf\x61\x13\xfb\x7f\xb5\xb7\xf3\x93\x9b\xa3\xe2\x24\x1a\x78\x00\x51\xd2\x6d\x5e\x6e\x8f\xa4\xc4\x3d\x74\x95\x1a\x42\x92\x55\x30\xba\x2f\x79\xb1\x6a\x77\x91\x5c\xe7\x43\x3a\x0b\x23\x11\x50\x8a\x28\x14\x14\x1f\x3f\x54\xe5\x7b\x7d\x93\xd7\xe5\x7b\xf1\x58\x36\xdb\x1e\xac\xeb\x0f\x3f\x5c\x62\xa4\xbe\x73\xb3\xae\xd4\xbd\xc7\xdc\x7b\x39\x80\x91\xc4\x86\xf4\x33\xad\xf3\x63\xde\xde\x17\xb5\x1f\x3f\x1e\x80\x00\x81\xe9\x6d\xb8\x38\x12\x7f\x9a\x5a\x2a\x23\xcd\x8c\xf6\x4d\x7d\x28\xdf\x51\x4e\x39\x57\x9d\x0a\x45\x7b\x1c\x52\x4c\xf8\x8d\x51\x6b\x9f\x25\xff\x9f\x32\xc8\xfa\xe3\xae\x94\x9d\xfa\x31\x6b\x4c\xa8\x49\xbd\xed\x46\xcd\x8f\x80\xf8\xfb\x97\x55\x31\x5a\xf3\x62\x12\x05\x28\x0d\xe9\x12\x51\x0b\xb3\xf3\xdd\x24\x46\x62\x9a\x71\x69\xf7\x6c\xb4\xaa\x9c\x08\xe9\x62\xaa\x48\x60\xb3\xf0\xbe\xa5\xbe\xb5\xdf\x1f\x5c\x5b\x40\x09\x36\xa8\x67\xa7\x95\x91\xf2\x74\x75\xba\x38\xa0\x99\x81\x2c\xe6\xe7\xe1\x9b\x10\x07\x51\x8a\xeb\x59\x6f\xe5\x89\x03\xc6\x90\x39\x62\x2d\xa7\x1d\xc1\x7a\xc8\xd7\x68\xc7\x65\x34\xb5\xf7\xe2\xa5\x56\x46\xfe\x7f\xdc\xcf\x63\x24\x8e\x44\x80\x48\xbe\xc7\xef\x2e\xae\x8f\xe3\x38\xc4\x08\xbc\xe2\x85\x7a\x28\x47\x81\x53\x1c\x67\x61\x9c\xf6\x34\x7d\x3d\x87\xb1\x57\xb9\x68\x07\x99\x88\xa9\x29\x2b\xa7\x61\x81\xea\x4f\x50\x8c\x53\xd3\x38\x56\x21\x36\xbc\xc0\x3e\x83\xcd\x1e\x79\x80\xfb\x2b\x14\xb3\x1f\x2f\x70\x82\x7e\xeb\x04\x48\x3a\xbb\x15\xf7\xeb\x63\x9d\x61\xc4\xf8\x50\x2a\x94\x93\x76\x01\x4d\x9c\x10\x63\x8c\x53\x43\xb3\xaa\x6d\x53\xda\x48\xd6\xf6\x2e\x3f\x49\xb2\xc4\x74\xbe\xb8\xea\xf1\xaa\x26\x63\x9e\x38\x25\x0a\x85\x1d\xff\x56\xd6\x87\x0b\xef\x25\xd1\x71\x4a\x01\x57\xea\x97\x8a\x17\x73\x5e\xbc\xfa\xbf\x27\x46\x83\x72\x5e\x5e\xf6\x87\xe6\x47\xce\xff\x56\x1e\xf8\x24\x72\x92\x61\x63\x0c\xab\xae\xe2\x62\x48\x32\x75\x7b\x73\xe0\xa8\xfd\xc9\x80\x60\x01\xfb\x2b\x10\xe6\x74\x2a\x16\x67\x21\x0b\xb8\x33\xa7\xa8\x57\xc5\xd4\x16\x18\x67\x99\xa1\xc0\xd8\xa6\xdb\x08\x64\xe0\x07\x41\x24\x3a\x09\x95\xfe\x02\x11\x67\xc0\x88\x13\xde\xe7\x47\x24\x4c\xd5\xf9\xde\x36\x34\xec\x18\x2e\x00\xfb\x23\x0a\xea\xa6\x74\x15\xf0\x58\xb0\x08\x79\x49\xe2\x72\x3a\x23\x98\x71\x74\x69\x22\x23\x2a\xf1\x66\x83\xfd\xad\x73\x74\x79\x42\x12\xec\x99\xaf\xcb\xe3\x91\x12\xe2\xce\x2f\x03\xa3\x6e\x2d\xaa\x92\x2b\xc9\xeb\xe6\xe9\x9c\x17\x43\xff\x17\x86\x0e\x44\xae\xd2\xf6\x5c\xc1\x5b\x5e\x5e\xea\x3b\x5e\x1f\x5e\x72\x5f\x44\x89\x65\xa8\xb0\x32\xbc\xc9\x4f\xe7\x23\xdc\x6f\xb6\x53\x74\x9a\xdf\x75\x2c\x46\xd3\x4a\xa6\x61\x28\x70\x0e\x36\x4d\x39\x6c\x98\xc5\x2a\x48\x52\xcc\xa8\x0a\xf5\xa9\xd4\x35\x23\x31\x64\x19\x10\x2b\x57\x51\xd5\x46\xc9\xcd\x9d\x42\x47\x12\x6b\x18\xdb\xb2\x6e\xb7\xcf\xfb\x1e\x27\xc6\x0e\x49\x48\x68\xaa\x70\x79\xbd\xe5\xaf\xe0\xbd\x5f\xaf\xb6\x83\xdf\xfc\x3e\x7b\x36\x1a\x9b\x3a\x84\x75\x80\xbd\xd2\xac\xea\x6d\xf3\x09\x65\xa6\xa1\x80\xf2\xab\xef\xbc\x72\x32\x19\x9f\x13\xd5\xdd\x07\x39\x45\x1a\x23\xce\x05\x2b\x45\xbf\x06\x2e\x0f\xe3\xfc\x2f\xa1\xca\x10\x90\x6f\x57\x8f\xb3\xc7\xc5\x72\xb7\x98\x3d\x23\x40\x6b\xfd\xf4\xf2\x78\xe3\xee\x40\xa0\x42\xd4\xf0\x35\x4a\x65\xb3\x42\xa1\x6a\xec\x4d\x39\xdc\xb1\x93\x90\xfb\x34\xcc\x4c\xeb\xfa\xc6\xb6\x80\x87\xf3\x30\x89\x92\xcc\xa1\x9d\x9c\x5f\x86\x89\x90\xfa\x13\x2e\x89\x53\x6a\xd4\x70\x79\x53\x95\xd6\x66\xa0\xe3\x19\xba\x6b\x8b\x81\x63\x1f\xdb\x7a\x4e\xb8\x8d\xc0\x61\xe8\x18\x49\x12\x1a\x1b\xb2\x62\x79\x3a\xb5\x4b\x79\x6e\x45\x42\x47\x17\x95\x44\x02\x63\x25\xec\xa0\xb6\x73\xe1\x47\xe9\x37\xc1\x24\x49\x63\x84\xdc\x3f\xfc\xf5\x6d\xbd\x9c\x6d\x11\xd2\xd8\x1d\xe3\x18\xc9\x2e\xe6\x8f\xe3\x53\xea\x10\xc3\x1d\x04\x98\x6c\xb6\xb3\xde\xa2\x98\xa4\x3a\x15\xdc\xba\x98\xed\x72\x9a\xb8\xbf\x67\x04\x10\x3d\xbb\xaa\x2d\xa1\xd5\x1f\xa0\x0c\x59\xd4\xdf\x4a\x7e\x74\xcf\xf2\x2a\x17\xf0\x6b\x77\x92\x29\x89\x5b\xf2\xf6\x70\x69\xe3\xe7\xb7\xfa\x6f\xfc\xdf\xff\x76\xe7\xe2\x01\xb7\xc5\x27\xcb\x0f\xdd\x15\x00\x0a\xd4\xee\x52\x34\xf9\x71\xf7\x4f\x2e\x5f\xcf\xa5\x7f\x01\xb8\xa2\x89\xcb\x44\x3b\xfe\x8e\x3f\x18\xa7\xb6\x3b\xf1\xb3\xac\x5e\xc7\xb9\x79\x22\x48\xd8\xdb\xa7\x0d\x20\x78\xaa\x8b\x9b\x88\x30\x43\x38\x6e\x9b\xf4\x14\x86\xc8\xd9\xf9\x0f\xb4\xc7\x13\x23\x04\xdf\xe1\xc8\xb6\x1f\x67\x98\xc4\x92\xb5\xa3\x33\x86\x64\x96\xe3\xc0\xd9\xa2\x3d\xc0\x13\x5c\x2c\x75\x89\xf7\x25\xf0\x7f\x57\x01\x62\x0b\xe5\xa1\xbd\x38\xb4\x09\x29\x8f\xaa\xbd\x94\xdc\x07\x1d\x89\x4c\x28\x6a\xee\x9b\x1e\xbe\x13\x7d\x3a\x82\xda\x4f\x38\x7c\xb5\xe3\x95\x24\x0e\x5f\xde\x4e\x39\xb7\x7e\x4d\xbf\xb5\x40\x18\x12\x77\x5d\xc9\x6f\x8e\x76\x2b\x57\x95\x76\x37\x1a\x82\xd4\xf0\x2e\x10\x02\x98\x97\xc5\xad\xa7\x52\x30\x92\xe8\x80\x20\xfc\xdc\x16\x76\xc6\x26\x02\xd7\x85\xfb\x44\x87\x21\xf5\xde\xf7\x67\x4b\x98\xf0\x2b\xf8\x55\xe1\xf1\xfa\x0c\x29\x25\x1a\x81\x8e\xef\xdd\x4b\xb8\x2d\x3b\x78\x71\x3b\x82\x9b\x59\xff\xbc\xd8\x0e\x7c\x05\xfc\x61\x8e\x04\x67\xbc\x84\x1a\x0a\x15\x7e\xcd\xfc\xfb\xe2\x5a\x02\x16\x2a\x8d\x32\xac\xed\xea\xc1\xf7\x30\x32\x0c\x18\x6e\x33\x69\xc8\x8c\x63\xd0\xcb\x66\xfb\x60\xe9\x1f\x8c\xa4\x51\xc4\xb1\xaa\x7c\x5f\x7e\xc0\x91\x6f\xa1\x6e\x7a\xaf\x70\x1a\x41\x88\x04\x99\x1f\xb9\x6c\xca\xea\xe3\xf7\xc5\xc5\x34\xd2\x21\x76\xf2\x55\x55\x16\x60\x73\xc3\x01\x21\xc9\x8f\x03\xec\xd0\x9c\xf2\x02\x2a\xc7\x84\x71\x13\xd3\x7d\x7d\x9c\x69\x07\xe7\x58\x97\x65\x73\xe7\xa4\x42\xdb\x43\x5c\x2a\xa3\xe0\x7f\x39\x97\x05\x4e\x3d\x6b\x0b\xe7\x46\x24\x89\xc0\xce\x98\xb5\x0a\xf4\xbf\x38\xc9\x42\x7c\x0d\xf6\x15\x47\x19\xe9\x53\x5e\xd7\x68\xa9\x31\xb2\x66\xbc\x5e\x71\xd2\x44\xa8\xc8\xc2\xce\x76\x6d\xce\xb1\x43\xa8\x4d\xf7\x8d\x9a\x90\xd8\xa3\xb5\x8e\xa0\x9e\xaa\x49\xf5\x28\x46\xd2\x54\x1a\x86\x01\xb6\x9f\x87\x28\x15\x3b\x82\x11\xc3\x31\xc0\x16\x07\x28\x94\xb4\x1b\xdd\x43\x96\xea\xc0\xe4\x8f\xd5\x29\x2f\x78\x03\x3d\x58\x4f\xca\x98\xc4\x79\xb8\x30\xbe\x90\x17\x51\xcb\x2a\x3f\x4f\x85\x29\xee\x03\x59\x82\xd9\xfa\x5b\x89\xb9\xa5\x31\x44\x18\x7d\xa1\x94\x98\x11\xec\xcc\x52\x77\x9f\x4b\x28\x6a\xd8\x42\x75\x9a\xe0\xe9\xb8\xbe\xb1\xbb\x87\xc3\x97\x3b\xe5\x71\x96\x59\xc3\x91\xc6\x88\x17\xb9\x2b\xe7\x2c\x45\xf8\xc0\x5f\xe5\x65\x56\xc1\x1d\x54\xa3\x95\x2f\x15\x84\x61\xbe\x56\x5d\x8a\x0d\xfe\xa8\x7e\xe5\x20\x55\x81\x32\x2e\x71\x0d\xaf\x9a\x9d\xe3\x84\xb7\x07\x52\x66\x0c\xdf\x2b\xe9\xf7\x50\x29\x7b\xe0\x9d\x54\x65\xc6\xe8\xe4\xc4\x7f\xa1\x47\x81\x38\xc2\xe6\xa3\x68\x0e\xf5\x30\x76\x89\xec\x70\x88\x25\x96\x02\x3d\x83\xe7\xa5\xa8\xc7\x8b\x7e\x0a\xc2\xa8\x3c\xf7\x14\x5e\xfc\x54\x44\xfb\x47\xb7\x7b\x5a\x84\x0c\x98\x62\x7f\xdd\x8d\xe1\x06\x29\x7a\xf4\x84\x8b\xd1\x9d\xd4\xa1\x90\xe0\x9a\x87\xdf\x8c\x82\xb9\x51\x72\xc1\x85\x7d\x78\x39\x5a\xb0\x30\x72\xcc\x97\x35\xff\xf7\xf0\xd6\xb6\x21\x0e\xb6\xc9\x30\xd8\x34\x50\x4d\x6e\x5e\x7d\x3b\x80\x86\x91\x64\x8e\xfa\xd2\x86\x2b\xa8\x49\x36\xbd\xdc\x33\xca\x29\xe2\x7f\x40\x9e\x2e\x57\x06\x98\xa3\xb1\x01\xcf\x50\x5f\xce\x20\xdb\x66\xcd\x1f\xc3\xa3\x00\xc4\x78\x60\xc9\xe1\x5b\xda\x5f\x7c\x58\x18\xaa\xd4\xd8\x24\x7a\x1a\xd0\xf0\xe7\xb3\x30\x31\x1a\x7e\x46\x81\xc2\xd4\xad\xdd\xad\x66\x11\x40\xcc\x3c\x4d\xcc\x10\x43\xbe\x66\xaa\xda\x0f\xc6\x0a\x90\xc1\xf4\xf0\x34\xef\x97\x42\x59\x42\xad\xec\x7e\x1f\x75\x3c\x7c\xed\x58\x22\x0c\xf1\xd4\x6a\x7d\x3d\xe9\xd1\x15\xa7\x44\x48\x4b\xf4\x93\xaf\xf3\x09\xc2\xfc\xf0\x52\xd2\xd8\x14\x61\xf6\xd0\xdc\x56\x00\x73\xee\x26\x37\x4b\x15\xc7\xec\xdb\xc8\xc7\x15\x1d\x1c\x99\x11\xc6\x80\xe0\x9a\xd8\x5c\xaa\xe2\x49\xeb\x85\xd3\xc8\x7d\x84\x5f\xe8\x66\xf8\x5c\x36\x9b\xf3\x31\xf7\xe7\xca\x02\xc1\x78\xbf\x07\x67\x96\x30\xaf\xdd\x30\x7d\x6d\x99\x32\xa2\x4f\x7b\xc0\xa5\xfc\x49\x5f\xb1\xc1\x18\x61\x3c\xc9\xac\xa7\xe6\x2b\x14\xbe\xd2\xb6\xf1\x19\x24\xe3\x82\x62\x78\xb3\x87\x66\x20\xe6\x73\x23\xfa\x40\x3c\xc6\x65\x16\x29\xd7\x5c\xe0\xe7\xb2\x58\xf9\xc8\x81\x71\x30\x2e\xec\x0f\xe5\x1b\xdc\x03\x32\xb0\x3f\xb9\x64\x49\xa3\xcc\x12\x51\x57\xb2\xc4\x1a\x53\xf0\xd9\x50\x6d\x30\xce\xb9\x71\x7c\xd8\x55\x18\xce\xbb\xaf\x04\xc2\xc1\x02\xeb\x50\x7a\xf1\xbe\xdc\xfb\x6d\x96\xe9\x90\x60\x16\x34\xcf\x9b\xe5\x07\x0c\xa6\x90\x0e\x13\xe3\x92\xce\x8f\x72\x64\x05\xd6\x1e\x8d\x54\x60\x0a\xbe\x12\x8a\x26\x7f\xcb\xeb\xbc\xd8\x2f\xb5\x2e\xab\xa6\x1e\x16\x6d\x99\x66\x01\xb2\xa4\x1f\xa0\xb8\x90\xd0\xff\x55\xa6\xb8\x85\xbc\xf3\xba\xdd\x3c\x50\x78\xc9\x6f\x68\x19\xa1\x14\x43\xcc\xb3\x41\xed\xf5\x6a\x66\x19\x89\x29\xd6\x7d\xf2\xb3\xae\x77\x87\x6e\x63\xce\x48\x22\x68\x38\x10\x2d\x5e\x1c\x79\x3e\xa9\x81\xdc\x8e\x66\x02\xdb\x48\x33\xf5\xd6\x3e\xcb\x1a\x06\x5d\xeb\xc9\x37\x26\x23\x82\x22\xf5\x55\x43\x23\x0f\x8f\xfd\x79\x9c\x11\xc5\x30\xea\xb7\xe1\x3d\x6e\x63\x95\x37\x64\x6f\x07\x40\xa4\x4c\xa6\xf4\xfb\x36\xf6\xf8\x52\x75\x86\xdb\x47\x85\x4a\x6a\x6d\xea\x34\x29\x5e\x39\x0e\xd3\x32\x2a\x8c\x52\xca\x66\xbb\x7c\x70\x97\x41\x55\xca\xe3\x3e\x9a\xe3\x36\x87\x63\x37\x07\x27\x1b\x19\x19\xd5\xa1\xd0\x5e\xa8\xb9\x7b\x4a\x54\x1b\x30\xfc\x1e\x0a\x62\x8b\xa1\xfd\x37\x21\xa3\x5a\xa2\xac\x52\x5e\xa3\xcf\xdd\x6a\xf1\xd4\x75\xa4\x3f\x79\x2c\x01\x25\xd8\xa7\x98\xbd\x95\x92\xab\xb2\x3f\x23\xb3\x20\x30\x31\x7c\x0d\xcd\xd3\xcd\xf2\x61\xf8\x74\x07\x57\x3e\xba\xfe\x80\x05\x88\x21\x59\x9a\x98\xa7\xc3\x89\x66\x41\x66\xba\x64\xed\xa6\x72\xa9\x8a\x51\x8d\x31\x8b\xc2\x00\xdf\x81\xe2\x72\x6a\x17\xa3\xba\xdd\xd6\xd4\xd3\xc5\xff\xc0\x28\x55\x48\x6a\x37\xd0\x7c\xab\x57\xe1\x8e\x31\x85\xfc\x96\xe1\x4a\xb5\x2d\x97\xcd\x61\xfa\x3d\xce\x22\x10\xd0\x4e\xe0\x7f\x96\x39\x42\x94\xaf\x16\xdc\xe9\x59\x19\x27\x04\x5f\xc5\x45\x59\x48\x38\x7f\x6d\xad\x37\xb0\xa6\xf2\x9f\x37\x7b\x88\x51\x7b\x6b\x6e\x01\x83\xb0\xe1\xe2\x98\xc5\x99\xa5\xc5\x95\x75\xd3\xdd\xbe\x38\x93\xc2\xad\x88\x6d\x40\x6a\x12\xb5\xdf\x20\x62\xb2\x98\x0b\x63\x44\x58\x16\x7b\x14\xa4\xac\xda\xa0\xc1\x9f\x53\xca\xb0\x53\x6d\xb8\x2d\x2b\x90\xbc\xbe\x6e\x10\x5c\x7a\xda\xd1\x23\xa4\xa0\x2d\xd0\x66\x89\xe0\xd2\x36\xba\x1f\xe1\xfd\x81\xff\x72\x81\xce\xe8\xb7\xa5\x01\x47\xbd\xd2\x72\xb4\x23\x64\x2c\x4c\x71\x07\x5c\x6d\x97\xd3\xa0\xea\xfe\x92\x98\xb1\x88\x72\x3e\xf0\x70\x08\x62\xf7\xa3\x18\x78\xdd\xa8\x35\x3f\xa9\x6e\x96\x30\x9d\xa4\xc6\xf9\x19\x7e\x19\xa8\x9f\x3b\x92\x45\x80\xdd\xcc\xcd\xf6\xe5\xc6\xcc\x1a\x77\x20\x13\x69\xa7\x25\x3d\xe7\xf5\x35\x91\xdb\x2f\x01\x59\x26\xb1\xb9\x68\x9c\x3b\x11\x5b\xbd\x2a\xda\x5d\x80\x8f\x45\x1f\xda\xc1\xda\x94\xdd\x4f\xf9\xf1\x68\x9b\xe2\xcf\x3c\xf7\x17\xc4\x13\x8a\xae\x2b\x0d\xa6\x6a\xa7\x33\xaf\xfc\x9a\xcc\x19\xc5\xc5\x3c\x3f\x9d\x8e\x7c\xf0\xce\xf2\x0c\x9c\xee\xd3\xf2\xd7\x19\xe9\x74\x03\x49\xa3\xe9\x55\x80\x43\xe6\x74\xae\xe7\xbc\x69\xec\xf6\xd0\x7f\x33\x45\x60\x4a\xd6\xb2\x2c\xea\xcb\x09\x9e\xce\x60\x00\x81\xe3\x3e\xa5\x1d\x2e\x63\x61\x5a\x8a\xc8\x67\xbf\x81\x2e\x25\xb1\x03\x54\x9a\x91\xc0\xbb\xe4\x4d\x08\x2d\xbb\x71\x2c\x63\xcc\xd9\x3c\xe4\x62\x58\x56\xcb\x54\xc6\xb3\x3e\x5b\xe1\xa1\x2c\x06\x4c\xa3\xfe\x39\x93\xc8\x7d\x88\x8b\xc4\xce\x1b\xdf\xe8\x18\x16\x63\x33\x08\xa2\x10\x31\xc9\xbc\xf8\xc5\x8b\xfd\xa2\xb7\xeb\x41\xc4\x03\xe5\x80\x7e\x2f\x45\x9b\xcd\x76\x73\x08\xe2\xa0\xaf\xf8\xf2\xeb\x0c\x55\x0e\xe3\x22\x89\x5f\x26\x41\x1b\x6a\x8a\x37\x61\x1d\x6d\xca\x9a\x49\xdc\x4f\x7e\x40\x55\x5f\x4e\xbf\x7f\x21\xb4\x8c\x4c\xb0\xf3\x7d\xfd\xb2\xb9\xf1\x67\xd1\x22\x20\x1d\xa0\xc4\x76\x4f\xc6\x58\x3b\x4e\x68\x8c\x60\xab\xf5\x7c\xb6\x78\x18\x68\xf2\xba\x01\x32\x4a\x68\x47\x28\xb5\xf5\xa2\x52\x21\x46\x75\xf0\xd0\x38\x8d\xb9\xb2\xb1\xd4\xba\x94\xaf\x60\x80\x86\x13\x9b\xe8\x64\x1d\x64\xb4\xad\x72\xca\x99\x81\x56\xa2\x1b\xd4\x10\xee\xe6\x86\x08\xee\x1e\x69\xbb\x65\xdc\x83\x46\x64\xf1\x2f\x27\xdf\x3a\x3d\xb9\x38\x05\x43\x82\x6f\x03\x39\x14\x21\x1c\x1e\x0e\x42\x85\x65\x17\x04\x04\x70\xb5\x87\x3f\x46\xfb\xc2\x68\xb8\x52\x28\x55\x6c\xab\x71\x91\x7d\x00\x3c\x4c\x21\x08\xad\xe6\x76\xa5\xee\xf2\xfd\x61\x33\x08\x4a\x86\x3f\x25\xe4\xc6\xb9\xc4\xf2\xa1\x71\x4a\xdc\x74\xe1\x18\x0f\x35\x13\x96\xfc\xfb\xb3\xac\x5e\xf5\xb1\x7c\x7f\x74\x42\x8d\xdd\xb5\x84\x3a\x13\xa1\xf3\xdd\x5d\xf0\x73\x37\x1f\x78\x14\x18\xc3\xa5\x1f\x79\xc3\x4f\x43\x3a\x00\x8f\x49\x2a\x4d\x00\xb1\xab\xcd\x5c\xdc\x89\x9e\x07\x55\x3b\x82\x4a\x5c\x58\x51\xe7\xf2\x06\xe4\x91\x57\x56\xf8\xc4\x2c\x19\x6e\x58\x64\x12\x80\x33\x6a\x7b\x0c\xbf\x43\x4a\xcc\xda\x6d\xdf\xfc\x47\xce\xbf\x34\xff\xb1\x9f\x4a\x00\x52\x35\x50\x5a\x9d\xdb\x69\xe5\xce\x9b\x86\x4c\xf4\xdd\xc4\xdb\x1b\x8d\xfa\x23\xcf\xff\x3f\x6b\x6f\xd6\xdc\x38\xae\x65\x8d\xfe\x9d\x7a\xb8\x0f\xc4\xc0\xe9\x51\x96\x65\xa7\xba\x6c\xcb\xc7\x52\x56\x9d\xea\x13\x1d\x0a\x0c\x1b\x36\x3f\x53\xa4\x9a\x83\x33\x55\xbf\xfe\x06\x37\x00\x4e\xa2\x9d\x75\x6f\x7c\xd1\x71\x22\xab\x4d\x90\xe2\x00\x6c\xec\x61\xed\xb5\xca\xf9\x74\x49\xa9\xc4\x86\x81\xb3\xb8\xd8\x54\xfc\x15\x04\x6a\xfa\xe3\x69\x6c\x6b\x06\x35\x14\xfa\x00\xe2\x34\xe3\x85\xba\x1a\x9d\xa2\x97\xd6\x2f\xeb\x2b\x7c\xd2\xf2\x79\x22\xec\x01\x65\xe8\x38\xdd\x95\x2e\x5f\xb4\xcb\x67\x95\x0e\x21\x64\x80\xc1\x4a\x01\x3f\x9b\xbe\x97\xc9\xca\x6e\x8e\x8c\xb6\x90\x91\x95\x2f\xb0\x69\xaa\x17\x50\x6d\x55\x0d\x22\xac\xd3\x44\x95\x90\x32\x09\x6d\xbd\x0f\x61\x4e\xb3\x2c\x95\x50\x21\x47\x2c\x6e\x69\x2d\x7f\x31\x83\x8a\x08\x15\x11\xe4\x5a\xbf\x19\xda\x7d\x91\x3d\xfe\xf3\x45\xef\xac\xf2\x6c\xfe\xab\xc4\xd6\x3e\xd1\x4d\x19\x4f\x29\x25\x04\x62\x51\xce\x88\x86\x98\x54\xe3\xdc\x08\x4d\x62\x49\xfb\x8d\x7a\x9f\x35\xb0\x87\xc5\x06\xd0\x6e\x2c\x55\xc6\x21\x27\xd6\xe2\xfc\xc9\x97\xd4\xa0\xb1\xd8\xe6\xf8\x4c\x1f\x4a\x31\xe6\x31\x4d\x02\x01\x1c\xb0\xcf\xee\xe8\x42\xc1\x01\xae\x2f\x40\x07\x88\x71\x7e\x28\xcb\x02\x2e\xb7\x59\xbf\xb9\x08\x13\x05\xb8\xf5\x39\x5d\xd7\xed\x7a\xe7\x55\xaf\xf1\xa0\x8e\x9d\xbc\xc1\xc6\xe5\x2b\x9f\xab\xf2\x23\x5b\xc0\x15\xfb\x33\x74\xc2\x79\xaf\xca\xf9\xd1\xf9\x70\x3d\xb9\x4f\x7f\x55\x0d\xc2\x61\x55\xb6\x7e\x7b\x91\x01\xa5\x88\x09\x70\xd5\x8c\xb6\x2a\xe6\x05\x0f\x49\x03\x8a\xdd\xa6\xcd\x1b\xae\x22\xff\xd7\xd4\xc4\xaa\xe7\x4c\x98\xd7\xc5\xe6\x2c\x52\xee\x24\x16\x28\xc2\xfa\x2e\x8b\x43\xb9\x2f\xfb\x9e\x5b\xc9\x12\x5b\xdf\x79\xb6\x4a\x9d\x87\x9f\x5e\x85\xb1\x3b\xa6\x98\x4e\xc6\xb5\x72\x6c\x54\x53\xcb\xac\x44\x49\x20\x39\xb7\x4a\x44\xf0\xb3\xa9\xc4\xbe\x11\x4d\x7d\x57\x56\xf7\x53\x2d\xfe\x24\x90\x21\x25\x2c\xf2\xe0\x3e\x54\x51\x1f\x92\xe1\x32\xa4\x21\xe6\xd9\x7c\x88\x82\x3f\xfc\x67\x25\xce\xe7\xab\x37\x14\xc6\x09\x75\xb4\xb9\xaa\x2f\x9a\xcc\xdd\x21\x19\x39\x31\x8b\x1f\xe2\x1d\xbe\xcf\x5c\x7d\x19\x39\x72\x1d\xeb\x80\x6f\x4e\xe7\xe6\x82\x3d\xfa\xfe\x6e\xa2\x94\xa4\x23\xac\x2d\x66\xc0\x97\xdb\x1d\xff\x9f\xc9\x27\x20\xee\xfc\x58\x09\x24\xcc\x41\xb9\x8c\x6b\x70\xa6\x4c\xc2\x10\xd3\x2c\xff\x9d\xbd\xbe\x5e\xc6\xa6\x5a\x26\x10\x69\x32\xe0\x52\xbc\xd7\xdb\xbd\xd5\xf6\x9a\xe1\x65\x30\x3c\x52\x70\x19\x87\x43\x2b\x6b\x59\x4c\xba\x8c\xa5\x64\x2c\x0a\x46\xf0\x90\x43\xb9\x55\xe5\xec\xae\x14\x09\x31\x0f\x68\xab\x6c\xb3\x57\xa6\xd2\x54\x49\x47\x65\xf5\xd0\x79\x18\x3e\x42\x92\x3a\x48\xed\x77\x6d\xf3\x26\xc3\xc6\x58\x7f\x80\xc6\xd4\x32\x4c\xaa\xb6\xca\x9a\xcb\x55\x2f\x9c\x04\x66\x61\x8e\xdd\x57\xb7\xef\xf7\x09\x7e\xcc\x7e\xd8\x04\x29\xfa\xb5\x65\x75\x7e\x13\x45\x73\x5d\xf6\x91\x26\xe4\xd8\xf5\x7c\x12\x3f\xb7\xeb\x9d\x05\xfc\x4e\x8a\x7f\xd2\xa4\x89\x15\xd7\x12\xef\xb0\xff\x21\xce\x3d\x37\xa8\x3f\x2e\x2d\x09\x59\x0d\xcd\x55\xa0\xb1\xbc\x75\x48\xe3\x44\x51\x6a\xc8\xf3\x3f\xca\x56\x8d\xd2\xca\xd2\x40\x92\x58\xdd\x86\x39\x0e\x44\x05\xa1\xc4\xed\xde\xf2\xf9\x1f\x95\xc8\x73\xd9\x4d\xbc\xc9\xc6\xa0\x02\x41\x11\xda\x82\x59\x18\xcb\x30\x5f\xb7\x79\x73\x57\x56\x3d\xc1\xf2\xf4\x1d\x28\x92\x68\xee\x92\x1e\x5e\xcf\xb4\xbc\xb3\x5e\x51\x3d\x1f\x9a\x5a\xee\x01\xdb\x59\x85\x4a\x7b\x0e\x89\x6a\xd5\xfa\xb7\xc5\x88\xb4\x6b\x7a\x2a\x75\xb2\x17\xce\x3a\x3b\x45\x51\x6f\x38\x14\x0b\x0c\xd3\xbe\x95\x61\x46\xc6\x3c\x7d\x0d\x8c\x72\x65\xdb\xc9\x6e\x44\x9e\x97\xcd\xb6\x33\xb9\xaf\xb8\xb9\x8d\xfd\x75\xc5\xe2\x04\x3b\x73\xbc\xa6\xef\xfc\x59\x58\x9a\x1a\x9b\x71\xef\xfc\xa1\x9e\xaf\xb8\xbf\x21\x63\x43\x28\xa1\xf5\x9d\xa8\x4e\x73\x53\xa2\x38\x65\x28\xad\xd3\x54\x97\x43\xf9\x67\x6f\x8d\x14\x87\x50\x0d\x55\x67\x2c\x53\x40\x9d\xfd\x0d\x5e\xbe\x62\x58\x77\x2a\x94\x80\x53\xeb\xfb\xfd\x78\x66\xab\xc8\x18\x8c\x24\xdf\x01\xce\x22\xcf\x3e\x60\x5c\x45\x56\x71\x18\xc4\xce\x79\x7e\x44\x68\xe5\x8c\x0d\x28\x09\x54\x12\x44\x98\xbc\xf3\xd5\x94\xa3\x4f\x2b\xaa\x84\x04\x98\x66\x7b\x6c\xd5\xe4\x27\x13\xa2\x88\xcb\x54\x20\x8e\x0d\xb9\x67\xfc\xb1\x48\x21\x59\xc2\xba\x3c\x9d\xca\x62\x53\x55\x65\x35\xae\xeb\xa8\x44\x50\x4b\x72\xdd\x5d\xd0\xcf\x0a\x3e\x96\x23\xe9\x06\x19\x8d\x15\x87\xb3\xab\xaa\x4d\x36\x66\x95\x86\x04\x9d\x41\x37\x37\x30\x75\x85\xa5\xf5\x6d\x71\x97\x15\x05\x5c\xfa\x81\x51\x48\xe3\x5e\xef\xa1\x54\x96\xf0\x75\xb5\xdb\x43\x83\x34\x41\xd3\xa5\x90\xa6\x5a\xbb\x3e\x40\xeb\x6d\x65\x4a\xe4\x37\xad\x1e\x98\x20\x94\x88\x05\x36\x78\x99\xb2\x52\xdd\x4a\x81\x3e\x9e\x53\x42\x28\xe2\x34\x96\x0e\x59\x93\xc3\xf6\x34\x94\x72\xfd\x10\x08\x90\x4e\x00\x35\x64\x77\x0a\xc4\xa7\xa4\xd3\xff\x7f\xff\x75\x3f\xa4\x83\x00\xb3\x1d\x0e\x4c\xdb\x45\x3f\xc5\x12\xec\x78\x31\x48\x51\x9a\x72\x44\x9f\x97\xc6\x5c\x97\x84\xe6\xbf\x14\x0a\xe5\xba\xde\x57\xe7\xf3\xb6\xa8\x1b\xf4\x9d\x17\xbd\x04\xa5\x05\x45\x2f\x73\x73\x7f\xbf\x3f\x1e\x76\xc7\x6f\xab\xc3\xfa\xdb\x91\x1c\x76\x2b\x1f\xbf\x28\xad\x52\x8c\x8a\x5f\x36\xfb\xc3\xcb\x76\x7d\xd8\x78\x19\xc5\xe3\xed\x77\x94\x9e\xf5\x60\x16\x05\x51\xa0\xbd\x56\x38\x9a\xac\x31\x9c\x50\x81\x02\xec\x49\xf0\xb9\x83\x43\xf9\x0b\x33\x61\x68\xe4\xeb\x0c\x88\xbd\xc2\x1a\xc1\xe0\xba\xe9\x20\x56\xe8\x4f\xdd\x67\xa6\xf1\x73\x5d\x93\x20\xc5\x2a\x9c\xa9\x00\xfe\xfd\xf0\x78\xdf\xff\x5d\x6a\x64\xf1\x74\xf9\xeb\x6f\xfd\xc4\xd6\x44\x49\xaf\xb2\x7e\x8b\x12\x98\x9d\xaf\x3e\x5e\xb0\x9a\x72\xc0\xd6\xfe\xfd\x76\xff\xfb\x01\xd4\x5b\x51\xe6\xe5\xeb\x05\xf9\x56\xc7\x6b\x50\x53\x45\x2c\x9c\x48\x74\xcf\xaf\xda\xb9\x38\x86\x63\x8b\xd0\x8c\x6a\xc4\xcd\xaf\xdf\x44\xb9\xf9\x39\xb9\x04\xa3\x06\x39\xbb\xb2\x7a\x86\xbc\x72\xc7\x43\x0a\x36\xd2\x77\x0a\xb9\x5d\xcc\x3d\xc6\xa4\xe9\x30\x62\x08\xda\x7c\x28\x5f\x6d\x7d\xda\xbf\xe4\xbe\xf0\xfc\xe5\xce\xa6\x23\x62\x95\x4d\x50\xb0\x0c\x6b\x4e\x57\x54\xd4\x8b\x4d\x04\x63\xec\x99\x8e\xa5\xad\x90\x67\x85\x2a\x4f\x59\xf1\x6a\x77\x98\x11\xad\xb3\xb7\xd1\x3a\xd6\x89\xa5\x92\xc9\x3e\xe0\x11\x6e\x84\x7a\x7f\xbc\xa0\x8b\xd8\x0f\x30\xb6\xea\x76\x10\x3f\xb3\x89\xc5\xd3\xb1\x49\xa9\x6f\xca\xab\xc6\xb4\xb4\xd3\x07\x4a\x42\x4b\xe7\x38\x8a\x18\xbe\x5c\x3f\x3a\x91\x2c\x71\xf9\x9b\x7f\x35\x97\x7d\x03\xe7\xbb\xb6\x98\x42\x42\xfb\x08\xeb\xf3\xff\xf0\x17\x53\x36\x17\x71\x6e\x65\x9e\xd5\x6f\x13\xa2\xc8\xf1\x1b\x4b\x43\xe9\xd4\x4a\x3a\xcf\x65\x3f\x18\x31\x9d\x3a\x8c\x5a\x05\x66\xec\xd3\x69\x21\x88\x4f\xfe\xde\x3a\x5f\xf8\xae\xac\x2c\x2c\xfa\xeb\x4a\xa6\x96\x71\x8a\x93\x68\x8f\x04\x7c\xab\x42\xdf\x95\xde\x9f\xd3\x52\xc6\x68\x71\x5f\x84\xca\x8a\xd7\x75\xde\x4a\x57\xf8\xe8\x07\x68\x40\x08\xfc\xf3\xf6\xb8\xb9\xdd\x1e\x8e\x3e\xed\xa2\x95\x30\xde\xb2\xbf\x80\x99\x54\x8f\xb4\x92\xc6\x73\xb3\x5a\xf9\xb2\x11\xbb\x8a\x56\x10\xf8\x0c\xcb\xea\x87\xa8\xf4\x08\x34\xa5\x15\x80\x72\x0a\xda\xdf\x5a\x14\x1a\x5a\x00\x6c\x69\xad\x14\xd6\xd6\x2d\x13\xcd\xf1\xdb\xea\xe5\x76\xc4\x0c\xa0\x41\x87\x49\xd4\xc7\xa9\x77\x95\xe3\xd9\xf9\x66\x99\x5e\xa6\x5e\x81\x06\x48\xd1\x88\x9d\x90\x0f\xcf\xb1\x63\xfa\x2b\x19\x6a\x71\x09\x07\xd0\xfa\x32\x48\x7d\x77\x47\x38\xc1\x0f\xfd\xd4\xaa\x1c\xda\xfa\x8f\x0c\x91\x2f\xd9\x09\x9c\x3e\x85\x5d\x02\xc8\xe4\xff\x4b\xa5\xa0\xd9\xe7\x32\x82\x59\x8e\x6f\xf1\x01\x16\xd6\x35\xde\xc2\xb4\x91\x24\xe0\x9e\x0a\x09\x01\x41\x64\xf6\x48\x06\x00\x53\x8d\x4f\xf0\x63\x84\x63\x81\x80\xa5\xd8\x7b\x5a\x61\xca\xf0\x1e\x8d\x36\x36\x74\x4f\xb3\x87\x7e\xb4\x0a\xb0\x47\xe2\x51\xd4\x35\x72\xba\xec\x91\x3f\xc1\x5f\x8c\x30\x49\x9c\x8f\x71\x16\x85\x0d\x6b\x5c\xbe\xff\x1f\x61\x5b\x81\x84\x32\x8c\xfa\xdc\x89\xa5\xee\x9d\x3e\x07\x90\xd0\xc4\x91\x2f\x66\x65\xb9\x5e\x98\x0a\x40\x12\x86\xd9\xae\xf5\xc3\x6a\xbf\x3f\x3e\x3f\xac\x9e\x0e\xfd\x2d\xca\x54\x59\x0a\xd6\xa2\x5b\x8a\x98\x77\xff\xba\x17\x0f\x68\x48\x62\xe5\xb1\xb0\xb5\x6d\x00\x18\x9e\x99\x46\x96\x49\xab\x5b\x82\x65\xfb\xba\x40\x96\xd5\x0d\xd2\x21\x62\x90\xbb\x5d\xdf\x71\x21\x0e\xdd\x9b\xc0\x98\x25\x78\x73\x7c\x63\x3f\x4a\xd3\x1f\x89\x25\xe6\x33\x46\x88\x99\xa7\xce\x98\xce\xaf\xcf\x0c\x11\x36\x51\xf7\xfa\x9a\x8f\x2a\x25\x83\x97\x0a\x3c\x06\x2c\xa8\x38\x6e\x6e\xfc\xbc\x9d\x67\x59\xb6\x0d\x02\x56\x77\x66\x9a\x5b\x82\x90\x1a\xac\x03\xe3\xd3\xae\x45\xfd\x46\xfa\x23\x3a\xc6\x6c\x51\x17\x96\x5c\xa3\x98\xfb\x1d\x61\xa6\xb4\xd2\x9d\x08\x01\xe2\x40\xb7\x87\x9d\x25\xf5\xf4\xcd\xca\x10\x71\x5b\x9e\x93\xed\xe5\xa6\xc4\x6f\xe2\x0f\x48\xdb\x0c\xb5\xf6\x05\xc6\x1b\x51\xbc\xbb\x89\xe1\x86\xc4\x5c\x06\xbc\x2f\xd9\x60\x59\xdc\xc2\x2b\xac\x44\xf4\x0b\x7c\xe0\x3a\xdc\x14\xce\x3b\xb4\xff\x6f\xff\x9c\x89\x24\x76\x0b\x71\xdc\x1c\x96\x78\xe5\xff\xb3\x07\x38\x7d\xd2\x34\x88\x5d\x8b\x32\x96\x2c\xfc\x6f\xa5\x82\x60\xbf\xfe\xfe\xb0\x3a\x7c\xdf\x1f\x1f\x36\xc3\xc4\x4c\x21\x05\xcf\x5c\xdd\x9d\xb2\xd5\xf5\xcd\xe5\x50\x9e\x33\x35\x9b\xdc\xa9\x49\x13\xe5\xab\x6c\xca\x79\x82\xf3\xe4\x07\x88\x84\xc6\x4e\xdb\xc1\x62\x95\xa7\x87\x25\xb1\xcc\x67\x27\x5b\xbb\xd9\xea\x43\xb9\xfd\xe3\x93\x96\x49\x90\x91\x8c\x8d\x47\x91\x5b\xb3\xf9\x2c\xb2\xea\xd3\x38\xd9\x9f\x26\x83\x64\xe8\xe2\x73\xce\xa0\x3f\x06\x1a\xeb\x23\x5e\x71\xaa\xfc\xbc\x15\xd3\xdf\xd3\xe0\x45\x82\x62\xb6\xab\x14\x75\x34\x6f\x2e\x2f\x85\x9e\x2a\xaa\x77\x43\xb8\x48\x2d\xaa\xdb\xe5\x83\x7b\x05\xbf\xe9\x38\x0d\x8c\x3a\x68\xf2\x6d\xa9\xda\xce\xed\xf3\xc4\x1e\xf3\x81\x26\xe9\x73\xf0\xbd\xbb\xe1\x0e\x42\x1a\x23\xfa\xe3\x08\xcd\xdb\x34\x64\x02\xc3\x42\x66\x69\x75\x2e\x58\x3d\x9e\x06\x37\x60\x04\x47\xa6\x20\xf8\xd9\xdc\xf8\x64\xdb\xd7\x3b\xb7\x09\x18\x1f\x64\xf4\xad\x5f\xd7\xb9\x14\xaa\xd4\xd3\xb8\xc6\x04\xcc\x88\x68\xc4\x77\xf0\x0c\x3d\xd5\x9b\x21\x09\x53\xb6\xfd\xb0\xce\x9a\x9e\x89\x38\x09\x0c\x0d\x18\x6e\xed\x7d\x27\xc8\xf4\x3d\x18\x9a\x26\x29\xef\xbb\x8a\xef\xca\x6a\x0d\x73\xd4\xb2\xa1\x46\x04\xae\xa5\x78\x0f\x79\x6e\x4d\xf4\x64\x72\x18\xc6\x15\xf1\x1a\x2b\x65\xd5\x80\x1e\xa5\x02\x0d\x4b\x2d\xec\xdd\x19\xa6\xad\xce\xfa\x3c\xa8\x61\x26\x48\xdd\x4e\x77\x7f\xbf\x5e\x34\xb7\x86\x13\x88\x23\x87\x4a\x70\xd5\xfe\xd9\x1d\x72\xce\xa8\x73\x4e\x61\x5c\x22\x35\x3c\x64\x88\x89\x45\xe8\x69\xb7\x75\x57\x9b\x5c\x9c\x07\x14\xaa\xe1\xc2\x9a\xe4\x1a\xe0\xd1\x89\x63\xf6\x2f\x95\x4b\x25\x13\x1f\x43\x23\x93\x69\xdf\x6e\xe1\x46\x84\x61\x64\xf1\xc9\x58\xaa\xee\xff\x2a\x18\xee\x30\x57\x7a\x22\xff\xac\x25\xc4\x84\x10\xa0\x10\x6e\xfd\x56\xb6\xb9\xbe\x29\xcb\x7a\x56\x67\x30\x91\xb2\x4d\xde\x35\x34\xa8\xfe\xbf\x28\x03\xde\x8d\xd3\xb1\x65\x45\xf8\x21\xce\xd3\xfd\xc0\xc4\xda\xb2\x5d\x63\x2b\xda\x0b\x08\xed\x39\xd3\x87\xfb\x88\xc1\x12\x65\xad\x9e\xb6\x8f\x9b\x71\x8b\x83\x49\xa2\x00\xdb\x1f\xb6\xf3\x94\xbd\x49\x52\x81\xdb\x8c\xc4\x2c\xd0\x93\x38\xc1\x34\x01\x64\x92\xd4\xe2\x2f\x07\xba\xd5\xdb\x97\xc7\xdf\xaf\x01\x20\xb3\x77\x92\xe8\x08\x6b\xd8\x15\xe8\x39\xa7\x6c\x77\x14\x04\x26\x43\x9f\xdb\xe6\x78\xf3\x72\xf8\x76\xbc\xbf\x3b\xcc\x26\x91\xa0\x31\x35\x7e\xdb\xef\x76\xca\x6e\x26\x2d\xd0\xdc\x24\xb3\x1f\x16\x3c\x44\xb8\x8c\x2a\x4f\xe7\x1c\x1a\xd0\x07\x51\xbf\x4f\x52\xb1\x46\xb8\x3a\xfc\x2b\x6a\x05\x5f\xa0\xaa\x7b\x00\x40\x33\x9f\xcb\x22\x4e\x79\x0f\xd8\xab\xef\xca\xca\xe5\x66\xfa\x6b\x25\x51\x60\x9c\xb2\x5d\xdb\xc0\xc6\x41\xf9\x1f\x45\xa1\xaf\x9a\x14\x8d\x22\x91\x87\x97\xf6\xad\xab\xd7\x8b\x03\xb8\x15\x67\x74\xc6\xd9\x36\x6d\x3c\x8b\x8b\x05\x0e\x2d\x09\x06\x90\x68\xde\x84\xea\x2f\x25\x35\xf6\x7c\x79\x79\xd7\xb1\x81\x22\x41\x40\x0c\xe2\xc9\x5c\x07\xc2\x88\x7e\xde\xc5\x4e\x24\x20\x11\x37\xf1\xc8\x86\xdd\x3c\x0f\x8e\xca\xd2\xb6\xd3\x9d\x61\x3b\x6d\x5e\xa1\xb9\x69\xd4\x0b\xfc\x6f\x0b\x75\x33\xb0\x46\x2d\x30\x8a\x90\x80\xb2\x24\xb6\x69\xcb\xaa\x78\x01\xfd\x92\x49\x59\xda\xe2\xc4\x74\x1c\x0b\x00\xd3\x04\xab\x07\x1f\x58\x90\x80\x07\x36\x93\x5f\xb4\xa7\x9d\xf1\x5a\xfb\x75\x7f\x94\x12\x5c\x78\x9b\x9f\xe7\xce\x67\xf1\x41\x40\x7f\x38\x04\xa1\xbd\xd4\x9a\xa7\xc0\x4f\x48\x10\x0a\x61\x11\x25\x95\x28\x9a\x95\xfe\xc8\xea\x72\x09\xc7\x4e\x82\x88\x83\x6f\x9c\xb5\x5e\x51\x59\x79\x7c\x92\x1f\xa1\x43\x9f\x69\x5c\x67\xcd\xc5\x69\x0f\xa1\xef\x3c\xe6\xbf\x9b\xbd\x91\x58\x52\x74\xd5\x9e\xca\x0f\xd1\x2d\x78\x7f\xb5\x84\x10\xa4\x8c\x94\x6d\x55\x8b\xea\x59\x5c\x76\x6d\xf3\x34\xda\x88\xae\xc5\x7b\xba\x93\xc2\x94\x7a\x4e\x99\xdf\x0b\x65\x59\x82\xa7\xbf\x97\x44\x31\x6e\x3b\x88\xde\x79\x82\x1f\x37\x99\xbe\x1a\x91\x92\xc4\xb2\x82\xae\xb0\x05\xda\x25\xad\xe7\xbf\x05\x21\x36\x94\x5b\x0b\x3b\xc8\x42\xfb\x07\x10\x24\x45\x22\x6a\x9f\x81\x5a\x97\xb9\xd3\x6f\x9c\xfd\x9e\xa0\x56\x74\xfd\xfc\x87\xe5\x35\xc9\xca\xc2\x36\x07\xfb\xe3\xcc\xea\x03\xbf\x89\x4a\x1f\xf3\x9e\xe6\xbe\x3b\x92\x24\xd4\x8c\xd4\x90\x5e\x6d\xc4\xbf\x04\x3b\x24\x81\x50\x76\x23\xc6\x38\x09\x75\xc8\x67\x0f\x24\x45\x80\xab\xf1\xb9\x95\x79\xa6\x8e\x5d\xf0\x36\x61\x5b\x25\x81\x94\xa0\x98\x47\xc7\x7c\x83\xfc\xec\xa3\x13\x12\x48\xb0\x5a\x59\xae\xa9\x1d\xad\x10\xb2\x9a\xff\xdf\x48\x68\x92\x40\x05\xc2\x24\x83\x02\xb4\x85\x08\x5c\xa6\xfa\x88\x4b\x19\x19\x12\x28\x29\xb5\x93\x86\x3f\x9e\x30\x9e\xf5\x25\x6b\x96\xfa\xb5\xaf\x8c\x65\x77\x7c\x7c\x11\x7f\x8b\x55\x91\xd5\xd3\xfe\x19\x12\xe8\xd0\x2a\x30\x75\xbe\x8a\x9b\x79\xb6\xcb\xa4\x9f\xfc\xc0\x0d\x4a\xfc\x28\x51\xbf\xed\xda\xaf\x2b\x3a\x24\x80\x38\xc1\x2d\x4e\x5b\x88\xc5\x56\x95\x13\xdd\xe7\x6e\x44\x6a\x29\xa4\xee\xf3\x52\x8a\x7c\x74\x2f\x24\xe0\x56\xa3\x4b\xd8\xc5\x7a\x99\xc8\xff\x24\x84\x10\x08\xc4\xc8\x12\x8a\x9f\x87\x9f\xf7\xa2\xbe\x8e\x5e\xbb\x91\x0a\x85\xcd\x7d\x73\x8b\x15\xd0\xf0\x07\x8d\xe5\x1c\xce\xea\xbb\x0a\xe0\xef\x59\x03\x31\x21\x34\xd0\x98\xfa\x3b\x5d\x1e\x44\x17\xfb\x18\x7f\x22\x4d\x28\x3a\x36\x9b\xe6\xed\x0f\x28\x9a\xb6\x2f\x54\x13\xc2\x80\x62\xbe\xd1\x83\x38\x9c\x87\x6f\xf1\x0a\x6e\x4c\x28\xa8\x07\xbe\xef\x8a\x6e\x27\xb4\x4c\x83\x23\x30\x08\x21\xa1\x09\xd1\x16\x6d\x3e\x84\x6a\xaf\x9a\x9b\x09\x89\x94\x25\x4e\xc0\x79\x8a\x49\x8a\xba\x67\xe1\x74\x43\x62\xce\xb0\xc0\x60\xb2\xd7\xb7\x2e\x2e\xf9\xac\xc3\x89\x90\x84\x45\x8c\x79\x4d\xb4\x6e\xb3\xab\xa6\x4d\x40\x84\x20\x28\xbc\xfb\x9a\x8d\x5b\xc1\x80\x9c\xd3\xfb\x42\x9c\xeb\xb7\xb2\x99\x5d\x2f\x65\x82\x05\x3d\xa9\x94\xdb\x36\x6c\xf6\x74\x3e\x32\x4c\x2d\x2d\xb7\x73\xee\x36\xaa\x44\x02\xbd\xb1\x31\xba\x42\x54\x11\x92\xaa\x00\xfb\x18\x3b\xd7\xca\x3f\x6e\x6a\xb8\xf0\x88\xc9\x52\xcd\x7e\x47\x04\xc2\xaa\x5c\x20\xe2\xd8\x3a\x13\xfe\x44\x01\xca\x0c\x69\x0c\x4c\x8a\xfb\x43\x92\x50\xac\x64\x16\xa5\xeb\x58\xfa\xca\x77\x24\x44\x0a\x89\x1d\x65\x28\x78\x9b\xd5\x6b\x91\xe7\x50\x4d\xbc\x25\x42\x54\x44\xa3\x81\xd6\x76\xab\x4a\xcc\x36\x6f\x8a\x2b\x17\xb0\x1b\x1a\xe1\x3c\x29\xc4\x09\xf6\xad\x52\x50\xd7\x33\xd4\x1b\x21\x1a\x68\x60\x01\x4f\x4e\x2c\x0e\xf4\xcd\xc5\xce\x87\xd9\xd5\x80\xf0\xb1\x34\x94\xef\x27\x9a\x0d\xe2\x06\x33\x1b\xb7\x59\xdd\xed\x4a\x30\x9f\x53\x10\x3a\x11\x0e\xaf\x22\xe3\xff\x2e\x22\x0d\x93\x5a\xc4\x17\xf4\x44\x43\xa1\xbd\x5b\x82\x31\x86\x74\x6f\xa2\x46\xe5\xac\xbf\x40\x54\xf3\xe5\x6e\x80\xa3\x39\x40\xcd\x8f\x81\xd5\x3d\x21\x34\x88\xad\x47\xa0\xb1\xce\x70\xff\xf0\x6f\x7f\x80\xc8\x40\x0f\x6c\xcc\xfb\x6e\xd7\xd5\xc8\x18\x33\x99\xd6\x94\x68\xdb\xb1\xf2\x78\x79\xce\xfe\xfe\x5b\x3c\x67\x16\x29\xf1\x5c\xc1\x98\xe4\xff\x33\x38\xf5\x2f\x9b\xe7\xbf\x34\xf8\x94\x68\x6b\x5e\x5e\x56\x87\xcd\xf1\x76\xf5\xd7\x31\xf6\x77\xcf\x22\xf0\x0a\x69\xdf\x6b\xa8\xfe\x9a\xf1\x30\xf4\xb7\xcf\x03\x66\x15\x0a\xca\xa2\xb5\xaa\x9e\xf8\x0e\xa7\x74\xdd\xdd\x30\x89\x1f\xad\x6e\xa5\x7f\xb5\x23\x66\xc7\xa9\xcb\x47\xb9\x94\xe8\x03\xab\xb2\x68\xb2\xa2\x75\xa4\xb5\xc3\xa6\x4f\x43\x1a\xf2\x64\x1a\x32\xef\x3b\x27\xba\xba\xc9\x85\x7a\xef\x75\xe2\x0e\x97\xf3\xd4\x43\xa5\x21\xb5\xc2\xaf\x9d\x33\x29\x6a\xf8\x57\x9b\xcd\x2a\xf5\x84\x86\x8a\xa0\x33\x6f\x31\x13\xfb\x39\xc6\xab\x1b\x10\xa1\xb6\xcf\xf1\x15\x9a\xdb\xec\x23\xd3\x50\xe8\x7a\xd1\x51\xa2\xa1\x02\x04\x53\xd5\x6f\xe5\x8f\x47\xa8\xeb\xc1\xf0\xd3\xd0\x28\x44\x1c\x35\x6f\x59\xa5\xdd\xc7\xde\x14\x7a\x40\x29\x12\x1a\x31\xe3\x89\x81\xf7\xdd\xa4\xd6\xa3\xa0\x83\xd0\x28\x4d\xb1\xf4\xf6\xaf\x36\xab\x32\x55\xd6\xc3\xdf\x05\xfa\x55\x1f\x65\x03\xcb\x77\x15\xa5\x96\xcc\x17\x29\xb3\x3a\xdb\xbf\x2f\xf3\x76\x22\xf0\xbd\xc4\x25\x33\x4c\x9a\x2e\xf8\x74\x64\x43\xcf\x6d\xf1\x5e\x5b\x61\xce\x7e\x53\xa5\x91\x92\x04\x7a\x58\xb2\x05\x07\xce\x75\x5c\xfc\x50\xe0\xd8\x3d\x70\x7e\xcb\x72\x51\x34\x6f\x55\x79\xce\xea\xd9\x37\x4b\x88\x25\x3e\xb4\x24\xdb\xd7\x20\xe7\x4f\xa6\x76\x1a\x88\xc4\x36\x65\x64\x2a\xcb\x46\x5b\x3b\x4d\x29\xf1\xb2\x4d\xb6\x7a\xde\x45\xb1\x9e\xa6\xa6\x1f\x14\x92\x54\x7b\x99\xc4\xeb\xe0\x98\xd0\x54\x08\x84\xe7\x78\x60\xe2\x1d\x20\x4b\x8e\x2f\xc9\xad\xb4\x86\xaf\x21\x91\x84\xa6\x46\x11\x35\x2d\x63\xb9\x23\x82\x1b\x5c\x7d\x37\x20\xac\x17\xd6\xb7\x53\x4d\xe0\xcd\x84\x0a\x93\x80\xf2\x20\x21\xb4\xa6\x03\x29\x15\xa1\x52\x84\x81\xb2\x38\xd8\x4d\xa1\x47\xf5\x4f\x42\x15\xa3\x48\xa6\xf0\x09\xa9\xd8\xf4\x46\x55\x12\x8d\xc4\x93\xac\x56\xea\xbc\xce\x3b\xf9\x66\x4a\x1a\x96\x38\x2c\xcd\x9d\xca\x66\xaf\x4e\x69\x6d\x5c\xbc\xbc\x17\x1f\xa0\x9d\x08\xaa\x3f\x6a\x62\x94\xb2\xc2\x7a\xd2\x73\xf7\x1b\x3d\xee\x8f\x50\x1d\x06\x5c\x4f\x8c\xbc\x75\x26\xa6\x33\x5c\x47\x0a\x2f\xe1\x58\x70\x9c\x8e\xe2\xf4\x26\x80\x68\x04\x12\xac\x9e\x0f\xb3\xb3\x21\x8a\xb1\x6f\xf9\xb1\x7b\x9d\x22\xbb\x82\xe7\x7f\x99\x2b\x26\x14\x74\xa8\x2c\xb2\xef\x5c\x56\x0b\xda\xe5\x7d\x85\x90\x50\x13\x86\xca\x25\xd6\x48\xb0\xd2\xb3\xed\x92\x1a\x6d\xe9\x1d\xcf\xe2\x72\x28\x7b\x04\xe3\xe2\xaf\xb2\x20\x24\x23\xcd\xff\xfb\xdd\xf3\xec\xc3\x4c\xbf\x28\x0b\x54\x6a\x41\xf6\x45\x53\xa1\xfa\x00\x7e\xd4\xa7\xf6\xe4\x70\xed\xd3\xd1\x34\x4c\x70\xa2\x5a\x22\xc4\x17\x91\xd5\xa0\xb7\x45\xdf\xde\x41\x18\x05\x8a\x95\x32\x2f\xe6\xb8\x17\xa6\x47\xec\xde\x55\xe5\xe9\xf3\x6d\x78\x78\x1b\x8c\x31\x8d\xd8\xdd\x87\xdf\x6f\xbe\x80\xe8\x13\xc6\x83\x88\xfb\xde\x9f\x12\xab\x19\x23\xd0\xa0\x1b\x13\x06\x52\xf3\x01\xef\x87\x0a\x5c\x98\x36\x42\x6f\xbe\x76\x7a\xc0\xde\x68\xb2\x48\x11\x69\xe1\x81\x96\xce\xb1\xdb\xf2\x76\x0e\xd9\x36\xf9\xed\xc8\x58\x62\xab\x1a\xbc\x44\xf2\xce\x60\xe5\x6c\x97\xeb\x45\x87\xa3\x3f\x4f\xd3\xa1\x41\xe8\xbf\x4a\xf9\x59\xab\xec\xf4\xb4\x34\x4c\xa2\xa8\xd7\xf7\xd8\x19\x0c\xc5\xfa\xbb\x4e\xa5\xc2\xc0\x14\x14\xbe\x06\xe8\xad\x17\x13\x61\x8c\xdd\xab\xc8\xcb\xe2\x93\x18\xeb\x31\x03\xd0\x64\x17\x67\x32\xa0\xdc\x4c\xc8\xcd\xb6\xc5\xf7\xfa\xba\x18\x34\xd9\x09\x99\x8c\x42\x21\xfa\x5e\xa5\xb5\xf8\x3f\x6d\x03\x53\x4d\x16\xc2\x34\x61\xca\x33\x5e\xdc\x4c\x77\x52\xa6\xc3\xd4\xf3\x78\x3b\x97\xbe\xec\x5d\xd5\xc9\xfc\xd3\x91\x42\x3c\xa0\x75\x32\x06\x2c\x9b\x3f\x9c\xd8\x5a\x8b\xa8\x9a\xcd\xcf\x73\xde\x57\x70\x09\xd3\x86\x63\xd6\xf0\x5c\xc1\x63\x56\x80\xbe\xeb\x51\x15\x84\x41\x6c\xd5\xf9\x7f\xf4\x14\x26\x4f\x65\x75\xf2\x10\x42\xc2\x20\x15\x4a\x78\x7a\xc0\xd9\xbc\xfd\x5c\xdc\x76\xd4\xcc\x45\x98\xe1\x1a\xab\xe0\x59\xbd\x6f\xc4\xbb\x15\xcf\xcc\xca\xfe\x0e\x4c\x18\x31\xcb\xee\xf4\x51\xdb\xc2\xf5\x70\x24\xc6\xa4\xe3\x43\x56\xbc\xbf\xc0\x07\x14\x7d\x54\xc6\x8c\x06\x35\xf2\x7d\xc0\x43\x49\xef\xca\xea\xd6\x67\x08\xfd\x1b\xe6\x81\xb2\x85\xfd\xf7\x8f\x66\x44\xbb\x41\x78\xa0\x03\xad\xfa\x94\x46\xd3\xd9\xf1\xf1\x34\xe7\xc4\x68\x86\x4a\x48\x99\x7a\xef\x62\xa7\xac\x02\xfd\x50\x7a\x13\xcd\x29\x0f\x99\xa5\x01\x15\x1f\xe0\x62\xab\xc5\x25\xde\xdf\x08\x15\x34\x14\xae\xa8\xb7\xca\x33\x05\x77\x65\x89\x1a\x98\xfe\xb8\x4c\xd0\xd4\x81\xce\x9a\x7b\x51\x69\x28\x7e\x81\x89\x22\x9c\x01\xd3\xce\x0d\x99\xd0\xf7\x5c\x0d\xb3\x7c\xc4\xaf\x02\x3b\xae\x06\x3f\x85\x33\x63\x19\x27\x9d\xdc\x53\x3d\xc2\xcf\x11\xce\xa3\x30\x10\xf3\x68\xe2\x50\x7e\xf2\x23\x3c\x89\x95\x63\x12\xdd\xb7\x67\xa8\x90\xd3\xad\x9a\x81\x36\x12\x3f\x18\x80\xda\xc5\xf6\x61\x23\x77\x87\x93\x9b\xf2\x4c\x11\x1e\x19\x66\x8d\x6a\x7d\xe7\x28\x21\xfb\x5b\x8f\xa5\x25\xc4\xd0\xd0\x45\x91\xcf\xae\x4b\x7a\xba\xbc\x78\xa2\xa9\x71\x7e\xce\x53\xa9\x61\xab\x97\x53\x56\x3c\x8d\xc2\x58\xfa\x1a\xc9\xa6\x79\x9b\x0b\xb1\x77\x43\x62\xa2\x6d\x9a\xa2\x6e\x61\xd6\xee\x31\xfb\x77\xc6\x4b\x43\x78\x0a\x22\x95\x3d\x40\x76\xff\x9e\x79\x26\x26\xc2\x45\x9c\x60\xd8\xfb\xfb\xe3\x57\x06\x9f\x0b\x99\x22\xd2\xa4\x8b\x9c\xeb\x31\x0e\x98\x70\x01\x01\xa2\x92\x5e\x95\xcf\x8c\x70\xc9\x2c\xa5\xaf\xf6\xbe\xf9\xec\x59\x64\xc8\xb0\xdc\xdd\xdd\xc8\xc8\x2d\xe4\xaa\xf3\xc9\x47\x04\x7e\xe3\x9e\xc3\xe5\x17\xa7\xa8\x10\x03\xb4\x1b\xf3\xd9\x3d\xe3\xc2\xf4\x37\x81\xda\x0a\xd8\xc0\xc2\x6d\x85\x92\xc6\xef\x8e\xf4\x83\x99\x44\xe6\x48\x27\xae\xfc\xab\x9e\x35\xc2\x21\x54\xa9\xec\x69\xa5\x7a\x01\x48\xff\x60\x10\x69\x0c\x35\x8e\x6d\x71\x16\xea\x7d\xab\xaf\x29\xeb\x09\x07\x29\x10\x94\x5d\x67\xa7\xe7\xb6\xf3\x47\x3f\x00\x31\xd5\x50\xdb\x46\xf6\xf1\xda\x30\x31\xc3\xf4\xfa\xb9\x0f\xf7\x36\xc3\x4a\x36\x29\x75\x5d\x4b\x97\x6e\x17\xdd\x7a\xb8\xd8\x00\x14\xeb\x9c\x6e\xdb\x95\x31\xdd\x2b\xb8\x91\x1a\xb9\xb9\x6d\x2f\xd4\xcd\x61\xbd\x20\x8e\x99\x90\x10\x99\x22\xdc\x96\x02\x05\x20\x71\x7f\x75\xb9\xb5\x04\xba\xee\x36\x42\x12\x29\x9c\xd4\xce\xb7\x3e\x6c\x9f\xeb\xf1\xc4\x09\xa9\xb2\xb4\x29\x48\x03\xb2\x87\xc6\x4a\xb6\x59\x75\xd1\xf1\xcb\x0d\x19\x51\x08\xd3\xec\x9c\xd4\x77\x6f\x85\x43\x1e\x1b\x8a\x3a\x9c\xbb\xa7\x6d\xff\x37\x19\xc6\xaa\xd7\xed\xaf\x57\xa6\x6f\x3a\x26\x21\xd7\x5c\x83\x27\xcb\xc0\x5a\xe1\xe2\x94\x0a\xc3\x80\x26\x31\x8a\x7c\x6f\xf6\xab\x87\xcd\x71\xfd\xb0\xdb\x6f\x9f\xee\x8f\x87\xed\xe3\xc6\x5f\x2b\x64\x71\x30\xe5\x0d\xef\xdc\x9b\x9d\xd9\x8f\xf1\xdd\xb3\x77\x16\xb1\x14\x7a\x76\xb1\x36\xe2\xfe\x5a\x91\x30\xd8\x9e\xb7\xca\xa1\x79\x83\xec\x4a\xa1\x6f\xea\x8f\x84\xb1\xe6\xc8\x31\x29\xb3\x42\xcf\x23\x00\x37\x24\x09\xe2\xc8\x95\xb3\xbf\x17\xd9\xff\xb6\xf0\x90\x15\xe3\x0e\x7b\x12\x26\x3c\xc6\xdf\x3c\x0a\xad\xd1\x72\xef\xcc\xa2\xbd\x1c\xee\x3e\xe1\x06\x1b\x8d\xd6\x6d\x93\xc1\x4d\x36\xee\x85\x23\x61\x12\x73\xc7\xdf\x8a\xaa\x17\x1a\x50\x7e\x79\xd4\x32\x35\xab\x41\x85\x29\x15\xc2\x4e\x8d\xba\x11\x45\xe3\xe8\xb8\xfd\xc1\x58\x07\x9e\x68\x67\xab\x66\x35\x89\xd9\x6d\x09\x9e\x78\xec\xd2\xc6\x39\x60\x0b\x4c\x66\x24\x94\x2a\xc6\xbc\x76\x17\x92\x3b\xa2\x8b\xe3\xb9\x2c\xf3\xa3\x18\xaf\xd3\x50\x31\x9b\x96\xb3\x1e\x18\x54\x7d\x7f\xb0\x77\xf8\x42\x4d\x0c\x84\xb8\x40\xba\x6b\xac\xdf\x44\x51\xc0\x35\xf8\x73\xfa\xe3\x5a\x69\x6c\xe6\xd0\x22\xcb\xbd\xc4\xf3\x10\x6d\x85\x1a\xac\xee\x9f\x13\xa4\x1b\xea\x2b\x53\x5c\xa4\x1b\x0d\xd2\x36\x97\xd7\xa2\x29\x61\xb6\x5f\x85\xa0\x22\xc4\xb4\xfd\xed\x40\xa6\x23\xfa\x31\x12\x9a\x98\x59\x71\xfe\xe3\x0f\x7c\x45\xd3\x94\x64\x14\xb0\x48\xc0\xd0\x76\x76\x12\x55\xb3\x3c\xbf\xa2\x40\x52\xde\x3d\xcf\xcd\xee\xe9\xfb\xfe\x78\xd8\x6e\x5e\x58\x7f\x11\x13\xc8\x70\x68\x0a\xfb\x57\x5b\x56\xbd\x4b\x1c\x11\x66\x25\x2d\x1e\xca\xd7\x67\xd1\xce\x80\x1b\x24\x22\x11\x93\xbd\x42\xf8\xbd\x38\x79\x80\xcb\x90\x27\x8c\x48\x6c\xd0\x3c\x55\xf0\x50\x0a\xfd\xef\xee\xb6\x96\x83\xb1\x88\xa4\x69\xd8\xd9\x8c\xdb\xd5\xce\x13\x02\x7d\xf9\x91\x22\xa2\x42\xb0\x38\x82\xac\x38\xca\x71\x1f\x35\x89\x88\xb6\xb0\x8f\xcd\x49\x64\xf9\x7e\x49\xa6\x62\x61\x4f\x88\x88\x09\xd0\x27\x86\x9f\xa0\xb6\xb7\xfe\x5a\x34\xb6\xd9\x3a\x9f\x80\xc5\xf9\x77\x0d\x28\x22\x11\xd5\x90\x2a\x5f\x87\xbc\x9c\x9b\x72\xf5\x21\x1a\x51\xcd\x47\x99\x08\x8b\xfd\x0f\xe5\xeb\x1d\x76\xa6\x0c\x78\x80\x6b\x88\xe0\xe7\x52\xea\x09\x89\x58\x94\x10\x18\x58\x37\xf6\xd9\x6b\x21\x3a\xd7\xe8\xaa\x21\xae\x5d\x22\x3b\x76\x17\xe1\x84\x99\xb1\x44\xc6\x73\x05\x96\xd9\xe9\x9b\xa8\xdf\xc6\x02\x00\xff\x34\x79\x3a\xda\xf4\x22\x4e\x8c\xb1\xb2\x63\x75\x56\x94\x48\x5b\x3b\xfd\x86\x3c\xb2\x79\xaa\xda\xf1\x4a\x20\xe4\x75\xf9\x69\x43\x66\x15\x9c\x6a\xc7\x77\x09\xbd\x42\xf0\xf4\x92\x61\x4a\x30\x33\xed\x43\x94\x4d\xf3\x36\x6f\x9b\x1d\xdf\x62\x4c\x2c\x29\x7d\x77\x59\x44\xc1\x3c\x64\xb2\x12\x57\x57\x8d\x23\x40\x8e\xad\xbb\xfb\xb2\x1a\x5b\xd2\x28\xd6\x29\x82\xac\x34\x78\x05\xad\x59\xea\x30\x4a\x24\xc7\xcf\x64\xbd\xe1\x3f\x1f\xbe\x72\x4b\x22\x91\xc4\xcc\xf4\x31\xef\x63\x59\x79\x41\x38\x67\xb8\xea\xbe\x69\x6b\xfa\x76\x64\x14\xc6\xdc\xc1\xdd\x47\x70\x2f\xcf\x0c\x37\x2c\x48\x69\x38\x36\xe5\x4d\x7c\xf4\x2b\x28\xcc\xb5\x6e\x6d\x7f\xba\x41\xe8\xcf\x7a\x7b\x37\xf2\x03\x23\xc5\x85\xb6\x08\x96\xba\x73\x81\xd6\x22\x57\xfd\xa1\x28\x52\x83\x70\xf3\x4b\x37\x07\x3e\x49\x95\x2e\xa7\x4e\x23\x15\x47\x98\xef\xbc\x2f\xcb\xbf\xe1\x9f\x49\x1e\x76\x27\x69\x14\x87\x72\xcd\xde\xab\x3c\x5f\x15\x7a\x2d\xf2\x25\x8e\x58\x12\x29\x11\x5b\xf0\x51\x5f\x08\xdf\xc3\x64\x3d\x4e\xef\x48\x13\x4b\x2c\xb7\xdf\xde\x3f\xae\x8e\x77\x87\x87\xe3\xfe\x79\xb3\xe9\x0d\x86\x66\x1a\xb3\xcc\x67\x97\x43\x58\x0d\xfa\x76\x78\x50\xb9\xad\xfe\x98\x15\xa6\x9c\x4d\x16\x2d\x05\x70\x0b\x4a\x84\xe6\x4d\xfc\x21\x7a\xc0\x20\x89\x80\x10\xe7\x2b\x35\x8f\xe2\xe7\x15\xfd\x01\x89\x80\x72\xaf\x3f\xd8\x9e\x1d\x06\xaf\xdf\x2d\x40\x33\xdc\xd3\xe0\x94\x35\x77\x30\xe9\x50\x9e\xde\x82\x61\x9c\xd9\x36\xc1\x9f\xd8\x3b\x67\x85\x75\x46\xad\xfc\xdd\x10\x83\x19\xc5\x93\xd0\xbf\x0f\xfb\x62\x64\x14\x20\x2d\x39\xf6\x40\x8e\x9c\xd7\xb9\x0d\xb9\xae\x0c\x46\xc6\x48\xf4\x2f\xbe\xdb\xbf\xdb\x15\xfe\xdb\x92\x21\x88\x03\xaa\xd8\xd0\xed\x76\xf4\x18\x79\x12\x07\x31\xc3\x95\xff\x78\xb9\xc9\x9a\xe1\xd6\xfd\x61\x12\xa8\xd8\x25\x01\x1e\x2f\xcf\x65\x9e\xa9\xac\xaf\xff\xc6\x84\x45\x08\x86\xb3\xbc\x21\x37\x97\x7f\x67\x23\xae\xa4\x7e\xf5\xc4\x24\xd4\x08\x3c\x3d\x6f\xf5\xb6\x81\xea\xd8\x9f\x9e\xa4\xda\xc1\x1d\x36\xa2\xca\x2f\xc8\xec\xf6\x35\x3d\x0e\x89\x29\x8f\x94\x3b\x09\xa3\x34\xed\xeb\x3f\xb3\x61\x49\xac\x2d\xf3\xf2\xee\x47\x71\x95\xb7\x8d\x59\x62\x61\x7c\x0f\xe5\xeb\xf7\xa2\x46\x1c\xe1\x6e\xdc\x1d\xe5\x87\xc9\x84\xb8\x5a\xf1\x53\x7b\x5a\x67\xcd\x02\x02\xc2\x0f\x05\x0b\x7f\x44\x54\x87\x12\xe7\xe3\x0f\xc8\xfc\x83\xf2\x98\x22\xcf\x0c\x22\xdb\x8e\xdb\xa7\xed\x61\x19\x0d\xe5\xf7\x97\x98\xcb\x08\x93\x14\x88\x19\x5d\xb7\xcd\x55\x26\x2a\x0e\x09\xf3\x3a\xd1\xab\x3c\x5f\x8b\x4a\xd7\x8f\xa5\x46\x35\x83\xe7\x2a\x3b\x89\xea\xf2\x47\x9f\x60\x8a\xc3\xc4\x60\x76\x48\x96\x6f\x3f\x7c\xca\x3e\x8e\x38\xc1\x9c\xd8\x7e\xbd\x5e\x7f\x65\x5d\xe3\x28\x16\xbe\x3a\x34\x48\x26\xcc\xe0\x44\x71\x4c\x6d\x86\x4e\x67\xb5\x90\xb9\x47\x53\xe0\x9c\x6e\xae\xc0\xa0\x24\x8e\x23\x89\x96\x46\x0a\xf5\xde\x9e\x8f\x76\x56\x7e\xf2\x66\xe3\xd8\x92\x3b\x1f\xc4\xfb\x24\x3a\x8c\x63\x63\xd0\x95\xeb\xc9\xb5\x96\xdc\xb8\x38\x49\x00\x71\x3b\x42\x6b\xaf\xec\xb8\x80\xfd\x24\x71\x22\x52\xee\x44\xb3\x8f\xb5\x42\xf6\x9a\xf9\x00\x89\x6d\xbb\xc7\x66\x94\x6f\xb6\x7d\x0c\xcf\xe2\x52\xdf\x01\x1c\xe5\x65\x99\x1d\x63\xd1\x22\xc6\xa9\xa2\x48\xfb\x31\x6a\x77\xfb\xb4\x84\x13\x0b\x1d\x61\xf5\xf7\xdf\xdf\x76\xfe\x0b\x0a\x63\xd0\x0b\x71\x18\x1d\x5f\xee\xb4\x58\x9d\xcb\xaf\x90\x3a\xee\x22\x92\x04\x5e\x43\xdd\x7e\x34\xfb\x8d\x9b\xcb\x93\xa8\x54\xf9\x02\xf5\x79\x24\x1a\xdf\x9f\xa3\x34\xed\xd3\x00\x8d\x78\xef\xf3\x45\xb1\x4c\x03\x9f\x0a\x5a\x8b\x06\x5e\xcb\xea\xb2\xed\x0f\x2a\x62\x55\x6c\x91\xad\x64\xbb\xde\x7d\x79\x8b\x89\x3f\x29\xe6\x1e\x81\xda\xe4\xf0\x00\xe2\xb5\x4f\x51\xc6\x2a\x49\x23\x07\x54\x7e\xe8\xa2\xf2\xd9\x17\xd3\x11\xc5\x59\x66\xe1\xad\xf7\xd0\x7c\xcb\x5e\xdf\xee\xb2\x8f\xfe\x7c\x48\x2c\x2b\xee\xfe\xb0\xfa\x7d\x73\xb4\x8e\x3e\x76\x25\xf6\x03\x52\xcd\x5c\x53\xa2\xf5\xaf\x67\x6f\x02\x94\x08\xec\x1e\x58\xd4\xd8\x0f\x75\x73\xf9\x8c\xc1\x8c\xc4\xa0\xa5\x76\x5e\xd3\x18\x7b\xef\x1f\xd4\x04\x81\x67\x9e\xc9\xe0\x03\x96\xb8\x73\x48\x6c\xa2\x04\x43\x83\x9b\x87\xd5\x6a\xbb\xde\x79\x11\x6b\x92\x04\xb1\x08\xe2\x71\xe2\x07\x9d\xed\x05\x6e\x68\x92\x04\x69\xac\x5c\x5a\x03\xe9\xf2\x3e\xed\x0d\x27\x08\xc9\x56\x83\x47\x70\x15\x10\x4c\xcc\x56\x42\x58\x3a\xe0\x74\x36\xb7\x9b\x7f\xcf\xae\x46\x64\x80\x98\x79\x65\xd1\x1b\xdb\xd3\x39\x77\xe4\xbe\xd3\xeb\x50\x42\x4c\x32\x95\x88\xaf\x9f\xda\x65\xae\xc2\x6e\x74\x8c\x60\x50\x84\x44\xd5\x36\xc8\xfe\x9a\xa6\x9e\x24\x94\x6b\xaf\xae\x78\x2b\x1a\x71\x24\xb3\x57\x44\x55\x84\x8c\xb3\x03\xdf\xea\x6f\x0b\xa6\x31\x61\x41\xe8\x84\xf6\x4f\x19\x92\x62\xfa\xaf\xc1\x59\xa2\x84\x27\x2e\xff\xfb\xef\x67\x51\x68\xf1\xaf\xb6\x6c\xc4\xce\xcc\x7e\x29\xe4\x01\x75\x0d\x2c\x9d\xbf\x75\xba\x2a\x9d\x7c\x6a\x12\x92\x50\x26\x30\xe8\x74\x3d\x83\x45\xd4\xbb\x83\x11\xb5\x79\xa3\x02\x7e\x1c\xde\x2a\x10\x7a\x5d\x9e\xc6\x3c\x32\xfd\xce\x33\x79\xa0\x84\xc7\xb6\x62\xef\xe4\x1b\xc7\xe9\x94\x24\x31\x31\x16\xe7\x9c\xc8\xb9\xff\x73\x1a\xca\x98\xf5\x25\xad\xea\xf2\x59\xcb\xa7\x1b\x2e\x48\x8a\xb1\xf3\x1d\xa0\x3e\x3b\xf1\x97\x11\x5c\x72\x57\x41\xd9\x8b\x1c\x1e\xb3\x49\x93\x38\x49\x84\x66\xa8\x90\x8a\x04\xf9\xb6\x2d\xee\x17\x1f\x59\x72\xab\xba\x65\xf5\xea\x10\xa3\x31\x2d\x19\x4c\x9f\x5d\x51\x4b\x73\xff\xed\xf9\x97\x74\x76\x24\x51\x51\x10\x19\xdb\x15\xf7\x0f\x25\x3f\xf0\xdf\x88\xcf\xee\x51\x73\x89\xe2\xc9\xe5\x8f\x4f\xf4\xd0\x49\x02\x89\x32\xc2\x03\x04\x5e\xcb\xef\x2f\x0f\x93\xbc\x61\x62\x62\x1d\xf4\x09\x85\xbe\x16\xea\xba\x4e\x1d\xc9\xcc\x7e\xa9\x37\x60\xfa\x33\x26\xa5\xc8\xde\x6c\x83\x28\x5f\xca\x43\x1a\x92\x4f\x1f\x6d\xba\x6c\x8d\x8e\x31\x4b\x2d\xc1\x94\x15\xdc\xb4\x3e\x05\x9a\x06\x3c\xc2\xf4\x55\x2e\xea\x81\x0a\xa8\x57\x58\xf6\x83\x94\x09\x1c\x0e\xe8\x45\x34\x70\xdc\x1c\xbe\x75\xce\xf3\xe4\x26\x53\x12\x0a\xe4\x82\xc2\xcc\xdb\x1e\xae\x52\x37\x4b\x5a\x51\x24\x25\x31\xc7\xf8\xeb\x8a\xd9\x8e\xa4\x44\x48\x24\xbf\xb0\x22\x3d\xeb\xb2\xf8\x80\xaa\xce\xca\xe2\x4a\xa8\x87\xa4\x44\xa6\x28\xb1\x7b\x3c\x5a\x0e\xdc\x42\xdb\x1c\x9c\x0b\x94\xeb\x47\xd1\xa8\xb7\xe3\xf1\xeb\x04\x4c\x4a\x34\x0b\x1c\x8d\x5c\xdd\x59\xde\xf7\x21\x14\x48\x29\xa3\x88\x26\x38\x75\xfe\xec\xf4\x34\xca\x19\x33\x83\x78\x87\x65\xc8\x77\x0d\x43\x5f\x7e\xd7\x94\x31\x1a\x4b\x57\x10\x23\x37\xa5\xf4\x3f\xc6\x12\x8e\xc5\xed\x3c\x2b\xde\xd1\xcc\x55\x4f\x23\x4a\x81\x61\x10\x3e\xf3\x19\xab\x08\x87\xb2\x4f\x9f\xba\xe3\x5c\xd8\x7c\x29\x3e\xfb\xb9\x2c\xbd\xcb\x99\x86\x81\x6d\x87\xb9\xc9\x9a\xba\x87\x89\xa4\x21\xa1\x6a\x22\xa5\xf3\x99\xa5\x73\xe3\x23\x92\x62\x0a\xee\x69\x73\x78\xf1\xd7\x88\x38\x41\x65\x83\xfb\xb6\x6e\xc4\x47\x89\x6c\x40\x7d\xfb\xcb\x3f\x02\x4e\xa4\x91\x4c\xbc\xb0\x14\x56\x28\x76\xd5\x7f\x43\x55\xce\x1e\x3d\x09\x14\x76\x24\xef\x77\x0f\xbb\x5e\x78\x9e\xa4\x09\xb1\x74\x4a\x18\x10\xdd\x55\xa2\x78\xcf\xfb\x38\x35\x4d\x40\x4b\x57\x67\x76\x28\x9d\xd9\x67\x4c\x09\xf5\x32\xcd\x63\x0e\x53\x7f\x94\x5a\x5d\x7e\xef\x60\x7e\xaf\x7d\xaa\x61\x54\x0f\x5c\xfe\xca\x42\x82\xc5\x9b\x65\x1f\x70\x57\x01\x7c\x9f\xd7\x92\x49\x3f\x52\x5b\x19\x8a\x4d\xdd\x64\xa7\x6e\xab\xdc\xae\x77\x63\x5f\xc1\x0d\xeb\xb6\xea\xee\xcb\x5a\x0d\x87\x6e\x9e\x65\x0b\xcd\x8d\xcb\x37\x23\x69\xe8\x14\x46\x6c\xc7\xc9\xec\x68\x1a\xe3\x7e\xe1\x1c\x9c\x41\xbe\x6a\xf9\x62\x2a\xb4\xc3\x7f\x0c\x68\xbe\x47\x51\x5c\xe6\x0d\x1f\xa9\x32\x1a\x6b\x77\x7f\xdd\x1d\x7e\x69\xbe\x53\x60\x69\xe0\xf4\x6d\x30\x93\xff\x99\xf3\x3d\x9b\x38\x00\x01\xd6\xd1\x31\x9f\x64\x84\x82\xad\x3e\x6e\x5e\xd6\x31\xf5\xbb\x58\x6a\x28\xc7\x2e\x33\x6b\x45\x87\x98\x72\x6e\xf8\x53\x43\xc3\xd0\x6a\xfb\x1c\xcf\xa2\xae\x55\xa9\xe1\xa8\xca\xaa\x1a\x79\xdb\x53\xf3\x9a\x9a\xd0\x8a\x6e\xcb\xb6\xea\x8c\xcf\x98\x9c\x9f\xa4\x26\x49\x69\xec\x69\x6a\x73\xa8\x9b\xb2\x80\x7a\x2c\x35\xf9\x05\x69\x23\x11\x41\xc0\xb0\x94\xf2\xd7\xee\xe9\x56\x0d\x19\x2a\x11\x30\x82\x58\x69\xe1\xb3\x74\xde\x29\x9d\x3c\x8b\x08\x12\x8e\x40\xc5\x0a\x4e\x02\x1b\xdf\xef\x45\x6d\x4b\x6b\xcf\x83\x49\x10\x41\x2a\x6d\x62\x1e\xaa\x57\x78\x04\x2d\xae\xa8\xe7\xdd\x40\xc2\x12\xb4\x4c\xc8\x15\xa5\xff\x28\x87\x0e\x78\x7f\x29\x62\x04\x42\x27\xb3\x06\x4e\xb6\x43\xaa\x3f\x44\xa9\x44\x4c\x95\x97\x1d\x71\x2c\x65\xbf\xf2\x08\xbb\xf3\x00\x86\x39\xfb\xdc\x73\xd9\x11\x41\x59\x82\x1e\x0b\x22\x28\xff\x14\x1f\x4e\xf6\xc5\x1f\x0d\xa3\xc4\x01\x75\xfe\xbd\xd0\x57\x22\x68\x62\x11\x2f\x4e\x09\xfe\x06\x86\xeb\x26\x56\x57\x26\xab\x91\xe6\xaa\x0f\xa2\x04\x63\x02\x9d\x0b\xfc\xfe\x87\x12\xd5\xf3\x26\x73\x41\x30\x69\x7b\x4c\x1c\x29\x81\x18\x6e\x87\x47\x11\x56\x1f\xaa\x32\xcf\xcb\x0f\xa8\x3c\x26\xcd\x1f\x16\x06\x4b\x9a\xb6\x38\xb4\x6c\x84\xdd\xd0\xb0\xb3\x14\xdd\xa4\x10\x27\xd1\x0c\x76\x76\x20\x01\x20\x22\x84\x04\xbb\xaf\xb7\xeb\x9d\x07\x9a\xcf\xba\x6f\x44\x14\xa8\x40\x8f\xc5\xf8\x67\x05\x00\x11\x33\xa1\xc3\x91\xf6\xe6\xfe\x72\x92\xe5\x2c\x92\x13\x71\x48\x61\x78\xde\xbd\x16\xb3\x92\x90\x88\x45\x88\x0b\x7a\xa5\x9a\xec\xa3\xc7\x46\x0e\x30\x4b\x11\x0b\x85\x95\x92\xc7\xd5\xbf\x8f\xcf\x9b\x97\xf5\xe6\xe9\x70\xdc\xdd\x1d\xf7\xab\x07\x5f\xee\x14\x09\xc4\x89\x73\xda\xef\x45\x2e\x7e\x0e\x99\x2e\x91\x86\x21\x26\x09\x41\x67\x0d\x92\x23\x2d\x24\xee\x85\x08\x03\x74\x4e\x84\xd6\x76\xea\x7a\xd8\xf9\xd7\x33\x4f\x74\xae\xaf\x75\x7c\x8f\xcf\x2f\xdb\x75\x7f\x3f\x52\x26\xe8\xf1\xe6\x28\xf3\xba\x33\xbf\xc3\xe5\x93\xec\x93\x50\xa9\x95\x24\x75\xbe\xe8\xda\x2b\x9d\x7c\xbd\xbf\x0a\xa5\x74\x20\x7b\x6b\x65\xe7\x18\x59\xce\x49\x09\xad\x43\x54\xf6\x3a\x4f\x11\x6d\x42\x03\x43\xbf\x0d\x65\xb8\x97\xa2\x24\x01\x34\x90\x6e\xd3\xeb\x69\xb6\x90\x8a\xe2\x3a\x1b\x2b\x40\x44\x08\xdc\x17\xcd\x93\xd7\xc0\x25\x02\x80\x1b\xee\xf1\x25\x0d\xdc\x42\x8d\x55\x1b\xd0\x2f\x16\xf9\xe8\x86\x99\x20\x46\xea\xb3\x7d\x76\x1a\xfe\x96\xa4\xdc\xc5\x48\xcf\x33\xa1\x86\xe5\x59\x6f\x52\x07\xce\x68\x44\xd5\x78\xd7\xfe\x17\xa9\x94\xd9\x5b\x35\xca\x92\xe1\x69\xc7\xb5\x88\x54\xf2\x3a\x13\x9f\x40\xf6\x84\x31\x91\x87\xd6\x1e\x1d\x91\xec\x51\x54\x32\x6b\xea\x63\x5d\xe6\xb3\x66\x18\x19\xc4\x1c\x93\xbe\x6d\x0d\xd5\xb1\x2c\x8e\x06\xdb\x79\xdc\xf3\x4a\xa2\x22\x29\x7d\xe0\x59\x3c\xf4\xac\xe3\x37\x97\x1b\x8b\xfd\xd9\xea\x6d\x71\x2f\x4e\x32\x47\x6a\xd1\xaa\xb9\xca\x13\xb9\x0b\x51\x66\x4b\x3c\xdd\x6e\xe3\x89\x9a\xdb\x81\x98\x99\x48\xaa\x03\xf4\x2b\xeb\xb7\xf2\xc7\x84\x90\xb9\x3b\xd4\x33\x0a\xdf\x5c\x60\x3f\x21\x95\x19\xf2\xc2\x92\x11\x1b\x4f\xc2\xcf\x66\x2c\x2d\xd6\x1f\x55\xa0\x3c\xe6\xef\xa7\x03\x50\x1f\x0e\x7f\x5a\xc8\x8c\xa6\xd3\xbb\x61\x20\x08\xeb\xcd\xcc\xb9\x2c\x6a\xb0\x54\x65\xd3\xa7\x0a\x39\x4f\x6d\xe9\x0c\x2c\x05\xee\x40\x17\x43\x64\x94\xda\xbd\xdb\x00\x1c\xb1\x1e\xee\x0f\xc4\x54\x23\xb8\x0f\xe7\x84\x43\xa1\x0d\xfc\x7b\x7e\x10\x8b\x30\x1a\xb7\x6b\x69\xfd\x96\xe5\x57\xa8\x6c\x3f\x52\x45\x60\xc5\xd4\xcb\xf3\xb1\xef\xfe\x93\xb1\x21\x56\xc5\xc7\xa6\xf3\xf6\x67\x28\xf4\xe0\x1c\xb9\x41\x49\x1a\x78\xec\xd0\x98\x48\xd8\x77\xd3\xba\x51\x29\xb3\xe4\xb4\xab\xdb\xcd\x1f\x2b\x7f\xaa\x30\xcc\xf6\x61\x43\x31\x33\xfc\x4b\xc2\x56\xfd\x49\x21\x32\x08\x9f\xed\x36\x7a\xd3\x5e\x3c\x0a\x6f\x26\x6a\xb5\x3c\x8b\x84\x49\xb0\xed\x0d\x11\xe1\x7b\xc7\xc4\x37\x4b\xc6\x4b\x49\x68\x6c\xe5\x8b\x7a\xd0\x52\x99\x15\x4d\xbd\x2a\xb4\xc7\xf4\xfb\x91\xd4\xb2\x63\x9f\xc5\xe5\x0e\xae\xe8\xcf\xfc\xa0\x30\xb5\x4e\x78\x59\xea\xfa\xa9\x6c\x76\xbf\xcf\x26\x81\x8c\x19\x52\x27\x74\x56\x64\x55\xa9\xb7\x31\x4d\xd5\xd8\x70\x49\x99\x72\xa4\xb6\xbb\x7d\x5a\x6f\xfe\xf5\x7d\x7b\xf0\x8d\x93\x52\xb1\xc8\x71\xc1\x23\x1f\xdb\x3e\x2b\x5e\x73\x78\xfe\xbf\xa8\x6f\x4c\xa4\x0a\x03\x70\x6e\xc3\xcd\xf7\xd5\x27\x8f\xaa\x92\x18\x17\xe9\xcd\xaf\x33\x16\x52\x53\xae\x89\xd3\xc9\xa8\x9a\x43\x4f\xb6\x49\xa4\x8e\x22\x63\xf9\x36\x5e\x3b\x5f\xf8\x11\x26\x7d\x98\x7e\x90\x8a\x13\x3d\xcd\xc9\x8d\x92\x8b\x64\x8a\x2c\x93\x86\x28\x24\xda\x38\xbc\x75\xf3\xb7\xd0\x7f\xd4\x8f\x17\x51\x9c\x84\x0f\x1c\x55\xa0\x35\x02\xd2\x3f\xb2\x3c\x17\xaf\x90\x8d\xf6\x54\x37\x82\x30\x1e\x39\xbf\x0a\xf1\x1d\xb6\x4b\xf9\x56\x94\x8b\xe9\x7b\x45\x35\x47\xb1\x85\xce\x1c\x8e\x6b\xcd\x8a\xea\xc4\xb3\x9b\xae\x3b\xb3\x50\xd4\x6d\xfd\x82\x7c\x90\x6e\x00\x4b\x42\x69\xdb\xe5\x4c\x9f\x43\x1f\x31\xf5\x10\xc5\x83\xd0\x12\x6f\x3a\xcc\xb6\x95\x06\x59\x60\x88\x5e\xfc\x48\x8a\x27\x21\xb8\x68\xf3\x36\xab\x55\x76\xce\x27\x0d\x57\x7e\x14\x10\x04\xee\x21\xb3\xf9\x97\x29\x04\x15\x46\x1a\xa9\x6d\x34\x8d\x75\x2c\x85\xb7\x98\x2a\x4c\x55\x32\x6a\xe3\x69\xc0\x11\xc4\xae\xaf\x73\xc0\x2a\x94\xb6\x95\x4e\x68\xfd\x08\x87\xf2\x7e\x4e\x4a\x4e\x54\xc4\x13\x54\xc6\x91\xd0\xfc\x55\xb6\xfd\x7e\xaf\x22\x0e\x18\xc2\xee\xb3\x9f\x96\x83\xe0\xa5\x6c\x73\x68\x7a\x60\x93\x8a\x83\x04\x57\xcd\x3a\xcf\xc0\x83\x9e\xae\x40\x1a\x7e\x6c\x6a\xd0\xf9\xeb\x25\x01\xa0\x52\x6f\xa2\x68\xbe\x24\x19\x9f\x96\x09\x96\xdd\x15\x15\x0b\x40\xe6\x24\xcb\xc4\xb5\xf9\x80\xea\x72\xeb\x59\xc3\x88\x4a\x08\xc7\xa6\x9b\x06\xf1\x6c\x0f\xa2\xb6\x5c\x46\xfd\x61\x19\xda\x44\x76\xd9\xed\xa1\xea\xfd\xc5\xaa\xea\x4e\xef\x3d\xa5\x1c\x89\xc1\x5c\x84\xf1\x52\x96\xa7\xfe\x25\xa5\x71\x82\xc2\xb6\x98\x18\xce\xea\x06\x7b\x1d\xbc\x5e\xbf\x1b\x23\xba\x3d\xcb\x76\x03\x6e\xb2\x6e\xbe\xad\x9a\xb9\xe0\xe1\xf2\xa3\xc9\x38\x55\x8b\x14\xc4\xd3\x0f\x28\x41\x98\x60\x02\x7a\xff\x9c\x4e\xcb\x9d\xa2\x78\xaa\x75\x0f\x2c\x7c\x28\xfb\x66\x2f\xa5\x64\x84\x45\x38\x6c\xbc\xac\xd5\x98\x41\x7a\x7a\x09\x4d\x1d\xef\x52\x9f\x4a\xbb\x03\x27\xe8\x35\x2e\x7a\xf4\x0f\xa3\x59\x80\xd8\xe8\xaa\x6c\x0b\x7d\x54\x47\xec\x7b\x3c\x8e\x80\x72\x4a\xf3\x10\xe7\x13\x32\xfb\x35\xe3\xa5\xad\x43\x40\x17\xc1\xa2\xf5\x3d\xd5\x0b\x51\x3a\x21\x13\xa1\x89\x71\xbc\xa6\x74\x12\x53\x8b\x85\x17\x79\x3d\x0d\xab\x94\x16\x0c\xd1\xf0\x8f\xdb\xa7\xc3\xf6\xe9\x1e\xb9\xe0\x7a\x2a\x38\xa2\x34\x10\xc4\x28\xdc\xef\x76\xb7\x47\x6c\xc6\xf0\x47\x20\xb6\xec\x06\x9d\x59\x3d\xc0\xcf\xfe\x4e\x40\x1a\xa4\x92\xfe\xb0\x09\xeb\x41\x30\x84\x28\xd0\x02\x77\xf2\xa7\x52\x8b\x5c\x8e\x3a\xa6\x94\x89\x8d\x0b\x76\xac\xbd\x41\x90\xda\xf6\x76\x46\x21\xe2\x79\x00\xcb\x32\x1f\x39\x55\x3a\x20\x80\x98\xde\xb3\xd3\x17\x25\x9a\x50\x15\x5a\x42\x13\xdc\xb8\x67\xf1\x97\x26\xcc\x36\xcb\x3b\xcf\xf3\x8a\xf8\x40\x93\xc8\x6a\xbc\x1d\xb3\xfa\x36\x13\xa7\xb2\xd0\x56\xd0\x07\xf4\x24\x0f\xad\xa9\x4a\xb0\x9d\x76\x8f\x4a\x39\x73\x76\x10\xa2\xa9\xd1\xa9\xf2\xb5\xb4\x56\x41\xb3\x54\x9c\xd2\x2c\x32\x88\x58\xfa\x7d\xf3\xc7\xf6\x69\x44\x05\x43\x34\x4b\x04\xc2\xf0\xed\x62\x3c\x9e\xac\xc2\xdd\xa2\x5d\xd1\x2c\x31\x88\xc5\xdf\xbf\x01\x34\x8f\x6d\x9d\xa9\xdf\x66\x03\x14\x67\xe1\xa4\xbd\x66\x46\x10\x4c\x34\x67\x1c\xa6\x94\xa3\xdb\x6e\x2e\x2c\x21\x85\x35\xe7\x96\xdf\xae\xb2\xf4\x36\xc7\x7c\xbc\xd2\x35\x0f\x05\x52\xe8\x65\xf5\x73\x05\xdb\xf5\xce\x32\x32\xac\x47\x22\x95\x44\x87\x10\x87\x16\x79\x8a\x6a\xe9\xdd\x46\xf4\xa7\xef\x47\xfe\x14\x5f\x74\x8d\x39\xd5\x51\xca\x24\xf8\x1a\x5c\x67\xf1\xc6\xfb\xb2\x8e\x94\x6d\xf3\x79\x13\x55\x37\x25\x51\x98\x33\xfb\xf0\xab\x5c\xc7\x71\x82\xc9\x83\x02\x7e\x3c\x96\x75\x17\xad\x65\x23\xc0\x86\x4e\x29\x68\x5b\x4f\x3d\xf7\x7f\x8a\xac\xb6\x66\x9d\xbd\xde\xe2\x1c\xc7\xa9\xd3\x6b\x28\xf4\xa3\x08\x02\x74\x20\xcf\x5e\x33\x79\x9d\xa7\xf5\xc3\xe2\x20\x74\xd5\x56\x6c\x22\xd9\xcd\xd3\xe0\x3a\x55\x21\x5e\xe8\x4d\x14\x3a\x07\x0f\xf9\x5e\x2c\x95\x6a\x61\x20\x80\x71\x45\xf4\xb6\x5d\xa0\x4b\x26\xda\xcb\xfb\x56\xa0\x01\x4e\x8e\x90\xfb\x33\x6a\xbf\x79\xd3\x81\x56\x51\x84\xb1\xa9\xad\xbe\x88\xe2\x7d\x16\x33\xfa\x61\x22\x08\xdd\xe4\xf7\x90\x37\xb1\xa8\x4d\x3e\x5a\xca\x3a\x0e\x50\xcb\xed\x3d\x53\xef\xa5\x31\x16\x65\x3a\xcd\xe7\x68\x20\x01\xd0\x51\x93\x4e\xd1\xac\xe6\x2b\x0a\x74\x88\xe4\x52\xc8\x33\xe3\x1a\xe7\xf1\xb7\x9f\x50\x79\xd9\x5f\xc9\xf0\x08\xf3\x54\x58\xd4\x77\x9d\x77\xaa\xec\x8f\x26\x29\x16\x59\x7d\x16\xf6\xd1\x3d\xa1\x0f\xc0\xa0\xdb\x22\x84\xd3\x54\xb4\xfd\x47\x53\xc4\x0a\x50\x30\xcc\x2e\x5f\x2b\x46\xb8\x39\x7c\xfb\x3a\x31\x02\x21\x4d\x95\x1e\x4d\x87\xbb\x0a\xc0\xcf\xe8\xd1\xa8\x30\x15\x76\xc2\x77\xee\xc6\xe7\x39\x12\x88\x52\x40\x9f\xd4\xb1\xa9\x3e\x42\x23\xae\xbb\xe4\x21\x52\x91\xa3\xfb\x6c\xba\xc8\x57\xfc\xec\x42\xd3\xd9\x4f\x46\x10\x24\x2e\xd8\x7c\xc8\x0c\x34\x43\x0c\x09\x71\xa8\x11\x77\xd4\x40\xdd\xd8\x65\x3e\xd4\xc1\x20\x8e\x6c\x1d\xca\x64\x85\xbe\xcb\x5e\xdb\xea\x33\x34\x11\xc4\x71\xe2\x61\x57\xeb\xb7\xb2\x1c\x78\x81\x20\x16\x29\xee\x28\xef\x59\x9e\x8f\xe3\x72\x32\x41\x4d\x40\x0c\x14\x27\x7f\x5b\xcf\xc3\x2d\x88\x1d\x73\x5d\x77\x8b\xc7\xe8\x28\x90\x6b\xe1\x05\x3a\xbb\x86\x33\xf7\x68\x93\x6c\x56\x41\xf4\x68\xb1\x13\x87\xb7\xaa\x4f\xc7\x40\xc2\xd2\x14\x1d\x97\xf2\xc7\x63\xab\xde\xb6\x85\x6b\xed\xf5\x87\x53\x5b\x70\x1a\xfc\x8e\x99\xa4\x00\x81\x44\x10\x84\xb8\x16\xf0\xc3\xb6\x43\xdc\x5c\xa6\x9d\x1f\x90\x0a\x89\x7b\xa0\x0b\x86\x37\x28\x06\x79\xf3\x49\xb2\x02\x04\xe7\x41\xdf\xaa\xa6\x01\x49\x9b\xa6\x0f\x2d\x22\xab\xaf\xfa\x0a\xcd\xe6\x23\xcb\x1f\xcb\xaa\xb9\x4c\x91\xe1\x20\x14\xc5\x0c\x30\xae\x64\xeb\xbc\x5a\x60\xf9\xec\x4a\x26\xc5\x1e\x18\x8c\x68\xc7\x9d\x1e\x20\x99\x15\x50\xaf\x5d\x59\x69\xdf\xc0\x79\x06\x2c\x00\xa9\x13\xdf\x9e\xe1\xfa\x48\x50\x38\xe5\x4b\x85\x86\xee\x2c\x00\xdf\xd4\x86\x9f\xc2\x4a\xb6\x74\x9b\xc4\x53\x59\x28\x78\x01\x4c\x86\xf6\x8b\x19\x74\x62\xe9\x07\xce\x59\xf1\x7a\xc8\x4e\x9d\xa9\x3f\x9d\xfb\x83\xc2\xc2\x25\x6b\xa8\x3e\x32\x05\x23\xf6\xac\xd9\x6b\xd5\x8a\xe1\x6b\xed\xd5\xf7\x57\x0e\x06\x32\x33\x8e\xd7\x15\x05\x30\x44\x92\x3e\x65\xd2\xbd\xc6\x4a\xa0\x08\xa6\xbf\x07\x93\x32\x5c\xb5\xb9\xa8\x9b\xbb\x16\x72\xdb\x31\x99\x15\xaf\x3d\x84\x1c\x8c\x0a\xc8\x18\x93\xfc\xad\x6c\x6b\x58\xa0\x80\x32\x81\xe2\x58\x36\x7d\xcc\xde\x11\x78\x36\xc2\xd8\x1a\x22\x38\xf2\x69\xae\x5f\x76\x7f\xde\x4e\xe9\x8f\x0c\x11\x42\xc7\x5e\x55\xa6\x50\x90\xbb\xc7\xbb\x72\x5d\x0c\xd1\x31\x5a\x6f\x3b\x19\xbb\x10\x0d\x31\xf2\x73\x3f\xdd\x8f\x76\xdc\xd2\xfe\xc6\xf7\xa5\x69\x7e\x88\x0a\x5c\xc3\xab\xfb\xee\x23\x92\x1c\x43\x8c\xc0\xf4\xed\xcb\xef\xeb\x95\xb2\x4d\x90\x5f\xdb\x46\x43\x05\xc3\x6a\xd7\x3d\x34\xb7\x28\x15\xaf\xde\x17\x28\x81\x0c\xd5\x9c\xab\x9e\xd8\xbf\xda\xea\x55\x33\xa9\xe5\x79\x8d\xc0\xb1\x93\xd0\x9d\x04\x03\xff\xa6\xeb\x60\xa6\xc7\x1f\x59\x9e\x4f\x3c\x3e\xc3\x20\x49\x63\x4f\xd7\x88\xd9\x45\x34\xa8\xd3\x5b\xe0\xc6\xa6\x63\x9a\x4c\xbd\x43\x33\xe9\x3e\x35\x61\x6a\xec\x86\xff\x26\x2a\xd8\xdb\xe9\xb8\xc8\x35\x4f\x4c\x68\xec\x27\x78\x85\xc6\x7d\x26\xdd\x05\x89\x43\x8e\xde\x44\xa1\x95\xce\x58\x97\xa7\x33\x34\x99\xe5\xdd\x1a\x18\xc8\x4c\x24\x4d\xac\xfb\x56\xc6\x41\xa3\x76\xca\x02\x61\x22\x15\x63\x87\xc4\xd1\x75\x3d\xcd\x1e\x27\x4e\xad\x0e\xae\x95\x1b\x3d\x42\xa1\x8f\x23\xfb\x6f\x92\x88\x62\xf9\x69\xf3\xf3\x3e\xab\x72\x53\x65\x50\xe8\xf1\x7c\x4c\xa2\x10\x6b\x0c\xb7\xab\xc3\xe6\xb8\x7b\xde\x3c\x1d\x77\x4f\xc7\xbb\x87\xdd\xee\xa5\x1f\x21\x22\x0b\xff\x47\x87\x02\x2b\x22\xed\xf9\x8c\x10\xd5\xa9\x25\x32\x89\x8c\xa9\x6b\x34\x41\x4f\x68\xa9\xa9\x66\x7a\xf3\x29\x51\x7c\xdc\x6b\x3a\x9f\xc0\xff\x49\xdc\xfa\x35\x42\x86\x91\x93\xdc\xee\x05\xfc\xdd\x21\x49\x2c\x9a\xf4\x2c\xaa\x26\x53\xd9\x59\x2c\x68\x5a\xfa\xa1\x34\x74\x84\xf4\x3b\x83\xdd\x73\xf9\xc4\x1d\x35\x92\x25\x58\xb5\x81\xac\xf8\x5b\xbc\xe5\x7d\x64\x67\xa4\x0a\x30\x9e\x3a\xb5\x39\x8d\x3f\xbb\xb8\x09\x50\xac\xb5\x29\x9b\x89\x1d\x36\xd2\x18\xcf\x88\x8b\xec\xfe\x53\x3b\x6f\x14\xd7\x08\xe6\xcf\x8a\x2e\x80\xae\xa1\x0b\xf0\x5d\x28\xb2\x98\xc0\x31\x2a\x36\x16\x41\x6a\xcb\x39\x77\x55\xf9\x37\x14\x53\xa3\xed\x47\x82\xe5\x25\x94\x56\xdb\x7e\x56\xa4\x32\xca\x48\x24\x6c\xf0\x04\x50\x96\xf9\x65\x52\xda\x34\x3a\x62\xaa\xfb\xa8\xef\xa2\x10\x42\x4a\x65\x9b\x98\x46\x45\x59\xa3\xa5\xf5\x63\x0e\x3d\x11\x5d\x56\xd4\x5f\x71\x1f\xb8\xf3\x20\x8c\xd1\xb3\x39\x89\x9f\x1e\x23\x3e\x3d\xae\x15\x16\xda\xd7\xd8\x77\xf2\xa3\xfc\x75\xc3\x80\x01\xd0\x58\x75\x46\x3e\xdd\x3e\x1f\xed\x7c\x10\x63\x02\xbb\xcb\xbf\x6c\x9e\x77\xcf\xeb\xd1\x4a\x34\xdc\x96\x9d\x0e\x9b\xd5\xe3\x84\xcf\x99\x18\xa3\x8d\x90\xa3\x6a\xa0\xfd\x30\x88\x50\x74\x24\x4c\x63\x5b\x4b\x83\xc0\x05\x5e\x88\x94\xde\x43\xf3\xdf\x79\x39\x48\x2c\x8f\x3f\x0e\x0d\x02\x11\x62\xcd\xd4\x36\xa0\x4d\xd8\x3c\x26\x7b\xee\xa8\xa6\x47\x03\x62\x0c\xe1\x3d\xf3\xc0\x01\xaa\x4a\x64\xd7\xf5\xa0\xe9\x3d\xd1\xc0\xb2\x88\xff\xdd\x38\x5a\x46\x1a\x50\x16\x63\x91\xcc\xa5\xf6\x31\xbd\xf2\xbd\xc8\xac\xfa\xf5\x52\x96\x87\x06\x94\x0b\xfc\xe5\xe7\xaa\x3c\x65\x75\x5d\x56\x97\xcf\x3b\x04\x69\x40\xa3\x18\x27\x85\xce\x4e\x96\xd9\x6b\xde\x5a\x4d\x03\x1a\x4b\x4c\xa8\x66\x75\xaf\x45\xb3\x60\x69\x69\xc0\x20\x46\x4c\xcf\xff\x69\xeb\x66\x0f\x85\xbe\x2d\x8b\x71\x73\x20\x0d\x98\x09\x8d\x17\x62\x9c\x4e\x71\x1a\x70\xc6\x11\x45\xed\x2d\xcc\xf1\xb3\x40\x6a\x76\xff\x9c\xc7\x98\x0d\x39\x54\xd9\xe9\x5c\x7e\x91\xcd\xfe\x8c\x97\xca\x5f\x07\x94\xd6\x3d\x02\xe7\xb7\xf1\xa7\x8c\x62\xab\xf6\x7a\x16\x6d\x0d\x48\x44\x76\xe3\xef\x3a\x92\x22\x49\x5d\x71\x78\x7f\x58\xdd\x6f\x8e\xf4\xf8\xb0\x7d\xdc\x1e\xfc\x80\x38\x4a\x51\xe8\xed\x00\x62\x4c\xff\xff\x65\xa2\x96\x06\x71\x6c\x89\xc2\x6e\xb3\x8f\x1a\xb1\x53\x6d\xa1\xcf\x65\xff\xae\x62\x19\xe0\x86\xd4\xf9\x40\x1e\x6f\x37\x4a\x55\xd1\x20\x49\x29\xf1\x5a\xe9\x68\x06\xee\x66\x94\x68\x34\x48\xb4\x41\xd0\x70\xdd\x88\x41\x05\x74\xd1\x67\xa0\x41\xca\x42\x7c\x37\xdf\x6e\xb7\x0f\xa3\x14\x39\x0d\x52\x6e\x04\x9f\x24\x43\xae\x2b\x00\x34\x48\xa5\x65\x63\xea\xc2\xb0\xce\x1e\xd5\x94\xf7\x17\xd0\x04\xf5\x8f\xc5\xf1\x23\x83\x1f\x7b\xc8\x73\x44\xbe\xd4\xab\xc6\xb7\xa9\x3f\x0a\x55\x95\xa2\xa8\x2f\xd7\x85\x40\x1a\x88\xd0\x58\xcd\xaa\xb6\xd0\x53\x58\x20\x0d\x64\x6a\xb0\x11\xec\xbd\x50\xcf\x50\x6d\x0e\xdf\x06\xb5\x73\x1a\x48\x50\xa9\x1e\x50\x71\x18\x53\xba\x43\x2a\x08\x31\x78\xbe\x7b\xde\x3e\x21\x4e\xfa\xf3\xda\x08\x0d\x14\xb1\x51\xdb\xb9\xcc\xf3\x9b\xb6\x2a\xfe\xd5\x5c\x1e\x45\xbf\x78\x55\x98\x62\x4d\xf5\x1e\x9a\x6d\xfd\x2c\xda\x3e\x68\xa6\x81\x8a\x2d\xcf\x5c\x56\xff\x01\x85\x2e\xab\x9d\x59\x4c\x48\xd1\x40\x25\x04\xeb\x68\x33\xa9\x9c\xdb\xed\xd3\xae\xbf\x96\x11\x98\x92\x7f\x28\x5f\x3b\x0f\xd3\xa6\xb9\xf4\xec\x23\x68\x15\xf2\x19\x73\xe5\xb6\x40\x02\x82\x76\xa4\xce\x32\xfd\xee\x10\x68\x62\x7c\x30\xd9\xcd\xa3\xe2\x15\xaa\x99\x1d\x85\x10\xd0\x24\x7b\x9e\xb1\x17\x50\x17\xb5\x04\x20\xf8\xe4\x5f\x7f\x99\x38\xc5\x5e\x11\x55\x7b\x58\xe4\xc3\x40\x70\x4a\x03\x48\x99\x09\xb1\x9d\xaa\xf3\x9e\xfd\x1f\x95\xc6\x72\x5c\x56\xb6\x47\xdf\xfd\x35\x7f\x6c\x13\x52\x24\x1d\xb2\x68\x34\xe4\x36\xe9\xcd\x91\x49\x65\x32\x28\x6e\xdd\x60\x87\xfd\x8c\x17\x81\x92\x20\x90\x10\xf5\x75\xf1\xc2\x26\x8d\xca\x76\xa2\x4c\xf9\xad\x17\x0e\xee\xc6\x03\xe2\x2d\xf5\x92\xa8\x0f\x25\x01\x8f\x7d\xee\xdf\x64\x0d\x09\x82\xa0\x3f\x62\x08\xd6\x1d\xac\xb2\x26\x86\x15\x33\x65\x4d\x37\x90\xb2\x20\xf6\x65\xa7\xcd\xcf\xfe\x1d\x11\xca\x6c\x73\xc5\xb9\xca\xfe\x06\xc4\x5b\x7a\x79\x45\x4a\x98\xcb\x19\x63\xaf\xda\x2a\xab\x6e\xab\xf2\xfc\x5b\xaf\xef\x7d\xf5\x39\x08\xef\xf6\x1d\x9b\xdb\xdd\xae\x77\xd3\x77\x4a\x78\x2c\xbd\x72\xca\x7d\x2b\x2a\x9d\x89\xa2\xc7\xcb\x50\xc2\x0d\x04\x0e\x21\xff\x08\x8d\xd0\xa2\x11\xbe\x9b\x72\x01\xe4\x41\x49\xc8\xed\xe3\xbc\x40\xd1\x0c\x05\x6b\x4a\x42\xc5\x10\xe0\x2c\xb3\x42\x41\xd1\x64\x1f\xb0\xa9\x2a\xe1\x59\x1c\x28\x89\xb8\x65\xe6\xb0\x69\x88\xa9\x59\xf5\x43\x40\x47\x6a\x2a\x1d\x4e\xfd\xe9\x31\xd3\x28\xd0\xf3\x3b\x14\xcd\xef\xe5\x44\x23\x90\x92\x24\x0d\x31\xbc\x90\xed\x65\x01\xb0\x43\x49\x02\x76\x31\xd9\xf8\x16\x3f\xff\x38\x95\x72\xed\xf1\x50\x92\x92\xd4\xf8\x32\x28\x86\x8d\xcf\x15\xd4\x90\xe7\xa3\xf4\x06\x25\x32\x8e\x71\xc1\x35\x48\x75\x7a\x53\x62\x60\x3b\xb2\x5b\x44\xa6\x89\x61\x3d\x59\xfc\x1b\x94\x15\x34\x99\x12\xb9\x4d\x09\xcf\x01\xe5\x8b\xab\x9a\x48\x00\x74\xd7\x5c\x69\xa1\x9e\x4d\x78\x95\x0a\x2c\x51\x63\x96\xa7\x71\xb9\x5e\x4f\x78\xea\x9d\x29\xbb\x25\xf9\xbb\xd2\x31\x0b\x23\xdf\x2a\x99\x15\x05\x34\x16\xc6\x34\x74\xc2\x52\x02\x94\xa7\x96\x44\xd2\xe1\x49\xfc\xc9\xc0\x79\x1a\x39\x4b\x68\xab\x03\xeb\x52\x5f\x55\xb2\xfc\xe0\x94\x44\x3e\x05\x75\x27\xb2\xdc\xa9\x6f\xe4\x50\xad\xdf\xba\x77\xf6\x58\x56\x70\x78\x13\x85\x8f\xf4\xfc\x8f\x98\xc4\x82\xa7\x85\xd6\xcf\xa3\xfd\xce\x1e\xa5\x01\x15\x88\x6d\x43\xe9\xc3\xb5\xd5\x92\xf3\xa4\xad\xb8\x7a\x47\x4c\xd9\xb4\x33\x46\x88\xfc\x76\x7d\xf3\xb6\x11\x45\x5b\x4a\x87\xe9\x75\x89\x50\x08\xc7\x73\x42\x1f\x76\x8e\x6e\x67\x26\x8a\x76\xe3\xa2\x81\xe9\xa8\x73\x8a\x3e\xe7\xe9\xea\x86\x47\x31\xef\xad\x56\x4f\x9a\x37\xf9\x88\x94\xa6\x91\xb6\xb4\x4e\x08\xe5\xf4\x7f\x15\x56\xf0\x34\x2b\xea\xb6\xea\x2c\xcc\x71\x3c\xeb\x29\x15\xc2\xcb\xc3\x37\x33\x54\xad\x43\xa1\x46\x7c\xbc\x0c\x28\x95\xb1\xef\x23\xb9\x59\xe2\xbd\xa2\x94\x91\x04\x3b\x38\x5f\xca\x1a\x38\xeb\xff\xca\x64\x2c\xfa\x54\xe9\xb7\xb2\x6e\xd6\x6d\x33\x7b\x02\x2e\x63\x94\x03\x47\xb0\xcd\xee\x77\x7f\x2a\x57\x02\x43\x2a\x24\xa3\xbc\xfd\x3e\x8e\xdf\x28\x0d\x89\x6d\xb4\xbb\x7d\xd9\x3d\x6d\x86\x1e\x27\x4a\xe3\xc4\x66\xff\x8f\x9e\x39\x67\x0c\xe8\x9f\x6f\x54\xe3\x65\x4b\x91\x67\xd9\xc6\x7c\xd9\x2c\xa4\xa7\x34\x89\x62\xe4\x4c\x7f\xbc\xd8\xf5\x80\x0d\x8c\x73\x48\xb9\x1f\x9b\x40\xe2\xa0\x4d\x0e\xdd\xb7\xad\x9f\x4a\x17\x13\x2e\xf8\x36\x34\xa5\x51\xe2\x5e\xc0\xab\x63\x2c\xb5\x2d\x92\xfe\xa1\x52\x4e\xb1\x73\x12\x59\x27\x6f\x41\xe4\xbf\x79\x66\xfc\x2f\xd7\x3f\x15\xdc\x12\x59\xa0\x3e\x21\xea\x25\xfa\x46\x8f\xc5\xf0\x87\xca\x20\x41\x1f\x07\x99\xe1\x1f\x45\x21\x5e\x11\x1c\x3a\x23\xc8\x99\xbe\x36\x19\x48\xec\x22\x6f\x3a\xb7\x37\x3b\x61\xa8\x4c\xfc\x8d\x4b\x12\x23\xad\xd9\xf1\x15\x9a\xcd\x39\x53\xcf\x79\x5b\xbf\x88\x2a\x73\x90\x32\xbf\xd8\xa9\xd4\x01\xba\x9d\x37\xbb\xc3\x71\xf3\xb0\x79\xdc\x3c\x1d\x8e\xfd\x1c\x52\x71\x84\x45\xc3\x91\x06\x4f\x0e\xd5\xde\xea\x51\x60\xbf\xb5\x1f\x28\x45\xe4\x5e\xfc\x77\x9c\xc2\xe3\xf2\x03\xa5\x9a\x5b\x22\xfe\x6e\x0e\x77\xdb\x8b\xf7\x0e\xa8\x4e\x25\xd6\x13\xcb\x22\xb7\x54\xc1\xf7\xdd\x2c\xef\xe2\x6e\xc7\xa0\xe2\xc7\x09\x83\xc2\x0e\x4d\x76\x02\xd7\xea\xe7\x8e\x00\x09\xd1\x2f\xb3\xe2\xea\x2f\x5d\x2c\x44\xfb\x63\x61\x8c\x69\x38\xc7\x63\xee\x38\xd4\xa7\x1f\x0a\x80\x46\x96\x46\xb8\x78\x2c\x3f\xa0\x19\xaf\x55\xc3\x08\x66\x93\x56\x39\xfc\x1c\xd2\x44\x94\x9a\x18\xa4\xf3\xc8\xef\x00\x5e\x40\xc1\x0c\x4b\x6a\xc7\x31\x42\x18\x76\x32\x34\x6f\x15\xd4\x6f\x65\xae\xeb\x9b\x8b\x25\x9b\x9f\xdc\x03\x23\x34\x42\x9c\x85\x33\x61\x5f\x44\x92\x8c\x00\x20\x44\xae\x8b\x4a\xba\x6f\x7e\x0f\x85\x77\x6e\x18\x25\x6c\x04\xc3\xdd\xfc\x54\x79\x5b\x67\x1f\xd7\x8d\x0e\x94\xd1\x24\x96\x36\x8b\xd5\xd9\xf3\x7f\xb5\xa2\x6a\xa0\xca\x2f\x03\xc3\xd3\x3c\xec\x64\x14\x02\xe4\x85\xba\xc5\xf4\xdc\x12\x0c\xc6\x0d\x64\x41\x18\x84\xde\xd0\x7a\x82\x27\x8b\x18\xeb\x77\xf9\xc9\x13\xb1\xd8\x72\xbf\x5a\x53\x7b\x0b\x1a\xb3\x7e\x7a\x82\x31\xf1\x43\x8d\x54\x72\xac\x7c\x83\xfe\xdd\x6c\x10\x4f\xa4\xf0\xb4\x90\x59\xb1\xcf\xb3\xf3\x59\xbc\xc2\x42\x7f\x28\x65\x61\x10\x09\xe7\x7a\x63\x9f\x21\x4d\xfd\xab\x0c\x89\xe4\x7d\x0d\xa9\x00\x51\xbd\xb8\x74\xa3\x3f\x1e\x13\x7c\x4a\xe9\xfd\x64\x16\x31\x8e\x62\x08\x6f\xa2\x7e\x3b\x94\xf8\xc0\x53\x27\x9e\x45\xb1\x65\xa0\x73\x89\xdb\x71\x3e\x78\xf6\x91\x63\x21\x11\x2a\xb4\xad\xf7\x00\xfa\x71\x52\x4a\xf7\x43\xa4\x83\xeb\x67\xc5\xd1\x4a\xbf\x1c\x9b\xf2\xd8\xf9\x3a\xfe\x86\x12\xa2\x70\xcb\xff\x53\x0c\xfb\x2d\x76\x7c\x9f\xf3\xcc\xe7\x78\x29\x4b\x42\x1a\x18\x8f\xc0\xed\x86\x74\xeb\x53\xbd\xf5\x87\x65\x8a\x11\xd4\x0d\x88\x66\x57\x59\x9c\x7f\xe7\x7d\x8c\x3b\xd6\xfc\x50\xa5\x12\xdf\x5d\xb3\x7d\xd9\x1f\x8e\xfb\xc3\xe6\xf9\xf8\xf8\xfd\xe1\xb0\x7d\x7e\xd8\x6e\x5e\xfc\x25\x53\xc2\x11\x7e\x7a\xea\xee\xa5\xce\x5e\x87\xa8\x90\xa5\x91\xd5\x50\xce\x0b\x8c\x4b\x40\xff\xd6\xf9\x7b\x34\x99\x4e\x98\x34\xb2\xb6\xc0\x27\xa1\xea\x6d\x61\x85\xb1\xfb\xcb\xc4\x96\xf5\xf2\x09\x9e\x3d\xa6\x88\xb2\x54\x12\xe8\xb3\xe1\xff\xdb\x42\x17\x9a\xe9\xd9\x7c\x48\x25\xc5\x80\xf5\x8c\x21\xcc\xf6\xb0\x3b\xbe\xa1\x3b\x76\xde\x16\x3d\x53\x04\x65\x42\x72\xab\xfa\x86\x1b\x2b\xe8\x43\x39\x7b\x13\x42\x31\xe7\xfb\x55\x99\xb9\x4c\x13\x48\xb3\xd5\x22\x63\x8e\x7e\xf9\x77\x0b\xee\x5b\xbd\xda\xc6\xb9\x4f\xd6\x96\x14\x81\x4c\x1c\xea\xf7\xae\xac\x4e\x6d\x2e\x7e\xeb\x0f\xb1\x84\x60\xef\x4b\xe7\x71\x5a\x49\xaa\x2f\x83\x41\x26\x15\xe0\x14\xff\x5b\xd4\x3f\xbb\xff\xf9\x2b\xa9\x84\x22\x7e\xe9\xee\x65\xb3\xf9\xef\x8d\xd3\x83\xf5\x07\x81\x24\xd8\x92\x6d\xfd\x31\x5b\x86\xf3\x9d\xe4\x9f\x58\x2c\x08\x23\xb4\x1c\xca\xee\x1f\x13\xbb\xce\x20\x02\xcc\xdc\x7c\x38\x08\xd4\x12\x53\x35\x65\xa0\xf5\xc0\xf3\x7d\x3a\x97\x05\x14\xcd\x76\x99\x90\x80\x32\x13\xc6\x6a\x5c\xdf\xb9\xab\xca\xd3\xca\x43\xce\x29\x0f\x88\xc1\xfd\xa2\x19\xb8\x3c\xf6\x28\xb8\x3a\xf2\xa3\x79\x40\x63\x7c\x37\xae\xdb\xb2\x2a\x4f\x25\x36\xdc\xff\xb6\x98\xec\xf2\x27\x09\xc0\x4e\x01\xe5\xa3\xf8\x17\x38\x8b\x4a\x9c\xa0\x81\x1e\x4f\x30\xb1\x08\x9c\x52\x82\x39\x3f\x27\x5c\xbb\x33\x58\x44\xdb\xe8\xde\xb5\xe3\x34\xd4\xb1\xb3\x2a\x4f\xe5\x4d\xd6\x6f\x9c\x9c\x26\x96\x14\xd2\x19\x93\x5e\x40\x39\x9f\x16\xe0\x29\x67\x81\xc2\xdc\xe6\xb1\x86\x42\x5b\x36\xfe\xb7\xec\xfc\x75\xf4\xc2\x19\x4b\x50\xdf\xc7\x58\xa1\xf1\x39\xea\x88\x72\x26\x02\x64\x5e\x71\xb0\xa4\x3b\x38\x09\x27\xed\x5f\x8f\x53\x0a\x9c\x19\x8d\xad\x4b\x42\xeb\xbe\xf1\xe9\x97\x78\xfd\xb1\x93\xc3\x39\x0d\xd0\xb9\xbd\xab\xa0\x56\xe5\xd8\x95\xe6\x5c\x26\x08\xca\x34\x19\xaa\x16\x9c\x3b\x9b\x7b\x73\x99\x32\xc7\x2e\xe7\xfe\x38\x07\x40\xd4\xd5\xaa\x33\xad\x90\xf7\xeb\x88\x87\x91\x65\xc6\x3a\x65\xc5\x98\x8b\x73\x52\xa4\xa0\x3c\x8c\x6d\x83\xba\x35\x14\x07\x21\xe7\x9e\x28\x8f\xb9\x24\x5e\x55\x1f\x53\xef\xee\xef\x09\x09\x53\x18\xa1\xc7\x7c\xcd\xf6\xd7\xbc\x56\x94\x27\x5c\xe0\x4b\xff\x18\xc9\x8e\x4e\x57\x0a\x4f\xb8\xc2\x44\xd1\x0d\x34\x75\x53\x81\x78\xdf\xae\x77\xfd\x4f\xa7\xb6\x6f\xdf\xa5\xfc\x2c\x39\xda\x5a\x9c\x67\x77\x9e\xa4\x0c\x63\xf6\xa3\x6c\x2f\x4f\xf8\xd1\x27\xfc\x4c\xc9\x6c\xaa\x24\x60\xcb\x5c\x5e\x89\xa6\x30\xd9\xeb\xf2\xca\xe4\x29\x89\x10\x04\x7c\xb6\xe2\x58\x13\x41\x23\xca\xd3\x30\xa2\xd1\xc0\x7b\x30\x13\x85\x58\x36\x62\x3c\x4d\x52\x35\x38\x0f\x3d\xdc\x63\x3a\x48\x84\x04\x61\x55\x2e\x43\x82\xc6\xd1\xe1\xe4\x3f\xe1\x43\xa2\x5c\x82\x75\xdd\x0e\x6f\xf0\x92\xa9\x37\xa8\x9b\x3f\x7b\xc6\x65\xca\x35\x91\xbe\x29\x68\xbb\xde\x61\xf4\x34\x30\xf6\x53\xae\xc3\xc8\x0b\xe5\xd9\xa0\xb6\xbd\x02\x61\x53\xae\x13\x8e\x4e\x9f\xb5\x31\xae\x67\xde\xcf\xb7\x3f\xb3\xe6\xed\x2e\x2f\x45\x33\x80\x75\x3e\xcd\xf5\xcd\xfe\xee\x53\x58\x5c\x4b\xcb\x96\xec\xbe\x37\x7a\x11\x93\xb5\xdf\x27\x5d\xca\x32\x9f\x2e\x3a\x08\x41\x9a\x89\x38\xdb\xe6\xf0\x6d\xb7\xbf\xee\x48\xf0\xe3\xb5\xd6\xe9\xd0\x00\xe6\x2b\xa2\x5f\x44\xd8\x1c\x40\xe1\x2e\x8a\xf2\x59\x65\xb1\x33\xae\x73\x64\xf6\xed\x4c\x60\x21\x9a\x4d\xd6\x34\x97\x4f\x56\xa3\xa1\xc6\x66\x50\x9d\x7a\x4f\x51\x37\x95\xe8\x1c\xce\xf5\xb5\x4f\x1e\x06\xb1\xc2\xce\xce\x17\xa1\x33\xbf\xe7\x85\x01\x88\xb8\x6f\x83\x33\x50\x55\x22\x1f\x7a\x23\x69\xd8\xdd\x83\x2d\x94\xda\xed\xf5\x04\x45\x83\xc1\x59\xf3\x2b\x2e\x0b\x1a\x92\x44\x21\xdc\x00\x7e\x42\xd5\x45\xb7\xcf\xed\x2f\xe6\x74\x48\x03\x40\x8b\xed\xd2\xe6\xe3\xda\xa1\x1f\x91\xc4\xa9\x83\xb2\xd8\xed\xf4\x1a\x9e\xf2\x65\xe9\x23\xa4\xc2\x82\x3d\x11\x4d\xe6\x13\x5a\xfe\x98\xa4\x48\xe1\x24\x50\x8d\x0b\xa1\x2c\x6d\x05\xc3\xce\xe1\x87\x01\xc3\x7b\xf0\xa5\xa4\xde\x48\x7c\x06\x0b\x77\x32\x6d\xf3\xb9\x16\xb2\x98\x23\x34\x4d\xb6\x97\xd5\x61\x3d\x36\xf0\x21\x13\xb6\x69\xb8\x57\xac\xfb\x6d\x22\x4b\xb7\xf0\xef\xf2\x1b\xe5\x5c\xe1\x04\xb9\x2f\xed\xeb\x9a\xfc\x48\x14\x25\xb1\x05\x83\x6b\x54\x68\x75\xbf\xe1\x25\xf0\xa8\x1f\x96\x08\xec\xef\x3d\x3b\xcc\xd3\xf1\x8c\x0d\x25\x96\x15\xb1\x0b\x0e\x17\xe3\xfa\x30\x8e\x34\xf6\x73\x3f\x88\xb6\xd0\x55\x79\x12\x57\x5f\xdf\x0f\x34\x11\xb1\x92\x56\x85\xaf\x36\x4d\x97\x42\x98\x28\x29\xf5\x54\xed\x64\xf0\x9d\xc3\x94\x24\x08\x0b\xd1\x90\xbf\x96\x5a\x4c\x6f\x66\xf6\xf9\x53\x6e\x90\x39\x36\x7b\x14\x79\xb6\xb0\x8d\x84\x69\x6a\x9b\x91\x70\x7e\xac\xcb\xf6\x5c\x16\xf5\xe0\x01\x87\xa9\x8a\x71\x4f\x76\x71\xf5\xf3\xd9\xe7\xa5\x43\x41\x69\xea\xd2\x1e\x1b\x54\xad\x9b\x5d\x58\x26\xd2\xf5\xad\x79\xe8\xab\x37\x57\xa1\xd4\x32\x76\x41\xb5\xad\xc0\x8a\xea\xe2\x12\x21\xb3\x8b\x28\x06\xb8\x0f\x62\x7e\xf6\x7e\x44\x8b\x30\xc2\xd8\x75\x8e\x53\x80\x98\xb2\x97\xec\xdc\x94\x37\xed\xcf\xc9\x47\x87\x80\x23\x0e\x5b\x9b\xba\xff\x93\x36\x9a\xf5\x4a\xbd\x75\xfd\x08\xea\xed\x9a\x21\x99\x86\x26\x74\x68\xa0\xce\x37\xba\xdd\x97\xb9\xcf\x7f\x86\x26\x0a\x91\x40\x69\xff\xc7\xc6\x97\x26\xa3\x20\xd5\x98\xe4\x36\x22\xcb\xe1\xaa\x58\x1b\x11\xa2\x0d\x8c\xa9\x1a\x97\x00\xcc\x34\x22\x32\x92\x73\x7e\x89\x87\x72\x10\xbb\xfa\x4f\xfa\x3f\xff\xa0\xed\x82\x46\x44\x71\xe5\x10\xf4\x9b\x97\xfd\xf1\xdb\xee\xe1\xb6\x0f\xcc\x22\xa2\x0c\x38\x5c\xfe\x07\xe4\x87\x72\x79\xa2\x46\x04\xac\x67\x63\xaa\xc9\x3a\x8a\x68\xca\x12\xde\xa3\x85\x50\xe6\xe8\x8b\x06\xe6\x6e\x7c\xc4\xa4\xef\x3b\x35\xe5\xf2\x83\x53\xa3\x62\x4b\xcf\xac\xab\xc5\xd8\x20\x62\x22\x65\x33\x36\xa2\x71\x23\x07\x8d\x18\xa4\xe8\xab\x1d\x11\x73\xbd\x2f\x55\x26\xf2\x27\x68\x7e\x94\xd5\xbb\x27\xd3\xfa\x92\x38\xe1\xb3\x77\xc9\x79\x84\xc4\x2f\x67\x51\xd5\x40\x7f\xc0\x54\xdd\x84\x46\x3c\x8c\x91\xe2\xc7\x36\x9e\x89\xd7\x6a\x16\x26\x46\x3c\xa1\xd4\x62\x95\x9a\x2a\x83\x0f\xf8\x73\x7d\xf0\x99\xab\x88\x1b\x9b\xe6\x91\xed\xe5\xb9\x2d\x66\x89\xe7\x28\xd4\x84\xf5\x20\x24\xc7\x19\xda\x2b\x19\xb6\xf5\x72\x0a\x27\x0a\x75\x88\x8d\x7c\x07\xe8\x5c\xc3\xce\x09\x5b\x15\xf5\x3c\x1f\x16\x85\x4e\x87\x0a\xd3\x69\xab\x42\x5f\xa3\x60\x68\x14\x1a\x89\xed\x9c\x25\x4e\xd9\x6e\xa7\x74\xde\xc5\xa4\x38\x1c\x45\x44\x5b\x81\xff\x73\x9e\x35\xb7\xab\xdd\x62\xc3\x25\x8d\xa2\x38\x15\x0e\x10\x74\xd7\x16\x7a\xff\x3c\xe9\x57\xa5\x51\x4c\x19\x66\x87\xef\xa1\x80\x0a\xc9\x6f\x64\x9e\xa9\xdf\x61\xa9\x9d\xb9\x1b\xcd\x51\x1a\xd1\x39\xc9\x2f\xce\xcf\xee\xab\x14\x51\x1c\xdb\xef\x86\xd3\xa1\x47\x0c\x7c\x36\x4b\x63\x91\x7a\xb3\x0a\x0d\x6c\x0b\x27\x8d\x37\x9d\x0a\x49\x62\x61\x28\xb2\x20\x34\x39\x9e\x6c\x92\xa5\x9f\x55\xff\x61\xff\xe3\xc7\x81\x41\xc8\xf4\x4b\x8b\x35\x4e\xb7\xf1\xd6\x93\xaa\xc6\xd7\x25\xdc\x28\xa5\x11\x06\xcc\xba\xdc\x97\x27\x68\xde\x86\x1a\x4f\x94\xa6\x0c\x41\x61\xeb\x4c\x09\x2d\x26\x6b\x33\x55\x96\xdc\xb2\x86\x72\xf6\xb9\x53\xcd\x10\x76\xd1\x73\xbe\x1c\xf8\x61\x36\x4f\x53\x6d\x52\x97\x75\x7b\x10\xf5\x10\xee\xfb\xc3\x00\x4c\x7b\x32\xae\x5f\x78\x43\x91\xe0\x89\x55\x8c\x80\x53\x86\x25\xbd\x71\xb2\x63\x79\x9d\x09\x9e\xaa\xc1\xb7\xec\xcc\x7d\x67\x2e\x30\xaa\xaf\xaa\x19\xde\x9c\x46\x8a\x04\xe8\x89\xc2\xcf\x37\xd1\xd6\x8d\x15\xe0\x9d\x8f\xa1\x1c\x53\xe3\xcf\xf7\xb7\x93\xb7\xa4\xa2\x14\xd3\x2b\x23\xe8\xdc\xb2\xcd\x51\x91\x89\x1d\x19\xa1\xd5\x1b\x5b\x36\x5e\x4a\x85\xae\x02\x63\x5d\xca\xa9\xbc\x38\x8d\x34\x63\xf8\x2d\x9b\xcc\x37\x41\x4d\xcf\xd7\xd2\xca\xfa\xee\x1f\xee\xfe\x1a\xa5\x9f\x23\x48\x35\xe6\x79\xb3\x22\x6b\x1c\xbb\x22\x3e\x87\x65\x56\xfd\x0c\xf5\x4b\x23\x30\x16\x62\x74\x16\x97\x89\x52\x46\x3f\xc0\x84\x96\x22\x0a\x0a\x3d\xad\x1f\x46\x26\x11\xc1\x20\xec\x6e\x69\xa7\x16\x1b\x9e\x96\xfe\xb1\xd7\x88\x03\x16\xa3\x2b\x74\x2a\xf5\x7a\xb3\x5b\x74\x97\x70\x0c\x72\xb2\xab\x12\xa3\xaa\xdf\xfc\xdf\x15\xf7\x55\x33\x7c\x53\xd7\x12\xe6\x34\x26\x54\x80\x1c\x71\xd4\xfe\x59\xe6\xef\x9e\x46\x67\xd9\xf4\xc4\x84\xc7\x0a\xfa\x54\x9e\xd3\x9f\x9a\xdc\x34\x91\xa0\xd5\x84\x1f\xc4\xf7\x09\x4e\x7f\x9c\x6a\xdb\x74\x90\xd5\x57\x78\xd0\x51\xbd\x29\x66\x84\xe2\xd4\xcb\xea\x9b\xd9\x93\x33\xc1\x31\xec\x16\x79\xee\x29\xab\x06\xb8\x8a\x1b\xc3\x39\xc3\x6c\xac\x23\x36\xc7\x36\xd8\x89\xc9\x8d\xc3\xd8\x60\x71\xae\xd7\xfc\x04\x71\xea\x5b\xef\x68\x1c\x05\x0a\x5b\xe5\xef\x4b\xab\x74\x5a\xf7\x07\x22\xbb\xa9\xd7\x7d\xdf\xd7\xa7\xd3\x28\x8e\x92\x18\x71\xe7\x3f\x20\x73\x49\x04\x6c\xc2\xf0\x47\xa5\x46\xfd\xdc\xe7\x97\xdd\xf3\x6e\xbf\xb9\x3d\xee\x0f\xab\xc3\xf7\x7d\x7f\x58\x29\xe3\xd8\x26\xbe\x41\x55\x4e\xba\xe4\x27\x2f\x3e\x26\x2a\xb1\x4c\xe0\x7b\xe1\xf5\x03\xbb\xbf\x1a\xc4\x23\x40\xa1\x9f\x73\xa1\xdc\x4c\x9c\x7e\x8a\x38\x0a\x11\xee\x54\x37\xd5\xba\x2c\x94\x68\x16\x21\x11\x71\xc2\x18\xae\xce\x1f\x55\xd6\x40\xdf\xdc\x79\x57\xce\xb0\x37\x71\x62\x14\xa2\xfb\x57\x59\xa5\xab\xf2\xec\x54\x4f\xdc\xc1\x34\x50\xf8\xb4\xfb\x4c\xc3\x4d\x95\xe9\xd7\x2f\xd0\xf7\xfe\x94\x58\xe2\xf5\x9e\x2b\x80\x1e\xd1\x12\xa7\xca\x4e\xfc\xba\x8b\x40\xd1\xc9\xab\x96\x57\x48\x0a\x22\x1c\x2a\xd3\x47\x89\xdb\xf3\xf1\xb4\xe4\x28\xc7\x02\x24\xc1\xda\x98\x53\x26\xe9\x62\xe8\x2f\xea\x0e\xb1\x54\xbd\xa2\xd6\x03\x98\xa6\xfc\xf0\x04\x57\x37\xed\x15\xfd\x2e\x8d\xa5\x91\x9e\x20\xf8\xc1\xa7\x07\x27\x6f\x58\x05\x1c\x83\x01\xf0\x55\x4c\xff\x77\x02\xdc\x6d\xf8\x78\x4b\x37\x97\x3f\xcf\xdb\x4f\x12\x31\xb1\x52\x1c\x9d\xea\x6e\x46\xdf\xda\xd6\x26\x98\x19\xfd\x58\x07\x09\x17\x5e\xfd\xae\xc9\x3e\xe0\xa6\xad\xb3\x02\xbb\x06\x9f\xa1\x5a\x8f\x3c\x3c\x7f\x42\x2c\xb1\x55\xf4\xae\xac\xdf\xc4\xec\xa5\x01\x57\x18\x74\x9e\x44\xd1\x8a\x3c\xbf\xec\x91\x5d\xd8\x51\x1d\xf4\x8c\x0f\x77\x65\x85\x24\x12\x9f\x88\x96\xcf\x1e\x02\x0c\x43\x5f\xf0\x88\xce\xe2\x63\xfd\x3a\xb4\x36\xf5\x23\xac\x67\x7e\x3a\x9a\xb6\xd0\xf5\x34\xc3\x11\x1b\xc2\x59\x6f\xfe\xa0\x86\xa2\x59\x7a\x0d\x86\x59\x22\xe3\x57\xe7\x28\x7d\xe5\xd8\xc4\x46\x59\x95\x92\xf5\x5b\xa6\xde\xa1\xb8\x13\xd5\xa9\xaf\x0a\xc5\xc6\xcd\xf9\xb7\xb2\x12\xfe\x26\x92\x80\x10\xee\xa8\x7a\xab\x41\xf0\x6c\xbc\x83\x26\x01\xb3\x5a\x4c\x9d\x2b\x97\x8b\xd7\xaf\x50\x7d\x49\xc0\x14\xa5\x4e\x1b\xd0\x72\xf6\xcd\x40\x32\x49\x20\x3d\x1d\xc8\x52\x05\x7f\xfa\x3c\x49\x67\xfd\xb1\x8e\xdd\xda\x29\x3e\x22\x03\xf7\x23\xb4\x60\x49\x4f\xb2\x7d\x73\xed\x78\xf8\x71\x06\xb0\xe4\xff\xaf\xb6\x73\x21\xcb\x62\xbb\x68\x3f\xba\xff\x43\x5c\x86\xaf\x3b\xc3\xfc\xf6\x29\xd8\xb6\xca\xfd\xe6\x79\xe5\x5f\x10\x8b\x98\x1c\xf7\x3e\xa3\x10\xdd\xb0\x6e\xaf\xad\x6d\xc2\xe2\x10\x46\x5a\xb9\xf6\x9b\xfe\x99\x35\x6f\xd7\x72\x0d\x34\x61\x89\xb2\x4a\x24\xad\xc4\x02\xa9\x43\x6e\x4c\x07\x71\x43\x91\x3d\xf5\x8c\xe1\x12\x5c\x31\xdd\xd1\x24\x8c\x05\xe6\x2f\x3d\xd3\xbc\xa5\x99\xef\x7e\xd4\x12\x2a\x5f\x67\x10\xbb\x17\x38\x81\xad\x24\xa1\xa6\x31\x0a\x10\xef\x56\x0f\xc7\x97\xcd\x6a\xfd\x6d\x73\x7b\x5c\xbf\x6c\x0f\x9b\x97\xed\xce\x63\x46\x92\x88\x52\x4f\xff\x70\xbb\x44\x15\x4e\x93\xd8\x41\x9a\xb0\x0d\xe8\xfc\x4b\x85\x73\x7f\x96\x52\xf8\x9e\xcb\x9e\x86\x71\x76\x5c\x47\xb8\xf1\xbb\x8a\xfb\x9c\xab\x71\x9c\x19\x75\x67\x24\x41\x64\xdb\x1d\x5b\x79\xca\x9a\x11\x13\x3c\xbe\x16\xaf\x53\x71\x4d\x99\x88\x21\xe4\x7f\xfe\xa7\xef\xe1\x18\xfd\x97\xbf\x32\x49\xd1\x2d\x3b\x7c\x5b\x3d\xfd\xbe\x3f\x6c\xf6\x07\x0f\xe2\x48\x12\xb0\xc8\xd7\x62\x68\xda\xad\x3a\xeb\xe3\x3d\x84\xe5\xfc\x4e\x92\x06\xa9\xcf\x14\xf5\x11\x8b\x3f\x44\x6d\xa6\x16\x5b\xda\x97\x2a\xcb\x89\x60\x0c\x35\x10\xb1\x9f\x33\x53\x30\xf2\x3c\x13\x01\xf6\x56\x95\x56\xfe\x4f\xca\xbd\x17\xf8\x79\x1e\x15\x6d\xe7\x55\xfe\x44\x89\x80\x39\x3f\xea\x20\xea\xf7\x87\xac\x6e\xf6\xbd\xd0\x29\x4d\x74\x64\xc9\x86\xf4\xa5\x38\xd6\xd9\x6b\xff\x67\x23\xb1\x96\x87\x6c\x4a\x42\xfd\xef\xcc\x83\x4e\x40\xc8\xc0\x46\x67\xa6\xf3\x7d\x5f\xa0\x2e\xf3\x8f\xde\x8c\x25\x86\xf4\xd9\xa6\x9d\xfc\x3f\x30\x23\x1f\xa7\x89\xe1\x01\xa2\xf0\xac\xac\x62\x69\xba\xa5\xf0\x9c\xf7\x35\xe3\xc4\x84\x06\x53\x93\x22\xab\xe8\xd7\x49\xdb\xc4\xc4\x56\xc8\xc0\x78\xde\x8d\xed\xed\xf2\x26\x9b\x98\x24\xc4\x4a\x2d\x9a\xbc\x39\x21\xec\x40\xe1\xfe\x28\xce\x53\x47\x24\x0d\x34\x41\x41\x33\x0f\x13\xf4\x2c\xa3\x79\x79\xc1\x02\xd4\xd4\xf5\xfe\x24\xa5\xe1\xaf\x65\x00\x37\x24\xe3\xf4\x34\x36\x3f\x3d\xb7\xbf\xaf\x4f\xa4\x84\x5a\x92\x0c\xe5\x72\x8d\x9e\x28\x9c\xa6\x84\x43\xe8\xa6\x97\x7d\xad\xe3\x46\x5d\x67\xc2\x12\x3f\xbd\x53\x12\xd9\xca\x34\xa0\x7a\xf3\xa7\xba\xe5\x63\xe3\x91\x92\x98\xd1\x79\x13\x10\xe8\xb9\xe6\xc9\xe2\xc6\x96\xb2\x38\x4e\x6d\x3b\xff\xee\xfc\xc9\x02\x49\x59\x2a\x69\xec\x93\x46\x88\xca\x1a\xe4\x72\x69\xca\x04\xc1\x70\xbe\x2d\xa4\x58\x4e\xeb\xa6\x5c\xc4\x16\x5c\x01\xb9\x11\x15\x7c\x13\x85\x2e\xdb\x5f\xc6\xf0\xb3\x3b\x0d\x19\xb7\xa2\xfe\xc7\x33\xd8\xee\xca\x11\x02\x32\x0d\x45\x2a\x85\x4f\xf2\xdc\xb6\x53\x09\x6b\x9a\x46\x9c\x0b\xcf\xa8\x83\xaf\xe5\x05\x32\x2c\x4e\xcc\xee\x34\xe2\x11\xde\xe9\x7f\xef\x6d\x0c\xf9\xc5\x96\x9c\xc6\x32\x45\xbe\x74\xaf\x3a\xf6\xb0\x79\xba\xef\x33\xcc\x69\xac\x2d\xe5\xcf\xcd\xe1\xe1\xb8\x3a\x7c\xdb\x3c\x6d\x57\xde\x8e\xa7\x89\x62\xc8\xd2\x93\x35\x70\xfa\xa3\x6c\xe0\xf6\x13\xfc\x52\x9a\xa8\x10\xe3\xa9\x5c\xd4\xcd\xf1\x47\x56\xf4\x62\x94\x34\x4d\x29\x93\xc6\xb3\xb2\x1c\xb1\xdb\x61\xd4\xe6\x30\xb2\xc5\x69\x1a\x59\x69\x5d\x38\x97\xea\x6d\x8c\xed\x4d\xd3\x48\xa7\x36\x51\x3a\xfa\x5b\x42\x90\xf3\x04\xb5\x63\x7e\xc5\xc4\x44\x53\xc1\xb8\x8a\x86\x88\x0f\x73\x93\x38\x37\x69\xe0\x47\xa4\xd4\x70\x27\x26\xa1\xc4\xd9\x61\x53\xe7\x10\xf2\x54\x6a\x2b\xa9\xe2\x74\x9c\x76\xe6\xe6\xf2\x00\xaf\x42\xcd\x50\x4d\xa9\x62\x9c\xf6\xcd\xb8\x53\x6e\x86\xee\x60\x82\xdd\x72\x2e\x79\x99\x0f\xed\xbd\x0b\xda\xa3\xa3\x57\xa4\x98\xb6\xed\xd2\x6e\x7f\x93\x3d\x1a\xe9\x3f\x89\xdb\x82\x66\x5f\x06\x52\x50\xd6\x96\x8a\xe6\x0d\xe1\x50\x1f\x24\xf2\xb7\x01\x52\x2b\x3d\x90\x50\x8d\x35\xdb\x67\x57\xd1\x0c\xdb\xfe\xb0\xe3\xeb\x30\x36\x71\xbf\x58\xb6\x60\x34\x42\x0d\x0f\x65\xf1\x26\xca\xd1\xa6\x93\x9a\x20\xc2\xbc\x96\x85\xd3\x1c\xeb\xf7\xe3\x7b\x51\xfe\xc8\x61\x14\x6c\xfd\x87\x0e\x8e\x13\x75\xef\x5f\x04\x89\xa5\xbf\xec\xe5\x10\xff\xf4\x9a\x1f\x54\x04\xa9\x42\x92\x7d\xcb\xc0\x84\xef\xe8\x5a\xa5\x7b\x3c\x2d\x04\xa1\x0c\x5d\x62\x54\x95\xcf\xb3\xba\xa7\x4e\x9a\xcd\xa5\xc9\x53\x09\xc2\x63\xe5\xf2\xd7\x7f\x95\xed\xba\xcc\x73\x50\xd7\xb4\xd8\xc3\x77\x13\x24\x61\x28\x69\xf0\xb8\xdb\x61\x63\xcc\x7a\xf7\x74\x78\x59\xad\x7d\x3d\x41\x10\x05\x3e\x50\xdf\x97\x6d\xa5\x60\xa1\x7c\x23\x58\x48\xd1\xf3\x34\x59\x85\xb2\xb0\xaf\x16\x6d\xe6\x6b\xac\xc5\xe8\x45\xb0\x30\xb6\x70\x18\x6c\x65\x2d\x73\x6d\x39\x50\xfa\xc3\x10\x62\x8c\xd7\x05\xf1\x9b\xe3\xfa\x61\xb5\x7d\x3c\x6e\x9e\x56\x37\x0f\x5e\x1a\x88\x0a\x66\x52\x04\xab\xfd\xb1\x43\x52\x1e\x8b\x17\x3a\xde\x7e\x47\xa5\x06\x6f\x20\x44\xd8\x79\x84\x8e\x98\x39\x2b\x6e\xfa\x34\x83\x3b\x1c\x05\x02\xe9\x2b\xdd\x1b\xca\x64\x0e\x68\x0c\x69\x3f\x80\xda\x94\x77\xe7\x73\x7d\x88\x66\x19\x70\x29\xa2\x48\x63\x6d\x06\x44\x95\x5f\xf6\xe7\xb2\xa8\x7b\xa0\xa8\x88\x95\x6d\x55\xc2\x99\xe9\x88\xfe\xfd\x66\x27\x92\x48\xf9\xc0\xe5\x45\x54\xf0\xfc\xb0\x3a\x6c\xe7\xa4\x67\x54\xa4\x41\x88\xa0\x74\xd3\x16\x6b\xeb\x8e\x63\x11\xe8\x70\x05\x39\x10\x32\x49\x51\x36\xb6\x1d\xa8\x95\xc6\x07\x45\xd2\x0b\x6d\x0c\x98\xe2\x59\x67\x2b\x15\x8a\xe8\x34\x1d\x84\x5b\x17\x32\xcf\x42\x09\xc1\x52\xdf\x3c\x94\xe5\xba\x82\x62\xf5\x2a\xb2\xa2\x6e\x56\x45\x76\x12\xf9\xbc\x9e\x2e\x74\x08\x58\xdd\xbd\x80\x2f\xcf\xfb\x03\x91\x61\x61\x1f\x1d\x7d\xbd\x58\x85\x06\x8e\xf0\x47\x53\x56\x0a\x2c\x05\x86\x65\x8a\xf8\x73\x6c\xd1\xbb\x61\x51\xdf\xd6\x63\x13\x52\x8b\x17\x1e\x72\xbe\xf3\x6c\x89\x00\x4a\xe9\xc0\x7b\xff\xdd\xd7\x2b\xdc\xbb\xf2\x00\x63\x61\x58\x48\x1d\x61\xda\x7d\x66\x16\xb9\xb5\xa9\x30\x9a\x62\xc5\x29\xab\x6d\x96\x60\xfa\x6a\x64\x10\x70\x8c\x7a\xd0\x27\xba\x6b\x0b\x7d\x45\x7b\x49\x65\x40\x29\x38\x39\xaa\x63\x7d\x06\x95\xcd\xa3\x3e\x19\x70\x8e\x88\xe6\x75\xd6\x5c\x1e\xc5\xa5\x9f\x7f\x32\x88\x28\x7a\x88\x36\x17\xe3\xf8\x14\xae\xa7\x8e\x0c\x92\xc8\xc9\x02\xeb\x9b\xf3\x32\x66\x56\x12\xa1\xb1\x25\xaf\xb1\x28\xd8\xc1\x91\x96\x44\x72\xec\x5d\xf1\xef\xfb\x50\xda\x5d\x74\xfa\x1b\x44\x46\xc8\xa4\xf5\x87\xef\x07\xac\xae\xfa\x7a\x24\x31\x32\x70\xfc\x2e\x36\x59\xf8\xe8\x00\x9b\x0b\xda\x96\x54\x52\x61\xf9\x67\xc7\xcd\x3c\x73\x7b\x3a\x3b\x03\x68\x18\x8f\x60\x9c\xd3\xaa\x8f\xa4\x26\xb5\xaa\x00\x9b\x3f\x36\x0f\xbb\xe7\xcd\x8b\x0f\x8a\x24\x4f\x29\xa2\x01\xb1\x25\x63\xd7\xe7\x06\x65\x18\x4b\xf4\x74\x1e\x77\x4f\xdf\x11\xc6\xfe\xfd\xe9\x78\xb7\xd9\xf4\x87\x93\x10\x57\xd3\x9f\x90\x5d\x31\x90\x50\x19\x25\xc6\x2a\x9f\xa3\x1b\xde\xb9\x30\x7a\xd4\x12\x24\x63\x2e\xb1\xb1\xa0\xfb\x49\xbf\xa1\xd5\xfd\x41\x19\x62\x72\xdc\x64\xc5\x84\x74\x8b\x4a\x11\x11\xee\x52\x64\x68\x29\x96\x43\x02\x29\x19\x8d\xec\xc4\xbc\x2f\x73\xfd\x68\x69\x2b\x67\x1d\x2c\x52\x2a\x85\x00\x63\x5b\x07\xd9\x6a\xac\x7e\x6c\x1b\xb8\x12\x5e\xf9\xcf\xff\x2c\xee\x45\x52\x6a\xe2\x6b\xcd\x9d\xf7\x75\x1e\x4f\x1b\xa9\x25\x72\xb5\x15\xe2\x04\x03\xab\xe9\xe4\x59\x24\xa4\x4a\x79\xfe\xe5\xd3\x15\x0d\x07\x95\x2a\x88\xc1\xeb\x48\xd8\xa7\xf5\x07\xb4\x55\x66\xbd\x5d\xfd\xfe\x7d\x6c\x73\xa4\x02\x83\x05\x10\xef\xe6\x63\xe7\x73\x37\x09\xbe\x24\x18\x74\x27\x43\xa0\x70\x6b\x1d\x30\x4a\x9e\x8c\xdf\xf7\x25\x75\xd6\xa2\xff\x48\xc0\x09\x6e\x40\x98\x36\xe9\x8c\x6e\x6f\xa6\xa4\x89\x78\xe4\x64\x3a\x2d\xf1\xb6\xdf\x5c\xfc\xf1\x54\xc4\x0e\xd2\xfe\x3c\xc0\xa7\xfc\x41\x91\x1a\x3a\x78\x46\xfb\xa6\xac\x46\xf2\xbb\x7e\x90\x8a\x59\x3a\x93\x0c\xfd\xb2\x50\x26\x0d\x18\xac\xfd\x8c\x38\xd6\xa8\x0a\x02\x11\x06\x1e\x01\xd2\x56\x35\x4c\x2a\xdd\x2a\xa0\x49\x3c\xd4\x2a\xb1\x3a\x70\x53\xfe\x9c\xde\x8a\x0a\xc2\xc4\xb2\xff\xbe\x95\x3f\x0e\x95\x4f\x62\x3c\x94\xaf\xd3\xaf\xa9\x82\x28\x44\xdc\x92\x12\xb9\xba\x82\x8d\x2b\x12\x73\xed\x5a\x17\xad\xb4\xe6\x72\xcd\x59\x91\x34\xc1\x52\x95\xf9\x79\xbe\xcd\x3e\xa6\x99\x81\x89\x49\x53\x34\x30\x08\x1f\x70\x02\x33\xf8\x99\xd8\x84\x4e\x8b\x2a\x1a\xa9\x48\x60\x4e\x69\x82\x13\x52\x2c\xa0\x18\x2e\x6e\x44\xd5\xbc\xa9\xea\x72\xee\xcf\xe0\x24\xc6\xaf\x7e\xb6\xfd\x37\xa3\x25\xad\x78\x62\x30\x3b\x7d\x94\xa2\x51\x6f\x9f\x79\xa9\xd7\x19\x39\x15\x12\x86\x49\xb6\x87\xcd\xd3\xcb\x52\x48\xd5\x5e\xf5\x25\x22\xf7\x27\x19\xd6\x0e\x5a\xae\xd9\xc6\xa1\x22\x49\x11\x1d\x89\x5c\x1c\x22\xff\x36\x00\x4b\x54\xcc\x38\xa6\x39\xee\xa1\xe9\x49\x3d\x8b\x99\x7d\x50\xb1\x14\xca\x49\x4c\xe5\xbb\x62\x2e\x40\xee\x53\x74\xfe\xb1\xc2\xe1\xb9\x92\xff\xf9\x07\xaa\xaa\xdd\xf5\x0d\xee\x4b\xff\x9d\xbd\xbe\x0e\x13\x21\x36\x5c\xfb\xae\x44\xa8\x6b\xf1\x0a\xa6\x2a\x4f\xba\xfc\xc8\xa6\xe6\x43\x25\xc2\x0a\x76\xdc\x8a\x06\xbb\xb7\x5c\xdc\x3d\x7b\x88\x44\xc5\x96\x5b\xbf\x7b\x43\x4d\x2b\xe7\xc5\xa1\xa5\x97\x9b\x06\x01\x66\xff\xbd\x98\x6d\xd5\x64\x75\x73\x0f\x05\xd4\x59\xbd\x47\x70\xf2\x32\x17\x31\x55\x69\x6c\xfb\x2c\x94\xf5\x3a\x5d\x69\x67\x7a\x47\x82\x58\x8c\xb6\xeb\x5f\x16\xc5\xfb\x62\x46\x40\x09\x15\xa1\xa7\x8c\xd6\x6f\x34\xcd\x64\x90\x60\x36\xf9\xb1\xfc\x80\x43\x79\x73\x05\xeb\x52\x32\xd5\x26\x75\x69\xf5\x2e\x44\x1d\xf6\x40\x25\xa5\xf5\xe3\x6f\xc5\x6b\x17\xe3\x0f\x7f\xd7\x2a\x18\x14\x55\x97\x0b\xb1\xd3\xbb\xeb\x2c\x6d\xf7\x99\xba\xd9\xb7\x29\xf4\xe7\x54\xa3\x33\x18\x51\x3b\x00\xaa\x54\xf7\xa3\xbe\x44\xd5\x16\x9d\xe7\x82\xd2\xe6\xfb\xd2\x34\x6b\x71\xf6\x8e\xd2\xf4\xe1\xb4\x4a\x99\x13\x9c\x73\x69\xb1\xa2\xf6\x2d\xde\x5f\x67\xd4\x14\x44\x21\x22\xdc\xb7\x7f\x8a\xfa\x0e\x03\x99\x37\x51\xc1\x64\xdd\x03\xa4\x98\x35\xf4\x7d\x91\x59\xa9\xef\xe6\x4d\x3e\xca\x10\xc2\x95\xaf\x9d\x94\x26\x6b\x96\xbf\x9f\xa1\x84\x44\xe3\xcc\x7c\xa1\xe7\xfc\xf2\x5f\xbd\x2a\xef\x89\x2a\xe3\xb2\x74\x4d\x5b\x15\x47\x93\x8b\xd7\xe3\xee\xee\xce\xdf\xb0\x01\x40\x1c\xc6\x8d\x65\xa0\xd9\x8b\xf3\xf9\x2d\xf3\xcc\x2b\x54\x13\x1e\x58\x17\x51\xe4\xea\x80\x84\x4c\x1b\x4f\x32\xb9\xf8\x8e\x34\x49\xa2\xd0\x75\x01\x0d\xad\x2e\x9a\x48\x85\xce\xca\xad\xa8\xde\x3f\xc9\x80\x69\x4a\x19\x82\x81\xb2\xc2\x54\x02\x43\xad\x61\xdf\x9c\xbe\x40\x4d\x93\x44\xd1\xbe\xa1\x0a\x51\xca\x2d\x32\xe6\xfe\x36\xbb\x64\x4a\x52\x6c\xd9\xb5\xae\x2d\xc6\x9d\x43\xcb\xba\xa6\x5a\xe1\xf4\xf9\x3e\x80\x16\x35\x63\x0c\x31\x7f\x36\x4c\x7a\x10\xf5\x38\xb1\x7e\xed\x1b\x6b\x1e\x04\xbe\x72\xb8\x92\x59\x8e\x8a\x9f\x77\x65\x35\x8e\x1a\xe7\x77\xcf\x49\x6a\x6c\xcc\x96\xe7\xdf\x8b\xce\xac\xac\x8a\x57\xc8\x6b\xb7\xc7\x5f\x81\x20\x34\x8f\x92\x9e\x0b\xb2\xef\x7b\xf8\x65\xdd\x61\x79\x12\xeb\x30\x4c\xb5\x65\xb9\x6c\xd4\x9b\x27\x04\x5c\x9a\x47\x53\x72\x73\xaa\x43\x90\x58\xfb\xb2\x58\xf9\xad\x3e\x94\x9b\x9f\x0d\x20\x01\x87\x2f\x55\x7f\x36\x29\xe2\x20\x41\xd8\x95\x1e\xc8\x22\xa0\x68\x6e\xda\x0b\x54\xd7\xcd\xc3\x3a\xe6\x96\x22\xf4\xaf\xef\xcf\xdd\x0b\x1f\xb7\x39\x7f\x86\x30\x77\x67\x26\x34\x45\xc8\xc3\x4b\x5b\x89\x1c\x85\xb0\xdb\x79\xe9\xdb\x8f\xd4\xc6\xb8\x38\xf0\x51\xfc\x1c\x93\xa8\xe8\x34\xd4\xc6\xf9\x56\x03\x8c\x7e\xfa\x3b\xa9\x50\xe8\x3c\x9d\xed\xbd\xdf\x95\x95\xc5\xa4\xf5\x97\x90\x96\x00\xa4\x5b\x71\x3b\x63\xd6\xa2\xb0\xa9\x99\x27\xf8\x89\xbb\xed\x63\x56\xac\x0a\xfd\x28\x7e\xe2\xb6\xfb\xbd\x68\xb2\xdc\x99\x41\x7f\x05\x99\x4a\xcd\x7d\x8d\x29\xab\x6b\x9f\x09\xd6\x8a\x58\x0e\x98\xfd\x66\xbd\x7b\xba\x45\x95\x79\xd4\x24\x39\xee\x0f\xab\x97\xc3\xf1\xb0\x7d\xdc\x0c\x43\x01\xdf\x3a\x36\xbf\x5f\xf1\x3a\x52\xad\x42\x4b\x86\x82\xbc\x42\xeb\x37\xd1\xe7\xb7\xb4\x8a\x13\x84\xb3\x96\x67\x28\xee\x87\x9d\x43\xab\x24\x46\x87\xc0\x69\xf5\xa0\x79\x1b\x83\x62\xb4\x02\x1d\x31\xd7\x9d\xfb\xad\x87\x02\xad\xc5\xd9\xfd\x97\x1f\xa7\xa3\x00\xd5\x68\x8f\xc2\xc6\x0e\x37\x97\xa1\x2b\x61\x78\xcd\x3a\x89\xb5\xea\xbd\xc7\xef\x23\x64\xe0\xec\xbb\x43\xa4\x4d\x3c\x72\x66\xe0\x75\x78\x16\x90\xb6\x1a\x74\x3a\x22\x8f\xa7\xca\x2f\x23\x45\xb9\x09\x88\x50\x83\x92\xa8\xfd\x71\x3c\x89\xac\x68\x8e\xdd\xbb\x47\xe6\xf6\x3d\x5c\x59\x20\xa3\x42\xfc\xc5\x3f\x37\x87\x6f\xc7\xd5\xed\xad\x87\xac\x6a\x03\x36\xb5\xeb\xf0\x0d\x15\xc0\xc2\xea\x58\x48\xf2\x02\x35\x31\xe6\x14\x7d\xfd\x43\x77\x93\xc5\x35\xe1\xb9\x8b\x03\x0b\x18\x16\x40\x26\xf5\x96\x85\x2a\x4b\xb2\x5c\x63\x01\x16\x4b\xaa\xc6\x7b\xdf\xd3\x9c\xc6\x9d\x02\x4b\xac\x8e\x80\xb0\x5b\xcd\xb6\x30\xa5\xa3\x7f\x9d\x0d\xe4\x84\x62\xc3\x52\x5b\xf8\xce\xa1\xe7\x0a\x4c\xf6\x73\xe2\x64\x01\x67\x02\x33\x1c\x87\x37\x70\x3c\x68\x65\x9e\xe9\xfd\x5b\xd6\x8c\x12\xaa\xc0\x23\x19\xf7\x2d\xba\x73\x22\x21\x08\x75\x10\xf7\x5a\x1d\xbd\x0c\xd1\x38\xcb\x0e\x11\xb1\x2a\x2c\x32\xd3\xbd\x62\x7d\x7f\x48\x63\x48\xe7\xf9\x5b\xac\x09\xfa\xc4\x54\x41\x24\xad\xe6\x6a\x59\xe4\x97\x6e\x51\x2b\xa8\x36\xb6\x4c\x74\xeb\xd4\x59\xd4\x58\xdf\x7c\xa1\x54\x04\x91\x66\xe8\x80\x9a\x5e\x1c\x7b\x42\x57\x00\x71\x4c\xa2\xd0\xb1\x12\xac\xf2\xfc\x53\x06\x5a\x0a\x29\x63\x16\x15\x7f\x3a\x97\x95\x77\x20\x9f\x45\x56\x2d\x50\x3c\x7b\xd3\x06\x29\x17\x98\x48\x06\x2c\x2f\xfa\x3f\x46\x29\x89\x86\x17\xec\xa3\x98\xd9\xcf\xc5\xb1\xa3\x37\xc9\x9a\x95\x31\x59\x9e\x0d\x6b\x1f\x04\x4b\x2d\x6b\x4e\x0e\xa2\xea\xe6\xe6\xaa\x82\x42\x0c\x72\x28\x14\x44\x1a\xa3\x3c\xb1\x45\x4e\xdc\x95\x55\x4f\x07\x4c\x41\x0a\x70\x3b\x40\x1f\x1a\x6f\xf6\x87\xf9\x4e\x07\x12\x6c\x85\xe9\xfc\x56\x36\xe5\xa8\x00\x06\x2a\xd4\x68\x0a\x6e\xb2\x72\xb1\x85\xe7\xeb\xee\x12\x50\x11\xc5\x5a\xef\xb1\x28\x91\x0e\x75\x7b\x3a\xe7\x60\x49\x0a\x27\x88\x0b\xe7\x32\x81\x16\xc6\x12\xc2\xdb\x89\xb6\xd4\xe3\x03\x40\x63\xa5\x86\x57\x3a\x2f\x05\xb6\x23\x4a\x03\x00\x9a\x20\x7d\x05\x2a\x82\xa1\x6f\x88\x1c\x3f\x9b\x81\x77\x00\x40\x47\x58\xe9\x42\xb6\xb1\x81\x4d\x62\xfa\x1c\x86\x85\x44\x8c\xda\xcd\xfd\xfe\xed\x0f\x47\x56\xfa\xf8\x45\x48\xd9\x2d\xb0\x0a\x96\x70\x22\x60\x12\x83\x14\xfa\x58\xd6\xb2\x1d\x26\xf6\x88\x09\x48\x88\xee\xeb\x23\x34\x62\xc4\x6e\x64\x82\x88\x52\xe1\x7a\x07\x27\x70\x33\x13\x48\x46\xd4\x40\x6d\x3c\x4d\x06\x9b\xc0\x69\x69\x9c\xc4\x3b\x8c\xaf\x47\x68\x82\xe6\xf3\xf1\xbf\x76\x7f\x8d\xfd\x67\x43\xa2\x04\x31\x1a\x95\x30\x26\x87\xa3\x9c\x64\xe0\x0c\x49\x81\x59\x2a\xfe\xbc\x11\x87\xbb\xb6\x50\xff\xd4\x09\xf2\x17\x00\xe5\x99\xad\x30\xe1\x9a\x35\x17\xcf\xca\x51\x98\x19\x1a\xde\xd0\x80\x7b\x06\xd1\x4d\xd1\xa0\x67\x37\xb6\x39\x86\x0a\x12\xb9\xfd\x75\xbd\x39\x44\xe3\x2c\xf0\x54\xb4\x80\x9a\xce\xe1\xc0\xba\x6a\xf9\x01\x8f\xa2\x7a\xb7\xdd\xfd\xb3\xba\x59\xc4\xe7\xff\x41\x68\x72\xbd\xc0\x0d\x4b\x01\xc3\xde\xd3\xbb\x4d\x53\xae\x85\x6f\x81\x32\x9c\x31\x4c\x18\xa3\x38\xc2\xc0\x48\x66\xb8\x64\xf8\xc5\xa5\xd0\xaf\xb0\x35\x77\x56\x02\x6a\xfa\xb8\x1c\x8c\xb7\xb2\xd6\x51\x1e\x7a\x44\x4d\x18\x85\xc8\xf4\xd3\x6a\xdb\x14\xde\x34\xe2\xda\x29\xf3\x63\x05\xc3\xfa\x60\x0f\xf8\xec\x26\xaa\x5b\x1d\xd8\x6d\x82\x55\xaf\xe9\x6f\x87\xc0\xb0\x86\xa4\x50\x04\xa2\xb9\xab\xca\x53\x37\x68\x31\x46\x36\x51\x64\x90\x68\xc0\xcf\xf2\xaf\x4b\xc8\x26\x4a\x2c\xe6\xbf\x12\xc5\xfb\x4c\x4d\x99\x9a\x98\x51\xa4\x59\x5b\xbf\xfc\xf5\x7c\xd8\xfd\xb1\xe9\xd9\xd5\x4c\x1c\x25\xba\x37\x01\x12\x0a\x40\x3e\xd2\x7e\x5b\x31\x71\x42\xb1\xe7\x5f\xa8\xf6\xdc\x16\xaa\x69\x2b\x24\xb9\xfb\xf2\x56\x12\x12\xe2\xfe\xeb\x88\x41\x7d\x29\xc9\x24\x61\x02\xc9\x80\x63\x83\x9a\xcf\x6e\x33\x89\x62\x24\xdc\xbb\x39\xd7\x93\xe5\x92\xc4\x91\xf5\x06\xdb\x33\x54\xcf\xab\xf5\xf0\x77\xa3\xa5\xaf\xd4\x0f\xd1\x4f\x03\x77\xd8\xf4\xd3\x0f\x93\x56\x82\x0a\xa7\x0b\xb6\xcb\x7d\xf4\xb0\x59\x23\x18\x47\xd0\xea\xb9\xad\xdf\xa6\x39\x9b\x7e\x5a\x8b\xd8\x60\x3d\xf3\x07\xaa\x49\xff\xf9\x56\xe6\x93\x68\xd8\x88\xd4\x6a\xf9\x65\x9d\x97\x5f\x97\x85\xc8\xd1\xf6\x79\x0a\x5e\x6a\x84\x62\x21\xf5\xa8\x87\x0c\x01\xc6\x0f\x02\x49\xab\xbb\x69\xf6\x02\xaa\xac\xf4\x2c\x2b\x65\x24\x93\x18\x92\x7e\x94\x0d\x3c\x95\x0f\xa5\x7a\xbf\xb9\xd8\x8a\x82\x1f\x10\x31\xaf\xd6\xba\x3d\x89\x57\x70\x4c\x13\x9d\x5f\x50\x5e\xb5\x73\x1a\x29\x01\xf1\xcf\x18\xdd\x5e\xa5\xc3\x67\x53\x4f\x6a\x95\xaa\x51\xaf\xf4\x18\x30\x69\x14\xb7\x60\x7d\xdc\x10\xea\xec\xb5\xf8\x04\x30\x6b\x74\x28\x85\xea\x21\x66\x33\xda\x4d\x03\x04\x50\xc3\xf6\xbf\x44\x31\x7d\x9b\x60\xb8\xef\x3c\x3a\x94\x0f\x59\x3d\xde\xbc\x26\xa2\x1e\xd4\x74\x51\x7d\x38\xc0\xe5\x2c\x35\x20\x36\x4c\xba\x2e\xe3\x7e\xea\x19\xa3\xc1\x25\x70\x8f\xd8\x64\x50\xe6\x0e\x5c\xe0\xba\x0d\x2d\xc4\x80\x05\x01\x09\x0c\xf3\x70\x60\x2b\xea\xeb\xc5\xb6\xa6\xe9\x48\x16\x04\x2c\xc5\xc0\x42\xfc\xef\x8f\xba\xfb\xdf\x6f\xee\xef\x44\x19\x2b\xbf\x22\xd4\xfb\x1f\x50\xb4\x75\xb7\x76\x2d\xaf\xaa\x1f\x61\x24\xb5\xc1\x69\xfd\xb6\x6b\x9b\x83\x0f\xe1\xdc\x8c\xc3\x01\xd8\xbd\xdf\x85\x33\xdf\x44\x8d\x4a\x27\xfb\x33\xcc\x4a\x13\x2c\xa0\x3c\x44\x0a\x97\xba\x3d\xd9\x76\xe8\x57\x88\xfd\x8f\x30\x4a\x50\xf1\xe2\xf9\xfe\xfb\xba\xff\x5b\x2c\x93\x5e\x13\x1b\x57\xc2\x1c\xb7\xc2\x02\x1e\x50\x45\x7c\x91\xb4\x8b\x33\xee\x45\xff\x68\x21\x97\x36\x0f\xec\x45\xa3\x9a\xdb\xac\x02\xac\xe9\x8d\xf6\x0c\x16\x84\x9a\x60\x77\xf8\xfd\xfd\xfd\xe8\xdb\xb2\x20\x62\xa9\xb0\x10\xa1\xbe\x9a\xff\x49\x23\x38\x0b\xe2\x48\xc4\x03\xd1\xc2\x7a\xb6\x6f\xb1\x20\xe1\x92\xb9\x12\xcf\x53\xd9\x6c\x8b\xfe\x8a\x58\xcc\xf8\x6d\x7a\xb1\x44\x39\x92\xdf\xac\xc0\x60\xf4\xde\x6f\x26\x2c\x48\xb4\xa5\xf9\xaa\xe1\x6b\x45\x4a\x16\xa4\xa1\x6d\xce\x44\x48\xc8\xb8\x8c\xce\x02\xa1\x4d\x18\x0d\x5a\x85\x1f\x59\xd9\xd6\x47\x04\xcf\x55\xa0\x44\xdd\x1c\x4d\x55\x9e\x8e\x59\x03\xa7\x45\x5a\x5b\x16\x48\xd6\xb3\x93\x6d\xeb\xbb\xec\xa7\xb7\x5e\x2c\x90\x51\x12\x25\x23\xe3\xb1\xae\x00\xb1\x6a\x22\xdf\x36\x70\xda\xea\xdf\x66\x17\x8a\x64\x82\x3e\xc7\x65\x37\x86\x8e\x7f\x9a\xc6\x65\x81\x92\xb6\xbd\xd5\x0a\x7d\x7c\xce\x81\xc4\x02\x05\x1a\xed\x18\x86\xe3\xe4\xd8\x4b\x00\xb1\x40\x07\x91\xc5\x75\x75\x33\x41\x9f\x0f\xe5\xb4\x90\x34\xbd\x45\x1d\xc7\xb8\xe7\x6c\x0e\xdf\x36\x2f\xbb\xa7\xcd\xf7\x47\x7f\x19\x48\x00\x7d\x8d\x2e\xf8\x58\x9d\xa0\xd0\x57\xaa\xba\x2c\x00\x63\xa9\xeb\x7d\xbe\xd0\x0a\x0e\x7d\x52\xf2\x9c\x3d\x80\xa1\x29\xd6\xda\x33\x55\x22\xe3\x8b\xff\x5d\xc3\xb4\xa5\x1f\xcf\xce\x79\x79\x72\xee\x38\x23\x41\x10\xa2\x5c\x00\xbe\xf7\x3f\x01\xde\x0f\x3f\xca\xfe\x98\x8e\x7a\x8f\x50\xd4\x56\xb6\xda\x1d\x22\x84\x21\xff\xbb\xcc\x85\x7a\xc7\x19\x39\x2a\x3b\x79\xf3\x41\x08\x25\xbe\xc1\xc5\xa2\xec\x70\xe7\x9a\x78\xdf\x8c\x50\x66\x58\xe0\xeb\x98\xf9\xa7\x0a\x58\xd3\xc7\xec\xce\x42\x88\x1a\xd2\xd1\xda\xf6\xb0\x3e\x48\x61\x84\x8a\x24\xe9\x91\x27\x88\x6d\x18\xaf\x5d\xc2\x25\x47\x1e\x70\x84\x72\x60\x50\x90\xc9\xb1\x62\xb2\x1f\xa6\x2d\xd0\xb7\x2d\xbc\x70\x0b\xcc\xe1\x35\x6e\x64\x18\xd8\xbe\xdd\xf2\xbc\x54\x70\x66\x24\x0a\x2c\x00\xc9\xb7\x18\x0d\x61\x62\x6f\xea\x19\x89\x58\x8a\xd5\x7d\x81\x8b\x7b\x2a\x4b\x78\x2d\x0d\xc1\x48\x12\x49\x8b\x17\xe8\xac\xd8\x76\xbd\x3b\xfe\x20\xfe\xf7\x92\x58\x59\x69\x9a\xea\x72\x6e\x44\x5b\x75\xfb\xef\x07\x78\x97\x87\x91\x04\x78\x30\x9e\x60\x37\xca\xf6\x61\x2f\x2f\x0a\x92\xc6\x80\x7e\x9a\x86\xba\xa9\xca\xfe\x2a\xa9\x16\x5e\xb7\x1f\x6d\xbf\xe7\x00\x24\xfe\x3c\x41\x62\xec\x27\xb1\x44\xdf\xa8\xa9\x35\x5a\x51\x44\x10\x81\xb1\xdc\x66\xed\x38\xbc\xfc\xdf\x85\xf4\x6a\x1a\x88\x15\x23\xe1\x38\x13\xc1\x88\x90\x82\xb3\x51\xef\xdb\xbc\x99\x89\x11\x49\x52\x4c\x2b\xff\xbe\x1b\xdb\x66\x22\x99\xc1\xcc\x8c\x73\x4e\x6f\xdb\xba\x39\x94\x56\xf0\x6f\xfa\xc0\x52\x72\xdf\x49\xb4\x42\xaa\x02\xd0\x16\x5e\xb7\x6a\x5f\x4f\x59\x31\xa3\x77\xbc\xfe\x94\x8a\xca\x84\xf6\xbc\xbb\x45\x01\xf9\xd4\x84\x11\xcd\x00\xf3\x01\xa5\xb1\x2e\x7c\xdf\x0e\xc7\x88\x56\x14\x5d\xcb\xf5\xea\xf0\x8f\xd5\xed\x17\x83\x65\x46\x20\xe0\x18\xe9\x37\x3f\xb2\xa6\x81\x6a\xab\x77\x06\x83\xc4\x65\x77\x86\x11\x20\x1a\x86\x94\xd7\xbc\xcc\xe7\x07\x45\x14\x99\x65\x5d\x01\xcc\x27\xb9\xfc\xed\x43\x12\xe0\xab\x5b\xac\x1f\xb5\x57\x24\x2f\x8c\x80\x66\x08\xb9\xc0\x74\xc4\x7f\x95\x59\x01\xba\x7f\xee\x7e\x4a\x98\x50\x68\xda\xeb\x8c\xbb\xd5\xd5\xff\xa6\x89\xc3\xa0\x57\xbe\x9a\xf1\x19\x4e\x36\x02\x1a\x10\x5b\x31\xbb\xc9\x9a\x3d\xe4\xa0\x9a\xe7\xaa\x6c\xe0\x35\xd3\xde\x74\xd0\x80\xdb\x68\x61\xe8\x83\xff\x87\x09\x8a\xe9\xbb\xa7\x41\x04\xa8\xe3\x73\x12\x55\x95\x81\x5e\x79\xe3\x43\x09\x85\x51\x5d\xc2\x95\x2a\x91\x37\xe6\xaa\x28\xc1\x28\x49\x05\x5a\x6d\xd0\x59\x4f\xc6\xbb\xd4\xd3\xc6\x68\xe7\x00\x52\xbb\xe3\xf8\x5f\x62\x5c\xa0\x8d\xbc\xcb\x72\xec\x6b\xf5\x8c\x07\xfe\x70\x18\x5a\x2e\xfe\x9e\x7d\x81\x51\x26\x01\xf3\xdd\x07\x0f\xd9\xfb\x47\xad\xc3\x8c\x72\x91\xe0\xb6\xe9\x24\xa2\xbf\x84\x57\x30\x1a\x52\x9a\x8a\xbe\x00\x31\x87\x6f\xf9\x41\x4c\xd9\x5e\x6a\x64\x52\x7e\x14\xd5\x6b\x56\xac\xb1\xfe\x7c\x03\x6f\x22\x37\x23\xc2\xed\xc9\xda\xa2\x61\xa8\x23\x57\x17\xdc\xfd\x28\x9c\xf4\x8a\x9f\x49\x34\x16\x8c\xf8\xc4\xf6\x31\x2b\xb2\xce\xcb\xe8\xc1\x2a\x8c\x26\x49\xe0\xa9\xdc\x30\x4d\xed\xff\x9c\x3a\x51\x0c\x00\x27\x76\x32\x9c\x21\x2d\xb9\x86\xad\x32\xbc\x63\x5f\x38\x0a\xb9\x5c\x6f\xec\x34\xd1\xd2\xa6\xb0\x11\x86\x93\x95\xc5\x78\x8b\xa6\x09\x04\x8c\xf6\x57\xc2\xbc\xf0\xb3\x58\x52\x77\x61\x34\x15\x0a\xdf\x77\x17\x3a\xa1\x44\x42\xa1\x91\xe3\x6c\x21\x4b\xc4\x68\xaa\x0d\x02\x06\x71\x63\xf1\x1c\x34\xfd\x0b\x11\x51\x84\xaa\x9e\xbe\xb5\x75\x2d\x2a\xdd\x2d\x6a\x7f\x5c\x06\x56\xaf\xb5\x57\x20\xda\xf5\xb0\xdb\x43\xf9\xd4\xe6\xf9\x74\x3f\xa7\x92\x2a\x0c\xa7\x11\xc2\x26\x72\x37\xe9\xdc\xa0\x27\xec\x86\x78\x14\xe7\xd9\xc7\x96\x29\xa0\x50\xf8\xe3\xea\xe9\xdb\xea\x70\x58\x3d\x3d\xbf\xec\xfe\xfd\x57\x74\xf8\xb6\xfa\x63\xd3\x5f\x58\xd1\x5e\x87\xb6\x2c\xf3\x6f\x59\x8d\xec\xbd\xa3\x8d\x9d\x4a\x63\x95\xc6\x6a\x24\xcc\x7f\xdf\x2c\xe0\x27\x19\xd5\x26\x4d\x3c\x91\xfa\x66\xd2\x3e\xc8\x28\x04\xd4\x6b\xef\xba\x8c\xbd\x45\x46\xfe\xb3\x55\x60\x22\x4e\xbc\xd9\x87\xa2\x69\xab\x79\xae\xbd\x1b\x92\x52\xcb\x64\xd1\xe6\x99\xe8\xad\x3e\x23\xa1\xc4\x49\xeb\x31\xb9\xc7\xbb\xcd\xea\xf0\xfd\x65\xb3\xef\x07\x24\x21\x9a\x8d\x93\xf8\xe9\x6c\xc6\x7e\x28\xb5\x31\x46\x39\x20\x6d\x4a\xd1\x9e\xee\xab\xb2\x3d\xd7\xfd\x81\x38\xd0\x89\xa3\x93\x52\x65\x5f\x98\x62\x8c\x75\xb6\xda\xe3\xfc\xfe\x4b\x68\x2f\x52\x34\xbc\x0d\xc6\xa9\x55\xfe\xad\xa0\x86\xea\x63\x06\x47\x64\x8c\x33\x9d\x04\x03\x7f\xc1\xc8\xf3\xf7\x03\x62\x8a\x49\xe0\xc3\x7a\x37\x90\xf9\x76\x7f\x8e\xa8\xd3\x1a\x3c\x80\x38\x2d\xcd\x59\xc6\x53\x42\xed\x36\xe2\xb6\x82\x6d\xbd\x3b\xc3\x70\x67\xda\xd6\x83\x3f\x32\xf8\x71\xdd\xaf\xcd\x18\x07\x82\x9b\xd4\x1e\x72\x84\x9b\x7d\x9d\x6a\x5e\xfc\x9a\x2c\x8a\x04\x2a\xff\x0b\xad\x6f\xba\xc7\x9a\x86\x35\x6e\x50\x1c\xc4\xf1\x40\xd8\x38\x29\xe3\x2c\xda\x3e\x16\x07\x0a\xbb\x63\xee\xee\xee\xc6\xbe\x09\x8b\x79\x6c\x12\xef\x2b\x7f\x40\x55\xcf\xde\x65\x1c\x25\x81\x4b\x18\x3f\x5e\x90\xfd\x14\xa9\xa2\xc6\xd3\x9f\x25\x49\x82\x7e\xda\xc3\xea\xce\xff\x29\x65\x09\x7a\x22\xbe\xd3\x06\x7a\xa1\xe3\xd9\x1b\x4b\x81\x20\x95\xc9\x7e\x73\x40\x6f\xcc\x21\xec\xfd\x75\x84\xb4\x2b\xab\xe7\x96\xab\x2d\xe6\xe1\xa7\xe3\xa0\xe4\xcb\xdb\x20\x93\x3c\x44\xe0\x64\x67\x3d\x1c\x06\x60\x0f\x4d\xdd\xa3\xf1\xfc\xf5\x25\x84\x3a\x1c\xe5\xc3\x1f\x4a\x51\xf4\x73\x58\xd1\x00\x93\x09\xdf\x9f\xb6\x07\x6f\x7b\x30\x16\x1e\xb8\xb1\x19\x53\x1a\x2c\x43\x8e\x98\xe4\xae\x18\x53\x26\x72\x02\x23\xa2\xa8\xd7\xe5\xe9\xdc\xcd\x56\x3d\x2f\xce\x33\xa6\xc3\x08\xb3\x4d\xba\xdc\xff\x10\xd5\x15\xf4\xd1\x8d\x02\xc1\x10\xd4\x5e\x97\xb9\xbe\x2b\xab\xc3\x5b\x56\xf5\x4b\x0a\x84\xc0\x2c\x9a\xe3\x9a\xfe\xe4\x02\xca\xb6\x07\x20\x34\xec\x38\xd7\x63\xba\xc2\x84\x31\x66\xb8\xd5\x05\xaa\xc0\x64\x43\xc1\xca\x1f\x34\x32\x62\x3d\x72\x73\xf7\x01\x55\x95\xf9\x32\x23\xe3\x41\xa8\x31\x7b\xd8\x16\x75\x23\xde\xa1\x9b\x36\x6d\x91\x4d\x29\x57\x18\x0f\x12\x8d\x69\x08\xd9\x56\xc5\x0b\x3a\x58\x9e\x01\x70\x18\x62\x42\x2c\xa8\xea\x59\x33\xe3\xe2\x23\x72\x62\x2c\xef\x71\xe6\x48\x15\x47\xb4\x8d\x8c\xd3\x94\x0a\x2b\x36\x54\xfc\x25\xae\x6a\x84\x8c\x53\x91\xea\xd4\xaf\xfc\x81\xa4\x9e\x71\x96\x58\xb4\x94\xf5\xc8\xd7\xa2\x6e\x72\xd8\x5d\xf5\x8e\x33\xce\x80\x63\x85\x4c\xd4\x99\x76\xb8\xcd\x6f\xe2\x03\x6e\x00\x8a\xc7\x6e\x62\xf7\x17\xe4\x54\x5a\xd4\xfe\x79\x16\xcf\x71\x1e\x53\xec\x34\x91\x6d\x96\x6b\x9f\x76\xea\xe1\xc0\x8c\x73\x4d\x6d\x5b\x65\x75\xf9\x8e\x32\xd1\xd8\xe6\x51\x56\xd3\xb0\x8f\x47\x84\x23\xff\xb5\xa9\x00\xf6\xad\x9c\x4c\x88\x64\xea\xb5\xf0\x88\xc5\xc9\x24\x24\x83\x62\x4c\xa8\xe7\x47\x09\x81\x39\xce\xfa\x0c\x45\xf3\x2c\xaa\x1a\x94\x55\x47\xef\xbf\x54\xa4\x19\xb6\x18\x21\xae\xd2\x31\xff\xcd\x2e\x12\x8b\x00\xf5\xe0\xb3\x2e\x6c\xb6\x5a\x4b\x85\xee\x41\x8a\x4b\x05\x67\xc6\x13\x69\xa4\x4b\x21\x6d\xd7\x8b\x04\x1b\x8c\x27\xae\x0b\x42\xf8\x68\x79\x4a\xf7\x30\x2e\xa4\x30\x9e\x68\xab\x94\xf0\x19\x93\xc2\x64\x3b\xe0\x89\x81\x68\x60\x6b\x1b\x36\x57\x77\x38\xa5\xc6\x91\x71\x77\x6b\xdb\x3a\x4c\x5f\x5c\x2d\x4d\x0d\xe2\xe9\x1c\x54\xea\x65\x98\x12\x92\x08\x64\x29\x39\x1d\xb1\x95\xc3\xcb\x3c\x33\x2e\x21\xf5\xb2\x9c\x36\x59\x0a\x7a\xdf\x9e\x6e\x2e\x13\xe8\xb5\x1b\xab\x18\x0b\x3d\x22\xb3\xcc\x75\x17\xc3\xfe\x09\xd9\xeb\x5b\xbf\x04\x54\xa4\x12\x8f\x09\x59\x7f\x3b\x76\xdf\xef\x48\xd2\x49\x90\xcb\x95\xb2\x56\xcb\x49\x7d\x5b\x9d\xcd\x45\x1b\xcb\x35\xa7\x2a\x72\xaa\x8e\x50\xdd\x95\x95\x02\x0f\x42\x99\x62\x08\xda\x29\x46\x76\x71\xdb\xe3\x10\x84\x58\xd4\xbe\xcf\x3e\xe0\xe5\xe9\x7e\xf6\x6c\xc0\x2d\x88\xb2\x80\x1f\x0e\xc2\xe6\x65\x1b\x19\x87\x88\xe2\x47\xb2\x3d\x4f\x23\xd9\x91\xf9\x2f\x00\xc7\x0e\x01\x4c\x5c\x8c\x34\xf4\xba\x23\xd2\x36\xa4\x7b\xe1\xde\xe7\x0a\x4e\x59\x7b\xfa\x34\xfe\xfd\xe2\x23\x1b\x62\x73\xd7\xc7\xfe\x62\xce\x2f\xd7\x9d\x4b\xba\xa0\x40\xcd\xb8\x09\x2d\xf2\x78\x2d\xaa\x67\x51\x39\xc9\x17\x16\x06\xda\x20\x95\x37\xaa\x4b\xe8\xec\xa3\x6e\xca\x5e\xcb\x89\x85\x01\xc8\xd0\x85\x1b\xdf\x44\xfd\xb6\x2d\xba\xef\xed\x5a\x82\xa7\xed\xd8\x2c\x24\x11\x17\xdd\x0f\x6c\x9f\x6e\xd6\xbf\xea\x16\x64\x21\x11\x81\x76\x32\x2d\xeb\xf6\xd4\x3d\x42\xf6\x01\x8e\x97\xdc\x0d\xa1\x21\xc3\xf2\xf6\xd3\xee\xc9\xfb\xc9\x21\x8b\x25\x76\x37\x58\xfd\x8f\xb7\x0a\x00\xc5\x58\x37\xff\xbb\xed\x3d\x85\x90\x49\x89\x53\xf4\x65\x67\x01\x47\x87\xcd\xf1\xf9\x65\xf7\xc7\xb6\xa7\x6c\x63\x21\x53\xa9\x65\x08\x82\xc6\xa7\x28\x7e\x4d\x26\x95\xf8\x93\x8d\xc1\xe6\xea\xb9\xb3\x31\x9d\xb9\x21\x0f\x52\x74\x58\xb6\x85\xc9\x4e\x65\xf1\x3e\x20\x49\x58\xc8\x59\x84\xd9\x37\xf8\xc8\x54\xf3\x67\x59\xbd\xcf\x60\x4f\x2c\x0c\x53\x6a\x2c\xa7\x52\x3d\xd7\x0d\x62\x61\xa8\x28\x6e\x8c\x06\xb1\x2a\x8f\x59\xdf\xac\xef\x8f\x03\x09\xd5\xa4\xb8\xd9\x6d\x14\x74\x3a\x23\xc2\x28\xa0\x08\x7b\x6f\x0b\x7b\x9d\xc9\xae\x18\x46\x4c\xe3\xc2\x3b\xbe\x42\xf3\x17\x88\x6a\x7e\x72\x18\x0e\x42\x3a\x13\xc9\xf2\x19\xa0\x7d\x94\x3a\x0a\xa3\x50\xa1\x17\x22\xb4\x25\x2f\x15\xb9\x23\x20\x9f\xe5\x41\xfb\x39\x15\x89\x10\xdb\x63\x7f\x00\xbc\xef\x0a\x18\xa1\xb8\x58\x18\x73\x82\x85\x26\xff\x19\x6e\xe1\xc3\x0a\xdb\xfa\xe3\x8a\x9a\x60\x4c\xcd\x73\x28\x1d\x43\xcc\xec\x51\x92\x30\x40\x20\xf1\x11\xef\xe2\xd0\x0b\x2b\x8e\x5c\xe1\x30\x89\x62\x8c\xac\x1d\x56\xfa\x05\xea\x36\x6f\x7e\xbb\x2e\xa2\xb3\x30\x65\x29\x3a\x7b\x5d\xf4\x3a\xad\x7c\x4d\xe6\x7f\x6a\x02\xac\x7d\x55\x98\x85\x9a\xda\xae\xc9\xdd\x89\x98\x5b\x6e\x75\x51\x75\xe1\xfc\x0b\x66\xf9\x3f\x41\x0c\xb2\x50\x28\x2b\xa2\x52\x97\xa6\x51\xe2\x3c\x64\x3f\xc2\xff\x97\xb5\x3f\x6b\x6e\x1c\x47\xf6\xc6\xe1\xaf\xd3\x17\xcf\x05\x41\x2c\x24\x2f\x65\x79\x29\x3d\xed\xed\x58\xaa\xaa\xe9\x73\xe2\x84\x02\x4b\xc2\xe6\x98\x22\x35\x24\x55\x2e\xf5\xa7\x7f\x83\x09\x80\x9b\xe8\xaa\x7e\xe3\xff\xdc\x74\xcd\x98\x10\x57\x2c\x89\xcc\xdf\xa2\x68\x12\xfb\xd7\x71\x07\x25\xfc\x99\x87\x19\x34\x1c\x67\x31\xce\xc9\xfd\x56\xf8\xab\xc7\x96\x76\x7f\x78\x81\x1f\x79\xb7\x95\x7c\xac\x1c\x7d\x73\x70\xfa\xa0\x5c\x79\xde\xd5\x53\x89\x33\xf3\x25\xaf\x92\x72\xa5\x0c\xe7\xc3\x5e\x6b\xaa\xaf\xe2\xdb\x68\x42\x38\x1b\x6a\x5b\x41\x2e\xf6\xb2\x59\x66\xe9\xa0\xe8\x18\x3c\xd2\xc3\x51\x41\x53\x67\xd7\xd3\x3b\xcf\x55\x4d\x93\x8f\xee\x56\xa7\x1c\x91\x5e\x65\xd5\xca\xfa\x7c\x0b\xc3\x01\xe5\x0e\x3c\xac\xfe\xb5\x79\xf8\xfa\xb0\x7f\x7c\x7a\xdc\x7f\xff\xb2\xd9\xdd\xdc\x6f\xb6\xbb\xfd\xea\xe1\xe9\xeb\xe3\x2e\xb4\x35\xb1\xc1\x98\xdd\x53\xf3\xa7\xdc\x63\xca\x81\x10\xac\xbf\xca\x40\x08\xda\x9e\xcb\xf6\x6d\xb6\xc3\xe4\x40\x29\x66\x63\xae\x73\x59\xfe\xdf\x5e\x96\x3a\x1c\xcc\x1c\x14\x03\x45\x52\x10\xc0\xdd\x1f\x51\x19\x4e\x0c\xdb\xb7\x1c\x0a\xe3\x05\x19\xfb\x83\x5a\xe0\x16\xdf\xad\x52\xd7\xd7\xb7\xbb\xe5\x65\x8a\x5b\x91\x04\x28\x9b\x2f\x76\xdf\x56\x75\x10\x96\x76\xfd\xd9\x47\xeb\xa3\x19\xde\x4a\x2a\x7d\xe8\xbb\x3d\xa1\xb1\x95\x3d\x85\x54\x0a\xb7\x5a\x4c\xe4\xe3\x67\x15\xe3\xae\x81\x44\xe0\xd5\xe3\xea\xe1\x66\xff\x65\xf5\xfd\xcf\xcd\xe3\x9d\xff\xb1\x88\xe2\x14\xf3\x34\x26\x6f\xba\xe1\x35\xda\x0d\x8b\x28\x51\x51\x3c\xf1\xbb\x87\x1f\xeb\x53\xbb\x9f\x9e\x5d\x10\xe2\xdc\x1b\x4f\x08\x55\x9e\x4b\x68\x86\x46\x49\x32\x10\x48\xef\xbb\x99\xc0\x1f\x88\x99\x26\x49\xef\xe6\xd0\x9e\x57\xe3\xc1\x2f\xe2\x44\xa5\x7e\x15\xbc\x39\x1c\x8b\xea\x0c\xb0\xb9\x20\x02\x84\xb6\x56\x60\x9a\xd9\x63\x82\xa6\xba\x2f\xbe\x0d\x65\xce\xa1\xd9\x96\x3f\x66\x4f\x41\x45\x8c\xa9\xf3\x50\xd3\xf8\x13\xb4\x96\xef\x31\x17\x17\x0b\xd3\x6f\x92\x36\xbf\x60\xa4\x50\x41\xd3\x84\x44\x7d\x12\xb1\x27\xf5\x8e\x6e\x23\xd5\x98\xeb\xb9\x1b\x65\x36\x04\x8b\xd2\xc0\xc5\xc1\x97\x8b\xdc\xc7\x66\xcc\xa4\xa2\x82\x93\x24\xf6\x99\x9a\x7d\x01\x3f\xa0\xcf\xc4\x09\xc1\x28\xce\xd6\x41\x57\x12\x13\x90\xb3\xdb\x0b\x3e\xbd\x5d\x6b\x63\x5c\x61\x5c\x35\x6d\xde\x9e\x5a\xf0\xa9\xb6\xe5\x1a\x95\x10\x00\xb1\x0a\xdf\xef\x0c\xc8\xef\xea\x43\x52\x91\xc4\x36\xa8\x40\xfd\x43\xd9\xe7\xf0\x43\x20\x38\x67\xca\x63\xfe\xb5\x0e\x3d\x5d\xa4\xb1\xc0\xd4\xf3\x5b\xfe\xfa\x06\x4d\x7b\x05\xfd\x85\x52\xce\x50\x26\x6e\x77\xb3\xfe\x32\x1e\xce\x22\x4d\x23\xf7\x3c\x6e\x5a\x5e\xe9\xb7\x1c\x7a\x03\x30\x2a\x32\x6b\x51\x19\xae\xa8\x5e\xe3\xdb\xaa\xde\x1e\x64\x51\xb8\x6c\xe2\x22\x7a\x89\x0a\x49\x22\xe6\xf9\x0b\xed\x67\x34\x8b\xa1\x69\x32\x98\xdb\xdc\xd6\xd5\xe1\xcf\xbf\xd6\x98\x5b\x98\x3e\xab\x24\x10\xd3\x81\xd3\x73\xf3\x53\x0f\x79\x4f\x21\x8d\xc5\x7d\x6b\x91\x2b\x95\xe3\xe6\x5e\x49\xfd\xde\xad\x0c\x7f\x9c\x06\x03\xae\x7e\xce\x98\x62\xc4\x66\xff\xfa\x53\x2a\x91\x8e\xb8\x38\x43\x7e\xee\x6b\x99\xb7\xa1\xd6\x27\xb4\x48\x70\xa4\x5c\x05\xd0\x10\x15\x5a\x4b\x32\x62\xa6\x6d\x74\xd5\x23\xc8\xa8\x30\xc2\x08\x27\x2f\x02\xef\xc5\xf9\xbe\x6a\x5b\xa8\xcf\x57\xcb\x73\xa0\x30\xa9\x42\xb8\xe0\xb6\x2a\x4e\xcd\x73\x21\x5b\x5b\xd5\x87\xfe\x4c\x99\x10\xbc\x7f\x6d\xc8\x88\x1c\x10\x0a\xf3\xf4\x8a\x30\x20\xb1\xdc\x70\x38\xbb\x8a\x9b\xff\x33\x30\x82\xe0\xe3\xf2\x74\x70\xa3\x65\x5e\xcc\x13\x20\x18\xa2\x20\xa0\x34\xce\x03\xfe\x97\xc9\x07\x01\x29\xc1\xac\x24\x42\xa1\xfa\xb7\x04\x19\x43\xed\x83\xc1\xc7\x7d\x64\xac\x46\x13\x42\x34\xe6\x0b\x7d\x31\x18\x4d\x21\xbd\xe2\xcf\x40\x3f\xc4\x08\xe5\x1f\xe5\x0e\x13\xc2\x52\x14\x88\xb6\x68\x0d\x94\xcf\x27\xfa\x84\x30\x27\x12\xb3\x6f\xa4\x85\x87\x53\xb1\xdc\x87\x13\xc2\x23\x64\xd4\x23\x94\x74\xe4\xc6\x47\x13\x92\x25\xca\xd5\x0a\xca\xc5\x79\x3c\x21\x40\x1c\x22\x0c\x1a\x2d\x8b\x10\x3e\xf9\x83\x31\x97\x28\x7c\x15\x42\x83\xdf\x11\xb6\xa6\x89\x8b\xe9\x3d\x52\x2e\x14\xee\xbd\xab\xc7\xaa\x5d\x15\x1f\xf2\xdc\xf8\x8d\x96\xc3\x4e\xa1\x76\x55\x78\xcf\x34\x25\x76\x6e\xa0\x72\x21\x59\x31\x3b\x7f\xea\x16\x4d\x1d\x6a\x1c\xff\x7a\x5e\x61\xf6\xb1\xe9\x4f\x9a\x81\x91\x83\xb9\x76\x5e\x95\xcd\xc6\x17\x76\x9a\x7e\x02\x49\xa8\x04\xac\xc1\xbb\x7a\x12\xc2\xd2\x5c\xf6\xc8\x1f\xe7\xc2\x25\x6b\xd6\x8f\x55\x0b\xf3\x64\xc4\xe2\x3e\xda\xff\x30\x21\x80\xc0\x98\xab\xed\xf2\x9e\xee\x12\x8f\x92\x24\xd4\xe0\x3e\x77\x48\xff\xf9\x30\x79\xfa\x0d\x53\x42\x71\x0a\x0b\x49\x57\xbc\x69\xdc\x00\x16\x30\x86\x76\x0d\xbb\x82\x7f\xfc\xef\xa5\x4a\x0b\x4d\x52\x61\x53\x0f\xd7\xb8\x0a\xba\x32\x0b\xa1\x6a\x92\xa6\x16\x03\xe8\x12\x7e\x8e\xbd\x51\x69\x92\x6a\x60\x2e\x53\x29\xbb\xa1\x7a\x38\xc2\x0c\xba\x93\x64\x71\xa6\x3c\x88\x08\x37\x93\x43\x70\x94\x64\x8c\x47\xae\x84\x78\xbe\xad\xea\x9d\x6c\x96\x61\xa9\x34\xc9\x4c\xc2\xd1\x87\xe4\x3a\x4c\x78\x89\x4c\x94\x33\x84\x0f\x81\x79\x08\x37\xbd\xe3\x5e\xdf\x09\x64\x0a\x18\x60\xad\x57\xbb\xb0\x27\x9a\x95\x0e\x12\x69\x24\xf2\xc0\xf4\xb0\xd1\x4b\x94\x70\x6e\x30\xb5\xc3\xdc\xe1\x4b\x59\x2e\x8f\x27\xda\x2a\x1c\xf9\xf7\xab\xeb\xdf\x89\x22\xd1\xc4\xf0\x18\x8b\x33\x2f\xab\x60\x38\x4d\x13\x60\xda\x04\x65\x0e\x79\x80\x55\x69\x56\x7d\x99\x27\x01\x11\x21\x0f\xde\x4d\xb9\xcf\xab\x09\xa6\x2e\x01\x21\x33\x9f\x57\xea\x33\xc1\xd3\x4f\x07\x89\xc6\x1d\x6b\x5d\x15\xc5\x75\x4f\x95\xa2\x89\x25\x0a\x61\xdc\x7b\x79\x3c\x76\x33\x8a\x7c\x7d\x05\xb3\x54\x98\x49\xa3\x48\xa0\x10\xe4\xd3\x47\xd9\xbd\xd9\xa7\xff\xfe\x23\x1c\x60\x1a\x6d\xfa\x9c\x94\xce\x88\x6b\x37\xdf\xb9\x7e\x3a\x85\x7e\xf6\xf7\x39\x12\x68\xd4\xf3\xc3\xb5\xc1\x28\x27\x7d\xfb\xd5\xc7\xb6\xe1\xae\x88\x34\x98\x6d\xbe\x7b\xba\xbf\xbe\xf9\xaf\xfe\xaf\x96\x63\x59\xdd\x89\xb3\x85\xbf\xc6\x99\xb2\xde\xe7\x0a\xc5\x90\xc2\x9f\xa5\xab\xbc\x79\xbb\xd0\xcf\x36\xf1\xa1\xb5\x62\xc1\x41\x6c\x5b\xc8\xe6\xcd\x65\x0b\xbb\x88\x79\x3a\x14\xba\xed\x14\xa2\x5c\xa4\xd6\xa7\x5a\xea\x80\xaa\xe9\x42\x2a\x04\x7f\xf5\x38\x93\x86\xfc\x5a\xd7\x6c\x38\xa3\x72\xbc\x7e\x97\x2c\xbc\xed\xd6\xbf\x1e\xf2\x93\x32\x02\xd1\x20\x11\xb2\xf8\x69\x19\x73\x72\x90\x4e\xfb\xd7\x7c\x1a\x01\xfa\xe6\x3c\xd6\xd6\x33\x51\x6e\xb0\x2f\xf4\xde\x12\xc3\x3a\x95\x72\x2b\x31\x84\xb9\xd9\xae\x5f\x9e\xbe\xef\xbf\xaf\xee\xef\x83\x81\x01\x4d\x85\x20\xa0\x7c\x76\x05\xe0\x6f\xd8\x1f\xc7\xfe\xce\x34\x15\x59\x8c\x32\xba\xbb\x6a\xa2\xb7\x43\xd3\x44\x28\xd4\xed\x2e\xe1\x23\x08\xf3\x3b\xe5\xa1\xf9\x8b\xf2\x8f\x39\xee\x2b\x49\xa6\xd1\x2b\x56\x57\x95\x43\xd3\x2e\x19\x41\xd0\x34\x63\x3c\xf8\x82\x8d\x11\x5d\xf3\xe8\x24\xcd\x52\x8e\xe1\xd7\xeb\xf9\x30\xec\x94\xd3\xcc\x52\xee\x53\x3f\x8f\xa7\xc3\x1a\x29\x07\xd3\x89\x22\x95\x91\xb3\x34\x3d\xca\xba\x8d\xa3\xd9\xfe\x38\x95\x2c\x45\xea\x91\x71\x13\xd8\x55\x21\x35\x0a\x1b\xde\x56\x35\xfc\x18\x9a\x29\xa3\xd1\x45\xb2\x05\x79\xa0\xe3\x70\x3a\xd5\x7e\xa6\x1d\x70\xb0\x3d\x22\x9c\xa6\x5a\x50\x1c\x2f\xf2\xc7\xc8\x9c\x98\xa6\x5a\x52\x04\x2c\x6b\x87\xb3\x1e\xa7\x8a\x52\x23\x20\xe2\x13\x48\xd3\x58\xc4\xe8\x93\x2e\x02\x8a\x38\x87\x1d\xf9\x0e\xc1\x8f\x77\x79\x56\x4f\x6d\x24\x70\xfa\xdf\x3e\xdd\xdf\xfc\x02\xa0\x99\x5a\x4e\xc4\xa0\x25\x34\x12\x0b\x0b\x81\x66\x6a\x13\x47\xf9\x09\xa5\x44\xb7\x65\x9f\x6f\xe0\xb2\x28\x12\x36\xf6\x01\xd2\x69\x36\x4f\x66\x91\x8a\x30\xee\xad\x6d\x5e\x9a\xe7\xf6\x62\x8f\xb1\x1c\x0a\x64\x84\xf5\x92\xa3\xa8\xe8\x5d\x95\xa7\xc6\x77\x9c\xab\xf3\xee\x7c\x9c\xa1\x1b\x49\xf8\x59\x12\xc7\xd9\xa0\x18\x8a\x3a\xf4\x2d\x1c\x3e\x29\x24\xcf\xaf\x29\x89\xf6\x8f\xbb\xc7\xa4\xd3\xbe\xc9\xff\x9e\xad\x4a\x19\x01\xc7\x80\x09\xbc\xdd\xe6\xe9\xe3\xa2\x2e\xd4\x35\xc2\x72\xff\xf7\x7f\xa4\x3c\x41\xb3\x98\x19\x94\x2d\x7b\x38\xef\xc2\xa2\x78\xf1\x9e\x16\xe6\x99\x8c\x31\x89\x62\xbf\x2e\x03\xf3\x7d\x77\xb3\xfc\xa9\x33\x96\x32\x14\x93\xdd\x54\xa7\xb1\xcf\x31\xcd\x98\x15\xd4\x29\x63\x1f\x8e\xc5\x80\x53\x5b\x3e\x0b\xe7\x0a\x23\xe5\xad\xc3\xa3\x3c\xcf\x7d\xe6\x3f\x79\xad\x5c\xba\xb5\x14\xe5\xba\x1e\xbf\x3e\xf8\xf4\xd6\x7e\xfb\xe7\x7d\xb8\x0d\x11\x01\xe2\x17\x1d\xa9\x6f\x59\x11\x79\x3a\x20\x32\x41\xb3\xd8\x23\xff\x7f\x2f\xad\x40\x33\xc1\xb9\x76\x16\x99\xed\x53\xf9\x45\xd6\x5d\x7f\x0f\xd1\x56\x96\x50\x07\xcc\x09\xb1\xf4\xd5\x6a\xd7\x1f\xe2\x80\x99\x84\x67\x79\x94\x57\x20\x27\xa5\xfc\x2c\xc9\xd2\x90\x96\x7e\x84\x8f\x6e\xfc\xdf\xc3\x0f\xf8\x64\x0b\x92\x25\x32\x0e\xeb\xd9\x38\x11\x3d\x6f\xa5\xf5\x40\xb3\xbb\x95\x45\xa1\x46\x26\xdd\xcb\xcb\x55\x96\x58\xaa\x1c\x52\xde\x69\x2c\x48\x27\x35\x3a\x83\xef\xfd\xb3\x81\x97\xb2\x0c\xa3\x92\xa0\xa4\xd1\xc0\x48\x57\x66\xd6\x94\x47\xa9\xcf\xa3\xc9\x7e\x2f\x9b\x65\x34\x52\xb2\xd7\x90\xcb\x0f\xa7\xc3\x90\xb3\xc8\xb2\x24\xb6\xbd\x42\xd3\xd2\xdc\x34\xbb\x9b\x2c\x8b\x63\x97\x80\x45\x63\xd7\xbd\x0c\xce\xa9\x34\xcb\x6c\x46\xed\x90\xe6\x35\xb7\x43\x81\x3b\x93\x91\xa3\x33\xf8\x6d\xbb\x83\x4c\x4f\x40\xf8\x99\xd4\xde\x0d\xe4\x74\x7e\xa8\xca\xd3\x18\x62\x36\xbb\x07\x69\x2d\xf6\x0e\xcc\x44\xf8\xda\x87\xd3\x4c\xac\x96\x28\xa7\x43\x59\x61\x76\x1e\x15\xbb\x74\xf1\x4b\xb7\xec\x34\x10\x1c\x61\xc2\x0a\x94\xa9\xd8\xe9\xc7\x34\xd0\x7e\x71\x86\xa6\x88\xde\xdc\xce\x0d\xb4\x69\xa6\x32\x12\xf4\x3a\x76\x68\x8f\xff\x02\xdd\xb8\x69\x9e\xa1\xf6\xea\xbe\xee\x0f\x50\x3b\x62\x5d\xb8\x82\x91\x96\x0c\xa0\x39\x88\x27\x2f\x9f\x45\xe1\x9f\xc5\x15\x28\x33\x4a\xe1\xee\x34\xd7\x55\x99\xeb\x31\xed\x8f\x66\xc6\x3a\x1f\x78\xdd\xa3\x69\x66\xa0\x9b\x0c\x24\x75\x2e\x33\xad\xac\xdb\x6f\x15\x3a\x23\x82\x3c\xcc\x1e\xcc\xda\x04\x85\xfa\x6f\x1f\xc2\xd4\x20\xa3\x44\xe0\xa7\x7c\xcd\xed\x45\xf2\xa9\x6f\x92\xe0\x42\x86\xc5\x27\x14\xe4\x18\xdf\x9c\x24\xa9\x48\x7a\x78\xd6\xbe\x96\xba\xd7\x9b\xa2\x92\x48\x2a\x3d\xcc\x6d\xcd\x6e\xc3\xfe\x39\xd8\x0e\xd6\x5d\xc7\xb9\xd4\x7f\xec\x7e\xe6\x50\xcd\x7f\x41\xf3\x38\xb7\x1b\xfd\xd5\x3f\xf3\x6a\xd5\xaf\xf0\x4d\x92\x58\xa7\xed\x74\x07\xed\x83\x2c\x73\x0b\x4d\x5b\x5d\x9d\x7b\x63\x97\xe5\x51\xed\x7f\x1b\xa7\x09\x6e\xc1\x67\xe6\x5b\x9f\x2d\x80\x41\xef\x7a\x1c\xde\x49\x9a\xc4\xc2\xe5\xaf\xab\xe3\x7f\x9d\xe0\x04\x23\x35\x18\xdf\x84\x11\x8b\x68\x7d\x03\x8d\x86\xb2\xfd\x57\x78\xad\xcc\xc6\xa8\x17\xf1\x11\x92\x58\x4f\x47\x40\x31\x92\x59\x6e\x45\x72\x12\x3b\x0c\xa9\x7c\x07\x23\xf3\xe2\x7c\x71\x5c\x62\x1d\xb9\xaa\xa5\x2e\xf2\xbf\x01\x05\x08\x9c\x7b\xe5\xa4\x7f\x49\xc1\x9d\x10\x9d\x93\x3f\x09\x0e\x5e\xb3\xdb\x15\x69\x86\xb7\xfb\x2a\x0f\xf0\x14\x38\x3d\x52\x48\x83\xba\x6e\x68\xea\xbe\xc2\x4a\x83\xd3\x6b\x5e\x4e\xba\x4b\xa1\x5c\x59\xff\x28\xcf\x83\x77\xf6\xf2\xdc\x21\x13\x95\x44\xce\xa6\xa0\xeb\x4e\x65\x65\x20\xa4\xa4\xc3\xd5\xb3\x28\x43\xf1\xb9\xe7\x97\xcd\xfa\x66\xff\xb2\xda\xdd\xec\x77\x5f\x36\x2f\xa1\x92\x26\x25\xcb\x78\x3a\xf2\x93\x43\xa2\xf8\x64\x2a\x93\x32\x73\x34\x74\xa7\xe6\xda\xb3\x4e\xa4\x22\x31\xd6\x7c\x82\x83\x51\xff\x77\x93\x40\x3c\xd2\xa8\x0b\x62\xd6\xcb\x28\x60\xa9\x19\xc3\x9d\xf2\x01\xe7\x92\xbc\x7c\x9d\x08\xaf\x75\xc7\x25\x92\x5b\xd1\xbb\xd6\xab\x06\xf5\xd7\xd2\x59\x8a\x95\x92\x90\x9e\xd9\x5f\xe7\xd6\x42\x17\x13\xef\xa5\x2b\x00\xed\x2b\xbb\x97\x98\x85\xda\xb7\xd5\xfe\x20\xcb\xf3\xe7\x08\x2e\x09\x51\x8a\xf1\xca\xcd\xee\x71\xbc\x12\x4b\xe0\xb1\xf0\xca\x92\x6b\xa8\xbb\xc7\xd1\x63\x97\xf4\xff\x57\xff\x4e\x87\xf1\x85\x4a\x3c\x95\x20\x62\x9c\xe6\xf6\x58\xe4\x9e\x7e\x26\xf0\x5e\x0e\x3e\xa4\x6d\x6e\xab\xba\xd7\x51\xe9\x5f\xb6\xa5\x9a\x45\x01\x1d\x33\x06\x90\x4d\xce\xa5\x22\x22\xd3\x81\xef\xb6\x5b\x3d\x75\x7d\x03\xca\xd6\xf9\xd6\x5f\x14\xc5\x7f\x2b\x1c\x46\x15\x61\x1a\x51\x91\x2d\x56\xa4\xa7\x03\x47\xc5\x54\xe1\x5d\x69\xdc\xd0\xc2\xe9\x50\xb8\x64\xf7\x63\xbf\xb6\xa8\x58\x33\xd4\xae\xf2\x22\x41\xb9\xaa\x65\x3d\x1b\xcd\x2a\x36\x09\x56\x07\x9a\xfc\xb5\xbc\x95\xba\x37\x8a\xf4\x87\xbb\xe5\x5e\x06\x32\xa7\xaf\x8b\x7f\xa2\x9e\x4f\x15\xd5\x29\x0e\xf8\x23\xe8\x3e\xf3\xa5\x58\x04\xca\xeb\x90\x9a\xbc\xbd\xf9\x0f\x5a\x83\x5c\x76\xa7\xd0\x3a\x91\xa8\xf3\xd4\xcf\x52\x7b\x69\xcc\x79\xac\x23\x31\x4c\xf9\x8a\x65\x24\x75\xf0\x54\x2f\xe0\x3d\x3b\x57\xe6\x08\x22\x57\xa7\xda\xed\xe0\x7d\x3e\x78\x92\xe9\xfe\x07\x21\xbd\xe2\xde\x32\xba\x81\x5e\x65\xfa\x16\x60\xa4\x08\x34\xbd\x2e\xb7\x8e\x6e\x5c\x05\xda\x90\xff\xbb\x88\x24\xa5\xa3\x71\x37\xec\x29\xd2\xe5\xe5\x46\x09\xc1\x11\x97\x76\x1c\xfb\x5a\x12\x3e\xa3\x8b\xa9\x94\x6a\xa2\x83\x17\xe2\x9d\x5c\x96\xe9\xa0\x2a\x55\x0e\x8f\x82\x18\x2a\xe4\x64\xf4\xc9\xe9\xd0\x42\xa7\x98\xf4\xc0\xa2\x33\xc6\xcd\x24\x0a\x20\x31\x95\x41\x86\x59\x34\xb4\x88\xa5\xb3\x67\x96\x54\x66\x49\xc8\xd8\x83\x3c\x38\x29\x91\x85\xfc\xaa\x92\x52\x58\x36\x18\x60\x57\x47\x28\x83\x9c\xab\x6f\x61\xb8\x65\xf1\x44\x84\xc3\x55\x7c\x67\x97\x34\x1e\x7f\xdd\xad\x85\x23\xf6\x9e\x82\xcc\x20\x8e\xe0\x58\x48\x3d\x58\x9f\xce\x53\x59\x0a\x94\x46\xe0\xa9\x0b\xaa\xb7\x50\x14\x88\xac\xbb\xad\xea\x55\xfb\x56\x40\xbb\x6c\xf5\x83\xbf\x43\xbb\x94\x7d\x3d\xe4\x16\x94\x25\x5a\x79\x09\x20\x79\xbe\x0e\x9e\x0a\x18\x1f\xf7\x4d\x98\x88\xb2\xbe\xdc\xb5\x83\xc3\xb1\x18\x28\x0d\xae\x8d\x8e\xd2\x04\xa1\x73\x9b\x52\x3b\x86\x05\xd4\xf4\x8f\x70\xcc\x18\x84\x56\xdf\x57\xaf\x8f\xf0\x31\x32\x16\x5f\xec\x3a\x9a\x44\x29\x63\x83\xf6\xd3\x3d\x58\x94\x2b\xc0\x9c\xc1\x8b\x1c\x95\x0e\x34\x49\x34\xf7\x48\x00\x9f\x04\x5c\x04\x40\x6a\x62\x63\x5c\x73\x4e\x65\xa1\xc2\x6f\x63\xe2\x14\xce\x42\x2c\xb0\x31\xf1\x31\xa4\xac\x66\xd9\x71\x1d\xa7\x26\xf0\x25\x9d\x30\x93\x9b\x3e\x6f\xab\xfa\xf6\x74\x59\x23\xd7\x71\x0a\x41\x35\x15\xbb\x51\xc8\x68\x0f\xf2\x8e\x54\x53\x65\xbc\xfc\x2b\xce\x2b\xbe\x14\xfd\xe9\x52\xa5\x99\x76\xce\x33\x07\xf9\x0e\x1e\xc0\x50\xcd\xaf\xcb\xb4\xc6\x34\x11\x42\x8d\x2e\x04\x4e\x96\x07\xaa\xe6\xc4\x39\xe4\xb4\x6f\xd0\xe0\xb6\xfd\x75\xe8\x90\x9a\x0b\x97\xb9\xc4\x60\x0a\x3f\x40\xd3\x1f\xca\x9c\x65\x30\x02\x98\x17\xd5\x0b\xa8\xe6\x40\x47\x36\x7e\x57\x2f\xab\xd9\x0d\x8b\xd4\x62\x2e\x6f\xb5\x19\x89\x63\x51\x1d\xc0\xb4\xb2\x46\x84\xd1\xd7\xb2\xa9\x8a\x5f\xf9\x8a\x52\x9d\x70\x30\xbe\x23\xdc\xc9\x16\x3e\xe4\xf9\x6a\x76\xa9\xc4\x24\x8e\x5a\x7e\x3a\xf8\x1d\xa8\x3c\xf7\x61\x93\x4e\xac\xd3\x0b\xf4\x28\x2a\xa4\x15\xb0\x31\x8e\x42\xa7\xc4\x89\xe5\xae\x6a\x95\xb7\x17\x5f\xbc\xdb\x89\xc6\x7e\x23\x6a\xab\x7a\x96\x34\xd4\x32\x15\x48\x20\xda\x77\x61\x57\x2d\xd5\xb3\x13\x3d\x93\xd3\x69\x41\xab\xd8\xa2\x7e\xff\xe6\x71\xb3\xdb\xac\xee\xf7\xdb\x9b\x9b\xeb\xfd\xed\xea\xe5\x61\xf3\x78\x37\x45\xf1\x68\xad\x63\x04\x97\xed\xa3\x9f\x1e\x2c\xbb\xee\xc5\x5f\xba\xa3\xa9\xf2\x51\x1e\x2e\xb1\x43\xa8\xd7\xf7\x3f\x6d\xb4\x76\xb1\x76\x2b\xf3\xa2\x79\xb2\xdf\xf3\xd2\x54\x1f\xe1\xb0\xe1\x40\xdc\x61\x75\x7a\x0d\xee\x96\xf0\x26\x47\x42\x15\xd3\x7b\x37\x8a\x93\x64\x1c\x99\xb5\xd5\x3e\x9a\x3d\x1f\x08\x67\x18\x61\xaa\x97\xea\x54\x40\x3b\xb2\x77\xfe\x75\x4d\xa1\xef\x50\x90\x4a\x07\x37\x76\xf6\xe6\xcf\x4f\xb3\xef\x60\xa5\x33\x7f\x39\x95\x0b\x02\x2c\x54\x5b\x65\x3c\x9e\xe0\x47\xf5\x3e\xb2\xb7\x9e\xb5\xd2\xdc\x0e\xd3\xeb\xa3\x3c\xc0\x0b\x74\x73\x9d\x6e\x61\x22\xf5\x4c\x0d\xe1\x8e\xd7\xb1\x7d\x93\xa6\xfa\x18\x87\x90\x26\x66\x71\xd0\xec\x77\x18\xc9\xe7\xaa\x9e\x2d\x03\x86\xd9\x8c\x89\x50\x11\x8f\x02\x29\xca\x1f\x0c\xe3\x52\x23\x08\xfb\xd2\xa6\x90\x1a\x1e\x5b\xd4\x90\x7b\x3a\x42\xe9\x47\xd0\xe4\x16\x38\x4d\x91\x8b\x83\xa4\x11\x2b\x35\x2c\xb8\x14\x0e\x92\x4c\xd4\x88\xd8\x69\x9f\xc9\xc3\xa6\x1f\x8b\x46\x08\x97\x30\xf7\x78\x84\x6e\xb5\x6a\xfa\x63\x89\xc5\x31\xd5\x05\x3a\x7e\xe2\xdd\x55\x77\xc3\xbe\x67\x79\xb0\x9a\x84\xc7\xd9\x90\x6a\xc1\x95\xa0\x9b\xdf\xaf\xa4\x7e\x87\x91\x5c\xf6\x3c\xec\x5c\xec\x77\x26\xe5\xb1\x97\x36\x3e\xb5\xa6\xfa\x28\x47\xf5\xad\xfe\x3e\xd3\x34\x32\x1e\x3e\xf8\x1c\x6c\x3e\xbb\x06\xeb\x81\xee\x36\x8f\xe6\x4c\x2a\x33\xac\x8f\xb4\x6f\x70\x5d\x95\xef\x70\xfe\x73\xa0\x02\x9b\x54\x49\xd4\xbe\xe8\xa2\x3c\x4c\x08\x7f\x96\x0c\x9b\x74\x2c\x93\x02\x4b\xc7\x65\xe3\x31\xc9\x62\x29\x7a\x33\x92\x19\xcc\xf1\xac\x8e\x55\x51\xa0\x3f\xc6\x72\x32\x77\x31\xa6\x35\x2a\x12\x78\xb9\xdd\xd3\x6e\x75\xbf\xfd\xb2\x1a\x48\x6b\x46\x11\x57\x44\x91\xc6\x3c\x57\xcd\x27\xa9\x2a\xa3\x52\x40\x6c\xc6\x97\x87\xf5\xa4\x63\x29\x15\x27\x8e\x4e\xf3\x43\x16\xb9\xb9\x14\x92\xa7\x46\x69\x8e\xb5\x60\x57\x74\xfc\xd7\xd3\xcb\xc5\xe6\xe9\x34\xe0\x37\x8d\xb2\x96\x79\x08\xd4\x1e\xfd\x2b\x50\xae\x62\x9f\x97\xfb\x66\xbc\x03\xf1\xad\x75\x94\x38\x95\x16\xc7\x37\x19\x21\x43\xc2\x0d\x6a\xd0\x08\x59\x5a\x57\x87\xa3\x2c\x3d\xab\xe6\x1f\x78\xd5\x52\x63\x12\x29\x7d\xa5\xf6\x4a\x96\xef\x8f\x23\xa3\x71\xdf\x02\x04\x18\x31\x04\x5f\x5d\x10\x3d\x6c\x92\x0d\xc8\x58\xba\x82\x74\x89\xd2\x76\x37\x3f\x75\x71\x32\xfd\xb4\x6b\x6c\xe2\x00\xa7\x57\xd7\xf2\x3c\x79\xa7\x36\x31\xb1\xc7\xc1\xb8\xa9\xcb\x95\xee\xc6\xd8\x12\x63\x8d\x43\x4e\xe5\x8d\x17\x7b\xbc\x3d\xf5\x09\x4c\x63\x81\x5b\x84\x49\xf8\x3f\x40\x44\x35\x7a\xf4\x7e\x39\x1d\x64\x79\xf3\xb2\x8e\x63\xfa\x0f\x61\x10\x10\x09\x90\xde\x06\x60\xd8\x2a\xfc\x63\x39\xd4\x70\x92\x84\xa6\x41\x42\xb6\xfa\xd1\xed\x39\x7c\x72\xa3\xdb\x55\x8e\x1e\x0b\x88\xd7\xf6\x97\xa8\x2c\x3c\x82\x49\x03\xc9\x24\xce\x60\x0f\xab\xc7\xd5\xdd\x0d\xea\xfb\xdf\x3f\xad\xff\xbc\xb9\xf6\x8e\x23\x7d\x3b\xa5\x30\xeb\x61\xe0\x3f\x27\x38\xc1\xa6\x7c\xed\x69\x00\x10\x93\x0c\xd4\x04\x43\xf6\x99\x4b\x1e\x85\x98\x0b\x17\xe7\xc9\x03\x6c\xcc\xdd\x5c\xba\x91\x42\x2c\x23\xdc\x90\xff\xbb\xca\xcb\xb1\x87\xde\xf2\x80\x07\x2a\x9c\xb6\xaf\xad\x4e\xb5\x37\xef\x9b\xa9\xd2\x51\x60\xa9\x41\xd1\x84\x7d\x73\x6c\x7f\x2f\xb6\x36\x3d\x3f\xcb\x34\x0f\x04\xb1\x2e\xc8\xc4\x98\x62\x31\xb9\x1f\x7e\x00\x60\x1c\x28\xb0\x7b\xf8\x85\x29\x07\xb8\x56\x68\xaa\x81\x3b\xc0\x95\x31\x6b\x98\x89\xdf\x40\x92\x2a\x9c\x15\x94\x37\x5b\x4c\x07\x67\xc6\x34\x34\xb1\x14\x03\xb8\xcd\xfa\x09\x35\x62\xfd\x9f\x53\x42\x64\x2f\xdb\xe8\xd2\xa1\xa7\x63\x7f\x90\x2a\xb7\xf7\x91\xe7\xb1\xd4\x2b\x85\xd4\x28\x35\xe1\x9e\x74\xaf\x70\x4a\x13\x99\xf5\xbc\x2c\x73\xaa\x1f\xbd\x09\xd3\xd7\x12\x15\x08\xc0\xec\x76\xb3\x87\x91\x91\x40\x94\xe4\x51\xea\x77\xf9\x0a\x37\x3f\x51\xf4\x69\xf2\x46\x24\x27\x68\xd2\xfb\x70\xb3\xfd\x32\xeb\x0e\x2a\x71\x76\x16\xda\xcd\x33\x63\x11\x4a\x3c\x18\x34\xa8\xb6\x5d\x54\x64\xae\xa1\xd1\x75\x7e\xbc\xcc\x24\x82\x8e\xc4\xe0\x6e\xb1\x6d\xa5\x1e\x13\x2e\x40\x47\x4e\x30\xb3\x79\xab\x3e\x9e\xa1\x3a\x16\xb0\x29\x31\x83\xda\x37\x90\xce\x5d\xee\x42\x38\x6a\x76\x19\x63\xa3\x98\x86\xd4\xf5\x77\xc8\x5f\x40\x8f\xa1\x9c\x00\x86\x62\x14\xfd\x9f\x13\xd4\xe7\xc7\xf9\x3c\x31\xee\x47\x00\x1a\xcb\x3a\xd0\xbe\x8d\x9c\x85\xa8\x8d\x14\x49\xd9\xf8\x5b\x3d\xc8\x9f\x0b\x13\xb4\x8d\x94\xc2\x0c\xff\xde\x83\x96\xb7\xef\x79\x51\xb8\x6a\xd7\x34\x1c\x9c\x3c\x80\x25\xc4\x20\xe1\x67\x0b\x6d\xcf\xac\x7f\xae\xf3\xb2\x5b\xd0\x8b\x29\xa7\x2a\xfc\x22\x26\x13\xc5\x9e\xe6\x7e\x8c\x42\xb1\x24\xb6\x88\xb7\xc3\x64\xed\xad\xeb\x96\x4b\xa8\xbd\xae\xa1\x17\xd6\x5a\xf0\x0d\x98\x07\x0f\x96\x74\x43\xa0\xaf\xe4\x05\x41\xd4\x65\xfc\xaf\x8d\x65\x8a\x38\xba\xbe\x04\xbc\x0e\x2f\xaf\xbf\xcd\x6e\x26\xb7\x03\x2c\xf0\xae\x1a\xcf\x9f\x96\x53\x27\x93\x79\xef\x0c\xe5\xae\x2e\xaa\x61\xa1\x5d\x62\x4d\xe2\xc3\xb5\x6b\x38\x54\x7a\x39\xbd\x60\xb9\x62\xc2\xc5\x67\x76\x7b\x6e\xba\xf0\x26\x1c\xe8\x26\xb4\xee\x04\xa7\xb2\x1b\x2f\xeb\x42\x36\x8d\xa3\xe1\x4f\x1f\x5f\x88\x38\xd0\xed\x77\xd5\x91\x90\x7d\x1c\x79\x9f\x80\x30\xeb\x59\xa1\x1d\x28\xa9\x57\x5e\x2f\x8a\xea\x03\xcc\x1c\xc5\x61\x85\xc9\x70\x3d\xc6\x40\x43\xb6\x18\x8d\x23\x68\xa2\x94\xc5\x64\x98\xda\x44\x46\x59\x2f\x70\x0b\xd6\xe6\x3a\xc7\x8c\x19\xba\xb8\x2d\x99\xa3\x50\x9b\x28\xe7\xb3\xf6\x8a\x60\x10\x05\xf5\x93\x7d\x7e\xab\xda\xaa\xbf\xcb\x04\x62\x7c\x63\x35\x98\xd3\x5c\xea\xc1\x66\xcc\x61\x9b\xbc\x09\x48\x2f\x78\x3a\x49\x6d\x84\xb6\xdc\x12\xaf\x43\xe4\xe5\x40\x27\xf7\x9e\xc9\x24\xed\xc7\xff\xee\xa4\xe0\xb9\x86\xa3\xcc\x67\xd4\x29\x2b\xa3\x04\x97\x78\x0b\xfa\x6d\x55\x14\xfd\x10\x98\x21\x58\xac\x8c\x23\x4c\x6b\x7b\xc7\x93\xc5\xe8\xd0\xca\x04\x10\xd7\x91\x37\xdb\xbc\xbb\x95\x35\xca\xa4\xbb\xdc\x7e\x30\x34\x09\x4d\xd3\x04\x37\x44\xbd\x0f\x97\xd9\x16\xfd\x02\x6b\x25\xb0\x98\x0f\x3e\xc5\xdd\xe4\xfc\x9b\x0c\x8f\x55\xcc\xe5\xbf\xbc\x1b\xed\xd5\xa9\x2e\x2f\xaa\x41\x56\x29\x8d\x20\xa3\xa7\xb2\xc8\x4b\xd8\x56\x3a\x97\xc5\x68\x93\xf3\xdb\x28\xc6\x2a\x1d\x23\x51\xed\x03\xf2\x97\x51\xd6\xc8\x6a\x9e\xf6\x7e\xbc\x16\xea\x4f\xb6\x81\x56\x4b\x8b\x92\x2b\x77\xa8\x0d\xf5\x37\x8c\x2a\xc2\x56\xab\x94\x3b\x0f\x79\x14\xd3\xf4\x46\x9e\xfd\x51\x4b\xa3\x5e\x36\xad\x3a\x42\xdd\x9e\x5f\xe4\xe0\xac\xdf\x35\xc8\x9c\xbe\x1c\x82\xe2\xbe\x41\x33\x13\xca\xee\x5a\x48\x2c\x74\xdc\x57\xd5\x7f\x86\x4c\x8e\x3f\x68\x04\x37\x5e\x06\xf1\x66\xf7\xe5\xe6\xe7\x11\xba\xad\xe9\x2d\x7c\x2a\x87\x11\x7e\x97\x4a\x94\x38\x5b\x5f\xad\xff\xfc\x15\xfc\xd1\x42\xc4\x11\x70\xf7\x7c\x42\x8a\xe1\x18\x17\x6e\x81\x44\x08\x8f\xca\x9b\x07\x68\xa1\x1e\x5e\x2b\x80\xa3\x81\x07\x79\xed\xaf\x13\x1b\xb4\x59\xef\xb3\x11\x49\xbd\x75\xd4\xbe\xcd\xf5\x3b\x9c\xf7\xb6\xee\x61\x5a\xd6\x12\x85\x20\x29\xaf\xae\x38\xae\x4e\xa6\xa1\x09\x57\xd8\x29\xaf\xf2\xb6\xad\x54\xcf\x1f\xb4\x36\x73\x89\x9a\x63\xb7\x46\xd4\x48\xf2\x9d\xe6\x8a\x59\x14\x69\x1a\x39\x54\x62\xb7\x02\x1e\xbb\x79\xc2\xcf\x3f\x93\x2e\xc0\x22\x92\xc6\x18\x57\xe2\xfa\xae\xdb\xdb\x5a\x4e\xcd\x21\x96\x5e\x33\x8b\x48\xa6\x65\xf7\xed\xbe\x3f\x7d\x1f\x85\xf8\x2c\x22\x20\x10\x23\x50\x60\xae\xef\xc9\x0e\x11\x71\xd3\x37\xb1\x29\x32\xc0\xa5\x31\x3e\x4b\x05\xbb\xaa\xc7\xee\xcf\x10\x55\x2c\x8a\x49\x8a\x5c\xed\xe3\x69\x26\x98\x4d\xe2\x34\x34\x91\x1a\x1d\xb0\x70\x5b\xf5\x17\xc8\xba\x57\x1a\x61\x11\xe5\x80\xef\x41\x1e\xa0\x34\x37\xb2\x2e\xce\xcf\xe3\x6c\xfd\x2f\xa8\x3a\xe1\x04\x0a\x32\x47\x58\x5f\x1d\x8f\xa1\x14\x79\xf1\x16\x59\xca\x30\xc1\xde\x3d\x42\x78\xaa\x6e\xd7\xdc\xfc\x71\x81\x6d\x18\x90\x0f\xb3\x5a\x18\x8b\x38\x33\xb8\x9d\xd1\xb2\x79\xab\x4e\xfd\xb7\x14\xd2\x29\x7a\x39\x86\xf9\x85\xaf\x35\x8b\x84\x8e\x12\x97\x83\x1c\x65\xfc\x58\x94\x50\x27\x2d\x1c\x16\xa0\x6e\x63\xf0\x9c\x4f\xe7\x78\x16\xa5\xd4\xb9\x6a\x48\x63\x06\x0f\xc8\xb9\xce\x3f\x8b\x52\x41\x5d\x1c\x18\xa4\x11\x66\xea\x5b\x5d\x0b\x46\x3d\x8c\xc5\x4d\xf2\xf9\x01\x9a\x56\x1e\x8e\x34\xee\x9b\x78\x81\xae\x1d\xc8\x43\x17\xa5\xe4\xe5\xab\xd3\xff\x27\xe9\x43\x85\x1c\xbc\xd0\x50\xab\xcc\xf4\x13\xee\x66\xfd\x74\x29\x44\xc4\x22\x29\x15\x76\xb6\xfd\x9b\x6c\x1e\x2f\xdf\x8a\x4a\x9c\xef\x9d\xe7\x84\x3a\xe5\xf6\xc5\x70\x9a\x45\x4a\x3b\x4a\xe0\xe3\xd3\xe3\xfe\x79\xf5\xd7\xea\xea\xfe\x66\x92\x8d\x64\x91\x8e\xb4\xf4\x22\x04\x0f\xf2\x67\x7e\x38\x1d\x70\x91\xf3\xda\x85\xf9\xec\xd6\x74\xd7\xcf\x71\xf6\x3f\x95\x7d\x6a\x6d\xdb\x56\x97\xc0\xa4\xf0\x03\x6b\x71\xdd\xeb\xb6\x39\xe8\x62\x00\xe6\x6a\x9e\xe9\x9f\xfd\xc4\x24\xd6\xa1\x2c\xb1\x64\xe1\x93\x57\xcb\xb9\x16\x4f\xff\x19\xff\x13\x06\x8f\x01\x89\x08\xe3\xf5\xd3\xc3\xd5\xe6\xf1\xe6\x7a\xff\xfd\x66\xb3\xbf\x7b\x5a\xdd\x87\x07\x87\x58\xe0\x44\x3e\xb1\x71\x1d\xb2\x78\x2c\x82\x24\xb5\x8e\xf1\x53\xfd\x1b\xf4\x8c\x11\xca\x22\x50\xce\xe3\xdf\x6d\x4e\xef\x73\x0d\x65\x03\x3b\xa8\x0f\xcd\xa2\x56\x27\x23\x51\x64\xbc\x51\x09\x9a\x17\xa1\xff\xe2\xae\x96\x61\xfa\x63\x24\x22\x22\xe4\xba\x56\x3d\x53\xd9\x2d\x71\xf3\xe9\x83\x44\x19\x47\x49\xd5\xbc\x27\x65\xfc\x4e\x4f\x69\x79\x1e\x20\x51\x06\xdc\x5f\x74\x97\xe7\x87\x3f\xcf\x0a\xea\xbb\x6a\xa9\x16\xc3\x48\x1c\x09\xc6\x43\x5f\xe9\xe6\x0b\xaf\x71\xbb\x24\x98\xcf\x48\x4c\x13\x0c\xb2\x1c\xf7\x2d\x0b\x4f\x19\x33\x86\x69\x96\x5b\x00\x33\x77\x72\x1d\xad\x64\x8c\xc4\x1c\x90\xdc\xd4\x63\xf1\xbc\x89\xfa\xae\x7a\xbc\x5d\xf7\x67\x13\x10\x0d\x0c\x94\x50\x6b\x9d\x9c\x87\x46\xb1\x1e\x89\x09\x10\xb7\xd9\x08\x8e\x5a\xe9\xec\x2b\xd1\x58\x23\x60\x65\xae\xca\xf2\x79\xc5\x9c\x11\x1c\x17\x6e\x22\xeb\xe6\xa2\x2e\x28\x98\xcb\x71\x31\xc2\x48\xe4\x74\xca\xe4\xcf\x9b\xdd\x97\xcb\x9d\x15\x23\x22\x02\x1d\x60\x81\xa1\xe6\xdd\xdb\xde\x84\x36\xa9\x43\xb8\xb7\x5d\xdc\xea\x91\xf9\xb3\x0b\x25\x56\x62\x9e\xea\xb5\x7a\x46\x4f\x8f\xf0\xd3\x54\x3b\x7b\x52\xdd\x57\x14\x96\x07\x20\x49\x8d\xa6\x4e\x5f\xe8\xb6\xaa\x4c\x33\xd1\x22\x63\x24\x23\x56\x0c\x29\x76\x7c\x8e\xaa\xe8\xdd\xf9\x18\xc9\x44\x84\x92\x9b\x5b\xbf\xa5\x71\x09\x81\x4f\xf8\x0a\xe1\x37\x3a\x4b\xfb\xec\xc2\x68\x0c\x12\x49\x62\xe5\xe7\xcb\x3f\xf3\xd6\x8b\xec\xcc\xa7\x8f\xe9\xb9\x14\xd3\x26\x1d\x65\x6a\x6f\xab\xfa\x05\xf5\xf2\x69\x38\xa9\x92\x16\xd9\xa2\x87\xbd\x33\x63\x70\xfa\x8d\xb3\xa5\x8f\x98\x48\x62\x95\xa5\x1b\x61\x7b\x23\xcf\x05\x0a\xee\x4c\xdf\x14\x08\x8d\x95\x3d\x05\x6d\x0f\x54\x67\x04\x54\xe2\x35\x14\xb0\x37\x8e\x5c\x39\x9a\xf9\xef\xad\xd4\x83\x6e\xe1\x6d\x0e\x85\x69\xa6\xb9\xba\x74\xf6\x6d\x2c\x4d\x10\xd6\xfc\x56\x7d\x3c\xf4\xe9\xd1\x55\xdd\xcd\xc5\x0e\xfb\x58\xd5\x0f\xe1\x46\x62\x92\xc5\x11\x73\xb4\x07\x74\xc8\x74\xad\xbb\xd1\xda\xb7\x00\x9d\x3a\xb8\xf1\x50\x83\x62\x71\xcc\x32\xed\x95\xcb\x5d\xe5\xd6\x91\xde\x4d\x7f\x3c\x8b\x13\x73\x31\xe8\x26\x37\x1a\xc7\xca\xb9\x83\xbf\xc8\xbc\xf8\x7b\x1c\x4b\xc5\x94\xf0\x44\x05\x97\xd9\xf2\x17\xd9\x20\x16\xb3\x54\xf2\xa1\x66\x74\x5d\xcb\x8f\xb9\x8d\x25\x8b\x59\xe6\xf2\x62\x07\x59\x9e\x64\x71\x75\x3a\x2f\x2c\xa9\x31\x53\x2c\x98\xa3\xfa\x05\x05\xfd\x1f\x26\x5f\x3c\x66\x36\x43\xb5\xab\xcd\xc3\xcd\xe6\x21\xdc\xad\x48\x23\xbc\x85\x23\x2e\xb3\xbb\x0a\xe7\xe3\x4d\xe3\xd1\x95\x7d\xab\x0c\x4c\x36\x0b\x49\x16\x8b\xb7\x61\xce\x88\x85\x64\x41\xdc\x7d\x0b\x45\x91\x97\xaf\xe3\x6a\x84\x6f\x94\x44\x46\xb9\xc9\xb9\xb0\x28\x14\x7b\xd2\xed\x78\xb3\xc1\xe2\x94\x18\xed\x01\xbf\x9e\xf9\x7d\x0a\xfb\x67\x34\xda\x72\xd1\x33\xce\xb3\xf3\xad\x2d\x8b\x53\x6d\x53\x2f\x6a\x50\xfd\x18\x04\x4c\x7f\x0f\x12\x62\x71\x96\x44\xb1\x67\x54\x6d\xcc\xcf\x2b\xd9\xea\xb7\xab\x73\x17\x5e\x95\x7d\xda\x3d\x8e\xc2\x6a\x15\x67\x69\x1a\xf2\xc9\xf7\xd5\x6b\xb5\x38\xdf\xc7\x52\x30\x24\x91\x5c\xef\x5e\xc2\xf4\x1e\x4b\x6d\x33\xe3\x89\x3b\xd7\xdb\xab\xcd\xe7\x2c\x06\x16\xab\x10\xc9\xbd\x81\x7e\x07\xb3\xcf\xfb\x1e\xa7\x52\x40\x86\xa4\xd3\xf7\x7f\x90\x75\x17\xa0\x2d\x56\x35\x66\x32\x18\x2c\x56\x9a\x26\x7e\x27\x89\xf4\xe8\x75\x85\x2f\xd4\x19\x32\x4d\xdf\xa6\xb2\x4e\x4f\xd5\x8b\x90\x86\x6a\x55\xd9\xae\xe5\x71\x97\x43\x1d\xcf\x3e\xae\x26\x09\xe2\x59\x07\xd7\xef\xb1\x94\x16\x8b\x35\xe3\x28\x6a\xf6\xf2\x74\xb5\x09\xe5\x1f\x16\x43\xe4\xaa\x10\x47\xe7\xc0\xe4\xc4\xfb\xbb\x69\xf3\xff\x4a\xfd\x7e\xac\xda\xd9\x5a\x3c\x7b\x47\x96\x38\x99\x2a\x53\x57\xc7\x10\xcf\xcf\x63\x8b\xd8\x5a\x37\xe9\x96\xa7\xc3\x73\x55\x04\xd8\x00\xa3\x51\x94\x72\x1f\x2a\xe2\x77\xf0\xab\x4f\x38\xca\x00\x10\xf9\xfb\x56\x57\xe5\xa9\xff\x11\x21\xae\x08\xd9\x8e\x69\x23\x61\xaf\xd2\x6c\xca\x75\x79\xee\x9b\xd2\x28\x75\xfc\x9c\x1f\xeb\x93\x8f\x30\xfa\x63\x49\x14\xf9\x7d\xf3\x71\x3c\xbe\xa7\xcf\x47\x49\x42\x30\x23\x1f\xca\xf0\x37\xab\x97\xfb\xbf\xae\x36\x2f\xd7\x7b\xa7\x97\x1c\x4e\x17\x13\x85\x84\xc4\x22\x47\x1d\xcd\x43\x5e\x4e\x57\x39\x1a\x67\x02\x4b\x45\xd7\x20\x8b\x35\x4e\x73\xd2\xf1\x97\x65\xf3\x89\xc3\xe0\x34\x0c\x9d\xf7\x6e\x4a\xa5\xc6\x37\xef\x79\xee\x93\x51\x4c\xa9\x71\xbc\x19\x94\x7b\xef\x79\xb6\x78\xc5\x7d\x5b\xed\xf5\x59\x17\x70\x0d\xdf\xf2\x30\xb3\x53\xc6\xdc\x58\xd1\x6f\xb2\x7e\x85\x87\xaa\x84\xfe\x2d\x32\xae\x50\xac\xdc\x85\xcf\x2e\xcc\xfc\xef\xea\xa0\x72\xd8\xff\xf7\xd3\xd5\xfe\xb5\x2a\xcc\x51\x0e\x9f\x8d\xe9\x34\x32\x5e\x2a\xb8\x44\x8f\xe2\x3f\xa6\xf8\x15\x46\x39\xe3\x0a\x7a\x29\xf9\x52\x63\xa7\x99\xbe\x77\x9e\x32\xcc\x3a\x14\xd5\x6b\x2f\x5d\x0f\x97\x88\xbd\xd9\xd7\xe2\x0a\x42\xed\xf0\x5e\x36\xed\xad\xac\x0f\xa3\x4c\x70\x1a\x5a\x19\x07\x1c\x78\xed\x22\x54\x7f\x65\xe2\x3e\x3c\x11\xd3\x96\x96\x60\xed\xc2\x8f\x68\xb4\xc0\x59\x9c\xbe\xa8\x50\x06\x83\x94\x6e\xc4\x9d\x1f\xf4\xba\xfb\x50\x13\x89\x43\x46\x93\x28\x25\x41\x0b\x42\xd7\xb9\xfa\xac\xcb\x25\xca\xe9\xda\xb5\xf9\x27\xb2\x09\x8c\xa6\x5c\x63\x56\x56\x36\x4d\xfe\x5a\x06\x04\xf4\x74\xfa\xa0\xa9\x88\x22\xe6\xd7\xba\x12\x8a\x66\xdb\x23\x8e\x18\xcd\x18\x08\xef\x31\xfe\xcd\x65\x53\x87\xb0\x91\x66\xd6\x7d\x41\xa9\xb5\x53\xb4\x02\x33\x10\xeb\xa6\x37\x22\x13\x9b\x04\xf5\xab\x3f\x1f\x71\xa1\x7c\x0c\xc0\x11\x46\xa5\x8c\x8c\xab\x0d\x37\x50\x5f\xcc\x20\xcb\xfb\x07\x2a\x4d\xe2\x80\x21\x32\x2f\xce\xdd\xeb\x1c\x34\x7a\x18\x55\x44\x22\xfa\xac\x39\x42\x69\x1e\xab\x5e\xc6\x8f\x51\xc5\x1c\x05\x42\x1a\xb3\xae\x0e\x17\x41\x3b\x55\x46\xe0\x00\xcd\x5b\x38\xf8\xca\xce\xf4\xba\x5a\x49\xcc\x65\x39\xdb\x64\xd9\xb6\x05\x0c\x85\x17\x46\xb5\x55\xe8\x16\xfc\xc3\xa9\xf5\x61\x18\xf3\x3c\x66\x42\x32\x0a\x9e\x65\xd1\x85\xdb\x27\x93\xb7\x61\xb1\xfc\x5a\xcf\x76\xbd\x14\x52\x13\x3b\x15\xcb\x0f\x0c\xa4\x3c\x5a\xd5\x77\x2a\x12\x3a\x95\xd5\x16\x25\xf0\x6f\x9e\xb6\x77\xa3\x8f\x67\xad\x08\x6e\x8a\xbb\xbc\x3d\x15\x32\xaf\x61\xbf\xae\x0e\xc7\x16\xf6\xde\x76\x83\xb1\x48\x51\x5c\xe9\xaf\xbe\xfe\xb5\xdf\x3c\xae\x5f\x6e\x56\xdb\x9b\xfe\x98\x21\xc2\xab\xc4\xf4\x98\xff\x49\xdf\x61\x84\x2a\x04\xa2\xcb\xbc\xee\x66\xf6\xe9\x5c\xc6\x88\x4d\xb3\xc1\x67\xfa\x7b\xde\x96\x17\x5b\x3b\x16\x93\x04\x09\x21\x0e\x83\xd9\x05\x37\x21\xb9\xc1\xe2\xcc\x41\x1f\xdc\x94\x75\x55\x9d\x5e\xdf\x7e\x6d\x79\xd1\xfd\x84\x27\x3e\x3a\x78\x39\x95\x3d\x72\x79\x66\xce\xe6\x1b\xd3\x98\xe2\xea\xfc\x73\x50\xad\x63\x8c\x5a\x57\x7e\xfd\xfa\x6d\x73\xbd\xb9\xfd\x6b\x64\xab\xcd\x18\x53\x34\x23\x13\x41\x61\x07\x76\xf6\x87\x05\xb7\x92\x0f\xc6\xfd\xe0\xc0\x42\xb3\xe7\x15\x22\x43\xd2\xba\x37\x1b\x0a\x01\x07\x4b\x22\x27\xb2\xf2\xb5\x31\x6b\x79\x74\x79\xd0\x65\x1b\x78\xc6\x92\x24\xf2\xfb\xa4\xc3\xd1\xbf\x9c\x7e\xdc\x85\x26\x3a\xc2\xd5\xba\x95\xef\xb0\xba\x3b\x41\x33\xeb\xc6\x2c\xd1\x0c\x1f\x1e\x61\xd2\xe3\xf9\x87\xa5\x29\x89\x9d\xa6\x14\x22\x67\xbd\xcf\xde\xec\x31\xd2\x8c\xa0\xf8\xdd\xea\x6a\xb7\x46\x5f\x8c\xf0\xeb\x8c\xc4\xf8\xcd\x03\x4c\xfb\xb1\xfa\x21\x87\x63\x94\x2a\xbf\xb3\xf9\xaf\x53\xd5\xc2\x44\x62\xb3\x3b\xce\x85\x08\xf3\x3d\xfc\xc0\xe8\xe2\x7b\x5e\x96\x50\x8f\xd8\x34\x8c\x65\x2a\x92\x03\x5f\xe1\xe1\xeb\xfd\x6e\xf3\x7c\xbf\xb9\x79\xd9\x6f\xd6\x4f\xbc\x6f\x64\x12\xb4\x2c\x0b\x9b\xf8\x87\xfe\x88\x32\x80\xe5\xa1\xfb\xb7\xe6\x9f\x55\x05\x18\xd3\x14\x8c\x47\x1c\xef\xde\x6a\x68\xde\xaa\xc2\x6c\x51\xac\x63\x2b\x2d\xb8\x3c\xc3\xec\xfd\x6a\x16\x3b\x6b\x90\x6e\x09\x9d\xc0\xb4\x18\xd3\x89\xc1\xb2\x93\x0b\xd8\x42\x7a\xe1\x82\x8b\xfe\x0b\x6a\x0e\x63\x86\xa6\x88\xfb\xfb\x91\xc3\xc7\xfe\x15\xda\xfd\x9d\xcc\xfb\x75\x9d\x19\xe1\x42\xb8\x8f\xc1\xb6\xe6\x41\xce\xe2\x46\x66\x94\x73\x50\x78\x01\x7d\xaa\xbb\x4b\xcd\x15\x44\x7e\x05\x24\x60\x0c\x92\x04\xb1\xeb\xff\xae\xf2\xd2\x19\xc3\x85\xab\x43\x9a\x61\x6a\xef\x6b\xef\x41\x39\x12\x5e\x99\x3e\x06\x48\x81\x6c\xbc\x9b\xb8\xff\x3e\x60\x23\x67\x47\x52\xe7\xe6\x15\xfc\xb2\x53\xd5\xcd\xc8\x92\x88\xf1\x88\x13\x13\x84\xcc\xc3\xfc\xd9\x3c\x56\xed\x63\x8f\x6e\x61\x3c\x52\x24\xf6\xf3\xac\xab\xb2\xdf\xf7\x3b\x69\x0f\xf8\x67\x9c\x24\xd4\xab\x62\x97\xed\x97\x6a\xfa\x0d\xbb\x4b\x90\x50\x44\x5f\x15\xc5\x88\x42\xcd\x78\x4c\x1d\xab\xa4\xa8\xaa\xf7\xd3\xf1\x92\x85\x37\x91\x03\x1c\x50\xfc\x8c\x53\x9a\x04\x5d\x87\x9b\xf6\xed\x25\x94\x3b\xfa\x3b\xa2\x29\xc1\x64\x8c\xdb\x33\x7c\x1b\xab\xea\x8d\xfb\x24\xa7\x59\x82\x69\xe6\x53\x03\x8f\x50\x95\x0f\xb2\x56\x05\xcc\x66\x57\x4e\xa5\xd3\xba\x40\xa4\xf3\x21\xdc\x3b\xe3\x60\xd3\x50\xfb\x7f\xcd\xab\xb2\xe7\xd1\x3e\xe7\x3f\xa1\x78\xfe\x3c\xce\xe5\x4c\x08\xf4\xc9\xc7\xe4\x65\xb7\x77\x2c\x9b\x53\x8d\x94\xe8\xc9\x50\xe6\x9c\x02\xea\xf6\x3a\x50\xdf\x62\x56\x8f\x0b\xad\x30\xac\x47\x41\x9c\xf0\xc3\x24\x32\x2e\xa8\x68\xba\x58\xe0\xe6\x3f\xdc\x75\x1c\xee\x46\x05\x0f\xad\x48\x8c\xb1\xe6\xc1\xd1\x3b\xf7\x2a\xb0\x40\x18\x4f\x79\x84\xd9\xa6\x41\xd7\x7e\x79\xdb\xc6\x53\xc1\x10\xbf\x7b\x2c\xe4\xf9\x82\xaf\x32\xbd\xd3\x34\x8b\x1c\xff\xf2\x74\x5e\xed\x5e\xfa\x2b\x29\x93\xf8\xb4\xd9\x97\xe3\xac\xeb\x64\x29\xc7\x6a\x7e\x37\x9e\xaa\xba\xef\x35\x92\x13\x70\x4e\x65\x28\x24\x51\x55\x53\xc1\x7d\xc6\x65\xc2\x82\x7b\x12\xea\x23\xd5\xcd\x2a\x20\xc7\x87\x36\xca\x15\x4f\x5d\xa9\xf0\xdf\xa0\xdb\xcf\x50\x22\x8c\x2b\x21\x11\x28\xa0\x4e\xe7\x2b\xd9\xe4\x7a\x2d\x6b\xd3\xec\x1f\x1c\xfb\xf2\xd7\x8b\x29\xd7\x69\x1a\xf5\xee\x5b\x5f\x64\x33\xd4\x9e\x6e\xab\xfa\x79\xcc\x09\x5e\x7e\xc1\x86\xa7\xc2\x55\x9a\x54\x91\xeb\xf0\x3d\x9a\x00\x52\x0b\xad\xb4\x46\x29\xb3\x7d\x8e\x91\xe7\x53\x5f\xa6\xe1\x90\x08\xd5\x5b\x1f\x9e\x0c\x94\xad\xdb\x26\x4c\x22\x6a\x0e\x12\x30\x78\x44\xd3\xb1\x6f\xd5\x47\x33\x67\xda\x7f\xc2\x74\x5c\xce\xeb\x7f\xce\x99\x1c\x61\x59\x18\x07\x9d\xa2\x5d\xf7\xed\xd3\xd7\xc7\xeb\x9b\x97\xfd\xcd\xbf\xd6\x5f\x56\x8f\x77\x37\x7b\x84\x4c\x86\x07\xb0\x9c\x67\x21\x93\xb7\x1d\xe0\x70\x13\xa9\xc1\x50\x7a\xfb\xe4\x7f\x75\x13\x47\x08\x58\x44\x44\x23\x5c\x74\xdf\xa4\x4b\x1d\xa2\xd4\xe2\x9b\xac\x03\x44\x82\x89\x88\xbb\xd1\xe3\x88\xa6\x79\x75\xda\x7f\xf4\xca\x38\xa1\x89\x97\xe4\x6e\x4e\xb9\xce\x0d\x0a\xf6\x4d\xc7\xa5\x20\x91\x20\xe3\x44\xa6\xe7\xa2\xfe\xb1\x90\xa6\x10\x84\x3b\x78\x76\x2f\x25\x3f\xe7\x4c\xf5\x37\x1f\x7b\x13\x53\x97\xfa\x7c\xb2\x0b\xc1\x91\x88\x63\xd7\xb3\xab\xb2\x38\x3f\xd7\xf9\x41\xd6\xe7\x87\x61\xa7\x2f\x62\x63\x71\x50\x99\xdc\xda\xcb\x3a\xa0\x6f\x44\x95\xcb\xa3\xbb\xf0\xaa\xc8\x61\x18\x39\x82\x31\xd0\xbe\x34\xf7\x5c\x57\x87\xbc\x99\x6d\x27\x05\x4b\x9d\x49\x02\x1c\xa0\x7e\x85\x52\x9f\xf7\xa7\x1e\x04\xc0\x04\xa7\x02\x65\x33\xae\x65\x0b\x63\x59\x85\x70\x38\x85\x58\x7a\x52\x50\xbb\xc8\x2c\xff\x7f\xfc\xff\xfd\x75\x05\xcd\x30\x3a\xf1\x4a\x1f\x2b\x67\xff\x17\x0e\x6a\x8a\x34\x16\x19\xa2\x30\x91\xa4\x02\xb7\xcc\xd5\x11\xca\xde\x66\x8b\x89\xc4\x64\xda\xf6\x5a\x1c\xb3\xdc\xea\x3f\x48\x34\x88\xc4\x26\x5a\x79\x88\x76\xbf\x26\xcf\x5e\x11\x3a\x3b\xa2\xaa\xf8\xcf\xef\x55\xdd\xb4\x63\xaf\x28\x26\x32\xe2\x32\xe8\xaf\xb5\x3c\x42\x83\xa6\x6c\xe6\xa4\xe1\xaa\xea\x36\x59\x7d\x23\x91\xa2\x98\xe3\x87\xa3\x79\x62\x64\x18\x94\x71\x98\x90\x51\x86\xf0\x9c\x95\x31\xde\xe7\xab\x5d\xe4\xf7\x30\x21\xe3\x14\x77\xe2\x7b\x69\x8c\xa3\x6c\xff\xb1\x90\x55\x49\x43\x6b\x6e\x0c\x04\xc6\xd3\xd2\xcb\x19\x9e\x51\x45\x9c\xcb\xb0\x44\xae\x7b\xe1\xfb\xcf\x1a\x3b\x37\xae\x63\x5d\xfd\xcc\xc1\x4c\xaa\x33\xd3\xfb\x55\x31\x0d\x02\xd2\x5e\x94\xb3\xde\x94\x3f\xaa\x5c\x43\x73\x75\xee\xf6\x21\xa7\xe5\xac\x47\x78\x02\x25\x52\xc4\x9f\x3f\xdc\xbc\xac\xbf\xf6\xba\x3d\x4c\x00\x4f\x31\xcf\x7c\x5f\xbd\xfa\x59\xf6\x6b\xa9\x1d\x81\x75\x01\xf9\x3c\xbd\x27\x48\x69\x6c\xfa\xd5\xaa\x85\xd5\xfc\x7b\x43\x96\x86\xf4\xf7\x6d\x0d\x70\x5f\x29\xcc\xad\x8d\x03\x1e\x61\x09\x49\xb9\x1f\x36\x37\xed\x1b\x6a\x00\xd5\x13\x20\xd0\xe7\xf0\x3e\x26\xac\xe0\x41\x09\x73\x7b\x94\x1f\xa5\xdf\x34\x85\xe5\x21\x89\xac\xc5\x7c\x5a\xaf\xce\xf6\x6b\xbf\x03\x96\x10\x91\x22\xa6\xd4\x71\x2c\x37\xe5\x1a\x33\x5d\x53\x3a\x2a\x4b\x28\x73\x5c\x53\x5d\x1d\xcf\x23\x43\x91\x8b\x90\xf9\x52\x5f\x83\x25\x14\x38\xf2\x46\x65\x20\x84\x6d\x7b\x9c\x0e\x4b\xb8\xb2\xc8\xb7\x33\xf9\x0f\x92\x2e\x77\x9a\x84\x5b\x17\x34\x77\x01\x00\xae\xad\x7f\xc2\xf9\x2e\x9c\x40\x58\x82\x93\xd4\x03\x94\xa7\x28\x9d\xdd\x76\x22\x22\x08\xa9\x87\xba\xbd\x34\x5b\x61\x49\x92\xa4\x08\xe3\x06\x73\xe9\x0c\xe1\x9b\xa4\x51\x14\xf9\xcb\xdf\xe6\x65\xde\xbc\xf9\xde\x17\x0e\xa7\xd6\x11\xce\x7f\x94\x47\xa8\xc1\x63\x98\xc3\xd1\x2c\x4e\xf0\xf9\x72\xed\xcc\xda\x1e\xe4\xcf\xde\x29\x99\x25\x92\x68\xdc\x05\xd7\x32\x6f\x90\xa4\x88\x3c\x81\x50\xad\xfd\x3c\xeb\x99\x46\xe3\x2c\x3a\x11\x51\x38\x1f\x87\x2c\x1b\x5b\xeb\x77\xb7\xda\xdf\x8b\xb4\x59\xac\x7b\xc6\x7e\xfb\x50\x99\xd9\x7a\x90\x28\xef\x9a\x78\xac\xab\x2e\x8e\x9d\x43\x5d\xc2\xe2\x96\xe8\x28\x13\x66\x90\x72\x73\x90\xb6\x7e\x30\xcf\x53\x6e\x89\xc9\x12\x74\xe6\x1c\x29\xc7\xcc\xc2\x91\xe9\x6d\x18\x1d\xa1\x78\xce\xb1\x07\xd6\xdf\xec\xbe\xf8\xca\xdb\x1f\x7d\x1b\x9e\xb9\xcc\xa2\xbe\xe0\x7c\x5c\xe2\xb5\x58\x62\x8c\xc0\x44\x87\x3a\x9d\x6f\xda\xb7\xd9\x73\x43\x94\x39\x5c\xc9\xd3\x9f\x37\x8f\xe8\xf5\xd7\x5b\xfd\xb1\x04\x88\x63\x98\xdf\xe6\x3f\xcf\x13\x3d\x66\x96\x40\x9c\x60\x70\xf1\x21\xc7\xb4\xa2\xee\xef\x0a\xad\x18\x1c\x89\xca\x6d\x0a\xba\x57\x3e\x7b\x2f\xa0\x63\x9c\x65\x31\x7c\xb9\x3a\x95\x7d\x8a\x3e\x01\x70\xd8\x8c\xcd\xfa\xe9\x8b\xac\x8d\x1e\xba\x8c\x8d\x49\xd2\xbd\x9b\x9b\x02\x74\x5b\xf7\xd9\xc9\xc4\x32\x89\xf8\xc8\xa6\xad\x8e\x68\x23\x73\x3e\xba\xef\x96\x86\x06\xa9\xc4\x85\xc4\xb1\x33\x27\xb3\x46\x1a\x45\x31\xd1\x63\x70\xce\x35\x48\x53\xe4\xc1\x34\x84\xa5\x11\x67\xcc\x0f\xa4\xf5\xea\x69\xcc\x8c\x67\x29\x89\x39\x4a\x29\xa1\x25\x07\x22\x77\xc6\xe6\xec\x2c\x25\x3c\x41\x00\x47\xb0\xf1\x59\x56\x23\x63\x69\x4c\x04\x0a\x6e\x1d\xe4\x3b\xac\xe5\x0c\xad\x35\x45\xe9\xb3\x94\x26\x19\xe2\xb9\xaf\x76\xeb\x30\xb5\xa7\xd4\x58\x5f\xa3\x7b\xfa\x01\xb5\x1d\xd9\xcc\x4e\xfb\x57\xca\x08\x47\x90\xf7\xd5\xa9\x45\x5e\x60\x38\x01\x33\x1a\x0d\xae\x5c\xb7\x0e\xfe\x5a\xcf\x75\xf5\x23\x1f\xd1\x77\xe6\x27\xb3\x76\x52\xad\x59\xbb\xc2\x03\xa6\x67\x87\x7d\x70\xca\x55\x16\xe9\x1e\xcf\x29\x0b\xb7\x5c\x87\x2b\x0b\x02\x18\x3a\xcb\x00\x2e\x1d\xc1\x02\x43\x93\x4c\x60\xae\x2f\x6f\xae\x03\x73\x3a\xaf\xca\xeb\x99\xfc\x17\x4b\x85\x61\x48\x0d\xde\xa3\xea\x81\x59\x30\x8b\xe8\xa2\x3e\x86\x35\xa4\xb0\x48\x3c\xd7\xb0\xcd\x5f\xcb\x90\xb6\xf8\x47\xea\xd3\xa3\xb3\xa9\x04\x81\x5b\x0f\x79\x01\x4d\x5b\x95\xb0\xbf\x92\xe5\xbb\x47\xea\x78\xaf\xef\xf1\x58\x4c\xbb\xaf\xe7\x7d\x5e\xf7\x35\xfc\x1b\xa1\x99\xe1\x4d\xa4\xdc\x71\x87\x5e\x83\x81\x66\xd6\x1f\x01\x27\x7c\x88\xdb\xf8\xd6\xb3\xfe\x2f\x41\xdc\x2c\x95\x11\x75\x69\x64\x8f\x16\xbf\xad\xea\xbf\xd0\x2e\x35\x9c\x49\xc6\x84\x46\x83\xc6\xd1\xba\xdb\xf0\x35\xde\xa9\xc3\x0f\x97\x54\xd1\x14\xc9\x46\xd6\xf9\x96\xaf\xe5\xf1\x05\xa4\x7e\x1b\x6e\x54\xa5\x02\x06\x41\x08\x9f\x14\x9b\xde\x88\x8e\x24\xcd\x82\x15\xcf\x3d\xd8\x65\x99\x58\x96\x1a\x43\x70\x74\xad\xab\xa6\xdb\xfa\x59\xbb\x34\xf5\x0f\xcd\x81\x32\x64\x70\xca\x53\x5b\x1d\x64\x9b\xeb\x3e\x49\x17\xee\x0d\xac\xa2\x21\xcd\xf3\x74\x9a\x7f\x7d\x1b\xb9\x64\x29\x8a\xc3\x57\xc5\x2d\xb9\x8d\xff\x98\xa5\x6d\x52\x4b\x18\x6e\xf6\xbd\x86\x9f\x9b\x34\x5c\x62\x3f\x5c\xc4\x0a\x83\x9b\x87\xa7\x12\xae\xea\xea\xae\xa8\x54\x10\xe9\x63\xa9\x95\xe0\x85\x9d\x37\xc1\x87\x86\x65\x51\xa4\xb0\xf2\xd2\x67\xe9\x66\xa0\xd3\x2c\x32\x3c\x4b\xb1\x41\xf0\x70\x6f\x02\xde\x22\x34\x21\x8a\x39\xef\x73\x39\xf0\x02\x2f\xa8\xe0\x2c\x8b\x63\x9a\xb0\x7e\xb0\x78\xfd\x9a\x70\x8c\x29\x84\xe8\xdb\xbc\x34\x2b\x0c\xfd\x77\x6f\xe0\xf2\xae\x7d\x93\x2c\x46\xc2\x3f\x1c\x72\x17\xe9\xf5\x05\x7e\xcc\x75\xcf\x76\x90\x59\x2c\x65\xa6\x27\x80\xa2\xc7\x5c\xbf\x97\x17\x90\xc2\x8c\xb2\x08\xab\xdc\xeb\xaa\x3e\x56\xb5\x6c\xe1\x11\x3e\x9a\xdf\x27\x64\x33\xca\x00\x81\x4f\xd7\xf2\x78\xf4\xa9\xf8\x0b\x81\xfa\xff\x33\xbb\x94\x8c\x04\xf4\xe6\x6e\xf7\xd5\x54\xd4\x24\xbc\x39\xfa\xbf\x8b\x1e\xc5\x2c\x63\x24\x43\x96\xca\xde\xcd\x85\xf8\x5b\xc4\x7f\xca\xba\xcd\x2f\xa3\xd5\x8b\xdf\x27\x32\xc5\xbd\xcd\xcd\x76\xcc\x8b\x64\x59\x9a\x58\xe9\x41\x9e\x8f\x95\x81\x97\xfc\xf5\xad\x5d\xbf\xe5\xc5\x54\x4e\x80\x65\xa9\x4d\xd0\xaa\xac\x8b\x90\x65\x21\xfb\x4c\x5b\x96\x71\x8a\x1d\x73\xf7\x06\xb7\x55\x55\xbc\xc8\x7a\x52\x4e\xcc\x32\xa5\xd1\x3b\xe5\x0e\x4a\xb7\x18\x21\x1e\xfe\x6b\x03\xf5\xe6\x7a\xb6\x27\xca\x32\x00\x9c\xb8\xca\x60\xc4\xf7\xf9\x17\x90\x09\xa5\xc9\x80\xb6\x76\x68\xab\x39\xc9\x65\xf6\x09\x64\xa2\xd5\xc8\xb2\xd7\x31\xe6\x77\xd5\x28\xab\xc3\x42\x4b\x69\xd1\x81\xc0\xe7\xf7\x1c\x61\x24\x1c\x53\x19\x76\xe5\x2f\xb2\x59\xc8\x21\x64\x12\xc2\xea\x8b\x4f\x7b\x94\x4d\xe3\xdc\x35\xe6\x51\x58\xa6\x54\x6c\xc6\x38\xbf\x2d\xd4\x3f\x72\x0d\x03\xa0\x2a\xd3\x96\xa7\x9e\xf2\x8a\x96\x16\xb3\x13\x98\xc8\xe0\xf2\xb8\xfb\xd6\xc3\xed\xe7\x23\xd8\x10\x81\xd8\x8c\x2b\x6b\xaf\xab\xea\x30\xf9\x32\x26\x8b\x51\xce\xe1\x28\xeb\xc6\x7d\x9a\x2f\x20\x4d\xb0\x09\xf0\x8d\x80\x1a\x44\xef\x6d\x65\xf9\x7a\x6a\x26\xbf\x07\xa1\x90\x3e\xff\x20\xdf\xe1\xea\x74\x76\x94\xda\xdf\x30\xa0\x67\x5f\x04\x32\x41\xa4\x0b\xab\xf6\xcf\x2f\x37\xfb\xed\xea\x3e\x64\xaf\x32\x9b\x31\xe5\xed\x33\x1f\x64\xab\xdf\x1c\xf4\x64\xb4\x24\xc8\x88\x30\xec\xd3\x55\x89\x76\xb7\x63\x8b\xd9\xd0\xc2\x8a\x68\x8c\x98\x0e\xd0\x8f\x5e\x82\x09\xbf\xec\x18\xd4\x3d\x4b\x1b\x49\x42\x8c\x75\xab\xfc\x61\x8c\xcb\x90\xc4\x72\x57\x6c\x2b\x64\xee\x5e\x6b\x73\xa9\x1f\xca\x64\x6c\x23\xc4\x72\x56\x93\x97\xb3\xb8\x6c\xcb\xd8\x72\x2c\x0c\x3d\x54\x5d\x18\x11\xf4\xe4\x99\xa4\x4c\x3b\x9f\x61\xd9\xc0\xc3\xf3\xd8\xe8\x80\x49\x9a\xc4\x08\xe6\x95\xc6\x8c\x55\x92\x17\x97\x35\xc9\xe2\x0c\xf3\x77\x0e\x21\x71\xfd\x5e\x38\x16\x8d\x27\xd0\x2c\xc7\x66\x92\x51\x97\x6a\x5c\x57\xa7\xba\x59\xf2\x60\x1e\x35\xcd\x12\xcc\x68\x77\x91\xf5\xc8\x05\xee\xe6\x5f\x5f\x96\x43\xc7\x30\xb9\x48\xc1\x44\x26\x7b\xee\x59\xf7\xf3\x90\xf3\x5b\x7e\x10\xc1\x9c\x5f\x86\xc3\xe1\x91\x3f\x66\x47\x53\x91\x45\xa3\x71\x15\xce\xf5\x8f\x82\x27\x29\xa4\x48\xe5\x10\x8b\xec\x40\x1e\x42\xda\xb4\x4f\x9a\xfa\xa6\x89\x72\xd2\x8c\x6b\x59\xce\x95\x9e\x98\x4c\x23\x2d\x7c\x62\xe0\x2a\xac\xb8\x32\xa5\x62\x84\x21\x7d\x96\x4d\xf3\x51\xd5\x4b\xda\xd8\x4c\x76\x5b\xb4\xa4\x8f\x7d\xfd\x32\xd6\xcd\xf8\x41\x7b\x6c\x71\x8e\x93\x99\xca\xdc\xce\x41\x1e\xbf\xdf\x6c\xc2\x75\x33\x93\x20\x1f\xd4\x55\x35\x50\xd5\x7c\xc2\x18\x65\x52\xc5\x1a\x27\xa3\xee\xc3\xec\xdb\x6a\xaf\xf2\x20\x60\x48\x66\x2f\x48\x53\x0a\x4e\x7c\x27\x24\x5d\x67\x4f\xae\x8d\x0c\xb6\xc7\x3d\x37\x4b\xd6\xed\x55\x1e\x82\x06\x69\x84\x45\x53\x21\xa7\x03\x99\xab\x02\xae\xe1\x50\xf5\x47\x53\x48\x5d\x9a\xb5\xc1\x27\x75\xf5\x20\x7f\x10\x14\xb3\xd1\x48\xa7\xe6\xf3\x8c\x95\xb4\x52\x26\xbd\x02\x8e\x86\xfc\xd8\x2e\xc5\xde\xd2\x2a\x1e\x0f\xe2\x6e\xfd\x16\x40\x5a\x43\x30\xe0\xf4\xfa\x2a\x5f\xbb\x1f\x8d\xa7\x46\x15\x09\x82\xe5\xf8\xb5\x3c\x1c\x65\xfe\x5a\xce\x3f\xcc\xe4\x32\x2a\x4a\x0d\x23\x83\xab\x75\xbc\x6f\x5c\x80\x1f\x0e\x43\x14\x7c\xea\x51\xcc\xde\x3b\x5e\x5d\xc2\xfd\xfd\xe4\xa7\x88\xd5\xb8\x23\x75\xde\x30\x1f\xe5\x58\xfe\x93\xa9\x18\x38\xe2\x07\x8b\xea\x03\xea\xc9\x97\x56\x94\xbb\x1c\xa8\x27\xb2\x21\x83\x14\x71\x35\xf3\xd5\x33\xb4\x17\x8e\x60\x6e\xa0\x9f\x92\x14\x55\x31\x8d\x07\xb0\x78\x65\xed\xc4\xe2\x95\x29\x46\x19\xce\x7b\x56\xe6\xc5\xf7\xbc\x7d\xf3\xf8\xb1\xc9\x8d\x30\x91\x22\x94\x72\x2b\x4b\x36\x5b\xb7\x14\x33\x14\xb1\x23\x06\x5a\xa8\x0f\x79\x09\x77\x95\x2c\xb6\xba\x42\xd6\x9f\xac\xcd\xc6\x2c\x33\x71\xa6\xef\x5c\x44\x19\xf5\x3d\xf1\xa5\x2a\x8a\xaf\xa8\x7b\xb4\x38\xec\x55\x42\x39\x4a\x2b\xf9\x67\x27\x21\x5d\xad\x12\x91\xc6\xac\x9f\x6b\x7a\x0f\xba\x70\x34\x13\xc8\xb6\xca\x1b\x97\xea\x9f\xbd\xbb\x24\x73\x71\x3f\x54\xcd\xd5\x6a\x7b\xf3\xc9\xb5\x53\x2a\xd1\xd7\xd6\x62\x36\x6b\xfd\x26\x0f\xc7\xbc\x2a\x07\x91\x2d\xa6\x52\x23\x70\xb5\x59\x39\x9c\xcb\xec\x2a\x59\x9a\xa5\x49\x8f\x53\xd3\x17\xb2\xb7\x0b\xd3\x8b\xca\x24\xc3\x33\x76\x2b\xee\x7e\xbb\xbb\x09\xd9\x15\x25\x63\x81\x9b\x99\x43\xbe\x50\x89\x5f\xaa\x04\x2b\x99\x30\xde\x67\x4d\x90\x60\x1b\xce\xa5\x53\xe7\xdb\x55\x83\x34\xfb\xa0\xaa\xb6\x97\xed\x3e\xef\xd7\xf2\xe1\x2d\x68\x93\x05\xd7\xa0\x2d\x48\xf4\xf1\x0a\x4c\xc4\x0b\x7d\x95\xc9\xf2\xa1\x34\x58\x4c\x4d\x7b\x88\xe1\x30\xa8\x0c\x95\x31\xfa\x03\xe5\x50\xbf\xc8\xbc\x3c\xc8\x77\xa8\x03\xb5\x79\x31\x2d\xaf\x8c\xb4\x98\x0d\xd6\x50\xb6\xcd\xa6\x7c\xee\xee\xb8\x37\x6b\x65\x0a\x98\x63\x66\xdd\x43\x69\xea\x3f\x3e\x97\x5b\xee\x5a\x12\x84\x27\xfc\x59\x9f\x8f\x6d\x75\x3c\xf7\x21\xda\xc3\x05\x73\x41\x75\x83\x95\x78\x85\xd7\xe7\xaa\x2a\xfa\xab\x49\x47\x48\xf8\xf3\x65\xbd\xb0\xaf\x56\x56\x58\x64\xeb\x1f\x30\x93\x89\x48\x05\xff\x4b\x1d\x91\x0c\x37\xc3\x65\x85\xd9\x4f\xfc\x75\x4f\x1c\x0c\xdf\x47\x13\xa6\x3c\x0d\xb6\x28\xae\xa1\x6c\xa5\xae\xf2\xb2\x59\xbd\xca\xbc\x6c\x9c\x0a\xd3\xf4\x1b\xe9\x98\x25\xa8\x38\x7c\x90\x79\xe9\x1c\xc0\x47\x9e\x1d\x4c\x53\xc6\x10\x94\xb0\xef\x57\x06\xef\xe7\x3c\xee\x2f\x9a\x82\x09\xe9\xe3\x2f\x55\xe1\x13\x22\x33\xbe\x87\x66\x00\x59\x20\xaf\xe4\x3f\xe0\x39\x70\x77\x99\xe6\x9a\xe2\x8b\x1d\x43\xce\x77\xd5\x66\xbd\x7a\x76\x13\x0d\x06\x76\x97\x83\x60\xa9\x66\xa4\x05\xe1\xa8\x03\xfa\x9a\xff\x80\x3f\xf3\xf2\xd5\x8c\xd0\xeb\xbf\x88\x74\xb4\x60\x92\xf8\x1c\xd3\xea\x78\x5c\x5e\x8a\xb5\x48\x5c\x38\x84\xb6\x3c\xb2\x7d\xfb\xcc\x9a\x87\x69\x21\x33\xeb\xbb\xfe\xed\xea\x6a\xa5\xc7\x12\x30\x8b\x1c\x23\x2d\xac\x40\xf6\xd2\xf3\xea\xaf\xa7\xaf\xbb\xfd\x6e\xf3\x10\xe2\x66\x9d\x28\xcb\x7c\x56\x19\x3f\xce\x48\x9b\xfd\xd2\x23\x92\xe9\x94\x3a\xab\xac\x57\x68\xbd\xb2\xf3\xd5\x79\x82\xf2\x9e\xdd\x6b\x6a\xb8\x43\xad\x41\x59\xbd\xd6\xd2\x7e\x1a\x57\xf5\xed\x2d\xee\x61\x5a\x68\xda\x07\x38\x54\xf5\x79\x53\xb6\xf0\x5a\xe7\xed\x19\xf3\x3c\x94\xb8\xfa\x85\x6f\x9e\x65\x4a\x98\x50\xa6\x75\xf2\x37\xab\xbc\xbe\xee\x26\x3d\xdf\x42\x0a\x0e\xde\x4a\xdd\x21\x4a\xbb\xa5\xeb\x7c\x5c\xb2\xa1\x60\x5a\x31\xa7\x81\xb0\x0f\x24\xc6\xee\x7d\x5e\xd8\x6b\x32\xad\xa4\x30\x63\x4b\x72\x94\x27\xfd\x3c\x9f\xa1\x95\xce\x30\x65\xa3\x4e\xe7\xe7\xaa\x95\xed\x0c\xba\xa3\x35\x25\x5c\x05\xbb\x55\x2c\x8b\x4e\x66\x66\xdf\xca\x28\xc5\x94\xe7\x79\x36\xa8\xd1\x1d\x1e\x12\x52\x67\x7f\x1c\x7c\x07\x6e\x03\x89\x47\x5b\x19\xa1\xb1\x0e\x96\xf7\xfe\xcc\x91\x41\xd1\x1f\xd3\x1c\x77\x0a\xdf\x57\x57\xa5\x4f\x8c\xff\x22\x05\xaf\xad\x96\x51\xd4\x53\x20\x5d\x81\xa2\x19\xef\xb0\x4c\x24\x1c\x1d\xdd\xe5\xd4\x6e\xda\xb7\x5d\x35\x78\xd1\x8d\xa3\x62\x12\xa7\xe1\xdf\xf0\x53\x29\x8d\xf3\x58\x93\xe6\xc9\x19\x17\xfb\xdb\x34\x31\x8b\x31\xe2\xd2\x01\x44\xb0\x20\x5f\xc1\x4c\x2c\xd2\xe0\x20\x74\x2d\xeb\xf7\xb2\x32\xd0\x57\x9b\xe6\x4d\x13\x8a\x41\x6f\x29\x0f\x30\xf7\xfc\x62\x86\x51\x2b\xbc\xb7\xc8\xca\xda\xbc\xc8\x65\x0b\x5b\x68\x2f\x02\x57\xc3\x44\x1a\xe4\xe9\x1f\xce\x08\x98\xb8\x82\xdf\x74\x6f\xc3\x12\x83\x15\xad\x6b\x79\xbe\x96\xc3\x24\x7f\x81\x94\x9f\x5d\x49\x13\x14\xe4\xde\x03\xda\xab\x6c\x4a\xeb\x60\xf6\xae\x54\xf5\x99\x0f\xd3\xe7\xa3\xd8\x70\x93\xb1\xf1\x46\x77\x55\x9a\xfb\x05\x72\xea\xec\xe6\x45\x14\x21\x6b\x60\x9d\xa3\x50\xd7\xcd\xcb\x3a\x8e\x48\x1a\x89\x38\xfb\x45\xfd\x66\x7e\x0e\x22\x69\x00\xa9\xdd\x3e\xa3\xce\xc5\x10\x28\x1a\x11\x5b\x87\x4c\xcf\x4b\x83\x08\x19\xa7\xb5\xdc\x9e\xaf\xce\x2f\xf0\x7a\x2a\x10\x0f\xfe\x79\x98\x62\x84\x72\x4a\x43\xb5\xb7\x5b\xbe\xc1\xb5\xbb\xdf\x0e\x98\x44\x3b\x63\x66\x07\xf1\xfd\xba\x29\xdb\xd4\x25\x6b\x26\x11\x82\x49\x40\x92\xa0\xeb\x14\x92\xe2\x4d\x88\x39\x17\x03\x01\x93\x46\x11\xb2\x6a\xde\x64\x13\x8a\x2f\xcf\xce\x1b\x78\x7a\xea\x94\x5a\x24\xa4\xdf\x41\x7b\x5f\xc9\x72\x63\x30\x2b\x57\xd5\xad\xad\x8a\xbc\x5a\x9e\xf0\x4d\xda\xcb\xc9\xd9\x53\x69\x7a\x71\x90\x4f\x50\x60\xb3\x1f\x67\x34\x43\x9d\xe2\xdd\xcd\xea\x61\xff\x7c\xf3\xb2\xbe\x79\xdc\xad\xee\xc2\xfc\x6f\x32\x05\xb8\xa6\xa9\xdc\xac\xd7\x8b\x22\x97\xcc\xc8\x04\x68\x1a\x84\x47\x8a\xaa\xee\x5d\xcb\x99\x91\x59\x2c\x93\x7e\xc8\x23\x0d\x7b\xf2\x45\xa4\x66\x98\xc7\xbc\x3d\xe9\xf7\x6e\x0b\x13\x7e\xa7\x12\x22\x69\xaf\x37\x0a\x35\x80\x27\xc9\xf6\x0d\x52\x83\x53\xda\xbe\x84\x9f\xed\x73\xd5\xee\xe4\x2c\x02\x34\x9a\x44\xb1\x07\x9f\xe1\x40\x68\x3f\xaa\x79\x8b\x58\x61\xcd\x6c\xdf\xc8\x1f\x30\x51\x8e\xfa\x95\xe0\xf3\xe8\xf7\x06\xb2\x61\x53\xed\x72\x6a\xe3\xc4\x9f\x31\x8c\x62\x6f\x2e\x64\xd3\xae\x65\x51\x3c\x7f\xdd\x86\x72\x96\x31\x19\xcf\xc8\x68\x4e\x1e\x82\x97\x59\xd7\xb1\x69\x82\x70\xbd\xed\xf3\x66\x77\x33\xfc\xde\xaa\x9e\xd3\x79\xb3\xfb\xb2\xdc\xeb\xac\xb2\x10\x08\x63\xc7\x0b\xce\x1f\x44\x4a\x20\xe8\x72\x7f\x06\x59\xef\xde\x6a\x80\xb1\x7e\x13\x03\x12\xc9\x2c\x1a\xdd\x62\xd3\x1f\x20\x31\x27\x7d\xa9\x79\xb0\xfb\xbd\xbf\x24\x77\x02\xf1\x3d\x00\x8b\xf4\xa8\x1c\x3a\x52\x6d\x09\x6d\x94\x23\x54\x80\xaf\xc9\x3d\x85\x7e\x00\x31\x65\x08\xa8\xcf\x7d\xa7\xde\x76\x71\x45\xd3\xe6\x4e\x8e\x1e\x13\x70\x4d\xfe\xba\x54\x9e\x81\xd8\x70\x9c\x15\xfb\x65\x7d\x0a\x4e\x04\x4a\x9d\x8d\xfd\xea\xf1\xeb\xe3\x5f\xab\xfe\xaf\x89\xc4\x9a\xef\xb1\x06\x9b\xff\x04\xf3\x65\x24\xf8\x19\x9a\x48\xe7\x28\x52\x95\x6e\xa9\x19\xe9\x3f\x31\x60\xdc\xbd\x53\xe9\xf0\x3a\x7f\x5f\xf0\xc2\x80\xe9\x1e\xe3\xb1\xcb\x0f\xb8\x4e\x6f\x41\x57\xa5\x69\x7a\x81\xf2\xd9\x05\x99\xa1\xc8\xf5\x76\x56\x54\xf3\xc4\x40\xaf\x3d\x76\x31\x31\x00\x33\x0e\xb7\xb9\xea\xbe\xea\x6d\x55\x0f\x52\xee\x79\xbf\x7d\xfe\xd5\x74\x0c\x3c\x4e\x10\x3f\xb1\x79\xb8\xbe\x19\xfb\x66\x4c\x56\xe9\xf9\x72\xd6\xfd\x7d\x3c\xc8\x41\x44\x80\x9a\xda\xb9\xae\xf6\xc7\xba\x3a\x54\x7b\x87\x18\x5d\x8e\x09\xa1\x0b\x87\xbd\xae\xee\xab\x33\x0d\xef\x65\xdd\xd3\xd0\x24\x71\x25\x5e\x04\x43\x1f\x02\x1f\xee\xe9\x08\xe5\xb6\x85\x63\xff\x89\x05\x38\x66\x14\x86\x24\x79\x59\x42\xd8\x18\x4c\x26\x21\x48\xa2\x08\xcb\xb3\xba\xa8\x4a\x98\x68\x39\xfe\x3a\xbb\xd7\xfd\x10\xfa\xbd\xaa\xd7\xfc\x01\xd3\xe3\x2a\x42\x2b\x91\x0a\x15\x04\x09\x0e\x93\xc2\xd6\xb0\xe6\x42\x92\x38\xf5\xa6\x3b\x68\xfb\x65\x69\x32\xcd\x42\x92\x18\x39\x30\x23\xdd\x4e\xb0\xae\x16\xb6\x72\x90\x64\x29\xf3\xe9\x87\xd5\xeb\x45\x1e\x01\x12\xa0\x18\xa4\x3f\x6c\x1e\x77\xfb\xcd\xe3\xee\xe6\xe5\x5b\x2f\xe8\x00\x29\x75\x13\xfe\xf6\x28\xeb\x77\xb4\x76\x1c\x65\x62\x20\xe5\xae\x5c\xf1\xd7\xdd\x53\xff\x27\x99\xa0\x34\xd7\xbe\x71\x80\xd7\x26\x37\xfd\xa3\xa7\x8a\xe2\xf4\x7e\x07\xed\xaa\x79\x0f\x04\x96\x6b\xd0\xf9\xa1\xaf\x26\x42\xaa\xac\xcd\xbc\xb8\x05\x2a\x20\x36\x73\x87\x16\x06\x19\x68\xda\x3b\x6a\xbb\xfd\x67\x70\x07\xba\xad\x4e\x21\xcb\x06\x32\x76\x7a\x9d\x77\xd0\x5e\x3f\xed\x1e\x4f\x87\x17\xf8\x51\xbd\x77\x41\x61\x37\x8e\xa1\x99\xbd\x51\x45\x08\x6a\x1a\x5c\x57\xaf\xaf\xe7\xc9\x73\x2a\x19\x45\x3d\xbe\xf3\xad\x2a\x4c\x9f\xab\x07\x65\x22\x64\x09\x3d\x9e\x4a\x68\x76\x88\xd8\xcf\x87\xdf\x19\x40\x3e\x32\x26\x87\xf6\xed\x1b\xec\xbf\x54\x7d\x4d\x15\x34\x4b\xf1\xac\x2e\x39\x88\x17\x8c\xa3\xbe\x82\x0a\xda\x48\xeb\xd8\x5c\x3f\x90\x83\x3c\xa2\xe3\x80\x06\x8d\x18\x96\x53\x13\x10\x44\xdd\x78\xdc\xd8\x95\xab\x58\x5d\x20\xf2\x3e\xe9\xb1\x86\x65\xd2\x09\xff\x3c\x57\x1f\x50\x9f\x2e\x94\x5c\xc0\x46\x89\x77\x77\x19\x24\x43\x71\xf6\x0f\x77\x62\x81\x61\x09\x5f\x49\xfd\xbe\x7d\xcf\xcb\xee\xf1\xc7\x6c\x06\xb0\x96\x20\x95\xfc\x43\x16\xa7\x31\xb7\xd5\x46\x82\x27\x43\xc5\x60\x55\x14\x13\xfa\xa6\x8d\x52\x67\x2f\x39\x64\x62\xe7\x52\x71\xcc\x92\x48\xd3\xde\x4e\xd3\x47\xa7\xf8\x3a\xfa\x4c\xab\x25\x99\xa5\x49\x7f\x15\x67\x8d\x33\xfd\xee\x96\xa8\x08\x05\x15\xf7\x7b\x5b\x54\x55\x0d\xe6\xbe\x7a\x25\xd1\x7e\xea\x4a\xde\x35\x73\xf4\x46\x7b\x94\x35\x02\x86\xfb\xfd\x88\x25\xda\xdb\x3a\xa2\x17\x9d\x5e\x42\x13\x5b\x1a\xd3\xa0\xc7\x86\xae\xb0\xbb\xea\xe6\xe7\x31\xaf\x67\x5d\xdb\x52\x9e\x61\xd5\xb8\xf7\x9b\x77\xd5\xf8\xfe\xb5\x70\x96\x26\xbd\xd3\xcf\x77\x80\x77\x5c\xa9\xc3\xd1\x94\x67\xb8\x14\x7b\x45\xc9\x59\x46\xd1\xa6\xa9\xc6\xb2\xd7\xae\x9a\x40\x98\x6c\xc6\xe2\x98\x84\x5c\x66\xd5\xce\xde\x4f\xa6\xb3\x10\x3a\xed\x7b\xa3\xdc\xbd\x1a\xab\x64\xcc\x43\x23\xff\x4b\x19\x6b\x0c\x89\x5c\xf6\x0e\xca\xb6\x59\xcf\xd2\x68\x56\x42\x82\xfb\xa2\x37\x28\x8a\x6a\xf6\x79\x55\xec\xf2\x88\x7b\x24\x34\x62\x89\x68\xa1\x7c\x3e\xd0\x56\x17\x82\x7c\xab\x58\x8c\x89\xfa\x1e\x23\xf9\xc5\x0d\xdf\xa5\xf5\xd2\xff\x44\xa7\x11\xe6\x3f\xca\xd3\xeb\xeb\x9c\xfb\x64\x0d\x49\x70\xfa\xc6\xa9\x07\x33\x78\xbb\x8f\x6a\x86\xa0\xb2\x86\xb3\xc4\x8d\xab\x55\x58\xf8\xcd\x6c\xa1\x0e\x2d\x13\x87\x91\x75\x60\x34\x84\xdc\xaf\x76\x9b\xa7\xc7\xfd\x80\x49\xb3\x46\x2a\x04\x9a\x1e\x73\xfd\xbe\xae\xca\xa6\x72\xfb\x39\x14\x61\x9b\xa3\xf5\xac\x01\x82\xc6\xa9\x83\x3a\xa8\xae\x6a\x67\x87\xb2\x03\x79\x18\xe5\xb6\x67\x4f\x6d\x40\xa3\x6e\x81\xb3\xba\x90\xe5\xbc\xef\x00\x77\xe2\x04\x1f\x90\x0f\xa0\x46\x0b\x52\xe1\x62\x79\x73\xc8\xdb\xfd\x93\xb5\xfa\x4d\xe6\xa5\xc7\x10\xdf\x16\x72\x39\x3b\x34\x5a\xe8\x2c\x80\xf3\x42\xf8\x56\xfd\x84\xe2\x5f\xe1\xb4\x36\x06\xef\x78\x55\x63\x95\x0c\x7b\xeb\x24\x1c\xb5\x96\x51\x44\x9a\x7e\xed\x8d\xb2\x1f\x73\xfd\x3e\x96\x76\x9a\x75\x46\xab\x19\x6a\xd2\x63\x39\x3f\x07\xb7\x6e\x34\xb3\xee\xb0\xb8\xa5\xb6\x56\x2b\x6e\xc2\x96\xc6\x13\xb2\x1e\xf2\x32\xbf\x90\xd7\xe2\x51\x14\x49\xe4\xe0\xee\xf2\xb6\x80\x4f\xa8\x8e\xcb\x4c\x8c\xf1\xe7\xe0\x51\x14\x53\x84\xea\xfe\x77\x5e\x14\xd5\x07\xa6\x97\xf0\xdd\x2e\x7e\x3d\x1e\x45\xd4\x50\xe7\x0b\x5e\x74\x1f\xbd\x96\x45\x3f\x1f\x62\x6d\x01\xa6\xda\xa7\x3c\x8a\x12\x70\xe7\x97\xef\xd2\xef\xa8\x79\x14\x99\x8c\x64\x61\x93\x54\xd7\x58\xdf\x99\xfe\x8c\x10\xc0\x9c\xd7\x43\xf5\x23\xff\x55\xc1\x96\x47\x71\x9c\x21\x21\xb2\x84\x8f\x75\x33\x7b\x49\x31\xa7\x99\x08\x8a\x5d\x0e\x70\xe7\xd9\x0c\xeb\x4f\x85\x4b\xba\xee\x47\x11\x7c\x7e\x90\x3f\xfb\xa4\xc6\xe0\x0a\xca\x23\x9a\xc6\x48\x08\xeb\x96\x40\x49\x67\x23\x83\x47\x54\x0a\x9c\xfc\x6e\x5e\xd6\x49\x4c\xf0\xeb\x0f\x04\x0c\x1e\x51\xe5\xca\x20\x8e\x3f\x81\xb0\xbd\xdf\x94\x28\x66\xb7\xc7\x33\xae\xc9\x58\x0a\xa8\xaa\x37\xd7\x8b\x72\x7f\x3c\xe2\x32\x72\x42\x5a\x85\x6c\x9a\xf3\x10\x32\xf0\x28\x21\x06\xe1\x45\xdb\xf5\xea\x65\x75\x85\x77\x49\xfa\x63\x0a\xd0\xf7\xf6\xdf\x55\x5e\x82\xe9\xf3\x41\xcd\x3d\x94\xbd\x6f\x3e\x8f\xd2\x8c\x63\x4d\x0d\x33\xa0\x98\xb8\x1f\x02\xe6\xff\x33\xfc\x97\x84\xfb\x4e\xa5\x70\x2e\x63\x55\x37\xd2\x1e\xf2\x72\x50\x66\xe4\x51\x6a\xd2\xd4\x7a\x00\xfb\x66\xfd\xb4\xe0\x05\x33\x7b\x0b\x19\x15\x48\xf2\xfa\xb7\x53\xce\x18\xe4\x8e\x79\x94\x49\x57\x86\x74\xe1\xfe\x35\x94\xd5\xa1\xdb\xb9\x85\xb5\x9a\x47\x92\x70\xdc\x20\xff\xa8\xda\xde\x85\x35\x70\xef\x96\xaf\x26\x63\x48\x7a\xb6\x5f\x73\x2a\xda\x4b\x5f\xcb\xd0\x0d\xe2\xd0\x0f\x24\x13\xb8\xd8\xc1\x21\x47\xa7\xc8\x1f\x10\x80\x5e\xfd\xb4\xc4\x23\x99\x00\x72\xcb\xc0\xb1\x5b\x9d\x4a\xae\x17\x06\x32\x3f\xf2\x66\xb8\x69\x4d\x45\x1c\x44\xc3\xd6\xb2\x36\xfd\xd7\x32\xa9\x44\xc5\xb9\x35\x86\xe6\x45\xd5\xb6\xd5\x68\xd1\xe5\x91\xc9\xa4\xed\x06\xc8\xcd\xe3\xf5\x90\x62\xe7\x91\x51\x94\x3b\x90\xbc\x79\x96\xe7\x3e\xe7\xf5\x59\xfa\xe6\x02\xfc\x30\x5f\xcf\x78\x04\x84\x21\x10\xc6\xed\x14\xfe\x02\x59\x37\xdb\xbc\xd4\x30\x71\xb5\xe1\x11\xc4\x4a\x7b\xf2\xe6\xfd\xfd\xb7\x3d\x98\xbc\xdd\xc7\xf1\x78\x6f\xc4\x23\xa0\x49\x6f\x1a\xfd\xd6\x2d\x78\x93\x9e\x04\x2c\xc1\x3a\xff\x9f\x27\x53\x8d\xfb\xb4\x8d\x01\xb1\xe8\x36\xef\xde\x66\x01\x83\x58\xdd\x74\xfd\x5e\x9a\x7c\x79\x64\x95\x88\xcd\x04\xbf\x5a\xe9\x05\xa5\xaa\xe9\x43\x93\x28\xa1\x48\x00\x46\x3b\x96\xc9\x5e\x9f\x93\x48\x31\xea\x0a\xab\x5d\xd4\xec\xc9\xf4\xe1\x20\xa1\x04\x5d\xf2\xa1\x7d\x83\x1a\xb3\x96\xfd\x11\x95\x32\x8f\x87\xd9\x1e\xa5\x86\xe6\x2d\x3f\x3a\x95\x90\x5f\x45\xd9\x9c\xd0\x94\xa2\xe8\xc5\xf3\xa9\x86\x55\x5e\xff\x33\x62\x36\x27\x54\x0b\xe2\x09\x5d\x33\xe7\xe7\xe9\x0b\x22\xd4\xa8\x54\xf8\x28\x78\xdf\x76\xe1\x20\x8e\xfa\x55\x69\x36\xce\x90\xe0\xe6\x3f\xb3\x17\xc0\x19\x37\x83\x6d\x5c\x55\x1f\xdc\xbe\x30\x1c\x05\x86\xf7\x7b\x94\x28\x3e\xf4\x74\x6a\x5f\xab\x6e\xb3\x36\x60\x80\x46\xc6\x7c\xfe\x37\x82\x71\xf0\x48\x5e\xa7\x8e\xf2\x35\x9f\xd5\x95\x38\x49\x98\xa4\x64\x62\x9a\xb5\x85\xc2\x4e\xb3\x88\xa1\x69\x62\x63\xef\xf0\xdd\xeb\x64\x2d\x7f\x67\x49\x29\x84\x25\xeb\x5c\xc8\x8f\xa6\xcf\xc1\x3e\xe4\xe5\x73\xd5\xb4\xc7\x6a\xfc\x75\xa5\x20\x88\x55\xbd\xce\x2f\x01\x40\xb3\xd7\x2a\x0d\x0b\xe0\xe4\xc7\xd3\xe1\xba\x96\xaf\xbd\x30\x29\x27\x12\x64\xe2\x51\x45\xa8\x7f\xf9\x2b\x3f\x4a\xff\x13\x25\xc0\x7a\x71\xaa\x55\x51\x7c\xab\xfa\x8c\x17\x27\x4a\x51\xc7\xc1\xed\x82\xca\x9b\xd2\x34\x84\x87\x43\x3a\x72\xe6\xe5\xaa\x98\x88\xf7\x70\xa2\xe3\x04\xbf\x21\x82\x9d\xb1\xa0\xb0\x85\x76\x34\x75\x13\xcd\x18\x09\xa4\xaa\x1f\x52\x55\xed\x3c\x27\x1d\xda\x71\xe5\xf7\x99\xe6\x5b\xb0\x47\xfe\x8d\x62\x31\x27\x3a\x33\x08\xfa\xb9\xbe\xbb\xea\xcf\x23\x0d\xe6\x07\x77\x5f\x9e\xbe\x6e\x57\x8f\xd7\xfd\xdf\x75\x62\x9d\x44\x5e\x5e\x5e\x58\x0d\x71\x62\xba\x27\x19\x07\xe8\x8b\x32\x5f\xcb\x77\x61\x98\xb0\x74\x94\x0f\xc4\x25\x2f\x9c\x18\x84\xa2\x9e\x1e\x4c\xa2\x68\x04\xf4\xe1\x04\x80\x62\x56\xc3\x6f\x97\x27\xa3\xdc\x66\x10\x47\xbd\x0a\xd0\x93\x9d\x56\x7c\x78\x1c\x51\x89\x79\x17\xa7\x5a\xfb\x58\x39\x1f\xbc\x4b\xc0\xc8\x64\x30\xc7\x51\x06\x58\x58\x0c\xbc\x88\xd1\x6e\x9e\xc7\x44\x30\x96\x05\x32\xf2\xfa\xd4\xb4\x95\xc9\x65\xd9\x1f\x55\x1c\x23\x02\x69\xb0\xd0\x85\xb4\xc2\x3f\x66\x13\xce\xa4\xa7\xc5\xb1\x70\xb6\xab\xf7\xd5\x6b\x8f\x16\x5f\x7f\x6e\x3d\xcd\xe3\x58\x6a\x2c\x87\x8d\xf7\xd1\x83\x0c\xb4\x6f\x44\x69\x8a\x12\xe5\x41\x1a\xfc\x21\x2f\x7b\xab\x57\x1e\xd3\x8c\x62\xe1\xa0\xdf\x77\x3c\x56\x4f\xd6\x2d\x98\xdd\x38\x0f\xe8\x21\x1e\xf3\x18\x82\x6c\xd9\xc8\x81\xef\x93\x1b\xe3\x5c\xa2\x82\xcb\x23\xd4\x55\x38\x81\x60\xae\x3c\x1a\x50\x5a\xcd\x02\xf2\x8a\xc7\x82\x03\x4e\x48\xc7\xee\xac\x7b\x39\xe9\xf2\xb1\x30\x51\xe6\xb4\xbe\x71\xa6\x1c\x91\x99\x96\x32\xe7\x3c\x4e\x88\x45\x8a\xcf\x3e\xc8\xae\x7f\xdd\x5e\x2f\x5e\x35\x11\x09\xc6\x16\xd7\xf0\xe3\xe5\xf3\xa4\x26\x8f\x93\x94\x12\x9f\xf5\x75\xf5\xf0\xe9\x07\x4c\xb4\x13\xae\xf1\x50\xbe\xae\xeb\xba\x59\xf5\x36\x7f\x7d\x6b\xe3\x6b\x90\x33\x56\x13\x8f\x53\x95\xe0\x4f\xbe\x6f\xee\xaf\xc7\x61\x46\x9c\xa5\x8e\x58\xdd\xef\xa1\x9b\x7f\xee\xa8\xdb\x9f\x22\xb1\x7d\xf9\x05\x55\xed\x90\x40\xe2\xf6\x06\x2c\x9a\x2c\x7b\xcb\xda\x76\x3c\xce\x0c\x47\x52\x61\x8b\x60\xb7\x11\xd6\x8d\xc7\x52\xa8\xc0\xfe\xec\xe9\x42\xae\x60\x3c\xfb\x0c\x32\x31\xc2\xa3\x0f\x6e\x7e\xb6\xb5\x1c\x73\x63\x3e\x79\xd1\xd2\x38\x0b\xf7\xb2\x2a\x6f\x4f\xe5\x6b\xae\x0a\xf0\xf4\xec\x80\x44\x98\xc7\xf6\xe3\x4a\x33\x8f\x95\x70\x40\xbd\xa6\xfb\x50\x28\x21\x36\x95\x2b\x9e\x7d\x05\x1d\x39\xcc\xb1\xfc\x99\x43\xb3\xa8\x35\x31\xbb\x3f\xcd\x1d\x68\x53\x9a\x7f\x9f\x9a\x6e\xc7\x3c\xb3\x58\xe1\xb1\xd6\x16\x0b\x04\x7f\x6d\xfe\xda\xfe\x22\xf0\x8e\x8d\x24\xa4\x07\x37\x04\x6d\xc2\xb5\x3c\x3a\x49\xe4\xd0\x1b\x8c\xb2\x98\x1e\x38\xe6\xfa\xfd\xeb\xcb\x7d\xff\x67\xcd\x53\x8f\x39\xf9\xaf\x53\xde\xde\xcf\x61\x44\x3c\x86\xcc\xa2\x37\xd7\xa8\x08\x3c\xb5\x14\xfb\xe4\x01\xc1\x40\x3a\xb0\x07\x27\xc8\xfb\x49\x3b\x4b\x5d\xde\xa2\x05\x79\x58\x58\xcd\x62\x2b\xdc\x8b\xca\x9b\xe7\xba\x7a\xad\xe5\xc1\x1b\x1c\x4e\xc1\x7d\x3c\xb6\xa9\x0a\x6a\x5c\x57\x55\xf5\xee\x3b\xea\xd8\x09\x95\xd3\x6e\x23\x85\x69\xb0\x3a\xe4\xc1\x26\xcf\x4a\x49\x1a\x13\x27\x1e\xe3\x00\x1b\xdd\x4c\xf7\x2b\x43\x68\x4e\x89\x52\x18\x34\x76\xf1\xe4\x17\xd9\x2d\xe1\x21\xc3\xc5\x69\x4c\x68\xe2\xec\x28\x7e\xfe\x5d\x05\xa1\x12\x4e\x63\xce\x91\xc0\xd6\x9c\x86\x3f\x89\x18\x97\x96\xf6\xb5\xf6\x4f\xdf\x3c\xcb\xba\x1d\x4d\x4f\xe8\x26\x29\x1b\x78\x46\xb6\x67\x70\x24\xe0\x94\x65\x4e\xb1\x17\x13\x6d\xd7\xf0\x03\x8a\xea\x88\x86\xa5\xfb\xbe\x85\x72\x55\xa3\x89\xe7\x17\xcc\xab\x80\x9c\xf2\x88\xe1\x58\x7f\x3a\xc2\x38\x47\xc8\x29\x67\xce\x00\xac\x06\x03\x70\xb8\x04\x70\x71\xca\xb9\x73\x87\xd8\x37\x45\xd5\x05\x19\x8f\xf0\x31\x7b\xb1\xdc\xc4\xa0\xfd\x6e\x12\xe5\x2d\x3f\x45\xc1\x70\x2a\x24\x47\x25\xb1\x7d\x03\xed\xd5\xa9\x2e\x6f\x01\x21\x7b\xb3\x6b\x0a\x65\x71\x7f\x7a\x75\x3a\x6f\x9e\xef\xc2\xbd\x26\x51\xe6\x2c\xcb\x7b\xdb\xd1\x6f\xf2\x54\xfc\x16\xa5\x3d\xfb\xa8\x09\x49\x10\xcc\xda\x2d\x69\xdd\x1d\x2c\xcd\xf8\x34\x49\x29\xf3\x51\x62\xb7\xc4\x6a\xc0\x4c\xfa\xf7\x3c\x50\x83\xa7\x2f\x20\x8d\x53\x04\xd6\x06\xf8\xf8\x2a\x28\xfa\x70\x2a\x19\x20\x48\x14\xad\x57\x3c\x13\x6a\xa9\x73\xca\xcc\xe0\x26\xf9\xe6\xee\x6e\xbb\xdf\x3d\xed\xbf\xac\x76\xeb\x2f\x7b\xf2\x65\xf3\xbc\xdd\x05\xa9\x2a\x4e\x15\xcf\xf0\x5b\x1c\x11\x15\x49\x9c\x28\xef\xfe\x38\x0a\x82\xa8\x49\x1d\x11\xed\xe1\x7c\x2b\xf3\x7a\xf2\xad\x8d\x8d\x13\x7c\x7f\x27\x28\x66\x97\x87\xd4\x69\x03\xbd\xc9\xe6\xed\xdb\x43\xf8\x81\x15\xd4\x17\xb5\x4a\xd3\x67\xf2\x77\x95\x77\x90\x99\xbd\x32\x9b\x00\x32\xbf\xae\xae\xef\xc7\x57\x65\x31\xcd\x02\x90\xe2\x3a\x6f\x74\x90\xc5\x5f\xce\x06\xb1\x98\x33\x4c\x86\x38\xbe\x5d\x25\x1d\x6e\x68\x8b\x72\xae\xf3\xdd\xf2\xff\x88\xa1\x7f\x65\xbe\x83\x31\x4a\x40\x87\xdc\x81\x6c\x81\x52\x1a\x6e\x84\x66\xd6\x85\x28\xd5\x01\x82\x97\x05\x0b\x07\x59\x14\x3b\x1e\x51\xf5\x7e\x72\x11\xf9\xe4\x21\x18\x95\x38\x5d\x07\xe0\xf6\x6c\x7e\x62\x8c\x19\xa0\xa1\xbf\xe4\x18\x97\xcd\xc4\x36\x38\x63\xdc\x81\x97\xcb\xd3\x01\xd9\x29\xfd\x46\x81\xb1\x54\xf3\x3e\x41\x77\x2a\x07\xfd\x07\x7f\x5c\x10\x8b\x31\x5a\xd7\x65\xa7\x96\x47\xd3\xcd\x0d\x13\x2c\x46\x2d\x89\x43\x5e\xa2\x25\x4f\x2d\x3f\xd0\x57\x7c\x7a\x23\xc2\x50\x4c\x0d\xad\x4a\xd9\x56\x87\x5c\x7e\xf2\x29\x12\xaa\xdc\xc9\xbc\xd6\x7d\x95\x23\xb4\x70\x76\x6f\x89\x30\xa1\xfa\xe7\x61\x6b\xbb\xf3\xd1\xd5\xad\xe6\x22\xbd\x9c\x25\x49\x0c\x72\x70\xf3\xf6\x8a\xc9\x93\x88\xaa\xcf\x24\x0f\xe9\x64\xce\x12\x69\x31\x0f\x5a\xc8\xa6\xbd\xca\x4d\x5f\xa8\xe3\x2c\x51\x6e\x3b\xe0\x14\x7b\xb6\x08\x96\x0d\xa5\x49\xce\xd2\xd8\x86\x05\xf0\xa9\x74\x63\x78\xf5\xba\x2c\x14\xc5\x59\xaa\x35\x06\x05\xd2\xd7\x78\x31\x9e\x18\x57\xaf\x38\xcb\x14\xf5\x42\x73\xdd\x4c\x8e\xfc\xe0\xa5\x7d\x01\xcb\x8c\xb3\x50\x7e\x90\x67\x59\x3e\xd7\x55\x5b\xe9\xaa\x98\x0b\x8c\xcc\x2e\x2f\xa9\x41\xf9\x35\x54\xb5\x90\x75\x7b\x51\x8a\x1f\x35\xcd\x34\xe6\x74\x36\x87\x23\x48\xfd\x76\x40\xac\x20\x42\xf3\xcd\x67\x18\xd6\x69\x3f\x51\x44\x63\x39\x57\x9f\xea\x67\x79\xde\x75\x0f\xb2\x09\x2b\x1b\x53\x8a\x22\x30\xec\xb1\x52\x05\x34\x0d\x3c\xa9\x22\xef\xd7\x24\xa6\x40\x23\x72\xfc\x28\xcf\xaa\xd7\x46\xe5\x4c\xc7\x80\x50\x9d\x2f\x79\x3b\x89\x06\x26\x89\x90\x79\x50\xb6\x98\xf8\x60\x9a\x49\x2c\x8c\x5c\x57\x1f\xa5\xf7\x00\xfe\x63\x01\x2f\xcd\x99\xe6\x29\xc2\x7a\x57\xa6\xf9\x01\x65\x7b\x9a\xd0\x08\x39\xd3\x4a\x60\xcc\xb0\x7b\x83\x4d\x51\x9c\x30\x2b\x99\xf7\x07\x4d\x86\x29\xc6\x35\x6a\x4c\x4e\x7f\x67\x6d\xe0\xd6\x5e\x78\x92\xf8\x26\x40\x63\xad\xbd\x31\x4e\x79\x72\x8a\x46\x4b\x61\x6b\x68\x9e\x72\x8c\x82\x8a\xdc\x02\x52\x35\xe6\x23\x12\xb4\x41\xa8\xc3\x37\x79\x2e\xf3\x90\xf2\x65\x96\x08\xe1\x5d\xcd\x1f\xab\xf2\x58\x57\x36\xef\xa6\x50\xd5\x85\xfb\xdd\x37\x5f\xdc\xd5\x30\x4b\x24\x22\x1b\xbf\x6d\xbe\xad\x5c\x95\xd1\xad\x92\xb3\x56\x34\x43\x8c\x2d\x74\x5b\x8f\xb7\x5e\x73\x69\xd8\xf2\x86\x76\x2c\xc5\xa0\x49\x9d\xce\x7f\xe6\x4d\x73\xb5\x5b\x77\x8b\xe0\x5a\x16\x85\x92\x9f\x38\x59\x70\x1e\xc5\x4e\x49\xd0\xc0\xb1\xc5\xdd\x6f\x0d\xcd\xb1\x9a\xa9\x36\x71\x1e\x09\x86\x4c\xb4\xbb\xb2\x6a\xf2\x66\x1a\x05\x7f\x1a\x41\xf0\x28\xe5\x58\xd7\xc5\xec\x80\xcb\xc2\xfe\x11\x0e\x49\x89\x65\xb7\xab\xa7\xc7\xaf\xdb\xfd\x6e\x73\xf3\xb2\xcf\xf6\xf7\x9b\x87\xcd\xae\x6f\xa1\x5d\xbc\xab\x4e\xe8\xf1\x7a\x21\x89\xc4\x39\x21\x4c\x7b\xcb\x9e\x47\xd9\x93\xdc\xd2\xfe\xa8\xe1\xbe\x6f\xdc\x04\xc1\xa5\xf5\x48\x84\x63\xf6\x22\x48\x0c\x88\xe9\xbd\x69\xdf\x70\x07\xd4\x4d\x7a\xf1\xec\x2d\x90\x34\x65\x72\x0c\x26\xba\xcf\x51\x87\xd5\x73\x3b\xe7\xad\x55\x9a\xf9\x0d\xb0\x97\xe4\x1f\xc4\x6f\x39\x27\x40\x1d\x2a\x5c\xfe\x00\x74\x3c\x5d\xc2\xb4\x71\x1e\xc7\x29\xa6\xec\xca\xd3\x01\x33\xd1\x3f\x64\x31\xeb\x91\x3c\x4e\x29\xe2\x9f\xbc\x42\xd3\xd4\xe8\x24\xb4\xc9\x04\xf5\x41\xd2\x36\x6f\x3d\x4e\x6a\x59\x36\x88\x73\x1a\x99\x44\x07\xb3\x4d\xd4\x30\xbe\xaa\x01\x4c\x70\x96\xef\x1a\x0b\x16\xda\x72\xad\x7d\x51\x1d\xfb\xee\x62\x47\xef\xc2\x13\xcc\xb4\xbf\xc9\xda\xac\xe5\x31\x90\x34\xc2\x64\xcd\x99\x88\x10\x4e\x0c\x3f\x5d\x1a\xe9\xea\x74\xfe\xf5\xae\x86\x33\x23\x30\xdb\x21\x8d\xd9\x41\x39\x92\x25\xbf\x4c\x4b\xff\x7f\xfc\xb7\xbf\xa0\x93\x73\x71\xfe\xb1\xff\xff\x05\xb2\x5d\x67\x16\x2a\xf8\x5b\xfc\x09\xe7\x45\xfd\x66\xce\xb9\x36\x98\x4a\x1d\xb4\xf0\x16\x88\xe7\xc3\x5a\xcb\xb9\x01\xc4\xdf\x5e\x15\x52\xbf\x3f\x9f\x6b\x79\xc8\xfb\xfe\x25\x08\xc1\x2c\xda\xee\x79\x77\xa9\xc4\xc3\xb9\x60\x2a\x73\xf4\xde\x2e\x80\x9a\x96\x9a\x39\x17\x9c\x3b\x9e\x4c\xa8\x70\x8d\x00\x25\x9c\xa7\x02\x90\x44\x19\x56\xdf\x75\x75\x38\x9c\xca\xbc\xbd\xf8\x66\xa1\x7d\x42\x13\x27\xe3\x86\x98\x89\x55\x33\x20\x4b\xbb\x83\xc2\x8c\x15\xd5\xae\x6b\xe4\x64\x4e\x5f\x7e\xaa\x9d\x28\xab\xc3\x90\x5c\xc9\xd7\xd9\xd3\x64\xd6\xa4\xa9\x07\x12\x43\xe3\x13\xe0\x93\xd9\x40\x25\x36\x40\xf6\x57\x0e\xce\xd3\x33\x58\x3f\xf9\x18\x2a\x65\x58\xf5\xc8\x1b\xa4\xb3\x97\xf8\x92\xef\x2f\x16\x18\xae\x09\xc3\x33\x37\x47\xd0\xb9\x2c\x7c\xa5\x00\xcb\xa8\x9b\x3e\xa5\xcf\x35\xe3\x48\x9b\xbc\xd9\x3c\xc7\x91\xdf\x39\xf7\xc7\x32\x67\x6e\xe6\x9e\xee\x66\xf7\x65\xce\xd9\x9d\x64\x46\xe6\x7d\x4b\x83\x53\x25\x6e\xa0\xdd\x7d\x54\x21\x70\xfa\xad\x37\x6e\xff\x6b\x85\xa6\x17\xab\xe9\x06\x84\x9b\x28\x41\xf6\x80\x53\xcd\xee\x1e\x3b\xfe\x6d\x9f\xff\x9c\x8b\xc3\xb9\x49\x74\x70\x13\x96\x7e\xfe\xb9\x92\x0d\xbc\xcc\x95\x57\x38\x87\x48\xc4\xfe\x79\x36\xda\xd7\x97\x67\x2d\xa4\x0d\x10\xd6\x3d\x92\xbe\xf6\x36\x00\x70\x38\xb7\xb1\x8b\x32\xdd\xcb\xbc\x83\x32\x9a\xbd\xcd\xbe\x0e\xc9\x2d\x30\x14\x43\xcd\xad\x8f\x5d\xec\xa9\xd8\x42\x89\x54\xcb\x66\xd7\x2f\x55\x16\x04\x78\x1d\x32\x27\x6d\x71\x53\xb6\xc8\x73\x99\xe6\x0c\x45\x14\x4b\xc3\x07\x81\xe1\xbc\x3a\x35\x83\xbe\xec\x1f\xa1\x51\xa6\x1c\x83\xb7\x3a\x74\x41\xe0\xa4\xb8\x27\x88\x21\x38\x4b\xfb\x99\xdc\xd7\xc5\xa6\x51\xbc\x20\x46\x23\xf9\x12\x97\x94\x6e\xe5\xd8\xe8\xea\x6b\x63\xd6\x30\xe1\xd2\x72\x11\x83\xb3\xe2\x58\x5d\x7f\xdb\x6c\x9f\x5e\xb6\x63\xf5\xc8\x6e\xf8\xc7\xc8\xfc\xff\xd4\x30\x7c\x71\x28\x0b\xa6\xe3\x94\x05\x1c\x06\x6a\x7d\x53\x36\x7d\x06\x1e\x1b\x62\x43\x62\x15\x15\xe4\xc6\xa5\xc6\xe1\x4c\x9c\xe9\x2c\xc8\x63\xc1\x41\xb9\x4c\xf7\x4b\x75\xc1\x38\xe6\x42\x50\x82\x65\x38\x6f\x0a\xe5\x50\x37\xe1\x98\x70\x2c\xe0\xdd\xcd\xea\x21\xd4\x7d\x45\x42\xe3\xcc\xb9\x1c\x38\xc6\xd3\x58\x3c\xb6\x3b\x6a\x31\x28\xb1\x55\x51\x54\x1f\xbf\x2e\x41\x89\x2e\x7a\x87\x81\x2f\xbe\x0f\x9b\x50\x21\xd3\x0c\x6d\xb4\x90\x82\xee\xf4\x89\xa7\xcf\xa7\x28\x41\x6b\x07\x87\x40\x71\xa9\xcb\x41\xd9\x64\x71\x99\x14\x2a\x31\xb8\xc6\x6c\xf3\xd7\x32\xac\x91\xf3\xd3\xaa\x4c\xeb\x90\x4c\x2e\x9b\x39\x98\x94\x0b\x1d\x91\x94\x84\xf9\xb4\xce\xa1\x19\xeb\xa7\x71\xa1\x99\x03\xbf\x7e\xaf\x2a\x33\x86\x58\x72\xa1\x85\x32\xbd\x20\xeb\x4b\xd7\x37\xa7\xdd\x5b\x27\xc4\xb8\xf9\x70\x15\x90\x71\xfd\x4f\xd3\x2c\xf6\x85\xb5\x2e\x54\x7b\x39\x15\x30\xff\xdc\xda\x38\xcf\x97\xeb\xd3\xe1\x70\x7e\xfa\xf6\x34\xb9\xb4\xd1\x49\xea\xf9\x50\xdf\x65\x5d\xe7\x55\xdd\xcc\xc1\x23\xc2\x80\x1b\x1b\xb7\xab\xe7\x5b\x94\xcc\xc2\x6f\x4b\xfb\x53\x80\x44\x81\x49\xac\x70\xcb\xd7\x69\x9f\x84\x94\xb9\x08\xba\xd6\x71\x34\x85\x33\x86\x16\x2a\xc6\x87\x6f\x4e\xea\x90\xb7\xa3\x42\x6b\xb7\x32\x6e\x03\xe4\x6e\x39\xf0\x9d\x66\xdf\xff\xe7\x7f\x07\xa3\xc0\x99\x65\x20\x17\x60\x12\x67\x72\xe7\x43\xb5\x00\xe3\xe2\xc2\xd2\x08\xe5\xe8\xbf\xbf\xc9\xf6\xbb\x6c\x1e\xce\x08\x74\x9f\x7c\x81\x24\x22\x1c\x39\xb4\xb8\x81\x6e\xde\xfe\x58\xd2\x91\x9d\xa2\xdb\x79\x42\x04\xe0\x0e\xc9\x15\x32\x10\xef\x3c\x1f\x60\x09\x51\xd2\xa2\x89\x71\x7e\x38\x16\x30\xb0\x9c\xfe\x51\x60\x94\xc4\x40\x71\x07\xd1\xe8\x85\x5d\xf0\xaf\x57\x9f\x84\x1a\x86\x75\xb2\xbe\xd4\x15\xd6\xe4\x67\x67\xb3\xb5\x5c\x6f\x4f\x98\x71\x1c\xd3\xa6\x94\x79\x71\xf0\x9e\x6d\xff\xf1\xaf\x32\xe1\x11\xf7\x4a\xa9\xde\xae\x63\xf9\xda\x9c\x38\xf6\x9b\x77\x17\xc0\x05\x7b\x6c\x11\xc0\x13\x11\x51\x04\x11\xa2\x6e\x75\x1f\x2d\x9c\x2e\x8c\x3a\x3e\x63\x82\xf1\x44\xd0\x04\x77\x28\xdb\xb7\xea\x78\x0d\x3f\x1d\xc2\xb8\x3f\xbd\xd0\xda\x09\x4c\xb8\x82\xdd\xa7\x1c\x80\xa5\x1d\x75\x92\x80\xc5\xc0\xfb\x7a\x73\xb7\x09\x67\x4c\xac\x45\x00\xd4\xa9\xac\xd0\x2e\x49\x16\x5d\xe8\xd2\x75\xdf\xaf\xc7\x5e\x78\x86\x27\x29\xe5\xbd\xc2\x63\xd5\xb4\xa8\x3b\xb1\x31\x63\x42\xa4\xbb\xe2\xe5\x8e\x2e\x49\x13\x8d\xd4\x01\x28\xf5\x68\x2b\xb5\xd0\x30\x13\x32\xee\x9d\x17\xd6\x45\xd5\xf8\xdd\x43\xa8\xf2\x26\x99\x26\x98\x5d\x3e\xca\x73\x9f\x2e\x6f\x50\xe4\x60\xfa\x9c\x99\x56\x06\xc6\xf4\xf7\x5f\x65\x4b\x12\xa9\x89\xce\x06\x57\x87\x53\xbd\x14\x41\x4f\xfb\x81\xa2\x71\xec\x97\xb4\xa7\xd5\xcb\xec\xea\x8a\x27\xc8\x7e\xff\xcf\x7f\x4e\xf9\xdf\x1f\xa8\x5a\x35\x9e\xb9\x12\x95\x18\xeb\x75\x0e\xef\xf3\xb6\x2d\xc0\xa1\x14\xee\xf2\xba\x08\x16\x8f\xa1\xa5\x4c\x70\x0b\xf4\xb0\xfa\xd7\x7e\xfd\xf4\xb8\x7b\xd9\x5c\xed\xd7\x5f\x6e\xd6\x7f\xee\x6f\x1e\xaf\x47\x14\x5f\x9e\x28\xad\x62\x37\xc5\x3b\x03\x9f\x5d\x7d\x6a\x5a\x30\x2e\x65\xa7\xcf\x8b\x48\x6c\x9e\x68\x4d\x30\xd1\x74\xf3\xd3\x0d\xf5\xbb\xdc\x4e\x68\x15\x3c\xd1\x86\x63\x6a\x72\x34\x7d\x7e\x32\xbe\xb4\x37\xb8\x1f\x4b\x80\xce\x2f\x67\x1d\x49\xe0\xad\x3a\xc0\xb5\xcc\x83\xfc\xbd\x3f\x6a\xa8\x4b\x7e\xaf\xd7\x5f\xf6\xf7\xf7\xdf\xf6\xb7\x9b\xdb\xd5\x9e\xf4\x47\x99\x46\x52\x5d\xfb\x56\x57\x1f\x5b\x5d\xcb\xe3\x6c\xb5\x48\x40\x48\x54\xd6\x34\xe0\xaa\x2d\x53\x0a\xe9\x27\x1f\xd2\xb2\x54\xf8\xc2\xd3\x23\xfc\x6c\x03\x7e\x6d\xf0\x46\xe0\x89\xe5\x0c\x9c\x08\x4f\x09\xed\x9b\xbc\x93\x2d\x7c\xc8\xf3\xf2\x5b\x48\x23\x2e\xa8\x1e\xd9\x07\xff\x31\x52\xea\x1e\xed\xc2\xd2\x48\x25\xa1\x94\x8c\x1c\xc1\x6b\x75\xf6\x72\x11\x93\xfb\x4b\x23\x50\x21\x59\x75\x0b\xbd\xa4\xfd\xb4\x0d\x21\x11\x62\x20\xbd\x7c\xc7\xf6\xed\xd4\x9a\xea\xa3\x9c\xb7\x32\x1a\xa3\x9e\x6d\xa5\xf3\xab\xfe\xad\xa7\x71\x94\x05\xe9\x76\x1f\x9c\x91\xa4\x3f\x26\x75\x00\x98\x6f\x74\xb5\x29\x6d\xd5\x1f\x51\x09\xae\xeb\x4f\xf5\xcf\x31\x0c\x23\x8d\x81\xf3\x31\xe9\xf4\xea\x93\xed\x5d\x4a\x89\xdb\xbc\xbf\x06\xf7\xd7\x71\xc0\x97\x86\x46\x59\x42\xc9\xc8\xf2\xf0\x93\x40\x68\xf6\x09\xa8\x22\x8e\x18\xe0\x51\x3e\x78\xdf\xbf\x4c\x0c\xa4\x82\x28\xe2\x13\x12\x5f\x4b\x85\xe5\x0f\xe3\xfa\xe6\xe5\x06\x3a\x15\xdd\xa0\xc0\x42\xc8\xf6\xa1\x1d\x8d\xeb\x54\xa8\x38\x08\xd1\x0c\x9b\xf1\x59\xc2\x36\x34\x85\x04\xf7\x7f\x1e\xc3\xf8\x02\x4d\x75\xaa\x67\x64\x21\x9e\x26\x0a\x30\xf7\xae\x21\x5f\xd6\x09\xe0\x69\x02\x06\xab\x5d\x45\xa5\xdf\xa7\xda\x0b\x3c\x4d\x55\xac\x1d\x36\xb6\x3a\xce\xfb\x55\x96\x69\x64\x3d\xb9\x04\x1b\xb2\x11\xbc\xda\x41\x88\xfa\xd2\x4c\x27\x31\x1f\xbc\x72\x46\xd4\x71\xdf\x40\x6a\x27\xb6\x35\xc1\x9e\x4c\x87\x7c\xaa\x13\xce\x1d\x48\x46\xe6\xe5\xe6\x7a\x0b\x7d\x85\x35\xd5\x60\x28\x1f\x81\xb1\xa6\x3f\x04\x46\x94\xb3\x99\x3e\x54\xf3\xc8\x2b\x05\x9e\x22\xc8\xeb\x05\x0e\xf2\xb8\x39\x1c\xab\xba\x05\xf3\x58\x75\xe7\xe9\x4f\x6f\x53\x86\x9b\xe7\xef\xbb\xdb\xf1\xec\x9b\x5a\x19\xdb\xc0\xe8\xa8\x6b\xe9\xf0\x04\x13\x86\xf0\xf2\x32\x91\x45\xd4\x99\x93\x60\x27\x59\x5e\x2b\x27\xef\x27\x8b\x52\x6b\x3d\x94\xc9\x0b\x37\x54\x4d\xfb\xa5\xaa\x7e\xcd\xc1\xe6\x59\xac\x1c\x7b\x67\x5f\xcb\x1e\x80\x93\x31\xe5\xbc\x1d\x9d\xe8\xcc\x58\x10\xcb\x37\xe0\x31\xc3\xa1\x57\xc2\xc7\xc2\x87\xc8\xb8\xce\xec\xa5\x52\x7d\x38\x68\x53\x45\x42\x2c\xee\x10\x10\xcf\xba\x7d\xb2\x57\xd0\x8e\x84\xee\x78\x26\xb2\x34\xa8\x6b\x3f\x56\x2d\x34\x23\x13\x1c\x9e\x09\x93\xc1\x18\xf1\xd9\x73\x98\x7f\xb9\x5b\xca\x92\x24\xc2\x94\xeb\xb5\x6c\xe5\xcd\x7f\x4e\x33\x03\x7b\x9e\x25\xa0\x70\x10\x40\x9d\xeb\xd3\x7b\xfe\x7b\x2d\x46\x9e\xa5\x34\x46\x14\x51\x40\xc3\x35\xf7\x88\xfa\x0a\x37\x9a\x32\xc0\x35\xed\xbb\xfc\xd1\x3d\x82\xcf\x43\x8d\x3b\x49\x96\x25\x04\xd1\xd8\x7e\xfb\x78\xeb\x14\x46\xfb\xa3\xc6\x4d\x5e\x58\xc4\x74\xf4\x75\x9b\x7f\x4e\x47\xb8\xb0\x55\xfc\xa7\xff\x4e\x1e\x4a\x26\x0e\x29\x92\x6b\x27\xe0\x12\xdf\x94\x0e\x22\xee\x8f\xab\x2c\xc1\xdc\xb0\xeb\x20\x21\x7f\xb1\x38\xfb\x66\x4a\x59\x1c\xfd\xb6\xa8\x64\x37\x9b\xf6\xe7\xd0\x3a\x09\x25\xb2\x8f\x50\x8a\xf0\xbc\x90\xef\x6f\x50\x3e\xcb\xc1\x7c\x80\x67\x5a\xeb\xc4\x57\x7e\x1d\xf0\xe7\x5b\x5e\x9f\x1a\x07\x34\xfb\xe4\xc2\x86\x28\x3d\x50\xc9\xef\xc1\xb6\xd3\x88\x27\x33\x92\x61\xa1\xb5\x87\x0d\xcb\x3a\x6f\xcf\x03\xaa\x6d\xda\x37\x20\xe6\x58\xe7\x7a\xcd\x7f\x80\x37\x1e\x79\xa8\x6a\x70\x28\xcd\xe5\x3b\x80\xc4\x15\xe2\x5f\xa1\xbd\x39\x56\xfa\x0d\x29\xe3\xd3\x26\x96\x27\x58\x13\x09\x52\x65\x7d\x9e\xe7\x37\xe3\xd6\x0a\xea\x5c\x0f\x70\x33\xec\xa9\xee\xb3\xa1\x26\x23\x42\x21\x38\x5b\x97\xcd\x05\x55\x43\x46\xa9\x45\x51\x30\x0c\x0e\x0f\xb9\xf7\x09\x1a\x88\x02\x32\xca\x2c\x7a\x98\x84\x92\x0e\x89\xc3\x7e\x56\x92\x48\x61\x19\x55\x9d\x6a\x97\x03\x1a\xa5\x80\x24\x61\x14\x6b\x96\x18\x78\xbd\x54\x79\xff\x77\x2e\x30\x4d\xda\x6d\x5d\x7f\xe4\xed\x79\xe4\x29\xc4\x25\x49\x24\x91\x03\xe4\x2e\x88\x5f\xa4\xff\xc3\xc2\xf3\x10\x1d\x23\x4d\xf5\x79\xfb\xb0\x47\xfb\xab\xf0\xd3\x38\x4e\x30\xd9\xb1\x7a\x5e\xf7\x7f\x62\x0e\x6a\xd2\x06\x6e\x50\xf0\x74\xee\x1b\x08\xb7\x2c\xe6\x0d\x26\xcd\xea\x03\x98\x3e\xcb\x3c\x7d\x4d\xb1\x30\x89\xe9\x61\xb9\xcf\x50\x1d\xfb\xcc\x82\x8c\x8d\xc1\xd5\xfc\x4d\x36\x4e\xd7\xbb\x3f\x60\xdd\xa3\x9a\xaa\x0c\xf9\xc4\x69\x87\x92\x34\xd2\x94\x4e\x1d\x9d\x3f\x4b\xbc\x48\xca\x9c\x52\x90\xc9\x1b\x8c\xb6\x2f\x0e\x5b\x26\x87\xfc\xc6\xf6\x74\x98\x05\xac\x92\xa6\x02\x17\xc0\x1f\x48\x6f\xbc\xe9\xe7\x7a\xc9\x32\x1b\x43\x5f\x36\x78\x96\x17\x97\xe6\x31\xc7\x8c\x5a\xc0\x1b\x05\x2a\x84\x3f\x9c\x50\x8e\xd1\xd9\x51\xd6\xed\x80\x09\x9e\x4c\x82\x32\xb5\x0c\xaf\x81\xeb\x41\xbf\x23\x9b\xdc\x9f\x14\x24\x1a\x29\x5e\xf7\xaf\x51\x0a\x70\x6a\xfb\xb5\x2c\xdb\x99\xd2\x2e\x97\x41\x2d\xa2\x69\xab\x5a\xbe\xce\x40\xfc\x52\x5a\x67\x99\x8d\xe3\xbb\xdb\x0e\x5e\xa8\xaf\x4d\x07\x95\x54\x91\xc6\x44\x9e\xcb\x5c\xd6\xd5\x0f\x28\x2f\x43\x60\xa9\xa4\x83\xbe\x38\x5b\xc9\xd9\x1d\xe9\xd8\x06\x97\xe5\x7b\x34\x1e\x1b\x45\xf7\xd2\x98\x0c\xbb\xdc\xf6\x98\xbf\xf7\x7f\x84\x48\xe0\x2f\xec\xa9\xd4\xfb\x88\x45\x57\xfd\x81\xd8\x12\x07\xff\x2a\x9d\xd1\xc0\xf0\xd2\x41\x18\x5c\x1b\x9f\xac\x85\x6e\xda\x7e\x3a\x8e\x4c\xae\x67\x0f\x65\x19\xc1\x41\xe3\x3e\xf0\x0e\xe4\x0c\x48\xa1\x22\x92\x82\xd3\x18\xdd\x9e\xd4\xbf\xd1\x23\x3f\x6f\x60\x27\x8f\xf3\x76\x99\x44\x04\xd9\xf5\xe6\x5b\x18\x65\x8a\xc4\x2e\xd0\x2f\xe4\xa9\xd4\x33\xc0\xa9\x22\x2c\xa6\x83\xe6\xf0\x00\x64\xea\x0e\x84\x84\xb5\x1f\x94\x0e\xec\x3c\x89\x48\x55\x6c\x1d\x70\xeb\x15\xda\xef\x58\x5a\x06\xe3\xea\x26\x2e\x1d\x3b\xbb\x18\x25\x06\x5f\xe3\xe1\x3c\xda\x3b\x28\x9a\xb9\x84\x03\x6e\x68\x57\xeb\xdd\xe6\xeb\x43\x7f\x48\xb3\x78\x20\x17\xbb\x2b\xcc\xcf\x09\x8e\xcf\x7b\x57\xc9\x22\xc8\x7d\x2f\xbe\x64\xc5\x18\x45\xd4\x16\xe8\xaa\xf4\xc8\x2c\xaf\x31\x11\x1a\x28\xc5\x83\x00\x81\x1f\x48\xe1\x10\x27\x89\xd3\x12\x36\x66\x2b\xed\x27\xe5\x5f\x25\xd2\x98\xd9\xc1\xad\x01\xea\x05\x0d\x8b\xae\x95\x93\x4b\x7d\x7e\xd9\x7c\x5b\xed\x6e\xf6\xdb\xdd\xea\x0e\xff\xfb\x12\xca\xd6\x2a\xa1\x86\x06\x24\xb7\x23\x86\x3f\xc2\xc7\x0b\xfc\xc8\x47\x64\x0d\x95\x70\x45\x9c\x50\x41\xf5\x5a\xc0\x24\x43\xab\x52\x41\x30\x59\xe9\xb8\x31\xeb\x6e\x17\x10\x22\x80\xd0\x42\x0b\x9c\x8e\x30\xb7\x82\xce\x27\x4f\xfd\xe5\x53\xe3\x6c\xb1\x30\x8b\xd7\x9d\xa0\xef\xdb\xe3\x08\x44\x65\x31\xd5\x32\x98\x6f\xf6\xf2\x1f\xd3\x0e\x92\x31\x4e\x9d\x4a\xa3\x3a\xbd\xee\xff\x7d\x32\xaf\x7d\x17\xfa\x1f\x42\xff\x77\x0e\x7d\x5f\x4a\x7c\xce\xc3\xa5\xff\x61\x43\x23\x12\xfd\xef\xe8\xcf\xe1\x9a\xda\x19\xc1\x3f\xf5\xec\xd7\x91\xc3\xda\xaf\xf2\xae\xa1\x20\xad\x32\x2b\xa2\x64\x1c\xa9\x77\x27\xba\x3b\x49\x9c\xe0\xc2\xac\xa0\x64\x14\x61\x71\xc4\xbd\x14\xa7\xff\xf9\x58\xd5\x07\xb7\xd1\x9f\xbc\x2a\x99\xb9\x5c\x84\xeb\x19\xf9\xe1\x74\xf8\x72\x36\x75\x85\x06\x6a\x9f\x4c\x0a\x4a\xea\x38\xf4\xb9\x4f\x6c\x0f\x7d\x43\x95\x18\x8c\x5f\xa5\x8b\x1f\xc2\x5f\xd3\x18\x33\x0a\xdf\x77\x4f\xc3\x9f\x20\xce\x3c\x7d\x21\x2f\x4f\xd5\xa9\x19\x7c\x5d\xb8\xea\x7a\x3f\x56\x64\x4b\x8d\x5a\xd4\x57\x27\x6b\x9f\x7b\x3b\x8f\xd0\xca\x68\x26\x83\xfc\x0d\xee\x2e\xf7\x3f\x88\xe8\x0f\x1a\x57\x10\x96\xc6\x3c\x95\x4f\x25\x38\x74\xeb\x2f\xa3\x24\x65\x80\x22\xa1\x66\x2b\x8d\x29\xe0\x79\x3e\x67\x40\x6c\x23\x77\x78\x92\x57\xfe\x2d\xe8\x28\xfc\x3c\xb5\xe0\x5c\x70\x30\x7e\x08\x34\xa4\xd5\x7c\x1a\xb1\x99\x40\x7c\xfd\xff\x7d\x7a\x9e\x1f\x01\xce\xcd\x80\x61\xbb\x3a\xdf\x1c\x64\x5e\x4c\xbb\xb9\x8e\x12\x8e\x38\x93\x5d\xa0\x62\x8d\x88\x73\x3a\xca\x6c\xec\x40\xf3\x47\x44\xc0\x8d\x19\xd0\x5c\x93\xc8\x79\xfe\x1f\xe5\x79\x55\x9a\x2f\xb2\x34\x0b\xda\x60\x93\x5b\xd2\x84\x1b\x14\x43\x06\x9f\xa6\x7b\x91\xed\xcc\x57\x91\x6b\x2a\x98\xd7\x8f\x72\xe8\x67\x24\x69\x4d\x6f\x9a\x26\x8e\xaf\xe4\xeb\x52\x4b\xd4\x76\xae\xa9\x52\x22\x68\x6c\x37\xaf\x21\xef\xac\x19\x50\x57\xeb\x80\xd2\x6c\x9d\x0d\xf4\x71\x90\x27\x9b\x9e\x82\x53\x6d\x89\x8f\xca\x7d\x00\x36\xdb\x09\x85\x86\x90\xa1\xeb\xe3\x21\x3f\x78\x9c\x8e\x60\x93\x81\xa9\x05\x8b\x42\x5d\xd7\xc1\x60\x9b\x0b\x46\x6c\x1a\x9a\x72\xaa\x24\x72\xc4\x7e\x74\x5f\x44\xf6\x4b\x9b\x4e\x52\x27\x8a\x59\x43\x5b\x9f\x9f\x6a\xa9\xbb\xf1\x3a\x93\x80\x0e\x4d\x65\x86\x4b\x42\x98\x48\x6e\x4f\x45\xe1\x93\x6e\xb7\x75\x75\xb8\x92\xe5\xfb\x34\x64\xd5\xa9\xa1\x18\xd0\xac\x77\x0f\xfd\x9f\x2c\x63\x5e\x3f\xa1\x47\x89\xeb\x8c\x3b\xaa\xb7\xe3\xbc\x62\xb6\xa7\x79\x72\x76\x43\x53\x96\xe0\xf8\x99\x32\x63\x70\x87\x75\xb7\x7e\xfa\xd7\x3f\x1c\x01\x5a\x12\x81\x7c\x6b\xbc\xcb\xbd\xa9\xca\xa1\x90\xac\x55\x0c\xde\x71\xc0\xd6\xd0\xbc\x05\xfb\x14\x4f\x29\x1d\x85\x45\x5a\x79\xfd\x6d\x97\xfa\x1b\x74\x84\xbb\x23\x20\xe3\x90\xe7\x2d\xf5\x1b\xfa\x37\xce\xf7\xfa\xa1\xad\x14\x21\xaf\x70\x1b\x20\x65\xfd\xa1\x24\x76\x80\xe8\xfb\x11\xc2\x49\x2b\x9d\xa6\x3d\x24\xfe\xeb\xf6\x1a\xe3\x9e\xfe\xa8\xa6\x04\xc9\x71\xa6\x9a\xe5\xa2\xc3\x71\x4e\x74\xec\x85\x89\x3d\x9a\xb9\x8b\xad\xc2\x51\x61\x95\x5b\x02\xab\xc3\x24\x23\xaf\x75\xe6\xe0\xbf\xe8\x8f\x33\x86\xda\x4c\x4f\x6f\xa4\x95\x81\xed\xf0\x54\xc2\xb7\xaa\x38\x0d\x6f\xcc\x0a\x82\xf4\x84\xa3\x3c\xbf\xc8\xf7\x59\x80\xaa\xad\x01\x1d\x70\x76\xdf\xbf\x4c\xf4\x54\x5d\x0b\x13\xc5\x1a\x01\x32\x6e\x88\x3f\x38\x50\xee\x20\xcb\xd5\x74\x81\xfc\xc7\x5c\x10\xc0\x90\x24\xc5\x5d\x5d\xd8\x0d\x4e\x22\x1c\x43\x32\xd9\xfb\x72\x76\xaf\x2b\xaf\x46\x00\xae\xd0\x46\x81\xe3\x8d\xd6\x88\xea\x75\x32\x56\x63\x50\x80\xa1\x8a\xa3\x4a\xd9\xb1\x2a\x72\x7d\x1e\xd8\xf1\xfe\x30\xe3\x86\x3a\xad\x5d\x34\x2f\x6f\xc2\x9c\x61\x38\x31\x24\x9b\x52\xeb\x6f\x76\x5f\x66\xd4\xf0\xd0\x96\x31\x05\x97\x6a\x85\x5f\xcb\x36\xff\xcd\xb6\xdb\x70\x9e\x61\x32\x63\xa7\xaa\xea\xfd\x77\x2e\x53\xdc\x70\x9d\x25\xde\x9f\xff\x33\x73\x88\xe9\x34\x65\x38\x08\x4c\x43\x7b\xa3\x15\xbc\x44\xef\x1d\x3a\xa2\x9f\x1b\x41\xbc\xdd\x22\x4e\xf8\x8f\xfd\xe0\x37\x82\x6a\xd4\x28\x7a\xb9\x79\x58\x6d\x1e\x37\x8f\x77\xfb\xed\xd7\xe7\xe7\xfb\xbf\xc2\xf1\x84\x18\x9c\x31\x9d\xc3\xdb\xcf\xe7\x42\xb6\xdd\xa2\xd2\x1f\x4e\x00\x53\x64\x38\x03\xa2\xfe\xcc\xc8\xf5\x9e\x9b\x34\x62\x1c\xa7\xd1\xbd\x01\x67\xc3\x17\x8e\x48\x42\xb2\xb8\x97\xf3\xbc\x95\x27\x3d\x53\x46\xe1\x46\x4a\xbf\x60\xca\x63\xde\xca\xc2\x8d\xb7\x9d\xac\x5f\x87\x5e\x24\xb5\xc1\x2d\xd2\x02\xc1\x7f\x75\x6a\x97\xcd\x6c\xb9\x51\xb1\x41\xfd\xd4\x67\x79\xae\x4e\xed\x7f\x9d\xe0\x04\xdb\x01\x84\x61\x54\xec\x8c\x3d\x9e\xab\x40\x39\x35\x9a\x3a\xdb\xff\x06\xda\x6e\xc2\x59\xdc\x75\x1b\xed\xb9\x7a\x70\x38\xb6\xe7\xed\x5b\x7e\x5c\xcb\xfa\xd5\x89\x02\xf6\x1f\x4c\x2b\xc5\x65\xbf\xc9\xf1\x5b\x93\xd9\x69\xc0\xb9\x39\x99\xc1\xa7\x16\x8b\xe7\xe1\xb0\x75\xe4\xb6\x6f\xdd\xac\x76\x40\x98\x70\xb7\x75\x0c\xb3\x8e\x6f\x65\x88\xc5\x81\xa1\xa0\xdd\x57\xe5\xbe\x9b\x16\xfa\x82\x95\x31\x31\x61\xc1\x37\x57\x16\x70\xdd\x6f\xa6\x02\xa1\xc9\x18\x95\xb8\x75\x62\x44\xa1\x7d\xae\x9a\xb6\x7d\x75\xfe\x5f\xcb\xef\xd5\xd8\x04\xa3\x0b\x93\x37\xdd\xf4\xed\x94\xf1\xaa\xf9\xf3\x01\x4b\x31\x8d\x84\xbf\x6d\xda\x7a\x02\xc0\x34\xc0\x2c\xae\x2b\xc5\x49\xbf\x9f\xbb\xa0\xb7\x96\xfa\x1d\xea\x40\x3b\x32\x00\x14\x05\x83\xff\x73\x82\xfa\x1c\x23\x7a\xf8\x4e\x36\x13\x65\xc0\x7f\xa0\x86\x62\xc0\x4a\x9c\x9c\xba\x8e\x73\x33\x64\x95\x8c\xe5\x11\xee\x22\xdb\xfc\xb8\xaf\x87\x14\xa6\xb1\x9c\x60\xca\x08\x45\x8a\x2e\x44\xfb\x38\x44\x91\x93\x82\x53\xf0\xf7\xb1\x2a\xc6\x33\x38\x44\x2c\xc2\x95\xc6\x4d\x98\x70\x41\xa0\xf8\x3f\xb3\x33\xf1\x08\x7c\xd9\x6f\x7f\xf4\x92\xe2\xfb\x6e\x9e\x9a\x1b\x84\x76\x4d\x19\x8a\xda\x3c\xa0\xbd\x74\x7e\x3a\x4c\xaf\x9b\xd2\x58\x87\xf5\xaa\xdb\x04\x4e\x82\x3d\x20\x22\x65\x01\xb9\x75\x6a\x61\xbb\x1c\xfa\x03\x65\xcc\x26\xc1\x31\x78\x98\xf3\xbb\x51\xb0\x90\xa5\x02\x2a\x34\x2e\x73\xb6\x17\xea\x1f\xdb\xbd\x71\xa0\x36\xe2\xbe\xeb\x05\x71\xd5\xd9\x43\x31\x02\x68\xe4\xe6\x4d\x83\xe6\xa5\x0b\x60\xd4\xa9\xae\x20\x8b\xeb\x7c\x09\xa7\x03\x2e\x12\x1c\x20\x3e\x45\x55\x57\x95\x1d\x61\xe5\xfe\xcf\xe2\xff\xfc\xf4\xc0\x3f\xff\x9f\xe4\x7f\xc3\xf5\x13\x8b\x3b\x66\x9f\x48\xae\x5e\xab\xaf\x75\xb1\x0c\xca\x04\x9e\x45\x88\x14\xba\xab\xab\xd3\x71\x1f\xb2\xa5\xc0\x3d\xb5\x64\x0b\xfa\x54\xe7\xed\x79\xbf\xea\x36\x5e\xce\x7f\x63\xfb\x26\x69\xd7\x01\x77\xd5\x38\xe4\x9b\x9d\xd6\x24\xe0\x1d\x81\xda\x55\x51\xcc\x33\xbd\xc0\x6d\x94\x0e\x02\x1e\xdf\xba\x17\x95\x83\xd9\x8e\xf2\x53\x4b\xca\x34\xd3\x52\x06\x08\x12\x87\x8e\x7a\x95\xd7\xed\x1b\x0a\x55\xf7\xc7\x14\x6e\xe9\xbd\x15\xa4\x2f\x52\x0c\xe9\xea\x59\x86\x0a\x04\x81\x50\xc0\xda\xcb\x5a\xe5\x6d\xb3\xff\x98\x13\x20\x16\x10\xc3\x20\x52\x4e\xe7\x56\x89\xb3\x1e\x99\x18\x86\x4e\xbb\xeb\x75\x48\x43\x41\x9a\x44\xca\xcd\xb0\x56\x9e\x8a\x76\x3c\xd0\x21\x23\x94\x25\x43\x79\x25\xff\x1b\x43\x0f\x17\xbb\x4c\x13\x86\x90\x65\x0a\x06\xbd\xe9\x2f\xf9\xeb\x1b\x34\x0e\xd4\xd1\xec\x97\x59\x52\x90\x29\x13\x8f\xb5\x1a\x7f\x59\x2e\x06\xa9\x5d\xfd\xc9\xc5\x5d\x58\x69\x58\x5c\x79\x40\x09\x12\x4c\x46\x7d\x03\x44\xcd\xff\xca\xe3\x96\x83\x66\x24\xf8\xd8\xb8\xb8\xe1\xc3\xcc\x82\x56\x30\x5c\x23\x2a\x02\x5d\x8a\x57\x45\x2e\xfb\x67\x37\x06\xa0\xb7\xd3\x1b\xb3\xa8\x2e\xb1\x33\x60\xac\x48\x8d\x7f\xa5\xdf\xc0\x31\x0c\x9c\xc1\xb7\x6f\x00\xb1\xc3\xa2\x7b\xe8\xd2\xae\x9b\x26\xeb\xdb\x7c\x14\xb4\xcf\xcc\x32\x38\x58\xe6\x6c\x5b\xec\x3e\x48\x35\x84\x93\x59\x2e\xb1\x6f\xdf\x41\x7d\x90\xa8\x1e\xf8\xc9\xdb\xb5\xd2\x89\x1a\x34\x4e\xd9\x7f\xf6\xe8\x56\xb9\xc5\xdc\xe6\x45\xb1\x7b\x83\x91\xec\x10\x58\x1b\x61\x38\xfd\x26\x6b\xa3\xab\x1a\xae\x64\xdb\x16\xd0\xed\xcb\x96\xe7\x50\x1b\x91\x34\x98\x3c\x7e\xaf\x82\xb5\x25\xb7\x51\xe2\x99\x7d\xab\xfb\xfb\x4f\x6c\xd1\xbb\x46\x4a\xb0\x21\x6b\x00\x66\x32\x9f\x76\x87\x31\x38\x7d\xd8\x3c\xee\x9f\xef\x57\x7f\xdd\xbc\x6c\xfb\x43\x90\xe0\x5b\xed\xee\x65\x57\x6d\xdb\x65\x33\x11\x6e\x23\x1b\x21\x7b\x12\x2b\x6b\xdf\x7b\x36\x4e\xf8\x3a\x96\x08\x8e\xa4\xac\x1b\xf3\x2a\xeb\x97\x5c\x77\x8f\xfd\xfd\x54\x36\xfa\x0d\xfa\x26\x99\x53\xfa\xe9\xb6\xd5\x3d\xd0\xd3\x1f\x8b\x39\x1f\x13\xef\x66\x2c\xeb\xe9\x90\xb2\xb1\x74\x92\x26\xed\xb0\x37\xb2\xb1\x71\x1e\xc3\x2e\xf3\xfa\x20\xcb\xf3\x75\x9d\x97\xef\xc3\x6f\x80\xe1\xfa\xba\x6f\xda\x7a\x5d\x95\x5a\xb6\xbf\x82\x9d\xf9\x1f\x51\xcd\x51\x55\xea\xbe\x7a\x5d\x32\xe5\x59\x8e\xe7\x2d\xe3\x31\xf7\xd2\x07\xae\x16\xb5\xdc\x8c\x13\xb7\x02\x49\x37\x39\xd3\xd9\x43\xf2\xd8\xd1\x52\x77\x77\x2f\x5f\x9f\xc7\x4b\x76\x77\x04\x8b\x27\x28\x19\x86\xbb\x9d\xfc\x92\xd3\x65\x79\x66\x70\xfa\x42\x71\x92\xc7\xf8\xe6\xa7\x06\x8c\x12\x27\x20\x81\xb0\x16\x58\x41\xa5\x9f\x8a\x61\xb3\x7e\xba\x82\x12\x10\x1e\x50\xcf\x98\x9e\x56\x24\xc4\xb9\x09\xbb\xec\xc3\xd0\x11\x26\xa7\x15\x6c\x94\x15\x3d\x5d\xc0\xe5\xe2\xd9\x38\xb5\x22\x91\xe0\x9f\xe8\xe6\x98\x37\x95\x99\xed\xae\x6c\xaa\x09\x5a\x28\xa0\xbc\xfe\x97\xea\x54\x37\x7f\x4c\x4e\x20\x29\x05\xe5\xa0\x53\x05\x52\xdd\x96\x60\xc4\x56\x2a\xca\xa6\x4a\x40\x58\xc2\xb3\x2d\xd4\x37\x4e\x70\xeb\xb3\x2f\x3b\xbb\x5f\x09\x22\x8a\x03\xdc\xbb\x39\xd5\x97\x05\x1d\xab\x0c\x41\xd5\xe3\xe7\xaa\xfc\x7b\x10\x42\xb0\xca\x18\x5c\x38\xf6\x55\xfd\x59\xe9\x28\xed\x9b\x82\x75\x3a\xad\xdd\x44\x37\x38\xda\x2e\x6e\xed\xad\x56\xcc\xc9\x33\xe7\xdd\xe6\x17\x7e\x20\x2d\xd9\xef\x95\xe7\x4e\x06\xdc\x6a\x43\x91\xb9\xd7\x05\xb6\xcd\xaa\x9e\x05\xdf\x56\x03\xc8\x34\x60\xaa\x4e\x5d\x4c\x88\x09\x33\x35\x08\xaf\x58\x03\x0a\xab\x64\x3f\xa0\x34\x55\x3d\x12\xee\xf1\xc7\x21\x62\x2c\x78\x64\xa0\x39\xd7\x8b\xe3\xc1\x3c\x56\x2d\x82\xc3\x47\x48\x6a\x0b\x9c\x63\x91\x16\x35\x20\xef\xea\xde\x89\x91\x5b\x10\x71\xe4\x5c\x54\x75\x55\x1b\xd4\x37\xb8\xbb\xd0\xaa\xb0\x60\x52\x1c\x2a\x88\xe4\xba\xaf\xaa\xf7\x53\x40\x18\x5b\xcb\x5d\x72\x20\x68\xc4\xf6\x7f\x4f\x22\xac\x69\xec\x8f\xf2\x7c\x0b\xfd\x22\x63\x6d\x26\x02\xcb\xc2\xa5\x3e\x01\xdd\x28\x1e\xaa\xb2\xfb\x08\xbe\x99\x88\x22\xc2\x7d\x51\xaf\x95\xc5\x33\x12\x1f\xfb\x43\x5c\x61\x8a\x27\xf0\x84\xba\xb5\x0c\x1f\xf6\x9f\x74\x2d\xd1\xed\x10\x22\xa7\x1c\xd2\xe6\xf6\xdc\x17\x8f\x97\x76\x01\x22\x8a\xac\x13\x36\x70\x42\xa7\x6f\x79\x61\x66\x98\xc1\x69\x73\x42\x29\xa6\xac\x7a\x77\x46\x59\x04\x44\x5e\xff\x64\x31\x73\x19\xa8\xdd\xea\x5f\xa3\x49\x47\x44\xb1\x76\x12\x02\x0e\x61\x7f\xae\xec\xe3\xa4\xcf\x60\x03\xd4\x73\x86\xf6\x6d\x0b\xa5\x99\xda\x11\x7e\xba\xee\x8b\x88\x1a\xea\xb4\x4b\x5c\xb9\xe7\x1a\x5a\x99\xcf\xd8\x7e\x22\x62\x71\x62\x3d\x6f\xe2\xee\x79\xfb\xd2\xf5\xb4\x79\x8b\x24\xc3\x84\xf6\xde\x07\x93\x5f\xf2\xa6\x5b\x41\x90\xe5\xf1\x49\x5d\xe6\x73\x31\xbb\xd0\x3e\x84\x90\x22\x62\xa9\xc6\x30\xc8\xbd\x69\xd9\xbc\x55\xa7\xfe\x8b\x73\x9d\x25\x10\x92\x14\xf5\x6b\x5e\xf6\xea\x47\xcb\x53\xbf\x88\x44\x94\xba\xf2\xb7\xb4\x70\x77\xea\xe2\x22\xbc\x64\x3c\xd5\xb4\x21\x7d\x73\x91\xe0\x82\xf2\x05\x8a\xa2\xfa\x5e\xd5\xc5\xa4\xae\x25\x22\x91\x3a\xd1\xb9\xeb\xbf\x36\xbb\xdf\xb9\x5c\xa4\xe1\x37\x36\x43\x4f\x7b\x35\x77\xca\x1e\x09\xa2\x89\x28\x89\xb4\x05\x3f\xfe\x7e\x40\x7d\x76\x6c\xc7\xe3\x31\x90\xb1\x45\x94\x50\x86\x73\x6a\x93\xbf\x96\xbb\xca\x2b\x5b\xad\x8c\xeb\x88\x83\x43\x8a\x88\x92\x24\x96\xdd\x90\x71\xc3\x21\x6f\xde\x82\xd4\xa7\x33\x5a\xbe\xcd\x65\xfb\x0c\xf5\x4d\xfb\x76\xb1\x59\xeb\x7e\x9b\x41\xd2\x57\xa3\xae\x4e\xe7\xd9\xf1\x94\xa6\x08\x20\xb5\x75\xf5\x37\x94\xbd\xef\xd2\xb4\x83\x66\xc2\x49\xf1\xa3\x9c\x50\xd7\xc9\x46\xf3\xef\xb4\xa5\x04\x8b\xb4\x8a\x22\x3f\xe4\x6d\x3f\x32\x94\xa2\xb8\x44\x6e\x37\x77\x0f\xab\xf0\x47\xed\xad\xa4\xbb\x69\xee\x5b\x15\x36\x08\x22\xd2\xa9\x9b\xd2\xba\x09\x76\x94\x8b\x14\x91\x96\x4e\x2a\xa1\xdb\x9c\xad\x8c\xf9\x94\x10\xef\x9b\x1b\x6f\x86\xe9\x16\x81\x3f\xe1\xec\xa4\x23\x67\x8f\x06\x82\x38\xe6\x62\x75\x38\xe4\xed\xae\x9a\x6c\xf4\x44\x04\x59\x86\xf2\x89\x57\x1e\x4d\x3e\x42\x2d\x77\x07\x15\x0a\xac\xb8\xfd\x89\xd3\x9e\xa9\xcf\x13\x11\x21\xdf\xd2\xf2\x08\xa7\x74\x25\x9b\x89\x47\x83\x20\x51\xc4\x64\xd7\x4d\xbe\xe5\xcd\xac\x98\x22\x48\x94\x46\x72\x9c\x18\x1d\x78\x4f\xf3\x86\x36\xc2\x3c\x45\x98\x9d\x10\x87\x30\xbd\x05\x42\xb8\x46\x0c\xd9\xc3\x39\xe8\xdb\x2f\x02\xc3\x05\x21\x82\xe1\xde\xb8\x9f\x40\x2f\xc3\xbb\xae\x91\xf3\xdc\x7c\x86\xfa\xbd\xb9\xb0\xf8\x0f\x8d\x12\x4a\x3c\xdf\x1a\xa5\xd4\x1d\xa9\x79\xa4\x24\x25\x08\x01\x8a\xa5\x91\xdb\xbc\x79\x53\xb2\x7c\xbf\xaa\xaa\xf1\x6a\x41\xe2\x04\xb0\x3f\x55\xbe\x74\x33\x9d\x90\x26\xff\x9d\xd0\x5a\xdc\x7f\x27\xb3\x52\x38\xa3\x89\x98\x83\x57\x38\x89\xd0\xc5\xcd\x4b\xb7\xf5\x76\xab\x1f\x6a\x39\xb6\x7a\x4e\x9e\x09\x17\x0b\xda\x9d\xe9\x42\x3d\x46\x10\xc6\xd3\x84\x8f\xb3\xe0\xf0\x29\x30\x72\xfa\x43\xc1\x5d\x52\xc8\xf5\x2c\x6f\x72\x8e\xd2\x11\x3d\xa3\x7a\xd4\x38\x15\x58\xb5\x44\xa3\x95\x1a\x4c\x30\x18\x76\x63\x64\x81\x0c\x22\x88\x50\x8e\x96\x31\xdc\xd8\x58\x23\x5e\x90\x84\x71\x27\x96\xd8\x5d\x72\x1f\xfe\x9a\xa6\x4e\x1c\xdc\x42\xab\xdf\x30\x4a\x6a\x6e\xab\xfa\x01\xba\xee\x14\x76\x4c\x82\x64\xb1\xb3\xa9\x3b\xd6\xf9\x0f\xd9\x42\xc0\xc4\xcc\xcb\xcb\x82\x68\x4a\x71\xe8\x61\xca\xaf\xf9\xcf\x49\xd6\xa3\x43\x12\xf7\xdb\x98\x84\xbc\x42\x51\xcb\x49\xb7\xd1\x99\x46\x0e\xeb\x10\x8e\xae\x91\x1f\x99\x7f\x0a\x7c\x14\x44\x4b\xc5\xbd\x4d\x6c\xb7\xca\x76\xc1\x10\x72\x1e\xfc\x61\xc3\x00\x85\xd8\x1f\x9f\x6e\x76\xe3\xe5\x9b\x98\xc4\x38\xe4\x18\x62\xa1\x37\x07\xf9\x3a\xff\x00\xc6\x38\x10\x7e\x30\xac\x97\xed\xc4\x23\xf6\x13\x58\xa7\x20\x10\x03\xca\x93\x62\x40\xbb\xae\xea\x5f\x4b\x8f\x09\x02\xdc\x08\xd9\x03\xb7\xff\xac\xda\xfc\x3d\xdc\x24\x68\x86\xfe\x44\xdb\xcd\xfd\xb7\x9b\x97\xfd\xea\xe1\xe9\xeb\xe3\x6e\xbf\x7b\xde\xf5\x0d\x0c\x05\x19\xbe\x78\x55\x14\x50\x37\x57\xe7\xc1\x2e\x7c\x32\xeb\x11\x9b\x4a\x1e\x8f\x23\xd0\x7d\xbc\xcf\x9d\x32\x29\x26\x49\xf6\x12\x13\x41\x5d\x5c\x5a\xe7\x18\x7b\x60\xab\x70\x2d\xab\x01\xa9\x2b\x4e\x0b\x79\xfc\x32\xe3\x28\x72\xce\x16\x88\xbb\x29\x8a\x11\x13\x64\x32\x56\xe3\xd0\x9c\x11\x0c\xe9\xd4\xe9\x3c\x5e\x0a\x62\x12\x67\x38\x3a\xb1\x7f\x4c\xd0\x2e\x22\x26\x42\x62\xc1\xe5\xb1\x72\xf7\x1e\x5c\x2b\xa6\x1f\x2d\x8e\x23\x4a\x02\x80\xa7\x32\xa7\xa2\x47\xab\x4d\x07\xcc\x28\x92\x89\x63\xca\x11\x3e\x8e\xb5\xbb\xb6\x6a\x61\x92\x62\x0a\x8d\xa4\x33\x90\x01\xf4\x0a\x68\x56\xa1\x83\xc5\x94\xc4\x4c\xf4\x95\x89\xe6\xa9\x44\x3b\xa5\xff\x1f\x6d\x7f\xd2\xdd\x38\x8e\xe5\x0f\xc3\xdf\xe5\xbf\xca\x45\x2d\x48\x90\x18\xf8\xee\x24\x5b\x76\xb8\xc2\x53\xdb\x8a\x88\xca\xac\x53\x47\x07\xc3\x85\xcc\x36\x45\xaa\x48\xca\x11\xce\x4f\xff\x1e\x5e\x00\x9c\x44\x3b\xb3\x17\xcf\xa2\x3b\x2a\x4d\x88\xa2\x48\x02\xb8\xc3\x6f\x58\x46\x30\x75\xa3\x15\x3a\x1e\x76\xcf\x0b\xca\xf6\x4b\xd5\xb4\x8f\x32\x37\xeb\xf7\xd5\xc3\xf4\x61\x91\x84\x03\x0f\x25\xaf\x72\x0f\x85\xef\x92\x2f\x2d\x30\x21\x2c\x22\x69\x1a\x05\x63\xa1\x6f\x4f\x37\x4b\x42\x37\x8c\x30\x1f\xc0\x0c\x72\xed\x0e\x0d\x31\x1d\x94\x49\x04\x1f\x21\xee\x75\x8d\xba\xab\x01\x0b\xe6\xc3\x25\xc2\x63\x83\x6b\xcd\x21\x2f\xc3\xce\x73\x53\x6e\x02\x1a\x91\x11\x6e\x7a\xdd\x8e\x6d\xae\x5f\xa1\xfd\x20\xf4\x23\x42\x10\xa0\x61\x51\x0a\x0f\x7d\x69\xeb\x27\x42\x64\x08\x70\xbc\xe9\x6b\x8c\x1f\xb5\xf9\x3e\x0c\x60\x3f\xfa\xfb\xec\x8b\xa4\x96\x81\x7b\xfe\x51\xc8\x4a\x64\xaa\x5c\xcd\xa5\x7b\x0b\xbd\x7a\xfd\x74\x84\x8a\xb2\xde\x52\xa8\x1b\x74\xdf\x9b\xbd\x32\xa2\x28\xa1\x68\x7c\x27\x0f\x70\x87\xee\x42\x4e\x5a\xbf\xdf\x0c\xc2\x38\xc6\x44\x12\x84\x35\xc6\x36\xe6\x9f\x67\x4d\x44\x53\x88\xbb\xdb\x1f\x84\x32\x7b\xf7\x9b\xf9\x1d\xe8\x6b\x11\xd3\x2c\x84\x68\xe5\x54\xc9\x2e\xef\x6e\xc2\xb5\x68\x03\x76\x84\x1e\xdd\xca\xf2\xf5\x6f\x5e\x8d\x89\x0c\xb6\x79\x76\x3f\x21\xdf\x56\x57\x79\x39\x12\x6b\xf6\x43\x40\x65\xda\xa3\x29\xae\xab\xc2\x4c\x45\xb3\xc2\x18\x43\x51\xe2\xe4\x5f\x87\xaa\x84\x56\x4e\x96\x20\x6b\x12\xe1\xfa\x32\x58\xca\x3a\x7d\x28\x81\xc9\x92\x98\x28\xc4\x55\x6d\xeb\xfc\xd8\x0c\x39\x30\x4b\xe2\x54\x62\xdd\x76\x0d\xed\x03\x36\x0f\xbf\x8b\xb4\x3f\x26\x32\x24\x2a\x3e\xde\xae\xee\x37\xdb\x31\x30\xba\x3b\xe6\xea\x78\xd0\xbe\xac\xf3\xea\x57\x17\xaf\x93\x70\x8c\xc4\xd6\xd9\x8d\xfc\xcc\x5b\xfd\x82\xf5\x65\xec\x85\x3f\xa1\x0e\xe3\x43\x61\x7a\xe3\x59\x96\x90\x04\x70\xeb\xcc\x1b\x9f\x65\xdf\xf7\xab\x6f\x92\xa4\x19\x96\x4f\x64\xb7\x18\x78\xdd\xae\x71\x4d\x93\x25\x29\x75\xcc\x6c\x87\x85\x1e\x21\x11\x58\x92\x32\xed\x9c\x87\x06\x04\xbb\x08\x87\x84\x44\x4a\x8b\xb7\x88\x43\x50\xe5\x72\xa3\x92\x25\x94\xb8\x92\xa1\xb7\xb7\x6e\xbe\x42\x08\x78\x13\xca\xa4\xca\x46\x2c\xb9\xa7\x10\xde\xf4\x03\x14\x25\x3c\xd4\xc4\x1f\xa5\x57\xb7\x9f\x9d\xdf\xa6\x01\xa8\xd5\x0b\x7b\x3f\xd6\x95\x39\xe9\x76\xd5\xfa\x88\xa6\x59\xbf\xdf\x55\xc6\xaf\x87\x61\xe5\x4b\x98\x20\xd6\x37\x55\xd0\x67\x63\xdc\x3d\x66\x09\xe7\x8a\x25\x23\x24\xd5\x6d\x25\xcb\x27\x38\x16\x52\xc3\xe5\xe9\x58\xe4\xe8\x0f\xf5\x79\xec\x96\x88\x34\x51\x3a\xa0\x2d\x27\xc1\x7e\x22\xa4\x44\x95\xc3\xcb\xcd\xfa\xdb\xf5\xee\xee\xe1\xb2\x7f\x31\x32\xe9\x78\x29\x0e\xd3\x7e\x51\xbf\x3f\x57\xc5\x03\xa2\x7f\x9b\x7e\x88\x8a\x0c\x9f\x88\xae\x5e\xe6\x8d\xae\xe1\x28\x4b\xdd\x7f\x83\x8c\x12\xec\xee\xbe\xc0\x2f\x62\x40\xcf\x6e\x9b\x8c\x3c\x01\x41\x16\x6f\x23\xb4\x5e\x38\xaa\x09\x51\x61\x7b\x1b\xfc\xa6\x59\xa2\x12\x85\x96\x99\xc1\xb3\x79\xfb\x02\x07\x30\xcf\x47\xa4\xb7\x2e\xae\xc0\x89\xa6\x71\x58\x18\x51\x1e\xf9\xe0\xa8\x52\xc8\x8a\x3f\xbb\x7f\xd3\x49\xa7\x59\x84\x18\xe6\x27\x40\x46\xfd\xc4\xf8\x86\x25\x86\x11\x04\x74\x75\x53\x7f\x62\x4a\xfd\x37\xff\x0d\xa7\x91\x11\x56\xc7\x8c\x27\xba\x0c\xae\x2f\x1e\x7f\x39\x67\x6f\xb0\x04\x88\x53\x17\x77\x31\xb9\x33\x52\x76\xfb\xd5\x28\xb4\x1d\x4f\x18\xe0\x0c\xc5\xf5\x1f\xee\x37\xbb\xcb\xd5\xef\xbf\xf5\x7f\x76\x9d\xec\x91\x19\xec\x4b\x8d\x9b\x62\xc0\x49\xb3\x04\x44\x42\x22\xdf\xd1\xb9\x7e\x7c\x0e\x7f\xb6\x44\x7a\x81\xf9\xff\x3d\x35\x93\x54\xe0\xef\xf2\x8a\xc2\x89\xd2\x08\xef\x62\xf3\x7e\x8c\x67\x6f\x81\xa5\x8e\xe6\x8e\x42\x29\x6b\x68\xc7\x44\x2f\x96\x46\x34\xc3\x0f\xea\x02\x24\x46\xf5\x5d\x54\x86\xb1\x77\x09\xc3\x28\x12\xf1\xb8\x07\xbc\x21\x0a\x73\xc9\x3e\x37\x0c\x26\x0c\x23\x1d\x8c\xf1\x70\x0a\xff\x36\x1b\x20\x32\x7c\x56\xcf\xc8\xad\xcc\x2b\x73\xb3\x7d\xd8\x35\xcb\xc9\x50\x9a\x10\xc7\x69\xed\x25\xd5\xfa\xd6\xc3\x94\x48\xc8\xd2\xc4\x44\x4e\x7e\xb7\x0b\x12\x9b\xa1\x09\x79\x53\xea\xaa\xae\x41\x23\x74\x63\x1a\xdc\xa5\xa9\x31\x68\x71\xf5\xe3\x61\xfd\x09\xd0\x88\xa5\x94\x90\xac\x07\x5f\xe5\x65\xfb\x60\x67\x97\x49\x39\xc7\x32\xf8\x60\x33\xb8\x94\xa7\xa5\x54\x26\x08\xa4\x59\x6d\xb7\x4f\xbb\xc7\xa7\x87\xcb\x6f\x17\x37\xeb\xdb\xb0\x6a\xa4\x4c\x51\x6c\xbd\x06\x3f\xb2\x56\x16\x1b\x59\x0f\xea\xf9\x2c\x65\x56\x61\x8a\xb1\x29\x40\xb7\x75\xe5\xd4\x1c\xfc\x31\x4e\xb9\x74\x10\xcc\xd2\x6d\xb4\xdb\xea\x2b\xc0\xb1\x3f\x2c\x9d\x2b\xc9\xc8\xe7\x70\xb1\xc9\xce\x52\x11\x9b\xd4\x93\x5f\xd1\xd1\x6d\xf6\x5b\x05\x49\x11\x6f\x8b\xca\xa6\xd9\x38\x8e\x4f\x05\x75\x62\x85\x4d\x3f\x17\x36\x23\x9c\xeb\xfc\x3c\x99\x92\xd9\xa4\x73\xfc\xa9\xb2\xc6\x87\x6f\x7f\x2a\x74\x84\x19\x42\x09\xa7\xee\xce\xf5\xaa\x1a\x2c\x15\x96\x38\xcc\x06\x5e\xc3\x77\x59\xe7\x52\xcd\xb5\x49\x58\x9a\x31\xc0\xf0\x72\xab\xff\x9e\x33\x04\x4b\x33\x1d\x49\x4f\xda\x09\xed\x92\xe5\x4b\x93\xb1\xf3\x99\xc5\xf0\x2e\x84\x14\xa9\xcc\x5c\x3a\xbc\xdb\x1d\x2a\x33\xa6\x95\x87\xe3\x60\xb1\xfe\xa3\x4e\xef\x17\x0b\x12\xe6\x1f\xdc\x06\x69\x1d\x2b\xec\x0e\xca\x53\x44\x3e\x9c\x9f\x21\x00\xed\x56\xdc\xcb\xaa\x28\x64\xff\x02\xe9\x58\x64\xdd\xeb\x77\xbb\xbe\x18\xaf\xd1\xa9\x26\x90\x39\x30\x17\xca\xdc\xed\xbc\xb7\x59\x7f\x58\x26\x38\x9f\xf7\x55\x61\xd6\xf3\x1a\x6a\x18\x03\xfd\xcb\xf7\x03\xe0\xd5\x41\x8d\xa7\xd7\x65\x62\x07\x90\xf5\x7d\x4f\x5c\xa6\xd6\xef\x4f\x55\x31\xc1\xe3\xb3\xd4\x70\x70\x5d\x05\x5f\x60\x6d\x1a\x98\xaf\x30\x46\x3a\x73\xe9\x1d\x2e\x6b\xde\x19\x1c\xd7\x22\xa8\xcf\xbe\xd6\xc4\xc8\x3e\xbb\xe8\x13\xe9\xe5\x0a\x52\x0a\x42\xeb\xb8\x07\xe0\x5d\xbc\xc8\x6e\xf1\x39\x3f\x9f\x4d\x9d\xad\xd3\x23\x04\x0e\x49\x33\xb9\x99\xd6\x48\x8c\x0c\x0e\x79\xd9\xa3\x0a\x59\x6a\xad\x45\x39\xbb\x4b\x90\x45\xb7\xfc\x16\xf0\x11\xf0\xa9\x6f\x57\x9e\x1b\xcd\x30\x1a\x89\x04\x55\x64\x76\xdd\x4d\x2c\x75\x0d\x26\x6f\xc1\xe0\x92\x35\x2b\x46\xd2\x48\x31\x6c\xca\x7b\x7f\x9d\xc7\xbe\x58\x43\xe3\x2e\x83\xf3\x01\x75\x71\x32\xdd\xa1\xa6\xe7\x1a\x30\x1a\x1b\x1d\xc3\xd0\x60\x5f\x7e\xf1\x29\x49\x88\xf5\x59\xac\xac\xf7\xbb\x64\x97\x97\xc7\xd3\xec\x39\xd1\x34\x05\xf4\xb0\x40\x02\x0d\x42\x29\xef\x57\x37\xb7\xbb\x8b\x87\x60\xab\xcb\x68\xaa\x38\x62\x21\x56\x6d\x5b\xd5\xd0\x5c\xe6\xfb\x1c\x9d\xec\x82\x71\x2a\xcc\x7f\x17\x8d\x04\xfe\xae\x43\x5e\x0e\xa6\x07\x8c\x52\x16\x21\x54\x74\x5f\x4b\x0d\x6e\xdb\xc1\x39\xd9\x1f\xb7\x91\x71\xf5\x94\xe3\xfb\xaa\x28\xbe\x1c\xd5\x7d\x65\xba\x98\x13\x91\x17\xdd\x93\x9a\x5e\x3a\x33\x5a\xb1\x89\xc0\xf5\x00\x4f\x66\x94\x27\x6e\x9d\xbf\x83\x5a\x9f\xea\x91\x71\x78\x38\x4e\x21\x1d\xec\x05\x46\x36\xcc\x93\x65\x86\x72\xe1\x84\xf3\x7e\xf6\x10\xf6\xa1\x91\x3b\x2a\x64\x50\x91\xc5\x28\xae\xf4\x58\xc8\x49\x74\x45\x85\x12\xaa\xf7\xb5\x58\x10\x32\x58\x02\xc9\x32\x9a\x45\x19\xa5\xfd\xd5\x7d\x39\xa7\x6e\x31\x9a\xc5\xaa\x2f\xf6\x5f\xc9\x1c\xe1\x72\x3f\x5e\xba\x34\xb6\x3a\x1e\xc1\xfc\x36\x1d\x2c\x28\x96\x68\x7b\xe9\x52\xd7\x9a\xbb\x9a\x21\x1d\x19\xcd\x0c\xe5\xc9\xa8\xd9\x1a\x80\xce\x1f\xbc\x63\x32\x25\xd4\xc1\x9d\xf5\x73\x3f\x95\xa8\x34\x4c\x3b\x7b\x90\x37\x28\xbe\x1d\x2f\xe4\xc4\xca\x7e\xda\xed\x67\x54\x45\x0e\xcb\xff\x9c\x97\xfb\x53\x81\x0c\xe5\x2d\x34\x6d\xb0\x7f\x61\x54\xf3\x4c\xf9\xd2\x0a\xd6\x0a\x2f\x65\x2b\x3d\xfd\x72\x5a\x8a\x99\x54\x64\xa8\xd6\x2c\x18\x66\x5f\x6e\x6a\x4d\x22\x2c\xb4\x61\x16\xb8\x29\xbb\x4d\x68\xea\x34\xce\xa8\xd1\x11\x86\x22\x9b\xd2\x04\x0a\xe8\x7c\xb9\x9f\xde\x2c\x50\xce\x35\x76\x8f\x20\x99\x57\xb4\x65\x1a\x9a\xaf\xd4\x1a\x92\x8c\x4b\xaa\x5e\x80\xbc\x5a\xa4\x5f\x33\x6a\x21\x4a\xbc\xf9\x5a\xf7\xd7\x1b\x1d\x62\x57\x16\x11\xe5\xb4\x2b\xd1\x5a\x15\x17\xc9\x27\xc0\xc8\xeb\xb6\x9b\x7e\x6d\xe0\xb6\xdd\x57\xed\x48\x25\x92\x61\x1b\x34\x1d\x3a\x51\xe7\x56\xda\x8c\x45\x99\x42\x9a\xd4\xce\x41\x55\xce\xf6\xba\xd9\x4d\x65\x91\x22\xc4\x91\xa2\xdf\xa1\xc6\x88\x62\x76\x3e\x95\x84\xba\xcb\xf3\xe9\x70\x53\xae\xdf\xfb\x16\x79\xb8\xcf\x2c\x52\x0a\xcb\x57\x2e\xec\x5f\x15\x05\xaa\x3b\xcd\x7a\xad\x67\x3d\x00\xb1\x58\xf1\x65\x91\x56\xd6\xb5\x0e\x51\xfb\x07\x74\x3e\xec\x8b\x2c\x8e\x22\xdc\x4e\xdd\xe4\x9b\xa5\x21\x61\x4c\x46\x02\x03\xe3\x56\x36\xed\xea\x64\xf2\xf6\xb2\xd2\xa7\x6e\xac\x3c\x83\xb2\x30\x46\xb8\xc0\x18\x0f\x5f\xee\x1d\xdf\xc9\x71\x21\x80\x11\x01\x48\xfc\xfc\x09\x79\xe3\xf1\xcd\x33\x4e\x2f\x63\x49\xa4\x02\x83\xd6\x63\x99\xe5\xec\x9a\x92\x84\x72\x67\xa1\xd2\xa0\x96\x7b\xae\x0a\xac\x54\xdd\xc1\xe7\xf2\x67\x0b\xe1\x92\xdb\xa3\x66\x17\xa0\x52\xed\x42\xa2\x93\x19\x19\xef\x31\x96\x46\x02\xfc\x95\x39\x0d\x82\xaf\xf0\x3e\xc9\x56\x58\xca\x05\x62\xcc\xee\xe1\x54\x57\x97\xab\x87\xe5\x6a\x05\x4b\xb9\x92\x7a\xa2\xd1\xee\x8c\xce\x67\xbf\x93\xc5\x2e\x31\x85\xf6\x65\x57\x07\x8f\xab\x70\x8c\xa7\x09\xed\xf5\x5f\xba\x6c\x90\xce\xee\x23\xb3\x1a\x9b\x04\x2f\x55\x61\xf2\x72\xdf\x3c\xd8\xdd\x7a\x33\xd3\x8f\x62\x8c\x27\x29\xa2\xd1\x64\xd3\x40\xdd\x6e\xfe\x1b\x53\x0f\x1c\xa7\xff\x98\xfc\xdb\xbf\x9e\x42\xa6\x58\xbe\x73\xec\x67\xef\xd6\x04\x8f\xb2\xd6\x50\x34\x73\x72\xf7\xbf\xff\x33\xbb\xb7\x99\xd6\xa1\x1a\x72\x55\x03\x60\x2c\x56\x7f\x80\x81\x60\x19\x44\x18\x25\x1d\xf2\xbd\x23\x21\x04\x90\xe9\xa8\x0c\xc9\x14\x75\xca\xdc\xd8\xed\x77\x77\x33\x1f\xfc\xd5\x19\x53\x59\x82\x72\xd8\x5d\xee\x7e\x55\xd5\x4f\x70\xac\xea\xb6\x4b\x24\x07\x45\xde\xdf\x96\x16\x6f\xa6\x23\x87\x53\xda\x9d\xca\xee\xb3\xc1\xdb\x2f\x9c\xd7\x88\x34\x92\x13\xa1\xc9\x74\x22\x34\xc9\x98\xb1\x24\x09\x6e\x79\x79\xf9\x3a\xee\x27\x31\xa0\x31\x32\xb9\xaa\xa6\xc8\x5f\xc7\x3b\x22\xb3\x29\xc5\xbd\x6d\x2d\x9b\x5c\x93\x64\x30\xa1\x5c\xbe\x47\x96\xf1\xc4\x99\xae\x38\x0d\xae\x97\xbc\x30\x53\xb1\x5c\xc6\x23\xe2\xb4\x03\x43\x75\xba\x99\x2d\x4b\x3c\x4a\x9c\xd4\xe5\xfe\x73\xb3\xcd\x30\x9a\x47\x48\x0a\x38\xe4\x06\x2b\x37\x18\x2b\x8f\xfb\xd4\x3c\xd2\x8e\x15\xbe\x2e\x4e\x5e\x6f\xac\x3f\x02\x31\x16\x8d\xdd\x7a\x7a\x0b\x7b\x28\x8d\x1c\x3a\x2a\x4b\x6b\x18\x8f\x23\x57\xdf\x6c\xba\x05\xe1\x0d\x42\x08\xbf\xd0\x63\xe1\x31\x75\x22\x8b\xeb\xca\xbc\x3f\x94\x0b\xaa\x0b\x8c\xc7\x4a\x38\x31\x6a\x94\x2e\x79\x18\x43\xbb\xfe\x9d\x2c\xf3\x82\x45\xf8\x28\x58\xd4\x88\xdf\xd7\xfb\xd9\x49\x49\x42\x62\x3a\x42\x34\x76\xd9\xf1\x6f\xd3\x96\xf0\xe2\x1e\xc9\x09\x08\x8c\x10\x6e\xab\x7d\x40\x03\x2f\xe8\xc1\xcd\x3e\x63\x63\xac\xf7\xa1\xcf\x0d\xba\x90\x7a\xa0\x81\x3f\x9e\x44\x19\x32\xc5\x65\x51\x5c\x9f\xae\xf3\x37\x28\x77\xfd\x21\xe1\x70\x8c\xeb\x53\x5d\xf6\xf4\xa2\x3e\x11\xa3\x91\x2f\x3d\xf1\x34\x33\xd8\x78\xfd\xe3\x61\xac\x83\xc9\x38\xd5\x16\x4b\x27\x77\xf2\xd7\x5f\x91\x9f\x18\x67\x59\x96\xd8\xb1\x8d\x57\xef\x22\x38\xfd\x3d\x3c\xd1\x12\x7a\xab\xd7\x43\x35\x4b\x58\xc3\x28\x50\xe0\x59\xe7\xf9\x7e\x2c\x9a\x37\x79\x52\xcb\x75\x75\x2e\xd2\x14\xb9\x88\x9e\x77\x76\x97\x8f\xfa\x41\x5c\x68\x82\x31\xe8\x97\xca\x14\x9b\x99\x6b\x16\xe3\x59\x94\x62\x79\x0a\xe9\x7a\xcb\x93\x90\x67\xd4\x39\x18\x35\xa8\xf7\x7b\xa6\x10\xcb\xb8\x64\x0c\x17\x7c\xe7\x9c\x8c\x59\xcf\x07\xa7\x52\x09\xb3\xfe\x66\x5c\xe5\x8d\x96\xc5\x77\x27\xe7\x3d\xfd\x3d\x2a\x71\x5d\x0b\x17\x23\xe0\x2c\x1c\x97\x39\xb8\xe2\x19\xba\x91\x0d\x52\xfc\x4f\xe8\xed\xf6\xf9\xcb\xa8\xc0\x71\x16\x9f\xbf\x7d\xdf\x6d\x7f\x7f\x0c\x55\x1f\xae\x23\x8a\x40\xc8\x12\x7e\x3e\x56\xe5\x9f\xf9\x55\x9d\xcf\x01\x9b\x8c\x6b\x22\xe8\x98\x60\x84\x4f\x7a\x96\xfb\x70\xcd\x00\x17\x63\xd7\x50\x7e\xca\x4d\x0f\x66\xe3\x9a\x83\x91\xfd\x1a\x84\xaf\xf5\x7a\xce\xff\x63\x1c\x48\x8a\x5b\x82\x85\x2e\x47\xd2\x72\xdc\xdf\xe7\x90\x51\xa4\xfa\xdc\xaf\x36\x17\xfd\xdf\xa4\x23\xf5\xfe\xd8\x3c\x3f\x4f\x5e\x65\x00\x67\x4f\x78\xac\xf3\xb7\xbc\x80\xfd\x20\xb7\x7d\xdb\xcb\x9a\x31\x6e\xb3\x2c\x92\x53\x9b\xb5\x6f\xcf\xf3\x8b\xb2\x0a\x10\xf1\xba\x2a\xab\xee\x49\xb8\x89\x8c\xdb\xe3\x3c\xb8\x11\x51\x2a\xa5\x09\x7d\x64\x0c\x6d\x66\xc7\x81\xa2\xb0\x07\x1c\xf2\xf6\x9f\x95\x42\x2c\xc3\x4a\x6b\x38\x2e\x64\xdb\xfe\x23\x71\xa2\xa9\xeb\xc3\x15\x05\xd4\x37\x66\x5e\xda\x10\x71\x2a\xb0\x88\xbb\x3b\xd6\x7d\xb3\x6d\xc1\xa8\xa8\x1b\x98\xe1\x23\xd8\x3e\x3d\xdc\x5f\xdc\xae\x9e\x9f\x6f\xc2\x6d\x14\xb1\x8c\xb0\xc7\x83\x2f\xf0\x73\x70\xf0\x5c\x1d\xf3\xaf\xf0\x3e\xd9\xf5\x04\x89\x5c\xdf\xff\x0f\xa8\x2b\x74\xae\x19\xdf\x75\x41\x22\x89\xc5\x0c\xb7\x50\xde\x74\x29\xf7\x38\xc0\x9b\x4e\x06\x91\xa4\x2c\x8e\x46\xdd\x91\x4d\xa3\xe5\x71\xc2\xa6\x4e\xc8\x3f\x46\xd9\xe6\x24\x73\x12\x09\x8b\x31\xd8\x86\x5f\x79\xd3\x36\xcb\xa5\x44\x91\x80\x9b\xde\x3f\xbe\x7c\x9b\x5c\x68\x4a\x94\x1e\x54\x53\xee\x2b\xc4\x5d\x0e\x2b\x3a\x4b\x7d\xd9\xaa\xfb\x1f\xe1\x23\xd4\x3a\xdc\xe1\x0b\x5c\xbc\x2b\xa8\xaf\x65\x0b\xaf\x00\x47\xa8\xb7\x3f\xab\xfe\xbc\x8c\x83\xd3\xac\x28\xf2\xb7\xde\x12\x66\xfa\xb3\xd3\x4c\xa2\x89\x1d\xda\x9a\x77\x51\xff\xc5\x4b\x35\x77\x6f\x60\x68\xc9\xe6\x27\x0c\x16\x5b\xf3\xaa\x1c\x55\xf4\x05\x25\x16\xbb\x37\x0a\x43\xa2\x49\x5b\x48\xb0\x04\xd0\x43\x24\x2f\xcf\x15\x36\x67\x8f\x80\x71\x8e\x85\x80\xb6\x3e\xc1\xec\x24\x19\x38\xb0\x18\xc2\x2c\x8b\xaa\x01\xd3\x3b\x9f\x87\x31\x42\x51\xeb\xb5\x51\xef\x7a\x86\x40\xb3\x7e\xdf\xbe\x1f\x67\xeb\xbb\xc8\xb8\x46\x25\x45\x5f\x00\xef\x17\x06\x91\x49\x8a\xd5\xbb\xe3\xa9\x9d\x3c\x21\x29\x04\x42\x32\x7a\x3b\xc9\xeb\x5a\x1e\x61\x7d\x7a\x77\x2a\xc1\xb3\xd3\x1b\xa2\x30\xe0\xfa\x03\x4e\xe3\xc6\xaa\x30\x34\x11\xc9\x8c\x17\xd9\xc5\x4f\xe3\xb9\xb9\xdc\x9b\x1f\x17\x44\x85\x01\x6b\xa2\x00\x58\x3c\x54\x6f\xce\x05\x07\x35\xff\xfc\x0f\xba\x69\xe1\x70\x6e\x3d\xfd\x21\xa1\x81\x09\x63\xb9\x33\x5d\x2d\x5a\xa8\xaf\x00\x3b\x59\x66\x9a\xd8\xfb\x91\x90\x68\x44\xcf\x6c\xaa\xe6\x31\xff\xf3\x4f\xf9\x5c\xe4\x1a\x50\x4a\x66\xfa\xc6\x80\x72\x44\x3b\x67\xb4\xe7\xf0\x54\x1f\xcc\x3c\x4b\x28\xa6\x05\x37\xba\x2a\x3f\x60\x33\x31\x61\x33\x8d\x4b\x3e\xa2\x52\xf2\xa6\x75\xdc\xd0\xa5\xbe\x42\x16\x09\x95\xd8\x91\x7c\x63\x80\xa5\xdd\x82\xd9\x43\xbd\xda\x7e\x7e\xab\xc3\x6c\xcd\x22\x61\x91\x49\x7b\x75\x75\xfd\x59\xe8\x91\x45\xc6\x79\x36\x5c\x40\xf7\xca\x15\xc5\xfb\x4d\xb7\x7b\x9b\xf1\xfb\x93\xc5\xb1\x73\xe5\xde\x16\x7a\xf4\x42\x64\x71\xe2\xf1\xbe\x2f\x75\x55\x1d\xa0\x7e\xbf\x92\xf5\xa1\xcf\x99\x33\x22\xb5\x18\x9b\x1c\xf6\x6a\x71\xf7\xd5\xd4\xca\x8e\x65\x09\x03\xe3\x7a\xe6\xd8\x93\x3a\x3a\xe3\x13\xc4\x97\xe3\xaf\xf2\xc1\x8a\x18\xf9\xd3\x8c\x5e\xac\x0f\xf8\x18\xff\x19\xbf\x76\x19\x4d\x01\xc5\xd6\x7b\xf6\xdd\xe4\x29\x66\x2c\x8d\x82\xfe\x1c\x32\x5c\xff\x4f\x5d\x8b\x8c\x89\x08\xd7\x6a\x69\xcc\x6a\xed\x3f\xfa\x01\x9b\x30\x7c\x02\x20\xf8\x83\x77\xb7\xda\x38\x37\xf3\x2b\xc0\xc6\xf1\xf9\x86\x93\xf1\xc4\xe1\x59\x9f\xbc\xdd\xfb\xa1\xdb\x31\xca\x72\x70\x94\x5b\x8e\x80\x33\x41\x15\xf8\x65\xa5\x5b\x23\x9f\x65\x21\x83\xaa\x1f\xcb\xb2\x54\x61\x75\xe0\x29\xf8\x0b\xb3\x2c\x13\x29\xfa\xb8\x75\x67\x19\x97\x80\xb2\x4c\x32\x6a\x7b\xbf\xf9\x49\x2e\x9f\x49\x2d\x42\x47\x00\x81\x8e\x50\x6a\x08\x12\xc7\xcb\xc1\x5b\x26\x6d\x6c\xbd\xc6\x7b\xde\xbc\x84\x77\xfd\x1a\xfa\x73\x2a\x42\xac\x73\xe0\xec\x21\x5d\x5e\x5b\x1a\x55\x0f\x47\x7a\x0a\x2c\x53\x89\x45\xf0\x5d\x8f\x89\x6b\x7c\x55\x6b\x56\xc7\xca\x34\x4b\xb0\xee\xaf\x64\x40\x49\x6e\x6b\xe9\xb5\xaf\xc5\xbf\xc9\x7f\x46\xba\x47\xe9\x7f\x46\xaf\x12\xff\xcf\x90\x9e\xff\x9b\xfd\x27\xec\x63\x99\x16\x8e\x8f\xae\x4e\xef\xe1\x71\x4c\x9e\xb2\x49\x13\x0c\x77\x7c\x7f\x23\x70\xe7\x6f\xbf\x6d\x67\x8f\xd7\x70\x41\x87\xf5\xe6\xae\x32\x0b\xec\xf1\x6e\x94\xc1\x39\x8d\x2f\xc8\x2d\x48\x93\x97\xfb\x2e\x78\xf8\x60\x69\xca\x20\x02\x44\x48\x07\xe9\x65\xbf\x2b\x2d\x06\x47\x99\x8d\xb5\xdb\x3c\x5c\x8b\x60\xf0\xb5\xcc\xab\xd2\x8b\x25\xf9\xdb\x28\xa3\xd4\xad\x19\x85\x6c\xba\x07\x5e\xd7\xb2\x68\x10\x43\x1f\xb2\x27\x19\x73\x8b\xb1\xe4\xa1\x32\xb9\x7d\xc7\xce\xe3\xc5\xa0\x92\x36\xbd\x4c\x19\x7b\xfb\xef\x2f\x50\xe4\xd5\xa4\xc3\x22\x09\x58\x2c\x0c\xdc\x94\x06\x0e\x65\xde\xe0\xd5\x04\xe7\x06\x26\x89\xcd\x84\xec\x4b\x3b\x4d\x55\xca\x02\xb5\x9c\xae\x7a\xef\x61\xf8\x60\x45\x96\x49\xcc\xe3\xe1\x8e\xaf\x8a\x62\xd5\xb6\xde\xd4\x0d\x45\xd4\x2f\xaa\x02\x43\x05\x35\xdf\x1f\x65\x92\x48\x04\x3e\x3e\x55\xa7\xd2\xac\x07\x95\x14\x26\x13\x9e\x60\xee\x94\x97\x23\xa9\xeb\x99\xb0\xc6\xec\xb7\x27\x3a\xc3\x66\xf3\x8d\x3d\xcb\xd2\x26\xeb\xb9\x4c\x20\x42\x0a\x4f\x20\xe0\x98\x78\xe0\x1c\x33\x99\x46\x80\xe0\x98\x9d\xfb\x39\x9b\x5f\xd8\xed\x99\x85\xd4\x32\xb5\x0c\x17\x83\xbb\x87\xbb\xf0\x41\x1a\xd1\x20\x76\xd8\xdd\xb5\xd9\x4f\xa5\xdc\x89\x5a\x76\x97\x82\x3b\xb4\x0f\xec\xe2\xf1\xd2\x2a\x29\x38\xc7\xc2\xbe\xd8\x17\x2a\xb0\xcb\x77\x9e\x5a\x8b\x19\xb3\x4b\x14\xbc\x60\xda\x78\xda\x48\x16\x6b\x54\x9b\x39\x80\xc9\x75\x15\xc2\x1b\xc9\x98\xd1\xbe\x4a\xfe\xbd\x6a\xe1\x09\x9a\x53\xd1\x07\x50\x92\xab\x0c\xfb\xfa\x07\xf9\x6b\xcc\x6a\xbc\x19\x55\xb8\xa4\x30\x32\xe1\xbd\x0b\xfd\x0f\x04\xc9\xcc\x42\x4a\x99\xc5\x12\xc3\xdc\x67\xf4\x40\x58\xda\x5b\x65\x96\xa6\xa8\xd6\xf7\x03\x8a\xe2\xfd\x51\xf6\xa7\x97\x09\x45\x2e\xc5\xe3\xb7\xf5\xed\xcd\xc5\xee\x79\x75\xbb\x79\xde\x91\xdd\xe3\xe6\xe9\xe6\xe1\x72\xb7\xe9\x57\x59\x29\xa9\xb3\x35\x40\x41\x38\xd5\x54\xc5\xa9\x85\x40\x2d\xea\x53\x53\x29\x99\xc6\xd6\xf2\x63\x72\x39\xf5\xdc\x66\x52\x25\x4e\x3b\xf1\x69\xf3\xbc\x79\xfa\xbe\xb9\xdc\x6d\x1f\xbe\x6e\xee\x9f\x77\x57\x0f\x4f\xbb\x9b\x8b\x87\x1d\x5a\xb1\x6d\x9e\xfb\xe1\x56\xa3\x6e\x61\x77\xdb\xa6\x5d\xa7\xd9\xb3\xd1\xca\x31\x12\x43\x1a\xe1\xaa\xf9\x23\x60\x50\x18\x07\x99\x0a\x4e\xce\x17\x0f\x3f\x00\x5e\xe3\x85\x3e\xb0\x04\x6a\x21\x54\xcb\x86\x22\xe2\x42\xa5\x4c\x82\x56\x59\xf7\xc5\xbb\xc2\x09\xcf\x4e\x6b\x26\xcb\x2f\x92\x65\x4a\xfa\x3e\xc7\x25\x7c\x84\x77\x93\x56\xc6\x98\x19\xa1\xd3\x74\x2d\x47\x70\x36\x15\x09\x42\x44\xef\x6f\x13\x80\xf9\xb3\x49\xa0\x22\xe5\x18\x8b\xba\x2a\xf7\xa3\x67\xa0\x22\xab\xf1\x92\x11\xee\x82\xd2\x74\xd8\xd1\x9c\xbc\xca\x2a\x4e\x29\x06\xcd\x9b\x3f\x9d\xd5\xbc\xff\x33\xe1\x49\x16\x87\xcf\x0e\x2d\xc5\xcf\xa2\x0d\x11\x3e\xaa\x00\x1b\x6b\xdd\x63\x7e\x5a\x6d\x37\x01\xa4\xa8\x12\x6a\xb9\x23\xac\x4b\xb3\x3b\x05\x35\x38\xa6\x52\xc6\xc6\x9e\x72\x3f\x64\x5f\xff\x52\x29\xe3\x03\xfc\x15\x25\x0a\x97\xa8\xc9\x4c\x51\x70\x75\x1f\x23\x5b\xf9\x8c\x22\x59\xc1\x8a\x10\x17\xc1\x07\xfb\x9c\xff\x6a\x01\xa6\xcd\xbd\x70\xc1\xcc\xb3\xc9\x57\xa5\xec\x3b\x51\x8a\x81\x76\xee\xe3\x2f\xd5\xcf\x5b\xd9\xb4\x53\x47\xfd\x30\xc8\xa6\x98\x89\xb8\xda\xcd\xdd\x74\x62\xcf\x9e\x12\x8f\x53\x07\x9b\xfe\xad\xff\x83\x93\x47\x6a\xa0\x5d\x9d\xda\xea\x1e\x7e\xaa\xaa\x34\x83\x2e\x10\x53\x9c\x39\x07\xf4\xbb\x53\x17\x83\x04\x74\xcb\xec\x1a\xb8\x12\x98\x5b\x34\x3d\xb4\xcf\xc3\x84\xa7\xc3\x84\x70\x1e\x88\x0d\xb4\xb7\xb7\xdf\x77\x60\xf2\x76\x17\x47\xd3\x77\x41\xd8\x48\x06\x82\xf7\x40\x2d\xed\x2f\x38\x4b\xa9\x0a\x89\x51\x77\x57\xc7\x52\x92\x4c\x49\x9e\x25\x43\xe9\xcf\x15\x9e\x1d\x69\x71\x79\x57\x55\x2a\x56\xe8\x85\x71\x84\x3d\x46\x50\x7f\x0f\x79\xbc\x1c\xe0\x2a\x15\x03\x6a\xce\xb6\x95\xdf\x17\x67\x77\x5f\x51\xe9\x48\x54\xa7\x77\x07\xe2\x98\xde\x1d\xc5\xe3\xe0\x58\xe0\x11\x1c\x50\xe3\x6f\x0c\xbf\x4e\x09\x8b\x0b\x33\x32\xa1\x67\x5e\xbb\xd3\x6f\xd2\x24\x49\x44\xd0\x22\x6e\x4e\x87\x81\x71\xcb\x94\x49\x01\xa9\x39\xdd\x57\x04\xad\xc6\x8f\x40\xe3\xd3\x0b\x34\x20\x31\xe9\x3a\x56\x4d\xeb\x42\xc2\xcf\x44\xe7\x99\x82\x24\x13\x4e\x7b\xca\xbb\x1f\x5e\x55\xf5\x99\x5a\x3e\x53\x40\x5d\x5f\x37\x6f\x3c\xf0\xe2\x21\x44\x36\x0a\x24\x20\xd0\xc9\x54\x3d\xaa\xfb\xa3\x47\xf1\x69\xd9\x41\x59\x65\x52\x9f\x49\x20\x65\xe3\x71\xd0\xe3\x3b\xbb\x7b\x3a\x22\x20\xc4\x28\x8a\x18\xa4\x6c\xfc\x00\x92\x18\x84\xbc\x6c\x8a\xbc\x85\xe7\x97\xfc\x78\x0c\x2e\x29\x9f\x24\x91\x9a\x28\x9a\x18\x34\x2c\xc9\x0f\x7a\x5e\xc9\xd2\x04\x04\x8a\x87\x4b\xac\xce\xcd\x17\xf5\xa5\xdc\xcd\x7f\x30\xd1\x10\xca\xdd\xdf\x57\x6d\x75\x70\xb1\xfc\xd2\x05\xa4\x94\x62\x64\xd3\x4d\x2d\x72\xeb\x4c\x17\x46\xad\x2f\x4d\xb9\xc5\xec\x4f\x25\x64\x5b\xad\xdf\x7b\x81\xd4\x70\x38\x4b\x63\x34\xf8\x7a\xbe\x9c\x5c\x39\x55\x3a\xee\x99\xc8\x61\x81\x30\xbf\x9d\x66\x2a\x87\x4c\x33\xcb\x98\x27\xc3\x3c\xe7\xc5\xdb\x47\x1c\xf8\xe5\xd8\x4e\x0b\x9d\x66\xf1\xb8\xfc\x0f\x35\x16\x0a\x7e\x3b\x27\xba\xe8\x2c\xe3\xb8\xca\x23\x33\xab\x3d\x29\x64\x7f\x84\xeb\x95\x09\x51\x34\x4c\xa3\xcd\xaf\xbc\x99\xee\x46\x5a\x45\x09\xf6\x3b\xbe\xde\xac\x6f\x9e\x77\x93\x9f\xaa\x68\x12\x7b\x2a\x08\xee\xd5\xa5\x73\x92\xbc\x5d\xe8\xa7\xcd\x9e\x92\xa2\x1a\xb1\xb4\x16\xba\x08\xf2\x2a\xaf\x9b\x76\x55\x23\x8e\xc1\x2d\xea\x13\x43\x04\xa6\x95\x24\xa1\xb1\xbf\x2a\x8a\xf5\xe9\x7d\xa0\x14\x6a\x4d\xa5\xc3\x7d\x42\xd3\xde\x34\x0f\xa8\xec\xf0\x28\xf3\xfa\xc9\x87\x23\x0b\x00\xef\xcf\xaf\xcd\xf0\x58\x41\x1f\xf0\x29\xa8\x1f\xac\x93\x04\xee\xbf\xd2\x28\x89\xa1\x91\x3c\x1e\xa1\x9c\x32\x90\x35\x44\x04\xa1\xfc\x61\xb6\x7c\x46\x43\xd7\x20\x12\x32\xf0\x02\x9f\x5b\x59\x3b\x10\xfb\x07\xa3\x33\x81\x71\x77\xcf\x1f\xad\xca\x99\x2f\x0f\xd3\x60\x53\xac\x49\x04\x8b\x21\x17\x47\x26\xbb\xe7\xed\xea\x6b\xe8\x38\x68\x1b\x03\x62\x43\xae\xa1\x5b\xe4\x47\xe5\x19\x13\xc5\x9c\xf0\x60\xfd\x8a\x30\xfe\xad\xfc\xf5\x28\x6b\x79\x80\xf6\xc3\x4e\xb2\x89\x84\x53\xc9\xc4\x82\x01\xa6\xd3\x41\x69\x97\x99\x48\xa5\x18\x1d\x7a\xd0\x60\xe3\xed\x33\x5c\x53\x7d\x34\x08\xfb\x0e\x75\x37\x28\x19\xa5\x47\x26\x26\x89\xc7\xff\x62\x6b\xe9\x13\x00\xb0\x89\x25\xf3\xb2\xa9\x48\xdb\x0b\x7f\x26\x49\x9c\x26\x23\x88\x85\x2f\xf7\x87\x2e\xc8\xb4\xf5\x63\x08\x73\xb6\xbc\xae\xc9\xd8\x6d\x5c\xb2\x85\x5a\x16\x8f\x55\x35\x55\xc4\x64\x86\x80\x23\x6d\x7c\x79\xb8\xbd\x44\xf0\xda\x20\x03\xcd\x0c\xb1\x80\xc5\x3b\xcf\x9a\x44\x39\xc6\x2e\x6e\x1b\x6c\x1e\x98\x49\x28\x18\x4f\x12\x70\x1d\x9b\x59\x7c\x62\x12\x49\x94\x08\x4d\xf0\x5e\x78\xf1\x62\x26\x1d\xce\x4c\xa2\x6d\xe4\xca\xfe\xf2\xcf\x77\x90\xf5\x79\x86\x62\x12\x9b\x2a\xee\xc0\x0e\x4f\xb2\x85\x6f\x4f\xb7\xe1\x2a\x52\x9d\x62\xd3\xe8\xdb\x7a\x7b\xd1\xff\x0d\x94\xe5\x7e\x4e\xed\xb0\x55\x3e\x26\x04\x9a\xd4\x02\x36\xb4\xdf\x72\xf0\x58\xae\x27\x38\xc8\x7c\x04\x54\x36\xa9\xb5\x38\x2b\x91\x9d\x59\xcc\x6f\x1d\x8d\x05\x96\x4a\x51\x76\xde\xa9\x50\xdd\xe5\xf3\xce\xa5\xa1\x49\xca\x32\x2f\x54\xfb\xe8\x9e\xff\x66\xfb\x25\x7c\x03\x4d\x2d\x66\x90\x18\xa8\x74\x7b\xd2\x9d\x93\x18\x0e\xf4\x93\xcf\x44\xed\xfe\x6a\xbb\x0c\x5f\x91\x65\x19\xeb\xa9\xa2\xde\xcc\x33\xaf\xc6\x64\x7e\x43\xf5\x60\xa6\x26\x9b\xe6\x58\xd5\xed\x6d\xb5\xcf\x75\xa0\x8f\x87\x71\x4c\x0b\xe9\x23\xb5\xad\x2c\x5f\xc7\xd0\xf8\xfe\xe5\x63\x3a\x73\x16\x8c\xd2\xf3\xca\x7a\x55\x4b\x3f\x80\xa7\x11\x86\x3c\x23\xd4\xe1\x79\x0f\xde\x08\xe9\xb2\x51\xef\x2f\xe3\x31\x24\xbe\x20\x1d\x76\xd0\x64\x5c\xab\xea\xff\xe3\x33\xfb\x42\x66\x32\xe2\x84\x0b\x8a\x2e\xf8\x96\x45\x31\xd6\x89\x09\x43\x54\xa4\xa9\xa7\x1b\x9c\x13\x43\xfa\x2d\xc9\x74\x73\x35\x72\x34\xb8\x21\x18\x33\xca\x4a\x94\x56\xba\xbc\xb9\x9f\x90\x76\x8d\x16\x02\x4b\x7f\x48\xdf\x36\xb0\xfd\xd7\xff\xad\xd8\x6a\xb4\x70\x24\xd2\xa3\x5b\xd4\xbc\xaa\x16\x4e\xea\x30\xc2\x67\x6c\xf8\xca\x87\x54\xb6\xdb\xcd\xaa\x53\x3b\xc0\x4d\x07\x5e\xaa\x31\x51\x12\x72\x85\x27\x30\x00\x87\x05\xac\xbc\x31\xd4\xc5\xc0\x5d\x26\x50\x35\x0d\xc6\xaf\x23\x4e\xe5\x30\x10\xb2\x0c\x39\x5c\xcf\xd0\xfa\x18\x7e\xf9\x87\x80\x4d\x94\x7f\xdd\x2e\x4f\xaf\x4e\x8a\x72\xbc\xff\x18\x9b\x98\x60\x74\xec\xe4\xe7\xf1\xb9\xdf\xe5\xe5\xb5\x6c\xee\x01\x4c\x8f\x71\x82\x18\x28\x32\x5b\xef\xe5\x21\xc7\x14\xd6\xff\x9d\x30\xe7\xa1\xe7\x37\x25\x94\x55\xf2\x0d\xcd\x0f\xe4\x43\xc2\x07\x75\x1a\xe9\xa1\x3c\x66\x6d\x5e\xe4\x67\xb0\x7f\x48\x22\x86\x8b\x55\x09\xbf\xda\xab\x02\x7e\xe5\xaa\x00\x1f\xbd\x87\x11\x44\x2b\x6f\xeb\xf4\xec\x4c\x95\xaf\x5c\x3f\xfa\x23\x1d\xf5\xee\x23\xce\x52\x09\x65\xd7\x50\x5c\x77\x59\x0d\x01\x12\xa6\x5d\xca\x77\x04\xd0\x2f\x0f\xf6\xdc\x5f\x89\x41\xc2\x9d\x56\x5a\x1b\x60\xaa\x57\x88\x80\x0d\x47\xb3\x4c\xc7\x41\xc1\xf5\x32\x7f\xcb\x9b\x79\x09\x0c\x52\xce\xf0\x61\xea\x60\x48\x34\x4d\x8d\x21\xcd\xd2\x88\xf7\x4e\x70\xdf\xca\xbc\x9d\x9f\x20\xcb\x12\xdd\xa3\x22\x3e\x58\xac\xce\x15\x64\x20\x95\x49\x02\xa1\xd8\xbb\x6e\x75\xa8\x1d\xbb\xb2\xef\x43\x39\x69\xb2\x8e\xbe\x0e\x62\xd4\x03\x41\x81\xac\x40\xda\xfd\x34\x48\x02\x2a\x14\x78\x16\xfd\xee\xd4\x7c\x60\xa2\xdd\x0d\xd3\x91\x0e\xce\x29\x45\xb7\x2f\x37\xb3\x80\x68\xf9\x55\xa2\x1a\x70\x09\x3b\x7a\x23\x65\x9c\x38\xff\x94\xfa\xf5\x58\xf5\x0f\x82\x25\x2c\x0e\xc0\x25\x28\x0a\xec\xce\x9e\x26\x58\xcd\xe9\x39\x19\x00\x6e\x18\x37\xf7\x9b\x7f\x4d\xe2\x58\x10\xda\xcb\x23\xe0\xbb\x8e\x41\xc8\x71\x84\xf7\x80\x8c\x64\xb8\x99\x77\xeb\xde\x25\xe8\xfc\x20\x67\xf3\x1c\x32\x9e\x22\xcf\xf2\x50\xd5\x72\x4c\x1a\x83\x2c\x53\x18\xe8\xfe\x6b\x3b\x81\xfa\x80\x4a\x04\xba\x0a\x60\xda\x89\x70\xf4\xab\xaa\x9e\x04\xb6\xa0\x59\x8c\xf6\xa3\x50\x9a\xcd\xdb\x10\x2c\x81\x16\xce\x77\x25\x30\x7c\xb7\xde\x4e\xe5\xd8\xad\x52\x73\x72\x0b\x68\x0d\x59\x14\xd6\x35\xba\x73\x40\xc4\x6b\xd9\x7c\x6b\xe4\x1e\xe2\x34\x8a\xd6\x15\x52\x43\xfd\x70\xc3\x22\xc8\x7a\x26\xe6\xcf\xd2\x67\x2e\x3d\x10\xc0\x0f\x03\x61\xd1\xac\xc4\xc1\x71\xfc\x6b\x16\x87\x93\x58\x95\x21\x85\xd8\x3f\x63\x2f\x40\x34\x27\x4d\xd9\x38\x02\x84\xe2\x9a\xfc\xed\xaa\xaa\xfb\x96\xcd\x6d\xfe\xdf\x93\x73\xcd\x9e\x74\x6c\x6c\xec\x75\x31\x76\x4a\xb7\xd5\x5f\xd6\x24\x26\x53\xda\xc6\x99\x41\x91\x2b\xe4\x2c\xb1\x31\x98\xc7\xc6\x96\x60\x3f\xa6\x4b\x62\x3c\xbd\x60\x55\x4f\x73\x20\x4b\x68\xaa\x3c\xa9\xe0\xa2\x2a\xdf\xa0\x46\xa9\xf5\x21\x94\xb3\x44\x58\xe7\x75\x85\x20\xeb\x03\x0a\xbb\x78\x61\xb3\x4f\x33\x71\x4b\xb2\x08\x5f\x3d\x53\x41\x83\x4f\xd9\x65\x60\x93\x59\x64\x09\x50\xc4\xdd\xed\x1a\x68\xbf\xc8\xbc\x46\xca\x2e\xd6\x66\xf8\xec\x96\x26\x84\x62\xff\x14\x31\xc7\x37\xd6\xeb\x88\x06\x46\xc9\x43\x8d\x8a\xd3\xfd\x16\x60\x13\x22\x9c\x12\x91\x93\x9a\x6b\xe6\x67\xa3\x0a\x81\x86\x57\x00\x63\x93\xda\x70\x54\x3b\xa0\xa2\x13\x14\x58\x48\x46\x6c\x62\x22\x6f\x32\x7e\xc8\x5b\x30\x13\xc9\x65\x66\x69\xec\x88\xe6\x6f\x55\x0b\x23\x86\xbc\xa5\xca\x3a\x03\x94\x2e\xe7\x82\xc6\x19\x30\x86\x7d\xda\x32\x48\xe3\x28\xb8\xa3\xde\x34\x2e\xe7\xf5\xc7\x78\x12\x27\xde\x57\x6d\x07\xa5\x31\xa3\x07\xc4\x33\x57\x0a\x73\xf5\x84\x8b\xaa\x1a\x7c\xc8\xfa\x11\x60\xfc\xc6\x79\x07\x4d\x73\x26\x0b\x62\x05\x21\x48\x98\xbe\x3c\x95\xaf\x8f\x72\x6c\x32\xc7\xac\xe0\x0c\xb7\x95\x97\xf7\x23\xd4\x0e\xe0\xbf\x90\x88\x5b\x91\xd1\x28\x68\x3b\x96\x98\x70\xf7\x78\xcb\xd9\xad\x13\xca\x55\xdf\xdb\xfc\xd7\xd8\xaf\x35\x1c\x85\x34\x90\x5c\xda\xab\x60\x4f\xba\xfc\x82\xc9\x88\xf1\xb8\x2f\xd7\xbe\xc8\x1a\x9e\x5f\xe6\xbd\x74\x2b\x63\x81\xbc\x3d\xc7\x9d\xfc\xf1\x32\x88\xa2\xe7\xe5\x1e\x95\x1b\x2f\x4f\xdd\xff\x1c\x3c\x47\x98\x55\x82\x23\x28\x13\xc1\xd5\xb5\x6c\xc1\xac\x4f\xef\x73\x5f\xd9\xc9\x2c\x52\x2a\xc5\xa2\x72\x37\xcb\x7e\xa9\xca\xbb\xe9\x9f\xea\xc9\x5b\xa5\x40\x09\xdd\xeb\xa7\x07\x27\xf0\x40\x01\xb0\x16\xa2\xc8\x8e\xa0\x86\x1e\x29\xe9\xd7\x2f\x1e\x45\x91\xc1\x85\xd8\x31\xbf\xa0\xbd\x0b\x64\x40\x1e\x45\x94\x04\x5f\xe8\x5b\xd9\x65\x14\x18\x81\xe7\x55\x40\x59\xe7\x50\x5f\x5c\x7c\x1b\xef\x65\xe3\x9b\xc4\xa3\x48\x83\x67\x82\x14\x48\x40\x92\x79\xf9\xf0\xa1\x74\x61\x78\x00\x3c\x8a\xe3\x08\x85\xdb\x6b\x24\xc6\x8f\xf2\xb8\x70\x5d\xb1\x74\x5e\xa3\xae\xad\xbd\x0e\x0b\x1e\x8f\x08\x4f\xa8\x97\x7a\xbb\x90\xc7\xbc\xad\x96\x9d\x43\x79\x94\x28\x6e\x7c\x9e\xf8\xf8\xf0\x70\xeb\x2a\xc9\x13\xb8\x34\x8f\x12\xa0\x11\x73\xdd\x83\x3d\xa4\xae\xf1\xe2\x0f\xa5\x91\xc4\x45\x63\x65\x4c\x97\xcb\xce\xe2\x21\x1e\xa5\x34\x61\x81\xfc\x2d\xcb\x2e\xf0\x5f\x26\x10\xa5\xc3\xab\xce\xa3\x54\x08\x1b\x92\x37\xef\xdf\x50\xdd\xf4\xcf\x74\xe9\x5d\xe5\x51\xaa\x1d\x8e\xf3\x6e\xf5\xaf\x9b\xbb\x6f\x77\xc1\x27\xf9\xdb\xf6\xe6\xe1\x7e\x77\x7b\x73\x77\xb3\xdd\x5c\x86\xce\xd8\xb7\xe7\xcb\x70\xfd\x94\x46\x68\xb5\x0f\xa7\xba\x1a\xd0\x85\x3c\xa2\xd2\x35\x38\x7b\x80\x3b\x02\xe6\x7e\x9b\x7e\x27\xb5\x04\xcb\x78\x5e\x96\x61\x41\x33\x78\xf6\x1a\x50\xab\x4d\xda\x07\x6f\x4b\xfa\xc2\x3c\x62\x9c\x66\x4e\x68\x7c\x9f\x2f\x93\x4a\x27\xcf\x86\x49\x45\x7d\x3c\xb8\x49\x9f\xaa\x9f\xbe\x96\x36\x3f\xa9\x72\x9e\x45\x8f\xd7\xfd\x2f\xe7\x00\xb8\xaa\xd9\xaa\x3e\x48\x57\x5b\x98\xfe\x3a\xa1\xa8\x7b\x67\xb1\x01\x33\xda\xf7\x78\x94\xc5\x0e\x4d\x51\x95\xa1\x48\xe9\x54\x8d\x1d\x76\xe2\xd3\xf0\x8f\x47\x19\xc9\x1c\x81\x2d\xa0\xc3\x6e\xfc\x62\xfd\xc1\x4d\xcb\x94\xab\x5c\xcb\x37\x99\x17\xdd\xea\xf8\xe8\xea\x22\xbd\x1e\x28\x8f\x54\x92\x21\xbe\xef\xf6\xe1\xe2\xeb\xb7\xc7\x1d\xbb\xc3\xa6\xe4\xf6\xe6\x6e\xf3\xbc\x5d\xdd\x3d\xf6\xc3\x84\xc2\x45\xe4\x45\x36\x57\xf9\x1b\xfc\x0e\xb2\x9e\x02\xf2\x79\xa4\xa4\x15\x69\xff\xea\x5d\xe7\x6f\x10\xd0\xc8\x3c\x52\x4a\x20\xf0\xf0\xe2\xe9\xe1\xc7\xe5\xee\xc7\x66\xf3\x35\xf6\x6f\x54\x3f\xc2\x6a\x24\xdd\x75\x91\x19\xae\x0c\xfd\x3c\xd1\x29\x61\xc1\x4e\xa8\x44\x12\x7c\x7f\x33\x8d\x92\xa8\xc4\xb0\x7d\xd8\xae\x6e\x77\xe8\xf1\xbd\xea\x2f\x19\x68\x8a\x02\x83\x79\xd9\xc5\x5e\x67\x49\xd4\xe4\xc6\xda\x08\xb0\x00\x67\x06\xdc\xca\x59\x69\x9a\x47\x56\x64\xc1\xbc\xf5\x7a\xfb\x30\xc9\x2e\x78\x1c\x91\x0c\x1b\xf0\xad\xe7\x8f\x17\xbd\x42\xdc\xd8\x81\x85\xc7\x71\x44\xb5\x0e\x0a\x33\xa7\xa2\xfd\xcc\x22\x91\xc7\x71\xec\x1c\x87\x82\x72\xdb\x0e\x31\xb6\xd3\x2a\xcb\xbf\xe3\x69\x35\x9e\xc7\x71\xa2\x70\x2f\x3f\x38\x67\x9c\xdb\xbc\xc1\x15\x79\x36\x28\x75\x4b\xbe\x8f\xab\xfa\x40\x7e\x34\x02\x52\x19\xa2\xe5\xee\x3e\xf4\x92\x93\x3c\x26\xd4\xb9\xe0\x75\xb1\x79\xd8\xb4\x9c\x75\xf2\xf4\xfa\x09\xb7\x58\xad\xfb\x03\x26\x0a\x14\x3c\x26\x3a\xd6\x4e\x31\x11\x60\x24\x9a\xc6\xe3\x84\xb9\x77\x1c\x77\xce\x27\x7c\xc7\xbf\x35\xe6\x02\x71\xd7\x61\x88\x10\xce\xdf\x1f\xda\x6b\x28\x61\xda\x25\x3f\x0d\x36\x0d\x3c\x4e\x4c\x86\xc2\xeb\xd8\x64\xdf\xc5\x51\xb4\x23\x34\x0a\xa7\x49\x55\x84\x3d\xe5\xca\xda\x05\xcc\xe0\xec\x96\x52\xe3\xc2\xe0\x6d\x0e\xf5\x8f\xbc\x30\x5a\xb6\x41\xe4\x77\xf9\xc9\xb1\x18\x9c\x6f\x73\x75\x38\xc8\xd2\x5c\x43\x3b\x5e\xfd\x63\x46\x9c\xf7\x65\x0d\x6d\x2d\xf3\xf6\xb9\x95\xa5\x91\xb5\xd9\x91\x30\x80\xa7\x54\xca\x01\xe4\x83\x8e\xf4\x70\xc6\xd5\xef\x07\x6b\x6f\x4a\xd8\xed\x76\xc1\x10\x29\x1c\x14\x0c\x45\xa4\x9f\x56\x5b\x94\xd0\xd8\xc5\x69\x7f\x08\x6c\x28\x3c\x7f\xaf\x3c\x81\x48\x1e\xfe\xcf\xad\xc7\xd9\xbd\x12\xc4\x04\xfb\x26\x59\xb8\x4a\xc6\xcd\xc5\xc3\x18\x68\xcb\xe3\x2c\x06\x94\xed\xcc\x9b\x1f\x2f\x88\x61\x7a\xef\xcb\x98\x3c\xce\xa8\x21\x49\x2f\x6f\xdc\xca\xa2\x70\x2c\xbe\x71\x7c\xce\xe3\x8c\x09\x87\xa4\x29\xaa\x9f\x21\x7c\x88\xc3\x31\x1e\xd3\xee\x86\xfc\x74\x8a\xf8\x6f\xb2\x95\xfd\xfd\xc8\x40\x48\x3f\x03\x67\x45\x9f\x61\x23\x8d\x55\x0a\x89\x0e\x56\x7d\x75\x17\x64\xcd\xe8\x3c\x7e\x9c\xe6\x52\xaa\xf0\x5b\x77\xdd\xdb\xfc\x27\xec\x5a\x08\xd6\x33\x3c\xd6\xd2\x15\xd7\x8c\x6c\xe5\x2c\x17\xe3\xb1\xd6\x19\xee\x6a\x08\xfb\xea\x7e\xa3\xaf\x52\x85\xc3\x60\x52\x07\xb7\x92\x75\xbb\xae\x26\x58\x61\x1e\x6b\xcb\x30\xc4\x39\x9e\x8a\xc2\x95\x63\x11\x0c\xe5\x97\x13\xdb\x42\xed\x8c\xe1\xfd\xa2\x1f\x3e\x66\x12\xc0\x2b\x96\xc6\x6c\x7e\xb5\xb5\xbc\x94\xef\xcd\xec\xb2\x8c\x4c\x71\x31\xbe\x76\x39\xfe\x78\x03\x8b\x21\x8a\x91\xca\x75\x3c\x35\x2f\xf7\x95\x01\xf4\x84\x98\x91\x72\xc3\x50\xea\x6c\xc3\x46\xf6\x45\x4d\x10\x6b\xc1\xe4\x3b\x9c\xd3\x02\xc3\x1a\xc1\x2e\x24\xd7\x5f\x64\x6d\xe6\x05\x77\x4e\x22\x9a\x00\x1b\x5a\x0d\xdb\x97\xbc\xc1\x39\x15\x60\xd5\x9c\x44\x4a\x61\x1c\x5a\xe4\xb2\x1c\x39\xcb\x73\x12\x47\x96\xf5\x99\xe2\x9d\xcc\xcb\x21\xa6\xe6\x24\x4e\x39\x2e\x04\xda\xdf\xbb\x9b\xe6\x02\x6b\xb8\x53\xfb\x46\x4e\x62\xa3\x44\xe6\xb5\xc7\xf3\x1a\xbe\xbe\xeb\x41\xee\xc1\x0f\x21\x82\x21\xad\x2b\x6f\xb6\x2f\x50\xc3\xaa\x7c\x28\xaf\x2b\x54\x78\xf1\x7d\x8f\x30\xce\xa4\xd8\x84\x80\xd2\x56\xb5\x0e\xf1\x8c\xd3\xc8\xf4\x43\x12\x12\xa1\x3e\xc6\x3d\xfc\x44\x57\x93\x2e\x8b\xc0\xac\xd2\x57\xd8\x3e\xa8\xad\x7f\x08\xbe\xe6\x24\x8d\x08\x4e\x8a\xd5\xe6\xfe\xe6\xfa\x6e\xf5\x47\xf8\xa6\x14\x38\x8a\x36\x3e\xca\x32\xb8\x24\x73\x42\x23\x19\xb8\x98\xcf\xaf\xa7\xa2\x98\x3d\x0b\x1a\x67\x98\x64\x3a\x26\xcf\xcc\x09\x6f\x34\x91\x08\x4d\x9c\x74\x6e\xe9\x9b\x7a\xb7\x20\x6d\xff\xbc\xa8\x10\x2a\xa0\xab\xce\x76\xe8\xc9\x6c\x27\xd4\x30\xec\x0f\x3a\x92\xc5\x34\xba\xfb\xa8\xaf\x30\x94\x84\x38\x61\x44\x40\x88\xd6\xbb\xf7\xf9\xb9\x85\x23\x99\xfd\x28\xa6\xa4\x13\x0c\x2d\x83\xcc\x45\xdd\xe6\x33\x5f\x62\x4e\x38\x95\xca\xaf\xcc\x77\x53\x5d\xad\xcf\xd7\x45\xc2\x95\x13\x91\xee\xc3\x37\x57\xdf\x3d\x87\x63\x71\x22\xa2\x84\xb8\x66\x42\x51\xdc\x4d\x3d\x64\x39\x11\xb1\xc5\x19\xec\xeb\xe9\xde\x7c\xce\xcc\x4f\x91\x58\xcc\xd9\x90\x47\x87\x81\x78\x68\xef\xce\x8a\x80\x61\x3c\x77\xdc\x0a\xa7\x71\x1c\xcc\xf8\xc3\xed\x13\x82\x6b\xd2\xe3\x37\x83\x8e\x43\x17\x15\x34\xad\x3c\xcc\x67\x6a\xc6\xa3\x2c\x19\x15\x12\x47\x32\xfd\x61\x84\xb5\x36\xe0\x71\xab\x43\x50\x48\xf0\x07\x25\x17\x9e\x22\xf3\x56\xe9\x01\x36\xc2\x89\x4a\x62\xd4\x7f\xf0\xe0\x49\x44\x90\xbe\x9c\x83\x7c\x38\x51\xd2\xa1\xf8\x5d\x95\x64\x73\x40\x57\xaf\x69\xb2\x3e\x95\x26\x08\x8b\x16\x51\x5a\xa0\x70\xef\xf5\xc5\x45\x88\xd0\x51\x54\xd4\x1f\x36\x2c\x41\xce\xd0\x65\xfe\xf6\xf6\xfe\xed\xb8\x58\x9b\x9f\x93\xd7\x3f\x2b\x92\x71\x62\x94\xf1\xeb\xf1\x1b\xd4\xed\xee\x20\xf5\x4b\x5e\x0e\xdf\x67\xd2\x2c\xd4\x47\x30\xa1\x82\x87\x53\xbb\x6a\xdb\x6a\x92\x80\x13\x63\x04\x72\xe7\xb0\x80\xba\x06\x5b\xd5\x30\xf6\xf7\xf5\xa3\x2c\xa1\x58\x3b\xea\x02\xd8\xee\x4d\x98\x36\xa7\x66\xd7\x65\x69\x4a\x9d\xc4\xfc\xb7\x9b\xfb\x6d\x4c\xa2\xd9\x33\x46\x6d\xfc\x11\x1d\x6f\xfd\xfe\x04\xcd\x7f\x4f\xe1\xca\x93\x38\x03\xa7\x58\x32\x71\x02\x0f\xf8\x80\x05\x80\xc8\xec\x9f\xc9\xd5\x24\xb1\x14\xb8\x60\x1a\x5f\xea\x08\x35\xf8\xff\xef\xac\x92\x26\x6b\x67\x12\x6b\x8d\xb2\x99\x8f\x05\x98\x7d\x70\xf4\xef\xb7\x89\xc9\x9d\x49\x48\x0a\x58\x5a\xe8\x36\x75\x94\x2d\x27\xbf\xfd\x35\x9f\x93\x27\xc4\x44\xa8\x6b\x97\xef\xcb\xaa\x86\xaf\xbf\x5f\x74\x29\x48\x70\x12\xe0\x49\x12\x29\x11\x16\x64\xbc\xb2\xb8\x3f\xc2\x52\xc4\x19\x9e\x4a\xe5\xa1\x93\xa3\xf6\x25\x4f\x12\x01\x18\x81\xfc\xaf\xd4\xaf\x8f\x55\xbb\x86\xa6\x1d\x9c\xda\x78\x92\x98\x18\xb5\x38\x90\x05\x77\x27\xcb\x93\xb3\xe1\x1a\x7d\xde\xa4\x8e\xa4\xea\x9d\xb0\xce\x9b\x37\x3c\x49\x6c\xc2\xa2\xff\x9b\xaa\xd4\x07\x6c\x88\x0f\xff\x9d\xde\xe3\xd4\x5a\xcc\x01\x7a\xe9\x2f\xb3\xd9\x7e\x99\x5d\x14\xa5\x11\x66\xa4\x01\xb9\x31\xa0\x37\x97\xcf\xc9\x12\x11\xcb\x51\x1c\x30\x62\x4e\xf0\x84\x65\x1a\x67\xd8\xfa\xe1\xdb\xfd\xf6\xf7\x45\x1b\x9c\x6e\x10\xa0\x01\x9f\x8b\xc3\xf1\x41\x48\x6f\xfd\x3e\xfb\x2a\x6b\x62\xd6\xf3\x30\xa6\x61\xa8\x1f\x92\x25\x0a\xf9\x6c\x8e\xac\x87\x60\x9d\x2f\xb2\x18\x4c\xc2\xd2\x33\x23\x67\x9e\x64\xda\x51\xc5\xf7\xd0\xfe\xb3\x52\x4f\x12\x37\xa7\xe5\x1f\x9b\xd9\x0c\x1f\x3b\x26\x94\xd7\xf2\x00\xbe\x5f\x30\x36\xb9\xe7\x89\x24\x02\x7b\x54\xae\x80\xfb\xa3\xaa\x5f\x67\x57\x29\x29\xc3\x46\xc7\xf7\xfc\xf5\x75\x5c\x9c\xe5\x89\x54\x44\xc3\xe0\xdc\x76\x05\x70\xa6\x1d\xc2\x13\x95\x44\xc1\x12\xea\x2b\xbc\xf7\xa2\x26\x43\xaf\x76\x96\xa9\x27\xca\x80\x13\x5f\x7c\x6f\x5a\x38\x2c\xda\x53\x84\xec\x2f\xd1\x94\xe1\x8e\x56\x59\xf4\x92\x29\x46\x74\x7e\x9e\x68\x15\xe1\xb2\x5b\x63\x17\x19\xcc\x57\x59\x1f\xba\x00\x7d\x32\xeb\xb5\x51\xd8\x48\xbe\xcd\xdb\x60\x2a\xc5\x13\xa3\xc4\xe0\xed\x77\xbf\xb3\xa5\xee\x8f\xe8\x04\x2d\x6f\x1c\x3d\xf1\xa1\x2c\xf2\x12\xae\x7f\x0c\x47\x79\xec\xcb\x07\x17\xef\xba\x18\x49\x15\xf2\x04\x14\x30\xf7\xea\x39\xcc\xe6\x47\xcd\x46\x9e\x58\x16\x63\x6f\x2f\x2c\xa8\x55\x3d\x7f\x71\x6c\x26\x99\x1c\x21\xc3\x2f\x6f\xa6\x56\x19\x3c\x8d\x78\x86\xdb\x73\x5e\xfe\xcf\x29\x6f\x6f\xcf\xd2\xf6\x34\x52\xdc\xa1\x04\xbb\xb4\x02\x4e\x87\xeb\xaa\x30\x8f\x75\xb8\xda\x34\x26\x12\xe7\xc2\x16\xe4\x61\x55\x1a\x5f\x38\xf3\x6e\x36\x81\xf5\xb0\xbc\xad\xa4\xb1\x54\xa9\x2f\x6b\x9e\x8e\xa1\x45\x72\x55\xc8\x7d\x7f\x72\xeb\x52\xb7\x36\xef\xcd\x41\xc2\x21\x42\x09\x16\xe0\xf7\xf9\x1b\x3c\xd6\xd5\x1e\x74\xfb\x09\xd0\x8b\xa7\x84\x67\xc4\x4e\x04\x9f\xd6\xef\x9b\x37\xa8\xdf\xab\x72\xd2\xbf\xe7\x29\xb1\x3a\x51\x73\xc2\x42\xf8\xda\x14\x32\x54\xe3\xb8\x90\x45\xe1\x90\x6e\x7f\x17\x07\x31\xbb\x1e\x1a\x1b\xac\x25\x4a\x63\xfe\xe7\x94\xeb\x57\x54\x06\x18\x97\x05\x52\x6a\x9c\x69\xd2\xff\xca\xbc\x70\xd1\xe1\x8c\xf9\xcc\x53\xc6\x28\x16\x9a\xe0\x57\x0b\xa5\xb9\x0c\x85\xfc\xe9\x37\x71\xaf\x3f\xf9\x7c\xcc\x35\x78\xc7\x83\xf0\x1d\x5c\x3a\x71\x91\x3d\xb4\x3f\x6a\x79\x3c\xf6\xde\x3e\xfd\x00\xeb\x28\x03\x35\xde\x85\x27\xf8\x5f\xd0\xfd\xbd\x10\xa0\x91\x4e\x7d\xf9\x5e\xca\x43\xae\xe3\x1d\xfd\x35\xfb\xea\x2c\xd6\xb8\x15\xe8\xa2\x6a\xfa\x00\xd9\x1f\x93\x3c\x72\xaa\xf6\x85\xd4\x70\x5f\xb5\x30\x12\x08\xfd\x00\x5b\xca\x53\x95\xda\x50\x31\x7b\xce\xf7\x65\x97\x4d\x9d\x54\x91\xeb\x19\x4b\x9b\xa7\x2a\x73\x7e\xec\x3d\xaf\xfd\x20\xeb\x77\xef\x08\x62\x7c\x57\x73\x7a\x2f\x0d\x33\x22\x1e\x04\xf2\xc2\x65\x1a\x9e\x48\xef\xca\x7e\xeb\x48\x0e\xe3\x6c\x6b\xae\x69\xb5\xf8\x8f\x3f\x93\x4d\x12\xd4\x2c\x30\xd5\x73\x7b\xb2\x36\x7c\x81\x15\x3c\xf5\x98\x8d\xbc\x34\x50\x5f\xc8\x42\x2f\x77\x19\x52\x2b\xc0\xb2\x60\x9a\xf7\xf6\xd1\x20\x48\x78\x34\x92\x03\xde\x3e\xf7\xdf\x64\x39\x8a\x13\xfd\xfe\xf0\xfb\xc3\x8f\xe9\xaf\xa7\x51\xc2\xd0\x37\xe6\xea\x54\x1a\x9f\x1b\xb8\x3b\xfb\x0c\x7f\xa1\x83\xc5\x69\xa4\x89\xe1\x21\xe0\xbc\x29\x27\xd1\x28\x8d\x39\x47\x34\x8c\x83\x42\x39\x98\xc9\x79\x0e\x40\x49\x1c\x51\x36\x08\x8c\xe4\x25\x5c\x55\xf5\xe7\x99\xdd\xe4\x67\x53\x92\x52\x7c\x7c\x72\x66\xb8\x32\x1f\xc6\x54\xd4\x7b\xe7\x78\x80\x65\xaf\x0c\x15\xc6\x08\x43\x3d\xac\xe1\xa6\xcc\x51\xff\xf8\x7c\x11\x9e\x9f\x37\x73\x19\x96\x67\x6c\xce\xee\x2e\xd1\x16\x19\x1b\x79\x83\xaa\xef\xbf\xf2\x66\x2e\x0b\xc5\x69\xa2\x62\x6f\x27\x8e\x77\xff\x61\x51\x26\x8c\xd3\x34\xd6\x19\xcc\x28\x0b\xc9\xe4\xdd\xa7\x69\xe2\x5e\x93\xd3\x71\x5f\x4b\x03\x23\x5d\xc5\x30\x40\xd8\x10\x1a\xa0\x59\x6d\xff\xcb\x53\x15\x3b\xf8\x1b\x3e\x85\x5e\x2a\xfa\xb3\x15\xee\x83\x04\xa7\x3f\x21\x41\x9c\x22\xa6\x76\xf5\x87\x81\xa0\x1f\x4d\x63\x13\xb8\x14\x08\x84\x69\x4e\x87\xc5\xb4\x20\x0c\x57\x3e\x48\x76\x81\xe6\xe0\x22\xfd\xe1\x8e\x49\x59\xc4\x70\x0e\xba\xe2\xdc\x2c\x3a\xa6\xcc\x26\x58\x9f\xb8\xad\xf6\x9b\xba\xae\xea\xbb\x66\xbf\xa4\xd8\xc3\x29\x97\x44\x07\xc4\xf3\xce\xc0\xf1\x03\x1f\x45\x4e\xb9\x71\x89\x91\xed\x42\xb6\xf5\x69\xba\x48\x51\x41\x79\xe4\x7d\xcc\xbf\x57\x27\xfd\x32\x2c\xcc\x54\x30\x15\x98\xcd\x8f\x37\xee\x29\x93\xfe\x98\x92\x28\x03\xe2\x0b\x13\x57\x55\x7d\x0d\x25\xdc\x4a\x35\x5d\x7d\x69\x96\xc5\xde\x88\x4e\x16\xb7\xd5\x7e\x9c\x27\x7d\xac\x02\xd4\x7d\x2c\x83\x68\x80\xeb\x7e\x85\xf7\x51\xe3\x83\x66\xd2\x05\xdb\xbb\xee\xae\x8f\x4d\x31\x39\xcd\x34\xb1\x71\x60\x63\x1f\x8f\x79\x09\x4d\x73\x91\xb7\xf9\x9f\x73\x05\x08\x4e\x33\x13\xeb\xc4\x37\x88\xbc\xa0\xf1\xdc\x2e\x6c\xf9\x15\x91\xc2\x60\xdd\xe4\x58\x35\x8b\x3d\x6e\x4e\xa5\x16\x78\x15\x8f\xab\xdf\x1f\xbe\x6d\x77\x97\xab\x6d\x08\xc9\xa9\x34\x99\xf3\xa6\xaa\x8e\xf0\x24\xf3\xe0\x11\xe2\x8f\xea\x24\xc1\x68\xea\xb6\xda\x3f\x9e\x66\x64\xf2\x98\x88\xe9\xb7\x68\xee\x30\xcd\x08\x7d\xd2\x55\x69\x7e\x07\x89\xce\x73\x3f\xbb\x75\x6e\x51\xbf\x9a\x53\xad\x12\xa0\x61\x3b\xf4\xd6\xb2\xe1\xdb\x8d\x8e\x60\x48\x91\xfd\x92\x74\x89\x55\x9d\x73\x19\x3a\x4e\x0d\xa4\xd8\xcd\x40\x38\xcd\x43\xe9\xd4\xb3\x27\x98\x6e\x4e\x81\x2b\xdc\xf8\x9d\x81\x65\x5e\xee\x5d\xf7\x75\x7a\x22\x90\x14\xf8\x88\x13\x33\x7b\x50\xd6\x83\x17\x74\xc8\x97\xc6\xfc\x26\x4e\x2d\x8f\x51\x64\x71\xb3\xfd\xd2\x03\xc3\xfb\xbe\x3a\xb5\x06\x92\x41\x0c\x05\x45\x18\xdd\x92\xfe\x29\x24\xd8\x7d\x98\x45\x31\xb1\xc1\xed\xb9\x6a\xe0\x9f\x79\xb9\xef\x85\x68\xfd\xc6\xfa\x6f\x1a\x30\xb3\xc4\x2b\x3b\x71\x16\x65\x06\x13\xb7\xdd\x6e\x04\x20\xe3\x2c\x52\x31\x0f\x5c\xa6\xc7\x17\xd9\xbc\x5c\xd5\xd5\x61\xed\xbc\x2c\x6f\x96\x49\x88\x9c\xc5\x24\x46\x9a\x6f\x51\x49\xe3\x54\xf5\xc3\xe9\x62\xaa\xb1\xab\x0b\x08\x34\x79\x82\xfd\xa9\x18\x33\xbf\x27\xef\x0a\x8b\xad\x03\xf1\x40\xd3\xdd\xc5\x11\x5e\x86\x33\xc2\x45\xdf\xd8\xaf\x8e\xd2\x61\xde\x17\x9b\x48\x8c\x18\x8a\x04\xe6\xdd\xaf\x50\x97\x65\x49\x24\x89\x83\xd4\x60\x59\xef\xcc\x7f\x6a\xba\x4f\xb3\x24\xc9\x10\xcc\xbe\x6b\xa0\x28\x1e\x4f\xed\xb6\x7a\x38\xfe\xf5\xfe\x3a\x3b\x49\x1a\x53\xdc\x7f\x6c\x5e\xf6\x08\x4f\xf4\x05\xf8\x40\x43\x95\xb3\x14\x0c\x22\x43\x9d\x69\xb3\x83\xf0\xfa\x22\xf1\x43\xf9\xcf\xd3\xa0\x7f\xcc\x19\x15\xc2\x69\xa4\x1c\x8f\xc5\xfb\xee\xb9\xad\x6a\xd8\xdd\x98\xdd\x15\xf4\xcf\x91\x66\x91\x5f\x38\x70\x9f\x9d\x58\x83\x7d\x1c\x37\x32\xce\x39\x5e\xc3\x76\x3b\x70\x2d\x38\xe3\x19\xc3\xa2\x80\xd3\x87\x44\xdb\xed\x05\x9b\xab\x11\x6b\x9a\x33\x91\x3a\x67\x41\xec\x4e\xb8\xc9\x1d\xf9\x43\x59\x1c\xa3\x5e\xcd\xaa\xae\xfd\xcf\xbb\x69\xae\x50\x7a\x73\x3a\xa7\x58\x26\x62\x44\x9c\x8d\x3b\xe0\xd8\x95\x0c\xd7\x95\x65\x12\x8d\x4d\x91\x1e\xdc\xd3\xbe\x39\xcb\x94\xc6\x20\xcd\x73\x42\x9f\x8f\xdd\x12\x36\x92\x4a\xe8\x46\x38\x93\xe3\xea\x08\xe5\xe6\xf9\xe1\x31\xe4\xcd\xe3\x9f\x90\x69\xe2\x22\xa5\x6e\xb5\x72\xaf\x75\x33\x10\x2c\xdd\x71\x67\xb7\xb0\xaf\x5a\xa9\x47\xf7\x4b\x45\xce\xd7\xf0\xfe\xa4\x0b\x38\x35\xdf\x31\x41\x1f\x27\xfa\x5d\x70\x15\x64\xda\x2f\x73\x0d\x3f\xf2\x72\x2a\xc4\x34\x01\xa2\x8f\x5a\x03\x4c\xc5\x94\xb1\x91\x61\x8b\x43\xdf\x37\xfd\x79\x65\xe2\x36\xdc\x9e\x78\xe3\xb5\x16\xce\x23\x24\xa6\xbd\xd9\xb1\x23\x75\x34\xad\x2c\xe6\x53\xc9\xc8\x28\x0a\xf7\xf7\xe2\xe1\xe6\x3e\x7c\x0b\xf0\x0c\x03\xa7\x56\xd6\xf8\x03\x9c\xa6\x87\x87\xf9\x85\x31\x40\xb0\x27\xbd\x69\x5f\x7e\x9c\x7e\xe5\x32\xfc\xdd\xc6\xda\x9b\x6c\x60\x42\xb3\x2a\x7b\x8c\x6a\x28\x27\x33\x4b\x9c\xad\x7e\xb7\x0a\x94\xcf\xef\x07\x15\xb0\xef\x9c\x59\xca\xf1\xce\x3e\xbf\xe4\x6d\x77\xc7\x2f\x86\xa2\x1c\xb3\x19\x77\x14\xf9\xbc\x04\xaf\x04\x32\x79\x9f\x78\x94\x32\x64\xa8\x5e\x5c\x5f\x8c\xde\x6e\x1e\x89\x04\x05\xc0\x1e\xd6\x9b\xab\xd5\xc5\xf4\x16\xf0\x98\x6b\x67\x41\xfc\x22\xf5\x6b\x35\xa1\xfe\x71\x4e\x24\x49\x64\x10\x98\xde\x9f\x7a\xb8\x62\x77\xc4\xb5\x42\x5d\x63\x20\x3f\x9c\x0e\xeb\x99\xf6\x37\xe7\x49\x04\x86\xcf\xd8\x8a\xcd\xfa\x54\xbc\x7e\x1c\x97\xf1\x24\x35\xd4\x77\x79\xd7\x70\x06\x31\xff\xc7\xec\x0b\x74\x64\xbc\x08\xed\x73\x75\x2a\x66\xbf\x2c\x05\x1a\x80\xe8\x8f\x2e\x21\xf9\x01\xf9\xec\x12\x29\x77\x3c\xae\xcb\x93\x7e\xed\x27\x0f\xa7\x92\x62\xa3\xe0\x52\x1a\x39\x16\x92\xf0\x87\x19\x4d\xb0\x94\xbb\x6b\x5a\xb4\xd0\xc6\x3c\xf9\x09\xcd\x60\x67\x97\x20\x48\xe4\x00\x02\xfe\x6d\xbd\xcc\x1b\x39\x57\xa4\xe0\x5c\xe8\x08\xcb\x65\xb2\xae\xe5\xfb\x83\xbd\xaf\xca\x6d\x9d\xbf\xe5\xb2\xe8\x3d\x23\xfd\xc0\x2c\x31\xda\x19\xbc\xbf\x55\xaf\xf0\x50\x6a\x98\x0b\x37\x73\x2e\xa5\x4d\x1d\xe4\xa4\x99\x3c\x4a\x69\x29\xc6\x00\xcd\x49\x75\xcf\x21\x34\xe7\xfc\x51\x95\x49\x0c\x88\xf2\x06\xf5\x83\xe6\x27\xd5\x24\x16\x69\xe8\xbd\x7b\xf3\xd4\xf1\xd2\xce\x75\xc2\xa8\x0f\x15\x8f\x0e\xcc\x77\x74\x3c\xd6\x70\x3c\xb5\x98\xd3\x34\x27\x75\xc8\x43\xa3\x77\xb2\xb8\xce\x2b\xdf\x5c\x83\x51\xce\xe6\x5a\xbf\x9e\x8e\x31\x99\xa5\x52\xdc\xa4\x02\xc9\x9d\xc8\xc1\xc7\xf8\x33\x09\xdf\x66\x8c\x41\xb8\xb6\xee\x9b\x48\x3b\x2c\x88\x84\xe3\x96\xb2\xd8\x91\x90\x31\x50\x43\xb5\x22\xd7\x1f\xf1\x08\xce\x11\x0c\x92\x8b\x28\x72\x3c\x85\xbb\x4b\xda\xc5\x0a\x6e\x6b\xce\xcb\xfd\x57\x78\xff\x59\xd5\x66\x22\x7e\xc1\x45\x14\xeb\xb0\x2f\xdd\xc3\x2f\x47\x05\xbf\xac\xca\x85\x7a\x8c\x88\x52\x8e\x60\xb9\xbe\xc3\x1d\xbe\x31\x26\x69\x16\x16\x2e\x54\xde\x47\x31\xec\x71\x04\x29\xe2\x44\xe0\x8e\xff\x63\xfd\xad\xff\x14\x8f\x30\x67\x43\x0f\x41\xf7\x8c\xfc\x91\x24\x4e\x31\x54\xef\x63\xb7\x1d\xb4\x2f\xbb\x51\x18\x23\x12\xce\x31\xf8\x7b\x5a\xdd\x8d\xf1\xf8\x5c\x24\xca\x62\x14\xb5\xb9\xbe\x7e\xde\x6d\x1f\x76\x5f\x56\xdb\x8b\x2f\xbb\xf8\xf2\x69\x75\xfd\x70\xdf\x0f\x32\x8e\x44\x61\x01\x9e\xe0\x58\xbc\x6f\x5f\x6a\x90\xfd\xb9\x53\xe1\x88\x8c\x3f\xeb\xbc\x05\xa3\x3e\x49\xe4\xd0\x39\x01\x89\xbc\xf7\x57\x4f\x9b\xcd\x1f\x9b\xdd\x76\xb3\xba\xdb\xb9\xea\x7a\x38\x1d\x4f\x14\x42\xbf\x10\xe5\xbc\x45\xa4\xd0\xe8\x7a\x79\x0a\xc1\x04\xbb\xbb\xfd\xab\x00\x72\x73\x8c\xa0\x30\x88\x43\x6a\x02\xab\xa5\x2a\x9b\x5e\xcb\x2b\x1c\xd7\x99\x1d\xe5\x55\x23\x89\xfb\xe5\x80\x4a\x70\xcb\x71\x9e\x7f\xad\x4c\xa5\xfa\x72\xb2\x10\x91\x90\xb6\x67\xaf\x3c\x57\x85\xb9\xae\xfa\x4a\x87\x10\x31\x18\x08\xbd\x1b\xa9\x5f\x5d\xcf\xf2\xc2\x69\xf9\xcb\x85\x06\x81\xc8\x8c\x45\xec\x7b\x5e\x3a\xfd\xef\xbe\xac\x3a\xa9\xb4\x08\x19\x3b\xdd\x7d\xff\xb5\x98\x3e\xbc\x85\x83\x3a\x4e\x5d\xa8\x23\x4f\x3d\x66\x4e\x98\x94\x60\x8b\x02\x89\xbb\x2e\x89\x9e\x09\xe5\x73\x61\xa8\xc5\x3e\xb8\x37\x9e\xc2\x42\xf5\xf2\xdd\x30\xe0\xcc\x55\x4f\x0d\x5a\x98\x5f\xcb\x43\x17\x90\xda\x22\xef\x49\x76\x1f\xf4\x42\x97\xd7\x83\xb3\xe6\xd0\x44\x3b\xcc\x7f\x27\xc4\x11\x9a\xb5\x3f\x6f\xbe\x3c\xed\x7e\xac\x6e\x6f\x37\xdb\xdd\xea\xf2\xf2\x69\xf3\x1c\x82\x29\x01\x42\x10\x4f\x8d\x5d\x69\x47\x4d\xf6\x64\xda\xf5\xfb\x4d\x69\xe0\xd7\x07\xb4\x7b\x2e\x40\x25\x08\x96\x72\xa5\x2b\x8f\xf9\xf9\xf1\x02\xe5\x63\x77\x13\x67\x99\x92\x00\x95\x6a\x39\x78\x74\x4c\xf0\xe2\x5c\x80\xe5\xc8\x6a\x7d\x02\x59\xdc\x49\x53\xe7\x61\x9e\x64\x11\xc9\x50\x58\xc7\xb5\x55\x56\x88\x21\x43\xcd\xfd\x2e\x6e\x99\xdd\x8b\xb0\x5f\x66\x51\x12\xe1\x87\x5a\x07\xc5\x73\x02\x3e\x67\xc2\x2b\x93\x3a\x8d\xff\x64\x4c\xa8\x4c\x7b\x13\x8d\x6e\x07\x3f\x33\x86\xe1\x59\x9c\x6a\xe6\x30\xde\x55\x51\x95\xfb\x71\x6a\xe1\x47\x90\xc8\xc5\x1c\x85\x6c\xda\xc7\xee\xcb\x1f\xde\xa0\xb6\x45\x60\xa8\xf2\x8c\xa4\x02\xc1\xe9\xd5\x08\xcf\xfb\x9c\xff\x09\xfd\x71\x1a\x63\x81\xe3\x51\x96\xdd\x6e\x5b\x0f\x07\x44\x8c\x1a\x6b\x45\xb5\xcf\xa7\x36\x9a\x3c\x4b\x08\x44\x5e\x71\x37\x24\x49\x73\xa5\x88\xc9\x3b\x99\x25\x29\xa0\x30\x5a\xf3\x9a\x97\x8e\x8c\x67\xc6\x9d\x9f\x2c\x91\x40\xc9\xc4\x3a\xea\x52\x56\x08\x25\x98\x40\xd4\xb2\x34\x11\x34\xeb\x7b\x74\xe3\x32\x7d\x96\x66\x19\xa2\x17\x4a\xf8\xf9\xad\xce\xd7\xb2\x99\xee\x91\x19\x8d\x6c\x68\x72\x8c\x52\xe4\xc5\x1c\x2f\x63\x71\xac\x54\xcf\xdf\xbb\x2e\x2a\x25\x8b\x8b\xaa\x6c\xda\x5a\xe6\x68\xc6\xd0\x4b\x79\x87\x9f\xbb\x94\xa3\x65\x4c\x72\x35\x14\x39\x27\xfc\xe7\x7d\x7f\x9f\x99\x49\x31\x39\xc7\xe4\x71\xb2\x9a\x66\x0c\x9c\x06\x60\x17\x04\x7b\x29\x7c\xec\x12\x4f\x5f\x12\x9e\x30\x87\x6c\xfe\x29\x8f\x9e\x99\x5b\xd5\x5f\x07\x0a\xca\xec\xa2\x04\xc9\x10\x59\x55\xc8\x53\xa9\x5f\x06\x73\x96\x51\x54\xf8\x61\x7c\x98\x89\x34\x55\x93\xad\x2c\xbc\x51\x3d\x56\x3f\x13\xcc\x86\x47\x89\x58\x86\xee\x01\x56\xb5\xef\xcb\x87\x41\x92\x59\x2e\x07\x0f\xf1\x1f\xb2\xae\xf3\x51\xd7\x6c\x7c\x0d\xe1\x13\x22\xb1\xbe\x2a\xd4\x77\x18\xa7\xf7\x41\x2a\x8d\x71\xb6\xec\x5e\x98\xa7\x53\xd9\xcd\x49\x87\x35\xf9\xab\xbe\xb7\x3f\x81\x8a\x9d\x9d\x3d\xf2\x5e\x0e\x0a\xea\x0b\x59\xa2\x7f\xf7\xf4\x06\x2a\x2b\x71\x21\x1b\x30\xfc\xfe\x80\xb6\x16\xb9\x23\x4e\xb8\xec\x74\x26\xde\xb7\x88\x62\xc8\x4c\xca\x50\xaa\xef\x72\xf5\xb0\xad\x4f\xe7\xb8\xf1\x7f\x2c\xcb\x7b\xfb\x6a\x98\x3f\x09\xa4\x0a\xe3\x04\x38\x1c\xdb\xf7\xd9\x64\x05\x91\x4a\xaf\x4d\x71\xf1\x02\xff\x3d\xc1\x38\x38\xc9\x6c\x12\xa1\x50\xb0\x3a\xd5\x65\xb7\x57\xcd\x6e\xaa\x4d\x0d\xae\x97\x3b\x04\x5d\x1e\x8e\x32\xdf\xcf\x17\x03\x9b\xe9\x6c\x6c\xa2\x17\x56\x54\x19\xc5\x31\x4b\xbd\xac\xc8\xb6\x97\x3d\x05\xe8\x17\x1f\x19\xa5\x0a\xe3\xde\xaf\xdf\x7e\x9f\x08\x80\x73\x19\x71\x07\xa4\x6c\xa0\xfd\x71\xe6\xc6\x27\xfa\x41\x32\x10\x95\x90\xcf\xe3\xc3\x6a\xbf\x9f\x4c\x7f\x89\x8c\x32\xc1\x9d\x88\x28\x12\x55\xaf\x1f\xff\x75\x9e\x07\xf9\xa1\x31\xb3\xb1\xef\x09\x3e\xeb\x3a\x3f\xb6\x9b\x5f\xa0\x4f\x73\x45\x41\x2e\x89\xcc\xd0\xfb\x65\x17\x68\x1a\xdb\xd5\xd3\xf5\x66\xfb\x5b\x7f\xd8\xaa\x64\xc0\x46\xae\xa1\x4f\x25\x64\xc2\x05\x9a\x02\x75\x41\xc7\xf3\x49\x35\xf8\x2d\x67\x21\xaa\x4c\xb2\x28\xf1\x0e\x72\x3e\x85\xfd\xc7\xd2\x3f\x61\xb4\x02\x4e\xe7\x6a\xbb\x1f\xce\x28\x99\x40\x8a\xde\x5a\xb9\x76\xfd\xce\x80\x40\x96\x69\xc4\xa5\x17\x54\x59\x9f\xea\x72\x81\xb9\x37\x14\x0c\x24\xe3\x14\xb7\xdb\x4b\xd9\xca\x6e\x73\x42\x55\xde\x0f\xf0\x22\xfe\x23\x9c\x71\x48\xfa\xd5\xf5\x62\xb5\xbc\x50\xc9\x6e\xfd\xc4\xd4\x18\x23\x6a\xb7\x7e\x14\x60\x7a\x7b\x6e\xdc\xee\x66\x4f\x44\xa4\x4c\xd2\x60\x78\x51\x9e\x73\xc7\x67\x0f\x5a\x08\x8d\xd5\xe3\x7c\xac\xa6\x11\x6e\x43\x16\x3b\x9e\x50\xb7\xa9\x63\xc5\x16\x5b\xc3\xfd\x51\xce\x29\x19\x9a\x53\xb9\x2c\x36\x25\x1c\xde\x2f\xaa\x83\xca\x47\xe9\x06\x6a\x61\x86\x8f\xc8\x10\x18\xb6\xb2\x70\xfb\xda\xca\x35\x58\x8e\x83\xba\x19\x97\x99\x02\xa4\x85\xaf\xf3\xf6\x19\xba\xe4\x77\x55\xd7\xd5\xff\x4a\x33\x7c\xb5\x66\xda\x9b\xa2\xad\x4a\xb3\xad\x8e\xa7\x59\xe9\x45\xca\x38\x35\xa4\x6f\xaf\x20\x9b\xf2\xe1\xd4\xea\xea\x03\x77\x36\x2e\x25\x51\xc8\x51\xaa\x0f\x27\x5f\x2c\x21\x62\xba\xc4\x48\x95\x12\x7c\x9b\xef\xde\x9b\x16\xea\xfc\x74\xc0\xf9\xba\x74\xe3\x8c\x27\xf1\x7c\xbf\x79\xde\xae\x46\x75\x2b\x09\x51\x84\x55\xea\x3f\x40\xe5\x77\xb2\x8b\x04\xfe\x4a\xba\xed\xff\x0a\x54\xfa\xab\x1a\xea\xe2\x8f\x87\xc8\x20\x8c\xf5\x1d\x64\xed\x9a\x08\xfd\x3c\xb5\xdc\xad\x9d\x3d\x3c\x34\xe8\xe0\xdc\x43\xbe\x7f\x51\xd5\x69\x44\x52\x58\x7e\x8b\x2d\xc4\x3c\x0b\x05\xb5\x56\x16\x8e\x54\xfe\x0c\x6d\xf7\x0a\x3b\x15\xaf\xc5\xa2\xb7\x8a\x62\xa3\xb3\xe0\x46\x51\x2c\x30\x2a\x46\x43\x15\xa0\x7e\x58\x00\x61\x4f\x1a\x38\x61\x8c\x61\xd8\x55\x69\x4e\x87\x9b\x8b\x87\x80\x53\x53\x31\xd5\x58\xcd\x3e\xf6\xfe\x93\x3f\x83\xe0\x23\x57\xa4\x0b\xdb\xfa\xbe\x81\x73\xe1\x97\xc5\x75\xfe\x06\xab\x9f\x23\x84\xfa\x72\x85\x5a\x11\x16\x4b\xc7\xfd\x87\xbe\xcb\xae\x88\x05\xc4\x6a\x16\x27\xfd\xfa\x5e\x06\x51\x54\xae\x92\x48\xe0\x62\x04\x1e\xdf\x79\x79\x73\x19\x98\xd0\xd3\x35\x51\x75\xab\x5c\x77\xda\xa7\x01\xc3\xa0\x52\x0e\xae\xea\xd2\xed\x32\x93\x88\x51\xa5\xc0\xb0\xd1\x5c\x06\x81\x96\x70\x80\xa6\x1c\x9c\x63\x91\x37\xea\xbb\xcc\x6b\xd0\x6d\x35\x53\x4f\x0c\xa3\x69\x8c\x4a\x0c\x98\xd4\x3d\xca\xf7\x81\x77\xa3\x28\xe5\x91\xaf\x0b\xb6\x79\xb9\xef\xb2\xef\xe6\xa5\x17\xee\xe1\x8a\x72\x8b\xc8\x85\x6b\xac\xd5\x41\xfd\x94\xef\xbd\x00\xf0\xf2\x83\xa7\x5d\xd8\x3f\xba\x15\x5d\x5e\xb0\xd9\x7e\xd9\x56\x03\xd1\x4f\x51\x4d\x50\x7f\xf5\xe1\x62\xfb\x43\x36\x2d\x6c\xab\x4d\x09\xf5\xfe\xfd\x9f\xdf\xfb\x11\x36\x46\x73\xc0\x5f\x47\xfc\x39\x53\x66\x94\xe2\x89\xab\x65\x3a\x20\xdb\xd7\xdf\x2f\x96\xd7\x60\xc5\x69\x8c\xb9\xa4\x23\xc4\xd5\xd2\x7c\xcc\x87\xfb\xa8\xa4\xac\xb8\x8c\x30\x7d\x73\x2a\x1a\xcd\xaa\x06\x2f\x4c\x11\x2e\x46\x64\x0c\x8b\x99\x4a\x9a\x3d\x78\x55\x81\xfe\x4a\x33\x49\x51\xa0\x2d\xec\x2f\x53\x67\xc2\x30\x08\x12\x04\x27\x97\xd5\x21\x2f\x07\x2d\x13\xae\x24\xe3\x0a\xbc\xc4\x06\xd6\x20\xa6\xad\xb9\xee\x38\xea\x53\xac\x6a\xd9\xe8\x71\x8d\x5d\x29\x42\xf1\x81\x7f\x2b\x0d\xd4\x87\xbc\x1c\x79\xc1\x7e\xb0\x38\x85\x0f\x76\x3b\x22\xee\xc2\x06\x7e\x61\x5b\xbf\xaf\x6c\x2a\xc5\x5c\x43\x61\x57\xc3\x1b\xc8\x62\x9d\x9b\xbf\x52\xd8\x3b\xb3\x75\x5f\x5c\xbf\x95\xe2\x32\xf4\x8a\xdd\x02\x33\xe6\x87\x28\x1d\x59\x84\x2d\xba\x37\x21\xaf\x4d\x5d\x1d\x3f\x78\xf9\x34\xcb\x70\xd3\x5b\xe7\xed\xf5\x29\x2f\x8c\x93\xf3\xf3\x07\x4d\x9a\x21\xf0\xb9\x4b\x36\x9d\x2a\x31\xbe\xa0\x8e\x64\xe6\xc7\x00\x27\x7c\x70\x1e\x9b\x14\xde\x15\xc8\x84\xda\xb1\x22\xcb\xd0\x36\x8a\xe7\xbf\xc8\xf2\x14\x17\xa6\xdf\x7f\xff\x7b\x56\xa4\x1c\x55\x5a\x21\xc8\xb7\x81\xf9\x1d\xba\x7d\xca\xc8\xb0\x12\xe8\x28\x62\x88\xb4\xee\xd6\xf2\xc0\xc3\xc5\x05\x66\x56\xe7\xd1\x11\xa5\xc1\xe4\xf7\x1e\x7e\xa2\xca\xec\x8c\x4b\xb1\xf8\x10\x74\x9c\x29\x34\xad\x7d\xab\x5a\x28\xaa\xfd\x6f\x63\x85\xd8\xf9\x50\x05\x58\x90\xdd\x63\x6a\x89\x75\x8c\x51\xeb\x47\xc7\x60\x30\x00\x0d\x6d\x96\xad\x23\xe9\xcf\xae\x33\xe8\x79\x39\x7a\x63\xfb\xb2\x96\xe5\x6b\x37\x3d\x7c\xcd\xbc\x9f\x60\x9a\x00\x30\xd2\xab\x7a\x60\xf6\xb9\x29\x4d\xb3\x0a\xd3\x40\x27\xc2\x2d\x16\x9b\x43\xf5\xbf\xf9\x68\x16\xe8\x54\x4a\xe8\x33\x58\xbc\x69\xdf\xa1\x19\x9d\x99\x46\x06\x6d\xdf\xa0\x5b\x3a\xd7\x5d\x16\xe7\xaf\x32\x9e\xa0\x52\xc2\x68\xea\x74\x76\x1c\x24\xfa\xa4\xe0\xaf\x9f\xaa\xa6\xc6\x69\xd0\xdd\x6e\x2e\xb1\x1a\xe9\xa4\x7a\xc3\xf7\xf3\xc8\xa0\x34\x26\xfc\x3a\x76\x77\xf9\x09\x8a\x4a\x9a\xfb\xd3\xc7\x74\xb9\x10\xfd\x6a\x9e\x99\x1e\xf9\x59\x15\x43\x16\xa7\x45\x9a\x25\xde\x29\x69\xa2\xe2\xbd\x3c\x61\xb4\x60\x84\xf7\x3a\x71\xed\xb8\xf9\x7a\x1a\xe1\x5e\xb5\x90\x8a\x0f\x38\xb8\x1e\xa0\xf0\x39\xca\x42\x67\x34\xa2\x22\xd4\x59\xc6\xde\x07\xe7\x81\xb8\x56\x31\xc5\x02\x61\x17\x53\xcf\x5e\x14\x1d\x43\xec\xbb\x45\x9b\x5f\x5d\x32\x0e\x75\xf7\xae\x84\x5f\xac\x55\x9a\xf6\x9e\x12\x7b\x32\xfc\x99\xf2\x60\x77\xe8\x12\x20\x78\x86\xc2\x39\x59\x3d\xbf\x54\xa7\xc2\xdc\x57\x5e\x79\x16\xe5\x5a\xa6\x88\x45\xad\xb5\xc6\x78\xd1\xc1\xd7\xee\x06\xfe\x84\xd6\x46\xe0\x91\x5d\xde\x04\xb0\xe9\xec\x82\xc1\xc6\xb8\xe8\xbb\x2d\xe3\xfb\xcd\xe3\x2c\x9a\xd1\x60\x6d\xc0\x28\xaf\x03\x15\x36\x9c\xde\x26\x69\x40\x55\x39\xfb\xdc\x41\xf5\xf6\x09\x70\x71\xf0\xd8\x89\xe9\x29\x2d\xe7\xb8\x4d\x39\x7a\xe2\x75\x7f\x36\x1d\xa3\xa2\x80\x71\xbd\xa3\xd5\x7e\x2c\xcb\xef\xc6\x98\x38\x95\x08\xa1\xbc\x93\xbf\x5c\x05\x30\xbc\x4c\x86\x50\x82\xe2\x36\x2d\x34\x4d\xfd\xaf\xe1\xaf\x29\x16\xc0\x2f\xee\x1e\x06\xef\x78\x7f\x2c\xa1\x04\xd7\x48\x97\xef\x38\x8b\x11\x74\xe7\xd9\xe5\xde\xca\x62\x81\x1a\x69\x12\x16\x73\x86\x10\x93\xa2\x19\x4e\xc5\x19\x42\x82\x9f\x1e\x6e\x37\xbb\xdb\xcd\xf7\xcd\xed\xee\xf1\xe9\xe1\xfb\xcd\xe5\xe6\xa9\x1f\x22\x5d\x67\xe9\x20\x5f\xe1\x0f\xa8\x67\x6c\x63\x93\x6a\x89\xa0\x64\x87\x98\xb8\xaa\xab\xc3\xe7\x2f\xac\xa1\x31\xc7\xa0\x15\x53\x36\x9f\x17\x05\x3d\xf3\xf1\xb4\x36\x34\x8d\x1d\x76\xca\x19\x47\xcf\xbe\x97\xf2\x48\x77\x6f\xe4\xc3\x97\xeb\xa7\xfc\x0d\xea\x27\x68\xaa\xe0\x50\xcb\x0d\xd5\x4c\xb9\x70\xb7\xec\x16\xbe\x42\x1e\x9b\xb1\x55\x1f\x37\x8c\x13\xec\xec\xb8\xc9\x76\xa3\x2b\x24\x46\xb9\x6d\x6a\xfa\x45\x3c\x75\x0a\x5f\xa8\x59\x97\x9b\xcd\xf6\xcb\x5a\xf6\x7b\x99\xe1\xcc\xbd\x65\x7d\xf4\xbf\x69\xda\xfc\x30\xa7\xba\x85\xc1\x99\x45\x35\x7d\x75\x7a\xbf\xd1\x70\x59\xcb\xb2\xb7\xa3\xe3\x86\x1b\x82\x4f\x1c\xab\xb0\xc1\x2f\xd8\x1f\x13\x51\x22\x93\x20\x9f\x86\x18\xe7\xd1\xca\xf9\x8f\x61\xf9\x34\x22\xe6\xb8\x7c\x1e\x97\x1c\x34\xb9\x11\xdc\xf5\x31\x5d\x4f\xf8\x09\xec\xa6\x7d\x99\xab\xe3\xfa\xa1\x99\x21\x48\x65\x3b\x4f\xe1\x3e\x4f\x9c\xfc\xc7\x65\x2c\x82\x2d\xc6\x13\x2a\xf8\xe5\x1a\xe6\x86\x66\xdc\xc8\xc4\x3d\x85\x41\x3a\xf2\xaf\x40\x47\xe1\x87\xca\x4c\x63\xe6\xe0\x70\xc2\xe1\x73\x9f\xbf\x79\x2a\x4a\x94\xc7\x07\xff\x36\x3d\x20\x59\x14\x79\xc9\x20\x16\xee\xb9\x8e\x34\xf5\x75\x02\xdf\x4f\xd8\xf4\xdd\x38\xa3\x0d\xc1\x3a\x60\x73\x3a\x4e\x61\x1d\x46\x5b\x83\x6a\x03\xa5\xcf\x7e\x9b\x5b\xb0\xfd\x6b\x69\x34\x25\x71\xef\xf1\xb1\xe0\xa2\x8d\x21\x1c\x0d\xa3\x21\x95\x7e\xff\xd9\x69\x59\x1a\xd7\x81\x1c\xdf\x05\x63\x99\x36\x93\x22\x3b\x9a\x08\xb8\xda\xd6\x67\x02\xcb\xdc\x80\x8d\x02\x86\xfa\x0a\xe0\x09\x74\x7e\xcc\xa1\xf7\x9f\xf4\x83\x6c\x2a\x50\x0b\xda\xaf\x34\x30\xe7\x93\x1a\xab\x33\x7c\xfd\x91\x54\x11\xc4\x0a\xc4\xe0\xb8\x39\xdd\x51\x21\x62\x14\xb1\x13\x8f\xb7\xab\xed\xcd\xfd\xb7\xbb\xdd\xea\xee\xe1\xdb\xfd\x76\xf7\xaf\xc7\x7e\xbd\x81\xc8\x72\xd4\xac\xd8\xfe\xcc\x1b\xcf\x97\x0b\x87\xe2\x88\x64\x3e\x51\xeb\xa6\xeb\x64\x12\x4c\xae\x0b\x62\x42\x10\x35\xb0\x0b\xb2\x7a\xe1\xef\x99\xc6\xba\xc8\x66\xbd\xd9\xce\xfb\x67\x40\x28\x20\x0b\xd8\x29\x58\x0e\x3d\xc5\x79\x51\x0f\xd2\x98\x58\xe7\x68\xaf\x4f\x75\xde\xce\x85\x7c\xc2\x28\xc2\x48\x17\x52\x7d\x7d\xb8\x7f\xde\xae\xee\xb7\x0f\xfd\x4f\x4c\xd3\x0c\xaf\xee\xe6\x72\x52\xd1\x84\x94\x29\x69\x47\x31\xdd\xf7\xea\xd7\xc8\x7f\x66\xfe\x6b\x45\xf8\x14\xb0\xd4\xbf\x26\x7e\x7f\xbd\x0b\x01\x2d\x30\xe1\xc2\x69\xd7\x68\xbc\xac\x4f\xaf\xaf\xe7\xe9\x99\x1f\xcb\x23\x17\xd5\x7c\xaf\x5a\xb8\x3b\x35\xb9\x9e\x67\x31\x61\x9c\xd1\x78\xce\x9b\x8b\x07\x5c\x34\x17\x40\xe7\x9f\x96\xd4\x40\xd0\x14\x81\x59\xd2\x98\x31\xb7\x68\xf2\xa3\x44\xe6\x92\x7d\xfc\x51\xea\xfd\xae\x3a\x1c\xe4\x6c\x35\x03\x21\x33\xe1\xbc\xf4\xbd\x0b\xf4\x75\x35\x83\x77\x40\xc6\x41\x74\xcf\xc0\xcf\xe0\x70\xbd\x4b\x3a\x7a\x1c\xa4\x70\xb8\x74\x04\xac\x79\x72\x6c\x1a\xf5\x07\x05\xee\x73\x8f\xd7\xd7\xf2\x30\xe9\xc1\x80\xcc\x1c\x3f\xe4\xe6\xfe\x6b\xf8\x93\x92\x89\xf6\x09\xfd\xfa\xf4\xde\xa5\xfc\xe7\x19\x36\x28\xc3\x99\xf6\xc5\xd8\x39\x3f\xfc\x33\xbc\x25\x68\xe9\x25\x6c\x5f\x40\xbf\x92\xe5\x7a\x1d\x98\x58\x39\x1b\xb0\x41\x36\x76\xf1\x4e\x1b\x1a\xc7\xbe\x4a\xb9\x3a\x22\x56\xcb\x54\x0b\x46\x8f\x1c\x4c\x16\x29\x2f\xfc\x87\x6f\xfd\x58\x70\x8e\x83\x51\x04\xc3\x7c\x03\xba\x0a\xea\xee\x7f\x59\x6b\x9b\x5d\x31\xa4\xc8\x70\xb9\xcb\x75\x5e\x3e\xc9\x46\xfe\x53\x1e\x4e\x61\x61\x05\x30\xc6\x8a\xc1\x4a\x7f\x55\x1a\x1f\x71\x9e\x31\x14\xc0\x02\xb8\xd5\xd9\xfb\x94\x5f\x6e\xbf\x8f\x1f\x98\x8d\x18\x68\x1f\xcd\x5e\x55\xf5\x6b\x20\xe3\x4c\x0b\x7b\x36\x52\x42\x0f\xcc\xcd\xaa\x9c\x1a\xad\x76\xc7\x2d\xe2\x7a\xbb\xd7\x18\x9c\x66\xd0\x18\xcf\xee\x54\x9e\xc2\xd2\x67\x23\xeb\x64\xb0\x1b\x68\xbf\xe6\xe5\xde\x54\x07\x87\xf5\x0d\x53\xd5\xc6\x8c\x68\x31\x40\xe4\xbb\x15\x6a\x52\xa6\xb2\x31\x70\x8b\xe6\x44\xbb\xa6\xb2\xed\x85\x3c\x7e\x6b\xc2\x7e\x64\x49\xea\x30\x03\x2f\xb2\x79\x79\x94\xfd\x2b\x66\x49\x66\x8d\xe9\xeb\xe8\x01\x26\xf7\x78\xbe\xdf\xdb\x04\x28\x36\x2a\xc6\xaa\x0f\x0f\xf6\x42\x9e\x0a\x53\xfb\x4d\xdf\xbf\x31\x36\x8d\x52\xdd\xe7\x45\x9e\x1f\xfc\x02\x87\x69\x70\x6f\xd3\x48\xb9\xee\x35\xfe\x88\x27\x68\xa0\x7e\x83\xef\xfd\x43\xb2\x34\x4a\x5c\x53\x6b\xf3\x1d\x41\x24\xfd\xdf\x63\x89\x94\x75\xd9\xbe\x4c\x1e\x1a\xd5\x02\xf7\x0e\xe8\xb2\x58\x5f\x8f\xbb\xaf\xae\x60\xd6\x7b\xb3\x4c\x41\xec\xbc\xa6\x4f\x0d\x38\x7f\xd3\x59\x1c\x6f\x79\x0a\x88\xf2\x3d\x1d\xcd\x45\x75\x3a\x56\x25\x36\x02\x9c\xdd\x41\xaf\x1e\x31\x8a\x9d\x2d\xd7\x52\x65\xfd\x6d\x74\x4e\x48\xd3\xd9\x61\x39\x10\x19\x0f\xac\x92\x8b\xaa\x99\xf5\xc9\x6c\x46\x93\xd4\x97\x3d\x6e\xf3\xf2\x15\xcc\x4d\xff\xdb\x74\x14\x59\x9f\x21\x6e\x1f\xb7\x9f\x6a\x0b\x59\x6d\x1c\x26\x09\xd7\xb2\x9b\x8b\x87\xd9\xb7\x68\xa3\x50\x71\xd5\xe5\x45\x33\x01\xc6\xe9\x50\x13\xa5\x18\x8d\x6c\x5f\x20\x30\x06\x03\x6f\x2a\x8c\xd0\xa9\x57\xae\x5c\x12\x28\x1e\x80\xaa\x16\x3c\xcf\x61\x2a\xfd\xb2\xcc\x72\xb3\x60\x63\xe4\x19\x85\x6e\xe0\xe7\x12\x12\xd6\x02\xc5\xe2\xe8\xe0\x8d\x72\x8d\x2a\xc2\x17\x83\x14\xa7\x88\xa2\x88\x92\x91\xab\xee\x10\x7a\x5d\x55\xf5\x20\x1a\x22\xa2\x98\x19\x39\x56\x9c\xff\xcb\x84\x45\x44\x31\x87\x88\xce\x84\xc5\xe7\x3f\x4a\x44\xb1\x4a\x1d\xdb\x01\x01\x27\xbb\xfe\xfb\xb4\x6b\xa5\xbb\xfa\xf8\x3f\x2b\xb5\xb8\xf7\x88\x88\x30\xee\x70\xae\x70\x38\x16\x7d\xc0\x22\xa2\x24\x55\xb8\x08\xb9\x62\xd8\xf6\xe6\x4c\xcb\x39\x8c\xe3\x2e\x7f\x7f\xcb\xe1\xe7\xae\x0b\x18\xf7\xf2\x00\x83\xf4\xb6\x88\x52\x26\x62\xd1\xc7\x7b\x5e\x95\xc4\x2d\xe1\xfd\x4d\x4c\x05\x73\x26\x1d\xf2\xbd\x5b\x54\xff\xda\x22\x48\x44\xa9\x89\xe3\xa0\x5c\x87\x68\x3a\x8c\x6c\xb7\xd5\x6f\xd3\x61\x34\x01\x70\xee\x7a\x5d\xee\x53\xda\xaa\x3e\x38\x99\xd6\xe5\x5f\x43\xd3\x08\x35\xf7\xef\xab\xda\x34\x6d\x5d\x1d\x1c\x29\xf7\x09\xd3\x44\xaf\x3b\x3a\xe0\x67\x45\xc4\xe2\x24\x64\x1b\x4e\xf1\x7a\xc4\x01\x17\x11\x4b\x59\xc2\x47\xcc\x5a\x34\x50\x71\x29\xe7\x6f\xd3\xe2\xd2\xdf\xf8\x67\x72\x9d\x2c\x55\x41\x9b\xb8\xfb\xf1\x7e\xf6\x6c\xb7\x77\x9e\xac\x10\x3b\xf5\x05\x5f\xe2\x11\x11\xa3\x04\xab\x00\xbd\x5d\xdd\x14\x71\x3d\xbd\x67\x9c\x70\xcc\x4a\xf2\x16\x0e\x18\xd1\x6f\xab\xc0\x8a\x9c\xbd\x7b\x9c\x66\xa4\x7b\xf8\xbb\x3e\x0b\x1d\x89\x73\xcc\x86\x7a\xb3\xa6\xbc\xe9\xc3\x5f\xe7\x97\xfa\x5b\x3f\x20\x65\x22\x60\x33\xf6\xa1\x4f\x3e\x0d\x47\xc2\x50\xeb\xdc\xd8\x0a\xd9\x63\xd2\xf2\x3f\xc1\x8c\x7c\x67\x44\x24\x84\xa4\x69\xcf\x5f\x73\xc6\xdb\xcf\xed\xe8\x05\x17\x36\x31\x4e\x1c\xaf\x74\x22\x0d\x8b\xe1\x8c\x88\x32\x9a\x62\xcc\xe3\xca\xa1\x4f\xd0\x4b\x16\x8c\x90\xa0\x22\xca\x78\xcc\x7c\x19\xeb\xf2\x54\xee\xa1\x2a\x2f\x73\x6b\x73\x7d\x2a\xda\xf7\xd9\x9d\x90\x11\x63\xe9\xc8\x0d\xc8\xf9\x56\xfa\x8e\x6c\x18\x63\xa2\x49\x40\x3e\xd3\x41\xed\x06\x00\x2e\x65\x68\xd8\x70\x0f\x3f\xaf\xe5\x41\x15\xde\xd1\xff\xcc\x37\xe8\x6f\x85\x41\x22\x52\x09\x03\x3e\x90\xba\x2e\xe4\xc0\x07\x14\x91\x12\x69\x6a\x47\x57\xfd\x03\x50\x6e\x7b\xf9\x4c\x3a\x72\x9e\x5f\xc5\x71\xd5\xbc\x8e\xca\xfd\x22\xd2\xd4\x0e\x4c\xf1\xde\xcb\x40\x44\x9a\x0b\xbc\x29\xdd\x76\x2d\x6b\xfd\x82\x32\x51\x83\xde\xb9\x88\xb4\x54\xe8\x3b\x78\xe5\x1c\x2a\x48\xff\x77\xa3\x93\x61\xdb\x39\xd7\x9a\x10\x91\xd1\x29\xca\x40\xe5\x3d\xa5\xd4\x49\xbf\xf6\xaf\x0a\x70\x57\xe4\x78\xd8\xae\xfa\x3f\x09\x47\x83\x6d\xa0\xfd\x56\x7a\x61\xdc\x3b\x0c\x2f\xe7\xce\x6a\x22\x02\x69\xb8\x23\x65\xb6\xa7\xba\x7c\x40\xb3\x0e\x34\x8a\x98\x5d\x87\xd5\xae\x77\x96\x8f\x34\x89\x45\x1c\x11\x67\x23\xd6\x48\x0b\x17\xb2\x69\xbd\xb1\xfb\xe4\x7e\xc6\x11\x65\x18\x01\x5f\xdf\x3d\xb9\x22\x33\x3a\xd0\x0d\xea\x85\x22\x8e\xa4\x73\xdd\x5a\x9f\xde\x2f\x64\x7d\x25\xf3\x62\xc1\x51\x65\x76\x52\x9d\xb9\x9a\xcc\x8b\x9c\x90\x43\x45\x1c\x33\xe3\x5c\x85\xbb\x30\x1f\x5b\xab\xb2\xe8\x22\x87\xd9\x55\xc5\xd2\x81\x39\xfd\xd7\x4c\xfa\x86\x61\x08\xc4\xc1\xff\xe6\x12\xd4\x69\xdf\xdf\x43\x7f\x9c\x80\xc8\xf8\x04\x5b\xe7\xa0\x11\xd3\xb3\x10\xd0\x9e\x07\xff\x96\x37\x30\x11\x9c\x16\x71\x92\x44\xa9\x9b\x09\x75\xb7\x03\x3c\x94\x6b\x78\x91\x85\xed\x9e\xf5\x13\xbc\x41\x7d\xde\x19\x39\x4f\x11\x96\x25\x56\x44\x9c\x30\x47\x8b\x77\xc5\xba\x6f\x8d\xc7\xb6\x4e\x07\xa5\xcc\x75\x01\xd4\xa9\x2e\x97\x22\x27\x11\xa7\x99\xc5\x28\x4e\xc1\x3e\x2f\x87\x62\xa0\x88\x53\xeb\xcc\xa9\x6e\xab\x7d\x34\x7d\x04\x94\x67\xa8\x4c\x96\xfb\x02\xe1\x63\x12\x3e\x43\x01\xc4\x18\xd2\x84\x72\x8d\xb3\x27\xd3\x4d\x32\x94\x05\x38\x99\x3d\x38\xb3\xac\xe1\x9e\x73\x19\xa3\xbe\x0b\xc2\xf0\xb7\xd5\xba\xdb\x17\xaf\xf2\xb2\x84\xf7\xf0\x15\x1c\xb4\x09\xc0\xaa\x5e\xf6\x7c\xf6\x15\x22\xb2\x8e\x40\xdc\xcd\x46\xc4\x6f\x2f\x6f\xa9\xb1\xa0\xce\xed\x5d\xe6\xf5\x65\x5d\x1d\xa7\x00\x80\x19\xbc\x49\xc4\x99\x31\x02\x26\x2f\x84\xbb\x80\xaf\xc3\xd5\x49\xe5\xe4\x54\xa5\xe9\xed\x61\x10\x09\xb7\xb8\x99\xc5\xd2\x00\xea\x22\x4a\x95\x8f\x6b\x3a\x22\x56\x84\x21\x9b\xc8\x49\x13\xfb\xde\xeb\xae\x3f\x0a\xc2\x4b\x7b\x05\x6c\x8b\x88\x35\xa1\xc8\xf9\xee\x7d\x80\xf6\xb0\x7e\xef\x62\x3c\xd3\x8f\xb0\x2e\xff\x93\xc6\x04\x73\xe7\xc5\xe6\xb5\x88\x4d\xe2\x92\xe4\xdb\xaa\xdc\xaf\xab\x53\xb7\x94\x86\x5b\x42\xc6\x8e\x1f\xd3\xd7\x33\xfc\x61\xb8\x5f\x46\x6a\xbc\x5f\x9b\x8b\x2f\x0f\xe1\x2a\xc0\x30\x84\x9e\x15\x95\x7e\xc5\x97\xa7\x3f\x00\x12\x63\x50\xcf\xb5\x6c\xba\xed\xb0\x9b\x27\x77\xd0\xca\x2e\xc8\xfd\xed\xac\x7c\xb6\x64\x71\x2c\x62\xb0\x36\x68\xfa\xdf\xc9\x5f\x73\x76\x8f\x88\xad\x04\x5c\x8c\xa0\x34\xcf\xdb\xfe\xb2\xac\x96\x2a\x09\x88\xb8\xfc\xe8\x95\x9d\xc3\x53\x46\x21\xaa\xf7\x6e\x7d\x98\x30\xa2\xba\x8f\x39\xcb\x0f\x77\xd7\xc3\xd2\x3d\xb9\x1e\x6b\x9c\xa8\x4c\xde\x3c\x0f\x5d\x44\xf7\xa2\xa1\x34\x51\xff\x7c\x2c\x44\xa8\x31\xf3\x07\xc8\x42\x4f\x68\x69\xdd\x31\x82\xfd\xac\x1d\x1c\xf2\xd6\x53\x76\x3e\x68\x6c\x4f\x9f\x01\x89\x92\x34\x46\xf4\x5e\xfb\x52\x40\x0b\x68\xae\x34\x3a\x33\x89\xd2\xc8\xd1\x4d\x1d\x40\x63\xa9\xec\x2d\x48\x04\x04\xd3\xe0\x12\x7e\x8e\x71\x9d\x7f\x65\x89\x33\x3b\x89\x65\xe8\x76\xd2\xdd\x85\xea\x10\x66\x0c\x89\x95\x4a\x93\x7e\x19\xdb\x55\x68\x18\x30\x79\x1f\x09\x89\x52\xe1\x85\x08\x83\x4f\x99\x07\x42\x4c\xc7\x25\x32\xc3\x0a\x86\x3b\xd5\x15\xc0\xb6\xcb\xd0\xa6\x57\x91\x18\x67\xdd\xef\x1d\x46\x26\x15\x20\x3f\x84\xa6\x80\x2a\xed\x2f\xb9\x81\xe7\x93\xea\x12\xa2\x7d\x35\x23\xad\x09\x42\x79\x14\x54\x8f\xee\x31\xf9\x2e\xaa\x76\x39\x8d\x21\x2c\x75\x26\xfb\x47\x94\xb0\x54\xdd\x26\xe2\x04\xc3\x73\xa8\x9b\x9b\x30\xbd\x67\xe7\x67\x1a\xb0\x78\x81\x73\x6c\x5b\x39\x99\xac\xf9\x18\xeb\xf8\xb3\x4e\xfd\xf3\xb5\x57\x82\x3f\xc3\x56\xf9\xf1\x9c\x2a\x0c\x63\x0f\xb9\xd3\x04\x3e\x1d\x97\x25\x67\x66\xd7\xcf\xb3\x84\x38\x8f\xe6\xfc\xcf\x31\x08\x56\x10\x2e\x33\xd4\xf1\x32\x3e\xa7\xc5\x1a\x8a\x0b\x8e\xfd\x88\x4c\xba\x3c\x35\x04\x8b\xab\xd2\xfc\xe8\x16\xe4\x6f\x75\x71\xf6\xad\xe3\x79\x43\x64\x6c\x30\x7b\xf9\x5a\xe7\xcd\xb6\x37\x72\xeb\xfe\x6e\x83\x0b\xd2\x65\xfe\x76\x31\xb2\x6c\xf4\x03\x54\x0a\xf8\x23\xbb\x1d\x31\x68\x0e\x08\xa2\x74\x82\xb2\x9c\x4f\xc1\x78\xf9\xa2\x2a\x9b\x2e\x1b\x47\xf0\x52\xfe\x16\x38\x5f\x82\x18\x41\xbd\xfb\xde\x2b\x94\x77\xf9\x68\xc7\x5f\x4e\x85\x89\x31\x69\x3c\x2c\xbd\x13\xf7\xe5\xe9\x40\x20\x0c\xd3\xd9\x5c\x57\x9b\xd2\xdc\xf6\x9d\x5d\x41\x20\xe3\x51\xe6\x61\xdd\xb5\x59\x96\x92\xc3\xe8\xee\x43\x12\x92\x20\x00\x34\x28\x2e\xac\xdf\x0b\xf9\xb3\xb9\xcb\x0b\x68\xda\xaa\x84\x3b\xf9\xeb\xb1\x6a\xda\x63\x35\xd8\x6b\x09\x62\x13\x87\x37\x41\x5d\x98\x99\x68\x52\x77\x14\xf0\xed\x46\x45\xcf\xb9\x32\x55\x18\xc3\x41\x0c\x33\xf7\x29\xdf\x57\x88\x4f\x58\x0c\x33\x92\x28\xb6\x4e\xa0\xfc\xa4\x2e\xe1\xed\xa1\xff\xe9\x49\x24\x34\x96\x88\x5e\x9c\x4c\xea\x4d\x39\x92\x47\x16\x49\x24\x39\x26\xe8\xeb\xed\x97\xa7\x6d\xb0\x8b\x5d\x7e\xbb\x93\x08\x22\x6c\x84\xac\xb6\xdb\x49\x49\xc2\x1f\x8e\x85\x40\x53\x6f\xa9\x64\x69\x46\x7f\x86\x4c\x7b\x4a\xc6\x63\x21\xdb\x2e\x15\x5b\x90\xd7\x11\x09\x21\x69\xe2\x94\x32\x2b\x9b\x07\x01\xd3\x70\x12\xa2\x34\x26\x00\x9b\xed\x97\xdd\xe3\xd3\xcd\xc5\xa6\x3f\x00\x0a\xf5\xe6\x8a\xaa\xc8\xfb\xb2\x43\x92\xc4\x0a\xe9\x29\x12\x33\xdd\x47\x94\xfc\x0d\x87\x28\x43\x6d\xc0\xbc\x59\x9f\xea\x72\xd0\x8b\x14\x49\x22\xc1\x7d\xe8\xbf\x27\x79\x90\xfd\xf5\xa7\x84\x63\x84\xdf\xed\x0c\x28\xfa\x71\x51\x99\xd9\x8b\x97\xa4\x94\xa0\x8a\xd6\xdd\xea\xe9\xeb\x66\x3b\x0a\xcd\x93\x94\x11\x2d\xfb\xe5\xf0\xaa\xae\x0e\x23\x25\x58\x3f\x86\x46\x19\x02\x07\x65\xd3\x60\xfc\xef\xf2\xf3\x6d\xe5\x89\x19\x9b\xff\x9e\xf2\xf6\xfd\x6a\x48\x6f\x13\x4a\x24\xde\x0d\x3f\xdc\xcb\x8f\x96\xa6\x4b\xda\x90\x87\xf1\x57\x28\xd4\xc5\x3a\x79\x38\xb9\x92\xd8\x82\xbd\x85\x7d\x55\xc8\xfe\x45\x61\xc4\x60\xa4\x1d\xfc\x48\x1d\x4b\x66\xf9\x14\x2c\x33\x4c\x8d\xb8\xda\x73\xaf\xf4\x19\x74\x2c\x7c\xca\x26\x81\x96\x1d\xc0\xac\xeb\xee\x46\xe4\xfd\xd2\x91\x08\xe9\x5a\xd9\x35\x12\x1f\x07\x53\x88\xfe\xb8\x62\xb8\x91\xa1\x69\xe2\xd0\x02\x15\x49\x96\x5a\xd3\x93\x42\x31\x85\x5d\xf5\x87\x68\x8c\xb0\xb8\x87\x1f\xf7\xbb\x8b\x41\x64\x7f\xa1\x25\x22\xc2\x27\x84\x55\xdd\x27\xbc\xe1\x5d\xd0\x1f\xf6\x47\x65\x02\xd2\xf1\x53\xdb\xb6\x72\x3f\x64\xb4\xbc\x26\x92\x3a\x41\xb8\xa7\x5c\xbf\x04\xac\xf2\x1c\x6d\x34\x5e\x76\x12\xc9\x52\x44\x50\xdc\x34\x2b\x17\x44\x4f\x13\xd8\x44\x66\x04\x7c\x96\xe5\x38\x0c\x41\x88\x7e\xf9\xd9\x28\x49\xc2\xb3\xb9\x69\x9e\xa1\x6d\x47\xa7\x52\x32\x65\xac\x5f\x70\xbe\xe4\xc6\x40\xb9\x2c\x33\x24\x12\x6d\x62\xe9\xa5\x4a\x4e\xa6\x79\x84\x7a\x13\x84\x00\xbb\x63\x80\x29\x4f\x09\x3f\x11\x67\xd8\xff\xdd\xb2\xc4\x49\xb5\x22\x82\x5f\xbf\xf6\x89\x5c\x62\xba\x1c\x36\xe0\xb9\xca\x71\x0b\x42\x24\xc6\x3a\x0d\xdd\x3d\x52\x2e\xc2\x16\x3c\xd3\x3a\x13\x89\x35\x06\xe7\xef\xcd\x8f\xd5\xfa\x21\x04\x9e\x69\x14\x59\x4c\xd0\xd0\xa9\xa0\x2f\xf8\x8b\x34\xca\x68\x90\xca\xfa\x91\x97\xae\x8f\x7c\xcc\xcb\xfd\xcd\xe5\x82\x46\x85\x48\x63\x4a\x10\xf5\xf7\x7c\x44\xd2\x07\xa6\xbb\xcd\xfa\x7d\x71\x2d\x4e\x63\xc6\x91\x23\x72\x6a\xa0\x6e\x1e\x07\x42\xa5\x48\x63\x2e\x70\xa7\xbf\x5d\x3f\xdf\x0f\x7f\xcb\x10\xc8\x93\x1f\x6d\xb3\x6a\xbd\x69\xe0\x6d\x55\xbd\xce\xd0\xf3\x22\x8d\xb3\xc4\x9b\x60\xb5\xdb\xbc\x80\x2f\xc7\x73\x44\x5b\x98\x4d\x69\x2c\x1d\xe9\x48\x9d\xde\x6f\x5a\x38\xfc\x2d\x91\x2c\x91\xc6\xc6\x20\xe2\xb5\x7d\xc9\x6b\xe3\xaa\xaa\x2e\x05\x9b\xc0\x53\x45\x4a\x98\x0c\x0e\xf0\x18\x6f\x5f\x82\x34\x45\x5e\x8e\x71\x02\x22\x25\xca\x45\x12\xc8\x51\x48\xc3\x47\x13\xe6\x76\x73\x1f\x20\xe2\x5a\x77\x35\xf0\xdd\x16\xb7\x9e\x34\xd1\xb1\xd3\x7e\xce\x07\x7b\xd0\x31\x6a\xba\x1b\x41\xb0\xef\x7d\x77\x73\xbf\x5b\x5d\x5c\x6c\x1e\xb7\x9b\xcb\xd0\xe8\xbf\xba\xb9\xbf\xdf\xfc\xde\x8f\xb4\xd6\x75\x14\xf3\x7d\x79\x9a\x8a\x11\x8b\x34\xa5\xe0\x96\xd6\x17\x99\xcc\x0e\xd1\x34\xc1\xe8\xd7\x2d\x69\x93\xb4\xed\x2f\xee\x2a\xa3\x19\xae\x9d\x58\x52\x19\x61\x9a\xfd\x61\x1e\x39\xab\x08\x2f\xc7\x75\x27\x5b\xa8\xf3\x99\x7f\x99\x48\x79\x16\x61\x5e\x2e\xf7\x50\xb6\x37\xe5\x5b\x35\x3f\x8b\xb1\x58\x4d\x71\x6b\xd8\xc6\x17\x62\xcf\x1a\x30\x22\x15\x84\x38\x1c\x61\xfe\xa7\x3c\xa8\x90\xe0\xa6\x82\x47\x3a\xe0\x05\x07\x37\xd9\xe5\x1f\x24\xb8\xe3\x17\x39\x8e\xfd\x90\x76\xf5\xe7\x12\x1a\xbf\xa2\x97\x98\x93\xcd\xeb\xfc\x2a\xac\xc2\xca\xaa\x34\xc6\x2b\x2e\xd7\xff\xac\xd4\xe7\x91\x60\x2a\x49\x12\xf5\x6e\xab\x87\x63\x0b\x3b\x3a\x49\x06\x53\x49\x18\x2a\x0e\x1e\x64\x83\xfb\xbb\x7b\x1f\x3f\x61\x0e\x8a\x54\xa6\x5c\xa5\x3d\xa8\xb6\x99\x9d\xcf\x38\x73\xc8\xab\x2e\x4c\x7b\x86\x33\x84\xb7\x48\x25\xc4\xb8\x30\x34\xb2\x00\x17\xd7\x4c\xfa\xed\x22\x55\xd4\x60\x67\xd1\xe6\x03\x8e\xa5\xff\x72\x25\x9c\x66\x4f\x77\xad\x2b\xbf\xfd\x5f\x01\x2c\xcb\x2c\x8b\x54\x59\xc6\xfd\xb4\x7b\xec\x72\x85\x01\x51\x2e\x52\x1d\xa7\x88\x4b\xb8\x95\x1a\x9a\xbf\xdc\x56\x52\xcd\x1c\xb6\x72\x3d\x5d\x1f\xc2\x51\xc9\x55\x50\x43\x3a\xb5\x6d\x55\x8e\xeb\xb8\x29\x18\x89\x31\xd4\xa2\xa2\xea\x70\x12\x9b\x38\xb5\x36\x7c\xed\x77\xed\x0b\xec\xea\x53\x01\xb3\xfb\x67\xa5\x75\xc2\x2d\xdd\xc2\xef\xed\x03\x37\x6f\x7d\xfe\x4c\x23\x21\x43\x07\xe9\x09\xba\x25\x68\x02\x64\x14\x34\x26\x29\xce\xca\x8b\x2a\x2f\x69\x96\xc6\xfd\xdf\x99\x44\x4c\x1a\x02\xdb\xae\x6a\xa7\xac\xdb\x1f\xcc\x00\xbb\xc4\x23\xaf\x9b\xc1\xe7\x46\x50\x12\x11\x2c\x77\x1f\xe4\xaf\xdd\x76\xe0\x44\xed\x8a\x81\x19\x2c\x28\x49\x39\xde\x6f\x24\x9b\x7a\xa8\xd6\xd3\x05\x89\xc2\xf1\x24\xcd\x90\x00\x7d\x94\xef\xdb\x0a\x51\xad\x93\xbb\x43\x13\xea\x5c\xff\xdc\x66\xeb\xc5\x52\xc6\x71\xf5\x55\x55\x3b\x88\xea\x79\xe3\x5c\xd0\x84\x25\xcc\x11\x81\xdf\x40\x16\x23\x78\xde\x88\x28\x3f\x0c\x05\x07\x8e\x2f\xcd\x7c\xd3\xa4\x09\x37\xd2\x86\x67\x74\x87\xfe\xc0\xab\xb6\x85\xc3\xb9\xa1\x7b\xf8\x80\xd0\x89\x03\xab\x7b\x68\x98\xeb\xab\x9d\x77\x5c\x05\x4d\x99\xeb\xb5\x23\x36\x18\xf6\xb9\xf6\xba\x04\xa3\x07\x91\x2a\x89\xc1\xd2\xca\x98\x27\xac\xa0\x37\x7e\x1b\x9e\x9d\x8a\x46\x8a\xc9\x71\x44\x79\x7a\x1f\xbf\x91\x94\x66\x52\x7a\x3e\xba\x86\xa6\x19\x7d\xd1\xe2\xab\x49\x99\x36\x0e\x5e\x0a\x26\xd7\xf2\xd7\x30\x5d\x29\x33\x34\xf6\x18\x9a\xc0\x2b\x1a\xb4\x77\x05\xe5\x09\xc1\xb5\xfa\xf2\xe1\xf6\x76\xf5\xb4\xbb\xdc\x5c\xdc\xdc\xad\x6e\x9f\x77\x77\xdf\x6e\xb7\x37\x8f\xb7\x37\x01\x51\x26\xa8\x88\xb3\x20\x82\xff\x5d\xb6\x37\x66\x08\x16\xc6\xf3\x90\x0a\x22\x30\x4d\x7c\x83\xd2\x54\xf5\xb8\x83\x48\x85\x34\x58\x4a\xd9\xfc\x3a\x16\x55\x0d\xc3\x5d\x13\xd2\x60\xb0\xd4\x78\x88\xf8\x84\xa8\x90\x86\x41\x56\x26\x6a\x04\xc2\x0f\x2a\x7a\x4e\xee\xc6\x0f\xca\x34\xc3\x85\xbc\x3a\x3a\xb5\xa4\xc0\xa4\xbd\xb9\xfc\xe0\xc6\xc9\x44\x21\x95\xd3\x2b\x4c\x8d\x66\x47\xa8\x04\x50\x49\x41\x07\xe6\x3f\x42\x5b\x77\x36\xee\x67\x85\x62\x89\xf1\x21\xcc\x18\x1d\xb5\xce\x67\x55\x06\xaa\x98\xb6\x3e\x7d\xfe\x03\xda\x97\x45\x3e\xbc\xa0\x9a\x65\xde\x19\x1f\x64\xdd\x57\x32\xa7\x63\x80\x70\xa7\x41\x53\x57\xa7\x63\x33\xb9\xc3\x90\x46\x18\x8b\x14\xb9\x05\x07\x8c\xd9\xf5\xb7\x06\x74\x8c\xb9\x44\x01\xb6\x65\xb3\x8b\xb3\x34\x8a\x63\x8f\xbf\x7d\xea\xde\xb3\x7b\xf8\x15\x4e\xca\x22\x11\x51\xe9\x34\x77\xbb\x65\xe7\x2e\xd8\x64\x08\x16\x29\x8b\x20\xc3\xe6\xa5\xfa\xf9\xb3\xaa\x7b\xfe\x8d\x60\x91\x71\xca\x2e\xbb\x50\xc6\xe9\x2b\xc8\x53\x81\xfb\x7f\x2c\xff\xe7\xe2\x2e\xcd\xe2\x88\x60\x40\xac\xab\xc3\xb1\xc8\xbb\xa0\x79\xd2\x3c\x61\x24\xce\x30\x9b\xba\x43\x87\xd0\x45\x37\x5e\xc1\x88\x71\xa9\x2d\x1a\x1f\xe5\xe5\x7e\xfb\x7e\x0c\xb3\x8e\x25\x31\xc4\x62\xe2\x75\xfd\x61\x40\x34\xec\xbf\xb3\x11\x61\x2b\x64\x09\x55\xd1\x20\xf0\x1a\xae\xc6\xa3\x5e\x66\xbf\x73\x7a\x89\x89\x16\x86\x3a\x10\x91\x2e\x4e\x06\x66\x10\x4b\xc1\x12\xe3\x24\xff\x26\x0d\xd5\xe7\xb3\x9c\x86\x25\x36\x41\xea\xc5\x02\x44\x76\x71\x3f\x66\xa9\xa4\xb8\xc2\xf9\x65\x27\xf8\xf1\x7b\x7b\xde\x30\xc8\x44\x08\x30\x7b\x5a\x5d\x0e\x5a\x62\x82\xd1\x28\x46\x6d\x98\x91\xec\x66\x14\xee\x05\x15\x22\x98\xe1\xd8\xbc\x3e\x7c\x87\x5a\x55\x23\xc4\xca\xc7\x98\x18\xc1\xa8\x56\x86\x0d\x9a\x24\x9e\x16\xd1\xac\xdf\xb7\xb5\x74\x5a\xb6\xf9\xe7\x86\xa7\x82\x31\xe1\xb8\x2b\xb8\xe5\x1e\x8b\xf7\x27\xf9\x73\xb9\xf0\xca\x78\x2c\x51\x6d\x19\x95\xa3\xe6\x8b\x3b\xe3\xc4\x0a\x8f\xf1\xc3\x8e\xef\x79\x2c\xca\x44\xea\x9a\x12\x25\xfc\x6a\xbf\x95\xb7\x13\xc2\x84\x60\x82\x6a\x93\x0d\xf4\x51\xaf\x79\x39\x3b\x85\x8a\x53\x61\x82\x9c\x17\x3a\xec\xbe\xfb\xc2\xc9\x5d\x65\x60\x23\xeb\xf2\x5b\xd9\xe6\xc5\xad\x6c\x5a\x27\xba\xb0\x06\x5d\x1d\xc0\x6d\xad\x61\xe5\x1c\x73\x57\x3f\x98\x4d\x2a\xcd\xa8\x8b\x13\xf5\x16\xe7\x7b\xf0\xd3\x1b\x93\x2e\x05\x53\x2a\x71\x56\x5e\x2f\xd5\xcf\x72\xf6\x7e\x29\x05\x9e\xea\x8a\x6a\x57\x83\x9e\xe0\xb9\xa8\x4d\x80\xf2\xcd\x2e\x42\x47\x80\xed\xec\x4b\xe7\x3d\x17\xbe\xd4\x24\x06\x13\xee\x6e\xf0\xb6\x5a\xbb\x53\xcd\xee\x93\xc9\x58\x16\x18\xc3\x3b\x2f\xd6\xb3\x58\x19\x67\x46\x09\x0c\x7a\x77\x5d\x96\x9e\xef\xbd\xcc\xc1\xa7\x25\x6c\x06\xd4\x59\x8f\x3c\xe6\x25\xc8\xe3\xb1\x80\x55\xad\xa5\x81\x6d\x5d\x1d\x5f\x66\x95\x7d\x06\x86\xa0\x20\x55\xd0\xc6\x94\xc5\x8f\xaa\x2e\x8c\x0b\xec\xc6\x2e\x39\x31\x41\xb3\xfb\xaa\x2a\xfa\x55\x02\x2c\x4b\x03\x7e\x62\x8e\xe2\xed\xbf\x81\x47\x31\xa5\xba\x2f\x25\x6d\x5f\x4b\x24\xaa\xf4\x5c\x2a\xc1\x23\xa2\xb5\xf3\xd2\x52\xa7\xfd\xee\x45\x36\x2f\x84\xb2\xcb\xea\xa4\x0a\x3f\xcb\xc2\x38\x6a\xb1\x34\x77\x0f\xd5\x87\x9c\xf0\x30\x34\x13\xc1\xd5\xfd\xaa\x06\x58\xf2\x8c\x15\x3c\xa6\x2e\x28\x6c\xbb\x45\xee\x09\x0e\x32\x1f\x5b\x4f\xa1\xed\x92\x83\xcf\x42\xd9\x6d\xc8\x70\x95\x17\x30\xaf\x48\x2c\x85\xf3\x9c\xb0\x04\xab\xac\x9b\x32\xdf\x1f\xe4\x76\x72\x4e\xae\xd0\x99\x6f\xe7\xed\x50\x3c\xb5\x70\x7a\x61\x44\x29\x74\x5e\xdd\xf9\xf6\x60\xe1\x3b\xc7\x4b\xd3\x9e\x13\x1d\x65\x69\x70\x59\x6c\xaa\xc2\x4c\xbf\x4f\x33\xdc\x56\x1a\x79\x38\x16\xf0\xdc\x56\xf5\x90\x19\xf2\x84\x47\x58\xfe\x42\xf8\xaa\x73\x18\x5a\xb0\x70\x11\x3c\x31\x04\x6d\xe1\xb6\x5f\x56\xf7\x5f\x9f\xb7\x9b\xe7\x6d\x38\x43\x6a\x25\x62\xdb\x7c\xef\x30\xd8\x40\x84\xc3\x34\x49\xb0\xdd\x75\x90\xbf\x9e\xa0\xa9\x8a\x37\x30\xab\x7d\x55\xde\x98\x7e\x80\xc7\x5b\x9f\xca\x80\xcc\x3a\x73\xfc\x99\x5e\x0a\x95\x8e\xf0\x09\xae\xae\xb6\xbd\x7d\x0c\xa1\x0e\x67\x91\x4b\x4e\x8a\x4a\xa2\xc7\x91\x92\x0d\x4c\xec\x1c\xe7\xb7\x99\xd1\x58\x6b\xaf\x30\x57\x83\x34\xef\x37\xfd\x85\xb3\x2c\x43\xa0\xad\x23\xbc\x8f\x13\x81\x99\x13\x9c\xe0\x3c\xd2\x98\x58\x39\x55\xff\x59\xbd\x2f\x8c\x61\x12\xcb\xd6\x2d\x34\xed\xf6\xa5\xae\x7e\x6e\x6b\x59\x5a\xe7\xfb\xb6\x39\x1c\xdb\xf7\x09\x70\x56\x70\x11\x29\x0c\x77\x1a\x69\x61\x7e\x88\x24\x08\x3a\xf8\x56\xe6\xba\xaa\xcb\xbb\xbc\x78\xed\x0f\x25\x94\x05\x9d\xeb\x35\xb4\x1e\x59\x16\x0e\x32\xc2\x49\xa8\x12\xe0\xbe\x18\x0c\xa0\xc2\x80\x2c\x8b\xc6\xae\x3f\x81\x8e\xf3\x0c\xf9\x9f\xf3\x44\x9b\x0b\x69\xa4\xee\xed\x52\x76\xc8\x97\x9b\xc6\xd2\x5c\x18\x8e\x44\x5a\x75\x7a\x7f\x3e\x82\xce\x65\xb1\x3e\xe5\x85\xf9\xc4\x74\xab\xff\xa0\xe2\xbe\x47\x71\xf1\xf4\xfb\xe3\xf6\xe1\x7e\x77\xf1\x6d\x3b\x69\x45\x73\x29\x00\x6b\x1a\x8e\x68\xd7\x6d\x55\x21\xd7\xe4\x2a\x8a\xb0\xe7\xde\xbd\xa6\xdd\xff\x75\xa9\xe4\x47\x25\xf8\xe9\x8f\x52\xb1\x8a\x5c\x1a\xd7\x83\xe8\x02\x03\x78\x7d\x7a\x47\x5f\xbe\xe7\x85\x25\x27\x2c\x87\x5c\x49\xc0\xd8\x02\xa7\x93\x85\x1a\x4a\x0d\x8f\xb2\x9b\x17\xae\xa8\xf9\x80\x71\x7d\x7e\x1e\x41\xcd\xe2\xc8\xc9\xdd\x50\x0a\x2c\xed\xf9\x5a\x4e\x4d\x68\xbc\xf1\xce\x6e\x9e\x32\x1a\x7b\xf4\x5e\x58\xff\x83\x62\xbf\x1f\xac\x13\xa0\xa6\xef\xe5\xfd\x1d\x8d\x2e\xc1\x75\xca\xd2\x11\x7e\xd1\x69\xb2\x99\xb3\xe2\xeb\x72\x34\x83\x12\x93\x38\x47\x4f\x26\x90\xa3\x5c\xb5\xba\x8f\xbe\xb9\xe6\xd6\xfb\x3f\x77\x0b\x32\xba\xa4\x21\x6e\x7c\x52\x86\xe6\x5a\x6b\x41\xfa\x9a\xe7\xeb\xb9\x36\xc8\x62\x5b\x83\x6b\xeb\xec\x36\xd1\x6a\x7e\x5b\xf5\x92\xf2\x7f\xd5\xa3\x99\xbc\xd9\x86\x24\xd2\xc1\xd8\x9c\x1e\xe5\xc4\x6c\x16\x19\x78\x89\x19\xa4\xe5\x10\x3f\x77\x3d\xef\xb0\x71\x88\x34\xe2\x46\xeb\x53\xf9\x58\x9c\xf6\xf9\x34\x39\x4e\xa3\xd9\x8d\x03\x42\xb0\x06\xd4\xe6\x50\xd3\xf1\xb7\x59\x16\x73\x11\x36\xa9\x5c\x9f\xfd\xa2\x85\xb0\x94\x5b\xab\x33\x3f\x7b\xbb\x19\xfe\x28\xdf\xd7\xef\xf7\xa7\xc3\xe4\x33\xe1\x96\x89\x88\xa9\x64\xdc\xd3\xfe\xa3\x2a\x3f\xe8\x49\x8a\x48\x3a\xfa\xd0\x40\x48\x77\xb3\xe7\xbe\x2a\x37\xed\x0b\xd2\x7f\xb7\xd5\x9d\x2c\xdf\x3f\xd4\x96\x45\x3c\x8e\x93\xc7\xad\x0e\x47\x28\x1b\x9c\x2f\x57\x32\x2f\x3e\xc1\x0a\x0b\x92\xb8\x78\xe7\xed\x78\x1c\x6f\x7e\x82\xa4\x0a\x63\x9b\xc7\xaa\xfc\x33\xef\xd1\x83\xfd\x51\xae\x63\x0f\x11\x42\xad\xb6\xc9\x9b\x22\x88\x71\xc2\x2a\x07\xf9\xeb\xe2\x45\x76\xd9\xcf\x50\xe7\x12\x49\xca\x85\xc7\x38\xe4\xba\x42\x15\x40\x94\x8b\x1a\x06\x68\x4a\xe4\xb4\x7d\x86\x90\xe3\xc7\xc1\xbf\x41\x88\xd4\xab\xb5\x77\x6b\xf8\x40\xa7\xc7\xd6\x42\x80\x3c\x5e\xca\x56\xee\xc4\x64\x61\x15\x69\x06\xf8\xb1\xb5\x6c\x5e\x7d\x05\x66\xe9\x7e\xce\xee\x51\xaa\x44\xc4\x07\x9f\x9c\x8f\xaa\xc9\x22\xd5\x06\xab\x9a\x3a\x50\xb6\xd1\xe1\x67\x00\xad\x89\xd4\x2a\x27\xf7\xf2\x02\xfa\x15\x4b\x0e\xcd\xaa\x34\x77\x18\xec\x2e\xc2\x2b\x46\x9f\xa5\x96\x04\x12\xeb\x9f\xeb\xaa\x2a\xc6\xe7\x65\x34\xc1\x20\x63\x5f\xcb\x23\xe0\x92\x9b\x17\xc6\x2d\x9c\xbf\xf5\x43\x00\x25\xa1\x74\x01\xb2\x3c\x1d\x47\x95\x49\xc1\x24\x63\x63\x80\xf7\xbd\x3c\xc0\xbf\x6e\x2e\xbb\x0d\xf6\x52\x1e\x8f\xbf\xcd\x96\x83\xf1\x45\x31\x2d\x13\x8f\x86\xfa\x02\x75\xb5\x7e\x9c\x6e\xde\x82\x27\x4e\xa5\x1b\xfb\xfd\xed\x49\xc1\x45\x91\x1f\x3f\x32\xf1\x9c\x4e\x08\xce\x52\x24\xf4\x48\x63\xd6\xd5\xa9\xd4\xf3\x7d\x54\x88\xc8\xd9\x68\xae\xf3\xb6\x85\xe2\x14\x8a\x13\x42\x08\xcb\xe2\x31\x3f\x62\xb1\x9a\x28\xb2\x88\x60\x75\x23\x2f\xbb\x48\xb1\x01\x5f\xb2\xed\xd6\x07\xdc\xae\x7a\x73\x7c\x21\x32\x26\xb1\xc4\x6f\xa0\xc8\xdf\xa0\xc6\x8a\xf5\xf4\xae\x84\x81\x5c\x7b\xa8\x3c\x46\x84\x3b\xb4\x3f\x08\x67\x91\x89\x45\x9d\xa2\x5d\x80\xaf\x5f\x55\xf5\x72\x5c\x2a\xa4\x54\xc4\xcb\xa3\x8d\xe8\x59\x7f\xab\x47\x23\xa4\x01\x94\xe3\x39\xf6\x76\x41\xd3\xdb\xa6\x98\xd3\x7e\x3e\xe4\x65\x97\xed\xe6\xe5\xfe\xba\x92\xc5\x50\x4a\x13\x86\x66\x58\x38\xc4\x29\x7f\x29\x5b\x57\x86\xf8\x21\xdf\x20\x84\x8b\x02\x64\x4c\x42\xc9\xb8\xef\x98\xf9\x63\x96\x28\x84\xdd\x22\xb6\xf7\xa9\xf7\xa4\x10\x59\x24\x1c\x7b\xd5\xc7\x3d\xd0\xbe\xec\xde\x46\x10\xa1\x2c\x12\xae\x54\x7f\x80\x62\x90\x33\x9f\x2d\x71\x59\x04\x6e\x83\xc8\x9b\x55\x0d\xa5\x9c\x8a\x75\x8a\x8c\x10\x70\xaa\x87\x32\x6f\x60\x75\x3c\x42\x20\x4c\x89\x8c\x24\x31\x32\x7b\x8e\x75\x75\xa8\x46\xd2\x98\x22\x23\x54\xe0\x4b\xda\x78\x4a\x10\x76\x80\xe2\xfe\x68\xe6\xdc\xb4\xbf\x95\xdd\x3b\xdc\xdd\x8f\x0d\x46\xab\x73\x78\x73\x46\x94\x42\x43\x42\x5f\xf7\x79\xc9\x0b\xd3\x5b\xb7\x2f\x24\xc5\xfd\x24\xca\x88\xa1\xb8\x28\x05\x4f\xc9\xdd\x2d\xe4\xb3\x3e\x46\x96\x10\x87\xdf\x47\x11\x8c\xaa\x5c\xee\xd7\x66\x49\x02\x61\xa1\x7a\xbe\x7b\x9c\xb0\x78\x86\xae\x40\x96\x80\x7b\x42\x5e\x27\xf6\x4d\x0e\x0b\x7b\x96\xd2\x58\xf0\x3e\xac\xf1\xd1\x7f\x5e\xee\x1d\xe9\x60\x71\x0b\xc9\x52\x63\x48\xf0\x56\x1e\x45\x23\x19\x8d\x13\x04\x3c\x0f\x55\xb5\x39\x6c\x36\x0c\x64\x59\x60\xc4\x7d\xad\xf2\x57\x98\x3f\x55\xe6\x7d\xf8\xeb\x1e\x1b\x3f\xbd\x00\x26\x94\x0e\x6b\x5b\x7d\x6e\x50\x2c\x32\xae\x62\xc4\x96\x3d\x3e\x6d\xf0\xb5\xfc\xb2\x7a\xba\x1c\xb0\x2d\x19\xd7\xb1\x75\xe7\x2f\x4d\x75\x18\xf9\xf0\xfd\x1d\xf6\xc1\x64\x55\xc9\xb8\xb1\x59\xe8\x06\x1e\xf3\xa6\x32\xfd\xeb\x9d\x51\x26\x06\xa9\xaf\x4b\xb0\xf2\x54\xb4\x7f\x54\x26\x97\x67\x26\x58\x67\x81\xd8\xe2\x4c\xcf\x32\xeb\x96\xa5\xaa\xfc\x36\x51\xd1\xfc\xc7\x6c\x94\xc5\xd2\xde\xe1\xdd\xc1\xa3\xc7\xb0\xbc\x4c\xd1\xcc\x78\x75\x86\x4b\x87\x4c\x6c\xee\xa7\x9b\x79\xa6\xe3\xc8\xf8\x44\xf7\x12\x0a\xd8\x2f\xa9\x7d\x7e\x50\xcf\x0b\x67\x30\x0e\x6f\x76\x3a\x36\x50\xb7\x0f\xe5\x02\x17\x2e\x08\x5a\xcd\x3e\x69\x08\xc1\xaa\x45\x09\x3f\x7d\xcd\x6c\x1e\x2a\x3b\x9a\x68\x18\x9e\xd1\x20\xd2\xee\xb8\x0b\x17\x1e\xb7\x38\xa7\x04\xfa\xf1\x10\x73\x84\x42\xef\x76\x4d\x21\x9b\x97\xdd\x6e\x36\x9d\x80\x46\x3c\xe9\x03\xe5\xf6\x1c\xdf\x17\xc6\x49\xf7\x20\x4a\xf8\xd5\x9e\xd7\x06\x33\x1b\x69\x94\x28\x09\xf3\xfb\xaa\xaa\xe7\xdf\x64\x65\x6c\x7c\x9d\xe7\x2a\xdf\xbf\xb4\x67\xaf\xb8\x55\x14\x83\x6f\xdc\xad\xd0\x85\xb5\xca\xcf\x0d\xf9\x86\x45\x45\x46\xe0\x78\x11\xeb\x3a\x37\x7b\xd8\xbe\x80\xb3\xc4\xf1\x47\x63\xe2\xd4\x61\x77\x7b\x68\xbf\xe5\xa1\x3e\x92\x86\xa3\xd4\xc6\x71\xaf\x66\x74\x27\x7f\x4d\xd2\x61\x19\x73\xe5\x1a\xf8\xf3\x42\xa9\x8c\x41\xa0\xe8\x59\x97\x45\x93\x2b\xd4\x24\xf1\x47\x08\xa3\x88\xc7\x38\x95\x3f\x5f\xf2\x16\x10\xfe\xe0\x2e\x1e\xce\xd6\x03\x49\xb2\x0c\x73\xab\xbb\xf7\x65\x5f\xb4\x45\x92\xb7\xff\x6c\x9a\x05\x49\xd4\xc6\xa1\xdc\xbe\x95\x83\x5b\xea\xd4\x06\x4b\xc8\x14\x04\xd3\x63\x85\xba\x27\xf9\x33\x1c\xa3\x84\x62\x65\x2d\x3c\xb5\x8f\xe1\x9a\x92\x52\x2d\x54\x90\xf3\x6c\xda\xa7\x2e\xfa\x9b\x0d\x61\x9a\xa7\x59\x78\xc0\x75\xe3\xd8\x5c\xba\x32\x50\xdf\x8c\xe4\xd4\xba\x71\x1a\xed\x21\xba\xbd\x26\xd4\x5e\x3c\x40\x04\x55\xfc\x67\xa7\xe5\x29\x25\x14\x65\x28\x7d\x5f\xd8\xdf\xa1\xc9\x3f\x61\x6c\x16\x45\x5e\x37\xe0\x47\x78\x06\x1f\xe1\xfb\xc7\x6f\x12\xd7\x12\x6b\x90\x55\x19\x6e\x5f\xe8\xc0\x7d\x94\xb0\x8e\x63\x22\x29\x32\x67\x8a\x23\x8d\xd9\xb5\xd5\x4e\x9d\xde\x77\xce\x29\x34\xfc\x64\xa1\x92\xd4\xe3\xbe\xba\x55\xec\x66\x2e\xc2\xe3\x8a\x17\xd1\x4c\xf5\x4e\x48\xa1\x33\x3a\x44\xdb\x97\xf0\x36\x9d\x53\x52\x18\x86\x4a\xf9\x07\x59\x4a\xcf\x1f\xf1\x47\x32\x9a\xe2\x6b\x3a\x60\x19\xef\x06\xdb\xfd\xfe\x2d\x94\x71\x84\xec\x5d\x0c\xd6\xff\x59\xe5\x41\xd7\xed\x7f\xc6\x76\xe2\x61\xac\x50\x81\x41\xe9\x14\x5f\xbc\x22\xcf\x6c\x94\x24\x88\xc9\x71\xc0\x9f\xe6\xe6\xf2\xeb\x6c\x80\xd2\x29\x26\x70\x5d\x46\x83\x3e\x15\xc6\x77\x00\xc2\x95\x6b\xce\x10\x85\xa9\x3d\xe1\xf8\x2f\xe5\xbd\x84\x34\x94\xa0\x99\xc7\x65\x75\xfa\x7d\xe2\x7e\x22\xa4\x51\xd6\x49\x04\xb9\x8b\x78\xb0\x78\xf4\x5b\x03\x66\xd5\x38\xcc\x54\x18\x09\x0a\xa2\x68\xac\xd3\xd3\x25\x17\xeb\xd3\x19\x47\x2f\x0c\xd7\x10\xca\x50\xeb\xd3\xbb\x6b\xdc\x2c\xb7\xe5\x24\x18\x82\x1a\x29\xf9\xaf\x3c\x44\xf0\xd2\x26\xce\xfa\x68\x77\x90\xf9\x54\xf5\x41\x48\xdb\xe5\x3a\xff\xef\xff\xf7\xff\xbe\x3f\x5d\xed\x36\xd7\xd7\xbb\x8b\x87\xbe\xa2\x2a\xad\x10\x89\x0b\x44\x0e\xbb\xb6\x96\x8b\xd5\x89\xe9\x85\x5a\x01\x26\xed\xdf\x84\xa0\x37\x3d\xdd\x01\xa5\x35\x30\x88\x8c\x7b\x6d\xf5\x6b\xd9\x97\x11\xa4\x85\x94\x8c\xfc\xd9\x5d\x95\x76\x3d\x75\x8c\xc6\xef\x0d\x44\x56\x15\xc7\x80\x8e\x1b\x97\x7f\x54\x25\xe0\x4a\xfe\x97\xcf\x51\x11\x70\xbd\xbf\x2e\xe5\x2e\xaa\x76\x55\x1a\xe4\x27\xbb\x56\xf9\xbf\xff\xf3\xd9\xa2\xa8\x12\x42\x82\x67\x47\x9f\x6d\x4f\x1e\x83\x4a\x24\x4d\x1c\x9d\xaa\xfa\x5f\xd0\xed\x1d\xce\x99\x99\x6e\x9f\x50\x69\xaa\x11\xc5\x2f\x9b\x6e\x27\xdf\xfc\xf7\x83\x95\x39\x8c\xa6\x11\x06\xfc\x79\x89\xba\xb8\xe1\xaf\x4a\x30\x1f\x87\x1f\xab\x06\xe6\x5c\x67\x45\x63\xe9\xd5\x25\x6a\xd7\x3a\xf8\x5e\xb5\x0b\x85\xcf\x30\x9a\xb2\xd4\xa3\x03\x1d\x69\x58\x57\xcb\x51\xaa\xa2\x19\xc7\x17\xe7\x0d\x4a\x73\x9a\xb2\x76\x15\xa7\x69\x96\x0c\x9c\xd1\xd5\xc9\xe4\xee\xff\xcd\xb4\x6b\x84\xe2\x32\xc6\x14\xdf\x9e\x4a\x5c\x70\x51\x8e\x6e\xf2\xba\x28\xde\x2d\x79\x7e\x07\x8a\x7c\x1b\xa2\xff\x22\x60\x96\xf6\x2c\xcb\x1b\xec\x0c\xfd\x36\x12\x01\x16\x8a\x5b\x8a\xa2\xa9\x9e\x25\xd8\x4c\x3a\xdd\x4a\xe8\x14\xc3\xf3\x23\xb6\x98\x7a\xd8\x92\x3f\x9a\x45\x84\xb8\x69\x77\x90\x65\x9b\xeb\xef\x4e\xbb\xa0\x3f\x4c\x09\xb2\xf1\x1e\xeb\x5c\xe7\xe5\xde\xe9\x99\xce\x9e\x70\x26\x53\xb4\x69\xcb\xcb\xbc\xfd\x2e\x47\x58\x9c\x70\x1c\xe2\xc8\x11\x49\xf2\x3f\xe1\x13\x1b\x62\xa1\xa4\x26\xa8\x21\x76\x07\x26\xef\x66\xcc\xae\xdf\x7c\xe7\xd1\xed\xf2\xe7\x55\xa4\x31\xf8\x6a\x41\x1e\xa6\xab\x91\x52\xb1\xc0\x42\xed\x21\x2f\xdb\xcb\xe7\xf5\xc5\x54\xbd\x6a\x76\x1a\xe6\x48\x1e\xab\x57\xa8\x9b\x97\x0a\x5e\xc7\x2b\xa0\x52\x99\xc5\x9c\x13\x11\xd8\xdd\xe4\x7f\x9e\x17\x1b\x95\x66\x14\x92\xa1\x1d\x86\xfb\x7f\xbd\x7a\xdb\xcf\x7c\xc6\xa7\x1f\x02\x9d\x21\x3a\xc4\x69\x21\x39\xad\xfb\xd9\x9d\xb4\x2c\x52\xe3\xda\xa0\x07\x4e\xf5\x0e\x70\x42\x59\x1b\xc7\x1e\xc8\x78\x59\x57\xc7\xdf\x96\x7a\xbb\x6e\xa8\x8e\xa8\xc0\xf6\x33\x92\x26\x2c\x8c\x42\x94\xf9\x40\x25\xa4\x3f\xe7\x45\x20\x3f\x4d\x48\xdb\x3a\x52\x8e\x8b\x17\x66\x54\xe3\x38\xa8\x16\xea\x1a\x96\xc1\x2b\x3a\x26\x0a\x97\x33\x03\xb2\x7d\xc1\xb2\x9b\x0d\x38\x19\x1d\x67\x11\x22\xd4\xee\xf3\xbb\xa0\xe3\xf3\xd7\x8b\x9d\x26\x32\x52\xc1\xf3\x7a\x9d\xd7\x33\xe5\x33\xa1\x93\x88\xf8\xca\xad\x53\xfc\x7d\xb0\xb6\x81\xb9\x6b\xb4\xd0\x89\x92\xb8\x5e\x3d\xca\xba\x9b\x46\x45\xe0\x97\x87\x8b\x4b\xac\x0d\x36\xac\x88\xa5\x47\x80\xd4\xf4\x9b\x52\x96\x38\x5c\xd9\xa2\xb0\x8b\x23\xeb\x9f\xce\x50\xcb\x3a\x05\x21\xfc\x05\x3a\xc2\xdc\xae\x19\xd1\xf6\x35\xa5\x3a\xe5\x83\x5a\x4d\xfe\x27\x7c\x47\x03\xcc\x65\xdf\x7a\xa1\x59\xe4\xda\xa9\x3e\xad\xa9\xca\x7d\x3d\x17\x24\x3a\x7f\xd6\x8c\x11\x29\x47\x42\x33\xe7\xba\xbe\x42\x33\xa9\x9c\x2c\x90\x6b\x42\xde\xb4\xa1\xcd\xe2\x8f\xf3\x6e\xfe\xe0\x17\x57\x3f\xcd\xb3\x2c\xe0\x4e\xea\xba\x92\x65\xf3\xbe\xea\x87\x40\x92\x79\x6f\xd7\x11\x0b\x45\x8b\xd4\xa9\xf4\x2a\xd9\xea\x17\x07\xe8\x9f\x89\xbc\x4e\xaa\x20\x5a\x18\x89\x59\x92\x81\x60\xf2\xb8\x93\xe6\x90\x97\x3b\x5d\x05\x2d\x06\x3f\x32\x8b\xdd\xca\xd2\x40\x69\xb6\x95\x7f\x25\xbb\xb7\x74\xc2\xba\xfe\xe0\xa6\x64\xb1\x41\x56\x88\x37\xe8\xbf\xa8\xaa\xc2\x54\x3f\xcb\xbe\xf1\x18\x64\xd9\xc7\x9f\x70\x6b\x44\x98\xa8\xbe\xfc\x33\x9b\xcf\x3a\x93\xdc\xf8\x66\xd3\x63\xfe\x0b\x7c\xed\xaa\xb7\xc6\xfe\x77\x30\xf0\xfc\x4f\x18\xaf\x95\x43\xa8\xe7\x87\x3e\x21\xd1\x19\x28\x15\x2a\x21\xf0\x3e\xf1\x7c\xf4\x23\xa4\x8e\xb9\x59\xd0\xcc\xf8\xe1\x35\x33\x92\x89\x64\x86\x56\x24\x4e\x91\x48\x62\xf2\xb6\x8f\xfa\x7f\x3b\x8f\xf2\x75\xb7\x2e\x24\xa3\xcb\x47\xc0\xdb\xe4\x02\x3e\xb8\xa1\x4a\x8b\x34\xa8\x32\xf6\x1d\xb6\x47\xa9\x5f\xe5\x3c\x09\xd2\xca\xd8\xd8\xc9\xe9\x7e\xc3\x7b\x82\xed\xdc\xf0\xd3\x35\x15\xe0\x7b\xf1\x13\x69\x27\xa1\xb5\x88\x31\xdf\xf4\x25\x80\xcd\xaf\x23\xe8\x16\xdf\xd2\xde\xb2\xc0\x6d\xc1\xa2\xff\x80\xeb\x20\x94\x55\x8b\x92\x9b\xd3\x57\x5e\x4b\x92\xd1\x21\xea\xdd\x56\x7d\x9e\x85\xbf\xf9\x83\xfd\x4c\x6b\x4b\x10\x9a\xf2\xec\x43\xfc\xf1\x5a\xf1\x79\xa1\x46\x1b\x62\x70\xb6\xa3\x58\xea\xd3\xb7\xcb\xf0\xc3\x20\x89\x52\xe1\x01\x86\x3f\x01\x5e\x77\x3f\x11\xa1\x92\xf4\xc7\x41\x70\xc7\x11\x3f\xe4\xa5\xe3\x23\x3e\x55\xc5\x9c\x55\xeb\x07\x5b\xa2\x74\xe8\x19\xb7\xb2\x1e\xe9\xbb\x68\xcb\x98\xfb\x9e\xfc\xbf\xa7\xdc\x38\xfe\x65\xf7\x64\x7f\x04\x0f\x33\x61\xa2\xd4\x79\xe4\xb8\xd4\x6c\x27\x27\x41\xb7\x89\x04\xf1\xbb\x7e\x61\xbd\xbf\xc8\x79\xb5\xc6\x44\x2a\x25\x66\x8c\x70\xc6\xea\x62\xde\x67\x7a\x26\x8e\x29\xae\xa5\x8f\x55\xf9\x3e\x18\x21\x75\x7f\x77\x72\xa3\x3e\x58\xf2\x1e\x4f\xcb\x50\xb9\xd9\x77\xc6\x44\xa6\x3d\xea\xfa\x07\xe4\x7d\x6a\x1a\x8e\x0b\x07\x90\xb6\x80\x1a\xb0\xcf\x47\xe4\xf8\x4f\xcf\x41\x62\xeb\x00\x0b\x55\x51\xa0\x63\x79\x33\x1f\x60\x25\x7a\x37\x60\x49\xbd\x79\x71\xdb\xf9\x27\x4d\x35\x93\x52\x67\xd6\xd5\xc5\xdb\x75\xdb\x9d\x31\xe8\x4b\x96\xc6\xb3\x9e\x36\xce\xfa\xea\x73\x7d\x20\x43\x09\x38\x4f\xb2\xaa\x2a\x66\x55\x51\xc3\x22\x20\xbd\x2e\x32\xc2\x9f\x9c\x4a\xde\x50\x95\xf9\x74\xe2\x1a\x96\x51\x74\x35\xc2\x05\x7a\xde\xfb\x3c\xef\x2e\x1a\x4e\x12\xc4\x2d\x6c\x91\x94\xf6\x09\x30\x7f\xf6\x3d\x9c\xc5\xd6\xf1\x06\xca\xee\xe6\xe5\xfb\xc9\x0e\x63\xb8\x36\xb8\x7d\xc0\x2f\x97\xf7\x4f\x71\x36\x86\x43\x84\x11\x6f\x28\xc3\x5c\xbc\x84\x46\x85\x11\x9a\x63\x82\xff\x7c\x3a\x1c\x64\x3d\x35\x03\x42\xc4\x55\x18\x67\x24\x2a\x2e\xc2\x7f\x4f\xb2\x57\xc9\x9d\x4c\x1e\x93\x25\x5c\x0e\xb5\xfb\x91\xbb\x48\xcc\x86\xd4\x6a\xfa\xb3\x32\xae\x13\x1f\x3b\x60\x9b\xfa\x51\xee\xc1\x61\x72\xa7\x67\xb6\x3a\x1d\x70\x02\xbd\x8e\x5b\x17\x59\x4f\x1f\xb5\xcc\x94\x35\x83\xa8\xb2\xab\x42\x37\x0f\xe5\xb9\x43\x83\x30\x4a\xa4\x4a\x87\x99\xf6\xdf\x53\x5e\x83\xc1\x02\xbd\x0b\xe9\xfa\x69\xab\x80\xcb\xb1\xe3\xf5\xdf\xd8\x1f\x8d\x8e\x0c\x16\xaa\xb6\x4f\xa3\xb6\x6a\xb7\x6e\x23\xd3\xfd\xd0\xc5\xc9\x77\xf9\x39\x84\xa2\xbf\xd9\x36\x89\xb1\xdc\x70\xc8\xcb\xa0\x97\x37\x6e\x0a\x18\x0b\xc0\xbc\x86\x2e\x8a\xcc\x78\x25\x9c\xe5\x89\x04\x51\x2c\x51\xe5\x03\x1b\x69\x43\xb0\x35\x1a\xc0\x09\xbe\xc4\xae\xa3\xfa\x41\x03\xdf\x8f\x8d\xe3\x14\x31\x4b\x45\xb5\x0f\x3d\xb8\xcf\xcb\x03\x10\xb3\x18\x8b\xa8\x37\x2d\x1c\xc6\x7a\xfa\xfe\x30\x91\x36\x82\x21\x8a\x5b\xcb\xb6\xfd\x08\x55\x07\x44\xcb\x80\x45\xbd\x28\x4e\x90\xf6\xe7\xf0\x61\x4f\x2d\x4b\x73\x09\x45\x10\xd3\x17\x40\x2c\xc1\xc6\xbc\x7b\x71\xcc\xe4\x8b\x13\xed\xd4\x06\xa5\x31\xce\x6b\x1a\x4c\xf7\xce\x4c\xdf\x28\x48\xb4\x0d\x10\x75\xcf\xab\x18\xbf\x99\x90\x58\x0b\xff\x7f\xce\xde\xa4\xbb\x71\x1c\xdb\x1a\xfd\x2f\xdf\x28\x07\x35\x20\x48\xb0\xc1\x9b\xc9\xb2\x1c\x56\xa5\xbb\xcf\x52\x44\x56\xde\xbb\xee\xd2\x3a\x00\x0e\x64\x5e\x53\xa4\x92\xa4\xc2\xe1\xfc\xf5\x6f\xf1\x00\x60\x27\x29\x22\xdf\x1b\x54\x39\x52\x04\x3b\x10\xcd\x69\xf6\xd9\x7b\xb8\x81\x73\x3f\x68\x09\xb5\x23\x6a\xd6\xd3\x3c\x35\x14\xbc\xda\x2d\xdf\x3a\x5b\xba\xdc\x5b\x5d\x77\x3c\x4b\x84\x21\x17\x01\xfa\xca\xcc\xd2\x54\x4b\x2c\x8a\x29\x10\x0b\xb9\x4c\xac\x70\x89\x0f\x27\xbd\x54\xed\xf2\x34\xf3\x35\x31\x8e\x33\x02\xb5\xb7\x1f\x79\x67\xe4\x74\x3e\xd0\x86\xb4\xd1\x5d\x38\xfa\x6c\xa9\x72\xe7\x25\x61\xea\x68\x82\xbf\x57\xef\x38\x4f\x5f\xfb\x46\xa9\x16\x16\x88\x32\x23\xf7\x9c\xf4\x51\x22\x38\xd8\x7a\xe8\xa7\xa7\x11\xe6\x19\xd3\x24\x36\xae\xb0\xe6\xe6\xf4\x39\x09\x8f\x63\xc6\x2c\x53\x13\xc5\x02\x8f\xd3\x2a\x1f\xcc\x62\x46\x8b\x76\x2f\xeb\xbc\xd0\xfa\x42\x20\x75\x30\xcc\x30\x8b\x39\x09\x4f\x6c\x6e\x5f\x7f\x56\x07\x85\x19\x5a\x7c\xfb\xc6\x42\x67\xc6\x6e\x2e\x8a\x20\xa4\xa8\xf2\x13\x7e\xbc\x42\x8b\x9b\x39\xd7\x09\x8a\x98\xe9\x7e\x1b\x5d\x8e\x5c\x9d\x79\x3b\xcd\x29\x32\x6f\x6b\xa9\x96\x45\xae\xde\x9d\xfa\xe5\x78\x6b\x42\x61\x24\xd5\x1d\xbd\xe3\xa7\xc7\x24\x36\xbd\x96\xe7\xa8\x00\x1c\x81\x33\x29\x7a\x84\xd6\x19\x07\x0b\x42\x1a\x50\x5c\xd5\x9a\x25\xd6\x1f\x9d\x06\x04\x11\x32\xb4\x2a\x33\x44\x42\xf9\xba\x19\x7e\x37\x54\x8d\x7a\x80\xf2\x04\x85\x45\x4c\x4f\x26\x91\x4c\x6c\xbd\xf4\x43\xb5\x27\xcb\xf8\x21\x27\xdd\x85\xcb\x2b\x81\x4c\x81\x36\xe2\x5d\xde\xdc\x9f\x86\xa2\x7a\x94\x82\x73\xe9\xb3\x63\x3a\x9f\x6d\xbc\x93\x0f\x24\x8d\x48\xe3\x9e\x45\xea\x4a\x59\x12\xaa\xc4\x50\x90\x66\x89\xc6\xdf\x43\x65\x51\x66\x7a\x91\x6a\xaa\x69\xec\xdf\x5e\x29\x49\x7c\x10\xa0\xb5\x55\x80\xbd\xbc\xfa\xe8\x4c\x52\xb1\x53\x59\xb5\xaf\x94\xe4\xec\xdc\xa5\x0d\x9e\x73\x0f\xfb\xf6\x18\x52\xad\xf6\x1b\x34\x37\x48\xf9\xb3\xa6\xad\x4f\x83\xe2\x45\x86\xc8\x25\x19\x7b\xbb\x6e\x96\xeb\xb5\x21\x5d\xc4\xcb\x70\x06\x44\xe0\x64\x60\x51\x37\xdf\x58\xdd\x6f\x7f\x1d\x13\x0b\x23\x07\x68\xfc\x73\xa1\x7b\x7a\xd2\xd9\x72\x66\x94\xb0\x3c\x14\xce\x3d\x5c\x35\x0a\x8e\x78\xdf\x59\x2f\xfd\xc5\x50\x53\x22\x77\xb1\x7e\xbd\x7d\x7d\x7e\xd9\xec\x5e\x56\xaf\xeb\x67\x6f\x6f\x9b\x20\x0c\x48\x74\xb2\xb3\x23\x1c\x18\xfc\x34\x94\xf9\x1a\xd6\xd9\xf8\x7d\xc5\xc1\x08\x2e\x38\xcb\x4f\x99\x50\x32\x62\x53\xd9\x60\x7d\xc4\xb2\xbd\xef\xb5\x80\x33\x13\x71\xa9\x6c\x28\x84\x20\xca\x8b\x52\x4f\x58\x9d\x2e\xf6\xb6\x89\x23\xed\x8b\x14\x6f\xa1\x05\x8f\x27\x9e\x35\x42\xfb\x09\xc7\xa2\x45\x77\xd5\x88\x7d\xce\x24\xda\x0a\x9e\x2a\xff\xb5\x3a\x1f\x40\x42\x83\xdb\x1f\x97\x3f\xb3\x49\x5d\xd5\x14\xc9\x56\xd8\xcb\xba\x44\xe7\x2c\xd9\x62\x84\x31\xb4\x11\xef\x6c\x8e\x3c\x8c\x13\x7f\x57\x90\x32\xb2\xeb\x4e\xfb\x88\x4d\xd3\x99\x6e\xe3\x61\x6f\x40\x73\x72\xc6\x3c\x47\xea\x6b\xde\xf4\x0b\x93\x91\x1c\xc8\x5a\xd8\xbc\x55\x55\xfb\x5a\xc9\xbc\xbc\xaf\x46\xc2\xd9\x93\x0b\xa9\x20\xa3\x5c\xd7\x80\x77\x7e\x3a\x23\xb0\x30\x8a\x59\x52\xe8\xdb\x93\xfa\x87\xb1\x26\xa3\x92\x98\x46\xe0\x40\x1a\x44\x61\x8c\x8b\xeb\x80\x51\x12\x28\xae\x63\x2c\x74\xa6\x07\xbf\x4c\x36\x17\xa3\x03\x99\xe0\x58\xe7\xb2\x21\xaa\x28\xef\x4c\xfb\x01\xa7\xa3\x18\xfb\x2a\x60\x2b\x40\x7f\xd9\x70\x9f\x3c\x82\x36\x91\xe6\x63\xe1\x46\xc2\x23\x35\x93\x28\x9e\x41\xad\x49\xf0\x98\x68\x7c\x5f\x88\x89\xc4\xf7\xb9\x09\xb5\x1a\x80\x08\x2f\x36\xe0\x3f\x2f\xcf\x9a\x4c\x3d\x63\x04\x67\xc9\x24\x5c\xf5\x2b\x58\xf0\x2f\xff\x5e\x99\x11\x73\x7b\xd2\x18\x15\x59\x81\xc6\xa2\xb5\xe5\x5d\x0b\xa5\xfa\x37\xc1\x2c\xb1\xd1\x70\x62\xbe\xa4\x5f\x45\x10\x08\xa0\xa0\x9e\xc7\x7f\x2d\xce\x09\xd6\xcf\xf7\x4f\x11\x30\x29\x88\x07\xd0\x3b\x1a\x6e\x19\xba\xab\xab\x03\x29\xc3\x4c\x06\x9a\x08\xc2\xc0\x50\x58\xf8\x05\x54\x6e\xf2\xa6\xbd\x83\xba\x8f\xe3\x88\x20\x14\x3a\x73\x06\xfa\x0e\x8a\xcb\xab\xb2\x08\x22\x1e\x10\x10\x37\x6f\x9a\x13\x4e\x82\xd8\xae\x41\x6c\x34\xed\xa3\xb5\x55\x55\xb1\x65\xb9\xd3\x26\x09\x37\x24\x44\xe8\x0c\x5a\xbb\xae\x4f\x2c\xea\x4b\x03\x59\x04\x49\x8c\xc2\x05\x07\xad\x89\xb2\x39\x82\xc2\x6e\x9c\x52\xde\xea\xe6\x73\xad\x67\x6f\x9c\xa6\x40\x77\xda\xbc\x81\x45\x00\xf7\x06\x86\x08\x52\x4c\xb3\xd4\x5b\x53\xdd\x5e\xdd\xc7\x9a\x66\xdc\x5b\x22\xc8\x02\x46\x5e\x9b\x15\x46\xbb\xdd\xf4\x7a\xbb\xd9\x58\xf7\x7a\x68\x4c\x89\xc4\xc1\x50\x7c\xab\xb0\xcc\x7f\xbc\x74\xfe\xf0\xcc\x60\x14\x41\xc6\x38\x05\x33\xad\xb5\x60\x81\x2e\x97\x7b\xbe\xb3\xec\x5c\xb4\xcb\x02\x44\x4e\xf5\x99\x50\x81\x08\x20\x60\x54\x91\xd5\xbb\xa6\x50\xb8\x79\x96\xf9\xb2\x26\x0a\xec\xfd\x04\x41\xea\xc6\xb1\x08\x20\x75\x9e\xbc\x8d\x21\x38\x86\xf7\xc9\x08\x04\x61\x81\x77\xc7\x41\xc7\xf8\x31\xb7\xd8\x95\xb1\x85\x29\x02\x50\x11\xd1\x9b\x1c\xf2\xb2\x75\x1e\xa5\x3f\x24\x43\x20\x20\x09\xd5\xbb\x5d\xab\xc9\x72\x6d\x55\x92\x51\x58\xe8\x0f\x28\x46\x74\xc0\x22\xd0\x89\xb0\xe4\x04\x55\x31\x5c\x18\x43\x48\x9c\xb7\xe0\xd3\xa4\x8e\x36\xc6\xd3\xb8\x9c\xd9\xae\x22\xc0\x2c\xa2\x6a\xd0\xbc\x79\x2e\x07\x1a\x69\x11\xa0\xd0\xa1\x63\xc8\xe9\x85\x9a\x36\x47\x1a\xb6\x23\x78\x92\x08\x10\x04\xe5\x3c\x95\xe5\x21\x1f\xea\x47\xfe\x35\xfd\x50\x28\x81\x92\x3c\xa6\x80\x7d\x7f\xae\x66\xa4\x15\xa6\x11\x8a\x7b\x22\x33\x1f\x08\xaf\xbb\xa3\xc8\x7b\x7d\x16\x2a\xb9\xf7\x47\x4c\xc8\xac\x16\x7a\x5d\x7d\xe8\x1d\x96\x7a\xa7\xfb\xc0\xbd\x60\x81\x0c\xd2\x6e\x71\x79\xfa\xba\xec\x7f\x52\xda\x4a\x48\x9d\x64\x43\x56\xf0\x43\xa5\xde\xe7\xe4\xc4\xae\x2d\x8b\x32\x6a\xbb\xbe\x5f\xfe\x8a\xd9\x40\x30\xa6\xb4\xb0\xfc\x1e\xc5\xf7\xbe\xc4\xad\x0f\x8d\x74\xc7\xad\x8e\xc1\xa9\x6c\xc0\xe0\x2b\x36\xf9\xbe\x9c\x51\xec\x0a\xc6\xd0\xd2\xe4\xe4\xcd\xd7\xb2\xc6\xee\xfa\x83\x15\x27\x58\x98\xc9\xd4\x05\x31\x76\x54\xcc\x47\x81\xf6\xdd\x5f\x27\x3c\xe1\xae\x73\xf2\x3c\x17\x8e\x60\x21\x48\x32\x97\x75\x5d\x1d\x3b\x9b\x66\x0e\xdb\x11\x2c\x8a\x7b\x8e\xfe\xa9\x96\xd6\x19\x70\x58\xb0\x28\xb1\x75\x00\x05\x34\xed\xf2\x8f\xe5\x6a\x7b\xef\xef\x13\xc9\x2c\xf0\x19\x48\xef\x3c\x4d\x22\xe9\xae\x1d\x0f\x52\x35\x5e\xe6\xb7\x97\x13\xbf\x82\x71\xc3\xd0\x5b\x57\xce\x2a\xf3\x5c\x2d\xd3\xf9\xce\xe2\x6e\xa7\xeb\xf9\xab\x6e\xf3\xe6\x78\x6a\xf1\xe7\x85\xcb\xee\xcc\x24\xd6\x4a\xf6\x58\x14\x32\x75\x6e\xb1\x68\xe1\x92\xb4\x89\x60\x89\xb2\xa1\x5a\x8a\xea\x6a\xc4\xc3\x4f\x63\x32\x82\x65\xdc\x56\xe4\xd9\xfa\xd3\xc2\xce\x96\xaa\x6c\xaa\xcb\xb5\xce\x82\x65\x20\x99\xb4\x91\xb1\x61\xe8\x8a\xce\x2a\x20\xd3\xa5\x30\xf9\x10\x34\x1f\x60\x7b\xbe\x1d\x46\x44\xff\xf9\x2d\x2f\xff\xfe\x47\xd8\x04\xc1\x20\xb4\x5a\x0e\x9e\xa3\xe7\x42\xc0\x4c\x30\x88\x30\x74\x89\x54\x5f\xca\xef\x1f\x0d\x32\x49\x79\x3a\x6c\xdf\xc8\x4a\x5a\x97\xbd\x12\xa7\x60\x00\x96\x32\x01\xb4\xde\xb4\x60\xcc\x59\x1a\xa3\x1f\x80\xa0\x8c\x49\xe7\x21\x93\xc9\x83\xaa\x34\xa2\x92\x3e\x67\xeb\x11\xa5\x51\x3f\x19\x34\x37\xe8\x28\x65\x4b\xca\x98\xf5\x90\x21\xc1\x34\xda\xba\x02\x53\x57\x87\xed\xc3\x62\x7a\x55\x6d\x6c\x31\x82\xb7\x4b\x51\x2f\xe6\x13\x1f\x13\x63\x95\x04\xdf\xf2\x66\xea\x2d\x0b\x86\x69\x2c\xcd\x40\xbe\xef\x10\x26\x3f\xf5\x19\x04\x33\xb1\x42\x9b\xf1\xa5\xf0\x85\x39\x15\x0e\xcd\xed\xaf\x6a\x20\xa1\x44\xd1\x4b\x63\xf9\xc5\x36\xf9\xfe\x4a\xc4\x44\x30\x83\x8c\xa0\x61\xed\xe7\x11\x6f\x4e\xc6\x9c\xad\x35\x61\x90\x70\xcb\xc2\xd4\xb9\x5b\x8b\xb6\x05\xf5\x46\x45\x19\x73\x84\xb6\x08\x03\xa9\x68\x12\x1d\x50\xe7\xe3\xfa\x4d\x11\xb2\x28\x14\x66\xd4\x4d\x37\x45\xb5\x9f\x74\x64\x18\x86\x09\x79\x19\x1b\x6c\x89\xfb\xf1\x82\x0c\x9f\x08\x43\x1e\x52\x08\xe5\x0d\x0a\x47\xca\x38\x92\xd0\x14\x61\x18\x07\x14\xf4\x54\xd5\xe1\x50\x95\x37\x27\xdd\x6d\x32\xa3\x88\x41\xd7\x42\x11\xf2\xdf\x9a\x09\x0e\xea\x32\x89\x2a\x88\x30\x62\x52\xa9\xc1\x25\x7b\xf2\x3a\xba\x22\x8c\x22\xe3\x53\x74\x76\x79\xfa\x72\xc2\xa6\x71\xe1\x5a\xdf\x88\x33\x0b\xba\xea\x79\x59\xba\x3d\xb3\x6c\xab\xfa\x73\x56\x03\x29\x42\xce\x91\xfc\x23\xcb\x0b\xeb\x07\x63\x18\xeb\x54\xca\x91\xaa\xf1\x4d\x0d\xfb\xfe\xf2\xb1\x11\xe8\xd0\x84\x7f\x54\x75\x83\x84\xb0\x5a\xeb\x89\x17\x22\xc2\x24\x31\x0a\x7a\xf5\xa2\x4d\x55\xe8\xe7\xd2\x56\x8b\x8f\x38\xe6\x45\x98\x98\x94\xe6\xe5\x97\x47\x8f\xa4\x70\x07\xd2\xc8\xb0\xd8\x4f\x3c\x1b\x94\x9f\x7c\xad\x8c\x89\xc4\x19\x51\x2e\xe8\xd4\xd8\xb4\xdc\x95\x7a\x36\x7f\x5a\x02\x52\xf7\xd2\xd9\xce\x5e\xf4\xae\xd7\x14\x5a\x20\xc2\x2c\x4b\x68\xf1\x7e\xa9\xb1\xf1\xc2\x14\x3d\xf7\xec\x2f\x7c\x0a\x77\x09\xc1\x24\x09\x50\x38\xc2\xe3\xb1\x16\xfc\x78\x74\xcd\xce\x82\x00\x79\x38\x56\x7c\x76\xa4\x49\xfe\xb0\x8e\xc5\xc0\x30\x47\x05\xa1\xbf\x42\x8c\xbb\x33\x55\x10\x92\x12\xa8\xaf\x6d\xf2\x8c\xe1\x45\x45\xbc\x35\xa3\x41\xa4\x74\x44\xdc\x2e\x56\x85\xe5\xfe\x53\xd7\xd3\xf9\xa4\x23\xe6\xdd\xc7\x55\xa9\x09\xd1\x34\xae\xb1\xf4\xad\x64\x10\x5b\xd3\x9c\x4e\xa6\xa8\xc9\xd8\xc1\xf5\xcd\x8c\x26\x1a\x39\x9f\xe5\xbe\xb5\x6a\x8c\xfd\x28\xc1\x20\xa1\xc7\x1e\xc0\xfc\xb7\xf9\xf7\x66\x76\x2f\x74\xd4\x97\xda\x09\x3d\x3f\xf5\x28\x39\x11\x62\x64\x23\x08\x33\x1d\x10\xcb\xe2\x32\xbb\x4c\xa6\x3d\x2a\xfd\x5b\x8e\x1f\xdd\x04\xf4\x4a\x0a\xb3\x86\xc8\x20\xec\xe1\x7b\x5f\x1b\x5b\x15\x7c\x53\x80\x7a\x1f\x6f\x10\xbe\xb5\x49\x52\x57\xf7\xb8\x58\x3e\xbc\x56\x05\x66\x22\x0d\xa3\x8c\x85\xa2\x33\xe3\x82\x80\x85\x51\xe0\x1f\xd7\x64\x4c\x9b\x89\xcb\xbb\xad\x11\x9a\x53\x3d\xeb\xdf\x28\x60\x60\xac\xc5\xbd\xef\x0d\x1e\x7f\xc8\x25\xa8\xec\xc8\x3b\x4f\xbf\x8f\xc7\x6d\xe6\xce\x61\xcc\x92\x77\xda\x62\x14\x55\xf9\x6b\x31\x25\x6c\x26\x64\x52\x5e\xeb\xa6\xc5\x65\x2f\x27\x0a\x83\x90\x74\x40\xfe\xb8\x7f\xf9\xad\xff\x29\xa5\xad\xea\xee\x76\x79\x29\xe2\x2d\xa2\xd0\x05\xa8\x5b\x6c\xda\x5d\x6d\x53\x01\xfd\xc9\x29\x10\xc4\xc1\x8f\x91\x5d\x43\xe1\x78\x07\x70\x91\x9e\x52\x78\xd2\xeb\x51\xa8\x21\x75\x11\x4a\xca\x78\x42\xb1\x23\xce\xf6\xdd\xa1\xea\xc9\xda\xbb\x56\x8a\xf2\xcf\xce\x3d\x9a\xe4\x2b\xa6\x0f\x18\xa5\x96\x88\xd4\x46\xe9\x1c\x53\xc9\x74\xe5\x8b\xa2\xd4\x52\x22\xdb\x10\x87\x83\xa9\xf5\xfe\x9a\x6b\xc4\x99\xa1\x20\xcd\x76\xb9\xd8\x78\xeb\x33\xe2\x22\xb4\xac\x49\x70\x20\xcc\x6a\xef\x15\x45\x5c\x33\x36\x08\x7a\x7f\xad\x8b\x8b\x4f\x17\xc7\xb6\x8e\xbc\x21\xd2\x61\xca\xba\xcd\x26\x49\x14\x67\x09\x99\xed\x3d\xd1\xf1\x1e\x67\x8a\x03\x22\x8a\x65\xc2\xa2\x61\xb2\x60\xd9\x36\x6e\x9f\x9a\x37\x54\x48\x9f\xe4\x83\x84\x2c\xae\x39\x48\x51\x22\x33\xcd\x27\x84\xf4\xaf\xc4\x78\x35\xa2\xd0\x15\x51\x0a\x01\xad\x27\xdd\x86\xd6\xca\xaa\x7a\xef\x0f\xe8\x88\xb2\x03\xcb\x37\x38\x1c\xfb\xd4\xad\x88\x52\x0c\x69\xe7\xe8\xd6\x84\xaa\xfe\x5c\x94\x7a\x83\xe5\xcc\xdf\x8f\xb2\x24\xf6\x3c\x9d\x5f\x2c\x19\x44\x55\x37\xeb\xde\x13\x8b\xb2\x2c\x90\x63\x25\x80\xcd\x1b\xd4\x78\xd9\xae\x8d\x84\xb1\x5c\x97\x35\xaa\xea\x3b\xd6\x4b\x98\x99\x59\x11\x60\x4a\x86\x0c\x25\x03\xd6\x96\x65\x9a\xfb\x3b\xc9\x94\x93\x21\xa9\x2a\xcb\x12\x85\x16\x55\x38\x2e\x8e\x16\x91\xcc\x64\xe0\x41\x53\x96\xcf\x3b\x57\x50\x3c\x42\xfd\x6e\x29\x38\x72\xf5\x3e\xff\xa0\x8a\x69\x6b\xfd\x92\x3d\xe1\x1c\x72\x3b\xe8\x7a\xe5\xcf\x7e\x21\x8d\x14\x4a\x39\xa4\x9a\x29\xa4\x40\xa4\x1e\xd7\x49\x71\x7a\xd3\x27\x52\x86\xa7\x4e\x76\xb5\xde\xa3\x4d\xfd\xd9\x94\xc3\xdd\x15\xd6\x07\x11\xe9\xd0\x7e\xd5\x3d\xb6\x23\xa5\x4d\x11\x69\x2e\xc8\xfb\xff\xf7\x76\x35\xde\x55\x22\x23\x99\xc7\xff\x55\xa7\x11\x15\xdb\x35\xf0\xa1\xe0\x41\x60\xc8\x56\xda\xbc\xe7\x93\x40\x02\x0f\x42\xa0\x05\x77\xb7\xd3\xb6\xdc\x69\xb7\xeb\x0f\x01\x12\x9b\xe9\x50\xa5\x38\xbb\x26\x18\xf4\xcb\xd0\x1d\xe4\xc5\xcd\xa9\x2e\xbf\x9c\x3e\x9f\xaa\xc5\xa9\x77\x1b\x38\xd3\x32\x71\x06\xca\x50\xd6\x2d\x78\x14\x24\x34\x27\x96\x50\xda\x84\xb8\x3f\xc0\x23\x20\x04\x83\x6c\xdb\x66\x82\x8d\x15\x3c\x0e\x39\xc5\x75\x9f\x56\x37\xcb\x9f\x39\xe5\x3c\x86\x8c\x30\x2c\x56\xc0\xe4\x75\xb5\x59\xbd\x7e\x5b\xb1\x81\x29\x59\xf0\x58\x32\xda\x10\x5a\x78\xc7\xc1\x1d\x9f\x5e\x44\x27\x96\xdb\xc3\x6b\xd1\xf5\xe7\x62\x10\xe8\x41\x5a\x8f\xc4\x6b\xfc\xc8\xe1\x49\xa8\xa2\xf1\x0e\x0a\xaa\x0d\xa7\x13\x84\x27\xb1\xa6\xcc\x84\x86\x16\xee\xaa\xfa\x22\x1f\xb7\xe0\x89\x8e\x48\xb0\x63\x73\x2c\x28\xb3\xba\x6a\xdf\xb6\xd5\xaa\x55\xfe\x46\x69\x04\x94\xd7\x7e\x79\x5d\x6e\x59\x10\xec\x6e\x47\x84\xb3\x82\xa7\x49\x90\x88\x79\x61\xcc\xec\x0e\x69\x92\x68\xed\xe3\x6b\x4e\x6d\x6a\x12\xa1\x16\x3c\x8b\x84\x15\x8b\x7f\x43\xf5\xfe\x05\xf2\xb2\xd9\x56\x0e\xbd\xe3\xef\x94\xa5\x31\x71\xc1\xec\x34\xaa\xfc\x00\x45\xc3\xb2\xfe\x90\x41\x0a\xfd\x7e\x14\xbd\x4a\x9a\x3b\x22\x62\x96\xda\x1a\x8a\xf2\x7b\xae\xda\xbb\x7c\x5e\x4b\x32\x0c\x32\x81\xcc\xaa\x0f\x9f\xea\x31\xc0\x58\x70\x48\x42\xe9\x4a\x65\xc6\xb6\x0a\x69\x94\xd0\x34\x65\xc1\x74\x54\x80\x88\x08\x01\xdb\xee\x71\x83\x6d\x9b\x97\xfb\xe6\xa5\xdb\xbf\x5d\xa4\x6c\xed\x6a\x8c\x5f\xb0\x1e\xd1\x8b\x0a\x2e\x33\xfb\xb9\xba\x07\xad\xea\x1c\x4f\x24\xee\x94\x2b\x36\x9e\x91\x5c\x42\x16\x45\x83\x40\xf6\xcc\x7d\xe4\x0a\x18\x21\x2a\x96\x50\x4e\x4e\x53\x5a\xd8\x85\xb5\x00\x45\xb5\x1a\x3f\x35\x93\xb9\xd2\x8a\xea\x63\x17\xb7\xff\xf9\xa9\x1a\xf0\x2f\x8b\x14\x7f\xf1\xdf\xee\x76\x3a\x88\x89\xf0\x4e\x9e\x3e\x77\xba\x1e\xc9\xf2\xcc\xdb\x25\x48\xee\xe4\xb6\xce\x8f\xdd\x28\xda\x22\x1c\xa6\xbe\x1a\xd7\xa9\xb4\x62\xd4\x05\xe4\x07\x47\x6a\x3b\x97\xdf\x11\x1c\x83\x28\x71\x98\x83\x62\x51\x3a\x4e\xe0\x5d\x78\x59\x31\xd4\x9f\x13\x23\xeb\x06\xe0\x97\xd5\xea\xb7\xfe\x27\x13\xda\x02\xe4\xce\xdc\x5c\xf4\xa5\x65\xf3\xbb\xa1\x65\x67\xdf\x75\xfe\x5b\x7e\x70\x62\x08\x17\x57\x68\x6e\x92\x98\xf6\x0f\x0b\x6e\xa0\x17\xa0\x10\xe2\x6c\xaf\xe7\x06\x2d\x60\x83\x5a\xdc\x63\xe1\x87\x6b\x1c\x24\x40\xc1\xcc\xc7\xc5\x7f\x76\xdb\xd7\xc5\xd3\xf2\x7e\xb5\xf1\xc7\x18\xb7\x56\x4e\xe7\xa4\x39\x9c\xd4\x78\xe4\xc6\x4c\xa8\x38\xe8\xab\xb2\x67\x88\xfe\x8b\x9f\x2e\x0e\x43\xae\xbd\x6c\xbd\x03\x16\xdf\x14\x95\xec\x7c\x44\x7c\xaa\xda\xd7\x3e\x0a\xe2\x9f\x21\x8c\x74\x9a\x0e\xfa\x8f\x8e\xdc\x6c\x6a\xb3\xc5\x61\xca\xbd\xc3\x3b\x4b\x48\x58\x5c\x0d\xa5\xb7\xcf\xd3\x12\x71\x98\xa5\x94\x16\xee\xe6\x19\x4e\xa8\xc8\x7c\x03\x23\x68\x97\x18\xf2\x7b\x4b\xcb\x46\x87\xf3\x4b\x71\x13\x4b\x5b\x88\x5d\x2e\xdf\xaa\x1e\x2a\x20\xe2\xb8\xfb\x48\xce\xd3\x22\x56\x24\xa8\xdb\x5c\xe5\x47\x28\xaf\x80\x6a\x2f\xcf\xb1\x38\x16\x31\xed\x4c\x26\xaf\x1b\x87\x38\x5f\x3e\x7b\x98\x54\x7f\x33\xb4\x4a\x5c\x34\x9c\x7d\x32\x7c\x16\xd6\x8d\x93\x34\x23\xcf\x07\x7f\x1c\xf3\x1a\x47\xc0\x21\x11\x27\x19\x90\xed\xb8\x25\xb6\x29\xd6\xff\x2c\x22\x10\x3e\xa0\x30\xc1\xe3\x88\x38\x31\x0a\x1d\x8a\x61\x51\x5c\x25\x83\x76\x8d\x53\xce\x68\xb4\x7d\xf9\xcf\x6a\xf3\x01\xc7\x63\x6f\x52\xc4\x69\xc6\x48\x75\x98\x96\xf4\xb5\xf9\x13\xa1\xbe\x87\xe6\x05\x9a\x21\xc8\x16\xa7\x3a\xa1\x24\x7b\x79\x3a\x3c\x9b\x07\xdc\x63\xa9\xa1\xee\x9f\x3d\x35\x99\x34\x43\x21\xce\x63\xf5\x1d\x07\x64\xb6\x7f\x00\x91\xf0\x40\x78\xf0\xff\xbe\xb6\x2a\x46\x7d\x9c\x33\x16\x69\x4c\xf8\xde\xfb\xe5\xc3\xaf\x83\xec\xb1\x50\xd2\x4a\xae\x9c\xca\x77\x6b\x88\x11\x31\xc3\x28\x5b\x11\x43\x66\x19\x3c\x6d\x39\xec\x1f\x88\xef\x8f\x90\x97\xeb\xe5\x33\x2d\x33\x5e\xb1\xbe\x6f\x2d\x5d\x9d\x37\x94\xdd\xf6\xed\x0a\xbd\xa7\x53\x39\x06\x09\xc4\x90\x52\x40\x69\xc3\x94\x4b\x28\x75\xdf\x0b\x92\x6b\x0a\x61\xbd\x9e\xc6\x59\x93\x58\x1a\x4b\x90\xdf\x5a\x5a\x46\x16\x1c\xeb\xd1\x18\x55\xcc\x46\x24\xf6\xe8\x10\xd2\xa8\x69\xeb\x1d\xb3\x8b\x77\xad\xa4\x96\xbd\x10\xcc\x85\x92\xe6\xb1\x33\x1a\x2b\xae\xc8\x81\x3c\x59\xee\x03\xfc\x3e\xb1\x95\x63\x95\x24\x09\x8c\x98\x2e\x0f\x87\xaa\x74\xe0\x5d\xdf\xc2\x44\xc4\x35\xf8\x1d\x8a\x5c\x8f\x25\xc1\x67\xab\x73\xac\x39\x32\xd9\x17\x74\x50\x66\x9d\x04\x26\xa7\x43\x0f\x33\x49\x0e\x87\xf5\x38\x2f\x60\x75\x45\x8c\x2a\xe6\x9e\x59\x1a\xd4\xfb\xfc\x28\x46\x64\x5f\x5d\x0b\x21\xb9\x66\x86\x27\x54\xd0\x7b\x80\xfa\x7d\x51\x14\xaf\x3d\xc0\x43\x24\x01\x47\x6d\xd7\x4b\xe7\xef\xee\x6c\x8d\xcf\x6f\xe7\xe6\x7a\xc2\x98\x26\x5f\xc2\xcd\x07\x2b\x8a\x77\xf3\x79\x39\xee\x9e\xb0\xd0\x08\x5f\x40\x30\x64\x00\xb7\x7d\xf0\x6e\xfa\x2a\x09\x8b\x18\xf9\xc1\x4f\xf8\xb1\x2a\xdb\x7a\x4a\xf3\x21\x12\xc6\x53\x1a\x2c\x35\xe5\xf8\xfd\x28\x49\x42\x40\xf0\x3c\x12\xcf\xcf\x0f\x3b\xd4\x79\xbb\x0b\x27\xca\x79\x22\x89\x58\x2a\x9d\xcb\x40\x41\xde\x81\x2a\x55\x24\x51\x6a\xc3\x57\x47\x1b\x79\x78\xc9\x1d\xcb\xc4\x40\xa8\x41\x6d\x24\xf7\x8a\x31\x7b\x8a\x6c\x5d\x0d\x8e\x4d\x6f\x9c\x69\x74\x6e\xef\xba\xc5\xc3\x53\xd5\xeb\xcf\x4e\xdf\x3d\x52\x56\x2d\xaf\xf5\x42\x2f\x93\xe2\x6c\xdf\x48\x83\x74\x3e\xef\x53\xa5\xd1\x87\x47\xc7\xf9\xe5\x24\xce\x98\x0f\x61\xbe\xc0\x50\x65\x34\x2d\x64\x9e\x9c\x91\x44\x21\x81\x12\x15\x94\x57\x19\xb0\x2e\x0c\x85\x24\x31\x0e\xb1\x79\xc8\xcb\x4d\x8f\xd8\x5e\x97\xdf\xf3\x73\x78\x90\x3f\x27\x4d\x06\xdc\x57\x7d\x78\xae\x41\x5d\xc1\xa5\x88\x24\xc9\x20\x72\x51\x96\xe7\x23\x96\xaf\x55\x75\x38\x57\x32\x14\x49\x1a\x2b\x70\x02\x9f\x97\x87\x7e\x92\x26\xd2\xa2\xca\xed\x76\x9a\xff\x8d\x8f\xa3\x38\x4d\x92\xb9\x1a\xc2\xbc\x21\xc0\x97\xd5\x54\x98\x7d\x9d\x4c\xd9\x1a\x49\xfa\xf0\xea\x0d\xf2\x72\x79\x6a\x73\x6c\x06\xc8\xbf\x48\x32\x2d\xc9\xdf\xfa\x02\x7f\xe3\xc8\x65\x4c\x44\x66\x82\xb0\xd7\x37\x9a\x99\xba\x89\x30\x92\x90\xdc\x5f\x37\xb7\xab\xed\xfd\x40\x2e\x23\x12\x60\x29\xf0\x21\x5c\xfb\x8a\x8d\xe7\x6f\xbb\x18\x95\x48\x14\x44\x84\x14\x3b\x9e\xda\x9d\x8f\x3c\xec\x4c\xf5\xcb\xe2\xc4\xab\xd6\xef\x78\x8c\x28\x0c\x98\x67\xd5\x80\xbc\xf8\xa4\x81\x62\x0b\xf4\xbf\x55\xc5\xe9\x80\x1b\x1c\xa7\x6a\x12\x1d\x5b\xa2\x65\x02\xea\x1e\xab\x7a\x46\x80\xee\x5b\x65\x81\x17\xcd\xe8\xd5\x35\xfa\xa5\xe4\x92\xf9\x9a\x60\x10\x59\x2c\xf7\xc0\x1f\x70\x05\xe0\x28\x12\xd4\x69\x0c\xce\x0e\x6c\xf0\x52\x9d\x9f\x48\x0c\x0f\xc8\xab\x23\x2a\xfa\xe7\xb2\xdf\x08\xd2\x20\x0a\x69\xde\x2e\x8b\x7c\xcc\x22\x26\xd2\x80\x47\xe4\x49\xae\x55\xd5\x3b\x52\xbf\x90\xf4\x14\x69\x00\x81\xf1\x95\x40\x9d\xf7\x66\x79\x69\xfb\x50\x4a\x5e\x95\x84\x19\xf1\xad\xb5\xd5\xa1\xb1\x7b\x82\xdf\xe8\x52\x16\x82\xb1\x44\x0a\xe5\x7e\x8b\xf5\xe1\xbe\x2a\x46\x5d\x9e\xb2\x34\x12\x6e\xbf\xf9\xb6\x7e\x19\x71\x69\x8b\x34\x34\xb6\xdc\xbb\x1e\x07\x72\x08\xe2\x7f\xb5\x38\x42\xa4\x11\x0b\xa9\x9a\xab\x5b\x13\x89\x08\xfc\x76\x30\x09\xd2\x48\x07\xe4\xc7\x76\x03\xfd\x03\x6a\x9c\x74\x51\x84\x11\xb3\x31\x2d\xc2\x5b\x6c\xb0\x28\x96\x79\xfb\x79\x57\xd5\x03\xf2\xdf\x9b\x3e\x29\x8f\x52\xf2\x3e\x8e\x30\xd2\x51\x12\x29\x4f\x22\xe8\x19\x8c\xce\x25\xad\x44\xca\x05\x68\x2b\xcf\xe0\x40\xb4\xd3\x29\x9b\xc6\xc8\x69\x62\xb9\x32\x40\x9f\x9b\xf8\x5a\xe6\x7d\x78\x30\x4d\x02\x4b\x2c\x45\x85\x8c\x4e\x51\xf9\x9c\x8d\x47\xa4\x49\x1c\x11\xaf\x29\x25\x79\x07\x14\xe5\x0c\xcf\x29\xd2\x24\x4d\x42\xb7\x15\x2d\x76\xdd\xde\x48\x15\x3a\xb3\x8b\xa5\x46\x90\xad\xf7\x75\xbb\x1c\x89\x40\x8a\x34\x63\x82\x39\x4a\x66\x27\xf1\x77\x46\x27\x32\x5a\x7e\xd3\xcc\x28\x0a\x42\x53\xfa\x72\x08\xca\x91\x42\xc5\x65\xe4\x99\x48\x45\xc0\x88\x4c\xf1\x8f\xbc\x7d\x1b\x87\xd7\xa6\x0f\x08\xa9\x06\x39\x0f\x35\x0f\x30\xa0\x51\xa9\x63\x0f\x17\xba\x00\x12\xfa\xd7\x2c\x38\x9d\xca\xc0\x8a\x6e\x5b\x60\xf4\x25\x2c\x49\xaa\xb8\xc5\x6c\x37\x6f\xd5\x87\x0f\x34\x50\x61\xc9\xdd\xa9\x28\x66\x7d\xad\x32\x1b\x4f\x3e\xc2\xe7\x08\xdd\x7d\xf3\xb9\xb8\x30\xcd\x53\x25\x03\x42\x9a\xba\xd8\xd4\xc4\x80\x4c\x95\x42\x42\x64\x77\x6b\x7b\xbf\x3c\x8f\x7a\x5a\x87\x92\x39\x44\x09\xd5\x11\x2e\xea\xba\x77\x4d\x52\x1d\xc7\x44\xf4\x74\xf0\x45\x40\x5f\xb0\xbd\xa9\xa0\x9e\x65\x2e\x53\xe4\xa9\x27\xee\xec\xe6\x51\x67\x6e\xaf\x66\xa5\x1f\x22\x0b\x02\x45\x50\xdb\x43\x5b\x5f\xe4\xf7\x11\x59\xc0\xb5\x67\xd5\xd9\xc0\x1e\x3c\xc4\xb5\xee\x8f\xc7\x86\x4a\x78\x9a\x28\x74\x61\x9d\xe1\x00\x01\x34\x5e\x5e\x96\xb3\x2d\x28\x0b\x0c\x63\x66\x08\x41\x4f\x20\x79\xd3\xa1\x91\xb1\x48\x50\x16\x22\x6f\xfe\x98\x71\xde\x3c\x5c\x00\xc6\x65\x0c\x52\x32\xe8\xec\x46\xb1\x98\xbd\x2d\xd3\x01\xf9\xd0\x5d\xbf\xdf\x55\xf5\x1f\x55\xfd\xfe\x73\x37\x3d\x63\x3a\xa6\x6f\x4e\xab\xb5\x7b\x3f\xd7\xc1\x59\x98\xd8\xd4\xad\xed\x10\xcb\x79\x56\xb7\x67\xec\xbb\x22\x0b\x25\xcb\x5c\x98\x66\xb3\xfa\xfd\xeb\x65\x4b\x25\x0b\x75\x6a\x09\x72\x89\x0f\xdc\x89\x99\x13\x39\xaf\xf5\xcc\xc6\xf8\xb3\x84\xf7\xc3\x3e\xfc\x9f\xb9\x62\xf1\xd8\xfb\xc8\xa2\x24\xd1\xa9\xd5\xca\xcb\xb2\xac\xa7\xad\xde\x84\x97\x4d\x97\x2c\xd2\xa1\xcd\x8a\x57\x85\xde\x7c\x1e\xa4\x67\xd5\x11\x19\x0f\x22\xc2\x51\x22\xb1\x95\xe7\x0a\x6d\x39\xc0\x65\xf4\x3b\x35\x57\xd1\x54\xcf\xb9\x98\x30\xba\x8b\x8c\x63\x4c\x93\x6f\xd7\x9c\xe4\x9c\x28\xf6\x62\x0a\x26\x8b\x03\x43\xf8\xd2\x12\x7f\xb4\x9b\x16\x8f\xb3\x8e\x8e\x43\x4d\x85\x4c\x2f\x8b\xd7\xcd\x6a\xb9\x5b\xbe\xae\x6e\xd7\xdb\xcd\xee\x71\xfd\xb4\x7e\x5c\x3c\x38\x01\x28\x7f\xf7\x38\x4a\x84\x05\x9c\x80\xfe\x6a\x2f\x33\x9d\x41\x59\x2c\x24\x85\x75\x6c\xea\xf1\x01\x88\x3d\xb9\x46\x9c\x37\x83\x28\x10\x97\x96\xd1\x2b\x5d\x1c\x83\x24\x52\x46\x1b\xb6\xef\x2c\xef\x09\x32\x31\x4b\x38\xf7\xb0\x89\xbb\x1a\x91\xf2\xd9\xb3\x61\x9e\x70\x41\x79\xb4\xed\xe7\xdf\xd5\x44\x1f\x4d\x64\x89\xb0\xd6\x38\x45\x3e\xac\xfa\xb7\x15\xdf\x6c\xe6\xd1\xbc\x2c\x31\x26\x0a\xfb\xdc\x77\xf7\x65\xd6\xa4\x31\xbd\xc7\x68\xd6\xb1\x59\x1c\x13\x72\xc7\x0e\xf5\x33\xbe\x0e\x41\x42\x1f\xc2\x3b\x13\xb4\xa1\xcd\x31\x1a\x59\x26\x43\x37\x93\x1f\xab\xf9\xb4\xcd\x14\x33\x66\x54\x46\xd2\x4d\x73\x3f\xbc\x66\x2d\x75\x2c\x28\xe1\xf8\x2b\xbf\x61\x62\x53\x8e\x6d\xc0\xce\x51\xa6\x42\x1e\xe2\xe0\xa5\x41\xe9\xd8\xea\xa6\xaf\x24\x52\x46\xe8\xef\x9d\x3c\x7d\xbe\x42\xf9\x7e\x65\x81\x12\x4e\xc0\xb4\xf2\xe4\xca\x67\x22\xdc\x22\x03\x96\xd1\x2a\x82\x43\xd5\x75\x33\x08\x12\x8a\x0c\x20\x8c\x64\xef\xb5\xaa\x3e\xa7\x38\xbb\x8a\x8e\xd1\xf9\x1d\x3b\xa8\x65\xde\x36\x3b\xe7\x40\xee\xaa\x23\x96\xa3\x0d\x24\x53\x82\x13\x2f\xc6\x06\xdb\xdb\x5c\xbf\xc0\xe7\xf3\xa9\xbd\x80\x20\xcc\x14\x32\xd2\x20\xb0\x29\x9e\xce\x5d\xa4\x6f\xb7\xbe\xbd\x32\xa9\xb5\xb2\xe1\x70\xcf\x0c\x1b\xb1\x89\xd3\x9b\x61\x24\xe2\xc0\x73\x6e\xfe\x52\x28\x40\x64\x26\x4d\x28\xee\x78\xac\x51\xe5\x15\x0e\x35\x8e\x22\x33\x32\xa0\x80\xbd\x9d\x7c\xb7\x38\x00\x4e\xc6\xdf\xd2\x68\x2b\xa2\x42\xa3\x7d\x10\xd3\x17\x82\x69\xa4\x7a\xf7\x3b\x92\x77\xf6\xbf\x86\x01\x12\x20\xc1\x4b\xf2\x2e\xa1\x79\xab\x4e\xed\x6f\x3f\x8b\xb2\x8b\x30\x62\x24\x45\xf9\xf2\xba\xda\xad\x97\xcf\x76\x39\xf9\xfa\xb8\x5b\x3e\x3f\x6d\x5f\xd7\x37\x5f\xb7\xeb\xe7\xa7\xfe\x06\x80\x64\xab\x7f\xbd\x59\x6d\x97\xcf\xeb\xa7\xdd\xc3\xea\xf6\xcb\xea\x75\xb7\x7d\xf6\xff\x5a\x3d\x6d\x5f\xff\xdc\xdd\x3e\x2f\xbf\x3e\xae\x9e\xb6\xbb\x97\x45\x8f\xda\x14\x51\x10\x52\xfc\xa6\xce\x9b\xf7\x66\x3a\x1a\x45\xc4\x13\x12\x64\xeb\x56\xbe\x97\xaa\x21\x14\x80\xa7\xb1\x17\x22\x8a\x6d\x8c\x69\x8f\xed\xe2\x20\x73\x2c\xdb\x2d\x1e\x8e\x2e\xae\x4c\x61\x85\xf9\xf5\xb8\x01\x9a\x04\xdb\xea\xf8\xf5\xe8\xb8\x55\xdc\xa1\x38\x0c\x44\x7a\xd1\x0d\xec\x5b\x44\x01\x71\xfe\x2d\x9a\xb6\xf3\x5d\x4b\x52\x6c\x18\x1b\xe4\x22\x8d\xa3\x4c\xf4\x1a\xd6\x9d\xcf\x30\x1e\x27\x22\x4d\x2c\x89\x57\x63\x59\xe2\x67\xf3\x45\xa4\x26\x53\x66\xc4\x04\xe6\x96\x02\xf2\x30\xe6\xa6\xb2\xc8\x78\xea\xa1\x00\x9a\x88\xcf\xce\xcd\x64\x91\xa1\x61\x67\xe9\xb6\x47\x78\xbf\x30\x40\xa7\x27\x0a\x6e\x69\x32\x6e\xf1\xbb\xaa\xca\x70\xf2\x8e\x22\x49\xa5\xed\x27\x8d\x78\x58\xfd\x20\xb9\x19\x7d\xdd\xbf\x11\x42\x6b\x5a\x9a\x57\x9b\xea\x54\x4c\x2e\x05\x01\x52\xb8\xfa\xf9\x88\xe5\x62\x4d\x6b\x12\x51\x0d\x4e\x1b\x31\x8c\x92\x81\xcc\xb7\x3d\x4b\x46\xf9\x76\x90\x10\xc8\xf8\xdf\x27\xbd\x1f\x6d\xcf\x14\x52\x9f\xac\x8a\xfd\x60\x00\x0c\x46\x6a\x3b\x37\x20\x73\x1c\xdb\xdf\x3f\xfd\x97\xbb\x84\x8c\x38\x85\xb4\xec\x74\x5d\x56\xa7\x63\x81\xeb\x03\xec\x71\xfd\x72\xb7\x79\xeb\x5c\xcd\xc9\x00\x90\x71\x44\xb1\xdb\xd7\xf5\xf2\x7e\xf2\x92\x32\xe1\xba\xdf\x48\x7a\x6e\xf6\x9d\xc6\xb2\x3a\xe4\xe5\x08\x18\x24\x64\x92\xd2\xa2\xfa\x6d\xfd\xba\x9d\x5e\xc2\x64\xc2\xd5\x51\xd8\xed\x78\x5b\x59\x84\xf0\x93\x27\xca\x10\x42\x05\x51\x12\xf4\xae\xeb\x78\x79\xf7\x0d\x38\x8f\x3c\x05\x22\x45\x69\x3a\xc7\x84\x20\x92\x57\x8a\x71\xdc\x79\x9a\xc5\x71\x32\xcf\x4e\x9c\x87\xf7\x84\xce\x78\x60\x2c\x1f\xc7\x4b\xf5\x3e\x30\x35\x4c\x7a\x09\x03\xa3\xc4\x98\x5a\xf1\xa5\xea\x2f\x80\x51\x4a\x55\x9f\xdd\x52\xb6\x28\x27\xaa\xd2\x97\x17\x5b\x81\x59\x4a\xde\xbc\xb5\x36\x46\x24\x4d\xf3\x76\xca\x10\x15\xed\xf1\x0d\x1a\x8c\x56\xa5\xa5\xf4\xf0\xf7\x35\x2c\x20\x48\x6c\x5d\x55\x87\xa7\x7c\xff\xd6\x36\xcf\x66\xe2\xc1\x5e\x88\xdc\x09\x23\x34\xcd\xf7\x3f\x97\x37\xe3\x4f\x05\x81\x4c\x52\x31\xc3\xb3\x55\xe7\x7b\x7a\x9f\x0d\x62\x9e\xc9\x70\xda\xeb\x10\x26\x09\xd5\x42\x3c\x61\x55\x5e\x82\x5b\x8f\x7b\x15\xc2\xd4\xba\x14\xc7\x37\x9c\x04\x5a\x20\x0a\x42\xc2\x75\x7d\xdd\xdc\x2e\xfb\xdf\x20\xf0\xca\x94\x8f\x79\x79\x6a\xcf\x7d\x5d\xdf\x10\x2d\xbf\xf9\xb2\xaa\x25\xcc\x52\xf9\xc0\x99\xf0\xb2\xbc\xbb\xa6\x33\xb0\x76\xb7\xf0\x39\xdb\xdf\x81\xc7\xcc\xc8\x5e\xcf\x51\x11\x11\x41\x89\xc5\x64\xe2\x00\x8f\x2d\x5c\xc8\x63\x3a\x2c\xd0\xb9\x73\xaf\xad\xd2\x43\x63\xff\x3c\x55\xed\xba\xfc\xda\x78\x06\x66\x01\x5c\x58\x35\xab\x03\xfc\x18\xc7\x36\xec\x58\x98\xf9\x67\xc0\xa5\xa6\x8d\xc8\x74\xe3\x17\x7c\xb0\xa8\xcf\x3f\x01\x57\x8c\xb4\x5c\x6f\xf1\xfb\xd4\x5b\x84\xd8\x84\xda\x4c\xcb\x6f\x6c\x1e\xd9\x1d\x4f\x84\x0a\xfa\x4c\xaa\xf4\x70\xbf\x33\xdc\x8e\x6b\x9d\x82\xad\xb2\xbb\xc5\x62\x53\xa9\x1c\x0a\x4f\x7e\x34\xf3\x78\x5c\xf3\x8c\x59\x89\x74\x4a\x94\xbc\xcc\x99\xcb\x2f\x7f\xb6\x2c\x4a\x89\xa0\xb2\xa0\xc2\xdf\x9f\x3a\x83\x20\x78\x1c\x0d\xf2\xdd\x6e\x71\xf1\x7d\x77\x56\xca\x01\x42\x47\x04\x02\xba\xca\x93\x30\x7d\x7a\xa1\x13\x0a\xb5\xdb\x95\xef\xd5\xab\x4f\x38\x7b\xdc\x35\x02\xb0\x13\xc9\xc6\x98\xd4\xa7\xdd\x19\x2d\xfa\xcd\x35\x91\x28\x69\xaf\x7b\xb1\x32\x64\x5f\xe0\x80\xab\x1f\xb3\x1d\x16\x74\x00\x91\xab\x7f\xb4\x95\x36\x17\x02\x3e\xa0\x03\x34\x13\x86\x01\x3b\x5a\x7c\x48\xeb\x72\x87\xea\x38\xb0\x61\xcc\xbc\xd4\x36\x4d\xb5\x05\x2f\x11\x23\x40\x43\x4a\x7e\x42\x8f\xe9\xb6\x3b\xd9\x38\x76\x08\xc8\x14\x11\x46\x94\xd0\xe6\xdf\xf1\x15\x8f\xa7\x76\x0c\x4e\x01\x54\x90\x26\x3d\x04\xbe\x86\x79\x1e\x0c\x4c\xc0\x89\x3c\xd0\x7e\xa7\x27\x50\x77\x75\x75\x78\x7a\xb8\x9b\xf5\x81\x61\x96\x5c\xeb\x35\x6f\xb0\xfe\x0e\xab\xed\xfd\xbc\x41\xa8\x95\xab\x40\x1d\x15\x32\xce\x6f\x06\x96\xac\x7a\xa1\xf5\xc8\xaf\x39\x27\x21\x10\x60\x94\xa4\x9c\xaf\x3c\xd5\xb3\xf5\x41\xb2\x28\xa3\xdd\xf3\xf7\xbc\x28\x06\xfe\x2f\x21\x59\xca\xac\xce\x7a\x7e\x38\x16\xd8\x5e\xd3\xd6\x98\x3c\xb6\x64\x59\x10\x12\xbd\x22\x62\xf3\x6a\xd5\xf3\xf6\xb5\x27\x34\x11\x92\x19\xa0\x10\xe4\xeb\xf3\xc3\x8a\x90\x0e\x9b\x3b\xaf\x53\x29\x64\x18\x58\x09\x5a\xd0\x7a\xf5\xa3\xad\xe1\x8a\x5b\xee\x5b\xcb\x80\x9c\xb1\xc5\xcd\xed\xea\x61\xb7\xb8\xbd\x7d\x5d\x6d\x36\xfd\xa5\xb4\xad\x67\xe9\x8c\x38\x2f\xbe\xeb\x63\xb0\x32\x8a\x2c\xab\xca\x17\x6c\x97\x79\xfb\x49\x2c\x9c\xfe\x50\xd6\xd7\xb5\xad\xcb\xef\x15\xd1\x2c\xba\x55\xc6\x03\x98\x2f\x05\xea\x65\x64\x32\xb2\x90\xef\x0a\x38\x0c\x6f\xcb\x85\x4e\x7a\x02\xda\x25\x1c\x09\x5b\x01\xea\x6d\x8e\x5b\x90\x1c\x22\xc2\x0c\xdf\xe2\xb1\xdf\x64\x25\x57\x96\x0c\x9b\xce\x76\x49\x90\x97\xba\x3a\x54\x76\x51\x9b\x5e\x21\x66\x4e\xd0\x91\xf4\x88\x0f\xa7\x32\x6f\xaf\xa9\xd2\xf8\x33\x42\x6b\x85\xd4\x4e\x5b\x74\x3c\x0d\x64\x1c\x4a\x21\x1d\x43\xdb\x98\xa8\xfa\x52\xc8\xd3\x9f\xc2\x03\x0a\x61\xdf\x9d\xd4\xfb\x9f\xd5\xa9\xbf\x92\x8c\x69\x74\x1d\xe0\x07\xe5\x02\xc6\xf0\x29\x19\xa3\x55\xf8\xaf\x4e\xed\xf1\xd4\xda\x3c\xd5\xe5\xaf\x9d\x30\x4b\x04\x68\x4d\xbc\x6f\x98\x9b\x4f\x4f\x7c\x38\x6a\x94\x19\x1e\x0c\xce\x83\x63\xa6\x99\x84\x3f\x65\x8a\x29\x77\x59\xf6\xc7\xcf\xce\xe4\x75\xa6\xfd\x6c\x52\x64\x22\x23\xdb\x9b\xe2\xcd\xcb\xaa\xfc\x8e\x75\xbb\x2e\xdb\xea\xbe\x2d\xd4\x6f\xff\xb0\x70\xf4\x7a\x74\x58\x66\x92\x3b\x9d\x1f\xd0\x63\xbe\x37\x21\x33\x2d\xe3\xd8\x9a\x56\x37\x23\x96\x65\x21\x45\x14\xa9\x91\xb2\xce\x1d\x14\x85\x84\x0b\x76\xd7\xb9\x58\x9f\x90\x22\x4e\x69\x58\xbf\xde\x4c\xac\x55\x29\x52\x4d\x76\x03\x45\xfa\x37\x79\xef\xc1\x4a\x88\x6c\x9e\xde\x65\x2e\x5d\x15\xdc\x39\x71\xb2\x90\x90\x61\xc2\x7a\xd4\x42\x91\xab\xbc\xdd\x58\x95\xdd\xcf\x31\xa8\x43\xca\x38\xa6\x19\x02\xc7\x71\x5d\xeb\xa5\x24\xb2\x54\x01\x12\xe2\xa9\x5b\xe9\x71\xe2\xda\x49\x15\x5a\x67\xe1\x06\xf6\x2f\xa0\xde\xa7\xc7\x78\x4c\xd4\x26\xdb\xfb\xe7\xfe\x27\x08\xb5\xc3\x97\x3a\x8d\xd7\x8b\x0a\xf4\x97\x87\x9c\x92\x8e\xe3\x17\x0f\xd5\xf4\x46\x46\x50\x81\x69\x9b\x77\xbb\xdb\x31\x1f\xad\x6f\x5a\x5a\xf4\x39\x75\xe8\x16\xe1\x70\x77\xb2\xf2\x30\xbd\xfd\x22\x31\x4b\x81\xd9\x98\x4d\xe9\xad\x2c\x77\xc8\xa8\x84\x30\xb5\x2f\xeb\x6f\xcf\xdb\xe5\xfd\xc2\xd3\xd5\x08\x15\xc8\x30\x76\x81\x9e\xbe\xac\xf1\x12\xfa\x5f\x31\x16\x64\x16\xdd\x66\x41\x6b\xa7\xc2\xcf\x69\xc5\xb2\xc4\x77\xc6\x13\x7e\xdc\x9c\x9a\xbc\xc4\xc6\xd3\xd3\x4e\x3e\xaa\x62\x99\x24\x68\x31\xf9\x3f\xa7\xe6\x02\x40\x54\x31\xa1\x29\x21\xa5\xaa\x52\xc1\x45\xa0\xbf\x0a\x39\xa7\xca\x7f\xfc\x81\xea\xd4\xe2\x06\x0b\xa3\xd1\x12\x5b\xf8\x67\x0a\xbb\x99\x3d\x29\x0f\x87\x4f\x5a\xef\xa6\x33\x5b\x71\xae\xd1\xb8\xf5\xe8\x31\x27\x2d\xbf\x0b\x2a\x04\xd3\x73\xe2\x20\xa5\xd2\x73\xef\x77\xdf\xe2\xf7\xab\x59\x20\x15\xc7\x19\x77\x09\x8b\x61\x79\xcd\xfe\x3b\xfe\x1f\x7f\x1c\x91\xa2\x64\xee\x5d\x48\x60\xe6\xce\x69\xca\x8f\x83\x42\x2a\x49\x45\x9a\x78\x6d\x0e\x85\xc7\x96\xb6\xb0\x8b\x26\xa6\x4a\x84\x05\xf5\x13\x29\x28\xd6\xb9\x53\x05\xf3\x9d\x93\x46\x31\xe1\xde\x64\x5e\xb7\x6f\x36\x80\xfd\x56\x63\xf3\x56\xf5\xc0\x41\x95\x26\x89\x95\x7d\x85\x93\x4d\x7f\x13\xe3\x76\x8b\xe5\x28\x62\xa2\xd2\x54\x13\x42\xaa\xf3\xd6\xc6\xd5\xd9\x2a\x05\xcb\x58\xe6\x6c\x4a\x57\xf2\x7b\x5e\x47\xaf\x52\x4c\x29\x54\x77\x93\xb7\x45\xfe\xd7\xa9\xaa\x37\x2d\x94\x1a\x6a\xfd\xcf\x28\x3a\x84\x12\x99\x0a\xfc\xaa\x0b\x3f\xbe\x40\x33\x22\xf2\x11\xaa\xfb\xbe\xc4\x30\x72\xa8\xca\xf6\xae\xc6\xf2\xef\x19\x18\x46\x09\x15\x93\xf0\x5f\x53\x54\x47\x9c\x01\x86\x95\xc0\xcc\xba\xb3\xd5\x04\x20\xaf\x64\x28\xb4\x57\x75\x58\x35\xaa\xae\x3e\xfa\xa0\x95\x92\xca\x12\x62\x78\x83\xb7\x73\xd1\xfb\x39\xaa\x54\xac\xc2\x21\x27\x68\x7d\xd0\xe7\xf2\x95\x14\xce\x9b\x89\x08\xfa\xec\x8b\xaa\x18\x49\x45\x5c\xe6\x7a\x5e\x76\x3c\x1d\x6f\x2a\xb3\x62\x36\x3d\x2b\xed\x2c\xa8\xad\x94\x8e\x04\xf8\x80\xab\xbd\xc4\x6e\x71\x79\x2b\x57\xca\x84\x99\x1a\xd9\x19\x84\x8e\x55\x55\x7d\x05\x2a\xa0\x34\x97\x14\x42\xd3\xa8\x72\x9d\x97\xfb\xb1\x8f\xad\x34\x24\xf4\x0a\x34\xa4\x5e\xbe\x79\x54\xbc\x42\x96\x90\x3f\x74\x80\x1f\xaf\x23\x4c\xbe\xc2\x28\x92\x4e\x5b\x89\xb4\x45\x56\xaf\xcb\x2c\x0c\x1e\x07\xce\xfe\xe9\xb3\x62\x6c\x05\x51\x35\xcd\x46\xe2\x82\xea\xaf\xa4\x99\x70\x01\xde\xa7\xca\x86\xe0\xa1\x97\x41\xed\x3b\xc6\xc4\x49\x30\x05\x8a\x0c\x49\x7e\x7f\x25\x23\xac\x35\xb4\x73\x10\x80\x57\x34\x3f\xa1\xba\x16\xca\x40\x16\x3a\xb8\xb8\xab\x47\xba\xa0\xda\x74\xe5\x54\x9d\x32\x39\x01\x7d\x4d\x97\x2e\x1d\x1a\x45\xcc\x84\xb7\x95\x6a\xab\xfa\x2c\xb2\xa6\x23\x60\xb1\x1c\x96\x65\xfa\x14\x83\x81\x71\xd1\xd9\xd4\x11\xea\xcc\xf6\xb9\xc9\x4b\xf4\xf8\xd3\x1b\x4a\x2a\x3c\x74\xcb\xba\xbf\x38\x67\x81\xaf\xe8\x5f\xab\x6a\x4a\x68\x3f\xf9\x2e\x9a\x43\x42\xbc\x3b\xb9\x53\x6f\x98\x15\xbe\x4f\xdf\x5a\xc7\xc2\x72\x76\x39\x0a\x1a\x92\xc6\xee\xcf\x99\xba\xe5\x3a\xd6\x56\xfe\x7d\x51\x1c\xdf\xc0\xd6\xe1\x8c\x64\x29\xbd\x49\xa4\x13\x26\x08\x98\xd4\xcd\x56\x2f\xc8\x6e\x93\x4b\xd3\x5b\x27\xcc\x62\x91\x1b\x6c\x9f\xeb\x3d\x94\x67\x02\x9d\x42\x27\x69\x4a\x44\x5d\x1f\x79\xa9\xab\x0f\x8b\xc5\xa7\x58\x05\x31\xce\x7a\x08\xae\x4e\x74\x42\xde\x13\x29\x81\x3a\x3c\xc4\xc2\x49\x7b\xcd\x6e\x9a\x06\x01\xd1\x73\x6f\xdf\xf0\x0b\x5d\x6e\x3b\xe2\x77\xba\xbe\xee\xe9\x34\x0e\x47\x4c\x76\x9b\x7c\x5f\x6e\x2b\xcb\x79\xbb\xd8\xd7\x88\x67\x22\xd2\x42\xa7\xa9\x95\xaa\x26\xc1\xb5\x66\x5b\xfd\x01\x79\xfb\x50\xf5\xb8\x17\x9d\x25\x2a\xee\x39\x5a\x5b\xc8\x8b\x79\x4c\x5a\x67\x92\xdb\xa2\x1d\xac\xeb\xaa\x9e\x44\x70\x74\xa6\x80\xaa\x2e\xba\xa1\xfd\x52\x5d\x89\x65\xe8\xcc\x88\xc4\x79\x41\xb6\x3e\x9b\x60\xb5\xcd\xd2\xf3\x38\x93\xd0\xbc\x7f\x20\x21\x83\xd8\x4a\x63\x9b\xbc\x28\xba\x43\x26\x47\xb2\x79\x06\x59\x14\xa1\x05\x6a\x2a\x7d\x71\x13\xb2\x33\x8b\xae\x38\x26\x1a\xb2\x58\x47\x33\xf9\xc0\xba\xcd\x55\x31\x0c\x6b\x89\x92\x34\x62\xcc\xa9\xd4\x77\x55\xed\x74\x3d\xfc\x51\x95\xa5\x1e\xbd\xf5\xb5\xc1\xfa\x11\x7e\xcc\xd1\xa2\xbe\xa1\x94\x46\x0c\xc9\xce\x87\x4a\x36\x6d\xbf\x7d\x68\xa5\x13\xca\x39\x37\x90\x6f\x4f\xd2\xff\xaa\x05\x86\xe1\x20\x11\x58\xe7\x23\x68\xe4\x45\x71\xe4\x99\xe9\xaf\x35\x5a\xb2\xda\x12\x4f\x75\xa5\xa1\xef\x47\x0c\xad\x1a\xf0\x06\x5b\x57\xac\x3d\xaf\xa1\x9b\xf5\x93\x61\x32\x70\x71\x3d\xe2\x07\x70\xac\x63\x0f\xd0\xb4\xee\x9f\xeb\x2b\xf9\x71\x64\x22\x93\x03\xaa\xd7\xdf\xe6\x34\x26\xe9\x98\xde\x0c\xc3\x24\x88\xb5\x47\xb8\xd1\xc2\x6b\xe3\x31\xdb\x8a\x26\x56\x35\x1b\x84\x18\x66\xc0\x9d\x90\xd9\x17\x38\xa0\x2d\x07\xf5\xdf\x0f\x43\x15\x90\x53\xe8\x04\x88\x88\x3b\x1d\xe7\xb5\x0b\xd7\x00\x7b\xb3\x1b\xe9\x8c\xaa\x0e\xde\xa0\xd4\x45\x67\x3e\x76\x5b\x06\x95\x20\x36\x44\xe0\x71\xa5\x07\x78\x00\xc6\x29\x02\xef\x71\x73\x3a\xcc\x1e\x9f\x87\x11\x79\x89\x5e\x18\xdc\x0c\x58\x2d\xe4\x69\x66\x1c\xf9\xc7\x17\x68\xee\xaa\xfa\xb6\x86\x8f\x01\x99\x86\x1c\x43\x1b\xc2\x26\x10\xf4\xe8\x11\xdc\xf1\x38\xb4\x15\xbc\x7b\x6c\x47\xb5\x30\xfd\xe0\xc6\x38\x0b\x49\xb7\xe8\xee\xd4\x9e\xea\xff\xe0\x95\xd1\x35\xc2\x59\x60\x12\xc5\xc2\xf1\x4f\xac\x55\x75\x41\x55\xbb\x6b\x02\xe4\xed\x2b\x72\x65\x1b\x1f\x55\x9d\x65\xe6\x30\x89\x53\x21\x47\x0c\x0f\x1e\x71\x73\x39\x2a\x6e\x35\xa7\xfc\xc8\xc6\x44\x5a\x1e\x36\x1f\x2a\x1a\x6a\x1e\x2e\x06\x1d\x31\x95\xb6\x23\x4d\x5d\xfd\x8d\xa4\x65\xd8\xcc\x93\x67\x98\x9a\x98\x78\x59\x9e\x97\xff\xb5\x78\x59\xfb\x2e\xca\x62\xe7\x66\x21\x1c\xa6\xe9\x41\xcc\x52\x4b\x04\xec\x49\x06\x87\xf2\x0e\xdf\x40\xa2\xb4\x9a\xf2\x04\x3b\xba\xe2\xbc\xa0\xe0\x16\x7c\x03\xfa\xfb\x60\xc1\xb3\xf8\x5f\xa3\x49\xe2\x80\x30\x09\xff\xd7\xf8\x3f\xfc\xf9\x49\x4a\x74\xec\x37\xab\x3f\xfd\x9d\x21\x54\x94\xb3\xab\x4a\x3b\xa0\x5e\xaa\xa2\xb8\x23\x4e\xe5\x51\xfa\x1c\x21\xe1\x3e\x04\xb5\xa1\x07\xea\x4f\x4f\x53\x5b\xd8\x5a\x83\x97\x1b\x9d\x6b\xc1\xcc\x06\x39\x40\x42\x50\xae\x53\x43\xac\x6b\x67\x40\x31\x94\x11\x8b\x2c\x9b\xca\x2b\x82\xfe\xdc\x56\x8f\x67\xf6\x0b\x4a\x6e\x08\x2f\xf6\xf8\xe7\xbf\x7b\xd2\x40\x81\x12\x33\x9a\x20\x45\xf5\x09\x45\xfb\x39\x16\x39\x11\xa8\xb4\xad\x58\x75\xf5\x6e\x14\xac\xbe\x39\xf9\x48\x06\xea\x40\x46\x9e\x41\xb8\x06\xd5\xb9\x50\x5f\x60\x5a\x5c\x88\x3a\x44\xaa\x23\xd9\xf5\x74\x06\xf5\xd8\xe3\xbb\xfc\xbe\x1a\x53\x4a\xae\x34\x4e\x00\x7d\x10\xca\xf7\x0d\x0c\x63\x7c\x14\xf3\xa2\x11\xea\x90\xdc\xbe\x0d\x66\x29\x31\x3c\xdd\xc2\xdf\xfd\x4f\x60\xf9\x70\x5b\x02\x09\x5c\x08\x17\x21\x6a\x13\xb8\x57\x7a\xd1\x86\xd0\xad\x67\xd8\x0f\x34\x3c\xa0\x92\xd8\xd2\xed\x6a\xf7\x08\x45\xfb\xf6\xe9\x8a\xaa\xf3\xaa\xb7\x5f\xd1\xa4\xb6\x8e\xc9\x03\x9b\x29\xc5\x52\x57\x87\xaa\xbd\x66\xbf\xa1\xc9\x42\x8a\x28\xc9\x53\x71\x46\xa3\x3c\x09\x45\xcd\x4e\x03\x26\xe3\xf1\x84\xef\xde\x70\x16\x78\xb5\x4d\x4d\xc0\x2c\xd8\x04\xb4\x3e\x83\x2f\xfb\x26\x11\x12\xad\xf5\xda\x8b\xdc\x61\xed\x24\x47\x85\x09\x94\x22\x54\xee\xb1\xc6\x5d\x33\x42\x82\x1a\x16\xea\xc0\x11\x4e\x8f\x01\x31\xfd\x51\xa4\x9c\x6c\x59\x7d\x87\xa9\x61\x69\x58\x66\xe5\x31\xac\x11\xfa\x98\x17\xd8\xb4\x55\x89\x83\xdb\xfd\x42\x0a\x45\x5e\x41\x54\x18\xa6\xc2\xc4\x3b\xc2\x58\xfb\x5e\x1a\xc7\xd5\x7f\x2a\x69\x23\x0c\xd3\x11\xd9\xdd\x9b\x0f\x98\xc1\xbf\x4c\xc8\x02\x4a\x1c\x58\x46\x05\x72\xb3\x17\x39\x51\x1e\x5f\x23\xed\x31\x61\xc8\xc1\x45\x59\xa8\xbf\xff\x5d\xc9\x59\x97\x87\xa9\x8e\xc7\x7c\x0d\x93\xe8\xd5\xe5\x47\x8c\x52\xc5\xbd\x82\xdf\x2e\x2f\x69\x87\x1f\xc9\x34\x08\x13\x89\x98\xc0\x29\x6d\xd5\x77\x24\x4f\xad\x39\xa5\xab\x7e\xc6\x74\xf6\xdb\x35\x35\x13\x61\x38\xea\x14\x86\x2a\xaf\x2d\xec\x67\xbd\xc1\x8d\x8e\xd3\xc1\x04\x7b\xa9\xab\x1f\x7e\xfa\x9b\x24\x32\x14\xd7\xee\x16\x6f\xd9\xff\x18\x07\xc6\xfb\xea\xa3\xd5\xd0\x24\x69\x20\x94\x43\x81\xff\xcc\xa7\x35\x09\x66\x54\x8d\xac\x6b\x20\xa9\x05\x9b\xc0\x1a\x7b\x5a\x26\x65\x16\x7b\x55\x40\x43\xca\x06\x7d\x04\xc1\x64\x31\x50\xaa\xc3\x0d\xfc\x59\x56\xea\xa7\x06\x88\xc9\x92\x80\xea\x49\x56\xe5\xbe\x86\xb1\xa6\xde\x74\x6a\x64\x99\xed\xb2\xe5\x1b\xc9\xcc\x0f\x6f\x98\x81\xd5\x46\xed\x9e\xea\x15\x5a\x87\x6c\x24\x42\x9a\xbb\xaa\xb6\xf0\x45\x95\xfb\x9d\xba\xdf\x6d\x8d\x60\x31\x4d\x78\xe8\x1c\x89\xbe\x4e\x7c\xfa\x6c\x82\x59\xba\x85\xde\x94\xee\x3f\xb9\x90\xf6\xa9\xc9\x71\xcc\xcb\xfd\x23\xf6\xd0\x48\x03\xdc\x4a\xf4\x12\xa8\xe5\xb5\x92\x7d\x4a\xc2\x80\x92\x24\x1b\xbc\x7e\xda\xae\x5e\xbf\x2d\x1e\xfc\xef\x32\x8d\x2d\xef\x9a\xcb\xd1\xd9\x20\xff\xe5\x0f\xa5\x02\x46\xcf\xf4\x05\xdb\x9b\x5c\x6f\xb0\xce\xe7\x8c\x23\x46\xe9\x40\x78\x44\x11\xf9\x63\xe7\x5e\xb8\x6b\xa9\x19\x07\xe6\xe5\x82\xb7\x75\xfe\x3d\x87\x62\x08\x92\x4d\x6f\xac\x75\x46\x59\x68\x0f\xa5\x7a\x58\x3f\xae\x3d\x20\xd3\x20\xe3\x44\x54\x78\x80\x1f\xd6\xeb\x7c\xa9\x9a\x26\x1f\xb2\x61\x06\x43\x9b\x7f\x75\x39\x43\x38\x1c\x21\x2f\xf7\x93\x7d\xcf\x74\xa6\x5d\x34\x82\x0e\x35\xdb\x8a\x2a\x57\xa6\xcf\x81\x59\x1c\x38\x07\xd6\x7f\x94\x59\x03\x8c\x69\x7f\x5c\xde\x6c\xec\xf8\xbd\x60\xf9\x5d\xb5\x8e\xa7\xbc\xbf\xc2\x98\xd4\x60\x70\x0e\x85\xed\xf9\xb0\x20\x08\x52\x4d\xb1\x35\xc7\x5e\xf6\x98\x97\x4e\xa7\xa5\x97\x94\xee\xda\x58\xa0\x35\x96\x56\x38\xef\x42\xdc\x1e\x82\x00\xb2\x70\x1c\x70\xb5\x15\xda\x73\x96\x3e\x08\x58\xa0\xc6\x2e\x14\x94\xef\x33\x5d\x21\xdf\x4e\x58\xbd\x0a\xe7\x43\xd8\x50\xfb\xb4\x37\x21\x08\x39\x44\x66\x08\x07\xad\x9f\x16\xa3\x39\x0f\x41\x04\xf6\xe5\xdc\x42\x34\xe4\xf2\xe6\xd7\xe1\x22\xa0\x78\xf6\x4b\x0d\xef\xd0\xbc\x4d\x2e\x12\x87\x81\x23\x18\x76\xc3\xf1\x1a\xbd\x30\x04\x31\x07\x4b\x1f\xdd\x9f\x2b\xac\x32\x9d\xc1\x56\xbd\x39\x8d\x2a\x8d\x3f\x6e\x3e\x37\x25\x1c\x9b\xb7\xaa\x9d\x54\xd7\xf9\x93\x40\xd3\x3c\xb3\xa3\xc8\x0a\x49\xfe\xd4\xf6\x81\x20\x46\xcb\x2c\x92\x97\x4d\x0b\x65\x9b\xff\x44\xe5\xd7\x9d\x91\x44\xda\x61\x90\xbb\xcf\xd4\xcd\x1a\xf4\x0f\x9d\x24\x01\xb7\x4c\xcd\x48\x71\xd3\xc9\x16\x39\xbd\x6f\xa2\xa4\xf7\x66\x76\x96\xdf\xbc\xbf\x88\x42\x1f\x19\xa3\x3a\x56\x17\xcd\x99\x7e\xe3\x2c\xb0\x38\xb6\xbc\xeb\x94\x67\x73\xc1\x14\x87\x40\x04\x5c\xdb\xb9\x99\x53\xad\xe0\x6e\x45\xd2\x89\xfd\xd3\x8a\x4c\x69\xab\x5f\xa5\xde\xd1\x2b\x1f\xfa\x83\x10\x47\x94\xf5\xb8\xc9\xd5\xa7\x2a\x70\x8c\x57\x86\x40\xf1\x54\x0d\xd0\x62\x37\x99\xed\xfc\x9a\x3e\xa6\x92\x76\xcf\xfa\xb6\x1c\x67\x43\xfd\x41\x15\x51\xb1\xc1\xe6\x71\xfd\xf0\xbc\x5b\x3e\x3f\x3e\x7e\x7d\x5a\x6f\xff\x9c\x40\xbe\x21\xc0\x18\x52\xcf\x75\x52\xbd\xf4\xf0\xeb\x6b\x64\x88\x10\x60\x16\x3b\xee\xd5\xdb\x1c\x0e\x55\xe9\x53\x58\xfe\x82\x86\x21\xa9\x73\xdb\x82\xdd\x11\xf5\xfe\xf4\x0b\xb1\x20\x05\x97\x0b\xb7\x72\x8c\x57\x98\xa2\xe7\x1c\xb3\xb3\xab\xb0\x50\x18\x46\x43\xc2\xd2\xbe\x59\x1b\x6e\x44\xad\x0a\x2c\x0c\x34\x21\xc6\x3a\xd3\xe3\x26\x6f\x57\x7f\x9d\xa0\xb8\x83\xbc\xa0\x01\xff\xfc\x7c\xd3\xb7\xe3\x29\x61\x11\x36\xf9\x69\x3c\xcd\x58\x98\x5a\xa1\xf6\x23\xb1\x5d\xc7\xb8\xf7\x7c\x79\xc0\xa2\x54\x90\xe5\xb6\x5c\xbd\xde\xec\x86\x72\x43\x60\x11\xd8\x9d\xbb\x85\x77\xec\xf9\x28\xed\xcf\x5d\xdf\xcd\xc1\xa1\xc0\x22\x44\x4a\xfe\x63\xad\xc2\x60\x72\x84\x67\x82\xc0\x23\xdf\x73\xec\xcb\x71\x3c\x05\xd4\xbd\x25\x48\x9a\x4e\x53\xc6\x0d\x23\xb0\x83\xd5\x2e\xea\x46\x9d\x4f\x21\x00\x8b\x63\x46\xf3\xa2\x07\x9b\x8c\xd8\x5c\xae\x6c\x67\xc0\xe2\x54\x9b\x81\x5a\xc8\x7f\xef\x5f\x04\x42\x66\x1f\x2a\x4e\x6d\x99\xc2\x9e\xb8\x46\x6f\xa0\xe9\xbf\x4f\x92\x66\x54\x62\xf9\xf0\xf5\x71\xe1\x7f\x4b\x03\xbb\xef\xed\x8c\x4d\x96\xef\x3a\x2f\xcb\x1f\x63\x09\x15\xe6\xcd\xe4\xdf\xbb\x51\xfb\x6f\x50\xef\xc7\xea\xda\x88\x4b\x43\x13\xa2\x2f\xe1\xfe\x28\x57\xe5\x3e\x2f\x71\xd6\x77\x69\x6c\x17\x4a\x1b\x61\x99\x94\xbc\xf5\xbb\x17\xb0\x2c\x49\xa9\xca\xb4\xa8\xaa\xf7\xd3\xf1\x9c\x41\x0e\x58\x06\x19\xa5\x03\xbe\x96\x4d\xe5\x3e\x75\x73\x73\xaa\x67\x71\x55\x60\x99\x8a\xa9\x40\x6e\xf3\xe8\x67\x24\x13\xa1\x4a\x9d\xd3\xf6\xc7\xc3\xe3\xd6\x90\xba\xfa\xec\x34\xc1\x2d\xe4\xcd\xea\xf6\x15\x55\xdb\x56\xc9\x7d\x75\xaa\xcf\xcb\xee\x2f\x7f\x51\x91\x70\x2a\x03\xfb\xf6\xfa\xef\xc9\x60\x13\xa0\x88\xcc\xc4\xa0\x7a\x5b\x14\xc5\xb7\xaa\x75\x31\xb2\x97\xda\xca\xe4\xdc\x7c\x5e\xd8\x18\x98\x90\xdc\x92\x85\x6b\x6d\x39\xcd\xaf\xdc\x55\x65\xe4\x87\xb9\x6a\xc0\x11\x5b\x24\x30\x81\x51\xdc\xaf\x43\x97\xe4\xb0\x81\x81\x94\x96\xb6\x87\xb4\x6e\x72\x2c\xdb\xe9\xda\x7d\x65\xe4\x81\xe1\x8a\xf7\x25\xcc\x13\x3e\xee\xd9\xf3\x49\x21\xc8\x14\xdb\xdc\x2c\x57\x57\xc6\x90\x94\x2c\x71\x36\xe0\xbf\x9b\xaa\xdc\x56\x2e\x3a\x78\x01\x7e\xd3\x35\x06\xca\x1c\xf9\x69\xbb\xe9\xad\x1b\x26\x35\x10\xee\xf9\xa1\xda\xbf\xe2\x6c\x24\x4f\xe3\x26\xd9\xfc\xa2\xc8\x53\xca\xce\x2e\x9f\x86\x40\xc2\xf4\x3d\x34\x0f\x0d\x1f\x95\x24\xf0\x71\xb4\x1d\x98\xce\x80\x84\x64\x7e\x44\x61\x14\x46\x3e\xbe\x7a\x21\x5b\x30\xeb\x1e\xad\x59\x12\x8e\x4a\xf0\xae\x74\x11\x32\x4e\x43\xbf\x79\xab\x3e\xee\x5e\x1e\xaa\x0f\xac\x8b\xbc\x7f\x71\x93\x42\x4f\xc8\x80\xcd\xe5\x38\x28\x30\xa3\x91\xbb\x4d\xfa\x11\x7e\x7c\xe4\x13\xa8\x14\x84\x81\x0e\x28\xf1\xdb\x6b\x89\x76\x96\xc0\x24\x60\xdc\x5f\x2a\x0c\x4c\x6a\x85\x19\x47\x83\xce\xd9\x3a\xa3\xdd\xba\x6b\x46\x85\xb6\x79\xb3\x26\x95\x8b\xb3\x1c\x21\x84\x2c\x82\x9e\x9f\xa6\xdb\x40\x3a\x67\x74\xc6\x1d\x06\x61\x94\x1a\xaa\x73\xbf\x0b\x6f\xfd\x4f\x9c\x65\x54\xca\x49\x15\x5a\x88\xfa\x1e\x9a\xb7\x45\x7f\xd0\x68\x4b\xbd\x66\xc1\x3c\x5f\xb0\x44\x5b\xda\x38\x7d\x8b\x38\x64\xe4\x8e\xc9\xce\xe8\x2c\xff\x37\x2f\xbe\x60\x09\xc7\xd1\x9a\x14\xc6\x61\x46\xdb\x14\x34\x9f\xa5\x3a\xab\x4c\x87\x30\x06\x24\xa9\xad\xed\x6a\xb3\xdd\xdd\x3f\x7f\xdd\xac\xfc\x23\x24\x22\xa2\xac\xd9\xfb\xa7\x1a\x53\xbf\xfd\xdc\xb2\x0b\x13\x6d\xa7\xd5\x97\x09\x78\x07\xc2\x6e\x5b\x1f\x4d\xf2\xce\x8e\xee\xcd\x9e\x30\x05\x1b\xac\xf1\x91\x83\x2f\xf9\x77\x84\x0f\x98\x99\x5f\x61\x0a\x59\x26\x87\x62\x48\x67\x1e\x13\x07\xa7\x5d\x19\x88\x8f\xc7\xba\xa4\x5e\x1c\x64\x02\x34\x1a\xd9\x0b\x93\x5c\xd2\x28\xf0\x05\xa1\xe0\x8a\x82\xcf\xd2\xf3\x7a\x8e\x22\x0b\xbe\x89\x4c\x2d\xb2\xdb\x12\x88\xf5\x6e\xdf\xf8\x32\x10\x64\x04\xd8\xde\x2e\xbe\xfe\xbe\x5a\xfc\xe9\x09\xcd\x20\x84\x24\x20\x74\x88\xa9\x6a\xcc\xf7\x25\x95\xec\x8f\x00\xef\x10\x82\x46\x42\x9c\xde\x56\x56\x19\x6e\x56\x49\xff\xdf\xe1\x10\x20\x4b\x9d\xcc\x67\x9f\xb7\x19\x8e\xcd\xbe\x0b\x60\x48\xa3\xed\x3d\x2f\x8a\x6d\x5e\x78\x8e\x9b\x51\x64\x1e\x42\x69\xb4\x71\xeb\x75\xf8\xff\x6b\x3b\x0f\x95\x0c\xb9\xc5\xc1\x36\x6d\xd1\xf9\x40\x0b\xfd\xbf\x27\x27\x6b\xe3\x9a\x20\x13\x94\xba\x7d\xda\xbe\xfe\xb9\x18\x99\x1b\x03\xf5\x0c\x84\x18\x5a\x99\x58\x57\x4e\x78\xea\xb6\xef\xaa\x98\x8d\x7d\xe4\x89\xd5\xc6\xee\xeb\x07\x86\x8a\x49\x08\x4d\x62\x93\xea\xa4\xb5\x5b\xe0\x94\x7d\xc6\xb6\x89\x02\xce\x2d\x1f\x1a\x85\x9d\xfe\x31\xbd\x06\x44\x41\xa2\x28\x51\xea\x6d\xfc\x89\x9d\x1e\x31\x63\x85\xd0\x6a\xb4\x5c\x68\x15\xd4\xda\xe9\xb2\xcc\xcd\xe6\x28\x8c\x24\x65\x1a\xe7\xab\xd4\xd5\x2c\x2d\x44\xa1\xc8\x7c\x11\xe5\x1d\xe2\xbc\x16\x79\xfa\x86\x11\xb3\x81\x6f\x2f\xc9\xe7\x91\xef\x33\xc2\x6d\x88\xa2\xc8\x16\x70\x1e\xe0\xc7\xae\x99\xbc\x4d\x64\x62\xc2\x32\xee\xb1\x25\xde\xe7\xc9\x2e\xe4\xdd\xb3\x88\x07\x48\xc3\xeb\xe6\xf7\xf1\xac\x8f\x38\x53\x99\xc7\xe0\xaf\xea\xba\xaa\x5f\xab\xaa\x75\x2c\x66\xed\xa7\xad\xa5\xfb\x5a\x56\x1f\x25\x6a\xaf\xe1\xea\xcf\x8c\x04\x91\xfd\x1c\x5d\xb6\x7e\x09\x47\xd2\xf7\x1c\x1a\x70\x9e\x5a\x85\x8b\xf6\x16\xf1\x4c\x0b\xea\x62\xa9\xef\x3c\x08\x10\x71\xa1\x68\xb5\x6a\x2c\x4d\xb3\xb4\x55\x89\x6d\x0b\x26\xff\x49\x61\x04\x44\x5c\x4a\xbb\x7b\xd0\x1b\xf8\x6f\x30\xc7\x78\x42\x14\xc7\x10\x4f\xa8\xc8\xba\xcf\x30\x8b\x30\x44\xb1\xd0\x5e\xbe\x67\xa5\x4f\x76\x95\x5d\xe6\x6d\xfe\xf7\x9c\x38\x01\xa2\x58\x5a\xe4\x6e\x4e\xa6\xc3\x15\x76\x0d\x88\x62\x63\x0d\xd1\xce\x24\x72\xd5\x85\xee\x48\xa2\x22\x6d\x55\x35\xe1\x70\x29\x5c\x33\x7d\xb2\x04\xad\xbc\x54\xb7\x67\x6f\x0e\x50\x14\x63\x69\x1f\x88\x12\x13\x83\xc5\x1c\xca\xd3\x7e\xf6\xa4\x19\xc8\x50\x8d\xc8\x9a\x4e\x75\x33\xe1\xf3\x86\x48\x04\xb6\x2c\x47\x9e\x3e\x5f\xb0\xde\xa0\xd3\xad\x61\xc9\xd4\xf3\x8f\x04\x57\x64\xd8\x63\x0d\x0d\x5a\xc3\xd9\x49\x81\x8c\x61\x34\x10\x09\x94\xb6\xfc\xbe\xa8\x24\x14\x8e\xaa\x78\xbc\xb0\x46\x90\xd9\x10\x36\x39\xf8\x3b\xcb\xf3\xd1\x9f\x0e\x60\xb7\x52\x2c\x75\xaf\x3e\x3d\x5a\x50\x22\x19\x30\x0a\xf3\xf5\xf9\xc2\xf2\x06\xdf\xa0\x30\x3f\xdf\x0f\x23\x09\x4a\x5b\x26\x7b\xf5\x7e\x3a\xee\x3a\x87\x4a\x57\x1f\xfd\x04\x91\x2a\x24\xdb\x37\xb7\xd1\x7f\x97\xa2\xb8\xb4\xe6\xa8\x28\xa1\xdc\xe2\x6d\x55\x14\xf7\x90\xf7\x5f\x54\x71\x4e\x60\x8f\x5e\x34\xad\xea\x0f\xe9\x24\x14\xc1\xb8\x0c\xce\xaf\x71\x75\x9f\xbe\x9e\x3e\xac\x4e\x95\xb6\x22\xd1\xc5\x95\xea\x1d\x88\xb4\x0c\xc8\x35\xd9\x1d\xc8\xc8\x1a\x38\xb7\x21\xc2\x28\xa5\x42\xf6\x8d\xcb\x68\x59\xf8\x4c\x5e\xee\x6d\x00\x72\x3f\x0b\x45\x44\xc8\x39\x21\x0a\xa1\xe9\x0c\xba\xea\x3b\xae\x4b\x53\xd5\x87\x8b\x66\x86\x3f\x45\x08\x2a\x7f\xbe\xcf\xf7\x6f\x4b\xda\x64\x26\xeb\x8d\x49\x2c\xbb\x7d\x3b\xca\x96\x2c\x4a\xed\xa0\x3e\xd4\xf4\xee\x54\xaa\xc9\x0d\x4e\x17\xb0\x71\x10\x99\xce\x68\xfb\x3f\xff\xcf\xff\xf9\xeb\x84\xf5\xe7\xf2\x2d\x97\x53\xd6\x70\xe0\x41\x92\xe9\x31\xaf\xf2\x6f\xfe\x77\x69\x13\x44\xe0\x2b\xea\xbe\x1e\xf7\x83\x60\x00\xf0\x40\x59\x03\xe9\xcf\xea\xa4\xb1\xb7\xfc\x79\x98\x58\x0d\x0d\x8b\x0c\x58\x39\x09\xa0\x9b\xd3\xe7\x64\xd7\xf8\x07\x05\x86\xc0\x43\x47\x09\xe7\x8a\x69\x68\xd5\x1e\x92\x7c\x7e\x5e\xf1\x10\xa5\x47\x5b\x5d\xf4\x53\x78\x14\x85\xe4\x52\x38\x14\xa9\xab\x4e\x9d\xac\xaf\xbe\xa5\x51\x54\x94\x59\x63\x7b\xaa\xcb\x5d\x8d\xff\x4b\x84\x70\xbb\xa3\x0d\xcd\xce\x7a\x8e\x0b\x45\x4b\xc3\xb7\x6e\x53\xaa\x5e\xa1\xdb\x99\xc6\x5f\x91\x73\x40\xe1\xb0\x22\x8b\xaf\x8f\xb3\xb3\xe3\xd0\xca\x3e\x97\xf8\xf1\x65\x54\x5d\xff\x73\xc3\x84\xc7\x71\x4c\x4f\x68\xba\x8f\x52\x8f\x23\x7c\xbe\x41\x9a\x22\xf4\xaf\x30\xb8\x0f\x63\x02\xd0\xe9\x25\x93\xd0\x58\xb7\xd5\xa3\x81\x9f\xf0\xe3\x5c\x42\x1d\x78\xc2\x13\x67\x2c\x16\x15\x68\x62\xa5\xfa\xa9\x67\xca\x93\x24\x20\x04\xac\xaf\x9e\x5e\x3f\x7d\x5b\x6d\xb6\x8f\xab\x3e\x3a\xc7\x93\x0c\x2d\xa9\xc1\x4d\x35\x40\x48\x81\x27\x42\x31\x57\xf6\x6a\xd3\xb4\x45\x9f\x66\xbc\x10\x95\x77\xc9\x7f\xe0\x89\x34\xe4\xdd\x5b\x07\xc6\x01\xf5\xdd\xb1\x54\x59\xe7\x66\x73\x2a\x5f\x6c\xcf\x8d\xb9\x5a\xa7\xcf\x9d\x09\xce\x7a\x20\xd6\xc0\x9e\x74\x47\x25\x5f\xbe\x0d\xa8\x20\xea\x01\xc7\xdd\xa2\xd4\x1f\x12\x10\x11\x64\xd3\x1a\x7d\xdb\xfa\xd4\xb4\x1b\xf5\xeb\xde\x82\x2c\x65\x44\xed\x55\xe5\xa5\x74\x73\xdc\x5f\x12\x04\x90\x55\xf2\xe3\xad\x69\x27\xbf\x1b\xcb\x29\x3c\x30\x16\x4e\x07\x83\x0c\x32\xaf\x08\x40\x5f\x74\x28\x97\x07\x2e\xd1\xd2\x2a\xe4\x65\x67\x42\xe5\xdf\xf1\x8c\x74\x1b\xb8\xca\x18\xed\x9b\x9b\xd5\xe2\x76\x0a\x3a\xbe\xfc\x0e\xca\xd5\xc2\x83\xd6\xdf\x8e\xe6\x57\x43\xfa\xec\xef\x6c\xfe\xeb\xd8\xc2\xe6\xd4\x58\x53\x06\xb8\x96\x9c\x3c\xbd\x7e\x61\xba\x39\x7d\xde\x8c\x3e\x35\x46\x41\x18\x8f\x84\x6f\x2e\x2f\x0a\xc8\x13\xaa\x9f\x3f\xd6\xb8\x2f\xa1\x6c\x5f\xaa\x32\xc7\x26\xc7\xfe\x33\x62\x0a\x64\x96\xfb\x7d\x94\x68\xfb\x28\x80\xdc\xb7\x00\xee\x29\xfa\xbf\x96\x1a\xeb\x6e\x79\x3c\x79\x28\xc7\x34\xe4\xc0\x92\xf3\x3c\xd2\xb5\xff\x77\xce\xcc\x14\xda\x02\xdc\x48\x96\xb8\xec\xef\x28\xa2\x39\x7d\x29\x23\x7b\x9a\xc2\x5e\xd4\xfc\xe3\x6a\x35\x17\x70\x83\x19\xe5\x7a\x0e\xd6\xaa\x1f\x63\x00\x20\x0e\x62\xc9\x1d\xf9\xc4\xe2\xd4\x76\xbd\x3c\xb2\x0b\xa7\x17\x8a\x19\xe7\xa4\x2a\x85\x4d\xeb\x8d\xc3\x6b\xa8\x7f\x88\x99\x30\x64\x30\x0d\x45\xef\xab\xb2\xc5\xfa\x58\xe7\x7d\xd4\x34\x66\x3a\x30\x7d\x90\x97\xc8\x63\xd7\xe5\x84\x46\x13\x62\x86\x19\x31\x94\xec\xda\xfc\x30\xb1\x8f\xe2\x50\x30\x02\x47\xfe\x9e\x97\xfb\x53\x5e\xfe\x5e\x57\x1f\xbd\x79\x15\x47\x51\x42\xb8\xf5\x2f\x35\x94\x73\xc6\x91\xcb\xc3\x3a\x8e\x32\x4b\xb9\x65\xc9\x7e\x5f\x88\x2c\xac\xe8\x56\xca\xda\xa3\x1c\x20\x8e\x54\x44\xe0\x91\xde\x20\x6d\xee\xab\x42\x63\xfd\x38\xae\xd2\xbe\x68\x0b\xc4\x91\x09\x29\xcd\x57\x56\xe4\x5a\xf8\x2b\xf2\x18\xd0\x25\xe2\x6c\x2c\xd7\x49\x56\x0e\x00\x4f\x88\x79\x2a\x1c\x9f\x4b\xa9\x5d\xe1\xd5\xa2\xd4\xc3\x33\xf4\xed\x74\xe2\x78\xfe\x54\x55\x6b\xab\x43\x36\xdb\x6e\xe3\x58\x06\x84\x6c\xdc\x14\x98\x1f\xcb\xbc\xfe\x18\x65\x59\x21\x8e\x75\x44\xc6\x7d\xde\x8c\x08\xc5\x20\x4e\x62\x46\xe1\xfb\xd5\xe3\x7a\xb3\x59\x3f\x3f\xed\xee\x9e\x5f\x77\x2f\xaf\xab\xcd\xe2\x61\xd5\xb7\x91\xa1\x47\x1e\x59\x92\xd2\x3f\xa0\x5e\x77\x5f\xdc\xc0\x0c\xee\x02\x71\xa2\x80\x72\x60\x05\x34\xe3\xb2\x02\x88\x13\xa7\x23\x51\xc0\xfe\x16\x4d\x5d\x35\xc3\x23\x60\x46\xb8\xfa\x9d\x35\xd1\xad\x50\xef\x6d\x09\x13\x2b\x3d\x4e\x4c\x64\x25\x91\x4f\x75\x49\x89\xb5\x8b\xe6\x52\x9c\x18\x24\x47\x93\x40\xdd\x3e\xf7\x79\xf9\xb3\xa5\x81\x7d\xad\xf5\xed\xef\xfe\x51\xb2\xd8\xb2\x7c\xde\x54\xfb\x63\x5e\x8c\x09\x1f\x20\x16\xcc\x82\x99\x6d\x7e\xb6\xb3\xc8\x1d\x0b\xa4\x3f\x1e\x29\x4b\xed\x5f\xe3\x2e\x57\x97\x55\xd9\x20\x16\x28\x89\x6c\xc0\xa9\xf2\x38\xd5\xd9\xb1\x3d\x14\x43\x92\x51\x78\xb4\xce\xd5\x1b\xed\x16\x57\x49\xe7\x20\x96\x68\x95\xa3\x7a\xba\x81\x5b\x24\x38\xfd\xe0\x9f\xc6\x8a\x09\xe5\x52\xd9\x7f\x20\xbe\x3f\x55\xfd\x01\x11\x58\x6d\xdb\x43\x5e\xb6\x33\x6f\x7a\xfa\xc7\x9f\xa0\x80\x7a\x67\xae\x5d\x74\x47\x48\xc4\xf3\x72\x64\x88\x95\x89\xe9\xa3\xfd\x75\x82\xba\xc5\x3a\xf2\xb7\xd6\x19\xa3\x4f\x6e\x08\xc7\x37\xad\x65\x87\x58\x6b\x4d\x70\x4a\x3c\x60\xbd\xc7\x52\x7d\x2e\x4a\x7d\x9f\x6b\x8d\x25\xd1\xb2\xed\xf7\x7d\x80\x26\xd6\xda\x96\xf2\xf6\x4d\x9d\xb0\xdc\x6c\x70\xf4\x73\xc4\xc8\xc8\xaa\xa8\xd8\xe8\xdf\x1d\xe2\x59\x08\x22\x09\x78\x60\xf5\x28\x6d\x4d\xc3\x88\xf4\x7a\x66\x79\x25\x41\x16\xe9\x21\x25\x4f\xbb\x4c\xb7\xc0\x8c\x2a\xf8\x20\x09\x04\xb3\x60\xa4\x6e\x21\xfc\x5a\xe6\x7f\x9d\x70\xa2\x8d\x0e\x09\x8b\x33\x93\x7a\x16\xc3\x0d\xb6\x6d\x41\x20\x30\x57\x0c\xde\xb7\x82\x90\x94\x03\x9f\xf0\xe3\xf7\xea\x02\x65\xeb\x3f\xc4\xff\x4e\x87\x63\xc2\x64\x98\xe8\x5e\x76\x67\xf9\x4c\x55\x3a\xdb\x8f\xaa\xbf\xab\x94\x64\x01\x5b\x39\xa0\x76\x1c\x43\x22\x81\xe7\x29\x5a\x7b\xde\xdd\x09\xd3\x16\xbb\x69\x97\x8d\xb1\xd8\x00\x24\x61\x22\x6d\x45\x9f\x31\xb4\x30\x7a\x32\xe8\xe9\x03\x86\x19\xf3\x58\x1c\xcb\x73\x54\x9a\xaa\xef\x93\x10\x45\x5f\xa7\xb1\x2f\xab\x1a\x7b\x04\x77\x33\x2e\x06\xa9\xaa\xa2\x7f\xa2\xd0\x68\x22\x50\x7c\xfa\xb6\xbd\x5a\x0b\x3a\x7d\x82\x38\xc8\x14\xf6\xa1\x93\x65\x55\x15\xe4\x37\xcf\x1a\x45\x4a\x58\xba\xa8\xf6\x8b\xad\xcf\x9f\x37\xe0\x40\x60\xb1\xc2\x8a\x64\xba\x19\xe4\x31\x37\x43\x0e\x36\x89\x75\x46\xce\xce\xa9\x21\xd1\x84\x76\x16\x49\x4b\x92\x50\xd2\xde\xb8\x79\x7e\x58\xfb\x10\x7e\x92\xc4\x31\xd1\xec\x7e\xff\x95\xe8\x36\x24\x69\x60\x51\xa6\xb7\xf8\xe3\x57\xf0\xbd\x6b\x57\xe0\xb1\xd3\x93\xb1\xd3\x76\xac\x26\x08\x49\xaa\x62\xee\x92\x3b\x1b\xf5\x86\x07\x20\x2a\x96\xbc\xfd\x3c\x27\xb3\x82\x24\x35\x96\xd0\xb8\x73\xd0\xaa\x93\xdb\x5d\xae\x71\xd1\xf6\xe7\x70\xcf\x95\x6e\x07\x54\x73\x09\x78\x09\x49\xc6\x0d\x71\xca\xac\xda\xb7\xc7\xa6\xc7\x57\x24\x99\xb0\x68\x57\x5b\x29\x32\x62\x90\x87\x24\x03\x8c\xc6\xd1\xff\x17\x28\x40\xe7\xe5\x19\x20\xdb\x35\x17\x21\xf3\x62\xc7\xb6\x7a\xc0\xef\x0b\xb3\x4f\x2f\x44\x40\x1e\x3c\x91\xb3\x64\xa3\x12\x3e\x48\x84\xb1\xf6\x1e\xa9\x25\xb4\xa7\x02\xf2\x1a\x77\xcb\xea\x70\x6c\x71\xc7\x7c\x23\x88\x62\xab\xea\x54\x20\xd4\x17\x31\x3f\x09\x64\x32\x71\x8f\xf2\x58\x95\xed\xdb\xaf\xb8\x77\x21\x91\xcc\xd2\x14\xec\xb1\xbd\xb9\x42\x2b\x03\x89\x4c\x32\x0a\x6d\x7a\x68\x12\xf1\xda\xcd\x8d\xd6\x44\x0a\x89\xbe\x2c\xe1\x63\x5b\x79\xe3\xb6\xdb\xa4\x27\x2a\xbd\x90\x48\x95\xc5\xe0\x79\x02\x5a\xac\x29\xeb\x38\x7b\x15\x15\x84\x94\x88\x6f\xc0\xe0\x60\x27\x47\x67\xad\x64\x98\x8c\x00\xb8\xae\x9c\xa2\xe9\x6c\xab\x0b\x61\x0a\x77\x96\x0e\x35\x71\x97\x3d\x2e\xb6\xcf\x5f\xfd\x43\xe9\x48\x90\x35\xfb\x80\xf0\xde\xff\x26\x05\x05\x90\x2c\xe4\xf5\xcc\x0a\x77\xad\x30\x00\xcb\x16\x92\x3b\x9d\x93\x6b\xb0\xbb\xd9\x63\x20\x06\xa4\x63\xbc\x73\xe8\xab\xee\x35\x27\x6b\x63\x1a\x88\x94\xd6\x1c\x2a\x4d\x1c\x7a\xa1\xd9\xd7\xd5\x3c\xb4\x9e\xb2\x2c\xa0\x0e\x6b\x11\x0e\x4e\x92\xec\xd8\xef\x69\xbb\x03\xfc\xf0\x17\x0d\x11\x68\xde\xd2\x82\x3b\xdb\xca\xd2\x28\x4b\x28\x40\xde\x7c\x20\x5e\xae\x3c\x80\x34\x12\x19\xa6\xbd\x7c\x31\x65\x3a\x5e\xd1\xac\x4b\x55\x1d\x2e\x33\xca\x43\xca\x25\xa7\xba\x45\xd4\x79\xbb\x38\xe6\x57\x77\xad\xb1\xa9\x97\x72\x44\x92\x09\xb2\x03\xea\x02\xde\xd8\xb7\x33\xb6\x12\xcd\xcf\xd7\x39\x49\x21\xa4\x71\x96\x84\xb1\xa7\xfd\xaf\xef\xd8\xba\x6c\xef\xc2\xee\x5f\xe1\xd7\xbc\xfb\xa7\xdf\xbf\xce\x73\x1d\x43\xcf\xc4\xc6\x2e\x77\x9d\x1b\x55\xcb\xbc\xc5\xfa\x1a\xfd\x0a\xa4\x89\xd0\x91\xa3\x21\xc8\xcb\xfd\x16\xea\x7d\x6f\x80\xa7\x09\x24\x54\xd7\xfd\x31\x48\x84\xfb\xc4\xbb\x67\x49\xf3\x2d\xb5\x20\xfb\x47\x9e\x3e\xb7\xa4\x79\xf0\xdb\x25\xa3\xec\x27\x96\x5a\x9a\xc6\x40\xa4\x7f\xaf\x79\xf3\x4e\x0b\x8e\xfd\xdc\x2c\xcc\xfc\x46\x98\xa6\x12\xac\xc6\x74\x75\x38\x42\xf9\x39\xaa\x79\x87\x34\x93\xa9\x91\x33\x34\xb4\x47\x85\xaf\x28\x08\x37\x00\xaa\xd2\xcc\xc4\x38\x18\x41\x8e\x97\x6e\x5a\xf0\x32\x97\x99\x84\x14\x52\xa4\xf0\xcb\x6a\x7b\xbf\x7b\x59\xbd\xee\x1e\x16\xaf\xde\xdd\x48\x21\x33\x64\xc2\xdf\xff\xfb\xce\xff\xa4\xc2\x40\xa7\xbe\x8e\xca\x16\x21\x10\x0f\xf4\xf4\xa2\x2a\x04\x87\x68\xfb\x74\xc2\x9c\x97\x69\x1e\xfa\xe6\x92\x1e\xfc\x08\x9f\xdd\xfe\xfb\x53\x2b\x20\x55\xa1\x26\x43\xe9\x0d\x1a\x62\x7c\x3b\x1e\x0b\x2f\x41\x56\x57\x87\x4d\x75\xaa\xd5\xb5\x39\xa0\x92\x48\xc5\x23\x82\xa5\x9e\x72\xd6\x1f\x57\x56\xd9\xef\x15\x0f\x70\x5c\x1f\x8e\x55\x3d\x44\x70\x52\xcd\x42\x6e\xe5\xbc\x9b\xb6\xae\x3e\x27\x41\x1c\xd7\x04\xa3\x80\x0c\x29\x3b\xf7\x9b\x61\xc4\x61\x6c\x15\x4b\x40\x6b\xc2\xcb\xf5\x34\x97\xd9\xe5\x85\x29\x45\x1d\xd0\x6c\x7d\x5c\xfc\x67\x77\xb3\xbe\xdd\xdd\xbd\x2e\x96\xbb\xed\xf3\x4b\x7f\x41\x13\x11\x55\xd4\x2f\x98\xac\x36\x70\x20\x62\xca\xb5\xf6\x7b\x58\x6a\x18\xa3\x6f\xfa\x8a\x6d\x9d\xa3\xaf\x64\xf4\x07\x33\x0b\x97\x38\xd6\xb8\xc4\xb2\xa9\xea\x11\x6e\x20\x0b\x32\x20\x54\xcd\x9f\x50\xc3\x5f\xbf\xf9\x1f\x45\x40\x3c\x23\xdd\xdb\x76\x33\x79\x1e\xa9\xf2\xcd\xb4\xa0\xaa\xa6\xbc\x71\xa5\x43\x63\x4b\x25\x0b\xb4\x21\x8f\x3f\x6f\xee\xf2\xba\x69\x6f\x40\xef\x71\x35\xd3\x5c\x80\x8c\xf1\x44\x3b\x0c\x2f\xe1\x9f\x5f\x6a\x5c\x2f\x9f\x7f\xeb\x8f\x2a\x1b\x22\xfd\x9c\x55\xcd\x40\x16\xa6\x28\x85\x97\x89\x55\x95\xd5\x7b\x99\x8c\x8c\x2c\x84\x80\x16\xb0\xc7\xf5\x66\xeb\x15\x6b\x20\x8b\x34\x27\xaa\xae\xce\xd3\x7d\xfc\x6c\xdf\x3a\xdf\xef\x6a\x15\x36\x64\x89\x13\xe6\xfd\xdf\x53\xfd\xf9\x5c\x16\x79\x89\x63\x78\x35\x64\x49\x1a\x52\x2e\xe5\x76\xfd\xe4\xc8\xbb\x66\x36\x76\x96\x32\x65\x59\xd0\xeb\xaa\x81\xbc\xfe\x56\x9d\xd4\x1b\xd6\xcd\x98\x80\x03\xb2\x94\x07\xd9\xc0\x16\xd8\x6d\xdf\x63\xef\x7f\x3a\xe4\xb3\x34\x4b\xa3\xa1\xc6\xe4\x4c\xe2\xcf\xdb\xe6\xd1\xe5\x4a\x6d\xc8\x52\xb0\x7d\x47\x0a\x6d\x17\xeb\xaf\x67\x9d\x90\xca\x98\xe6\x98\x86\xbc\xf8\x24\x8c\xd7\xb0\x69\xfb\x26\x3a\xa3\xc0\xfa\x1b\x34\x0f\xb9\xc2\xb2\xc1\x2d\xd6\x87\x99\xf3\x9d\x65\xcc\x46\x40\xf3\xc6\xc9\xac\xcc\x0e\x2b\x2b\x2d\x00\x5a\x7f\xc3\xc6\x95\x00\xc8\xeb\xfc\x4e\xb3\xc7\xcc\x14\x37\x38\x64\xe4\x9d\x47\xa3\xf1\xc7\xaf\x80\xca\x99\x08\x12\x52\x49\x29\xaa\xbd\x2f\xcb\xfd\x96\xc3\x5d\x0e\xe7\xb2\x45\xd3\x27\x16\xa1\x65\xc8\xf3\x1e\x5c\xb7\x79\x8d\x8c\x6c\xdf\x4a\x46\x5e\x63\x6f\xa7\xaa\xc3\x01\x4a\xed\x0b\xbc\xa6\x0d\x21\xb0\x91\xec\x9d\x0c\x7f\xbb\x94\xaa\xcd\x24\xb7\xec\x4d\x8f\xa8\x73\xb8\xa9\x2b\xd0\x0a\xfa\x58\x4f\x26\x63\x26\x33\xaf\x95\xaf\xbf\xc0\xb5\x41\x2d\x53\x4d\xb5\x63\xcb\xc5\xb6\x3f\x35\x45\x92\xc8\xe8\xf7\xcf\x9d\x05\x41\xf6\x23\x54\x0a\x9b\x08\x5b\x6d\xef\x87\x93\xa4\xa6\x15\x6d\xfb\x06\xe5\x5b\xf9\x7d\x1c\xd0\xc9\xa4\xc9\x28\x47\x47\x64\x45\xde\xcc\xb8\xac\x01\x37\xad\x46\x86\x4c\xc5\x56\xf6\xc0\x3e\xc1\xb6\x86\x91\x69\x9d\xa9\x4c\x51\x49\xbe\x2d\xa0\x1f\x50\xb7\x99\xd2\x69\xe6\xa3\xbb\xa7\xba\xac\xbe\x77\xb7\xbb\xd2\x01\x18\x06\x61\x36\x29\x40\xe8\x9e\x50\xbd\xcd\x97\x27\x8c\x04\x65\x83\x77\xa7\xb2\xb3\x98\x57\xa5\xaa\xb4\x4d\x45\xae\xf5\x6f\x93\xb0\xbc\x3f\x21\x0e\x3d\xef\xec\xee\x58\x7d\xcc\x41\x00\x19\xc6\x60\x55\x9f\xde\x60\x59\x1d\x0e\xf9\x7c\x00\xa0\xc6\xcc\x4d\xa3\x5f\x2a\x29\x41\x66\x98\xf1\x06\x98\xf3\x5c\x36\x2e\xac\x62\x03\xbe\xf3\xb1\x3b\xb6\x03\x33\x13\xcb\xd4\x31\xd2\xfe\xe7\x65\xe1\x74\xd7\xed\x31\x11\xc4\x9c\x0a\xfe\xed\x0a\xb3\x3e\x9e\xf5\xe3\xbf\x7e\x02\x9b\x10\x61\xa2\x29\x86\x7c\x00\xbb\xb6\x8e\xd9\xbc\x41\x44\x11\x7a\xb5\x98\xcd\xc1\x2b\x4b\x74\x8e\xee\x79\x52\x4d\x44\xda\x52\xd9\x12\x33\xad\xb5\xd4\xf1\x63\x50\xb0\x18\x37\x94\x7a\xe0\x48\x9b\xc0\xa4\xa7\x5f\x40\xf0\x24\xa2\x2f\x44\x1c\xfb\xd7\x4a\x59\x86\x0b\xc7\x71\x46\xd4\x39\xb9\xaf\x1e\x24\x6b\x92\x04\x56\x2f\x07\xfb\x45\x9c\x8a\x70\x00\xee\xf4\x28\x98\xd9\x63\xc4\xa9\x95\x41\x57\xca\x95\xae\x8f\xf8\x4e\x40\xc4\x60\x09\xc1\x8e\x39\x0e\x3f\x59\xd9\x81\x27\xfc\x78\xa9\x5a\x2c\xdb\xdc\x95\x8a\x5e\xde\x24\x44\x6c\x2c\x52\xbf\xc1\xf6\xfe\xfe\xf5\x22\x6e\x48\x24\x18\x52\xba\x74\xb9\xdd\x8e\x45\xda\x41\xa4\x11\x52\x90\x4e\x56\x75\x5d\x5d\xec\xf0\x54\x3b\xc2\x75\x22\x0e\xc6\x16\x34\xb4\x30\x27\xc0\xbf\xe4\x7f\x88\x2c\xb2\x09\xd5\xdf\x4f\x45\x75\x1a\x4d\x60\x91\x81\x70\x34\xef\x65\xd0\x75\xf0\x72\x3c\x6a\x32\x25\xc9\x50\xe8\x0e\x4c\x0c\x0d\x91\x69\x54\xce\x83\x58\xd9\x52\xd8\xa6\x7d\x36\x2b\x50\x6f\x17\xcc\x39\x21\xc2\x80\x62\x66\x2e\xa4\xd9\x27\x8b\xfc\xd5\x04\x00\xe5\x0c\x77\x8d\xa5\x3c\x98\x79\xa5\x42\xa0\xa0\x9e\xf1\xa5\xdc\x9a\x62\x7a\xcd\xfc\x2e\x46\x65\x69\xef\x61\xbe\x75\x0b\x55\x4f\xe6\xba\x1c\x34\x9e\x9e\x2f\x6b\xa9\x82\x90\xa1\x24\x66\xe3\x9d\xc9\x8b\x62\x09\xb5\xde\x58\x86\xaa\xa9\x79\x79\x89\xda\xc1\x5f\x20\x8a\xa1\xe7\xfc\x72\x20\x99\xa1\x74\x4a\x48\x1e\x24\x16\xb0\xd4\xf7\xbe\xcc\x02\x72\x8b\x96\x6f\x50\xef\xbb\xcf\x32\x8b\x1b\x0b\x09\xb6\x12\x62\x24\x14\xfb\x2b\xbc\xf9\xcf\x71\xe8\x42\xca\x20\x04\x0f\xde\x23\x60\xae\xa9\xae\x4c\x2a\xc5\x45\x2a\xfd\xfb\xdc\x9c\xca\x32\xc7\xc6\xda\xc7\xfd\x38\x50\x49\x94\xf8\x84\xdc\x5f\xa7\xdc\x74\x7b\x7f\xd3\xe6\xed\xa9\x25\x2d\xa8\x85\x9e\xaf\x04\x4a\x46\xb4\x97\xbe\x9d\x4a\x5d\xa3\x9e\x94\x5c\x77\x47\x21\xf2\xe4\xf2\x35\xa1\xe0\x77\x95\xd9\xed\x7d\xa1\x59\xe6\x9b\x99\xd0\x55\xab\x53\x1a\x4e\xe6\x7d\x98\x41\x68\x66\x28\x94\x76\xb2\x61\x69\xe7\x68\xfa\x8c\xa5\xd0\x51\x16\x09\xcf\xee\x75\x2a\xfb\x7a\xf5\xe9\x43\x6a\x6e\x35\x60\x7b\x01\xcb\x33\xf4\x99\xd0\x89\x24\x4b\xfb\xcb\xea\xbf\xd6\xfd\xbd\x53\x91\x79\x55\x7a\xc2\xd3\xdd\x60\xeb\xcc\xf4\xd9\x0d\x30\xb0\x0b\x9c\x27\x9d\xa2\xc5\xa8\x7f\x07\xcc\x92\x94\xf5\xfd\x9e\xf7\xbf\x9b\x0c\xb8\x93\x38\xdb\xc9\xf3\x9a\x00\x61\x24\x23\x57\xfd\xed\x74\x80\x32\xff\x6b\xb2\xb8\x18\xc5\x1d\x13\xce\x11\xe7\xb1\x90\xcb\x30\x1d\x61\x8c\x24\x88\x53\x8f\xc2\x99\xd1\x99\xf4\x0e\x0d\x04\x81\xd5\x49\xde\x7b\xbf\x60\xfa\x60\x10\x64\x09\xcd\xdf\x43\x5e\x7a\x49\x91\x9f\xd9\xff\x10\x18\x0d\xda\xb5\xbf\x54\x08\x06\x2c\xe0\x91\x03\x4e\xfa\x69\x31\x51\x81\x06\x60\x1c\x2c\xa1\x61\x6f\x04\xcd\x49\x30\x4f\x67\x38\x30\x60\x02\x4d\x3a\xe5\x23\xf8\xbf\x27\xac\x3f\x7b\x9a\xb2\xe9\x63\x86\x2a\xcc\x02\xbb\x99\x8f\x21\xbd\x2c\xbc\x5a\x94\xe9\x4e\x8c\x98\xa2\x41\x4a\xce\xd7\xeb\x7a\xb9\xca\xfc\x63\x47\x51\x9a\x3a\xe6\xab\xc7\x66\x7f\xe9\xa6\x51\x1c\x50\x54\xeb\xe5\x75\xb5\x5b\xbe\x3e\xff\x71\xbb\x59\x3c\xac\x76\xb7\x5f\x5f\x17\x83\x02\x00\x00\x8f\xac\xcc\xc5\x1e\xdb\x27\xf9\x52\x57\xff\x8b\xaa\x6d\x26\xd9\x47\xe0\x18\x12\x47\xa6\x8d\x53\x3f\x2f\xe7\x5b\xf7\x74\x34\x00\xc7\x88\x39\xb3\xc7\x73\x81\x5c\x7a\xbc\x98\x73\x4f\xad\xfc\x9f\xe5\x4b\x71\xda\xcf\x8b\xe4\x20\x96\xa1\x1a\x04\x6b\x2e\xab\xd5\x00\x24\x98\x50\x71\xba\x03\x5a\x75\x8e\xdb\xbc\x85\x61\xd2\x2d\x8d\x5f\x0b\x2b\xdc\xf9\x7c\x6a\x29\x70\x37\x71\x17\x20\xd5\x82\x86\xfe\xed\xf3\x72\xe9\xfb\x27\x63\xd6\x1e\xca\x7f\x60\xd9\xb9\xfe\xfe\x77\xc1\xf8\x88\x83\x7e\xad\x11\xe6\xdd\xf1\xdf\xff\x33\x1d\x8a\x82\x9b\x51\xf6\xf3\x6b\xe3\x02\xb7\xb4\xb4\x11\xe2\xee\xac\xaa\x06\x44\x62\x22\x5b\x80\x50\x14\xa8\x48\xae\x45\x8d\x69\x1f\x00\x44\x9a\x59\xfe\xc7\x9a\x88\x67\x67\x3d\x28\xb2\xc4\xf3\xce\xe4\x87\xd3\x61\x5c\x32\x45\x1b\x63\xd8\x5f\x46\xd8\x52\xf8\x75\x43\xa4\xf1\x03\xa7\x2f\x00\xc4\x31\xb1\xca\xbd\xd4\x55\x4b\x80\xb2\xc5\x31\x9f\xdd\xa6\x9b\x0f\xe9\xc4\x5e\xa7\x0d\x63\x35\x01\x83\x83\xcc\x18\x73\x1f\xfc\xe1\x79\xd9\x19\x24\xf3\xb2\xc2\x2b\xd9\xbc\x4b\x96\x1f\x48\x19\x27\xc6\xe7\xe5\x49\x10\x76\x3d\x2e\x03\x03\x89\x69\x30\xd7\x38\xbe\xab\xea\x8b\x96\x16\x48\x63\x3c\xd7\xe0\xcb\xb7\xd5\xe5\x34\x17\xa8\xc0\x10\x0c\xa1\xaf\x8f\x80\xe6\x6c\xb5\x07\xc5\x52\xd2\xa5\x76\x0a\xa1\xcf\x5e\x65\x65\x36\xd2\x54\xc2\x28\x79\x47\xa0\xcb\x91\x5c\x16\x80\x36\x8e\xb2\xc5\x95\x5e\x7e\xf5\xdb\x53\x33\xde\xd8\x00\x59\xa4\xe4\xb8\x6e\xfc\xe6\xf3\xeb\xe6\x76\xf6\x30\xc8\x6c\x09\xaa\x4f\x61\xf4\x4f\xd3\x6b\xa0\x0d\x6e\x1d\x20\x8f\x69\x24\x15\xd0\x58\x3e\x4b\x62\x88\x3a\x16\x79\x1f\x9b\x05\x13\x08\x60\xde\x8c\xa7\xc5\xd9\x5a\xf3\xb6\x53\xfb\x56\x89\xb0\x1c\x69\x44\x04\xec\x88\x85\x2d\xfa\xe5\x27\xc0\x35\x30\x68\x88\xba\x72\xbd\xfd\x99\x18\x3f\xc8\x20\xce\x68\x36\xbb\xc9\x80\x93\x6b\xfa\xb7\x91\x8c\x65\x64\x28\x36\xf9\x7e\xee\x41\x5c\xba\x28\x83\x58\xdb\xc4\x5d\x71\x56\x3a\x35\x5a\xf7\x25\xd3\x49\xc6\xfa\x7c\xe8\x5d\x5d\x1d\xce\x8a\x71\x5d\xcb\x90\x19\x8a\x42\x7b\x8e\x43\xca\x18\xbb\x63\x51\x80\xc2\x87\x12\x77\x14\x60\xde\xbc\x55\xa7\x42\xdf\x60\xd4\xa7\x53\xc8\xe1\x68\x6e\x3e\x59\x10\xf4\xa7\xc5\x99\xad\xac\xca\xf7\xb2\x1a\xf3\x7e\x82\x8c\x30\x72\x25\xed\xdd\x73\xfd\x3e\xe2\x44\x9e\x3e\x15\x0f\x43\xfa\x82\xa0\xf5\xea\x70\x2c\xaa\x4f\xbc\x46\x16\x75\xa9\x97\x78\x9a\x48\x37\xe7\x6e\xf1\x3b\x16\xd5\x71\xce\x1a\x05\x92\x8b\x2c\xb5\x61\xc7\x0d\x09\x83\xb5\x96\x47\xe8\x78\xc1\xf1\xf0\x67\x28\x20\xa7\xba\x7b\x61\x5b\x76\x38\x19\x18\x92\x6b\x2b\x7a\xfb\x02\xc7\xcf\xfa\xd4\x78\xe6\xb6\xe9\x45\xe2\x90\x85\xd2\x25\x82\xc6\xe1\x7c\x19\x1b\xa5\xdc\x6e\xb4\xfd\x3c\x4e\x77\xa2\xe9\x08\x94\x49\x14\x65\xc1\xd4\x84\x3e\x17\x18\xbc\xdc\xaf\xa9\xb1\x6a\x0a\x44\x55\xbc\xc1\xb6\xcd\xcb\xbd\x9b\xb0\xff\x18\x40\xf8\xff\x09\xbc\x20\xb3\xc0\x52\xcd\xa9\xaa\x6c\xf3\xf2\x84\xeb\xad\x8f\xcb\xca\x2c\xb2\x15\x35\x4e\xe8\xad\x6c\x4e\x35\xd6\xc3\x4a\xe4\x5a\x89\xc0\x0e\x79\xfc\x41\xe9\x98\xe7\xf2\xda\x48\x06\x99\xd9\xa0\x08\x14\x8e\x28\x67\x88\xf7\x48\xd0\x32\x91\x93\x18\xc7\xc3\x44\x99\x60\xfa\xd0\x32\xb0\xda\xfa\x8f\xaf\xb7\x9b\x91\xde\xb1\xbf\x98\x92\x9c\xaa\x5c\x7c\x8c\x80\x96\xa1\x2f\x78\x56\xe7\x2e\xb5\x0c\x02\x87\x92\xec\xdc\xaf\x19\x48\xf2\x72\x46\xeb\xb2\xed\x2a\xb5\x89\xad\x8c\xa6\xe3\xc8\xee\x19\x0d\x24\x06\xc2\xaa\x96\x7b\x22\x1c\x90\x18\xc7\x84\x74\x78\x83\xe6\xed\x01\xcb\x7d\x8f\x5c\x20\x3c\x2a\x58\x5a\xf2\xce\xb0\xb8\x04\xec\x97\x98\x66\xe4\xc3\x1d\x4e\xc5\xb6\xb2\xa5\xbb\xbf\x4d\x1a\x98\x88\xbb\xc2\xad\xc2\x92\x9e\xfb\x35\x55\x05\x0c\xe9\x29\x37\xf7\x0b\xb2\xe6\xfe\xdc\x6c\x3d\x95\x0a\xa8\x40\x01\xb9\xa3\xf2\xf4\xf9\x2d\x87\x7f\x57\x6f\x50\xf6\x87\x90\xd1\x0e\x60\xa0\xcd\xf7\xa7\x49\x14\x43\x05\x88\xc4\xc0\x62\x87\x49\x67\x8f\xfc\xee\x35\x7f\x41\x31\xc8\x08\x54\xf1\x81\xf9\x2b\xe4\xcd\x04\xa2\xa8\x98\xb1\x25\x0d\xf6\xcc\xe2\x38\xa8\x21\xba\x06\x61\x9c\xd2\x77\x26\xc9\xb8\xe6\xed\xcc\x8d\x98\x6c\x86\x2a\x4c\x0d\x85\xe0\x73\xf7\xd9\xfb\xb7\x0e\x55\x92\x39\x9a\xa7\x41\x53\xd4\x1f\x8c\x38\x23\x0a\x85\xf2\x74\x78\xac\xf4\xa9\x18\x3a\x2b\x42\x20\x68\xbb\xc5\x0b\xae\xbe\x43\x71\x82\xde\xe6\x9e\x26\x0d\xaf\x82\x59\xdd\xa5\x38\xd7\xe4\xdf\x6d\x6f\xb6\xbb\xc7\xf5\x93\x17\x1e\x00\xc5\x91\x69\xaa\x62\xc1\x03\x4d\xac\x53\x8d\x4e\xab\xd9\x35\x48\xc0\x6e\x40\x79\xf3\x2c\x9b\x8a\xd4\xc2\xdd\x91\x34\x53\xf4\x56\xb7\x95\xa2\xdd\xc9\xfd\x9c\xb1\x90\x0a\x92\xb1\xb5\x91\x91\x11\x63\x26\x28\xc1\x24\x65\x9f\x4f\x25\x45\x57\xa6\xd6\x84\x12\x29\xd2\x0c\xed\xa3\xc3\xb7\x30\x96\xa8\x00\x25\x0c\xf4\x2c\x33\x04\xe9\x1e\x81\xb4\x94\x14\x82\x2c\x5c\x2a\x00\x9b\x0e\x59\x85\x2c\x8d\x42\x97\x8e\x71\xec\x7c\xfe\x34\xe4\x8c\x02\x0e\xb6\xcc\x7d\x8b\x4d\x3b\x8a\x16\x29\x04\x20\x7e\xe6\x2f\x8e\xc9\xe3\x0b\x1c\x64\x81\xf5\xc0\x21\xa3\x8c\xe0\xda\x6d\x26\xdb\x1c\x6b\x92\x54\xf8\xe9\x92\xa7\x19\x67\x38\x60\xd3\xad\xbf\xbd\xb4\xcb\x5f\x73\x37\x72\x9d\xaf\x9e\x8e\x98\x78\x2d\x17\xa2\xb6\x33\x27\x8f\x45\xd5\x2c\xed\xd9\xd8\x1c\x51\xc1\x1d\x5a\xc4\xf9\xec\x22\x99\x2d\x9c\x94\xdd\xd2\xf4\x4c\x02\x6f\xcd\x4b\x5d\x1d\xf2\xa2\xff\xf4\x9a\xe9\xcc\xeb\x05\xdc\xa2\xec\x06\x74\xf7\x67\xb6\x51\xea\x30\x48\xf8\xa8\x44\x65\x93\x97\x0a\x5f\x11\xf4\xc8\xf6\xd6\xa1\x53\x2c\xfe\xfa\xb8\x9c\x44\x00\x75\x88\xe0\xf3\x39\x0e\xf6\x40\xba\x7a\x84\x64\xeb\xc3\x03\x3a\x34\x61\x26\x7c\x9c\xeb\x05\x6b\xc7\xc5\x7a\x39\xc2\xef\x02\x1f\x3a\x0a\x78\xea\x63\x07\xca\xe7\xf5\x96\x45\xd5\xa0\x1e\xd9\xd7\x9a\x27\xd2\x26\xea\xa2\xb0\xad\xee\xf1\x87\x23\x1e\x9c\x0c\x4c\xcd\x53\xab\xe6\x39\x08\xf3\x58\x50\xcc\x78\x23\xd2\x3c\x55\xc4\xfb\x79\x5b\xc3\x7e\xf8\x35\xd6\x29\xc5\xbf\xbd\x3d\xf4\x6c\x4c\xe3\xa3\x8e\x37\x9f\xcf\x3d\xe5\x84\x4e\xb2\x90\x28\xba\xee\x2b\x4a\x49\xdd\x3e\x6d\x66\x9f\x2c\xc9\x42\x30\x5e\x40\xe4\xf9\x8f\x61\x12\x6b\x01\x3d\xf1\xba\xcb\x99\x77\x13\x63\x12\x07\xd2\x42\x65\xe4\x84\x7e\xb1\x6c\x40\xcb\xaa\x24\xfe\xe9\xb1\x5d\xa4\x21\x48\x7c\xed\xe0\x14\xcd\xa0\x81\x09\x2a\x3d\xdc\x3e\xff\xbe\x7a\xda\xfd\xb1\x78\x78\x58\x6d\xfb\x63\x59\x00\xa1\xc7\xc4\x97\x25\xd6\xcd\xc3\xf0\x81\x65\x68\x49\xf9\x7b\x26\xfa\xd3\xbb\xcd\x98\x35\x23\x69\x76\xd0\x12\x62\xa0\x2f\x0c\x47\x3e\x1b\x5f\x3a\x8a\xc9\x0c\xff\xa3\xaa\xdf\xb1\x7e\xa9\xaa\xe2\xde\x53\xd2\x82\xd6\x98\x31\xe6\x2c\xd0\x70\x07\x5a\xe7\xe5\xde\x05\x64\x7c\x0b\x63\xc1\xa2\x47\xeb\x9c\xfa\x7a\xee\x43\x93\xff\xdd\x77\x3d\x86\x3c\xb1\x2c\x3b\xef\x38\x26\x93\x99\x3c\x08\x06\x51\x42\x05\xe3\xea\x0d\x8a\x02\xcb\x3d\x4e\x90\xfa\x18\x24\x8a\x42\x29\x9b\xc5\x1d\xf6\xfb\x29\x06\x90\xda\xb9\x5e\xe6\x7f\xcd\x3c\x15\x64\x99\x36\x3d\xb1\xac\x63\x6d\x7b\xa8\xd4\xfb\xed\xd9\x74\xed\x16\x69\x32\x72\x08\x4c\x78\x5e\x70\x84\x91\x44\xe9\x24\x45\x1d\x8b\xf7\x68\x8c\x23\x0f\x83\x00\x7a\x2a\xe6\xce\x60\xc9\x0b\xdc\x4f\x2b\x28\x91\xa7\x01\xb8\x40\x21\x81\xf9\x67\x4f\xc0\x53\xfb\x85\xca\xaa\xad\xea\xae\xef\x26\x27\xc7\x18\xd0\x6b\xd2\x22\xf0\x08\xe5\xe7\x34\xda\x35\x70\x2f\x8e\x2a\xcd\xc6\x90\x4e\x8c\x31\x4a\x43\x0f\x7e\x3b\xb5\x6f\x96\xac\x7f\xfa\x08\x49\x64\xe1\x1b\x72\xca\xe2\x85\x89\xc8\x1c\xab\x58\xa9\x67\x56\xb5\xbb\x4d\xdf\x50\x01\x8c\xc6\x77\xfd\xd9\xc3\x02\x1f\x7a\x9a\x54\xc0\x34\x91\x84\x98\x1b\xc9\x62\x9f\xe5\x1a\xce\xe1\x30\x98\x76\x53\x8c\xe8\x36\x3a\x97\x42\xbd\x3b\x2a\xb1\x6b\xb1\x47\x77\x56\x16\x49\xe2\xbd\xb9\x5d\x6f\x5e\x1e\x16\x7f\xee\x96\x0f\x8b\xcd\x66\xfd\x7f\xbf\x7a\x24\x0d\x66\xb1\xb4\xd6\x7c\x5b\xd5\xf8\x64\x6d\xf1\xff\x3e\x2b\xcc\x9f\x5f\x35\x63\x90\xb8\x84\xb1\x4f\x9b\xcc\x19\xaf\xff\x35\xd3\xdf\xbf\x56\xe3\x7c\xed\xef\x74\x76\x64\x8a\xd1\x7b\x8c\x8b\x25\x7b\x30\xf5\x65\x33\x1a\x45\x96\x28\x33\x52\x94\x2a\x1d\xe7\xdd\x2c\x1b\x82\xc0\x42\xf2\x41\x95\xaf\x01\x74\xe2\x21\x64\x57\x4f\x03\xea\x08\xa1\x49\xd0\x87\x92\xbb\xdd\x34\x2f\xf7\x93\xcc\x20\xca\xcc\x10\x64\x3e\x6f\x9e\xaa\x96\x84\x9e\x2f\x45\x5c\x51\xa2\xd4\x96\xdc\xdb\x2a\xd3\x7f\x0e\x46\x11\x2a\xcc\x64\x40\xf6\xff\xd3\xb6\x1a\x70\xbf\xa8\x79\x44\xd6\x42\x45\x26\x54\xe7\x12\x9f\xe6\x49\x1b\xc4\x80\xf3\x19\xc7\xb7\x07\x03\x78\xcb\x0f\x31\x82\x98\xf7\xa9\xe9\xc5\xf6\xb1\x27\x23\x76\x0d\x0c\xb3\x80\x16\x38\x1e\xb1\xd4\x76\x2d\xb0\x05\xf0\x53\x09\xf9\x59\x87\x1b\xc1\x48\x9b\x7c\x9b\x1f\xf0\x01\x4d\x7b\x83\xa6\xaa\xe7\x5c\xb1\x60\x98\x04\x25\x9c\x64\x70\x5d\xcd\xc2\x99\x86\xa9\x8c\xd2\xc1\x14\x86\x7d\x5c\x3f\xed\x6e\xbe\xfe\xe9\xcf\x0c\x95\xd5\xcf\x1f\x48\x53\xaa\x9f\xcb\x66\x75\xa7\xa0\x65\xaf\xa4\xca\x37\xd5\x8e\x2d\x74\x13\x6a\x46\x44\x5f\x45\xf7\x63\xe2\x7f\xe5\x02\x28\xbb\x46\x82\x1f\x90\x9f\x15\xc4\xb9\x66\x31\xcb\x48\xca\x76\x77\x26\xe0\x35\x8b\xd7\x5d\x0a\xcc\x99\x38\x8d\x7d\x30\x70\x43\xc4\xa6\x7d\xa8\x60\xd6\x1f\x89\x0a\x9d\x06\x73\x0b\xc5\x54\xa0\x03\x4c\x9a\x71\xca\xa7\x5a\x09\xe2\xd5\x77\x2c\xdb\x66\xf5\x63\x94\xd4\x72\xed\xb2\x10\x3c\x6f\x14\x01\x99\xbe\x96\x0d\x41\xc8\x88\x7e\xde\x5f\x4c\x18\x4b\xa8\x57\x23\xcc\xe2\x06\x06\x82\x4c\xba\xbd\xe4\xb6\xdb\x66\xcf\xb6\x10\x03\x3c\x91\xac\x0f\x24\xfa\xa1\x66\x20\x55\x09\x8c\x34\x48\x9b\x77\x6c\x2f\x97\xf1\x5f\xa2\xd2\x9d\xf5\x99\x54\x5a\x3b\xeb\x73\xe5\x8c\xb4\xb3\x12\x27\x23\x4d\x92\x88\x09\x57\xe2\x98\xb1\xb4\x7f\x30\x15\x25\xe4\x1b\x3f\x7f\x94\x23\x53\xd2\x28\xc3\x68\x6c\xf6\x1f\x75\x93\xef\x2f\x42\xbb\x8d\x76\x94\xb7\xae\x4c\x64\xad\x2a\x8a\x15\x8f\x74\x11\xc1\x98\x54\x70\x9b\x77\x71\xa5\xad\x9b\xcf\xa6\x45\xb7\xb3\xc8\x20\x08\x85\xd3\x02\x6b\x37\x58\x14\xbd\x0a\xc0\x44\x88\xcf\xb7\xcd\x4c\xe0\xfc\x00\x57\x0b\x79\x9e\x2d\x90\x41\xa0\x38\xa5\x44\xf7\x75\xf5\xe1\x1c\xa4\x66\x0c\xf5\x92\x01\x8b\x2c\x6b\x9f\x82\x42\x4d\xe4\xce\xfe\x35\xbd\x12\xcb\xa4\x72\xb4\x9d\x3e\x91\x71\x8b\x47\xbf\x16\xc9\x20\x64\xda\x12\x34\x81\xc1\x17\xf8\xbc\x54\x24\xe1\x5b\xc6\x9c\x96\x57\x99\xbb\x72\x3a\x2b\xd3\x60\x09\x3a\xc6\x86\xb0\x0c\x42\x95\x49\x47\xea\xd2\xad\xad\xdb\xff\x5c\x79\xb8\x88\xb3\x28\x19\x25\xf4\x1a\xff\x54\x51\x62\x95\xa5\x5e\x5e\x57\x3b\x5a\x40\x6e\x9e\x9f\xbe\x6e\x76\x2f\xab\xd7\xe5\xea\x69\xbb\xf8\xb2\xea\x1b\x66\x86\x24\x8c\x50\xd7\x13\x9a\x73\x19\x44\x46\x91\xd9\xd4\xbd\x11\xd6\x83\x80\xcd\xf8\xeb\xcb\x80\x47\x18\x38\xec\xcd\x8b\xf5\xde\x67\x13\x57\x06\x9c\x43\xec\xf9\x41\x2b\x32\xed\x5d\xc5\xef\x84\x6c\x59\x06\x3c\x66\xb4\x13\x2c\x17\x5b\xc2\xb9\xae\xb6\xf7\xbb\xcd\x6a\xf9\xfc\x74\xbb\x5b\x2d\x5e\x1f\xfe\xdc\xdd\xac\x5f\x6f\x77\xaf\x8b\x6d\xff\xf0\x3c\x0b\x84\xe7\xb9\x27\xf0\x6f\xb3\x21\x86\x36\xed\xe3\xe3\x5d\x93\xc4\xab\x2e\x2d\x97\xf7\x3b\xd4\x79\xbb\x0b\x93\xb1\x55\x25\x83\x18\x0c\x95\x26\x35\xf0\x1d\x6f\xba\xef\x30\xfb\x1a\x09\x24\x44\x96\xd5\x50\x84\xd2\x9a\x85\x58\x4c\x3f\xdc\xc5\x55\x57\x06\x69\x68\x02\xcb\x07\x4d\x39\x07\xeb\x84\x5e\x65\xab\xb9\x72\x8d\x48\xca\x49\x5e\x6b\x8f\xe7\xc4\x6d\x32\x48\x53\xcb\xba\xd6\xed\x30\x7d\x79\xf3\x90\xc1\xf0\xad\xa4\x95\x37\xb3\x6e\x20\xd1\xc7\x16\x45\x7f\x10\xb5\xf4\x35\x07\xcc\xff\x98\x85\x22\xb4\x7a\x5f\x54\x9d\xe2\x28\xa7\xef\xaa\x7a\x31\x9c\x98\xa5\x86\xe2\xc9\xcd\x2f\xe5\x47\x64\x20\xc2\x98\x0c\x2d\x2b\x25\x70\x0f\xcd\xaa\xd4\xde\x07\x95\x81\x88\x45\xc0\x27\xa2\x94\x43\xd1\xd9\x68\xcb\x92\x81\xc8\x02\x1a\x2d\x2f\x6f\x15\x96\xf9\x0f\xaf\x18\xea\x0f\xcb\x2c\x0b\xfb\x1c\xb3\xad\xed\xb0\xa8\x0b\x62\x9e\xea\xbe\xd9\x06\xeb\x1c\x8a\xbe\xd8\xc6\x9f\x27\x94\xc7\x33\x3d\x40\xe7\xee\xf4\xb5\xc5\xff\x80\x49\xab\x3b\x1d\x35\x1f\x9c\xb4\xbc\xdc\x8f\xbd\x17\x19\xa8\xd4\xd0\xba\x44\x09\xd6\xdd\x1f\x8b\x6f\xab\xb0\x1b\xeb\xeb\xe7\x5b\xdf\x42\x07\x21\x91\xc3\x5b\xa2\xe3\x59\xdf\x61\x20\x08\xc6\xb0\x7e\x5a\xfd\x87\x1e\xec\x09\x3f\xfc\x89\x28\xec\x37\xb0\x4a\x7b\x2d\xbc\xf7\x33\x19\x31\x26\x68\xef\x97\xc5\xc6\x66\x85\xfd\x01\xa3\x02\x9b\x7a\xa5\x81\xbd\x7c\xab\xaa\xe6\x72\x1d\x73\xd7\x94\x51\x5a\xaf\xe7\x67\x24\x7d\xb2\xcd\xb1\xc8\xcf\x28\x1a\xcf\x0a\x16\xae\x5a\x4a\x92\x05\xa1\xa0\xc2\x73\x4a\x6d\x04\x3b\xa4\xe0\xb3\x13\x76\x2f\xb0\xee\x9c\x51\x3f\x74\x59\xc0\xe3\x88\x8f\xb5\xb3\x6f\xa0\x55\x6f\xfd\x51\x91\x2a\x97\xb5\xfd\x82\x25\x3e\xe6\x3f\x70\x9e\xbd\x9b\x98\xd2\x92\xb1\x00\xc9\x5d\x7b\xc4\xe6\xed\xa5\xca\xcb\x5e\x27\xff\x02\x56\x53\x32\x66\x64\x64\xd3\x91\xea\x54\x5b\x6f\xe5\x65\x46\xed\x26\x59\xc8\x14\x39\xd1\x60\xdd\xa3\x19\xc5\xf9\x64\x67\x9f\x9f\x67\x88\x8d\x77\x18\xad\xab\x46\x41\x31\xc6\x5f\xf9\xa6\xa1\x25\xf8\x68\x1c\xcd\xc1\xda\x05\x3c\xe6\xcd\xb2\x90\xc0\xb7\x8f\x8b\x8d\xa5\x78\x76\xf4\x3b\x3f\xb5\x12\x25\x0b\x25\x12\xe8\x16\x94\xaa\x4f\x76\x0f\x9f\x01\x2a\x2e\x0e\x0f\x16\xaa\x90\x62\xb2\x36\xd6\xe6\xeb\x0e\x1e\xa1\x79\xbf\xb2\xaf\xb2\x50\x2b\xaa\xf4\xba\xc5\x8f\x51\xa8\x4a\xb2\x28\x52\x94\xf6\xfe\x03\x5a\x78\x83\xe9\x21\x99\x58\x26\xd6\xfc\x80\x77\x75\xcf\x61\x23\x59\xa4\x39\x3a\xce\x9c\x2d\xc2\x61\x5e\x57\x71\x41\x19\xaf\x3b\xc7\xd6\x37\x4d\x55\xf4\x2e\xbf\x1d\x0f\x63\xe6\x6c\x8e\x27\xa8\x55\xd5\x2c\xab\x1a\x7f\x3e\xb8\x38\xcf\x62\xe6\x37\x3d\xaa\x1a\x99\x98\x1f\x8c\xc7\x82\xd0\x52\x04\x72\x7b\x1a\x38\x47\xaf\x6a\xb0\x48\xc6\xd3\x90\x0f\x02\xa5\xd3\x3d\x8a\xf1\x0c\x29\x75\x7f\x6a\x2c\x29\xe1\x97\x13\xd4\x7a\xd6\x26\x4e\x34\x91\x1c\xd0\x3d\x4b\x38\xb5\xcd\x84\xe6\x46\xb2\x38\x8d\x59\xdc\xcf\xb0\x75\x69\x2a\x2f\x7e\x3e\x7d\xb9\x18\xac\xcd\x78\x74\x75\x2e\x5e\xc9\xcb\x1d\x4e\x84\x4a\x6d\xb9\x4c\x5e\x8e\x45\x86\xdc\xe1\x14\x24\x91\x78\xf7\x1c\x2c\x2e\x2e\xda\x5b\xb0\xe2\x7f\x66\xf5\x3a\x7d\x6c\x41\x32\x11\x66\x10\xf7\x75\x55\x58\xef\x7b\x16\x0b\xc9\x04\xf0\x34\xf1\x6e\x61\xfe\x37\xee\x88\x07\xe8\x32\x20\x74\xf6\x85\x41\x19\x22\x08\xf9\x2f\x55\x56\x3f\x26\x83\x0e\x74\x42\x79\x03\x07\xc4\xb1\x6a\x2a\x57\x48\xbc\x24\x93\x3c\x20\x83\xac\xc4\x0f\x2b\xa7\xff\x4f\x6e\x2e\x85\x9d\x3c\x6e\x87\x9d\x75\xb6\xca\x02\x32\xe5\x1e\x17\xeb\xa7\xcb\xb6\xdc\xee\xe5\x7e\xb1\x59\x85\xbf\xf5\x27\xa4\x44\xdb\x4f\x46\x42\x9b\xcf\xf5\x84\x67\x37\x57\x8a\x9b\x7e\x55\xbd\xa1\xb8\xfd\x6c\x29\x51\x26\x64\x36\xb6\x66\x0b\x72\xcf\x0e\x5b\xfa\xf7\x12\x3f\x6e\x6a\x7c\xab\xca\xab\x78\xc2\x3e\x41\x3e\x2b\x71\xb8\xb6\x6f\xfc\xc3\xdf\xdd\x73\xe8\x28\xa5\xad\xb7\xdb\x4a\x28\xf4\x0a\x65\xe7\xb3\x7c\x3d\x2e\x4a\xfd\x50\xed\xf3\xfe\x8b\xea\x24\x35\xa2\x47\xf9\x17\x3b\x9d\x37\xf2\x54\x37\x38\x64\x8b\x24\xd3\x52\x90\xae\xcd\x1b\x34\x9b\x53\xae\xf2\xc1\x42\x61\x26\x0a\x03\x47\xd8\xd3\xf5\xc7\xac\xc8\xf4\xf2\xc3\x85\x01\xb7\x41\x4d\x97\x8b\x80\x02\x5b\xe7\x39\x9e\x27\x93\x46\x67\xe9\x80\x70\x7f\xbb\x1e\x2f\xb8\x7d\xc3\x03\xae\x8c\x41\xd5\xfe\x76\x2e\xc3\xdb\x9d\x21\x0c\x78\xc4\x7a\x5d\x49\x90\x79\x31\xae\x27\x3e\x9d\x15\xc0\xc9\x90\x71\x4d\xc2\x5b\xf9\x61\x94\xb0\x91\x21\xd3\x51\x30\x84\xe7\x48\x5f\x63\x6a\x4b\x86\x61\x60\x69\xbf\x41\x6b\x57\x80\xef\xb5\x78\x66\xb6\xd2\xf4\x19\xc3\x48\x58\xb4\x21\x49\xbf\xdf\xe0\x3e\x2f\x07\xdc\x8f\x0c\x43\x95\x92\xb9\xfb\x8e\x78\x3c\xe2\x98\x1b\x48\x86\x21\x32\x4a\x02\x91\x18\xc3\x2d\x7c\x7a\x23\x35\x8c\x22\x41\x4b\x4e\xd7\x53\x77\xd0\xbc\xe5\x55\xf9\x02\x35\x4c\x85\x78\xd9\xec\x8f\x3f\x37\x36\x81\x97\xc7\x20\x2f\xd7\xaa\x71\x12\xfb\x96\x6b\xc2\x53\x11\x59\x52\x94\xef\x08\xc5\x12\xf3\x62\x5c\x7b\x3d\xff\x3b\x28\x57\xf5\x7d\xcc\x55\xe4\x35\x12\x5e\xf1\xaf\x53\x5e\xa3\x7e\x84\xff\xad\xfa\xce\x8e\x53\x1d\x8d\x8c\xec\xee\x31\x28\x49\x38\xf9\x70\xd9\xc5\x84\xa8\x0c\x63\x21\xb5\x73\x9f\x4f\xc7\xb5\xba\x8c\xba\x95\x61\x9a\xa5\x16\x74\xa0\xf5\x1d\xe2\x1d\xa2\xbe\x19\x3b\xab\x63\x97\x28\x4c\x33\x20\xbe\x0f\x3b\x5e\x6f\xa0\xbc\x2c\x79\x21\xc3\x54\x31\xca\xbb\x1c\xe0\xc7\x4b\x5f\x1e\x2e\xc3\x8c\x05\x2c\xf3\x5c\x2d\x14\x07\x99\x9e\x96\x65\x89\x87\x79\x3f\x55\x75\xfb\xf6\x52\x15\xf3\x0d\xd5\xb7\x04\x69\x65\x44\xfc\x6e\x71\x8d\x6b\x47\x86\x99\x36\x84\x06\x7d\x5a\x2e\xbf\x7e\x0e\x83\x46\x04\x42\x99\x7e\x57\xeb\xec\xff\x97\x1a\xbf\xe7\x95\x37\x6d\xfa\x88\x5c\xd7\x14\x28\x3c\x8e\x0e\xec\x42\x2a\x6f\xfd\x41\x2e\x2c\xc7\xac\xf5\x4b\xd6\xa5\xaf\x32\xf1\xc7\x85\xa0\x3a\xcd\xf6\x54\x0f\xf7\x46\xcb\x7e\x9b\x2b\xcb\x2e\xdd\x6b\x43\xca\x10\x12\x43\x86\xbe\x22\x6f\x69\x75\xac\xd4\xdb\xd7\xe3\xb6\x9a\x75\x14\x64\x8c\x88\x7f\x68\x4f\xef\xe5\x70\xfd\x41\x91\xf8\xa5\xe8\x36\xdf\xe7\x2d\x14\x8b\x9a\x22\x28\x79\xb9\x3f\x93\xa1\x66\x61\xe6\x4f\xd3\x91\x0f\x82\x6d\xde\xb1\x55\x6f\xd8\x3c\x97\x14\x01\xfb\x23\x6f\xdf\x2c\x95\xcf\xec\x2b\x00\x06\x3e\xcb\xb7\xac\x4e\xc7\xaa\x7c\x3c\x15\x77\xa0\xe6\xaa\x7c\x32\x94\xdc\x22\xa8\x8f\x03\x5c\x63\x1c\x16\x96\xa1\x44\x8b\xe3\x24\x06\x58\x07\xff\x9b\xb6\x50\x3c\x22\x33\xc5\x66\x8a\xbf\xe4\xd0\xf3\x8d\xc9\x50\x87\xda\x8f\x9b\x85\xcd\x81\xd4\xef\xd8\x52\x81\xd8\x90\x89\x91\xa1\xe6\x48\x04\x8e\x6a\x54\xea\xde\x0d\xaf\xf9\x30\xd4\x98\x52\x12\xfd\xad\x3a\x35\xde\xd1\x7c\x36\xe4\xe1\xfb\x3b\x62\x28\x69\xd6\x2c\x17\xbf\x6f\x46\x23\x05\x23\x46\x01\xc7\xcd\x76\xf1\xba\x5d\x3f\x7d\xd9\x3d\x3c\xdf\x6c\xb6\x3e\x57\x28\x43\xe4\x4c\x4e\x90\xde\x9b\xb7\xfc\x78\x03\x6d\x5b\xe0\x1f\x79\x39\xc8\x83\xb8\xc4\xa1\x0c\x31\xd1\x6a\x8c\x81\x98\x4e\x71\x14\xa1\x23\xd6\xf8\x80\x5a\x2f\xca\x3d\x0e\x0f\x68\x44\x12\x7b\xc7\x24\x6f\x3f\x9d\x31\xd6\xd7\x2f\xba\x66\x86\x25\x14\xe2\x25\x87\x58\x55\xda\x32\x66\x9c\xe6\xd3\xcd\xa4\x40\xf9\x85\xa5\x9f\x6e\x1e\x37\xa7\xbf\xaa\x61\x41\x8c\x02\x2e\x90\x11\x08\xab\x6d\xb1\xfe\xbc\xf9\x5c\x6d\xef\xe3\xe9\xa5\x22\x06\x40\xdf\xea\xbf\xbc\x2e\x83\x8c\x98\xd4\xb1\x8b\xa7\xd7\xa8\x72\x9b\xe2\xed\xb1\x05\x32\x0a\xc3\x54\xb0\x41\x14\xbe\x8f\x98\xaf\x7c\xa2\x51\x46\x61\x2c\xa8\xb4\xad\xed\x69\xe0\x6c\xed\xe5\xf3\xb1\x9f\x17\x51\xe8\xca\x38\x1b\x4a\xc2\xfa\xfa\xe6\x61\x7c\x44\xa1\xe0\xe8\x00\x41\xaf\xa8\xf2\x63\x8e\x9e\x1e\xeb\xa2\x5e\xa9\x8c\x42\x93\x84\x96\x71\x7b\xf1\x38\x51\xdd\x90\x51\x24\x39\x7d\xe9\xea\x38\xd5\x58\x93\x11\x8f\x30\x33\x9e\x1f\xbd\x73\x49\x96\x35\xea\xbc\x9d\x75\x13\xcf\x22\x42\xf7\xa9\x02\x72\xc7\x64\xb5\x1a\x17\xeb\xc9\x88\x03\x97\x56\xcf\xb3\x69\x51\xdb\xbc\xeb\xa2\x28\xb6\xd5\xa2\x98\xf2\x4b\xc8\x28\x86\x90\xca\x98\x8f\x50\xb7\x65\x2f\x8d\x26\xa3\x24\x30\x5c\x3b\xbc\x9b\x4d\x63\x84\x9c\xd8\x2f\xfa\x87\x4d\x50\x53\x20\x6f\x79\x18\x43\x05\x65\x94\x32\x8b\x94\xd3\xd5\x2b\xd2\x23\x5e\x5e\x7c\xa3\x34\x11\xc4\x85\xb9\xfd\xf1\x5c\xe7\xfb\x79\xc1\x89\x8c\x52\x4c\x62\x97\x3c\x5f\x42\x51\x6c\xd4\x1b\xea\x53\x81\xfa\xe6\x73\x3a\xd4\xa3\x8c\x1b\xd1\xf7\x5a\x79\xf2\xe7\x8b\x50\x13\x89\xe8\xe1\xb1\x1b\xbb\x34\xab\x67\x1d\xd9\xed\x82\xd0\xaf\xf3\x44\xd1\xed\x4f\x06\x10\x49\xea\x21\x16\x34\x3d\xac\x6c\xa6\x3f\xac\x92\x28\x70\xc5\xf0\x6f\xf9\xf1\x62\x62\x5a\x46\x8a\x1b\x82\x10\xbf\x3a\x1e\x8d\xdf\x46\x38\x08\x19\x29\x88\x68\x7e\x2d\xef\x1e\x7e\xeb\x7f\x32\xa4\xcc\x60\xb1\x74\x43\x74\x5d\x46\x4a\x3b\x35\x81\xaa\x7d\x59\x4e\x87\x5c\x18\xfc\x33\x7b\x37\xd2\x2c\x20\x74\xe5\xcd\xe3\x72\x3b\xf9\x62\x5a\xa7\x5c\x4c\x60\xb7\xf9\xdf\x34\x30\x47\x70\x2e\x19\x61\x18\x69\xd1\x87\xe1\xc6\x69\x6e\x19\xa1\xab\xbf\x73\x34\x05\x50\x9e\x0c\xa8\xce\x1c\xa9\x2f\x54\xb5\xc8\xc8\x64\x49\x64\x06\x05\xa4\xed\xe7\x71\x9a\x59\x94\x3c\x88\x6d\xfc\x9f\x3e\x8d\x4f\xb2\xbd\x92\x59\x39\x42\xf4\x49\x1e\x08\x85\xca\xcf\x4b\xaa\x5d\xf9\x6d\x9a\x3d\x75\xed\xba\x2d\x2c\xf5\x61\xa3\xf6\xa3\xba\x83\xa2\xc1\x45\xd3\x60\xdd\x3e\x55\x9e\x45\xde\xb5\x8d\xc2\x88\xa2\x06\x48\x65\xba\x79\xa5\xfd\x6a\xc4\xb9\x30\x14\xe1\xfe\xa8\x3e\xa1\xfa\x2b\x87\xb2\xfb\xdf\x74\x42\x71\x0e\x36\x80\xeb\xd3\x20\xab\xed\xfd\x66\x86\x2f\x94\x9c\x2b\x41\xc1\x31\x05\xc7\xb1\xd1\xe6\x8f\x1a\x4b\x52\xbc\xbd\x79\xf6\x8b\x06\x8f\xc1\x72\x51\x6f\x2a\xa5\xac\xb2\xce\xcc\x49\x9b\xf6\x5f\x82\xcc\xb8\x68\xc2\x37\xac\xbb\xd5\xbb\x79\x36\x3d\x41\xef\xf4\x76\x69\xa4\x22\xc7\x93\xf3\x3b\x7e\x36\x37\x9f\xb7\xd8\x2d\x7f\x6e\xbf\x19\xe3\xd5\x24\x4f\x53\x27\x83\x30\xca\x26\xdf\x7c\x3e\xe0\x1e\xd4\x19\x24\xf8\x72\xe4\x87\xa7\x8a\x05\xd2\x56\x60\xa6\x21\x1b\x31\x76\x4a\x2e\x82\x8c\xf2\x68\xcb\x9b\xe7\xfe\xa7\x84\x73\x7d\x85\x2d\xe3\xe6\xb3\xc5\xee\xd5\x7c\x5b\x48\x33\xe6\x8a\x7f\xbe\x55\x2d\xd6\xb3\xb0\x3c\x97\x99\x5d\x71\x6e\x89\x30\xed\xb7\xfe\x57\x08\x87\xb2\x09\x0a\x91\x6d\x73\xe7\xd3\xce\xfc\x2b\x2e\x4d\xea\x8b\xe0\x28\x26\x42\xad\xe7\xb8\x78\xc9\x15\x0f\x28\x0d\xad\xab\x12\x5a\x5c\x6d\xef\x7f\xeb\x0f\x58\x17\x69\xd5\xb4\x0f\xf9\x5f\xa7\x5c\x4f\xf5\xbf\x25\x57\x68\xb9\x69\x7c\x58\x6c\xdf\xf9\x25\xf9\x0f\x2c\xae\xe3\x8a\x25\xd7\x4c\x08\xec\xf1\x88\xa3\x90\xe0\x45\x1f\x73\x90\x88\x1d\x9b\x13\x5c\x47\x86\xe2\xdf\xff\x19\xa5\x6d\xcf\xd3\xef\x92\xeb\xd8\x96\xc3\x38\x3d\xa0\x52\xff\xbb\xca\xcb\xe5\xed\xcb\x2d\xe4\xb3\x5e\xc0\x54\x58\xdd\x31\x87\x50\x27\x43\xda\x33\xfc\x8b\xbe\x55\x66\x89\x73\x1e\x51\xaf\x7c\x4c\x9b\xa3\xb1\xae\xf9\x08\x26\x8d\xfa\x52\x49\xbc\xe4\x06\x54\x86\x6e\x80\x34\xbd\x17\xe4\x0f\x1a\x13\xe1\x88\xc9\x68\x9e\x68\xbe\x1c\x6c\x19\xbf\x6f\x1c\x28\x4d\x41\x64\x68\x5b\x50\xef\x24\xaa\x30\xee\x55\x76\x4d\xe6\x4e\xc6\x2c\x4a\x62\xe7\x65\x65\x61\xb7\x09\xfd\x76\xd6\x42\x60\x20\x46\x0a\x03\x83\xd5\x12\x33\x05\x54\xe7\x5e\x57\x85\xa5\x16\x99\xa3\x40\x26\xbd\x10\x33\xcd\xfc\x8a\xba\xb4\xa6\x90\x1d\x59\xe7\x29\x81\x38\xe4\x49\xe4\xb8\x69\x5c\xd6\x14\x6b\x17\xab\xb2\x79\x98\xc2\x45\x6c\xfc\xbc\x89\xa3\x28\xb6\xda\x2f\xb9\x69\x9b\x8b\x01\xbe\x38\xe2\xda\x0a\xa4\x77\xbe\x40\x69\x73\x6b\x8f\xd5\xf7\x79\xf6\x2f\x8e\xb2\x80\xdc\x9b\xbb\xaa\x26\x42\xaf\x6a\xb5\xbe\xf3\xaf\x1c\x29\x49\x28\x20\xd0\xfa\xa9\x1a\x22\x61\xa3\xe5\x27\xe6\x41\x42\x50\x3b\x82\x05\x3b\xb2\x85\x31\x51\xa4\x8c\x79\xa8\x53\x3e\x5a\xe8\xc9\x3b\x5e\xfd\xb5\xee\xbd\x85\x98\x47\x16\xb7\x73\x80\x1f\x54\xb3\x74\xc1\xc4\x8a\x79\x12\x6a\x17\x15\x79\xf4\x9b\x5c\x1c\x2b\x46\x56\xd5\xf1\xd4\xbc\x4d\xf3\x72\xae\x41\x02\x86\x04\x2d\xfa\x00\xc8\xa1\x7a\xac\x4a\x1a\x77\x17\x57\xe9\x38\x65\x82\x4c\xa5\x3f\xaa\xa2\x27\x09\x97\x71\x8a\x92\x02\x88\x64\x3c\x6d\x70\x7f\xc0\xc1\x9f\xa1\xba\x71\x17\x3c\xeb\xb6\xce\x31\xb3\x95\x8c\xb3\x54\x8e\xea\xf6\x5f\x4e\xc7\xe3\xe7\x26\xef\x3a\xd1\x7d\xdf\xab\x00\xd8\xe9\x82\x12\x67\xca\xaa\x6c\xb9\xfd\x79\x39\x43\x35\xc8\x58\xc4\x9c\x07\x3e\xa7\x5e\x97\x96\x13\xe4\x1a\x3f\xd7\xf4\x54\x60\x29\x99\x0a\xa4\xb0\xad\x47\x28\x62\x19\x43\xc2\xcd\x58\xe9\xfb\x09\x0e\xf8\x9f\x12\x0e\x67\x4c\x88\x7d\x5e\xc8\x8f\x0b\xc9\x94\x70\x5e\x9e\x25\x29\xbb\x1e\xbd\x89\x25\x0f\x09\x0a\x53\xe4\x0d\x01\x83\xfb\xae\x95\x42\xb9\x02\xf4\x76\x42\x22\x29\x63\xa9\x62\xea\xf4\x3f\x5e\x16\x7f\x4e\x7b\x5c\x39\x32\xfc\x07\x26\x76\x63\x9b\x2a\x56\x00\x44\x43\x46\xc9\xf0\x52\xcf\x0b\xbd\x67\x1d\xae\x95\x0d\x52\xaf\x9b\x85\x45\xeb\xce\xfa\x5b\x63\x48\xb6\xd7\xdd\xa9\xbc\x83\x7c\xa4\xa2\x22\x63\x8c\xac\xe4\xce\x3d\xb4\xea\x6d\xb5\xdf\xf7\xbf\x27\x49\xea\x60\x83\x4f\xf8\x71\x21\xc8\xf3\x8b\x31\x60\xb8\x25\x4e\x02\xad\x6f\xa1\x85\x4d\x5b\x23\x1c\xe6\xeb\xe7\x64\x7f\x4d\x82\x28\x0a\x86\x18\xd0\x83\x0f\xea\xb9\xcb\x8f\xaf\x9e\x04\x19\x27\x5a\xbb\xe6\x23\x6f\xd5\xdb\x08\x2e\x2e\x13\x16\x67\xa4\x72\x6e\x4e\xa5\xee\xa6\xf8\x99\x64\xcb\xe4\x39\x93\x50\x28\xe2\x13\x38\xec\x56\xdb\x7b\xbb\x1f\xf7\x24\x3a\xf5\xf7\xde\x2d\x4f\x22\x65\xa9\x19\x47\xd4\xef\xce\xb2\xb7\x77\xf7\x26\xda\xcf\x75\x77\xfa\x8b\x65\xbe\x38\xf0\x74\x7c\x05\x85\xbf\x5d\x88\x93\x26\x3c\x4e\xb9\xd7\x7e\xba\x23\x85\x42\xff\x30\x5c\x58\x55\x8c\x86\x33\xa7\xe2\xde\x1f\xb0\xca\xbb\x75\xd5\xbd\xfd\xa8\x02\x44\x26\x5c\x46\x76\xed\x73\x02\xeb\x3b\x98\x04\x57\x13\xae\x53\x32\x3c\x89\x2c\x7e\xe7\xd1\xa2\x3b\x42\x68\x4d\xb7\x80\x24\x91\x26\xc9\x9c\x42\xe1\xe3\xa7\x05\xfc\x4e\x3f\x65\xa2\x19\x81\x9e\x37\xdb\xcd\x76\xb5\xf1\x56\x68\x92\x60\x24\xb9\x8d\x72\xbb\x29\xb2\x2e\xcf\x4b\xaa\x64\x92\xb2\x58\x79\xea\xc5\xce\xed\x7e\x85\xf2\x7d\x8c\x22\x92\x49\x1a\x61\x0a\x7d\x2d\x54\x2f\xd1\x29\x93\x94\x47\xf4\x1a\xdf\xab\x16\x09\x19\xa0\x73\xfb\x39\xe7\x3a\x7b\x32\x49\x13\xa0\x4f\xda\x38\xd7\xb0\x73\x13\xa7\x49\x3c\x7e\x71\x90\x9f\x95\x4c\xf9\xeb\xe9\x78\x80\x59\xf7\x84\x0d\x53\x18\x50\x92\xa2\x61\xc2\xc1\xe2\xfa\x8a\xda\x6b\x05\x1e\x32\xc9\x94\xa6\x04\x6f\x5d\xea\x47\xf8\xb1\xf3\x57\x11\x61\xcf\x8e\xfe\x52\x57\xfa\xa4\x2e\xeb\x16\xca\x44\x44\x21\x19\xf2\x8d\x13\x2a\x79\xfe\xde\x07\xdc\x13\x91\x5a\x04\xb6\x2d\xca\x73\x54\x23\x7f\xcf\xb7\xa5\x44\x08\x23\x25\x11\x7e\xe3\x61\x5b\xc3\xac\x13\x01\x94\xca\x2c\x8c\xf5\xb8\xe9\x56\x2a\x94\x5f\x72\xd3\xbf\xae\xd4\x09\x2d\x7d\x4b\xa7\x81\x93\x97\x8e\x4e\xa2\x6f\x60\x22\x22\x06\xca\xdd\x7c\x3b\xcd\x80\xb9\x17\x6c\xc8\x44\x31\x65\x7a\x3a\x87\x7b\x2c\xf4\xc4\x9b\x4c\x54\x22\xd0\x66\x0b\x07\x75\x17\x8b\xec\x72\x0d\x74\x82\xdc\xaa\x01\x14\xfa\x85\x62\x58\xe3\xb5\x37\xd1\x89\x61\xda\x97\x25\x34\xcf\xc3\xef\xc6\x96\x17\xde\xae\x1e\x9f\xef\x17\x9b\x7b\x02\xcd\xcf\x1f\xf4\x34\xd7\x62\x92\x09\xb2\x00\x1c\x88\xda\x41\x4c\x2e\x00\xa8\x5d\x5b\x93\x25\x54\x9b\xb1\xbc\xb7\x05\x15\xc4\x33\xf3\x5b\x7f\x50\xf0\x91\x30\xf0\x8a\x84\x6c\x67\x5f\xcb\x48\xab\x30\xfc\x05\xdb\xe7\x7a\x0f\xe5\x04\x0e\x92\x18\xc5\x6d\x50\x6e\x40\xd5\x4d\x07\x4c\x1a\x04\x8c\xa0\x7e\xaf\x56\xb5\x4c\xdf\x2c\xef\x7f\x46\x04\x24\x53\xc6\x12\xb4\xec\xe7\xdf\x73\xfc\xb0\x74\x11\x5e\xc8\xea\xe2\x98\x4c\x43\x08\x71\x42\xe5\x7a\x2a\xaf\x40\xd8\xd2\x50\x6b\xcf\x63\xf0\x98\x97\xf9\xa1\xa7\x5b\x98\x36\x8b\x18\x27\xa2\xf4\x9b\xd5\xf8\x43\xa6\x11\xf0\x44\x4e\x21\xb9\xfe\xc9\x7c\x0b\xc5\x02\x4b\x5c\x6e\xe5\x5b\xba\x7d\xf6\x4e\x99\x9f\xc9\x53\xbb\x33\x79\x6c\xa8\xfa\x8e\x86\xec\x4d\x31\x61\x9d\x74\x4d\x12\x14\x9e\x02\xe1\x15\xcd\x65\x1b\x2e\x4d\x83\x94\xa9\x5e\x21\xb6\xc7\x1c\xcb\x54\x48\x49\x59\xab\xc7\x2d\x16\x43\xe5\x92\x4c\x21\xb0\xa4\xf0\xda\xee\x3e\x97\x09\x70\x65\x0a\x06\x6d\x91\xa5\x73\x81\xa6\x60\xbb\x54\xf2\x98\x2c\x82\x37\x68\xde\x2c\x15\xf0\x05\xb0\xb4\x4c\xa5\x52\x99\x2b\x62\x73\x35\x20\xfd\x05\x4c\x84\x1e\xce\xd0\x99\x6f\x63\x4b\x2c\x55\x11\x77\xe5\xca\xad\x27\xcc\x0d\x27\x10\xb8\x54\x47\x19\x15\xfa\x36\x2f\x54\x5a\xd5\x3f\x97\x4e\x24\x65\xfa\x0f\xf0\x8e\xf5\x57\x97\x00\xfe\xbd\x54\xb3\xb7\xc3\xd4\xc2\x6a\xb7\xb3\x2f\x6e\x02\xad\xf5\x25\x87\xed\xb2\xe3\x36\xf0\x50\x5f\x1c\xda\x86\x5b\x86\xec\x9d\x82\x42\x75\x4f\x19\xcc\xc6\x9d\x41\x5b\x93\xee\x45\xf8\x08\x07\x7c\x79\x28\x67\x41\x80\xb4\xe7\x5b\x64\x9e\x77\xae\xfa\xa9\x99\x05\x31\xba\xb0\x3a\x19\xcd\xb3\x60\x63\x16\x48\x4d\xfb\x86\x23\x13\xb8\x82\x07\xc8\x58\xa0\x08\x0f\x80\xc7\x4a\xbd\xcd\x2e\xc1\x24\x03\x33\x70\x22\x8f\x93\xaf\x59\xc8\x18\x7d\x0f\x55\x54\x0d\x45\xc8\x58\x7f\xc4\x70\x32\x90\x5e\x16\x7f\x2e\x9f\xd7\x4f\x0f\x7f\xfa\x03\x51\x68\x29\x7f\x8e\xf0\x39\xa3\x19\xe8\x8e\xa5\x81\x47\x4d\x38\x01\x7d\x92\x84\x58\x50\x5d\x9b\xaf\x9f\x9d\x3d\x5f\x14\x45\xcc\x41\x3b\x17\x75\xfb\x51\xd5\xef\x5f\xea\xea\x74\xec\xef\x97\xda\x8a\x9f\xc5\xe3\xcd\x62\xb3\x59\xdc\x3e\xbf\xee\x36\xeb\xff\xf8\xa3\x9c\x59\xc5\xa4\xce\xfa\xae\x60\x59\x95\x0d\x96\x8d\x07\x04\xcb\x8c\xc7\x8a\x8d\xeb\x95\x88\x3e\xad\x73\x5e\x7b\x3a\x95\x45\xd1\x8e\x85\xb0\x67\xfd\x1a\x33\x41\xc5\x50\xe4\x76\x50\xfa\xf8\xd9\xcc\x1e\x3f\x16\xdc\x4b\xee\xcd\x63\x89\x97\x62\x8a\x59\x12\x05\x22\x9e\x96\x73\x57\xb5\x8f\x4d\xfd\x36\xc1\x2e\xb8\x33\x3c\x7d\xb7\xa3\x29\x2b\x49\xbf\x79\xfa\x10\x29\x46\x16\xf3\x4b\x9c\x40\x63\x96\x48\x99\x65\x89\x0e\xfc\xac\xec\xac\x7d\x0a\x10\x9f\xe6\x88\x97\x2c\x83\x24\xf3\x6c\x19\xd5\xac\xda\x5a\x66\x99\xb2\xc9\xcd\x06\xdb\xcd\x11\x14\x2e\x6b\x30\x73\x5d\xc1\xe9\x12\x97\x29\xc6\x6c\xdd\x0d\xd9\x00\x34\x5f\x2d\xfc\x7d\xda\xc5\x2a\x46\x5a\x92\xbc\x39\x46\xb2\x2f\x1f\x75\xde\xa2\xa7\xb0\x21\x03\x6d\x06\xea\x70\x27\xeb\x54\xd1\xbb\x51\xfb\x65\x55\xea\x7c\x80\xf8\x4c\xb7\xe3\x0c\x63\x83\xb6\xa6\x4a\x55\xa5\xb6\xfe\x98\x0d\x02\xac\x4a\x3d\x0e\x59\x67\xa8\x0c\x81\x1b\x5a\x84\xc3\xa2\xd7\x00\x99\x1a\x74\x99\xc9\x62\xba\xf3\x53\xa5\xd1\x0b\xb5\x9f\xed\xee\x3e\x72\x2b\x82\x44\x91\xa7\x86\xdd\xd4\xbf\xc9\xf5\x5d\x55\xdb\x94\xe8\xb4\x33\x44\x00\x11\x49\xbb\x6e\xb6\x8b\xed\x6a\x77\xfb\xfc\x44\xa4\x38\xbb\xd7\xe7\xaf\x4f\xb7\x3b\x9f\x65\x11\x8c\x59\x25\xcd\x3d\xb6\x1b\x2b\x4e\x78\xb4\x5a\xa0\x55\x83\x7a\xd1\x4e\x8d\x72\xc1\x74\x4c\x90\x2d\x82\x64\x0e\x94\x3b\xfd\xc5\x50\xf8\x7a\xbf\xf1\xc5\x9e\xaa\x6e\xdb\x98\x5d\xc9\x70\x02\x78\x92\x94\xea\xb3\xb9\xc9\xbb\x11\x5c\x62\x9f\x7c\x11\xa1\x10\x94\x10\x03\x6f\x54\x3e\x42\xd9\x0f\xd5\xff\x8e\x03\xdf\x1d\x51\x1c\x08\x33\x00\xe9\xda\x8a\x34\x0c\xbc\xfb\x3d\x9e\x8a\x59\x7f\x86\x25\x86\x7d\xc7\xcf\x2b\xf6\x85\x88\xf4\xff\x4b\xda\x9b\x75\x37\x8a\xab\xfb\xc3\x5f\xa7\x2e\xce\x05\x12\x08\xd0\xa5\xed\x38\x89\x4f\x65\xda\xb1\xab\xab\x7b\x9f\x75\x96\x97\x86\x47\x09\xbb\x30\xf8\x00\x4e\x95\xfb\xd3\xbf\x8b\x47\x12\x93\x71\xaa\xff\xeb\xbd\xd9\xd5\x3b\xc8\xd8\x80\x90\x9e\xe1\x37\x84\x28\xe2\x54\x23\x26\x75\x0a\x02\xfa\x34\x6d\xe5\x8c\x07\x68\xa3\x71\xf3\xf2\x99\xca\x47\x3b\x2e\xc6\x36\xf9\x3a\x17\xfa\x58\x56\xa2\xbb\x72\x06\x2a\xf0\x00\xd3\x85\xd6\xe3\x6d\x97\xc7\x69\x60\x35\x66\x3a\x63\xef\xe1\xbe\xc9\x63\xae\x90\xd9\x02\x1e\xb1\xde\x2e\x07\x50\x35\x19\xd4\x93\x90\x64\xf4\xa3\x63\x88\x30\x86\xd8\x1f\x2b\x78\x54\xb7\x5d\x24\xcc\x13\x1a\x69\xd2\x49\x1d\xe5\xa7\x3a\xfb\xb0\xa4\xe1\xb9\xc2\xae\x2b\x74\x74\x0f\x39\xa1\x31\x02\x5c\x0f\xa7\xbc\xc9\xec\xc2\xdd\xbe\x80\x37\xf3\x9a\xa6\xe3\x77\x9e\x27\xcc\x4a\x64\xe2\xe2\x36\x96\xab\xb9\x72\xe7\xd3\x80\x60\xd1\x7b\xf7\x0e\xf7\x6d\x50\x72\x84\x6e\xe5\xe2\x69\x94\xe0\x5b\xb3\x38\x88\xbf\xcb\x62\x09\x75\x53\x43\x9e\x43\xf5\x20\x64\xfd\xfb\x00\x9c\xa7\x31\xc3\x62\x0a\xde\xd2\x36\x1f\x1d\xc6\x0c\x9c\xf3\xc4\xe8\x81\x8b\xc5\x3d\x6a\x7f\xc2\xaf\xc9\xca\xc7\xb9\x4c\xb0\xa4\x2a\x2a\x99\x35\xed\x1e\x6c\xcb\x9d\x5d\x57\xc4\x0d\x13\x24\x4e\xac\x83\x56\xa6\x00\x5d\x79\x6b\xcf\x18\xbc\xa2\x52\x36\xe6\x39\xd3\x60\xb8\xe6\x73\xa1\x6d\x41\xb2\x0d\xb1\xc4\xf1\x15\x44\xbb\x3a\x76\xdf\x65\x18\x3e\xa2\x9f\x87\xd3\xbc\xa3\xb6\xe4\x92\x28\xa9\x2f\x58\x39\xba\xdb\xf9\xb9\x8c\xa9\xb4\x1a\x6d\xcb\x90\x7e\xf9\xec\x99\x4a\x0d\x34\xf1\xa8\xd4\x03\x3e\xa5\xe5\xf9\x7b\xbb\xe0\x5e\xc5\xbe\x8e\x57\x69\xae\x12\xab\x04\xe1\x90\x70\x28\x99\x35\xf0\x5c\x90\x5c\x41\x2c\x7a\xd5\xaa\x8b\x19\xf3\x9b\x0e\xd1\x6f\x01\x7d\x93\x02\x3a\xd7\x71\x8a\x02\xad\xce\xf8\xc3\x45\x2a\x93\xe7\x0e\x34\x45\x8d\x81\x43\x56\x34\xaf\x70\x25\x6f\xe2\x10\x25\x58\x13\xd9\xe7\xa8\x2f\xe2\xff\xca\x42\x54\x0c\x79\x84\x06\xaa\xed\x90\x44\x31\xdf\x78\xe3\x60\x00\xc9\x0f\xb9\xa8\x2d\x97\x75\x0c\x81\xe3\x46\x80\x2f\xd4\xaf\x77\xf7\xbd\x09\x9f\xe4\xc6\xc4\xb8\xf3\xe7\x60\x1a\x4e\xc6\xdb\x89\x20\x5c\x63\xe6\xb8\xbe\xbb\xdb\xee\x77\xcf\xfb\xfb\xc5\x6e\x75\xbf\x27\xab\xd7\x85\x6f\x4e\x0a\xa2\x42\x2c\xd9\xec\x6b\x25\xd0\x95\xd9\x87\x06\x83\x35\x41\x10\x90\x83\xfe\xd2\x1d\x14\x56\xcb\x66\x74\x0d\xa2\x8d\x0b\xf1\x29\xd7\x0e\xab\x68\x9d\xc1\xa7\xf9\x91\xa0\x29\x47\x05\xc5\xfa\x28\x7e\x16\x83\x6f\xbb\xb8\x2b\x22\xe4\x20\xbc\xe0\x2e\x26\xe5\x5d\xb5\x5b\x84\x00\x83\x28\xea\x03\xaa\x06\xaa\x57\x71\x98\xa4\x43\x22\x62\xb6\x73\x26\x45\x0d\x2f\xa7\x22\xeb\x90\x25\x22\x4a\xa4\xb5\xe8\xcc\x54\x67\x36\x2e\x45\xa4\x14\x12\x1f\xc4\x98\x77\x3c\x7e\xe8\x82\x85\x81\x4f\x30\x6f\xc0\xb4\xb7\xe2\x15\x54\x79\x40\x2f\x48\x7f\x26\x96\x30\x6c\x59\xdc\x9f\x0e\xa2\xd8\x36\xa2\xd0\x1d\xaa\xea\x93\x95\x6b\xfa\x45\x69\x80\xb4\x85\xaa\x8d\xb8\x06\x3b\x86\x60\xa9\xd5\x49\x3e\x88\xe2\x24\xf2\xe7\x0f\xa8\xaa\x4c\xc3\xda\x86\x3f\xf7\xd9\xdb\x3b\xd4\xcd\x32\xd3\x8b\x42\x2f\x33\xad\x2f\x3b\x09\x93\xef\x89\xa3\xd0\x2b\x1b\x5b\xb9\xf8\x0b\x81\xb0\xcb\x1a\x95\x88\x93\xc4\x08\x87\xbd\x7b\xa9\xe0\x90\x9d\x0e\x2f\x62\x4a\x17\x12\x89\xd4\xca\x0a\xde\xb7\x4b\x59\x87\x3d\xb9\x2d\xab\x36\xdd\x99\x3c\xae\x04\x58\x12\xf4\xae\xa2\xa3\xca\xdc\xc5\x4b\xdd\xaf\x96\x22\x81\xc4\xf4\x1d\x0c\x44\x54\x4e\x57\xa6\xd1\x8a\x24\x30\x9e\xf5\xe5\xa7\x42\xe4\xaf\x58\x0b\x9b\xc4\x71\x7e\xac\x16\x38\x5f\x8f\x8e\x75\x37\xec\x7f\x8a\xd4\x18\xe5\x44\x6e\xee\x2a\x71\xec\x40\xe2\x82\xd3\x24\x6e\xdf\xab\xc5\xb2\xbe\x9e\x5f\x08\x1e\x1a\xd4\x4b\x3b\x88\xb7\x4c\x59\xe5\x58\x7f\x44\x24\x58\x7e\xbb\x5d\xac\x76\xcf\xaf\xfb\xa8\xfb\xbb\xe6\xb8\x5f\xae\x0f\x22\xcb\xb7\xc3\xbc\x73\x26\x5e\x11\xdc\x84\xcc\xf7\xb5\x56\x39\x88\x6a\x99\x79\x95\x11\x7f\x42\x41\xad\xd5\x95\x70\x00\xac\xab\x37\x7c\x76\x86\x8a\x54\x5a\xca\x42\x1b\x74\x55\x53\x55\x79\x37\x48\xc6\xd6\x86\xb3\x53\xd2\x41\xcd\xd6\xc9\x98\xd4\x42\xb2\xda\x5f\xfa\xf2\xe3\xcd\xa1\xa4\xfc\x41\xc1\xa8\xb3\xa7\xc4\xb2\x7b\xf7\xe3\x15\x50\xd4\xd1\xfc\x71\x56\x17\x9a\x58\xdd\x90\x84\x24\xde\xaf\x13\x2b\x83\xd7\x59\x56\xdd\x47\x34\x1a\x43\x65\xf5\xa6\xc0\xd6\xf3\xf8\xb0\x66\x1a\x3a\xfd\x92\xc7\xac\x98\xf3\x3a\x92\x42\xa7\x3a\xb5\x4d\x64\xf4\xdb\x19\xa8\x28\xf8\x46\xc1\xff\x4e\xee\xa5\x96\x12\x97\x8c\xf5\xee\x65\x18\xa9\x08\xa0\xc2\xfb\xa2\xe2\x14\xd1\xb7\x99\xec\x8e\x29\xeb\x36\x5f\xc1\x47\xf6\x31\x49\xc7\x05\x80\xc1\x65\xbb\x6e\xca\xe3\x6e\x40\xc0\x10\x26\x26\x48\x8d\x70\x64\x5c\xda\xfd\x3d\x11\x41\x0f\x89\x7c\xa9\x4e\x20\x3d\x78\x49\x06\x51\x8a\x2a\x94\xee\xdd\x7c\x3d\xe5\x53\xc9\x7a\x29\x03\x23\x00\xfa\xd2\xd7\xcc\x8c\x94\x84\x47\xa1\x25\xa3\x7b\x65\x8b\xd9\x00\x46\x12\xc1\xc0\xf4\x5f\x77\x03\x83\xe4\x78\x74\x42\x1a\xf4\x45\x27\x71\x6c\x44\xe6\xbd\xf9\xfa\x2e\xf6\x44\xa5\x41\x4a\x9a\x5a\xfd\xa4\x43\x56\x0c\xa1\xb7\x32\x0c\x12\x9f\x0b\x3d\xda\xa7\xd5\x55\x6e\xfd\x88\x38\xc5\x1a\xf2\xb1\xcc\xf3\x1b\xd1\x08\x54\x23\x7c\xef\x11\x8b\x92\x31\x85\xd6\x3f\x12\xb9\xf8\xd6\x99\x05\x6e\xcb\xea\xf6\xd4\x9c\x2a\x5b\x31\x9c\x5b\xd6\xfc\xa7\xb5\x35\x39\xaa\x7b\xc9\x96\xf1\x80\x38\x12\x12\xba\x5a\x70\xfb\xf0\x2c\xa9\x78\x34\xf7\x64\xc2\x18\x26\x14\x35\xf2\xe6\xe6\x1e\x43\x92\x12\x8b\x06\x3c\x55\x8f\xe2\xd7\xb2\xcb\x6b\x65\x9a\x18\x84\x1f\x64\xf5\x4e\xf4\xf5\x59\x7f\x30\xd5\xb8\xc5\x23\x8a\x05\x75\xd8\xbb\x8f\x49\xaa\x87\xc2\x8f\x2f\x50\xf5\x45\x4d\xc9\x43\xe2\x85\x9e\x9e\xe0\x17\xca\xa5\x2e\x9a\x1f\x73\xdd\x70\xc9\x0d\x58\x5e\xa2\x1e\xca\x57\x5f\x3c\x75\x41\xa2\x50\x8d\x6b\xbc\xc3\xe6\x8b\xff\x62\xa1\x21\xc2\xc0\xa5\xd6\x83\x9f\x23\x19\x8f\x7a\x92\xbc\xad\x5d\xbb\xbd\xf3\x9f\xe6\x8d\x57\x63\xcd\xb9\x55\x52\x4a\x26\x8c\xc7\x91\x91\x5b\x91\xe5\xdd\x0f\x94\xb1\x25\x6c\x6c\x1a\x38\x38\x44\x75\x77\x88\x1b\x2c\x7c\xc9\xd3\xd9\x37\x4f\xc6\xb7\x4a\x2a\x3b\x5b\x97\x59\x53\x88\xc2\x79\x9d\x0d\x65\x27\xdd\x38\x1d\x06\xb8\xd9\x2d\x1f\x76\xc3\xad\xc8\x1f\x15\x09\x84\x7d\x3d\x0a\x7a\xc5\xe2\xc1\x0e\x2b\xb5\xb2\x84\xd2\x7d\x87\x52\x98\xeb\x3e\x7d\x9e\x65\x4b\x6d\x04\x86\xf9\x4e\x13\xd7\x36\x87\x2e\xf3\xca\x2e\x50\x97\x10\x04\xcc\xc9\x20\xdc\xb5\x81\xa7\x98\x74\x00\x24\x44\x89\x6d\xab\x21\x64\x6a\x57\xf6\x3e\xae\x52\x82\xe2\xd8\xa1\xb0\xf2\x46\xfb\x5d\xba\xfe\x73\xbf\xb8\x79\xdc\x3c\xf9\x01\x26\x08\x13\x87\x02\xf4\xd8\xdd\xb9\x6c\xfb\x37\x17\x65\x18\xc1\x6a\xf1\xcd\xf3\xf7\xfd\xf7\x0e\x8b\x24\x4d\x12\x22\xd6\xf3\x36\x3f\xaf\x44\x35\x74\xa2\x97\x2a\x08\x52\x94\xfc\xfa\x55\x89\xee\x4f\x11\xd8\xb3\xac\x57\x9b\xc7\xc5\xc3\xd6\x6e\xfb\xdd\x51\x16\xfb\x1a\xe3\x53\xd9\x88\xea\x3c\xcb\x61\x50\x01\x4b\x03\xf7\xee\x60\x0b\xfc\x0a\xa5\x78\xf4\xfb\xdb\x0f\x85\xa1\xf7\x37\x9e\x28\x11\x49\x15\xc8\x14\xab\x82\x99\x47\x78\x5a\x42\xee\x6e\x64\x6c\x2f\x15\xa1\xc6\x02\xe1\x07\x52\x03\xbe\xec\x13\x8d\x5a\xe3\x3d\x08\xe3\x33\xae\x89\x22\x5c\x6a\xd1\xb7\xca\x8d\xc9\x47\x12\x45\x12\x1d\x54\xa3\x0e\x76\xa1\x40\x3f\x95\x7d\x5c\xa0\xc2\x20\xe0\xae\x81\x71\x53\x95\xc7\xee\xef\x91\x88\x2d\x7f\xb4\x68\x43\xd5\x1b\x50\x58\x0c\x1e\x4f\x2a\xc5\x52\xeb\x0a\x6d\xcd\x3f\x1b\xf1\xd6\x55\xc5\x15\x13\x02\xa3\x2f\xe4\x9a\xb4\x41\xff\x07\x54\x5d\x5e\xae\x98\xb4\xae\x52\x6f\xbd\xc4\x34\x46\x3a\xfe\xb0\x49\x9d\x46\x40\xa1\x27\xf2\xb0\x93\x67\x12\x8b\x04\x11\x3e\x42\xff\xe7\x54\x37\xab\xd3\x95\x36\xaf\x4a\x82\x04\xb5\x37\x96\xbb\xdf\x66\x16\xfe\x13\x46\x70\xb7\x6e\xae\xda\x04\x67\x7c\xbe\x94\x49\x8c\x34\x50\x46\xae\x87\x95\xa9\x34\xd5\xf8\xa6\x14\xe2\x00\x68\x38\x38\xbb\x28\x2b\x9e\x24\x18\x6d\x1e\xcb\xa3\x6a\x63\xe4\x51\xa8\xac\xb8\x8c\xad\x04\x44\xa1\x9f\x0d\xda\xf3\x8f\x67\xaf\x20\xd6\x30\xd3\xf1\x5e\xea\x95\x28\x50\x34\x60\x32\x4a\x73\x7c\x38\xd8\x7d\xaa\x1b\x44\x68\x5b\x9c\xdf\x78\x9c\x8c\x28\x76\xa0\xf7\x38\xaf\x76\x65\x6f\x49\xe5\x07\xc4\x26\x70\x58\xd7\x87\xb2\xee\x48\xdc\xbd\x72\x94\x54\x52\x04\x08\xb9\xdf\xf7\x22\xec\x17\xa4\xc3\x99\x74\x44\xb5\x79\xa7\xe8\x4a\xcd\x2f\xa2\x6a\x9e\x4d\xef\x1f\x8d\x49\x50\x3f\x69\xa4\x8c\x11\xd8\x2a\xa1\xa9\x17\x15\xbc\x88\xf3\xb5\x2e\x8f\x52\xae\x0a\xd0\x78\x2d\x9e\x89\xd4\x8f\x54\x4a\x12\x44\x5a\xac\xcb\xfa\x25\xfb\xfb\x6f\xb1\xcd\x2f\x34\x4b\x94\x92\x26\x76\xe2\x62\x18\xfc\xcc\x8b\xd8\x4b\xa5\x03\x2b\x73\xd9\x7d\x49\xf6\xf2\xfa\xfc\xb4\x7b\x7e\xc8\x3e\x7a\xbb\x2d\xa9\xb4\xb6\xb4\x3e\xbc\x8f\x6f\xf5\xd3\xe9\x0a\x72\x5f\x69\x50\xda\x05\xe2\x9b\xba\x3e\x4d\x89\x21\xe3\x18\x5c\x41\x60\x19\x86\x15\xd4\x65\x6e\xa5\xc1\x7d\x8f\x64\x56\xce\x66\xf2\x65\x20\x18\x56\x3e\x3e\x32\xf8\xb9\x2a\x0f\xc7\xb2\xb8\xda\xa2\x53\x26\x00\x54\x2d\xbc\x5b\x2d\x5e\xfc\x55\x99\x38\x42\x90\xc4\x1d\x34\xaf\x6d\x1c\x74\x1a\x60\xc1\x94\x31\x11\xc1\x7d\xac\x3e\x17\x6a\x3b\x23\x39\x3f\xfe\x02\x1d\x84\x04\xd9\xee\x56\xff\x00\x2f\xfe\xcb\x64\x84\xb4\xb6\xfc\x42\xeb\xd5\x7b\x96\xcf\x6b\xd8\x4b\x1d\x18\x4b\x92\x70\x32\xde\xcb\x76\xb7\x1b\xad\x9b\x9a\xc8\x18\x09\xa5\x76\xc0\x0e\xcb\xa5\xee\x9a\x34\x65\x29\xaa\xfe\xfd\xa7\xcc\x8a\x47\x2c\x1c\x8c\x6e\x48\xe4\x12\x7b\x1d\x06\xd6\x05\xf8\x2b\xfc\x18\x6e\x5b\x3a\x24\x09\x58\xa0\xdd\x27\x04\x0d\x1d\x26\x5c\xb6\xab\x5c\xd6\xdc\xc0\xc7\xa0\x22\xa2\x59\x10\xa5\xed\xee\xf4\x52\xe6\x99\x3a\x4f\x45\xd6\xc7\x59\x6c\xf7\x11\x65\x05\x5b\x7b\x96\x17\x36\x39\x06\x3c\x4e\xcd\x42\x09\x62\xc0\xc6\x46\x11\x71\x7f\x2c\xb6\xae\x9e\xdf\xff\x5c\x75\x7f\xd2\xa1\xd5\xf5\x51\x65\x05\xd8\x68\xac\xaf\x2a\xa9\x8d\x6f\x6d\x4c\x0c\x1d\x7a\x5e\x8c\x0b\xaa\x3a\x8e\xad\x7c\xca\x63\xa9\x33\x73\x6e\x57\xc9\x2f\xa3\xfa\xe3\x27\x68\x61\x1d\x6b\x41\x7a\xd1\x2c\x79\x6a\xe0\xcf\xc5\xe6\xe9\x72\x7b\x98\xdc\xea\x24\x66\x98\xfd\x3a\x49\xa4\xb1\xad\x81\x1f\xc3\x29\x9a\x21\x2d\xb3\x46\x95\x59\xb1\x12\xf5\xbb\x93\x38\xee\x46\x68\x2b\xb1\x56\xb7\x8b\xc1\x4b\xe9\x57\x3f\x9d\x52\x49\x03\xdf\x76\x5c\x89\xee\x42\xd3\x38\xe6\x43\xaa\xc2\xc2\x99\xb2\xd7\xde\x16\xce\x8f\x4b\xac\x29\x4e\xfb\xb0\x1e\x85\x7a\xcf\x8a\x51\x14\xa4\x05\x61\x91\x3b\xff\x73\xde\x75\x4c\x66\xeb\xa3\x5a\x28\x82\xfb\xf9\xd7\x87\xed\x3f\xdc\xe9\xb4\x94\x0a\x15\x0e\xdb\x9d\xc6\x09\xcc\x5d\x2d\x6d\x7c\xfe\xfa\x4a\x00\xeb\xb9\xd2\x54\xfb\xdc\x82\xeb\x46\xdf\xa4\x18\x4b\x9d\x0f\xe5\xfb\xbe\x2f\xcd\x6a\xc5\x04\x06\x1b\x3f\xa7\x28\xce\x51\x83\xeb\xca\x6c\x83\xc4\x60\x26\xb8\xca\x33\xf5\x63\x79\x6a\x9a\xb2\xbb\x71\xc6\x90\xd8\xed\x5c\x03\xf5\x2b\x09\x24\xb0\x6b\xd6\x9b\xd5\x14\xbf\xad\xca\xc3\x08\xff\x36\xbe\x2c\x20\xa1\x4e\x2c\x09\xee\x84\x05\x3f\x0c\x89\x7a\x42\x0b\xea\x59\x3a\x7e\x8f\xf3\xa5\x78\x36\x28\x66\xe6\xe8\x2d\xe7\x75\xd1\x64\xcd\x44\x9a\x04\x42\x91\xa2\xce\xda\xfe\x23\xf4\x27\x0a\xb5\x41\x01\x94\x8f\xec\x88\xa1\xda\x01\x8a\x36\x8c\xed\xc4\x83\xba\xbd\x10\xa2\x30\x74\xd8\x02\xf5\xa3\x7e\x81\x0a\xb7\xca\xee\x60\x9a\xa2\xc6\xed\xcb\xb7\xe5\xc3\x66\xb5\x7f\x5d\x6f\xd7\xaf\x7f\x74\x01\x37\x30\x9a\xa4\x16\x20\x33\x36\xfe\x7d\xa9\xc0\xb2\xad\xbf\x8c\x9a\x1b\x9f\x47\xf5\x90\x08\x1b\x66\x78\x44\x89\xf5\x97\x9d\x37\x7d\x99\x7e\xd4\x44\xa8\xca\x77\xfb\xfc\xed\xe9\x66\xfd\xba\xbf\xfd\xf6\x74\xe3\x9d\xa3\xdb\xa3\xb6\x70\x6d\x4d\x36\x3c\x9d\xb6\xae\x3d\x03\xfd\x4a\x3e\x79\x55\xfe\x5e\x42\x6a\x78\xe4\x79\xe5\x58\x5f\xd8\x9b\xd8\x7f\x1b\x0f\xac\xdb\xa6\xa7\x0a\x7c\x87\xac\xa7\x8d\x00\x0f\x24\xc2\xc2\xc4\x07\x54\xe2\x0d\x3a\x97\x18\x7f\x38\x12\x18\xaf\xde\x89\x76\x17\x39\xef\x1f\x4f\x7f\x65\xfb\xa7\xb2\xbb\x14\x9e\x50\xdb\xe5\xd8\x3c\xed\x11\x14\x87\x3d\x86\xf5\x9f\xab\xfb\xc5\x53\xa7\xfc\x05\x5c\x09\xac\x50\xdd\x41\x55\x65\x03\x31\x66\x09\x22\x16\xf6\xbd\x12\x06\xb6\x27\xd9\x54\xe1\xcd\xc3\x95\xb9\x2a\x14\xc5\xfe\xc8\x76\xb7\x58\x0f\xb9\x3f\x20\x89\x40\xa0\xa3\xcb\x90\x87\xd5\xba\xdf\xb5\x8b\xfc\x19\xe2\x40\xc6\xde\xfe\xf0\x90\x15\x53\xf3\x0c\x09\x92\x1b\xf4\xa7\x3f\x94\x1f\xb6\x80\xd3\xab\x99\x5e\x13\xea\xee\x3f\xdc\x26\x05\xa4\x2f\x03\x5e\xc1\x6d\x81\x8a\x53\xdf\xe0\xd9\xdc\xec\x95\x55\x26\xf2\x17\x09\x34\x22\x72\x40\x89\x99\x88\xe6\x4b\x80\xc4\x26\x94\x48\x2c\x6c\x43\xba\xf6\xdd\x6f\x23\xd9\x8b\x12\x1d\x18\x46\x29\xf2\x07\x9f\x9f\x6e\x37\x77\xfb\xc7\xc5\x9f\xfb\xdd\x66\xf5\x75\xbd\xdb\xfa\x93\x99\x44\x0a\x36\xe0\xe4\x8f\xa1\x8b\x76\x90\x09\x84\xa5\xc8\x1c\x9d\xd6\xe5\xb8\xb4\x39\xbe\x07\x86\x84\x96\xe5\xff\x6d\xb7\xda\x36\xa5\x9f\x7e\x26\x8c\x68\xe8\x82\x9e\x17\xcb\x23\x9d\x7c\x49\xc8\x42\xdc\x16\xdf\xb2\x0f\xf8\x44\x27\x7a\xfc\x65\x11\x23\xcc\xca\xac\x0b\x3d\x0c\xf8\x0d\x4b\x4c\x04\x5e\xc5\xed\x00\x75\x73\xd1\x2e\x32\x71\xc0\x42\xd7\xea\xf4\x22\x7c\xb3\x3d\x01\x13\x53\x83\x78\x01\x2c\x84\x95\xc7\x32\x3f\x6f\xdf\xab\xec\x70\xbc\x15\xd5\xe1\x72\x70\x1a\x73\xa7\x17\xdf\xcc\xcb\xcf\xce\x15\x9d\x5c\x34\x66\x92\x88\x61\xfb\x75\xfd\xb8\xd9\x6e\x37\xcf\x4f\xfb\xdb\xe7\x57\xd4\x67\xd9\xee\x16\x77\xeb\xc4\xdf\xcc\x94\x01\x4a\x3b\x6d\xb3\xb7\x83\xd8\x3c\x0f\x77\x5a\x93\x26\x84\xce\x2b\x67\x8e\xe2\xbf\xc0\x0f\x17\xd6\x78\xf4\x0d\x9a\x45\xe3\x96\xe8\x59\x7e\xa4\x11\x91\x8c\xc0\x87\x44\x0b\x8b\x30\xf7\x5f\x2a\x54\x28\xe5\xd5\x69\x34\x55\xab\x1d\x3f\x43\x19\x24\x8a\xf7\x88\xd7\xdf\x3c\x71\xa9\x12\x16\x76\xf4\xba\x91\xc8\xa2\x1b\xa1\xa8\x09\xc3\xc1\x0b\x74\xb3\x78\x9e\x03\x94\x1a\x08\x04\xa8\xbe\x4e\xb9\xfe\x35\xa5\xf8\x18\x88\x00\xb3\xb5\x3b\x91\xe5\xf9\x44\x27\xc1\x40\x9a\x62\xfe\xbf\xa8\x1a\x38\x99\x59\xdb\x52\x37\xd2\xa8\xc4\x0a\x55\x0a\x4c\x62\x61\xac\x3f\x62\x8c\x61\xc2\x11\x65\xbc\x98\xac\x90\x39\x20\x1b\x6c\x14\x54\x0e\x7f\xbe\x0a\x82\x90\x20\xe9\xcc\xd6\x4b\xf6\x1b\xb7\x37\xaa\x20\x50\x80\x90\xd4\x53\xf1\x2e\xf2\x66\x1f\x06\x9d\x72\xa1\x0a\x08\xb5\xf4\x99\x2e\x9c\x2b\xb4\x65\x1d\x60\x69\x7b\x56\x53\x6c\xe6\xbf\xdc\xc9\xa8\x23\x94\xb5\xcb\xca\xd3\xb7\xc7\xe5\xfa\x75\xff\x7c\xbb\x7f\x79\x5d\x3f\x6e\xbe\x3d\xda\x59\xeb\xbf\x97\x42\x60\x1d\x2f\xc5\x07\xd0\xf1\xb4\x18\x4e\x32\x15\x44\xc4\x16\x1f\x40\x67\xcd\x4b\x55\x9a\x2c\xef\x99\x3d\x83\xc0\x7a\x78\x3f\x06\x1e\xe7\xd3\x21\xfe\xa4\x34\xc4\xae\x10\xd6\x78\xfe\x75\x12\x1d\x22\x53\x05\x91\xe4\xb8\xad\xb5\x0b\xc8\x16\x5c\x70\x3b\x94\x8e\x50\x41\x1c\xc6\x69\xec\x65\x56\x72\x71\xee\xfd\x3a\xfd\x00\x23\xb0\xe3\x65\x31\x57\x2f\xaf\xeb\x2e\x61\x56\x41\x9a\x6a\x14\x2c\xfe\x99\x15\xce\xcb\xa8\x5d\xdc\xba\xa3\x02\x82\x21\x70\x03\x57\x98\x4e\x53\xd5\x8f\xe2\x24\x44\xca\xbf\x29\x4f\x95\xaf\x6b\xab\x80\xa7\x1c\x8d\x80\xf1\xb4\xae\xa4\x69\xd5\x33\xc6\x78\x41\x15\x70\x69\xac\x72\xc1\xfb\x00\x2b\xe5\x8e\x89\x88\x18\xcb\xdb\x93\x0d\xd4\x05\x74\x57\x2d\x09\x4b\x7b\xa2\xda\xd3\xed\xee\x52\x46\x7b\x2e\x81\x8a\xfc\xc7\xc3\x04\xf7\x70\x88\x55\xcc\x80\x87\xdd\x69\x23\x01\xac\x57\xd4\xab\xad\xd6\xc6\x67\xd8\x42\x15\x48\x01\x4c\xf6\x0b\xc4\x2b\xe8\xbe\xbe\xe2\xcf\xab\x82\xd0\x42\x33\x9c\xca\xc3\x73\x01\xbd\x08\xa5\x0a\x14\x57\x08\x0d\xb0\xeb\x93\x87\xf3\x2c\x64\xf6\x65\x34\xfb\x94\xb1\xf1\xac\xb6\x72\xc1\xfe\xd3\x3a\x50\xd4\x72\x30\xab\x1f\xdd\xdf\x22\xd2\xc1\x4a\xae\x8a\x52\x5d\x54\xb9\x55\xa0\x63\x6b\xdf\xb2\x3a\xd5\x4d\x79\xb8\x01\x91\xb7\xb3\xe5\xff\xb1\xf1\xe0\xcf\x25\x94\xa1\x5d\xfe\xff\x8a\xd4\xde\x51\x89\x40\x05\x1a\x00\x4b\x80\x56\x48\xa2\xec\x6a\xb9\xcb\x73\xbb\x0b\x67\xa3\xae\xff\xb5\xab\xb0\xaf\x69\xbf\xbb\xa2\xa3\x0b\xaa\xb9\x8f\x58\x35\xf3\x6c\x1a\xff\x09\x6a\xd9\xec\x56\xdd\x0d\x9c\x7c\xdd\x6f\xea\xd5\xed\xc7\x84\x0b\xa8\xde\x50\x2c\x6a\x32\xb3\x21\xb2\x68\x47\x64\x72\x96\x47\x28\xbc\x40\xc9\x6b\xef\xc5\xa2\x02\x10\xd6\x11\x7b\x6f\x9f\xfe\xe3\xc3\xd2\x36\xa3\x36\x7a\x36\x84\x51\x01\xa8\xc0\x16\xb8\x2d\xa1\x25\xcf\x06\xe5\x24\x37\xc4\x04\x29\x75\x6a\x20\xb7\x0f\x5f\x6f\x6e\xcb\x6a\xda\xaf\x50\x81\x49\x81\xb8\xd4\xcd\x1a\x20\x6c\xd5\xd4\x2d\x56\x05\xc6\x30\xa7\x87\xfd\xcb\x13\x00\x3d\x21\x4d\x91\x20\xb6\xc4\x01\xa1\xb5\x6d\x29\x5f\xf8\x23\xf9\xc5\x98\x10\x16\x62\xa8\x97\xd5\x2f\xf4\xe5\xeb\xfd\x58\xc8\x6b\x7c\x7d\x84\xa4\x0a\xe3\xe8\x0f\xa8\x32\x73\xbe\x3a\xf9\xe6\x71\xf4\xd4\x7f\x23\x0d\x29\x36\xd6\x1e\x33\xdf\x53\x55\x84\xb2\x18\xed\xc5\xfb\x6a\xf9\xec\x73\x25\x54\x85\x18\xb7\x2d\x77\xdf\x9f\xf7\xab\x87\xc5\xe6\xd1\x4b\xcf\x75\x67\xd2\x29\x86\x38\xa2\xca\x9a\xf7\x03\x34\x99\x9a\x0f\x38\x15\x09\x43\x81\xd0\xe3\x63\x05\x1f\x59\x9e\xbd\x81\x9e\x0d\x63\xdb\x81\x0a\xc5\xcf\xed\x63\x5d\xc2\x8c\x9f\xb4\x22\xa1\xb0\x3d\xd7\xf6\xbd\x76\xfe\x47\xe3\x01\x91\x96\xd8\xde\x44\x1d\xd7\xf7\xaa\xfc\x59\x63\xae\x85\x78\xe1\x4d\xa1\xca\xaa\x02\xd5\x0c\x20\xc6\x8a\x30\x26\x99\xdb\x74\x35\xdc\x96\xd5\xc4\x5f\x81\xfe\xef\x78\x49\x1d\xbe\x69\x84\xc5\x94\x84\x03\x2b\xbe\x11\xdc\x65\xb8\x76\x91\x38\xb0\x50\x73\xbb\x18\x6c\x8a\x31\x32\x58\x91\x98\x91\xc8\xe3\xf2\x06\xe0\xff\xf6\x00\x0f\xa9\xeb\x54\x74\x4a\x25\xbd\xac\xdb\xf8\x1e\xc6\x49\xe0\xf9\x2e\x56\xd3\xc9\xd6\xd0\xc7\x83\x12\x6a\x7c\x67\xdd\xb2\x25\xc6\xbf\x24\x51\x4c\x48\xdf\xe0\xfa\x79\x61\xa7\xa9\x48\x62\x94\x97\x60\xfe\x0e\xe2\x58\x16\xf5\xa2\x3a\x9c\xe9\x64\x14\x4f\x92\xd0\xe1\x8a\x97\xc3\x55\xd8\x1f\x56\x24\x61\x1e\x48\x21\x50\xe3\xb8\x99\x7e\x11\xd7\x54\x75\x0c\xc3\x83\x14\xcd\xf7\xb2\x68\xf7\x96\x59\x8d\x2b\x45\x84\x8c\xb0\x28\xd8\xbf\xa8\xa5\xb9\x14\x22\x53\x44\x25\x02\x59\xc2\x99\x2a\x3b\x89\x33\xea\x6f\xb7\x0e\x08\x92\xe9\xb4\x05\x93\x79\xdc\xa8\x3f\x1a\x09\x2c\x9f\xdc\x55\x00\xc5\x5a\x95\xd8\x80\x19\x84\x8b\x8a\x68\x6e\xad\x64\xfa\xf2\xa1\x4b\x87\x2f\x6c\x3b\x26\xf1\x1a\xd1\xdc\x60\x66\xe6\xf4\xe0\x3a\xde\xe4\xe4\xf1\x40\x10\x89\x78\x88\xff\x73\xf9\xe7\x4d\x36\xe9\x01\xbb\x66\x8f\x22\x40\x89\xee\x44\x72\x46\xea\x2b\x8a\xb4\xb9\x0a\x16\x48\x00\xb6\xd0\x9c\x8e\x9f\x86\xf7\x8a\x06\x31\x47\xd2\xe3\xde\x58\x32\xec\xe4\x68\x4a\xb0\xdc\x6c\xdb\xdf\x75\x5f\x5f\x50\x94\x24\x1a\x65\xcb\xfe\xae\xff\xf3\xf7\x27\xa8\x6e\x45\x89\x89\xa5\xf4\x2d\x0c\xf5\x03\xb4\x25\xa0\xf4\x59\x58\x3b\xc4\xa0\xe8\x4f\x8d\xdd\x51\x3b\x6a\xe9\xbf\x88\x0a\x85\x4d\x7c\x87\x7b\xdc\x5b\xb6\xc8\x78\xf2\xd1\x30\x60\xd6\x1e\xa6\x41\x5b\x9a\x5c\x4c\x2e\x84\x45\xb1\x75\xad\xc9\x8a\xe6\x8a\x88\x6e\x37\x52\x61\x0e\xf2\x13\x17\x98\x1b\xf8\xf0\xbf\x83\xf1\x98\x45\x3e\x2c\xb5\xbb\xde\x8d\x68\xc4\x58\xa2\x4b\x51\x66\x18\x66\x6d\x79\x56\xfc\xf0\xfd\xac\xc9\xc2\x48\x63\x02\xd4\x65\x42\xed\xfa\xf2\x9a\xbd\xbd\x37\x2f\x42\xfb\x53\xc4\x89\xc4\xa8\x48\x1d\xca\x11\x52\x55\xd1\x58\x84\xae\xaa\x6b\x57\x27\xec\x05\x2f\xcf\x58\x5a\x69\x5f\x92\x17\xa4\x0d\xfd\xae\x44\x73\xb5\xdc\xa5\x68\xac\x38\xe6\xe8\xdb\xdd\xbf\x5e\x2a\xd8\xac\x9e\xc3\x1d\xd4\xcd\x3d\xe4\xc7\x2b\xae\xf6\x8a\xc6\x20\x11\x7e\xb1\x7e\xab\xa0\xc9\x86\x62\xbf\x8a\x26\xd4\xaa\x39\xed\xe5\xe9\x7c\x05\xa6\xa7\x68\x12\x0a\x9e\xfa\x1b\x6b\x2e\x11\x37\x8a\x26\x09\xc7\xa2\xdf\x5b\x99\x6b\x6f\x7d\xd5\x94\x55\x57\x4e\x55\xb4\x5d\x29\xc1\x96\xb0\xee\xd6\xfb\x76\x93\x5b\xef\xee\xd1\xc4\xae\xbb\xab\xa9\xd1\x31\xb8\x29\xe0\x2e\xc8\x1d\xe1\x31\x95\xbc\x73\x23\x58\xbc\x5d\x44\x1f\x94\x73\x8d\xd0\xad\x85\x2e\x91\xbf\x81\x54\x9b\x5e\x99\x03\xdf\x67\xe6\xc7\x4a\xe5\x23\xee\xff\x2e\x4f\x13\x5c\x89\xa2\x82\xf1\x30\x1d\x88\xdf\x81\xde\x95\xce\x03\xa1\x17\x37\x53\x54\xa6\x14\x0b\xae\xdf\x21\x7b\x10\xd9\xfa\xd7\xe8\xb6\x6a\xc2\xbc\x38\x14\xa2\x0a\xda\x45\xab\xbb\x4e\x1d\x72\xe4\xc4\xed\xda\x74\xbc\x12\x87\xe7\x23\x14\x4f\x80\xd4\xaf\xb1\x9c\x97\xa2\x10\x4b\x5c\xd1\x2d\x56\xa4\x8d\xdf\x2f\xdc\xcf\x14\x35\x41\xa4\xf9\x68\xfd\xfb\x56\x67\xc5\x1b\x82\x94\x2f\x42\x84\x59\x04\xb6\xa2\x26\x8e\x9c\x4c\xa2\x13\xa4\xf3\xe2\x8d\x33\x11\x41\x18\x04\x09\x1f\xba\xe1\x5e\x24\x1f\x61\x90\x24\xdc\xf3\x24\x3f\x44\x96\xb7\xe9\xfb\x1f\x80\x05\x39\x97\x4a\x8e\xbe\x3e\x0c\xd2\x14\x71\xa4\xf7\x50\x65\x28\xe1\x35\x56\xc0\x9a\x5f\x1a\xc3\x20\x15\x58\xc2\x5f\x14\x70\x28\xb3\xcf\xd6\xb8\x90\x84\x0c\x13\x83\x63\x59\xe6\x43\x64\x9b\xff\xc1\x44\xc7\x89\xab\x8e\x3d\x95\xcf\x66\xeb\x99\x2a\xfe\x38\x8d\x62\xc4\x5b\x60\xc1\xd0\x16\x7b\xad\x5b\xc2\xe6\xe9\x8f\xf5\x76\xf7\xfc\xba\xed\x46\x2a\x86\x79\xd7\xe2\x13\x0c\xb5\x0a\x29\x24\x89\xc5\x58\x3e\x0a\x3b\x75\xea\x11\xcb\x41\x85\x61\x44\x30\xef\xff\x2e\xda\x65\xaa\x5b\xd6\xc3\x90\x49\xd4\x47\x28\x15\x88\x62\xd0\x00\x51\x61\xc8\x05\x3e\xc3\x7f\x6d\xef\xbf\xad\x9e\x3d\xd0\x47\x85\xa1\x60\x88\x41\x7e\x5d\x6f\xd7\x8b\xd7\xd5\xfd\x7e\xf1\x74\xb3\xbf\x59\xff\xb1\x7e\x78\x7e\x79\x5c\x3f\xed\xfc\x05\x8d\xe3\xcd\x30\x0a\x2d\x9a\xb1\x5d\x5f\xb0\x69\xdb\xfd\xb4\x28\xb6\x15\xbd\xa6\x7c\x7b\xcb\xe1\x5e\xe4\xcd\xe0\xc5\x08\x23\x2d\xc1\x1a\xe2\x62\xcb\xcd\x27\xed\x61\x1c\x1a\xdc\x13\x17\xb2\xc6\x39\x3e\xba\xbf\x71\x6c\xa5\x70\x0a\xf8\xe9\x69\x12\x16\x88\x33\xbe\x6d\x31\xb7\xe6\xe3\xc7\xf2\x78\x09\xf5\x52\x61\x2c\xc0\x5a\xeb\xe5\x20\xbc\xca\xcb\x78\x44\x12\xe9\x54\xf7\x99\xf3\x54\x7e\xc5\x8f\x62\x21\xf6\xea\xbf\xaf\x37\xe8\x91\x71\xbb\x79\x7a\x5a\xff\xe5\x7f\x6b\x92\x28\x0c\x07\xbe\x15\x8e\xb5\x3a\x54\x5b\x99\x9c\x88\x13\xac\xbc\x7d\xc7\x0a\xcb\xdc\xc4\x4c\x14\xd8\x89\xe5\x8b\x60\x4b\x51\x77\xb3\x32\x01\x6b\x18\x64\x79\x8d\x7e\x9a\x60\x25\xbd\x1f\x12\x7a\xff\xee\xed\x51\xfc\x2c\xb2\xe2\x6d\xae\x66\xdb\x0e\xb4\x48\xf4\x6f\xdb\xa7\x8b\xd7\xea\x33\xb4\x5f\x17\xec\x85\x29\x05\x4c\xa8\x10\xf8\xbb\xa9\xb1\x6b\x83\xe8\x0e\x6c\x7b\xce\x61\x9f\x55\x98\x46\x31\xaa\x4d\xac\xca\xa2\x3e\x1d\x10\x66\x92\x0d\xb3\x5b\x3f\x0c\x2c\x83\x79\x8f\x4f\xce\xed\xa9\x9d\xe9\xd6\x05\xf8\x4f\x85\x5c\x1a\xec\x88\xde\x54\xa0\xdf\xaa\xed\x4f\x71\xdc\x96\x79\xe9\xd6\xf9\xff\x1a\xfe\x33\xe3\x01\x76\xe5\xef\xfe\xd4\x4a\xf2\xd0\x91\xb1\x6d\x07\x6e\xbe\x58\xfb\xe9\x5d\x4b\x27\x27\x95\xb1\x15\xb8\x43\xe0\xd1\xb9\x6e\x44\xde\x86\x91\x5f\xb3\x42\x7f\x87\x36\xb8\x98\xcc\x73\x15\x04\xa8\xea\xd4\xa6\x8c\xba\x12\xc6\x35\x1d\x47\x65\xb8\x50\x45\x32\x74\xf1\x4e\x1b\x2e\x39\x3c\x89\x3b\xa8\x99\x2d\xdc\x3c\x2e\x9e\xee\x17\xbb\xdd\xe2\xe9\xe5\xf5\xf9\xcf\xbf\xe8\xd3\xcd\xe2\x8f\xb5\x1f\x03\xc4\x60\xd6\x7b\x28\x35\xfc\x3a\x4e\x12\xe4\x41\xce\x15\x02\x07\x22\xba\xf4\xf8\xaf\xf2\x54\xd5\x90\x9b\x2f\x33\xc5\x6b\x15\x9a\xc4\x4a\xb2\xee\x7b\xdf\xf9\x5d\x65\x0d\x34\x47\x6f\xbc\xe1\x04\x93\xe5\xfa\x68\x5b\x15\xfd\x02\x62\x04\xa0\xf5\xdc\x12\xe0\x5b\x31\x68\xb1\xce\x2d\xec\x51\x10\xd9\xcc\xbd\xc6\x6d\xa3\x5e\x65\x48\x1b\x1c\xfd\xa4\x88\x84\x1c\x4b\x3e\x1f\x19\xfc\x0c\x9d\xae\x84\x8a\x88\x26\x88\x80\x7a\x28\xdf\x3a\x13\x95\xce\x14\x7b\x34\xdb\x22\x4a\x52\x62\xa3\x6c\x73\x2a\xf4\xb5\x46\xa8\x1b\x1c\x05\xb1\xb7\xc8\xd8\x14\xc7\x13\xb2\xc6\x3e\x65\x01\xaa\x28\x0a\x03\xe9\x40\xdc\xb7\x59\x21\xf2\x07\xab\xf7\x3a\x07\x73\x54\x51\xa4\x24\xed\x14\xc3\xb3\xb2\xf8\xd7\x49\xd8\x4e\xb4\x3f\xae\x0d\xa6\x04\x32\xd3\xf5\x5e\x95\x87\xe3\xa9\x01\xbd\x57\xa7\xaa\xeb\x4e\xa8\x88\x29\x43\x2d\x2d\x45\xff\x77\x29\x7d\xd4\xe1\x25\x1d\x67\x40\x1a\x2a\x8a\x09\x70\xd7\x1c\xc2\x06\xa0\x73\xa8\x99\xdc\xea\x58\x25\xa8\x61\x23\x3d\x05\x7e\xef\xbf\x32\xd1\x5a\xa9\xce\xb1\x6b\x00\x95\x50\x51\xca\x6d\xe1\x16\x45\x78\x9e\xcd\x4b\x2e\x0a\xb8\x0a\xae\x75\x9f\xf1\xdd\x57\x1b\x19\xb9\x3b\x85\x36\xba\x97\xab\x5b\x37\xb5\x22\x11\x5b\xf0\x97\x86\x1c\x59\xe2\x57\x42\xe6\x48\x98\x84\xf6\x66\x40\x4f\xf0\x13\xf5\x7a\x6e\x20\x9f\x78\x91\xa8\x48\x06\x0a\x37\xdd\x5b\x4c\x7a\xb0\x40\x3f\x30\x49\xec\xbf\x59\x06\x90\xb8\x75\x1a\x15\x4a\xb2\x29\xfd\x47\x45\x32\xb1\x4a\x50\x7f\x64\xf0\xb3\x83\xa4\xab\x48\xa6\x89\xb6\xcb\x6e\x95\xf9\xd7\x3b\xc2\x4c\xa3\x7d\x47\x4e\xc5\xcc\x46\x18\x29\x16\x63\x83\xc5\x96\x3e\x5e\xca\x7c\x0c\x94\x52\x91\x0e\x09\x77\x90\x74\x4c\x51\x6e\x40\xe4\xbb\xec\x30\x11\x80\x52\x91\x66\x1c\x85\x51\x90\x27\x36\xf6\x51\x55\x91\xd6\x56\xb0\xe8\x06\x0e\xa5\xaa\x84\xea\xa6\x20\x84\x06\x0b\x28\xfb\x36\x86\x76\x5b\xac\xb3\x32\xfa\xe4\xe1\x40\x6a\xc9\x1c\x05\xfc\x6a\xda\xa7\xd3\xc3\x9c\x54\x04\x5c\x31\x67\x67\x74\x14\x15\x0c\x91\x91\x93\x89\x01\x26\x24\x4e\x85\xae\xc2\xbe\x81\x7d\x59\x8f\x4e\x31\x75\x90\xd5\x46\x26\xd1\xc2\x2d\xca\x8f\xa2\x51\xef\x03\x8e\x99\x62\x41\x10\x79\x5d\x86\xcd\xea\xb9\x57\xeb\x50\x2c\xd0\x09\xb3\x0e\x63\xda\x93\x89\xae\x54\xa7\xdd\x07\x48\x1a\x60\x95\x64\x7f\xfc\x2c\xb1\x65\x6d\x9a\x93\xf6\x4a\x9c\x56\x42\x7d\x22\x8c\x30\xf9\x84\x56\x11\xe9\x9c\x15\x5f\x87\x5e\x78\x8a\x85\x51\x64\x84\x07\xb8\xec\xde\xb3\xfa\x15\xda\x45\x60\xca\x93\x69\x07\x6a\x9f\x37\x5b\xae\xf0\xaf\xa2\xf3\x23\x55\x2c\x34\x31\xb1\x11\x13\x4a\xe3\xac\x77\xf7\xe3\xb9\xc6\xa2\xd8\xa4\x88\x70\xe8\x42\x47\x16\x71\xc0\x8c\x73\xf5\xfc\xf0\xfc\xba\x5f\xbe\x3e\x7f\xf7\xc1\x28\x63\x81\x65\x6d\x2f\x8a\xa2\x3c\x15\x16\x0d\xf3\x1b\xa4\x97\x62\x8c\x58\x12\xb2\x6d\xbd\xa0\xe6\xfa\xdc\xde\xc3\x18\x4d\x2d\xb3\xc1\xb6\x3c\xbe\x5c\x76\x1b\x18\x73\xbc\x67\xd3\xae\xb3\xd9\xdf\xd0\xd1\x26\x3a\x21\x13\x37\x30\x26\x0c\xfd\x3d\x94\x28\xbc\x36\xda\x47\x99\xa9\x36\x83\x71\xcb\xf2\x5c\xc4\xc7\xe2\x08\xa4\x55\xea\x03\xf8\x1b\x96\xe7\xa3\xa8\xeb\x81\x39\x91\x1b\x95\x26\x44\x9a\xbe\xe4\x52\x5b\xcd\x97\x9b\x19\xfe\x99\xfb\x00\x0f\x38\x36\xec\x94\xff\xb9\xf3\xb2\xa6\xed\x40\xe9\xf1\xa8\x8b\x3c\x7f\x14\x98\x72\xa1\x86\x50\x37\x31\xb8\x49\x94\xb8\x82\x56\x67\x7d\x91\x2c\xfe\x87\x68\xf5\xf6\x84\xd6\x75\xfa\x66\xb1\x7b\xf1\x5f\x22\x02\xdb\xff\xde\x66\x87\xe3\xc8\x29\xad\x1b\x20\x00\x23\xb8\x87\x52\x89\xbc\x76\x0a\x45\xef\xd9\xb1\x3b\x0e\x04\xf3\x6b\xc7\x4d\x2c\x2f\x51\xa6\x83\xa7\x2a\xd3\xd0\x87\x57\x9b\xe2\x23\x6b\xc0\x22\xcf\xc7\xb7\x46\xa9\xd8\xf6\x0e\x2c\xff\x42\x57\xf0\xf6\xe5\x77\xf8\x22\xc5\x14\x58\xae\xe9\xb1\xfc\x09\x55\x9b\x0b\xcd\x6e\x4c\x63\x15\x3b\xc5\x34\x03\x24\x0e\xe0\x96\xb6\x85\xa6\xfd\xfd\x83\xdf\x0b\x81\xb5\xaf\x9c\x22\xf3\xc6\xb3\x04\xa8\xc4\xab\x7a\x74\xf0\x25\x64\x8e\xfb\xfb\x63\x62\x8d\x28\xeb\x2d\xfa\x99\x9f\xde\xd6\xbf\x1a\x27\x53\x36\x42\x50\x28\x66\x38\xc7\x9d\xe7\x09\x7e\xae\x8b\xa6\xef\x85\x7e\x0a\x01\x53\xcc\xc8\x04\x1b\xe3\x07\x0b\xe8\xb4\x66\x4f\xbf\xbd\x5d\x71\x00\x69\x10\x7b\x49\x9d\xe1\xcb\xe5\xa7\x5f\x4c\x22\x16\x38\xd7\x45\xe7\x5b\x3c\x3f\xe7\x63\x92\x5a\xf8\xaa\x3b\xfa\x6c\x9e\xfa\x3c\xcb\x0d\x09\x9d\xc8\xd8\x13\xfc\x6a\x7a\x69\x7a\x15\x87\xa9\x4d\x9c\x70\xff\x41\x25\x73\x5d\x5e\xc3\xb9\xba\x8f\x44\x51\x80\x9d\x67\x5b\xe4\x45\xf3\x7b\xef\x7e\x3a\x7b\x83\xe2\x28\x25\xf8\x4a\x0a\xd5\x9c\x44\x3e\x80\x8e\xb5\x87\x62\x15\xb9\x06\x82\x2b\x3f\x0e\x00\x4b\xaa\x5d\x23\x10\x9e\x6d\x85\x1c\x31\xc7\x19\xa8\x39\xaa\x98\x31\x2b\x9d\xe9\x55\x0b\x3b\x77\x80\x51\x02\x10\xb3\x94\x7b\xf7\x83\x07\x51\x37\xdb\xdd\x6a\xf4\x2b\x98\x21\xb8\x14\x60\x4e\x85\x95\x82\xae\x03\x18\xc7\xd4\x8a\xbc\x3c\x94\x6f\xab\x32\xcf\x61\x06\xd2\x3f\xbe\xda\x38\xa4\xd8\xf1\x45\xfb\x16\xc8\xc7\xd7\x1b\x87\xc6\x28\x0f\xc9\x3c\x15\xf5\xf7\xac\x79\xc7\x88\x69\x33\x16\x79\x56\x71\xac\x38\x8e\x34\x59\xa1\x97\x50\x77\x97\x12\xeb\x20\x72\x02\x3b\xb7\x00\xde\x16\x61\x22\x96\xa4\xe2\xd8\x50\x54\x7a\xec\x4b\x5d\xb7\x00\xae\xf6\x7d\x85\x4e\xa2\xe2\x24\x16\x98\x4c\xad\xbe\xfd\xdb\x7f\x5d\x62\x9c\x9c\x6f\x57\xee\x72\x4d\x87\xf1\x27\x53\x2a\xb5\x0b\xda\xac\x10\xd8\xa2\x17\x25\x5d\xe4\xb9\xed\x74\x8c\x7f\x61\x1a\xa6\xde\xdc\xf1\xa5\xec\xaf\x2f\x95\x0a\x01\x63\xdb\xa1\xec\xd1\x6c\xa2\x1e\x73\xc6\x30\x76\xc3\x10\xd9\x67\x1c\xbf\x2b\x19\xfb\xcf\xf2\x30\xd0\x1e\xc1\xf3\xf3\x56\xe4\xb9\x44\xa2\x0f\x8a\xa6\x59\x43\xa3\xd3\x68\x26\xf2\x76\x47\x74\x94\x57\x39\x78\x1e\x02\x8c\xb2\xda\xf4\xd9\x24\xc4\x8f\x65\x1c\xa4\xcc\xf5\x02\xca\xaa\xfd\x1e\xd4\x0d\x9f\x5f\xc3\x62\x29\x28\x56\x40\xb2\xfa\x41\x34\xb0\x9c\xf4\xab\x63\x95\x86\x18\x68\x77\x16\xcb\xbf\x45\x0e\xcc\x67\xdb\xf3\xef\xb4\xa1\xe0\x53\x31\xaf\xc8\x96\x8c\x17\x10\xa3\xa2\xd0\x01\x61\x50\xa2\x60\xb3\x7a\x9e\x95\xc1\x9b\xfc\x9a\x39\xf7\xe0\x41\xdb\xd2\x37\x98\x92\x80\x48\x91\x0e\x80\x1a\x65\xe9\xf5\x18\x55\x42\x12\x82\x75\xe6\x1e\xb8\x2a\xc8\xbd\xa8\xdf\xf7\xee\xcc\xdd\x38\x09\x18\xff\x5b\x63\x30\xac\xb5\xf6\x81\x71\x42\xc0\x22\x40\x6d\xed\xe8\x1f\x28\x33\xb6\x1f\x51\x64\x20\x37\xf2\x8f\xb6\x83\x84\x52\xae\x2c\x36\xb9\x68\x4e\x9e\xb8\xa7\x12\x9a\x18\xcc\x43\xca\x5c\xaf\xb2\x0a\xdf\xa5\xac\x78\x1b\x92\xe8\x54\x42\x95\x6d\xb8\x1c\x3b\xe7\x5a\x7f\x40\x47\x22\x1a\x34\x24\x87\x50\xa3\xd1\xe3\x75\xe3\xc3\xd0\xa0\x0a\xf2\x4f\xc8\x76\xe5\xb7\x7a\xac\x9f\xaa\x92\x90\xf1\x58\xb9\x7e\xee\x97\x31\xc8\xfc\xb3\xc9\x33\x2d\x00\x25\x51\x1a\x62\x5d\xc5\xc6\x47\xcb\xd3\xd9\x86\x48\xf3\xf7\x25\x52\x4c\x05\x9e\x33\xf6\x6c\x8c\xbf\xb6\x48\xc7\xd4\xfa\xe7\xab\x1f\xa0\x37\xc5\xb0\xf6\x91\xb0\x98\x21\xfe\x68\x71\xb3\x7a\x17\x59\x81\x22\x71\x13\x1e\xc6\x64\x4a\x77\x1f\x94\x44\xf7\x24\xb1\xe5\x79\x31\x29\x55\x24\x31\x4f\xf1\x1e\xe5\x6d\xb8\xb2\x1a\xc8\xb1\xf9\xe3\x32\x92\x0e\x75\x8a\xd9\x32\xe8\x8b\x1e\x58\x37\x7b\x13\x22\x90\xc3\x5f\xc0\xcf\xb1\xea\xe6\xe4\x1e\xa4\x89\x55\x81\x11\x52\x2a\xdb\x95\x53\x7d\xc1\x3a\x49\xb9\x91\xd4\x33\x2c\xd1\xfd\x4e\xbf\xc1\x3c\x19\x49\x25\x3c\x22\x88\x2c\x3d\x56\xd9\xdf\x70\x01\xff\x48\xb8\xb0\xd2\x5f\x15\x98\x61\x59\xc5\x1f\x55\x02\x37\xbc\x85\xd6\x13\x73\xca\xf1\x38\x11\x87\x3e\xef\xc3\x5f\x74\x19\x2b\x26\x22\x25\x91\x95\xe2\xc0\x7b\xf3\x07\x7a\xc2\x38\x07\xc5\x8e\x50\x75\xb5\xb9\xe2\x4e\xa2\x42\x26\xf9\x40\x66\x63\xdf\x40\xdd\xa7\xcf\x89\x8a\x02\x7c\x0f\xef\xc4\x01\x1e\xca\xb7\x4c\x4d\xba\x3f\x89\xe2\x80\x4d\x2d\xe8\x30\x6e\x89\x26\x90\x22\xc4\xe4\xfc\x35\xcb\x73\xa8\xa6\x1f\xd1\x21\x8d\x88\x17\x89\xdd\x67\xe5\x69\x2f\x7c\xff\xa5\x1b\xc2\x52\xdc\x0e\xb3\xba\x5d\x47\xd6\xbf\x8e\x59\xc7\xe1\x54\x89\xd6\x1c\x8b\xf7\x7b\x25\x8a\x57\xb4\x61\x9b\x5f\xd7\x13\x20\xd4\xcb\x22\x9d\x8e\xdb\x46\xa0\xa8\x7c\x1b\x13\xdc\x42\x7f\x36\x60\x01\x32\x72\x0f\xe2\x97\x17\x8b\xdc\x14\xdf\x21\xeb\x8e\x27\x71\x88\x2a\x31\xdb\xd5\xca\xff\xcd\x24\x36\x80\x5c\x18\xc8\xb3\xa1\x74\xee\xf8\xfb\x8d\xd2\x08\xde\x58\x3e\xfc\xf1\x3b\xe9\x5c\x95\x06\x46\xf3\xa0\x13\x54\xdd\x36\x17\xa8\xbf\x94\x50\x85\x46\xa2\xce\xe7\xd8\x73\x89\xda\x1d\xfe\x8b\x1f\x92\xc8\x78\x68\x8b\xd0\x5b\x34\x8e\x6f\x4d\x4a\x13\x1e\xc8\xae\x0f\xed\x81\x7e\x29\xd5\x4a\xf5\x88\x60\x5b\xad\xed\x4d\xb0\xfd\x4b\x97\x86\x14\xd0\x29\xf2\x4e\xe4\xe2\xd7\x19\x3b\x3f\x9f\x5d\x5a\xe4\xfc\x88\xad\xfb\x51\x17\xe0\xa5\x71\xa4\x91\x74\xe7\x20\x5e\x63\x01\x21\x95\xc6\xa0\x90\xdd\xf4\xf4\xf8\x99\xe2\x9b\x4a\x93\xc4\xc2\xaf\x45\x9e\x97\x3f\x3d\x54\xce\xcf\xb6\x34\x91\x14\xa3\xb9\x8d\x06\x5b\x82\x9c\xdd\x86\xd3\x94\x72\xac\x91\x3d\x0c\x65\x4b\x55\x9a\x32\x2b\xc3\xd1\x93\xab\xaf\x54\xfb\xd3\x34\xb1\x02\x28\x03\x8d\x03\x04\xd9\x8c\x9f\x61\x9a\x32\xe5\x1a\xb7\x37\xa0\x6c\xca\x3b\x19\x21\x53\xa4\x24\xed\x7d\xf6\x6f\x65\xb8\xfd\x51\x9d\xe0\xfb\xe8\xa1\xc0\x1b\xe3\x4c\x04\xd1\x4b\xe0\xf1\x7a\x3b\x72\x90\x89\xa6\x5c\x12\xe5\xde\x8b\xcd\xd3\x6a\xfd\xb4\xdb\xfc\xb1\xde\xbf\x3c\x3f\x3f\xec\x17\x37\x37\xaf\x93\xeb\x12\x41\xe8\x6d\xb0\x97\x27\x74\x7f\x98\x8b\x08\x53\x41\x63\x2c\x69\x69\xf8\x78\x44\x1c\xac\x8d\x78\x6d\xe9\x73\x7a\x8d\x22\x0a\xa4\xa7\x63\x3d\x95\x0d\xca\x37\x4e\xce\x27\x43\x82\xf5\x56\xfd\x2e\x8a\x11\x1c\x00\xb5\x92\x1d\x20\x2c\xcf\xa1\x78\x83\x2d\x72\x36\x1b\xd0\x57\x1e\xad\x4c\x03\x6f\x72\x87\x8a\xd3\x43\x5f\x09\x95\x4a\x6e\x2b\x4b\x35\x34\x6b\xef\xf5\xe7\x60\x01\x93\x5f\xd4\xe6\xd9\x5d\x35\x77\xb3\x7a\xb6\xa9\xee\xf8\xca\x74\x60\x19\xd4\xea\xbd\xac\xa1\xe7\xc3\xfa\xa3\x14\x34\x38\xd9\x4a\xd2\xfd\x31\x8c\xd1\x4d\x65\x77\xbf\x78\xfa\x8a\xa2\xec\xdd\xeb\xa8\x79\x2a\x6c\x13\xb3\xa7\x43\x9c\x7a\x41\xc0\xa1\xd8\x93\x4a\xb5\xb1\x65\xed\x3b\x0b\x9c\x9f\x10\x8f\x55\x0a\x34\x42\xe1\x4a\x65\xc5\xb8\x46\xcd\xf0\x14\x98\x41\x1a\x27\x06\x79\xbb\x93\x84\x97\x0a\x8e\x22\xeb\xee\x12\xa4\x06\x3a\x1a\xc1\x58\xa0\x5e\xa5\x00\x11\x2e\x5d\xd8\x74\x73\x0a\xab\x8b\x49\xfb\x3c\x35\xdc\x72\xae\x6e\x6c\xb9\xf7\xb2\x65\x9f\x1a\xce\x30\x9b\x6f\x7f\xc2\x0c\x40\x2b\x35\x5c\x61\xa9\x21\xab\x6b\xa7\x45\xde\x49\xc4\x7e\x9e\x18\xa6\x46\x85\x81\x25\xeb\xeb\x85\x9e\x20\xe5\x3e\x33\x8c\xb1\x1f\xe7\x41\xa2\x30\x63\x79\x10\x85\xf6\xb8\xae\xdf\x86\xb0\x3c\x90\x14\x59\xaf\x47\x71\x0e\xd8\xd8\x11\x4f\x71\xc2\x88\xf0\x62\xf8\xf3\xca\xb2\x7e\xfa\x72\x22\x35\xa6\x65\x42\xeb\xc7\xf2\x03\x2e\x36\xf4\x0e\xdb\xc9\x89\x16\x42\x79\xc4\x3c\x2e\x1b\xdb\x7e\xa3\xe3\x34\x10\x18\xcb\xb7\x1b\xfc\x56\x14\x59\x73\xc6\x05\xb7\x3b\x1c\x81\xd3\xdb\x52\x76\x35\x79\x85\x0e\x4c\xc4\x43\x6a\x05\xf4\xfd\xb2\x33\xd7\xb7\xe6\x61\x64\xd9\x8a\xa6\xac\x94\x2b\xf4\xae\x8c\x93\x0c\xf5\x0d\x5a\x1e\x26\x1a\x83\x71\x27\xf9\xf1\xb0\xdc\xef\xd6\x8b\x47\xff\x3d\x11\x65\x10\xf5\x6c\xe2\x36\x30\x1d\x83\x97\x78\x14\xca\x58\x79\xfe\x4f\x7b\xbf\x55\xb3\x42\x07\x9e\xd1\x3d\x8b\xa2\x30\x74\x60\x1c\xab\x1d\xb3\xfd\x91\x8d\x35\x24\xda\x31\xd2\x36\x01\xbd\x5e\x4a\x76\x28\x2b\x9d\x61\x67\xeb\x9f\x25\x1c\x3c\x62\x3a\xf4\x76\x0b\xcf\xc6\x5c\x18\x6d\xa6\xe3\x5d\x97\x47\x5a\xe2\xf8\xc7\xc7\xdf\xed\x99\x9c\x11\x8a\xe2\xce\xca\x62\xae\x47\x6f\x2b\x67\x84\xe1\xd4\xd2\xe5\x8b\x38\x97\xa7\x3e\xc8\xfb\x9f\x88\xf7\x09\x5e\xc4\x27\x55\x06\xce\xa2\x40\xdb\x44\x17\x55\x96\x9b\x06\x26\x8b\x1c\x67\x42\x81\x0f\x3b\xe7\x6c\x5e\x15\x8f\x05\x55\x0e\x36\xe4\xba\xeb\xea\xc7\xcc\xdb\xcc\x63\xc1\xf0\x5a\x57\xcf\xcf\xfb\xed\xfd\xe2\xd5\x77\x74\x79\x0c\xd6\x85\x4d\x42\xb3\xa9\xb7\xd0\x34\x79\x3f\x47\x53\x62\x01\x25\x6f\xd0\x2c\xb3\xfc\x4a\x4b\x81\xa7\xa9\xb0\xa0\xd8\xfa\x21\x2b\x7e\x80\x9e\xb1\xa2\x53\x9c\xd3\x48\x33\x1b\x68\x57\x96\xaf\xd0\xe3\x3c\xb8\x88\x0c\x02\x74\x71\x99\xf1\x21\xc3\x55\xe0\x33\x17\xc0\x10\x0d\xf5\xaf\x13\x54\x67\x0b\x43\x1f\x21\xcc\x26\xc3\x25\x55\x88\x44\x7f\x2c\xf5\x29\x47\xfc\x70\xf7\x8a\x5f\x29\x91\xb8\x0f\x2a\xca\x11\x14\x5d\xc0\x4f\x97\x1c\x8c\x2b\x07\x93\xd1\x40\x31\xf4\xf6\xcb\xf1\x53\xd9\x3c\x9d\x2e\xdb\x57\x7e\xb4\xa1\x28\xfc\xbd\xcd\xde\x8a\x3f\xa0\x42\x9a\xde\xdc\xc4\xd3\xa9\xed\xf0\x79\x76\xcb\x6d\x59\x21\x32\xf0\xca\xb5\x6a\x67\x23\x81\x24\x98\xbc\x6c\x7c\xdc\xc5\x21\x25\x88\x60\x6b\xaa\xec\xed\x0d\x2a\xbb\x5f\x36\x03\xef\x4d\xc5\x41\xe9\xc0\x6e\x6f\x37\xa0\xfc\xe7\x4c\x12\x24\x91\x6f\x4d\xb7\x21\x6c\xdd\xdc\x82\x77\x64\x9d\xcc\x31\x93\x48\x7c\xcd\xa1\xd0\xdb\x8b\x88\x8c\x9b\x94\x23\xf7\x7e\x65\xed\x96\x66\x9a\xae\x9f\x61\x2c\xb8\x51\x56\x8d\xfa\x28\xce\xb7\x65\xe5\xfd\xf1\x67\xef\x82\x08\xb4\xc6\x50\xb5\x79\x83\x8e\xbc\xab\x04\x09\x0c\x97\x5d\x89\xd5\xf1\x83\xc6\x25\x24\x3f\x32\x49\x18\xb3\x59\x14\x54\x56\x4a\xa7\x3b\xc2\x2d\x40\x3c\xfb\x80\x69\x34\x29\x42\x19\x45\x4e\x4d\x68\x28\xd5\x38\x7e\xf2\x22\x54\xcc\x93\xef\x6e\x44\x33\x67\x27\xa0\x44\x94\xc4\x48\x1c\x42\xaa\x42\x1b\xb7\xda\x7e\x92\x1e\xb5\x89\x27\xe7\x8d\x00\x8c\xa3\x58\x2d\x4f\x59\x3e\x21\xb1\x08\x46\x12\xed\xbb\x3c\xb8\x06\x2f\x4f\xe7\x1b\x68\x50\x5a\x6b\x3a\xd2\xa4\x74\xe0\x25\x71\x3a\xe0\x23\xeb\x39\xbc\xfd\x15\x33\xcd\x28\xeb\x9d\x51\x2c\xf6\xf1\x7e\xb3\x9a\x85\x21\x08\xa6\x05\xce\x80\x43\x56\x34\x33\x72\x1a\xfd\x69\x63\x45\xb1\x15\xb2\x29\xea\xd3\x34\x5f\x15\xb1\x49\x22\xa4\x2a\x94\x8d\x68\x4a\x07\xca\x9b\x88\xd1\x2a\x91\x44\x04\xd5\x24\x97\xff\x5e\x8d\x69\x85\xe3\x6f\x4a\x78\x88\x49\x1c\x34\xef\xb8\x6a\x6e\x7c\x5c\x2b\xd2\x48\x47\x7d\xfb\x18\x13\x51\x1b\xa9\xee\x2a\x3b\x73\x6e\x01\x1c\x1b\x2d\xeb\x12\x74\xc1\x85\xf2\x08\x91\x25\x38\x3a\xfe\xb5\x75\x4c\x70\x48\xb0\x7b\xdd\x35\x16\xb1\xaa\xdf\xc7\x88\x42\x04\x41\x1a\xba\x00\x75\xd8\x69\x16\x82\x59\x70\x7f\x3b\x81\x06\xe8\x2f\x21\x84\x80\xd8\xe7\xf2\xdf\x21\x1b\x96\xdc\x85\x10\x12\x2b\x21\x16\x92\xe3\x24\xc9\x31\xb3\xdd\xb8\x6a\xc3\x85\x96\xdb\x15\x18\xd4\x1c\xa3\x71\x72\x6d\x42\x27\xb2\xe7\x89\x3c\x66\xde\x04\x6a\x5c\xab\x73\x83\xa5\x48\x64\xc7\x2d\x5c\xbd\x8b\xea\xad\xdf\x1c\x84\x22\x1c\x57\x15\x84\x1c\x0e\xc3\x13\xa1\x42\x19\x51\xef\xb2\x6d\xc9\xc7\xdd\x21\x66\xf0\x0d\x36\x80\x64\x91\x77\x70\xf5\x86\x09\x58\x41\x68\x96\x62\x9f\xbd\xdd\x79\x3a\x89\xae\xe9\x5d\x98\x7f\x8f\xb5\xb0\xa5\x23\xab\xce\x3a\xb0\x9d\x52\x42\xeb\xd8\x73\x37\x6c\x19\x68\xaa\xd5\xf1\x69\x1c\x23\x20\x20\x18\x62\x76\x36\x8b\xb7\xa7\x42\x0d\x98\xd9\x4a\x00\x09\x71\x55\x06\x9d\x39\x9a\xcc\xe9\x92\x4f\xff\x5f\xed\xff\xf9\x1f\xf6\xbf\xfe\x33\x8c\xe3\x02\xf0\x0e\xe2\xb8\x2d\x2b\x2f\xf4\xf8\x3f\xdd\xf1\x84\x10\xe3\xde\x4e\x6b\x9a\xf9\xc9\x8b\x23\x03\xae\x71\x32\xdd\x8d\x3c\x6e\x95\x0c\x04\x43\xbe\x96\xeb\x98\x7e\x0e\x73\x90\x24\xb5\x6b\x56\x01\xa0\x6f\xb3\xb7\xf7\xa6\x4d\x21\x4e\xb9\x9f\xe7\x92\xc8\x98\xb8\xdd\xa7\x63\x6d\xcd\x74\x36\x26\x27\x05\x8e\x25\xfc\x93\x73\x45\x59\x74\xa7\xa3\xce\x2f\xb4\x16\xa2\xd3\x1a\x9f\x3f\x47\x18\x0b\xb0\x0e\x42\xff\x77\x82\x1a\x45\x18\x76\xe5\xb7\xed\xcd\x97\x39\xee\xec\xe4\xa3\x09\x4d\x55\xd7\x4e\x7f\x85\x0f\x6b\x9f\xe1\x33\xc6\xc9\x6a\x2b\x43\x6e\x95\xaf\xdf\x70\xb5\x5d\x76\x39\x9e\x0c\x55\xca\x6d\x59\x56\xe8\x75\xf3\x3e\xd6\xd5\x54\x32\x4a\x04\x96\x42\x70\xd1\xb8\x6d\x63\xfc\xad\x38\x1c\xc7\x88\x39\xc9\x22\x9e\xb8\xf0\xfc\xd9\x91\x17\xbf\x0c\xcd\xfd\xfc\xb0\x98\x23\x0f\xf3\x0e\x1a\x5b\xdc\x1b\xf2\x89\x26\x97\xc7\x44\x80\xd5\x6b\xbb\xe4\xaf\xca\x36\x48\x2f\x2e\xfb\x6e\x32\x65\x29\xd6\xae\x5e\x5e\x57\xf3\xe5\xb6\xcb\x1c\x4d\x72\x1e\x63\x25\xfa\xa1\x7c\x7b\xf4\xee\x2f\xde\x72\x7b\x7c\x76\x19\x50\xa1\xb1\xcf\x5d\x65\xff\x39\x89\xc2\x77\x17\xa4\x24\x21\x24\xfe\xad\x7c\xbd\xdf\x75\x7f\x77\x94\xd1\xed\xfd\xd3\xbf\x69\xf7\x47\x11\x63\xcb\x2a\xab\x5f\x2a\xe8\xf6\x5a\x98\x6c\x9d\x52\x02\xc5\x1a\xd0\xd3\xe6\xf1\x76\x81\xe8\xde\xf5\xee\x7e\xff\xf2\xba\xde\xf7\xb6\x10\x4a\xaa\xd4\x92\x4c\xda\x49\xf7\x8e\xb4\xae\xa1\xa5\x94\x92\x4a\x2a\x5c\x14\xf6\x47\x71\x5e\xbd\x67\xea\xfa\xbb\xa5\x0d\xc1\x80\xb5\x7d\x13\x17\xaf\xab\x2b\xa3\x20\x49\xb0\x9b\xbf\xcc\x1a\x67\x71\x24\x3a\xc6\x8a\x84\x94\x23\x68\xb9\x4b\x2c\xb0\xd4\x72\x85\xfd\x27\x41\x5a\x0a\xca\xca\xaa\x68\x4c\x25\xdb\xdc\x28\x13\x11\x54\x37\x71\x50\x99\x97\x0a\x79\x37\xe5\xaf\xf3\xe4\x76\x19\x41\xb0\x20\xfc\x7f\xa7\xb2\x81\x45\xed\x53\x5a\x15\xd0\x08\xb5\xf2\x54\x29\x2b\x51\x6d\x0e\xc7\xf6\xcd\x9a\x54\xd1\x51\xd6\x11\x05\xbb\xc4\xf1\x08\x85\xfe\x86\x0a\x10\x5b\x9c\x24\xb3\x00\x1e\x45\x12\xdb\x53\x77\x69\x2e\x52\x26\x57\x65\x9e\x8b\x06\x2a\x91\x77\x3b\xdb\xe8\x52\x14\x35\x0c\x63\x88\x9b\x4c\x01\xca\x1d\xcd\x57\x11\x55\x18\x28\xcc\x34\xe4\xe9\x8c\xed\x26\x4b\x0e\x42\x8a\xf0\x3f\x5a\xca\x55\x18\x01\xc2\xc2\xff\xce\xf2\x5c\xec\xab\x09\x2b\x5d\x45\x81\xcd\xd1\xb5\xdb\xbe\xf6\x62\xd8\xad\x57\x91\x90\x9e\xfc\xea\x55\x0d\xba\x75\x64\xdd\xe3\xb6\x14\x0b\x00\x6b\x4d\x1d\x8b\xef\xba\x74\x96\x52\x8c\x70\x04\x12\xf9\x54\x36\x3b\xc0\x80\x68\xa9\x18\x01\xc4\xdc\xff\xc8\x9a\x4b\x5c\xac\x62\x8c\x04\xae\xe9\xbe\x03\x71\x98\xd6\x7b\xfa\x35\x45\x31\x16\x25\xb6\x4d\x9b\x5b\x51\xb4\xc7\x6c\x0e\xb6\xe5\xb7\x1f\xc5\x12\x4b\x3e\xf7\x5e\xe5\x97\x78\x59\x3f\xc1\x14\x53\x56\x8c\x38\xab\x1f\x4e\xc5\x79\xc4\xec\x53\x0c\x98\x2b\xb9\x7f\x94\x3f\xb0\x62\xb1\x3c\x5b\x4d\xa7\xd9\xb7\x48\xc5\x81\xd5\x2a\xcf\x6a\x54\x8a\xb6\xa1\xf1\x97\xe9\x18\x40\xf4\xd3\xd6\x33\x36\x54\x1c\x4a\x8b\x74\xf1\x99\xec\xed\x00\x46\xa7\x62\xa1\x06\xe2\xff\xce\x76\x71\xb0\x7d\xab\x24\x15\xf8\xbe\x59\xe2\x11\x0d\xea\xf3\x41\x7a\xf1\x1a\xa5\x12\x10\x58\x58\xfb\x33\x13\xdd\x65\xa5\x1c\xac\x89\xff\x6a\x40\xec\x50\xa9\x14\xde\xa8\x6a\x79\x3a\x3b\x4b\xed\xbe\xa2\xaf\x52\x45\xd1\x46\xe2\x52\xc6\x64\x14\xe2\xb8\xd1\x3c\x0e\x71\xe3\x32\xa7\x42\x2f\x4f\xd5\x95\xd5\x49\xf1\x54\x22\xa1\xc2\xed\xf0\xeb\x3c\x3b\xb4\x1b\xc0\x95\x5c\x4c\x71\x2e\x44\x38\x74\xb8\xba\x2d\x2b\x07\xf2\xc6\x57\x6a\x72\xaf\x05\x13\xe1\x50\x02\x6c\xae\x98\xa0\x44\x6a\x62\xd7\x6e\xc5\x08\xdb\x56\xb7\x26\x83\x64\x98\xe2\x2d\x6b\xa0\x68\xde\x91\x52\xe5\x6f\x8b\x8c\xb4\xbf\x6d\x2f\xed\xba\x99\x95\xc5\xa3\xf8\xd5\x61\x77\x46\xab\x99\x92\x8c\x3b\x3f\xd3\x0f\x10\xb9\xc5\x74\x4c\x7e\xb3\xe4\x86\x3a\xe8\xec\x5e\x0c\x93\x73\x7f\x5c\xc7\xf8\x4a\x59\x80\xdf\x68\xba\xb6\xeb\x9d\xa3\xf4\xb7\xd1\xf8\xaa\x2c\x14\x1c\x9b\x3e\x69\x55\x2a\x4a\x10\x2a\xf9\x28\x9a\xf7\x2f\xa3\x6f\x6d\x17\x17\xd2\xf5\x42\x1a\x58\xf9\x02\xfc\xe4\xdb\x95\xa1\xda\x0b\x3b\x3a\x89\x8b\xa1\xb7\xae\x52\x9a\x52\x5b\xe5\x11\x07\x78\xb5\xf1\xce\x67\x68\x75\xa5\x95\x49\x03\x5f\x7c\x6e\xd3\x95\x17\x71\xaa\x41\x0f\x20\x06\x0a\x48\x80\x7d\x95\x6a\xa0\x88\x3d\x1f\xad\x29\x88\x38\x16\xb0\x0e\xe8\x14\xdb\x26\xc4\x93\xe3\x09\x20\xa8\xb2\x72\x86\x03\xed\x0b\x77\x5b\x95\x87\xef\x02\x5d\x76\xba\x62\x95\x02\x49\xf0\x41\x15\x65\x93\x99\xf3\x70\x02\xfb\x35\x46\x07\x82\x59\xda\xb9\x7b\x1d\xbe\x67\xcd\xbb\xd5\x90\xb0\x14\x99\x01\xea\x72\x7e\x3d\xd7\x81\xb1\x1e\xfe\xbb\xd7\xe7\xa7\x55\x2e\xea\x3a\x53\x9f\xd5\x0d\x35\xa5\xc4\xea\xf2\x20\xb4\xc9\xff\x56\x4d\x19\x0f\xa2\x21\x98\x68\x51\x68\xab\x6f\x36\xa3\xb2\xa3\x74\x98\x30\x62\x0d\x6e\x7f\x5e\x94\xae\xa6\xfb\x4f\xaf\xe1\xf2\x0f\xe1\x30\xfe\x3b\x4c\x80\xef\x94\x40\x3e\xc3\x0c\x42\x5c\x47\xc4\x60\x91\x1c\x1b\x2d\xab\xf2\x70\x84\xa6\x57\x00\xbf\xa6\xeb\x95\x06\xa3\xb5\xbb\x3d\x89\xb6\xaf\x13\x96\xf8\x6c\xe1\xce\x07\x64\x3a\xa2\xdc\x93\xd6\xdb\xe9\xd4\xab\xb8\x8c\x7f\x6b\x94\x44\x48\xae\xf8\xfb\x87\xef\xf7\x3b\x60\xc2\x55\xe7\xa0\xbe\x38\x3f\x8b\xc7\xb9\xf8\x2f\xff\x45\x9a\x62\x1b\xed\xd7\x7c\xdf\x56\x47\x46\x5b\x3a\x8c\xf8\x75\x27\x0e\x7d\xc7\x5c\xb3\x30\x41\x79\xd2\x4e\xc9\xf0\x77\xfa\x20\xb3\x99\xf7\xf0\x7f\xbb\x3b\xc8\xb4\xf2\xf2\xe3\x4f\xf0\xcb\x36\x16\x5c\xd7\x51\x2f\x61\x36\xc1\xd6\xb1\xf2\xce\x23\xa0\xb7\x59\xf1\x96\x5b\x65\xd0\x41\xac\xa1\x93\x00\x12\xea\x2c\x1c\xb2\x06\xeb\x11\xdd\x74\x4d\x59\x1a\x75\x65\x85\x36\x4d\x56\xef\xdd\x26\xa3\x53\xa6\x95\x4b\x76\xbf\x67\xce\x46\x75\x3a\x81\x53\xa9\xb1\xda\xb9\x11\xc5\x60\xff\xd2\xa9\x96\x08\x4d\x40\xf8\xcd\xe7\xd3\x93\x07\x80\x22\x26\xeb\xc5\x3f\x4c\x26\xb4\xa0\x02\x27\xc9\x56\x18\xeb\x11\x3f\x57\x69\xd3\x22\x8a\x90\xcf\x9f\x97\xe5\x8f\xd3\xf1\xb5\x3c\x8b\xbc\x99\x20\xce\xb4\x24\x56\x33\xdd\xab\xb0\x43\xd5\x64\x26\x53\x23\xa4\xa7\x1f\xaa\x53\x67\xad\xde\xf1\x08\xfc\xc5\xaa\xd4\x5a\x36\xd5\x65\xd7\x0d\xd7\x4a\x6a\x4c\x33\x11\xfa\x3a\xd4\xbb\xd0\x4a\x0b\xf0\xee\x1e\x2e\x2c\xb7\x35\xc0\x07\xd1\xfe\xc9\xa7\x95\x4f\xe5\xd0\x9e\x52\x69\x88\x42\xdd\xab\x55\xdb\x98\xf6\x51\xfc\x42\xd6\xf4\x97\x49\xa1\xb5\xfb\x48\x8c\x53\x75\xb9\x78\xfa\xfa\xb4\xf6\x09\x93\x36\x21\xc1\x29\x63\x9d\x2d\xce\xa2\xfb\xbb\x24\x30\x6e\x79\xdf\xdf\x8e\xef\x17\x04\x41\x8a\x41\xa2\x13\x3f\x38\x3d\x8a\xfa\xc7\x95\xd4\x03\x02\x26\xb1\xdf\x2b\xcb\xaa\xb8\x15\x07\xd0\xed\xea\x32\xbf\xf1\x40\x10\x07\x78\x73\x9d\xbf\xe0\x16\xa1\xb0\x6e\xc7\x1a\x39\x8a\xfa\xf1\xd2\xfa\x56\x5b\x52\xf7\x65\x19\xee\xea\xcb\xf8\xe9\x1e\x00\x81\xb4\x38\x12\x57\xd1\x9a\x7c\x29\x21\xf6\x09\x54\xd9\xdb\x7b\x13\x8f\x8d\x50\x15\x90\xd4\x72\x09\x2a\xa4\xb1\x7f\xdb\x4e\xc0\xae\x40\x99\xc0\x34\xb5\x38\x1d\x9c\x36\x82\x7f\xcf\x80\x0a\xeb\x78\x85\xfd\xb1\xb2\xda\x17\xf0\xb3\x3b\x04\x01\x38\x0f\xf9\x07\x51\x37\xbb\x9f\xe5\xe2\x20\x45\x5d\x0b\x5d\x56\x57\x04\xa1\x80\x9a\x10\x15\xb9\x2c\x7f\xad\x7e\x3e\x14\xd9\x4d\x1f\x25\xbb\x41\x21\x00\x92\x9f\xfc\xc3\x5e\x1f\x8e\xd9\x54\x7d\x07\x22\x16\x60\x1b\x5d\xa0\x26\xe7\xbb\xe8\x7e\x56\x64\x88\x87\x71\xdd\x89\xba\x33\x90\xbc\xec\x1c\x00\x0b\xad\x3a\x15\xd2\x6a\x7e\x65\x87\xd3\xc1\x5a\x9f\x1e\xa0\x68\xd0\xf8\xd6\x27\xb6\xc0\xd2\xc4\x1a\x3c\x61\x38\xb0\x6d\x73\xc4\x29\xf8\x01\x62\x2e\x71\x29\xfb\xb6\xbd\xd9\x6f\x9e\xda\x64\xdd\x7f\x3a\x89\xac\xf8\xc8\xb1\x2a\x9b\x52\x75\x21\x37\x24\x9c\x61\x37\x7c\x0b\x95\xcc\xc4\x47\xbd\xac\xc4\xdf\x59\x7f\x54\x82\x17\x3e\xff\x56\x64\xff\x77\x82\xed\x11\xc3\xc0\x61\x75\x15\x04\x4b\x9c\x9d\x5d\x5e\xfe\xbc\x3d\x15\x6a\x24\x0b\x35\xd4\xf5\x02\x21\x68\xe8\x92\xa8\x8e\xea\xee\x03\xd1\xc9\xca\x09\x42\x47\xd2\xf4\x8a\xc5\x8e\x2d\xe6\x0e\x2a\x4e\x50\x48\xc6\x32\x26\xb0\x1a\x5d\x67\x6f\xe3\x90\x79\xba\xa7\x81\xd2\x01\x56\x17\x3d\x0d\xdd\x71\xb9\xbb\x73\x02\x43\xbc\x34\x4e\x3e\x8c\xae\x97\x42\xfd\xe8\x0c\x8d\x15\x28\x13\x63\x86\xb5\xcf\x8a\x0f\xa8\xea\x49\x00\x0f\x5a\x04\xde\x6a\x13\xf7\x97\x76\xf7\x1e\x2d\x38\x00\x69\x92\x78\x55\xb4\x49\x28\x0d\x20\x84\x37\x30\xdb\x95\x5a\x9c\x71\x71\x1b\xf7\x9c\x01\xb4\xc4\xe4\x5d\x0d\x89\x87\xe3\xd3\x18\x62\x2d\x52\x7f\x1d\x41\x35\xe5\x6e\x77\x4b\x86\x4b\x31\x18\x6a\xf9\xba\xab\xf5\xea\x49\x9c\x8f\xe7\x4c\x8b\x2b\x40\x45\x30\x42\xc7\x6e\xb7\x5d\x64\xd5\xba\xd0\xcd\x85\xd4\x0e\x18\x61\x88\x53\xc0\x69\xb7\xd5\x7a\x5d\xe8\x4b\x41\x1e\x13\x28\x82\xb1\x4d\xd5\x41\xaa\x0c\xe1\x1c\xe5\x75\x6c\xcb\xdb\x51\x38\xa7\xc9\xfb\x3f\xfc\xd7\x9f\x52\x59\xe6\xfe\x43\xf9\x76\x0b\xb0\xfe\x10\xea\x34\xb3\x4f\x19\x1a\x04\xd8\x0e\x86\xe2\xcd\x89\x8e\xf7\x37\xd8\x50\x9a\x5a\x92\xde\xd3\xd3\xee\xc6\xd7\xb7\x4c\x18\x5a\xa5\xc2\x2e\x66\xb5\x34\x64\xd0\x83\x2e\xc8\x3f\xfb\x8d\x21\x8b\x51\x94\xfd\x66\xbd\x22\xac\xa7\x98\xf9\xa3\x09\x60\xf6\xbc\x29\x4c\x59\x1d\x5e\x41\x9e\x26\x04\x4a\x13\x72\x6b\xc9\xb0\xcb\xd4\x4e\xa8\x5d\xf9\xb9\xdc\xa5\x32\xa1\x20\x98\x43\x09\xad\x5f\x5f\x17\xe3\xc5\xc2\x84\x10\xa7\xb6\x09\xef\xee\xc2\xfa\x57\xbb\x20\xce\xaf\x9a\x26\xe2\x0a\xeb\x8e\x0e\x56\x33\xe0\xf8\x99\x48\xdb\x9a\x80\xb2\xe4\x88\xb1\x5a\x84\x61\x89\x92\x56\xa0\xb3\x5d\x05\x27\x37\x9c\x69\x89\x5a\x16\x15\xa8\xea\x94\x35\xf7\x50\x95\xfe\x50\x22\x13\x04\x3c\xd7\xb9\xa8\xdf\x3b\xc7\x85\x1f\x30\x15\x11\x18\x5f\x71\xa2\x39\x22\x22\x8f\xb9\x38\x2f\x0a\x7d\x9b\x15\x59\xfd\xfe\xdf\x42\xfd\x38\x96\xbf\xb5\xa0\x71\xa7\x48\x83\x28\x74\xa2\x8b\x6d\x04\xde\x17\xa6\x4d\x4a\x18\x36\x0a\xc4\xf1\xf8\x5d\xd4\x8f\x62\x0a\xf7\x30\x3c\xb0\x3c\xa0\x75\x1b\x98\x9a\x1e\x2e\x67\x38\x15\xb8\x53\xf4\x5c\x8c\xe5\x40\xa6\xe0\x7a\x71\xc8\x70\xc3\xa0\xb7\x24\xdb\xa2\x42\x8b\x73\x1a\x73\x23\x44\x6a\x2d\x09\x50\xee\xca\x62\xbd\x3d\x22\xf3\x75\xf0\x90\x84\x90\x48\x29\x3e\x20\x6a\xee\x60\x99\xe6\xb3\xa5\x11\xff\x01\x48\x10\x02\xe3\x87\x7d\x2b\x7a\x4b\xda\x76\x61\xdc\x95\x16\xde\x35\x5b\x32\x35\x32\x0c\xd2\x81\x4e\x15\x16\xd7\xfd\x56\x66\x64\xa2\x90\xd5\x64\xc3\xa4\x97\xf2\x78\xca\x45\x35\x84\x44\x8e\x7f\x89\x8e\x75\x84\x56\x63\xab\xfb\xfd\xc3\xc3\x1f\xfb\xdb\xcd\xed\xc2\x3b\x1c\x2b\xa3\x53\x8e\x7b\xd4\x3e\x2b\xd4\x30\x90\x34\x5a\x28\xec\x79\x6c\x77\x8b\xd7\xdd\xe6\xe9\x6e\xff\xb2\x58\x6d\x6e\x37\x5b\x1f\xe8\x19\x88\x05\x5a\xe5\x34\x4e\x92\x1e\xa1\x03\x70\x3a\xec\x27\x5a\x61\xa6\x5d\xae\xac\xf4\x95\x95\x07\x5f\xb6\x53\xab\x82\xee\x7a\x8c\xa0\x44\xf5\xfe\xb0\x7a\xd3\xc0\xc1\x4d\x71\x1d\x04\x01\xb7\xc5\xdf\x3e\xcb\xdd\x95\x36\x9b\xa7\x01\x49\xbb\x61\x29\x47\x39\x0e\xbf\x97\x5d\x25\xb1\x0c\xef\xb3\x0e\x02\x21\x3b\x49\xea\x75\x6e\x56\xe5\xe1\x70\x2a\xb2\xe6\x3c\x3d\x8d\x1b\x4e\x28\xc5\x2e\xfe\xd1\xe2\x84\x9d\xcc\xcc\xef\x50\x46\xb3\x2f\x4a\x7b\x32\xdb\xe8\xf0\x31\xd2\x63\x56\x34\x5f\xa1\x67\xa8\x8d\x07\x87\x01\xd6\xd8\x5e\x5e\xd7\xdb\xc5\xc3\x7a\x8f\x4f\x65\xff\x7d\xbd\xfe\x1a\xfa\x5b\x10\x4a\x82\xd3\xa2\x71\xbf\xca\xfd\x39\x8a\x54\x60\x15\x69\x8f\xe2\x84\x02\x9e\x70\x38\xf6\xbc\x1c\x1d\x44\x9c\x58\xd1\x64\x71\xfc\x9e\x69\x8f\xff\xd6\x01\x23\x96\x39\x70\x0f\x45\x75\x7e\xcc\x8a\xec\x9f\x25\x50\x3a\x60\x94\x2a\x27\x7a\xb4\x77\x24\xd2\x3d\x7a\xfa\xd6\xfb\x83\xf8\xf5\x65\x7c\x17\x18\x4d\xb1\xe8\xef\x13\xf2\xbd\x4d\xf0\x7d\xd1\x4d\x07\x4c\x68\xa4\x74\x3c\x3d\x3c\xf8\x3f\xc5\x34\x88\xbc\xf2\xa4\x7d\xa3\x16\x15\x74\xf0\x9f\x36\x2a\x42\xeb\xa4\xbe\x23\x8e\x06\x2b\x51\xe8\xfa\x72\x6d\xc2\xbb\xf5\x2d\xd2\x6e\xa2\x25\xc4\x12\xe9\x5c\xb2\xb6\x55\xe5\xe9\x58\x5e\xa9\x65\xe9\x20\x11\xc0\x7d\x05\x35\xd3\x1e\x0f\x31\x9e\x2d\x69\xac\x71\x09\xf6\xb9\xbc\xf3\x80\xf1\x47\x39\xb7\x09\x64\x76\xc8\x9a\x75\xa1\xfb\x2d\x41\x07\x29\x80\xf1\xd2\x78\xcf\xaf\x73\xa0\x08\x1d\x70\xc9\x71\x45\xda\xc1\x6a\x10\xa3\xe8\x80\xab\x18\x5b\xbc\x88\x82\x9f\xc9\x5d\xe6\x27\xa3\x08\x25\x8a\x8a\x22\xb7\x64\x79\x1e\x92\xff\x74\x20\x98\xf1\xaa\x6d\xc8\x4f\x59\x8d\x0e\x26\x21\x96\x15\x70\x19\xe8\xc8\xb7\x59\x59\x60\xb9\xa7\x2f\xee\xe9\x40\x08\x8d\xe5\xf0\x23\x22\xaf\x50\xe1\xe0\xb9\xb8\x50\x7e\xd6\x81\x80\x08\xc3\xf0\x45\xfd\x0e\xa3\x4b\x93\xa1\xe6\xd2\x21\xa5\x3c\xfc\x73\xfc\x51\x19\x49\xaf\xb7\xf5\xe7\x8b\x5f\x5b\xe7\xef\x9f\x94\xd6\xeb\xf1\x71\xf3\xb4\x79\xfc\xf6\xb8\x5f\x3d\x3f\xed\x5e\x37\xcb\x6f\xbb\xcd\xf3\x93\xff\x42\x25\x00\xc3\x7b\xbc\x2b\x43\x7f\x2a\x1d\x28\x93\x60\x1a\x84\x6c\x7e\x6b\x8b\x34\xbc\xb3\xb6\x88\x45\xfc\xed\xd5\x01\xc1\xd7\xf7\x5d\x7c\x80\x6e\x6f\xd2\x0d\x7c\xf4\x05\x0d\x1d\x68\x9a\x20\x95\xef\xff\x7a\x64\x5a\x27\x21\x10\xd2\xff\x21\xe4\x7f\xfd\xc0\x50\x29\x33\x70\xa4\xd8\x75\x18\x12\x1d\xe8\x34\x41\xd0\xf2\xc3\xbf\xff\xdd\xfd\x49\x87\xca\xb1\x11\x96\xdf\xbe\x5d\x54\xb9\xc6\x73\x00\x18\xb1\xe6\xd1\xb5\x93\x68\x2d\xfe\x75\x82\x13\x4c\xee\x5b\x1b\xa8\x87\xae\xde\x63\x4d\x46\x2d\xef\xc8\x7f\xa5\x89\x82\x50\x78\x1b\xda\x85\xd6\x0b\x75\x51\x1c\xd7\x81\x69\xa3\xdf\x76\x7f\xbb\x26\x5b\xa5\x03\xa3\x02\x6c\x53\x7e\x94\x0d\xd4\x7f\x75\xef\x0d\x09\x28\x61\x08\x6d\xac\x84\x15\x51\xa9\x2f\xb9\x31\xc3\xe5\x88\x04\x4e\x42\xaa\x6e\x63\x00\x74\x7b\x3f\xdf\xe6\xe2\x6d\x84\xc0\x76\x43\x09\x11\x18\x4f\x21\x02\x7a\x57\xfe\xd8\x96\xb9\xbf\x2e\x42\xb8\x8e\xac\x02\xd8\x1b\xe4\xed\xb3\xfb\xc3\xcf\x05\x42\x09\xb5\x89\x85\x33\x85\x41\xc7\xbe\xac\x2c\x90\x30\xaa\xb2\xe3\x85\x84\xad\x26\x54\x48\x81\x48\xa5\xc7\xd5\x50\x41\x5e\x93\x30\xb2\xca\x99\x2b\xaf\x87\x5d\xf7\x47\x42\x08\x3c\x6e\x7a\xb0\x5a\x90\x50\xf3\x84\xfa\x0e\x98\xbe\x05\x98\x0d\x04\x34\x09\x41\x58\xb2\x19\xfe\xcc\x36\x10\x7c\xa9\xca\xff\x80\x6a\xc3\x8b\xf1\xf3\x21\x51\x9c\xa0\x12\x26\x5a\xd3\x5b\xc5\x80\x49\x51\x5c\x93\x88\xcb\xb0\x83\xb6\x56\xb0\x29\x9a\xfa\x4b\x0f\x20\xe9\xbf\x96\x51\x8d\x69\xdb\xf1\x54\xbf\x2f\xdb\x6f\x59\x54\x95\x98\xe7\x6f\x68\xc2\xa2\x00\x31\x18\xed\x0d\x5e\xf6\x01\xfc\xf8\x35\x27\x8c\x27\x88\xf3\x92\xa7\xf3\x4d\x25\xde\x26\x59\x8a\x26\x4c\x50\x14\xd4\x78\x28\xdf\xda\xfd\x0e\xe6\x1d\x94\x34\x61\xd2\x9a\x56\x3b\x9c\x32\xd6\x82\x5c\x27\xcf\x8d\x88\x8d\x4e\x6d\x1a\x97\xe7\x37\x22\xfb\xb4\xd8\xa8\x49\x12\xc7\x3e\x87\xdd\x82\xaa\xa0\x99\xfc\xae\x94\x5a\x27\x34\x57\x84\x68\xf7\xa7\xf1\xe5\x8b\x48\x7a\x5d\x8e\x0b\xdf\x36\x4d\x44\x92\xc4\xac\x73\xe2\x3b\x43\x65\xf5\x41\x2d\xfc\xca\x09\x82\x6a\x22\x15\xc7\x56\x83\x3c\x9d\xbf\x9f\x7e\x65\xe2\x51\xf4\x4c\x30\x4d\x54\x68\xad\x6f\xeb\x7b\x51\xdf\x94\x3f\x8b\xf6\xf5\xba\x6c\x4a\x8f\xbf\x57\xa5\x01\xe2\x13\x31\x52\x39\x96\xd5\xf4\xb2\x94\x88\xc0\x29\x25\xdf\x9d\xda\xf7\x71\x74\x54\x13\x96\x0c\x6b\x41\xb7\x00\xa3\x34\x46\x13\x4d\xa9\xab\xed\xa3\xed\x5d\x59\xd4\xde\x8e\x35\x8e\xc6\xef\xb2\xa6\x56\xb7\x45\x89\x06\xde\xca\x2a\x53\x22\xc7\x87\x56\x4f\xee\xa3\x4e\xe3\xd0\xa1\x9b\x95\x28\x4e\x35\x54\xa7\x62\x72\x33\xb5\x31\x68\x2d\xde\x79\x45\x5c\x4a\xab\x74\x5d\x69\x4d\x20\x96\x2c\xf6\x2f\xdf\xea\x12\xcc\xad\x09\x08\x93\xa4\x1d\x67\xab\x12\x55\x6f\x48\xa8\x89\xd1\x86\xf6\x52\x1d\xe3\x5f\x42\x03\xc2\xfd\xac\x41\x2c\x49\xfb\x66\xa2\x22\xd9\x6c\x91\x42\x53\xc2\x84\xb6\xa2\x55\x4d\x1b\xe8\xcd\x57\x48\x35\x25\x31\xc1\x1d\xaa\x2a\xf3\x79\x4e\x82\xa6\x34\x66\xa8\xe8\xe6\x4c\x04\xf6\xcf\xb7\xfb\xd5\xfd\xf3\x66\xe5\xbd\x03\x34\xa5\x89\x51\xce\x3a\xca\xa2\x18\x07\x57\x45\xa9\x0c\x23\x37\x1f\x17\xc7\xa3\xcb\x67\xb4\xdf\xb5\xdc\xa0\x48\x48\x8b\x80\xcf\xcb\x1a\x16\x3d\x5a\x0e\x87\xf7\x26\x2d\x7e\xb4\x26\xb8\x94\x56\x1f\xbe\x4a\xea\x0f\x18\x86\xa7\xb1\xd9\xc6\xf2\xbc\x6c\xd4\xee\xd7\x90\x60\xad\x29\x8b\x25\x2e\x5a\xa3\xfc\x6d\x7c\x4f\x58\x4a\x02\x87\x0b\xf3\xfc\xa7\xee\x08\x4d\xc4\x8c\x47\xd3\xb3\x79\x2e\x60\xf1\x06\x85\x3a\x4f\x1e\x1b\xe3\x1a\xdf\xc6\x7d\xbb\x36\xac\x44\xbb\x5c\xa3\x2e\xc4\xef\xb2\x80\xc9\x59\x84\xc1\x5f\x54\x01\x82\x18\xf1\xad\x77\x87\x62\x9d\x5a\xeb\x01\xe8\xe8\xa9\x33\xb4\x65\x3f\x18\x24\xd6\x46\x40\xbf\xc1\x4b\xf6\xd6\x66\xa8\x77\xfe\x44\x09\xb5\x37\x66\x27\x60\x10\x74\xd0\x94\x04\xc8\xdb\x43\x2f\x80\xac\xf6\x48\x80\xc9\x65\xa6\x29\x70\x1b\xdf\x0d\x73\x72\x4d\x53\x6d\xdd\x86\xd6\xab\xdd\xef\x73\x02\xca\xd3\x94\xf5\x4d\xe7\xdc\x3a\xf3\xf9\x63\x82\xe2\xcb\xea\xe1\xac\xf7\x65\xae\x51\x4a\x66\x68\x35\x30\xbe\x5a\x11\x70\x12\x0c\x44\x4f\x3d\x8c\xb3\x7e\xe9\xc8\x4e\x9a\x0a\x13\x3b\x51\x0a\xef\x85\xef\x04\x0d\x6f\xb3\x42\x74\x77\x41\xa5\x0a\x8b\xfd\xaf\x95\x1a\x6e\xc4\x54\x71\x8a\xca\xa3\xb2\xca\xf4\x1b\x3c\x95\x7a\x22\x69\xae\x69\x3b\xe3\x70\x6f\x10\x39\xa0\x5d\xd7\x5a\x54\xf9\x79\x99\x55\x7a\x5d\xe8\x41\x2e\xad\xa9\x0e\x4d\xe4\x0a\xc1\x5f\xe1\xdc\xf5\x60\x4e\x1d\x37\xa0\x7b\x5b\xb4\x92\xb4\x03\x87\xce\x79\x2c\xb9\x71\x20\x52\x5c\x03\x7c\x6e\xd1\xd5\x83\x67\xbd\x50\x26\x2b\x83\x09\x23\x4c\x5e\xf0\x55\x6c\x17\xb3\x1c\x1a\xf0\x30\x14\x4d\x4d\x42\x71\xc1\x5e\x89\x2a\x1b\xde\x92\x30\x08\xac\x72\xeb\xc9\x8b\x14\x41\x3d\x93\x61\xf8\xc1\xce\x4a\xe9\x5e\xd4\x77\x65\xe9\x58\x60\xfe\x3a\xc3\x40\x5b\xc9\x2b\x1f\xa3\x5b\xe9\x9d\x31\x14\x43\x87\x01\x0c\x9e\xa0\x7b\x78\x9f\x29\xe2\xe9\x90\x50\x22\xc3\x5e\x05\x41\xbb\x82\x41\x07\xe2\xd0\x21\x49\x2c\x08\xe8\x59\x35\xa7\x7a\x74\x79\x34\xb4\x56\x1d\x0f\xa5\xd7\x5d\xb2\x4b\x9a\x38\x3a\xff\xe4\xb9\xf0\x32\x0c\x09\xe7\xae\x84\xd0\x26\x3b\xdf\xb3\x42\x97\x3f\xc7\xd3\x35\x0c\x23\x46\xb9\x7b\xc9\xab\x4c\xd9\x7a\xfd\xf8\x52\xa3\x54\x62\x7f\xc2\x6e\x47\x63\xdb\x83\xc9\x35\x32\x27\x84\x60\x67\xd3\xe4\xd5\x08\x99\xe4\x58\x06\x5d\xbc\xfe\xe9\xca\x14\xfe\xfa\x62\x02\x2e\x07\xc6\xe8\x23\x7b\x6b\xd7\xde\x69\x58\x17\xc6\xc4\x9a\x14\x62\xce\x63\xef\xf5\x85\x7f\x9c\x0e\x13\xa6\x85\x2f\x36\x3c\x8a\x1f\xb0\x69\x6e\x45\xd6\xdd\xe3\xc4\x30\xea\x02\x82\xc5\x5b\x56\xbc\x5d\x54\xb5\x75\x98\x4a\x6b\x49\xd5\x55\x85\x31\xa9\x7c\x36\xbe\x7f\xd3\x14\xb5\xcf\x3f\x66\xb7\xb7\x30\x75\xce\x3d\x73\x88\xa3\x01\x3c\x49\x87\x3c\xb2\x64\xb4\x7a\x22\x2a\xa7\x43\x1e\x33\xb4\x1b\x90\xa7\x33\x54\x8b\x09\xf0\x78\x74\x8a\x84\x22\x09\xe9\x76\xb1\xdc\x8c\xa6\x0c\xe7\xae\xa7\x8e\xdc\xd5\x2f\x33\x68\x81\xd1\x7f\x5e\x3d\xf0\xcf\xff\xd3\x3f\x26\xc1\x34\x68\xb7\xa0\xbe\xa0\x14\x86\x6f\x0f\xe8\x50\x18\x6b\x1f\xea\x17\x87\x07\x38\x94\x45\x33\x8c\x56\xda\x6c\x3f\x48\x07\x0c\xf3\x6d\x7d\x9c\xd1\xb1\xf0\xf9\x6b\x28\x35\x31\xa9\x23\x14\xd8\x39\xe1\xa4\xe9\xfb\x19\xa1\x1c\xb6\xe2\xbf\x4f\x7f\x67\x56\x66\x78\xbc\xc3\x86\x9a\xd1\xd0\x11\xc6\xe8\xb3\x99\x4c\x07\x1d\x33\xec\x48\x1d\xc4\xaf\xa1\x92\x53\xf7\xd9\x24\x40\x2c\x92\x55\x74\x6f\xae\xa1\xc3\x27\x53\x44\xa7\x0c\xd3\x84\x3b\x51\x88\xa9\xd0\xfb\xec\xb2\x1a\x6a\x30\x58\x59\x2a\xab\xf3\xdf\xc2\x7f\x39\x98\x34\x71\xf1\x59\x1b\x49\xe6\x59\xdd\x38\x73\xca\xf1\x87\x4d\x00\x38\x4b\x84\x93\x50\xfa\x07\x1e\x86\x3a\x34\x3a\x65\xdc\x25\x18\xb7\x27\xf5\xc3\x3f\xa1\x28\xa2\x02\x2c\x5a\xea\x5b\xfb\x3c\xbe\x0c\x81\x1d\xa3\x53\x44\x51\x02\x3e\xd8\xb5\x4d\x7e\x8c\x22\x8f\xe2\x38\x69\x70\xea\x28\x52\x56\x2e\xa0\x7d\x67\x1e\x5d\xfc\xba\x28\xf4\x76\x00\xb1\x7b\x82\x9f\xb8\x75\xa9\x77\xd1\x45\x0a\x51\x64\x08\x3e\x3a\x5c\x87\x51\x2c\xb0\xab\xa0\xeb\x88\x25\x54\x5a\xe4\x64\x37\xbd\x22\x06\x14\x83\x03\xf4\xb9\x11\x39\x0d\xc7\x36\xe6\x3a\x8a\x13\x43\x69\xbf\x86\xb5\xe7\x5c\x37\xef\xf3\xaf\x7a\x94\xd0\x04\x2b\xcd\x03\x45\xba\x4f\x37\xb8\x28\x61\x11\x82\x33\x0f\xfb\x76\xc2\x7a\xf8\x94\x8e\x92\x24\x41\x78\x19\x5e\xc7\x5d\x59\xba\x18\xb3\x8b\x1e\x3e\x7f\x56\x51\xa2\x12\xef\xab\x8c\xf7\xce\x81\xbe\xdd\x51\x9e\x12\xdc\x1d\x6f\x44\x0e\xe5\xc8\x81\x55\x47\x5c\xe9\xc4\x95\x6d\x3a\x8b\x0b\xbf\x17\x46\x5c\x0b\x4c\xf9\xeb\xa6\x3c\x3a\x85\xac\x7e\xea\x47\x82\x6a\x7c\xba\xe8\x9d\xaf\xca\x01\x9f\x7a\xf2\xeb\x74\x1a\x78\xbf\x9a\xbe\xea\x30\xd1\x13\x9e\xd1\x11\x6c\x3f\x08\x08\x53\x39\x15\x7e\x35\x58\xd4\x37\xce\xbf\xcd\xff\x0a\x88\x02\xd7\xed\xba\x75\x51\x5a\x77\xdd\xc0\x12\x04\x76\xbc\x3e\x3f\xac\x6d\x4f\x78\xbf\x7a\x5d\x2f\x3a\x53\x7d\x1d\x81\x20\xd2\xc1\x0c\xb0\x49\x70\x5b\x56\xcf\xce\x43\xd8\x0d\x61\x01\x0b\x88\xbb\xca\xa7\x72\xde\x04\x4f\xb3\xa0\x5d\xb5\x90\x2f\xbb\x85\xf6\x2e\xdd\x64\x35\x2a\xce\x22\x23\xf1\xb5\x1c\xb4\xa8\x66\x0b\x20\x8c\x18\x6b\x3a\x57\xdb\x46\x03\x4a\xec\x5d\xb2\xd3\x34\xa3\x84\xa0\xa4\x3e\x6e\x81\x7b\xa7\x46\xe9\xaf\x97\x51\x41\x8c\x3b\xcb\xb6\xa9\xb2\x1f\x63\x12\xfc\xe4\x2b\x43\x2e\x43\xe6\x4c\x29\x9b\x17\x28\xda\xc0\x76\xb4\xc0\x8d\x1e\x05\x0b\x25\x75\xcb\xf2\x47\xf9\x03\x5c\x75\x6b\x8e\x36\xaa\x19\x23\x69\xdc\xde\x8c\xf7\xb2\xaa\x01\xd5\x17\x6c\xc1\x7b\xfc\xfd\x2c\xb4\xf4\xdd\x6e\xf6\x88\xea\xec\x80\xe8\xd7\x9c\xdd\xae\x2a\xee\x69\xc6\x98\x93\xb6\x47\xf5\x95\xb2\x9a\x7e\x59\x42\xd0\xaf\x78\x3f\xb2\x54\x9b\x5c\x22\x93\x31\xb2\xdb\x9b\xf7\xac\xd2\x7d\x8b\x4d\xb3\x58\xa8\xc4\x6a\xc7\x2f\x1e\xd6\x7f\x76\x7f\x95\x0a\x91\x24\x4b\x51\xfc\xa8\xca\xcc\xff\x39\x89\xc2\xd4\x93\x21\xe1\x70\xaa\x2a\xf1\x06\xb7\x48\xba\x69\x13\xb5\xf1\xcf\x4a\x52\xe9\x44\x0f\x1a\x91\x23\x7e\xcd\xc3\x64\x35\x4b\x03\x0a\x74\x40\x83\xb6\xa0\xa8\xf1\xe7\xb9\xb2\xfd\x36\xff\x76\x74\xab\xc4\xdc\x2d\xe2\x9a\x20\xb2\x4f\x63\xf9\x7d\x36\x64\x64\x82\x52\xe6\x80\x2f\xd9\x9b\x4f\x4a\x9c\x90\xd5\xf8\x66\xa9\x28\xc2\xb2\xc3\xd1\x42\xd1\xfd\x5f\xd3\x08\xfb\xec\x59\x6d\xb5\x2b\x46\x49\x3d\x53\xca\xf5\x81\x2a\xa1\xc1\x59\x64\x74\x9f\x04\x8b\x48\xc7\x02\xe7\xd8\x93\xde\x8d\xd0\x4e\x7b\x19\x1f\x71\x7b\x7a\xdf\x5f\x62\x3a\x4d\x11\x92\xfa\xb0\xfb\xeb\xae\xfb\x1b\x00\xe2\xf3\xd6\x77\x77\x68\x49\x7b\xbf\xd8\xad\xee\xf7\x64\xf7\xed\x75\xe7\x09\x2e\x9a\x41\x64\xb0\xed\xbe\xac\xca\xdb\xac\x1e\x18\xd3\x6a\x66\x42\xab\xad\x5e\xc0\xaf\xc6\x97\x93\x6b\x8b\x55\xd9\x76\xf1\x0c\x33\xa9\xc6\x95\xcd\x94\xd5\x4f\x51\x69\xe4\xdc\x95\xae\x08\xe3\x40\x2b\xe3\x27\x66\x44\xc0\xdc\x2b\xba\xa8\x40\x5c\x49\x16\xe2\x80\x44\x08\x1a\xb9\xcd\x7e\x81\x5e\x41\x96\x0f\x10\xa3\xd3\xa1\x12\xd0\x97\x64\xb3\x7a\x9e\xf5\x30\xd0\x71\x00\x56\x9c\xa2\x1a\x69\x2a\x8c\xe1\xb5\xc3\x59\x10\x07\xa0\x53\xe6\xa7\xf0\xc7\xea\xd4\x38\x88\xd3\x14\xdb\xae\x63\x12\x45\xf8\x66\x2c\xf4\x87\x28\x14\xb4\x8b\xe8\x1f\xa5\xfa\x9d\x16\x91\x8e\x29\x4d\x70\x1d\x13\xa3\x5f\x34\x9e\xbd\x7e\x68\x02\xdc\xd2\x19\x76\xd5\x19\x5c\xe3\x7f\xa2\x3d\xa2\x63\x2a\x53\x2c\xf8\x64\x75\x1b\xf3\x57\x75\xd7\x45\x43\x4f\xa3\x31\x4e\x70\x76\xaf\x89\x43\x95\x24\x12\xdb\x7d\x7f\x8b\x4a\xbf\xc2\x31\x17\xed\x05\x0d\x41\x78\x17\x9f\x30\xc2\xb7\xf0\xb3\x5f\x90\xf7\x6f\xa8\x2b\xde\xfb\x20\x35\x8e\x12\xe2\x6f\xe8\x52\xd4\x90\x67\xc5\x4c\x09\x28\x8e\x12\x1d\x76\x78\x2b\x67\xd0\x8e\x61\x8a\xca\x8e\xe2\x5a\xce\x15\x47\x52\x79\xc0\x6e\x47\x28\xf4\xd4\x9a\x4e\x65\x4a\xc7\x2c\xe0\xf8\x66\xbf\x6c\xf6\xeb\x9b\xcd\x6e\x1f\x76\x07\x62\x89\xeb\xd5\x21\x2b\xbe\x43\xd6\x83\xd4\xfc\xf1\x38\xd2\xb1\xe8\x44\x29\xdb\x9f\x5d\x5f\xc2\xa3\xdd\xd8\x24\x10\x28\x84\x63\x79\x8a\xb6\x12\x7c\xa9\x0f\xa9\xe3\x24\x24\xd8\xc1\x7f\x38\xe9\xd3\x61\x18\x8e\xc4\x69\x6a\xf5\xa5\xd6\xcd\xfb\xcb\xb9\x12\x87\xae\x66\x12\xa7\xca\xb8\x70\xb4\xd0\x03\x6e\x8a\x8e\x39\xa1\xc4\x51\x85\x6e\x4a\x75\x3a\x5c\x0d\x2e\xfc\x78\x25\x70\xce\xfe\xd4\x1e\x17\x30\x0d\xda\x7d\x2a\x13\x73\xb0\x37\xad\xb6\x24\x83\x97\xaa\x6c\xc3\x31\x1f\x2a\xc6\x82\xda\xb0\xfa\x60\x39\xe5\xcb\xd3\xb8\x3b\x19\x8b\x58\x47\xb6\x2b\xe8\xe2\x6e\x04\xed\x7e\x56\x25\x88\x45\x6c\x50\xb8\xe8\x58\x95\xbf\xce\x17\x40\x8e\xd9\x64\x72\x7c\x75\x92\x59\x31\x97\x37\x68\x5c\xa3\xb8\x77\x53\xb4\x3e\xa0\xfe\xd7\x29\x96\xa2\x00\x52\x56\xf7\x85\xcf\xcd\x6a\xf1\xe2\x38\xef\x53\x6c\xed\xe4\x87\x2a\x65\xbd\x1e\x1d\xd4\xe3\x42\x9f\x43\xc7\x4a\xa7\xe8\xd9\x85\x1e\xe8\x8b\xdd\xe6\xf9\x69\xbf\xdd\x2d\xbe\xae\xbf\xf4\xc7\xb5\xcd\x71\x8d\x79\x69\xba\x9f\x05\x2c\x06\x3b\x9f\x8b\x33\x5a\x07\xd4\x4f\xe5\x2b\x34\x6d\x2e\xfd\x8f\xd0\x0b\xb1\xa1\x91\x8e\xbc\x15\xff\xa1\xf6\x70\x83\x24\xa0\x04\x03\x7b\x54\x23\xfe\x9a\x79\x17\x50\x9d\x04\x31\x0b\x5c\x08\xbc\xcd\x1a\xb8\xe2\xff\xa8\x93\x40\x5a\x09\xd5\xa5\x68\x9a\x1c\x9e\xcd\x2e\x6b\x44\x31\x2a\xd4\x24\x81\x0a\xd4\x50\xc6\x66\x57\xfa\x92\xef\xe7\x01\x7c\x42\x82\x14\x58\x6f\xc2\xf6\x50\x0e\xb0\xd8\xfe\x4d\x73\xe4\x67\xfb\x2f\x8d\xfe\xd7\x7f\x94\x24\xce\x7b\xaf\xd0\x16\xda\x3c\x3f\xb7\xda\x81\x78\x63\x50\x03\xe2\xb5\x3d\xbf\xff\xd9\x84\x69\xae\xf1\xca\xd4\x0f\x5d\x76\x53\x24\x21\x86\x20\x44\xdd\xc6\xce\xce\x6d\x9f\xee\x57\x8b\x17\x3f\x82\x72\xea\x65\xde\xdc\xbc\xb1\xaf\x40\xbb\x0b\x4e\x53\x22\xff\x11\x61\x69\x74\x1a\xf4\x49\x35\xa3\xe5\x61\xf2\x83\xa9\x49\x31\xc6\xb0\x02\xfe\x7f\x4c\x44\x58\x75\x12\x46\x32\x0c\xbc\xfc\xde\x63\x56\xa0\xfb\xc5\x6c\x4f\x3d\x09\x55\x80\x12\x6e\x87\xac\x68\xbe\x67\xcd\xfb\xd4\xf3\x66\xbe\x06\x9e\x44\x09\xc7\xae\x57\x56\xdf\x54\xd9\x07\xfc\x7d\x76\xcb\xb2\xad\x76\x23\xce\xb8\x57\x15\xd4\x49\x94\x12\x6c\x47\x1d\xca\x22\x1b\xf0\x87\x07\xed\x9a\x24\x32\x1a\x45\x99\xef\xf2\x52\x8a\x7c\x57\x9e\xaa\xd1\x04\x62\x2c\x0c\x3d\x65\x7d\x1a\xcd\x0d\xea\x3e\x09\x4b\x02\x0c\xf5\x75\xb9\x1c\xbc\x19\xfe\xa0\xb1\xb1\x4f\x7b\x92\xae\x2a\xe9\x8e\xc5\x01\x51\x81\xcf\xc5\xea\x32\xff\x18\x55\xda\xa6\xc5\x9c\x24\x09\x78\x60\x0b\xb2\xd9\xdb\xdb\x21\x1b\x27\x8f\x49\x12\x47\x2c\x71\x25\x82\xe5\xd3\x6e\xf2\x33\x52\x97\xd3\xe3\x1e\x3a\x95\x37\x19\xdf\x67\x4e\x53\xec\x0c\x22\xca\x80\xec\x4d\xa1\xbe\x74\x47\x38\x92\x78\x76\x37\xf3\x01\xc5\x70\xff\x49\x04\x63\x08\x2d\x7e\x39\xc9\xaf\x70\xbe\x17\xf5\xfb\xee\x7c\x84\x1e\x03\xd1\x8d\x33\x76\x0a\x16\x58\xe7\x7e\x36\x9e\x82\xd4\xdd\x25\xc9\x68\xe4\x36\xc5\xf6\x25\x6e\x44\x3e\x24\x98\xe9\x44\x69\x65\x5c\xe5\xee\xe1\xe1\x8f\x3d\xe8\xac\xd9\xa7\xa3\x9e\x4f\xa2\x8c\x41\x05\x88\x8e\x99\x55\x89\xe3\xb1\x17\x1a\x5d\x5c\xb0\xea\x74\xa2\xa9\xc5\x8c\xe3\xb7\xbe\x54\x30\x54\x90\xd5\x89\x16\x86\xdb\x25\xc2\x96\xe0\x45\x56\x7d\xa2\x20\xe0\x3e\x04\x4c\x82\x6b\x47\xac\xf2\x53\x07\x12\x49\x20\xb1\x6a\x84\xa7\x1a\xaa\xbb\xaa\xfc\x59\xbf\x94\x65\x3e\xfe\x3e\x48\x05\x3e\x5c\x0f\x3b\xb2\xc0\xf4\xee\x16\x81\x12\x48\x24\xbe\xfd\xf6\x74\xb3\x79\xba\xdb\xaf\x9f\x6e\xf6\xbb\xcd\xe3\x7a\xbb\x5b\x3c\x76\xcb\x83\xa1\x31\x38\x99\xac\xcd\x8b\x7f\x33\xa7\x52\x1c\xe3\x5f\x6c\x20\xc6\xae\xce\x3d\xe4\x59\xe9\xbf\x2d\x0d\x02\x22\xfa\xed\xa6\x7d\xd7\xb3\xe2\xcd\x99\xfd\x8c\x66\x5d\x1a\x70\xab\x17\x7f\xb4\x08\x82\xbd\xd5\x62\xed\xce\xa3\xc2\xc8\x46\x28\xb2\x0d\x51\x1c\x23\x61\x7a\x0a\xc5\x7d\x09\xc8\xfd\xe6\xe5\x79\xa3\x27\x83\x88\x20\xca\xc9\x62\xaf\x72\x71\xd8\x4d\xf1\x63\x29\x11\xb6\x49\xb6\x7c\xd9\x2f\x76\xf7\xeb\xa7\xcd\xc2\xa3\x77\x52\x02\xd4\xf7\x2e\x77\xa2\xf8\x81\x13\x6c\x2d\xaa\x02\xf4\xa8\xfe\x92\x12\x63\xbb\xa0\xb5\x30\x1d\x8a\x6c\xf5\x9e\xe5\x17\xa2\x9b\xf3\x91\x81\x3b\x0b\xa5\x31\x61\x5d\x04\x77\x5b\x56\x8b\x0a\x9d\x87\x6d\xef\xc0\xb1\x4d\x26\x3f\x3e\x64\x16\xab\x05\xa7\xaa\x74\x06\x85\x93\x01\x89\x09\x1d\x1e\xc0\x4a\x39\xec\x20\xcf\xa7\x29\x75\x1a\x2a\xc5\x59\x6f\xa6\xbf\x2d\xc4\xb1\x7e\x2f\x9b\x4e\xe2\xe6\xf1\x94\x4f\xcb\xfc\x69\x44\x8d\xd0\xae\xe8\x64\xdd\x1d\xfd\x6d\x8b\x84\xa5\x9a\xa8\xaa\x7d\xe1\xe6\x70\xc2\x3a\x65\x91\xd1\x2e\xfe\x71\x45\x98\xae\xc8\x96\x32\x6e\x30\x36\x42\x47\xf6\xee\x8f\x22\xc1\x15\xee\x8f\x72\x46\x06\xba\x5f\xb8\xd3\x38\x48\x91\x23\x8a\x9a\x76\xcf\xa7\x6e\x46\xc5\x51\x1a\xb9\x8c\xce\xa5\x49\xdf\x0a\x6b\xfe\x89\x50\xbf\x45\xbb\x6c\x80\x7e\x81\xca\xa9\x42\x8e\x7f\x6e\x1c\x07\xd2\x7d\xba\xb3\x30\x72\xd7\x35\x1e\x67\x84\x88\x87\x9c\xe3\x5d\x79\x97\x7d\xfc\xde\x44\xf3\xb3\x7f\x2f\x04\xc3\x27\xb7\x32\x71\xb0\x4d\xcb\xe0\x77\xc2\x3a\xbb\x72\x09\x36\x1c\xbb\xd6\x5f\x4b\xd3\x30\xc4\x55\xf8\x88\x17\xdc\x3e\xc2\xdd\xf3\xfe\x67\x97\x8a\xa4\x3c\x4d\x10\x9e\x63\xdf\xe5\x45\xa1\xef\xa0\x99\xb8\xdb\xeb\x54\x24\x06\x01\x30\x7f\x3c\x2c\x6d\x77\x17\x9d\x1c\x27\xd3\x4b\x28\xf0\xcb\xcb\xe9\x78\x0d\x60\xeb\xc6\x4a\x22\x11\xb8\x7c\xc8\x7e\x61\x5b\x79\x3e\xc8\x4b\xa5\x8e\x50\x83\x7f\xe7\xa9\xc0\x36\xe1\x04\x3d\x71\x3a\xf9\x3c\x08\x4d\x55\x68\x17\xbe\xa3\xcb\xc4\xf4\x44\xf4\x5d\x23\x48\x41\x74\x98\x27\x47\x63\x76\xcb\x0d\x9d\x8e\x65\x01\x96\x17\x2d\xd4\xf8\x5b\x91\xa9\xb2\xf2\x9b\x70\xaa\x39\x45\x48\x66\xf3\x0e\x1d\xa4\x5d\xa7\x40\x41\xa0\xc6\x90\x90\x79\xf9\xb3\xfb\x6b\xc4\xb0\xfc\xdc\xbc\xc3\x5d\x95\x4d\x27\x23\x30\x8d\x09\x2d\x1c\xa0\x42\x5c\xc1\x40\x7b\xfa\xd3\xb2\x76\x6a\xa8\xd0\xc3\xbe\xce\x28\xe6\x48\x4d\x92\xe0\xab\x73\xb7\x5e\x93\x20\xe8\xfe\xca\x99\xb5\x53\xb7\x85\xe5\x9b\xea\xf4\x36\x89\xda\x78\xc0\x85\xe6\x1e\xb5\x04\x7a\x51\x38\x87\x88\xb9\x04\x9e\x93\x34\x40\xce\xca\xeb\xaf\xf5\xe2\x61\x87\x1a\x94\x39\x8c\xa5\xb6\x34\x27\x3c\x24\x56\x82\xa6\x78\x7b\xe8\xfb\xe0\x9c\x40\x1a\x38\x09\x7e\xdc\x54\x57\x65\xf5\xcf\xb4\x8d\x74\x1b\x00\xbb\x22\x5c\xbb\xdf\xcc\x79\x28\x68\x4e\x93\x20\xf6\x56\xa8\x95\x98\xa6\x4a\x9c\x26\xd6\xc4\xee\x20\x7e\xb9\x4a\xec\x58\x1b\x47\x73\x9a\x0a\xe3\x6d\x91\x44\x27\x27\xa4\x39\xe5\x04\x25\xfa\xb2\xfa\x01\xde\x44\xbe\x68\x1a\xe1\xa4\x93\x66\x7e\xa8\x22\xd8\x74\x6a\xa0\x6e\x7c\xad\xbc\x3b\x8f\x02\x6c\x2f\xd9\x76\x21\xf6\x59\xee\x41\xe0\x7e\x3f\xd8\x4a\x38\x35\xda\x84\xc3\xe6\x7e\x5d\x4f\x4b\x5c\x3c\x4c\x58\x0a\x63\x40\x78\x97\xf4\xf1\x10\x04\x52\x6b\xdb\xd0\xf4\x16\xe0\xe9\x74\x70\x1a\x3e\xdd\x71\x85\x6f\xe9\xb1\x2c\xf3\xef\xc3\x9d\x9b\x47\x01\xc3\xc8\xd8\x6a\x7d\x2d\x4e\x4d\x59\x65\x5a\xe8\x75\x3b\x77\xca\x4a\x8c\xbd\xbd\x34\x8f\x78\x8c\xe5\x6d\xf0\x8c\x0d\x84\x20\xf4\x98\x5f\x1e\x71\x6b\xd8\x7c\x33\xf9\xf9\x2c\x36\xa4\x13\xa2\x9d\x66\xe0\x7e\x8c\xa1\x11\x73\x71\xef\x0f\x98\x54\x75\x79\x12\xeb\xc4\x5a\xaa\x7f\x20\xd5\xf5\x70\xc8\xea\xba\xef\x9b\xf0\x24\x89\x2d\xec\x6c\x48\x22\xed\x8e\x69\x2c\x54\x63\x19\x14\x75\x5c\xf2\xb2\x9e\xa2\x0f\x78\x0a\xb6\x5f\xbe\x77\x37\x63\x2e\xe5\xe1\xa9\x89\x20\xec\x52\xb3\x95\xa8\x74\x7d\x03\x06\x3a\x06\x8f\xe6\x3c\x0a\x90\xc1\x63\x97\x95\x57\x68\x44\xd6\x11\x6f\x35\xe7\xcc\x20\x6d\xce\x07\xb0\x8b\x42\xdf\x8e\x40\x62\x93\xe9\xc5\x25\xc5\xde\x2e\x14\x1a\xbd\xd6\xdc\x9f\x45\x22\xb1\xd4\x87\x65\xdb\x17\xa8\x9c\xbf\x9e\x0d\x3e\xae\xa4\xda\x5c\xe8\x20\x85\xee\xb7\xf7\x45\xa9\xee\x7d\x10\x46\x75\x39\x7b\x23\xde\xfa\x4d\x9e\xcb\x28\xe2\xd2\x27\x38\x1f\x50\x9c\x00\xab\xc9\x56\xa0\xa3\x87\x4a\x8d\xaa\x26\x5c\xa7\x8c\xa8\xce\xcc\x15\xdf\x30\x5c\x69\x76\xe5\x42\xf5\x98\x4b\x0e\x31\x44\xc9\xc0\xa2\x70\xb3\x7a\x1e\x6a\x3d\x6b\x0e\xa9\xc0\x47\xbf\x7a\xbc\xbb\x23\x74\xeb\xfc\x34\xfe\x21\x3d\x81\x83\xb1\x4a\x21\x0f\xe5\xdb\x4b\xbb\x69\x58\x3a\xf0\x30\x73\xe1\x26\xe4\xb8\x68\x5a\x8f\xd0\xc9\xe4\x31\xdc\x32\xe5\x9c\x58\xfc\xac\xd1\x91\x1d\x2a\x82\x90\x73\x57\xbb\x7c\x12\x4d\xf6\x01\xaf\x70\x3c\x35\xe2\xb2\xf1\x23\x08\x63\x58\x03\xb0\x8c\x4c\x2b\x1b\xd6\xa7\x80\x82\xc4\x10\xd9\x85\xa9\x12\x6d\xc2\x35\x43\x49\xd7\x82\x70\x4b\xbf\xab\xf1\x1c\xed\xa2\x51\x0d\xdc\x72\xb5\x20\x90\x50\xb7\x2a\xb4\x73\xfe\x25\x17\xe3\x4a\x9a\xa0\x82\x0a\xe2\x9a\x55\xd5\x47\xef\xa4\x05\xdd\x00\x0d\x48\xd0\xfa\xbe\xfe\xfd\x7d\x16\xd4\x28\xe4\xcc\xce\x02\x34\x66\x22\x68\x11\xea\x24\x74\x26\x4c\xbb\x72\x28\xba\x3e\xad\x18\x8a\x28\xd6\x68\x62\xd9\xff\xc2\x3f\x15\xe4\x93\x5b\x1a\xe9\x50\x71\xdf\xec\x1d\x52\x16\x44\xa4\x6d\x2d\xa7\x80\x9f\x96\xf1\x33\x29\x9e\x08\x96\x5a\x47\x53\x84\xe4\x35\xfd\x72\x26\x98\x92\xac\xb3\x8f\xec\xfe\x68\x34\xca\xbd\xda\x7a\x6c\xd7\x66\x1b\xed\xce\x22\x8e\x01\xd9\xf2\xbd\x0b\xd2\x1c\x8c\x4f\x24\x71\x8a\x19\x01\xae\xdc\x55\x79\x98\x18\x67\x5c\x99\x67\x89\x0e\x50\x34\x11\x3b\x5c\x98\xba\xf4\x4e\x1b\xe3\x91\x69\x40\x31\x2a\x04\x4b\x35\xc5\x70\xf3\xb2\x6c\xe6\x07\x33\x1a\xb9\x37\xc5\x7a\x4e\xba\x54\x70\x28\x62\xe7\x87\x26\x16\x39\xef\x4e\x74\x7b\x2a\xf4\x4b\x2e\x1a\x53\x56\xbe\x8b\x23\x52\xc1\x50\x06\xa4\xc0\x37\x01\x37\xbf\xf7\x76\x2a\x4f\x4e\x64\x28\xee\x28\x7b\xf4\xec\x42\xfd\x82\x8b\x84\x47\x70\xa2\x11\x34\x79\x2a\xfc\xc6\xd8\xe9\x11\x6a\xc1\x65\xe2\xe1\xf0\xf7\x90\xe7\xbe\xfc\x26\x84\xb0\xc2\x77\xf7\xcf\xdf\xb6\xeb\xfd\xfa\xe6\x6e\xdd\x1d\x31\x81\xa0\x7e\xe2\x7d\xe6\x0c\xe4\xc6\xcb\x30\x45\x5d\x9e\xe5\xf3\xd3\xb7\x2d\xd9\x3f\x6c\x1e\x37\xbe\x0d\x24\x54\x60\x1d\x65\xef\x30\x63\x1b\x71\xbd\xb5\x50\x89\xa5\xf2\x3a\x14\x64\x0f\x81\xf5\x03\x34\xa3\x26\x72\x32\xb1\xd1\xe4\xa2\x21\xd4\xd6\xfa\xa4\xcd\x75\x1e\x4e\xea\xc7\xd8\xb1\x61\xfc\x13\xc1\x61\x84\x47\xfa\x94\xbf\x49\x63\xfc\x47\x79\x88\xb5\xa0\x7d\xdd\x66\x22\x76\x96\x8e\xfb\x3b\xb3\x2f\xf1\x85\xf3\x8d\x3f\x9d\x8e\x2c\xaf\xca\x55\xe7\x71\x9f\xb0\x3a\x77\x73\x2a\x5d\x5a\x98\x20\xd5\xbc\x97\x50\xdc\x36\x70\x38\x8a\x2b\x5d\x70\x61\x22\xed\xf9\x30\xbb\xf2\x84\xcc\xd6\xa2\x19\x74\x95\x85\x61\x01\x9a\x42\xd9\x6a\x8e\xcf\x13\xae\xd6\xfa\x47\xbf\x5d\x06\x54\x63\x71\x7d\x97\xbd\x9d\x44\xc1\x06\x9d\x4b\x19\xa4\x04\x1b\x36\x76\x75\xa1\xdd\x9f\x21\x0d\x5d\xa5\xf6\x92\xeb\xe0\xc6\x10\xca\xb1\xa8\x6f\x45\xf8\xbd\xb7\xee\x5e\x75\x5d\x69\x49\x94\xc2\x1e\xf9\xcb\xb7\xe5\xc3\x66\x85\x6a\x81\xdb\x3d\xd9\xbf\x2e\x76\x7e\xce\x4a\x1a\x5a\xf9\x47\xe9\x93\x7c\x2c\x6f\x7c\x2b\x94\x55\x8e\x5d\x95\xe5\x8f\x0c\xba\xc1\x31\xc1\xfa\xd4\xbb\xa8\x86\xa6\x62\xfe\x70\xc4\x25\xd6\xa0\xd0\x1c\xc8\x0a\xfb\x5f\xc9\x3a\x65\xa4\x85\x75\x88\x75\xeb\x8b\x65\x74\x62\xc4\x37\x5c\xfc\x25\x23\x96\xca\x7b\xf7\xf8\xaf\xdf\xf6\x29\x25\x23\x29\xc6\xbb\x7e\xd1\xca\xc6\xed\x2a\xc9\x22\xc5\x87\x68\xdf\xad\x8d\xde\xc7\x0b\xa8\x7f\xff\x25\x4b\x38\x46\x54\x6d\x38\xfa\x50\x76\x40\x5f\x19\x2b\x82\xe6\x84\x9b\xed\xf0\x39\x26\x24\xc5\x76\x20\x16\xbc\xc6\xfa\xe2\x5a\x26\x69\xa8\x9c\x66\xff\x3d\xd6\x90\x1d\x61\x66\xfe\xa5\x93\x49\x2a\x42\x17\xb8\x58\x7e\xf2\x4c\x36\x2d\x13\x35\xb0\x40\xf5\x33\xb6\x0d\x22\xda\xc7\x78\x0b\xdd\x33\x4b\x03\x16\x7a\x7e\x82\x0b\x35\xe6\xa0\xd0\x32\x35\x29\xd6\x36\xd6\x0f\x8b\xdf\xa8\xd1\x6b\xc9\x63\x16\x9a\xc1\x8d\x1c\x7a\xed\x6b\xc9\x93\x08\x81\x92\x56\x5d\xce\xde\xe9\x61\xad\x52\x72\x45\xc2\x5e\x43\xe3\xa5\xcc\x33\x87\xb5\x70\x71\x93\x94\x3c\x48\x85\xb7\x01\x5c\xe4\xb9\x7b\x85\xfd\xe7\xa5\x04\x8f\xda\xbe\x05\xd8\x4d\xad\x71\xb4\x54\xd4\x68\xe2\x25\x8a\x7e\x7a\xd1\x84\xcf\xdf\x51\x9d\xd8\xfb\xd9\xee\x17\xa2\x7e\xcf\xae\xe8\x67\x6b\xa9\x8d\x40\x2e\x38\x12\x4c\x45\x8e\xf4\x39\xaf\x2a\xe2\x86\x40\x28\x5d\x7f\xc8\xa1\x01\xb6\x4d\x25\x1a\x78\xeb\xee\x00\xc4\x0a\x57\x93\xbd\xb3\xe3\x47\x36\xc4\xb5\x65\x71\xf4\xf5\x2a\x20\x14\x41\x6c\xab\xff\x76\xfe\x43\x5a\x05\x89\x4d\x07\x8f\x99\x2a\x8f\xf5\x3e\xab\xf7\xe0\x44\x4b\xdd\x00\xa2\x22\x64\x86\x60\x2e\x29\xb2\xdc\x4a\x7d\xb5\x6f\xf0\x8b\x40\x21\x3c\x71\x80\xa7\xb2\xcf\x35\x14\x15\xd4\x9a\x87\x3c\xae\x56\xeb\xd7\x15\x0d\x3e\x9b\x0e\x2a\x0a\xac\x7b\xc5\xcf\x7e\x49\xb8\x81\x0f\xc8\xcb\x23\x54\xf5\xaa\x2b\xbe\xa9\x28\xa4\xd8\x21\x5a\xdc\xbe\xe2\x14\xfc\x07\x67\x66\x61\xe2\x02\xdf\x9b\x13\xe4\x64\xfc\x9c\x55\xa4\x62\x61\xb1\x12\x28\xbb\x89\xcd\x9d\xf1\xdd\x8a\x85\xc1\xa7\xfa\xad\xd6\x3d\x53\xfe\xa3\x0d\x68\x67\xd7\x25\x15\x03\xc5\xfe\x7c\x59\x38\xa5\xb7\x09\x4a\xad\xdd\x79\x69\xda\x77\x91\x77\xa2\x42\xcf\x24\xa1\xde\x07\x63\x42\x66\xd9\x45\xed\xf4\x7d\x18\x70\xde\xdc\xf1\x94\x05\xb8\xa9\x3a\x4d\x95\xf6\x75\xab\xed\x23\xd1\x9b\xa2\x81\x1e\xeb\xaa\xd2\x94\x9b\xb8\xdf\xc3\x6e\xb2\x5a\x9e\xaa\x1a\x2e\x6b\x16\x8a\x47\x56\x26\x70\x2b\x8e\x19\x8c\x82\x7e\xc5\x19\x49\x2d\x0f\xb6\xce\xde\x8a\xae\x0b\x31\x67\xdc\xa3\x15\x77\xed\x55\x5c\xff\x75\x25\x0e\xdd\x59\x1c\xf3\x62\x99\xe5\xb9\x2c\xfb\xee\x8a\x12\x01\xc3\xf8\x58\x64\xd5\x6d\x55\x1e\x5f\x4a\x6f\xa0\xae\x95\x60\x56\x8c\xf9\x54\xeb\x17\xa8\xd6\x5d\x6a\xa6\x44\x22\x02\x2b\x91\x8c\xc5\xb1\xc7\x4e\x0d\xc1\x0f\x90\x94\xe1\x4e\xd3\x6d\x4b\x74\xaa\xa4\x3a\x79\x2d\xa4\x73\xe2\x56\xed\xcd\xbc\xcd\xb3\xe3\xb1\x7f\x1e\x9a\x31\xeb\xa1\x24\x4f\x67\x94\x2c\x1b\xa8\x02\xfa\x21\x71\x84\x2c\x68\x9b\x5c\x2f\x0a\xbd\x2e\x74\xf9\xf3\x66\x7e\x81\x56\x9a\x73\x44\x4e\xec\x11\x22\x22\xff\xbe\x10\x81\x9f\x8e\x37\x40\xe8\x48\x77\xa2\x83\xc4\xfc\x13\x70\xaf\x32\x49\xca\xbd\x37\xec\x10\x14\x7c\x53\x16\xdd\x2d\x35\x5a\x08\x3d\xd0\x29\x2c\xce\xd3\x5a\xbd\x32\x26\x32\x5d\x01\xd6\xc3\xd4\xb2\xe2\x0d\xf1\xa7\xc5\x74\x2a\xe8\x80\x59\xae\xda\x1b\x34\x9b\x83\x13\x9f\x7d\xb0\x80\xe5\xe1\xcf\xf4\xb8\x19\x4d\xa2\x34\x70\xbf\x72\x89\x64\x97\xc9\xf9\x08\x24\x68\xb1\xfe\xd7\x5f\xcb\xe1\xfc\xd4\x04\xac\x09\xe2\x1b\x34\x48\x8a\x6d\x63\x4d\x5b\x24\xf1\x23\x28\x91\x81\x55\xc3\x46\x2a\x4f\xfb\x4a\x65\xc5\xdb\x28\x99\xd7\xa1\x22\xdc\x65\x0e\x03\x58\xcc\x28\x62\xd2\x11\x4d\x1d\x2c\xb2\xbd\x47\xf7\xa3\xe0\xd1\x0f\x49\x34\x86\xd6\xdf\x9d\x6e\x9e\xff\xb3\xa1\x9c\x7a\x83\x34\x57\xfc\xde\x42\x9e\x7b\x07\x07\x3f\x8e\x09\x45\x23\x7c\x0d\x3f\x60\x7c\x00\x28\x02\xbf\x94\x28\xd6\xed\x4c\x1e\x72\x72\xdc\x90\x38\x0e\x70\x96\x64\x85\xc2\xdc\xab\x82\x49\xab\x58\xc7\xdc\x16\x5a\x44\xa7\xae\xf5\x58\x6a\x3f\x03\x74\xac\x20\x71\x8f\xf7\xd5\xa3\x3c\x26\xbb\xbc\x4e\x22\x26\xa5\x67\x55\xb7\xf1\xcf\x3f\x99\x7f\x3a\x89\x12\x04\xbc\x76\x6f\xe3\xd7\xf3\x6a\x57\x2e\xc1\x71\x1d\x26\x05\x2f\x9d\xe8\x58\x13\x27\x17\x79\x3a\x1e\xbb\xaa\xa0\x4e\x20\x8a\x86\x85\x67\x91\x7b\xd6\x90\x1f\x91\x3a\x43\xcc\x1a\x0a\xed\xfd\xf7\xfc\x31\x1e\x30\xfc\xf4\xe3\x62\x37\x88\xbc\xb4\x48\x09\x56\x83\xb0\xfe\x66\xcd\xa9\xd1\x92\xe0\x37\xdb\xe9\x7c\xd6\xd2\x26\x65\xb8\x36\xef\x8f\x0e\x8d\x86\xb5\x36\x93\x5d\x31\xef\x6f\x3f\xc0\xb0\x5f\xf7\x08\x3a\x53\xe2\x7c\x2a\x1e\xb2\xe2\xc7\x67\x9b\x9a\x96\x11\xb5\xd1\x8d\x5d\xfe\x1d\x03\x62\x70\xa1\x8a\x0b\xac\xec\xbb\x2e\xbc\xed\x77\x5f\xdc\x65\x65\x52\xe2\xaa\x6e\x7b\x0d\x22\x6f\xf3\xac\x8b\x06\xab\x86\x38\xb0\xfd\x06\xdf\x90\x2c\xaf\x78\xb7\x68\x0d\x3c\xc0\xc0\xf6\xb6\x44\x98\x42\xcf\x02\x73\xc7\x0d\xa3\x88\x76\x02\x51\xe5\x67\x07\x18\xc1\x2c\xac\x1b\x90\x70\x2a\x1d\x2e\xda\xe1\xb2\xef\x44\x8d\xca\xdf\xe3\x5f\x05\x01\xa5\xd8\x6e\xd7\x55\x79\x5c\x14\xea\xbd\x9c\x45\xe2\x41\x10\x19\xac\x81\x8b\x53\xf3\x5e\x56\xed\x36\xec\xbd\x01\x11\xf4\x67\x79\x5c\x64\x2c\x98\xe0\x3f\x0a\xca\xea\xb0\xdf\xaf\xbf\x3f\x3f\xdc\x92\xe0\xcf\x71\xfe\x70\xed\xdf\x6b\xb9\xed\x04\xdd\x31\xbe\x1c\x42\x1d\x9e\xb1\xe8\x1b\x9d\xd7\xe1\xcf\x40\xb4\x42\xad\xa0\x0a\xb7\x9a\x37\xc8\xeb\x4e\x60\x4e\x03\x25\xd6\x41\x07\x95\x19\xca\x1c\x44\x61\xa1\xe5\xa3\x33\x50\x1e\x21\xcb\x4b\xbd\xff\xb0\xaa\x09\x9f\xc1\xd4\x80\x8a\x80\xb9\x70\xf8\x5b\x36\x35\xaa\xfd\xaf\xc1\x8d\x9f\x36\x15\x21\x0c\x09\x52\x56\xfc\x0b\x7b\xf3\xfa\xf2\x6d\xf2\x28\x23\x13\x61\x39\x44\x68\xfd\x04\x3f\x17\x59\x85\x5a\x0c\x33\x65\xbd\x8b\x50\x16\x18\x09\xf0\x85\xc6\xf2\x98\x6d\x1e\x63\x19\xc9\x67\xc1\xc0\x12\x4b\xb9\xfa\x03\xba\x59\x08\x31\xa7\x69\x64\x7b\x1f\xb5\xaa\x32\x79\xa5\xe8\x04\x31\x57\x98\x64\x38\x7d\xc1\x1b\x91\xe5\xe7\x9b\xec\x63\x52\x77\x87\x98\x1b\xeb\xd8\xee\xf6\xd5\x85\xf5\x2f\xff\x8d\x22\x94\x86\x58\x86\x51\xd8\xa1\x9d\x6e\xab\xf2\xb0\xcc\x85\xfa\xd1\x06\x56\x93\x6f\x48\x22\x21\xdc\xdd\x5f\xd7\xc8\x30\xb0\xcc\xee\x49\x8b\x11\x52\xc6\x71\x73\x72\xb9\xe1\x4a\x5c\x5b\x72\x00\x29\x24\x6e\x91\x7c\x96\xed\xe0\x36\x94\x2f\x4f\x4d\x87\x93\x9a\xbf\xdf\xed\xcf\x46\x51\x84\xd5\xb0\x04\x01\x3c\xa4\x58\xcf\xf5\xdd\xcf\x2b\xdf\xca\x1d\x46\xbb\xcd\xb7\x3a\x87\xe1\xa9\xac\xec\x3f\x7c\xad\xdc\x29\x45\x1c\x60\xd4\x65\x81\x70\x47\xd0\x99\x18\xfe\x30\x45\x12\xb4\x51\xca\x8a\x8f\xac\x99\x22\xcc\x41\x85\x5a\x58\x8b\xc9\xba\xa9\xca\x2b\x12\x0f\xa0\x52\x92\x3a\xd7\x78\x2b\x13\x3d\xa8\x64\x83\x86\x10\x75\x59\x8e\xb6\x10\xb0\x71\x2d\x20\x57\xf2\xdc\x14\x1a\x77\xd0\xf1\x09\x35\x28\x61\x7d\x13\xeb\x66\x51\xe8\x65\xe7\x02\x3e\xbe\x5b\xc0\x42\xc9\x7d\x0e\x2f\x2a\x3d\x30\xf0\xfa\x6d\x93\x12\x0c\x89\xb0\x90\x81\xd8\xbf\xfd\x11\xaa\x11\xfa\x1e\x0c\xd1\x98\xd2\xb7\xe1\x64\x56\xa8\x1e\xf1\xde\x0d\x08\xa9\x74\xb1\x10\x3e\xa6\xa5\x68\xd4\x3b\x5e\xb8\x9b\xc9\x84\xa6\x17\xff\x85\xb6\x3a\x03\x24\x45\x37\xd5\x8d\x54\x88\xab\x45\x45\xd1\x70\x92\x83\x99\x20\x76\xc0\x54\x57\x8b\xec\xb0\x94\x37\xf0\x81\x1c\x25\x3f\xce\x68\x61\x91\xe1\x8b\xe3\x31\x77\xea\xb5\xeb\x5f\x59\x53\xcf\x35\x21\x0c\x09\xa2\xd8\x56\xef\xcc\xa9\xd0\xfe\x0a\x27\xdf\x4d\x98\x65\x1c\xe1\xdd\x19\x26\x5a\xff\x35\x19\x27\x52\x6c\x78\xaf\x9f\xfe\xbb\xc7\xd7\x8e\x9f\xab\xa1\x41\x8a\x5b\xd2\xb6\x29\x8f\xff\xf2\x3f\x9a\x26\x14\xcb\x54\xab\xb2\x3e\x94\xa3\xad\x73\xfc\xe1\x30\x20\x42\x78\xae\xc4\xd7\xf3\x8c\x8f\xf3\xfc\x12\x68\x42\x26\x24\x8c\x84\x04\x16\x85\xb6\xae\x4d\x57\xea\x0f\x26\x4c\x53\xd5\xf9\x25\x7f\x73\xe4\xe9\x45\xa1\xbf\x15\x23\xb2\xb2\x9f\x0c\x26\x14\x14\x21\x2f\x4a\x38\x0c\xe4\xf2\x74\x7e\xea\xa9\xc5\x93\xb3\x47\x44\x61\x90\x2e\xba\xfb\xe4\xfa\x95\x3d\xb2\xc7\x44\xb1\xf5\x1b\xfc\x37\x14\xda\x9b\x42\x6a\x13\x39\x7f\xb5\x53\xa1\xca\x12\xcd\x5e\xb2\x0f\xdb\x10\x9d\xd4\x67\xed\xbc\xe3\x43\x9b\x70\x6d\x22\x4d\xd1\xc9\xeb\xee\xe1\xcf\xd5\x80\x32\x68\x18\x8b\x90\x88\x3d\x36\x58\xd2\x86\xa5\xa1\x0d\x46\x1c\x62\x77\xb9\xbc\x19\x29\x1e\x6a\xc3\x8c\x42\x25\x86\xbd\xb3\x9e\x9d\xb7\xc2\x9a\xcc\x94\x98\x50\xdb\x46\x6d\x6f\xee\xc2\x41\x69\xf0\x1d\xea\xee\x67\x2c\x74\x6c\x25\x3c\x16\x55\xe5\x20\x69\x9b\xfa\xa9\x6c\x6c\x6f\xe3\xb6\xac\x1c\x00\x7a\x7c\x63\x63\x61\xbc\x90\xe7\xea\xfe\xee\xdb\xf6\x66\x06\x85\x6d\x12\x1e\xea\xf6\xdc\xf8\x1c\xdb\x20\xe7\xcb\xb0\x21\x36\x17\x4c\x98\x94\x5a\xbb\x9f\x5f\x69\xea\x55\xec\x4c\x9a\x28\xfc\x89\xfb\x8e\x61\x58\xaa\x1f\x9d\x10\x54\xff\x75\xa9\x50\xa9\x2d\x65\x29\xf0\x8c\x78\xa4\x50\x7e\x08\x79\xe9\x7a\xe9\x3f\xa4\xac\x43\xf6\x1b\x34\xb7\x15\xc0\xee\x54\x35\x79\x97\xaa\x99\x54\x29\x9c\x6d\x7b\x9b\x63\x75\xae\x3f\xe3\x9b\x21\x62\xa3\x64\xdf\x3e\x5a\x68\x6d\x0d\x14\xfd\xe1\x24\xc0\xfa\xe2\x32\x6b\x7e\xc0\x08\x72\x6b\x84\x49\x4c\xd0\x33\x20\xeb\x81\x8e\x88\x91\x01\x61\xc6\x7b\x96\x8a\xba\x53\x16\xf8\x0e\xd9\xe4\xc2\x65\x10\x19\x17\x3b\xaf\x7f\x65\x75\xb3\x82\x7c\x92\x8d\x19\xc9\x39\xc6\x61\xcd\x50\x67\xa4\xb6\xb6\x71\xf9\x45\xa3\x76\x72\x8f\xa4\x32\xbe\x05\xb9\x12\xc7\x0b\x02\xad\x51\xa0\xd3\x1e\xac\x85\xd7\xbe\x1e\x95\xec\x8c\x26\x34\xa2\x43\xeb\xed\x6a\xab\xca\x0a\x36\xc5\xf2\x94\xff\xb8\x1e\x97\x18\xed\xba\x63\x6d\xd2\x5e\x68\xf8\xb5\x9c\xe2\x0d\x26\xef\xbb\x86\x10\xc1\xe4\x42\x66\xe3\x64\xd9\x80\x49\xa2\x4e\xb4\xac\x16\x39\xec\x91\x25\x36\x50\x8c\x32\x86\x24\x48\xaa\x7b\x3d\xd6\x03\xc1\x11\x63\x22\x81\xef\xa6\x50\x0d\xe2\xaf\x87\x9d\x7d\xeb\xbb\x6d\x32\xa8\x46\x11\xad\x31\x60\xe3\xa9\x1f\x1f\xea\x26\xfb\x98\xaf\xbb\x18\x03\x0c\x91\x98\xf2\x74\x7e\xc9\x07\xc0\x9c\xf1\x1b\x61\x0c\x47\x76\xa1\x97\xd1\x82\xa3\x45\xf9\xdc\xc2\x78\xfe\x43\x10\xb0\xce\x0a\xd1\x1f\x24\xdd\xb1\x58\xcb\x5e\xee\x4b\x9f\x54\xb3\x6d\xda\x1d\x66\x0e\x7d\x07\x41\x90\x28\x4c\xb3\xde\xb2\x0f\x58\x37\xef\xbf\x46\xca\x44\x10\x04\xa9\x44\x3a\x8c\x33\x97\xc5\x7d\x71\xbc\x28\xba\x07\x08\x01\xd1\xd6\x0f\x75\xa1\xf5\x50\xef\x62\x12\x9f\xff\xd7\xe5\x5f\xdd\x3f\x97\x4c\x1f\x08\x68\x12\x62\xd6\x8f\x73\x7d\xa0\x34\xe9\x0f\x73\xcb\x5f\x73\xef\xec\xd4\xe2\xc1\x8d\x0a\x99\xc0\x7d\x67\x09\xcd\x73\x71\x2f\xea\xf7\x3f\x52\xea\xaf\x2f\x62\x41\x48\x7a\xb4\xb3\xeb\x4c\x5f\xb1\x9b\x87\x20\x4a\x43\xc2\x3a\xcc\x4d\x59\x4d\x94\xcc\x27\xf7\x36\x4a\x53\x91\x0e\xde\xc4\xac\xda\x8a\x5c\xdc\xc0\x8b\xa8\xc4\xa7\x1d\x56\x08\x22\x9e\x60\xfe\xe2\x52\x6d\xa7\x70\x6c\x13\x2a\x37\x84\xc5\x06\x9c\xee\xc6\x32\xab\x9a\xf7\xde\xce\xae\x3f\x0d\x93\x20\x3b\x6d\xc2\x2f\x23\x73\x8b\xdf\xfc\x7b\xf1\x86\x42\xc0\x34\xe3\xda\xb9\xeb\xed\x4a\x57\x42\xe9\x45\x5c\xcb\x1c\x97\xb4\xc9\x0f\xd0\xa9\xc0\x6e\xb6\x2a\x0f\xc7\x53\x03\x4f\xf0\xab\xb9\x83\x22\x18\x74\x85\x21\x88\x53\xeb\xd6\xf4\x91\x55\xcd\x49\xe4\x2e\x3f\x1e\xed\x8a\x10\x24\x3a\xd1\xa2\x37\xd1\xfa\x9a\x35\xcd\x79\xa1\x46\xca\xdf\xdd\x2f\x4e\xfd\x4f\x4e\x29\x63\xbd\x99\xe2\xf3\xcf\x02\xa5\x96\xc6\xcf\x34\x95\x14\x6b\x44\x8f\x59\x01\xf5\x73\xb1\x43\xfe\xc0\xf8\x2a\x52\x65\x51\xc8\x76\x4d\xb3\x2b\xfe\xef\xf2\xf1\xf1\x19\xb8\x4a\xbd\xd1\x54\x9b\x1f\x39\x94\x7b\x57\xd2\x9e\xfc\x24\x0e\x02\x79\xf6\x6e\x56\x5a\xea\xef\x15\x47\x5c\x08\x04\x33\xc2\x9a\x41\x7c\x88\x2a\x13\xc5\xf4\x6c\x42\x4b\xe3\xd0\xd1\x1d\x8b\x80\x10\x7f\x5f\x85\xe1\x3c\xf4\xcb\x05\xae\x7a\xb7\x03\x4b\xa0\x2b\x97\x23\x03\x9b\x5e\xd7\xd0\x6c\x21\xcf\x2f\x58\x86\x10\x48\x29\x30\x0c\xce\xca\x9f\x85\xff\x2a\x45\x53\xdc\x3c\x74\x25\xb2\x62\x2f\xf2\xbc\xb9\x9e\xfc\x43\xa0\x42\xab\x47\x6a\xc1\x67\xe8\x00\x3e\x27\x99\x07\x81\x4a\xad\x09\x5f\x6f\x6a\xf2\xff\xdb\xcd\xc4\x9d\x59\xb3\xc0\xca\x8c\xb7\x21\x58\x27\x92\x70\x5b\x56\x73\xef\x9a\x96\x01\xb6\xed\x7f\xc0\x79\x61\xb7\xb0\xc9\x00\x48\x0d\xaa\xfa\x3b\xa6\x43\x47\xf3\x9b\xbf\x7c\x10\x0c\x1b\xfb\x36\x26\xb3\x9b\xf8\x6d\x79\x95\xa4\xe7\x3f\x05\xc6\x23\xda\x76\x99\xfa\x01\x63\x7a\xff\x74\xb0\xb1\xd0\x00\x0d\xa6\x2a\xeb\x91\x93\x3e\x04\x26\x66\x60\x79\x7b\x4b\xc8\xcb\x9f\x63\x65\xc3\xe1\xbe\x05\x81\xe1\x12\x5b\xf1\xdb\x83\xa8\x1a\x25\x2a\xd9\xeb\x67\xcc\xff\x4a\x03\x40\x86\x5e\x55\xaf\x60\xc6\x6f\x3b\x09\x48\x8a\x68\xa1\x83\xf8\xb5\xeb\x23\xda\xee\x68\xcc\x4d\xd8\xeb\x00\x3a\x3e\xff\xec\xdb\x41\x02\x09\x78\x91\xc7\x2a\x3b\x88\xea\x3c\x40\x9b\x00\x21\xc4\xba\x68\xba\x4f\x3c\x1b\x6c\xec\xed\x4a\xd5\xc5\x6d\x40\x68\x60\x23\x22\x6b\x67\x0b\xbb\xf2\x45\x9c\xad\x99\xd5\x48\xd1\x09\x08\xa5\x09\x3e\xde\xaf\xbb\x55\xe7\x88\xd8\x9d\x24\xa5\x1e\x15\xe1\x68\xdb\x08\x62\x1b\xff\xd2\x30\x0a\x11\x5b\xf5\x28\x9a\xf7\x17\x84\x01\xf4\xf7\x23\x52\xd6\xb7\x76\xe4\x75\xe4\x8e\x31\xc2\x23\xe7\xb6\xbd\xcc\x9a\xba\x9c\xc3\x69\x02\x61\xc0\x23\xd9\xe9\xbb\x19\x0c\x1c\xfd\x21\x63\xa3\x69\x6c\xfb\xb9\x2d\xad\x3b\x7b\xcc\x02\xa4\xf0\xd4\x5d\xcd\x7d\x57\x2e\x4f\xe7\x2e\xaf\x00\x92\x68\x40\x88\x6b\x87\x56\xd2\x93\xaf\x4e\x83\xc4\x36\x8d\x3f\x44\x9e\xe9\x09\xa9\x1a\x48\x9a\xc4\x28\x4f\x70\x84\xea\x20\xda\x2c\xd6\x1f\xe0\x29\xe7\x30\xe3\x05\xe4\x0f\x03\x60\xc4\xee\xbc\x0b\x2f\x0a\x29\x93\x89\x20\x88\x42\x1a\xdf\xf7\x4e\x14\xc8\x34\xbb\xf2\x52\xef\x00\x88\x60\x0c\x59\x6f\x12\xdd\xa0\xfd\x1f\x05\xc5\xe5\x48\x36\xb5\x37\x2a\xf7\x6b\x28\x91\xdc\x60\xcc\xbb\x7a\x7d\xfe\x7e\x83\x68\xe4\xef\x8b\x87\x87\xf5\x6e\xbf\xb8\xb9\x79\xed\x06\xc9\x38\x0c\x7b\x23\xf1\xab\xbf\xfa\xf4\x5b\xce\x04\x10\xcd\x99\x43\x06\x37\x1d\x83\xe0\x5e\xe4\x03\xb4\x23\x10\xa0\x02\x6d\x6b\x31\xb5\x5f\x2c\x37\x38\xe3\xfc\xb1\x10\xb0\x5b\xf1\xf2\xfc\xb8\x58\x3d\x6f\x9e\x06\x7f\x97\xa4\x73\xb0\x5e\x9e\xce\x03\x4d\x1a\x3f\x04\x24\xb6\xf1\x97\xa2\xaa\x20\x5f\xbc\x81\xbe\x7d\x7e\x7c\xf6\x27\x30\x81\xf5\x9d\x5d\xdf\xfd\xf5\xb2\xeb\xfe\xa8\x05\x56\x3e\xbf\x97\xd5\x0f\x55\x66\xc5\xbc\x69\x24\x10\x63\xa4\xad\x8a\x40\xdd\xec\xde\xab\xf2\x67\xfd\x0a\x58\xd1\x1a\x5b\xf7\xac\x0b\x67\x59\x69\xff\xaf\x9f\x87\x34\x48\x8c\x08\x3a\x35\xc6\x76\x89\xc5\xc5\x6f\x18\x34\x51\x0a\x96\x0d\x6c\x0b\x77\x79\xd9\x34\x65\x72\x23\xce\x97\x80\xb7\xd9\x39\x44\xc3\xd8\x16\xc0\x6b\x68\x16\x45\x9b\x50\x5d\xe6\xc2\x40\x23\x6a\x01\x19\x63\xd9\xeb\xdd\x3c\x5f\x16\x28\x0b\x12\x6f\x82\x81\xa6\xa0\xab\x53\x75\x99\x79\x02\x8d\x43\x40\x22\x9c\xc9\xaa\xba\x71\x00\xfc\x2b\x9b\xf4\xe5\x4e\x46\xe3\x94\x87\xce\xdd\x62\x0b\x85\x7e\x79\xde\x5e\xe9\x9f\x0d\x17\x76\x1a\x0b\x4a\xfd\x3a\x5b\x6e\x5f\x61\x4e\x46\xc1\x0f\x55\x01\x06\x87\x3f\x45\xd6\x0c\xfb\x9b\xed\x91\x30\xb0\x65\x9c\xca\xd7\xd8\x2c\xbd\xc2\x1f\x07\x86\x51\xc1\xfe\x90\x15\x68\xec\xbe\x6d\xaa\x69\x9a\x41\xaf\x5b\x6b\xbb\xb3\x24\x21\x20\x70\x50\x9e\xce\x0f\x99\x82\xa2\x86\xdb\xb2\xb2\x38\x8d\xf1\x0f\x4d\xb4\xf5\xa4\x72\xd6\xaf\x73\xf4\x2e\xa0\x69\xa0\x11\xf7\x64\xb2\x42\xb7\x21\xeb\x5f\x03\x14\xf4\xa0\xfa\x03\x34\x0d\x6d\x3f\x08\x1c\xc7\x7f\x57\xce\x14\x55\x81\xf2\x94\x21\x3a\xfd\x80\xe6\xbc\xb8\x35\x4c\xed\x5d\x80\x72\x6d\x55\x77\x30\xda\xd8\xcb\x5e\x3f\x11\xa8\x08\xed\xde\xe2\x74\x7a\x7d\x2f\xbd\xbb\xc7\x22\x8e\x92\x60\x8a\x31\xbc\x12\x58\x51\x91\x86\xd8\xae\x5d\x1f\xfe\x23\x86\x92\x8f\x40\x85\x0c\x6d\xb6\xd7\xd7\x0e\xae\x24\xe1\x33\xf8\x65\xa0\x02\x58\xec\xb1\xbb\x59\xf1\xd6\x37\xf9\x81\xaa\xd8\x44\x7a\xe0\xb9\xf8\x47\x1b\xd4\x65\xe3\x7a\xe6\xd0\xb4\xcd\x7d\x4c\x07\x31\xe7\xfd\xbe\xd9\xc0\x3e\xf4\xa9\x1b\x85\xc0\x82\x98\x75\xb9\xb1\x15\xdc\xa1\xf6\xfa\xb5\xf7\xd9\x7f\x96\x06\x49\x32\x58\x3f\x6b\x27\x1e\xb4\x1a\x02\xea\x7a\x5a\x1e\x84\x41\x18\x20\x20\x7a\x09\x75\x33\xe3\xac\x09\x61\x10\x25\x9e\x43\x84\xf9\xc1\xa4\xfc\x8e\x03\x3a\x8a\x6c\x55\xd6\xf5\xaa\x2c\x0a\xe4\x94\x8c\x8b\x6e\xf3\x71\x5d\x18\xb0\xb4\x8b\x78\xca\x1a\x91\xd1\x1b\x3d\x65\x6e\x4f\x3e\x92\x84\x9e\xcb\x77\xb1\x8a\x87\x24\x4a\x50\x8e\x03\x11\xbf\x8d\xc8\x51\x36\xf4\xd3\x98\x3f\x24\x71\x48\x47\x82\x85\xeb\x37\x44\x12\x4c\xcf\x9c\x24\x28\xac\xe0\x9b\x32\x9b\xa3\xa9\x91\xa2\xb8\xcb\x9a\x89\xdc\x33\x84\x94\x12\x2b\x3a\xeb\xcf\x69\x9f\xc6\xbf\x9a\xf3\xf2\x6c\xb5\x93\xc6\x27\xa7\x89\xd6\x2e\x59\xe9\x2a\xeb\xf3\x37\x8c\x42\x84\xb0\x1a\x40\x5b\xee\x81\xc7\x26\x84\x21\x0f\x64\x34\x52\x53\x7b\x84\xe6\xbd\xd4\x8b\xe5\xa6\x1f\x22\xb1\x0e\xa9\x3a\x00\xb6\x57\x47\xfc\xfc\x31\x45\x21\x23\x71\x8f\x37\xf8\x9e\xa1\x84\xe9\xae\xfc\x9e\x15\xdb\x73\xdd\xc0\xc1\x7f\x01\x23\x76\x3e\x3d\xf6\xdc\xf9\x95\x25\x6e\x4f\xf7\xc6\xff\x57\xce\xa5\xff\x82\xc4\x12\xf0\xdb\x8d\xf3\x09\x7e\x3a\xe1\x47\xdc\x0b\x2d\x61\x74\xe3\x6a\x8d\x8b\x42\x2f\x6e\xc0\xfe\x77\xf7\xeb\x12\x89\x7b\xcd\x22\x6b\x97\x6c\x63\x32\xd5\x23\xd1\x5f\x9f\xb7\xdd\x4f\x9b\xab\x91\x84\xb1\xe0\x88\x44\x7b\x82\x53\xe5\x2b\xa3\x10\x26\x81\x44\xea\xfd\xd0\x06\xe6\x53\x82\x27\x84\x09\xd5\xca\x02\x83\x4c\x56\xc0\xaa\x9c\xa0\x25\x21\x4c\x84\xf6\x72\x66\x6e\x99\x5a\x54\xd5\x04\x3c\x04\x61\xa2\x2c\xf6\xd7\x11\x00\xcb\xea\x3b\x64\x7d\x9d\xc7\x0d\xe2\x44\xe1\x02\x8b\x3b\x70\xbb\x6d\xd0\xb0\x3b\xc4\xec\x9b\xfd\x2a\x0a\x5d\x1e\x86\xd6\xe4\x10\x0a\xc9\x49\x38\xaa\xb5\x0e\xf1\x4b\x73\xb5\x94\x4f\xdb\x2a\x10\x0a\xc3\x43\x33\x90\x02\x7e\xcc\x26\x80\x39\x08\x65\xc4\xa8\x8b\xfd\xbc\xea\xc7\x25\x52\x01\x42\xa9\x63\x2c\xec\x6d\x91\x0b\xa8\x01\x31\x86\x83\x15\x4d\x47\x80\xcd\xb1\xdb\x4c\x96\x85\x50\x2a\x1b\x30\xf0\x20\xd4\x2c\x0c\x42\x4f\x6f\x72\x7a\xde\x73\x9c\x26\x08\x75\x6c\xed\x2f\x50\x29\xbf\x8d\x2d\x86\x32\x86\xd3\x67\xa1\x13\x0b\x41\x6d\xc3\xa2\xdb\xb2\x6a\x4e\xdd\x0e\x11\x6a\x69\x98\x5b\xe1\xd0\x0b\xec\x45\x54\x4d\x01\x95\x4b\xfc\xc6\x77\x49\x2b\x15\x07\x8e\x18\xb7\xaf\x8f\x99\x82\xfd\x01\xf2\xa1\x44\xad\x1b\x08\x44\xa3\x04\xb8\xc9\xea\x77\xa8\xfe\xea\x54\x85\x06\x23\xb4\x95\x34\xac\xed\x2f\x1f\xc8\x54\x8c\x67\x63\x14\xc4\x81\x67\x55\x7c\xcd\x8a\x37\x5d\x0e\x29\x35\x10\x91\xc8\x3a\xe3\xac\xf3\xec\x57\x37\x3f\x22\x12\x4b\x64\x89\x55\x38\x77\x6e\xb3\xb7\xf7\x86\xde\x80\x68\xde\xc7\x84\x51\x88\x48\x62\x35\x46\xee\xc6\xa6\x48\xa7\xab\x68\x1c\x88\x68\x64\x70\xad\x29\x8b\xdc\x66\xb5\xdb\x2e\xb9\x9c\xdb\xa1\xa2\x30\x92\x18\x67\xdd\x2c\x6e\xfa\x5e\x35\x44\x61\x2a\x13\x67\x61\x7f\x14\xe7\x61\x38\x10\x85\x90\xa0\xc6\x81\xc5\xda\x7e\xcd\x74\xfd\x90\x15\x3f\x7e\x07\x67\x87\x28\x82\x04\xd5\x0f\x6e\xd6\xb7\xaf\xcf\xdb\xdd\xfe\xf1\xf9\x69\x77\xff\xf0\xd7\x58\x30\x0c\x22\x46\xad\xb4\x7a\x1b\x64\x75\xf2\xcd\x17\xaa\xff\x10\x31\x16\x5a\x27\x2f\x55\x65\x03\x7f\xb1\xc1\x74\x8d\x18\x13\x28\xce\xe4\xca\xd4\x48\xb2\xff\x74\x7d\x8c\xe2\x54\x58\x83\x29\x87\xd5\x7a\x14\x93\xba\x60\x14\x0b\x23\xdc\x8e\x7e\x63\x5d\xa8\xee\x2a\x81\xdc\xc2\x3e\xb8\x8d\x62\x19\x63\xee\xfb\x03\xce\xf5\x2b\xa8\xf9\x42\x4b\x14\x9b\x04\x1f\x55\x7b\xdf\xff\xfc\xf4\xd6\xc5\x46\x4a\x2f\x2b\xdc\x26\xf3\x7f\x96\xd5\xad\xc8\x72\x2c\x27\x3d\x3f\x2f\xfd\xd7\x26\x51\x8a\xc5\x21\xa7\x50\x31\xc6\x23\x9f\x2e\x21\x2c\xe9\x48\xe0\xb0\x5f\x05\xa2\x44\xa6\x28\x47\x86\xfa\x38\xaf\x5e\xe8\x71\xfe\x0d\x48\xb4\xb6\x4e\x54\x43\x47\xc5\x97\x7e\x0e\xa7\x51\x12\x59\xaa\x79\x59\xd6\xe0\x0c\xbf\xe7\x2e\x92\xc7\x29\xb6\x6a\xdb\x60\x7f\xfa\x22\xf0\xc4\x46\xb2\x3a\xab\x8f\xb9\x38\x3f\x65\x13\x10\x32\x44\x9c\x4b\xbc\xf6\xe2\x74\x18\xd5\x41\x22\x2e\x28\x92\x7e\xdb\x4d\xc5\x05\xda\xfd\xa1\x88\x38\xdc\xbf\xf3\xac\x6a\x23\xa8\x0b\x52\xd9\xe4\x8b\x94\xb1\x22\x7a\x65\xae\xb7\xe5\x29\x5f\x82\x12\xa7\x7a\x3a\x3b\xb9\xd6\xb8\x62\xb7\x8f\xe9\xb2\x6f\xf0\x3b\xf0\xde\xa7\xfc\x1b\x88\xb8\x31\x58\xda\x59\x14\xcd\xdf\xa3\x57\x53\x50\xdb\x6f\xfd\x56\xf4\x10\xb3\xc9\x0f\x13\x3c\xc2\x1d\x77\xa3\xca\x57\xa8\x4f\x87\x6e\xb3\x8b\x84\x4c\xb0\x14\xb4\x5c\x3c\x7d\x7d\x7d\xf6\xb6\x52\x10\x09\x6d\xa2\x8e\x93\xec\x30\x7c\xdd\x52\x26\x8c\xf8\xff\x38\xfb\x93\xee\xc6\x71\xac\x5b\x18\xfe\x2f\xef\x28\x07\x35\x00\x3b\x10\xf8\x66\x92\x2c\x47\xb8\xc2\xb6\x5c\x92\x9c\x91\x59\x77\x3d\x4b\x0b\xcd\x81\xcd\xc7\x14\xa9\x22\x29\x3b\x54\xbf\xfe\x5b\x3c\x00\xd8\x89\x76\xe6\xbd\x93\xca\x28\x03\xa4\x48\x10\xcd\x69\xf6\xd9\x1b\xb1\x58\x56\x1a\x66\x44\xe5\x35\x9f\x5a\x8a\x25\xb1\xba\x5a\x16\x69\xd4\x3a\xff\x50\x2d\x66\x42\x53\xb1\x34\x2c\x74\x19\xab\x26\x47\x7a\x63\xd7\xa0\x68\x6c\x09\x4c\x2a\x51\x34\xf5\xa0\x1a\xce\xb7\xcb\x10\x97\xa8\x33\xb7\xea\x83\x68\x4d\x9b\x83\x3c\x5f\x26\xbf\xa0\x89\xf0\x6c\x99\xf7\xa5\x7a\x3b\x9f\xee\x07\x41\xf7\x79\x5b\x2e\xd6\x09\xf1\x07\x92\x2f\xf6\x19\x07\x29\x63\x20\x06\x17\x44\x03\xe2\xb8\x28\xf4\xfa\xd7\x09\xaa\xa6\x1e\x4f\x4a\xc3\xa9\x55\x1f\x3b\x59\x40\xa6\x2f\x7f\xc5\xa4\xe8\x27\x0b\xcd\x88\x14\xf7\x26\x61\x73\xf4\xdf\x45\xed\x74\xff\x87\xe4\x21\xb6\x6f\x42\x92\x00\xd3\xca\x1f\x90\xf9\x60\xd6\x97\xaf\x95\x10\x61\x29\xe5\x5d\x3c\xb3\xa7\xfe\x75\xed\x41\x4c\x02\x97\x25\xb7\x16\xcf\x30\x55\x93\x04\x49\xa8\xbb\x12\x55\x84\x00\xe2\x5b\x67\x50\x28\xb8\x87\x77\xf0\x52\x2c\x93\x1f\x0d\x34\x45\x74\xb1\x11\x59\x5e\x0b\x03\x07\xa1\x75\x36\x54\xd7\x9c\xf4\x0f\x49\x80\xd1\x84\xf5\x6a\xb1\xfb\xee\x7f\x3b\x54\x32\x09\x3c\x94\x59\x95\x95\xfe\x01\x97\xdf\xae\xe4\xbe\x5d\xe7\x28\xb1\x8a\x89\x79\xa5\x9c\x7b\x38\xfe\x78\x49\xa4\x2d\x44\x4f\x9d\x8f\xad\xe7\x91\xbd\x4f\x6c\x87\x24\x32\x31\x56\x70\x9d\x2a\xc8\x54\xd9\x6b\xa9\x41\x12\x47\x22\x70\xa6\xc0\x7d\x29\x8a\xb1\x89\x32\xde\x44\x92\x84\x48\x84\x14\xe7\x02\xed\x70\x2c\x06\xe8\x2a\x82\x20\x49\x75\x84\x7e\xc0\xb1\xd4\x99\xb9\x7c\x2f\xab\x1a\x2e\xb7\x00\x96\x25\xd7\x72\xb5\x0f\x47\xc8\xe5\x45\x13\xc6\x22\xe2\x79\x5a\xce\x4d\x59\x94\xc7\xf2\x5c\xef\x4a\xd3\x7c\x88\x0a\x36\xd5\x4b\x0f\x2e\x80\x84\x07\xdc\x4b\xfc\xad\x75\x79\x9d\xaa\x49\x78\xa8\x44\xbb\x83\x61\x4a\xed\x07\x14\xba\x44\x5a\x0a\xdf\xca\x35\xc2\x09\xfe\xb7\xcc\x8a\x4e\x9d\xd7\xb7\x89\x00\x23\xd6\xb8\x27\x3c\x64\xc5\xb7\xd2\xcb\x0c\x40\x22\x43\x86\xae\x3b\xb6\xd9\xcf\x14\x5a\x49\xfb\x30\xf6\x69\x5f\xb7\x6f\x78\x44\x97\x7f\x20\x15\x82\x87\xbe\xf9\x2d\xba\xd3\x49\xb1\x05\xfd\x9d\x66\xc3\x64\x35\x68\x9e\x8a\xb0\x57\x3f\x70\x2c\x17\x5d\xfd\xe7\xf8\xbd\x81\x07\x58\x64\x08\xbf\x40\x9d\x11\xaa\xf0\xe6\xea\x32\xf1\x02\xa1\xae\xe4\x5f\x21\x01\xe0\xd0\x57\xc0\xa8\x8b\x8b\xf7\xf8\x1d\xf0\xff\xb0\xff\x19\xcd\x42\x30\x31\xc6\x0b\x31\xac\xf5\x9a\x41\xae\xff\xa2\x44\xad\xbd\x84\x21\xc2\x63\xf5\x9a\xbd\xc3\x90\xf6\x0f\x28\x89\x65\xd0\xd1\x97\x59\x91\xc8\x69\xa2\x0b\xf1\x6f\xf4\x7f\x06\x47\x3c\x0d\x02\x85\xe1\x75\x47\x84\x57\x95\xc7\xe7\xc2\x52\xb6\x8d\xdf\x8d\x86\x52\xa2\xa3\x73\x93\xbd\x64\x8d\xc8\x07\x46\x22\x0d\x15\x67\x61\x8f\x95\x5b\x6c\xff\x18\x16\xc6\x01\x8d\x62\x12\x5a\x82\x72\xa7\x1f\x39\x39\xd6\x69\x94\x0a\x0c\x7e\x77\xa7\x95\x27\x30\xf9\x9a\xee\xc6\x5f\xad\x6d\x4c\x01\x51\x41\xa7\x7e\x9f\x99\xe9\x09\x06\x33\x76\x99\xb2\x72\x9c\xde\xa4\x71\xa9\xcd\xc1\x2a\xa6\x71\xc0\x11\xd7\x84\x71\x47\xe4\xad\x18\xe5\x73\x68\x2c\x2c\x88\xf3\x29\x6f\xb7\xc7\xd1\x87\x48\x8c\xd5\x36\xcd\xcb\x97\x45\x9e\x0f\x66\xcb\xe4\x64\xa3\x54\x89\xc4\x78\x26\x87\xaa\xb6\xa1\x21\xf4\xd6\xe6\xe4\xbc\x81\x52\x6d\x4b\xb4\x15\x0a\xaf\x7b\xa2\x7f\x36\x79\x49\x6a\x00\x67\xf9\x7e\xbf\xfa\x5b\xe5\x68\x40\x99\x21\x84\xa0\xaf\x60\x23\x2c\x77\xc5\x00\x5a\x34\xb9\x3b\x27\x16\xe3\xb0\x68\x6c\x74\x44\xd8\xb5\xe7\xdf\x9d\x47\x14\xc1\xf6\xf6\x70\x68\xed\x0e\x3c\x20\xda\x4d\x6b\x71\xca\xba\x5e\x31\x43\x5e\xa5\xa7\xef\x9b\xf5\xe3\xdd\x1f\x87\xd5\x66\xbb\x5b\xdc\x6d\x0f\x0f\x8b\x3f\x0e\xab\xc5\xf6\xdb\xa6\xeb\x98\xc4\xba\xe3\xa6\xbe\x55\xfd\x0d\x14\xe0\x42\x6b\xed\x40\xd1\xa8\xd7\x2f\x70\xe2\x40\x39\x84\x24\x1e\x8a\x34\xd5\x33\x94\x42\xa3\xc8\x13\x15\x81\xc4\x13\xe9\xe9\xee\x8f\x91\x62\x8c\x6f\x0e\x05\x7a\xcf\xed\xf3\x3e\xad\xb7\x77\x9b\x9b\xc3\x6a\xf3\xdc\xf9\x2e\x54\x26\x31\x0d\x7d\xc5\xc0\x4a\xa8\x57\xb8\x81\x1a\xc9\x80\x41\x6f\xe1\x54\x56\xcd\x63\xb9\x7b\x2d\x3f\x96\x65\x31\x5d\x66\x32\xb1\x24\x20\xf5\xf9\xf8\x5d\x54\x7a\x25\x4e\x4f\x67\x99\x67\x6a\x38\x37\x65\x6a\xf7\xb1\xcc\x1d\x17\xb6\x8a\xda\x37\xb2\x04\xb7\x81\x77\x91\x9f\xe1\x1b\x34\xbf\x8d\x3e\xb5\x04\xc7\x5f\x2d\x2e\xbf\x4d\x42\xe7\xae\x87\x82\x40\xba\xd5\x64\xb5\xde\x76\x90\xe7\x5e\xc1\x73\xdc\x55\x87\x09\x6e\xe2\x07\x44\x44\x41\x01\x75\x1d\xe6\xc3\xe5\xe7\xfb\x25\x51\xe0\xf1\x00\x67\x89\xfc\xb3\xcd\x04\x3b\x06\x54\xa7\x5a\x0e\xd5\x73\xea\x26\x6b\x30\x58\x6b\xe9\x7d\x66\x19\xfa\xff\x31\xb9\x85\x16\xf8\xe8\xd6\xcd\x1b\x0a\xa5\xfd\x0d\x28\xc6\x70\x67\xa6\xda\x44\xb8\xd2\xe0\x17\x54\x2a\xab\x61\x73\x1a\xad\xdf\xcf\xef\xd1\x6f\xac\x26\x8c\xd0\x40\xcc\x8b\xdf\x46\x83\x61\x58\x8c\x1e\x01\xaa\x21\x0d\xb5\xb8\x26\x64\x34\xbe\xbb\xd6\x08\x41\xaa\x90\xff\x6e\xed\xf5\x67\x81\x1a\xc3\xb9\x53\x0d\xf8\x3d\x2b\xe0\x22\x2a\x3d\xda\xef\x5d\xed\x43\x7f\x9c\x0e\x0f\xd1\x94\x18\xed\x29\xdf\x10\xe4\x39\x62\x82\x1c\xbc\x46\x1a\x68\x40\x48\x63\xeb\x86\x3b\xa7\xcd\xb7\x98\x18\x89\xf0\x0e\xaf\xa2\x5e\xe4\xf9\x2e\x7b\x99\x07\xe3\x41\x1a\x32\x63\x8f\xc5\xb2\x30\x19\xaa\xdd\xb4\x46\x97\xbf\x4f\xc8\x29\x7e\xb5\x87\xcd\x62\x35\x3a\x37\xd2\x50\xf0\xd0\xc6\x4b\x8b\xb7\x6d\x99\xe7\x4b\x28\xc0\x64\x2a\x13\x55\xdf\x45\x09\xcc\x7c\x23\x55\xb1\x0f\x5a\xf6\xcb\x7b\xf5\x7a\x2e\x7c\x9a\x24\x8d\x92\x24\x4e\xbd\x10\x24\x54\xcb\xcb\xfa\x28\xb2\x1c\x73\x0d\x63\x0e\x02\x48\x23\x6e\x15\x32\x5e\xa0\xb3\xea\x27\x1d\x74\x8c\x12\x3e\xf9\xb9\xb8\x54\x1d\xe9\x9b\x6b\x8c\x03\x2b\x5d\x9c\xd5\x96\xed\x64\x5b\x76\xc2\x60\x90\xc6\xb1\x2d\xdd\x6d\x2a\x51\x38\x59\x63\xa8\x7a\xa1\xb7\xf9\x11\x8c\x45\x82\xe5\xb9\xe2\x5d\x54\xe2\xc5\xb2\x83\x0c\x82\xd6\x69\x12\xca\x98\xf8\x92\x13\x94\x05\x43\x9c\x92\x6f\x8d\x53\xe5\x0a\x98\xfc\xd0\x8c\x63\x40\x93\x5f\x4b\x92\x00\x63\x88\x0d\xd4\xcd\x5d\xd1\x20\xff\xbb\xdd\x63\x5c\x9c\x32\xfa\x9f\xae\xa7\x05\x2e\xa1\x7a\xdd\xee\x8a\x9b\x1d\xd2\x44\x6b\xab\xfd\x69\x43\x4f\xc3\xa0\x58\x4a\x89\x40\x5b\xe6\x7d\xf0\x05\x7c\x53\xd2\x15\x81\x3d\x88\x22\x33\xed\x83\x7c\x4d\x06\x0d\x29\x4d\xe3\xc0\x65\xa7\x7f\xbe\x8a\x1c\xfc\x6c\x98\x09\x7f\xa6\x94\x85\xcc\x52\xea\xee\xc4\x84\xde\x06\x52\x0a\x11\x92\xe2\x2d\xb3\x3c\x2f\xcd\xbd\xd0\xdd\xd1\x9e\xa6\x11\x41\x50\xc1\x9f\x9b\xe7\xe1\x91\x9f\xa6\xc2\xa0\xa6\xf3\x72\x37\x30\x8e\xd3\xd4\xa9\xf5\x35\xbd\x09\x60\x00\x46\x60\x95\x34\x35\x80\x3b\x8d\xf4\x65\x36\x2e\x56\x3d\xcd\x10\xa5\xa9\x31\x81\xf1\xc9\x77\x0c\x5f\x7c\xae\x90\x0e\x29\x33\xc4\x58\x53\xf7\x38\x8b\x55\x86\x94\x27\x21\x52\xd2\x68\xf1\x3e\x7a\x15\xae\x2d\x96\xa4\x86\xe6\x70\xea\x89\xdf\x9d\x44\xf5\xfc\x11\x9b\x8a\x80\xf2\xd4\x93\xf5\xcf\x88\xe1\xfb\x6e\x9c\x5a\x28\x49\x6b\xf5\x1f\xde\xcb\x66\x54\xff\x05\xa9\x8c\x28\x96\x0d\x9c\xc4\xe5\xf6\xea\x81\x25\x27\x5e\xa8\x6a\xff\x32\xcb\xb0\x0c\xa9\xe2\x80\xee\x48\x5e\xbe\xdc\xe6\x65\x59\xfd\x76\xed\x1d\xa5\x4a\x52\x6f\x2e\xce\xe0\xb0\x52\xa5\x13\xac\x52\xec\x8b\x9a\xd7\xbf\x5c\x89\xf6\xdf\xca\xad\xa4\x9a\x98\x38\xc6\x14\x57\x7b\x6e\xff\x80\xd6\xda\xad\xa1\xa8\xbb\x6c\x47\x0a\x84\x62\xdd\xaf\x3c\x5f\x7a\xcb\xd2\x3f\x1e\x44\x31\x86\x9c\x4d\x55\x1e\xbf\xc3\xaf\xf1\x00\x01\x4b\xb9\xe9\x33\xc5\x8b\x3e\xbf\xe6\x83\xe8\x29\x70\x8e\xe7\xe8\x90\xa0\xe2\xcb\xac\x42\x0a\x5c\x58\xa5\x5a\x9f\x66\x7b\x6a\x4d\xf0\xfe\x69\x45\x22\x9d\x3f\x3b\x3e\x00\x8c\xb6\xc5\xc3\x4d\x75\xd9\xe1\xc9\x5e\x94\x1a\x6c\x90\x61\x8e\x8d\xa6\xbd\x40\x51\xa7\x20\xb7\xec\xd4\x86\xb3\x69\xd0\x3d\x35\xc6\x60\xcd\x7f\x56\xe8\xec\x3d\xd3\x67\x91\xe3\x06\xda\xc9\x92\x00\x23\x42\x23\xb1\xe5\x6b\xa9\xf3\xbf\x51\xe9\x0b\x2c\x60\xb6\x58\x4d\x60\xa5\x08\x1e\x76\x1d\x1a\xd0\x77\x91\x8a\x3b\x7d\xa0\x01\xa3\xf1\x72\x26\xf9\xea\x2f\x50\x09\xd6\x25\x9f\xca\x32\x5f\x37\xaf\xbd\x18\x72\xdb\x64\x85\x6e\x65\x87\xcd\x9b\x5f\x10\x2c\x74\x76\xe6\x09\xaa\x3a\x13\x5d\x5c\x88\xc5\x2c\x8e\xa1\x43\xa6\xfe\x84\xec\xe5\xf5\xd3\x80\xd4\xe4\x96\xb1\x8e\x03\x27\x45\x54\xf5\xc8\xf0\x3e\xb5\xe4\xba\x25\x31\x68\x1f\xc8\x81\xfa\x9c\x37\x73\x91\x04\x96\x24\x14\x93\xa1\xa7\xde\x41\xb2\x8e\x93\x65\xe3\x75\xbd\x28\xb1\xaa\x15\xa6\xfd\x4c\xad\x47\x0d\xe2\x38\x3a\xc9\x19\x0d\x43\x2c\xd1\xc7\xca\x8d\xc5\xe6\x4e\x2f\x2f\x8f\x62\x4c\x8a\x03\x8c\x72\x16\x7b\x31\x61\x93\x97\xe2\xad\x5e\xbc\x88\xac\xa8\x9b\x99\x5c\x2f\xa3\x9a\x44\x2e\x61\xee\xc8\xfc\x1c\x87\xf0\x10\x3a\x37\x79\xe7\x34\x61\xf8\xce\x18\xc1\x44\xa6\x78\x3c\xd9\xbf\x04\x03\xb0\xd4\x24\xae\x2a\xd1\xe6\x4f\x2a\x67\x0a\x84\x5d\xbb\x42\xa2\x59\x9b\xe4\x2b\x2b\x14\x00\xfb\x8b\xe9\xc8\x12\x85\xc0\xf5\xfb\xc5\xf6\xdb\xfa\xf0\xf4\xbc\x5d\x7d\x5f\xec\xd6\x07\x24\xcc\xf2\x43\xc6\x63\x4b\x6d\x8d\x58\xcd\x1c\xee\x6e\x96\x97\x91\xb6\xc7\xf8\x29\xb9\xd0\x84\xf8\x82\xab\x5f\x58\x15\xfa\x04\x55\x6b\xe6\x4c\xc6\x8d\x1b\x8a\x8a\x3e\x7d\x26\x79\x6e\x37\xeb\xb1\xf7\xff\x8f\x79\xe6\xc9\x0b\x8b\x88\x63\x84\xf5\x24\x2e\xbb\xf2\x08\x65\x31\xcf\xc1\x0e\x4c\xc4\x02\xdd\xea\x73\x0d\xd5\x1e\x0a\x81\xf1\xcd\x57\x04\xf8\x4f\xbc\x0f\x26\x8c\x8a\xdc\x79\xb0\xcb\xc5\x3b\xb2\xd7\x8e\xf5\x42\x81\xc9\x28\x96\x3d\xff\xc5\x23\x7c\xec\x40\x9d\xab\xac\xb9\xdc\x8c\xf1\x3d\x73\x10\x09\x26\x15\xc3\xbc\x8c\x45\x59\x23\xac\xfb\xcb\xe0\x29\x53\xc6\x16\x1c\xb4\x9f\xec\x35\xab\xc7\x21\x45\xa6\x8d\x3d\xfc\x4e\x55\xa9\xda\x03\x7e\x54\xcf\x06\x0c\x62\x8a\xb1\x89\x97\xf3\x7c\x85\x1c\xb4\xd6\x94\x71\xa4\x92\xfe\x48\xfa\x84\x02\x0e\x98\x09\x80\xb9\xc1\xe9\xfd\xc7\x27\x51\x89\xe3\x5f\x62\xd3\xfd\x1d\x22\xae\x5d\x80\x1b\xcd\x4d\x9b\xda\x7e\xf0\xa8\x46\x66\xc0\x16\x87\xdf\x79\xfd\xcb\xed\x79\xb7\x7f\xc8\x8a\x97\x5b\x91\xbf\x38\xaa\x14\xe0\x24\x22\xc6\x91\xca\x66\xc7\xf3\xf1\xb1\xec\x89\x5a\x46\x76\x10\x27\xd2\xe2\xdc\x1c\x13\xb1\x63\xd2\x6b\x3f\x78\x30\x76\x50\x39\x51\x0a\x8d\x84\x6f\xe5\x7b\x3b\x06\x83\x15\x7c\x9d\x3f\xf7\x97\x40\x00\x83\x3a\x95\xd5\xb9\xc9\xec\xbc\x8f\x6d\xcc\xd1\xfd\x27\xb8\x2e\xec\xb5\xad\xee\x36\x41\xbb\x6e\xff\xbf\xff\xdf\xff\xf7\xb8\x79\x3c\xec\xb7\x8b\xc7\xdd\xed\x7a\xbb\x58\xde\xaf\x91\x72\xde\xbf\x48\x48\x28\xe2\x0c\xd7\x9b\x87\xee\x4f\x8c\x38\x71\x8c\x76\x71\x7e\x13\x93\x03\x8f\x87\x02\x50\xb1\xf4\x60\xc0\x53\x6d\x0e\x1a\x01\xa8\xe5\xca\xd1\x00\xc7\xdd\x6b\x6b\x30\xdc\x15\x4d\xe9\xa2\x97\xfe\x37\x22\x4e\x6c\xaa\x4e\x1c\xb3\xfc\xb2\x85\xba\x3c\x57\x0a\xdc\xfc\xf8\xbb\x3e\xb0\x37\x22\x78\xa4\x98\xcf\x88\x74\xac\x5f\x76\xba\xce\x25\x8f\x79\x4c\xa4\xf4\xa4\xbe\x87\xf6\x7f\x84\x74\xac\xc7\x0e\x70\xb5\x12\x35\xac\x7f\x9d\x40\x21\x4f\xd3\xb9\x33\x91\x79\x1c\x59\x02\x5c\xb4\x08\x07\x3a\x43\x75\xd7\x41\x24\xc6\x1f\x0a\x50\x39\x8d\xe5\xf1\x08\x25\x09\xef\x14\xf4\xe7\x8b\x7c\x78\x22\x89\xf2\xca\xf3\xa7\xb2\xa8\x4b\x74\xb6\x6a\x27\xaa\xd0\xde\xf3\xb3\xbc\x26\x4f\x64\x88\x4f\xa8\x9d\xe4\xdf\x73\xe5\x83\xd8\x9c\xc6\xd6\x0c\x59\x6d\x9e\x9e\xd6\xdb\xc3\xe2\x61\xf3\xfc\xb8\x3f\xfc\xf1\xb4\xde\x76\x3d\xd2\x18\x15\x15\x7f\xae\x47\x48\x5a\x4e\x41\x22\x09\xbc\x2a\xe1\x09\xaa\x75\xf3\xba\x31\xa6\xee\x32\x5b\x3c\xe5\x52\xb8\x80\xc9\x47\x56\xcc\x06\x03\x39\x8b\x15\xbe\xd2\xff\x96\x96\xaf\x74\x51\x68\xab\x09\x33\x6f\x6a\x70\xa6\xa8\xf4\x32\x98\x48\xaa\x8c\x6c\x47\x56\x1e\xa9\x1b\x6d\x91\x30\x9b\x94\x13\xc5\xb7\xde\x9e\xe1\x22\x0d\x10\xf9\x77\xff\xef\x7b\x17\x2a\xed\x5a\x40\x23\x65\xd0\xf7\xc5\xea\xfb\xdd\x76\xf3\xe3\xd9\x37\xc8\x54\xa0\x19\xea\x80\x1a\x13\x43\x9d\x4b\x43\xb8\xf2\x82\xf1\x4e\x85\x78\x0a\x26\x1c\x3f\xbf\x52\x96\xd4\xd2\x95\x0a\xa1\xe9\x3e\xf5\x09\x5d\x57\x48\x54\x94\x3a\x7a\xa9\xac\xdd\xd8\x17\x2e\xae\x3c\xa0\x23\x01\x0e\x94\xa7\xda\x6b\x0f\xfe\xe5\x0a\x19\x5a\x2a\x1c\x98\x0c\xec\xae\xe6\xd6\x86\x7b\xcb\x91\xd1\xc3\x4d\x98\x62\x5d\x50\x87\x97\x5c\xe4\xf9\xa2\xba\x8e\x92\x4c\x5e\xd4\x70\x0b\x25\xa9\x91\x3b\xd0\x19\x37\xeb\xd5\x76\xbd\xda\xfc\xbe\xde\x5e\x09\x57\x0c\x9d\x61\x67\xb6\x09\x12\x2b\xe9\xf6\x6e\x9b\xa8\x15\x32\xcb\xb3\xe6\x53\x0c\xfc\xe8\xed\x04\xa1\x0a\x99\x34\x97\xf7\x0f\xb3\xe4\x22\xbe\x1b\x0f\xa9\x0b\x40\x2d\x05\x7a\xff\xcd\xf8\x6c\x61\x5d\xa5\x95\x20\x32\x89\xbd\x4e\xbe\xe5\x81\xb8\x2b\x5a\x5b\x49\x5c\x27\x51\x04\xd1\x0c\x29\x85\x6e\x2c\x01\xc2\x15\x6b\x3d\x88\x00\x00\x71\x3b\x37\xe2\xb4\x12\xc3\x3a\x5a\x10\x81\x31\x08\xec\x6b\x4d\x25\xbd\xfe\x25\x8e\xa7\x29\x8e\x5c\x84\x09\x45\xff\xec\x8f\x3f\xff\xf4\x57\x45\x9c\x28\xe7\x12\x6e\x3e\x40\x5f\x09\x9e\xba\x6e\x71\x2c\x85\xec\xb0\xd8\x58\x9e\x63\xe3\x66\xb3\x7e\x95\x48\x02\x8a\xd4\x4d\xff\xdc\xfa\xc0\xb0\x48\xc2\x10\x3d\x3f\x0d\xef\x43\x62\x71\x10\x49\x22\xd1\xeb\x3b\xb4\x9b\x58\xb7\x73\x0e\xd5\x7b\x86\x67\xa0\x48\x28\x20\x25\xe5\xe2\xe6\x77\x7f\x07\x1a\x47\x78\xc8\x94\xa7\x7a\x5c\xa5\x29\x68\x0a\x58\xf2\xb9\xde\xaf\x5e\x45\xe5\xc8\x12\x27\xaf\x46\x39\xe0\x92\xd9\x83\xab\xf4\x99\x7c\x14\xaa\x6d\x65\xef\xb2\x6c\xac\x92\xcd\xf8\x72\x0c\xe2\x75\xc9\x7c\xab\x0e\x32\xe9\x11\x09\x6f\x46\x7b\x02\x24\x87\x18\x1f\xff\x50\x1a\x6b\x44\x4a\xf9\x35\x73\x23\x32\x55\x4e\xef\x95\x46\x68\xec\x6e\xd7\xf7\xeb\xd6\x6e\xde\xed\x17\xfd\x10\xb3\x30\x44\x23\xdf\x95\xa4\xbe\x66\xc5\x4b\x67\x39\x76\xa9\xc4\xff\xf3\x3f\x57\xd9\x45\xf7\x0f\xe6\xd7\x10\x8b\x6c\xed\x67\xfd\x21\x4e\x93\x7c\x95\x60\x11\x65\x81\x57\x23\xaf\x40\xd4\xe7\x8e\xcf\x78\x76\x4d\x0b\xa6\x15\x66\xac\x17\x4f\x4f\x87\x87\xc5\xe3\xe2\xdb\x7a\x7b\xd8\x6e\xbc\x06\x24\x08\x06\x16\xdc\xed\xb4\xc7\xad\x0e\xc3\xbc\x19\x28\x98\x61\xe8\xae\xfb\x32\xe4\x4f\x96\x27\x0f\x24\x1e\x9c\x0e\xf3\x84\x15\xe3\x63\xf5\xfb\xbf\x65\x07\x0a\x9e\x28\x34\xa1\x73\x51\x37\xce\x6a\x2e\xab\x91\xed\x26\x38\x0b\x82\xd4\xbb\x48\x65\xa5\xb3\xe2\x3a\xde\x24\x38\xb3\xa4\xd4\x0f\x47\x5b\xfb\xf5\x45\x42\x4a\x88\x00\xc2\x0e\xd8\x5d\x34\x50\x34\xcb\xcb\x8d\x68\xc4\x27\xf5\x08\x93\x8b\x13\x2b\x87\x69\x8b\xd0\x13\xf2\xf6\x5c\xeb\xbb\x62\xd5\x13\xb7\x83\x10\x54\x78\xe9\x9b\xb1\x53\x21\x04\xd3\xb1\xad\xab\xb3\x46\xc1\x67\x38\xe2\xc9\x20\x09\xee\x0a\xb0\xac\x30\xbd\xff\x2b\x80\x67\xdf\x6d\x3d\xb1\x95\x38\xdd\xd9\x70\xc0\x4f\xc8\x3e\xf9\xb8\x2a\xe6\x18\x60\x6c\x32\x18\x09\x2b\x8d\x7f\x0e\xa4\xa5\x43\xaf\xa1\x71\x4c\x0d\x8b\xc9\x68\x9b\x40\xe3\x56\xf5\xb4\x5d\xed\x03\x42\x0e\x5b\x0f\x8c\x17\x06\x88\x67\x1a\x58\x9d\xeb\xa6\x3c\x5a\x19\xb6\xe2\x65\xe4\x8c\x4b\x12\x1b\xcf\x7a\x67\xc7\xc2\xf1\x78\xcc\xc7\x1b\x25\xa1\x14\x4b\x22\x90\x2a\xca\x9b\xe3\x49\x8f\x6c\xa5\x6e\x75\x4d\x8f\x2d\x7f\x39\xa4\x51\xa7\xaa\xff\xa4\x9a\x5d\x03\xa7\x89\x95\x2c\x83\x94\xa3\x51\x74\x14\xbf\x5c\x66\xac\xb5\x85\x3b\x5a\x60\x90\x21\xb1\xfc\x6c\x76\x13\x7a\x12\x2f\x30\x5f\x12\x2a\x23\x0a\x91\x2f\x37\xc0\x69\xe5\xff\x0e\xc4\xca\xd5\x97\xea\x2f\x93\xa6\x32\x4e\xac\xdf\x6f\x65\x76\x2c\xdc\xad\x27\x11\x00\x19\x03\xc1\xc7\x95\xa2\x51\xaf\x5b\xc8\x3d\xcf\x31\xee\x34\xbd\xc3\xf2\x19\x08\xb8\xdb\x90\x7a\x26\x1b\x36\xda\xb5\xc6\xfb\x17\xf3\xa6\xbb\x4c\x62\x2b\xb0\x57\xff\xe7\x2c\x2a\xd8\x98\xdd\xf9\xda\xe5\xf3\x5d\x45\x2a\x54\xcf\x28\x00\x95\xd7\x88\xb8\xce\x03\xc9\xc4\x58\xfe\xae\xf5\xfe\xee\xf1\xcb\x71\xa1\x71\x80\x35\xa6\xf7\x65\x95\x35\x62\xe9\x53\xb6\x92\xc6\x16\xe2\x8d\x48\xe0\x6b\x8f\xad\xef\x85\x89\x97\x87\xc5\x1f\x87\xd6\xcd\xb2\xe2\x1d\xcf\x4f\x4f\xf7\x7f\x76\x37\x62\xdc\xa4\x8e\x93\xe0\x2a\x4a\x2c\xa9\xa6\xe8\xb9\xa8\x32\xeb\x43\x3c\x03\x06\xcb\x49\x6f\x63\x8b\xa3\x7d\x31\x56\xeb\xe9\x4e\xa6\x5d\x1a\xa4\x58\xee\xe7\xd9\x37\xfa\x30\xa4\x4c\x29\x00\x92\xb5\x1c\x33\x5c\xe0\x76\x1d\x7d\xcb\xde\xe1\x2f\x0a\x36\x64\xea\x42\x9c\x56\xe2\xf8\xae\x40\x26\x23\xf8\x9c\x98\x0b\x24\x8b\x02\x07\xfc\xc0\x5a\xf5\xd9\x98\xbe\x64\x49\xea\x05\x5a\xda\x79\x7d\x08\x13\xff\xa8\x8c\xa9\xc0\xc9\xe0\x55\x2f\x15\x40\xf1\x1d\x44\xde\xbc\x0e\x6d\x27\xc9\xb8\xf0\x49\xaf\xa7\x32\x2b\x9a\x49\x00\x43\xf2\x94\xa2\x3a\xb2\x40\xe9\x84\xf5\x7f\x82\xd4\xcd\xe8\xf4\x1f\xee\xbf\xbe\x23\x0b\x70\xae\x3c\x6e\xf6\x87\xf5\xe3\xcd\xfa\xe6\x70\x7b\xf7\xe8\xcf\x3a\x29\x42\x8e\x0e\xad\x53\x72\x3c\x3c\x6d\xb6\xa8\xcb\xf9\xf0\x7c\xbf\xbf\x7b\xba\xbf\xeb\xbc\x27\x29\x04\x90\xfe\x28\xf7\x65\x51\x9f\x1d\x5b\xe3\xa1\x10\x2a\x08\x5c\x4d\xed\x5c\x44\x70\x7e\x1f\x97\x32\xb4\xf4\x7a\xd6\xc2\x33\x19\x1e\x3f\x28\x48\x32\x9b\x6f\x90\x32\x11\x88\x9e\x19\x57\xa8\x2c\xcf\x57\x21\x77\xd7\x5f\x85\x94\x6a\xbf\xf9\x22\x68\xef\x79\x77\xd3\x1e\x4d\xfb\xf2\x27\x64\xdb\xc1\xf6\x01\x49\x82\xe0\xa9\x49\xcd\xd6\xfc\x6d\x41\x53\x8b\x20\xde\xde\xba\xeb\x55\x14\xd0\xd4\x0c\x9f\xec\x5b\x29\xf2\xfa\xb6\x2a\x8f\x1e\xb9\x01\xe8\xfd\x7e\x1a\x0e\x9a\x2b\x4b\xf0\xf7\x0e\xd3\xd0\xd1\x15\x3c\x65\xaa\x69\xdd\xf9\xa1\x3a\x64\x2f\x79\x3b\x1a\x2c\x15\x33\x89\xe1\x93\x65\xd6\xb4\x86\x68\xeb\x8f\xf8\x16\xce\x51\xc4\xbf\x46\xad\x91\xcd\xed\xad\xa9\xac\x46\x5c\x57\x85\xac\x62\xdd\x89\xb8\x3d\x41\x55\x77\x6e\x9c\x4a\xc2\x40\x30\xcf\xfe\x3a\x40\x69\xcd\x2e\xa6\xc1\xbf\x06\xb4\x61\x7f\x51\xe8\xaf\x12\x11\x11\x5f\x79\x3a\x90\x17\xf1\xad\xc6\xc4\x96\x24\xe4\x39\xd3\xe3\x26\x1a\x69\xd1\xa1\xdc\xee\xea\x4d\x91\x5f\xb0\x84\x64\x6c\x74\x28\x4a\x53\xe7\x89\x5a\x05\xf5\x76\x2f\x29\xfa\xf0\xf8\x64\x18\x59\xcc\x82\x70\x20\x7a\xdb\x4e\x53\x3f\x18\x8c\xc6\xbc\xab\xd5\x2e\x3a\xee\x1a\x50\x8c\x03\xda\x35\x87\xac\xb6\xa8\x8e\xae\xc1\x28\x3c\xa6\x5a\x4f\xe2\x8b\x6d\x5d\x71\x6e\x45\xd9\xff\x57\xa8\xb7\x53\xd9\x0c\x37\x0e\xc5\x45\xe2\xe5\xee\xee\x41\x98\x79\xc0\xaf\x12\x22\x40\x1f\xf0\x60\xb9\xcf\xbe\x67\x2f\xaf\x08\x63\xd7\x7a\x1a\xa4\x56\x52\xc5\x5e\x52\xed\x11\x3e\x96\xdb\x3f\x9e\xc4\xc4\x07\x54\x8a\x50\x4c\x16\x2c\xcf\x97\xc5\x75\x6d\xda\x2c\x59\xe5\xc8\x37\xfd\xc7\xf4\x76\x96\x16\xa9\x72\x7c\x0a\x43\x22\x00\xa5\x02\x92\xba\x7c\xdd\x73\xe1\x40\x6e\x08\x6d\xca\x7e\x41\x3e\x22\x7b\x98\x07\x95\x74\x1f\x5a\x99\xa4\xe3\x5f\x40\x77\x01\xf3\xe1\x36\x02\xd4\xff\x9c\x0e\xed\xe1\xd0\x4e\xb7\x87\x73\x1e\x26\x74\x79\x09\x13\xea\x9b\x21\xb0\xe4\xd9\xf5\x80\x04\xab\x6b\x8b\xb8\xd5\xb8\x69\x44\xd5\x91\x95\x4e\x06\x17\x58\x82\x05\x13\xeb\xfd\x10\x04\x34\xf7\xcd\x41\x1a\x8c\xb0\x3f\x94\xd5\xe9\x15\xce\x23\x94\x9b\x32\x44\x7b\xd1\x5d\x47\xf2\xdd\xb5\xa8\x18\x27\xe8\x47\x59\xbd\xdd\x96\x55\x77\x80\x68\x42\x25\x75\x99\xc4\xdd\x6b\x76\x1a\x55\x47\x8f\x27\x8b\x26\x2c\xb5\xc9\x7c\x91\xc3\x83\xe5\x24\xef\x74\xc4\x41\x13\x2e\x15\x1f\x2c\x98\xdf\x11\x4f\x34\x9b\x74\xd4\x44\xb8\x08\x63\x5e\xd6\xa8\x5f\xa9\x5e\x61\xe1\xf1\xc5\xae\x4f\xc0\xec\x77\x19\xe4\x7c\xef\xf7\xab\xdd\x71\xc0\x55\xe9\x37\x03\x1d\x12\x5b\x47\xde\x38\x43\x7e\x3f\x04\xff\xea\x30\xe2\x08\xe9\xfb\xf7\xea\xf1\xcf\x19\xe4\x98\x8e\x22\x57\x9a\x7f\x96\x87\x93\xf5\xc4\x5d\x66\xfd\x50\x97\xf9\x27\x31\x48\x1d\xc5\x29\x62\x9b\x4f\x50\x99\xb2\x3a\xda\xb3\x1b\x35\x20\x87\xa9\x63\x1d\x71\x8e\x07\x74\x03\xe2\x68\xc3\x0b\x07\x6f\xf6\xeb\xc8\x58\xff\x5b\x95\x1a\x7e\x0d\xc0\x9b\x3a\x21\x96\x75\xd3\x31\xd0\x96\x6f\xf6\x5c\x18\x95\xb9\x8e\xb0\x43\x3a\x31\x21\xfe\x4c\x01\x1f\x7b\x1f\xeb\x15\xc7\x93\xc8\x5e\x8a\xdf\x66\x96\xda\xd5\xd9\xac\x69\x2a\xe2\xb8\x23\x95\x51\x63\x86\x2a\x4d\x79\x80\x31\x92\x3c\x3b\x66\xcd\xb0\x84\x74\x32\x28\xa9\x8a\x5c\xb5\xa7\xa7\x9e\x98\x50\xbf\x5f\xf5\x17\x48\x65\x63\x50\x4b\x71\xfd\xcb\x73\x38\x82\x66\xc4\x82\x16\x6f\xcf\x85\x9e\xb8\xfa\x9a\xb1\x10\x91\x1d\x7a\x02\xe0\x83\xea\xa7\xa8\x57\x65\x55\x41\xdf\x97\x07\x11\x82\xe3\x0b\xf8\xd5\x20\x6a\xcd\x0b\x82\x81\xe6\x12\x90\x27\xa4\x81\xe3\xe9\x6a\xb3\x98\xf5\x52\x34\x37\x1a\x13\x42\x77\xab\xcd\x61\x14\x58\xd4\x32\x0d\xd1\x8a\xb0\xb0\xf0\xb5\x95\xa2\xcf\x0a\x44\x56\x8d\x17\xbb\x96\x26\x8e\xa8\x0f\xbc\x65\x0a\x86\x8a\x0c\xae\x8b\x8a\x0d\x4a\xc4\x3a\xd5\xef\xd6\xbe\x9d\x1f\x70\x95\xda\x14\x83\xd0\x56\x02\x63\x63\x4c\x27\xcd\x97\xf8\x3e\xc6\xea\xe0\xf7\x06\xce\x9f\x20\xaa\x6f\xe2\x88\xab\xb8\x78\xb1\x2c\xe3\x7d\x84\xa9\xfb\xea\x9a\x82\x74\x0f\x7a\xdb\xa3\xa5\xb4\x56\x16\xca\x7e\x38\x78\x46\xc4\x6a\x25\xf2\x5c\x0e\xf9\x0d\xe6\x3f\xb7\x56\x0c\xe3\xc5\x45\xd9\x64\xe6\xb2\x9b\xc9\x74\xfa\x8e\x86\xd2\x04\xd1\xaf\xd6\xd9\xf7\x3f\x0d\x01\x0b\x52\x9f\x21\xc7\x53\xe1\x7a\x78\x21\x12\xb8\x43\xfe\x80\x53\x3e\x62\xf4\x03\x0d\x69\xac\x82\xce\xb9\xda\x5e\x41\xa3\x34\xf0\x58\x7a\xf9\xe6\xac\x80\xe7\x93\xa5\xca\x3b\xa0\xf0\xf2\x27\x73\x18\x64\x80\xe5\x19\x7a\xc4\x21\x0e\x1a\x14\x65\xed\x86\xf8\xd1\x0d\x9c\x11\xe0\x5d\x81\x5d\x6b\x19\x61\xee\x0f\x9a\x3e\xd6\xaf\x8d\x89\xb4\xf4\x94\x83\xd5\x31\x1b\x20\x5c\x6c\x0f\x20\x11\x41\xc2\xbb\x5b\xa1\xda\x2b\xc7\xd1\xa3\xd1\x24\x02\x92\x5a\x7a\xa3\x87\x3f\xd7\x0f\x4f\xeb\xed\xc6\xdb\xf0\x40\x78\xec\xc9\xb3\x77\xb8\x80\xce\x15\x6c\x37\xb7\xdb\x21\xdc\x0b\x88\x73\x87\xda\xa5\xdc\x9a\x70\x58\xdf\x30\x5a\x87\x10\xc4\x04\xd9\x5e\x50\xef\x7e\x38\xd0\x10\xa4\x40\x10\x8c\x2b\xaa\xf7\xac\x18\x6c\x6d\x10\x06\x92\xf5\x54\xe2\x58\xa4\x77\x78\x83\x8b\x1f\x01\x88\x68\x82\x30\x5e\x1b\x75\xeb\x80\x57\x68\x24\xeb\x63\x36\x24\x4a\xee\xae\x30\xc4\x29\xe4\x97\x9f\xa9\x00\x01\x44\x26\x4e\x6d\xb0\xf4\xdc\xd4\x5f\x27\xda\xe7\x82\xf1\xe3\x91\x8d\x4c\x8a\x00\xb1\xa7\xf6\xdd\x3a\x4c\x1f\xc4\xda\x72\xce\x0b\xed\x44\x05\xea\x7d\xe9\xbd\xc2\x89\x97\x02\xb1\xd1\xac\x13\x63\xfa\x99\x35\xaf\xdd\x97\x18\x7d\x85\x24\x89\x94\xea\x38\x08\xae\xd4\xa6\x01\x12\xc1\x30\xad\x30\x22\x70\x1f\xb8\x10\xae\x1b\x4d\x62\x62\x43\xbd\xef\x50\x34\xd0\x7f\x29\x6a\x22\x62\x05\xf4\x84\x46\xb2\x9f\xaa\xcc\xf3\xfa\x8f\xf6\xb8\x1a\x6d\x06\x90\x32\x82\xca\x2f\x88\xcf\x19\x8e\x71\x17\xe6\x00\x16\xd9\x87\x75\xbb\x96\xc5\x0a\x7c\x52\x2f\xe0\x2f\x11\x56\x99\xd0\x3b\x1f\x43\x5b\x07\x78\xa4\x30\x5c\x7a\x2a\xeb\x66\xd2\x92\x1a\x4c\x61\xff\xee\xf9\xe7\x3e\x3a\x35\x45\xd7\x43\x86\x04\xa3\x57\x7e\x8b\x72\x78\x1d\xdf\x1a\x45\x06\x3d\xb1\x76\x22\xb4\xfb\x50\xfb\xbd\xfa\x46\x2b\x14\xfe\xe3\x9f\x2b\x6f\x06\xc2\xf9\xd8\xb5\x26\x04\x25\xe2\x0f\xf2\x5c\xe8\xfc\x53\xee\xff\x6e\x50\x64\xa2\xac\xf9\x8f\x05\x02\x37\xe5\xd8\xcf\x00\x99\x6a\xab\x5b\x82\x4a\x7c\x8b\x29\x15\xee\x64\xd6\x48\x06\x09\xae\xab\xe7\x95\x7f\x1e\x95\xe8\xd4\xa7\x71\xca\x32\x1f\xa2\x39\x41\x51\x83\xa7\x43\x7b\xeb\xf5\xfe\xfb\x64\x4e\x28\xce\x15\xeb\x2c\xfa\x6b\xdd\x79\x00\xa5\xad\x54\x99\x1c\xe1\x0d\xfa\xc8\x8d\xef\x66\x2c\xb4\xca\x65\xf2\xdd\x2e\xd1\x4e\xea\x07\x98\x04\x88\x69\xec\x2a\xbf\x46\x9f\x13\x02\x85\x35\x6a\xf2\x7c\x81\x6a\xfd\x4b\x01\x68\xd0\x5e\xf1\x61\xac\x99\x35\x59\x89\x86\x24\xb8\x05\x1d\xf2\xf2\x03\xaa\x9b\xf2\xe3\x93\xc4\x8f\x21\x86\x20\x34\xdb\x3e\x23\xe2\xdd\x9f\xca\x8f\x4f\xf8\x38\xe6\x23\x11\x26\x10\x14\xcf\xc3\xa3\x78\xf3\x3e\xde\xa4\x03\x30\x36\x0a\xa3\xd8\xf2\xe9\xc3\xfa\x77\x1f\x69\x31\x61\x28\x3c\x1d\xec\x0a\x19\xdc\x56\x38\x2f\xba\xe6\x44\x20\xbd\xc6\xe0\xf0\x5a\xff\x6a\x2a\x31\x3a\x2b\x67\x37\x25\x13\x52\x91\x7a\x59\x9a\x1d\x86\x2f\x86\x1e\x8c\x09\x59\x18\x73\x5f\xb6\xf1\xed\x6c\xe1\xac\x7d\x1b\xc5\x8c\xf1\xe6\xe6\x7e\x0c\x26\xb8\xf6\xbc\x4d\xc8\x43\x0c\xbe\x2d\xf7\x1e\x4c\x61\xa2\x90\x62\xd1\x14\x5a\x18\x12\x86\x73\xd0\xc4\xb1\xdd\x60\xd0\x36\xf7\x14\x5a\x56\x27\x52\xe8\xbf\xe4\xcc\xf0\x37\x49\x43\x4c\xdb\xed\x9a\xb2\x12\x2f\x70\x0d\xb1\xf9\x7a\xc3\x36\x31\x8b\xc0\x9d\xab\x0f\x97\x9f\xe2\xa5\x1f\x96\x98\x13\x7c\x74\x73\xce\xf3\x81\x73\x6e\x62\x65\xcb\x61\x72\xd4\x3c\xf8\x5a\x75\x07\x4c\x12\x81\x6e\x17\xca\x5d\x91\x35\x56\xfb\x68\xf3\xc3\xdf\x29\x11\x10\x06\x3e\x18\x82\xb6\xde\xa7\x14\xcb\x60\x12\x05\xa1\xf7\x33\x03\xac\xb9\x2c\x5e\xb0\x0e\xa9\xbb\x1b\x08\x4c\x15\xa0\xf4\xc1\xe4\x28\x34\x14\x52\x9c\x5c\x96\x06\x6d\x74\x63\x0a\x1a\x4b\x1f\x0e\x5d\x95\xe8\xbc\xe9\x65\xd2\x50\x07\x56\xa5\x4f\xbd\xad\x9b\xd7\x6d\xbb\x1b\xf9\x1f\x4f\x39\x78\x1c\xb2\xa3\xb9\xac\xe1\x79\x7b\x37\xfe\xa5\x54\xd1\x98\x0f\x09\x0d\x7b\x7f\xc2\x39\x45\x86\x05\x36\x70\x61\xaa\xb2\x68\xb6\xe7\xc2\x52\x21\xb4\xb6\x5c\xdd\x88\xa3\x8f\xe5\x1a\x16\x12\x14\x5f\x2b\x2b\xdd\x6e\x0b\xa0\x2c\x51\xd0\x6c\x28\xc3\xb0\x04\x88\x35\xdd\x54\x59\xe8\x9f\x00\x96\xf6\x60\x58\x0b\x6b\x58\x6a\xd1\x8c\x96\xdc\x61\xf7\x96\x15\x8b\xd3\x09\x04\xea\xd8\x8d\x86\x23\x08\xbb\x47\x35\x61\xec\x02\xb0\xeb\xe3\x29\x2f\x2f\x4e\x41\xcd\x35\x73\xc5\xf1\x57\xdb\x0d\xb4\x53\xca\x99\xb7\xc7\x8c\x20\x04\x9c\xab\xfd\xb4\x5d\xef\x6f\xd6\x6e\x79\xf7\xe5\x26\x93\xed\x44\x84\x11\x26\x4f\x7c\x4e\xd5\x52\xd4\xf9\x9f\x16\x51\x37\xaf\xee\x6a\x5b\xb2\x70\xb5\x1a\xfa\x64\x81\x91\x3a\xf1\x25\xb0\x2e\x3f\xe5\x88\x51\xc6\x0f\xa9\xd2\x34\x35\x8e\x44\xb2\x11\x43\x5b\xc4\xe8\x58\xa1\xf3\xf3\xaf\xe7\xc5\x76\xbf\xde\xde\xff\x79\x70\x0f\xe6\x9f\x48\x27\x86\x5b\xed\xa9\x77\xac\x9a\x7d\x17\x39\x32\xb5\xb9\x66\xa0\x1a\xcf\x7a\xfb\xbe\x0f\x65\xd1\xbc\xe6\x9d\x92\xfc\x4c\x45\x80\x69\x6d\x0e\x7c\xc3\xd7\xf2\xc3\x11\x38\xee\xca\xaa\x5b\x0a\xc0\x14\x26\x15\xd7\x4f\xfb\x2f\xcc\x60\x63\x22\xe5\x13\x97\xb6\x08\xb9\x7b\x20\xa3\x05\xc1\x7a\xfb\x42\x97\x55\x0d\xd7\xb2\xf0\x86\x90\x48\x60\x58\x15\x59\xb1\x5b\x1f\x73\x18\x70\x31\x84\x28\x82\x85\xb8\xaf\xa2\x3e\xf8\x92\xf3\x03\x20\x72\xa9\xeb\x21\x8d\xcd\x66\xb4\xcf\x6f\xc1\xed\xbe\xc9\x58\x41\x6a\x4b\x00\x5f\x77\xcc\x56\xbe\x3d\xa0\x09\xb8\x8c\xf6\xe1\x24\x2e\x87\x0f\x1f\x6c\x31\x24\xe0\x51\xd8\xde\xf5\x58\x34\xa7\x7d\xd9\xd5\x1e\x34\xbe\x98\xd7\x90\x00\x02\x3f\xd9\x6c\x25\x18\x16\x81\x35\x53\x77\xc9\x90\x50\x5a\x7d\xe0\x1a\x59\x67\x30\xbf\x3f\x65\xaf\x36\x24\x62\x09\x06\x96\x8a\xf3\x71\x00\x84\xe8\x9e\x34\x62\x22\x11\x7d\xb1\x69\xf6\x5f\x68\x77\x0e\xcf\x4d\xe1\x3b\x71\x81\xab\xd9\x7e\xfe\xfc\xc4\x46\x33\xcf\x90\xc8\x24\x2a\xf2\x74\x79\xcf\x85\xdd\x78\xfd\xc5\x71\x98\x3a\x9a\xc3\x3c\x7f\x2a\xeb\xec\x0a\xa3\x62\x48\xcc\x35\x38\x61\xf7\x65\xfb\xa9\xbb\x6b\x93\xd8\x66\xdd\x51\x45\xb1\x12\xf9\xfd\x94\xbe\xd7\x90\x84\x3a\x09\x8d\xb3\xb4\x7b\x99\xdf\xa3\x47\xbf\x40\x03\x40\x5a\x5e\x3b\x05\x3e\x0f\x64\x0e\xae\x88\x39\x4e\x1f\x25\xf2\x7c\x53\x6c\x5b\x9f\xa6\xff\x44\x2c\xa0\x98\xc5\x7f\x5a\x6f\x7f\x8c\x66\x15\x0b\x59\xaf\x49\xb9\x84\xa6\x1b\x67\x26\x28\x19\x2a\x2c\x85\xd7\xb4\x3d\xc3\x68\xfa\xb4\xd0\x7e\x00\xc8\x32\x84\xe9\xb8\xc3\xc3\x5f\xab\xf5\x1b\xc2\x20\x42\x3a\xe0\x4e\x69\xb1\x97\xd2\x98\x0c\x1e\x8f\xad\xc4\xf6\x0b\x52\x50\x22\x6d\xd1\x30\x36\x62\x88\x88\x6d\xa2\xcb\x8b\xef\x20\x5b\x50\xd7\x48\x6d\x31\x9b\x8d\xf2\x5a\x11\xd2\x2f\x70\x1b\x86\x48\x15\x24\xa1\xf7\x9c\xae\xcc\xef\xe1\x2b\xaa\xd4\xca\x51\xd4\xd0\x58\x37\x2c\x2b\x8b\x7a\x25\xf2\x7c\x0a\xf7\x34\x44\x07\x14\xb9\xaa\xe1\x98\x35\x28\x31\x5a\xd5\xcf\x18\x7c\xd3\xd7\x89\x57\x43\x74\x24\x31\x7e\x89\xbc\x15\xf3\x5f\x5e\xd3\x14\x4c\x8f\x08\xc9\xca\xeb\x50\x85\x21\xa0\x28\x3a\x6f\xff\x16\x03\x1f\xd9\x04\x44\x09\x4d\x70\xd3\xa9\x40\x1c\xc7\x1c\x3f\x26\x20\x46\xc7\x2e\xeb\xb2\x3c\x0f\xab\xb7\x4c\x10\x84\x91\x25\x15\x44\xae\x07\x63\xb2\x3c\x13\xcd\x3c\x67\x85\x09\x02\x48\x4c\x97\x08\xf1\xdb\xf0\x88\x7c\xd8\x75\x0c\xc3\xd8\x51\x2b\xfe\x1a\xc8\xdd\x7d\x05\xbe\x30\x41\x18\x25\x18\x14\xf1\x79\x49\x97\x96\x74\x59\xc9\x74\x14\x56\x33\x41\x14\xa6\x1e\xfb\x61\xeb\xf2\xc6\x37\x8b\x62\x82\xb5\x6f\x15\xba\x79\xbb\x29\xee\xd2\x04\x91\xd1\x21\x1f\x04\x2f\xed\x5b\xcc\xd9\x09\x26\x88\x49\x42\x5d\x99\x99\x85\xf4\x8c\x90\x59\x26\x88\x43\x16\x87\x5e\x0e\x79\x91\x67\xa2\x1e\x9a\x37\x6d\x3b\x27\x4e\x68\x5d\xf6\xd3\x38\x88\x65\x4a\xa5\x0b\x97\x6c\x71\xa3\xf1\x36\xa6\x09\x62\xcd\x84\xdd\x80\x9c\xb0\xbb\x3d\x28\x46\xbb\x7d\x90\x10\xab\x5c\xde\xa0\xcd\x54\xf7\xa5\x2b\x26\x48\x42\x4d\x6c\x51\x1e\x66\x5b\x57\x58\xb2\x79\xae\xa0\xef\xc0\x20\xb5\x78\x64\xa7\x17\xd8\xe3\xcb\xbb\xd4\xb8\x09\x68\x64\x13\x51\x8b\x17\x31\x9c\x6d\x14\xa4\x67\x33\xbd\x3b\x6c\x83\xc9\xd0\x32\x66\xab\x18\x5d\x75\xd3\x5f\x61\x6f\x26\x83\xcd\x8d\xc1\xb9\x7a\x78\x15\xad\xb3\xec\x49\xe4\xdc\xc1\x30\xee\x2b\xe2\x10\xcb\x37\x91\xe9\xa0\x1a\x42\xf1\x4c\x20\x78\x88\x6e\x51\x71\x3e\xb6\x36\x65\xbd\xcb\x0a\x05\x8b\x33\x96\xef\xa1\x54\xc4\xf4\x5e\x86\xf3\x6e\x8f\xd8\x7f\x64\x4d\x03\xd5\xdd\x3c\xd5\xcf\x3c\xfc\xc5\x04\x92\x48\x04\xdb\xc8\x73\x6e\x2d\x49\x24\x76\x9b\xc7\x48\x98\x40\x85\xb6\x08\x11\xd1\xd6\x26\x7b\x87\x05\x4e\xfc\x5b\x91\x7b\x8e\x3e\x13\x28\xc5\xd0\xea\xdd\x2d\xbe\x2d\xba\xc0\xc3\x78\x2f\x0d\x94\xe2\x58\x64\xf4\x5d\xd4\xaf\xfb\xcb\x09\x2c\xb0\xaf\xb7\x9d\x4d\xa0\x13\x93\x76\x89\x3d\xfd\x02\xd5\xa3\x38\x42\xcf\x14\x6c\x02\xcd\x6c\xee\x13\x9a\xd7\xbf\x5e\xae\x9f\x7c\x37\xcd\x89\xec\x9c\xb6\x25\x88\xc1\x64\xd6\x26\x36\xe9\x60\xad\x7d\x5d\xbb\x70\x25\xb1\x3e\xf9\x21\xd0\x56\x7f\xfa\xe3\x78\xb6\x91\xce\x20\x64\x23\x0b\xdc\x04\x26\xa5\x38\x3f\x6d\x90\xa7\x1e\xc5\xdd\x4d\x60\x54\x12\x75\x55\xb6\xbb\x53\x9e\x35\x7d\x0b\xc5\x82\x1e\x4b\x44\xec\xd4\x26\x3c\xa1\xc6\x4a\x54\x7d\x47\x2d\xf1\xf0\x2f\x8d\xc1\x70\xcf\x78\x2e\x85\x41\x08\x08\xa4\x5f\xde\xed\x77\x37\x8e\x8b\xa1\x4b\x37\x8e\x3f\x5f\x18\xa4\x1a\x77\x81\x5c\xd4\x98\x4f\x1f\x6d\x1d\x61\xc8\x6d\x9c\xe4\x11\x5e\x90\xbe\xe6\xe7\xeb\xd9\x98\x0c\xea\x1d\x5c\x93\xd1\xcc\x81\x9c\x4d\x18\xea\xa0\x73\x0f\x75\xf6\x92\x0d\x0f\x86\x30\x36\x21\x6e\x33\xcd\x50\x35\xed\xaf\xbe\xfb\xf8\xf9\x93\x20\xe1\xca\x83\x55\x7c\x41\xce\xb5\x69\x6e\xc2\x84\x5b\x78\x61\x71\x3e\xb6\xb6\x4d\x9d\x79\xc9\x5c\xdf\x0e\xe0\x15\x3c\x7e\x96\x9f\xc2\x1b\x5d\x67\x2a\x12\x8f\xe1\xc5\x58\xdc\x0b\x14\x4d\x38\x19\xd9\x34\x54\xc4\x69\x8b\x97\x15\x16\xc1\x16\x50\x79\x5a\x6f\xff\xab\x69\x92\x22\xce\x74\x99\x35\xf5\x6b\x79\x12\x85\x06\x51\x75\xe3\xc3\x42\xc9\x5c\xf2\x60\xb0\xbb\x86\x2c\xe2\x69\x6f\x97\x5e\x87\xc1\x4c\xc8\x52\xab\xb1\xfd\x94\x35\xeb\x73\x35\x6d\x64\x49\xd8\x55\x24\xd5\xd7\x72\xfd\xe3\x57\x65\xcc\x02\x9d\x5f\xa0\xe9\x93\xed\x93\xb1\xe5\x84\x68\x84\xdb\x66\x47\xb8\x2f\xd5\x5b\x3d\x6d\x0f\x02\xe4\x77\xcf\xb3\xba\x59\x2e\x37\xfe\x3d\x38\x4d\xb1\x20\xe0\x79\x7f\x77\x7f\xb7\xff\x73\x80\x65\x35\x21\x77\xd1\x2f\x2c\x66\x79\x12\x99\xd5\x6a\xab\x6f\xcb\xea\x01\xda\x07\x9e\xf0\x35\xb6\x13\x89\xd8\xc4\x5c\x05\xb0\x04\xa8\x36\xc5\x03\x8c\x27\xb3\xa0\x1a\x03\xac\x7f\x6e\x36\xcb\xc5\xac\xff\xf5\x65\x4c\xc6\x84\x42\x02\x3e\xd3\xef\x65\x07\x21\x62\xb3\xe1\x1f\x13\x4a\x21\x89\xfb\x72\xa8\xd8\xe5\xa4\x81\x7d\x2b\x30\xa4\x0b\x7d\x10\xe7\xec\x67\xf9\x91\xc1\x68\x55\xa8\x50\xc8\xae\xbe\x19\x15\xcf\xca\x1a\x7c\xa9\xd9\x30\xa1\xea\xfb\x47\x02\x93\x34\xed\x12\xc6\xa0\xe7\xe1\x3d\x20\xed\xfe\x7a\x70\x9d\xbb\x1b\xc7\x31\x32\x7e\x3c\x3b\x61\xe9\x2c\x7f\xeb\x76\xc9\x10\x28\x47\x26\xba\xbb\xd5\x06\xc5\x52\xa1\x6b\x60\x3a\xee\xe3\x90\xfb\x4a\x78\xa0\x80\x09\x81\x03\x02\x9d\x9a\x57\xb8\xe9\x51\x00\xbe\x51\x48\x08\xfa\xd8\xba\x68\xca\xaa\x17\x0c\x1f\x0f\x2c\x28\x2b\xee\xab\x5b\xc3\x71\x10\xb7\x9d\xde\x11\x42\x8c\x59\xb5\x26\xc3\x53\xd9\x74\x4f\x61\x28\x8e\xd7\xea\xe1\x9b\x03\x2e\x99\x88\x44\x1a\x4d\xc5\x53\xbb\xe1\xaf\x2d\x3f\x6f\xd7\x16\x47\x89\xee\x09\x9f\xa1\x41\xdf\x0c\x2d\xb0\x7a\x98\x7a\x76\xdb\x79\x14\x06\x84\x42\xa7\x8b\xb0\xb8\xbf\xff\x73\x7e\xa9\x44\xa1\x32\x44\xb9\xcc\xf9\x64\xa1\x47\xa1\x4e\xb8\x65\x73\x18\x80\x42\x4c\x14\x85\x21\x52\x14\x08\xad\xaf\x98\x02\x67\xb7\x9e\x28\x52\x21\x73\xc6\xf4\xe2\x22\x8a\xe6\xa6\x2a\xb3\x66\xad\xca\xa2\x3c\x66\xff\x39\xc3\xc1\x71\x58\xb3\xee\x17\xb4\x49\x53\xaf\xc9\xb0\xc8\xf3\xdf\xcb\x29\x41\xa9\x89\x62\x07\xbc\x47\x8f\xa9\x1f\xa8\x98\x29\x0c\xce\xdd\x15\xad\x65\xe0\x4a\x2e\xbe\xe6\x50\xf9\xc7\x6c\xab\xbf\x9f\x50\x14\x3c\xc2\x7b\xc4\x23\xe7\x3a\x24\xc4\x52\xb8\xa9\x41\xd1\xd7\xe6\xd4\xad\x8c\x28\xa1\x86\xdb\x10\x67\xd3\x94\x6e\x37\x1a\x92\xe5\x9a\x28\x11\x69\xd2\x29\x7c\x8d\x0d\x3f\xd7\x83\x92\x08\x0f\x8c\xd7\x32\x9f\xa4\xe9\x4d\x44\x53\x82\xe1\x9b\x8e\xf6\x71\x81\x32\xbf\x7e\x8b\xec\xba\x31\x4b\x61\xfe\x62\x23\x80\xcf\x45\x93\xe5\x9e\x74\xcd\xf3\x45\x8c\x92\x26\xed\x25\xb1\x34\x03\x64\x50\x23\xf2\xb1\x68\x9f\x89\xa8\xb6\xf9\x9f\x83\x85\x16\xec\x4e\xd3\x5d\x3d\xa2\x86\x99\xa0\x2f\xe2\x6b\x4f\xcd\x2f\xcb\xb9\x3f\x31\x14\xa3\x54\x10\xe3\x9f\xbf\x9c\x4c\x05\x16\x0a\x62\x11\xba\xdf\xd7\x8b\xfb\xc3\xf3\xe3\xdd\xde\x3f\x20\x13\x0c\x43\xda\xcb\xed\xe6\xf1\xdf\xeb\xeb\x42\x35\x13\x31\x07\xf5\xf1\xa0\xb2\x39\x63\xab\x43\x26\x7f\x0a\x95\x33\x11\xd3\x0c\xd3\x72\xbb\xd1\x06\x1e\xb5\x6b\x97\xdb\xa4\xcb\x1f\xfd\x19\x34\x59\x1f\x3c\xa1\x22\xee\x20\xae\x2e\xc9\xf8\x20\xea\x29\x57\x50\xdb\x13\x64\x27\x8a\xee\xca\xb2\xb3\x7a\x10\xae\x1d\x10\xc8\x05\xfe\x1a\x16\x30\x62\x61\x7a\xc5\x5b\x51\x7e\x4c\x3f\x11\x67\xb1\x74\xc4\xc9\xdb\x72\x90\x6b\x1b\x50\xa3\xba\x9e\x92\x4a\xac\xad\x55\x50\x34\xf5\xd3\x28\xed\x6f\x22\xc9\x54\x24\x06\x61\xeb\x6b\x39\x8b\xc9\x5b\x4b\x61\xe5\x71\x2a\x10\xba\xb3\x16\x27\x5d\x40\x23\x08\xe2\x94\xa9\xb7\xe7\xa2\xdd\x2b\x9e\xc4\xe0\xa8\xee\x06\x5f\x43\x88\x45\x3a\x65\xb1\x03\x31\x10\x5a\x99\x3f\xe9\x22\x48\x28\x86\x7e\x4c\x56\xe8\xcd\xb9\xf1\xeb\x60\x79\xb1\x55\x0c\x2b\xd1\xc0\x4b\x59\x7d\xad\x09\x68\x22\x60\xa9\x67\xd5\xf9\x26\xf0\x94\x57\x55\x0f\xaa\x37\x91\x49\x08\xa6\x70\xd0\x68\xbe\x5b\x6d\x26\x91\x77\x13\x93\xc0\xba\x33\xc3\xd2\x81\xeb\x19\xf6\x17\x16\x7f\xff\x79\x62\xe2\xf4\x86\xe6\xb8\xf4\xce\x03\xb6\x5b\xd7\x3d\x80\x18\x7d\x70\x59\x81\x78\xdb\x67\x93\x80\x44\x1c\x12\x86\x68\xe5\x9b\xf5\xed\xe2\xf9\x7e\x7f\xd8\xad\x1f\x6f\x0e\xdf\x16\x3b\xff\xf4\x21\x8d\x23\xf7\xfa\x7b\x51\xbc\xf5\x25\xfa\x7e\xcd\xc6\xa1\x60\xa8\x7b\xb0\xcf\x1a\x31\x9c\x2a\x71\x14\x50\xea\x62\x59\x88\x19\x1f\x86\x57\xe2\x98\x70\xf4\x42\xf1\x8a\xed\xcd\xea\x4b\x96\x02\x13\xc7\x5c\x90\x64\x24\x1f\xed\x1a\x12\x1a\x78\x3e\xf0\xd5\x30\x01\x3d\xcd\xf7\x9a\x98\x06\x11\x9a\x82\x39\x98\x26\x20\x93\x61\xa0\xb1\x3d\xa9\x7d\x34\xf0\xa9\x82\x1d\xd6\x27\x5a\x14\xda\x57\x7b\xd9\xf5\x47\x1b\xc4\xcd\x62\x2a\x13\x4c\x63\xfa\xd0\xdf\x01\x8f\x60\x33\x23\x32\xe6\x2e\x48\x09\x43\x50\x8a\x93\x91\xb0\x41\xbc\x5b\xdc\x78\xfd\x3b\xa7\xa9\x42\x5d\x37\xbb\x99\xa1\x70\x7d\x17\x58\x1b\xfc\x74\xca\x22\xdc\x94\x0f\x2f\x56\xaa\x1e\xb6\x20\xf2\xe3\xa7\x48\x21\x13\xa7\x5a\x07\xdc\xb9\xe9\x77\xc3\x42\x97\xd9\x32\x0e\x77\x11\x8b\x23\x6e\x6b\x45\x8b\xb3\xc8\x0f\x1f\x23\xda\x11\x13\x33\x15\xa0\x8d\x66\x9f\xf5\x21\x2b\x1c\x49\xf7\x4c\x70\x2c\xe6\x22\xa4\x96\x8d\x03\x8b\x0f\x0f\xd0\xd9\xa5\x31\x57\x0a\x41\x0a\x15\x82\xd3\x9e\xeb\x01\xdc\x68\xde\xfd\x8a\xb9\x16\xb1\x1c\x61\x1e\xf5\x68\x76\x8a\xd0\x32\xfa\x3a\xe0\xcc\x4c\xdd\xb7\x89\x65\x2c\xb1\x54\xf3\x68\x8b\x54\x6b\x3b\x25\xc6\x07\x68\xac\x94\xb2\xe0\x1e\xe4\xa6\x6a\x7f\xc2\x1a\x32\x7e\xc8\x82\xc4\x0f\x95\x82\x34\x76\xa9\xf9\x1b\x1b\xd6\xd2\xae\x5a\x71\x1c\xa4\x75\xdd\x35\x4b\x51\x7f\xe6\xb0\x12\x79\x6e\x53\x76\x70\x45\x12\xd5\xf7\x8d\xc5\x20\x2e\xef\x8c\x84\x91\xa5\x17\x6b\x45\x30\x07\x66\xbf\x45\x47\x3a\x7e\x8d\xd7\xeb\x37\x1b\x88\xa3\x30\xe8\xc9\x78\x37\x66\xf2\xc9\x20\xb1\xfe\x93\xaf\x1e\xb1\x62\xba\x2e\xc5\xfb\x49\xd4\x39\x06\x1d\x21\x1d\x66\xdd\xc0\x29\xf4\x0f\x67\x22\x85\xae\xe3\xcd\xb9\x78\x81\xb2\x58\xbd\xb6\x1f\x64\x48\x18\xf7\xb7\xa9\x39\x3a\x44\xe7\xa7\xa1\x92\xd8\x48\x8e\x8f\xdd\x55\x0f\x0c\xe5\x0d\x96\x17\x34\xf4\x5f\x45\x7d\x45\xe5\xef\x2f\xd7\x80\x7b\xaa\xaa\xca\xba\x3d\x12\xde\x46\x5b\x9b\x31\x4a\x06\x4e\x9e\x37\x7b\x87\x4e\xdd\x7d\xfa\xfc\x33\x6b\x36\x21\x46\x7a\x6a\xdb\x7d\x25\x4e\x57\x9a\x92\x6d\x0f\x8d\xf8\x8e\x0f\x9c\xb0\x1d\xa8\x6b\xd7\x05\xf8\x92\x20\x54\xfe\xc4\x1a\x92\x01\xcc\xa6\xf4\x4c\x12\xb0\x18\x33\x91\x8f\xf0\xf1\xa3\x1c\x88\x17\xfc\xcd\x51\x77\x77\x09\x75\x8c\xbc\x26\x56\x59\x6a\xd7\x54\xd9\xe9\xd4\x61\xf1\xda\x66\x41\xad\x1e\x87\x7a\x2d\x32\x25\xf2\x51\x48\x32\x89\x12\x9b\xf9\xed\x15\xc4\xb6\xeb\x9f\x8b\xed\xcd\x28\x4b\x6b\x92\x38\x48\x23\x1b\x92\x47\xb1\xff\x60\xe7\x91\x44\x26\x49\x04\x4b\xbc\xfa\x55\xd5\x64\x75\xd3\xeb\xcf\x99\x84\x3a\x81\x61\xac\xf5\xfb\xcf\x39\xab\xe0\x78\x15\xf7\x4e\x28\x4d\x30\x32\x5f\x34\xaf\x08\x6a\x40\x92\xa8\x47\x7f\x8b\x34\xb0\x84\x79\x77\xab\xcd\xd3\xf6\x6e\xe5\x83\x01\x09\x23\x1c\x2d\x4f\x40\x6c\xa3\x33\xc7\x3b\xda\x0a\x93\xb0\x80\x13\xe7\x58\xf4\xea\x93\x7c\x64\x3c\x26\x2c\x10\x96\x6a\x3b\x7b\x07\x2f\x37\x71\x9d\x1a\x4a\x78\xcc\xd1\x36\xce\x6a\xef\x1c\x0c\x2b\x1d\x4c\x22\x12\x81\x45\x26\x96\x6e\xce\x33\xcc\xe2\xe4\x62\xbe\x8b\x8c\x30\x38\xe4\x4f\x39\x3d\x57\x73\x3a\x9c\x8e\x42\x72\x3f\x95\x1e\xe1\x57\xeb\xd1\x9d\x7a\x5a\x3e\x93\x48\x22\x03\xe5\xa2\x2b\xf6\xa0\xf4\x0d\x02\x90\x36\x41\x14\xea\xb5\xac\xe6\xb3\x07\x89\x54\x09\xc6\x90\x46\x1a\x44\xfe\x0e\x2a\x04\xe3\x6a\x4b\xbd\x93\x33\x5c\x0c\x7f\x6b\x13\xf0\xb7\x4a\x34\x86\xdd\x11\x92\x87\x79\x59\x55\xea\xac\x78\xf1\xa4\x97\xa3\x8f\xa1\x3a\x20\x73\xed\x70\xff\xa3\xa7\x32\xa9\xe4\x7d\xf6\x00\x19\x01\x87\x03\xa2\xc3\x08\x6b\x17\xf6\x9b\x1f\xeb\xc7\xdd\xe1\x76\xf3\xfc\x78\xb3\xd8\xdf\x6d\xba\x79\x04\x44\x22\x3b\x26\x12\x34\x96\x85\x5e\x5e\x1c\x33\xc6\xd0\xa4\x4a\x20\xb1\x87\xa6\xce\x8c\x99\x3f\xab\x13\xa0\x01\x7a\xed\xc8\xc2\x56\xbf\x22\x3c\x69\x59\xfe\xfa\x6d\x52\xa1\x34\xb9\x88\x2b\xe4\x7e\xb3\x34\x61\xfb\x81\x96\xcd\x60\xb8\x4c\x48\x50\x48\xe0\xfe\x61\xe1\x9f\xda\xd0\xc4\x16\xf0\x88\x06\x64\xa9\xba\x3f\x8b\x58\xf4\x20\x04\x97\x8a\x98\xad\x24\x33\x94\xb4\x1b\xe3\x00\x43\xb8\x6d\xad\x81\x47\x57\xf4\x68\x28\x51\x06\x63\xa0\xfe\x1c\xc1\xb4\xa6\xaf\xcf\xfb\xd2\xcc\xa7\x01\xb1\xd9\xc1\x07\xd1\x34\xaf\xf0\xf1\xb3\x2c\xfe\x0e\xad\xb2\xa1\x41\x18\x90\xb0\x47\xda\x89\xaa\xca\x3a\x6f\x9d\x06\xa9\xc1\x42\x93\x4c\x95\xd6\xf6\x9a\x9a\xf5\x34\xd0\x22\x4a\xbc\x40\x86\x6c\x46\x61\x34\x1a\x92\x18\xa7\x36\xea\x2f\xe1\x62\xee\x4b\x67\xdb\x56\x5b\x0f\xe5\x04\x3c\xa1\xda\x0d\xf7\x67\xdf\x29\x70\x89\xae\x32\xcf\x6f\xd0\x5d\xf5\x0d\xb1\x85\x32\x9c\x44\x55\xc3\xb2\x2c\xf3\xb1\x3d\x42\xc3\x54\xe0\x22\xc7\x43\xcc\x63\x47\xae\x50\xba\xbe\x33\x27\x89\xf1\x95\xfe\xd6\x08\xf9\x3b\xc1\x6d\x1a\x4a\x12\xf6\x6c\xb6\xcf\x3b\xf8\xcf\x4b\xd5\xed\xe7\x34\x0a\x23\x04\x62\xea\x72\x98\xe8\x99\xdb\x61\x68\x14\x5a\x84\xf9\x03\x40\x73\x3e\xcd\xaa\xab\x5c\x3b\x35\x34\x8a\x99\xb4\x36\x57\x79\x72\x84\xf1\xdd\x6f\x27\x11\xae\x1d\x8b\x04\xb1\x69\xad\x7a\x78\x3e\xd3\x38\x8a\xfc\xf0\x7f\x17\xf5\x2b\x68\x74\xe7\xae\x36\x90\x2f\x04\xf7\x0c\x4d\x42\x50\xa9\x83\x80\x59\x35\x37\x87\x65\x1a\x0f\x53\x7b\x64\x25\x48\xfc\xad\x91\x56\x60\x64\x8f\x51\x1a\x84\x58\xe6\x33\x30\x51\x7b\x3e\x7b\x8f\x65\xf2\x9d\x53\x2e\x11\xfe\x80\x2b\x5d\x18\x93\xc3\xdd\x6a\xd3\x35\x4a\x8d\xd9\x90\xdd\xf2\xce\xb2\x66\x7e\xa6\xa3\xe5\xfb\x1b\x8e\x74\x1c\x77\xf7\xf7\x77\xff\x7a\xbe\xbb\x39\xd8\x0d\xcb\xdf\x8e\x05\x01\xce\xbd\x7e\x56\xdc\x7e\x22\x35\x66\x28\x93\x91\xe7\x71\x7b\xb8\x74\xee\x59\x77\xf4\x53\xa6\x44\x4a\x3c\x6d\xa9\x13\x86\xbd\x0a\x28\xf6\xdb\x0f\xe5\x34\xc2\x50\x6a\xeb\x2e\x63\x51\xe8\xf6\x9c\x83\x0f\x14\x53\xce\x0d\xf5\x5c\x8e\x77\x05\xee\xe8\x3f\xe0\x32\x5f\x37\x6a\x28\x37\xc2\x3a\x87\xad\x69\x7e\x5f\xaa\xb7\xac\x78\x19\x2a\xd8\x18\x2a\x22\x8d\x60\xc6\x83\x67\x9b\xf8\x77\x59\xc0\xbd\x28\xf4\x6f\x36\xc4\x72\x25\xd0\xee\xaf\x4b\x43\x66\xb3\xc4\xc8\x1d\x70\xce\x9b\xec\x94\x43\xbb\xab\x4f\x41\xf5\x86\x0a\xc5\x70\xb0\x5d\x8c\x19\xeb\x89\xfe\x2e\x68\xde\xdd\x42\xb2\x14\x41\x41\x9b\x9f\x8f\xeb\xed\xe1\x69\xb3\xb9\x3f\xac\x36\x0f\x0f\x77\xbb\x5d\x7f\xb6\x50\x25\x0c\xf5\x05\x43\x58\xe0\xec\x0e\x95\x7f\x9c\xbb\x77\xb9\xbe\xb3\x89\xc2\x34\xe9\x6a\x1b\x6b\x87\x2d\x9c\x8c\xa3\xa1\x41\xe0\x3a\xf9\xa2\xbb\x01\x16\xd0\x50\xc3\x19\x73\xe0\x90\xe7\xbc\xc9\x8e\xa2\x81\xcd\xb9\x51\xe5\x71\x08\xc0\x37\xd4\x88\x18\x4f\x96\xbb\xd5\xe6\xa0\x1d\xe3\xb6\x6f\x92\x02\xef\x70\xbb\x5e\xec\x9f\xb7\xeb\x8e\x7e\x6c\x77\xd8\x3c\x1e\x96\xeb\xef\x8b\x7b\x1f\x40\x4f\x09\xb1\x5a\x9b\x99\x3e\x98\xb2\x4f\x5b\xcd\x4e\xf4\x94\x04\x20\x1c\x89\xcf\xcb\xb9\x5f\x7a\x29\x71\x0c\xe7\x96\x76\xeb\xf1\x7c\xdc\x9c\xa0\xb8\x01\x91\x4f\xb6\xe1\x94\x24\x0c\x37\x48\xf9\xb9\x42\xe0\x78\xb0\x52\x22\x6d\x01\x9d\xe3\xc1\xf3\xe9\x11\xdf\xaa\x94\x4f\xf9\xee\x2b\x81\x1b\x57\x3f\xf9\xd3\x20\xb6\x08\x5a\xe7\x3a\xd8\xd3\xe1\x51\x1c\xad\x9c\xf2\x64\x6b\xf2\xd7\xa4\xc0\x88\xdf\xf0\xd0\x64\x41\x42\x32\x7f\x50\xa5\x81\xb4\x75\x30\x28\xd2\xb9\x2f\x9f\x77\x37\xbd\x36\x90\x49\x03\x13\x29\x17\xa4\x59\x6a\x5b\xb2\xe8\x80\xc1\xbd\x03\x4b\xdd\x4c\x4e\x43\x66\x05\xfe\xda\xb5\xf9\x08\x1f\xdf\x3a\x8c\xaf\x49\x43\xce\x1d\xae\xc4\x3e\xb9\xe3\xf4\xf2\xad\x40\xb0\x06\x69\xd7\x08\x99\x35\xc3\xc8\x95\xef\x60\x54\x9a\xfa\x19\xa6\xbd\xba\xf4\xf5\xe0\x46\x81\x95\xae\x84\x5f\xd6\x02\xf6\x0c\x08\x16\x8d\xe8\x0e\xe1\xf1\x17\x8c\x54\x22\xc6\xc5\x8f\x8e\x98\xc7\xb5\xc7\x71\x02\xae\xde\xd4\xda\x73\xaf\x59\xa5\x97\xf0\xd2\xa1\x3a\xd2\x38\x09\xf0\x0e\xdf\xda\x1e\x65\x05\x3d\x68\xd5\xa4\x09\x09\x53\x47\xd0\xdd\x85\xe1\xd3\x24\xa2\xa1\x25\x4e\x80\xea\x05\x0a\xd5\x21\x33\x6d\x46\xb4\xeb\x95\x3a\x55\x50\x65\x3d\x92\x51\x36\x3e\x4d\x62\x61\x13\x30\xc6\xa0\x58\xdf\xf0\x0c\x4b\x93\x44\xa5\x2e\xb9\x6c\xcd\x58\x2b\x2a\xeb\x3f\x59\xd4\xc7\x69\x06\xff\x0c\x07\xca\x18\x26\xa5\x84\x23\x47\x34\xca\x09\xef\x9a\xf2\xb4\xba\x74\x86\x6e\x4a\x29\x47\xa0\xc0\x51\x54\x83\x81\xa0\x22\xc0\xc9\x8b\x29\xf9\x5c\x64\x47\x70\xdc\xdf\xe3\x11\xa7\xda\x20\xfa\x50\xe4\x36\x0e\xd1\x1f\x54\x69\x4a\x2c\x1c\xab\xc6\x57\x1d\xcc\xd2\x34\x8a\xb8\x19\x56\x3b\x7e\xba\x33\x0e\x0d\x81\x34\x4d\x58\xc4\x3b\xf1\xa4\xee\x9b\xa6\xd4\x60\xe8\x4b\xf8\xf9\x31\xa2\x7a\x30\x69\xca\x2c\x4c\xa1\xee\x91\xc8\x23\x37\x20\x65\xd2\x5a\x11\x58\x48\x62\x63\x1f\x9f\xb3\x57\x98\x94\x93\x84\xa4\x2e\xbf\xb6\x9e\xea\xdb\x99\x54\xc4\x96\x29\x4d\x41\x51\x9f\x2b\x5f\x0f\xfa\x8f\xa1\xcd\x9f\x0a\x66\x0b\x9e\x5a\x0f\xb6\x9d\x25\x83\x18\x73\x2a\x53\x69\xd9\x67\xea\x3d\x88\xe3\x3d\xda\x75\xf6\x1c\xdb\xbc\x43\x75\x67\xda\xbf\xce\x9a\xdd\xa9\x14\x44\x04\x83\x4a\x62\xd9\x25\x27\x53\x1d\x45\x58\x90\x22\xb4\x5e\x89\xfa\x15\x4b\x0e\x27\x00\xcc\x4f\xa3\xd5\xdd\x8b\xeb\x58\x0b\x67\x4b\x21\xb4\xde\x12\x6b\x74\x3f\x91\x72\x2d\x5c\xc1\x28\x4e\x94\x07\xf1\xeb\xa6\x2c\x7a\xb4\x6b\xaa\xa5\x55\x3f\x3f\x0c\x38\xc7\xe6\x49\x9d\xfd\x05\xca\xa0\x69\xf2\x0a\xa2\xfb\xda\x06\x42\xa4\x0b\xc2\x6c\x2e\x6e\x73\x78\x4a\xf9\xaf\xcd\x48\x48\xb9\x4f\xab\x62\xe8\xdf\xfd\xc2\xac\x41\xc3\x48\x6a\x30\x6c\x0d\xc5\x7f\xce\x70\x9e\x80\x8a\x18\x69\xbf\xc5\x60\x40\x1d\x88\xc5\x21\x36\xc6\x49\x15\x7f\x89\x8e\x70\x8e\x56\xc8\xf2\xdc\x2e\x9b\xbb\xd5\x66\x68\xb5\xb8\x7e\x01\x28\xa3\xba\x72\x3d\x4b\x32\x36\x9b\x26\x63\x81\x71\x89\x6f\xb4\x10\xef\x54\x79\x93\xd5\xca\x95\xda\xb7\xdb\xae\x78\x71\xd9\x2d\x76\x6d\xba\xb0\x90\x29\xde\x69\x8e\xd8\x91\x58\x34\xdd\x1b\x8c\x1f\x29\x94\x4c\x39\x88\xc5\xc0\x78\xeb\xf7\x21\x16\x45\x36\x6e\x5e\x43\x73\x0b\x50\x3f\x88\x5f\xcf\xa7\xa6\xbc\xde\xe0\x59\x94\x30\xdc\x27\x51\x52\x53\xe4\x3f\xcb\x2a\xef\xc8\x19\xcf\x1d\x0d\x90\x25\xad\xf0\x97\xa4\x81\x07\xd0\x78\x12\xb2\x4f\x3c\xc2\xee\x02\x2b\x3d\x71\x5b\x65\x4a\xa8\x1e\x96\xc7\x22\x16\xa7\xcc\xe7\x5e\xeb\x46\x14\x4d\x66\x4f\xc9\x2b\x75\x4d\xc3\xe2\xf6\x90\xc3\x8c\x7f\x03\xbe\xe0\xda\x37\xa5\xc4\x43\x03\xcb\x77\x78\xbc\x9d\xa5\x1b\xf3\x7d\x85\xc0\x8c\x60\xf9\x31\x20\x57\x71\x6d\x09\x09\xd0\x50\x33\x79\x76\xaa\x7f\x96\xdd\x63\x26\x49\x8c\x71\xd1\x02\x3e\xf0\x1c\x2f\xbb\x5f\x4e\x0c\x0f\x6d\x35\xe0\x53\x79\xb3\x1e\x60\xe2\x19\x25\x2a\x31\x9d\x17\xfb\x85\xec\x81\x61\xd4\x24\x20\xba\x02\xf1\x41\x58\x83\xa5\xa1\x94\x41\x1f\x58\xab\x17\x85\xee\x2b\x30\x26\x51\x64\x96\xf2\x08\x9f\xc5\x64\xbf\x0e\x62\x54\x4f\xe6\x3b\x28\x16\x0f\xa3\x4c\x9b\x73\xd3\xe9\x7a\x18\x96\x42\x84\xae\xb1\xf5\x1c\x77\xf5\xe9\x13\xe2\xad\xf1\x1a\x62\x41\x80\xe5\x05\x5e\x48\xae\x3d\xed\x7f\x0e\x23\xa0\x73\x5c\x22\x86\xb1\x94\x30\x07\x88\xae\x32\x98\x88\x9c\x19\xc6\x04\x21\x23\x7a\x1b\x6b\x19\xec\x9a\xea\x8c\xb4\x2f\xdd\x3b\x33\x01\x78\x6c\x9d\xca\x13\xf6\x43\x05\xea\x06\x8e\x2e\x5c\x77\x99\xa6\x2a\x19\x93\x29\x1f\x06\x17\x66\xe9\x03\x86\x67\xf3\xd7\x89\xc0\xfe\x91\x79\xcc\xa1\x63\xc7\x68\x0d\x3e\x51\xe9\xd5\xcc\x47\x10\x89\x55\x99\xac\xe0\xbe\x14\xfa\xd3\xa4\x34\x93\xa1\xea\x0b\x27\xd6\xcd\xeb\x3f\x2d\xff\xc9\x16\x54\x3b\x5e\xdd\x34\x93\x52\xa2\x7d\xbe\x91\xff\x8b\xc6\x08\x6a\xf1\x4d\x08\x29\xa6\x77\x56\x02\x9f\xd4\x25\xb2\x3e\x99\x94\x52\xd3\x78\x44\xce\xff\x08\xcd\x47\x59\xbd\xf5\xa4\xd4\xfd\x9e\xf6\x77\x83\x7f\xdd\xad\x01\xd3\xc5\x0f\x99\xaa\xca\x9b\x85\xb7\x41\x98\x4a\x55\x62\x89\x5a\x30\xe8\xff\x00\x9d\x15\xcb\x74\x14\x62\xdc\xf2\x08\xf9\x55\xd8\xc2\x77\x89\xb9\x50\xde\x5c\x2c\x7b\x6a\xa0\x49\x2f\x99\x62\xda\x54\x9e\x2f\x37\x59\x85\x7c\xa0\x96\x68\xf8\x94\x0b\x35\x9d\x86\x90\xc6\x98\x77\xab\x5b\x77\x57\x7b\xf3\xdb\x37\x32\xc3\x75\xe7\x69\xae\xf7\xdf\xf7\xa5\xe7\xb5\xfb\x3a\x30\xc6\x40\x48\x5c\xef\xff\x7e\x5c\x4c\x7f\x50\xc6\x69\xec\xea\x15\xae\x30\x73\xad\xbb\x89\x45\x01\xa6\x02\xf8\xef\xfe\xc3\x9b\xba\x9c\xa4\x01\x52\x14\x55\xa7\xf2\x63\x7e\x36\x71\xc2\x52\xac\xea\x78\x15\xf5\xeb\xb2\x9d\x1d\x43\xff\x8f\x13\xa6\xa4\xa3\xfd\x5d\x89\x53\xe3\x89\x12\xbe\x14\x22\x35\x9c\x98\x50\x4a\x1f\x83\xfe\xd8\x0a\x29\xb3\xc9\x9e\xcd\x83\x88\x63\xd5\xc4\x53\xf9\x06\xaa\xbc\x26\x2c\x9d\xdc\x31\x8c\x13\xea\xa0\xfd\xeb\xa2\xe9\x4b\xa5\xe7\xe7\x11\x0f\xb9\x1a\xc0\xcc\x9c\x35\xe8\xc9\xee\x46\xdb\x14\x0f\x75\x84\x8c\x5e\xef\x19\x7c\xdc\x02\x96\xa0\x3f\x39\x14\xd7\x2d\xf8\x4f\xca\xa3\x34\xc1\xe1\xc7\x64\xfa\x77\xc8\x4f\xdd\x11\xc3\x23\x69\x7c\x49\xab\x53\xd6\xb2\x74\x1c\x59\xf1\x72\x0b\x28\x57\x59\x77\xa7\x02\x8f\x89\x75\xf8\x9b\xcb\x09\x3c\x15\x87\xe1\xb1\xb1\x04\xdd\xa7\x6c\x2e\xb0\xce\x13\x1e\x61\x26\xd5\x16\x51\xd9\x7a\xc8\xf9\xf7\xa6\x22\x00\xe7\x3b\x23\xcd\xe8\xa7\xd4\xbc\x23\xe3\x84\xa7\x89\xa0\xb1\xd7\x94\x46\x9a\xc1\x2f\xa7\x29\x4f\x85\x46\x6e\x07\x8b\x2f\xbf\x8a\x36\x8d\x3f\x5d\xaa\x8c\x67\x77\xb4\x34\x59\xa3\xd0\x1e\x4f\x35\x41\x0b\xe0\x4e\x66\xff\x15\xf8\xe3\xc3\x9c\x2f\x4f\x21\x12\xc4\x11\x27\x43\xdd\x3c\x89\x4b\x79\x9e\x6c\x9c\x9c\xc5\x36\xd6\xb1\x78\x5e\x2f\x47\x17\xb3\xd4\xb2\xa8\x18\x4b\x46\xf2\x60\x19\xdf\xf7\xa2\x42\xab\xe2\xb9\xee\x3e\x00\x53\xc0\xcc\xe0\xfc\xbb\x05\x78\x3c\x1f\x1d\xa1\x9d\xef\x03\x04\x83\xb8\x0f\xe3\xdf\xe0\x3a\xc2\xea\x1e\x09\xcd\x7d\xf9\xd1\xfd\x15\x84\x13\x8e\x68\x3c\x34\xeb\x66\x39\x59\x02\xdc\x58\x42\xcc\x9d\x30\x70\x83\x5a\x87\x9f\x7c\x55\x11\x87\x18\x3a\x3d\xbd\x66\xb9\xd0\x90\x9f\x5e\x33\x31\xa8\x8b\xe2\x22\xb1\xe1\xf4\x63\x56\xec\xb2\x97\xa2\x9f\x57\x82\x6a\x74\x25\x50\x7f\xd1\x19\xd8\xd7\x65\xb7\x86\x0b\x29\xc0\x6b\x91\xd4\xbd\x6c\x6d\x7f\x1f\x09\xb8\xbd\x38\xf4\xe5\x0e\xf2\x7c\x0c\xaf\x1e\xbf\x98\xd0\x56\xa9\xdd\xae\xbe\x69\xfa\x7b\xf2\x72\x32\xb5\xf8\x72\x6f\x26\xa0\x0e\xe6\x90\xcc\xd5\x70\x29\xad\x70\x38\x12\x87\x58\xb1\x04\xfc\x04\x43\xfe\x55\xdf\xd5\x70\x84\x63\x1e\x4e\xe2\xb2\x2a\x8f\x13\xf6\x48\xd7\x49\x07\x0a\xd5\x94\xfe\x3b\xf5\xbd\xb8\x8e\x38\x71\x91\x68\xb8\xcf\xfe\x73\xb6\x48\x53\x5f\x18\xe8\x45\x3c\xfd\x73\x69\x08\xd1\x6a\x3a\x23\x00\x6a\x77\xb2\x35\x9a\xa3\x14\x1f\xd7\x26\x4c\x2d\x01\xcf\xc7\xba\x68\xcd\x8e\xb9\x8c\xf7\x38\x78\xfe\xc9\x19\xed\x0d\x15\x8e\xc4\x23\x03\x66\x5e\x35\x2a\x0b\x1e\xaf\x6c\x93\xc8\xd0\x87\x7a\xe1\x58\x56\x97\x9f\x55\xf6\x09\x3f\xaf\x11\x41\xcc\x50\xa1\xc9\xe9\x65\xa3\xfb\x87\xe5\x25\x96\x50\xcc\xf7\x4a\x13\x0c\x5e\xe1\xe2\x5f\xbf\xbc\x4c\x63\x5c\xe3\x27\x10\x81\x00\x92\x78\xd2\x51\x3f\x92\xbb\xac\x78\xc9\x5d\x9d\xd2\x27\x35\x25\x22\x0a\x83\x20\xf0\x88\xba\x31\xfa\xd2\x0f\x85\x88\x28\xc5\xc8\xb3\xa3\x0b\x7d\x15\x35\xec\xcb\xbb\xd5\xe6\x03\xe0\x2d\xf2\x0f\x1c\x09\x86\xf6\xca\xbb\x45\x0e\xc3\x50\x2c\x75\xf4\xf9\x45\xac\x06\x75\x1f\x4f\xf9\x5f\xa8\x6b\x18\x91\xc4\x92\xb9\x1a\x64\xcc\x0e\x22\xd9\xfd\xe8\xad\xa6\x17\xd0\x20\x36\xbe\xba\x2a\x17\x1f\xb5\x27\x2c\xb1\x28\xf0\x9b\x73\x35\xe0\xd0\x69\xbb\x87\xb8\xb1\x39\x91\x88\xb9\xc2\xcb\xaf\xdd\xff\xab\x9f\xa7\xd0\xa9\xcd\xdc\xe9\x8d\x79\x7e\xbe\xbb\x19\x45\x51\x44\x22\x28\xf2\xdc\x9d\x8e\xbe\x4e\xda\x3f\x0c\x4d\x62\xd6\x81\x66\x2c\x01\xaf\xff\x2e\xf5\x52\xe4\x79\xd9\xf7\xd4\x02\x45\x18\x1f\x4a\x7d\xce\x9b\x2f\x79\x0e\xc6\xe3\xcf\x02\x89\xb4\xe0\x43\xf1\xd3\xf9\x81\x6c\x8d\x75\xd2\xd1\x8a\xb8\x9c\x91\xff\x7d\x4e\x28\xca\x43\x09\xad\x6f\xdb\x39\xfc\x09\x77\x91\x11\x5c\x29\x5c\x49\xdf\xa1\xca\xb0\x9e\xcd\xfa\x27\xb7\x42\x35\xa5\x17\xf4\x33\x82\x43\x62\x65\xd5\x91\x17\x75\x32\x65\x04\x55\xd2\xaa\x57\x5a\x51\x81\xfb\x52\xbd\xad\x3b\x1c\xae\x10\x69\x8a\x8f\xa2\xc1\x86\xac\x26\x01\x04\x21\x64\x84\xe9\x5d\x64\x5b\x5d\x34\x8d\x50\xaf\x58\x8d\xda\x23\x29\x03\xe2\x27\xbb\xd0\xb1\x2d\x20\xef\x39\x3c\xf6\x20\x8e\x5f\x31\xcc\x18\x21\x49\x12\xbb\xb0\x59\xf7\xb5\xae\xcd\x73\xdf\x59\x47\x58\xcc\x71\x7c\x12\xe7\x1a\xf4\x20\x4d\x2e\x54\x64\xeb\x1d\x0c\x40\xfd\x4d\x20\x29\x4c\xf7\x92\x9a\x45\x98\x10\x3c\x34\xd9\x11\xb6\xbe\x08\xaf\x6f\xb5\xc2\xa8\xeb\xa2\x81\x6a\x0b\xc5\x90\xa8\xd1\x08\xad\xad\xbb\x27\x6d\x45\x88\xff\x33\x10\x9a\x74\x26\xbb\xa8\x9a\x3b\x55\x3e\x55\x98\x3e\x1b\x3f\x31\xc4\x0c\x59\xe7\x0d\x26\x6a\x6a\x54\xac\x2c\x3c\x9f\x88\x11\xc0\x2c\xc6\xe4\x6e\xb5\x39\xce\xa4\x35\x7d\x2f\x43\x45\xe2\x21\xd8\x50\xdd\x96\xd5\xbd\xa8\x9b\x07\x2c\xe7\xee\xdf\xc3\x50\x86\x11\xe2\x93\xb8\x40\xa7\xe7\xb8\x12\xa7\xac\x2f\x3b\x17\x86\x25\xc4\xd1\x90\xa2\xd0\xd1\x78\x2b\x34\xd2\x66\xa0\x70\xe7\xdc\x42\x0d\xa2\x52\xaf\x57\xcc\xfe\x9f\xac\x5d\x03\x52\x89\xbf\x2e\xb4\x19\x5f\x25\x89\xb6\x7c\xb5\x3d\xf9\x19\xee\xea\x77\x85\x29\x3d\x8c\x4b\x06\x3c\xd5\x41\xcf\x09\xde\x9e\xaa\x9b\xe2\x8b\x40\x89\x0c\x03\x8b\xd3\x43\xdd\xbf\xc2\x97\x7b\x5a\x39\xa2\x49\xcf\xc4\xb0\xd0\xe5\x6c\x56\x90\x77\xc9\x23\x19\x72\x8d\x49\xc1\x93\xa8\x9b\xc5\x4b\x05\x33\xf0\x1e\x19\x1a\x86\x6c\x64\x59\xbd\x6a\xad\x11\x57\x31\x6a\xeb\x1d\xbb\x2e\xb2\xd7\x59\x46\xc5\x8e\x75\xf3\x6a\x2b\x97\xd1\x40\xf9\x3e\x49\xa9\x5d\x95\xd7\xc9\x98\xb1\xd8\x72\xb2\x6d\x4c\x05\x35\x54\xb6\x5a\x79\x62\x18\xc8\x58\x26\x69\xe4\x37\xbf\xf9\xe3\x53\x26\x84\xe0\x51\xff\xbf\x65\x56\xf8\xc0\xe8\xe4\x36\x49\x60\x15\x52\xfe\x55\xd6\x59\x71\xae\x07\x75\xa8\x32\x09\x89\x67\x25\xbb\xcd\x0a\x51\xa8\x4c\xe4\xb3\x01\x62\x99\x88\x98\x85\x03\x02\xbd\xab\xf4\xa5\xa4\xa9\xb1\xde\xd2\xd3\xb9\x7a\x01\xa7\xd7\xd1\x8d\x3d\xd5\x9c\x0f\xc2\x39\x03\x4e\x99\x29\x89\xba\x91\x69\x6c\x93\x37\xdf\xcb\x73\x85\x2c\x64\x8f\xbd\x23\xd9\x75\x11\x60\x41\x4e\xcb\x76\xed\xd9\x89\x3f\xbe\x0b\x8b\xed\xbe\x6e\xc5\x49\x06\x5c\xc4\xbe\xdd\x04\xb8\x0f\xbb\xab\xf6\xa5\x75\x14\xee\xae\xe0\xe2\xae\x3f\xa7\x34\xb2\x0c\x88\x16\x7a\x32\x8d\x31\xce\x7f\x1f\x11\xa6\xa8\x52\x70\x3c\x64\x5d\x61\x68\xbd\xf4\xb0\x2b\xbf\x73\x8c\x7f\x49\x30\x8d\xfb\x50\x53\x7e\x87\x5f\x3b\xcb\x8d\x30\xbe\xab\x8c\x14\xc2\x60\x7a\x20\xdc\x13\x2a\xa7\x85\x43\x0d\x08\x23\x25\x97\xb8\x0f\x1f\xb2\xda\xd5\x61\x4e\x7e\x49\x45\x80\x53\x63\xf9\x7c\x7b\xdb\x15\x41\x48\xe5\x84\x32\xa4\x67\xe0\xf9\xb2\xd4\xcc\x5d\xa4\x63\x83\xfb\x19\xee\x33\x4e\x39\xf1\x6f\xc5\x5f\x24\x44\x2c\x54\x9d\xb8\x35\x06\xbf\x07\x53\x14\x44\xa2\x3a\x0e\xa5\xde\xba\xde\x7c\x74\x47\x81\x04\x80\xd0\x27\xb4\x6d\x10\x11\xaa\x76\xaf\xfc\x26\xea\xc5\x4c\xe0\x51\x91\x80\x62\x7f\x9f\xcb\x7f\x12\xea\xed\xea\x5c\x52\x81\x3b\x24\x3a\xf7\xac\x2a\x8f\xb6\xc6\xbb\x67\x0c\x9b\xdf\xab\x54\x48\x42\x4c\x04\x3a\x9b\xf6\x07\x5c\x06\xd2\xb7\x46\x85\x34\xc6\xe2\x39\xcf\x69\xfd\x85\x34\xa2\x51\x11\x89\x11\x85\x62\x95\xa1\x06\xd9\x74\x15\xa9\x28\x92\x98\x6e\xb4\xb0\xed\xdb\xb2\x6a\xce\x05\xac\xca\xf2\x2d\x1b\x72\xff\x18\x15\x83\x40\x63\x14\x83\xcc\x4f\xd0\xb8\xad\xed\xf3\x17\x48\x28\xc5\x77\x77\xb9\x69\x27\x29\xe8\x7f\x38\x01\x83\xd4\xfa\xea\x30\x2a\xfd\x18\x70\x26\x19\x95\x18\x8d\xfc\xf3\xb7\x5b\x0b\x31\x70\x7f\xa6\x42\x87\x1e\xd2\xe4\x99\x18\xd1\x76\x5d\x5e\xf6\x59\x93\x4f\x8a\x8e\x14\x95\xc6\x32\xe3\xa8\x32\x82\x62\x68\x1b\xa8\x54\x84\xbe\x06\x6e\xdd\xbc\xce\x7e\x67\x26\x02\x34\x11\x5c\x6a\x7d\x28\x9b\x3c\xff\xda\x3c\x89\x49\xe4\xd8\x76\xad\x64\x31\xaa\x53\x2f\xb3\x4a\xaf\x0b\x3d\x74\x48\x14\x97\x06\x11\x7c\x07\x77\xae\x7e\x88\x4a\x2f\x73\x31\x80\xd8\x0f\x2d\x5c\x25\x22\x92\xa4\xee\xe8\x79\xca\x85\x9d\x0f\xa3\x98\x84\x92\x31\x24\xc3\xf9\xe6\x98\xce\xe7\x9f\x54\x82\x75\x60\x5f\xa0\xb9\xad\x00\x6e\x2a\xf1\xd2\x99\xa2\x4a\x71\x65\xfa\xa3\x72\x52\x77\xe9\xfa\xe8\xc4\x52\xfd\x7e\xb3\x14\xf9\xee\x0b\xbb\xc4\xf8\xb8\x2b\x10\x70\x64\xf0\xed\x88\xdc\x67\x05\xfc\xac\xca\xce\x44\x51\x40\x6d\xa1\xe8\x41\x68\xfd\x03\xe0\x34\xdd\x88\x15\x68\x1a\xda\x74\x48\x5d\xe6\xef\xb0\xec\xf0\x5f\x0a\x80\x45\xc6\x73\x50\x94\x47\xa7\x76\x37\xfe\x75\x13\x05\x10\x0d\xe1\x77\x58\x1d\x34\x55\xcd\x34\x9a\x84\x1c\xe9\x72\xff\xfc\xf7\x6a\x4e\x57\xe5\x7c\x05\x0e\xd3\x01\x4d\xe2\xa0\xc3\xc2\x43\x15\x8e\xc1\x08\x3a\x90\x01\x7a\xa6\x47\xf1\xab\xfd\x59\x57\x88\x75\x8f\xc2\xee\xae\x4b\x18\xa5\xc8\xe4\x7c\xb7\xd9\x0d\x0d\xcc\xf6\xef\xe0\x7c\x34\x17\x28\xff\x39\xaf\x5f\x66\x74\xc8\x24\xa6\x57\x1b\xa8\x51\x14\xce\x69\x74\x35\x97\xf6\x1f\xfe\x7e\x91\x90\x6c\xc0\x08\xe1\xff\x1c\x1b\xc6\x9d\x9d\xfd\x7b\x76\xba\x62\xb3\x32\x3a\x49\x23\x6e\xab\x4a\x0a\xbb\x42\x12\x7f\x69\x22\x22\x3e\x46\x3b\xec\x1e\xee\xee\xd7\x9f\x39\xc6\x3a\xd1\x29\x82\x8f\xd7\x36\xff\x37\x0b\xc0\x1b\x8d\x6e\x02\x16\xa1\x7e\xd0\xa0\x4a\x0d\x3b\x4c\xbc\x0f\xc3\xbc\x9a\x06\x01\x0a\x18\x22\x3d\xe6\x38\x85\xa6\xa9\x13\x60\xeb\x4d\xc8\xae\x0c\xe1\xb6\x5d\x39\xbe\x5f\x1a\xd8\x9d\x16\xc1\xd6\xed\xe1\xf7\x6d\x7d\xd8\x78\x8d\x05\xa3\x53\x4e\xa9\x27\x29\x29\xdf\xe0\x58\x5e\x3d\xf3\x97\xa7\xb7\x4e\x85\xc0\x02\xbb\x73\x81\x41\xee\x2e\xa8\x3b\xbb\x28\x35\x63\x21\x62\x5b\xbe\x41\xb3\x7a\xcd\x4e\xd7\x9c\x47\x9a\xc9\x18\x49\x53\xde\x45\x91\xd5\xaf\xed\x31\x37\x99\xee\x9a\x13\x8e\x56\xd4\x84\x5b\x74\x77\x96\xc7\xac\x19\x28\xe0\x5c\x39\xdf\xb3\xa7\xb2\xe6\x26\x40\x73\xf6\x46\x94\xdb\x73\x4f\x9d\xa2\x45\xc0\xb0\x3c\xef\x55\xd4\x4f\x65\x99\x0f\x2b\xfd\x7c\x8f\x28\x41\x72\x65\x7f\x48\x4e\xb0\x0a\x5a\x24\x8a\x75\xf1\xb6\xd6\xbf\x2b\xcb\xfc\x21\x2b\x9a\x7f\x9d\xcb\x0e\x90\xa0\x65\xc4\x70\x4f\xdb\x57\xea\xcb\xc9\x22\xd3\x00\x63\xbb\xba\x3c\xcb\x2e\x04\xad\x65\x1a\x22\x89\xd4\x0b\x72\x5b\xf9\xbf\x2a\x92\x60\x38\xe3\xe4\xbc\x91\x55\xbb\x22\x86\xda\xd1\x46\xab\x30\xc6\x58\x5b\x0e\xa6\xe1\xf1\x64\x84\x4d\x12\xe8\xc4\x03\x11\x17\x79\xe7\xc7\x8f\x5f\xdf\xa4\x31\x02\x5b\x0e\x18\x42\x8a\x0e\xc3\x65\x67\x84\xa2\x7e\x7f\x5d\xfc\x61\xb2\xa2\x80\x89\x71\x09\x01\xa1\x18\x44\xb1\xd5\x17\xf7\x96\x57\x6b\xf4\x0b\x10\x10\x81\x3a\xde\x38\x9f\x47\x62\x62\xff\x98\xdc\x2b\x92\x3c\xf4\x7a\xa7\x0e\xec\x39\xc7\xf1\x6e\x20\xa4\xd2\x92\x65\x89\x2c\xaf\xaf\xe5\xcb\x0c\x84\x32\x4a\x12\x5f\xa4\x78\x84\xdf\x45\x87\xb0\x80\x10\x24\x77\x15\x08\x3b\xc8\xbb\xda\xde\xc9\xa6\x35\x79\xb4\x28\xa0\x98\x86\xf0\xd5\x5c\x8f\x65\x93\x19\xcf\x58\x35\xe9\x9a\x58\xc9\x6e\xa1\xf5\xea\x55\xb4\x33\xa9\xc3\xd2\xcc\x47\x11\x20\x02\x45\xb5\x17\x53\x37\x50\xe8\x65\x59\xd6\xcd\x80\x97\xdb\xf5\x8b\x63\xa1\x9d\x91\x10\x3f\x74\x86\x23\xc4\x29\xb5\xa0\xce\xd7\xf2\xe3\xe1\xe2\xb8\x13\x47\x26\xbb\xeb\x98\x30\x40\x90\xcf\xbe\xca\xfa\x1d\x08\x12\x63\xc1\xd7\xaf\x42\xbd\xed\xa1\x38\x97\xe7\x89\x4b\x04\x94\x68\x04\x0f\x75\x29\x49\x3c\xce\xa1\x9a\xe7\xda\x01\xaf\x6e\x81\x44\x51\x9d\xa6\x95\x87\x84\x4e\xdd\x29\x60\x82\x08\xac\xed\x95\xea\xbe\x6c\x9a\x72\x6b\x4f\xcf\xee\xf9\x98\x08\x88\x25\x27\xf8\x91\x0d\xc2\xe6\xc0\x94\xb4\x72\xdc\x55\x79\x2c\xdb\xef\x80\xfc\x77\xfb\x12\x01\x25\x62\x7a\xfc\x00\x0f\x38\x62\x15\xfc\x32\xf7\x31\x86\x2e\xbc\x80\xb2\xac\xed\x73\xbf\x97\x0d\xb4\xd3\x61\x05\x53\x2c\x04\x70\x11\x60\xc0\x77\xf9\xe3\x79\x78\x0c\x82\x08\x00\x91\x6b\xde\x65\xba\xd6\x9a\x9e\xec\x62\xfe\x3a\x1a\x63\x02\xb0\x75\x00\x5f\x72\xd1\x61\x0a\x40\x88\x10\x33\x1c\x4a\xe4\xf9\x1e\xea\xcf\x19\x5c\xae\x08\x6f\x0d\x08\xad\x3c\x04\xc5\x61\x7b\xbf\x74\x4b\x40\xca\x00\x92\x21\xfa\xfe\xbb\xa8\x17\x66\x52\xd8\x06\x5a\x71\xac\xa4\x7f\x05\xfd\x32\xa1\xb5\x02\xad\x43\x13\x7a\x66\xf1\xba\xe9\x53\xa4\x00\x91\xcd\xc2\x78\x6f\x58\x7c\x2d\xbc\x39\x02\xe6\x00\xa4\x56\x40\xd9\xbb\x0f\xb3\xb5\x81\x93\x97\x81\x54\x26\xe9\x00\x8e\xf4\xaf\xb3\xa8\x1a\xa8\x76\x20\xea\xb2\xf8\xad\xbf\xb9\x21\x2a\xe2\x76\x5a\x2d\xcf\x97\x65\x3b\xf7\xbb\xa7\x36\x41\x60\xeb\xaa\xb1\xa2\xe0\x07\x8c\xe5\x5b\x8c\x09\x44\x82\x26\xff\xdd\x6a\x73\xf8\xbe\xd8\xde\xac\x16\x4f\xfe\xca\x30\x00\x0c\x51\xdd\x97\xae\x50\xf5\x6a\x02\x0c\x3f\x95\x09\x93\x44\xd3\x11\x63\xcb\x48\x23\xc3\xf5\x8a\x79\x84\x45\x47\xf7\x9b\x6f\x07\x1f\x66\x74\xa1\x31\x1b\x8d\xe9\x7e\x64\x74\x59\xc2\xed\x91\x28\xb4\x7e\xc8\x8a\xf3\x15\x97\x84\x49\x94\x44\x58\xa2\x23\x43\x1e\xe5\x26\xfd\xf2\x34\x89\x21\x61\xd0\x6b\xa8\x57\x20\xf4\xe5\xb9\x9e\x2e\x7a\x43\x69\x82\xb9\x9d\x7b\xa7\x52\xfc\xd9\xe9\xfd\xe5\x54\x34\x34\x05\x0c\x3d\x78\x5e\xec\xa7\xaa\xfb\x26\x54\x31\xad\xed\xa0\xa3\x2a\x7d\xe7\x65\x1a\x0a\x3c\x0d\x1c\xe9\x5a\x6b\xb8\x8b\x6a\x72\x48\x99\x34\x0c\xb9\x93\x47\x6d\xb7\x18\xa8\x2e\x73\x16\xb8\x61\x41\x64\xf4\xc0\x31\x41\x0d\xc5\x89\x91\x6f\x58\x28\x30\xbe\xe3\x93\x2d\xf6\xc8\x9b\x0f\x1c\xcc\xbf\x24\x4b\x93\x58\x79\x55\x14\x51\x59\x65\xdb\x1b\x90\xe7\x97\xdb\xb2\x6a\xd7\xcf\xf6\x69\xe5\xdf\x8d\x47\x96\xfc\xf8\xb1\x14\xaf\x83\x60\x81\xe1\x89\x11\xb6\x5e\xb3\x69\x3d\x84\x91\x28\x83\x31\x5c\x32\x24\xfa\x2a\xe0\x63\x82\x5d\x76\x1d\x04\xa7\xde\xea\x5c\x96\x65\x3e\xa2\xb4\x73\x5d\x64\xac\xb1\xa0\xa3\x80\x5f\x16\x06\x3c\x80\x65\x1b\x99\x00\x75\x5e\xd9\xfa\x1d\x85\x16\x67\xbc\x90\xfe\x8d\xa5\xb2\x99\x1c\x28\xf4\x9d\x42\xf9\x14\x74\x0b\x7d\x0e\xc9\x48\xcd\x3d\x4d\xe8\xad\x32\x5d\x35\xdf\x57\x40\x76\xa3\x1c\xa5\x5d\x5e\xbe\x64\xf3\xec\xac\xc6\x28\x16\x05\xc2\x0b\xeb\x60\x82\xee\xae\x68\xe0\xa5\x75\x3a\xb0\x3a\x2f\x0a\x2d\x26\xc3\x77\xd7\x2a\xb0\x44\x02\xf6\x01\x6e\x6c\x5a\x61\x62\xcf\x18\x1d\x8a\xc0\x31\xf1\x7f\x42\xfa\xf6\x25\xe1\x8a\xbb\x0b\x70\x89\x65\xe2\x7e\xb2\xed\xcb\xbf\x39\x7d\x40\x26\xc8\xac\xfe\x70\x59\x96\x7f\xb3\x3c\xc8\x80\xb2\xa8\xd2\xf7\xac\x50\x99\x07\x19\x73\x42\x88\x8c\xb4\xe3\xd5\xf0\x45\x3b\xc3\x97\x6d\x7b\x18\x85\xf5\x02\x6f\x59\x9e\x77\xa7\xda\xc8\x44\xe6\x84\x04\x24\xd6\x7d\x4d\xbb\xfb\x6e\xc3\xea\x9f\xeb\x63\x6b\x98\xa0\xbd\xfe\x3f\x13\x0e\x8e\xf6\x27\x62\x83\x5e\x16\x46\x76\x76\x9d\xb7\xb9\x31\xdf\xcb\x73\x0d\x6b\x3d\x8e\x6a\xb5\x17\xb0\x28\xb6\x1a\xeb\x65\xf5\xd1\x3a\xd3\xad\xf5\xf9\x13\xb2\x49\xb7\x50\x4b\x2c\xd9\xab\xb2\x97\xd7\x26\x48\x27\xad\x91\xd0\xc6\xca\x76\x63\x1c\x09\xf4\x2d\xb8\xe9\xd2\x36\x1a\x83\xc0\xc8\x3f\xd6\xfb\xd0\xff\x2d\x0e\xa5\x30\x57\x6c\xf5\xbd\x37\xd8\x76\x89\x75\x60\xf1\x06\xa2\x86\xfd\x47\x39\xc4\x74\x75\xb7\x49\x9c\xa2\x92\x33\x52\xf2\x72\x7e\x1d\x70\x42\x92\x90\x7a\xe9\x67\xaf\x7a\xdd\xff\xee\xf8\x6d\x12\x6e\x0d\x9c\x83\x16\x97\x7a\x5f\xde\x4c\xdc\x68\x4e\x08\x0d\x42\xb4\xc0\x97\xe2\xbf\xff\x7d\x6d\x3a\x0b\xa7\x6d\x89\x6c\x28\x0c\x33\xff\x1d\x49\xef\xf2\x72\xcd\xfe\xd4\x76\x4e\x2c\x07\x45\xeb\xd4\x41\xd5\x5c\x76\x63\x22\x81\xb6\x07\x8b\x1c\xec\x5d\xe2\x93\x0e\xcc\xe8\x7f\x8c\xef\x95\x12\x2b\x6d\x3d\x54\x97\xff\x34\xe1\xf9\xc9\x2d\x82\x30\x95\x1e\xed\xda\x5c\x6d\x76\x6d\x8f\x90\x2a\x9f\x49\xe9\x58\x8c\xda\xbf\x2b\x8d\x8e\xd9\x7e\xf3\xc7\x00\x97\xd2\x36\xe8\x04\x03\x3a\xfe\x03\x59\x9b\x24\x9e\x8c\x03\xa3\x11\x06\x94\xb4\x8d\x4c\xed\x41\x1c\x9f\xa0\x9a\x50\xfb\xb7\xfd\x98\x2d\x6d\x3c\x17\x35\x34\xeb\xed\x2a\x4d\xd3\xc9\x78\x31\x4d\x7d\x6a\xfb\x3b\xaa\xdd\xe1\xea\x1a\xbf\x04\xe7\x80\xa0\xf8\x53\x05\x77\xaa\x1c\xbe\x86\x20\x96\x88\xca\x79\x9d\x23\x05\xf1\xc9\x58\x09\x9e\xe2\xd1\x01\xc5\x90\xe3\x9d\x13\x22\xd3\x4e\xcb\xeb\x67\x59\xbd\xf5\x18\xde\xf1\xf5\xca\x10\x8c\xf2\xc0\xa9\x54\xaf\xbf\x75\x7f\x34\x9e\xb5\x7d\x5d\xbf\x94\xfb\x3f\x6e\x27\x3c\xac\x9c\x10\x1d\x45\x28\x28\x33\x5e\x39\xab\x11\xcd\x21\x76\xb3\x62\x78\x1d\xdc\x7c\x00\x37\xf8\xdc\xc9\x6a\x2f\xa4\x06\x41\xe7\x47\xf1\x0b\x8f\xb3\xa0\x0f\x6e\x3f\xb5\xc3\xe9\x30\x10\xbe\x37\xb3\x4a\x31\x9e\x1e\xc9\x43\x67\xf6\x15\x4c\xe7\x8e\xd6\xdc\x89\x40\x7d\x78\x9b\xe0\x01\xa9\x3f\xec\x9c\x18\xfc\xf9\x2b\xbc\x03\xde\x48\x22\x07\xc3\xcf\xd5\xad\x7f\x0c\x08\xc2\xd8\xeb\xe4\xa0\x3c\x56\xdf\x90\xd0\x60\xa8\xe4\x5a\x97\x85\xc8\x1f\xb2\x42\x8d\xbd\xc6\xb6\xab\x4c\xac\xa9\x60\xc3\x4b\x1d\xc3\xdb\xf4\xcb\x19\xc2\x88\x2d\xb5\x7a\x87\x1e\xf7\xde\x0b\x27\x76\xfa\xb3\xb6\x7f\x40\xe2\x94\x68\x97\x76\x5a\xd4\xab\xf2\x98\x15\x2f\x8b\x42\xdf\x62\xfc\xe8\x37\xdf\x29\xb5\x8a\x14\xf5\x80\x99\x61\x7e\x23\x0b\x88\x4a\x89\xec\xf9\x47\x5a\xbb\x0a\x03\xd1\xf5\x6d\x59\x3d\x95\x65\xde\xdd\xd2\xa4\xa1\xb3\x99\x7f\xc0\xa5\x5e\x5e\x9e\xce\xd5\xa9\xac\x27\x5b\x59\x10\x52\x81\x13\xd1\x4a\x57\xd5\xeb\x5f\x50\xa9\xac\xee\xc9\x4a\xe6\xe2\x48\xed\x65\x2a\x16\x7d\x1d\xef\x84\xac\x9c\x93\x20\x4a\x0c\xe6\xdb\x8f\xe2\xd7\x16\x84\x7a\x75\xfe\x68\xdb\x22\xec\xbe\xee\x1d\xcc\x61\xa6\x6e\xf2\x23\x91\x0e\xa0\x53\xed\xeb\x88\x3d\x9c\xb3\x36\x02\xfa\x4c\x2e\x8c\x25\x49\x6d\xee\xa9\x54\x6f\x22\xab\x50\xa8\xc1\xb5\x25\xa1\xc6\xb2\xb6\xfb\xac\x35\xf5\x1b\xf5\x37\xd8\x90\xda\xab\x20\xd0\x6a\xe8\xfc\xb9\xcf\x34\x55\x03\xe2\x24\xa0\x52\xa1\x27\xa0\xb0\x64\x64\x5a\x67\xe8\x3a\xa5\xc4\x32\xf0\x61\x15\xf8\xfb\xe0\xb8\x0c\xd2\xc0\x26\xc2\xcb\x02\xfa\x3f\x59\x55\xfb\xba\x35\x43\x8b\x73\x8d\x56\x61\x30\xf9\x59\xa6\x62\xa7\x7d\x5d\xed\xa0\x7a\x87\xca\xd9\xee\xd7\x96\x26\x27\x81\x0c\x89\x65\x2b\xc0\x5a\x8e\x53\x56\x74\x3f\x2f\x9d\x54\x08\xbc\x0b\x75\x1e\xf8\x4c\xbe\x99\x5b\x05\x13\xac\x49\xf1\x30\xb2\x81\x49\xe2\xba\xa9\xd8\xca\x6a\x5a\xc4\xc9\xef\xed\x44\xf5\x3f\xa0\xd2\x04\xbf\xbf\x2a\x8f\xc7\x69\x84\xba\x6d\xe6\x31\x66\x78\xea\xd7\xf2\xc3\xef\x6e\xc3\x22\xac\xb6\x0b\x88\x74\x28\x01\xbb\x56\x65\x7d\xa9\x1b\x38\x0e\xc8\x9c\x39\x09\x74\x9a\xe2\x24\x78\x2f\xb1\xaa\xd4\x12\xa6\xb5\x5e\xea\xf8\x8d\xb4\x20\x18\x2d\x42\x8b\xc9\xe6\xef\xa7\xfb\xd0\xe8\x09\x43\x12\x26\x18\x8c\xd8\x18\x93\x29\x91\xb7\xe7\x8c\x07\x68\x70\x12\x06\x8a\x44\x4e\x87\x47\x67\x4d\x8f\xab\x18\xdf\x23\xd0\x1a\x19\x49\x1e\xb2\x62\x09\x8d\x0d\xc5\x5b\x7a\xb7\xc9\x6c\x0a\xa3\x90\x5a\xfb\xb7\xb4\x96\xf9\xfc\xf1\x1f\x46\xd4\xb2\x4f\xef\x5e\xbd\x38\x43\xfb\x47\xc5\xd1\x9f\xfb\xf3\x7c\x1a\x12\x72\x72\x12\x26\x42\x62\x28\x0d\x9a\x0e\x0d\xd7\x94\x3f\xfe\x5c\x4d\x7e\x3c\x01\x0b\xb2\x2f\x2c\xb6\xfe\xce\x2f\xe2\xb0\xf5\x62\xbd\xd8\xc0\x4a\x78\x39\x87\xb6\x41\x68\x04\xc2\x2f\x64\x8d\x9f\x6e\xf7\x71\x95\x01\x6a\x7b\x49\x8d\x65\x9d\x5b\xac\x47\xff\x56\x89\xd3\xeb\xb2\x2c\xa7\x65\x64\xbe\xb3\x06\xc4\x8b\x59\xf2\xd0\x29\x35\x2c\x27\x61\x9a\x58\x64\x32\x12\x98\xb8\x60\xe3\xc6\x98\x49\x2f\x16\x25\x18\xe1\x36\x16\x8c\x15\x0e\x63\x33\x6d\xb3\x09\x71\x5b\x95\xa5\xbe\xac\x73\x44\x82\x2c\x2f\xbb\xb3\x44\x8c\x34\x2a\x46\x8c\x9f\x8a\xc7\x71\x2c\x3a\x4c\xa3\xfc\xe4\x9c\x0f\xb9\x88\xc2\x3e\xb0\xb3\x15\xe7\xba\xaf\xb0\x0e\xba\x95\x73\xee\x44\xbe\x38\x09\x05\x8b\x94\xf6\x15\x4f\x16\x88\x7a\x9e\xb5\xfc\xbe\x0a\x12\xb4\xf7\x91\x36\x08\x87\xa1\x26\x9f\xad\xe5\x24\x54\x44\x23\x15\xa1\x27\x5b\xf2\x4c\xca\x75\xb7\x47\x87\x2a\x12\xda\x46\x52\x36\x0f\x77\x8b\xe0\xb0\xb8\xb9\xd9\x76\x6d\x94\x21\x22\xf2\xa9\x2a\x1b\xb4\xf5\xb7\x30\x56\x01\x98\x5f\x35\x8a\x87\x16\xa2\x96\x8b\xcb\x77\xe1\xcc\x9a\x51\x99\x99\xfd\x5f\x2f\x8e\x3f\x14\x77\x3f\xf7\x0a\x67\x9c\x84\x3a\x49\x10\x58\xb0\xdf\xec\x17\xf7\x43\x0d\x74\x4e\x42\xa0\x31\xc6\xe8\x36\xa2\x79\xed\xfe\xa6\x01\xf5\x30\x21\x3b\x05\x34\xd9\x9d\x4f\x28\x53\xa9\x27\xd3\xc3\x04\x31\x1f\x1a\x4c\x9e\x07\x67\xf6\x6d\x22\x42\x20\x72\x3c\x50\x8f\xf0\x31\xc9\xd7\x0f\x0f\x8e\x88\xc4\x51\x6c\x05\x5b\x0d\xec\xcb\xdd\x59\x8e\x37\x4d\xdf\x0b\x62\x4c\x56\x5a\xc8\xc3\xb9\xd0\x5b\x31\xf8\x1e\x51\x90\xda\x42\x62\x9c\xbb\x56\xc8\x00\x55\x56\x7b\x32\xa4\xb6\x93\xd4\xf8\xbd\x0f\xf2\xec\xc4\x1b\x6e\xab\xf2\xb8\xc3\x42\xf5\xf1\xac\x8c\xc2\xc8\x9e\x8f\xfb\xea\x5c\x37\x39\xd4\x75\x07\x89\xc5\x33\xe3\xa1\xd4\xad\x8f\xdb\xbb\xed\xfd\xce\x1e\x85\xd2\x78\xc1\xb2\x1b\x71\xb1\x91\x24\xff\x04\xa1\x09\x44\x6f\x9b\x2e\xa1\xf8\xaf\x15\x1f\xfa\x64\x10\x23\x0d\x68\x9c\x61\xd9\x5d\x17\xb5\xe1\x24\x8a\x53\x6a\xe1\xca\xe7\xa3\xb2\xd5\xc2\x5d\x8b\x8c\x43\x47\x79\x3d\xa8\x07\xe5\x24\x4a\x64\x8c\xb4\x3f\xcb\xac\xc8\xce\x9f\xa7\x96\x38\x89\x68\x1c\xa2\xfd\xb6\x2a\xeb\x63\xe9\x2f\xf7\xaa\x79\xb5\x47\x28\xef\x26\xfa\xc0\x9c\x44\x3c\xb2\x6f\x7e\x14\xbf\x9e\xa0\x42\xd0\xa3\x6f\x01\x82\xe2\x9e\x05\x7c\xdc\x88\x8b\xff\xab\x88\x00\x11\x01\xc6\x51\x04\xdf\xa9\xee\xe7\x04\x0b\x91\x1f\xce\xd1\x5e\x9c\xba\x9a\x42\xf0\x96\x75\x24\x03\x83\xc4\x58\x50\x08\xd5\x74\xec\x78\x22\x3f\xe4\xc3\x58\xcf\xec\xca\x8f\x94\xb2\x81\xd7\xb1\xfa\xfa\x2c\xa0\x84\x93\x48\x13\x81\xc2\x0f\xa7\x09\x96\x65\x74\x9a\x46\x3a\x8a\xe2\x11\x06\xe8\x16\xd5\xde\xc6\xab\x28\xd2\xdc\x22\xbd\x7f\x82\x44\x42\xaf\xee\x6a\x19\x60\x58\xe2\xd7\x6f\x83\xa9\x04\x3c\xc1\xe9\x72\x03\xf5\xdb\x95\x26\x30\x27\x91\x09\x55\x6c\x55\x22\x5a\x8f\x1d\x8a\x06\xf7\xf6\xee\xa8\x8d\x8c\x89\xb1\xee\x15\xb1\xaa\x37\x3f\x22\xf7\xf7\x38\x88\x03\x44\xea\x0f\x18\x3b\xda\xbf\x4a\xcb\xd8\xb1\x7c\xfc\xd9\xfd\xc9\x84\xf8\x45\x7d\x8e\xc3\x27\x57\xaf\xdd\xae\x38\x30\x36\x0d\x7b\xc4\xb4\xf4\x30\xa8\x79\xc5\x45\xc2\x51\x28\x07\x81\x85\x1a\xde\x63\xbb\x48\xc3\xa7\x2e\x0c\x14\x87\x42\x84\x16\xfb\x81\x5b\xcc\x6d\x7b\xb2\xb6\x27\x0c\x4c\x0e\x8f\x38\x94\x56\x34\xe7\x84\xc1\x8a\xd1\x4a\x88\x43\xad\x34\xf7\x6d\x0f\x65\x01\x97\x7f\x9d\x85\x2d\x4a\x72\x3d\x22\xa2\x88\x0b\x5e\xfe\x0e\x55\x9d\x95\xc5\xdd\xf1\x64\x4f\x36\x87\x2e\xfc\xa2\x1e\xa7\xbd\x3e\x90\x74\x98\xcb\x5b\xe4\x39\x4a\xc6\x4d\xd3\x88\x9c\xc4\x71\x02\xdc\x0c\xad\xe3\x47\x39\xe9\x41\x0d\x18\x4b\xbb\xff\xb1\x3a\xdb\x8a\x96\xd1\xc7\x8e\xd3\x98\x28\x07\xdf\xd9\xd4\x4a\xf8\x75\x10\xa7\x42\x63\xcd\x53\x87\xcd\x72\x9c\xcd\xe3\xab\x59\x24\xb0\xc6\xe4\xa9\x9d\x93\x56\x92\x61\xda\x83\x05\xd4\xd2\x15\xd7\xe7\xbc\x41\xf9\x8e\x6a\x30\x9c\xcc\x24\x56\x18\x69\xe4\x56\x7f\x1b\x88\xcd\x8f\xdf\x47\xa4\x3a\xb6\x42\x19\x5a\x8c\xa8\x3a\xda\x36\x61\x85\x83\x4d\x59\xc1\x4b\xd5\x01\xbd\xda\x16\xad\xd0\x38\x5c\x6f\x57\x61\x64\x05\x2d\x86\x33\x68\xfc\x13\x32\xa6\xf8\x4e\x8f\xeb\xcd\xd0\x76\x8b\x25\x4d\x2d\x1b\x8a\x2a\x91\x47\x5d\x5b\x37\x3a\xef\x3e\xbc\xd4\x54\x93\x01\xd5\x6e\xdd\x09\xa9\x8f\x7f\x40\x51\xc2\x3b\x6e\x6a\xa1\x9a\x4e\xc0\xa2\x6d\x93\x1a\xb3\x86\x2e\x24\x33\xa8\x62\x71\x1d\x74\x68\x5d\x6e\x69\xc9\x90\x36\x13\x73\x2b\xd6\x91\xc1\x64\xcc\xdd\xe2\x66\x6c\x69\xc5\x3a\x01\x0c\xa6\xda\x9c\xcc\x61\x25\xea\xd7\xc3\x53\x55\x96\x66\xa6\x2a\xb8\xed\x2e\x22\xb4\x45\x96\x67\x2c\xba\xfa\x8b\x50\xd6\xfc\x8e\x18\x6b\xc5\x10\x1c\xe6\x18\x42\x2b\x8b\xcf\xba\xcf\xe4\xf4\xa9\x5b\x03\xa2\x3d\x18\xb7\x3b\xc7\xaf\xe6\x1a\x20\x50\xb6\xee\x00\x65\x93\x7c\x0d\xdf\xe8\x47\x12\x12\xaa\x70\x10\x05\x1d\xe7\xdf\xbc\xf9\x92\x10\x69\x8b\x08\x4b\x99\x67\x2f\x6e\x21\xba\xa6\x40\x07\x4c\xf8\x1c\x92\x55\x3d\x9e\xec\x43\x49\x98\x28\x62\x41\xa7\xef\xf7\x83\x40\x47\x12\xf2\x04\xa2\x5e\xc2\x74\x0c\x4b\xf1\x7d\xa4\x25\xb2\x45\x95\x34\x31\x92\xf1\x1d\xfb\xcf\x49\x04\x26\xc1\x28\x72\xe1\x72\xd7\xae\x16\xe2\xeb\xf4\xaa\xbf\xd8\x58\x4a\xc7\x51\xcd\xc5\xff\x61\x7d\xc9\x32\xfd\x9f\x49\x32\x73\x76\xff\x49\xe2\xd4\xf2\x4c\x38\x06\x58\xf1\xeb\x9f\xe7\x6b\x8d\x70\xdf\x57\x4a\xc4\xe5\xdc\x3d\xde\xed\xef\x16\xf7\x87\xbd\x4b\x35\x62\x93\x06\x8b\x26\xed\xa9\xd8\xce\x3d\x8f\xc6\x8c\x09\xda\x27\x57\x39\x49\x92\x20\x45\x80\xe2\xf3\xef\x37\xc3\x55\x98\x24\x21\x47\xb0\x92\x8d\x4d\x78\x5a\xa6\xc9\x0e\x9e\x24\x52\x61\x18\xee\x5f\xdb\xf1\xc5\xc6\x48\x37\x44\xea\xcd\x73\x14\xcc\x6c\xac\x49\x2a\xed\x11\xa8\x44\xb1\x6b\xca\xd3\xcf\xb2\x7a\xf3\xf7\x48\x4d\xc8\x7a\x63\xeb\x3e\xab\x47\xc5\xd2\x7f\x6b\x59\x24\x4c\x31\xe1\xa4\xb6\x97\xe7\xcb\x2d\xc0\xf2\x34\x7d\x03\x06\x21\x12\xb6\xc9\xf3\x65\x5a\x43\xe7\x7a\x70\xaa\x75\xe0\xb7\x11\x14\x04\x5d\x9e\xab\x59\x20\x29\x27\x89\x48\xad\x30\xe5\x76\x26\x2e\xf9\xc9\x15\x9c\x60\x68\xac\xc0\x08\xfa\xdd\xf1\x58\x56\x8d\xc8\xbb\x35\x23\x20\x41\x88\x8b\x01\xf5\xea\x90\x61\x18\xb7\xec\x55\xfe\x38\x49\x64\x1a\xe2\x7c\x3e\x58\xf5\x2a\x97\xdc\x74\x72\x86\x9f\x4c\x29\xc9\x08\x1e\x9f\x68\x97\xed\x9a\xb3\x86\xa2\x29\x1c\x2c\xb2\xfb\x75\xa9\x13\xc4\xec\xd4\xe7\x13\x54\x7f\x2f\x7e\x99\x48\x90\x08\x55\x47\xf8\xc6\x53\x55\xca\x1c\x8e\x93\x41\x57\x3c\x46\xec\xcd\xe2\x79\x7b\xf7\x87\xff\x2d\x1d\x85\x68\x54\x1c\x0a\xf8\xe8\x88\x01\x7c\x9b\x12\x58\x1b\xf9\x2a\xde\x61\x9d\xb5\x7b\xfd\xa2\x71\x30\xbe\xab\xca\xc7\xf9\xaf\x08\xd4\x52\xd3\xfe\x73\xb7\x79\x3c\x0c\xdc\x45\x4a\x08\x0f\x9c\x69\x6c\xe3\x14\x33\xf3\x94\x92\x48\x7a\xcd\xf4\x75\xad\xaa\xf2\xa3\x5e\x5e\xae\xe4\x10\xda\x7e\x31\x21\x36\x30\x57\x74\xf7\x07\xab\x5d\xf1\x7b\x59\x95\x05\xfc\xd7\x9f\x40\x34\x70\x35\x60\x1d\xb3\x63\x99\x23\x49\xf7\x98\xe5\xa5\xeb\x0c\x98\xf5\x36\xe7\x42\x6f\x8a\x49\xde\x8d\x06\x5a\x84\x58\xd0\xbf\x78\xfc\xbe\xd8\xef\x17\x8f\x4f\xdb\xcd\x1f\x7f\xae\x17\xbb\xfd\xfa\xf1\x66\xe1\x74\x81\x39\xa1\x61\x10\x23\x5b\x9a\xe5\xef\xfc\xe3\x69\x31\x3f\x25\x69\x98\x46\x98\x87\x10\xf5\xa5\x50\xb6\x1e\x04\xe6\x79\xb9\xdb\xce\x22\x8e\x1d\xd1\x78\x6b\x4e\x7c\x92\xad\x1d\x6f\xc0\x34\x02\x46\xc9\x90\x0a\xa3\xca\x86\xe9\xdb\xf1\x2f\xc4\x09\x43\xd3\xbc\x80\x8f\xef\x03\xee\x61\xdf\x4a\x65\x2c\xfc\xef\x37\xf0\x21\x26\x01\x30\x4a\xa3\x20\xb6\xbc\x2e\x2f\x2f\x39\xdc\x5b\xd5\xa4\x42\xc1\xc0\x54\xa7\x34\x56\xb8\xca\x44\x75\xbc\x2c\xb2\x4a\x55\xc2\x34\x8e\xf9\xb2\xbe\x62\x91\x68\xfb\x33\x2a\xba\xf8\x22\x6a\xf9\xe1\x30\x79\x64\xba\x37\x88\x28\x55\x56\x11\x5e\x68\xbd\x2d\x2f\x22\x6f\x2e\x9e\x0d\xf4\x93\x77\x4d\x29\xb7\x72\xa4\x8d\xc8\xf3\xac\x2c\x5a\xd3\x7d\x7e\x01\xd3\x54\x52\x4f\x0d\xb6\x76\x50\xf1\x71\x07\x46\x42\x8b\xb4\xc5\x83\x7a\xa4\x76\xd9\xb6\x52\xab\xdc\xdf\x21\xb3\xe6\x83\xd4\x54\x04\x81\x87\x29\x2c\xf2\x1c\x2d\xf1\xcd\xb9\x9b\x7a\x22\xa4\x08\xed\xaf\x4b\xd3\xf4\x09\x65\x2a\xa4\x2d\x2b\xb5\x39\x28\x3b\x85\x3a\x41\x46\xac\x1c\x8c\xf0\x74\x41\x7a\x45\x4b\x07\x7b\xf7\xf8\x6d\xbf\x5e\x3c\xf8\x1e\x4a\xa4\xa1\x67\x0c\xd8\x62\xc9\x90\x43\x57\x74\xf7\xd0\x49\xca\xdc\xc4\x6b\x9d\xd5\xb9\xda\x9a\xb6\x17\xe3\x1e\x36\xdf\x21\x6a\x77\x20\xba\x2d\x8e\x42\x00\xca\x15\x39\x62\xd9\x2e\x22\xad\x67\xf7\x10\x0a\x3c\x26\x6e\x22\x7a\xf8\xee\xe8\xc7\x52\x12\x5a\x9a\x8c\x17\xc0\xa8\xe1\x9d\x5e\x5e\xb6\xa2\x78\x1b\x7f\x97\x94\xc8\x80\x69\xc7\x91\xb9\xc8\xf3\x2d\xbc\x67\xad\xe5\x39\x50\xd1\xa9\xc7\xb9\xa5\x94\x00\xc3\x90\x10\x16\xd7\xfa\x17\xbd\x32\xbd\xd2\x20\x4e\x91\x52\xd2\x7b\xe4\x58\xa0\x60\x41\x1b\xae\x47\xa8\x13\x26\x86\x51\xa0\x73\x9e\xfb\x48\xd0\xac\xad\x32\xaf\x0e\x33\xd5\x8e\xf9\xbf\x0a\xdc\xa5\x51\x40\xd1\x2f\x6e\xdf\x7f\x2d\xaa\x22\x2b\x5e\xbe\xac\x01\xc6\x4b\x18\xda\x09\xc7\xcc\x8a\x2d\xdf\x96\xd5\xa3\xe7\xce\x9a\x8c\x6e\x14\x32\x0c\x74\xee\x6e\xf7\x4f\xdb\xf5\x6a\xe3\x77\xbf\x34\x4a\x52\x3c\x5f\x9e\xc7\xd8\xe6\xe5\x05\x97\xce\xf8\x43\xc6\xa1\xab\xc5\x2f\xb2\xa6\x86\x97\xce\xa7\xfc\x3a\x30\x91\x26\x51\x12\x0d\x0b\x6d\x1e\x44\x56\xf4\x61\x91\x34\x89\x79\xca\x3d\x11\x65\xfb\x1a\xee\xb8\xdd\x97\x8e\x36\xc0\xdb\xdd\xee\xbf\xfe\xb2\xd4\x2a\xa7\xef\x00\x76\xe5\xb9\x1a\x5a\x5a\x69\x22\x03\x14\x30\xba\x2f\x5f\x3a\x22\x2a\xe8\x78\x37\x27\x43\x93\x48\xc0\x0d\xe1\xd8\x36\xd7\xd9\xcb\x28\xbe\x96\x26\x26\x08\x9d\xb1\xe4\x86\xc6\x61\x41\x26\xa1\xc4\x94\x86\x02\x8b\x65\x30\xa3\xb0\x44\x71\x9c\xab\x13\x33\xa5\x51\x60\xac\x59\xda\x53\xf1\x4e\x46\x8b\x8a\x88\xb9\x10\xf3\x52\xa8\x37\xeb\x4a\xde\x1d\xb1\x4e\xee\xca\xba\x4f\xa9\x30\x1d\xc7\x9e\xd5\xcc\x12\xb1\x7f\x74\xaa\x02\xea\xc8\x7f\xbe\xae\x55\xe2\x24\x4d\x23\x82\xc4\x3e\xf2\x5c\x15\xbb\xd2\x51\xeb\xd6\xb7\x65\x35\xd1\xc3\x6a\xbb\x32\x21\x6d\xd1\x9d\xdf\xe0\xff\xdf\xdc\xb3\x34\xd5\x0a\xa3\x03\x35\xa2\xda\x57\xc8\xb2\x3d\xeb\x77\xa7\x2c\x89\x6d\xf6\x50\xeb\xa7\x0c\xd4\x84\x49\x62\x6a\xe3\xf8\x8b\x64\x82\x55\x0f\x2e\x0b\x8c\xd0\xc1\xfe\x70\x4b\x79\x4a\xb1\x2c\x28\xd3\x3d\xb4\x24\x15\x51\xaa\x12\xbf\x55\x15\x1a\x6b\xf6\x6f\x90\x7b\x74\x53\xac\xa7\xc5\x52\x9f\xa0\x57\x27\x8f\x21\x0c\xc5\x9d\xf4\x5c\x74\x7e\x5b\x2a\x49\x64\x0d\x22\x34\x39\xc6\xb4\x27\x7f\x99\x95\x4c\x65\x68\x73\xc1\x56\x13\xac\x79\x1d\x89\xee\xb4\xed\x89\x4d\x46\x39\x2f\x7e\x82\xbf\xf3\x9d\xc0\x0a\x71\x94\x9d\x3c\xef\xed\xb9\xd0\x63\xa7\x3d\x55\x09\x41\xa8\xa7\x40\x61\xfd\xf6\x3c\x19\x1d\x36\xa9\x36\x56\xc7\xea\x00\xad\x53\x3a\x9a\xcd\x9f\xd1\xbe\x8c\x0f\x8f\xd4\xd0\x14\xb1\x57\x27\x71\xae\x61\x79\xbe\x48\xaf\xca\xd6\xb6\xa5\xc2\xc1\xf8\x0a\x05\x39\x32\x7f\x18\x03\xd5\x88\x7c\xae\xbd\x61\xf7\x4d\x19\x89\x62\x3c\xd6\xb0\x90\x61\x32\x2b\xfc\x79\xc0\x88\x4a\x99\xa5\xa1\xff\x65\xcf\x15\x33\xa0\xbc\xe1\x84\x05\xc4\x92\x8b\xe2\x7e\xf0\x0e\x35\x16\x8d\x7e\xb9\x11\xb3\x40\x59\xd2\xd4\xa3\xa8\xde\xb0\x5c\x75\x28\xbd\xd4\x77\x0b\x13\x15\xba\x8a\x68\x4b\xef\xd4\xdb\x06\x2c\x64\xca\x91\x75\xfc\x6a\x9e\xaa\xf2\x98\xd5\xd0\x25\xde\xda\x46\xed\x29\x09\x71\xca\xd8\xcb\x9f\x8b\xd6\x66\xaa\x1d\xed\x83\xeb\x1b\x25\xf6\x50\x98\x94\x5d\xf7\x12\xe5\x6d\x1f\xca\xd0\x34\xbe\xf9\x63\xd5\xfd\x89\x01\xe9\x0a\x2c\x2d\xe0\x63\xba\xc5\xb1\x88\x73\xdc\xe2\xf6\xa0\x5e\x8b\x72\xd9\xcd\x67\x16\x13\x86\x71\x88\x4f\xe4\x39\xdb\x1e\x91\x0d\x5c\xa2\x0c\xe2\x22\xb7\xcc\xb3\xe0\xc4\x10\xbb\xdb\x44\x1a\x85\x1d\x8a\xf3\xf1\xce\xb3\x9c\x76\x6d\x26\xb0\x9a\xc9\x79\x59\xc3\x43\x39\x2d\x2d\xe0\x84\x25\x89\xc2\x54\xf8\x62\xb5\xff\x2a\x15\xc0\x12\x69\x75\xf6\x91\xed\xf3\x5a\x22\x65\xec\x29\xc5\xfe\x22\x60\x68\x9d\xbc\x64\xef\x80\xfb\x6c\xd5\xb3\xc2\x72\xc2\x68\xa8\x03\x39\xa8\x10\xba\x56\x68\x69\x3b\xb1\x14\x4f\xf8\x5d\x76\x2c\x73\xe8\x82\x6a\x8c\xf2\x2e\x8e\xfa\x20\xaa\x76\x00\x07\x5a\x70\x6d\xbb\x86\xc8\x4a\xee\x79\xab\xf4\x5a\xcc\xca\x75\x65\xcc\x46\x44\x51\x53\xcd\xb2\xaf\x75\xa3\xcb\x43\x7b\xf6\x28\x28\xbb\x3f\x25\xd0\x79\x79\x2e\xad\xfe\x09\x58\x77\x7e\xde\x73\xb0\xe4\xff\x4e\x88\x71\x90\xcd\x61\xdc\xd0\xa0\x67\x3f\xb4\x44\x9a\x93\xf1\x10\xd2\x72\x1f\x54\x65\x6e\x65\x74\x67\xed\x4b\x26\x99\x25\xba\xf4\x11\xe9\x4e\x50\x5c\xe4\xeb\x5f\x27\x28\xea\xce\x80\x66\x2a\x12\xb4\x0b\xa5\x3d\xd7\x50\x8d\xd3\x2b\x4c\x29\x95\xf4\x51\x85\x8d\xb1\xcc\x80\xeb\xa2\xa9\xb2\xfe\x26\x3a\xa0\xba\xed\x64\x21\xea\x28\x89\xea\x93\xf4\xd7\x41\x7f\xa6\x45\x6c\x79\x4d\xb2\x23\xec\x33\xa8\x82\xee\x36\x3a\x0e\x1c\x3f\x00\xee\xac\x79\xe3\x37\x5a\xdf\x03\x48\xcc\x2d\xa6\xa7\x6e\xca\x6a\x72\xcc\x32\x08\x75\x28\x5c\xdd\x61\x99\x15\x83\xad\x02\x42\x8b\xf6\x3c\x8a\x2c\xaf\x0f\x4d\x79\xd0\x90\x67\xef\xfd\x5b\x1a\xca\x70\x4f\x3d\x17\x15\xd4\xa7\xb2\xd0\xa0\x57\xdd\x42\xe2\x84\x50\xa3\x3c\x3d\x54\x05\xaa\xc1\x4d\x15\x21\x4a\x18\xea\xdd\xb6\x0f\x39\x7e\x16\x4e\x88\x36\x0e\x2c\x7f\x03\xb2\x99\x53\xe8\x68\x7b\x25\x11\x25\x63\xe2\xa9\x7a\xa6\xda\xb1\xed\xa9\x20\x68\x67\xfc\x6a\xf1\xb8\x5a\xdf\xa3\xe4\xc5\xe1\x66\xb1\xf7\x46\x29\x0f\x42\x8d\x9b\x51\x7b\x2a\x64\xc5\xcb\x03\xb4\x67\x78\x56\x1f\xef\x87\xbe\x1a\x0f\xa5\x2d\xe0\x7e\x2a\x9b\x8d\xb1\xa1\x6e\xd7\x12\x25\x16\xce\x82\x32\x5f\x97\x53\x23\xce\x95\xf3\x96\x6e\x27\xfc\xc3\x6d\x67\xe6\xc8\x17\x05\x4a\x31\x2d\x6a\x7f\xb0\x8c\x8f\x75\xdf\x5b\xda\x60\x3e\x0a\x5d\xfa\xc2\x3d\x36\x87\x16\xe4\x91\x49\x30\x44\xb6\x05\xdc\xa5\x97\x67\x5f\xf5\xe0\xda\x63\x6e\xfc\x0c\xb1\x0b\x7e\xd3\x81\x7f\x78\x2c\xc3\xd0\x89\xd0\x5c\xc7\x74\x26\x7e\xc6\x8c\x15\xc9\x63\x95\x22\xd9\xdb\x7b\xe9\xb0\x36\x7e\x39\xf1\xc4\xd1\xdb\x1e\xb3\xa2\x59\xff\x6a\x2a\x31\x3a\xd2\x79\x12\x13\x64\xf8\x5e\x6f\x57\x01\x4d\xfa\xbf\xc6\xac\x2f\xbf\xbd\x17\x85\x6e\x8f\xba\x2f\x31\x85\x3c\x49\x23\x1a\x75\x3b\xc0\x6d\x55\x1e\x6f\xcf\xcd\xb9\x82\xf5\xaf\x93\x28\xea\x76\x25\x3c\x88\xd3\xe4\x5b\x24\x32\xc4\x7c\xd0\xdd\x93\xea\xf7\x12\x9e\x68\x43\xad\xec\xae\xac\x44\x75\x09\xcd\xb9\xe8\x49\x77\x38\xe1\x69\x60\xb0\x0e\x00\x54\x05\xaa\x7c\x87\xea\x67\x25\x4e\x27\xa8\x7e\xcf\xe0\x63\xde\x81\xf3\x17\x86\x80\xd1\xd4\xfb\xf2\xc5\x97\x6b\xd9\x79\xf4\x99\x89\x37\x3c\x48\x78\x1a\xa7\xdc\x19\x8b\x22\xcf\xbb\x87\xe1\x1c\xa1\xd5\x77\xdb\xa5\xff\x13\xa3\xe1\x80\x67\x6c\x27\xf2\x61\xed\xf9\xfc\xe0\x31\x43\x1c\xe7\xe2\xc5\x89\xe5\x2f\x2f\x16\x05\xd3\xf6\xa3\xf1\x3f\xdc\x7f\xc6\xc3\xa7\x22\x8a\xaa\x8d\x1d\xe3\xd7\x97\x46\x58\xe7\x52\x8d\xff\xef\xd5\x28\x29\x6e\x94\xe8\x45\xf4\x9d\x0a\xed\xee\x43\x9c\xae\x92\x89\xee\x0a\x1d\x86\x58\x1e\x71\x14\xc5\xe5\xa0\x30\x27\x2c\x45\xf1\xd6\x4d\x32\x1d\x2a\xd4\xa8\x7e\x15\xf5\x20\xa3\xce\x75\x24\x95\xf5\x2c\xee\xf4\x84\x7e\x89\xc6\xbe\x0f\x65\x68\x9d\x9d\x2a\xe4\x68\x1a\xa6\x43\x38\xc4\xb6\x4e\x17\x2b\x59\x5e\xba\xbf\x32\x83\xeb\xdb\x26\x49\x2c\xef\xb4\x4b\x6c\xf8\x1e\x2a\x41\x1f\xef\xc7\x45\x42\xb5\xc8\xaa\x9b\xaa\x9c\x4e\x4c\x54\x27\xee\xd4\x38\xdd\xf9\x3c\x9a\x0d\x86\x06\x96\xf0\x2f\xcb\x3b\x26\x0f\x0f\x6b\x99\xe4\x3f\x3a\x48\xff\x27\xf3\x52\x10\x06\xe9\x28\xed\xfe\x5c\x38\x48\xc4\xb7\xb2\x1c\x3f\x99\x20\x22\x14\x96\xff\xc1\x96\x47\x6d\xcc\xbe\x2a\xcb\xd3\xa7\xb4\x1b\xee\xb2\x40\x5b\x2a\xb5\xfd\x6e\xbf\xde\x75\x10\x7d\x11\x12\x32\xa2\x1f\xf8\x6d\x02\x6c\x15\x61\x12\xe8\x9e\xde\xf2\x11\x3e\xf6\xa2\x78\xfb\x09\xe2\xd4\x2d\x47\x11\x26\x06\xcd\xdc\x9f\xb0\x74\xfb\x6f\xd9\x35\x41\x80\x74\x81\x1d\xd5\xbd\xdb\x96\x7d\x7b\xa4\x59\xea\x64\x84\xef\x45\xf1\x72\x16\x2f\x30\x1a\x65\x11\xeb\x10\xab\xde\x64\xf9\x8e\xbc\x55\x37\xbd\x18\x8a\xbf\x47\x12\x11\xe6\x11\x80\x36\x4c\xb9\xbc\x74\x36\xc3\x38\x84\x24\x12\x0e\x68\x2f\x2d\x45\x9d\x29\xe7\xdf\x77\xc2\x51\xcc\x77\x52\x29\x96\x2d\xdc\x43\x5d\x97\xc5\x21\x98\x77\xa1\x05\x0d\x29\x6a\x54\x2a\x51\x6c\xa1\x56\xe7\x49\xf4\x44\xd0\x84\xa0\xa5\xe0\x6a\xba\xd1\xb0\x98\x74\x49\x49\x10\xf9\x73\xaf\x83\x1b\xf8\xf7\x4a\x43\x61\xf9\xaa\x2d\xa3\xe4\x4a\x9c\x76\x30\x39\x58\x45\x1a\xc7\xc6\xda\x2e\x75\x3d\xb0\xc6\x44\x2a\x85\xfd\xac\x88\xcc\x19\x50\x38\xb9\x76\x96\x04\xc8\x29\x8b\x68\xbb\x25\x34\x5b\xcc\x97\x8f\x46\x81\xf1\x54\x21\xb0\x05\x35\xfb\x66\xe8\x81\x38\x11\x3c\x0d\x84\x83\x09\x3d\xdd\x59\xf9\xb2\x30\x1d\x7f\x40\xae\x14\xea\x28\x15\xe2\x98\xb9\x92\x45\xff\x10\x22\x0c\x2c\x10\x5f\x64\xf9\xa5\x27\xc5\x68\x5b\x58\x64\x35\xbd\xeb\x9e\x17\x61\xf6\x01\x64\x12\x23\x60\x57\x95\x85\xc9\x5e\xce\x15\x3c\x38\xaa\x04\x5c\x72\x93\xbe\xa9\xc6\x00\x80\x45\xab\x6e\xcf\x05\xea\x92\x8d\x93\x08\x42\x2a\x89\x24\x56\xfb\xaa\x2c\x2e\xd6\x9f\x52\x97\x69\x05\xc9\x64\x22\x28\xa7\x87\xa3\xa1\xf5\x9a\x27\xa9\x35\xa1\x02\xe6\xa3\x32\x0f\x59\xf1\x4d\xd4\x57\x45\x8d\x6d\xa7\xc8\x60\x78\xf9\xe0\xd9\xa5\xc6\xcc\x26\x93\x37\x51\x69\x82\x69\xea\x53\x55\x9a\xac\xa9\xad\x95\x84\x6a\xce\xfe\x35\x94\x4a\xe3\x61\x66\xc1\xc9\x6a\x7e\x5e\x2c\xca\x89\xd0\x11\x41\x34\xaf\x7f\x5b\xcc\xec\xd4\xaf\xd9\xc9\x4f\xcc\x6a\xea\xe5\x09\xad\x15\x17\x43\x08\xd2\xc3\xc5\xe6\xdc\x1f\xc4\xaf\x49\x57\x08\x62\xcc\x3f\xd4\x1f\xe2\x74\x10\xb2\x9f\x05\x40\x23\x84\x55\xd9\x98\xc3\xa2\x3b\x58\x05\x50\x86\xf6\xc4\xcb\xa5\x2b\x01\x10\x26\xb0\xda\x90\x22\xcf\x97\xe5\x2f\x1f\x26\xf6\x8d\xca\xf2\xdd\x08\xad\x91\x9e\xf1\x7a\x4b\xbc\xaa\xad\xb2\x57\x4a\x42\x13\x84\xd0\xe6\xc2\x51\xf0\xff\xe6\x1b\x98\xcd\xb8\x21\x1d\x68\xa1\x07\x5c\xa1\x6d\x23\x58\x12\x2e\xed\xe8\xf5\x3b\x9e\x1a\x4e\x64\x90\x1a\x6e\xc5\x9b\x5a\x93\xdb\x05\x97\xf7\xaf\x15\xd4\xaf\x65\xee\x97\xa1\x0c\x43\x4d\x1c\x75\xeb\xe1\xe4\x89\x71\xfe\x62\x27\x97\x61\x12\x22\xf3\xca\xb7\xb2\x7c\xc9\x01\x69\x4f\x66\x02\x3e\x32\xa4\x04\xed\x92\x47\x71\x04\x9f\x87\x9d\xe1\x70\x9b\x8b\xbf\xc9\x50\x40\xdc\x8b\x05\xda\xca\xbf\x11\x4e\x72\xb4\xab\xca\x50\x01\xa2\x6e\x8e\xef\xc5\x09\x2a\xe8\x40\x99\x32\x22\x61\x62\x8b\x51\x0f\xa6\x93\xd0\xf7\x6d\x01\x47\x6a\xfa\xdd\xf7\xc5\x76\xfd\xb4\xde\xde\x6d\x6e\xba\x26\xce\x10\xe6\xb7\xb3\x34\x37\xdf\x7e\xee\xc7\xcb\x45\x46\x9a\x5b\x6a\x63\x04\x1f\x8c\x2c\x24\xd7\x23\x56\x16\x41\xd1\x5a\xbd\x0b\xcb\x5b\x3f\xb2\x7b\xdb\x0e\x98\x93\x2a\xce\xc7\x41\x76\xba\x6b\x4e\x12\x1a\x58\xf5\x95\x1a\xaa\xc9\xae\x2b\x13\xa0\x0e\x95\x85\xfb\x99\x95\x80\xeb\xdf\x8c\x86\x09\x86\x2e\xea\xa6\x54\x6f\x3d\x81\xed\xd7\x5f\x95\xa6\x81\xcf\xe3\xb4\xd6\x4a\x96\xc3\x0b\x58\xd5\x96\xc1\x3c\xa5\x32\xb4\x42\xe2\x65\x71\xee\xdd\x60\x49\x4d\x8a\x5c\xea\x5b\x51\xbf\x66\x7a\x18\x1b\x94\xa9\xd6\x88\xab\x69\x48\x78\x18\xa3\x9e\x1e\x84\x9a\xb7\xe6\x64\xaa\x8d\x95\x25\xd3\xba\xdd\x7e\x97\x97\xa7\xd7\xb2\x98\x61\xf3\xe5\x44\x72\x26\x82\xc0\xc5\xf2\xf1\xfc\x99\xdd\x5a\x24\x97\x80\xd9\xc9\x2d\x86\x56\xb1\x24\xe8\x3a\x6f\x24\xb9\xb2\x05\xaa\x9e\xe2\x63\x3a\xae\x82\x00\x55\x9d\xff\xb4\x31\x4b\x68\xda\xe5\x72\x5b\x56\x0f\x48\x69\xe9\xd2\x09\xf3\xbb\xb4\x14\x51\xac\x54\xc7\x94\x8e\xab\x7c\x1c\xfd\x94\x42\x08\x3c\x75\x2c\xe7\x56\x59\xe6\xeb\x69\x5a\x45\xca\xc4\x0a\xd4\xac\x9b\xd7\xf0\x79\x77\x33\x6d\xa5\x01\xb2\xe5\x8c\xea\xe0\x66\xd8\x27\xda\xae\x8c\xa4\x2e\x47\xf6\x7b\x99\x9f\x8f\xe0\x35\x3a\xea\xe1\x41\x28\x55\x40\x71\x63\x92\xe7\xca\x7a\x02\x8e\x4d\x90\x13\xa9\x23\x82\x02\x40\x07\x9b\x0e\x7b\x15\xd5\x71\x74\xf2\x4a\x2d\xad\x76\x97\x2a\xeb\x66\x63\xf6\xbf\x1c\xb3\x94\x6f\x85\x24\x48\x7b\x26\xc6\xf9\xf8\x92\x04\x22\x71\xa6\x5b\x01\xd3\x21\x40\xb3\x33\xff\x24\x00\x15\xa2\x13\xa5\x2d\x6a\x53\x56\xb6\xe4\xe3\xcb\x2c\x91\x34\xc4\xfa\xec\x36\x5c\x7f\x9c\x18\xe0\xd2\x44\x31\xb3\xb5\xa3\x4e\xb6\xfb\xc1\x93\x19\xf9\xdf\x35\xb1\xcd\x69\xda\xc4\xae\x03\xd1\xeb\x7d\x89\xe4\x5d\x93\x12\x36\x69\x28\xc7\x98\x5a\x5e\xbe\x94\x9e\x6b\xbd\xfd\x33\x4b\x45\xe4\xb5\x5f\xdb\xd1\xfb\x02\xa3\xa2\x82\x90\xb1\x71\xf9\xd6\x6d\x30\x7e\x6a\x15\x46\x14\x03\x4e\x07\xa1\xf5\x4f\xc8\xae\xf9\xc9\xda\x3e\x34\xc5\xaa\x1c\xfc\xdc\x5b\x50\xe5\xf1\x08\x85\xbe\x46\xa3\xaa\x28\x0c\xd1\xdf\x94\x18\x45\xd8\xf5\xc1\x51\x15\x89\x08\xfd\x05\x57\x32\x60\x8b\x5e\xba\x46\x13\x31\xe3\x09\x54\x3a\xe0\xf1\x68\x6e\xa8\x98\xa4\x58\x48\xa2\xcb\xa2\x6c\xee\xaa\xb2\xb8\x11\xa7\xd3\x70\xe3\x50\x71\xc2\x71\x64\xf2\x02\x5d\x2e\xd0\x73\x88\x76\x15\x53\x8e\xbb\x56\x67\x00\x1c\x74\x66\x4c\xa6\xce\x79\x73\x39\x88\xa6\x81\xe3\xe9\x53\x8e\x0b\x7f\x0b\x65\xcb\x9e\x5e\xda\x4f\xe0\xc8\xec\x7f\x66\x85\x1e\x93\x3f\x72\xa2\x28\x61\x58\x10\xd4\xda\x48\x8f\x9f\x41\x36\x15\x95\x16\x5d\xe7\xa5\xce\x06\x87\xb2\xa2\x3a\xc0\x4c\x96\x3b\x57\xc6\x78\x69\xd7\x27\xe5\xc2\x6d\xde\xa2\x6a\x16\xa8\x84\x9a\x15\x2f\x58\x2f\xdd\x33\xc1\x71\xa2\x98\xb0\x88\x31\x64\x1f\xc4\x32\xec\x11\x71\x5b\xd7\x4b\x62\x55\xc2\xca\xd1\x98\xf5\xb2\x06\xb3\xab\xa3\x57\xe3\xfb\xe2\x3f\xee\xd6\x9c\x25\xe8\xca\xc8\xf3\x65\x05\x95\x23\xe0\x99\xd8\x95\x8a\x33\x5b\x44\xe5\x48\xd8\xb6\xa2\x78\x5b\x96\x7d\x1c\x5b\x71\x4d\x0d\x43\x7f\xa8\x78\x83\x6a\xfd\x2b\x1b\xf9\x00\x4a\x84\x04\x0b\x2d\xb2\x22\x6b\x0e\x1f\x23\xf5\x98\x6b\x49\x92\xee\x9a\xd4\x74\x91\xa8\x61\x52\xcb\xb7\x47\x4c\x73\xbf\x8a\xac\xa0\xcc\xec\x87\x10\x5c\x4b\x17\x25\xff\xd6\x1e\xf3\xcb\xcb\xbf\xce\x22\xcb\x9b\x8b\xc3\xf5\xf9\x6e\x22\x94\x71\x4f\x89\xf7\x5f\x40\x3b\xf8\x66\xa0\x1f\xd8\x76\xd2\x09\xea\x6d\x9c\x1c\x5b\xd5\xb6\x0f\x06\x28\x49\x62\x70\xe3\x38\x27\xf4\xd0\xfd\x90\x8c\x59\xd2\x53\x22\xcf\x5b\xd2\x93\xa1\x90\xca\x46\x22\x50\xfe\x4a\x96\x85\x50\x6a\x52\x71\xaf\xa4\x11\xe8\x88\x09\x59\x56\x13\xef\x50\x29\x2d\x90\xd0\xcf\x63\xa3\x16\x55\x25\x2e\xed\xb1\xe7\x09\x0d\xb3\x4e\x04\xf7\x53\xf5\x31\x4e\x94\x26\x9a\xd0\x01\xda\xc1\x11\x9c\x78\x76\xc7\x91\x0d\xe0\x2f\x49\x2c\x30\xe9\x77\x78\xcd\x54\x0e\xdb\xfd\x66\xf2\x68\x9a\x06\xa9\x17\xd4\x46\x0e\xfa\xdd\xdb\xb4\x60\x4b\x69\x46\x10\x21\x9a\x67\x0a\x8a\x1a\xf6\x50\x1d\x6b\x54\xf8\xaf\x9b\x27\xa8\x76\xf0\x89\xf9\xa1\xb4\x56\x3e\x27\xbb\x3e\x65\x75\xa9\x5d\x46\x76\x32\x72\xc0\x2d\x71\x22\x52\xd3\xc2\x9d\x2a\x3b\xce\xe9\xae\xb6\x76\x78\x94\x2a\x13\x19\x2c\x33\x5d\xfc\x58\xdc\xdd\xed\x37\xdd\x9f\x13\x86\x29\x91\x76\xba\xfe\xd9\x1d\x8f\xca\xa4\x21\x26\x05\xda\xcd\x66\x55\x1e\x8f\x25\x72\xb4\x6f\x45\xeb\x8a\x8e\xe2\xab\xca\xa4\x14\x8b\xa3\xe5\xb9\xd0\x39\x6c\xcc\x0c\x20\x4e\x99\x54\xe0\x24\x85\x5f\x59\xdd\xd4\x78\xde\x8e\x5f\xc6\x28\x48\x1c\x7c\xeb\x05\x9a\x97\xb2\x9c\xd6\x12\xea\x80\xca\x88\xf4\x2b\xf9\x26\xab\x4f\xe7\x06\x96\xe7\xcb\xe0\xec\x1e\x6e\xf1\x3a\xe0\x21\x96\x24\x1d\x6c\x3c\x76\xd6\x7f\xd6\x81\xb2\x8e\xcf\xee\x7c\x3c\xce\x04\x29\x7b\xc8\xf0\xe8\x5f\x67\xaf\xc8\xe5\xee\x12\x86\x00\x8e\xb1\xe4\x4e\x95\xed\x47\xb6\x61\xba\xd9\x55\xa1\xc3\x98\x28\x17\xb5\x3b\xe8\x19\x6d\x5d\xdf\x8d\x11\x2f\x3d\xba\x14\xf5\x1b\x34\xed\xf4\x2f\xae\xac\x46\x1d\x2a\x4b\x9b\xdb\xe7\x3f\x91\x1f\x3f\x7b\x41\xd6\x72\xcb\x14\xed\xbb\x9a\x14\x4b\x32\x5a\x47\x13\xb4\x5b\x07\x8b\x42\xaf\x44\x9e\x5b\x81\xf2\xbf\x48\x83\x8d\x43\xef\x93\xbf\x8e\x1f\x2b\x4a\x89\xec\xa2\x43\x18\x6a\x9e\x3c\x77\xcc\x25\xd7\x9d\x36\xda\x58\x9a\xcb\x77\x91\x0a\xa1\x04\x59\x81\xc5\x10\xdd\x5f\x35\x42\x0d\x3f\xa0\x19\x84\x7c\x74\xc2\xac\x92\x6e\xf3\x52\xb9\x71\x78\x12\x55\x33\xa0\xa7\xf0\x1d\x69\x10\xf2\x0e\xb9\xfd\x09\x9e\x51\xd3\x08\x12\xdd\xfb\x00\x5e\xa5\xdd\xb7\x32\xe9\x03\xaf\xed\xd8\xed\x2f\xa7\x29\x26\x5a\x53\x19\xa3\x7b\xf7\x76\x51\xfe\x87\x53\x16\xa1\x54\xcf\x72\xbd\xbe\xfd\xe7\x7a\xfb\xe3\xcf\xc9\xeb\xb2\xc8\x5a\x84\xbb\xa7\x0e\x00\xa7\x99\x88\x11\x22\x27\x85\x7e\x81\xd1\x33\x88\x54\x45\x56\xf4\xec\x1b\x14\xf0\x90\xfd\xea\x2c\x20\x2d\x84\xf1\x84\x3c\x0f\x59\x91\x1d\x45\x3e\xae\xdd\xd0\x32\x14\x36\x33\x7b\xe5\x9c\xfd\x5f\x21\x5a\xb4\xa4\x61\x64\x86\x3b\x34\x4e\x29\x91\xbb\x39\x75\x75\x3c\x0c\x9f\x5f\xa6\xcc\x26\xb8\x3d\xaa\xbc\xd3\x0d\x6d\x1b\x5d\xd1\x13\x1a\x45\xb8\x4f\x2f\x27\x12\xf7\xae\xa3\x22\x14\x8d\xc9\x6f\x9e\x0a\x63\xb4\xe9\x69\x25\x2d\x26\xd6\x3d\xc8\x13\x94\xa7\x2e\xf2\xa2\x35\x09\xd1\x07\x71\xf4\xa2\xb7\x55\x79\xfc\x4b\x64\x79\xef\x8c\x6a\x1d\x46\x68\x9e\xe6\x59\xdd\x3c\x55\x17\xd5\x94\xb4\xbb\x33\xd7\xe8\x5c\x9c\x00\x91\x16\x3f\xb3\xe6\xf5\xa6\x67\x97\xe3\x44\x43\x1c\xe3\xb5\x3a\x7b\x87\x64\x32\x0d\x80\x85\x91\x4d\x3e\x1e\xb3\xe2\xa1\xd4\xdd\xf3\x02\x07\xb4\x1c\x2c\x5c\x12\xf9\xaf\x57\x5d\x05\x80\x36\x71\xec\x09\xbe\x6e\x4a\x75\xc6\x70\xc5\xac\x7e\xc5\xe7\x6a\x4e\xed\x5d\x24\xc1\x23\xfb\x54\xb9\x3a\xa4\x61\xc4\x12\x02\x62\xa9\x85\x5b\x77\x0c\xb3\x33\xfe\x83\xf7\x1d\xc2\x84\xf8\x44\x24\x0c\x30\xb0\x10\x68\xc0\x9c\x96\x43\x21\xdc\x5a\x1e\x1e\xbf\x35\x41\x18\x50\xe2\x0e\x00\x54\x49\xd4\xa2\x99\x2e\x29\x08\x25\xb7\xca\x79\xa4\x3e\x81\xca\xfa\x5f\x0d\x75\xe7\xda\x56\x50\xbf\xde\x97\xea\xed\xf9\xe4\x88\x01\x5c\x97\x28\x02\xde\xb1\x6d\xdf\xdc\xec\x4d\x69\x71\x35\x3d\x04\x1c\x22\x15\x7a\x19\x44\x67\xcb\x7a\x4b\x22\x08\x99\xdb\xea\x21\x4e\x39\x5a\xeb\x50\xa9\x80\x26\x78\x0b\x23\x14\x5c\xd5\xdb\x8e\xd0\x14\x10\x8b\x20\x22\x9e\x7c\xf3\xa6\x2c\x46\x79\x71\x48\x88\x14\x43\x96\xba\x45\xde\xf8\x80\xf5\xe4\x68\x9b\x8d\x56\xb5\x8e\x2c\x12\xcb\xb4\xbe\xdd\x9f\xdd\x4d\x53\x5b\x31\x20\xac\x8b\xb4\x2e\x74\x3d\x72\x81\x20\x49\x95\xe8\x42\xc7\xd5\xd1\x57\x05\x2e\x0a\xed\xe3\x9d\x96\x72\xf6\xdc\x57\x91\x78\x5b\x10\x68\xac\x83\xc8\xe6\xb3\x5c\x76\xcc\xff\x6c\x1a\x06\x78\xc4\x20\x6c\x65\x24\x5c\xe4\x3b\xd0\x40\x59\xc1\x36\xcc\x5c\x7a\x47\xb2\x2a\x8f\xbb\xec\xa5\x40\x4d\xb0\x61\x40\xeb\x53\x64\x95\xbf\x5d\x4a\x51\xa3\xf0\x28\xde\xe0\x3e\xeb\x12\x2b\x90\x0a\x9b\x4f\x54\xa5\x86\x5f\x88\x0e\x99\x44\xba\x81\x85\xd4\xba\xcf\x19\x54\x9d\x18\xcc\x78\x60\x59\x14\xa0\x8c\x70\xbb\x3b\x58\x9a\x9b\xdd\x5b\x96\xe7\xf5\xdf\xdd\x2d\xa7\x45\xdd\xc0\x40\xeb\x76\x8a\xfd\x33\x2b\x94\x0b\xc8\x3d\xd9\xbc\xde\xa7\x14\x79\x7f\x73\x43\x9e\x4c\x09\x66\xd2\xc4\x66\x90\xdf\x01\x33\xbc\xbb\x76\x7a\x4e\xea\x29\x80\x73\x89\xe1\x34\x2b\x79\xb9\x45\xeb\xb1\x1b\x41\x41\x8c\xb4\x75\xa9\x3b\x34\x17\x96\x97\xf5\xf9\x05\xba\x8c\x3d\x48\x4e\x51\x42\xf1\x69\xbb\x79\x58\xef\xbf\xaf\x9f\x77\x07\x4b\x47\x7c\xf7\xb8\xda\xae\x1f\xd6\x8f\xfb\xae\x27\xe8\x38\x1a\xe5\xfd\xcd\xaa\x3c\x57\x7d\x00\x0f\x14\x09\x99\x23\x4a\x7c\x2a\x3b\xb0\xd4\x38\x77\x05\x2a\x49\x91\x78\xd4\xd9\x2d\xf3\x07\x37\x68\x2a\x11\xba\x81\xfe\xab\x2f\x79\xf5\xbf\x03\x21\x20\x7e\xe7\x76\xb5\x7a\xca\x85\x02\x7b\x64\x7c\x5d\xa5\x00\x10\x47\x91\x83\x2d\xa0\x20\x06\x86\xce\x6e\x7a\x0f\x0a\x40\x13\x65\x91\xb9\xcd\xca\x07\x4b\xa7\x56\x3d\x80\x06\x24\xaa\x59\x6d\x1e\x1e\x86\x4c\x03\x60\x08\x13\xee\xf6\xed\xa3\x36\xd7\xa1\x6c\x43\x98\xc4\xa1\xf6\x25\x8c\x13\x56\x07\x43\x38\x93\xb2\x33\xa5\xf6\xe2\x6d\xe2\x06\x1b\x22\x2c\x99\xc7\x12\x54\x79\x84\xbd\xd0\xa7\x32\x87\xa7\x2a\xeb\xe9\x46\x0c\xd1\x12\xcb\xe6\x56\xdb\xdd\x00\x3c\xeb\x1b\x4d\x8c\x83\x3a\x00\x95\x8c\x62\x51\x86\x18\x40\xe1\xb9\x06\xea\x26\xf4\x2b\x0d\x55\x30\x5d\x87\x40\x73\x9c\x6a\x77\xbf\xfe\xff\xb4\xfd\x49\x73\xe3\x38\xb6\x3f\x0c\x7f\x9d\x5a\xf4\x82\x18\x38\x2d\x65\x59\xce\x54\xa7\x6d\xb9\x2c\x39\xb3\xaa\x3b\x3a\x14\x18\x0e\x6c\x96\x29\x52\x4d\x52\x76\xba\x3f\xfd\x1b\x3c\x00\x38\x89\x72\xd6\xff\xbe\xf1\xdc\x45\x57\x5e\x13\xa2\x28\x12\x04\xce\xf0\x1b\x00\x19\x0d\xfe\xef\x34\x04\x2f\x58\x36\x74\xe7\xf5\x47\x55\x82\x02\x1e\xaa\x2c\xde\xa0\x6a\x76\xe5\x40\xb2\x6d\x14\xed\x1b\xaa\x2d\x73\xf1\x19\x9a\x8d\xfc\x6b\x99\x8b\xba\x76\x92\x35\xbe\x24\x6e\x98\xb4\xb5\xc4\xcc\x82\xf6\x90\xaf\xd1\x26\xc3\xdd\xe2\x65\x98\x06\xe9\x2d\x4e\x40\x1c\x2c\x57\xc2\xfe\x50\xe7\x43\x38\xbe\xad\x5c\x31\x6c\x92\x77\xda\xf5\x22\x9f\x0d\x64\x0d\xd7\xd4\x74\x6e\x06\x77\xe2\xe7\x52\x1c\xc7\x7a\x41\x26\x0c\x94\xaf\x0a\x60\xdc\x3e\xc9\x67\xbb\x25\xc4\x84\x54\x60\x62\x76\xbb\xd9\xed\xba\x0f\xf3\x54\x0a\x8f\x03\x50\xaf\x18\x01\xdd\x94\xd5\x6c\xca\x63\xc2\x90\x20\x53\xb0\x34\x06\xaa\xab\x46\xb5\x4b\xef\xe2\x78\x9c\x7f\x9d\x4c\xa8\xa8\xea\xc2\x78\xf3\x39\x88\xc3\x84\x26\xc5\x90\xfe\xfa\xeb\xd3\xd5\x80\x5c\x65\x22\x49\xfd\x43\xf6\x49\xea\xd5\xc7\xd8\xbb\x6b\x7c\x8d\x09\x89\x03\xab\x3c\x57\x8f\x14\x5d\x4c\xa2\x08\x02\xa3\x5f\x3e\x32\x0f\x0f\x33\x82\xc4\x38\xfb\x55\x59\xd4\x68\x4d\xdb\x85\xfa\x46\x30\x16\x5b\x69\xa5\xb2\xb2\x30\xc6\x76\x45\xb8\x81\x36\xe9\x79\x04\x95\x1d\x11\xa5\x67\xd3\x97\x99\xf2\x9e\x11\x71\x6c\xcb\x99\x5d\x7d\x6f\x5d\x98\x1c\x5f\x8d\x91\x05\xcf\xfc\x2a\x6c\x44\x92\x22\xdd\xfa\x0b\xa6\x70\xf0\x49\x75\xde\x08\xc1\xa0\x7b\xfe\x99\x1a\x55\x8e\xdc\x56\x98\xf8\xa1\x32\xc6\xe5\xe6\xaf\x53\xdd\x84\x01\x72\xb2\xfc\x11\x4d\xa0\xc7\x20\xee\x4d\x55\x1e\xf6\xef\x53\x62\x8f\x1f\x0b\x56\xc1\xed\xba\xcc\x45\xb5\x2b\x75\xa7\xe8\x60\xa4\xb1\x7a\xa1\x4d\x75\xaa\xad\xc8\xa1\x2d\x47\xfe\x3d\xe2\x9f\x51\x54\xe0\x62\xe5\x8a\x7d\x5f\x04\x36\x99\x4d\xe6\xf1\x29\x46\xb5\x53\xd0\xbd\x65\x8f\xeb\x4d\xf7\xb2\x6b\xce\x02\x9b\xe1\x63\x25\x1b\x9b\x3f\xbc\x3b\x18\x32\x9c\xb5\x46\x54\x87\x5d\xe6\xf6\x4b\x0f\x43\x1b\xdc\x1c\x1d\x72\x6c\x58\xca\xf6\x61\xdb\xfe\x91\x3f\x12\xc5\x1d\x0e\xd0\x66\x43\xee\xfd\x40\x7e\x43\xf7\xeb\xb5\x61\xa8\x72\xbe\x7f\x2b\x4f\xea\x05\xaa\x7a\xb4\xe8\xb8\x41\x10\x46\x41\x57\x24\xb5\x7e\x72\xb3\xcf\x95\x04\x41\x14\x63\xb2\x9a\xd5\x23\x4d\x9f\xd1\x7c\x27\x01\xe1\x06\x03\xd8\xbd\x45\x4c\x9d\x93\xb1\xfa\xe7\x4f\x02\x2a\x15\xea\x39\xec\x70\x05\x19\xc7\x57\x24\x60\x81\xc2\xd4\xb4\xfd\xfd\x23\x1d\x49\x12\x30\x46\xb1\xa7\x67\x25\x65\x30\x8b\xd8\xee\x17\xdf\x17\xeb\xdb\xc5\xd5\xed\xaa\x1b\x95\x2a\x84\xbe\xd9\x4b\x71\x9c\xb2\x8e\x7c\x3f\xff\x2b\x99\x32\xf8\xa5\xbb\x17\x28\x8f\x2f\xa2\x80\x7a\xf0\xd6\x92\x80\x01\xc3\xd8\xdf\x9a\xaa\xf6\x04\x65\x77\x98\xcb\xc8\x70\xbf\x07\x20\xd6\xc3\x79\xc3\x01\x74\x36\xff\xed\x30\xc5\x10\x61\x9b\x39\x3c\xfc\x95\xef\x09\x25\xb3\x33\x91\x04\x5c\x4b\x4d\x7b\x4b\x3f\x87\x01\xf8\x0c\xc4\x47\x82\x90\x00\x16\x0b\x8f\x65\x99\x8f\xa3\x07\x12\x84\x3c\xc4\xb6\xac\xcd\xbf\x1e\x1e\x57\x6d\x0a\xd6\x1d\x8c\x8d\x75\x8a\xe8\x6c\x55\x97\x0f\xf7\xfe\x60\x14\x10\xbc\x01\x88\x06\x77\xd6\x46\xe3\x44\x61\x14\x2d\x90\x20\xd2\xb1\x14\x9d\x72\x59\xd7\x31\x27\x41\x92\x58\x83\xfd\x76\x9d\x38\xc9\x3c\xab\x5f\xa0\x5a\x9e\xe6\xb5\x67\x48\x90\x32\xe9\x99\xcf\x4f\x59\xd1\xdc\x90\x1b\x7a\xe1\x09\x2a\xa9\x91\xca\xd8\xab\xea\xcc\x9b\xcc\xa6\x24\xd0\x21\x05\xe1\xcd\x6c\x8e\x68\xe0\xea\xaf\x0e\xa4\xc0\x19\x26\x4f\x1f\x57\xe5\xc0\x67\xcd\x1d\x36\xcc\x5a\x27\xcb\x0c\xdd\x4c\x6c\x60\xaa\xaa\x72\x26\xa4\xf6\x9f\x08\xad\x56\xb0\x65\x10\x62\xf8\xd5\x37\x34\x08\x09\xb8\xf5\x3c\xb3\x1d\xa2\x21\x70\xc4\x0f\x08\x13\xed\x7a\x41\x77\x88\x12\x99\x78\x6a\xa5\x84\xd0\xd0\x20\x58\xb1\x79\xc9\x2a\xfd\x03\xe0\x75\x50\x32\x23\x84\xc6\x0a\x91\xbb\x7b\x95\x83\xa8\xba\x74\x77\xf6\x76\x13\x16\x69\xe6\xfa\xf6\x4d\x0e\x43\x3a\x9d\xaf\x1a\x10\xc2\x03\x8a\x51\xec\x01\x7b\x56\x56\xc3\xce\x7f\x19\x0f\x43\x2c\x48\x58\x32\xc2\x5c\xe3\x94\x10\x1e\x31\x4d\xdd\x04\xd8\x6c\x6e\xe7\x40\x47\x84\xf0\x38\xc4\xf5\x24\x2b\xd4\x7d\xd9\x05\x79\xed\xdf\xb5\xb1\xc8\x46\xdc\x11\xc7\x29\x11\x21\x3c\x05\xec\x66\x55\x50\x83\x85\x49\x67\xc5\xf3\x30\x8f\x26\x24\xa4\x0a\xab\x8d\x4e\x6e\x70\x88\x29\x20\x24\x0c\x03\xff\x22\xdb\xde\x34\x9e\x63\x72\xbf\x43\x21\xfd\x20\xdf\xa5\x98\x7d\xf6\x24\x54\xc2\xa7\x0d\x0f\xe2\x03\x2a\xf7\xde\xf8\xa3\x90\x22\xe8\x1b\x21\xbd\xca\xba\x5f\xdd\x82\x69\x36\x67\x86\xd9\xee\x03\x11\xe7\xc6\xe1\xcb\xd7\xca\x59\x07\x0d\x8b\x45\x84\x44\x00\x88\x46\x69\x83\xd8\xaf\xa2\x5e\x96\x15\x62\x57\x1c\xd3\x70\x3b\x88\x4c\x09\x89\xb9\x35\xc5\x14\x5a\xaf\x10\xfa\xad\x60\x8a\x12\x1f\xbf\xd2\x24\xe6\x76\x61\x46\x7e\x5b\x71\x3a\x74\x67\x72\x52\xa4\x0e\x4c\xf1\x54\xe4\xb6\xdf\x38\x71\x83\x6d\x47\xc6\x1a\x2b\x3c\x23\x7b\x57\xac\x5a\xf5\xf9\xe6\xec\x2b\x4b\x62\x65\xbd\x5b\x3b\x7c\xe5\x23\x08\x8d\x20\xa4\xc9\x38\x60\xc8\x5c\x05\x4c\xea\x27\x6a\x27\x84\x24\x9c\x84\x4e\xb9\x75\x83\x4d\xd5\x21\x8b\x61\x68\xd7\x3f\xf8\x27\xfd\xcf\x70\xf6\x27\x61\xec\xeb\xfc\x1d\x1d\xf8\xd3\x78\x82\x90\x94\x0b\x61\xa1\x7c\x3f\x9d\xc3\xe8\x58\x89\x86\x90\x14\x42\x6b\xfc\x84\xbc\xba\x01\x9a\xa5\x5d\xc0\xbb\xaa\xc2\x79\xb3\xea\xbc\x98\x9d\x9c\x29\x9b\x12\x22\x78\x80\x20\xdd\xc5\xe3\xc3\x70\x53\x23\x22\x8c\x64\x57\x51\xb2\x74\xfd\xf6\xfb\xfe\x05\x55\x39\x4a\xcf\x08\x11\xb1\x35\x1d\xb2\xdb\xdf\x00\xc1\x4b\x88\x48\x9d\x2a\x55\x05\xd6\x94\x00\xb5\x78\xfc\x41\xad\x2c\x1e\x44\x9c\x1b\x07\xf4\x35\x10\x42\x64\x68\x2c\xb4\xec\x24\x67\xb0\x40\x84\x28\x50\xd4\x5b\xbf\x74\xd2\x06\xeb\x19\x17\xcc\xf1\xd3\xd6\x81\x75\xa7\x39\x64\x85\xd3\xd7\xf6\x17\xa6\x63\x0b\x54\xb9\xfe\x71\xb5\x1b\x8b\x8e\x7f\x16\x0f\x13\xa2\x13\xae\x7a\x99\x40\xab\xa1\xd4\x01\x00\xe6\x77\x1b\x02\x92\xa2\x77\x8b\xb0\x59\xbf\xa3\x8a\x4d\x26\x26\x18\x8a\xd1\x73\x9b\x71\x8e\xf5\xdc\x2e\x4c\x2a\x30\x21\xc2\x1c\x8f\x9d\xf9\xea\x30\x22\x21\x66\xe8\xbe\xe7\xa4\x0f\xf2\x7c\xbc\xb5\x18\x43\x51\xf3\xd0\xbb\x13\x3c\x8a\x06\x6c\xdd\xf2\xcc\x62\xa3\xfb\x84\x95\x8f\xc8\x45\xdd\x58\x98\xe0\x64\x83\xa4\x84\x27\xd8\xb3\x3a\xd5\xba\x1a\x48\xe3\x11\x4a\xa9\x75\xef\xc1\xea\xc0\xb2\xf4\xa9\x15\xa1\x54\x28\xac\x28\x7d\x7b\xfa\x73\x39\x9c\x9e\x94\x05\x89\x56\x23\x2c\xce\x18\x12\x42\x28\x0f\x0c\xe7\xbe\xc6\x6e\xa0\x82\xc9\x5d\xa5\xdc\x10\x65\xbc\xdb\xbe\x46\x27\x90\x17\xff\xe1\x90\x86\xb8\x8a\xff\xc8\x34\xac\x0a\xa8\x9e\x3f\xba\x23\x11\x20\x44\xc8\x12\xc3\xee\x4e\x75\xb3\xf4\xc9\xd3\x78\x27\xa0\x21\x28\xdc\x0a\xed\xee\x8d\xf2\xa9\xed\x9b\xe3\x4f\x14\x4b\x85\x84\x20\xd4\x05\x58\x3d\x6e\x7d\xc4\x7a\xbb\x59\x7e\xdb\x0f\x01\x73\x84\xc6\xda\xaa\x27\xad\xfe\x78\x58\x2d\x77\xab\xeb\xfd\xb9\x6a\x62\x3b\x48\xe0\xee\xfa\xf8\xa8\x4a\x0f\x42\x70\x87\x92\x38\xc4\x77\x79\xbd\xdc\xd8\x22\x56\xd4\x1f\x49\x31\x4d\x12\x15\x6a\x83\x7a\x20\xe1\xe4\x4e\x25\x52\x62\x4b\x6f\x27\x0a\xf1\xea\x03\x56\x9a\x72\x40\x3e\xcc\x21\x2b\x86\x7a\xe5\x6d\x3a\xe1\x46\x48\xe7\x5a\x23\xad\x6a\xc6\x68\xde\xb8\x70\x9f\x2a\x66\x10\x07\xb0\xfa\x73\x74\xc9\x2a\x91\x71\x67\x3c\xf9\xa5\x8d\x10\x47\xaf\xfe\x3f\x66\x16\x02\xaa\x23\x40\xa0\xba\x7b\x97\x26\x3d\xfc\xd9\x37\x85\x6a\x48\xb4\x85\xf9\xff\x1c\x09\xd4\x12\x0a\xd2\xa2\x00\xad\x9e\xd5\xc6\x3c\x5d\x6d\xea\x3e\x52\xa5\x00\x14\x89\x43\xa8\x66\xd2\xee\x65\xfd\x6c\x36\x91\x0d\x4b\x9f\xa1\x59\x34\x2f\x50\x64\xa2\xa8\x37\xc5\xee\x05\xac\xab\xb7\xc9\x20\xd7\x93\x3b\x6c\x22\x85\xb6\x1e\x58\xb5\x59\xff\xbe\x1b\xdd\x0b\x93\x86\x48\x1e\x7a\xca\x9b\xee\xd6\x1a\x93\x98\xce\xc8\xde\x0b\x05\x4f\x66\x20\x0b\x48\x82\x01\xe9\xf2\x43\x42\x85\x45\xa3\x4c\x0d\xcf\xcc\x02\x6e\x30\xfc\xcb\xea\x6f\x7f\x2e\x1f\xe1\xbf\xa7\xbe\xd6\x4d\x58\x90\xb2\x4e\x1e\x36\xf3\x7b\xc0\xf8\xba\x19\x09\x13\xe3\x5a\x71\xeb\x3a\x17\x13\x8c\x13\x61\x24\x49\x62\x17\xa1\x3f\x76\x2d\x8f\x31\xd4\x85\x30\xa2\x93\x2e\x30\x41\xec\x4e\x59\x34\x5d\xda\x4f\x18\xe5\x21\xe1\xc8\x46\x35\x59\xdf\x11\x6d\xff\x2e\x31\x50\xb7\x5a\x35\xd3\xb0\x68\xfe\x79\x33\x9a\x72\xac\x92\xa9\x17\xec\xf5\x0f\x03\x24\x46\x65\x42\xac\x88\x4d\x63\x03\xc3\x51\xc7\x63\x76\xd1\x63\x54\x59\x3d\x1f\x25\x72\xb5\x5d\xdd\xde\x96\xe7\x21\x21\xa3\xda\x12\x6e\x96\x8b\xdd\xc2\x7f\x57\x18\xa7\xd6\x83\xae\xcf\x88\x6f\xb3\xba\x19\x8b\xfb\xf5\xd8\x50\xc2\xc2\x94\xa3\x7a\xe8\x3f\x57\xbb\xa7\x6d\x7f\x1a\xa1\x82\xc4\x3b\xdb\xaf\x47\x0f\x6a\x7c\x0d\x11\x31\x91\x5f\x0d\x45\x61\x2d\x47\x97\xa2\xd0\x67\xe3\x12\x86\x65\x84\xf5\xe6\x1a\xd7\x23\xff\x45\x91\x66\xd8\x38\xfb\x56\x36\x2f\x3f\xb2\xf3\x1d\xf1\xff\x52\xc7\x27\x2c\x66\xb1\xc5\x97\x36\xe5\xf1\x26\x17\xcf\x1b\x63\xfc\x17\xc6\x3c\x26\xae\xe8\xdb\xbe\xfe\x57\xe5\xe9\xf9\xa5\x99\x5c\x6c\x1c\x42\xa2\x7b\xe3\xb3\xd5\xc0\x4b\xb4\x3d\x9a\x58\x21\x93\x87\xcd\x76\x1c\xb1\xb4\x47\x50\x49\xca\x8a\x65\xee\xbe\xac\xbc\x0f\x68\xfb\xf1\xed\x60\xa7\x64\xb1\x8c\xc0\x79\x86\x2c\xc6\xf2\xbd\xf3\xdd\xc6\x39\x26\x25\x61\xb1\x22\x22\xf6\x16\xe4\x67\x16\x35\xed\x00\x4d\x9c\x1c\x3d\x76\xf8\x2c\x91\xb3\xdd\x93\x3b\x3b\xd5\xe9\x2f\x37\x29\x96\x72\xdf\x32\x78\xb7\xf2\xad\xb7\x65\xb3\x31\xcb\x5c\xf4\xc0\x61\xc2\x12\xc3\x90\xe0\x8d\x8b\xa8\x5d\x0e\xc7\xe2\x04\x7f\xa7\x0b\x33\x4f\x6a\x22\x2c\x25\x89\xe8\xf5\x18\xb6\xbe\xc3\xfd\xd9\x83\x4f\x26\xf7\x25\x8d\x62\xed\xfa\x86\xf7\xf0\xb3\xb9\x01\x18\xf8\xc9\xfb\x31\x89\xf1\xd1\x5d\x47\x54\xc8\x8a\xe7\x9b\x89\xf6\x24\x61\x92\x80\x57\x7f\xfd\x52\x95\xa7\xa3\x15\x06\x9b\x5e\x8f\x8f\x7b\x99\xa4\x69\xe8\x36\x0b\x10\xf9\xe3\x29\xbf\x58\xe4\x62\x4a\x59\x86\x79\x8d\xa6\xb4\x58\xd8\x9d\x41\x7e\x12\xa6\x4c\x88\xef\x39\x94\xdd\x13\xd0\x94\x01\x1d\x19\x72\xde\x15\x1f\x0b\xd3\xa6\xc6\xef\x62\xbe\x28\x4d\x98\x66\x01\x0a\xcb\xdd\xae\xaf\x47\xab\xb5\x8e\x52\x2c\xde\xd8\xf5\xc9\x1e\x9a\x9f\x86\xb3\x1d\xf1\x4b\x0f\x7d\x7c\x1b\xb5\x4e\x38\xea\xae\x3e\xae\xb6\x9b\xdb\x6b\xec\xe5\xac\xb6\x5b\x7f\x0d\x10\x24\x48\xd8\x72\xac\x25\xb4\x9f\xdc\x9e\x8b\x03\x5f\x78\xdf\x21\x8e\x85\xee\xc5\x15\xbb\x60\x8d\x19\x4e\x2d\x41\x06\xd4\xdd\x29\xff\x7b\xf1\x36\x33\x3c\x46\xea\xcd\x23\xa0\xa4\xf2\x85\xbb\x69\x64\x14\xd8\xfa\x79\x5e\x56\xb7\x20\x34\x54\xb2\xc7\x48\xb6\xc7\xad\x4a\x81\xc8\xf4\x43\x59\xe6\x43\xb9\x18\xc2\x8c\xb2\x24\x30\x99\xe9\xb2\x7c\xb1\x98\x80\xd1\x5a\xc2\x03\x2e\x4c\xef\xa1\x80\x0f\x65\x44\xb9\x1e\x5f\x0d\x0f\xda\xcc\xba\x47\x98\xef\x8f\xe5\x3b\x54\x24\xf9\x6d\x32\xca\xd9\x00\x62\x43\xc5\x06\x65\x95\x57\x53\x6d\x8f\x72\x24\x9f\xb8\x3c\x03\x17\x31\x8b\x6f\xf2\x03\x8c\x75\x40\x72\xa5\xe6\x47\xb4\x5a\xc3\x57\x74\x54\xd0\xe0\x81\x49\x23\xe7\xe6\xb1\xee\x7c\xcc\xfd\x41\x12\x28\x14\x03\xa9\x1b\xf1\x0a\x4e\x73\xaf\x37\xcc\xc4\x01\xc0\x89\xef\xfa\x5b\xea\xfd\xb9\xa4\x0d\xe1\x24\x54\x98\xbc\xec\x1e\x17\xf7\xdb\x9b\xd5\xe3\xdd\xe2\x7e\xf1\x65\xf5\xb8\xff\xb6\xfa\xb3\x3b\x93\x34\xb8\xb7\x21\x6f\x77\x68\xc8\x31\xbf\x89\x73\xa2\x23\xc4\xd6\xa0\x85\xcc\xa8\x8d\x4a\x38\x25\x0a\x03\xa3\xd5\xf2\x71\x39\xdc\xc1\x38\x65\xe0\x7d\xfb\xac\x7c\xc1\xad\xa8\x1b\xbb\x57\xae\xaf\x27\xd7\xcc\x28\x09\x1d\x5b\xc3\x02\x73\x1c\x94\x62\x7c\x19\x2c\x02\xbc\xcd\xa8\x9c\x73\x0b\xa6\x19\xbe\xad\x9c\x93\x10\xf3\xcb\xea\x54\x0c\xa4\x54\x92\x7f\x73\xdf\xf2\xa2\xff\xf9\x37\xff\x8f\x1f\x9c\x6a\x24\x52\xee\xcb\xf7\x19\xd8\x69\x1f\x06\x70\x6e\x28\x62\x9f\x16\xb7\x57\xcd\xf0\xdb\xc2\xc4\xea\xeb\x63\x3f\x62\xdc\x5f\x9e\xd9\xaa\x1c\xe0\xc1\x47\xce\x3c\x14\x31\x36\xf0\x3a\x09\xcc\x55\xa1\x27\xaa\xa5\x84\xc7\xda\x8a\x62\xa0\x4e\xcd\x08\x39\x43\x78\x12\x10\xaf\x72\xb4\x7c\x11\xcd\x1d\xd4\xb5\x78\x86\x45\x73\x2e\xba\x4f\x78\x42\x02\x84\x9e\x3b\x8f\x6d\xac\x75\x94\xd5\x47\x77\x2a\x42\x50\x06\x40\xb5\x51\x60\xdd\x6c\xde\x6c\x49\xbd\x3f\xcc\x71\x4f\x73\xa8\xa6\xfd\xb3\x38\xc0\x5e\x8e\x42\x77\x9e\x48\x8a\x78\xe0\x76\xe6\x2e\xf2\x7c\x53\x21\x65\xbf\x19\x94\x72\xfe\x3d\x2c\xe6\x0c\x41\xb5\xe7\x75\x92\xe9\xbf\xfc\x3d\x4b\x69\x1a\x46\x1e\xa0\x9a\xa9\x09\x9c\x87\xf0\x94\x77\xbc\x09\x44\x18\x54\xbd\x27\x8c\x1f\x91\x04\x9a\x0f\x1c\x41\x3e\x7b\xee\x69\x0a\x88\x47\xd7\x59\x6d\xc5\xdd\x90\x44\x3e\xf9\x4a\x41\xac\x7f\xc4\x33\x34\x3f\xb2\xe2\x71\x6a\xfc\x41\xb8\x08\x25\x32\xa3\x8f\xe5\xd1\x96\x27\xfc\xa5\x08\x60\x9e\x08\xe7\xd0\x85\x1e\xca\xf0\x54\x83\x76\xdf\x66\xe5\xea\xbb\xf4\x8e\xcb\xd8\x68\x3a\x64\x07\xb4\x11\x4b\x1b\xac\x0d\x9c\x64\x26\x6f\xae\xd4\x80\xab\xe5\xde\xf7\x94\x11\x3b\x26\x1a\xf1\x37\xa1\x99\xee\x7f\xfb\xfb\xa2\x43\x1b\xb3\x9b\x4c\x34\x56\x6e\x7f\x69\x9b\xe9\xa0\x6d\x67\xcb\x8f\xd3\x56\x1a\x25\xab\x2d\x12\x68\xc2\x75\x24\x5c\x43\x84\x82\xc6\x56\x8a\x27\x2b\x9e\x7f\xa1\xb1\x45\x38\x10\x00\xe2\xcb\xc9\x5b\x10\x95\x7a\xc1\x9c\x61\x20\x5a\x4a\xb8\x89\x09\xb6\xf8\x5d\x72\x39\x46\x64\xf8\x31\x86\xa1\x90\x3c\x16\x3e\x6f\xc6\x7c\xf3\x7f\x0f\x19\xe7\xa3\x89\xda\xb3\xce\xe7\x67\xab\x3d\x79\x18\x04\xa9\x88\x87\xed\x8c\xaa\x3c\xdc\xc1\x05\x58\x2e\x09\x03\x12\x2a\xb7\xf2\x2d\xdb\x0d\xf3\x2a\xef\x14\x9c\x48\x18\x24\xd4\x27\x11\xf7\xa8\x6b\x74\xa9\xe1\x4b\x42\xa2\x62\xd4\x54\xfd\x52\x89\x42\xdf\xb4\x6f\x6a\x55\xa0\x13\xe1\x8c\x8b\xfb\xb0\xb6\x1f\x52\x9e\xd8\x84\xca\x4e\xc3\x36\xa7\x79\x10\xde\x0d\x85\x84\xd4\x04\xd2\x4d\xd4\x5b\xac\x33\x21\x7a\x72\x62\xdf\xd3\x0e\x8b\xf1\x4a\x7f\x94\x55\xae\x97\xa7\xe3\x85\x38\x69\x72\x21\xe3\x73\x30\x1d\x20\xfb\xd5\x1e\xbc\xc9\x4b\xd1\xec\xca\xa7\xc2\xa2\x8b\x47\x0d\x89\x90\x27\xa9\x75\x09\x40\x45\x8c\xd1\x26\x1b\xf2\x44\x59\x81\x4a\xe4\x6a\x7b\x27\xa1\xf6\xbf\xd3\x39\x18\xb6\xff\x97\x76\x48\xa2\x1f\x90\xb9\x25\xe3\x4e\x38\xc2\xd3\x74\xbc\x0c\x88\xe8\xdc\x9d\x8d\xa5\xb6\xce\x46\xeb\x61\xa8\x14\x6d\x6f\xeb\xd7\xac\xb9\x14\x38\x26\x33\xb1\x7a\x32\x1f\x25\x86\x91\x08\x6c\xca\xde\x55\x10\x6b\x2c\x5d\xf8\xa8\x2a\x8c\xda\xb0\xab\x47\xa6\xf6\x6d\x43\x3f\x20\x86\x10\x97\xcf\xac\xfe\xfd\x24\xf2\xac\x41\x0d\xbe\x39\x48\x07\x09\x05\x0f\xc2\x5e\x43\xba\xf3\x1d\xcb\x8a\xec\x70\x3a\xdc\x00\xcc\xb5\x91\x43\x19\x4a\x4c\x64\xef\xa1\xb4\x93\xa0\xaf\xee\x85\xca\x80\x50\xe3\x9c\x02\xe9\xfb\xae\x17\x34\x6a\x5d\x4e\x74\xe8\x48\xa8\x39\x37\x8e\xf0\xfd\x78\x73\xb3\x05\x54\xd9\xa9\x17\x7a\xfa\x30\xb5\xa4\x2c\x70\x22\x62\xa8\xcc\x6c\xc5\xb1\xee\xcb\xdd\x4b\xd5\x77\xe9\xec\x97\x74\x6f\x2b\x90\x80\x5b\x78\x57\x75\x73\x2a\xd4\x78\x96\x41\xfb\xdd\x36\x65\xc9\x3f\xf6\xaa\x3c\x1c\xa1\xa8\x07\x40\x26\x12\x82\xd3\x5b\xb8\xcd\xde\xb0\x28\x55\x7b\x0c\x5e\x3d\xc4\xe0\xfd\xff\x83\xbd\x23\xa1\x61\x96\xa4\x6a\xf3\xbe\x3b\xf1\xb3\x7d\x0a\x98\x14\x5d\x9f\xda\x8b\xfd\x72\x12\x95\x28\x1a\x40\x5b\xe9\x81\x21\xb3\xfd\x78\x14\x30\x8e\x3d\x98\x61\x6b\xa4\x3b\x14\xa1\x4b\xf1\xd7\x6b\x5b\xff\xea\x31\x36\x24\x0a\xe2\x10\xef\xa6\x5d\xe3\xaf\x3e\xda\x35\xa1\x38\x17\x98\x9d\xbf\xe6\x28\x10\x42\xaa\x51\x0b\xfe\xaa\x5d\xdf\xfa\xda\x4f\x44\x18\x20\xf8\xf6\x66\xb7\xec\xfe\x64\xe2\xc4\xbd\x8d\x28\xb9\x66\xf1\xa2\xee\x20\x15\x29\x12\x90\xbf\x5c\x2f\xed\x4e\x19\xf6\x47\x24\xf6\xf5\xda\xf9\x59\x3c\x6f\x9b\x32\x87\xe2\x41\xfc\x1d\xd9\x7b\x77\x02\x66\x12\x0c\xbc\x11\xe3\xe1\x2b\xb5\x11\x8f\x53\x66\xb5\xeb\xdf\x00\xf9\xb0\xff\x2c\x6d\x2e\x32\xdf\x5e\x8c\xc2\xc8\x62\xe0\xed\x63\xca\x8f\x84\x4c\xee\x76\x18\x47\x88\xb3\x30\xed\x4f\x1b\x4a\xe6\x91\x28\x4c\x22\xec\xd9\x2d\x5f\xc4\xe1\x98\x95\xc5\x36\x3b\x1c\xcf\x31\x9c\x6e\x70\xc4\x42\x65\x11\x19\xcf\xfb\x43\x76\xc1\x6c\x87\x44\x51\x2c\xc0\x55\xdb\x9d\x9f\xc1\x58\xb4\x82\x44\x91\xe0\x7c\xd2\x95\x10\x39\x74\x42\x59\x24\x8a\xa4\xad\x92\xac\x55\xb9\x90\xa2\xd0\xe5\x74\x1d\x8e\x22\xe5\x00\x01\xc2\x6f\xfc\x51\xac\x42\xa1\x27\xc2\x65\xe7\x52\x9e\x24\x4a\xb8\xc1\x5a\xd2\xdd\xdd\xe3\xe4\x46\x25\x29\xc1\x40\xce\x3b\x95\x39\x94\xe0\xa2\xbd\x6d\xd8\xb0\x1b\xad\xf7\x91\xa0\x92\xa6\x3d\x31\xe7\x6b\x59\xd5\x88\xbd\xdf\x36\xa7\xe9\xbb\x20\x78\x8c\x9a\xa7\xed\x33\x65\xe3\x65\x67\xb4\x29\x46\x82\x5b\xa3\x6f\xa1\xf5\x03\x7c\xee\x2a\x7e\xf9\x25\x90\xa1\xc2\x0e\xf1\x6e\x7d\xb7\x42\x64\xcf\x7a\xb9\xf1\x17\x2d\xc1\x0a\x8d\x7c\x5d\xdd\x3e\xf0\xaf\x4f\x77\x8b\xfb\xf5\xce\xa7\x67\x91\x4a\x53\xe3\xe5\x0a\x1d\xc4\x76\x55\x68\xb4\xc0\x42\xe7\xbc\xd1\x4e\x13\x69\xa9\x3c\xf3\xd8\xc6\x98\x88\x7e\x5e\xb6\xab\x55\x93\x0d\xad\x2b\x07\xab\x75\xfb\x21\xec\x21\x2e\xcb\xac\x88\x93\x08\x53\x1b\x92\xf8\x0b\xd0\x26\xc5\x56\xc9\x63\x6f\xc3\xd1\xfe\x11\x04\xed\xa0\x95\x68\x09\x39\x8a\xa2\xdd\x30\x08\xad\xd6\x74\xd3\xa9\x5d\xde\xf6\x3d\xe7\x08\x52\x86\xf1\x68\x27\x35\xd5\x5e\xeb\xf7\xc7\xed\xc4\x36\x74\x76\x4f\x8d\x40\x46\xc8\x8b\xda\xba\x05\x62\xa8\xb2\xf2\x8f\x0b\xff\xeb\x3e\x6a\x42\x8d\xb1\x23\x2a\x6d\xfe\xb3\x94\x88\x24\xb0\x74\x54\x38\x33\x5a\xf6\x9f\x89\x15\x65\xdd\x6e\x9f\xcf\x39\x3b\x91\x38\xa0\x1a\xfb\x62\x2f\xd9\xf3\x4b\x7b\xcf\x07\x5e\x91\xf3\xd3\x22\x0e\xda\x40\xd6\xa1\x1a\xb2\xc9\xc3\x8c\x49\x10\x62\x8a\xb2\x47\x01\x42\xaf\x18\xb2\x31\x33\x6f\x50\x4c\x48\x84\x09\xf6\x3d\xbc\x63\xe9\xf2\x4c\x07\x85\xc4\x24\x09\x54\xdc\x45\x97\xda\xd6\x5a\xc8\xf6\x98\x67\x03\x78\xec\xe4\x33\x2c\xb4\x94\x0d\x27\x5a\x6a\xf9\xdf\x57\xd9\xa0\xbb\xd8\x87\xc5\xfe\x23\x22\x1a\xf8\xc0\xcc\xf8\xbf\x4c\xa3\xe4\x98\x93\x44\x91\x4e\xc5\x05\x9f\xe6\x99\x79\x14\x89\xc3\x28\x45\x3d\x9c\x77\xf0\x5a\x37\x77\xc2\x47\xfa\x71\x14\x30\x08\xc7\x30\xf0\xbb\x8f\xf6\xbb\xeb\xf6\x39\xe4\x30\xd5\xdf\x24\x71\xc4\x03\xe9\x3e\xb1\x5d\xdd\x0a\x09\x9e\xd1\x4a\xe2\x38\x91\xa9\x9a\x88\xdd\xce\x54\x50\xe3\x24\x66\xd8\x1a\x7a\x17\x55\x95\x95\xd5\x2f\xda\x4c\xb1\xd0\x02\x5b\x29\x6d\x62\xbd\xb4\x4e\x0f\xb6\x58\x80\x8e\x83\x6b\xed\x2c\xef\x57\xc8\x63\xf4\xd7\x22\xb9\xb1\x32\xa1\xbf\xff\x31\x8c\xe0\x62\x1d\x04\x29\x78\x33\x66\x2c\x8e\xcf\x3d\x72\x4d\x25\x56\x40\xdf\xcb\xfc\xf5\x0b\x14\x50\x67\xe7\xb0\xd2\xf1\x45\x82\x4a\x80\x76\x2b\xf6\xe2\x78\xf4\x4d\xa3\xe1\x92\x18\x9b\xc8\x6a\x08\xbd\x77\xf8\x9e\xd8\x28\xe5\x49\x6d\xff\x2c\xa5\x67\x7c\x4c\xb3\x8d\xf1\xe5\x19\x9d\xe0\x56\x27\x4f\x1f\x5f\x56\xf7\xc1\xf2\x25\x93\xd9\x67\xb1\xb1\xfd\x58\x42\x78\x18\x5b\x4e\x4b\x21\x0e\xb0\x6d\xca\x36\xea\x1f\xbf\x3b\x09\x89\xd2\x84\xf8\x02\x41\x69\xba\x29\x8e\x2a\xcc\x7d\x02\xe6\x46\xd3\x44\x38\x6c\x4a\x53\x89\x3d\x2a\x80\xec\xb5\xe7\x6d\xb8\x31\x2c\x88\xfd\x42\xfc\x08\x07\x91\x15\x1b\x63\x85\xcf\x67\xb7\xdc\x84\x85\x29\xee\xcc\x05\x80\xae\xaf\xb2\xca\x0b\xb7\x90\x84\xc5\x21\x73\x33\xef\xd9\xd9\x09\xf8\x23\xda\x8a\x3e\xda\x69\xb1\xbe\xbf\x5e\x5f\x3a\xb9\xd1\x81\xa7\x0d\xb4\xb1\x1e\x3e\x7a\x77\x2c\xe4\x51\x62\xcb\x0c\x79\x7e\xd5\x6e\x9b\xf3\x5c\x51\x92\x84\x49\x8c\x84\xab\x8e\xc0\xe2\x9d\x6f\x49\x12\x85\x31\x82\x29\x70\x2b\xd8\x67\x85\x29\xab\xc3\xe8\x66\xc4\x54\xa4\x56\x7c\x66\x75\x38\x36\x1f\x33\xfa\x25\x24\x89\x59\x10\xc0\x30\xe8\xf0\x81\x4e\xbf\x62\x26\x71\x64\x05\x0a\x3a\x87\x2c\x3b\x97\x3b\xe6\xb5\x1f\x96\xa4\x48\x69\xbb\xfb\x73\xb9\x59\xfb\xa2\x62\x92\xf0\x90\x0c\xf5\xd5\x9e\x6a\xa8\xbe\x54\xe5\x7b\xf3\xf2\x50\x96\xf9\x27\x7a\x4c\x24\x49\x42\x70\x7e\x73\x3f\x1b\x2b\xb8\xb6\xbe\xee\x4e\x9b\x5a\x29\x7c\x2b\xce\x85\x45\xf6\x4b\x67\xd1\x8c\xd0\x5e\x8c\x7f\x32\xa9\x52\x11\xa6\x56\x95\xc9\x1a\x78\xfa\x3f\x83\xc6\xc2\xcd\xbf\xb2\xa2\xd4\x83\x3f\x1b\xc0\x45\xf0\xf9\x34\xb5\xc0\x24\x89\x68\xb3\x26\x7c\x1c\x2b\x0b\x3a\x02\xed\x8a\x7c\x08\x9b\x18\xcf\x7c\x41\x01\xf5\xda\xdb\x0d\xad\xae\xcb\xea\x63\x69\xeb\xfd\x53\x0a\x12\x49\x64\xc2\x90\x36\x82\xf1\xc8\xd6\x0b\xcb\x91\x44\x05\x96\x44\x7c\x5b\x3e\xa3\x6b\xd5\x99\x54\xd6\x78\x2b\x4e\x54\x9c\x20\x55\xe1\x45\x9c\xc5\x95\x89\x12\xd6\xd8\xef\xea\x54\x15\xbd\x65\xd8\xa7\x15\xe6\x44\xf3\x00\x91\xf5\x02\xb7\xe4\x11\xce\x6f\xbc\x5a\x25\x40\xad\x80\xe8\x17\x2b\xb4\x82\x78\xbd\xf6\xf5\x66\xe3\xa5\x37\x31\x44\x4a\x67\x13\xff\x17\xa8\xe6\xdb\x49\x77\x5d\xa2\xc4\xf0\x14\xd1\xdf\xf7\xd7\xc3\xb9\x65\x42\xe3\x7b\xe7\x77\x99\x05\xe4\xef\xaa\xec\xf9\x79\xda\x0c\x4c\x4c\x64\xb5\xb7\xda\x57\x11\xf5\x40\x46\xb8\xbf\xc4\x24\x11\x9e\xe7\x7a\x75\xbf\xb9\x5b\xdf\x2f\x76\x1b\x47\xce\x21\x29\xe1\x96\x75\xee\xf1\x6a\x4f\x55\x3e\xc7\x36\x27\x6d\x6a\x69\x9c\x12\xdc\x52\x1c\x85\xf2\x34\xf9\xee\x22\xda\x20\x15\xb9\x04\xbb\x41\x9d\xfc\x1f\x93\x21\x32\x44\xc5\x80\x87\x5c\x34\x59\x71\x1a\x9b\xd0\x5d\x14\x48\x27\x29\x0d\x98\xc0\x4c\xba\x03\x75\xd8\x78\xba\x54\xaf\xbb\x72\xc8\x2e\xf3\xe3\x99\x8e\xad\x6f\x71\xbe\x3d\x1d\x07\x7e\xe7\xa3\x27\x92\x52\xc3\xbd\xde\x8b\x13\xa2\x1d\x1f\x67\x92\x82\x15\x3c\xb5\x4a\x0a\x97\x52\xcd\xe9\xa7\x84\x6d\x37\xe1\x02\xea\x78\xa0\xd3\x92\x5f\x1a\xa6\x06\x58\xc7\xb0\xbe\x11\xd8\x0b\x3b\x0d\x40\x11\x69\x44\x63\xe6\x18\x13\x1d\x3a\xe0\x5c\x7b\x80\xa4\x91\xd4\x08\x9d\x7a\x7e\x56\xd3\x23\xc0\xfd\xfe\xb3\xc8\xf3\x6d\x03\x47\x3f\xe1\xd2\x38\x50\x88\xbf\xae\x85\xe9\x28\x2b\x53\x5a\x14\x49\x63\x1e\x1b\xd9\x0b\xcf\xdb\xfc\x77\xfc\x1d\x71\x08\xd6\x94\xc7\x2a\x3e\x5d\xdb\xea\xb4\x5e\xbd\x4d\xc5\x10\x49\x1a\xc7\x2a\x74\x75\x93\xeb\xdd\x24\xc7\x4a\x13\xca\xb4\xb7\xfc\x17\xf5\x8b\x0b\x40\x46\xb3\x20\xe1\x81\xe8\x48\x46\xfe\x12\x93\x24\x46\x34\xff\xfa\xee\x7a\xf5\x87\xbb\xce\x59\xfd\x15\x3f\x1e\x02\x14\x8b\xbf\xcd\x0a\x93\x15\x9d\xcf\x22\x49\x53\x07\x3c\xb7\x7d\xae\x76\xf1\xde\x77\x87\x84\xa5\x9f\xe9\xa2\x70\x36\xd1\x77\xce\x5a\xc2\x8f\x10\x9c\xa0\x9e\x3b\x14\xfa\x26\x1b\xc0\x14\x26\x5f\x2e\x84\x85\xe8\xfe\x6b\xfd\x65\x3d\x78\xd1\x53\xa1\x8c\x8f\xc0\x8f\x58\x32\xc9\x45\xdd\x34\x03\xbf\x8e\xc9\x14\x93\x2c\xc0\xb5\xf8\x66\x37\x0a\xc8\x52\x29\x2c\x77\xca\x47\x3e\xf5\x6a\x60\x25\x49\x52\x09\x49\xd2\x47\xc5\x16\x35\xd3\x99\x71\x7c\x8a\x9a\x49\x25\x58\xe6\x58\x57\xe9\xef\x15\x56\x48\x2a\x4d\x84\xed\xc8\xd5\xf3\xf3\x60\xf1\x9d\x7b\x5b\xba\xc9\xad\x52\xed\x7d\x97\xb1\x19\xbe\x56\xe5\x5c\xb1\x28\x55\x22\xc1\xae\x07\x82\x10\x8f\x55\x56\x43\x7d\x7b\xeb\x0b\x34\xa9\x66\x1c\x43\x90\xbb\xc5\x1f\xeb\xbb\xa7\xbb\xfd\x7a\xb9\x71\x20\xba\x6e\x44\x22\xb1\x5a\xec\x1d\xc1\x3f\x61\x43\xfe\x32\x99\xc6\x7a\x7b\x1f\x37\xa4\x40\x38\xb6\xac\x8f\x15\xe8\x4c\x35\x43\x22\x71\xd2\x0d\x49\xb1\x59\xf7\x24\xb3\xff\xfa\x4b\x82\xd8\xa0\x45\x57\x6d\x29\xd5\xf7\xf0\x7e\x57\x96\xc5\xe4\x75\x00\xad\x62\xd5\xb5\xd3\xb2\xe2\x63\x0b\x85\x1e\x2b\xd4\x92\xd4\x30\x82\x6c\xcf\x45\xf1\xea\xb7\xf0\xd4\x38\x71\xf5\x83\x78\x85\xca\xe1\x88\x07\x52\xda\x24\x35\x69\xa0\x44\xa7\xe8\xe6\xfd\x20\x77\xa5\x5d\x5a\x46\x77\x5f\x04\x84\x13\xde\x49\xb0\xbc\x65\xe5\xc9\x69\x24\xcd\x4e\x6f\x11\x08\x85\x6a\xed\xf0\xdf\x53\x3f\xeb\x44\x20\x05\xa2\x70\x32\x55\x3a\xc7\x7b\x77\x80\x24\x69\x04\x9d\x36\x17\xf2\x2e\xcb\xca\x43\xa0\x9d\x25\xf1\xe8\xae\x08\x62\x48\xe4\xdd\xba\xc5\xcf\x1f\x1d\x12\x4c\xd0\x28\x12\x1d\x56\x79\xd5\xbc\x2c\x2d\xb8\xeb\x11\x54\x06\x6f\x5d\x20\x20\x18\x0f\x82\xc8\xf3\xf4\xbc\xb3\xc1\xe6\xd4\xa8\xf2\x30\xf4\x5c\x20\x82\x29\xeb\x96\x54\x59\x65\x0f\xbc\x81\x37\x65\x75\xb0\x37\xc9\x0d\xe2\xa9\xe5\x73\x79\x39\x3b\x6b\xf5\xe8\x8f\x86\xa1\x5d\xd0\x34\xbc\x41\x5e\x1e\xa1\xda\x0b\xad\xf7\xaa\xac\x9b\x7d\x69\xba\xee\xd7\x78\x89\x13\x61\x1c\xda\x02\xaf\x31\x59\x9e\x89\xe6\x1c\x0e\x23\x42\x69\x33\x68\x09\x75\xb3\x3d\x59\x68\xbc\x67\x4f\x12\x11\xc5\x36\x97\xc7\xa0\xf9\x06\x83\x47\xd4\x4b\x1a\xe2\xec\x45\xcc\x12\x2f\x5b\x84\x25\x69\x44\x0e\x8e\x09\xa0\x93\x27\x1b\x33\xe1\x58\xef\x20\x10\x2a\x8c\x02\x02\x9b\x53\x73\xf4\x1e\x59\x44\xc4\x42\x60\xcf\x15\xe7\x2b\xf5\x7f\x4d\x42\x6a\x7a\x90\x90\x35\x92\x1e\x74\x07\xfd\xa8\x34\xc6\x20\x36\xcf\x8a\xd7\xc9\x33\x4f\x83\x00\xe7\xe0\x7e\x8c\xaf\x98\x76\x5b\x85\x48\xb9\x21\x9e\x60\x08\x35\xba\xc0\xc0\x35\xdc\x41\x2d\x1c\x01\x6e\x4a\x5f\x98\x94\x02\xfc\x79\x24\x60\x98\x66\x7d\xea\x2b\x10\x6e\x57\x9e\xb8\x6b\x12\x21\x14\x8f\x5d\x49\xee\x5e\xa8\x5d\x79\x0f\x8d\x99\x5e\x93\x36\xf8\xe3\x37\x0f\x5e\xcf\x62\xbb\x5b\x7c\xf3\x94\x2a\x21\x1c\xaa\xdb\x31\x23\x86\xf4\x9e\xf1\x57\xc9\x40\x61\xfc\x23\xac\x58\xae\xed\x71\x0e\x99\x2d\x42\x51\x85\xcc\x1c\xcc\xeb\xed\xf2\xee\xe3\x6d\x3f\x82\x47\xa8\x97\xd0\x4e\xa7\xa1\x2d\x39\x11\x2a\x86\xc8\x8a\x80\x69\xf8\xb9\x99\xfe\x06\x95\x5a\x1b\xab\xa3\x63\xae\x8d\xdd\x16\xfd\x20\x9d\x60\xa0\x70\xbd\xfa\xe7\x70\x43\x12\x9a\x08\x14\x97\xfe\x0e\x55\x21\x0e\x0f\x9d\xe6\xc6\xa0\xd6\x2c\x34\x8d\xbd\xc0\x17\xc2\x2c\x3a\xb5\x0d\x22\x34\xb7\xd4\xf1\x36\x9c\xde\x95\x5b\x68\x3a\x22\x62\x32\xe8\x7e\xba\xc1\x26\xd1\x38\x51\x2a\x18\x18\x66\x1f\xb7\xaa\xac\x66\x84\x62\xc7\x97\x6f\x14\x67\x8e\x73\x64\x11\xee\xb3\xd4\x62\x22\x89\x08\xb0\x0c\xb9\x7d\xcf\xea\xda\x0a\x61\xaf\x7e\xda\x99\xfd\xff\xba\xab\xb8\x33\x52\x0a\x72\x58\x14\xb7\x8f\xff\x01\xaa\xaf\x50\x65\xcd\x25\x8a\x9a\xa4\x8c\x93\x74\xb8\xb8\xdc\xf4\x75\x51\x49\x39\xc1\xb9\xf0\xf5\x98\x9f\x46\x3c\x45\x49\x43\xc9\x2c\xff\xe9\xad\x7c\x85\x45\xa1\xb7\x80\xfb\x0f\xa0\xfa\xf9\xb8\xd2\x39\xf9\x42\xc9\x02\x07\xd0\x59\x8f\x9f\xbd\xe4\xcc\x6a\x65\x18\x0b\x08\xf3\x48\x4a\xff\x9d\x5c\x04\x28\xde\x71\xdd\xe9\x06\x76\x47\xb4\x95\x7b\x69\x83\x9d\x07\x14\xc8\xee\x51\x1e\x32\x74\x8e\x36\xcf\xe2\x80\xab\xc6\xe4\x4b\xc3\x84\xa3\x08\xdd\xde\xea\xb7\x7e\x17\x79\xa6\x87\x76\xd4\x93\xdb\x1c\x89\x20\x89\x06\x16\xe1\x03\xb2\xc0\xfc\x07\x62\x61\x35\xd5\xa6\xde\xeb\xe3\xbb\x12\x6b\x06\x76\x9b\xd0\x00\x87\xed\xa9\x6a\xef\xf8\x08\x60\xe9\x07\x9a\x10\xf4\x90\xfd\x3c\xfe\xb6\x44\x70\x6c\x34\xb7\x77\x02\x0d\xf1\xfd\x5d\x48\xe3\x14\x3b\x41\x18\x57\x56\x75\xf3\x03\xe0\xb5\x2f\xda\xcb\x54\x46\xdc\xc1\x27\xaf\x17\xc7\xe3\x68\x2f\x91\x22\xd4\xb8\x59\x1e\x2b\x58\x2f\x37\x77\xa2\xf8\xb8\xa8\x21\x47\xa4\x10\x12\xf3\x81\xe5\xf2\x76\x34\x63\x24\x0d\xad\xa9\xd6\xe1\x98\xef\x8f\x83\x12\x8f\x94\x3c\x41\xb6\xea\x61\xdf\xbe\x9d\x52\xd4\xfd\x11\x49\x89\x55\x0d\xc8\x44\x7e\x0d\x42\xe7\x59\x31\x38\x68\x45\x1e\xbf\x40\xa7\x01\xd3\xeb\x22\xb5\x87\x81\xa3\x69\xe0\x11\x1b\x66\x3b\x31\xb5\x53\x27\x52\xea\x08\x17\xd5\xef\x90\x89\xe7\x73\x61\xe4\x76\x80\xc2\x1d\xd2\x89\x2a\xf8\x53\xab\x24\x74\x9a\x50\xcd\x0e\x99\xdf\x93\xee\xa3\x54\x89\xe0\xa1\x17\xdf\x5d\xe8\xee\x7d\xd2\x8a\x23\x50\x14\xdb\x71\xf7\xf0\xbe\x3d\xe2\x1a\xd8\x49\xd8\x8c\x2f\x4f\x9b\x14\x97\xbc\xac\xde\xb9\xdc\xd6\x2d\x50\x12\x02\xc9\xc8\x60\x12\x58\xeb\x81\x49\xcc\x25\x81\xda\x36\x94\x5d\x56\x96\xcb\x65\x99\xcd\x8a\xb3\x13\x09\x69\x80\xfd\xbb\xbd\x3e\x4d\x81\x01\xd2\xa4\x2a\xf4\x7a\x15\x7b\xdf\xb3\xc1\x32\xd2\x8d\xf0\x2a\xe2\x44\x1a\x90\x88\x3b\x59\x56\x1f\x75\x93\xf9\x7c\xdc\x1e\x54\x01\x63\x58\x5e\xdb\x39\x47\x91\xee\xef\xa1\xc4\xfc\xb6\x47\xb4\x8e\x7f\x81\x22\x44\x21\x98\x4f\x5b\x09\xbb\xa1\x37\xf0\xec\x22\xa8\x08\x50\x45\x9c\xea\x52\x47\x0b\x9d\x92\xf3\x14\x0d\x58\xec\x80\x29\x8b\xaa\x59\xd5\x6a\xae\xe0\xa7\x28\x4b\xa9\xd5\xec\x7e\xdb\x0a\x73\xa1\x65\xa9\x68\x98\xc2\x50\xd8\x42\x9e\x11\xd0\xfc\xc0\x58\x52\xcf\xe7\x6b\xc7\x22\x93\x6a\x94\xa7\x2b\xc6\x42\xac\xdb\xe2\xad\xce\x0a\x54\xeb\xc5\x82\xe4\xea\xbf\xdf\x45\xee\xa3\x5d\xc5\x20\xb4\x90\x4c\x39\xf9\x5d\x0c\x62\x5b\x59\x79\x29\xdf\xf3\xb7\xff\xbd\x94\xa7\xc9\x00\x1e\xd2\xd4\x72\x34\x10\x8b\x93\x67\x75\xb3\x3d\xda\x74\x60\x32\x30\x0d\xa8\x95\x47\x70\x70\xb8\x55\xa1\x72\xf1\x76\xa9\x74\xa8\xb8\x8a\xad\xc3\xfd\x14\x3b\x4b\xa2\xc0\x0d\x89\xa8\x40\x3e\xe3\x6d\xe9\xbd\x6e\x46\xe3\xe8\xb8\x50\xa3\x62\x02\x54\xf6\x20\x35\x6c\xb4\xf5\x19\x93\x8a\xa9\x46\x11\x93\x97\x32\xd7\xdb\x93\xec\xb4\x6b\x67\x68\xb4\x2a\x4e\x05\xae\x89\xcb\xcd\x7d\x40\x49\xec\x6f\x63\x42\x63\x0c\x85\x16\xda\xaa\xb2\x5e\x30\xe2\xf5\xa3\x63\xa6\x9c\x86\x24\x42\x77\xcf\x38\x22\xe3\xef\x4c\x80\xa1\xd8\x1a\xb8\x4d\xdd\x11\x29\xdc\x51\xa1\x05\x2e\x3c\xf0\x66\x2d\x9f\xfb\xc5\x50\x49\x6e\xa9\xfb\x50\xe8\x8d\xa1\xfc\x6b\xf7\xf7\x34\x11\x66\x04\x3b\x98\xc3\x8d\x2b\x25\xac\xdd\x9c\x86\x37\xff\x49\x4d\xb9\x93\x9f\x6d\x10\xac\xf5\x99\xeb\x1e\x51\x9a\x87\xb6\xde\x9a\x67\x50\xdc\x88\xea\xd0\x9d\x26\x86\xd4\xdb\x9c\x14\x90\x5f\xc3\xa8\x0d\x35\x8f\xed\x51\x1a\x14\x32\x52\x2d\xc9\xec\x7a\x7d\xbf\x71\x8a\x6c\x43\xba\x99\x82\x44\xe1\x7a\xba\xfe\x7d\xd7\xa1\x46\xfb\x63\x10\xb8\xca\xe5\xee\xbd\x9c\xfc\x5a\x00\x82\x4d\x0c\xe9\x44\x30\xe6\xad\xbb\x89\x02\x13\x09\xcb\x61\xfc\x58\xf8\x7c\xc8\x7f\x81\xa1\x04\xe1\x5d\x4d\x2f\xe5\xf5\xa9\x97\xa3\xff\x58\x2c\x30\xf9\x3d\x59\xcb\x8e\x91\x22\xde\xf8\x1e\x18\x19\x23\x3d\x47\x41\x96\xa3\x73\xeb\xe8\x44\x3a\x90\x0c\x7f\xc3\xfe\xd0\xee\x6d\xb3\x5f\xa6\x03\x6d\x45\xf2\x84\x52\xd5\x09\x96\xe5\xe9\x58\x16\xf5\x03\x54\xb6\x66\xb3\xda\xf9\x59\xa2\x49\x18\x63\x58\x96\x83\x69\x08\x99\x7c\x13\x09\x6d\x97\xe3\x1d\x32\x1b\xb6\x77\x4e\xab\xa4\x8d\xae\x71\xde\x1c\xf3\x53\x53\xaa\x4a\xa8\x8f\xfc\x2d\x5f\xa8\x17\x9b\xf4\xce\x2c\x8f\x9a\x32\x41\xc4\x84\xa2\xe9\x0f\xa5\x0c\xc5\x6d\x2e\x66\x81\x9a\xb3\x10\xf7\xee\xc3\xc7\x50\x42\x40\x73\x26\xb1\x2d\x5d\x65\xcf\x2f\x4d\x1c\x4d\xae\x9f\x47\x14\xa3\xbc\x17\x51\xbf\x3c\xb5\x8b\x56\xfe\x91\x15\xcf\x03\xc0\x6c\x67\xcc\xe5\x83\x11\x1d\x86\x89\x8c\xcf\x4c\xf9\xff\x9c\x04\x55\x3a\x0c\x15\xc2\xcf\x1f\x4f\xd9\x1f\xa7\xa1\x8c\x0e\xd1\xa1\x8e\x11\xcb\x59\x9e\x1a\x72\x5d\x76\xd1\x87\x8e\x28\xc1\xe5\xdc\x9d\x28\x14\xfd\x81\x10\xdc\xe6\x72\x3a\x2e\xcb\x6a\xea\x48\x3a\xff\x84\x23\x16\x79\xf5\x65\x57\xbe\x40\xf7\xa3\x4f\xd1\x3d\x3a\x66\x76\xef\xb1\xf9\xac\xc7\xf6\x37\x48\xc0\x1f\x81\xcf\xba\x75\x53\xc7\x91\x94\xd2\x67\x09\x8d\xc8\x9d\x09\x8a\x8f\x50\x74\x9c\x10\x8c\xde\x5e\x5f\x77\x50\x37\xeb\xe5\xc6\xef\x3a\x3a\x09\x52\x34\x8f\xdc\xdb\x74\xd6\xca\x56\xfe\x4a\xe8\x66\x48\xbe\xd6\x89\xb4\xbe\xe2\x57\xa7\x0f\x9b\xbd\x77\xcf\x3d\x25\x1a\x63\xf0\x1b\xa8\xaf\xa0\xea\x5a\x37\x3a\x8d\x42\x4e\x3a\x21\x7e\xd0\x5b\x31\x89\x4e\xb4\x70\x46\xa0\xfe\xed\xbd\x24\xa7\x39\x89\x52\xb5\x48\x09\x2a\x18\xfe\x58\xdc\xde\xae\x76\xfb\xdb\xab\xfd\xe2\xfa\xae\x2b\xa3\x6a\xa9\xb9\x62\x76\xc1\xd8\x95\xa7\x36\xe3\x84\xa2\x19\xb3\x80\xdc\x48\x15\xc4\x71\xcf\xa8\x5f\x1c\x8f\xb9\xd7\xbc\xff\x4c\x51\xf2\x93\xff\xf8\xf3\x12\x62\x5c\x49\x0b\xb1\x98\x0f\x17\x3d\x3f\xba\x0f\x48\xe2\xcd\xdb\x96\x4f\xdb\xeb\x0b\x4b\x89\x8a\x34\x6e\x4c\x48\xe7\xbe\x29\x2b\x6f\xc7\xe7\x7f\xb9\x4a\xc3\xc8\x35\xbe\x6f\xcb\xe7\x51\x1e\xa0\xb5\xb0\x5e\x7f\x6a\x90\x95\x69\xe0\x06\x77\x62\x84\xe0\xb7\xf3\xbd\x9d\xb8\xf5\x5c\x92\xa3\x21\xe4\xb1\x2f\x02\xba\x90\xb7\x1a\xb6\x97\x34\xe8\xc4\x88\x41\x0e\x7b\x35\xeb\xe5\x43\xb4\x09\x3a\xaa\xe2\xc8\x25\x8a\x68\x93\x86\x48\x42\xbe\xda\x8e\x24\x08\xb4\x11\x69\x64\xf3\xab\x63\x59\x8d\x0a\xac\xc4\xdf\x19\x03\x9c\xba\x93\xde\xc0\x79\xa2\x6f\x47\x41\x10\xa6\x74\x28\x30\xd7\xe7\x50\x10\xc4\x4e\x5b\x0e\xf5\xe0\x4f\xb3\x71\xea\xf4\x6c\x22\xc4\x18\x04\xdf\x29\x0b\xe8\xde\x36\x30\x36\x38\x20\x10\x48\xeb\x13\xfc\x50\x95\xa5\xb1\x1c\x9d\x5e\x30\x8e\x40\x00\x2c\x55\x1e\x3c\x6e\xd5\x3a\x26\x82\x28\x93\x6f\x25\x2c\xc5\x8e\x64\xa5\x8a\x41\xb6\x0f\x24\xb5\x5e\x74\x56\xe9\xed\x53\xfb\x66\xff\x09\xa5\x30\xa6\x1b\xf9\x83\xff\x0a\x47\x79\xe1\x56\x50\xaa\xd2\xc0\x6b\x16\x19\xa1\xa0\xbe\xa4\x14\xea\x5f\x62\xa0\x4c\x60\x8a\x67\xd7\x3f\x2c\xf9\xd8\x52\x4a\x51\x6a\x18\xf7\x91\x81\x1a\x8a\x60\xf4\xaf\xe5\xef\xa7\x19\xc4\x11\xb0\x00\x94\xb5\xcf\xf8\x68\xb3\x50\xcb\x41\xfa\xbf\xa1\xe3\x80\x31\x9b\x99\x16\xa7\xc3\x55\x05\xef\x7e\x99\x83\x30\x60\x58\x57\xca\x6a\x54\x42\x47\xce\x70\xd5\x3d\xc6\x90\xca\x94\x78\x5f\x3f\x2c\x59\xfb\x03\x51\xaa\x98\xd3\x01\xad\xf4\x55\x59\x4e\x0a\x9b\x10\xa6\x52\x99\x9e\xf4\x7c\xdf\x0b\x63\x40\xa4\x03\xef\x2b\x7c\xb3\x7e\xdc\xee\xf6\xdb\xdd\xea\x61\x7f\xbb\xbe\x5b\xef\xfc\x90\x98\x58\xe5\x37\xcc\xc9\x69\x81\xc2\x3e\x93\x9b\x13\x33\x2a\x5d\xbf\xcd\x56\x3b\x86\x0e\x18\xc3\x7b\x30\xd4\xef\x81\x38\xb5\xbe\x39\x2f\xa5\xce\xa1\xc2\xed\x66\x58\x1a\x87\xd8\xd8\x3e\x19\xae\x1c\x96\x88\xf8\x88\x2d\x2f\x77\x3c\x89\x02\x6f\x7e\xfb\x20\x10\xc0\xaf\x67\xed\x45\xdb\x91\xcc\x75\x22\x1a\xaf\xe6\xdd\x15\x00\x4f\x03\x2b\x14\x02\x49\x42\xb0\x1a\x23\x64\x76\x0b\xc5\x73\xd3\x6b\xb2\xf8\x49\x95\x68\x86\xa8\xb7\xf6\x66\x5e\x65\xcd\xa6\x6a\xd3\x5c\xe4\x61\x6c\x36\x57\xdd\xa5\x19\xc5\x7a\x85\xff\x87\xec\x78\x8e\x8c\x1b\x4f\xbf\xd4\xd8\xef\x7d\xc9\xd0\xd0\x75\x6e\x2b\x01\x41\x53\xee\x2a\x63\x5b\xe8\x04\x39\xa7\xb9\x19\x08\xae\xd1\xd4\xa9\x2e\x44\xa3\x5e\x40\x6f\xfc\x22\x07\x22\x4c\x41\x3a\x00\x52\x87\x9c\x9e\x7e\x3a\x11\x81\x73\xec\x39\xcb\x04\xc6\x97\x23\xd3\x18\xa3\x8b\xe3\x8b\xa8\x0e\xa2\xa9\xb2\x09\xf9\x0a\xa4\x4a\xa2\x76\xc2\x16\xe5\x0d\xc0\x59\x24\x30\x1e\xab\x88\x35\x64\xdd\xd7\x2f\xa7\xe6\xba\x7c\xef\xae\x59\x25\x3c\xb4\xc4\xb7\x45\x73\x57\xd6\xcd\xd8\x3b\x64\xb4\x27\x82\x4a\x09\x96\x0e\x37\xef\xd8\x1f\x59\x1f\x8e\x79\x77\x1a\x2d\x50\xe2\xfb\x0e\x8a\x13\x99\x84\x77\xa0\xa3\x04\x65\xf4\xdc\xd3\x6a\xa7\x87\x57\x38\x1b\x23\x14\x26\x17\xad\xc1\x0a\x93\x5f\x7b\xb7\xf4\xbf\x07\x11\x07\x88\x25\x96\x62\x5d\xd9\x62\x90\xb7\x82\x21\x56\x7a\xba\x86\x66\x2a\xce\x3a\x7b\xe3\x4c\x40\x19\x92\x3c\x5f\x4e\x85\xae\x40\x7f\x9b\x48\x93\x98\x80\x1a\x5c\xfc\xaf\x21\x17\x1f\xde\x8c\x78\x7c\x0a\x42\x04\x0e\x69\x23\xf5\x1f\x59\x31\x74\x90\x26\x86\x28\xe3\xfc\xe6\x85\x69\x7a\xd1\x28\x43\x0c\x43\xdc\x23\xf6\xc1\xac\x0f\xf0\xe4\xb4\x34\x0e\x10\x42\xad\xa7\x96\x98\xc4\x50\x90\x28\x88\xfb\x02\x59\xf7\x45\x8c\x6b\x14\x56\xed\xec\x23\x27\x98\x87\x33\xe6\x9c\x53\x47\x1a\x91\xb5\xfa\x68\xd2\xb0\xf6\x95\x72\x7d\xcd\xb2\x68\x84\xf2\x22\x85\x57\x1f\x33\x4c\x41\xc3\x14\x47\x88\xef\x97\xed\x9f\x9f\x71\x86\x0c\x97\x31\x2a\xd7\xd5\xe5\x29\x6f\x97\xda\x87\x33\x14\xa9\x09\x23\x16\x8b\x0e\x51\xe5\xb6\xda\x61\x1c\x63\x42\xc5\x30\x2a\xd5\x65\x21\x1a\xb4\x0d\xb0\xe8\x51\xb4\x62\x1e\x3e\x67\xcf\x9a\x34\xa1\x61\x28\xa3\x73\xb7\xf8\xc3\xf6\x9d\xf7\x5f\x1e\x17\xf7\xbb\xd5\xca\xf7\x9f\x4d\xa4\xac\x73\x57\x4f\xab\x5b\x2f\x37\x68\x5e\xe7\x47\xc4\xed\x6d\xc7\x57\x89\xd0\xe4\x2a\x9b\x94\x06\x4c\xac\x0c\x5a\xda\x88\x37\x91\xe5\xe8\xd1\x34\x14\xe9\x31\x49\xc8\xb1\xa5\x6f\x37\x53\x2c\x83\x6f\xaa\xe7\xb3\xd9\xd9\xcf\x65\x93\x06\x04\xd1\x6e\x2f\xd9\xf3\x0b\x2e\x96\xba\x07\x80\x99\x54\x4a\x6f\x52\xe6\xbc\x5b\x50\xb5\x66\x32\x51\x52\xc3\x3d\xf0\xfa\x11\xb7\x70\x95\x9f\x90\x52\x31\xc8\x0a\x8d\x08\xc2\x30\x1c\xee\x03\x63\xda\xb4\x11\x24\x8d\xb4\x97\x49\xab\x51\xc4\x0a\xb4\x35\x08\xf2\xd6\xbd\x83\x7e\x80\x11\xb4\x73\xac\x7e\x10\xd9\x85\x2d\xc5\x48\x1e\x26\x76\xd3\x45\xf1\xd9\x3b\xf1\x17\x7a\x4b\xfa\xc4\x6c\x32\x38\xe5\xd8\xb0\xcc\xea\x6d\x53\x0e\xa4\xd7\x8c\xe2\x0c\x49\x34\x6d\x02\xb1\x13\x3d\x57\xca\x1f\x8e\x15\x1a\x31\xec\x2a\x80\x81\x1c\x89\xd1\x44\xc5\xba\xf7\x12\x84\xea\xea\x03\xa1\x71\xa3\x0f\x6b\x29\xc3\xb0\x67\x66\x3f\x55\xf9\xb0\x46\x6c\xb4\x89\x10\x67\x01\x39\x28\xe7\xbc\x82\x6b\xb4\x2a\x87\x26\x06\xf3\x3f\x1e\x42\x11\x59\xa8\x76\xfb\xf6\x5f\x61\x31\x75\xc4\x4c\x30\x10\x4b\x21\x5d\xb6\x61\x8f\xb4\xfb\xd5\x25\xd1\xbf\x71\x45\xc4\x80\x60\x61\x17\xf5\x5a\x2b\x1e\x1b\x18\x4c\xae\x42\x13\x65\x79\x3a\xc6\xe4\x30\x40\xc4\xcf\x89\x85\x7c\x9a\x80\xfa\x6d\xd8\x00\x88\x74\x68\xbb\x76\x55\xf6\x11\xc0\xfc\x62\x6e\x4c\x24\xb1\xf0\xe6\xa0\x5b\xf5\x0d\x66\xa2\xf6\x3e\xd0\x20\x48\xa4\x11\x1d\xf2\xa0\x3c\x55\x6d\xdc\x8a\xd1\x9b\xa8\x3e\xe6\xbc\xeb\x68\x40\x84\x4a\x5d\x16\xb4\xdc\xdc\xfb\x13\xb5\xd9\x11\xb6\x0c\xec\xf5\xee\x4a\xa7\xe1\x37\xbc\x7e\x1a\x30\x12\x05\xc1\x80\xe6\x3b\x50\xde\x9f\x5b\x3e\xff\xe3\x3f\x96\x4a\x6b\x8d\x6b\xd7\xaa\xef\x28\x9a\x38\xb9\x2c\xa6\x24\xe2\x3b\x8d\x85\x99\xfd\x38\x57\x60\x1d\x2e\xc2\x23\x6d\x79\x1a\xf0\x38\xe2\x4e\xd6\xe2\x6b\x59\xbe\x5a\x4f\xdd\x72\xfa\xcb\xb9\xa4\xb8\x05\x1c\xc4\xcf\xef\x50\x65\xc3\xf5\x87\x06\x5c\x05\xd8\xfc\xfb\xfd\xdb\xb2\x7f\x15\x68\x10\x0a\xc9\x94\x03\x99\x3c\x62\x19\xa0\x3b\xa2\x15\xb6\x03\x9f\x6a\xad\xd0\x6e\xdd\xff\x1d\x14\xd7\x5d\xd1\x60\x7b\x2c\x8b\xba\x44\xaa\xc1\xa7\x0f\x9a\x06\xa1\x91\x88\x81\x69\x03\xbf\xde\x4b\xf6\xe4\x91\xce\x34\x88\x22\xc6\x23\x0f\x5c\xac\x9b\x1c\x6e\xcb\xb2\xe9\x5c\x86\xb3\xb2\xe8\x4d\x3b\xc7\x67\x8e\x52\xc0\xdf\xbd\x47\xb4\x49\xf5\xda\xb1\xbc\xdd\xf1\x38\xb6\xcc\x88\xfa\x24\xbf\x67\xd5\x39\x79\xdb\x0d\x4b\x99\xd6\xd1\x90\xaf\x8a\x2f\x44\x77\x10\x62\x97\xb7\x3f\xd5\x50\x3d\x82\x99\x13\xc5\xa4\x41\x9a\x1a\x2d\xbb\xbb\xd3\x6e\x03\xab\xe6\x65\xbe\x51\x42\x83\x54\x32\xe5\xf7\xd8\xaa\xd3\xa0\x1c\x3e\xf8\x14\x40\x5a\x41\xf7\x76\x1d\xf0\x45\xf1\xf2\xdc\xc2\x72\xfe\x27\xc9\x80\xe2\xa6\x53\x94\x3d\x6c\xcb\x1f\x62\xc2\xdb\x1e\xde\x58\x20\xcf\x72\x38\x5d\xa4\x8c\xf0\x93\x39\xe8\x67\xa8\x86\x4a\x1b\x34\x50\x29\x47\xc0\x4c\x57\x68\xba\x29\xab\xcd\xc8\xbc\xfd\x34\xcb\xa5\xa1\x81\x56\x40\x1c\x4f\x6f\x51\x3c\x43\xbe\x14\x95\xde\x42\x95\xb9\xf7\xac\x1b\xa6\x39\x26\x78\x26\xab\x6a\xb4\x63\x6d\x0a\x8b\xca\xe9\xb7\x25\x1a\x68\x03\xc8\x83\x5f\xdd\x2c\x1e\xef\x86\x53\x1a\x98\x4a\xdd\x3c\x6a\x1f\xd5\xa4\x58\x37\xfc\x1e\xe0\xda\x12\xef\x9c\x0a\xc3\xaf\x2b\x89\x34\x30\x46\x60\xeb\xa6\x7c\x2f\xa0\xda\x98\xe1\x9e\x41\x09\xe1\xd6\x2a\xd1\x5b\xac\x8e\x69\xbe\xe3\xa1\x29\xc3\xa4\xd2\x93\xfe\xc6\x20\x64\x4a\x68\x10\xf8\x46\xb4\xc5\x13\x7b\x38\xcd\x2d\xbc\x41\x7e\x53\x9e\xc6\xe9\x4d\xfb\x81\x10\x69\xf3\xc5\xe9\xf0\xcf\x52\xfa\xdb\x44\x28\x63\x36\x2c\xd1\xfa\xea\xf4\x31\xb5\x1a\x9b\x7c\x27\xe3\xb8\x5f\xda\x5d\xa7\x3f\x43\x2c\x06\xc9\x98\x15\x23\x98\xab\xc5\x53\x42\x63\x42\x6d\x33\xbe\xf0\x09\x8b\xe5\x7f\x66\x43\x07\xf0\x4f\xaa\x98\x94\x50\x1d\x60\x8b\x11\x6d\x3b\xae\xa0\xa9\xd7\x06\x21\xaa\xf7\x65\xb3\x3d\x21\x48\xfd\xb7\xb1\x85\xfe\x7c\x96\x40\x09\x6f\xdf\x7b\xdb\x55\x37\xd9\x4f\xd0\x1d\xda\xf9\x8c\x23\x36\xdb\x5c\x69\x4f\x20\x65\x3a\xa0\x1e\xdb\xce\xe8\xd5\xc7\xe0\xff\x59\x14\xda\x02\x37\xd7\xf3\x92\x36\x94\xf0\x30\xc2\x55\xf4\x50\xea\xcc\x64\x50\xad\x7e\xfa\xdb\xca\x1d\x5c\x07\xcd\x75\x7e\x0c\x7d\x4a\xeb\xc9\x93\xe5\x32\x42\xac\xd9\x41\x54\x55\xd6\xed\x8d\x84\x43\x88\x50\xaf\xbe\xa7\x73\x3a\xf3\x28\x9c\x06\x07\x94\x84\x32\x44\x28\xf5\x97\x32\xd7\x77\x59\x01\xb3\x34\xff\xd3\x14\xd9\x4d\x49\x14\x53\x94\x0d\x51\x65\x39\x5a\x0d\x48\x24\xad\x50\xd0\xbb\x53\x32\xb4\xcd\x8a\xee\xa8\x32\xb8\xed\x38\xeb\xb9\xad\xc8\xa1\xf6\xcb\xd8\x28\xce\xa4\x24\x26\x01\xa4\x03\xd7\x1b\x7b\xa2\x91\x72\x38\x25\x71\x18\x04\x4e\x3a\x0a\xf1\xbb\xae\x0e\xf8\x59\x73\x91\x92\x58\x71\xe6\x2d\x19\x2a\xa1\xf2\xce\x82\x6d\x7c\x9f\x13\x9a\x38\x1f\x9a\xc3\x21\x6b\x3a\x52\xd2\xe8\x36\xc8\x20\xe0\x97\x80\xd6\x93\x47\x2f\x49\x68\xa5\x72\x84\x2c\xab\xaf\xe5\xa9\x1a\x97\xfc\xce\xef\xf8\xe0\xa3\x54\x63\x80\xd8\x87\x7f\xbf\x7d\xb6\xce\x13\xc9\x43\xd4\xf6\xeb\x7a\x07\xed\xcb\xe3\xb5\x69\x27\x43\x75\x64\x82\xbe\xb1\x36\x11\x1c\xa5\x44\xc7\x14\x74\xc7\x2a\xd2\x1d\x2f\xe4\xb7\x41\x3e\x45\x89\x06\x45\xc9\xc0\x28\xe8\x5e\x1c\xe0\x8f\xf5\xf5\x19\x77\xcf\x67\x33\x94\x00\xb1\xc6\x8f\x68\x31\xdf\xeb\x77\x52\xd2\x86\xba\xd1\x20\x66\x5c\x62\xb0\x31\x5e\x83\xdd\x50\x13\x6a\x70\x58\x5b\x44\x2e\x7d\x2f\x9b\x0b\x64\x0f\x4a\x8c\x73\x22\x71\x2e\x7d\x37\x22\xcb\xfb\xa2\x2e\xa5\x01\xb5\x2b\xd5\x6a\xf7\xd4\xfd\x29\x96\x3a\xf1\x22\x49\x4b\x51\xd5\x6b\xfd\x73\x79\xd6\x03\xa6\x34\xd0\x1c\x3f\xba\x2f\xca\xf7\x6b\xd1\x0c\xc0\x50\xed\xb1\x10\xe3\xd5\xeb\xec\x80\x4e\x36\xb3\x55\x5e\x37\x96\x32\xc0\x3c\xf7\x2a\x3f\xc1\xa3\x4b\x00\x2c\x24\xe9\x72\x02\x4d\x29\xd3\x60\x0b\x0a\x03\x1d\x4f\x1b\xe9\x8d\xab\xf8\x94\x72\x1a\x23\xc6\x5c\x89\x62\x5b\x7a\x74\x0d\xa5\x3c\xb5\xee\x03\x15\x3c\x9f\xd0\x70\xe1\x15\x8a\x3b\xf1\x13\xdf\x4c\x3f\x26\x0c\x2c\x3e\x38\x2f\x55\x9b\x9f\x7c\x5c\xd2\x23\xf0\xc3\x13\x9b\xd4\x0b\xdd\x2e\x29\xcd\x99\x9c\x33\xa5\x51\xe0\x9c\x1c\x32\xa8\xf6\x4a\x1c\xf7\xc4\x7f\x55\x1c\x87\x48\xaf\xb0\xbb\xcb\x3d\xbc\x23\xf6\xfb\xf3\x58\x92\xc6\x71\x6a\xcd\xe7\xa5\xea\xce\x23\x41\x5b\xd9\xf8\x36\x22\x19\xc5\xbe\x34\x09\x23\xed\x75\xe2\x33\xf5\x5a\xdf\x94\xd5\xd0\x69\xd9\x8f\x82\x34\xd0\x23\x1c\xf0\xd5\xf6\xd1\x9f\x22\x55\x21\xf6\xc9\x0b\x78\xdf\x1f\x44\x56\x8c\xb7\x41\x3f\x08\x18\x3a\x4a\xd9\x66\x15\xb6\x13\xa6\x45\xc0\x09\x01\x96\xd2\xd4\x30\xdc\xef\xbe\x7d\x1f\xe2\xb9\x28\x15\x09\x47\x31\xbd\xa3\xf8\x38\x74\xce\x6b\x94\xca\x80\x60\x29\xf6\x5d\xe4\xaf\x38\xfe\xb6\x6c\x2e\x0a\xa7\x9e\x03\xe2\x07\x6f\x24\x95\x01\x27\x3e\x6c\xc6\xee\xfe\xf6\x74\x68\x97\xa9\xc9\xb2\x48\xa5\x20\x58\xe3\xee\x10\x76\xcb\x53\x55\x5d\x7f\x14\xe2\x90\xa9\x01\xb6\x82\x52\x09\x1a\x57\xa1\x76\xd5\xba\xbf\xd9\xd5\xf7\x65\xe3\x49\x7c\x7d\xee\x34\xa6\xf3\x52\xaa\x22\x0e\xc6\x2b\xea\x74\xd1\xfe\x04\xc5\x77\x9e\x73\x51\x2d\x42\x5c\x81\x1e\xcb\xf6\x79\x3f\x94\x65\xee\xb5\x33\xc6\xcf\x44\xeb\x10\x71\x15\x99\x12\xc7\xae\x88\x3a\xb2\x89\x1c\xab\x6f\x77\x1f\x8b\xb5\xdd\x8c\x8a\x36\xd7\x82\x6f\xf0\xe1\x7f\xa6\x21\xd6\xf5\x04\x10\x3a\xd4\x23\xf6\x29\x35\x31\x41\xcd\x26\x87\x49\x69\xda\x0f\x3e\xcf\xf6\xd8\x28\x35\x2a\xb1\x16\x72\xa2\x7e\x7d\xa8\xca\x76\x95\x05\x7d\x5f\x2e\xcb\x7a\xe8\xe1\x61\x07\xb3\x80\x06\x78\x35\x9d\x85\xca\x9d\xc8\x50\x72\x61\xba\xef\xf5\x8f\x97\x11\x08\x4c\xfa\xff\x04\xb3\x1e\xe5\xc2\x8c\x12\x82\x30\xe4\xfa\xa5\x7c\xbf\xcd\xde\xc0\x77\x32\xfd\x22\xc1\x28\xb7\xf5\xf4\xab\xc5\xfd\x72\xf3\xb8\xbf\x5f\xed\x7e\x6c\x1e\xbf\x75\x47\x8d\x96\x61\x9f\x30\xad\x7e\xce\x4b\x28\x52\xc6\x54\x80\xc4\x36\xa7\x5b\xf7\xdb\xf4\x28\xb1\xaf\x35\x12\xa5\xcf\xb3\x71\x3f\x4c\x87\x91\x43\xec\x3d\x15\x47\x91\xe9\x01\x1c\x7f\xa4\x0f\xe0\xc6\xf3\x08\xac\x19\x3f\xd4\x0d\x19\x66\x5c\x8c\x27\x81\xd3\x93\xcb\xf3\x6d\x79\xca\xe7\xbc\xad\x29\xe3\xca\x22\x63\xee\x16\x7f\xec\x1f\x57\xdf\x57\x8b\xdb\xfd\xf5\xd3\xe3\x62\xb7\xde\xdc\xef\xd7\xf7\xfb\xed\x6a\xb9\xb9\xbf\xde\xfa\x7b\x11\x31\x81\x44\x92\xae\x40\xae\x4f\xea\x6f\x4b\x43\xf8\x73\x24\x29\x74\x6e\x62\x8f\x56\x01\xe1\xa3\xfb\x82\xd4\x5a\x66\x75\xaf\xe8\xa2\xd0\xd7\x60\x9d\x30\xb1\x86\x39\x23\x34\xdb\x86\xf5\x84\xda\x9f\x0a\x7a\x24\x64\x4f\x59\x0c\xd6\xb4\xee\xe0\x4a\x2c\xd3\xf5\xff\xe2\x3e\xcf\x62\x88\x90\x66\xdb\xab\x14\x62\xd8\x0e\x53\x91\x3a\xca\xd2\x90\x06\x4e\x36\xf6\xf7\x53\x59\x9d\x0e\x3e\xd4\x1b\x3e\x28\x41\x04\x6e\xe3\xdb\xab\xe5\x6a\xf2\x79\x41\x01\x9f\xf9\x3f\xb3\xe2\x8b\x28\x9e\x07\x29\x20\x13\x2c\x42\x5a\xe1\xc3\xd5\x27\x1b\x70\xfb\x50\x6c\x00\x9d\x29\xa8\xca\xe1\xea\xcb\x44\x94\x0a\xe8\xb9\xba\x8f\xf0\x06\x85\x2b\xa0\xf9\x2b\x93\x0c\x6c\x7e\x61\xcd\x4f\x7c\x50\xbb\x83\xc3\x71\xa8\x30\x3e\xcd\x26\x2f\xc8\x5a\xfd\xea\xbf\xe3\x2b\x97\xa9\x2d\x26\x3f\x43\x73\x2d\x1a\x31\x4a\xdd\x99\x4c\x25\x5e\x3b\xa6\x4d\x36\x8c\x7b\x38\x97\xfd\x74\x83\x15\x44\xd8\x83\xd1\x95\x30\xcd\x3d\xbc\x2f\xfb\xd8\xbd\x7d\xa7\x22\xe7\xa1\xd2\x2e\x7f\xf3\xf3\x52\x4b\x9e\x5a\x6b\x6c\x53\x56\x87\x8d\x31\x98\x50\xb4\x31\x43\xbf\x76\x4f\xd6\x7c\xa6\xc1\xca\x06\x60\xb8\xba\x1b\x43\x4b\xae\x21\x87\x67\x31\x07\x7d\x1b\x2d\x53\xf3\xdc\x10\x77\x7e\x20\x32\xe1\xae\xa8\xb5\x2b\x71\x89\x2e\xf3\x33\xa9\x52\x3f\x98\x46\x08\x26\xf6\x66\x98\x5f\xda\x04\x59\x96\xe5\xab\xbf\x0d\x26\x48\x31\x63\x5a\xde\xde\x3f\x3a\xa0\xcc\xa7\x4d\x25\xca\x0c\x89\x2d\x66\xc3\xe2\x9a\x97\x2f\x53\x41\x4a\xca\x4c\xc2\x71\x99\xb9\x5a\x2c\x57\xfb\x0e\x61\x46\x99\x71\x0f\xaf\x5d\x98\x6e\xb1\xf6\xf2\x20\x3e\x64\x27\xec\x46\x99\x11\x01\x02\x57\x96\x2f\x59\xde\x93\x4b\x4e\x23\x01\xb0\xd1\x42\xce\x03\x66\xb9\x04\x6d\xec\x45\x87\x33\x85\x07\xa1\xa5\xc4\x3b\x04\xb3\x6d\x7b\xe0\xed\xb2\xdd\x82\x25\x14\xcd\x24\x1a\xe0\x81\xa3\x10\xe6\xa2\xd0\x07\x51\xbd\xa2\xf6\x86\x3b\x46\x38\xc1\x0a\x9e\xf5\xc8\xf9\x21\x6a\x97\xb1\x9b\x53\xde\x0f\xb1\x46\xec\x9b\x23\x14\xd7\x53\x19\x74\xca\x49\x62\x25\x41\x7d\x32\xf0\xad\x50\x53\x0e\x12\xe5\x8c\x5a\x31\x8e\xac\xf6\x6d\x03\xcc\x17\x5f\xce\x05\xfb\x28\x47\x15\x5c\x27\x08\xdc\xce\x50\x05\x8f\xf0\x96\xa1\x0e\x98\x5d\xf6\x69\xe0\x46\x72\x45\x91\x90\x75\xac\x20\x53\xe5\xd3\xf6\xda\x5f\x32\x37\x3c\xf5\xc2\xd2\xf6\xdc\xbb\xb2\xe3\xf9\x4e\xbe\x2e\x0c\x84\x72\x9b\x6e\xfb\x62\x2e\xcb\x3c\x17\xfb\xc5\x62\x1f\x90\x19\x90\x1f\xe5\x21\xb5\x21\xa7\x7d\x00\x37\x00\xcb\x4e\x6d\x77\x7c\xde\x88\x58\x18\xd4\x90\x9c\x75\x4e\x31\xa6\x3c\x12\xd2\x53\x9d\xce\xac\xbb\x26\xbc\x28\xca\x23\x08\x3b\x3b\xc9\xce\xf1\xd4\x5d\xe6\xe8\x86\xc7\x34\xc0\x02\xeb\x31\xfb\xdf\xff\xc4\x30\xe4\xe3\xb1\x31\x5e\x06\xcf\xc1\x53\xce\xf4\x32\x28\x4f\x02\x82\xa5\xef\x36\x3d\x28\x8b\x36\x5d\x5c\xeb\x3b\x71\x3c\x0e\xbd\xa7\x86\xd9\x25\x4f\x82\x48\x58\x34\x51\x73\xaa\x8a\x73\xe6\x00\xe5\x89\xe6\x3e\x13\x5c\x35\x2f\xf7\x33\xdb\x0b\x4f\x89\xc1\x00\xb1\x3e\xc9\x5d\x79\xaa\xb0\x0f\x92\x15\xcf\x83\x6c\x8d\xa7\x69\x8a\x52\x04\x2e\x82\xf9\xb2\xf0\xc6\xa1\x03\x00\x07\xe5\xa9\x54\x1e\xce\xbe\x6f\x03\xcc\x7d\x79\xec\x36\x0a\x9e\xea\x24\x0a\x3b\xe6\xf6\xad\x78\xff\x80\xca\x47\x48\x5c\x12\xca\x42\x0f\xfd\x20\x96\x14\x32\xb9\x4a\xc9\xec\x46\x63\xeb\xc5\xbb\x72\xc6\xb4\x91\x72\x19\xc6\xcc\x63\x41\x7f\xb4\xfb\x71\xfb\x23\xca\x53\x33\x4d\xde\xb9\x94\x44\xf7\x4d\xc6\xd5\xee\xeb\x39\x87\x85\x72\x45\xad\x80\x8e\x5f\x3c\x3a\xeb\xe0\x4f\xc1\xc6\x94\x2b\x11\x86\x56\xb1\xae\xd0\x62\x2a\x54\xf7\x37\xf7\xaf\xb3\x53\x46\xc4\x16\x95\x4e\xc7\x5f\x40\x82\x29\xd7\x3a\xb4\xc6\xcc\x28\x40\x01\x79\xde\x53\xcc\xe6\xbe\xd5\x83\x52\x28\xd7\xa0\x95\x4b\xff\x56\xc7\xac\x2e\x35\xd8\x77\xf3\x70\x18\xb8\x20\xcc\x87\x5d\x1c\x22\xe6\x25\x04\x9d\xd1\xff\xa3\x2d\x28\x4c\xdf\x3c\x13\x49\x64\x18\x2d\x37\xf7\xbb\xd5\x76\xb7\x5f\xdf\xef\x56\x8f\xdf\x17\xb7\xfe\xd1\x18\x87\x49\x6f\x57\xb5\x87\xb2\xaa\xd5\x8b\x9f\x86\x61\x40\x2c\xf3\x52\x3c\xbb\xf9\x39\x59\x73\xc3\x20\xe2\xb8\x4c\xac\xef\xd7\xbb\x11\x6d\x9a\x86\x41\xcc\xfd\x6f\x5b\xe4\xf9\x43\x5e\x7a\xd4\x27\x0d\x83\x54\x11\xef\xbf\xb7\x97\x1f\x7b\x1f\xcb\xf9\xc3\x32\xc0\x18\xe2\x98\xa9\xf2\x58\xef\x4f\x75\x7f\x88\xc4\x56\x60\xb5\x8d\x81\x1f\x87\xb1\xcc\xec\x3d\x0a\xdb\x05\x22\xec\xaa\x55\x9f\xf2\x97\x68\x48\x21\xc1\x16\xc0\xfa\xcb\x20\x60\x0b\x59\x98\x20\xae\x50\x9d\xea\xa6\xd4\xd6\xeb\xa1\xbf\x1e\x16\x05\x58\x97\x7e\x2c\xcb\xc3\xdd\xf8\x57\xb0\x84\xaa\xc0\x2b\x6f\x0c\xb1\xb6\x34\xe4\x24\xb5\xe1\xed\xeb\x47\x21\xd4\xe0\xcb\x78\xca\x22\x67\x4e\x29\x50\xf9\x6f\x29\x8e\xeb\x62\xd5\x75\xa2\x42\xae\x28\xe2\x0b\xdc\x6a\x5b\x36\x22\x7f\xf4\x63\x27\x8f\x26\x0c\x24\xea\x09\xa0\xd0\xa3\xbb\x82\xc9\x90\x28\x0e\x11\x1f\xe2\xee\x09\x5a\xd6\x5a\xcf\x32\xff\x7d\x91\x8a\x89\x1e\xe8\x13\xdf\xa0\x0a\xd0\xc7\xcc\x02\xdf\x2e\x04\x81\xea\xb4\x76\x94\xc8\xf3\x67\x7f\x96\x38\x64\x9a\x79\x06\xfd\x17\x9b\xb7\x66\x65\xe1\x85\x1e\xba\x61\xa9\x41\x6c\xd5\x02\x2b\xa1\xfe\xaf\x09\xd7\x38\x1b\x7c\xe7\x62\xdc\x18\x0d\x93\x24\x40\xd3\x93\x5a\xbc\xc1\xb8\x6c\x1b\x26\x2a\x41\x56\xcc\x00\x9b\x3b\xbc\xd9\x89\x0e\x51\x42\x3a\xab\xd7\xaa\x7c\x3c\x15\x45\xd7\xbe\xa7\xa1\x10\x14\x4b\xc7\x9e\x97\xfd\x23\x6b\x5e\x06\x8f\x41\x28\x6a\x6d\x16\xeb\xf5\x72\xb3\xe9\x17\xdd\x50\x68\x02\x71\xaf\x4d\xbf\xc8\xf3\x9b\x76\x67\xbf\xb4\xd1\x85\x32\x61\x5e\x58\x77\x59\x4a\xb8\xa9\x32\x98\xd8\x9f\xd0\x50\x49\xad\x7b\x10\x13\x1a\x1b\x4d\x06\xe8\x24\xd0\x03\x64\xea\x1e\xd7\x21\x7f\x49\x9a\x01\x52\xbc\xf4\x75\xf9\x5e\xd8\xca\x6a\x79\x25\xea\x4c\x4d\x6e\xa4\x69\x1f\xe1\xd4\x39\xcd\x9a\x48\x94\xd5\xc7\x58\x66\xe5\xf2\x4b\x64\x62\x8a\x8a\x23\x6f\xf0\xbf\xc6\xb6\x23\x6d\x19\x76\xda\x75\x8e\x82\xd0\xaa\x8c\x3a\x85\xc3\x9d\x23\x9b\x9f\x21\xdf\xfd\xf0\x94\x11\x97\xb4\xbb\xc2\xfa\x6c\x8f\x3d\x0a\x20\xc6\x12\xe8\x73\xf6\xe6\xca\xf4\xbf\x4d\x4e\x64\xac\xd4\x3e\xea\xad\xdf\x94\xd5\xea\x54\x95\x93\x21\x54\x4a\xec\x7f\x34\x59\x63\x9b\x5b\xb6\x29\xfc\x9b\x3f\xac\xe3\x2e\xb2\x18\x57\xeb\x27\xd7\xcc\xa4\x55\xe2\x85\xe6\xc5\xc3\x51\xee\x44\x37\xff\x22\x06\x2c\x76\xd6\x47\xcd\x05\x99\xf5\x8b\x30\x71\x1a\x71\x41\xa2\xd4\xa1\xaa\xbc\xc5\xdd\xa7\xbb\x54\xc4\xc1\x6a\x54\xbd\x89\xfc\x04\x0f\x50\xdd\x65\xaa\x2a\xfb\xea\x51\x14\x46\xd2\x1a\x49\xfb\x54\x7d\xe4\x5c\x77\xf6\xa8\xa3\x30\x4d\x23\x1f\xe9\xb4\x09\xdd\x00\xa7\xe1\x27\x55\x14\x71\x92\x5a\x00\x73\xa6\x9c\xf3\xd7\x85\x9b\x15\x07\x1a\xa7\xa9\x93\x6c\x1e\x59\x07\xfb\x21\x82\xe1\x05\x1a\xab\xef\xf0\x1d\xb0\x20\x35\xa6\xb1\xd3\x28\x96\x34\x25\xbd\x9f\xcb\xc8\x56\x89\x46\xb1\x16\x48\x73\xe8\x64\x5e\xbe\x38\xe9\xb2\xf1\x57\x25\x81\x45\x7a\xdd\x94\x55\x63\xe3\xea\x3e\x05\x8f\x12\x2a\x31\x33\x45\xc2\xf1\xa6\x98\x7e\x14\xa8\xf6\x60\x81\xdb\xcd\xd3\xf5\x4d\x59\x7d\x11\xd3\x9f\x92\x26\x89\x23\x9a\x23\x88\x7d\xac\x98\x48\xa3\x34\xe5\x08\xf9\x6a\x73\xad\x1b\x91\xe5\xdb\xd2\x34\x03\x4f\x3c\x1a\xa5\x2a\xf0\x66\x30\x8b\x4e\x64\xec\xf2\xa3\x4a\x81\x63\xd7\x66\xe8\x01\x3a\x51\xea\xa1\x91\xa0\xd6\xd0\x46\xb5\x67\xb3\xc0\x57\xd0\x3d\xcb\x9e\xa2\xd2\x68\x38\xd0\xb2\xdd\x0e\x96\x99\x48\xa4\x02\xbb\x37\x3d\xa5\x73\xa0\xc4\xb1\x28\x34\x82\xa7\xfc\x58\x11\x88\xc4\x65\xc1\xab\xe6\x65\x57\x4e\x5e\x62\xc9\x18\x0a\x77\x1d\x73\xf1\xb1\x3d\x82\xca\x4c\xa6\xae\xcb\x93\xcc\x2f\x80\xf3\x69\x24\x85\x40\x8d\x96\x63\x55\x96\xa6\x87\x87\xd2\x48\x6a\x82\xbb\x47\x56\xb7\x93\x01\xcb\x8b\xd9\x34\x20\x8f\x14\x49\xa3\xc1\xa4\x68\xaf\xf6\x02\xa8\x75\x98\xcc\x47\x9a\x12\x64\x6d\x3a\x85\x48\xbb\xaf\x95\x93\xee\x77\xa4\x8d\xc6\xe0\x54\xa2\xaf\xfc\x9f\xe5\x69\x77\x92\x60\x9d\x4d\xfd\x45\x9a\x40\x61\x0e\xe5\xf0\x04\x75\x8f\xcd\xa7\x91\x49\x79\x0a\xc3\xb7\xf2\x47\x99\xbf\xee\xca\xce\xd8\xb7\xfb\xa2\x38\x08\x78\xe0\x0a\x26\xef\x5f\xa1\x2a\x6f\xcb\xa6\x81\xea\x63\xa6\x02\x1b\x07\x89\x42\xe5\x50\x91\x43\x53\x4e\xc0\x69\x34\x26\x81\x8a\x86\x3b\xae\x25\x1e\x74\x7c\x07\x1a\x93\x28\x08\x79\x87\xfe\xaf\xba\x3f\x4b\x6b\x24\x8b\xd8\xb1\x07\x91\xe9\x5d\x69\x01\x1c\xf3\x4d\xfd\x98\x48\xcb\x4c\xaf\xa1\xf9\x9a\x3d\xbf\xa0\xcc\xc2\xe4\x37\x51\x22\x91\x74\xaf\x5d\x89\x77\x68\x47\xf0\x8f\xc9\x50\x60\x58\x15\x3e\x88\xe2\x63\x6f\x57\x11\x95\x75\x8d\xa3\x98\x11\xeb\xff\x7e\xbd\x1c\x7a\x00\xb6\x7f\x17\x28\xcc\x6b\x23\xaa\xda\x89\x78\xf9\x83\x8c\x62\x7b\xe6\x4e\xfc\xc4\xaa\x06\x22\x1c\xc6\x93\x35\x66\x91\x6d\x76\xdb\x9b\xd1\x59\xd4\x31\x3a\xbc\xe1\x3c\x4d\x91\x75\x74\xc8\x8a\xab\x8e\xfe\x44\x63\xae\x48\xd4\xe9\x13\xd6\x7d\x8f\x41\x3b\x44\x4d\xfb\xff\x94\x5d\xd6\x16\x87\x5a\x63\x6d\x18\xfd\xcd\x00\x7e\x7f\xf8\x73\x72\xbb\xa2\x40\x30\xc0\xc0\xfa\x0d\x7a\x32\x00\x8d\x23\x16\x22\x26\xf3\x54\x64\xff\x6d\xd7\xfe\x91\xb8\x1b\x8d\xa3\x38\x44\xd4\x6e\xe7\x32\x32\x67\x59\xf1\x7f\xfc\xd7\xdf\xaa\x21\xc7\x31\x81\xc0\x21\xfe\x97\x50\x35\xed\x0b\x2f\x1a\xb8\x83\x06\x65\xf0\x2e\x31\x57\xa7\x27\xa1\x11\xe2\xd6\x31\x0d\x7e\xa8\xbc\xf4\xea\x39\xee\x60\xf2\x31\x46\x94\xe3\x88\xba\x5a\xf3\xd5\xc7\x52\x14\x3a\xd3\x1d\x59\x94\xc6\x89\xe2\x68\xaa\xdf\x88\xea\x19\x1a\x9b\x0b\x77\xab\x89\x1b\x93\x06\xc4\xe2\x5c\xe0\x67\x83\x0e\xb6\xb9\x25\x1a\xb8\xc3\x82\x10\xe9\x50\x5c\x57\x95\x28\xd4\xcb\xe4\xe1\x09\x2e\xe2\xa1\x0c\x64\x1b\x73\xb6\xd3\x11\xc5\xad\x3e\x6f\x3b\xc6\x22\x0d\xac\x62\x80\x2a\x07\xe1\x68\x2c\x84\x88\xbd\x9d\x15\x14\x30\x1b\x32\xc5\x42\x71\x33\x70\x0f\xf5\xfb\xa9\x0b\x59\xda\x09\x6d\x5f\x8a\x99\x6a\x47\x2c\x95\x40\x86\x0a\x1c\xa0\x7a\x86\x42\x7d\xa0\x0c\xef\xae\x7c\x7e\xee\xb6\x8d\x58\x71\x82\x20\xfc\x6e\x39\x99\xeb\x86\xc5\x2a\x0a\xb0\x27\x7c\xb5\xfe\xf6\xfb\x69\xb0\x6c\xb9\xc3\x5a\x10\xcb\x5e\xc8\xf3\xf2\x7d\xc4\x70\x9a\xcd\xdf\x63\x2d\x13\x7c\x5e\x59\x91\x35\x93\x2f\xfc\x9b\x53\xb2\x3d\x83\x71\x7d\x55\xb0\x1a\x68\xe3\x4a\xb9\x1b\x07\x9c\x61\xbb\xac\xc2\x76\xdf\x42\x3b\x89\xf7\xcf\x4f\x0e\x51\x8a\x75\xe6\x7d\x3b\x19\xb0\x81\x34\x0a\x78\xfe\xe6\x25\x82\x26\x58\x7d\x29\xe0\xdd\x6a\x92\xcf\x23\x0e\x62\x43\xac\x74\x09\xf6\x84\x16\xf7\xd7\x9b\xbb\xfd\xf5\xea\x76\xf1\xa7\x7f\x42\x86\xdb\x0a\x01\xfc\x7c\x11\xa7\xda\xaa\xa9\x5d\x8d\xda\x5a\xe3\x2f\x4e\x02\x99\x20\x97\xb0\x3e\x56\x20\x34\x3a\x6b\xce\x2e\xca\x49\xa0\x6d\x15\x6e\xfb\x2e\x8e\x6d\xee\xf5\x3f\xf7\x95\x09\x89\x6c\xb7\xd8\x2b\x66\xb7\xf7\x0c\x5b\x43\x75\x53\x95\x1f\xdd\xa8\x98\x24\xbc\x13\x47\xf1\xd4\xc1\xfa\xa6\xac\xbe\x43\xa1\xa7\xb5\xc8\x84\x24\x31\xc6\x15\xed\xbd\x3c\x3c\xa0\x66\xc9\x85\xeb\x22\x42\xf8\x0e\x4f\x57\x8d\x1c\xd2\xcd\xba\x95\x3b\x21\x4a\x47\x61\xb7\x3f\x5c\xc4\x39\x4f\x4e\x0f\xd4\xc2\xd5\xda\x5c\xca\x5a\x36\x5c\x14\xf7\xf9\x9b\xb3\x72\xbe\xad\xf0\x8f\x71\xbf\xf8\xff\x8b\x73\x4f\x09\x18\x34\xa1\x5c\x0d\x9a\xc9\x88\x24\x9c\xed\x24\x27\x34\x25\xd8\xab\x3b\x56\xd0\x41\xc1\x1c\x66\x7c\x08\xd4\x4a\x58\xc0\xd0\x57\x04\x0d\xd7\x7f\x00\xbc\x3e\x15\x48\x0d\xeb\x96\xd6\x84\x69\x81\x21\x49\x1b\x45\x36\x16\xcb\x85\xd8\x77\xd2\x0d\x80\x08\x55\x1a\x84\xfa\xef\x29\xab\x11\xd4\x57\x0f\x5d\xd9\x69\xc2\x69\x12\xd0\x41\xa1\x1a\x2a\x94\x73\x98\x5c\x32\x67\xd4\xa9\xb6\xe1\xf9\xf5\x40\xf1\x92\x26\x9c\x6b\x2c\xa9\xec\x1d\x80\xf3\xb1\x9c\xac\x2a\xc9\x70\xe6\xf0\x48\x48\x6b\x10\xd9\x74\x5a\x6d\x17\x67\xc1\x79\xbf\x32\xe1\x89\x95\xb3\xb7\xe1\xe5\xaf\x96\x06\xff\x21\x25\x03\x35\xa0\x79\x3f\x54\xe0\x74\xde\xdd\x80\x28\x0d\xb8\xdb\x12\xf6\xba\x9c\x45\xec\x0e\x97\xb7\x24\x4a\x6d\x2c\xfe\x78\xaa\x87\x1a\x2e\x34\x89\x63\x82\xfd\xcf\xbf\x44\xf1\x50\x36\xfb\xee\xcf\x89\xb4\xd6\xc6\x16\x4d\xfe\x09\x0c\x2d\x89\x55\x12\xbb\xe2\xc7\xbd\x78\xbb\x1d\x6e\x96\x49\x12\x02\x2e\x59\x18\xa7\x54\x1f\xbd\x24\xe4\xb4\x6c\x3b\x3e\x65\xa2\xa0\x37\x1c\x7f\x2c\xf3\xbc\xbe\xfa\x38\x07\xd4\x24\x69\x20\xd1\x7e\x64\x7b\xc8\x9a\x97\xd1\xaf\x4a\x99\xe5\xca\xbc\x88\xda\xcd\x69\xeb\x97\xed\x0f\x27\x29\xc2\xf0\x71\x1b\xf2\x82\x90\xa3\x27\xeb\x07\xa6\x4c\x7b\x90\xec\xe9\x63\x59\x3a\x8d\xc4\xa7\x22\x9b\xf6\xad\x12\x11\x04\x28\xa4\xac\x51\x58\x03\x6b\x8f\xe3\x01\x32\x88\xb0\xab\xb4\x5a\xd4\x75\xff\xd2\x48\xae\x34\xed\xb4\x99\xf0\x5a\xbe\x8a\x4a\x77\x56\x17\x34\x91\x51\x82\xea\xe6\x7b\x79\xfa\x78\x38\x35\xbb\x12\xc1\x77\xbf\xdc\x63\xc6\x3f\x44\xc6\x29\x85\x11\x71\xc2\xb2\x0f\xa6\x10\x8d\xe9\x44\x1e\x9f\x45\x85\x46\x3a\xa9\xda\x45\x55\xad\x8b\xe6\x26\x83\x5c\x33\x7f\xa5\x2a\xa1\xa2\x87\x21\xd8\x9f\x39\x5b\x02\x99\x3f\xbb\x0e\x52\x6d\x0b\x60\x96\x84\xde\x3b\x64\xd3\x44\xd3\x00\x41\x65\xfb\x53\x71\x14\xea\xf5\x01\x9a\x73\xc6\x09\x4d\x34\x27\x08\x64\x7d\xb3\xf8\x93\xf9\x37\xc2\xbf\xe2\x33\xf2\x29\x34\xd1\x09\xc1\xde\x85\xbf\x4f\x03\xb3\xa2\xf9\xa9\x0a\x51\x98\x52\x57\xca\xf6\x6a\x16\xeb\xe2\x5a\x7c\x4c\xc1\xf8\x09\x44\x92\xb8\xc0\xf1\xa9\xab\x15\xb9\x8e\x54\x62\x02\xab\x54\xb5\x74\xc8\x1e\x51\x35\x57\x1d\xff\x64\xfc\x8d\x86\x44\x4e\x2f\x18\x4d\x1d\x4e\x45\x6f\xea\xde\x6e\xa9\x84\xde\x95\x45\xf3\x32\x9d\x9e\x46\x09\xa2\xdd\x0f\xbb\xae\xc4\x7b\x3e\xcc\x90\x12\xa3\xc3\xd0\x1a\xd5\xb8\x12\xf7\xa7\x35\xa8\x34\x88\xac\x82\x60\x56\x23\xf6\x5a\x65\x47\x31\x51\x2a\xa4\x29\x91\x04\x35\x21\x9a\x4a\x68\xb8\x06\x91\xf7\x7a\xdb\x6e\x04\x0d\x15\x93\x4e\xfe\x34\xff\x18\xf2\x93\x68\xca\x94\x42\x76\xe0\x6e\xf3\xf4\x6b\xec\x70\xca\x40\xd2\x2e\x65\xdd\x2a\x71\x38\x20\x81\x4c\x64\x93\x72\x65\xca\x0c\x27\xe0\x4a\x16\xeb\xe2\x2d\x6b\x06\xa8\xa3\x5f\xbc\x50\xbe\x0a\x93\xf2\x40\x9a\x74\x10\xe0\xcf\x4c\x91\xf9\xbb\xc6\x23\x8a\x61\xd0\xfe\x98\x0b\x85\xeb\x39\x7e\x6a\x33\xd4\x84\x9e\xe4\x38\xfe\x93\x10\x10\xea\x2e\xdb\x02\x8c\x31\x9f\x72\x47\xc3\x28\x44\x6e\x72\x3b\x6b\x7e\x0e\x9a\x1e\x69\xa8\x03\x84\x25\xe7\xe5\x87\xc8\x9b\x8f\xde\x3b\x8d\xa6\x51\x42\xbc\x95\x6e\xbb\xb0\x7a\x6a\xc8\xfc\x85\xc7\x69\x60\x3d\x14\x41\x1c\x76\xef\xe5\x75\xf6\x56\x4f\xb7\xf6\x34\x16\x06\xdf\xfd\x55\x9e\x1d\xb2\xe2\x62\x7e\x9f\xc6\xca\xba\xbb\x2a\xd7\x1d\xf3\x7f\xd6\x31\x2a\xab\x5d\x67\x0a\xc6\x1d\x98\x34\x25\x04\x29\x2a\x8d\x78\x85\x6d\x21\x8e\xf5\x4b\x39\x9d\x6b\x29\x84\x21\xed\x6a\x5e\xb7\x99\x85\xb8\x8d\xde\xec\x34\x35\x14\x69\x5b\xed\x32\xea\x4f\x2d\x98\xc2\xf4\x62\x75\xf7\xc5\xbf\xf0\xe3\xd7\x26\x15\xb1\x35\x57\x6e\x37\xe2\xac\x99\xc8\x8b\xd3\x54\x08\xcb\x4c\x3e\x58\xeb\xab\xce\x58\xe0\x26\x33\xdd\x26\x98\x0a\x15\x92\xde\x7e\xc9\x3a\xa7\xcc\xb5\x61\x53\x29\x12\xe4\x1d\x77\x52\x46\x55\x79\x78\x7c\xef\xf0\x32\xa9\xe2\x11\xba\x22\x61\x63\xe0\x09\xf1\xd5\x7d\xb3\x23\x55\x21\x15\xf1\x20\x9e\x2b\x6b\xdf\x8d\x1e\x5f\xb3\xa6\x01\x62\x5b\xdb\xfb\xf9\x74\xfc\x51\x56\x1e\xfa\x91\x6a\x88\x87\xe0\x82\x3d\x25\xa3\x8a\x52\x0a\x11\x8d\x60\x00\xa0\x1f\x72\xa7\x26\x77\x1b\xd2\x00\x45\xab\xd4\xa9\x6a\x77\xde\xee\xbd\x06\x65\x51\xda\xcf\x5e\x68\x7d\x46\xe5\x94\xa6\x86\x10\x2c\x01\xf8\x87\x62\xf5\xbd\x86\x90\xdb\xd4\x24\x5a\xf7\xa4\x91\x2b\xb8\xec\xa8\x35\x01\x07\x89\x80\x47\xd4\x3d\x33\x1f\x8f\xdc\x9f\x7c\x51\x53\x04\x89\x6d\xd3\x20\x4d\xb7\x6e\xca\x03\x6e\x71\x53\xbe\xa5\x1f\x6c\x2c\x8c\xde\xd5\x7f\xad\x29\xe6\x30\x26\x16\x84\x24\x56\x2e\x57\x14\x8f\x28\xb5\xe9\xca\xdd\xf3\x88\x31\x41\x03\x6d\xd5\xbb\xee\x37\xf7\xeb\xbb\x3f\xfc\x59\xa8\xe4\x98\x9c\xa2\xa3\xfc\xee\x75\x5e\x3d\x8f\x0a\x96\x40\xdc\xb7\x98\x36\x47\x28\xbe\x8b\xbc\x4d\x7a\x0b\xf0\xbc\x9c\xcb\xad\x08\xc1\xd2\x08\xfb\x76\xdf\xcb\x1c\xa1\x1f\x93\xb5\x53\x70\x1a\x07\xfd\xe6\xda\x19\x00\xf9\x6b\xe4\x89\xb5\xe0\xaf\xc1\x7a\x24\x4c\x05\xd6\xfc\x30\xa5\xa8\x65\xbd\x0a\x8d\xdd\x0e\xff\x53\x46\xbf\x24\x34\x0c\xe5\x2c\xaf\x44\x3d\x94\x57\xa3\x22\x4a\x59\x1a\x7a\x97\x82\x46\xe4\x8b\xac\xba\xae\xca\xe3\x78\x8a\x8b\x38\x88\x43\xab\x48\xd9\xbc\x88\xf7\x9d\x6f\x66\x8b\x38\x50\xdc\xc6\x68\xc7\xbc\xfc\x80\x6a\x40\x13\x10\x31\x33\x58\x3d\x6b\x2c\x3a\x2b\xef\x59\xff\x54\xc4\x09\xd1\x7d\xbf\xb6\xbd\xa8\x99\xe8\x43\xc4\x09\x67\xaa\x53\xd4\xb2\x40\xae\x81\x01\x28\x15\x71\x4a\x78\xe2\xe9\x78\x1f\xc7\xa6\xfc\x0e\x55\x7d\xaa\x47\x84\x16\x11\xa7\x4c\x0f\x52\x97\xbd\x8f\xae\x44\x42\x08\x4e\x25\xec\xfa\xdd\x65\x39\xd4\x4d\x59\xc0\x79\x46\x3a\xb8\xee\x84\x53\xee\xc5\x46\x3b\xbc\xea\xf2\xc7\xe4\xba\x53\xa6\x99\x13\x4b\x5a\xe4\x0d\x6e\x20\x17\x88\x4b\x9f\x81\xe2\x84\x10\x81\x6d\xbc\x17\x6f\x50\x74\x0a\x07\x54\x48\x99\x60\xf1\xa0\x7c\x83\xaa\xca\x34\x0c\x34\x61\xa9\x50\x92\x63\x9b\x45\xf5\x75\xd2\x73\xd4\x93\xd0\x31\x4d\x9c\x32\x8f\x31\x7b\xea\x3f\x0c\x81\x35\x02\x54\xa2\xb0\x4d\xa9\x9b\xaa\x44\x99\x27\x5d\xbe\x2f\xf4\x5f\x27\x0b\x0f\xb5\x16\xdc\xfe\x23\x22\x40\xc5\x1b\xf8\x79\xc4\x4e\x0c\xe8\xdf\x9c\x7a\xe1\xe8\x96\x98\x20\xc2\x3a\x15\xb6\x2e\x3e\xea\x06\x0e\x03\x20\xc8\xc4\x0e\xd3\x7f\x24\x56\x58\x7d\x69\x5e\xaa\xf2\xbd\xfe\xf1\x02\xc5\x17\xab\x52\xdc\xd3\xab\x57\x56\x03\xab\xab\xa9\x09\x23\x54\xa4\xfb\xf5\xe3\x4f\xd2\x1d\x50\x0c\x4b\x42\x8f\x9b\xdb\xd5\xfe\x0e\xa1\x1e\xee\x90\x0c\x18\xa1\x1e\x07\xf2\xb8\xbe\x7a\x42\x48\xf0\x76\xb7\x78\xdc\x75\x23\x54\x68\xbb\x28\xe5\xfb\x6f\x33\x2f\x97\x0c\x74\x6c\x17\xc0\x32\x9f\x67\xcf\x53\x19\x18\xc0\x09\xef\xc4\x02\xad\x29\x85\xdf\x36\x25\x89\x2c\x61\x7f\x79\xff\xe7\xdf\xf3\xed\xa0\x92\xa4\x49\xdc\xa7\xed\x87\xac\x50\x62\xf2\xd2\x4a\x22\x03\x84\xbd\x3f\x0a\xf5\x02\xf9\x30\x9d\x93\x44\xba\xb2\x2d\xb6\x97\x45\x9e\x4b\xa1\x50\xe0\xec\xb3\xc6\x8e\xa4\xa1\xc0\xe5\xd0\xad\xc8\xa3\xa5\x5b\x32\x4a\x13\x97\x61\xaf\x2b\xf0\x9b\xa8\x64\xa9\xb4\xe2\x02\xe8\x30\xf6\x20\x9a\x51\x3d\xee\xd3\xa4\x5d\xf2\x88\xa5\x41\xf7\x1b\xaf\xe1\x6d\xb6\x9c\x22\xb9\x8c\xbc\x3f\xf6\x5e\x42\xd3\x94\xd5\xbe\x93\xbd\x6d\x8f\x4a\xe4\xd6\x57\x5d\xbd\x42\x72\xad\x51\x16\xe6\xf8\x82\xeb\xc1\x7e\x80\x30\x93\x51\xc4\x89\x35\xbb\xc1\x9c\xf1\x6b\xf6\xfc\xd2\x1d\x02\xe9\xc5\xb8\x1e\x10\x2f\x39\xd3\x8c\x95\xb1\xd4\x34\xee\x0c\xb6\x70\x51\xdf\x4f\xae\x37\x96\x06\x2b\x04\x3e\x45\xee\xfd\x1e\xa8\x8c\x75\xe8\x29\x8c\x0e\xdd\xf9\x45\xd4\xf9\xa0\xc5\x29\x93\x88\x61\x1a\xb0\x90\x42\x3e\xf4\x39\x6e\x77\x38\x8e\x31\x80\xf2\xb6\xdd\x1b\xd3\x45\x96\x77\x59\xfe\x3a\xb9\x94\x94\x05\xfe\xa1\x3d\x42\x7d\x04\x54\x45\xb0\x4b\xf1\x64\x60\xd4\xc9\x78\x5f\x1d\xcf\x63\x20\x99\x1a\xc0\x05\xe5\x0f\x28\xba\xce\xa9\x14\xdc\x12\xc5\xbe\x54\x99\x76\x42\xd8\x33\x30\xf4\xf9\x4a\xb5\x14\x71\xec\x25\x8c\xbe\x43\xd3\x5b\xfe\xf7\xab\xb1\x94\x0c\x22\xe1\x1d\xef\xde\xa0\x5a\x1f\x06\xda\x24\xa3\x99\x2b\x4d\x84\x0e\xee\x2b\x7f\x69\x8a\xd1\xb0\x8b\x4a\xba\xc6\x93\x54\x4a\x5a\x88\x95\x38\xd5\xf0\x08\x1a\x0e\xc7\x41\x2b\x58\x2a\x13\x20\x6a\x7f\xbd\xdc\xec\x1f\xbe\x2e\xb6\x2b\x3a\x02\x1e\x4a\xcd\x12\x2c\xb3\xb4\x5b\x95\x57\x06\x9e\xdc\x28\xcd\x8c\xd5\x76\x16\x59\x61\xeb\x7e\x8d\xc8\xad\x02\x8d\xb5\xe5\x6c\xd7\x10\x3f\xd6\xd8\xde\x9c\x4d\x2d\x11\x9a\xda\x40\x25\x26\x9d\x36\x09\xa1\x55\x09\x6f\xa3\x4c\xc4\x62\xeb\xf2\x1a\x56\xb5\x3a\x41\x3e\x25\x8e\xcc\x2f\x4e\x10\xc5\xd8\xb8\xff\x93\xec\xf3\xbe\xa5\x31\x0a\x0f\x25\xa8\x10\x01\x24\xe8\x81\x6f\x17\xb1\x36\xff\xcc\xb3\x73\xc5\xd7\x4b\x10\xc2\xe9\xb7\xaa\x10\x7b\x24\xe7\x62\xc7\xf3\xe5\x0c\x69\xa8\x44\x1b\x02\x67\x8e\x6b\x2d\x8a\x97\x03\x56\xdd\xf8\x56\xab\x20\x08\xd3\xa0\x03\xa4\x38\x5d\xbc\x0e\x37\xeb\x9f\xb9\x0a\x02\xc1\x86\x49\x02\x5a\x36\xf4\x07\x0d\x86\x20\x99\x53\x19\xaa\x47\x59\xb5\x22\x29\xc3\x1c\xe8\x28\xd4\x2b\x1a\xd5\x8d\x1f\x8d\xa2\x52\xc9\xbe\x24\xfc\x08\x2a\x3b\x66\x53\xf7\x1e\xaa\x18\xb1\xbc\x88\x7f\x6d\xd6\xf7\xc3\x97\x59\xf1\x80\x71\xee\x5f\x4f\x03\x55\xd5\x26\xfd\x7a\xfa\x25\x5c\x58\x05\xf4\x3b\x6c\xa2\x8e\xd1\x24\x6e\x48\xc8\x62\xb0\xe5\xbb\xc6\x19\xa9\x0f\xd6\x3c\x15\x3a\x88\xb7\xe7\x9e\x26\xfe\xef\x71\x84\xb2\xa5\xa7\xa2\x9d\x16\x6e\xf1\xb5\x9e\x32\xbb\xcd\x7c\xc0\xad\x22\x19\xa5\xb1\xd7\x30\xfb\x22\x0a\x31\xbe\x61\x91\x34\x5e\x7e\xcd\xee\x22\xf5\x20\xf1\x56\x71\x20\x8c\x33\x9d\xd9\x3f\xdd\xef\x6f\x37\xcb\x6f\xfb\xdd\xfa\xce\x6b\xfe\x50\x15\x27\xb1\x03\xdf\x5a\xf8\xd4\xbe\x02\x75\xaa\x54\xf6\x06\x53\xae\x8c\x4a\x38\xc1\x12\x86\x3c\x7d\xbc\xc2\xd9\xc1\xd8\xca\x2c\xfc\x55\x66\xc5\x43\x55\xbe\x65\x7a\x5a\x15\x52\x49\x22\x30\x62\xf6\xf6\x6a\x32\x87\xd1\xb3\x49\x40\x22\xc8\xfc\x7a\x7b\x23\xf2\x1a\x46\x9b\xa8\x1b\x92\x0a\x42\xc4\x00\x25\x58\xd3\xcf\xdb\x5f\x2a\x15\xa9\x77\x6c\x6b\x6c\xcd\xea\x7a\x30\x17\x53\x61\x9b\x63\xa2\x5d\xa5\x45\x03\xd8\x14\x3a\x0d\x9c\x28\xa8\x12\x4c\xe0\xef\xda\x66\xc5\x73\xde\xc9\x83\x5f\x52\x9f\x19\x2e\x91\x4a\x86\x06\xa3\x4d\xe7\x0e\x3d\xcf\x89\x19\x06\x22\x93\x07\x2f\x53\xcb\x0a\x7b\x46\x13\x12\x1b\x33\x22\xd4\xa5\x7a\x5d\x15\x7a\x38\xdd\xa4\x16\x58\x65\xae\x4f\x52\x36\x1f\xea\x50\x16\x30\xaf\x11\x4e\x95\x04\x89\xa1\xae\xad\xd1\x5c\x65\xcd\x10\x3c\xad\x14\xb5\xc2\x31\xba\x12\x59\xd1\xe1\x3d\xc7\x13\x4e\x13\x83\xc6\xa9\xab\xdd\xd7\xfd\xf5\x6a\xb9\xbe\x5b\xdc\x76\xb3\x49\x53\x89\xcc\x08\x51\xab\x2c\xdb\x95\x7d\x11\x91\xf8\x01\xed\x7e\x8c\xe9\x8d\x68\x5e\x30\x83\x17\x24\xf4\x9f\x36\x44\x73\x97\xdc\x6f\x9b\x0e\x1a\xaa\x8c\xe6\xf8\x32\xef\x6d\xd2\x78\x07\x7a\xd2\x16\xf3\x6f\x97\x01\x89\x91\xfa\xad\x28\xc4\xf2\x45\x54\x39\x40\x31\x1b\xfd\x0d\xe3\x3e\x1d\xa4\x0a\x63\x17\xd5\xed\x06\xa3\x75\x5a\x07\xa9\x41\x39\x4e\xe7\x29\x62\x49\x5d\x3e\x75\x9c\x04\x2b\x3a\xd0\x04\xab\x94\xdd\xa7\x49\x64\x01\x51\xcf\xe2\x00\xeb\x7a\xf3\x36\x7d\x2b\x34\x11\x12\x25\x31\x97\x9b\xfb\xef\xab\xc7\xdd\xea\x71\x6f\xff\xb5\x6d\x83\xe6\x1f\x5f\xd7\xbb\xd5\xed\x7a\xeb\xf7\x43\x4d\x43\x8a\x8f\x2f\x1b\xa6\x28\x9a\x46\xb1\xf7\x83\x5d\x35\x2f\x4f\xb5\xee\xb9\x2b\x93\x6f\xa3\x89\x55\xaf\xdf\x76\x7a\xac\x54\x53\x43\x30\x74\x95\x1e\xe9\xe3\xee\xa7\x66\x8c\x62\x0f\xa2\x5d\x3c\x96\x8f\x8b\xdd\x6a\xbb\xdf\x6d\xf6\xdb\xd5\xad\x47\x74\x6b\x26\x01\xa5\xe3\x00\xed\xb9\x46\x75\x05\xcd\x29\x47\xce\x80\x94\x6e\xa3\x98\x1c\xe6\x91\x15\xfd\xc7\x9d\xd1\x22\x02\xea\xee\xa0\x4e\x51\x86\xe0\x6d\xbc\xd9\x4e\x3a\x60\x73\xe5\x71\x1d\x92\x14\xdb\xfb\x8b\xdd\xf6\x8f\x4f\x98\x6f\x3a\x4c\x12\x24\x58\xac\xef\xd7\xbb\xf5\xe2\x76\xbf\xdc\xac\xef\xb7\xfb\x9b\xcd\xe3\xfe\xfb\xfa\xe1\xe1\x76\xb1\x5c\xdd\xad\xee\xbb\xfb\x1e\xa6\x02\xe9\xdd\x3b\xf1\x0a\xce\xee\xc1\x1f\x8a\x02\x8e\xb9\xe9\x32\xab\x10\x37\x95\x15\xcf\x43\x29\x76\xaa\xa3\x88\x11\xd7\x92\xf8\x13\xc4\xf4\xf9\x47\x49\x84\xab\x04\xba\xb4\xf5\xd2\xbe\xe3\x31\xa9\x60\x4e\xc0\xe4\xbe\xd4\x50\xef\x4a\xcc\x40\xe7\x56\x0d\x1d\xcb\x08\x93\xaf\xbf\x4e\xba\x27\x7e\xfe\x9b\xb0\xff\x9c\x57\x9b\xce\xff\x35\x0d\x67\xfe\xcd\xfb\x41\x24\xf8\xcf\xe0\xcf\xfe\xdb\x4c\x9c\xc4\x23\xf2\x4b\xcf\xb9\x99\x5d\x91\x75\xa2\x12\x65\xbc\x78\xf5\xfa\x70\x2c\x2b\xb4\x58\x9a\x5d\xad\x74\x9a\x40\xea\x99\xfe\xed\x64\x9e\x6f\xce\x7c\x9e\xf4\xe8\x34\x8d\xb4\xb7\xf8\x2e\x8f\xa7\x1c\xdd\xb6\xae\x3e\x36\xc6\xd4\x30\x7d\x3f\xd2\x34\x46\x9a\xcf\xef\x27\x61\x45\x4d\xac\xf3\x96\x7f\x94\x29\x30\x99\x38\x79\x55\x05\xc7\xf6\x59\x3f\x88\x8f\x03\x72\xc4\xdc\x10\x41\x53\xec\x96\xa1\xb5\xc2\xd4\x76\x63\x2e\x09\xd4\x22\xb1\x7a\xc8\x0e\x90\xba\x6d\xe0\x88\x35\x99\x45\xde\x7d\xaf\x50\x34\x4c\x46\xe6\xc5\xeb\x06\x0e\x03\x65\x2e\x3f\x0e\x54\xe8\x16\x82\x5b\x51\x37\x57\xa7\x33\x82\xbe\x96\xc6\x22\xb4\xc4\xb1\x5d\xd0\xd0\x9e\xba\xbb\xca\x4f\xb1\x06\x5a\x19\x16\x3a\x54\x6c\xd5\xbc\x78\x2f\xa1\x47\x6b\xfc\xd5\xcb\x2a\x69\x4d\x28\x52\xe0\x2c\x03\xa7\x9d\xa9\x8f\xf0\xdf\x0b\xb3\x41\xb3\x04\x4b\x72\xa2\xaa\xc4\x87\xb0\xda\x36\xe3\x11\x26\x22\x98\x68\xbc\x8f\xe4\x61\x6e\xa6\x90\x0c\x6d\x22\x40\x34\xae\x29\xab\xe6\x54\xc0\x1e\x53\x3c\x59\x81\xe8\x56\x49\x93\x5a\xc2\x94\xbd\xae\xeb\x6a\xa8\x7e\x3e\xb7\x31\x18\xc3\x31\x0b\x6e\x83\x90\x9e\xd1\x04\x81\x14\x28\xcb\xfe\x5c\xe6\xfa\xaa\x3c\x75\x6a\xb2\x14\x08\x01\xca\x5d\x13\xc2\xee\x21\xb7\x60\xfa\xa3\x51\x8c\xe1\x4f\xad\x5e\x40\x9f\x72\xc0\x1d\xb8\x67\x0e\x02\x49\x74\xea\x5e\x8c\x3f\xd5\x61\x2a\x10\x33\xfa\xb1\x40\x84\x44\xb5\xfe\x0c\xd5\x0c\xc1\x77\x90\xa1\xde\x4e\x2b\xf6\xc0\x98\x75\x9a\x02\x14\x34\xf5\x22\x3b\x83\xd2\x21\xf0\x20\xb4\x7e\x74\x2e\x5c\x7f\xb0\xe0\xd0\xc9\x79\x38\x51\x08\x03\x47\x12\x7d\x86\xac\xff\x31\x0b\x02\x38\xa5\x91\x70\xa8\x34\x9f\x89\xdf\x00\x2c\xe4\xe4\x91\x02\xa7\xcc\xf2\xe2\x9f\xcf\x22\x77\xe0\x32\xc6\xd5\xb4\x03\x32\xcc\xc8\x7c\xb7\xa3\x12\xab\xc7\xe4\xd8\x0f\x56\x4b\xed\x7f\xa0\xdd\xdb\x38\xfd\x42\xa5\x71\x2b\xca\x94\xa5\x38\xd7\x4f\x45\xdd\x67\x85\x10\xa6\x89\xed\x03\x42\xdd\xec\xdb\xd9\xbd\x76\xc6\x28\xff\x5d\x77\x61\x00\x24\x9c\x61\x62\x8f\x70\x7e\x7b\x16\x5c\xb2\x2f\x83\xa1\x21\xd1\x09\x92\x6c\xae\x45\x96\x7f\x58\x9f\xe5\xb9\x5c\x02\x52\x07\xdc\xed\x4d\xe6\xe7\xf7\x2c\x10\x22\xc2\xe2\xb0\xbf\x37\xb7\xe5\x1b\xba\x79\x7f\x8c\xf5\xa0\x2e\xa5\xa5\x20\xb4\xc0\x3d\x37\x6f\xd7\x06\xe4\x44\x09\x12\x7d\x15\xf5\xcb\xde\x8d\xf3\x3f\x56\xb2\x50\x3a\xb7\xc8\xad\x70\x90\xb1\x29\x25\x0b\xa4\x49\x22\x2b\xa7\xfd\x66\x1d\xad\x60\x27\xea\x57\xd7\xda\x5a\x34\xe7\x12\xa9\x14\x54\x04\x88\x9b\xb2\xaf\xa0\x6d\xbf\xcf\x04\xc4\x83\x0f\x98\xd0\x23\x37\x5c\xf5\x66\x07\xde\x30\xa4\x3d\x1a\xd9\x7c\xb4\x12\x45\x83\x9e\x6b\x4f\x45\x1b\xc5\xe0\x4c\x1f\xdf\xc8\xc1\x7c\xd7\x49\x82\x95\x95\xa5\xca\xcc\x30\x01\x01\x08\x98\x95\x5c\xb6\xdf\xf4\xd4\xd3\xc1\x00\x00\xa2\x5e\xa2\x65\x51\xe8\xab\xd3\xc7\x22\xcf\xc7\xad\xa1\x8b\xb5\xe8\xd9\xcd\x0d\xc0\x40\x2a\x7d\xb1\x05\xdd\xc4\xf3\xb3\xb7\xce\x68\x1a\x5b\x9a\xcf\xa9\x68\x36\xe6\xfa\x22\x2b\xca\x04\x01\xc5\x17\xe7\x80\xea\xe6\x13\xae\x82\x09\x02\x8d\x4d\xad\x1d\x6a\xa6\xac\x7e\x1e\xa1\x6a\x86\xbf\xdd\x10\x63\xf5\x40\xdd\xc4\xd9\x37\xe5\x1e\xff\xf9\xdb\x19\x2a\xcb\xb0\x90\x60\x77\xb9\x3c\x42\xd1\x66\x21\xfe\x26\x19\x1e\x11\x70\x1c\x2e\x54\xe8\xdf\x98\xb9\x0b\xe5\x49\x32\xd8\x1e\x6c\x89\x06\xba\x5b\x39\xba\x45\x86\x6b\x6a\xf9\x6b\x47\x51\xbc\x8e\xae\x37\xa4\x1a\x21\xe0\xd7\xeb\xe5\xaa\xfb\x1b\x8b\x91\x77\xf2\xe5\x76\x71\xd7\xfd\x4d\x01\xb6\x1c\x2f\x88\x5e\x8e\x83\x47\x13\xb5\x2f\x49\xa7\x42\x9e\x35\x18\x8b\xa1\x50\xed\x8c\xe1\x2b\x35\x91\x88\x79\xd7\xd4\xc7\xcb\x5b\x8a\xe3\xae\xb4\x82\x03\xfe\x0a\x62\x29\x70\xad\xbe\x5b\xdd\x6e\xee\x1f\x36\x8f\xbb\xfd\x72\x73\xf7\xb0\xb8\xff\x73\xe8\xaf\x48\x4d\xa2\x01\x39\xf8\x77\x7f\x8c\x7e\x67\x4a\x23\x08\x9d\x45\xea\x5d\xf9\x06\x57\x55\xd9\x1d\x8a\x08\x71\x8d\x26\xc4\x38\x88\xce\x2b\x63\x4e\x0c\xc5\x08\xc2\x31\x35\xb9\x12\xc5\xab\xd7\xd1\x77\x87\x24\x17\x28\xda\xd3\x40\x65\x3b\xe3\x0f\x42\xbd\x0e\x9c\xfa\xfd\xb0\xd8\xda\x6a\xb7\xaf\xd8\xc3\x40\x4d\xc0\x1d\xd6\x44\x51\x6b\x95\xd3\xec\x11\x8f\x38\x0d\x4f\x8c\x26\xc6\xbb\xf0\x3f\x88\x0f\xe8\x68\x74\x33\xf2\x24\x06\x02\xdb\x50\x79\x28\x5f\xa1\x72\x62\xe6\xfe\x10\x0f\xd0\x09\x4c\xb6\xcf\xf3\xaa\x9f\xa5\xdd\x63\x04\x08\x89\x7f\x8c\xcb\x8d\xed\xae\x8c\xaf\xd5\x04\x1a\x79\xdf\x7e\x25\xed\xcd\x50\xa9\x31\x2c\xf6\x95\xcc\xbb\xf6\x67\x7c\x2d\x0f\x4e\xf2\xaf\x9e\x9e\x85\x4b\x14\x24\x41\xc0\xb1\x67\x41\xf8\x63\xb1\xed\x29\x15\xf0\x7e\x73\x6a\x4e\x15\xf8\xe3\x73\x81\x10\x0b\x02\xe6\x5a\xde\xf8\x3e\x88\x1c\xea\xc5\xe4\x06\xb3\x20\xe0\x80\x0c\x51\x84\x1a\x3b\xcb\x39\x79\x01\x3a\xcb\x02\x42\x35\xd6\x20\x6f\x4b\x31\x4c\xeb\x58\x40\x40\x32\x2f\xb5\xdf\xc0\x61\x73\x1c\x69\xec\x0f\x42\x20\x16\xb0\x88\xb1\x4e\xb3\xaa\x12\x0d\xf8\xce\x16\x0b\x38\x4d\xfd\xab\x72\xb3\x79\xba\xbf\x5e\x3d\x6e\xf7\x0f\x9b\xcd\xed\x7e\x71\x7d\x3d\xf6\xcb\x66\x01\x8f\x04\x19\x6a\xe2\xa2\xbe\x82\xdf\xaa\xfd\x18\x6d\x69\x59\x28\x5f\x93\x59\xd1\x8e\xac\x2c\xa6\xd2\x07\x2c\x08\x09\xc7\x28\xeb\xdb\xfa\x69\x3b\x78\x55\x58\x10\xca\x00\xa7\xe7\x8f\xb2\xca\xf5\x56\x18\x68\x3e\xb6\xa0\x4e\x6d\xb4\x3f\x1a\x17\x05\x29\x06\x5a\x5f\x7e\x8e\x01\xb3\xfe\x30\xb5\xea\x6f\xb6\xbf\xe2\xdb\xff\xbb\xd2\xca\xaa\xae\x7e\x1e\x3b\x4c\x08\x0b\xa2\x88\x61\xaf\xee\x61\xb5\x7b\xdc\xfc\xb2\xc7\xc4\x82\x98\x46\x0e\x66\xfc\x56\xbe\x82\xd7\xf9\xd8\xe2\xf7\x4c\xf1\x9d\x17\x98\x08\xe3\x8b\x8d\x95\x40\x3a\xc3\x4b\x79\xaa\xe1\x1b\xc0\xf1\xb7\xd9\xb9\x90\x04\x4a\xdb\xef\x45\x60\x4f\x5f\x6e\xbe\x18\x63\xb2\x20\x21\x4e\x19\xa3\x2a\xdf\xb1\x25\x38\x2c\x03\xb1\x20\x61\x21\x16\x79\x8f\xe2\x23\xeb\x6e\x6d\x22\xac\x14\x00\x2e\x88\xfb\x6a\xe0\xdc\xca\x82\x94\x44\x92\x0e\xd6\x56\xc0\xc2\xeb\xe8\xf6\x88\x40\x3b\x8a\x0c\xa8\x57\x57\x8e\xfe\xfd\x54\x36\x62\x36\x3d\x64\x81\x48\x02\xc9\xc7\x7a\xba\xff\x03\xbd\x6d\x57\x17\xbb\x7e\xf9\x71\xa9\x4e\xa9\x07\x7a\x8d\xc0\x4c\xff\xee\xf3\xe2\x7f\x87\xff\xf9\xc7\xa8\x17\xf9\x49\x99\x81\x05\x02\x12\xe9\x48\xd7\xed\xbd\xb9\xc9\xc5\x73\x1f\x53\xb3\x40\xc6\x02\xcd\x08\x1c\xd5\x61\x73\xc9\x29\x85\x05\x52\x4a\xe8\xf5\x2f\xae\x00\x34\x52\x0d\x27\xdc\x5b\x16\xa8\xc0\x9a\x5e\x3e\xf7\xbe\x0d\x22\x5f\x15\x4d\xf5\x71\x53\x56\x8e\xfd\x34\x7e\x80\x8a\x10\x5c\x26\x55\x27\x8e\x39\x7f\x05\x8a\x06\x41\x7b\xad\x6f\x99\x6a\xb2\x83\xbf\x67\x2a\x8c\x31\x28\xb6\x9c\xac\xed\xf0\xe3\x7f\x27\xed\x66\x81\x92\x09\x1b\x56\x96\xdb\x70\x6a\x96\x3a\xf8\xf9\xbf\xba\xb3\x99\x24\x1d\xb8\xc5\x2f\xb4\x3e\xc7\xe8\xfa\xb1\x3a\xa2\x0e\x04\xb4\x56\x9d\x79\x6a\x9f\x24\x0d\x28\x49\x2c\xd0\xa1\xb5\x4b\xa8\xe0\x0d\x44\xbe\x05\x35\xa8\x6d\x4f\x9e\xb9\x96\x44\x48\x4f\x23\xfb\x4b\xa8\xd7\x73\x69\x09\x16\x68\x2d\x13\xff\xe5\x1a\xc4\xe4\x99\x00\x21\x71\xb7\xcc\xd7\x8f\x20\x74\xfb\xf8\x1c\xc6\x7c\x72\x26\xa0\x56\xb6\x76\xbf\xdd\x2d\x8b\x71\x40\xc7\x02\xd0\x5d\xbb\x6d\x2b\xde\x40\x7f\x17\x95\x3f\x64\x42\x23\xa1\x33\x80\xf0\x15\xa5\x65\xfb\x4e\xd5\xa7\xc3\x6f\xe3\xdf\x64\x40\x53\xb4\xc3\x2f\x5e\xab\xb2\x28\x87\xfc\x53\x46\x02\x12\x80\x63\x8d\x21\xcb\x69\xbc\xff\x31\x12\xc4\x96\x12\xff\x70\xbd\x18\x7f\x4e\x0a\xac\xe4\xef\xd6\x7f\x5c\x82\x51\x9f\x3f\x62\x42\x52\x86\x10\x42\x2b\x79\x72\x87\x45\x6c\x77\x88\x72\xc6\x2d\x42\xfd\xe3\xd8\x94\xaa\x3c\x1c\x45\x05\x4f\xb5\x43\x1a\x3e\x55\xf9\xf8\x57\x11\x1a\x73\xcb\xf1\x75\x4c\x76\x7b\xef\xb6\x0a\x0a\x98\xd4\x90\xba\x6f\xa7\xb1\x55\x7a\xba\xb2\x9b\x0a\x36\x51\x46\xcf\x8e\xb0\x20\x64\x3d\x4c\xde\x16\x60\x26\x23\x12\x23\xac\x9d\xaa\x6f\x81\xa0\xa7\x56\x6f\xdf\x3e\xf1\x19\xea\xae\x97\xa5\x04\x15\xfa\x0e\xb6\x08\x08\xdb\x97\xb2\x71\x4a\xb2\xc7\x4e\x3a\x78\xf6\x35\x23\x4c\x2b\xce\x7c\x7b\xc8\x15\x47\xaa\xf2\xb0\xaa\x54\x14\xc7\xb3\x79\x24\x23\x5c\x02\xb6\xa1\xb0\x86\x3c\xbb\xbe\x91\x88\x71\x54\x77\x7b\xf8\xb2\xbb\x1a\x3d\xdb\x28\xa6\x81\x2f\x72\xd8\xaf\x1b\xc9\xd3\x32\x12\x25\x09\x12\x24\x6c\x7c\x7f\x25\x6a\x78\x7a\x5c\x8f\xd6\x79\x12\x29\x86\xe2\x05\x3e\xfa\xba\x3a\xf5\x7d\xf4\x99\x89\x11\x73\x8a\xaa\x0e\x28\x4a\x8b\xe8\xf6\x51\xe5\x81\x91\x58\x49\xeb\xe6\xfe\xb4\xdb\xdc\xdc\xec\x1f\x1e\x57\xe8\x5f\xbe\xb9\x5f\x75\x23\x74\xa4\x59\x07\xd7\x77\x1c\xf9\xc9\xa4\x49\x98\x46\x6c\xe1\xd1\x06\x26\x13\x0e\xdb\xe4\xb6\xa7\x54\xe1\x4e\x37\x5e\x8f\x2e\xad\x8c\x6e\xce\x8d\xbf\x2f\x4d\x18\x4a\x3f\x2c\xcb\xa2\x80\x59\x43\x48\x3f\xd0\x70\x2b\x37\x8f\x4a\xab\x50\xdd\x97\xd5\xc1\xd7\x24\x19\x11\x5c\x85\xd2\x82\x05\x87\xad\x5b\xd4\xbc\xa3\xdd\xa0\x90\x86\x4e\xc0\xc9\xee\x7f\x7f\xb3\xb3\x3c\xb9\x12\xc9\x18\x16\x0f\xfb\xc9\x36\x47\x55\x63\x44\x05\x01\xb7\xb0\xa7\xaa\x2a\x9b\xda\xd7\xb6\x7d\x08\xcf\x88\x8a\x6c\x8d\xd0\x61\x0d\x67\xb0\xa6\x8c\xa8\x44\x8a\x2e\xf7\xdd\x1f\xad\x64\x60\xf7\xcc\x95\x0e\x94\xa3\x97\x5c\xfd\x7e\x3b\x59\x98\xb4\xb0\x10\x15\xd1\x71\xcf\x67\xd2\x4b\x46\xb4\xb1\x6d\x7a\x5f\xbf\xb0\x0f\x13\xf4\xee\xa5\x2a\x0b\xcb\x6b\xed\x13\x5f\x46\x80\x73\x6c\x17\x5e\x9d\x3e\x6e\x45\xd1\x26\xe2\xab\xe6\x65\x72\x4a\x88\x6d\x08\x73\x65\x91\x55\xdf\x3a\xf4\x2b\x23\x46\x6a\x44\x2c\xed\x2a\x28\x9e\x9f\x45\x0e\xae\x32\xc9\x28\x51\x12\x93\xef\xed\x97\x5d\xf7\x27\xad\xf0\xd2\xda\x58\xdf\x23\x23\x27\xef\x05\x25\x10\xe1\xc6\xed\xda\xf7\x8d\xc2\x42\x93\xa5\xef\x8f\xae\x8a\xb2\x90\x63\xdb\xc7\x95\x64\xcb\x91\x7f\xa0\x1f\x13\x27\xb6\x8f\xb1\xb9\xdf\x3d\x2e\x96\xbb\xfd\xd7\xcd\xed\xf5\xea\x71\x7f\xb5\xb9\x7f\xda\xfa\xcb\x62\x20\x70\xce\x8a\x77\x51\xe9\x36\x4e\xb7\xce\x19\x96\x03\x3b\xfb\xa6\x50\xae\x8d\x57\xc6\x1d\x30\xe0\x2c\x20\x42\xeb\x49\xd0\x42\x43\x26\x70\x69\xb2\x61\xc7\x2b\xe2\x34\xfb\x7b\x48\xc3\xd8\x02\x01\x71\x37\x6b\x03\x9f\xbc\x14\xcd\x54\x44\xab\xff\xee\x98\x4a\x31\x74\xac\xdf\x7d\x1c\x61\xf2\x85\x71\x98\x60\x60\x61\x69\x0d\x3b\x61\x4b\x56\xa4\x3b\x43\x92\x12\xe8\x8d\xcf\x90\x88\xe5\x0e\x25\xcc\x1a\xfe\xd7\xd0\x2c\xe1\xdc\x10\xd2\x8f\x92\x46\xb9\x8d\xfa\xfe\x74\xb8\x83\xba\x16\xcf\xe7\x90\x48\x3f\xd8\x08\x4b\x1d\x13\xc7\xac\x11\xb9\x93\x4e\x68\xef\xd6\xe4\xaa\xd3\x20\xf2\x92\x18\xff\x14\xea\xf5\x58\xfa\xe5\x97\xa6\x0e\x7e\x6a\x53\x8c\x95\xce\x9a\xc5\x33\x14\x5d\x78\x2c\x86\xeb\x8c\xff\x88\xa1\xa8\xa7\x77\x2c\xeb\x26\x53\xa5\x55\x75\xe9\x39\xc9\x8c\x8a\x00\x20\xf6\xa8\xea\xf2\x7d\x07\x3f\x1b\x4c\xbb\xd3\xa8\x1b\x11\x4b\xea\xf4\xcd\x16\xc7\xe3\x85\x5f\x27\xb4\x46\x00\x7e\x01\xef\xf7\x03\xfb\xbc\x8b\xa9\xce\x68\xb9\xa4\x02\x58\xe4\xec\xf3\xa0\xba\x3f\x1d\xae\x41\xe4\x93\x0d\x98\x4a\x10\xd8\xea\xb1\xf3\xfc\x21\x17\x05\x34\x4f\x8f\xb7\x17\xd1\x71\xa3\x17\x40\x91\x20\xe9\x64\xf7\xf5\x57\x6f\x2f\x90\xf8\xc3\x2c\x42\xf1\x9b\xed\x51\x28\xef\x84\xea\x03\x14\xaa\xd2\x00\xa3\x65\xeb\x3a\x8c\x6d\xc4\xdd\xca\x57\xa1\x18\x55\x3a\xb6\x79\xb4\x0b\xfb\x2c\xe5\x6f\x57\xf6\x5a\x15\x8c\x6a\x19\x63\x9b\xfb\x58\x95\x26\x6b\x70\x13\xbf\xca\x1a\x2b\xc8\x78\x0d\x32\x6b\x7a\x5d\x4a\x46\x35\x18\xeb\xe3\xfd\x5c\x2d\x7d\xdb\xa8\x4f\x78\x28\x10\x15\x47\x23\x24\xd0\xaa\xbd\x99\x37\x65\xb5\xda\x7d\xed\x77\x5a\x3f\x9a\xda\x2e\xdb\x7e\x94\x9f\xc3\xe9\x30\x59\x45\x0c\x0f\x51\x48\xf0\x53\xb7\x9c\x4b\x1b\xca\x05\xcc\xbb\x3f\x75\x6a\xc3\xfb\xf6\x35\x6b\x57\xdf\x77\x57\x82\xef\xa0\x24\x7e\x9c\xd0\xa4\xab\xb8\xa1\x0e\x1c\xe8\x9b\xb2\xda\x9c\x1a\x55\x1e\x60\xf4\xbc\x8c\xb6\x69\x7e\x53\x7e\xb5\xee\x51\xd7\x50\x94\x58\xde\x9a\x02\x9b\x18\x35\xa0\x78\x30\x90\xa0\xfb\x15\x53\x86\xb1\xc0\xa4\xb1\xe9\x50\x89\xd7\xb8\x8d\x09\x6b\x8e\x70\x5e\xf8\x66\x8c\x90\x88\xd1\xc1\x42\x64\x5d\x31\x26\x63\x22\xa5\x8d\xe3\x69\x35\x67\xfe\x91\x8c\x11\x61\x7d\x41\x9f\xa1\xd9\x5b\xe9\xed\xf1\x71\x1a\xd8\x39\x01\x3f\x8f\xed\x8e\x91\x55\xed\x0c\x7b\x04\xa1\x5e\xac\x9a\xc4\x64\x74\x98\x60\xb4\x2d\xb4\xbe\xa9\x00\x10\xda\x68\x1d\x14\xd7\xc5\x5b\x99\xa9\x5f\x30\xac\x18\x63\x24\xc1\xa4\x1a\x65\x9c\xce\xa3\x37\x3f\x4a\x10\xbc\xe8\xf5\x6e\xb5\x74\x0a\x9f\x8c\x31\x65\xb0\xe1\xd1\x06\x74\xa7\x22\x6b\x3e\x6c\x75\x75\x88\xbb\x60\x8c\x69\x6b\x49\x7a\xb7\xf6\x78\x03\xc6\x38\xb5\xac\xae\x2f\x65\x99\x8b\xf9\xc7\x34\x5a\x10\x18\x4f\x0c\x56\x55\xcb\x37\xd0\x18\xb4\x58\x63\x78\x61\xc5\xc7\x5c\x5c\x02\x17\xaf\x9e\x0b\x89\xef\xe4\xba\x30\x65\xdd\x5d\x84\xd0\x81\x2b\x73\x7f\x87\xca\xea\x68\x4e\xc2\xfa\x59\x19\x52\xc6\xc2\x84\x61\x6f\x7e\x44\x1a\x39\xb7\x0a\x65\x2c\xd4\x0a\x41\x21\xe8\xb0\x32\xc4\x4d\x30\x16\x91\x20\x76\xc2\xaa\x26\xab\x0e\x88\x69\x42\x86\xcc\xf8\x0c\x89\xb2\xa2\x6c\x87\xb2\xd8\x95\xbb\x4a\x64\xde\x0c\xd2\x29\x4c\x32\x96\x86\x1a\xb1\x3a\x3b\x91\xbf\xd6\xd6\x02\xc3\x1f\x49\x53\xc4\xe1\x7c\xd9\x5d\x2f\xb7\x8d\x28\xb4\xa8\xf4\xdf\x43\x51\x33\x96\xaa\x00\x4b\xaf\xf8\xf6\xae\x97\x9b\xae\xb7\xec\x8f\x43\xca\x3b\xdd\xdb\xbd\xc1\xb2\xc9\xe8\x1e\x09\x11\x45\xd6\xe8\xec\x01\x2a\x17\xee\x0f\x89\x88\x8c\x49\xc1\x49\x17\xcb\xaf\x9a\x97\x75\xf1\x03\x32\x7f\x7e\x69\xe2\xc8\x2a\x0c\x34\x50\xe8\x7d\x9e\x19\xd8\x97\x66\xaf\x86\x2a\xb1\xfd\x5d\x52\x71\x9a\x78\x21\x8d\x11\xac\x83\x31\xad\x6c\xf9\xab\xb6\x5c\x48\x1a\x46\xbf\x7d\x56\xee\xe0\x01\x05\x12\x7b\x9b\xae\x36\x3a\xba\x6b\xe3\x89\x79\x97\x18\xc6\x83\x38\x42\x5c\xde\x15\x34\x9b\xe2\x6e\xf8\x06\xb9\x01\x84\x32\xa2\x3a\x3e\x1d\x2e\x89\xf3\x01\x06\x27\x34\x89\x07\xe6\xfb\x5a\x34\xe2\xa9\xca\x1f\xd0\xf2\x65\x14\xe1\x71\x22\x04\x66\xd1\x59\x97\x8f\x8e\xe8\x51\x93\x0b\x90\x0a\xc1\x3f\xba\x42\x0a\xc7\xf8\x3b\x69\x90\x22\x10\xbe\x12\x85\x0f\x62\x39\x25\x11\x2a\x1d\x40\x9e\x3d\x67\x32\x87\xa5\x33\xe2\x58\x17\xaa\x82\xc3\x0c\x46\xdd\x7f\x8e\x41\xaa\x46\x10\x92\x39\x5b\x29\xc6\x59\xc8\x31\x08\x31\xe8\x2a\xb1\x3d\x76\xf3\x95\xb3\x58\x22\xb7\xee\x26\x93\xed\x72\xdc\xd7\x0d\x38\x4b\x53\x0b\x32\x82\xba\xd9\xab\x76\x8e\xd3\x3d\xdd\x67\x85\x95\x05\xc7\x16\x68\x7d\xf5\x11\xfa\xe1\x5c\x04\x72\x2a\x73\xdb\xed\xf4\xe3\xab\xe1\x32\xd0\x5e\x39\x0a\xaa\x65\x79\x38\xe6\xd0\xa0\x86\xc9\x3c\x45\x91\x71\xae\x42\xaf\x3c\xd3\x66\x16\x3d\xf9\x76\x32\x35\xa2\x50\x23\xc6\x7b\x55\x55\x8e\x32\xef\x65\x3c\x19\x8f\x92\x54\xa4\xc3\x6d\xa4\x82\x33\x21\x28\xc6\xa3\x34\x09\x9c\x87\xd1\x43\xf9\x0e\xd5\xde\xff\xbe\x38\x30\xd8\x7e\x45\xf9\x7c\xb7\xf6\x4d\x80\x24\x9f\xf6\x2c\x19\x8f\x13\x8a\xc4\x0c\x34\x90\x2d\x34\x54\xf4\xc2\xaf\x48\xa2\x50\x07\x1e\x92\xef\x6c\x83\x1c\xa1\x77\xfe\xcc\x89\x4c\x90\x4e\xab\x3a\x83\xaf\xdd\x80\x63\xb8\xbf\xfa\x1b\xfa\xa8\x8c\x27\x4a\x18\xaf\x69\x7f\x75\xfa\xd8\x39\xfc\x9f\x5f\xba\x79\xa2\xc0\xc4\x5d\xb1\xef\xc2\x84\x4c\x8c\xe9\x84\xf4\xb7\xd7\x8f\xb6\x88\x3d\x1e\x92\x4a\x81\x30\xe2\x45\x56\x3d\x96\xc7\x61\x7d\x84\x8b\x80\xa6\x7e\x77\x28\x1b\x58\x34\xbb\x9f\xde\x6b\x63\xb6\x84\xdf\xce\x39\xec\x5a\x2e\xfe\xf8\x63\x7c\x22\x11\x50\x97\xdd\x55\x59\xd3\x4d\x69\x29\x2d\xd3\xf5\x4e\x64\xc5\xd5\xe0\xf5\x93\xca\x7e\x2f\xfc\x14\xed\x5c\xbc\x39\x15\xea\x3c\xd0\xe1\x2a\x8c\xb0\x6a\xdf\xae\x12\x1b\x73\xe1\x06\xe8\x44\x60\x20\xb1\x2b\x5f\x47\x57\xa4\x25\x47\x14\xd2\x55\xe6\xf3\x31\x0e\x01\x43\x20\x46\x53\x5e\x21\x21\x6d\xb8\x94\x73\x48\x6c\xc4\x2c\xb4\xde\x14\x5f\xa7\xa6\x75\x8c\x83\x08\x91\x71\xf3\xbe\xb7\x08\x41\x7f\x52\x93\x52\xcc\xda\xfe\x05\x32\x5b\x96\x19\x62\x67\xef\x9e\x2f\x4a\x5a\xd8\x4f\x85\x01\x63\xce\x21\xb3\x4d\x9b\xde\x61\x9e\x38\xc4\x42\xc2\x28\x46\x6e\x4f\xdb\xeb\xfd\xc3\xea\x71\xbf\xda\x7d\xf5\xd4\x25\x16\x12\x1e\xe1\xb4\x75\x50\x53\x5c\x98\xe7\x85\x01\x26\x27\x4d\xb5\xd3\x53\xc5\x54\x7d\x99\x83\x38\xf3\x56\x64\x21\x11\x09\xa6\x27\x56\x86\xd6\x1a\xfe\xcf\x70\x7a\x59\xd8\xc6\xb9\xd4\xe9\x64\x0d\x97\xf0\x90\x87\x02\x01\x97\x59\x6d\x83\xa5\x81\x8b\x29\x0b\xc3\x54\xa2\x82\x46\xbb\xe9\xf5\x24\x6b\x16\x86\x3a\x42\x43\xbe\x3b\xd1\x6e\xe3\xdd\x5f\x41\x52\xa7\xcc\xfc\x96\xe5\xd0\x25\x0f\x61\x14\x58\x96\x53\x7d\x92\x6e\xf1\xc3\xc0\xd6\x75\xc0\xc7\xbf\x28\x92\x04\x53\xc7\xab\x1f\xcb\xaf\xbf\x82\xda\xb2\x30\x82\x24\x36\xbd\xbd\xa0\xc5\xcf\xb8\x63\x09\xe1\x22\xea\xe3\x1a\xbb\x87\xd6\x7d\xab\xa3\x1b\x97\x08\xc2\x3d\xbd\xf2\x78\xa9\xbc\xdc\x37\xbe\x59\x98\xa4\xb6\x93\xac\xe6\x01\x9a\x2c\x14\x02\xb8\x8d\x34\xef\xd7\x77\x4f\x77\xfb\xab\x95\x2f\xc3\x84\x92\x44\xd4\xf1\x05\xf6\xd6\x8a\xef\x39\x2f\xa5\xc8\xf7\xe2\xa4\x33\xd4\x35\x39\x0d\x9a\x98\xa1\xa4\x92\x38\x88\xfc\x55\xf9\x93\x76\x7f\x8e\xad\x31\xb1\x3c\x7d\x0c\x80\x6b\x17\xa6\x92\x94\x71\x14\x7b\xd3\x12\xf4\x70\x9c\xa6\x56\x83\xdf\xa6\x88\x41\xf2\xb7\x3b\xa5\x4d\x3d\xc6\xef\x85\x12\x0a\xc1\xa3\x88\x0b\x29\x7a\x90\xc0\x2f\x85\x3c\x59\xa8\x69\x8a\x9b\xdc\xd5\xc3\x70\x1d\x08\x75\xc4\xfd\x63\xb4\x65\x9a\x9b\xb2\xda\x82\xaa\xd0\x05\x71\x32\x41\xb4\x91\xb1\xbd\xc0\xbf\x4e\x75\xa7\x6f\xc2\x42\x20\xa1\x65\x74\x5a\xdf\x97\x1b\xdc\xd4\x27\x42\x82\x7e\x68\x1a\x2b\xd7\x38\x6c\x7a\x08\x3e\xa6\x5a\x77\xa0\x33\x31\xa7\x2c\x33\xfe\x1d\x20\x59\xe8\x4a\x50\xbb\xf2\x2a\x17\xea\x75\x2c\x0a\xdf\x0d\x93\x18\x5a\x23\x59\x62\x7b\xbd\xbf\x79\xba\xbf\x5e\xdf\x7f\xe9\x2e\x19\x34\xda\xb6\x2f\x45\x65\x61\x5c\x93\xf5\x2c\x34\x9c\x61\x87\x33\x3b\x8a\xaa\xf9\x6d\xb8\x71\x87\x86\x5b\x1a\x7f\x1b\xce\xf9\xc6\xf7\xfc\x3d\x37\x32\x45\x57\x84\xbb\x8f\x99\x1c\x30\xf2\x5e\xdd\x1d\x3c\x6e\x29\x2e\x54\xa8\xa3\x20\x22\x08\xea\xc0\xb4\xc7\x01\x28\x46\x37\x36\x0a\x12\x6d\x30\x62\x13\x55\xfe\xe1\x7c\x0a\x26\x7a\xea\x2c\x0a\x24\x61\x49\x67\x24\xd1\x6e\xa6\x7d\x31\x6a\x9a\x2f\x45\x94\x72\x69\xd5\x07\x35\xd6\x10\x70\x79\x1a\x38\xf2\xb3\x88\x3a\x0e\xb3\x53\xb9\x42\x14\xed\x75\xa6\x06\x0e\xe6\x2c\xa2\x9c\x60\xf6\xf3\x82\x0a\xd8\xb7\x99\x82\x42\xc1\x4a\x54\xbd\x6e\x32\x8b\x68\x6c\x30\x8f\xb0\xaf\xe3\x9d\xf8\xd9\x1d\x48\x09\x2a\xd1\xdd\x9c\xd4\xeb\xb7\x93\x28\x6e\xb3\xee\x08\x84\xe8\xed\xde\x91\x1f\xad\xc5\xd5\x76\x75\xbf\x1d\xe4\xef\xb3\xcd\xf0\x88\x91\x50\x47\x1d\x49\x1e\x26\x8c\x31\x16\x31\x6a\x05\x9b\xac\x9b\xf1\xfd\x55\x57\x89\xef\x66\x7c\xd4\x86\x5f\x38\x3b\x6a\x04\x14\xf5\x76\x03\xb3\x39\xa3\xff\x50\x9b\xa4\xb4\xa9\x58\xf6\x3f\xa8\x6c\xa8\xe6\x8f\x08\xc2\x89\xb7\xa4\x46\x31\xc1\x61\x5b\x33\x62\xca\xa6\xf7\x26\x2f\xcb\x6a\xc0\x4f\x67\x11\x73\x6f\x24\x5e\x6a\x9b\xfa\xef\xa6\x9a\x90\x7e\x24\x0f\x02\xfc\xf2\xaf\xd7\xcb\xee\x4f\x4c\x60\xb3\xc1\x88\xff\xfd\xef\xa3\xd7\xb8\x66\x51\x98\xc6\xa8\x0b\x78\xb8\x2d\x85\x5e\x14\xfa\x11\x9b\x78\xc3\xa7\x1a\x25\x01\x37\x9d\x25\x73\x59\xfd\x73\xa0\x3f\x34\xbf\xfe\x44\x91\xd1\x61\x27\xfc\x2b\xf2\x93\x2b\xb0\x3c\x82\x2a\x2b\x0d\xd5\xfa\x7a\x28\xbb\xe8\x13\xdb\x28\x26\x81\x74\xcb\x53\xe7\x3a\xeb\x01\x4f\xe3\xa7\x16\x8b\x04\x4b\x8a\xcd\x7e\x51\xe8\xaa\x4b\x1b\xa2\xd8\x24\xc8\x21\xd8\x3e\x0c\x25\x3c\x59\x94\x30\xc3\xf4\x80\x7c\x86\xb4\x06\x5b\x51\x98\x67\xa2\xb1\x28\x31\x3c\x41\xfd\x3d\x09\xed\xda\xb6\x7b\x11\x17\xba\x3c\x51\x62\x62\xd4\x26\x93\xa7\x0a\xf5\xa9\x2f\x4b\xfa\xb0\x28\xe5\x06\xf7\x88\xf2\x78\x2c\x8b\x7e\xff\x89\xa4\xab\x51\xee\x84\x7a\xf9\x38\x03\xf5\xcc\xe4\xeb\x91\x8c\x02\xa6\xc7\xec\xf6\x51\xc8\x1c\x49\x69\xb0\x35\x69\xb5\x56\xcb\xba\x59\xab\xa1\x64\xe8\x5a\xf7\x23\x8d\xe5\x77\x35\x2f\x40\x68\x20\x46\x2d\xba\x48\x1a\x85\xb7\x7a\x53\x29\x6b\xf0\xe7\xfe\xae\x52\x89\x4d\xb7\xf5\x72\xa3\x41\xe8\x3c\x2b\xba\x89\xaa\x8c\xc4\xf7\xd5\x2f\x75\x6b\xb7\x81\x7d\x2e\xa3\xe1\x3e\xac\xa9\x0c\xdc\x92\xef\xcc\xa6\x16\xcd\x5a\xcf\xde\x10\xf7\x09\x48\x53\x6c\x6c\x2e\x9e\x06\xb1\x53\x04\x2a\xc5\x3e\xbb\x30\x0d\x54\x2b\xa1\x5e\xfc\x01\x13\xc5\x88\x7f\xb2\x32\x09\xdb\xa6\xac\xfa\xfa\x6b\x64\x1c\xd5\x0d\x25\xf9\x8b\xa1\x7b\xe0\xec\x06\x15\x19\xad\xb1\x67\xfa\xfd\xe9\x76\xb9\xb8\xdf\x3f\x3c\x6e\xee\xda\xb0\xf4\x69\xbb\x5f\xfd\x81\xcd\x98\xf5\xe6\x7e\x7f\xb5\xd8\xfa\x7e\x66\x1c\xa4\xd6\x5e\xc7\x89\x9f\xdd\x89\x62\xe8\xc9\x3a\xed\x14\xc5\x81\x08\x70\x51\xdc\x6d\xbf\xfb\x57\x39\x26\x8a\x21\xa0\x5b\xf4\x18\x81\x47\xf8\x0b\xd4\x8c\xb6\x92\xff\x84\x06\x14\x57\x39\x21\x7a\xfa\xfb\xd3\xc3\x60\xd9\xf4\x67\xa5\x81\xd5\x39\x7a\xce\xde\x60\xf1\x2e\x3e\xce\xb2\xe1\xf1\x2f\x8f\x59\xc4\x91\xfe\x62\x77\x54\x67\x93\x96\x55\x30\x51\x1b\xf2\xa3\x85\x8e\x1c\x79\x34\x6b\xc0\x06\x0d\xdd\x7a\x15\x33\x99\xc8\x6e\xc7\xeb\xd0\x1e\x97\x36\xab\x98\x01\xc5\xfe\xcd\x32\xab\x54\x0e\x63\x0b\xd9\xb3\xd6\x67\xcc\x4c\xc7\xd7\xf6\x41\xe9\x5c\xd7\x32\xe6\xc4\x2a\xe3\x66\x0d\x9a\xe6\x8d\xc2\xf7\x98\x53\x8d\x96\xff\x07\xf1\x8a\x82\x30\xa7\x33\xc5\x86\xf3\xff\x9d\x9c\x5e\x71\x24\xdc\x94\x6f\x50\xd5\x2f\x65\xd7\xf7\x89\x39\x28\x44\xfb\xbc\x7b\x5b\x9e\xbb\x6e\x3a\xc6\x21\x0d\x3c\xad\xdb\xe7\x46\xe3\x9b\x32\x90\x13\x64\x71\x44\x15\x36\xec\xf6\x15\xd8\xf9\xdb\x9d\x27\x8a\x44\x18\x7b\x1c\xd5\x45\x0e\xe4\xa5\x26\xf8\xf0\x2b\x92\x84\x5a\xb1\xec\xa5\x2f\x01\x9f\x8b\xbe\xb2\x38\x0e\x99\x2d\x99\x54\xa2\x0d\x3e\x1a\x91\x2f\x87\x92\x4e\x2c\x8e\x13\xa0\xda\x43\xa8\x0f\xc7\x06\xf6\xd1\xf8\x86\x27\x8e\xe1\xd9\xe6\xf2\xeb\x69\xff\x37\x4e\x4c\x80\x5e\xd5\x5b\x25\x0e\xdb\x36\xe8\x19\xae\xf6\x71\x1a\xc4\x18\xe6\xca\xb2\x7c\xbd\x16\x1f\xdf\xb3\xa9\x93\x6c\x3b\xc4\x78\x3a\xf1\x37\x98\xc4\xad\x71\x4a\x68\x64\x89\x83\x95\x29\x2b\x44\x81\x74\xa7\x8e\x18\x16\x0b\xdd\x92\xd6\xbe\x40\x22\xdf\x95\xa7\x2a\xab\x0f\x36\xa4\xfe\x7b\x9e\xc4\x2c\x4e\x13\x83\x15\xf1\xab\xd3\xa9\x3a\x88\xa2\x1e\xff\x02\x9d\xb2\x68\x28\xe9\xdd\xeb\x2b\x9c\x19\xc6\xb8\x8f\x88\x58\x28\xc4\x1b\x23\xb5\x40\x3c\x77\x8c\x91\xee\xa4\x22\xb5\x2a\xbb\x3f\xae\xd6\xbf\xcc\xf8\x62\xa1\x25\x38\xff\x8a\x02\x91\xfb\xe3\x5b\x24\x49\x8a\xce\x97\xd6\x70\xab\xfc\x10\xf9\xe8\xfa\x65\xac\x2c\x3f\xdd\xd5\x84\x3c\x25\xf8\xef\xec\x00\xb1\x0a\x6c\x3b\xc5\xe5\xb7\xfa\x19\xf4\x18\x36\x12\xab\x40\xa3\x9b\x8e\x10\xa2\xfb\x53\x0a\xcc\xc6\xf8\x85\xc6\x26\xff\x76\x2a\x20\xcc\x62\xa5\x01\x27\xef\x8b\xa8\x1f\xc4\x34\x52\x8c\xb5\x8a\x71\x01\x5c\x1c\x8f\xd6\xc6\xd7\xfd\x1d\x02\x2b\xd3\x75\x98\x61\xd9\xfb\x21\x69\x90\xca\x5e\x6b\xa5\x7e\x70\xcd\x81\xeb\x19\x19\x11\xff\x11\x29\x35\x9d\x44\xe7\x36\x20\xb1\xd0\x7b\x3f\xcc\x24\x4e\x90\xcf\x79\x65\x58\xea\x7b\xfd\x80\xbd\xc6\xc9\x2f\x30\x14\x58\x87\x28\xba\x1b\xa9\xde\xb1\xd8\x44\x10\xc7\x1e\xc5\x69\xca\xf1\xdb\x66\x34\xc3\xdc\xa5\x2f\x30\xa3\x12\xd0\xcd\xa9\xd0\x88\x05\xbd\x98\xa7\x8d\x17\xb9\x24\x88\x88\x7f\xad\x1e\xda\xc5\xa1\xac\x3e\xf0\x4d\x99\x7a\xc8\xb1\x24\x48\x98\x27\xbc\x39\x5d\xc3\x49\x8c\x30\x19\x2e\x13\x88\x07\x76\x07\x0b\xad\xb3\xe2\xd9\x2a\x69\xf8\x9f\x98\x10\x16\x63\xc8\xb6\x13\x75\xf9\x22\xba\xbf\xa6\xa9\x08\x3b\xbf\x41\xd8\x98\x5b\x51\x37\x63\x0c\x73\x42\xb4\xf0\xea\x63\x2b\x64\x9c\x9f\x39\x81\xb1\x84\x80\xc5\xcd\xda\xdb\xea\xb8\xf0\x97\xaa\xa2\x09\x71\x0a\x29\xab\xa7\xc5\x57\x74\x3d\xf2\x5f\x45\xc1\x44\xb6\x7a\xf3\xa6\x47\x0d\xa2\x84\x05\x0a\xb5\x70\xeb\x32\x7f\x3a\x5e\x97\xef\x05\x7a\x3e\xa3\x2e\x88\x8b\x96\xc7\x37\x9b\x69\x6b\x01\xb1\xcd\x8a\x67\x47\x8e\xdc\x41\xdd\x10\xee\x4f\xc8\x63\x8d\x22\xfc\xbb\xc7\xdb\x76\x46\x9f\xbf\x11\x09\x37\x0c\x41\x12\xd3\x53\xa4\xfe\x14\x21\xe7\xc8\x2b\x37\x42\x35\xbd\xa2\x15\x4b\xc2\x94\x60\x18\x23\xb0\x98\xb5\x97\x83\x6a\x56\x12\xc5\x06\x59\x62\x55\x99\x83\x15\xd0\x75\x07\x12\x19\x5a\x89\x5e\x74\x81\xda\x2f\x6e\x6f\x37\xcb\xc5\x6e\x75\x6d\xc9\xc9\x8f\xdf\x3b\xb4\x4a\x22\x78\x84\x7d\xc6\x76\xe4\xee\xeb\x0c\x2e\x2c\x11\xc0\x11\x45\xd4\xf5\x9d\xaf\xb3\xba\x7c\x2f\xee\xcb\x8e\xc1\xd6\x33\x03\x58\x22\x43\x83\x31\x40\x59\x65\xcf\xfd\xf5\xc8\x88\xa3\x48\x64\x9b\x3a\xef\xca\x3b\xe8\x1f\x85\x54\x3a\xf2\xec\x25\x0b\xb9\x5e\x23\x7b\xce\x64\x97\x1a\x43\x89\xe2\x2c\x88\x07\x2c\xc1\xa5\xc8\x5d\x59\x95\x0f\x5c\x1f\x49\xf4\x8f\xd9\x45\xfc\x73\x48\x6e\xa2\x03\x8e\xef\xd5\xf6\x90\x8d\xb4\x17\x58\xa2\xa9\x41\x3c\x96\x25\x72\x5f\x43\x0e\x73\x78\xb4\xe9\xe9\x52\xdb\xd4\x46\xf9\x04\x78\xed\xf2\xa7\x44\x0b\xea\xb6\x65\x55\xb6\xa9\x20\xc2\x1d\x7a\xc1\x02\x96\x68\x69\xb5\x5e\xd7\xcb\xcd\x7e\xd7\xc3\xc2\x12\x88\x0c\x3e\x8e\x3b\xd4\x1d\xb0\xb6\x1f\x9f\xff\x24\xc3\x94\xea\x45\xf6\x2e\x32\xb1\x7e\xf5\xdf\x99\xbd\x2b\x31\x3c\x88\x45\xd7\xe2\x6f\x53\xb2\x0e\xbf\xf4\x8b\x65\xc6\x44\x16\xbc\xd5\x66\xa0\xbd\x11\x4a\x37\xb3\x4d\x1c\x44\xfd\x35\xef\xca\x63\xa6\xe6\x8b\xcc\x76\x7c\x1a\x70\x21\x6c\xbb\x3c\x2b\x9c\x21\x87\x3f\x92\x5a\xca\x83\xf3\x13\xe1\xf3\x93\x2a\xa5\x01\x24\xa6\xd3\x5c\xb9\x14\x10\xa3\x35\x25\xb6\x16\xdc\xcf\xbd\x3a\xc3\x24\xa7\x34\x51\xc8\xb2\x6d\x5e\xb2\x4a\x0f\x8b\xcf\x29\x85\x10\x5f\x57\xa8\x66\xf8\xce\x6e\x0c\x0b\x02\x1a\xf4\xf5\xdf\x65\xd9\x26\x12\xb6\xb8\x5c\x75\x4c\x58\x96\x32\x15\x78\xb7\xb0\x1b\xf1\xff\xe3\xec\xcd\xb6\x1b\xc7\xad\xfd\xe1\xd7\xe9\x8b\x5c\x90\x98\x48\x5e\xca\xb2\x5c\xa5\xd3\x9e\x22\xc9\x5d\x7d\x92\x95\xa5\x85\x61\xc3\xe6\x31\x45\x2a\x24\x65\x97\xfb\xe9\xbf\xc5\x0d\x80\x93\x64\x57\xff\xbf\x9b\x54\xda\x84\x24\x0e\x20\xb0\x87\xdf\xa0\xea\x5c\x7f\x72\x59\x2c\x02\xdc\xbf\xd7\xf7\xbb\xb1\x71\x38\xcd\x38\x49\xd5\x98\xdd\x13\x40\x9a\xcb\xaa\x2a\x4c\xd5\x87\x32\x99\x20\x4c\xaa\xfe\x09\x6f\x5b\xf9\x3a\xbf\x5e\x21\x13\xeb\xcf\xf8\x9f\xa7\x5c\xbf\x5e\x9d\x3e\x1e\x65\xfb\x32\x96\x90\xa6\x59\x42\x32\x84\x78\xe5\x65\xd3\x76\x4b\x71\x3d\x72\x5e\x0e\x43\xa4\xc5\x04\xef\xb1\x90\x1f\x79\xf9\xec\x92\xc6\xfe\xa0\x75\xa2\xc4\xef\x00\xaf\x0f\x25\x0c\xea\x55\x34\x4b\x23\x12\x00\x6c\xdd\x5e\x72\xe3\xb3\xf3\xf5\xac\xf4\x98\xa5\x22\xce\xa8\xd3\x2c\x44\x9c\x31\x8e\xba\xd8\x47\xcd\x52\x88\xb0\x2e\x68\xba\xbd\x69\xfa\x25\xa0\x95\x27\x06\xdd\xc9\x9f\x8f\xb2\xd6\x50\xcc\x3a\xbf\x59\x46\xb9\x56\x41\xe0\xb3\x7b\xa5\xd7\xe5\x5d\x5e\x9e\x7a\xfd\x4c\x9a\x65\x49\x84\x64\xdb\x85\x31\x5d\x70\x9f\xb7\x2d\x40\xb7\x05\xa1\x75\xd3\x27\x4f\x32\x4b\x45\x68\x9a\x05\xb0\xf6\xb8\x9a\x95\x65\x46\x5b\x47\x06\xcb\x4b\x34\x5b\xf2\x76\xe1\x97\xdf\xbf\x2c\x33\x26\x71\x08\xf8\xfa\x0d\xea\x55\x69\x50\x63\x29\x88\x2b\x8d\x6a\x46\xe7\x0b\xe8\x14\x9d\x34\xe7\xd1\xce\xfc\xd2\xe7\xa8\x8f\x49\xe9\x3b\x93\x2c\xc1\xfa\x85\xe7\x9b\x77\x4b\x6b\x8e\x5c\x2b\xdc\x01\xc7\x4b\x4d\x26\x13\xa7\x77\x61\xe0\x50\xcd\x8e\xa4\xc6\x39\x55\xe2\x8c\x79\x84\x23\x38\x1e\xd2\x64\xbe\xab\x84\xca\xe0\x80\xd8\xbe\x14\xd0\xce\xa7\xb1\x4a\x52\xac\x96\x7a\x3a\x8a\xd3\x50\x3e\xeb\x0e\x66\xca\x6a\xac\x2e\xef\x76\x8b\x50\x26\xc8\x74\x24\xb1\xb3\x15\x64\x2c\xc3\x9f\x09\x0d\x73\xe5\xb1\xae\x5a\x87\x5f\xbe\xa9\xea\xbb\x8f\xa7\xf2\xe8\xfe\x00\xc6\x9d\xf4\x27\xc8\xf5\x4c\x1b\x27\x13\x75\xfd\xfc\xf3\x1a\x0e\xa7\xba\x96\xcf\xb0\x81\x63\x55\xb7\x5f\xc8\xd7\x4f\xe7\x8d\xa1\x52\x07\x97\xe3\x3e\x93\x0c\xa7\x68\xd2\x04\xa9\x0d\xfb\x63\xd5\xb4\x7f\x04\x88\xef\xdf\xd1\x3a\xa0\x99\x81\x34\xca\x42\xb1\x72\xd0\x43\xa4\x19\x44\x31\x62\x28\x2a\x7c\x92\x9f\xba\x37\x4d\xbf\x0d\x18\xc5\xb2\xc5\x3b\xe4\x8f\x9e\x9b\xeb\xaa\x67\xb3\x57\x13\x24\x73\x04\xcb\xea\xe0\x49\xf3\xbe\x38\x95\x59\x45\xb1\xa6\xf9\xf0\x2e\xcb\x21\x20\x41\x41\x77\xd7\xcf\x7e\x45\x55\xcc\xa5\x6c\x5e\xb6\xd2\x0e\xc7\x33\xca\x7d\xfa\xeb\xaa\xf0\xe3\xb9\x25\xbb\x40\x91\x0c\x54\x15\x24\x91\xce\xa1\x1e\x32\x32\x3a\x4a\x1d\x94\xb0\x0b\x85\x16\xd6\xe6\x45\x3e\xac\x50\x92\xd8\x34\xf5\xaf\x6e\x5b\x1d\x67\x72\xd6\xdd\x61\x89\x97\xbe\x0a\x50\x9e\xc9\x6b\xe7\x07\xd1\x98\xe3\xdd\xbe\x5d\x4d\x5a\xe0\x92\x12\x8b\x19\xb4\xa3\xe2\x5d\xa8\x10\x48\x9a\xa4\x58\x76\x96\xc6\x7c\xaf\x4c\x81\x5a\x63\xaf\x9f\x20\x91\x25\x8b\x5c\xfb\x15\xbd\x68\x7b\x77\x63\xf4\x40\x57\x9e\xb1\xd0\x65\x47\xd8\x20\xba\xbd\xe8\x1a\x1c\x0a\x6a\x92\x71\x81\xe5\xf5\x2d\x04\xd3\x97\xef\xb2\x34\x73\xfe\x36\x95\x9c\x64\xc1\xa5\x7c\xe7\xe1\x4a\x50\x3f\x56\x55\x31\x7e\xba\x92\x67\xdc\x3a\xcc\xee\x51\x7e\x20\x5f\xf3\xf2\x05\x70\x99\x19\x17\x91\xe0\xfd\xa8\x4f\x4d\x0b\xfd\x83\x10\x99\x74\xde\x2a\x37\x55\x0d\x5a\x36\xdd\x3a\x39\x95\xd8\xa2\x32\xa5\x8e\xcf\x39\x5e\x5c\x65\x16\x8b\xd4\x19\x8f\x4e\x1a\x05\x32\x8b\xad\xf7\xc6\x6f\x3d\x83\x65\x64\xe5\x36\xdc\x9a\x33\x07\xa6\xfe\x26\x65\xdc\xc1\x4d\x9a\xd3\xb1\xbb\xe8\x77\xa8\x6f\x4e\xc5\x75\x2d\x9f\xab\x72\x9c\x9d\xca\x4c\x10\xeb\xf7\xfb\xa7\xd2\x40\xfd\x5c\x4b\x73\x0a\x32\x09\x9f\x59\x15\xfe\xba\x74\xe6\x83\x64\xc1\x26\xed\x01\x99\x65\x31\x6e\xa9\x01\x84\x77\x2d\xf3\xd9\x94\x97\x34\xc2\x16\xf3\x95\xac\xeb\x8f\xa7\x36\x2f\xf2\xf6\x63\x54\x13\x96\x92\x6b\xe7\xfe\xb2\xde\xdd\x3f\xec\xa6\x0d\x4f\x29\x95\x54\x9e\x97\x50\x54\xfa\x75\xb6\x07\xcf\x1e\xa8\xd4\x06\xb1\x5b\x88\xf3\xbb\x95\x0a\x42\x9b\x5b\x2a\xcd\x83\xf8\xd7\xf6\xa4\xfa\xad\xc3\xdd\xb7\xe9\x2f\x6a\x2a\x7c\x87\x2e\x88\xc3\x5c\xec\x61\x49\x4d\x33\x54\x8c\x2d\x70\x6e\x38\x33\xc2\x70\x88\x47\xcc\x21\x3b\x30\x80\xf9\x39\x99\x34\x3a\xd1\x58\xb4\x5c\xfd\xb1\x5b\x7e\xd1\x94\x90\xc6\x7a\xc6\xf6\xe9\x70\x5c\x94\xe6\xfa\xd4\x37\x11\x25\xd8\xd4\xc9\x3e\xe3\x72\x5a\x15\x6f\x7d\x09\x4f\xda\x88\x20\x8c\x54\x7b\x08\xd5\xec\xa4\x2d\xa5\x88\xe2\xd5\xb2\x36\xd7\xb5\x7c\x9f\xcc\x50\x9b\x02\xd2\x5a\x0f\xf2\x43\x81\x03\xf0\x4f\x8f\x2b\xe3\xc5\xed\xf0\x95\xf7\x77\xe7\x02\xda\xe9\xd2\xff\x0b\xdf\x61\x21\x10\xed\xae\xaa\x3e\xe6\x53\x31\x73\x3c\x8f\x3a\x7f\x7e\xe9\x72\xe5\xc9\x87\x54\xcc\xb9\x9f\x63\x53\xd5\x71\xaa\x62\xe1\xea\x75\xeb\xd7\x53\x2d\x31\x94\xbf\x78\x33\x55\x6c\x18\xba\x2d\x04\x02\xc4\x65\x18\x9a\x22\x31\x71\xb3\xed\xa4\x7a\x28\xc9\x7c\x84\x4e\x5d\x68\x81\x86\x47\xbb\x97\x1a\x9a\x97\x5e\xfc\x84\x2a\xc2\x44\x02\xbd\x31\xc1\x19\x48\x47\xd1\x08\xf0\xe5\x34\x15\xda\xbb\xd4\x9e\x8c\xb2\x44\x1d\xfb\x5e\x77\xe4\xab\xda\x6f\x3c\x35\xa3\xa6\x8a\x4a\x2a\x82\xc8\x74\x55\xd7\xd0\x1c\x2b\x2f\xad\xd6\xc2\x33\xd4\x6e\xa7\x9a\x68\x02\xcc\x6e\x0e\x55\xce\xce\xff\x8f\xbc\x39\xc9\xe2\xa6\x32\xa6\xdb\x55\xfb\x17\x54\x31\x99\x60\x15\xef\xf7\xf5\x6e\x5c\x34\x51\x4c\x0b\x2c\xb0\xed\xdd\x86\x32\x71\xd5\xb9\xa4\x31\x36\xfc\x22\xe7\x09\x42\x68\xcc\x16\xda\x45\xad\xf2\xb6\x96\xf5\xc7\xb9\x63\xdc\xb8\x00\xa9\x44\x66\x53\xef\xa6\xf1\xe8\x51\x82\xf9\x2f\x52\x6a\x95\xc4\x16\xe5\x1e\xae\x65\x15\x67\x51\xec\x84\xe9\xa7\x0f\x34\x81\xc4\x19\x10\x19\xe3\x1e\x42\x71\x81\xd3\xa1\x52\x9a\x22\x9d\x51\xa2\x59\xda\xcc\xe9\x83\xaa\x14\x9c\xeb\x7e\xde\xdc\xa1\x41\xe4\xc5\xfe\xa8\x92\xd4\xc6\xae\xc8\x84\xbc\xa8\xb3\x28\x67\x7c\xb5\x52\x0a\x2c\xe5\xf6\x56\xea\xeb\xee\x7d\x3e\x40\xf7\x9f\xdb\xb1\x10\xcb\x25\x10\x9c\x52\x54\x82\xf3\xae\x0c\x6c\xf4\x45\x5d\xcf\xcc\x52\xa9\x52\xd2\xa2\xf2\x3d\x02\x16\xae\xf2\xda\x38\x6e\xaf\xd3\xdf\x9a\x7e\xa1\x4e\x12\x67\xab\x0e\xd5\x35\xbc\xd9\xde\xe7\x92\x2a\x9d\x09\x2b\x27\x82\x52\xb3\x5f\xd1\x5e\x91\xef\x78\x2a\x8a\x4d\x35\x83\x66\x29\x13\xc5\xcc\xcb\x1f\xae\x36\xd7\xab\xdb\xdd\xc2\x29\x1e\x84\xc3\x31\x43\x86\xff\x21\x2f\x5b\xaf\x6a\x87\x60\xb0\xcb\x89\x8f\x32\x24\xc1\x4e\xf3\xfa\xe1\x1d\xfe\xb7\x3a\xf5\xdf\xc2\x2c\xc6\xb5\xc1\x27\xf4\xf9\x2b\x89\xe7\x19\x30\x6d\x1c\xe2\x29\x93\x45\xf8\x45\x75\xae\x5f\x10\x4f\x82\x08\xa1\x5d\xe5\x4f\x6d\xfe\xb2\x43\x64\x71\xa9\xbf\xdb\x3e\x06\x08\x94\x02\x65\xc0\xd9\x61\xd4\xc7\xca\xa5\x0d\x33\x32\xb2\x8e\x92\x24\xd6\x83\x13\x6e\x73\x49\x2d\x83\xea\x58\x08\xff\x45\x87\xe3\xa9\x85\x55\x69\xaa\xf7\x4b\xb8\xe0\xcb\x41\xb4\x8e\x33\x40\x08\x4d\x2d\x5b\x08\xed\x63\x4d\x74\x9f\x9f\x7b\x3b\x89\x2d\xa2\x84\xa6\xab\xae\x26\xbe\x0b\x7f\x90\x3f\xd1\x50\x36\x7c\x9c\x12\x40\x5f\x12\xd7\xd0\xf7\x26\xb2\xd3\x99\xa4\x69\x9a\x89\xa1\xf0\x2b\xf7\x41\xaf\x92\x6a\x46\x19\xf8\x23\x4e\x44\x03\x2b\xe2\x97\xcf\x9e\x49\x83\xd1\xd9\x5b\x0e\xef\x77\xf2\x27\x9a\x53\x84\x94\x59\xf3\x38\x75\x6d\xcd\xe6\x1e\x26\x3b\x9c\xe6\x09\xd5\x91\x27\x77\xbe\x74\x2b\xef\x18\x4c\xa3\xb9\x74\x82\xee\xef\x58\x00\xf6\x3a\xa3\x3d\xa3\x48\x0b\x96\x70\x3d\x60\xac\xa6\x0d\xc7\x5f\x27\xbd\xe1\x5b\xb2\x0c\x73\x8c\x26\xff\x0b\x1e\x2c\xc2\x3c\xfd\x91\x44\xcb\x94\x05\x82\xe6\x55\x5f\xf6\xd4\x09\x44\x18\xce\x2f\x8c\x71\x31\xaa\xf9\x44\x69\x62\xfa\x32\xe8\x54\x45\xb8\x9d\x4b\x63\xba\x18\x36\x7f\x2e\xd1\x0b\xf5\x32\x43\x59\x67\x44\x21\x95\x1e\x46\x42\x74\x6e\xd1\x08\x03\x98\xc4\x85\xb2\xef\x7e\x79\x4c\x61\xbf\xfd\xd3\xff\xfc\x9b\xfe\x27\x0c\xe6\x4e\x03\xec\x4e\x96\x27\x8b\xf0\x63\x5f\x55\x1f\xbf\x4e\x3a\x4b\x35\x6e\xb7\x23\x5e\xfd\x3f\x4f\x72\x16\x1f\xea\x4c\x09\x8c\xb2\xb7\xdf\x76\x67\x26\x5b\x54\x4b\x6e\xb0\x07\xb1\x5c\xff\xb5\x83\xbf\x66\x3f\xa0\x62\x07\xd1\x77\x15\x66\x59\x8c\x8a\xe5\x5a\x0b\x83\xe4\x5b\x57\xd5\xaa\xea\x43\x37\x1d\xe7\xaf\xa2\xce\x62\x4c\x99\x5a\xd9\xbc\xf6\xed\xfc\xcb\x53\x52\xcb\x0c\x5f\x28\x94\x04\x09\x9f\x37\x84\x20\x3e\x0b\x21\xf0\x87\xbc\x74\xf0\xcf\x6a\xae\x92\xa2\x8d\x51\x28\xe3\xf8\x5c\x15\x66\x57\xad\x4e\x21\x98\xd7\x90\x25\x58\x21\xec\x8d\x3a\x6f\x82\x9d\xbe\x1f\x60\x4d\x92\xf9\x92\x16\xb6\x54\xab\x7a\x9c\x8d\x98\x28\x31\x58\x00\x7f\xa9\x4e\x75\x33\x3d\x92\x26\x92\x8c\xbc\x5f\x28\x9d\xdc\x3b\x13\x19\xc0\x0e\xb8\xaf\x54\xcc\xee\x8c\x89\x49\x8c\x81\xce\x20\x7e\xf6\x46\xcf\xb5\xcf\xa8\x89\x53\xc8\xc8\xf0\xd6\x38\xba\xf4\x64\xea\x19\x42\x20\xa4\xd5\xab\x9b\xb9\x8b\xc8\xe5\x9d\xdd\xd0\x38\xa1\xd2\x9b\xaf\x3d\x63\x3d\xc8\x91\x10\x3e\x35\x7a\x9c\xdc\x6f\xc3\x44\x82\xc5\x92\xab\xdd\x72\xf7\x7b\x08\x68\x0c\x4b\x55\xdc\xdd\xec\xbf\xaa\x83\xca\x27\xa9\x9e\xe1\xb1\xc1\x10\xd4\xb5\x56\x2a\x7b\xa4\xa6\x3f\x44\x12\x34\x03\x76\xe5\xe0\x79\x2d\x3b\x0c\x4a\x09\x9f\xd8\x41\xf7\x4a\x5d\xd3\xf9\x6c\x78\x16\xa5\x5e\xdf\x5f\x1e\x3f\x4b\x5d\x0d\xd7\x1c\x4b\xbf\x41\xf3\x66\x29\xbd\xb7\xd4\xec\xdb\x44\x94\x65\x91\x97\x17\xb8\x0c\x8e\x36\x22\xd5\xb8\x81\x1f\x6b\x6c\x63\x3a\xbf\x8a\x99\x04\x37\x35\x09\xcf\xdc\x44\x76\x80\x87\x89\xe2\x15\x35\x89\xb0\x58\x9b\xbb\x5e\xfd\xb1\xba\x7d\x78\xdc\x2f\x17\x8f\x08\x06\xdf\x3c\x3c\xdd\x5f\xf7\x83\x32\x67\x05\xfb\x22\x9b\x97\x20\xd1\x71\x71\x2d\x32\x89\x16\xca\xfa\xce\xad\xac\xf5\xcb\x75\xfe\x36\x55\x45\x30\x69\x6c\x10\x3b\xef\xfc\x9f\xc6\x29\xdd\xec\xbe\xa7\x4c\xe1\x8e\x56\x79\x79\xc8\x7d\x09\xef\x1b\x59\x9a\xea\x70\xbd\x75\x7e\xb5\x67\xb8\x8a\xbe\x2d\x34\xdc\xa3\x54\x70\x18\x74\x46\x6e\xea\xea\x10\xbc\x69\xc3\x80\x94\x79\xc9\xe8\xe6\x08\xe5\xc8\xf2\x83\x9a\x2c\x72\x6b\xd0\xf7\x0a\xb9\xf9\x6b\xdd\x53\xdf\x4c\x16\x83\xf4\x0d\xce\x9b\xda\x61\x8d\xe4\x4c\xb9\x6d\x76\x22\x99\x88\x90\x4b\xa6\x4e\x75\xb9\x2f\xaa\xa6\xbf\x21\x99\x71\xb2\xfd\x08\xdd\x40\xa0\xe7\x6f\xd3\x0f\x5a\x93\xb0\xde\xd6\xea\x54\xc8\xbc\x86\xbd\x07\x79\x84\xd6\xa4\x91\xb1\xc1\x42\xbf\xeb\x63\x43\x5d\x5d\x50\xa9\x99\xde\x5e\xc9\xb4\xf5\xe5\xaa\x2e\x78\xac\x5b\x30\xbe\x71\x6c\x67\x1c\x6b\x23\xad\x92\xa4\x4f\xc1\x8f\xd5\xac\xf7\x6c\x54\x92\x04\xb7\xbc\x7d\x77\x6b\xf7\xb2\x4b\x0c\x9a\xfd\x20\x2d\x49\x8d\x8e\x09\x36\x57\x91\x53\xfc\x58\x57\xdd\x82\x3c\xfb\x1a\xc3\x62\x6c\xb7\x3b\xb5\xa9\xab\x8f\xa5\x63\x6b\x4e\x26\x5a\x18\x9a\x50\xd4\x96\x29\xab\x36\xb7\x1f\xb7\xf0\x2c\xf5\x47\x40\xc4\x4c\xcf\xdd\x64\x0c\x55\x41\xe6\x45\x51\x63\x32\xa7\x49\xd9\x9c\x0e\x87\x95\xd6\x45\x1f\x84\x18\x20\xce\x5e\x7c\xe3\xf5\x7a\xb6\xad\xb4\xf6\xb7\x8b\x0d\xb2\x49\x8c\x69\x40\x38\xd1\xd9\xe5\xf7\x6f\x4f\xdb\xeb\xc7\x4d\xaf\xc8\x47\x8d\x55\x4a\xab\x00\xd6\x7f\x85\x72\x2c\x1a\xfb\x75\x63\xcf\x58\x90\xd8\xb3\xaa\x7a\xcc\x2f\x44\xc4\xd9\x32\xdc\x74\x3b\x73\x79\x0b\xd2\x0c\x5d\x7b\x88\x23\x82\x01\xff\xd8\xee\x2f\x1c\xe2\x19\x0a\xd7\x2e\x76\x3b\x54\xd7\xde\x3e\xdd\x2d\xae\x6e\xc3\x49\x02\x61\x0a\xfb\x7c\xdd\x92\xf3\x87\x3c\x15\xed\xe0\xea\x48\x81\x5a\xed\x48\xfe\x6d\x75\xec\x62\xdb\x87\xf2\x1e\x7e\xb6\xe3\x20\x12\x18\x11\x18\xc3\xdf\xad\xef\xf7\x3f\xd6\xbb\xef\xd7\x9b\xc5\x8f\xfd\x8f\xd5\xba\x3f\x4e\x89\x17\xdf\xb2\x79\x51\x7c\xcb\x6d\x3b\x1c\x51\x0a\x82\x32\x71\x33\xf5\x7f\xa1\xc0\x94\x65\x3d\x84\x11\x50\xfc\xa4\xbd\x04\x1c\x9f\xde\x38\xe0\x54\x60\xf3\xf1\x20\x7f\x0e\x18\xb8\x70\x2c\x73\xdd\x84\xf7\x5e\xa4\xd9\x1f\x10\x89\x42\xcc\xd7\xfa\xf1\x66\x3b\x8a\x39\x20\x89\x39\xe2\x7d\x9b\x77\x79\x5c\xe8\x36\x7f\xcb\xdb\x8f\x50\xe9\x0c\x43\x8c\x40\xd6\x89\x97\xc5\x41\x64\xde\x20\x9d\xd1\x5f\x4d\xca\xb4\xc9\x3c\x61\x2e\x7c\x34\x13\x71\x78\xc7\xbb\xbb\x7a\x9d\x97\xb9\x2f\x2f\xac\xfb\xbb\x9b\xc9\x08\x83\xcc\x6e\xdb\x1e\xad\xef\x20\x23\x88\x7a\xfa\xf1\x45\x83\xd4\xf3\x8a\x64\x37\x63\xa2\x41\x74\x1c\x8b\x00\x61\x4a\xfe\xe2\xae\xaa\x88\x61\x87\xca\x84\x9a\x16\x28\x4a\xd1\x69\xd4\xbd\x8c\xd7\x20\xdb\x17\xef\x1f\x39\x06\x44\x82\xa2\x5a\x90\xa0\xb8\xfe\x65\x88\x00\x26\x8a\x11\x8b\x0b\xba\x6a\xd0\xd1\x69\x3c\x11\x0d\x63\xe8\x64\x00\x3f\xdb\x5a\x8e\x3b\xaf\x60\x64\x12\x2a\xf0\xb8\x18\x74\xc1\x11\xfd\x6d\xf6\xd5\xd2\xd9\x63\xdb\x1a\xe0\xaf\xb3\xd4\x0c\x8c\x02\x04\x8a\x2d\xbf\xaf\x6e\x97\x0f\xeb\x10\x5f\x00\x28\x8a\x7d\x37\xac\xdb\x6d\x2e\x34\xd8\xc3\x38\x1d\x5b\xff\x9e\xe3\xa3\x1f\x97\x62\xc7\x6b\x05\x58\x65\xb0\xd4\x7e\xfd\xb8\xd6\xd5\x8f\xd9\x2c\xb4\x91\x52\xb8\x92\x54\x67\x7e\x93\x7f\x43\xed\x3b\x00\x19\x2f\x6d\xd0\x36\x56\x02\x63\xe7\xdb\x93\x7e\xfd\x98\xaa\xc3\x59\x92\x28\x67\x91\xee\xaa\x42\x0f\x6f\x50\x17\xb6\x7a\x3f\xc7\xee\x58\x22\x0d\xc6\xb6\xab\x9f\x6d\x0d\x87\x49\xbc\x65\x89\x92\x24\x68\xd1\x99\xfc\x8d\x70\xb1\x8f\x49\x7a\xf5\x31\x44\x96\x96\x58\x89\x08\xe3\xdd\x4b\x30\x55\x08\x47\x28\x11\x3c\x0b\xbb\x12\x96\xda\xfb\xd8\x27\x8c\xa0\x0a\x91\x32\x6e\xb6\x6d\xe5\xb9\xec\xe3\x74\x32\x59\x46\x1d\xb6\xfd\x19\xda\xd5\xc1\x79\xc9\xfd\x4f\xa5\x3e\x49\xbd\x2c\x37\x06\x4d\x1d\xd6\xcb\x07\x8c\xa4\x3e\x4b\x1a\xac\xa0\x90\x78\x64\xf3\x15\x94\x70\x86\x1e\xb3\xc2\xba\x2c\xc5\x4b\x6f\xcd\x3c\x7b\xbe\xd6\xf8\xb0\x89\xd6\x59\x36\x2e\x99\x5d\xac\x4b\xd9\x94\x08\xa7\xd4\x54\xd5\xad\xad\x8a\xbc\xda\x9e\x0e\x07\x39\x14\x47\x67\x17\x97\x32\x8d\x24\xb5\x43\x5e\xa2\x30\xed\xe5\x10\xd5\xa6\x3c\x42\x6e\x6b\x79\x3a\x4c\xf7\x16\x9b\x42\x86\xb4\xd1\x03\x98\xfc\x74\xb8\x0b\x52\xe7\xd4\x4a\x96\x20\x40\xb1\x4b\x27\xbe\x75\x99\x50\x2f\xc0\x3a\x80\x5d\xad\xb4\x49\xea\x06\x3d\x3f\x83\x59\xa0\x5b\x38\x9c\xa9\x54\x53\xab\x88\x83\x2f\x3f\x3b\x05\xcc\x45\xdb\x4a\xfd\x3a\x92\x4e\xfa\x72\xf1\xb0\x9a\x68\xac\xbe\xbf\x23\xd3\x67\xdd\x5c\x8f\x26\x8f\xe6\x80\x6f\xdd\xde\x03\x72\xba\xdd\xcb\x31\x82\x9a\x9b\xbc\x17\x30\xa7\x16\x22\x42\x07\xf9\x94\x33\x25\xff\x7f\xff\x67\x84\xe1\xb5\xc0\x08\x4b\x7b\x37\xe9\xa7\x75\xd9\x4e\x0a\xb7\x61\x94\x74\xc6\xfa\x63\x2f\xb8\xed\xfe\x6e\xf1\x67\xff\x9b\x92\x5a\xed\x2d\x76\xab\x3a\xf4\x69\xe7\xad\x51\x0b\x2a\x46\x90\xd5\x4d\x55\x6b\xe8\xd6\xd2\xef\x50\x1c\xe7\xb5\x1a\x6b\x29\x30\xe9\x90\x18\x50\xb7\xf7\xf0\xfe\x14\x40\x87\xe7\x0a\x9a\x5f\xae\x23\xdd\xf0\xe1\x52\xad\x75\xcc\xaf\x63\x0d\x6f\x79\x75\x6a\xe6\xe5\x0c\x1c\xc6\xa2\x88\x38\x26\xaf\xcb\x89\xfb\xd7\x9b\x45\x91\x60\x18\x8d\x1f\x91\x42\xf9\x58\xc3\x7a\xf7\xb0\xf7\x7e\x68\xeb\xb2\xef\x44\xb2\x28\xca\x94\xd3\xdd\xae\xde\xa1\x7e\x3a\xd3\xd1\x99\x3c\x72\x16\xc5\x2c\xf1\xc2\xed\xb9\x82\xc7\xa0\x8f\x35\xbe\x23\xdd\x18\x83\x05\xa4\x77\xc8\x1d\x93\xd9\x39\x9c\x85\x1f\x8c\x53\x87\x65\x75\x08\x98\x4d\x55\x0c\x5a\xba\x43\xd7\xf3\x1f\xb3\xaf\xd4\x29\x41\xfd\xec\xc5\x6a\x39\xb9\xcc\xd8\x70\xc4\x0f\x75\x6f\xc3\xea\xe7\x94\x6d\xd8\x8f\x01\xc7\xe2\xf7\x4a\x75\xc5\x09\x01\xfc\x97\xaf\x8f\x70\x82\xd9\x6d\x50\x65\x79\xc0\xe6\xe9\x17\xc8\x0f\x16\x51\x48\x9d\x41\xb7\x6c\xf2\xb2\x0a\x3f\xca\x98\x46\x48\xca\x3e\x2f\xdf\xaa\x57\xf0\xca\x7a\x33\xc2\xce\xdf\x9a\x17\xc3\x2f\x71\xe1\x8c\x3a\x71\x51\xd9\x7c\xd1\x18\x63\x11\x57\x0c\xab\x8c\x01\x86\x34\x71\x0f\x66\x11\xd7\x49\xea\x85\xff\x83\xed\xc4\xc5\xc5\x97\x45\xdc\x80\x03\x8e\xa1\xb4\x42\x97\xd8\x62\x6f\xb1\x3f\x6a\xf1\xda\x0b\xa7\xc0\x1e\x42\x28\x16\x09\xe2\x34\xb5\x0e\x48\x45\xc9\xcb\xe7\xb1\xd0\x0a\x8b\x84\x70\x1c\x52\x97\x9a\x62\xc3\x69\x51\xcc\x85\x2d\x59\x24\x24\xc8\xde\xda\x17\x61\x89\xbf\xde\x78\x59\x24\xb4\x0b\x3c\x1a\x84\x40\x76\x71\xfb\x33\xdc\x00\x8c\x96\xb5\xd9\xaf\x00\xc1\xaa\xde\xfd\xd5\xea\x76\x32\xb9\x12\xa6\x22\x1a\x62\xc5\xf6\xbd\xaa\x5f\x31\xd2\x08\x47\x13\x8d\x42\x0f\x5e\xf8\x09\xbb\x7d\x67\xee\x02\x2c\x4a\xa4\x48\x47\x45\x81\x1b\xc7\x9e\x99\xca\x47\xb3\x28\x01\x99\xa5\x01\x07\x55\xbf\x42\x8b\x15\xb2\xb9\x12\x31\x8b\xd2\x98\x22\x17\x43\x0e\x85\xb2\xb3\x21\x94\x61\x84\x7f\x97\x9b\xb2\x5b\x69\x87\x32\x21\x8b\xb2\x28\x52\xa9\xe7\x17\x74\x41\x07\x0e\x38\x67\x19\xb0\x28\x4b\x62\x11\x74\xb7\x1d\xb0\x2b\x38\xf5\x8c\xc6\x64\x82\x8c\xbb\xda\x5d\x88\x22\x2f\x78\x27\xb0\x2e\xb9\x47\x49\x9c\x41\x1b\xca\xbb\xbb\x4e\xbf\x50\x76\x4f\x2e\x78\xbd\x8d\x0a\x81\xcb\xf1\xd4\x91\x29\x91\x53\xc7\xb9\xe5\x6e\x7b\x1e\x7f\xcf\xa6\xb1\x94\xae\x96\xe5\xd8\x25\xf9\xe1\x74\xf8\xa3\x42\x15\x40\xb4\xb8\x9a\x9d\x87\x22\x19\x92\x6a\x01\x29\x02\x4e\xb9\x71\x16\xbf\xb2\x48\x29\x67\xeb\xd6\xdd\x21\xe7\xed\x30\x46\x5c\xb2\x48\x81\x0c\x17\x33\xa2\x49\xad\xcd\x68\x9f\x66\x91\x8e\x39\x5a\x18\x63\xdb\x1e\xe6\x0f\x41\xc7\x09\x2e\xa4\xcb\xcd\xc3\x8f\xeb\xfd\x8f\xd5\xea\x77\xb6\x7f\x5c\x6d\xd6\x0f\xfd\xe2\x6d\xa2\x04\xb1\x1e\x0b\x73\x70\xbd\xe8\xfd\x66\xb5\xb8\xbe\x5b\x8d\xab\x94\x2c\x32\xdc\xe1\xbf\x6f\xaa\xaa\x0f\x17\x2e\x42\xe3\x7e\x15\xf7\xf6\xdf\x07\x88\xcf\x59\x14\xc7\xaa\x9f\x5a\x26\x21\xe0\xb8\x84\x18\xec\x8e\xc0\x26\x2c\x32\x52\x31\xbf\x99\xd9\xfc\x27\x98\x21\xdd\x63\x91\x51\xd6\x91\x97\x70\x9d\x7c\x18\x2d\x2e\x06\x32\xac\x9e\x1e\x6b\x74\x4a\xbb\x50\x72\x63\x91\xb1\x0c\x71\x13\x63\xfe\xd5\x27\x4b\x22\x28\x27\xc4\xe1\x02\x92\xa6\xb7\x1a\x0b\x5f\x65\x23\x02\x51\x70\x60\xf4\x44\x5d\xef\x14\x78\x81\x75\xd5\x8d\x17\xc2\x15\x82\xf0\xf4\x6e\xc1\x8c\x16\x58\x9b\x72\x6c\x4f\x5d\x75\xaf\x7d\x3b\xb9\x19\x56\x42\x06\x83\xea\xc0\x55\x55\x35\x2d\xd4\xff\x3c\xc1\xcc\xe0\x97\xc5\x11\x4f\x70\x11\xdd\xf7\x05\x51\x5c\x65\x9c\xf2\x4b\x1f\xcd\xa5\x61\xb4\x70\xd6\x59\x81\x68\xe0\x2c\x01\xb6\xf2\x00\xf7\xd5\x70\x57\xe3\x28\x11\xde\x8f\x15\xf4\x6b\x80\xa6\x39\x7a\xeb\xec\xe7\x63\xed\x4c\x2b\x9c\xec\xcb\x25\x35\x23\x16\x33\xe3\x88\xaf\x03\xfd\xe2\xa9\x31\xbd\xd8\xa9\x1f\xc4\x33\x1a\x9b\x01\x83\x7b\x9d\xbf\xe5\x06\x4a\xd3\x4c\xf6\x84\x58\x88\x28\xb4\xb6\x30\x5a\xbc\x93\x3f\x1f\x9d\x84\xf3\xec\x37\x45\x9a\x51\xdf\x8d\xbe\x86\x43\x35\x78\x0f\xb2\x58\x64\xd6\x0b\x4c\xc0\x5a\x57\x8e\xbe\xd5\xd3\x1d\xc2\x18\xc5\x88\xab\x53\xde\x76\x21\xcf\xe4\x55\x89\xd3\xd8\xa1\xdb\x9c\x5b\xf5\x51\xd6\xa3\xc4\x9a\xc5\x29\x49\x70\x95\x36\xa5\x64\xb3\x93\x4a\x55\x2a\xfb\xaa\xdb\x13\x9a\xcc\xbb\x3e\xd4\x2f\x37\xfd\xf0\x05\x86\x70\x57\x62\xae\xde\xe0\xea\xe4\xfd\x55\xfe\x31\x19\x93\x79\xf1\xff\xea\x08\xa5\xb7\xb1\xbf\x0a\xe7\x96\x25\x22\x35\xe1\xb9\x7a\x29\xd0\x8b\xbc\x42\x16\x67\x5d\x7e\x31\x78\xe2\x57\xd6\x35\x21\xaf\x66\xcf\x3f\x93\xc4\xc8\x60\xf6\x80\xa4\x93\x6b\x68\x65\x3e\xe0\x73\xff\x31\xb9\x75\x99\x75\x2c\x78\x03\xba\xf6\xd8\xfb\x5d\xb5\x38\x57\x84\xe9\x46\x3a\x01\x68\xd4\x15\x37\x33\x3d\x53\x16\x4b\xa6\x74\x30\xcf\x72\xbe\x40\xcb\x6e\xbd\x38\x9d\x51\x13\x59\x2c\x79\x94\xb0\xc0\xd6\xaa\x8a\x42\xd6\x7b\x39\xae\xba\xb3\x58\xa6\x0c\x11\x11\x08\x77\x72\x6b\xa4\x03\x95\xd8\xf9\xde\x1a\xab\x28\x16\x5e\xd8\xc2\xed\xc1\x7f\xab\x4b\xcc\x62\x23\x93\xde\x23\xdd\x31\x49\x4d\x80\x60\xf9\x11\x90\xa5\x88\xde\x5a\xdd\xad\xb7\x68\xb2\x77\xf3\xb0\xd9\x6f\x17\xb7\xab\xed\x6e\xf1\x6d\x15\x87\x61\x36\xe3\xa9\x8b\x8c\xbb\xcd\xf1\xf7\x4f\x0c\x15\x19\x89\xe2\x14\x5b\xcb\xb2\x6e\xf3\xa6\x5d\x1d\x64\xee\xfb\xa3\x8c\x90\x2e\xb6\xf2\xb1\x4f\xde\x7e\x60\x7a\x74\x49\x6a\xe9\xec\x2f\xbe\x5e\xc5\x08\x49\x28\xa6\x84\xdb\xc5\xdd\xd3\x66\xb1\x0e\x5f\x4c\x09\xd3\x3e\x16\xda\x1e\xab\xb2\xa9\x6a\xd4\x8c\x0f\x55\xf8\x10\xc8\x10\xca\x2d\x92\xb5\xe4\xf1\xb6\xd2\xaf\x43\x3e\x11\x0e\x27\x71\xa6\x42\x35\x0c\x4b\x4a\x37\x55\x7d\x93\xd7\xa1\x20\xc3\x08\x4d\x39\x0a\x80\x3b\xc3\x8e\xee\xa1\xf6\x47\xac\x2b\x30\x37\x27\x75\xc8\xb1\xeb\xef\xf4\x20\x67\x3b\x33\xe9\x92\x4f\x36\x82\xe2\x07\x65\x9c\x5e\x9f\x68\x7a\x4a\x2c\x05\xaf\xa0\x8d\x59\xb2\xaf\x98\xaf\xcb\xc7\xba\x7a\x1e\xa5\x5a\x84\x27\xdc\x19\xd9\xe7\x1a\xca\x26\x24\x3f\x33\x58\x3c\x23\x02\x08\x16\xcd\xde\x42\x56\xb9\x85\xfe\xda\x12\x42\x51\x12\x79\xdf\x04\x2f\xd8\x4f\x48\x39\x8c\x24\xd2\xe9\x99\x23\x06\x6c\xe4\x50\x3d\x9b\x0a\x89\xb1\x48\x09\xc7\xe9\xdd\xad\xe2\x6f\x17\xed\xab\x18\x49\x23\x82\x49\x50\xa0\x7b\x3f\x5c\xef\x6f\x76\xb7\xfb\xed\xe3\x6a\x15\xa2\x09\x92\x12\x8a\xc9\xe4\xea\x66\xb1\x1d\x4a\x72\x8c\xa4\x9c\x10\x8f\xf5\xbe\x9f\x19\x28\x30\x92\x19\xc6\x5c\xc6\xe4\xc4\x0e\x3f\x9c\x48\xd7\x99\xcc\xc2\x0c\x8c\xe3\x3f\x2d\x53\x69\xfc\xb4\x5a\xfc\xf3\x76\x76\xce\x52\xc5\x38\x97\xee\xba\x7c\xa7\x7a\x7e\x2e\x46\x92\x1d\xdd\x51\x82\x6f\xb6\x3a\x7d\xec\x72\x3d\x7a\x5d\x47\x59\xe4\xe5\x9b\x26\x35\x75\x71\x7d\x25\x8b\x75\x89\xf8\xd8\xfe\x29\xab\x44\x70\x7f\xad\xb7\xf9\x30\x2b\x55\x16\x85\xf3\x74\xa1\xeb\x6e\x20\x69\x31\xa2\x74\x8a\xe5\xf6\x53\x89\x9e\xd3\x8b\xf2\x79\x62\xd5\xce\x88\x61\x02\xb7\xd2\x30\x25\x1d\x68\xe0\xb3\xa2\x31\x23\x26\xa1\xca\xdd\x54\x69\x86\x8a\x2c\x43\x57\xbe\x9e\xbc\xb6\x81\x2e\x6f\x92\xc5\x8f\x7e\x83\x22\x20\x99\x10\xbd\xf2\xaf\x9a\x15\x2b\x18\x8d\x04\x60\x73\x64\x71\x6a\xab\xda\xb5\x17\xaf\xa1\x90\x1f\xfd\xee\x48\x63\xea\xa4\xbd\x5d\x7f\x20\x77\x00\xd0\xe0\x48\x32\x4d\x5a\x68\x4c\xad\x03\x4a\x16\x20\xbb\x00\xa1\x41\x50\xd4\x59\x2e\x1f\xae\x8a\xc6\x9c\x62\x03\x7f\xdb\x56\x25\x3c\xca\x63\x1f\x2e\xd1\x18\x58\x4c\x02\x3c\xcf\xb7\x8f\x36\xb2\x9d\x21\xc3\x19\x8d\x2d\xb7\x63\x35\xcb\x1b\x08\xc5\x03\x3f\x80\xc4\x5c\x42\xdf\x67\xee\xf6\xac\x9b\x53\x39\x61\x2b\x32\x4a\xb8\x03\x28\x6d\xff\x7b\xca\xeb\x71\x7a\x44\x89\xce\x88\x0e\x6e\xb0\x81\x6c\xa2\x2b\x24\x25\xc7\xb3\x53\x21\x36\xd2\x0e\x07\x8f\xc1\xce\x12\xbb\x6d\xfe\x8e\x39\xa7\x9c\xb9\x18\xd8\x2f\xf5\x69\xfb\x82\x65\x3f\xc9\x29\x95\x2c\x4b\x7b\xe5\x94\xee\x19\xc8\xbc\x1c\x4b\x49\x75\x43\x52\x64\x42\x76\xe1\x6a\xf5\x25\xd8\x8a\x51\xa6\x33\xa7\x37\x8c\xb1\xe1\x3d\xbc\xdf\x39\x17\xa7\x2f\x0b\xbb\x8c\x32\x93\x20\x1e\x49\x06\x71\xe8\x98\xdc\x55\x65\xfb\x12\xde\x1a\xca\xa9\xc6\x12\xed\xb1\x6a\xda\x3b\x24\x65\x2c\x0b\xe9\x7d\x15\x3d\x18\xba\x9f\x35\x5c\xa7\x98\xc2\xba\xdc\xff\x2a\xef\xa7\x5e\xc2\x85\x5b\x60\xab\x67\x8c\x73\xaf\xc0\x56\x75\x78\xc7\x68\x1a\xb3\x00\xbb\xc2\x2a\xe1\xb1\x9b\x3f\x8b\xcb\x24\x65\x46\x53\xed\xf0\xd2\xee\x47\x56\x48\x31\xbc\xbc\x84\xd2\x2c\x12\x41\x24\xb1\xdb\x53\xfc\x7b\x33\x1b\x13\xc7\xca\xa3\xcd\x7e\x54\x75\x03\x58\xb1\x98\x8d\x91\xd4\xe1\x62\x37\xdd\x0b\x35\x7b\xef\x24\x07\x7c\x6f\x37\xab\xfb\xd5\x9f\xfb\xc5\xee\xe1\x6e\xbd\xdc\x6f\x57\xbb\xdd\x2d\x5a\xbe\xee\xd7\x61\x0d\xa6\x2a\x4a\x98\x6b\x89\x76\xab\x8c\xfb\x9d\x8b\x4b\xe8\xc5\xa0\x24\x26\xe9\xec\xea\x54\x4a\x6c\x1c\xd6\xb3\xa0\xd2\x1e\xf7\x47\x0d\xe1\x5e\x2e\xef\x1e\xde\xaf\xa0\xbd\xa0\x59\xcf\xa8\xb1\x80\xdf\xa1\x90\x58\x18\xce\x14\xe2\x04\xf1\x9c\x25\x80\x01\x33\xb7\x64\x67\x14\x52\x82\xbd\xea\xb7\x6a\xd6\x78\x4d\xc3\x00\xc5\xb1\x37\xd1\xe0\x74\xbe\x75\x4a\x8d\xfe\x98\x95\x14\xcb\x4e\x77\x8f\x2f\x55\xe9\x23\xb6\xfe\x98\xd6\x99\x97\x36\xdb\x54\x0d\xac\x76\xdf\x27\x3b\x12\xb5\xc6\xe5\x5e\xb8\x1f\x91\x47\x6f\x2a\xde\x63\xf2\x2f\x20\xf4\x59\x97\xcd\x05\x15\x35\x47\xa1\xbf\x38\xad\x58\x4c\xdc\x3a\xee\x6a\x3e\xdf\x50\x08\xca\xc9\xca\x87\xde\x0e\x8e\xb1\x08\x29\x43\xa1\xa9\xad\xab\x31\x0f\x07\x33\x8c\x61\xdc\xad\x9c\x61\x64\x19\x8b\x41\x30\x31\x12\xae\x1f\x53\x42\xa6\x01\x02\x23\x19\x15\x28\xab\xf8\x75\x5e\xc1\x48\x66\x31\x31\xe9\x96\xcc\xeb\x5a\xbe\x2f\xca\x0f\x54\xc3\xf9\xa2\x7a\xc8\x88\x95\xd8\x38\x35\x70\x2c\xaa\xc0\x24\x3d\xdb\x5d\xc3\xba\xde\x2d\xcb\x81\x71\xb2\x78\x93\x79\xd1\x6d\x8d\xb8\xab\x2e\x7b\xf7\x8c\x30\x2b\x18\x25\x06\x9c\x9a\x53\x5e\x23\x82\xe1\xd8\x53\xb9\xfa\x21\x3c\x85\x68\xc4\xcc\x73\x0a\x51\x6e\x66\x3a\xe1\xdd\xe9\x9d\xa0\x2a\x53\xd0\x9b\x9e\xe7\x07\xe8\xa6\xd2\x6c\x0c\xcb\xb2\x78\x90\xc8\xcc\xcb\xe7\xee\xce\x8e\xeb\x4a\x8c\x83\x42\xb0\xd4\x2e\x18\xd2\x85\x03\x82\x2b\x2b\x7a\x39\xb9\xeb\xd3\x05\x1a\x1b\x63\x49\x12\xe3\x5c\xee\x76\x1d\x30\x67\xcf\x35\xb1\x4e\xf6\xe1\x54\xb6\x7d\xac\xce\xd2\xd4\x91\x7d\x5d\x41\xe2\x31\xf4\xa8\x19\x4b\x95\x06\x39\x6e\x49\x61\x3e\x7c\x7f\x1a\x44\x53\x67\x73\x01\x81\xa1\xfe\x25\xaf\xf4\xeb\xe4\xba\x32\xce\x44\x3a\x31\x0c\xdc\xf4\x60\x4f\xc6\x32\x49\x83\xf0\x28\xd2\x98\xbc\x8a\xb7\x83\x37\x5f\x5c\x2f\x99\x8c\x25\x56\xb6\x97\xab\xdb\xf5\x43\x88\x11\x99\x54\x1a\x45\xb7\xf7\xee\xd5\xf0\x0a\xf1\x63\x97\x5e\xc6\xa4\x8e\xb0\x6d\x7f\xb7\x58\xdf\x63\xfa\xb3\xdf\xee\x16\x9b\xdd\x7e\xb7\xbe\x5b\xf5\x63\x2c\xc1\x0d\x7c\x07\xcf\xd3\x79\x77\x01\x07\xc2\x98\x4a\x34\xb5\xc1\x37\xef\xa7\x5b\xba\x1f\xec\xa4\x10\xc7\x74\x6c\xb2\xc4\x03\xa5\x66\x27\xa4\xd3\x8c\x64\x43\xce\x8c\x3a\x8d\x13\x83\xa5\xd1\x56\xcc\x8c\x14\x98\x56\x80\xc9\xdb\xbb\xca\x9c\x2e\xb4\x43\x27\x0b\x74\x58\x5a\x8c\x26\xc4\x53\x8d\x36\x70\xa8\xde\xba\xb7\x63\x6d\x30\x02\x5c\xb7\x70\xd6\x19\xfc\xf7\x7f\x3e\x27\x1f\x0d\x0f\x01\x64\x44\xfa\x6c\x7f\xcc\xbc\xc5\x1c\x66\x36\xfb\x40\x32\x8c\xa3\x1f\x1e\x57\x9b\x05\xea\x3a\x2d\xee\x1e\x9e\x82\xd3\x38\x63\x36\x62\xd8\x02\x9d\xfa\xdf\xa2\x20\x18\xc8\x50\x55\x23\x9f\xac\x15\x36\x72\x0d\x02\x0f\xf5\xb6\x15\xfa\x0f\x41\x0b\xb5\xf3\x9a\xf2\x3f\xc2\x23\x15\x6b\x8f\xf2\x5c\x3a\x79\xd9\x2e\x32\x1b\x9b\x82\x5c\x7a\xc2\x3c\x56\x5a\xfa\xa7\x77\x2a\xda\xfd\x5b\xd5\xd3\x7e\x19\x8f\xad\xb3\x7e\xdb\x39\x77\x7c\x1b\xfe\x4e\x38\x60\x34\x59\x54\xef\x03\xb1\x99\x71\x4a\x34\xda\x9e\xa9\xa2\xd2\xaf\x1e\xb3\x3d\xdd\x12\x46\x91\x24\xa7\x2a\x0b\x5b\xe3\x83\x17\x5f\xf4\x9d\xe1\x5f\x38\x8a\x85\xcf\x5b\x9a\x06\x12\x0f\x76\xad\x75\x2e\xeb\x0f\xac\x64\x4c\x9e\x0e\xa7\xd6\x89\x6f\xba\x98\xcc\x61\x3f\x2f\xd8\xac\x33\xce\xa8\x46\x6a\x44\xde\x5c\xc3\xb1\x06\x0c\xc4\x66\xdf\xc5\x98\x7f\x18\x83\x17\xf2\x04\x14\xc8\x38\xe7\x26\xf6\xec\x45\x8f\x08\x3c\xcb\x12\x38\xcf\x08\xb3\x23\x06\xe1\x1f\x55\x71\x0a\xd0\x83\xe9\x48\x21\x0c\xd6\xdb\xfe\xaf\x52\x8f\x3d\xd0\x8e\x71\xe1\x89\xf9\x4d\xeb\xee\x74\xff\x77\x9b\x80\x2f\xfc\x7c\x97\xcd\xcb\xd5\xc7\x25\x66\x79\x37\x4c\xa1\x24\x43\xdf\x58\x40\xf5\xb6\x8b\xdb\x20\x4f\x32\x91\x46\x7d\x2d\xeb\xa9\x81\xda\xb9\x1e\x5f\xe2\xa3\x31\x9e\xe8\x18\xbb\xaa\xce\x99\x7a\xe0\x24\xcf\x47\x09\x84\x97\xda\xaa\xd6\xb0\x2a\x0d\x76\x9e\xfc\xb1\x94\x51\xe6\xa0\x4e\x79\xb7\x15\x6d\x46\x7e\x83\x8c\x67\x4c\x90\x69\x9f\x63\xe1\x54\xff\x3f\xd1\x3f\x60\x3c\xd3\x84\xb3\xbe\xdf\x38\x87\xbe\x7d\x19\x95\x73\x49\x38\x4a\xdf\xfc\xf7\x04\xf5\xc7\xa0\x5c\x3f\xbf\x66\x29\x15\x46\x94\xbd\xcd\xe7\x52\x1e\xc3\x09\x4b\xe3\x80\xc7\xbe\x7c\x7b\x3d\x7a\x5b\xb4\xd0\xbd\xf3\xea\x5e\x16\xc5\xfe\x34\x32\xb0\x66\x5c\x27\xcc\x31\x00\xf3\xe7\x21\x8a\x98\x9c\x9e\x4e\x34\xb6\xe1\x86\x9b\xb1\x0b\x67\xf0\xf7\x0a\x6b\xdc\x24\x2a\x09\x6a\x7c\xfa\x05\x9a\xed\x68\x1e\x1b\xe3\x04\xd8\xbb\xe7\xe0\x9c\x22\x5b\x59\x4c\x12\x23\x0e\xdc\x22\x3c\xa6\xae\x4e\xcf\x2f\x93\x43\x22\x22\x29\x0a\xd1\xf9\xe4\xad\x1e\x69\xfe\x4e\x4e\x41\xc4\x8c\x09\xd3\x73\xce\x35\x34\x4d\x5e\x3e\x9f\xb5\xe5\x44\xcc\x9d\xe3\x4e\x03\xed\x4d\x0d\xf0\x97\x53\x12\x69\x4f\x63\x46\x35\x13\x44\x24\xd8\x22\x39\xe4\x65\x1b\xe4\xdb\xfb\x5b\x31\xf9\x3e\x02\x12\x6b\xe1\x4b\x5f\xa1\x0d\xfa\xe4\xd3\x47\x2b\x88\x65\x98\x72\xa8\x8f\x56\xd6\xf5\x90\x79\xfb\xc3\x54\x68\x18\xdc\xe3\x1e\xeb\xea\x50\xdd\x55\x65\xd3\xce\xf0\x09\xd3\x37\x4a\x20\x0e\xdb\x63\x13\x1f\x4a\xf8\xd1\xa7\xc7\x82\x11\x8b\x35\xa9\xdc\xdb\x1b\x9e\x85\xa8\x61\x1c\x4b\x70\x15\x2a\xaa\xea\xf5\xe9\xe8\xd0\xa2\x75\x78\x21\x2f\x46\x30\x82\x47\x4e\xa3\xf5\x5b\x15\x64\x97\x99\xe0\xdc\x62\xd3\xff\x58\xe7\x65\x3b\xf2\xe6\x63\x82\xa7\xae\x87\x71\x94\x75\x83\xef\xfc\xba\xcc\xdf\xce\xe1\x9d\x61\xb4\x8e\xb1\x47\xf4\x26\xcb\xbc\x79\x39\x47\x80\x33\x21\x18\x43\x7d\x0a\x7b\xea\xaf\x35\xc9\x34\xd6\xcb\xdc\xba\xe2\x38\xd4\x67\xd6\x8b\x4c\x64\x2c\xc6\x47\x3a\x04\xaa\xee\x29\x10\xbf\xfb\x0b\x99\x66\x08\xb0\x6b\x5e\xaa\xe3\x75\x75\x52\x43\x1d\x42\x48\x93\x31\x13\x5e\xcc\xf0\x8c\x57\xb8\x32\x5d\x00\xf5\x30\x21\x21\x45\x75\xb1\x9b\xbb\x6f\xdf\x57\x8b\xdb\xdd\xf7\xe5\x62\x13\xe2\x26\xa1\x24\xc3\x67\xb3\x7d\xc9\x9b\x97\xd3\xaf\x54\xd2\x98\x50\x5a\x07\xb2\x6f\xe0\x20\x85\x23\x96\x21\x65\xfd\x3d\x2f\x4b\x8c\x87\x1c\x82\xd8\x1f\xd5\x11\x0d\x3a\x59\x7d\x73\x7d\x56\xa5\x11\x5a\x12\x34\xf7\x39\x35\x50\x7f\x26\x57\xe0\x87\x9a\x98\xe1\xf2\x0d\xed\xcb\xae\x7a\x6a\x66\x3b\x81\x30\x69\x1a\xf9\x7a\xd6\xdd\xc7\xa3\xd4\xb9\x1d\x6a\x72\xc2\x64\xce\x16\x70\xe8\x3d\xcd\xf7\x88\xfe\x4d\xb0\x69\x9a\x8c\x0c\xc0\x73\x84\x1a\xb7\x9f\x55\x55\x93\x88\xa5\x48\x53\xb1\x79\x51\x4c\xbc\x5b\xff\x76\x09\xe7\x57\xff\x8e\xa8\x9b\x17\xa8\x8d\x2c\x89\x78\x8c\x41\x81\xdb\xa8\x90\xfe\x39\xdf\xa6\x93\x28\x91\xce\x43\xa9\x81\x76\x73\x86\x03\x48\x22\x15\x61\x21\xbf\xaf\x95\x8d\xc5\xb7\xa7\x43\x49\xa2\xb0\x86\xeb\x70\x55\xbe\xb2\x3d\x2d\xf6\x25\x44\x51\x57\x1b\xc3\xa4\x6d\x1c\x46\x27\x04\x54\x22\xfa\x46\x51\x77\x6f\x51\x88\x7e\x3c\xdf\x12\x9a\x64\xa9\x8b\xe3\x9c\x0e\x1c\x56\xd7\xe5\x61\x10\x09\x1b\xce\x86\xc5\x11\x2a\x15\x5a\x6c\x62\x06\x89\x4c\x7f\x90\x0b\xc0\x3c\xe3\x8f\xfc\xb5\x72\x82\x85\xd3\xe0\x71\x7a\x8b\x78\xa6\xe9\x00\x14\xfe\xe7\x69\x5e\x8a\x20\x33\x57\x28\x96\x88\xc4\xc9\xd9\x3a\x51\x93\xfc\x12\x7f\xd6\x8f\x4c\x48\x8c\xd8\x17\xb7\x75\xaf\x4a\x33\xda\x3d\x93\x94\x09\x34\x29\xd8\xe0\xc1\xee\x19\x9e\x89\x7d\x86\x91\x32\xd1\x59\xa8\x2c\xbb\x7b\x33\x4f\x1f\x93\x54\x2a\x24\x54\x43\xfb\xf2\xd4\x98\x11\x5b\x8f\x25\xa9\x92\x2c\xf1\x9c\x99\xa7\x52\x3b\x64\x3e\x96\x45\x67\x3f\x63\x13\xed\x15\x36\x71\xcb\x5b\x05\x5e\x39\x4b\x32\x4b\xb0\x92\x89\xde\xf0\xfb\xeb\xd5\xe2\xfa\x76\x1d\xe4\xca\x58\x22\x69\xec\xf3\xc7\x57\x28\xf7\xe5\x00\x80\x49\x24\x15\x56\x05\x95\xf7\xb7\x7e\xdd\x4e\xa4\x96\x18\x97\x60\x1f\xed\x33\xa6\x2f\x4b\xa4\x65\xc2\x33\x9a\xae\x4e\x75\xe9\x51\xd8\x7e\x9b\xb8\x93\xc7\xf9\xf2\x35\xfd\xb4\xd2\x09\x26\x40\x77\x8b\x3f\xf7\xbb\xcd\xe2\x7e\x7b\xb3\xda\x74\x89\xe4\xf6\x71\x11\x72\xd2\x44\x19\xd7\xae\xad\xe5\xfb\x9d\x2c\x4f\xb2\x28\x3e\x5c\x2b\x61\xdc\x1f\x99\x4d\x3e\xad\x34\x56\x53\x8d\xac\x73\xd9\x42\xbf\xda\x24\x90\x4a\xec\xeb\x20\xbb\x7b\x7f\xb7\xbe\xdf\xf5\x3a\xed\x2c\xb1\x89\x89\x5d\x2d\xcc\x13\x67\xfa\x03\x29\x38\xb2\xad\xae\x96\xf2\xe8\xb6\xf3\x4f\xb0\x67\x89\xcd\x12\xad\x03\x18\x73\x04\x28\x99\x8f\xca\x84\xf1\xdd\xc6\x6f\xdd\xb4\x7e\xf1\x12\xcf\xe1\xb8\xa1\x41\xa4\x7b\x59\x81\xed\xf2\x0e\x28\xdb\x11\xf8\xe9\xf3\x64\x2b\x8d\xb4\x4b\x0e\x9e\xa1\x7d\xcc\x8b\x42\xba\xc2\x43\xf3\x7b\xde\xf6\x2a\x2d\xb3\xfa\x62\x4a\x52\x80\xd4\x91\xac\xf2\xe7\x97\xb1\x46\x10\x4b\xa9\x30\xde\xbc\xb8\x34\x7e\x93\x69\xfa\x63\x90\xc5\x63\x4a\xf4\x65\xa2\xf7\xec\xc7\xa8\x25\xc8\x2e\x0d\x90\xab\xca\xe6\x05\x5c\xbc\xa0\xe9\x75\x09\x42\x8d\xaf\x18\x4e\x49\xe1\xd3\x97\x3f\x15\xa9\x45\x6d\x0c\xe9\xe8\x7c\x8f\xf2\x03\x37\x63\x19\x30\x22\x69\xc2\x33\xc3\x47\xf9\x15\x9a\xe7\x7e\xde\xc7\x49\x13\x91\x65\x2e\x65\x73\x0c\x86\xbe\x3c\x36\x5d\x5c\xd3\xcc\x7a\x5a\xab\x2c\x34\xf2\x74\xc7\xef\x78\x2a\x93\x08\x77\xe4\xb9\xd6\xa1\x08\x03\x14\xe7\x89\x7f\x6e\xd7\x79\x73\x3c\xf5\xeb\x50\xaa\x44\x92\x45\x23\xf7\x9e\xe6\xb3\xf2\x46\xaa\xb4\x93\x9b\xff\xd3\x76\xfb\x69\xd0\x20\x09\xdf\xa3\x4d\x16\x74\x7b\xae\xeb\xaa\x84\xc7\xa0\x02\xcc\x52\x6d\x4d\x34\x3c\x94\xab\xaa\x6a\x3f\xae\x46\x6a\x47\x7e\x94\xc9\x5c\xc1\xa2\x3f\x91\xab\x8f\xd5\xee\xfb\x74\x6e\xa7\x10\x4b\xac\xdc\x2e\xfe\x58\xac\x6f\x17\x57\xb7\xab\xbd\x13\x5c\x0c\x3f\x65\x63\xa7\x80\xd1\x05\xd0\xb7\x95\x7e\xf5\xd5\x9c\x2f\xbb\x7d\xa9\xe5\x51\xd8\x9d\x96\x52\xbf\xcc\x4e\x2c\x8b\x12\x81\xaa\x52\x50\x36\xa7\xda\x89\x79\x0e\x6b\x59\x16\x47\x46\x44\x67\xae\xce\x9f\xe2\xa6\xc6\xb3\x2e\x8b\x65\x0a\x43\xb1\xf8\xf0\xea\xc1\xca\x93\xb3\xcb\x48\x14\xe3\xb3\xbd\x7d\xf8\xb6\xbf\x91\x79\x01\x66\xc2\xda\x98\x0d\xa6\xd6\x0d\xae\x9e\x37\xe8\xb5\x79\x5f\xb5\x68\x64\xf0\x85\x90\x04\xcb\x88\x55\x08\x7c\xba\xfa\x16\x6e\x64\x46\x23\xe7\xb0\x80\x05\x43\x59\x3e\x95\x32\x4c\xcc\x4b\x8d\xbe\x8c\xc6\x4e\x48\xf6\x0d\xea\xdc\x7e\x6c\xa1\x7e\xcb\xf5\xfc\x3e\x52\xc2\x30\x3e\x70\x56\xda\xb7\x93\x26\x70\x18\x22\x75\xe4\x85\x5c\xaf\x64\xdb\x16\xe7\xf8\xc6\x8c\xaa\x4c\x8d\xcc\x70\xf2\x5e\xb2\x87\x65\xd4\x46\x71\xcf\xbe\xd9\x4a\x0b\x13\x57\x91\xf3\xde\xef\xf4\xf4\x18\x8d\xb0\x7d\x74\xb5\x5b\xee\xb7\x4f\xeb\xed\x76\xb5\xdf\xad\x57\x9b\x7d\x00\x5f\x64\x9c\x12\xd4\x0b\x35\xd5\x7b\xb9\x7b\x81\xeb\xba\x77\xa7\x63\x19\x67\x59\xf0\x47\xb9\x93\x3f\x7b\x90\xba\x93\xe4\xeb\xc9\xac\xd3\x2b\xe1\x5e\x37\xbc\x1b\xb8\xfa\x99\x37\xed\x0c\xf2\x99\x71\x9b\x6a\x17\x93\x3e\xd7\x12\x43\x04\x57\xbb\xf3\x87\x85\xb1\x58\xda\x74\xf4\x99\x7f\x9e\xaa\xfa\x74\x98\xd6\x72\xb2\x84\x49\x70\x55\x65\x67\x73\xb5\x70\x24\x63\xdf\xc1\x0a\x83\x54\x82\x6c\xb2\x0f\x54\xb0\xc0\x82\xde\x18\x76\x95\x75\xdb\x1a\xef\x67\xe9\x12\xea\x2f\xb4\x42\x59\x96\x2a\xb0\xde\xdc\xb0\x2e\x2a\x69\xc0\xdc\x41\xfb\x72\xfe\x0e\x86\xe1\x56\xe1\xa6\xb9\xba\x5d\xff\x19\x7e\x30\x23\x2e\x5a\x5c\x2f\x1f\xb0\xfc\xdb\xff\x9d\x3a\x86\xf3\x5e\xd5\x00\xa6\xcb\xc8\x3f\xab\xaf\x86\x0f\x08\x57\xfa\x19\x77\x6b\x51\x52\x7b\xf6\x24\x32\x88\xe2\x34\xc8\xd1\x9c\x74\x3b\x65\x69\xb3\x4c\x8a\x14\x23\x1c\x17\xab\x79\x2c\xc1\xe5\xeb\x91\x99\xe1\xa3\xba\x41\x77\x92\x83\x22\x8b\x1f\xa3\xb8\x53\x25\xe9\x09\x6f\x8f\x75\x5e\xea\xfc\x58\xc0\x68\xc9\x0a\x63\x33\x88\x87\xe9\xfe\xfd\x74\x90\xe5\xd4\xfd\xf0\x52\xa5\xf1\x33\x65\x6e\x96\x29\x99\x20\x48\xe7\xdb\xfd\x72\x08\x37\x3f\x49\x59\xfc\x47\x34\x8f\x32\xef\xee\xf4\x2e\x73\x2c\x80\x6f\x56\xbb\xeb\xd5\x25\x10\x49\xa6\xd3\x4c\x46\x4e\xb3\xe9\x4a\x5e\x8d\xc9\x48\x2c\xd3\x3a\x03\xd9\x97\x99\xb0\xda\x72\x25\xbb\x59\x79\xf5\xf1\x6d\xa8\x1b\x65\xda\x6a\xe1\x0a\x5e\x9e\x5b\x37\xfd\x05\x43\x5c\x43\xb2\xe9\xd9\xfb\x2c\x33\x4a\xf0\xa0\xc2\x31\x35\x67\x65\x99\xd1\x2e\xc4\xc0\x52\xdd\x0f\xdf\xe2\xda\x55\x8e\x12\xf8\x49\xd2\x99\x19\x2b\x91\xa7\x34\xc0\x2a\x7b\x18\x64\x3b\x82\x39\xcf\x58\x5e\xd3\xef\x80\x54\x62\xc9\xe0\x30\x11\x5a\x65\x19\x48\xc7\x6a\xec\xa6\x52\xe3\xaa\x83\x23\xb3\x48\x96\x81\x8a\xf1\xad\x57\xb2\x7c\x85\xba\x71\x3d\x59\x7f\xcc\xa6\x11\x2e\x7e\x2e\x84\x5c\x39\x57\xb5\xd1\x41\x1d\xe0\x91\x17\x6d\x70\xdd\x38\x19\xa5\x1a\x4b\x5b\xbb\x87\xdd\xe2\xd6\x79\x03\xff\x16\x0e\xa9\x14\xcd\x86\x6c\x5d\x1d\x76\x79\x01\xbe\xf0\x1a\xf7\x1f\xd5\x31\x06\xa0\xae\x69\xfe\x47\x85\xee\xbd\x4b\x59\x1a\x94\x31\xbc\xfa\xd8\x96\xf2\xd8\xbc\x54\x6e\x95\xf9\x7a\xd7\x95\x71\x12\x47\x21\x4c\xbd\xf7\x22\x62\x4b\x59\xb6\x57\x35\xf4\x8e\x16\x4c\xc6\x0a\x82\xec\xaa\xd3\x1d\x9a\x7d\x89\x71\x6a\x22\x21\x48\xbc\xca\xcd\x4d\x55\x6f\x5f\xa1\xd5\x33\xd0\xa0\x24\x84\xe9\x68\x02\x46\x3f\x42\xd9\xd3\x50\x99\x24\x34\x8a\x07\x3b\x64\x44\xfd\x84\x43\x9c\x72\xa4\x03\x05\x7f\xf0\xcb\x25\x2a\xc9\xa9\x61\xbd\x9a\x7a\x1f\x21\x48\x2e\xa2\x10\x33\xdf\xc9\x9f\x4b\x39\x43\xbc\x49\xae\x09\x38\xc1\xb0\x9f\x23\x21\x95\xee\xef\x1a\xa1\x38\x5e\x6f\x27\xa4\xd4\xd3\xab\x12\xc2\xd9\x57\xa3\xfe\xe8\x20\xe8\x34\x1c\x45\x01\x91\x4a\xfd\x1f\xe8\xf6\x5b\x51\xbd\x0d\xd7\x9b\x30\x82\x24\xf8\xa3\x2c\xf3\x51\x63\x5d\x26\x89\x8b\x37\x70\x1a\x1d\x2b\xb7\x6a\x8e\xdc\x97\x98\x4c\xc0\x29\x30\x8d\xcd\xd3\x2f\x56\xd3\x65\x1a\x19\x13\xa8\x73\x55\x55\x5c\x08\x6f\x64\x4a\x04\xaa\xb0\x9d\xca\xc0\xf1\x9e\xd7\xb8\x67\x5f\x99\x11\x64\xa6\xe7\xcd\x63\x71\x7a\xce\xcb\x5e\xda\x29\x9c\x9d\x14\x09\x76\x1f\x4b\x78\xf7\x1e\x44\x5f\xf7\xbf\xa5\x4c\x1d\xe1\x77\x61\xcc\x98\xa7\x3d\xff\xd0\x85\x45\x35\xfc\x33\xd9\xb6\xa5\xca\x04\x82\xdf\xff\xdc\x6c\xda\xd1\xfa\x27\x95\x02\x14\xbf\x78\x9c\x88\x62\x30\x69\x98\xb3\x99\xce\x75\x75\x2d\x3f\xfa\xe7\x03\xc4\xa5\x69\x41\x4a\xe6\x3b\x14\x50\xe6\x33\xff\x6b\x26\x81\xa5\xb8\x3c\x57\x65\x97\xb9\x2e\x65\x51\x80\xf9\x6d\x3a\x22\x91\xb8\xe6\xcb\xc0\xcd\xe9\x66\xf0\xe5\x5b\x01\x36\x0a\x6e\xce\x7f\x74\xe9\xad\x2a\x86\xf9\x62\x33\xe3\x00\x33\x01\x19\xb4\xac\x0e\x2a\x18\xad\x4c\x9e\x91\x8a\x92\x34\xb2\xbe\x33\xd0\x5e\x48\x51\x15\xb1\x16\xdf\x45\x47\xeb\xac\x97\x17\x5c\x97\xfc\x48\x1a\x5b\x35\xce\x0a\x06\x82\xd1\x97\xbb\x96\xa2\x22\x41\x12\xc8\xbe\x95\xaf\x80\x6b\x4b\xf3\x92\x9f\x39\xf3\xf9\xc1\x8c\x39\x86\x81\xff\xeb\xae\x9a\xac\x5f\x63\x86\x21\x53\x4c\xbb\x72\xed\x5d\x75\x80\xb2\x95\x05\x7a\x1a\x84\x97\x47\x71\xe2\xa8\xe9\x43\x4b\xe3\xb1\x86\xab\xd3\x07\xf6\x3a\x1d\xad\xe7\xd3\x5c\x50\x71\x9d\x59\xda\x57\x4e\x0f\xc7\x4b\x14\x18\xc5\xc1\x08\xcf\x9b\xaa\x6a\xbc\xb0\xb1\x6c\x13\x53\x42\x50\x04\x3d\x4a\x64\x6a\xae\x9b\x42\x96\x97\x69\xb3\x4c\x89\x44\x05\x85\xac\x1f\x20\x5f\xa1\x04\x73\x0d\x16\xa1\xab\x88\x7b\x9f\x8e\x4e\xd3\x0c\xc3\xd5\x97\xaa\x30\x7d\xc7\x37\x1c\x03\x9e\x42\xe8\xa0\x63\x60\x76\xf9\xa9\xa4\x90\x20\x4e\xd4\x6b\x76\x9e\x3f\xc4\xb3\xd2\xdb\x70\xe3\xb3\xd8\xf9\x5f\x35\xef\x72\x16\xbf\xa9\x2c\x76\x90\x11\x5d\x95\x2e\x80\xfb\xad\x3f\x60\x1d\xc9\x6d\xb1\xd9\xdd\xaf\x36\xdb\xfe\xef\x2c\x36\x6a\xd4\xa7\x18\x6b\x64\x85\x21\xca\x71\x97\x10\x65\xec\xca\xca\x07\xac\x55\x6d\xe0\xbf\xfd\xd7\x28\x83\x38\xc1\xab\xe2\x04\xd7\xb9\x3c\x54\x65\x3f\x11\x32\x1b\x63\xac\xea\x76\xca\x65\x55\xbe\x39\x57\xee\xd9\xaf\x48\x15\x89\x78\x62\xdb\x7d\x5f\x8d\x63\x45\x25\xb5\xc5\x58\x71\x98\x50\x7f\xdc\x5e\xff\x8a\xcc\xa4\x54\xec\xa0\x3f\x87\xbc\xbc\xc9\xcb\x32\x38\xaf\x87\x93\x53\x89\xc1\x10\x2b\x6f\xe1\xf0\x3d\xef\x6e\xc0\xc7\x83\x7d\x9c\xd8\xb7\xcf\x1e\x9c\xb2\x8a\x0f\x9a\x64\xbd\xde\xee\x48\x53\x7c\x7a\x02\x3a\x31\xd6\xdd\x99\x4a\xbf\x36\xbb\xea\x5b\xa0\x3d\x2a\x6d\x1c\xd3\xc7\x07\x2f\xfd\x14\x32\xdc\xe9\x7c\x97\xf0\xfe\x88\x05\x8c\x91\x1a\x2b\x53\x46\x39\x46\xc7\x1d\x34\x8d\x7c\xee\x56\x30\xf8\xac\x17\xea\x3f\x01\xc4\x91\x38\x1a\x68\x17\x6d\x75\xf8\x06\xe5\x25\x88\x99\x02\xe5\x98\x5c\xcb\x30\x75\xae\xf2\x56\x57\x79\xb9\x1c\xcb\x3d\x7e\xc5\x0f\x67\xca\xa6\x11\xf3\x6f\x64\xfb\xc9\xed\xb3\x69\x8a\x95\xcc\xf2\x74\xb8\xaa\x70\x15\x70\x07\x74\x24\x24\xf7\x99\x87\x06\xd4\x9b\xec\x8f\x48\x07\x97\x09\x52\x10\xff\xfa\xb1\xdc\x55\x97\xdd\xe5\x27\x17\xae\x23\x4b\x51\x39\x20\x18\x4b\x3c\xae\x36\xcb\xd5\xfd\x6e\xf1\x6d\xb5\xe7\xe1\xcb\xe3\x44\x60\xc8\x31\x6a\x43\xcf\x24\x94\x98\x8e\x33\xd7\x70\xbb\xad\x9e\xb1\x27\x5c\x54\xcd\x27\x04\x7c\xa6\x63\xe3\x7c\x92\x8f\xb2\x6e\x9d\xae\x8f\x0f\xc2\x2f\xde\x0e\x4d\x62\x8b\x0b\xdd\x76\xb7\xd8\x39\x78\xe3\xf7\xc5\xf6\x7b\x38\x39\x92\x70\x69\xbc\xbc\x5c\xff\xde\xdc\x04\x4d\x61\xa6\x29\x8d\x83\x88\xc0\xae\x87\x2c\x35\xdb\x21\x85\xd0\x94\x1a\xac\x69\xb9\xcb\xd3\xed\xae\xba\x3a\xe5\x45\x77\x77\x3f\xe9\xe7\x68\x6a\x9d\xbb\xb0\x27\x20\xe1\xb4\xfd\x2e\x9b\x97\xa7\xa1\x77\xaf\x59\xac\x4c\x00\x3e\x63\x93\x02\xcc\x3f\xdb\x8f\xf1\xef\x32\x91\xa0\x51\xaf\x92\xe5\xe2\x64\xf2\xb3\x76\xac\x66\x09\x07\x1d\x3c\xaf\x82\x45\xe2\x6c\x73\xd4\x0c\x28\x26\x00\x7b\x84\xa2\x15\xa7\x03\x7c\x81\xef\xd7\x22\x8e\x85\x1d\xe4\x4a\x5c\xf6\x38\x0f\xd9\xb4\x20\xce\xb7\x64\xfb\xb8\xd8\x2c\x27\xaa\x4b\x4c\x0b\xe6\xae\xdd\x97\xe7\x5a\xbd\x19\x2c\xc2\x26\xd9\xa3\x16\x59\x82\x81\x1f\x5a\xa2\xac\xcb\xc7\x2e\x23\xa2\xe1\x6b\x92\x48\xab\x38\x1c\x5c\x95\x26\xd8\xe9\x31\x9d\x24\x99\xc8\x46\x82\x3b\x67\x45\x32\x7c\x21\x27\xaa\xcd\xb3\x46\xb5\x4e\x13\x57\xfe\xec\x82\xf7\x5a\xbe\x2f\x8a\x62\xd5\xbe\x3c\xcc\x34\x1f\x59\x97\x7d\x62\xf1\xe1\x06\xe6\x79\xa0\x4e\xb5\xc1\x57\x70\x51\x03\x28\x39\x0a\x92\x75\x16\x69\x64\xac\xaf\x8a\xbc\x85\xc9\x01\x25\x58\x12\x7c\x8c\x46\x46\x76\xf3\xcd\x6a\xf2\x3c\x64\x66\x71\xee\xbd\xe4\xcf\x2f\xd0\xb4\x53\x9e\x8f\x96\x1a\xb0\x23\x19\xe0\x25\x3f\xc3\x01\x15\x65\xf8\x5b\x7d\x99\xed\x52\x7a\xad\x75\x94\x62\xbf\x62\xbf\xdf\x8f\x3a\x0f\x5a\x2b\x8d\xd8\xd4\xde\x5a\x42\xb6\x2d\xd4\xe5\x59\xd5\x6f\x12\xc2\x5e\x5c\xcc\xb4\x51\x80\xc5\xa0\x2d\xb4\xd7\xf2\x78\xcc\x07\x3b\xa5\xbf\x61\x4f\xc2\xb4\x31\xd2\xc6\x7d\xc1\x09\x6b\x49\xa5\xf1\x9e\x94\x93\x34\x58\x83\x4e\x13\xd7\xbb\x47\xde\x26\x9d\xfa\xe6\x31\x6d\x33\x15\xa3\xb6\xc2\xb7\x09\x9f\x5f\x5b\x45\x8d\x2f\x4c\xae\x5b\x38\xec\xe0\x70\xfc\x5e\x15\xe6\x8c\x7e\x6b\xa2\xc8\x69\xc5\xf5\x4c\x87\x07\xfb\x70\x84\x72\xdb\xc2\x31\x9c\x84\x89\xa2\x14\x6c\x58\xba\x2f\xf6\x17\xc2\x40\x62\x31\x69\x5f\x9c\xda\x97\xaa\xdb\x49\x3f\xd3\xfd\x1e\xfd\x3e\x75\xf2\x6b\x48\xf3\xf1\x02\x2a\x57\xa7\x8f\xea\xd4\x4e\x2b\xec\xd3\x4f\xc5\x91\xc6\xa8\x1f\x05\xd0\x50\xf8\xdd\x4f\xa0\xd3\x99\xa9\x28\x33\x31\x49\x3c\x86\xdd\x97\x29\xb6\x00\xe6\x82\xb1\x63\x18\x4e\x29\x66\xdc\xcd\x11\x65\x36\x96\x0e\xaa\x36\x1b\xa3\x12\xec\xd6\xb4\x75\xfe\xfc\x0c\xf5\x8d\xcc\x8b\x9b\x42\x3e\xf7\x77\x8c\x08\xad\x78\x00\xad\x75\xb3\x0c\xbb\xdf\xeb\xa9\x05\x37\x33\x44\x11\x7c\x7a\xa7\x52\xe2\x1d\xcb\xff\x9a\x19\x9d\x75\x43\x8c\xf5\x41\xf7\xf6\x35\x2f\x8a\xf9\x37\x68\x19\x08\x1f\x57\x1f\x8b\x22\x97\xcd\x7c\x80\x49\x64\xf0\x31\xea\x52\x92\xaa\x9e\xfd\x00\x35\x34\x75\xed\x57\x97\x57\x7e\x87\xa2\xa8\x86\x76\x72\xfa\x0f\x07\xe9\x73\xff\x7b\x61\x32\x1b\x6a\x00\x85\x67\xbb\x69\xfc\x07\xba\x4a\x3e\x4f\xdf\x47\xc3\x98\xc5\x93\x74\x39\x91\x2b\x59\xcf\x6e\x28\xe3\xd4\xf9\x9c\xaf\xef\xf7\xeb\xfb\x3f\x56\xdb\x1d\x6e\x78\x8f\xdf\x17\xdb\x9e\xd7\x67\x18\x4f\x31\xbc\x42\x4e\xff\x15\xb4\x9f\x45\x1e\x7e\x38\x67\x1c\x91\x83\xab\xf5\xf2\x9f\x23\xe3\x52\x66\x38\xa7\x08\x7c\x0f\x0b\x81\x87\xcc\xff\x02\x83\x10\x56\x59\x23\xa8\x44\x1d\xba\x02\x6c\x4b\x67\xd7\x21\x18\xc7\xb9\x56\x43\x53\x15\x6f\x80\x98\x9d\xd9\xdd\x48\x22\xe2\x7c\xf7\x9f\x01\xb7\x22\x59\xb7\x6b\x1f\x60\x87\x13\x4c\x04\xc1\x5c\x14\x25\xcd\xe6\x1f\x4f\xe8\xb0\xaf\xbf\x42\x39\xda\x59\x4d\xc6\x2d\xca\x51\xdc\x2d\xfe\xdc\x8f\x55\x5b\xfa\xe3\xc2\xe2\xb2\x75\xb5\x5b\x26\x24\x8a\xaa\x92\x0d\x37\x25\xd3\x99\xf6\xb5\xf9\x07\xe5\xdc\x57\x66\xbf\x9c\x69\xf7\xed\xcb\x00\x83\xfa\xf9\xd1\x25\x31\x4b\xcf\x19\x85\x1a\x17\x31\xa4\xce\x9d\xc9\xf9\x7c\x16\x83\x1b\x19\x25\x88\xd4\x0f\x71\x98\x6b\x0b\x7b\x63\xb0\xd1\xa9\x4b\xab\x82\x62\xdf\x48\x06\xc8\x1f\x54\xcc\xa0\xda\xa3\x8b\x01\xb7\xad\x7c\x45\x52\xe5\x74\xff\x0c\x63\x65\x9a\xa0\x11\xd8\x5e\x9e\xda\xea\x30\x57\x8a\x62\x46\x69\xe7\xfd\x82\xe8\xd6\x73\x14\xb0\x51\x90\x30\xe8\x75\x57\x3c\x25\xe6\xcb\x60\xd3\xe8\x44\x07\xc0\xda\x15\xfa\xc8\xa3\x67\xd2\x3e\x5c\x9b\x4e\x99\xc6\x7c\xef\x69\xf7\x7d\xbf\xbe\x5f\xef\x96\x0f\xf7\xdf\x36\xab\x6d\x48\xc4\x8c\xd1\x29\x16\x02\x1c\x63\xd3\x73\xe1\x87\xa4\xcf\x00\x4d\x11\x2f\xb9\x1f\x90\xc7\x8b\xb2\x6a\x5f\x1c\x5a\xec\xf2\x92\xdd\xbf\x26\x56\xa4\xd8\x51\x2c\xaa\xe7\xbc\xfc\x03\x3b\x53\xb3\x35\xc4\x1a\x9a\x4a\x5f\x83\xdc\xe7\x25\x2e\xd5\x58\xa4\x8a\x57\xff\xc5\x7f\x43\x7a\x02\x51\x6a\xd1\xef\x7d\xb0\xee\xbd\x20\x06\x9f\x86\xc1\x19\x8f\xe3\xb1\x01\xe2\xae\x7a\x2c\x64\x6b\xab\x7a\x56\xbd\x81\xc8\xd0\xc4\x29\xf9\xc9\xe7\x3e\x94\x82\x08\x28\x71\x88\x8a\x5a\xbf\x6c\x4e\xe5\x90\x08\x41\x64\x53\xc6\x7a\x65\x7c\xf0\xe8\xa3\x66\x0e\x08\x81\x38\x4a\x30\x60\xea\x82\xc8\x11\xc4\x19\x62\x5f\x1e\xe8\xe6\xda\x41\xb6\xd0\xbc\x57\x75\x31\x03\x09\x03\xe1\xda\x49\x2e\xe1\x2e\xbe\x3c\x35\x6d\x75\x98\xbf\x34\x40\x84\x4b\x90\x91\xa9\x8a\xf9\x65\x5f\x0c\xcc\xcb\x67\x47\xcd\x0a\x05\xb8\xe1\x89\x02\x4b\x40\x0c\x04\xb3\x3d\x42\xad\xc3\xc9\x31\x99\x62\xce\xd3\x1c\x8b\x7c\xee\x84\xcf\x80\xe9\x14\xeb\x6a\xeb\xc7\x9b\xed\xb6\x1d\x88\x5f\xc0\x23\x08\xcd\xed\x6d\xfe\x5c\xce\xaa\xfa\x2c\x1a\xff\x33\xe2\x3f\x7d\x15\x07\x01\x57\x09\x0c\x3a\xf9\xfd\xfe\x1b\x8e\x42\xea\xe0\x85\xa0\x4f\xc5\x43\x61\x16\xe3\x8d\x07\xd2\x28\xc1\x16\x85\x17\x89\x18\xcc\x18\x19\xa4\x89\x40\xfc\xc0\x09\x51\x26\x57\x1f\x67\x15\x6d\xc8\xa8\xc3\x36\xed\x1d\xb5\x26\xbc\x12\x9f\x64\xa2\xe3\x3a\xc9\xa8\x58\x02\x8a\x09\xcc\x97\x9f\xca\x66\xd6\xaa\x1a\x82\x6a\x50\x32\x72\x49\x41\x2b\xc7\x55\x63\x50\x86\x62\x41\xf4\xe8\x9b\x1e\x0b\x34\xe1\xaf\x2e\xa8\xbc\x5e\xca\xbc\x41\x13\x4a\xbd\x45\x6d\xb1\x94\x05\xaa\xc6\x39\x3a\x6b\x7f\x96\xff\x66\xe1\x1c\x34\x4d\x70\xe7\xab\xa1\xc9\x7b\xdc\xe9\x65\x1f\xd8\x6e\xb0\xc4\x00\xe6\xe8\xa4\xdc\x67\x65\x0d\x30\x99\xf2\xcc\xf2\xe3\x05\x5d\x43\x3f\x08\x8c\xc4\x4d\xea\x25\xaf\xa1\xf6\x02\xba\x37\xa7\x32\xe8\xed\xfc\xc2\x36\x62\x38\x17\x9b\xa5\x09\x0c\xd6\xa9\x13\xd3\x4d\x06\x56\x1a\xec\x75\xfd\x55\x8d\x71\x1a\x60\xa5\x45\x78\xfb\xf1\xa4\x8a\xbc\x79\xe9\x82\xd7\x62\xf4\x72\x5a\x2b\x11\x87\x1a\xc0\xc6\x67\xf8\x07\x1b\x45\x69\xa4\x27\x36\xf2\x8f\x35\x1c\xf2\xd3\xa1\x79\x94\x33\x9b\x23\x66\x23\xc5\x90\x2e\xb9\xab\xf3\xe3\xa9\x41\xf7\xd8\x71\x28\x6d\x63\x6a\x99\x1c\x78\x8d\xc8\x35\x99\xfe\x5c\x9c\x52\xed\x53\xde\x09\xb1\xc2\xc6\x69\xaa\x06\xe0\xf0\xba\x69\x4e\xf0\x45\x3f\xf2\x8b\x69\x33\xed\x4f\x5a\x92\x69\xd4\xaf\x3c\x80\x91\xc5\xda\x22\x54\x7a\xb6\x4d\x59\x02\x22\x54\x76\x6e\x6f\xff\xd8\x83\xc9\xdb\x7d\x1c\xff\x36\xfd\x1e\x30\x1c\xcb\xbf\x6e\x09\xbb\xcf\xcb\xff\x93\x93\xd9\x1b\x5a\x5a\x96\x12\x27\x4a\x71\xb7\xbe\x5f\xdf\x3d\xdd\x0d\x21\x5a\xb7\x69\x87\xcb\xa5\x69\x82\x45\xf6\x6f\x1e\x51\x18\xfe\x6c\xd3\xd8\xf4\x1b\xe6\xc2\x47\xba\x17\x2a\xe2\x96\x25\x31\x06\x03\xc7\x40\xfa\xf5\x7f\xe7\xd2\xf9\xfe\xdc\x2e\x76\x0f\x13\x11\x34\xcb\xad\x45\x20\x91\x82\xf6\x6e\x64\x01\x38\xde\x67\xac\x88\x64\x88\x98\x7e\x3f\x99\xaa\xb9\x05\x3b\x0b\x0a\xac\x88\x63\x8a\x09\xe7\x4f\xd0\xa7\x40\x1e\x99\x3e\x64\xc1\x32\xe3\x4b\xec\x7d\x45\x62\xf6\x25\x4a\x86\x42\xb1\x87\x87\x23\x79\x17\x7d\x74\x27\x0b\xa3\x15\x90\x22\x83\x26\x2f\xc3\x6e\x8e\xd1\xd4\x6f\x17\x97\xda\x3e\xcb\x0f\xab\x81\x4d\xb8\x42\x8c\xf2\x23\xd4\xaf\x93\xa9\x9a\x08\x47\x38\xb9\x5f\x3c\x86\x3f\xa5\x90\x71\xd6\x57\x58\x07\xd3\x8d\x70\x3c\x23\x34\xf4\x32\xb0\x4c\xf4\x58\x83\xc9\x27\x62\x23\xd3\x37\xda\x66\x89\xc0\xd8\xd4\xcb\xee\x84\x6d\x7e\x3a\x48\xd2\x98\xc6\x81\x3a\x3a\xd4\x65\xfa\xe9\x24\xb9\xd2\x9e\x0e\x70\x0f\xef\x9e\x64\xdd\xbf\x36\x52\x59\xe5\x1f\xd8\x75\xa5\xcf\xc4\x3c\x99\x55\x9c\xe1\x53\x87\x53\x5d\x0d\xae\x38\xb3\x31\xa9\xd0\xd1\x08\x28\xbb\x2f\xc6\xc2\x42\xd6\xc4\x1a\x1f\xd6\x76\xb1\xbe\x5c\x2e\x9c\x3e\x5b\xa3\x1c\x66\xfc\x7b\x55\x7c\x5c\xe5\xca\xe7\x2f\xf1\xd4\x25\x67\xf6\xce\x18\xa5\xd4\x90\xf6\x6c\xc0\x00\x1c\x7c\x65\xf6\x7b\x10\x62\xe9\xc3\x31\x76\x79\x87\xb5\x40\x19\x96\x4d\xb7\xf9\xe1\x18\x1c\xc1\xbe\x58\x20\xe6\x5b\x9c\x05\x01\xe8\xbb\xf2\xba\xcb\x5f\x77\xf2\x75\xb4\x81\x59\x1b\x3b\x59\xda\x7d\xe3\xa5\xb5\x0e\xa7\x76\xe0\x17\x4c\xaf\xdf\x32\x45\xfc\x12\xb7\xc5\xdc\xe0\x0c\x72\x64\xad\x4a\xe3\xcc\xdb\x0f\xb8\x07\x3a\xef\x51\x86\x81\xe0\x70\xb2\x8f\x55\x91\xeb\x8f\x8b\xee\x48\x3c\x8a\xb8\x44\x15\xa6\xdb\xf5\xe2\xfe\xdb\x68\x92\x77\x47\x14\x72\x87\xbf\x05\x56\xe7\xfa\x7a\x12\xaf\xf2\x28\x92\x2e\x29\xbe\x43\x0e\x67\xc8\x4e\x7e\x85\x3d\xf7\x1f\x8e\xbd\xd3\x5c\xd8\x5d\xbc\x9d\xc5\xec\xf4\x48\x66\x71\xc1\x78\x74\xe5\xe8\x51\x15\x9e\x47\x44\xa9\xd4\x59\xbd\x95\xd5\xa9\xd4\xe0\xc0\xbb\xfd\x51\x93\x78\xb9\x2b\xa7\x28\xb8\xc5\x98\xfe\x33\x1b\x69\x1e\xd1\x38\xf6\xe0\xcf\xd6\x93\x41\x17\xe7\xaf\x67\x1a\x06\x13\x85\xe5\xbb\xfa\xb3\x76\x16\x8f\xa8\x66\xca\x19\x09\xcb\xba\xdd\x54\xa7\x02\xda\x16\x26\x37\x98\x45\x19\xf6\x8e\x0f\xf5\xeb\x5e\x4f\x4a\x87\x3c\x62\xc2\x49\x7e\x8e\x8c\x39\xec\xa9\x34\x60\x56\xed\x0b\xc2\x46\xf2\x46\x9f\x31\xdf\x79\xc4\x2c\xc1\x5b\xb2\xfb\x7e\xb5\x9c\xfc\x16\x8f\x5c\xc9\xbf\x3a\xb6\xf9\x41\x16\xab\x9f\xc7\xd9\x27\x79\xc6\x10\x56\xd5\xc2\xcf\xf6\xa6\xaa\x67\x4f\x9a\x2b\x22\x07\xce\xdf\xa3\x2c\x4d\xbf\x54\xfc\x9b\x5c\x4e\x39\x79\x24\x44\x8a\x75\x40\x8f\x27\xcc\xcb\x89\xa1\xfb\x7c\xac\x33\x54\xc7\xe5\xf1\x98\xeb\x70\xde\x22\x4d\xd3\xa1\xd3\x73\x96\x61\x5d\x7e\x94\x22\x8b\xa9\x8b\xe2\x10\xa2\x7d\x9b\xff\xf7\x94\x9b\x73\x16\x34\x8f\x84\x74\x38\xd4\x3b\x59\xd7\xb9\x7c\x86\xd9\xe4\x13\xd2\xc1\x39\x50\x98\x31\x1f\xf2\x92\xf3\x9d\x23\xac\x03\x3c\x4a\x14\x47\x5a\xf6\xd6\x99\x53\xf7\xb5\xd3\x2f\xe1\x27\x3c\x4a\x0c\xcd\x7c\xf0\x33\x3b\xc7\x54\xc4\xcc\xab\x87\x6d\x07\xbb\x5c\x1e\x65\x1e\x07\x17\x34\x2e\x7a\x95\xb2\x7e\x80\x92\x21\x38\xfb\x1f\xa9\x5f\x8f\xd5\xb4\xfa\xcb\x23\xc5\x9d\x8e\xa4\xf6\xd3\x7d\xf3\xe7\x08\x0b\x35\x0c\xe2\x91\xe3\x16\x9e\xea\xf6\x65\xff\x7e\x99\x78\xc6\x23\x9d\x32\xec\xe1\x1c\x5d\x35\xff\x51\xd6\xfd\x5c\xd6\x2a\x45\x01\x39\x8c\x8d\x30\x00\x7d\xb0\x5f\x0a\x78\xf0\xc8\xc8\x48\x8f\x4b\x89\x3d\xdb\x1e\x0f\x61\x2a\xf4\x22\x9b\xbb\xbc\xdc\xc8\x71\x1d\x6c\x32\x1f\xd2\xfe\x03\x26\xce\xc6\xd2\x90\xb3\xa7\x6c\xac\x45\x7d\xd7\xd0\x1b\x35\xe0\xd8\xb3\xe1\x07\xc1\xa6\xa1\x60\xe3\x63\xaa\xf6\xe3\x13\xb3\x1e\xff\x09\xcb\x62\x54\x17\x79\x3e\x29\x05\x75\x17\x05\x3c\xbc\x41\xdd\xbe\xd4\xbd\xaf\x32\x8f\x6c\x96\xc6\xce\x8d\xf8\xff\x40\x07\xdd\xb0\x73\xf3\x48\x37\x3a\x8e\xe2\x38\x8d\x87\xd0\xce\x1c\xf2\x8b\x06\x86\x3c\x8e\x69\x94\xc9\x89\x6e\xe4\xb2\x2a\xba\xf5\xa3\xf6\xd2\x41\x17\x04\x33\x78\x1c\x0b\xb7\x87\x63\x1a\xef\xb7\xce\x30\x8f\x62\x42\x18\xed\xe5\x0a\xce\xbc\x61\xff\x1f\x09\x45\xe1\x3b\x13\x81\xcb\xba\xc3\x92\xc2\x43\x2d\xf5\xcc\x31\x9f\xc7\x34\xa2\xd8\x3d\xe9\xa7\xdc\x80\xf6\x0d\x23\x44\x22\x4d\x20\x74\x94\xdd\xaa\xe6\x97\x89\xe9\x8f\xd1\x94\x28\x3b\xa2\x5e\x7e\x97\xcd\xaa\x5b\x4a\xfb\xaf\xc9\x92\x34\x1a\x71\xd3\x31\x3e\x0b\x07\x59\x1a\x2b\x6f\xb8\xe4\x35\xc2\xcf\x19\x39\xa3\x5d\x97\xc7\x3c\x12\xa8\xbc\x34\x92\xfc\xd9\xc8\x16\x56\x2c\x7c\x23\x97\x1c\x69\x9e\x57\x4f\xdb\xf5\xfd\x6a\xbb\xdd\x7b\x83\x15\x2c\xc4\x3a\x00\xdc\xfe\x76\x7d\xb7\xde\x0d\x1f\xb0\xc8\x4f\x59\xa0\xbe\xe7\xb2\xcb\x20\xbc\x4d\xe3\xe5\xad\x2c\x16\xd4\x52\x74\xf5\xb5\xde\x57\x68\xbc\x70\xc4\x42\x3a\xe9\x87\x67\x68\x17\x45\x31\xf3\x3f\xe0\x71\x12\x27\xd8\xb0\x0d\xe7\xef\xe5\x22\xbb\x80\xe6\xea\xe3\xee\x13\xf3\x1a\x1e\xa7\x3c\xc5\x89\xa7\xab\xa6\x8d\x47\x40\x23\x1e\x67\x99\x22\xbd\xe4\xe5\x8f\xc1\xed\xf1\x8b\x82\x07\x8f\x33\xa0\xd8\x5a\x92\xa1\x66\x33\xfd\x35\x15\xc5\xda\xfb\xae\xf6\x08\xe0\x6b\x35\x9b\x40\x8a\x10\xab\x66\x10\x8d\xbf\x45\x84\xfb\xec\xa4\x14\x11\x88\xe2\x71\xb3\x6c\x10\xd4\xe2\xb1\xf2\xfa\x57\x6e\xab\x5b\x95\xd8\xf2\x0c\x1c\x9e\xd9\xb9\x6b\xeb\x18\x50\x5d\x88\xa7\xab\x63\xff\x1d\x26\xa2\x14\xf1\xc4\x68\xc4\xb9\x6f\xab\xd7\x72\xbf\x5e\x3e\xc4\xfd\x71\xa1\x33\x1d\x12\xa3\x37\x87\xc6\x99\x00\xac\x79\x6c\x52\xc7\xe2\x6a\xc0\xf5\x8c\x1f\xa1\xfe\x5e\x9d\xea\xd9\x09\x40\xec\x10\xd6\xed\x40\x41\xbe\xa9\xea\x6e\xff\x68\x86\x75\x36\x06\xc9\x6d\x3c\x56\xf8\x0d\x82\xfc\x4d\xf8\xd1\xe9\xb7\x5a\x26\x05\xb8\xda\x28\xf6\x6a\xee\x6f\x76\x5f\x6a\xb6\xba\x8f\x91\x48\x50\xcc\xb1\x4a\x6c\x8a\xdd\x56\xc1\x3e\x9b\x93\x48\x46\xd8\x4a\xbe\x5e\xdd\x2c\x9e\x6e\x77\xfb\xe5\x66\xe5\xc4\x20\xc6\x2f\x07\x89\xb4\xc6\x32\x33\x32\x5e\x77\xdd\x62\xf2\xb3\x3f\x64\x1d\x7c\xf4\x5e\xfe\xac\xba\x20\x6c\x1c\x10\x91\x38\x8a\x22\xbf\xb7\x3f\x94\xc5\xc7\xf6\xa5\x7a\x0f\x6b\x9b\x19\x0a\x84\xdd\x38\x08\xe2\xcc\xae\xa1\x82\x9a\x18\xf0\x77\xdc\xda\x38\x89\x13\x40\xae\x5c\x09\xef\x4e\xaa\xfe\xb7\x49\xcd\x8b\x13\xa2\x25\x82\xed\xfc\x9a\xbb\xdf\x55\xfb\xd0\xa3\x08\x2f\x24\x61\xca\x20\xb1\x7d\x1f\x34\xbe\x5f\xa1\xec\x8b\xa0\x17\x97\x57\xc2\x75\x34\x03\xc6\x4e\xe3\x39\xc2\x2d\x45\xce\x74\xbf\x40\x38\xfd\x4d\xec\x38\x9c\x85\x49\x44\x44\x12\x65\x47\x1e\x57\x8f\xe1\xa4\x04\x8d\xd3\x80\x67\x59\x1e\x64\xed\x17\x5d\xbf\xe7\x92\x24\xd2\xc6\x4f\x9e\x07\x6f\xd2\x34\x4f\x64\x38\x49\x38\x70\x5f\xb3\x72\xbd\xa1\x41\x28\x97\x93\x54\x44\x58\x3d\x7b\xba\x5a\xed\x96\x0f\xeb\xfb\xfd\xed\xea\xfa\xdb\x6a\xb3\xdf\x3d\x84\xff\xb7\xba\xdf\x6d\xfe\x77\x7f\xfd\xb0\x7c\x72\x2b\xe7\xf7\x05\x8f\xc9\xf0\xf1\x14\x8b\x89\x55\x79\x27\xbb\xed\xa1\x1c\x05\x3e\x24\x4d\x5c\xfa\xfe\x56\xb5\x60\x7c\x51\x27\x1c\x4a\x89\xf5\x2a\x1a\x6d\xb5\x92\x75\xf1\x31\x3c\x8f\xbf\x53\x89\xe3\x24\x95\x24\x49\xfb\xe5\x35\x7c\x3a\x28\xad\xf5\x4f\x35\x35\x31\x9a\x4b\xb9\x86\x24\x16\x8a\xa7\x05\x33\x4e\x52\xeb\x9a\x9b\xe5\xe9\xd0\x4b\x5f\x84\x4d\x8b\xc8\x94\x61\x69\x63\x53\xe9\x57\x68\x11\x4d\x18\x8e\x64\x14\xe3\x99\xef\xf0\x53\x96\x13\x2c\xe3\x67\x85\x2e\x4e\xa4\x71\x86\xa9\xd6\xa9\x7d\x6f\xab\x83\xaf\x42\x4e\xaf\x4d\x11\x81\x68\x29\x3c\xe6\xab\x95\x66\x36\x46\x47\x4e\x64\x2f\x2f\xf3\x76\x00\xd2\x73\x62\x84\x43\x10\xf5\xb2\x0e\xab\xb2\x3f\x66\x89\x15\xbe\x78\xef\xb9\x97\xeb\xe6\xa6\xae\xfe\x82\xf2\xea\xe3\x7a\x0c\xcc\x9b\xfc\x14\x8d\x44\x82\x78\xba\xa2\x7a\xc6\x37\x1f\xdf\xff\x6e\x99\xfa\xe9\xcb\x6f\xe1\x3d\xa3\x51\x92\xea\x31\xb7\xf8\x3a\x7f\x6b\xfa\x9e\xda\xbc\x77\xc5\x69\x1c\x3b\x03\x53\x83\xf9\xe6\xaa\xd6\x24\x72\x1d\xc6\xc9\x5b\x44\x63\xcd\x31\xcf\x08\xfa\xc1\xdf\xae\x1e\x3f\x39\xd3\xd8\x44\xb8\x4a\x79\xee\xed\xac\x90\xca\x29\x89\x28\x3e\x6a\x53\x5d\xd6\xf8\xe0\x94\x68\x36\x70\x96\x6b\x0d\xc5\x9c\x7c\xce\x29\x8d\x12\xe3\x7a\xa2\x6f\x20\x8b\xad\xce\x9b\xa6\x9b\xb6\xe3\x07\x4d\x29\x33\xca\x3d\x05\x14\xde\x9b\xfd\x08\x63\x91\xc5\xf5\x6a\x09\x79\x81\xf8\xa4\x70\x00\x04\xb6\x60\x9c\x47\x57\x35\x43\x67\x71\xca\x35\xf4\xed\xf1\xaa\x2a\xa6\xbf\x29\x22\x19\x39\xf0\x61\xe1\x33\xeb\x65\xfd\xd1\xb4\xb2\x98\x05\xaf\x54\x30\x07\xab\xc9\x9b\x09\x26\x88\x53\x21\x9c\x62\x16\xce\x9d\x80\xaf\x08\xc7\x74\x84\x5e\x4e\xa6\x5a\xa2\x73\x36\x94\xe6\x0a\x59\xa0\xfd\x00\x88\xd0\xd9\xc3\x11\xbd\xae\xf3\x1a\xe3\xed\x8f\x89\x23\xee\xac\x9c\xc3\x69\x92\x64\xc2\x4e\x64\x67\xd0\x88\xce\x95\xd8\xa6\x67\x9d\x24\x4e\x7c\xac\x45\xa3\x40\xf8\xaf\x33\xbb\x7c\xca\xcb\xf6\xb7\xc9\x3d\x4a\x20\x75\x6b\x62\xfe\x7c\x59\x9d\x9a\xd3\x34\xa5\x58\x22\x77\x01\x06\x4e\xbe\x05\xaa\xb2\x85\x6b\xc9\x34\x43\xd4\x69\x37\x8f\x5f\xa0\x08\x32\x97\x17\x77\x1f\x9a\x81\xc1\x9e\x80\x77\x6e\x2d\xf2\xe3\xdc\x0d\x84\x53\x19\x51\xed\x19\x8a\x77\x79\x51\xf4\xe1\x7d\x38\x9c\x58\x2c\x8a\x74\xd7\x76\x57\xbd\xc1\x34\x83\xa4\x52\x32\x34\x99\xfe\x06\x23\x14\x89\xdf\x03\xa8\x62\x04\xab\x8b\xea\xf4\xb1\x2c\x4e\x4d\xeb\x75\x9a\xc2\x67\x55\x02\xb8\xad\xf5\x1e\xc3\x20\x0f\x63\x4c\x0e\xa7\x2a\x75\x90\xbf\xb6\xdb\x5e\xda\x49\xe8\x4f\x95\x34\x18\x2c\x21\xc3\xcf\xdb\x8c\x8e\xa8\xd8\xd3\x8b\x04\xca\xd0\xf9\xe0\x5a\x56\x9b\x53\x01\x4d\x28\x09\x39\xdc\xe6\xdf\xcc\x5c\xce\x41\xc0\x9c\x02\x4b\x98\xcf\xb6\x7e\xaf\x06\xf1\xb8\x4b\xfc\x71\xce\x22\x2e\xbc\x9e\x7b\xbb\x01\x03\x07\x9c\x50\x17\x94\xda\x39\xeb\x32\xe6\xee\x7c\x57\xa5\x09\xd1\x1f\x8b\x33\xc6\xe5\x08\x3e\x82\xc2\xb6\xa1\x47\x34\x2a\x87\x72\x16\x2b\x1d\x08\xd5\x4f\xdb\xeb\x4b\xf9\x1e\x23\x59\x84\x78\xd8\xe7\x13\x34\xcd\xa3\x6c\x9a\xf7\x91\x9a\xfa\x85\x0b\x65\x34\x89\xb0\x2f\x86\x9d\xf3\xc5\xf5\xf5\xc3\x8f\xfb\xd5\x26\x9c\x1a\x4d\x39\xba\xdc\x5c\x3f\xdc\xbb\x00\x6d\xb3\xd8\xad\xc2\x41\x16\xbb\xed\xe0\x5f\xab\xd5\x8f\xc5\xfd\x6e\x9c\x19\x30\x96\x49\x33\xc0\x09\x50\xbc\x14\xb7\xcb\xd9\xd9\x72\xed\x98\x9a\x87\xbc\xbc\xa9\x6a\xe4\x26\x62\x2c\x3a\x94\x89\x58\x12\x31\xd4\x4c\x7b\xd8\x7d\x5f\x6d\x96\x9b\xa7\xf5\xb6\x0b\x10\xfe\xdc\x6d\x16\x4b\x3c\xa3\xab\xc5\xb6\x3f\xa3\x84\x3b\x78\xda\x41\xbe\x82\x2b\xeb\x84\x03\xca\x95\x80\x1f\x6b\x38\xf6\xa1\xe0\x97\x9b\x3d\x4b\xa3\x34\xc9\x82\x06\xbf\x95\xa7\xa2\xbd\x83\x56\x1a\xd9\xca\xa7\xcd\x7a\xb2\x0a\xb2\x8c\x72\x0e\xde\xb4\x12\x63\xae\x0d\xe0\x66\x35\xbb\xd8\x4c\x64\xa8\xde\xf7\x5c\x99\x2d\xb4\x3d\x9d\xe4\xf2\x46\xc5\x32\x4d\x51\x15\xc5\x91\x2e\x3f\x55\xcc\xe0\x2c\xb3\xce\x99\xe4\x6e\x75\xbf\x5d\xcc\xbe\x44\x72\x1d\x0a\xca\x3d\x4d\x9a\x33\x99\x5a\xa7\xa6\xef\xa1\x0e\xdd\x76\xb9\x01\xfb\xf7\xa2\x20\x26\x15\xc3\x7d\xa6\x09\x2a\x81\x9c\x29\xa2\xb0\xdb\xb8\x85\xc2\x16\x05\xd4\x1f\xff\x5b\x9d\xc6\x2b\x02\xd3\x0a\x68\x80\xbf\x6d\x8f\xa0\x73\x59\x7c\x05\x6c\x9b\xfd\xa2\x21\xce\xb5\xd2\xa5\x60\x4f\x75\x31\xaf\xd6\xfd\x9b\xff\x27\x0c\x55\x0c\x3b\xca\x25\xbc\x07\xb5\x98\xcf\xb5\xeb\x38\x83\x54\x13\xcf\xc6\xf7\xe4\x86\x4f\xca\x8f\xb3\xcf\x59\xaa\x48\x34\x72\xd4\xb0\x50\x7f\x1f\xc9\xa9\xfd\xaa\x74\x12\xbe\xc5\x12\x2c\x72\x78\xd1\x7b\xbc\x63\x63\x7d\x60\xce\x23\x1d\x61\x07\x72\xa8\x1e\x39\xb2\xf5\xd7\x4a\x9b\x9c\xc7\xc6\xf9\xad\x16\xdd\x82\x32\xd4\xd5\x39\x89\x19\x6e\x54\xc8\xda\xd6\x55\x6d\x7e\xe4\x9f\x64\xfd\x9c\x10\xc0\xae\xd7\x0f\x90\xc7\xca\x55\xd7\x7a\x22\x24\xe7\x84\x3a\x79\x82\x12\xde\xef\x00\x39\xbe\x97\xee\x2f\xa7\xd4\x22\xc6\x20\x77\xee\x15\xeb\xf2\x4c\xa2\x89\x77\x11\x48\x14\x24\x3b\xdd\xea\xea\xb0\xfc\xf3\x61\x9c\x23\xb6\xf7\x36\x97\xe5\x95\xac\x86\x2e\x0c\xe7\x54\x70\xec\xac\x74\x31\x29\x94\xba\xa8\x4e\x66\xbc\x18\x71\x2a\x9d\xd2\xfb\x55\x0d\xe5\x73\xd3\xef\x46\xe1\x30\xa3\x22\xeb\x6e\xf2\xc3\xfd\x6a\x7f\xbd\x5a\xae\xef\x16\xb7\xfb\x7f\x3e\x2d\xee\x77\x4f\x77\xfb\xc5\xfd\xbf\x3c\x9e\x6a\xe4\xec\xc9\x39\x93\xc4\xc5\x3d\x0e\x2d\xf5\x2e\xbb\xfd\x77\xc4\x76\x0a\xc3\x74\x1a\x7c\x24\x96\xf5\x87\xa9\xb7\x6d\x55\x3b\x52\xc1\x80\xe2\xe0\x9c\xd9\x0c\x27\x93\xcd\x8b\x62\xf9\x22\xcb\x12\x66\x31\x18\x67\xd6\x75\x63\x0e\x41\x3a\xe3\x32\x46\x9b\x73\x2e\x9d\x36\xc2\x45\xa1\x9d\xcb\xcf\x99\xeb\x0c\x63\x1c\x2d\x8f\x0b\x94\x15\xed\x13\x11\x2e\x58\x4a\xdd\xb6\x36\x4f\x05\xb8\x90\xce\x47\xe3\xdb\x1f\xce\xfb\x7d\x5a\x08\xff\xe2\x95\xe3\x42\x45\x88\x59\x71\x85\xc1\xc7\xaa\xa8\xca\xbc\x4f\xec\x79\x92\x02\xb2\xb0\x4e\x0d\x5c\xaf\x6e\x57\xdf\x16\xbb\xd5\x72\x71\x7b\xdb\x1f\xce\x22\xec\x43\xef\x55\x6e\x0c\xbe\x73\x8b\x12\x8d\x39\xe1\x2a\x3f\x5f\xd0\xa7\x0f\x23\x95\xca\xd1\x7a\x3e\xf4\x4c\xca\x87\xf3\x14\xb2\x58\xcc\x7c\x97\x65\x31\xf8\x65\xf8\x61\x19\x71\xa2\x1f\x06\xd4\xe9\x79\xff\x22\x9b\x17\x7a\xf5\x11\x32\x70\x3f\x46\xc5\x9c\xf2\x50\x72\xbc\xa9\xea\x7b\x78\x77\x7e\x7a\xb3\x3b\xa8\x38\x60\xde\xb0\xdc\x4d\xda\x39\xdc\xc4\x4e\x00\xcc\x13\x04\x46\x89\x33\x37\x71\x82\x16\x7d\x3d\x74\xdb\xc7\x6c\xeb\xb2\x4b\xb1\xf3\xf2\xd9\x61\xf2\x6f\xaa\xba\x47\x43\x4e\x6f\x81\x61\x4e\xdb\x5c\x1a\x73\x1b\xaa\xd1\xd3\xb3\x32\xcc\xe0\x8d\xf8\x91\xff\x2c\x64\xbf\x6c\x18\x1e\xa9\xc4\xab\x5b\xba\x56\xdc\xaf\x54\xbd\x38\x07\xcb\x9c\xa0\x29\xd2\x39\x86\xf2\x38\xb7\x11\x43\x1d\x8b\xe6\xf9\xa8\x67\xbf\x6e\xad\x40\x35\xfc\x3f\xf2\xb7\xbc\x0a\x73\x42\x44\x89\x13\xcb\xac\xa1\xad\x73\x78\x43\x06\x49\x38\x94\x46\x58\xab\xd8\x4b\x55\xd5\xa1\xb9\x37\xb2\xa7\xe5\x22\x26\x80\xf5\x6f\xe4\x24\xce\x7b\xf7\x5c\xc4\x89\xd1\xae\x56\x7f\xac\x6a\x04\xa7\xfc\xf6\x4b\xec\x3a\x17\xb1\x8c\x50\xb3\xa2\x84\x9f\x83\x2e\x70\x77\xd7\x87\x12\x95\x88\x6d\x64\xbc\x8d\x96\xcf\x5d\x6f\xf3\xb7\xf0\x28\x05\x89\x35\x3e\xe5\xf6\x05\xae\x3e\x77\xf7\x08\x83\xa9\x70\x74\x5f\x2c\xd6\x4d\x57\x0f\x41\x58\x2a\x9d\xb3\x7a\x8b\x72\xc1\xe0\x15\xdf\x4f\x23\x13\xd2\x51\xec\x2e\x28\x57\x34\xf1\x92\x48\xf9\x1c\xc2\x76\xfe\xdb\xd4\x3b\xdd\xf7\x82\xb5\xb3\xc2\x81\x60\x1c\xe8\x48\xfa\xec\x3a\x10\x7d\x86\x7a\x63\xb7\x8c\xa0\x24\xe1\xe0\x3d\x6f\x63\x76\x6e\x3e\xdf\x0d\xb4\xb1\x6f\x91\x07\x87\x8c\xfe\x3a\x39\x01\xe6\x4c\xc6\xbb\x0d\xb0\x6f\xd7\x5c\xde\xbd\x04\x4e\xb3\xe0\xeb\x52\x98\xd9\x66\x22\xb8\x25\x08\x09\x5f\x14\xc5\xb2\x37\x80\xea\xfe\x0c\x48\xef\xcb\x1b\xcc\x06\xc7\x02\x09\x5c\x88\x34\x8d\xb0\xe6\x1c\x0b\x1f\x9d\x87\x03\x59\x86\x0c\x3c\x03\x6a\xf4\xca\xcd\x4e\x28\x89\x33\xee\x6b\x47\x37\x79\x81\x52\x85\xbb\xde\x2c\xa5\x3b\x0c\xc6\x99\x07\x3e\xbb\xd2\xea\x08\x8b\x10\x86\x48\xe7\x09\x53\xa2\x3a\x7a\xf8\x60\x46\x25\xc6\x10\xcb\xea\x80\xd5\xf4\x6e\x5f\xbc\xac\xef\xc5\x85\x24\x06\x5f\x2f\xe5\x53\xbd\x30\xb9\x2f\xd0\x9f\xbb\xc1\x20\x83\x42\x4a\x6e\x2e\x43\x0c\x84\xe4\x0e\xd6\x8a\x42\xe5\xce\xc6\x6a\x61\x5b\xa8\x7b\x78\x11\x17\x32\x75\x2a\x66\x48\x4a\x47\x85\xff\x33\x0e\x24\x17\x52\xf1\x9e\xbe\x2d\x6b\x68\xab\x90\x8d\x5e\x4c\x7f\x85\x4a\xfa\x7c\xeb\x8f\x5c\xc3\xb1\x86\x26\x37\x50\xb6\x70\x0d\x77\xd0\xc8\x33\xb7\x83\x09\x4c\xa4\x7f\x8b\xb5\x4e\xb1\xfe\xbb\xbe\x5f\x87\xee\x4c\x38\x69\x43\xe2\x84\x04\x4e\x5f\x2b\xf5\xeb\x59\x89\x53\x00\xb7\x0e\x5d\x51\x3d\x63\x81\x5a\x5a\x5b\xc0\x72\xda\xcb\xbe\x3c\x15\x20\xe3\x78\xd3\xcc\xa9\x7c\x86\xaa\x9c\xbf\x50\x96\xd1\xc0\xd4\x0c\xfe\xb1\xcd\xd5\x07\x72\x28\xea\x8f\x49\xe2\x21\xac\xc9\x10\x52\xe3\x1f\x68\xa0\x56\xce\x67\xbb\xb5\xd6\xf8\x8a\xae\x23\xbf\x74\x8f\x67\xf2\xa3\x49\x14\x2b\xf4\xe8\xac\xab\xa2\xa8\xde\x82\x5a\x6f\x5e\x99\xb5\x5d\x15\xf2\xd8\x93\xd3\x78\x12\xd1\xc4\x51\xae\xab\xd2\xcc\xd1\xc0\x3c\x89\x32\x16\x94\x09\xda\x0d\x1c\x4f\xad\xdb\x64\x66\xcf\xe1\xe2\x53\x4d\x08\x09\x10\xe5\xaa\x86\x3f\xdd\x02\x76\x01\xd3\x17\xfe\x9d\x9c\x3f\x21\x80\x6e\x23\x47\xf9\xf1\x58\x55\xe1\xb5\x4a\x08\x37\x78\xab\xe1\x90\xb7\x9b\xaa\x98\xd1\x39\x47\xcb\x62\x42\xd2\x44\x43\xbf\xc6\x86\x62\x73\xc2\x2c\x83\x01\x44\x7c\x27\x5b\xfd\x72\x39\xa1\x98\x6c\x7e\x09\x17\x34\xd0\xef\x02\x3d\x0c\x95\xe0\x87\xd7\x39\x11\xb1\xc6\x2a\xf8\xf6\x6a\xb9\x0d\xbf\x26\x54\x8c\xd5\x81\x50\x60\x1d\xe3\xb6\xbe\xe4\x86\x76\x1f\x75\xf4\xf5\xc6\x7b\x52\xdc\x4e\x14\x0e\xc2\x20\xe0\x8a\x8e\x2a\x0d\x67\xfc\xb8\x73\xd4\x43\x92\x64\x0c\x23\xbd\xdb\xea\xf9\xf7\x11\x79\xe6\xcc\x4f\xf6\xd2\x9c\x0f\x18\xe8\xf0\xaf\xe7\x13\xf1\x24\x55\x1a\xfc\xfb\xb5\xac\xc1\xe4\xad\xcb\x0f\xce\x65\x4d\xbb\x88\xcf\xd5\xd6\x0c\xfc\xf7\x04\x41\xb3\x82\x27\x19\x61\x4e\x34\xb4\x96\x9f\x7b\xc2\xff\x8d\x42\x4f\x22\x49\x82\xaf\xfa\x68\x73\xca\xc2\x8f\x48\xe1\x24\x91\x91\x69\xb8\xd5\x2f\xd0\xc7\x62\x89\x94\x14\x4f\xeb\xb9\x2a\x4c\x70\x56\x9e\xee\xcc\x89\x94\x3c\x75\xb2\x4b\x6f\xc3\xc7\x74\x86\xcb\xf5\x77\x79\x3c\x7e\x5c\xc1\x04\x35\x94\x28\x92\x46\xc9\x58\x6c\xbf\xfb\xdf\xf1\x6a\x79\x79\x8f\x4e\x14\x01\x0f\x6d\x76\x34\xf3\x39\x5e\x24\x51\xdc\xb5\x4b\x6d\x6e\xe4\x23\xd4\xb8\x5e\xf5\xc7\x92\x34\x0e\x4a\xc0\x17\x6a\xa0\x89\x4a\x0d\xb6\x6b\x11\x49\xac\x1b\x59\x4c\xe8\x75\x3c\x51\x2a\x46\x8b\x04\x95\x4f\xa9\x59\x3c\xd1\x91\xb5\xa4\xd7\x5d\x71\x9f\x7a\x28\x61\x90\xb0\xe6\x89\x49\x09\x8f\x46\x48\x97\x71\x14\x3f\xfd\x32\xa3\x55\x0c\xfd\xc2\xd2\x40\xfd\x26\xfb\xbc\xe3\xb2\x80\x22\x4f\x20\x72\x3a\x72\x48\x82\x2d\xaa\xf7\xdd\x40\x56\x92\xc5\xf8\x5d\xb4\x11\xc7\xad\xfd\x00\x75\x97\xd1\x85\x3c\x34\x9c\xa5\x8d\x49\xe4\x9c\x7c\x1e\xf1\x26\x3c\x3a\x26\xe1\x24\x3c\x48\x2c\x4d\x1c\x35\xb2\x6a\x65\xe1\x4a\x73\x0f\x16\xdb\x4c\xa1\xf2\x8a\x6d\x89\xea\xd4\x8e\xec\xeb\x79\x62\x33\x19\x39\x3b\xa6\x0f\xb4\x03\xf6\x7f\x4f\x23\xea\x34\xbb\x50\x97\x6a\x7d\xff\x6d\x7f\xf5\x74\x7b\xbb\xed\x8f\x72\x83\xd3\x08\xdd\x68\xa7\x2f\x4c\x1a\xa5\x71\xac\x43\x5b\xb3\x70\x32\x1c\x87\xcf\xd2\xfc\x34\xd2\x4e\xb7\xf9\x80\xcd\x09\xdf\x1a\xf2\xc7\x62\x21\x31\x19\xd0\x23\x70\x57\xaf\xd8\xcd\xd3\x38\x61\xd8\x33\xef\x76\x6c\x2f\x65\xf9\xeb\x7e\x54\x1a\xa7\x2e\xc6\x47\xe5\x9f\x77\xc8\x77\xd5\xcd\x0c\xb0\x96\x12\x42\xbc\x0d\x9a\xe3\xb4\xf8\xc7\x36\xea\xca\xa7\x24\x4b\x30\x02\xcf\xcb\xa6\xcd\xdb\x93\x8b\x14\x27\x33\x26\xa5\x71\x84\x12\x10\x4e\x29\x6e\xdf\x7c\xa6\x65\xc7\x53\xca\xa8\xcd\x42\x4b\xd3\x40\x7d\x0d\xb2\xd8\x1e\xcf\x92\xde\x94\x6a\x57\xcd\x40\xb8\xc3\x44\x78\x96\xa7\x2c\xcd\x98\x6f\xe1\xaf\x9c\x23\xe6\x79\x98\x93\x32\xab\x9c\xbc\x0f\x56\x14\xb6\xdf\x17\x9b\xd5\xfe\xe1\x66\xbf\x5b\x2d\xee\xc2\xf7\x70\x99\x26\xae\x62\xd2\x25\x23\x98\xdb\xca\x21\x25\x4f\x45\x9a\x61\x9c\xd8\x6d\x68\x77\x79\xd9\x4e\xfb\xf0\xd3\x5f\x4b\x52\x83\x76\x2b\x3e\x2d\x5a\x2f\x1f\xdc\x3b\x3c\x41\x81\xa5\x49\x96\x69\xd7\x43\xd1\x55\x6d\xce\x40\x40\xd3\xaf\x4c\x23\x2a\xbc\xce\x59\x40\xe4\x6c\x90\xc8\x06\x6b\x3d\xbf\xd8\x94\x26\x5e\xaa\x23\x84\x01\x43\xb4\x30\x7d\xb9\xd3\x94\xa6\xb8\xf3\x63\xab\xef\x36\x6f\x2e\x02\xbf\x3e\x5b\xe3\x87\xf7\x38\xcd\x32\x2a\xc7\xc0\x39\x0f\x70\xf1\x2d\xa7\xc9\xba\x95\x4a\x2a\x82\xcd\xf1\x7a\xb7\x43\x51\xd2\x6d\x3e\xa5\x5d\xf2\x54\x32\x27\xac\xeb\xc1\x4c\xbb\x6a\xe1\x25\xf8\x67\x4c\xe5\x51\x01\x20\x95\x59\x46\x93\xb1\xd4\xf9\x19\x87\x2b\x26\x3e\xea\x48\x55\x4c\x54\xe6\x04\xe8\x46\x2f\x96\xa2\xd6\x17\x84\x4a\x59\xec\xed\xa9\x34\xb5\xcc\xfb\xce\x4d\xaa\x84\x03\x0d\x0d\x86\x1b\x33\xce\xe8\xec\xa1\x69\xa6\x50\x3f\x1c\xab\xe2\xce\x82\x34\x57\x05\x8c\x94\x16\x77\xd5\x76\x2c\xcf\x76\x39\xd2\x9a\x7f\x2b\x10\xac\xf0\x6f\x8f\xd5\xeb\xd0\xae\x98\xbc\xea\x26\x4e\x48\x28\x7f\x61\x35\x7e\x16\x97\xfb\x61\x10\x45\x48\x42\xdb\x56\x63\x76\x10\x4f\x2d\x15\x84\x4d\xec\x62\x7e\xe4\xe5\x48\xb8\x8a\xa7\xd6\x00\x62\x1d\x4a\x78\x7f\xcc\xcb\x12\xcc\xe2\x78\x5c\x97\x4d\x3b\xc9\x6e\x26\x4f\x34\x8b\x12\x92\x75\x53\x6d\x29\x8f\xed\xa9\x86\xdd\x0b\xdc\x14\x72\x22\x10\xcd\xb3\xc8\x30\x15\xda\x7e\x23\x03\x1b\x9e\x45\x60\x11\xd9\xe7\x6a\x5e\x5f\x56\xb0\xa7\xbf\x1a\x47\x86\xf5\xd6\x9f\x8f\x75\x7e\x90\x75\x78\x01\x33\xc2\xd3\xd8\x39\xf6\x99\x6a\x6f\x40\x9a\x22\x2f\xa1\x3f\x98\x99\xb1\x97\xcd\x3d\xfc\x9c\x76\xcb\x32\x62\xd8\x70\x93\xee\x2b\xd3\xa3\xbd\x32\x1a\xf5\xa2\x3b\x8b\x06\x7b\xcb\xfa\xb5\x79\x6a\xa0\x76\xe4\xd3\xcb\xb4\x25\x9e\x51\xe2\x94\xbc\xa4\x31\x08\x45\x31\xb3\x9c\xaf\x4b\x38\x11\x0e\xf6\x3f\xb8\x8a\x85\x5f\x63\x59\x1a\xb8\x32\x5d\x1e\x58\xbf\x92\xe9\x3d\x65\x59\xa6\xc4\x04\x7b\x56\xd9\xbc\xbf\x0a\xce\xdd\x65\x02\x52\x41\xcf\x84\xda\xbf\x2c\x51\x74\xef\x3d\x06\xf9\x5e\x36\x72\xae\x64\xc4\x33\x21\x34\x0d\xe4\x22\x68\x5f\xf6\x6a\x9a\x5c\x86\x51\x99\x92\x83\x62\x82\x19\xd0\x73\xd3\x61\x49\x92\xa0\x9a\xd9\xfa\xad\xaa\x51\xfb\x36\x5c\x43\x92\x3a\xed\xc6\xa6\xed\xe2\x6a\x2d\xe7\x9d\x87\x4f\x45\x81\x79\x96\x46\x29\x16\x07\x3c\x5c\x77\x07\x3f\xfb\x6f\xed\x36\xc3\xee\x10\x2e\x50\xd5\xfb\x08\x4a\x32\x33\xf0\xe8\x86\x5a\x64\x6c\x7e\x83\xf6\xb6\x6a\x5b\xf0\x34\xba\x34\x1c\x4e\x32\xc7\x69\xeb\x82\x6c\xc7\x7b\x86\xa2\xe8\xf5\x00\x79\x96\x7a\x59\xe9\xa3\xef\xa1\x36\x1b\x59\xbe\x86\x83\x59\xa2\x79\x3c\x16\x49\x0e\x71\xfd\xc5\x35\x27\xcb\xa4\x72\xba\x86\xa1\x14\x31\x51\x16\xf1\x83\x64\x6c\x91\x67\xf9\x7d\x08\x90\x33\xa9\x59\xea\x28\x81\xcd\xcb\x6c\xb8\xa2\x56\x0e\x0a\x95\xdb\x57\x0f\x7f\x99\x1b\xcd\xf1\x4c\x09\x57\xcd\xed\xb2\x0b\xb7\xde\xf5\x7e\x5c\xf3\xaf\x4c\x9d\x69\x53\xaf\x1d\xf0\x70\x04\xf4\x79\x9f\x3d\x74\x4d\x04\xaa\x6d\x75\x4b\x68\xcf\x98\x98\x0d\x91\x71\x46\x46\xf2\xbc\xa7\xe3\x59\x6a\x9f\x69\xc5\x83\x1c\x79\xf7\xc9\x7d\x3d\x13\xa2\xf3\xc3\x0c\x8f\xb1\x51\xf8\x83\x6e\xf5\x4b\x55\x15\x5f\x14\x5b\x67\x57\x0e\x2c\x61\xbd\xc3\xd6\xba\x69\x4e\xdd\x3c\xbf\x95\x4d\x7b\x57\x99\xdc\xe6\x7d\x1c\x91\x41\x16\xd9\x3e\x5a\x1d\x49\x8e\x2c\xcf\xbb\xdb\x99\x15\x4e\xaf\x30\xf8\xf6\xdd\xc9\x9f\xf3\x02\xba\x8c\x62\x1e\xf1\x01\x23\xee\x1b\x1d\x8e\x7c\x1f\x86\xd0\x4c\xc9\x91\x97\xda\x08\x62\xf7\xcb\x37\x44\x46\x49\x8a\x6a\x11\x2f\xb2\x71\x24\xd1\xe9\x39\xca\x28\x25\x24\xee\x35\x15\xcf\x1c\x58\xb8\x8c\xac\xf3\xf2\x75\x38\x68\x17\xec\x9a\xe1\x60\xe6\x0d\x34\x0f\xd5\xdb\x05\x47\x45\x2e\x63\x92\x25\x32\x7c\xdc\x0b\xac\x39\x3a\xd2\xf0\x2d\x31\x75\x62\x43\xc7\xaa\xf8\x40\x4f\x95\xdc\x6b\xe0\x8d\x92\x42\x19\xeb\x98\x79\x14\xda\xee\xa5\x06\xf8\x21\x3f\x6e\xbb\xf5\xfe\x42\xe0\x3c\xfc\x3a\x21\x3c\x76\xb5\xcf\xee\x17\x67\x97\x4e\xa8\xf3\x19\x6d\xa0\xdd\x07\x05\x47\x79\x09\x41\x2e\x09\xd5\xd4\x19\x2e\x1d\xf2\x01\xeb\x19\x0e\x1a\x47\x46\x58\xeb\x0a\x15\x98\x46\x8d\x07\x49\x95\x15\xd0\x1b\x21\x57\xa7\xd6\x2b\xe4\x83\x19\xe9\x04\x73\x49\x81\x20\xc7\x30\x6f\xfc\x45\x3b\xa0\xd7\xec\x2c\x58\x22\xb8\x07\x14\x75\x11\xec\xe0\x4f\x13\x8e\xdb\x44\x78\x55\xa6\x2e\x2a\xb9\x3f\x1d\xc2\x11\x1e\x49\x14\x9d\x38\x54\xa5\xac\x83\x72\x27\x97\x3c\x76\x42\x8d\x23\xd0\xab\x07\x39\x0d\x23\x84\x70\x3c\x01\x94\x5b\x58\xed\xbe\x5f\x0e\x95\x24\x67\x31\x2a\x79\xec\x8f\x4e\xd8\x66\x57\x79\x05\xe3\x91\x8d\x1a\x97\xb8\x4a\x61\xe2\xa3\x11\xa1\x32\x4e\xe2\x25\x37\x4e\x71\xf0\x03\xce\xfc\xe2\xa6\xbf\x25\x6c\x26\xfb\x35\xc5\x2f\xb9\xbf\x7d\xed\xb6\x74\x39\xba\x90\x49\x94\x0a\xbf\xf7\x3a\x16\x95\x03\x8d\xcc\x46\xa5\x9a\xe3\xb5\xbd\xc8\x66\x53\xcd\xa2\x3d\xbf\x47\x48\x29\x5d\x1d\xf6\x4a\xb6\xf2\x75\x72\x59\x8a\x12\xe9\x7e\x43\x9f\xea\xbc\xfd\x98\xcd\x1e\x43\x5d\x95\x60\x59\x95\x25\xe8\x91\x93\x2d\x97\xc6\x28\xa4\xb0\xe3\x8c\x39\xcf\xd3\xa4\xb1\xae\x11\x36\x54\x3d\xce\xab\x40\x12\x22\x85\x29\x1a\xfc\x74\x1a\x2c\x70\x4e\xb4\xfd\xf5\x7d\x02\x21\x30\x3d\xb8\xcb\x0b\x68\xd0\xf8\xb7\xce\xf5\x85\xb8\x39\xfc\x1b\x30\x86\xd2\x26\x51\x24\x42\x01\xb5\x6e\xda\xd0\x1d\x38\xc7\x4a\x4b\xab\xa3\x89\x4e\xac\x23\x77\x85\xc9\xad\xe2\x98\x27\xbe\x4c\x77\x5b\xe9\xd7\x19\x9c\x68\x3a\x43\x54\x9c\x2a\xc4\xc6\xcd\x03\xb6\x8b\x61\x90\x8a\x81\x59\xdf\xdc\x73\x88\xc6\xcf\xa0\x0c\xf3\x0a\xde\x78\xa1\x55\xb1\x75\xfa\x77\x83\x0e\x08\xd4\x6e\x53\x1c\x1a\x3a\x8a\xc4\x31\x32\x87\xd0\xee\x6b\x91\xd7\xcb\x5a\x36\x2f\x93\x78\x4f\x11\xee\x98\xbc\x57\x79\xf5\x5c\x4b\x6b\xf3\xfe\xb3\x26\xc6\x80\x06\x67\xd7\xcd\xc8\x69\xcc\x1f\xa7\xcc\x62\x2e\xb8\xef\xe5\xf9\xa7\x77\x58\x51\xce\x11\x76\xe4\xd8\x01\x1f\xd7\x50\xc0\xf3\x5c\x62\x84\x2b\xaa\x33\x14\x8d\xd8\xe5\xd5\x78\x1e\x2b\x6a\x5c\xd9\xb5\x19\x90\x1b\x98\x01\x9d\xc5\x06\x8a\xa9\x14\xdf\x97\x5e\xcd\x74\x7b\x52\x9f\x3c\x28\x1e\xf1\x60\x08\xec\xb7\x96\x87\x93\xd7\xb4\x85\x7a\x9c\xb1\x28\x4e\x13\xe3\xd8\x0d\x85\x7d\xe8\x4f\x8a\x1b\x8e\xc2\x60\xce\xd8\x44\x36\x67\x8a\xc6\x7e\x9c\x48\x2d\x24\x23\xe1\x9a\x5d\xb5\x6a\x5f\xd6\xe5\x71\xa6\xf4\x14\x46\xcb\x08\x2f\x40\xcb\xf2\x3a\x6f\xd4\xa9\x6e\xc0\x7b\x6f\xe0\xe5\xf6\x73\x32\x89\xe3\x34\x09\x02\x48\x37\x75\x75\x58\x9e\xe3\xca\x54\xa2\x29\x46\x16\x2e\x53\x3d\x82\xf9\xc2\x4e\xe6\xb3\xd7\x70\xfa\x3a\xaa\x04\x5c\xbc\xf9\x0d\xe5\x8a\xf3\xc3\xe9\x70\xe5\x02\xf4\xbe\x38\xa9\x12\x1b\x61\x25\x68\x1f\x88\xef\x5f\x70\x63\x54\x9a\x45\x46\x8c\xd4\x24\xdc\xec\xf1\x45\xb7\x91\x44\x06\x4e\xba\x8b\x2b\x84\x4a\xb5\x4b\xad\x9b\xfc\xb9\x94\xc5\x95\xd4\xaf\xa7\xe3\x8f\x99\x2d\x48\x18\x6a\x0d\xd8\x10\x64\x1e\x8e\x2d\xec\xc9\x34\xe5\x51\x99\x00\x14\x67\x71\x75\xc2\x55\x69\xc6\x84\xe7\x70\x7b\x42\x49\x5c\x65\x4a\x89\x74\xf8\x3e\x0f\x2a\xbf\x48\x05\x53\x52\x30\x24\x1f\xdc\x56\xcf\x37\x55\x3d\xaa\xbc\x5e\x6e\x0e\x28\x69\x9c\xda\x2e\x2e\x36\x3b\x90\x61\x47\x55\x2a\xa1\xf8\xb6\xf7\xe0\xdd\x5f\x3d\xc9\x4f\x9e\xe8\xec\x36\xaa\xd4\x78\x11\x02\xac\x37\xc9\xc1\x45\xec\x92\x6a\x43\xf8\x50\x66\xb5\xd7\x17\xfc\x5e\x15\xe7\xf8\x39\xa5\x14\xb0\xb1\xe3\xc9\x60\xa7\x7e\x09\x6a\xa9\x34\x11\x09\xed\x83\xba\xe9\xa6\xa3\x34\x55\x28\xa0\x88\x8c\xab\xc3\x79\xd0\xab\x74\x02\xd8\xc1\x39\xca\x8f\xd0\x8a\x0e\x37\x4d\xa7\x3c\xf6\x0c\x25\x07\x58\xfe\x64\x3e\xea\x8c\x63\x8d\xb2\x5f\x4a\xa7\x26\x7c\x5c\x19\x19\x67\x63\xdd\xb0\xaf\x01\x2c\xca\xc8\x04\xc1\x3d\x7b\xaf\x68\x73\x6a\x3e\xf1\x46\xe0\xca\x68\x99\x39\xb8\xf5\xee\xe3\xf8\x19\x2f\x5a\x01\xe7\xd2\x99\xe8\x75\xdf\xd8\x38\xa7\x97\x3d\x89\xf6\x37\xa0\xea\xd3\x50\xa2\x50\x90\x70\x46\x7c\x9b\xf7\xf6\x16\xe4\xf3\xb0\xa0\x41\x26\xb1\x6f\x76\x0f\xef\xd7\x20\x8b\xff\xe7\x4e\xcc\xa5\x6a\xde\x64\x47\xd2\x11\x49\xb0\xd1\xba\x58\x86\x62\x83\x8e\x52\xeb\xbd\x22\x03\x9e\x63\xde\x88\xd4\x51\xc6\xb1\x1e\x8b\x15\x97\x07\xfb\xf4\xb4\xbe\xfe\x6d\xfa\xb5\x9a\x5a\x31\x88\x30\x7c\x93\x07\x70\xd4\xc1\xc9\x44\xd1\x91\x66\x81\xd2\x85\xc9\x4f\x77\x3f\xcf\x7f\xcc\x08\xdc\xf4\xc1\xe4\x2d\x26\xcd\x5f\xf6\x6b\x74\x04\x4e\xff\x21\x4c\xe4\x5e\x35\x7a\xd1\x56\x87\x5c\xcf\xbe\x9c\xc4\x80\x1c\x47\x55\x9c\xe0\x21\x2c\xda\x9a\x08\x83\xa0\xb5\xf6\x25\xaf\xcd\x2e\x87\x3a\xd0\xc6\x9f\x8e\x47\xa8\xf1\x54\xc7\x6d\x1e\x4d\x4c\x8a\x2f\x8f\xa9\xf3\x37\x58\xca\x7a\x7a\x33\x68\x44\xb1\x0b\x70\xfc\xa8\xe5\xe1\x02\x92\x6a\x7a\x4f\x68\x94\xa1\x08\xeb\xa9\x9c\xca\xa6\x4c\x27\xa1\xa6\x0a\xb0\xb5\x71\x1c\xb4\xce\x1d\x42\x66\x7a\x37\xa8\xd5\x88\xce\xdb\x37\xd0\xa2\x1c\xf4\x55\xe8\x66\x5f\x9e\xb6\x9a\x51\x83\x25\x02\x54\xb6\x23\xd3\xce\xbd\x66\x09\xc3\xdc\xff\x8f\xaa\x85\x87\xf2\xee\x63\x07\x4d\x21\x97\x55\x51\xf5\x77\x82\x01\xc7\xdf\x5b\xfc\xb9\x5e\x2c\x1f\xd6\xf7\x9f\x9c\x3d\xe7\xce\xb1\xeb\xc7\xbf\xba\x59\x3f\x8e\x21\x34\x97\x04\x39\x58\x2f\xb2\xb0\x17\xa3\x40\xcd\xc1\x64\x83\xc7\x77\x6f\xf1\x77\xb1\x24\xa9\x85\x95\xd8\xf0\x7f\x85\x8f\x07\x3b\x5f\xc9\xfd\x98\x44\x12\xea\x65\x21\xab\xab\x53\x78\x31\x75\xa2\xa2\x60\x63\xe3\x1e\xc5\x2e\xe0\x8f\x74\x6a\x18\x3a\x6e\x62\x83\xf4\x9c\x7d\x7c\xa1\x7c\xae\x33\xe2\x82\xf8\xb7\x1c\xde\x31\x85\xee\xe5\x97\xcf\xdc\xd3\xb9\xce\xa8\x03\x11\x77\x81\x54\x0e\xf5\x46\xb6\xe7\xa8\xc4\x4f\xe6\x7f\x26\xf8\x48\x50\x05\x39\x6c\xe1\x48\xc2\x10\xfb\x5f\xf6\x92\x0e\xdf\x65\xf3\x02\xc3\x8f\x5a\x8e\xb7\xa1\xd1\xb2\x00\x13\xfa\x9c\x8f\x53\xfe\x81\xd6\x04\xf0\xd4\xae\x17\xbb\xd5\x7e\xbd\x7c\xd8\x8f\xcc\x5d\xb8\xd6\x09\x43\xec\x8f\x3a\x61\xb0\xe3\xf9\xd9\xb3\x97\x4e\x83\x74\xa6\x87\x07\xa8\x9f\xa1\xd4\x1f\xf3\x28\x60\x76\x49\xda\xa6\xf8\x92\x7a\x96\xd5\x27\x73\xca\x24\x14\x3d\x14\x1e\x8e\xa3\x04\x49\x9b\x44\xd8\xc1\xb6\xc1\x2d\x06\xe1\x18\x28\xa6\xe8\xc4\x01\xb3\xc5\xe6\xa5\x3b\x6c\x62\x12\xe1\xda\xe8\xea\xca\x93\x94\xcc\x10\x22\x10\x1b\x77\xf7\xf1\xd4\x40\x7d\x3f\x40\xdb\xc2\x71\xe5\x54\x2c\xfc\x76\x32\xb6\x63\xbd\x98\x35\x04\x1a\xcd\x68\xc6\x18\x9a\x02\x6a\x35\x1e\xf2\xb2\x1d\xf4\x10\xc2\xc1\x8c\x63\xf3\xe4\xcf\xeb\xc9\x9f\x59\x62\x31\x32\x1f\x35\xdc\xd3\x0b\x60\x30\xc3\x6c\x62\x7c\xbd\xf2\x20\xeb\x8f\x6f\x72\xec\x50\xc2\x0d\x4f\x04\x36\x48\x3d\x78\xba\x99\x2a\xf4\x76\x11\x75\x8c\xc9\xd3\xb6\x0b\xe5\xda\x53\x0d\x1b\x78\xee\x8f\x59\x81\x80\xf2\x0a\x3d\xe9\x64\xb1\xcd\xfb\x29\x68\x04\xa3\x78\x49\x20\xeb\x72\xc4\x93\x32\x22\x89\xb1\xca\x8c\xef\xd3\x7c\x07\x30\x22\x4b\x5c\x49\xa0\xae\x2a\xfb\x60\x37\x20\xcd\xb4\x6a\xf7\xcb\xc6\xa8\x49\x32\x8a\xb9\xb7\x09\x52\x76\x33\x10\xd3\x27\xc1\xc1\x74\x8d\x1e\x77\xa2\x4c\xca\x14\x62\x24\xf6\x35\xa0\xde\xe7\x65\xa6\x81\x49\x99\xc9\xb2\xbe\x5c\x5a\xd5\x8f\xa7\xba\x37\x7b\xe1\x26\xcd\x9c\x21\x67\xf3\x71\x50\x3d\xb0\xc6\xa4\xd6\xa1\xba\x9a\xd3\xe1\xbb\xac\xcd\x52\x1e\xd7\xcb\x07\xe4\xa2\xf7\xcf\x2f\x93\x11\xfe\x3a\xfc\x74\x14\xfe\x41\x46\xa6\xf7\x71\xe9\x87\x6a\x1d\xa7\xc1\x3e\xc9\x31\xf3\x2e\xbf\x41\x46\x45\x14\x5f\xde\xd7\xfa\xe3\xd8\x42\x5f\x1a\x32\x4a\x8a\x60\x5d\xf9\x1d\x64\xd1\xbe\xdc\x54\xf5\xb2\xf2\x7c\x93\xb0\x8a\x1a\x05\xe0\x9c\xdf\x72\xfb\x0b\xf2\xb2\xd1\x52\x63\xef\x6a\xfd\x6d\xb7\xfd\x76\x1d\x7e\xc6\xb0\x14\xf7\x0e\xff\x3a\x36\x8f\x50\x8f\xd1\xa6\xc6\x28\x2a\x7d\xa1\xe0\x7f\xe0\x1d\x8a\x4f\xee\x38\x44\x91\x24\xbd\x81\x0e\xd4\x6f\x60\xae\xb1\x85\x87\x4b\x34\x36\x8e\xe7\x88\x9c\xd9\x17\xc8\x08\xeb\xd1\xba\x00\x59\x2e\xf4\xa4\xac\x12\x02\x6a\x88\x78\x1c\x47\x17\x9f\x91\xd7\x7f\xe4\x10\x0b\x40\x72\x0d\xea\x51\xa2\x94\x84\xb5\xfd\xa3\x87\x38\xb3\x41\x37\xe7\x74\xfc\x7f\x26\x53\xfd\xff\xfc\xf7\x0b\x27\x7b\x0e\xb1\xc9\x6c\x32\x08\xc9\x35\x37\x55\x3d\x01\x37\xf8\x61\x44\x66\x28\xca\x86\xb9\xe4\xa6\xbb\xa9\x63\x4c\x74\x18\xa4\x13\xcc\x0f\x8e\x7d\x93\x78\xbd\x7c\xf0\x2f\x5f\x35\xc7\xd0\x01\xcd\x04\x16\xa0\xfa\x86\x86\xcf\x2e\xc7\x74\x0d\xa0\xda\xe1\x48\xda\x3e\x39\xdf\xbe\xcb\x23\x26\xe8\x5f\x87\x84\x40\xb5\xc1\x08\xf2\x58\xc3\x68\xaf\xbe\x3c\x96\xe9\x18\xf7\x9a\x17\xd9\x2d\x7a\x5d\xf0\x0a\xc6\xb1\x39\xa6\xb1\x2b\x30\xc3\x10\x17\x74\xfd\x74\xff\x6d\xf5\x70\x7f\x99\x66\x0f\x3c\x4e\x70\xa1\x74\x65\xef\x19\x84\x7f\x7a\x13\xb8\x0f\x10\x4c\xa5\x4f\x48\xb2\x1c\x77\x47\x41\x08\xa7\xe8\x9d\xa3\x3c\x9c\x23\x7c\xa0\x5e\x5f\x18\x90\x24\x32\xe2\x81\x4e\xd9\xc2\x61\x8b\x9a\xf9\x63\xf4\x3c\x24\x8a\xa2\xfa\x43\x97\x31\x15\x83\x9c\x28\x87\x34\xa1\x29\x1f\x63\xdf\x37\x60\xfb\x63\x52\x38\x73\xf6\xea\x8a\x92\xdf\xce\xd6\x41\x48\x8d\x60\x6c\x10\x0d\x72\x34\xff\xe9\x2a\x33\x5e\x89\x21\xb5\x34\x94\x59\x10\xe4\x1f\x7e\x27\x8b\x63\xdc\x1a\x2c\xc0\xd5\xc0\xa4\x04\x95\x3a\x97\xa2\x45\xdb\xc2\xe1\xf8\x49\x31\x0f\x34\x18\x24\xb3\xfe\xeb\x97\xd0\x79\xd0\x60\x5d\x45\x74\x0b\xed\xe6\x84\x2b\xcd\x08\xad\x04\x26\xe5\x49\x40\x6c\x3d\xd6\x60\xc0\xe6\x25\x98\x09\xba\x01\x20\x76\xfd\x90\xbc\x59\x62\x90\x55\x0c\x4f\x01\x98\x63\x53\x35\x80\x4e\x4f\x5d\xc8\x70\x03\xae\x22\xc4\xa7\x61\x2c\x40\xaa\xa4\xaf\xfb\xaf\xcb\x33\x94\x60\x18\xa4\x08\xf3\x1e\x08\xa8\xe3\x82\xc2\x65\x7d\x88\x02\x36\x8b\x93\x74\xa4\xc9\x8f\x16\x0f\x5f\x69\xec\xd8\x48\xa4\x4c\xf5\x86\x28\xaf\xf2\x19\xba\xe0\x65\xac\xf7\x16\x06\xda\x18\xa3\xdf\x2e\x73\xb8\xaa\x73\xf3\x0c\x53\x4a\xe4\x74\xf6\xda\x98\x08\x7c\x3b\x7d\xfb\x77\x57\xf5\x31\x5d\x18\x90\x28\xcc\x65\x83\x5c\x50\xdf\xdb\xb5\x24\x82\x14\x7d\xf9\x16\xf7\xd7\xcb\xcd\xff\x3e\xee\xbe\x7a\x7e\x96\x10\x16\x79\xdc\xc3\xfa\x20\x9f\xe1\x1c\x09\x64\x49\x4a\x1c\xc0\x58\x16\xe0\x50\x4e\xbe\x94\xe0\x8f\xd3\x94\x28\x3d\x04\x03\xae\x91\x76\x71\x39\xb0\x2c\x01\x06\xa1\xf3\xfe\x7c\x2a\x50\xa0\x1c\x7b\x64\xb7\xf0\x06\xc5\xa5\x3a\xbf\xe5\x49\x8a\x60\xfa\x9b\xf5\xd5\x62\xfb\x7b\xf8\x51\x9e\x59\x04\xbb\xbe\x55\x73\x5b\x86\xe9\xf5\x09\x62\x55\x36\xaa\x5b\x5c\xc3\x5b\xae\x61\xb4\x01\x7d\xea\xaf\xc0\x6d\xca\x12\x3b\x16\x0e\xdf\x55\x17\x4d\x1a\xce\x2f\x33\x63\x14\xf7\xee\xdd\x8b\x2c\x5f\x67\xfc\x42\x2b\x13\x16\x2c\xe4\xf7\xb9\xae\xca\xfc\xbf\xfb\x76\x8a\x0c\x9c\x4e\x05\x65\xb4\xf1\xe2\x1c\x2f\x93\x2f\x52\x56\xf6\x5e\x71\x57\x27\x8c\x00\x9f\xca\xc1\xbc\x24\xbc\x44\x56\x0b\x8a\x29\xcc\xe3\xed\xe2\x7f\x57\x1b\x97\x60\xec\x1f\x57\x9b\xf5\xc3\xf5\xb6\x1f\x93\x64\x58\xa8\x0e\x68\xa4\x0d\x38\x93\x10\xe8\xa5\x9a\x7d\xea\xf1\x89\xd6\x6e\xf8\x1a\x15\x45\xbe\x63\xf8\x25\xce\xc7\x1a\x23\x90\xdd\xf3\x22\x9b\xbe\x3f\x37\x4f\x39\xfb\xe7\x00\x11\xa0\xc6\x98\x0b\xfe\xaf\x67\xd3\x13\x48\x82\x88\x71\x54\xb8\x5b\xd6\xf9\xb1\xad\xc2\x55\x01\x73\xa6\x63\x8e\x87\xb1\x84\x7a\xa6\x19\x3c\xc1\x10\xcf\xce\x10\x38\xa1\x5e\xc4\x66\x7b\x52\x65\x65\xfc\x2a\x8c\x1f\x21\xb3\x20\xc7\x82\x48\x45\x8f\x73\x5a\xdb\xa5\x2c\x9f\x1a\xf8\x0a\xf0\x69\x41\x58\xc4\x2a\xf7\x0d\xc8\x10\x5d\xcd\x56\x18\x4b\x18\xa2\xdd\xb7\x50\x14\x97\xbf\xf0\x93\x49\x68\xa9\xd6\x1e\x9b\x7f\xf7\xb1\x38\x1e\x7b\xd7\x32\x6e\xad\xb5\x51\x16\x0e\x5d\xc9\x52\x96\xd2\x1f\x13\x51\x44\x98\x75\xfd\x5b\x75\xfa\x70\x56\x64\x66\x38\x26\xb1\x8e\x5c\x75\xdb\xaf\x47\x8b\x0d\x36\x62\x97\xc2\x3f\x11\x45\xe0\x74\x09\x36\xab\xed\xea\xf6\x76\x7d\xff\x6d\xff\x74\x7f\xfb\xb0\xfc\x7d\xbf\x7c\x78\xba\xdf\xf5\xdf\x0c\x1a\xab\x64\xed\x79\xed\x75\x76\xb5\x7e\x56\x88\x28\xb2\xce\x79\x76\xa4\x47\x13\xf4\x86\xe7\x69\xc7\xac\x53\x39\x3d\xc1\x38\x12\xdc\x55\x36\xa5\x7e\x01\x73\x27\xff\xcf\x91\x75\xc6\x77\x53\x44\x31\x75\xb2\x47\xdd\xcb\x76\x8b\x0e\xe7\x8f\xaf\xcf\xdf\xd0\xec\x21\x5c\x43\x9c\x38\xf5\x0c\x59\xe4\xda\x59\x01\x34\xd7\x9f\xe4\x47\x9f\x95\xa6\xdd\xe4\x8a\xc2\x17\x1a\x08\x66\x43\xbb\x79\xf9\xed\x52\x34\x20\x22\x42\x23\xac\x49\x78\x78\xd1\x68\xeb\xfa\x12\xe0\x33\xbd\x21\x84\x3a\xbf\x84\x45\x61\xe5\xae\x7a\x9f\x7a\xa9\x75\x87\xb5\xb2\xfd\x8a\x5a\xfb\x8e\xf2\x78\x9f\x15\x11\x11\x06\xcb\x44\x57\x27\xfd\x0a\xed\xa2\x44\xfd\x78\xa7\x8e\x50\x1a\x2c\xd0\xa0\x04\xe6\x57\x13\x58\x44\x44\x39\xe2\xf2\xe2\xee\x6a\xd7\x93\x74\x44\x44\xc0\x99\x89\xf7\x22\x2a\xf0\x16\x0e\xd1\x94\xc9\x28\x38\xf5\x15\xa7\x49\x11\xa1\x3b\xea\x0c\x0d\xd6\xcb\x87\xfd\xb7\x5a\x1e\x5f\x20\x60\xd7\x44\xc4\x12\x07\xc0\x3d\xc8\x56\xbf\x04\x6e\xff\x55\x6e\x9a\xd9\x85\xb1\xcc\xf9\x40\x36\xce\x58\x68\xe3\x24\xb6\x7c\xe6\xf6\x8f\xc9\x3f\xe1\x13\x92\xf4\x11\x02\x6a\x7f\x1f\xb7\xf9\x5f\x30\x9b\x5d\xdc\xbf\xe4\x18\xbc\xb8\xd0\x7f\x14\xae\x8a\x48\xd0\x08\x81\x5c\x5d\x4e\x7a\x3d\x55\xb8\x10\x91\x10\x1a\xc3\x7d\xb4\x3a\x0c\x41\xf6\x67\xb5\x91\xf0\x99\x0c\x70\xfb\x5c\xae\x1f\x2f\xea\x42\xfa\x61\x09\x03\x94\x10\x94\xc6\x5c\x41\x09\x58\x81\xa8\x2f\xf3\xd8\x44\x94\x08\xd7\x69\x7d\x1f\xa4\x54\x2f\x2e\x55\x97\x99\x8a\x22\x4a\xd2\x44\x92\xde\xf7\xbe\x1a\xb9\x02\xf2\x28\x1a\xf2\xab\xee\x3f\xc2\x27\xa4\x73\xac\x43\x90\x33\xce\xd2\xdf\xce\x4a\x85\xc8\xbb\x4c\x83\xbf\xd4\x34\x88\xfb\xb2\x35\x24\xa2\x94\x32\xd4\xa7\x30\x0b\x63\x66\x92\xf3\x97\x5a\x01\xe1\x53\x09\x43\x04\xbe\xc3\x72\x5f\xe5\x66\xce\x8a\x09\xe3\xc0\x11\xa2\xae\x65\x2b\x7f\x74\xdb\x60\x97\x15\x5d\xe8\x9c\xcf\x7f\x72\x32\xa7\x33\xce\x10\xc6\xa2\x5f\x64\xfd\x0c\x0b\xf3\x06\x75\x9b\x37\x23\x5a\xd5\x24\x45\xfd\xac\xa1\x25\xa2\x2c\xa5\xd6\xeb\x0b\x2e\xea\x36\xb7\xf2\x4c\x8c\x60\x7a\xf2\x19\xb0\xd4\x75\xc6\xab\xf6\xa3\xc6\x5e\xdc\xb6\x87\x58\x89\x48\xb2\x54\xc2\x08\x57\x3c\x86\x5c\xff\xed\x24\x7b\xfa\x30\x24\x4f\x10\x8f\xbe\xfd\xbe\x20\x5c\x74\x11\x76\x6f\x8d\x3a\x3d\x35\x25\xa3\x74\xb0\xe4\xbc\xc9\x4b\x59\x62\xdd\xac\xad\x65\x0b\xcf\x1f\xe1\x14\x55\x28\xe5\x57\xef\xb3\x2d\xd5\xb7\x39\xbb\x21\xce\x97\xaa\x4b\x07\x2e\xca\x4e\x8b\xc8\x50\x8b\x69\x6b\x7e\x38\x16\xfb\x43\x5e\x5e\x42\x68\x0c\xe9\x9d\x88\x4c\xaa\x31\x58\xe9\x36\x90\x1b\x99\x17\x4e\xe3\xd3\x6d\x28\x1b\x70\xd2\x77\xf7\x55\x3b\x12\x18\x16\x91\xc9\x98\x0a\x90\x50\x8f\x59\xdb\x3f\x57\x21\x6b\x11\x11\x70\x67\x42\xe3\xf9\xf8\x88\x88\x1a\x82\xaa\x4b\xa5\xa3\x80\xed\xce\xc2\x3d\x83\xd4\x91\xa6\x71\xfb\xed\xbf\x57\xdb\xc8\xbb\x0c\xdf\xc3\xfb\x76\x6c\x68\xf8\xab\x67\xe7\xbf\xc1\x4a\xc7\xbf\x6b\x3e\xca\xf6\xe5\x1b\x94\x9f\x68\x01\x88\x38\x22\x06\xa1\x26\x58\x1b\xde\x5e\x6c\x92\x8a\x38\x82\x08\xbb\xce\xdf\xa0\x5d\x34\xaf\x18\xed\x7a\x21\xd7\xdf\xc2\x08\xeb\x44\x59\x8f\x6f\x30\x38\xe5\xfb\x63\x71\xe6\x5c\x89\xb6\xaf\x75\xae\xa6\xe5\x5f\x11\xc7\xca\x62\x2a\xbf\x7f\x86\xb6\x57\x76\xc9\x0b\x58\xa0\x78\x12\x25\xff\x18\xad\xe8\x31\x8d\xdd\x62\x3c\x12\xa1\x9d\x9e\x28\x25\x9c\x38\x99\x54\x2f\x4d\x16\xfe\xae\x34\xa2\x8b\xf2\x66\xf5\x56\x15\x6f\xc8\xbc\x40\xb2\xcf\x27\x16\x82\x22\x66\x89\xd3\x66\x0e\x3b\xf9\xca\xe1\x7d\xc3\x17\x32\x9d\x88\x5e\xf7\xa5\xd1\x93\xed\x2e\xe6\xa0\x51\xfb\xe4\x5d\x36\xdb\x93\xc3\x21\xfa\x23\x42\xb1\xd8\x51\xf7\xb4\xeb\xc4\x9c\xb7\xba\x44\x9c\x88\x04\xcb\x6d\x21\xf8\xc0\x16\xff\x45\x54\xbc\x88\x93\x54\x93\x68\x8a\x6a\x23\xe1\xc7\x12\xe3\xa0\xbc\x5a\xd6\xad\xfc\x99\x4f\x6e\x7b\x2a\x14\x62\xf5\xee\x16\x7f\x06\x47\xc6\xfd\xc3\xcd\xde\x9b\x03\xf5\xa3\xb2\x78\xa4\xcf\xb3\x6a\xb4\x3c\xc2\xb9\xce\xb7\x1f\x9c\x51\xe7\x25\x72\xc8\xcb\x9e\x79\x2c\x62\x19\x0b\xeb\xb6\x16\x5d\x95\x66\x4c\x07\xe9\x47\x64\x24\x94\x75\x07\xff\x84\x64\x7a\x47\x65\x46\x9c\xf4\xa5\x6c\x70\xda\x8d\x6a\xfc\x22\x56\xb1\xc0\x8a\x92\x34\x66\x5d\xee\x40\x1e\x7c\x6b\x70\xae\x03\x25\x62\x45\x9c\x9e\xbf\x6c\x9a\xfc\xb9\xbc\xea\xf6\xf9\x8f\x33\x04\x77\x58\x99\x63\x05\x14\x49\x00\xba\x2f\xee\x88\x58\x13\x96\x44\x7d\xe8\xbb\xa9\xaa\xb6\x7f\xb6\x3a\x93\x28\x80\xec\x56\xbf\x4f\x40\x28\x5f\xbf\xb6\xb1\xd6\x4e\xbe\x44\xe6\xb5\xa9\xab\xa3\xd7\x95\x9b\xb8\xae\x8b\x58\x9b\x14\x0b\x10\x2d\x1a\xff\x37\x37\x15\x4a\xf3\xac\x7e\xe2\x44\x9b\x7e\x9f\x89\x89\x17\x54\x73\x40\x9c\xbc\x7c\x9e\x4d\x64\x43\x9d\x52\x24\xb6\x95\x82\xae\x54\x73\x8d\x7d\xba\xe9\xcd\x33\x54\x07\x7e\xf0\xea\xa7\x2e\x4e\x66\xe8\xe8\x0e\x7b\x70\x0c\x99\x13\x0a\x41\xce\xd9\xd5\x09\x2d\xf5\x77\xef\x55\xf8\x39\x1b\x1b\x7c\x02\x9b\xc5\xfd\xb7\x95\xcb\x87\x69\x7f\xcc\x6a\xb7\xca\xc8\x16\xde\xe5\x47\x2f\x7d\x34\xc1\xc6\x0a\x12\xa9\x2c\x1b\x00\x1e\x2d\xd4\x68\xf3\x84\x2a\x3e\x77\xb2\x94\xcf\xf8\x72\x5f\x0e\x94\x48\xcc\x12\xca\xc3\x6b\x8b\x62\xbe\xb3\x59\x4c\xe2\x84\x21\x03\xc1\x63\xe3\x97\x85\x7c\x03\x67\xb2\x31\x1b\xa7\x34\xd6\x98\x83\x75\x8a\x6c\x5e\x03\x25\x69\xc6\xfa\xf9\x5b\x4f\x9e\xc4\xd6\x09\x58\x6d\xb1\xbd\xb7\xc8\xeb\xeb\xba\x3a\xfe\xe9\xec\x88\xa6\x23\x49\x6c\xb0\x89\x71\x38\x15\x7f\xce\x0e\xd1\x38\x75\x82\x69\x20\x0f\xbf\x03\x1c\x9d\xd8\x47\xb0\xc4\xf5\x83\x18\xb1\x41\x1e\xec\xa6\xae\xca\x76\xe5\x53\xb8\x31\x12\x5a\x10\x26\x5c\x06\xf4\xaf\x83\xd2\xfd\xdf\x80\xd3\xb1\xba\xec\x75\xe5\xad\x0c\x67\xa7\xc1\xa5\xd0\x4e\xa1\xbb\x36\x38\x73\x87\x1c\x82\x24\xca\xa2\x26\xce\x11\x23\x93\x55\x69\x9a\x45\xeb\xf8\xf0\xb3\x0d\x9e\xa4\x94\xc6\x51\x00\xd0\x9c\x9a\x30\x0d\x26\xc1\x66\x18\xca\xac\xf2\xee\x48\xf7\xf9\x5f\xaf\xdb\x91\xe9\xb2\x20\xa9\xd0\x78\xbf\x3c\x4f\x70\x52\xd1\x0d\x43\x32\x46\x92\x51\x0e\xbc\x81\xc6\xa3\x0a\x77\xd5\x38\x20\x20\x99\x91\xc8\xed\x9b\xf0\x1b\x04\x9b\x47\xb1\x93\xda\xd6\xa7\xa1\x1f\x91\xc2\x89\xb8\x68\xb4\x95\x6d\x27\x4b\x1e\x91\x52\xa1\xe2\x37\x4e\x81\x91\x5c\xb5\x20\x4a\x3a\x37\xe5\xff\x9e\x64\x2d\xcb\x36\x2f\xcf\xa0\x15\x17\x7e\x4b\x49\x67\x7a\xda\x2d\x13\x60\xd6\x0f\xbf\xaa\x2f\x0b\xa2\x33\x67\xee\xb9\x7d\xb8\x7d\xda\x8e\x37\x0f\xa2\x33\x8d\x90\xc1\x6e\xf3\xf8\xe3\x61\xb7\xba\x0e\xe2\x47\xab\xcd\xb2\x1f\x23\x39\x8a\x86\x2f\xab\x46\xf5\x93\xca\x44\x4e\xab\xb7\x7a\x83\x7a\x23\xf3\x06\xcc\x53\x89\x8c\xcb\x70\x5c\x02\x0f\xd4\xe6\x6e\x99\x9f\x76\x6b\x05\xb1\x16\x24\x84\xdd\xce\xa3\xd1\x6e\x5c\x63\xd7\x0f\xa1\x51\xb7\x52\x0d\x5e\x20\x55\x71\x46\xf1\x0a\xb7\x84\xc6\x3a\x46\x32\xfc\x8d\xeb\x0d\xdf\x00\xac\xcb\x49\x77\x5c\x50\x4a\x23\xea\xe1\x7b\xdb\x7a\x0a\xb9\x11\x94\x05\x33\x3c\x67\xf7\xe8\x03\xbf\xee\x7c\x7a\x1c\x5b\x18\x99\x08\x54\x78\x2a\xf2\xa6\xed\x16\xc4\xd1\xf9\x32\x70\x61\x2c\xae\x97\xfb\xca\xee\x9d\xc6\xcc\x84\x37\x2a\x28\x8f\x08\xe2\x94\x76\x8b\xfb\xeb\xa0\xbb\x27\x28\x67\x16\x31\xf0\x57\x0f\xf7\x4f\xdb\x00\x61\xf8\xb6\x8a\xbb\x6d\x7c\xdf\xed\xe3\xb4\x1f\x09\x12\x57\x2b\x44\x19\xef\xaa\x79\x32\x36\x79\x9b\x28\xb7\x1a\xe5\xf6\x3e\xe4\x4b\x55\x39\x01\xa6\xa7\x7a\xea\x87\x29\xa8\xa0\x11\x22\xbd\x57\xbb\x6f\x0f\xb7\xe3\xd6\x7d\x77\x88\xe0\x46\xf1\x58\x57\x4d\x77\x19\xed\x47\x7f\x84\x1b\x6c\xb1\x1c\xab\xaa\x98\x28\x49\x0a\x9a\x44\xd6\xa5\xa0\xf2\x0d\x1e\xf3\x69\x40\x45\x13\xe6\x68\x61\xbd\x19\xc6\x0f\x74\x0c\x45\x73\xbf\xcb\xf1\x1b\x4d\x63\xe7\xec\xe8\x1d\xa1\x5a\x38\xac\xfb\xbb\x99\x12\x8b\x25\xfe\x67\x79\x08\x80\xbb\x61\x07\xa3\x29\xd5\x21\xf7\x38\x77\x46\x4d\xc3\x20\x21\x9d\x31\xd4\xc7\x1d\xb4\x2f\x95\x21\xd3\x13\x4e\x33\x85\xc5\x0a\x34\xe3\xff\xdc\x19\x25\x8c\x96\x29\x46\x37\x5d\x3e\xea\x92\x51\x0c\x0b\xdd\x32\x36\xdb\xd2\xa9\xcc\x24\xb2\x0b\x71\xc2\xac\xcb\xb7\x1e\x94\x20\xa8\x8e\x12\x64\xf9\xdd\x9e\xf4\x6b\x7f\xcf\x75\x1c\x93\x38\x34\x72\x6a\xd8\xbf\x7e\xe8\x50\xfc\x46\xc1\x82\x7d\x79\x3a\x78\x36\xd3\xf4\x87\x74\x1c\x9b\x9e\xfc\xb3\xd5\xf2\x70\x98\x55\x48\x05\xd5\x94\x66\xc9\xd0\xe8\xde\x7f\x80\xec\xe7\xbc\x16\xce\x38\xee\x58\x35\xa8\x52\xf1\x38\x99\xd0\x46\x38\xad\x01\xac\xbf\xdf\x56\x4d\x83\xfd\xd7\xfe\xa8\x71\x84\xda\xeb\x5c\xb6\xd5\xa1\xff\x2b\x30\x43\x5c\x16\x72\x49\x0d\x69\xf4\x08\x81\x88\x34\xea\x4d\x10\xb6\x79\x0b\xbb\xfc\xf8\x89\x39\xbc\xa0\x20\x28\xf2\x7a\x0e\x13\xde\xa8\x60\x51\xec\x62\xbd\xdd\xa9\xad\xea\x5c\x5e\x26\x58\x9d\x41\x34\x04\x8b\x84\x8b\x1b\x43\x2f\xeb\x5c\xec\x48\xb0\xc8\x48\x07\x7b\x68\x5f\xa6\x04\x21\xc1\xe2\xcc\x45\x02\x8f\x8b\x3f\x7d\x81\xaf\xbf\x30\x46\x64\x8c\x33\xa5\x3a\xb6\xeb\xf2\x5b\x5f\x3a\x66\x44\x6b\x7c\x56\xd6\x83\x50\x11\xc7\xe3\x4b\x9a\xd3\xc9\xc6\x88\x31\x58\xb7\x40\x45\xd7\xbc\x5f\xea\x18\x95\x80\x75\x08\x47\x67\xc5\x19\xeb\x18\x05\x5d\x70\xe9\xc8\xfb\x5b\x79\x80\xfb\x6a\x78\x69\x19\xb3\x1a\x57\x50\x17\xd4\x3b\x89\xbf\x49\x89\x74\x8e\xd3\x14\x8c\x47\x12\xd7\xac\x77\x07\xc9\x9d\xf4\xd6\x04\xe3\x94\x26\x72\xa0\x58\x9d\xb9\x83\x09\xc6\x95\xc4\xa5\xb4\x84\xf7\x10\x62\x5f\x5c\x00\x98\x20\x11\xce\x96\xdd\x0b\xdc\x55\x4d\x3b\x72\x31\x58\xbd\xf5\x2b\x33\xba\xec\x88\x7e\x99\x40\x66\xf9\x67\xdf\x97\x12\xe6\x2b\xf7\xb8\x61\x9c\x6b\x34\x0b\x26\xb2\x98\x7a\xc1\x92\xc7\xaa\xfc\x2b\xc7\xf5\x63\x5d\xfe\x80\x7c\x76\x15\x42\xa5\xdc\x0c\xec\x26\xec\x88\x4e\xa2\x5c\x26\x8c\x65\x66\xa0\xca\xad\x7a\x76\x88\x60\x09\xe1\x38\x09\x8c\x07\xb6\x5d\x9a\x5f\x89\xb1\x38\x89\x76\xab\x6d\xf8\x53\xaa\x33\xeb\xd6\x35\x84\xe8\xf5\xcb\x21\xcb\x04\xc7\x6a\x83\xbb\xe9\x57\xb2\x7c\x9d\x5d\x56\x96\x10\x3e\x56\xea\x7d\x78\x83\xda\xd4\xd2\xb6\x5f\xb4\x59\x04\xcb\xb2\x04\x99\xb2\x77\x95\x9c\x88\x09\x08\x96\x69\x2d\x07\x2a\xee\x58\x5e\x79\x42\xaa\x9b\x7f\x9f\xc9\x52\x27\x41\xe0\x1a\x64\xe1\xdb\x24\x93\xf8\xfa\x3e\xdd\xee\x36\x8b\xfd\xf7\xd5\xe6\x61\x7f\xf7\x74\xbb\x5b\x3f\xde\xae\xfb\xad\x92\x49\xc3\x30\x74\xdd\xad\x57\x9b\x78\xbf\x0c\xb6\x6d\x82\x49\x0b\xd8\xa8\x92\x06\x45\xcf\xdb\x97\x39\xa2\x5c\x30\x95\x25\x28\x09\xa8\xaa\x9f\x64\xdb\xca\x9a\x87\xcf\xea\x48\x61\x4f\x7b\xf5\xb3\x85\xb2\x41\xd9\x0b\x6c\xa1\x87\xd8\x2f\xfd\x4f\x18\x98\x38\x2c\xaa\xbf\x51\xbb\x0a\xc3\xe7\x0b\xe9\x13\xd3\x29\x15\xee\x59\x60\xe6\xb7\x42\x9b\x3c\x57\x99\xea\x65\x8e\xc3\xcf\x83\xd6\xd8\x4b\xb2\x55\xad\xa1\xcf\xef\xc2\x51\x2b\x62\x9b\x05\x22\x65\xe3\x7c\x48\xa7\xd7\x65\x85\xc1\xf0\x73\x55\xc0\xf1\x45\x0e\x2b\x81\x4d\xad\xea\x59\x8c\xd7\x79\x59\x0d\xce\xc7\x82\x59\x69\xb0\xf7\xe3\x7f\xed\x5b\x25\x8b\xc1\xcc\x27\x8c\x51\x99\x30\x83\x8d\x6d\x9f\xb9\x72\x42\x89\x8e\x46\x1e\x78\xa1\x04\x33\x99\x6e\x9c\x50\xb7\x1d\xe2\x06\x8c\x1a\x2a\x81\x03\x23\x38\x49\x62\x0c\x2b\xeb\x53\xe9\x25\xf3\x4f\x83\x99\xea\x59\xe9\x92\x53\x62\x7a\xd9\x9a\xbc\x7c\x0e\xbf\x17\x8e\x1a\xc0\xb5\xc4\x29\xd2\xbf\x07\x69\x05\xc1\xa9\x4d\xb1\xa2\x80\xc8\x20\x1f\xa8\xcc\xd2\x61\xce\x58\xe2\x54\xbf\x2b\x84\x23\x3f\xfc\x7f\x9c\x7d\x5b\x73\xe2\x3a\xb6\xff\xd7\xd9\x0f\xff\x07\x5f\x25\xf9\x11\x08\xe9\xe6\x74\x12\x18\x20\xdd\x7b\xcf\xa9\x53\x94\x2e\x4b\x89\x4f\x8c\xcd\xd8\x26\x09\xf3\xe9\xff\xe5\x25\xc9\x37\x4c\x7a\xcf\xa9\x9a\x9a\xde\x15\x0b\x63\x64\x5b\x5a\x97\xdf\x45\xef\x3f\x8a\xfd\x6b\x5a\x8e\xa4\xef\x48\x1c\xb3\x40\xf5\xcc\xa8\x9e\xe0\xa3\x05\x99\x4f\xc5\xdd\x71\x9c\x18\xbb\x1d\x44\x5b\x3d\x2e\xfa\x44\x7e\x12\xc7\x10\x09\xb3\xb3\x65\xd9\x4a\x41\xbb\x03\xc4\x24\x09\x11\xc8\xbb\x37\x45\x81\xcd\x2d\xfd\xe2\x2b\xe0\x14\x73\xf1\x70\x4c\xa3\xc4\x4f\xda\x75\xc0\x90\xba\xee\xcb\xe2\x68\xcc\x52\x87\xbf\x9e\x52\xf3\x0a\xbf\x40\xfd\x50\x7c\xfc\x4a\xf3\x29\x84\x33\x89\xa9\x66\xa8\x40\xb3\x2f\x4e\x83\xfa\x53\xcc\x7c\x05\x7e\x0f\x1c\x30\xd6\x63\xff\x02\xdf\x45\x62\x16\x07\x18\xa0\xda\x1a\x37\xd2\x01\xd7\x79\x7f\x3b\x18\x48\x1a\xfe\xe6\xff\x4d\x3f\x7a\x82\x7c\x49\xe2\x24\x02\x8c\x52\x7e\x15\x65\xa6\xe6\xe9\x08\xdb\x12\xb8\x7f\xc6\x91\xc8\xef\x88\xca\x24\x4e\x18\x71\x6e\xad\x7d\xed\x08\x12\xf3\x30\x40\x98\xc6\xfa\x73\xf7\x0a\x59\x0d\xe5\xf2\x02\xdd\x31\x61\x00\x4c\x28\x87\x7e\x07\xc7\xe2\xa5\xe4\xa7\xd7\x54\xb6\x0f\x01\x97\x92\xda\x12\x8d\x13\x85\x9b\x9f\x15\x32\xb6\x56\xd3\xba\x1a\x24\x16\x9e\x44\x4c\x2a\x2e\x11\xce\x50\xd0\x0a\x98\xa0\xa0\xfe\x4d\x7d\x05\x33\x71\x57\x61\x18\xfe\x75\xf8\xb4\x88\x40\x38\xf2\xb1\xed\x0a\x34\x77\xdc\xe2\xfd\x2d\x81\x69\xf4\x80\x89\x98\x63\x69\xfd\xc4\x2f\xbb\x22\x3b\x1b\x51\xe3\x0f\x5e\xaa\x6f\x45\xa1\xb6\x70\x9a\xde\x74\x62\x41\x7d\x44\xc4\x48\x3d\xc2\xed\x90\x58\x28\x1d\x9a\x76\x7e\x3d\x3b\xab\xb4\x06\x85\x82\x17\xd7\x3d\xc1\x58\x40\x14\xd3\xde\xc3\x39\x3b\x5d\xb5\xd8\xad\x97\x64\x3f\xbd\x6f\x3f\xcc\x91\x83\x2e\xce\xd9\x9b\xd5\x4f\xc8\x6f\xa9\x31\x90\x58\x92\x28\x6c\x5d\xab\x35\x94\x70\xad\xb8\xe8\x46\x26\x9e\x6b\x54\x3e\x15\x0a\xe6\x97\x89\xd2\x71\x0c\x0a\x4c\x35\xdd\x96\xa5\x76\x20\xcb\xb6\x16\x4b\xbc\xd0\xe0\x93\x5e\x8b\x7a\x53\xd4\xbc\x2e\xfa\x68\x22\x42\x3c\x2e\x42\xee\x10\xbe\x26\xf1\x7e\xee\x93\x87\xba\x6d\x8a\x78\xdc\x49\x60\xa2\xd8\x5d\xb3\xed\xd8\xdb\x3f\xf8\xc7\x8e\xf6\xa9\xd1\xcc\x58\x64\x69\xf3\x8e\x9b\xbd\x0c\xd4\x1f\x13\x6f\x06\x09\x3c\x83\xaa\x1b\x2b\xe2\x5c\x25\xf1\xc3\x6f\x9a\xee\x23\x92\xc0\x6a\xae\xbf\x40\xde\xe4\x38\x30\xab\xb1\xfd\x53\x94\x96\x0f\x9a\x16\x39\x0a\xb6\xf1\x2f\x75\xb9\x6f\x20\x6f\xba\x2a\x8f\xfd\xb6\x90\x0a\xdf\x6e\x6f\xcb\x4a\x9e\x21\x1b\xda\xa9\x12\x12\x32\x6a\x19\xfa\xf2\x5c\x56\xe9\x3b\x18\x58\xf0\x97\x95\x41\x12\xf2\xc8\x14\xad\x9b\xa7\x7f\x5e\x16\xf9\x35\x95\x66\xf4\xab\x43\xcd\x98\xe5\xc8\x61\xa0\xf1\xbd\x2b\x60\x37\xa9\x02\x36\xf3\x0e\x69\x65\x17\x4c\xec\xba\x8c\x2e\x34\xb2\xcc\xb0\x26\x3e\x3b\x98\xfb\xe3\xee\x16\xae\x99\xee\xff\xfc\xf6\x03\x2a\x50\x66\xef\xa8\x8a\x73\x29\x61\x60\x2e\xf2\xff\x7a\xbc\x78\x42\x62\xc2\x98\x5d\x0c\x50\x49\xf7\x3f\x6c\x4e\xba\xb3\x30\xa6\x8c\xa9\x58\x91\x63\x8a\xb2\xff\x28\x36\xc5\xe9\x46\x9b\x8b\xc4\x82\xc4\x1d\xcb\xce\x84\x55\x23\xfd\x0e\x42\x62\x30\xe0\x1c\x91\xd6\x47\x5e\xbd\x1d\xaa\xd7\xe2\x63\x3c\x44\x1b\x67\xbf\x53\x09\x2f\x39\xcf\x0d\x7b\xea\xae\x70\x04\x00\x42\x88\x2f\xbc\xc8\x09\x1a\x9b\x84\xbe\x3a\x15\x79\x35\x55\x2c\x27\x84\xc5\xc4\x08\xb4\x15\xa7\x87\xeb\xbb\x40\xa4\x70\x94\x0f\x5b\xad\x56\xf8\xba\x41\xf7\x6d\x60\x82\xbc\xb4\x72\x31\xde\x0e\xc6\x67\xa1\x5e\x24\x03\xa3\x5e\x52\xf4\xb4\xed\xde\x6e\xb5\xbe\x08\x0b\x28\xfe\x84\x7d\x0b\xbe\xdb\x5a\x6b\xdf\xe9\x45\x97\x30\x12\xa3\xde\xd7\x0e\x11\xe0\x53\x6f\x35\xa3\x26\xb4\x38\x9c\x4c\x40\x37\xc8\x07\x08\x13\x01\x96\x3a\x67\x3f\x46\x05\x3f\x92\x84\x21\xb6\x3a\xee\x9e\xb7\x06\x93\xbc\x59\x6e\x0f\x3f\x97\xbb\xfd\xea\xe9\x5b\x3b\x86\x28\x6e\x35\x73\xbf\xa7\xef\xdd\xdc\x70\x3f\x71\x0a\xa9\x87\xba\x95\xa9\x20\x84\x87\x04\xd3\x9d\x1c\x3e\x5a\xbf\xc0\x5b\xac\x89\xe9\xdf\xcb\x43\x11\xd8\xe6\xdf\x7f\x3d\x2e\xf7\xdf\x07\x5d\xad\xd1\x50\xaa\xd0\x5e\xe5\xc4\x2f\x26\x9b\x1d\x4c\x0b\xe7\x41\x6c\xc9\xf8\x9b\xb2\x38\x41\x59\x5f\x6e\x5a\xeb\xdf\xb4\xda\xff\x02\x16\x48\x08\x97\x22\x64\x36\x14\xdf\xbf\xf6\x54\x93\x9e\x8a\xfa\x5a\x31\x8f\x10\x0e\x20\x3b\xcb\x18\xd4\x08\xcd\xae\xc5\x67\x08\x11\x61\x8c\x72\x54\xce\xb6\xb6\xd5\x12\x71\xc7\xa9\xc2\x1a\x08\xe2\xee\x6d\x7d\xff\xde\xa4\x0c\xc3\x0e\xf3\x68\xe9\x52\x1c\x10\xc2\xa1\xb9\xac\x8b\xf2\x32\x4c\x8a\x9b\x7c\x25\x20\xce\xef\x71\x0c\x58\xbb\x71\xb3\x80\x00\x86\xa0\xd6\x9e\xc3\x9a\x56\xd9\x4c\xcd\x8d\x51\x1c\x37\x9d\x8e\x6c\xc4\x5d\xe9\x94\x68\x92\x20\x8e\xfa\xf0\x82\x70\xc4\x36\x55\x9d\x06\xdd\x11\xad\x49\xdc\x36\x64\xe7\xe7\xb2\x0d\xed\xa8\xe7\x51\x04\xc3\x88\x73\x99\xdf\x3d\x2d\xa6\xdf\x25\xea\xc5\x89\x11\xb7\x4e\xdf\x61\xf6\xc1\x2f\xd6\xec\xa8\x57\x54\x71\x03\xa5\x27\xa4\xab\x95\x83\xec\x59\xf7\x11\xea\x83\xc6\xd9\xff\xb5\x5c\x1d\xf6\xeb\xc3\xea\x69\xb7\xfa\xf6\x7d\xef\x2a\x01\x34\x54\xc6\xc6\x10\xde\x31\xe4\xee\x3f\x92\x34\x8a\x38\x86\xbc\xb3\xbb\xbb\x2d\x4a\x0e\x9a\xda\xfe\xee\x30\x5b\xf4\x61\x83\x34\xf6\x08\xf2\x01\x14\x64\x60\x6d\x8d\xa7\x70\xda\x84\xc6\x42\x18\xf8\x5e\x51\x67\x30\x10\x35\x23\x94\x5a\x16\x95\x71\xc5\x0f\xbc\xbb\xa2\xc5\x85\x51\xca\x22\x64\x87\x77\x80\xd6\x41\x30\x32\x9c\x35\x16\x10\x65\x2c\x5d\x3e\x6d\x8e\x67\xbc\x17\x27\x4a\x23\x94\x45\x1a\x39\xae\xad\x1c\x72\x30\xfd\x2c\x52\xc6\x7d\x8c\xe4\xd0\x32\xfe\x2b\x39\x34\x42\x99\xd2\x68\x28\xf2\x08\x65\x96\xe6\x8b\xbe\xe9\xf8\xc4\x72\x48\x19\x08\xec\x1c\xec\xb8\x86\xbb\xf4\x7d\x7a\x1d\xa6\x4c\x0b\x83\xf4\x99\x2d\xf6\xab\xc5\xec\xc1\xd9\xda\x3c\xce\xfe\x3c\x2c\x66\xdb\x6f\xae\xa7\x46\x93\xd0\x28\xe8\xb9\x78\xf5\xab\x37\x8c\x26\xca\x00\x3e\x4c\xe5\x15\x74\xfb\x7c\x72\x8f\x61\x8f\x00\x55\x04\xdd\xda\xf0\x7b\x07\x47\x42\x45\x40\x10\x41\x6a\x30\xfb\x5d\x32\x43\x45\x28\xb1\xf4\x7c\xce\xd3\x7a\x79\x4a\xe5\xb7\xb2\xf8\xa8\x5d\x24\x42\x65\x18\x62\x09\xbd\x6d\xc4\xda\xbf\x2b\xe5\x71\xe3\x93\xa3\xb0\xb7\x3b\x7a\x9e\x80\x18\x48\xf2\x0b\xd4\xb3\xb6\xa9\x49\x81\x11\x54\x51\x30\x0c\xb6\xb3\x00\xd7\x99\xbb\xfe\xe7\x7a\xa2\xb5\x2f\x65\xa7\xbb\xc7\xcf\x55\x7b\x5a\xad\x03\xcc\xc5\x85\xf1\x1a\x31\x7f\x65\x9e\xa7\x7a\x4e\x33\x0b\x7e\x9a\xb2\x35\x21\xcc\xa7\xc6\xd9\x12\xcb\xec\x81\xd7\xf5\xb9\x58\xe0\x6b\x04\x08\x37\x77\xf2\x71\xf5\xb0\xdc\xed\xd7\x4f\x0e\x74\xc1\xc2\x08\x42\xd2\x43\xe4\xec\x6a\x9e\x2b\x5e\xaa\xb1\xb8\x38\x61\xa1\xf2\xb1\xd7\xb5\xfe\xfe\x6b\xfd\xeb\x57\xfb\x79\x0d\x61\x87\x00\xbb\xa2\x88\x4d\x16\x4a\x58\xa4\xb8\xcf\xdb\x0f\x21\x60\x28\xad\x9e\x73\x04\x1f\xb8\xd9\x60\x91\x06\x4b\xa8\xaf\xa1\x84\xaa\x5e\x5c\x64\x06\x0f\x90\xbf\xb4\x37\x95\xc5\x40\x43\x62\x23\x9a\xd9\x3b\xaf\x79\xd9\x5a\x4a\xda\x11\x24\x30\xec\xba\x0d\xaf\xeb\xcb\x94\x3b\x61\xff\x4d\x41\x35\x3a\x83\xb7\x90\x19\x3f\xf2\x0d\x7f\xe1\x47\xc8\x1d\xce\xbc\x39\x1e\x22\x87\xcb\xbc\x9e\x2b\x59\x4c\x2f\x10\x8c\x79\x21\x66\x4f\x8b\xbf\x5c\x87\x92\x31\x5f\x21\x74\xa6\xb9\x86\x0d\x2f\xfb\x42\x46\x84\xb1\x98\x49\xe6\xde\x92\x12\x13\xcf\xf6\x10\x0d\x8d\x2f\x12\xfa\x70\x0e\x03\x16\x96\x78\x8c\x87\x3d\x25\xf0\xf2\x0d\xea\x47\xfe\x36\x2a\x6a\xfa\xa3\x27\x90\x25\x09\xc5\x55\xf7\xbe\x28\x6a\xc1\xb3\xbf\xdb\x6a\x60\x09\x97\x88\x85\xd8\xff\xb5\x59\x1e\x9e\xd6\xfb\xc3\xec\xe7\x6c\xf5\x30\x9b\xb7\x10\x1e\x96\x80\x31\x1a\x59\xcc\x17\xed\x2f\x17\xbe\x51\xce\xfd\xfb\x92\x2c\xc3\xab\x15\xc2\x0f\x6c\x81\xee\x01\x5e\x78\x66\xac\x0a\xf2\xb7\xc1\x4e\xc2\x84\x32\xe4\xcf\x87\xe2\xa5\x49\x81\x4d\xf6\x7e\xb5\x94\x0c\x3f\x02\x11\x96\xc5\x1f\xff\xda\x6c\x06\xb7\x43\xf9\x12\xa1\xf1\x8e\x89\x54\x94\x8b\xe2\x78\x6c\xd6\x95\x4b\x3b\x84\x86\xc6\x49\x03\x1b\xa9\x15\x94\xef\xa9\x84\x60\x12\x8c\xeb\x12\x36\xa6\x12\xcf\x39\x49\xd8\x6e\x32\x66\x24\xf6\x28\x28\xe2\xb5\x5b\x79\x4f\xf2\x98\x30\xed\x71\x62\x03\xf3\x79\xaa\xe6\x97\x5d\x5a\xf7\x90\x5c\x6c\x34\x5d\x3a\x31\xee\x21\x98\x2b\xb4\x5c\x83\xd1\x18\x69\x50\xd0\x77\xc5\xcb\x96\xb7\x0d\x96\xc4\x13\x80\x2a\xb1\x66\x97\xfd\xd6\x76\x75\xdc\x2f\x48\x3c\xc9\x91\x4a\xfa\x7c\x6c\x4e\xe7\xbb\xcf\xf9\xdc\x10\xcd\x4d\x18\xb7\xca\xb1\x55\x70\xe6\xd9\x82\x9f\x26\xda\x11\x49\x10\xc6\xdc\xfa\x60\x60\x74\x5e\xb7\xe6\xed\x24\x09\x58\x88\x22\xec\x2d\xa5\xee\x67\x91\x9d\x8f\xb0\xcc\x65\xc6\xdf\xe1\x9a\x12\xf1\x3b\xd8\xcb\x80\x68\x34\x8d\x47\x4e\x82\xc4\x88\xd5\xd9\xb0\x7a\x94\x7d\xd8\x41\x61\x64\xaa\x19\x69\xb5\xed\xbf\x9f\x49\x48\x09\x36\x1e\xb7\xa7\xf6\xb5\x4c\x42\xa6\x90\x09\xfb\x81\xe9\x93\x1a\x86\x95\x49\x44\x22\x14\xf9\x48\xab\x05\x3f\x67\xaa\x6c\x72\xe2\x53\x5a\xda\x9b\xc4\xdc\x28\xed\x85\x49\x47\x25\x1f\xa4\x30\x49\x4c\x19\xc2\x2b\x0c\xf4\xb8\x65\x93\xff\x0d\xab\x6b\x82\xbc\x4e\x6c\x23\xac\xcd\x7a\xd1\x7f\xf2\x13\x02\x71\x62\x8b\xf1\xe7\xe3\x06\x05\xc2\xbb\x43\x1a\xdd\x0c\x76\x0f\xeb\x36\xb6\x4b\x88\x16\x68\x9a\x7e\xc7\x2b\x89\xb0\xa5\x2f\x56\xd7\x84\x46\x10\xd1\xb6\x4f\x6a\x23\xa7\x39\xd4\xab\x7c\x42\x53\x8b\x24\x2c\x22\xa1\x3f\x04\x6f\xf9\x9e\xfb\x62\xa6\xcc\x0e\x5c\x99\x67\xc8\x40\xb1\x26\x99\xcd\x24\x49\xa4\x91\x0c\x6f\x62\x57\x14\xff\xf9\x01\x97\xbf\x35\x55\x5c\x46\xa8\xcb\xb5\xd9\xae\xfe\xb9\x3c\x6c\xd6\x7b\x07\x5e\x9c\x7d\x5b\x36\x71\x91\xbb\x18\x01\xcc\x94\x4a\xa1\xaa\xbf\x01\xd6\xdc\xfb\x08\x80\x44\x80\x84\x56\x87\xf6\x25\x2d\xf2\x35\x32\x0e\xad\xf4\x92\x1b\xa4\x43\x67\xc6\x62\x57\x87\x96\x9a\xd8\x9d\x49\x72\x0f\x2b\x61\x95\xe4\xef\x60\x40\x92\x65\xe1\x70\x41\x6e\x8c\x88\x14\xef\x24\x7e\xce\xc2\xaa\x64\x5c\xcb\x71\x35\x63\xa9\x0c\x7b\x53\x53\xbd\x8e\xfb\x36\x89\x8a\x05\x16\x67\x6c\xd7\xd5\x6a\x52\x4f\x01\x77\x13\xc5\xc3\x20\x6a\x23\x15\x85\x2b\x90\xf9\xd6\xc1\x73\xa0\x94\xa2\x7e\xab\x2d\xb1\xe0\x37\xaa\xab\x09\x84\x14\xc1\x2a\x30\xce\x9b\x6f\x0c\xe7\x21\x06\x03\x47\xa3\xdb\x65\x56\x1e\x77\x4c\x18\x2e\x9e\xb9\xb2\x9f\xe8\xe2\x09\x65\xb5\x31\x9c\x97\xd1\xf2\x98\x80\x8e\xbc\x2e\xe2\x32\xf6\x24\xa8\xc8\x6c\x8f\x6b\x9f\x3b\x10\x3d\xda\x15\xfd\xe3\x0c\xd5\x78\x2e\x34\xe3\x2c\x6c\x95\x45\x75\x5a\x1e\xf9\xb5\xd0\x20\x49\x34\x4f\xb0\x6f\xbc\x1c\x6b\x7a\xf0\x0c\xc1\xbc\x30\xc1\x14\x70\x1f\x15\x06\xe8\x8c\x49\xf1\x59\xb6\x2c\x72\xc2\xbd\x28\xb1\x11\x7a\x5d\x42\xfa\x3e\xe2\xa7\xd9\x41\x7e\x13\xc9\x77\xe6\xaf\xd6\x36\xdb\x8a\xff\xa5\xf9\x8b\xf5\xe8\x1e\xbd\x95\x4d\x92\x12\x4b\x57\xe7\x68\xb6\xaa\xc3\xbf\xce\x3c\xaf\xbb\xad\x91\x87\x91\xc6\x0e\xa9\xbb\x6d\xc3\xe8\x62\x32\x4d\xe0\x51\xa4\x30\x6e\x50\xf0\x7e\x86\xec\xdd\x10\x76\x33\x18\xcd\x16\x8f\x12\x45\x6c\xc9\x73\x91\x96\xb2\x2d\x24\xf0\xd8\xd7\xd8\x34\x5d\xa7\xd9\x4f\xcc\x4d\x0d\x6e\xcf\x1d\x25\x26\x7b\xb4\xdc\xc6\xea\xa9\xa8\xaf\x0a\x57\x9c\x04\x31\x0a\x31\x9e\x32\x9e\xd7\xb2\xbf\x2a\x72\xc2\x44\xe2\x5b\x55\xcc\xe7\x5c\x41\x55\x97\xc5\xa5\x57\xc7\xe0\x24\x51\x5e\x2b\x78\xbd\xfb\xd7\x99\x97\xa6\xa1\x75\xa3\x3e\xc8\x09\x37\x92\xb8\x9b\xf5\xf7\x5d\x5d\x9c\x3a\x59\x53\xc2\xa9\xe7\xe3\xd2\x5e\x97\x5c\xc1\xd8\xb9\x99\x70\x4a\xfd\xd6\x97\xd9\x2a\xc8\xb7\x70\x57\x4e\xa5\xc6\x40\x41\xf2\x2c\xbb\x6b\xae\xb2\xc3\x25\x72\xe6\x11\x14\xd4\x38\x15\x95\x53\xde\x71\xa8\xe1\xe6\xeb\x1f\xd3\xbe\x3d\xf1\xf4\x55\x27\x51\xe0\x90\x2b\x86\x85\x67\xbb\x7e\x83\x9e\x21\x4f\xe2\x80\x5b\xd0\x2b\xca\x9e\x67\x19\xb6\xda\x1e\x0a\x9e\xb7\xd6\x31\x3d\x79\x64\xf3\xaf\xc9\x95\x6c\x63\xb5\xbd\xdd\x89\xd2\xb8\xe7\x1e\x1c\x14\x60\x66\x80\xca\x43\xa2\x8d\x1d\xcc\x49\x68\x88\xfc\x46\x74\x1c\x05\xeb\x9a\x30\xc6\xad\x9d\x9c\x0b\xb3\xef\x56\x50\x8f\xb1\xd8\x76\x84\x48\x28\x5e\xfa\x2b\xaf\x7e\x0e\x48\x15\xf6\xb8\x8c\x13\x14\x1d\x6e\xe6\x70\xb5\x58\xff\x8e\x5d\xf4\x75\x5d\x8f\xab\xc8\x0f\x7d\x27\xb8\xf1\xaf\x73\x13\x01\x18\xdd\x08\x77\x9c\x48\x63\xc9\x34\xd2\xcf\x75\x87\xa9\x17\x71\x2b\xda\xdb\x67\x76\xfd\xb7\x4f\xae\xb8\x94\xee\x23\x5c\x05\x60\xdb\xb9\xbb\xba\xe8\xb8\x7e\x5c\x69\x40\x31\xb5\x26\xae\x6b\x56\x20\xbc\x53\x5f\xf0\x5b\x38\x44\x66\x32\xb9\x52\xc6\x32\x1a\xd4\xac\x14\xe9\x55\xe9\x8e\x6b\x11\x92\xd8\xa5\x54\x23\x4b\x73\xc2\xb5\x34\x56\xc9\x60\xf7\xa8\x1e\x52\x9f\x6b\x29\xad\xcc\x90\xe5\xff\x15\xf9\xb5\x3b\x20\x11\xbe\x6f\xe0\xbf\x15\x42\xeb\xee\x0a\x2e\xb9\x7b\x21\x84\x1f\x46\x38\x85\xf8\xd5\xad\xb8\xe7\x68\x25\x14\x3e\x44\xca\xc0\xd6\xad\x74\xd8\x64\x34\x20\x02\x99\x04\xdd\x82\xb9\xc9\x78\xad\x8b\xb2\x75\x66\x9c\x32\x61\x26\x22\xa2\xda\x48\xd2\x14\x99\x5a\xe7\xbb\x1e\x30\x5a\xc4\xb1\x71\x2b\xad\x53\x18\x70\x00\x45\xcc\x78\x97\x0c\xa2\x6c\xc5\x7d\x51\xf6\x48\x57\x22\xe6\xd4\x78\x2d\xa0\x24\xc0\x08\x97\xe4\xc6\xc8\x18\xb7\xa8\x7b\x80\x51\x7d\x66\xf2\xdd\x16\xb1\xa6\x88\x79\xdc\xf0\xb2\x19\x9e\x61\x0f\xda\x7d\x21\xe1\x1a\xcd\xa0\x2b\x14\xc0\x32\x0a\xfc\x29\xcf\xef\x8a\xb3\xc8\xa0\x89\x3e\x6f\x71\xd9\x06\x7d\xf5\x21\xeb\x9e\x08\x4a\x64\x60\xa1\x85\xf9\x68\x07\x16\x2c\x60\xa8\x03\xf5\xd0\x03\xa4\xff\xbf\x7e\xb8\x24\x18\x89\x70\xb7\x77\x52\x4b\x6e\x4d\x53\x83\xd5\x48\x30\x02\x58\xb4\xd8\x3c\x2c\xb6\x3f\x8b\x3e\x51\xdd\x0e\x48\x3c\x53\x1c\x9b\x9d\x9c\x4d\x22\x11\x09\x4f\xb0\x0c\x70\x04\xc5\xb3\x79\xd1\xac\x98\xb9\x9a\x9f\xcb\xbc\x2f\x96\xe9\xe2\x2d\x21\x7c\x8d\x64\x69\x43\x4e\xac\xf9\x5b\x9a\xbf\x58\x35\xee\xd1\x77\x09\x9e\x60\x01\xb2\xca\x78\xf5\xba\x3b\xf2\x2c\x7b\xae\xa0\xcc\x47\x06\x8f\xdd\x2c\x48\x4f\x63\xe8\x55\xe4\xd9\x05\x97\x86\xea\xbe\x4c\x3b\x0f\x25\x22\xa4\xcf\x59\xe2\x70\x11\xf2\xcd\xfd\xf8\x43\x6a\xb9\xa5\xe3\x0b\x90\x41\xc0\x4c\x40\xbb\x3c\xdc\x3f\x3f\xdd\xad\x9e\xbe\x1d\xbe\xad\x67\x0f\xed\xf9\x42\x1d\x72\x87\x3a\x2b\x41\xf2\xaa\xde\xc9\x62\x0c\x80\x17\x32\xe2\x88\x44\x12\x03\xa9\x19\x22\x64\xcc\x05\x75\x9e\x35\x08\xe4\xdd\x3e\x0c\x42\x3f\x21\x75\x80\x77\x8d\x1f\x0f\xe9\xa1\xc8\x0f\xf5\x2b\x1c\x3e\x5c\xd9\xdf\x9d\x46\x79\x89\xc1\xc3\xa8\xb4\x3e\x54\x5c\xc3\x58\x00\x66\x70\x4a\xc5\x94\x41\x69\xdb\x1a\xe2\xcc\x49\xe3\x4e\x87\x4d\x02\x18\xa3\x8e\xb5\x10\x0c\x61\xc1\x42\xfb\x31\x26\xb2\x2f\xfc\x08\x7d\xc2\x99\xd0\x11\x20\x35\x69\xbf\xde\xcf\x1e\x5c\x8d\xfa\x7e\xbd\x3d\x2c\xb6\xeb\x5f\x77\x3d\x12\x93\xd0\xb1\x91\x35\x7d\xdc\xae\xee\x9e\xdb\x89\xd5\x32\x08\x4c\xe7\x6c\x95\xb7\x56\x68\xc3\x9b\x23\x3d\x2d\x9c\x78\x5d\x3b\x64\x95\xcf\xd1\xde\x6d\xd4\xf6\x97\xbe\xc7\x90\x65\x60\xa8\x45\xfb\xe2\xb7\xa4\x5d\xe9\x07\x1c\x2d\x75\xee\xcf\xd2\xfa\x27\x10\xe9\x47\xca\xd8\x03\x64\x45\xd5\x25\x4f\xb7\x5a\x3f\xfd\x7f\xbb\x1a\xe7\x57\x0d\x23\xf7\x8a\x48\x9f\x18\x22\xcc\x73\x05\x19\x54\x95\xdd\xc6\x4f\x56\x74\xc2\x5d\x4e\x10\x52\x11\xb9\x06\x24\xa8\xbe\xe4\x94\x1b\x41\x88\x34\x5b\x22\x0a\xe7\x42\x59\x35\xa9\x9c\x3b\xc8\x18\xf6\xf5\x5a\x6f\x9a\xc3\x91\x7f\xb6\x07\x55\x84\xf4\x82\x3f\xf7\x0f\xbd\x3f\xc9\xa4\xb5\x1b\x48\x4f\xd8\xa7\xb7\xe7\x75\x63\x42\x62\x1a\xb0\xa9\x2c\x96\xb7\xd1\x59\x32\x64\x46\xa2\xe0\x05\xea\xe5\xfe\xfb\xf3\xee\xce\x7d\x3e\x0e\x34\xe6\x57\x87\xc3\xe1\x30\x96\xe1\x9b\x84\xb2\xb8\xcf\x45\x1e\x69\xcb\xe6\xcd\xae\xd4\x9e\x90\x46\xf8\x86\x36\xa9\xa6\x17\xce\xb2\x54\xc2\xfc\x7c\x19\x4c\x63\x0c\x1c\x03\xfb\x54\x16\x73\x78\x49\x9b\xa8\xab\xfd\x38\x09\x04\x52\x4f\xec\xef\x98\x17\x45\xfb\x30\xd0\xc0\x37\x4e\x1d\x65\x7a\xdc\x02\x37\xde\xd1\xbd\x80\x43\xd2\x88\xa2\xa4\xd0\xd3\xfc\x57\xfb\x27\x6e\x04\xd8\xb1\x8b\xb5\xfd\x1c\x44\xfa\x76\x08\xf3\x05\xa2\xde\xce\x79\x2a\x8b\x32\x1f\xbb\x33\x12\xc9\x82\x88\x77\x34\x5e\xbb\x8d\x36\xdb\xf4\xa8\xd8\x29\x59\x60\xe8\x1a\x78\xbf\x7e\x41\xfa\xf2\xda\x1d\x8a\x05\xba\x66\xee\xa1\xaa\xe7\x3c\x97\x45\x79\x5f\x94\xc7\x73\xc6\xdb\x01\x8a\x63\x17\xa6\xc8\xc1\x9a\x7e\x2f\xcf\xed\x4d\xe6\x94\x60\x55\xf7\xa1\xa8\xeb\xf4\xb3\xb3\x4f\x21\x52\x44\x02\x01\x2e\xdb\xe5\x6e\xb9\xfd\xb9\xbc\x3b\x2c\x17\xeb\xdd\x5f\xbb\xfd\xf2\xf1\xf0\x6d\xbb\x7e\x76\xb0\x4e\x29\xa9\x71\x33\xb2\x25\x7a\xc8\x40\x8c\x23\xff\xff\x26\xff\xd3\xfb\x4f\xf7\x39\x2e\x11\x5f\xf7\x5a\x9c\xcb\xc3\xa0\xea\x2f\x95\xf0\xf0\x4e\xd9\x18\x1a\x4a\x9b\xea\xdb\xc3\xe0\xd1\xc4\x24\x4c\x79\x71\x4c\x73\xde\x65\x7f\x12\x78\x88\x9d\x15\x2b\x22\xeb\x02\x94\x9e\xa1\xc6\xe8\x16\x81\xf2\x28\xeb\x8b\xdd\x1b\x9a\x55\xb5\xca\x07\x88\x89\xe1\x6d\xd3\x71\x80\xd7\x67\xa2\xa1\x66\xf7\xb9\x92\x2b\x27\x52\x2b\x3f\xe8\xd0\x5e\xff\x67\x57\xfa\xe6\x44\xdc\x23\x2e\x9b\x3e\x97\xd5\xa0\xf3\x23\xb5\x0e\x95\x6e\xf1\xcd\x4d\xf2\x8f\x70\xb2\xa2\x9a\x96\x27\x22\xca\xf3\x02\x6e\x54\xe8\x44\xf3\xa4\x0d\x77\x01\xe5\x05\x1e\xa6\x4a\x65\x75\xca\x5a\x34\xa9\xf2\x83\x00\xec\xde\x88\xb1\xf3\xd0\x27\xc4\x0d\x4a\x62\xa1\x9c\xc5\x6f\x9d\xf7\xb3\x0b\xe5\x4b\x63\xc9\xab\xd3\xac\x86\x72\x7e\x46\x53\xd4\x0e\x9e\xa1\x02\x66\x3c\xe7\xab\x53\x9a\x3b\x3d\x11\x77\x08\x14\x58\x27\x93\x2b\x21\x5a\x3b\x24\xf4\x13\x62\x8b\xcb\xbb\xf3\xd1\xf8\x8f\xf7\x97\x05\x15\xd2\x10\x4c\xd4\xd8\x3e\xdf\x2a\xa4\x89\x09\xa2\xb0\xc4\x81\xc3\xad\xfd\x85\x1b\x11\x85\xa6\x59\xd5\x4d\xed\x7d\x07\xc5\x6d\x07\x91\x18\xaf\x7c\xb5\x58\x1f\x16\xb3\x4d\xd0\xfe\x5d\x0a\xa4\xde\xdf\xa7\xa7\xca\x9a\xf5\xf2\xae\x99\x3d\xe6\x0a\xa8\x48\x79\x89\x61\xd6\xbe\xa7\x55\x31\x5a\x7e\x54\x04\x42\xfb\xe6\x5a\x73\xb8\x0c\xe5\x55\x89\x8a\x34\x89\x3a\x1f\x1e\x03\x7e\xf8\x9b\xb5\x62\x7b\x06\x12\x79\x18\x29\xee\xb7\xb3\xa7\xdd\xfd\x72\x7b\xd8\x6c\xd7\x7f\xfe\xe5\xce\x4f\x88\xd4\xa8\xc0\xf9\x79\x82\xb2\xae\x06\x66\x8c\x44\x11\xe9\x87\x06\x9f\x50\xc2\xcf\xe7\x4d\x4f\x37\xd1\x8d\xa0\x3c\x41\xbf\xf0\xc3\x11\xf2\xf3\x30\x09\x52\x54\x87\x58\x44\xcd\xac\xb5\xfa\x63\x9a\xff\xe3\x5c\x94\xe7\xe3\x63\x1b\x5a\x29\xe6\xfb\xc6\xed\x7c\xc2\x5a\xcd\x0d\x11\x1e\xe6\x52\x5d\xb2\xd3\xf2\x09\x47\x03\x75\x84\x9e\x30\x47\x73\x43\xdb\xbc\xaa\x3d\x0c\xa8\xbf\x6e\xed\xbd\xbe\xa7\x4d\x24\x79\x99\xee\xef\xaa\x24\x89\x91\x45\xfb\xf8\xf8\x68\x3b\x54\x6d\x02\xab\x12\x6e\x36\xe4\xa3\x69\x8e\x63\x53\x61\xa9\x90\x5f\x8e\x8a\x2b\x93\x0b\x8b\xe2\xbe\xc1\x83\x57\x90\xab\xe5\xfe\xbb\xd5\xe2\xb2\x5d\x75\x1b\x6f\x0e\xef\x1c\x0f\x18\x56\x53\x5e\x78\x75\x5f\x94\x8b\x87\x95\xbb\x00\x61\x49\x8d\x55\x7d\x16\xdd\xdf\x94\xef\x72\xe0\x45\x5a\x5f\xee\x0b\x6b\x3d\x3a\xd5\x29\x53\x42\x44\x8c\x8c\x2a\x81\xd7\xeb\x9c\x12\x42\xa2\x8e\x1e\x4e\xc1\xe1\x0e\x3a\xd8\x86\x1b\x00\x31\x12\xe0\x57\xc7\xd3\xa2\x89\xa7\x87\x3f\x59\x46\xc4\xd7\xfd\xca\x84\xb9\x7b\xd7\x96\x07\x44\x81\x67\x18\xf8\x87\x23\x7f\x83\x5f\x9d\x00\x8b\xe5\x3b\x4d\xc2\x72\x14\xc4\x44\x0d\xdc\x4c\xee\xb3\xf4\x74\x83\x48\xa1\x80\x18\xac\xf5\xbf\xea\xcb\x4f\xa3\xc0\x59\xb4\xfc\x41\x05\x89\x44\x54\x89\xcc\x2f\xf3\x5a\xf6\xb2\x75\xd5\x04\x1d\x7d\xa3\xae\xbe\x4d\xb0\x1d\xa2\xc3\x18\xdf\xd1\xfd\xc3\xdd\xe1\x69\x7d\xe7\x42\x66\xa5\x39\xc5\xc0\x17\x4d\xc0\x0e\x27\x28\x0f\xd0\xb6\x78\x95\x96\x02\xb8\x13\xdc\xea\x39\xfb\x34\x47\x4c\xbf\xff\x03\x66\x25\xa0\x18\x86\x4b\x58\xc1\x8b\x35\xea\xc5\x58\x9c\xb7\xab\x50\x0c\xbb\xd3\xa3\xc6\x19\x78\x60\x10\xbb\x03\x53\xce\xd1\xbf\xd7\xf0\x70\xf0\x39\x31\x61\x49\x7a\x84\x39\xd4\x1f\x00\xb9\x7d\xc8\xdd\xac\x41\x40\x8c\xd4\x96\xeb\xb1\x6f\xf8\x65\x7d\x46\x47\xdc\x6a\xcc\x83\x83\x30\x0c\xcc\xcb\xc9\xd3\xdc\x74\x36\x3e\xfb\x2a\x8a\x04\xa2\xd0\xb0\x05\x6c\x41\xc5\xed\x14\xc3\xb3\x44\x00\x61\x9f\xeb\x3b\xb9\xe4\x41\xa4\x8d\x86\x82\x8b\x6e\xad\x00\x80\x7a\xb4\xdf\x7d\xc7\x5d\x70\x0d\xb1\xc7\x8d\xb6\x0e\x7f\xb7\xa4\xac\xe1\xa9\x62\x16\x72\x97\x89\x1a\xb1\xac\xe1\x71\x02\x04\xdf\x90\xe5\x7e\xf1\xf4\x55\x93\x08\x28\xd1\x68\xf1\xfe\x9c\x3b\x7c\x49\x07\xdd\x1d\x9e\x92\x85\x26\x0b\x35\xe2\x08\x5f\x17\x98\x81\x49\x63\x09\xa0\xca\xf4\xf4\xe8\x1e\x21\x60\xca\x8f\x2c\x38\xcf\x8a\x95\xde\x46\xd1\x43\xa2\x34\xf2\x90\x15\x22\x48\x9e\xe0\x63\x14\xa0\x42\xa2\x8d\xf8\x44\x87\xeb\x7a\xf7\xdd\x5e\x08\x9c\x46\x98\x7a\xaf\x4f\x5c\x76\xc5\x72\xe0\x94\xe0\xba\xbe\xce\xdb\x38\xad\xf8\x32\x36\x72\x39\x15\x70\x66\x90\x4e\xa5\xed\x57\x5e\x51\xef\x81\x27\x1a\x39\x64\x03\x8e\xf0\xef\x1a\xa6\xc3\x39\x16\x5c\xe0\x62\xdc\xa9\x0d\x5a\x89\x11\x7d\xce\x1c\xe6\xdf\x94\xd4\x46\x9f\xd3\xc2\x16\x26\x72\x28\x79\x66\xda\x73\x2e\x42\x05\xe9\x4b\x64\xdf\xd6\xe9\x09\x51\x56\x57\x39\x64\x1b\x14\x81\x24\x1a\x2d\x2f\x66\x9b\x4d\xfb\x69\xea\x23\x18\x70\xb1\x7e\x7c\x7c\x7e\x5a\xed\xff\x42\xf2\x71\x5f\x4f\x9d\x80\xd4\xa1\xa1\x19\x9c\x05\xde\x22\x63\xfa\x35\xce\xde\x46\x3f\x56\xf9\x1e\x37\x75\xc0\xea\x0c\x9b\xf5\xaa\x7d\xe5\x94\x30\xdc\x74\xe9\xb0\x12\xf7\x3c\xcb\x04\xbf\x4d\x56\xb0\x9f\x03\x2f\x44\x2e\xce\xe1\x20\xfb\xe6\x8b\x6d\xfc\x0f\x20\x35\x46\xf1\x68\x4f\xd7\x4e\x6c\x76\x31\x1b\x4d\xb7\x9e\x69\xca\x8d\xcb\x20\xaf\x5e\x0f\xae\xd0\xd1\xbe\x17\x6e\x90\x30\xd1\xd6\x0b\xd4\x26\xfc\x5b\xd5\x70\x9c\x8d\x56\x06\xed\x25\x89\xb0\xa2\xbe\x3b\xa7\x18\x6c\xc8\xf1\x7f\xb8\x11\x9c\x23\x9e\x5b\xa7\xb9\x7a\x82\xcf\x7a\x87\x5a\x2a\x53\x35\x77\xed\x87\xd4\x33\x84\x9b\x3a\x7d\xec\xce\xe0\x53\x6e\x5a\x29\x45\xbd\x47\xf6\x88\x3b\x10\x50\xdf\x33\x36\x6a\xf8\x3c\xac\x47\x8c\x46\x1d\x50\x03\x75\xed\xd9\xf1\x4d\x6f\x69\x3a\x24\x09\x32\x0e\x17\x0f\xab\xf9\xf3\x9f\xbd\xa8\x43\x87\x49\x80\x95\x4f\xc8\xd2\xcf\xd4\x3d\x72\x3a\x0a\x18\xf6\x4d\x44\x13\x76\xdb\xc8\xf2\xa6\xa5\xe7\xf0\xa2\xa2\xc0\x78\x04\x56\xcd\xe6\xb3\xaa\xdc\xbd\xd9\xc2\x29\xe3\x23\xf5\x40\x1d\x51\xe6\x79\xad\x09\x08\x6a\x8a\xe4\x23\x20\xb3\x33\xda\x25\x3a\x4a\x22\xb4\x6b\x3f\x95\x86\x97\x53\x56\xe0\x8d\xce\x47\xa8\x87\xe2\x0b\xa6\xd4\x8b\x7c\xc5\x79\x21\xc6\x83\x18\x45\xc7\xd9\xb2\x49\x89\x49\x30\x3a\x4a\x89\xc6\x4e\xb9\xc3\xce\x8e\x9e\x2d\x4d\x99\x47\x1d\xec\xfb\x0c\xd9\xf8\xe3\x49\x68\x00\x70\x06\xa3\x30\x1d\x05\xea\x44\x6a\x84\x8e\x57\xaf\xbc\x84\x9e\x95\x38\xd1\x22\x00\x12\xd8\xd6\xdb\x65\xac\x55\xd2\x7f\x7c\xb5\xe0\xc2\xb5\x43\xfe\x59\x1c\x45\x0a\xd5\xfd\x39\xcb\x56\xb9\x2e\xe6\x97\x89\x28\x56\x4b\xcf\x93\xc1\xa0\x13\x76\x4b\x0a\xcf\x6d\xd5\x5a\x0a\x8d\xbf\x25\x3f\x1f\xd7\x7a\xc7\x8f\xa7\x0c\xf6\x97\x53\x9b\xa1\x69\xa9\x02\x5c\x59\xaa\x8c\xbf\xc3\x0e\xca\x8e\xb9\xab\x95\xaf\xb4\xb1\xc0\x46\x71\x8c\x7d\xc9\xc7\x4a\x29\x5a\xc5\x31\xca\xe2\x09\x43\x34\x5e\x94\xa0\x52\xcb\xa7\x77\x8b\xb6\x06\x3f\x0c\x0d\x6c\x08\xbd\x28\x7b\x8d\x3f\x0d\x71\x84\xc2\x44\xcd\x7d\x82\x0a\x75\x52\xfa\x47\x09\x20\xe4\xd3\x09\xd7\x1f\x0a\xdb\xb0\x3d\x94\x3c\x57\xc5\xf1\x6e\x77\x30\x26\x4d\xc7\x14\xbd\x67\xa6\x7b\x18\x1a\x94\x51\x66\x80\xcf\xba\xe4\x4d\xaa\xd7\x3d\x07\xa0\x43\xcc\xaf\x4c\x91\xbf\x57\x2d\x18\xea\x06\x4e\x96\x62\x1d\xb5\xef\xa6\xc6\x2e\xd1\xda\x0b\x3d\xc3\x4b\xac\xd3\x12\x7e\xa5\x99\xfa\xee\x1a\xef\x93\xb8\xc9\xf1\x3f\xee\x34\x51\xc4\xc2\x1e\xdb\x7d\x56\xa5\x0a\xae\x44\x95\x6e\xbc\xc9\x9a\x1a\x44\x09\x32\x07\xfe\x5a\x3f\x4f\x98\x25\x7f\x85\x21\x9a\x5c\xe4\xb5\xa6\x46\xae\xde\x12\x2e\x57\x0a\xfa\xdd\x70\xad\x39\x41\x2d\x30\xcc\x17\xd1\xe4\x7f\xeb\xe8\x38\xa3\xe7\x47\x73\xe9\xb5\xca\xf6\x08\xcb\xba\x71\x21\x38\x9e\x7a\x5e\x14\xc4\x23\x19\x52\xa7\x8b\xfa\x1f\xc9\x90\xba\xd3\x29\x0f\xfd\xe2\xaa\x26\x84\x38\x04\x07\x13\x75\x76\x64\x5c\xea\xf9\x41\x22\xac\xf2\xf6\x82\x97\xea\x4a\x41\x9a\x7a\x01\x4d\x10\x51\xb7\x5d\xde\x2f\xb7\xdb\xd9\x83\xb5\x93\xdf\xce\xf6\x4b\x77\x92\x80\x31\xd3\x87\x6e\x16\x4f\xe3\xd0\x6d\x2e\xc3\xb7\x03\xc2\x08\x94\x93\x4d\xb6\x70\x74\xeb\xcb\x3c\x35\xff\xd4\x0b\x19\x13\xf1\x90\x47\x66\xb6\xbf\xae\xb6\x42\xbd\x10\x74\xd8\xb5\xcc\x7a\x5a\x8d\xee\xb8\xe6\xd8\x19\xb5\x4a\x58\xff\x70\xf7\x8f\x7a\x91\x6f\xd8\x9f\x2f\x50\xdf\xc3\x48\xcb\xdb\x0d\x21\x5c\x3b\xa8\xfd\xa6\x2c\xde\x53\x35\x5a\xac\xa8\x17\xd3\x08\xcd\xf4\xb2\x1c\xad\x90\x9a\x2c\x4f\x85\xc1\x64\x58\x4e\xbd\x98\xc7\x89\x4d\xd7\x9e\xf3\x53\x59\x34\x61\x01\xa8\x7f\x9c\xa1\xbc\xf4\xca\x5e\xd4\x23\x01\x60\x77\x33\x95\x45\xd8\x5b\x74\xa9\x47\x35\xf5\x8c\x68\x63\xcd\xb3\xaa\x87\x1c\xa3\x1e\xa3\xb1\x61\x5c\x18\x88\xd1\x2e\xe7\xa7\xea\xb5\xa8\x57\xed\x4d\x66\x10\x60\x15\xe1\xc8\x3f\x77\x4d\x8a\xec\x68\xca\xd4\x6b\xfe\xc7\x91\x61\xdf\x3c\x63\xe7\x63\xaf\xfe\x42\xbd\x44\x2a\xc7\x0f\x70\xfc\x94\x6f\x65\x71\x3e\x55\x3f\xe0\x32\x1b\x4f\x58\xa2\x3c\x8c\xdc\x9f\xe0\x63\xc3\x2f\x65\x91\x65\xa3\xe9\xe2\xb1\x36\x7e\x27\x3d\xaa\xcb\x4a\x7d\x8e\x4e\xc3\xb5\xc2\x80\xe7\x71\xf6\xe7\xea\xf1\xf9\xf1\x40\xa2\xc3\x7c\xb5\x3f\xec\x56\xdf\x9e\x96\x77\x87\xd5\xd3\x7e\xf9\x6d\xb9\x3d\xfc\x9c\x3d\x3c\xb7\x4f\x9f\x12\xa6\x52\xb8\xdb\x2c\x17\xab\xd9\xc3\x6a\xb7\x6f\xe2\xc6\x1f\xcb\xc3\xfe\xd7\xda\x8d\x81\x38\x31\x8a\x2c\x5c\xc3\xb7\x26\x59\x2b\xeb\x94\x67\xe6\xce\x2f\x20\xcd\xbe\x24\xd0\x51\xdf\xf3\x04\x58\xba\xce\x43\xfa\xde\x9a\x1f\x51\xdf\xa3\x8a\x28\xb7\x61\x15\x9f\x43\x8e\x33\xf5\x3d\xed\x59\x8e\x8b\xc1\x2d\x58\xa9\x98\xde\x1e\x49\x7d\x3f\xf4\xf0\x59\x7f\x3c\x67\xbc\x8b\x79\xa8\xef\x53\xdf\x34\x68\xed\xed\x6c\xff\x0e\x09\xd6\xf4\xff\x71\x86\xf3\x70\xb9\xa1\xbe\xaf\x03\xcf\xe8\x52\xef\x78\x2e\xeb\xce\x5a\x8d\xfa\x81\x4f\x85\x75\xe0\x38\xbb\xdd\x91\xfa\x01\x8f\x11\xe5\xe6\xac\x0c\x0d\xa9\x73\x74\xd6\x80\x53\x82\x48\x18\xfe\x06\xa6\x96\xd1\x7e\x5c\x71\xe6\xd0\xaf\xd6\x9b\xd0\x73\xc7\x42\x12\x60\x2b\xe6\x64\x00\x3a\x43\x2e\x2d\xf5\xa3\xd0\x70\x59\x9a\xcd\x6f\xd4\x2a\xa6\x7e\x14\x07\x8e\x85\xfc\x3d\x55\x6a\x64\xed\x4b\xfd\x88\x07\xce\x99\x20\xcd\x5f\xd6\x39\x74\xed\x14\xea\x47\xda\x38\xa3\x1e\x6c\x2d\xac\x5f\x6b\x72\x63\x62\xce\xb0\x3a\xb3\x3b\x97\xef\xe9\x3b\xcf\xb6\x3c\x97\xaf\x7b\xd4\x2d\xe9\xee\x40\xac\x98\xd7\xae\x8d\x06\x7d\x64\x56\x2d\x5b\x29\x6c\x67\x31\xd6\x1e\x2e\x91\xeb\x39\xb6\x14\xb6\x5f\x24\xc3\xd4\x27\x49\x84\x0c\x24\x14\xf6\xf1\xdd\x29\xa8\x6f\x64\x4b\xf6\x0f\x4f\x56\x0a\xeb\x69\xf6\xb8\x6c\x8f\x06\x84\xd8\x5e\xd4\x4a\xa2\xf6\xd2\x75\x1d\x89\xfa\x34\xe4\x56\xfa\x44\x37\x09\xda\x86\x5f\xae\x5d\xb6\xa9\x4f\x63\x1f\xd5\x5b\xd0\x91\x30\x57\x77\x90\xa5\xef\xb6\xf0\x7a\x0d\x16\xea\xaf\xe2\x3e\xe5\x80\xda\xd2\x77\xfb\xc5\xe2\xb0\x7a\x58\xff\x3a\xc4\xed\x05\x8a\x00\x1b\xb6\xce\x29\xab\x8d\xc3\x6f\x20\xdd\xa8\x4f\x15\x25\xba\x9d\x5c\x63\xd3\xb3\xb1\x66\x94\x37\x3f\xa2\x91\x02\xa8\xd3\x2c\xbb\x2f\x8b\xa3\x79\x03\xec\x41\x46\x0d\xc2\x42\x16\xa6\xce\x31\x50\x3f\xa7\x3e\x13\x31\x76\x2d\x72\xf8\xd8\x97\xc0\xab\x73\x39\x7e\x57\x13\x1d\x24\xce\xa9\x71\x0f\xfc\x38\x01\xb0\xa3\x3e\x0f\x63\xec\xc3\xd9\xa6\x50\x56\x54\x50\x8f\x4b\x87\xd4\xe7\x89\x29\x7a\xcb\xf2\x52\xd5\xae\xa4\xde\xfc\x99\x63\x26\xb4\x10\x9f\xfd\x32\x3e\xf5\x45\x20\x02\x70\x7a\x7a\x00\x98\xd0\x96\xf7\x00\xaa\xc9\x47\xd7\xb7\xa6\x43\x28\x1f\x5b\xab\x50\xd5\xe9\x91\xd7\x70\xcd\x54\xa2\xbe\x64\x46\x7d\xac\x2b\xf5\xef\x6a\x2e\xdf\x0c\x2b\xdf\x8d\x91\xd2\xb7\xb0\x9f\xe5\x76\x11\x78\x83\xd8\xd0\x8e\x51\x81\x50\xae\x9d\x64\x8b\x81\xf3\x0b\xf6\x7c\xfa\xb1\x28\xf5\x95\x00\xf7\xca\x3c\x89\x72\xad\x31\x45\x18\x33\x70\xa8\x0f\x84\x60\x3a\x6a\xa6\xb1\xb3\x98\xed\xe4\x7a\x9c\xca\xad\x05\x95\xb9\x04\x8b\xfa\xc0\x3c\xe9\x3a\xea\x3d\xa0\x02\xf5\x41\x1a\xa2\xe7\x4b\x56\x08\x90\xbd\xd7\x58\x87\x11\xf7\xad\x08\xbf\xd1\x84\x9b\x10\x0b\xa4\xbe\x86\x18\x9b\x2d\xa7\xa2\x18\x74\x22\xa9\xaf\xb5\x76\xb6\xd7\x33\x55\x59\xcb\xf9\x29\xaa\x1a\x0d\xbc\xd0\x43\xb9\xdf\x63\xfa\x89\x0c\x98\x2d\x17\x22\xad\x6f\xfa\xd5\xb5\x9f\x8a\x23\x8b\x2b\xfd\x76\xc6\x45\xa8\x8b\x08\x02\x2f\xf2\x21\xea\x7b\xf1\x5e\x3d\x6f\x81\x17\x29\xe6\x98\x74\x2f\xa8\xd9\x5c\x7c\x5e\x56\xcd\x96\xd3\xec\xea\xbd\x46\x00\x0d\x3c\x1a\x60\x99\xa6\x84\xaa\xc8\x50\x97\x32\xcb\x20\x7f\x19\xa0\x79\x69\xe0\x29\x85\x7b\xcf\xdb\x3c\x6d\xaf\xc3\x27\xbe\xb3\x44\x6a\x92\xb8\x5e\xd9\x96\x06\x3e\xf5\xd0\x34\xe7\xc8\x3f\xe7\x50\x1b\x0c\xd1\x5d\x0b\xb5\xa0\x81\xaf\x14\xd6\xe4\xbe\x35\xb1\x5f\x6e\xc4\x30\xed\xa1\xc0\x8b\x11\xa8\xf5\x9c\xd7\xa8\x95\xd2\x5b\x30\x6e\x47\xf2\x43\xb9\xf6\xdb\x13\x1b\xd0\x30\x30\x36\xbb\x47\x14\x7d\x3b\xa4\xb2\x68\xbf\x58\x2a\xec\x82\x2d\xad\xff\x5a\x07\xd2\xbd\x95\x73\xda\x0f\x86\x31\xc7\x6e\x83\x15\xd8\xb9\x2d\xc1\x4e\x83\x88\xf8\x88\x76\xfe\x5e\xfc\xe3\x3c\x3f\x97\xe3\x84\x97\x06\x91\x36\xec\x1b\x27\x67\xe3\x5e\xae\x6a\xf0\x08\xc4\x22\xc2\xda\xcb\x7c\xfd\xe7\xaa\xf7\x64\x07\xb1\x50\xcc\xeb\x2b\x61\xf6\x08\xd9\x83\xfb\x49\x9a\xa5\xdb\x31\x5b\xee\x6e\x8a\x3e\xd1\x80\xfa\x3e\x6a\xb9\xfe\x28\x4a\xe0\xbb\x57\x0b\x43\xff\x22\xdd\x68\x3f\x47\x10\x47\xd0\x92\x79\x73\xf8\xe8\xc9\x5e\xd2\x80\x42\x48\x13\x0b\xaf\x86\xba\x7b\xc9\x27\x76\xc8\x20\x89\x20\x66\x53\x76\xb5\x13\x8e\x07\x34\x48\x48\x84\x2d\x83\xff\x2d\xd2\x7c\xff\x0a\xdf\x9b\x79\x9b\x3c\x2b\x35\xb2\x10\x15\xd4\x6b\x63\x81\x31\x86\xce\x37\x63\x22\x42\x5d\x63\x62\x96\x2b\x04\x95\x5f\x7a\xc6\x51\x34\x48\x92\x10\x65\xaa\x45\x20\xfa\x80\xe2\xe6\x80\xc2\xc8\x3d\x03\xec\xa5\xde\xf1\x4b\xd5\x1e\xb2\xb1\xf1\x01\x41\x62\x28\xf6\x73\x0b\x5d\xe7\x3e\x01\x32\x20\x3d\xd5\x89\x5f\xbc\x2c\xd3\xe2\x4a\xd7\xea\xc6\x63\x9f\xe8\x44\x24\x3d\xf5\x86\x45\x61\xa1\x98\xa3\x9f\xcb\x45\x12\x9b\xea\x46\x9e\x5f\x32\x3e\x88\xfe\x03\xae\x25\xf3\x7a\x0d\x8e\x16\xcd\x3e\xd6\x3b\xa4\x81\xf4\x49\x02\x46\xeb\x41\x14\x69\x9f\xd6\x42\x03\xc9\x43\xe3\x0e\xb9\x7e\xda\xcf\x9e\x66\x18\xdb\xb8\x63\xca\xe7\x48\x0c\x3a\xbc\x18\x47\x06\x03\xe3\x70\x7b\x76\x00\xc4\x8f\x7d\x94\xaa\xb3\xb6\xf0\x4d\x9e\x8d\xdc\xa7\x41\x1b\x99\x06\x9a\x1b\xb7\x4e\x2b\xc1\x06\xfc\x38\x58\xce\x42\x2f\x92\x60\x75\xa5\xa7\xac\xde\x69\xe8\x91\x04\x3b\xc1\x9d\x7a\xeb\x91\x0f\xf5\xe0\x27\xdf\xef\xd0\x23\x32\xb0\x6b\xe2\x1d\xaf\x79\xf8\xf7\xee\x4f\xe8\x09\x03\x6b\x6e\x92\xcb\xe1\xf5\x0c\x9f\xed\xd0\xe7\x0c\xeb\x10\x9a\x1f\x41\x35\x11\xcd\x23\xaf\xaa\x7d\xb1\x52\xe3\x1f\x10\x5a\x50\xec\xa6\x2c\xfa\xf8\x2b\x1a\x86\x4a\xe2\x7b\x67\xab\xf5\xc3\xf6\x06\x0d\x23\x12\x21\x5e\xf3\x3b\x1a\xd4\xba\x3f\xb2\x18\xc3\xd9\x96\xbb\xef\x6a\x31\xa8\xfb\x3c\x5c\xc1\xc2\xd8\xaa\x73\xbf\x40\xfd\xdd\xef\xe3\x34\x69\x18\x47\x09\xb6\xf9\x0e\x3d\xf3\x86\x29\xca\x3b\x0d\x49\xc0\x8c\x47\xb2\xc9\x60\x97\x25\x77\xe7\x20\x31\x37\x05\x14\xae\xe1\xab\xb0\x3a\x24\xb1\x32\x2a\xe1\xfc\x08\x6b\xa5\xda\xcf\xf3\x18\xa3\xba\xbb\xce\x5a\xe9\x0b\xc9\xb9\x66\x3c\x60\x50\xd5\x7a\xb5\x5c\x07\xb2\x76\x24\x8d\x14\xb6\x43\xcc\xe2\x7b\x6d\xa6\xe7\x86\x25\x12\x05\xfd\x16\xf3\xd5\x9f\x5f\xd4\xa6\x98\x1b\x2e\x24\x4a\x2b\xef\x5e\xd3\x1c\x3a\x43\xe0\x5b\xdd\xa3\x09\x5e\x67\xd7\x69\xa1\x21\x8b\x7c\x66\x33\xf8\x9f\x50\x56\x57\x5c\x15\x1a\x32\xe6\x01\x6b\x03\x44\xa8\xfa\x05\x20\x5b\xe7\x6b\x06\x05\x60\xa4\x59\xea\x73\x99\x6f\x0a\xdc\xfd\xdf\xae\x88\xc1\xed\x68\xa3\x3e\xd9\xbc\xd4\x08\x3a\x5a\x6b\x2b\x6c\xeb\x5e\xd8\x90\xb1\x18\xf9\x6a\x28\xef\x56\x21\x65\x68\x97\xfe\x1b\x0e\x0a\x8c\x41\x38\x2a\x2a\xb9\xb1\x09\x31\xed\x69\x9e\x3f\x9f\x5e\x50\x5e\xd1\x1d\x11\xc4\xb3\x8f\xde\xd2\x84\x3a\xcd\xd5\xff\x4c\xe1\x63\x74\x0f\x98\x4e\xb0\xde\x53\xb7\xda\x25\x2f\xa9\x9c\x9d\xeb\x57\x63\x16\x34\xbc\xaf\x89\x6f\xd9\xc5\x36\x25\x7e\xe4\x0a\xbe\x6a\x32\xd3\x30\x09\x3c\x04\x57\xbc\xa7\xf0\x11\x07\xee\xea\x92\x24\xf6\xa5\x83\xfb\x2d\xdd\x02\x3c\xfd\xd4\x25\x4a\x24\x9d\xe4\x70\xfb\xec\x0d\x9c\x12\xed\x50\xae\x02\x2b\x1f\x7f\x2c\xde\x01\xf1\xf9\x46\x7a\x75\x38\x4c\xc4\x04\xef\xeb\xe3\xea\xe9\x70\xbf\x5d\x2e\xff\xb9\x3c\x38\x05\x14\x77\x81\x42\x32\xe7\x83\xbf\xe9\x9c\xb3\x2b\xeb\x44\x31\xd9\x15\xa0\xa1\x14\x92\xc6\x3d\x0f\x8c\xd9\xe9\x04\xa6\x13\x29\x5f\xdd\x89\x15\x89\x30\x40\xda\x9d\xb2\xb4\x76\xe5\xcb\xe9\xd3\x29\xa1\x05\x1d\xd8\x31\xf4\xf4\x53\x69\x08\xa1\x1f\x0b\xc7\x2e\x7c\x69\x36\xc2\x26\xef\x7b\x80\x17\x2e\x2f\x5b\x38\x9d\x4d\x6c\x3b\xd2\x38\xa5\x21\x24\xc2\x95\x25\x3a\xe4\x70\x7b\x4c\x62\x75\x60\xcb\x55\x3a\xf8\x3b\x37\xce\x44\x08\x21\x1e\xee\x2f\xa1\x26\x7e\x60\x82\x97\x63\x9a\x1b\x2d\xbb\xe1\xfd\xd3\xd2\x78\x6b\xed\x56\x8f\xfd\x85\x54\x03\x05\xdd\x3a\x17\xfc\x02\x78\xeb\x97\xf4\x22\x2f\xf1\x13\xab\xdd\x62\x5f\x90\xaf\x56\xb8\xc8\x83\x08\x43\xf7\x0c\x74\xcd\xe8\xf0\x0a\x22\x1f\xb4\xb1\x0e\x30\x2b\xe8\x9c\xe7\x6f\x58\x83\xb3\x87\x03\xcf\xb0\xc3\xb3\xe2\x45\x17\x59\x5a\x0c\x57\x81\x28\x08\x19\xca\x11\x98\xfe\xc6\xe3\xa2\xfd\x58\xcc\xd1\x7d\x6e\xf6\xf4\x78\x7f\xae\xcf\x25\x38\x94\x92\x3b\x2e\x79\x44\x5a\xf6\xe7\xf8\x59\x8d\x02\x45\x22\x03\xed\x45\x76\xd5\x04\xa0\xd9\x0e\x0c\x7d\xaa\x50\x9c\xfa\xb5\x04\xb8\x7b\x70\xa7\x0f\xb9\xb1\x01\x45\x74\xa8\xa3\x3d\xcf\x72\x85\xb3\x68\x5a\x05\xdd\xb2\xeb\x3e\x23\x8d\xe7\x7d\x13\x0e\x3e\x76\x79\x46\x14\x2a\x23\x98\xf0\xbf\x80\x7a\x6c\xe7\xba\x38\xf2\x3a\x95\x8b\x22\xcb\x40\xd6\xad\xd7\x08\x8d\x42\xd0\x88\xa9\x7b\xeb\x3e\x1b\x11\xd3\xf3\x2d\x8b\x7c\x00\x51\xa3\x51\xc4\x7d\xe1\x77\x7c\x1e\x54\x91\xea\x2c\xb5\xfe\x56\x43\x9e\x46\x31\x97\x91\x6a\x5d\x7a\x51\xea\xe9\x39\xcd\xeb\x3f\x46\x1f\x1a\xde\xb2\x98\x2b\x23\x71\x59\xf3\x17\x70\x26\xab\x34\x22\x01\xb1\x24\x8b\xba\xe2\xf7\x67\xf9\x56\x0d\xae\x97\x84\x82\xda\x7c\x63\xb3\x5e\x3f\x18\xab\x8c\x80\xb6\x87\xe3\x48\x76\xd8\x41\xd7\x82\xeb\x0e\x6a\xe7\x6e\x9a\x96\xa0\x5a\xf1\x60\x1a\x11\x1d\x05\xf6\x85\xb3\xfd\x78\x0c\xc2\x86\x37\x99\xfa\x51\xdc\x19\x3e\x99\x2c\xda\x18\x2f\x7c\x5e\x21\xd1\x86\xcb\x44\xc4\x7c\xbf\xd3\x7a\xae\xf6\x06\xd9\x02\xe7\xe3\xc1\x9f\x2e\xb7\x47\x2c\x0c\xd1\xb8\x6b\x53\xbd\x61\x4d\xc3\x5d\x28\xa3\x1c\x03\x3d\x83\xf9\x37\x8e\xfe\x87\xd9\xc2\x49\xdc\xd2\x88\x09\x8d\x17\x29\xd0\xfc\xcc\x2c\x46\xc3\x89\x67\x4a\x60\x3b\xf8\xae\xe4\x2f\x45\xfe\x63\x2a\x48\xbc\xf1\x23\x94\xc4\x87\xfc\x74\x6e\x26\xf7\xeb\xc8\x32\x42\x6b\x78\x94\x52\xa9\xe1\x50\x17\xfd\x96\x3b\x8d\x38\x33\x16\x95\x25\xfc\x2f\xc8\x7a\x01\xa5\x55\x76\x9d\x16\x1e\xa6\x91\x08\x62\xcb\x1d\x45\x79\x5e\x63\x37\xf9\xc8\x6f\xec\x46\x91\x50\xc4\x4c\x5e\x89\x79\x43\x51\x5e\x06\x36\x71\x37\xae\x58\x32\x82\x75\xec\xf9\xd9\xc5\xfe\x91\xd4\x1e\x7e\xaf\x71\x7a\x30\x88\x44\x67\x48\xe2\xc6\x00\x35\x5e\x14\x4d\x0e\xd0\xac\x90\x98\x06\x9b\xf0\x62\x78\x7e\x80\x50\xf4\x20\x8c\x0f\x85\x7c\x7b\x3e\x99\x80\xb3\x03\xce\x8e\xa6\x1c\x74\x82\x55\xbf\x13\x2f\x2b\x98\x17\x45\x36\xc8\x0b\x22\xcd\x8d\xb0\xf9\xb7\xf4\x1d\x66\xf9\x2c\x7f\x81\x6c\xb1\x9b\x0e\xc5\x23\xad\x0c\x86\xab\x82\xfa\x81\x57\xb5\xb1\x28\xda\x42\xe5\xfc\x52\x6d\x53\xd3\x72\x99\x68\xec\xc5\xd4\xa4\x9b\x75\xe1\x48\xab\x34\xf6\x98\x36\x80\xba\x22\xcb\x7a\x32\xd8\x34\xf6\x23\x95\x38\x51\xd6\x6b\xcd\x6a\x1a\xfb\xcc\xa8\x03\x1d\xd6\xc7\x1c\xaa\x2e\x2e\xb4\x87\x03\x96\x68\xd5\x73\x3d\x30\x02\x0b\xa3\x73\x04\xc2\xb8\xaf\xbc\x18\xd3\x07\x00\x65\xf0\xca\xc6\x19\x66\xf0\x6b\xe3\x40\xfb\x58\xf2\x32\xb8\xa8\xd9\x4b\x6b\x68\x40\xe3\x30\xa2\x82\x75\x01\x88\xf9\x18\x8a\xbc\x22\xd6\xc5\x0a\x7f\x0f\x1e\x2d\xe6\x3e\x4a\x05\x76\x6a\xe6\x45\xbf\xce\x1e\x87\x9c\xa1\x62\xe9\x66\xf1\x7d\x96\xb9\xcd\x33\x8e\x78\x84\x7a\x80\xe8\x83\x6f\xa8\x9b\x5f\x58\x68\x5e\x75\x98\x51\x37\xbc\x8b\x09\xe2\x88\x53\x65\xd4\x40\xcf\x15\xec\xa0\xdd\x1a\xe3\x98\x1a\x82\xed\x3f\xf6\xf3\x3f\x6e\x3b\x2b\xd2\x38\xe6\x14\xa5\x19\x5f\x79\x65\xbc\x03\xdc\x09\x08\xe1\xce\xb8\xf0\x31\xcd\xeb\xbb\xf4\xa5\xbf\x93\x4f\xf5\xec\x69\x4c\x68\x4c\x93\x5e\x51\xaf\x2b\x3e\x5d\x53\x9d\x86\x97\x41\xc3\x84\xdb\x52\xdb\x8f\xb3\x2a\xaa\x7d\x61\x44\xd3\xdd\xd5\x50\xb0\xf2\x31\xe7\xaa\x2e\x8e\x03\x1a\x22\x8d\x59\x24\x50\xd8\xe7\xf0\xca\xab\x99\x51\xe3\x48\xb3\xb6\xb1\x4d\x63\xc6\x35\x46\x6e\xaa\x80\x6a\x99\xd7\xe5\xc5\x28\x3b\x0e\xaf\x3d\x89\x7d\x5c\xec\x1f\x8a\x97\xed\x00\xa6\xe7\x8e\x4b\x1f\x09\xdd\xf3\xf3\xa5\x8f\x8b\x9d\xde\xfc\x62\xe1\x1b\x7d\xa4\x17\xa8\x0f\x3a\x2d\xab\x1a\xbf\xec\x8f\x6b\x0d\x58\x1a\x0b\xae\x70\xf3\x3a\x98\x30\x19\x7f\x59\x79\x59\x8d\xbf\x5f\x40\x80\x88\x00\x38\x5a\x87\xb1\xca\x18\xb5\x4d\x8b\x15\xd2\x58\x06\xa1\xe7\xd4\xff\x20\x1d\xbf\x79\x32\x96\xdc\x61\xf0\x31\x87\x46\x99\x9a\xd1\x98\x24\x46\x75\x86\xd5\x62\xdd\x57\x93\x70\xdd\x91\x58\x69\x8d\x1a\x8b\xc7\x22\x6f\x82\x8f\x95\xda\x17\xa8\x13\x8f\xe9\xf4\xf0\x54\xe0\x79\x3e\x77\x3b\x1d\xc6\x39\xf7\x48\x7c\x71\xe0\x59\x1a\x43\x44\x42\xee\xbc\xaa\xde\x8b\xf4\x9a\x14\x77\x63\xa6\x81\x12\xe4\xde\xb6\xa4\x3a\x03\xc9\xaf\xbe\x28\x60\x12\x2f\x34\xba\x8c\x25\x54\xf2\x0c\x53\xb5\x13\xe2\x09\x43\xf7\x3d\xa0\xca\x94\xbd\x4a\xe2\x47\xa1\x31\xe9\xc9\xf8\xa0\xc1\x4d\x7c\xe2\x21\xac\x68\x87\xb6\x67\xa8\x72\x02\x6a\x5b\x9c\x6b\x28\x77\xdb\x9f\x57\x28\x87\xb1\xc9\x3a\x25\xbe\x54\xb8\x34\x95\xa0\xce\x12\xbe\xf3\x5a\xbe\x2e\x8a\x22\x53\xc5\xc7\xad\x1f\x11\x84\x22\xee\x56\xac\xb6\x04\xd2\xdf\x0a\x48\x60\x85\x49\x78\x55\x41\x59\x2f\xff\x75\xe5\xee\x4e\x49\x40\xfb\xce\x02\x07\x61\x72\x9e\x2f\xe7\x9c\x04\x60\x4a\x20\xa9\x2c\x6c\x43\xaa\x03\x00\x51\x12\x68\xe6\x05\xd6\xe5\x68\xc1\x4f\x5b\x63\x62\xeb\x8e\x86\xd4\x37\x3b\xe3\x94\xed\xd0\xe8\x7b\x22\x2f\x36\xf8\x7e\x83\xb7\xae\x8b\xb7\xfc\xb0\x5a\xac\x5d\x32\x4a\x62\x11\xa1\x9b\x08\x3f\xd7\xc5\x0e\xba\xdb\x84\xf6\x6f\x4e\x99\xe0\x0e\x9a\x28\xdb\x79\x0f\xba\x11\x8c\x06\xd6\x08\xe3\x20\xa1\x99\xba\x6c\x8a\x16\x4d\x09\x0d\x68\x90\x74\xc6\x79\x86\xbb\xda\x7b\x62\x98\x1b\x97\x10\xcc\x19\x5a\x8a\xe8\x23\x6e\x66\xe3\xb3\x29\xa3\x81\x7c\xae\x5c\xeb\x18\x3e\x7e\x41\x3a\xbd\x28\x12\xaa\xb5\xb6\xb5\x5d\x34\x42\x1f\x4c\x15\x92\xe7\x27\x37\x75\xc2\x12\x86\xea\x07\x22\x9d\x46\x09\x0f\x12\x30\x92\x84\x06\xf0\xa1\x16\xdf\xef\xdd\xf4\x24\xc0\xa5\x83\xf9\x9f\x2f\xeb\xd3\x20\x11\x25\x89\xf6\x5a\xad\xf5\xfe\x86\x4d\xb8\x27\x10\xde\xf7\x6e\x04\x39\xfa\x0f\x05\xa7\x86\xb5\xad\x4b\x68\xc2\xe3\x05\x2f\xcb\xa2\x1e\xbf\x74\x9c\x45\xa1\x65\xe0\xb5\x55\x15\x22\x3c\x5f\xda\x5b\xf5\x54\xd4\x5b\xc0\xc7\x1c\xd7\x98\xbe\x35\x31\x25\x22\x4e\x30\x52\x5b\x66\x97\xcf\x72\xf7\x5a\xa6\xc7\xd3\x3d\x2f\x8f\xe3\xf4\x8d\x08\x15\x21\x94\xfc\x61\xbd\x7e\x5c\xcd\xda\x67\x49\x28\xa3\xc5\x7c\xe4\x6f\x23\x52\xce\xa8\x1e\x74\xe3\x9d\x90\xa1\x11\xd6\x68\xad\x78\x8c\xf0\xc4\x95\x51\x4e\xf7\x09\xe5\x79\x46\x9b\xe5\xac\xd2\xda\x0a\x52\x0f\xf6\x24\xa2\x7c\xa2\xfa\x7d\x14\x13\x8b\x14\x65\xda\x42\x1d\x88\x0a\x89\x1a\xf9\x1c\xba\xee\x3b\x01\x4f\x39\xa4\xfb\x13\x7c\xd6\x13\xad\x01\x02\x7e\x84\x39\x60\x93\x11\xe1\xf1\x56\x89\x86\x12\x1d\x1a\xaf\xf9\xac\xf8\x58\x14\xc7\x53\x51\xdd\xfa\x21\x9a\x18\xa7\xec\x9e\x4a\xa8\x9f\x7c\xe7\xd5\xeb\xc1\x8e\x6b\xcf\x28\x15\x22\xe6\x5d\x5c\x90\xb5\x15\xe9\xcd\xcc\xe5\x7a\x08\xd0\x69\xb6\xce\xd9\xf6\x07\x9a\x68\x6d\x0f\xfe\xc1\xf3\xfe\x4f\x6a\xc8\x78\x32\xd7\x1e\xd9\x72\xad\xb3\xe9\x06\x27\xf5\xa9\xa1\x3d\xe4\x45\x79\xe4\xd9\xb6\x28\x8e\x8f\x8e\x90\x4b\xb1\x95\xdc\x2d\xb4\x26\xf1\xfa\xb2\x97\x46\x83\x80\xcb\x16\x05\x70\x5a\xeb\xfe\x4b\x42\x03\x99\xe0\x4b\x52\x35\xab\xe2\x39\x43\xc5\xd5\x61\x25\x2e\x9a\x56\x90\xb7\x9f\x0f\x83\x18\x15\xd1\xd2\x6a\x65\xb6\xd2\x2b\x82\x36\xa5\x61\xc4\x10\x00\x85\x0e\x18\x6b\xad\xd1\x9a\x10\xe4\xb9\x86\x47\xfe\xd9\x55\x05\x68\x18\x09\xec\x70\xce\x9f\xe6\xbf\x15\xd5\xa3\x34\x14\x01\x36\xf4\x0f\xdf\xb9\x7c\x4d\xcb\xe2\xed\x3c\xf8\x61\x91\xf4\x31\xda\xdf\xbd\xa6\x90\xa9\xc5\xb9\x1c\xc0\x01\x68\x4c\x22\x6c\x57\xfc\xf3\x92\x65\x69\xf7\x47\xe3\x85\x92\xf6\xcc\x78\xa7\xe7\x94\xf8\x31\x6f\xed\x9d\xee\x78\x0d\x9d\x74\x31\xa5\x24\xf2\x63\xdd\x22\xeb\xfa\xc6\xa4\x53\x84\x0c\x4a\x09\x37\x37\xa8\x55\x24\x99\x2c\xe0\xd3\x26\xb3\x46\x1c\xd4\xa9\xc8\xab\xa2\xec\x17\xf1\x28\x65\xb1\x74\x25\xc3\x55\x9e\xd6\xdc\x19\x77\x3d\x57\x69\xfe\xe2\x64\xa9\x47\x9d\x09\x4a\x13\xf0\x8d\x3e\xfc\xae\x2e\x4e\xed\x5f\x79\x88\xf8\x82\xe5\x5f\xdf\x07\x53\x46\x39\x47\x5a\x04\x36\xab\x0e\x90\xab\x6f\x66\x61\x75\xc7\x19\xf3\xb1\x99\xf5\x0d\xea\x45\x5a\x5f\x76\x43\x4c\x15\x65\xdc\x47\x51\x30\x23\xf9\xea\x2a\xbf\x5f\xa7\xe8\x34\xf1\x13\x61\xa6\xe6\x7f\xcf\xd5\x2d\x20\x21\x4d\x02\x1d\x34\xa3\x36\x70\x14\x69\x93\xf5\xb4\x4e\x86\x94\x26\x89\x42\xf1\xb4\xfd\x51\x46\x7f\xe3\xa9\x4a\x94\x34\xc6\x98\x90\x2b\xe3\x34\x8e\x2a\x3c\x03\x83\x41\x9c\x37\x23\xd7\x88\x41\xb2\x2d\x99\x2f\x78\xcf\x55\xe4\x3f\x5c\x19\x78\x6c\x1c\x01\xd0\x41\x79\x7a\x2a\x38\xd3\xbe\x2d\x2f\x1a\x8c\xc2\xdf\x11\x56\xa6\x94\x8b\x50\x3a\x85\x9a\x7e\x81\x83\x72\xcd\xb0\x76\xee\x5c\xa1\xaa\x8a\xbf\x8c\x4d\x0d\xec\x0c\x4d\xe6\x57\x54\x78\x31\x96\x71\x8e\xfc\xb3\xbd\x9b\xf6\x90\x54\x12\x21\x6f\x0e\x93\x67\x55\x9d\xd7\x27\x63\x61\xe6\xf6\x0b\xaa\x02\x19\xb5\xda\x43\x06\x6a\xd2\x1d\x23\x01\xb5\x0c\x5a\xdc\x01\xad\x4b\x93\xfe\x9a\xe6\xd3\xfd\x70\x95\x18\x7b\x1b\x93\xc8\x18\x85\xdc\xe1\x08\xf0\x12\xb0\xa0\x9c\x6f\xfc\x08\x96\xc9\x34\x3e\xeb\x8d\xfb\xf7\xf5\x97\x83\x32\x6d\x55\x0d\x4d\xe8\x8c\xe0\xd9\x0c\x14\xfe\x8e\x26\xd9\xd8\xf0\x4b\xf7\x30\x81\xe2\x98\xa7\xd6\x9f\x0f\xc5\xcb\xe8\x12\xb5\x1f\xa0\x8d\xdc\x55\x95\x91\xea\xd0\xe8\xaf\xb4\x3b\xbc\x51\xc8\xdb\x35\x5b\x67\xfa\x09\xd9\xc4\xfe\x4a\x35\x35\xb7\x45\x40\x8d\x22\x22\xc0\x8f\x87\xa0\x3d\x61\x02\x58\xc7\x29\xb4\xce\xd2\x1c\xb0\x96\x74\x63\x8f\xa5\x5a\x27\x88\x2d\x72\x68\x58\x3e\x32\xc6\xa2\xcc\xf7\x58\x6c\xe3\xa4\x4d\xc6\x2f\x3b\x18\xf7\xf6\x98\xcf\x43\x0a\x6e\x95\xfc\x2a\xb7\x60\xbe\x0c\x51\xbd\x42\x58\xc1\x86\xca\x7a\x0a\x4d\xa0\xb1\x59\x20\x13\x6c\x07\x9c\x73\x8d\x9a\x44\x4d\x0e\xd8\xad\x51\x2c\x00\x1f\x69\x51\x58\x10\x7d\x2c\x5a\x80\x16\x0b\x63\x63\xf5\x55\xa1\x92\x6f\x0d\x41\x13\x15\xe0\xaa\x38\x39\x03\x2c\x14\xc6\x87\x6d\x99\xbe\xbc\xd6\xaf\xcd\xc2\x9a\xe6\xcd\x4c\x14\x32\xe5\x99\x11\x88\x44\x91\xe3\xbf\x27\x11\x4b\x59\xe4\x47\x48\x80\x77\x89\xe3\x3f\xf7\x7f\xb6\x2d\xaa\xe9\x80\x9c\x45\x24\x41\x13\x2a\x94\x42\x5e\xeb\xa1\xbd\x13\x65\x11\x8b\xb1\x9c\xf5\x04\xef\x5c\xf1\x79\xc6\xe5\x1b\xca\x56\x8c\x4e\xc2\x35\xf2\x4c\x6c\x5b\x7f\x20\x96\x3b\x41\x55\x18\xcd\x42\xa4\x63\x66\xbc\x35\xad\x44\xed\x77\x5e\xaa\x01\x03\x83\x32\xea\x03\xe2\x73\x8c\xaa\xe1\xd9\x79\x5c\x50\x46\xb9\xc9\x95\x2b\xa8\x9f\x9b\x73\xff\x31\xf6\xfc\xb1\xe3\x58\xa8\x7c\xed\xd2\x75\x7c\xac\x51\x4c\xf1\x94\xa5\x30\x0a\xd9\x19\xe3\x0c\x03\xac\xef\xeb\xe7\xbf\x31\xe7\x4c\x86\x28\xde\xf5\x7d\x2a\x35\x64\x4c\xc5\x18\x85\xd9\x5a\xa8\xa9\x72\x74\x82\x32\x23\x92\x0c\x65\x89\x6f\x60\x80\xda\x72\xdc\x1c\xcc\x68\x34\xe1\x89\x4e\x8c\xca\xa4\x9b\xb2\x1e\x39\xda\x0e\xe1\xc2\x24\x9a\xae\x61\x77\x7f\x6e\xf6\xa2\xea\x5c\xf6\x7a\x69\x8c\x6b\x25\x6d\x45\xc5\xaa\xb2\x1d\xfb\x09\xe3\xe8\x59\x11\x42\x21\x5a\x45\x43\xcf\xd4\x9b\x32\x21\x03\xdc\x1c\x0f\x86\x25\x0c\xf5\xee\x2d\xcd\xa6\xb1\x59\xec\xeb\x1d\x8c\xc9\x58\x20\x3a\xe9\x61\xbd\xf8\xb1\xbc\x3b\x04\x7f\x1d\xee\x3a\xf6\x02\x93\x3c\xc4\xd4\xbf\xd9\x85\x76\x67\x71\xe3\x45\x97\x22\xc6\xbe\x2b\xd6\xa8\x9a\x19\x71\x6b\x24\x53\xb1\xc4\x98\x64\xb6\x5b\xf4\xaa\x9a\x4c\x11\xa3\xc7\xeb\x66\x6a\xb9\xff\x7e\x63\x02\x14\x31\xd2\xc4\xab\xc5\xda\x60\x7f\x5b\x73\x39\xca\x14\x17\xc2\xc9\x90\x1e\x74\x71\x2e\x91\xbf\xbd\xfc\xd7\xdc\x6c\x77\x6e\x98\x26\x86\x30\x61\xb8\x10\xce\x46\x1a\x17\x9f\xd8\x0d\x61\x49\xd8\x99\x8b\x6f\xca\xe2\x58\xfc\xb8\xa8\xcb\x74\xb9\x3b\xf1\x02\xe2\x84\x8b\x8c\xee\x15\xa6\x2b\xfb\xd7\x12\x2a\x8c\x03\x06\x93\x93\x78\x31\x67\x26\xf0\x97\xc5\x3b\x94\x97\x56\xc1\x87\x26\x1e\x65\x08\x91\x41\x1a\x59\xf5\x1d\x5a\xea\x49\xe2\xfb\x1a\x6b\x12\x8f\x97\x66\x87\xeb\x6f\x20\x89\x1f\x48\x0c\x9a\x30\x84\xdd\x94\xb0\x5a\xac\x7b\x0f\x61\x12\x10\x4f\x98\xfe\x07\xb6\x04\x47\xed\xda\x24\x24\xc6\x6c\xf0\x1b\xd4\x73\x5e\xc1\xd3\xdf\x43\xe5\x24\x21\xf5\x23\x8c\xe7\x8c\x81\x95\xd5\xca\xbc\x83\x53\x09\x43\x64\x47\xaf\xac\x9c\x84\x20\x74\xe4\x1e\xf5\x22\x03\x9e\x3f\xf2\x93\x09\x7f\x47\xc4\xb8\xe1\xfc\xc6\x1e\x35\x44\xe7\xa2\x38\xde\x17\xe5\x3c\xed\x2a\x7c\x49\xcc\x09\x22\xfc\xe7\xab\xfd\xaf\x57\x9e\xc1\x40\xca\xa4\x39\xcc\x85\x0d\xe1\x9f\xe0\xe3\x86\x23\x35\x4d\xa8\x2f\x51\x74\x72\xff\x01\x79\x7d\x59\xe7\xf0\x98\x66\xd9\x15\xf5\x6b\x38\x05\x4d\x22\x1d\x3b\x01\x7f\x85\xf1\xf9\xe8\x4e\x53\x1d\xe3\x82\xb7\x7c\xd8\x0f\x4f\xf4\x1f\xd1\xae\xec\xc9\x58\x1c\xe2\x6d\x36\x55\xab\x7d\xb1\xe7\x23\x3a\x48\xc2\xb8\xef\x19\x5d\xe5\xa7\x73\x96\x4d\xa6\xa4\x09\x53\x1a\xa3\xc8\x2d\x18\x86\xe6\x00\x84\x94\x30\x20\xa8\xb9\xdc\xb1\x9d\x1f\x16\xbf\x36\xd7\x6b\xa5\x1d\x9e\x78\x04\xa3\xe7\xdd\xd1\x78\xe3\xda\x20\x1b\xe9\xd6\x53\x48\x1c\xf7\xb1\x80\x63\x4d\xe3\x3d\xcd\x32\x9e\xe6\xa8\xe4\xed\xe2\xf2\xd1\x17\x44\x02\x25\xfd\xad\x44\xeb\x09\xf2\x09\x03\x74\x9a\x24\x14\xb0\xdb\x55\xd5\x3d\x4d\x88\xbb\xb4\xe2\x59\x56\x7c\xf4\x8d\x70\x69\xc2\x63\xf0\x79\x67\xcf\xdb\xac\xdb\x07\x5e\x8a\xb4\xae\x0e\xd5\xcd\x90\x3d\xe1\xda\x8f\x54\x0b\x75\xb4\x15\xbd\xfe\x16\x94\x88\x28\x51\xe0\x46\xf4\x5a\xee\xc7\xeb\xe2\x5f\x22\x88\x46\x34\x3f\xba\x51\x61\x20\xec\x0e\x48\x12\xf6\x8d\x3f\xe7\xa9\x6a\x62\xcc\xf3\xb8\x86\x9e\x08\x2d\xb0\xe2\xb1\x79\x7e\xdc\x7c\x5f\xb7\x18\x80\x44\x06\x11\x02\xa2\x9a\x24\xb6\xa2\xed\x5f\x29\xc7\xd3\xe2\x6e\xdb\xe2\xd4\x46\x17\x25\xb9\xa9\x48\xae\x64\x31\x56\x91\xfe\x5b\x12\x45\x34\x91\x9a\x05\x51\x6b\xef\x88\x26\xaa\x4d\xaa\xdc\x4e\xbd\x22\x0a\xeb\x87\xdf\x9f\xf7\x61\x74\xf8\x35\x7b\x78\x58\xba\xea\x4c\x02\x9e\x46\xd1\x38\xab\xe5\xb8\x85\xea\x7c\xec\x3e\x09\x7e\x92\x74\xc4\x21\x09\xa0\xaa\xc9\xb2\x6a\x02\x8c\xa1\xc2\x10\x7c\xa6\x55\x5d\x4d\x99\x82\xd1\x44\xfb\x09\xa6\x23\x75\x79\x59\xe5\x15\x94\xf5\x0e\xfe\x75\x86\x5c\xc2\xb8\x37\xc2\xbd\xc4\x70\x55\x9b\x00\xf4\xb1\xc8\xdb\x65\x9a\x7b\x3c\xc4\xe0\x73\x77\x02\x50\x0b\x6e\x85\x83\x46\x49\x39\xf7\x65\x20\x55\x47\x34\xbf\x6f\xf6\xc2\x56\x50\x82\x72\x5f\x19\x95\xaa\x03\x1c\xd3\xda\xf0\xfc\xd6\x1d\x76\xd3\xc1\xee\xaf\x14\x01\x28\x0f\x18\xb3\xbe\x91\x15\xb4\xf8\x64\xb7\x9e\xf3\xd0\x37\xd1\xce\xe2\xfb\xfd\x61\x7d\xcc\x53\x55\x64\x99\x73\x89\xa6\x3c\x0c\x23\xdc\xbe\xeb\xf6\x26\xdf\xa5\x57\x72\x9f\xc3\xfb\xca\xa3\xc0\x08\xfa\x55\x92\xe7\xeb\x73\x7d\x3a\xd7\xd5\x34\x62\xc3\x8d\x0f\x03\xad\x3b\xf7\x55\xa8\xf6\x85\x53\x79\x1c\xad\x46\x3c\x0e\x03\xdf\x52\xc5\x76\x1f\xfc\x34\xb9\xda\xde\xfc\xb7\x37\x25\x71\x4c\x03\x0b\x6e\x3b\x7c\xa4\xf9\x41\x16\xa0\xdb\x19\x21\x01\x65\xd0\xf5\x60\x5f\x60\xfc\xd8\x70\x12\x24\xbc\x65\x6f\xbf\x1a\xca\xe5\x70\x1f\xe1\x04\x34\xa2\x73\x66\xe7\x66\xea\x86\x1d\xe5\xe6\xcd\x09\x6d\x47\x79\xb1\xf8\x6e\x70\x22\x71\x7b\x30\xd6\x58\x9c\xaf\xa0\x4c\xa1\x9a\x0d\x00\xbf\x9c\x32\x0f\xbb\xb9\x46\x9e\x61\x78\x52\xa9\x85\x23\x92\xed\x5f\x61\x5f\x94\xf2\xf5\xf0\xa5\xc8\x07\xe5\x4c\x12\x7c\x30\x9b\x47\xca\x24\xca\xd3\xfb\xea\xd5\x5c\x4e\x54\xf0\x79\x12\x7b\xcc\xe6\xed\xf3\xd9\xf3\x74\x2d\x8b\x27\xd4\x33\xa2\xc3\x9d\xf8\xe4\xac\x7c\xa9\xfe\x82\xea\x66\x6f\x76\x7a\x7f\xe3\x09\x4b\x70\x67\x3a\x1c\x5e\xa0\x16\xc3\xd9\x4f\x92\x90\x73\x27\x5e\x30\x7e\x88\xb8\x95\x4a\x45\x0f\x46\xf9\x9c\x0f\xbc\x7e\x87\x8f\x26\xe7\x34\x94\x4e\xaa\x86\x57\x60\xc0\x51\xa3\xd7\x9e\x8b\x90\x04\xad\x58\xfd\xf8\xcb\xc0\x68\x6f\x54\xe8\x11\x87\xc1\x8e\x33\x3f\xba\xba\x37\xbd\x07\x54\x44\x94\x91\x2e\x08\xeb\x3b\x1d\x50\x2e\x62\xc1\xfb\xc1\xef\x21\xd5\x07\xcd\xd3\x6e\xe9\xe4\x22\x01\xec\xa6\x59\x6a\x3c\x76\xc7\x7a\x31\x1e\x17\x9c\xea\xa4\x0b\x29\x77\xc6\x7e\x78\xf0\x5a\xdb\x91\x32\x34\xe6\xca\x87\xd3\xb8\x6e\x77\x36\xf2\x4f\xc3\x9f\x2b\x43\x81\xe5\x8f\xc5\xf7\x3f\x07\x0f\xa7\x0c\x4d\x75\x2d\x2f\x1e\x8b\x12\x9e\xe0\xb3\xc6\xcd\xcc\x86\x81\xbd\xae\x0e\x97\x11\x47\x58\x4b\x5a\xe1\x08\xcb\x4c\x1e\xce\xb8\x14\x06\xad\x82\x5a\xca\x03\x4e\x5b\xbf\x70\xdd\x72\xe9\x9b\x0f\x24\xb8\x1f\x77\x48\xc8\xfb\xb2\x38\x7e\x5d\x40\xe3\xca\x97\xa6\x04\x99\xd5\x50\xba\x75\xb3\xad\x58\x0c\xc7\x42\x14\x59\x4f\x79\xf4\x35\xb9\x07\x18\x51\x32\x39\x88\x08\x1f\xfc\xd5\x7d\x0b\x61\xe4\x20\x28\xb7\xfb\xd4\x1e\xf8\x71\xde\xfa\xa9\x99\xbc\x6b\x38\xb5\x00\x12\x5b\x2c\xb3\xba\xe4\x83\xb9\xd5\x61\x84\xda\x4d\x08\x26\xc7\xe9\x9a\x77\xd5\x34\xae\xa9\x41\x94\xbc\x40\xfd\x33\xad\xb8\x09\x30\x36\x3c\xbd\x29\xab\xe9\x3e\x97\x18\x9b\xa7\xc3\xb9\x82\xd2\x42\x11\xa6\x17\x11\x2d\x22\xeb\x4f\x8e\xdd\xcd\x43\x37\xc9\xd3\x6f\x95\xf0\x22\x03\x49\x31\x54\xcc\xd5\x62\x1d\x1c\x1e\x56\x8f\x2d\xcc\x4e\x78\xcc\xb7\xc8\x4e\x53\x00\xbc\x03\x9e\x35\x4f\x2f\xaa\x83\xbc\x77\x2f\x8e\x1b\x9e\x18\x8f\x95\x36\x8e\x98\xbd\x94\x80\x88\xe5\xf6\x84\xdc\x78\x6a\xdd\xa7\xff\xfe\xb7\x5b\x4a\x85\xef\x99\x7d\xdd\x2e\xf3\x38\x2f\xf7\x9d\x88\xde\x97\x0b\xa7\xf0\x63\x4f\xb6\x48\x82\x31\x4e\xca\x8d\x11\x81\x68\x39\x5d\xb9\xda\xd5\xbc\xae\x1e\x5b\x76\xb8\xf0\xb5\xf6\xd5\x10\xc9\x3d\x07\xde\xde\x38\x11\x50\x89\xad\x5c\xe5\xcc\xe3\x46\x15\xda\x9b\x05\x09\x11\xe8\x18\x0b\x2f\xf9\xf9\x68\xd4\xcb\xda\x73\x86\xbe\x4f\xa0\x95\x00\x69\x9e\x82\xb1\x6b\x15\x15\x61\x04\xd6\x04\x95\xab\x26\xeb\x6a\x41\xed\xed\xf9\x43\x2e\x30\x5b\x9f\x43\xab\x19\x8f\x6f\xf0\xef\x12\x93\x89\x9d\x58\x84\xc2\x44\xa0\xa9\x83\xcc\x58\xd0\x46\x64\xfb\xa9\x22\x52\x0a\xfb\xc2\xb6\xe2\x68\xad\xaf\x46\x4a\xf4\x54\xc4\x7e\x14\x05\x2d\x58\x36\x3d\x9e\x8f\xbf\xf8\x48\xe4\x8b\x0a\xe2\x4b\xd4\xde\x7b\x49\xdf\x3b\x1c\xf8\x74\x8e\x2e\x08\x13\xc4\x6b\xd1\x9a\xf7\x25\xc0\xb7\x81\xf5\x0b\x15\x44\x6a\xfc\xca\x54\x16\x1b\x5e\xf2\x23\xd4\x50\x56\xbb\xb6\xce\x2e\x68\x68\xc0\xd0\xcd\x25\x15\xf2\xed\xd9\x36\x21\xfb\xd8\x8b\x68\xf4\x66\xd0\xc8\x03\x0b\x5a\xee\xab\x94\x5b\x99\x7f\xfb\x4f\x4b\xd7\x14\xcc\xa7\x08\x62\x10\xf0\x92\x1a\xe9\xd1\xfe\x4c\x5b\x09\x10\x2a\x12\x65\x90\x82\x27\x5e\x99\x24\x06\xf2\xfa\xa0\x11\x72\xec\xae\x95\x47\x81\xb0\x24\xc9\xaa\x38\x42\x7d\x3b\x8d\x15\x9c\x25\xd2\xc6\x60\x73\xa8\x9f\xf3\xab\x59\x16\x9e\x02\xcf\x96\x7c\xae\x80\x0a\xbd\x61\x01\x47\xa8\x49\x0e\x1f\xef\x3d\x2a\xdc\xf0\x2e\x28\x16\x78\x46\x4e\xeb\x7d\xd2\x8b\xd7\x0d\x93\x54\xb2\x6b\x5b\xcc\xde\xbe\x22\x94\x4c\xa4\xbd\x1b\x58\xde\x19\xe5\xd6\x76\x14\x48\x0f\x03\x22\xe3\x78\xb8\xf8\xe7\xf6\xc6\x24\x68\xc5\x90\x28\x8b\x1a\x32\x19\xaf\xaa\x47\x90\xaf\x58\x99\xf0\x93\xd1\xef\xd4\x3a\xa1\xcd\xfb\x24\xca\x82\x2b\xc9\xab\xfa\xef\xf5\x6f\xa4\x17\x90\xc0\xec\xe1\x47\xcb\x6f\x18\x50\x72\xa5\x47\x14\x3a\xdb\x28\x10\x1d\xc2\xf0\x7a\x35\x90\x1e\x53\xb8\x3c\x1a\xe5\xeb\x29\xa2\xa4\xf4\xfd\x00\x1b\xfc\x68\xc2\x73\x25\x52\x22\x83\xd8\x88\x6e\xc9\xe2\x7c\xba\xc5\xb2\x90\x01\x4f\x06\x64\x83\xfb\xe2\xf3\x86\x00\x89\x0c\xa5\x44\xb4\xa0\xe0\x23\x26\xb4\x8c\xfc\x48\xe9\xbe\xb3\xf7\x54\xd6\x26\x63\xb0\x8a\x94\xaf\xc5\xc7\x63\x13\xeb\x9a\x64\x6b\xfa\xcb\x88\xe7\xe1\x92\xb7\x33\xf4\xef\x7f\xdc\xcd\x46\xbf\x8e\x40\x80\xb1\xc1\x6c\xfb\xb8\xde\xba\xc9\x65\x3a\x44\x0d\xa8\xae\xb0\x31\x84\x47\xda\x79\xf6\xbb\x69\x4e\x3c\x86\xbd\x5f\x5d\x16\x47\x7c\xc0\x12\x72\xd3\x2b\xb6\x17\xcc\xc9\xc4\xf7\xcd\xdc\xe7\x69\xfd\xc8\xaf\xac\x5c\xa9\x4c\xc2\x30\x71\x16\xb1\x87\x14\x33\xd0\x03\xaf\x5b\x36\xbf\x1d\x25\x02\xe9\xdb\xcd\x66\x77\xe2\x12\x9a\x95\xcd\x7a\x74\x63\x01\x7b\x7e\x79\x2c\x14\x98\xad\xd3\xc1\x68\xa5\x50\x5a\x26\xfd\x60\x5c\x18\xe4\x41\xc7\x54\xbf\x16\x08\x1a\x4e\x9e\x0c\x3d\xea\xf5\xb6\xea\xfb\x34\xcb\x26\x05\xc8\xa8\x94\xca\xa3\xc2\x78\x04\xa4\xe7\xa3\xbb\x6e\xe5\x33\x2c\x23\xc8\xe2\x74\x59\xe6\x75\x5a\xc2\xb7\xac\xd0\xe9\x98\x09\x27\x15\x0f\x23\x27\x97\xc8\xcb\x97\xbe\x66\x16\x95\x4a\x0a\x6d\x7b\x28\x69\xbe\xfc\xd7\x39\x3d\x1d\x7b\x4d\xbf\xe9\x00\x47\x42\xc8\x23\xe1\x44\x63\xd2\xba\x5a\xe5\x76\xbe\x26\x98\x44\xe3\x8f\x32\x19\xd9\x06\xc6\x3d\xaf\x5e\xd3\x22\xdf\x9d\xd3\xba\x53\x8d\xf0\xaf\x3e\x20\x42\xdf\x4e\x93\xed\x39\xac\xf2\x4e\x44\xb5\x1d\xa7\xbc\xc0\x28\x1a\xdf\xf1\xa2\x23\x8f\x0f\x26\x42\x79\xc2\x73\xe6\x7e\x4d\x96\xec\x84\x02\x87\x83\x7c\x3f\x66\x9d\x44\xb8\x73\xa8\xbc\x83\x32\x7d\xe7\x18\x4f\xbb\x71\x71\x02\x9d\xc1\x58\xbb\x30\x0d\x2f\x2a\x0c\x38\xda\x26\x71\x5d\x43\xd9\x7a\x12\x0e\xcb\xc2\x2a\x0c\x25\x6a\x81\x8a\x73\x99\x3f\x15\x35\x32\x02\xa7\x96\x7d\x15\xc6\x3e\xee\x34\x07\x65\x60\x9a\x46\x4e\xf6\x6a\xc2\x87\xbf\x27\x24\x01\x52\xdc\xfb\x96\xc8\x8f\x00\xf5\xd9\x96\x00\x26\xd2\x51\x15\x4a\x82\xdc\x58\x2c\x7f\xee\x6a\x38\x31\x77\xad\x51\x10\xe3\xe2\x2d\x79\x3e\x87\xdf\x69\x69\xa8\x88\x72\x8b\xd2\x1c\xac\x49\xdc\xa9\x46\x8d\x2e\x35\x92\x1a\x1b\x2e\x69\x9e\xd6\x29\x37\xc0\x34\x9b\xc3\xdf\x38\xbf\x36\xcd\xa8\x13\x86\x6a\xeb\x1c\x8c\x26\xd9\x10\x83\xa5\xe2\xd8\x47\x9d\x85\xfd\x72\xe1\xdc\x14\x9e\x9e\x1f\x1d\xb3\x42\xc5\x92\x70\xeb\xee\xe6\xba\x70\xfd\x47\xd7\x85\x02\x2a\xd6\x2c\x70\x92\xad\x9b\xf5\xae\x2f\x94\x4a\x15\xf1\x4d\xc4\x89\x54\x19\x05\x70\x34\xa5\xf6\xe1\xe5\x92\x50\x1b\xb1\xfc\x3c\xad\x07\xb5\x09\x45\x98\xa4\xb4\x53\x3f\x18\xfe\x68\x37\x46\x02\x06\xdd\xb2\x38\x9e\x78\x6e\xbb\xba\x2b\x33\x55\xed\x79\x14\x47\xf9\x40\xf8\x3c\x95\xc5\xa9\x4c\xc7\xae\xdd\x54\xd1\x88\x63\x8b\x42\xf1\x9a\xef\xd0\xcf\x7e\x61\x7b\x6f\x4d\x1a\xb5\x1a\x46\x09\xcc\x7d\x48\x07\x00\x4e\xdc\xb3\x17\xc7\x29\xe6\x47\xb2\x6f\x9b\xb3\x80\x62\x74\xd5\x8c\x49\x94\x03\xae\xce\xe2\xb7\x55\x0a\xf7\x11\x4e\x21\x19\xab\x8e\x7c\x2f\xce\x65\x76\xd9\xf6\x6d\x5f\x87\x5f\xc4\xb9\x17\x85\x7d\x72\xfe\xe0\x09\xbb\x8e\xa3\xbb\x44\x5d\x09\x8f\xe3\xf2\x5a\x15\x52\x42\xf9\xcd\xd5\x88\x95\xa0\xa0\x84\x75\x7c\x6d\x59\xe6\xed\xc1\x84\x9b\x9d\x1d\xe3\xa6\x2b\xd2\xe6\xe8\xea\x84\x96\xb1\x45\x62\x0f\x4b\xb5\x4a\x46\x1c\xd1\x0a\x7c\x68\x37\xd5\x1e\x95\x58\xbf\x06\x5e\x66\x97\x79\x5a\xaa\x47\xfe\xb9\x81\x72\x03\x65\xd5\x6e\x60\x4a\x36\xfb\x91\x01\xd1\x36\x17\xf1\x6f\x50\xe8\x01\xee\x2a\x91\x4a\x25\xcc\x69\x7c\x59\xb7\x3f\x0c\x08\x9b\x1b\xbe\x28\xda\x47\x58\x81\xc0\x67\x10\x69\x17\xae\xaf\x3b\x7d\x87\x40\x09\xcf\xd8\x20\x95\xfb\xc2\x75\xfc\x06\x2b\x88\x0e\x7c\x47\xbc\x32\xd7\xca\x67\xb5\x8d\x06\x46\x35\x25\xa5\x63\x2f\x30\x95\xf8\x66\x17\x11\x0e\xf9\x3f\x1e\x44\x11\x8d\x5f\x75\x22\x27\xee\xba\x35\xe3\x46\x8a\xdc\x5a\x10\x9e\x7a\x6c\xf2\xc1\x49\xc0\xf7\x2c\x68\xc4\x39\x40\x23\x10\xf0\xcb\xe5\x13\xfc\x40\xa0\x72\x55\xc6\x2b\x33\x6b\x76\x8d\xa8\x6a\x7e\x74\xf9\x28\xf8\x34\x8e\xac\xce\xe9\x7b\x5a\x9c\x91\xa2\x70\xd5\x68\x07\x9f\x71\x1d\xf6\xbb\xd8\x0f\x1d\x96\x02\x7c\x45\x50\xf0\x77\xb3\x5d\xa2\xc2\xec\x7c\xb6\x5b\x1e\x36\xdb\xd5\x62\x79\x58\x3d\x1d\x7e\x2d\x57\xed\x40\x30\x20\xd9\xd5\xc3\xbd\xe3\xce\x3b\x99\xa2\x1f\x60\xa4\x6f\xdc\x48\x1d\x61\xab\xd4\x54\x21\x4c\x0f\xca\x1d\x0b\x3d\x2d\x6d\x6d\x6d\x63\x74\x21\x06\x0b\xd6\x68\x12\xa2\xc0\x0b\x5a\x4f\x49\x71\xbe\xdc\x68\xb7\x42\xc4\x22\x63\x30\x68\x58\xcf\x60\x75\xdb\x0c\x93\x6e\x74\xea\xff\xfe\x9f\xee\xbf\xdc\xc7\x65\x80\x17\xec\xee\xcf\xa6\x04\x9d\x7e\xfe\x31\xc5\x7a\x81\x48\x2b\x04\xb0\x23\x6d\xa6\x05\xe4\x40\xa4\x81\xd3\xb6\x2b\x61\xd6\x00\xbb\x8a\x41\xac\x7c\xd4\x22\xa8\x5f\xd3\x52\x3d\x14\xed\x93\x0f\x24\x8a\xf1\xc6\xa4\x95\x5b\x0b\xd1\xad\x7d\xf8\x85\x44\x52\x27\x33\xf3\x0b\xe0\x2d\xbb\x8c\xdb\x01\x40\x14\x47\x94\xc2\xc1\xd5\xb8\xdc\x17\xb3\xd8\xd7\x9d\xb0\xfb\xfa\x64\xdb\x0e\x6d\x72\xf2\xb5\xf6\x22\x30\x11\x21\x2a\x13\x54\x97\x2f\xde\x22\xdc\x4f\xfe\xf3\x7f\xf8\x8c\xfb\x6a\x88\x03\xcf\x75\xfb\xf6\xc5\x23\xcf\x2f\x1d\x09\x7f\x9c\x2e\x41\x12\x50\x74\xa6\x51\xe9\x4b\x5a\xf3\xac\xb3\x8a\x75\xc7\x63\xcf\xa1\xe1\x1f\xf9\xe7\x2a\x7f\xb7\x14\xd9\xf1\x8b\x92\x70\xcf\x58\xfc\xda\xd7\xb8\xe7\x8e\x44\x21\x11\x80\x15\x2e\xb7\xe5\xa0\xa8\xf3\xf4\xc4\xf1\xc8\x6b\x7b\x05\x69\x7d\xd9\x42\x85\x1b\xde\xf8\xeb\x38\x01\x6c\x2e\xe3\xc3\x62\xd7\x33\x6a\xe5\x22\xff\x9b\xba\x1f\x27\x3c\xe0\xae\x70\x6a\x97\xea\xdb\xb5\x19\x10\xbe\x81\xa8\x97\x99\x3c\x88\xbe\x34\x1d\x08\xbf\xaf\xda\x5b\x94\xd5\xae\x2e\xe4\xdb\x95\xff\x10\x05\x01\x1e\x02\xbb\x6d\xdb\xdf\xf6\xbd\x90\x15\xdc\x0f\xb3\x27\x57\x68\x90\x41\x28\x9d\x00\x9e\x75\x29\xbf\xd6\x67\x02\x49\x22\x0c\x88\x1f\x67\x7f\x1e\x7e\xad\xf6\xdf\xef\xb6\xb3\x5f\xce\xa0\x8b\x82\xa4\x01\x96\x3f\x77\xfb\x87\xef\x13\xb1\xe2\x14\xb8\x09\xa4\x32\x72\x3a\xf9\x26\xe3\xcd\x66\x83\xa0\xf7\x65\x0b\x21\x00\xa9\x39\x37\x99\x77\x76\xa3\x3b\x0a\xe0\x45\x06\x60\x9b\xcb\x12\x97\x91\x39\xaf\xde\xa0\xae\x30\xfd\xbe\x92\x5e\x6f\x3f\xc4\xb1\x44\xbc\x6b\x82\xb3\x12\x1c\x27\x3b\x74\xdf\x0b\xdc\xc3\xa5\x05\xd9\xe0\x6d\xbc\x04\xa0\x00\x73\xd5\xfb\xd9\x62\xbf\xde\xb6\x96\xbf\x14\x74\x42\xf1\x77\xb8\x10\x77\xce\xab\x2f\x65\x3e\x40\x6b\x8d\xed\x7c\x8e\x05\xcd\x7d\xe1\x6a\xd8\x6b\x63\x89\x34\x98\x25\xed\x27\x11\xf6\x46\xb6\xeb\x6f\xf6\x0b\x75\x10\x00\x4f\x1c\x9e\xd9\x12\x9c\x6f\xcc\x90\x0e\x58\xe4\xdb\x00\x09\x9d\xda\x6c\x3e\x61\x6c\xba\x47\x43\x45\x84\x44\x8f\xb4\x9a\x43\x2b\x55\xda\x8f\x8e\x75\xa0\x63\x69\x3c\x00\xac\xf6\xff\xc0\x00\x90\xea\xd0\xf3\x51\x7e\xcc\x14\xf3\x7a\x5b\x96\x0e\x85\xb0\xc5\xeb\x63\xf1\x8e\x9b\xd9\xb0\x1f\xa1\x43\x19\x60\xb1\x21\xad\x2c\xda\x77\x28\x07\x4d\x75\xa8\x8c\x07\xf8\xce\xc8\xd4\x18\x15\xe4\x49\x30\x85\x8e\x48\xec\x14\x6d\x9e\xe0\xb3\xb6\x7c\xff\x7f\x38\x3b\xd8\xe1\xe0\x98\x41\x62\x2a\xa3\x0f\xe9\xbf\xce\xcd\xde\xd8\xc1\x19\x75\x9c\x18\xed\x9a\x43\x0e\x9f\x75\x1f\xa1\xac\x89\x47\xb0\x2c\xb4\x7b\x2d\x3e\x9e\x73\xcb\x17\x9a\x0e\x81\x34\x0d\x63\x65\x7a\x2d\x73\x9e\xe7\x63\xa0\xa6\xa6\x22\x72\xbb\xc5\xfc\x77\xfd\x02\xcd\x34\x00\x76\x7e\xd6\xdb\xcd\x30\x37\xd4\x49\xe2\xa1\x7a\xcc\x8f\xa7\xf5\xaf\x87\xe5\xdd\xb7\xe5\x61\xbf\x3e\x7c\x5b\xee\x0f\xfe\xfd\x76\xf6\xf4\xe3\xa1\x6d\x88\x68\x1e\x46\x56\xf1\x33\xcb\xf6\xdc\xc2\x18\x7e\x27\x44\xa6\x85\x47\x51\xc6\xc6\x44\xcd\xe5\xc5\xd2\xac\xee\x0a\x79\x1e\x4b\xb4\x69\x11\x70\xec\xc7\xfd\xd7\xfe\xb9\xfb\x93\x74\x3e\x45\x0b\xcb\xeb\x9c\xd5\x9d\x5d\x7c\xef\x7b\x84\x46\xf9\xf1\x45\x91\xe6\x55\xb3\xe0\x55\x93\x20\xcf\xfe\x2b\xa5\x65\x12\x72\x61\x85\xe8\xe7\x3d\x01\x7c\x77\x58\xc4\x51\xdf\x8b\x0f\x8d\x3c\xa6\x6f\x96\x04\x5f\x58\xd0\xd8\x37\x7e\x04\x94\x59\x99\x8e\x11\xb5\x04\x65\x1d\x61\x0c\x61\xc7\x40\x6d\x40\x7d\x81\x4e\xd2\x4a\xc7\x78\x93\xee\xd7\xcf\x4f\x77\xcb\xed\xce\x65\x99\x3f\x97\xbb\xfd\xf2\xee\xe0\xd8\x3c\x1a\x62\x40\x02\x44\xb3\x85\xa8\x77\xe3\x20\xb9\x9f\xad\x1f\x8a\x97\xe2\x86\xec\x8f\x06\x1a\x60\xcc\x72\xae\xe0\xa9\xb3\x6e\x74\x07\x13\x23\xff\x51\xf5\x7a\xe1\x01\x1d\x8d\x11\x49\x40\x3a\x21\x88\xc9\x90\xd7\x0d\x55\xe6\x67\xe0\x4f\xfd\x13\x15\x75\xdd\x95\xeb\x30\x44\xd8\xfa\x4c\x29\xf4\xa2\x38\x97\x15\xfc\x9e\x98\xa6\x75\x2c\x9c\x44\x60\xf3\x7e\x1f\x9c\x43\x05\xd5\x9a\x28\xdf\x6b\x71\x81\x63\x7f\x53\xb7\x40\x33\xcf\x8b\x38\x56\x72\xad\x32\x71\x5f\x32\x75\x7a\xca\x98\xe7\xc5\x11\x22\x13\x53\x59\x74\x02\xfa\xed\xf9\xb4\xd1\x94\xb4\x9d\x2b\x63\x0b\x3f\xf9\x28\x30\xcf\x4f\x78\xe4\xb7\x3c\x0a\xfb\x62\xfe\x02\x9e\xd5\xaf\x3d\x4f\xf5\x89\x46\xd7\xe8\x82\x7c\xc9\x9d\x91\xb4\x89\x1c\xdb\x75\xd6\x4a\x4e\xf7\x81\x61\xcd\x70\x81\x18\x8a\x4d\x59\x14\x7a\xad\x91\xe9\x0c\x6d\x83\x9e\x79\x41\xd4\x6a\xdb\x0e\xe4\x82\xbf\xac\xd9\x35\x1f\xd3\xbe\xab\x85\xee\x5f\xcb\xe2\xa3\x95\x42\xbd\x4b\xab\x26\x23\x7d\x2a\xea\x41\x6a\xca\xbc\x40\x29\x04\x70\xdd\x9d\xa4\xfb\x53\x48\x4c\x77\x7c\x76\xf7\x73\xb5\x5b\x6f\x77\x3d\x5a\xb1\x1b\x12\xf9\xed\x53\x6e\x19\xe0\xd3\xd3\x12\x31\x1f\xcc\xd6\x34\x43\xdf\x49\xe4\x28\xda\x63\x31\x8d\xf1\xf1\xe0\x4a\x75\x6d\x90\xf9\x90\xbb\x3f\x3a\x5d\x9c\xf8\x3a\x72\x09\x81\xe9\xa9\x8d\x00\x19\xa3\xf1\x8a\x2a\x43\x79\xcb\xd5\xd8\x28\x90\x79\x24\x54\x60\xe4\x4a\x5e\x36\x45\x96\xfd\x2c\xea\x1e\x40\x68\xfa\x84\x84\x04\x28\xda\x70\x9f\x15\x1f\xf2\x95\x0f\x70\x2b\xcc\x4b\xc2\x08\xbb\x23\xa6\xac\x38\x46\x27\x4e\x95\x7d\x99\x97\xf0\xd0\x60\x5d\xb1\x1c\xb4\x69\xf2\xda\xcc\x59\xef\x31\x4f\x78\x31\xce\x5f\xcb\x3a\x37\xa1\x61\x4b\xab\xbc\xc1\x73\x64\x9e\x88\xc3\xd0\x72\x12\xdb\xc6\xa1\x79\x84\x7e\x5d\xb7\x9f\xfb\xc1\x02\xf3\x64\xa0\x03\xbf\xe3\xd2\xde\x17\x25\xa0\x25\xe8\xad\xb5\x91\x79\x52\x7b\x71\xe8\xe4\x60\xa2\xbe\x4a\x33\xf3\x14\x8d\x71\x81\xdf\x02\x57\x9d\x7c\x24\xf3\x94\x8c\x98\x6d\xe5\x4d\x9b\xab\x4d\xff\x2e\x20\x80\x7c\xf9\x3a\x3d\xc2\x03\xe8\x7a\x5f\x2c\x5a\xcb\x49\xe6\x01\x93\xe8\xcf\x65\xf4\x82\x8c\xfc\x60\x9f\xb7\x37\xa8\x7b\x0d\x19\xa3\xbf\xfb\x5e\x08\x12\x8d\x24\xad\x37\xb8\xe3\x57\x54\xe0\x1b\x9f\xd2\x24\x40\x85\x9e\xb7\x54\xbe\x15\x5a\xbb\xcb\xd4\x0c\x62\xe8\xd0\xd0\xfc\x04\xe5\x1f\xd3\x0f\x49\x97\x7e\x5d\x1b\x47\xb9\x93\x09\x0f\xd1\x2e\x5c\x14\x65\x3d\xbf\xcc\xcb\xe2\x0d\xda\xe7\x47\x6b\xe3\x65\x0d\x86\x56\xd8\x42\xef\x07\x77\xdc\xf7\xfc\x00\x37\x05\xbb\xfc\xa1\x40\x6f\x7b\x0e\xdf\x03\x8f\x75\x02\x6c\x87\xa2\x8b\xa6\x98\xef\x7b\x06\x22\x6b\xfe\xfa\x3b\xff\x93\xe1\xec\x34\x1f\x46\x9b\xba\x9f\xcb\x6d\xff\x35\xf2\x7d\xdf\xe0\x1b\x34\x97\x75\x51\xb6\x95\x4f\xe6\xfb\x92\xa2\x8c\x92\xe5\x6b\x0d\xcf\x16\x84\x31\x96\x98\xf2\xf3\x71\xff\x9a\xe6\x2f\x95\xfb\x54\x90\x78\x58\x7c\xcb\x40\xd7\x11\x1d\x7d\x2a\x62\x89\x60\x56\xd1\x37\x55\xf5\xab\x31\x3f\xfb\x63\x1a\x49\xec\x3e\xa3\x3c\x30\x21\xaf\x9b\x4f\xa3\x7e\x3a\x9c\xd4\x98\x10\x14\xd1\x79\x28\xea\x1a\x85\xf6\x47\x2e\x6d\xcc\x27\x9e\x87\x3c\x95\x3b\xf8\x05\xe9\x0e\xe4\xb9\x4c\xeb\xcb\xce\x20\x64\x06\x13\x42\xc2\xd8\x89\xda\x61\xbc\x62\x14\x56\x7a\x6d\x01\x37\x8e\xeb\xd8\x62\x59\x9a\x8c\x79\x83\xe8\x84\xe1\x10\x9a\x18\x89\x3f\x71\x2e\x9d\x7b\xd1\x68\x04\x0b\x12\x2c\xb5\xed\x67\xdb\x26\x06\xb5\x61\xce\xec\xee\x6e\xbb\xdc\xed\xdc\x15\x25\x3e\x0f\x4c\x82\xbb\x31\x68\xcc\xb0\x0f\x0b\x66\x3e\xf7\xc3\x80\x3a\xfc\xc7\xbe\x70\x0a\xfe\xee\x01\x31\xb0\xc7\xdf\x52\x02\xa7\xca\xac\xcc\xe7\xc4\xc3\xc7\x06\x2d\x47\x64\xdd\x84\x4c\xf7\x65\x71\x44\x7f\xb8\xae\xe2\xcb\x7c\x0e\x91\xd7\xfc\xd4\xd9\x62\xbf\x5a\x3f\x1d\xf6\xb3\x3f\xdd\xd5\x89\x20\x1a\xb3\xb1\x67\xe3\xc7\x49\x44\x5e\x6c\xb8\x26\x99\x05\x8f\xa2\xfd\xa7\x3b\x4a\x4c\x37\xb7\x2a\x32\x75\x5f\x94\xf7\xa9\x76\xe9\x2f\xf3\x25\x49\xb0\x4d\x60\x80\x8f\x33\xa5\x6e\x24\xb4\xcc\x97\xcc\xc3\x5e\xcf\x23\x4f\xf9\xe8\x2e\xc8\x04\x3c\x44\x24\xcf\x77\xcf\xed\x89\x25\x45\xc8\xd1\x37\xa8\xb7\xa9\x7c\xfd\xc7\x39\x75\x79\x1a\xf3\x95\xa2\xf8\x88\xd8\x18\xea\x20\xfb\xba\xf3\x83\x53\x07\x5e\x08\x44\x8c\x21\x77\x7f\xb8\x83\x94\x59\x81\x1d\xcc\x11\x6c\x14\x53\x16\xc7\xb6\xb1\xe5\x46\x06\xbe\x4f\x3a\x2c\xf9\xfe\x72\x82\x2b\x49\x6e\x16\x04\xd4\x73\x0d\xb4\x4e\xf2\x8b\xf4\xa3\x57\x16\x04\x49\x84\x26\x3a\x87\xb4\x9a\xb5\xc5\xed\x75\x79\x4d\x2b\x68\x86\x12\x63\xe3\x30\xc2\x63\xba\xc3\x10\xe3\x1d\x77\x2e\x0f\x03\x08\xfc\xf0\x25\x0e\xc2\x88\xe3\xcb\x77\xe4\x9f\x07\x2c\xd6\x1e\xde\xd3\xda\x89\x8a\xb1\x20\xa4\x46\xdf\xdc\xfa\x24\xfd\x27\xf6\x9f\x76\x77\x99\xe2\x86\xb2\x20\x8a\x02\xec\x11\xd4\xad\x7e\xc1\x6f\x5e\x02\xf7\x39\x1a\x9b\xd2\x81\x29\x14\xfd\xb8\xc8\x3f\x46\x1b\x41\x10\x25\x31\xe2\xc1\x79\x5d\xf7\x0c\x07\xbb\xc3\x12\x10\x03\xb2\x28\x2f\xa7\xba\xd8\xa7\xf2\x0d\xea\x6a\xb5\x58\xdf\x5c\xac\xff\x8f\xff\xba\xaf\x03\x53\x4a\x45\x0d\x0d\x04\x66\xb8\x97\xdf\x34\x76\xbf\xdc\x1a\x82\xd8\x0f\x31\xa2\x40\xfd\x25\x50\x8e\x01\x3b\xfd\x55\x31\x55\x2c\x6a\x9f\x44\x4b\xa9\xdd\x37\x01\x42\x31\xf2\x54\x62\x01\x89\xa9\x6e\xf9\xe9\x03\x37\xe2\xaf\xe7\x9f\x7a\x0a\xc1\xf8\xbc\xfe\xec\x2f\xcd\x01\xf5\x43\x93\xd6\x23\xd0\xeb\xd3\x2d\x74\xb7\xc3\x99\x2b\x20\xca\xe8\xc7\x50\x26\xf0\x36\xd9\x9f\xb1\xfb\x00\x38\x5d\xbd\x07\x94\x27\xc8\xe3\xa8\xa1\x44\xaf\xe6\x66\x63\xff\x5f\x90\xf5\xe8\xed\x4b\x3c\xe9\xe2\xb2\x37\x98\x43\xc6\x51\x14\x73\x7a\x31\x0a\xd0\x24\xbc\x2f\x42\x33\x3d\x11\x3c\x08\xa9\x55\x5d\xac\xd3\xfc\xc5\x68\x34\x8d\x86\xb0\x10\x4b\x2c\x36\x66\x6d\x17\x8e\xf1\x7b\xf3\xb7\x58\x3b\xee\x9c\x09\x01\xec\x9f\x17\xf9\xb9\xea\x14\x92\xed\x51\x11\x2b\x8c\xf3\xed\xea\x67\x0b\x47\xdb\x73\x76\xed\xe0\xe4\x3e\x41\x08\xeb\xb7\x89\x2c\x73\xf2\xea\x22\xdb\xd7\x47\x88\x58\xb1\x76\xd5\x6c\xd2\x6c\xc7\xb6\xbd\xa2\x14\xb0\x40\x7a\x51\x1c\x3b\xb4\x09\xc8\x54\xa7\x4d\x02\x7a\x1c\x68\x91\x0e\x7f\x1f\xc4\x34\xb0\x66\x65\x5b\x5e\xc3\x93\x33\xe6\x66\x81\x8e\x38\x1e\x59\x3d\xdd\xaf\x17\xeb\xed\xe6\x70\xb7\x7e\xea\x49\xa9\xb2\xd0\x0b\x03\x04\x7a\xe7\xf0\x81\x36\x21\xed\xdf\x19\x41\xb0\xd0\xf7\xc7\x7d\x77\x0f\x7e\x13\x65\x4f\xbf\xcc\xa1\xc7\x99\x93\x78\x73\x25\xa0\xfd\xa7\x35\x60\x1e\xd6\xe5\x9a\xb1\x1c\x77\xae\x67\x13\x7e\xa3\xdc\xfe\x70\x84\x1f\x0a\x83\xf6\x68\x9e\x46\xb3\xc3\xcc\x34\x62\x88\x7b\x9a\xf0\x83\xe9\x09\xfd\x38\x70\xf0\x96\x26\xb2\xa9\x1e\x53\x59\x16\x8f\x85\x6a\xee\xf0\xca\x75\x67\x58\xe8\x4b\x8e\x58\x25\xd4\xdf\x4c\xf3\x14\x5f\x70\x7b\x2c\x08\x23\x61\x1f\x5c\x93\x08\x5d\x49\x12\xb8\x81\x60\x0c\xea\x4a\xd4\xd7\xab\x8c\x1d\x03\xa8\xf9\xa5\x8f\x06\x60\x61\x48\xb9\x51\x35\x6d\x82\xd1\x9e\xca\x14\x0b\x23\x16\x83\x89\xb1\x2e\x4e\x2b\xb2\xbf\x66\x84\x31\xd3\x98\xfa\x48\x7e\x3a\xa4\xf9\xe1\xc3\x69\xb9\xb0\x30\x06\xcd\x75\xff\x1a\xf7\x45\xa7\x1d\x3d\x9a\x12\x42\x14\xca\x14\xa4\xd5\x63\x4f\xaf\x73\x38\xd3\x89\x47\x43\xcf\xee\x36\xb3\x2c\x1b\xac\xbc\x6e\x88\x2f\xb1\x9f\x73\x3c\xd7\xf0\xd8\xb3\xb8\x62\x61\x02\xdc\xdd\x74\xb3\x5b\x58\x17\xf7\xd1\x75\x70\xaa\x23\xbb\xc5\xdf\x3d\xcd\x6e\xcc\x29\x67\x92\x39\x35\xee\x6d\x91\x8d\x1c\x33\x99\x7b\xcb\x42\x9e\xc4\x22\x30\xaf\xa5\x7c\x5b\x64\xe9\x84\x23\xe6\xf4\x13\x2a\x02\x15\x5b\xc9\x02\x74\xa1\x1b\xff\x4c\x91\x44\xda\x56\xb8\x79\x96\xfe\x1b\x1c\x7c\x74\xb0\x60\x86\x42\x46\x46\x0a\xd9\x09\xd9\x66\x37\xc5\xf0\x58\x28\x3d\x8e\xd1\x86\xcc\x8a\x0a\xc6\xe1\x51\x28\x23\x62\xe4\x35\xce\x26\x75\xee\x29\x81\xb2\x50\x52\x12\x3a\x11\x80\x66\x09\xc7\x0e\xe1\x0d\x78\x7b\x6f\x5d\x09\x25\x8b\xf0\x35\xf8\xf9\x6f\x9e\xff\xae\xb6\xca\x42\x09\x11\x3a\xa3\x35\x93\x1e\xb8\xaf\x56\x9a\x4a\xe3\xd2\xe4\x44\x27\xba\xa0\x6b\x3e\x8d\x6c\x60\x21\xf8\x21\xd6\x95\xbe\xf3\x36\xe2\x0c\x41\xd3\xc0\xae\x71\x77\xa9\xd6\xa9\x3c\x67\xf5\x65\xf4\x6c\x68\x1a\x38\x0c\xd9\xa2\xd9\x57\xea\x1a\x03\xc5\x83\x3d\x47\xe4\xf1\x18\x99\x8b\x4f\xf7\x8b\xfe\x1b\x12\x79\x9c\x48\xe5\xbc\xe7\x45\x6b\x7e\x7d\xad\x88\xda\x0c\x65\x28\xaa\x7a\x4c\x73\x5b\xe9\x9b\x43\xbd\xca\x07\xef\x6a\xe4\x87\x5a\xfb\xce\xef\xc9\xcc\xf5\x75\x01\x9b\x45\x3e\x09\xb1\xbf\xf3\x63\xfb\xd7\x66\xbf\x7e\x5a\x3d\x3f\xb6\x27\x48\x8c\x0c\x49\xf5\x5a\x9c\x33\x85\xa5\xb5\x75\x3e\xab\x6b\x38\x9e\x6a\xd4\xd3\xc3\x4d\xe4\xd7\x2b\xe4\x4f\x45\xbf\xdf\xc0\x22\x9f\x07\x66\xdf\x68\x02\x8e\x26\x53\xf2\x37\x9d\x20\x08\x8b\x02\x92\x20\x86\xe2\xd0\xba\x69\xda\xee\x74\xf3\xbc\x04\xe1\xd7\x61\x52\x14\xd0\x08\xd7\x8b\x53\x09\xfb\x17\x68\xad\xd5\x58\x14\xf0\x10\x3d\xaa\x0e\x07\xe9\x9c\x65\x07\xa0\x98\x76\xfa\x02\x90\xf8\x24\xaa\x92\x7f\xac\x6a\x38\xda\x6c\x75\x7a\x97\x8a\x42\x20\x91\xdd\x04\x9b\xc1\xd5\x72\x31\xfd\xc0\x44\x21\x70\xe8\x01\x5e\x6c\x53\xca\x1e\x8c\xfc\x10\x73\x8c\x03\x94\xbc\x82\xa7\x42\x8d\xef\x69\x14\x46\xb4\x17\x40\xf4\x24\x66\x7b\xc2\x78\x13\x28\x1f\x16\x45\x31\xb4\xc6\x4e\xf8\x0e\xcb\xcb\x58\x03\x7c\xf8\x8b\x22\xe2\x23\xe6\xe4\x67\x0a\x1f\x1d\x81\x9e\x45\x11\x35\xeb\x45\x2b\x69\xd7\x3d\x9c\x91\x8a\xb9\xd1\xeb\x29\x6b\xac\x68\x7d\xf1\x0e\x46\x31\x0d\x94\x71\x49\x49\xdf\x31\x4e\x83\xd5\x62\x8d\xe0\x4c\x6b\xaf\xec\xce\x1a\x8b\x08\xa7\x76\xf3\x7d\xb6\x5b\xc6\xc6\x7c\xf8\xb0\x5f\x39\x1b\x2e\x16\xd1\x18\xf0\x4e\xcd\xf7\x8b\xe5\xfe\xfb\xe8\xc9\xa5\x2a\x40\xef\x90\x6f\x45\xa1\x1e\xce\xf2\xad\xff\x53\x98\x97\x38\xca\xf6\x06\x29\x5d\xa8\xec\x9e\xe6\x2f\x46\x7b\x75\x72\xc1\x8e\x18\xa5\xd8\x53\xfc\x56\xf0\xec\x7b\xda\x16\x0d\xb3\xf6\xa4\x1a\x8c\x69\x05\xbe\x67\x5b\x53\x2a\x54\xfb\x62\x29\x8b\xea\x52\xd5\x70\x74\x03\x79\x40\xb1\x52\x7f\x3c\xec\x1e\xb7\x76\x69\x76\x87\x22\xea\x59\xf9\xab\x0f\x5e\x2a\x50\xeb\x73\x2d\x8b\x76\xc7\x8e\x38\x35\xfd\xb5\x3d\xff\x77\x5a\x0f\xd6\x07\x2e\x43\xca\x50\xf2\x07\x9f\xd6\x7d\x5a\xb7\x0b\x6f\x24\x24\xc3\x57\xd5\xa8\x8c\xe0\xc6\xe5\x0e\x35\x61\x99\xd7\x83\x15\x0c\x58\x19\x6e\x8c\x6f\x74\xf6\xd0\x34\xd3\x14\x5a\x5a\x55\x8d\x6e\xef\xeb\x03\x23\x46\x10\x09\x16\x49\xf0\x74\x5f\xb2\xa4\x2e\xb8\x94\x53\x0a\x57\x2c\x52\xbe\x8f\x4e\x8f\xef\x3c\x4b\x55\x1f\x2e\xc8\x22\x15\xf1\xa4\x35\x7e\x3a\xa6\x79\x35\xd5\x33\x65\x91\x52\x86\x0e\x79\x07\xef\x66\xcd\x33\xfd\x86\xc7\xe2\xf6\xd6\x69\x3f\x09\xbe\xc6\x62\xfa\xb1\x90\x6f\xcd\x16\xb1\xc3\xb5\x0d\x5d\xa3\xa1\xb5\xf7\xee\x59\xad\xb0\x08\x02\x03\x46\xb6\xca\x1f\xc6\x85\xc9\x9d\x7c\x68\x98\x35\xfa\x9d\x60\x9d\x34\xee\xcf\xf9\x8f\xde\xa3\x09\xd2\x33\x92\xb0\x28\x54\x8c\xc2\xcb\xd7\xcc\xa2\xdf\x55\x89\x86\xdf\xa4\x85\x11\xe3\x32\xcd\x9f\x95\x05\x60\xdc\x97\xc5\x11\x3b\xed\x57\x2a\x6c\x2c\xf6\x54\x18\x08\x6b\x90\x5f\xf3\xb4\x5b\xbb\x63\x3f\x50\x14\xfd\xaa\x8a\x73\xae\xfc\xbd\x7d\xd4\x8f\xbc\x97\x7a\xc4\x7e\x6c\x34\x49\xda\x48\xaf\xe4\xef\x90\x4d\x33\x6f\x27\x16\x88\xd8\x27\x04\xd5\x51\x0e\xb2\x38\x9e\xce\x35\x58\xf0\xde\xa4\x22\xe1\xe0\x5f\xb7\x5a\xc6\x7e\x12\x46\x2e\x98\x68\x79\x36\xfd\xce\xf0\xd7\xff\xb8\xb3\x88\x00\x31\xa3\x33\xd7\x6d\x66\xb1\xaf\x15\xca\xd3\xc1\x3b\xe4\xb5\x35\xde\xb1\x87\x02\x2f\x41\x01\x78\xdb\x71\x74\xb6\x39\x2c\x0e\xe2\x24\x96\x5d\xf3\x40\x8d\xe6\x3a\x14\x41\x5f\x07\xe4\xb5\x80\x3c\xfd\xfc\xba\xa9\x15\x47\x11\x75\xe0\x70\x07\x7e\x1b\x6c\x17\x71\x44\x39\x8a\x65\xa9\x22\xe7\x32\x2d\xf2\x45\x79\xfe\xf7\xb6\xf8\x5f\xee\xae\x29\x8e\x3c\xd1\x3d\x12\x46\x4d\xa7\x45\x6e\xb1\x98\xc6\x3e\xeb\x84\x03\x11\x6a\x34\xbc\x68\x4a\x62\xc4\x40\xa0\x76\xfc\xea\x1e\xab\xd2\x93\x20\x7e\x16\x33\x69\x5c\x02\xef\xb7\xcb\xa5\x55\x78\x77\x57\x91\x84\xac\xb7\xa9\x4d\x31\x37\x9a\x31\x82\x1a\x7d\xda\xbc\x6a\x72\xfa\xba\x90\x45\xd6\x9e\x80\xc4\xae\xc5\x78\xe0\xcd\x86\x9a\xd6\x97\x83\xb8\x1c\xd2\x69\xd6\x4f\xf3\x01\x8a\x6d\xe1\xbc\x70\xc9\x43\x10\xb9\x43\x94\xe0\x9b\x7c\xe4\x9f\x87\xf7\x4e\x2f\x8f\xc5\x09\x4b\x10\x63\x53\x9d\xc5\xcf\xb4\x3c\x57\x77\xa0\xa7\x77\xce\x66\x24\xe6\xdc\xdb\xf5\xc3\xf2\x80\x3d\xf1\xc3\xe3\xea\x69\xbf\xdc\xb6\xa7\xe2\x0a\xfd\x7f\x0f\x27\x7e\x99\x37\x99\xd0\x70\xcf\x8a\x39\x63\x06\x98\xb4\x7a\x5a\xba\xd2\x6c\x2c\xa8\x8f\x91\x9a\xe4\x99\x9c\xa7\xb9\x02\x35\xcf\xd2\x5c\x35\x77\x3d\x88\xc9\x14\x4c\x90\xc5\x42\xa9\xc8\x40\xfb\x5c\xf9\x65\x96\x75\xe1\x46\x2c\x69\xec\xfc\x2b\x8d\xcf\xd3\x19\xb9\xf3\x39\xb6\xab\xdd\x20\x15\x19\xb3\x6a\xa3\xcd\x3f\xdb\x2c\x46\x77\x4f\xc5\x14\xd5\x72\x97\x9f\xbb\x57\xc8\x32\xc4\x73\xb5\xc7\x80\x07\x96\x1c\xd6\xdb\x99\x47\x17\xa9\x74\xc8\x6d\x9a\xf4\x1d\xca\x62\x56\xf5\x7c\x89\x86\x23\x21\x90\xaa\xf3\x27\x74\x3f\xe9\x6a\x31\x37\x1a\xe3\xc8\x92\x73\x3b\x0f\xca\x33\x47\xad\xfc\xde\xc3\x66\x7f\xe3\xde\x41\x64\xb8\xb2\xd5\xf9\x68\x73\x9c\x71\x73\x34\xd6\x01\x41\x3c\xe3\x4c\x29\x43\x05\x1c\x17\x14\x63\x2d\x29\xb4\x06\x1b\x26\x9d\x1a\x00\x5b\x18\xf1\x42\x29\x0d\x3b\x0d\x9b\xcf\x56\xfb\xbf\x3d\xca\x7c\xdf\x96\x3c\xac\x21\xc3\x13\x3f\x42\x07\x6e\x65\xc4\x53\x1e\xb7\x4e\xcc\x6e\x3f\x72\x7c\xcc\xd1\xf2\x45\x42\xa2\xd1\xe9\x08\x9f\x01\x38\x5d\x97\xbd\x49\x44\x14\xb1\xb1\xeb\xd3\xf9\xd8\x93\x7f\x86\x53\x51\xd6\x4f\xc5\xee\xb5\xf8\x18\xe5\xb6\x24\xf6\x02\x6a\x4a\x01\x79\x71\xce\x25\x0c\xe2\x17\x42\x98\xe8\x04\x3a\x2a\x6c\x1f\xdf\x17\xae\xd3\xee\x06\xd1\x20\xf0\x9d\x38\x2c\xf0\x72\xd6\x44\x3a\x5f\x42\x85\x18\x61\xa1\x8f\xef\xe0\x62\xf1\xfd\xb0\xbc\x5b\xed\x1d\xb8\x84\x11\x46\x42\xcc\x97\x96\x3d\x36\x3f\x23\x8c\x12\x94\xeb\xb3\xe6\x39\xe6\xe6\x5f\xb1\x91\xcd\xce\x9c\xb8\x09\x63\xcc\x40\xdb\x67\xae\xf8\x40\x12\x2e\xb9\x5d\x67\x77\x56\xf4\x74\x7a\x61\x21\x89\xa0\xe8\x24\xb0\x7e\x5a\x1e\x1e\x57\x0f\x0f\x5d\x31\x8a\x24\xda\xc7\xc6\xc8\xd1\x38\xe6\x4c\x93\xa4\xec\x58\x11\xf2\x84\xb7\x2e\xac\xef\x9d\xef\x12\x23\x22\x26\x58\x65\xcc\x9a\x3d\xfc\xae\xfd\xab\x48\x12\x3e\xee\x26\x84\xde\xa0\x09\x40\x84\x8e\x31\x20\x42\x8e\xa8\x4a\xaf\xbd\xcb\x07\x2c\xb3\xe9\x32\x3d\x91\x7e\x12\xb2\x56\xb3\x20\xad\xea\x92\x63\x9e\x3c\x7a\xa6\x24\x95\x58\x72\x9f\xa7\xf5\xac\x14\xfd\x10\x95\x48\x69\x18\x72\xe3\xce\xeb\x97\x7b\x1d\x91\x52\x52\xed\x56\x89\xec\xaa\xf0\x4b\x94\xc7\xb0\x01\xb2\xde\x2d\x3b\xaf\x1f\x46\x94\x54\x91\x25\xca\x2f\x2e\x32\x83\x41\x64\x6f\xc7\x00\x4d\x7c\xee\x5e\xb7\xb2\x55\xe8\x6a\x7f\x32\x50\x40\x87\x86\x19\xf2\x20\xbf\x7d\x5b\x4c\x34\x60\x08\xc8\x88\x74\x8f\xfc\x03\xe8\xfa\xae\xe4\x69\x3e\xfe\x2a\x08\x11\x80\xd3\xbc\x12\x06\x1e\xd2\xc2\xd7\x47\x23\x75\x28\x13\x0b\xb8\x1d\xd7\x47\x47\xe0\x84\x1b\x37\x4a\xd3\x10\x77\xd5\x22\x1f\x17\xa6\xa8\x17\x44\x9e\x71\x1b\xd5\x36\xd7\xe2\x23\xb6\x18\xa3\x9e\xa2\x1a\x2c\x0a\xc1\x96\x43\x46\x23\x7c\x29\x50\xd1\xf1\xb1\xc8\xa1\x2e\xc6\x07\x21\xc2\xc6\xf9\x91\xbf\x41\xbf\x50\xb1\x9a\x26\x55\xa0\xe4\x9f\xf3\x71\x78\x5d\x1a\xf8\x7a\xff\xe1\xa5\x3e\x00\x5e\xf3\x66\x61\xd9\xfe\x8c\x06\x89\x0c\xad\x14\x5d\xb3\x0f\x3c\x9f\xae\x05\x2c\x19\x0d\xb8\xe1\x01\x3b\x62\xcc\xf3\xea\x56\xc6\x8b\x86\x64\xb4\xb5\x8e\xc3\x54\x14\xc6\x53\x17\xf1\x10\xf7\x87\x5f\xb3\xd5\xfe\x30\x7f\x58\x2f\x7e\xb8\xce\x2f\x8d\xa4\x32\x10\x1c\x28\x75\x51\x1e\xad\xf2\xc1\xe4\xcd\xa1\x91\x8e\x8d\xf0\xbb\x52\xf6\x91\x1b\xfc\xd8\x38\x89\x51\xff\x7d\xd3\x64\x6a\xdb\xa2\xc9\xd4\x1c\x2e\xb5\xb7\xc4\x33\xcf\x0e\x27\x91\xd1\x34\xaa\xa0\x17\x1d\xdb\x41\x96\xc0\xc5\x28\x49\x0c\x2b\xb8\x82\x1a\x2b\x2e\xee\xb2\x09\x00\xf1\xad\x43\x73\x8f\x1d\x3f\xfc\xd9\x34\x00\x14\xea\x55\x69\x55\x9e\x4f\xed\x67\x69\x4c\x95\x7d\xbb\xea\x6c\x54\xab\xa0\x34\x09\x30\xfa\x76\xc9\x9e\xd1\x69\xb9\x6b\xb5\x04\x9b\x44\x5a\xa1\x7e\xcf\x2c\x6b\x11\xee\x8c\x32\x29\x51\x08\xe4\x71\xf9\xb0\x7e\x3a\xcc\x76\xbb\x65\x7b\xc3\x13\xdf\xc3\x67\x44\x41\x06\x35\x7c\x3f\x09\xac\x90\x0c\x1f\x3c\x41\x13\xcc\xf7\xf1\xde\x3c\xce\x1e\x1e\xfa\x6b\x0f\x15\x89\x87\x65\xb7\xf9\xfa\xf9\x69\xff\x57\x5f\x3c\x82\x51\x21\x19\xea\xbb\x7d\x2f\xb2\xf4\xad\x38\xd5\xd6\x53\x6a\xf0\x79\x49\x8c\x23\x5c\xf5\xc1\x4f\x63\x14\xd3\x17\xdd\x9a\xab\xc5\x74\xf4\xe4\xc9\x04\x30\x2f\xde\xf0\xcb\xaa\x44\x5d\xbf\xf6\x0b\x45\x82\xd5\x06\xab\x28\x89\x55\x8a\x3e\xf8\xce\x0d\x03\x69\x6f\x62\xfe\x0e\x65\x3d\x72\x51\x66\x54\x25\x14\xb7\xf8\xd5\xc3\xfd\x68\xbe\x20\x26\xa8\x62\x2a\xce\x97\x1f\xe9\x71\xf4\x31\xe0\x2c\xb1\xb0\x6c\x0c\xcb\xa6\x38\xa3\xcd\x28\x60\xda\x81\x06\x36\xad\x82\x08\xa3\x3a\x14\xca\xd8\x1f\x64\xfc\xf2\x65\x4b\x71\xf8\xe4\x68\xea\xe3\x3b\xbb\x5f\x3d\x22\xe2\x77\xb1\x5e\xff\x68\xcf\xc9\x0d\x90\xef\x54\xc2\xfb\x7f\x71\xf9\x76\x2a\xea\xea\x01\xf2\x97\x16\x65\xc0\xbc\x88\xa2\x7c\xdd\xf1\x9c\xd5\xe9\x2e\x7d\x31\x90\x8a\x61\x00\xc6\xbc\xc8\x6c\x63\x36\x4d\x43\xf4\xec\xf9\x1a\x57\xc7\x3c\x22\x30\x54\xb7\x13\x3b\xe1\x3e\xce\x58\x40\x55\x0f\xb4\x84\x18\x5f\xf7\x35\x01\xf8\x78\xc8\xd5\x55\xd6\xef\x50\xaa\xf3\x8d\xba\x39\x0b\x63\x83\x18\xb7\x72\x71\x1b\xd3\xb3\x6b\x21\x08\x2c\x8c\x8d\x9d\xa8\xc6\xd7\xfb\x8f\x5e\x94\xc7\x42\x91\x18\x2d\x7e\xa5\x66\x47\xc8\xd5\x71\x0c\x01\x60\x51\x20\x31\x1d\x4f\x4f\xba\xfa\x36\xc6\x08\xb1\x88\x85\xe8\xf7\x6c\x7f\xe7\x63\x65\x18\x51\x96\x0f\xd2\xd6\xe7\x19\x89\x38\xd7\x9d\xe3\x38\x94\xf5\xe5\x3e\xe3\x2f\x7d\x76\x38\x63\x84\x48\xdc\x50\x4f\xc8\x7d\x33\x36\x2f\x77\xeb\xbb\xf6\xee\x0f\xbe\x99\x10\x40\x29\x9b\xc3\x0b\xe4\xd5\x37\x6b\xac\xdb\x7e\x9d\x32\x92\x22\x78\x2f\xc7\x2c\xe3\x71\x27\x92\x51\x42\xbc\xa4\x43\x19\x8e\x01\x8b\x43\x35\x12\xc6\x98\x67\x38\x93\x56\xcc\xf9\x0b\x1b\xd0\xee\x6a\x99\x95\x6c\x6d\x85\x85\x51\x5a\x26\x1f\x69\xb6\x32\xc6\x7d\x6b\x9d\xda\x64\xc6\x57\x0a\x00\xa3\xb1\x89\x16\x71\xcf\x75\x68\xa5\xd6\xda\x3e\xae\xb3\x5c\x0d\x78\x0d\xa3\xab\x11\x71\xe2\xf5\xd9\x40\xf3\xdd\xec\x7e\x79\x6b\x2c\x67\x18\xfd\xb5\x26\x72\xcd\x32\x62\xa4\x31\xdc\x08\x2d\xd1\x03\xe6\xe0\x7e\xdc\xad\x33\x69\xa3\x8f\x8e\xc4\x36\xc7\xaf\x99\xe5\xca\x2a\xf4\x8f\x66\x42\x71\xe6\xe9\xae\x41\xf9\xc4\x47\x3c\x1c\x96\x78\x41\x80\x25\x30\x55\xb6\xc6\x80\x2c\xf1\x14\x11\xd2\x40\x7a\xee\xd2\xea\x74\xae\xa1\x9a\xd5\xa8\xd8\xd0\xe9\xf3\xb0\xc4\x03\x8e\x35\xd4\x4e\x6d\xa1\xe5\xa5\xad\x5b\x56\xfa\x6f\x15\x9b\x58\xe2\x69\xf3\x66\x3d\x14\x12\x6d\xce\xca\x6d\x51\x75\xf9\x4c\xe2\x2b\xe2\x5b\xc3\x56\x0b\x12\xde\xdb\x30\xaf\xb7\xf0\x24\x81\xe7\xa1\x05\xd0\x1e\x3e\xb9\x29\x36\x1e\xff\xb8\x22\x0b\x31\x37\x38\xa1\x18\x9e\x1d\xb8\x63\x86\xee\x26\xba\xd0\x76\x70\x18\x49\xcf\xd0\xfd\x2e\x83\x4e\x65\x0f\xfc\x38\x2a\xb5\x26\xa1\x0e\x50\x2b\x9b\x3b\xda\xf1\x06\x55\xfc\xc6\x40\x44\x3b\x3a\x0a\x02\xdf\x96\x57\x50\x66\xf0\xbe\x28\xbf\xf3\x52\x7d\xf0\x12\xb6\x08\x6e\x74\xbf\x31\x0a\x25\x63\xad\x87\xe7\x2f\xe0\xa7\x22\xc7\x6a\xc1\xf0\x82\x23\xc1\x69\xdf\xda\x75\x7d\x1e\x15\x74\x92\xd8\x17\x71\x8f\xdf\x35\xce\x02\xba\x51\x58\x05\xd6\xcd\x73\xda\x62\xc5\x9b\xe8\xda\x5d\x50\xac\x14\xed\xf2\x91\x73\xc6\x0d\xd6\xb2\xa5\x7b\x75\xef\x7b\x42\x98\xc6\x84\x73\x52\x90\xec\xea\x55\x4f\x48\x92\x20\x82\x73\xc3\xab\xaa\x49\x84\xfb\x81\x40\x42\x04\x41\x86\x19\xe2\xc9\x8b\x67\x5c\xfd\xdc\x31\x1a\xea\xa0\x15\xe9\x6d\x1e\x00\x59\x83\x9a\xac\x68\x24\x14\x98\xc9\xe3\x25\xcf\x78\x89\xc0\xad\xa1\x15\x30\x4b\x98\x4f\x63\x62\x1d\x50\x6d\x60\x3c\xbc\x4e\x16\x4a\x69\xb8\x38\x6d\xab\x15\xf5\xbd\xdd\x7b\x9d\x30\x30\x76\xc3\x46\xe6\x0a\x9a\x89\x74\x87\x92\x80\x12\xdb\x86\x6c\x92\x9a\xe1\x63\x3d\xbc\xd4\x84\x06\xe8\x6e\x98\xc3\xc7\xb6\xc9\x5f\x5b\x51\x38\x96\x24\x3c\xc0\x2b\xe0\x4d\x1c\xb7\x68\x56\xbc\xca\x22\x41\x6e\xa6\x98\x93\xb9\x8c\xb5\xc2\x61\x09\x8f\x63\xb3\x12\x21\x0b\x8e\x57\x30\xc3\xa7\x04\x6d\xd8\x66\xe5\xcb\xb5\xd7\xdc\xf0\x52\x45\x9c\x18\x37\x8d\xd7\xb3\xd6\x19\xa0\x92\xfc\x70\xce\x24\x70\x84\x1f\x8f\xbd\xb4\x0d\x26\x71\x72\x77\x4e\x24\xa8\xa0\xe3\xb1\x0e\x85\x38\x87\x23\x95\x88\x31\xc3\x5d\xe5\xa7\x73\xfb\xa0\x2a\xa5\x11\xf5\x8a\x2d\x8b\x3b\x8c\x60\x47\x35\xe0\x04\x22\x8e\x37\xea\x60\xd1\x3a\x57\x8e\x17\x93\x3f\x97\x7b\xb1\xb0\x6e\xa7\xcd\x49\xbb\xb6\xf9\x1f\xe3\x61\x12\x1b\x77\x28\x42\x5b\x16\x33\x9c\xd1\x0d\x7f\xc1\x8a\x5f\xd1\xeb\x66\x70\x8f\x51\xdf\xc6\x84\x7f\x36\xe7\x98\x5e\x95\xb8\x27\x34\x0a\xe4\xdc\x17\x25\xbc\x43\x69\x00\x2d\xee\x18\xf8\x46\x57\xc9\xd4\xee\x7f\xe4\x85\x7c\x2b\xce\xf5\xa6\x48\x1d\xbc\x64\xa0\xdb\x3e\xf1\xff\xbd\xeb\xf1\xbd\x04\x1b\x3e\x0e\xa2\xf0\xeb\x15\xf2\xfb\xa2\x7c\x6b\x1f\x71\xee\x33\x0f\x29\x85\xab\xc5\xfa\xa9\x68\xb5\xc5\xba\xc3\x22\xc4\xcc\x0e\x2b\xb2\xeb\xcd\x72\x3b\xdb\x3b\xc5\x1e\xc6\x7d\xf0\x91\xf3\xe4\x1c\xf5\xb1\x44\x70\x03\x02\xc3\x03\x62\x5c\xb4\x4f\xfc\xb2\x80\xc2\x9d\x22\x48\x78\xec\xd8\x25\xd6\x69\xf1\x2e\xad\x8a\x8f\xfc\xa9\xa8\xfb\xca\x23\xed\x78\x1d\x23\x66\x7e\x5f\x3c\xb4\xae\x5f\x8c\x87\x9e\x36\x7a\xb1\x4d\x1c\x6d\xde\x44\xd3\x15\x6d\x07\x04\x01\xc2\x5c\xf1\x4a\x17\x85\xbb\xcd\xee\x68\x28\x5c\xc6\xfe\x2d\x2b\x04\xcf\x16\x45\x5e\xa1\xb0\xcd\x18\x03\xf3\xff\xa6\x5f\x46\x77\x9e\x48\x0f\x28\xc6\x7d\x7f\x60\x37\x84\x80\x6b\x9c\xa2\x14\x0b\x2e\x5c\x8e\x3e\xd3\xbb\x71\x51\x00\xc8\xb3\x7f\x87\xd2\xf4\xa9\xbb\x4a\xa8\x81\xcc\x3c\x76\x69\x94\xfd\x48\x9c\xc4\x3c\xee\xec\x6c\x9d\xc4\x47\xfa\xef\x1e\x19\x8f\x71\xc2\x89\x34\xec\x99\x7d\xab\xdd\xd7\xef\xa4\x73\x1a\x72\x6d\x6b\x3a\x58\x58\x1c\x2d\x9a\x9c\x4a\x03\xe1\xa9\x2c\x37\x6b\x48\x1c\x63\xbc\x49\x42\xd0\x7a\x79\x33\xc0\x5f\x70\x96\x04\xd2\xc2\xad\xe6\x97\x8c\x7f\x54\x0b\x4b\xcf\xfb\x59\xd4\xb0\x45\xe3\x57\x50\x77\xe7\x72\x70\xb5\x09\x87\xc8\x58\xf4\x1e\x79\x8a\xfb\x58\x2b\xf6\xc6\x78\xd2\x84\x53\xf8\x53\x0e\x47\xfe\x79\x78\x29\x78\x76\x28\xfb\xbe\x02\x8c\x0b\x5f\x52\x9b\xdf\x37\x5f\xf5\x82\x5d\x37\x74\x54\xfb\x63\xa2\xd5\xcf\x25\x4f\x9c\x46\xed\xd0\xd6\x95\x71\xa9\x28\x77\x4a\xab\xbc\x1a\x60\xe9\xb9\xf2\xbc\xc8\x46\x5c\x1d\xd1\xba\x13\x8d\x66\x5c\x05\xda\xb7\xe7\x4d\x47\x4b\x17\xd7\x24\x48\x0c\x28\x3c\xcf\xa1\xbc\x03\x99\xaa\x9e\x15\x31\x13\x9e\x07\x60\x5b\x34\xf7\xcd\x5b\x6c\x94\xd4\xdc\x41\x5f\x23\x26\x02\x1f\xfc\x4e\xd2\xba\x5a\x55\xd5\xb9\x9d\x05\xe1\x45\x86\xbc\xb6\x6b\x36\xe3\xb4\x1a\xec\xc7\xc2\xa3\x0c\xc3\x1d\xa3\x85\xb3\xff\x28\x26\xb4\x70\x98\xf0\xc1\x23\xbc\xcb\xfa\xfa\xa0\x78\x11\x84\x1c\x1b\x3f\xcd\xc6\x86\x68\xc1\x65\x55\x77\x99\x88\x08\x63\xa0\xd8\x74\xe6\xef\xb0\x05\xe3\x10\x32\xd1\xb5\x14\xa1\xd2\xc8\x5b\x7f\xe2\x47\x84\x1a\x0c\xa6\x49\x44\x3e\x45\xe9\x3a\xa3\x20\xfb\x0d\xea\x99\x6a\xd2\xad\xb4\x82\xe3\xd8\x6c\x86\x89\x38\xa2\xd0\x2f\xa0\x18\x2a\x09\x2a\x0f\x4e\xbe\xb9\x82\x2a\x63\x23\xbd\xe1\x97\xfb\xa2\x6c\xf3\xb2\xee\x8c\x89\xa7\xa1\x05\x66\xad\x07\xbd\x80\xff\x0e\xbb\x76\x7d\xef\x3f\x83\xff\xe9\x2d\xc4\x22\xe1\x81\xea\x0c\x80\xac\xaa\xdc\xf0\x1a\x12\x6b\x63\xd3\xba\x4f\x98\xae\xfb\xf4\x9e\x2a\x78\x10\x21\x0e\x57\xf2\x7c\x77\xc9\xeb\x57\xa8\x9a\xe5\x3d\xad\xaf\x0c\x1c\xdd\x78\x42\x89\x72\x81\x78\x5d\x5e\x6e\x0c\x13\x32\xa2\x76\x29\xb4\x5a\x31\x93\x8d\xe6\xe1\x9d\x93\x3c\xf2\x3b\x23\xc9\x1d\x40\x3e\x19\xb3\x09\xa9\x85\xb0\xb8\xaa\xf4\x68\x01\x8c\xd5\x1c\x74\x61\x52\x2a\xf7\xc0\xa8\x30\xee\x37\x82\x07\x7b\xa8\x1f\xb0\x7e\x9a\xd9\x3e\x9f\x2a\x26\xf8\x78\xc8\x22\xd7\x69\x79\xec\xc5\x58\x42\x69\xa2\x63\x17\xc4\xad\x14\xc2\x2a\xdb\xf7\x5a\x40\x10\x20\x20\x44\x17\xa5\x86\x74\x00\xdf\x76\x23\xa8\x24\xce\xd4\x09\x9b\x45\x43\x94\x8d\x00\xaa\x34\xed\xda\xd3\x98\x66\xb4\x2f\xa8\xf6\x22\x94\x92\x90\x19\xf0\xf2\x39\x6f\x82\x4b\x17\xe0\x4d\xdf\x00\xad\x05\x16\x1b\x8f\xa8\x57\xbc\xb5\xfe\x13\xc3\x89\x94\x1e\x35\x35\x98\xf7\xa2\x86\xb2\xea\x03\x45\xa5\xc7\x08\x62\xc3\x0e\x46\x50\x60\x0b\xff\x6a\x8f\x08\x91\x44\x2d\xe7\x8a\xe7\xe3\x7c\x53\xfa\x84\x31\xa3\xdb\x50\xc0\x9b\x5b\x1f\x64\xe0\x49\xcf\x73\x02\x03\x3d\x7b\xfa\xc1\x65\xcb\x20\x64\xd8\xbe\xa9\xe4\x2b\x64\x59\x9a\xbf\xdc\xcd\xdd\x09\x42\x5f\x60\x4c\xc4\x95\x1a\x18\x43\x8d\xea\x7c\x13\x0f\x96\x0c\x13\x89\x30\xe4\x59\x7e\x16\x69\xdf\x92\x89\xc9\xd8\x27\xc8\xb5\x48\xf3\x4e\x9e\x63\x10\x12\x47\x6e\xa0\xb5\x77\x36\x06\x71\x75\xb3\xdd\x7e\xd6\x25\xef\xa8\x3d\xad\xbc\xab\xfb\x00\x31\xba\x9c\x7d\xba\x4b\x35\xbf\x0c\xc2\x7f\x49\x88\xc0\xa6\xca\x01\x2b\xc2\x43\x8f\xb0\xe1\xcc\x90\xc4\xe0\xdb\xee\x96\xf7\xb3\xe7\x87\xfd\xe1\x69\xd6\xe2\xaf\x24\xe1\x11\x71\x30\x2a\x7e\x29\xce\x75\x1f\xae\xdc\x02\x20\x24\x01\x4a\xbc\x7e\x03\xcc\x1d\xa0\x51\xcc\xac\xd7\xb0\xc9\x80\xe6\x97\x95\xea\x01\x8a\xec\x30\x16\x72\x5c\xff\x37\xdb\xd5\xcf\xd9\x7e\x79\xd8\xcd\x1e\xda\x4b\x60\x42\x61\xa3\xef\xdb\x6a\xb1\x1f\xe8\xa9\x33\x99\xd8\xb2\xfc\x4b\xab\xef\xba\xe0\x59\xd6\x6d\x4d\x32\xd1\xdc\xe8\xc4\x22\xa1\xc5\x84\x11\x43\x0d\x55\x3b\x90\x13\x82\xb3\xd5\x12\xdd\x07\x8d\x70\x29\x7c\xb3\x38\xa6\xd5\x96\xe7\xaa\xb0\x0a\xba\xed\xd1\xc0\x88\xb5\x19\xd1\xde\xe6\x77\x22\xe5\xa0\xbd\x0a\xc1\x63\xcc\x2e\xf6\xc0\x8f\xb3\x5c\x39\x17\xe0\xde\xa3\x3a\x7c\xcc\x85\x08\x50\xaf\x0a\xd3\x89\x76\x93\x94\x02\xb4\xa1\x7f\xe7\xe9\xb4\x1b\xd3\xf0\x2c\x32\x08\xb0\x9c\x35\x4f\x45\x31\x78\x30\x65\x60\x08\x12\x3f\x31\x72\x03\xf5\xe3\xaf\xc5\xe8\x02\x24\xa1\xc8\x8a\x50\xe7\xe3\x69\x92\x2f\x27\x95\x36\x52\xc7\x26\x61\x5a\x34\x6b\xda\xb0\x50\x28\x21\xa2\xb8\x1f\x2f\x37\x06\x88\x3f\xa5\x15\x3d\x5c\x59\x24\x68\xe3\x7a\xd5\x4a\x82\xb5\x33\xa8\x89\x52\x61\x9b\x06\x39\x7c\xd3\xb4\x39\x79\xfb\x11\xd3\x38\xf9\xd7\x19\xca\xcb\xd3\x80\x69\xea\x46\xf0\x28\xb2\xba\xc7\xf7\xbb\xfd\x6d\x37\x54\xa6\x3c\xab\xd1\x75\x78\x71\x52\x23\xd6\x20\xaf\x7d\x03\x94\x47\xc3\xd8\x46\x5f\x76\xf9\xec\x39\x32\x32\xe5\x71\x22\x2d\x10\x62\x6e\x14\x53\xbb\xbb\x6f\xb1\x35\xa3\xaf\x14\x46\x39\x34\xad\x9e\x8a\xfc\x9f\x50\x16\x93\xd8\x19\xe5\x29\xf0\x6c\x9d\xd3\x3c\x93\xfb\xc2\x68\x8d\xdc\xf8\x25\x7e\xec\x1b\x28\x12\x4a\xed\xa5\x50\xb9\xb2\xbf\x3d\x1e\x44\x0c\x0b\x23\xdf\x8c\x51\x1b\x94\xf3\xb1\xdb\x37\x53\x01\x84\xc2\xa1\x55\x6c\x1b\xe5\x17\xa4\xa3\x41\xa1\x27\x2d\xea\xb0\x09\x1a\x91\x5c\xeb\xbe\x23\xf4\x8d\x2e\xdc\x6c\xb5\x75\xf2\x56\x4c\x85\xb1\x46\x6e\x25\xcf\xe5\x6b\x6b\x09\xc8\x54\xe4\x47\xc8\x72\xe2\xa7\x53\x76\xb1\xc2\xf0\xd5\xb0\x9a\xff\x9f\x41\xe5\x54\xc4\x62\x6c\x22\xa9\xb4\xb2\xf5\xa9\xe7\x0a\xca\xab\x77\x40\x45\x92\x1b\x31\x5f\x5e\x55\x70\x14\xd9\x65\x92\x53\xdd\x7b\x9e\x54\x04\x2e\x2a\x30\x85\x8d\xb5\xd6\x15\xcf\x0c\x4b\x62\x7e\x59\xe7\xed\xc3\x10\x7b\x3e\xbe\x3c\xeb\x4b\x55\x43\xb9\x69\x1e\xf7\xf6\x10\xf7\x85\x63\xaa\xde\x97\xc5\x71\x25\x8b\xf6\x90\x56\x92\xbb\xf2\x7c\xd7\x54\x53\x44\x02\xee\x06\x73\xa8\x77\x50\xcf\xf2\xea\xe3\x77\x44\x33\x45\x14\x03\x65\xb9\xbc\xd8\x8e\xb0\x4e\xd9\xee\x94\xd4\x33\x1a\x41\xcd\x06\xb3\x05\x0d\x65\xec\x7d\xc6\x5e\x7b\xd4\x82\x45\xc1\x82\xff\x9a\xeb\x9c\x65\x35\x6f\x1f\x22\x1a\xc6\x81\x4b\x21\x9b\xe7\xe3\x79\xbb\x1a\x35\xd4\xdc\xc0\x28\xc6\xdd\x65\xf7\x5a\x7c\x5c\x49\x0c\x33\x45\x89\xd1\xbb\x78\xbc\xf0\xaa\x7e\x85\x3c\xe5\x2f\x25\x7f\x4f\xdb\x87\x83\x32\x8d\xc2\xd8\x55\x91\x35\x79\x59\x9a\x1b\x2b\xcc\x1e\x21\x41\x31\xae\x30\x99\x74\xa5\xe3\x29\xb6\xcd\x68\x72\x98\xa2\x48\x82\xfc\x99\xa5\x3d\xea\xbe\xe2\x81\x8f\x5a\xa6\xbb\xe5\xa2\x85\xad\xb7\xc7\x98\x8f\x6c\x25\xf4\x17\x6e\x42\x1e\x1b\xdb\xf4\xf2\x65\xc5\x39\xc3\x48\xc1\xc4\xd7\xff\x55\x5c\xaa\x62\x2a\xc8\x56\x5c\x8a\xc8\x32\x76\x1e\x0a\xf9\xb6\x29\xaa\xaf\xb4\x67\x6f\x3c\xe4\xc2\xa7\xb8\xf6\x37\xaf\x28\x3f\x67\xe8\x57\xf7\xef\x36\x29\x53\x92\x70\x9c\x38\x95\xbe\xff\x79\x63\x16\x24\x13\x51\xe4\x80\x13\xcd\x4a\x87\xad\x0a\x7b\x50\x79\x01\x16\x6d\xcc\x6f\x31\x9e\xf9\xa5\x31\xc0\xb9\xfc\xd1\x8f\x7a\x95\xf2\x8c\x2b\x85\xd9\x1a\xd7\xfa\xa1\xa8\xeb\xf6\x89\x56\x91\xa0\xb6\xf4\x8e\x2f\x89\x81\xc2\xf6\xf7\x2a\x05\x91\x0e\xfb\x75\x5d\x73\x83\x75\x51\xb2\xe0\x16\x64\xd6\x7d\x32\x09\xac\x62\xbd\xd1\x70\xe2\xf8\x3e\x6d\x8a\xb2\xd6\x45\x96\x16\x37\x7e\x36\x48\x82\xf4\x96\xed\xf2\xdb\xf3\xc3\x6c\x7b\xd8\xb6\xae\x75\x4c\x81\xd2\xa1\xe7\xea\x03\x3b\xf9\x5a\x14\x57\xc0\x16\x3b\x52\x87\xca\xb3\x23\x9f\x8a\x7a\xd4\x3c\x57\x9a\x50\x69\x94\x5a\xde\x81\x67\xd6\x5c\x7b\x70\x02\xf0\x3c\x88\x23\x07\x12\xca\xb2\x5f\x69\xae\x8a\x8f\x1e\x54\x08\xbc\x40\x20\xc5\x98\x8b\x26\x1e\xc9\x77\x4d\xe2\xe8\x0e\x25\x21\x3e\xa8\x88\x70\xfc\xd6\x3d\x5f\x83\x57\x0f\x3c\x2d\x50\x52\xa2\x75\xc0\xb3\x11\xcf\xa0\x6f\x0e\x7e\xa0\xb0\x2c\x60\xb6\xf9\x59\x9e\x1e\x7b\x60\x9e\x89\x78\x18\xfc\xd8\x43\x1a\x59\x9a\xeb\xa2\x07\x5d\x1c\xfe\x3a\x9f\x87\xb8\x35\x3f\xa4\xef\x70\x02\xdb\x8b\xbf\xe7\x67\x09\x57\xf0\x8d\xf1\x27\x45\xe4\xdb\x89\xed\x79\x29\x35\x7f\x37\xd4\x99\xaa\x2e\x4e\xe8\xb3\xd7\x2b\xd1\x40\x10\x2a\x34\x54\x1e\x74\xc7\xe2\xf6\x68\x4c\x71\xba\x64\x4f\x3f\xf4\xc9\x49\x51\x33\x08\xfd\x88\x07\xc3\x2e\x54\x91\x1b\xd5\xb9\x3e\xd9\x06\x42\xe2\xcc\xca\x79\x35\x3b\xa5\x9b\xb2\xd0\xe9\xa8\x31\x0d\xa1\xf2\x95\x85\x4c\xfe\x4a\x73\xe8\x94\xa5\x3b\x13\x46\x06\x91\x17\x9b\x57\x17\xdf\x2d\x8c\xd1\x46\xc9\x15\x44\x14\x10\xed\xfd\x50\x14\x03\x8e\x1d\x44\x3a\x66\x0e\x5c\xf8\x36\x06\x28\x41\x1c\x50\xf7\xf5\xae\x25\x33\xc8\xcc\x20\x0e\x74\xc2\x7b\x1b\x98\x85\xe6\x8f\xce\x12\xc9\xd8\xc2\x13\x67\xd5\xbe\x15\xde\x64\x40\x7c\x13\xf0\x1d\x50\x21\xe2\xf3\x32\x7c\xea\x81\x86\x0a\xdd\x65\x5e\x79\xb5\x3e\xd7\x55\xcd\x51\x9b\xb3\x15\xb4\x6e\x27\x89\x12\xc0\x08\x44\x9c\x2f\xfd\x08\x0a\x28\x70\xab\x82\x8b\x18\x0a\xd7\xff\x19\x37\x8a\xa1\xc9\xa7\xb4\xad\xd7\x22\x04\x6b\x0b\xd0\xac\xd6\xdd\xcf\x64\x3a\x24\xb6\x27\xfb\x57\x71\x2e\x8d\xd9\xa2\xc1\xb6\x0e\xe7\x99\xfb\x06\xae\xd2\x4c\x87\xcd\x72\xff\x06\x8c\x0e\x78\xac\x65\xaf\x12\x65\xba\x7a\xee\x18\x89\x31\x0b\x3d\xa0\x3b\xc3\x5a\x77\x15\x60\xe0\x92\x63\xf6\x9b\xe6\x3f\xd2\xaa\x9a\xef\x17\xa3\x89\xe7\xda\x77\x8d\xca\x79\xb3\xf4\x4c\x7f\xb9\xf0\x3d\x24\x49\x2f\x9c\x11\xb0\x01\x46\x8e\x1d\x3d\x18\xc8\x30\x72\x49\x2f\x2a\x87\x8c\x9d\x44\x86\xd2\x2c\xee\x43\x89\x97\xb4\x0e\xcd\x07\xd5\xdf\x4c\xdd\x08\xe5\x23\xbe\x19\x85\xe9\x8f\xe9\xe7\xd0\x3c\xd3\xf9\x4a\xdb\xc1\x4a\x26\x72\xd8\xe2\x75\x4c\x2c\x3b\x40\x47\x02\xdb\xc7\xe6\xfb\xd2\xe2\xdc\x3a\x0e\xa9\x76\x48\x2c\xf0\xb9\x9a\x9f\x2f\xab\x1a\x8e\xa3\xd5\xc9\x0c\xd2\x5e\xc8\x10\x8d\x64\xf3\xd3\x96\xc4\x3b\x98\x12\xed\x45\x7e\x60\x1b\xa0\xb8\x0c\x58\x0c\xca\x68\x94\x1f\xfa\xe8\x34\xff\xb8\x7a\xda\x1f\x5a\xdf\x50\xa6\x7d\x70\xaa\x0f\x56\x4a\xba\x32\xcb\x76\x4f\x30\x95\xe9\xc0\x0b\x31\xfa\x5c\x9c\x4b\x5e\xf7\xda\x06\x3a\x08\x8c\xb7\xd3\x7d\x3a\xb0\xa6\x67\x3a\x08\x79\xcf\xb8\xfa\x96\x5a\xe5\x2d\x49\x24\x1d\xc4\xd2\xd5\xa7\x8b\x77\xc0\xaf\x1d\xa3\xfd\x74\xc0\x62\x8a\x74\xfe\x2c\x85\xdc\x48\xf6\x9b\x3a\x48\x7f\x31\xbe\x41\x72\xd1\x01\xd7\x21\x6f\xaf\xaf\xad\x4e\xb5\x10\xb5\x29\xde\x85\x0e\x7d\xc9\x02\x47\x34\x0b\xd6\x7a\x34\xc5\x61\xa0\x9c\x0b\xce\x82\xd7\xff\x9f\xb2\x2f\x69\x6e\x1c\xc7\xf2\xff\x2e\x73\xaa\x43\x1d\x08\xee\xf8\xdf\x24\x59\x76\x6a\xd2\x5b\x4b\xca\xcc\xaa\xe9\xe8\x50\x3c\x00\x0f\x36\xc7\x14\xa9\x26\x29\x3b\xd5\x9f\xfe\x1f\x7c\x00\xb8\x89\xce\xaa\xc9\x4b\x46\x98\x10\x45\x91\x20\xf0\x96\xdf\x62\x95\xfb\xac\xe5\xae\x1b\x22\xd2\x0e\xd8\x49\x3e\xa7\x53\x5d\xa7\x7f\xfe\xeb\xf7\x71\x91\x41\x07\x32\xa4\x15\x64\xb5\x7d\xfa\x71\x43\x52\xc4\x3f\xd6\x9b\xe1\x13\x0c\xfd\x80\x78\xb8\x22\x6b\xea\x63\x96\x8f\x9f\x43\xd8\xa6\x3d\xa6\x3b\x54\x9e\x1b\x97\x82\x76\xd7\x13\x86\xa6\x06\x67\x3a\xf1\x9d\x43\xe8\x76\x88\xf8\xd2\xa1\x60\xf4\x05\xed\x1c\x7c\xaa\x40\xf6\x8f\x3f\xd4\x66\xd5\xfa\xfa\x0a\x59\x75\xce\xb7\x70\x04\xf5\x0a\xdd\x97\x47\xbe\x24\x4b\x42\xb2\xc2\xa5\x66\xdc\x97\xc7\x0f\xd6\x1d\x45\x34\x6e\xd5\x27\xf8\x28\xb2\xe2\x65\x9c\xd3\xe9\x98\x03\x9a\x4c\x46\xa9\xd5\x6b\x96\xab\x7d\xf9\x0c\xed\x5e\x37\xbf\x84\xe8\x58\x26\x68\xda\x34\x1a\x2b\x6c\xb3\xed\xac\x81\x91\x2e\x9d\x1b\xa8\x35\x95\x34\x8d\x2f\xca\x5f\xb8\xc4\xd9\xcf\x24\xbe\xf1\xc7\x59\x3d\x75\xba\x3a\x3a\x11\xc6\xf4\xe5\xdb\x72\xd4\x90\xd1\x29\xe3\x81\x91\x70\xec\xcd\xb3\x6f\xb3\x9f\x03\x84\xc4\xa4\x8e\xa4\xd3\x24\xe4\x36\x78\x6e\xf7\x54\x6a\x47\x50\xf8\xea\x4f\x66\x58\xaa\x91\x94\x87\x41\x1a\xf1\xbd\xba\x79\xf8\x73\x39\x19\xc3\x63\x49\x33\x7b\x21\xca\x73\xf3\x15\xf3\xf7\x2e\x19\xd0\x3c\xf1\xe9\x71\x59\xb5\x9b\xa1\xca\x9d\x86\xd8\xb0\xbe\x05\x34\xf2\xb5\x93\xff\xd8\x7f\xf9\xdc\x2d\x3a\xd5\x00\x1c\xd8\x20\xda\xbe\x76\x94\x4b\x35\x08\x45\x97\x73\xb3\x78\xea\xbe\x4a\x47\xa4\x3d\xb9\x5f\xd6\x98\xbb\x1c\x52\x0b\x0f\x64\x57\x4e\xb6\xa8\xab\xac\x2c\xcc\x2b\xed\xc6\xf8\x48\x7b\x54\x9b\xac\xec\x9a\xf2\x74\xea\x16\x54\x2d\x7d\x24\x40\xca\x9d\x61\xc0\x53\xd4\x39\xbe\x12\x19\x19\x55\x88\x8f\xa9\x8a\xeb\xe4\x59\x4b\xc9\x03\x9c\x9a\x59\x4d\x31\x0e\x5a\x89\x80\xaa\x5d\xdb\xf5\xd3\xca\x5d\x83\xd2\x2a\xc5\x2e\x08\x7a\x80\x3c\x97\xce\x2e\x71\xb6\x70\xaf\xd1\x17\x14\x12\x3d\x96\x4d\xa6\x33\x6a\x58\x93\xf3\xe5\x6c\x6b\x42\x6b\xc6\x68\x4d\xb5\x3b\xf4\x15\xe1\xb8\x1b\x26\x80\x75\xb8\x6f\x87\x5f\xeb\x6e\x94\x4e\x3d\x6a\xc9\x10\x0e\xcc\xea\xbf\x0d\x4f\xc0\x3d\x2f\xf0\xa4\x81\xca\x9c\xeb\x06\x55\x97\x37\xd6\xd3\x71\x92\x13\xd0\x65\x27\xcf\xaa\x5c\x75\x5c\x10\xee\xb1\x20\x8a\x8d\xd1\x2e\x09\x9d\xcc\x44\xf2\xdc\x63\x31\xa3\x37\x8a\x2e\xe3\x53\x1e\x61\x5f\xa8\xe0\x1e\x13\xc6\x93\xe1\xcf\xed\x1f\xee\x8b\xfc\x76\x1f\x6d\x27\x6d\xfb\x26\xf7\x18\x1c\xee\x05\x41\x40\x39\x78\x9b\x54\xd7\x37\x08\x2a\xcf\x5c\x21\x83\x7b\x41\x94\x52\x38\x60\x0b\x29\x03\xb6\x3f\xf7\x82\x24\xa4\x02\xd6\x0e\x9b\x1a\x65\x59\xa8\xfd\x1e\x7e\x8e\xf5\x1c\xdd\xc8\x34\x26\xf4\x9a\x82\x2c\xbf\x58\x52\x6d\x77\x16\x30\x04\xbd\x36\x91\xb5\x87\x46\xf0\x35\x37\x4c\xfa\x54\x7a\xa1\x55\xfd\x61\xf1\x47\xbf\xaa\x73\x2f\x8c\x3d\xd2\x4f\xa3\x0e\xdb\xd7\x2c\xcf\x27\x9f\x0d\xd3\x90\x38\x4a\xef\x06\x14\xf9\x39\x3a\x8e\x7b\x21\x18\x29\x7b\xdb\xc0\x56\x37\x70\xa9\xbb\xaf\x41\x96\x84\x4e\xa5\x76\x90\x1a\xb4\x47\x14\x7d\x6a\x8b\xa7\xf3\x50\x77\x96\x7b\x91\x67\x78\xd2\x77\x50\x2f\xcf\x97\xee\xaf\x22\xa1\x2d\x3b\x2f\x5f\xbe\x65\x57\x77\x2b\x66\x40\x89\xdb\x22\x6f\xba\xba\x6a\x1b\xbe\x8d\x7f\x54\x6c\x4b\x30\x0f\x8b\xc7\xc5\xdd\xba\xbd\x1d\x87\xe7\xf5\xf6\xb0\x7d\xfa\xf6\x78\xe3\xbe\x27\xd6\x21\x93\x4e\xdc\xe5\x1d\xf3\xf2\x34\xf1\xb8\x68\x87\xa4\xa4\x58\xbd\xb6\x11\xf4\xf8\x68\x12\x9b\x45\x64\xf3\xe5\x3c\xa4\x81\x70\x2f\x65\x31\xa9\xd2\x2e\x33\xe2\x8a\xef\xb2\xbc\xeb\x53\x73\x2f\x15\x3e\x4d\x35\xd3\x27\x75\x0b\xe4\xe8\xb6\x5f\xad\x90\xdc\x4b\x55\x40\x49\xdc\xe2\x61\xbd\x1c\x7d\x17\x67\xd2\x5a\x8f\xd4\x58\x35\xf7\xf0\x71\xf9\x44\x97\x93\x7b\x3c\x8d\x95\x72\x72\x33\x1f\xd6\x1d\x60\x76\x4a\x72\xd0\x54\x20\x7b\x85\x59\x4b\x30\xee\x71\xc5\x28\x2d\xb4\x51\x19\xd6\x03\x5e\x1d\xf7\x20\x06\x22\x8c\xec\x56\x87\x9c\x44\x3e\xbb\x03\x98\x90\x42\x1c\x35\xdb\xfe\xa7\xbc\x69\x67\xbc\xa1\xad\xd8\x01\x32\x0a\xd3\xc8\x68\xfa\xfc\xbc\x3c\x60\xf5\x42\xec\x2b\x7f\xaa\x63\x30\xc9\x7a\xb8\x27\x93\x08\xed\x4f\xeb\x70\x4f\xa8\xc6\xc6\xd1\xbf\x8f\x9f\x9e\x4c\x75\xd2\x2b\x1c\x0e\x72\x2d\xee\x49\x08\xb4\xee\x16\xbe\x7d\xb9\x44\x5b\xad\xee\x7f\x89\x94\x91\x71\x99\x3b\x5f\x48\x28\xcd\x64\xcf\xd7\xf6\xdb\xdc\x53\xb1\x56\xfe\x80\x89\x58\x41\x21\x5f\x71\x3a\x08\x8d\x20\x4b\x4d\xa2\x9b\x5b\x34\x3c\x41\x7a\xd0\xc3\x1b\x8b\x2c\x31\x8a\x2a\xa6\x76\xb2\xcc\xa7\x49\x5b\x3b\x44\x5a\xb4\x82\x81\xb8\xec\x1a\x3c\x75\x1f\xf7\x39\xfd\xe4\xfa\x2c\x8e\x59\xd3\xdf\x20\x77\x38\x61\x14\x6f\x74\x00\xe0\xf9\x72\x6f\x38\x8a\x97\xb8\x87\xa9\x07\x1d\x67\x9d\xc6\x3f\xe9\x39\xce\x26\xf7\x50\x59\x9e\x29\xf9\xc8\xd3\x26\xbf\x93\xaf\x78\x9c\xde\x0d\x54\x40\xd8\xfc\xdb\x0a\xf1\x3f\x63\x53\x25\xee\xe9\x40\x9b\xbe\xba\x81\x5f\x6d\xb1\x3e\x95\x45\x8d\x3b\x5a\x64\xbf\x40\xae\x47\x45\x29\xe6\xce\xa9\x43\xe6\x8a\xb2\x84\xf7\x1f\xf7\xee\xdd\x20\x08\x03\xab\xbb\x7c\x7f\xff\xdd\x50\xcd\xd8\x10\x3d\xc3\x19\xf3\x14\xc1\xb1\x9c\x9d\xc7\xfa\xf1\x86\x14\x1b\x76\xfb\xc5\x83\x5b\x73\x19\x8b\x7d\x25\x9c\x3c\xf2\xc4\x78\xbc\x3d\x1a\x50\x75\x0b\xab\xaa\xac\x16\x85\xb2\x74\x9a\xf1\xd7\x70\x9f\x7b\x4e\xe6\xff\x72\x6a\x4a\x95\xc1\xb1\x2c\xd4\xf8\x66\x30\x3f\x4a\xc0\x4e\x2e\xd3\xfe\xbc\x87\x42\x4d\xb6\x57\x16\x04\xa9\xe7\xda\x37\x43\x8a\xd0\xe8\x31\xb2\x40\x49\x5a\xb4\x16\xeb\xdb\xe1\x02\xc3\x42\x2f\x48\xc1\xe1\x6a\x8a\xb7\x6d\x99\xe7\x77\x55\xf9\xd1\xbc\xde\x96\x55\x9b\xee\x4c\xfa\x23\x9c\x85\x0c\x08\x43\x9d\x69\x7d\xee\xcf\xe2\x0b\x83\x5b\x1c\xa8\xd4\x8d\x96\x14\x16\x85\x26\x84\x59\x6c\xbf\xba\x0f\xc5\x7e\x40\x01\x14\x2d\x11\x63\x39\xbe\x39\x6b\x4d\xf7\xa9\xd8\xe0\x9b\x9c\x70\xe6\xc4\x16\x93\xb3\x38\x49\x09\xe2\x75\x5f\xbe\x98\x5b\xbf\xde\x7f\x99\x5f\x32\x59\x2c\x03\x6a\xe3\x14\x14\xbf\xad\x9b\x57\x83\xf8\xef\x4e\x95\x48\x49\xbd\xeb\x2f\x65\xf1\x72\xc4\x79\x79\x9e\x61\xf7\xdc\x7e\x2c\xe5\x7e\xe4\xa8\x7b\x14\xb6\x7c\xc2\x7b\xb3\xc3\xb9\x60\xb2\x2b\x14\x53\x87\xbc\x5e\x5e\xb6\x50\xbc\x5d\xbf\xa1\xf3\xb7\x84\x4b\x2e\x2d\x50\xfd\xae\xcc\xd5\x12\xda\x45\x79\x79\x59\x83\x7c\x1d\x3d\x6b\x08\x04\x71\x3a\x16\xdb\xd5\xcd\xe1\xf6\xdb\xe3\xcd\xe1\x66\xfd\xfc\xb4\x73\x05\x51\xce\x80\x6b\x52\x24\xa4\xde\xc7\x17\xa8\x97\x88\x85\x41\x51\xa3\xda\x97\x93\xac\x90\x33\x11\x47\x9e\xf3\xa4\xda\x28\x2c\x6c\x70\x3a\x58\x74\x98\x90\x60\x9d\xbd\x9b\xf3\xe9\xaf\x74\x9f\xfe\x4a\x1e\xc2\xed\x07\x4c\x72\x40\xbb\xd2\xf4\xa5\x32\x1a\x14\xf6\x63\xa4\x4f\x5e\x68\x7d\xf5\x65\xb3\x7a\x9a\x61\xc1\x70\xa6\x12\xe3\xcc\x63\xe4\x1e\x8e\x65\x41\x2b\xc8\x2f\x95\x36\x38\x53\x2a\x12\xb1\xb5\x8c\x25\xbf\xe0\xae\x76\x73\x80\xe6\x90\x7d\x4a\x7d\xe0\x0c\x3d\x16\x70\xbb\xc2\xe5\xd8\xe0\x7f\x97\xe2\xb7\xf1\x84\xc0\x30\x31\xfe\xf4\x65\x56\x0c\xaa\x2c\xf3\x55\x69\xce\x30\x35\xf1\x88\x3c\x1c\xe1\x67\x0f\xec\xd9\x95\xb9\xdb\xcf\x18\x6a\x53\x1c\xa0\xa8\xa4\x7e\x75\x62\x12\x96\x62\xc7\x99\x8e\x13\x32\x5c\xb4\xfc\xf4\x7f\x7c\xdb\x5c\x33\x12\x39\xd3\x10\x81\xe9\xb9\x17\x50\x5d\xc6\x28\xac\x4f\x6e\x93\x46\xa0\x7b\xfb\xf0\xf0\x77\x5f\x1e\xad\x95\xe9\x5b\x5b\xbe\xf2\xa8\x31\x39\xa7\x15\x34\x86\xb1\x8c\xae\xd8\xf7\x38\x06\x41\xe7\x11\xf7\xa4\xaf\x84\x0b\xdd\x38\x34\x2f\xba\x38\x5f\x9e\xfb\x46\xcc\x78\x9e\xf8\x4c\x9a\xcc\x73\x91\x0b\xac\x9a\x5e\x8e\x87\xfb\xbe\x17\x1a\x10\x47\x99\x93\xbb\xb0\xfb\x33\x02\x55\xbd\xc0\x86\x17\x63\x73\xc0\xf1\x9d\xf2\xc3\xd0\x88\xb6\x37\x58\x37\x03\xf9\x06\xee\x87\xa9\xa2\x65\x72\xf1\x33\xc3\x85\xec\xd4\xf4\x9d\x88\x04\xf7\x43\x1e\xa1\x05\x48\x61\x65\x10\x1c\x26\x21\xed\x06\x80\x08\xa8\x02\xb6\xf9\x3e\xbc\xea\x10\x14\x35\xa8\xca\x77\x68\xb0\x3f\x9b\x00\xd6\x63\x1f\x86\xfe\x36\xbf\x14\xc6\xe6\x7e\x24\xb8\x64\x9d\xb1\x62\x73\x8b\xb8\x10\xf5\xe4\x3e\x47\x2a\x4e\x07\x2a\xd9\xa6\x59\x41\xed\x9d\x5f\x70\x97\xb8\x1f\x7b\xcc\x96\xf9\x3e\xa0\x22\x31\xb8\x11\x91\x79\x32\x3a\x09\x53\xc2\xfb\x53\x94\x39\xe5\x3a\xce\x7f\x24\x4d\x19\x73\xa4\x08\x52\xdb\xee\x6e\x52\x9a\x2a\x63\x41\x01\x39\xf6\x4a\xf7\xdc\x87\x00\x93\x68\xd0\x24\x6c\xf3\xe3\x67\xb8\xd4\x93\x67\x4c\x1b\xd9\xf8\x41\x03\x1a\x13\xee\xac\xde\x81\xc6\xe7\x73\x21\x9b\x33\xf4\xc2\x75\xcc\x0e\x13\xbe\x26\xf6\x11\x28\xb5\xcb\xcb\x17\xb0\xd6\x54\xa3\x97\xc5\x17\xc2\x23\xde\x1d\xbe\xf7\x02\xe0\x6e\x05\xf4\x85\xf4\xa8\xfe\x7c\x82\xcb\xa1\x29\x0f\x4f\xeb\x07\x77\xf1\x92\x45\xda\xca\x74\x1c\xbe\x2f\xee\xbf\xad\xbb\x03\x56\x54\x6d\x5f\xe1\xdb\x00\x15\xcf\x7d\x19\x86\xd4\xa9\xfc\xb6\xde\x3f\x75\x7f\x4b\x13\x6f\xa8\x89\x44\x04\xa9\x6b\x7f\x48\xee\x4b\x61\x40\xe3\x2f\xd8\x3c\x55\xa6\x62\x6f\x99\x51\xe6\x7d\x24\xf8\xd8\x95\xfc\xca\x3f\x07\x00\x4e\xee\xab\x90\x51\xed\xeb\xee\x71\x3b\x79\x2d\xd1\x03\xd2\x38\x70\xeb\xef\x75\x75\x89\xfb\xe8\x1b\x04\x16\x01\x8b\x09\x85\x5b\xbc\x38\xd3\x48\x37\x24\x09\xc1\xca\xa7\x10\x28\x00\xab\x51\x9e\xeb\x63\xea\x53\x98\x25\xba\x74\x62\x7e\x2a\x21\x1a\x4d\xca\x0a\xb2\x1a\xf7\x70\x9a\x5e\x09\xa6\x94\x48\x3b\xf5\xad\x5f\x24\xe4\xbe\x86\x80\xb8\xcb\x4f\xc7\x22\xab\x97\x5d\x1a\x15\x78\xa1\x24\xe0\x35\xed\x53\x9d\xe9\xfe\xec\x39\x02\x8f\x7b\xca\xeb\xcc\x30\x6c\x95\x79\xf6\x2d\x0b\x18\x70\xba\x49\x74\x49\xdb\xaf\x89\xf7\x3f\xee\x0b\xfd\x28\x74\x10\x30\x0b\xb0\x46\xf5\x54\xa1\x05\x4f\x4d\xd6\xc9\xc0\x57\xd2\x33\xde\xc9\x0a\xf7\xa5\x0b\x69\x87\xf3\x36\xf0\x35\x50\x2f\x62\xf1\xbc\xf1\xdd\x97\x04\x9e\x29\x1f\xe7\x99\xa0\xe2\xa2\x00\xf9\xd6\xbe\x8f\xa3\x79\xd1\x55\xdc\xed\x86\x1f\x87\xa6\x12\x1e\x77\x1b\x7f\x10\x80\x1f\x82\xe3\x8f\xdd\x64\x15\xca\xe6\x86\xfc\xa2\xdd\x71\x19\x3b\xd2\xe2\x73\xf9\xd6\xee\xf7\x57\x9a\xc2\x3c\x08\x94\x4f\x4a\x88\xed\xdb\x77\x42\x99\x4d\x8c\xfd\x5d\xde\x11\x84\xa9\x27\x1d\x14\x81\x1a\x52\x5b\x5b\x3c\xb1\xf0\xb3\x2e\x58\x0a\xc2\xd4\xd4\x64\xcd\x1a\x56\xdf\x9e\x07\x91\xfc\xe4\x41\x84\xa9\xa6\x55\x12\x5f\x5e\xc6\x0e\xf1\xdd\xd7\x46\xbe\x0c\xfb\xce\xf5\xb2\xa9\x89\x9e\x62\xc7\xfc\x3e\x93\x20\x05\x51\x9a\xd2\xaa\x73\x84\x9f\xed\xfa\xb9\x2a\xcb\xb7\xcc\xcd\xfd\x20\xe2\x81\x0d\xdf\x9b\xad\x71\x32\xfd\x02\x85\xca\xa7\x66\x9c\x6e\xb4\xe0\x44\xc9\xfe\x5f\xea\x41\xb6\x59\x83\x3b\x4f\x9c\x84\xd4\x24\xb5\x18\x31\x8b\xe1\x9f\x17\x4e\xe0\x41\xcc\x53\x42\x23\x58\xd2\x30\x4d\xbb\x11\x04\x92\x07\x89\x1f\x10\xf4\x64\x38\x0f\xdc\xa1\x34\xa0\x35\x0c\x2b\x68\x53\xf4\x87\x2e\x99\x9e\x0c\xe3\x09\xb1\xae\xef\xb2\xe3\xd1\xd5\x61\xec\xa1\x34\xe4\x4e\xf6\xf8\xd6\xb0\xf4\xe6\xb7\xe6\x20\x8d\x12\x2e\xba\xfa\x75\x73\xae\x47\xfc\x4c\x37\x48\x78\x0a\x07\x92\x7c\x6d\x94\xb5\xb2\x82\xf8\xce\xbe\xbe\x1d\x85\xee\x4d\xea\xe5\x4e\x18\xef\x4e\xa2\x15\x95\xbc\x55\xf9\x51\xec\x87\x4a\xa9\xe3\x3b\xc7\x03\x46\xca\x38\x25\x79\x9b\x93\x69\xa8\x0b\xf5\x02\x1e\x09\xda\x12\x9e\xb4\x7e\xc0\xe2\xfc\x50\x56\x75\xb7\xb9\x07\x20\x0c\x60\x95\xba\x38\x4e\x33\x69\xf2\xfa\x82\x8e\x49\x02\x67\x59\xe1\x6b\x79\x45\x14\xbb\x0a\x02\x3e\x8b\xd9\xff\x8f\x7f\xb7\x5f\x2e\x42\x4d\xcd\xba\xa6\xf3\x6f\x7b\xf9\xe4\x1e\x88\x54\xd2\xfd\x26\xdc\xa0\xe3\x9b\xa9\xe7\xec\x27\xf6\x06\x09\xff\x64\xb1\x5b\x15\x84\x94\xd4\x85\x41\xe2\xfa\x98\xb9\xd6\xb1\x43\x79\x20\x93\xd4\xb1\x6e\xda\xd7\xc3\xb1\xf6\x26\xb7\x46\x42\x42\x74\x8f\xed\x7e\xc9\xdc\x27\x15\x63\xa4\x14\xb5\x2c\xf3\x66\x34\xbd\x14\x0b\x84\x75\x06\x3d\x6c\x56\x4f\x93\xc2\x6d\xa0\x7c\x6e\xf6\xe0\xac\x50\x47\x38\x1d\xc6\xf1\xf1\xf8\x7b\x55\x10\xa6\x7c\xe0\x3d\xb8\x7b\x2d\xab\xe6\xca\x7a\x90\x07\x08\x48\xbf\xc2\x08\xd6\xb5\x3b\xc3\x03\x8e\xae\x09\x15\x90\x16\xc9\x4b\xf6\x8e\x8b\xaa\xf9\x28\xab\x37\x8b\x37\xbc\x26\xe4\xda\x8f\xe8\x80\x11\x6f\x6c\xff\xb4\xdb\x14\x75\x93\x35\x06\x90\xfd\xa5\xcc\x09\xe1\x30\xc2\x8a\xf1\x40\xab\x50\xe1\x00\x1c\x57\x1b\xaf\xe2\xf1\x75\x86\x5e\x18\x06\xc6\xbe\xe3\x1d\xf3\xf3\x95\x21\xa3\x1b\x15\x01\x49\x8d\x3c\xe2\x47\xc7\x95\x9a\xaf\xf6\x85\x9e\x16\x94\x71\x77\x62\x07\x0f\xe8\xd8\xcd\x3c\x64\x81\x08\xcd\x4c\x29\x0a\x94\xcd\x4c\x85\x3d\x64\xb1\x4f\x08\x9b\x25\xd4\x99\x41\x7d\x5a\xf9\xaa\xee\x1c\xa9\x51\xec\xae\xb3\x97\xc2\xc9\x02\x8e\x57\x9a\x90\xa1\x11\x58\xa9\x0d\xaa\x69\xae\x93\xc3\x43\x1f\x8c\x9a\xf5\xc4\x4e\xe8\xff\xfa\xff\x5f\x59\x78\xf1\xd0\x97\x68\xa0\x18\x99\xa3\xa1\x91\x74\xfe\xf9\x44\x1d\x38\xb7\x2b\x85\x3e\x1a\x9f\x62\xed\xb6\xe1\x30\x08\x34\xf9\x0a\xde\x55\x88\xc5\x8f\xb2\xca\xd5\x2d\x54\x43\x20\x0e\x0f\x83\x30\x8e\x39\x99\xb9\x88\x6a\x80\x22\xe4\x61\xc0\x8d\xad\x0c\x49\x5f\x42\x53\x56\x93\xe9\x11\x86\xa1\x11\x3c\xdd\xac\x9e\x4e\x3d\xca\x93\x87\xa1\x48\x88\xc2\x64\xca\x9a\xe5\xc7\x2f\xb0\xcf\x3c\x0c\x55\x44\x50\x84\x36\x12\x6b\x86\xce\x44\x3c\x8c\xe2\xc8\x2d\xaf\xbd\x65\xfe\xae\x29\x4f\x83\x48\x2f\x8c\x30\x50\x06\x6b\xa3\x10\x8f\x03\x2a\x15\x0f\xe3\x50\xd2\x0f\xd0\xa6\x34\xe9\xba\x8e\x3c\x8c\x05\x27\x72\x9f\x95\x3d\x1b\x47\x0b\x61\xea\xa7\xd4\x4a\x5b\x82\xb8\x2c\x11\x46\xdb\x4c\x98\x62\x68\xe0\x84\x90\xcb\x07\xa8\xde\xb0\x4d\x8d\x7e\x1b\xe5\xb0\x76\x24\x4f\x8c\xe1\x7f\x47\xed\xe3\xa3\xa8\x29\xe4\x89\x69\x5d\x3b\x36\xe9\x76\x86\xcd\xe1\x86\x6a\xcf\xb2\x58\xe9\x85\x58\x37\xaf\xfb\xf2\xc7\xe0\x9d\x80\x98\xd3\x46\x23\xb1\x68\x6a\xdb\x16\x9a\x04\xcd\x21\x48\x20\x74\xf2\xbe\xc2\xa2\x1c\xfd\x24\xc1\xc0\xeb\x51\x5c\x37\xd9\xfb\x0a\xaa\x59\x9e\x38\x0f\xa5\x8c\x6c\xe3\xa8\x59\x5c\xa0\x68\x6e\xaa\x32\x6b\xd6\xb2\x2c\xca\x63\xf6\xef\x33\x1e\x56\xe5\xf1\xd4\xe0\x81\x4f\xbe\x5b\x05\x9c\xa6\x58\xd7\x84\xdd\xf5\xca\x3f\xed\x51\x81\x83\x72\xc6\x6d\x9b\x43\x65\x65\xe1\xf0\x37\xb3\xc5\x92\xf1\xeb\x81\x91\x11\xd7\xdd\x91\xa5\xad\x55\x7d\x1e\x60\x59\x78\xa8\x7d\x74\x60\x3c\xab\x03\x82\x55\xf6\x8e\xd7\x3c\x91\x2f\x50\xbf\x0e\xfb\x0b\xa1\x16\x3e\x45\x53\xb7\x59\x4e\xf2\x77\x9b\xae\x1c\x16\x6a\x34\x75\xdf\x21\xad\xf4\x3e\xab\x9b\x87\x69\x9e\x10\x6a\x1d\x33\x3b\x17\xbe\x66\xcd\xb4\xf7\x1a\x79\x20\x89\x0f\x57\x95\x79\xbe\x2d\xcb\xab\xce\xa8\x1d\xc6\xc0\x37\xd3\xc0\x36\x72\xe0\x48\x84\xd3\x01\x47\xa4\xab\x98\xfc\x93\xff\xeb\xd7\x65\xc6\x88\x69\x43\xe6\xa4\xa9\x60\xfd\x18\xec\x0f\x8b\x7c\xdf\x77\x0a\x54\x94\xd3\x19\x79\xe5\xfa\x50\x4b\xe8\x63\x93\xc8\x17\x31\xb1\xb1\x0e\x95\x89\x0c\x1d\xd8\x70\xfe\x45\x8f\x82\x30\x34\xc6\xcc\x26\xcc\xfd\x5e\x9e\xe5\x2b\x56\x0f\xcd\xeb\xba\x79\xed\x41\x85\x3c\x0a\xd2\x94\x5b\x79\x38\x22\xa1\x98\x93\x4d\xf5\x4d\x3e\xf9\x55\xa1\xa7\x89\xab\x58\x94\xd5\x31\x7b\x83\xec\xbd\x74\xa7\x0d\xa5\xe1\x58\xfc\xf7\xb7\x9d\xab\x90\x46\x91\x0f\x94\x20\x93\xac\xcb\xa6\x78\x2f\xdf\x88\xf4\xe7\x8f\xb8\xfd\xe3\x52\xc3\x75\xbb\x2f\x8a\x42\x4c\x44\xdf\x34\xba\xc5\x46\xbe\x0e\x56\xa8\x28\x0a\xb5\x48\x5c\xed\xf2\x2c\x9b\xef\x70\xce\x9b\xee\x60\x1c\x93\x18\x44\x97\x72\x18\x34\xe6\x1d\x1c\x49\x88\xdd\x9f\x5f\x11\xa2\x38\x32\x3c\xd3\xed\xfa\x6e\xb3\xdb\xaf\xb7\xb7\x6b\x97\xf5\x47\x31\xf8\xc4\xde\x3f\xa2\xca\xce\xc7\xbe\x57\x1b\x25\x09\x23\x95\xd5\x15\x54\x05\xbc\x8c\x42\x89\x28\x49\x03\xd5\x1e\x33\x6d\xf1\xc1\x9b\x13\x25\xa0\x28\xff\x73\x3d\x2a\xca\xf8\x9d\xff\x1d\x8f\x12\x1d\x50\xb1\xec\xeb\x3b\x14\x8e\xe6\xe2\x8e\xa5\x41\xc8\x92\x39\x0b\x8f\xc9\x33\x9c\xb9\xa7\x29\x37\xa7\xb5\xb6\x7a\xdb\x32\xbf\xd2\xd1\xe9\xc7\xca\x38\xb6\x80\x94\x7a\x28\x78\xec\x0e\xab\x28\x0a\x3a\x1f\x21\xa3\x12\x73\xa8\xa0\xc1\xc3\x09\xab\x83\xe9\xf7\x77\x57\xac\x3d\x23\x54\x5b\x41\xdd\x64\xf2\x01\xa1\xee\x9c\xb3\x79\x04\x2c\x22\x6d\xbf\x36\xd8\x1e\x13\x7f\x79\x04\x3e\xe7\x36\x54\xb2\xfd\xc5\x1d\x92\xfb\xff\xf8\x62\xc0\x17\x04\x8e\xba\xc1\x73\x3d\xe8\x64\xb8\xa3\x89\xe9\xcb\x1f\x9a\xf2\xbe\xbd\xae\x89\x1a\x1f\x8f\x40\xc4\x84\xe7\xbb\x5b\xec\x0c\xf8\x79\x64\x4b\xdf\x26\x0b\xc6\x04\xaf\x5d\x9f\xb3\xea\xa6\x2a\x4f\x13\xa9\xac\xc9\x8a\x22\x7c\xf4\x6d\xb3\xe2\x5b\x51\x21\xa8\xc9\xa2\xeb\x86\x85\x1e\x79\xf2\x1c\xec\x14\xb7\x4b\xce\x80\xda\xd1\x8e\x01\x2a\x6f\xdc\x97\x86\xd9\xb0\x1b\x82\xf2\x06\x46\x90\x6e\x78\x04\xa4\x21\xa0\x11\x7b\x6e\x37\x8f\xa4\x30\x06\x8d\xaa\xfc\x51\x56\x6f\x8b\x42\x3d\xc3\x65\xbd\xe8\x5e\x58\x29\x53\x92\x34\x39\x95\x1f\x68\x5c\xad\x87\x92\xdc\x3c\x92\x2a\x36\xfd\x46\x9a\x35\x23\x77\xd0\xf9\x25\x55\x71\x10\xce\xb8\x0d\x9c\x23\x1d\x8f\x30\x34\x3e\x03\x54\x61\xaa\xdb\xd7\x75\x7c\x43\x30\xe2\xa4\xbf\xb6\xd8\xae\x9e\x1e\x17\xee\x53\x3a\xf5\x90\x9b\x10\x77\x57\xea\x66\x35\xdd\x06\x22\x0d\x92\x04\x39\x0c\xb4\x73\xa6\xde\x6e\xc6\xc5\x9e\x65\x22\xec\xbe\x6f\x5c\x86\x11\x7b\x56\x56\xc1\x74\x18\x6f\xce\x98\x0f\xaa\xbf\xb1\xa7\x38\xf5\xf1\xc8\x8e\xe9\xeb\x59\x7d\x62\x65\xcb\x63\x16\x00\x41\xb6\x8f\xd8\xc0\xee\x1a\xc3\xee\x46\x85\x09\xf1\x41\x1f\xa0\x91\xaf\x4b\x43\x65\xfa\x44\x97\xea\x57\x10\x3a\x1e\x07\x1e\x23\x07\x4f\xa3\x3f\x95\x1d\xb1\x3c\x37\xd7\x5e\x7c\x3c\x0e\x58\xca\xf0\xaf\x03\x0b\xe6\xfd\x36\x39\x3f\xa4\xb4\xde\x8f\x34\x0e\x7f\x55\x1c\x8e\xc3\x48\x40\xcf\x6d\xd9\x35\x78\x6a\x23\x69\x22\xa9\xf7\x05\xca\x38\x8c\x7d\x7a\x31\x0e\x64\x00\x62\xc0\x17\xc4\xf6\x22\x9e\xe3\xf8\xb5\x8d\x43\x1e\x50\x27\xee\x08\x6f\x36\xa2\xf8\xad\x3b\xa2\x3c\x5b\x94\xb0\x02\x12\x13\xbe\xb2\x1d\x17\xb1\x44\x6a\xcb\x8a\x1e\x62\x2c\xe2\x88\x29\x61\x37\x43\x0b\x1d\x9d\x7c\x50\x04\xaa\xd3\xf7\x22\x28\xfb\x53\x47\xce\x77\x43\x10\x22\xdb\x35\x79\xbe\x9d\x53\xce\xe3\x71\xc2\x14\x49\xb2\xec\x40\xc2\x20\x03\x88\x93\x54\x84\xf6\xa3\x2e\x2a\xdb\xbf\x56\x88\x33\xed\xa4\x38\x15\x46\x3d\x7b\x57\xbe\x60\x93\xed\x49\x81\xa4\x3f\x13\x0f\x3c\x7f\x7c\x23\x46\xda\xf4\x23\xb5\xfe\xeb\xbf\x31\xcf\xfb\xd7\x9c\xa0\xff\xaf\x43\x9c\x98\xb7\x7b\xfe\x7f\xfd\xbf\xff\xfa\xb1\xf9\xba\x21\x31\xd6\xbf\xec\x57\xc5\x5c\xf8\x51\x6c\x5b\xdf\xe6\x4e\x4e\x2d\x66\xc6\x5f\x01\xa1\x89\x5d\xdb\xbf\x5a\x91\xba\xf9\x1d\x3b\x86\xd4\x23\xae\xd4\xc0\xf0\x63\x32\x5f\x07\xd3\x4f\x84\x01\x55\x3d\xf3\xac\x69\x9c\xba\x2e\x8f\x45\x2a\x92\x78\xd0\xcc\x51\xd9\x7b\xa6\xce\x90\x0f\xfd\x37\x26\x2e\xa5\xb3\x3d\xea\x58\x0a\xa0\x9a\x9f\x1c\xf5\xb3\xe7\x7f\xa1\x94\x9a\x60\xed\xab\x52\xbe\x0d\x77\xbc\x58\xf9\x0c\xa0\x37\xce\xb8\x5e\x8d\x63\xe5\xab\xd8\x96\x5d\x17\xcd\xdb\xb2\xac\xeb\x7f\x9c\x71\xa2\xee\xcf\x63\x15\x30\x4f\x59\x37\xa7\x23\xce\xf2\xbe\x79\x8c\x90\x38\xb6\xc8\x53\xf5\x02\xc5\x63\xe7\x1b\xc5\x63\x94\x8c\x76\xa7\x65\xf6\x62\x1c\xad\x06\xf3\x0e\x55\x8c\xa6\x05\x02\x45\x0d\x34\x83\xad\x7f\xc2\x75\x21\xf3\xf7\x39\x1c\x4c\xac\x03\x3f\x4c\x9c\x56\xc5\x0f\xe8\x92\xc8\x58\xc7\x46\x39\x2d\x93\xb6\x97\x7e\x6c\xb3\xaf\x61\xbf\x3c\xd6\x49\x4c\x05\x9a\x3b\x8b\x6e\x78\xc8\x8a\x71\x47\x3d\xf1\x42\x61\x38\x48\xf5\x42\x4a\x3c\x35\xa8\x36\x47\xdb\xd1\xb0\xae\x3f\xd3\x64\x21\xf1\x12\xdf\x99\xda\x5b\xe9\xde\xd1\x09\xd1\x27\x25\xad\x67\xa8\x2e\x23\x00\xfe\xf5\x64\x6f\xc3\xc1\x54\x39\x1e\x70\x9d\xbd\x8c\x49\x38\x3c\x61\xd2\x18\xa4\xbe\x9c\x4f\xc3\x27\x9f\xf8\xcc\xa7\xfc\xde\x10\x07\x6f\xcb\xca\x34\x69\xdc\x51\x61\xf6\x8e\x57\xc8\x1b\x54\xb7\x0e\xb6\x99\x04\x22\xb5\x8e\xa3\x0d\xe4\x96\x3b\x31\xcc\xb4\x92\xd0\x33\x26\xb7\x79\xf6\xef\x73\xa6\xb2\xe6\xb2\x50\x2e\x30\x4b\x22\x2f\xa0\xa0\x56\x9c\xab\xa2\x4f\xe4\x93\xc8\x33\x92\xc9\x64\x37\x7d\xad\x25\xc8\x93\x88\x71\x3a\xe7\x2e\x2b\x48\x94\x2d\x6b\x2e\x8f\xb6\x98\x35\x32\xe0\x18\xff\xf0\x28\x50\xd8\x41\xdf\x0e\x54\xd7\xea\x4e\x18\x09\x72\x4b\xde\xac\x9e\x56\xa4\x92\xe6\xfe\x2e\x3d\xba\xef\x79\xf9\x72\x83\xe2\x3c\x12\xd2\xe5\x49\xcc\x62\xc2\xc6\xfe\x59\x9e\x7f\x64\x9f\x12\x24\xdd\xe0\x20\xa6\x18\xe8\x94\xc3\x65\x8e\x94\xc6\x93\x38\x0e\x55\x77\x2b\x3b\xa5\x41\x77\x29\x71\x12\x4b\xc3\x78\x44\xf9\xd6\x21\xec\x8c\x0f\xe0\x78\x2a\xc5\x09\x50\x97\xec\xf6\x7e\xf5\x2b\x4c\x42\x12\xab\x80\x64\x34\xda\xbd\x61\xe0\x9d\xc4\x93\x58\x47\xd4\x44\xb7\x2e\xe9\x37\x65\x57\x63\x4b\x62\xcd\xd1\x36\x90\x17\x2f\x55\x46\xfd\xc7\x55\x9b\x00\xbc\x5f\xcb\x08\xf0\x24\x61\x9e\xe1\x72\xdf\x3f\x6d\xff\x74\xa7\x48\x12\xc5\x2d\xf5\xd7\xe0\x2f\xa9\x95\xe5\x7c\x2b\xdc\x20\x60\x84\x31\xcd\xea\xae\x99\x35\x0f\x9a\x4a\x12\x11\xf3\xce\xe8\xc9\xd6\x33\xe7\x22\xc4\xf9\xa7\x92\xf2\x38\xa1\x62\x57\x57\x81\x9b\x77\x75\xe0\x49\x2a\x90\x90\xc6\x9d\x31\xaf\x31\x69\x77\x17\x9c\x6a\x8f\x59\x59\x3e\x67\x1d\xb0\xbd\xca\x5a\x92\x36\xc8\x94\x1d\xf1\xd2\x04\xa1\xdf\x0a\x99\xe3\x03\x56\x6f\xa4\xc9\x5a\x8e\xc1\x73\x56\x1e\x82\x27\x5c\x24\xb4\x2e\xaf\xd6\xfb\xc5\x6a\xbd\x98\x9e\x57\x7a\x9e\xc5\x42\x8e\x28\x48\xe3\x9f\xc0\x51\x87\x9d\x45\xcf\x32\x9b\xa0\xc6\x12\xf0\xcc\x02\x70\x28\xf0\x63\x26\x16\x48\x80\xf9\x54\xb9\x86\xa6\x29\x3f\xb0\x79\x1d\xf7\x81\x12\xf0\x25\x81\x79\x0b\x0b\xb4\x7f\xb8\xb4\xe1\x5d\x59\x0c\xdf\x27\x80\x80\x69\x0b\x51\xb6\xb2\xf9\xf3\xef\x82\x90\xb1\x34\xd5\xf4\xc6\xaf\x9b\xea\xb7\xd1\x41\x19\x86\x18\xf6\x04\xe5\xed\x54\xdf\x9c\x27\x32\x4d\x49\x75\xad\xcb\xbf\x6d\xf6\x76\x93\xd5\x4d\x7b\xcd\x9b\x62\x3b\x34\x77\x70\x9f\xc2\x98\x48\xb3\x58\x28\x18\x94\x5f\x06\xa7\xd5\xb1\xe1\xd7\x43\x03\x35\x36\x87\xfa\x15\xfc\x28\xa6\x37\xb2\x76\x84\x4d\x9e\x28\x5f\x91\x47\x93\x71\xf4\xcc\x06\x01\x68\xa2\xd2\x30\x09\x2c\x47\xa7\x7a\x77\xcd\xd9\xa9\x4e\x19\x4f\x94\x62\x44\xd0\x55\x48\x36\x50\xab\x8e\xc1\xc3\x13\xf4\x7c\xca\xe9\x3f\xca\xea\xf8\x5a\xe6\xb8\xa9\x07\x90\x87\x44\x7b\x8c\x3b\xa7\xb0\x23\xbc\xe0\x17\x72\x51\x9c\xc5\x63\x26\x3a\x88\x88\x45\x6f\x18\x42\xe4\x4e\x75\x15\x35\x7c\xe2\x8b\xfe\xfb\xa8\x63\x96\xe8\xc8\x53\xe9\xd0\xfe\xab\xd9\x67\x48\x1a\x9f\xd2\x79\xa3\xb5\x83\x98\x01\xe0\x2c\x1e\x46\xfb\x8e\x56\xc2\xce\x09\x7a\x9a\x54\x63\xf9\xf5\x52\xaa\xb5\x22\xf9\x86\x7f\x9f\xa1\x6a\xb0\xba\x2d\xcf\x55\x57\x35\x4d\x3d\x26\x0c\xa3\x0f\x5e\x5e\x71\x21\xff\x7d\x1e\xab\x87\xf2\xd4\x4b\x41\x6b\xab\x0b\x91\x15\x2f\xd6\xaa\x6a\x74\xff\x53\x4f\x21\xfa\xc3\xf9\x43\xf6\x18\x7f\x13\x02\xe7\xce\x81\x32\xb5\x78\x86\x39\x84\x77\xca\x12\x11\x0e\x34\x91\xbe\x63\xdd\x38\x89\xcc\x76\xf3\x1d\xe8\xe2\x8d\xaf\x8d\x09\x45\x85\x91\xa1\x55\xb4\x5b\x72\x1e\xe0\xa7\xbb\x0f\xbe\x87\x04\xc6\x30\x9c\xe3\xdd\xb9\xe8\x3d\x40\x78\xea\xfb\x11\x45\x39\xaf\x65\x43\xc1\xdb\x8c\x16\xc1\xe4\xd7\xf8\xa9\x8f\xbc\x53\xd3\x98\xf8\x1c\x0d\x1a\xfd\x6e\x38\x26\x84\x06\xb7\xcd\xef\x2c\xcf\xb3\xb2\xa8\x49\xbd\xba\x73\x91\xdd\x97\x37\x55\xe9\xa6\x47\x1a\x86\xc6\x63\x1a\x28\x62\xb2\x8c\xbb\x19\x05\x3a\x9e\x86\x89\x4e\xac\xbc\xfd\xb7\xa2\x2e\x73\x35\x02\x81\xa4\xa1\x0e\x3c\x8b\xec\x7c\x80\x9f\x26\x16\x19\xff\x96\x88\x21\x4d\x7c\x2b\x1d\xd3\x09\xf8\xa5\xd3\x82\x55\x1a\x2b\x1e\xc4\x53\xb1\x55\xa7\x6d\x35\x3e\x69\x12\xa7\x14\x51\xd3\xfe\x3e\xbb\x55\xa5\x49\xaa\x22\x37\xe4\x50\xcb\xac\xae\x7b\xa0\x66\x9a\x70\x41\x75\x3c\xb3\x8f\x65\x47\xdc\x14\x3b\x94\xdd\x51\xe1\x3b\x08\xbb\x63\x4e\xcf\x4a\x37\x4f\xbe\x31\xf5\xa5\x32\x76\x7a\xed\x67\xc6\x32\x00\xa4\x51\x4d\x30\x5d\x6a\x30\x4c\x81\x00\x76\x0c\x87\x08\x6c\x0a\x6f\x30\xc0\xfa\x19\xaa\x26\x93\xd9\x09\x8a\x09\x91\x8a\xa7\xc0\x34\xcd\xb9\x13\x09\x4b\x6e\x21\xeb\x77\xf4\x14\x24\x23\x0f\x95\xc5\x66\x7b\xb3\x7d\x7a\x3e\xec\xb7\x8b\xc7\xdd\x66\x3f\x76\xb8\xe7\xa9\xf0\x7c\xaa\x85\x1d\xda\xa4\xf9\xb9\xca\x8e\x65\xa5\x32\x98\x37\xf6\x72\x1f\x49\x7c\x02\xcd\x7f\x40\x83\xd5\xbe\xc2\xe9\xe3\x16\x29\xa7\xb4\x2b\xab\xef\xf1\x05\xf2\x41\x11\x37\x15\x60\x54\xff\xc4\x39\x7f\x9b\x8a\x17\x7f\x2a\x7f\xcc\x53\x81\x9e\x1a\x11\x6d\xf7\x65\x1b\x8a\xe6\x53\x7b\xa9\xc9\x85\xca\x50\x47\xd6\x24\x61\xdd\xbc\xba\x77\x76\x46\x83\x83\xa7\x12\x44\x62\x89\x6b\xe6\xba\xca\xea\xb8\x87\xea\x05\x9b\xc3\xa9\x2c\x27\x3d\xef\x14\x45\xe8\xc0\xc5\x5b\x28\xde\xbc\xc0\xfd\x3e\xcd\x7d\x12\xe7\xd9\x3c\x0e\x38\x5d\xdc\x13\x01\x74\x34\x7c\x8a\xae\xed\x35\xb8\xe3\x4a\x70\xbf\x2b\x4a\xed\xce\x23\x3e\x30\xe7\xcc\xf7\x49\xf3\x6a\xf9\xc5\xc1\xc4\x79\x90\x24\x14\xd7\x98\x97\x77\x99\x97\x6f\x3d\x01\x75\x50\xb5\xe0\x81\x36\x0c\x73\xe1\xdc\x8f\x86\x8a\x61\x9c\x87\xc8\x48\xec\x61\xa1\xd4\xaa\x2c\x9a\x21\xa4\xe1\x93\xd4\x77\x3e\x15\xe6\x91\x10\x94\x4d\x61\xf3\xaa\xcb\xea\x14\x28\xd1\x15\xcc\x79\x9c\xa4\xd4\xb5\xc9\xa1\x6e\x4c\xee\xe8\x8e\x70\x6e\x54\xb4\xee\xb0\xa1\xdc\x67\x53\xbc\x77\x87\xc0\xa0\x99\xd7\x7f\xee\x47\xf7\x82\x0b\x45\xd3\x75\xbb\xd8\xaf\x0f\x96\x90\xe0\x8e\x01\xe7\x71\xe4\x16\xa2\xa2\x57\x13\x9c\xac\xb3\x23\xf8\xce\x70\xa1\xe3\xc2\x4b\x08\x09\x92\xd5\xb6\xf0\xf8\xa5\x2b\x21\x71\x11\x99\x46\xcf\xed\x62\xb7\xde\xff\x75\x09\x84\x4b\x01\xa4\xf0\x77\x33\x23\x18\xf8\x09\x32\x97\x4b\xd4\xf4\xca\x5a\xac\x0c\x35\x9a\x57\xe7\x93\x09\x5b\xeb\x29\x77\x77\xfc\x3f\x73\x8f\x42\x05\x06\x80\xde\xcb\x6f\xde\x65\xef\xfd\x0d\x54\x81\x2d\x71\x62\x73\x87\x85\xad\xb3\xb8\xa8\x97\xab\x30\x16\x43\xbb\x70\xea\x17\xbd\x67\xf8\x31\x2d\x76\x71\xa5\x8c\xa5\x61\xfb\x76\xd8\xe6\xd2\x0a\x4e\x6d\x18\xe2\xba\xe6\x1c\x45\x6c\x94\x8d\xdc\xe4\xdb\xbf\x3a\x25\x1f\xce\x35\x4b\x49\xbb\xf4\x5c\xd4\xc6\x5e\xdc\xfd\x3d\x14\xd6\x91\x28\xef\x72\xb2\x91\xb8\x21\xe7\x3a\x8a\x09\xf9\x4a\x2c\xd6\x9e\x51\xcf\xc1\x0b\x7c\x69\x9e\x9f\x8d\x8a\xec\xf2\xb0\x45\xf8\x4c\xb4\xb2\xfd\x90\x4c\x0c\x06\x0d\xf2\x79\x93\x30\x0e\x2c\x09\x42\x1b\x00\x7f\xc9\x94\xc2\xe2\xbe\x7c\xc9\xe4\x74\x10\x84\x4e\x50\xf5\xa1\x54\xc6\x64\x67\x58\x54\x00\x1f\x99\x49\x46\xda\xd4\xfa\x1e\x9a\xfb\xe2\xe5\xf6\x9c\xe7\x76\x2b\x1c\xce\x04\x08\xd0\x18\x13\x34\x58\x37\x8f\xf8\x02\x4d\xf6\x8e\xed\xb3\x78\xc1\xea\x2b\x8e\xf2\x7d\x08\xb4\x47\x6c\x82\xaa\x0d\x3c\x93\x49\x65\x17\xc2\x10\xa9\x46\xb5\x5c\xff\xe1\x6a\xe0\x10\xa6\x31\xdd\xe2\x13\xc8\xb7\x91\xc0\xd6\xe0\x63\x29\x52\xcf\xe9\xd6\x74\xd5\x3b\x78\xd0\xac\x08\xdd\x67\x28\xa6\x4f\x7b\x7d\x10\xa9\xc4\x54\x83\x5c\xb8\x37\x15\xab\xe0\x10\x73\xc3\x04\xff\xba\x5a\x51\x06\xe8\x2e\x3e\xd6\x89\xea\x69\x78\x5b\x13\xd7\x8f\x02\x12\x48\x22\xdf\xee\x16\x06\xdb\x39\xb5\x91\xe5\x90\xf0\x84\x5a\xce\xdd\xde\xdf\xae\xc9\x7e\xf7\x79\x91\x46\x89\x31\xf1\x54\xb5\x83\x92\x5e\xf7\x4c\xfb\xd1\xa9\x15\xee\x59\x9e\x2f\x58\xb5\x8f\xf4\x1a\x86\x04\x09\x72\xc7\x8f\x3a\x58\x70\xdf\x21\x93\x65\x91\xfd\xfb\x40\x12\xde\x35\xf5\xd1\xb0\x57\x0e\xe1\x90\x46\x31\x06\x4e\x02\x80\xde\xe4\x41\x83\x17\xd2\xd4\xa8\x31\x9f\x4f\x2f\x15\xa8\x4f\x40\x40\x90\x6a\x9f\xfa\x1d\xeb\x42\xb6\x9b\x8b\x0d\x78\xdd\x39\x38\x18\x91\xe0\xe5\x66\xbf\x33\x3c\xd5\x21\xa1\x17\xb8\x94\xc2\x68\x36\xe0\x43\x56\xe0\xc8\xb8\x95\x03\x44\x8a\xda\xdb\x04\x2f\xeb\xfe\xc8\x03\x6a\xae\x17\x67\xea\xaa\x77\xcf\x44\x40\x8a\x63\xe6\xc9\xdf\xe3\xf1\x80\x00\x10\xd6\x39\xcb\x00\x45\xf6\xe5\x0f\xa8\x47\xf0\x3e\x10\x2a\x21\x91\xd0\xdb\xcd\x76\xb7\x27\x8a\x1a\x4d\x99\x1e\x58\x06\x32\x8c\x62\x3e\x74\xc4\x35\xe1\xf3\xf5\x14\xb5\xe3\x15\x67\xd2\xe8\x31\xaa\x51\xab\x62\x72\x77\x31\x36\x10\xea\x1f\x14\xa4\x8f\x7e\xd1\xd8\x7e\xb4\x3f\x73\xbb\x14\x11\x79\xb5\x21\x6a\xf9\x7e\x88\x9c\x99\x0e\xd5\x26\x8e\x6a\x17\x94\xcb\xba\x68\xb2\xe6\xb2\xcb\x8e\xa7\x29\xd2\x06\x74\xc8\xd8\xc0\x6c\x14\xa7\xe9\xe7\xe4\xa2\xb5\xe0\xa2\xf7\x55\xf9\x6e\x60\x49\xa8\x5c\x06\xe0\x6e\x49\x78\x1d\x8e\x31\xff\x5f\xbf\xcf\x24\x08\xc2\x53\x92\x00\x5c\x50\xe1\x22\xcf\xbf\x9d\x4e\x58\x49\x70\xd1\xaf\x4b\x7f\x05\x03\x25\x8c\xbe\xe1\xb7\x1a\x2b\x53\x74\x1d\xbf\x24\xc2\xf7\x13\xcf\x6a\xdf\x13\x61\xab\x50\xd3\x01\xdc\x73\x1a\x65\xce\xb0\x66\x0d\x55\xf1\xad\x68\xb2\x7c\x84\x06\x16\x3e\xf8\x04\xa7\x2b\xb5\xce\xb3\x02\xef\xce\xd0\xc6\xb5\x05\x11\x80\x3e\x59\xb0\xec\x27\xc3\x38\x22\x19\x40\xe9\x1a\xd0\x2f\xbd\x47\x09\x17\x61\x02\x3a\xed\x2a\x4a\x07\x12\xbd\x51\xd0\xc0\xe1\xa5\x2a\xcf\xa7\xfa\x40\x74\xfa\x43\xdd\x09\x77\x71\x11\x82\x47\xb5\x85\xe5\x7e\x7b\xef\xfe\x16\x45\x01\xb5\x84\x1a\xac\x8e\xf5\x88\x98\x22\xa2\x54\x53\x0d\x2f\x93\xe5\xf3\xb9\x7e\x6d\xf7\xd6\x79\x20\x8b\x88\x84\xa9\x0f\xbd\x96\x55\x6d\xd4\xda\x66\xaa\x48\x22\x0e\x7c\x2a\xde\xb4\x89\x24\xb1\x5a\xdc\x17\xc5\x3a\x02\x66\x83\x6a\x27\x50\x3a\x5a\x48\x45\xe2\x33\xab\xde\xfe\x01\x95\x5a\x37\xaf\x8b\xfe\x81\xb8\xb5\x5c\x24\x89\x17\xf8\x1d\xc5\x65\x79\xbe\x5c\x9b\xf2\x71\x91\x06\x3a\xe8\x73\xc4\x2d\x2a\x3c\x9e\xae\xeb\x3d\x22\x6d\x77\x33\xd3\x55\xac\xb2\xe6\x32\x2e\x78\x89\x14\x83\xd8\xd0\xcb\xf2\x12\xac\xf8\xe5\xf5\x4a\x2b\xc0\xf2\x94\xcd\x05\xad\xce\x75\x53\x1e\xb1\xb2\xe7\xba\xda\x0b\x04\x28\x03\x73\x6c\x9f\xe4\x42\x29\x2a\xf0\x66\xc5\xcb\xf7\xb2\xe9\x9f\x89\x48\x8d\x86\xa6\x55\x3d\xa0\xe8\xf2\x93\x5c\x45\x88\x34\x21\x67\x60\x7d\x2e\xb0\x82\x7c\x51\xa8\x65\x56\x35\xd6\xcb\xf7\xf7\x99\xb7\x47\x7a\x40\xfe\xa2\xf8\xf3\x94\x55\x97\x41\xb6\x24\x64\xea\xc7\x46\xfe\xb5\x79\xc0\x63\x59\x5d\x16\x55\x05\x97\xee\xa8\x60\x46\xab\xe2\x35\xab\xd4\x0f\xc4\xb7\x07\xc8\x0a\xe7\xba\xbe\xae\x9b\xec\x38\x78\xd8\x4a\x72\xa3\x5a\xdc\xae\x66\x0b\xa5\xb2\xeb\xea\xb1\x40\xf0\x8c\x35\x72\x9e\xdf\x96\x55\xa7\x5e\xc9\xa5\xe7\x19\x03\xbb\x17\x6c\x16\x4d\x03\xf2\xcd\xdc\x7b\xf2\x98\xb6\x43\x7c\x4f\x06\xd6\x2e\xaf\x0d\xd5\xf6\xe5\xad\xf3\x78\xd1\x0d\x56\x9d\xe6\x15\x97\x7e\xa8\x88\xee\xbe\xeb\x4a\x57\xdb\xb2\x3c\x2e\x0a\x65\x1a\x0e\xc3\xbb\xda\x47\x16\x7d\x45\x4f\xfa\x89\x0a\x7b\x0b\x35\x63\x8d\xf0\x30\x11\x3e\xe3\xd2\x07\x1d\x0d\x54\x61\xd6\x50\xe5\x97\x19\x55\x18\x2e\x7d\x61\xc2\x0c\x8a\x04\x7a\xc7\x95\x57\xa8\x91\xf5\xe6\x76\xed\x38\x41\x5f\x4b\xee\x22\x75\x8d\xcd\x4d\x29\xcf\xd4\xaa\x22\xbc\xfb\x27\x86\x70\xc3\x0b\x0f\x7c\x8f\xd8\x13\xfb\x8f\xd2\xd0\xe9\x3a\xe7\xf1\xab\xfc\xd7\xcd\x25\x19\xc6\x21\xed\x00\xa7\x73\x63\xb8\xa4\xcd\xe5\xb9\x2a\xdb\xa0\xb8\x9a\x65\x14\xcb\x90\xa7\x91\xdf\xa9\x1f\x8f\xf8\xc3\x76\x44\xd4\xce\x05\xc2\x24\x28\x5c\x4e\xb6\x8a\xb1\x9e\x30\x97\x31\x37\xf7\xda\xe4\xad\xc7\xec\x7c\xac\x7b\xee\x85\x1b\xa3\x7c\x02\x37\x5b\x61\x95\x79\x43\xf0\xf1\x3d\x8f\x15\xd0\xaf\xfa\xb6\xff\xe1\x9a\xb2\x32\xf1\x43\xb2\xa9\xa8\xdf\xb2\xd3\xa6\xb8\xcf\x8a\x4f\x36\x45\x99\x44\x11\x45\xa6\xe4\x6b\x70\x3c\x61\x93\x75\xc6\x06\xe7\x5e\x6f\x8a\xcb\xd4\x8b\x08\xfd\x6c\x7c\x2c\xdc\xd7\xa4\x7e\x9c\x76\xea\x62\x4b\x68\x9a\xc1\x21\x6b\x15\x4d\x9e\x06\xa2\x2c\xfe\x93\x99\x59\x5e\x77\x03\x54\x64\xac\x7b\xba\x9a\x9f\x4c\xb5\xa4\xb2\x37\xbc\x54\xd8\xde\x4d\x1b\x07\x8c\xee\xa9\x1d\x0a\xd2\x77\xe6\xc9\x4b\xc8\xf3\xb2\x19\x97\x93\x46\xe9\xb4\x04\xed\x7b\x3d\xf5\xd4\x22\x27\xa6\x18\xa4\xf1\x7d\x11\x5e\x4a\xe7\xb7\xb1\xe5\xb0\x97\x28\x85\x34\x90\xb5\x25\x7e\x9e\xdf\x5f\xe7\xa5\x2c\x9e\xf9\x2f\xfd\xfd\x57\x13\x46\x7a\x9e\xb2\xfd\xe5\x99\x6a\xb8\x1b\x24\x50\x76\x60\x8b\xe5\x65\x8f\xe0\x2a\xf9\x52\xea\x40\x8d\x9c\x82\x7e\x51\x86\x92\x52\x2b\x5a\x72\x74\x59\xbd\x7d\xfb\x55\x10\x2c\x95\xcf\x8c\x03\x0e\xe1\xa2\xad\x52\xdb\xb0\x02\x23\x55\xe8\x51\xb7\xe7\x50\x63\x63\xe0\x07\xa3\xfb\xe3\x46\x21\x7a\xd6\xb1\xc5\x7d\x10\x3d\x8f\x7a\x7f\xdf\xb7\xeb\x27\xd2\x30\x3f\x3c\x3d\xaf\x1f\x37\x8f\x77\xa4\x90\xd0\x8d\x62\xbe\xb4\xf7\x85\x16\x0f\x62\xc0\x5b\xab\xd0\xf1\x8f\x42\xce\xa8\xe3\xf1\x52\x96\x6a\xec\x1d\xc5\x25\x0a\xe3\x7f\xbc\xdc\xaf\xba\xe2\xa1\x3b\x84\x8a\x28\x22\x54\x00\xb2\x1e\x06\xc4\x50\xff\xe4\x2d\xd2\x51\x44\x6a\x6c\x44\xdc\x2b\x7b\x76\xbf\xd4\xc8\xa8\xdf\x98\xd5\xf5\x19\x57\xa5\x73\xea\xb2\x0e\x1e\xfa\xb9\xac\xeb\x6c\xf0\x3e\x69\x4c\x28\x8e\xa1\xbe\x3c\xd5\x13\xb2\x7a\x2a\x3e\x20\xb5\x46\x0a\x0f\xdb\xb7\x1a\xaa\x65\xff\xbc\x95\xa7\xbd\x58\x76\x52\x75\x8f\xe5\x00\xf7\x31\x07\x54\xb1\x9f\x62\x81\x31\x4f\x30\x96\x90\x78\x1d\x93\x28\x96\xf2\x20\xe9\x7c\xcd\x6e\x76\x2e\x0f\x50\x4c\x86\xcc\x5a\xa8\xbf\xbc\x18\x15\xee\x4b\x77\x4c\x79\x04\x33\x50\x28\xce\x2f\x26\x8e\xfb\x42\x85\x03\xd3\x2b\x1c\x62\xe2\x15\xc3\x24\xea\xdd\xae\x8f\x66\x32\xb9\x1f\xac\x7c\x1f\x49\x5e\xdf\xde\xbd\xa9\x92\x8a\x0a\x40\x12\xd8\x9e\x48\x13\x37\x98\x37\x70\xf3\x8b\xd5\xd3\x7e\x28\x64\x81\xee\xa3\xfc\xf9\xd2\x88\x0a\x01\x9d\xa1\x8d\xa3\xff\xd8\xb8\xbe\xbb\xb8\xc8\x53\x91\x53\xda\x9b\xf6\x0b\x55\xe4\x0b\x70\x75\x07\x63\x23\x40\xc2\x93\xee\x28\x68\xea\xbf\x9f\x89\x1d\xb8\x84\x46\x9a\xf0\xd4\x1e\x8e\x43\x20\x77\x53\xcb\xb8\xbf\xb5\x32\x45\xee\x68\xe2\x51\x9e\xec\xda\x95\x9d\x72\xc2\xbe\xec\xe8\x9a\x76\x68\x92\xc6\xa4\x32\x94\x43\xdd\x3c\x94\x45\xd7\x6b\x52\x09\xf7\xc1\xef\x5b\x38\xcf\x06\x33\x63\xd2\x52\xd3\xcf\xe9\x46\x2a\xe5\x1b\x44\xc8\x5a\x96\xdd\x03\x70\x9c\x32\x95\x7a\xa8\xac\x15\xea\x0e\xab\xf7\x36\x6a\x9e\xf3\x72\xe5\x2a\x0d\x04\xf5\x3e\x96\xe7\xcb\x76\x35\xa1\xdc\xff\x32\x71\x55\x29\x4f\xb4\x2b\x64\xb5\xe1\x54\xfb\xac\x8d\x9b\xe8\x2f\x91\x42\x8a\x8b\x80\xe2\xff\xc6\xa8\xe6\x3c\x64\xc5\xde\xed\x37\xaa\x9d\x78\xed\x1d\xfe\xfa\xb8\x74\x7f\x12\xb1\x4f\xaf\xd0\xfd\xd3\xdd\x61\x77\xca\x0a\x6b\xdb\xa8\xae\xfc\x32\xe7\xaf\x52\x24\x48\xc8\xcd\x3d\x9c\x9e\xcb\x3c\xbf\x4a\x8d\xfe\x56\x92\xae\x84\xd6\x9e\xd1\x30\xbf\xac\xca\x73\x55\x7f\xb2\x79\x2b\x99\x70\xb7\x3f\x2c\xab\x36\xc1\x6b\x76\xb2\xac\xec\xbd\xb7\x3b\xa5\x52\xcc\x3c\x1b\xac\x9b\x7b\xc2\xb0\x50\x61\x62\xd5\x35\x36\x95\x12\xbe\x33\xd3\x6e\xaf\x6d\x7f\x39\x4d\x1a\xcb\x0a\x43\x4d\x80\x8a\x6f\x8f\xae\x62\xae\x50\xf3\xd8\xc6\x32\xb2\x42\x95\x89\x2c\x6f\xf3\xe9\xfe\xeb\xd9\xa4\x90\xaa\x74\xa0\x12\x18\xc3\xf6\x2c\x98\xe8\x3f\x38\x15\x74\x19\xef\xdf\x4a\x43\x42\x08\xd5\xbb\xbe\x3f\x7b\x39\x19\xc9\xf5\xce\xca\xb0\xbf\x2b\x1a\x95\x08\xfb\xc5\x64\x77\x3e\xee\xde\xb2\x3c\x9f\xd4\xe4\xd0\xf3\x8c\xbc\xf5\x11\xab\x17\x2c\xa4\x51\xa7\x77\xc7\x94\x91\x2d\x18\xe8\xaf\x3f\x57\xa8\xb3\x9f\x23\x00\x0d\xb2\x20\xd0\xdc\xf9\x49\xfc\x1f\xf9\x55\xee\x14\x52\x8e\x4b\x77\x8b\x42\xb5\x6b\xb0\x55\xf4\xf9\x5b\xf3\x05\x99\x62\x04\x62\xd2\x59\xde\x60\xf5\x03\xaa\x2a\x2b\xab\xc5\xb9\x82\x4f\x60\x7f\xe8\x83\xa0\x9d\xd7\xb0\x4e\x1e\xb2\xe2\xaa\x60\x88\x01\x24\x14\x00\x11\x8d\xc4\xe0\x37\x67\xdf\x81\x79\x0d\x5f\x8e\x61\x22\x48\x21\xe1\x26\x2b\xca\x5b\xa8\xdc\x1e\x85\x61\x9a\x18\x74\x8f\xff\xed\xf9\xb5\xec\x92\x22\x4c\x98\x88\x4d\x4d\x58\x96\x85\x9a\xf3\xcc\xe0\x98\x84\x92\x6a\xb3\xd6\xe6\x67\x5f\x7e\xc1\xaa\xdc\x14\x06\x13\x31\xb9\xfe\x44\x7a\x24\xc2\x78\x01\xe8\x72\x3c\x4c\x24\x2a\x22\x15\x95\x62\xea\xdb\xc6\x31\xd5\x81\x67\x43\xca\x87\xc8\xca\x8e\x8e\xbf\x9f\xb3\x88\xee\xb3\x6a\xf7\x80\x33\x2e\xce\x2a\x9b\x76\x7a\xdd\xc8\xc0\xc0\xcd\xc4\xf9\xd2\xae\xc6\x2e\x6b\xb6\x4a\x47\x1d\xf2\x00\xc1\xd3\xca\x72\xbe\x4e\xe7\x06\x17\x79\x6e\xb4\x03\xfa\x38\x19\x45\x1c\x7b\x81\x9d\x64\x84\xf0\x99\x7c\x95\xe0\x26\x41\xa6\x04\xa8\x83\x65\xa2\x64\x21\xf5\x2d\x26\x82\xfe\x1c\x25\xc4\x5c\x4f\x6b\x77\xfe\x95\x61\x30\x47\x29\x0c\x76\xde\xd0\xb9\xcf\x0d\xd6\xae\x75\xfb\x8c\x55\x56\xba\xbd\x01\x55\x22\xd2\xc4\x51\x97\x2b\x72\xc7\x9c\xe9\x5a\x23\x72\x2f\x31\x98\x10\x8d\xc5\x40\xc2\x04\x35\x33\xb2\xcc\x75\x53\x9e\xfa\x60\x67\x7c\xe7\xb5\x66\xd4\x10\x2b\xf0\x67\xb3\xee\xdc\xd7\x3a\x41\x7d\xae\x3d\x1f\x1c\xe3\xde\x64\x0d\x8e\x16\xe8\x28\x63\xa3\x8b\xd1\x9e\x2f\x68\xf9\xda\x7c\xb9\x75\x2c\xa3\xd9\xed\x43\x7b\x89\x20\x20\xc0\x81\x50\x77\xc6\x37\xad\x41\xf5\xdd\xb1\x0f\xa7\x27\x66\xb1\xa4\x1a\x83\xa5\x27\xe2\x6a\xe0\x30\x34\x1d\x9a\x30\x27\x8b\xb5\xcb\x1a\xfc\x1c\xf8\xa4\x83\x20\x71\xe2\x16\xbb\x32\x7f\xc7\xca\xfd\xa8\x19\x73\x23\xae\x83\xd0\x60\x9e\x49\x68\xa4\x2c\xf3\x49\x87\x43\x87\x5c\xd3\xcc\x78\xcf\x9a\x67\xac\x7e\x60\xd6\x1d\x10\x7e\xc4\xac\xc8\x8b\xfb\x5b\x24\x03\x2a\xde\x1f\x4b\x75\xce\x9b\x36\x29\x18\xb3\x56\x75\x24\x39\x35\xd9\x8e\x64\x3d\x4c\x5f\xf4\xa4\x3f\xf9\x1d\xb1\xe7\x53\xe2\xa0\xac\x05\xe0\x0e\xe5\x38\x26\xd7\x71\xc4\x9c\x3b\xdf\x33\x54\x70\x9c\xdc\xb2\x18\x62\x1e\xb8\xba\x57\xdd\x8c\x0d\x93\xc7\x77\x21\x56\xdc\x79\x71\x53\x34\xed\xf4\x53\x8d\x72\x35\x56\xa8\x56\xce\xc1\xc5\xfd\x14\xce\x64\xd4\x83\x3e\xe8\x5d\xfc\x78\x86\x4c\x75\xc7\x05\xd2\x44\xdf\xaf\x1d\x7c\x54\x43\x8c\xd4\x1b\x59\x37\xaf\xcf\x39\xaa\xfe\xb6\x08\x16\xa9\x91\xea\x7d\xbb\xdd\x0d\x4c\x18\xb9\x16\xc8\x09\x90\x37\xee\x9f\x4f\xa3\x73\x2d\x74\x00\xbe\x83\x70\x14\xcd\xe7\x26\x3b\x5c\x4b\x30\x61\xba\x41\xc0\x3e\x69\x63\x53\x46\x4b\xf7\x0a\x8a\x49\x54\xa8\x15\xf3\xc9\x84\x1b\x1b\xd9\xfd\x89\x1b\x0e\x38\x16\xaa\x57\x31\xea\x6b\x2e\x5a\x49\x46\x5d\xfd\x0a\x15\x16\xe5\x31\x2b\xc0\xbc\x0a\xd3\x77\x5d\x23\x4b\x29\x43\xd6\x6d\xbe\xba\x2c\x3b\xb5\x39\x8d\xb1\x71\x48\x5e\x41\xfd\xba\xef\x21\xd1\xe0\x79\x81\x30\x1e\xfd\xaf\x28\xdf\x9c\xc0\x85\xd1\xa0\x9d\xfd\xb5\xe0\x79\xa9\x4a\xba\x52\xd3\x33\x5c\x8e\x74\x77\xc8\x1a\x76\xb4\x78\x80\xc7\x44\xa8\xec\xda\xe0\x40\x7b\xe3\x01\x7e\x9b\x42\x50\x20\x6e\x2b\x92\x83\x2e\xd5\x27\x89\xbd\xfb\x24\x2a\x6d\x48\x16\x3f\xad\x27\x29\x56\x0e\x44\x61\x87\x04\x41\x42\xb9\x21\x18\x50\x40\xbb\x26\x59\x32\xec\xad\x85\xdc\x13\x1a\xf6\x7e\xa8\x02\x3c\xbe\xbc\x20\x31\xea\x33\x34\x05\x34\x56\x95\x6d\x44\xff\x36\xbe\x96\x40\x71\xa7\xa2\xb8\xde\xae\x12\x9f\xcd\xb1\x65\xc1\x0b\x34\x32\xb3\x31\xbf\x7f\x72\x67\xc3\x24\x22\xac\xd4\x62\xf7\xe5\x7e\xfd\xe7\x18\xe1\x02\x5e\x08\x21\xda\xda\xf3\xd3\x09\x0b\x6a\x69\x63\xdd\x6c\x8a\x45\xd3\x94\xeb\xde\x9c\xb0\x1b\x2e\xac\x35\xa4\xc6\x85\x52\x9b\xdf\x46\x28\x02\x37\x48\xa4\x8e\xa7\x76\x97\xe9\xa6\x9c\xbf\xf2\x10\x0d\x70\xfd\x98\x75\x9c\xec\x99\xaa\x1d\x78\xa1\x4e\x68\x49\x7a\x39\x77\xe6\x0a\xed\x1f\x65\xea\xf8\x90\xa5\xc2\xb1\x7e\xb7\x1d\x13\x49\x45\x15\xf1\x43\x8d\xcd\x23\x54\xb2\xac\x57\x65\x85\x93\x8b\x99\x3c\x9c\x38\x02\xda\x49\x54\x56\xd3\x63\x37\x12\xcb\xc7\xe1\x0c\x88\xe3\x84\x68\x44\x16\x3e\xd6\x54\x19\x7e\xa6\x58\x02\x5e\x2c\x18\xeb\xc9\x62\xcf\x5d\xba\x08\x5e\x2c\x7d\xe7\x3e\xb1\x2d\x1e\x8e\xb4\xfe\x75\xde\x7f\xe0\x25\x41\x12\xda\x85\xe2\x16\x71\xd0\x68\x9d\xbf\x99\x49\x9b\xb8\xba\x58\xaa\xcd\x2d\x1d\xb2\xc2\x1e\x4f\xc3\x98\x58\xa8\x0f\x97\xaf\x99\xaa\xd7\xea\x6c\xad\xb6\x3a\x18\x3b\x78\x69\xec\x93\x9e\xb6\x8b\x24\x6e\xab\x91\x9b\x06\x78\xdc\x4b\x8c\x63\x8f\xdb\x04\xdb\xe8\xf6\xfb\xe0\xa1\x70\x48\x51\xbb\xe4\x39\x2b\x96\x97\x55\x07\x34\xb4\xba\x71\xe0\x81\xf6\x51\xba\xf0\x62\xe8\x29\x0f\x9e\xf0\x15\x19\x37\x75\x17\x80\x48\x7d\xbd\x1c\xfb\x16\x13\x78\x12\x2c\x4c\x8c\x56\x93\x7b\x23\x27\xdb\xad\x6a\xe0\xa9\x50\x53\x59\xd6\xe9\x71\x3e\xaf\xb7\x9b\xa7\x1b\xf7\x69\x15\x1b\xa6\xc5\x28\x5c\xba\x0a\x7a\x67\x03\x73\xf0\x30\x44\xea\xb6\x52\x69\xe5\x61\x20\x45\x6c\x83\x2c\xf0\x30\x31\x53\xce\x6d\x53\x83\xea\x51\x7b\x10\xad\x94\x4a\x1b\x13\xef\x20\xc7\x1b\xcc\xb3\xa1\x59\xe4\xf4\xfb\x38\x1a\xb1\x49\xfc\x18\xa5\x9f\xf3\x57\xa7\x59\x14\x1b\x71\x9c\xec\x3f\x38\x7e\xfc\xcc\xd3\x89\xe3\x86\x8f\x35\x54\x87\xe4\xc9\x6e\xac\x41\x24\x89\xf3\xc5\x6a\xf2\x5f\x4b\xfa\x00\x63\xa1\xa6\x72\xc6\xa1\x73\x2c\xb9\xf2\x3f\x9f\xd9\xc8\x81\xb1\x58\x52\x5f\x86\x5a\xb5\xed\x73\xb5\xf9\xab\xcb\xd6\x80\xf9\x3c\x52\xae\x4a\x63\xed\xe8\x0d\xa0\x64\x74\x9e\xd0\xf7\x3b\x23\xc5\xa2\xa9\x2e\x03\x9e\x28\xb0\x28\x4d\x49\xc9\x71\xf9\xb4\x7c\x1a\x4e\x61\x16\xe9\x50\xbb\x3a\x73\x5f\xc2\x9a\x5b\xc4\x58\xec\x01\x5d\xc6\x03\x66\x75\x0d\xa3\xb3\xc4\x81\xf1\x90\xb0\x3d\xd0\xef\x65\xd3\xeb\x26\xbb\x21\x91\xa6\x8c\xc1\x0e\x59\xc1\x69\xd8\x3c\x04\x16\xc7\x3e\xe7\xae\x7b\x3d\xd2\x70\x05\x16\x27\x31\xad\x19\xba\xac\x64\x1b\x71\xd6\xe7\x49\x52\x0c\x2c\xb6\xb2\x32\xe4\xbf\x47\x0b\x15\xf9\xaf\xef\x94\xac\xf3\xe1\x3b\xc5\x52\x88\xa8\x06\xff\xb8\xfe\xe3\x79\xb1\x5d\xfc\x82\x81\x01\x8c\x03\x77\x24\xbe\x4d\xd1\xa4\xbf\x75\xf5\x79\x60\x10\xc7\x46\x35\x8e\x74\xaf\x25\xde\xe2\x70\x2d\x63\x20\x43\x82\x42\xb4\x3b\x88\xfd\x31\x23\xe3\x12\x60\x22\xf4\x09\x8f\x4a\x33\x2a\x33\xf3\xcf\x0a\x47\x55\x6e\x8c\x84\x94\x82\x2c\x23\xa3\xbb\xff\xb2\xde\x1e\x1e\x36\x8f\x87\xd5\xd3\xe3\x7e\xbb\x59\xba\x51\x98\x20\x6d\x9f\x15\xc9\x16\xee\xa0\x29\x77\xaf\x59\xdf\x17\x04\x86\x5c\x11\x35\x65\x79\xbe\xfc\x55\x99\x67\x36\x8b\x07\xa6\x63\x23\x56\x41\x26\x9f\xf2\xad\x8d\x02\x56\x9d\x98\x3c\x73\xcf\x40\xab\x80\x96\x5c\xa8\x8e\x97\xe7\x1c\x0a\xac\x57\x57\xb8\xea\x76\x94\x24\x51\x08\xb3\x01\x7c\x29\xab\x1a\x77\xaf\x25\xf6\x24\xd3\xbf\xe2\x19\xfe\xed\xff\x27\xbf\x41\x87\x54\x10\xdd\x9e\xc9\x29\xce\xf1\x01\xc0\xf7\x7c\x65\x81\xde\xc7\xf2\x1d\x0d\x7e\xc3\x1d\x8a\xd1\x22\xc4\x76\x27\x83\x84\x1c\x9d\xd3\xf7\x52\x9f\x58\x25\xd4\x9b\x38\x58\xc4\xfa\x64\x27\xf2\x99\xcf\x3a\x6f\x48\xd7\x8e\xbb\x96\xc1\x06\xbf\x7d\xc1\x92\xfe\x0d\x59\x3a\x4f\x04\x77\x31\x3e\x33\xf2\x63\xa7\xaa\xfc\x5f\x94\xcd\xc4\x63\x0e\x7c\x5f\x21\x55\xb1\xc4\xf9\xb2\xc8\x73\xf3\xf6\x3d\xc3\xa5\x0d\x59\x3e\x2b\xcf\x8d\x2f\x34\x08\x53\xea\xb5\xd6\x4d\x59\x91\xe7\xe1\x0d\x34\x40\xc8\xfa\x11\x8a\xc3\x85\x13\x7e\xc0\x7d\xe1\xbb\x16\x58\x55\x37\xcb\xf3\xe5\xf1\x7c\xd5\xdc\x74\x83\xc1\x04\xc0\x7f\xd8\x7f\x5e\xfc\xcb\xc2\x26\xf8\x61\x94\xb8\x26\xc8\x03\xe1\xd1\x87\x0a\x23\xd7\x17\x1f\x31\x96\x9a\x0a\x2e\xe5\xae\x43\x76\xe6\xaf\xb0\xa8\xe0\xc7\x89\x4f\x7a\x3a\x24\x53\xed\xa2\x40\x3f\x89\x99\x63\x07\xdc\x13\x5f\x62\xba\xe2\xf8\x89\x48\x5c\x9c\x38\x09\xd6\xc6\xe3\x52\x3f\xd5\x76\x11\xd9\xa3\x7c\x2d\x32\x09\xf9\x0c\xa6\x18\xfc\x34\xd2\xc4\x07\x3e\x5e\x3a\x72\xd9\x9f\xdd\x5e\xe9\xa7\x9c\x51\xbd\xc7\x15\xb1\x21\xc7\x4e\x65\x02\x7c\x2e\x25\xd5\x0f\x0e\x0a\x1b\xac\xda\x04\xf7\x79\xe2\xd2\x0e\x3e\x30\x4d\x72\x9b\x5d\xea\x73\x8f\xef\xd9\xb9\xbe\x59\x3c\xcd\x87\x7e\x3e\xf8\x46\x05\xb0\xc6\x66\x7c\xc1\x7f\xab\xf6\x07\xbe\x08\x05\x55\xa3\x4c\x9a\x33\xa4\xaa\xce\xee\xd7\xbe\xf2\x63\xc2\x35\x7f\x74\xba\x8e\xed\x92\x4a\xaf\xca\xb4\x7e\x07\xbe\x92\x40\x27\xd7\xe7\x42\x95\x33\x2c\x6d\xf0\xd1\x37\x15\x75\xdb\xe2\x5c\x17\xaa\xef\xd0\x83\x8f\xb1\xe9\xd0\xbf\x97\x96\x9d\x94\x7a\x83\x3d\xdf\xd7\x1c\xe9\x5a\xde\x10\x57\xd5\xa5\x19\x6c\x76\xbe\x16\xa9\x11\x69\x75\xf5\x59\xfb\x48\x9e\x09\x55\x6f\x47\x05\x5e\x12\x70\x32\x95\x38\xe1\xb5\xa3\x12\x04\x2c\x14\xb4\x5b\xdf\x55\xe5\xf9\x34\xda\xc8\x03\x96\x48\x67\xe3\xf9\xe5\xc7\xca\xee\x1e\xcb\x8b\x29\x07\x8d\x7e\x62\xc0\x20\xd2\x43\x93\xf8\x07\x72\xdc\x9e\x9f\x88\x01\x03\xe9\x76\xb3\x7b\xa8\x1b\x6b\x71\x65\x78\x81\x76\xf7\x9b\x7b\x2c\x01\x13\xcc\xb9\xe0\x1e\x9a\xeb\x87\x68\x47\xf9\x01\x10\xbe\xf0\x61\xf1\x87\xce\x8a\xce\x79\x0f\x02\x3f\x64\x84\xdc\x5d\x28\x35\xa0\x26\x7c\x72\x8d\x7e\x84\x04\x48\xc0\x01\x47\x8f\x90\x1e\xfb\x8f\xd2\x9d\x30\x88\x8d\xf5\x82\x59\xaf\x69\x5a\xb5\xc1\x35\x29\x50\xba\x21\xa0\x75\x47\xd6\x70\xd0\x0b\x8a\x18\x47\xef\x7e\x10\xc8\x98\x59\x63\xf0\xe7\xc5\x6f\xb3\x8a\x60\x73\x8b\x54\x0f\xd6\xfb\xe4\xe8\xe8\x79\x06\x18\x10\x6d\xcd\xae\xdb\x3d\x89\x1a\x82\x30\x64\x04\x26\xa6\xfe\x99\xf1\xa7\x38\xe8\x73\x17\xf9\x05\x61\xa2\x28\xe4\x72\x36\x0b\xb7\xe7\x1e\x8e\x0f\x41\xa4\xd3\xd4\x90\xdb\x55\xf6\x72\x68\x77\xb5\x83\xd1\xeb\x1d\xdf\xd3\x58\x73\x42\x5c\x69\xa4\x36\x60\x5d\x76\x27\x48\x14\xeb\x35\x72\x28\x7f\x59\xb7\xf7\xe7\xb6\xac\x06\x2a\x29\x9f\x13\xff\xed\x59\xd2\xa0\x23\xf4\x6c\xea\xfa\xfc\x09\x72\x1a\x82\x34\x15\xca\x18\x3b\x6d\xc7\xf1\x5d\x90\x82\xb4\x46\x13\x54\x17\xb1\x6d\x93\xda\x2a\xfa\x76\x2f\x65\x90\x02\x12\x42\xdc\xd4\xec\x77\xd9\x4b\x01\xcd\xb9\xba\x86\x86\x8e\x1f\x72\x2a\x34\x51\x64\xda\x37\x7d\xc8\x13\xb3\x87\x21\x95\xb4\x71\xac\x7f\x66\x79\x76\x1e\x25\x78\x01\xa0\x72\xfc\xa2\x07\xc8\x8a\x6b\x19\x0a\x08\x64\xc8\xa2\xb4\x23\x8d\xcc\x2d\xec\x81\xc4\x28\x64\xce\xcb\xec\xb7\x61\xd7\x08\x02\xc5\xb4\x41\x6e\x7f\x60\xd1\x5c\xf6\xaf\x59\xd5\x5c\x06\x52\x45\x10\x20\x24\xa4\x6c\x4f\x62\x8a\xf5\x64\xfe\x6a\x19\x93\x4d\x51\x56\x9e\x47\xd1\x74\xa0\x15\xd3\xa2\xcb\x7e\x21\x27\x7c\xe4\xfc\x7d\xea\x3e\xa1\x49\x7a\x6f\x08\x7a\x18\x75\x8b\x21\xf4\xe2\x80\x80\xe0\xdf\xd7\xbb\xfd\xe6\xf1\xee\x70\xd3\x59\x9f\x42\xe8\x41\x60\x98\x3a\x56\xb6\xe4\x1a\x1f\xd2\x4d\x98\xd0\x53\x29\x35\xe4\xf1\xdf\x83\xc5\x6a\x24\x41\x31\x7c\x7f\x42\x26\x0d\x31\xf1\x83\xee\xed\xbe\x34\xb7\x67\x76\xfd\x08\x7d\xae\x9c\x87\xc5\x4d\x56\x53\x58\x86\xd5\x68\x79\x0d\x7d\x30\x49\xb5\x59\x60\x0e\x99\x2c\x4d\xe7\xfa\xb7\xc9\x99\x40\x87\xa9\x93\xc1\xb3\xaa\xbf\x63\x73\x47\x37\x50\x72\x92\x75\xd6\x65\x45\x21\x7e\xed\x56\xbe\xd0\xd7\x01\xa1\x44\x0c\xf6\x73\x72\x4b\x46\x0f\x32\x0c\xe2\x40\x5a\x7a\x72\x9b\x85\xb5\xc9\x5f\x3f\xef\xc3\x20\x36\x8e\x25\xe2\x5c\x15\x4b\xa8\x33\x23\x55\xeb\x1e\x76\x18\x24\x01\x58\x9d\x42\x23\xd7\x35\xa5\x4a\xcd\x47\x58\x61\x90\x28\x2a\xbd\xe6\x65\xf9\x76\x3e\x3d\x57\x99\xfd\x05\x13\xdb\x43\x08\x83\x54\x46\xfd\x46\xbe\x29\xea\xb3\xcb\x79\xea\xa7\xd3\xc8\x3c\xcc\x6e\xa4\x9f\xfe\xd7\xfd\xfe\xd9\xbf\x0e\xbe\x11\x23\x32\x1a\xfd\xbe\x58\xb8\x5f\x19\x06\x91\xc1\xc5\x1a\xcb\xa0\xbb\x7e\x19\x0d\xc3\x80\x3b\xc7\xd1\xc7\xf3\x91\x4a\x0c\xae\xc4\x3a\xf9\x25\x61\xcc\xa9\x31\xe8\xe4\xff\x2c\x9f\xc1\xf4\x09\x27\x63\xa3\x50\x50\x46\xaa\xf0\x94\x97\x17\x54\x0b\x93\x21\xbb\x2f\x8d\xb8\x09\xa7\x6a\x6c\x48\x4b\xf4\x06\x6b\x59\x65\xa7\xc1\x76\xea\x06\x82\x1f\x1b\x6b\x7a\x69\xc2\x7a\x52\xe4\xaa\xb3\x97\xee\x4c\x18\x68\x1c\xd5\x6f\x8d\x6c\xc0\x78\x8a\xc4\x91\xa0\x75\x2a\x87\xda\x5c\xc8\x01\x98\xe7\x4e\x11\x27\xc6\x48\x8d\xb8\x22\x63\xcb\x76\x08\x13\x16\x9a\x77\x93\x5e\xed\x91\x6a\xf2\x15\xd9\x02\xc2\x24\xf1\xac\x30\x21\xca\xb7\xf5\xcf\x53\x56\xe1\x64\xd9\x09\x93\xc4\x60\x60\xef\xcb\x97\xb1\x39\xc7\xfc\xc3\x4c\x52\xe3\x5b\xf2\xbf\x65\x0f\xbc\x9c\xcc\xff\x44\x22\x06\xbd\xd6\xe2\x1d\x5a\x40\x5f\xfa\xcf\x30\x75\x17\x96\x7a\xa6\xce\xf5\x0a\xf5\x97\xf2\x5c\xe5\x97\x36\x38\xf8\x91\x35\xaf\xd9\x98\x2d\x7e\x4d\x0b\xbc\xfa\x8d\x69\x00\x46\x1d\xfa\x27\x56\x32\xab\xd1\xfc\x4c\xb5\x3e\xd2\x93\x46\x63\xcb\x30\x57\x0b\x0a\x53\x14\x74\xa3\x69\x61\x75\xef\x19\x49\x00\x8d\x75\x3a\x21\xe4\xce\xb6\x61\xf3\xb8\xde\x1e\x56\xdb\xf5\x62\xbf\x79\x7a\x1c\xba\x27\x43\x08\x9e\xa6\x0c\x4a\x52\x19\x21\xef\x75\xa0\x21\x04\xc9\xa8\x18\xdc\x64\xc5\x65\xf3\x7c\xbb\x7b\x6d\x77\xae\xd1\xbc\x12\x8c\x13\x52\x7b\x97\xc1\x0a\xea\xd7\x41\xb7\x21\x14\x4c\x51\xcf\xd4\x6c\x94\x7f\x73\x39\x10\x69\xa2\xad\x76\x04\x11\x7f\x07\xbf\x5a\xa4\x9a\x70\x42\xed\xb4\xdb\x14\x3b\x3c\x66\xc4\xf4\x21\xcf\xf0\xee\x3b\xa5\x95\x77\x35\xf2\xbf\x03\xd9\xf6\x51\x19\x29\x94\x60\x96\xba\xac\xc1\x63\xfd\xa4\x47\x2e\x04\x6e\x88\x30\x04\x47\x32\x07\x3a\xc2\x75\x8b\x64\x72\xe5\x52\xf9\x54\x64\xa4\x30\x4a\x97\xe7\xca\x79\xca\xf6\x15\x99\x50\x31\xae\xd3\x21\xdd\x7b\x21\x09\xd8\xd1\x4c\x28\xb5\x10\x2a\x0d\xd4\x06\x23\xc6\xfd\x8a\x90\xb1\x78\x45\x02\xb0\x63\x31\x88\x0d\x30\xa8\x68\xb2\x7f\x9f\xaf\x5e\x14\xe4\x82\xb8\xec\xb7\x7f\x3c\x43\xb7\x2d\xa0\x62\x21\x1f\x94\xdc\xea\x7f\x9f\xa1\xc2\xae\x61\x0c\xa1\x66\x46\x1f\x6e\xbd\x5f\x55\x65\x5d\x3f\x97\x0d\x34\xa5\xf5\xe1\x9f\x4f\x9d\x42\x9d\xa4\x14\x25\x74\xc6\xcc\xa3\x84\x68\x72\xd1\x5a\xa5\xa9\x11\xd0\xb5\x89\x60\x2f\xce\xd3\x8d\xd0\x74\x43\x0b\xfc\xd9\x2c\x2b\x17\x79\x47\x5e\xa2\x68\x1f\xd2\x88\x56\xbb\x78\x1c\xc8\x45\x5e\x2a\xd3\xe1\xf2\xea\x70\x96\xf6\x30\xe3\x46\xaf\xf9\xa5\x2c\x95\xb8\x4c\xd6\xdb\x88\xb5\x29\x0a\x75\xf4\x87\x31\x58\xe4\xc7\x82\x77\xf4\x2c\xdc\xc8\x31\x7e\x1f\x22\x5f\x18\xd5\x38\x5a\xaf\x5c\xb7\xc6\x7d\x38\x8c\x38\x09\xc4\x7c\xea\x9c\x72\xad\x71\x3a\x3e\x7b\x98\x1a\x49\x44\x50\x8a\xe4\x10\xa7\x75\xb2\xf1\x4f\x88\x62\x88\xb8\xab\xf7\x97\xb9\x2a\x3f\x8a\x29\xb9\x66\x10\x3a\x44\xb1\xb5\x2f\x1d\xd8\x5f\x92\x42\x2a\xf1\xf7\xba\x9b\x1a\x47\x8c\xc8\x48\x54\x00\xbc\x7b\xba\xbf\xe9\x0e\xc4\x31\xc9\x94\xed\xbe\xdf\x53\x1f\x92\x70\xc2\xcb\xf2\xe7\x44\xed\xff\x9f\xbe\x71\x81\xf8\xa7\x6f\x97\xbf\x28\x61\x8a\x1b\x6a\xcd\x22\x3f\xbd\xc2\x7d\xf9\xe1\xc0\x2f\xcc\x8d\x08\x12\x57\xfe\xf8\x8a\x97\xc9\x86\x12\xa5\xcc\x27\xf8\xa8\x3c\x57\x35\xaa\xc9\xc2\x17\xa5\xb1\x22\xd5\xb1\x87\xc5\x1f\x06\xe2\xfa\xfd\xe9\xfe\x9b\x03\xb7\x42\x94\xca\x80\xb8\x1d\x64\x50\x40\xf0\xd6\xab\xf5\x69\xb2\x5c\x47\xdc\x0f\x49\xae\xf3\xbe\xac\x5d\x27\x74\x3e\xfe\x8b\x78\x20\x28\x6e\xe8\xf1\xf9\xba\x6f\xe8\x44\x9c\x63\xe0\x54\x8f\x75\x55\x1e\xc7\x5c\xad\xf1\x99\xc0\x37\x1e\x3a\xed\x76\x6b\x93\x7c\xd9\x86\x0b\xee\x5c\x10\x87\x54\x51\x3f\x66\x79\x9e\x59\x5d\x9b\x3e\x56\x8e\xa4\x07\x42\x3a\x25\x95\x4e\xc1\xe0\xea\xc5\x8d\x94\x4a\x02\xdb\xbb\xdd\x66\xf2\x75\x30\x75\xd1\xe3\xb4\x86\x1f\x3a\xb3\xb9\x4d\xe1\x44\x2e\x1b\x78\xf9\xb5\x08\x07\x44\x28\xfc\x94\x8c\x86\xbe\xfd\xd9\x6e\x3f\x8b\xe7\xc3\xfd\xd3\x8f\xc3\xb7\x5d\x37\x7b\x34\x4b\x90\x24\xbd\xe5\xc8\xc5\x03\x22\x1d\x85\x22\x70\xf8\xb2\xe6\x95\x58\xbd\xf3\xc2\x86\x10\xfb\x5e\x80\x6e\xc2\xe7\x65\x9d\x15\x2f\x4f\x22\xcf\x5e\x06\x5e\x2c\x6e\x2d\x8c\xfd\x94\xd1\xfe\x60\xca\xd4\x7e\x14\xff\xe6\x0e\x88\x84\x72\x7e\x81\xb2\x3c\xe2\xfe\x5c\x35\x39\x9a\xee\x9f\x1b\x11\xb0\x88\xa0\x75\xf6\x1a\xda\x6d\xf2\x19\xaa\xa6\xe8\x50\x44\x10\x87\xe0\x27\x56\x4e\x43\x2d\x2f\x13\xc7\x35\x88\x23\x4f\x2b\xa3\x57\xb4\xa7\xf2\x18\x5c\x2d\xfb\x71\xc4\x8c\xe4\x1a\xd1\x27\xe9\x0e\x5b\x8c\x9a\x3b\xee\x87\xc6\xd7\xe5\xe9\xeb\xfa\xb1\x57\xa1\x87\x38\x52\xca\x35\xf0\xba\x62\x0d\x25\xf9\xc3\xdd\x3a\x8e\x10\x8c\x16\x5f\x3b\x33\xdb\x0d\xb2\xc3\xba\x52\x2b\xc1\x35\xc9\xee\xda\x68\xba\x39\x2b\xac\x77\xd9\x7f\xa6\xcc\x62\x88\x13\x4f\xd8\x69\x25\xcb\x42\x59\x75\x80\x71\x65\x2b\x4e\x03\x3f\x90\x03\x93\xf2\x1b\x6c\x20\xcb\xbb\x3b\x95\x86\x31\x25\xac\x07\xb7\xff\x8c\x0a\x4b\x93\xe7\xcb\x7d\xa3\x24\xf9\x82\xcd\xd3\xe9\x0e\xba\x93\x40\xe0\x81\x71\x13\xa2\x1c\xcb\x38\xd8\x8f\x2f\x15\xe2\x94\xa6\x86\x01\xf0\x5a\xaa\x83\x3d\x26\x02\x9f\x60\xe3\xa6\x6e\x3e\x30\xec\xbf\x8a\x0c\x63\x11\x7b\x89\x1e\xd5\x28\xf6\xb6\x18\x62\x28\x81\xdd\x25\x09\x15\x50\x11\x81\x54\x4a\xbf\x9d\x26\x13\x40\xa2\x8a\x7b\x4c\xff\xe2\x05\x8b\x89\xc7\x2e\xc4\x2a\x00\x4a\xd7\xc4\x80\xe6\xd2\xc7\x40\xb1\x4a\x8c\xbf\xd5\x41\x42\xf1\x00\x0d\x7e\xcf\xc0\x30\x4c\x49\xae\xc9\xf2\xe2\x7f\x3f\xf7\xf4\x78\x88\x15\x8f\xcd\x3a\x59\x1e\x45\x56\xe0\xc3\xe5\x2e\xab\xf2\x4f\x56\x82\x58\x81\x64\xf6\x56\xdf\x3f\xed\xa7\x02\x88\x93\x4b\xd5\x68\xed\x37\x5d\x4b\xf5\xb6\xac\xda\x57\x62\x92\xb9\xc5\xc8\x39\x9d\x54\x61\x8e\x0d\x12\x1f\xcc\xf2\x08\x66\xf1\x1e\x31\xca\x88\x90\xa8\x07\x71\xce\x72\xb5\xb9\x06\x68\x0e\x6e\x08\x2a\x20\x74\xee\x7f\x9f\x4f\xd9\xe0\x65\xd5\x3c\xa1\xe8\xe2\x66\xd3\xbd\x21\x5a\xc4\x54\xab\x3d\x55\xa5\x32\xc2\x4d\xdf\x0a\x8b\x5e\x77\x9b\xc7\x80\xf9\x0e\xb1\x96\x82\x6c\x58\x4f\xe5\x69\x3d\xea\x75\xc7\x1a\x23\x4f\xba\xac\xbc\x0d\xf7\x6e\xcb\x2b\x24\xdc\xe8\x56\x25\x1e\x33\x1e\xcc\x3f\x36\xfb\x2f\x37\xdb\xc5\x8f\xc5\xfd\x61\xed\x1c\x6e\x21\xf1\x7c\xa0\x96\xd5\xe2\xfb\x62\x73\xbf\x58\xde\xaf\x0f\xff\xfd\xb4\x79\xdc\x1b\x11\xb1\x6e\x50\x1a\x45\x38\x28\x4a\x92\x6c\xa9\x3b\x86\x82\x82\x96\x92\xac\x15\x46\x2d\xcf\x84\x05\x86\x53\x7a\xaa\xf0\x80\xdd\x42\x92\xb0\xd4\x8f\xd0\x6e\x0d\x5f\x8b\xf2\x63\x80\xab\x82\xc4\x67\x01\x85\xfd\xbb\x6f\xcf\xcf\xf7\x7f\x1e\x6e\x9f\xb6\x87\xe5\xd3\xd3\xb7\xc7\xfd\x9f\xdd\x08\x3f\xa1\x70\x00\xce\x4d\x79\x4b\xe2\x41\x83\xc5\x3b\xf1\x93\xc8\xb7\x4b\x89\xd9\xb4\xdb\xbb\xd7\x6b\xfd\x42\xe2\x73\x45\x70\x4b\x4a\x60\x0e\x22\xfb\x04\xa7\x91\xf8\xa0\x85\xd3\x0e\xad\xad\xd5\x94\x05\x78\xf5\x73\x20\x09\xbc\x98\xe8\x55\x23\x84\xf0\x5f\xf4\xe5\xdc\x47\x79\xa8\xa3\x81\x52\x7f\x10\x8e\x16\xcc\x24\x04\x45\xe4\x1e\x6a\xca\xb9\x96\xee\xe4\xe1\x86\x92\xb9\xe9\x70\x83\x1a\xce\x79\x6f\x4d\x75\x07\xf5\xb0\x03\x9e\x44\xcc\x23\x41\x0e\x38\x9d\xf2\xcb\x6a\xa0\xec\xf2\x4b\xf8\x4b\x12\x01\x10\xbc\x1e\x8f\x99\xf1\xa4\x91\x2b\x38\x81\x41\x83\x2f\x94\x9a\xca\xde\x59\x50\x47\x12\xb3\x90\x36\x57\x23\xb8\x62\x96\xc7\x41\xe4\x97\xc4\x2c\x02\x47\xa8\x99\xe9\x05\x26\x89\x6f\x54\xb2\xcc\x3b\x02\xa7\x13\xaa\x2b\xdf\xbd\x4f\xee\x6b\x12\x85\x24\x4e\x4b\x5b\xd8\xf5\xa7\xdc\xa8\xc4\xd0\x3a\x08\x82\x9f\x75\x85\xc3\x24\x8d\x02\x69\x5e\xbd\xba\xd9\xff\x31\x85\xad\xff\xfa\x9b\x53\xd0\xd2\x10\x6e\xd5\x59\xe2\x4d\xf6\x7e\xe8\xce\x2a\x3d\xda\xe0\x6c\x4d\x21\xab\x9b\x7a\x53\x18\x76\xea\xf8\x76\xa7\xd2\xd8\x99\xd7\x48\x4a\xde\xa4\xff\x75\xfc\x24\xe9\x49\x78\xc2\xc8\x01\xcb\xf5\x8b\xba\xfc\x25\xe1\x3a\x24\xb1\x2a\x5a\x21\x20\xcb\x0d\xaa\x61\x53\xd4\x67\xad\x33\x99\x21\x59\xeb\xb9\xc1\x10\xf8\x04\xba\x7c\x2c\x6f\xe1\x0d\x07\x69\x74\x02\x89\x55\x8e\x86\x37\xdc\x0e\xf0\x26\xf6\xb0\x88\x84\x01\xa2\x56\x97\x36\xf8\xe9\x4e\x28\x00\x48\x36\x75\xdd\xc6\x33\xcd\xd0\x3f\x14\x12\x81\x21\x6d\x09\x67\x87\x4c\x9f\x93\x26\x86\x44\x45\x3e\x7d\xf3\xfe\x15\x6f\xb2\x97\xac\x21\xe5\xde\x42\x75\x3a\x73\x90\x28\x11\x59\x4a\xca\x31\x2b\x76\x58\x28\x92\x7f\x19\x51\xa0\x21\x41\xcf\x23\xfc\x91\xd5\xfd\xc1\x31\xf4\x28\x41\x8e\x44\x11\x40\x43\x02\x59\x5e\x16\x03\xbd\x1d\x48\x10\x19\xf1\x78\xdd\xdb\x57\x3f\x96\xcd\x6d\x55\xfe\x07\xa7\xaf\x21\x6a\x41\x7b\xf4\x4b\xa6\xdb\x05\xf9\xd7\x75\x86\xd4\x8b\x99\xf3\x33\xbd\xcf\x24\x16\x12\x77\xaf\xe5\x69\x50\x60\xf5\xa7\x1f\x40\x63\x55\x6e\xee\xd9\xfe\xad\xb8\xe6\xad\x43\xca\x38\xd2\xaa\x4a\x18\x91\x01\x11\xc4\xfe\x98\xd4\xf7\x02\x86\x83\xa8\xa8\x0d\x48\xb2\x17\x93\x76\xd5\x43\x2e\x28\xa4\x7e\xa8\xbd\x61\x57\x6d\x5f\x8a\xb3\x7c\xc3\x66\xff\x51\x4e\xad\x9c\xdc\x27\x52\xa0\xa7\x5a\x56\x20\xad\xad\x08\xa8\x61\x19\x7c\xb8\xb2\xa5\x3e\x78\x1c\x3a\xd6\x6d\x27\x4c\x01\xa9\x2f\xf9\xd4\x39\x79\x62\x9c\x0c\xa9\xaf\x53\xd2\x22\xc9\x6a\x8b\x45\xb2\x7f\x0f\x58\x4a\xf0\x06\x0a\x09\x0e\x1f\x23\x30\x2c\xa4\x41\x10\xa1\xd7\x29\x62\x8d\x16\xda\x34\x64\x86\xe4\x66\x62\x84\x1b\x53\xed\x9c\x2c\x48\x69\x98\x70\xd2\x80\x2f\x3b\x33\xdb\x5f\xe7\x1f\x69\xa8\x3c\xea\x07\x82\x35\xe9\x9e\x2e\x25\x73\xca\x30\xb3\x0d\xfa\x34\xf6\x25\x31\x2d\x6a\x22\x64\xf7\xac\x18\x77\x38\x48\xa9\x58\xf4\x88\x1f\x0e\xbf\x3f\xb9\xf6\x18\xa4\x72\x0d\x55\xcc\xd5\xf4\xa8\x54\x84\xa6\xac\x5f\xb3\xa6\xb9\x6c\xa1\x98\x0e\x48\x50\x88\xde\xa6\x72\x91\xe7\xe5\x87\xb1\xec\x9b\xff\xe1\xa9\x67\x88\xc1\x8a\xae\xb4\x7e\x2c\xbb\x87\x90\x7a\x29\xb5\x14\x80\x48\xf1\xaf\xd9\x74\x41\x49\x53\x06\xc4\xec\x39\xc1\x65\xdf\xee\xed\xd3\x96\x76\x9a\xfa\x82\x12\x21\x83\x9d\x69\x66\x24\x76\x3e\xf5\x6b\x81\x94\x33\x8f\x02\xff\x37\xb4\xbd\xe4\xf1\x6d\xe6\x60\x74\xa3\x3f\xa8\xa2\x1a\xaf\xca\x42\x67\xd5\xb1\x9e\x83\x82\xa5\x80\x46\x4a\xc2\x42\x0e\xa1\x26\x10\x9d\x29\x8f\x8f\xaf\x58\x04\x2a\x75\x08\xc8\x3c\x33\x10\xe6\xff\x45\x39\x0d\xbe\x53\x09\x8c\x6a\x5e\x99\x2c\xd7\x9d\xaa\x2e\xa4\x12\x81\x2a\xfb\xed\x42\xfe\x7c\x76\x12\x69\xf4\xf7\x74\x24\x00\x79\x83\xef\x57\x18\x81\x54\x31\xe3\xbb\x0e\x4a\x91\xad\xdd\x6c\x86\x91\xaa\x20\xa6\x1f\x73\x28\x4f\x48\x6d\x85\xed\xe7\xa8\xec\x54\xa5\xb1\xec\x40\x14\x6d\xc8\x77\xb0\x9a\x47\xdd\x7c\xc4\x44\x50\x04\xe7\x26\x23\x6d\x0d\x6a\xbe\x21\x36\x0a\xab\x3f\x79\x91\xb4\xc7\x49\x66\xa1\xc0\x8f\xaf\x03\x1e\x87\x3b\xca\x02\x6e\xe9\x99\xb6\x5b\xc7\xa6\x23\x42\xa3\xa3\x62\x2a\x99\xed\xae\x6a\x78\xfe\xa3\x25\x4f\x27\x86\x7f\x52\xc3\x3b\x0e\x1d\x00\xa7\xd7\x92\xf8\xca\x74\x32\xcf\x28\x40\x16\xcc\xb7\x52\x76\xc0\x3d\x0f\x69\xb3\xb0\x7e\x46\x66\x57\x9b\x8d\xb0\xdc\x07\x02\x49\x70\xa7\x89\xb3\xef\xdf\x61\x84\x01\xf7\x43\x0e\x36\x19\x1b\x2b\xc8\xce\xf2\x07\x3e\x3b\x89\x48\xd0\x92\x1b\xbe\x63\xd1\x9c\x2b\xac\xe9\x61\xba\x9f\x14\x20\x0f\xbd\x41\x14\x61\x6c\x57\x1f\xf1\x63\x8b\xef\x59\x9d\x95\xc5\x63\x69\x7c\x8d\x7a\xc9\x00\xe0\x21\x08\x62\x64\xb7\x73\x0e\x73\x7c\x19\x5a\x94\xfd\xc2\x22\x01\x78\x14\x84\x44\xe2\x5f\x7d\xb9\x7f\xda\x6e\x1e\xd7\x03\x19\x2b\xe0\x51\x08\xda\xa9\x0d\x54\x38\xd4\xfb\x03\x1e\xc5\x9c\xaa\x63\x9d\x24\x7a\x59\x4d\xef\x75\x24\x21\x1c\x40\x61\x56\x70\xda\x22\xc8\xd7\x6e\xe7\xe1\x91\xf2\x28\xcf\xbf\x59\xaf\x1d\x82\x85\xc7\x5e\x92\x50\x79\x71\xf9\xb5\xfb\x93\xed\x24\xbd\xc0\x11\x1f\xf1\x67\xd3\xfd\x3d\x41\x2a\x64\x16\xf8\xd3\xca\xa3\x77\x47\x78\x42\x82\x62\x7d\xfa\x6e\xac\x76\x26\x2b\x1b\x8f\x75\x6a\x56\x4d\x7c\x77\x2f\x3f\x4f\xbc\x90\xce\x6a\xb5\x22\x36\xea\xe7\xe4\x67\xa5\x00\xb4\xa7\xef\x64\x59\x9d\xb2\xf2\x57\x58\x4e\x9e\x82\x61\x66\xdc\xad\x76\xa3\xbb\x47\xd6\x9d\xae\x39\x6f\xfa\x80\xc3\x6a\x18\xe7\x28\x68\x5f\x55\x15\xd8\xa6\xe3\x14\x4e\xf6\x37\xd3\x9e\xff\xeb\xff\xee\xfb\x75\x82\x66\xbf\x7f\x28\x95\xb5\xfe\xed\x10\x1c\x1c\x22\x23\x20\x6a\x02\xeb\x5e\xf3\x79\x7c\x9f\x04\x4b\x48\x7e\xfa\xf9\xae\xfd\x01\xcf\x39\x34\xba\x74\x8c\x45\xe0\x22\x0a\x88\x09\xb9\xc8\x75\x59\x55\xe5\x20\x00\xe6\x42\x32\x72\xbd\x86\x4c\x55\xe5\x69\xc2\x9b\x07\x2e\x7d\xae\x6d\x8e\xd8\x7c\xd6\x9a\xe0\x32\x0c\xa8\x6d\x47\x6a\x95\xb7\x59\x9e\x8f\x6e\xbf\xe4\x06\x94\xd4\x31\xda\x97\x50\xbc\x8d\x19\x26\x5c\x79\xa6\xc3\x6e\x25\x0a\xcf\x45\x73\x19\x4a\x8b\x01\x57\x71\x44\x6f\xc0\xe2\xf9\x79\xe5\xfe\x86\x81\xa9\xf8\xd5\x67\xf2\xfb\xd6\xe7\xee\xb5\x46\x65\xcc\x39\xcd\x44\xbc\x2f\x61\xc6\x95\xc0\x0e\xd5\x2c\xf0\xec\xc3\xff\x78\xc8\x0a\xcb\x24\x03\xf0\x82\x88\x0a\x14\x0a\xdf\x0f\xc7\x71\x37\x17\xbc\x40\x1a\xbd\x0a\xb7\x32\x39\x21\xd1\xab\xfd\x09\xbc\xc4\xb0\xab\x6e\x32\x6c\x3a\x47\x44\x77\x0c\x22\xe3\x95\xdc\x48\x7b\x6f\x26\xcd\x25\xf0\xb4\x36\xde\x1f\x36\x54\x74\x9f\x64\x9e\x91\x3a\x77\x31\xa0\xa1\x7a\x3e\x0f\x64\x49\xc7\xbf\x12\x98\x87\xb4\x43\xec\x7a\x79\x03\x00\x16\x18\x71\x49\x87\x32\x1d\x98\xc7\x01\x30\x65\x0c\x7c\x0c\x04\xeb\xe9\x1d\xab\x9a\x94\x3b\x46\xd3\x0e\xfc\xd8\x48\x53\x55\x96\x92\xb6\x34\x97\x3f\xce\x98\xdd\xd8\x34\x51\x16\x8f\xbf\x91\x25\x9b\x31\xd3\x03\x08\xc0\x38\xf0\x9b\x6c\x66\xc4\x3c\x1c\x7f\x71\x08\x71\x87\x58\x3b\x41\x93\xcd\x78\xfc\xcd\xad\x11\x10\x25\x9c\xd8\x79\xcb\xd7\xc6\xad\x8c\x10\x21\x26\xc1\xa0\xa5\x65\xe3\x22\xca\x2d\x86\x3c\x51\x80\x48\x87\xe4\x87\x77\x7a\x85\x1a\x0f\x81\xb1\x6f\x3b\x0c\x3c\x1a\x01\x62\x16\x21\xda\x72\xc9\xdf\xcc\xe7\x21\xf1\x03\xdf\x73\xea\x0f\x78\x3e\xae\xa0\xba\xb2\xe7\x3b\x4f\x05\x45\xdb\x8f\x25\xf4\x6e\x1e\x07\x3e\x4a\x57\x67\x16\x94\xb5\xd4\xaf\x50\xb9\xd2\xd5\xdf\xda\x7e\x21\x09\x23\x23\x97\x60\x75\x57\x7e\x64\xcd\x6b\x79\x36\x45\x3c\xac\x4e\x54\x88\x9c\x8d\x20\x20\x0d\x05\x55\xd9\x49\x2f\xe3\xb1\x54\x93\xa5\x0a\xb8\xaf\x3d\x03\x77\xc2\xf7\xac\x3c\xd7\x94\xab\x4d\x27\x02\x0f\x7c\x3f\x74\x7e\x31\xd7\xf8\x2f\x37\x8a\x2b\xd2\x16\x2c\x3f\x0a\xac\x9e\xe1\x5c\xe3\x7f\x83\x7c\x3b\x95\xcd\xa0\x80\x05\x5c\xfb\x89\xe8\xfd\x54\xda\xf0\xc8\x1f\x37\x35\x01\x02\x23\x3d\x6a\x8a\x46\xab\xf2\x98\xd5\xf5\x94\xed\xda\x8e\x42\xec\x45\xab\x1f\x33\xf9\x56\xc0\x71\xba\xf5\xbb\xb1\x61\xcc\xe3\x41\x82\xb9\xfd\xc4\x7a\x1c\xda\x29\x19\x59\x80\xe2\x5d\x99\xab\x81\xa1\xca\x18\xb2\xe9\x86\xc7\x22\x54\x43\xe5\xad\xe9\x4f\x91\x29\x91\xd0\xb3\xda\x1a\x2a\x50\xc8\xde\x6e\x77\x75\x03\xc7\x53\xdf\xde\x02\xe1\x49\xca\x34\x96\x59\xf3\xed\x79\xb8\x62\x83\xe4\x48\xc0\xd6\x75\xd7\x7f\xe8\x8e\x08\x03\x51\xae\xb1\x79\xc4\xce\xb2\x6e\xfe\x87\x49\xc1\x9c\x46\xd8\xae\xcc\xcf\x73\x0a\xe7\x76\x24\x06\xca\xb3\x14\xc4\x1f\x98\xed\x33\xac\x98\xfb\x42\x1d\x86\x94\x34\x98\x9a\x1e\x16\x75\x69\xd4\x8c\xc7\x27\xd0\x11\x92\x97\xde\x38\xd0\x5c\xa2\x2e\x2b\xa4\x1e\xff\x67\xec\x68\x00\xcd\xb5\x67\x41\x03\xdf\xdb\x35\x6e\xda\xd4\x02\x2d\xb4\xb6\xcf\x87\x48\x37\x9b\xc2\x0f\x7f\x20\xbe\x99\x95\xe1\x3a\x9a\x1d\xc6\xf9\xe6\x14\xc2\x8b\x8d\xe9\xf5\x31\xcb\xdb\xd8\xad\x18\x6a\x31\xb5\x47\xb5\x03\x86\x4d\x3a\x9f\x76\x00\xf3\x7c\xe2\x76\x66\xf5\x42\xeb\x2c\xcf\xae\x3b\x5b\xa2\x0d\xda\x7a\xf5\xe7\xc3\xf2\x20\xcb\xf3\xa9\xfc\xc4\x1b\x16\x04\x13\x21\x29\xaf\x4c\x3b\x2e\xee\x92\x98\x0a\xe3\x74\xf0\xca\x40\x8e\x33\xda\xdc\x93\x1e\xae\xf0\xa3\x80\x10\x0a\x7d\x51\x65\xb3\x5a\x3c\xb7\x0b\x07\x71\x3e\xb1\x8d\x5a\x66\xfb\xf2\xee\xf3\xd2\xb0\xba\x29\xd2\x31\x24\xb7\x5f\x99\x44\x81\x08\x58\x4c\x3c\xd0\x45\x91\x1d\x21\x77\xe2\x3d\xb3\x55\x5e\x11\xc4\x0c\x8c\x52\x8d\x7b\x1f\xee\x3b\x8e\x38\x88\x00\x98\x76\x6a\x84\xef\x27\x53\xbe\x1c\xac\x21\x22\x10\x9a\xb6\xf1\x76\x6e\x1e\xc8\xfe\xf8\x30\x02\x57\xdb\x61\xa1\xef\xa7\xbd\xca\x90\xb9\xac\x7a\x79\x99\xcd\x8e\xda\xc1\x3a\x18\xec\x9d\xd3\x7b\xf3\xd9\xff\x93\x10\x4d\x84\x61\x4a\xfb\xaa\x59\x96\x6e\xcb\xea\x8d\xf8\xcc\xdd\xc3\x0c\xd3\x80\xf0\x4c\xef\x99\x75\x88\xee\x0e\x08\x9f\x8a\x6e\x56\x3b\x67\x52\x59\x14\xa1\x0a\x28\x01\xb3\xa8\x0b\x93\x76\x98\xd2\xd0\xf4\xa7\x44\x71\x42\x8c\x2b\x6a\xf8\x77\xb6\xef\x65\x65\x24\xd9\x0d\xbd\xfa\x6a\xde\xd8\xcf\x26\x9c\x77\x3e\x98\x37\x96\x81\x3a\xbf\x4e\x88\x44\x79\xc2\xe2\x44\xf6\xaf\x78\xd5\x80\x15\x89\xf6\x9d\xc3\xe9\xe1\x5c\x0f\xd4\x3e\xdc\xff\xa3\xb3\xa5\x9e\xa6\xc6\xd9\xf2\x3c\x22\xd2\x89\x34\x16\x89\x5b\x11\xca\x06\xbf\x9c\xc5\xb8\xbd\x2a\xb8\x27\xc0\xe9\x43\x67\xcd\xc5\x09\x56\x80\xe0\x91\x4f\x75\x01\x01\xe2\x3f\xf3\xc2\xd1\x20\xb8\x0d\x36\x4e\xd5\x80\x4c\x26\x84\x97\x12\xe0\xdd\x18\x18\x22\x79\xb8\xdd\x56\xe5\xf1\x4b\xd9\xa1\x05\x84\xf0\x8d\x52\x7e\x3b\xb9\x4c\x8b\xcd\x90\xaf\x6e\xcb\xea\x5b\x3d\xed\xcd\x0a\xc1\x91\x7e\x05\xf5\x4a\x6f\x88\x23\xf4\x8c\xd5\x33\x56\x75\x3f\x5d\xa5\x17\x10\x5c\xdb\x5a\xad\xd4\xd3\xc2\x9b\x50\x41\x44\x1d\x15\x6a\xe2\x3a\xca\xca\x78\xed\x15\x2a\x51\xb4\x7f\xed\x30\xd7\x37\x68\x9c\x58\x87\xe7\x40\x3f\x21\x64\x29\xf9\x7c\x4d\xc8\xeb\xd7\xea\x88\x57\x1a\x6b\x20\x30\xe0\x5e\xec\x4e\x30\x62\x60\x08\x94\x8c\x32\xbb\x9b\xcd\x6e\xf5\xf4\xed\x71\x7f\xd8\xed\x17\x77\xeb\xc3\xfe\xcb\xd6\xd9\xb6\x82\x40\xa5\xf4\x00\xe5\xfb\xad\xc8\xca\x62\xa3\xe6\x70\xbe\x42\x0b\xa0\x38\xec\x86\xca\xa4\xcb\x2c\xcf\x3b\xd9\xee\xf1\xdd\x95\x5e\xaa\xb4\x21\x28\x90\xea\xda\xd4\x08\x7f\xfa\xae\xfe\x3e\x44\xde\x48\x96\x78\x24\x48\x61\x6b\xf2\x4e\x4f\xe5\xf7\xf3\x40\x57\x05\x24\x4b\x05\x51\x52\xb7\xeb\x7f\x7c\xdb\x6c\xd7\x37\x87\xdd\xe6\xee\x71\xb1\xff\xb6\x5d\xbb\xae\xa5\x64\x9a\x13\xaf\xb4\x9d\xef\x92\x74\x3d\x8e\x53\x57\x0c\x90\xbe\x8f\x91\xd3\xd2\x38\x94\x05\xee\xab\x33\x2e\x0a\x75\x0b\x79\x8d\x0b\xf2\xc7\x71\xa7\xf3\x83\x80\x16\xa4\x87\xb2\x80\x4a\xbe\x5e\xba\xbf\xdb\xdb\x42\xb8\x86\x43\xcf\x5a\x95\x41\xc0\x8c\x41\x6f\x05\x45\xe3\x4c\x68\x9f\xb1\xb2\xe1\x53\x3d\x7d\xcc\x6e\xc9\x92\x81\x96\x18\x3b\xe9\xc3\xe2\x6d\x8b\x93\x9a\x97\x0c\xe3\xc4\x15\x43\x16\x79\xbe\xcb\x5e\x3a\xc7\x93\xfe\x87\x85\x1a\x08\x64\x97\xd5\x8b\xac\x6a\x93\x57\x52\x7f\xef\x0a\x1e\x32\xf2\x80\x1a\x4d\x0d\x16\x47\x6a\x24\x77\x07\x52\x15\xd9\x19\x71\xc8\xbb\xe5\x50\x26\xa9\xa1\x8d\xb6\x3b\xcf\xcd\x00\x2b\x3c\x5e\x84\x64\x2a\x95\x21\x04\x42\x2e\x6d\xb4\x79\x95\xf6\x49\x9e\xa0\x93\x00\x7f\x3c\x1f\x6f\x36\x37\x5f\xca\x5c\xf5\x48\x06\x49\x66\xfc\xd6\xa0\xa8\x19\x38\x7f\x81\x84\x18\xc9\xce\xa0\xcb\x2d\x0d\x21\xe7\x50\x8f\xe1\x7e\xe3\xaf\x03\x91\x52\xa8\xa5\xcb\xaa\x4d\x04\x6f\x87\x01\xf5\x3c\x73\x4b\x82\x42\x12\xc2\x70\x95\x2f\xb7\x6a\xdf\x18\xeb\xf6\xc7\xb2\x31\x3a\x99\xdd\xed\x04\x34\xc8\x3e\x53\x98\x76\x2f\xf2\x2f\xc9\xe3\x52\xb0\xc8\x1b\xb8\x0d\x3f\xe0\xf1\x2a\x02\x18\x5f\x95\x60\xa0\x42\x27\x5d\x1f\x24\x93\xbb\x2a\x82\xd4\xb7\x77\x95\x48\xa5\xf5\xa6\xd8\x35\xe7\xee\x0a\x05\xf8\xa4\x97\x32\xd0\x66\x29\xfb\x42\xb3\x14\x4a\x92\xc3\x9c\x0d\xdf\xcb\x06\x97\x67\x4a\x31\xb1\xe3\xeb\x3b\x04\xdf\x88\xc0\x21\x95\x97\x98\xee\xc0\x70\x05\x1b\x17\x79\xdd\x04\x0f\xdd\x0c\x57\x91\x11\x86\x7c\xc1\xe6\xee\x8c\x75\x63\x94\x0c\xe7\x1f\x85\x92\x1e\x5a\xd6\xd6\xaa\x3c\x1e\xcf\x45\xe6\xd8\x19\x66\xd6\x4c\xde\x0d\x1d\x7b\x41\x47\xfc\x38\x18\xca\xc4\x01\x46\x59\x80\xd4\xb1\xd6\xe3\x00\xaf\xf3\xfc\xe9\x86\x08\x06\xce\x31\x6a\xf5\xe5\x80\x2a\x6b\x0e\x7e\x64\x8f\x2a\x0f\x8c\x33\x15\x28\xd5\x39\xdd\xa1\x9a\x6c\xe2\xe9\x75\x10\xa8\x3c\x99\x52\x24\xba\x29\xcf\xdb\xb2\x6c\xea\x31\x2c\x73\xbe\x43\x34\x58\x83\x15\xf3\x14\x61\x7c\x9e\xd7\xf7\x4f\xa6\xce\xb8\xb9\x71\xbe\xef\x2e\x26\x57\x4c\x04\x8e\xb9\xf1\xf5\x71\x45\x0c\x32\x2a\xe8\xbb\xc3\x92\x73\x5b\x69\x50\xd4\x34\x98\x0d\xc0\x94\x1f\x19\xb7\xce\xd5\xd3\xee\xc1\x50\xe6\x7b\x97\xee\x4f\xea\x07\xca\x8f\x93\x30\xec\x99\xc4\x9d\xfa\x9b\xfd\x86\x45\x33\xeb\x09\x64\x3f\x1c\xa2\x94\x86\xba\x62\x45\x36\xea\x4e\x15\xd9\x5d\x7a\xa8\x0d\x74\x6b\xb5\xd8\x8f\x7b\x6a\x9f\x34\x5c\xa7\xdf\xa0\x39\xa1\x73\x0d\xea\xf8\x5c\x0d\x3c\xa0\x41\x45\x91\xef\x77\xe2\xbd\x59\x2f\xfc\x0d\x2a\x12\xc6\x69\xbd\x4d\x41\x72\xb8\x5c\xeb\xe1\x80\x4a\x02\x4d\x1f\xae\xce\xc5\x73\x7e\x7e\xc9\x8a\x9d\x31\xe9\x18\x5e\x4f\x07\x8e\xfa\x7d\xb8\xa5\x5d\x11\x62\xc6\xcd\x19\x95\x84\x3a\x75\x86\x86\x79\x5e\x7e\xb8\x95\xc8\x28\x39\x0f\xa2\x70\x95\xa0\x20\x96\x7b\x7d\x42\x99\x41\xde\x06\x50\x03\x03\x04\x50\x29\x37\x04\x45\x53\xac\x34\xdd\x10\xb7\x42\xfd\x33\xfd\xd7\x30\xaa\x50\xa9\x88\x44\xe2\x3c\x54\x1b\x90\xaf\x47\x7a\x28\xd6\xeb\x30\xfb\x4c\x83\x1f\x14\xf7\x3c\x65\xf7\xae\x03\x01\x09\x0f\xb4\x88\x1f\x94\xe5\x20\x8e\xd3\x47\x05\x09\x90\xa1\x82\x69\x43\xef\x61\xf0\x36\xd8\x11\x02\x58\x68\x1d\x2e\x77\xcd\x98\xc9\xa4\x24\x8b\xa8\xbb\xbf\x7b\x85\xa5\x2b\x4d\x2a\x29\x22\x14\x57\x2d\x7f\x7f\x24\x2f\x0c\x4a\xf9\x56\xcb\x61\xf3\x78\x58\xef\xbf\x18\xb7\x27\x77\x0a\x4c\x62\x5a\x1f\xac\x72\x98\x69\x7b\xfc\x45\xbf\x57\xa1\x8a\x94\x41\xa0\x43\xf3\x4a\x80\x1e\x70\x08\x4f\xf4\x3c\x23\x69\xff\x03\x47\x86\x12\x80\x1e\x0b\xbd\x5e\xd0\x75\x5b\x52\x6b\xc2\xa2\x6b\xec\x22\x3a\x07\xaf\x41\x2f\x8e\x93\x8e\x20\x90\xe5\xa4\x82\x7e\x8f\xba\xf9\xad\x3f\x4e\x5a\x1c\xa4\xa8\x4a\xcb\xfd\x58\xfe\x03\xbd\xd4\x27\xfc\xe2\x73\x59\xee\x5e\xb3\x66\x74\x51\xcc\xf7\xa8\xb8\x4b\x2b\xfa\xff\xb4\x41\x91\xf1\x94\x37\xd8\x04\x37\x28\x08\x08\x56\x46\x32\xfe\x6d\x40\x30\x09\x40\x90\x41\x4c\x45\xeb\x7f\x44\x9e\xd7\x9d\x59\x86\x14\x6d\x1e\x33\xfb\x8a\xcf\x32\x24\xd0\x67\x06\x29\x9b\x43\xdd\x94\x83\xed\x1f\xfd\x34\x20\x48\x70\xe7\x90\x33\xe6\x5b\xda\x51\x41\x9a\xd2\x2a\x54\xe0\xc7\x18\x22\x89\x61\x1c\x0b\x93\xd3\xc9\xec\x94\x61\xd1\xac\xf7\x5f\xba\x63\xed\xe7\xfa\x2a\x17\xf5\x6a\x8d\xd6\xcf\xc4\x33\xab\x7f\xe5\x30\x62\xc0\x74\xaf\x44\xd9\x6e\x03\xbb\xf3\xe9\x54\x56\xcd\xa6\xd8\x97\xe7\xaa\x80\xeb\x90\x13\xa3\x38\x25\x12\xa7\x99\x56\xbb\xf5\xfa\x66\x37\xbf\x22\x62\xa4\x24\xb7\xef\xfe\xe3\x78\xc1\xb3\x03\xe2\xc0\x0b\x6c\xb9\xeb\x4b\x9b\x5c\xde\xd8\xbd\x7d\x49\x13\xa2\xfb\xd9\x71\x60\xf1\x16\xa6\x45\xf8\x90\x15\x4d\xe7\x50\xd3\x0f\x8a\x10\x2d\xc6\xb8\x83\x11\xfc\x8a\x10\xec\x3e\x96\x1a\x5c\x84\x2b\x6b\x74\x96\x5a\xb3\xd7\x2b\x8c\xa8\x80\xf8\x9f\x9f\xfb\xd2\xfb\xf9\xdd\x9f\x40\xe7\x31\x96\x40\x3e\x22\x3b\xda\x8f\x47\xb3\x32\x46\xcd\x9c\xc8\xd7\xf9\xd8\x06\x7f\xe4\xf1\x23\xcb\x2e\x99\xc2\x04\x38\xb5\x79\xa8\x23\x41\x68\xd0\xcf\xeb\x32\xf6\x23\x69\x9a\xc6\xa4\x18\xef\xce\x91\x82\x24\x08\xca\x7e\xbb\xb8\xd9\x3c\xde\xb5\x39\xd3\x76\xbf\xbe\xe9\x0e\x8b\x98\x92\x8a\x1f\x0f\xab\xd1\xd5\xf1\xd4\x83\xb4\x23\xff\xfc\x20\xb2\xc0\xf8\x9b\xb8\x0a\x52\x8b\x2a\x2f\xca\xa6\xcf\xa8\x91\x6b\x1d\x0f\x55\x96\x4c\x61\xce\x48\xc8\x4c\xce\x01\x9e\xd1\x4c\x21\xb3\x27\x04\x95\x67\x85\xb3\xe1\x01\x84\x28\x4c\xa3\x8e\x6d\xf9\x50\xbe\xe3\x4c\xcf\x7d\x5c\x24\x47\xc1\x42\x72\xac\xa8\xcf\xc7\x2f\x50\xa9\x15\x9c\x46\x29\x24\x8a\xc8\xb8\x5f\x11\x20\x63\xf5\x0a\xd5\x71\xce\x0e\x15\x50\xc4\x1c\x9c\x72\x41\x05\x1f\x33\x6e\xc3\x6e\xa0\xd2\x14\x58\x9b\x30\xd3\x66\x08\xb4\x72\x8d\xc7\x49\x4c\x03\xd7\xc1\x38\xce\xb8\xc7\xb7\x23\x4c\x02\xe3\xfa\x12\x9b\xe7\xee\xaa\x25\x0a\xaa\x7c\xb9\x39\xb9\x84\x7c\x58\xbb\x41\xa9\x05\x09\x33\xae\x9b\x36\x6d\x00\xf7\x67\x15\xa5\xb4\x4a\x1f\x54\x9b\xa8\x97\x97\x6d\x29\xca\xe9\x75\xa9\x18\x24\x1f\x94\xa5\x2c\x2b\xa9\xeb\xc5\x7c\x56\xef\x45\x05\x82\x44\x0d\xde\x8d\x80\xa2\xe5\x27\xb9\x83\x82\x39\xe6\x99\x79\xee\xce\xf4\xb2\xfe\x6d\x26\xcc\x42\xf4\xc2\xd8\x26\x59\xb9\x05\x41\xcd\xee\x49\x88\x90\x7a\x86\x89\xb2\xfd\xba\xde\x1f\x56\x5f\x16\x8f\x77\xeb\xc9\x7d\xd4\x9e\x8c\xe5\xb8\x9a\x69\x99\x0c\x83\x3a\x05\xea\x80\xf1\xae\x4e\xb1\xcc\x41\xbe\xd1\x62\xf7\x91\x35\xf2\xb5\x1b\x93\x9a\xc0\xd2\x6c\x66\xbd\xe8\xdd\x68\xcb\x47\xad\xb5\xcf\x5d\x33\xd3\xb4\x31\xc7\x65\x74\xed\x79\x01\x01\x3e\x5c\xbf\xa1\x78\x37\xa5\xe7\xed\xa7\x69\xa7\xf6\x42\xe3\x0a\xef\x3c\x68\x20\x47\xc3\x11\xb1\xc7\x99\x0a\xc8\xd9\x50\x63\x77\xd3\x35\x43\x4d\xb2\x00\xa5\xd6\x58\x7d\xc1\xfc\x34\x9f\x80\x68\xdf\xd7\x04\x68\xd8\xbd\x66\xfd\x56\xa4\xfd\x48\x79\x03\x77\x54\x63\xc7\x31\x04\x71\x6b\xdf\x56\xca\x8c\xc1\xa9\x63\x3c\xf4\xbb\x87\xf6\x53\xe3\xc2\xfe\xb8\xfe\x63\x7f\x78\x7e\xda\x1f\x6e\xb7\x8b\xd5\x61\xff\xf4\xdc\x9d\x41\x30\xc2\xe1\x0d\x8b\x06\xee\x90\x04\xd5\x5b\x20\x0e\x5a\xd6\x3a\xf0\xbd\xc0\xda\xdf\x6f\x64\xe9\x54\xcd\x3b\xc3\x87\xeb\x7b\x17\x04\x91\xdf\xab\x62\xde\x9d\x9d\x04\xe1\xaf\xdb\x72\x3a\x10\x46\x2b\xf7\xc5\xa6\xe8\x4f\x9a\x68\x3e\xab\x57\x84\x13\xd6\xcd\x8f\x91\xf7\xc2\xf8\x8e\x86\xa0\x89\x60\xb3\x6c\x5f\x85\xee\x27\x85\x22\x92\x86\xa2\xf2\xf4\x81\xea\xb6\x42\x74\x57\xf2\x3c\xe0\xee\xdb\xc1\x51\x94\x24\x86\x7d\x54\xec\xce\xc7\xcd\xea\x89\x1e\x77\xdc\xd3\x7b\x74\xec\x19\x5b\xa2\x83\xd5\x84\x18\xc5\x51\x93\xdf\x12\x87\x29\x37\x33\x0e\xe5\x1b\x39\x74\x8e\xbf\x2d\x0e\x55\xea\x0d\x9a\x72\x84\xc4\x3b\x91\xdd\x05\xeb\xbe\x2f\x0a\xb9\x61\x4f\x74\xc2\xc3\x63\x45\x4e\xd0\x49\x24\xfc\x5e\xcd\xa2\x9d\x11\xa8\x6e\xcb\xaa\xa3\x90\x77\xb7\x22\x4d\x51\xa8\xbe\x32\xf0\x74\xca\x0a\xca\xd8\xbb\xb9\x95\xca\x50\x18\x66\x7d\x7d\x2a\x8b\x6b\x87\xa6\x41\x2c\xaf\x53\x1d\x29\x74\x2f\xdc\xfa\xe6\xdb\x6e\x10\x28\x6a\xce\x12\x6d\x51\x8a\x5b\x34\x61\xc1\xa7\xaa\x6d\xf3\xf3\x80\x47\x40\x01\x3a\xf9\xe8\x5e\xab\x56\x6a\xae\x3d\xb2\xf9\xfb\x80\x77\xac\x89\x77\xe2\xbe\x1b\x02\x65\x4c\xc3\x8c\x55\x79\xbb\xd5\x7e\x1d\x97\x27\xb5\xf0\x43\xb0\xa9\xd7\xea\x7e\x73\x5b\x56\x77\x30\x3d\xbf\xe0\x86\x4e\x2b\xce\x17\x6b\x95\x3c\xd7\x3e\xd1\x02\xcd\xe3\x69\x7a\xf9\xc6\x27\x6d\xfb\xd7\xb3\xd5\x16\x2d\xb5\x70\x2e\xa4\xcb\x73\x55\x58\x1d\xe8\x5d\x03\xcd\xd5\x6f\x54\x61\x4c\x43\x69\x75\xdc\x9f\xab\x62\x79\xf9\xe2\x70\x94\x6e\xe1\xd3\x2a\x35\xbb\xd2\x7d\xd6\xde\xa8\x9f\xbf\x02\x85\xce\xdf\x69\xc5\x15\x2d\x28\x55\x69\x64\x45\xdd\x4d\xc2\xc0\x94\xcb\x9e\xa0\xce\xea\x61\x54\xa2\x51\x28\x96\x0e\x30\x0c\x07\xb3\x16\x75\x87\xa5\x47\xc2\x20\xeb\xdd\xd3\x33\x59\xcf\xfe\xa8\xe0\x74\xc2\x6a\xf3\x7c\xbb\xfb\x02\xfd\x38\x1d\x78\x14\xe6\xde\x66\x2f\xaf\xcd\xaa\x4d\x9e\x6d\x89\x7d\x7e\xaf\xd3\x1a\x42\x5a\x51\x5c\x77\xdc\x15\x80\xc9\x01\xe1\xd3\x16\x99\xf0\x58\x00\x68\xcb\x42\xcb\x4c\x5d\x83\x9c\x85\xc7\x64\x02\xd2\x29\x6e\xd5\xaf\x1b\x35\xdf\x3e\x12\x9e\x8f\x7e\x94\x76\x68\xbc\xfc\xc4\xfc\xc9\x80\x00\x0c\xc0\xbc\xe9\x28\xec\xb4\x91\xcf\x83\xf0\xec\x67\xc2\x28\x36\xf6\x42\xc6\xad\x98\x9c\x2c\xae\xec\x0e\xdd\xd8\x18\x9d\x98\x67\x1b\x37\x81\x24\xef\x5f\x98\x02\xbf\x84\x17\x45\x41\xd4\xc9\x0d\x9c\xca\xac\x18\xaa\x2c\x08\x2f\xe2\x01\xc5\xb4\x77\x65\xfd\x8a\x45\xbb\xd0\xf7\x4e\xb9\x74\x94\xf2\xe7\xae\x1e\xba\x43\x59\xb5\xc9\xc0\x50\xb3\xac\x2c\xf3\x51\x51\x41\x78\x71\x18\x6b\xa3\x28\xa2\x8e\x59\x71\xa0\xd2\x5a\xd1\x90\xea\xf4\xec\x92\x2d\xbc\x18\xb9\x25\xab\xec\x6d\xd0\xf6\x8c\x55\x3d\x4d\x6e\x84\x97\x5a\x55\x78\x5a\x6c\x5c\xf4\x5d\xb9\x3a\xa9\xf0\x52\x30\x5d\x35\x18\xd6\x32\xfa\x83\x92\x58\x71\xa2\x5d\x46\x4c\x7d\xb2\xef\x25\xbb\x41\xdc\xd7\x9d\xde\xec\xf1\x7c\xb5\x4b\xb9\x51\x49\x4c\x21\x9e\xf5\xd6\x78\x2e\xcb\xdc\x6d\x85\xdd\x89\x94\xa6\x45\x16\x94\x22\x26\x06\xe9\x73\xcf\xbf\x8f\xe3\x7b\x01\x61\x42\x20\x82\xc5\x5b\x56\xc1\xf0\x85\x13\x1e\x44\x21\x01\xf2\xee\xcb\x17\xaa\xd6\xb4\xe9\xfe\xa7\xc2\x9a\xed\x70\x8c\x0d\x1f\xf7\xf2\x49\x7f\xd3\x0d\x04\x49\xc9\x8f\x93\x21\xb6\x71\x13\xf1\x71\xfa\xd0\x49\x78\x20\xb9\x30\xcd\x37\x7d\x1e\x92\x5a\x85\x27\x22\x41\x4a\x0b\x0f\x9b\xc7\xc3\x72\xf1\xf8\x75\xfb\x74\x7f\xdf\x1d\xe3\x92\x62\x19\x5b\x32\x81\xe2\xed\xa6\x02\xb7\x47\x08\x4f\x32\x24\xd9\xf0\xe5\xd3\xe3\xb7\xdd\xe1\x61\xf1\xc7\xe1\xe6\xdb\x96\xc4\x1c\xdc\x08\xc5\x84\xef\xc0\x0c\x27\xf8\x28\xb2\xe2\xe5\x76\xd2\x15\x12\x1e\x4a\xe3\xd4\x5d\xe0\xc7\x0e\xfb\x19\x81\x98\x50\xa9\xc9\x8a\x72\x9b\x66\x85\x63\xe4\x8e\xef\x82\xf6\x23\x52\xab\x22\xc2\xe1\x7d\xd9\xa3\x16\xfe\xd9\x1b\x2d\xfe\x33\xfd\xd7\xb8\x9e\xe6\x58\xdf\xc2\xd3\x20\xc1\x18\xc7\x65\x75\xb3\x51\x36\xcf\x9a\x81\x35\x08\xe6\x05\x9c\xde\xab\x4d\xfd\x44\xbc\xb6\xe1\x4a\x2e\x98\x87\x9c\xc0\xc2\x15\x7c\xd8\xe6\xe7\x93\x9e\x55\xfd\x13\x8c\x79\x9a\x76\xc7\x3b\xb8\x98\xee\x22\xe4\x0b\x55\x7f\xca\xc6\x1f\xa5\x67\x82\xb1\xc8\x98\x06\x3f\x7f\x5b\xde\x6f\x56\x86\x4c\x4e\x09\xa9\xbd\x79\xcc\x67\x48\x3e\x16\x1f\xd8\xbc\xfe\x98\xe8\xfd\xbb\x21\x71\x1c\x9a\x9a\x87\x09\xa6\x1e\xb2\xa2\x7d\x23\xba\x33\x70\x46\xf5\xc5\x7b\x27\x65\x24\x98\x0f\xa1\x35\x3a\x6c\x56\x50\xdc\x64\xb5\x38\x57\x35\xba\x0e\x96\xa9\x2c\xf4\x93\x98\x05\x7e\xc0\x7b\x87\xd9\x76\x8d\x2b\xc6\xed\x7a\xe6\x2e\x25\xe0\x91\x67\x83\x0d\xe3\x15\xf6\xdb\x3c\x20\x78\x3c\xf9\x59\xa0\x7c\xcf\xca\xcf\x3a\x5b\xca\xed\xf9\xda\xf0\xec\x93\x4f\x47\xa8\xa9\x65\xb4\x7e\xbc\x71\x06\xd8\x87\x09\xa9\x44\xb0\xd8\x8f\x08\xb9\x63\xf6\xc7\x5d\xf6\x52\x4c\xee\x62\x1c\x4a\xea\x42\xec\xb1\x6e\xcc\x76\xe6\xde\x2c\x96\x04\x2a\x1a\x0a\x08\x3f\x97\x79\x26\xaf\x24\xfe\x66\x5b\x3a\x82\xb5\xcb\xa5\x74\xab\xff\x0f\x84\xde\xcf\x56\xb0\x94\x21\x09\x3b\x1c\xb2\x7a\x41\x6f\xe6\xa0\x06\x39\x3e\x4b\xaa\x12\x6e\x48\x98\x68\x2c\x71\x0f\xe7\x5a\x0d\x91\x77\x82\x71\x3f\x22\x9e\xe6\x87\xeb\x57\x8c\xdf\x4e\x46\x70\xf0\xff\xfa\x7f\xff\x75\x41\xa8\xd8\x7d\x39\x41\x4e\x09\x46\x1c\xb6\x36\x44\xce\x21\x3b\xde\x3d\xec\xe7\xb7\x48\x06\x5c\xf8\x86\x4b\x53\x37\x59\x41\x51\xad\x3d\x51\xea\x75\xa7\x52\x09\xf7\xed\x98\xaa\xbc\x7c\x6e\xe2\x24\x98\xf0\x80\x32\x05\x71\xbe\x64\xc5\xcb\xba\x96\x55\xf9\x31\xb9\x30\x11\xb3\xc8\x19\x6b\xcf\x6f\x06\x4c\xa4\xc6\x87\xe9\xf0\x02\xa7\x27\xbd\x23\xb9\x91\xdd\x79\xde\x8c\x41\x30\x21\x0c\x1c\x98\x30\x8a\x13\xba\xd3\x6c\xbb\x50\x30\x29\x24\x61\x7b\xcc\xf4\xb9\x19\x58\x02\xb8\xab\x94\xca\xb4\xee\x4e\x65\xed\xd4\x32\xa7\x5d\x80\x5f\x03\x5c\xfe\x69\x65\x80\x04\x53\x49\x4c\x64\x33\x5d\x37\x43\x49\x49\x77\x34\x35\xf6\xa2\x32\xff\x4f\xe0\x8f\x97\x2d\x95\x9a\x60\xe1\x05\x8b\xe7\xb2\x39\x74\x9f\x50\x01\x59\xc7\x9f\xce\x79\xbe\xcd\x4e\xab\xd2\x71\xec\x04\xc3\x20\x25\x98\xa3\x55\xcd\xbf\x6d\xf7\x94\x0e\xbe\x44\xdf\x9b\x4d\xea\x32\x82\xe9\x30\x26\x02\x25\xe4\xf9\x43\x96\xbb\x38\x86\xe9\xc4\x58\xdd\x2d\xd7\xfb\xc3\x76\x7d\xbf\x5e\xec\xd6\x03\xfd\x34\xc1\x34\xc7\x24\x34\xc4\xeb\x6a\xfa\xf2\x69\xf4\x94\x41\xed\xd9\x57\x4f\x39\xc0\xcd\xf8\xbb\x7d\xe6\x99\xe6\x5f\x51\x36\x84\x77\xec\x79\x09\xc2\x67\xcc\x37\xa5\xc5\xd7\xf2\x74\x83\x3f\x87\xdb\xb6\xcf\x12\xcd\x3d\x07\x73\xa3\x9a\x3f\xed\x3e\xb3\x73\xd2\x67\xdc\xa7\x97\x6d\xff\xb4\x5f\xdc\x1f\x2c\x4f\x79\xf9\xb4\xdf\x3f\x3d\x1c\x96\x4f\xdf\x1c\x0e\x59\xf8\x7e\x02\x24\xdc\x42\xfd\x85\xfb\x9b\xc3\xfd\x62\xb9\xbe\xef\x0e\x4a\x2f\x72\x36\xaa\xbf\x8d\xce\x1f\x84\xc0\x3b\x85\xa5\x7a\x79\xf9\xd1\x26\x4e\xfb\x91\x33\x91\xf0\xc3\x34\x21\x30\xcf\x61\xc4\xe9\x1c\x2a\x5b\xcd\x2f\x87\x7e\x28\x02\xe1\x39\x1a\xe0\xa4\xbc\x25\xfc\xc8\xd3\x89\x41\x93\x64\x44\x9b\x76\x0d\x03\xe1\x47\xbe\x30\x1d\xf1\x60\x74\xe7\xa2\x58\x87\x71\x17\x67\x53\x11\x64\x18\xbe\xfa\x11\x1a\x95\x79\x6b\x3c\x6e\xba\x1f\x75\xf7\x86\xe0\x27\x0e\xa6\xf6\xd3\x71\x80\xd2\x06\xdc\xa4\x1a\x3c\x2e\x17\x0b\x3f\x4e\x22\x63\x6e\x5a\x10\x9c\xf6\x57\xc1\xbb\x1f\x0b\x40\x83\xf2\x6f\x93\xf3\xbf\x74\x67\xb7\x9f\x4a\x62\x4e\xb1\x1e\xed\xba\x9b\xc7\xbb\xc3\x72\xe1\x36\x5f\x3f\x11\x3a\x70\xf2\xb0\xae\xd8\x65\xd3\xc3\x7e\x7b\xf4\xd3\x30\x40\xbf\x93\xfd\xb8\x79\x5c\x4c\x6e\x79\x6a\xad\x05\xad\xb6\xdc\x69\x3e\x90\xf0\x53\x25\x22\xfb\xdc\x0c\xa9\x68\xa3\xa6\x00\x12\x37\x52\xc7\xce\x7c\xff\x7c\x72\x4e\x5c\x9d\x4b\xc0\x27\x7d\xf6\xf6\x63\x49\x04\xbd\xa2\x85\x45\x68\x0d\x7b\x04\xc2\xe7\xe0\x93\xa5\xc9\x33\x5c\xe8\xd5\x9a\xbf\xd3\x5c\x0a\x67\xdd\x49\xcd\x29\x87\xdb\x74\x87\x35\x23\x55\x80\x73\xed\xd4\xa5\x0c\xad\xfe\x0e\xa6\x01\x9f\x0f\x5c\x11\xca\xa7\xac\xb2\x97\x1b\x7c\x77\x67\x00\x30\x99\xb4\x26\x2e\xae\xed\xcf\x4c\xb0\x64\xc2\x17\x9e\x17\xf4\x4c\xe3\x4e\x9d\xee\x9d\x6a\x61\x16\xc0\xfe\x6b\x52\xe6\xe8\x8d\x13\x29\xa7\x45\xe8\xdb\x6a\x71\xff\xd7\xa1\x9b\x2f\x94\xa4\x8e\x30\xdd\xcc\x8e\x33\xd9\x75\x47\xdc\x4f\x91\x22\x52\xb6\x23\x36\xd4\x4e\x10\xbe\xf2\x25\x65\x27\x65\x85\x03\xfc\x9d\xf0\x31\x52\x41\x07\x3a\x6b\x53\x96\x79\xd4\x8b\xf0\x11\x42\x61\x41\x9b\x6e\xc7\x9c\xcb\x66\x02\x0f\x58\xea\x9c\x97\xda\xa5\xe6\x37\xf7\x77\x99\x58\x66\x4d\x3b\x2f\x9f\xcb\xaa\x99\x77\x9a\x10\x01\x63\x82\x34\x10\xe0\x1d\x2b\x78\x21\xeb\xfb\xaa\x0d\x9a\x87\xd7\x1d\xf8\x76\xfd\xf8\x72\x86\x42\xe1\xdf\x0c\x80\x03\x3f\x88\x84\x6d\xb0\x2d\x84\x73\xcd\x17\x41\xe0\x71\x12\x0d\x95\x8e\x90\xf6\x4b\xc6\xb5\x08\x02\x1f\xa8\x91\x76\x82\x4b\x2f\x14\x23\x82\x40\x25\xa2\xb7\xe2\x70\x35\x8d\xbf\x08\x2b\x07\xf9\x5b\x10\x68\x8f\xd8\x99\x86\xc8\xbc\x3b\x8b\x4e\x01\x91\x70\xd5\xe3\xd9\x1c\x84\x41\x10\xda\xa6\xed\x96\x16\x83\x99\x0a\x47\x10\x06\x86\x59\xf0\x9a\xbd\xbc\x62\x3d\x26\x79\x74\x43\x90\x2a\xbc\x0e\x6b\x94\xe5\xbd\x04\xd5\xaf\xb2\xc8\x20\x4c\x74\x68\x30\x5f\x70\xb4\xfb\x9c\xff\x27\x82\xeb\x8f\x8a\x20\x04\xf4\x02\xeb\x7d\x9e\x15\x2f\x4f\xe7\xa6\x6f\xaf\x89\x20\xf2\x90\x2a\x79\x59\xbd\xae\x25\x9c\x5c\x7b\xca\x2d\x3c\x41\xc4\xbc\x34\xe9\xee\xc6\xbe\x42\x62\x13\x4c\x7e\x5f\x14\x86\x54\x7a\x68\x03\x21\x03\xb0\x73\xf7\x7c\x8a\x88\xb8\xbe\xfe\x88\x1b\x49\xa7\xed\x1f\x4b\x31\xea\x59\x8b\x20\x12\xa6\xc0\x4f\xdb\x40\xf7\x7b\x62\x2f\x4a\xe4\xa0\x5b\x73\x37\x60\x24\xb8\x21\xb1\x4f\x33\xcc\x76\x0e\x06\x0a\xcd\xfd\x59\x92\x80\x44\x8a\xa5\x61\xbe\x50\xf7\x83\x24\x50\x66\x66\x44\x2c\x03\xab\x4f\xd4\x3c\xb4\xb9\x7a\xfb\xd2\x1c\xaf\x4c\x00\x44\x90\xf8\x91\xd1\x00\x68\xe0\x05\xef\xb0\x28\x8f\xb6\x81\x9e\xda\x01\x5c\x02\x61\x1b\x56\x4f\x9b\xc7\xc3\xf3\x7a\x6b\xec\x0f\xdc\x25\x71\x1d\x24\x0e\x4a\x4d\x38\xea\xe5\x65\xa3\xbe\x67\x75\x36\x80\x0e\xf4\x5f\xc6\x35\xb7\x6d\x6f\x8b\x72\x32\xab\xfa\x6d\x59\x0d\x6a\x07\x01\x04\x1e\x35\x17\x77\x8f\x5f\x7f\x01\xf2\x69\xc7\xc5\x94\x09\x74\x35\x27\x6b\x10\x9c\x35\xaf\xd7\xf5\x5f\x11\xb4\x21\x07\x0c\x44\x73\x17\x0f\x4f\xdf\x1e\xdd\x1e\x1a\x08\x30\xce\x67\x47\xf8\x69\x5d\x47\x07\x13\x5d\xc8\x58\xf7\xe4\xbe\xed\xca\xf7\xe6\xe8\x7d\x22\x90\x42\xd1\x9c\xea\x38\xc9\x93\xe3\x8a\x25\xd4\x71\xa7\x88\x6a\xf7\xfc\xad\x56\xab\x8e\x29\xeb\x86\x68\x69\x59\x86\xcf\xe5\x0d\x21\x7d\xbb\x0a\x45\x80\xbe\xd1\x16\xa4\xdf\x69\x9c\x84\xdb\x64\x44\xbe\x96\x37\x78\x2c\x27\xdf\x85\xdc\x30\x4d\x2d\xe5\x8d\xac\x55\x46\x12\x1e\x83\xc9\x82\xc8\x62\xc7\x86\xca\x0c\x87\xfa\x2f\x80\x4c\x7f\x4b\x78\x5e\x04\x5a\x25\x46\xdc\x04\x5f\x2c\x67\xf3\x93\xcf\x77\xe3\x35\x65\x06\xeb\xef\x0f\xbb\xd5\x76\xf3\xdc\x86\xe8\x77\x9b\xdd\x7e\xfb\xe7\x61\xf1\xec\x92\xe4\xd0\xe3\x91\x33\xae\x50\x59\xb3\x50\xef\xed\xcb\x3b\xc5\x56\x8b\x90\x01\x97\xc6\xb1\x5e\x95\xcf\xe5\x8f\xe1\x6b\x1a\x32\x61\xe7\x58\x59\x39\x8a\x87\x08\xfd\x18\x29\x3d\x83\xba\xce\x5e\x8a\x36\xc3\xbe\x3a\x67\x28\x05\x75\xe5\x49\x8c\xae\x57\x54\x14\x61\x1c\x78\x54\x70\x33\xcd\x98\xfa\x19\x2b\xe3\x8b\xef\x0e\x87\xb1\x13\xbd\x30\xef\xc9\x46\x2d\x5e\x20\x2b\xea\x59\x4e\xb6\x08\x63\x48\x98\x74\x60\x43\x2b\xcc\x04\x63\x3e\x8d\x08\x93\x24\x75\x9a\x60\x07\xa8\x44\xd6\xd4\x87\x1a\x72\x24\xfa\xbc\xfb\xe2\xd4\x0b\x03\x2b\xee\x63\xaa\x74\xcf\x39\x48\xd2\x22\x7a\x3c\x1f\x27\xe7\x4b\x13\x23\x81\x7d\xb0\x00\xd5\x8e\x22\x40\x76\x4b\xd7\x2c\x91\xcf\xe0\xe1\x73\xdb\x7b\xc8\x43\x46\x77\xee\x0e\x9b\x36\x5a\x18\xf6\x01\xed\x08\x88\x85\xea\x20\xd0\xf5\x09\x8e\x16\x7a\xe0\x0e\x27\x1a\x2d\x5c\xb0\x43\x42\xb2\x64\x94\x8d\x84\xc2\x57\xb4\x1c\x9d\x8c\x3d\xdb\x93\xd6\xf2\xd5\xe1\x37\xba\xb2\xeb\xec\xd6\x1c\x0a\x9e\x10\x84\xc5\xd4\x1e\x77\x84\x4d\x3b\xce\xf0\x15\xdd\x70\xc1\x89\x6f\x54\xcb\x57\x54\x67\x1b\x63\x18\xd6\x72\x7d\x9b\xfd\xec\x75\x06\x5c\x53\x21\x94\xcc\xa7\xdc\xee\x60\x7b\x06\xfd\xa6\x3b\x75\x6a\x1f\xdf\x38\xc9\xb8\x67\x77\xeb\xbb\xf2\xbd\x59\xb4\xc9\xae\xb4\xe8\x1a\x03\x63\x9c\x41\x42\x88\x50\x26\x22\xf1\xac\x85\xde\xf1\xe4\x1c\xb5\x68\x23\x70\x77\x54\x45\xa1\x96\x23\x8d\xc6\x76\xfa\x4c\x1a\x14\xa1\xe2\x28\xed\x54\xbc\xab\xca\x8f\x55\x39\xf1\x20\x15\x21\x46\x86\xba\x92\xd5\xf7\x50\x37\x5d\xf9\x6f\x7c\x1a\xcd\xb8\x74\x7a\x58\x65\xd1\xbc\x76\x6f\x9d\x66\x68\x64\x68\xcd\xe2\xb3\xea\xb8\x14\x22\xf2\xc2\xc0\x6c\xe4\xed\x2b\x50\xe6\x39\x75\x2e\xfe\x5a\x41\x57\x44\x0c\xcd\x2e\xfc\x82\xcd\x4e\xbe\xe2\x71\x16\xee\x3e\xba\xbe\xc8\x97\x40\x3f\xb3\x4d\x9e\x06\x58\x3b\x9a\xdb\xd1\x5f\xb1\x7c\xec\x39\x02\x0e\xcc\x32\x5f\xd6\x85\xac\x2e\xa7\xe6\x2b\x5e\x46\x33\x34\x0a\x20\xe0\x8e\x94\xfc\x35\x93\x6f\x93\x5d\x2a\x0a\x54\x9a\x18\x16\x99\x95\xfa\x74\xf8\xee\xf1\x37\x45\x1e\x52\xc0\x47\x3c\xff\xac\xc0\x8d\x5b\x69\xa2\x38\xd0\xc6\x9c\x0f\xde\xaf\xd8\xa9\xa3\x2b\x89\xe3\x88\x32\x4a\x57\x2e\xb4\x15\xef\xb1\x36\x87\x1b\x9b\x18\x67\x01\x59\x1e\x4f\xed\xb2\xd6\xa9\xbb\xfe\xad\xd2\x67\x14\x73\x83\x02\x2c\xca\xc6\x22\x37\x51\x59\xed\x5f\xdd\x60\xe5\x87\x5f\xca\x73\x17\xfc\x45\xb1\x8a\x65\xa7\xdd\x9a\xb7\x1b\x7b\x35\xed\x6a\x45\x09\xe3\x60\x09\xef\xed\x3e\x5b\xcf\xca\x01\x89\x28\x0d\x18\x41\x9a\xd6\xcb\xc5\xe3\xd7\x81\x8e\x83\x88\xd2\x76\xc9\xa6\xd7\xa3\xc9\xaa\x79\x75\x3f\x11\xa5\x68\xf1\x2d\xc6\x22\xcf\x88\xe6\xb9\xd7\xed\x8a\x41\x28\x22\xee\xc5\x68\xa1\x61\xf7\x99\x1e\x28\x58\x89\x88\xa7\x92\x50\xef\x27\x92\xb0\x37\xb0\xb6\x76\x3b\xde\x9e\x73\xec\x7e\x39\xd7\x86\xbf\x66\xd4\xa2\x8d\xc6\x41\xb7\x4b\x47\xe0\x23\xb3\x00\xf4\x25\xa8\x17\xbc\xcb\xde\xa7\xfb\x53\x04\x71\x4c\x94\x0d\x63\x61\xb1\x29\x9e\x3b\x49\x44\x87\x02\x4f\xdd\x48\x85\xce\xee\x93\x00\x00\xae\xda\x1b\x09\x8f\x53\x9d\x7e\xf1\xf8\x30\x74\x28\x13\x91\x08\x3d\x4a\x82\x89\xff\xfc\x23\xcb\xbb\x29\x27\xb8\x31\xfa\x75\x2d\xcc\xdd\x59\xcc\x2f\xb2\x91\xf4\x04\xd5\x48\xc5\xb9\x2a\x9e\xb1\xfa\xc0\xac\x0d\xfb\xbb\xa2\x61\x24\x25\x37\xda\x49\x43\x10\x1f\x9b\xfc\x46\xa9\xa5\xb2\x2b\x75\x3b\x85\xd8\xb8\x0e\x1b\x29\xdf\x50\xaa\xf6\xcf\x9b\xee\x4f\x89\xf2\xac\xf1\xb8\x0d\xdc\xb6\x78\xca\xb1\xc8\xea\xd7\xb9\x25\x7e\xc4\x2f\x98\x10\xa7\xdb\x34\x19\x69\xe6\xb8\x3e\xc4\xcf\xb2\xbb\x75\x18\x29\x22\x78\x14\xf8\x61\x8c\x98\x6f\xcf\xcd\xb9\xc2\x89\x96\xff\xa7\xb1\xd4\xf8\x7b\x74\x0a\x42\xf4\xe4\x9a\x53\x49\xac\x5a\xf7\x55\x5a\x21\x89\x39\x9c\xe0\xf2\x74\x9e\x85\x1a\x88\xd8\x63\xd2\x91\x90\xff\x71\x46\x67\x44\x37\x1e\x62\x99\xfc\x27\xb8\x34\xa5\x85\x90\x88\x98\xf9\x40\xe4\x19\x4d\x51\xe3\xae\x81\xb7\xa9\xde\x8d\x88\x19\x57\x54\xe2\x3c\x58\x45\xcb\x9c\xd0\x31\xa8\x9c\x24\x0b\x55\xdf\x9c\xaa\xd7\xa8\x30\x14\x33\xa9\xa9\x8f\xf2\xf0\xb4\xdc\xdc\x6f\xf6\x7f\xae\xb6\xeb\x1b\x27\xc5\x2e\x62\x3f\xec\x50\xee\x26\x84\x1a\xdd\x96\x38\xf0\x8d\x3e\x89\xe9\x2c\x2e\xf2\xc9\xca\x10\x07\x56\x90\x86\xa6\xee\xcd\x6a\xb5\xfc\xd5\x22\x18\x07\xca\xd3\x46\x5c\xa1\x1a\xbe\x6b\x71\x80\x22\xb4\x37\xdf\x80\x39\xea\x25\xbd\x8f\xd7\xde\x3f\x22\x8e\x63\xe3\x37\x2f\xcb\xfa\xb7\xf1\x81\xb4\x03\x09\x3c\x9e\x8f\xcf\x65\x9d\x91\x56\x81\x5d\x46\x46\xd4\xb6\xf1\x55\x25\x2c\xa6\xfe\x94\xed\xef\x7f\x2f\x9b\x9e\x25\xe9\x86\xa4\x42\xbb\x86\xfb\x16\x3a\x2b\x47\x11\x27\xc2\xac\xff\x3a\x83\xe6\x9a\x21\x20\xe2\xd4\x1b\xac\xae\xc7\x13\x14\x17\x82\x00\xbe\x5a\xe6\xd3\x64\xb0\xe4\xd4\x21\xd9\x9d\xc5\x31\x6b\x4c\x4f\x7f\x89\xcd\xe4\x5a\x78\xec\xa5\x26\xad\x03\x75\x50\x2f\x3f\x0f\x59\xf1\x8e\x45\x53\x56\x97\x83\x05\x48\x1f\xba\x30\x2e\xe6\x0a\x89\x39\xe2\x5e\x71\x6a\xf1\xcc\x4a\x1e\xd8\x0f\x80\x2f\x8c\x93\xc8\xa9\xca\x1a\x7c\xa2\xa6\xee\x97\xac\x1e\x91\x88\x27\x9f\x88\x8d\xca\x8a\x15\xd9\x21\x3b\xcc\x4f\x46\x02\x23\xc5\xa9\x8e\x56\x05\x0d\x7c\x9a\xfa\x0c\x36\xc4\x58\xa4\x41\x6a\x12\xfa\x8c\x3a\x00\xed\x32\x62\xc8\x5f\xee\x77\xca\xc8\x4f\x27\xf6\xaa\xbf\xaa\x89\xc4\x32\x8a\xd1\xc0\xf6\xc5\x64\x17\x8b\x55\x1a\xab\xb8\x57\x18\x1c\x19\x46\x59\x22\x98\x1a\x4e\x5e\xc5\x8d\x34\x96\xf9\xea\xb1\x6e\xd8\xef\xa3\x2f\x55\x42\x12\x3a\x81\xf0\x42\xbb\xd7\xd2\x95\x03\x63\x0c\x8d\xc5\x43\xdd\xa9\x59\x7d\x2b\x6c\x95\xb3\xdd\xb1\x97\xe7\x8b\xa1\xa9\x0e\x50\x4b\xee\x93\x92\x51\x38\xf7\x05\x2b\x51\xaf\x5e\xc7\xe8\x69\x91\xb0\x30\x40\xd1\xe5\x6e\xf5\x2a\x87\x0f\x41\xeb\x46\x37\x00\x12\xc9\x2d\x1a\xc2\xdc\x85\x7d\x49\x82\xef\xe3\x0a\xa9\x1b\xad\x50\xda\x12\xef\xf7\xac\xc0\x0b\x54\x16\xfb\x38\x97\x83\x24\x7e\x82\x04\x9f\x5b\x3d\x66\x0d\x8e\x2e\x2b\x00\x23\xe2\xf8\x0a\xf5\xfe\xa3\x6c\x37\xa5\x31\x66\x4e\x24\x61\x60\xea\xa0\x4e\xbc\x40\xb1\x74\x14\xc7\x26\x91\xe7\xbb\x4b\x69\xc3\x60\xf2\xec\x5f\xff\x6c\x2a\x50\x83\x49\x65\xc7\xc6\xdc\x74\x71\xff\xbb\x1e\xc4\x08\x49\x0c\x7e\x34\x64\xe6\xdf\xe2\x75\x1e\x3e\x3b\x8f\x93\x58\x32\x03\xad\x43\x38\x06\xed\x1b\x35\x52\x12\x17\x49\xac\x05\xcd\xa0\x43\x85\xb2\xac\x94\x13\x1e\x9a\x32\x22\x45\x92\xb0\x80\xda\x28\x9b\xe3\xa9\xac\x9a\x36\x05\x5e\xba\x73\x24\x7e\xe4\x1b\x4d\x3c\x12\xfc\x66\x87\xda\x50\x8b\xdc\xe1\xc8\xd3\x96\xe5\xba\xac\xa0\x90\xaf\x9b\x62\x7d\xca\xea\x52\xcd\x43\x65\x45\x92\x48\x9f\x81\x13\xa4\x83\xec\x68\x3b\x16\xee\xa8\x32\x31\x05\x28\xb5\x87\x97\xe5\xe5\xa1\x6c\xb3\xac\xfd\xe5\x64\xa3\x99\x09\x59\x55\x24\x29\xf3\xb5\xfd\xc0\xe1\xdf\xe7\x72\xc6\x6d\x70\xfe\x32\x52\xdf\xa3\x3c\x69\xbf\xdb\xad\x57\x4f\x5d\xd3\x2c\x69\xdf\x39\x23\xae\x50\xea\xac\x69\xd7\xc8\xa1\x3a\xc5\x68\x12\xa6\xa9\xd1\x4d\x27\xd7\xfa\x4f\xc9\xc5\x7f\x67\xf7\xff\xdc\xee\xb7\x7f\xbd\x93\x54\x1a\x1c\xf0\x11\x15\xe4\xa6\xb0\xf3\xeb\x5e\x5b\x22\xbd\x94\x14\xb3\xd7\xdb\xd5\xa8\xe0\xed\x0e\xfb\x29\xad\xdf\x39\xd4\x8d\x51\x9d\x9c\x4c\x57\x19\x45\xcc\xe4\x61\xc7\x63\xd6\x34\x87\x93\x6d\xa4\xcc\x7f\x9b\x4a\x03\x52\x73\x3b\x95\x95\x2c\x47\x6f\x99\x42\x8d\x36\xe8\x3e\x57\x85\x2d\xfe\x11\x7f\x3e\x57\x0b\x45\x8e\x68\xb5\x8b\xe6\xc6\xe7\xc4\x28\xa2\x1e\x4a\xe9\xfa\x16\x8e\x75\xe0\x4e\x8d\xca\x14\x0f\xc4\xf9\x72\x9f\x1d\x27\x32\xae\x22\x41\x14\xcc\xc9\xd9\xca\x0a\x4e\x0f\x59\x41\xb2\x29\x57\x75\xef\x04\xb5\x59\xd9\x09\x23\xf8\xad\xe9\x04\x05\x44\xa2\x59\x4c\xd9\x68\xf6\xad\xdd\xdd\x60\xf8\xe6\x6a\x00\xaa\x06\xb4\x31\xcf\x53\xe7\x1b\x2b\x52\x4f\x72\xaa\xae\x9e\xe0\xf2\x50\x16\x78\x69\xca\x01\x8b\x58\xa4\x2c\x32\x14\x73\x53\xa3\x7b\x80\x37\xac\x06\x26\x90\x6e\x50\x0a\xa4\x40\xbc\xbb\x1f\xac\xa6\x7f\xd9\xb1\x48\xdb\xf8\x2c\x75\x36\xe4\x1f\x83\xc5\x20\x65\x32\x25\x44\xa0\x55\xbe\xc5\x06\xab\x99\x40\x21\xf5\x59\x42\x60\xcb\xd7\xf2\x5c\xe3\xb0\x6e\x90\xfa\x69\xec\xf1\xbe\x43\x37\x6c\x0d\xb4\xab\x66\x97\x1c\x8e\x7f\x87\x0f\xe6\x09\xdd\x97\x2f\xcb\xf2\x3c\x10\xa9\x9a\x7d\x33\x1c\xc3\x5e\xa4\x01\x53\xb4\xa1\xb4\x51\xce\x8c\x3d\x94\x48\x83\xd0\x57\xb6\x0c\x66\xd0\x3c\x4e\x02\x61\x79\x31\x01\xe4\x2f\x5f\x8e\x34\x88\x15\xad\x43\xed\xac\x2e\xcf\x9f\x44\x0a\x69\x18\x78\xb4\x6f\x0d\xa9\xba\xef\x58\x9c\x67\xb9\x2d\xf6\x33\x91\x17\x90\x8a\x15\x12\x5c\xe4\x06\x65\x56\x7f\xa6\xae\x23\xd2\x28\x02\xcb\x9a\x21\x1c\xff\xfa\x1f\xdf\x36\xb6\xe7\x39\x0e\x14\x67\xbb\xb2\x69\x24\x38\xed\x9a\x66\xcb\xbf\xa9\xce\xf3\xba\xf2\xed\x40\x63\xb2\xb7\x2a\x25\xc8\x32\x1f\xba\x47\x8b\x34\x8e\x0c\x71\xc2\x6a\x12\xd1\x5c\x1d\x67\x57\x69\xcc\x4d\x45\x77\xf1\x88\xc7\x32\xdb\x39\xca\x49\xdf\x0b\x4f\x53\x4f\x13\x78\xd6\xf5\x3a\x6c\x83\x67\x67\x0b\x65\x7f\x25\x6c\x35\xb9\xde\xf6\xf1\x6b\xb3\x31\x2f\xaa\x66\xca\xe2\x10\x29\xf7\x62\x02\xf3\x59\x63\xd1\x6e\x3f\x4a\x79\x98\x50\x0b\xe9\x08\x3f\x6d\x04\xef\x8e\x40\x12\x6a\xaf\x6b\x0f\x99\x06\xd9\x78\xaa\x82\x40\xca\x17\x9b\x76\xee\x43\xa1\x9a\x9e\xc4\x26\x52\x82\xec\x52\xd5\xac\x2a\x8b\x97\x2f\x30\x80\x3a\xb8\x11\x41\x1c\xa9\x31\x03\x33\xea\x3e\x1d\x7b\xe4\x7c\xa2\xb3\x42\x99\x3d\xcd\x02\xff\x3e\x01\x10\xa7\xa2\x4d\x06\x3a\xd7\x9d\xdb\x73\xa1\xb2\xe2\xa5\xb9\x56\x65\x13\xa9\x62\x8a\xde\x83\xd5\x62\x7b\xb3\x78\x7c\x5a\xdd\x2f\x76\xbb\xcd\xca\x7d\xb1\x0a\xbc\xd8\x76\xe3\x6f\xb3\xe2\xba\x79\x91\xaa\x20\x54\x2e\xf0\x7a\xa9\x10\x87\x2c\xd9\xe9\x66\xe5\x76\xdd\x54\x41\x1c\xdb\x14\x67\xdd\xbc\x5e\xb9\xfb\x8b\x14\x85\x9f\xa6\xa3\x40\xf2\x07\x66\xb3\x1a\x25\xed\xd8\x44\x84\x4e\x8a\x4a\x66\x90\xdb\x8e\xfa\x9c\xe5\xaa\x48\xb5\x1f\xf2\x7e\x19\x5b\x92\x23\x5f\x3e\x1d\x13\x01\x51\xb9\x57\x97\xff\xcf\xda\x9f\x74\x37\x8e\x23\xd1\xe2\xf8\x77\x79\xab\x5a\xd4\x82\x20\x38\x80\xff\x9d\x24\xcb\x99\xea\xf4\xa0\x96\x94\x99\x55\xdd\xa7\x8f\x0e\x86\x80\xc4\x32\x45\xaa\x38\xd8\x56\x7d\xfa\xff\x61\x00\xe0\x24\xd9\xd5\xfd\xde\x6f\xd3\xd9\x65\x82\x14\x07\x20\x10\xc3\x8d\x7b\x05\x94\x57\xce\x28\xd3\xa1\x72\xba\xba\xbb\x34\x03\x17\xa1\xfd\x32\xca\xc6\x0e\x57\xb4\x8e\x89\x61\x68\xe6\x35\x6c\x0b\x5d\x2f\xf8\xf9\x27\xaf\x46\x14\x9e\x82\x69\xa5\x2d\xf5\x44\x3b\xbf\x96\xef\x67\xcc\x77\x39\xf0\x01\xbe\x51\x7b\xbd\xc4\x23\x0a\x1b\x6b\x6c\x7f\xc5\x0e\xf8\x69\x3b\x20\xa2\xfb\x77\xf2\xa1\xe4\xe7\xd8\xb3\x4d\xbc\x98\x62\x29\x80\x77\xb5\xab\x9e\xb7\x46\x24\x84\x10\xa3\x30\x53\x9c\x4e\x45\x8e\xc4\x79\x87\xe6\xa3\xac\x57\x42\x82\xc4\x72\xdf\x80\x68\x2e\xeb\x02\x2b\xa3\xc3\x0d\x20\x21\x3a\x11\xa8\x99\xdb\xff\x84\xef\x2b\x27\x0e\x85\x34\xf6\x3c\x03\x3e\x11\x29\x10\x89\x1f\x27\x18\xe3\x60\x5d\x6b\x03\xd8\x14\x3c\x3a\xce\x15\x52\x9b\x98\x9c\x27\x7e\xaa\xab\x76\x25\x91\x50\xce\x5d\xab\xc8\x13\xbc\x3d\x14\x87\x03\x86\x22\x8e\x0d\xee\xf6\x43\x05\xa1\x97\xc4\xc3\x9a\xf7\x4d\x3b\x64\x09\xd9\x45\x12\x25\x3e\x56\xf2\x26\x30\xa1\x8f\x5a\x0d\x44\x12\xd9\x46\x18\xeb\xc6\xac\x3b\x8e\x46\x91\x44\x60\xb4\xcb\x91\x46\xe5\x16\xdd\x90\x48\x62\xca\x8c\x16\x84\xf5\xfc\x89\xf7\xdf\x9a\xc9\xff\xf5\x5f\xf7\x83\x12\x5c\xa6\xf2\x67\x51\xbe\x0c\xfa\xc5\x44\xc2\x42\x41\x7b\x01\xd2\x47\x8b\xf4\xae\xba\xc3\x51\xe8\x00\x40\xb3\x2c\xbb\x2f\xca\x75\x23\xbe\xc1\x65\x6c\x97\x13\xc6\x13\x97\x40\x79\xb8\x42\x44\xd9\x31\x09\x31\x2a\x66\xaf\x58\xe7\x59\xe5\xba\x68\x17\x80\xfb\x9d\x24\x64\x5c\x77\xbf\x63\x7a\xba\x50\x46\x54\x75\x23\x38\x33\x88\x26\x83\xe9\xb2\x32\x26\x83\x27\xe1\x9e\xc9\x12\x7f\xe5\xf2\x65\xb2\x4d\x25\xdc\xa7\x98\xdb\xdd\x36\x67\x28\x87\x56\x21\xe1\x41\x0c\x36\x90\x43\x8f\xd8\x1a\x2b\x2b\xf5\x39\x7e\x04\xe1\x09\xf4\x09\x4f\x3c\xcd\x57\x8b\xe7\xfb\xa2\x29\xeb\xe3\x4f\x80\x49\x00\x96\x08\x6e\x28\x9a\x8a\x92\xcb\x2c\xfd\x0b\xf6\x7f\x36\x50\x5e\xc6\xb8\xaf\x7f\xd3\xff\xb8\xd1\x90\xa0\xcb\xd3\x5e\x15\xa9\xad\xdb\xfb\xab\xb6\x45\x97\x72\x4d\x04\x74\x74\x49\x5d\x7d\xd0\x56\x2c\xec\x08\x29\x7d\x27\x5e\x3d\x50\x2a\xc7\xbe\xa7\x1e\x81\xe5\xc6\x02\xb1\x60\x81\xdc\x02\xe3\xe6\x4d\xf6\x72\xab\x41\x66\xda\x2a\x93\x28\x8f\xe2\xb6\xb2\x6f\xf7\x15\x80\x2d\x12\x4b\x35\xe5\xe7\x5c\x9a\x22\x51\xbe\xc4\x1e\xbb\xcd\x72\xbb\xdc\xfc\x58\xde\xed\x8d\xd0\xcb\xde\xb6\x60\x6d\xdd\x9d\x81\x17\x63\x27\x46\x3b\x31\x6a\x53\xf6\x46\xf7\xc8\xb2\x5d\x0b\x4e\x88\xf4\x4c\xf2\x2d\xcd\x9b\x3c\xed\x76\x79\x4e\x78\xac\x2c\xd3\x32\x8a\x10\x0e\x0b\xfa\x9c\x7a\x92\x9a\x24\x05\xcf\xea\xa3\xec\x3d\x79\x4e\x89\x81\x28\x28\xa8\x79\x7e\xc8\xe0\x9f\x0d\xcf\xeb\x54\x2e\xb2\xa2\x51\xab\xe7\x1d\x26\x88\xdc\x50\x6a\x30\xc1\x26\x13\xf9\x00\xba\x6e\x5d\xff\x9f\x90\xde\xf6\xf0\x38\x95\x3e\x18\x8a\xc2\xd7\xb4\x02\x13\xe9\x74\xd7\x52\x4c\xf6\xca\x0a\xeb\xb2\x38\x15\xf7\x69\x75\x5c\xb4\x01\xd7\x35\xc9\xa5\xe0\x81\x0a\x2c\x7f\xe9\x2b\x54\x35\xa8\x8e\x3f\xa0\x3d\x24\x64\x3b\xd5\xbe\x6f\xef\xe6\xbb\xc5\xf4\x3c\x10\xd8\xe4\xb3\x5d\xaf\x9e\xae\x77\x6b\x1e\x32\x8a\x90\xb8\x59\x75\x4e\x4d\x7e\x69\x10\xe5\xf0\x50\x04\x4e\x63\x0c\x45\x66\xbf\xf2\xea\xd8\x2b\x2d\xba\x29\xc1\xa3\x50\xbb\x48\xfc\x09\xde\xe4\x40\x51\xca\x0e\x88\xa9\x0a\x0c\x36\xdb\xf9\x88\x26\x5b\xfe\x41\x9f\xa6\xe0\x2c\x09\x9c\x0c\xe5\x53\x73\xb2\x5e\x41\xf7\xa5\x59\x12\x49\xd9\xf7\x9a\x18\x05\xb8\x01\xf8\xa2\xbb\x31\x96\x58\x8e\x33\x03\x89\x68\x72\x55\x7d\x03\x38\x4f\xdd\x3f\xce\xc0\x10\x25\xbb\xca\x98\xa9\x7f\x7f\x08\x0e\xe7\x3c\xf4\x90\xe5\xb6\xc9\xdb\xb0\xa7\x4c\xdb\xed\xfe\x56\xd2\x71\x1c\xd8\x70\xe1\x29\xcc\xd4\x2e\x7f\xcc\x16\xb3\x6d\xf7\xfd\x04\x4d\xd0\x63\xba\x2b\xf2\x43\x99\xde\x88\xd7\xb9\x50\x5c\x45\x5d\x7f\xf3\x20\x7d\x3b\x79\x0e\x19\x81\x91\x97\xec\xe9\x16\xba\xd8\x93\x4b\x16\x19\x59\x53\xcb\x2c\x35\xeb\x6a\x23\x33\x61\xa9\x84\x75\xe6\x24\x13\x04\x97\x32\xc1\xba\xa4\x25\x75\xb9\xe9\xab\x72\xa9\x09\xa8\x2e\x0a\xd9\x5e\xf2\xfa\x08\x55\xfa\x57\x9a\x1f\x3e\xc0\xb4\xd9\xf3\x94\x52\x09\xb3\xf6\x67\x48\x2b\xfd\xd9\x4b\x87\x30\x72\x5a\x12\xcb\xaa\x4e\x4f\xad\xed\xbb\x51\x2f\xe0\xc0\xa5\x29\x07\xa1\x5a\x9c\x45\x49\xbb\xfe\x8b\x81\x06\xac\xe0\x3a\xd6\x88\xf2\xc1\xc6\x85\x5d\xb1\x6d\x6f\x86\xe7\x2f\x65\xe1\xa8\xd4\x04\xd7\xca\xc3\x58\x51\x97\xad\xa9\x2b\xca\x81\xfa\x5f\x37\xc2\xc7\xf6\x05\xa7\x75\xbf\x80\xb2\x2e\xd0\xf3\x9c\x6c\x40\xc2\xf3\x0c\x0e\x18\x55\xa7\xca\xe1\xbe\x25\x3c\x62\x56\xe9\x32\x6b\x4d\xd3\x9d\x18\xff\x86\xf0\x02\x86\xe8\xd7\xbc\x38\xa5\x39\xcf\x4c\xf0\xee\x8e\x41\xa0\xec\xae\xf9\xbd\x9d\x82\xc3\xdc\xf5\x58\x0f\x5f\x08\x4f\x87\x89\x4b\x7a\x5e\x91\x64\x08\x41\x58\x84\xad\xdd\x8f\xbc\x96\xc7\x34\x3f\x18\x91\xb5\x5f\x86\x7e\x92\x20\x89\xaf\x55\xcf\xc2\x38\xd2\x6f\x11\x82\x28\x01\xbc\xf3\x3b\x6f\xf7\x05\x09\xa2\x15\x4a\x12\xa1\x5e\xcc\xbe\xaa\xbb\x24\xb4\xf0\x81\x87\xbc\xc3\xb0\x59\x2b\x5e\x4c\x8b\x14\x82\xfa\x02\xac\x8e\x78\x96\x41\xbb\xb2\x91\x89\x61\x8a\x3e\x13\x54\x98\xb6\xab\x0a\xea\x59\x59\xae\xf2\xfa\x3e\x85\x4c\x91\x5f\xc6\x3b\x9a\x08\x7d\x8a\xb0\x7a\xec\xc1\x36\xc2\xba\x37\x67\xa0\x08\x65\x12\x99\x52\xfd\x80\x75\xa1\x32\x24\xdf\xdd\x3e\x2c\x42\x09\xe8\x4d\x9d\x1d\xa0\x0f\xa1\x18\xd0\x7d\xb0\x50\x05\xce\x9d\x7a\x2c\x72\x34\x86\xc3\xa9\x10\xea\xc4\x23\x88\xf6\x1d\xfa\x28\x6d\x14\x29\xfa\xca\xf4\x4d\xfc\xf8\xa0\x4c\xed\x4e\xa2\x09\xef\x21\x61\xd6\x5d\xaa\xea\x55\xbe\xac\x8f\x93\x77\x15\x31\x8a\xc9\x9f\x53\xda\xba\x5e\xdd\x17\x89\x03\x21\x54\xd7\x12\xd0\x3a\x24\xbb\x81\xd4\x81\x1d\xc4\x02\x86\xf9\xbf\xb4\xda\x34\x08\xdf\x5c\xc9\x09\xd4\x47\xb0\x40\x2a\xcb\xd6\xbb\x05\x4b\x44\x5f\xd9\xc6\xe6\x29\x14\xfa\xa6\xc9\x10\x4c\x84\x58\x85\x5d\x3f\x7f\x5b\x2c\xba\x5f\x06\x89\x09\x97\xed\x89\x97\xf5\x4c\xbd\xb6\xd6\x4c\x2d\x86\x62\xd7\x37\x6a\x80\x6d\xc0\x86\xb1\x53\xe5\x78\x35\xb1\x85\xdf\x15\x43\x45\xe2\x19\x36\xf1\xd4\x29\xe5\xcd\x72\x35\x2f\xf9\x30\xa5\x20\x04\xa7\x8e\xa5\xcd\x3c\x8b\xed\xd6\x1b\x2f\x28\x49\x42\x74\x39\x67\x59\xf6\xd0\xb7\x26\x08\x19\xc6\x41\x57\x84\xb9\xe2\x08\x15\x42\x09\xdf\x81\x59\x3a\xb1\xcd\xdb\x33\x12\xb8\x96\x4e\xf9\x19\x17\xeb\x3d\xc0\x38\x7f\x34\x86\x1a\xf5\xff\x0c\x66\x09\x28\xa3\x6c\xa9\x20\x1b\x02\x0c\x6e\x57\x1e\x84\xe6\xa6\x6b\xe0\x81\x9f\x44\x51\x0f\xa6\xa8\xf4\xb4\xf2\x2d\xf2\x0c\x6b\xc1\xb8\xb7\x74\x9d\x13\x37\x38\xf3\x84\x24\x94\x46\x96\xc2\x12\x25\xb6\xca\x1e\x23\x2d\x7d\x21\x8d\x84\x23\xce\x78\x23\x72\x3f\xfc\x8c\x92\x7a\x5c\x19\xe2\x40\x94\x3a\xfe\x8c\x93\x58\x48\x4a\x68\x68\xd3\xc5\x45\xd3\xbb\xf8\x26\x43\xd1\xf1\x75\x08\x49\xa9\x61\x68\x79\x04\x85\x84\xce\x03\xde\xef\x6a\x3f\xf8\x8f\xaf\x80\xb4\xfb\xf6\xac\xd0\xe7\xd4\xa8\x74\x1f\x16\x19\xaf\xaa\x54\xfe\x72\xc5\xa1\x27\x64\x48\x25\x46\xc3\x8f\x05\xbe\x93\x34\xeb\x4e\x8f\x0c\x0b\xc4\xd3\xf7\xc7\xfd\xf3\xfd\x7e\xf1\xf5\x79\xb5\x70\x74\xa2\x42\x46\x44\x19\x2e\x15\x80\xba\x39\x4f\x01\xd7\xff\x85\x3e\x9c\x90\x51\x60\xbc\xef\x8a\xa7\xbb\x6e\x71\xcb\x48\x84\xf8\x86\x4d\x03\xc8\xf2\xbd\x86\x7c\x94\xaf\xec\xe7\x88\x8c\x14\xc3\x36\xe0\x39\x22\xc3\x1b\xc7\x93\xf7\xcb\xe4\x67\xb4\x07\x72\x8c\x0f\xef\x14\x14\xc6\x23\x63\x2f\x32\x79\xf2\x46\x64\x69\x75\x04\x53\xc4\x9b\x86\xc9\x32\xf6\x15\xee\x8b\x6f\x45\x59\xd5\x0b\x5e\xc1\x86\xd7\x60\x08\xa5\x57\xf9\xfc\xec\x96\xa3\x8c\x03\x5f\x5b\xd2\x9e\x6d\x0d\xe7\xe7\x1c\x86\x35\xb1\xf1\x4f\xb3\xd0\xe8\x3c\x8a\xa6\xcc\xdb\xc5\x77\x2b\x52\x95\x2c\x89\xb4\xe9\xff\x50\xae\x57\x64\x7a\x19\x48\x00\x7a\x38\x4d\x9a\x1f\xee\x40\x4e\xc6\x70\x1a\x22\xf6\xeb\xbb\x80\x41\xc8\x21\x39\x33\xe2\x29\x15\xd4\x3b\xcc\x7b\x5c\xce\x46\x74\x76\x72\xba\x60\x0a\xfd\xea\x39\xcf\xb2\xbf\x86\xbb\x81\x94\xbe\x40\x0a\x14\x59\x97\xd9\xbf\xba\xad\x45\xca\x84\xf8\x26\x40\xf9\x03\x64\xfd\x04\x87\xa2\x4e\xf9\x95\x4a\x83\x90\x52\x03\x52\xb4\xf2\x01\x5d\xb1\xbb\x86\x52\xa6\x82\xa1\x8b\x12\x09\xaf\xc4\xc4\xa8\x49\x08\x89\xa5\xc5\xcc\x7b\x8d\xc3\x49\x03\xd4\xed\x35\x08\xda\xc8\x69\x1f\xa0\x7e\x40\x59\x40\x51\xb4\xb1\xc2\x68\x51\xeb\x20\x71\x60\x90\xf6\xe3\xac\xf9\x45\x70\xf9\x32\x94\xd0\x70\x03\x63\x1a\xfa\x0e\x7a\xd7\xbe\x45\xac\x42\xe4\xdc\x58\xda\xc1\xd4\xd5\x4c\x62\xfa\x96\x77\x41\xf0\xe7\x6b\x45\x27\x06\x27\xb5\x5e\xfd\x78\x76\xae\xa2\xd4\x12\xc0\xf1\xc7\x0d\xcb\x82\x9f\xa2\xa1\x95\x47\x63\x6c\x2d\x1c\xe9\xad\xae\x4e\xe7\x6c\x52\x43\xf8\xe0\x6c\x9e\x98\x7d\xa8\x5a\xe6\x0a\x51\xee\x5f\xcf\x62\xf4\xb6\x14\xd1\x9a\x75\x9c\xa3\xf7\xdc\xb2\x73\x7c\x8a\x67\xf8\xf5\x16\x78\x54\xf9\x91\x4f\x3b\xcd\x91\x06\xfb\xe3\xc6\x18\x0d\x37\x8e\x6b\x9b\xb7\xea\xfb\xaa\x94\xaf\x12\xac\xb5\xfd\x2b\x3d\xeb\x8c\x8f\x1a\x1c\x15\xa5\x01\x56\xbc\x90\x96\xe1\x79\x4c\x06\x28\x14\x8d\x42\xcc\x9c\xce\x9a\xfa\x08\x6d\xd8\x3d\x24\x5a\xba\x39\x89\x54\x40\x74\xdc\xdb\x18\xf3\x5b\x63\x67\xf7\xef\x5b\xaa\x54\xa0\x82\xd0\x52\x15\x59\xd1\xa4\x49\x3f\xf8\x67\xae\x88\x0a\x80\x20\xfc\x55\x40\x5d\x17\xa5\x13\x51\x1e\xbf\xa8\x00\x12\xdc\x0c\x17\x9b\xe7\x9f\x77\x46\x27\x66\xf7\x75\xbf\x7a\xda\xff\x5c\xae\xf6\xf7\xdf\x9f\xee\xf6\x8f\x2b\x87\x4d\x54\x61\x14\x27\xe0\x18\xe6\x30\x74\x5b\x2d\x9e\x97\xef\x2e\x24\x1f\xe4\x95\x54\xe4\x51\xe4\x6d\xcc\x05\x3f\xf0\xc1\x9f\x43\x43\x36\xff\x76\x2c\x9e\xdf\xf2\xea\xf7\xa2\xe9\x8e\x24\xa1\xcf\x9c\x1a\xe0\xb7\x8b\x9c\xdc\x67\x94\x84\x88\xd4\x3c\x72\x74\xc7\xd2\x12\xd4\x36\x3d\xe4\x1c\x35\xb9\x76\x85\xf5\xc1\xfb\xdf\xe1\x81\x72\x8d\x03\x06\x5e\x6e\xd4\x58\x5d\x94\xa9\x62\xcf\x37\xbe\x15\x64\xd9\xa2\xe4\xe2\x76\x00\xa8\x62\x15\xb1\x8e\xc4\x7e\x96\x4b\xeb\x50\x9a\x60\x62\xf4\xe5\x2d\xfb\x6f\xf7\x8f\xbd\x00\xf3\x14\xe6\x4f\xba\x5e\x90\x47\x5e\xbd\x4c\xc4\xde\xfa\x9f\x63\xe0\x21\xd7\xc0\xa1\xc9\xab\xeb\x2c\x88\x4a\x3c\xce\x61\x40\x72\x51\xed\x0a\x93\x5c\xeb\x06\x24\x04\x03\x30\xe4\xf7\x9b\xa1\xac\x91\xd9\x34\x4d\x75\xf7\xf6\xfa\x6d\x3d\xbd\xc8\x1a\xca\xab\xcc\xc0\x00\x5b\xa4\x38\x8b\x30\x62\x85\x77\x63\xc1\xdc\xdd\xdd\x5e\x00\x42\x04\xd2\x64\x20\x5b\x87\x6f\xef\x82\xac\x79\x3a\x09\x84\x95\x8c\x42\x9f\xf6\xa6\xb4\xeb\x14\xbd\x6a\x2d\xef\x8d\xa5\x92\xe0\x21\x1c\xe4\x6e\xb5\x58\xee\xbf\xae\xbe\xf4\x9d\x3f\x4a\x79\xb1\x37\x4c\x92\xe0\x9b\xda\x15\x56\xfd\xf7\x6f\xfb\x47\x6e\x96\x31\x94\x8a\x8d\x8a\x16\xc6\x82\x36\xd5\x37\x4e\x2c\x2b\x60\x4c\xdb\x78\x49\xf2\xc9\x4e\xa6\x74\xc8\xd1\x1a\xfc\x0b\xf2\xf4\xdd\xdd\xa9\x8e\x4c\xd7\x7d\x85\xe1\xca\x24\x47\xac\xb4\x66\x58\xd8\xc5\xcc\x2c\x38\xb4\x0b\x78\x71\x82\x82\x23\x19\xe8\x3a\x4e\xc6\xaf\x12\x3c\xc6\x31\xe1\xf3\xb4\x58\x8f\x28\x7a\x05\x78\x9a\xa0\x4c\xc2\xf3\x3b\xc6\xfc\x4f\x50\xbf\x15\xe5\x4b\x7f\x54\xc6\x46\x3f\xeb\x70\xc8\xe0\xae\xec\x42\x5d\x20\xc0\x45\x3c\xee\xf7\xd8\xd6\xfc\x05\x6e\xb2\x0b\xbb\x73\xda\x5d\x08\xfd\x81\xfc\x05\x27\xde\xde\x82\xc1\x16\x45\x9e\x83\xac\x07\x02\x5e\xbb\xe2\x09\xde\x6e\x94\x73\xc1\xa7\x0c\x63\x0b\xab\xec\xf6\x6c\xdf\xd0\x75\xf3\xf6\xf8\xa7\x7d\xcd\x31\xd1\x93\x56\x06\x5e\xbf\xb1\x79\xbc\x8f\x88\x21\xc0\xd7\xda\x55\x1f\xb1\x07\xd5\xd2\x6e\xf4\x53\x0d\xa8\xf0\x91\x92\x13\x72\xd5\x69\xc1\xd8\x43\x81\x32\xcc\x0a\xd5\x39\x4b\xa7\xb8\xc9\xf1\x87\x09\xbd\x98\x39\x99\xb0\x39\xe4\x7f\xb9\x2b\x84\x91\xc4\xbd\xb3\x32\xa4\xa8\xb7\xcd\x02\x84\xb1\x29\xfa\x60\x14\x57\xf3\xac\x5d\x26\xdd\x9b\x0a\xb9\x21\xbd\xc2\x16\x1b\x54\x7e\xe8\x8e\x08\x8a\x5d\x5d\x8f\x50\x73\x55\x64\x19\x2f\x9f\xcf\x83\x64\x33\x44\x24\x66\x30\x22\x02\x36\xc4\xe5\x8e\xc0\x7c\xf0\x6f\xff\x3a\x22\x15\x18\xc1\x33\xab\xd5\xb0\x85\x6c\xe2\x0d\x43\xac\x89\xb2\xca\xd1\x50\xea\xce\xed\x03\xc6\x38\xa6\x0c\xf6\x65\xd1\xde\x26\xb2\xac\x8d\xd6\x10\x30\xee\xe3\x0e\x6d\x59\xad\xd1\x06\xba\xb3\x13\x8b\xf5\xb1\x25\x49\x53\x2c\xb3\x99\x89\x51\x76\x07\x78\xe4\x73\xa3\xae\xd0\x5a\xeb\x89\xb7\x0a\x9c\x87\x8e\x05\x1e\xdb\xaa\xd3\xfa\xf2\xc4\x3f\x50\x90\x16\xc0\x15\x8d\x0c\x84\xb4\x2a\xb2\x57\x58\xe6\xb5\xdd\x48\xa0\xaa\x66\xb9\x1a\xd9\x55\x7b\x8a\x88\x24\x46\xd3\xf8\x41\x9c\xf6\x67\xf7\x18\x8a\x12\xbb\xf1\xb4\x41\x33\x3f\x41\xdd\xab\x0b\x7f\x30\xa9\x95\x30\xc4\x0c\x8f\x17\xc7\xf7\xd7\x7d\x7c\xa0\x14\x19\x12\x2b\x7e\xf9\x1d\xfa\xbf\xc6\x21\x3a\xa7\xa5\x49\x5c\x2c\x51\x28\xa2\xe3\xf0\x99\x3c\x21\x08\xf0\x6d\x1d\x7f\x57\x36\x95\x8b\x25\xf5\x78\x15\x80\x8e\xb1\x05\x0b\xdb\x31\x87\xec\x04\xf6\xb8\xf6\x64\x60\xcb\x98\xe8\x0f\xa7\x58\x6c\x99\x5f\x4c\x2b\xfe\xe4\x0d\x69\xce\xb0\x9e\x7e\x97\x56\x7f\x36\xd5\xbc\xa8\xbb\xab\xa8\x00\x57\xfd\x99\x5f\xee\x61\x62\x60\xb5\xe7\x19\xed\xe3\x87\xd5\x8f\x5f\xdc\x9f\x68\x8c\xd5\xc2\x39\xaf\xa0\x57\x4b\xfb\x1b\x68\xe2\xe7\x31\xa8\xf6\x62\x0f\xe9\xfa\xa1\x3e\x6e\x78\x5a\x81\xea\xa4\xcb\x10\x94\xdc\xfd\x34\x33\xb2\xef\x7f\x14\x69\x3e\x2b\x21\x77\xd5\x17\x4d\x24\x65\x89\x7b\x53\x7b\xb2\xe7\x4a\x75\x87\x34\xc1\xd6\x47\xfb\x5d\x10\x89\xf9\x51\xb3\x9a\x3d\xc5\xf7\x09\x5e\xcd\x39\x38\xe3\x30\x44\xfb\x89\x1f\xa9\x81\x94\xec\x95\x79\x1c\x8f\xe6\x02\x77\xcd\xb3\xa1\x13\x6d\xfd\xf5\x41\xb7\xb7\xa6\x9e\x40\x58\xf8\x91\xe7\x2a\x33\xcc\xc1\x69\x7e\x98\x88\x4a\x4d\xee\x8f\x06\x26\x8b\x08\xb2\x04\x59\xbc\x42\x49\xff\x1b\x58\x90\xa6\x89\x92\xe0\xfc\x78\x5b\xc0\x1e\xb8\x8f\x3a\x90\x21\x22\x85\x2d\x03\x0e\xa8\xa7\x34\xff\x83\xbb\x09\xae\xa3\x38\xc6\x45\x64\x84\xf4\xc8\x7e\x90\x8f\xd1\x11\xf3\xf0\xc3\xd4\xae\x39\xbc\xc8\xb6\x50\x3f\x15\xb5\x9b\xd6\x56\x9f\x62\x08\x78\xd3\x91\x30\xec\xc4\x5d\x65\xa5\x28\xef\xd3\x57\x68\x83\xf4\x6e\x88\x02\x2c\xfb\xda\x2c\x84\x2d\x7f\xb5\x81\xfe\xa2\x00\x47\x30\x32\xec\x50\xd6\x11\x08\xcc\x1a\x75\x64\xde\xd5\xd2\x7a\x4e\x1f\xbc\xcc\x38\xe0\x58\x88\x3b\x23\x7e\xd9\x71\x76\xba\x84\x9f\x8e\x41\x63\x6a\xd1\x74\xe1\x60\x9b\xc7\x36\x3d\x5c\x4d\xa0\xd1\x22\x9f\xfc\x02\x8b\x42\xcc\x6f\xe6\x86\x4e\xbe\x98\x80\x1a\xc7\x86\x47\x33\xa5\x63\x2b\x53\xd3\x7e\xda\x87\xa2\xba\xf2\x9f\xec\xc8\x24\x16\xca\x86\xcc\x7b\x65\xf4\xc1\x95\xeb\xd6\xec\xf7\x2a\x9d\xc4\x86\xc3\x66\xfe\xf4\xd4\xfd\x49\x2a\x3f\xc2\x19\x8c\x73\x72\x50\x4b\xd6\x9c\x68\x2c\xfa\x3d\x6f\xee\x96\x9b\xfd\xfd\xea\xe1\xe1\xc3\xa5\x7d\x4b\x1d\x79\xf2\xe8\x9c\x99\xcc\x9a\xa5\xf1\x7d\xec\xf2\x1c\x9a\x33\xe6\xf7\x94\xcb\x53\x36\xba\xf1\x83\x72\xee\x23\x7c\xc0\xe4\x64\x4b\xae\x0c\x21\x68\x67\x28\x35\xd7\x0a\xab\x9c\xcb\xcd\xc2\xf7\xe9\xdf\xb5\x05\x0e\xfd\x6b\x2d\x92\x98\x58\x4d\x81\xd4\x50\x92\xec\xd3\x5c\xb6\xf1\x66\x47\x3a\xd1\x8e\x71\xe9\x84\x76\xbd\x90\x0f\x66\x92\xe0\x14\x7d\xfa\x54\x16\xbe\xec\x32\x69\x5a\x32\x4f\x9b\x46\xed\xf3\x56\xa6\xf7\xa9\x69\xe0\xb0\x07\x15\x53\x11\xe9\x78\x87\x5b\x27\x6f\x12\x2c\x6a\x25\x01\x03\x4a\x05\x93\x29\xec\x66\xbc\x52\x44\x08\x87\x66\x3d\xc2\x89\x77\x3d\x69\xe3\xc8\xf7\xbf\xb3\xc4\x4a\x47\x4c\xf5\xe6\xf2\xa1\xe0\x7d\x26\xef\xdf\xff\x99\x02\xad\x35\x90\x18\x6b\x60\xdb\xdd\x6c\x28\xe0\x2b\x34\xc4\x42\x85\x5d\x95\x16\xb5\xad\xab\xf9\x65\xb4\xfe\x41\x71\x14\x99\xdd\x1f\xa0\x36\x85\x92\x5d\x4f\x83\xea\x06\x69\xdf\xc3\xf4\x67\x55\xe8\x7a\xdb\x7c\x10\x32\x6a\x1d\x45\x48\xf5\x97\x17\x75\xaa\x2f\x0e\x92\xbc\x37\x4e\x16\xf6\x9c\xd8\xe7\x19\xf9\x25\xd2\xf3\x88\x30\x4d\xf4\xa6\x1e\xf8\x75\xb6\x59\xee\x9f\xef\x91\x30\x69\xf7\xfb\x2f\x6e\x50\x48\x94\x53\xda\x40\xfc\x77\xc7\x36\x95\x9e\x60\x7b\xe6\xf9\xf4\xa2\xb1\x81\x4c\x59\xf7\xe5\x2e\xad\xce\x8d\x43\xa0\x93\xeb\x66\xf9\x5b\xdf\x83\xd9\x4b\x11\x20\xda\xe6\x22\x9e\xee\x3f\x2e\x80\x4a\x8f\x68\x85\xe5\xac\x75\x7a\x3a\xc1\x50\xcb\x57\x7a\x54\x78\xd8\xc2\xd7\xda\xe6\x55\xbd\x6d\xbd\xb3\x6a\x36\x28\x13\x4a\x8f\x6a\x12\x5b\x8d\x13\x39\x3e\x55\x73\x23\x73\x58\x4c\xf4\xf9\xa5\x17\x10\x43\x06\x6c\x6b\x4e\x9f\xe5\xba\xa4\x17\xd0\x18\xdb\x5f\x80\xcb\xe3\xf7\xdc\x34\x92\x8d\xee\x20\x48\x14\x9a\xc8\xe3\x45\x95\x85\x6d\x31\x1b\x51\x02\x4a\x2f\x80\xc0\x00\xc9\x4b\x30\x8d\xed\xe0\xdc\xd4\xf6\x98\x44\x2c\x42\xc6\x2b\x53\x5e\xd8\xeb\xd8\x1d\x0b\xbd\x84\xda\xaf\xb7\x03\x7e\xb2\xb4\x10\xd7\x1e\x92\xf4\x42\xc1\x23\x1b\x4c\x22\xc4\xf0\x69\x20\x2b\x6d\x87\x44\x11\x58\xe6\x5f\x30\x7e\x8a\xfb\x95\x38\xf6\x30\xc9\xfc\xaf\xd5\x43\xf7\x27\xe1\x4b\xeb\x11\xdb\x10\x02\xf7\x7f\x77\x98\x79\x1a\x71\xa1\xd5\xb1\x78\xbb\x45\x20\x21\x3d\x16\x79\x58\x52\xcc\x50\x56\xf1\x8e\x5f\xfa\x73\x55\x18\x24\xce\x20\xae\x16\xcf\x37\x57\x85\xf4\x92\x90\x5a\xed\x9a\xda\xf4\x99\xdd\xb0\x89\x9d\x15\x95\x5e\xc2\x23\x43\xdb\x8a\x0d\x18\x8f\x1b\xf7\x6b\x89\xa0\xb8\xb8\xd6\xa6\x8f\x7e\xa8\x76\x3a\xf9\x3d\x21\x02\x87\x6d\x83\xaa\xc6\x52\x71\x77\x11\x69\x6a\x94\xbc\x46\x8c\x41\x51\xae\x14\xa0\x5f\x3f\x79\xe8\x44\xc6\x32\xb2\xd2\xaa\x0d\x54\x95\x25\x19\x68\x63\x92\xf1\x6f\x49\x86\x54\x06\x80\xf9\xdd\x9f\x53\xfe\x40\x6b\xa0\xa4\x97\x68\x86\x79\xe5\x75\xfa\x6e\x64\xf6\xbb\x50\x52\x7a\x3c\x30\xc5\xad\x59\xf6\xc6\x2f\xd5\x7d\x57\x74\x91\x1e\x76\x49\xe0\x9a\x29\x4f\x69\xce\x6b\x07\xb5\xed\x8e\x73\x8e\x84\xb2\x68\xba\xa6\x20\x74\xe9\x09\x65\x18\x5e\x9c\x67\x73\x57\xf2\x43\x47\xa4\x2d\x3d\xe9\xfb\xd4\x39\x3e\x77\x25\x7f\x5b\xf6\xfc\x8a\xd2\x93\xd2\x24\xf1\xac\x1e\x65\x89\x39\x83\xee\x54\xe5\x11\xd4\xa8\xda\x63\x72\xec\xf9\x0c\x86\x48\xc3\x1d\xd5\x81\xc6\xf2\x45\x06\x55\x95\xe6\x87\xee\x34\xa0\x1a\xbb\x12\xdf\xca\xf4\x03\xb6\x7a\xe9\x41\x6c\x4a\xef\x19\xe8\xba\xf5\x3c\x1c\xf6\x4b\xeb\xfe\xe6\x00\x22\xdc\xcf\xbf\xb6\x06\xe1\xa3\xde\x96\xdb\x36\x40\x93\x08\xfa\x6a\xf1\xb3\x6e\x17\xe3\x2c\xef\x3a\x3d\xdc\x2f\x68\x69\x42\xb5\x99\x03\x2b\x4b\x42\x62\xed\x59\x14\x03\x19\xbf\x68\x42\x58\xff\x26\x31\xcc\x37\x0b\xe9\xbe\x2c\x4e\x5b\x28\x87\x05\xcb\xeb\xbd\x5f\x12\x92\x50\x44\x24\x7c\x29\xa1\x8d\x08\x67\xbf\x0c\x0f\xfa\x84\x63\x81\xe5\x01\xcb\x76\xe9\xe9\x97\x0f\x84\xe5\xbb\xe1\x02\x83\x82\x13\x64\x46\xe8\x6c\x7b\x2c\xae\xd2\xd5\x6e\x2c\xf5\xb0\x32\xcb\x71\xa7\xdb\x63\xd0\xe2\x5e\x00\xf1\x99\x41\x32\x3f\x14\x19\x41\x62\xe5\xae\x38\x24\x89\x2f\xb9\x4f\x3a\xf6\x85\xe6\x6c\x39\x1b\xaf\xa0\x79\x6e\xb8\x32\xd6\x2a\xad\x7e\x40\xae\x8a\xdb\xb9\x48\x49\x68\x68\xe0\x88\x4e\x0d\xa9\x5a\xa9\xee\x6e\x82\xd8\xe4\x62\x45\x93\xbd\x20\x8a\xc9\x04\xcd\xff\xfe\xcf\xaf\x37\xf0\x80\xee\x1c\x19\xc7\xc2\x51\x94\x5f\xae\xaa\x6c\x92\x04\xe0\x87\x06\x16\x93\xff\xb3\x49\xdf\x8b\x1a\xae\x11\x27\x92\x84\x9e\xa7\xbd\x41\xeb\xc0\x63\x1b\x08\x4e\x3f\xe7\x64\xef\x34\x6e\xf8\xc8\x39\x77\x57\x13\x9e\x8b\x95\x87\x0d\x0d\xdd\x83\xb6\xc7\x85\x35\xc7\xae\x02\x5c\xcd\x5e\x79\x9a\xf5\x74\x8d\xed\x28\xd3\x0b\xd0\xae\x91\x28\x9c\x3c\x56\x44\x4c\xef\x08\x0a\x2d\xbf\xd7\xab\x13\x3f\x00\x42\x7f\xdd\xab\x22\xd1\x18\xc1\x7d\xb3\xfe\x3e\x7c\x93\x51\x14\xc5\xce\x16\xe4\xd5\x5b\xb7\x0e\x49\x14\x29\xec\x80\x7a\x68\x5e\x86\x4d\x1b\x92\xc4\xbe\x46\x08\xea\xb2\x3e\xfe\x80\x1c\x13\xf5\x41\x77\x2c\x30\x81\x3b\xb2\xea\xa3\xf8\x7c\x5f\xe1\x1e\x3f\x09\x23\x26\xd4\xdb\x72\xa5\x32\xd8\x9b\x1e\x2a\x7b\x0c\xd5\xb9\xcd\x53\xa2\x57\x67\xa5\x85\x6e\xd4\x41\x25\x49\x34\x31\xed\x74\xed\xee\x67\x37\xcc\xf1\x08\xee\x85\x98\xea\x79\x4d\xab\xb4\x7e\x80\xfc\x50\xbb\x1d\x83\x70\xda\xd5\x6d\x77\xfc\x65\x7a\x8b\x22\x09\x3c\x8b\xe8\x7c\xb4\x52\xff\x43\x33\x4a\x44\x62\xa8\x33\xac\x40\xdf\xb0\x41\xcd\x2c\xe4\x61\x94\xde\x0e\x97\x58\x6c\xb2\x6c\x3f\xb7\xd3\x9e\x9f\x79\xce\x92\x48\x11\xe3\x6e\x6b\x63\x77\xd3\xc1\xe8\x1a\xdf\x27\x73\x5b\x31\x8d\x75\xc4\x2f\xeb\xa7\xdb\x68\x94\xc9\x12\x55\x49\x9c\x78\x0e\x13\xd7\x6e\xab\x8b\xed\x2d\x40\xae\x1d\x0d\x1e\xe5\x86\x12\xc9\x65\x67\xec\x01\xed\xf9\x56\x0a\xfc\xe3\xf2\xec\xf8\xa1\x34\xa5\x56\x6f\xb8\x6e\xca\xfc\xa1\xf5\xaf\x9a\x0b\x94\xa6\x05\xc3\x8d\x89\x0c\x75\x62\xd7\xe3\xb3\x5a\x77\x87\xa4\x0c\x8c\x0b\x73\x48\xe5\x28\xdb\x2c\x7d\xcf\x66\x0c\x37\xab\xed\x37\xf7\x37\xe2\x99\xfc\xbb\x83\xbe\x7f\x29\x32\x65\x7a\x02\xeb\xb1\xcb\x76\x2b\xd7\x22\x7d\x42\x62\x2c\xdd\x6d\xe0\xcf\xa6\xaa\x27\xb4\x86\xd2\xf7\x43\x81\x37\x5a\x8f\xb7\x9e\x9e\xe2\x6b\x5c\xe9\x97\x7e\x40\x7c\xfc\x4c\x27\xab\xae\x6a\x5b\x15\xb0\xa4\xe7\x86\x44\x61\x20\xfb\xf6\xf2\x6a\x2c\xc7\x2b\xfd\x00\x78\x60\x33\x7d\x0f\x69\xfe\x72\xc3\xd0\xf9\x01\x80\xc5\xaa\xbc\x16\x83\xdd\x79\xf8\x1d\xfc\x40\x4b\x7c\x32\xfb\x33\x76\x9f\x9b\xde\x6f\xe8\x29\x84\x39\x1b\xd0\xe2\x34\x0c\x1e\x7d\x59\x3f\xa4\x1e\x4a\x0d\x9c\xcb\x01\x32\x70\x72\xb9\x90\x92\x41\x75\x7c\xb9\xfb\x3a\xaa\x8d\x49\x3f\x54\x09\x96\x30\xce\x1c\xc5\xbf\x79\xe7\x13\xde\x2c\xcc\x49\x3f\xf2\x43\x04\x08\xee\x96\xb3\x47\x0b\xf2\xf6\xdc\xb5\xa2\x44\x62\x95\x79\x37\x7f\x08\x86\x26\xcd\x8f\xb9\xd1\xbd\x1b\x4b\x69\x58\xe9\xdd\xa8\xdf\x89\xdc\x70\xe0\x1e\xeb\xad\xb0\xa5\xdb\xd8\xed\x1e\xf1\xa2\x2b\x15\xfe\x32\xba\xa5\x58\xeb\x44\x0c\x6b\x85\xf7\xcb\xa5\xdf\xe7\x5a\xdd\x4d\xb0\x88\x61\xa7\x96\x82\xd7\x45\xd3\x3d\x7f\x42\x0d\x67\xb4\x6d\xd3\x43\x9d\xdd\xf1\xdd\xf0\x58\x30\xcb\x53\x65\x7e\x3f\xd7\xc5\x57\x28\xd3\xfa\x7a\x37\x9e\x7c\x1f\x41\x78\x62\x03\x68\x43\xfe\xd3\x1a\x95\x0e\x2a\x28\x7d\x49\x84\x6f\x69\x4c\xee\x20\x83\x03\xaf\xe1\x86\xbc\xe3\x75\x0f\xf1\xa7\x6e\x8c\x2f\x95\xc2\x64\xf0\xe3\xf7\x87\xdd\x6a\xbb\xfa\xb2\xdf\x7d\x7b\x72\xbf\x08\xbe\x21\x6d\x6a\xbf\x74\x86\x10\xaf\xca\x70\x5f\x77\x4b\x1a\xb8\x0f\xd6\xe8\x2e\xeb\xe3\xf2\xfd\xda\x35\xf6\xb5\xe7\x61\xf1\x65\xb9\x5e\x7d\x12\xcf\xfa\x3a\xf0\xf0\xcd\xde\x2d\x7f\x38\x63\xe2\xeb\x50\xb3\x5e\x95\xda\xd4\xc2\xaf\xe8\x59\xa5\xaf\x63\x1e\x38\x8d\x8b\xf2\x52\xd5\x93\x3e\x30\xe9\x6b\xc6\x90\xe7\xa1\xf5\xac\xe6\x4d\xae\x32\x18\xcd\x37\xcd\xc3\xd0\x56\x52\xee\xd3\xd2\xf1\x4f\x49\xea\x25\xae\x2a\x71\x2a\x5e\x61\x01\x65\x9d\x6a\xcb\xbd\xe5\xf0\xbd\xc6\xef\xcc\xf4\x38\x6a\xa4\xc4\x37\xfc\x72\x93\x7e\x8f\x89\xe1\xc7\x73\xfe\x4d\x26\x4e\x1c\x25\x61\x84\x55\x2c\x93\x9f\x34\x42\x68\x03\x15\x29\x49\x89\x0c\xdd\x4b\x47\xe6\xd5\x9b\xec\x47\x92\xfa\x34\xa0\x91\x13\x29\x79\x07\x75\x0b\x00\x25\x29\x15\x11\x92\xff\x99\xda\xbb\x73\x7f\x3e\xdb\x22\x68\xc0\x89\x01\xd2\xdf\x8e\x2b\x68\xc0\x21\xb4\xc5\x97\xd5\xe2\x79\x24\xca\xf8\x3f\xf5\x29\x49\x1a\x12\x6d\x3a\xc6\x9e\xee\xfe\x57\x9d\x1a\x49\x23\x20\x01\xc1\x15\x8c\x35\x69\xd4\xa6\xec\x70\x97\x92\xc6\x3e\x45\xa8\xf4\x5b\x9a\xab\xe2\x0d\x29\x23\xb7\x35\x9c\x7d\x77\x9c\x79\xc4\xb4\x27\x61\x1e\x78\x5d\x16\x85\x7e\xd6\x56\xc8\xf1\x98\x9e\x1d\xc0\x68\xe2\x64\xf8\x7d\xca\xec\xd7\xf1\x9c\x60\x5e\x8c\xdc\x4c\x1d\x85\xf3\x76\xb7\x59\xad\xd7\x4b\xd7\xed\x22\x29\x63\x0a\xb3\xfc\x0f\xc5\xc1\x16\x6e\x3f\x61\x46\x91\x34\xf1\x01\xf9\x22\x7e\xa4\xe5\x21\xcd\x1f\x87\x53\x9a\x26\x2c\x8c\x07\x39\x90\x99\x52\x93\xc9\x21\xec\xdc\x7e\x49\xb3\xcc\x25\x23\xc6\x97\x17\x09\xe7\x86\xe8\x28\x57\x45\xbb\xea\xca\xff\xae\xf7\x5c\x52\x21\x55\x14\xf6\x10\x52\x2b\x69\x73\xdf\x40\xf6\x19\x2a\x53\x52\x19\x1b\xf9\x8e\xba\xd7\x6b\xb1\xe7\xba\xc7\x92\x49\xcc\xcd\x16\x56\x1c\x53\x91\xd6\x96\xfe\xc0\x1e\x55\xc2\x68\xd4\xf4\xc0\x99\x47\xa4\x19\xbd\x4b\xb5\x4e\x65\x93\xd5\x17\x37\x12\x3c\x43\x75\x98\xca\x02\x77\xf8\xaa\x3b\xa0\x08\x37\xbd\x1c\x69\x5d\x7d\x37\xcc\xd0\x73\xc7\x29\x60\xc7\x68\x02\xe8\x9a\x15\x26\xe9\x3e\xfe\xca\x3a\xb6\xf8\x32\x4c\x44\x8e\xe8\x77\x7f\x9d\xcc\x14\x77\x06\xc4\x18\xe2\x19\xd2\x7e\x50\x46\x4b\xd4\x35\x3e\x9a\x41\x81\xe7\x27\x96\x4c\x3b\x57\xb3\x1f\x9b\xdb\x2f\x30\xf0\x22\x8a\xf5\x9e\x9f\xb3\x87\x87\xe5\x6e\xbf\x63\xcb\xdf\xf6\xed\xce\xdb\x5d\x25\x01\x64\x84\xfa\x51\xd4\xf0\x9c\x4f\xdd\x05\x37\x08\x78\xe8\x08\xff\x36\x37\xa4\xae\x64\x40\xb8\xd1\xd5\xef\x92\x1d\xc6\x47\x98\x5f\x56\x6a\x3a\x12\x42\x24\x3c\xfe\xed\x8b\x03\x5f\xb8\x5b\xf1\x23\x22\xb0\xe2\xf6\xfc\xf0\xfd\x71\xb9\x5f\xfe\xb6\xdb\xcc\xf6\x46\xd9\x65\xf1\xfc\x74\xb7\xea\x65\x5d\x64\x40\x55\x12\xf6\x71\x61\xc9\x3f\xa3\x47\x76\xa7\x80\x30\x26\x28\xe7\xe7\xea\x58\xe0\xe2\xaf\x6a\x7e\x72\x9e\x61\x10\x68\x0f\x3f\xe2\x2c\xfb\xb3\x49\x33\x5e\xce\x53\x99\xba\x63\x61\x48\x10\xdb\x72\x5f\x14\xf5\x9c\x67\xd9\x20\x20\x0f\x62\x5f\x1a\x5e\x45\x23\x72\x64\xa5\x81\xba\xa3\xd4\xa8\xdb\xb8\xcd\xff\x69\x40\xf4\x3b\xfe\xec\x41\xcc\x3c\xf4\xdc\x6c\x77\x0e\xf6\xae\x18\xbe\x2c\x77\x31\x46\x24\xe2\xc0\x3a\xa7\xde\xd9\xf9\xb1\x5b\x1d\xb0\x04\x5c\xb6\xfa\x09\xde\x96\xef\x06\xdf\x7f\xab\x45\x47\x06\x89\x2f\xf0\x9a\x25\x86\x66\xed\xee\x75\x9f\x72\x37\xb3\x83\x24\x11\xa1\xdd\x48\xef\x01\xfa\x60\xf8\xbe\x98\xf0\xe1\xc8\x80\x0b\xf0\xa2\xae\xf3\x1b\xe7\xf9\x35\x9d\x86\x0c\x38\xf8\x98\xe6\x35\xd5\xaa\x1b\x95\x71\x19\x88\x28\xa4\xca\x4e\x6d\x6c\xca\xda\x15\x8f\xd5\x61\x0b\x28\xb8\x3d\x19\x9a\x18\xbe\xa2\xf6\xfe\x3a\x46\x5b\xf3\x59\xc7\x8f\x29\xb8\x46\x44\xec\xf6\xe5\xf2\xc6\xb3\x97\x0f\x40\x59\x32\x10\x92\xf3\xb0\x83\xed\xce\x9b\xcb\x08\xcf\x23\x03\x19\x9a\xb4\x1e\x3a\xf9\x08\xe9\xef\xb3\xa7\x81\xe4\x0c\x73\xe5\x2b\xc4\xfa\x7c\x4a\x33\x21\x03\x05\xcc\xd0\x69\xf0\xd7\xd7\x7e\x15\x80\xa7\x5d\x9d\xc9\x35\xda\x6e\x21\xbb\x45\xd5\x2c\x03\xa0\x31\x26\x66\x90\x31\x6f\x95\xa7\xf5\xba\x2c\xfe\x00\x59\x0f\x75\x37\x64\x00\x8a\x0f\xa5\x89\x67\xee\xef\xba\x5d\xb6\xb6\xe3\x37\xcd\x61\x80\x81\x6a\x8f\x99\x66\x8a\xbd\x4e\x73\x35\x60\x9e\x1e\xdf\x40\xe8\x05\x21\x66\xe5\x4c\x12\x6b\x0c\x8a\x93\xa1\x07\x31\x36\x9c\xd6\x07\x68\x77\x7c\x34\xab\xee\x18\xa1\x02\xa1\x2a\xf3\xb7\x51\x76\x2b\xf4\x23\xca\xbc\x1e\xce\x80\x49\x83\x05\x32\x43\xdd\xfe\x5e\xa1\xcf\x63\x6d\xb6\xf4\x7c\x92\x46\x0e\x69\x14\x05\x8e\x1d\x7b\x0b\x75\x73\x7e\x4c\xdf\x7b\xda\xb4\xff\xce\xdf\x08\x83\x00\x62\xbf\xf3\xf8\xd6\x60\x52\xc0\x37\x8d\x6d\x18\x88\x84\xd8\xb4\x88\x13\x96\x5b\x5c\x7f\xb6\x30\x50\x06\xfa\x84\x84\x56\xa7\xb4\x77\xaa\x5c\xf0\x1e\x86\xa1\x71\x34\x8a\xb3\xc5\x5f\x3b\xa1\xd1\x31\xc9\x8d\x0c\x23\xc2\x91\x37\xdd\x04\xc6\x41\xf7\xe7\x48\x62\x58\x2d\x79\xa9\xaa\x3d\x4e\xd5\xc9\x3d\x44\x2c\x52\x26\x2d\xb8\xdc\x2c\x98\x4f\xdc\x99\x71\xc2\xb0\x51\xe1\x9f\xdf\x9f\x9d\x02\x8a\x0c\x63\x15\xa2\xfb\x69\xfc\x9e\xfb\x34\x3f\x40\x69\x42\xc6\x71\xce\x6d\xf4\x0b\x4c\xc4\xce\x72\xfc\x2c\xd3\x1a\xca\x95\x1a\x6f\x8c\x21\x13\x80\xd1\x27\xd6\x1a\x1e\x2f\xc3\xcd\x20\x64\x32\x74\xca\x4a\x2b\xcb\x19\xe4\x4f\x1e\x21\x21\x01\x46\xa6\x59\xaa\xc1\x8a\x78\xd8\xfc\x80\x1d\x20\x28\xc5\x9d\xfb\x4d\x74\x7f\x11\xd2\x45\x62\x4e\xaf\xe5\xa6\x51\x0c\x65\x48\xb1\x93\x37\x2b\xe4\x0b\xfa\x81\xc6\xfb\x35\x49\xe0\xf1\x6d\xa8\x10\xb0\x55\xf1\x1f\xb3\xc5\xb7\xf5\xf3\x6e\xff\x73\xf5\xf4\xe4\x40\x91\x32\x54\xb1\x47\xcd\x46\x95\x9e\x50\xac\x6a\xb0\x77\x7e\x2a\x2e\xd5\x9e\xea\xe3\x4e\xb9\x3e\x16\x39\x0c\xd7\x88\x82\x90\x75\xa5\xf0\x8d\x4b\x91\x87\xe0\xc5\xac\x97\x1e\x98\xcf\x9f\xef\x6e\x29\xdb\xcb\x10\x88\x87\x7c\x46\xfb\x91\xcd\x1c\x00\x28\x64\x08\x89\x87\xc8\x50\xc7\x2b\xdf\x0b\x87\xba\x1f\xd3\x5c\xa3\x4a\x7b\xa7\x77\xbe\x28\x4e\x48\x66\x33\xac\x0a\x98\xb1\x91\x47\x03\x1e\x5b\x73\xbe\xd2\x4f\x45\x7d\x5f\x94\x1d\xbf\x9b\x8c\x3c\x46\x71\x03\x3a\xa5\x79\x3d\x78\xd7\xe8\x67\x9c\xc0\x31\x28\x8e\x5f\x4e\xe4\xd3\x88\x59\xec\xea\xcf\x34\xcf\x07\x2e\xd5\xf8\xb7\xfd\xc8\xc7\x22\xcd\xea\x2b\xaf\xc1\x7b\x9f\xef\x16\x43\x1c\x8f\x8c\xa8\x2f\x1d\x5d\xfd\x16\xca\xd7\xd4\xea\x8a\x8c\xf7\xd3\x88\x26\x14\x6b\x2a\x3d\x9f\x7c\xbb\xf1\x4d\x4a\x5f\x11\x4d\x14\xa2\xab\xbe\x67\x75\x3a\xf8\x5e\x11\x55\x1c\xc2\x1e\x52\x59\x94\xc6\x15\x95\x13\x7b\x15\x05\x81\x8f\x6e\xdf\x7a\xb3\x5a\xa0\x9a\xda\x97\xe5\xfe\xf9\x69\x69\x7c\x20\x77\xb1\x28\x08\xfd\x2e\x38\xc3\x0f\xf7\x01\x41\x98\x1b\x1f\x32\xe4\x68\xdd\xf1\xac\x43\xe4\xcb\x28\xd2\xe0\x19\xd9\xd8\xb4\xfd\x78\x0f\x3c\x57\x27\x5e\xbe\x4c\x1e\x28\xa6\x21\xe2\xdf\x4c\xc5\x7b\xd3\x9b\xf6\x28\x0e\x01\x4b\xcd\x85\x43\x90\x76\x07\xb4\x67\x03\x64\x74\xcc\x2e\x23\xc2\xfa\xf6\xb0\xaf\x45\x97\x4a\x5c\xd6\xc7\xe0\xd6\xae\x1e\x31\xa2\x11\xfa\x69\xb4\x1a\x11\x47\x6c\x3d\xd3\xee\x93\xb0\x84\x48\xbb\x4f\xef\x0d\x2f\x85\xcd\x64\x4f\x2f\x25\x54\x64\xba\x2d\x2f\x6b\x6c\xac\x9d\x1c\x4f\x42\x8e\x61\xd1\x3e\xad\x56\xf9\xf6\x3a\x0f\x1e\x25\x71\xe4\x6a\xc7\xab\xc5\xf3\xe3\x0d\xc5\xef\x76\x4c\xec\x5a\x36\x37\x4e\xc9\xc0\x04\x08\xe3\x71\x3c\x34\x52\xdb\x9b\xf4\x5c\xa7\x6a\xb8\xa8\x23\x9e\xc4\x60\x20\x1e\x19\xd4\xf0\x78\x59\x74\x3e\x58\x24\x69\x40\x13\xdb\x90\xb4\x81\x73\x53\xf3\xeb\xba\x6b\x04\x24\x49\xf8\x88\xb1\xe1\x91\xe7\x0d\xcf\xb2\xcb\xe7\x39\xa6\x08\x88\x42\x6c\x1a\x9c\xd2\xfa\x1f\x85\x30\x39\xfc\x69\x8e\x3e\xd2\x2c\x76\x9d\xfe\xeb\x0a\x1a\x55\x18\x18\xe8\xc8\x3d\x8d\x3d\xcf\x30\x8c\xbb\x28\x00\x93\xaf\xd3\x56\x52\x19\x7b\xb1\x81\xe6\xef\x4f\xf5\x71\x57\xfc\x28\x1a\x79\x9c\x12\x8d\xca\xd8\x63\x86\xe6\xe9\x5c\x42\x55\xa7\x5d\xa6\x23\xf6\x12\x8a\x99\x1d\x0b\xfd\x2d\x8a\x6c\xbc\xe2\x63\x4f\x30\xec\x61\xfe\xf6\xfb\x02\x5b\x2a\x1e\x1e\x77\xee\x5c\x12\x86\x46\x9e\xc4\x98\x35\xbb\x99\x1b\x5c\xd9\xf8\x4b\xc5\x44\x99\x56\x24\x74\x63\x07\x75\x0d\xe6\x8e\x83\x46\x11\x8c\x2e\x74\x5f\x94\x3c\x3d\x7c\x29\x79\xb7\xc6\x62\xa2\x15\x9a\x48\x1b\x7a\x3d\xcc\xf7\x8e\xdb\xc2\x8d\xf0\xa3\x40\x19\xea\xa7\x2c\xc3\x3a\xca\x6d\xbf\x22\xa6\x5e\xc0\xc6\x54\x63\x0b\x5e\xd5\x19\x3c\x14\x45\xf7\x6b\xd4\xf7\xb1\xf1\xe6\xae\xb8\x83\xd7\xc9\xbb\xa4\x31\xe0\xce\xa0\x9b\x5c\xad\x07\xa7\xb0\x58\xc6\x5d\x98\x79\xad\xe7\x22\x63\xaa\x0d\x0e\xed\x6e\xf6\xe4\xd2\xf3\x71\xe0\x19\x21\xcf\x3d\xf2\x88\x14\x35\x20\x0a\x00\x21\xb5\x9f\x77\x4e\xc9\x38\xf4\x18\x96\x8d\x76\x25\x54\xca\x45\x48\x71\x18\x6a\x43\xe7\x5a\x37\x5a\x77\x7f\x8c\x7c\x34\x50\x2e\xc0\xc1\xa9\x74\xb3\x5f\xbc\x1d\x0b\x48\x75\xb6\xde\x2c\x57\x8b\xe7\xfd\x7a\xb9\x59\x3d\x77\xef\x38\xe2\x11\x62\x2b\x45\x63\x1a\xc5\x7a\x69\x0d\x19\xc7\x21\x10\x6d\xd7\xdc\x81\xd7\xe0\xe4\x13\x6f\x7f\x05\x16\x73\x8c\xe4\x7e\xff\xfe\xf4\xdb\xea\xe9\xbf\xcc\x7c\xc4\x89\x65\xa1\xac\xa0\xfe\xed\xaf\xec\x45\xfe\xf1\x67\xf1\x76\x2c\xfe\x3c\xbe\x15\xe9\xb1\x4a\x79\xf1\x67\xf3\x06\xe9\x5f\xef\x45\xda\x14\x93\xc7\x4a\xfc\x04\xeb\xda\x60\xc9\x0c\xa6\x87\xb9\x46\xfc\x5e\x5a\x55\x0d\xb8\x10\x6f\xf3\x09\x0e\xe7\x73\x47\x37\xe6\x34\xc1\x64\x94\x2a\x0c\xf7\x86\x65\x7f\xf7\xa7\x97\xbb\xae\x35\xc5\x5c\xc4\x98\xcf\xcd\x9b\x93\x55\x1a\x12\xbd\xa5\x8e\x05\x95\x41\x88\x8c\x2d\xef\x43\x65\x9c\xf6\x80\x42\xe2\xdf\x76\x05\x6d\x77\x8b\x67\xd7\xef\x24\x63\x11\x1b\x68\xc5\x36\xcd\x0f\x19\x6c\x8b\xa6\x94\xd0\x61\x45\xdc\x18\x30\x8d\xb8\xb6\xe3\x0e\x79\x6c\x26\x6e\x5c\x2c\xfd\x00\x7d\xb3\xe7\x1c\x03\x32\x5c\x63\xf3\xa2\x78\xf9\xe1\x11\xea\x9c\xc2\x58\xc6\x86\xa0\xa1\x84\xbc\x8d\xcd\xaf\xdb\xc1\x64\xac\xa4\xc2\x92\xd4\xb1\xa8\x6a\x9b\x87\x73\x67\x43\x04\x7d\xb2\x74\x53\xbc\xdc\x84\xf1\xc4\xc0\x38\xae\x4e\xae\x46\xd1\xd4\xa7\x96\x39\x06\xce\xa5\x91\xd6\x7d\x81\xdd\x88\x49\xf4\x83\xf1\xc2\xd0\x34\xf5\x0d\xf4\x93\x29\x03\x2a\xc2\xf0\x74\x76\x48\x3f\x06\x6d\xff\x4f\xe9\x58\x46\x98\x87\x90\x07\xb7\x34\xb7\x86\x0d\xe4\xca\xe8\x33\xc2\x43\xd7\x4a\x61\xf9\xff\x6c\x5b\xe9\xe8\x45\x31\x9f\x70\x19\x0c\x48\x48\xaa\x95\xde\x98\xb2\x23\x54\xd5\xee\xc8\xf3\x0e\x3e\x2a\x99\xaf\x7d\x6e\x93\xca\xdb\x37\x94\x07\x9f\x5c\x8c\x7a\x02\x1c\x2a\xb2\xe6\x35\xb4\xbe\x69\x9f\x41\x63\x34\x31\x31\x28\xea\x8b\xb9\xc4\x15\xbf\x2c\x8a\xd3\xa9\xc9\xfb\x99\xc6\x28\x37\x0d\xad\x66\x6b\x9e\x34\x5f\xb9\x31\xc2\xc3\x34\xe4\x0f\x9e\x41\xb1\x83\x6a\x34\xd3\x59\x40\x24\x89\xdc\x24\x59\x14\x65\x09\xd2\xb8\x53\x1d\x7c\x96\xb9\x91\x8a\xa0\x80\xef\x13\x74\x15\x15\x16\x00\x20\xb9\x1a\xea\x0c\x8d\xed\xce\xf8\x26\x42\x02\xc2\xb2\xcd\xef\x21\xaf\x3b\x6f\x9d\x85\xdc\xc7\xb5\x92\xe6\xba\x78\x84\xaa\xea\x2b\x07\x2c\x22\x21\x37\x9c\x15\xfb\x5b\x58\x2c\x16\x85\x51\x10\x8e\x6a\x63\xd8\x5d\x7d\x9f\x35\xd5\x71\x90\x45\x1d\x7f\xec\x48\xf8\x01\x19\xca\x24\x9c\x8a\x59\x17\xfb\x33\x26\x62\x64\x54\x32\xb0\xad\x27\x78\xb3\x42\x2c\x4e\xb6\xeb\xff\x96\xc4\x4c\x32\x26\x85\x88\x46\xe9\x5e\xcb\xcb\xe0\x7e\x3a\xa1\x0a\x61\x99\x0f\x69\xfe\xd2\x7a\x5f\xa3\xaf\x94\x70\x0f\x9c\x0a\x5a\xef\x66\x8d\x5f\x47\xc2\x89\xc7\xfb\x1a\xec\x00\xcb\x2a\x59\xa2\x94\xb0\xd8\x8a\x45\xd1\xc6\x7a\xb7\x38\xa7\x25\x4b\x80\x61\xc3\xe5\x3c\x55\xc8\xa2\x3e\x26\xa9\x1b\x3f\x10\x0f\x79\xd8\x3e\x90\x68\x4d\xaa\x5a\xa4\x75\xfa\x57\x7f\xbf\x1c\xc0\xb4\xfb\x94\xc0\x5f\x56\xea\x91\xa7\x79\x0d\x48\xe4\xe8\x7f\x30\x41\x84\x30\x28\x74\x17\xd7\x15\xbc\x54\x5b\xc3\x74\x7f\xab\x40\xc1\x84\x54\x66\x75\x8b\xf1\x7c\x06\xa2\x9c\xbf\xbb\x38\xa6\xe7\x21\x8c\x93\x69\x16\xa2\xe7\xb4\x95\xb2\xfb\x53\x62\x04\xff\xde\x52\x55\x1f\x4b\xfe\x36\x2f\x6c\x5e\x6f\xf2\x72\x75\xa2\x6d\x7b\xfa\xa9\x78\x85\x87\xf4\xcf\x26\x55\x53\xd6\x16\x99\x78\xbe\x41\x82\x73\xd4\x68\x5b\xfe\x49\x2c\xaa\xf6\xd7\xe1\x3f\xee\x11\x12\x8f\x69\x04\x57\x9b\xec\xfb\xff\x0d\xa8\x23\x21\xdc\x34\xea\x1c\xa0\xfe\x02\x39\x0c\xb2\xcd\x81\xe7\x86\x28\x85\xdf\xc9\x82\x8e\xc7\xcc\x3e\x32\xf1\xbd\x50\x74\xe4\x81\x9f\x5b\xf1\xc4\x8f\x3c\xbc\xe1\xaf\xbc\x3a\xda\x7c\xde\xf8\x35\x25\xbe\xd0\x48\x74\xd4\xda\x48\x23\xfa\x05\x86\x8e\xbf\x23\x64\x94\x09\xe5\x21\x3a\x55\x46\x54\xda\x50\xa9\x19\xaa\x23\x37\x22\xf0\x89\x74\xba\xd1\x03\x9a\x0e\x99\x04\x10\x61\x89\x37\x2f\xea\xde\x57\x4a\x22\x4f\x3a\x84\xf9\xec\xc2\xf3\xfa\xae\x2c\xd2\x7a\x29\x8b\xbc\x38\xa5\x7f\x36\xb0\x5f\x14\xa7\x73\x0d\xfb\x68\xf2\xb1\x62\x42\x0c\xa4\x6a\x88\xab\x4b\xe2\x18\x02\xda\x03\xcc\x9f\x6d\x4d\xd4\xed\x9d\x6e\x14\x0b\x30\xb9\xd5\x0b\xfb\xce\xb2\x6c\xcc\xf5\x25\x13\x46\xb4\xb4\x40\xb3\x2d\xae\xb6\x51\x7c\xdf\x2e\x57\x7c\x9b\xa2\x19\xf3\x11\x4a\xa4\xfb\xb3\xb5\xf5\xfb\x26\x3f\xa4\xae\xc4\x39\x0e\xfd\x13\x1e\x88\xb8\x0b\xfd\xed\xce\x75\x3b\x15\x99\x08\x62\x90\x4e\x15\xd4\xa6\x77\x34\x6b\x43\xc0\xc3\xb4\x58\x92\x08\x1f\x7c\x32\xc4\x60\x4d\xbe\xaf\x60\x1a\x01\xe9\xb3\x87\xc5\xfe\xfe\xf9\xfb\xd3\x1d\x2a\xda\xef\x67\x77\x77\x9b\xe5\xd6\x25\x02\x12\x49\x03\xab\x99\x6c\x7b\x13\x8d\xd4\x54\x77\x58\x12\xdf\x91\xa9\xf3\xda\x75\xce\x8e\x6f\x44\x79\x31\x62\x10\xbb\x20\xe6\x6e\xf5\xf4\xec\x2e\xa0\x20\x40\xfd\xef\xd5\xd3\x6e\x72\x7f\xe0\x9b\x56\x88\xed\xfc\xcb\x62\x82\x2e\x4a\x40\x9a\xca\x83\xc5\xd7\xcd\xca\x92\x5f\xba\x63\x3a\x70\xe4\xaa\x77\x69\x85\x9f\x11\x2d\xc7\x73\xde\x8f\x48\x62\xdb\x8b\x7e\xc7\x6b\xbe\x2b\x1e\x06\xfc\xbe\x1f\xa1\x18\xec\xb9\x5a\x44\x18\x24\x7d\x81\xfa\x0b\x3f\x89\x0c\xca\xc5\xb1\x48\xaf\xf0\x31\x89\x06\xe3\x35\xa0\x01\x72\xfc\x91\x9f\x21\x8a\x12\x0d\xcc\xa9\xe9\xce\x67\x53\x08\xa8\x1b\xa3\x13\x44\xae\xb4\x11\xe7\xd7\xe5\xe6\x79\xe0\xcd\x72\x0f\x42\x70\x88\xcd\x22\x53\xd7\x52\x84\x92\x93\x50\x85\x48\x27\x92\xa9\x55\xfe\x9a\x9a\x66\x18\x77\xbe\x2f\x12\x03\x87\xb5\xfc\x45\xce\x03\xb9\xf9\x1e\x38\x8d\xa2\x44\x75\x64\xb3\x3d\x5f\x20\x94\x43\xca\xb5\x7e\xb8\xf4\x13\xe9\x78\x23\xab\x11\x83\x8e\xe4\x81\x4f\x1d\xa1\xa1\x6d\x7f\x1c\x3d\x35\x0f\x82\x10\x59\x5f\x5e\xa0\xfe\xb3\xe1\xee\x7e\xc3\x20\x44\x08\x78\x1f\xae\x4e\x1f\x37\xd4\x26\x23\xb8\xe5\x1a\xd0\xab\xf9\x0a\xd9\xb9\xdb\x48\x79\x14\x73\xf4\xa9\xf3\xa2\xb6\xfa\xde\xaa\x3b\x04\x11\xae\x31\x8e\x15\x8e\xa9\xdd\x1e\xdd\x7c\x1c\x84\x08\x9e\x99\x17\xe2\x91\x97\x19\x5c\x06\xe9\x16\x1e\x87\xd4\x36\x5f\xf2\x52\x1e\x9f\x0a\x35\xf1\xd8\x79\x1c\x6b\x6c\x7a\x7c\x49\xf3\x83\x2a\x4e\xd5\xfc\x62\x73\x1d\xe3\x27\x89\xa5\xa1\xb6\xc0\x44\xd8\x00\xf3\xc5\x39\x27\x0e\xf1\xf0\xd0\xb8\xb8\x73\x7c\x2e\xe7\xb1\x76\x6a\x7d\xf5\x31\xad\x9c\x36\x4a\x77\x09\x11\x22\x0e\x67\x10\x31\x60\x94\xd3\x1f\xd7\xe8\xba\xb5\xeb\x7e\x29\x0b\xbb\xc6\x13\x77\x58\xc5\x81\xf0\x3a\x79\xe7\xc1\xdd\x0f\x19\x8c\x25\x57\x82\x84\x36\x27\x5e\x67\xb0\x38\xf2\x3c\xef\x31\x9c\x1f\x46\x05\x1f\x20\x88\x6e\x17\xb4\x39\x44\xc4\xb3\xec\x5e\xb3\xb7\x09\xa5\x8b\xe4\x90\x18\x6d\x57\x93\x50\x38\x43\x59\x5f\x3a\x31\x40\x77\x97\xc0\x05\xba\xa1\xe3\x0e\xbd\xd0\x3d\xab\xa6\x81\x0c\x46\x8c\xba\xcb\x0e\x44\xca\x75\x12\x25\x06\xa1\x96\xc1\x05\x4a\xbf\x3a\x16\x6f\xc3\x17\x71\xfd\xbf\xe6\x44\xe1\xf9\xc0\x2c\xf1\x15\xbf\xac\x8f\xbc\x82\x65\xae\xe6\x57\xd3\xce\x8d\x0e\x14\x61\xc6\xfb\x1e\x63\x14\x04\x09\x63\x6c\xd2\xfb\xe1\xd4\x45\xdb\x3f\xf1\x04\xad\x50\x09\xf0\x37\x7c\x64\x52\x10\x48\x10\x05\x2b\x1b\x91\xca\x89\x6f\x21\x7c\xa2\xd1\x47\x5b\x9d\xda\x77\xe3\xaa\x65\x55\x77\x98\x1a\xca\xa5\x87\x42\xbe\x34\x93\xa2\xa8\xf0\x13\x0f\xad\xd6\x62\xb1\x1c\x18\x2c\xe1\x8b\x28\x11\x0e\x3d\x65\x38\x64\xc7\x8f\x4a\x89\x17\xdb\x39\xf3\x50\xbc\x5d\xcb\x2b\x48\x41\xa9\x01\x5e\xcc\x79\x95\x9a\x7e\xa2\xc7\x62\xc0\x3c\x33\x19\x1c\x52\xc3\x56\x04\x69\x76\x97\xbe\x7e\xf0\x7e\x03\xdf\xa4\xd7\xd7\x77\x6e\x0f\x14\x01\x23\x60\x37\x39\x03\x83\xbf\x55\x26\x15\x81\xa0\x28\x9d\x89\x5e\x4e\xbb\x46\xb3\x42\xbe\x8c\xb7\x79\x11\x05\x26\xe3\xa0\x40\xd4\x4e\xbe\x4b\x8a\x88\x87\x5e\xe0\x3c\xfa\xac\x28\x6f\x25\x07\x44\x04\x0a\xf5\xa3\xa1\x92\xfc\x3c\x31\x23\x22\xd2\xa6\xbe\x60\x3d\xee\xef\x86\x8a\xcc\x5d\x3f\x0e\x38\xfa\x85\xa7\xc3\xa9\x36\xac\x79\x13\x8f\x6f\xf2\x0a\xe2\x30\x71\xc4\x6f\xf3\x32\x55\x07\xc3\x69\xa4\xb9\x84\xca\x92\xc6\x77\x57\x0e\xad\x46\x12\x12\x68\xe6\x4d\xb5\x3c\x7c\x50\xb5\x14\x31\x33\xcc\xc1\xa7\x34\xdf\x36\x48\x5d\xd2\x5d\x44\x41\x60\x7d\xbe\xaf\xd8\x9a\x5c\x5e\x53\x82\x48\xc1\xb8\x1f\x99\xed\x31\xd3\x77\x96\x9c\xc0\x5d\x21\xa1\x44\xdb\x89\xe2\x5a\xe8\xdb\x68\x30\xcd\xb2\x51\xc1\x49\x24\x09\x43\x67\x23\xcd\xdb\x90\x71\x42\xf1\x21\x45\x22\x09\xb6\xaf\xad\xaa\xaa\xf9\x18\x2d\x24\x38\x0d\xd1\x94\x1d\xb2\x42\x38\x75\xe3\xc9\xd6\x23\x78\xe4\xe1\xd6\x23\xd2\xfa\xc4\xab\x17\xd3\x43\xf3\xd1\xf5\x62\xc3\xe3\xe3\xe8\xa4\xdb\x5b\x6b\xca\xcb\xf4\x8a\x2a\x09\xc9\x50\x36\xd1\x65\x5f\xee\xcb\xe2\x34\x76\x69\x05\xd7\x12\x3f\xf8\xfa\xc8\x4b\x7e\x2a\xca\xee\x80\x20\x51\x68\x14\x33\x9f\xf3\x79\x51\x96\xc5\x24\xc9\x29\x44\x12\x60\x1d\x43\x43\x2d\x8f\xa6\x95\xf2\xbe\x28\x1f\xa1\x8d\x9c\xf3\x7a\x7e\xc1\x4a\xf2\x64\xf2\x49\x5f\x45\x36\xa0\xdd\x9f\x10\xa6\xb6\x4f\x5b\xc3\x3a\x19\xc5\x62\x44\x75\xd9\x57\x8e\x2e\xdb\xae\xb0\xce\xf4\xb8\xd7\x53\x0a\xa9\xa5\x8c\x87\xe9\x80\x2f\xc5\x2d\xaa\x37\x89\xc4\x41\xda\xf6\x52\x7c\xb0\xa0\x55\xac\xb8\x11\xb8\xa8\x9a\x13\xac\x16\xce\xf5\x14\x4a\x6b\x8c\x40\x9a\x5c\x64\x3d\x3c\x4f\x40\x08\x5a\x4d\xf0\x31\x4e\xe6\x52\x0a\x4d\x04\xea\x58\xc0\x20\x15\x3a\xeb\x26\xa2\x8e\x29\x47\x05\x30\xab\xf9\x5a\xf6\x94\xd7\xe3\x9b\xd2\x09\x20\x44\x72\x48\x1f\x65\x0e\x49\x2f\x00\x84\xd4\xe7\xf0\xb6\x41\xd5\xa4\xf1\xa9\xd2\x93\x21\xe6\x89\xe0\x1d\xf7\xb0\x7d\x5a\xb8\x33\x89\x34\xa4\x65\x28\x64\x5b\x1f\x4b\x30\x0c\xd4\xcb\x3f\xc7\x56\x48\xfa\x81\x89\x9d\x97\xef\xdf\xf2\xe2\xfd\x76\x98\x21\x7d\xc6\xf1\x36\xe6\xea\xdc\xa1\xdb\x1d\xf5\xec\x40\x4b\x40\x4a\x5f\x48\x7c\x8d\xb3\x63\x0a\x99\x5a\x34\xe5\xf8\x71\x28\xf5\xfc\xa0\xd3\x91\xa8\x52\x05\x79\x0d\x77\xf0\x08\x15\xff\x5b\x8c\xc4\x68\x79\x4a\x2a\x12\x6c\x45\x9c\x17\xc5\x0b\x96\x11\xed\xdf\x03\x3f\x51\xd2\xed\xca\xad\x77\x31\x64\x92\x93\x32\x88\x63\x4c\xa8\x9b\x57\x7d\xcf\xab\xe3\x34\x11\x42\x3a\xc1\x03\xe2\x5e\x72\xc0\x29\xd6\x33\x17\xbc\x1c\x3d\x4d\xa0\xa8\x32\x82\xa4\xf9\x2b\x94\xf5\x53\x73\xda\xf6\x74\x7b\xd7\x39\x6b\x19\x28\x8e\x65\xbd\x9f\x5f\x67\x4d\x7d\x2c\xca\xf4\x2f\x98\x7c\x8c\x30\x4e\x90\x77\xc0\x10\x67\xfe\xa3\x10\xb7\xba\x2d\x06\xff\xef\xaa\xab\xb2\x0f\x78\x65\xa8\x14\xba\x20\x7b\x93\xda\x30\xdf\x6d\x86\xae\xed\xc4\xa7\x96\x31\xe5\xa6\x82\xca\xd3\x0a\xee\xf8\x85\xba\xfb\x89\x03\x1f\x0b\x5b\x43\x12\x6a\x57\x8e\xbc\x99\xee\x91\xb1\x4a\xb0\xaf\x1d\xf1\x41\xf3\xb4\x54\xd5\xe4\x11\x63\x1d\x23\x4e\xbe\xab\xe2\x4f\x66\x34\xf3\xcd\x7e\xb3\xcc\x8b\xe6\x70\xc4\x60\xa9\x9a\x0e\x09\x8c\x68\x2c\xe4\xaf\x90\x15\x67\x03\x23\x9a\x3e\x53\xe2\x27\x58\xe2\x7f\x49\xb3\x6c\xfb\xe6\xda\xe2\xa5\x4c\x82\x08\x8b\x9e\xcf\x59\xfa\x3a\xfa\x9a\x89\x60\xe8\xd4\x28\xc3\x5f\x64\x4b\xf3\x93\xab\x72\x22\xa3\xc0\x09\x1a\xe5\x2e\x88\xbf\x56\x06\x91\x92\xc7\x1c\x73\x1d\xff\x6c\xa0\x81\x3b\x38\xf1\x5c\x41\xb5\xcc\x17\xbd\xc8\xac\x94\x1c\x64\x62\x19\x5b\x6d\xa0\xd4\x39\xa1\x2e\xcd\xd3\xee\xf5\xd8\x18\xbf\x05\x44\x3b\x59\x4f\xac\xb8\x7a\xff\x63\x43\x27\x85\x90\x91\x2d\x55\xa4\xa7\xe6\xb4\x2e\xde\xa0\xfc\x7e\xde\x62\xc6\x43\xfc\xe5\x6e\xa0\x75\x72\x31\x71\x56\x97\xc0\x4f\x69\x7d\x99\x78\x7a\x52\x0a\x1f\x53\x11\xd8\xfc\xb3\xe6\x0e\x7f\xc3\x06\x73\xd0\xac\xcb\x1b\xd3\x5d\x2a\x13\xf5\x1e\xa0\xde\x36\x27\xb3\x35\x3e\x6b\xbb\xdf\xeb\x26\xdb\xd6\x70\xee\x5e\x85\xf2\x04\xee\x68\x18\x13\x36\x79\x6d\xb3\x99\xee\x68\xac\x58\xd4\x41\x2f\xa0\xbc\x2e\x30\xf7\xce\x81\x54\x2a\x41\x3f\x77\xdd\x9c\x3e\x13\x1f\x96\x52\x13\x6e\xd5\xd5\xe0\xcc\x4b\xf8\xbe\x71\x3d\xd4\x48\xad\xd8\xbe\xf4\xc7\xd9\xd3\xd7\xd9\x6e\x37\x7b\x5a\x6f\x9e\x7f\xfb\x9d\x78\xbb\xaf\xb3\xc7\xed\x6e\xf6\xc3\xc1\x94\x94\x47\x8c\x23\x72\x80\xd3\xd7\x73\x8f\x99\xea\x0f\x47\xde\x70\x83\x18\xaf\x05\xe5\x05\x09\x72\x71\xba\xd4\x04\x58\x9c\xfd\xed\xcd\x4b\x79\x2c\x88\x86\xc2\xb4\x7b\xa8\x8f\x7b\x5d\x16\xa7\xbd\x9c\xd2\xa7\x4d\x4f\x14\x88\x4a\x5a\xc0\x2b\x97\xe3\x6c\xfe\x64\xa0\x0c\x09\xe9\x61\x23\x8f\x69\x5e\xcf\x72\xb5\xe6\xd7\x0d\x90\xe3\xf3\x88\x17\x19\x52\x67\x4c\x00\x6c\xa0\xdd\x2e\xd3\xfc\x30\x4f\x4d\xdf\xf3\x64\x70\xe2\x21\x31\x88\xb1\xc1\x53\xd5\x0e\xa9\x08\x27\x3e\x19\x94\x48\x3f\x6a\x28\x1a\x5b\x1e\xe5\x7b\x3e\xba\xdc\xa7\x34\x6f\x1d\xbf\xee\x25\xfb\xbe\x4f\xc8\x50\x99\xcb\x48\xa8\xf6\xca\xef\xd3\xeb\xd0\xd8\x8b\x1d\x47\x52\xcf\x22\x33\xc0\x5c\x2a\x2a\x45\x38\x84\x1e\xef\xeb\xeb\xf6\x2a\x15\x90\x18\x2b\xed\x86\xf8\xd4\xd6\x06\xa6\x2a\x10\x52\x05\x34\x42\x08\xf0\x97\xe5\xd3\x6e\x36\x50\x87\x96\x2a\xd0\x02\x5b\x47\x77\x29\x94\x7b\x47\xe1\x6b\x8f\x85\xd2\xb0\x68\x57\x50\xcf\xaa\x76\x55\x0c\x51\x68\x2a\xf6\x7c\xa7\xb7\x3f\x73\x30\x49\x84\x91\xdd\x9e\x1e\x71\xc8\x94\x53\x77\x7a\x7e\x7e\x30\xaa\xf6\xfe\x28\x60\x56\x71\x6c\x38\x33\xcd\x47\x5b\xe5\x46\x57\x67\x5d\xa2\xb0\x29\xa8\xa5\x4a\x47\x78\xe8\xbf\xdb\xcc\x3f\x8a\xe1\x3f\x6b\xa5\x50\x2c\x00\x84\x18\xce\xd6\x6b\x9c\xc4\x11\x71\x6d\x12\xed\x8a\xc7\x40\xcd\xd2\xba\x18\x63\x3a\xec\x33\xf9\xe0\x92\x9c\x80\x83\xf4\x74\xcd\x57\xc5\x38\xe4\x98\x9e\x11\x72\xcc\xbe\xb4\xde\xe8\xba\xa8\x60\x3e\x20\x12\xfe\xe8\x47\xa4\xc2\x94\x16\x02\x42\x27\xb3\x84\x83\x46\x30\xfc\xbe\xea\xb1\x94\x8a\xeb\x00\xcb\xf0\xb3\xcd\x62\xf1\x49\xb7\x92\x12\x81\x06\x9b\xbb\x5c\x62\xeb\xb0\x84\x2b\x37\xea\xef\x19\x9a\xa4\x12\xdc\xf4\x77\xd7\x43\xd8\x53\x1b\xbd\x77\xf9\x31\x25\xa4\x51\xa8\xe4\x4a\xfd\x40\xa5\x9c\xc9\xa2\x56\x3e\xc4\xb6\x0c\xf6\x15\xca\x62\xd4\x95\xd7\x8f\x02\xe9\x3b\x39\x69\x9b\xbc\x27\xcc\xfd\x02\x40\x82\xbc\xe9\x9b\xa6\x3a\x0e\xd2\x66\x4a\x13\x16\xdb\x88\xe2\xb9\x6b\x81\x53\x3a\x50\xa8\x1f\xf8\x49\x43\x8e\x1b\xc9\x38\x22\x2e\x7e\xee\xe6\x4f\xc3\x0d\x5f\x69\x4e\x9d\x4a\x41\x6b\x97\xef\x8b\x72\x5d\xa6\xaf\x69\x06\x53\x64\x0e\x78\x01\x0c\x48\x1f\x1c\xd7\xfc\xed\xce\x05\xf0\x89\xc9\xe2\x69\x43\xdd\x60\x56\xe6\xd8\xf0\x83\x2f\x63\x04\xf7\xcd\x10\x2c\xc9\x8d\xbe\x4b\xcd\xdb\x37\x7b\xdb\x2a\x01\x25\x0c\x6b\xd9\x6f\x43\x3c\x0a\x1b\x32\xe3\x4c\xff\x5f\x77\xa2\xc6\x4c\xf0\xb6\x6e\xd4\xb5\x8e\x87\x04\x9a\x44\xf8\x7a\x72\x78\xaf\x6d\x40\x3f\xb9\x59\xaa\x03\xac\x67\x7c\x5f\xef\xdf\xd2\x7c\xde\x31\xce\x4b\x08\x89\x8c\x9d\x64\xcf\x13\xbc\x19\xbc\x5f\x35\x33\xf0\x6d\x1b\x26\x74\x83\x23\xe6\x63\x45\x6e\x0e\xd8\xaf\x36\xa4\xf3\xb8\x39\xbb\x81\x79\x80\x04\x46\x26\x82\x79\x2b\x56\xf9\x6b\x6b\x3d\x67\x58\x83\xbb\xe7\x59\xe7\x1e\x00\x0b\x3c\x14\x9d\x73\x2f\xe7\xa9\xa8\x67\x37\x28\xb4\x25\x30\x2d\x31\x4d\xfc\x50\x1c\xee\x8b\xf2\xc5\x36\x2e\xde\x8c\x30\x20\x89\x8c\x76\xd1\x99\x5f\x46\xd6\x15\x12\x30\x78\xf1\xbd\x68\xca\x1c\xb9\x32\x0e\x1f\xf4\xa8\x01\x27\x3e\x32\xdc\x2c\x1e\x77\x3b\x97\x87\x03\x11\x4a\x74\x34\x53\x59\x60\x9a\x84\x8c\xa8\xd9\x24\x08\x9e\x78\x1d\xd6\xf6\x27\xc0\xcb\x7d\xc7\x09\x25\x41\xfa\x31\xb3\xa0\xb8\x9a\x1f\xa6\xcf\x27\x25\xb3\x8d\xd6\xb5\x85\x27\x4f\x06\x28\x0f\x30\xcd\x96\x9a\x5a\xc9\x20\x7b\x0c\x2a\x94\xa8\x69\x6e\x4b\xe4\x85\xea\x8f\x00\x31\x04\x2d\x86\x18\x57\x7d\x81\xda\x40\x28\xab\x95\xc3\x3c\x01\x90\x18\xab\xdc\x8f\xa0\xf2\xa6\xfb\xe6\xda\xe7\xe8\x1e\x71\xa5\x1e\xf8\x35\xe3\xac\x1b\xc5\x98\x25\x2e\x42\x58\x36\x8e\xb4\x9f\x64\x3c\x2e\x91\xda\x24\x2c\x9e\x9a\xd3\x3c\xe3\xf2\x65\x98\xd0\x01\xcd\x43\x7c\x6f\x6f\x63\x70\xee\xe8\xab\x6a\x12\x1b\xf6\xf6\xad\xe4\xa7\x81\x95\xd1\x3e\xa1\x58\xf8\x9b\xe5\xe9\x09\xc6\x07\x14\xee\xcf\xcb\xdd\xe2\x2b\x55\x3f\xba\x3f\xcb\xd8\x37\x64\x9e\xa7\xaf\xbc\x54\x0b\x7e\x76\x09\x62\xc7\x00\xa4\x29\xf1\x2d\x8a\x33\xcb\x7e\x16\xd9\xcb\x72\x02\xaa\x1a\xaf\x70\x4d\xc3\x08\xa7\xc5\xb9\x2c\x4e\x45\xbb\x2c\x6c\x7f\xf8\x07\x99\x27\x1d\x10\x3f\xe8\x21\x0d\xad\xe3\x9e\xe6\x4d\xd1\x54\x77\xa6\xdf\xcd\x95\xc0\x74\xc0\xba\xa2\xe3\xca\x0a\x35\xdd\xe8\x06\xd7\x01\x63\xdc\x35\xc0\x18\x3f\x69\xee\x5e\xf0\xc0\xa9\xd7\x41\x42\x3c\xdb\x77\x6e\x36\xcc\x5d\x31\x93\x7f\x36\x29\xcf\x91\xef\xaa\x1a\x49\x8e\x49\x1d\x48\x81\xb4\xf2\xfb\x91\x36\xcb\xdf\x71\xf0\x4a\x1d\x06\xa6\x1d\x47\xa4\x93\x4a\xa5\x0e\x43\x89\x70\xde\x8a\x9f\xce\x19\xcc\x8b\x22\xdb\x20\x99\x65\xf7\x93\xa1\x8c\x88\x85\x69\xff\x80\x32\xd5\xe9\xa0\xd6\xd6\xfb\x70\x3a\xf2\x04\x8b\x5c\x45\x54\x7f\xda\x12\xa8\xa3\xc8\xc3\x4b\xbe\x39\xba\x1f\x27\x7e\x9e\xd7\xd5\x7d\xc6\x0f\x93\x5b\x8c\xa2\x04\x65\xfe\x64\x06\xbc\x1c\xcc\xe6\x7f\xff\xe7\xd7\xc9\xdb\x8c\x34\x41\xb4\xd0\x62\xfe\xc3\x65\xa2\x74\xcc\x42\x9c\x59\xdf\x67\xeb\x5b\xdf\x89\x49\x39\xcc\x48\x99\x4f\xe5\x16\x9c\x4e\x68\x60\xa0\xda\x46\xed\xc0\x85\x05\xe8\xc7\x4c\xb5\x58\xa4\x4e\x82\x24\x18\x3d\xd7\xa0\x43\xb3\xbb\xc7\x44\x05\xf2\xca\x3b\x4c\x46\xde\xa1\x4e\x80\x22\xe3\xcb\x6e\xa0\x8e\xf6\xc1\x6a\xd7\xdc\x33\x64\xe9\x03\x62\xeb\x79\xd3\xcd\x56\x1e\x9b\xf6\x9e\xb4\x9a\xb6\x00\x45\xc1\x64\x8e\x70\x45\x7c\x36\x82\x09\x0d\xa4\xca\xf1\x89\x6f\x31\x05\xda\x93\x25\x37\xce\xf5\x53\xf1\x3a\x94\x87\x96\x5a\x85\x0a\xcb\x3a\xb8\xd7\x58\x94\xd0\x47\x4b\x56\xf1\xa8\xd7\x9b\xcc\x8a\xb2\xfa\x2d\xf8\xc5\xe6\x90\x82\x3e\x1e\xf6\xbd\x49\x6f\xb5\x56\xca\x43\xa7\x6f\xbe\x78\xea\x7e\x56\x83\xb1\x3f\xbf\xad\x5c\xa9\xa1\xfd\x8b\xb2\xd6\x13\xad\xdd\x90\x68\xca\x0d\x89\x24\xce\x62\x0c\x1f\xf7\xf5\x40\x23\x51\x6a\x1d\x52\x64\x98\xcc\x3b\xbd\x0b\x3c\xa0\x3c\xcf\x03\x2c\x79\xff\xf8\xbe\xde\xaf\x97\x1b\x84\x2c\xaf\x37\xcb\x3d\x02\x37\x36\x33\xd7\x84\xa3\x3c\x4f\x6b\xcc\x96\xa6\x95\x45\x70\x61\xf8\x32\x80\x55\x28\x8f\x40\x8c\x00\xc0\x25\x2f\xb3\x8b\x5d\xfc\x06\xdd\x3c\x4e\x55\x2a\x8f\x32\x69\x3c\xb6\xe5\x76\x47\xdc\x2f\x04\x96\x37\x06\xcf\x2b\x1a\x17\x26\x0d\x1a\xcd\x95\x17\x5a\x75\x5d\xdc\x7e\x50\xfb\x6e\x78\x03\x61\x60\xf2\xf4\x2e\xd7\x7f\x33\x83\xa9\xbc\x88\xc4\x58\x15\xd8\xdf\x62\x3e\x77\x63\x28\x60\x33\xe4\xfd\xea\x7e\xeb\x56\x78\x79\xb3\x71\x52\x79\x51\x42\x5d\xab\xd1\x2c\x3f\xd8\xea\xa5\x65\x77\x50\x5e\xc4\x89\x0a\x3b\x54\x51\xeb\xee\x74\x4c\xe7\xb7\x00\x5a\xca\x8b\x49\x80\x79\xc9\xfa\x00\x5b\xa8\x1f\xba\x0d\x5f\x79\x71\x22\xb0\xc4\x67\xc0\x44\x1d\xf7\xeb\xf8\x6e\x62\x11\x19\x4a\x43\xb3\xee\xbf\xe7\xe9\x15\xbd\xf4\xa7\x06\x57\x79\xb1\xd6\xe8\xd4\x64\xf9\x5e\xa7\xef\xa0\xe8\x3e\xcb\xcb\xd6\x3b\xbf\xb5\x7c\x94\xc7\xa8\x8f\xce\xba\x00\x59\x9c\xc0\xea\x15\xb8\x63\xcc\xe3\x43\x1d\xd1\xef\x79\x47\x7a\x3e\xf6\x57\x94\x97\x50\xe3\xea\xa4\x15\xce\x2c\x9b\x16\xad\xaf\xd2\x0d\x6e\x78\x1c\xc4\xa4\xef\xd4\x1b\xd3\x50\x75\x63\x12\x04\x9e\xdf\xc1\xc9\x24\x21\x86\x56\x61\x72\x39\xcd\xb0\x49\xc6\x26\xef\x41\x70\xf9\x72\x45\x1d\xa1\x3c\xe1\x4b\x24\x31\x3b\x1b\xec\x3e\xb2\x65\x7e\x70\x45\xe9\x49\x6a\xf6\x5a\xc4\x6c\xc1\xa2\xe4\xe2\x0b\xe4\x16\x74\xd9\x59\x5e\xe5\x49\x02\x98\x71\x7d\x43\xcf\xb2\x13\x4e\x54\x9e\xd4\xd2\x97\x8e\x6c\xc2\x2e\xdc\x6d\x23\x8c\xa8\x9c\x1d\xa3\x3c\xee\x4a\x72\x3b\xd3\xad\x72\x38\x64\xf0\x85\x9f\xe0\x2e\x7d\xad\x2c\xe5\x5e\x3f\x3a\xd1\x98\x17\xe1\x7f\xf1\x3a\x3d\x57\x03\x63\xa7\x3c\xa5\x13\x61\x7d\x83\xde\xb6\x93\x6e\x75\x82\x67\x96\x6c\xf7\x43\xb3\xe7\x61\x3a\x5d\x79\x10\x32\xfc\x20\xad\xa3\x7f\x1e\xa0\x94\xdc\x61\xad\x95\x81\x39\xbf\x16\x2f\xf0\xb1\x3c\xee\x64\x6d\x69\x12\xa3\x32\x50\xd3\x4f\x1c\x6c\x47\xef\x1e\x49\xb3\x18\x5b\x45\xad\x78\x36\x42\xac\x6d\x35\x0a\x1d\x42\x6f\xf8\xaa\xb5\x88\x30\x87\x5d\xbb\xcd\x06\x46\x0a\xae\x8a\x78\x51\x82\xb0\x89\xbd\x9d\x56\x8f\x29\x66\xca\xc7\xc9\x34\x1b\x41\xbb\x7b\x24\x1e\xf3\x30\x71\xf0\x3d\x4f\xb3\x62\x88\x54\x54\xc4\xd3\x8a\xb3\x4e\x71\x7d\xaf\x01\xf6\x0a\x8c\x4c\x5e\x57\xe7\x55\x84\xb0\x38\xf6\x7a\xd6\xe3\xf1\x9c\x23\x24\x31\xe4\xfe\xcb\x13\x94\x07\xc8\xe5\xe5\x7b\xbe\xe6\x8d\x8b\x78\xf0\xb8\xe3\x3a\xb3\x93\x64\xf7\xfe\xc8\xcf\xc3\x5d\x59\x11\xc2\x39\x76\x4c\xb9\x85\x78\x0f\x30\x15\x97\x52\x84\x68\x2f\xb1\x51\xf0\xee\xdd\x64\x8b\xbe\xfd\x3c\x8e\xed\x0b\xf1\x13\xae\x8d\x6f\x0a\xaf\xf3\xbe\x3e\xa6\x88\x0f\x31\x32\xf1\xfc\x05\xd2\xfd\x89\x92\x30\xea\xe8\x1c\x0d\x85\xe2\xf3\xdb\x74\x37\x20\x34\x20\xcc\x26\x5e\xb8\xc9\xd6\x54\x97\xaa\x86\xd3\x6d\x7b\x43\x68\xa2\xb5\x51\xf8\xfa\xa3\x78\x19\x74\xba\x29\x12\x78\x86\xd2\x2a\xcd\x2d\xab\xb0\xbf\x46\xbc\x46\x77\x3c\xd0\xcc\x28\xeb\x97\xf0\x0a\x79\x0d\x6a\x7e\x79\xe2\x86\x72\x37\xad\x2f\x57\x1b\xeb\xe4\x87\x83\x90\x19\x76\xc2\x82\xab\x6b\xdb\x40\x02\x4d\x68\xd0\xe1\x77\x8b\x5f\x6e\x48\x1c\x2a\x12\xd2\x00\x2b\x31\x2e\x3c\xb5\xbc\x92\xe3\x2b\x45\xb1\xef\xe0\x24\x33\xad\xd3\x2c\x45\xde\xfb\xba\xfb\x4e\x11\x97\x3c\xea\x8c\x95\x6b\xbe\xb8\x49\xba\xa2\x48\xec\xc9\x50\xb9\xdb\xd2\xe3\x59\x11\x47\x61\x18\xf5\x29\x2f\x23\xc4\xfd\x21\xab\x97\x22\x2c\x09\x62\x3a\x74\xb3\x66\x39\x0a\x8b\x7e\x42\xce\xa2\x08\x83\x00\x13\xdf\x16\x4b\x35\xcb\xd5\xbc\xb9\x74\xcf\xa5\x3e\xc4\xfa\x5c\x35\x57\x29\xc2\x13\x8d\x3b\x77\x09\x82\xd7\x60\x3e\xee\xde\xbd\x15\x2e\x4d\x4a\xb0\x63\xa9\xe9\x31\x30\x8a\x08\x4f\xab\x11\x24\x5c\x35\xb2\x9e\x0a\xf3\xdc\xca\x88\x29\x22\x82\xc8\xc8\xe1\x59\x2f\xbb\x6f\xe1\x51\x44\xb0\x24\x08\x7b\x24\x29\xa8\x0d\x28\x80\xdb\xc9\x55\x45\x84\x30\x50\x0d\xd3\xd0\x85\x76\x7c\x96\x2b\x33\x05\x66\x59\x36\x99\x05\x02\x12\x74\xa7\x78\x53\x17\x67\x7e\xe9\x04\x15\x14\x91\xd4\xa8\x1c\xa5\xd5\x23\x7f\xc7\x92\x4e\x27\xc4\xff\xa5\xe0\xd9\x48\xfe\x5d\x11\x19\xa8\xc0\x08\x8a\x5d\x66\x39\xcf\x2e\x55\x7a\x1d\x79\x8d\x5f\xb3\x22\x01\x78\x1d\x87\x12\x94\x6e\x86\x3d\xa4\x2f\x3d\x5a\xa8\x7b\x3f\x4a\x49\xf4\x0c\x75\xfa\x0a\xbf\x03\x2f\xbf\x94\xbc\x7f\x41\xe0\xa9\x80\x59\x00\xec\x24\x33\xf7\x37\x4e\x89\xbb\x00\x0d\x2d\x7a\xa6\xe6\x59\xdf\x9f\xdb\x5d\x3f\x0a\x90\x34\x0f\x75\x8c\xf6\x3f\x97\xcb\x6f\x74\xd8\xb0\xaa\x08\x88\x00\x8b\x49\x8f\xb3\xdd\xbe\x17\x3b\xb2\xb2\xab\x03\xb9\xd5\x76\xa4\x46\x15\xdb\x1c\xde\x1d\x60\x75\xc8\x03\xad\x08\x80\x48\x4c\x16\x5f\xc1\x09\x5b\xe3\xe7\x4d\x79\x3b\x63\xa5\x88\xf6\x19\x62\xce\x54\xb1\x6e\xaa\xe3\x47\x83\x14\x73\xe8\x47\xe4\x79\x32\xd0\x8b\xd9\xa1\x04\xa4\xda\xda\x0d\x64\xc5\x26\x9f\x48\x6b\x40\x4c\xd7\x5e\x22\x09\xd4\xb8\x6e\xa2\x7c\x2f\x08\x1c\xe6\x13\xcd\xc2\x4c\xa9\x72\x96\xab\x45\xf9\xd6\x71\x46\x7c\xc4\x95\xfa\xeb\xc4\x3f\xf1\xbd\x20\x42\x9f\xc7\xaa\x74\xa6\xa7\x1b\x8d\x12\x6e\x68\xe2\x05\xcc\x95\x44\x27\x98\x46\xe5\x7b\x82\x92\xc0\x51\x31\xda\x0e\x86\x21\x57\x84\xf2\x89\x47\xa3\xc4\xf1\x15\x3f\xf2\x77\xf3\xbd\x8f\x25\x54\xc7\x8e\x1f\xbe\x1d\x65\x1a\x67\x10\x73\x5d\x94\x29\x54\x43\xd6\x46\xe5\x13\xea\x33\x83\xfd\xe0\x25\xa8\xe5\xfb\x19\xf2\x6e\xb7\xf4\x89\x32\xb2\x29\x07\xc4\xe9\x42\x9f\xa0\x50\xbe\x4f\x43\xa4\x77\xde\x67\xc0\xcf\xed\x4c\xae\xe6\xa0\xa7\x42\x22\xca\xf7\x65\x84\xec\xa8\x02\x0f\xee\x31\x25\x79\x82\xfa\x58\xa8\xbd\xc3\x0f\xb5\x57\x9d\x5f\xa8\xe7\x79\x9e\xbb\x38\x95\x46\x16\xc9\x8a\x86\x9b\xf6\x64\x77\x30\xf0\x24\x6e\x69\x3f\x8b\xf2\xa5\x3a\x3a\x15\x1e\xe5\x07\xa1\xe1\x96\x35\x1c\x19\x06\x43\x59\x8d\x4c\xb8\x1f\xb0\x00\x11\x5e\x73\xe0\xaf\x50\x0e\x76\x43\x3f\x60\x60\xaa\xeb\x4d\x99\xd3\x4f\xcb\x12\xca\x0f\x64\x80\x3b\xff\xfe\xcc\x2f\xed\xf6\xf6\xac\x75\x05\xf5\xe4\xc1\x03\x08\x50\x5a\xb3\x3e\x82\x6d\x7a\xb7\x07\xc2\x30\x42\x1f\x6c\x59\x1f\x1f\x8b\xbc\x58\x17\xd9\xc4\x13\xf7\x23\xdf\x13\x26\x32\xe3\xd9\xb2\xaa\x31\x1f\xd1\x9c\x8b\x61\x03\x8c\xf2\xa3\x88\x29\x87\x08\xb1\xc1\xf6\x95\x7c\xcf\xe4\xbe\x63\x2a\x7c\xaf\x93\xda\x36\x7c\x97\xee\x72\x71\x18\x60\x41\x7b\x00\xa5\xd9\x15\x3b\xfe\xde\x1d\x8f\x0d\xfe\x15\x41\x6c\x27\xa3\xa7\x39\xcc\xee\xb6\x23\x38\x02\x4b\x9a\xdc\xf1\x4a\xae\xad\x1e\x64\x39\x79\x3e\x16\x7b\x58\xe1\x7f\x58\xcf\x56\xa3\x67\x4a\xfc\x30\xb4\x18\xb6\xc5\x76\xb1\xdc\x2c\x62\x9f\x4c\xce\x4d\x24\x77\xbb\xbd\x13\xdc\xcd\x78\x35\x52\x2e\x56\x3e\x27\x86\x47\x17\x5b\x7c\x67\x4a\x7d\x90\x52\x51\x3e\x67\x12\x29\x6b\x9b\x7c\x98\xc9\x29\xa7\x1c\x13\x0a\x35\x41\x30\xf1\xf0\xfd\x5f\xff\x1a\xdd\x32\x87\xc8\xa7\x7d\xe1\xf7\x1f\xa8\x6f\xd8\xbd\x13\xae\x35\x86\xb3\x9d\x23\x59\x16\xa7\x0f\x5b\x3e\xaf\x3c\x09\x7b\x11\x61\x19\xa6\xd2\xbc\x82\xb2\xde\x15\xe7\x54\xda\x2e\x9a\x70\x1a\x07\xd8\xb6\x9a\xd0\x9e\x29\xa5\xa1\x90\xb3\xbd\xcc\xee\xae\xa4\x32\x2c\xb5\xb2\xc8\x32\x90\xf5\xfe\xc4\xd3\x7c\xdf\xef\x98\xa8\x00\x08\x58\x88\xa9\x9b\x12\xee\xe0\xb5\xe7\x5d\x53\x3e\x04\x31\x2e\xa1\x57\xd3\x5e\xf1\x61\x8d\x79\xf4\x41\x40\x12\x66\xab\xae\xad\x2f\x7d\xb3\xff\xd8\x0e\xd5\xc4\xf4\xae\x18\x03\x6a\xa9\xe5\x51\x09\xd7\x46\x28\xe3\x7f\x06\xd7\x18\xff\xd7\x84\x6c\x78\x7c\xe2\xe0\xe7\x24\x95\xa6\x12\xf8\x47\xa3\xc6\x92\x85\xd3\x81\x82\x39\xd6\x3e\xcc\x06\xb7\x7b\xce\xed\xc9\xa2\xb5\x81\xe9\xaf\x16\x77\x23\x8b\x4d\xbd\x90\x05\xd2\x61\x34\x4b\xb5\x5f\xf0\xf3\xd8\x6a\x50\x3f\xf6\xb1\x96\xa0\x41\x1e\x7f\x14\x35\x6c\xa0\x6a\xb2\xfa\xbe\x28\x17\x3c\x57\xa8\x6d\x33\xbf\x98\x1c\xcf\xcd\x09\x4d\x03\x4f\xc4\xb6\x85\xc6\xb8\x99\xba\x28\x99\xef\x7e\x3f\x8c\x42\x24\x18\x73\xd3\xf1\x79\xb2\x32\x69\xa8\x24\xa2\xd4\x9f\xe0\x0d\xa5\x8c\xa7\xde\xe6\x38\xb0\xb3\x27\x45\x32\xc4\xcd\x5b\x97\x00\xb3\x3c\x3d\xf1\xac\x1a\x10\xae\x29\xca\xa4\x42\x73\xf6\xfc\x96\x83\xb2\xa0\x5a\x2e\xd2\x36\x88\x58\x97\xc5\xfb\xc4\xfa\x51\x26\x01\xb3\x20\x55\x5d\x9c\xd7\x25\xac\x64\xe1\x2e\x94\x78\xca\xf1\x88\xac\xaa\x9f\x80\xda\x7d\xe7\xd6\x29\xee\xf7\x5f\x9a\x24\xa1\xb4\x94\x4c\x5f\xa1\x2c\xd6\xc5\x47\x01\x0a\xe5\x32\x72\x82\x17\x48\x91\x3b\xea\xa9\x1f\xdf\x12\x97\xa6\xd7\x2d\xad\x36\x46\x22\x42\xdd\x17\xe5\x1d\x68\xc8\xd5\x94\x67\x49\x51\x0e\x06\x77\x54\xd5\x81\x7c\xb1\xca\xc2\xe3\x11\xd2\x33\x8a\x68\x6b\x07\xe0\x1f\xff\x9a\xa4\xc2\xc5\x20\x88\xef\xfc\xca\xab\xa3\xc1\xb5\xad\xda\x38\xcf\xca\x52\xb8\xc1\x51\x64\xa8\xf0\xaa\x79\x09\xb8\x56\x06\x93\xea\x73\x6f\x91\x4a\x49\x30\x87\x68\x97\x9a\x61\xc6\xbf\x39\xa5\xa9\x22\x0a\x77\xb3\xa6\x82\x72\x7b\x2e\xf2\xaa\x30\x35\xca\x75\x79\x6d\x5b\xa7\x06\x8c\xaa\x38\x20\xae\x1e\x39\x13\xc5\x2b\x8c\x3c\x10\xaa\x12\x81\x49\xdd\xfb\xe5\xa0\xaf\x5c\x51\x05\x1d\x7e\x7a\x5d\x94\xb5\x2e\xb2\xb4\x58\x0d\x10\xb1\x93\x1f\x01\x2f\xc2\x45\x87\x24\x26\x77\x1d\xd5\x99\xa2\x40\xb8\x60\x5d\xc6\xa8\xa3\xfc\xe8\x0e\x4b\xc2\x63\x47\xdb\x5a\x96\x29\x3f\xc0\x1d\xd4\x3c\x75\xf2\x61\x8a\x6a\x1f\x42\xab\xea\xf5\x02\xcb\xfa\x38\x26\xd5\x1b\xbb\x9a\x54\x73\x30\x28\xf4\x76\xdd\xa3\x76\x55\x51\x56\x28\x46\x6f\x7a\xbe\x3e\xdf\xa2\xa9\x86\x00\xa7\xef\xec\xcb\xec\xc7\x72\xf7\x75\xb9\xb9\x81\x62\x57\x81\xe7\xfb\x68\xb4\x0c\x9f\x77\xcd\xeb\xb4\xaa\x53\xb9\x2b\x3b\x13\x1e\x78\x11\x27\x36\x01\xd5\x1a\xef\x0a\x31\x09\xed\xac\xbd\xfd\xf6\x02\x8f\x09\x74\xd3\x0e\xdc\xba\x71\xfb\xee\x4a\x49\x28\x1d\xa5\xf9\x49\xa4\xad\xa3\x0d\xa7\xf3\xf2\xbd\x5d\x7a\x9d\x5a\x9a\xb3\x05\x01\x21\x09\xaa\xe5\x61\x09\x36\x87\xb7\x72\x90\x7e\x0b\x08\x37\x20\xcd\x03\xd4\xcf\x52\x36\xe7\xeb\x9e\x5d\x15\x10\x15\x75\xb5\x6b\xdb\x97\x66\x4b\x4c\x3f\xd3\xfa\xf8\x04\x6f\x9b\x2f\xbf\x0d\x37\xe0\xc0\x27\xc0\x63\x97\x35\xe9\x04\x43\xba\xa3\xcc\x4f\xec\x24\xfa\x82\xfd\x5a\xba\x70\x4c\x4b\xb7\x7e\xdd\x6f\xa3\x66\x5b\xcb\x33\x22\xe5\xb7\x8a\xa1\x2a\xa0\x3e\xc5\x2e\x6f\x55\x72\xd7\x97\x7c\xfb\xbd\x52\x3f\xe6\x46\x13\xbd\x90\x2f\xf3\xe6\xb2\x80\xb2\x76\xe4\x06\xff\xdd\x2a\x0d\x28\x95\x36\x55\xc8\x4b\xa8\x9e\xf5\x76\xed\xc2\xb5\x20\xf0\x09\xaa\x5f\xcf\x9b\xcb\xa6\xfd\xc0\xed\x46\x81\x21\xcb\xd0\x3e\x07\x01\x97\x98\xe8\x3f\x77\x69\xc4\xe5\x7b\x5a\x59\xf0\x0d\x1b\xcf\xdf\x20\x50\x46\x7d\x65\x8a\x21\x6b\xe3\x21\x9e\x65\x1f\xc5\xc2\x63\xd4\xcc\xe8\xaf\xb7\xb1\x33\x2a\x08\xb4\xa1\xda\x94\xc5\xe9\xdc\xd4\xed\xc2\x5a\xb4\x0e\xdd\x95\x41\x0d\xc2\x36\x28\x6f\xdd\xd6\xd6\x94\xc6\xf1\xf4\xa8\x48\xd4\x48\x1f\xb4\x1a\x6d\x1a\x41\xa8\x3c\xf4\x57\x10\xa2\xbb\x05\x4b\xde\x82\x52\x27\x1f\x3b\xcc\xff\xf3\xbf\x58\xbb\xf2\xec\x4f\x46\x34\x44\x3f\x3b\xe3\x15\x22\x01\x07\x61\x53\x10\x51\x81\x49\x55\xae\x14\xea\x60\x7f\xfe\xed\x63\x62\x58\xac\x0d\x3a\x6b\x07\xef\xed\x17\xb6\xe2\xfb\xa3\xb7\xea\xc6\xb3\x28\x74\x2a\xb5\xe7\x0f\xa6\x24\x0b\x4c\x44\x76\xe6\x97\xa2\xa9\x3f\xc8\x43\x05\x09\x35\x9a\xe9\x8f\xab\xa7\xd5\xd3\x97\xfd\xf3\xf7\xdd\xfa\xbb\x0b\xfe\x83\x24\x26\xc2\xda\x4c\x7c\x9b\x23\x7b\x1e\x24\x09\xc5\x00\x47\xf3\x46\x5a\x22\xcd\x11\x30\x46\x05\x5c\xf8\x9c\x0e\x7d\x29\xd3\x2a\x37\x9e\x89\x5c\x70\xa7\xa5\xd0\xf1\x44\x76\x56\x49\x10\x9f\xf6\xb9\xe9\x81\xd4\xe2\xa4\xc9\x55\x05\x92\x44\xd8\x2c\x04\xa8\xef\x08\xd3\x3a\xd0\xaf\xa3\xa7\x96\xa1\xc9\x7f\x9c\x52\x27\x29\xe0\x0e\x58\xbd\xaa\x0a\xb2\x6c\x9f\x76\x16\x4d\xc6\x31\xb5\xe0\x3e\x95\xd6\xa3\x88\x2a\x90\xcc\x40\x61\x4d\xdf\x7d\xa6\xae\x19\x34\x54\x20\xa5\xc1\x0e\xac\x8b\xf3\x39\x1d\xfc\x9a\xf6\x11\x5f\x8b\x84\x7f\x24\x0a\xbb\xce\xa1\x89\xb5\x55\xcc\xe0\xe3\xbe\xf2\xf3\xd9\x39\x99\x01\x30\xe3\xe4\xd9\xa4\x7c\x57\xc3\xbc\x99\x1a\x09\x80\x7b\xda\x56\x04\x1e\x8b\x57\xb0\x55\xd8\xab\xfe\x3a\x15\x68\x6d\x6e\x15\xda\x7b\x19\x45\xd5\x21\x89\x23\xad\x5c\x4f\x20\x9c\xd2\xe6\x64\x78\x27\xc6\xe4\xba\x2a\x24\x2a\x71\x32\xb9\x8f\xfc\xfd\x16\x6d\xb1\x0a\x7d\x1d\x07\x62\xc8\x11\xfa\x85\x9f\x27\x97\xa1\xbe\x37\x20\xac\xf8\x7f\x26\x47\xf9\x75\xc2\xeb\xa1\x42\x1a\x7a\x86\x20\xa0\x69\x9f\xf5\x27\x4f\x7b\x2a\x5f\x15\xd2\x28\xc6\xfa\xc5\xb7\xd5\xdd\x70\xa7\x09\x29\x33\x88\xa5\xc7\xd9\x6f\xfb\xdd\x66\xf6\xb4\xbd\x77\xc4\x82\x2a\xa4\x9a\x38\x49\x70\x87\x81\x6b\x77\xa2\xf2\xd1\x66\x07\x9d\x37\x17\x06\x32\xc6\x7e\xe0\xbc\xa8\x3b\xfe\x3e\x15\x06\x3a\x20\xb6\x31\xcb\x38\x11\x13\xb7\x3d\x0c\xb5\xe0\xbd\x99\xe8\xdb\x88\x27\xef\x36\x0a\x14\x6e\x86\x4d\x9e\x15\xf2\xe5\xb3\x34\x74\x18\x25\x09\x3a\xb1\xa7\xcb\xfe\x34\xe4\x20\x51\x61\xec\x31\xe4\x48\x3a\x5d\x76\x4d\x96\x9e\xab\xb9\xb5\xa4\xc3\xb7\xda\x3d\x4f\x1c\x86\xe8\x36\xda\xe8\xf8\xe6\x4e\x39\x9e\x90\x61\x1c\x27\x38\x7d\xb7\x69\x0d\xe3\x69\xc6\x68\x02\x74\x90\xff\x7b\x4c\xb3\xf6\x55\xe6\xdd\xad\xb1\x50\xe3\x27\xc8\x0a\x3e\x12\xa5\x53\x21\xe3\x86\xd3\xa1\xc9\xd3\x7a\xb0\xf9\x5d\x19\xdc\x90\x71\x6e\xe6\x96\xad\x6c\xb6\x37\x20\x6b\x50\x6e\x6d\x7f\x88\x9e\x57\x21\x13\x04\xdd\xf6\x5e\x86\xfe\xe6\x8a\x0b\x13\x8f\x10\x18\x62\x8c\xcd\x14\xf0\xdd\xec\x4b\x12\x29\x0c\xd5\x6c\x65\xba\x38\x0c\x88\x7a\xb4\x04\x12\x01\x28\x5a\x9c\xa5\x96\xbc\xa6\xd3\x19\x50\xa1\xb4\x9c\x14\xad\x43\x5b\x1d\xbe\x38\x3d\xd0\xf6\x40\xa7\x61\x6b\x79\x72\x5b\x5f\xc1\x61\xe8\xc6\xef\x41\xc6\x02\x01\xb2\x36\x45\x90\x16\x46\x76\xbb\x7a\xd6\x93\xa9\xa7\xc0\xe4\x0a\xb6\xbb\x7f\xda\x32\xd2\x07\x8f\x0d\x56\x56\xd5\xb2\xde\x5b\x91\xe5\xcf\xd0\xf1\x2a\x04\xe1\xc5\x36\x1f\xde\x3a\x9d\xd9\xf5\x7d\x82\x16\x28\x23\x5c\x1b\x65\x70\xab\xbd\x3d\x0c\xba\x43\xed\x07\x7e\xdf\xb9\xd4\xd3\xe0\x20\x91\xc5\xf4\x7a\x3a\x34\x85\xdb\xd3\x4b\x3d\x20\x4a\x51\x11\x21\x09\x35\x98\xc6\xaa\x2a\x5e\xd1\xe9\x1e\xca\x86\xa8\x88\xc4\x1a\xb1\x16\xb6\xd6\x7d\x9f\x66\x93\x06\x7c\x15\x91\x44\xf1\x01\x00\x69\x57\x34\x65\xce\x5b\x4f\x74\xce\xf3\x97\xee\x3a\x10\x61\xa3\xd7\x91\x97\x4a\xf2\xf3\x2a\xef\x7a\xa3\x55\xe4\x87\x86\xa9\xe7\x5c\xbc\x41\x79\xe2\x97\xa2\x5c\x34\xf5\x55\x61\x32\xf2\xb5\x87\x25\x4e\xac\x37\x7e\x69\x3d\xd4\x41\xa2\x33\xa2\x11\xc5\xbe\x4b\x0b\x64\x34\x81\xe5\x40\xe8\x4e\x45\x94\x05\x58\xf8\x1b\x82\x62\x54\x14\xf0\x10\x6b\xfe\x39\xbc\xa1\xf0\x34\xba\xcf\x5d\x56\xa2\x1b\xa5\x02\xd3\xa2\x80\x45\x9b\xe5\xfb\x39\x2b\x0c\x05\xcb\xfc\x72\xdd\xeb\xa3\xa2\xd0\x27\x84\xf5\x0c\x3d\x32\x2b\xaa\x34\x3f\x0c\xdf\x6b\xc4\x13\xa9\x5c\xbd\xb6\x0d\xcb\x26\x57\x88\x20\x21\xb6\xc8\x96\x6d\x6b\xd9\x06\x09\xf3\xba\xb8\x72\xab\xfe\x4b\x1e\xe1\x2b\xda\x8a\xc1\xb6\x10\xc5\x22\xe8\x1a\x8c\x8f\x4d\xfe\x12\xed\x8a\x1e\x9c\x62\xc7\xb0\xd0\x47\x9e\x66\x53\xb8\x7f\x3e\x43\xc9\x2d\xe0\x59\x1e\xe1\x26\x1d\x85\x8a\x70\x69\xfe\x9f\xff\xdf\xff\x59\x2c\x37\xbb\x51\x3e\x34\x4a\xb4\x42\x5b\xbb\x94\xc5\x09\xfa\x79\xc0\x03\x85\x2e\x2d\xcf\xba\x0a\xfa\xf8\xa5\x70\x21\xf0\xa5\x19\x43\x0f\xca\xa8\x7e\x8c\x6d\x48\xc4\x05\x04\x36\x1a\x7b\x48\xf3\x97\xc9\x64\xe5\x2a\x46\x3f\xd5\x7a\xe7\xf8\x2b\xf8\x72\x87\x84\x18\xbf\x4e\xcf\x31\xe2\xbf\x5f\x9d\xa5\xbf\x96\x79\x18\x4b\xbe\xab\x48\xc4\x01\xf6\x33\xdf\xad\xb6\xeb\x87\xd9\xef\xfb\xc5\xc3\x6c\xbb\x5d\xfd\xf3\xfb\x72\xbf\xdc\xed\x7f\xac\xee\x96\xcf\xee\xa1\x85\xf6\xa8\xb3\x1f\x26\xbf\x64\x13\x3f\xa3\xd0\x38\x52\xbe\x8f\xc0\x8c\x75\x59\x1c\x4a\x7e\x3a\x41\xa9\xb8\x52\x97\x51\x1d\x2c\x52\x3e\x35\x8d\x32\x4e\x37\xec\xbe\x99\x08\xc1\xa8\x48\xc5\x0c\x89\x3c\x64\xfb\xa9\xe9\xaa\x32\x69\x64\x77\x90\x85\xd8\x7f\x36\xdc\xd7\xaa\x5f\x46\xa8\xb9\xc9\xd5\xa4\x46\x9c\xd1\xf6\x94\x66\x20\xd2\x5a\x34\x57\x72\x22\xcd\x94\x8f\x50\x45\xe0\x49\xdf\x26\xb3\xe6\x65\x71\x83\x07\x7d\xf2\x36\x21\x30\x4c\xaf\xa6\x20\xd7\x09\x81\xfc\x32\xa9\x21\x8e\xff\xd3\x9d\xcb\xb9\x45\x5e\xd5\x4d\x99\x3b\x80\xa1\xe1\xcc\x1a\xdd\x94\x8e\x19\x12\xd1\x3c\xa4\x39\x58\xae\x67\x77\x84\x47\x64\xa0\xdc\xed\x42\xc7\x5e\xd6\x69\xfc\x4e\x34\x97\x08\xe5\x91\x45\x91\xa9\xe2\x6d\xd2\x95\xac\x22\x2d\x3c\xdc\xaf\xd2\xca\x14\x7d\x7b\x27\x2c\xf6\x3c\x86\x19\x34\xc9\xcf\x74\x7c\xd5\xd8\x8b\x95\x47\x5d\x55\xcc\xf6\xb3\x18\x36\xf3\x9b\xfb\x52\x4c\x42\xcf\x62\xa3\xbb\x2a\xbb\x01\xeb\x8d\x87\xf9\x94\x62\xb9\xe5\x71\xf5\xb4\x5f\x3c\x3f\xed\x36\xab\xf9\x77\x64\xfa\xf9\xb9\x74\xb8\x43\x15\xfb\x8a\xe1\xee\x91\x35\xf2\xe5\x32\xb7\x9f\xd8\x9a\x8f\x98\x52\x8d\x00\xe0\xaa\xe3\x11\x1b\x16\xc7\x63\x1a\xfa\x08\x48\xb4\x7a\xd0\x86\x72\xab\x3b\x66\x90\xa4\xf3\xe6\xe2\x7a\xfb\x47\xaf\x2a\xa6\xa1\x96\x46\x47\x0b\x65\xe2\x8a\xb4\x73\x7d\x62\x2a\x01\xf3\x37\xaf\x56\x1b\x7d\x0d\x53\xf7\x31\x0e\x68\x8c\x19\x32\x4b\x7e\x3a\xbb\xfb\xb1\xda\x3e\x3b\xe7\x35\x0e\x04\x8d\x95\xe3\x6d\x18\x94\x58\x47\xd6\x24\x0e\x44\x82\xdb\x0a\x16\xf8\x04\xaf\x52\x34\xc5\xa6\xe5\xc0\x64\x94\x76\xc7\xd6\x06\xb9\xe1\x5a\x60\x70\x37\x4c\xba\x3e\xf6\x55\x86\x38\x94\x04\xcd\xfa\xfe\x8f\x22\xcd\x17\x77\xeb\x69\x77\x8e\x1d\x16\x91\x88\x5b\x95\x2d\xac\xbd\x2f\x5c\xbb\xaa\x8a\x23\xe0\x21\x73\xbb\xd8\x38\xfe\x8c\x63\x0f\xb0\x54\xc5\x45\x85\x0e\x83\xcd\xea\x96\xdd\x71\xca\x89\xd1\x98\xaa\xab\x61\x4a\xa5\xff\xe1\x58\x28\x8c\xd0\xb2\xa6\xe3\xfe\x55\x71\x0c\xc6\x98\x61\xc4\xc7\xd3\xbc\xab\x5a\x0c\xce\xd3\x0c\x93\x9a\xa2\xb9\x2c\xac\x6b\x25\xb2\xeb\x5e\xab\xd1\x39\x49\x10\xe1\x7e\x6c\x71\x41\x46\x77\xf9\x33\x16\x24\x15\xf3\x88\x22\x03\xb0\x71\x63\xef\xca\xf4\x3c\x21\x58\x98\xbc\x47\x2e\xb5\x91\x1c\xcf\x1a\x90\xc7\xf4\x3c\xb4\x96\xb1\x08\x23\xb4\x96\x46\x0e\xfd\x59\x5b\x5d\xae\xee\x70\x1c\xa1\x61\x7e\x82\xcb\x89\x77\xaf\x50\x30\xc6\x62\xc7\x9b\x8f\x77\xfa\xc8\x11\xe9\x36\x15\xe1\x77\xe3\x75\x8c\xcd\x3f\xeb\x87\x0e\x8d\x10\xab\x28\x42\xaa\xd2\x53\x93\xd5\xe9\x39\x4b\x3b\xb8\xb6\x8a\x15\x0f\x90\xd4\xa4\x57\x8d\x27\xbf\x7c\x90\x91\xba\x99\xc1\x8b\xc1\x37\xf0\x5b\x64\x64\x6d\xfd\xa3\x0f\x36\xb5\x18\x22\xe9\x1a\x06\x37\x50\x9d\x8b\xbc\xba\x9d\x22\x8f\x41\x50\x44\x74\x99\x20\xcc\x84\xde\x26\x8f\x3c\xfc\x34\xcc\xe3\x26\x9b\xe5\x48\x2c\x41\x2d\xeb\xe3\xae\xb0\xb5\xd4\xd1\x67\x61\x9e\x64\x84\xf5\x7a\x6e\x43\x04\x21\x23\xa1\x39\x86\xeb\xda\x21\xc7\x6f\x38\x03\x8c\x44\xcc\xca\x72\x9e\x8a\x57\x78\xe4\xf9\xe5\x23\xf1\x5d\xc5\x7c\x22\x9d\x22\xa6\x61\xa4\x6e\xa7\x3e\x02\xf5\xfb\x40\x87\xf9\x31\xa0\xf6\x0b\xd2\xcd\xa4\x45\x3b\xcd\x2d\x70\x79\x94\x32\xb5\xa3\x69\x6c\x1a\x0c\x7b\x44\xef\x35\x72\x6c\xf4\x22\x19\x8d\x25\x7a\x2f\xcb\xdd\xd7\xfd\x62\xb6\x76\x0f\x4c\x01\x88\xe8\x74\x76\x17\xbc\x44\xda\x31\x37\x23\x58\x90\x50\x7c\xaf\xed\x8c\x40\x7b\xff\x3b\x74\xb3\x91\x05\x1c\x2c\x54\x82\x77\x22\x02\xa3\xf9\xc0\xc2\x48\x20\xfd\xc1\x9f\x0d\x74\x33\x9f\x85\x8c\x23\xb6\x77\x7d\x84\x22\x4f\xdf\x6f\x2f\x1e\x16\x6a\x89\xd9\x2c\x9d\xe6\x0a\x9d\xdc\xf6\x21\x37\x53\x22\xa7\xee\x97\xa2\xc8\xb4\x29\x6c\xeb\x12\xb9\xac\xdd\x9f\xb9\x42\xa2\xb6\x45\x56\x54\xb0\xd2\xf3\xe6\xd0\x1d\xd1\xca\x93\x23\x42\x8a\x5d\xd9\x80\x31\xad\x6e\x4c\xcc\x69\x4c\x27\x85\xe6\xa1\xfe\xea\x80\xf2\xa0\xaf\xd2\x8c\x5f\x7b\x0c\xb1\xb6\xcc\x89\x3f\x21\x1d\x48\x89\x19\x4e\xd7\xf1\x6c\x67\xcc\x37\x45\xaa\x6d\x51\xf7\xc1\x05\x63\x21\x0b\xa0\xff\xd8\xfc\x94\x4e\xc1\x0d\x8c\x31\x30\xc0\x7b\xdb\xd7\x3b\xec\xfb\x56\x8c\x69\xca\x89\x23\x2b\x42\x21\xc0\xc9\x62\x9b\xdc\x74\xc2\xd5\x00\xa9\xf6\x08\xf2\xb8\xdc\x7d\xbd\xbd\x92\x59\x02\xb1\x32\x1e\x5d\xbb\xd6\xf2\xc3\x18\xb0\xc4\xb8\xe7\x9b\xfe\xd4\xa2\xaa\x9f\xf5\x73\x3e\x24\xe0\x50\x8c\x13\x86\xec\x45\x3f\x76\x9f\x74\xc6\x2b\xc6\x99\xc4\xc6\x90\x9e\x0c\xdf\xb4\xf9\xba\xd8\xd8\x0d\x13\x1a\xb3\x6e\x27\x2c\x45\xcd\xea\x1a\x4e\xe7\xfa\x03\x0b\xc4\x84\xc7\x68\xaf\xe8\xf1\x50\xf0\x1c\x89\xce\xd3\xfc\x80\xfd\xe2\xd5\x55\xc4\xed\x78\x38\xda\xaf\x1c\xff\xc7\x16\x6b\xff\x1d\x4c\x94\xcd\xdc\xd5\x49\x68\xe9\x4e\xf8\x69\xd1\xb8\xed\x93\x49\x6a\xb8\x00\x0e\xe9\x2b\x20\x49\xce\xe2\xc8\xcb\x8e\x67\x57\x31\x19\xf8\x58\xe8\xe1\x4a\x21\x34\xef\xb1\x50\x9f\xb7\x0c\x2b\x26\x63\x1f\xdf\x8d\xa1\xa9\xfa\xb6\x79\xbc\x9d\x7b\x62\x32\x49\x1c\x44\x77\x95\xeb\x62\x7e\xf9\x9e\xa7\x45\x3e\x51\x24\x51\x4c\xf2\x90\x12\x07\xf8\xb6\x93\x65\x62\x7b\xa4\x08\x50\x4d\x47\x77\x01\xab\x49\x0d\x4c\x8b\x80\x4c\xf9\xbe\x61\x77\x2b\x79\xee\x1a\x00\x6f\xe1\xee\x99\x4a\x4c\xf2\x66\xef\x92\x8f\x97\x73\x5d\x5d\xec\x02\xff\xf5\xff\x9b\x7f\x26\xbf\x28\x94\xdf\x9b\xef\xfd\xcb\x45\x4e\xfd\x37\xa6\x74\xa4\x7a\x16\xc1\x99\x32\x4a\x34\x1b\xe3\x85\x9b\xb7\x66\x11\x21\x0c\x7c\x82\xa1\xe3\xf7\xa7\x0e\xca\xc7\x00\x4c\x33\x93\xa9\xaf\x90\xc9\x3b\xd4\xbe\x40\x5e\x92\x87\x81\x29\xd6\x81\xf4\x63\xa7\x48\x61\x52\x92\x63\x0f\x2b\xf1\x7c\x2d\x8d\x66\x05\x48\x94\x1a\x31\x19\x61\x77\x98\x50\xe9\x54\x75\xf0\x35\x23\xc0\xe4\xe6\xac\x49\x7c\x4a\x30\xd5\xb5\x6f\x72\x54\x2d\x85\x57\xc8\x4c\x6a\x66\x32\x2e\xd4\x58\x13\xdd\x2c\xef\xbf\x3f\xdd\x0d\xbb\x71\x12\xea\x69\x2c\x93\xe5\xf0\xb6\x03\x7e\x7a\xce\x97\x16\x44\x7c\x53\xf5\x54\x25\xd4\xe7\x58\x21\x71\x2e\xf3\x36\x3d\xe4\xbc\x6e\x1c\xf3\xee\xd8\x93\x48\x82\x38\xc0\xd4\xd0\xe2\xe9\x6e\xfc\x5d\x92\x80\x1b\xdd\x4a\x34\xda\x08\xca\xdb\xbd\xb9\xba\x54\x12\x48\xa3\x8d\xb0\x7e\xde\xfe\xe8\xfe\xa6\x38\x3e\x83\x6e\xbf\x04\x3a\xb4\x16\xe3\xe4\x06\x84\x9a\xa0\x33\xcf\x95\xba\x86\x0c\x26\x11\xf5\xb1\xc5\xf5\x09\xde\x1e\x80\x4f\x25\x0a\x98\xdb\xe5\x93\x48\x00\xba\xc6\x27\xfe\xde\x5a\xa7\x21\x2e\x3d\x89\xb4\xe1\xf2\x37\xdf\xeb\x32\xf2\x5d\x92\x58\x48\xe5\x12\x0f\x12\x91\xc1\xb0\x5a\x3c\x8f\x2a\x25\x09\x63\x26\xfe\xfa\x6d\x72\x73\x2c\x31\xe0\x33\x79\xe4\xe5\x01\xee\x78\x9a\x5d\x0c\xab\xf6\xad\x9c\x48\xc2\xa4\x01\x1e\xb6\x1e\xd2\xc0\xa2\xdb\xa3\x3c\x04\xd2\xe9\x7a\xd9\x5c\x66\x47\x49\xa5\x12\x1e\x6b\x70\xb9\x8b\x0c\x3a\x45\x13\x95\x70\xe1\x2b\x36\x80\xea\x7e\xaf\x7a\x68\x3a\xe9\x2e\x0e\x01\x6a\xf5\x6d\x6b\x5e\x57\xd6\x16\xf4\x57\x00\x11\x6b\x57\xb9\xaa\xa1\x84\xaa\xee\xd5\x88\xaf\xe5\xb9\x27\x73\x99\x6b\x69\x6e\x0c\x6b\xd5\x06\xdb\x68\x9a\x8d\xed\x00\xe1\x03\xe6\xcb\x37\xf0\x0a\x79\x03\xdb\xd6\xe6\xe6\x87\x31\xb7\x0c\xc2\x25\xf0\x55\xde\x6d\x77\xfb\xcd\xfe\x69\x3f\xdf\xaf\x37\xcf\x5f\x36\x4e\x28\x50\x25\x22\x34\x3d\xb9\xa0\x52\x34\xa1\xe3\xaf\x28\xda\xc0\x1a\x91\x89\x65\xf1\x56\xfd\x3c\x42\xfe\x54\xe4\x4e\x93\xfb\x0e\x95\xde\xaa\x99\x63\x3f\x54\x89\x4c\x82\xbe\xd4\x66\x4b\xf2\x28\x0c\xde\x1d\xe7\x28\xb7\xd7\xba\x27\x78\xa7\x45\x66\x2c\x7c\xeb\xe1\xae\x39\xa2\xc0\xf1\x7f\xb7\xfc\x04\xab\x1a\x4e\xab\xfe\x54\xee\x63\x95\x21\xad\x2c\x44\x72\x3c\x09\xa4\x64\xf8\xba\x76\xed\x95\x5d\x99\x67\xff\x54\x20\xf5\xbf\x1d\xa3\x02\xa3\x77\x6d\xbc\xee\x2f\x90\xff\xe0\x4d\xf6\x01\xe4\x27\x51\x82\xa2\x48\xed\x89\xbf\x80\x55\xfd\xfe\x34\x8e\x4a\x94\xd4\xcc\xe6\xd2\x7f\x5b\x3f\xb8\xdf\xd4\x52\x22\xb1\x02\xf6\xd5\x39\x3f\x7e\x4a\xb8\xaa\xb8\x17\x85\xc8\x76\xbc\x01\xa5\x86\x82\x59\x8a\x7b\x32\x46\x9b\x96\x17\x6f\x0b\x9e\xaf\xcb\xe2\x35\x55\xf0\x95\x57\xc7\x6e\x80\x32\xae\x8a\x6a\x6a\x79\x74\x54\xb0\xdd\x31\xe9\x58\xcd\x57\x8b\xe7\x9f\x90\x5a\x9d\x76\x7b\x98\x30\xd3\x73\x7e\x5f\xc2\x09\x39\x29\xd4\xc8\x91\xe1\x24\xe1\x52\xda\xac\x8a\x43\x66\x6f\x80\xab\x4b\x37\x40\x78\x48\x46\x6c\x76\xb8\xeb\xd8\x97\x13\x21\x63\xd1\xbd\xf2\x39\xf0\xf2\x46\x69\x93\xfb\x11\xf5\xa7\xaa\x8f\xd5\xde\x52\x2b\xf6\xb7\xeb\x8b\x18\x85\xb3\x8c\x8e\xfb\xdd\xd3\x6a\xf2\x63\xd4\x0b\x30\x06\x3c\xf3\xcb\x7d\x51\x62\xb5\x79\x95\x8f\x49\xec\xae\x22\xbe\x9b\x1f\x9f\x53\x5f\x22\xa0\xfa\x0e\x34\x3f\x73\xd9\x7b\xad\x3c\xa0\xe0\xb8\x5d\x97\xef\x75\xc9\x31\x7f\x32\x86\x94\xf2\x20\x02\x57\x7c\xea\xea\xf6\xdd\xc1\x30\x49\x5c\x33\xcb\x2a\x17\x03\x32\xb8\xf1\x1d\x84\xe0\x81\xe3\x10\xb8\xe3\x97\xec\x8a\x8a\x53\xf1\x28\x06\x04\x7b\x3c\x9f\x21\x7f\x2c\x72\xb8\x8c\x3b\x33\x78\xc4\x4c\xb9\x96\xab\x3f\x9a\xbe\x9b\xda\x46\x61\xd3\x6b\x25\x84\x19\x02\xf9\xd3\x29\xc5\x26\xf2\xdb\x68\x16\x1e\xb3\x28\xb0\xd4\x08\x4f\x8e\x2e\x6f\x95\x7f\x4d\xab\x76\x07\xb8\xc1\x9e\xa7\x38\x13\x60\x21\xa9\xe9\x44\xe7\xdd\x0d\x80\x18\xfc\x61\x07\xc9\xfb\x78\x2b\xe1\x49\x14\x7a\xd8\xdd\x51\xb4\x86\x18\x9a\xd3\x67\x6e\x35\x4f\x94\x46\x72\x47\xd7\x08\x34\xb1\x88\x9c\xc7\xa6\xb8\xb4\xdd\xed\x16\xa3\xd9\xce\x13\x90\xb6\xcd\xa5\x35\xcd\xbd\xad\xbe\x07\xb8\xbb\xea\x2d\xe3\x9c\x43\x62\x41\xd5\x8b\x2c\x1d\xc8\xb1\x8d\xb7\x27\x2e\x7c\x0f\x3b\xdf\xd0\x01\x9a\x4d\x3f\xa2\xa0\x12\x57\x6f\x53\x41\xb9\x41\xfc\xdf\x28\x67\x46\x26\xd3\x42\x04\x11\xf2\x26\xcd\x16\x8b\xe5\x7a\xb7\xbf\x5b\x2d\x9c\xe7\xd2\x86\x09\x7e\x68\xf1\x1c\x37\xe8\xc7\x5b\x77\x81\x62\x96\xba\xdd\x91\xdf\x7e\x16\xe5\xcb\xd4\x88\x72\x09\x86\xf7\x62\xf9\xbc\xfd\x52\x64\xea\xf6\xce\xc4\x55\x42\x71\xe3\x41\x67\xda\x90\x9a\xb9\x7b\x00\x1f\x98\xd7\xe1\x45\xee\x8a\xdc\x2a\xef\xdb\xc3\x3a\x8c\xa5\x2d\x23\xcc\xd5\xb9\x0d\xc9\x1d\xbf\xa1\x8b\x46\x48\xf4\x1f\x37\x36\x8e\x31\x5d\xf7\x05\x3a\xd6\x7d\xd4\xfa\xd8\x41\x89\x1f\x02\xd4\x63\x5a\x95\x70\xee\xae\x9d\x98\xea\x9e\x41\x3e\xb7\x1e\xcf\x4c\xd7\x37\x80\x53\xe3\x27\xd6\x89\x04\x3a\x2c\x5d\xd4\xa8\x71\x32\x8a\xf6\xb8\x16\x81\x95\xac\x4a\xff\x1a\x2a\x43\xb4\x47\x24\xa6\x1e\xdb\xb9\x6d\x5c\xa3\xd1\xab\x12\x9e\x6f\xe0\xd8\x25\xe8\xa6\x82\xf6\x9d\xff\xd2\x1d\x61\xdc\x06\x2e\x8f\x50\x73\xc5\x6b\x6e\x17\x91\x05\xc8\x0c\xe7\xb4\xf0\xa2\x04\x9d\x11\x23\x88\x36\xbc\x05\xe1\x25\x46\x12\x7f\x4c\x46\xf0\x58\xbc\xa6\xe3\x92\xb8\x20\x82\x61\xc5\xe5\x54\xb9\x2e\x42\x41\x24\x47\xa7\xd3\xd2\xc5\x3d\xa4\xda\x19\x0f\xe1\xb3\x08\xf7\xad\xb4\x72\x01\xe4\x48\xf1\x4d\x09\x1a\x78\x0a\xd9\x71\x4b\x5e\x21\x91\xc9\xd7\x14\x4a\x5e\xca\xe3\x65\x6a\x39\x7a\xd6\x1c\x77\x6a\x12\x46\xb6\xaa\xdd\xce\x01\xc1\x7b\x45\x8d\xf1\xeb\x0b\xbc\x18\xf3\x56\x5b\x24\xf3\x5e\xad\x6f\x22\x1c\x45\x40\x63\xc4\xdb\xe4\xcd\x69\x5f\xa7\xf2\x05\xea\x6a\x6f\x33\x06\xfb\x21\xa6\x50\x04\x61\x8c\x0e\x19\x57\xea\x01\x8b\xe1\x7d\x49\x6e\x92\xdc\x12\xa1\x12\x30\x64\x81\x43\x32\xf3\xcf\x2b\x2a\x22\x8a\x25\x32\x7c\xe9\x26\x97\xf7\x65\x71\x5a\x50\xf7\xc3\xb1\x07\xa4\x77\x8b\xd4\xae\xd8\xf0\x7c\x3a\x55\x62\xad\x8d\x04\x30\xa6\xc7\xbe\xf0\x13\x6c\x9a\x36\xec\x14\x37\xa6\x15\xa3\x81\x86\x01\x25\xc2\x3a\xed\x8a\xc2\x82\x29\x9a\x50\x77\xac\x7d\xc8\x81\xc8\x59\x7f\x85\x84\x18\x76\x82\x76\xb5\xc8\xa6\x84\xc7\x8e\x89\x46\x09\x21\x4d\x8e\xca\x24\xea\x3a\x51\xfa\x89\xd4\xa8\x12\xd2\x33\x50\xdd\x12\xfe\x6c\xd2\x12\xd4\x3c\x55\xd3\x11\x81\x46\x22\x9c\x73\xcf\x32\xe1\xf2\x9c\xe3\x81\x8a\x88\x24\x72\xad\x94\x32\x3d\xf7\xe6\xd4\x0d\xe0\x89\x67\xf9\xa9\xbe\xa6\x87\x23\x54\xf5\x63\x51\xd6\x07\x7e\x18\xb6\x6f\x0a\xa5\x01\xdd\xcb\x87\x42\x36\xd5\x73\x07\xf6\x10\x40\x43\x0f\xcb\x50\x45\x7e\x58\x67\xbc\xa7\x20\xf9\xb7\xdf\x67\x3f\xd8\x04\x8a\x2c\xb4\xe7\x61\x5a\x1a\x37\x09\x33\x01\x3e\xd9\x77\x84\xf6\x42\x0c\xd2\xd0\xce\xb7\xce\x8b\xc1\x27\xba\xa3\x21\x20\xd1\x91\x71\x84\x36\x80\x8c\x22\xd7\x94\x29\x4a\xe8\xd8\x43\xd7\xa3\x67\x07\x84\xd2\xc9\x7f\x28\xa1\x81\x08\x1b\x95\xb4\xde\xd6\xe6\xc3\x1e\x84\xf6\xe3\xb0\xce\xda\x0f\x30\xce\xd2\x63\x1e\x16\x9e\xda\x8f\x9b\x0d\x37\x40\x49\x3c\x45\x6c\x85\xc4\xd1\xe2\x58\x98\xa4\xd5\xc7\x18\x14\xdb\x25\x21\x3e\x9a\xfa\xbc\x39\xb5\x8b\x78\x42\x31\xaa\x24\x51\x09\x42\x4b\x1c\x24\x68\x5a\x2d\xbf\xf1\x0a\xa5\x1f\x6b\xa0\x9d\x24\xa3\x85\xd1\xf4\xef\x46\xfa\x89\xb6\x9a\x6f\x1f\x75\x07\x4a\x5f\x32\x6d\x7a\x26\x4b\xc0\x14\xf3\x43\x71\x08\x66\x79\x91\x5f\xdc\x26\x25\x69\x68\xca\xd5\xee\x53\x70\x35\x65\x5a\x53\x92\xc6\x04\x79\xb4\xbe\x3f\xec\x36\xab\xdf\x06\x50\x73\x19\xf8\x1a\x25\x9f\x86\x8c\xaf\xe3\x6d\x54\x06\x54\xfb\x46\x7f\xea\x6d\x79\x6a\x43\x24\x80\xd6\x0f\xec\x08\xb2\xdd\x30\x91\xa0\xbc\x9d\xb5\x55\x98\xad\xe8\x8e\x49\xa3\xff\x7b\x70\xac\x83\x77\xe9\x01\xaa\x0f\x5c\x0c\x19\x80\xc6\x27\xda\xbb\x6e\xaa\x59\x59\x4f\x69\x4c\x94\x0c\x05\xc5\x42\x68\xc5\x5f\x01\x19\x3e\x6e\x01\x1e\xae\x10\xb8\x53\x45\x00\x7b\xb1\x28\xd0\x0c\x5c\x03\x9d\x51\xff\x69\x43\xda\xfb\x62\x5c\x01\x96\x91\x24\x28\xc2\xb6\xe3\xe9\x1b\x47\x95\x4b\x91\xa5\xf2\xb3\x85\x24\x23\x4d\x8c\x96\x53\x71\x98\xa7\xaa\x6b\xdc\xf8\x14\xfe\x23\x63\x1e\x24\xa6\x9c\x6d\xde\xc0\xf7\x0a\xca\x81\xec\x9b\x1d\xc5\x18\xc5\xad\xe2\x1f\x69\x23\x79\x7a\x4d\xd2\xc9\x6e\xde\x50\xe2\x85\xa2\x77\x2d\x7a\x28\xd9\x08\xa4\x30\xb9\x9f\xc4\x13\xb8\x63\x7f\x29\x01\x5a\x33\x7e\xd7\x06\xef\xa6\xd4\x37\x5a\x73\x89\xcf\xb0\x52\xf1\xf0\xc7\x1b\xfe\xdd\xed\x19\x92\xd3\xc8\xef\x55\x7f\x47\xe2\x74\x4a\xf2\x00\x30\xae\x3b\xf1\x5a\x1e\x4d\x3c\xfc\xfc\x32\xb8\x9f\x6b\xd1\x03\x25\x85\xa7\xc3\xb0\xa7\xcc\x43\x8b\x3e\xeb\xae\x28\x42\x19\x39\xce\xee\xac\xae\x7e\x62\x2f\x0a\xa8\xf9\x05\x93\x1f\xdd\x28\x50\x4c\xb8\x94\xf5\xf7\xbc\xec\x30\x6f\xa3\xbc\x8e\x14\x3a\x06\xf3\x31\x3e\x50\xde\x53\x52\xca\x50\x68\x67\xf1\x07\x5a\xff\x23\x4f\x41\xaa\xc0\x08\xbd\x99\x2c\xe5\xf2\x1d\x4a\x99\x56\xb0\x3d\xf3\xee\xfd\x01\x10\xa4\x4f\x7f\x2d\x6a\x58\xb8\x3f\xea\x30\x12\xc6\xe5\x2e\x0a\xbd\xbb\x9c\x61\xbf\x7b\xd8\x3e\x0d\x71\x92\xca\x0b\xb9\x23\xb0\x37\xac\x3a\x43\xa1\xc5\xd1\xa7\x54\x1e\xa7\x86\x2d\xe9\xad\x0b\xdf\x6f\xdb\x5c\xe5\x69\x8d\xfb\xcc\x89\xbf\xef\x85\x13\xff\xa8\xce\x5d\xf4\xa8\x48\xc4\xe2\x61\x6c\xd2\xab\x28\x4c\x12\x02\xca\x27\x09\xf2\x2e\xbd\x39\x17\x65\x5a\xdb\xe8\xcd\xa2\xf2\x19\xd0\xa0\x0b\x9f\xa1\xfc\x01\xb9\x1a\x70\x17\x9b\xb6\xe3\x3e\x1b\x69\xcf\xa2\x5e\x80\x0d\x94\xbd\x0a\xd3\x87\xad\x09\x8a\xc6\x54\x24\x9d\xe0\xde\xcb\x30\xcf\x34\xbe\xed\xc0\x4b\x94\xb5\xe0\xeb\x8c\x5f\x46\xea\x28\xa3\x09\xa0\x02\x6d\xb8\x25\x0d\xa8\x6c\x08\x6f\x50\xa1\x9f\x60\xca\xb8\x63\xaa\xb1\xa9\xa2\xec\x1a\xd4\xd2\xf7\x0f\xdd\x76\xf0\x55\x28\x12\x74\x66\xf6\xa8\x0d\xd1\xe9\xed\xdb\xa3\x11\x95\x4e\x01\x08\x0d\xf9\xb5\x9a\x8b\x52\x71\x90\x60\xfe\xb9\x03\x00\x6d\x1b\xb7\x95\xa8\x58\x50\x49\x9d\xca\x74\x96\xcd\x5b\x53\xdd\x15\x9e\x55\x0c\xb1\x8b\x95\x9f\xb5\x6e\x43\xf3\x61\x55\x56\x31\x92\xc8\xae\x56\xa7\x8b\xa6\xb4\xdc\xf1\xab\x7e\x48\x22\x8d\x24\x9a\xe4\xf9\x1a\x4a\x5d\x94\xa7\x71\x78\x68\xb3\xd0\x8a\x07\x21\x52\x00\xee\x75\x5a\x56\x66\x27\xe9\xb1\x80\x8a\x43\xac\x8d\x4e\x75\x8d\xc1\x13\x3c\x37\xb5\x2c\x26\xb4\xad\xcc\xbe\x4a\xe6\x4e\xd2\x21\xe7\x6e\x0d\x4d\xfc\x35\x25\x03\x1e\x8c\xe8\x7b\x8b\xf2\xb4\xe3\xe5\x01\xea\xbd\x02\x8d\x59\xb5\xc9\x09\x52\x26\x26\x3d\x97\x8d\x7b\x93\x95\x0a\x3d\x0c\xd7\xdb\xe9\x72\x65\x1e\x15\x44\x80\x60\xdc\x73\xeb\xb5\xcd\x53\xd5\xfa\xd5\x68\x91\xb6\xb2\x9d\x10\xd3\xfb\x02\x08\x71\x55\x6f\xb3\xe2\x0c\x2b\xdb\x33\x3e\xf1\x4a\x95\x8e\x8c\x6c\xd3\xec\xfb\x6e\x3b\x40\x3b\x2a\xcd\x02\x6f\x48\x38\x7c\x97\xbe\xba\x4f\x09\x1e\x21\x48\xe0\x59\x3b\x6c\xdb\x50\xae\xf6\x76\x3c\x00\x1e\x08\xc4\x00\x2a\x7e\x3e\x77\x79\x4c\x20\x3e\xc5\xa4\xb9\xf1\x3e\x56\x8b\xe7\x13\xaf\x3e\xa8\x67\x00\x61\x3a\x31\xcd\xb7\x38\xff\xf9\x14\x4f\x33\x8e\xab\xc0\x17\x0a\xb7\x8c\xcd\xef\xa3\xbe\x63\xf0\x75\xec\xbc\x6b\x24\x9b\xbe\xd6\x52\x51\x40\x49\xa8\x6d\xf6\xd2\x7c\xc8\x76\xcd\x71\x59\xaf\x1b\xf1\x0d\x26\x75\x59\xa0\x89\xc4\x5e\x82\x76\xe6\xe2\x3e\x82\xd2\xe9\xee\xe7\x02\x6d\xe2\x82\x0a\x1e\x9b\xd2\x69\x25\x28\x08\x09\x13\xdc\xac\x23\x28\xeb\x3b\xb7\x9a\x76\xc5\x9c\xe7\x2f\xed\xc7\x74\x03\xa3\x28\xc2\xf7\x06\xa5\xf4\xbd\x9e\x9d\x00\x22\xc1\xb1\xea\x3d\x2b\xeb\x45\xa7\xb0\xa1\x20\x92\xc6\x8e\x71\xa5\xe6\xc5\xfb\x6d\xcf\xe2\x16\x33\x06\x73\xe7\xab\x84\xf3\x41\xe0\x65\x00\x83\xb3\x5c\x8d\x8d\xd7\xf8\x75\xc5\xca\xa3\x83\x9c\x15\x94\x55\xa7\xbf\x75\x13\x32\x07\x8c\x7a\x83\xed\xfc\x0b\xe4\xde\x50\xb5\xab\x03\xc3\xfb\x6c\xf4\xaf\x25\xa8\x57\xc0\x42\xe3\xbb\x95\xad\xb7\x5a\xc9\x36\xe8\x73\xd6\x7e\x3a\xbf\x21\x21\xd2\xc1\x60\x17\x8b\xaf\x96\x6e\xca\x01\xef\x20\xf1\x3d\xd7\x2a\xf9\xd4\xfc\xc1\x87\x42\xdf\xed\x41\x8d\xfb\x13\xe2\xce\xea\x55\x7e\x76\x5c\xc0\x0a\x12\x15\xe2\x21\x04\xd8\xf4\x4d\x34\x33\xf5\x9a\xf6\x2c\x61\x3d\x5e\xa0\xdf\x9e\x20\xd1\x26\x66\x39\xf3\xcb\x3f\xb8\x7c\x39\x17\xb5\x73\x72\x80\xd3\xa0\x83\x39\xcf\xa1\x76\x4c\xa7\x0a\xb8\x08\x30\x1a\xde\x9f\xcb\x42\x42\x55\xf5\x12\xa9\x6b\x2e\x5f\x46\x8c\x81\x6c\xda\x71\x6c\x2f\x21\x3c\x31\x6c\xfd\x28\xf2\x0a\xf2\xfa\x3e\xcd\x26\x95\x30\x90\x3e\xc1\xa4\xd7\x09\x6a\x6e\x85\xa2\x31\xbd\xfe\x37\xad\x21\xee\x6c\x6a\xf4\x5d\xda\x70\xdb\x95\x1d\x30\x8b\x34\xf9\x28\x92\x27\x60\xb5\xd3\xce\x4d\x0d\x58\x07\xff\x00\x61\x05\x92\x83\xab\xdc\x2d\xf3\xba\xbc\xac\xf2\xc7\x22\xaf\x8f\x1f\xca\x5b\xba\xd3\x94\xc9\x32\x94\x60\x52\x8d\x96\xf1\x69\xf0\x51\x3e\xf9\x7f\x93\x97\xa7\x08\x23\xb1\x4d\x26\x62\xe1\xba\xf8\x01\x65\xd5\x54\x36\xb1\xe8\x46\xd1\xd0\x72\x88\x9d\x79\x53\x39\x8d\x31\x67\x34\xb5\x17\x05\xc4\xea\x21\xde\xc1\xb9\xa8\xdb\x2d\xe9\xa6\xa9\xd4\x1e\xe3\x8e\x1f\xcb\x44\x7d\x18\xba\x21\xbc\xc5\x49\x17\x8d\x5a\x99\xb5\xc7\x43\x4c\xc9\xcd\xee\xee\x36\xfb\xc7\xd9\xef\xb3\xfd\x6e\xd9\xd5\xb4\xb4\x27\x49\xdc\x6b\xbd\x2c\x78\x0d\x87\xa2\x4c\x25\xcf\x0c\xe8\xe8\x56\x1a\xc7\x5a\x03\x4d\x58\xc0\x6d\x53\xea\x01\x76\x6f\xc5\xb2\x4b\x1f\x69\x92\x44\x60\x9b\xcc\x3a\x54\x94\x4d\x67\x0c\x9a\x65\xdd\x60\xf0\x51\xa4\xad\x6b\x9f\x6f\x37\xad\xbf\x97\x09\x55\xda\x27\x46\x5f\x6e\xa6\xd4\xae\xb8\x9b\x4f\x2e\xeb\x13\x81\xed\x53\x66\xf7\xd8\x1e\x79\x39\x45\x98\x8d\x3f\xa4\xa6\x89\x08\x78\x07\x09\x58\xa4\xb7\x5a\x59\x75\xc0\x0c\xc9\x83\xbb\xd9\x2d\x98\x96\x2c\x53\xeb\x9c\xa2\x7f\x74\xa0\x1c\x0c\x76\xe1\xe0\x31\xdd\x4b\x0a\x89\x60\x5d\xd9\x72\x5d\x16\xba\xa7\xc4\xd4\x21\x8d\x11\xbc\xee\xc8\x5c\xe6\x90\x83\x4e\x65\xca\xcb\xcb\x67\xd4\xb0\x4a\x87\x3c\x0a\xac\x57\x39\xcb\xb2\xe2\x0d\x5b\x5d\x90\x74\xe0\xf6\x43\x87\x52\x20\xa7\x67\x5a\xe1\xec\xb1\x16\xd2\x7d\x62\xe6\x45\xca\xa2\xc3\xe7\x4d\x99\x77\x92\x41\x93\x97\xc2\x74\x84\x98\x91\xef\xce\x3a\xea\x84\xc6\xf8\x69\x1e\x8a\x83\x7f\x0d\x27\xd7\x49\x10\x62\x28\x92\x01\xbc\x6c\x6b\xe0\xd9\x0e\x35\x8a\xcb\x7d\x77\x7e\x4c\x10\x0d\x5d\x35\xe2\x1a\xee\xa9\x13\x4e\x90\xc7\xcf\x4a\xa3\x7c\xfb\xdd\x85\x33\x9a\x73\x1f\x93\xfe\xcf\x3f\x9f\x96\x9b\xed\x7e\xf6\x74\xb7\x5f\xcf\x36\x3b\xf3\x1f\x43\xf1\x50\xa5\xb9\x0a\x31\xf5\xb0\x7c\x3f\xf3\x7e\xe6\x0a\x2f\xc6\x1d\xf9\xe7\xd7\xd5\x6e\xf9\xb0\xda\xa2\x26\xe8\xe3\xec\xb7\x11\x3a\xb9\x1b\x1c\x05\x38\xc5\x6a\x24\x3c\x34\x70\xea\xee\x13\x8a\x76\x2f\xb2\xa5\x2d\xfe\x96\x3f\x14\x3c\x5f\x4d\xf6\x1f\x2d\x44\xc8\x82\x8e\x3a\xe6\xa9\xc8\xbb\xd5\x02\xca\xee\x94\xe3\x37\x2d\xa5\x17\x9a\x32\xe3\xf2\xfd\x9c\x96\xa0\xee\x80\xab\x2c\xed\xf2\x77\x5a\x6a\x8a\xc9\xe8\x07\xa8\x64\xf1\x0a\xef\xfb\xc5\xef\x8b\x0f\x36\xfa\xf1\x95\x15\x51\xd0\x11\xd8\x7f\x9e\xbf\xd3\x2a\x00\xdf\x35\xe5\xf5\x5c\x91\x5a\x31\xe1\x32\x8f\xf3\x26\xcd\xae\x73\x45\x5a\x81\x8f\x51\xdf\x30\x86\xd1\xe0\x1b\xd2\xc7\xdc\x89\xe3\xb7\x61\x68\x77\x50\x2a\x34\xf0\xc5\x19\x72\x87\x46\xb2\x87\x74\xcc\x30\xad\x8e\x9c\x62\xfd\xd2\xd1\x9a\xd3\x8e\x82\xf6\xfb\x18\x1d\xdf\x3a\xa7\xbe\x60\x3d\x77\xcb\xdd\xde\xfe\x9f\xfd\x97\xcd\xf3\x77\x8b\xc4\x01\x8f\x04\x52\x9b\xfb\x44\x25\x96\x4d\x91\x4d\xec\xe1\xad\x6d\x05\x3c\xa2\x13\x91\xf4\x3d\xa2\xbe\xbb\x9c\x4f\x03\x84\xdf\xad\xbf\xae\x1e\xfa\x04\x19\x78\x34\xe2\x88\x30\x7a\x9a\x2f\x1e\xfe\xb6\x6f\x01\x3c\xca\x8d\x74\xf5\x2c\x57\xef\x45\xf9\x50\x1c\x0e\xce\x1d\x01\x8f\xca\x10\x8d\xc9\x1d\xb4\xb3\xa1\x76\x7c\x83\xed\x81\x04\x4b\x9f\xf3\xe6\xf2\x0d\x2e\xe3\x95\x04\x5e\x28\x4d\xa7\x10\x77\xb8\xc4\x41\xd8\x05\x5e\xa8\x20\xf2\x3b\x7e\x19\x0b\x9b\xb8\x46\x09\x81\x17\x79\xda\x34\x02\x9e\x6d\x12\x0a\xc9\x2f\x3b\xe7\xbf\xf3\x70\xc0\x8b\x95\x6f\x88\xf8\xea\xba\x28\x73\xb8\x6c\xd3\x43\xee\x7e\x2e\x61\x0a\xb7\x36\x97\xe0\x09\x6f\xda\x2c\xf0\xb8\x6f\xf2\xa9\xa8\x4e\x62\x58\x82\x67\x0f\x0f\xcf\x3f\x67\x4f\xae\xc4\x07\x9e\x88\xb9\x61\x19\x35\x6e\xca\x02\x19\xca\x3e\x26\xa2\x01\x4f\x7a\x04\x5d\xe6\xac\x0d\x1e\xdc\xdf\x84\x8f\x25\xf9\x5e\x70\x6e\x7e\xb1\xb5\xf2\x69\xd3\x55\x3b\x58\x44\xae\x3c\x59\x6d\xcf\x65\x5a\xc3\xf3\x5b\x9e\xe6\x07\x5b\xac\x9a\x4c\x44\x09\x1c\x5f\x84\x30\x24\x29\x83\xb7\xae\x18\xf1\x23\x33\xf9\x56\x8b\xe7\x11\x81\x39\x78\x9a\x86\xd8\xde\xef\xf6\x9f\x6a\xdb\x54\x67\xc8\xbb\x26\x1a\xf0\xb4\x12\x78\xba\x81\xad\xf5\x52\x53\x40\x7c\x3f\xc0\x1e\xd0\xcc\xac\x23\x03\x89\xcd\xab\xa6\xec\x1a\x86\xad\xd3\x00\xc4\x8f\x82\x20\x19\xe4\x49\xee\x8b\x72\xc3\xb5\x76\x19\x59\x20\xbe\x4c\x6c\x9a\x23\xcb\x30\x32\xbc\xb5\x1d\x01\xf1\x55\x8c\x95\xd6\x27\x30\x9f\x14\xa9\xa3\x3e\x6d\x29\xbe\x09\x1e\x03\xe2\x6b\x82\xa1\x4b\x93\xa7\x75\x15\x7a\xb6\xf0\x8c\xb8\x02\x77\x4b\x34\x62\x58\xa8\x71\x59\x9a\xa9\xbb\x0f\x84\x0a\x8e\x0a\x50\xf3\xa7\x85\xd1\x46\x6a\x9f\xcc\x22\xb2\xdc\x10\x45\x31\xe2\xfd\x91\x42\x9d\xf3\xd3\x17\x38\x61\x02\x13\xc3\x6d\x37\x26\xf0\x24\xfa\x72\xcb\xa7\xc5\xe6\xf7\x35\xb6\xab\x7c\x5b\xfe\xee\x8e\x86\xd4\xc8\xec\x1d\xa0\xc6\x8e\x3e\x28\x4d\xdf\x6a\x65\x7a\x94\xc7\xd3\x80\x84\x89\x42\xe7\xe7\x81\x9f\x44\xd1\x5d\x42\x48\x7c\x6b\x98\x3b\x1c\x84\x16\x40\x22\xca\xa5\x0d\x49\x1c\xe1\x86\xc5\xaf\x0f\x9d\x3e\x20\x71\x22\x12\xeb\x4f\xde\x97\x00\xae\x34\x32\x7c\xe1\x36\x16\x06\xc2\xa8\xe9\xed\x7a\x48\xb1\x72\xe1\xe4\x4e\xff\x4e\xde\xf6\xb3\x64\x12\x90\x24\x62\x8c\xd8\xf9\x31\x2a\xf7\xde\x36\x9d\x84\x7b\x1e\xe7\xd6\x8b\xbe\x6e\xc3\x70\x83\x02\xd5\x17\x07\x47\xb2\x92\x40\xb8\x32\xc0\x98\xdf\x96\x9b\x99\xfb\x9b\x48\x3c\xa7\xa5\xfd\xc0\x73\x65\xe1\x5f\x7f\x73\x27\x02\x0c\x91\xdc\x16\x40\x99\x8c\xdb\x6d\x8b\x41\x84\x8e\x31\xb0\xe5\x4a\xb9\xe9\xfd\xe1\x9d\xcb\x48\x99\x86\xda\x01\x90\xfc\xbe\xf9\x80\xf9\x1b\x08\x12\xb9\xda\x14\x83\x03\x39\x8e\x08\x06\x81\x00\x91\x38\xcd\x4e\x06\xca\x38\x6a\xa8\x61\x6e\x4c\xe4\x21\xdf\x9f\x2d\x90\x3d\x6b\x2d\x71\x1e\x7f\xba\x8b\x11\x88\x42\xdf\x84\x2a\x8e\xd7\x71\xfc\x69\x75\x18\x62\x82\xca\x52\x3f\x98\x07\x7f\x1f\xf7\x47\x80\xef\x05\x14\x1d\x65\x95\x1e\x3a\xbf\x16\x7c\x2f\x02\x6c\x87\xc3\x52\xed\xf6\x25\x1d\xe4\xa5\x6c\x41\x19\x7c\x8f\x19\xe1\x9d\x4a\x1e\x41\x35\x19\xa8\x5d\x71\xfe\x7e\xee\xae\xc0\x13\xee\x0d\x2c\x53\x5f\x99\x98\xcc\x55\xd6\x9d\xa0\x31\xfe\x79\x03\x78\xc9\x2e\x7b\x95\x56\xa2\x29\x2b\xe4\xb6\xec\xae\x29\x62\x6c\x3b\xea\xd5\xba\x8d\x60\x2c\x52\x6b\xf7\xf7\xae\x23\x2c\x42\x59\x8e\xec\x13\x4f\x33\x77\x88\x10\x40\x5f\x4f\xf1\xcb\x7d\x9a\xa7\x95\xeb\xdc\x77\xeb\xd1\x27\x54\x0b\xab\x19\x9a\x6d\x00\x53\x74\x0b\x9e\x65\x82\xcb\x97\x5b\x04\xec\xe0\xfb\x91\x8f\x89\x48\x84\xff\xd9\xb0\xbc\x42\x0c\x80\xfb\x4d\x3f\x91\x58\xa4\x68\xa3\x40\x74\x4e\x56\xb7\x90\x01\xe0\xfb\x42\xa1\x47\x98\xe1\xf4\x41\xea\x2b\x13\xbb\xf3\xee\xf6\x29\x01\x74\x85\xb9\x28\x4a\x64\xa4\x9c\x7c\x4b\x1a\x79\xd8\x8d\x7e\xe4\xd5\x2c\xcb\x66\x75\x5d\x56\xe3\x8a\x98\xef\x06\x32\x1a\x45\x4e\x35\x99\xeb\xd6\x9c\x4c\x72\x37\x6e\x60\xc2\x71\x2b\x4a\x6b\x38\x99\xba\xe0\xad\x4e\x34\xf0\xa9\xf4\xbd\xa4\x8b\xc9\xee\xc0\x08\x2c\x8e\x23\x48\xf0\x03\xea\x63\x97\x9c\x2e\x8b\xbf\x20\xef\xcb\xdc\xe0\x07\xa0\xd0\x5e\x1a\x57\xe1\xfe\x79\xb3\x5f\x3d\xfd\x58\x6e\x77\x8e\x44\x02\xfc\x90\x98\x76\x49\x87\xc0\xd9\x80\x84\xf4\x5c\xff\xb7\x44\xb1\xc3\xb4\x22\xf8\x61\xe0\x47\xbe\xcb\x42\x72\x59\xdf\x35\xa6\x56\xb3\xca\xef\xf8\xa5\x9b\x48\x61\xa0\x88\x41\x0d\xa4\x2e\x65\x07\x7e\x08\x12\x5d\xe3\x6f\xb3\x87\x70\x90\x92\x04\x3f\xd4\x0a\x61\xc5\xdb\xa2\x7e\x29\xfa\x24\x2c\xf8\x31\xa7\xe8\x41\x54\x5c\x1e\xfb\xbf\x32\xc2\xb1\x87\xd6\xa5\x66\x3f\xae\x55\x80\xcf\x7c\xea\xdb\x10\xc5\x0a\xa6\xd9\x8e\xa7\xa1\x52\x99\x1b\x1b\xd3\xc4\x00\x06\x0e\x36\x08\xc4\x2b\x2f\xf8\x79\xe1\x88\x98\xaf\x50\x50\xb7\xd0\x9f\xe0\x33\x46\xe3\xc0\x89\x6e\xe5\x57\x1a\x67\xe3\x4f\xcb\xb8\x40\x28\x8e\x89\xdf\x51\xe4\xcd\x3d\x69\x12\x86\x89\xb4\x2d\x16\xdf\x00\xce\x69\x7e\xf8\x67\x53\xf4\x0b\x24\x89\x69\x02\x03\xfe\x59\xdb\x0f\x69\x8a\xc7\xb7\x2c\x45\x02\xc2\xd3\xbd\xfb\x5e\xcd\xde\x0c\x47\xc9\x7d\x51\x0e\x8b\x76\xe0\x73\x21\x1d\x4d\xbd\x52\x13\x27\xc3\x57\x5e\xe0\x36\x1d\x53\x47\xdb\x15\x86\x97\xea\x33\xaf\x67\xe0\xf8\xf7\x85\x27\xf0\x41\x45\xac\xf7\xe5\x6e\xf6\x88\x82\xaf\xbd\x00\xeb\x83\xf2\x58\x14\x95\x63\x45\x1d\xdd\x13\xf5\x22\x85\x5b\xd5\x63\x9a\xd7\x7d\xff\xf2\x64\x4c\x9c\xa0\x3d\x81\xfa\xe8\xaa\x3b\xee\x88\x32\x1a\x45\xa2\xb9\x6c\x78\x89\x60\xe3\xc9\xb9\x24\x54\x08\x14\x34\x60\xb6\x1b\x59\x73\xa0\x6d\x6c\x14\x19\x10\x44\x6b\x61\xaa\xc5\xd1\xb8\x19\xf6\xb0\x4f\x74\xe0\x77\xa9\xe5\x2e\x0c\x7e\xce\xb3\xcb\x20\x7c\xa0\x7e\x90\x70\x4b\x65\xfa\x98\xe6\xed\xa4\xb0\xa9\x41\xe6\x06\x84\x02\x63\x83\x6d\x21\x53\x9e\x6d\xe0\x94\x8e\x5b\xf9\x3f\x0e\xaf\xa8\x1f\xb1\xd0\xb0\x26\x20\xf2\x7d\x3f\x53\xaa\xbd\xd3\x39\x2f\x3f\xcd\x94\xdb\xb3\x29\xb1\x5c\x9c\x35\x2f\xeb\x95\x2c\x3e\x64\xbb\xfd\x7f\xfd\xd7\xfd\x9e\x36\x50\x2e\x2b\x52\x35\x82\x9c\x01\x0d\xbc\xd8\xca\xd6\x38\x71\x81\xf1\xd9\x81\xa7\x51\xb5\x08\x72\xf4\x0f\xbf\x38\xbe\x59\xa0\x81\xe0\x18\xdb\x0f\xc5\x58\x56\x8b\xe7\xfd\x6e\xb5\xdc\xd0\x41\xff\x07\xd0\x40\xc5\x0e\xd7\x70\x87\xe0\xd1\xeb\x8f\x1e\x5a\x50\xdf\xba\x84\x79\x73\x99\x1e\x8c\x7d\xb7\x8a\x8c\xcc\x8a\xec\xe5\x5e\x47\x33\x9c\x86\xda\xe0\x54\xdb\x38\x0a\x16\xbc\x2c\x8b\xba\x32\x1a\xff\x37\x3d\x5a\x1a\x69\x05\x86\x24\xfb\xf0\x34\xa8\xaa\x8f\x2c\x0b\x8d\xfd\x98\x8a\xbe\xd4\x63\x51\x23\x37\xed\x3a\x8d\x65\x82\x4c\x95\x55\x23\x2a\x59\xa6\x58\x62\xef\x39\x5b\x26\x17\x66\x5e\x62\xd9\xee\xea\xff\x3f\x6b\x6f\xd6\x9c\x3a\x92\xad\x81\xfe\x97\xf3\xd4\x0f\xfd\xa0\x29\x95\xd2\x7d\x03\x8c\xf7\xe6\x94\x6d\x68\xc0\xb5\xab\xaa\xe3\x04\x91\xc3\x4a\x50\x5b\x48\xb4\x24\xec\x4d\xfd\xfa\x1b\x5a\x39\x68\x40\x76\xd5\x8d\xb8\x0f\x5d\xdb\x4d\xa6\xe6\x1c\xd6\xf0\xad\xef\x7b\xcc\x6a\xc1\x72\x94\x7d\xba\xdd\xc1\x7a\xfe\x82\x3c\xc3\x9e\x8d\x28\xf4\x59\x90\x68\xcd\xc9\x2f\xf4\xe7\x44\xc2\x04\x62\x91\xca\x76\x1f\xdd\x8d\x09\x01\x20\x4c\x04\x8d\xb5\xdb\x27\xde\x3a\x70\x7a\xff\x0c\xa9\xe4\x61\x62\xb0\x99\x8b\x13\xd4\x4d\xbd\x6b\x5c\xda\x08\x42\x16\x86\x28\x06\x73\x40\x3f\x78\xc3\x32\x79\x27\xbe\x3e\xba\x24\x0f\xf5\x92\xd4\x64\x67\x67\x3f\x85\x9c\x52\x5c\xca\x73\xcd\xe5\x62\x75\x9b\x6d\x6b\xaa\x4d\xde\xc5\xfa\xe5\x71\xb5\x7d\xee\xd3\xa2\xb7\x8d\x52\x87\x03\x41\x94\x85\xd4\x59\x37\xdb\x26\x62\x1d\xb1\x13\x59\x93\xfd\x09\x45\xdd\xa9\x9a\x9b\x0e\xd2\xd3\x95\xd4\xc5\xf5\xbc\x56\x46\x8d\xac\xc7\x68\x66\x33\x24\x5d\x7f\x5f\x73\xc9\xcd\xd9\x5b\x73\x97\x46\x1c\x3e\xa7\x0c\xa4\x17\x5b\x47\x0d\x93\xad\x73\xe8\x33\xdc\x40\x28\xa3\x14\x43\x95\xda\x68\xc4\xdc\x4f\xd6\xbb\x14\x4d\x3c\x33\x54\x34\x7b\xaf\xe3\xfd\xed\x7d\x1d\xa9\x22\x5d\x72\xff\x01\x45\x73\xdb\x9f\xb2\xaa\xb9\x75\x88\x6b\x7b\x2a\x08\x42\xcf\xac\x8c\x3b\x47\x85\x80\x2e\xfe\x78\xee\x83\xf1\x93\x59\x9e\x2f\x58\x53\xcf\xb0\x44\xa0\x5b\x3a\x40\xea\x6a\x9a\x1a\x9a\xd5\x99\x1d\x75\x86\x67\x6a\x23\x0f\x95\xaf\x30\xb4\xa4\xb5\xb1\xd6\x6a\x5d\x1d\xfb\x18\x22\x88\xfc\x38\xf1\x03\xc7\xe3\xd6\x2e\xa6\x83\x7a\x36\x88\xfc\x54\xa7\x52\x2b\x6d\x76\x58\xe2\xcd\x37\xf8\x3a\x81\x03\x91\x6f\xf8\x6b\xde\x33\xf8\xe8\xc5\x76\xe6\x37\xa3\xd3\x3c\xb4\xde\xec\x41\x9c\x86\xca\x96\xe2\xb2\xcb\xd8\x28\x8d\x42\x4f\x63\xae\x0f\x29\x39\x00\x87\x66\x77\x66\x95\x43\x54\x67\xf6\x9e\xc3\x38\xc5\x85\xf7\x71\xfd\xfa\xf2\x30\x43\xef\x1f\xb5\x6a\xd0\xc4\xdc\xb9\x5e\xa9\x42\xd2\x82\xe6\x94\x55\xb2\xaf\x00\x02\x11\x21\x69\x98\xf6\xec\x1f\x26\x10\xb1\xe2\x9a\x53\x1f\xcd\xa3\x03\x93\xf2\xa1\x2a\x0b\xc0\x8a\xa8\x62\x54\xda\x0f\x11\x91\x80\xd8\xaf\x4d\x06\x02\x26\x62\x1e\x93\xb9\x3e\x88\x08\x78\x18\x44\x94\xac\x7a\x2b\x4a\x09\x43\x1a\x78\x88\x68\xe0\x47\x3a\x21\xf0\x9d\x55\xef\x50\x37\x4b\xd4\xf3\x73\x77\x4f\xdb\x1d\xc2\x46\x6b\xb5\x48\x96\x6d\x4a\x22\x29\x2d\x89\xb8\x0e\x79\xac\xd5\x3e\xb3\xd1\xad\xe1\xbb\x4e\x64\xa0\xa4\x1d\xf9\x9a\x31\x71\x6a\x8c\x45\xa9\x17\xa0\xd3\xf5\xc7\x1f\xfd\x28\x93\x6d\x0c\x18\x8b\xbb\x92\x99\xa7\xa9\xec\x04\x44\x29\x4d\xb1\xd6\x65\x51\xd6\xe7\x4c\xa0\xf2\x78\xdf\xc0\x8e\x52\x48\x31\x05\x96\x9d\x2f\x65\xd5\xa0\xb2\x4f\x85\x8e\xd6\x1d\x70\xc6\xba\xa8\x11\x23\x0c\x43\xcf\x1a\xa5\x6c\x4b\xe4\x20\x62\xb1\x1f\x9a\x3a\xb6\x7e\xc4\xf1\x2f\x13\xec\xd3\x81\x76\x88\x58\x9a\xda\x3d\xaa\x9d\x3d\x5a\xea\x69\x32\xe0\x12\xb1\x54\xe1\xbe\xbd\x5b\x2c\xca\xf3\x25\xcf\x5a\x8b\xd1\x6a\xc6\x9b\x2e\x9c\xf9\x48\xaf\xda\xfa\x94\xf3\xeb\x6d\xff\x51\x0e\xcc\xda\x88\x43\x68\x07\xa6\x15\x4c\x1d\xbd\x4a\x0e\xc2\x3c\x5f\x21\xa1\x5a\xd5\xa6\xc6\xca\x8d\x5d\xe1\x87\xa8\xca\x7c\xb9\x56\x97\xd6\x16\x85\xac\xe7\x8c\x45\x32\xd2\x15\xf7\x06\xcf\x21\xca\x65\x71\x97\x23\x80\x08\x98\x0e\xe4\x1c\xa1\xd1\x81\xc7\x7d\x6f\x5f\xb6\x7d\x84\x2e\x9e\xe8\x31\xff\xbd\x16\xed\xc6\x64\x4c\xcf\xc1\x5d\x13\x2f\x65\x58\xdd\xf3\x72\x3c\xb2\xfe\x97\x27\xbe\x47\x10\xaa\x62\x48\xbb\x7a\xf7\x4a\x82\x48\xe8\x78\xd4\x95\x3f\x67\xc5\x75\x42\x29\xd2\x76\x4c\x12\xe6\xd9\x7c\xac\xad\xb1\x00\x12\xc6\x3e\x5a\xdc\xdf\xb4\x2f\xb1\x29\xcb\x51\x21\x1b\x90\xc8\x8b\x71\x93\xbc\xe8\x92\xb9\x1f\x59\x73\xb2\x76\xd0\x94\xf7\x19\x47\x83\xb1\x41\x88\x4f\x70\x58\x6f\xca\xe2\xcf\x6c\xf0\x58\xd4\x93\x71\x57\xbc\xf7\x88\xf0\x44\xe4\x33\xae\x47\x08\xce\xe9\xff\x5a\xab\x87\x24\x51\x8c\x1b\x4f\x01\x1f\xbb\x86\x15\x12\x75\x45\xcf\x17\x96\x1d\xef\xb8\x8f\x26\xc7\x24\x49\x52\xcd\xa2\x7d\x40\xe5\xc9\xd1\xe3\x27\x4c\xa6\xd4\xea\x74\x54\x67\x86\xdc\x13\x4f\x63\x2c\x2e\x90\x44\x68\xd5\x1c\x09\xff\x9f\x52\xa1\x40\x12\xd0\x14\xd4\xed\x42\xda\x8e\xe7\xe5\xcf\x0b\x54\x19\xf4\xc8\x31\xff\xd9\x7f\xda\xd4\x8f\xa4\xd3\xaa\x1d\x6a\xf7\xd9\x1e\xc0\xfd\xc8\x51\x65\x68\xd0\xf7\xa8\x0b\x93\x21\xc2\x39\x11\xa8\xa6\x41\xb0\x07\x95\x15\xf2\xa5\xfc\x9e\x15\x86\x66\xf2\x3b\x30\xab\xc0\x69\x8e\xe2\x41\xe4\x33\xcb\x05\x54\x55\xe5\x87\x2e\xd0\x9f\xc8\x32\x10\x4e\x42\x04\xd8\x76\xfc\x9c\x7f\x63\x1d\x21\x42\x32\x24\xa1\xc8\x2c\xf5\xb3\x86\x11\x7d\xab\xca\x8f\x61\x05\x0f\x10\xe9\x05\x44\xb3\x4d\x1d\xaf\x39\xab\xba\xc2\xa4\xe1\x7d\xc8\x48\x44\xbd\x20\x20\x92\x18\x8f\xb7\xec\x9e\x27\x4b\x20\x89\x95\x79\xbb\xcb\x42\x95\x95\x80\x5f\x6e\xa2\x67\xe5\x10\x10\x80\x71\x0b\x3d\x68\x9f\x4a\x94\x56\x1c\x05\x21\x08\x00\xc1\xd0\xa0\xe6\xd0\xdb\x95\xaa\x11\x2e\xbd\x41\x94\x9f\x60\x0a\xec\xa2\xd7\xae\xe0\xc0\x06\xc6\x06\x51\x8c\x21\x07\x36\x6b\x1a\x66\x2b\xb3\x21\xf6\x42\x1f\x33\xed\x7f\x64\xc7\x3f\xd8\xb1\x3f\x8f\x62\x4f\x25\x32\xee\x2b\xf5\xef\x2e\x4c\x40\x7d\xca\x2e\x73\xd6\x34\x79\xeb\x6a\xd7\xf3\xdb\x28\xa9\x0b\x71\x48\x7d\xae\x71\x04\x4d\x56\x0d\x21\x34\x10\x87\xa9\x76\x32\x3f\x32\x5b\xd7\x6c\xaf\x16\x51\xc6\x84\x5b\x7d\xd9\x19\x46\x84\xb0\x10\x47\x89\x87\xef\x70\xf6\x45\x72\x16\x62\x12\x49\xc5\x8c\x42\x10\x9c\x1f\xcb\xea\x6d\x88\x39\x86\x98\xd0\x08\xd9\x16\xc0\x00\x79\xfb\xce\x7e\x4c\x98\x87\x38\x4f\x93\x3e\x82\x3c\x5f\x64\xcd\xed\xb1\xac\x34\xba\xb9\x1f\xd5\x8c\x89\xa0\xd0\x71\xf3\x3c\xb1\x76\xd4\x6f\xe1\x1d\x99\x09\xb4\xbb\x13\x78\xfd\x51\x10\x13\xc5\xb8\x67\x0b\x3f\x56\xf5\x23\xc6\xeb\xec\x95\x63\x21\xd1\x0b\x51\x95\xa9\xb9\xb4\xc9\x9f\x98\x2a\x2d\xdb\x6c\x00\xde\x55\xf3\x51\x56\xe3\xb8\xe9\x70\xf2\xc7\x49\x2c\x3c\xa7\xcf\xc3\x94\x1a\x04\xcf\xe3\x84\xf2\x58\x3b\xcf\x4d\x95\xc1\xfb\x74\xb9\x3c\xc4\x89\x60\x58\xbe\x77\xa9\x34\x79\x19\x6b\x9c\xb7\x30\xbd\xe6\xc4\x69\x98\xa0\x4e\xf0\x5e\x67\x28\x1a\x71\x72\x16\xbd\xed\x41\x35\x15\x26\xc6\x09\xda\x21\xbe\x56\x5b\xdc\xc0\x60\xa0\x4b\x69\x7b\x27\x04\x4c\x06\x96\x5f\x6f\xf7\x98\x5b\x88\xd3\x54\x7b\xd1\x73\x01\xc5\x71\x51\x2a\x05\x30\x18\xc4\x69\xaa\xa1\x9a\xc0\xc4\x69\x96\x55\x0f\x55\x79\x19\x4c\xf8\x38\x65\x31\x32\x7d\xeb\x82\x39\x7d\xf9\x97\xb2\xe9\x91\x3f\xbb\x9e\x42\x27\x3c\xd0\x0a\x99\x1a\x7a\xa9\xd2\x72\xfa\x97\x0a\xce\x0e\x93\x00\x31\x23\x54\x17\x1b\x57\xf0\x9e\x95\x46\x3c\xcb\xd4\xc9\xb8\x3e\x2a\x40\xf8\x81\x1d\x93\xcb\xe6\xb4\x6b\xf8\xf4\x9e\x1b\x33\xa5\x41\x2b\x76\x4b\xd8\x5d\x60\xec\xe5\xc4\x5c\x70\x46\x1c\xbf\x5a\xad\x35\xde\xb3\x09\x3e\xe3\xe9\x0f\xc9\x25\xe0\xb6\x6e\x8b\x24\x1c\x7c\x07\x83\xf1\x65\x67\x19\x0d\xdf\x80\xf0\x12\x24\x02\x39\x1c\x4e\xac\xde\x96\xf7\xcb\xb3\xed\xc7\x23\xac\xf5\x78\x2f\x1b\x18\x66\x78\x63\x19\xe9\xda\xb8\xff\x94\x59\xb1\x65\x02\x66\x85\xd4\x39\x85\x4f\x4e\x25\xe3\xd4\x14\xb3\x36\x97\x51\x11\xe7\x5d\xc5\xc5\xff\x3f\xb1\xa7\x58\xa6\x44\x50\x5b\xa9\xff\xfd\x3e\x61\x10\x83\x64\x08\x2b\x50\x9f\x68\x9d\x42\xac\x02\xc0\x3c\xf6\x2f\x2e\x72\x1d\x2b\xe2\x61\x8a\x77\x9e\x65\xc7\xf2\x8b\xb0\x75\xac\x78\x88\xe5\xc4\xa2\x3c\x5f\x58\xd1\x6e\x4e\x4f\x28\x1c\xd8\x0d\x6a\xea\xf9\x1e\xd2\x8b\x3d\xb0\xfa\x94\x49\x66\x9d\x37\x1a\xa4\x51\x20\x7a\xa3\xc2\x41\xd0\x81\x06\x2c\x35\x2c\x16\x85\xdc\x97\xbd\xcc\x9f\x5d\xee\x28\xf1\x42\x5f\x13\x58\xd7\xa7\xe9\x9c\xe6\x74\xe5\x96\x3d\x9c\x02\xd6\x54\xf2\xb2\x7c\x5b\xff\xba\xda\xed\xa6\x76\xef\xfe\x83\x52\xc2\xb4\xf0\x28\xcf\x9a\x4b\x7e\xad\x87\xce\x33\x25\x22\x42\xdd\x16\x7e\xad\xbf\x8a\xbd\x0f\xde\x1d\x8d\x7d\x8e\x53\x94\x77\x56\x14\xda\x5c\xa3\x5e\x10\x6a\xf2\x09\x24\xd3\x40\xde\x35\xbb\x0a\x50\x1a\x2b\x45\x7a\x22\xac\x7a\x2f\xe4\x25\x86\x62\x4d\x9f\x34\xf1\xec\xea\xab\xb3\x3b\xd7\x69\xfe\x73\xa0\xcc\x0f\x8d\x60\x62\x79\x19\x51\x22\x00\xe5\x89\xd4\x9c\xcb\xd9\x3b\x60\xc5\xf7\xbe\xc4\x7a\xfb\xc1\x2a\x4d\x85\x4a\x62\xde\xd7\x5b\x69\xd7\x95\xcf\x85\xdd\x87\x97\x90\xbe\x67\x69\xa3\x9f\xd9\x4f\xcd\xef\x32\xb2\x75\xa8\x0c\x74\x51\xf3\xb9\xec\xed\x14\xd3\xa7\x03\xe2\x63\x15\xc2\x43\x26\xb0\x30\xd5\xbe\x10\x05\x02\xad\x1b\x8c\xd1\x1d\x9a\xec\x0c\x87\xbc\x13\xf3\x81\xc4\xf3\x43\x94\x41\x7a\x82\x42\x2e\xca\xa2\x80\x51\xb9\x08\x24\x1e\xa7\x88\xb1\xeb\xe8\xca\xb4\x44\x31\xf2\x95\x3d\xb2\xdc\xaa\xcb\x41\xe2\x09\xbd\xc9\xea\x78\x20\x96\x89\x96\xe7\x33\x14\x12\x39\x02\x2b\x97\x8d\xb3\xe3\x3a\xf1\x7d\x0f\x0c\xca\xef\x5f\x57\x18\xb2\xd3\x40\xe2\x87\x29\x6e\xcb\x80\x80\xb3\x5a\x97\x8a\x4f\x4e\xcc\xc4\xa7\x02\x49\x6a\xb6\xeb\xd7\x97\x87\xc3\xd3\xf2\xe5\x9b\x05\x87\x41\xe2\x8b\x88\x87\x66\x7a\x69\x16\xce\xbf\x83\x1a\x86\xc4\x87\xc0\xa9\xe1\x1a\xa5\xc9\x61\x74\x38\x09\x13\x82\x66\x5a\x05\x47\x26\x47\x5e\x46\x12\x32\x8e\xfb\x4a\x01\x1f\xcb\x9f\xd9\x34\x80\x2b\x0c\xac\x63\x9f\x44\x3e\x49\xcc\x70\xd8\x3c\xcd\xf6\x5f\x01\x46\x21\x89\x88\xae\xbe\xeb\xa3\xc7\xc3\xc8\x3e\x70\x24\x23\x64\xce\x73\xbc\x68\xd5\xa2\x2c\xde\xb1\x04\x6c\x38\xbe\x12\x42\xb4\x0b\x59\xeb\xd2\x98\x4f\xeb\xab\x20\x21\x54\xcb\xe9\x1b\x54\x93\x21\x20\x9e\x7e\x71\xb1\xa4\x96\x61\xf1\xd7\xb1\x4b\x9c\xc4\x2a\x31\xcc\xa6\xc8\x66\x65\x41\x30\x9f\xec\x8d\xee\x20\x9e\x68\x50\x6a\xeb\x72\x63\xb1\xfb\xb8\x2e\xc6\xf4\xa4\x8c\x08\x27\x5d\x90\x09\x78\x04\x67\x45\x24\x54\x68\x83\xfb\x08\xcd\x13\xab\x9b\x5d\x56\x1c\x1d\xac\x28\xa1\x4a\x53\x35\xa1\xb8\xb0\x3b\x24\x09\x63\xb4\x82\xf6\xdf\xd7\xdb\xbe\x71\x93\xa4\x9e\xae\xae\x28\x2c\xe9\xfb\xbc\xbc\x1e\x4f\x6e\x56\xa5\xa1\x44\x48\xd6\xfe\x04\xaf\x79\x93\x9d\x59\x03\x3f\xca\x2a\x97\x0f\xd9\x31\x6b\x58\xee\xbc\x6d\xd3\x9d\x79\x8a\x50\xa7\x74\x38\xf1\xfa\x59\xe4\x5b\x46\x93\xf5\xb5\x59\xb0\x6a\xdc\xce\x23\x4f\x2b\x94\xad\x0d\x03\x91\x85\xc0\xb9\x3b\x66\x8a\x82\x66\xd8\x3c\x56\xac\x01\x1b\xbd\x68\xad\x93\xef\xe5\xd8\xf7\x4d\xb8\x8a\x71\x42\x89\x6b\x35\xa1\x06\x0a\x89\x08\x89\x43\xfb\x5e\x65\xd6\x18\x65\xa4\xe9\x10\x51\x22\xc2\x14\x3a\x44\xf4\xf7\xb2\xb5\x68\x6f\xc8\x14\xf1\x8f\xfb\x74\x58\x22\x94\xe6\xb5\xd7\x5e\xec\x3f\xb0\x43\xb7\x70\x27\x10\x84\x88\x68\xc8\x59\xad\xf9\x1c\x0e\xef\xc4\xde\x16\x18\xe6\x97\x42\x35\xed\xa4\xab\xfb\xcb\x7f\xf7\xb6\x20\xd2\xe8\x47\xa3\xe9\x79\xad\x8a\x76\x3c\x8c\x5e\x29\x00\xc1\x62\x55\x03\xb2\x41\xce\x82\x4f\x57\x8e\xce\x9d\x4c\x94\x4f\xb4\xb2\xc8\xa9\xfc\x40\x1a\xb4\xe1\xab\x50\x01\x25\x5e\x2f\x4b\xbe\x2a\xde\xb3\x06\xfa\x90\x7d\x48\x94\xe0\xf8\xa9\xac\xd9\x8a\x85\x08\xb6\x3a\x09\x52\x2f\xf6\x71\xb4\x18\xd1\xdb\xed\xd5\x71\xbd\x43\xea\x09\x88\x85\xf3\x53\xb5\x58\xf8\x63\x59\x21\xa8\x64\xdb\x3e\xad\xab\xb8\x87\xd4\x53\xba\xa8\x86\xe7\x4c\xbc\x7d\x2f\xdd\x5c\x48\x7d\x73\x81\xdd\x7e\xf6\x6d\x79\x08\x0e\xbb\xfd\x6c\xbb\x77\x8d\x89\x26\x4e\x44\xd5\x64\x53\x1f\x34\x7c\xc6\xd4\x4f\x34\xa3\x91\xde\xda\x8c\xd7\x54\x0f\x96\xfe\xd4\x4f\x13\x14\xc6\x42\xf7\x76\xb4\xef\xa5\x81\x47\xb0\xaa\xbf\xdd\x72\x50\x65\x6e\x76\x75\x2e\x54\x1a\x44\x91\x5d\x29\xb7\x70\x71\xbc\x96\xad\xa3\xf8\xb3\xa9\xd8\xbc\x2c\xe4\x28\xb0\x6b\x0f\x24\x14\x73\xc5\x07\xb4\x1e\x8d\x00\xd2\x8e\x29\xb8\xd3\x3c\xfc\x22\x9e\x90\x06\x22\x4d\xfd\x9e\x15\xb2\x2d\xf3\xfc\x99\x49\xf7\xf2\x02\xa9\x64\x62\x55\x2d\x98\x2e\xbd\x63\xba\xca\x43\x1b\x8a\xfd\xb1\x9e\x86\x3e\xc4\xdc\x96\xd8\x6a\x15\xe5\x4e\x66\x65\x38\x6c\xd3\x50\x7a\xa0\x31\xdb\x7a\x1d\xd4\x3c\x9e\xe3\xa7\x8c\x88\x16\x08\x67\xb8\xf1\xf6\x8b\x70\xa6\xa8\x95\x3e\x89\xe1\x0c\x4f\x49\xa2\x04\x89\xaf\x9e\x18\x87\x7c\x57\xe6\xa3\xd8\x53\x4a\x62\xaa\x3d\xbd\x4a\x04\x1e\xc2\x58\xde\x27\x6a\xc1\x27\x77\xee\x94\xa4\x21\xe2\x71\x2c\xd3\x75\x99\x0f\x8d\xcd\x94\x28\x8d\xb9\xad\xb5\x9c\x9d\x11\x83\x1a\x9e\x24\x0e\x78\x68\xd8\x83\xdb\x6d\xba\x0f\xba\xd8\xb4\x8f\xef\xdb\x93\xc5\x91\x87\x2e\x0b\x77\x52\xca\x23\x7d\x5d\x48\x63\xa2\xcb\xab\x2a\x78\x87\xaa\x71\x20\x57\x4b\x2f\x66\x7b\xb1\x00\x83\x15\xc7\x0e\x16\x92\x52\xa2\x85\xc9\x5f\x76\x9b\xfe\x5e\x91\xd2\x58\x87\x17\x9a\x12\x4b\x84\x86\x03\x80\x26\x44\x9b\xa1\x38\x64\x17\xd7\xaa\x2e\xab\x43\x37\xd7\x13\x02\x3d\xb1\xf3\xae\xc6\x76\x5c\xda\x3b\x5c\x70\xd3\x84\x6a\x72\xbe\xa6\x02\x70\xf2\xa5\x90\xa6\xd4\x0f\x7c\x97\x00\x52\xd9\x71\xc0\x9d\x6b\x3a\x31\x9a\xd8\x38\x4c\x3b\x41\x0c\xed\x77\x29\xb2\x41\x55\xca\xe8\x82\x2c\xd1\x01\x19\x76\xac\x60\x64\x26\xa7\x0c\xe4\x00\x9b\xb4\xbf\x07\x51\xa6\x3c\xd6\xf9\x4c\x1d\x68\x59\x77\x89\xe2\xc1\xb0\xe9\x97\xde\xf5\x7f\xb7\xf1\x9a\x54\x80\x66\x1f\x9b\x57\x2c\x2b\x9e\xe0\x98\x35\x3d\xdc\x52\x2a\x0d\x55\x8d\xde\xfb\xfe\x82\xae\x00\x52\x19\x6a\xd0\xae\x16\xa7\xce\xcb\x52\x7e\x59\x1b\x34\x3a\x1a\x08\x47\x5d\xff\xd9\x76\x35\x79\x98\xed\xc6\x74\xf5\xf0\x66\xbb\xd4\x68\x87\x7e\x32\x2f\x05\xae\xb9\x0b\x3f\xb2\x02\xd1\x12\x77\x42\x18\xb6\x9f\x70\x52\x3a\xdf\x59\x7d\x1a\x67\xa2\x99\x17\x0a\x9c\xc1\x86\x57\xe0\x15\x75\x24\x06\xc9\x41\xe6\xc5\x11\x37\x35\x14\x08\x54\x32\x72\xf8\xd7\x3e\x95\xa9\xed\xca\x35\x03\x35\x93\x72\x0f\xec\x3c\x84\x56\x7f\x69\x54\x33\x4f\x78\xe8\x6e\xb0\xa2\x28\xaf\x85\x40\x30\xe4\x4b\xe7\xae\x30\xdf\xe4\xef\x71\x3d\x94\x00\x28\x96\xb3\x85\xcb\x55\xd7\x44\x61\x1e\xaa\x9a\x0e\x9a\x31\x9f\x6b\xb1\x25\x93\xde\x84\xa2\xb1\x7a\x9c\xc3\x7b\x08\x7c\x0f\xed\x63\xac\xc3\x9e\xb2\x6e\x58\x10\x7a\x1a\xcb\x83\x22\x38\xab\xc5\x3a\xdc\x43\xdd\x7c\x87\xfc\x32\x55\xdd\x6e\x0f\xa2\x9e\x6f\x9c\x19\xc3\xa8\x5e\x0f\xe2\xe8\xa3\x37\x11\x24\x1c\x0b\x6a\x4c\x38\x4a\xe7\x2d\x27\xb5\x8d\x3f\x79\x95\xa1\xa7\x15\x6a\x90\xc1\xee\x0d\xce\x65\xd1\x79\xbc\x5d\xaf\xc8\xa3\x98\x7a\x33\x8a\x73\x5a\x50\x0f\xaa\x65\x73\x1a\x77\x4c\x3c\xac\x9c\x43\x2e\x9a\x76\x6a\x3e\xe6\xe5\xc7\x27\xd5\x5b\xc0\x08\xe1\xbc\xab\x90\x7e\x04\x98\x82\x5e\x31\x42\xb5\x88\x3f\x6a\xbd\xad\xfe\x02\xfe\xcb\x48\xe2\xfb\x26\xe4\xf8\x04\xcd\xc9\x08\xde\xcf\x9a\xef\xd9\x78\x2b\x67\x31\x4d\x68\xec\xc4\x2d\x7a\xac\xdc\xbd\x2e\x29\xc1\xd2\x52\xf3\xe0\x59\x0e\x68\x2c\x76\x45\x24\x63\xb3\x90\x51\x5f\x84\xd4\x4a\xd3\xd4\xc8\x11\x0b\x72\x0b\xe8\xb9\x16\x47\x8b\xa8\xdc\x21\x12\xc4\xcd\x2c\x1a\x26\x69\x3b\xcd\x4f\x59\x3b\xda\xda\xe5\x6d\x18\x74\xf0\xdd\xd9\xe3\x08\xe9\xe4\xeb\x2b\x47\x21\xb4\x01\x55\x0f\x30\x4a\x63\xd1\x13\x13\xb2\xb6\x5d\x47\x8d\x05\x2c\x09\xa8\x17\x3b\x48\xea\x16\x58\x8e\x3e\x85\xce\x10\xfc\xe3\xda\x13\x9d\x02\xd6\x7a\x0c\x5d\x52\xe3\x71\xaa\x90\x75\x68\xdd\xd8\xff\x3a\x1e\x8a\x51\xe5\x3a\xb0\x34\xd2\x11\x46\x74\x9f\x5a\x7b\x74\x7e\xfb\x05\x0c\xb8\xc8\x5e\x36\x4d\x24\x42\xf9\xb2\xa2\xb5\x63\x7a\xb1\x84\xae\x3e\xd1\xcd\x17\x16\x69\x8c\x46\x56\x3f\xb1\x9e\xf8\x57\x27\x02\x3c\xb8\x3a\xf7\x00\x85\x94\x1f\xb3\x42\xd3\x95\x7e\x9a\x87\xb2\x07\x10\x9d\x4e\xb0\x94\x10\x3d\xa4\x03\xe3\x24\x20\xe1\x00\x2f\xe0\x5a\x80\xc3\x80\x34\x01\xaa\x7b\x48\x2a\x13\xc2\x47\xb4\x71\xe3\xc4\x34\x6f\x5d\xf1\xf3\xdf\x8b\xf3\x32\xe9\x6b\xb4\xa6\x31\x92\xb5\xce\xf2\xc0\x46\x66\xd2\xe7\x48\x43\x90\x97\xcc\xee\x97\x23\xbd\x2e\x60\x92\x06\x5d\x62\xea\x3e\xa0\xc6\xa4\xa4\x88\x86\xaf\x34\xa9\x77\x01\xb7\x87\xf2\xa3\x78\xc9\x04\xe4\xb7\xe5\x7e\xd4\x19\x82\x88\x18\xaf\x6e\x67\x30\xf0\x26\x9b\xf2\xcf\xbf\xff\xcf\xe8\x94\x31\xd1\xe0\x4e\x56\xe5\x37\x63\x98\x75\x02\x4b\xc0\x40\xb8\xaa\x62\x43\xa0\xdb\xce\xe8\x5e\x42\x9c\x81\xd0\x25\x71\xed\x12\xfc\xf7\x64\x88\x80\x29\x9f\x32\x6b\xe8\xb0\xea\x1d\x5e\x2f\x83\xec\x06\xf7\x88\xc2\xc1\x81\xb4\x32\xb6\x7a\xd9\xb6\x31\x4d\x78\x6c\xa3\x21\x7f\xf5\x3d\xbf\x5e\xa6\xb9\x9f\x78\x98\x0c\x6e\x07\x61\x93\xa9\x0c\xaa\x7d\x39\x91\x4e\xe1\x81\xc7\x98\x19\x79\x1b\x1d\xa0\xd8\x57\x9a\xd4\xdc\x0d\x40\x6b\xe6\xf0\x30\x50\x92\x77\x59\xd5\xec\x4f\x18\x12\x68\x02\x0f\x63\x4f\x74\x88\x87\x2d\xbb\xd6\x5a\x44\xa6\x77\x8b\xfe\x40\x4f\xdd\x0e\x3a\x1e\x45\x34\x89\x7a\x1f\xa4\x7e\x2c\xab\x01\x69\x29\xf0\x88\xe8\x85\xe8\x08\xcd\xc1\xfa\xa8\x07\x56\xd7\xd0\x1c\xa4\xa9\x0d\x3a\xa8\xaa\x3c\xbb\xff\x37\x46\x20\xda\xf3\x48\x5d\x2a\x57\xbe\xb1\x73\x86\xce\x94\xf5\x57\x0e\xf6\x52\xc4\xe7\xf8\xf1\xbf\x95\xa5\xcc\xaf\xe2\xad\xa3\x79\x05\x4e\x52\xe8\xb1\x74\xb4\xa6\xf3\x72\xff\xbd\x29\x5f\x77\x0f\xa3\x57\x1b\x8b\x34\xd4\x2c\xcc\xba\x38\x79\xb0\xd9\x73\x1a\xa4\x68\x0e\xd8\xc9\xec\xc8\xe4\xbf\x10\x54\x04\x4e\xa5\x4f\xfb\x7e\xfc\x46\x63\x0b\x47\xc0\x00\xd3\x39\xf1\x39\x66\x56\xae\x85\xd6\xc0\xb4\x4b\x8b\x1b\x73\x49\x1c\x1b\x12\x5f\xdc\xf3\x7a\x1b\x03\x4f\x04\x57\x66\x4e\x1e\x5a\x3f\xf2\x3d\x6b\x6e\x07\x39\x64\xe8\x1b\xc4\x4f\x78\x2a\xe2\x44\xeb\x5b\xc3\x05\x4f\x77\xbf\x2c\xf0\x54\x4a\x8b\xef\x99\x43\x53\x6f\x34\x83\x83\x0b\x7c\x71\xe6\xf9\x48\x47\xf2\xf0\x7b\xaf\x6c\x94\x33\xc5\x64\x2f\x82\x36\xc3\x7c\xf6\x04\xc8\x8a\x73\x3f\x18\x44\x39\x70\xd5\xb6\x67\xe1\x44\x86\xa2\x93\x04\x5d\x54\x2c\x3b\x6a\x1b\xd2\x76\x50\x41\xe8\x3b\xac\xb5\xc6\xe6\x65\x7f\x82\x63\xcb\x01\x2e\x12\x81\xbb\x6e\x56\xbf\x00\xc8\xa7\x92\xb9\x41\x21\x98\x66\xab\xc0\x65\xb5\xf5\xa6\xb7\x20\xaa\x6b\x36\xa5\xee\x3f\x34\x69\x38\xf8\x21\x26\x86\x96\x2f\x0f\xc3\x8a\x6d\xe0\x10\x49\x0c\xa2\x5f\x1c\x21\xf8\xbf\xae\xac\x6a\xba\x42\x5b\xae\x62\x89\x4c\xd4\x9d\x14\x8b\x6e\x10\x1e\xd1\x54\x1e\xf3\xd5\xcb\xb7\xaf\xb2\xe7\xc2\x0f\x84\xc1\x29\xe4\x79\xbd\x2a\x8e\x55\xeb\x78\x95\xd7\xe6\x01\x2e\x39\x4c\x6a\x2b\x0e\x0e\x0f\x68\xc0\xa3\x81\x66\xeb\x86\x8d\x38\x29\x41\x84\x81\x8c\x48\x3f\x32\xfc\x23\x2b\xda\x91\x6e\xb9\x86\xb4\x0d\xd0\x5f\x0e\x44\x48\x42\xac\x4e\xad\xcc\xba\x5c\xc8\xf2\x6c\x9f\x2d\x64\x29\x46\x1d\xb5\x90\x45\x3b\x68\x31\x37\x35\xae\xdf\xfb\x34\x68\xd6\x5f\x14\xfa\x31\x16\x11\x79\x52\x23\x6b\x4f\xd0\x8e\x2f\x39\x60\x88\x03\x41\x58\x92\xea\x40\xc8\x47\x2f\xf7\xd3\x8e\x7a\x84\x9e\x23\xfb\xc9\x0e\x8a\x3b\x35\xe8\x7b\x3c\x9d\xa0\x51\x82\x09\xfe\x6f\xd9\x3b\x68\xfa\x48\xdb\x10\x7b\x98\x7a\x39\xd4\x60\xf6\xcd\xe9\x85\x40\xd0\x24\xc1\xd9\xe6\x02\x51\xee\x0c\xad\xc3\xdd\xa9\xa7\x19\x72\x13\xd7\x0a\x3a\x18\x5d\xac\xed\x28\x13\x09\xf7\xb0\x7e\xb6\x2e\x3b\x1a\x4f\x77\xa3\x09\x00\xc2\x11\xb5\x6b\x71\xbe\xd8\xd9\x24\xd2\x40\x5a\x16\x42\x6d\x9a\x62\xc4\xc3\x09\x67\x81\x60\x5e\x62\x2a\xf7\x77\xd7\x0b\x54\xef\x59\x6d\xf9\x91\x41\xb0\x58\x63\xf9\xdd\x3c\x1d\x71\x64\x40\xbb\xf8\x44\xba\x9e\xf3\x9c\x15\x5b\xa8\xc5\x15\x7a\x52\x66\xed\xde\x1c\xa7\xbe\xa3\x83\xb4\x42\x0c\xdd\xeb\x01\x5f\x62\xad\xcc\x0f\xc8\xf6\x65\x87\xe4\xe8\x3a\x28\x3f\x40\xd7\xf4\xfb\x72\xb6\xfd\x4a\x8b\x05\x84\x4a\x3d\x6b\x9f\x6b\x8b\x1f\x21\x42\xa5\x5b\x45\xa5\x4f\x42\x14\xa9\x38\xe3\xc4\x1f\x3e\x88\xf4\x21\xc2\x17\x5e\x63\xd8\x1f\x03\xf1\x3d\xa1\x04\x90\x41\xac\xa0\xaf\x25\xb0\x2a\xda\x8d\xa4\x7f\x03\x32\xe4\xb1\x55\x2c\xda\x57\xd7\xba\x19\x6d\xba\x32\x04\xa9\x1c\x9f\x88\x8e\xf9\x39\x1d\x57\x90\x51\x24\xf0\x4d\x19\xe1\x95\xdd\x25\x1f\xb1\x85\x83\x8c\xa8\x4e\x55\x31\x24\x55\x0b\xdc\x91\xa9\x87\xf5\x56\x56\xff\x60\x25\xca\x0d\xab\x1a\xdf\xb5\x33\x19\x59\x73\x96\x69\x7f\xd3\x65\x44\x24\x09\x95\x2b\x0f\x19\x4a\xe5\xda\x0e\x34\x8c\x3d\x0b\xff\xc9\x8a\xd6\xd7\x99\x80\x35\x48\x92\x08\x6a\xb8\xc6\x5a\x83\xba\x8f\x53\xfd\x2a\x5e\x2a\x89\x48\x90\xbf\x1e\x11\xef\xfd\x88\x83\xa4\x11\xc3\xda\x06\xc3\x00\x93\x97\x05\x4c\x56\xcc\x0c\xbe\x01\xa5\x7a\xc4\xae\x4d\x8e\x71\x53\x65\x7f\x22\x73\xe7\xe8\x73\xd3\x24\xc0\xf0\xcb\xb7\xe5\xcb\xd2\x4d\x31\x49\x93\x08\x91\x5a\xe8\x38\x35\xef\x3d\x6b\x42\xd2\x44\x7f\xbc\xcd\x76\x89\x85\xfd\xa6\xc6\x7f\xfd\xb8\xef\x44\xab\x40\xd2\x34\x41\x77\x7a\x51\x39\x6b\xd4\xb4\x24\x3e\xc7\x09\x2a\xc1\x16\x88\x6e\xaa\x52\x5e\xc7\xea\x2e\x20\xd3\x30\xf4\x3b\x32\xe8\x71\x63\x9a\x92\x4e\xaf\x78\x5e\x4c\xf1\xea\x99\xae\x8c\x4a\x7c\x7d\x59\xdd\x2f\x66\x9b\x4c\xc0\x48\x41\x79\x14\x39\x19\xd3\x1d\xc2\xd0\xfe\xae\x84\xea\x70\x18\x08\xd0\x69\x7c\xe3\x56\x33\xbe\x1d\xe9\x79\x83\x94\x3e\x47\x5c\x4f\x6b\xb0\x2f\xdf\xcf\xbb\x1e\xe8\x4d\x4a\x11\xe1\x72\xa2\x75\x4c\x0d\x63\xa6\x8b\xc1\x76\xc9\x7e\x29\x15\xc7\xb9\x26\x21\x67\xb7\xc3\xa5\x2c\xf3\x83\x7e\x27\x87\x7b\xb2\x65\x90\x40\x19\x2e\x0d\xc8\x30\xe9\xec\x91\x7b\x86\x4d\x90\xed\x78\xd7\xc2\xbf\x37\xce\xc4\x1b\x26\x7e\x5c\x93\x42\x07\xf7\x23\x93\xce\xd2\x90\x2a\x20\xb1\x85\x73\x9d\xb2\xcb\x84\xe5\x2e\x55\x14\xa0\xaa\xab\x91\x0a\xd6\x6b\xd3\x28\x27\x82\x94\x2d\xd4\x01\x98\x91\x21\x07\x33\x33\x77\xdd\x34\x05\x15\x43\x2f\xd8\x29\x6d\xae\x95\x45\x2d\x0d\xba\x83\x17\x12\x1c\x74\x79\x59\xbe\x5d\x2f\x0b\x56\x94\x45\x26\x58\xfe\x58\x56\x67\xd6\x27\x67\x06\xf0\xa2\x18\x11\x0d\xae\x3a\x13\xd8\xb9\xbf\x90\x83\x17\x53\x62\xe9\x23\xff\x7b\x65\x15\x74\x8f\x9a\x4c\xa3\x6c\xc1\x4b\x43\x44\xd9\xfe\xa7\xcc\x0a\x43\x2e\x36\xec\xd0\x9a\xbd\x58\x01\x7d\x2a\x57\x75\x8f\x11\x1d\x20\x08\x54\xca\x6c\x89\xe4\xf9\xd2\xc0\x21\x0c\x06\x8b\x2d\x04\x29\x60\x1e\xc3\x0e\xb4\xca\x3a\x24\x83\x7d\x78\x14\x65\x81\x90\xf8\x36\x39\xd4\x3e\xe1\x48\xb8\x7b\xf0\xdd\x20\x4c\x13\x2b\xac\xbf\xcf\x8c\x04\xf4\xac\x90\x46\x40\x7b\xb4\x4c\x42\x94\x68\x0e\x0b\x27\x59\x00\x55\x01\xd7\x09\x5e\x50\x00\x12\x11\x5f\x5a\xb2\x99\x75\x01\x0f\x9a\x2d\xc8\x3e\x3b\x21\x84\x18\xac\xfe\xb7\xf2\x7d\x6f\x57\x6c\xd3\x1a\x7b\x3e\xee\xe7\x96\x55\x4d\x0b\xf4\x4e\x3f\x41\xec\x8b\xd4\x4a\xb5\xe0\xda\x9e\x15\xc7\x5f\xcb\x06\x34\x33\xac\xbd\x5e\x4c\x53\xe8\xc9\xb8\xfe\xb8\x63\x48\xb5\xfd\x18\x45\xa2\xcc\xb2\xc8\xb3\x02\x7a\x3e\x08\xc4\xc2\x03\x07\x01\x09\x0e\x75\x79\x06\xc4\xc6\xdb\x66\xa5\xd0\x17\x42\xaa\x41\xa6\xe0\xf9\x3a\x4d\xbe\x0a\x40\x7d\x1d\xb3\x7c\x2a\x8f\x9b\x32\xcf\xc4\xed\x01\x44\x7b\x31\x39\x5d\xfe\x06\x54\x71\xa9\xc1\xbe\x4d\xc5\x3e\x25\xd2\x06\x48\x42\xcd\x9e\x89\xe5\x50\x07\x38\x5f\xb2\x0a\x0e\xb5\xe8\x4a\xc9\x20\x21\x3a\xce\x90\xd5\x46\xba\x4d\x47\x1b\xb4\xd4\xca\xe8\x64\x4a\xcb\x45\xdd\x80\x55\x03\xf4\x26\xa4\x11\x21\x71\x3f\x14\x51\x3f\x63\x36\x7d\xcc\xd6\x05\x90\x8a\x84\x6b\x4b\x1b\x1a\xf6\x37\x6a\x40\x21\x95\x92\x68\x59\xd7\x6b\xde\x1c\xea\xa6\x0b\x80\x60\x68\x56\xa1\xe9\xd7\xb0\xdc\x64\x09\xeb\x81\x0f\x0b\x2c\x62\x21\xeb\x84\x25\x03\xf7\x7b\x4c\xf1\xd3\x23\x12\x1d\xaa\xb7\xc1\x48\x63\x8c\x62\xb2\x1c\x7e\x66\xae\x5e\xdc\x1e\xc8\x43\x8d\xcc\x69\x8d\xfe\x52\x29\xf7\x73\x94\x5a\xc9\xf9\xa7\x52\xbc\x5d\x2f\x87\x3a\x3b\xdf\x0f\xcf\xd1\xd7\xe1\x44\xa3\x68\x75\xe1\x5d\x7f\x2a\xf0\x58\xf8\xc6\x7a\x44\xcc\xea\x02\x25\xdd\x2b\xf6\x91\x15\xc7\xfa\x4b\x77\x0d\x38\x4d\x31\x5f\xc1\xaf\x59\x2e\x5f\xab\x7b\x10\xf8\xf0\x1e\x44\x10\x98\xca\x4c\xac\x5a\x45\x13\x6f\x48\x61\x05\x20\x22\x8e\x40\x68\x9d\x8b\x43\x79\x80\xa1\x85\x07\x22\x86\xc4\x59\xe1\x4f\xe5\x31\x13\x5f\x23\x57\x40\x26\x21\x0a\x55\x16\xf0\xa3\x7b\xb9\x40\x68\xa2\x15\x23\x75\x6d\xc3\xc1\x77\x2d\x89\x17\xf9\x36\xa6\x9f\x15\x4d\xeb\xf6\xda\x14\xcc\xe0\x71\x20\x21\x48\xef\xc6\xcb\xf2\x6d\xc9\xaa\x02\x81\x67\xd3\x8b\x04\x30\x5d\x77\xb5\x99\xad\x7b\xc9\x30\x00\x45\x7c\x0f\x21\x7e\x72\x71\xad\x9b\xf2\x3c\xc5\x75\x79\xbf\xe6\xab\x58\x21\x07\x35\x93\xd2\x0a\xd2\x8d\xdf\xc0\x70\x0a\x2b\x29\xf1\x61\x01\xab\xb9\x26\x0b\xa5\x40\x49\x40\xce\x16\xa4\x5a\xfe\xe5\x65\xfd\xc3\xdc\xa4\xf2\x62\x12\x0a\xe7\x5d\x44\xe8\xda\xf4\xda\xd0\x12\x51\x0f\xd9\xfb\xf4\xb2\xa0\xfc\xc0\x43\xdb\xb3\x35\x0b\xa6\x93\xea\xca\x0f\x09\x4e\x76\x09\x82\xdd\x40\x7e\x12\x66\x55\xbe\xe2\x02\xe5\xa2\xaf\xb2\x3e\x95\x4d\x5f\x7e\x1c\x54\x40\x53\x2c\x14\xe9\x53\xde\xff\xdb\x8f\xff\x6f\x74\xa9\x80\xea\x70\x2e\x6a\xb2\x48\x4b\xeb\x0d\x2a\x24\x9a\x80\xa1\x86\xc6\x70\x6f\x3e\x02\x58\x8c\xfe\xf0\x14\x61\xcc\xf1\x4a\xff\xbd\xc2\x75\xc0\x98\xa5\x22\x2f\x08\x0d\xec\xa0\xb5\x6a\xeb\xf6\x91\x07\x4a\xb5\xa0\x22\xc2\x74\x58\xa5\x3c\xb7\x3e\x1c\x7e\xed\xc0\x1d\x1f\xa7\x1a\x52\x76\x85\xba\x7e\xcc\xb3\x8b\x6b\x48\x98\x0d\xc6\xcc\x5d\xd6\xbc\x5d\x8a\x31\x4b\xd8\x9a\x6e\x23\x7b\x48\x91\x20\xb4\xb5\x68\xf3\x5b\x03\x38\x86\xa7\x5f\x3e\x09\x23\xcf\xeb\x28\x25\x33\x81\x24\x21\x78\x80\xe9\x11\x87\x90\xd2\xce\x5c\xb3\x02\xe6\xc3\x8f\x13\x73\x85\xe2\xc1\x08\x66\xc7\xba\xf1\xa6\x3c\x88\xe1\xd4\x55\xb1\x60\x9e\x2e\x02\x56\x4d\x18\x8e\x6e\x99\xb2\x28\xee\x83\xc0\xdb\xe7\x7b\x2c\x2b\x47\x31\x07\x8a\x02\x45\x6b\x7b\xac\x58\x34\x41\x68\xa0\x92\x84\x62\x2a\xed\xcc\xde\x60\xd5\x6c\x7b\xc4\x37\xf7\x11\x08\x95\xfa\xb1\x25\x16\x58\x57\xd9\x31\x2b\x58\xae\x45\x2d\xed\x95\x53\x42\x30\x68\xb3\x38\x01\x54\xf5\x0f\x56\x0c\x6a\x45\x54\x1a\x13\x1c\x12\x5b\x60\xf9\x12\xf7\x8d\x61\x33\x8d\x38\xb7\xa1\x94\x6f\x79\xc9\x59\x3e\x4c\xbd\x2b\x64\x45\xb4\x5e\xab\x28\x25\x54\xb8\xd1\xe8\x92\xbf\xe1\x8b\x66\x94\xc6\x0e\x9d\xfb\x68\x69\x64\x3e\x59\x78\xdd\x13\x72\xa6\x67\x77\x6b\x6e\xfe\x15\xd4\xc6\x1e\x22\x34\x2b\xe9\x66\xb5\x58\x6f\x76\xa6\xa2\x11\x2a\x5d\xc6\x74\x17\xd7\x31\x07\x09\xcf\x4f\xdb\xd1\xf4\xfb\x7a\xbb\xda\x2f\x7f\xb3\xcf\x27\x12\x1f\x97\x4a\x04\x87\xb0\xfc\x80\x37\x7f\xa8\xc1\x92\x19\x83\x12\x69\x84\x20\x8b\xb7\x9b\xe8\x09\x3c\x80\x92\xbe\x51\x78\x6f\x2d\xc3\x17\xf8\xd9\x2c\x2b\x76\x18\x3a\x3b\x0a\xe2\x08\x51\xa2\x5b\x28\x2c\xff\x87\x02\x29\x2c\x44\xe8\xf9\x36\x13\xe2\x3a\xd8\xac\x15\x80\xc2\x02\x01\x0e\xcd\xec\xc8\xb2\xa2\xc6\x42\xbd\x4f\x96\x30\xc5\x63\xbc\x37\x4c\x77\x99\xac\xe0\xd7\x65\x9d\xfd\x97\xa2\x3c\x2f\x08\x91\x49\xee\x9c\x15\x7d\x58\xcc\x60\xc4\x2a\xcf\x23\x7a\x5f\xd7\x6e\xc7\x3f\x46\xa7\x10\x5a\x45\x88\x37\x37\x51\x5f\xf9\xf9\xd3\x60\x98\xf2\x02\x4f\xa2\x1d\x02\xff\xbd\xb2\xbc\x7e\x29\x17\x3d\xd9\xa0\xde\x5a\xa4\xbc\x20\x50\x18\xd2\x58\x3d\x3f\x2c\x7f\xab\x41\xd3\xf6\x75\x35\xef\x16\x4e\xa7\xbc\x90\xfa\x58\xa1\xa6\xe7\xdd\x47\x3b\x7b\xcb\x77\xa8\xa0\xcb\x5f\x8f\x1e\x38\x14\x21\xf2\x2c\x9e\x32\xa1\xd7\xaa\x5e\x91\x91\xf2\x42\x99\x60\xb1\xea\xe2\xdb\xbe\x37\x4d\x94\x17\x51\x85\x1b\x8d\xba\x22\x5a\xf9\x3f\x20\x06\x40\x2d\xe5\x45\x09\xc5\xfa\x9a\x5f\x57\x4f\x4f\xb3\x6f\xcb\xc3\xea\x65\xb1\x5d\xce\x76\xcb\x1e\x31\x85\xf2\xa2\x34\xc5\xf9\xc1\xb3\xbb\x62\x68\xd3\x83\x04\xca\xa2\xe7\x9e\xb3\xc2\x62\xbe\x3a\x45\xf5\x7e\x81\x60\xcf\x60\x1c\x9d\x24\xe2\xc8\xbb\xb0\xbb\xd6\xa7\xac\xdb\xd3\x95\x47\x58\x68\x9d\x55\xc7\x89\xdb\xee\x93\x9e\x36\xa2\x1d\xbf\xca\xeb\xee\xc1\x35\x32\x82\x6b\xe7\xaf\x19\x7c\xcc\xef\x11\x8e\xae\x97\x11\xb0\x2a\xf3\x9c\x35\x50\x61\xce\x69\x34\x86\x12\x13\xc8\x73\x02\x27\x2b\xf5\x02\xad\x57\x3d\xee\x17\x71\xad\xaf\x3a\x7b\xde\xd9\xbb\x48\x58\x8c\xb0\x90\x8f\xb2\x7a\x73\xb5\x39\xca\x4b\x94\xc0\x4d\xad\xbe\x72\xb3\x74\xb9\x14\xbe\x5d\xc4\x86\xe7\x4e\x09\x60\xb0\x8b\xd5\x52\xd9\x93\x30\xdf\x07\xc3\xd6\x89\x0f\x7f\xf8\xc8\xdc\x70\xe0\x3e\x45\xdc\x8c\x2a\xab\x8f\xd6\x10\xeb\x45\xee\xbe\x28\x2a\x54\x1e\xa7\x5a\x60\xe6\xb1\x2c\x87\xc3\x84\x83\x1f\x99\x30\xfc\xb7\x0a\xe0\xad\xd6\x45\x0a\x5a\x81\x70\x7e\x1b\xcd\x2c\x49\x54\xd0\xa3\x49\x9b\xe5\xf9\xb8\x03\x44\xa9\xd7\x0f\xd8\xdb\x48\xfd\xe0\xa9\xc1\x4f\x93\xf8\x2f\x79\xcb\x4d\xf6\x50\x79\x10\xfa\x9e\x89\xa3\x62\x41\x00\xa2\x33\x06\xcb\x9a\xf2\x80\xa4\x18\x7e\x99\xcd\x17\x0f\x83\x89\x02\x54\x46\x5d\x09\xcc\xcd\xa0\x8d\x6b\xd7\x0c\xda\xe3\xff\x66\xa9\x55\x5a\xbb\x6d\x71\x13\xb9\x7b\xe5\x8a\x26\xc2\xc4\x11\x55\xd6\x1a\x52\x8d\xcd\x0c\x29\xdf\x63\x29\x3e\xee\xb5\x86\x6a\xd9\x2e\x56\x30\xb4\x14\x95\xef\xd3\xd0\xa7\x1d\x6f\xc3\x33\x2b\x6e\x86\xb6\xc1\xed\x3a\xff\xfc\x0c\x72\xa0\x7c\x3f\x21\x61\xec\xf2\xa6\xae\xc0\x4c\xf9\x3e\x68\x56\x87\xba\x53\x3a\xe9\x6c\xaf\xe1\xec\xf3\x83\x38\x48\xfc\x5e\x91\x73\x85\x35\xed\x23\x22\xb1\x64\x92\xb7\x43\xf9\x81\x92\x80\x21\xea\x52\x66\xea\x36\xff\x84\xe2\x4f\xf9\xa1\x17\xe3\x64\xda\x84\x0f\x06\x50\x69\x6f\x35\x0c\x62\x8c\x52\x8d\xa9\x81\x0f\x3f\x96\xab\x9d\xeb\x24\x22\xa1\xa3\x4d\x0c\x73\x12\x9b\xaa\xbc\xb4\x9b\x28\xd4\x93\x8e\xb6\xf2\x23\x2a\xd0\xf1\x68\xdc\x8a\xb9\x2a\x16\x2e\x5d\xa1\x7c\x02\x34\x30\xd1\xa1\x23\x3b\x83\x60\x95\x2c\x7a\xd5\x57\x83\xc5\xdd\x8f\x7d\x19\x6a\x1e\x93\x1a\xee\x60\x1a\xb6\x0f\x09\x51\x40\x40\x63\x8c\x6d\xd0\x75\xb9\xff\xde\x57\x3f\x55\x7e\x1c\xeb\xe4\x3f\xe6\x74\xee\x8c\xf3\xbb\x0f\x1c\x73\x2a\x3d\xa7\x81\x52\xf5\xa7\xc1\x34\x05\xbd\xf2\x63\x19\x63\x34\x46\x65\xaa\x39\x21\x40\xb3\x5b\x3a\x7d\x1a\x69\x8e\xb6\xd9\x6a\xfb\xb0\x5d\x6f\x0e\xbb\xef\xb3\xad\x5d\xed\xfd\xc4\xd3\xf7\x26\x2c\x0d\x99\x09\x67\xe2\xfa\x34\x1e\xb8\x89\xcf\x89\x23\x6e\xe8\x59\xee\xca\x4f\x22\x29\x35\x74\xf2\x58\xc1\x91\x35\x30\x3c\x7e\x74\xbb\x49\x0c\xd2\xb2\xad\x5c\x58\xdf\x18\xee\xed\x9a\x7e\x1a\xa4\x16\x56\xfc\xad\x2a\xaf\x17\xb4\xae\xeb\xa6\x13\x75\x32\xfd\x18\x8b\xbc\x8e\x06\x7a\x96\xe7\xb6\x2c\xc0\x00\xc5\x1c\x43\xcd\xf0\x26\x18\x68\x92\xec\xc7\xdd\x6c\xb0\x8d\xfa\x0c\x62\xf4\xa0\x71\x70\xce\xb6\xbb\xc3\x7e\x7d\xf8\xb6\x7a\xdc\xdb\x76\x1e\x72\xcc\xce\x8e\xc6\xb4\x90\x5a\x49\xcb\xd6\xba\x22\xab\xa0\x95\x9d\x1c\xa7\x07\x95\x0f\x8c\x45\x26\x81\xdc\x2f\x5d\xfd\x91\x35\xa7\x07\x10\x1d\x90\xe6\x7e\x5a\x29\x8f\x6a\x56\xf4\x1f\xb3\xe7\xc1\x8d\xab\x20\x4c\x2c\x5d\x3a\x88\xb7\xfa\x7a\xc6\x7b\x19\xae\x8a\xbe\x0a\xa4\x2e\xb2\xb4\xb2\x64\x48\x7c\x52\x3d\x7e\x42\x22\xa7\x02\x2f\x0c\x08\xe9\x95\x49\x8c\xe2\xbd\x2a\xf0\x9c\x48\x4b\x21\x57\x45\xeb\xf1\x65\xef\x59\xcd\xa6\x36\x20\x73\x84\x0f\x52\xc5\x16\x25\xf7\x0e\xf9\x66\xb6\xfe\x5b\x15\x67\x2a\x08\x42\x1f\xab\x61\xb1\x3c\xcb\x25\xd3\x55\x10\x30\x65\xa5\xff\x83\xdf\x3f\xb9\x6a\x18\x0a\x04\xdc\xed\x20\xbb\x5d\xaf\xf6\xc8\x90\xf2\x48\x3b\xcf\xac\x39\x3d\xb0\x86\x1d\xde\x53\xdb\x16\x05\x1c\x43\x72\x2f\xaf\xfb\x5d\x97\x67\x51\x41\x44\x52\x2c\x2e\xc0\x50\xdd\x43\x56\xe3\x94\x01\xb9\x6a\xe0\xec\xa8\x44\x4d\x57\x4a\x24\xfa\x51\x1a\xee\x3e\xed\x9a\xab\x80\xc6\xa1\x34\x6a\xf0\x0e\xee\xde\x5f\x8e\x82\x44\x51\xf4\xdd\x9b\x72\xd7\xb1\x5d\xbb\x36\x5d\x86\x30\x62\x7f\x03\x69\x4c\xb2\x05\xbb\x0c\x99\x3d\x46\xef\x25\x8d\x79\x1c\xd8\xe4\x19\x22\xc4\xf5\x86\x36\xbc\xc5\x14\x7c\x84\x23\x35\x27\x93\xac\x99\x44\x41\xab\x80\xf9\x11\xf2\x1a\x41\x25\x92\xc0\x1b\x12\xe4\xa8\x80\xc5\x9a\xbe\xf0\x92\xb3\x46\x95\xd5\x59\x8b\xce\x0d\xe0\xf2\x2a\xe0\x5e\x88\x6c\x77\x4f\xb3\xb9\xfb\x29\x08\x70\x33\x58\xb0\xe2\x77\xd6\x33\x17\x03\xce\x85\x32\xcc\x8a\x47\xa8\x8c\x92\xd3\x9f\x23\x6a\x09\x15\x70\x11\x06\xa6\xb8\x7a\xb5\x5f\xdb\x83\x85\xaf\xeb\x1c\x26\x45\x17\xef\x02\x9c\x2a\x10\x29\x41\x58\xd5\x39\x2b\x9a\x59\x21\xfb\xa5\x31\xa3\x77\x2a\x04\x17\xc2\xd2\xab\xe3\x6c\x7e\xac\xca\xb3\xfe\x73\x28\x63\x3f\xba\x02\xc4\x88\xa8\x1b\x44\x7b\xba\x45\x31\x00\x4f\x2b\xf5\x9c\x31\x0c\xb9\x19\xaa\x3b\x0e\x6f\x01\xa8\x96\x9c\xbd\x54\xf0\xfe\xdb\x76\xd3\xd7\x20\x56\x01\x30\x15\x81\x83\x3d\x2c\x58\x47\x37\xfe\x95\x53\xab\x02\x80\x84\x9b\x10\x0d\xda\xb1\xf5\xfc\x36\x40\xec\x4e\x7b\x70\x81\xf2\x34\x82\x0f\x27\x8c\x53\x72\x1a\x52\x2b\xa8\x40\x91\x04\x74\xa8\x2b\x93\x87\x8a\x75\x63\x4a\xa9\x20\xf0\x0d\x59\x25\xeb\x7e\x64\x98\xb2\x3a\x78\x3f\xbf\xd9\xf5\xd3\xb4\x85\x9e\x60\xa9\xe1\x04\x59\x5f\xa0\x98\x67\xb2\x9e\xdf\xe6\x99\x94\x9f\x00\xaf\x55\xe8\x27\x0c\xa3\xcc\xdf\x7f\xf9\xbe\xf8\xbc\x7c\x5a\x85\xbe\x84\x60\x8c\x45\x7e\x2c\xab\x45\x5e\x5e\xa5\x8d\xbc\xec\x81\x0d\x39\x1e\x55\x18\x50\x3f\xd0\x2e\xb6\xca\xe1\x67\x6f\x00\x87\x41\x6a\x1c\xa1\x0b\xab\xc0\x16\xd5\x0d\x1e\x26\x8c\x62\xc4\x31\x65\xf5\xcb\xf5\xbc\x1d\x88\x4c\xa8\x30\xa4\x02\x53\x3a\x07\x6d\x38\xe3\xa5\xbf\xe0\x76\x50\x61\x28\x53\xb4\xca\xfe\x53\x66\xc5\xac\xd6\x56\x9f\x69\x8a\x18\xc7\x58\xc1\xe6\xb7\x6f\x83\x1b\x88\x04\x20\x75\x0b\x42\xb7\xb4\xc6\x8d\xca\x33\xd1\x6c\xa1\x2e\xf3\x6b\x17\x72\x57\x21\xf1\x15\xa2\x17\x1a\x1d\xe6\x97\x00\x67\x90\x8b\x53\xeb\x21\xba\x2e\xa9\xef\x99\x8d\xaf\xbd\xd9\x6e\xf4\xd8\x1d\x2a\x24\x82\x01\x38\xa6\x18\x24\x0f\x5f\x3d\xd4\x6b\xd5\x17\xe2\xb0\x5d\xa5\x26\xd7\xc3\xe8\xc6\x04\xa6\xf2\x2f\x37\x94\x90\x7a\x29\x2a\xcb\xf3\xeb\x0d\xa9\x39\xa7\x5f\x1a\x0d\x19\xed\x54\x55\x17\xac\x90\xb8\xc7\x8f\x99\x86\x26\x2a\x8f\x54\x48\x39\xc1\x50\x22\x4e\xb5\x4c\xf3\xce\xed\x72\x56\x9f\xb2\xe2\xd8\x07\x13\xa8\x30\x8d\x05\x8e\xe8\x76\xf2\x9b\xa8\x8a\x6d\x12\x51\x84\xce\x1a\x06\xfe\x57\xc5\x09\xaa\xac\xe9\xad\xba\xa1\x00\x42\x2c\x03\xf8\xb3\x51\x42\xfd\xc2\xf9\x0b\x25\xe5\x9e\x11\xb3\xc2\xc2\xe6\x9a\xdd\x25\x1f\x4c\x4f\xf0\x13\xac\x38\x5b\xd6\xa2\xe4\xac\x6a\xb7\xc1\xc1\xe0\x00\xc9\x31\xaf\x06\x86\x35\x4f\xeb\xea\xe8\x28\x57\x47\x51\xa3\x42\x50\x51\x68\x24\xbb\xf1\xf8\xef\x65\x2e\xa1\x6a\xcd\x6b\xb9\xd6\x67\x5c\x7c\xbe\x47\x85\x8a\x86\x98\x7e\x41\x62\xc3\xe5\xc3\x61\xf6\xf0\x6c\x21\x7d\x2a\x54\x8c\x23\x2d\x0c\x1b\x9a\x3a\xa1\x52\xd4\xaa\xee\x2d\x7f\x6a\x1a\x38\x3b\xc1\x0c\x58\x70\x6c\xcb\x44\x5e\x2c\x50\x78\x12\x53\x6c\xab\xc5\xda\x11\x52\xdb\xf6\x24\x40\x6c\xc3\x9e\xed\xd9\xde\xda\x10\x51\xe0\xc7\xb8\x78\xb4\x3e\xdf\x1d\x50\x51\x45\x41\x12\x22\x2c\xee\x3f\x92\xe5\xd0\x0e\x03\x79\x84\xfa\x56\xf7\x2c\x8a\x28\x94\x4c\x59\x1b\x6a\xd9\x9c\xf6\x1f\x00\xc3\xe0\x4d\x14\x4a\x89\x26\x02\x56\x92\xe3\x20\xda\x3b\xbf\xd7\x74\x89\x78\x88\x36\xe5\xf2\xb7\xfd\x61\xb1\x7e\xde\xcc\x5e\x7e\x3f\xec\x7f\xac\x5d\xb3\x62\x48\x00\xff\x08\x20\x39\x13\x6f\x36\x12\xd9\x9f\x18\xc9\xd0\xa7\x8a\x48\xa4\x70\xdf\x7c\x5a\xbe\x4e\x7f\x99\x88\xf0\x88\x98\xf9\xfc\x5c\xca\x6b\x0e\xf3\xdb\x8b\xf5\xaa\xee\xce\x26\xf4\x02\x5f\x94\x12\xd0\x46\xfd\xc7\xa8\x5d\xa5\x48\x19\xb3\x99\xed\xbf\x8f\xde\x61\x92\x42\x64\xf9\x52\x75\xa4\x61\xda\xb5\x8d\xd2\x88\x60\x72\xe7\xa9\x3c\x3e\x67\x9f\x8d\xa7\x28\x15\xa0\xcc\xf8\xdf\x35\xed\x64\x99\x5c\x1d\x22\xc6\x18\xa0\x92\x77\x7d\xc6\x87\x1a\x5e\x8a\x33\x0f\x4c\xa2\x7e\xa5\x51\xcc\xf7\xd0\x0a\x15\x09\xe9\xe1\x39\xac\x54\x78\xd6\xc0\xf9\x90\x61\x55\x8d\xe9\x01\x49\xe4\x75\x4c\x40\xc6\x06\xb3\x0c\x9f\xc3\x4b\xaa\x28\xf1\x92\x9e\x0c\x18\xba\x3c\x13\xf9\x28\x15\xa9\x54\xeb\x1d\xea\xaa\xdf\xfe\x94\x8d\x54\x9a\x24\x56\x05\xbb\x75\xf9\x3e\x71\xe0\x23\xc5\xc0\x51\x76\xa1\x01\xf9\x03\x59\xe0\xf9\xed\xe5\x7a\xee\x17\x55\x25\xff\x8e\x8c\xf3\x4a\xbc\x94\x71\xf4\xaa\x5e\x5f\x1e\x56\x2f\xdf\x9c\x53\xfc\x3c\x33\xb1\x6c\x45\xfc\x84\xa0\x75\xa7\xa5\xb7\x58\x7d\x5a\x5f\x3f\xf9\x4a\xc4\x17\x0a\xad\x7d\xae\x4d\xcc\x83\x13\x5a\x39\xa8\xb2\x3a\x08\x4c\xf9\x1d\xde\xcb\x8e\x0a\x47\x91\xc0\x27\x58\x17\x8d\x5d\xfb\x49\x08\x45\x82\x80\x0a\x53\xc3\xa7\xb2\xea\xdc\xc3\x10\x8c\x96\xf1\xeb\x17\x81\x4b\x12\x70\x1a\x69\x16\x81\xc6\x9d\x58\x85\x5a\xae\x01\xd1\x17\x23\x72\x51\x45\x42\x4f\x20\xc0\xe5\x7f\x67\x8b\x5f\x36\xeb\xfd\x61\xf1\xbd\xd3\x5a\x51\x24\x24\x09\xda\x36\xad\x4d\x79\x67\x45\x0d\x4c\xd1\x29\x00\xba\x22\x61\x0c\x52\xda\x7a\x87\x72\x44\x99\xa5\x48\x08\x1e\xb5\xfc\x1e\x05\xe4\xcf\xec\x67\x97\x9a\x52\x24\x8a\x22\x54\x74\x45\x5e\x89\xb2\x9c\x56\x54\x50\x24\x4a\x62\xe4\x5c\x7f\xbe\xb5\x7b\xf0\x5f\x01\xdc\x14\x89\x52\x0f\x6d\x9a\x67\xf6\xf3\x60\x59\xb3\xdd\x25\x85\xe7\x0b\xb7\xf3\x68\x70\xd9\x18\xc6\xa5\xe5\x38\xdc\x01\x41\xa4\xf4\x84\xfe\xd6\xfa\xdb\x5f\x40\x88\x15\x21\x5e\x90\x86\xfd\xca\xe6\x7e\x24\x86\x90\x84\x50\x8b\x35\x99\xb3\x3f\x9f\xa1\x39\x95\xd2\x8e\xe4\x6e\xaf\x22\x04\x04\xe6\xb3\xcc\x94\xfd\x15\x47\xd8\x83\x83\x33\x28\x12\xa7\x8c\x47\x1d\x1c\x65\xad\x10\x69\x32\xfd\xf2\xe2\x14\xe2\xd8\x51\xe3\xb4\xf6\x62\x27\x74\x71\x97\x4b\x53\x84\x06\x5e\x94\xd8\xb2\x8f\xe2\x9d\x39\x0b\x7b\xf8\x5d\x29\x21\x88\x42\xe9\x17\x21\xda\xbb\xa3\x54\x73\x1a\xd7\x1d\x47\xaa\xe3\x9a\x1c\x9d\x45\xfa\x31\xf4\x59\xa4\x6d\xf6\xd6\x9e\x2a\x49\x03\xac\xe8\x38\xb1\xfa\xf4\x77\x68\x0b\x15\x49\xa4\xd6\x2e\x31\xdc\x76\xeb\x6a\xc2\x8d\x21\xa9\xaf\xd3\x47\x3d\xa7\xdb\x27\xf6\x9a\xa9\x12\x68\xcb\x7c\x03\x0b\x38\x7e\xc8\x2a\x40\xf6\x7a\xeb\x2a\x10\x46\x34\x43\x2c\x22\x70\xe0\x10\xb9\xdf\x13\x4d\x4a\x89\x73\xfc\x78\xad\x3e\xd5\x2b\xf9\xe7\x70\xd7\x1b\x3e\x03\x4b\x39\x15\x7d\x96\x9e\x6b\xd5\xbd\x5d\x26\x12\xdc\xaa\x85\xe6\xb2\x1a\x6e\x61\x84\xfb\x12\xb1\x9d\xdf\x56\xfb\xef\xaf\xf3\xc3\xd3\xea\xe5\x17\x7b\x20\x97\x89\x19\x08\xcd\x4b\x29\x59\x8e\x20\xc0\xd7\xed\xd3\x60\x9f\x27\xc2\xf7\xb5\xa7\xff\x51\x1e\x84\x23\x54\x50\x44\xc4\x14\xb9\x76\x9e\xaf\x79\x93\x5d\x72\x58\x56\x55\x59\xd5\x43\x70\x87\x22\x02\x12\x64\x16\x5c\xbc\xec\x0f\xfd\x35\x9f\x08\x05\xe8\xba\x62\x0d\x55\xdd\x0f\xde\x11\xe5\x11\x4c\x9c\x9d\x6f\xbf\xa2\xa2\xae\xfb\x39\x41\x28\xf7\xc1\x14\x9a\x3b\x56\xd3\xe1\xf0\x56\x54\x50\xa7\x58\xab\x01\xc1\x7f\xa7\x78\x4c\x11\xa5\x88\xc7\x4c\xe8\xd1\xf8\x81\x5f\x9a\xea\xb1\x1f\xf1\xd8\xc8\xf2\xec\xb3\x26\xef\x28\x0f\x3e\x25\x96\x57\xb1\x1f\x87\xb8\x45\xf7\x88\x36\xec\x58\x89\x03\xdf\xc3\x6a\xc6\xd5\x62\x7d\x40\x30\xe3\xa0\x3e\x5e\xc5\x41\x44\x11\xd3\xf0\xf0\xc7\xfa\x05\x34\x6b\x9e\x6d\x89\x23\xab\x3e\x8d\xd9\xfe\x71\x6d\x90\x9d\xcc\x71\x00\x01\x8a\xba\xe1\x5e\xbd\x63\x39\x1c\x34\x61\xb4\x03\x45\x0e\xe7\x63\x1c\xd2\x04\xcd\x4b\x28\xe4\x6a\xb1\xee\xad\x38\x71\xa8\x08\x02\xdb\x0c\x79\x0d\x96\x8b\x4c\xbe\xd7\x38\xe2\xb1\xe2\x66\xbd\x99\x29\x95\xe5\x99\x8d\xc7\x4e\x5b\x4c\x31\x89\xb4\x65\x59\x43\x9e\xeb\x0f\xb1\x12\xa5\xbd\x2e\x49\x83\xb4\x2f\x71\x59\xc9\xc7\xb2\x9a\x89\xff\x5e\xb3\x0a\x4c\xd9\xe6\x44\xde\xc2\x1e\xac\x02\x8c\x89\xae\x9a\x2b\x77\x4f\x12\x13\xc0\x6c\x68\xa9\x14\x54\x9f\xa9\xee\xdb\xbe\x09\xe7\xac\xa3\xf0\x5d\x59\xa8\xa7\x8a\x69\xe4\x63\xd0\x91\x09\x51\x5d\x8d\xe2\xcc\xb4\x19\x13\xd3\x08\x10\x91\x7e\xbe\xcd\xb0\x48\xae\x97\x1f\x57\x31\x4d\x04\xa6\x72\x64\x65\xe1\x22\x2a\x4e\x02\x5d\x87\x82\xfb\xb9\xa1\x09\xb2\x84\x8c\xd3\xf7\x99\x44\x0c\xd9\x23\x8c\xa6\xe2\x6c\xff\xec\x2a\xef\x4c\x8f\x94\x13\xd6\x15\x7a\xf5\xb8\x87\x8c\x56\xd7\xfd\x6d\xb3\x48\x69\x98\xf6\xad\xf5\xb8\xb3\xa2\x57\x9d\x69\x7a\xf0\x48\xfb\xfe\x73\xa4\xd8\x14\xa3\xb7\x98\x8c\xce\xc7\x65\x80\xcc\xfa\x59\x3d\xab\x78\xd6\x54\xec\x2e\x92\x1b\x8b\xc0\xc3\xb8\xec\xf3\xf6\x13\xd9\x43\xdb\x2f\x94\x5c\x9a\x18\xc2\xd7\x01\xa3\x58\x0a\x89\xf0\x4e\x2c\x6b\xfb\x63\xb1\xae\x7a\x63\x1a\xc2\x08\xa1\x88\xbb\xf5\xe6\xfb\xea\xf7\x99\xfb\x39\xe2\x88\x3b\xfc\x80\xcc\x60\x8c\xf7\xa5\x0d\xb6\x4f\x8f\x60\x95\x6a\xc4\xb1\x7e\xb9\xb3\xcd\x6a\x73\xe5\x79\x26\x5c\x69\xaf\xed\xc6\x03\xde\x31\x61\x6e\x33\x71\x72\xcb\xe7\xe0\xf1\x94\x0a\xd0\xa5\x5d\xae\x8a\xf7\x32\x13\x59\x71\x1c\x85\x31\xa9\x27\x42\x89\xfa\x4c\xe5\xdf\x8b\x9b\x51\x4f\x72\x3f\x70\x75\xcf\xcb\xf3\x25\x2f\x6f\x70\x57\x96\x69\x3a\xb7\x76\xea\x18\xe7\x67\xaf\x1c\x72\xb0\xe2\x56\xbb\x2b\xff\x0f\x88\x66\xb0\x98\xd3\x50\x72\xe1\x75\x3b\xfa\x1e\xd8\xb9\x35\xf8\xec\xbc\xa1\x91\x11\x97\xd5\x0a\xee\x9a\x44\x61\x76\x3e\xf7\x4f\x41\x42\x1d\x9d\x7f\x5e\x3e\xad\x5f\x0e\xf3\xd9\x6e\x79\x78\x7d\xb1\x72\x02\x8a\x12\xa1\x05\xdc\xca\x62\x50\x74\xaa\x28\x01\x9d\xf9\xb4\xec\x29\x48\x6b\x6b\xda\xe2\x40\x23\x1a\xda\xc5\xef\x93\xa7\x8e\xd3\xc4\xa3\x3d\xee\x01\xcd\xad\x34\xec\x43\xd3\x00\x83\x47\x5b\xac\x01\x18\x35\x26\x29\xf3\x44\x57\xf9\x9b\xe7\xb6\xf8\xfc\x61\x54\x69\x38\x39\xdf\x68\xea\x45\xa8\xb0\xd0\x39\x19\x1f\x59\x73\xd2\xbb\x9f\x7d\x0c\x16\x00\x26\x04\xf6\xcb\xd9\x33\x1a\xec\xf6\x77\x12\x32\xdf\xac\xb9\x1a\x45\xfe\x15\xbb\xb2\xa2\xdc\x53\xc2\xc9\x9b\x56\x13\xda\x98\xb6\x5f\xa4\x91\x0d\xa6\xce\x62\xfa\xc6\x79\x1a\x23\xdb\xcb\x8e\x9d\x5b\xbb\x60\xbb\x88\x29\xfd\x22\x84\x49\x39\x4b\xac\x70\x91\xd1\x5d\x5b\x36\xa7\x67\xf6\x06\x95\x96\x67\x1c\x71\x21\x29\x2a\x12\xbd\x2b\x95\x28\x88\xdf\xf7\xa9\xa8\x48\x23\xc6\x1c\xdc\x54\xcb\xe7\xb8\xb7\x25\xdb\x1d\x50\x43\x03\x2a\x10\xac\x81\x07\x50\x50\x08\xd8\x5d\x79\x73\xbb\xf4\xd5\xd6\xb0\x2f\x16\x1f\xce\x8e\xc7\xec\x5a\x1c\x33\x14\xdd\x9b\x48\x0b\x52\xf0\x42\x8c\xac\x1b\xbc\x01\xf5\x06\x4c\xc0\x8a\x82\xaf\x40\x27\x04\x6c\x78\xc1\x36\x48\xc2\x9d\xc6\x4c\x6b\xaf\xef\x9f\x36\xbe\x3d\x4a\x79\xba\x62\x98\x5d\x2e\xbf\x42\x55\x67\x25\xd6\xa1\xcf\x9a\x49\xd0\x9f\xa2\x2a\xd0\x18\x46\xfd\x5d\x1e\xca\xe3\xf4\xc2\x44\x15\x8d\x71\x48\xee\xb2\xf6\xd3\x3c\x74\x20\x1e\xaa\x8c\xcf\xb8\x58\x3f\x6f\x9e\x96\x98\xfc\xde\xed\x67\xfb\x57\x9b\xfe\x4e\xbc\x28\x05\x36\x90\x55\x5b\x3e\xed\x17\x4f\xac\xea\x22\x7b\xd6\xcc\x48\x3c\x9a\xc6\x1a\x47\x7c\x7b\x2e\xab\x4e\x23\x43\x25\x9e\xf4\xb9\x21\xe1\xad\x59\x0e\xdf\xca\xce\x55\x4e\x7c\x4f\xa3\x67\xff\x58\xbf\x38\xa8\x59\xfb\x6b\x8c\x3a\x0e\x8e\x17\x20\xcf\x07\xdc\xba\x83\x07\x4c\xfc\x94\xa3\x67\xd8\x71\x34\xf4\xca\x46\xa6\x98\x3c\x55\xe2\x8b\x08\x0b\x70\x79\x86\x28\xcf\xa3\x35\x35\x92\xd0\xf3\x12\x66\xa2\xfc\x96\x01\x0e\xd3\x43\xae\x43\x2a\x83\xc0\x46\xf5\x91\x18\x89\x65\x77\xd9\x8f\x2f\x29\x6d\x54\x42\x42\x8a\xe0\x0b\x79\xbd\xe4\xa8\x2f\x30\xb2\x67\x13\x42\x38\xa6\xb2\x5b\xeb\xec\xc9\x7a\xf2\xd7\x7e\x99\xc6\xf0\x1b\x27\x24\x96\x48\x1b\x24\x4b\x97\xba\x33\x2d\xd4\xd7\xe6\x8f\x28\xcf\x17\xab\xf5\x37\xc1\x31\xa2\x12\x1a\x85\xca\xa0\x59\x7a\x6c\x19\x2a\xa1\x4c\xb3\xd9\xb6\xbe\xd4\x9d\x02\xce\xe8\x14\x2a\xf2\x53\x0b\xcc\xdd\x67\x48\xc3\x92\xf5\xa2\x10\x49\xe2\x03\x46\x7c\x9f\x4b\xbe\xfb\xef\x95\x39\x4b\x2a\x49\x7c\x15\xc5\x16\x5d\xb9\x61\x58\x41\x3d\x7c\xc2\x94\x7a\x18\x62\xe8\x93\x1c\x1b\x9c\x80\x3d\x09\xf3\x43\x49\xb5\x71\xa1\x65\xc6\x86\x67\x60\x1c\x10\x7e\xa7\xb2\x9f\x1b\xa8\x4c\xa4\x78\x72\xcb\x4c\x7a\x73\x3d\x61\x12\x74\xb6\x29\x7b\x07\xc1\x0a\x79\x6b\xdc\x60\x61\x40\xa4\xf3\x67\x1e\xcb\x6b\xd5\xd5\x7a\xb4\x8d\x3a\x6a\xb9\xdc\x2e\x68\xe0\x4f\x10\x2e\x98\x7e\x22\x22\xc2\x10\x37\xfc\xab\xf5\xe3\xb3\xb2\x18\xed\x15\xb6\x23\x15\x91\x70\x74\x7e\xbb\xeb\x79\xdc\x01\x12\x2d\xb5\xb7\xc8\xf2\x3c\x2b\x0b\x96\x55\xee\x66\x94\x27\xd1\x72\xd7\xdc\xa3\x1f\x25\x26\xe5\x97\xff\x9d\x97\x65\xee\xba\x44\x22\xd2\xee\xb0\x91\xe8\xdb\x88\xe6\x37\xdf\xeb\x9a\x95\x36\x88\x8c\xad\x81\xe6\x77\x8d\x5f\xb7\x0f\xe2\x56\x89\x52\xa9\x6f\x0b\xbd\x2e\x65\x51\x97\x95\xab\xdd\x54\xa9\x17\x50\x54\x74\x53\x87\x4b\x95\xbd\xbb\x5f\x43\x65\x53\xf1\xcb\x73\xd6\x8c\x6b\x4e\x55\xea\xc5\x09\xce\x4a\xad\xe7\x92\x99\xef\x3f\xbd\xb5\xa4\x7e\x20\x91\x9b\x0c\xb5\x10\xfb\x44\x20\x2a\xf5\x89\x16\x5f\x6d\xc7\xe6\x41\x0b\x6e\x59\xa3\x26\xf5\xa5\xaf\x9f\xbf\x62\xaa\x79\x81\x8f\xd6\xcd\x68\x0d\x2b\x0b\x4e\x18\xdd\x52\x10\x86\xba\x1c\x14\x6b\x85\x31\x7e\xbb\x37\x9c\xf6\x96\x03\x4d\xa5\x41\x94\x60\xc6\xd8\x44\x8b\x51\x07\xa6\xaf\x51\xf5\xe5\x32\x91\x06\x54\x73\xa8\x1c\x01\x41\xb3\x68\xca\x0c\x7b\x44\xbe\x8a\xd3\x4f\x99\x76\x06\xb4\xd4\x2a\x8d\x42\x0f\xd1\x44\x68\xca\xd5\x27\x56\xb9\x15\x3a\x8d\x64\x8c\x3b\x4f\x56\x55\x20\xaf\x22\xe3\xf9\x1d\x3c\x20\x8d\x14\xc7\xf4\x53\xeb\xd1\x35\x6f\xf3\xd2\xd9\x5c\x29\x91\x10\x47\xbd\xd5\x7a\x5f\x7e\x1b\xc0\xbe\x86\xf7\x1c\xfb\x3a\xb2\xd2\x6e\x05\xf5\x26\xbb\xb8\xfb\x8b\x43\x81\x41\xcd\x0b\xe6\xa3\x86\x3b\x6a\x1a\x4b\xf0\x1c\x9f\x55\x5d\x5e\x2b\xd1\x87\xed\xab\xb4\xb5\x57\xdb\x83\x51\x3f\x70\x32\x6c\x9d\x52\xca\x2d\x69\xdb\xbc\xe4\xa3\x37\x49\x99\x87\xb9\x51\xac\x00\xab\x05\xbb\x80\x6c\x4f\x05\xab\x62\x87\x93\xd5\x5d\x47\xa6\x58\x20\x89\x1b\xf8\x41\xb6\xc6\x71\xbf\xe0\x47\xa5\x54\x49\x6e\x70\x45\x03\x41\xca\xf7\xbb\xfb\x49\x02\xaa\x74\xad\xd1\x7b\x56\x43\xb5\x61\x95\x7b\x9a\x24\x4d\x88\xd4\xef\xba\xcf\xcd\x3d\x7a\x93\x09\x8b\xf0\x4d\xaa\x2c\xcf\xf5\x5e\x34\x90\x29\xfc\x77\xd8\x05\xf6\x7a\x7f\x06\xff\xf7\xcf\xbe\x45\x83\xbf\xa7\xa3\xc4\xcb\xbf\x83\xff\xb3\xd7\x90\x0a\x33\x66\xc7\xde\x7a\xfa\xef\xff\x1b\xdf\x08\x78\x48\xad\xc1\xa4\x1c\xcb\x89\x4d\xb9\x6e\x69\x1a\xc6\x38\xb0\xe7\x57\xe3\xec\xff\xc3\x35\x24\xf8\x4a\x76\xab\xa7\xd9\xd3\xec\xfb\xca\xfe\xce\x52\x8e\x31\xd3\x97\x87\xd7\xdf\xe6\xdd\xe6\x96\x32\x88\xc3\x10\x09\x15\x25\x9c\x33\xeb\xbc\xa5\xdc\xd7\xe1\xcb\x13\xa6\xf7\x4c\xb1\xf6\xf0\xe5\xf3\x50\x33\x51\xd4\x5a\x81\x22\xd8\x02\x13\x5d\x8a\x2d\xe5\x91\x2e\x08\x7c\x2d\x4e\x2c\x1f\xf3\xfd\xaa\x14\x58\x80\xcd\x12\x44\x29\x61\x6c\xe5\xa5\xc0\x84\xd6\x2b\x42\xef\xbb\x27\x60\x67\xda\x95\xaf\xbd\xea\xa3\x46\x49\x96\x85\xad\x5d\x74\x0b\x95\x4a\x42\xdc\xed\x2a\xcb\xa1\xb2\xaa\xeb\x6b\xeb\x0f\xec\x6e\x45\x73\x1a\x19\x37\x91\x3d\x88\xa7\x71\x32\x99\x9e\xb2\x1d\x20\xc6\xb1\xa9\xd1\xe9\xd3\xe1\x58\xe6\x29\x1a\x6b\x52\xf2\xdb\x43\x75\x3d\xda\x59\xce\x3c\xa5\xb7\x9f\xcb\xb1\xec\x87\xe8\x58\x40\x02\x84\xf6\x95\x4a\x75\x35\x60\x8a\x45\x44\xb1\xd8\x04\x74\x9e\x35\xb6\xd4\x35\xc5\x94\x44\x1d\xf6\xf4\xf3\xc2\x4c\xc5\x22\xae\xe1\x9b\xf3\xf6\x91\x6c\xae\x8a\x11\x8f\xa1\x41\xf9\x5e\xb6\xe6\xbc\xd3\xf3\x73\xcd\x52\xe3\x53\xac\xb8\x80\x71\xe0\x3f\xb9\x04\x01\x22\x2d\xb4\x6c\xfb\x4b\x79\x1f\xe6\x66\x31\x8b\x21\xec\x22\xf1\xf6\x32\xb1\xd2\x19\xac\x17\xf8\x68\xe7\x6e\x26\xb2\xcb\xdf\xe5\xef\x53\x8c\xd2\x04\x51\x3f\xaf\xcb\x01\x26\x86\x51\x43\x38\x59\x69\xdb\x73\xbc\x0a\xb3\xc4\x13\x31\x38\xca\x0e\x27\xf1\x90\x95\x45\x87\xb6\x64\x09\xe8\x38\xcf\x0e\x9a\xe5\x3b\xcb\xaf\xd6\x6d\x73\x98\xda\x6b\x0f\xc6\xcc\xd2\x40\xe1\x60\x3e\x95\x6e\xaf\x60\x69\xa4\x79\x90\xe7\x0f\xb3\xdf\x77\xb3\xa7\xa5\xfb\xdd\x28\xb6\x1a\xe2\x9a\xdf\x81\x55\x6b\xb5\x2a\x54\xde\x5f\x03\x59\x4a\x38\xa2\x03\x0f\x70\xce\x9a\xff\x2d\xf9\xa6\x1c\xf0\xdb\xff\xc5\x1b\xfa\xe7\x7d\xac\x9e\xa5\x09\xc5\x8f\x24\xae\xd5\xa6\xac\xb3\xc1\xc5\xb8\xae\x4d\x9b\x3d\xfc\xba\xda\xad\xb7\x87\xf5\x8b\xbb\x5b\x16\xea\xfa\x11\x0e\x56\x53\x56\x31\x1e\x87\xb8\x25\xaf\x16\xeb\xf9\x6a\x00\xc9\x66\x5c\x69\xfd\x20\x33\xe9\x8e\x03\x60\x10\x13\xb1\x26\x6f\xc5\xe2\x34\x77\xab\xdd\x2d\x8a\x58\xca\x3e\x05\xc8\x93\xa9\xb0\xf8\x01\x99\x3b\x45\xca\x90\x94\x31\x13\xe5\x77\x56\x2f\x3b\xcd\x7f\xc5\x04\x00\x72\xd2\x3e\xc3\x19\x06\x37\x25\x03\x29\xcc\x7e\xb2\x67\x3f\x57\xc5\xfc\x32\x32\xfb\x18\x24\x1a\x40\xf6\x8d\xdd\xe6\xac\x60\x05\x1b\x1c\x0f\x2c\x15\xc6\xb6\x7a\x2d\x5c\x58\xe1\x31\x67\x6e\x1c\x83\x08\x31\x35\x88\xcc\x24\x77\xa1\xa4\xf1\x47\xbb\xdb\x3b\xee\xb2\xf6\xd3\xce\x01\x03\x91\x06\xb4\x5f\xf8\x75\xba\x16\x6f\xee\x1e\x14\x98\xb0\x49\x21\x5f\x3a\x42\x74\xd3\xaa\x48\x00\x60\x9c\xb2\xfd\x47\xf9\x6b\x99\x5f\xbb\xa1\xaa\x62\xc5\x3b\x36\xbf\x01\x11\xab\x4d\x88\x30\x45\x3d\x4f\x13\x9a\x14\x57\x96\x0f\x28\x6d\x46\x57\x12\x0a\xa5\xb6\x37\x50\xd5\x65\xc1\x5c\xc8\x6d\x30\x09\xb9\x17\x06\x88\xdd\x37\x9b\xc7\x33\xcb\x8a\x1e\xdc\x92\x7b\xa1\xce\x46\xa0\x73\xf2\x84\xd1\xe9\x6f\xac\x7e\x42\xb5\x80\xc1\xe5\xb8\x1f\xc9\xd4\xb1\x16\x9b\x95\x7e\xde\xde\xf9\xbe\x62\x59\x9e\x15\xc7\x3f\x46\x38\x73\x7b\x1c\x27\x26\xbc\x6e\x73\x65\xdf\xae\xac\xb5\xb9\xc6\x74\x23\x8a\x07\x44\xa2\xc5\xad\x85\x11\x2c\x2c\xc7\x34\x86\xbe\xe6\x52\xd4\xb0\x65\xcc\x90\x0e\x5e\x1c\x0f\x39\xc5\x41\x7d\xa8\xa1\xd1\xc5\xf0\x63\xb5\x77\xc5\x43\xa9\xb9\x40\xb4\xde\x90\x45\xf2\xcc\x6f\x46\x67\x65\x74\x3f\x51\xc0\x31\x39\x56\x5c\xcf\xb6\x04\xdb\xde\x4d\x24\x62\x2c\x0d\x62\xa8\x88\xb0\xfc\x6f\xe0\x9b\x88\xb7\x6f\x28\xf1\x7c\xdb\x51\xfa\x48\x9a\x79\xd0\x3b\xdd\x88\x82\x53\x71\x12\x70\x5c\x24\x2d\x65\x61\xfd\x0d\x29\x59\xc6\xaf\x86\x70\xc9\xd3\x9e\x10\xfd\xac\xde\x41\x9f\x1f\x64\x52\x2c\x78\x60\xc9\xf0\x38\x0c\x10\xc0\x6d\x15\x87\xed\xe0\x9e\xb3\xe2\x6d\x52\x23\xc1\x1e\x47\xf4\x16\xf8\x98\xd5\xa7\x4d\x55\xfe\xbc\x23\xee\x77\xfd\xf4\x96\x6e\x42\x27\x7a\x45\xba\x13\xf6\x51\x3c\x4e\x13\x2b\xfc\xd7\x23\xca\x5e\x15\x0a\x09\x2c\xee\xea\xd4\x78\x2c\x28\x66\x54\x30\x7e\x38\xce\x7c\x0f\x9e\x90\x12\x22\x4d\x44\xf4\x7b\xd9\x98\x58\xc8\xf0\x26\x93\x98\x50\x6e\x75\xe0\xe4\xb0\x5a\x56\xf1\x84\xc6\x36\x18\x3c\xcb\x73\x9d\x74\x42\x49\x63\xcd\xea\xa0\x5a\x3f\x6b\x7c\x42\x29\x9d\x9a\x1a\xab\xd1\xbe\x1a\xba\x03\x3c\x25\x81\x47\x2c\xd1\xbf\x7e\xe5\xbb\xeb\xd9\xb6\xb2\x80\x68\x4a\xc8\xeb\xf9\xcc\xaa\x5b\x9f\x62\xc7\xf4\x10\x31\xc3\x2b\xa0\x2f\xf4\x1d\xf2\xfc\xfb\x4d\x76\xcc\x69\x8a\x4b\x01\xca\xd4\x3f\x30\x5d\xfb\x80\x71\x47\x35\x2e\xd2\x55\x5c\x91\x10\x69\xab\x98\x94\x5a\x94\x1f\xa4\x2e\x55\x1a\x5e\x51\x78\x91\xb0\x3a\x50\xcf\xec\xa7\x75\x2a\x87\x39\x47\xd3\xd5\x4f\xbc\xd0\xef\xbd\x4f\xac\xe8\x9f\xa4\xfe\x6b\xfb\xca\x88\x77\x6a\x04\x86\x21\xc3\x8e\x0b\xe1\x4b\x0f\x2d\x6d\xd4\x6b\xfb\x7b\x45\xa3\x4a\xf8\x4a\xdb\xfc\xab\xa2\x2c\xdf\xfb\xc2\x84\x0a\x73\x33\x4e\xfe\xcb\xa0\xcc\x67\xf2\x1d\xaa\x26\xab\xfb\xe9\x7f\x11\xf8\x00\xa8\x9a\x8b\xb3\x41\x55\xee\xf7\x90\xd1\xc8\x82\x33\x6d\xe6\xa3\x1e\x71\x7e\x29\x11\x92\x84\xb2\xce\x44\x34\xf1\xde\xe1\x6d\x86\x29\x89\x52\xb7\xf0\xdb\x82\x8b\xbe\xfe\xa0\x5d\xa2\x44\xc8\x23\x70\x72\x47\xff\xba\x96\xd5\xf5\x3c\x3e\x19\x10\x4d\xd6\xad\x59\x82\x10\xd2\x26\xb3\xda\x61\x4b\xfb\xdb\x9d\x39\x84\x84\xc6\x35\x82\x66\x25\xe7\x37\x54\xd9\x1d\x7e\x1c\x92\x10\xc4\xe9\xb6\x4b\xfa\xa6\x75\x30\x7a\x98\x5b\x41\x04\x20\xe8\xd3\x70\x4f\x3e\x77\x91\x7c\x11\x0b\xc0\xea\x0f\x13\x3f\xa9\xff\xd5\xdc\x5c\x93\x24\x48\xc7\xd4\x31\xe8\x6d\x41\x64\x97\x0c\x8a\x26\xb0\x7d\xa8\x1f\x22\x64\xea\x97\xb2\x68\xca\x81\x83\x25\xa8\xcf\xb5\x06\x8d\x73\xd5\xc7\x55\xd7\x4a\x50\x12\xe2\xda\x94\xd5\x9a\xf8\xaf\x28\x25\x4c\xa0\x3f\x04\x65\x81\xe7\xb9\xaa\x5e\x4d\x1d\x6c\x9a\x92\xc4\x43\x46\x8c\x0f\xc8\x34\xf8\x05\x35\x67\x6c\x91\x42\xed\xba\xa5\x01\x56\x4c\x5f\x10\x83\xd3\xec\x6f\x17\xe8\x6b\xc1\x2b\x91\x80\xa4\xda\x78\x41\x19\xd4\x59\x73\x2f\xa8\xa8\x44\xea\x47\x18\x70\x72\xe5\x43\xdd\x97\x18\xca\x67\xb9\xef\x92\x06\x5a\xf7\x5c\x73\xf1\x7d\x4d\x3a\x3b\xba\x96\xd0\xc1\xc0\xef\xdb\x1f\xcd\x5f\x89\xd2\x0f\x97\x72\x91\x4a\xbd\x0e\x3e\x56\xac\x28\x32\xf1\x36\xf8\x2e\x8c\x11\xc4\xe7\xc1\xcf\x06\xc1\xb3\xc8\x7c\x74\xca\x2e\xa3\x47\xe5\xbe\x1f\x19\xdc\xd2\xae\x34\x86\xe2\x78\xf5\xe0\x41\x8a\x22\x89\x07\x56\x4f\x25\xba\x46\x0f\xc4\xa9\x8f\x1f\xd1\xa4\xf4\x8d\x98\x83\x3b\xe8\xde\xf6\x10\x5c\xc4\x98\xfc\xe3\x59\xf3\x9e\x9d\x07\x4f\xc1\x05\x0d\x13\x8b\x45\x6c\xa0\x3a\x83\xcc\xee\xf2\x67\x42\x44\x5a\x4c\xae\x86\xe6\x50\x19\x9d\xce\x83\x82\x41\x2a\x46\x48\x10\xb1\x6f\x8b\x4d\x7b\xa4\xa9\x4a\x40\x20\x91\x53\x5c\x66\x72\x51\x9e\x5b\x9b\x6a\x12\x4c\x2f\x80\x08\x5d\x89\xd4\x0e\x99\xce\x8f\x1a\xe3\x03\x04\x24\x29\xb2\xd3\x23\xd5\xb2\xa8\x6e\x97\xa6\x3c\x54\x20\x5a\xd3\xbd\xbf\x22\x29\xdf\xe7\x9a\x47\xab\x7d\xb0\xac\x30\x30\xf9\x46\x23\x37\x6d\xa7\xc8\xf7\x3b\x10\x25\x86\xd1\x6d\x10\x6e\xf8\xda\x55\x92\x8e\x20\x21\xcc\x0f\xdb\x71\x7b\x30\xfd\xcc\x19\xa5\x17\x86\x98\x49\xca\x6a\x8d\x55\x9e\xb6\x13\xa4\x47\xbc\x58\xab\x1f\x5c\x6b\x37\x0d\xa5\xcf\xa5\x06\x22\x19\x5d\xad\x5c\x4d\xc2\x34\xa5\x0f\x54\x69\x59\x34\x9d\x3b\xd0\xe3\x6a\x50\x90\x62\x7a\x86\x4c\x1a\xac\x5e\xf3\x85\x79\x23\x23\xc9\x22\x07\xc1\x37\xb0\xd4\x41\xce\x4e\x46\x8a\x4a\xad\x1b\x7e\xc9\x99\x80\x1f\xd9\x9f\x77\x66\x80\x24\x41\x8a\x51\xc9\xd6\xe3\xc2\x05\x64\x57\xe6\xb2\x4f\x01\xa0\x24\x89\x28\x1a\xc2\x1b\x76\x03\x27\xd5\xb3\x60\x97\xac\xf9\x0c\x4b\x2e\x09\x49\x90\xc4\x76\x5e\xb1\x42\x9c\xa0\x93\xd4\x62\xf9\xd7\x54\xd8\x4a\xc6\x91\x2e\x3a\x57\x59\x21\x27\xcb\xd0\x64\xcc\x24\xc2\x3c\xae\x05\xca\x9c\x8d\x0e\x97\x9a\x4a\x6f\x96\x55\xb2\x2a\x2f\xcf\xc8\xd7\x34\x7d\x93\xb1\x49\xd5\x9f\x35\x8f\xe0\x40\xc1\x5b\x49\x2a\x58\xc2\x06\x88\xb9\xbd\x7e\x98\x95\x1c\x2d\x8e\x32\x21\x7a\xa0\x19\x50\xc8\x46\xeb\x3a\xde\x5b\x00\xc3\xc7\x48\x52\x1f\xa9\x7c\x51\xf0\x7d\x36\xeb\x4f\x72\x99\xf0\xc8\x28\xbe\x4b\x44\xc4\xed\xc7\x29\x27\x99\x70\x85\x2f\x01\x49\xe4\x6c\x99\x82\xd3\xcb\x51\x32\x11\x21\xce\xed\xc5\xf7\xe5\xe2\x97\x23\x6b\xd7\xba\x5e\x2b\x0b\x63\xf4\x49\x9e\x7f\xff\xfd\x9b\xfb\x8d\x30\xd9\x43\xcd\x02\x4e\x29\x0b\x4a\xac\x5d\xaf\x38\xa0\x86\x61\x65\x99\x83\xb3\x80\xbf\x4e\xb9\x4b\x1e\x12\x43\x68\xd4\x54\xd9\xf1\x08\xd5\x43\xc5\x3e\xd6\xc5\xba\x62\x22\xcf\xfe\xd4\x10\x37\x7b\x05\xe1\x69\x15\x91\xd6\xef\xc0\x87\x2f\xab\x5b\x9f\xd9\x4a\x49\x61\x0a\x15\x0f\x97\x76\x95\x68\x1a\x90\x06\xb2\xd6\x7e\x21\x05\x95\xc6\x40\x4d\x7f\x74\x11\x49\x5f\x13\x11\xce\xaf\x37\x5c\x7b\xfa\x86\xb4\x14\x24\xe4\x7e\xcf\x5d\x79\x2a\x59\xb1\xd5\xd3\xe7\x93\x13\xca\x30\xc0\x6a\xec\x03\x52\x92\xb2\x2c\xb7\x58\x44\x17\x08\x1a\x5c\x40\xa6\x89\xe5\x9b\x19\x66\x08\xbf\x8e\x65\x49\x29\x09\xe2\x33\x77\x00\x72\x3f\xa4\x73\x54\x12\x22\x50\x46\x2e\x17\x19\x72\xfb\x91\x3a\x09\x60\x8a\x79\x81\x9d\x0d\x31\x5f\x5f\x50\xbf\xc3\x75\x48\xe5\x11\xaa\x1c\xdf\x83\x25\x95\x1e\xcd\x3e\x95\xc6\x46\x48\x33\xfb\xb3\xb5\x4e\x7f\x94\xd5\xdb\x67\xfb\x5f\x2f\x74\x03\x9e\x47\x40\xc7\x8b\xab\x1a\x76\xa7\x12\x5e\xca\xc6\x96\x50\x0e\x1e\x15\xbc\x50\x20\xb9\xdf\x86\xdd\x90\xce\x3b\x7b\xff\x05\x46\xd1\x01\xf0\x23\x82\x1b\xd4\x7c\xfd\xf2\xba\x3b\xec\x57\xcb\xed\xc1\x3f\x60\xcd\xc8\x3f\x6c\x0f\x2a\x10\x04\x9e\x89\x72\xfa\x71\x21\xf4\x22\x8c\xe0\x89\xd6\xf4\x3f\x34\x27\x38\x34\xa7\x0c\x46\xc1\x40\x08\x23\x69\xb8\xd8\x4c\x88\xf3\xbe\x3a\x09\xc2\x54\xe2\xa2\xb3\xf8\xbe\x7a\x59\xee\x96\x87\xe5\x6f\x8b\xef\xb3\x97\x6f\x4b\xcb\x95\xa5\x20\xa2\x7e\x80\xe0\x6d\xcb\x54\x3f\x08\x2e\xbb\xbc\x41\x32\x8a\xfa\x43\xc4\x63\x1b\x28\x36\x88\xbd\x42\xd7\xb7\x7c\x89\x8e\x46\x21\xe9\x44\x87\x4d\xb5\x37\xf9\x49\x85\x36\xc4\x61\xc4\x53\x1b\x1c\xd1\xe2\x22\xda\x15\x9b\xdc\x52\x21\x4e\x53\x2c\xb7\x6b\x6c\x39\x9c\xbf\x6c\x4e\x1b\x0b\xe8\x05\x1a\x30\x9c\x0b\x4c\x2b\xe8\x6a\x17\xd4\x2d\xa9\x40\x99\xe8\x61\xa3\x30\x2f\x3a\xb0\xe5\x81\x72\x5d\x60\xdc\x63\x2b\x78\x2d\xda\x15\x46\xd6\xd3\xae\x19\x24\x5e\xa0\xfa\xb6\xf6\xf2\xe7\xf4\x34\x85\xc4\x57\xa4\xab\x9d\x6d\x1f\x0d\x63\x45\x23\xd5\x7a\xd3\x39\x0d\x35\xa7\xb7\x26\x09\x06\x69\xf0\x4f\xea\xda\xf9\x47\xa3\xd3\xa7\x5c\x53\x25\x34\x55\x76\xc9\x61\x5b\x96\xe7\x67\xe7\x85\x40\xaa\xe2\x20\x1c\xea\x34\xd8\xcd\xa6\x37\x41\x5a\xa7\x10\xf3\x32\x65\x2e\xa7\x75\x53\x3f\xfb\x77\xf8\x49\x79\xa2\xa9\x56\x51\x53\x0b\xbf\xc0\x27\xfc\xa2\x0a\x44\xc4\x10\x82\xbc\xbb\x5c\x9b\x22\x7b\xb3\x46\xe0\xf0\x7c\x22\x81\xd0\x54\xd0\xec\x4b\x2c\x3a\x6e\xdd\x3f\x8b\x4e\x1e\xbb\x81\x6d\xf7\xd4\x15\xb0\x81\x31\x25\xee\x86\xdf\x27\xf7\x2e\x78\x9c\x6a\x7e\x83\x22\xab\x4f\x9d\x34\xa8\x02\xa1\x02\xf4\xb7\x7e\xc3\x32\xc1\xaf\x40\x8b\x20\x43\xc2\x3a\x24\xeb\xfc\x9a\xbf\xf5\xc9\x84\xea\xcf\x21\xf9\x20\xc3\x14\xf5\x1e\x8b\xeb\xb9\x57\x5d\x6d\xbd\x5e\xb7\x70\x48\xe6\xd3\xc0\x15\x3f\x76\x58\x1f\x90\x9c\x46\x69\x47\xe8\x39\x49\x38\x01\xe0\x47\xac\xab\x7a\x2c\x9b\x11\x15\x47\xff\xfb\x00\x49\x31\xe8\x83\x8c\x92\xa2\xe9\xe3\x03\x41\x79\x0c\xb1\x8b\x73\x64\xca\x79\xec\xc0\x24\xa0\x82\x58\x40\x7f\xcd\xf8\x7a\xad\x50\x69\x88\x9b\x07\xbf\xa2\x44\xca\x60\x5c\x2b\xcf\x63\x18\x9b\xe4\xd0\xac\x8b\xb5\x94\xcb\x77\x28\x7a\x83\x56\x79\xa1\x8f\xd7\xd2\xef\x7a\x5a\x69\xf3\xb3\xf0\xb6\x39\x85\x1f\x70\x23\x04\xdf\xae\x0a\x76\xad\x6e\x37\xa0\x6f\x77\x95\x58\xca\xe7\x04\x13\x61\xed\xfc\x58\x61\x61\x9c\xf5\xc8\x55\x40\x14\xfa\x18\xc6\x14\x7e\x60\x0d\xe8\xdc\xe0\xf4\x94\x55\x61\xc0\x91\xda\xf8\x58\xb1\x02\xbf\x04\x0a\x09\x61\xa0\x50\xc3\x87\x47\x97\x0e\x43\x25\x6d\x6a\xfb\x66\x97\xe1\x91\xac\xbd\x52\x61\x94\x60\x58\x6c\xb5\xd9\xff\x3a\x64\x75\xd3\x6d\xc8\xe7\x54\x16\xf5\xf5\x8c\xe2\x0d\xe5\xfb\xb8\xfe\x5e\x85\x31\x37\xa1\x81\x45\x9e\x41\xd1\xb4\x66\xf7\x27\x0c\x4d\x2a\x4c\x3d\x0c\x8d\x9a\xac\x99\xa9\x61\xb8\xb9\xa5\x47\x85\x69\x84\xf2\xa6\xc7\x72\x77\x2a\x5d\xee\x5b\x45\x7e\x80\x59\xed\xd5\x62\x0d\x03\x00\x83\x8a\x68\x94\x68\xb1\x82\x39\x34\x9b\xb2\xae\xb3\xce\x3f\x53\xc4\x0f\x14\xbb\x8b\x80\x6a\x24\xcd\xe8\x3d\xc4\x7e\x84\x4c\x8a\xe7\xdb\x9c\x89\x37\x1b\x04\xb1\x8d\x24\x70\xf9\x96\xc1\xee\x3c\x7a\x15\xd4\xd7\x4a\x60\x9a\x80\x66\xc1\x1a\x38\x96\xd5\xed\xab\xc9\xaf\x68\x14\xe0\x46\xbb\xbb\x56\x47\x18\x1b\x4a\x8a\xa6\xd4\x37\x17\xfe\x01\xd9\x66\x32\x36\xa3\x12\x11\x87\x7a\xc7\xaf\xaf\xf0\xcc\x7e\x9a\x74\x70\x3f\x0d\xac\x52\xcf\xc3\x64\x79\xeb\x5b\x7e\x00\xbc\x1d\x3e\x10\x11\x69\xf7\x7b\x95\x86\x9e\x41\xae\x34\x4d\x0e\x9f\xe3\x0b\x14\xf3\x28\x92\xc7\xd9\xfa\xb8\x51\x6b\x14\xda\xa9\xfc\xb8\xdb\x8f\xde\x0e\x53\x61\xa0\x23\x2c\x1a\xab\xf1\x00\x39\x34\x30\x99\xb6\x56\x3c\x00\x03\x76\x2b\x3f\xb6\x46\x89\x60\x78\x36\xce\xb5\xf1\xb7\x2b\x8d\xdd\x37\x94\xf7\xea\xcd\x79\x91\x26\xbe\x1a\xa4\xc0\x27\x22\x57\x4a\x88\x48\x84\x8e\x6c\x02\xe5\x02\xcf\xd7\x9c\x35\xd9\x3b\xe0\xe4\x79\x77\x4c\x4a\x4a\xfa\x02\xf1\x89\xfb\xea\x0a\x8f\x79\x76\x59\x2d\xd6\x9f\x96\x96\x7c\x19\x69\x51\x92\xc7\x38\xae\xdf\x0d\x37\xcb\x1d\x2c\x40\x01\x23\x68\x62\x1c\xac\x1f\xbe\x2e\xe0\xb5\xc8\x9a\x55\xb1\x6b\xc6\x54\xdd\x4a\x29\x3f\x05\x23\xac\xd0\x18\xbe\x97\xb2\xfa\x51\x95\x0d\x20\x92\x64\x7a\x52\xaa\x90\xa2\x2d\x60\xcb\x00\x77\xab\x3f\x74\xb6\x94\x79\x1e\x12\x8f\xfd\xcf\xff\xf3\x3f\xbf\xfb\x07\xcd\x2a\x6e\x74\x84\xd0\xf4\x72\xf3\xb0\xed\xc8\x00\x85\x63\x3f\x20\x73\x22\x95\xa6\xc9\x0f\x35\x02\x70\x77\x62\xc5\xcf\x8e\x52\xad\x6d\x01\x81\x88\x06\xe5\x28\x39\x6d\xdc\x04\x1b\x15\xce\xc8\x76\x52\xac\x2d\x7b\xfd\x27\x14\x18\xcc\xf3\x82\x20\xd4\xf8\xf1\x0a\x44\x59\x49\x34\xc6\xd0\x9a\xe8\xaa\x91\x7b\xef\xaa\x3d\x80\xfb\x34\x75\xf5\x6c\xda\x21\x7d\x2c\xab\xd9\xa5\x94\x50\x31\x59\xf6\x6d\x3d\xe6\x79\x61\xa8\xcb\x9c\x74\xf9\x35\x6a\x1b\x3d\xb0\x5b\x6d\xef\x36\x8c\x89\x45\xb8\xe9\xb0\xe7\x5a\x2d\x4e\x65\x26\xa0\x1e\x9d\x27\xf2\x83\xa4\x13\x9d\x1c\x56\x59\x61\x73\xc8\xa5\xc9\xf5\x37\x1a\xb5\x35\x2c\xa7\x6e\xfb\xd0\x10\x03\xe1\x18\x64\xdd\x54\x13\xb2\x9d\x6d\x27\x00\x1c\x5a\x59\x8d\x0c\xb4\x32\x63\xc5\x3d\xb7\x93\xe9\x4b\x22\x82\xd8\x09\x61\x52\x30\x7f\x0e\x9d\x47\xdf\x9e\x93\x90\x10\xab\xe3\x34\x9c\xfa\x2e\xee\xda\xf6\xe0\x09\x5a\x00\x2f\xd7\x3c\x7f\x66\x17\x47\x64\xcd\x3c\x2f\xe6\x1e\x26\x3b\x0e\x15\x1c\x71\x9c\x0f\xdf\x4b\x0c\x1e\xa2\x55\x2f\x18\x6c\xfa\x28\x9f\x9c\x90\x3a\xf3\x3c\xea\x13\x62\x2b\x81\x90\x0d\xe1\x6f\x38\xa1\xed\x61\x5c\xc3\x17\x4d\x3d\x31\x86\xe5\xea\xd1\x1d\x27\x32\xc0\x95\x6f\x03\xcd\xa9\x82\x61\x52\x0c\x9b\x93\x54\xfb\xdf\x98\x9e\x19\xea\x6f\xb6\xed\x8a\x60\x4e\xe3\x90\xd5\x2f\xb8\x58\xec\xcb\x65\x25\xe6\x58\x4a\x3f\xea\x9a\xa6\x1c\xf3\x24\x12\xf2\x86\x2d\x1f\xaf\x85\xf8\xdb\x16\xf3\xf0\x9e\x58\x18\x45\x3a\x73\xad\x73\xcc\xfe\xe0\x5d\x31\xca\x62\xd9\x0f\x4a\xbe\xc0\xc7\x56\x0b\x94\xd5\x8d\x56\x44\x9e\xe4\xc3\x6c\x0f\x05\x89\xda\xc8\xd6\xeb\xeb\xa3\x0b\x47\x43\x86\x29\x86\xce\x28\xf2\x1d\x1c\xbe\x2d\xf7\x87\xc7\xa5\x5b\x35\xb8\x17\x85\x30\x50\x82\xed\xd0\x41\x6d\x73\xec\x59\x8d\xa2\x87\x97\x95\xfd\x55\x78\x0c\xd1\xff\x4f\xe5\x31\xf8\xa4\xa2\xd3\xf6\x0c\x01\xed\xd9\x25\x06\xc6\x9f\x32\xe5\xd6\x0c\x91\x6a\x16\x1f\x86\x91\x41\x96\xc3\xb3\x8e\x95\x8d\x3e\xaa\x80\xd0\xaa\xed\xad\x5c\xa5\xa2\xe6\xa4\x72\x3d\x62\x1c\xe9\xe7\xac\x68\xbd\x7e\x07\x9f\xfc\x02\xd4\x63\x8e\x94\x94\x46\x26\x4b\xb8\x78\xdd\x3d\x4c\x04\x57\xb1\x13\x0f\xb4\xb5\x81\xeb\xd4\x77\xc8\xf3\x12\x65\x33\xec\xf5\xa5\x48\x7b\x2a\xda\xf5\xc5\x1f\x9f\x40\x32\x34\xee\x34\x4d\xce\x84\x30\x16\xf3\x3c\x10\x69\x1a\x76\x7c\x6d\x63\xe5\xf3\xb6\x07\xa4\x88\xb0\x86\x9f\x59\xdd\x58\xe0\xf4\xb0\x8b\xf2\xd3\x84\x75\x51\x36\x0d\x26\xb4\x6d\xb1\x06\xcc\x1f\xea\x32\x97\xeb\x6b\x53\x67\x12\x36\xcf\x7f\xb8\x66\x4a\xc1\x77\x42\x80\xd6\x2b\x19\xdd\xa4\x92\xa1\x48\x7a\x01\xac\x09\x1f\x04\x7b\xd1\xae\x2c\xe5\xd6\xda\x1d\xb6\x01\x12\xe4\x62\xc3\x9c\x23\x2f\xab\x11\x2c\xaf\xed\xa1\x54\xdc\x13\x90\xb0\x30\x50\xdd\xea\x7b\xa9\xd0\xd1\x92\x42\x54\x98\xab\xb4\xb8\x64\xe6\xf9\xbe\xef\xe1\x4a\xad\x0b\x61\xfa\x0d\xa1\x42\x4b\x3c\xab\x5d\x70\xf8\xf1\xda\x4b\x90\x0c\x16\x36\x3f\x48\x35\x33\x75\x85\xac\x33\xbb\x6b\x75\xc9\xaf\xb5\x25\x3f\x66\x9e\x1f\xfa\x54\xc3\xd9\xda\x0d\xf6\x7b\x76\x29\x5d\x43\x20\x51\xa4\xc1\x18\x07\x86\x58\x63\xf8\xfe\xfc\x90\xf0\xa0\x93\x0c\x51\x30\xfa\xc4\x7e\x48\xa4\xa7\x83\xf3\xbb\xec\x38\xb2\x7a\xda\x66\xc6\x29\x35\xe1\xc5\x2c\x6f\xc6\x07\x33\x89\xa6\xbd\x8e\x5a\x3d\xbc\x6e\x67\xfb\xd5\xfa\xc5\xdd\x1f\x44\x58\x04\xf0\xad\xbc\xee\x4e\x3a\x25\x8c\x8b\x9a\x69\x8e\x78\x8a\x3b\x19\x92\x99\xeb\x8c\xce\x67\x1b\x90\x4f\x04\xf7\x3d\xbb\x01\xad\x2d\x85\xda\xf0\x66\xa8\xe7\xa3\x6b\x27\xd8\x65\x83\x55\x04\x2e\x36\xd6\x36\x06\x3a\x61\x23\xca\xf3\xf9\x5a\x64\xcd\x6d\x91\x67\x86\x59\xbf\x6d\x25\x5a\x85\x47\x27\xe3\x7b\xc1\xa8\x2f\xac\x33\x3c\x8c\xa7\xdd\x56\x3d\xcb\xf3\x45\x59\xe3\x4b\xac\xc7\x8b\xe2\xbf\x07\xa8\xda\x81\xe6\xa7\xcd\x92\xb5\xe7\x4b\x53\x74\xb7\x15\x58\x36\x43\xdf\xdd\x21\xc8\x10\x15\x75\xfc\x00\x0d\xa4\x2f\x52\x88\xe6\x88\x84\x2a\xc4\xb1\x3d\xb0\x86\x59\x12\x99\x5f\xdd\x48\x19\x7d\xe6\x44\x05\x5c\x17\x3c\xe5\xc8\x82\xa8\xbd\x46\x84\xd4\x0c\x47\xad\xe9\x9f\x86\x4a\xa5\x56\xaf\x16\xe4\x90\xef\x9b\x79\x3e\x0b\x19\x96\xc4\x3d\x95\x47\x23\xde\x3f\xf6\x99\x87\x6f\x92\x45\x34\x11\x96\x3b\x17\xce\xb7\x45\x79\xe6\x99\x06\x42\xaf\xc7\xf9\xa7\xd1\xd0\x60\x91\xb0\x3e\xdc\xf3\x6d\x55\xd4\xc8\x2e\x54\xaf\xd5\x6c\xc3\xc4\x5b\x8f\x20\xc5\x74\xe7\x9e\x2e\x51\x3c\x5a\xb2\x51\xa8\x40\xba\x6a\xca\xc9\xfd\xc4\xe7\x42\xf3\x6f\x9e\xcb\xa2\xed\x7f\x60\x28\xbd\x37\x3e\xb1\x48\x6c\x3d\x82\x64\xd9\x74\x60\xad\xed\xa6\x18\xbd\x03\xce\xcd\x17\xcb\xb5\x51\xc6\xb0\x6f\x50\xf8\x51\x04\x96\x6d\x22\x13\x5f\xb8\xfe\x6d\xe7\x28\x49\x9d\xee\xde\xcf\x47\x80\x7d\xc5\xe4\xf8\xc9\x45\x1c\x28\x3d\x95\x6d\xd0\xee\x09\x2d\x76\x77\x45\x1e\x21\x92\xca\xde\xd4\xe3\xdd\x5a\x21\x81\x62\xa4\x67\xfe\xd8\x39\xa1\xcc\xf3\xc1\x67\x81\x6f\xc5\x33\xb5\x72\xae\x06\xa2\x0e\x64\xaa\x26\xcd\x04\x1f\x98\x8e\x6a\xcf\xa0\x2a\xeb\x9b\x3b\xa5\x92\x5c\xd3\xd7\xe8\x0c\xf3\xe6\x9a\x5b\xed\x8d\xa1\x55\x18\xf8\x91\x40\x52\x8e\x76\x1f\x5e\xe4\x65\x6d\xdf\x5f\xe0\xd3\x40\x1a\x77\x6d\x56\xd7\x78\x27\x83\x87\x09\xfc\x84\xc7\x26\x2d\x63\x26\xdb\x7d\x85\x53\xdb\x4d\x52\x63\x2d\xa1\xf8\x57\xeb\x42\x57\xa3\x2e\x01\x13\x89\x15\x68\x09\x67\xd5\xd1\x2e\x3a\x41\x20\x7c\x62\x35\x6e\x58\xfd\xa6\xfd\xd4\xd1\x03\x04\x92\xe1\xd8\xc2\x0d\x06\x71\x4b\xac\x58\x17\x73\x38\xb1\x5c\xad\xd5\x16\xc4\xb5\xaa\xef\x55\x50\x3f\x91\x8f\xb2\xe7\x84\x20\x69\x9f\x7d\xb6\x59\x3f\x3d\xad\x17\xeb\xd5\x8b\x63\x55\x9a\x3d\xaf\x5f\x5f\xf6\xf6\x06\xc3\x88\x69\xfd\x38\x4c\xb3\xea\xe1\x30\x73\x8d\x32\xc2\x0c\xcd\x16\x64\x26\xca\xc2\xfd\x0c\x54\x76\x85\x73\x28\xc5\xb6\x65\xc5\x9b\xce\xb5\x36\x65\x75\x5b\xfe\xbc\x64\x95\xa9\x5f\xf6\xed\x63\x46\x41\x12\xe9\x5c\xb3\xb3\x8f\x90\x7d\x0e\x99\x70\xfa\x39\x93\xe1\xf8\x08\x22\x60\x48\x1f\xf6\x3c\xfb\xed\x30\x6f\x6f\xfd\xf7\xc3\xac\x7d\xa6\xd9\x7e\xf9\xd0\x97\x6b\x67\x5e\x40\xb8\x40\x07\xdd\x41\x3a\xda\x01\xac\x25\x95\xc7\xb0\xd3\xee\x55\xc5\x61\x84\x0b\xcf\x25\x6b\x78\xe9\xb6\x8b\x20\x0e\x19\x31\x92\x2e\xc7\x52\xb2\xaf\x16\xa0\x20\x4e\x98\x4e\xf0\x8a\xf2\xdc\x9f\x17\x41\x9c\x46\x38\x74\x32\x30\xa9\xbe\xf6\x37\xa9\xe9\x30\x77\xd7\x42\xa1\xc4\xf7\xf0\x08\xc9\xf0\x6e\x1a\x60\xe7\x2e\xd2\xdd\xdd\x2d\xf5\x24\x17\x26\x42\x92\xbf\xf7\xc0\x0f\x6d\x5b\x44\x98\x49\x76\xb1\xea\x78\x08\x0e\x59\x71\xb9\x8e\x47\x33\x25\x02\x21\x70\xec\xd2\x9a\x3b\x77\x11\x02\xe6\x05\x09\x09\x71\xe6\xcd\x75\x91\xe3\x80\x0d\x00\x9b\x49\x34\x64\x8e\x32\x16\xf4\xa6\x7d\x98\xb5\x1a\x9f\x8d\x31\x2d\x24\xe6\xd0\x87\xbf\xb2\x2a\xc3\x34\xe5\x27\x51\xeb\xf6\x20\xa9\xa3\xce\x82\x75\xdf\x71\x0a\xfe\x6d\x9f\x9c\x85\x61\xd2\x25\x71\x36\x98\x18\xee\xec\xa7\x80\x85\x91\xa6\x97\x7e\xcb\xda\xcd\x44\xcf\xf5\xf9\x6d\x35\x99\x46\x67\xad\xdb\xaf\xf1\x32\x77\x1c\x19\x83\xcc\x00\x76\x8c\xd1\xe3\xbf\x16\x63\xe3\xd4\x75\x60\xc4\x77\xe2\x7e\xe3\x99\xcf\xa9\x2e\xe8\x78\x9e\xbd\xcc\xbe\x2d\x9f\x97\x2f\xfb\xc3\x7e\x39\x7b\x3e\xec\x5e\x37\x9b\xa7\xdf\x7b\xc9\xbf\xb6\x6f\xca\x98\x18\x30\x9d\xb6\x2b\xda\xfc\x36\xe9\x3d\x04\x22\xd2\x8a\x51\xff\xe5\x3f\x77\x18\x49\x1b\x0c\x32\x11\x71\x54\xf5\x38\x95\xb9\x65\xe0\x22\xae\x8d\x04\xb8\x3b\xb5\x4b\xd9\xaa\x68\xe0\x08\xd5\x2f\x70\xd3\xf9\x67\xdb\x45\xe9\x62\x26\x05\xb0\x71\x1b\x7e\x20\x83\x50\x53\xd4\x5e\xf9\x62\x68\x0b\x04\x90\x26\xd2\x84\xd7\x66\x72\xf4\x12\x42\x8f\x84\xa9\x31\xdc\xd7\xcd\x09\xaa\x67\x76\x19\x30\x7e\xd8\x6e\x3c\x01\x8d\xd7\xc6\x98\x46\xed\xe2\x2a\xa1\x9f\xa4\x5c\xb3\xe0\xbe\xeb\xc0\xb2\xf9\x3d\x88\x3d\x74\xb3\x3e\x00\xde\x36\xa5\xbd\x99\x30\xf2\x74\xb6\xf7\x5a\xa8\xaa\xfc\xd3\xbd\x94\x30\x0a\xb5\x90\x07\xb3\x3c\xac\x23\x03\x32\x8c\x88\x12\x06\xc6\xa1\xf9\xf7\x7b\xe6\x50\x68\x2b\x4e\xde\xcb\xfb\x5a\xf7\x89\x24\x05\xf3\x42\x12\xa5\x76\xcf\xdc\xed\x9f\x37\x77\xf4\x6b\x6d\x17\x02\xc2\x90\x00\xf6\x33\x97\xff\x1c\xf7\xd2\x7c\xa8\x52\x6b\x79\x8d\xcf\xc1\xb5\xfc\xc6\xc5\xc9\x30\x30\x2f\x8c\x95\xa7\xcc\x3b\x7f\x45\x80\xc7\x6f\x9b\xd9\x70\x04\x85\x34\x96\xca\xe6\x74\xea\xb7\x39\xb2\x67\xad\x1e\x0c\x0c\xc0\xf6\x49\x28\x42\x19\xd1\x7e\xd7\xc5\x6a\x9f\xe6\xa2\x98\x17\x26\x04\x70\xa7\xae\xaf\x17\x0d\x6c\x68\x2d\x90\xc7\xaa\x3c\x7f\x05\x36\x6b\x8f\x63\x4a\x5b\xbe\xd0\x2c\x2c\x11\xff\x1c\x9a\xfa\x13\x9c\x32\xf3\xc2\x34\x48\x70\x80\x1f\x5c\x2d\xcf\x67\x66\xfd\xe8\x38\xd0\x55\x1e\xa8\xa4\x06\xcd\x4b\xe9\xb2\x9b\x0e\xd3\xc5\xbc\x90\xfb\x80\x6c\x24\x87\x23\x34\x3d\x13\x69\x74\x2e\x1e\xc7\x18\xad\xfa\x23\xcb\x73\xa8\xb2\xeb\xb9\x0f\x48\x63\x5e\x28\x0c\xa0\xa8\x9d\xd0\xae\xae\x78\xc3\x2a\x76\xff\x3a\x26\x2a\x23\xda\x13\x08\x8f\x07\x96\x22\xd2\x24\x81\xc7\xe8\x06\xe6\x85\xd2\x53\xa8\x16\x8e\x6c\x19\xc6\x81\x1f\x87\xc0\xdb\x6e\xca\x23\x1a\x26\x52\x34\x20\x9f\x58\xe1\xe6\x11\xf0\xc4\xd3\x33\x0f\xd1\x6d\x66\x56\xb4\xdf\x6d\x87\xa5\xa3\xd7\xea\x4e\x5f\xe8\x53\xed\xe1\x4f\x51\x15\xbd\xa9\xa4\x02\x12\x99\xd5\xe2\x07\xf0\xba\x35\x49\x9a\xd7\x2a\xb3\xb7\xa3\xe2\x30\x64\x36\xfc\xf9\xa4\x45\xf7\x46\x4b\x8a\x62\x5a\x56\xa2\x83\xab\x8e\xde\x89\xe2\x91\x51\xaa\x7d\xd3\x86\x72\xef\xf3\x46\x3e\x15\x69\x47\x98\xda\xba\x40\xcd\x94\xb3\x75\xf7\xc5\xa3\x20\x90\x9a\x31\x69\xfd\xb4\xde\x1e\x5e\xd6\xfb\xc3\xec\xd7\xd9\xea\x69\x36\x7f\xb2\x61\xaf\xb6\x8b\xc5\x68\xcf\x2e\x19\x6e\x41\xa3\x73\xc4\xca\x92\x1e\xb4\x36\x51\x57\xec\xd3\xb6\x25\x1c\xf7\x7e\x43\x29\x58\x6b\xcd\xa6\x1e\x8f\x8d\xed\xc7\x53\x4c\xa1\x15\xf0\xb1\x28\xcf\x53\x02\xf0\x83\x95\x28\x0a\xe3\x14\x57\x03\x26\xe5\xbc\x2c\xdb\x5d\xec\x5f\x7d\x61\x31\xdb\x8b\x2a\xc4\x6d\xe8\x12\xb2\xa1\xde\xe4\xe8\x45\x84\x9c\xa3\xc9\xa6\xb7\xe3\x79\x79\x3d\x9e\x9a\x55\x81\x05\x7b\x9b\xaa\x3c\xb6\x43\xdc\xf4\x8c\xda\x27\xee\x41\x08\x35\xad\xde\x27\x5e\x58\x14\x71\x0f\x85\x0e\xef\x5c\x0a\xd3\x4e\x02\xae\x78\xaf\x80\xe3\x11\x8c\x92\x7d\xdb\xa6\x24\x12\xd4\x0e\x02\x97\x13\x8e\x6d\x14\xa7\x1c\xbf\x22\x1a\x4f\xfb\x12\x95\x8a\x47\x1f\x29\x16\x44\x99\x12\x3e\xa3\x9b\x25\x47\x51\x93\x88\x06\x32\xc6\x6f\x85\x4c\xd3\xab\x62\xf6\xc0\x6e\xf6\x56\x92\x94\xa1\xc7\x23\x2b\x5d\xba\x63\x7f\x4f\xc3\x04\x51\x92\xd7\xc2\x01\xd6\x6c\x75\x02\xf3\x22\xe6\xa5\x48\x9f\x69\xc8\xe9\xa6\xe1\x36\xb6\x2f\x49\x91\x68\xa4\x62\x85\x7c\x2e\xdd\x00\x62\x31\xc3\x18\x19\x73\x80\x98\x4d\x6f\x57\x88\x58\x42\x84\x67\xe1\xee\x8f\x7a\x73\x1c\x3e\x15\x0f\x05\xa6\x22\xcf\x59\x01\x87\xff\x30\x09\x87\x71\x78\x3f\xe2\xd2\x0b\x94\x0d\x9c\x62\xad\x3c\xce\xad\x61\x27\x21\x42\xd4\xa7\x3f\x30\x29\x1f\x40\xb1\x6b\xde\xac\x2f\x80\xb4\x4e\xf3\x9b\x01\x25\x4e\xe1\x73\x19\x96\x43\x08\xd2\xb3\xcd\x30\xc5\xa0\x0d\x86\x2f\x5d\xa2\x48\x46\xc2\xea\x2c\xb7\x96\xd3\xa2\xcc\x73\x76\xf0\x3c\xbf\xfd\xdf\x20\xc1\x12\x49\x46\xd1\x42\xd8\x2d\x7f\x7b\xe9\xdb\x4d\x11\x84\x11\x4e\xc0\xaf\xd8\x9d\xbe\x8c\xcb\x47\x8a\x6a\xf2\x95\xe7\xe7\xf5\xf0\xd4\x4a\x00\x41\x8a\x8b\xd5\xcb\xc3\x7c\xfd\xf0\x7b\xbf\x91\x78\x29\xc5\x46\x43\xd9\xb8\xd5\xdc\x4a\xce\xca\x1a\xbc\x20\xe2\x49\x9d\xc7\xd5\x69\x26\x8d\x90\xb5\x36\x0c\xf1\x53\x8d\xb0\x9f\xaf\xf7\x87\xe5\x93\x36\x39\x03\xd7\xc8\x63\x44\x0a\x62\x7e\xe5\x40\x0e\x8e\xef\x8a\x79\x24\x10\x24\x35\xba\x83\xe8\xf0\x39\x80\xe2\xe7\x15\xdb\xed\x51\xc0\xb0\x3c\xf1\xa3\xca\x1a\xd8\x35\x57\xe5\xbc\x83\x7f\x4e\xbd\x1e\x12\x28\x5d\x4e\xdf\x0e\x0b\x2d\x2e\x3e\x7a\xb8\x50\x00\x26\x6a\x2d\x00\x7c\xdb\xbb\xc5\x10\x38\x86\x40\xd6\x9b\xa5\x8e\x42\x1e\x76\xfb\xd9\x2f\x76\xe9\x25\x51\x22\x03\x65\x00\xa8\xd6\x15\x79\x2a\x6b\x8c\x55\x5c\xae\x4d\x57\x89\xda\xf6\x15\x1c\x74\x66\x6c\x63\xc8\xfe\x6d\x0b\xa1\x89\x6f\x2c\xa7\x5d\x56\xc1\x78\xfd\x26\x44\x46\x08\xe4\xac\xae\xda\x26\x89\xbc\xe9\xb0\x07\x21\x4a\xb3\x1f\x1c\x2e\x5a\xee\x4a\x83\xd2\x5f\xe0\x63\xf4\xc4\x71\x14\xe3\x6e\x64\x00\x33\x8f\x00\x3d\xe4\x68\xdb\x1e\x87\x68\x83\x3d\xfd\xef\xe2\x7f\xdd\x6f\x69\x28\x34\x60\x09\x58\xb5\x3b\x83\xb5\x7d\x09\x0d\x14\x96\xaa\x36\x59\x93\x23\x23\xdd\xf0\xe6\x29\xa5\x71\x0f\x51\x06\xe2\x64\xe3\x22\x5f\xb9\xbf\x84\xa6\x09\x92\x0d\x66\xa2\xdc\x35\xe5\xe5\x02\xf2\x19\x0b\x26\xf3\x9b\xbb\xae\x64\x5a\xc2\x2c\x67\xe2\xad\xdd\xb3\xfb\x88\xc3\xd1\xd9\x12\x2f\xc5\x85\xda\x39\xf1\x08\x01\xd1\x09\xf7\x1e\x8a\xbb\xed\x29\x00\x4d\x96\x76\x89\x5e\xb0\xfa\x64\x43\xa5\x24\x55\xaa\x07\x97\x7a\x81\x8f\x7d\x79\xad\xd8\xb9\xa7\xe7\x68\x6d\x52\xc2\xfc\x00\xbf\xa7\x01\xf1\xee\x1a\x60\xb9\xbd\xfb\x60\xb0\x2c\x10\x46\x3d\x8c\x86\xfc\x6b\xff\x34\x61\x67\x11\x9e\x00\xd6\xd3\x1e\xec\x02\x3d\xb0\x49\x08\xe7\x2c\x8a\x1d\x46\xca\xa0\x0c\x90\x05\xb3\xf7\x44\x22\xa2\x68\xf0\x67\xa2\x0c\x9e\xd9\x4f\xf7\x33\xe5\xf8\xd9\x9c\x44\xc4\xbe\x1c\xd7\x64\x99\x9e\xd2\x0b\x51\x52\xc2\xa0\x67\x7a\xe1\x44\x22\xbd\x38\xc1\x4c\x7a\x79\x2d\x4c\xae\x00\xb7\xe7\x5f\xa1\x6e\x9c\x8d\x41\xc0\x97\xdc\x04\x47\x91\x5f\x5f\xb9\x9c\x06\x81\x90\x73\xcf\x8a\xc5\xd6\x99\x98\xb3\x3c\x2f\x9b\xd6\xdb\x0e\x3d\xcc\x73\x0f\x07\x13\x24\x01\x16\x2a\x9d\xca\x8f\x67\x56\xf4\x31\xd7\xcc\x23\x4a\x68\x07\x7f\x51\x66\xc5\x53\xd9\x34\x23\x03\x8d\x28\x21\xa0\xcf\xe4\x74\x8f\xcd\x1b\x7b\x17\x71\xfb\x81\xda\x53\xfe\xb1\xdf\xcf\xbf\xa0\xf9\xed\xc7\x0d\x62\x4f\x46\xe8\x7b\xfe\x92\xe5\xf9\xee\x23\x6b\xc4\x69\x59\x1c\xd9\x71\xc8\x22\xd4\xf6\x03\xcd\x56\xa8\x79\x86\x4c\x25\xb9\xff\xb5\x33\x11\xfb\x94\x49\x57\xcd\xf0\xcc\x7e\xf6\x2a\x19\xda\x56\xe0\x4c\x97\xc4\x95\x97\xb2\x06\xc3\xdc\x35\xba\x6e\x10\xa7\xa1\x41\xdf\x3d\x96\x9a\xa0\x4a\x7f\x34\x13\x5e\x1d\xbe\xf2\x38\x48\x08\x56\x7d\x2c\x4e\xac\xca\x9a\xdb\xaa\x40\x6b\x0b\xea\x7a\x78\xe9\x40\x6a\xf1\xda\xfd\x7a\x3f\x7b\x3a\xec\x66\xfb\xf5\xee\xbb\xcd\xb1\xc6\xa1\xd4\x62\x12\x28\x21\xf8\x0f\xfb\x8e\xff\xe9\xfe\xe8\x4f\x89\x38\xf2\x75\x66\x5c\x27\xae\xda\x8d\x7e\x32\xcf\x18\x47\x51\x82\x71\x92\x79\xf9\xf6\x76\xdb\x94\xe5\x9c\x9d\x7e\x5c\xff\xfc\x0e\x95\x1d\x5c\x31\x61\x01\xd6\xb8\x77\x6b\xf3\xe3\x6c\xb5\xff\x7e\xff\xbd\x47\x2f\x39\xf6\x52\x94\xc0\x31\x3c\x55\xbb\x9c\xbd\x4f\x6b\x37\x31\x2f\xa6\x91\x8f\x89\x30\x5d\xe1\x64\x82\x57\x66\x69\x83\xfa\x1f\xa3\xe0\x4e\x9c\x44\x81\xf1\x88\xce\x2c\x2b\xba\xa4\x66\x9c\x40\x22\xf5\x35\x8b\xf7\xec\xde\x58\xfd\xe4\x4e\x13\x90\x9c\xf4\x93\xee\x56\x4b\xce\xb4\xa7\x44\xe9\xbd\x0f\x73\x2e\xe6\x3d\xd6\xbd\x56\xe1\xd4\x22\x56\xa2\xb4\x95\x0f\xcc\x8b\x99\x88\x31\x1c\x93\x9b\x75\x75\x0b\x82\xf5\x98\x4b\xee\x90\xeb\x78\x08\xa0\x97\x31\xdb\x2f\x16\xba\x72\x31\xef\x1e\x8f\x53\xe0\x5e\x8f\x07\xc3\x04\x85\x3f\x95\xe1\x61\x5e\x2c\x08\xc3\x7b\x3f\x97\x45\x73\xca\x6f\x7d\xab\x32\x16\x4c\x0f\xa8\x1e\xbc\x6e\x87\x10\x32\xf9\x55\x85\x05\x1e\xc8\x71\x42\x5b\x45\xb8\x6a\x3a\x7b\x1a\x0b\x90\x58\xf9\xb1\x5d\xee\x96\xdb\x5f\x97\x87\xa7\xf5\xe2\x97\xc3\x7e\xf5\x6c\x77\xfe\x58\x7a\x09\x82\x09\x44\xbb\xf5\x37\xee\x57\x53\xa3\x7e\xac\x98\x80\x9e\x98\x45\xdb\x24\x63\x6c\x82\x33\x54\x47\x28\xc4\xed\x31\xbf\xd6\x27\xd7\x0a\x11\xea\x39\xb6\xc6\x75\x32\x78\x86\x64\xb0\xb8\x80\x97\x22\x90\x7b\xa3\x8b\xbc\x77\x23\x1c\x72\xdb\x83\x24\x18\xd3\xcb\xea\xad\x0e\xe7\xca\xc7\xb2\x5a\x94\xe7\x4b\xce\xb2\x82\x8d\x13\x11\x31\xa8\x48\x19\xfc\xbf\xfe\x1a\xe8\x51\x85\xe6\xbe\xa8\x1f\x88\xd0\x40\xa5\xea\xad\xd5\x53\x71\x6d\x12\xd1\xf3\x7d\xa6\x76\xd3\x14\xb4\xae\x91\x5e\xf1\xbf\x37\xb9\x30\xc1\x45\x0d\xd7\x9e\x40\xa8\xb7\x47\xc4\x9c\xda\xc8\x85\x8e\x69\x98\x6a\xcd\xfe\xee\x4c\x5b\x5b\x0e\xe5\x28\xe4\xfb\x80\x82\x94\x79\x34\x0a\xe2\x58\xab\xc2\x4c\x81\x25\x06\xef\x88\x46\x92\x68\x7e\xd4\xc2\x40\xef\x3b\xc8\x30\xf3\x28\x49\x35\xcd\x3f\x52\x80\x95\x45\x63\x81\x80\x93\x23\x8a\x12\xf0\x63\xd3\xfb\x7a\xf9\x74\xda\x76\xf3\x84\xc6\x52\x6b\xa7\x14\x65\x93\xa9\xdb\x52\x6f\xec\x3b\xc8\x73\x0d\x72\x98\xbe\x4a\x0c\x01\xa2\xd5\x1f\x46\x2c\x4f\xcc\xa3\x34\x0c\x7c\x13\xbd\x6f\xaa\x4c\x34\xaf\x45\x93\xe5\xae\x91\x70\x0c\xdf\xcf\x5e\xed\x06\x66\x1b\x62\x46\xd2\x1e\xe9\xa5\x59\xcd\xfb\x2b\x31\xa5\x54\xcb\x53\x64\xa2\xd4\xa3\x62\x59\xc8\x87\xce\x38\xa6\x94\x07\x69\xd2\xbb\x32\xc2\xc6\x6d\x9b\x88\x51\x12\xec\x98\xbd\xc3\x36\x3b\x9e\x1a\x2c\x42\x1b\x7e\x86\x44\xd1\xd0\x90\xa9\xe3\x1a\x53\xe6\xc3\x88\xbc\x19\xf4\x34\xf5\x04\x37\x55\x9a\x8f\x15\xc0\x9f\x13\x78\x4b\x86\x94\x8f\xa1\x0e\x29\xb5\xa6\xef\xbd\x9a\x81\xe9\xc6\x03\x2f\x56\x76\x07\x75\x38\x7d\x67\xac\x50\x1e\x44\xb1\xa6\x51\x28\xdf\x61\x35\x26\x8f\x32\x9d\x84\xaf\xe5\xb3\x6a\x1c\xad\xef\x77\xc0\xce\xb6\x4b\xa4\x2c\x97\xde\x9e\x5d\x1c\xa5\x86\xbd\x8c\xa0\x5a\xa2\x70\xf9\xf2\x80\xeb\xca\x6e\x3f\x7b\xde\x74\x8d\x02\x6c\xb5\x61\x2f\x8a\x44\x45\x02\xb8\x4a\x88\x8e\xcc\xe9\x2e\xdd\x4f\x45\xea\x23\x8b\xb0\x96\x33\x71\x4f\xb8\x3a\x5f\x72\x84\x9a\x30\x57\x44\x6e\x0e\x90\x2c\x49\x8c\x62\x69\x5e\xde\x85\x5f\xcc\x22\x34\xfa\xd5\x6e\x68\x54\x32\x86\xf2\x22\x05\x7c\xd8\x54\xea\x70\xe4\x02\x93\x34\xb4\xe4\xfb\xb9\xd4\x75\x36\x23\x5c\x11\x55\x1e\xc3\x91\xf4\xb0\x7c\xdc\xae\x77\xfb\xc3\xec\x71\xbf\xdc\x1e\x5a\x7f\xf6\xbb\x4d\xc4\x51\x15\x32\xa2\x27\xf8\xac\x69\xa0\x90\x63\x83\x8a\x2a\x63\x4b\xbe\x5e\x8e\x36\xfc\x66\xd5\xf8\x83\x10\x07\xf9\xf3\x84\x40\xd9\x57\x54\x31\xed\x49\x89\xd2\x85\x9f\x50\x80\xca\x44\xc6\xaa\x9b\x5b\x1c\x55\xa2\xfc\xb4\x03\xe4\xb4\x8b\xf1\x40\x1f\xa7\xed\x22\x3c\xcd\x25\x5f\xbe\xc3\xbe\xdc\xee\x6c\xea\x25\xf1\x82\x08\xe9\x56\x74\x00\xab\x2c\xf3\x81\x39\x95\x78\x61\xc2\xc1\x0d\x30\x24\x68\x90\x56\xab\xa7\x07\xb1\x6e\x7b\x8a\xc4\x52\x82\x3f\xb1\x33\x2f\x9f\x4b\x09\xf9\xf0\x1b\x24\xbe\x12\x78\xa3\x9d\xbc\x80\x8a\xed\x95\x02\x2f\x40\x78\x74\xbb\x02\x7d\x5a\x7e\x32\x3c\x5d\xe0\x73\x0c\x85\x3a\x0a\x9f\x49\x03\x2d\x09\x42\xdf\xf7\x3b\x36\x1c\x4b\xbd\x3e\xbd\xe3\x26\x41\xaa\x77\x36\x99\xbd\x67\xad\xd5\xca\x6f\xde\xe8\x29\x02\x91\x20\x95\xca\xc3\x72\xf6\xf0\xb4\x7a\xb1\x5b\x71\x12\xfa\x0a\xe5\x33\xe7\x2f\xf3\xf9\x5f\x23\x58\x92\x30\x06\x4b\xf7\x6b\xee\xa4\x82\x4f\x36\x8a\x24\x14\x1c\xd9\xdb\x8c\xb0\x5f\x3d\x16\x47\x1d\x9e\x39\x32\x44\xdd\x07\x63\x38\x6e\xd1\x62\xfe\x94\x8a\xbd\x3d\x82\xb2\x74\x54\xa4\x3d\x21\x82\xdc\x76\x64\x0a\x3b\x62\x9c\x64\xc2\x80\x9d\x08\x3a\x26\x11\x00\xed\xd8\x88\xb6\x9a\x60\xe0\xd8\x23\x57\x36\xfd\x88\x9f\x06\x89\x31\x3d\xa1\x6a\x0e\x9a\xa6\x2b\x2b\x8b\x43\x53\x1e\xfa\xf8\xed\xe1\x2d\x91\x80\x23\xd0\x6a\x77\x2b\x2c\x10\xbe\x97\xd9\x4a\x48\x9a\x20\x08\x16\xce\xd9\xfd\x10\xd6\xb0\x13\x39\x01\xc2\x67\x5e\x42\xe3\x08\x8f\x64\x15\x8a\x0c\xf4\x9d\xd9\x84\x52\x2d\x31\x7b\xee\xd1\x1c\xb5\x3f\x27\x21\x5a\xfa\xcf\xe5\x7b\x06\xa2\x83\x7a\x27\x94\x09\x24\x73\xba\x40\xf5\x00\x4c\x3e\x65\x45\x77\x0c\x03\xc3\x15\x64\x62\x02\xda\x5e\xd3\xce\xf3\xac\x90\xad\x8b\xff\x69\x82\x2c\x49\x43\x50\xc1\x1d\x2b\x88\x6d\x24\x80\xc1\xf2\xa7\xf2\xf8\x6a\x32\x82\xa6\xc4\xe8\x73\x29\xba\xf6\x30\x05\x18\x21\x7a\xcb\xf2\xfc\x50\xa3\xeb\x68\xcf\xc8\x98\xde\x6a\x5f\xe0\x43\x5f\x6a\x26\xff\x73\xad\x9b\xf1\xae\x93\x70\x3f\x42\xdc\xbe\x21\xe9\xd1\xd6\x53\x97\xb5\x4e\x78\x18\x22\xe1\xc1\x72\x61\x7f\x11\x26\x04\x7c\x84\xe6\x31\x63\xfd\x82\x95\x7f\xdc\xcb\xb7\x31\x2f\x91\xa1\x42\x14\x08\x9a\x4c\xe5\xe5\xaf\xd2\x18\x63\xcd\xe4\x7f\x0e\xf7\x8f\x44\x2a\x4a\x3d\xb7\xa5\x6d\x75\x3a\xe8\xf6\x58\x95\x67\xfb\xf7\xe8\x09\x21\x54\x9e\x29\xe7\xd0\x96\x4b\xfd\x5c\x76\xa8\xff\x04\x12\x1e\xc6\x76\x7b\x7f\xbc\x16\x03\xab\x24\x01\xe9\x63\x46\x35\x2b\xb2\xe6\xb5\xa8\x1d\x13\x20\xf3\x12\xe5\x73\xcf\x18\x44\xb3\xaa\x7a\xcd\x8a\xe6\x31\x83\x5c\x06\xae\x3d\x89\x70\x96\x60\x98\x02\x2f\xfc\xa3\x62\x97\xcb\xdd\x17\x50\x82\x59\xd2\xcd\x57\xc7\x68\x14\x0d\x5f\x62\xea\x85\x14\xb3\x7d\x43\xea\x19\x73\xa9\xd4\xf7\x34\x82\xb5\x2c\xf2\x9b\x5d\xa7\xd3\x20\x00\xe4\x73\x40\x79\x10\x9b\xe7\x1c\x63\xa9\xd2\x80\x32\xd4\x85\x73\x09\x67\x69\x6c\xef\x7a\xdc\x31\x15\xd2\x50\x9f\xbe\x3b\xbe\xd8\xf6\xb5\x8f\x23\xc0\xd3\x63\x35\x0d\x18\x04\xc4\xe2\xe3\x5c\x59\x98\xbd\xd9\x88\x69\xda\xa0\xd6\x09\x61\xd2\xce\x8b\x94\x44\x2c\xea\xec\x97\x25\xab\x5a\x8b\x68\x7c\x67\x71\x48\x34\xa3\x56\x97\x69\x5b\x2d\x66\x9b\x7f\x8c\x07\xd4\xf4\xb8\xb3\x27\x49\x62\x11\xf5\x18\xa4\x07\x21\xb1\x34\x06\x8d\x1f\xe1\x79\xb3\x85\x86\x65\x05\xc8\x99\xb0\x08\xd2\x94\xa6\xa1\x66\x65\xd0\x58\x15\x70\xe9\x92\x34\x61\x5e\x64\x39\xd2\x58\x21\xad\x80\xe9\xca\x8e\xbe\x34\x8d\x69\x9a\xda\xb7\x32\xbf\xe6\xb9\xfb\xa6\x29\xd5\xb8\xb0\xed\xfa\x69\x79\xd8\xce\x67\x8b\x9e\x64\x5f\xdb\x9c\x46\x38\x6c\x97\xbb\xf5\x66\xb8\x90\xa6\x29\xd3\x55\xd3\x46\x47\x5f\xcb\x00\xd8\x36\xe9\xd9\x62\x12\x2c\x0d\x59\x15\xad\xf7\xff\x09\x80\x23\x4d\x21\xe6\x23\xad\x4e\x9b\xe4\xdd\xb6\x0b\xfe\xe8\x43\x30\x8f\x60\x81\x8e\x51\xf0\x82\x29\xda\xf3\x4f\x46\x07\xf3\x21\xd0\xc0\x4f\x96\xb7\x86\xc5\x1d\x12\xf2\x93\xc5\xa2\xbf\x9d\xa6\x0c\x3c\xe4\xd2\x67\xbc\x7e\xc8\x7a\x51\xfe\xe1\xa5\x78\x98\x22\x7a\x10\x71\xec\x8b\xeb\xe5\x2f\x54\x2f\x07\x57\xe0\x14\xd0\x8c\xc7\x69\x68\xdc\x4e\xc7\xe9\xca\xbc\x54\x08\x86\x50\x76\x64\xe2\xb4\x93\x6e\x52\xab\xa6\xed\x0c\x9a\x69\xf5\x50\xeb\x64\xd0\xd7\x91\x88\x54\x46\x01\x22\x49\x5e\x99\xe8\xb8\x3e\xfe\xaa\x8c\xeb\x2f\xfe\xb5\xab\x6a\x2a\x23\x9d\x23\xd1\xac\x42\x7b\x38\x5f\xee\xd9\xea\xdb\x6e\xa9\xf0\xd2\x61\xc5\xf5\xb6\x6f\xa1\xf5\x8a\x70\x52\x29\x65\x64\x80\x60\x88\x7a\xef\x1b\x12\x3d\x37\x2c\x95\x52\x45\x43\x09\xad\xed\x91\x8f\xaf\x0b\x01\x86\x8d\x3f\x61\xfa\x19\xcc\xf4\x09\xac\xb3\x7d\x4a\x08\xa5\x67\xb9\x47\x4e\x59\x2e\xf5\x1c\x1f\x98\x95\x29\xa4\x02\x0b\xa4\x30\xc6\x35\xcf\xa4\xbc\x2b\xcb\x48\x55\x1c\xa7\x66\xb7\xfe\x06\xcd\x73\x59\x00\x16\x63\x7e\x51\x0e\xdc\x1e\x94\xc4\xe8\x3f\x63\x3e\xdc\xc9\xbf\xda\x81\xa3\x78\xd0\x53\xc5\xed\xe5\x82\xbe\x1c\x95\x13\x64\x4d\xcc\x63\x9e\x0c\x43\xab\x8c\x30\x7b\xf9\xfd\xf0\x63\xf6\xf4\xb4\xb4\x7e\x04\xf3\xbd\x24\xe8\x34\x5c\x34\xf0\xf1\xd7\xd7\xcd\x74\x4c\x8d\x05\x9c\x58\x67\xec\x93\xfa\x34\x16\x08\x1f\x5f\x58\xeb\x33\xfe\xca\xf2\x5d\x76\x67\x8c\xb2\x40\xc5\x81\x19\x36\x16\x62\xbf\x9a\x2c\xbd\x65\x1e\x0b\x43\x0a\x26\xae\xb3\x83\xe6\x7a\x19\x6f\xc9\x2c\x04\x11\x4b\xcb\x63\x82\x29\xf6\x46\xe3\x40\x4e\xac\x1a\x5f\x38\x12\x3c\xd6\xa1\x8e\x77\xa8\xd8\xd0\x65\x62\x91\x4c\x11\x10\xc6\x59\x23\x4e\x6e\xb2\x6e\x77\xf3\x7b\x73\xd9\x1c\x41\x84\x44\x8d\x8d\xf5\x1b\xbb\x64\xfd\xe8\x08\x8b\x53\x1d\xcd\xb6\x08\xbc\x7d\x06\x95\xff\x5a\x0f\xa0\x48\xb6\x2b\xa4\x38\x8f\x2d\x82\x6b\x88\xc8\x61\xd4\x0f\x7d\x31\x66\xbb\xd7\x10\xf8\x47\x96\xd7\x5d\xbf\x20\x45\x7f\x50\x01\x68\x62\x55\xfb\x7b\xac\x03\xa7\xe2\xc4\xda\x05\x14\xaa\x7a\xc8\xc3\xdb\x76\x91\x02\x07\x9b\x25\x7c\x3c\xf8\x18\xee\x83\x2e\xa8\xc1\x28\x68\x6c\xd6\x37\x76\x86\x05\xae\xc7\x7f\x07\xec\xcf\x12\x2f\xb2\x48\xe3\x65\x73\x7a\xad\x07\xa9\x7d\x96\xc4\x12\xdd\x40\x03\x31\xd7\x61\xa4\x32\x97\xa5\xab\x93\x61\x09\x44\x98\x1f\xb7\x40\x7e\x9b\x91\x30\xcd\x29\x21\x9e\x36\xa2\x59\x3b\x2f\x51\xdf\xed\x20\x7a\x3b\x35\x4b\x13\xcd\xf0\x85\x48\x33\xcf\xfe\xca\x58\x62\x18\x58\x1c\xe1\xfd\x73\x56\xf4\x9e\x97\x07\x09\x9a\xc1\x8d\x3a\xba\x9f\x42\x0f\x41\xb0\xf3\xf6\xf5\xbf\xfd\xe6\x7e\xa6\x1e\x4e\xfe\x43\x56\x2f\xca\xf6\xe6\x3f\x0a\x6d\xb2\x4c\xae\xda\x8c\xa7\x31\x09\x7b\x80\x09\x7c\x69\xff\xfe\xbf\x4e\xe8\xac\xf7\xd7\x97\xcb\xd9\xf8\xbc\x52\x67\x6e\x98\xde\x6b\xcb\x11\x4e\x90\x89\x88\x1a\x1a\xe3\xd6\xec\x86\xeb\x79\x5f\xde\x33\xae\xb5\xfd\x08\xa5\x8e\x56\x62\x5e\x96\xcd\x6d\xdc\x81\xeb\x0a\xaf\xd6\xcc\x1d\x44\xfb\x98\xf4\x22\xd1\x59\xe2\x1b\x4d\xbe\xb5\x5a\xac\xed\x2d\x48\xe2\x63\x02\xf4\x97\x97\xf5\x0f\xfb\x1b\x30\x19\x49\x07\x87\x87\xa6\x6f\x65\x31\xe5\xf9\x9a\x65\x17\x2b\xcc\xbe\xdc\x0d\x99\x0a\x03\xac\xb4\x6c\x4e\x59\x65\xbc\xc4\x61\x62\x96\x29\x49\x43\xbf\x87\xc3\x99\x8c\x39\x30\x05\x1a\xce\xd4\x7a\x9d\xbd\x8a\xf9\x9e\xab\x39\xea\xaf\x38\x06\xaa\xaf\x3a\x66\xf4\xfd\xdb\x7e\x78\x42\xee\xc5\x7e\x6a\xe0\x88\xeb\x02\x10\xb0\x58\x34\x1d\xbf\xc7\xb8\x77\xea\x43\x64\x99\xc6\x1f\xdb\x59\x36\xfa\x40\xdc\xe7\xa1\x26\x4d\x44\xa9\xb8\x1d\x34\x2b\xc4\x53\x4f\x8e\x0a\xee\xab\x18\x23\xec\xdf\xac\xbd\x79\x58\x15\x24\x18\x9d\x31\x48\x92\xb8\xd3\xde\x99\x15\x72\x7e\x6d\x0d\x72\x13\xcd\xbf\xde\x96\xcd\xe9\xaf\x0a\x8f\xa6\x07\x25\x0f\xd2\xd4\x0a\x4f\xf6\x62\xea\x83\x30\xed\xf0\xf1\x03\x0e\x82\x77\x94\xdc\x56\xcc\xce\xf2\xf0\xda\xd1\xcc\x43\x5f\x12\x03\x0e\xdb\x30\xf1\x56\xef\xcb\x17\xf8\xd9\x20\x21\xd8\xb5\x83\xed\x5b\xdd\xc0\xf6\x00\xae\x39\x50\x5f\x7e\x9d\xdf\x51\x11\x30\x8f\x47\xa1\xd6\xe4\xb0\x82\xec\x3b\x4b\x57\x68\xcd\x00\x1e\x85\xcc\x5a\x25\xba\x8a\xb8\x03\xef\xf2\x88\xe8\x82\xb7\x66\x6c\xe0\xcd\x8c\x40\xe9\xe8\x23\x47\x69\xa2\x59\xfa\xea\xfa\x0a\x13\x32\x40\xcc\xe3\x84\x78\x1a\xd9\x92\xe7\xed\x92\x3b\x1e\x04\x44\x28\xa2\x7a\x4e\x2f\xe6\x69\x2a\xe7\x45\xd5\x0f\xa6\x5e\x4a\x8e\xe2\x05\x7d\x1b\xc8\xac\xd7\x5f\x46\x2f\x79\x4c\x42\x87\x07\x35\x1f\x61\x25\xe7\xb7\x89\x12\x6a\x4e\x3d\xc0\x28\xb0\x60\x97\x1e\xd9\x78\xdb\x10\x4b\x74\xda\xfe\xb7\xbf\x43\x72\x9a\xc6\x8e\x68\x17\x7e\x36\x3b\xf8\xef\x15\x0a\x01\xce\x15\xe2\x54\x0a\x14\x0d\x74\x6e\xdc\x1d\x25\xd3\xf4\xfa\xd8\x5f\x93\x38\x05\x1d\x63\xca\x6a\x54\x4e\xc8\x8a\xa3\x96\x58\x5c\x15\x86\xd8\x76\xca\x62\xe2\xd4\x20\x91\x8d\x3a\xbd\x65\xb5\xe9\x16\xd5\xe9\xd1\x9b\x50\x69\x14\x45\x6b\xb8\x9e\x6b\xcd\xa0\x63\xda\x52\x48\xa4\x2b\xe9\xee\xf2\x52\xeb\xa2\x9f\x39\xe2\xa9\xd2\x08\x79\x23\x1d\x74\x75\xdb\x3b\xe7\x41\xa8\xd3\x85\xf8\xc5\x1f\x01\x6d\xde\x13\xb0\xe6\x07\xab\x3e\x13\x28\x69\x0f\xa3\x04\x83\x33\x07\x26\xe5\x2e\x3b\x4e\xc3\xd7\xb8\x20\x14\xdd\x18\x8c\x51\x33\x31\x22\xba\x6e\x3b\x28\x61\x19\xcb\x5a\xf7\xe6\xb5\xca\x06\x4b\x3f\x97\xbe\x8e\x57\x9d\x4a\x99\x77\x8e\xce\x27\x8b\x92\x0c\x85\xf7\x35\xe8\x71\x0a\x3e\xc8\x25\xf7\x70\x06\x36\xad\x29\x85\x18\x3e\xfb\x6e\xa4\x90\x08\xbe\x9d\x2f\x10\x55\xd3\x1b\x64\x12\x28\x58\x60\x54\x6b\x0e\xf6\x35\x06\x7e\x64\xcd\xa9\xb3\x61\x07\x46\x3f\x97\x90\x62\x04\x91\x5f\x6f\x8b\xcc\x6c\x81\xd6\x91\xe1\xe0\xc5\xca\x95\xca\x75\xe5\xb5\x1c\x02\xad\xcc\xd8\xfa\xd0\xa3\xe9\x0c\x10\x61\x92\x63\x5e\xdd\xf2\x3c\x6b\xe0\x53\xc9\x9f\xb6\xaf\x62\xa9\x89\x3c\x68\xa5\x89\xe9\x2f\xab\x3c\x82\x28\x8c\x03\x8e\x95\xfd\xa9\x82\xfa\x54\xba\x42\x6c\xae\x28\xd5\x2b\x04\x2b\xec\xe7\x98\x83\x1a\xc9\x59\x33\x4f\x78\x3e\xe0\x4a\x2a\xb3\x77\x4d\x02\xe7\xcc\x33\xe1\x51\x0f\x8d\xab\x59\x25\x30\xf1\xda\x7f\xb3\xc2\x37\x4c\xf5\xdf\xaf\x25\xcf\x36\x65\x9f\x9a\xb7\x6d\x15\x2c\x8c\x3a\x26\xe7\xd5\x27\xcf\x2a\x7c\xf0\x31\xaf\x70\x45\x69\x92\xc7\x6b\x21\x2b\x96\xd5\x5d\x96\x4b\x84\x81\xc4\xe2\xc0\xfd\xf6\x79\xf8\xce\xbe\x74\xd2\xed\xc1\x24\x02\x66\xa5\x1d\xcf\x66\xc2\xa9\xf5\x05\x8a\x07\xe8\x36\x13\x11\x72\x11\x1b\x0e\x99\xf5\x3b\x54\x2a\x2f\x3f\xe6\x18\xf2\x99\x7e\xf3\x22\x0a\xc0\x12\x14\x6d\xd6\xeb\xa7\x03\xc8\xac\x39\xf8\x36\xce\x27\x48\x4c\x59\xd0\x87\x95\x19\x01\x2f\xdb\x4c\x01\x97\x35\xfc\x6c\xce\x71\xef\x07\x65\x44\x1c\x05\xb8\x68\x9d\xaf\x79\x93\xa1\x92\xf8\x54\x39\xc2\xa7\x6e\xad\x88\x63\x5d\x67\xf7\xc7\x72\xbb\xee\xd1\x96\x88\x38\xe6\x08\x4b\x39\xb3\x9f\xfa\x9e\x16\xac\x6e\xf2\xee\xb2\x10\x13\x18\xca\x12\xf5\x73\x09\xfe\xc8\x33\x13\x34\x04\x14\x75\xfe\xfe\x30\xfb\x0b\x05\x73\xe6\x89\x24\xa6\x08\x69\x63\xad\x95\xa7\x37\x48\xdc\x44\x9c\xcb\x2b\x12\x26\x7d\xaf\xcb\xf6\xb8\xf8\xa3\x2d\x12\x9e\x5e\x74\x45\x22\x74\xb6\x12\xce\x97\xe6\xb6\xe8\x56\x05\x91\x80\x87\x90\xbd\xd6\x71\x5a\xb0\x62\x07\x85\x5c\x36\xa7\x8e\x07\xe9\xc7\x09\x0a\xf7\xfe\x3b\x54\x92\x3d\x3c\x25\x80\xe8\x11\x43\x36\x8a\x6c\x4f\xc7\x1e\x73\x8c\x48\x63\x88\x4c\x25\x27\xc2\x24\xb1\x54\x62\xcf\xaa\xa3\x43\x36\x8a\x94\x72\x44\x68\x5d\xd8\xcd\xb0\xf1\xdb\x86\x54\x20\x8a\xe7\xa2\x63\xab\xc8\xec\x39\x95\x27\x16\xad\x93\xa9\x05\xfb\xc5\x5b\x5e\x1e\x07\x28\x4b\x21\x20\x94\x41\xcf\x78\x5e\xc9\x09\x99\x02\xe6\x09\x09\xbe\xf2\x1c\xdb\x1b\x3e\x73\x7f\x58\x40\xa4\xa5\xbf\x2f\x55\x76\x63\xee\xc7\x84\x61\x94\x7c\x97\x15\xc7\x1c\x74\xb9\x96\xf9\x26\xcd\xcd\x75\x12\x1c\x29\xeb\x54\x56\xc8\xf5\xd5\x49\x82\xcd\x6f\x73\x56\x7c\x4a\xab\x67\x8e\x55\x9e\x2f\x51\x24\xa4\x2c\xa0\x2a\xbf\x75\x4b\x97\x50\x3e\xc5\xc8\x32\xc3\x09\x8b\x12\x88\xae\x3c\x6b\x32\xc2\x21\x54\x92\x10\x3a\x0c\x43\xb5\x3b\x24\x1f\x99\x4d\x42\x71\xe1\x73\xc7\xa8\x94\x97\xb7\x26\x3b\x03\xae\x6d\xee\x8f\xa2\xe3\xfe\x6e\x0f\x10\x7e\x1a\xf7\x60\xcb\x05\x54\x37\x8d\x09\xc7\x14\x78\x7f\xcf\x90\x5e\x44\xd0\x73\x98\x5d\x2e\xf9\xa0\xb2\x4d\x7a\xdc\x0f\xa5\x2b\x65\x78\x9b\x94\xd7\x1e\x7c\x76\xe9\x71\x88\x06\x70\xd3\xa1\xdc\x74\x0f\xdb\x20\x3d\xd0\xb4\x81\xfc\x9a\x99\xd8\xea\xa8\xd0\x4d\xfa\x81\xcf\x52\x63\x2c\x97\x79\x26\x3e\x71\x4d\xa5\x2f\xc1\x44\x65\x0a\xb9\x03\x90\xb3\x42\xf6\x79\xe0\x87\xe9\x56\xe9\xab\x54\x73\xae\x68\x3a\xf3\x95\xa9\x13\xfe\x42\xa6\x95\x79\x32\x0c\x88\x66\x65\xbd\xb0\x8f\xc2\x18\xd8\xc3\x6f\x29\x43\x43\x36\x70\xd0\x25\x1d\xaf\x45\x61\x82\x7c\xd5\xc8\x46\x96\x51\x2c\xd0\xe0\xb4\x24\x54\x06\x3e\x80\xd5\x4a\x5d\x98\x25\xbc\xf3\xa3\xff\xed\x07\x9f\x00\xf7\x24\xa1\x89\xd2\x96\xf9\x0e\xaa\x77\x4b\x1f\x39\xb0\x75\x64\xec\x11\xc4\x31\x33\x29\x17\x50\x35\x99\xca\xb4\xa6\xe5\x43\x29\xae\x7a\x32\x8f\xd6\xab\xe1\x7b\x8b\x43\x45\x4d\x62\xbe\x6f\x8d\x3c\x67\x45\x76\x36\x4c\xfe\xd6\xd2\x90\x94\x73\x9f\xdb\x52\x36\x8d\xad\xbc\x0f\x98\xca\xc4\x03\x34\x2e\x32\x73\xe1\x97\xf2\x53\xa6\x1c\x99\xf8\x5a\x37\x6e\x51\x16\x35\x14\xcd\x63\x36\x86\x7f\xc9\x84\x6a\x4c\x1f\xbf\x56\x45\xbb\xef\x0c\xa0\x29\xe3\xb3\x25\x91\xa5\x47\xd0\x74\x0a\x3b\xcd\xec\xd4\x19\x11\x32\x31\xc9\x87\x83\xb6\xa5\xad\x22\xfc\x97\x7e\xa3\x4c\x78\xc4\x3b\x16\x19\x13\x10\xb3\x8c\xfb\x3d\xc6\xad\xfe\x3c\x48\x78\x84\xe3\x11\x43\xed\xcf\x59\xd1\xf4\x50\xf8\x32\x01\x4d\x34\x8a\x9a\x8b\x97\xb2\xcc\x87\x71\x24\x99\xc6\x71\xea\x82\x6c\x59\x81\x23\xca\xd8\xfa\x2f\x65\xf3\x07\x54\x96\xdc\x44\xb2\x50\x83\x84\x66\xc2\x7e\xb5\xe2\x38\x49\x3a\x25\x19\x95\x81\x61\x4a\x68\x1b\x0d\xa9\xc1\xf0\x65\x73\x8f\x61\x9a\xa3\xca\x8e\xa7\x26\x1a\xae\x56\x92\x27\x11\x2e\x02\x8f\xc1\xeb\x66\xf6\xbb\xbd\x01\x2e\x13\x24\xaf\xd1\xf1\xe8\x76\xc9\xd2\xbc\x5d\x87\xae\x03\xa0\x19\x9a\x97\xc7\xd6\x56\x0f\xbe\x5e\x87\xa5\x88\x39\x52\x0f\x39\x58\xe1\xc6\xd5\x04\x49\x01\x3a\x91\x5e\x94\xcd\x29\x2b\x8e\x4f\x19\xb7\x2d\x32\xa6\x49\x3b\x32\x7f\x5d\x0c\x38\x17\xa4\xe4\x11\x6e\xf3\x06\xea\xfd\x0b\xb8\x73\x49\xf0\x30\xce\x3c\x53\x0d\xe3\xbd\xed\x47\xaa\x94\x20\xd1\xfe\x07\x02\x7b\x70\xb8\x0d\x63\x57\x52\x89\x18\xeb\x2b\x1e\x56\x8b\xe5\xe1\x69\xfd\x63\xb9\x35\x2d\xe0\xc5\x02\xfd\x76\x53\x4d\xfb\x3d\x3b\x9e\x6a\x51\x3a\x00\x2f\x78\x22\xf4\xa9\x23\x52\x94\xb0\x56\x0a\xa1\xa8\x5a\x64\x62\xf8\xbe\xc1\xf7\x3c\x74\xdf\x56\x59\x56\x94\x78\x87\x13\x18\x6d\xf7\x16\xa7\x5e\x26\xf8\xb1\xd6\x4a\xc6\x5c\x38\x86\x73\x3b\xfe\x1b\xdb\x45\x45\x81\x91\x3d\xb0\x5c\xe3\xa3\x0c\x30\x04\x21\xe0\xf0\x2f\x2f\x50\xcc\xec\x32\x0e\x01\xe3\x56\xd3\x16\xc9\x97\xb4\x09\xf7\x8d\x9d\x3b\x7c\x17\x44\x92\x4a\xe3\x3b\x3c\xb3\x22\x53\x50\x37\x2b\x59\xcf\x6f\x2f\x3d\x86\xcf\xe1\x7a\x04\x84\xe8\xd0\x87\x31\x45\xf4\xb8\xfe\x7a\x7e\x02\xe1\x3c\x36\xf1\xfb\xcd\xca\xd8\xbf\x74\xb0\x4a\x02\x81\x24\xf0\x4d\x7d\x66\x25\x5b\x7b\x7b\x81\x92\x4a\x5b\x60\xf5\x27\xe7\x37\xc1\x87\x49\xf1\x1e\xe6\x41\x6c\x72\x6d\x47\x6b\x3f\xda\x87\x8e\x59\x64\x93\xaa\x3a\x7d\x01\xd5\xfe\xa7\x59\x68\x9e\x17\x3f\x3e\x79\x6e\x1a\x44\x88\x97\x36\x0b\xeb\x2f\x45\xf9\x61\x94\x51\xbe\xc4\x2e\x01\xe5\x11\xc2\x70\x73\x56\x9b\x00\xe3\x0e\x5c\x90\x11\x12\x1e\x63\xb4\xbd\x39\xc1\xc1\x9c\xe7\xa0\xca\xea\x50\x22\x55\xf8\x61\xe6\xfa\xc9\x00\x87\xf4\x40\xf0\x7f\xd2\xa7\xb1\x07\x80\x42\x1b\x62\x07\xcd\xeb\xee\x61\x03\xd5\x72\xff\xfd\xc0\x6f\xe3\xbc\xa8\xe9\xcd\x3c\x40\x17\x55\x94\x45\xdd\x54\xba\xb0\xae\xef\x32\x03\x33\x9a\x8c\x3b\x74\x8d\xce\x5b\xf8\x18\x9f\x81\x11\x69\x89\x37\x71\x86\xaf\xea\x7e\xd5\xb1\x91\x48\x19\x8e\x5b\x4e\x24\x3a\x46\xb3\xd5\xf6\x61\xbb\xde\x0c\x79\x30\x40\x44\x60\xf1\x11\xaf\xf9\xff\xcb\xdb\x9b\x34\x37\x8e\x63\x6b\xa0\xff\xe5\xae\x72\xd1\x0b\x02\xe0\x78\x77\xb2\x24\x3b\xd5\xe5\xa9\x2d\x39\xb3\xaa\x3b\x3a\x14\x18\x0e\x6c\x5e\x53\xa4\x8a\xa4\x9c\xe9\xfe\xf5\x2f\x78\x30\x70\x10\xe5\xac\x7e\xf1\xe2\x6d\x2a\x2b\x4c\x90\xe2\x00\x1c\x9c\xe1\x3b\xdf\xd7\xe6\x07\xde\x3a\xb0\xb9\xa7\x1a\x74\x11\x0c\xc8\x44\x23\xb4\xc6\xa5\x7e\x1e\x87\x92\x51\xee\x82\x2a\x94\xe8\xe0\x77\x46\xf8\x0e\x3e\x55\x3c\x99\x95\x34\xe9\xb7\x50\x50\x71\x82\xbc\x40\xeb\xb6\x3a\xf2\x8f\x7b\x40\xdc\x90\xff\x1d\x9e\x61\x7a\xcf\x27\xa2\xe6\x88\x1f\x46\x53\x55\x49\x8a\x20\xa3\xb2\x7a\xd0\x98\x07\xef\xef\x59\xc6\x48\xeb\xff\xbc\x5d\xb5\xd5\xd7\xc5\xb7\xc9\x5b\x57\x52\x21\xb4\xb7\xdb\x7c\xfb\x7d\x8e\x04\x81\x43\x10\x00\x90\x08\x29\xea\xf2\x06\x17\xc1\x43\xed\x84\x9a\xe6\xcb\x67\xa0\xd3\x18\x0b\x19\x57\xc5\x69\xe4\x94\x82\xce\x08\x56\xbb\x5c\xd1\x67\xed\xe3\x0a\xd0\x60\x78\xff\x0f\x7b\x69\xa8\x60\x73\x18\xc1\x1f\x74\x60\x65\x59\xdc\xec\xab\x4c\x6e\x4e\x0f\xd9\xfb\x67\xa3\x35\x1d\x84\x92\xd9\x84\xcc\x6f\x79\xdb\x7e\x20\x3d\xc7\xf8\x25\xe8\x00\x32\x4c\x5d\xac\x56\x7f\xbf\xda\x39\x98\x91\x26\x91\x48\x13\x5f\x51\xab\x3f\x10\xd2\xe1\x8e\xc5\x31\xb6\x22\xa2\xe7\xb1\x85\x0b\xc9\x30\x4d\x04\xc7\x4e\xb2\xbc\xc1\x1c\xc0\xc0\xfb\xc2\xca\xa2\xbb\x1a\x0d\x81\xbb\x4d\xa3\x6a\x79\x31\xae\x93\x4c\xae\x19\xf2\x0c\x9d\x6b\xcf\x01\xe0\xae\x12\x2a\xe6\xe8\x25\x4c\xea\x1d\x51\xf4\x9f\xf1\x39\xe9\x88\x2a\xee\x45\x88\xee\x30\x75\x72\xd6\x7d\xa3\xa3\x98\x60\x37\xd6\xda\xb4\xde\xd9\x9e\xad\x73\x86\x35\x1d\x13\x86\xf1\xf4\x35\x7f\x83\x27\x28\x1c\x61\x88\x3d\x9a\xd0\x0c\xfd\xb2\x47\xde\x34\xc3\x79\xa1\x93\x34\x42\x1c\xbd\xd1\xd8\x13\x15\xaf\x95\x3f\x24\x84\x61\x2c\x01\x9b\xd7\x6e\x76\xd5\x42\xbd\xe7\x4d\x35\xf5\xcd\x75\x4a\x53\xdc\x78\xfb\x7e\x31\x9d\x0a\x40\x67\x11\x9f\xce\x32\xb2\x58\xe7\x4d\xf3\x40\x63\x52\x64\xe9\xec\x55\x55\xef\x86\xda\xd2\xe3\xf7\xc4\x33\x16\x78\xc1\xb3\x01\x58\x4f\x73\x1d\x73\x97\x99\x31\x3a\x28\x67\xce\xcf\xf8\x36\x05\x09\xb3\xc4\xb3\x28\x39\x0f\x7e\x32\x1f\x45\xa2\x31\xba\xbc\xb9\xf3\x55\x73\x2d\xc3\x2c\xb3\xa0\xfd\xdf\xbf\x8c\x46\x43\x4c\x31\x6b\xb6\xfd\xba\xa0\x51\x3c\xda\x14\xb5\x26\x49\x60\xba\x6d\xcc\x47\x73\xd4\x73\xc3\xcf\x7c\xe1\x4e\x35\x24\x42\x0c\x0a\xca\x9b\xf2\x1e\x7e\xdc\xf1\xfa\x0d\x5a\xa3\x9a\xe1\xc6\x69\x85\x8b\xa7\xe6\xa5\xfa\x32\xde\x4e\x71\x04\x09\x82\x04\x62\x0f\x49\x35\x3b\xd8\xae\xf2\x4e\x1f\x09\x08\xa3\xdc\x4a\x50\x15\x82\xcb\xb7\x1b\xde\xf4\x87\x0c\x34\xcd\x18\xf6\xfd\x6a\xb3\xdd\x3d\x6d\xae\x9e\x77\xeb\x95\x1f\x91\xc4\x18\xbd\x19\x6f\xdf\x60\xb5\x51\x52\xd8\x1d\x97\x86\xfe\xaa\x8b\xb7\xf7\xbe\xce\x4b\x02\xa2\x13\xd9\x2b\xe2\xfb\xa4\x2a\x09\x28\x35\xb2\x5a\x37\xa7\xce\x21\x1c\xbc\x4d\x12\xd0\x8c\x6b\x4b\x62\xaf\x76\x79\xe1\xb3\x54\xa3\x7f\xdc\x58\x48\x79\xe4\x54\x9d\x5b\xa8\x8f\x55\x5e\xb6\x5f\x26\x4e\xc8\xe8\x35\xb1\xcc\xf4\xe7\x5c\xe5\xed\xf6\xb5\x3a\x1e\x47\x94\x48\x24\x08\x33\x89\xfc\x13\xff\xac\x8a\xea\xa7\xff\xa3\x92\x2a\xec\x39\x72\x4d\x49\xf0\x1c\x31\x4b\x82\x10\x22\xe8\xbd\xa3\x7b\xf8\x61\xa2\xac\xb9\x4f\x4f\x82\x28\x49\xb1\xb4\x89\xc2\x00\x33\x79\xe3\x5f\x49\x3b\x72\x12\xc4\x8c\x06\xb6\x85\xd3\xfa\xa5\xae\xd4\xdd\x1d\x53\xd4\x16\x28\x87\x42\x57\x73\x08\x30\x12\xc4\xa9\xe9\x5b\xb0\x59\x31\xd7\xae\x76\x10\xbc\x69\xb8\xaa\xea\x5e\x41\xaa\x1b\xac\x04\x76\xf6\x4f\xc8\xb5\x48\xd3\x9e\xb5\x1d\x91\x20\xd6\x01\x22\x70\x91\x7b\x75\x71\x68\x27\x19\x6d\x12\x24\x59\x66\xf2\xff\x5d\x8c\x86\x11\x1a\xb2\x01\xfa\x62\x9b\xaf\x3a\xb8\xf1\x12\x30\x43\xcd\x1d\x6e\xfc\xb9\xcd\x0b\x9f\xbc\x22\x41\x9a\x98\x8e\xa9\xed\x9f\xa7\xbc\xae\xa1\xb8\xc9\x0f\x7e\xa2\xa7\x69\x84\xdb\xf4\x72\xfd\xd0\xff\x29\xd3\x96\xf6\xc6\x05\x8f\xe7\x4e\x6b\x9f\xa0\x1a\xbd\xfe\x2c\x0a\x2d\x1a\x04\x7d\x4d\x97\x23\x71\x47\x79\x90\xda\xfc\x8c\x59\x30\xf3\xaf\x3e\x13\xa9\x70\x9d\x54\xcb\x79\x45\x28\x4e\x02\x9e\x24\xa9\x01\xce\x21\x81\x41\x8f\x1c\xb2\x2c\x6f\x76\x98\x20\x81\x8e\x5c\x47\x4c\x0e\xa5\x6a\xae\xf3\xf2\x05\xea\xc6\xdc\x41\xb7\x57\x5d\xc2\x94\xb9\x2b\x30\x8d\x85\x6f\xa4\x3d\xdb\x3f\x2e\x9e\x76\xf7\x2e\x2e\x23\x81\x00\x30\x51\x7f\x3b\x20\xd4\xf9\x9e\xb7\xaf\x86\x8c\xb8\x9c\xf1\x13\x66\x1c\x29\x12\xc8\x40\x63\xd5\x0c\x41\x8f\x77\xcf\xb7\xbb\xcd\xc3\xf7\xc1\xcf\xc8\x30\x34\xd2\xb1\x24\xb5\xbc\x6e\xee\x80\xe2\x99\x69\xac\x18\x36\xe8\xcc\x3f\x88\x0a\x35\x26\x90\x6d\xb1\x8f\x1f\x27\xaa\xb0\xdd\x90\xd8\x10\x66\x55\x1a\x3b\x38\x8a\x1d\x14\xd0\x13\x86\x90\x40\xa5\x01\x76\x92\xff\x79\xca\x5b\x5b\x57\x1c\x7f\x15\xc5\x35\x86\x28\x37\x75\x75\x3a\xda\xb6\xe1\xfc\x42\x92\x86\x04\x10\x44\x98\x58\x3f\x22\x3f\xb6\xcd\x0c\x39\xe9\xe5\xee\x78\xac\x10\x49\xcc\x6b\x91\xb7\xc6\x49\xb8\x46\x26\xf2\xbf\x9f\x9c\xbe\x53\x37\x4a\x1a\xaa\x1f\xab\xc9\x38\x20\xc7\xfe\x57\xf8\x79\x4e\xac\xf7\x13\x48\xe7\x92\x46\x86\xe6\xa8\x84\x9a\x17\x8f\xa7\xfa\x58\x21\x23\x8a\xce\xdb\xed\xb1\xc8\xdb\xb6\x5f\x71\xa0\x09\x66\x33\xbe\x7f\xff\x3e\xb2\x95\x3a\xd0\x8e\xb5\x0e\x21\xd1\x73\xb8\x70\x12\x74\x71\xb1\xc9\xbd\x39\x39\x18\x7f\x7e\xc8\x38\xf3\x9b\xc3\x78\x22\x77\xfe\x50\xd0\xe3\x95\x9b\x0b\x76\x4b\x4b\x46\xb5\xe3\x87\x6b\x5a\x5e\xfa\x44\x71\xdf\xc8\x44\x48\x10\xc4\xac\xc7\xc2\xdd\x3c\x3c\xce\x25\xe5\x09\x09\x98\xc6\xb6\x33\xde\xb6\xf5\xf3\xf3\x66\x35\xbf\x14\x49\xa0\x0c\x9f\x08\x02\xbb\x3c\x5c\x80\x10\x92\x09\x8c\x27\xfc\x5e\x37\xf0\xad\x09\x21\x22\xc0\xec\xb7\x4d\x23\x1a\x31\xb7\x5d\x75\xaa\xf3\xe6\xf0\x97\x50\x57\xdd\x25\xb8\xf0\xe0\xf0\x6e\xf7\x1d\x02\x61\x08\xa1\x94\x99\xfc\xba\x91\x6e\x1b\xe3\x0f\x26\x18\x37\x42\x58\x60\x88\x78\xcd\x3b\xd9\xc1\xe1\x58\x18\x94\xc8\xa2\x79\x43\x46\x9e\x01\x2a\x71\xa6\x39\xe1\x2c\xa8\x77\x97\x25\xa6\x47\xd2\x85\x1f\xdd\x8e\xc0\xdc\x1d\x32\xa1\x31\x47\xf2\xcf\x0d\x7a\x1a\xee\xcf\xa1\x88\x10\xa9\xbb\x37\xf7\xf2\xcf\x4a\xe5\xfc\xd7\x5c\xe4\xf3\x1f\x27\x8a\x0c\x9d\xbd\xf1\xfc\x1e\xea\x97\x91\x6f\x41\xa2\x48\x47\xd2\x14\x80\x31\xc7\xb6\x5c\xf9\xbb\x88\x52\xe9\x9a\xbb\x6d\xd1\x67\xf9\x0a\x3d\x5f\xe1\x19\xc4\x62\xf4\x7f\xee\x1a\x59\xca\x52\x5f\xeb\x32\x3d\x89\xe3\x19\x4b\x22\x30\x5a\xbc\xdf\xf2\xba\x1d\x85\x6e\x84\xc4\x49\x68\x7a\xa1\xf3\xf7\x29\x98\x8f\x90\x38\x53\xe8\xbf\xef\x8f\xfc\x63\xac\xe1\x33\xff\x22\x92\x30\x45\x3b\x6e\x29\x63\x6e\xae\xe6\xa1\x9f\x84\xa4\x4c\xe1\x74\xbe\xce\x7f\x82\x32\xc8\xc9\xd1\x5d\xa5\x29\x44\xf1\x08\xb7\xbb\xca\x3b\x7b\x79\x2a\xfc\x9e\x4b\x52\xc1\x71\x0f\x73\x5f\xdd\xa5\x83\xdd\x61\xc9\xe9\x30\xa3\xbf\x6d\xe1\x38\xf7\x5e\xdd\x70\x4d\x43\xbb\x71\x9e\x2b\xc9\x70\x42\xb2\x80\x63\xae\xd6\xfd\x1a\x32\xf9\xcd\xc0\x6d\x08\xc9\x92\x18\xb9\x93\x2c\xc5\xd1\xa0\x87\xc5\x89\xbd\x1e\x4f\x86\xf0\x71\xfc\x4e\x32\x6e\x74\x30\x5e\xa0\x6d\x2b\xc5\x3f\x7c\xed\x8f\x10\xce\x05\x0a\xd4\x58\x5b\x32\x50\x26\x99\x9b\x17\x93\x77\xcd\x45\x82\x1a\x55\xfa\x54\xaa\x66\x57\x2d\x1d\x3b\xf4\xe4\xe7\x05\x17\xe8\x84\xde\xcc\x8a\x35\xcd\x58\x06\xa5\x33\xa4\x92\x7b\x2c\x78\x09\x98\xd7\x1e\x7d\x42\x20\x71\x18\xf5\x31\xb6\xf1\x1b\x8c\x50\xfa\xf8\x7d\x01\xa5\xca\x58\x98\xd5\x94\x9d\x9d\x10\x48\xb4\xab\x23\xef\x73\x59\x95\xf9\x9f\x7b\xdb\x4d\xb4\xaf\x8e\x83\x1f\x53\xc4\x15\xed\xae\xf2\xba\x7d\x3d\x7f\xbb\x3a\x55\x08\x86\xbb\xae\x0e\xa3\xfb\xa4\x41\xac\x1c\xdb\xe7\x73\x03\xf5\x2c\xe7\x10\xa1\x41\x92\x04\x69\xff\x51\x57\x4e\x40\xdd\x5f\x45\x2b\x9c\x8c\x8a\x7f\x9c\xf7\x9f\x11\x4a\x02\x8e\x49\x4e\x28\xd5\x46\x56\x7d\xdb\x32\xa1\x84\x08\x39\x44\xec\x2e\xf9\xe1\xc8\xf3\x17\x7f\x7b\x44\x19\x66\xc9\xce\x53\xbd\xe6\x79\x81\x55\x59\x54\xf4\x34\x94\xec\x5b\x7e\x80\x4d\x0b\x07\x87\x75\x22\x94\x42\x80\x30\xd7\xda\x68\x79\x60\xce\xc8\x59\x43\xca\x02\x82\xbe\xda\xb1\xae\x0e\xd0\xbe\x0e\x77\x0b\xca\x68\x82\x6d\xdd\x06\x0d\x88\x12\x18\xfe\x01\x58\x68\x30\xe4\x7b\xc4\x55\x7a\x0c\xd3\xfc\xf2\xa6\x2c\x8b\xb9\xf5\x6f\xef\x87\x32\x3a\xc3\xac\x29\xa1\x4c\x32\x4c\x3f\x55\xc3\x78\xc5\x1e\x0b\x09\xc5\x32\xf3\x72\xb1\xdb\x3f\xae\x9f\xf6\xeb\xdd\xd7\xfd\xd5\x62\xbb\xde\x3f\x2d\x76\x6b\x77\x53\x21\x63\x9a\x0f\x10\x7e\xe7\x94\xd5\xdd\x18\x8e\x41\xe2\x21\x2f\x5b\x4b\xe8\xd4\x4c\x87\x64\x29\xa6\x27\xf1\x3e\x4c\x95\x0e\x65\x53\x27\x53\x20\x92\x29\xb5\x61\xba\x65\xf4\xc2\x2f\xfd\xfc\xb4\x19\x99\x7b\x1a\xf7\xe1\xbc\x36\x94\x26\xb3\x6e\x04\x8d\x65\x84\x5f\xf6\x66\xb1\xdd\xef\x1e\xf6\x8b\xe7\xdd\xd7\x87\xa7\xcd\x3f\xd7\xfb\xf5\xef\xeb\xe5\x73\x4f\x32\x4f\x68\xac\x62\xa4\x1f\x92\x45\xe7\x2e\x59\x72\x96\xc9\x43\x24\xd2\x60\x68\x6e\xab\x17\x5b\xbb\x74\x80\xc7\xc9\xcf\xa6\x21\x95\xd2\xa1\x42\x3f\x06\xf9\xa8\xd4\x0e\xc8\x88\x46\x7c\xd6\xa8\xcf\xe4\xd3\x16\x1b\x42\xb3\x94\x19\xd8\x0b\xbe\x88\x35\x32\xab\xcc\x04\x2f\x34\x93\xc2\xbc\x9b\xd3\xe1\x60\x25\x57\x2d\xcf\x9e\x1b\x00\xa6\x13\x6c\x0b\xad\x41\x11\x6d\xa1\x28\xae\xce\x3f\x2b\x8f\x28\x66\xce\xb9\x53\xce\x77\x17\xe0\xb1\xe9\xbb\xfe\xed\x8f\xa5\xfb\x93\xa4\x51\x6c\xd4\xb4\x61\x3d\x10\xce\xea\x8e\x24\x4a\xa5\x7d\x83\xa2\x9f\xd8\xf3\x25\x67\x42\x25\x57\x49\xe0\x29\x6a\x3b\x7f\x6f\x34\xa1\x15\x35\x18\xf4\x6e\x8f\x58\xd5\xfc\xc7\xae\x7a\xac\x2a\x73\x7f\x67\x06\x89\xaa\x04\xd0\x2f\xf9\x7e\x1a\x54\xb0\x08\x55\x3c\x45\x31\x86\x15\xbc\xe7\x8d\x77\x87\x29\x84\x34\x73\x72\x21\x79\x23\xf3\x23\xa6\xcd\xfd\xd1\x28\x32\x84\x1d\x55\x51\x6c\xfc\x7a\x86\x2c\x4e\x02\xcf\x98\xbe\xde\x7d\x1d\x4a\xea\x4d\xee\x06\x20\xc1\xc6\x6d\x93\x6d\xb8\xe3\x79\x89\x9d\x68\xf5\x64\xf2\xe8\x38\x83\xc0\xe3\x9e\xe7\xf3\x98\x84\x91\x48\x24\xbd\xc0\xdc\x63\x9d\x4b\x8f\xc2\x22\x8c\xf2\x24\x8d\xbc\xbb\x32\xae\x08\x1b\x26\xeb\x3e\x62\x60\x94\x1b\x89\x0f\xa7\xf2\xd3\xf0\x69\x38\xc4\x28\x17\xa9\xe7\x8d\xb1\x0a\xc2\x83\x6f\xcc\x28\x30\xd6\x0b\x18\xac\x00\xd4\x88\x88\x76\x72\xeb\x2c\x25\x46\xd6\xc2\x42\x10\xfa\x66\xc2\xe1\x8c\x88\x43\x3b\x3c\x0c\x23\x0c\xb7\xdf\x91\x62\xaa\x67\xe1\x1c\x87\x85\x2c\x4c\x62\x0c\x66\xda\xfd\x5d\x2e\x5f\x79\x5e\x50\x77\x77\x51\x20\x51\x18\xc3\x82\xdb\x1e\xeb\xea\x08\x75\xdb\x27\x22\x6c\x1e\xea\x5f\x24\xb0\x8e\x0a\x8b\x49\xc4\x4d\xde\xaf\xe9\xa2\xa7\x2b\xe0\x93\x8f\xc4\xe2\xc8\x70\xa0\x29\x78\xdf\x37\x6d\x0d\xfc\xd0\x0c\xb1\x3e\x84\xc5\xdc\x08\x04\xbe\xa0\x66\x2c\xd4\x5f\x79\xf3\x7a\xa6\x8c\x42\x58\x2c\xc3\x30\x1d\x77\xe8\x75\xab\x31\x2f\x5f\x3e\x7b\x83\x19\xa1\x98\x06\xed\x2c\xf6\xf2\x76\xbd\x70\x01\x36\xcb\x14\x18\xed\x23\xe3\x26\x7f\xfd\x10\x75\xae\x6c\x51\x73\xf2\xcb\x3c\x91\xd0\x4f\x20\x6c\xa7\xaa\x61\x92\x23\x71\x43\x81\xc0\xa4\x8d\xb0\xf9\x32\x97\x84\x63\x92\x86\xe8\xaf\x5c\xe5\xed\x6b\xb7\xe6\xac\x1b\x34\x74\x06\x98\x8c\x52\xac\x8b\x16\xd5\x4b\xb7\x28\x17\xa6\x09\xb8\x3e\x0b\xf7\x27\xcf\xac\x68\xc2\x7a\xbe\xf8\x47\xde\xe6\x50\xb6\x5f\x81\x17\x86\xe0\x60\xbe\x0b\xd0\x9d\xcb\x0c\x4b\xae\x02\x07\x18\x37\x6f\x7a\xd0\x71\x4d\x98\x4a\xc1\x76\x90\x76\x91\x73\x3b\x61\x76\x20\x0c\x18\x8b\x86\x92\xaa\x4f\xa0\x6d\xc9\xe7\x4c\xa6\xc3\x9e\xa1\x33\x83\xd5\x34\x9c\x42\x86\x4d\xd0\x57\x41\x48\x18\x44\x11\xce\xd8\xbb\xbc\x78\x5b\x56\x63\xca\x3e\x12\x06\x3c\x4e\xcd\x6b\x92\xbc\x40\x78\x8b\x47\x69\x90\x30\x80\x10\xac\xcb\xb6\xaa\xab\xe3\x7d\xd5\xe6\x9e\xe6\xa9\x3b\x9a\x64\xb2\xd7\x2b\x3e\x9c\x0e\x2b\x10\xbe\xdf\x7d\x3c\x0f\x42\x12\x98\xad\x34\x2f\xdb\x6e\xe2\xbd\x40\xd9\x1e\x78\xd3\x74\x4b\xa8\x1c\x7e\xb7\x90\x48\x88\x4d\xe1\x19\xf5\x30\xb0\x34\x3f\x02\xc2\x8d\xaf\x4b\x83\x30\x10\xc8\xab\x57\xb8\x2b\x50\x15\x1b\xf2\xd1\x46\xf2\x23\x7c\xe5\xdd\xcb\x1f\x3f\x74\x18\x53\x7c\xe8\xdb\xdf\xfe\xf8\x15\x44\x91\x84\x61\xaa\x79\xe2\x9b\x82\x4c\x9a\xc1\x3c\xa2\xfd\x2e\xee\x77\x43\xce\xd0\xa2\xfe\x70\xda\xa5\x7f\x99\x36\x9a\x84\x51\x60\x10\x0b\xbf\xaf\x9e\x16\x6e\xb7\x0b\xa3\x30\x65\x76\x8f\x42\x95\x82\x1e\x34\x30\xda\xac\xc2\x28\xcc\x10\x43\xd1\x37\x36\x5b\xf7\x68\x4a\xa1\x3c\xf9\xcd\x98\xa1\xd8\x90\xe5\x43\x38\x07\xef\x93\x30\xca\x0c\x91\xb9\xb1\xb8\x86\x53\x64\x8c\xb3\xe9\xc7\x26\x49\x26\xb3\x3e\x7f\x60\x32\x86\xee\x51\xb2\x20\x42\xd1\x89\x15\x5c\x4a\x51\x86\x59\x60\x02\x49\x07\xca\x40\x90\xd9\x2f\x1a\x4a\xa6\x97\x48\x12\x87\xa6\xef\x4b\xfe\xcb\xe1\x2b\x70\x03\x53\x1d\x79\xf6\xd8\x7d\x0d\x8d\x97\xf3\x22\x21\x8f\x62\xb4\x95\x98\x71\x0e\xe8\xa0\x3e\x4e\x42\x91\x26\x89\x29\xb7\x74\x21\xd8\xfa\x1d\xea\x0f\x51\xb9\x3e\x74\x14\xf7\xf0\xbd\xac\xbb\x87\x59\xc6\x9b\x31\x4e\x8f\x84\x92\x19\xb5\x58\x75\x03\x6d\xe7\x62\x7c\x39\x4d\xb8\xb9\x48\x28\x33\x01\x5e\x43\xcf\xc6\xd0\x9b\x6e\x87\x1a\x3f\xbc\xd4\x2c\x1b\x1a\x16\x9b\x84\x5f\xf2\x5a\x0d\xe1\x63\x24\x54\x24\xc3\xd6\x41\x6c\x24\x78\x3c\x89\x22\x97\x83\x6c\x57\xa8\x42\x9a\x0c\x67\xd3\x95\x57\x3d\xbb\xf0\xe1\x54\x1c\x61\x51\xaf\xfd\x01\xd0\x6e\xda\x91\x0b\x1d\x42\x67\x43\x0c\xc7\x68\x77\x43\xee\x4d\x41\x9a\x62\xea\x5b\xe7\xb5\x05\x12\x2c\xf9\xd1\x1f\xe4\x99\x34\xde\x4e\xa1\x9d\xea\xcd\xca\xf5\xb4\x77\x87\xb9\x25\x06\x3d\x3a\x60\xab\x3d\xa2\x25\x41\x9d\x7b\xde\x59\x2b\x50\xbb\xd7\xbc\xf9\x0e\xf0\xe6\x0f\x6b\x8f\x07\xbd\x32\x0b\xe8\x8c\x6b\x7a\xb4\xb0\xa2\x40\x00\xbe\x0a\x35\xa8\x09\x1b\x75\xc2\x61\xb4\x15\xd1\xd0\x18\x42\xc7\xcf\x72\x0f\x3f\x07\xd8\x5f\xa8\xfb\x3d\x96\xd0\xd4\x9d\x23\x28\x46\x4c\xcf\xbf\x7d\x77\x97\x61\x9d\xa5\xf9\x9f\xff\xfd\x9f\x5d\xde\x16\x30\xa6\x21\x23\x11\x8b\x29\x92\xde\x2c\x5a\x2e\x87\xf6\x32\x62\x82\x61\x4e\xfb\x9f\x00\x8f\xce\x94\x5e\x4a\xa2\xff\xc5\x7f\xed\x95\xc3\x20\x44\x7a\x2c\xb3\x75\x3f\x97\xb9\xac\xea\x72\x80\xe2\x23\x51\x18\x85\xc2\x82\x84\x06\xb9\x91\x33\x07\x39\x0a\xb9\xc9\xb8\xb8\xd2\xf9\x4d\xe5\x71\xf6\x24\x0a\x25\x98\xd2\x84\xa9\x1d\xcd\x47\xed\x51\x24\x40\x58\x99\x64\xa8\xbb\x9d\x58\xf0\xe6\x82\x6f\x1f\xc5\x12\x12\xdf\x7e\xff\x04\xf9\x41\x9c\xea\x06\x54\x9f\x2a\x8f\x92\x38\x8b\x9d\x10\x6d\xaf\x34\xfd\x50\x16\x1f\x83\x95\x10\x25\xa9\xc2\xa6\xcc\xf5\x3b\x60\xc7\xdb\x8e\x97\xe3\xee\xed\x89\x07\x13\x25\x99\x99\x08\x25\xb4\x16\xc3\x62\xbc\x98\x6d\x55\x4c\xf6\xc3\x28\x0d\x34\xa6\x72\x14\x3f\xf4\xa5\xb1\x28\x25\x06\x1e\xe5\xd6\xde\xf7\xd7\xaa\x98\x7a\x42\x93\xeb\x58\xed\xbf\xa6\xe5\xed\xa9\xf1\x6d\x95\xdd\x81\x18\x9d\x91\x82\x37\xed\x2d\x3f\xfa\xa4\x42\x94\x85\x8a\x1a\x26\x5a\x93\xf8\x70\x2a\xf1\x9f\xe6\x03\xa3\x4c\x46\x68\x15\xb9\x6d\x97\x30\x37\xd5\x59\xac\xa5\xbf\xb0\x34\x52\x1b\x2f\xb6\x7d\x1b\x50\xcf\x19\x41\xc0\xfa\x82\x3b\x1d\x71\x4a\xd1\xeb\xbe\xe1\x07\x07\x1e\x72\x47\xd2\x98\x74\x2f\xff\x5b\xd5\x9a\x4c\xf8\x63\xb7\x90\x2a\xd9\xa7\x62\x22\x9e\x71\xa4\x2e\xe9\xa2\x09\x28\x25\xf7\x7f\xd7\x86\x5d\xe9\x09\x8e\x45\x2e\x07\x06\x22\x12\xa1\xa2\xca\x13\xdb\x76\xa6\xf1\x8c\xd3\x62\x72\x83\x22\x62\x58\xf6\x3e\xd6\xb0\x3f\xe4\xe5\x28\xee\x72\x43\xb2\x24\xb6\xf9\x46\x03\xe9\x58\x16\xbc\x69\xbe\x8c\x66\x86\x10\x0c\x09\xe9\xad\x28\x7a\xc5\xeb\x31\x88\x7a\xfc\xa3\x92\x24\x48\x55\x6a\xc8\xcd\xab\xfa\xb6\x1a\xe7\xa1\x23\xa9\x0c\xe8\xaf\x8b\xbb\xd6\x4f\x4b\x1a\xfc\x05\xf6\x0c\x12\xa9\x28\xc3\xbd\x06\xd7\x85\xa1\xd2\x1d\xd7\x1c\x23\x25\x08\x12\x96\xef\x5d\xaa\xd5\x5c\x77\x46\x6a\x8a\x44\xc0\x32\xe2\x04\x67\x5d\x51\xf0\xb9\xcc\xff\x3c\x01\x92\xf1\x36\xb3\x00\x3b\x12\x07\x69\x64\x6e\x62\x1e\x0a\xe7\x20\x03\x71\x90\x85\x18\x2f\x8a\x53\x5d\x1a\x40\xc3\x1d\x7f\x83\xda\x8b\x63\xb8\x61\x42\x61\x16\x0c\xbc\x83\x34\x92\x72\x22\x31\x89\x43\xea\x34\x62\xae\xf2\xf6\xa1\xde\x9e\xe4\x60\x12\xc5\x24\x96\xd8\xac\xff\xca\x9b\xeb\x1a\x00\x5f\x47\x7d\x97\x97\x4f\xbc\xcd\xcb\x97\x66\xe4\x3d\xcc\xbf\xd7\x98\x86\x99\x09\x87\xba\x19\xb2\xdf\xcf\x47\x53\x31\xe5\x09\x62\xfb\xb0\x5e\x8f\x51\x61\x31\x6d\xf4\x25\x31\x95\x41\x68\x0b\x0c\x06\x3a\xdd\x5c\x4f\x78\xc5\x49\xcc\x62\x65\xb8\x8d\x5b\x38\xee\x5e\x6b\x80\x2f\xa3\xdf\x61\x29\x73\xcc\x08\x96\xfd\xdc\xf9\xa1\x8b\xb6\xad\x8c\xcc\xc1\x40\x22\x87\xc4\x2c\x93\x68\x0c\xa5\x75\x99\x2c\x08\xbc\x99\xfe\x2c\x8f\x31\x69\xd6\x8b\xe0\x92\x98\xc9\x20\x0b\x6c\xeb\x90\xf1\x22\xfd\x7b\x0d\xd3\x10\x73\xe0\xbb\x57\xd8\x1c\x0e\x55\xdd\xf2\xa2\x79\x7c\xad\xda\xea\x42\x55\x68\xfc\x63\x51\xc8\x12\x53\xa9\xb5\xe4\xf5\xf3\xcb\x33\x8e\x52\x6d\x51\x29\xe5\x23\xd4\x48\x7e\x3e\x99\x76\xd3\xf2\x40\x1c\x65\x29\xc6\x43\xcf\x25\x8a\x95\xa9\xe1\x6e\x1a\xc7\x24\xe5\x7d\x0c\x6a\x14\xe0\x47\xa0\x70\x12\xc7\x4c\xa2\x75\xb9\xdb\xdc\xef\x1f\x9f\xd6\xfb\xeb\xe7\xfb\xd5\xe6\xfe\x66\x7f\xf3\xb0\xb8\xf5\x63\x42\x0e\xd4\xb1\x8c\xf3\x81\xe6\x31\x02\x21\x88\x1f\x26\x42\x24\xb1\xc7\x7e\xe5\x33\x72\x51\x7f\xc7\x09\x4d\x1c\x5c\xf9\x6e\x6c\x82\x36\x65\xbf\xa9\xc5\x69\xa2\x2c\x39\x92\x69\x66\x25\xcd\xee\x54\xfb\xdb\x4e\x55\x8a\x14\x1d\x2f\xfc\x00\xe3\x94\x76\x9c\xc5\x01\x36\xf7\x2f\x97\x5f\xf7\xeb\xd5\x66\xb7\x67\xfe\x48\xca\x48\xe4\x64\x5b\xda\x9a\x1b\x73\x60\x5d\xfb\xf1\x97\xc8\xa4\xc1\x71\x8a\xaa\x72\xc9\xac\x98\x33\xa3\x49\x8d\x1d\x6b\xd3\xfc\xe3\xb4\xfa\x15\x0b\x30\xfd\x9a\x96\xd1\xbd\x8b\x01\xce\x5c\x89\x58\xc6\xdc\xd3\x3e\x0e\x25\xc7\x26\xd7\x92\x69\x8c\x06\xd2\xd5\x78\x9e\xd0\x61\x9f\xdc\xb2\x54\x02\x5f\xff\x81\xff\xbc\xad\xe4\xdb\xea\x34\x24\x40\x25\xb1\x8a\xb2\xd8\x26\xdd\x26\xfa\x01\x76\x00\x44\x0c\x05\x41\x96\xf5\xc7\xb1\xad\xb6\xfc\x85\x2f\xab\xba\x06\xd9\x82\xfa\x0a\x75\xf7\xe5\xcf\x16\x91\x66\x49\x12\xfa\x66\x3a\xa8\xdf\x7d\xa3\xb7\x1b\xd0\x05\xb0\x03\x2f\x7e\x8f\x0b\xb6\xb3\x90\xf3\x0e\x40\x12\x50\x8a\x6d\x1e\x6f\xf0\xb1\x3e\x1c\x8b\xea\x03\xa0\xb1\xcc\x4a\xfd\xb3\x24\x81\x4d\x15\x77\x53\xa8\x79\x19\x2e\xff\x84\x24\x09\x37\x6f\xa1\x33\xb2\xb9\x95\x9f\x6f\x3c\x0e\xd2\xa7\x26\x12\x22\x62\x8c\x30\xcc\xcb\x44\x71\xc1\x79\x55\x32\x92\xd0\x20\x8c\xba\x75\xf9\xf8\xbc\xfd\xea\xa6\x7b\x42\x95\xa9\x4b\x1d\xd1\x1a\x8c\x27\x61\xc2\x08\x8b\x87\x55\xb9\x7d\x5b\xd9\x5e\x9f\x89\x5c\x27\x49\x98\xe0\x58\xb5\xef\x69\x27\xdf\x5d\x16\x2e\x09\x89\x0a\xb4\xdb\x3a\x6f\xf3\x3f\x4f\x56\x41\xf4\x5c\xa6\x8b\x24\x21\x0b\x11\x24\xb0\xb7\xe1\xdc\x4f\x09\xa0\x40\x9d\x37\x55\x0d\x4e\x09\x53\x42\x7d\x22\x76\x59\x55\xb5\xca\x4b\x97\x6f\x23\x7e\x14\x4f\xc1\x7a\x04\xf7\xf0\x63\x59\x15\x55\x3d\xda\xbf\x93\x50\x86\xd8\x2c\x74\xc8\x1d\x1d\x45\xe4\x1e\x20\x56\x09\x86\xd1\x9e\x76\xe1\xd3\xb6\x69\x92\xc4\x3a\xc6\xfe\x32\x8d\xd5\xe2\xce\xd0\x4c\x6b\xbf\x49\x12\x19\x36\xef\xbc\xb9\x44\xc2\xe6\x06\x66\x9c\xf9\x3e\x05\x28\xd4\x99\x0e\x25\x49\xd2\x90\xb0\x1e\xc9\x87\xf9\xbc\xbb\xbc\xbc\xad\x5e\xaa\x0b\x1e\x6a\x92\xc6\x69\xe0\x1a\x22\xbb\x67\xca\xab\x72\x59\xf9\x2d\x24\x49\x63\x85\xcd\x4c\x36\x5d\x0d\x4d\x33\x48\x2d\x8c\x32\x31\x49\x9a\xa4\x69\x30\xe1\x24\x1a\xe9\xe8\x9f\xb1\xe6\x93\x84\xd3\x38\x35\xf4\x76\xa5\x21\xae\x75\xbf\xcb\x33\xc0\xf9\xb6\x98\x3c\xa0\xa0\x14\xfb\x64\xd0\x49\xda\xa3\xd5\xb0\x47\x24\x4f\x31\x1c\xa8\xab\x53\x79\xc6\x3b\xe2\xc6\xc8\x04\xf5\xd3\x9b\xb6\xaa\x41\x0d\x15\x45\xed\x00\x15\x52\x04\xe9\x98\x06\xca\x89\x37\x93\xa8\x48\x87\xe1\x08\x9c\xe3\xc3\x93\xe9\x75\x12\xc2\xb8\x2f\xd3\xec\xaa\x67\xf4\x36\xc7\xb3\x4c\x29\x1a\x5b\x67\xc2\x83\xac\xea\x09\x71\x31\x49\x14\xa4\xa9\x53\xa6\x68\x79\xb1\xe9\x13\x74\xc3\x9d\x31\x81\x30\x46\xe0\xe3\xbd\x98\xfc\x9d\xd3\x48\x38\x95\xa8\x23\x56\x9c\x97\x95\x82\x91\xfb\x9b\x80\x08\xb0\x14\x82\x9b\xc8\xd7\xaa\x50\xe7\xd5\xd9\x8b\x8d\xcb\x24\x01\xa9\x33\xb0\xfc\x95\xd3\x30\xe5\x9c\xba\x62\x9e\x35\xc7\x5d\x0a\x0c\x1a\xa1\x81\xf6\x86\x37\xc6\x90\x5d\x57\x35\x6e\x25\xb7\x55\x35\xf1\x71\x13\x1d\x18\x9e\x88\xcd\xf2\x61\x6f\x54\xa3\x77\x9b\xbb\xb5\xdf\x1f\x13\xcd\x23\xc4\xec\xe8\xbc\x28\xac\xef\xcf\xeb\xe6\xbc\xa2\xef\x86\x03\x47\x46\x59\x9b\x22\x33\x2b\xff\xb2\x0a\x1d\x49\x83\x10\x90\xfb\xcd\x7e\xc1\x09\x87\xeb\x7c\xdc\x9e\x12\x61\xb4\x04\xb7\x05\x3f\x1c\xa0\x3e\xc3\x80\x93\x94\x32\x6a\x74\x13\x1a\xd3\x70\x81\x1f\xd4\x86\x5f\xe3\x6b\xd1\x98\xa3\xa2\xcb\xf2\xee\xb7\x2f\xee\x4f\x8a\x1b\xee\x25\xe4\x26\x1e\x50\x65\x91\x94\x25\x26\xb4\x5c\xf6\xe9\xc2\xc9\xf5\x18\x64\x58\xf2\x58\xd7\x75\x55\xbb\xc5\x3e\x9c\xb4\x69\x98\x30\x6c\x34\xb4\xa5\x4f\xcf\xec\x6a\xa7\xcb\x5f\xeb\x28\x20\x69\x98\x0a\x64\xaf\x69\xaa\x03\xdc\x41\xfb\x3a\x4d\x48\xa7\x51\xa2\xc3\xee\xc9\x1e\x76\x5f\xd7\x4f\xcb\xa7\xe7\xcd\x76\xfd\xb4\xbf\x5b\xfc\xbe\x5f\x2e\x9e\x6e\x5c\x14\x9d\xc6\x91\x11\x8a\x74\x2d\x87\x83\x62\xc9\xf4\xeb\xa6\x31\x10\x6a\xfd\x05\x7c\xa1\xce\x70\x9b\x26\xfe\x3e\xaf\x90\x26\x24\x71\x9d\xb7\xdd\x1d\xef\xaa\x47\x3e\x88\x3f\x07\x03\x53\xa6\xa8\x9d\xad\x3b\xfe\x73\xb6\xf6\x9c\xa6\x91\x42\x82\x2f\x9f\x75\xfe\x0e\xb9\xa1\x12\x71\xcf\x90\xa6\x92\x85\x6e\xce\x1f\x44\x91\x97\x2f\x97\x94\x00\x49\x9a\x0a\x83\xfb\xe1\x23\x31\x9d\xeb\xaa\xde\x1e\xbb\xb0\x60\xe2\x3a\xa6\xa9\x96\x98\x96\xa9\x6a\x05\xf5\x0a\x8e\xed\xeb\x38\x37\x9d\x66\x3c\x4c\xfb\xfc\xc4\xb0\x3a\x9d\x76\xaf\x4c\x8c\x90\x41\xa6\x84\xe8\x0e\xd3\x20\x1b\x08\xfc\x74\x6f\xd4\x58\x8e\xc9\x0b\xe0\x89\xd0\x72\xc8\x1a\x77\x36\x42\xe8\xd8\x6d\xc7\xd7\xa7\x52\x4d\xb2\xe2\x76\x90\x24\x1c\xa3\xaa\x2e\xde\xdc\x55\xdd\x63\xba\x1b\x91\x49\x44\x2c\xac\xe4\x8c\x16\x9d\xa4\x52\x9a\xcc\x7d\x9f\x7c\xb7\xee\xf1\xf8\xbd\x4a\x15\xa0\x2d\xee\x35\x43\xe6\xf7\xe0\x54\x29\x8e\x61\xb5\x25\x00\x76\x50\xa8\x29\xdd\xed\x2f\x12\xe2\x93\x8b\x42\x60\x88\xdf\xb1\xd5\xbc\xae\xab\x1f\x79\xf9\xb2\x69\xe1\x70\x31\x45\x3d\x2a\xe3\xce\xcf\x14\x20\x06\xf3\x51\x7b\x5d\xf2\x7d\xcd\x65\x5f\xbf\x4f\x81\x02\xe2\x0d\x0b\xd0\x6d\x9c\x4d\xde\x07\x68\x82\x50\xea\xc5\xed\xad\x4b\xec\xa6\x3a\x34\x62\xbe\x5d\x28\x5e\xd5\x1a\x72\x4c\x50\x0c\xca\x37\xc3\x9d\x3d\xd5\x49\x84\xb6\x71\xf7\x0a\xd2\xe7\x8e\x53\x9d\x09\xcc\x93\x76\x2e\xa4\x61\x64\x3a\x2b\x6d\x8f\x9f\x23\x0b\x02\x69\x2a\xba\xfc\xcd\xcc\x32\x83\x62\x9d\xac\xb3\x2c\x60\x46\x54\xc0\xfe\xd5\x66\xc0\x9e\x1b\x50\x8b\xc6\x14\x85\x9c\x0b\x97\x05\x0c\x38\x3a\x01\x27\x71\xc8\xdb\xe9\x75\xa2\x20\xf0\xf2\xbf\x5b\xac\x29\xd9\x6a\xd2\x20\xb3\x9a\x05\x09\xb3\x38\x44\x71\x7a\xb9\xe5\x2d\x34\xad\x6b\x0b\x5d\x76\xb1\xf9\xd0\x83\xcf\x68\x10\xe1\xe0\x4a\xeb\x4b\xe0\xe1\x8c\x06\xda\xaa\x18\x60\x67\x7e\xf9\x82\x20\x3a\x77\x90\x26\x48\xb7\xd6\xbb\x1d\x57\x35\x70\x35\xeb\x85\x65\x94\x87\xc8\xd0\x6b\x45\x7e\x88\xbf\x88\x56\x98\x0c\xc6\xba\xc9\xba\x54\x0d\x09\xdc\x21\x46\x8c\xfe\x7e\x5b\x7f\x2c\xca\xaa\x7d\x45\xcd\x63\x77\x30\x64\x84\x58\x49\x5c\x27\xae\x50\xfa\x63\x51\x18\xd9\xbe\xb0\x8d\x82\xb2\x45\xa1\x20\x5d\xb9\xc3\x71\xa0\x52\xa3\xfe\x62\x68\xc0\x7f\xfb\x90\xfe\x10\x33\x95\x2b\x01\xad\xc9\xe1\xec\xaa\xe7\x06\x21\x95\x57\xbe\x2a\x95\xc5\x51\x86\x3e\x0d\xb6\x8a\x40\xb9\x38\x3c\xb7\x72\x3c\x4f\xb3\x38\x52\xd8\x57\x75\xa8\x9c\x80\xf5\x80\x85\xe8\x8c\x26\xcb\x9d\x94\xa5\xe8\xd3\xba\x58\xc6\xe7\xc7\x56\x35\x7f\xf1\x1c\x95\x24\x8b\x05\x60\x67\x57\xde\xac\xf2\x2e\x6e\x5c\x81\xc8\xdb\xf5\x40\x9a\x81\x64\x09\xd5\x58\x2e\x36\xfe\x76\x0f\x56\x1b\x4f\xaa\x24\x32\xfd\x73\x38\x27\x93\xe4\xe6\x57\xc4\x6c\xee\x34\x19\x84\xd4\x93\xce\xd8\xf4\xcf\xf4\xd2\x20\x31\x92\x83\x9f\x12\x6c\x4f\x58\x73\x75\xaa\x7d\xf5\x23\x4b\x53\xf3\x8d\xba\x19\x73\x53\x54\x02\xd1\xe0\x38\x53\xd5\xae\x52\xbe\x81\x28\x4b\xb9\xe9\x01\xbf\xfd\xed\xf6\x9f\xee\x6f\x19\x0d\x49\x1f\xec\x2c\x79\xa9\x30\xeb\xf8\x50\xae\x0b\x98\xef\x38\x9e\x43\x5e\x67\x22\x0a\x91\x4f\xb7\x31\xa9\x3d\xbf\xf5\x65\x22\x4d\xd0\xc9\xf7\xc6\x79\xbd\xdd\xcd\x87\x29\x99\x00\xe1\x36\xe5\x65\x75\x38\xf2\x72\xda\x63\x47\x32\x49\x74\xe0\x52\x92\x4f\x5e\x68\x69\x7c\x19\x19\x06\x58\xbe\x2e\xe1\xc7\x46\xed\x78\xf9\xf6\x1d\xf8\xd1\xc7\xe1\x99\xcc\xa4\x23\x09\x5a\xb7\xaf\xba\xae\x0e\xcf\xdb\x95\x3f\x28\x8c\x7c\x0c\x57\x26\x39\x6c\xff\xac\x44\x3c\xec\xdd\x70\xe2\x5a\xc6\xe8\x0c\xf0\x31\x19\x10\x85\x08\x14\x5c\x81\x9b\xd2\xf2\x67\x22\x6a\xd0\xaf\x52\xa0\xa6\x31\x11\x89\x1c\x0d\xf3\xf2\xe4\x09\x40\x31\x0c\x80\x1c\x8c\xb1\xdb\x32\x7b\xd0\x4f\x06\x90\x20\xea\xde\xc6\x6b\x79\x89\x69\xd9\x2b\x40\x46\x96\xc9\xa5\x34\x17\x4e\x9b\x7c\x50\x66\x99\xff\x00\x3c\x08\x43\xb4\x62\xa8\xcb\x34\x42\xb9\xf0\x00\x00\xd3\x8c\xb7\xd5\x8b\xa1\x2a\x59\x1c\x8f\x45\x3e\x53\xb3\x98\x63\xab\x23\x18\x41\x30\x2b\x17\xbc\xcd\x5f\x26\x10\x15\x4e\x40\x83\xb5\xec\x46\x26\xee\xac\x2a\x38\x9a\x06\x9c\x06\x81\xf4\x9c\x6d\x25\x72\x39\xb9\x1b\x65\x60\x80\x29\x46\x80\x7a\x56\x8d\xc0\x19\x09\x1e\x66\x3c\x30\x24\x57\xc8\xa2\x95\x1f\xe0\x42\x04\xcd\xa3\x4c\x63\xa7\xd7\xbe\x86\x12\x7e\xb8\xdf\x8a\x94\xc1\x37\x19\x79\x15\xd7\x9c\x3c\xbe\xd5\x38\x36\xe1\x8e\x02\x75\x92\xf8\x85\x26\x0e\x39\x8f\x55\x84\xde\x93\x5b\x21\xfb\xcf\x73\xdd\x3c\xe9\x9e\xdf\x52\xa0\x55\x87\xc3\x4c\x83\xe2\xd9\xf8\x94\x39\x13\xd3\xbd\x96\x92\x1f\xe0\x1b\xd4\xb9\xce\x61\xac\xae\x4e\x78\x12\x06\x91\x41\x3b\x39\x0a\xfe\xed\x8b\x7f\xb5\x49\xc8\x39\x78\xb0\xd9\x1d\x9c\x07\x2b\x3c\xc9\xb4\x91\xa9\xfc\x91\x97\x83\x92\x05\xa1\xe9\xb8\xf9\x6f\xe0\x62\xf3\x04\x62\x64\xac\x38\xe4\x65\xbb\xab\x81\x37\xa7\xfa\x63\x94\x91\xe3\x69\x44\x23\xc3\x08\xd0\x9e\xea\x12\x01\x8c\xee\x48\x9a\xa0\xf3\x9b\xa3\xcc\x10\x32\x09\x5e\x28\x23\x71\x2e\x18\x32\xdc\xfc\x80\xfc\xe5\xd5\x3f\x13\x57\x41\xa6\x6c\x41\xba\x2a\x3f\x43\xb3\x71\x11\xc6\x28\xd0\x67\x1b\x7b\x2d\x2c\x7f\xb2\xe0\xb8\x4c\x28\x02\x3e\x6d\x80\x79\x39\xb6\x76\xe3\x55\x68\xb4\xd5\xbe\xaf\xf6\xdb\xaf\x8b\x27\x87\xc7\xe5\x52\x07\x58\xd3\x5a\xd4\xed\x72\x0a\xd1\xe1\x8a\x8a\x2c\xf3\x9f\xc2\x51\xbd\x5b\xb7\xfa\xd2\x1b\x50\x51\x88\x1b\xf2\x6b\x55\x28\x97\x64\xf4\x17\x4c\xac\x82\x22\xca\xa1\x9c\xea\xd2\x5b\x70\xae\x84\xa0\xb6\x43\xd3\x6f\x0f\xb3\xd4\x43\x84\x2b\x15\x61\x3a\xef\xb5\x0b\xec\x8b\x11\x17\xd3\x85\x95\x0c\x82\x60\xac\x79\xe4\x1f\x82\xcb\x37\x5b\x96\xb9\xb0\x0a\x41\x12\xcc\x3c\x1b\xc5\xec\xed\xe6\xf6\x9b\xef\x38\xe3\x3a\x0b\xb0\x0c\xa1\x4f\xa5\xe4\x9e\x9d\x9f\x70\xcd\x8d\x33\x7f\xac\xe1\x3d\x2f\xf2\x17\x50\xcf\xe5\xed\x8c\x58\x90\x19\x2e\x02\xcd\xd0\x1f\x38\x35\x50\xf7\x9d\xe3\xe3\x31\x24\x0c\x44\xec\xe1\xa3\x7d\xab\xba\x89\xaf\xdc\xa0\x98\x72\xcb\x5d\xb7\x6f\xf3\x03\xe8\x7a\xc8\x16\x3a\xf9\x55\x12\x43\x24\x3d\xa9\x3b\xf6\xa5\x4e\xfc\x0b\x41\xa4\xa1\x88\x7b\xe5\xcd\xb8\xa5\x62\xe8\x91\x0b\x02\x51\x60\x0d\xe9\x5d\x5e\xb6\x5d\x9c\x89\x2c\x00\x1f\x93\xab\x51\x4a\x22\x8b\xe2\x85\xc3\x71\x90\xa6\x16\x94\x3a\x41\xa1\x62\xfd\x53\x16\xa7\xa9\x18\x13\x11\x94\x45\x28\x3c\x76\xac\x8e\xb7\xbc\x7c\x39\xf5\xc5\x73\x41\xa3\x14\xd9\x26\x11\x53\xf2\x1d\xe0\xcd\x24\x20\xdc\xd1\xd4\x10\x14\xef\x4e\x45\x7e\x1c\xce\x3e\x41\xb9\xc4\xf3\x24\x32\x91\x4c\x52\x72\x82\x45\xd2\x49\x21\x6c\xad\x4f\x32\x9a\x76\x82\x65\xc6\xf7\xda\x5b\xcb\x84\x69\xf4\x89\x99\x15\x0c\x4c\xa7\x9f\x2e\xba\xf5\xbf\xaa\xbc\xfb\x2b\xc2\x20\x73\x5a\xab\xdf\xab\x5a\x19\x14\xd6\xd0\xbb\x11\xa1\x32\x45\xeb\xd5\xef\x57\xcb\x73\xde\x58\x22\x42\x6d\xfa\x02\xff\xaf\xca\xc7\xf4\xa5\xf6\x78\x24\x0c\xf6\xea\xe3\xd0\x4e\x65\xb4\x88\x88\x83\x54\x66\x2e\xa1\x9d\x97\x58\xd0\x3f\x4d\xc9\x94\x06\xc3\x43\x89\x9b\x74\x2f\x7b\x35\xc3\xbc\x86\xda\xcc\xa2\xd7\x1f\x7a\xc6\x1d\x6e\x98\x0c\x9d\xe7\x68\xf5\xaf\x34\x56\x21\xda\xfa\xa7\xf5\xe3\xed\x62\xb9\xde\xba\x77\x95\x24\x29\x8b\x3c\xc2\xc0\xc1\x22\xe7\x78\x67\x89\x48\x38\xc4\x36\x53\xaf\xd0\xb9\xae\x6a\x6c\x60\x18\xbd\x9a\x44\x1b\x05\x7b\xc3\x96\xf9\x04\x7f\x9e\xf2\xda\x14\xd4\xcf\xb6\xb5\x61\x24\x6c\xcf\x4e\xe3\x38\xb0\xb7\xf3\xb5\x3a\xd5\x2f\x05\x6f\x9a\x71\x41\x5d\xa4\x32\xc4\x72\x44\xc1\x1b\xc7\xc9\x60\x6e\xd6\x1e\xcf\x42\x89\xf0\xc5\x16\xf3\xf6\xdf\x3d\x78\x5c\x64\x5c\x63\x31\xcf\x78\x07\x57\xd0\xfa\x89\x9c\x49\x91\x3a\x01\xb8\xbc\x3d\x15\x3c\xaf\x61\xdf\xb9\xac\x2d\xec\x63\x3f\x08\x02\xdc\x6f\x9e\x4b\xfe\xd2\xb9\x78\xe3\xcf\xc3\x03\x4b\xfd\x5f\xe5\xe5\xae\xae\xaa\xa3\xbf\x38\x0f\x43\x8c\x04\x8d\x43\x3e\xab\x1c\x38\x79\x09\x3c\x89\x70\x31\xeb\x5c\xb8\x80\x78\x08\x8e\x12\x22\xa6\xd4\x58\xe5\xa2\xed\xdd\x48\x21\x92\x14\xf3\xe0\x07\xfe\x06\xbe\x1d\xf8\x62\x3a\x62\x3c\x3d\x04\x37\x14\x16\x28\xbb\x8d\x14\x6b\x27\x51\x5c\xf2\x2b\x85\x24\x06\xc1\xa1\xab\xfa\x05\xfb\x6b\xce\x13\x02\xe3\xb7\x23\x93\x18\x7d\x74\xf8\xd9\x42\xa9\x1e\x9f\xd6\xbb\xd5\x7a\x32\xb9\x64\xc2\xf1\x1b\x34\xaf\x9c\xed\x23\x47\xf2\x49\x84\x8a\x22\xdc\x50\x3a\x6f\x6e\x05\x92\x7f\xf8\x9d\x6e\xfa\x64\x17\x9b\xb1\x84\xe2\xa6\x5d\xd6\x98\xe3\x4d\xe7\xb0\x7c\x19\x14\x97\x84\x52\x24\xb4\x49\xc1\x75\xa9\xaa\xba\x41\xf5\xbd\xcf\xdd\x30\x01\x49\x86\x3b\x4b\x37\xc3\x8f\xcf\x7d\xf7\x5c\xfc\x6f\x37\x40\x05\xa8\xe1\x32\xa8\x62\x0b\x9d\x72\x74\x4f\xa0\x54\x9b\xe5\xc3\xfe\x07\xf1\x07\x34\x20\x52\x0d\xd9\xd0\xd1\x6a\x16\x7e\xc7\x96\x41\x64\xe2\x87\xcb\x3c\xbe\xe1\x30\x81\x26\x49\xc8\x1c\xee\xd3\x54\x68\x8c\x05\xc5\xb0\xa5\x3b\xb7\xbf\x32\x89\x08\x26\xa3\x25\x2f\xe4\x3d\xfc\xd8\xbe\xe5\xe5\xe2\x78\x04\x5e\xf7\x64\xa4\xce\xd5\x73\x38\x3b\x49\x22\xd3\xc6\xbd\xcc\x8f\xaf\x50\x3f\x16\xfc\x63\xde\x3f\x91\xb4\x8b\xb3\xfe\xe7\x7f\xff\xe7\x6e\xf1\xbb\x2f\xe9\x2f\xee\x1e\x9e\xef\x77\xee\xe7\xa9\x8e\xc3\xb0\xcf\x00\x85\xee\xef\x2c\x48\xd1\x35\x7b\xac\xab\xe6\x88\x86\xa6\xb9\x71\x82\x36\x6e\x4c\x18\xa6\xa8\x37\xf0\x96\x97\x2f\xaa\x3a\xb8\x42\xd8\x35\x40\x5f\xc0\x97\x61\x92\x78\xc6\xaa\xaa\x73\x81\x7f\xcb\xbd\xb3\x29\x43\x25\x90\x40\x04\xda\xd7\xfd\x01\x7c\x6c\x24\x23\x92\x11\x6b\x84\xae\xdc\xdf\xe2\xd4\x14\xca\x30\x84\xdb\x37\xaf\xbc\x86\xfd\x71\x90\x5e\x92\xb1\x0a\x10\x60\xc4\xf3\x7a\xe5\x7a\x7d\x57\xd0\xb4\x75\xe5\xc2\x75\x99\x06\xd2\xb1\xe4\x3e\xd7\xf9\x0c\x88\x56\xa6\x92\x27\xbd\x47\x6e\xaa\xf1\xb3\xa1\x8e\xcc\x02\x8e\x49\x39\x0b\xaa\x47\x74\x42\xd3\x19\x9f\xab\x0f\x97\x2b\x98\x5f\xbc\x32\x23\xa6\x96\x51\x9b\x6a\xc0\x1a\xd3\x1f\xfd\x73\x64\x8c\xa0\x9b\x3a\xc5\xb2\x7d\xba\x18\x64\xc6\x42\xfc\xd4\x3b\x68\x5a\x1b\x37\x8d\x3e\x56\x16\x71\x5c\xc5\x37\xdb\xcd\x2c\x3c\x7c\xb8\x68\x27\xb3\x28\x53\x14\x77\xa8\x83\x01\xc4\xbb\x34\xc6\x3f\x4e\x55\xed\x7b\x7c\x24\x0f\x02\xc4\xb7\xae\x6f\x37\xbf\xdb\x7c\xfa\x16\x06\x1d\xf3\x92\x27\x01\xf2\x4d\x62\x0d\x72\x95\xbf\xfb\xbf\xa7\x1a\xf5\x6d\x6e\x77\x4f\xa3\x1b\x16\x8c\x08\x23\x11\xd4\xf3\x05\x13\x29\x38\x60\xca\x59\x8e\xfa\x23\x1a\x67\xac\xa4\x22\x51\xa0\x70\xf3\x73\x74\xa2\x67\x70\x0b\x09\x91\x70\xa4\x47\x9b\xb2\xdb\x6d\xf3\xf7\x41\xb7\x92\x84\x04\xb0\xb6\x5b\x1d\xa1\xec\x37\x8b\x38\x1c\xf2\x75\xfb\x59\x00\x3c\x46\xed\x63\x59\x7f\x1c\x5b\x7e\xaa\x9d\xfe\xad\x3b\x2c\x4c\x9c\x85\x35\x71\x4b\x1f\x34\xa3\x45\xd1\x0d\x64\x28\x91\x63\x61\x17\x6d\xcd\x5b\x78\xc9\xa1\xe9\x2b\x97\x7e\x82\xa8\x20\x0d\x63\xe9\xf4\x2e\xb1\x79\xe1\xc2\x6e\xf6\xff\xd5\xbf\xee\x77\x79\x98\x5a\xb0\x97\x97\xd7\x1c\x5a\x79\x15\x70\x81\xfd\xf3\x56\x98\x63\xc8\x26\x3f\x24\x5e\x22\x8a\x04\x0a\xd7\xce\xb6\xad\x4a\xb8\xad\x5e\xe6\x9d\x78\x45\x03\x23\x20\x32\xe0\x21\x19\x73\xe3\xba\x71\x11\x45\x9f\xa5\xa8\x7a\x6a\x2f\xa2\x68\x92\x61\x94\x75\x84\xba\xa9\xca\x5e\x3a\xce\x1f\x4f\x03\xc5\xfa\xa2\x04\x66\x9f\xdd\x6e\xa0\x58\x4c\xb0\xfd\x6d\xf5\xdb\xb6\xff\x93\x14\x1e\x5f\x8f\x8b\x72\x5d\xb6\x79\x6b\x84\x62\x2b\x3d\x06\x10\x8d\x97\x90\x0a\x53\x8e\xb1\x8b\xad\x7c\x2c\x5f\x79\x59\xc2\x45\x76\x7f\x77\x92\x4c\xa4\xd1\x31\x39\xe4\xed\xf6\x0d\xcb\xb1\x9d\xbb\x71\x93\xbf\x5f\xc0\x43\xa7\x7f\xf1\x4b\x86\x32\x45\xff\x65\x9b\xbf\x94\x7e\xe2\xab\x88\x11\x2c\x82\x2e\xf9\x31\x6f\x7d\xb0\xa0\x22\xc1\x50\x4a\xd4\xaf\xa8\xdd\xcf\x41\x26\x4f\xc5\x44\x60\x80\x84\xc8\xca\x1c\x6a\xb7\x85\xa8\x24\x30\x49\x35\xac\x61\xe1\x2b\x5e\xf2\xde\xf1\xea\xd3\x15\x2a\x51\x44\xa9\x5f\xaa\x42\xff\x97\xff\x7e\xce\x4d\xe0\x8a\xd1\x2a\x01\x89\x34\x4f\xc6\x8a\x23\x71\xfe\xba\x57\xbd\xb7\x83\x52\x2a\xb1\x7e\xb8\xbe\x5a\xdc\xbb\x92\xb1\xea\x1c\x65\x0c\x91\xa4\xb1\xcf\xdb\x53\x8d\x20\x0a\xa4\xce\x2e\x26\x32\x16\x44\x65\x24\xc2\xbc\x0a\x4e\x9c\x51\x32\x46\x65\x04\xb0\xc7\xa6\x05\xf9\x5a\x56\x45\xf5\xf2\x31\x9d\xaa\x9c\x6a\x61\x92\x13\x6d\x9d\xc3\x3b\xac\x16\x0f\x96\x1a\x64\xf0\x1a\x39\xa3\xe8\xed\x6c\x5f\xab\x63\x2e\x8a\x9e\x89\x4a\x71\x8b\xcb\x6f\xa0\x28\xae\x8b\xca\x43\x87\x15\x17\x26\x54\x78\x58\x6c\x66\x41\xf6\x76\x98\xc8\x0c\xd1\x8e\xe7\xcf\x9b\x0b\x26\xec\x58\x49\x98\x4b\xff\x74\xb3\x6b\xa6\x35\x77\x70\xcb\x4a\x9a\x28\xf0\x79\xbb\x5a\xfe\xee\x6e\x4a\x29\x9d\x04\x83\x1a\xdc\xba\x7d\xfd\xca\x4b\x55\xc0\x3c\xb0\x58\x01\x27\x58\xc4\xc2\x75\x79\x55\x70\xf9\x36\x84\x96\x4c\x06\xeb\x04\x44\x37\x29\xff\xb8\xfa\xed\x12\xca\x86\xce\x2b\xe0\x91\x2e\xfa\xc0\x56\x8b\xda\xf4\x83\x7d\x87\x7c\x53\x6e\xa1\xd0\x9d\xb7\xf1\xc5\x8d\x09\x43\x03\x07\x33\x79\xea\x70\xd2\x09\x07\x81\xa4\x18\x9a\xfe\xc0\x32\x1e\x7a\x20\x7e\x8b\x04\x12\x49\xec\xd3\x93\xbc\x3c\x35\x67\x90\x27\x60\x82\xa0\xfa\x57\xb7\x47\x34\x5e\x69\x91\x00\x93\x41\x60\xc2\x8e\x1c\xa9\xdf\x77\x8e\x49\x90\x40\x28\x05\x76\x5b\xe5\xe5\x3b\x34\xc6\x0c\xb7\x63\x2d\x30\x02\xa1\x32\xe0\x04\x93\x7e\x6c\x5e\xf3\xe3\x53\xd5\x0c\xee\x2a\x04\xae\x7b\x47\xe7\xb9\x81\x7a\x0a\xd9\x98\x2b\xa8\x9e\x55\x5d\xc7\xcf\x12\xea\x04\x51\x59\x9e\xb5\x73\xca\x7a\x3e\x57\x1b\x76\x9e\xb0\x9f\x6d\x10\x11\x8e\x89\x8c\xce\x42\xa2\xaf\x77\x92\xe7\xfd\x9a\x10\xc5\x06\x92\xba\xe4\xcd\xeb\x83\x27\x62\x83\x28\x0b\xb1\x5c\xdb\x59\xb3\xab\x93\x0b\x5f\x21\x8e\x03\xc7\xdb\x68\xb0\xc6\xb0\x1b\x14\xaf\x20\xe6\x86\x31\xb2\x84\x9f\xc8\xc8\xe0\x9b\x10\x20\x01\x23\x2e\x2f\x5d\x65\xec\xea\x54\x97\x23\x3e\x1a\x48\x33\x8e\x2a\xf1\xa6\x9d\x7b\x78\x80\x27\xa9\x0d\x18\x16\x26\x67\x6a\xa9\x93\xfc\xef\x66\x4c\xc4\x6c\xb0\x08\x77\xf9\x71\xfa\x1d\x66\x57\x24\x64\x51\x82\x98\x03\xe0\xad\xed\x77\x69\x16\x45\xfe\x3e\xf1\x8a\x80\x07\x01\x62\xee\x4c\xe2\x77\xc7\xdf\xb0\x2b\xdc\x14\xee\x2e\x84\xa1\x20\x02\x81\x39\x0d\x28\xf2\x43\x5e\xf2\xfa\xff\x4e\x2f\x5c\x4d\x38\xf9\x09\x88\xd4\x70\xb8\x0c\x35\x83\xd4\x99\x32\xe4\x64\x82\x48\x11\x62\x19\x13\x3b\x9d\xbb\x3d\xf3\x36\x3f\xe4\xed\x0e\x3c\x13\x15\x40\x92\xe2\x87\x58\xec\x76\xfe\x4f\xa9\x4c\x52\xa7\x36\x34\xf4\x38\x40\x67\x26\xc1\x50\x83\x73\x4e\xfe\x5a\x39\x51\x13\xce\xb1\xda\x66\x12\x69\xdf\xaa\x16\x3c\xe9\xf9\xac\x39\xd2\x44\x19\x8a\x72\x94\x11\xca\xff\x03\x73\x7d\x06\x9a\x86\x82\x0d\xb5\xc0\x56\xd0\xf2\xbc\x98\xec\x19\x9a\xc5\x1c\x1f\x67\xfd\xf4\xb0\x5d\x3e\xf8\x66\x31\x1d\x32\x6d\xe4\x30\xef\x37\xcb\xe1\x53\xea\x50\x64\x32\x9d\xc4\x24\x37\x97\x7a\xdc\x74\x14\x72\x64\x78\x28\x27\x7a\x52\xee\x70\x2c\x9c\x62\xe4\x53\x55\x14\x0f\xa7\xf6\x78\x1a\xd3\x54\xa6\x13\xa7\x63\xfc\x22\x12\x4d\x31\x8e\xd9\x8b\x1a\x40\x7d\xcf\xdb\xd7\x79\x37\x4f\xa7\x21\x51\x89\x4f\x0b\x5d\xf7\xe8\x44\x9d\x72\xc5\xe5\xc0\x7c\x0d\xca\x52\x3a\x05\x8e\x62\x00\xe5\xe9\xf0\xa0\x57\xd0\xcd\xe8\x1a\x14\x2a\xbb\xba\xf8\xcb\xed\xb0\x3a\x0b\x28\x7a\xfc\x4b\xd3\xcb\xf6\x0d\x9a\x76\x7b\x84\x29\x76\x5a\x67\x24\x40\x03\x6f\x5e\x1f\xe6\xb4\xfb\xcd\x4a\x73\x96\x79\x99\x5c\xc4\x22\xf9\x16\xe6\xf1\x55\x78\x14\x06\x3d\xa3\xfb\xb7\xaa\x73\xd9\x90\x58\xe9\x2f\xfb\xe9\xfe\x42\x71\xec\xd4\x41\x8d\xc3\xe8\x19\x42\x46\x41\x88\xe6\x92\x62\x49\xf2\xba\x2a\x8a\xea\xc7\x79\xff\xdf\xe0\x19\x34\x04\xd2\xd2\x9a\x3e\x41\x93\xab\x13\x2f\x66\x27\xa8\x08\x18\x82\x00\x6f\xaa\xaa\x67\xc7\xfb\xd5\xed\x8f\xdf\x83\x20\x0a\x11\x4a\x0e\x11\xe7\xfe\xcc\x42\xcc\x4c\x37\xae\x9f\x15\xf1\x93\x98\x48\x9d\xaa\x15\xcf\x96\x44\xb4\xa4\x44\x5b\xe8\xd7\xb6\xe5\x5a\xaf\xf2\x06\x7b\xe1\x90\xd2\x7b\x0e\x4e\xa6\xa5\x64\xc2\xd2\xb1\xbe\x80\x0b\x15\xb5\x0a\x33\xe1\x3a\x10\xae\xe7\x14\xf2\x88\x56\x19\xd5\x96\xcc\xa0\xcd\x4d\x5e\x0e\xcd\x72\x93\xbf\x8c\x5a\x81\x35\x08\x8e\xa0\x03\xd3\x89\x62\xf9\xef\xed\x31\x2d\x38\x46\x45\x8f\x8f\x37\xd6\x50\xd1\x20\x48\x0d\x8c\x88\x23\x09\xca\x55\xae\xae\x91\x4f\x72\x1e\xe8\x42\x83\x40\xc9\x84\x0d\x04\xc4\x3a\x37\xf5\xf5\x1c\x37\x46\x03\x42\x29\x35\x6d\xb5\xde\x5b\x9f\x8e\x10\xda\xc1\xef\xda\x02\x7d\xdd\xe1\xdb\xa5\x41\x17\x9c\x75\x4f\xf2\xed\x61\xb7\xb9\xbf\xd9\xaf\xef\x57\x08\x0f\x75\x37\x4e\x40\x61\x69\xd1\xd9\x72\xbf\x4b\x5d\x82\xae\xf6\x0f\x41\x99\xd1\x5e\x69\xac\x76\x82\x25\x3b\xd9\xdd\x3e\x7e\x99\x0c\x84\x10\xf1\x89\x05\x6f\xda\xfd\xab\x0f\x35\x68\xc0\xc2\x14\x57\xe0\xae\xb2\xed\xf8\xee\xef\x91\x86\x5e\x22\xce\x62\xa8\xf3\x83\x59\xc1\x33\xac\x06\x34\x08\xb3\x08\x63\xbf\x3b\x5e\xf2\x17\xf0\x17\x4a\x42\xe2\x04\x1f\x7b\xe9\x93\x53\x0f\xfa\xa5\x41\x22\x12\xcc\x12\x6e\x17\xb7\xa6\x4b\xc6\x9d\x9a\x0a\x86\xb3\x49\xe7\xa5\xba\xce\x5f\x4e\xf5\x24\x02\xa0\x41\xc6\x80\x88\x9e\x4b\x63\xc9\x2d\xb7\xfb\x75\x5d\x1d\x1e\x6b\x78\xcf\xab\x53\xf3\x29\x6b\x32\x0d\x32\xee\x69\x56\xb6\xf8\x58\x06\x32\x35\xfe\x82\x1c\x14\x86\x13\x47\x54\xa5\x7c\xad\x01\x7a\x79\x08\x1a\x88\x94\xa3\x03\xdc\xb6\xc5\x06\xad\xea\xd0\x41\xa1\x81\x10\x22\x15\x0e\x37\xa0\x5c\xa9\x24\x34\xea\xc6\x7f\xeb\x0b\xce\x34\x9c\x66\x7d\x2f\x93\x48\xd0\x40\x48\xa3\xc8\xd9\xed\xbd\x3f\x66\x18\x31\xed\x30\x49\x22\xd9\x7d\xc7\xbd\x6b\x14\xf1\x6c\x53\xe3\xab\xfe\x8b\x7d\x42\x2b\x36\x6b\x4c\x69\x20\xc3\x00\xdb\xd8\xef\x2a\x95\xeb\x8f\x2d\xb4\xed\x50\x4e\xfd\xff\x55\x46\x84\x06\x52\x86\x28\x5d\x88\x1f\xe0\xfa\x54\xca\x33\x2c\x25\x0d\xa4\x0a\x42\xd7\xd6\x68\x20\xb4\xd5\x67\x14\x06\x34\x90\x3a\x80\x64\x00\xb9\xbd\x5f\x7c\xbb\xcb\x65\x5d\x3d\x6f\x57\x93\x19\xa5\x94\x76\x65\x53\x47\x8e\x60\xae\xe8\x76\x3e\x1a\x28\xd0\xb1\x47\x43\x99\x6a\x3e\xba\x5f\xa6\xe2\x59\xd5\x1f\x36\xb9\x65\x87\x03\x8d\x30\x67\x62\xaa\x5b\xdf\x21\x9f\xfc\x22\x68\xc1\x5d\x3e\xeb\xa6\x86\x8f\x0b\x8f\xa0\xc3\x58\x1a\x23\xc3\x6b\xf9\x3a\x67\x94\xbb\x31\x80\xb5\xf3\x63\xfe\x13\x8a\xbe\x79\x02\xb9\xc8\x70\xf9\x8b\xd3\xc7\xd5\xa9\x2c\x3f\x46\x0b\x90\x04\x32\xe6\x1e\x5d\x55\xd5\x8f\x3c\x57\xfe\x44\x9d\x21\x26\xb8\x9b\x39\xe8\x07\x6c\x07\xf6\x9e\x12\x92\x84\x18\xea\xaf\x1c\x5d\xec\x3b\xd4\x8d\x17\x94\x1c\xdf\x1d\x21\x99\x69\x41\xb6\x54\x90\xc3\x50\x71\x3a\x90\x63\xcf\x82\x73\x2b\xaf\xab\xda\xf6\x65\xd9\x01\x34\xa2\xcc\x52\x1a\x23\x3a\x75\x76\x26\x11\x16\x44\xc4\x78\x3a\xc8\x5d\x74\xe2\xc5\x5d\x5e\x3a\x3f\xc6\xa7\xd3\x29\x61\x29\x43\xd5\xd0\x23\xd4\xd8\x8a\x2f\x6c\x2b\xb5\x43\x19\xf2\xe2\xcb\xe4\xc2\x59\x82\x89\xac\x6f\x39\xfc\xb8\x82\x96\xce\x7f\x31\xc2\x24\xc5\xf8\x63\xc5\x3f\xae\x3e\x56\x7c\x48\x3b\x43\x49\x44\x22\xb0\x34\x90\x9d\xfb\xa4\x4c\xf6\xbd\xd9\x37\x9e\xb2\x98\x92\x88\x02\x3e\x66\x0b\x4d\xfb\x50\x73\xe9\xfc\x48\x4a\xa2\x30\x1a\x73\x2f\x9c\xea\x72\xa8\x8b\xea\x86\x59\x81\xe9\xc6\x35\x04\xbe\x9b\x94\xdf\x19\xf3\x0f\x25\x71\xc2\x71\x1f\xd8\x2b\x5b\x2c\x73\xd3\x9d\xc4\x56\x06\xdf\x13\xcd\x54\xa2\xba\xb0\xce\x48\x92\x68\x6d\x43\xae\xdf\xe0\x63\x08\xce\xa2\x24\x4d\x8c\x0d\xe5\xef\x3c\x2f\xba\x08\xc8\xb4\xac\xf9\xdf\x49\x55\x8a\x08\x4a\x59\x00\xaf\x17\xa5\x5a\xa1\x7b\xfa\x81\x0c\x8a\xbb\x1f\xd5\x77\x80\x37\x3f\x36\x0b\x44\x18\x8f\xf2\x67\x36\xb6\xba\x70\x5f\x19\x23\x58\xa4\x58\x5a\x7a\x2a\x23\x45\x3a\xaf\xa4\x75\x9a\x21\x62\x9e\x1c\x1b\xad\x1e\xce\x28\x4e\x9f\x2d\xc8\x53\x9d\xb7\x39\x34\x7b\xe2\xee\x93\xc7\x86\x72\x14\xd3\xe2\xed\xa2\xae\xb9\x7b\x29\xa3\xfd\x85\xa8\x48\x60\xdf\xcb\xc9\x70\x4c\x1b\x67\xa7\xe7\x0c\xa4\x44\x65\x21\xf5\xed\x6a\x4f\x03\x1e\x12\x4a\x94\xce\xf0\x9d\xef\xbe\x6e\x9e\x76\x7f\xec\x57\x8b\x3f\xb6\xee\x10\x10\x47\x1c\x7d\xac\xea\x76\x63\x84\x89\x6c\x79\x79\x22\x9a\x41\x09\xf0\x18\x77\xdb\x65\x3d\x14\xd8\xa1\x04\x80\x23\x6b\x0c\x47\xd1\x70\xd4\x0f\xf7\x98\x93\xe9\x12\x07\xd0\x99\x2b\x32\xf1\xba\xce\xa1\xbe\x1f\x8b\x52\x51\xa2\x03\xc3\x1b\xf7\x35\xc7\xcf\x3b\x99\x86\x3a\x09\x31\xa5\xd7\xad\xf6\x9b\xaa\x7a\x02\x63\xee\xa6\xa3\x52\x93\x3e\x3d\x9e\xc4\x20\xe2\xa7\x44\x0b\xd3\xa3\xdd\x77\x03\x9b\x03\x34\x08\x68\xe2\x1b\xe5\x2d\x04\x66\xf4\x05\x68\x10\x68\xcc\xf4\x2d\x5e\x6a\x40\xb7\xf7\xb9\x2e\xd6\xa5\x3f\x9f\x67\x28\x67\xe7\xd6\xc0\x6d\xf5\x0e\xdb\xee\xf6\x3b\x1b\xd1\xfb\xd9\xe4\xcc\xbf\x9e\xcb\x7a\x51\x1a\xa8\x18\x17\x5b\xeb\x36\xe3\x01\x79\x0c\xa5\x24\x60\x08\xe3\x53\xd5\x13\x88\xd3\xc7\x6e\xac\x06\xda\x1d\x4f\x44\x4f\xa9\x6b\xda\x89\xfe\x59\x1d\x44\x3e\x6a\xf0\xa6\x94\xf2\x88\x6a\x87\x73\x79\xac\x9a\x16\xf9\x48\x7c\xf9\x60\xe3\xdf\x0e\x95\x19\x96\x8b\x14\xc8\x82\xd7\x60\xe0\xf0\x9d\xd1\xe5\xff\x99\x37\xad\x94\x05\x21\xf2\xed\xef\x9b\x23\xc8\x9c\x17\x43\x84\xd1\xfc\x12\xa4\x8c\xc5\x88\x25\x70\x4c\x79\xbf\x12\xe2\xf5\xa7\x49\x04\x1a\x5c\xf1\x52\xa2\x02\xc6\x3b\xd4\x2d\xd4\x0e\x30\xe4\x46\x45\xd4\xf5\xb2\x0f\xc8\x56\xc7\x5f\x38\x0c\x8c\x92\xfd\x56\x56\x47\xb7\xae\x68\x98\x0a\xb0\xbd\x38\xfb\x63\x0d\xfb\xb7\x0f\xb9\x47\x58\xec\xbe\x3c\x1d\x3a\x7f\x69\x92\x79\xa1\x34\xe4\x11\x3a\x7b\xc7\x53\xf3\xba\x7f\x83\x33\x35\xbc\xc9\x63\x87\x32\x09\xa3\x09\xb4\x75\x76\xf3\xa6\xa1\x0e\xb1\x34\x01\xbc\x2e\x3b\x3f\xaa\xf3\x61\xb7\x72\x20\xb9\x3a\xde\x25\x69\x44\x39\xda\xe5\xda\xb6\xeb\xa1\x02\x25\x3f\x0c\x7a\x63\x28\x8d\x6c\xb5\xde\xf9\x3d\xcd\xd5\xc7\x77\xfe\x0e\x23\x1c\xcc\x85\x1b\x8f\x89\x91\xfe\x35\xfd\x07\x5d\x64\xdf\x5f\x36\x4e\xcc\x06\x5d\xc2\x0f\x6f\x4b\x3f\x49\xf3\x52\x9a\x10\x41\x8c\x24\x8c\xe5\x5d\x1c\xe7\x70\x29\x4d\x59\x8a\xc1\xdb\xda\xe8\xda\x63\x53\xf7\x45\x4c\xf7\xfc\x0d\x67\x41\x86\xb9\x15\x43\x4a\xfd\x65\xf4\xfb\x19\x61\xc2\xa2\x03\x77\xc0\x0f\x53\x2a\x8f\x0b\x17\x14\x59\x30\x24\x59\xb1\x52\x39\x13\x9b\x47\x39\x33\x01\xce\x75\x55\xbf\x4c\x80\x96\x94\x0a\x66\x58\x2c\xf6\x4e\x0f\xef\xc2\xea\x10\x11\x27\xd2\x75\xd4\x16\x30\xb5\x4e\x22\x4b\x30\x68\xf6\x54\xc4\xe5\x15\xbc\xf2\x42\x4f\x6e\x45\xf0\x04\x9b\xa8\x9c\xe3\x84\xa1\xa8\xcb\x54\x50\x2a\x04\x4b\x51\x0c\xe3\x6a\x31\x4b\xed\x6c\x87\xc9\x94\x60\x42\xf5\x6e\xb3\xba\x79\x5a\xac\xd6\xfb\xdd\x1f\x8f\x6b\xe7\xf2\x51\x29\x8c\x16\x71\x83\x7d\x9c\x08\x81\xbb\xae\xea\xc5\x10\xbb\xd1\xff\xa2\x54\x71\xe4\xca\xc2\x87\x23\x97\xad\x09\xae\xe6\xbc\x3e\x2a\x21\xf3\xf9\x3b\x23\x2f\x6b\xf8\x25\x1c\x67\xb8\xdb\xfc\xa9\x8a\x0c\x9d\xbe\x21\x15\xc4\xb1\x13\x91\x65\x4a\x95\x36\x14\xe0\x2f\x06\xae\x36\x42\x5b\x51\x0a\x59\x80\x90\x6a\x38\x1e\xfc\x9f\xa4\x09\x90\xb1\xc6\x52\x77\xc6\x7d\xa4\xe0\x4e\x29\x28\x86\x99\xed\x6e\x6f\xe0\x85\xbd\xe0\xc3\xf4\x0b\x68\x2a\xa8\x5d\x70\xfb\xce\xdd\xdf\xcf\xd5\x4d\x26\xdf\x5e\x8b\x2c\xed\xeb\x65\x96\x1c\x75\x12\x9d\xd9\x4d\x9a\x05\x94\x63\x87\xcc\x9f\x27\xe8\x36\x9f\xb2\xb3\x14\x98\xc0\x1d\x5d\x92\x05\x99\xc9\x0b\x20\x30\xe0\x2e\x2f\x7d\x73\x3e\x65\x81\x8c\xa8\xe1\xc9\xb7\xd8\xe8\xd1\x03\x30\xc2\x53\x43\x4d\xd6\x1c\xdd\x19\x94\x44\x91\xfd\x30\x02\x5a\x43\x82\x86\x7b\xca\xe4\xd4\x2e\xce\xc9\x2c\x27\x89\xe1\x7f\xc8\xdb\x57\x03\xd5\x79\xe2\x17\x08\x56\x29\xa3\x29\xc1\x98\xa5\x3c\x1d\x1c\xcf\x6d\x83\x2c\x76\xfd\x2d\xd3\x14\x0c\x13\xf1\xf5\xe6\xdb\xfa\xeb\xf3\xfd\xea\xc9\x29\xc6\x50\x46\x33\x82\xf1\xda\x3f\x9e\x37\x0f\x43\x07\x9b\x51\x88\x11\x24\x63\x76\xc9\x6b\xc4\x55\x0c\x6d\x02\x8b\x38\x44\xd6\x39\xee\x6e\xb4\x3a\xb5\x43\xff\xb1\x9f\xc4\x2c\xa6\x1c\x1d\xd3\xaf\x1f\xa7\xf2\xef\x1c\x46\xbf\x12\xa7\x40\x6c\xe6\x6d\x61\x30\x32\x5f\x86\x67\x72\x86\x59\x58\xa4\x90\x7e\x79\xaa\x4e\xa5\xfa\x0d\x3e\x16\xca\x3f\x59\x0c\x71\x6c\x85\xc2\xef\xb9\xbc\xf0\x86\x62\x10\xd8\x9a\xde\x9c\x84\x21\x61\x1d\x17\x89\x66\x2b\x45\xe7\x04\x85\x94\xc5\x9a\xa5\xb6\x08\x73\xc3\x0f\xdd\x36\x7f\xe1\x07\x93\x30\xd4\xa6\xb8\xf0\xb1\xb4\x74\x9c\xe8\x75\x22\x2d\xe6\x60\x73\x66\x49\x64\x14\xeb\x5f\xa0\x5d\xba\x47\x4a\x74\xa8\x4c\xbb\xc1\x3b\x14\xd5\x11\x6a\x6c\xa5\xb4\x06\xd7\x8e\xc9\x58\x46\x1d\xf5\x8c\x81\x14\xf1\xe2\x89\x7b\xf5\x2b\xca\xb2\x88\x60\xd2\xfd\x7b\xae\x6c\x79\xd4\x6e\x8a\x93\x79\x9e\x25\x51\x6c\x2b\xa3\xc6\x0f\x9a\xf7\x57\x58\xa6\x28\x96\xe1\x7f\xb3\x08\xf5\x2d\x2f\xe0\xee\x12\xbe\x9a\x32\xce\x12\x44\x45\xae\x6c\x73\x60\x5e\xce\xc3\x29\x28\xe3\x61\xe6\x32\xaf\xeb\x46\xd6\xd5\x8f\x8b\xcc\x27\x94\xf1\xc8\x90\xa4\x6c\xdf\x46\xa1\x20\x13\x91\x70\xbd\x3e\xe6\x21\x9e\xcd\x4f\x4c\x9e\x55\x24\x19\x32\x81\x5d\xe5\x6d\x2f\x5a\x45\x99\x10\xa6\x91\x11\xb5\x41\x96\x45\xd5\xc0\xac\x70\x13\x65\x42\xc6\x7a\xe8\x0b\x98\x26\xd9\x59\x5f\x84\x09\x90\xc8\x8c\x66\x4a\x89\xf2\xe4\xa9\xb1\x28\x13\x5a\xe1\x26\xf2\x03\xf2\x47\xa8\x97\x5f\xaf\xdd\x01\xc9\x58\x96\x0c\x3e\x6a\xf3\xc8\x73\xb5\xab\x6e\xf8\xa4\xad\x9c\x32\x99\xc6\x88\x6b\x72\xdb\xd4\xd5\xa9\x78\xbb\x24\x23\xe1\x2d\x9f\xa2\x06\xeb\x84\x55\x78\x50\xab\xfc\x3d\xef\x42\xd9\xbf\x9f\xea\xbc\x51\xb9\x34\x21\xeb\x68\xd7\x64\x8a\x49\x04\x59\x59\x4e\xee\x61\x7a\x99\x32\x15\x87\x56\x2f\xc4\x34\x6c\xd8\x3e\xf2\x09\x90\x9c\x32\xc5\x09\x96\x7b\xb1\x29\xc6\xb3\xed\x9d\xdd\xe7\x6c\x4d\x96\x32\xe8\x42\x1a\x9f\x46\x1d\x36\x06\x4e\xc9\x04\x69\xe0\x4e\x61\x90\xf6\x5d\x13\xf3\xa8\xd0\xf1\x97\xd5\x21\x41\xef\x57\x9e\x5c\x53\x2d\x0d\x83\xc4\x7c\xc1\x77\xa8\x73\xfd\x61\x29\x2d\xdc\xe9\xf6\xd5\xf6\x9a\x2d\xdd\xff\x4e\x0a\x04\x97\x20\xb6\x7d\xbe\xd0\xfd\x92\x4a\x79\x5f\x9b\xe9\xc2\xf4\xe2\xe3\x69\xd8\x7d\x31\xba\xd9\x90\x48\x23\x57\x64\x89\x41\x46\xa8\x0c\x1a\xd2\x40\x63\x56\x1e\xb5\xd9\x0e\xf9\xc9\xc0\x3a\x6e\x3f\xd9\x44\x27\x97\xa7\x61\xa2\x89\x4b\xe7\xf2\x1a\xd5\xc3\xfa\xde\x37\x1a\xd2\x88\x60\x1b\xfc\xce\x03\x43\xd8\xcd\xf8\x8b\x87\x54\x07\xa8\x0b\x61\x74\x64\x86\x27\x33\x11\xbb\xd5\x3e\xdb\x83\x73\x3e\x6d\x43\xa6\x23\x42\xfb\xaf\x59\x73\xf9\x36\x9e\xa5\x61\x08\x01\x33\xd1\x97\xce\xcb\x7c\x8e\xec\x80\x86\xa1\x66\xb8\x4f\x6c\xdd\xde\xea\xee\x28\x12\x86\x27\xc8\x2c\x0a\x9c\xa3\xd7\x55\xdd\xbe\x82\x3e\xb5\xa7\xda\xdf\x78\xcc\xcc\x8d\xdb\x14\x80\x65\x1a\xe8\x2d\x79\x18\xab\x94\x19\xc2\xd2\xc2\x89\xcd\x2f\x79\x59\x56\x16\xb6\xeb\xc3\xdb\xcf\x3e\x82\xeb\x9b\xa2\xae\x86\x39\x57\x6b\xa2\x61\x42\x34\x52\x3b\x74\xfb\xc9\xbb\x91\x03\x9d\x33\x97\x61\x92\x4a\x8c\x4a\x97\xbb\x4f\x68\x77\x69\x98\x08\xc9\x6c\x6f\x4e\x75\x6a\xfd\xfc\x4f\x59\xa4\x88\x2d\x33\xd5\xd5\x85\xa4\x6a\x98\x2a\x8e\x5f\x67\xfd\xd3\xd5\xc0\xbb\xbf\x41\x6a\xc9\xf0\x27\x5f\x2a\x55\x1a\x7d\xa3\xdf\xaf\xdd\x6e\x17\x66\x94\x46\xd6\xa8\x5a\x79\xfb\xff\x80\x7a\x6e\x26\x04\xe7\x6e\x70\xc4\xe5\x30\x8b\xb0\xac\xca\x97\x73\xe3\x1b\x66\x89\xc0\x3e\x9b\xf5\xee\x1f\x27\xde\x4b\x8e\xd1\x90\x53\xa2\x2d\x55\xda\x55\x5e\x14\x48\x90\xe3\x37\x82\x50\x48\x3d\xc9\x89\xf5\x0a\x7d\xe3\xad\x24\x14\xa0\x8d\x55\x2a\x90\x4e\x7c\x7a\x58\x66\xa6\x85\xfd\xea\xf9\x8f\xf5\xd3\x7e\xb9\x78\xdc\x7f\xdd\xdc\x7c\xdd\xfb\x0e\x54\x1a\x2a\xca\xc0\x28\x66\x22\xd1\xe2\x50\x9e\x64\xf2\x86\x55\x16\xdb\xae\xdf\xf7\xea\xcd\xb9\xf4\xe3\xc9\xad\x04\xa0\xeb\x6d\xf2\x32\xe7\xcc\x89\x34\x04\x6a\x04\xb2\x3c\xe7\x93\xe2\xd5\x7e\x48\xd4\x35\xf9\x51\xe0\xf1\x88\x23\xca\xac\x8c\x9a\x37\x79\xf9\xf2\xd8\x67\x5a\x42\xe0\x29\xe6\xa2\x1e\x9f\x1e\x1e\xae\x8d\x40\xd8\x76\x73\xe3\x8f\xaa\xd0\x28\x60\x35\x88\x93\x80\x4f\xe4\xd5\xba\xc1\x29\xb7\x21\xb1\x91\xbe\x74\x57\xd1\xc4\xd0\x96\x1e\x91\x40\xb7\xf8\x18\xf0\x65\x75\xb7\xe2\x26\x6c\x14\x84\x09\xb7\xfc\x82\xeb\xb2\x9d\xf4\x42\xd1\x28\x88\x12\x7c\x05\xfb\x9e\x3f\x02\x25\x4c\x67\x8d\x6c\x14\xe8\x90\x79\xeb\x9f\x83\xb2\x0c\x07\xb7\xbc\x69\x87\x09\xb3\xa8\x73\x0a\xa1\x87\x4d\x9b\xc2\xba\x95\x6c\x19\x5f\x91\x26\x89\x66\x2e\xa2\x30\x9b\x35\x16\xb1\x7b\x74\x03\x8d\x68\x9a\x60\xc3\x2b\x96\xa4\x96\x03\x26\x14\x7b\x9c\xc5\x09\x2a\x2e\x1e\x90\x67\x85\x0e\x3c\xe5\x88\xc9\x20\x36\xda\x4c\x79\x8d\xb3\x37\x2f\x5f\x86\x90\x2a\x1a\x85\x81\x49\xe1\x3e\xf2\xe3\x47\x3d\x21\x1a\x3e\xb7\xbb\x51\x08\x31\x16\x69\x0e\x58\x8d\x3c\x38\x96\xa2\xc6\xa3\x1a\xdc\x75\xa3\x80\x60\x9e\x83\x17\xed\x1e\x9b\x55\x0b\xc4\x62\x8b\xf3\xda\xbc\x3b\x21\x94\x46\x16\xc8\x49\xdd\x39\x91\x02\x77\x3c\x35\xa4\xf7\xa6\x98\x3c\x94\x1b\xa3\x51\xa4\x62\xb4\x69\x2d\x72\x36\x3a\xe2\x17\xb8\xd0\xd1\x4b\xa3\x38\xe4\xd8\x75\xeb\x78\xe2\x1f\x6d\x89\xa2\x2a\x9b\xab\xf3\xfe\x63\x7f\x92\xc6\x3e\xaf\x1a\x9d\x49\x43\xd7\x73\x03\x67\x5a\xa6\x76\x74\x92\x6a\xcc\x3c\xf0\xfa\xf0\x81\x73\xc3\xb4\x86\x35\xdf\x27\x90\x2f\x1a\xa5\xca\xdc\x0c\x3a\x78\x47\xe4\x57\x18\x0f\xc8\x42\x81\x3d\xbc\x2f\x35\x7c\x74\x71\xef\x1d\x2f\x07\x9e\x92\x1b\x14\x47\x26\xd0\x46\xd2\x8b\xbb\x19\x1d\xcd\xc9\x45\x63\x10\xe0\xdb\x5c\xcc\x47\xbc\xae\xab\x43\xe7\xbe\x3e\xd6\xd5\x0b\x48\xbf\x22\x27\x27\x26\x31\x86\xa3\xbe\x01\x7d\x21\x25\xba\x15\x67\x03\x53\x06\x91\xdd\x43\xe7\x39\x74\x27\xb7\xc4\x99\xc1\xbe\xe9\xbc\x54\x2e\x66\xdd\x94\x77\xfc\xe7\xfa\xe7\x11\x73\xfc\xbb\x69\xff\x1c\x8d\x44\x1a\x19\x0c\x67\x55\xa8\x8d\x02\xfe\x1d\xf2\x8d\xac\xdc\xbc\x10\x99\xc9\xcc\x18\xa0\x98\x4d\x5e\xef\xaa\x29\xa5\x9b\x1b\x2d\xd3\xc0\x83\xd5\x71\xee\x99\x0d\xfd\xe4\x7b\x2c\x69\x24\x20\x64\x46\x43\xba\xcd\x35\xb2\x2e\x6b\x27\x41\xfa\xa9\xc7\x1a\x49\xa2\x31\xb7\x67\x13\x75\x1e\xf7\x73\x5b\x71\xd5\xaf\x1a\x95\x66\x49\xcf\x53\xdb\x19\x01\x97\x20\x8a\x20\x4e\xb3\x74\x60\x7c\xaf\xab\x1a\xf2\x97\xf2\x2f\x30\xcf\xd2\x08\x84\x51\x35\x81\x9f\x03\x36\x1f\x77\x61\x4d\x15\xf6\x91\x3c\x81\xc1\x2e\x75\x8b\x7a\x50\xa3\x9b\xbf\xa2\x8e\x22\x27\x69\x8f\x14\x31\xdb\xfc\x3f\x7e\xa5\xea\x08\xf0\x4e\x55\xb5\x50\x2a\x37\x52\x79\xb6\x21\xf5\x6c\x06\x8c\x2f\x2a\x53\x23\x45\xa3\x0e\x79\xb9\x50\x6a\x99\x9f\x65\x6c\xfe\x36\x4c\x47\x45\x5a\x49\x4c\xa9\x81\xca\x5b\x23\x9e\x75\x21\x5f\x3a\xf2\x6d\x22\xad\x43\x84\x9e\x7c\x3d\x1d\x78\xb9\x6d\x79\xa9\x78\x6d\xfa\x85\xe8\x67\xbd\x26\xe6\xec\x38\x88\x14\x3a\x7d\x48\x4b\x7d\x7b\x92\x6f\x1f\xc6\x16\x9c\x45\x3a\xb3\x3e\x7e\xea\xae\x92\x25\xd1\x44\x4b\x1d\x41\xc8\x6a\xb8\xba\x2f\xb2\xac\x9d\x5d\x75\xde\x29\x8c\x03\x19\x60\x9a\xfc\xf1\xe9\xe1\x6e\xbd\xfb\xba\x7e\xde\xee\xb7\x5f\x37\x8f\xfb\xdb\xcd\xdd\xc6\x21\x7c\xe2\x40\xa5\x48\xe8\x7e\xe0\x6f\x60\x27\xfe\x13\x70\x47\xab\x4f\x63\x92\xc4\xb8\x2e\x5b\x68\xda\x4d\x09\x7f\x1a\xef\xa9\x8b\xa6\xdd\x08\x1a\x72\xb3\xdf\xf1\xbc\x81\xbf\x73\xf9\x76\xac\xfa\x63\xd2\xf0\x48\xd9\x1d\x60\xf9\x9a\x1f\xaf\xf8\x8b\x3b\xca\xa8\xa9\xb2\x39\xb6\x0b\x53\x90\x6e\xfc\xe1\x6e\x7f\x1a\x71\x54\x75\x3e\x91\x2f\xb1\xc4\x2c\x0e\x88\x63\x90\x31\x3c\x95\x93\x6a\x89\x1b\x97\xa6\x58\x50\xef\x1e\x01\xab\xe9\xfe\xf6\x98\x1c\xca\xf5\x5c\x9d\x3e\x46\x11\x88\x1b\x04\x09\x12\x9c\xac\x55\xde\xb6\xa0\x46\x8e\xc4\x78\x61\xc4\x61\x68\xca\x21\x7e\x99\x9e\x0a\xb3\xaf\xcf\xc1\xb6\x68\x1c\x6a\x92\x76\x6f\x6e\xf9\xf4\xf0\x7d\x85\x48\x9d\xf5\xee\xeb\x7e\x73\xbf\xff\xbe\xde\xec\x17\xcb\xe5\xfa\x71\xb7\x5e\xed\xef\x1c\xa0\x92\xc6\x11\x51\x18\x37\x1f\xad\x01\x59\xd4\xc0\x7d\xb5\x0c\x6f\x25\x74\x73\x24\x1c\x4d\x9b\x4f\x40\x2f\x71\x94\x18\xaa\xd5\x55\x65\xd5\x03\x99\xfb\xb9\x98\xc5\xe8\x9f\x6c\xdb\xe3\x88\xf8\x9e\xc6\xb1\x08\x34\xb5\x4d\xac\xdb\x96\x4b\x5f\x45\x8e\x63\xdb\xb2\x61\x79\x09\x9e\x36\x73\x71\x48\x1c\xeb\x10\x67\x5d\x61\x49\x42\xa1\x47\x53\xd2\x38\x61\x01\x2a\x31\x1f\xf2\xd2\x36\x64\xf8\x23\x51\x26\x45\x4f\x26\xe6\x7f\xb4\x73\xee\xb5\xeb\x8c\x6e\xbc\x0b\x70\xc1\x95\x8d\x53\xc1\x3c\x06\xe0\x2a\x6f\x7f\xaf\xea\x6b\x9e\x17\x58\xc0\x79\x78\xb8\x72\x17\xcd\x68\xe0\xf4\x49\x47\x72\x18\xd3\x60\x7e\xd6\x5b\x8c\x33\x60\x44\xff\xff\xd1\xfc\x64\x7f\x8f\x13\x61\xa8\x4b\x0b\xe0\x75\x17\xa0\x8f\x02\xa6\xc9\x58\x19\x23\x88\xe2\xaa\xba\xaa\x76\xd5\x6f\xfd\x67\x15\x01\xe0\x06\xa7\xc4\xb7\x4b\xc6\x3f\x16\x54\xd9\xc8\x02\x8e\x83\x50\x29\x16\xa9\xa1\x76\x6e\x3d\xeb\xfe\xfa\xa7\x05\x20\xbb\x11\x4a\x61\x8d\xd5\x54\xe2\x67\x44\x1f\x69\x2c\x93\x94\x04\x8e\x11\xa4\xc2\xb2\x92\x63\xb6\xb0\x23\x54\x98\x85\x36\x71\x6e\x92\x83\x93\x2b\xa8\x58\x81\x15\x70\xbb\x84\x35\x89\x55\x62\xe4\xd3\xf2\xde\xdd\xb6\x49\x3e\x37\xc0\x82\x0f\xd1\x31\x1f\xb0\x43\xfb\xbb\x00\x42\x2c\x45\x98\xa9\xfb\x8f\xf6\x08\x48\x38\xf6\xbd\xed\xf3\x32\x6f\x1f\x8e\x79\x39\xe4\x52\x1a\x8f\xd4\xd2\x40\x0d\x5b\x5e\xa3\x71\xb3\xb8\xac\x0b\x7b\x88\xe3\xd4\xb4\x67\xeb\x38\x44\x38\xad\x9b\xef\xfb\x4a\xef\xad\xe6\x6e\xfb\xb1\x57\x53\xfe\x53\x9a\x04\x59\x80\x4e\xec\x55\x2b\x79\xd9\x1d\xf8\xe2\x0e\x70\x13\x9c\xbe\x43\xe9\x98\xcd\x68\x12\x48\xa5\x99\x2b\xf7\xd4\x6f\xd0\xa2\x77\x3a\xda\x62\x12\x1a\x04\xc8\x83\xa3\x1d\x7b\xfb\x75\x5e\x14\x57\xd5\x94\x24\x8b\x26\x34\xe3\x41\xdf\x9c\xb1\x82\x02\x5e\x78\x5b\xd5\xdd\x27\xf2\x69\xe8\xd9\xf9\x96\xb0\x20\xc9\xac\x52\x71\x4f\xc5\x3f\x7a\x8d\x09\x0b\x24\xb5\x09\xae\x5d\xb5\xb8\xfe\xfe\x65\x72\x85\x84\xa5\x4e\xbb\x79\x9a\x7e\x4a\x42\x42\x30\xb5\xbe\xe6\x75\xfb\x7a\x1c\x6a\x9f\x76\xc7\x04\x52\x86\x22\x33\xe5\x66\xb7\x71\x64\x08\x34\x09\x43\x4e\x2d\x58\xea\xb1\xae\xd4\xe9\x1c\x09\x39\x6b\x6b\x93\x08\x0c\xb6\xf2\x05\xda\x15\x52\x07\x0d\x6f\x25\x4e\x0c\x1d\xc4\xb1\x86\xd5\xcd\x3f\x87\xf6\x36\x49\x82\x08\xad\xc9\xa9\x31\xd9\x65\xff\x77\x61\x8a\x93\xcb\xc5\xd3\xef\x03\x5d\x5e\x9a\x24\x2a\x32\xdb\x76\x1f\x5a\x7a\x66\x30\x3f\x46\xf3\x34\x9d\x94\xd1\x1f\xfc\x4f\xa6\xa9\xc0\x24\xc3\xb2\x2a\x75\x91\xcb\x16\x01\x68\xb8\xbd\x1a\x30\xea\xc4\x81\x4e\x52\x69\x38\x7d\x05\x97\x6f\xdf\xf3\x52\x55\x3f\x16\xea\xff\x4e\xc6\xa3\x7c\xe2\x6d\x5e\xf9\x0b\x6b\x85\x0a\xe1\x22\x57\x0f\xe5\xc2\x34\xc2\xec\xaa\xab\xd3\x04\xb6\x92\x64\x71\xac\x2c\x17\x56\xde\xbc\x36\x50\x68\xe5\x1b\x98\x68\x92\xa5\x1a\x2b\xd3\x37\xd0\xfe\xe3\x04\xa7\x91\x80\x05\x4d\x32\x19\x9a\x1e\x6b\xa5\x1e\xc1\x50\x68\xcd\xcf\x2e\x9e\x01\x92\xf6\x98\x4c\xc2\x08\x63\x9a\x70\x10\x08\xc7\x36\x5c\x04\xf8\xa5\xc6\x27\x8b\x4c\x60\xfa\xfc\xd0\x39\xc1\x72\x46\x08\x7a\x34\x4b\x25\x49\xb0\x1b\x7e\xbd\x7c\xb8\x7f\xb8\xfb\x63\x7f\xf5\xf0\xb0\x75\x6e\x58\x22\x19\x37\x5e\x69\xf9\x32\xa7\x28\x3d\xbe\x50\x9c\x20\x78\x08\x95\x25\xf7\x35\xbc\x03\x2f\xf6\x1c\x7d\xa0\xc3\x21\x6f\xe7\x13\xe2\xee\xdc\x24\xc3\x0a\x5e\x5e\x36\x50\xfb\x76\x8e\xf9\xae\x32\x77\x4a\xc6\x0d\xfe\x8c\x1f\x60\xd4\xa7\x4e\x13\x95\x52\x74\xf6\x0b\xcc\xce\x38\x6a\x5e\x9a\x40\x60\xa8\x73\xff\x71\x7b\xfd\x87\xff\x1b\x64\x48\x5e\x7d\xe4\x1f\x6d\xe5\x46\xa6\x81\x60\xb8\xc4\x6c\x1f\x1a\xb2\xc6\xb0\xc1\xa2\x48\x03\x69\x32\x87\x3d\x77\xa7\xc9\xbb\x78\xf1\x6e\x9a\x76\x3f\xc6\x2d\xd7\xa5\x6f\x13\xa5\x29\xb1\xad\x01\xa2\xfb\x3a\xce\x46\xd2\xcb\xe9\x8d\x94\x05\x86\x65\x79\xf9\xca\xeb\x17\x04\xbb\xb8\x03\x54\x62\x15\x66\xc9\x8f\x47\x53\x25\x51\xdd\x84\x18\x06\x7e\x6e\xa4\xcc\x1c\x3d\xd9\x2d\xef\x9c\x0b\x35\x9a\x52\x29\xd3\x99\x63\xe9\xc1\x96\xed\x59\xc1\x9d\x6e\x98\x21\x93\x7b\x81\xd6\x4e\x5f\xdb\x90\x6b\xaf\x36\x1e\x1d\x8a\xd8\x68\xb3\xf2\x9f\x46\xb7\x62\xfc\x9b\x51\x10\x0a\xb3\xdb\x6d\x7f\xf0\x63\x4f\x7f\x43\xd3\x28\x8a\x94\x85\x1d\xec\x16\x0f\xd7\xfc\x90\x17\x53\x45\x16\x37\x32\x31\x4a\xb4\xb7\xd5\x4b\xe7\x57\x3c\x79\xda\xd1\xe9\x38\x4d\x10\x73\xd7\x60\x34\x73\x51\xf5\xf4\x17\x75\x90\xbf\x8d\x76\x41\x7b\xe9\x38\x08\x90\xaa\xc2\xf1\x26\x9b\x0a\xd3\x85\x5d\x23\x8d\x43\x82\x9c\xfb\x7b\x14\xf3\x28\xce\x0a\xe5\xc3\x8d\x34\x8d\x6d\xff\xd2\xd7\xea\xd4\x80\x97\xf1\xa1\x69\x4a\x28\x76\x1c\xc2\xcf\xbc\xe9\x02\xd8\x8d\xf7\x38\xd3\x94\x32\xdc\x4a\xef\x60\xdb\xcf\xb8\x54\xc4\xc1\x80\x3e\x76\x0a\x64\x48\x53\x2d\x9c\x4f\xb8\xc4\xea\xf5\xf3\x20\x53\xd3\x33\x5b\xf6\x4f\x91\x05\x19\x0a\x87\x37\x1f\x65\xfb\x0a\x4d\x17\x66\x9b\x10\xf8\x5f\x91\x9b\xb4\x59\x18\x64\xd6\x25\xf6\xa0\xea\x5d\xb5\xe8\x82\xe8\x66\x9a\x27\x4a\xb3\x38\xc1\x14\xa6\xce\x8f\x8d\xc9\x25\x1a\x64\x93\x2d\x96\xcd\x67\x2f\xd2\x4c\x11\xdc\x64\xac\xb3\xe3\xe6\xbf\x7b\x6a\x4e\x8c\x2e\xec\xcd\xd5\x70\xcb\x4a\x05\xd1\xd8\x8c\x9c\x37\xb7\xae\x89\x8f\xd1\x51\xc8\x9f\x0a\x99\x65\x46\x74\xeb\xb8\x3d\xf0\xba\x1d\x9d\x2f\x63\xc3\x86\xd3\x40\xbb\x58\xde\x3e\x55\x05\x44\x59\x96\xd1\x2c\x24\x2c\x48\x92\x8c\xb1\x90\xb1\x74\xf2\x82\x65\x12\x4b\x39\xe2\x52\xbd\x38\xf5\xa6\x58\xc2\x59\xdb\x97\xaa\x80\x0c\x54\x56\x97\xd5\xe1\x58\x95\x50\x5e\x68\x7b\x48\x55\x94\xa0\x2f\x21\x5a\xe9\x9e\x02\xe2\x54\xd9\xe6\xf2\x87\x52\xc2\x9d\xd7\x1c\x98\x18\x0e\x90\x3a\x10\xb6\xe1\x09\xb9\x15\x40\x7d\xe5\xe5\x08\x19\x90\x76\x6b\xab\xbb\xfc\x42\xa9\x55\x5d\x95\xf0\x19\x89\xb0\x39\x25\xeb\x2c\x5a\xe7\x06\x0c\x32\x15\x9b\x83\xdb\x43\xb3\x40\x87\x68\x21\x8b\xea\xa5\x1a\x26\x95\x33\x92\x45\x81\xc5\x12\x98\xf0\xed\x36\x17\x35\xf7\xd0\xc0\x8c\x46\x31\x52\xb3\x63\xea\xcf\x77\xf8\xd2\x8c\xea\x04\x9f\xd6\xfa\x51\xd6\x41\xb7\x07\x19\x4b\x84\xf2\x01\x02\x2a\xa8\x1f\x79\xe9\xaf\xc9\xe2\xd4\x76\xec\xe4\x2f\x2f\x50\x5f\xe7\xa5\xcd\xb0\xfb\x01\x52\xa0\x56\xc6\xed\x7a\x87\x5d\x86\xfb\xe1\x74\xc9\x98\x22\x48\xab\xde\x70\x0d\xdb\x93\x98\xff\x42\x59\x18\x46\x88\xca\x5f\x97\xb2\xe0\xef\xd0\xac\xd6\xbf\x3f\xd6\xd5\xcf\xb3\x9c\xcb\x2f\x2d\xd5\x74\x1a\x8d\x76\xd9\x2c\x8c\x42\xea\x83\x3f\xdc\xd8\x76\xb7\x7f\x1c\xa1\x5e\xef\xbe\x7e\x99\xdc\x50\x2a\xb1\xb7\xd1\x94\x16\x57\x06\xdf\x31\xf0\x41\xb3\x10\x14\x6e\x6e\xef\x55\xeb\x81\x05\x0f\xfa\xc2\xe3\x45\x81\xc6\x09\x88\xe2\xed\x9f\x66\xa2\x2e\x4e\xf9\x2c\x4a\x05\xc6\x77\xfb\x61\x1b\x2c\x76\xc0\x3e\xe8\x6d\x5b\xd5\xfc\x65\x92\xc6\xc8\x62\x1a\xa3\x99\xb4\x79\x4b\x14\x57\xd8\x02\xa8\xc5\xa0\xc9\x79\xda\x82\xf9\xdf\xdd\x53\x2c\x18\xb5\xab\xc8\xef\x29\x7d\xa1\x23\x8b\x35\x28\x03\x7f\x6e\x7f\x25\x29\x4a\xb3\x44\x99\x86\xdd\xea\x08\xe5\x10\x62\x3b\xa9\x9a\x67\x69\x42\xc3\x68\x0c\x33\x37\x10\xcf\xd9\x78\x3f\x4b\x05\xc7\x0d\x61\x51\xb6\xf9\x9f\x27\x40\x27\x6e\x76\x6b\xca\x32\x41\x22\xbb\xeb\x5a\x99\x48\x0b\x23\x1d\xe1\xe9\x32\xce\xb9\x42\x4e\x24\xde\xd6\xf0\x3b\xbf\xd8\xdd\xf8\xcb\xf4\xe0\xf9\xeb\x14\x89\x46\x42\xaa\xdd\x5b\x51\x3a\xa9\xe7\xe1\x5a\x92\x2c\xc2\x02\xf8\x43\xfd\x52\x95\xe3\x23\x32\x96\xe9\x00\x65\xf2\xcd\x0a\x36\xff\x3a\xc1\x9f\x49\x95\x86\x3d\x6a\x63\x5d\x2a\xbb\x32\x26\x0b\x42\x85\x29\xa6\x46\x55\x7d\x3c\x8d\x7e\x5a\x45\x49\xda\xe7\xea\x16\x57\xf6\xd7\x66\x71\x8f\x99\x12\xa6\x6e\xeb\x41\xeb\xbb\x6a\x3b\xe8\xa3\x9d\x8c\xd6\x99\xa1\xad\xa8\x4a\x84\x70\xf6\xcd\x49\xe3\x55\xad\x21\xc3\x98\xea\xf9\x6a\x84\x8a\xcb\xb4\xa6\xa9\x6d\x66\x44\x5e\xd0\x6d\xcb\x47\x1e\x18\x0f\x28\x45\x73\xda\x1c\x5e\xc6\x4f\xcb\x03\x15\x68\x1b\x9a\xee\x61\x14\x98\x72\x12\x06\x88\x4a\xbc\xcb\xcb\x8d\x4f\xcd\xfb\x83\x11\x45\xdc\xd2\x36\x7f\x29\x79\xf1\xf8\x51\x4c\x93\x9e\x9c\x24\x31\x75\x3a\x07\x57\x75\xf5\xe6\xed\x28\xa7\x81\x41\x0a\x6d\x0e\x47\xa8\xab\xcd\x6e\x90\xc4\xe1\x94\x19\xa2\x8d\x17\xcf\x64\x33\xd2\xbc\xa6\xbc\xb3\xfc\xc8\x4d\x6a\x80\x79\x47\xff\xf1\xc7\xcf\xc5\x54\x80\x70\xd2\x2b\xf6\xeb\x9c\x3a\x0f\x53\x06\xb6\xde\xbf\xdc\x4e\x1e\x23\x22\x12\x41\xf1\x7d\x85\xb6\x5f\x08\xb3\xcb\x8b\x47\xd4\xac\xef\x9e\x59\x69\x8d\xec\xd9\x23\x45\x8c\xe9\x39\x4c\xe2\xe2\x5d\xff\x84\x5a\xe6\xcd\x64\x4e\xf2\x98\x1b\x0a\xad\xce\x91\x9c\x2a\x36\x5e\xd8\x18\xdc\x99\x92\xd3\xc4\x37\x0b\x3d\x42\xbd\xfb\x39\xb9\x76\x12\xc6\x26\xd9\x89\xb8\x24\x63\x10\xda\xea\xdc\x65\x1e\x9f\x95\x32\x16\x6b\xc7\x24\x8d\xbb\xb0\x25\x31\x99\x0c\x0b\x39\xa2\x4c\xff\x53\x95\xd0\x79\xff\xf5\x61\x0c\x1a\xe4\x29\x50\x47\xb0\x69\xab\x80\x55\x8d\x97\xa3\x17\xde\x54\x16\x25\xc2\x8a\x77\xce\xe8\x58\xcc\x2f\x7d\x9e\xc5\x09\x72\xd6\xb6\x96\xd4\xc3\x17\xa0\x79\xc6\x2d\xf8\x87\x23\x7d\x94\xef\xcd\xe1\x99\x22\xd8\x2a\xdb\x79\x72\xb6\x03\x6e\x7d\x3f\x9d\x1c\x3c\x48\x10\x76\x0b\x65\x0b\xf5\x6d\xd5\xb6\xe0\x2f\xcc\x39\xc1\xe6\x92\x55\xfe\x92\x4f\x6b\xea\x5c\xd0\x18\xb3\x77\x47\x97\xd9\x6b\x61\x5c\x6f\xe6\x32\xe0\xc4\x11\xb0\x35\x50\x23\xf7\xc1\x6c\x0e\x9f\xcb\x88\x19\x45\x16\xcf\xe3\x65\x80\x71\xcb\xd3\xc4\xc5\xe3\x92\x1b\x51\x4d\x71\xfa\xb8\xcd\x25\x94\xcd\xb9\x73\x3a\x5a\x16\x8a\xc4\x28\x3d\xfc\x3d\x2f\xd7\x43\x7b\xc3\x15\x8b\x91\xd7\x72\xfb\xfc\xcd\xfd\x09\x12\x0a\x6e\x53\xb3\x69\x80\x03\x4c\x9d\x4c\x0e\x69\xcc\x6d\x8d\xf3\xb9\x6c\x9b\x3f\x27\x08\x67\xae\x03\x30\x32\x0b\x4d\x17\xbf\x19\x5a\x86\x59\xfb\xca\x75\xa4\xb1\x67\x5e\x56\x65\xdb\x63\x4f\x3e\x2b\x33\x88\x80\xa5\xd8\xe3\xd1\x85\xbe\x5a\xa3\xa1\x35\xf4\x04\xcb\x99\xca\xcd\xfc\x44\x12\x41\x1a\x27\x0a\x3d\xe0\x43\x5e\x4e\x83\x4f\x11\xe8\x4c\xc7\x5e\x1f\xec\x3b\xe4\xd7\x55\x6d\xd8\xae\x8d\x1e\xdb\x6d\xe7\x5d\x7d\xae\x48\x41\x05\xb1\x38\x5d\x04\xf4\x76\xcb\xe1\x4e\x3a\xcb\x29\x88\x32\x20\xf9\xbc\xd4\x05\x9f\xbc\x5c\x41\x89\x4a\xac\xa5\xca\xcb\xad\x69\xe1\xb9\xf4\x5b\x63\x94\xa0\xbd\x40\x18\x28\x92\xcd\xcb\xdd\xb8\x11\xd4\xd5\xc8\xeb\xc6\x55\xa9\xd7\x3e\x10\x13\x61\x12\x61\xc2\xb6\xe8\x9e\xf3\xa1\x9c\xd1\x00\xa2\x22\x8a\x8c\xfe\x74\x55\x73\xd9\xc5\x47\x7b\x04\xbd\xcf\x3b\x4c\xd3\xce\x78\x11\x07\x1a\x99\x88\x9d\xd6\xdd\x9d\xe9\x10\xbf\x28\xeb\x3f\x3d\x5d\x0a\xe8\x7b\x0c\x76\x3f\x57\xbc\xe5\x48\x38\x61\x73\x77\xa3\xdd\x56\xc4\x3a\x00\x69\x95\x5d\x0d\xdb\x7e\x65\x73\x21\x7d\x5e\x7f\x24\xf4\x4a\x45\x92\x25\x88\x5c\x16\xe2\xc3\xad\x64\x91\x70\x82\x61\xc5\xd5\x72\xed\xff\x04\x14\xc1\x81\x7f\x9e\xe0\x04\x77\x95\xf2\x63\xd3\x34\x73\xd0\xeb\xeb\x1a\xe0\x37\x10\xbc\xcf\x29\x8a\x2c\x34\x39\x10\x24\x37\xf8\x81\xd9\x7a\x7b\x84\xab\x80\x39\x35\x56\xc3\x05\x4b\x13\x77\x4c\x44\x2a\xb4\x00\xf1\xfd\xc9\x52\xb0\x4f\xe6\xad\x88\x19\x52\xaf\x0f\x68\xfa\x67\xd1\x17\x42\x80\xe1\x46\x44\x5e\x85\xe6\x73\x4a\x28\x7b\x8a\x0c\x80\xb9\xf2\xad\x41\x9c\x57\x6f\x3d\x39\x0d\x15\x92\xa4\x4c\x7b\x81\xfd\xc7\x82\x4b\xe8\x33\x6b\x42\x12\xe9\x0a\xfd\xf7\xa7\x6e\x9f\x79\xd0\x1a\xea\xca\x23\x62\x85\xa4\x80\x66\xba\x67\xf8\xbc\xcc\xcf\x45\x85\x14\x2c\xb0\x8c\x18\x9a\x97\x62\xda\xb5\x2d\xa4\xe4\x68\x55\x8e\xc5\x47\xfd\x54\xaa\x66\x5e\xcd\x95\x0a\x09\x80\xdf\x54\x9c\xf2\x42\xed\x31\xec\xe8\x71\x99\xa2\x8b\xd9\x91\x55\x9f\xd7\xa6\x75\x0d\x0b\x48\xd8\x24\xe3\xd2\x8e\x02\x48\x12\x5b\xf1\x4f\x37\x60\x06\x27\xed\x06\x53\x86\x3e\xc8\xd5\x62\xbb\x59\xee\x9f\x16\x3b\x3f\x93\x20\xa4\xb8\xe6\x87\x3c\x36\x93\x67\xd2\x44\x21\xd1\xd6\xea\xf9\x69\xb1\xdb\x3c\xdc\xef\xef\x1f\xee\x9f\xb7\xeb\xdd\x7a\x71\xe7\xae\xa2\x63\xd3\xa7\x75\xf0\xc4\x56\xfd\x11\x93\x33\x75\xf0\xf2\x73\x21\xc5\x6e\x8c\x46\x04\x87\x75\x4c\x6c\x23\xe6\xf8\xc5\x6b\x0e\x98\xa2\x39\x1c\x6c\x6a\x79\xca\xd5\x4a\x65\xc0\x02\x44\x90\x1a\xeb\xf3\x54\x55\x0e\x7b\xd9\x4e\x50\x73\x92\x24\x61\x94\x0d\x34\x05\x9d\x3a\xf9\xf5\xa9\x28\xac\xe4\xf4\x92\x97\x1e\x41\x20\x69\x44\x70\x0a\xde\x56\x28\x7b\x34\x86\x4d\xbb\x31\x60\x84\xb4\xde\xf2\xa2\x98\x72\x4b\xd8\x21\x8c\x47\x56\x9c\xb3\xbd\xe6\x45\x21\xb8\x7c\xb3\x5d\xb7\x23\x92\x0d\xc9\x04\x8d\xe2\xde\x1b\xc7\x49\x3f\x79\x02\x26\x14\x62\xaa\xf0\x9d\x0e\x9c\xeb\x4f\x7d\x2e\x19\x5a\x91\xcc\x2e\x20\x94\xd5\x80\xdf\x9c\xca\x30\x8c\x90\x8a\x53\x55\x80\x60\xa3\xaf\xfc\x1d\x66\xdd\x05\x19\xa6\x19\xae\x75\x28\x65\xa5\xc0\x90\x77\x54\x17\xe8\x54\x64\xc8\x03\xf4\xf2\x1a\x27\x63\xeb\x95\x7b\xa8\x0c\x25\x73\xb2\xee\xae\xb0\x63\x32\xa2\xf3\x6e\xb1\x0c\x15\x8d\x53\xa7\x80\xfc\x04\x7a\xf2\x76\x23\x6a\x5a\x42\x97\x55\x0d\x77\xa0\xf2\x5e\xb8\x9b\xca\x58\x1b\x19\x09\xe7\x83\x63\x13\x65\x7b\x52\xf9\x99\xb0\xf8\xe4\x37\x93\x04\x62\x43\x73\x75\x0b\xba\x9d\x0b\x14\x64\x2a\x12\xa7\x43\x86\x73\xe7\xfa\xfc\x65\xcc\x5b\x36\x99\x31\xc3\x60\x27\x8a\xbc\x74\xe9\x36\x99\x65\x2a\x74\xd4\x77\xd8\xe4\xfe\xcd\x68\x69\x0f\x2b\xb0\x7d\xe2\x40\x66\x2a\x66\x46\x42\xb9\x3c\xf1\x62\x98\x02\x93\x92\x18\x42\x0a\x95\x37\xfc\xa5\x86\xe9\x77\x54\xca\x70\xb2\x49\xff\xd3\x4a\xa5\x2e\xe7\x63\x13\x1f\x0f\xe2\xff\x3e\xf7\x67\x24\x04\x1a\x33\xab\x87\xbc\x1c\x03\x58\xdc\xf1\x90\x62\x77\x0b\x96\xf6\xf6\x8f\x4f\xeb\xcd\xf2\x61\xbf\x5c\x3c\xfa\xe3\x51\x6a\x22\xcf\x0a\x25\x54\x87\x0d\x5e\x52\xeb\x2c\xb3\x8e\xcc\x57\xa8\x2b\x8b\xa0\x41\x1f\x68\xfc\x0d\x54\x20\x08\xbe\xb4\x27\x50\xa6\x7e\x30\xdf\xc3\xa8\x02\x9d\x19\xc5\x22\x5e\x3e\x81\x02\x38\x3c\xef\x7e\x7f\x18\x29\xa9\x0f\xb2\x95\x8a\x04\x02\x0d\xca\xdb\x47\xbf\x87\x2a\x22\x8d\x8e\x35\xf6\x8c\xff\x96\x97\x2f\xd6\x5b\x1e\xbf\x5d\x45\xa4\xc6\x80\xeb\x58\x57\xc7\x57\xe8\x22\x32\xdb\xc3\x3a\x19\x47\x43\x19\xb9\x0d\xbb\xf3\x89\x76\x35\x2f\xe5\xab\xfb\x86\x8a\x65\xa6\x7e\xcb\x95\xfa\xed\x12\x07\x88\x62\x60\xe8\x28\x2d\xd4\xa4\x5b\x66\x53\xed\x98\xd9\x8f\xa7\x42\x66\x50\x70\xb9\xac\x90\xad\xd0\x62\x9c\xfc\x17\x50\x61\x9c\x22\xcc\xa4\x39\x02\xd8\x76\x7b\xe2\x4f\x56\x02\x19\x72\x4a\xf8\xf1\x7c\x2c\x2a\xae\xa6\xbc\x82\x27\xab\x96\x32\xf4\x89\x54\x94\x58\x15\x54\x63\xdb\xbc\x5c\xc2\x27\xc5\x0d\x15\x89\x54\xe8\x01\x26\x09\xf5\xef\xef\x00\xd5\x86\xaf\xc1\x63\x00\x54\xcc\x33\x23\xa8\xcc\x11\xd6\x61\xd9\xe3\x0c\x80\xcf\x8f\x51\x0c\x71\xd7\xef\xb9\x82\x6a\x92\x1e\x51\xb1\x4e\x11\x4d\x8d\xd6\xaa\xe7\x35\x09\xdd\xc9\x49\x48\x4d\x2c\x7c\x9c\x2f\x9e\xa9\x24\x14\xd4\xee\x76\x7f\xaf\xc4\xd7\xbc\x7b\x0f\x58\xae\x1a\x0f\x4b\x49\x26\x42\x27\x0a\xd1\x4d\x9e\x6d\xee\x10\x65\x2a\x65\x22\xea\x25\xc4\x2f\x7c\xf1\x34\x03\xcc\xb9\x0a\xec\x0a\xed\x42\x6e\x77\x7a\x96\x68\xe4\x5f\x73\xa4\x4c\x7e\xde\xa2\x77\xdd\xcd\xa4\x53\x83\x3d\x61\x76\xb2\x0c\xd8\x24\x14\x4f\x43\x47\x1b\xb5\x5c\x3c\x8c\x93\xfc\xae\x00\xa3\x44\x1c\x86\x80\x40\x0b\x2c\x28\x5d\x2c\x90\x8d\x6f\x58\x26\x4a\xea\xbf\x56\xd6\xf8\x6f\xff\xfd\x85\xad\xf5\x37\x2e\x33\x95\x49\xaf\x2e\x3a\xee\xa7\x19\x85\xad\x4a\x0a\xb3\x2c\x44\x5e\x62\xd3\x06\x6a\xa7\x76\x73\xee\x82\x55\x51\x14\xb2\x18\xdb\x68\x1c\x9f\xfd\x64\x91\x2b\x46\x53\x9b\xfc\xdd\x2c\x1f\x3e\x55\x51\xa6\x4a\x65\x4a\x59\x6a\xd2\x3b\xde\xc2\x45\x36\x3f\xaa\x80\x66\x2a\x1c\xd1\xfe\x8e\x8b\xab\xd3\xe1\x61\x84\x4c\x1e\xb7\xe8\x9f\xef\xed\xbe\x02\xb3\x3a\x7d\x54\x41\x24\xa2\xa0\xd7\x8e\x7d\xac\xab\xc3\x84\x71\x42\x01\xa7\x66\x73\x87\x52\x0d\x34\xc3\xa7\x83\x94\x50\x8e\xe3\x93\x97\x0d\xc7\x8d\xa5\xb7\xb9\x6e\x18\x44\x2e\xcd\xe4\xab\xe8\xbf\x98\x53\x9a\xc6\xd8\xfd\x7e\xac\xf3\xd2\xe2\x7b\xbe\x8c\x07\xc4\x32\x34\xd6\xab\xc8\x8d\x75\x9d\xfd\xdc\x3a\x31\xad\xeb\x2b\x80\xe3\xac\xef\x7f\xe9\x5f\x77\x3e\xa7\xda\xbe\xa9\x2d\x3f\x1c\x2d\x4d\xd0\xc4\x81\x85\x00\x00\x99\x81\xdb\x57\xb0\xbd\xa3\x5e\x50\xd9\x8e\x20\x3c\x55\xc6\xd7\xc0\x7a\xc5\x6c\x19\x1b\x28\x33\x01\xfc\x6e\xb1\xb9\xdd\xaf\xef\x36\xdb\xed\xe6\xc1\x41\x66\x80\xa6\x21\x76\x44\x5b\x0e\xc3\x2d\xc8\x1a\x30\xf7\xc4\x8b\x5e\x2d\xeb\x6f\x93\x0b\x66\x59\x3a\xa4\x38\x7f\x84\x7a\xa2\xa2\x6d\x07\xb2\x24\x0a\x64\x8f\x73\x58\x6e\xb7\xae\xdd\x09\x58\x2a\xa2\xf0\xec\x1b\xf7\xb5\x66\x08\x03\x30\x95\x6f\xa3\x38\x31\x36\xbb\x10\x45\x80\x50\x97\xcd\x3f\x1c\x72\x11\x22\x4d\xd0\xef\x5a\xf1\x33\x0a\xaf\xf1\xed\xc7\xd4\x20\x84\x4f\x03\x75\x6e\x0a\x71\x14\x26\x7d\xa6\xde\x7a\xd7\x9f\x3a\x63\x90\x50\xc3\xdc\x9c\x37\xf7\xf0\xc3\xc6\x41\xe3\x9f\x4a\x68\x68\x48\x67\xf3\x36\xff\x0f\x94\x4d\x9f\x64\x1f\x5f\x29\x0d\x8c\x9a\x13\xba\x34\xfe\x15\xa4\x21\x11\x2e\x1f\x57\x1e\x4d\x83\x14\xa8\x7f\x9c\xa0\xfe\xb8\x32\x6f\x63\x7a\x99\x28\x42\xef\x03\xc1\x1f\xd7\x79\x51\x3c\xd4\xbf\xe5\x3d\x9f\xc2\xbf\xa2\x7f\x0f\xea\x26\xf1\xbf\xff\x2b\x25\x6b\x0a\x19\x31\x6f\xc8\xa0\x86\xb6\xa6\x59\xa0\xee\xb7\x7e\xe0\x94\xa3\x52\xd2\x72\x40\xcb\xe5\x0e\x25\x09\xd1\x83\x6a\x01\x1e\x9c\x42\x05\x80\x27\xd2\x71\x6a\x6e\xe5\x2b\x1c\xf8\xe4\xab\xf3\xd4\x54\x07\xba\x89\xc7\x3f\xb8\x28\x3c\x03\x6e\xef\xde\x02\xcf\x52\xb4\x9c\xb8\x22\x26\x4e\x8d\x1b\xc2\xd3\x2c\xb6\x3c\xcf\x79\xf9\x72\x95\x2b\x05\x23\xbd\x7c\x0a\x22\x50\x06\x86\x9d\xeb\x76\x6f\x1f\x68\x73\xbf\x38\x54\x6d\x01\x1f\xb7\x79\x09\x93\xe1\x24\xc6\x48\xa2\xa8\xe4\x9b\x89\xf5\x4c\xcf\xdc\x64\x22\x0e\x6e\x53\x70\x4e\x50\x1d\x6a\xbd\xb8\xdb\x3f\xae\x9f\x96\xeb\xfb\xdd\x7e\xfd\xcd\x45\xd9\x20\x04\xc5\xda\x78\x2e\x2b\x2b\x42\x6c\x0f\x48\x62\xba\xb7\xbb\x28\x7e\x5b\x9d\x6a\x09\xb3\x2c\x8a\x20\x69\x94\xf6\x45\x56\x7f\x76\x14\x12\xbb\xee\xb0\x48\xd4\xed\x3d\xe8\x43\xf3\x81\x0b\x0e\x40\x5c\x06\xdf\x46\xb7\xfb\x1f\xb9\xbf\x04\x84\x41\x10\x78\xd2\xdd\x6e\x1e\x34\x98\x21\x99\x7c\x2c\x48\x63\x64\x98\x7d\x3c\x35\xcd\xc7\x2f\x2b\x94\x00\x76\x07\x3d\x7e\xd4\xfc\x90\x4f\xd8\x4f\x74\x90\x29\xcd\x7b\x0c\xb4\xbd\x15\x4d\x62\x83\xed\xc4\xb2\x47\xe7\xbb\x98\xa4\xd9\x40\x4c\xca\x0f\x74\xba\xad\x3f\x5d\x22\xcd\x7b\xae\x03\x7f\x50\x93\x94\xba\xfd\x11\x5b\xf5\xfe\x3b\x56\x58\xaa\x29\x33\xad\x42\xdf\x1e\x97\x3f\xdd\x35\x69\x6c\xca\x4b\xd7\xbb\xdd\xa6\x69\x4e\x7f\x35\x73\xa8\x19\x61\x99\x27\x46\x55\xa6\xe8\x88\x18\x67\x2f\xe3\xee\x06\x5a\x0d\x7f\xae\xd4\x3d\xfc\x98\xdd\x04\x34\x4b\x4c\xc6\x9e\x2b\x85\xba\xda\x15\xa6\x5c\xe6\x37\xff\xe9\x7d\x64\x0a\xf9\x02\x1f\x6e\x57\xdb\xc7\xdd\xc6\xff\xaa\xe0\x91\x2d\x8a\x6c\x11\xa9\xd3\xe6\x3f\x4d\xf7\xd0\xe4\x97\x41\x99\x9e\x72\xc3\x4f\x77\xcf\x0f\x30\xdd\xca\x75\x18\x02\x42\x7e\x8e\x7b\x63\x94\xf7\xfc\x53\x2d\x56\x77\x56\x14\xe3\x33\x9d\x29\xba\x5c\x18\xae\x23\x27\xfb\xb3\xe2\x2d\x7f\xac\xf2\xb2\xbd\xae\xea\xed\x49\xfc\x1f\xcc\x40\x59\x47\xef\x20\x8a\x05\x35\x8a\x75\xba\x0b\x3a\x7b\xda\xb5\x79\x47\x43\x47\x00\x98\x00\x5d\xf2\x5a\x54\xa5\x13\x2c\x44\xf5\xab\x81\x59\xd4\x31\x44\x88\x0a\xfd\x96\xc3\x8f\xbb\x8f\x55\xfe\x3e\xfd\x6c\x49\x22\xa4\xec\x99\x36\x26\xab\x22\x49\x0d\x4c\x02\x83\x8f\xcd\xf2\x61\x7e\xc3\xd3\x49\x46\x11\xf1\x86\x05\x84\xbc\x69\x31\xfb\xb2\x50\xea\x7c\x26\xba\x13\x3a\xe7\xc3\xef\x85\x1b\x59\xa1\x34\x92\x9b\x75\x13\x2f\x59\x27\x82\xe1\xae\x93\x97\x4d\xdb\x99\x84\x66\x7a\x97\x22\x41\x4c\x94\xe4\xb6\x2f\xc4\x65\xb2\x36\xfa\x1e\x60\xe6\x2e\xe6\x22\x3a\x9d\xe8\xc8\x89\x90\x5d\x39\xb0\xdf\x25\x48\x88\xce\x08\xd7\x26\x68\x9f\xfa\x24\x3a\x8b\x04\x2e\x16\x53\x2f\x6a\x01\x1a\x44\x39\x4c\x47\x01\xc7\x39\x6f\xe4\x49\xa6\x4f\xc4\x03\x82\x64\x44\x79\x83\x35\x32\x43\x32\x34\xf9\x72\x82\x90\x24\xf2\x5a\x02\xd3\x2b\x08\x66\xfa\xb1\x0a\xb8\xd4\x7a\xac\x45\x96\x6a\xff\x71\xf3\xf2\x65\x2f\x8b\xaa\xec\x2d\x95\xe0\x14\x2b\xbe\xa6\x39\x14\xe3\xb3\xe9\x1d\x80\x71\xd3\x5e\xf9\x3b\x6c\xbe\x7b\xe3\xae\x65\x20\x70\x3a\x5c\x9d\x3e\xb0\xa1\xeb\x57\x90\x19\x77\x1a\xa5\xe8\xb1\xdd\x2e\xae\x37\xf7\x8b\x5b\xe6\x2f\xa7\x08\xee\xfa\x1c\x3f\x89\xa9\x6e\x6d\xca\xe7\xc6\x1b\x69\x15\x90\xa4\x97\x9d\xc5\xde\xb9\x07\xed\x3d\x21\x4c\x58\x6d\x76\x0f\x53\xd8\x9e\x56\x60\xea\xcf\x2f\x28\x55\x7a\x6a\x96\x15\x68\x9d\xcb\xbc\x07\x04\x68\x48\x03\x8a\x7b\x64\xb3\xfe\xe9\xe2\x59\x16\x04\x01\xa1\xa9\x2b\x4c\xf4\xe9\xa5\x51\x3b\xcb\xf0\xd1\x58\x10\xc4\x1c\xb3\x05\xe2\xf4\x71\x55\xa1\xbc\xc2\xa3\x17\x5d\xed\x8e\xea\x08\xdd\x9a\xf5\xee\x7a\xb0\x7a\x59\x10\x58\xf6\xf9\xa7\xcd\x6f\x23\xe4\xcb\xf0\x33\xb0\x20\x90\x31\x32\x37\x22\x75\x4f\x7d\xe8\xb6\x9d\x27\x90\xef\x5f\x26\xb7\x00\x86\xee\x7d\x6f\x36\xe6\x47\x5e\x23\x79\xf9\x70\x4b\x65\x01\x21\x1c\x21\x15\xdf\xbb\x77\xc8\x6b\xde\x3d\x52\xf7\xcb\xc4\xdd\x11\x11\x46\x96\xfa\x2e\x2f\xa0\x69\xab\x12\xf6\x1b\x59\x5d\xf3\xbc\x73\x91\x06\xbb\x2d\x0b\x28\x8d\x63\xc3\x7b\xab\x72\xfd\xb1\x28\x0a\x4c\x91\x2d\xf9\x71\xba\xbc\x59\x40\xb5\x42\x1e\x8c\xef\x5f\x37\xbb\xf5\xed\x66\xbb\xdb\x5f\x3d\xdc\x3f\x6f\x07\x25\x01\x16\xb0\x40\x90\xc0\x55\xd4\x4f\x58\xee\x71\xed\xbf\x96\x62\x72\x64\x54\x3f\x9d\x69\x2c\x60\x44\x24\x89\x8f\x0d\xd4\x50\x8b\x81\x05\x8c\x6a\x24\xc1\x45\x10\xc0\xae\x86\xe6\xd5\xf3\x9c\xb2\x80\x45\x21\xce\xd1\xef\x90\xe3\xa7\xef\xb6\xf8\x7a\x4e\x12\x94\x05\x2c\x89\x1d\xc1\xb8\x8b\xaa\x96\x67\x10\x45\x16\x84\x91\xd1\x8a\x3f\xf2\x8f\xe7\xa3\xfb\x99\x50\xc7\xb4\x8f\x20\x36\xe5\x2b\xd4\x79\xeb\xe8\xed\xfb\xc6\x19\x5f\xda\xba\x30\xed\x22\x46\x31\x9b\xbd\xe5\x1a\xfa\x84\x7c\xe3\x7e\x25\xe2\x12\x31\x69\xc6\x81\x1b\x3a\x81\x2c\x88\x21\xc1\x07\x45\x4f\x7f\xe3\x05\x15\x9a\xc9\xdd\x27\x69\x8a\xa9\x54\xc5\xeb\xb7\xb2\x52\x30\x52\x9b\x75\x63\x44\x82\xbe\x9e\xd9\xda\xa6\x19\xb9\xf1\xd8\x34\xa1\xca\x88\x47\x0e\x50\xdc\xee\x98\x34\x34\xfe\xc8\x0b\xd2\xbf\x52\x05\xe3\x99\x97\x45\x46\x4e\x55\x98\x4a\xc1\x68\x41\x65\x69\x80\xf1\xe2\xde\xa5\xed\xa6\x1c\xc7\x2c\xc8\x34\x75\xb0\x19\xac\x35\x70\x79\xa6\x3c\xf3\xb7\xe9\x19\x51\x9a\x0d\x85\x3f\x06\x7d\x19\x2c\xe0\xa9\xe7\x32\xba\xe3\x39\xd2\x39\x3d\xf2\x9a\x1f\xa0\x1d\x18\xed\x5f\xcc\x57\x11\x49\x23\x5d\xdc\x5a\xb0\xfe\x5d\xa5\xa0\x70\xbf\x20\x14\x70\x83\x44\x7f\xd0\x5a\xbe\xf2\xbc\x9c\x53\x26\xef\xb7\x3a\x16\xc8\x48\x13\x3b\x35\xf7\x75\x55\xf9\x37\x2c\x65\x84\xa5\xfe\xc3\xa9\x68\xf3\xeb\xfc\x67\x9f\x87\xf9\x17\xfd\xb7\x13\x56\x64\x81\x8a\x62\xfc\xa0\x9b\x16\x0e\xa3\xd7\xab\xa2\x4c\xda\x1a\xd6\xfa\xe5\xa5\x19\x2d\x2b\x10\x01\xd6\x34\x75\x0d\x96\x08\xdb\xa3\xb2\x58\x00\x4a\xa1\x17\x22\xf2\x76\x5b\xcc\xb0\xd5\x4c\xde\x07\xe8\x0c\x39\xb2\xdb\xea\x8a\x37\xc0\xe8\x97\xe1\xc3\xe9\x24\xc5\x0c\x10\x37\x10\x35\x57\xe5\xee\xf9\x7b\x59\xa0\x45\x44\x95\x4d\x12\x75\x5e\xcf\x4d\xae\xdb\xc9\xa4\xd5\x82\x63\x55\x1d\x4a\x75\x75\xfa\xb8\xe2\x28\xf6\xea\xee\x97\x04\x34\xc3\xc0\xfc\x07\xe4\xa8\xd8\xe9\x42\x54\x46\x82\x88\x22\x60\x16\x1b\x06\x07\xc9\xef\xf1\xe5\x49\x10\x8b\x2c\xf2\x08\xa6\x76\x3e\xb3\xc2\x48\xa0\x19\x4a\xef\xb7\xd0\xb4\xf6\x29\xc7\xaf\x82\x10\xa2\x30\x40\x71\x13\xfa\xd6\x60\xea\xcf\x1c\xdb\x91\x9d\xef\xcc\x7c\x0a\x2e\xce\x75\xa2\x12\x33\xe4\x6c\x6e\xb8\x4c\x0c\x14\xb5\x2a\x0a\xde\x42\xcd\x8b\xbc\xc1\x70\xce\xcc\xf4\xf1\x3d\x13\x65\x7c\x17\xae\xd4\x80\xc2\xf5\xd3\x10\xa0\x3b\x29\x43\xd5\x27\x33\x33\x3e\x64\x55\x95\x9b\x9b\x87\x2f\xfe\xa8\x4a\x2c\xf5\x69\xef\x4b\xa5\xff\x22\x81\x9d\x91\x84\x26\x44\x5b\x7b\xe9\x61\x49\x67\x91\x3b\x23\x4c\x3a\x62\x44\x84\x6c\x97\x7a\x7a\xef\x61\x92\xf8\x24\x78\x69\x7a\x73\x3b\xdb\x37\x92\xd9\x19\xdf\x78\xc8\xa5\xe1\xb6\x6f\x5b\x38\x1c\xdb\x5d\x85\x05\xe3\x25\xaf\xcf\x9c\x4e\x47\x43\xc5\x48\xa8\x24\x4e\x3f\x0d\xf0\xc8\x3f\xfa\xb9\x13\x45\x01\x6e\x05\x87\xaa\x6c\x5f\xe3\xc0\xa6\x2f\x07\xc7\xb9\xd4\x56\x89\xb1\x85\x7a\xcf\x87\xa0\x33\x46\x22\xa9\x10\x7e\x8a\xaa\x98\x0f\x1a\xa1\xff\x13\x13\x4a\x62\xce\x33\x9b\xf4\x75\x64\x94\x13\xed\x99\x61\xcc\xcc\x48\x92\x69\x70\xba\x44\xb6\x63\x74\xd8\x11\xc6\x48\xc2\x85\x34\x4d\x0c\xc8\xaa\x7e\xc7\x7f\xba\x23\xa9\x8a\x28\xb1\x95\x3e\x51\xc0\x15\xe8\xaa\x36\x0c\x98\x83\x44\x00\x23\x59\xa8\x22\xfb\x69\x3d\xd1\xea\xc9\x74\x5a\xf5\xdf\x2d\x13\x86\x44\xfd\xdb\x6e\xae\x8b\xeb\x34\xc5\x3e\x32\xc2\xb3\x04\x09\x13\x1f\x91\x69\xe9\xbc\x46\xc9\x88\x48\x23\xac\xf1\xed\xc5\xe9\xc3\x61\x15\x76\xbb\xbb\x33\xc3\x33\xeb\x72\x11\x19\x85\xb8\xb1\x9a\x0a\xa2\xd1\x54\xdd\x3f\x3e\xad\xf7\xbe\xcd\x85\x11\xc9\x01\x41\xbd\x8b\xb7\xbc\xa8\x86\x02\x88\x8c\x48\xc9\xd0\xfe\xc2\x3b\x2f\x4e\x67\xd4\x62\x8c\x48\x95\xa0\xb7\xd3\xf9\x6a\xeb\x9f\x47\xaf\xb2\x31\x9a\x79\x8a\x9a\x34\xcd\xd7\x87\xaf\x0f\x9f\x24\x3e\x18\x51\x16\x83\xe0\x77\x05\x93\x3f\x9a\xe6\xd8\xe7\x77\x37\xa2\xa2\x08\x13\x1b\x96\x4f\x8e\xd7\x97\x3a\xb6\xed\x78\x60\x71\x62\x2b\xe2\xeb\x9f\x12\x8e\x53\x12\xa2\xe9\xf0\x08\x32\x9b\x63\xc7\x3e\x21\x87\xc5\x2f\xa7\x16\x13\xd2\x14\x6d\x50\x79\x3a\x60\x11\xed\x9d\x17\x7e\xea\x6b\x2a\x23\x6a\x91\x87\x25\xd4\x74\xff\x5e\xb5\xa0\x5c\xa8\x7f\xac\xa1\x3c\x1d\xfd\xd8\x98\x68\x9b\x5b\x36\x3c\x84\xfc\x78\x01\xa2\xc2\x88\x4e\x32\x8c\x9e\x9b\xa2\x3a\x82\x35\xe6\xd3\xd4\x0f\x23\x5a\x73\x66\xa7\xf0\xb2\x3d\xcd\xf6\x9e\x31\x1a\x10\x85\x30\xa7\xb3\xc6\x75\x77\x3c\x95\x08\x92\xe2\x0a\xcb\x3b\x9b\xb2\xad\xce\xc4\xec\xec\x50\x12\x40\x9a\xd8\xdd\x0b\xce\x1b\x12\xec\x28\x4a\xa4\x31\xf1\x2d\x1c\xd3\x2f\xee\x8f\xcc\xac\xb6\xf5\xee\xeb\xfa\x69\x7f\xb7\xb9\xdf\x2f\x1f\xee\x77\x4f\x9b\xab\xfd\xf3\x76\xe1\x07\x71\x89\x75\xb1\x76\x18\x4a\xaf\x7f\x1e\x79\xa9\x66\xaa\xb7\xe3\xd6\xea\xf1\x9d\x52\x19\x1a\x2e\xf2\xca\xe8\x95\x7c\x19\xdf\xa1\x0a\xb3\xee\xa8\xab\x31\xab\xbc\x7c\x59\xcb\xaa\xf9\x68\x5a\x38\xf4\xf0\x69\x46\x19\x4f\x30\xd7\xb1\xbd\xda\xf5\x7f\xd2\xd8\x41\xf4\xca\x9b\xdd\x8f\x6a\xdb\xc2\xd1\x65\xdd\xfc\x08\x61\xda\xe2\xa5\xa9\xd0\x3f\xfa\x9c\xb2\x1b\x10\x06\x21\x36\x0c\x54\x5a\x03\xaa\xef\x5c\x57\xf5\x76\xa6\x13\xc0\x0d\x8f\x23\xa4\xda\xc3\x64\xd9\x43\x39\x6a\x6d\x67\x34\xe4\x8a\xda\x8d\xe3\xae\xb3\xde\x93\xaf\x1b\x4a\x89\xb6\xb9\x3a\xb6\xf9\x81\x17\x03\xcd\x53\x37\x00\x14\x76\xf8\x5d\x9d\xea\xf2\xb9\x6c\xbc\xd6\xf2\x64\x94\x36\x45\xe7\x96\x97\x6f\x8d\xb1\xa8\xbb\x57\xb8\x87\x1f\x3b\x5e\xbe\xed\x3e\x8e\xfe\xd9\xa2\x20\xe5\x46\xf2\xae\x3e\xf2\x36\x77\x7f\x8e\x29\xe0\xd6\x2c\x4e\x75\x39\xb4\xa4\xf6\x70\x42\x02\xb0\x09\xb7\xa1\x42\xc3\xe4\xa3\x26\x2c\x42\xaa\xca\x56\xc1\xea\x34\xcc\xea\x32\x9a\xf0\x0c\x9b\x9b\xcb\xd3\x61\x59\x9d\xea\xc6\xdf\x4f\x22\xc3\xc8\x10\x07\xbe\xbb\x50\x92\xa6\x3a\xc3\xfc\xf3\xbe\x84\x9f\xed\xd5\x49\x39\x1a\xc4\x45\xa9\xd6\xa5\x5a\x94\xea\xa1\x8b\xc6\x79\x61\x98\xbe\x06\xde\x22\xcd\x98\xc4\x69\xf5\xca\x4b\xb5\xab\x96\xa8\xb8\x7b\xea\x11\x8b\x8c\xf2\xd8\x34\xde\x23\xc0\xab\xe5\x85\xd3\x11\x98\xce\xdd\xf1\x83\x71\x99\xa1\xcb\x67\x59\x4b\xf7\x9b\xd5\x2f\xa5\x92\xdd\x99\xda\xbc\x12\xdb\xca\xb7\x28\xd5\x75\x0d\x70\x5e\x4f\xf6\xc3\x35\xbe\xe7\xa2\xe2\x67\x21\x5d\x73\x16\xd3\x9d\xb5\xd4\x32\x2a\x74\xe4\xf8\x4b\x2d\x00\x05\x09\x7b\xdd\xfb\x91\x4c\x60\x8f\xcb\x0d\xb4\x96\xa2\x79\xde\x44\x48\x61\x34\x4c\x5f\xc0\xcb\xa1\x4c\xb3\xab\x8c\x4a\x20\xc6\x30\x59\x54\xc4\x05\x43\x4e\x21\x33\x70\x4b\xd7\xc3\x62\x12\x71\x55\xdd\xc3\x22\x19\xd5\x81\x0e\x1d\x6c\xf2\x9a\xe7\x45\x1f\x42\x3f\x97\xe6\xfa\x7d\x77\x2b\x32\x90\x9b\xf3\x58\x90\x12\xa4\x64\x38\x95\x4e\x15\x74\x71\x52\xf9\x0c\x9e\xdf\x8e\x27\xb1\xc4\x70\xe2\x69\xb1\x5b\xef\xb7\x8b\xdb\xf5\x76\xb7\xb8\x59\x27\xee\x72\x24\x35\x6a\xcb\x9d\x01\x45\x91\xbe\xc6\x1f\xc9\x8c\x7c\xa9\xc6\xcf\x87\xe9\x4c\x7f\x48\x2a\x66\x78\xaa\x7f\x83\x8f\x11\x62\x70\x34\x17\x3a\xf3\x49\xe8\x80\x1e\x7d\x18\x04\x31\x9a\x46\xc8\x58\x75\xd6\x97\x76\xc6\x3c\xcc\x18\x0b\x4c\xbb\x10\x82\x7a\x16\xa5\x42\xfe\xb1\xd1\x07\x64\x2c\x8e\x9c\x24\xf3\xae\x06\xde\x9c\xea\x8f\x39\x16\x01\xc6\x98\xce\x10\xc2\x7b\x5b\xbd\x18\x36\xa0\x47\x57\xec\x9b\x9f\x1a\x2c\x8c\x13\x69\x93\xa1\xcb\xe2\xe4\x18\xb3\x18\x0b\x41\x61\x84\x28\xab\xb2\x39\x21\x31\x33\x4c\xee\x29\x4a\x39\x74\xb7\xfd\xb4\x5e\x3c\xae\x9f\xf6\x9b\xfb\xdd\xd3\xfa\x71\xb3\xda\xaf\x7f\xdf\x3d\x2d\x96\x88\xd5\xbc\x5a\x6c\x5d\x62\x87\x45\x22\xc5\x5c\xda\xf5\xf3\xd6\xfd\x29\x49\x43\xc7\x19\x76\x73\xe2\xb5\xca\x79\xf9\x74\x2a\x2f\xd8\x65\x96\x0a\x85\x89\xf3\xe6\xb5\xfa\xb1\xab\x8e\x98\xc9\x1b\xf5\x7c\x31\x96\x82\xc1\x4c\x35\x0e\x21\x73\x09\x94\xca\x58\xc6\x38\xb3\xed\x69\xab\x9a\xff\x58\xb7\xaf\x63\xc8\xc9\xbc\x93\xc4\xb2\x88\x5b\x82\x6e\x5e\xcb\x57\x03\xf7\x6a\x7e\xef\xc6\x4e\x3e\x44\xc6\xb9\xf6\x9d\xea\x5c\x7a\xfa\xfc\xf0\x5f\xff\xfe\xdb\x38\x3f\xd9\x8d\x35\x69\x54\x9f\x57\x78\x38\x42\x39\x36\x85\x2c\x93\x04\x67\xc0\x62\x79\x7f\xbf\x91\xd5\xaf\xfa\x67\x26\xeb\x24\x93\xd4\x55\xfa\x9c\xdb\xb2\x83\xa6\xdd\x55\x13\xb3\x31\x3e\x8b\x47\x94\x5a\xee\x44\xcc\xc2\x58\xb2\x36\x3f\x71\x45\x12\xa1\xf7\x8a\x32\x41\x0b\xa5\xb0\xf3\xc5\xac\x18\x37\x02\x38\x41\x03\xb5\xbe\x5f\x3f\x6c\xcf\xda\xd5\x18\x93\xb6\x43\x1b\x5d\x10\x8c\x83\x26\x8d\xad\x8c\x49\x21\x71\xfb\xde\x2d\x37\x7b\x3e\x5c\xa8\x2a\xcc\xb0\x4c\xbf\xab\x3b\x9f\xb9\xf6\x7f\x8e\x54\x66\x9b\x6b\x57\xf0\xee\xff\x1a\x47\x8e\x04\xff\xda\xa8\x37\x4f\xee\x44\xa9\x34\x20\xae\x47\xd2\x2c\xb1\x89\xee\xaa\x1d\x08\x44\xe1\x33\xa9\x9a\x1f\x7b\xd2\x6b\xc6\x20\x36\x02\xd9\x36\x7e\xba\xae\xab\xff\x0c\xd0\x1c\x7d\x44\xc2\x20\x55\x08\x8d\x7c\xfa\xb9\x5e\xdc\xe2\x1b\x9d\x84\x05\x0c\x94\xb1\x4e\xe5\xe9\xf0\x04\xda\xff\x55\x6b\x34\xbc\x56\x63\x05\x1a\x53\xb2\x9d\x65\x6e\x76\x3b\x24\xd3\xcc\x43\xa0\xef\xa1\xfd\x51\xd5\x2e\x19\x1d\x06\xd4\x40\x69\x3b\x47\xf5\xb5\x82\x32\xff\x69\x3a\x55\xfd\x92\x21\xd9\xbf\xdd\x50\x09\xd8\xf8\x62\x11\xac\x6f\xa2\x2a\xce\x74\x5d\xfd\x50\x9d\x18\x9a\x8a\x5c\x4d\x0f\xa9\x08\xdd\xd9\x4a\xeb\x22\x2f\xe1\xac\xd6\x36\x7a\xcd\x21\x09\x8d\x28\x3c\xb6\x2a\x2f\x1f\xb6\xbb\x2e\xe4\xda\xef\x36\xeb\x27\x27\x65\xc4\x42\x9a\xc5\x98\x90\xdb\xf1\x7c\xe0\x46\x86\x2c\x52\x68\x06\x4c\x76\xf9\x76\xfd\x6d\x7d\xeb\xb8\x35\x58\x18\x91\xc8\x00\x79\x4d\xe3\xe6\xd5\x90\xdd\xe2\x92\xb5\x08\xa3\x30\x41\x5b\x8f\x45\x1a\x53\xc3\x9f\x3e\x5d\x14\x1b\x59\x13\x13\x8b\xe0\x52\xe8\x22\x8e\xc9\x75\x92\xd0\x73\x81\xb8\x2e\x00\x16\xc6\x22\xc6\x34\xc1\x92\x1f\x5b\x9e\x97\xbf\xe5\x6d\x9b\x43\x7f\x14\x22\xc3\xed\x09\xf0\xb6\xff\x31\x68\xe9\x66\x61\x42\x29\xa6\x4b\x0e\x95\x7c\xc3\x74\xbf\xdd\x58\xc6\x3f\x9a\x80\x46\x22\x47\xc9\x0b\x79\x3c\x35\xed\x71\x8e\x26\xda\x8e\x4d\xc1\x08\x2d\x63\x63\x52\x33\xd1\x3c\x65\x61\x16\x46\x98\xb5\x3d\xf0\x9f\xb6\x31\xf4\x0a\xda\x4d\xe9\xd5\xf8\xbb\x11\x5a\x19\xd2\x97\x23\xc8\xd6\x4a\xa4\x8d\x7f\x23\x13\x9a\x5b\xf2\x9f\x51\x16\x79\x3e\x63\x14\x66\x2a\x46\x14\xc6\xf5\xd3\xa3\xfb\x11\xae\x62\x14\x58\x90\x45\x25\xdf\x0e\x9e\x4b\x8f\x85\x42\xe8\xc8\x56\x7a\x6e\x50\x5b\xb0\xc0\xdc\x8f\x3d\x2a\xe3\x04\x57\x6e\xf7\x64\x5f\x79\xf3\x3a\xc7\xa9\xf8\x59\x05\xeb\x02\x4b\xba\x5b\x6b\xa1\x94\x69\x68\x0b\x75\x93\xf7\xa6\xa8\x21\x37\x7e\x37\x2a\xb1\x1f\x87\x8f\x41\xb6\x2a\x54\x21\x15\xa9\xe7\xb5\x40\x4b\x30\x93\x5e\x0f\x55\xc4\x2c\x6d\xb7\x21\x7c\xb7\x9c\x89\xdf\x10\xd7\xf4\xc5\x0f\xd2\x08\x31\xbd\xc9\xdf\x01\x9b\x83\x86\x64\xaf\x2c\x54\x89\xc4\x52\x98\x2e\x72\x84\xa9\x22\x81\x54\x37\x57\x87\x5d\xe6\x6e\x6c\x46\x5d\x32\xce\x37\xd1\x82\x42\x30\xc3\xe4\x8b\xaa\x2c\xc4\xea\xd9\xf5\xf3\xef\xc3\x56\x3b\x16\x2a\xad\x11\x77\xb4\xdd\xdc\x7e\x5b\x3f\xb9\xfc\xc9\xfd\x6a\xe9\x06\x40\x64\x50\xd6\x9d\xd5\xcd\x61\x1e\xc8\xcf\x42\xc8\x0c\x37\x92\x75\x1d\xaf\x64\x75\x3a\x56\x17\xb8\x4b\x3a\xcf\x45\x62\x37\x81\x11\x07\xdb\xd5\x27\x30\x29\xcf\xa1\xf7\x16\xea\x90\x22\x93\x41\xe7\x28\x5d\x56\x69\x60\xa1\x4e\xa9\x51\xa1\x3d\x1d\x0e\x16\x6c\xed\x57\xa6\x96\x11\x9a\xc5\xfd\x65\x96\x56\x33\x32\x0a\x22\x86\x11\xf0\x81\xbf\xc1\x55\xae\x46\x41\x4c\x14\xa4\xc2\x25\xe9\xbb\x8d\x1f\x7b\x50\x5e\xac\x1e\x92\x1d\x42\xba\xa0\xa5\x7b\x8f\x77\x5b\xfb\x3d\x47\x53\x23\x22\x91\x40\x22\xa1\x1e\xe1\xfa\x1d\xe0\xad\xa7\x35\xf4\x37\x42\x35\xe1\xa9\xb5\x05\xdb\xaf\x0b\x36\x4c\xa8\x47\x2c\x16\xe8\x8f\xf9\x5e\x4c\x53\x29\x7a\xcc\x61\xd2\x87\xc1\x22\x26\x63\x44\xee\x3c\x56\xe5\xcb\x3c\x88\x93\x45\x11\x65\x48\x52\x68\x03\xf3\xdb\x8a\x97\x2b\x3e\x60\xec\x62\x51\xac\x3d\x45\xda\x23\x92\x8b\x0d\x72\x2e\x83\x99\x18\x25\x09\x60\x36\xd3\x86\x5d\x86\xbb\xb0\x4f\x92\xa7\xff\xa2\x3d\xc6\x6c\xf4\xbf\xee\xfc\x34\x45\xa9\xe6\x1f\xe3\x0e\xb1\x89\x75\x8b\xd2\x20\xce\x0c\xfc\xc0\xf6\x1f\x62\x0d\x67\xd0\x1d\xd3\xf9\xbc\x1c\x09\xdb\xf6\xc3\x66\x8e\x8d\x95\xad\xfe\x14\x32\xca\x22\xcc\x6f\x9a\xfe\xbd\xee\x2c\xcc\xfa\xdc\x9e\x65\x7d\x22\xce\x01\xc1\x3a\x88\xe0\xdb\xac\xf6\xee\xa7\x39\x30\x8e\x9d\x78\x3e\xcc\x8a\x84\x0c\x33\x53\x70\x3b\xf0\xbc\x3c\x63\xd8\x62\x91\x50\x21\x33\xf5\x13\x4f\x94\xde\xfd\x31\xca\x88\xc1\xce\x9b\x68\x72\x72\x8e\x96\x38\xd7\x90\x1e\xeb\x09\x89\x5b\x46\x49\x82\xd1\x37\x96\x5c\x61\x81\xf5\xc0\x7f\x1a\x8a\x71\xb7\x38\x22\xa9\x0d\xc5\x5b\x37\xe5\xf7\xdd\x45\xbe\x8c\x4d\xe9\xd9\x7f\xed\x79\x2a\x66\xc4\x70\x6a\x9f\x30\x9f\x8c\x92\x28\xfe\x98\xc2\x78\xb7\x5e\xad\x7f\xf7\x7f\x4b\x52\x8e\x7c\x1b\x2e\xae\xbc\x81\x92\x5c\x58\x86\x8a\x87\xc4\x3a\x43\xc5\x48\xf5\x9b\x45\x10\x93\x44\xfb\xe6\xd7\x99\xfa\x6d\x04\x29\x03\xa7\x93\x0e\xc7\x82\x9f\xa9\xac\xd9\x71\x3a\x8b\x88\xdb\x6e\x57\x4d\xfb\x8f\xf6\xa2\x1c\xdb\xf8\xc4\x38\x08\x32\x74\xf1\x37\x07\x23\x1d\x3c\xec\xe7\x1d\x4d\x91\x38\x10\x06\xfb\x7c\xe7\xc6\xb9\xb7\x1e\x13\x41\x70\xaf\xc7\x17\x3e\xbb\x4b\xc5\x34\x14\xe8\x72\x3b\xd6\x58\xe7\xfc\x58\xe7\x61\x90\x5d\x8a\x69\x1a\x21\x67\x84\xe3\xa9\x59\xf2\xe6\xf5\xb1\xae\xfc\xe1\x2c\x95\x89\xeb\x4b\x37\xfb\x82\x3b\x22\x75\x60\xa8\x15\x4f\xf0\xbd\xaa\x8b\xb3\x14\xf4\x70\x12\xc5\xcc\x2a\xc8\xff\xe8\x7c\xb1\xbb\xea\x3d\xf7\x37\x10\x12\x69\x5d\x97\x5a\xed\x0f\xd0\xf2\x62\x6f\x54\x9e\xdc\x71\x11\xf5\xe2\x17\x46\xf4\xed\x9e\x1f\x7a\xe6\x09\x17\x62\xc5\x91\xb0\x69\x37\xde\x8c\x55\x5e\x67\x00\x8f\x2c\x8e\x34\xc3\xb4\xc2\x73\x9b\xbb\xe2\x6b\x1c\xc7\x0a\x39\x54\x3a\x37\x6c\xf7\xc3\xf0\xfd\x3c\xe5\x0d\x5c\xc1\x8b\xf7\x3c\xe3\x44\xa4\xb8\xb4\xb6\xc7\x22\x6f\x11\xea\x34\x52\x21\xfc\xc5\x3c\xf8\xe5\xbf\xe3\x59\x90\x28\x43\xff\x64\x98\xa7\x07\x72\x8d\x2c\x4e\x20\x72\x82\x68\x1b\x1b\xc5\x0c\xe0\x18\xd3\x34\x53\x9c\x92\x20\x31\x72\xa1\xad\x51\x54\xc2\x49\x30\xdc\xa4\xe2\x2c\x8e\x10\x02\xb4\x5b\x3c\xdd\xac\x07\xf0\x52\x16\x67\x22\x40\x7b\x61\x8d\x73\x33\xca\x97\xc6\x99\x10\x18\xf6\x77\xa6\x74\x4c\x65\x7b\xe1\xa9\x78\x10\xa1\x0b\x67\xa2\x9c\xa5\x51\xec\xec\xec\xe5\x37\xee\x05\x46\x59\xcc\xc3\x14\x5d\xfc\xf5\xee\x6b\x14\x04\x55\x99\x90\xcc\x1f\x4a\x22\xa7\x7c\xfe\x30\x89\x4e\x62\x41\x22\x65\xa0\xe0\x58\xaa\x3a\x95\xaa\xc8\xcb\x17\x2c\xbb\xb4\xe7\x69\xd8\x58\xa4\x5c\x0f\x5a\x2f\x51\x53\x3a\xff\x84\xa3\xfa\x53\xf7\x30\x16\x5c\xa1\xf2\xd6\x2b\x6f\xfe\x5e\x89\xee\x45\x1f\x0e\x50\x2a\xbb\x80\x3f\xdd\x3b\x62\x01\x21\xe6\x93\xb6\xa6\xb5\xfa\x8f\x87\xe7\xe9\xad\x42\x86\x89\xe0\x23\xff\x30\xad\x9d\xbc\x7b\x34\xbf\x90\x24\x95\x18\x9d\xe4\xa5\xae\xea\x03\xaf\x1f\x7a\xd7\xd7\x8d\x48\x01\xcb\x2e\xcf\x23\x0d\x9c\x6a\xbe\x5e\x1d\x2b\x41\xd1\xcd\xdc\x42\xa9\x6e\x97\x4f\x7f\x81\x48\x9d\xc5\x4a\x69\x84\x2f\xed\x83\x9f\xd7\x55\xfd\x66\x45\xb2\x7b\x6f\x31\xd6\x84\x26\xe0\xd9\xc2\x1e\x6b\x18\xf2\x15\x8d\x7f\x5f\x53\x43\x5d\x2f\xad\x58\xe9\x04\x00\xce\x62\xad\x8d\x80\x5d\x0b\xfc\x40\x10\xa0\xe9\x6d\xa4\xd6\x0a\x11\xd6\x8b\xd5\xc8\x59\x4d\x48\xc2\x60\xc8\x2a\xbe\x2f\x40\xb7\x28\xe9\xd1\xec\xdb\x6a\x7f\xac\x2b\x44\x77\xda\xd1\x94\xa4\x48\x2f\x71\xb7\xb8\x5b\x77\x31\x6a\xff\x77\x8e\x01\x90\xb4\x6f\x10\xa3\xc5\xbc\x2a\x87\x9d\xfa\x76\x28\x63\x81\xdb\x51\x2c\x31\x24\xa8\xef\xaf\x50\xe2\xae\xfc\xf0\xde\x0f\x0c\x99\x57\x39\x78\x34\x77\xf1\xb5\x3a\x8d\x3b\xa5\x59\x12\x86\x29\x32\x7a\x1e\x0b\x2e\xc1\x64\x61\x46\xaf\xa4\x1b\x80\x4b\xf1\xc6\x56\xa6\xae\x3e\xee\xa7\x97\x48\x8c\xc0\xbe\x4b\xbe\x9e\xc9\x9c\xb3\x24\x52\x10\xba\x4c\xa4\x25\x22\xbb\xe2\xe5\xbc\x68\x19\x4b\xe2\x90\xa0\xba\xc6\xdd\xe2\xf7\xfd\xd3\xe6\xfe\x66\xbf\xdd\xfc\xd3\x19\x8e\x24\x8e\x75\xea\xd5\x3c\x47\x51\x4c\x12\x4b\x92\x59\xf2\x3a\x04\x16\x5a\xe8\xd7\x70\xd7\x48\x12\x12\x84\x8e\xac\xee\x02\x03\xe7\xe4\x6e\x12\xc1\xb0\x7b\xec\x8f\xaa\xa8\x66\xaa\x2e\x49\xa2\x0d\x5a\x06\x4b\x94\x35\xb6\xa7\xf1\xc5\x20\xb5\x37\xb6\x54\x49\x9a\xa4\x56\x46\xa6\x39\x1d\x60\xe6\xfb\xa6\x69\xd6\x6b\x98\x03\x36\x31\xdd\xe4\x75\x31\xf9\xd5\x54\x98\xa4\xe5\x0b\x3f\xc0\xda\xf7\x6c\xb0\x24\xa3\x59\x1a\x0d\x50\x8b\xab\xba\x3a\x36\xd3\x79\x9e\x64\x2c\xc6\x46\x86\xed\x09\xfb\x02\x1d\xb5\xc4\xe8\x7b\x38\x0b\x94\x64\x10\xa3\x69\x44\xd7\xee\x11\xea\xdd\x6b\x75\x6a\x78\xa9\x90\x10\xe1\xba\xaa\xaf\x4e\x1f\x5d\x4c\x6c\x47\x73\x66\xa8\xa4\x8c\x52\xe0\xa3\x51\xcd\xf3\x07\x93\x04\x9d\x95\x2d\xb4\x9b\xc7\xa7\xc9\x6e\x3a\x76\x15\xa7\x0c\x0b\xa3\xaf\x28\x38\x43\x32\x56\xe5\x2a\x4c\x23\x9b\x99\x08\x08\x90\xab\xc5\x8b\x8a\xf3\x2e\xd2\x9a\x6d\x85\xeb\x06\x27\x08\xaf\x84\xf6\xf5\xca\xb3\x9e\xb3\x44\x32\xe2\x98\x10\xf7\xb9\xac\xca\xfc\x4f\xa7\xf2\xfd\xa9\xbd\x4a\xa4\xe4\xc8\x5f\xeb\xe4\x34\xae\xaa\xd3\xcb\xeb\x39\xba\xfb\x17\x99\x03\x7b\x31\x45\x22\xdb\x56\xaf\x67\x48\x48\x59\xa2\x78\x8c\xf8\xba\xe6\xb5\xfa\xe1\x42\xed\xfb\xd3\x61\x3a\x0a\x24\x63\xc3\x08\xed\x7b\x5e\xc2\x16\x8a\x33\xa6\x14\x3b\x1e\x62\xd3\xa5\x06\xed\xab\x25\xff\xb8\xf3\xda\x33\x5f\xfc\x18\x8d\xde\x97\x46\x70\xe7\xd5\xc7\xca\x89\x24\xba\x01\x3a\x08\xb4\x13\x4c\x6d\xe1\x70\x65\x5a\x30\x36\xab\xc9\x3c\xd6\x8a\xb9\x50\xfe\x6b\x75\x80\x85\x7a\x9f\x0d\x0b\xd3\x40\x49\xa4\x6b\xf8\x71\x74\xa5\xfa\x94\x28\x30\x18\xc4\x6e\x9e\x8f\xab\x23\x29\xe5\x46\xba\x46\x57\xa7\xba\x7d\x75\xf8\xf7\xa7\x1e\xa3\x95\x52\x50\x88\x0a\xdf\x02\x14\x70\xd3\x63\x38\x53\x46\x03\xe4\x32\xdf\x6d\x76\x8b\xfb\xa1\xa9\x4f\x19\xe3\x86\x4b\xc8\x49\xa6\x2e\xab\x42\x0d\xb5\xf8\x58\x1a\xa6\xc2\x51\x18\xdd\x55\x65\x67\x0d\x37\xdf\xfc\x4d\x85\x5c\x07\xa6\xf1\xbd\x7e\x83\x76\x7f\x75\xfa\x98\xd4\x94\xdd\x38\x15\xa3\xfd\x2b\xaa\x1f\x50\x5f\x0d\x4a\x77\x69\x94\x19\x74\x42\x0b\x4d\xbb\x3f\x42\x2d\x1f\xb4\x4b\x6b\xa6\x31\x53\x29\x19\x8a\x96\xde\x56\x3f\x4c\xe3\xf9\xec\x44\x4d\x13\x92\x60\x8e\x02\x7e\x5e\x03\x60\x1d\xd4\x5d\x29\x89\x4c\x07\x13\x74\x0e\x3c\x1a\xfd\xe7\xed\xea\xfb\x7a\xe3\x8f\x4b\x8d\x84\xf5\x28\xba\xe5\x55\x28\xdd\xd1\x34\x0a\xf1\x2d\x79\x85\xdf\xb9\x6c\x9d\x1b\xcb\x53\xcc\x52\xae\x56\x8b\x79\x60\x44\x9a\x31\x6e\xe6\xae\x21\xb0\xb3\x1f\xb2\x9e\x8e\x8a\xb4\xd6\x7e\xd4\xf6\xe3\x20\xaa\x62\x64\xf7\xd3\x2c\x49\x6d\xaf\x9c\x15\x3f\x9e\xef\x3d\x60\x69\x06\x7a\xd8\xed\xed\x6a\xc3\xb3\x2b\x25\x15\x71\x8a\xd2\x08\x65\x55\xfe\x07\xea\xca\x83\xca\x0d\x7d\xdb\x75\x55\x2f\x8e\x13\x00\x69\x2a\xd2\x10\x17\x8e\xe9\xcf\xfa\x7f\x88\x7b\x97\xe6\xc6\x71\x2d\x6b\xf4\xbf\x7c\xa3\x1a\x9c\x01\x09\x02\x20\x79\x67\xb2\x2c\x3b\xdd\xe9\x87\xda\x92\x33\xab\xba\xa3\x43\x81\xc7\x86\xcd\x4e\x8a\xd4\x21\x29\xdb\xaa\x5f\x7f\x83\x1b\x00\x5f\xa2\x9c\x15\x5f\xdc\x88\x3b\x39\x59\xc7\x84\xf8\x04\xb0\x5f\x6b\xaf\x75\xbd\xf9\xb1\x7a\xdc\xbe\x3c\x7b\xf3\x96\xc8\x54\x84\xa9\xef\x10\xfd\xcf\x63\xd9\x0c\x2b\xe8\x89\xa2\x89\x4d\x61\x7a\xdb\xa0\x2d\xe9\xc1\x4b\x91\x35\xe4\x0a\x1a\xd1\x0d\x04\x82\xf0\x06\x2b\x56\x36\x59\x1c\x1a\x00\x73\x02\xb7\x95\x4b\x2a\x85\xbf\x09\x32\x13\x90\x9c\x58\x04\xcd\xb1\x86\xab\xa3\xaf\xb2\x24\x26\x4c\x84\x45\xff\xe8\xab\xdc\x61\x80\x7d\xce\x3c\x0d\x62\x1d\x87\x9d\xdb\xdc\xfd\x35\xb1\x64\xec\xca\x0a\xa0\x8f\xdf\x4e\x1a\x12\x8b\x8a\x72\x6f\xdf\x26\x19\xfd\x31\x1e\x22\x9f\x8a\x9f\x58\xe7\x90\xe5\x34\x54\x21\xf6\x04\xe9\xec\x7d\xfe\x8b\xa5\x84\x80\x67\xe3\x5a\x8a\x06\x5e\xcb\x2a\x3b\xd7\xac\x9a\xfe\x86\x1b\x8c\xcd\xd7\xd9\x27\xe4\xf5\x83\xe8\x22\xb7\x94\x18\x46\x71\xb9\x67\xef\xf0\x80\xed\x35\x93\x34\x7a\x1a\x51\x8d\xf5\xce\x97\xc3\xeb\x97\x4a\xe0\xa3\x49\x98\x46\x09\xd3\x43\x7d\xbd\x9f\x59\xf3\x66\x8b\x69\x85\x82\xa5\xc8\xf3\x5b\xd1\x3d\x73\xa4\x15\x36\x94\xec\x30\xa0\xae\x07\x52\x63\x51\x1a\x19\x19\x58\xd7\x4c\x1f\x15\xec\xcb\xe2\x02\x21\x43\x94\xd2\x30\x46\x8f\xe0\xfe\xe9\x76\xf7\x08\x1f\x57\xe7\x11\x97\x1f\x98\x32\x2c\x46\x64\xf5\xba\x02\x31\xc1\x20\xa6\x0c\x08\xc6\xc0\xdb\xf5\xfd\xe2\xaf\x2f\x9a\xee\x86\xc9\x9b\x94\x87\xc4\xf2\x73\xbb\xa6\x9a\x67\xd0\xb0\x3f\xb4\xf3\x7a\x3d\x94\x42\x8c\x52\x4e\xad\x11\x68\xca\x2b\x8f\xea\xfd\xd7\x0c\x80\x39\xe5\x8c\x7a\x4a\xa9\x75\x59\xbc\xbe\x8b\x7c\xfb\xf9\x0c\x4d\x95\xc1\xbb\xc8\x17\x16\x8a\xd9\xdf\x73\xac\x13\x8f\x62\x7c\x29\x8e\x35\xe8\x39\x12\x99\x28\x4d\x02\x1e\xb9\xca\xd7\x6a\x0f\xd5\x2b\x14\xcd\x37\x91\x37\x83\x74\x50\x9a\x04\x36\x56\x43\x2d\x9f\x41\x95\x2f\x4d\x12\x86\x3b\xff\x32\x2f\x8f\xda\x4b\x42\x5d\x24\x17\x9d\x4c\x86\x44\x26\xa9\x1c\xf4\xae\xda\x45\x31\xff\x75\x52\x16\x61\xaf\x1f\x36\xed\xf4\x17\xf0\x47\xc1\xb2\xcc\xfe\x57\xf9\x26\xaa\xad\x4f\xa7\xa7\x82\xd8\x3f\xeb\xaa\x3c\xb4\x3b\xc9\x80\x92\x25\x4a\x85\x6b\xc1\xaf\x00\x43\x84\x99\x12\x43\x2a\xe2\x00\x3d\x56\x27\x94\xfc\x0c\x35\x54\xef\xe0\xe9\x1c\xba\x13\x09\x50\x7c\xc4\xd7\x15\xc5\xdd\x31\x19\x09\xb4\xac\xb9\x98\x9e\x5b\xc7\xd4\x91\xb5\xfc\x28\x3b\xeb\x9d\xca\x30\xd0\x48\xa2\x2c\xea\x06\x7d\xe8\x9d\x08\xbb\xb3\x69\x19\xe0\x6e\xe5\x04\x86\xe6\x28\x28\x27\xaf\x4d\xab\x14\x03\xdd\x6f\x4f\x2f\xcf\xfe\x2c\x10\x86\xd4\xa1\xd5\x37\xab\xe5\xd3\xe3\xf5\x6e\xb3\x5d\xad\xad\xb6\xe2\xfa\xfe\x6e\xd5\x0f\x04\x0d\xae\x10\xd3\xe4\x80\xc5\xbe\x6e\xc6\x9a\x98\x7a\x58\x98\x25\x13\xea\x76\x33\x93\xda\xe2\x60\x8f\x3a\xc0\x4e\xa4\x76\x73\x9d\xff\xb4\x46\x10\xc4\x56\xfc\x58\xaf\x26\xd8\xde\xd4\x08\xe5\x41\x25\x7d\x87\xb7\x3d\x26\x02\xae\x98\xa5\x6b\xd4\x77\xcb\x27\xcc\x2e\x75\x87\x00\x2c\x93\xe3\xfb\x04\x8f\x34\xba\xb0\x08\x13\x4b\x67\x5d\xbe\x43\x65\xf2\x89\xf6\x4b\x7b\x38\xee\x65\x80\x9c\xb7\x7b\xe1\x44\x4a\x73\xdd\x11\x9b\x49\xa8\x9e\xcc\xf7\xa2\xfc\x28\xd6\x55\xeb\x38\x36\xa7\xb3\x7b\x0f\x75\x80\xee\x6d\xeb\x64\x5a\x06\xfc\x61\x61\xd0\x27\xa2\x04\x89\xc3\x80\xd9\x97\xfc\x0b\x6c\x3f\x9a\x63\xee\x9f\xdc\x2a\x0d\x6c\x8b\x88\xe5\xc2\x33\x55\xb9\x97\xf3\x20\x4a\x41\x03\xcb\x7d\xbc\xa8\x9a\xcc\x64\x2a\x13\xf9\x23\x1c\xab\xf6\x7f\x87\xd5\x70\x41\x03\x10\x6c\x84\xb4\x1a\xbd\x60\x9a\x30\xf4\x06\xb5\x95\x6a\x3c\x3d\x03\xe6\x02\x26\x97\x6a\x23\x42\x44\x2f\xb5\x36\x29\x17\xd9\x98\x20\x32\x12\xd4\x91\xe9\xa1\xd3\x87\x6d\x47\x96\x8a\x6e\xd7\x6e\x63\xa7\x1b\x80\x75\x59\xe6\xbb\xcc\x2a\x30\xa9\xb2\xef\xd2\x11\x54\x8a\x68\x90\x15\x7b\xcb\x3a\x2f\x57\xb0\x30\x45\x1f\xcf\x89\x17\xdb\x9b\xdf\x0c\x70\xab\x82\x71\x16\x0c\x0a\x31\x78\xec\x41\x7c\x0e\xb5\x2c\x23\xc1\x05\x8d\x7a\xf8\x17\xb4\x1f\xe9\xfb\x5f\xcb\xc9\x13\x72\x15\xe3\xa0\x5d\x56\xdf\xe9\xd5\xa7\x6d\x3c\x19\x7a\x67\x22\xe6\x14\xdb\x14\x9a\x0c\xaa\x70\x08\x89\x12\xb1\x4c\x02\xda\x6b\x1f\x8a\xcf\x5b\x51\x1f\xce\x58\x1a\x23\x11\x83\x53\xf5\xf4\x79\xe9\x3c\x9f\xdc\x45\x12\x6a\x1a\xf8\xbc\xf3\xd5\xad\x2f\x05\x88\x84\x58\x44\xb2\xb2\xfd\xd8\xcf\x30\x09\x96\x45\x1a\xa6\xdc\x7e\xc5\xcf\x2d\xd4\xcd\x63\x59\xed\x45\xfe\x8f\x48\x64\x22\x91\x46\x31\xc2\xdc\x37\x7f\xdd\xff\xb8\xeb\x5e\x6d\xaa\x39\x66\x4e\x17\xfa\x3d\xab\xa1\x5a\x8a\xfa\xe0\x25\x0d\xdd\x08\x11\xa6\xc3\x50\xc3\xa3\xf0\xc7\x37\x26\x99\x25\x92\x40\xfe\x07\xd4\x5b\x38\xf6\x6c\x47\x91\x90\x82\x05\x36\x31\x66\xa0\xaa\xa0\x5a\x0d\xfd\x30\xa1\x43\x1e\x5b\xb2\xe6\x4e\xa2\x66\x75\xc8\xea\xf2\xdc\x47\xf1\x3f\x90\x16\xbd\xd9\x93\x02\xbf\xbe\xe6\xe0\x25\xf8\xba\x39\x07\xc4\xa0\xe6\xaf\xf8\xb8\xc4\x3e\x13\x09\x48\xac\xdb\x88\x9f\xa2\xaf\x31\xc9\x20\x34\xb8\xea\xb2\xa2\xf1\x9b\x4d\xbb\xd5\x8d\x3f\xb5\x0c\xa4\x31\xd4\xeb\x74\x54\x75\x59\x88\x7c\xd3\xae\xfc\x85\x6a\x8e\x22\xf7\x5d\xc2\xb3\x8e\x95\x0c\x14\xe7\xa1\xef\xaf\x2f\xe0\xe5\x60\x5f\xca\xce\x35\x28\x4c\xae\x14\x6a\x0b\x1c\xcf\xcb\xd7\x55\xad\xc4\x01\xbe\x89\x46\xbd\x79\x4e\x87\xde\xf0\x4b\x12\x71\x24\xb7\x3c\x60\xdb\xe4\x6c\xf2\x53\x12\xaa\x95\xdb\xfd\x36\xc7\x7d\x3d\x6c\x07\xf5\x23\xd2\x28\xe9\x89\x0d\x2d\xa7\xa0\x63\x84\xf2\xb1\x99\x24\xca\xba\x36\x15\x08\xdd\x6e\x4e\x2a\x1f\x53\x93\x44\x32\xa2\x21\x46\xd4\xb6\xdd\x75\x83\x14\x93\xfe\xd7\x91\x31\x5e\x53\xdc\xe1\x66\xcb\xa5\x17\x15\xdd\xbe\x8d\x9b\x19\x25\x25\x0a\xcb\xf0\xe3\xbc\x9e\x83\x33\x24\xe3\x89\x2e\xa9\x90\x08\xc2\xbe\xba\x5a\xcf\x0a\xbd\xfb\x61\x32\x88\x2d\x20\xed\x7e\xb7\x58\x7b\x68\x86\x6c\x3d\x40\xac\x06\xd8\xe7\xee\x4a\x12\x92\x13\xa9\x22\xdf\x3a\x6e\xcb\x8a\x93\x2a\xb6\xe4\x4c\x13\x67\xa7\x45\xf5\xda\x41\x76\x64\x12\xa4\x58\xfe\xfd\x59\x56\xbf\x7e\xb4\x41\xfa\xa9\x3b\xa2\x34\x0a\x72\xec\xe0\xdf\xc7\xec\x70\x5d\x7e\x14\x83\x7e\x82\x7f\x0d\xd7\x90\x4c\x09\x51\xc2\x06\xd5\x6b\x51\x68\xb1\x7a\x5e\x92\xe0\x1f\xf1\x27\x44\x32\x65\xa9\xee\xb9\xd3\x77\x1a\xde\x27\x77\x9e\xca\x04\x95\xbd\x9d\x63\xe7\x6c\xd6\x4d\x59\x3d\x39\x9e\x58\x7f\xc3\x52\x11\x94\x4e\x7b\x6d\x1f\x43\xd4\xf5\x08\x04\xfb\xe5\x06\x24\xa5\x49\x30\xdc\x7a\xd9\x2c\x06\xf9\x66\xa9\x22\xa3\x3a\x0e\xb7\x3c\x47\x59\x9c\x87\xac\xb8\x15\xb5\x6b\x89\xf7\xe3\x78\xc8\xbd\x1c\x99\xa5\xd8\xe9\x23\x0f\xa9\x15\x67\xcc\xd7\x36\xf7\x22\xf3\xe8\xc3\x6d\x96\xe7\x53\x4e\x8f\x48\x42\x60\x35\xe4\x6c\x2f\xcd\x4c\xb7\xa8\x04\x43\xd1\x7d\x2e\x8e\xfb\xd6\xd7\xeb\xae\x63\x98\x4c\x45\x17\xcc\xf6\xca\xc1\x93\xd7\x69\xb4\xa1\x9d\x16\xf8\x06\xec\x90\xf1\x15\x0c\x04\x18\x7c\xef\xea\xe3\xde\x76\xcd\xaf\xa1\xfa\x55\xbb\x86\xb1\xc8\x97\xfe\x55\x10\x2b\x2e\xba\x9a\x02\xae\xfa\x31\xb2\x52\x05\xc2\xd1\xf5\x78\x1f\xfb\xae\x76\x6d\xf8\x6e\x40\x98\x32\x4c\x1b\xb7\x01\x59\x59\xf5\x1b\xa4\x0a\x75\x82\x7b\x85\x29\x2b\x1b\x36\x3e\x15\x57\xf0\x26\x72\x33\xcd\xd2\x2a\x92\x68\xcc\xf6\xc0\x3b\x14\x0d\xda\xcd\xc9\x1b\x53\x44\x51\x4e\xfc\x46\xfa\xec\xe2\x03\x7f\x21\x4a\x43\x70\x89\x69\x34\x34\x65\x75\x9a\x91\x85\x8c\x14\x4d\x6d\x67\xd8\x75\x99\xe7\xa2\x1a\x40\xe2\x14\x0b\x24\x36\x56\x95\xed\xf4\xf0\x36\x68\xb4\xdb\x28\xce\x15\xd2\xc8\x14\x65\xb3\xfa\xf7\x51\xe4\x7f\xcc\xf0\xf7\x8c\x32\x79\x8a\x27\x10\x59\xdc\x5a\xa1\x20\xbf\x15\x7b\xcb\x19\x69\x93\xf5\x35\x36\x62\x60\x9b\x97\x1b\x9e\x70\x89\xd5\x85\x85\x12\x1a\xf6\x63\xa6\x5b\x3f\x24\x91\x91\xe3\x95\xf5\xdb\xe5\x2c\x08\x53\x25\x60\x2c\x5f\x05\x0a\x25\x5d\x9d\x10\x4c\xff\x4d\xf8\xdd\x46\xa5\xda\x20\x2f\xef\x21\x3f\x36\xa5\xaa\x06\x07\x8c\x42\xca\xd9\xae\x31\x78\x7b\x19\x4b\x3b\xbe\xa4\x08\x63\xcf\xed\xff\xb2\xb9\x5e\x6d\xbf\x0d\x83\x2b\x25\x23\xf0\x50\x8c\xc9\x3c\x6b\x23\xfe\xb9\x67\x95\x3c\x4e\x3d\x37\x19\x3a\x32\x7d\xb0\xa1\xa4\xb1\x44\xdd\x6d\xfc\xfe\xb4\xbe\xc4\x46\xd2\xd7\x1d\x87\x1d\x9d\xa3\x4f\xa4\x12\xcb\x93\xd8\x67\x4d\x5b\x23\x3d\x7e\x30\x4d\x34\xba\x4d\x05\x7c\x36\x0e\x5d\x34\x19\x40\x03\xac\x26\xbb\x69\x79\xb5\x5d\xce\xdb\x04\x65\x22\x40\x69\x84\xbc\xfc\x80\xda\x1b\x4f\x1b\x44\xf6\x75\x05\x1d\xc4\x94\x59\x00\xc2\xeb\x9b\xe7\xfa\xf4\xc7\x48\x10\xa3\x87\xdc\xe5\x22\x2d\x22\xaa\x3b\x1c\x01\xfe\x14\xb1\x31\x64\x29\x7c\x06\x59\x47\x82\xf8\x82\xf7\xb2\x02\x9d\x35\x57\x65\x31\x31\x2f\x9a\x02\x95\xcc\x5a\x00\x94\xfe\x99\x22\x50\xce\x3e\xb9\x66\x51\x8a\xe9\xd1\x07\x78\x15\x43\xa7\x4e\x33\xb0\x89\x06\xd7\x79\x36\x9b\xe8\xd6\x0c\x14\x42\x6f\xd7\xf9\x69\x54\xe7\xd4\x9c\xda\x4e\x71\x14\x15\x7e\xee\xfe\xca\x12\xdd\xcb\xe5\xdd\x3b\x65\xd7\xac\x2c\xc6\x0c\x62\x7e\xb4\xb1\xb5\x25\x4b\xa1\xf5\x1d\x4e\x13\x27\x45\xc7\x52\x53\xcb\xa9\xbb\xb9\xc4\x0c\x12\xe9\x84\x44\xc8\x16\x66\xa7\xc7\xd3\xf3\x62\x79\x7f\xf7\x5f\xab\xdd\xed\x62\xe3\x54\x8e\x27\xc3\xe3\x04\xc3\xb3\x2d\x54\x95\x98\xa9\xa0\xe9\x24\xa1\x98\x72\xcd\xea\xc5\xbb\xc8\xf2\xd6\x21\x9b\x10\x57\xf9\x81\x46\x23\xe4\x1d\xb7\xbb\x85\x52\x50\xb7\x9b\xda\x06\xaa\x1e\xf8\xaa\x53\x4a\xad\xec\x87\x30\xf0\x20\x9a\xb7\x85\x3e\xa3\x51\xf3\x23\x55\x84\xe6\xd7\x13\x7a\x9e\x93\xaa\x4e\xf4\x66\x22\x2d\x24\x09\x3b\x94\x00\xa2\xed\x97\x79\x59\x7b\xd3\x30\x7f\x19\xc5\x19\x06\x9d\x1f\xd9\x01\xce\x9a\x23\x27\x43\x13\x81\xfb\x13\x7c\x56\x7d\xa5\x42\x2b\x49\x35\xe9\xdd\x84\x81\x14\x65\xa4\x15\x08\x4c\x40\x3b\xe3\xbc\x99\x91\xc9\x9a\x03\xcf\x68\x4d\x78\x98\x8e\x02\x57\x47\x61\xdd\x1d\x97\x18\xb2\xb9\xf2\xf5\x79\x2f\xb4\xd6\x91\x10\xce\xba\xdc\x5e\x6d\xa7\x07\x15\xc1\xbc\xa8\x97\x4c\xbe\xd0\x61\xe5\x46\x43\x1a\x61\x8a\xc2\x86\xa9\x5e\xe9\xac\xdd\x01\x91\x47\xfa\x50\x66\x33\x4f\xe5\xff\x1d\x9f\xc9\xa4\xa4\x17\x73\x9f\xbe\x6d\x37\xc8\x44\x01\xe6\xc6\x6f\xef\xae\xbb\x77\x6c\x92\x18\x83\xdd\x37\x28\x1a\x91\xd5\x65\x5e\x76\x47\x54\x84\x59\xe7\x4d\xa7\x16\xdb\x1d\x90\x08\x0f\xdc\xa1\xb0\x43\xf6\xef\xa3\x2d\x9f\x07\x93\xc9\x6d\xda\xeb\x39\x87\x7d\x97\x71\xba\x13\xd8\xa2\x6e\x8f\x42\x18\x31\x63\x1d\x0d\xcb\x27\x52\xfe\xca\x66\xc8\x1c\x47\x67\x84\x90\xea\xd8\xc5\x3f\xf7\x5d\x85\x08\x93\x60\x75\xeb\x79\xdd\xda\x8a\x70\x77\x05\xc3\x3d\x81\x36\x82\x0a\xca\xea\x01\x1a\xa1\x45\x23\x9e\xcc\xb7\xac\x6e\xca\x2a\x53\x22\xf7\x7f\x9b\xa3\x72\x8b\x80\x04\x96\x6f\xa4\xf5\x57\x9e\xe1\x70\x6c\xc6\x30\xb3\x33\x9c\x2c\x90\xc0\xa6\xfe\x7d\xac\xf8\x52\xac\x45\x86\xcc\x69\x53\x46\xba\xc9\x85\x52\xcb\x12\x56\x7e\x14\x9e\x16\xf9\x4e\x9f\xa3\x1d\x81\xa4\xd6\x73\xfe\x71\x77\xb5\xda\xae\xa1\x1a\xd6\x09\x80\xc8\x50\xc3\x08\xf7\xb0\xa8\x64\xd6\x4c\x08\xe2\x22\x20\x0a\x7c\x53\xa6\x4b\xc0\x15\x7a\xc4\x6c\x16\x41\x14\x12\xea\xd6\x3b\x8a\xb9\x75\x7f\x17\x76\x27\xf7\xee\xc0\xaa\x79\x5b\x97\xe5\x85\x7a\x2a\xd0\x84\xe3\xdd\x1e\x1a\xb5\x93\x73\xb9\x65\xa0\x2a\x50\x9e\x16\x15\x71\xc5\xd9\xdf\x13\x4e\xfb\x08\x38\x8f\x65\xd4\xeb\x1c\xa2\x68\xfd\xfc\xf5\x78\xcc\xc3\xc0\x43\x24\x6c\xc2\xd6\x1d\x89\x03\x1e\x3a\xef\x61\x2d\xb2\xc2\xca\x2b\x2e\x1a\x8b\x1a\x1e\x9f\x24\xe6\x2a\x18\x30\x26\x76\x67\x48\x62\x34\x87\x37\x77\xdb\xa1\x75\x82\x24\x0a\x71\x51\x3d\xc2\x87\x6d\xed\xab\xca\xfd\x84\xf8\xe6\xc2\x74\x4e\x78\x80\x76\xed\x7a\x75\xb3\x78\xb9\xdf\x0e\x79\x7d\x20\x91\xdc\x6a\x01\x43\x53\x1d\xf7\xaa\xcc\x0a\xa7\xc2\xe0\x8e\x8b\x30\x8a\x79\xe7\x3f\x39\x72\x8b\x2e\x64\x6e\xaf\xc3\xa9\x1f\x4a\x2d\xf4\xc0\x61\xc6\xc3\x91\xc0\xf4\xa4\xb7\x0a\x24\xef\x1b\xf8\xb7\xdf\x76\xeb\xe7\x15\x0a\xc5\x6f\x7f\xfa\xf6\x7d\x90\x32\x90\x51\x47\xf2\x54\x67\x1a\xaa\x11\xe1\xb9\x1f\x06\x02\xb3\xe7\xa8\x04\x51\x16\x4a\x34\x0f\xb0\x2f\xab\x13\x45\x02\x4d\x7f\x32\x15\xda\xc0\x1f\xe5\xe6\x26\x26\x19\x14\xe3\x68\x73\x5a\x47\x6b\x08\xad\xf9\xcd\xff\x8e\xef\x43\x49\x0b\x01\xb8\xde\xac\x5f\xba\x2e\xc9\x69\x28\x0d\x46\x59\xb1\x5c\xbf\x6c\x2d\xbc\x7a\x20\xfa\x1e\x99\x90\x52\x84\x63\x3d\xdd\xdc\x6c\x56\xdb\x30\x8d\x83\x20\x0c\xc2\xee\xa8\xd4\x5d\x7f\x5c\x79\xec\xb3\x4d\x26\x04\x40\x88\xe3\x73\x1b\x72\x57\x88\x24\xb0\x89\x87\xf1\xfb\x32\x84\xc4\x5e\xaf\x76\xc8\xcc\x70\x01\x2a\xe7\x7f\x24\x92\x30\xf2\x5b\x74\xbd\x68\x7c\x82\x66\x72\x6a\x4d\x70\xe6\x6e\xfe\x6b\xf1\xfb\x9a\x94\x89\x42\x89\xbc\x06\x0d\x88\xfd\x6c\x32\xd9\x44\x5c\x63\xcd\x62\x5d\x95\xcf\xa2\x11\x23\xc8\xa6\x1f\xa2\xb5\x25\xa6\x40\x3d\x9c\x7e\x45\x8f\x95\x68\xfe\x7f\xfa\x4f\x37\xd7\x0d\x25\x14\x21\x7c\xef\xed\x4d\x9e\xd6\x55\x59\x9a\xdf\xde\xe7\xff\x07\x97\xef\xd8\x59\x0c\xd5\x56\x4b\xe3\x71\xf1\xe0\x17\xbe\x61\x22\xb4\x34\x11\x36\xaf\xbc\x15\xbf\xa0\x7c\x1f\x74\x7a\x8c\x3f\x05\x53\x01\x86\x94\xb9\x38\x16\xea\x6d\x2a\xdc\xd6\x1e\x0f\xd1\x83\x2a\xe0\xb3\x73\x71\x0c\xe7\x92\xda\x75\xf5\xf1\x9f\x47\xa8\xf1\xbb\x0d\x8d\x58\x1b\x4c\x61\xb9\xe2\x80\xcc\xba\xa3\x4e\x5d\x13\x07\xe0\x34\x37\xab\xe6\xb4\x13\xdd\x9f\x55\x8a\xad\x65\xb6\xe4\xed\x85\x1b\xfb\x44\xa1\x89\x81\xf0\x5e\x5e\xfb\xc1\x6d\xc1\x75\x7d\xec\xf6\x68\x93\x80\x50\xd0\xed\xf3\x98\xb2\x1d\x3f\x6d\x9a\x86\xa2\xf3\x82\xd7\x65\xe3\xb1\xfe\x46\x28\x70\x72\xa6\x0d\xee\x81\x96\xc4\xf2\x5c\xd3\x28\x32\x02\x0c\xda\xd9\x87\x4c\x55\xe5\x55\xd6\x0c\x82\x7e\x23\x59\xea\x1b\x4b\x90\x7a\x01\x73\x43\xdd\xc1\xc4\x84\x3e\xe5\x83\x4c\x7b\xeb\xa7\xfb\xbf\xba\x83\x52\x58\xa6\x39\x97\xab\x9f\x69\x35\x36\x2a\xb4\x94\x45\x36\x04\x77\x58\x8c\x8e\x4b\x3e\x32\x2a\x22\xca\x35\x9d\xff\xbc\x1f\xb4\x61\x19\x95\x84\x4a\x0e\xe1\x2d\x3f\x32\x71\x25\xd4\xaf\x8b\x61\x8a\x51\x82\x63\x8a\xe6\xbe\x7c\x1d\x56\xd5\xbe\x4c\xda\x19\x25\xac\x2a\x61\x5d\xe6\xda\xd6\xf3\xfd\x01\x93\x4a\x27\xf6\xe5\xd0\xf3\xae\xed\xe4\xc9\x0c\xc1\x33\x46\x73\x8d\x59\x77\x64\xef\xc9\x1c\x9f\x19\x9d\x5c\x45\x1b\x00\xdb\x9a\xd2\x75\xac\x1a\x08\x34\xe2\xe2\x8f\x35\x54\xcb\x0a\xd1\xb4\x67\x11\x90\x81\x38\xc0\xb7\xe0\x6b\xc8\xbd\xa3\x67\x4c\x00\xd8\x20\x97\xb5\xb3\x09\xab\x90\x53\xd1\xcc\xb9\xed\xce\x3a\x6f\xe3\x8b\xb4\x9b\x1f\x1b\x38\x46\x33\xea\x36\x91\x31\x94\x20\x81\x48\x7b\x17\xf9\x52\x54\xda\x86\x61\x8e\xd5\xb6\x53\x20\xf5\xa3\x85\x42\x67\xb9\x71\xb7\x4b\x83\x80\xa5\x1d\x63\xf1\x57\x1c\x30\x34\x08\x52\x40\xa7\x7e\xbb\xda\x6c\x77\x0f\x4f\xd7\xab\xee\x14\xd2\x02\xc0\xd0\x2f\x80\x42\x6f\xc4\x7e\x0c\x61\xed\x7b\xa6\x47\xef\x9f\x06\xa1\x26\x78\x71\xab\xb9\x76\x39\x61\x4d\x83\x10\x58\xc2\x06\x9e\xde\xee\x50\x65\xef\xa2\x71\x5c\x75\x7e\x61\xd3\x20\xe2\x32\x54\xbe\x04\x8b\x4b\x0e\xc1\xb6\xfe\x68\x1a\x60\xa7\x15\x5a\xa8\x65\xb9\x3f\x40\x83\xe0\x40\xcb\x7f\x79\xec\xd1\x96\xed\x50\x41\xfa\x7e\xdd\xc7\xb2\x78\x86\x03\x88\xa6\xdd\x07\x7e\x1c\x8c\x77\xa9\xdc\x27\xbc\xa4\xa7\x3c\xda\xe2\x69\x40\x0d\x41\xeb\xbb\x6f\x97\x7b\x0f\x82\xa3\x01\xa3\x14\xd3\xeb\x45\xd9\x64\xe6\x64\x33\x72\x1b\x70\xf9\xe0\x6e\x10\xb3\xa2\x2c\x8e\xf5\x40\x9d\x09\x37\xe1\x14\x1a\xbc\x0b\xce\x13\xc4\x0f\xb6\x4e\xcf\x35\x78\x6f\xc3\xa1\x95\xfc\x59\x63\x2d\xf1\xab\xde\x7e\xfb\xde\xfd\x09\x00\xdb\x48\xdd\x53\x6d\xcb\x45\x7e\x78\x13\x12\x1a\x47\x0f\x33\xb4\xfa\x34\x48\xa2\x04\x4b\xeb\x55\xf6\xfa\xd6\x50\xfa\xc7\xf8\xbb\x25\x3c\xc1\xb9\xe1\x0d\x88\x2f\xd7\xcd\x19\x10\x1a\xa4\x51\x1c\x26\x7e\xed\x8c\x61\x2b\xe3\xd3\xa6\x54\x04\x7a\x24\x3c\x08\x70\x53\x56\x3e\xaa\xf9\x0a\xc8\x41\x83\x14\x24\x96\xfd\xde\x44\xed\xcb\x66\x63\x0f\x8c\x06\x82\x26\x08\x46\xd5\x20\x9a\xb7\x6b\xd1\x88\xdd\x7b\xe4\x5f\x8f\x48\x53\xa1\xbc\x36\x6e\x0d\x55\xe3\x19\x84\x1f\x8f\x7b\x97\x4f\x9f\x80\x8b\xc6\xf7\x2e\x80\xa2\x2f\xba\x6b\xff\xbc\x2d\xad\x07\x3a\x1e\x22\x55\xc4\x88\xcf\x6a\x5b\x2e\xc2\x63\xdd\xcd\x16\x15\x08\x7c\xa7\x2f\x9b\xeb\x5b\xb1\x97\x39\xd6\x8f\xba\x18\x80\x06\x8a\x11\x2c\x76\x1e\x07\x04\xe4\xbf\x27\x78\xa6\x81\x4a\x84\x76\xdc\xd0\xb7\x50\x40\x9d\xd5\x4b\x61\xd9\x97\xba\x33\xeb\x08\xab\xbb\xfb\xac\x18\x52\xaa\xde\x15\x3f\x21\xeb\xc6\x80\xed\x80\x73\xa4\x98\x1a\x8a\x26\x6b\x4e\x77\x7b\xf1\x0a\x2f\xcf\xf7\xb3\xb9\x00\x1a\xe8\x88\x60\xf0\xb1\xcf\x8a\xb1\xd8\xbf\x3b\x0e\x81\x4c\x3d\x25\xc9\x6d\x29\xf2\x67\x10\xaa\x4b\x4e\xd3\x00\xb4\xed\xde\x77\xe4\xf8\x43\xdd\xc3\x09\x91\xa5\xfb\x81\x09\x63\x64\x7e\x3f\x54\x60\xb2\x4f\xd0\x67\x55\x40\x1a\x18\xa9\x89\x74\x2d\x70\x28\x86\x37\xde\x79\x69\x18\x50\x42\x2d\x94\xf1\xa1\x2c\xe0\xb4\xe9\x1c\x1d\x1a\x06\x69\x80\xb6\xfb\x87\x28\xb2\xe6\xe4\x27\xfd\x0c\xc3\xf1\xf0\xa6\xc2\x40\xc4\x86\xf8\xa8\xb0\x8b\x8a\x1c\x4d\xc5\xf4\xe2\xc6\xaa\x21\x5a\xf3\x73\x03\x30\xdb\x7c\x49\x43\xa2\xb8\x6f\x3e\x78\x3e\xe6\x9d\x6e\x9e\x3f\x6a\x12\xac\xf7\x5b\x9f\x73\x46\x0c\x6c\x34\x41\x42\x62\x94\xa7\x91\xcb\x0a\xc0\x36\xa3\x91\x0d\xeb\xff\xd7\xed\x85\xb3\xff\xe7\xbf\xd9\xff\xcc\xfd\x97\xbb\x46\x44\x28\xb3\x55\xfe\x76\x97\xc2\x56\xcb\xf2\x82\x6b\x41\xc3\x88\xc6\x68\xbf\x5b\x5b\x5d\x2f\x45\xd1\x6d\x2f\xfe\x38\x27\xd8\x2d\xf7\xb0\xf8\x73\x67\x49\xe0\x90\x66\xa6\x3f\x9c\x70\xe2\x49\xc6\xac\x28\xd0\xf8\xfd\x50\xca\x11\xcb\xfb\xfc\x9d\x06\xff\xe5\x7f\x45\x65\x80\x7b\xcf\xe6\x65\x08\x4b\x6e\xff\x1e\xc5\x69\x4f\xd3\x31\xc5\xd0\xd2\x90\x42\x80\x5e\xe9\x75\xb6\x17\x3d\x2a\x8d\x86\x2c\x89\xb0\x0e\x5a\x1c\xf7\x1e\x03\x30\x6d\x15\xa0\x21\x4b\x39\x73\xcc\xe3\x59\x9e\x63\xd3\xd3\x26\x7b\x6d\x3d\x57\xcc\x78\xf8\x51\xc2\x32\x5e\x66\x45\xd6\xfc\xcc\x9a\xb7\xcd\x5b\x76\xa8\xbb\x83\x32\x01\x27\x37\xb6\x5c\x7e\xdb\x81\xce\x9a\x5d\x14\xfa\xa3\x5c\x12\xee\x10\xbe\xd5\xe2\xcc\x67\xe9\x06\xd1\xc4\x9b\x57\x65\x85\xc3\xa7\xbd\x96\x34\x8c\x23\x16\x5b\x1e\x20\xc4\xa9\x0e\x69\x47\x68\x98\x86\x1c\x45\x8a\x2c\x75\x86\x38\x1c\x40\x4f\xf0\x71\x34\x4c\x29\x41\xaa\x54\x1f\xff\x2e\x8f\x48\x55\x7e\x46\x58\x41\xc3\xd4\xd8\xda\x5a\x27\xbc\x61\xe9\xcc\x67\xf7\xb7\x50\xa4\xd4\x8b\x9a\x6f\x9a\xf2\x30\xdb\x9c\x44\x43\x19\x25\x8e\xb7\xad\x59\xe3\xee\xb0\xbe\xc8\xb8\x40\x43\x99\x2a\x2c\x79\x1d\x0b\x47\xeb\x3c\x87\x39\xa0\xa1\x0e\x18\x76\x42\x9a\xec\x73\xea\x63\x8d\xcf\xa7\x45\x84\xe5\x7b\x53\xee\xcb\xc8\x6f\x6f\xa1\x06\xcb\xbb\xda\xee\x7e\x0b\xd9\xbd\x4a\xe0\x21\xbe\xa6\xbd\xe5\xab\x1d\xd1\xe9\xd0\x10\x62\xcd\x7a\x2b\xb0\x7a\x5e\x86\x9c\x2d\xdb\x5d\x73\xbc\x05\x53\x37\xdc\x04\xb6\x24\x7b\x0b\x55\xfd\x36\x9a\xd7\x46\x77\x81\xc8\x54\x7e\x04\x53\x82\x7e\x98\x09\x81\xd9\x66\x62\x17\x4f\x5d\x8b\x93\xbf\x57\x12\x84\x21\xa6\x2e\x6b\x51\x6c\x4b\x4c\x97\x8e\x56\x1a\x09\x08\x0b\x3c\x98\xa4\x5d\x00\x9b\x32\x1f\x27\x0e\xda\x21\xb6\xc9\xa2\xdd\x90\x17\xba\x44\x60\x2a\x0a\x4e\x6c\x3d\xe0\xdb\x4e\x5a\x36\x6f\xf6\x49\x40\xc1\x0b\x95\xfe\xe7\xb1\xaf\x6b\x53\x42\x42\x2a\x49\x27\x64\xe1\x6a\x5a\x0e\x5b\xaa\x4e\x93\xbb\x20\xd2\x8a\x67\xda\x26\x94\xb1\x90\x83\x1b\x12\x39\x62\x75\xa1\xb5\xe5\xa6\x1a\x26\x68\xfd\x98\x44\x47\x03\xcc\x81\xfb\x76\x2f\x23\xe5\x2e\x37\x94\x32\xab\x6f\x34\x48\x16\x3e\x55\xd9\x6b\x56\x88\x7c\x72\x6f\xd4\x08\x74\xc5\x1e\xd7\x7f\x6e\x86\x9f\x90\xb0\x28\xc2\x68\xae\x39\x4a\x64\x35\x7e\x19\x48\xde\x50\xc2\xa8\xb1\x1c\x7c\x48\xcc\xe0\xf1\x83\x85\x05\x02\x76\x83\xa4\xe5\xea\xd4\xb6\xd7\x0d\x91\x3e\x97\xca\x28\xe3\x49\x4d\xb8\x63\x8c\x6f\x9d\xb5\x9b\x4c\x4e\x6e\x9a\x27\x1a\xfb\x3c\x50\x94\x17\xee\x9a\xff\xbc\xac\xc9\x7b\xe9\xfc\xca\x6a\x07\x23\xe3\xf4\xfa\x7e\x31\xd2\xd0\x74\x77\xe5\x3d\x0d\x12\x33\x4b\x02\xf7\xe7\xf6\xaf\x1b\xff\x6c\x31\x67\x51\xc7\x64\xe0\x1a\x91\x8f\xfb\xee\xa8\x62\x3a\xf5\xfd\x2d\x53\xc7\xb5\x27\x84\x9a\x24\x74\x28\x89\x01\x30\x79\x79\x53\x1d\xcb\x36\x84\xbd\x5a\x6d\x17\xfe\x9c\x49\x10\x61\x85\x7b\x9f\x15\x80\x5c\xd0\xea\x9f\x30\xa6\x52\x92\xb0\x10\x5d\xd7\xa5\x45\xed\x5f\x20\x06\xa3\x24\x49\x74\x18\x77\xb3\xf4\xa6\xac\x1c\x18\x78\xa0\x9a\x42\x49\x9a\x50\xdc\x8a\x0b\xf8\xe8\xb7\xe0\x4b\xa1\xcc\xfc\xab\x17\x82\x62\x17\x20\xb2\x9f\x21\x3b\xdd\xc4\x18\x10\xa1\x92\x20\x1a\x34\xc2\x2d\x8c\xc9\xf2\x6c\x2a\x82\x4a\x89\xd0\x56\x21\xfb\xb1\xdc\x1f\x2b\x71\x7d\x2a\xc4\x3e\x53\x75\x9f\x10\xa1\x44\x06\x3a\xb1\x94\xa5\x08\xa2\xa8\x07\x76\x8f\x48\x2e\x8d\xc3\x93\xb9\x6c\xcf\x99\x54\xda\x60\xf1\x29\x19\x62\xda\x65\xa8\x5c\x7b\x33\x40\xb4\xfe\x53\x81\x38\x77\x3a\xcd\x23\x44\x4d\x6d\xa0\x39\x7a\x16\xd8\xec\x1f\xd0\x86\xff\xee\xb4\x2a\x08\x6c\x65\xff\xe3\xfb\x51\x7b\x6e\xda\x8b\x62\xe3\xc9\x64\xbb\xd3\x0a\x92\xa0\x13\xab\x77\xf9\x80\x72\x62\xed\x08\x84\x1c\xdb\xaf\xbc\x43\x71\x81\x44\x89\x12\x88\x38\xc2\xc6\xeb\xd6\xef\x3e\xe6\x30\x50\xeb\x1a\x6f\x03\xe3\x9a\xbc\x77\xf1\x06\x27\x12\x14\x5d\xf9\x87\xea\x26\x93\x15\x8c\xf6\x29\x50\xa1\xb4\x4e\x0e\xce\x56\x07\x93\x99\xfc\x5e\x69\xa6\xbc\x74\x5d\x1b\x09\x98\x0b\x6b\x00\x4c\x8c\xf3\xe5\x50\x36\x9b\x8f\x09\x99\x13\x25\x26\x24\xdc\x61\x2b\xaa\xac\x39\x59\xc0\x6f\x77\x0c\x1c\x51\x52\xf5\x0b\x9a\xb0\xfb\x73\x64\x3a\xcc\xc7\xe2\xc9\xd6\x6b\xd5\xa9\xeb\xd0\xbf\x84\xf3\x18\xbd\xf0\x28\xe4\x0a\xd3\x9d\x56\x75\x6e\x12\xba\x45\x84\x51\xdf\x36\xea\xaa\x84\x63\xab\x1e\x11\xa5\x25\x32\x70\x67\x50\xed\x9e\x45\x56\xb4\xd6\xb0\xea\x8e\x02\x47\x8a\x8d\xfa\x23\x6b\xd4\xdb\xb6\x7c\x84\xcf\x91\x40\x30\x8d\xa2\x30\x25\x7d\x57\xeb\x23\x7c\x74\x07\x44\x20\x53\xaf\x38\xae\xca\x4a\x5f\x9d\xd6\x55\xf9\x9e\xe9\xbe\x5e\x37\xdf\x19\xea\x7f\xaf\x19\xce\x0f\x8f\xbf\x7a\xa9\xcf\x41\xb9\x7e\xa8\xb1\xbd\x86\x2e\x27\xb0\x28\x7a\x36\xc9\x23\x52\x85\xda\x27\xf7\x77\x46\x43\x21\x3d\x71\xef\xc5\x9a\x25\x8d\x68\x64\xf5\xb3\xcb\x51\x68\xfa\xbb\x25\xed\x7e\xcc\x78\xea\xcb\x48\x4e\xdc\xb0\xac\xae\xa1\x56\x55\x76\x38\x13\x26\xa4\x11\x67\x4c\xd9\xae\xae\xff\x45\xa4\x32\xe6\x10\x86\x21\x7a\xc4\xb9\x40\xee\x0d\xe7\x2e\x4d\x2a\x17\x17\x37\x80\x7e\x8f\x8a\x5a\xb3\xe8\x28\x08\x6d\xe7\xc4\xd7\x4d\xd2\xd3\xdc\xe2\xfc\xff\x75\xe7\x8e\x43\x4e\x65\x97\x76\x43\x9d\x4a\xbb\xd2\x66\xc4\x1e\x68\x14\xc7\x04\x65\x18\x9b\xb7\xac\xd2\x7f\x3e\xdb\xaa\x0e\xd6\xb9\xfd\xd3\xc6\x29\xf7\x28\x46\x2b\x1c\xb8\xc9\x5e\x8b\x7e\x56\xc6\x42\x3a\xda\xc5\xa6\x6b\x4f\xad\x6f\x60\x14\xa8\x46\x31\x04\x1d\x26\xcc\x8a\x6f\xf7\x5a\xe0\x34\x4a\x42\xad\x5d\xf5\xbf\xc8\xe1\x34\x5a\x33\x89\x26\xb8\x4f\xfe\x78\xda\xde\x3d\xde\xee\xbc\xd6\xb8\x3f\x9c\x86\x54\x7b\xe6\x97\xb2\x6c\x56\xfa\xb5\xfb\x4a\x69\x6a\x43\x1e\x4b\xa6\xd2\x7f\xbd\x54\x47\x88\x06\xb0\x8f\xfa\x64\x6c\xe4\x3c\x9f\xdc\x73\x3f\x91\x04\x30\x77\xb2\x85\xba\xe1\xfe\x3c\x92\x01\xae\x75\x79\x3c\xfd\x04\x71\x98\x54\x25\x69\x24\x63\x65\xa9\x23\x45\xb5\x15\x9f\xd9\xe8\xa9\x64\x4a\x84\x85\x14\x7a\x1d\x95\xbb\xa2\x0d\xf0\xb3\x77\x58\x1e\x9b\x7e\x14\x25\x16\x6e\x9f\xbd\xbe\x62\xa1\xf0\x3f\x84\xfa\x75\x28\x9b\x01\xa1\x0b\x8d\x24\x30\xf4\x1a\x90\x48\x15\x06\x91\x56\xa4\x68\x8a\xe9\x81\xfd\x31\x0f\xf9\x1f\xb6\x05\xb1\xc7\xdd\xd2\x48\x31\x8a\x3e\xf7\xa0\xbf\x27\xfa\x26\xea\xb7\x9d\x7b\x90\xee\x3c\x3c\x08\xc8\xb0\x86\x7f\x75\xea\x74\xaa\xbc\xeb\x15\x29\x09\xa1\xdb\xb9\xb7\xed\x5c\x5a\x8b\xaa\x39\x39\x48\x4a\x59\x5d\x5b\x06\xfa\x61\x36\x37\xd2\xa1\x6d\x14\x19\x67\x44\xa0\xbe\xf2\xd7\xd5\x31\xc7\x45\x9f\xd5\xb8\x6c\xbf\x08\xd5\x22\x9d\x70\xd6\x29\xe7\x8a\xfa\xec\x63\x68\x65\xf9\x30\x4f\x50\x5f\x1d\x4f\x17\xd8\xcc\x68\x04\x01\xd5\x49\x57\xea\xee\xbc\x8c\x51\x3a\x2b\x82\x40\x61\xee\xa8\xf5\x78\x73\xcc\x4f\x8e\xba\x9f\xfc\x28\xc1\xb0\xa1\x6c\x40\x7a\xfd\xb5\xed\x30\xa0\xa4\x7b\x81\xed\xa2\x6d\xa7\x85\xbd\xb0\xff\x5e\x34\xe0\x52\x69\x4f\x23\xd1\x67\x90\x67\x1f\x85\x06\x49\x88\x78\x08\x6c\x8a\xc2\xa8\xcb\x9b\x3a\x1a\x88\xd0\xeb\x67\x7f\x87\xd3\x00\x2b\x49\x69\x20\x2d\x1b\x69\x1b\x1f\x97\x55\x63\xca\x3c\x2b\xe7\x6a\x4c\x94\x06\x5a\xdb\x48\x3a\x7b\x75\xa8\xd9\x39\x2e\x7a\x4a\x43\x6e\xd9\x3e\x6c\x5c\xae\x7e\xe1\x3d\x63\xcd\x69\x4e\xec\x62\xf2\x10\xa1\x8a\x70\xe6\x75\xf5\xa0\x51\x93\x2d\xa5\x84\x86\x48\x79\x51\x1f\xf7\xbe\x33\xbf\x3b\xc4\x2c\x37\x69\x3b\xb9\x3d\x0b\x58\xbd\xae\x4a\x93\x35\x9b\xce\xfd\xa7\x44\x26\xc4\x6e\xf6\xf5\x41\x7c\x14\x3d\xf4\x88\x52\xa2\x13\x12\x74\xe9\xb3\xd5\x67\x53\x09\x64\x6d\xfb\x0a\xbc\x46\x69\x14\x44\x98\x9e\x05\xa1\xde\xd6\x2f\x9b\xed\x61\xf8\x76\xa3\x24\x42\xd0\xa2\xeb\x3d\x80\xa6\x75\x11\xce\xf7\x9e\xd1\x74\xa3\x51\x9a\xd8\xe6\xfd\x0f\x80\xc3\x4b\xd1\x75\x83\x7a\x08\x57\xf7\x32\xa2\x54\x2b\xd6\x89\x9e\x59\xcf\xc0\xc1\xa5\xc7\xf7\x48\x99\x55\xd4\xea\x38\xd7\xbe\xc2\x0b\x51\x4a\x63\xe6\xcb\x91\x0f\xad\x3f\x72\x05\xcd\x95\xa8\x33\x85\x1f\x71\x36\x1a\xa7\x54\x00\x92\x4c\x5b\x1e\xd4\x31\x87\x2a\xa5\xd4\x30\x5c\xd7\xd5\x71\xb2\x4c\x29\x8b\xac\xf4\xbf\x23\x2c\xba\xdd\x2e\xce\x06\x08\x4c\xed\xda\xfe\xa2\x76\x25\xd7\x0f\xe2\x70\xe8\x20\xac\xed\x08\xc0\x4e\x39\x14\xf7\xed\xd8\x2f\x29\x65\x5a\x61\xea\xd1\x06\x4d\xb6\x85\x0e\x05\x9c\x2f\x40\x66\x29\x65\x26\x0a\x74\xe7\x63\x0f\xa1\x07\x8b\x42\xdb\x72\x5d\xdf\xce\xd1\xfb\xc5\xe1\xb9\x5b\x4c\x39\x25\x56\x1c\x01\xfb\xfc\x8b\xac\xb9\xc9\x3e\x27\x4f\x16\x07\x09\xf2\x10\x42\x81\x9b\xfd\xd0\x5c\xd0\x98\x06\x18\xcb\xed\xac\x58\xd6\x3b\x38\x41\xff\xf9\xfb\x8e\x8d\xc1\x45\x71\xfd\xa7\x7f\xf1\xdd\x14\x49\x88\x25\xff\xee\xd0\x74\x05\xd4\x75\x0f\x4c\xea\xe6\x5c\x22\x0c\x9a\x55\xe7\x9f\x5e\x50\x8d\xf7\x83\x8d\xc5\x69\x3d\x1d\x9b\xa9\x60\x14\xa5\xa9\xe0\x9e\xdc\xf7\x7a\xb3\xb5\x9e\xc8\xfd\xc3\xe3\xd3\x64\x37\x11\x41\x80\x35\x32\xe1\x62\x86\x7a\xd3\xf5\xc8\x50\x2a\x43\x8b\x98\x69\x27\xe0\xe9\xba\x3a\xbe\x76\xcf\x23\x69\x8c\xfc\x17\x58\x1c\x1e\x36\xcd\x51\x2a\xb9\x8c\xa9\x77\x2c\xf3\xb2\x9a\x03\x02\x53\xaa\x8c\x41\xe2\x9d\xe5\xe9\xd0\xde\xcd\x53\xf5\x2a\x8a\xec\xef\x41\x6d\x61\xf2\xac\x3a\x00\x74\x25\x1f\x16\xdf\xff\xe3\x7e\xe5\x2d\x15\xd5\xc2\xc2\xb0\x1f\x33\xff\xe9\x3a\x11\x12\x4a\xb5\x0e\x30\x7c\xcd\x54\xd9\xe3\xa2\x29\xd5\x40\xc1\xe6\xdb\x5b\x77\xbd\x86\x4d\x03\x87\x75\xff\xe2\x20\x48\x31\x4c\xf9\x40\x62\xe5\x9d\x3c\x56\xbd\xbb\xdb\x1b\x51\x0a\x42\xc7\x91\xc5\xd7\xe6\x27\x53\x56\x4b\xb0\xcd\x94\x62\x00\xb5\xf8\xd7\xef\xff\xf1\x67\xd3\x22\x52\x3e\xe2\xef\xd4\x1c\xa6\x8e\xed\xf8\xd3\x19\x1a\x60\x9a\xde\xe6\xec\xda\xb8\xfd\x01\xa5\x7d\xea\x17\xec\x8d\xea\xfb\x39\xda\x6d\x47\x79\x36\xd5\xd5\xe7\xa1\xac\xda\x75\x35\x3f\xa9\x58\xc0\x39\x26\x1c\x37\x59\xf1\x7a\xcc\x31\x8a\xdb\x42\x4d\x98\x3f\x55\xc8\x25\x96\x48\x36\x85\x38\xd4\x6f\x65\xb3\x15\xfd\x7a\x61\x21\x37\x16\x3b\x6d\x51\xb7\xed\xae\x3e\xa4\xff\xa1\x8c\x04\x02\xa0\x6f\x47\x9c\x40\xd3\x28\x23\x51\x00\x2e\x13\xbe\xb3\x0d\xf3\xbb\x7a\x40\xe5\xe2\x46\x45\x81\xa4\xbe\x67\xd4\x26\xdd\xd6\x55\xf9\x3a\xb0\x4f\x2c\xa2\x60\x7a\x16\xc8\xac\x78\xb5\x73\x74\xd7\x1d\x97\x1c\xb3\x96\x1f\xc7\xd7\xe3\x20\x1f\xc7\x28\x4f\x2c\xe4\xae\x2c\xa7\xc5\x21\x46\xa5\x65\x84\xc3\x6f\xe4\x8a\xb6\xc3\x8f\xc8\xa8\x62\x5a\xf5\xbd\x69\x0d\xf8\x29\xc7\x18\x8f\x90\x18\xeb\xc5\xd9\x9f\x3c\x5f\xbc\x42\x31\x15\x28\x18\x5f\x8e\x47\x80\x29\x1e\x0b\x84\xb1\x4c\x35\x7e\x66\x74\xf2\x2f\x94\xc5\x8c\xd8\x9a\x1b\x1c\x6e\x44\xb5\xef\xfe\xac\x88\x45\xab\xe4\x19\x14\xcd\x06\x3a\xfb\xdc\x1e\xd1\xc3\xe9\xdf\x09\x15\x5f\x98\x10\x31\x84\xd8\xc0\xe0\xd1\xce\x16\x7c\x31\x19\x63\x08\x36\xbe\x21\x27\x61\x93\x35\xa2\xc8\x8e\xfb\xdd\x3e\x2b\xc4\xb0\xde\xc8\x12\x66\x09\x3e\x6a\x68\xfe\x7e\xb1\x27\x18\xc9\x83\xfe\x37\xf9\x9f\x91\xff\xcf\x12\x88\xa8\xf1\x4c\xdd\x1f\x7e\x8b\x9b\xf5\x8b\x58\x2a\x80\x0c\x3a\x5d\xdb\x97\x3c\x98\xe5\x6e\x90\x88\xad\x08\x16\x7c\x82\x3a\x36\x2e\x33\xdc\xc5\xc9\x80\xdd\x20\x3e\x59\x39\x79\x46\x19\xc6\x29\xeb\xb4\x9d\x51\x78\xc3\x91\xdf\x55\xb6\x0d\x51\x54\xa7\x1f\x1e\x29\x43\x99\x8a\xd3\xc8\x22\x4c\x5b\x07\xc8\x45\x65\xff\x1d\xc6\xfc\x7f\x86\x65\x3d\x3f\x58\x4a\xcb\xa8\x0b\x85\x76\xdd\x4c\xf5\x17\xe4\xb9\x94\x29\x9d\x32\x4b\x7a\x54\x5c\xd4\xe7\x1d\xff\x42\x27\x36\xde\xc4\x48\xb0\x52\x6f\xd9\x80\x0c\x73\x66\x47\x62\x10\x86\x48\xa3\x82\xdd\x51\x0f\xa2\x51\x6f\x57\xc7\xdf\xb2\x76\x4e\xae\x09\xa1\xf0\x8a\xe3\x8e\xd3\xfd\x58\x34\x53\xb9\x56\xca\x20\x56\xd2\x65\xf6\x57\x45\xd3\xe3\x3f\xbe\xfa\x67\xfc\x59\x01\x22\xd4\x41\x68\x7d\xf7\x27\xe3\xab\xe3\xfe\x53\x18\x12\xa0\xf2\x8b\x12\x79\x33\xb0\xee\xcc\x50\x89\x61\xda\xaf\xac\x69\x4e\x68\x8c\xb7\xa5\x05\x14\x8f\xef\xcf\x30\x9e\xb8\x46\x1a\x3c\xbc\x12\x55\x81\xfe\xa3\x3f\x1e\x5b\x46\xb7\xac\x70\x2b\xca\xb5\x5c\xac\x2b\xc0\x90\x5d\x4f\x89\xb5\x7f\x93\xb0\xb0\xa7\xe5\x01\x1d\x92\x03\x5d\x1d\x4f\x7d\x3d\xfa\x8f\xc9\x48\x99\x60\x5e\xda\x41\x13\xb0\xb4\xed\x60\x4d\xc3\x53\x27\xdd\x70\x8d\x49\xba\x83\x8d\x5a\xbb\xee\x46\xf7\x3c\x3c\x4c\x38\xe6\x12\xeb\x7f\x1f\xc5\xaf\xee\x8f\x29\x4f\xc8\xa0\x5f\xb6\xdd\x8a\xae\x17\x77\xf3\x7e\x28\x0f\x95\x15\x5c\xfd\xf9\xed\xe9\x7e\xb5\x43\xc5\xa5\xee\x44\x46\x59\x9a\xc4\xd5\xfd\xcd\xf5\x6a\xb3\x7d\x7e\x59\x6e\x77\xd7\xab\xfb\xc5\x5f\x7e\x04\x09\x34\xca\xa7\xa2\x86\x82\x65\x3c\x88\xba\x63\x91\x52\x4e\x8d\xfb\x1b\x54\xe5\x1f\x5f\xc8\x77\x51\x4e\x4c\x62\xfb\x71\xef\x26\xda\xd0\xed\x21\x8b\x56\x41\x1c\x60\x21\xf2\x45\x51\x7f\x4c\x30\xf4\x94\x47\x51\x8c\xe5\xb3\x47\x04\x10\x3d\xfc\x66\x89\xf1\x88\x5b\x78\x4b\xa7\x5d\xd7\xe7\xff\xff\xe1\x97\x9f\xbc\xc5\x48\x58\x62\x95\xd6\x6b\xb4\x0c\x3b\xdf\x44\x7d\x05\xaf\xc7\xee\x31\xa8\xb6\x3d\x5e\x60\x15\x61\xdc\x5f\x59\x2a\x05\xf1\x94\x11\x4b\x5b\x42\x05\xbd\xeb\x9d\x72\xce\x80\x63\xf7\x73\xa7\xd3\xfc\x3d\x53\xbf\x7e\x8c\x00\xda\x93\x7b\x49\x68\x88\x02\x41\xaa\x38\xad\x9a\xb7\x01\xcc\x8a\x27\xa9\xa6\x0e\xd4\x88\x3d\x68\x50\xe8\xa6\xf7\x3d\x78\x9a\x2a\xf4\x09\x90\xba\xd2\x1b\xb0\xce\x7e\xf1\x54\x26\x41\x3a\x51\x9e\x9e\x7c\x86\x14\x98\x70\xb9\x26\x5c\x7f\x77\x0d\xec\xef\xf4\xc4\x3c\x73\x11\x12\xac\x57\x2d\x94\x82\x43\xf3\x5c\x1e\x9b\x01\xaa\xea\xac\x96\xd6\x13\xea\x50\x2e\x92\x14\xbb\xce\x4d\x55\xee\x91\x24\x6f\x34\xc8\xaf\x1a\x91\x72\x2c\x58\x75\xe0\xa8\x67\x78\xcd\x4a\xab\x69\x9a\x7d\x4e\x22\x83\xff\x0e\xf9\x24\x14\xe1\xc2\x80\xef\x4e\x77\x1a\xf1\x5e\x70\xa3\x7b\x50\x19\x01\xa6\x2e\x1a\x27\xb6\x71\x0d\xfb\x63\x55\x89\x57\x18\xeb\xb0\xf8\xd1\x9c\x39\x3d\xc3\x42\x2f\x45\xa1\x4f\x93\x17\xa2\x22\x1e\xb9\x34\xcf\x4f\x94\x48\x18\x60\x7c\x29\x57\x71\x8a\x5b\xa6\xcd\x56\xa2\x3b\x32\xfd\x7d\x62\xd0\x57\xbb\x6b\x86\xf5\x2d\xae\xc3\x10\xbd\x9c\xd7\x9e\x15\x99\x72\x6d\x24\xb5\xed\x90\x75\x99\xbf\xc3\x12\x01\x12\xf6\xd9\xbc\x6f\xc7\xc1\xe8\x11\xf0\xb2\xbe\x29\xab\x76\x8b\xbc\x24\x3b\x46\xb9\x89\x54\xec\x3e\xfc\x7d\xf6\x0e\x0f\xe2\xf3\x0a\xba\x07\x30\x90\x78\x7c\xc7\x90\x95\x86\xc6\x41\x60\xf9\xdc\x7b\x96\xad\x73\x90\x30\x8d\x03\x61\x30\x09\xb6\x7a\xb7\xed\x14\xa3\x67\x8f\x09\x63\xe8\x24\x61\xb3\x2a\xc0\xaf\x36\xde\xf4\x0f\x1b\x93\x94\x23\x16\xcb\x4f\xe6\x9b\xc1\x21\x95\xa0\x92\xc6\x0e\x8d\xfe\x98\x97\xfe\x5f\x83\x4f\x1d\x33\x6a\x3c\xdc\xcd\xa5\xc6\x27\x90\x7e\x1a\x33\xc9\xb4\x5d\x38\xef\xd0\xf9\x15\x31\x37\x91\xb6\xe0\xda\x76\x6e\x64\xc5\xeb\x0d\x40\x5f\x56\x8d\x63\x9e\x32\x67\xab\x6a\xc8\x8d\xae\xca\x43\x73\xd6\x68\x4b\xe3\x84\x59\x7e\x40\x50\x36\xcb\x32\x2a\x50\x9e\x6b\x3a\x8c\x7f\x9c\x06\xcc\x73\x3d\x5c\x95\x85\xee\x6b\x73\xf3\x9f\x31\x16\x52\x5b\xc2\x4a\xa8\x9b\xbb\x7a\x73\xc4\xd6\x46\x73\xec\x1e\x49\x00\xa3\xa4\x6f\xd7\xc3\x98\xd2\x66\x8e\xfa\x11\x71\x68\x06\x23\x4e\x07\x98\xfb\xa6\x32\x14\x5c\x0d\xb4\xc9\xdb\x08\x7c\x44\x6a\x3f\x79\x10\x45\x35\xb7\xe2\xc1\xdd\x96\xed\x0d\x4d\xac\xb8\xb4\x34\xdb\xa5\xb1\x12\x07\x1b\xac\xfe\xcc\x22\x51\x62\x05\x69\x4f\xd6\xd8\x6e\xf8\x3b\x0f\xc4\xf1\xa7\x83\x38\xc4\x3c\xe8\xa2\x28\xca\x07\xd0\xfd\xf7\x84\x38\xc4\xc8\x6f\xb1\x5c\x0e\x0d\x54\x6c\x98\x65\xc6\x5f\xae\x97\xab\xee\x6f\x4a\xc5\xd6\x70\xb7\x1e\x2a\x38\xf5\x5a\x77\xef\xc3\x92\xe1\xe8\xb5\x24\x41\x10\x22\x5e\x6b\xac\xf6\x79\x75\x5a\x6d\xbf\xcd\x9b\xef\x24\x20\x09\xee\xb8\xef\x22\x3f\xc2\x14\x34\x95\x04\xca\x0b\xa2\xa0\xa7\x7d\x03\x30\x79\x1f\x49\x48\x2c\xe3\x4d\x56\x7f\x87\x13\x66\x29\xe7\xbf\x40\x42\x02\x66\x11\xdf\x7b\x31\x10\x49\xa2\x09\x09\x63\xdc\xcc\x3d\x1e\xbe\xfb\x3b\xb3\x7c\x5d\x05\x7c\x36\xeb\x1f\xeb\x2b\xd1\xe4\xa3\xa2\x49\x42\x12\x89\x94\x16\xdb\x2a\x2b\x60\xf9\xd6\xb1\xd9\xd1\x84\xb8\xfd\xdb\xc7\x31\x4e\xe0\x67\x3c\x85\x12\x6a\xa8\x57\x24\xff\x8f\xb2\xf6\xf6\x32\x61\x21\x33\x56\x06\x02\x3b\x9d\xea\x26\x6b\x30\x21\x85\xac\x5d\xa3\x3a\xf1\x20\x47\x90\x30\x6e\xad\x2c\x96\x5d\x2b\x0c\xc2\x46\x45\x5d\x37\x2c\x96\x0a\x93\xdf\x56\xc8\xc6\xef\x63\x49\x6c\x34\xc2\x2f\xa1\x79\xc3\x26\xa5\x21\x17\x27\x4d\xd2\xc8\x4a\xe0\xec\x70\xce\x6d\xcb\x2b\x68\x1a\x97\x6c\x19\x21\x03\xfb\x47\x4b\x13\xa3\x9d\x50\x5f\x5e\x9e\x66\x19\x29\x69\x92\x0a\x82\x60\xc4\x1a\x31\x96\xd8\x7c\xd9\xdd\x90\xe0\x3c\x1a\x48\x1e\x21\x41\xc7\xb6\xbc\x5b\x2e\xd6\x23\x06\xbf\x8b\xf8\x95\x61\x7c\x91\x48\x2d\x63\x57\x94\x3e\xe6\xdd\xe6\x9d\x48\x08\xb0\xcb\x43\x58\xb1\x5c\xe8\x2c\xc5\x7f\x1c\xab\x09\x68\x28\x51\x69\xa2\x75\xf7\x40\x50\x8d\xc0\xad\x89\x02\x83\x5d\xba\x0e\x01\xd3\x06\x1e\x46\x28\xdb\x77\xa0\xcb\x8f\x6e\x5e\xe8\x14\x62\x97\x94\xbf\x53\xe5\x28\x97\x95\x68\xe0\x98\x43\x1f\xb0\x15\xa3\xd7\x39\xbf\x6a\x20\xb4\x8a\x36\x58\x95\xf0\xc6\xe1\xd2\xa2\x34\xd2\xaa\x7c\xed\x5a\xf3\x3d\x31\x14\xb3\xbf\x48\x03\x4e\xb0\x5a\xf7\xb0\xf8\xd3\x0a\x38\xfd\xe1\x0f\x08\x9e\x76\x9a\x03\x57\x42\xbf\x76\x20\xac\x94\x44\x32\x31\xbe\x72\x71\x39\xc4\x49\x89\x6b\x99\x19\xd4\x83\x66\xcb\x96\x69\xc4\x0c\xee\xc4\x96\x2e\xb8\x6b\xac\x9d\xfb\xc4\x69\x94\x44\x61\xe4\xbb\x06\xde\x45\xa1\x7a\x81\xc3\x79\x20\x64\x1a\xc9\x28\x35\xa3\x3e\x83\xd6\xf8\xfa\x87\xa1\x34\xc4\x4a\xd7\x54\x65\xd1\x45\xcc\xe3\x99\x9c\x52\x26\x70\xf9\x98\xd6\xec\x14\xd0\x64\xaa\xec\x4e\x94\x58\xbc\x4f\x0d\xcd\x9d\xee\xca\x76\x29\x0b\x63\x4c\x0e\x3c\x40\xfd\x86\xe8\xf3\xf9\x57\xc0\x88\x09\x9d\x4c\xce\xba\xcc\x33\x75\x5a\x8b\x4c\x3f\x9d\xf7\xf3\xf5\xc3\x13\x37\xbf\x10\x94\xfe\x28\xf6\x23\xd1\x7e\x9a\x32\xca\x30\xe9\xd5\xa3\x3a\xff\x49\x37\x0f\x4d\x99\x4a\xa9\xab\x00\xef\x9a\xf2\x90\x77\xc4\x79\x5f\xcf\x23\x1e\x29\x5c\x62\x9b\xc5\xfa\xe9\xc7\xe2\xe1\x8f\x59\xfc\xc1\x85\x4b\xf2\x24\xf6\xc5\xad\x57\xa0\x63\x46\x7d\x9a\xc6\x4c\x60\x20\x5c\x89\xac\x06\x4f\x82\x87\x5d\xee\x7b\xe1\x89\x68\xfa\x73\xc5\x89\xc0\xf2\x86\x68\x57\xdc\xfd\xd3\x76\x7a\x58\x27\xca\x82\xc9\xfb\x8d\xa0\x37\xa8\x69\x0c\xdc\xa7\x99\x1d\xb6\xb0\x13\x64\x1d\x9f\x27\x89\x82\x38\x1d\xd1\x65\x63\x6a\x7d\xe0\x7c\xce\xbf\xa6\x24\xb1\xe5\xf7\xc6\x8a\x02\xda\xf9\x3a\xd0\x06\xa2\x69\x2a\x15\xee\x30\xd7\xab\xa5\xd7\x5e\xa1\xa9\x08\x21\x76\xc5\x8b\x49\xdb\xb9\x1f\x40\x09\x06\x52\xcb\xea\xd4\x94\x28\x04\xb2\xec\x5a\x01\x52\x29\x19\xc2\x70\xd4\x40\xd9\x74\xe0\x5f\xb9\x51\x8a\x48\x29\x7d\xcc\x54\x00\x52\xf8\x55\xa7\x25\x32\x3c\x74\xd6\x27\x55\x2a\xb6\x58\x1c\xcb\x8f\xe7\x80\x35\x33\x22\x1f\xc9\xec\x0e\x9d\xea\x20\x92\xaa\xff\x00\x1b\xc8\xf3\x70\x5c\x06\x4c\x35\x8b\x50\x61\x01\xf5\xd6\x9f\xe1\x1d\x23\xf6\xee\x20\x97\xc8\x52\x5d\xbf\xc1\x2f\xf0\xfe\x4e\x0a\x81\xb0\x10\xfb\x72\x7f\xc8\xbd\x9a\x13\x4d\x81\x32\xe4\xaf\xdb\x67\x45\xb3\x14\x87\xbb\xa2\x75\x4e\xfc\x31\x11\x60\x2a\xaa\x12\xc5\xaf\x27\x33\xfc\x04\x22\x70\x0a\x85\xce\x51\x99\x14\x41\x44\x48\x13\xd6\xef\xdf\xab\xe6\xcd\x17\x24\x1d\xba\x64\x3c\x55\x44\x28\x62\xec\x54\x5e\x42\xd5\x20\xc6\xd4\xe2\x9e\x47\xcb\x5f\x84\xc2\xb6\xca\x21\x55\xcb\x16\xc4\xbe\x1e\xb2\x0c\x8f\xf2\x7a\x22\x04\xe2\x09\xa6\x5e\xea\x71\x97\x25\x15\xa4\x7d\x45\xff\xe7\xff\xf9\x3f\xff\x3e\x66\xea\x57\x5d\xf6\x18\x3f\x1f\x31\x09\x22\x52\x24\xc5\x44\x3a\xff\x2f\xf7\x02\x11\x45\x1c\x15\x5a\x1f\x17\x9b\xed\x1f\xdd\xdf\x52\x0c\xe0\x74\x79\x26\x9f\x4a\x51\x40\x4b\xb9\x70\x39\x87\xea\x0c\x3a\xd8\x46\x58\x18\xd2\xdd\x3f\xdd\xee\xfc\x6b\x5b\xb5\xaf\xf7\x62\xaa\xb8\x8d\x59\x30\xb5\xb3\x3e\x55\x98\x8d\xef\x3a\xeb\xa9\xa0\x8a\x10\xbf\x5c\x8b\x57\xc8\xef\x45\xdd\x5c\x89\xa6\xc9\xa1\x23\x17\x71\xcd\xec\x54\xb0\x36\x58\x6c\x43\xb3\x97\x47\x5f\xcb\x11\x0c\x08\xed\x54\x6d\xb2\xbf\x61\x55\xe8\x41\x81\x43\x30\xc3\x58\xa7\xff\xbf\x83\xcf\x43\x59\x40\xd1\x10\x7f\x98\xc7\x56\xd7\xd1\xe1\x35\x47\x46\x5e\xf0\x04\x90\x62\xf8\x58\x43\x95\x97\xaf\x13\xa1\x3a\x2a\x78\x1a\xe2\x46\x70\x10\x55\x0d\x96\xc8\x09\xe5\x38\x9b\x4c\x7a\x64\xa7\x1b\x19\x33\xc5\xa1\x2b\x75\x6e\xca\x5c\x8f\x5c\x12\x11\x33\xd0\x6a\x90\x43\xbb\x86\x3e\xf0\x1c\x1b\x19\x11\x2b\xe3\x1a\x13\x34\xc0\xbe\x8d\xdf\x31\xe3\x38\x4a\x8c\x88\x24\x72\x52\xfa\xfb\xcc\x37\x9c\x4f\x06\x30\x89\x5c\xb1\xd8\xcf\x37\x7f\xa1\xc4\x24\x28\xb8\xd1\xe9\x2b\x7d\x2b\xbb\xb8\x4b\xa4\x44\x23\xfe\x66\x67\x17\xd0\x08\x2b\x39\x3e\x4d\x4a\x19\xef\x54\xa7\x87\xf2\x9d\xf3\x57\x15\x8a\xa3\xc9\xd3\x99\x31\x7f\x4c\x66\xbd\x8c\x80\x3a\x4e\xa2\x5e\x81\x69\xea\x37\xcc\x9f\x56\xf2\x54\xe9\x0e\x73\x7e\x75\x3c\x21\x92\x7d\x94\x64\x11\x2a\xb2\x1b\xb4\x15\x23\xbd\x39\xce\x40\x59\x85\x92\x4a\xbb\x46\xa6\xd7\x42\x14\xcd\xe1\x78\x38\x74\x2c\x3c\x54\xe8\x50\x60\xa2\xef\x1d\xda\x15\x91\x69\xa1\x07\xc7\x24\xa1\xfd\x96\xe3\x94\xc0\x2f\x0b\x2b\x51\xa1\x15\x41\xaf\xd1\x36\x20\xce\x50\xc7\xb5\x43\x28\xc2\xda\x0d\xa8\xb7\x36\xe2\xb0\x93\xf0\xa6\xac\x96\xa2\xd0\xd9\x00\x74\x2e\xb4\xd2\xe0\x36\x9c\x4d\x56\xbc\xe6\x70\x7b\xc4\x42\xb3\x03\x0c\x74\x2f\x01\x22\x82\xf1\x7f\x2d\xda\x5d\xf8\xaa\x2c\xf3\x81\xe5\x10\x26\xd4\xa1\xe8\x4a\x4f\x1d\x8e\x66\x40\xa0\x4a\x85\x11\x80\xf8\xc1\xc5\xb1\x29\xbf\x77\x01\x9a\x0c\x22\x83\x05\xf7\xcc\xd1\x54\xdc\x97\xea\xd7\x1c\xdd\x11\x95\x01\xd7\xd8\x97\xf5\x06\xe2\xb0\xf1\xbb\x5f\xe2\x67\x81\x0c\x44\x84\x7a\x5e\xf0\x39\xe2\xe9\xda\x96\xc3\x78\x50\x86\x2c\xc5\xe2\x94\x44\x33\xd8\x60\xc7\x77\xdd\x1d\xe4\x96\x9e\xb8\xe7\xf4\xc4\x58\xa2\x2a\xf7\xcf\xc8\xf6\x06\x55\xfd\x65\xdf\x88\x0c\x53\x86\xfe\x8c\xa3\xec\x9b\x16\x2e\x64\x28\x03\x44\xaa\xf8\x0b\xb4\x0f\x0b\x8e\xef\xd8\xaa\x72\x20\x5e\x73\xf2\x23\x05\x36\x43\xe3\x20\xbf\x4b\x91\x9f\x6d\x02\xae\x89\xe4\x0c\xfa\x7b\x99\xca\xfe\xeb\x5a\x82\x8c\x42\x40\xab\x2b\xb3\xe6\xa7\x68\x26\xb6\x40\x46\x44\x62\xb6\x6b\x5f\xea\xcc\x9c\x9e\xcf\x0a\x0c\x32\x92\x01\x7a\x9a\xcf\xd7\x7f\x8e\x5e\x3f\x4d\xac\x7c\xce\x2b\x34\x76\xa5\xcd\x2e\x4b\xc9\x08\xd8\x4f\xfd\xea\x77\x16\xc9\x8c\x40\x68\x41\x4f\x51\xec\x0e\xc4\x94\x21\x1d\xe2\x6f\x82\xcc\x11\x4d\x3c\x95\xb1\x61\x8e\x56\xa0\x2e\xf3\xa3\x55\x8f\x1a\x3f\x42\x22\x18\x72\x7f\xd5\x42\x89\xaa\x77\x2e\x64\xa2\x08\xc4\xae\x4e\x27\x2a\x97\x7a\x26\xc1\x18\x0b\x24\xd3\x30\x30\x72\x90\xf2\x3b\x27\xfa\x6a\xc7\x70\xf4\x77\x5a\x17\xe6\x8a\x5c\x5d\x40\xb7\x48\x41\xd2\xd8\xf1\xf9\x59\xb6\x14\x6c\xe2\xdc\xe4\x43\x8c\xdd\xc0\xa8\x48\xc1\x24\xe2\x11\xee\xa1\x2c\x32\xdd\x3f\xb2\xd0\x01\x56\x78\x5b\xcb\xdc\xda\x86\x39\x5e\x77\x2a\x65\x18\xa1\xdd\x6d\x5d\x08\x04\x59\x4d\xdd\x88\xaf\xf4\xb9\xa8\x94\xc4\x4a\x44\xdf\x97\xaf\xed\xaf\xbd\xcc\xef\xf8\x89\x24\x8d\x90\x80\xe2\x0a\xca\x42\x96\xde\xa5\x93\x52\x43\x17\xaf\xde\x2d\x9f\x76\x9b\x97\xf5\xda\xd3\x29\x50\x29\x4d\x88\xf9\xd7\xfb\xc5\xcb\xf2\xdb\xf2\xe9\x11\x05\xd2\xfd\x41\xc5\x42\xfc\xe9\xda\xb9\x9e\xa5\xca\x44\xbe\xce\x45\x63\xca\xae\xc4\x2d\x15\x24\xe8\xc1\x2c\x37\xa3\xcc\x99\xd4\xb1\xc0\x55\xe9\x7c\x68\xcc\x61\x88\xea\xd4\x1f\x96\x49\xc7\xd4\xe9\x4b\x75\xfe\x20\x10\x4b\x33\xf0\x4d\x54\x7a\x99\x83\xa8\xba\x03\x9c\x62\x57\xd8\x87\xa8\xaa\xac\xac\x86\x39\x27\x09\x5a\xa0\x97\xd7\xa1\x2e\xc6\x9f\x00\x4c\x8c\x3c\x29\x48\x7d\x80\x86\xc9\xc2\x07\x7f\x57\x13\x9a\x9e\xc5\xe6\xab\x7d\x91\x71\xca\x03\x42\xa5\x61\x29\x5a\x9e\xe5\xd3\xf3\xea\x71\xb5\x45\x42\xd4\xe3\x39\x60\x79\xdc\xfb\xa2\x82\xc4\x92\xc3\x6b\x90\xc7\xd7\x9d\x17\x40\x44\x19\x38\xb8\x5b\xdf\x6c\xa6\x45\xe2\xd1\xfc\x50\x01\x68\xcc\x42\xb9\x06\xa7\x33\xde\xe8\x99\x09\xad\x02\x63\x5b\xe8\xca\xa2\x8d\x1d\x0b\xf8\xa8\xa5\xc8\x33\xaf\xee\x41\x55\x08\x76\x4f\x77\x58\x34\xb7\x89\x8e\xde\x86\x8a\xb4\xc1\xcf\x21\x8f\xc6\xf8\xdf\x45\x10\x63\x23\xe8\xf3\xcb\xd5\xee\x69\x5f\x64\x1a\x19\x3f\xfd\x51\x4a\x83\x0e\x96\x24\xea\x37\x29\xd4\xaf\x59\x1c\x81\xa2\xda\xa0\x43\xf4\xf3\x76\xd4\x88\xaa\xa8\xb1\x59\x54\x4b\x71\x86\xbd\xa8\x5e\x10\x23\x71\x7d\x1d\xce\xed\x57\x4c\x1a\xde\x13\x37\x6d\x7e\x65\x87\x99\x6c\xb5\xe2\xd4\x72\x4c\x0e\xb2\xd5\x53\x68\xa1\xe2\x8c\x63\x16\x38\xab\x91\xcd\xf3\xde\xb2\x8b\x8f\xbf\x01\x8f\x23\x84\x1f\x62\x5b\xe8\x28\x6f\xae\xb8\x51\x48\x16\x26\xf2\xbc\xfc\x58\xd5\xaa\x2a\x3f\x06\x76\x5e\xc5\x8c\xab\x78\xa2\x34\xdf\x46\x34\xfe\xe7\xb1\xb2\xa4\x5c\x07\x9b\x68\xf6\x38\x56\x95\xa4\x11\xba\x95\xd0\xbc\x39\x7b\x3c\xd9\x6d\x55\x22\x23\xa6\xd1\xa2\x14\x70\xf2\xef\xd9\x1d\x4b\x23\x25\x5c\xf6\x65\x88\xed\xdb\x64\x7f\x4f\xdf\x50\x1a\xa7\xdc\x35\xa0\x97\x66\x57\x9a\x9d\x65\x76\xdc\xfd\xf2\x6c\xc7\x54\xa5\x32\x50\xa2\x23\xbd\xdf\x7e\x4e\xde\x8d\x97\x5a\xfc\x71\xff\x74\xbb\x9c\x69\x06\x1b\x2d\x05\x91\x58\xb9\xf2\x76\x1d\xdf\x64\x5d\x5e\x48\x09\x88\x11\xb6\xb9\xeb\xc2\x48\xa8\xae\xcb\xd7\xdf\x82\x21\xc6\xf3\x4a\x80\x44\x1b\x7a\x40\x7c\x68\xf7\x85\x95\x0e\x31\x47\x2c\x2b\x10\xbf\xe0\x1d\x0a\xab\x6a\xe4\x8e\x02\x4d\x94\x23\x0f\xe8\x60\x29\xb3\xa5\xcc\xee\x89\x21\xb1\xd2\xe0\x8e\x24\xf0\x8b\x8e\xa6\x59\x28\x85\x0e\x0d\xb1\xaa\xa0\x99\xa9\xca\xba\x19\x2e\x01\x4d\x88\xc2\x84\x9e\x25\x00\xba\x2e\x8b\x01\x05\x32\xd5\x24\x91\x9c\x78\x36\x65\x2d\xf2\xfa\xea\x58\x15\xe0\x35\x78\xdc\xa0\x28\xe2\x9e\x73\x6e\x75\x7f\xf7\xe7\x6c\x39\x45\x53\x13\xf8\x94\xec\x6e\x88\xd8\xd0\x8c\xf1\xa4\x43\xa1\xae\x6c\x5e\xfc\x19\x54\x06\x1d\x31\x30\xd5\x2c\xb6\xae\xc0\xce\x94\xd5\x28\xab\x3a\xd8\x83\x34\x13\x11\xb2\x0c\x39\xc5\xfb\xb9\xfa\xaa\x66\x82\x61\x9e\x6f\xfb\xe7\x47\xd6\xbc\x2d\x4b\x7d\xd6\xc6\xe7\x07\x42\x14\xc0\x2c\xcf\x6d\x5f\x19\xd4\x9c\x6b\x81\xb2\x57\x83\x16\x02\xcd\xb9\xc1\xca\xb3\x12\xb9\x7a\xb6\xcc\x77\x33\x9e\x85\xe6\xb1\xf6\x1d\x15\x59\xfd\x66\x55\xdc\x9b\x1e\xb0\xa1\x79\x6a\x1c\x5f\xd3\xa9\x3c\x36\x0f\xd0\xbc\x95\x7a\x71\x75\xd7\x1d\x96\x12\xe7\x6f\x2e\x1a\xec\xa8\x41\xf2\x31\x77\x2c\x0e\xa9\x72\x0d\x31\x18\x67\xd9\x44\x17\x99\x7c\x90\x98\x24\xf8\xde\xd7\xcf\x2b\x34\xe5\xcf\x77\x9b\xef\xbb\xf5\xea\x79\xb9\x7a\xdc\x2e\x6e\x57\xdd\xc9\x98\xf5\x97\x6b\x68\x1c\x95\xcb\xa3\xd8\xcf\x32\xc1\x52\x9d\x10\x83\x70\x2a\x5b\xd5\xf0\x2d\x0f\x3a\xa1\x81\x48\x3c\x0d\x88\x4d\x3a\xb4\xd1\x4b\xf5\x20\x3e\xc7\x13\x29\x91\x34\x10\x1e\x9f\x44\x1c\x71\xde\xf8\xb5\xa5\x01\xc5\xa5\xe5\x0a\x78\xb5\xed\xae\xf5\x07\x5b\xe7\xbd\x5b\x27\xcd\xe5\x2e\xc0\xcb\xa8\x4d\x9d\x12\x8a\x78\x36\xf8\xc4\xdd\xbb\x5d\x14\x37\x8e\x97\xaa\xbb\x0c\x53\xb1\x9b\xef\xcf\xa5\x2c\x91\x8b\x6a\xbe\xf4\xa2\xd3\x98\x61\xaf\xf8\x62\x79\xff\xd7\xf5\x68\x9c\x1f\x90\x32\x42\x3c\xa1\xef\xe9\xd0\x88\x63\xf5\x0c\xaa\x7c\x87\x6a\x52\xfa\xd7\x22\x4e\xd1\x59\x70\xa2\x7e\x4f\xe6\x5c\xd8\x86\x6a\x49\xc0\x69\xe5\x66\xcd\xb5\x28\x7f\xdb\x46\xf5\x7f\x15\x79\x68\x99\x28\xc4\xc9\x5e\x65\x20\xc7\xe8\x6a\x2d\x85\xc1\x34\xa6\x6c\x57\xcc\x33\x34\xc7\xaa\x98\x33\x26\x5a\x4a\xdb\x86\xfa\xbf\x4e\x9c\x7f\x04\x76\xb8\x70\x59\x1d\x47\x98\x09\xc8\xea\x87\xac\xc8\xf6\xc7\xfd\xb0\xbc\xa8\xb5\x89\x50\x52\xa6\x70\x39\xea\xf5\xb1\xf8\x55\x6f\x4b\x97\x1e\xf2\xa3\x20\x52\x5e\x1a\xfb\x06\xa6\xa4\xbd\x83\x74\x81\x06\x4e\x95\xad\x23\xb7\x1b\x12\xe8\xf6\x92\xfe\x24\x26\x88\x99\x25\xdf\xc1\x66\xc8\x0b\xca\x6c\x54\x9b\x88\x20\xe8\x1d\x0a\xbd\xbb\x7f\x5a\x7e\x7f\x59\x77\x67\xe0\x96\xae\x7d\x94\x20\x98\x8d\x2d\xb4\x49\x94\xcd\xc7\x82\xab\x40\x7b\x70\x60\xb5\x1b\xe1\x70\xb5\x31\x01\xfa\xb9\x7f\xff\xfd\xb7\xfb\x13\x04\x21\x41\x2a\xd7\x67\xb1\x87\xe9\xd4\x83\x80\x18\xa5\x46\xdc\x89\xa5\xb9\xc0\x78\x4b\x81\xd0\x30\x1e\x66\x3d\x17\x55\x03\x46\xa8\xa6\xbe\xeb\xcc\x1e\x10\xcd\x23\xfb\xca\x6c\xd0\xec\xff\x1e\x45\xb1\x85\xf6\xba\x0b\x5d\x43\x0e\xaf\xa2\x99\x21\x79\x19\x5f\x33\x8a\x52\x15\xfa\x6e\xf5\x21\x3b\xee\x6c\x9c\x33\xb6\x99\x10\xf1\xc0\xd3\xb2\xf9\x80\x60\x32\x07\x81\x8a\x18\xe7\xaa\x78\x17\x8d\xa8\xe6\x6c\x0a\x70\xad\x23\xe1\x08\xbb\xae\xab\xbe\xf2\x0c\x09\x8b\x98\x3b\xfd\x76\xd5\xbc\x5d\xf2\x1b\xfc\x68\xb0\x2c\xb1\x50\x34\x6d\xf4\x0b\xf0\x2c\x8c\xe9\x21\x32\xd3\x16\x62\x48\xa5\xc5\x76\xbf\x7f\xe2\xee\xee\x22\xa6\x19\xd0\x99\x1b\x2f\x68\x87\xa5\xb8\x2a\x45\xa5\x9f\xcb\x0f\x4f\x7e\x7f\x3c\x07\x0b\x82\x50\x32\xa2\x9d\x71\xb3\xcc\x31\xc7\xa2\x39\x21\xe2\x5a\xec\x1f\xc4\x84\x3c\x04\x04\x28\x4c\x8e\x35\xa2\xea\x9d\x3e\x90\x2c\x46\xfc\x43\x01\xa0\x9d\xa5\xbb\x99\x96\xec\x40\x0a\xea\x55\x49\xd1\x61\x5e\x96\x65\x9e\x15\xaf\xa3\x5e\x5b\x90\x26\xc6\x41\xcb\xb2\xaa\x45\x95\x1d\xf7\x96\x2a\x1b\x67\x6c\xd7\xba\x0e\x2a\xe0\x24\xe8\xd1\xba\x3d\xd7\x1d\x05\x15\x86\xd2\x03\xb1\x1a\x38\xdc\x1c\x0b\x75\x5e\x36\x02\x05\x0c\xf1\x51\x87\xd2\x17\x67\x40\x13\x82\xdb\x3d\xe2\x58\x90\xa3\xea\x5e\x7c\x9c\xfa\x67\xd4\xc6\x4a\x34\x08\xad\x1f\xcb\x66\x5c\xe4\x03\x88\x15\x92\x70\xed\x54\xb9\x3f\x1c\x1b\x58\x96\x7b\x2f\xf4\x30\xbe\x30\x68\xaa\xdd\x4b\x38\x1e\x7e\xfa\x4e\xa1\x99\x6d\x07\x0c\x51\xd2\x39\xd2\x5d\x74\x30\x03\xe4\x02\xa3\x18\x56\x20\x73\x51\xbb\xf7\xfa\x06\x5d\xf4\x6a\x02\x9d\x4a\x97\x59\x5f\x5e\x2a\x62\x9a\x90\x51\xa4\x78\x73\x8c\xd9\xa0\x31\x09\x7f\x53\x56\xb6\xcd\x7f\x7e\x23\x30\x84\x87\xc8\x5c\x29\x33\xfd\xc7\x8c\xfd\x34\x24\x91\xf8\xa8\xe6\x68\x75\x58\xb3\xe2\xae\xe8\x41\x8a\x86\xa4\x42\xe8\x41\x4e\xf9\xac\x72\x6a\x22\x26\x11\xfe\xb8\xcf\xa6\x24\x45\x26\x32\x22\x0c\x3c\xda\x4c\x7b\x4e\x6a\x6a\x28\xe7\xc4\x0c\xc0\x84\x16\x67\x6d\x5b\x71\xe6\x9f\x82\xc9\x04\xb7\x16\x04\x5a\x78\xe9\xea\x01\x00\xd2\xf0\xc8\xca\x3a\xd6\xae\xc2\x8b\x98\x76\x7b\xc6\x2f\x7d\x75\xc3\xb5\x75\x55\xaf\x00\x6e\xb3\xbd\x9f\xa0\x26\x56\x44\x3a\xe0\xde\x3d\x98\x06\x95\xad\xee\xc6\xb3\xc4\x24\xc4\x20\x7d\x89\xe8\xc0\x3f\x53\x98\x8e\x49\x52\x82\x9c\x1c\x9b\xc5\xfd\x2a\xd8\x2d\x17\xde\xa0\x98\x34\x14\x04\x86\xcd\x11\x03\x16\x65\x6a\x52\x12\xdb\xf6\x59\x6c\x68\x39\x5d\x36\x7b\x26\x8d\xac\xbe\xfa\xae\x29\x8f\xc8\x1b\x36\xbb\xe1\x18\x11\x33\x6c\x0c\x43\x7a\xc0\x3b\x55\x0e\xd3\xc8\x46\x24\x9a\xd9\xf4\xdb\x48\x51\x69\xfc\xb0\x42\x31\xac\xab\x54\xa2\x69\xe7\xdc\x53\x01\xeb\xed\xc3\xe4\x85\x08\x63\xdb\xb8\x32\xdf\xcf\x5b\x3f\x1d\x9b\x73\xde\x05\x9f\x5f\x36\x3a\x52\x5e\x68\xfc\x0b\x4a\x3c\xa3\xb9\x61\x56\x48\x6a\x55\x74\xca\x31\xd4\x68\x11\x63\x39\xea\x58\xb7\xdb\x59\x9d\xe9\x4e\x9b\xa9\x1b\x01\x89\xad\x9e\xe2\x02\xd9\x69\x50\xb9\xa8\x60\xd7\x88\x5f\x59\xf1\xba\x6b\xca\x72\x97\x97\x9d\x07\x6f\xc0\x08\x2c\x38\xec\xbc\x1e\xd9\xb0\x42\x65\x4c\x12\x21\xe5\xa0\x4b\x3e\xd5\x57\xa7\xc9\xb2\x1b\xbf\x70\xa3\x63\x6c\xb4\x2e\xca\x27\xe3\x55\xf1\xdc\xe4\x62\x41\x10\x6b\x74\x0d\xcb\x03\x14\xab\xd7\xb3\x20\xd6\x8f\x4a\x3b\xd2\xb4\xd6\x84\xaf\x9a\xb7\x1f\x65\x7e\xdc\xb7\x76\x45\x8f\xb9\xf2\x59\x10\x86\x04\x57\xb9\x2e\x9f\xcb\x3c\xbf\x82\xdf\x12\x1b\x8f\x56\x01\x0b\x42\xc6\x22\xd7\x25\x80\x40\x4e\x2b\x2f\xeb\xef\x37\x14\x32\x4a\x3b\x25\xc1\x07\xe8\xfe\x0e\x89\xad\xd5\x96\x45\xd3\x25\xc1\x58\x40\x42\xe1\x69\x95\x1e\x4b\x0d\x83\x1e\x5b\x16\x10\x46\xd0\x7f\x76\xb7\xef\xba\x67\xc7\x0f\x43\x84\x00\x67\xab\x1f\xe1\xb3\xf1\xb1\x56\x59\xdc\xe9\xee\x34\xd2\x60\x27\x45\x66\x53\x2d\x97\x53\x5d\x2c\x88\x68\x8c\x2e\xc1\xfe\x98\x93\xf6\xd9\x26\x3c\x2e\x2c\x88\x52\xbb\x36\x5c\x93\x4f\xd3\x53\x8d\xfa\xab\x51\xa9\xd1\x2f\x2c\xe0\xb3\xd9\x56\x42\x83\x65\xd5\x74\x47\x39\x8d\xfc\x56\x81\x3b\xf2\xba\x2c\xf3\x4d\xa7\xad\xc4\x02\x0e\xb6\x25\xa9\xab\x50\x88\xe2\x6c\x91\xfd\x6b\xfc\x06\x62\x66\x2b\x79\xcf\x58\xa4\x74\xdd\xbf\x45\x93\xfd\xfb\x38\xae\x2e\xb2\x20\x8e\x39\x6e\xdf\xfb\x4e\x3f\x7b\xe8\xcb\xb1\x20\x11\x80\xb8\xcf\x35\xd9\x0e\x33\xb4\x2c\x48\xb4\x46\xa2\xf6\xa7\x5c\x2f\x45\xf1\x97\xe8\xf9\x68\x58\x90\xca\xc0\x29\x0a\xb4\xeb\x18\xdb\x68\xb3\xe6\x74\xa7\x3f\xfd\x00\x11\x1a\xe0\xc3\xdd\x6b\xb8\xee\x58\x20\x49\xa8\xba\x00\xf2\x70\x6c\xae\x87\xf0\xa4\xf1\xcb\x57\x51\xc2\x85\xd7\x88\xee\x37\x74\x16\x28\x9d\x60\x4d\xe0\xbd\x6c\xa0\x9e\xba\x29\x2c\x50\x26\x41\x8a\xc2\x36\x12\x5e\x7f\x5b\x6c\x56\xa4\x8d\x85\xef\x9e\xae\xfd\xef\x75\x12\x2a\x27\xeb\x89\x82\x57\x67\xc1\x17\x0b\x80\x04\x2a\xf4\xcd\x64\x63\x6f\xda\x8f\x50\x11\x19\xb4\xe4\x76\x37\x07\xda\x02\x43\xb1\xbf\xb2\xcc\x11\xca\x36\xff\x7c\xa0\x15\x4a\x1f\x99\x4c\x74\xaf\xc7\x10\x81\x8c\x61\x0b\x9b\xf8\xb0\x45\xc2\x59\xc3\xc7\xc2\x20\x25\x98\x9d\xb0\xb5\x3f\xef\x07\xb1\x30\x30\xb1\x8f\x69\xb1\x10\xee\x59\x7e\x59\x48\x8c\xc4\xb3\x77\xa2\x7b\x17\xce\x1c\x31\xeb\xfd\x8b\xd6\x5d\x97\x39\x6c\xdc\x04\xf1\xb3\x3e\x64\x34\x11\x0e\x24\x73\x68\x4a\x4f\xd0\xd5\x1d\x15\x02\x29\xf7\x94\xee\x12\x2c\x2c\x8c\x43\x5b\x8b\x7a\xc8\xf2\x3c\x2b\x0b\xab\xf7\x34\x9c\x76\x61\x1c\xd3\xc0\x61\x4c\xda\x88\x70\x48\x68\x82\x7b\x64\xe4\x07\x26\xae\xef\x75\xa1\xc5\x1e\x46\xa7\x48\x69\x98\x42\xff\x51\xca\xea\xe4\x03\x14\x3f\x42\xf0\x00\xa1\xc0\xd8\x0a\x71\x0f\xa2\xa3\x9a\x65\xa1\x48\x6c\x0b\x4d\x2d\x72\xb8\x94\x29\xf7\x43\x75\x80\xdd\x63\x59\x8d\x2c\xd5\x7f\x75\x95\x08\x16\x0a\x10\x44\x0f\x35\x23\xcf\xf1\xd7\x7e\xa4\xa1\x98\x18\xd6\x3e\xcb\x5a\x56\x23\xfc\x0e\x0b\x65\x9c\x42\xdf\x62\xf4\xd7\xd1\x13\xed\x6d\xcb\x59\xd3\xc2\x42\x29\x2c\x54\xdb\xa6\x5b\xbd\x08\xbc\xc5\x15\x76\xd2\xe3\xe3\xbb\x90\x32\xf6\x20\xfe\xbb\xe2\xbd\xcc\x14\x7c\x13\xf5\xdb\x44\x0d\x95\x85\x9a\xa5\x64\xc8\x4e\x88\x42\xd4\x5f\xc5\x7c\xed\x4f\x0c\xa6\x70\xac\x72\x9e\xf5\xe6\x26\x1d\xa5\x2c\xd4\x92\x72\xd9\x3d\xe2\xf5\x9f\xe3\x55\x16\x02\x27\x38\xd1\x9c\xba\x2f\x72\xa4\x1e\x75\xd6\x20\xd6\xb3\x9d\x19\x43\xd4\x2d\x0b\x21\x09\xd1\xe5\xde\x3e\xc3\xe7\x60\xd7\x0a\x4d\x14\x27\xa4\xb3\x09\x65\xb5\xb3\x49\xd0\xec\xb8\x3f\x13\x97\x61\xa1\xa1\xa1\xe8\xa8\x77\x0a\x93\x9d\x67\x92\x2f\xe3\x05\x58\x68\xa4\xc4\xa9\xe1\xb9\x7f\x71\xdd\x20\x2b\x65\xf6\x5a\x88\xe6\x58\x5d\xe4\xbb\xf8\x6d\xe6\x66\x60\xba\x42\x03\x21\xe6\x7a\x6d\x55\xf4\x4b\x93\x41\x82\x38\x45\x5f\xca\xc9\x7f\x58\xb5\x96\xbb\x33\xe4\xeb\xf8\x41\x48\x18\x44\x88\x4f\x43\x2e\x71\x64\xf2\xb1\x72\x95\xde\x7e\x90\x90\x9a\x38\xee\xde\x53\xd3\x29\x44\x4c\x1a\x12\x18\x09\x41\x3a\x9d\x99\x36\x92\xf0\x64\x2c\xb3\x93\x86\x84\x26\xc0\xfc\xf6\x6d\x05\x50\xc8\xf2\xc3\x5f\x8c\x08\x4d\x86\x54\xd8\xf3\x48\x4c\x37\x38\x92\x09\x12\x11\xe5\x99\x4f\x28\x32\x42\x15\x50\xd3\xcb\xe1\xba\xbb\xb0\x65\xb1\x72\x89\x6d\xb8\x17\x6e\x89\x71\xab\xbd\x6d\xdb\xf7\x70\x1e\xaf\xab\xf2\x50\x65\xd0\x88\xea\x74\x7d\x01\x5f\xcb\x08\x33\x94\xcc\xe3\xb1\x2f\x41\xb0\xdd\x0f\xb9\x4a\xd0\xb4\xdc\x2d\x9f\x2c\x29\xcb\x3f\xc1\x9b\x32\xc2\x4d\x8c\x4f\xb8\x7e\xbe\x5b\xae\x76\x8b\x9b\xed\xea\x79\xb7\x79\xba\xd9\x76\xa1\x05\x23\x71\x90\x72\xab\xac\xd4\xa9\xa7\xff\xdf\xe6\x15\xdd\x19\x93\x34\xc4\xe4\x09\x5c\x40\x30\x31\x92\x28\x89\xb7\xe5\x5c\x67\x8f\x3b\x7d\xee\xa5\x54\x18\x49\x0c\x78\x09\x9a\x0d\xa8\x63\x05\xd8\xb4\xd0\xc5\x32\x8c\xa4\x81\xc1\xf2\xe0\xa1\x35\x04\x3b\xb2\xeb\x25\xaa\x18\x49\xdb\x50\xa7\x33\x46\xe8\x84\x0d\x8d\x02\x49\x99\x40\x15\xfc\x85\x10\xb3\xa2\xf0\x67\x55\x57\x46\xd2\xa4\x6b\xd3\x59\xe4\xb9\x15\x5e\xc5\xad\xa0\xef\x9a\x1a\xbd\x8f\xae\x8d\x8a\x11\x11\x98\x04\xfc\x7e\xda\x40\xf5\x2e\xf2\x65\x09\xc6\x64\xaa\x9d\x62\x97\x9b\x71\x26\xef\x55\x86\xd6\xb8\x1b\x71\x54\xd0\x74\x7c\x1a\x1b\x50\xdd\x4b\x93\x44\x22\xd5\xdb\x9b\xa8\x7f\x4e\xd8\xba\x18\x91\x69\x80\x89\xba\x8d\x2a\xab\x31\x30\x6c\xf8\xb8\xe3\xa7\x96\x2a\x8c\xdb\xa7\x5e\xd5\x75\x1b\xa3\xf9\xb2\x3b\x23\x2a\x60\x5e\xe2\xfb\xb1\xdd\x32\x55\x59\x55\xa0\x9a\x6b\xa8\x71\x4f\x6b\x63\xac\x43\x59\x35\x96\xdd\xad\xbb\x3f\x15\x06\x21\xb8\xd0\x60\x6c\x74\x88\x0a\x43\xe1\x5c\x94\xa1\x58\x62\x32\x6f\x49\x88\x8a\x2c\x53\x7c\xfd\x56\x1e\x3a\x76\x18\x7f\x2c\x05\xd3\xeb\xd6\xde\xb9\xf2\xfb\xf4\x7a\x86\x61\x3d\xfa\x9b\x28\xf2\xac\xd8\x82\x2f\x9c\xcd\xbd\x05\xed\x10\x27\xb2\xdd\x26\x1f\xfd\x65\x80\x87\x9e\x58\xf0\x3a\x13\xfb\xb2\xd0\x0e\xd6\x3c\x57\x22\x63\x04\x4c\x2a\xad\xac\x60\xf9\x6b\x67\xca\x6a\x57\x94\x1a\x26\x63\x4c\xc4\x2d\xe9\x73\x56\xd7\x7b\x54\x42\x3e\xbb\x6f\x93\xa4\x36\x54\x3c\xfe\xaf\x70\x70\xcc\x2f\x1d\x93\x28\xa0\x06\xdf\x54\xd9\xee\x52\x1b\x68\xfe\xe3\xf0\x90\x15\x57\x13\x42\x00\x16\x85\x91\xe5\xbd\xdd\x34\x22\xab\x36\x0d\x1c\xae\x41\x89\x93\xe7\xe5\xeb\x52\x6e\x6e\x34\xe1\xd6\x19\xb6\x18\x44\x5b\x60\xad\xbb\x83\xa9\x45\xff\xbe\xa2\x7e\xb8\x87\x02\x96\xd5\x7e\x8a\x6a\x63\x51\x44\xac\x9a\xe1\x7e\x28\xa9\x76\x71\x11\x46\x11\x8f\x31\x38\xb2\xdb\xa0\xbf\x5e\xa4\x85\x89\x3b\x53\xde\x9a\xa5\x75\xeb\xea\x21\xa4\xc8\x0f\x31\x16\x42\xb2\xdb\x23\xd7\x7c\x27\x8e\x15\x92\xb1\x6a\x62\x48\x12\xf7\x0b\x1a\xb2\xc0\xdb\xba\xc3\xde\x9f\x87\x0b\x40\xd0\xee\x41\x9c\xae\x32\xdd\xf7\x71\xb5\x5e\xed\xec\xce\x1d\x71\x65\x8c\x93\x76\x80\xaa\x59\xfd\x9b\xdb\x71\xce\x74\x8f\xf3\x4b\x2c\xe2\x5a\xfa\x60\xd6\x0b\xb8\xcf\x51\x79\x0d\xf2\xbd\x2c\x6a\x7d\x64\x8b\x26\x40\x93\x5c\xaf\x2d\xd7\x9e\x6f\x2e\x66\x51\x2c\x63\x54\x6c\x42\xd8\xfe\x25\xaa\x12\x37\x36\x09\x13\xe5\x58\xad\xda\x68\xfc\xbc\x53\xcd\x8f\x8b\x2c\x95\x49\xa7\x8d\x3b\x39\xac\x49\xe2\xa2\xdc\x87\xac\x78\x10\x3e\x16\x8c\x44\x68\xdb\xcc\x9d\x2f\x34\x8e\x4f\x23\x41\x63\x1a\x77\x7a\x86\xb6\x64\xba\x2c\x6b\xcf\x60\xeb\xd9\xd1\x59\x24\x40\x62\x40\x27\x94\x3a\xee\xb1\xb7\xd7\x5f\x40\x86\xca\x6d\x31\xed\x66\x4b\x18\xff\x63\xf4\x7c\xd2\x28\x4c\xcc\xbc\xbb\x48\x63\xf0\x80\xe3\x17\xa1\xb8\x65\xda\x43\x72\xa4\x65\xe9\x32\xbf\xf5\x74\x54\x6c\xbb\x68\x6b\x40\xac\x96\x6b\xe1\x9f\x0a\xd0\xb1\x48\xc9\xee\xb5\x76\x09\xe2\x89\xbf\x32\xe4\xf8\x72\xbf\xd2\x8c\xe0\x97\xad\x1b\x38\x6c\x3f\xca\x36\x56\x1f\xa1\xa8\x59\xa4\x39\x87\x5e\x8e\x7e\x71\xfc\x74\x1d\x86\x93\xcf\x01\x2a\xc0\xce\x1a\x37\x2c\xab\x90\x16\xef\x9c\xb3\x9c\x45\x26\x80\xd0\x75\xeb\xdf\x56\x62\x86\xaa\xb1\xb7\xc0\x91\x09\xa3\xa4\xf7\x82\x10\x58\xbf\x45\xb1\xcc\xc6\x06\x2f\x33\x5c\x81\xb3\x96\x8d\x06\x21\xf7\xee\xf5\xce\xe2\xc1\xb3\x62\x87\xe2\x20\x3b\x40\x25\xbd\xc9\xf0\x48\x46\x36\x9e\x76\x24\x1e\xf7\xa0\x5f\x7d\xb3\xf4\x0c\x44\x82\xd1\x40\xcb\x78\x40\x0f\x38\x8d\xc2\xdd\xa8\x30\x10\x08\x02\xfa\x75\x52\x4e\x21\x6b\xdc\x49\xc0\x68\x18\x1b\x6c\x3f\xf5\x4c\x2c\x77\xcb\x27\xff\x41\x26\xa7\x12\x96\xb5\xd0\x65\xdf\x47\x4c\x9e\x8c\x12\xa2\x13\xe1\x58\x8f\x37\xa5\x6f\xab\x65\x94\x88\x00\x33\xdd\xad\x89\x38\x1e\x16\x79\xbe\x39\x54\xd9\x54\x15\x83\x51\xa2\x22\x04\x7f\x62\x4b\x8f\x63\x92\xf4\xa7\x88\x42\x86\xdb\xcd\x06\x9a\xab\xe3\xa9\x3c\xce\xef\x1f\x7e\xb0\x88\xc1\xd1\x78\xb4\x73\xeb\xe5\x80\x9e\xeb\xe4\x8b\x9f\x65\x62\x19\x8d\xa4\x80\xb8\xab\xc4\x23\xa9\xac\x07\x61\x8e\xdf\x17\x0d\x0c\x7e\xd8\x5b\x74\x9a\xfc\x3d\x52\x1a\x8b\xa1\x1a\xe7\x72\x2a\xd6\xcb\x28\x65\x29\xb5\x8d\x10\xad\x33\x31\x60\xad\xf0\xc7\x93\x00\xc1\xf6\x4b\x28\x9a\x4a\xe4\x59\x73\xba\xcd\x4c\xb3\x79\xeb\x5f\x04\x35\x81\x55\x89\xc9\x0a\x51\x3c\x8f\x78\x74\xdd\x08\xe6\xd2\xe6\xee\x3d\x17\xaf\xd8\x7c\x3a\xf4\x13\x29\x4b\x02\x4c\xaa\xea\xaa\x6b\x8c\x60\x94\x19\x83\x96\xc1\xc7\x1d\x1d\x1b\xc7\xaa\x79\x43\xe9\xe8\xc1\xa3\xf2\xc0\x0a\x98\xec\x7c\x95\xf3\x8c\xfb\x65\xfe\xcb\xf0\x38\xf6\xa8\xf0\x27\x24\x8b\xda\x66\x4d\x8e\xd5\x9b\x32\x9f\x97\x75\x64\x94\x27\x01\x8a\x34\xac\x4f\x95\xd8\x67\xd3\xa9\xcb\x95\x44\x23\xa9\x3c\xb5\xcd\xe0\x87\xc6\xba\x37\x76\x77\x78\x84\x8f\x6f\xd7\x7f\x92\x60\x16\xf3\xc0\x68\x1c\x11\x9b\x4a\xea\xe0\xaf\x9d\xeb\x3b\xec\xa4\x69\x07\x9a\x38\x19\xbc\x26\x84\x50\x3e\x63\xbc\xb7\x2d\x47\x74\x8c\xfe\x07\x69\x8a\x59\xda\x35\x54\x75\x39\xdb\xb4\xc0\x68\x2c\x34\xd6\x5f\x7a\x1e\x4e\x13\x72\xff\xb2\x63\x50\xd4\xf3\x6a\xce\xe8\xdf\x8e\xee\x2e\xe1\x21\x36\xb3\x6e\x10\x4e\xdf\xd3\x7e\x5c\xda\xb0\xa6\x9f\xeb\x8b\x9e\x2c\x7f\x85\x44\x44\xbe\xde\xf3\x31\x60\x89\xf6\x3e\x09\x4d\x69\x80\x65\xbc\x6b\x78\x17\x9d\x34\x21\xa3\x29\x8f\xf1\x33\x3e\x8a\x7d\xe6\xd9\xa8\xc7\x3a\xe9\x93\x82\x72\xfb\x13\xe0\xb6\x54\xfb\x31\xa5\x42\xfa\x07\x3d\x82\x8c\xa6\x42\x85\xbe\x95\xeb\xf1\x66\x7b\x53\x56\x23\x8a\x87\xb9\xa4\x06\x15\x44\x26\x9e\xd1\x0b\xbf\xc4\x37\x51\xbf\xdd\x40\xa3\x7c\x1d\x80\x4a\x22\x70\xd3\x95\xc7\xaa\xe8\x39\xca\x19\x95\x02\x74\x2f\x66\x8f\x64\x56\x80\xfb\xcf\x64\x3e\x28\x22\x52\x31\x15\xd3\x1c\xf6\x1d\x31\xaa\x34\x35\xb1\x97\xcb\x19\xe8\x67\xba\xc3\x3a\xb2\xb1\xad\x6f\x6d\x58\x0c\x7d\x58\x0a\xa1\x8d\x30\x37\x47\x79\xa8\xc0\x8c\xa0\x2e\x8c\x82\x91\xe8\x47\x5c\x7d\xbf\xf2\x7f\x32\xc6\x0a\x1e\xb5\xa6\xe3\xbd\x6c\x60\xdd\x7a\x26\x23\x07\x86\x05\x81\x8a\x9c\x25\x5b\x5c\x04\xaa\x31\x16\x10\x89\x4d\x70\x48\x9c\xb0\xb3\xa5\x21\x7f\xd7\x2c\x30\x09\x6a\xf2\x15\x62\x3f\x41\x8e\x32\x16\x12\xed\x39\xa0\xb7\x9b\x9e\x8e\xd1\x1f\x8d\x04\x3a\x37\x2e\x45\x0d\xef\x36\x8f\x3d\x39\x05\xb7\xed\x43\x1b\x28\x34\xfa\xed\xdb\xf2\x9c\x20\x8c\xb1\x30\x89\x31\x68\x35\x99\xf7\xdd\x58\xa8\x01\x9d\xba\x87\xb2\x80\xe6\x4d\xb8\x30\x67\x03\x33\xa5\x46\xc6\x48\x14\x1a\x67\x2a\x73\x51\x41\x2f\x23\x31\xf4\x8b\x18\x51\x09\x1a\x88\xfb\xf2\xb5\xbd\x9f\x1b\x91\xe5\x7f\xcc\x55\x5e\x19\x8b\x58\xc0\xc1\x3f\xdb\x90\x5d\xd4\x1f\xe7\x06\x37\xb1\xfd\xb1\x19\xac\xa6\xd6\x3b\xc6\xc7\xc8\xed\xf4\x99\x21\xf9\x6c\xc7\x30\xc4\xca\x29\x14\x13\xa8\xbd\x9c\x06\xe8\x45\xd3\x9d\x46\xb0\xd4\xee\x9e\x6d\xc8\x7f\xac\x2e\x6c\x2e\xe3\xdd\x8a\x45\xca\x2a\x65\x37\x19\x54\xe4\xfe\x69\xdb\x9d\x0d\x42\x4f\xc5\xfc\x52\xfb\x2e\x97\x73\x79\x3d\xc6\x68\xa8\xd0\x8d\x58\xdc\x2d\xbb\x1f\x53\x11\x63\x2d\x78\xfd\x74\xf7\xb8\xdd\xec\xb6\x4f\xbb\xcd\x7a\xf5\xe8\x2b\x19\x8c\x11\x2b\x51\x8b\x15\xde\xee\x8f\x94\xa1\xce\x3a\x56\x05\xd5\x6c\xca\x63\xf4\x59\xb8\xb0\xfc\x5b\xff\xb5\x58\x2f\xfe\xf4\x27\x89\x4d\x82\x25\x80\x7d\x59\x34\x6f\x84\x2a\x5b\x48\xb0\xd4\x85\x7e\x4c\xd2\x3a\x51\x6e\x57\xd8\x35\x1f\x25\x32\xa5\xac\xfe\xfd\xd2\x86\x77\xa3\x77\x9e\x50\x8a\x09\x7b\xa1\xb5\x67\xb8\xf8\xda\x24\xb2\x94\xd8\x1d\x1b\x5b\x95\xf5\x40\x61\x99\xb1\x94\x59\x04\x6d\x7b\x27\x93\xa6\x8a\x4b\x27\x03\x45\xac\xf2\x01\x92\x34\x39\xb2\xbe\x95\xeb\x5c\x9a\x8f\x8d\x98\x0c\xad\x7a\x08\xda\xf2\xa7\xf6\x06\x36\x48\xda\x3a\x9e\xd2\x52\x1a\xe3\x30\x68\xd7\xad\xc1\xb7\xe0\xcd\xf9\x33\x2a\x16\x6a\x9b\xaf\x79\x7f\x87\x62\x07\x16\xef\xed\x0f\xa6\x36\x79\x87\x88\xc0\x3f\xdb\x18\xa0\x4f\xdb\x31\x25\xa4\xe7\xb6\xeb\x10\x9b\x23\xfb\xcb\x94\x0a\x11\x00\x56\x38\x05\xe4\x9f\x90\x0d\x6b\xab\x4c\x69\x16\xf6\xfa\x64\x8e\xa9\x67\x7c\x7b\x9a\xf0\x40\xf7\xb5\x93\xc7\xf2\x19\x8c\xff\xb9\x06\x85\x3c\x20\xb9\x2d\x20\x5e\x2a\xdb\x33\x06\x69\xe4\xa1\xc1\xd7\x9d\x8a\xa4\x3f\xa6\x22\x54\x12\xb8\x3a\xe6\xbf\xa6\x69\x8c\xb9\x53\x41\x82\x2c\xdf\x57\x7f\xf9\x24\x0c\x0f\x88\xa5\xa1\xb6\xe5\x8d\x76\x35\xdd\x94\x15\xb6\x1f\x8c\x55\x25\xe7\xea\xd8\x3c\x88\x4c\xd0\xd3\xd8\xac\x44\x95\x9f\xee\x0a\x55\xee\xe1\xea\x34\x9b\xc3\xe1\x41\x2a\x30\x5d\xe1\xe0\xd4\xbe\xdd\x61\x90\x96\xe4\x81\x48\x71\x62\xeb\x23\xe4\x8b\xa2\x6c\x67\xc9\xb2\x7c\x37\x60\x2e\x38\xe1\x3c\x8c\x62\xd2\x09\xba\x87\xfe\xb9\x42\x19\xa2\x0a\xae\xa3\x3d\xbc\x12\x8d\x7a\xfb\xfd\x1b\xe2\x84\x70\x68\xe7\x4c\x89\xd9\x45\x91\x2f\x0e\x87\xdc\x31\x9c\x6e\xb2\xd7\xe2\xe5\x30\x9a\xab\x9c\x10\x95\xb6\xd7\xfe\x5c\xbd\x3c\x0f\x8a\x23\x9c\xc4\x56\x28\x58\x89\x3c\xf7\x5a\xf9\xe3\xbb\xa6\x89\xc5\xa4\xa9\x66\xe4\x54\x73\x16\xa5\x98\x56\xdb\xb9\x98\x62\xf4\xd0\xe9\xbc\x14\x20\xe3\x0c\x0c\xc2\x90\x71\x1f\xf8\x39\x24\x55\x61\x9c\xeb\x08\x17\x77\x5d\x9a\x66\x29\x0e\xcb\x6f\x37\xfe\x48\x1c\x28\xcf\xd3\xb0\x43\x0a\x1f\x51\xc9\xac\xa9\x77\x07\xa8\x5c\xdc\xe8\x07\xa6\x11\x36\x5e\xa1\x22\x59\x36\x09\xfb\x78\xac\x2d\xc3\xe4\xa1\x82\x83\xa8\x00\x45\x62\x2e\xb6\xdf\x32\x9e\xa4\x96\xa0\x7f\xf3\xb2\xdc\x9e\xf1\x34\x31\x9e\x88\xc0\x4d\xe9\x13\x42\x9c\x91\x75\xaf\x6b\x12\x39\xf6\x64\x2f\x7d\xa2\x78\xb6\x35\x96\x71\x11\x6a\x24\x0b\x7e\x28\xab\xd6\x4b\xf8\x06\x79\x6e\xd9\x07\xfc\x63\xc9\x48\x87\x61\xcf\xb5\xa9\xbd\x94\x40\x97\xc4\xe2\x92\x07\xd8\x4f\xbe\x1b\x60\x01\xbb\xf6\xbd\xf1\xd5\x24\xd8\x5c\x83\xf6\xca\x04\xbb\x02\x3e\x6c\x34\x3e\x9e\x33\x12\x8c\xb6\x8a\x4d\x28\x9d\xad\x77\x16\x92\xbb\x3b\x8c\xbc\x18\xae\x88\x50\x81\xc7\x49\xfc\x84\xcc\xbe\xd3\xae\x54\xc4\x15\x93\x48\xaa\xe0\xf3\x51\x8e\xf4\xee\xc2\x22\xd1\xa1\xed\x92\x75\xac\x01\x3f\xc4\x31\x6f\x66\x39\x5d\x18\xd7\x31\x0f\x1c\x58\xd0\x3a\x56\x13\xe1\xc0\x79\x8b\xc0\x75\xca\xb1\x4e\x78\x2c\x66\x72\x91\x7e\x8c\x01\xa4\x8f\xf0\x99\x47\x0e\x31\xc1\x92\x9b\x53\x78\x73\x66\xa4\x3f\x2a\x85\x27\xd3\x6c\xc3\x37\xbf\xa7\x8c\x2f\x6c\x88\xb6\x1c\x84\xc7\xa6\x7c\x78\xba\xba\xbb\x5f\x0d\x1a\x28\x18\x37\x4c\x22\x6f\xa8\x0f\xa3\x7c\x0f\xc7\x74\x6b\x32\xa9\x44\xb7\xee\xbb\x4b\x6c\xad\x9e\x97\x24\xf0\x24\x2e\x5f\x19\xfb\x38\x60\x56\x23\xe9\x00\x95\x29\x2b\xa7\x89\xb5\x69\x84\xfa\xb5\x6e\xfc\x12\x8a\x89\x14\x08\x9f\x5a\xae\xee\x7f\x9f\xa7\x8d\xa3\x50\x79\xf5\xd9\xed\x9f\x9b\xd9\xe7\x8e\x23\x91\xa2\x83\x78\x95\xe5\xa2\x81\xaa\x2b\x2d\xc4\x94\xa4\x40\x3a\x16\xbc\x65\x59\xe8\xcc\x8a\x6b\xde\x67\xb2\x9a\xb8\x7d\x31\x4d\x63\x0f\x1a\x74\x09\xd3\x91\x50\x0c\x8b\xa9\x02\x41\x7d\x8f\xcb\x98\xfb\xc6\x8d\x60\x24\x88\xfa\x1c\x1a\x12\x78\xfc\xb3\xbc\x55\xcc\xa8\x95\xd4\x40\xc9\xd7\x88\x4f\xcf\x9b\x30\x46\x3a\x42\x80\x71\xb6\xcf\x0d\xe1\x5c\xf8\xa2\xc7\x25\xe9\x4a\x16\xc7\x60\x30\x13\xa9\xf2\xb2\x86\x75\xd9\x8c\x96\x63\x9c\x08\x88\xc8\x00\x09\x2d\xc5\x9c\xdc\x8b\x1f\x0c\x36\x63\xf7\x2c\x74\x76\xdc\x0f\x21\x6b\x2c\x4e\x03\xa9\x2d\x15\x02\x42\x22\xc3\x01\x4f\x02\x8b\xd3\x30\xc1\xc4\xfb\xa1\x51\xc8\x59\xd3\xfd\x28\xa2\x18\xa3\x79\x10\x5c\x7b\xf3\x5d\x3e\xe4\x3f\x1e\xba\x61\x40\xb9\x45\xb9\x5b\x96\x8e\x2f\xb9\x06\x58\x2c\x12\xea\x5e\x4b\xa1\xc7\x6b\x2a\x56\x41\x8a\x08\x7f\xeb\xb5\xfc\x31\xeb\x7d\x7f\xa1\xcf\xc3\x62\xc5\x21\xb1\xe7\xce\xf3\x79\x64\xfe\x59\xcc\x3f\x7c\x11\x0a\x18\xa6\xe8\xdc\x8e\xfa\x1d\xe0\x30\xcd\xb6\xc6\x3a\x64\xdc\x56\x7a\x9a\x06\x26\x1c\x58\x2c\xd6\x49\x88\x65\xb8\x87\xa7\xc7\xc5\xf2\x69\xb5\xd9\x2e\xbc\x6b\x1f\x43\xcc\x13\x27\xa0\x75\x3f\x23\x43\xdd\x7b\x19\xb1\x69\xbd\xf1\x36\x80\xbc\x1a\x06\xad\xb1\x71\xcd\xf5\xa8\x3f\xd0\xa8\xb7\xbb\xc2\x94\x6d\xe0\x1c\x90\x6e\x04\xb7\x04\xa5\x15\x08\xbd\xdc\x5e\x9f\x2f\x87\x24\xa0\x0c\x65\x19\x36\x4d\xeb\xad\x39\x3a\xfb\xb3\x8c\x76\x12\xc4\x56\x31\xe5\xe6\xee\xcf\xd5\xf5\x6e\xfd\xbc\xda\x2c\xee\x57\xbb\x97\xcd\xb5\xe5\x8e\xdd\x61\xc9\xf9\x0f\x3f\x38\x0d\xad\x1c\x47\x8f\x75\xdf\x40\xa1\xd6\x50\x3d\x74\xe8\xe1\x76\x54\x87\xa2\xdd\x20\x99\xd9\xf3\xb0\x18\x3d\x7a\xc7\x49\x20\x98\x0f\x84\x9f\xc1\x55\x3e\xfc\x79\xc2\x24\x40\x1d\xbf\x9d\xb4\x24\xc8\x59\x2f\xa1\xf8\xdf\xff\xf3\xaf\xf3\xff\x38\x0e\x68\x0c\x58\x12\x0a\x82\xf6\x1d\xeb\x65\x3b\x39\xda\x4d\x92\x50\x45\x5e\x21\x6f\xf3\x6d\x41\x18\x1f\xae\x92\x24\x34\x06\xdb\xca\x96\xe5\xe1\x84\x7b\x82\x0f\x28\x7e\x1b\x71\x25\x24\xd0\x98\x13\xed\x15\x9f\x27\xfb\x65\x42\x12\x89\x2c\x18\x07\x71\xb2\x22\x2a\xe3\x17\x12\x31\xdb\xbf\xd9\xfa\x38\xc7\x26\x83\x39\x57\xa3\x3f\x19\x0d\x43\x74\xfc\xea\x53\xa1\x26\x27\xa2\xc4\x4a\xdd\x2c\x8f\x72\x9a\x79\x4e\x68\x64\x50\x62\x08\xe9\x6d\x2e\x9c\x39\x76\x5a\xb2\xd9\xdf\xf0\x64\xce\x49\xd7\x59\x42\x75\x82\x81\x89\x95\x5b\x71\x2a\xdc\xb3\xad\x5b\xa3\x13\x33\x1e\x22\x01\xc9\xf5\xdd\x66\xf9\xf4\xf2\xb8\xdd\x6d\xb6\x8b\xdb\xd5\x6e\xfb\xf3\xc9\x7f\x9c\xd6\xee\x78\x20\xa1\xb6\x90\xee\x06\xf6\xf5\xac\x58\xd6\xf8\xed\x73\x63\xf9\x2e\x77\xf5\x51\xd6\xc3\x5b\x76\xb7\x30\xbe\x93\x98\xdb\x04\x4d\xfb\xaa\x45\xa5\xb7\xe5\xca\x5a\xa8\x3f\x86\x96\x70\x98\x11\xfd\xda\x8c\x24\x71\xa2\x38\xf3\x2d\xa3\xb8\x40\x86\x50\x94\xdf\x38\x2e\x49\xac\x52\xcc\x81\x49\x6c\xf2\xb0\x45\xad\x11\x66\x2c\x89\x95\x6d\xf9\x76\xca\x42\x1b\x54\xc6\xc0\x48\x02\x33\x25\xe7\xdb\x4b\x12\x6b\x41\x5c\x0c\xbb\x16\xea\x97\xf0\x34\x35\x67\x0f\x95\x0c\x37\xc7\x24\x11\x29\x72\xa9\x56\xc7\xfa\x2d\x6b\xa0\x6e\x32\x35\x24\xff\x60\x49\x1a\x4a\x5c\xb5\x96\xb6\xa2\xab\x84\x61\x9a\x73\x10\xd5\xb4\x77\xd2\xad\xc7\x34\x49\xbc\x81\x43\x2e\x89\x0a\x2a\x4b\xbe\xd7\x3d\x9f\x50\x21\x22\xc2\x3c\xf5\x64\x7d\xe7\xf2\x7d\x93\xd9\x2b\x09\x20\xa1\xc4\xbd\x35\x29\xf7\xd9\xbf\x8f\x99\xf7\x47\x13\xc9\x6c\x8a\x64\xd3\x54\x20\xf6\x59\x73\x72\xcd\xd7\xe3\xc5\x21\x63\x00\x2f\x74\x92\x8b\xd7\xaf\x89\xdb\x58\x22\x05\x45\x28\xcc\xbe\x7d\x40\xff\xd2\xb7\xed\xce\x90\x9f\xda\x17\xdb\xe7\xf7\x7a\xfd\x4c\xf7\x53\x15\xc4\xe8\xba\x1b\x68\xd4\x1b\xa6\xcb\xaf\x4e\x77\xba\xf5\x96\xd7\xad\x53\xdb\x46\xa8\xfb\x6c\x3e\x4b\x9e\xa8\x28\x40\x18\x21\xe2\x15\xfc\xd6\x9f\xe8\x48\xa0\xe3\xae\x8f\xfb\x43\xbb\xb8\xff\x38\x6f\xac\x62\x89\x16\xc6\x23\x45\xad\xfa\x58\xf6\x37\xe8\x6d\x79\x3d\xa8\x18\xbb\x91\x46\x5b\xa6\x2e\xdc\x81\x0d\x12\xf8\x23\xdf\xea\x20\x18\x4e\x8c\xa1\x68\x24\x30\x3a\xdf\xbe\x65\xf5\xb8\x4b\x8d\xa5\x01\x23\x88\xce\xb4\xe6\x1c\x9f\xce\x95\xee\xbf\x79\x2f\xdc\xed\x61\xbe\x52\xef\xff\xf5\x77\x9c\x06\x71\x9a\xf6\x50\xb2\xdf\x68\x77\xb3\x34\xe4\x04\x91\xa8\x4f\x3f\x57\xc3\xa9\x99\x86\x71\x80\x8e\x05\x82\x8d\xb2\x4e\x8f\x6b\xc2\x9f\x31\xef\x5a\x4c\x2f\x11\x4b\x61\x7a\x9e\x0f\x1b\xac\x74\xc7\x34\x0c\x04\xf1\xfc\x4c\xf5\xec\x66\x9e\xb2\x61\x46\xef\xc9\x9f\x40\x5b\xdf\xa8\x35\xf1\xf5\x2b\xf6\x48\x62\xd1\xc9\x5f\x80\x30\x69\x09\xd4\x72\x10\x95\xff\x84\x33\x15\xfc\x34\x0a\x62\x84\x1a\xb4\x41\xd2\x18\x7d\x16\x4e\x2e\x19\x25\x94\x59\x9f\xa7\xcc\xf3\x65\x95\x35\x99\x12\xf9\x75\x9f\x4a\x4a\x69\xc0\xb8\xe9\x30\xed\x0a\xee\x8a\xd5\xe7\x1c\xcb\x00\x4b\x29\xb3\xe8\xf6\x57\xbb\xb1\x4c\x33\x4e\x29\x15\xa1\x6d\x06\xc8\xde\xe1\x76\xd2\x55\xdd\x1e\x25\x96\x41\xd5\x4e\x17\x6c\xcf\xac\x67\x4d\x87\xff\x81\x24\x56\x59\xec\x79\x85\x8a\xe7\xad\xcd\x78\xde\xee\xa8\xbf\x71\x26\x52\xec\x4c\x43\x4a\xcf\x5b\xb1\x87\xdb\xcc\x5c\x9a\x38\x4c\x72\x04\x80\xdd\x66\xfb\x3c\xeb\x4e\x60\xec\x6c\xfa\xf7\x51\x38\x5a\xa9\x6b\x68\x03\xb9\xf6\x9d\xab\x12\xea\x47\x68\xbf\xb2\xa8\x32\x51\xaf\x45\x25\x5e\xf6\xe2\xb1\x7c\x17\x4f\xc7\xf7\x4c\x97\x55\x26\xd6\xa5\x86\x6a\x03\x4b\xa1\x45\xdd\x54\x1d\x62\x38\xe5\x71\x10\xa5\x1d\x2b\xd6\x83\x27\xfa\x9a\xf7\x85\x52\x9e\x28\xe4\x5d\x1c\x5a\x8d\x1f\x76\xee\x5d\x78\x96\x98\x9b\x74\xd0\x8b\x04\x43\x55\x5c\xbf\xad\xa6\x71\x9a\x22\x6c\xdf\xbe\xec\x05\xb6\x51\x8e\x84\xac\x66\x27\x7f\x42\x12\x94\x5e\xb0\x78\x97\x1b\x91\xd7\x30\xd8\x11\xd2\x84\x81\x17\x4e\x1f\xd0\x26\xb0\xb4\x35\x63\xe0\x85\x8b\xbe\x67\x79\xd9\x1d\x48\x35\x52\x3c\x14\x59\x31\x75\x47\xd2\x14\x8c\xe5\xd2\x2f\xaa\x8b\x65\xd1\x54\x44\x31\x73\x3e\xf1\x40\x7c\xf0\x82\xb0\x07\x4b\x85\xb2\x2d\x12\xf2\xf8\x75\xc3\x32\x4b\x05\x18\x6a\xef\x4c\xfd\x9a\xb4\x72\xb1\x54\x98\x08\xd9\x11\xb3\xda\x37\xc5\x77\x60\xeb\xf1\x40\x19\xa6\x91\xf0\xdb\xa8\x2a\x2b\xfd\x85\xc6\x07\x4b\x65\xac\xc1\x0a\x97\x15\xf5\x71\x0f\xcb\x32\x2b\x6e\xca\xaa\x9d\x53\x17\xbe\xb4\x12\x4a\xba\x0e\xf4\x87\xac\xf8\x09\x99\xab\xb7\x4d\xde\xa4\xe6\x69\x62\x5b\x34\xb0\x3b\xfd\xbe\xac\x9b\xd1\x5c\xd0\x69\x84\x0c\xa4\x1e\x44\x86\xe9\xf7\x8f\xf2\x63\x36\x4d\x9a\x6a\x69\xac\x23\x9f\x99\x66\xf7\x35\x3c\x2d\xd5\x60\xd0\x5f\x5c\x5c\xfd\xb5\xd9\xf8\xcb\x81\x12\x5e\xa3\xd0\xe6\x70\xee\xf4\x85\x94\x6c\x6a\x22\xc0\x6a\x3c\x36\xdf\x4e\x9e\xca\x24\x02\x69\x14\x6e\x6f\x96\xbe\x88\x97\x9a\x54\x63\x7e\xd6\x46\x36\x96\x13\xd7\xb2\x9d\xcc\x9e\x5f\x04\xa1\xf4\x74\x0b\xcb\x76\xfe\x4f\x7a\xa8\x3b\x59\xed\xe1\x3f\xbe\x3e\x29\x02\x66\x77\xce\x9b\x65\x8f\x2d\xd8\x0e\x58\x2c\xe7\xbe\xb1\x20\x24\x41\xfc\xbb\x5b\x94\x63\x67\x4e\x10\x61\x35\x46\x0e\xc7\xaa\x86\xae\x60\xe1\x0f\x2a\xe9\x49\xb8\x9d\xfc\xc4\xf8\x8d\x08\x62\x2c\x01\xaa\x6a\xb7\x4e\x64\x3f\x00\xa8\x9f\xe6\x95\x83\x99\x88\x88\xc2\xb9\x79\xbb\x7a\x58\x7e\x5b\xdc\xf9\xa4\xbb\x88\x84\xc6\xd9\xd0\x49\xc4\x5e\x95\x97\xd2\xa5\x82\xb2\xd8\x4b\xb1\x3c\x43\xad\x8e\x73\xfe\xa6\x60\x14\x90\xdc\x63\xe3\x33\x06\x6d\x98\x80\x95\xaf\xff\x6c\xcd\x62\x56\x8e\x60\x19\x82\x19\x8a\x7e\xa6\xe7\x62\x75\xb8\xcb\xf3\x2e\xb6\xd6\x8c\xce\xdf\x16\x67\xd2\xca\x69\xbc\x81\xfa\xf5\x0e\x6f\x15\xd4\x87\xf2\x5c\xf9\xda\x8f\x16\x31\xae\x22\xd1\x5a\x5a\x12\x58\xf5\xa0\xee\x93\x70\x6d\x49\x77\x6a\xc8\xf3\x87\xd3\x95\x28\x44\x31\x09\xaa\x45\xac\x03\x5c\x5f\x98\x96\x86\xe3\xfe\x06\x29\xae\x2c\xb0\x43\x0d\x10\xb2\x22\xd6\x16\x1f\x77\xa8\x7a\x50\xc2\x18\xf3\x25\x92\x08\xd0\x68\x61\x84\x99\x86\x93\x2b\x25\x69\x8a\x61\xd2\x9b\xc8\xfb\xb3\x26\x8a\x45\xce\x6d\xdd\x43\x5d\x67\xcb\x72\xbf\x3f\xb6\x11\xf6\xfc\x9c\x4f\x13\xcb\x73\x94\x15\x66\x00\xad\x13\xa9\x14\x89\xf6\xca\xa1\x79\x6e\xf9\x1f\x26\x97\x4f\x95\xb1\x4a\x80\xd9\x67\xf3\xb6\x05\xb1\xef\x05\xb0\xfc\x69\x70\x55\x74\xe8\xa1\x6f\xc7\xbd\x28\x36\x8d\x28\x34\x86\x52\x83\x84\xfa\x14\x6b\x71\x9e\x67\x14\x82\x46\x34\xf1\x88\x8f\xe6\x98\x8b\xac\x82\xdd\xb2\xdc\x1f\x1a\xd8\xa5\x93\x3b\x13\x8c\x8e\x7b\x68\x87\x1b\x9c\x90\x11\x45\xd7\xc2\x96\xeb\x7a\xe0\xda\x68\x0a\xcd\xda\x01\x21\x19\x8d\xad\x1e\x0a\x76\x1e\xc2\xe3\x71\x4f\x7e\x76\xb5\x14\x21\x93\xd4\x53\xac\x20\x51\xe7\xe8\x01\x24\xc4\x96\x2f\xb6\x46\x8e\x7a\xd1\x25\x31\x84\x92\x01\xb6\x3e\xde\x3f\xdd\xee\xae\xa0\xf9\x79\xae\x15\x30\xb9\x0d\xa5\x2c\x07\xeb\xda\x92\x4a\x99\xaa\x75\x29\x8e\x0a\xdb\x4b\x06\x4b\x4d\x69\x12\xf4\x56\x1d\x93\x3c\x37\x55\xb9\x7f\x42\xce\xf5\x9b\x72\xd2\xf9\x22\x74\xc0\x10\x51\x3e\xe8\x58\xf8\x1b\x8a\x2f\x28\x2d\x98\xd0\xa1\xfd\x28\x16\x85\xe0\xdc\xf9\xaf\x03\x25\xa1\x25\x21\x3e\xec\xb8\x6a\x1d\xc3\x42\xcf\x77\x8e\x08\x0d\xd6\x43\x54\xa2\xd0\x43\x41\x56\x26\x80\x33\xe9\xaa\xea\xb7\xfd\x5e\x01\x32\x95\xf1\xa0\x0e\xd1\xf5\x90\x75\xa5\x08\x61\x38\xc7\x70\xe9\x5b\xf9\x71\x5f\x16\xaf\x77\xf5\x75\x56\x1f\x8e\xad\x57\xf4\x0e\x22\xdf\x34\x59\x9e\x3f\x1f\x91\xce\x75\x3c\xa5\x64\xc0\xed\xc2\xbf\x7b\xfc\x3e\x6a\x97\x94\x41\x6a\xf5\x30\x91\x15\x1d\xef\xde\xaa\xa6\xb9\xc3\x61\x9a\x22\x34\x08\x0a\x3d\xf5\xd3\x46\x0f\x2b\x43\x08\xfd\xba\x6d\x7e\xaf\x49\xe4\x7e\x44\x08\x51\x7d\x01\x5a\xec\x48\x30\x9a\x73\x92\x10\x9b\x29\xf2\x9c\xb6\xd3\xd3\xfa\xc8\x5b\x46\x5c\xe0\x9a\xa8\x1b\x91\xc3\x90\xd2\x81\xc9\x28\x26\x68\x01\x46\x85\x5b\x7f\x4c\x87\x18\x49\x37\x50\xec\x45\x95\x95\xc5\xa0\xb2\x28\x69\xc0\xd1\xcf\x6b\xef\x0c\xff\x3e\x7e\x60\x1a\x2a\xcc\xa0\x2d\xbe\xd3\xe4\x37\xec\x5f\x4c\x52\x21\x10\x67\x0e\x3a\x6b\x1e\xb2\xbc\xf5\xb2\x8a\xcb\x08\xae\xe9\xbf\xb3\x67\x34\xb1\x8e\xdc\x34\x7c\x85\xa2\xb1\x30\x50\x5b\x3f\xbd\x3a\x59\xa6\x86\xd9\x69\x29\x59\x94\x60\xd5\xbf\x80\xcf\x06\xd3\x73\x43\xd2\x26\x26\x59\x92\x22\x6e\x6d\xdf\x6e\x01\x7d\x0b\xa4\xe4\x94\xe0\xf3\xee\x6a\x68\x2c\xa7\xab\x2f\x54\x77\x2b\x56\x72\x10\x89\x95\x69\x9d\x96\x2e\x65\x1c\x58\xc2\x2b\xcc\x2f\xd8\x58\xd0\xa2\x8e\x2e\x35\x94\x9d\x97\x8c\x65\xcc\x92\xb0\x53\x42\x19\x75\x55\xca\x38\xb1\x0a\x52\x79\x89\x0b\xb9\x7d\x0b\xe1\x42\xeb\xf9\xc6\x8c\x09\x12\xe6\x1f\xff\xbf\xee\x5a\xb6\x23\xec\x11\xe4\x31\x17\xa3\xd5\x94\xc4\x56\x1a\x72\xd3\xbc\xde\x94\xc7\x0a\x6f\x74\xd5\xef\xdd\x32\x85\x94\x90\x9e\x96\x0f\x0a\x84\xff\x35\x62\x7f\x98\xbc\x2e\x11\x59\x4c\x17\x7a\x7d\x2e\x7a\x9c\x35\xf8\x52\xa6\x21\x27\x7e\xa4\xd0\x17\xba\x62\xa5\x54\x51\xe8\x6a\x8d\x8f\xcb\xcd\x99\xb4\x6a\x3b\xc0\xea\x92\xfb\xea\xdd\xd5\x69\x1e\x08\x25\xa5\xe6\x98\x75\xb6\x70\x8a\xbe\xd7\x72\x72\x5b\x10\x4b\xcb\xd4\xf2\x0b\xc6\x94\x94\xf3\x5b\x81\x8a\x63\x74\x8e\x2d\xa9\xd4\x1a\xaa\xef\x43\xdc\x8c\xd4\x21\xe3\x2e\x97\x70\x9d\xd5\x2a\x3b\xe4\xf0\xe3\xac\x33\x47\x6a\xc7\xc8\x27\x8f\x27\x4b\xa2\xf9\xcf\x14\xf8\xdd\xaf\x21\x50\x28\xc8\x8b\xf5\xc8\x75\x55\x7e\xce\xf3\xd9\x8f\x9f\x13\x42\x81\x2e\xce\xde\xf6\x46\x9d\xb5\xb8\x4c\x11\x90\x12\x24\xb5\x71\x51\xfb\x51\x6d\xa9\xf9\xac\x0b\x5c\x82\x34\x68\x98\x1c\xbb\x18\xce\x31\x0b\x5f\x1a\x8a\x7e\x33\x69\x62\x81\x75\xdb\xe5\x7a\xd3\xf5\x05\xf5\x07\x45\x8a\xbb\x1b\x5e\xc9\x4e\xd3\x51\x06\x4d\x1a\x1d\x72\xd1\xf1\xd8\xdc\x97\xa2\x43\x7c\xaa\x80\x50\xa7\xff\xd5\x58\xa1\x9b\x89\x16\xde\xac\x11\x50\x01\x95\x06\x86\x22\x1a\x20\xf6\xa3\x0a\x80\x8b\x39\xc6\xff\xb8\x1f\x87\x81\x05\xa2\xdb\xf8\xaf\x41\xc9\xcc\x39\x49\x42\xa6\x42\xa2\x71\x07\x7b\x3a\x40\xb1\x78\xfc\x73\x06\xdb\xa0\x42\x46\x9d\xa3\xdb\x9e\x2c\x5b\x97\x65\xbe\xd2\x59\xb3\x23\xa3\xb9\xac\x42\x2d\x31\x63\xbb\xac\xca\xba\x3e\x88\x53\x3d\x5c\xcd\x8a\x24\x76\x11\xb6\x66\xba\x7c\x6f\x06\x08\x95\xb9\xde\x2b\x15\x81\x44\x51\xd5\x17\x29\x7f\x67\x10\x14\xe5\xf6\xfe\xb2\xfa\x09\x55\xde\x16\xc5\x89\xcc\x67\x05\x14\xa3\x96\xac\xba\xf5\xb3\xc5\x71\x00\x0b\x55\x8c\xf2\xc8\x8c\x2a\xca\xf9\xc9\x99\xff\x6d\xa7\xe8\xc0\x14\x8b\x39\xc6\x96\xeb\x1f\xdb\xdd\xdd\xe3\x8f\xdd\xf6\xe9\xfb\xea\x71\xd3\x1f\x95\x58\x8a\xb8\xba\xdb\x5e\xdf\x3d\xae\x9e\x9f\xba\x03\x49\x8a\xd4\xf5\xba\x0d\xa2\x51\x02\x70\x51\xc9\xac\xa9\x7c\xdb\xe8\x0c\xe9\x95\xff\x25\x68\xe8\x53\xa5\xb7\x62\x0f\x17\xb4\x5c\xfa\xf0\xc7\xa7\x96\xdd\x19\xb8\x50\xe8\x95\x1c\xba\x3a\xf3\x1a\xaa\x87\xb2\xe8\x2a\x70\x2a\x16\x96\x2e\x12\xe1\x7b\xf6\x42\xdf\xe1\xb4\xf3\xed\x0e\x8f\x25\x66\x65\xdd\xe0\x24\xe4\x96\xdc\x0e\x15\x33\x5d\x7a\xe3\x77\x3e\xca\xf4\xe6\x26\x73\x3d\xe1\x01\xfa\x70\xd0\xbc\xed\x5c\xd3\x7f\x77\x39\x41\x3c\xae\xe3\x6d\x32\x75\x13\x19\x63\x01\xa0\xe3\x3a\x3b\xca\x3c\xab\xdf\xa6\x85\x59\x95\xc6\x96\x9b\x73\x7b\xb7\xf0\x67\x4d\x95\xc6\x36\x70\xfc\x7c\xbb\x97\xc7\x3b\x5f\x8c\x55\x82\x08\x34\x48\x3f\x56\x9b\xed\xdd\xe3\xed\xee\xee\x71\xbb\x7a\xfe\xb1\xb8\xef\x8e\x47\x0c\xc1\xb6\xdb\x61\x98\x7d\xf6\xd8\xe3\x1b\x10\xc0\x03\xd5\x15\xeb\xcf\xda\xe1\x94\xe4\x1c\x6f\x70\xf9\x56\x95\x45\x59\x2f\xcb\x0b\x40\xd3\xf3\xf9\x2c\x21\x0e\x3b\x21\x35\xdb\xdd\xb2\x2a\xb4\xdd\xaf\xc7\x23\x95\x4e\x7c\x23\x2b\xc6\x1c\xc8\x62\x8b\x7a\x4c\x1d\x68\xbe\xbb\x1f\x65\x64\xe0\x8b\xe5\xcb\x4b\x6c\x3f\x4c\xe9\xd0\xd2\x6b\x98\xea\x52\x1b\x9c\xd2\x91\x41\x5d\x82\xba\x01\xd8\x77\xf3\x4d\xc7\xdc\x33\x9b\xe1\x1e\x71\x2e\x74\xc4\x94\x4e\x02\x4c\x87\x5c\x3d\x3d\xbe\x6c\x76\xeb\x65\xbb\xdc\x76\x3f\x9e\x57\x4f\x36\xa3\x8b\x74\x1e\xbb\xb0\x3b\xa3\x88\x53\x32\x64\x50\x18\xc4\x1e\x7d\x8d\xa5\x77\x82\xa6\xee\x90\x82\x80\xa7\x96\x31\xd5\xbe\x3d\xdc\x69\xbb\xd3\x43\x64\x39\xf4\x2d\xfb\x8b\xc8\x46\x72\x11\x4c\x01\x0d\x23\x0b\x22\x42\x21\xcf\x11\x43\x86\x32\x51\x82\x8c\x5c\x56\xbf\x6f\xf5\xd9\x54\x62\xb4\xe4\xc7\x8f\x6d\xa2\x04\xb1\x25\x4e\x95\xc0\xe7\x02\xda\x2d\xa8\x1e\x14\x8d\x66\x1e\x64\xf0\x5f\xb6\x90\x36\xaa\xa7\x29\xc3\xb8\x71\x54\xc0\xcf\x56\x6f\xb1\xeb\xbf\xef\x46\xa4\xa8\x96\xb8\x7a\xbc\x6e\x27\xfe\xf6\xee\xc1\x17\xf2\x75\x40\x13\x3d\xe0\xaa\xfd\x0d\x72\xc2\xff\x48\x5a\x01\x19\x79\x3c\x21\x4a\x5f\x5c\x48\xd5\xea\x30\x51\x48\xd7\x86\x91\x63\xbb\xc3\xcd\x81\xe7\x75\xa8\x02\x0b\x72\x10\x7b\x18\xe4\x45\x74\x14\x29\xdc\x91\x1f\xa0\xae\xc5\x2b\x6c\x5a\x3f\xb0\x5c\xbe\x89\xa2\x80\x9e\xae\xff\x8b\xba\x8d\x8e\x12\xca\xa4\xf7\x96\x90\xb4\x67\x9c\x7b\xd3\x2c\x26\xd8\x31\x60\xb2\x4f\xd0\xe7\xde\x9e\x66\xb1\xc4\x58\xd3\xed\x85\x8b\x42\x5f\x9f\x93\x74\x8e\xd3\xbb\xfe\x97\x2e\xe1\xb9\x2e\xf3\xd3\xf2\x58\x37\xe5\xbe\x87\xd2\x69\xa6\x65\xa0\x7a\x18\xee\xb2\xcc\x3d\x62\x6a\xd6\x2b\xd5\x3c\x4a\xcc\x70\x3b\xb4\x3c\x1b\x6f\xd9\xc1\x57\x99\xc6\x9f\x87\xc7\xb1\xe8\x84\x75\x73\xb8\x1a\x13\xa1\xf9\x41\x89\xc4\xbe\xb2\xe7\xc5\x76\xb5\x43\x8d\xe0\x76\xf5\xf9\x3b\xe4\xda\x76\x63\xef\xb3\x62\x50\x36\x44\xd0\xea\x65\xb0\xaa\x8e\x45\x88\x00\x67\x5f\x14\x2c\x2b\xdf\xbd\x62\x55\x7c\x2e\xcc\xaa\xf9\x1d\x50\x27\x9c\x20\xb6\x69\xf1\x5a\x65\xe8\x5d\x5d\x43\xad\xaa\xec\x30\xb0\xed\x3a\x89\xad\x32\xba\xfb\xae\x1e\xdd\x32\x3f\x6d\x93\xd8\x26\x54\x94\x28\x1e\xc4\x2f\xe8\x84\x4c\x99\x4e\xa4\xa5\x97\xde\x67\x5a\xd4\x4e\xcb\xcc\xf6\xab\x82\x6d\x78\xcf\x8a\xd7\xc9\xd4\x49\x94\xd5\xce\xb0\xca\x77\xbb\x66\x30\x6f\x45\x20\x8d\x2b\xff\x63\x25\xef\x4e\xcf\x65\x98\x2f\xd5\x3f\xb5\x4c\x22\x6c\x01\xdd\xe3\x95\x9f\x5d\x50\x3f\xe3\xbe\x69\x65\x6c\x35\xfa\x88\x3d\xd0\x57\xd0\xd4\x23\x2d\x77\x37\x4a\xf7\xaa\xb7\x38\xc5\xed\x1a\x7c\x32\x73\xf5\x3c\x0d\x21\xc1\xb9\x73\xb7\xbd\xba\xdb\x6e\x86\x7e\x9e\x86\x88\x63\x6c\x2a\xf4\xbe\xa3\x72\x64\x1a\x92\xd0\xe2\x86\xdb\x25\xfe\x70\xde\x8d\x3c\xbe\x63\x30\x89\x72\x8a\xb1\xf2\xc9\xd8\xdc\xd3\x62\x3f\xd3\x29\xa1\x8d\x4e\x52\x31\xa0\xd5\xba\xb0\xec\xec\x2b\xf4\x77\x6f\x00\x90\x38\x0b\x05\xc3\xde\xaa\xf2\xc3\x92\x05\xc2\x23\x7c\x3c\xc3\x7b\x56\x67\x65\xf1\x58\x36\x08\x88\x1c\xf4\x94\x40\x10\x00\x42\x32\xff\xf3\x71\xfb\x72\x79\x7a\x43\x18\x24\x58\x06\x16\x5a\xaf\xf6\x56\xef\xf0\x12\xee\x6d\x3c\x95\x21\x0c\x63\x84\x5f\xec\xc5\xe7\xba\xfc\xe8\x7c\x4e\x08\x15\x93\xce\x74\xff\x38\xa7\x15\x77\x83\x48\x00\xa2\x7b\x13\xd8\x7d\x8a\xc8\xf2\xeb\x76\xbf\x1e\xad\x69\x20\x24\x40\x8c\xf9\x0c\xdb\x15\x10\x2d\x51\x3e\x63\x57\xab\xa6\xfc\x6d\x4e\x65\xfc\xdb\x28\x0a\x9c\xbc\xb4\x4d\x88\x8e\xcc\x20\x50\x26\xc1\xf6\x71\x14\xaf\x93\xf2\x04\x50\x48\xb1\x1d\x68\x2f\x3e\x97\x3f\x97\x6d\xc0\x6a\x93\xcc\xf7\x50\xd7\xdb\x37\x51\x74\xe7\x30\x56\x96\xe9\xbe\x7c\xdd\x0e\xa8\x54\x46\x0f\xf2\x8f\x34\xdb\x19\x30\xa2\x10\xd2\x74\xb7\xdf\x83\xce\xac\x66\xe4\x25\xa2\x5c\x06\x2c\xb2\xb1\x18\x4e\xdf\x67\x51\xe8\x72\x8f\xea\x34\xa2\xd0\xa2\x9c\x3c\x0c\x63\x89\x68\xa7\xc9\xc3\xdd\xe3\xee\xe6\xe5\xf1\x7a\xb7\x78\x78\x7a\x79\xf4\xfe\x25\xb0\xd8\x20\x91\xdc\xad\x6d\x02\xba\xca\x10\x51\x32\xf9\x0c\x0c\x2c\x36\xb5\xfe\x10\x87\x6d\x39\xc9\x67\x00\x27\xb6\x7f\xc1\x88\x3c\x97\x42\xfd\x7a\xf6\xed\x21\x10\x87\x91\xcd\x74\xf8\xb7\x73\x2c\x74\x8d\x88\x91\xa7\x22\x3f\x2b\x6c\xfa\x1f\xf1\x18\x51\x7a\xc6\xae\xb3\x09\x8d\xe4\xf8\xc6\x62\x11\xa1\xbf\x59\x1f\xf7\x7b\x57\xa8\xea\x25\xa7\x19\x24\x24\xc1\x86\x73\xdb\x96\xa1\xdb\x90\xf5\x4e\x4f\x36\x0f\x48\x14\xd3\x2e\xe9\x8b\x1a\x49\xd9\xeb\xdb\xa5\xf7\x9e\x06\x00\xae\xab\x7f\xa2\x01\x31\xc8\x94\x41\xca\xac\x9c\xfb\xe7\xe7\xe7\xe4\x52\xa9\x31\xe8\xcc\x77\x52\xe0\xce\xb3\xf8\xd2\xa4\x80\x08\xbb\x3e\xad\xb5\xa8\xc4\x1e\x9a\xde\x2a\x83\x0c\x15\xa2\xc0\x9e\xde\xc7\x88\xdb\x99\xc0\x14\x64\x2c\xd0\x41\x2e\xad\x91\xe8\x5e\x93\x94\x29\xb6\x6b\xb4\x1f\x6f\xf5\xfc\x7c\xdf\x46\xb8\x03\x6a\x4f\x06\x52\x85\x98\x67\x45\x24\x4f\x73\x94\xb0\xcc\xb3\xc3\x85\x04\x8c\xff\x49\xeb\x67\xba\x4a\x7a\x59\xc0\x09\x37\xf1\xee\xae\x15\x35\x02\x3a\xb0\xf3\x95\xa8\xc1\xb5\xba\x57\xbe\x7b\xa0\x3f\x93\x12\xca\xe3\xd7\x87\xcc\x6b\xe7\xed\xee\xa0\x20\x45\x74\xf8\x7e\xde\xfa\x81\x02\x81\x36\x45\x42\x13\x06\x41\xb0\x0b\xa1\x8b\x39\x41\x2b\x8d\x19\x61\x68\xde\x9a\x33\x97\x0a\x20\x4e\xd1\xe1\x84\xcf\x06\x55\x57\xd1\x81\x69\xef\x00\x9b\x4b\xc6\xfb\x99\x09\xb4\x9f\x4f\xb7\x50\x04\x6e\x21\x8f\xef\xd4\x70\x4b\x7c\x95\xa9\x72\x55\xf4\x0d\x7e\x60\xd2\x14\x51\x8f\xff\x5b\x36\x58\x21\x1f\x80\x3e\x4d\x40\xa4\x65\xa1\x13\xd5\xaf\x65\xb9\x97\xa2\xb1\xcc\xa2\xa3\x33\x9b\x40\x5b\x21\x9a\xd6\x93\xbe\x71\xa2\x2c\xfe\x43\x9b\x30\xa4\x48\x56\xb4\xad\xca\xa2\x6b\xa8\x34\x21\x49\x70\x93\xad\x9b\xf2\xb0\x81\x3c\x3f\xab\x30\x98\x30\x51\x41\xc7\x7c\x2c\xaa\x66\xa0\x62\xc3\x4c\x08\x04\x63\x57\x9b\x33\x9c\x42\x10\x0c\x61\x31\x76\x44\x76\xc4\xdc\xae\x0b\x65\x5b\x3a\xee\x7d\x3f\x8e\xc7\x3c\xe8\x69\x1c\xb2\x3d\x3c\x64\xc5\x88\x84\xa7\xbf\x1f\x22\x42\xc4\xb4\xf7\x02\x5d\x5f\x9b\x32\x43\xc0\x6a\x79\xca\xb2\xaa\x5a\x53\x66\xf7\xf3\x51\xd4\x64\x22\x16\x23\xf2\xfc\x61\xf1\xe7\xf3\xd3\xcb\xe3\xf5\xa6\x3b\xa0\x08\x86\x53\x42\x6b\xd7\x3d\x38\x02\x62\x1a\xca\xa9\x07\x93\x3c\xc2\x67\xb3\x3d\x56\xc5\xb2\xcc\xcb\x49\x04\x69\x68\xc2\x31\x9b\xb8\xba\xbf\xf2\xbb\xaf\xa1\xc2\xd8\x32\x3a\xc2\x0b\xbc\x1b\xe2\xc0\xe6\x33\xdd\xda\x86\x2a\x8e\x65\x3c\x2b\x68\x82\x1f\xc3\x1f\x8a\x23\x02\x23\xd6\x3e\xb8\xdf\x2e\x7f\x5e\xca\x55\x9a\x98\x09\x66\xb9\x0d\xf2\x5c\x54\xb6\x5d\xe9\x57\x96\x97\xa3\x9e\x25\x13\x27\x04\x39\x56\xcb\x22\x77\x50\x3f\x7f\x40\x85\x74\x58\x91\xeb\x3e\xc0\xe8\x22\x89\x4c\x62\xab\x7e\x54\x63\xd2\x75\xd3\x94\x15\x06\x45\xdd\x5d\x27\x4a\x5b\x2e\xff\xe3\xc9\xd6\xa0\x27\xd3\x27\x95\x0c\xbd\x83\x36\xcc\xb2\x4d\x11\xfe\x80\xd1\x69\xea\x99\x51\x36\xbd\x7e\x28\x33\x82\xd0\x14\x83\xfc\xfd\xe7\xa6\xec\xfa\x94\x0c\x5a\x59\xcb\xd5\xf4\x31\x54\x5b\x1a\x9b\x14\x23\x44\x48\x5c\x4b\xa3\x8d\x21\xba\xdf\x6b\xcb\xe6\x65\x51\xa3\x3b\x17\xad\x46\xbd\x5b\x33\x7e\xbf\x32\x25\xe8\x0a\x1e\x6b\x8f\x14\xf5\xdc\x20\xe3\xeb\x49\x41\xb1\xba\x91\xd5\x43\x51\x9b\xeb\x63\xf7\x38\x52\x27\xe8\x1a\xbc\xe6\xa5\x14\xf9\xd5\xd9\xbc\x95\x5a\x5b\x4a\x61\x5c\x38\xeb\x0a\xf6\xd9\x71\x5f\x4f\xaf\x62\x2c\x13\x4e\x56\xb7\x1b\x5b\x59\x35\x97\x28\x36\x8d\x22\xa9\xc5\x64\x43\xa1\xdb\xcf\x75\xa1\x0d\xd5\xe8\x40\x84\xb6\xbe\x2a\xaa\x57\xf0\x01\xee\x64\x4c\x98\x44\x49\x27\xf8\x7f\xac\xc9\xf4\xb8\x62\xb8\xe4\xd4\x59\x2c\xe9\x06\x80\x51\x18\xef\x35\x6f\x59\xa5\x31\x47\xb8\xea\x67\x80\x21\x0c\xf5\xa0\xee\x9f\x96\x77\xea\x3c\x29\x8b\xa3\x78\x10\x84\x14\x6c\xff\xff\x69\x39\x25\x9d\xe0\x41\x18\xda\xd6\x34\x1f\xf2\x6d\x45\x9e\x67\xa0\x2d\x57\xee\x71\x58\x7d\xef\x0c\x3c\x0f\x48\x28\x54\x57\x4c\x18\xd9\x18\x1e\x10\xca\xb0\x8f\xd2\x2b\x9e\xdc\xdc\x3d\xde\x6d\xbe\x75\x47\x63\x8d\x3e\xfb\x9d\x2a\x8b\x72\x9f\x5d\x44\xe2\x1c\xa7\x10\xee\xfe\x8e\x29\x35\x58\x07\x79\xcf\xaa\xe6\x28\xf2\x55\xd1\x64\x4d\x06\xb5\x47\x88\xfa\x51\x2a\x44\x0a\x74\xdc\xa9\xa1\x42\x64\xe1\xe8\xdd\xf2\x80\x07\x06\xa3\x9a\xab\xac\xd1\xc3\x0c\xdf\xb9\xe7\xc0\x03\xce\x54\x8a\xaa\x7b\x55\xf9\x0b\x2a\x6f\xab\xbb\x38\x62\x90\xeb\xe7\x01\xe7\x8c\x44\x3d\x11\xd4\x4e\x0c\x66\x2b\x0f\x78\x1a\x7a\x1d\x9f\xbb\x06\x5a\x97\xf5\x15\x5e\x9e\xef\xe6\xbf\x5d\x1c\x58\x1d\xa7\x7d\x56\x6c\x8e\xfb\xbb\xe5\x13\x76\xf6\x24\x2f\x9b\x6b\x7f\xba\x98\x32\x1f\x66\x58\x79\x81\xeb\x69\x2b\x09\x0f\x92\x80\xc7\x2e\xb3\x70\x5d\x1d\x5f\xcf\x25\xb5\x78\x90\x08\x8e\x39\x17\xcb\xd4\xb7\xd0\xf5\xb9\x9a\x0e\x0f\x52\xc6\x11\xf3\x5a\xc0\x47\x7b\xeb\xc3\x66\xe7\xdf\x96\x79\xcf\xa6\xd2\xbf\xc6\x1f\x23\x4d\x23\x14\x09\x3b\x88\xd3\x75\x66\xe6\x91\x50\x3c\x48\x81\x04\x29\xe6\xf3\x9f\xb7\xdf\xae\x17\x7f\xf9\xb7\x90\x1a\xeb\x9f\x3b\xa9\x70\x6c\xb0\x44\x08\x2d\xb5\xbe\x49\x48\x27\x27\x92\x3c\x8d\xf4\x20\xba\xee\xf4\xb1\x79\x20\x13\x81\x95\xa5\x7d\x56\x1c\xeb\x6d\x79\x44\x29\x89\xbf\x9d\x2e\xd1\x28\x04\xeb\xbe\xb8\x94\x0a\xbd\xa3\x87\x52\x43\xbe\x2c\xcb\x4a\x67\x45\x4f\x34\xc4\x03\x95\x04\x88\x78\x47\xc7\x6a\xb8\xcb\xd9\x8d\xec\xae\xf8\x09\x59\x37\x36\x55\x48\x1c\xb0\x7d\x83\xab\x32\x6f\xde\xae\x17\x77\xcb\xa7\x4b\x75\xe4\x7f\xfa\xaf\x3b\xb7\x56\xb6\xef\xcc\x32\x2c\x34\xdb\xb2\xbd\xee\xf8\xc5\x40\x40\xd1\xde\x2d\xc5\xe1\x00\xda\x96\xf0\xda\xa0\xfb\x22\x35\x8b\xff\x5d\x22\x07\x41\x44\x56\xbc\xda\x1a\xe3\x79\x55\x91\x07\x20\x49\x9a\x7a\x28\x5a\x6b\x17\x7a\xae\xf0\x25\x6a\x5b\x37\x03\xa4\x0c\x0f\x4c\x64\xa1\x2f\x56\xa3\xa9\xe3\xb3\xe6\x61\x60\x20\x95\xdd\x06\xfc\xad\xcc\xd1\x67\x10\xdd\xf1\x30\x52\x1e\xfd\xb1\x39\x15\xcd\x1b\xd4\x0e\x81\x6d\x55\x60\xc7\xbb\x41\x18\xc6\x06\xb1\xbe\xc8\x2a\xb0\xae\x7a\x86\x20\x7f\x1c\x02\x84\xe1\x9a\xb2\x52\xf0\x0c\x45\xd3\x6e\x3d\x7e\xbb\x09\x89\xb2\x2a\xd2\xe0\xcb\xca\xcf\x4e\x15\xd3\x1d\x8f\x12\xd0\xa9\x97\x59\xae\xba\xbf\x2a\x8a\x8c\xc4\x8f\x3f\xb7\xfe\x4f\x94\x49\x74\x5f\xb3\x1a\xfd\xdf\xa1\xc3\xdf\x0d\xd1\x0c\xa3\x98\x5b\xb4\x87\x03\xa7\x84\x87\x2c\x14\x89\x15\x87\xb9\x86\xba\xa9\xca\x53\xb7\x21\x86\x8c\x44\xb1\xc5\x5d\xc9\x4a\x14\x73\xb2\x12\x3c\x64\xda\x36\x3b\x8c\xa8\x5c\xb7\xa5\x87\xce\x9e\x27\x28\x78\x18\x27\x71\x64\xf9\xfc\xb3\xe2\x15\x61\xf4\x76\x0b\xf1\x97\x8d\x85\xb1\x21\x47\x95\x69\xc4\x50\xfa\x03\x09\xb3\xc4\x8f\x36\x02\x5a\x96\xfb\x7d\xfb\x61\xe4\xd4\x8f\xe0\x61\x92\xa6\x91\xa3\x13\xba\xbd\x5a\x0c\x0b\x23\x3c\x4c\x8c\x65\x07\xec\x5d\xbe\xcd\x66\xf5\xb8\x5d\xfd\x31\xc6\xd0\xf0\x30\xa5\x09\x26\x11\xf7\xa2\x6e\x6f\xb1\x3c\x9c\xfc\x7d\x48\x1d\x63\xfc\x78\x38\x56\xaf\x80\x8a\x59\xfb\x73\x1e\x3a\x1e\x2a\x9a\x18\x07\x5f\x5e\x97\x79\x6e\xa7\x50\xdd\x33\xc6\xf3\x50\x31\x99\x38\x69\xa4\x4d\x73\xd4\x50\x34\x3e\xcf\xeb\x06\xe8\x40\x80\x65\x7d\xff\xbc\xea\xa0\x86\x3c\xd4\x3c\x21\xa9\x3f\xb3\x65\x85\x36\x67\xa9\x1e\x37\x16\x42\x83\x7c\x8f\xbb\xfa\xed\xd8\x69\xdb\x24\xdd\x53\x02\xb7\x8c\x5e\x0d\xd4\xcd\x8d\xc8\xf2\x36\x80\xb8\x3d\x9e\x7e\xbe\x41\xb1\x69\xca\x76\x41\xfb\x8b\x42\x6a\x6c\x65\xbf\x6c\x4d\x14\x1a\xc9\x27\x73\xe9\xa2\x86\xa3\x1c\x06\x7a\xba\x39\x26\x92\xd0\xe7\xc3\x2d\xd1\xdd\x43\xe8\x07\x1b\x48\x91\x66\x02\x71\x61\xa3\x1e\x60\x4e\xc2\x88\x52\x31\x90\x25\x19\xd3\x29\xf9\x41\x9a\x63\xa4\xf2\xe7\xfa\xbf\xfc\xef\x48\x24\x30\x61\xda\x3e\x96\xd5\xac\x99\xfc\x86\x30\x1b\x9e\x6f\xdd\x1d\x66\x65\xb1\x81\xea\x3d\xeb\x2f\x1d\x41\x8a\x88\x0d\xe7\xb4\x5e\xcf\x94\xa5\x66\x23\x27\x4e\x68\x94\xf8\x36\x68\x8b\xbd\xfa\x0e\xe3\x54\x2d\x27\x94\xa5\xb1\xb3\x3e\x0e\xee\xeb\xbd\xa9\x01\xcb\x06\x27\x34\xb1\xb1\x00\x5a\x01\x64\x27\x6f\x0d\xfa\x20\xcc\xe6\x84\x45\x11\x6e\x32\x3a\x33\xe3\x9e\xbd\xd1\x3a\x25\x8c\x73\xea\x48\x79\xbb\x3e\x74\x57\x44\x9a\xac\x4f\xc2\xb4\x55\xe6\x7f\x10\x56\x37\xdd\x92\x48\x7c\xfd\xc8\x5c\x05\x98\xba\xb0\x4b\xb3\xa3\x75\xfd\x2a\x81\xd7\xfe\x28\xb2\xf0\x88\xba\xce\x5e\x8b\xab\xbe\x0b\x6e\x1e\x9f\xc8\x09\x37\x14\xf1\xa7\x76\x1b\xb3\x6c\x63\x22\xbf\x2b\xea\x23\x2a\xe5\x5b\x64\x86\x1b\x1b\x27\x14\xbc\x80\xdb\xf2\xdb\x0e\x74\xd6\xec\xa2\x3f\x46\xef\x24\x4e\xb5\xd4\x5d\x92\xa8\xc9\x7c\xc6\x7c\x09\xd9\x59\x9d\x6b\x72\x27\x49\x98\xe2\xc2\x5c\x68\xbd\xfa\x04\x35\x3e\x6f\x12\x33\xed\xf3\x38\xa7\xb5\xa8\x9b\x9f\x59\x31\x9d\x7f\x22\x88\xb5\x85\xf2\xa1\x3e\xd3\xae\x8d\x43\xce\xc6\x24\x96\x5c\x51\xd4\x75\xa9\x32\xd7\x65\xb5\x15\xf5\xb4\xbd\xd8\x0f\xd7\x06\xd3\xb3\x5d\x33\xdd\xc5\xd2\xf6\x57\xe5\x99\x79\xc6\x15\x4e\x14\x24\xca\xd6\x54\x0e\x59\x23\x72\xdf\x99\xe4\x8e\x6a\xaa\x4d\x84\xe4\x21\xb2\xde\x1c\x65\xe3\x95\xf9\xe6\xdf\x9e\x8e\x93\xc0\x12\x51\xd4\xc7\x3d\xac\x07\x36\x93\xe8\x54\x8a\x68\x64\x4f\xbc\x14\xf1\x8d\x15\x2e\x9a\x2c\x24\xa0\x04\x7d\xe3\xa5\xd8\x1f\x44\x3b\x8b\x50\x9c\x5c\x65\x9d\x08\x31\x27\xc0\x44\xac\x7d\x29\xdc\xd3\x81\x76\x07\x45\x90\x3a\x88\xd4\xfd\xf2\x79\x98\xef\xe6\xc4\x44\x0c\x01\x2c\x36\x4a\xbc\x12\xc5\xaf\x61\x14\xc9\xa3\x40\xa4\x88\x4b\xc6\xd6\x0a\x9f\xcd\xfe\x09\x19\x2e\x54\xb7\x53\x8d\xee\x36\x0a\x69\x34\xa4\xf4\x1f\x6a\xb5\xf2\x88\x44\x14\x02\xdf\x48\x3c\x56\x0f\xe0\x11\x89\x0d\xf6\xe3\x39\x3f\x8c\xb4\x6f\x25\x2b\x8e\xfb\x19\xa7\x3b\x22\xc2\x66\x35\x6a\x68\x2c\xc3\xc7\xf4\xb8\x66\x18\x3e\x3f\x2c\x1e\xbf\x2d\xb6\xdb\xc5\xe3\xfa\xf9\xe9\xcf\xfb\xd5\xe3\xe2\x87\xbf\x5a\xa4\x13\xed\xb6\xa7\xeb\xf2\xf8\xba\x98\xa4\xfb\x79\x14\x99\xae\xfc\xef\x71\xc2\x4f\x1f\xe0\x6a\xea\x0b\x4b\xe2\x37\xd5\x63\x1a\x9a\xe1\x88\xb2\x84\x39\x8f\x6e\x55\x2b\x71\x00\x6f\xf9\x8e\xc3\x9e\x0c\x37\x98\x69\x9b\x13\xff\x51\x36\x33\x4d\x08\x3c\x62\x10\x23\x0c\xf8\xea\x78\x5a\x5d\xad\xb6\xcd\xf0\x2b\x46\xdc\x50\x84\x98\xa0\xaa\xbc\x2d\x4f\x8e\xd6\x4d\x14\x93\x20\x71\xa4\x9c\xd5\x63\x79\x5f\x16\xaf\x48\x45\x34\x24\xd2\xf3\x23\xa9\xfd\x42\x42\xeb\x11\x9b\xe3\xa0\xc3\xd6\x8d\x4c\x22\x82\x4b\xb7\x9d\x38\x37\xc7\x42\xfd\x31\x3a\x4f\x1a\x5a\x36\x24\x81\xcd\xb0\x93\x26\x0e\x7f\x8a\x34\x8a\x13\xcb\xb2\xa1\xd1\x9d\x9e\xe9\x6a\xe5\x91\x48\x8d\xa7\xa1\x78\x84\xcf\x66\x53\x88\x43\xfd\x56\x36\xe7\xe8\x11\x1e\x09\xb0\xfe\x24\xbe\x9d\xf6\xe1\x9e\x71\xf5\x0d\x1a\x14\x78\x24\x53\x4b\xfd\x26\x8e\x4d\x79\x75\xac\xfc\x2a\x89\x14\x0b\x02\x2b\x91\xb1\xcb\x07\xb2\x33\x3c\x52\xb1\xf5\x3d\xad\xa7\xbd\x2d\xcf\x97\x5f\xa4\x03\x69\xbd\xe0\xac\xd0\x8b\x42\x5b\xd0\xcd\x3f\xc1\x43\xf3\x48\x73\x13\xb0\xa1\xdb\x6f\x1b\xcf\x7e\x13\x30\x9e\x15\xf4\x78\xa4\x53\x5b\xaf\x56\x96\xaa\x66\x71\x2e\x42\xc7\x23\xad\xac\x30\xbf\x5d\xed\xcf\x8d\xdc\x20\x74\x1b\x55\x2a\x64\x36\xda\xe1\x23\x08\x03\xe3\x69\xe0\x8a\x0a\x84\x76\xc8\x85\xf3\x64\x15\x8f\x4c\x18\xf9\x2e\xb6\xb5\xa8\xa0\x68\x5e\x8a\xd6\xe8\x76\x5b\x5e\x64\x18\x10\xe1\xfd\x9f\x41\x21\x96\x47\x26\x09\x90\xeb\xac\x56\x1d\xd7\x8e\xc8\xc7\xf9\x1e\x4e\x83\x88\x47\xdc\xcb\xf1\xbf\x7b\x3e\xb1\xaf\x64\xa0\x38\x0d\x12\xa6\x54\xaf\xd8\x87\x82\x09\x13\x73\x42\x43\x4d\x12\xeb\xfd\xbf\x97\xbf\xc0\x4b\xaf\x6c\x10\x32\xf6\xc7\x97\x16\x63\x4e\xec\x98\xd3\x10\x34\xb6\x63\x5d\x3d\x2d\xbf\xca\x9b\x50\x42\xb5\x57\x5e\xfd\x91\xbd\xce\x9a\x3a\x4a\xe2\xff\x97\xb5\x37\xeb\x6e\x1d\x37\xba\x40\xff\x4e\x3f\xe4\x81\xe0\x00\x80\x8f\xb2\x2c\xfb\x28\xf1\x14\x49\xee\xd3\xfd\xf5\xca\xd2\xc2\x50\xb0\x19\x53\xa4\x42\x52\xb6\x95\x5f\x7f\x17\x0b\x00\x27\xd1\x3e\xb9\xeb\xde\x97\x9c\x8e\x09\x52\x1c\x80\x42\x0d\xbb\xf6\xb6\x9b\x51\x5e\xd6\xcd\x5e\x14\x7a\x8f\xc0\xd0\xbd\x75\xd5\x7f\xf3\x83\x54\xe0\xdb\xcf\x87\x6d\xfe\xdd\x17\x8f\x23\x65\xb5\x41\x5c\x9b\xe4\x2c\x72\x97\xc6\x31\x49\x99\x6d\x2f\x87\xcf\x75\x6b\x9a\xfd\xe4\x8f\x93\x34\x40\x6b\x2e\x5c\xf8\xe6\xbc\x29\x7f\x54\x44\xd8\x82\x65\x63\xdb\x1b\x94\x13\x76\x7c\x1c\x7e\x04\xf0\x78\xcc\x80\x73\x2b\x0e\x18\x50\x74\xd7\x30\x26\x31\x9e\x75\xff\xab\x7a\x35\x8d\xa9\x49\x31\x73\x75\xaa\xfb\x84\xb8\xbf\x04\x0b\xd3\xc0\x21\x85\x17\x9f\xd9\xc4\xa2\xc5\x2c\xb6\x7e\x72\xbb\x55\x94\x4d\xcf\x18\x35\xfb\x65\x18\x70\x74\x30\x90\x66\xe9\x7f\xa9\xd1\xd2\x98\x87\x1c\xaf\x2f\xcb\xcf\x41\xc7\x07\x8d\x79\x62\xf3\x4b\xc7\x5c\x28\xf0\xf4\x75\xc3\x76\x4e\x1a\x73\x03\x98\xc5\x76\x5f\x27\xcf\x77\xa7\xaa\x28\xdf\xa7\xbb\x59\x9c\x12\xdb\x94\xb4\x7f\xc9\x9c\x42\xcb\xbc\xf7\x18\xa7\x94\x23\x09\xe8\xbf\xcb\xd1\x2a\x8b\x05\x51\x81\xf4\x4e\xf6\xb6\xcc\x75\x2f\xf3\x52\x9e\x6c\x12\xb6\x1b\xaa\x13\xcf\xdd\xe7\x16\xc4\x04\xaa\x4c\x63\x19\x58\x65\x6e\xa1\xf5\x35\xbc\x5b\xb3\xe5\x4f\x97\x34\x42\xc1\xe5\x27\x51\x29\xc8\xff\xb8\x7d\xfa\xe3\x8b\x52\x43\x3b\x14\xac\xb2\x67\x57\xae\x99\x93\x48\x99\x9e\x24\x03\x7c\x15\x3b\xa8\x1b\xf6\x77\xff\xab\x8a\x59\xfb\xd2\xe7\x63\xbe\x4d\xf9\xc4\x9a\x28\xcc\x98\xbd\x8a\xfa\xb5\x67\xfb\xfd\xbe\x6b\xe0\xf2\xcb\x6b\xd0\x18\xe5\x37\x4d\x73\xc9\x6c\x41\x63\x60\x29\x8a\x16\x38\x96\x96\x7a\x29\x8a\xa2\xc4\xe6\xb4\xc9\xfb\x84\xd4\x6a\xf5\xbe\x57\x6a\x18\x1a\xc5\xa0\x39\xe2\x4d\x9b\x01\x05\xa7\x3b\x64\x02\xe5\x89\xa3\x10\x34\xbf\x2e\x56\xa7\xaa\x5c\x42\xc7\x2f\x4b\x63\x43\x52\x36\x44\x66\x5f\x65\x3a\x96\xbf\x8d\x8d\xa4\xe1\xb6\x1a\xd1\x7e\xc9\x53\xf1\x02\x65\xe1\xd9\x2b\xe6\x9f\xd8\x08\x8e\x8f\xf4\x54\xc1\x7f\xff\x5b\x2e\xef\x77\xf3\xe3\x92\x00\xa4\x9c\x4a\xc9\x78\x36\x81\xad\xd5\x2c\x1c\x91\xd8\x8d\xcf\x26\x89\x40\x87\x15\xc1\x39\x9d\x2d\x4a\xc2\x98\xe1\x82\xda\xee\xb6\xbb\xd5\x76\x17\xf9\xbf\x47\xed\xa4\xb3\xfc\xa1\x50\x5d\xc1\xf7\x75\x73\x9a\xc4\xd4\xaa\x8a\x1f\x45\xf1\x46\x12\x7f\x91\x38\x25\xc8\xb7\x7d\x06\xf8\xef\xb9\xfb\xa3\x32\x08\x20\x3a\x96\xdd\x6b\x4d\x12\x63\xc9\xfd\xf3\x76\x9f\xde\xa7\xe3\x3c\x76\x42\x99\xa5\x05\xee\x4a\xf9\x0f\xf0\x31\x47\xf7\xec\x87\x43\x82\x3e\x66\x2e\xea\x4e\x9f\xbc\xb6\xa5\xe1\x6b\xd1\xdd\x06\x0b\x63\x44\x74\xfd\x10\x95\x56\x5d\x4a\x36\x61\xa1\xf2\x32\x06\x60\x21\x3c\x63\xc5\x0e\x9a\x30\x25\x53\x8b\x83\x90\x87\xac\xd9\x20\xd5\xd7\xd8\xb4\x24\x69\x94\x78\x95\x7d\xfb\x24\x28\x52\xe7\x7f\x42\x84\x14\x69\x18\x2a\x5b\x18\xb5\x17\xbf\xcb\xba\xec\x4d\x22\x18\xc3\xca\xc5\xff\x41\xd1\x78\x34\x34\x4d\x84\x4a\x91\x51\x4b\x0e\x89\x21\xb1\x03\xa8\xfe\xda\xc4\x27\x02\x12\xd2\x69\x81\x5c\x5b\x66\xde\x1b\x91\xe5\x27\x5f\xc3\xa3\x89\x8c\x98\x27\x53\xf9\xa3\x10\x97\x0e\xb8\x1f\x46\x6d\x93\x19\xe6\x15\x7b\xce\x34\x67\x76\x13\x15\x05\x48\x30\xb0\xef\x13\x64\x9b\x3e\x23\x95\x40\x4a\x50\x01\x59\x7a\xf9\xfc\xba\xaf\x17\xd2\x04\x84\xd2\x8e\x35\x64\x02\xf6\xf0\x03\x94\x04\xe9\x69\xae\x3e\xad\x61\x78\x17\x79\xd6\x83\xb4\x68\x62\x02\xc3\x52\x3f\x65\x41\xe4\xfb\xed\x41\x54\xcd\x7e\x7d\x7d\x61\xb7\xc6\x7b\x55\xbf\xb3\x26\x86\x10\xac\x3b\x7e\x40\xb6\x2b\x9f\x6b\x6d\xd7\xfe\xf8\x3d\x98\xc4\x89\x17\x8a\x63\x3b\x09\xf7\xee\xe7\x69\xd0\x7e\xb7\x9e\xaa\xa2\xf5\x57\xb3\xe2\xc5\x4a\x72\x5e\x44\xd4\xb3\x6b\x94\x06\x34\x45\xd7\x69\xf7\x0a\x76\x61\x43\x73\x9d\xbd\xb4\x61\xb3\xdd\xe7\xd5\xb9\xfb\x31\x61\x85\x07\xbd\x19\xfc\xd1\xbe\xcc\xd1\x2b\xa3\x81\xe1\x21\xf3\x5d\x5e\xab\x42\xd7\x7e\x59\xd2\x30\x96\xe8\xad\xaf\xb7\x43\x2e\x31\x4a\xa3\x30\x0d\x62\x47\x5e\xbc\x57\xe2\xe8\x59\x33\x28\x8d\xa4\x2d\x1e\xbe\x67\xf0\x81\x3a\xcd\xff\x10\xd5\x61\x52\xfb\xa1\x71\x18\x22\x43\x3f\xb8\x16\xf5\xce\x75\x71\xc7\x13\x1a\x60\x61\x2b\x2b\x3c\x35\xfe\xad\x98\xe0\x4a\x28\x4d\xb8\x65\x4b\xb9\xca\x5a\xa3\x0e\x0a\x11\xeb\x50\xbd\x0b\xdd\xd5\x38\x28\x25\x29\xa6\x01\x70\xe3\x7d\x28\xab\x83\xc8\xbb\xe4\x75\x59\x75\x02\xe6\x94\xd2\x50\x60\x3e\x37\x2b\xb2\x8e\x0a\xd0\x51\x22\x75\x77\x45\xa9\xc1\x10\x65\xb7\xbb\xed\xbb\x16\x29\xa5\x0c\xb0\xe4\x6a\x75\xeb\x2e\x24\x9e\xfd\x28\x63\xf0\x07\x6c\x70\x33\xb3\x5f\x51\x46\x42\x44\xd4\xb4\x2e\x56\xfd\x68\x3c\xc4\x6a\xd6\x72\x51\x16\x0b\x4c\x62\x6c\xa0\x1e\xb9\xcb\xfe\x30\x97\xd4\x31\xa0\xfd\x5d\x68\x18\x36\x53\x8e\x8a\x5e\x6e\x38\xd7\x0c\x17\xec\x43\xa6\xe0\xf6\x74\x7e\x2a\x8b\xff\xfa\xd2\x0f\x4d\x23\xeb\xf9\xbd\x96\x75\x93\xe5\xb0\x13\x6f\x50\xbe\x7f\xc1\xd8\x40\x69\x2a\x13\x04\xe4\x1f\xc5\x79\xdf\xc9\x34\x53\x9a\xaa\x14\xfb\x87\x7c\x5b\x29\x68\x97\x0a\x9d\xb8\xc2\x34\xd5\x29\x56\xdc\xd4\x5e\xa1\x5c\xcd\x88\x78\x9d\x52\xa1\x98\x95\xe1\xb5\x0d\x94\xb3\xa1\x07\x95\x34\xc4\x70\xf0\x45\x1c\xe0\xf1\x1d\xaa\xab\x33\x72\xfe\xfa\xa3\x8c\xb9\x46\xaf\x3c\x2f\x3f\xc6\x1b\x32\x55\x81\x24\x3e\xad\x5f\xe6\x1a\x05\x81\x40\x1c\x66\x43\x04\xaa\x92\x08\x1b\xff\x27\x35\xec\x0b\xaf\x65\xe8\xe1\x52\x25\x6d\x69\xfb\x16\x46\x7e\x1f\xd5\x89\xed\x63\xb4\xe0\xf9\x07\x71\x80\xfa\x28\xc6\xf4\xaa\x94\x6a\xc9\x02\x4f\x7d\xf1\xf8\x78\x67\x53\x8e\x61\xd4\x5d\x43\x1b\xac\xe8\x1d\x44\x66\xc3\x6f\xd1\xc0\x53\x7f\xd4\xb0\x80\x74\x95\xa9\x9b\xe9\x6e\x45\x81\x82\x5d\x94\xe8\xef\x84\xdb\xf3\x41\x7a\x5e\x7e\x4a\x01\x02\x2b\x9c\xec\xbc\x88\xae\xe9\x6e\xde\x5a\xb9\xb3\x8c\x03\xbf\xa0\x18\x49\x64\xd3\xaf\xfe\x8a\xa6\x8d\x9e\xd0\xe8\x94\x9d\xed\xa7\x86\x59\xe1\xe4\x76\x52\x3b\x5d\xf9\xc9\xaa\x37\x3a\x76\xf0\xea\xa2\xd9\x95\x2f\x2f\xf9\xb0\x2c\xc7\x02\x99\x22\xac\xa9\x80\xba\x69\xe7\x98\x2a\x0b\xbd\x2d\xbf\xda\xff\x59\xa0\x48\xe4\x84\x8a\xda\xcf\xec\x12\xd1\xfe\x9b\x30\x12\x32\x47\x75\xd0\xba\x06\x57\x13\xb9\x0b\xca\xc2\x34\xb5\x62\x1f\x7e\xcd\x5f\x40\x78\x07\xb7\x16\x25\x41\x18\x75\xd0\x5b\x93\xe5\xf0\x94\xa9\x39\x7d\x47\x3f\x5e\x12\x54\x0b\xf0\xf4\x3b\xd3\x05\xe7\xf7\x6d\x16\x13\x8b\xc6\xc8\x8a\x7f\x83\x6a\x1c\x6b\xbf\xc7\x73\xf9\x47\x89\x19\x65\x81\x0b\xf3\xda\xe3\xb6\x10\xea\x0e\x26\x3c\x60\xe0\xad\xe4\x1d\xbc\xd7\xfd\x01\x8e\x07\xf0\xa2\xbe\x21\x04\x31\xad\x30\x24\x86\x9a\x6c\x59\xee\x64\x2a\x09\x56\x16\x46\x88\x51\x87\xbb\x73\x43\x98\x91\x98\x30\x82\x4f\x54\xda\x08\x31\x8f\xe5\x8e\xf1\x80\x23\xcd\xbc\xc9\x2a\x2b\x92\x7c\x57\xbe\x04\x8b\xa2\x2c\xce\x87\x6e\x48\x1c\x63\x11\x56\xe5\x20\x8a\xc7\x53\x77\xd9\x34\xb0\x62\x21\x77\x8f\xcb\x7f\xec\x96\xdd\x5f\x49\x42\xb9\x93\x9c\x58\x4c\xf9\x3d\xdd\x18\x41\x01\x3d\x4e\x09\x23\xb1\x59\xca\x84\x26\x8e\x2a\x27\xcf\xd7\xcb\xbc\x3c\xa1\xb4\xde\xe2\x45\x64\x45\x6d\xdf\xf9\x78\x9e\x32\x01\x40\x3a\x82\xf6\xa5\x4d\xa9\x76\x46\x88\x09\xa3\xf1\xe3\xb6\xf3\x2a\x1c\x24\x5c\x26\xaf\x50\x8a\x04\x35\x02\x9c\x34\x13\xb2\xa3\xe2\xea\xfd\x45\xdd\x83\x49\x99\xf0\xa8\xfb\x75\x71\xbc\x29\x2b\xbb\x18\xee\x5b\xd3\xd0\x2b\xb6\x53\xa6\x42\x16\x05\x03\x30\xd0\x13\x54\x03\xd8\x56\x7b\x5c\x23\x1e\x45\x28\x05\xc7\x66\x5f\xfa\x76\x91\xee\x38\x97\xd8\xf6\x82\xe2\xc8\xa7\xc2\x61\x34\xba\x19\xa4\x84\x82\x14\x45\x0a\x76\xfb\x9e\x7a\xf8\xbb\xec\x0c\xd3\x21\xf5\xc4\xeb\x5b\x61\x86\xe5\x59\xa6\x81\x63\xb6\xee\xda\xa6\xbe\x47\x5f\x08\x52\x82\x91\xaf\xed\xb5\xdc\xdf\x7b\x6d\x02\xca\x40\x72\x4c\xbb\x6d\x77\x9b\xf5\xfd\x38\x7c\xff\x36\x54\x61\x20\x0d\x8a\x94\xd8\xfc\xca\xf7\x31\xaa\x3b\xc5\x90\xd0\x52\xc0\x92\xfd\x7b\xf9\xdf\x4a\x74\xa6\x8d\x99\x34\x45\xaf\xf7\x6e\xfd\xcf\xe7\xf5\xf5\x62\xb7\x7e\x7c\xd8\x6f\x56\xdb\xd5\xe6\xf7\xd5\x7e\xd3\xfe\xdf\x6e\xa0\x8a\x7c\xe6\xcf\x46\x83\xae\x24\x30\xbb\xd9\xf1\x80\x28\x69\xab\x3c\xf5\x8c\x54\xfb\xe8\xe6\x78\xc0\x15\xfa\x20\x7b\xa4\x30\xc8\xf2\xac\x39\x63\x54\x40\xd8\x6f\x93\x81\xa9\x30\xce\x7d\x78\xd4\x13\x68\x36\xe5\x81\x14\xc2\x03\x93\xa1\xd0\x43\x8e\x77\xca\x89\x34\xa1\xe5\x51\x7c\x11\xf9\x55\xd9\xff\xdd\xa4\x49\xd0\xb5\x07\xdf\x8b\xcf\x79\x93\xcc\xc3\x88\x60\x99\xef\x28\xaa\xda\x7e\xfb\xe1\xe4\xe0\xa1\xd6\x98\x66\xdd\xfe\x1c\xc8\xa2\xce\x2e\x1e\x1e\x85\x16\xd5\x25\x2c\xa9\x55\xb7\x63\x8d\x7f\x2f\x4a\x23\x61\xeb\x25\xf2\xf4\xb2\x47\x34\x73\x56\x60\xe8\xf1\xf9\x78\x6a\x8e\xa7\xe6\x6e\x5a\xfc\xe0\x71\x64\x10\xd7\x83\x1c\x3b\x31\x9f\x1e\xa5\x01\xfa\xdb\x38\xd1\xee\xad\xd2\x75\xe7\x49\x5e\xee\x0b\x3c\x96\x2a\xed\x0c\x85\x37\xf6\x7e\xd3\xe6\xb1\x31\x58\x20\x92\xee\xe3\x12\x3a\xf9\xfe\x6d\xc8\x8b\xaa\x87\xd7\xc3\xd5\xc0\x13\x0a\xc8\x34\xff\xf7\xdd\xea\x6a\xbd\x9b\x77\xd6\x78\x22\x62\x2c\x7a\xe0\xbb\xbe\x2b\x85\x95\x36\x19\x30\x8e\xfc\x95\xf6\x61\x22\xfb\x97\xab\x98\xfc\x15\xff\xab\x3b\x1f\x90\x22\xe0\x90\x15\x50\xb5\x11\xce\xa3\xb9\x13\x75\x6b\xe3\x4b\xd3\xdd\x08\x88\xc4\x45\xc9\x9b\xc7\x9b\x8d\x13\xc1\x73\x07\x69\x10\x22\xc6\x19\xb5\x8e\xf3\xb9\x17\x35\xbe\x61\x26\x01\x7d\xb7\x4d\x89\xbc\x48\x8b\x42\x6f\xa0\x46\x99\x8d\xee\x92\x3c\x01\xce\x3b\x50\xf4\x0b\x20\xf2\xcc\x1d\x4b\x13\x99\x08\xaf\x36\x91\xe5\x67\x14\xba\xeb\x0e\x52\xa9\x6d\x01\x02\x7b\x0d\x3a\x6e\x9a\xd3\x6c\x7f\xd5\xa8\x7a\xc4\x45\xc8\xb1\x90\xb2\x2b\x4f\x55\x1b\x17\x17\xcd\xb2\xfc\x46\xb8\x79\x3c\x4f\x05\xa3\x98\x29\xb7\x9e\xdf\x4d\x59\x59\x54\xaa\xbf\x2f\x99\x10\xd0\x9e\x00\xd6\xe9\x37\x7d\x95\x27\x9b\xeb\xf1\xf6\x97\x49\x49\xa7\xbb\xe9\xbc\x94\xe1\xab\x51\x89\xc2\xc8\x7e\x7b\xbd\xfb\x15\x1f\x31\xe5\x2a\x95\xd2\x5d\xeb\x2a\x9b\xe7\xf6\xa2\x5c\x39\xf1\x78\x24\x84\x6a\xb7\x9e\x6f\xcd\x98\x4e\x05\xe6\x41\xf6\x88\x1e\xf8\x28\x26\xdd\x88\xdf\x67\x02\xb9\x36\x12\x21\x4b\xbb\xdd\x68\x11\x40\xc8\x3c\x67\xf4\xdd\x09\x75\xf9\x8f\x93\x0d\x9f\x43\x9c\xa0\x8b\x67\x5d\x9f\xab\x6d\x99\xeb\xfd\xf2\x71\xf3\xb0\xda\x6c\x77\x8f\x0f\xab\xee\x4a\x89\xc0\x0e\x65\xed\x55\x3d\xda\x3d\xee\xa6\xac\x5c\xe8\x3e\x31\x01\x26\x90\x08\x88\xd9\x3d\xee\x16\x77\xfb\xbb\xc5\x66\xb5\xbf\x79\xdc\xec\xfb\xa6\x48\xca\x8d\x31\x91\x6d\xf0\x29\x6c\xa7\xd0\xbc\x39\x4c\x83\x28\xc4\xfb\x93\xf0\x92\x15\x03\x80\x3f\x1e\x01\xab\xcd\x5c\x7e\x9e\x77\x17\x9a\xd1\x3f\xb3\xe6\x15\x29\x71\x61\x28\x78\x33\x2d\x98\xce\x95\x51\x52\xc2\x18\xb6\xe4\x0a\x3d\xec\x63\x9d\x69\xb7\xa5\x69\x48\xac\xa0\x89\xad\xf8\x0d\xd7\x76\x1a\xaa\x10\x43\xbe\x7d\x53\xee\xb2\x1c\xd6\x88\xd2\x8f\xc2\xbf\x0d\xd6\x4d\x1a\xea\x04\x43\x5e\xa7\x14\x8b\xf9\x7b\x27\xb2\x3f\xbb\xd9\xba\xd3\xa2\xd8\xee\x25\x7b\x57\x6c\x7b\x2c\xa0\x53\x7c\xa5\x69\x94\x70\xc4\x1b\xbd\x97\xb8\x9a\x76\xe2\x38\x88\x10\xd2\x88\x06\x81\xcd\x29\x96\xf9\xa8\xd6\x9e\x46\xd4\xf2\xd1\xa2\xf9\x7a\x34\xbb\x57\xd8\x64\x5e\x25\x89\xa6\x71\x10\x5a\xd0\x74\x55\x7e\x34\xfd\x5f\x09\x35\xae\xf4\xf1\x50\x6a\xd8\x9d\x8f\x93\xa8\x2a\x8d\xb9\xd2\xe9\xa8\xb9\xa8\x82\x8e\x8f\xf1\x2f\x42\x27\x59\xf9\x34\xd6\x02\xf7\x73\x24\x23\x5d\x3f\xdc\xee\xb7\x0f\x8b\xf5\x5d\xf7\x7b\xc6\x92\xee\x61\x07\xf9\xe4\x5b\x24\x61\x80\xcf\x2d\x72\xf5\x0a\x87\xf3\xf4\xa8\x12\xca\x95\xd3\xb1\x04\xa4\xeb\xab\xf3\x52\x34\xf0\x52\x56\xe7\x71\x10\x9c\xb2\x20\x15\x36\x1c\xf8\x01\x9f\x16\xf0\x43\xe3\xc9\xe5\x58\x18\xda\x34\x8f\xcb\xcf\x0c\xfb\x69\x87\xb6\x22\x65\x91\x41\xc3\xa2\xca\xc3\xf1\xd4\xc0\x76\x7a\x1d\x25\x88\xed\x9a\x2e\xb2\xfa\x75\x9b\x15\x2f\xb9\xed\xde\x99\x35\x2a\x29\x0f\x04\x61\x9d\x31\x3c\x94\x17\x08\x80\x6f\xbd\xb3\xb4\xdd\xed\x43\xcb\xe3\xfb\x06\x67\x4b\xe1\x35\x91\x51\xa3\x29\xe7\x09\xb2\x1c\x7f\xf4\x3e\xe6\x28\x72\x4d\x53\xa5\x43\xe7\x32\xdf\x56\xe5\x07\xca\xd0\x16\x4d\x55\xe6\x08\x40\x5b\x74\x13\x2a\xd5\x56\xd4\xb9\x16\x65\x2d\x4a\xda\xfd\xd9\x58\xfa\x0f\x9b\xc3\xf8\x59\x56\xcd\xeb\x64\xce\x88\xd0\x92\x31\xa3\x51\x72\x70\xb5\x6e\x5d\x89\xc4\x22\x4f\x5b\x77\xcf\xc2\x88\x27\xb6\x34\x15\x1a\x30\x87\x72\xb7\xba\xde\xdf\x3f\xdf\xed\xd6\xdb\xf5\xad\x3f\x5b\xea\x58\xd8\x8c\xf2\x0b\xde\xed\xa0\x34\x9f\x4a\x10\xd2\x2f\x9c\xc9\x3b\x51\x61\x28\x5d\xb7\xd7\x9f\xe2\x3c\x71\x08\x53\x95\x48\xc4\xb1\xc9\x53\xbb\x2d\x2f\xf3\xb2\x3e\x55\x30\x04\x68\xf8\x71\xd4\x0a\xa5\x75\xcc\x9d\xa8\x4e\xe5\x0f\x4a\x69\x17\xf5\x0b\x34\xa8\xb6\x34\x4c\x8f\xa4\x5a\x5b\xe9\x59\xcb\x1b\x27\xea\x3a\xc3\x16\xfa\x87\xd3\xb4\x9a\x93\x6a\x63\x55\xa3\x4f\xc5\xd0\x5a\x02\xb7\x9a\xa1\x76\x93\xfd\x0e\x02\x96\x82\x00\xd4\x12\x73\x41\x97\x6f\xf8\xda\x95\xf7\xd9\xb4\xf2\x9e\x1a\xa6\x31\xca\xbb\x79\x7c\x7e\x70\x3e\xfd\xd3\x6a\xb3\x5c\xf9\x4e\x4e\x9a\x1a\xce\x91\xf1\xa7\x13\x04\x45\x85\xb2\xf1\x0b\x14\x84\x27\xc8\xe2\xf5\xf1\xda\x31\x2d\x50\x11\x06\x06\x6d\xcb\xf5\x76\x25\xea\x33\xd2\xa0\xd7\xd9\xcb\xff\x44\xf9\x41\x45\x14\x6b\x04\x7f\xef\xad\xbf\xbd\x14\x95\xee\x11\xf6\x5e\x03\x88\x8a\x48\xc4\x51\xda\x29\xb5\x8f\x5a\x9b\x66\x5f\x8e\x88\xa4\x65\x4d\x45\x49\x9b\x7a\x68\xf0\x45\x22\x8d\x97\x25\x45\xcf\x2b\x1c\xf4\x41\x51\x41\x43\x8d\x65\xda\x81\x38\x67\xd8\x1d\x8b\x22\x0c\x28\x36\x8f\x8b\xee\x4f\x22\xd0\x76\xdf\x53\xe5\x01\xa1\xf3\xdd\x11\x43\xb0\xc8\xef\x53\x89\x77\x99\x82\xa2\x86\x39\x48\xa2\xe0\xd4\xe6\x50\x4e\xb5\x9e\x81\x95\x8b\x54\x04\x69\xda\x2b\x4f\xac\x55\xfb\x89\xfd\xef\x08\x66\xac\xd4\x43\x91\x9f\x6f\x2c\x29\x54\xf7\xa8\x92\x84\x84\x0e\x69\x83\xeb\x45\x75\x38\x93\xc9\xe5\x65\x64\xc9\x34\xb2\x22\x6b\x32\x6c\xf9\xfb\x8a\xb5\xc0\x9f\x20\x08\x4e\xdd\xab\xac\x8d\x42\x3e\xbb\x5f\x93\x36\x29\xe6\x55\xc2\x89\x13\x96\xf0\xb1\xc0\x34\x26\x10\x2a\x0d\xbd\xeb\xf5\x77\xa1\xde\x8e\x65\xe3\x90\xc1\x93\x1b\xd4\x09\xeb\x80\x9d\x99\x3a\xe5\xcd\x79\xab\x44\x0e\xf7\x96\x58\x2b\x83\x6a\xe8\x20\x0b\x08\x84\xb0\xf8\x30\x1b\x20\xf9\xbf\x1b\x6d\x55\x85\x5b\x6f\xb0\x47\x10\xcb\x80\x40\x62\xb1\x66\x78\xbd\x19\x98\xb6\x0c\x12\x81\x33\x7c\xfd\xb0\xde\xad\x17\x77\x7b\x64\x71\xb9\x5b\x6f\x77\x23\xc2\x24\x2a\x03\x1e\x63\x41\x32\xab\x1f\x8f\xdd\xf5\x49\xa0\xd1\x48\x62\xe3\x58\xbb\x9e\xf7\x37\x65\xb5\x5f\x66\x15\x6e\xb3\x3d\xfe\x4e\x12\x62\x90\xf8\xc9\x20\x8b\x44\x26\xf2\xfd\x7a\xf9\xd8\x1d\xa4\x09\x74\xa9\xaf\x7d\xe6\x6b\x80\xdd\xe1\xd4\x62\x97\x67\xf9\xd4\xfc\x18\x65\x53\xf1\x2f\xa2\x6e\x5f\x9f\x98\x44\x98\x32\x0c\x28\x5a\x47\x5d\x6e\xcb\x03\x34\xaf\x17\xfe\xa2\x0c\x29\x45\xbb\xb8\x42\x97\xed\xd4\x46\x35\x36\xd5\xf6\xc5\x2f\x86\x2a\x8e\x58\x8f\x35\x1a\xe2\xda\x06\x83\xb4\xc1\x46\x84\xca\x1e\xbd\x2e\xd5\xe9\x00\xf3\xe2\x55\x54\x46\x42\x7a\x7a\xcc\x7b\x0b\x5d\x18\xa3\xa4\x65\x1c\x84\x08\xcc\xb8\xbf\x7d\xee\xfe\x14\xa7\xa1\x45\x8e\x54\xef\xa7\x21\x8d\x17\x95\xb1\x0c\xb0\x6c\xd4\x40\xed\x48\xf2\x5b\x9f\x63\x32\xfd\x64\x42\x22\xab\x62\x90\x15\x22\x1f\x62\x37\x64\x92\x00\xfe\x9a\xb3\xe1\x7e\x96\x0f\x63\x2e\x99\x30\x89\x4c\x95\x35\xf6\xab\xb6\xd3\xeb\xab\xd7\xc5\x8c\xa5\xaa\xf4\x26\x78\x08\x00\x24\x69\x38\x0c\x93\x24\x67\x12\xdb\x11\xa1\xf2\x89\x48\x99\x06\x29\x38\xc6\x14\xdd\x6d\xc3\x52\x84\x16\xe4\x6f\x40\xbd\xfe\x5e\x36\x88\xa9\xb9\x29\x2b\x84\x00\x5e\x9d\xc7\x28\xb9\xf9\xdb\x92\x01\xb1\xa6\x14\x6c\x3f\xf0\xba\x10\x28\x40\xea\x38\xbf\x70\x1a\x7e\x59\xad\x95\x92\x50\xca\x06\x0a\x8d\x8d\x7a\xbd\x68\x7d\x72\x56\x5e\x2a\xc2\xbd\xea\x24\x62\xe3\xa6\xeb\x50\x27\x71\xc8\x86\x82\xd2\x43\xac\x83\xd4\x3c\xc1\x46\xdb\x43\xa3\x9f\x2a\x18\xf9\xcc\x52\x2b\x45\x6c\x03\xe3\xa2\xb9\x03\x51\x7f\x51\xae\x92\x26\xd2\x98\x50\x2a\x2b\xa1\xda\x67\xdd\xff\xe7\x04\xd5\x84\xec\xef\xaf\xf0\x5f\xd3\xb3\x9c\x32\xa9\xdd\x9d\x24\x54\x8f\xe6\x1a\xa0\xf5\x5c\x7d\x41\x66\x38\x89\x55\xe0\x13\xe1\xf5\xba\xe8\xbb\x77\xc6\x93\x4e\x05\x69\xc4\x89\xdb\x18\xad\xca\x46\xeb\xa8\xd4\x48\x08\x39\x5b\xcd\x56\x81\x4e\xd0\x65\xfa\xf3\xf4\x96\x4d\x55\xc0\xa9\x22\x9a\x7a\x96\xc7\x45\xf1\x02\x79\xeb\xbc\xba\x40\xe8\x34\xe8\xc6\x52\xc4\x70\x66\x61\x0f\x08\x03\xdf\x57\x23\x19\x41\x37\x28\x24\x14\x01\x49\x0e\xb0\x6f\xfb\x1d\x67\x3d\x61\x15\x86\xd4\x04\xae\x9e\xf8\x55\x3a\xf3\x72\xda\xa8\x30\xb2\xe9\x5a\xdf\xed\x50\x3f\x41\xf5\x5c\xeb\xcd\x45\x87\x8b\x0a\x63\xe9\xbb\x44\x37\x4e\xcd\x6f\xb8\x46\x55\x98\xa4\x9e\xaa\x6f\xff\xda\xc7\x6c\x17\xdf\x5e\x85\xc6\x96\xc9\x2c\x12\x70\xf1\x52\x01\x22\x1e\x27\xd6\x40\x45\x81\xb4\xb2\x32\xad\xd7\x70\x2b\xea\xa5\x0b\x98\x7a\x4b\xae\x22\xa0\x32\xb5\xd8\xd1\xae\x03\x98\xaa\x58\xd9\x14\x73\x5f\x5b\x5c\x1c\xa7\x71\xbe\x8a\x75\x82\xdd\xe0\xf7\xd0\x54\x65\x51\x1e\x60\xf4\x11\x63\xb0\xcc\xb2\xaf\xa2\xc6\x52\xe1\xf8\xdc\x84\x12\x04\x61\x8b\xca\x39\x8e\x37\x15\x74\xaf\x21\xe1\x16\xfd\xd2\xee\xb5\xa5\x1c\x7c\xf9\xfe\xc9\x68\xa8\x6c\xe7\x73\x71\x11\xb4\x29\x4a\x43\x2c\x62\x2f\x0f\xde\xde\x28\x4a\x13\x96\x0c\x55\x40\xde\xb3\xd6\xa6\x20\xec\x75\x9e\x02\x83\x2a\x2a\x00\x6d\xd4\xe3\xf5\x6a\xf5\x34\x7a\x34\x26\x0d\x17\x9e\x1c\xa3\x7d\x3d\x73\xfd\x2d\x8a\x19\x86\x0c\x07\xf7\x65\x76\xf8\x65\xfe\x47\xf1\x90\x04\xee\xd3\xbb\xb6\x3a\x51\x89\x83\x37\x8d\x2a\x8d\xa2\x38\xed\xd9\xc9\x86\xed\xa8\x43\xdf\xe7\x9b\x7f\xfc\x85\x62\x8d\x2f\x5e\x9f\xec\x52\x76\x79\x78\x7f\x34\xd1\x30\x64\xb2\xfa\x75\x77\x87\x4a\x39\x41\x38\xe5\xb6\x9d\xcf\x15\xe4\x37\xa2\x3a\x74\x99\x36\x25\x02\x8b\x7b\x7a\x5a\x6c\x86\x6c\x2c\x54\x89\x28\x0c\x65\xa7\x22\xe3\xdb\x01\x75\x77\x38\x89\x31\x64\xcf\xc5\xc7\xaa\xc0\x4e\xbc\x76\x7e\x6f\xca\xce\x95\x57\x32\xa6\xc8\xe0\xa5\x5a\x33\xfd\x67\x79\xfa\x1e\x22\xa5\x64\x0a\x14\x17\xa9\x7a\x05\x7d\xca\x61\x08\xc9\xbd\x20\x7f\xa4\x4a\x2a\x8d\xd8\xa9\xe2\x74\xc0\x44\x6a\x73\xaa\xc0\xd1\xc0\x79\xeb\xa3\x82\x38\x1c\xea\xed\xdb\x76\x38\x0f\x15\x79\x80\xe6\xa3\xac\xde\xe6\x2a\x62\x4a\x27\xb6\x5b\xe2\x5e\x7c\xda\xf9\x53\x94\x1a\x6a\x27\x14\x31\xe4\xc8\xe2\xfe\x04\xae\xb0\xcc\x86\x5b\xd2\xfe\x5e\xbc\xf5\x2f\x18\xc2\x04\x2d\xc1\x7a\x6a\x94\xa1\x8d\x79\xfb\xde\x9e\x61\xf7\x91\x02\xae\xd0\x2e\xfc\x10\x85\xae\x1f\x8b\xd9\xd9\x79\x9a\xb2\xbf\x53\x05\x82\xa3\x9d\xff\x87\x38\x67\xa3\x05\x01\x02\xa4\x4f\x10\x77\x48\xcc\xee\xa0\x24\x26\x72\x65\xd2\x09\x5b\xf2\x8c\x31\x35\xc2\xe0\xfc\xbc\xbf\xff\x16\x6f\xac\x8c\x64\xc2\xd9\x88\x2b\x31\x45\xcd\x2b\x23\x25\xee\x0c\x15\xbc\x43\x71\x82\xb1\xe3\xa5\x03\x47\x39\x88\x12\x95\xf5\xeb\x53\x99\x15\xcd\xd5\x19\x9d\xaa\xb2\x1a\x61\xfe\x35\x49\x02\xe8\xc1\xc6\x1d\x10\x65\xe8\x45\x0c\xc8\xfe\xda\xf1\x04\x9b\xe2\x5b\x87\xbe\xbe\x03\xd3\xac\x8b\x9e\xc4\xb4\x3d\x9c\xd2\x9e\xce\x6f\xca\x95\xe7\x9c\x27\x37\x36\x8c\x00\x95\x36\x5d\x77\xb9\x7f\x9f\x3a\x94\xc6\xe7\xc7\x76\x20\x0e\xa3\x97\xad\xa3\xd8\xe0\xc6\xea\x62\x94\x27\x71\x2e\xcd\x45\xbb\xdf\x78\xdb\xd3\x71\xa0\x31\x60\xb5\x9e\xa1\x8b\xcb\xc6\x2f\x54\xc7\xa9\x56\xc8\x13\x7a\xc8\x3a\x31\xb3\xd9\xad\xf4\x6f\x93\xf3\x3c\xa9\x05\xe6\x75\x4e\x47\xd7\x91\x3b\x19\x04\xa9\xee\x41\xa1\x57\xe7\xdd\xe7\x6f\x97\xb3\x4f\x27\x71\x8c\x7b\x52\x7d\x3a\xfc\x10\x95\x5e\x8a\xe3\x53\x05\xeb\xe5\x23\xf1\xcf\x4e\x75\x80\x4d\x45\x77\xd0\xd4\x46\x64\xa3\x62\xb3\x66\x61\x8c\x04\x49\x08\xb6\x30\xa2\x9f\x0c\x4c\x5b\x79\x77\xa1\xf5\xee\x23\x2b\x66\x61\x29\x9a\x33\x83\xcd\x48\x87\xb3\x95\x44\x13\x79\x2f\x31\xec\x86\xa4\x51\x80\x09\xfc\x9b\xd6\x9c\x75\x98\xdd\xee\xa0\xc5\x50\xee\x6b\x70\x0d\x28\x0e\x7e\x4f\xe7\x6a\x1f\x3a\x4d\xb8\x72\x9f\xf8\x0e\x61\x94\xc7\xae\x10\xaf\x53\x6a\x03\xbc\xbd\xdf\x0a\x50\x15\x7e\xbe\x04\xa0\x05\x01\x36\x10\x14\x5f\x14\xfa\x6e\xc6\x79\x9e\x7c\x33\x11\x31\x2b\x1e\xda\x94\x05\xf8\x5e\x25\x7f\x2c\xa6\x4c\x79\x7c\xce\x7f\xcf\x0b\x63\xb2\x3c\x1b\x09\x76\x9d\x06\x50\xa8\xf9\xea\x8c\x16\x49\x2c\x22\x9f\xe8\xec\xba\xe8\xbf\x00\x94\x68\xa1\x34\x96\x9a\xb1\x34\x98\xa4\x93\xb9\xa3\x02\x82\xf5\xe4\xab\xcd\xcd\x45\xe7\xfa\x5f\x51\x6f\x5f\xbe\xfc\xcf\xaf\xaa\x21\xdf\x02\x31\xb4\x22\x09\xee\x4f\xe8\xbe\x4d\x68\x0d\xbb\x21\x42\x77\x5e\xc2\x27\xa6\x6f\xa2\x85\x05\x2e\x67\x65\xf1\x04\x95\x47\xc7\x4e\xcf\xa3\x0c\xe5\xb1\x91\x09\xc4\xbf\x77\xc5\x63\x74\x4d\x1d\xe2\xd0\x73\xf3\x4d\xa6\xa9\x92\x04\x6b\x36\xae\x27\x65\x42\xee\x44\xb5\x52\xdc\xb3\x27\xb4\x3e\x59\x7b\x03\x45\x53\x56\xe7\x79\x7f\x58\xeb\x80\x02\x99\x42\xa3\x22\x0f\x4b\xd4\x5a\x59\xaa\x8c\x9b\x2c\xcf\xaf\x4e\xe7\x71\x3c\xff\x3f\xc2\xce\x27\xdf\x5a\x2b\x20\x8e\xf0\xda\x95\x2d\x67\xca\xbb\x1a\xe2\x10\x31\xa0\x3d\xf3\x65\xdf\x05\xe2\x87\x88\x24\x01\xb7\xe9\xac\x9a\xd7\x5d\x39\xd5\x76\x9d\x37\x57\xa0\x43\xa7\xd6\xaa\x01\x0e\x7b\x83\x8a\x25\x5f\x3d\xca\x78\xa9\x81\xd1\x88\xe2\xff\x3f\xa8\xca\x1f\x65\x39\x56\x58\xf9\xe5\xde\xaa\x4d\x10\x61\xa7\xef\x66\x75\xb3\x5f\x6e\x56\xd7\xeb\xdd\x76\xff\xb4\xda\xec\x17\x7f\xac\x7d\x81\x4b\x9b\xc8\xd6\xd5\x71\xe5\xa3\x42\xb3\xd7\xde\x1b\x7f\x66\xd3\x7a\xfe\xb6\x86\x3c\x62\xf5\xbb\x2f\x2b\xe8\x59\xfd\x28\x04\x21\xc5\x36\xed\xbd\x23\x87\x9c\x68\x63\xb8\x51\x24\xe1\x86\x4f\x65\x95\x47\xaf\x0d\x08\xb5\xfd\x64\x3d\xaf\xe3\x06\xd0\x41\xbd\x13\xed\x9f\x06\xdc\x8e\x03\xb2\x35\x0a\x44\x2a\x34\x26\xeb\x42\x97\xe8\x3d\xf9\x03\x21\x05\x4b\xc2\x22\x9a\xbc\xac\xf4\x18\xd4\x09\x21\x58\x7a\xdb\x0a\xd4\x59\xe5\x56\x8d\xaf\x67\x68\x80\x88\x58\x30\xbc\xc0\x26\xdf\x03\x06\xdf\xb3\x56\x1d\xa2\x90\xa7\xae\x0c\xfc\x00\x9f\xcd\x3d\xb4\xf1\xf0\x93\xd3\xb6\xfd\xd6\x46\x42\x64\x94\x71\x1d\x7c\x57\x63\x4c\xf5\x78\x5c\x1c\x04\xb8\xbb\xf8\xed\x62\x16\x5f\x0d\x71\xca\x24\xed\xd7\xa5\x77\xef\xe7\xef\x3a\x16\x60\x29\xca\xd4\x71\xf2\x63\x49\x98\x62\xe6\xdc\xb5\xaa\x89\xfc\x36\x33\x23\x40\x0f\x24\x51\x80\xb5\xae\xed\xdd\x3f\x26\x7f\x97\x98\xb5\x45\x72\x67\xb2\x5f\x2c\xad\xe2\xeb\x05\xee\x07\x12\x13\x22\x77\xea\xf6\xb5\xfc\xd8\xbb\xfb\xdb\x9b\xb2\xda\x97\xf8\x9e\xf7\x1e\x19\x06\x2c\xa6\xa9\xf2\xa5\x6a\x4c\xf4\xfe\x10\xf5\xa4\x28\x03\x8c\x59\x9a\xba\x1a\x9a\x55\xd1\x54\xe7\x19\xc2\x1a\x60\x26\xc6\xbe\x96\xed\x6e\xb1\x5b\xed\x1f\x7f\x3e\xac\x3c\x25\x0e\x70\x62\xab\x0a\x36\x86\xf8\x09\xd9\x7c\x88\x02\xdc\x41\xfe\x31\x0c\xae\xad\xde\x64\xd6\xd9\x0a\xe0\xc2\x36\xb5\x36\xa2\x7a\x81\xc6\x67\xd0\x21\x85\xd4\x75\x71\x21\x7e\xa5\x67\xa9\xfb\xd6\x84\x80\x60\x42\x5b\xf0\xcb\x27\x8a\x19\x4c\x59\xc3\xbe\x38\x4b\xd8\x0f\x70\x7d\xbb\x5c\x74\x24\x4a\x20\x25\x24\x56\xa3\xe3\xc3\x37\xf4\x7f\xeb\xca\x81\x0a\x88\x45\xbc\xe6\x20\x2a\x47\xae\x36\x10\x84\x9a\x0e\x66\x01\xf7\x0f\x88\x12\x4e\x21\x1f\x65\x7f\x40\x45\x41\x27\xf4\x61\x5b\xdd\xfe\x04\x51\x59\xbd\xf1\xde\xb0\x79\x4a\x08\x50\xc6\x18\x9b\x53\xde\xcb\xc6\xc7\xde\xa0\x13\x1a\x41\x4f\xd9\x53\x47\xe1\xb8\x84\x05\x90\x58\x8d\xd7\x21\x6e\xfd\xa9\x82\xcb\x4e\x5e\x00\x6a\xb4\xe3\x69\xdd\xd7\xea\xb5\x82\x43\x3d\x50\x47\xa7\x00\x82\x61\xa8\x91\xa3\xd2\xac\xdf\x67\x3b\x19\x1d\x0a\xc6\x58\x66\x8e\x6b\x68\x44\x96\x83\xb6\xc8\xb9\x19\x7d\x0c\x3b\xde\x04\x4c\x20\x7e\x57\x66\x2f\xb2\x3c\x60\xd2\x7d\x9b\xbd\x8c\xd0\x59\x26\x50\x12\x9b\x79\xaf\x45\x95\x95\x88\x27\xcc\x6a\x9b\x6b\xec\x46\x40\xc2\x6c\x46\xef\x0e\xc4\xb1\x7d\x85\xa3\xf7\x66\x88\x4a\x7d\xc5\xe8\x29\x9b\xc6\x32\x86\x18\x9d\x10\xdf\x9a\x36\x9a\x04\x6e\x40\x18\x58\x7e\x85\xbb\xf2\x65\x89\xfa\x95\x16\xf1\x34\x56\xb0\x9c\x9c\x92\x30\xc4\xc7\x2c\x5e\xaa\x72\x07\xea\xb5\x0d\xda\x87\x06\xc1\x84\x02\xd0\x50\xc8\x0e\x03\x60\x42\xe0\xd8\xd2\x85\x41\xc2\x70\x63\xf4\xc7\x8d\x4e\x1c\x45\x0b\x6e\xdc\xfd\x86\x6d\x62\x6e\xb3\x35\xa6\x02\x18\xe6\x41\x4d\x2c\x64\xe8\x68\x46\xb7\x03\xd1\xa3\xf1\xcd\x26\x89\xa5\x5d\x6c\xcd\xb4\x50\xbb\xf2\xe1\xee\x66\x3a\x82\x11\x5c\x3d\xbd\x82\x1b\xb2\x57\x4e\x5d\x32\x93\x08\x9b\x74\x28\x8f\x50\x6c\x5f\x4b\x0f\xb8\x34\x54\x70\xfc\x84\x98\xc0\xac\x10\x42\x3f\x3e\x91\x6a\xee\xd1\x39\x8f\x32\xcf\x5e\xec\xbb\x1d\xe6\x36\x7d\x52\xd2\xb0\x20\x41\x56\xb9\xed\xb1\x3c\x35\x97\xcd\x7b\xdf\xae\x5f\xc3\xc2\x84\xb9\x9a\xc1\x36\x7b\x99\xee\xb3\x86\x25\x31\x42\xe9\x0f\xa2\x2a\x47\x12\x7d\xd4\x70\x42\x29\x77\x00\xfd\x21\xaf\x8c\x3f\xcc\x24\x46\x14\x3f\x4f\x87\xac\x78\x99\x05\x6c\xba\x91\x69\x94\xe0\xce\x06\x9f\x48\x9e\x57\x2d\x10\xa4\x0a\x7a\x7d\x25\x8a\xb7\xeb\x4a\x98\xee\xe3\xa5\x9c\xe3\x07\xbf\x5f\xfc\xb1\xbf\x5b\x3d\xdc\xee\x7e\x74\x47\x52\x2b\x10\xb4\x52\x65\x5e\xbe\x64\x4a\xe4\xdb\xd7\x0c\xba\x86\x23\x93\x6a\x01\xa4\x5b\xf1\x33\x65\x2c\x23\x03\x6e\x69\x53\xdd\x56\xf8\x73\x58\x67\xe8\x1f\x4b\xc6\x6c\xd4\x6f\x89\x45\xcd\x39\x4b\x4b\xba\x0c\x83\x91\x26\xd2\xce\xa8\xad\xbf\xc2\x4e\x19\x15\xda\x5e\xff\xf6\xf7\xb3\xe2\x04\x6b\xe5\xbb\x7b\x8d\x4a\x54\x10\x79\xd4\xd7\x44\xf0\x91\x1a\x1d\x04\x56\x7e\xf1\x24\xa7\x30\x37\x3f\x22\x8c\x39\x73\xd2\x9f\x95\x1e\x94\xeb\x8d\x4e\x29\x82\x1b\xac\x9d\x71\xbc\x36\x93\xa7\xe9\x1e\x43\x8b\x10\x3b\x35\xd7\xcb\xc7\xfd\x66\xb1\x5b\x45\xdd\x55\x40\x23\xc7\xad\xc8\xda\x99\x60\x85\x44\x9e\xa0\xda\x55\x1d\xc0\xd8\x00\x61\x9e\xc7\x73\xd3\x65\x78\xbd\xb6\x65\xdd\x8d\x62\x22\xb4\x8e\xdf\xa1\x7c\x87\xe9\xfd\x0c\x03\x56\x03\xed\x5a\x1e\xe4\x8b\x7f\x87\x42\x4f\x7b\x6c\x8d\x09\x03\x0c\xfb\x84\xd6\xbf\xc3\x6b\xa6\x2e\x29\xc6\x2e\x5a\xd2\x67\x9d\x2f\x63\x78\x82\x24\x31\xae\xa4\x87\xcc\x38\xf3\xe4\x8d\xd4\x18\xb0\xfc\xbb\xbe\x55\xeb\x2e\xab\x5d\xe1\xe3\x5e\x1c\x47\x37\xc8\x02\x12\x86\x08\x1b\x75\xf1\xdc\xe5\xbc\x64\x01\xa1\xb6\xe3\xa0\x86\xa6\x63\xf9\x9f\x0c\x09\x89\x44\x5a\x0b\xf8\x04\x75\x6a\xca\x6a\x91\x67\xef\xee\x13\xb3\x20\xe4\x31\x82\x3e\xea\x32\xd7\x57\x00\x15\xe6\x89\xba\x83\xd2\x02\x32\x0c\xf8\x3e\x0b\x51\x9d\x9f\xca\xb1\xbd\x67\x41\x14\xd8\xaf\x57\x97\x55\x33\x51\xe2\x74\xb3\xa3\x1d\x23\x12\x47\xe3\x8b\x9e\xa4\x63\xb8\xbc\xca\x9a\xf6\x17\xfb\x70\x69\xfa\xa2\xa7\x99\x50\x16\x44\x8a\x25\x5d\xe3\x23\x26\xc0\xda\x57\xd8\x75\x76\x4e\x08\xb8\x58\x90\x84\xb1\x8b\xbc\x1a\x87\xbc\xb5\x7a\xdc\xe3\x97\x44\x09\x45\xac\xd3\xd1\xd1\xc4\xf4\x4e\xca\x06\x54\x76\xcc\xc0\xef\x11\x2c\xa0\x5c\x23\x22\x16\xf7\x3f\x4b\x67\x70\x81\xbd\x9b\xfb\xf6\x2c\xa0\x22\xc4\x79\xe2\xca\xb5\xcf\x83\xca\xe7\xe0\x1c\x9b\xd4\xfd\xdb\xe4\xfe\x74\x88\x34\x62\xd7\x95\x78\x29\x8b\x5d\xbb\x88\x4e\x15\xcc\x03\xdd\xc7\x67\xb2\x20\x62\x5e\xd2\xee\x4b\x97\x71\xfe\x7e\x59\x64\xf9\x3a\x84\xd6\xde\xea\x8e\x68\xe1\xbe\x0b\x49\x58\xc0\x62\xc1\xbd\xb3\xe6\xb7\x1d\x57\x3b\x99\xbc\x2e\x7f\x82\x02\x14\xa6\xb1\xcb\xfe\x49\xd4\xf5\x6f\x93\x01\x46\x61\xbe\xf7\x28\xce\xd2\xe7\x58\x69\xfc\xb7\xe9\x17\xe7\xc4\xb6\x0f\xb9\xbf\x6f\x97\x98\xcd\xcf\xda\x07\x1f\x91\x73\xb1\x80\xc7\x09\x62\x3c\x7e\xcf\x54\x53\x56\xe7\x3f\x7e\x19\x17\xb3\x80\xd3\x64\x54\x68\x46\x38\xf5\x4d\x59\x2d\xcb\x3c\x07\xd5\x64\xf2\x0b\xa2\x42\x16\xa4\x54\x28\xdb\x72\xad\xef\xda\x4d\xe8\x77\xa8\xea\x21\xb9\xd1\xf8\xb3\x89\x34\x44\xcf\xb9\x86\xe6\x0e\xbd\xc7\xa0\x77\x60\xda\xa3\x02\x73\x50\x35\x2a\xee\x5f\x43\xd6\x9c\x27\x13\x5a\x06\xc4\x96\xce\x1b\xf1\x02\x1d\x18\x82\x05\x32\x24\xae\xa9\xd0\xf2\x4c\x3c\x89\x73\xb7\xde\x25\x48\xcc\x76\xb8\xaa\xd4\x16\xf2\xbc\xef\xdc\xbf\x7c\x20\x15\x13\xe9\xb2\x37\x43\x6c\x6a\xeb\x2a\x63\xbf\xe2\x30\xc0\xfa\x6a\xa6\x7d\x31\x77\x14\x04\x58\xab\xaa\x85\x81\x5b\xe4\x3f\x1b\x0a\x96\x4d\x06\x6b\x16\x20\x37\xc5\xb6\xc9\x8a\xb7\xf3\x5d\xfb\x3f\xfe\x89\x80\x87\xba\xe7\xfa\xbb\xa9\x00\x9e\x8b\x26\xcb\x2f\x48\x83\x59\x60\x48\x80\xae\xcc\xa9\x86\x4e\xa1\xef\x62\x3b\x65\x81\xe1\x56\xe8\xc4\x6f\x2c\xb8\x5d\x7e\x81\xbc\xf5\xa7\xa8\x48\xba\xbc\xdb\x52\x1c\xe7\xb0\x19\xed\x18\xca\xd1\x21\x3d\x15\xba\x12\x59\xdd\x95\xc0\x18\x21\x94\x43\xd4\x15\xf6\x51\xb8\x76\xab\x32\x28\x14\x4c\x3b\xd1\xdc\x09\x61\x10\x47\x51\xcf\xf3\xfa\xc5\xa8\x28\x4e\x53\x1b\x9a\x18\xb8\x1e\x3f\x24\x89\x62\xdb\x13\x23\x14\xd6\x84\xfd\x9d\x44\x22\xc2\x29\x99\x97\x2f\x2f\x63\xf9\x9b\xf1\xe9\x89\xa3\x5e\xb1\xe2\xf5\x73\x1b\x34\x23\x09\x53\x88\x5f\xec\x09\xba\x76\x20\x0e\xdb\x06\x8e\xe1\xf4\x6a\xd2\x12\x75\xb7\x7e\xc5\xd3\x66\xbd\x5c\xf9\xdb\x49\xb4\xf1\xa4\x23\xcf\x45\xf9\x51\x80\xf5\x5d\xe6\xde\x2f\x49\x8c\x49\xba\x66\x70\xc4\x62\x0f\x9a\xe3\x18\xa1\xc4\xf2\x03\x5a\x58\xdb\x84\x57\x9e\x11\xc6\x40\x3a\x5c\xed\xf6\x08\x79\xbe\x90\xd8\x57\xb3\x2c\x1d\x16\x82\xbb\x71\x3c\x0a\xec\x7e\x3d\xaa\xbc\x8d\x35\xba\x19\xe1\xdc\xb2\x1b\xd4\x96\x50\xe6\xbe\xd4\x60\x95\x3f\xbb\xe5\x4d\xb8\x26\xc4\x59\xb0\x6e\x87\xbb\x4c\x3c\x32\xc2\x21\xe4\xb6\x57\x42\xc2\x77\x9a\xe2\xed\x48\x86\x8d\x7a\x2a\x2f\x6b\xf8\x09\xf0\x96\x9f\xed\x96\xd9\xdd\x95\xf1\xd2\x7e\xa2\x52\xaf\x7f\x2f\xe5\x97\x79\xc6\x0b\xa9\x29\xfe\xd7\xbf\xfe\x8a\x87\x52\xfa\x5f\xe8\x51\xb9\x5f\x4a\x63\x4b\x24\x62\x09\x0f\x6c\xa6\xaa\x7d\xc0\x47\x33\xc9\x9a\x32\x92\xd2\x10\xab\x35\xb7\x8b\xfb\xd5\x1e\xd1\xd2\x3e\xd9\xc2\x48\xca\x03\x24\x92\xdc\x1e\x45\xf1\x36\x2b\x29\x39\x6b\x2d\x88\x88\x34\xee\xf4\xd7\xab\x9b\xc5\xf3\xdd\x6e\x7f\xf7\xb8\xfc\xc7\x7e\xf9\xb8\xdd\x61\x7a\xf3\xc7\xe3\xf3\xc6\xff\x82\x50\x02\x1b\x91\x0b\xf8\xd8\x82\x1a\x45\x58\x5f\xf8\x85\xfe\x44\x50\xcc\xca\x10\xee\x2a\x81\xac\x5b\xc3\xf8\x9a\x11\x19\x2b\x6c\x1f\x12\xd6\x59\xda\x9e\x0e\xb7\x1f\x9e\x87\x97\x11\xa9\x89\xd2\xa3\x24\xc7\x75\xaf\xd1\x33\xf9\x25\x09\xb6\xc1\x16\x55\x21\xdc\xdf\x34\x35\xa9\xcb\x13\xed\x36\x4b\x3f\xfb\x2e\xd0\x1f\x8c\x68\x4e\x70\x3b\x75\x85\x1b\xc8\x41\xfe\x36\x43\x7c\xcd\x08\x10\xdb\xe2\xfb\xf7\x32\x2b\x50\x95\xab\xb6\xd0\xde\xdf\x2e\xdf\xb3\x5f\x0a\x10\x53\x6d\xdb\x94\x3f\x37\x18\x57\xac\xbb\x0f\x07\x10\x28\xda\xd9\x64\x8b\xb8\xb2\x6e\xc1\x60\x66\x83\xe1\xb1\x1e\xc2\x0f\x7e\x66\xc5\x85\xf7\x4b\x4c\x1a\xe3\x96\xea\x8b\xe8\x5b\x68\x9e\xd7\xbf\xc8\x95\x32\x62\x04\x4b\x9d\x03\xd7\x7a\x84\xed\x7c\x9f\x75\xd6\x59\x18\x28\x89\x75\xe4\x89\xda\xd9\xf4\xdf\xf1\xe4\xfb\xf6\xc7\xc3\x00\x02\x2c\x88\x42\x3b\x75\x06\x11\x33\x0b\x03\xe3\xe8\x9f\xc5\xa7\x2d\x24\x0e\x93\xe8\x2c\x24\x2a\xa0\x28\x79\xb3\x7a\xd8\x8d\xce\x23\x3a\xc5\x24\xd4\xea\x90\x55\xa2\x81\xba\xe7\x2d\x60\x21\x01\x89\x99\x46\x4b\xe0\xb7\x3d\x17\x3a\x53\xa2\x01\x9b\x59\xf6\xcb\x2c\x0c\xd3\x14\x59\x24\x91\x14\x01\x45\x09\x06\xed\xa1\x2c\x8c\x42\x2b\x87\x5a\x43\x73\xfb\xb4\xbd\xcf\x8a\xd5\x44\x80\x91\x85\x11\xa3\x44\x74\x5d\xd4\x68\x65\x6f\xca\xea\xba\xfb\xe8\x61\xa4\x34\x3e\xf6\xe2\x9f\xcf\x8b\xc7\xf5\x83\xff\x73\x1c\xd8\x22\x45\x47\x92\xe1\xb1\xc9\xbf\x04\xfd\x4f\xff\xff\xec\xca\x1c\x06\x0e\x61\x4c\x03\x4d\xba\xe6\xec\xf7\x4c\x63\x96\xfe\x58\x66\x53\xd2\x32\x16\xc6\x90\xc4\x6e\xe5\xcf\xf9\x75\xbf\xd0\xbf\x9d\x1c\x1e\xda\xe1\x30\x36\x94\x5b\x16\xa5\xf6\x53\x3d\x1e\xe1\x82\x06\xcd\x0d\x4c\x28\x0d\x5d\x96\x6d\x3d\xf0\x7c\x46\x6f\x3d\x51\x31\x32\x14\x6d\x9b\xf6\x6a\x2f\x99\x7a\x12\x55\xd3\x06\x81\x5f\x4c\xe7\xc4\x08\xcc\xc7\x2f\xad\x86\xc5\x8b\x87\x46\x4c\x9e\x9e\x12\xcb\x9c\x92\xd5\x4f\xe2\x8c\x9c\x81\x05\x36\xec\xdd\xb4\xb1\x63\xee\x3f\x1d\x65\x81\xec\xb0\x63\xc7\xb2\x72\x8b\x54\x97\x1f\x57\xe7\x1e\x6e\x37\xbe\x01\x2a\xc1\x8b\x74\xed\xb1\xb8\xbe\xd7\x53\xd2\x78\x16\xb2\x28\xc5\xbc\xde\x2d\x34\xd7\xe5\x41\x64\x05\xa6\x8f\x46\x6f\x91\xd1\x08\x61\xa9\xad\x1f\xb7\x1f\x13\x8b\xb0\x90\x13\xdb\xa9\xe0\xbe\xdc\x4e\x7c\x4e\xd2\x67\x2c\xe4\x46\x74\x80\x8b\xf3\xb2\x12\xd9\xcb\x6d\xd5\x49\xef\xb3\x30\x0d\x15\x6e\x96\x96\xad\x67\xd5\xbc\x3a\x40\xbf\x3b\x2c\x82\xc4\xf8\x76\x47\xe7\x45\x0f\x99\xa3\x58\x28\x04\xa1\xce\x03\x7b\xaa\xca\x23\x54\xcd\xf9\xde\xbb\x92\xc4\x55\xa2\x87\xde\x50\x28\x49\x1c\xbb\x06\xeb\xec\x70\x3a\x38\xa1\x08\x7f\x39\xad\x92\x10\xbc\xea\xe0\xea\xf3\xf8\x5c\xb4\x6e\xf1\xe4\x91\xb4\xb2\xfd\x52\x58\xd7\x7d\x2c\xdc\x37\xf3\x97\x00\xc5\x90\xa3\x0e\x3f\xb7\x8d\x27\xb2\xe6\xec\x39\x51\xfd\x28\x13\x59\xb6\x15\x9b\x60\x79\xfa\xfd\xc9\xaa\x69\x4f\xd1\x17\x2c\x34\x89\x40\xc8\xf4\xb1\xea\x09\x8d\xe7\x13\x1e\x2c\x34\xc6\x8a\xbb\xc8\xd3\x19\x19\x78\x3a\x7f\xd4\x1e\x8f\x82\xd8\xea\x63\xbc\x94\xfa\xb9\xc0\x96\x03\x7f\x84\xa8\x18\x11\xc2\x42\xeb\xe7\xda\x91\x84\xdc\x95\xaa\x6b\x97\x99\xff\xc1\x88\x98\x88\x74\xc2\x04\x9f\x13\xf6\x11\x16\x85\xc4\xf2\xce\x78\x02\x8d\x41\x0b\x0a\x8b\xc2\x50\x63\x05\xee\xfa\x79\x63\x3b\x3d\xb6\x8b\xbb\xd5\x76\xb7\xb8\x5d\xdd\x2d\xb6\xbb\x6e\x54\x4c\xb0\x6c\xfd\x75\x4f\x2d\x21\xbd\xff\x43\x82\x41\x57\xed\xd0\x22\x45\xa1\xa6\x2a\x1e\xf5\x8d\x79\xf8\xc2\xb7\x4d\xde\x2c\x0a\x4d\x2a\x2c\x93\x8d\x4b\xa7\xe1\x76\x5c\xdf\x96\xe5\x53\x55\x6a\x97\x82\x99\x7f\x3b\x11\x0f\x70\x75\x6d\x5f\xb3\x63\x26\x7e\xeb\xfe\x6a\xa9\xb9\x56\x7f\xae\x8b\xa2\x7c\x77\x94\xf8\xdd\x3e\x12\x45\x10\x12\x54\x03\xf9\x98\xa6\xdc\x06\x57\x36\x2c\xb0\x04\xf2\xbf\x8b\x3c\xd3\xdb\x41\x2f\x84\x1b\x11\x53\x86\x20\x85\x1d\xd4\xcd\x32\x6b\x3a\x04\xb5\xa7\x2d\xfb\xe2\xc2\x49\xca\xad\x14\x49\x75\xf6\xba\x4a\x03\x7a\x03\x16\xd1\x88\x0b\x1b\x2a\xb7\xeb\xfd\xd6\xe5\xeb\xbd\xb7\x15\xd1\x04\x70\x5f\xbd\x05\x91\x43\xd1\x3d\x32\xe5\x02\xfb\x92\x3b\x55\xed\x11\x32\xee\x02\x09\xc6\x22\x16\xcb\x90\xb8\x12\x3e\xd6\x1b\xba\xdb\x9e\xee\x49\xc3\x6f\xcc\x40\xa1\xde\xc3\xed\xe7\xc2\xea\x20\x8e\x67\x23\x03\xa5\xd2\x01\x63\x48\xd3\x23\x03\x66\xf3\x02\x11\x8f\x15\x71\x6a\x59\x21\x54\x2a\x0c\xfc\xf3\xa4\x01\x89\x8c\xab\x90\x7c\x15\x6c\xf7\x0e\x56\x94\x32\x8d\x78\xf0\x4f\x71\x6a\xb7\xea\x5b\x51\x0f\x1a\x41\x58\x24\xa9\x45\xf7\xcb\x53\xd3\x94\xc5\x32\xcf\xd4\x5b\xb7\x48\x64\x2a\x91\x2e\xe2\x66\x77\xe3\xbd\xcb\xa1\x43\x12\xa9\xc0\xb1\xb9\xe6\x13\xbf\x95\x8c\x7c\xc4\xa8\x35\x6b\xac\x47\x15\x21\x4a\x79\xea\xe2\x45\x8a\x11\x64\xb7\xb4\xb6\x18\x83\x4e\xff\x3b\x9a\x46\x91\x1a\x44\x49\x43\x46\xa6\xc9\x5b\xd3\xa9\x65\x3f\xc9\x0a\x59\x7e\xae\xeb\xd5\xe1\x38\x4d\x98\x44\x10\x10\x7c\xaa\x9f\x16\x5b\x5b\x5f\x89\xfa\x0d\x9a\x4b\x80\xc6\xb7\xd9\xb6\x08\x22\x4b\x29\xea\xa5\x0f\xd7\xcb\x47\x35\x85\x01\xf9\xa1\x29\x8f\x2c\x8f\xcd\xc7\xaa\x98\x07\xed\xb2\x08\x20\x8a\x2c\xc9\xf2\xfa\x61\xff\xe3\xf1\xee\x7a\xb5\xd9\x2f\xae\xaf\x7d\x8c\x12\x19\x66\xa1\xbf\xad\x2f\x5b\xe6\x17\xa9\x08\x3f\x4a\xc5\x3e\xa4\xd8\x1f\x2b\xd8\xbf\x9d\xd5\x3e\x53\x65\x91\xfd\x67\x8f\x7c\x60\x7b\x0d\x45\x79\x70\xd2\x21\xa3\x1b\x88\x83\x88\x50\xcf\x62\x92\x15\x2f\xb5\x63\xec\xd1\xb6\xe8\x7a\x31\xb8\xd3\xa7\x5c\xbd\x0b\x59\x36\xdf\x21\x07\x58\x1c\x08\x92\xc6\xbe\x5f\xb5\xde\x95\xd6\x8f\xf8\xad\x3b\x4a\xad\x64\x5f\x0e\xa2\xda\x2c\xee\xbb\xbf\x2b\x83\xc5\xbb\xdd\xed\xfa\x66\x7a\x41\x0d\x48\x8e\x54\x08\xab\x0f\xd7\xed\xd9\x31\x49\x65\xe2\x2a\xfb\x8b\xac\xba\xcb\x4c\x73\x59\xdb\x67\x71\x28\xd2\x38\xbc\xf4\xf7\xa7\x19\xda\xde\x46\xcc\xbe\xee\x38\x0a\x63\x4b\x1e\x01\xed\xbe\x20\x72\xeb\xce\x8f\x24\xfb\xfd\x48\x41\x7b\x35\x54\x27\xde\x50\x2f\x06\x6e\x7f\x1c\x19\x81\xfb\xba\xec\x29\x91\x5b\xe3\x33\x61\x03\x63\x71\x2c\x68\x14\xf9\x76\xb5\x36\xbc\x1f\x38\xd3\x96\x75\xce\xfa\x2a\x7d\x66\x29\x4e\x38\x8d\xa4\x87\x21\x6c\x00\x75\xc0\x7c\xf1\x87\xc5\x49\x9a\x44\x7e\xdf\x6e\x44\xb5\xb6\x0d\x6e\xb3\xe9\x95\x38\x01\xc5\x2c\xcf\x13\x0a\x01\x79\x97\xa0\x1c\xd3\x8f\xb3\x98\xb2\x00\x0b\xcb\xb6\x9f\x67\x57\x7a\xf4\xc9\xf8\x2b\xb0\x20\x40\xb0\x6c\xb7\x1b\x3e\x55\xe5\x4b\x25\x0e\x93\x27\xe6\x91\x41\x2f\x6d\xb9\xd8\xa1\x50\xce\x25\xa6\xc1\x0d\x4c\x83\x44\x5b\x68\x77\x3b\xbd\x1c\x3b\xd1\x9c\x71\x8d\x53\x92\xf8\x06\x6a\xa1\xbb\xb9\x93\x12\x89\x8c\x14\x48\xdb\xd8\xf7\xa5\x4c\x4e\x65\x46\xa0\x56\x45\xb7\x2f\xc5\x29\x67\xb8\xd5\xa2\xac\x1b\x92\xb0\x60\x02\x1e\x0b\xcb\x93\x47\x4e\x21\x65\xb2\xeb\x58\x41\xc0\xcf\x16\x63\xda\x4b\xa9\x6c\x3b\xd7\xc2\xff\xfd\x1f\xf7\x13\x82\x70\xb4\x24\xc7\xb2\x6e\xc6\xf9\xad\x58\x0a\x21\x7a\x7f\xf7\xd1\xfc\x28\xf3\xbe\x13\x92\xc5\xad\x65\x34\x88\xc7\xb5\xef\x79\x91\xe7\x97\x02\x79\x2c\x86\x38\xc5\x0d\xe8\x58\xc1\x0b\x14\xf3\x18\xfd\xf1\xce\x1e\x83\x92\x24\x1c\x36\x2e\xb8\x77\x4b\x26\x2f\xd7\x84\x0c\xcb\xd0\xf7\x22\x6b\x1d\xd2\xd6\xf9\x43\x51\xde\x41\x51\x9f\x25\x41\x28\x22\xe3\xdb\xfc\x76\x20\xba\x1a\xce\x28\x8e\x4e\x02\x66\x85\x98\xf3\xf2\x1d\x9e\x2b\xbf\x99\x24\x61\x62\x9b\x34\x6a\xc8\xf3\x5f\xec\xc1\x49\x1b\x21\xa1\x99\x80\xaa\x91\x9e\xfe\x86\x25\x21\x73\x80\xe0\xf6\x69\xaa\xb7\xd3\x71\x3e\x69\x93\x84\x2a\xc4\x82\x5c\x07\x8b\x6a\x3f\xf5\x01\xee\xbb\x56\x66\x96\x44\x71\x84\x31\x8c\xca\x45\x76\xe8\x0a\x7b\x61\x77\x58\xdb\xae\x53\xdb\x77\xd7\x51\x86\xcc\x91\x2e\xcf\xff\x73\xba\x00\xf9\xb2\x24\x32\xda\xc3\x6f\x7e\x66\x85\xeb\x17\x98\x8a\x82\xb2\x24\x0e\xe3\x98\xfb\xec\x89\x99\x2d\x57\xb3\x24\x8e\x52\x8c\xb5\x0f\x59\x81\x13\xff\xa9\xcb\x26\x24\x89\x88\x2d\x11\x59\x95\xbd\xbc\x40\x1b\x51\xda\x7e\x48\x3f\x8f\x12\x1a\x58\x7d\xe0\xd5\xd5\x1a\xf1\x5e\xdd\xdf\x13\x8e\xc9\xce\xc3\xfe\xa9\x8d\x12\x74\xf7\x77\xce\xb1\xe3\xa0\xcc\xf5\x7d\x96\xe7\x59\x59\xac\x7a\x1d\x45\x96\x30\x4a\x0c\xe9\xd2\x8d\xcf\xe8\x86\x8c\x1c\xc4\x84\xb5\x0f\x65\x9f\x08\x0b\x55\x6d\x54\xf0\x4d\x8b\x09\x4b\x98\x50\xb1\xec\x7b\x8a\xdb\xbd\x7d\x6c\xe8\x12\x66\x54\xec\x68\x03\x77\x1f\xbf\x94\x4f\x76\x27\x71\xa1\xa8\x9d\xe5\xa0\xa0\x10\xf5\x04\xb5\xcd\x92\x94\x87\xae\x9b\xb0\x6a\xc3\xb6\x41\xf7\x54\xf7\xc3\x82\x68\xcc\x12\xe1\xc4\xb1\x2f\x76\x9e\xf3\xd9\x8f\x8f\x01\x33\xdf\x36\x01\xb3\x55\x65\x05\x8b\x42\x4f\xb4\x3f\x2f\x92\x2e\x93\x6b\xa4\x41\xec\xe6\xbd\xdb\x25\xc6\x3a\xcc\xe3\xa7\x14\x60\xd0\xa1\xdb\xfe\xb9\x44\x0a\x80\xb1\xdc\x15\x4b\x14\x35\xb4\x4f\x09\xe9\x61\xb3\xef\x70\xcf\x49\x14\x4f\x10\x5d\xaf\xa1\x81\xea\x90\x15\x6d\x24\x8a\xf4\x73\x98\xe9\xf4\x83\x52\x6e\xe3\x96\xd6\x26\x58\x38\x7f\xc7\x33\xcb\x12\x1d\x58\xe6\x75\x4b\xaf\xe9\x6b\x58\xcb\x76\x2f\xfe\x7f\x5b\xb7\x72\xf9\xa6\xf1\x8b\xd1\x3a\xc0\xea\xd3\x42\xeb\x27\x3b\x55\xfe\x01\xe7\x99\x26\x76\x96\x68\xc3\xb1\xd2\xfe\x56\x94\x1f\xb3\xe0\x50\x96\x40\xc8\xb1\x82\xde\x41\x4b\xca\x6a\xa8\xcf\x36\x7e\xc9\x20\x59\xd8\x77\x8e\xae\x3e\x33\x74\xde\x36\xe2\xbf\xbf\x9a\x8a\x93\xeb\x18\xe0\x40\xba\x8c\xc0\x9c\x87\x4a\x83\x48\x70\xea\xc9\xcc\x8d\x38\xe5\x0d\x86\x7f\x59\x73\xbe\x2a\x3d\x08\x96\xd1\x20\xb6\xa9\x2a\x99\x15\x9d\xa8\x03\xa3\x81\x26\xda\x11\x86\xb5\x5f\x0d\xa9\xf6\xba\x63\x10\xc7\x6e\x6f\xb8\x2b\xeb\x76\x3b\x1a\xdd\x1a\x25\x9c\xcb\x91\x98\x9b\x2b\x12\x8a\x6f\x98\xf3\xe6\x9f\x92\x46\x51\x40\x9d\x1f\x6a\x89\x7a\x90\xe3\x65\x68\x23\x68\xc4\x23\x2f\x9e\x68\x63\xd0\x1a\x06\xce\x12\x8d\xb8\xc2\x74\xb5\xc3\x9a\x39\xfe\xed\x21\xd6\x8f\xd1\x18\x64\xec\x9c\x63\x97\xd7\x5f\xd7\xf5\xa9\x5d\x67\x48\xd2\x34\xfb\x21\x69\x42\x48\x6c\x6b\x6e\x67\x91\x37\xe7\xd1\x56\x46\x93\x34\xf6\x75\x29\x97\x01\x18\xa6\xa1\x28\xe5\x20\x3d\x51\xf6\xce\x52\x14\xd6\xfd\x41\x13\xd9\xd6\xfa\xa6\xac\x60\xdb\x9c\xe4\x85\xb7\x3b\xb2\xe8\x94\xd1\x14\xfd\x1b\x93\xb9\xa2\x70\xbb\xbb\xae\x3c\x4b\x0e\xa3\x8c\xc5\x08\xc4\xfd\xb7\x6d\xf4\x99\x34\xd0\xb5\xc7\x01\xcb\x98\x8b\x3a\x17\x43\xa4\x18\xa3\x4c\x73\x69\x49\x8e\x90\x9d\x41\x7c\x76\x92\x88\x8c\x0a\x62\x61\xf3\x8e\x77\xe0\xa6\x2a\x67\x79\x5a\x19\x95\x32\x88\x61\x34\x1b\xca\x32\x9f\x9d\xaf\x3a\xb2\x19\x58\xec\x49\x40\x75\xfd\xd1\xdd\xe8\x24\x40\x2a\xdc\x83\x25\x48\x80\x29\x5e\xb6\x4f\x0c\x4c\xbe\x94\xd6\x14\x29\x65\x76\xeb\xd5\x26\x1a\x33\x84\x30\xaa\x41\x61\x58\xe8\x9a\x64\x1e\x6e\x3a\x56\xf7\xbf\x92\x8b\x96\x0f\x77\x0e\x40\x88\xf4\x18\xe6\xff\x43\x3b\x43\x77\x29\x21\x7b\x11\x84\xdf\x51\x79\xa9\x19\xc7\xe6\x2e\x28\xa7\x26\x4a\xe2\x68\x2c\x29\x56\x62\x8f\x92\x7f\x14\x13\x47\xc2\x76\x7e\x14\xaa\xac\xae\x45\x86\x59\xbd\x9d\x65\xb6\xcb\x3d\x1d\x30\x63\x01\xe3\x18\xdd\xfb\x0a\xef\x4d\x59\x3d\x4e\xa0\x49\x2c\x24\x80\x00\x13\xf7\xb2\x5d\x63\xe7\xf6\x3b\x99\x0a\xc6\xc2\x58\x22\x68\x43\x66\xc5\x4b\xe9\x7f\x2d\xe4\x09\x4f\x3b\xea\xc1\x66\xf1\xf2\x55\x57\x35\x63\x11\x21\x2e\x53\x5a\x56\x70\x93\xe5\x3d\xc3\xf9\xff\xe8\x38\x8d\x69\xd7\x18\x8b\x98\xc4\x6c\xb2\xef\x5f\x7f\xea\x28\x51\x98\xcd\xd7\xf8\x5e\xec\x46\xe4\x4e\x79\x7b\xf4\x79\x58\xa4\x53\xee\x32\x96\x8b\xba\xdd\x45\xaf\x11\x3a\xe1\x8e\xc6\xc4\x32\x77\x5b\xb5\xa7\x45\x9e\x3f\x57\x59\xdd\x1d\x8c\x62\xea\xac\xa4\x6b\x94\xfb\x4a\xe0\xae\x5d\xa0\x36\x2d\x2d\xf4\xbf\x4f\xb5\x37\xd6\xdb\x63\x95\x39\x56\xae\x79\x77\x95\x25\x09\xb1\xb5\x9d\xba\x75\xbf\xeb\x1e\x15\xeb\x8f\x4b\x82\x59\xcc\x87\xc5\xe3\x66\xbd\xdd\xef\x56\x8b\xfb\x11\xb7\x07\x6b\xed\x3c\x4b\xdd\x0a\x5f\x3e\x42\x31\x10\x0b\x62\x8c\xb2\x18\xb3\x77\xf2\x74\xde\x43\x01\xd5\xcb\x79\x82\x18\x18\xfe\xe3\x50\xad\x8c\x31\x62\xcd\x49\x56\x23\x1b\xc3\xe4\x49\x59\x62\x45\x78\xfe\x1c\x12\x26\x32\xc6\x84\x48\x7a\x60\xb7\x67\x8e\xdf\x42\x9e\x4f\x3e\x08\xd3\x01\x12\xd0\xbf\x42\x9e\x8f\x4b\x0f\x8c\x69\xc0\xc6\x43\xec\x86\xf2\xf4\xc5\xfe\x18\x28\xcc\x34\xde\x67\x85\x57\x9e\x9e\x6b\xc5\x62\x4c\xf0\x10\x1b\x62\x2c\x6d\xe5\x0c\x20\xcb\x8f\x13\x71\x0a\xde\xb3\x6a\xd0\x93\xee\x26\xeb\xf8\x82\x5a\x21\x0c\xf0\xa7\x7b\x26\x7f\x47\x02\x38\x06\xdc\xe2\x78\xac\xca\x77\x98\x28\x4f\xb8\x41\x32\x04\x4c\x44\x0d\x12\xbe\x4c\xc6\x9a\xcb\xbe\x9f\xa4\x23\x9c\xbf\x04\x21\x30\x49\xc1\x78\xb6\x66\x64\x83\x9f\x5e\x1e\x40\x90\x39\xbd\xf2\x2f\xfe\x9d\x02\x06\x98\x22\x32\xe0\x3e\x49\x32\xb5\xc7\x7e\x8c\x0f\xc9\x4a\x99\x15\xaf\x65\x89\x15\x83\xf5\xf5\x64\x9b\x68\xf7\x20\x84\x2a\x1e\xab\xf2\x50\xb6\xbb\xfc\x83\x57\x54\x60\xcc\x30\xc5\x47\x4c\xcf\xf7\xa2\x38\x4f\xe1\x84\x3c\x88\xa8\xec\x3a\x1a\x3a\x32\xe9\x59\x0b\xce\x03\x26\x91\x32\xb2\xeb\x5e\x3f\xb7\x16\xb2\x01\xfd\x2d\x41\xad\x3f\x99\x87\x58\x63\xb1\x73\x54\x98\x31\xe9\x1c\x52\x27\x23\xac\x36\x2f\xd5\xdb\xbd\xab\x65\x0c\xbf\x3d\x0f\x64\x68\x22\x5f\xa5\x40\xa7\x78\x38\x91\x39\x21\x0c\x79\xd2\xd0\x35\xc6\xbe\x03\x9f\xac\x9b\x7c\x40\x4e\x08\x47\xdf\xad\x2c\xf2\xf3\x75\xc7\x1c\xcd\x38\x89\x38\xee\xb9\xbb\x2a\x7b\xcf\x84\x25\x5b\x9e\x01\x62\x7c\x13\x40\x7c\xef\x4d\x7b\xdf\x83\x13\x87\x76\xdb\xab\xd7\xd6\xae\x21\x38\xb0\x6a\xc2\xef\x8b\x24\x3c\x12\xb1\x21\x9e\xbc\xa2\xb5\xa7\x43\x87\x8e\xc7\x9c\x23\x1f\x15\x26\xbf\xec\xee\x25\x3a\x61\xd3\xd9\x02\x73\x37\xe3\xdb\x73\xd1\x2b\xfe\xb9\xdd\x79\x5c\x1d\x8f\xb5\x55\xa2\xa9\x9d\x0d\xaf\x97\x50\x35\x99\xc9\xa6\x6b\x9f\xc7\x60\x10\x1d\xb5\xef\xaa\x3e\x18\x75\xfd\x6f\x31\x22\x4f\x52\x82\x59\x9c\xc3\xde\x31\x4e\x79\x91\xcc\x4e\xd8\x9f\xf1\x44\xa6\x18\x47\xee\xae\x57\xbd\x44\xbe\x3b\x46\x15\x41\xb0\x39\xd2\x30\xed\xaf\x17\x7f\x92\xbd\xaf\x75\xf9\x21\x8c\xdb\x44\x11\xca\xfb\x0f\xbb\xb9\x19\xe7\x24\xc0\x86\x9a\xfa\x24\x6b\x55\x65\x12\xee\x27\x42\x61\x7e\x9c\x10\xd8\xdc\xdc\x40\xdd\xec\x9b\xd7\x0a\x00\x63\x82\xd5\x7f\xda\xf0\xfb\xb7\xd1\x03\xa5\x10\xfa\xbe\xac\x81\x6a\xc3\xd0\x23\x76\x03\x45\x1c\x29\xd2\x51\x8c\x20\x5a\xac\x7d\x6f\xdd\xbd\x09\x9a\x10\xd1\x83\x17\xe7\x80\xaa\x7e\xa4\x36\x48\x57\xdb\x9a\x08\xe7\x4d\x5a\xd4\x79\x17\x98\x70\x2f\x82\xd9\x9a\x3f\xac\x80\x38\xf6\x8b\xb9\x8f\x33\xc9\xa3\x70\x19\x69\x0f\x2f\xd9\x9e\xe4\x38\x14\x1e\xdf\x88\x54\x06\x41\xbd\x76\x3f\xba\x12\xc5\x5b\x55\x4e\xb8\xee\x18\x57\x49\x8c\x7e\xe5\xd6\xc2\x67\xab\xe6\x62\x46\x29\x4e\x30\x75\x85\x97\xb1\x54\x22\x96\xc1\xc7\x56\x74\x26\x83\x65\x42\x99\x7f\xdf\x18\xf8\x56\x17\x39\x1e\xae\xb4\xc1\xb6\xa4\x17\xd1\xd5\xcb\xb8\x8e\x23\x74\xbb\xf6\x05\x4c\xe8\xaf\x18\xd7\x32\xc2\x8f\x28\xad\xf2\x05\x62\x2c\xbb\xf3\x00\x8c\x75\x1f\x6e\xc5\x01\xba\xbe\x48\xc6\x81\x46\xd8\xae\xf1\xc7\xc8\x6a\x01\xe7\x96\x99\xcf\xaf\x0e\x9f\x1f\xb0\x2d\xa3\xb3\x5f\x80\x4c\x57\x89\x09\x62\xe7\x0d\xaa\xb2\xf5\x36\xa0\xf2\xc9\x81\xe7\xe3\xd1\x51\x9e\x0d\x93\x44\xdc\x10\xea\x31\x9a\x5d\x29\x09\xb4\x45\x2b\x5f\x54\x27\x67\xed\x75\x1a\xa4\xb1\xdd\x18\x2c\x7a\xb9\xcc\xcf\xbe\x95\x01\x93\x17\x17\x2f\x39\x0d\x52\xc0\xd0\xee\x7a\x71\x3c\x6e\x40\x68\x3f\xf9\x52\xa2\x28\x66\x40\x7e\x96\xff\x16\x6f\x83\x4d\x39\x25\x5a\x60\x10\x2a\x4f\xe7\x3f\x06\x6e\xf5\x85\x22\xc1\xac\xe9\x48\xa3\xd0\x52\x5a\x1e\x44\xf5\xe6\x98\x81\xc2\x80\xa4\xfe\xe2\x71\x9c\xa0\x93\x56\x77\x45\xc0\x94\x85\x76\xaf\xb3\xcc\xaf\xc7\xac\x98\x3c\x01\x0b\x05\xa2\x56\xef\xcb\xf7\xcc\xe2\xb5\xbf\x81\xe1\xf9\x73\x9c\x02\x69\x56\x77\xc8\x46\xd0\x8b\x42\xf7\xa5\xef\xd1\xf4\x4f\x79\x22\x00\x31\x2e\x0f\x8b\xf5\xdd\xfd\x62\xbb\x5b\x6d\xf6\xeb\x87\xe5\x66\xb5\xd8\x7a\x24\x68\xca\x99\x44\x24\xe8\x1d\x14\xba\x2a\x33\xed\xf0\x13\xc3\x79\x95\xa6\x31\x8d\xed\xef\xde\x9f\xd7\x85\xa9\x26\xa8\x93\x34\xa5\x42\x5b\xde\x74\x61\xc0\xa5\xe0\xad\xc0\xe3\xa2\x59\xab\xf2\xab\x6d\xc1\x9f\xad\xc1\x0a\x81\x15\x25\x6a\x33\x74\x72\x6b\xf3\x9e\x41\x2a\x22\xdb\x11\xdd\x80\x38\x2c\xf2\xbc\x14\xaa\x67\xbd\xc1\xa3\x48\x9a\x96\xb5\x56\xcc\x64\xd5\xa1\x0b\xa3\x53\x11\x13\x14\x0d\xdf\x62\x8f\xa4\x53\xa1\xbd\xc4\xf6\xa5\x42\x45\x18\x54\x3b\x0f\x15\x5f\xc5\x4d\x59\xb9\x0e\x88\x9b\x53\xb7\x0c\x53\x19\x32\x64\x43\xf3\x2c\xaf\x9d\xc7\x13\x5f\x04\xa6\x7f\x91\x9e\xbe\x6b\xa0\x56\xda\xff\xaa\x62\x06\x37\xd5\xde\xee\xaf\xad\xba\xcf\xea\x3f\xd8\x6a\xe9\x7f\x53\x09\x8a\x05\xb2\x7d\x0d\xcd\xf6\x24\x8b\x52\xbb\xa6\xab\x49\xa5\xcd\x0d\xd7\x42\xa3\x77\x7b\x8b\x59\x80\x87\xd3\x61\xe2\xa1\xa4\x1a\x24\x32\xc6\x5b\x01\x03\xe4\x3f\xbb\x86\xae\x50\x9c\x82\x4a\x13\x4b\xf3\x08\x56\xc9\xad\xfe\x51\x7e\xdc\x9f\xd4\xeb\x4d\x87\xe9\x48\x4d\x48\xf1\xfb\x23\xb7\x4f\xf7\xc7\x98\x21\x90\xb3\x8d\x4d\x56\xbb\x1f\xbf\x8d\x9e\x9d\xfb\x41\x2c\x26\x43\x28\x73\xbb\x62\x57\x9f\x13\xbb\x9b\x1a\x2d\x11\x2c\x7f\xb4\x3a\xe0\xa3\x14\xb6\x08\xa8\x5d\x68\x8b\xcf\xa6\x3a\xa1\x3a\xf7\xf8\x6c\x11\xe8\x04\x5d\xf4\xba\x63\x17\x74\x07\x48\x40\x10\xb0\xd2\x64\x9f\x4e\x61\xbc\x3b\x02\x01\xc6\x55\xe2\xa4\xb3\xe6\x61\xf7\xfb\xf3\x0e\x3e\x47\x02\x89\xa3\x0c\xa4\x20\xa0\x99\x95\x60\xed\xb2\xd8\x22\xa4\x01\x16\x7e\x70\xf6\x5c\x03\xea\x9f\x4d\x36\x1f\x11\xb2\x30\x80\x7e\xdb\xf5\xf2\xca\xb3\xd3\x5e\x44\xdc\x20\x31\xf3\x6b\x56\x23\xcd\xc3\xe4\x68\xaa\x85\x07\xee\x54\x99\x7a\x43\xfe\xe2\xab\x53\x96\x4f\xd9\xec\x98\x88\xa4\x48\x5c\x53\x63\x51\x97\xd5\xfd\xa9\xce\xd4\xb7\xad\xc8\x4c\xc4\x31\x78\xfa\x43\x54\x56\x7e\x2e\xb2\xb2\x58\xeb\x49\x8f\x89\x48\xc0\x72\x47\xdb\x54\xc9\xf2\x54\x37\xe5\xe1\xe2\xe7\x69\x10\x63\x3e\xa5\x0d\x79\x9e\x8f\x4d\xd9\x67\xac\x04\x0d\x12\x6b\x13\xa1\x81\x72\x94\x5a\x12\x34\x14\x76\x59\x17\x97\x1c\x5f\xf3\x58\x52\x77\x22\x93\x80\xae\x4d\x01\x1f\x3f\xdb\x68\xbd\x97\xcb\x60\x82\x0b\xad\x5d\x02\xa0\xf5\x10\x30\xf1\x71\xb1\x21\xfc\x02\xb0\xf8\xab\x7f\xc7\x0f\x9f\x26\xcc\x78\x34\xbc\xc8\xe1\x5a\x9c\x1f\xca\x0f\x7f\x3b\x42\x45\xc8\xf8\xe1\x17\xc3\x42\xbf\x67\x75\x59\x8d\xdc\x48\x21\x74\x84\x05\xd9\xf7\x36\x74\x77\xda\x96\xdf\xee\x5d\x42\x52\xab\x76\xf7\xd1\xb5\x65\x5d\x0f\x72\x4d\x42\x4a\x8e\xed\xc3\x57\xf7\x7b\x5b\x47\x5c\xe6\xa2\xae\xf7\x9d\xac\x8e\x1f\xa6\x2c\x19\x12\x72\x30\xfa\xea\xe1\xc0\xb1\x17\x0a\x92\x44\x7b\x5c\x55\xbb\x03\x5c\x67\x78\xfb\xfe\x02\x90\x32\xa4\x42\xc7\xa0\xe1\x01\x3e\x5c\x9e\x17\x3d\x84\xf7\xcb\x52\xad\x3b\xcb\x04\xb6\x97\xfe\x01\x2a\x0d\xa2\xca\xbd\x4b\x25\x03\x96\x46\x2e\xc8\x76\xef\xa9\x5d\x3e\xe3\xdc\xcd\xfc\x86\x23\x03\x26\x6c\xc3\x74\x1b\x6b\x6c\x5b\x4f\xfd\x57\x61\xb5\x3b\x31\x0c\x62\x84\x4e\x1e\x5b\x9f\xea\x09\x71\xa0\xed\x57\x8c\xf6\x3d\xff\x2e\x93\xa1\x34\xc8\xbf\x7b\x38\xe5\xcd\xf9\xeb\x0c\xa8\x0f\x8a\x65\xa8\x23\x6c\x1c\xba\x2b\x5f\x16\x45\xfd\xd1\x7e\xd4\xf7\xd6\xfe\xce\xb6\xb6\xfd\xa2\x9d\xb2\xbd\x5a\xac\x64\x57\x74\x98\xad\xd4\xcb\xd0\xa8\xa0\xe7\xc1\xc2\xe9\xf5\x20\x0e\x60\x05\xad\xc6\xcc\x91\x73\x04\xf8\x4c\x46\x24\x46\x08\x5d\xdd\xc0\x71\x28\x58\xc4\x64\x24\x28\x7a\x28\xf7\x59\x31\xdf\x26\x1d\x07\x6e\x64\x2c\x29\xa6\x2f\xa1\x52\x61\x18\xdd\x88\x3c\xc7\xb6\xb4\x59\x68\xb2\x3b\x85\xa6\x56\x3e\xfb\xa9\xac\x1b\xcf\x6a\xec\x0e\x31\x62\x29\xad\x2c\xcb\xe0\x20\xd9\x43\x7e\x19\x37\xfb\x2b\x80\xcd\xc4\xfc\xfd\x54\x37\x07\xf1\x36\x4a\x07\x48\x66\x88\x17\x63\xb7\x2c\x28\xcf\x45\xd6\xd8\x98\xb7\xd7\x0a\x66\x92\x47\x96\x57\x78\xf1\x52\x59\x26\xcc\x6d\xbf\x91\x4a\x4e\x39\x2e\xa0\xd6\xcd\x3f\x1d\xe7\x8d\xbc\xe4\x3c\xc1\x76\x2c\x25\x8a\xd6\xad\x9d\x87\x24\x49\xae\x38\xed\x38\x30\xba\x4a\xe7\x20\x31\x28\x53\xc2\xb8\xa3\x60\x77\x79\xe1\x7e\x77\x93\x69\x6c\x35\xe4\x0a\xf8\xb8\x9a\x02\x98\xa5\x08\x14\xc2\x90\x3a\x56\xb3\x66\x53\x96\x87\xb1\xa1\x97\x22\xb6\x9d\x5c\x59\xed\x41\x85\xd5\x56\x14\xdd\x0f\x88\xd4\x20\xa9\x0b\x1c\xeb\x2c\x2f\xbb\xb7\x28\x89\x32\xde\x73\xd9\x88\xca\x56\xb9\x4e\x35\x7e\xad\x5e\xf3\xc8\x0f\x4e\x38\x76\x66\x63\x24\xdd\xd1\xf6\xfd\x36\x9c\x0f\x32\x4d\x10\x11\xbd\x38\xf6\x5f\x4a\x85\xe0\xf0\x8e\x76\xe1\x21\x51\x19\xda\x18\x6c\x96\x98\x07\x25\x48\x15\x29\xac\x87\x6d\x85\xf1\xd8\xa7\xf1\xdd\x28\xae\x30\x7a\x78\x2d\x3f\xee\x45\x71\xc6\xbc\xe9\x64\xf7\x93\x3a\x66\x29\xc2\xcd\xc4\x1b\xac\x9b\x9f\xd0\x7e\x7e\xe5\xef\x4b\x0b\x06\x83\x1e\xde\x76\xbd\xb5\x46\xa3\x8d\xd5\x57\xbb\xd1\x53\x69\x43\x28\xf4\x50\xd0\xab\x93\x43\x82\x93\x8e\xec\x0a\xff\xcb\x8d\x86\x90\x22\xa2\xe0\x54\xec\x2a\xa1\xde\x2e\xc5\x97\x7d\xd2\x46\x02\x4f\xb0\x75\x64\xf1\xbc\xfb\xf1\xe8\x31\x70\xd2\x10\x89\x35\xef\xa3\xaf\x24\xff\x22\xeb\xd4\x9d\xa6\xa4\x85\xb5\x18\x84\xb5\x78\x3b\x57\x6f\xb3\x62\x2c\xca\xc7\xa4\xe1\x29\x62\x3f\xed\xc8\x6e\x7f\xed\x90\xdc\xfc\xaf\x7f\xf9\xf9\x3d\xfc\x2f\x7b\xb6\x22\x29\x8f\x89\xf5\xfd\xda\x39\xbc\x2e\x3a\x63\xa3\x88\xb0\x9c\x27\x77\xe5\x4b\x1b\x1e\xcf\x06\xf8\xed\xa0\x44\xda\xce\x90\x45\xeb\xcd\x5d\x3b\xae\xcc\xfe\x22\x12\x33\x5d\x1a\x54\xa9\xc1\x89\xc8\x8f\x1e\x40\x11\xa0\x61\xda\xf5\xe4\xcd\x27\x51\x55\x98\xa8\xc4\x33\x84\x65\x39\x88\x17\x5b\xfb\x99\x41\xca\xa9\x88\x72\x6c\x3c\x3a\x9e\xea\xd7\xab\xd3\xb9\x8d\xa9\x27\x72\x98\x4c\x45\x0a\x10\x3a\x38\x94\x80\xb5\x11\xf1\x20\x18\xbe\x68\xe0\x18\x14\xa3\x54\xa4\x19\xf6\xc1\x65\xaa\x9c\x28\x19\x30\x15\x13\x40\x36\x80\xff\x42\x51\x64\xa3\x58\x4f\xc5\x42\xa2\x7f\xd1\xe5\x10\xac\x14\xe7\x61\x4e\x6b\x73\x6c\xbc\x54\x12\x58\xac\xbd\x6c\xdd\xce\xeb\xad\x2b\x6b\x8d\x92\x43\x2a\x49\x89\xe7\xd7\xbd\x82\x71\x0b\xa0\x4a\x54\x88\xd8\xd7\xab\xac\x6a\x5e\x6f\xa0\xbb\x5b\xaa\x78\xd4\x91\x6f\xd7\x4d\xd5\xfd\xdd\xc4\x3c\x1a\xa8\xa4\x62\x19\xfc\xd4\x95\x55\x15\x8b\xad\xcc\x6e\x1f\xec\xad\x44\x55\x80\x1e\x73\x1d\x8e\x9f\x81\xe9\x10\x2b\x74\xc2\x92\x5b\xda\x9d\xc4\x1f\x03\x77\xac\xae\xb3\x97\xe2\x9b\xe4\x94\x62\x46\xa3\xc6\xee\x58\x3a\x7c\x57\x0e\x18\xb3\x98\xe2\x51\x82\xb8\x85\xac\x30\x16\xa3\xb1\x1c\xb6\x3a\x2a\x0e\xd4\x11\xd3\x8a\xfc\x5e\x14\x27\x91\xdf\xa3\x0a\x0c\x36\xf8\x74\x6e\x97\x4a\xa9\x45\x9f\x23\x16\xb5\xdd\x06\xf6\xbd\x43\xad\x52\x6e\xb5\x3c\xdb\x2d\x2b\xda\xdb\x76\xad\x87\x36\x94\xf1\xc7\x53\x13\xf6\x52\x0e\xcb\xf2\x70\x84\x26\xfb\x8a\x63\x8b\xa9\x54\x5b\x46\xf3\x1f\xe2\x70\xb8\x2a\x8b\x2e\x26\x55\x22\x0a\x88\xdb\x6e\x3c\x70\x6c\x80\x72\xb3\x85\xf5\x89\xbf\xa8\x84\xe2\x68\x52\x3f\x20\x7b\x79\x9d\x76\x11\x29\xa1\x15\x16\x1a\xaf\xc5\x0b\xe4\xa2\x9b\x9d\x92\x02\x46\x9a\x5e\x0c\xac\xa9\xb2\x31\x60\x7f\xf0\x03\x12\x02\x6a\x2c\x33\xeb\xcd\x77\xdc\x6f\x6e\xb8\x8a\x63\x4f\xda\xbb\xcc\x9a\xb3\x17\xce\xda\x64\xea\xb5\x18\xc0\xd9\xfc\xe8\x34\x80\x91\x6c\x0d\x3e\xe4\x00\x69\xf1\x7d\x2e\x5a\xe9\xd0\xe6\x1d\xfd\x0c\x79\xaa\xb2\xf7\x2c\x87\xce\xf4\x4c\x26\x94\xa6\x0c\xcb\x05\x5d\x7d\x65\x0f\xc3\x1e\x15\xa5\x55\x28\x1c\x48\xd9\x7d\x3a\xc4\xad\x4c\x5e\x2a\x48\x8d\x48\x0b\xbb\xb7\x2f\x5a\x4f\xde\x97\xb2\xc9\x28\x1b\xe8\x89\x4e\x68\x3c\xaa\x1c\x2a\x70\x19\xf0\x76\xdb\xda\x36\x65\xd5\x37\x12\x28\xc3\x00\xfb\xe0\x0e\xd9\xe1\x94\xff\x36\x77\xb2\x81\x08\x53\x73\x42\xeb\x21\xd3\x45\x1c\x8c\x5f\x8d\x0e\x24\x55\xd0\xe9\xbf\xd8\xc4\xcb\x94\x67\x94\xe9\x40\xc5\x88\x64\x7e\x83\xb3\x3c\x9d\xa7\x07\x8d\x2d\x50\x28\x91\xe7\xdb\xa6\x6c\xe7\xe4\x55\x73\x09\x25\xfb\xc2\x95\xfe\xaa\xa2\x32\x67\x66\x75\x28\x19\x22\x27\xb7\xaf\xa2\x7a\x1b\x36\x46\xeb\x50\x87\xa8\x28\x86\xb4\xe7\x83\x54\xa4\x8e\x82\x18\xfd\xef\x0f\xec\xf8\x22\x56\xf6\x71\xd8\x6a\xea\xc6\xc5\x49\x8c\x99\xe1\xa6\x33\x94\x17\x77\x32\x6b\x7e\x74\x2c\x25\xea\x56\x1c\x4a\x0d\x9f\x17\x48\xca\xc9\xeb\x8e\xc1\x12\xe7\x1d\xbc\x75\x79\x3c\xc2\x80\xf1\x8a\xe9\x84\x84\xda\x81\x94\x5c\x5d\x46\x09\xcb\xe7\x7f\x75\x7e\x28\xe7\x1a\xf0\x74\x92\x48\xcc\xbb\x37\xd5\xf9\x3a\xab\x5b\xe3\x8b\x4e\xe4\xf8\x87\x13\x1d\x63\x72\xdb\xd5\x57\x17\x5a\x0f\x37\x22\x4d\x39\xc7\x52\x80\x4b\x26\x88\x49\x3f\x9c\x66\x2c\x0a\x92\x4e\xae\xf7\xbe\x2c\x9a\xd7\xfc\x8c\xaf\x6f\x36\x11\xa6\x79\xc8\x91\x3e\xf5\xfe\x7c\x33\x76\x44\xa6\xc3\x64\x10\xf4\x0a\xc7\xed\x13\xff\x0e\x55\x66\x32\x18\x29\x2d\x32\xcd\x53\x42\x5d\x0f\x9f\x75\x19\xdd\x1e\x39\xff\x49\x04\x25\x16\xac\xde\xed\x45\xfb\x43\x17\x33\x6a\xc1\x62\xe3\x70\xa1\xff\x3c\x5d\xd6\xe4\xb5\x30\x14\x17\x17\xe4\xd9\x4b\x26\x73\xb8\x29\x2b\x47\x42\xa8\x26\x39\x5f\x2d\x65\x1c\x0c\x25\x51\x47\xd1\xdc\x64\xa8\x51\xc2\x93\x2b\x94\x75\xf3\x68\x46\xfc\x96\x6e\x90\x0a\x6c\xe2\xe5\xa2\x1c\x65\x85\xaf\xfc\x13\x68\x26\x12\xcb\x3b\xac\xda\xc0\x07\xb4\xd7\xe3\x71\x4c\x1d\xf7\x59\xd1\xcf\x28\xcd\x6c\xd1\x1c\x9d\x9b\x53\x87\xab\xd2\xc0\x23\x2b\x4c\xed\x1a\x40\xbe\x78\x97\x90\x2a\xc4\x62\xfc\xe7\x24\x8a\x26\x6b\xce\x37\x28\x5c\xd2\x5d\x44\x30\x88\xbd\xb7\xf0\x24\xea\xe6\xae\xc4\xb6\xf8\xc9\x35\x80\x22\x49\xc6\xfe\x01\x3e\xee\x2c\xc2\x6f\x50\xbc\x18\x7b\xf6\xda\xa8\x18\xb3\xff\x5e\xfe\x64\xe1\xfa\x69\xec\xa6\x7e\x75\x9a\xb4\xc3\x68\xa3\x38\xa2\xeb\x4f\x85\xa7\xba\xf8\x6d\x04\x71\x9c\x8b\x6e\x21\x88\xac\x90\xec\xa1\xf5\x1a\xa1\x1a\x68\xd9\x31\x20\x82\x83\xc3\x32\x2c\x1a\xe7\x0f\x76\x38\xbb\x69\x47\x01\x10\x69\x99\x59\x4e\x85\x14\xc5\xfe\x74\xd1\x17\x04\x44\xd9\xf8\xfd\xcf\x53\x21\x21\xfb\x15\x9f\x3d\x83\x90\x00\x46\x93\xaf\x53\x69\x7c\x06\x61\x42\xad\x90\x2e\xd4\xcd\xf6\xb5\xac\x1a\x2b\x0a\xea\x6f\x3c\x54\x16\xd5\x61\xa1\x7f\xb6\xd5\xb4\xdf\xa2\x21\x0a\xb9\x76\xde\xe0\xb6\x3c\x00\x7a\x5b\xde\xa9\x80\x28\x12\x81\x72\x3d\x63\x6d\x1c\x3a\xe7\x9b\x43\x94\x04\xd8\x4f\x7a\x14\xe7\xc7\x53\x73\x5b\xbe\x43\x55\x74\xfa\x34\x0c\xe2\x84\x62\xfa\x48\x9e\xce\x3f\xb3\x5c\xab\x8e\xc4\xd5\x1f\x67\x29\x7e\x59\xbb\x23\xae\x1b\xe8\xd3\xe3\x7d\x87\x8a\x8f\x45\x20\xe6\x11\x2a\x0f\xdc\x67\x6f\x42\x97\xa3\x0b\x25\x51\xca\x9d\x44\xcd\x52\x1c\xd7\xc5\xcf\x8e\x93\x00\x12\x11\xa1\x50\xc4\x8f\xf5\xf5\x6a\xb3\x98\x7f\xd1\x63\x9b\x0c\x89\x92\x9e\x66\xf1\xe7\x6b\x79\x05\xbf\x28\x4f\x41\x62\x08\xb2\x2d\xdc\x95\x2f\x0f\x7b\x53\xa8\xaf\x58\x55\xfc\xaf\x8d\xea\x0f\x4e\x24\xe9\xcb\x4b\x47\x08\xb8\xcf\xb3\x37\xb0\x73\x72\x7c\x9c\xc5\x11\xf2\x21\xee\x8f\x95\xb5\x0c\x93\x5e\xf4\x59\x37\x1b\x58\x2c\xa4\x63\xe8\xb9\xff\x9c\x37\xd8\xc0\x74\x88\xe9\x82\xab\xab\x3f\x06\xbb\x27\x70\x62\x19\x52\x06\x42\x59\xc9\x0f\x51\xbf\xee\xdd\x2f\x74\xe3\xa8\xcd\x88\x5b\xea\x2e\xb8\xca\xf4\x4d\x79\x81\xab\xfe\xe2\xa1\xd3\x08\x1c\xad\xdb\x0c\xf3\xad\xbd\xdd\x30\xf0\x63\x63\x87\x80\xb7\xdb\xd8\x2c\x65\x0b\x88\x98\x2b\xe3\x60\x42\x57\xd5\x78\xea\x08\x9d\xa0\x5f\x74\x93\x79\x40\x04\xc8\x88\x5b\xbf\xdd\x79\x87\x36\xcf\xdb\xba\x31\xad\x47\x04\x5f\x74\x91\x82\xa4\x3c\xf1\x26\xe4\x06\x60\x86\xde\x97\x81\xe4\x96\x57\x36\xab\x97\x79\x06\x45\xf3\x24\x32\xfd\x3c\xc1\x16\x82\x54\x96\x11\xfb\xe8\xbd\x52\xed\xe4\xc9\xc7\x1c\x54\x6e\xb4\xa2\x24\x35\x23\xd2\x0d\xab\x2c\xeb\xca\xc6\xfe\xa1\x94\x82\xc4\x74\xa9\xc9\x7f\x9e\xb2\xc6\x5d\x74\x7a\x39\x1d\x78\x5f\x76\x7b\x04\x95\x89\x7c\xca\x6d\x02\x10\x85\xb8\x3e\x7e\x7f\xbe\x5b\x2e\x1e\xf6\x4f\x9b\xc7\xfb\xd5\xee\xc7\xea\x79\xbb\xbf\xd9\xdd\xed\xb7\x4f\xab\x8e\xea\x04\x40\x30\xbb\x9f\x8b\xdc\x29\xae\x75\x39\x6d\x00\x10\xb8\x0f\x3d\xc0\xc7\x00\x3f\x31\x79\x61\x26\x8e\x42\xd7\x65\xfa\x03\xf2\xbc\xfc\x59\x56\x1d\x0a\xde\x04\x2c\x20\x9d\xf6\xd1\xca\x91\xc4\x75\x07\x65\xa4\x7d\x3f\x63\xdd\xc1\x0e\x0d\x61\x12\x23\xb6\xab\x52\xab\x7e\x5e\x1b\xc2\xa5\x4f\x20\xf4\x04\xdd\x24\x1e\x99\x3b\x43\xa4\x6d\xe6\xb1\x0d\x24\x96\xbc\xde\xf1\x88\xce\x4e\x09\x13\x2a\x95\x38\x1a\x3a\xdf\xf2\xd0\x3d\xbf\x09\x4d\x0c\xa1\xd7\x4e\x40\x56\x8b\xd7\xec\x38\xf7\x89\x4d\x44\x20\x10\xde\x07\xcc\xf5\xa4\x00\x6c\xa2\xd0\x3a\xff\x8f\xc6\xe4\x59\x01\x4b\x51\x37\x39\x0c\x19\x94\xe7\x33\xf1\x26\xa2\x89\x67\xc7\x68\x7d\xa8\xf2\xd4\xcc\x90\x86\xb6\xc3\x94\x67\x16\xf5\xec\x13\x6d\xbc\xd4\x97\x14\xbb\x1d\xc5\x44\xa9\xe6\x9d\xfc\xc0\x56\xe4\xf0\x13\xb2\xdb\xb2\xcb\xc2\x9a\x08\x58\x60\xfa\x92\x0f\x92\x2d\xcc\x97\x1e\x4c\x6b\xd8\xd2\x3e\x95\xde\xfd\x55\x28\xaf\x27\x5e\xbd\xc3\xa4\x23\xdf\xc4\x29\x60\xd3\xc4\x41\x7c\x66\x87\xd3\xe1\xea\x74\xbe\x12\xea\xcd\x3a\x0c\xeb\x62\xd9\x6b\x3f\x30\x93\x70\xe5\xe4\x25\x50\xf9\xd3\xb5\x7f\xf4\x09\x23\xee\xc7\x81\x52\x16\x77\x07\xef\x59\x79\xaa\x2d\x98\x63\x98\x99\x30\x2c\x26\x4c\x77\x20\xd1\xd6\xbf\xf5\x5a\xf5\xaa\x27\xdf\x33\x9c\x70\xf4\x9b\x9a\xd7\xac\x6a\xce\xfb\x8f\x01\xf3\x2d\x33\x9c\x5a\xa7\x6a\x6f\x1f\xb7\xf5\xd7\x1f\xda\xc0\xfc\x8b\x79\xc5\x59\x6a\xe3\x57\xc8\x61\x8a\x17\x30\x5c\x24\xd8\x5c\x8c\x62\xf8\x5b\x07\x4e\x2a\xf3\xbc\x83\x0c\x4d\x66\x17\x37\xd2\x32\x8d\x61\x82\x6d\xaf\x26\xef\x34\x4d\x44\x1a\x62\xda\xa1\xd2\xaa\xd4\xa0\x2f\x98\x58\xfd\x40\x1e\x60\xca\x6b\x27\xde\xc0\xb6\x99\x77\x97\xd0\x06\xf7\x60\xeb\xc1\x61\x3c\x68\xd9\x13\xbf\x78\xbc\xd4\x58\x89\x50\x0b\x98\xb2\x2c\x3c\xdd\xc5\x84\xe4\x16\xd4\x7b\x38\xe6\x7b\xcb\xa4\xfe\xc5\x65\x64\x6a\xf9\x57\x5d\xa3\x37\x88\xc3\x97\x34\x5b\x46\x02\x43\xb3\x57\x0b\x03\x77\xa2\x1e\x22\xcf\x8c\x04\x9d\xc2\xc8\xc2\x3e\xbd\x8a\x1a\xd6\x85\x86\x4f\x3f\x46\x31\x8b\x1b\x13\x5a\xf7\xef\x7b\xf2\x82\x94\x48\x13\x2f\x41\x59\xa9\x7f\x36\x5f\x77\xbb\x8f\x9f\x43\x4b\xdb\xa0\x60\x9c\x0f\x37\xa8\x26\x18\x13\x08\x87\x64\x1c\xe6\xba\xba\xa3\xa1\x65\x50\x3c\x58\x1a\xd4\x42\xcf\xb1\xba\x5e\x56\xc5\x8c\x61\x02\x3b\x9d\xee\x17\x0f\x8b\x69\x2f\x97\x31\x32\xd4\x8e\xc1\xf7\xde\xae\xb3\x4d\x79\x2a\xa6\x56\xc3\x40\x42\x03\x4f\x76\xb9\x3d\x8a\x8f\x02\x0b\x7e\xd3\x4f\xf5\x25\xdb\x16\x0f\x02\xaa\x0d\x38\x17\x62\x2f\xf4\xc1\x1b\x6b\x1e\x10\x10\x58\xe9\xc9\x45\x1b\xf0\xdc\x95\x4d\x53\x76\x87\x8c\xf6\x04\x26\x0f\xf0\x31\x58\xa6\x3c\x08\xc3\x84\x39\x8e\xfa\x6a\xbf\x15\x5a\xe7\xe0\x33\xa3\x3c\x08\x69\xea\xfb\x39\xb7\x98\x79\x1a\x7d\x3b\x1e\x84\xc2\x0a\x05\x1f\xb2\xe2\xd1\x2c\xaa\xaa\xe7\x07\x70\x2f\x8d\x07\x51\x68\xb7\xed\xa6\xbc\xf2\xc4\xdc\xee\x48\x9c\x5a\xae\x78\xd4\x61\x5d\x6d\xc2\xdf\xba\xbf\x73\xcc\x7e\x2f\xf4\x7b\xbb\xf6\x3a\x52\xea\x39\x6e\x2e\x1e\xc4\x4a\xe1\xfd\xd7\x96\xda\xfe\x62\xf2\x8c\x5d\xda\x2e\xe1\xd7\xdb\x67\x1e\xc4\x5a\xa0\xb8\xaf\xca\x33\x63\x1c\xc0\xa6\x6f\x3e\xea\x6e\xcb\x28\x04\x7c\x2c\x1f\xef\xef\x9f\x1f\xd6\xbb\x3f\xc7\x3d\x21\x3c\x48\xa4\x01\xe3\x19\x7e\x2e\xd8\x4b\x67\x3f\xed\xd8\x99\xe7\x01\x8b\x25\x32\x66\xca\x53\xa1\x51\x5a\x1f\x8a\xcc\x6f\x8d\x3c\x60\x49\xca\x2d\xde\x40\xe5\xa7\xac\x7a\xae\x4f\xa2\xca\xca\xc9\x27\x61\x2c\xc5\xc6\x78\x9b\xa2\x68\x17\xed\xd5\xe9\xfc\x0f\x38\xd7\x4f\xeb\xeb\xf9\x5d\x85\x07\x0c\x04\x6e\x40\x05\x7c\xdc\x97\xc8\xbd\x9a\x35\x76\x1b\xda\xfb\xdf\xe6\x91\x64\xb1\x8f\xcb\x7b\x24\xa6\x47\xab\x7e\x9b\xcf\xe1\x01\x8f\x53\x34\x75\x9e\x48\xef\x38\x30\xcd\x3c\x48\x93\x44\x92\x51\xcf\x83\x55\xa6\xec\xc5\x4c\x7e\x1b\x5f\x4e\xd0\x00\xeb\xa2\xed\xfa\x43\xec\x87\x83\xca\xac\x0a\x3d\x08\x51\x79\x20\x52\x88\x5d\xde\x04\x13\x8b\xdf\x53\xeb\xf3\x40\x28\x83\x24\x67\x4e\x1a\x64\x0b\x79\xde\xa5\x13\x78\x20\x00\x12\x4b\xa3\x64\x2f\xd6\x91\xc5\xba\xe3\xd2\xd8\x4c\x41\xe3\x78\x6d\x3a\x11\xad\xf6\x90\x91\xdd\xa1\xfa\xd1\x60\x8b\x82\x3b\xa6\x68\x90\x82\x3f\xb6\x3e\x38\x1e\xe1\x2f\x5b\xc8\x78\xa0\x78\x8a\x09\xcf\x4d\x69\xeb\xd3\x8e\xc4\x75\x28\xd7\x36\x97\xa3\xe0\x81\x0e\x8d\xe7\xf7\x7c\x02\xa8\x5c\xec\xba\xfc\x32\x43\xc4\x03\x1d\x5b\x7e\x27\x44\x59\x4d\xa8\x80\xfd\x10\x11\xe0\x6a\xdd\x1e\x4f\x55\xfd\x5e\xff\x14\x55\x95\x95\x55\x1d\x7b\x20\x22\x0f\xb4\x4c\xf1\x6b\x15\xf0\xd9\x6c\x1b\x10\x79\xcf\x26\xe5\x47\x28\x91\x38\xc6\x6a\x4c\x9c\x0d\xfd\x4b\x1e\x68\x48\x70\x5b\xcf\xcb\xa6\x01\x07\x32\xe2\xee\x18\x44\xd4\x4a\x2b\x40\xdd\x5c\x67\x75\xeb\xb3\xe8\x0d\x08\x8d\x51\x9f\xbf\x3c\x50\x15\x38\xa4\x31\xe2\x48\x5c\x6f\xdd\x2f\xe6\xac\x49\x62\x25\x46\xf5\x92\x8e\xf8\x71\xfe\xbb\x98\x14\x10\x2a\xb3\x11\xc5\x5b\x56\xbc\x5c\x89\x3c\xc7\x6c\x1d\x42\x8e\x2e\x79\xb9\x78\x60\xc0\x86\xa9\xb7\xa5\x78\x05\xe1\x6f\x97\x04\x91\x65\x0a\xd3\x5e\x01\xea\x49\x9c\x61\x70\x94\x7b\xfa\xe3\xab\x5c\x8c\xde\x14\x09\x22\x85\x39\x91\xed\xf6\xc7\xff\x26\x0b\xc3\x49\xc0\x18\xa2\xca\x4e\x35\x54\x75\xcf\xd5\xdd\xfd\x9a\xb0\xc4\x69\x9d\x0c\x6b\x6f\x36\x49\x20\x15\x82\x44\x56\xbb\xe5\xab\xa8\xdc\x12\xdc\xbf\x87\xe3\xa7\x24\x51\x68\x41\xae\xaf\x56\x53\x6b\x3d\x6c\x16\xe4\x24\x0e\x54\xda\x5a\xbc\x47\x05\xa2\xd8\x2a\x71\x04\x8c\xab\xbf\xce\xfc\x70\x92\x04\xd6\x0f\xb2\x4e\x21\xb6\xd1\x3d\x9a\x31\x21\xf8\xf8\xcb\x90\x24\x06\xc2\x1c\x3a\xf3\xd9\x55\x87\x7b\x57\x86\x93\x44\xf0\xc4\x45\x77\x96\x61\xf5\xd4\xb9\xc4\x9c\x24\xc6\x10\xd7\xe6\x39\x97\xb2\xe4\x84\xc6\x02\xbb\x42\x76\xaf\x9f\xf7\xf5\xcb\x04\xa3\xe5\xc7\xf0\x14\x17\x79\xa6\xca\x4e\x1b\x7e\x7c\x15\x46\x2c\x79\xc7\x95\x93\xe5\xfd\x52\x50\x9f\x13\xa6\x14\xa6\xca\x30\xf3\x39\x94\x71\xe4\x84\x69\x2b\xf1\xef\x4a\xfa\x61\x30\xca\x1a\x72\xc2\x8c\x65\xf1\x37\x59\xa1\x1d\xe7\xe3\xf8\xda\x9c\x70\xdc\x3e\xb4\x38\x2e\x45\x35\xfa\x54\x3c\x54\x3a\x72\xda\xc1\x50\x59\x25\x08\x6b\x09\x6f\x87\xa4\xb9\xe3\x57\xcf\x45\x88\x99\x11\x6b\xd0\xb5\xbe\x14\xfc\x9d\x9c\x90\x26\x96\xe7\xd8\xee\x5f\x4f\xa2\x75\x2c\xb1\xd3\x6e\xf7\x0a\x65\x05\x0d\x92\xfd\x0f\xba\x66\x39\x49\x39\x41\xd1\xe4\xfa\x03\xe0\x88\xd4\xc9\x7d\x71\xf5\xb7\xc9\xc5\x55\x84\xc8\x82\x65\x2e\x46\x5b\x10\x11\x11\x60\x15\xea\x55\x20\x87\xdf\xe2\x78\xcc\x33\x25\x2e\x7a\x0d\x38\x11\xc6\x9a\xaa\x1a\xf2\xdc\x65\x02\xbe\xa1\x16\xe0\x44\x45\x52\x1b\xcb\x19\xd2\x3a\xff\xde\x97\xf1\x47\xb9\xed\x72\x15\x5a\xef\xca\x2e\xd7\x7b\x75\xca\xdf\x26\x7d\x4a\x9c\x68\xc2\x35\x1b\x88\xc0\xde\x43\x4f\xb4\x37\xef\x5d\xf8\x13\xa3\x38\x74\x56\xdf\x6a\x7a\xcd\x98\x22\xa2\x85\xc1\x84\xc2\x6a\xf7\x03\xaa\x22\x6b\xce\x07\x24\x26\x9e\x8e\x32\x1a\xc5\x0a\x97\x57\xde\xe9\x09\x03\xc2\x3d\xe5\x4f\x1b\x05\xb8\x3d\x02\x03\x46\xf7\xdf\xeb\x31\x1b\x31\x0f\x03\x19\xe3\xbb\xce\x10\x4a\x0f\x03\xc5\x79\x1e\x06\xda\xca\x19\xdd\x23\xa6\x1d\x3d\xa0\x77\xc8\xcb\x23\xa2\xb7\x07\x2a\xc6\x3c\x0c\x43\xa1\x8d\xfb\x10\x50\x3d\x9c\x0e\xed\x77\xbb\x06\x91\xfb\xb5\x10\x46\x2c\xc1\x8e\xe8\x5d\x79\x5b\x2e\xcb\x42\x41\xf5\x1d\xa5\x2e\x0f\xa3\x54\x07\xd2\x53\x77\x65\x6a\xb6\xea\xc9\xc3\x38\x32\xc6\x3d\xb0\x50\x4d\xde\x4d\xa1\x30\x96\x1a\xf7\x4a\x71\x6a\x4a\xdc\xdf\x67\x27\x44\x18\x03\xb5\x7c\xe3\x18\xe9\x0e\x5b\x63\x67\xe1\x99\x3c\x4c\x42\x8b\x4d\x75\x40\xe3\x09\x6e\x82\x87\x94\xc5\x48\xcb\x7e\xa8\x8f\xdd\x9f\x64\x1c\x7a\x02\x0c\x39\x15\x26\x73\x99\xd5\xd1\xff\xf5\xe7\x01\x30\xd7\x0e\x74\xc8\x9a\x71\x89\x73\x3a\xaf\x42\x46\x35\x0a\xa0\x6f\xa1\x51\xa2\x7e\x7d\x3c\xd9\xbb\x1a\x3f\x2d\x03\x83\x39\x9a\xd5\xfb\x5d\xf9\x8e\xb9\x6c\x6b\x03\xbe\xe0\xd5\x9f\xe6\x84\x47\xdf\x87\x87\x09\x32\xa5\xbd\x97\x03\x8a\x94\x2f\x8a\x8e\x17\x65\xd2\x61\x92\xd9\x5f\x8f\x59\x5a\x4c\xa1\xb5\x63\xd9\xbb\xf8\x12\x73\x2d\xc3\xfe\x6c\x00\xcc\x41\x1f\x4f\x15\xdc\x4c\xec\x4c\xc8\x4d\x1c\x93\x4e\xd2\xac\x0d\x2f\x57\xb5\xaa\xca\x8f\xdf\x06\xc5\x67\x1e\xa6\x2c\xd0\xee\x0d\x62\x02\xef\x7a\xc0\x9d\xf9\xab\xfa\xaf\xbf\x84\xb2\x5d\xff\x4e\x81\xc0\xcb\x90\xcf\x10\xae\xfa\x13\x34\xc7\x46\xa8\xdf\x9f\x9f\x6c\x53\xef\x7e\xfb\xfc\xf4\x74\xf7\xe7\x7e\xb7\x5e\x6d\x62\x3f\x81\x84\x08\x59\x8f\xc6\x1c\x6a\x06\x4d\x2e\x27\x23\x1a\x3b\x90\xc5\x75\x25\x3e\x9e\xfc\x05\xa4\x08\x31\x9f\x58\x41\x51\x9e\x0a\x05\xff\x00\x38\x76\xee\x70\xa8\x64\x80\xa8\xb4\xab\xd3\xf9\xba\x3c\xc9\xbc\x3f\xa2\x89\xc6\x34\xc6\xee\x23\x2b\xde\x46\xfd\x8f\x3c\xd4\xb1\xc0\x86\x31\x0c\xbd\xcd\x04\x97\xfe\xff\x13\x32\x7a\xfc\x74\x10\x68\x65\x37\x5a\x58\x9e\x65\xe7\x31\x8f\x9c\xae\x10\x48\xc4\x7a\x4a\x7a\x8b\xc0\x15\x5f\x44\x2e\x21\x44\x04\xe7\xdc\xbf\xb3\xe2\x25\x9f\x24\xea\x78\x68\x54\x1a\xdb\x3c\x78\x7d\x72\x99\x72\xdf\x04\x30\xd9\x0e\xa2\x80\x53\x0f\x5c\x48\x1e\xe0\x63\x57\x89\xac\x99\x02\x64\x67\xff\xe9\x1d\xb8\x88\x10\x21\x5c\xb5\xf8\x49\x54\xbd\x62\x19\x8f\x08\x4b\x88\x4b\x0a\xb4\x47\x2e\x85\x4a\x78\x44\xd2\xd8\x92\x4d\x5b\x45\xa8\x21\x57\xdd\x64\xa0\xb1\xba\xa5\xaa\x3c\x1c\x45\x05\xb6\x44\x3b\x6e\x7d\x1e\xfd\x4b\xdc\x79\x21\x89\xad\x6b\x5f\x1e\x9f\x8f\x8b\x77\x91\xe5\x3d\xb8\x84\x47\x61\x6c\xc9\xa1\x30\x91\xb2\xc1\x60\x1b\x7e\x82\xbc\xcd\x4c\x73\xf1\xae\x42\xcd\xb4\xf1\xbc\xdf\xae\x37\xfc\x0b\x4d\x0f\x1e\x45\x91\x9d\xb9\xf8\xfa\xb3\xdf\x1f\x2f\x34\x24\x86\x1f\x3f\x8a\x22\x4e\xa5\xcd\x6e\x38\xe9\x31\x7f\x40\x31\x04\x5a\x64\x85\x82\xa2\xc9\xde\xb3\x1a\xa7\xc3\x20\xa4\x75\x03\x63\xca\xc4\xd0\xdb\xef\x8b\xf1\xdd\x08\x66\xb0\xfd\xf3\x20\x3e\xbb\xac\x53\x87\xa7\xe2\x51\xac\x62\x24\xa4\x94\xa7\xf3\x42\xa9\x89\xc0\x3e\x8f\x92\xc0\x0a\x0c\x63\xb3\xb5\xcb\x0c\x82\x9e\x8c\x21\x56\x71\x08\xd9\x5a\x27\x99\x2d\x1e\xd1\xd0\x12\xbe\x3a\x63\x30\xe0\x0a\xe0\x11\xa5\x36\xe7\xe1\x4c\xc9\x6e\xf1\x70\xbd\xd8\x5c\xef\xad\xec\x99\x1b\xc3\x82\x38\x0d\xbd\xe0\xc1\xb4\x6d\x8e\x47\x2c\x4c\xb0\x5c\xb1\xdd\xfd\xca\xf3\x8f\x98\x00\xdc\x0a\x91\x79\xd3\xb6\xc2\xb6\x31\xc9\xd0\xb6\x7b\x4f\x37\x62\x2a\xc2\x38\xc9\xe1\x8a\xd0\x77\x40\x43\xfc\xc7\xe3\xe6\xa6\x27\xb2\xfb\x36\x62\x8e\x78\x62\x35\x90\x6a\xf0\xb4\x4b\xdf\x53\x89\xf1\x28\x35\x2a\xa1\x1e\xaa\x21\xf2\x85\x7a\xcd\xe0\x7d\x58\x60\xe6\x91\x24\x10\x5a\x9b\xdd\x3a\xb1\xb3\x37\xaf\x0c\x33\xb6\xdb\xab\xb5\x73\x97\xfa\x36\x3c\x02\xa2\x3d\xba\xed\xb9\x86\x0a\x11\x1a\xeb\x89\x64\x1a\x8f\x4c\x1a\xa3\x5b\x07\x28\x57\x46\x7e\x02\xf8\xdc\x48\x1c\x50\x82\xa4\x7c\x77\xe5\xcb\x3f\xce\xaa\xfd\xa1\xfa\xd2\x37\xf7\x63\x75\x88\x86\xe2\xd6\xb7\x47\xf3\x98\x70\x8d\x31\xf5\xd5\x6a\xf9\xab\x5a\x3d\x8f\x89\x16\xc8\xaf\x95\x97\xea\xcd\x09\x47\xd7\xdd\x85\x0c\x41\x58\xe2\xab\x28\x74\x0e\x63\x50\xdc\xfc\xdd\xb4\x8e\x1d\x74\xaa\x8c\x33\xde\x6c\x1c\x9a\xc0\x58\x7a\x94\x17\xc7\xd7\x3f\xe5\xad\x74\x03\x23\x95\x90\xa1\xbc\x97\x1f\x36\x2f\xbd\xd4\x8e\x4f\xf1\xa5\x89\xa6\x11\x97\x7b\xe2\xd4\x45\x8a\xe3\x24\xb6\xfc\x14\x8e\x3c\xe7\x3e\x2b\xfa\xb6\x40\x1e\x27\xa1\xe5\x50\x42\xa6\x25\xab\x17\xf8\x54\xe6\xb9\xf5\xbb\xbe\xc8\xd5\xc5\xd4\x51\xe4\x1f\xa1\x72\x76\x02\x33\xee\x8f\xc6\xa1\xb1\xc6\x37\x4c\x53\x85\x90\xc0\xfb\xf5\xc3\xfa\xe1\x76\xbf\x59\xfd\x5c\x6c\xae\xfd\xef\x53\x15\x22\x2e\x7d\x28\xbf\x33\xf8\x21\x63\x0b\x91\x1f\x22\x6b\xfe\x79\xea\x93\xc2\x31\x8b\x05\xf6\x3a\xee\x5d\x91\x68\x73\x2a\x26\x0c\x28\x3c\x66\x82\xa0\xfa\x44\xbb\x48\xa5\xa8\xc1\x6d\x63\xe3\x56\x98\x2f\xa8\x77\xda\xb3\x19\xb1\xbd\x9d\x8f\xc5\xae\x12\xb8\xd1\x0f\x3d\xa7\xd8\xe7\x13\x75\xb9\x98\xa9\x70\xf7\x17\xe2\x10\x42\x07\xcd\x74\x5d\xa4\xdb\xd2\x34\x03\x6a\x5c\x1e\xa7\xa1\xc1\x04\xc5\x31\x53\x6f\xbb\x4c\xbd\x41\x33\xd4\xe1\xe7\x71\x9a\x04\xda\x8c\xd0\xc7\xd9\xc1\xd6\xb2\x2e\x1e\x3b\xa5\x71\xe8\x60\x69\x98\x97\x58\xeb\xee\x47\x14\x20\x9a\xea\x90\x15\x1d\xc9\xc4\xf8\x5c\xc1\x02\x21\xdc\x22\x01\x7d\xe9\x4b\xc7\x32\xb5\xd1\x97\x6e\x7d\xbd\x13\x58\xcf\xc9\x5f\x5f\x25\x51\xd4\x83\x46\x1e\xe0\x63\x8a\x0c\x18\xba\xbe\xb1\xa2\x11\xb2\xcc\xac\x97\x8f\xfb\xe5\xe2\xc9\xfb\x7d\xb1\x0e\x58\x24\x86\x22\xe6\xed\x8c\xfd\x2e\xbe\x8d\xb5\x8e\x50\xd9\xb0\x01\x71\xb0\x5f\x77\x1f\xf9\xab\x41\x62\x99\xe1\x96\x9b\x3f\x9f\x76\x8f\x0f\xab\xcd\xea\xf9\xbe\x3b\x26\xd3\xb4\x2f\x64\xf6\xc5\xf4\xc9\xde\x1d\x83\x94\x5e\x14\xe6\xf7\x7b\xef\x30\x74\x14\xdc\xed\x62\x8b\xfd\x50\x13\x59\x31\xd3\xf2\x1d\x2a\x5d\x09\xd3\x3c\x63\x16\xbe\x4b\x66\xc5\x86\xd9\x14\x0b\x3e\x90\x2f\x0d\x55\x70\x59\x10\x1e\xad\xa1\x84\xc4\x04\xf3\x5c\x7b\x38\x64\xcd\x52\x34\xf0\x52\x56\xe7\xd5\xbb\xc8\x4f\x58\xb7\x9e\x33\x56\xf3\x5a\x25\x3c\x21\x34\xe9\x37\xe3\xed\x49\xda\x38\x73\x64\xfb\x13\x02\x21\xd6\xe7\xee\xca\x17\x4b\x07\xf9\xb0\xda\xcd\xbf\xfc\x24\x4c\x53\xb4\x2f\x88\xb3\x26\xb8\x21\xae\xbc\x48\x22\x4f\x42\x9d\x48\x2b\xa9\xef\xe4\x8f\xf6\x5d\x16\x6f\xfc\x80\x91\x0e\x3d\x9b\x70\xbb\x97\x5c\x9d\xdb\xff\x2d\xc4\x01\x46\xa8\x12\x9e\xc4\xa1\x41\xa1\xb4\xc5\xc3\x9f\xfe\x37\x12\x1d\x23\x2e\xb6\xbd\x2f\x0f\xbe\x1d\x3f\x0e\x4d\x12\xec\xf5\x5d\xfc\xe7\x24\x9e\xc4\xf9\xb7\x19\x07\x7d\x9c\x92\x4c\x5a\x87\xc8\x6a\xa2\x6a\x0d\x95\xe5\x05\xbd\xea\xb2\xb9\x09\xe5\x1c\xd3\xdf\xfb\xca\xf1\x82\x6d\xbb\x23\x32\x55\x1e\x85\x63\x79\xdf\xfc\x11\x46\x18\xa6\xae\xca\x23\x0c\x80\xea\x3c\x61\x09\x09\x5c\x49\xf5\xba\x10\x43\xb6\x35\x9e\xa4\x01\x89\x12\xe7\x8c\xb7\x3e\xae\x13\x4d\xe8\x0e\x87\x11\x2e\xd7\xff\xcb\xe4\x93\x6f\x5c\xe4\x49\x2a\x82\xd4\x35\x92\x0e\x63\x97\x24\x05\x89\xde\xb2\xa5\xe9\x68\x63\xad\x7d\xbc\xbf\x5b\xdf\xaf\x77\xdd\x08\x63\x70\xcb\xdf\x7e\xc0\x35\x7c\x4e\xd4\xff\x79\x22\x58\x88\x7d\xe2\x0f\xf0\x81\x65\x2e\xff\x67\x29\x48\xea\x51\x08\xf0\xbc\x59\x8f\x1c\xbb\x44\x68\xc0\xdc\x80\x2b\xb1\x6d\xf7\xbf\xaf\xb6\xbb\x76\x23\x18\x73\x84\xe0\x40\x74\x57\x1d\x97\xd3\x30\x3b\x9f\x48\x12\x61\x23\x12\x52\x50\x5e\x65\xcd\x83\x38\x35\x99\x1a\x96\x54\x79\xa2\x02\xdb\xf0\xbc\x3f\x0a\xf5\xb6\x11\xae\x7e\xf1\x3f\x45\x59\x89\x26\x76\xaf\x78\x87\x2a\x33\x56\xa3\x6b\x36\x76\x4d\xb4\x0b\x9e\x5e\x90\x13\x0c\xf9\x0f\x27\xf4\x02\x3c\x81\x80\xf5\xf0\x91\xfa\xcb\x5b\xf0\xa3\x93\x14\xe2\xa9\xbc\xe7\x18\x16\x39\xbf\xf2\xc0\x58\x72\x05\x71\x3c\x42\xa1\xaf\x45\xf5\x56\xb4\xf7\xfd\x6d\x16\xe2\x8b\x7b\x30\x11\xa3\xce\x1d\xb4\x2c\x05\x93\x8d\x21\x31\x89\x45\x9a\x34\x76\x27\xc4\x37\xeb\x0f\x19\x1b\x2e\xd7\xd0\x2c\x4e\x4d\xd9\x11\x35\x67\x65\xf1\x7b\x26\x56\xbb\x1f\xc3\x5a\x5d\x3d\x69\x77\x68\x4f\x07\x8c\x37\x0f\xd8\xca\xf1\x75\xd2\x8a\x06\xd2\xd8\x2e\x98\xcd\x72\x38\xad\x69\xa0\x09\x4e\xbf\x36\x68\x39\x15\x59\x63\x09\xdf\x2c\xdd\xb0\x1f\x43\xa4\x00\xd1\xe7\xaf\xf6\x62\xe4\x82\x51\x02\x84\x3a\xf0\xcb\xea\x80\x1d\xe9\xb0\x15\xb9\xa8\xce\xdf\xe7\x89\x29\x31\xa9\x97\x1e\x19\x82\xc6\x76\x93\x7a\x28\x0d\x99\xc2\xf4\xfd\xdd\xfa\x61\xbd\xec\x94\x6a\x38\x8d\x4c\x82\x85\x87\xab\x46\xfd\xd7\xd6\xea\x7e\x59\x2c\xa1\x31\xa1\x38\xb9\x96\x9b\xc7\x9f\xd7\xdb\xc5\xdd\x6a\x28\x60\xc6\x69\x1c\x2b\x0c\x1d\x3d\x56\x64\x0f\xcd\xeb\xbe\xdd\x27\xc0\xb2\xb2\x77\xe3\x98\x45\x55\x94\x4e\x65\x62\x6c\x59\x68\xcc\x05\x1e\xb6\x1c\x0f\xa7\x62\xc8\xca\xcc\x69\x92\x86\x84\x8e\xc8\x59\xef\x4a\xf5\x96\x15\xd7\xe2\x3c\x99\x38\x94\x06\x02\xd3\x79\x8e\xea\x7d\x9a\x39\xa4\x94\x52\xdc\x30\x97\x65\x51\x97\xa3\xef\xca\x02\x86\x31\x59\x56\x2f\xf3\xb2\x86\x1e\x5a\xc1\x29\x27\x04\x79\x91\xfc\x5e\xd2\xeb\x99\x8d\x7f\x9c\x47\x8c\xcb\x8e\xa6\xf7\xd1\xac\x0b\x55\x7e\x55\x25\xa0\x3c\xd2\x88\x98\xb5\x99\xed\xf3\x73\x91\xa9\x5f\xc4\x82\x94\x2b\x4d\x5d\xfc\xf2\x54\xe6\x99\x3a\xdb\x7e\xa4\x27\x6c\xd0\xf8\x6d\x92\xfe\xf3\xe7\x80\xe2\xae\x94\x33\xc2\xbc\x8c\x6f\x46\x48\x89\x01\xb5\xc8\xf3\x9b\x2c\x3f\xd4\x17\x6a\xc7\x9c\x4a\x16\x99\xa0\x0b\xfb\x87\x15\x49\x2a\x95\x15\xe1\x5a\xfd\xf1\xb4\x5a\xee\x56\xd7\xfb\xd5\x83\x77\xb8\xa9\x4a\x23\x7c\x27\xae\xc6\xfb\xe8\xd8\x96\x27\x4e\x3b\x85\x28\xc1\x4e\x85\x1a\x9b\x9f\x27\xf3\x19\x74\x62\x4d\xd6\x6b\x56\xe9\x7b\xf1\x39\xca\x8a\x53\x00\x86\xbe\x6c\x65\x33\x22\xcb\x53\x93\xc1\x38\x64\x8d\x83\xc9\xaf\x19\x16\x22\xc6\x63\xef\x85\x33\x6c\x5d\xc8\x87\xbb\xf3\x5f\x8c\x05\x22\x40\xfa\xd0\x76\xf9\xbd\x8a\xa2\x80\xbc\x9d\x29\xed\x2c\x83\xa6\xc9\x7b\xe6\x0f\x3f\x5c\x82\x6b\x1c\x6b\x7e\xb7\xaa\xf1\xdb\x06\x8e\x0e\x5b\xfd\xad\x8d\x66\x81\xd6\xb8\xab\xb7\x7e\xa2\xbd\xa9\xd6\x4a\x5b\x76\xb4\x8e\x4c\xf8\x0b\x86\x0a\xce\x88\x16\x98\x6a\xdc\xfe\x78\xdc\xf8\xbd\x96\x11\x63\xb0\x63\xeb\x16\x9a\x0b\xe5\x1d\xce\xc2\x24\x52\x8e\x51\xa9\xf5\x24\x4e\xfd\x76\xcb\x22\x49\x10\x9f\x71\x6b\x77\xa0\xc3\xe9\x70\xe5\xd1\x6a\x9c\xc5\x81\x60\xbe\xcc\x5c\x81\xce\x9a\x3b\xd0\x53\x32\x7c\xce\x92\xd8\x36\x38\xf8\xe6\xd6\xea\x5e\x1c\x8f\x17\xa5\x16\x96\xd0\x28\x62\x23\x74\x95\x03\x32\x97\x55\x7d\x07\xc5\x4b\xf3\xea\x90\xb7\xf7\xe5\xd2\xdf\x40\x92\x26\xca\x31\xfc\x17\xe5\x87\xf5\x2d\xfd\x21\x19\x82\x43\xc9\xac\xeb\x2b\xd1\xa8\xd7\x81\x1b\xc4\x68\xc0\x84\xed\x17\x2a\x3f\xbc\x7d\xde\x9b\xb2\xda\x97\xc7\xd6\xf6\xec\xaf\xfc\x65\x68\xc8\x11\xb9\x69\xe5\xc7\xd6\x9e\x62\xcd\x1f\xa5\x01\x96\x59\x17\x9b\x21\x05\x14\x67\x54\x70\xec\x51\xdc\x57\x65\xc7\x53\xc3\x19\x93\x09\x56\xd2\xbc\x23\xee\x5e\xe8\x0d\x38\xcc\xea\x8c\x5f\x3e\x58\x67\x8c\x69\x89\x00\xdf\xa2\x2c\xba\x1b\xe0\xc2\x6a\xa0\xd8\x20\xc8\xba\xf9\xa5\x6d\x1d\xea\xf3\x69\x8c\x0b\x80\xa1\xe2\xeb\x22\x9f\x94\xf0\xdc\xb8\x34\x48\x50\x81\x41\x0f\x76\xd5\x41\xe8\xfa\x0b\xd4\xf6\x17\xb3\x39\x15\x06\x49\x83\xbd\x54\xd7\x44\xfa\xc8\x8f\x32\x0a\x73\xa6\x02\xd9\x43\x2f\xec\x0f\x13\x26\x61\x72\x50\x0c\xbc\x29\xab\xad\x98\x91\xbb\xee\x8a\x3c\xfd\xb7\x96\x44\xa1\xfb\xfc\xd1\x77\x96\x5c\x81\x29\x2b\xdb\x7a\x37\x53\xf2\x64\x92\xd9\xf5\x60\x95\xa8\xac\xc2\xd9\xf8\x76\x14\x68\x74\x95\xb1\xf7\xdf\xc1\x30\x2e\x2a\x33\xa3\x33\x74\x18\x61\x0e\xec\xf6\x74\x38\x78\xe7\x99\x69\x2e\x31\x99\xfa\x21\xf2\x37\xbb\xa7\x63\x10\x3d\x0e\x3d\xa7\x7a\xe7\x9c\xe9\x34\x0e\x3b\xc6\xb9\xde\x16\x62\x4f\x0e\x52\x6a\x5c\x5f\xcf\x5b\x7a\x06\x81\xc2\x2f\x5c\xc0\xc7\xe2\xc5\xe5\xea\xc7\x1d\x82\x9c\x41\xa2\x23\xe3\x3d\xec\xcc\xeb\x14\xdc\x60\xc1\xa5\x50\xe7\xc9\x9b\x00\x96\x24\x03\xcd\xa4\xdf\xa6\xaa\x75\x9c\x81\xdb\xdd\xad\x54\x99\xe8\xee\x16\xa4\xf2\x52\x2b\x2e\x45\xe6\x16\xc4\xb8\xcd\xd9\x8d\x36\x91\x6d\x4b\x2e\x3f\x8a\x9b\x2c\x87\xf9\xcc\xbf\x1f\xcb\x63\xe4\xbf\xe8\xf2\xb7\x75\x89\xb2\x5b\xc3\xf2\xc4\xe4\x0c\xa3\x89\x55\x6c\x43\x90\xb8\xf3\x33\x5c\xd5\x7d\x36\x48\xe6\x41\x64\x79\x8b\x84\x9e\x90\x61\xce\x31\x88\x5d\xbc\x15\x1e\x24\x11\x31\x3e\x71\x22\x54\x9e\xfd\x17\xfa\xca\xa5\x1b\x43\x58\x1c\x38\x79\xf7\x1b\x71\x40\x36\xb7\x6a\x2e\x9c\xec\xde\x12\x27\xc6\x62\x65\x90\xdb\x73\xe7\xd1\xd7\xe3\x57\xc9\xc3\x84\x62\x57\x6f\x9d\x0f\x62\xf1\xaf\x52\x53\x3c\xa4\x34\xe8\x41\xb8\x4b\xc8\xf3\x75\x17\xa4\xf1\x50\xc7\xa9\x71\x99\x5d\xa1\xc0\xb7\x9b\x8d\xd7\x13\x8f\x62\x21\xdc\x7c\xf5\x54\xcc\x03\xc3\xc6\x23\xca\xe3\xb8\x73\x9c\x9e\xc4\x19\xba\xba\x0c\x8f\x84\xc0\x50\xe9\x36\x2f\xa5\xc8\xed\xcc\x58\x8a\xe3\x0f\x51\xe9\x6e\x88\x0c\x54\x5f\x8e\xda\xcc\x68\x8f\xf9\x81\x46\xa6\x81\x47\x83\xe1\x96\xec\x05\xac\xdd\x80\x24\x09\xf8\x40\x3d\xae\xcb\x37\x7a\x91\x97\x49\x3f\x8f\x3f\x4b\x0b\x49\x87\x2c\x1f\x4f\x50\x0d\xf4\x4e\xdd\x28\x1a\x1a\x65\x33\x7c\xab\x5a\x89\xa3\x4f\xf0\x8d\x69\x70\x39\xa7\x89\xd4\xb6\xf4\x51\x37\x50\xb5\x21\xd6\xda\x2d\xac\xf1\x2b\xa5\x9a\xa2\x33\xd8\x49\x33\x5d\x3a\xa4\xad\x23\x81\x63\x0e\x36\x09\xdb\x86\x51\x76\x2d\xeb\x45\x33\x44\x0d\xb6\x76\x88\xd0\x29\x3d\xed\x06\x50\x3a\xd9\xc6\x67\xb3\xae\x06\xe7\x10\x2b\x9b\xd2\x42\x04\xe9\x16\x4b\x7c\x0b\x9f\x83\xe0\x69\x24\xa8\xc3\x4b\x3f\x9c\x0e\x8f\xa6\x9d\x8a\x75\xbb\x89\x6f\xc5\x01\xd6\xda\x53\xc3\xb8\xd1\x32\x4c\x30\x43\xb7\xf8\xbf\xbb\xdd\xca\xb3\x9a\x71\x2e\x29\x11\x96\x7c\x71\xed\xa4\xe2\xf4\xaa\x28\x4f\x2f\xaf\x93\x17\x22\x21\x45\x53\xba\x59\x6d\x57\x9b\xdf\x57\xfb\xd5\x1f\xcb\x1f\x8b\x87\xdb\xd5\x7e\xb3\xd8\xf9\x78\x85\xab\x40\xe0\x74\xbd\x5b\xdc\x3f\x75\x7f\x4b\xc0\xd8\xf6\x93\xcf\xc6\xf9\xd2\xfe\x48\x6a\xf5\x4a\xf7\xf2\xd4\x3a\xe8\xd6\x26\x64\xff\x05\xfd\x94\x7d\x42\x3e\x6a\xc3\xfa\xaa\x59\xd9\x5d\x09\x22\xcb\x07\xd4\x86\x7c\x9b\x65\x18\x88\x19\x00\x3e\xe7\xa0\xac\x5c\x54\xfd\x5a\x7e\x3c\x17\x47\x91\x79\xf0\x8c\xef\x20\x98\x0c\x37\x21\xa6\x78\x96\xa2\xca\xcb\x7a\xe8\x7f\x70\x23\x62\xc4\x3d\x3a\x4d\x0c\x1f\x06\xd9\x80\x21\x9f\x4e\x4d\x03\x71\xa8\x07\x06\xff\x17\xfe\x29\x37\x60\x73\xa6\xda\xb5\x16\xa1\x53\x4b\x7c\xf5\x2b\x0d\x82\x18\x71\x02\x87\x52\x67\xe6\xfc\x4f\x6c\x0f\x55\xcb\xbc\x3c\xe9\xf5\xe3\x6e\x2e\x4b\xe2\xcf\x0b\xa9\x88\x5c\x62\xd5\xf2\x19\x8d\xcd\x61\x1a\x48\x86\xcc\x43\xc6\xb1\xdd\x5c\xd2\x0d\xf0\x34\xd0\x21\xfa\x58\xeb\x7a\xf7\x9a\xd5\x4e\xb3\xc2\x5f\x80\x24\x0a\x39\x0e\x8f\x58\xd1\x7b\xaa\x60\xbd\x7b\xdc\x7f\x40\xf6\x34\x62\xd0\xe7\x29\x61\x04\x69\x62\x70\x3d\xfc\x10\x75\x96\x5f\x4d\xa8\xc8\x79\x4a\x52\x8a\x69\x60\xa8\x04\x36\xf9\x8f\x79\x68\x78\x4a\x84\x41\x96\xd2\x03\xbc\x88\xa5\x28\x3c\x37\x26\x4f\x89\xd1\xc8\xda\x03\xa2\xca\xcf\x32\xab\xf4\x0a\xb5\xb0\xdc\xd1\x90\x5b\x89\x05\xef\xaa\xed\xb3\x89\x44\xdf\x5f\x3d\x81\xe1\xf8\x3f\xbf\x3c\xf0\xbf\xff\xa7\x4f\x2c\xa7\x61\x4a\xb0\x9f\x14\x95\xe8\xe1\x73\x96\xec\xd9\x0d\x8d\x39\xe3\x3d\x9b\xc1\x53\x55\x1e\xca\x7b\xb8\x0c\x7b\xe7\x3a\x2c\x79\x4a\x99\xf5\x88\x33\x5f\xf5\xc7\xe0\xbb\x7b\x19\x54\xa7\x38\x31\xb3\x7a\x03\x2f\xa7\x5c\xcc\x36\xae\xf0\x94\xb1\x00\xb1\x27\x4f\x39\x14\xa7\xc3\x6f\xa7\x0b\xce\x4e\x9e\x32\x6e\xf5\xcc\xea\xd2\x34\x1b\xa8\xcb\xfc\x1d\x2c\xcd\xd7\x78\x29\xa4\x9c\x46\xe8\x4f\xfb\x6c\x66\xeb\x66\x7a\x4b\x91\xa6\xae\x5b\xb9\x12\x19\xd2\x51\x67\x65\x7f\xc4\xf2\xf1\x1e\x11\xbc\xd7\x89\x42\x76\x0f\x22\x62\x13\xa4\xfe\x25\x95\x95\x73\x81\x51\xa6\xa5\x0b\xb5\x52\xa1\x94\xf0\x80\x73\x6f\xd5\xaf\x45\xf3\x45\x67\x14\x4f\x05\xc4\x98\xed\x2e\x5b\xf7\x01\x26\x6b\x45\x25\x12\x6c\xe7\xc6\x1f\xfb\xdd\xe3\x6e\x71\xe7\xb0\x2f\x8b\xfb\xc7\xe7\x0e\xc0\x9f\xaa\xd6\xfa\x0d\xbc\xea\x8b\xaa\xc4\xe4\x63\x2b\x2d\x70\x05\x22\xb0\xd9\x3d\xe5\x20\xbf\x92\x6a\x02\x98\x38\x35\x65\x29\xc7\x58\xca\xd4\x10\x16\x39\x3e\xe2\x01\x85\xf2\x24\x2b\x7e\xea\xc9\x2f\xa6\xb9\xd0\xd4\x24\x06\x53\x19\xea\x70\xc9\xa5\xd0\x1b\x00\x11\x10\x85\x4d\x89\xea\x5d\x0d\x78\x5e\xb8\x20\x3a\xc4\x00\xc2\x64\x55\xdd\x60\xa3\xca\xcf\x7b\xaf\xdc\xde\x97\xc6\x44\x1c\x44\xda\xd2\x95\x1c\x3d\xc6\xfe\x9b\xd9\x2f\x62\x69\x08\x19\xd0\xe9\x0d\x11\xe3\x9d\x5f\xfd\xb7\x19\x2f\x5b\x24\x21\x8b\x3b\x09\xde\x5c\x9c\x41\x6f\xad\x4e\xad\x27\x4c\x1b\xbc\x91\x90\x0f\xdd\xc8\x89\xb0\x09\x17\x49\x1c\x20\x03\x93\x6f\x73\x9f\x5d\x25\x22\x51\x21\x06\x0d\x15\x98\xac\x80\x5e\x48\x85\x0b\x4a\x38\x96\x4c\xd1\xde\x54\x58\x46\xd8\xab\xd6\xc1\x1a\x38\x69\x82\x42\x8a\x2f\x46\x43\x9e\xbd\x43\x75\x1e\xd7\xc0\x47\x9f\x4a\x30\x96\xf2\xd8\xeb\x53\x58\xda\xd4\x81\xeb\x2b\x52\x61\x65\xc2\x2d\xea\x77\x08\xc9\x9d\xbc\x5d\x41\xa4\x15\x7c\x13\x59\xf7\x1d\x05\x03\xe2\x7a\xc9\x77\x20\x0e\x3f\xb0\x88\x3e\xaa\x01\x08\x21\x42\x34\xcd\x16\x78\x73\x2f\x8e\x3d\x10\x4b\x48\x20\xc6\x41\x1e\x97\xab\x5d\x8c\x04\xdc\x57\xe7\xb5\x76\xce\x58\x37\x8a\xfa\x54\xeb\xa0\x8b\x7a\xad\x2f\x77\xc6\x49\x82\x59\xa8\x90\x5a\x81\xab\x57\x71\x09\x2c\x11\x10\x31\xb4\xee\xe0\x6a\x69\xe3\xde\xe0\xc9\xd3\x43\x04\xb1\xec\x1c\x6f\x4c\x54\xd9\x48\xc3\x42\x89\xa6\x99\xf7\xc9\xc9\x09\xa0\xb6\xb5\xa3\x4a\xdb\x89\xc2\xab\x9f\x72\x01\x69\x80\x29\xb3\xcd\xcd\x70\x85\x0a\x00\xa5\xd3\x8e\x57\xbb\xb9\x69\xed\x54\xd3\xe4\xb0\x1c\x0a\x2e\xcc\xbb\x04\xc2\x84\x11\x3e\xb6\xdf\xb6\x76\xe5\xf1\xd9\x97\x53\x84\x89\x8d\x49\xfc\x54\x47\x22\x2a\x8c\xc4\x66\x5a\x5c\xb9\x30\x14\x90\x4f\x04\x0e\x59\xf3\x43\xd4\xaf\xdb\x41\xab\xd8\xfc\xec\x37\xcc\x92\xe4\xa3\x46\x50\x25\x5a\x8b\xba\xbc\x8c\x1f\x85\x51\x09\x16\xd0\x8f\x08\xd4\xf5\x99\xe4\x49\x87\xc7\xf8\xa9\x64\x10\x11\x5c\x32\x8e\xd7\xac\xbd\xdb\xd3\x80\x7d\x76\xf0\xbf\xfe\x84\x84\xd0\xd0\xd1\xfc\x17\x2f\xb0\xcb\xf2\x81\x2e\xc9\x64\x4f\x92\x24\x21\xc6\xb6\x1a\x16\x8d\x18\xd0\x66\xfa\xc3\xdc\x96\x3a\x73\x30\xcd\x9d\x6b\x04\x71\x87\xc2\x24\x40\x06\x04\x14\xdf\xe8\x48\xdf\x06\xf9\x2d\x19\x52\xc7\x95\x51\x3f\xaf\x5b\xa3\x83\x21\xc4\xba\xa0\xf1\x08\x55\x20\x23\x62\x82\x76\xa1\xfe\xf8\xf1\x23\x9a\x51\xf5\xe2\x32\x0a\x43\x8c\x6d\xde\x2d\xf9\x8a\xfe\x99\x15\xc5\x58\xa4\x89\xcb\x98\x24\x96\x90\x5f\x14\x79\x26\x8a\x97\x9e\x26\x80\xcb\x38\x34\xc4\x0c\x4d\x53\xbd\x28\x1e\x8f\xc7\xb2\x80\xfe\xfc\x24\x00\xe8\x68\xab\x8a\xa2\xc8\x8a\x17\x97\xf0\xeb\x46\x30\xdb\x90\xf0\xfb\xfa\xa9\xd3\x5a\xfb\xaa\xf0\x34\x7e\xc7\x34\xb0\xc2\x36\x42\xbd\xdd\xd7\x2f\xb3\xb1\xbf\xe4\xa1\xc2\x7e\xfd\x2b\x51\x43\xc7\x19\x39\x01\x2a\x4a\x4e\x15\xb6\x85\xfc\x9f\xed\xd7\xf9\x25\x02\x48\x72\x96\xfa\x76\x7c\xdb\xb8\xba\x9e\xe4\x90\x64\x1b\x5a\x77\xa2\x20\x2b\xef\x0d\x4e\x06\xa5\x2c\x42\xb0\x1c\x96\x53\xee\xad\xc8\x50\xd6\x99\x33\x99\x72\x82\x31\xc0\xcd\xe3\xf3\x66\xf7\x63\x18\xeb\x48\x21\x52\xa6\x87\xd2\x5a\xd7\xd0\x80\x6a\x90\x8a\x71\xbc\xe8\xa4\x64\xd4\x76\xfe\x62\x91\x1e\xd3\xd9\x87\xc1\x07\x92\x90\xa0\x63\x82\xa1\xcb\xef\x65\x73\x91\xbb\x95\x2a\xa2\x58\xb0\xfb\x47\x0e\xe7\x62\xf8\xfd\x55\x24\xa8\x1a\xe7\xde\x9e\x72\x51\x14\xae\x83\xab\xab\xd3\xf9\xe1\xd2\xa0\x93\x70\x14\x67\x1b\x73\xb7\xb7\x71\x55\xea\xf3\x5c\x4a\x48\xea\x54\x39\xfd\x8f\x37\xb0\x98\xa0\x9d\x47\xc7\x4c\x5f\xa3\x16\x11\x38\xdb\xb6\xdb\x0c\xf2\xac\xf3\xb3\x06\x64\xa8\x6c\xa5\x45\xbd\x9d\x8e\xf4\xb0\x0f\x03\xc2\x03\x1e\x90\xc9\x63\x1b\x9d\x30\xd3\x95\x67\xa1\x7a\x34\xa6\xee\x16\xb0\x0a\x0c\x49\xa0\x43\x5b\xa3\x86\xfe\x38\x46\x50\x24\xd0\x58\xae\xba\x42\x0e\xf1\xd9\x06\x0e\x45\x42\x8d\x6a\x02\x4f\xed\x2b\x99\xc8\x15\x73\x45\x18\x60\xa9\xa0\xa3\xfb\x15\xf9\xf4\x7c\x11\x60\x9d\xfa\xea\xe4\xb4\xa9\x56\x9f\x13\x31\x80\x81\x67\xce\x1c\xab\x96\xb3\x6a\xce\xac\xa9\xd0\x11\x73\x8e\x72\x7c\x3d\xc4\xfc\x5b\x34\xbf\x0a\x19\xc7\xc4\x9d\x35\x21\xaa\x93\x12\xf0\x87\x95\x15\x4f\x3a\x88\xac\x58\x2f\x1f\x57\x43\x69\x25\xae\x22\x12\x60\x81\xb1\x27\x60\xb4\x33\xe1\x6b\x95\x73\xae\x22\x1d\xe2\xf6\x76\x27\x0e\x62\xb8\xc1\xa9\x08\x14\xf2\x79\x94\x2e\xdf\xb6\xff\xcf\x09\x7a\x0a\xef\xf1\x2a\xfe\x2b\xf4\x97\x8b\xd3\x14\x73\xf9\x79\xa5\x5c\x38\xde\x05\x28\x2a\x56\x1c\x19\x5f\xaa\xec\xe5\xb5\x71\xc6\xb5\x7f\xf5\x34\x21\xe1\x48\xdf\xf1\x01\x3e\xad\xeb\x39\x32\x6f\x8a\xa6\x21\x75\x8e\xbf\xcb\xa4\x38\x3e\x57\x7c\x57\xd7\x53\x6a\x7c\xae\x28\x50\xf4\xaf\x84\xd6\x56\x0c\xd4\xba\xcd\x3d\xcf\x28\x57\x18\x01\xd8\x95\x24\x64\x3e\x81\x72\xa8\x34\x8c\xb0\xac\x8b\x39\x0c\xa4\x8a\xba\x86\xf7\xc1\xba\x55\xa9\xe1\x48\x09\x71\x2a\xb6\x3e\x6f\xef\x17\xa9\x12\x34\xc5\x9a\x9e\x90\xf5\xf6\x24\xe7\xb7\x4e\x25\xa4\x85\xe9\xdb\x06\x1c\x7f\xaa\x64\x96\xe5\x1e\x29\x09\x5c\x82\xa9\xbb\x29\x29\x24\xce\x54\x94\xe0\x98\xba\x4e\x4a\xca\x44\xbb\xd5\x74\x2f\xde\xa6\x6f\x44\x81\xa1\x2e\xba\x58\xe6\x27\x08\x47\x0e\xa1\xd2\x81\xe8\x78\x78\xa1\xf3\x7b\x95\x56\x80\x8d\xda\x9e\xb9\x72\xad\x6b\x2c\x9e\x14\xed\x0f\x38\x34\xdb\x17\xce\x99\x82\xc0\x32\x83\xfe\xf3\x04\x35\x5e\x74\x34\xd3\x80\x4a\xec\xb7\xef\x00\x74\x9e\x8f\xf1\x7f\x03\x88\xe8\x20\x00\x3c\x5f\x8b\xf3\x68\xaa\xe8\x80\x73\xd9\xf5\xdc\x63\x52\xd2\x7f\x16\x4d\x02\x23\xb9\x4f\x28\xbf\xd8\x1d\x7a\xf8\x16\x34\xe1\x31\x76\x11\x42\xdd\xfc\x2c\xf3\xb7\x5d\x79\x75\xaa\xe6\x99\x17\xda\xb1\x12\xc9\x51\x7f\x64\x15\xdc\x96\xcb\xa9\xfe\xfb\xf8\x65\x68\x62\x94\x31\x1d\x32\xfe\x01\x3e\xae\x5a\xcf\xc4\xbf\x67\x1d\x06\x44\xf4\x6c\xd8\x0f\xa5\x46\xd2\xdd\x0b\xc1\x7b\x37\x3a\x8a\xa1\xab\xb3\x96\x87\x63\x03\xfb\x2e\xb5\xa4\x23\x41\xb1\x50\x7d\x3c\xe5\x39\x76\xe8\xb6\x17\xea\x90\xae\xa6\x01\x14\x14\x75\x83\x63\xce\x30\xe8\x5e\x2d\x36\x77\x7f\x5e\xad\x37\xd7\x16\xbb\xb0\xbf\x7f\xbe\xdb\xad\x9f\xee\xd6\xab\x4d\x37\x32\x05\xbf\x00\xbb\xbb\x42\xc4\xf5\xe4\xd6\x62\x11\x20\x9c\xee\x15\xaa\x72\x8a\x84\xd4\x31\x80\xe7\x34\xc1\xc0\x73\xf5\xd9\xbd\x80\x84\x18\xcc\x3b\xdd\x66\xa6\x99\x41\xef\xea\x24\x0a\x50\xb7\xcb\x8a\x8f\x1f\x5c\xb6\xd9\x1f\xa4\x96\xcf\xb5\xf1\xb9\xe5\x5d\x36\x38\x08\x06\x73\x66\xcb\xc5\xce\x29\x7e\x7c\x0f\x25\xd6\x89\xd1\xd8\x45\x81\xfa\xe5\xfe\x2a\x3c\x96\x6c\x48\x3f\xdc\xce\x56\xcb\x6a\x31\x3f\x3d\x79\x6c\x54\xe4\x59\xe8\x7b\x41\x1c\xae\x39\x27\x98\x3e\x01\x9b\x11\x73\x27\x8f\xcf\x85\x20\x49\xbc\xaf\xe1\x22\x55\x5b\x9e\x9d\x00\x21\x75\x9a\xc4\xa9\xcb\xab\xff\xc8\x5e\x5e\xa1\xb6\xd9\x49\x7c\xb9\x8b\x89\x2f\xa0\xd3\xc4\x20\x50\x1e\x21\x5b\xb3\x1d\xa9\x3a\x4d\x03\x0c\xbe\x50\x2e\x6c\x0b\x79\xde\x06\x36\x56\xf1\xd0\xdf\x7f\x2a\x78\x2a\x9c\xbe\x41\x26\xf2\xf5\xf2\xb1\x6f\x3b\xd0\x29\x70\x11\x39\x68\xfc\x0d\xc0\xda\x4c\x5b\x34\xb4\xa0\x1c\x97\xed\xde\x40\xa3\x5e\x2d\x96\x51\xdb\x8a\xde\x4d\x59\x3d\x5d\x36\x9f\x6a\x21\x19\xb7\x14\xde\x4f\x8b\x2d\x6a\xf8\x8e\x02\x51\x2d\x09\x8f\x3a\x19\x2a\x9b\xcd\x5d\x14\xfa\xd6\xf7\xeb\xf9\x51\x61\xdc\xe9\xb2\x96\x87\xe3\x40\xf4\xcd\x0d\x50\x3c\x44\xef\xf5\x54\xb4\xb6\x75\xd4\x4c\xaa\x75\xc0\x1c\x99\x6b\x23\xf2\xab\x01\x6a\x47\x6b\x30\x62\x18\xd4\x3d\x08\xf5\x00\x8d\xd9\x4c\x8c\xaf\x36\x11\x20\x40\x06\x75\xd9\xbf\xf2\xcb\x47\x9f\xc2\x30\xdb\x43\x69\x89\x60\xae\xb3\x0a\x2e\x5b\xd1\xfc\x50\x6e\x79\xa8\x90\xf5\x49\xfa\x5b\x33\x69\x8a\x29\x04\x44\xa8\x6e\xdf\xb2\x3c\xaf\xb7\x5f\xf3\xb3\x8d\x2f\x09\x41\xa8\x30\x1b\x6f\xa7\xef\x52\x4c\x04\xab\x38\x04\xb1\xc1\x6c\xa1\xd3\xc2\xf5\xd5\xc0\x01\x37\x06\x90\x34\x40\x4f\x75\x03\xef\xe5\x1b\xcc\x55\xd3\x81\xc8\x04\xeb\xa8\x8b\xf5\xf2\x2b\x8a\x1b\x0e\x51\xc4\x10\xcf\x06\xfa\xb4\xf4\x0a\x6f\x5f\x84\x14\x10\x09\x8a\xc1\xd8\x18\x7b\x56\xf7\x53\x14\x62\x2e\xd0\xd0\x3c\x89\x13\xde\x79\x67\xb8\xd7\x87\x63\xfe\x5c\x1c\xad\x64\xcb\x57\x7b\xd0\xf8\xf6\xe3\x94\x4a\xdb\x8d\x74\x51\xcc\x82\xd8\x55\xd2\x8e\xd8\x94\xd8\xad\x1f\x48\x92\x08\x23\x7d\x0d\xaa\x3a\x1f\x1b\x37\x97\xff\x0a\xe9\xbf\x5c\x4e\xaf\x4b\x31\x43\xc2\x62\xc7\x2b\xd8\x3c\xbe\xcc\x18\x45\x48\x20\xc4\x44\xcf\xbf\x4b\x39\x88\xbd\xfb\x7b\x48\x20\x16\x03\xe2\x52\xdb\x80\xf3\xad\xf1\x03\x0a\x0c\x73\x80\xe8\x43\x14\x67\x34\xf1\x17\x00\x6c\xa0\x00\x58\xd1\x7e\x99\x12\x8f\xfa\xe3\x26\xd5\xee\xce\xf7\x47\xe7\xd8\x77\x18\xbf\xc9\xf7\x9b\xaf\x09\x8f\xbe\x2a\x0b\x34\x86\x70\xa7\x02\x1d\x1f\xd7\x71\x57\x0f\x19\x7a\xdc\x48\x4e\x6c\x9d\xf4\x16\x0a\xb8\xda\x79\x10\x0c\x70\x43\x99\xf5\xa0\x3f\xaf\x7b\xa3\x00\x29\x89\x52\x0f\x9b\x5b\x3e\xa2\xbd\x10\xcd\x75\x99\xe7\x13\xed\x33\x0e\xa9\x0c\x51\xfd\xfc\xdd\x56\x43\xb7\x90\x83\x42\x2a\x97\xd9\x84\x0b\x08\x9e\x24\x7d\xbd\x75\x84\xc6\x02\x01\x46\x5b\x58\x5b\x23\xf2\x01\x45\x5e\xf7\x72\x55\x6a\x30\xff\xd6\xcd\x4c\x5c\x55\x13\xd2\xf8\xff\x0d\x59\x02\x4a\x31\xab\x8b\x2f\x85\xf2\x37\xa0\x89\x04\xe4\x93\x69\x6a\xff\x4d\x7c\x87\x1a\x00\x04\x91\xc5\x99\x2b\xab\x1e\x3c\xfa\x0e\x26\x96\x88\xf5\x7e\x5a\x6d\xee\xd7\xdb\xed\xfa\xf1\xe1\x7e\xf1\xb0\xb8\x5d\x6d\xf6\xff\x58\x79\xf4\x37\x18\x6a\x29\xd6\x5a\x7b\xbc\xab\x4e\xf5\xa0\xb9\xc5\x04\x61\x82\x3b\xdb\xf5\x1f\x37\xfb\x91\xc7\x6c\x82\x88\x62\x7d\x15\xdd\x5e\x5b\x95\x6f\xb7\xdf\xa7\x2e\xbd\x60\x02\xca\x11\x00\xb7\x5c\xed\x7e\x99\x5a\x30\xad\xc1\x56\xb6\x48\x91\x1d\x4e\x87\xbd\xb5\xa2\x83\x88\xdd\x04\x3a\x12\x2e\xb9\x8c\x1c\x45\xbe\x55\x6f\xf4\x21\x4d\x00\x16\xdc\x59\x43\x6e\x09\xcf\x5c\x4b\x4d\xf7\x86\x4d\x00\x12\x5b\x95\xda\xf5\xdc\xc6\x25\xcb\x76\x77\xad\x27\x08\x9e\xbf\x4d\xce\x31\x12\xbd\x6a\x54\x9e\x1d\x7a\xc5\x86\xb8\xea\x80\x18\x02\x77\xfd\x7c\x35\xa1\x14\xb8\x47\x49\x68\xf6\x1f\x5d\x24\x62\x42\x6d\x5b\x18\xb2\xda\x36\x9a\x76\xa0\x86\xcd\x09\x53\x45\x7e\x5c\x1c\x51\xdd\xa9\x61\xba\x5e\x85\xc1\xe1\x84\x52\x24\x20\x3c\x94\x1a\xf2\xbd\x50\xea\x54\x09\x75\xde\xab\x2a\x6b\xa0\xca\x44\x37\x4c\x4a\xcc\x81\x5a\x07\xa0\x81\x01\xf2\xdc\x24\x8a\xe2\xee\x5e\x8b\x77\x78\x82\xe3\x64\x17\x34\x34\x89\xb0\x7a\xeb\xab\x93\xc3\xed\xc2\x50\x95\x62\x47\x05\x54\xaa\x57\x29\xed\x0e\x3a\xed\x19\xf7\x3d\x9d\x00\xd5\xf3\xf6\xba\x1f\xc0\x63\xdd\x03\x24\xa6\x44\x4d\x86\x1a\x82\xe0\x4c\x9b\xbb\xbf\x75\xbc\xbd\xf7\xd0\xbc\x76\x7d\x8b\x86\x41\x18\x71\xcf\x4d\xde\xda\xbd\x9b\xb2\xba\x15\xd3\x96\x1b\xc3\x0c\xc7\x92\xdb\x7a\xf9\xb8\xc7\x57\xb9\x37\x27\x94\xfc\x18\x0f\xe3\xdc\xde\x91\x2c\x9b\x6f\x13\x2f\x86\xbb\xe8\xf9\xae\x7c\xb9\x3a\x9d\x6f\xca\xca\x13\x45\x7d\x51\x20\xf4\xa7\x29\xaa\x3d\xd5\x5a\x6b\xb2\x64\x59\x89\xa9\xaa\x04\x37\x1c\x42\xe1\x59\x91\x6f\x44\x96\xaf\xcd\x06\xde\xa1\xea\x5a\xed\x4c\x1a\x32\x9f\xf6\xb9\x13\xc5\xcb\x69\xf0\xce\xd2\x50\xa2\x95\xbf\xcf\x0a\xfd\xab\x36\x4c\x93\x72\xca\xc1\x43\x3c\x5a\x37\xc9\xae\x80\x01\x95\xa9\x1b\x28\x48\x2c\x83\xde\x73\xf0\x5f\xfa\xd9\xb5\xe5\x65\x68\x76\xfc\xd8\xd0\x28\x3a\x02\x3c\x5e\xc3\xbb\xd3\x92\xf2\x43\x12\x8a\xdd\x0c\xba\xa8\x6d\x12\xf1\xa2\x81\xf8\x34\x08\xfa\x8d\xa0\x40\x5c\x1c\x73\x27\x6a\x27\x23\x3f\xec\xab\x9a\x2c\xd5\x76\x17\x75\xc2\x79\x27\x98\x14\xc1\x8d\x50\x01\xef\x3c\x6a\x47\xec\x7d\x0d\xff\x0f\x69\x6f\xd2\xdd\x38\x8e\xe5\x8b\x7f\x97\xb7\xca\x45\x2d\x38\x81\x04\xfe\x3b\x59\x96\x23\xf4\xd2\x53\x59\x8a\x8c\xcc\xee\xd3\x47\xe7\x02\xb8\xb0\x59\xa6\x48\x15\x49\x39\xec\xfa\xf4\xff\xc3\x0b\x80\x93\xe8\x88\xec\xf3\x7a\xd1\x19\x65\x42\x14\x45\x82\xc0\x1d\x7e\xc3\xf1\x5c\x13\xe5\x65\x76\x22\x93\xd2\x04\x24\x23\xf5\x95\x35\x6d\xf0\xe7\x51\x21\x44\x16\x54\x03\xc5\xc5\x0f\x54\xb1\x55\x6f\xe9\x62\xea\x39\x03\xc4\x28\x08\x8c\x8d\x4c\x9f\x5a\x35\xfb\x46\x1d\x06\x8e\x77\x76\x7c\xc4\x7a\xe4\x84\xc9\x8d\x96\x11\x05\x27\xf4\xc7\x5f\xaf\xa6\xda\x08\x02\x59\x1d\x48\x87\xeb\x2e\x2f\xdb\x7b\x7c\xb7\x69\xda\xbc\x64\x6b\x30\x89\x95\x9b\x07\xb6\x0e\x6a\xa5\xe6\xcf\x97\x40\x1e\x83\x2c\xa1\x44\xeb\xf1\x69\x73\x20\xe0\x7c\xc8\x0e\x96\x0b\x73\xd7\x43\xf2\x0d\x6a\x60\xe1\x60\x3d\x67\xc9\xaf\xfd\xef\x37\x10\xdb\xf2\x22\x1c\xd1\xd9\x78\x34\x55\x71\x9e\x34\x2c\x3e\xa9\xbd\xcd\x1e\xb4\x01\xa1\x9d\xf0\xc3\x1a\x4a\x4d\xa8\xda\xf1\xee\x27\x82\x30\x14\x1e\x1b\xf5\x50\xa2\x2b\x74\x3d\xe1\xf4\xb6\x13\x41\x88\x56\xd9\xd3\x73\xe5\x4d\x45\x9d\x45\xd9\xb8\x79\x21\x82\xee\x35\xb0\xbc\x7e\x6b\x8f\x39\x6e\x3b\x88\x20\x74\xa2\xf2\x35\x9a\x1a\x9b\x97\xc1\x3d\x78\xea\xc2\x2b\x82\x10\x80\x56\x8f\x55\xee\xc4\x77\x8f\xf0\x6e\x4d\xe8\x47\x29\x8c\x08\x42\x85\xc4\x41\x32\x63\xff\x78\x97\xb4\x94\xa4\xd1\x98\xf8\xa1\x71\x60\x3b\x34\x96\x4a\x7b\x93\x37\x2f\x8b\xdb\x58\x37\x30\xf3\xe2\xcf\x94\x71\xee\x11\xa6\xf1\x98\x08\xe2\x54\x26\xb1\x5d\x42\x46\x62\xf1\x3f\x0d\x5a\x44\x10\x67\x89\xd5\x7b\xd8\xac\xee\xec\x84\xf0\x97\x96\x28\x45\xb2\x90\x3e\xdd\xa2\xf9\xeb\xf7\xda\xe9\x49\x12\x64\x44\x89\xdd\x3f\xdd\x85\x94\xb2\x39\xb1\x37\x77\x98\x31\xcb\xbd\x3a\xc2\xeb\x50\x66\xfb\xbd\x54\xbb\x16\x5e\x71\xf6\x23\x98\xb0\xc0\xdb\x0b\x6f\xf3\xe9\x37\x32\x93\x50\x41\xe8\xfa\xdb\xc3\xed\xf6\xfe\xcb\xc3\xf2\x2b\x35\xfb\x50\x1a\x26\xa1\x2b\xe5\x74\x31\xc6\xb1\x2a\xf1\x63\xf6\x4b\x52\x63\x13\xdc\x1a\xbd\x4c\xc0\xee\x47\xee\xc1\xda\xff\x98\x5e\x6a\x96\x1a\xef\x25\x7f\x95\x6b\xe2\xc8\xf6\x2d\x2f\x11\x70\x13\x11\x68\xe7\x06\xce\x6a\x59\xb8\x4a\x04\x22\x52\xd4\xae\x2f\xcf\xc7\xf5\x4b\x45\x50\x27\x7f\x44\x5b\xbe\x9c\xad\x51\x59\x33\x88\xa5\x82\xbc\x08\x3c\xdf\xfd\x38\x42\x31\x4c\xbf\x05\x12\x50\x4e\x8c\x66\xd7\xd6\x67\xd5\x86\xd3\x77\x0d\xd2\x24\x72\xc2\x46\x8f\xf0\xa1\xe1\xa3\xc7\xd6\x6e\x07\x52\x0b\xef\x07\x0b\x5a\xa3\xed\xd5\xbc\xe1\x86\x9c\xda\x16\x11\xa7\xe7\x11\x7f\xe7\x1f\xd3\x6f\xe4\x88\xae\x9f\xdd\x7d\xc1\xb6\xfc\xcb\x3b\x20\x87\xfe\x67\x01\x72\x9e\xf9\xe5\xde\xd7\x92\x2e\xba\xdd\x7d\x17\x5f\x04\x92\x61\x1a\x8d\xb0\x23\xcd\x9c\x71\x3e\xbd\x29\x3a\x56\x1a\x7c\x99\x61\xd2\xfc\xb9\xfa\x58\x2c\x2b\x8a\x00\x83\x94\x70\x0d\xb9\xaa\xbc\xc1\x99\x9e\x3d\x0c\x0c\x04\xba\x5b\x3d\x36\x0e\xf0\x47\x53\x06\xee\x05\xad\xea\xc7\x3a\xff\x0f\x3a\x80\xdf\xd2\xab\xea\x6f\x38\xca\x48\x0a\x5f\xe6\xe9\x96\xe3\x7d\xd5\x6d\x08\xeb\x0f\x75\x09\x37\x77\x1f\x31\xdc\x8a\x06\xd6\x68\xe9\xb5\x57\x1f\xb3\x1f\x6f\x94\xb1\x7c\x00\xef\xa9\x40\x64\x9c\xa5\x27\x65\xb4\xc8\x9c\xbe\x68\xf7\xea\x16\xd0\x8c\x1c\xe5\xba\xc3\x26\x0a\x7c\x3d\x48\xce\x90\x15\x22\x0c\xa3\x30\x09\xfa\xd4\xec\xa7\x7c\x32\x11\x46\x81\xc5\x0f\x5a\xe4\x16\x45\xba\x4b\x09\x5f\x37\xd0\xa4\x7a\x80\x79\x1e\xe4\xc7\x61\x52\xa3\x14\x61\xac\x92\xd8\x5c\xba\x70\x1c\xfe\x95\xa3\xce\x61\x56\x19\x11\x61\x8c\x92\x04\xba\x0e\xd4\x8c\x3f\x50\x65\xf3\xb0\x5d\x3f\x44\xfe\x7c\x49\xc4\xe9\xc9\x17\xd5\xf3\x4d\x55\x14\xd5\x0f\x32\x24\xee\xde\xf8\xfd\xfb\x6f\xd3\x8b\x4b\x32\x8c\x22\xcf\xf3\x20\x44\x95\x0d\xbc\x87\x95\x21\x64\x19\x0b\xf9\xa0\x1c\xb3\x6b\x6b\xb4\x74\xa8\xbf\x23\x1f\xe3\xce\x91\x85\x9a\xde\x7a\x5f\x22\x5d\x3b\xab\xc4\x87\x72\x45\x8e\xbd\xab\x2e\x7e\xe9\x53\x9a\xd9\x7c\xbe\x68\x52\x89\x90\x73\x9e\xf1\x1e\x73\x79\xac\x6a\xed\x55\xa7\x97\xe1\x5e\x22\xe4\x2a\x20\x1f\x9a\x86\xb6\xbe\x9b\x33\x4e\x3b\x7d\x22\x84\x30\xf0\x5d\x8e\xf5\xc8\x43\xce\x1f\x8d\x05\x58\xbd\xb7\x37\x27\xdd\x3c\xf4\x7b\x44\x08\x80\x24\x97\x7b\x9f\xbf\xe4\xc5\x52\x38\x7c\x9e\x73\x03\x45\x08\x52\x3b\x93\x4b\x2b\x81\xbe\xf6\xc8\x59\x11\xca\x08\x7d\xf3\xdb\x39\x53\x4e\x2f\x46\xaa\x98\xf8\xd7\x25\xbe\x7b\xd0\x7f\x37\xcb\xab\xd1\x19\x90\x67\x4e\x5a\x96\x5a\xe3\xe3\x46\xc1\x40\x45\x71\x83\x55\x2c\xbc\xbf\xc5\xa6\xc4\xfa\xf9\x83\xd0\x4d\xd3\xaf\x54\x28\xf8\xe0\xa8\x48\x45\xd9\xfe\x7c\xf1\x05\x04\xb2\x1b\xaf\x88\xaf\x91\x97\xf8\xe4\x11\x90\xfe\x90\x41\x6a\x0f\xdf\x54\x55\x23\xc1\xeb\x9a\x8a\x50\xa7\x8a\x42\xbe\x2e\x79\xb4\xaf\xc1\x55\x4f\x7b\x9b\x5e\xb0\x16\x82\xa4\x93\x7f\x0c\xdd\x06\x07\xbc\x5b\x56\x3f\x12\x21\x6a\xae\xfc\xae\xe3\x22\xae\xd9\x39\x11\x03\x5f\x96\xea\xed\xde\xa6\x23\x0c\x63\xc2\x32\xaa\x6f\xcf\x25\x8c\x1f\xbf\x01\x2b\x2d\xf7\x7f\xab\xe6\x65\x9a\x9d\x8a\xd0\x48\xeb\xfd\x7a\x57\x95\xd8\x56\x3b\xf8\x44\xf6\x48\x84\x46\x71\xba\x63\xf3\x6f\x5f\x44\x28\x89\x28\x88\x6d\xaf\xff\x19\xdb\x1b\x7a\xc3\xa7\x0f\x2c\x0a\x83\x40\x59\x09\x15\x9f\x4b\x88\x28\x94\x90\xe9\xbe\x56\x4d\xe8\x24\x59\x41\x2f\x0a\x2e\xa2\x28\xcc\xc8\xb9\xf3\xe0\xc3\x99\x55\xa9\xc7\x05\xde\x9f\x78\xbf\x88\x28\x62\x19\xc5\x73\x07\x52\x24\x6a\x5d\x13\xeb\x33\x7b\xaa\x61\x81\x89\x22\x26\x28\x51\x59\xfd\xb1\xda\xde\xae\xae\x6e\x37\x0e\x72\x69\x85\xc6\xfc\xb5\xc5\x28\xc1\x16\xe1\x65\x5e\x6a\x8a\xee\xf0\x7c\x5c\x14\xab\xf3\xab\x5b\x14\x1b\xe5\xf5\x7c\x89\x14\xb5\xb0\x34\x45\x49\x80\xb1\x5b\x01\xe9\xa4\x84\x4c\xbd\xa9\x6a\x0b\x7f\x9c\xde\xd4\x44\xc7\xde\xa1\xf5\xae\xdb\x22\xea\xfe\xce\x25\xd8\x5b\x1d\x76\x99\xab\xe5\xa5\x8e\xd5\x5b\x44\xc4\x02\xcb\x9b\x3c\x59\xc5\xaf\xc1\x54\x6e\xfa\x60\x59\xc4\x28\xe1\xb3\x56\xe6\x0e\x61\xe5\xa4\xf5\x7e\x92\xf4\x8b\x88\x69\x4b\x5e\xb9\x50\x9d\x9d\x9e\x3f\xe5\xd6\xe8\xc2\x5d\xe9\x54\x61\xc5\x8d\xc9\x4c\x42\x6c\x00\xba\x21\x3f\xbc\xb9\xb3\x88\x78\x96\x7a\xf4\xe0\x9f\xdd\x27\x96\x23\x8f\x48\xc4\x48\xd2\x04\x7d\xff\x76\x87\xd0\x54\xa5\x4d\x54\x46\xf4\x2e\xee\xc7\xb3\xc0\x2b\xcc\xe7\x94\x79\x2c\xaf\xe1\x91\xe0\xd6\x51\x04\x9a\xd7\x9b\xaa\x5e\xdd\x56\x70\xd1\x17\x98\x7d\x02\xc0\x50\x41\xc1\x96\xee\x0f\xa1\xff\x21\x20\x63\x2a\x29\x6e\x7c\x32\x29\x22\x15\x07\xde\x1d\xe2\x2a\x9f\x48\xeb\xf5\x03\x9c\xb6\x53\xb7\x41\x8e\x1b\x5f\x22\x52\x10\xd1\x8b\x85\x9a\x8c\x07\x2f\x08\x78\x22\xd2\x2c\x26\x3c\xbb\x43\xb6\x55\x67\xd2\xcb\x28\xdb\x3d\xbc\xaf\x8e\x63\x07\x49\x11\xe9\x14\xe8\x57\xba\x07\xb4\x3a\xb7\x2f\x58\xb6\xf9\x58\x05\x4c\x44\xa8\xd2\xd4\x12\xae\xa9\x6f\x3b\xa3\x6a\x8b\xc8\x04\x56\xd9\xd7\x22\x1e\x2d\x9f\xfb\xa7\xb0\x1d\xfa\x88\x1c\x13\xb5\x6f\x48\x60\xe8\xa1\xd0\x36\x81\xf3\x2b\xc2\xa8\x60\x2d\x22\xa3\x0c\xed\xaa\x64\xe5\x41\x15\x96\x65\x0d\x39\xb7\x08\x8c\xb2\xd8\x38\x0a\x59\xe6\xd8\x59\x9b\x77\x55\x9c\x47\x4a\xaf\x7e\x44\x12\x52\x5e\x6a\x95\x2f\x1f\xce\xad\x7f\x7c\x71\x84\x3a\xd0\xe3\x0d\xe0\xc9\xda\x5b\x4c\x3f\x9f\x26\x49\xd2\x3d\xd1\xc7\x87\xef\x5f\xe3\xd8\x7f\x36\x55\x51\x60\x53\x95\xdb\x0a\xf4\x9f\x5e\x27\x44\xc4\x99\x8a\x2c\x30\xe3\xdc\xbe\x54\x75\xde\xe0\x48\x95\xdd\x0f\x31\x21\xe1\x34\xf7\xb9\x46\xa7\xe3\x3a\xfb\x4e\x11\x24\x54\xdd\xbf\xc6\x37\x2b\x3b\x49\x89\xf2\xf2\xab\x18\x8b\x38\x61\x9e\x1b\x76\x76\xac\xfd\xf3\x00\xde\xf6\xcb\x58\x2c\x52\x08\x1d\x6c\x81\xa2\xb3\xc1\xae\x59\xc4\x90\x65\x24\x72\x08\xbe\x9b\x7a\x38\xcd\x0a\x9c\x22\x96\x21\xd0\xce\x7a\x70\x11\x76\xbd\x87\xa1\x37\x3d\x2c\xc4\xb1\x64\x31\xcd\x70\xda\x1f\x5c\x1d\x75\x52\x2a\x88\x55\x18\xf1\xee\xbd\xf9\x2b\x5a\xaf\x76\x5f\xfd\x5f\x75\xa6\x08\x1a\xf1\xef\x73\xae\x5e\xd7\x93\xc5\xe7\x13\x5e\x9c\x88\x35\x6a\x42\xc5\x3d\xbe\xe4\x05\x94\xed\x4b\x5d\x9d\x3e\x96\x32\xb2\xbf\xdb\xcf\x10\x31\x06\x31\x5d\x9b\x33\xd9\xa5\xc4\x3e\x99\x4c\xd7\x18\x23\x49\xad\x9a\xbf\xae\xfe\xd9\xff\x29\x09\x92\x64\x44\x06\xb5\xc9\xd8\xd5\xc7\xed\x48\x3c\xbc\x7f\x10\xc8\x33\x2b\x62\xd6\xc5\x88\xa5\xc2\xe2\x13\x05\x34\x11\x1b\xcd\xa8\xb9\x52\xd5\xcf\x50\xe6\xff\xc1\x9a\xb9\x2f\x4c\x02\x96\xd2\x32\xdd\x45\x92\xdb\x2b\xc4\xf2\x1e\xce\xcf\x2f\xed\x2c\xda\x48\x02\x26\xa2\xb8\xd7\x5a\x9c\xd3\x97\xba\xe3\x26\xb1\x36\xa6\xcd\xcb\xbe\xba\xc9\x8b\x71\x52\xe4\xc7\xe8\xc0\x96\xcd\xbb\x65\xfc\x70\x1a\x99\x9c\x8b\x24\x4c\x94\xf2\xe7\xaf\x1a\x5a\xb6\x9a\x95\x17\xad\x5b\xcf\xc0\x82\x22\x09\x25\x52\xb8\xe1\xf9\x34\x23\xbf\xb8\x85\x2d\x3d\x09\x15\xd7\xe9\x14\xc1\x43\xed\x86\x4d\x97\xb8\xf6\x65\x83\x24\x34\x26\xf2\x0c\x78\x38\x9e\x20\x7f\x2e\x37\x65\xb7\xf6\x5a\x50\xf9\x64\x33\x4f\x22\x69\x08\xdb\xac\xaf\xf1\x54\x54\xa4\xd9\x4c\x6d\xdc\x59\xa0\xb1\x58\xe2\x75\xdc\x5f\x91\x44\x1a\xe9\x09\xda\x38\x76\x87\xed\xf9\x92\x0e\x31\x0b\x1e\x93\x38\xb0\x91\xfa\xee\x05\xe4\xd9\x5f\x7a\xcc\x19\xe5\xa4\xba\x2a\x89\xde\x5b\x39\x35\xab\xd9\x7d\x8b\x79\x46\x60\x7a\x22\xbd\x5c\x9d\x3f\x28\x72\x76\xd0\x86\xc9\x0d\xec\xdf\x79\x9b\x2b\xf4\x7e\xa2\x16\x96\x16\xf8\xd3\xa9\xc8\xd3\x5e\x6d\x05\x75\x1a\x18\xb8\x51\x09\x4b\x28\xe6\xfc\xaf\x13\xd6\x77\x90\x97\x93\xa8\xf3\xa7\x2f\x51\x92\x98\x90\x80\x6f\x4e\x05\xf1\x7c\xe9\x7f\x36\x35\x59\xf5\x67\x70\xfc\x8c\xe9\x41\xf7\xc7\xe1\xec\x2c\x0c\x28\x7e\xea\xe9\x59\x12\x74\xbf\x4c\x25\x2c\xd3\xc2\xa2\x5d\xa1\x4b\x46\x6d\x51\xbf\x6f\xcf\x8b\x84\x29\x46\x53\x96\x96\xa7\x6d\xdf\xb5\x6b\x66\xb7\x9c\x19\x41\xc5\xd3\x13\xd4\x6d\x89\x75\x33\x29\xad\x26\x69\x0a\x9c\xf7\xb4\x80\x9d\xaa\xf3\xd3\xc5\x19\x52\x9d\x49\xc7\x37\xbc\x43\x0d\x45\x43\x8d\x3b\x57\x3d\xf1\x25\x9f\x24\x8b\x62\x0f\xb0\xb1\xe4\x73\x57\x9b\x9f\x9e\x8b\xc7\x09\x21\x90\xab\x13\x96\x5f\xe0\x88\x4f\xb4\x3a\x2e\xdf\x7c\xae\x33\xea\x1e\xfd\x17\xb6\x2f\xf5\x15\x94\xaf\x75\xd5\xa7\x47\x89\x48\x2d\xa8\xad\xcd\x8f\x68\x09\xf8\x8e\xf6\xdd\xe5\x33\xfd\xcf\x13\x2a\x8d\x9d\x81\xce\xa2\xb7\xf3\x74\x07\x4a\x84\x89\xc1\x43\x70\x3f\x6e\xa1\xa1\x76\x11\xaa\xf6\x6b\x75\xae\x27\x4b\x5f\x02\x41\x8a\x5e\x08\xde\xd1\xc9\x46\xf1\x46\x02\x32\xb2\xa2\xb6\x55\x8d\x8f\x03\xe0\xe1\x62\xb6\x2d\x15\x3a\x13\x15\x5b\x4d\xb8\xd5\xf9\x3d\x2f\xf2\xf3\xd1\x9f\x54\x25\x29\x91\xe3\xec\xee\xfe\x04\xe5\xb2\xaa\xb0\x48\x54\x66\x53\xc7\x22\x3f\xe6\x2d\xea\xc7\x3a\xff\xc4\x1b\x5b\x24\x98\x21\x81\xb5\xf3\x86\xd4\xd8\x0d\x69\xef\x7e\xf8\xf6\xdb\x82\xbb\x9e\xfb\x9c\x41\xa0\xae\x31\x15\xf8\x5c\x89\xbc\xd4\xd5\x8f\x87\xde\xb7\x5f\xb0\x20\xb2\xcc\x99\x2f\x55\x45\x7d\xa3\x5f\x34\xc6\x04\x0b\x18\xeb\x05\x75\x09\x64\x7e\x45\xe9\xd8\xf6\x7a\xc4\x46\xe8\x46\x21\xd1\x51\x8f\xf0\xbe\x6c\x9a\xd3\xc5\xcf\x92\x7c\x9f\x65\x9a\x58\x0f\xf8\x71\x5d\x8b\x85\x81\xe1\xc2\xbf\x38\x76\x47\x74\x3e\xa9\x7e\x25\x66\xa1\x62\x84\xd9\x39\x74\xe9\xde\x4e\xbd\xa0\x3e\x17\x33\x0b\xd1\x6e\x90\x10\xde\xe9\xb2\x5b\x39\xd7\x4e\xa6\xb2\x3f\x89\x89\xa8\xcf\xa7\xe1\x63\x0c\x1d\xee\x0e\x00\x71\x1c\xac\x9d\xcb\x9f\xcb\x4f\x91\x45\x91\x21\x71\xfb\x6d\xe3\x7b\x59\x0e\x22\xd6\x7f\x41\x14\xa7\xa4\x4a\x72\x8d\xd7\x36\xc5\x5a\xf4\xbf\x15\x2c\x4a\x2c\xa7\xfd\x48\x86\x70\x84\x16\x18\x71\x2e\x04\x8b\xb8\xeb\xf8\x3a\x5e\xc5\x63\xb5\x9a\xe9\xaa\x0e\x15\xa7\xd1\xbf\x16\xdf\x21\x16\x19\x4b\x44\xb8\x5b\xfd\x75\x69\x80\x2c\x58\xcc\x62\xaa\x39\xee\x7f\x54\x7f\xba\x37\xb6\x3f\xc4\x43\xcb\xdf\x74\xd4\x6c\x3b\x0b\xa1\xb8\xfa\xb8\xc5\x67\x50\x9f\x1a\x5b\xf9\x8f\xeb\x80\x6b\x57\xd4\xb8\x22\xec\xe3\xf2\xdc\x65\x49\x16\x53\x05\xd2\x02\x4c\x77\x58\x14\x8f\xd5\xd4\x89\x58\xb0\x44\x18\xee\xb6\xe2\xeb\xd5\xc3\xac\x75\x27\x58\xa2\x22\x42\x83\x3e\x77\xfb\xc2\xec\x18\x0b\x50\x79\x54\x6d\x55\x76\xf7\xf3\x1a\x0d\x96\x0d\xed\x8a\xd7\xe5\x32\x61\x59\x30\x16\x6b\x5a\x32\x88\xeb\xb5\x7f\x59\xf4\x7b\x13\x8c\x09\x4d\x90\x18\x8b\xde\xf3\xfd\x1c\x77\x30\x0d\x84\x02\x97\x77\x8d\x8b\xe2\xbf\xda\xec\x66\x57\x92\x45\xa0\xbc\x91\xe7\xb9\x70\x4e\xbc\xd3\x21\x3c\xb0\xc8\x15\x7d\x59\xa5\xfc\x59\xef\x50\x30\x1e\x59\x2e\xf9\x1b\x6d\xd7\xe3\xd5\x82\xc7\x29\x61\xbc\x3d\xe2\x61\xbb\x7e\x98\x4d\x63\x6e\x0c\x4d\x63\xa7\x5d\x7e\x7d\xb6\xcc\xaf\x6d\xd9\x2d\xcf\xfd\xab\x2b\x62\x29\x78\x9f\x5a\xfe\x51\x7d\x22\xe0\x20\x58\x37\x11\xba\xb7\x70\xf7\xb0\xf6\x9f\x85\xd8\xb6\x2d\xba\x8d\xa6\x3a\xb7\x43\x0f\x79\x7a\x21\x52\x09\x18\xb2\x57\xa7\xdf\xf4\xf7\x22\x0a\x26\x8d\x26\xd8\x10\x59\x8f\xad\xb4\xb6\xe1\xda\xc3\xa9\xef\xc3\xf6\x4c\x08\xf7\x01\x15\xdb\x5d\x90\x50\xa0\xfe\x42\x55\xa2\xd3\x68\x54\x40\x9e\x2c\x2f\x8a\xc5\xb1\xf0\xa0\x58\xda\x64\xf1\x39\xc7\x66\x6e\x41\x2d\x98\x0e\x42\x4f\xea\xf1\x72\xa7\x84\xe1\x77\xd9\xfc\x92\x8a\xa0\x60\x9a\xf1\x60\x6c\x69\xb3\x81\xba\x9c\x58\x58\x8d\x96\x6a\xcd\x99\xe6\x13\x22\xdf\x45\xab\x79\xbc\x30\x6b\xa1\x08\x71\xf0\xad\x54\x45\x05\xaf\xfe\xf7\x18\x93\x69\xab\x24\x79\x8d\xdd\xbb\x70\x35\xa2\x34\xbb\x31\x69\x90\x44\xf4\x9b\x8f\x5e\xd1\x8b\x98\x11\x3b\xec\xdb\x37\xa9\xb7\xf5\xfc\x0a\xa7\xd3\x07\x55\x72\x72\xf5\xb5\x3a\x0e\x67\xe0\x9c\x90\xe2\x6f\xa4\xdd\x39\xbe\xa1\x69\x18\x19\x8b\x75\x3f\xe6\x83\xb4\xf1\x7a\xb1\xaa\x34\xad\xb8\xa5\x21\x33\x24\xc2\x7e\x2a\xc0\xe7\xb4\xfd\x49\x51\x50\x04\x41\xb8\x18\xef\x5b\xe9\x0f\x46\xcc\x80\x5d\x44\xef\xbf\xae\xf6\xfb\xd5\xfd\xe3\xd3\xc3\x9f\x7f\xc5\x4f\xd7\x5e\xca\x42\xa4\x11\x64\xda\x21\xf2\x0e\xf2\x5c\xcf\x55\x85\x44\x1a\xa7\x56\xe1\xc9\xc1\xb5\x48\x17\x66\xaa\x2e\x2a\xd2\x44\x4a\xea\x35\xa9\xaa\x34\xf9\xf3\xb9\x46\x4b\x5f\x9e\xc4\xae\xfd\x50\xa4\x49\x4f\x5d\x11\x0b\x54\x9d\x4e\xa7\x94\x89\x44\xc7\xae\x0e\xef\xf2\xc5\xfd\xfe\xce\x61\x1f\x3c\xec\x5e\xa4\xac\xcb\x74\x9c\x90\x47\x35\x63\xa3\x88\x94\x21\x53\xce\xcc\xcc\xf6\xa2\xe7\x15\xcd\x7e\x76\xa5\x29\x4b\x10\x47\xcd\xe6\x1a\xf5\xa5\xd2\xbe\x48\xb3\x50\xf3\xa1\x7d\xa0\xed\x53\x98\x17\xd1\xbb\x51\x04\x6a\x40\xe2\xb6\x58\x24\xc6\x6c\x84\x89\x31\x73\xb3\xe0\xb1\xae\xfe\x85\xaa\xf5\x99\xcb\x27\x6b\x9f\xfb\x20\x8f\x03\xaa\x94\x9f\x8a\x73\x5b\x51\x51\xcf\xdf\x0a\x2e\x44\x28\xfd\xed\xaf\x8f\xc3\x64\xe5\x42\x07\xbd\xb0\xb6\xe5\x0b\xdf\xe0\x78\x1f\x4d\x39\xe8\x00\x9d\x67\x69\xeb\xd5\x94\x67\xdf\x2b\x05\x01\xf1\x07\x61\x50\x47\xff\x18\xaf\x2f\xa9\x48\x6c\x2f\x40\xbd\xa0\xf9\xa4\xc3\x90\x0a\x96\x59\xc8\x18\x89\x32\xa0\x65\x56\xf9\x2b\x11\xc6\x76\x8a\xfe\xf9\x6d\xfb\xfb\xef\x0f\xc3\x5f\xad\x73\x89\xb2\x11\xf4\x5c\xb7\x5e\xa4\x90\x08\x5a\xa7\xaf\x37\x37\x4f\x0f\xbb\xfd\xe1\x66\xb5\xde\x3f\x3c\xf9\x8f\x03\x03\xcb\x38\xfa\x31\xdc\x2d\x30\x01\x59\xc7\x10\xd0\x73\x5c\x87\x49\x65\xc8\x23\x12\x58\xbf\x7d\xb8\x5a\xdd\x6e\xf6\x5f\x37\xfd\x89\x64\xa4\x55\xdf\xc7\x2a\x8a\x71\xdc\x93\xca\x18\x3c\xc9\xe5\xba\x7d\xd9\xbd\x54\xa7\xd9\xef\x56\x31\x7a\xcd\x19\x1b\x90\x76\xb3\x71\x7a\xfb\x54\x82\xc4\x33\xea\x9d\x71\x3f\x37\x53\xf1\x9f\x48\xa5\x71\xc0\x03\xe7\xce\x33\x16\x03\x1a\xa6\xb7\xc2\x8c\x20\xc9\x16\x66\x3f\xfd\x56\x93\x30\xda\xa2\x37\xfb\xaf\xfb\x39\xd4\x62\xf9\x5b\x0d\xb7\xce\x55\xae\xed\x3a\x09\x77\x53\x23\x05\xed\xca\xad\xa7\x1e\xad\xdc\x91\x2c\x80\x68\x50\xb4\x2e\xa1\xb0\x92\x3f\x4f\xd0\xf7\x8a\x93\x4f\xbd\x36\x45\x16\xa0\x49\x7b\xb2\x89\x8f\x4d\xaf\x49\x31\xc0\xcf\x9e\x2c\xe4\x9a\x85\x23\x72\xbc\xc1\x9a\x18\xe9\xf2\x63\x55\xd7\xb3\x12\x68\x16\xaa\x28\xd6\x23\x6c\x23\x5e\xf8\x4c\x8a\x2c\x62\x40\x3f\x94\xd4\x81\x0f\xbb\xfd\xea\x89\xf5\x87\x52\x45\x0e\x38\x43\xbe\x6d\xc3\x44\x7f\x18\x12\xba\x94\xe6\xdf\x75\x3b\xc9\xf6\xb2\x18\x23\x7a\x93\x08\x1a\x98\xf7\x53\x3f\x4b\x02\x43\x9d\xae\xdd\x0f\x38\xd1\x5a\x30\x0e\xb6\x3e\x8b\x07\xa6\x3f\x29\x89\x55\xca\x87\xf9\xe9\x20\x05\x93\x55\x3a\x4b\x52\xa0\x16\x21\xa9\x4b\x57\xe7\x05\x07\xdf\x9f\x07\x1d\x59\x82\xb6\x4e\xf2\xf5\xf7\xed\xfd\xcf\x32\xb0\x8c\x05\xa1\xc5\x38\x40\xf9\xed\xad\xd9\x77\x8b\x78\xf9\x02\x3e\x03\xcd\x18\xb7\xee\xd7\x7d\x43\xec\xea\x83\x9c\x4f\x26\x86\x39\x9f\xa4\xd8\xd3\x26\xd9\x78\xdf\xcf\x18\xb7\x6a\x56\x6b\x17\xd1\x3d\xe5\xcf\x2f\x6d\x33\x56\x18\x5f\x4c\x35\xb2\x34\x09\xa9\x60\x6c\xab\x33\x5e\xea\x75\xa9\xad\x95\xa5\x99\x05\x33\x0e\x4a\x58\x77\x79\x39\x7d\x0b\xb2\x2c\x49\x84\xa5\x29\x4a\x28\x9f\x5c\x6d\x78\x36\x03\x33\x95\xd1\x14\xb2\xa1\xdf\x3f\xcf\xd5\xbc\x2f\x92\xf1\x48\x50\xc9\xfb\xe5\xdc\xbd\x32\xf3\xa5\x34\x13\x61\x4a\xbb\xb2\xf7\x67\x53\xaf\x23\x00\xe4\xf4\x9a\x45\x08\x56\x7d\xff\x19\x77\xd8\xcd\x3b\xf2\xe9\xf5\x57\x2b\x32\x46\xc5\x42\x59\x86\x11\x3f\xe4\xcd\xa1\x2a\x0f\xea\x5c\xbf\xe1\x58\xdb\x67\x72\x65\x90\xf6\x2e\xb6\x63\x78\xcb\x45\x04\xd3\x2f\x41\x99\xe4\x92\x7a\x2f\xb7\x0f\x5f\x0e\xde\xa4\xd8\xe5\x23\xd3\x1f\xdd\x0d\xa4\x94\xaa\xa8\x1a\x1c\xf3\xf5\x44\xa6\xb8\x4d\xd7\x9f\xf6\x9b\x71\x50\x95\x29\xc9\x5c\xcb\xa6\xef\xa5\x3c\x2f\x30\xce\xfc\x68\x15\x86\xae\x2e\xbd\xcf\x67\x1a\x74\x22\xd3\x09\xb7\xe2\x07\x58\xf6\x66\x9e\x0e\x6d\xf3\x33\xbb\x11\x91\x21\x53\xc2\x32\xa6\x5c\x78\x34\x3d\x6c\x54\xcc\x6d\x07\x60\x37\xa8\xdb\xf9\x63\x98\x11\x7f\x06\xf2\xfa\xba\xae\x4e\x97\x40\xc2\xcc\x18\x6d\xf5\x70\xc0\xe0\xbe\xea\xad\x73\xfa\xcb\xe6\x41\x02\x94\x29\x7e\x45\x28\xda\x97\x8f\x75\x95\x97\x73\x10\xc9\xec\x03\x52\x5a\x1b\xc4\xe6\x3a\x6f\xba\x7b\x7d\xae\x71\x44\xf4\x1a\x06\x86\x89\xa6\xdb\xf5\x70\x6e\xd5\x10\xe3\xf2\x50\x83\xf5\xe4\xc4\xa6\xdd\x96\xed\x23\xd4\x0d\xd6\xf7\xf8\x0c\x23\xbc\x1f\x8f\x02\x24\x6c\xc7\xb4\x90\xfc\xdf\xff\xf3\x8f\xfe\x5f\x7e\x60\x12\x51\xed\x70\xbd\xbf\x5b\xf7\x1f\x66\x96\xfc\x47\x0a\x03\xdf\xca\xa6\xf2\xbe\xfa\x82\xc7\x61\x12\x67\x5e\x91\xc8\xae\x95\x83\x9c\xc5\x70\xe9\x71\x88\xb4\xa6\xda\x6d\x8f\x9e\xe2\xaa\xd4\x8f\xd0\x34\x23\x5c\xae\xe0\x71\xc4\x1c\x7d\x89\xe2\x0b\x9f\xaa\xf5\x87\xd3\x98\xb8\x4b\x57\xab\xf5\xd7\xcd\xed\xc3\xd3\xfa\xeb\xaa\xef\x6d\xf2\xd8\x25\xd1\xf8\xae\x5e\xa6\xe2\x03\x82\xc7\x4a\xc4\x23\x05\xca\xbe\xa2\x32\x59\x91\x79\xac\x13\x8b\x8d\x06\x83\xd0\x34\x58\xb7\xa3\x0a\x15\x8f\xb5\x52\x81\xdf\xe1\x0d\xb9\xcf\xcc\x3e\x8e\x21\x55\x54\x2d\xc4\x7e\x12\x3e\xfa\x78\x9b\x27\x0a\x3d\xee\x8f\xd6\x57\x28\x1c\x9a\x63\xde\x86\xe3\x2c\x40\x42\x2f\x77\x33\x6c\x5f\x7d\xdc\x5d\x02\x23\x39\x4b\x02\x87\xc7\xab\x1a\x5c\xb5\xfd\x27\x53\x4d\x95\x90\xbc\xcc\xdb\x25\x2c\xc6\x62\x67\x9d\x33\x4c\xd5\x44\x00\xd6\xbe\x01\x97\x3d\x2e\x37\x3e\x55\x82\x18\x7d\x4d\x0b\x33\xb7\x3e\x3e\xcc\xaa\xfe\x7f\xf7\x7f\xaf\xaa\x62\xd4\x2e\x5b\x04\x93\xf1\x14\x0d\xf5\x34\x4b\xcf\x85\x5f\x57\x55\x91\x97\xcf\xa3\x5c\x8a\x67\x51\x4c\xef\x78\x0d\x0a\x27\x62\xd4\x0e\x86\x34\x7d\xfe\x19\xd3\x64\xdd\x46\x6d\xed\x64\x64\xae\x28\x78\xa6\x13\xfa\xdd\x87\xe3\x42\x3d\x75\x7a\x8b\x32\x9d\xb2\x64\xd0\x91\xde\xb6\x78\x9c\x3d\x91\xcc\x08\x42\x30\xf6\x61\xc3\x6c\x5b\x9e\x5e\x15\xe7\x21\x2d\xc4\x9e\x9b\xf0\x84\x34\x2b\xef\xab\xd6\xfd\x6b\x20\x8e\x76\x83\x13\x06\xbd\x5b\xb9\xa3\x80\xd9\x9c\x3e\xfa\x6d\x71\x5d\xe1\xda\x90\x38\x90\x7c\x96\x87\x13\xd6\x07\xac\xfa\xc9\xc5\x31\x26\x08\x61\x0b\xef\x8f\x30\x13\x8e\xec\x8e\x02\x85\x87\xf7\x9b\xfd\xd7\xf6\x17\xe0\x78\xc1\x45\x10\x11\x81\xe2\xf6\xdb\xfd\xa5\x27\x93\xe0\x90\x6a\x82\x53\x6c\xd7\x0f\xdf\x31\x7f\x82\xbc\x17\x6f\x13\x1c\xb8\xf5\xa6\x90\xe7\x8f\xf0\x12\xb9\x35\x89\x41\x47\x8b\x34\x07\x1d\x8e\x6c\x52\x48\x83\xb3\x6d\x47\x86\xcf\xb3\x0b\x30\x96\xd5\xd2\xad\x50\xeb\xaf\x07\xd4\x79\x7b\x08\xd3\x49\xe4\xcd\x55\x12\xd3\xfe\x2d\xbd\x02\xc6\xaa\x68\xb1\x56\x55\xfe\x89\xc5\x8b\xe0\x0a\x6c\x95\x05\xdf\xb1\x56\x79\x73\x51\x8e\xfa\xef\x78\x86\x40\xe3\x4a\x5a\x5c\x89\x8f\xb2\x9c\x8e\xec\xec\x6a\x35\x13\xb4\x81\x9e\x72\xf5\x6a\xed\x3a\xc8\x0b\xdf\xb7\x2f\x7f\x0e\x6f\xe0\x98\x60\xe6\x49\x5d\x8a\x84\x17\xc7\xa9\x11\x47\xb4\x42\x1f\x87\x67\xab\x93\xef\x8a\x17\x3b\x54\x55\xcf\x29\x10\xdc\x70\x2b\x3a\x74\xb5\xf9\x73\x75\xd7\xff\x51\x08\xcd\xfb\x7b\xee\x16\x40\xab\x22\x5d\xd5\x57\x1f\xdd\x6e\xaf\x5e\x2e\xf4\x8d\xed\x87\x45\x10\xaa\xd4\x15\x4f\xb7\x4d\xb7\x21\x3e\xe1\xf3\xd8\x4e\x48\x88\x40\x6b\x0a\xfa\xce\x65\xde\x36\x0f\x25\x6e\xda\x97\x35\x94\x57\xe7\x0f\x49\x5d\x20\x77\x15\x22\xe4\xda\xa8\x09\xf1\x3f\x4e\xfb\x63\x10\x25\xda\x2b\x38\x94\x30\x92\x21\x9e\xde\x24\x11\x2a\xe9\x93\xec\x53\x55\xce\x36\x59\x11\x1a\x30\x62\xc4\xe3\xe9\xcb\x85\x93\x2e\xbb\x88\x83\x14\x5d\x0f\xea\xf1\x8f\xc7\x6e\xea\x59\x69\xb6\xc5\xd9\x22\xe2\x2c\x8b\x8c\x17\x31\xdc\x12\x56\x39\x6f\x5e\xfa\x73\x61\xe8\x51\x99\x37\xa8\x5e\x60\x0f\xef\xfe\x50\xc2\x9d\x2c\x00\xb6\xf7\xf2\x63\x61\x67\x15\xa9\x4e\x95\x47\xbc\x9f\xeb\x8b\x42\x89\x48\x75\x46\xda\x00\x36\x14\x22\xe1\xa2\xbf\x67\x83\x2d\xba\x34\xc6\xbf\x39\x57\xc1\xfb\x02\x12\x44\x64\x86\x47\x66\xa6\x47\x68\xb1\xb5\xd3\x8b\xe4\xa1\xc5\x5a\x81\x53\x15\xf7\x3f\x8f\xb3\x28\xed\xb1\xca\x0d\xb6\x77\xf0\xbe\xcb\xff\xd3\x3f\x6e\x2e\xac\x34\x53\x3b\x15\x1e\xf4\x47\x8d\x96\xe8\x45\xa1\xdc\xa6\x75\xfc\xd4\xb7\x5d\x08\xc1\x02\x72\x87\x5b\xc3\xe9\xe4\xf0\xad\xa3\x62\xa3\x80\x98\x11\x8b\x70\xf7\x7d\xf5\xf8\xc9\x19\x20\x36\x04\xab\x79\xbc\x5d\xfd\xb5\x79\x3a\xec\xb7\x77\x9b\x87\x6f\xfb\xe1\x04\x86\x6a\x1f\xfd\xbe\xfb\x8b\x34\x6e\xf9\x1d\x16\xdd\x5e\x2c\x2d\xc9\xf1\xa1\xfc\xed\xb2\x6d\x7e\x11\xef\x0a\x80\x38\x4d\x07\x33\x91\x6b\xa7\xb9\xea\xaf\x4b\x0a\x8c\xdd\x0a\x4c\x99\xf3\xfe\x70\xdd\x6b\x40\x09\x21\x31\xa5\xbb\x62\x27\xa6\x37\xf3\xf4\x07\x4d\x42\x84\xc5\xc7\xaa\xc5\xb2\xcd\xa1\x38\x0c\x71\xca\xf4\x1a\x14\xc6\x54\x4d\xfd\x63\x7b\xbf\x39\xac\x57\x8f\xab\xf5\x76\xff\xd7\xe1\x71\xf3\x74\xb8\x5d\x79\xaf\x87\x6e\x09\xd1\xc9\x50\xc6\xf7\x29\xc2\x68\x9b\x13\x1a\x52\x6a\xd6\x1a\x7a\x43\xae\x71\x26\x56\x24\x84\x56\xd6\xe3\xf2\x25\xef\x3f\x62\x04\xb5\xcc\xab\x12\xd7\x58\xb6\xdb\xf2\x3b\xf6\xc7\x30\x00\x47\x73\x79\xdf\xae\x1f\x6e\xf2\xba\x69\x27\xe1\xbc\xc0\x34\xf1\x96\xa1\xfb\x1c\xeb\xe8\x8e\xba\x69\xb3\x1f\x87\x19\x46\x62\xd4\x4a\x9b\xba\xe1\xb8\x41\x26\xd0\xb4\x87\x1c\xc0\xd7\xff\xff\x06\x2e\x54\x18\x07\x57\xed\x41\x24\x8f\x05\xb4\xa6\xaa\x8f\x9f\xd8\x75\x0b\x61\x14\x03\x1b\xee\x1f\x4f\xeb\x17\xa8\x7b\xba\xa0\x10\xc6\x48\x22\xaf\xb7\xbd\x5b\x91\x55\x8a\x74\x81\x15\x04\x99\x5d\xdb\xf2\x52\xdd\x74\xd9\xf8\xbe\xba\x46\x68\x5f\xbe\xe7\xb3\xef\x80\x80\x27\x5e\x57\xb0\x9b\xc9\x7f\x54\xc5\xb9\x0f\xbd\x20\x90\x89\x60\xbe\xf4\xea\x32\x95\xaf\xd0\xbc\xb8\x15\xfd\x7f\xe1\xf3\x23\x20\xec\xfe\x8f\x34\x72\x40\xd7\xd0\xe6\xca\x69\x87\xf9\xc3\x5c\x0f\x8c\x90\x4d\xfb\xf2\x84\x0a\xf3\xb7\x3e\x80\x80\xd0\x48\xc7\x12\x1b\xd5\xbf\x6e\xaa\x7a\xe6\x1f\x26\x20\x4a\x05\x29\x94\xdb\x89\x77\x75\x96\x9f\xa0\x42\x21\x12\x60\xc0\x77\x4f\xc8\x4a\xf1\xbd\x57\xa2\x12\x10\x27\x31\x49\x8d\x3f\x9e\xff\xf3\x9f\x31\x2e\x6a\xfa\x65\x31\x08\x52\x37\x7e\x7b\x6f\x7b\x29\x21\x01\xb1\x42\x2a\x74\xde\x6e\x77\xbf\xaf\x0b\x68\x9a\x5c\xf5\x87\x34\x24\xfd\x97\x1e\x21\x2f\xbf\xb5\x6a\x80\x5e\x43\x12\x28\xef\xa1\x61\x03\xbe\x07\x33\xf3\xf5\x16\xc0\x42\xdb\xfe\xf6\xd8\xcb\x51\x09\x04\x18\x5a\x00\x84\xdd\xbb\x6d\xaf\x63\x8e\x1e\x87\x34\x64\x28\x2e\xea\x08\x53\x01\xc6\xd9\xc3\x4b\xd1\x16\x18\x87\x7e\xe1\xed\xfa\xfa\xb3\x84\x01\x78\x9a\x89\x11\xf4\xf0\x3f\xe8\x22\x94\xd9\x03\xe0\x46\x91\x70\x55\x17\x5d\x2f\x61\x88\x86\x13\x0a\x6d\x0d\x3a\xac\xd9\xf9\xed\x5c\x26\x48\x80\xc0\xc4\x38\xff\xad\x8f\xa2\x02\x3d\xd6\x5e\x13\x00\x2a\xc6\x64\xf4\x52\x7f\xcf\x4b\x9c\xc2\x49\x16\xa2\x5d\x00\xcd\x48\x87\xe7\x71\xf5\x6d\xb7\xb9\xee\xcf\x85\x41\xe6\x82\xf3\xbb\xbc\xfc\x02\x4d\xb2\x52\x6a\x0e\xb9\x01\x30\x21\x01\x72\xaf\xf2\xa2\x80\x97\xf5\xa8\x67\x00\x52\xc8\x24\x9d\x04\x6e\xdd\xef\xff\xec\xc6\x4b\xcc\xa4\xdb\xf3\xb7\xaa\xb2\xe1\xdb\x77\xc4\xd7\xa7\xb9\x0e\x98\x00\x15\x45\x8c\xae\xd7\x79\x83\xef\xa1\x28\xf2\x85\xe6\xc6\xb0\x24\x81\x4a\x14\x33\xbe\xd3\xe8\x58\xbd\x23\x01\x5c\x01\x4a\x25\x99\x5b\x00\xa8\xb3\x68\xc5\x46\xdd\x41\x0d\xa8\xfc\x82\xb6\x6b\xab\x13\xc5\x2c\xae\xdd\xec\x87\xe8\xcc\xd3\x10\x36\x6f\x55\xf1\x36\x12\xc0\xec\x41\x6c\x80\x3c\x26\x6c\xa0\xdf\xd4\xa0\xc5\x49\xd4\x04\x28\x03\xea\xc2\xd9\x9a\xdb\x1a\xf3\x62\x58\x38\x64\x90\x59\x2e\x7f\x77\x87\xb4\x85\x93\x2c\xa7\x76\xb3\x92\x8c\x7f\x1d\x64\xa0\xac\xa0\xe1\x69\x14\xaf\xf5\xeb\x8e\x0c\x90\x53\xf3\x72\xdd\x28\xdb\xfa\xf9\x49\x82\x24\xc3\xb0\xf7\xbf\xdc\x1e\xe1\x19\x17\x40\xf7\x32\x8c\xac\x76\x24\xe9\x7b\xb4\x43\x9e\x2b\x43\xcd\x82\xcc\xf1\x34\x27\x20\x2f\x19\x1a\xa3\x7b\xc0\xcb\xfa\x05\xff\x7d\xc6\xf1\x83\x90\x91\xb2\x56\x7d\xd6\x3a\xf3\x2f\x84\xbe\xb6\x20\x23\x05\x04\x42\xb3\x8b\xc5\x75\x0d\xcf\x55\xf9\xe5\x52\xaa\x77\xcc\x79\x93\x91\x52\x81\xf7\x99\x83\xf7\x31\x10\x61\x12\x18\xcb\x98\x45\x89\x45\xa3\x53\x11\x74\x41\xf8\xbc\x9b\xea\x01\xf9\x72\x76\x01\x6b\xb7\xf9\x77\xab\xd9\x5c\x9b\x6a\x7a\x7f\x12\x2e\xa9\x4f\xf9\xbd\xaf\xf7\xc8\x44\x66\x3e\x6a\xfe\x8e\xdd\x6e\xe6\x0f\xb0\x24\x92\xba\xf7\x2f\x0c\x67\x77\x9a\xb1\x50\x47\x23\x91\x03\xab\x35\x5b\xd5\xb6\xc0\x32\x59\x40\x24\xeb\x66\x21\x41\x6c\x28\x2a\xba\xa9\xea\x47\x04\x35\x05\xa0\xca\x54\x20\x15\xc7\x34\x21\x36\xa7\xca\xa7\x42\xa6\x4e\xfe\x8f\xbe\xce\x16\x2d\xc7\x9e\x06\x42\x66\x29\x0b\x7a\x6c\x6e\x49\xbd\x1a\x84\xe3\x12\x44\x5a\x66\x2a\x96\xf4\x62\x56\xbe\x00\xea\xc1\xe2\x92\xa7\x91\x88\x7a\xe1\x2a\x52\x0e\xa9\xaa\x62\x38\x2a\x88\x4c\x27\xcf\x1f\x4e\x6f\xf9\xbe\x37\xb2\xec\xcf\xce\x35\x50\xeb\xb9\xc0\x37\x2c\x0e\xb1\x87\x58\xf7\xe7\x30\x19\xb5\xd5\x1e\xeb\xaa\x45\xd5\xee\x5f\x70\x0d\x4d\xdb\x07\x6e\x12\x22\x19\x8c\x8c\x1e\x6e\xf2\xb2\x3f\x24\x83\x98\xde\x25\x8d\xa7\xd6\x27\x5d\xf3\x9a\xd4\xdc\x88\x5d\x48\x19\x5b\xb4\xdd\xb7\xf5\xfa\x61\x7b\x4f\xa1\xe4\xb8\x07\x28\x15\xd3\x72\x40\xb9\x7e\xc5\xe2\x93\x7d\x42\x9a\x50\x51\x60\xb6\xb9\xdf\x1d\x9e\x1e\x1e\x7c\xbc\x2e\x0d\xda\x76\xdb\xc4\x72\xc8\x1e\x53\x01\x8f\xb9\x57\x46\xdd\xda\x9a\x81\x07\xd7\xab\x90\xf7\x32\xe5\xf4\x51\x2b\x2e\x30\x9d\x66\x2a\x34\x11\x61\xa3\x35\x2a\xf8\x18\xb5\x78\x55\x04\x2a\xf6\x14\x8c\x6e\x71\x9a\x6d\x12\x2a\xc2\x38\xf5\x9c\x27\x5a\x35\x3f\x26\xb2\xed\x42\xc5\x91\xa2\xf7\xfa\x1e\x7f\x4c\xa0\x58\xd3\xd3\xc4\x3c\x21\xb5\x98\x2e\xa4\x6c\xda\x8d\xad\x36\x3e\xd9\x67\xe3\x97\x31\x95\x24\x91\xd7\xb0\x1e\xa0\xa6\xae\x7b\xb1\x2d\xbb\x28\xf4\xd2\xae\x5f\xa8\x84\x19\x2a\x70\x5b\x23\x69\xdc\x57\x9e\x40\xf5\x13\x14\x08\x41\x5b\xc8\xc9\x33\x62\xbd\xfe\x9e\x50\x4c\x59\xc5\x70\x78\x83\x8b\x8f\xbb\x21\x29\xa4\xd1\xe0\x53\xe1\x40\x2c\x93\xeb\x49\x55\x46\x65\xdb\x33\x15\xa6\x07\x33\x79\xef\x99\xf3\x05\xc6\xfa\xed\x42\x65\x01\x82\xfb\xd5\x24\x33\x3f\xfd\x75\x59\x8c\xdc\xed\x1c\x7b\x7c\x6f\x97\xfa\x4e\x2a\x4b\x13\x6e\x26\x81\xcf\x24\x39\x9e\x87\x3e\x2a\x4b\xad\xaf\x2f\xbd\x9d\x8e\xed\x38\xfd\x95\x3c\x8b\x69\x4e\xa9\xaa\x26\xa1\x33\xff\x67\x6d\x68\x33\x75\x85\x9a\xcf\x90\x09\x8b\xb1\xb5\x12\x2c\x8e\x6c\xc9\xa6\x84\x23\x8e\xe3\xa3\xe9\xaf\x81\x28\xc8\xa2\x49\xec\x61\xf7\x91\x11\x5e\x64\x2c\x61\x2d\x14\xa4\x01\x41\xfa\x24\x34\x38\x22\x37\x2a\x19\x45\x51\x36\x6e\xac\x53\xf1\xb6\x5b\xce\x5c\x7f\xf3\xe7\xd7\x2b\xb5\x75\xcf\x1b\xb8\x1d\xfb\x8a\xba\x03\x6d\xd5\xa2\x6b\xaa\x77\x13\x74\xb2\x0d\x2a\x15\x64\x14\x7a\x59\xef\x02\x2b\xdf\x78\xbd\xb9\x7f\xb8\xeb\x07\x24\x19\x51\x7b\x0d\xe4\xfd\x95\x2a\x65\x23\xe2\xdc\xb6\x1f\x76\x27\x50\x68\x05\x58\xfa\xf7\x54\x47\x92\x0c\xd1\x1c\x88\xbe\x4b\xe7\x96\x2f\x5b\x0b\x0c\x2c\x64\x47\x9d\xeb\x4b\x15\xcf\xe9\x73\xd6\x26\x25\xfe\x20\x49\x3b\xdc\x6d\xee\xae\x36\x4f\x87\x3f\x56\xb7\xfe\x4b\x4d\x10\xd3\x8f\xd9\x6c\xfe\x52\xd5\x4c\x5b\x52\xe8\x20\x91\x9a\xf7\x14\x99\x57\x42\xc6\xf7\x06\x3c\x54\x1c\x5f\x5c\x00\x75\xc0\x04\xe5\x06\x9b\xfd\xcd\xf7\xdf\xfc\xdf\x32\x16\xf6\x02\xfb\xcd\xbc\x24\x32\xfb\xbc\x0c\xd3\xc4\xeb\xa2\x3f\x98\x4d\xfb\xf2\x50\xf6\xd2\x43\x42\x07\x5a\x2b\x57\x0a\xf3\x25\x58\xab\x0e\xb9\x4c\x46\xd4\x81\xd1\xd4\xb6\x70\x62\x85\x4e\xae\xdb\x7a\x71\x2e\x40\x0e\xc7\x11\xea\xf4\x6e\xea\x28\x12\x84\x1c\x28\xa0\x69\x09\xbe\x3e\xb2\x2c\x12\x3a\x8a\xc1\x2b\xb1\x5c\x9d\x4b\x5d\xe0\xe6\xfd\x94\xd7\xd6\x45\xfc\xc1\x6c\x8e\xdd\x7c\x18\x17\xbf\xfc\xc7\x34\xa7\xfd\xdc\x3a\xe1\x1c\xee\x3e\x85\x59\xeb\x58\x03\xed\x50\xbb\xfc\x78\x2a\x70\x8a\x04\xd3\x49\x20\xa9\x14\x2b\xcf\x1f\x5d\xde\x71\xaa\xc7\x76\x8c\x3f\xe7\xfe\xf8\x33\x44\x09\xba\xea\xf8\xaf\xe0\x07\xfe\x13\x3c\xa0\x36\xd7\x11\xde\x77\x27\x74\x44\x97\xfe\x82\x84\x71\x62\x0c\x50\xab\x97\x6d\xd9\x60\x4d\xdd\xba\x2a\xbf\x54\x71\xf0\x1f\xd1\x29\x05\x2f\xdd\xfd\xa5\x5b\x7b\x30\x3e\xe2\xd0\x0c\x23\xeb\xfa\xb8\x5a\x7f\xee\xf3\x20\x74\x9a\x5a\xb9\x4f\x0b\xcb\x7d\x84\x1f\x97\xba\x34\xc3\x9e\xaf\xd3\x34\x66\xd1\x48\xb6\x4c\x5b\x91\x99\x03\x8c\x43\x4c\x9d\x45\x86\x64\x87\xa0\x68\xb1\xbe\x41\x68\xcf\x35\x3e\xa2\x05\x2c\x5c\x40\x92\x74\x96\x58\x82\x90\xb2\xfc\x86\x7d\xa5\xbd\x33\xb5\xd0\x3c\x32\x21\xf7\xc2\x43\x9b\x3f\x27\xf7\x8b\xb3\x28\x75\x50\x3c\xbb\x1e\x2e\x91\x6e\x86\xaf\x11\x86\xd1\x2a\x4a\xb8\xfc\xa2\x5c\xe2\xbd\x7c\x3a\xab\xc7\x51\x9e\x16\x26\x25\xb2\xd6\x5b\x8e\x3f\x6e\x2b\xf5\xfa\xed\xb4\xe0\x82\x20\x34\x04\x06\x9c\x23\x93\xef\x07\x5f\xac\xd4\x1a\xc2\x84\xcc\x27\xaf\x37\x7f\x7e\xdd\x7e\xf9\xfa\x19\x51\xe2\x17\x13\x11\x64\x98\xda\xce\x6a\x8b\xa5\xee\xae\x69\x19\x45\xaa\x65\x90\xa2\x5b\xc1\x1d\x5e\x73\xdc\xee\xd1\x52\x28\x4c\xa7\x7e\x76\x5f\xa0\x19\xc9\x94\x0a\x2d\xc1\x44\x94\xb4\x58\x4c\xdb\x24\x42\xd5\x12\x33\x6b\x68\x66\x81\x75\x3b\xca\xfb\x3f\x99\x77\x2a\xd4\xd4\xab\xeb\xd6\x95\x73\x01\xf5\xf5\xfe\x0f\x5a\xde\x1c\xcc\xd8\x7f\x9f\x4a\x44\xd8\x83\x65\xc9\xf3\xc7\x67\xa9\x5a\x87\x51\xc4\x96\xdb\xb9\xc3\xd7\xe8\x94\x53\x2d\xcc\x12\x99\x47\x46\x20\xb3\x49\xa8\x21\xd1\xc6\x7b\x52\xd3\x80\x39\x04\x72\xfa\x74\x91\x59\x21\x5a\x47\x90\x56\x63\x2c\x4e\x3f\x84\x87\xb6\x9e\x42\x47\xad\xed\x82\xab\xdf\x52\x39\xce\x8d\x33\x21\x90\xb8\xba\xdf\x99\xa0\xb8\xef\x02\xbb\x65\x57\x6b\x81\x41\x92\x90\x60\xda\x0e\x3d\x1e\x72\x0f\xcf\x93\x8c\x07\xc3\x40\x1a\x2b\x90\xa4\x72\xec\x21\x06\x18\x49\x45\x10\xb8\xaa\xc4\xa7\x81\xd3\x83\x11\x06\x54\xd0\x39\x38\xfb\xa7\xaa\xfa\x6d\x59\x14\xde\x8d\x8f\x03\x43\x35\x3d\x1b\x5b\xff\xfe\xeb\x3e\x05\xc6\xc6\x39\x9c\x52\x17\xa6\xfd\x5a\x39\x19\xe0\xe9\x0d\xc3\x24\x48\x29\x69\x3f\x90\xa0\x46\xf5\x96\x6b\xac\x5d\x31\xf8\xa7\xf3\x1f\x13\xd7\x62\xb1\x30\x39\x2b\xb3\x35\x32\x59\xff\xe4\x77\xb0\x2c\xa4\x1a\x6a\xef\x17\xe1\x6f\x48\x16\x47\x84\x13\x50\xd0\xbc\x8c\x6c\x99\xfd\x51\x11\x5b\x70\x31\x61\xc6\x6e\x2a\x62\x20\x15\x5d\x36\xb5\x7c\x71\x99\x8a\xe8\x9d\x1b\x38\x3b\xf3\x13\x2a\x49\x05\xfe\x3b\xd4\xf9\xa5\x93\xa9\xc0\xcc\x64\x94\x8c\xdf\xd4\xf8\x51\x8f\x14\x1f\x90\x3c\xab\x6c\x95\xa0\xe8\xde\x47\xbc\x41\x9c\xdb\x4b\x08\xe4\x90\xd2\xaf\x39\xd5\x55\x51\x95\xcf\x96\xde\x40\x45\x93\xd9\x75\x70\x13\x19\x97\xaf\x1f\x2c\x63\xf8\xf0\x56\x29\x84\x92\x44\x38\xfd\x12\x3f\xfd\x8c\x88\xad\x2c\xb8\xa5\x5e\x27\xb7\xfc\xe9\x93\x59\x2b\x12\x3b\xc9\x77\xa7\xaa\x6c\xfa\x4a\x13\x8a\xd4\x3a\xf0\x37\x14\x31\xcd\x93\x24\x84\xd0\x8a\x8c\x51\x60\xb3\xf7\x5b\x1b\x42\x02\x94\x20\x6c\xca\xd6\x9b\x18\xf9\x23\xa9\x65\x3e\x4b\x68\x72\xb5\x7f\xa9\xb1\x79\x19\xb0\x30\x08\xc2\x4a\xdc\x8d\x31\xa0\x4d\xef\xf7\x78\x09\xb0\x42\x10\x9a\x96\xe7\xc7\x6f\x4f\xeb\xaf\xab\xdd\x66\x37\x51\xfb\x42\xd0\x22\x74\xc4\xf3\xee\x27\xef\xab\x55\xa3\xf2\xdc\x5a\x16\xcd\x1e\xa2\x44\x49\x8b\x15\x41\x26\x1c\xc8\x6d\xab\x0f\xfe\x4c\x2a\xb3\xd2\x55\x56\x1f\x73\x11\x14\xf2\xbf\xda\x12\x50\x07\x01\x45\x5e\x8d\xed\x87\xf8\xbf\x0a\x25\x3d\xab\xbf\x28\xaa\x1f\xb3\x8b\x44\x40\x44\xdf\x55\x28\xbb\x90\xba\x99\x8f\xd0\x2c\xb6\x9c\x25\x7d\x56\x56\x81\xe5\x9f\xed\x27\x7d\x5c\x13\x04\x11\x61\xe5\x08\x2c\x4d\xb7\xf9\xc1\x2c\x0a\x4b\x99\x20\x4e\xa9\xe0\x08\x4a\x79\xf1\x6b\x7f\x04\x18\x69\xda\xf5\x5a\x20\xe3\x92\x50\xf3\x92\xcf\xb0\xc3\x26\x8c\x34\xd9\x7f\x3e\x41\x91\x9f\xc7\x86\x8a\xc2\x84\x29\xa3\x26\x51\xfb\x92\x37\x7f\x54\x2d\xd6\x8d\xd5\x0f\xf3\xc7\x23\x2d\x09\x29\x65\x21\x50\x53\x39\xe8\xe9\xea\x6f\x98\xc6\x24\x1a\x3b\x77\x92\x40\x9d\x3f\x51\x2a\x90\x94\x61\xa8\x3e\xfb\x54\x5d\x4a\xee\xcf\xee\x53\xaa\x91\xa6\xe5\xd7\xaa\x24\x25\xed\xe1\x92\xb2\x58\x53\x2d\xec\xd0\x6d\x7f\xb6\x93\x34\x59\x65\x47\xa1\x84\xc9\x84\xa1\x46\xd5\xcd\x9f\xfb\xd9\x3d\xc9\x54\x48\x8c\x7a\x1b\xce\x5f\x43\x8b\x0f\xe6\xc2\x83\x67\x7a\x49\x99\xb6\x2a\xf9\xc4\x97\x39\xb4\x1f\xa7\x0b\x74\xba\xc9\x30\xa5\xa4\xc3\x3f\x99\xd9\x0d\x5b\x9e\x12\x99\xc9\x68\x31\xac\x0e\x50\x3c\x57\x75\xde\x1e\x67\xab\x90\xe1\x49\x42\x1c\x0c\x47\x45\x5c\x96\xa9\x9d\x9d\x95\x67\x82\x6a\x17\x6f\x83\x9e\xe3\x4c\x01\xc7\x70\x54\x54\xb5\x59\x15\x50\x1f\xd7\xf4\x80\xf3\x93\x93\x99\x73\x43\x44\x12\x28\xa7\x05\x61\xb7\x83\x85\xdc\xc8\x08\x16\x6a\x57\xfd\xb9\x1f\x6a\x2f\xfe\x19\x08\x9e\x91\x1d\xf2\xb7\x9b\x87\x51\x7f\xc8\x08\x11\x51\x25\xec\x6a\xbf\xe6\x41\x10\x54\x65\x12\x79\x5e\x86\xf1\x9c\x55\x79\xae\xcb\xd5\x59\xe7\xad\xe7\xdf\xf5\x03\x30\x89\xa2\x31\x07\x7f\xfe\xf2\xc8\x30\xa4\x9e\xd7\xa9\x6a\x57\x5a\x9f\x3d\x53\xd9\xc8\x24\x26\xb5\xa4\xbe\x14\x4c\xb9\xaf\x77\xa8\xf3\x61\xed\x0c\x89\x65\x24\x37\x3e\x06\xbc\x41\x6c\xae\x3e\x08\xde\x32\xff\x4a\x95\x52\x45\xa7\xa8\xaa\xd7\xf3\x69\x9f\xab\x57\x6c\xbf\x56\x85\x9e\x97\xcd\x8d\x12\x2c\xb0\x0a\x4c\x1a\xdf\xf7\x2f\xf8\xbd\xaa\x5f\x55\x8d\x5e\xcb\xc5\x28\x93\xa5\xd2\x6b\xe3\x58\x9d\xe3\xdf\x46\x3a\x1d\xa3\x82\xbf\xd1\xa1\xa4\x25\x72\x5f\x83\xc6\x95\x31\xa8\x16\x2a\x2d\x7e\x6c\x6c\xe8\xfd\xec\x57\x0d\xcf\xac\x1d\xa4\x39\x85\xd1\x68\x8d\xdc\xfa\x09\x4c\xd5\x85\x9f\xc6\x0c\x06\x15\xd0\xc3\x20\xcd\xfa\x07\x6f\xda\x38\x17\x0d\x31\x26\x02\x86\x17\xef\x06\xf1\xf3\xbb\x47\x90\x3f\x97\x94\x13\xfd\x6f\xc3\xfd\x69\xc7\x96\xbe\x0b\x82\x10\x94\x9d\x1f\xc7\x49\x1d\x12\x82\x10\xed\x82\x60\x3b\xf5\x4e\xeb\x94\xf6\x97\xc5\x97\x1e\x82\x08\x2c\x67\xfd\x08\xff\xea\x5e\xcd\x8f\x3b\xa8\x9f\xfd\x24\x86\x20\x8e\x42\xea\x80\x28\x28\xd4\x25\x47\x12\x82\x38\x8b\xd0\x15\x97\x08\x78\x37\x8e\xed\x20\x88\xb5\xa1\x2d\xdb\xc6\x98\x9e\xbc\x37\x07\xaf\x4f\xaf\x27\x49\x99\xe4\x23\x4f\xdb\x0b\xdf\xd9\x70\xa9\x13\x02\x41\x22\x52\x11\x0e\xe2\xe6\x0b\x5d\x4c\x08\x12\x64\xa9\x9b\xe6\xdf\x5f\xaa\xc7\x1c\x2e\x2b\xde\x7f\xf7\xbf\xd3\x8b\x66\x91\xd4\xbd\x9b\xe4\xa3\x55\x01\x19\xc9\x48\x43\xc0\x52\x4d\xd2\x4a\xaa\xa8\x4a\x7a\x23\x1f\xab\xd3\xaa\xd4\x57\x55\xdb\x7e\x22\x4e\x08\x01\xe3\x40\xb4\x7b\xeb\x51\xf4\xdb\xec\xa0\xe4\x94\x93\x37\x71\xe2\x5a\x17\xee\x40\xca\x02\x5b\xfe\xe8\xbe\xde\xc9\xef\x8c\x76\x44\x08\xb2\x30\x20\x2c\xdb\x6d\xf5\xec\xee\xd2\x5d\xa5\xc9\x23\xee\x33\x82\xdd\x67\xff\xf5\x27\xcc\x84\x88\x26\xa4\x2f\xc7\x53\x1c\x13\x3b\x20\xe0\xcc\x12\x4a\x6c\xe7\x6b\x7d\x6e\xda\xea\x38\xc3\x74\x40\xc0\x95\xf0\x0b\xd1\xba\x7a\xc3\x9a\x5a\x73\x97\x5a\x55\x10\x70\x6d\xb4\x03\xd8\xdf\x20\x3e\x42\x0d\xc7\x4f\xad\x0e\x17\xdf\x20\x21\x2d\x21\xe9\xdc\xa0\xbe\x00\x94\x43\x20\x8d\x20\x8f\xd6\x1e\x01\xf2\x04\x3f\x1e\xab\xaa\x58\xf0\x33\x83\x40\xe9\x94\xd4\xd6\x0f\x43\xe9\xb9\x1b\x3b\x55\x65\xf8\x64\xea\x28\xa3\xa4\x03\x39\x96\xe7\x63\x33\x3b\xb3\x8e\x03\x43\x7e\x42\x5d\xe8\xd5\x1e\x4c\x6f\xb0\x0e\x81\x16\x86\xb6\x9d\x03\x58\x04\xc1\xd5\xc7\xc4\x5e\xd2\x8d\xc2\x98\x13\x1a\xe0\xae\x92\x79\x91\x97\xaf\xfe\xd3\x26\xd0\x04\x6e\xa0\xb6\xd6\xfc\xf9\x2e\x01\x28\x20\x0c\x94\x15\x6c\xb4\xb2\x49\x13\x4a\xa6\x1f\x81\x5c\x45\x1e\x68\x8b\x2b\x6a\x76\x5d\xee\xa7\x10\x86\x42\xa0\x6b\xcc\xbb\x45\x7a\x80\x74\x43\x18\x85\x92\xfa\xe8\xab\xab\xad\x25\x7e\xea\xc5\xc2\x06\x84\x11\xd3\x24\x36\xd9\xe6\x47\xfc\x0e\x79\xfb\xcd\xb2\xb7\xa6\xd7\x14\x65\x80\xb1\x07\xb3\x89\x03\x85\x67\xd7\xd8\x90\xbc\x6b\x5e\x95\x0f\x6f\x58\x9b\xa2\xfa\x71\xe8\xb2\xbe\x42\xef\x5f\x6a\xaf\x39\x06\x61\xac\x20\x1b\xfb\xc3\x3b\x95\x47\x7f\xd4\xfd\xd8\x1f\x90\xb7\x13\x18\x34\x84\x49\x88\x56\x9f\xff\x04\x75\x0b\x65\xff\x91\x44\xc5\xd4\xd9\x69\x7a\xcf\x38\xa7\xd7\xdc\x0f\x30\x40\x70\xe2\xed\xfa\x41\x0e\x86\x2e\x10\xb2\x34\x4d\x2c\x2d\xb7\xdb\x4b\xe7\x6f\x4d\xc8\xb8\x95\x51\x74\x8e\x1a\xb7\x08\x6f\xbf\xf2\x71\x9e\x3d\xdb\x34\x4c\x68\x06\x63\xfb\xf2\x84\x6d\x3d\x14\x10\x20\xcc\x84\x6d\xac\xd9\x45\xdc\xa1\x5f\xdb\xea\xd8\x1f\xc7\xcc\xb3\xaa\x6c\xa8\xb2\x9d\xce\xe1\x90\xc7\xdc\xc3\x5f\xef\xaa\xf2\x15\xfd\x3b\x16\x72\x2e\x29\x36\xdf\x41\xb7\x12\xbe\x5b\x23\x10\x7f\x4c\x05\x84\x90\xd8\x3f\xad\xee\x77\x37\x9b\xa7\xc5\x98\x1c\x42\x6e\xb2\x14\x06\xab\xd5\x1f\x5e\xc0\x74\x76\x83\x04\x8b\xad\x84\x06\x90\xea\x67\xbf\x5d\x86\x02\x35\x5d\x9b\xa9\x11\xff\xd3\x43\xdf\x9a\x6f\x65\x9b\x17\x4b\x4c\x21\x08\x25\x0b\x03\xcb\x4a\x42\xe8\x9f\x9b\x84\x14\xfa\x56\xd2\xf7\x7e\xfb\x0c\x55\x6c\x39\x5e\x57\xd0\xae\x61\xb8\xa5\x4a\x2b\xe2\x23\x5b\x3c\xda\xf4\x6e\x29\x13\x52\x73\x49\x9f\x8f\xa7\x9b\x1a\x97\x1c\x6a\xba\x41\x11\x69\x5c\x1f\xf2\x66\xab\x2f\x15\x76\xdc\x28\xcd\x03\x92\xe2\xdc\xec\xd6\x57\xd7\xf8\x46\x55\x82\x26\x7f\xf6\x57\xa1\x05\xa7\x76\x4b\x97\x0f\x57\xde\x86\xf1\x12\x06\x01\x21\x26\x19\x15\x9f\xee\x3e\x86\x42\x04\x84\xc8\x13\x6d\xd5\xa4\x3c\xc8\xcc\x1d\x30\x69\x60\x3b\xbb\xfb\xaf\x9b\xa7\xc3\xdd\xf6\xfe\xb0\x7e\xb8\xdf\x3f\x6d\xaf\x0e\x8f\x4f\xdb\x3f\x7a\x90\x23\x44\x41\x34\x50\x64\x1c\x73\xfa\xb6\xdf\xa7\xa2\x00\x43\x1c\x5a\x8c\x77\x44\x26\x9b\x0a\x76\xbb\x81\x61\x6a\xd9\xad\xdb\xfb\xed\x7e\xbb\xba\x3d\xec\x56\x8f\xb7\x5e\xbc\x11\xa2\x28\x8d\xc0\xda\xc7\xe2\xdb\xba\x3a\xd7\x3e\x63\xeb\x8e\x58\xa8\x42\x3b\x0e\x01\xff\x3b\x0c\x07\x80\xbb\xff\x37\xff\xef\x68\xa0\xe4\x4c\xfe\xe9\x4f\xc5\xad\x46\xb2\xcd\x90\xef\xce\xc5\xa1\xff\x12\xc9\x3c\xc8\xfa\x7a\xf5\x70\xa1\x2d\x05\x51\xcc\x12\x12\x06\xdb\x9d\xb0\x54\x13\x25\x7f\x88\xe2\x0c\x23\x47\xd0\x1e\x62\xf7\xfe\xb9\x44\x31\x0f\xc3\x60\xe2\x43\x30\x82\xec\xf4\x83\x94\x9c\x00\xdc\xbb\x78\x94\x9e\xf5\xc2\x7e\x3f\x3b\x3d\xda\x6a\x42\x17\xdb\x69\x2c\xdb\x91\x97\x0e\x44\x89\xb6\xc1\x09\x4d\xaa\xc9\x45\x27\xc8\x29\xe8\x2b\x1d\x28\x8e\x40\xfb\x25\xd1\x9e\xfc\x6b\x17\xb1\x48\x50\x61\xc8\x82\xf9\x2c\x4c\x86\xee\xcd\xf8\x55\x8b\x18\x0f\xd4\x3c\xaa\xa2\xe6\x65\x7f\x1a\x2e\x29\x05\xdc\xe7\x6d\xe1\x3b\x56\x9f\x00\xd3\x20\x62\x2a\xf3\x72\x6b\xd7\x58\x56\xc7\xbc\xa4\x54\x6e\x8c\xba\xe0\x7e\xa8\x61\x19\x7a\x9d\x6f\x92\x72\xda\xec\xbf\xda\xdd\x7c\xb1\x66\x04\x51\x16\x22\x89\xc3\xe7\xcd\xe2\x14\xcd\x22\xed\x91\x9b\xf7\x95\x46\xba\xff\x7e\x26\xf8\x21\x22\x25\x7c\x7f\x5f\x61\xbc\xcb\xcb\x71\x73\x6a\xf6\x7d\x4a\x53\xb1\x57\x63\x81\x2d\x12\xb4\x44\xfb\x98\xf7\x67\x1d\x11\x88\x78\x8c\x59\xda\x83\xe2\xda\x09\x78\xfd\x1f\xd3\x91\x89\xc5\x3f\x3e\xd6\x55\x65\x6c\x0e\x41\x12\x1f\xd3\x9f\xc6\x85\x0c\x59\x7f\x25\x0f\xe7\x76\xd7\xd6\x08\xc7\x59\xe5\x00\x22\x2e\x39\xad\x0a\x27\xe2\xb4\x8f\x83\xe3\x48\x64\x9c\x6e\x37\x6d\x79\x21\xc3\xe1\x01\x43\x10\x10\x69\xca\x6a\x97\x51\xb3\xaa\xf8\x24\xff\x83\x08\x42\xe5\x8d\xd9\xf7\x56\xab\x9c\xe8\x6a\xa8\xc9\x91\xe9\x6c\x55\xc1\x16\xb7\x91\x48\x32\xed\xd5\x39\xec\x6d\xff\x0e\xb5\xf3\xde\xed\xd2\x8f\xd9\x60\xb4\x76\x97\x36\x59\xb6\x5a\x4c\x57\x1f\xfb\x1e\xdd\x3b\xbd\x2a\xcd\x14\x69\xc7\xdd\xe4\x45\x61\xc5\x8b\x7f\x1a\x0f\x46\x1a\x53\x35\xf2\x94\xe9\x4b\x36\xfe\xb0\xe1\x24\x15\x79\x18\x71\x39\xed\xc6\xf7\x8b\xb7\x19\x33\x24\xd5\x38\xd7\x39\xff\x01\x0e\x86\x1c\x05\x3f\xb5\x81\x85\x08\x8d\xa4\x96\x16\xbd\x32\x8d\xc7\xfa\xde\x54\xce\xbb\x63\xfa\x2d\x26\x4b\x48\xa7\xc9\x7e\xcb\x5d\x25\xa9\x10\xb9\xdc\x58\xf5\x1f\xe1\x22\xb2\x22\xe5\xff\x3e\x63\xd3\x3e\xa1\xc6\x19\x83\x0b\x22\xa3\x42\x8a\x7f\xca\xf3\x91\x66\xce\x13\x76\x71\xf9\x7c\x90\xeb\x78\xf7\x86\x08\x3f\x69\x68\x40\x1c\x44\x91\x76\x65\x61\xda\xb5\x7f\x9b\x1d\x4e\x75\x26\x6c\x75\x09\x6f\xaa\xda\x9b\x6f\xe0\x61\x11\x42\x00\x71\x00\xd2\x9a\x99\xfb\xe2\xe0\xd5\xb9\x2e\xa7\xb9\x79\x1c\xc8\x8c\x42\xd1\x17\x68\x36\x65\x75\x7e\x7e\x21\xda\x63\x5f\x18\x70\x18\xb4\x81\x95\x77\xc9\x06\xbd\x24\x61\xb9\x53\x87\x80\xc8\x07\x1d\xf7\x31\xec\xc0\x8f\xc0\x04\x02\xaf\xa0\x55\x98\xaf\x1f\xb2\xce\xb5\x73\xaa\xbd\x64\xb0\x40\x1c\x87\x19\xf1\xd8\x4b\xfc\xf1\x58\x57\xc7\xea\x92\xee\xfd\x37\xb5\x32\xfd\xf9\x22\xdb\x05\xbf\xc7\x1f\x76\x0d\x9f\xaa\x5e\xf9\x51\x20\xbd\xde\x68\xb7\xd6\xe8\xd9\x45\x25\x31\xf3\x6c\x4f\xab\x75\x32\x82\x43\x5d\x5e\x94\x5b\xce\x63\x16\x2a\x63\x6b\x3e\xf9\xf3\x33\xd6\xbb\x97\x73\xab\xab\x1f\xe5\xec\xdc\x2c\x52\x84\x87\xf3\x54\xcb\x07\x63\xfa\xed\x2e\x4e\xe3\x98\xf2\x30\x4f\x21\xb4\x0a\xb5\x9b\xb7\x05\x6c\xe4\x24\x5c\x8c\xd3\xd4\x7a\xda\x98\xaa\x36\x98\x8f\xe5\x76\x21\x4e\x33\x5b\x4c\x75\xdd\xcf\x3b\x78\x27\x3d\x75\xa8\x09\xf9\xd5\xf3\x25\x20\x4e\xb9\xa2\x3d\xdc\xbd\xbb\x24\x66\xfc\xbf\x7a\x06\x3f\xd3\xc9\x9f\x5d\x2f\x00\xf2\xa1\x71\x34\xe3\xe3\x40\x9c\x4a\x6b\x6a\xea\x60\x22\xf7\x88\xfa\x17\xae\xdc\x10\x67\x49\x22\xb5\xeb\x4c\x9e\x72\x2c\xbd\x9a\x2e\xc4\x3c\x08\x3d\x76\x66\x3f\x62\x13\x8d\x37\xc6\x58\x84\x71\x98\xf5\x1e\x5a\x96\xe7\xbc\x03\x83\x77\xa8\x7b\xc1\x3e\x88\x41\x27\x14\x2d\xbe\x75\xaf\xd4\xaf\xda\x80\x10\x03\x1a\x16\x8c\x45\x9d\xa8\x9a\x39\x15\xe3\x71\x45\x48\x88\x65\x97\x04\xd1\xcc\xd0\xed\x4b\x0d\x3e\x3f\x8c\x35\x28\xd2\x05\x6f\x72\x8d\x57\xe8\xe9\xfa\x87\xbb\xd5\x9f\x7e\x04\xca\x2c\xf5\x96\x14\x8f\xf4\x0b\xc7\xee\x80\xcb\x0b\x6e\x8c\x2a\xa0\x64\x42\x79\x81\x60\x88\xd1\x44\xc4\xd0\x39\x55\x0d\xe1\x0f\x3d\x5a\xf5\x1f\x0b\xd0\x31\x88\x0d\xb3\x0c\xe4\xd5\x59\xb5\xd4\xf6\xdb\x59\xfe\xd1\x20\x52\x66\x07\x26\x41\x62\xcd\xeb\x9e\x50\x5f\x15\x67\x9b\x6a\x44\xfe\x60\xa8\x53\xda\xb8\x0e\xd8\xb4\xf9\x11\x5a\x74\x78\xde\x5f\x4d\xb5\xc9\x8d\x4e\xa2\x50\x24\x4e\xb8\xef\x0e\xde\xff\xc0\x3a\x1f\x55\x50\xfc\x6b\x9f\xc4\x41\xef\xe3\x4b\x5b\x37\x75\x56\x66\xb5\x90\x84\xc5\x99\x8c\xc6\x66\x1d\x5d\xb8\x30\x80\x38\x21\x61\x09\x0a\xe5\x49\x77\x1f\xf3\xbd\x29\x61\x32\x0c\xd1\xeb\xec\x5b\xe7\x03\x37\xdf\x28\x7e\x9a\x8d\x4e\x23\x9b\x8a\xff\x78\xb1\xea\x99\xd7\xbd\x78\x2c\x24\x9c\x09\x63\x5d\x10\x7e\x5c\x55\xd5\x6b\x5e\x3e\x1b\xf5\xd9\xb6\xfe\xc9\x7d\xe1\x99\xa1\xb0\xff\xf1\x69\x43\x26\x53\x8f\x9b\xa7\xf5\xe6\x7e\xbf\xfa\xb2\xf1\x52\xe1\x90\x88\x88\x11\x77\xbe\x39\xcb\x46\xd5\xb9\xfc\x54\xf8\xcd\x8f\xcf\x24\x89\x1f\x35\x4e\x44\x71\xa2\x9f\x3f\xc9\xfb\x17\x2f\xce\x2d\x4b\x09\x48\xcc\x4c\xff\xc8\x2e\x50\xac\x90\x80\xe2\x84\x75\xc5\xf7\x53\x55\xb7\x7b\x28\x5f\x49\x08\x74\xa9\xea\x97\xc8\x44\x07\xd2\x97\x5f\xde\x7c\x7a\x9f\xc8\x34\xa2\xf5\x34\x2f\xf3\x76\x1c\x62\xcd\xee\x92\x14\x9c\x92\x6d\x12\xea\x3b\x84\x87\x71\x51\x24\x91\x5a\xc7\xd2\xc1\x84\x28\x16\x59\xc3\x69\x80\x58\x40\xa2\x24\x4b\x06\x6d\xbd\x36\x1f\x12\x55\x1f\x1c\xfb\x81\x2a\x08\x7b\x6a\xc5\xd6\x0c\x71\xe6\x64\x6f\x4a\x94\xe6\x94\x6e\x81\xd6\x77\x48\xd2\x8d\x63\x10\xda\xe4\xba\x15\x46\x44\x5f\x27\xe2\xc0\x75\x65\x61\x5a\x5f\x47\x36\xb1\x6e\x9c\x4e\xa2\xd0\x49\x21\x3f\x58\x90\xec\x8f\x49\xe7\x6b\xfa\x7c\x75\x22\x02\x39\xe2\xc6\x74\x89\x0b\x89\xe1\x93\xda\x21\x9c\x4e\x73\xe6\xd3\x25\x98\x0b\x12\x04\xc8\x5c\x15\x6f\x5f\xb9\xb5\xe1\xc2\xd1\x7b\xf6\xc5\x88\x16\x8c\x40\xde\x74\x79\xf3\x3a\x02\x07\x41\x62\xd2\x20\xf4\xa6\x49\xb6\x84\xba\xfc\x2c\x8d\x0a\x48\x8e\x76\x4f\x4d\x5a\xf7\x69\x16\x06\x8a\xbb\xd6\xda\x6d\x5e\xbe\xee\xab\xc7\xaa\x69\x67\x89\x20\x0b\x63\x4b\xb5\xb2\x7b\xce\xb6\x34\xc5\x99\x92\xe5\x4f\x22\xbc\xe9\xd5\xb3\x30\x13\x56\x40\xba\xb9\xad\x9a\xbc\x7c\xbe\x9a\x49\x25\x03\x8b\x98\x22\xd4\x9c\x2d\xa4\xde\xe5\x05\x36\x6d\xe5\xb0\x1d\xdc\x8f\x81\x88\x14\x8b\x7c\x74\xb9\x2b\xab\x1f\xa6\x80\x57\x2f\x0c\x49\x0b\xfb\xe7\x82\x22\xc0\x22\x23\x49\xfe\xf5\x84\x75\x5e\xe9\xa8\xcf\x41\x3d\x2e\x02\x58\x9c\x84\x69\x38\x80\xf5\x09\xa3\x3b\xe6\x8c\x01\x8b\xb5\xa5\x25\x5c\x8d\xc4\x94\xba\xbf\x66\xda\x65\xb6\x14\xca\xfa\x18\xdd\x6d\x6a\x6e\x54\xe2\x00\xf7\xe7\xd2\xd4\xd5\x7f\xf0\xa0\x26\xcd\x52\x60\x09\x48\xe9\x8a\x0d\xb7\xbb\x4d\xd3\x05\xb2\x3f\x33\x86\xea\x3e\xa0\x63\xe6\x79\xc0\xdd\x34\x22\xc5\x2e\x7f\x10\x83\x91\xa1\xd1\xa1\xbe\x58\x45\x18\xe3\x21\x01\x59\x7e\x60\xee\x22\x9f\x11\x1e\xbc\x3b\x1c\xd3\xe2\xb7\xae\xca\x12\x9d\x42\xbd\x3f\x04\x21\x55\x0f\x9e\xf3\xb7\xee\x3b\x9d\x64\xc7\x72\x2b\xda\x7f\x44\x32\x66\xbc\xf4\x53\xad\xf7\x1f\x27\xbc\xb0\x4a\x00\x96\x2a\x4e\xdd\xac\xbc\xe9\xe3\x9e\x29\xc7\x08\x18\x67\xd6\x4e\xc8\xb7\xa7\x7e\x1e\xfa\x30\xae\x2d\xc2\x6c\xa2\x46\x8e\xe4\xdf\xd9\x5d\x43\xb4\x9c\xca\x32\x11\x58\x3b\x28\x07\xb8\x1b\x4d\x43\x91\x65\xce\xac\xbe\xd4\x14\x8c\x56\xf5\xd5\xc7\x94\x20\x37\x3b\x95\x0c\x08\xa9\xbf\x7e\x7a\xd8\xad\xb6\x4f\x87\xdd\xd7\xed\xe3\x81\x04\xbb\xfc\x4f\x12\x46\x52\xf2\xbb\x7e\xc1\x23\xf9\xbf\xac\x7b\x6e\x3f\x30\x08\x43\x35\xbc\x1a\x7b\x02\xf7\xdd\x55\xda\x2a\x0c\xcc\x26\x04\x44\x01\x3a\x37\x73\x07\xdb\x9e\xca\x0c\x8d\x37\x06\x26\x33\x6d\x38\xf5\x1d\xeb\x57\xec\x9b\x54\x13\xc9\x6c\x60\x52\x30\x6d\xf9\x1a\xd0\xbe\x58\xe2\xc5\xc1\x47\xc5\x4c\x05\x11\x15\x57\x6f\x37\xfb\x3f\xfb\xbf\xc5\x20\x2d\x7d\xf0\x07\xd4\x7a\x42\x1f\x01\xa6\x38\x57\xae\xed\x70\x43\xf5\xde\x71\x2d\xc7\xdf\x60\x9d\x64\xa1\x98\x8a\xa4\x11\x13\xda\x25\xcb\x7e\x54\xaa\x69\x3e\xe9\xba\x3a\x4d\x2f\x59\x2b\xa4\x52\x33\x58\xc6\xc3\xf0\x76\x6b\x1d\xd9\x42\x49\x75\x29\xe2\x32\x7b\x74\x3e\xf2\x64\xda\x58\x97\x34\xf2\x1f\x6e\x56\xf5\x2c\xa4\x61\x18\x31\x22\xd4\xa9\x02\xa1\xf6\x64\x42\x6b\x90\xe5\x47\x48\x9d\x0d\x2c\x53\xf7\x22\x53\x4f\xfa\xe7\x6b\x7e\x1a\x84\x89\x95\x63\xb7\x10\xe1\x02\xf5\xbc\xdd\x93\x06\x21\x64\x6e\xc5\xa0\xad\xcb\x76\x6b\x1c\xc8\xaf\xdf\x71\xd2\x20\x44\x72\x47\xb0\x80\x6c\xda\x8a\x77\xf9\xf3\x94\xe7\x3b\x4f\x68\xd3\x30\xb6\xbd\x01\x18\x3c\x48\x26\x0c\xaf\x6e\x84\xa1\xf2\xf5\xb7\x24\x1a\xd7\x1f\xd3\x30\xd5\xb4\xcf\x74\xfb\xd1\x6b\x5e\xb8\xdb\x31\xdb\x19\x67\x4e\x54\x90\x86\x99\x85\xb8\x12\x23\xec\x5b\x3d\x2b\x07\xa4\xa1\x88\xa8\x16\xb6\x7e\xda\xac\xf6\x9b\xc3\x1f\x9b\xa7\xdd\xf6\xe1\xfe\xf0\xf4\x70\xbb\xe9\xbf\xd7\x28\xe6\xe5\xdd\xad\x91\xea\x05\xf9\x15\xd2\x28\x08\x1d\x23\x4c\xcf\xbc\xd9\x21\x8d\xc2\x0c\x65\xcf\xe5\xeb\x16\xc4\x31\x9f\xef\xb1\x6a\x9a\xbc\xa7\xe4\x43\x1a\x71\x65\x1d\x33\xf2\x23\x8e\xdb\x5e\xb3\xfb\x18\x6b\xb4\x2c\x2f\xaa\xa1\xe7\xe5\x48\x65\x07\xd2\x24\x45\x42\x09\x2e\xab\xec\x9c\x47\xcc\x4f\x48\x93\xcc\x9a\x28\x3f\x63\xfb\x7b\x5e\x3e\x53\xf0\xd3\xf4\x27\x52\x49\x3c\xf6\xa2\xa4\xce\xdf\x4f\x33\xb0\x34\x31\xb1\x4a\x47\x06\x80\xb7\x13\x85\x34\xff\x06\xa4\x2c\xb5\xaa\x37\x76\xeb\xef\xd6\xcd\x89\xe6\xd2\xcf\xa3\xec\x94\x65\x29\xe3\xbe\xd8\xf9\x6c\x15\xef\xbe\xc0\xbc\x86\x99\xb2\x8c\xd3\xab\xd9\xc2\x2b\x56\x94\xf6\x7f\x72\x3a\x48\xbd\xc0\x65\x6f\x55\x3a\xd3\xab\x86\x94\xa9\x90\x2a\x41\xce\x77\xc2\xc1\xc0\xaf\x51\x15\x50\xbb\x54\xd9\xdf\xd3\x34\x13\xa4\x0c\xf0\xb4\xd9\x6d\x9e\xfe\xd8\x4c\x6c\xa7\x20\xcd\xb2\x98\x8d\xa9\xd0\x9f\xbc\xa8\x99\x54\x14\x13\x60\x0d\x0b\x0c\x42\x48\x33\x25\x68\x41\x73\xa8\xfd\xb9\xf5\x31\xa4\x3c\xb2\x5e\xc5\x54\x66\xbf\x3a\x7f\x8c\x3a\x99\x29\xe7\x82\x0a\xd7\xb4\x00\xf5\x7a\x1e\x4b\xe0\x8a\x54\x44\x21\x05\x48\x46\x2e\x78\x96\x43\x0a\x0a\xfc\xa3\xb8\xc6\x02\x9f\x41\x57\xd7\xb8\x69\xd4\x19\x0b\x20\xa3\xfe\x8f\xc5\xc2\xf5\x18\xee\x06\xa9\x64\x56\xcd\x61\x53\x7c\x4c\x8d\x34\x47\xcb\x8d\x4c\xe3\xd0\xb5\x04\x77\xd8\x92\x6e\xc1\x64\xdd\x90\x18\x07\xb6\xa5\x2e\x2f\x14\x33\x20\x95\x26\xb5\xea\x5d\x7e\xc3\xa6\x2c\x73\xb9\x01\x9d\x2a\xb0\x6e\x87\x7e\x3e\xf4\xef\x83\xee\xb6\x81\xee\xc5\xea\x75\xbb\x8a\x62\x04\x43\x82\x54\x67\x9a\xca\x15\xa3\x7c\x25\xc5\x84\xd3\x1d\xfa\xa3\x6a\x71\xa5\xdf\xb0\x6e\xf3\x06\x27\x6e\x9e\xd3\x4b\xc5\x94\x39\xed\xe9\xd7\x6f\x0d\xd6\xd7\xd8\x42\x5e\x2c\x83\x17\x21\x45\xe7\xf9\xe7\xbb\x32\xd7\xab\xd3\xe9\xbe\xd2\x5e\x15\xb1\xbf\x30\xc3\xa4\x4c\x47\xca\x71\x78\x9d\x3f\xe7\x2d\x14\xab\xba\xd7\x95\xed\xd7\x84\x2c\xca\x90\xf8\xf1\x77\xab\x3f\x0f\x8f\xdf\xae\x6e\xb7\xeb\xc3\xcd\xb7\xfb\xeb\xed\xfd\x97\xe9\x54\xce\x22\x13\x51\x0d\xc7\x8a\x80\xde\xbd\x4e\xd8\x62\xdd\xe1\xcc\xf2\x0b\xf2\xa6\x25\xe4\xd9\x75\xa5\xce\xd6\x60\x63\x2e\xd6\x31\x3c\xe8\x2c\x66\x9a\xa8\xb1\xff\x75\xb5\xda\xb5\x50\xea\x2e\xae\xfb\x5b\x1a\x3a\x90\xc5\xa9\x61\xe3\x52\x31\x99\xfe\xcd\xde\x8b\x2c\x89\x15\x41\xe9\x9a\xfc\xfd\x0e\x5a\xf5\x62\xf5\x42\xb7\xe5\x14\x02\x95\x25\xca\x7a\xc8\xf5\x78\xe0\x6f\x4f\xdb\xf9\x99\x0c\x50\x99\x4b\x9e\x3f\xee\xf1\xc7\xb6\x34\xf5\x54\xc9\x12\x32\x16\x66\x18\x0e\x55\xff\xab\xaa\xef\x81\x64\x69\x68\x59\xed\x73\xa9\xfe\x5e\xe5\xe3\x33\x9c\xe4\x34\xb9\x1f\x67\xbc\x59\x1a\x45\x54\x2a\xef\x2d\xef\x49\xac\x60\xdc\x94\xc9\xd2\x48\x10\xc8\xdb\xcf\xe0\xeb\xa7\xc7\xdd\xec\xa2\x53\x21\x48\xdb\xa9\x3c\x1f\x1f\xba\xe9\xfa\x52\x57\x3f\xfc\x44\xca\xb2\xc8\x3a\xa7\x7a\xfb\x9d\x71\xa9\xf4\x32\xe2\xf1\x1f\x62\x11\x99\x6b\x6a\x74\xe1\x13\xce\xb0\xa0\x7e\x9c\x89\x52\x2b\xb7\xdc\x6d\x1a\x3f\xd1\x17\x82\x8c\x03\x27\xb6\xf8\xd5\xf5\xa3\xbf\x34\x11\x67\xa4\x95\xeb\x98\x6e\xd4\xe7\x69\xd6\x55\xf5\x9a\xcf\xbf\x47\x08\x43\xc0\xcf\xff\xc2\xba\x7a\xbf\xce\x4b\xa8\xfb\x73\x48\x15\x38\x52\xd7\xbe\xae\x4e\x2f\x43\x75\x28\x83\xcc\x36\x1a\xf3\xe6\xc9\xad\xdc\xa8\x1f\x21\xff\x64\xfd\xce\x40\x2a\xae\x9d\x60\xc6\xf7\xaa\xd4\x9f\xed\x3e\x99\x4c\x15\xb3\x65\xc8\xba\xb5\xb0\xb8\xc9\x9c\x96\x2a\x54\x43\x83\xc7\x16\x1b\x9d\x4c\x6b\x7f\x69\x12\xad\x9a\xfe\x8f\x6e\x3e\xff\x91\x6b\xac\x56\xb3\x5f\xac\x20\x49\xad\x7a\x88\x7e\xc2\x37\xfc\x84\x90\x02\x99\x56\x9a\x7b\x19\x63\xcb\xc0\x58\x59\x05\x91\xf6\xc3\x3e\x6a\x37\x0e\xa5\x21\x6a\xa5\xe5\xaf\x87\x53\xfe\x3a\x64\x26\xb5\xba\x41\x0b\x11\xd3\x85\xf7\x2a\x8d\xa6\x04\xb9\xc4\x1f\x8b\x50\x66\x3e\xfa\xff\x7e\xe3\xe1\x41\x02\xd4\xe6\xff\x97\xae\xce\xf2\x73\xfd\x27\x3f\x1a\x51\x79\xf5\x3f\x2b\xbf\x5e\xbd\x4e\xb2\x6d\x1e\x86\x29\xc1\x93\xcc\xb9\xd4\xd6\xf0\x45\xe5\x27\x8f\xdc\x05\x1e\x1a\x4e\x84\xbe\xf2\x7c\x74\xe0\x9e\xc6\xbd\xa6\x93\xfd\x90\xc7\x31\xd0\x9a\xb7\x7f\x71\x7e\x22\xfe\x04\x09\x77\xe0\x21\xca\x30\xdf\xa0\xc5\xcb\x38\x92\x27\x3a\xa1\x64\xbd\xb7\xa1\x7b\x30\xa6\x3f\x01\x6a\x42\xb6\xdd\xfd\x75\x7d\x3b\x8e\x8c\x39\x0b\x12\x82\xc9\xdb\xee\x68\xaf\x0c\x36\xc6\xbd\x71\x26\x52\x0f\xcd\xfa\xd2\xad\xd1\xf5\xc7\x4d\x3e\x96\x02\x19\xee\x54\x1a\x67\xcc\x59\xd3\xb7\xd5\x1e\xd5\x8b\xd5\x9d\xfb\x1b\xb2\xcc\xfe\x04\x09\x26\x4e\x30\x10\xa8\xe9\xda\x45\x8d\xd6\x9d\xc1\x4f\x58\x9e\x66\x36\x01\x6c\xf2\xf2\xb9\xc0\xed\xf5\x9f\x77\xff\x1c\x9e\x44\x6a\x24\xe5\xa6\x5f\x37\xfb\xf5\xfa\x7f\xb9\x05\xf0\x2c\x8c\xb5\x7d\xed\xbc\x4e\x8b\x3f\x6d\x96\x25\x24\x4b\x99\x37\xdb\xb2\x39\xd7\x97\xcb\x0f\xcf\x44\x48\x21\x15\xd1\x29\x1c\x82\x0d\x17\x62\x11\x9e\x81\x09\x2d\x46\x3d\xaf\x27\x22\x5e\xc0\xb9\x94\xcc\x16\xf3\x88\xe0\x76\x9d\x37\x27\x6f\xed\x31\xaa\xeb\x4f\x66\xb7\xfb\x64\xb7\x7c\x11\x11\xe6\x1d\xba\x84\x2a\x9a\x2c\x03\x1c\x82\x80\x16\x26\xb2\xfd\x1a\x57\x54\xb8\x8c\xac\xd7\x65\x97\xa0\xbc\x41\xdb\xaf\x65\x5c\x66\xf6\x99\xd7\x48\x74\xa5\x5e\xdf\x75\xfa\xb8\xa4\x10\x44\x4b\x70\x35\x89\xe9\x41\x15\x85\x44\xcf\x1d\x53\x42\x81\x2b\x16\x47\xc9\xd0\x4c\x1a\x4a\xf5\x5c\x87\x21\xb5\x42\xf7\x2f\x79\xad\x1f\xa1\x6e\x3f\x88\x9c\xd1\x1f\xce\x42\x46\x62\xa9\x2d\x1e\x17\x77\x00\xae\x35\xa3\x2c\xef\xcb\xd3\x4d\x55\x7f\x81\x7e\xc2\x68\x8d\x14\x44\x3d\x75\xef\xde\x2f\xb0\x10\x5c\x23\x50\xf1\xd1\xe4\xa7\x66\xa5\xf5\xbe\xba\xed\xb2\xdc\xfa\xa2\x31\x3e\xda\x3a\x39\x72\xeb\xeb\x79\xbb\xff\xfd\xde\x7f\xa9\x09\x22\x6a\xf3\xec\x54\x4e\xea\x94\xbd\x96\x02\x1d\xa2\x10\x3f\x6f\x36\xc7\xea\x5f\x79\xff\xe7\x38\x65\x5e\xe5\xfc\x90\x97\xd4\xb5\xf2\xf9\xfb\x48\x2f\x06\xb8\x49\x12\xb4\xc5\xcb\xbe\xc2\x36\xb9\x11\x22\x54\xca\x16\x0d\xab\x31\xb1\x18\x44\xa8\x99\x7d\x39\xc8\x83\x63\x44\xaf\x04\x11\x45\x09\x41\xcc\x7e\x8c\x59\xf1\x7e\x61\x12\x51\x92\x52\x5d\xee\x70\x82\xba\xc1\x6d\xd9\xee\x54\x6e\xd1\x3f\x6a\x49\xd1\x14\x44\x1c\xc4\x5c\xf6\x35\x97\x83\xed\xa6\xfb\x63\x61\x2a\x32\x1b\xd7\xdc\x83\xea\xff\x1a\xc7\x56\xc2\xba\xd7\xb9\xce\x2b\x4d\x99\xe9\x88\x2a\x0e\x22\x49\x04\x81\x5c\xf6\x38\x5f\xff\x44\xc2\x12\x39\x86\xf1\xaf\x4a\xbd\xe4\x0b\xb8\xb8\xf0\x08\x96\x70\x87\xa6\x5c\xf7\x66\x10\xa3\x47\x2c\xd2\x54\xa8\xd0\x59\xd3\xfc\x36\xe9\x9b\xb8\x01\x59\x82\x86\x30\xf3\xe7\xa2\xcd\x5b\x1b\xf9\x4f\xbf\x82\x33\x20\xfd\xef\x01\x10\xfc\x1d\xf3\xe5\x7d\x5d\x70\x48\x42\xbf\xe4\x5a\xf5\x51\x57\xa6\x99\x28\x24\xcd\x2b\x16\x82\x6b\x96\x49\x97\xa9\x0c\x50\x97\x19\xd1\x1a\x84\x48\x32\x72\x6b\xec\x05\xbe\xf4\xc1\xd6\x64\x7b\x77\x95\x9f\x27\xea\x42\x24\x16\x28\xdd\x2b\xa4\x6e\xef\x7e\xf5\x09\x21\x89\x34\x70\xcc\xdf\x17\x3c\x98\xe6\x83\xd1\x26\x1c\xb4\xd9\xf6\x20\x9a\xe6\xfa\xdc\xcd\xb4\x87\x12\xaf\xe1\x63\xf6\xec\x85\x49\xb4\x95\xa7\x84\xe3\xfe\x47\xb5\xf5\x91\xb2\x80\x40\x50\x27\xe2\x78\x2e\xae\xf3\xb7\x5f\x7c\x2f\x44\x8a\xf8\x57\x2f\x55\xd3\x5e\x18\x97\x82\x80\xcc\xce\xbd\xdd\x59\x5e\x41\xf9\x8a\xf5\xb0\xd1\x0f\x31\xc6\xe8\x6c\xda\xfa\x97\xde\x6f\x1e\xfc\xaa\x20\x24\x93\xbd\xc5\x1a\xe4\xfa\x7a\xfb\xc7\xb5\xb7\x37\xf3\x43\x94\x06\x63\xbd\xeb\xf2\x72\x35\xaf\xaf\x09\x4c\x02\x0c\x06\x66\xf5\x35\xca\x59\xe3\x42\x98\x38\x25\x42\x83\x53\xae\xb3\x0b\xc0\x02\x10\xe2\x1f\xf3\x8f\x65\x66\xdc\xfd\x9e\xf2\xa6\x40\x18\x96\x10\x2a\xf6\xfe\x5c\x37\xf9\xc0\x69\x02\x61\xc0\xf2\x96\x08\x02\xde\xd6\xe0\x3a\x0d\xcb\x6e\xcc\x00\x41\x90\x52\xc7\x96\xca\x05\x36\xce\xfe\xcd\x1f\x4a\xb8\xb5\xa4\xb6\x42\x62\x9b\xf6\xc5\x46\xf1\xcd\x63\x5d\x29\x6c\x7a\x7e\x3a\x40\xc0\x90\x5c\xcc\x54\xde\x7e\xf8\x8a\xec\x13\x36\xd5\xb9\x5e\xb0\xdc\x5f\x7e\xd8\x10\x70\x14\xbe\x0b\x79\x35\xea\x21\x42\x60\x18\x55\x6b\xcf\x0d\xd6\xab\xa2\x46\xd0\x1f\x56\x15\x65\xd3\xbe\x4c\x9f\x06\x44\x89\x8e\xfb\x5a\x74\x17\x7e\x1f\x4c\xe6\x4f\x13\xc9\x8c\xa4\x67\xc0\x42\xb1\x7a\xb9\x91\xfe\x30\xa7\xa0\xb2\xae\xaa\x76\x8a\x09\x82\xc8\xa0\xef\x00\xde\x39\xc5\x32\xee\xe3\x5d\x88\x35\x7a\x8d\xb2\x2e\xc3\x6f\x06\xf7\x5d\x80\x24\x90\x56\x27\xe9\xdb\x58\x20\x01\x20\x49\x90\xa9\x1e\x11\xbd\xed\x4b\x0e\xc0\x42\x54\xa9\x67\xdd\x56\x35\xfe\x8c\xea\x0e\xc0\x20\x70\x84\x15\xc8\x7b\x8b\xff\x49\x04\x0b\x0c\x74\x1a\x8e\xab\x1f\x2b\x6f\x04\xec\xbf\x32\x4d\x79\xaf\xe9\xd3\x60\x4d\x02\xc0\xed\x56\xcf\x6e\x6c\x2a\xad\x55\xba\x2d\x51\x8f\x64\x0e\xbb\xcf\x5c\xee\x78\x90\x05\x29\x59\x21\x9f\x2a\xd7\xb8\xf7\x7f\x0f\x91\x96\xf5\x23\x05\x93\xa3\x8d\x84\x12\x32\xaa\x73\x36\x67\x49\xdc\xf9\xea\x06\xf1\x93\x56\x51\x97\x5c\x52\x33\xf0\xc7\xf9\x3d\x07\x0b\x3b\xf6\xe7\x11\x82\x93\x9a\xd6\x4d\x01\xd4\xfd\xe9\xf2\xda\xf7\xa1\x3c\x33\x04\x7e\x00\x71\x44\x12\x16\x9b\xe3\x29\xaf\xf1\x42\xc2\x65\xde\xa9\xfc\x7b\xa0\x01\x90\x71\x60\xc5\x0f\xf0\x54\x80\xc2\x95\xcc\x8b\x7c\x44\xc4\x1d\xa9\x75\x5d\xa4\x43\xfc\xb3\x53\xb2\x50\x09\xaf\x56\xff\xdb\xe7\x20\x81\x4f\x00\x69\xfe\x2c\xda\x84\x56\xf1\xf3\x74\x6e\xad\x53\xdc\xd3\xfd\x7d\xa5\x71\xf2\x80\x54\x14\x50\xc8\xfb\x5f\x88\xe5\x08\x49\x0e\x8a\x05\x84\x0f\xf2\x3b\xcc\xb5\xb5\x1f\x9f\x4d\x37\xc5\x03\x37\x4d\x1c\x76\x63\xc2\xc4\x19\xdf\x7c\x25\xac\xb6\x90\x13\xbb\xf3\x5f\xa3\x03\xab\x61\x99\x37\x24\x7f\x87\xf3\x79\xa8\x15\x77\x76\x04\x16\x83\x38\x44\x4c\x80\x01\xa3\x85\xcc\x11\x2c\xfa\xd2\x0b\x6d\x5a\xbf\x4a\x77\x3e\xaf\xc3\x00\x66\x99\xb0\xd2\xaf\x0d\xd6\xf4\x8e\x4c\x1f\x41\xff\xe3\x11\xc2\x78\x2c\x4a\x7f\x75\xae\xcb\xef\x2f\x58\xee\xda\xea\x74\x1a\xd6\x4a\xc3\x81\x4d\xae\x33\x3f\x56\xb5\xce\x67\x86\xe1\xb3\x29\x60\x04\x23\xb5\x8c\xc3\x33\x96\x5d\x06\x87\x3f\xeb\xa4\xca\x20\x16\xf4\x10\x6f\x61\xa2\x64\x03\x32\x48\x19\x21\xc7\x6e\x73\xe3\x98\x7e\x9f\x9d\x22\x4c\x34\x55\xac\xab\x5a\x93\x7f\x7c\x3b\x7b\xd4\x32\xca\xc0\xb5\xfd\x28\x81\x86\x35\x9c\x15\xf8\x95\x4f\xc6\x91\xd5\xc2\x18\x62\xbf\x0f\xa2\x8e\x2c\xfe\xc6\xe9\xb2\x26\xe3\x48\x91\x90\x2c\x55\x9c\xf3\x6e\x23\x79\xa6\x96\xe7\x27\x57\x9a\x04\x56\xc6\xa1\xad\x9e\x9f\x0b\x82\x4a\x8c\x1a\x5b\x32\x09\xac\x13\xfe\xc1\xe4\xcd\xcb\xea\xdf\x67\xa8\xf3\xf3\x0c\xb9\x2a\x59\xa4\x62\x0f\x74\xa1\xae\xaf\x97\x11\x74\xd9\x9c\x4c\x03\x24\x35\x1f\x0a\x9b\xa9\x0e\xa9\x1d\xd2\x7c\x0e\xa1\x96\x69\x1c\x53\x35\xea\x64\xcb\x02\x87\x06\xdb\x23\xbc\x3f\x55\x33\xb3\x13\x90\x69\x1a\x50\x81\xcb\xa5\x4e\xdd\x5e\xe6\x8e\x64\x11\x23\xda\x70\xae\x2a\xfb\x94\x77\xbd\x52\x02\xc8\x8c\x45\x2c\xb6\xd4\x41\x63\x1e\x73\xf5\xda\xf4\x47\xb8\x24\x04\xa5\xaa\x8e\x27\x2c\x1b\x68\xf1\x96\x14\xec\xee\xaa\x12\x6a\xf5\xb2\x1c\xd8\x4a\x6e\x52\x8a\x5f\xc0\x16\x77\xae\x3e\x82\xd1\x95\x08\x91\xd2\x5a\xba\x3a\xc1\xea\x5f\x30\x99\x49\xc4\xda\xb7\x69\x63\x17\x0a\x78\x0d\xca\xf1\x97\x5c\x88\x6f\xbb\x8f\x42\x64\x28\x58\xfd\x56\xe6\xaa\xaa\xcb\x27\x28\x55\xff\x8d\x10\x63\xec\xe5\x93\x3f\x8e\xb2\xe7\xa6\xb9\xc3\x32\xb6\xdb\xd9\x1d\xe4\xe5\x55\x9d\xeb\xe7\x0b\x06\xff\xa5\xa3\xfc\xec\xdb\xa5\xb4\x0d\x66\xc2\x6f\xb6\x58\x1b\x50\xb8\xed\x72\xf4\xee\xfa\xc7\xce\x63\x93\xd9\x2e\x75\x40\xcd\x02\xf7\xd2\xde\xe3\x8f\xdd\x4b\x55\x5f\x90\x08\xa4\x8e\x45\x90\x38\x74\x02\x42\xeb\xa1\x56\xc3\xd7\xeb\x24\xc5\x21\x96\x68\x9f\x2c\xa0\xda\x2a\x53\xdc\xc1\x69\x86\xf2\x9f\x94\x43\xa4\x66\x92\x0c\x66\x0e\xcd\x68\x42\x68\x61\x1d\x98\x5c\x90\xd6\xd3\xa3\x1e\xe1\x3c\x04\x68\x52\x43\x42\x36\x9b\x24\x1e\xd2\xff\xd1\xd8\xa6\xd2\xcd\xf6\x7e\xff\xf4\xed\xcf\x83\x6b\x71\xf9\xc3\x18\x58\x9b\x5c\xeb\x97\xd7\xad\xa7\xe7\xd3\xa9\xaa\x67\xf1\xad\xc4\xc8\xd0\x2f\x72\x89\xa2\x05\x4f\xf4\xe7\xc8\xb4\x4a\x7a\xe9\x06\xfb\xd2\x5c\xca\xe1\x83\x44\x25\xb9\xd3\x50\x7e\x82\x16\xc3\x60\xf6\x25\x26\x60\xca\xe1\xdd\x0e\xee\x97\x1e\x72\x55\x95\xf9\xbf\x0f\x50\xcb\xbc\x6d\xac\x4f\x07\xa1\xdd\x97\x97\x09\x13\xf3\x68\xa4\xbd\x78\x8b\x6f\x58\x4c\x5e\x72\x23\x02\x4a\xf1\x7a\x10\x66\xf5\x49\xc8\xac\x02\x6d\xcd\x37\x9c\x22\xc6\x13\x36\x58\x5f\x92\xf9\xfc\x60\x4c\x94\xd7\xfc\x46\x4a\xf1\x7b\x30\xf9\x82\x3a\x15\xa8\x30\x8e\xd9\xe0\x72\xd5\xcd\xa0\xe6\x0e\xde\xa9\xec\xef\x5f\x75\x15\x4a\xeb\x46\xd1\x80\xc1\x39\xcd\x73\x39\xdf\x53\xa1\xe2\x81\x9c\xf8\x3f\x84\x1e\x45\xaa\xa2\x24\xce\x12\xef\x31\xf9\xfe\x37\x20\x33\x2a\x52\x59\xe8\x24\xda\x08\xdc\x66\x55\xeb\xde\xf2\x16\xd7\x95\xfe\xec\x4e\xc4\x18\x87\x89\x2f\x9a\xe2\xdb\x82\xc3\x14\xa8\x04\x63\xca\xc7\x7e\xf8\x76\x73\x5e\x3e\x93\xb2\x88\xbf\x56\x96\xc9\xd8\x3a\xdc\xfc\x58\x3d\xde\x7d\xc6\x8a\xf5\x83\x41\xd2\x72\x31\xc4\x76\xb3\xe3\x0a\x89\xeb\xb9\x6b\xe1\x15\x5f\xac\x4c\x82\x3b\x94\x66\x92\x90\xb5\xf6\xe6\x3a\x3d\xd1\x6f\xa4\x65\x3b\x4f\xdf\x55\x2a\x21\x71\x18\x8b\xbb\x4a\x0f\xd6\xb7\x97\xd5\x71\x95\x25\xa9\x17\x72\xb9\x87\x23\x01\xd2\x16\x81\x5b\x2a\x4b\x54\x4f\xd8\xf6\x32\xaa\x1e\x99\xa9\x32\x96\x7a\xfe\xfd\x7b\x7e\xd6\x50\x5d\x22\x48\xfb\x1d\xb0\x0b\xc9\xbc\x48\xe5\x1d\x94\xf0\x6c\xe3\xf5\x91\x07\x98\x1f\x17\x5a\x8f\x9e\xbc\xb9\xaf\x36\xc7\x53\xeb\x9d\x49\xfa\x59\xc7\x33\xce\xc1\x4b\x42\x28\xab\x9d\xf8\x70\xc2\x92\x96\x51\x6c\x46\x96\x4f\x34\x96\x70\x12\x6e\xbd\x5c\x90\xf7\x1a\xc7\x58\x0a\x20\x0d\xa2\x09\x4b\xce\x46\x8e\x03\x7c\x78\x7a\xad\x32\x64\x44\x41\x3f\xf4\x50\xf2\xbf\x95\x63\x2a\x99\x24\x89\x85\x27\x9f\x20\x2f\xdb\x3f\xaa\x77\x1c\xd7\x0a\xf8\x65\x3b\x5b\x49\x4c\xa4\x23\xb1\x1f\x8e\xf0\xfe\x6d\xb3\x6f\x1e\xbb\x98\xa4\x3d\xd7\xe5\x2d\x36\xcd\xfe\x05\x66\x2c\x05\xa5\x62\x08\x9d\x38\x52\x39\xc7\xe5\xcd\xdd\x6d\x40\x29\x06\xa1\xa3\x2a\x59\xe2\xae\xbf\xdf\x9a\x59\xeb\x93\x51\x28\x71\x97\x97\x5d\x28\xf1\xad\x9c\x0b\x7a\x74\xa3\x81\x3a\xa1\x14\xb0\x59\xc5\x8c\x9f\xdf\x0b\x2d\x32\x6f\xd7\xfe\xad\xcc\xff\x7d\xc6\xdd\x89\x96\xee\x85\x3e\x82\xd2\xd2\x56\x48\xbb\x57\x37\xf7\xf7\x6c\xba\xbf\xfb\xfb\x85\x2a\xa3\x85\xc6\xe9\x49\xd4\x1f\xbb\xaa\x78\xa0\x8c\x6e\x89\x62\x14\x4e\xfe\x33\xbd\xf3\x26\x36\x44\x63\x50\x23\x84\xcd\xb6\x5c\xc3\xb9\xd0\x75\x55\x5a\x82\xca\x79\x2c\x94\x32\xe9\x29\x29\xe3\x44\x5c\x1b\x6c\xa9\x8b\xb6\xbd\x5e\x2c\x8d\x2a\xa3\xad\x72\x22\xe1\x80\xaf\xc8\x34\x67\x53\x52\x35\xe4\xe2\x1e\x1b\xa3\x94\x99\xe8\xbd\x5a\x54\xdf\x24\x56\xd0\x41\x10\x38\x3f\xfd\x57\x2c\xb7\x4d\x73\x9e\xdd\x4d\x1d\x48\x49\x7c\x93\xfd\xe6\x0e\xda\x8b\xc0\x6c\xf4\xee\xea\x30\x0a\x08\x61\x65\xa9\xcf\xee\x3b\xe7\x0e\x04\xa0\xc3\xd8\xf2\xfb\x4c\x3e\xf6\xc2\x1c\xc7\x0e\x3a\x92\x19\x89\xc2\xdb\xf5\x8c\x32\xa3\x59\xec\xa2\x63\x54\xa4\xe9\x45\xe5\x84\xe5\x35\x5c\x27\xa1\x5d\xea\xa8\xaa\xda\x60\xa9\x3f\x5f\xeb\x74\x12\x09\x02\xd9\x1c\xe4\xf9\x63\x5d\x1d\x8f\x55\xb9\xdf\x7f\xff\x55\x76\xed\x3e\xcb\xa2\x98\x90\x4c\x7f\xb8\xf7\x7b\x55\x6a\x2a\x88\xfc\x36\x77\xcb\x04\xcd\x58\x16\xa5\x83\x0c\xf8\xd8\xc7\x6a\x76\xf1\x2c\x8d\x23\x1b\xfa\xd9\x1c\xea\x1e\xdf\x7d\x39\x4d\xa7\x91\x06\xdb\x39\x31\x2d\x17\xb3\x07\x96\x85\x63\xa0\xac\x95\x30\x20\x04\xce\xe2\x9b\xa5\xb3\x90\xb9\x50\xa3\x57\xbd\xeb\x79\x80\x4b\x8b\xbd\xe6\x31\xd0\x1a\xd3\xbd\x81\x7b\xef\x39\xeb\xaf\x8c\x33\x93\x39\xc6\xc4\x4a\xbd\xe4\xf8\x86\xfa\x7a\xbe\xe2\xa5\x89\xfb\x8f\xfb\x8c\x88\x19\x0c\xae\x9a\xd6\xd2\xdf\x41\xd3\x46\xb3\x4b\x08\x34\xe1\x08\x27\xbb\x75\xe8\x85\x9d\x9a\x2b\xd9\x82\x16\x60\x68\xe3\x7a\xa5\x80\x64\xd2\x26\xd3\x10\x2a\xba\xfc\x6e\x81\xef\x56\xaa\xc9\x72\xd2\xf4\xa3\x12\x69\xd5\x7e\xa1\x40\xfb\x56\x2c\x3f\x25\xd0\x99\x95\x54\xa1\x52\xd3\xae\x0b\xad\x66\xef\xa1\x96\x60\x93\x2c\x2b\xa0\xd3\xe5\xd8\xfe\x4b\xa4\x62\x44\x54\x1c\x29\xea\x4e\x7d\x69\x96\x23\x85\xee\x73\x10\xf8\x4d\xb2\xa5\x5d\x6f\x3e\x41\xa7\x97\xa0\x02\xb0\x3c\x8e\x12\xe1\xf5\xdb\xe9\xa1\xbf\x02\x15\x02\x35\x26\xbc\xce\x43\x35\xdf\x1e\xb4\x8a\x25\x6d\xc8\x2f\xd0\x58\xfe\xdc\xf2\x25\x29\x6e\xe8\x8d\x7d\xaa\x9e\xcf\xf8\x58\x57\x6d\xa5\x06\xc0\x9e\x1b\xa3\x43\x69\x71\x52\x55\x09\xed\x28\x87\xd4\x18\x5a\x0f\x88\x83\xcb\xcf\x6c\xfb\xff\x06\x47\x1c\xfa\x74\x06\xe7\xd4\xc8\x62\x52\xa1\x3c\xd8\x3b\xbf\x86\x5a\xef\xb0\x5d\xb5\xc4\x84\xfe\x64\xaa\x23\xb7\x79\xfe\xbe\x3a\x6d\xdf\x3e\xfa\x6f\xe7\x9a\x2a\xb6\xda\xf9\x29\x79\xb1\xf7\x11\xaa\x40\xa3\x90\x84\x02\xce\x55\x65\x37\x53\x5b\xf3\x9d\x9e\xde\x04\x21\xb1\x8e\xfd\xcf\xf8\x24\xd4\x9e\xdd\x39\x13\x62\x66\xb7\xec\x02\x95\x4b\x48\xfa\xe0\xa9\x4b\x7a\x62\xde\xf3\x39\x76\xea\xa5\xaa\x0a\x6b\x35\x6a\x07\x60\x90\x71\x11\xf4\x1b\xe3\x2c\xdd\xc1\x20\x53\x7a\x8c\x2f\xbc\x25\x64\xca\x7c\x90\xb1\x3d\xe5\xbc\x54\xb7\x67\xf5\x6a\x35\x19\x16\x27\x12\x86\x86\xa9\x78\x48\xa4\xaf\xe9\x49\x4e\x1f\x33\x46\x71\x4c\xf7\x4a\x15\x08\xe5\xb7\x53\x17\x3d\xe7\xd5\xb9\x19\xf3\xec\x31\xd6\xb6\xee\xe8\x2b\x2e\x6b\x2a\x16\x0e\x07\xa9\x2e\x6e\xdd\xdc\x7f\xff\xcb\x03\x19\x30\x09\xb4\x57\x4d\x73\x81\x17\xa9\x41\x63\x4d\xf2\x99\xc5\x54\xa7\x00\x93\x2e\x1a\xfa\x3f\xff\xdf\xff\xd9\xb8\xca\x84\x3f\x4b\x1a\x59\xab\x8d\xe7\xee\x8e\x81\xaf\x30\x53\x8f\x74\x3f\xdd\x1c\x31\x63\x76\x65\x3a\x1e\x5c\xbe\xf8\xad\xd1\x2b\x92\x6a\xed\x93\x55\xcc\xd2\xc4\xbe\x42\xe4\x24\x7a\x03\x45\x63\x97\xad\x69\x4e\x8e\x3c\x0e\x23\x1c\x44\xbd\x5d\x00\x3f\x0a\x35\xad\x26\x91\xfd\x64\xbf\xea\x21\x47\xab\xca\xe6\x3b\xab\x37\x05\x5c\x30\xf8\x67\xcf\x48\x08\x45\x2d\x9c\x1e\xc9\x31\x0f\xea\xfe\x67\xfc\x05\x02\x12\xaa\xfa\x3b\x3c\x84\xb3\xfd\x5a\xc3\xc9\xff\x3e\xa1\x33\xec\xd6\x8e\xc3\x41\x41\x51\x48\xf8\x44\x15\x18\x10\xc2\x24\xd1\x5e\xe3\xc0\xd6\x49\x2d\xa9\xf0\xbf\x13\x2f\x6b\x81\x10\x8b\xb4\x77\xb5\xcf\x51\x17\x17\x40\x14\x84\xc4\x66\x00\xb7\xb9\x41\x0f\xd0\xf7\x5d\xee\xee\x20\x65\xe8\x4d\x5b\xaf\xab\x52\x81\xeb\x20\xfc\x63\x4c\xfd\xf5\x43\x99\x23\xd8\x3a\x91\xb0\xe5\x09\x0d\x60\x6d\x18\xf2\xe6\xaa\x5b\x49\x5d\xd1\x60\x78\xba\xa0\x03\x6a\x6c\xe5\x65\xde\xe6\x84\x6c\xdb\x96\x3a\x7f\xcb\xf5\x19\x8a\x35\x9c\x9a\x9b\x73\xa9\x09\x18\xf1\x09\xc6\x0a\x65\x6c\xf5\xb3\xa9\x82\xe3\xc0\x1f\xdb\xeb\xe6\xea\x63\x5d\xe4\x38\x87\xbc\xa2\x0a\x14\x2d\x91\x37\x79\x8d\xa6\xf8\x70\xc5\x44\xf8\xc5\x86\x80\x2a\x32\xe0\xbe\xe4\x4b\x5e\x17\x8d\xd3\x1e\x5e\x08\x8e\x51\x29\xa1\x7a\x6a\xda\x17\x38\xe2\x43\xaf\x85\x0c\xa8\x23\x15\xf7\x32\xc9\x3f\xa0\xd6\x4b\xfa\xb7\x7e\x6c\x1c\xd2\xc4\x71\xa1\xf3\xd8\x43\xb3\x1f\xa1\x88\x06\x42\xa1\x25\xf1\x27\x27\xe6\x8a\x80\x98\xf2\x14\x87\x76\xe4\xe8\x65\xb8\x48\x5b\x11\x81\x51\xc6\x70\x7d\x37\x79\x99\x4d\x9c\x4a\xab\x4e\x58\xbf\xe5\xe5\xb9\x19\x75\x01\x4c\x90\x24\x59\x38\x6d\xe9\xaf\xa1\x28\x2c\x58\x78\xc9\x3c\xfb\xf3\x66\xc5\x27\x9a\x5f\x26\x60\x86\x6e\x98\x89\xfd\x97\x86\x81\xd5\x0c\x24\x17\x20\x57\xa8\x83\x11\x45\xd6\x84\xb1\x26\xd2\x9f\x05\xac\xf6\x9f\x8b\x82\x84\x38\x0d\xa4\x8d\xf1\x60\x6e\xab\xf2\xf9\x6b\xa5\x3d\xec\xc1\xc4\x98\x50\x5f\x97\x22\x3e\x3e\xbd\x37\x26\xc9\x2c\x7d\xd2\xaa\x48\x5f\x91\x12\xbd\x9b\x90\xf3\xb7\xd4\x24\x42\xd0\xd7\x37\x50\xde\xe5\xe5\xad\x85\xde\xf8\x63\x26\x44\xdd\x2b\x79\x5c\x43\x5e\x7c\x3c\x62\x3d\x6e\x22\xb8\x81\x2c\xcc\xa8\x7a\xfb\x05\xad\x71\xef\xb0\xe9\x72\x3f\x42\x44\xd2\xb2\x44\xa8\x9f\xdb\xab\x51\xce\xc2\x6e\xc3\x50\x92\xd6\xd3\xe3\xd3\x66\xbd\xdd\x6d\xfb\x5e\xb7\xc9\x62\x34\xd9\x08\xab\x8e\x7a\xe4\x83\x06\x26\xc3\xcc\x1b\x3f\x11\x55\xf4\xad\xb7\xb2\x18\xae\x92\x07\x82\x08\x41\x87\xbc\xb1\x41\xde\xf0\xed\xb3\x9b\xc2\x39\x33\xdc\x67\xb5\xff\xd9\x96\x4d\x4b\xaf\xe9\xa5\x35\xca\xec\x73\x22\x09\x85\xee\xdd\x57\x48\x88\x40\xbd\xde\x54\xf5\x6e\xe0\xb7\x1b\xa1\x43\x52\x56\x22\xcf\xd9\xd3\x75\xf5\xfc\xc9\xb9\x20\xe1\xa4\x6e\xfd\xfb\xc3\xf6\x61\xb7\xf7\x0c\xb8\xbf\x05\xc5\xbd\x08\x2a\x0c\xc8\xd0\x92\xee\x6d\xa5\x7b\xec\x55\x04\x06\x8c\xa4\x95\x91\xd2\xa2\x1d\x96\x7a\xd4\x9a\xee\x1f\x8c\x0c\x38\x47\x6f\xa5\x7c\xed\xbc\xfd\xfd\x19\x24\x84\x3c\x19\xa2\xde\x17\xa8\xdd\x7e\xe6\x8a\x60\xb3\x07\x21\x65\x18\x05\x83\xcd\x20\x35\x9d\xa7\xd7\x2b\x75\xac\x07\x5d\xc7\x0b\x41\xc7\xbf\x25\x27\x67\x24\x5a\xbc\xea\x3d\xaa\x16\x6a\x8a\xa8\x2b\x92\x8e\x5f\x5c\xc0\x8c\xce\x32\x86\x83\xc2\x05\x7a\x72\xd7\x4d\x65\xa7\xfc\xf2\xa7\x4c\x20\x48\x40\xc6\xab\xe0\xd6\xaf\x65\xa5\x71\xde\xf5\xf1\x83\x23\xe0\xb1\x6f\xc5\x3c\x79\x54\x62\x6f\x5f\xd8\xdd\x8c\x7e\x46\x1b\xd0\xc6\xc9\xb4\x8c\x59\x3a\xfd\x61\x95\x58\xcb\x74\x1b\x88\x38\xbf\xec\xfe\xa9\xca\x20\x48\x40\x64\x5e\x7c\x4a\x1f\x68\xd1\x3d\x34\x88\x7a\xe2\xaa\x20\x83\x28\xe4\x3c\xe9\x5f\x72\x52\x84\x21\xeb\xb6\xf3\x85\x07\xa5\x0c\xa2\x48\x3a\x6b\x99\xa6\xe7\x20\xad\xa6\x67\x33\x11\xe5\x7b\x9b\x73\x5d\x9d\x7a\xf5\x04\x19\xc4\xca\x24\xa9\x63\x15\x5a\x9e\xc2\x3c\x43\x19\x96\x51\x19\xc4\x3a\x40\x3e\x4a\x59\xf3\xb6\xe9\x1e\x81\xb5\x06\x26\xc8\xe1\xdc\x79\x49\x06\x49\x10\x52\x18\xa7\x51\x15\xbd\x09\x95\x0c\x92\x24\x25\x4d\xc1\xe6\xa3\xd4\xc4\xf1\x72\x2c\x40\x17\x3f\x95\xfd\x38\xc6\x69\x73\xe8\x96\xae\x63\x99\x37\x34\xbf\x0f\x91\x3f\xcc\xc2\x8c\xbc\x10\xce\x0d\xd6\x45\xf5\x5c\x9d\xa7\x3b\xb5\x0c\x18\xa4\x54\x8d\xdd\x96\xb2\x6a\x49\x2b\xf8\x62\x3b\x59\x9a\x40\x32\x60\xd2\x18\xe3\x57\x2e\x6b\x67\x39\x4a\xce\xdd\xa0\x34\xb2\xfe\x31\xd6\x0a\xd2\x69\x8b\xf7\x72\x54\x7e\x10\xd3\xde\x42\xca\x49\xf8\xbb\x98\x62\xfc\x5a\xc8\x20\xcd\x80\xfa\xab\x96\x26\x3c\x9a\x73\x32\x48\x25\x82\xcd\x5e\xbb\xa8\x67\x32\xed\x96\xc2\x25\x19\xa4\x1a\x22\xd7\xf9\xf8\xb6\xff\xd4\x96\x4a\x06\x59\x62\x4d\x15\xae\x6e\x1f\x1e\x46\xfb\xb5\x0c\x32\x6e\x5f\xf4\x23\xf4\x53\x28\x33\x01\x73\x64\xe3\x5b\x28\xb5\x0d\x5a\xec\xd6\x35\x54\xc8\x64\xc0\x03\x20\xfa\x80\x65\x16\x5c\xe5\xd0\xbe\x14\x55\x39\x6d\xd1\x4e\x8b\x49\x73\x29\x93\xe9\x73\xe0\x3a\x20\x05\x8c\xdd\xe3\xea\xaf\xc9\x25\x72\x93\x31\xd9\xab\x0b\xe2\xc7\x78\x76\x09\xb4\xae\x51\x33\x4f\xe9\x9f\x16\x72\x65\x00\x82\x53\xfb\xd1\xae\x6e\x5f\xb0\x0c\x46\xdb\x80\x1b\x23\x23\x41\x21\x1c\x9c\x4e\xc5\xc7\x8e\x08\x7b\x37\x88\xfb\xc1\xaa\x48\x06\x52\x29\x5b\xb9\xb7\x5a\xb0\x75\x7f\x07\x95\x04\xa2\x10\x6f\xd7\x0f\xbf\x14\xd3\x98\xde\x04\xa5\x99\x1c\xa4\x18\xef\xf2\xb2\x5b\xfd\x2e\xdd\x05\x64\xa0\x50\x7b\x91\x42\xf5\xba\x34\x51\xfc\x38\xc3\xa9\xd9\xf3\xbd\x2a\x8c\xbf\x3c\x2d\x22\xad\x07\x5b\xac\x9e\xe9\x2f\x03\x0d\x0c\x2c\x60\x9b\x4a\xae\xd3\x53\x69\x19\x45\x03\xfd\xe0\x0a\x96\x84\x6d\x07\xe4\xc8\xec\x96\x63\x9a\xa5\x8e\x39\xbc\x39\x5a\xc3\xbe\x4f\x66\x89\xff\x80\x06\xe1\xb4\x3c\xfc\x42\xb7\x50\xfd\x92\x81\x01\x45\x9b\xcc\x08\x0d\x3d\xfd\x66\xa3\x6d\x31\xf0\xd8\xe5\x13\xfb\xa9\x43\xef\x4c\xe9\x56\x06\x06\x39\x35\xb3\x7a\xdc\x9c\xcf\xbb\x64\x18\x70\x11\x0e\x93\x66\xb2\x23\x79\x34\xf1\xa8\x8a\x26\xc3\x50\xc4\xd6\xc3\xf9\x69\x73\xb7\xbd\xdf\x1c\x56\xb7\xb7\x0f\xeb\xd5\x7e\xfb\x70\x7f\x58\x5d\x5f\x6f\xae\x97\xdf\xe8\x30\x44\xa9\x75\x2f\x86\xb3\xf5\x5d\xfc\x4f\x46\x47\x19\x04\xaa\x37\x17\xba\xc2\xa6\xfd\xa5\x43\x86\x0c\xe3\x2c\xb3\x1a\x4b\xdd\x9c\xdd\x21\x8e\x69\x41\x32\x4c\x20\x09\x6d\xa4\x88\x65\x17\xa9\xab\x8f\xaf\x58\x9c\xe6\xbf\x76\x76\x4a\x16\x44\x54\x46\xa5\xe9\x38\x6a\xb9\xc9\x90\x25\x19\x81\xca\x4b\x7c\xa7\x7e\x8f\xeb\xe2\xe6\x47\x3c\xf4\x43\x74\x46\x3f\xc2\x6e\xe1\x37\xb9\x69\x5f\x36\xef\x9f\xac\x64\x21\x33\xb6\x14\x7d\x82\x73\xd3\xbd\x20\x9e\xa2\x2a\xc3\x94\xa5\x74\x64\x0f\x05\x96\xed\x46\x9f\xad\x1d\xdd\x78\x2d\x09\x53\xc6\xe3\x70\xf2\xda\x7c\x22\x7e\x20\xc3\x54\xd9\xfa\x26\x68\x7d\x95\x3f\x93\x42\xd6\x65\x91\x49\x86\x59\x98\xd1\xa2\xff\xc7\x7a\xbd\x48\x4c\x18\x4f\xea\x30\x8b\xac\x4e\x15\x89\x14\x38\xbd\xb1\xab\x8f\x49\x89\xcc\x8f\x14\x48\x3c\x48\x1f\x5e\xd8\x9d\x69\xe2\xb6\x2a\xc3\x4c\x82\x57\x38\xfb\x02\xcd\xba\x2a\x9b\xf3\x7c\xe7\x0a\x39\x98\x28\xf3\xac\x4c\x02\xdb\x2c\xff\x5c\x6e\x52\x92\x3a\x22\x4c\x78\xff\x9a\xec\xab\xbf\xee\x66\x27\x14\x3a\xb6\x85\xfe\xea\x7c\x72\x77\x77\x0d\xc7\x13\xe4\xcf\xe5\x20\x0f\x21\x43\x61\x8c\xe9\x8d\xce\x6e\x6a\xf0\xc2\xc4\x32\x04\x9e\x68\x18\x34\x18\x48\x1f\xb2\xea\x52\xb3\x3e\xcd\x97\x21\x28\x41\x4c\x86\xab\xed\x7e\x77\x3d\x79\x82\x32\x54\xd2\xdd\xc2\x9d\x55\xcd\x21\x3e\xc9\x2d\x34\x84\xc1\xed\x87\xc5\x9c\x04\x4d\x36\x5b\xb2\xa5\x1e\xd2\x50\x19\xca\x8c\x99\xc8\x49\xf3\x7f\x2b\x4f\x90\xeb\x31\xb5\x53\x86\x12\x4d\xe2\xe2\x50\x4a\xb9\xac\xc8\xc6\xfc\x7e\xe9\x18\xe8\x3d\x85\xa6\xc9\x9f\x4b\x4f\xee\x98\xc9\x95\x4c\x1e\xbe\x76\xc6\x41\x34\xf7\x1e\x9d\x44\x49\xbf\x5c\xa0\x48\xc9\x07\xfa\xe8\x59\xcc\x16\x33\xef\x2f\x0a\xa5\xa4\x62\xce\x43\x89\x77\x79\x51\xcc\xe7\xb5\xc9\x84\x8f\x03\x7a\x1a\xf4\xc8\x08\xce\x8e\x8a\x82\x2c\x8d\x3c\x81\xdd\x98\xbc\xc8\xa1\xc5\x05\xb9\x6b\x19\x05\x02\xe9\x55\xba\x83\x32\x37\xd8\xb4\xd5\x62\x8e\x24\xa3\x50\x58\x9d\x8e\x1d\xb4\x50\x36\xde\x1a\x5e\x46\xa1\x0c\x7c\x91\xc5\xdf\xbd\xc9\x85\x74\xf7\x02\xfa\x8a\xe2\xc4\x4d\x5d\x46\x11\x43\xaa\x2a\xba\xe9\x7a\xd3\x97\x29\x65\x14\x41\x9a\xb8\xc4\x85\xba\x72\x54\x2f\xb9\xd0\xb3\x95\x51\xa4\x98\x07\xae\x3a\x81\xf4\x75\x91\x1b\xb3\x98\x42\xc8\x28\x0e\x19\x99\xa1\x17\xd0\xb4\x3e\x2e\x1d\x28\xd2\x32\x8a\x15\x0b\xb4\xa5\xb0\x5d\x77\xfb\xd0\xcd\xfe\xf7\x78\x87\xa7\xd6\xa9\x1a\xfb\x61\x2c\x56\x90\xda\xc4\xb2\x0b\xe4\x2b\x47\x19\xe0\xee\x70\x9a\xc4\xc4\x67\x51\xd5\xf1\x98\xb7\xeb\xaa\xe8\x92\xd4\x1a\x8a\x7d\x35\xe1\xd2\x4f\x7f\x48\x16\x07\xd4\x0c\xee\xe6\x98\x67\x8f\xcc\x7e\x6b\x26\x2d\x7a\xfa\xd8\x85\x45\x9f\x9c\x45\x67\x8c\x0d\x75\x1d\x2b\x52\x39\xb6\xc3\x95\x11\xcf\x12\x62\x0f\xcb\xf3\xc7\x6e\x2e\x59\x2c\x23\xae\x32\x0b\x4c\xb2\x55\x37\x57\x95\x9b\x64\x1e\x11\x47\xee\x6c\xc1\xeb\xb7\x5c\xb9\x30\xff\xea\x5c\x5f\x44\x83\x6e\x3c\x24\x86\xe6\x40\xdb\x23\xbe\xdf\xb0\x3c\xff\x62\xef\x8a\x80\x65\x59\xd4\x5b\x70\x7f\x85\x5a\xaf\xe1\x34\xbb\x5a\x48\xb5\x72\x38\xee\xa2\xf9\x82\x6d\xfb\x09\xac\x47\x46\x60\x62\x22\xa8\xad\xa1\x28\x96\x45\xa1\x64\xa4\xb8\x0c\xd3\x41\xc3\xef\xb6\xfa\xa1\xe0\xf4\x84\xa0\x7a\xcd\x18\x19\x21\x03\xda\x33\x4f\x05\xfc\xdc\xd4\x4a\x46\x28\x15\x6d\x2b\xe4\x7d\x44\xce\x88\xee\x65\x6d\xb1\xee\xed\x41\x64\x64\x02\x24\xae\x7d\x5f\x0f\x9f\x28\x9d\xc8\x38\xca\x32\x66\x45\x48\x08\xd2\xde\x6d\x65\x90\x0f\x24\x95\x4b\x20\x9b\xfb\x5c\x1c\x42\x9c\xf4\x39\xca\x09\xeb\xde\x7b\xc6\x0f\x50\x92\xea\x91\x79\xf9\x3e\x93\x06\x94\x71\xa2\x15\x85\xe8\xc7\xaa\x44\xf2\xdf\x1e\xaf\x41\x31\x0b\x23\x62\xd5\x15\x55\x77\xc7\x97\x01\x97\x32\x66\x09\x43\xb7\x34\xb8\xde\xda\xec\x78\x9a\x11\x63\xab\xdb\x99\x5f\xc7\x09\x75\x9c\x26\x81\xe2\x97\xa0\xc1\xc5\x62\xa1\x7f\x7a\x71\x8a\x09\xbd\x94\x47\x2f\xf9\xd4\x4c\xce\x99\x31\xab\x7e\x60\x35\x50\xe8\xc5\xb8\xfa\xb8\xc3\x2e\xf8\x2b\xdb\xe9\x8d\xe1\x31\x78\x9d\x67\x7f\xe7\x1c\x7b\xf3\xae\xd2\x78\x85\xaa\x3a\xa2\xf3\xe1\x18\xb5\x3d\x64\xcc\xd3\xc0\x91\x59\x9a\xf6\xd0\xfe\xa8\xa8\x29\xbd\xf9\x37\x59\xe0\xba\x21\x10\x47\xca\x96\x6f\xba\x49\xb6\x2a\x8a\xcd\x3b\x29\x2a\x17\x73\x0e\x6c\x3f\xde\x42\xc8\x1a\x05\xc7\x1d\x3a\xec\xef\x84\x76\x20\x63\xc9\x33\xe3\xe2\xe7\xcf\xc5\x83\x64\x2c\x35\x77\xca\x68\x5d\xbc\xb5\x3f\x97\x68\xf9\x99\x0b\x18\x0d\x8f\x2e\x18\xe0\xe7\x61\xc4\x87\xff\xe1\xba\xc8\xa3\x53\x1b\xa0\x5f\x65\xe1\x07\x9f\x58\xfe\xb8\xb1\x2a\x48\xc8\xec\xe1\x6a\xf5\xfb\x66\x32\xa9\x94\x06\xaa\xf7\x3f\x3e\x6d\x0e\xdb\xf5\x83\x35\xea\x3a\xec\xb7\x77\x9b\xbe\x36\x10\xeb\x08\x33\xeb\x74\x57\x20\xd4\xf3\xd2\xa6\x1f\x94\x20\x71\xd8\xec\xa4\x6b\x5e\xf2\xd3\x67\x5e\x49\xb3\x4b\xd3\x3a\x25\xf1\x71\x87\x71\xbd\xee\xf6\x91\xe1\x2d\x9b\x96\xe9\x64\x8c\x42\xb1\xd4\x75\x39\x9e\x51\x6f\xed\x82\x79\x59\xf8\x97\x31\x6a\x41\xbf\xec\x1a\x55\xde\xcc\xf6\xf3\x18\x8d\x2f\x54\x51\xdd\xd1\x20\xb9\x3f\xfe\xad\xec\x36\x36\x51\x44\x72\x02\x9e\x60\xff\x8b\xdf\x67\x52\x21\x94\x77\x87\xb4\x8a\x10\xf7\xf8\x3e\x08\x1f\x7f\x87\xa6\x5b\x1e\xfb\xc5\x2e\x09\x02\x4d\x95\xf1\x31\xb9\x7e\x54\xb1\x5c\xce\x6c\x93\x20\x4e\x02\x47\x41\xad\x6a\xfd\x99\x5d\xef\xf4\xda\x92\x40\x5a\xdd\xbe\xc1\xc5\x7d\x55\x36\x3f\xb0\xfe\x1d\x95\x82\xd7\x88\xa5\x17\x9f\x9f\x7d\xa9\x4c\x19\x0c\x55\x6f\xf0\x53\xe3\xe7\x97\x1a\xc6\x90\xf9\xd6\xa0\xaa\x6a\x5c\xf9\xca\xde\x74\x58\x14\x5a\x66\x11\xc5\x89\x2d\x3c\x98\x2e\x1a\xf1\x37\x29\x0e\x74\x22\xe6\x56\x41\x87\xb6\xb2\x0d\xbd\x9f\xbe\x0c\x49\x12\x59\x19\x80\x67\x6c\xb7\xeb\x49\xb9\x26\x49\x98\xa0\xfa\x80\x13\x90\xb3\xbc\xf5\x49\xf8\x9a\x24\x59\x10\xb8\x80\x9f\xba\xb1\xd7\x17\x39\x54\xc2\x30\x22\xbc\x82\x5f\x49\x17\x57\x99\x24\x4d\x20\xb1\x2e\xb4\xe7\x52\xbd\x1c\x74\x4f\xee\xed\x0e\x19\x5a\x55\xfd\xaf\x23\xc9\xa7\xeb\x51\x84\x75\x01\xe8\x91\x49\xaa\x54\xe2\xe4\x80\x0e\xd0\xb6\xd6\xaf\xca\xae\xb0\xfd\x98\x2c\x30\x41\x9f\x1f\x51\xa9\xd8\x1f\x88\x0d\xed\x3c\x44\x62\xb9\x71\x5e\xa2\xd3\x1f\x95\x99\x50\xba\xb9\x72\x93\x77\xf3\x75\x29\xb2\x4d\x78\xca\x88\x6d\x2b\x2b\x8f\x25\x6e\xa6\x0b\x67\xc2\xd3\xd4\xb7\xa3\x6f\x11\x34\xd6\x34\x74\xdc\x98\x91\x09\x17\xc6\xfa\x92\x54\xe4\x6a\x30\x2b\xd6\xcb\x84\x9b\xc8\x78\xb7\xb3\x7b\x6f\x37\x22\x13\xc1\x98\xb2\xa2\xf8\x04\x44\xb0\x1d\x27\x0b\xae\xb8\x68\x7e\xb9\x8f\x40\x84\x32\xf6\xcd\xf1\xa2\x52\xaf\x5d\x2c\xb0\xe0\x18\x21\x13\x99\x68\x62\xf5\x7e\xdf\xee\xbf\x5e\x3f\xad\xbe\xaf\x6e\x0f\xbb\xf5\xca\xab\x57\xc9\x44\xaa\x84\x00\xb4\x32\x6f\xe5\xb3\x9a\xcc\x2a\x69\x02\xaa\xbc\x83\x1e\xb4\xaa\x7d\x2a\x33\xc9\x66\xdd\x78\x95\x24\x3c\xf3\x38\xfb\xa6\xc5\xe3\x0e\x0a\x1c\x7b\xa7\xc8\x44\x07\x8a\x2a\x49\xd4\xd3\x58\xe9\xb9\xec\x93\x4c\x30\x0a\x69\x77\x78\x28\xf1\xaa\xa8\xa6\xd7\x83\xdc\xa6\xde\x83\xd0\xd6\x74\x8a\xa3\xb1\xee\xaf\x77\x57\xfe\x2f\x26\x4d\x48\x01\x92\x36\xe0\xe6\x05\x6b\xf2\x0b\x42\xeb\x06\x68\x1d\x66\xa6\x77\xcb\x40\x90\x59\x2e\x4b\xd3\xae\x8a\x62\x97\x97\xf3\x05\x9a\x05\x31\x52\x0a\xb9\xc3\xf6\xe8\x42\x9d\x66\x3e\x44\x2a\xdb\x24\x3c\xcb\x41\x09\x64\xfa\x4d\x2c\xc0\x8c\xd2\xcd\xf6\x25\xaf\xf5\xc1\xbd\xb8\xb3\xf3\x84\x59\x20\x5d\x93\xb2\x69\xfd\xa4\x67\xa1\x08\x6c\xc1\x0d\x0a\x35\x11\xb0\xfd\xc7\xec\xd3\x22\xb6\xf8\xca\x16\xea\xf6\x64\x0d\x9a\xfa\x4e\x45\x77\x58\x06\x96\x54\x82\xa7\xf1\x49\x7e\xda\x6d\xf5\x9f\x95\x41\xea\x34\xfd\xbb\x67\x3c\x62\x56\x4a\x16\x87\x48\x1a\xb9\x07\x2c\x55\xa5\xed\xa4\xdc\x2e\x4b\xf7\x4b\x16\xa7\x29\xa5\xcb\x27\x8b\x62\xa7\x90\xc4\x6f\xe0\x2c\xc9\x32\xa6\x7b\xdf\xb9\x5d\xfe\x4c\x22\x57\x8b\x2f\x04\x63\x22\xa3\x16\x9f\x83\x22\xb6\x30\x97\xf5\x91\x8c\xe9\xb0\x5f\x98\x57\xdb\x69\xe0\xcc\x52\x61\x79\x09\x36\xf5\x1c\xcc\x79\x97\x69\x92\x92\xa5\x2a\xa0\x3a\xe4\x63\x01\x6a\xa6\x83\xcd\x67\x43\xb3\xc0\xc2\xb3\x1b\x6c\xaf\xa0\xc1\xdd\xf9\x78\x5c\xea\xf9\x4b\x96\xf1\x58\x59\x07\xaf\xea\x44\x9b\xc6\x28\x4f\x64\xdc\xbd\xf1\xaf\xb9\x7a\x9d\x44\x6e\xfe\x78\x12\xd2\x7c\xb2\xdb\xef\x12\xa6\x29\x8e\xfe\x71\xe1\x25\x22\x99\x08\xac\x3c\x3b\xc1\x80\x48\x83\xc9\x5a\xfb\xf5\xcf\x13\xb2\xc0\x6a\x45\x83\xce\x5d\x8f\x63\xf6\xd5\x24\xaa\xdf\x3d\xf1\xdd\x7e\xf5\xb4\x3f\x5c\xf7\x4e\x2f\x92\x01\x02\x27\x6e\x0d\x96\xe7\x20\x9b\x7d\xae\xdb\xb7\x52\xdb\xbc\x99\xdd\x09\x2d\x83\x38\xed\x23\xdf\xed\xfa\x61\xf6\x49\x8c\xb8\x1a\xe3\x92\xfa\x8b\x45\x16\x7a\xb1\xb1\x7b\xfc\xe1\xa0\xe9\x9f\x3c\x42\xd4\x21\x73\x55\x83\x87\xbe\x75\xc0\xd0\x68\x6a\xae\x3f\x1c\xf1\x19\x16\xdb\x16\x6e\xa0\x89\x63\xde\x17\x1d\x4a\xfc\x80\x5a\xff\xcc\x78\x40\x32\x93\x4a\xd1\xc3\x5c\x6d\x44\xf5\xf3\xa4\x90\x19\x88\x3c\x73\x77\xbb\x9f\xdd\x83\x34\x48\xac\xf4\x9e\x9d\xf1\x96\x28\x71\x59\x18\x4d\x03\x86\xa4\xf1\x41\x30\x5e\xac\x9d\xdb\x8f\xb7\x48\x9c\x0f\xc6\xc4\x0b\x79\x7e\x47\xf9\x25\x37\xed\x43\xa9\xf0\x0e\xde\x97\x36\xcd\x34\x30\x86\x2a\x76\xf8\xee\xab\xe1\x69\x98\xf1\x0c\x6c\x08\x51\x19\xab\x95\xff\xf3\x38\x33\x0d\x05\x32\x47\x97\x18\xc9\xb8\x2c\x54\x49\xd3\x28\xb6\xfa\x7a\xd6\x3b\x06\xf5\x66\xff\x75\x39\x52\x4a\xa3\x24\x26\x56\x36\xd9\x6d\xb5\xdb\xe3\xa9\x4b\xcb\x8f\x64\x93\xe3\x6a\x25\xd3\x07\xd5\x7f\x4c\xf5\xd0\x55\xa8\xdb\x8f\xd5\xec\x8e\xc7\x81\xa1\xf7\xf3\x35\x3f\x36\x0f\xe5\x6a\xb2\x9c\xa6\x31\x93\x36\x14\x19\x54\x98\x7c\x8d\x69\x06\x20\x76\x1f\x48\x62\xe5\x03\x8a\x55\x51\x50\xc8\xd6\x6b\x49\xc9\x34\x49\x43\xaa\x0a\x5e\xe5\xed\x11\xea\x57\x97\xd5\x7e\x81\x16\x7f\xcc\x74\x11\x64\xca\xc2\xa0\x6f\xa2\xec\xd6\x57\x13\x5c\xe0\x67\xab\xf9\xf4\x86\x31\xc5\x28\xfd\xdf\xfd\xfb\x4c\x76\x58\x2f\xf8\x7f\xcf\x43\xff\x27\x65\x4a\x83\x43\x43\x5f\xe7\x50\x44\xfb\x8f\xd3\x64\x71\x4a\x99\x89\x28\x8a\x3f\xe6\x25\xc9\xec\x36\x97\xa9\x90\x1b\x99\xf2\xa0\xd7\xff\xf6\x77\xf0\x57\xbd\xb0\x8b\x96\xb4\x87\xc5\xc9\x34\x03\x2b\x2e\x38\x36\x39\xfa\x39\x5e\xc8\x7d\x90\xa7\x3a\xe8\x25\x61\x2b\x62\x98\xe9\x99\x43\xb2\x4c\x81\x69\x31\xf0\x75\xae\xba\x80\x6f\xb1\x4a\x9e\x82\x30\xd4\x76\x7b\x2d\x2b\xf5\x5a\x9d\xdb\x9e\xec\x79\x79\xab\x41\x27\xc4\x0c\xb0\xe4\x35\x9c\x4a\xd5\xca\x14\x30\x21\xe5\x1c\x30\x66\x2c\x95\x27\x53\xc9\x98\x45\x7f\x36\xbb\x5c\xa3\xe5\x29\x4e\xe5\x1b\x64\x2a\x33\x6b\xd4\xf7\x5c\x43\xd9\x3a\xf1\xaa\xe5\x37\x44\x1a\xa4\x38\xe7\x6b\x55\x3e\x37\x2f\x50\x52\xd9\xe6\x67\x3d\x8a\x54\x45\xc2\x1b\x74\x7c\xb7\xf0\x08\x3f\x09\x86\xb3\x2a\x66\x18\xef\xf1\x26\x4e\xf7\x61\xb2\x35\xfa\x81\x20\xa9\xab\xff\x58\x7d\xff\x9a\x5c\x8f\x85\xa8\x64\xaa\xa4\xed\xc5\x7c\xbb\xdf\x2e\x74\x38\x53\x65\x12\x22\xb0\xe4\x0e\xb7\x6b\x5d\x39\xce\xde\xe0\x5e\xa6\x9a\x83\xb0\x80\xfc\xe3\x0d\xc8\xfe\xaf\x10\x50\x8d\x7b\xff\xf0\xfb\xe6\xfe\x70\xf3\xf0\x74\x58\x3f\xdc\x75\x5f\xf1\x57\x3f\x42\x86\x44\xc9\xd6\x39\xf4\x6f\xa1\xd6\x86\x98\x63\x16\x35\xb3\x24\x48\x24\x53\x8d\x26\x74\x42\x3d\x5d\x30\x36\x8e\x58\x53\x0c\x2d\xb6\xf5\x19\xdb\x7d\x7f\x52\x4c\x04\x1b\xe9\x72\x36\x0f\x66\x8a\x26\xf7\xc3\x32\x81\x0e\xe4\xd7\x85\x0d\xfb\xea\x9f\xe7\xaa\xdb\xd8\xdb\x73\x3d\xbf\x27\x28\x02\x27\xed\x7e\xcc\xcb\xc3\x8f\xc9\xbc\x41\xc1\xa9\x70\x76\xa2\xa7\xf1\x07\x9c\x8b\xf9\x42\x84\x26\x20\x49\x31\xdf\xdc\xbc\x85\x92\x12\xf1\xf5\xda\x31\x61\x16\x5b\xb7\xa9\xc9\xb8\x71\x71\xf0\x13\x25\xef\xb3\xd3\x1a\x81\xa4\x9c\xfb\x56\xb5\xd8\x3c\x62\xed\xec\xb7\x47\xd3\x20\x0b\x82\x94\x26\x7b\x5b\x7d\xcf\x75\xfb\xe2\xac\xd4\x17\x08\x35\x32\x0b\x42\x45\x10\x88\x83\xa3\x5a\x82\x95\x40\xb0\x91\x90\x1f\x13\xe9\xc4\x2d\x06\x79\xb9\xac\xb0\x2d\xb3\x40\x4a\x52\xc2\x7b\x68\xdf\xc7\x8f\x2a\x0b\x74\xa0\x1c\x19\xbe\xdd\x38\x5d\xb0\x4f\xce\x80\x56\x68\xe3\xb1\x2a\xaa\x12\x7d\x48\xe4\x0e\x86\x92\x53\xbf\xec\x08\xef\x0b\x59\x78\x16\x65\x81\xb0\x25\xbd\x9c\x32\xfe\xeb\xfc\x6d\x58\xf4\xb3\x38\x34\x24\x6c\x49\xa2\xab\x3b\x6c\x1f\xde\xb0\xae\xf3\x05\x9b\xe2\x61\x05\xcc\xe2\x54\x32\xed\xdb\x47\x16\x3f\x67\x61\x52\xf4\xc5\x5e\xa7\x65\xf8\x0a\x8c\xa9\x6c\x5d\xe2\xfb\x6c\x1e\x64\xb1\x09\x08\x4a\x66\xf2\x52\xdb\x6a\xdf\x4c\xb1\x43\x66\x49\x16\x87\xe4\x51\xe8\x94\xc2\x7c\xb1\xd5\x1d\x66\x90\x50\xdf\xa7\x5b\x2d\x8b\xef\x2f\x88\xc5\x4d\x5e\x42\xa9\x86\xde\x64\xc6\x30\xa5\x6a\xed\xf5\xfe\xcf\x19\x29\x45\x66\x59\xc2\x29\x9e\x20\x2d\x28\xac\x0f\x35\x52\xe3\x72\xf4\x63\x33\xc1\xa8\x10\x70\x6f\x49\xac\x0e\x33\x7c\xc1\xd0\xf9\xc5\xe6\xe7\x4f\x26\x43\x5a\x03\xf3\xa6\x39\xe3\xa7\x60\x7a\x99\x71\x11\x9a\xc1\xe8\x6c\x97\x77\xb3\x73\x41\x00\x58\x66\xc2\xe8\xc8\x85\x6b\x57\xf8\x9c\x97\xfb\xfc\x88\xfb\xdd\x6c\x10\x84\x69\x64\x46\x54\xf1\x75\xfd\x71\x6a\xab\x31\xdc\x22\x03\xe7\x68\xdc\x2d\x71\x94\x16\x4e\xd4\xd4\xfd\x20\x48\xad\x52\x9a\xaa\xf6\x2f\x35\x36\xdd\x12\x45\x79\x58\xd4\x9f\xc6\xd8\x6f\x6a\xb0\x5d\xb5\x2d\xa8\xd7\xab\xaa\x6a\xac\x23\xc6\xa9\x98\x17\xd8\x33\x19\x27\x84\x10\xbb\xca\x5b\x55\xe5\xe5\xb5\xf7\x28\x18\x29\x2c\xf8\x91\x49\x46\xe2\x2e\xbd\x6c\x84\xaf\x66\x42\xdb\x62\xdd\x0f\x53\x32\xa2\xf6\x19\x49\xe3\x5c\x9d\x3f\xfa\xbf\x2b\x15\x3a\x2c\x8b\xce\x2f\x5c\x65\xdc\x20\x6d\x38\x09\xed\xed\xf2\x63\x33\xe8\x10\xc9\x0c\x59\x40\xee\xbc\x5f\xbc\xd5\x8e\xcc\x50\x68\xcf\xbd\x7f\xac\xf3\xb7\xbc\xc0\xe7\x61\x57\x9d\xde\x33\x94\x52\xe1\xc8\x57\xf0\x82\xbd\x2b\x33\x54\xa9\xb0\xf2\x44\xf9\xb1\xb2\x13\xab\x6d\x2b\xff\x5d\x86\x1b\x2b\x34\x05\x4d\xae\xba\x75\x6d\x32\x81\x79\x10\xb1\x40\x0c\x16\x7b\x0b\x8f\x8d\x07\x8a\x53\xd4\xf7\x04\xf5\x64\xce\xb9\xc3\x21\x5a\x9e\x52\x81\xa6\x4d\xc3\xe9\x23\xe2\x91\x16\xe0\x18\x63\x45\x81\xe5\xf3\x6c\xfb\xe5\x71\x18\x92\xfe\x28\xf5\xea\xa9\x91\x30\x69\x7a\xf0\x38\x91\x04\xcd\x82\xb6\x3a\xe6\x8a\x28\x49\x87\x81\xba\x93\x8c\xec\x2f\xb9\xb7\xbf\xe4\x0e\xb8\xf3\x8b\xff\x7f\x9e\x7b\x65\x32\x57\xcf\xe1\x49\x60\x95\x92\x6d\xff\x1a\xaf\xba\x1b\x77\xe1\xec\xfd\xff\xf0\x5f\xff\x35\x11\xd3\x2e\xef\xf3\x38\xca\xd9\x00\x6d\x01\xcc\xae\xd0\xb2\xaa\xfd\xae\xc1\x59\x60\x39\xae\x5d\xec\xfa\xa5\x2a\x66\x2f\x35\x67\x71\x40\x35\xbb\xbb\xfc\x52\x69\x76\x76\x11\x69\x14\x68\xdd\x73\x47\x9e\x71\x57\x15\x53\x0c\x01\x4f\xa5\x15\x35\x27\x3b\x9b\xb8\xff\x2b\x06\x14\x5e\x1f\xa8\x42\xf0\x93\x12\x30\xcf\x34\x0f\x53\xcf\xfb\xaf\x9b\xbe\x1f\xe3\x0e\xf3\x58\x53\x90\xd3\x13\x29\x37\x63\xed\x82\xcb\xe2\x2b\xe7\xdc\x2a\x49\x37\x13\xa7\xcf\x25\xd8\xae\xe4\x5c\x68\x42\x6e\x5c\x57\x35\xe8\x6a\x32\xef\x45\x9a\xf8\xd8\x70\x6f\x55\x22\x59\xd0\x1f\xd3\x9c\x72\xd8\xef\x5f\xbe\x4f\x3f\x63\xac\x12\xf1\x40\x12\xa2\x7b\xe6\x45\xdd\xba\x01\x3c\x0b\x46\x2e\x3e\xa7\x62\x3e\xdf\x21\x88\xd3\x80\xec\xae\xfa\x12\x2c\x87\xd0\x6a\xda\x50\x5b\x2d\x62\x07\x4b\xf7\xf9\x02\x0d\xd1\xec\xc3\x24\x08\x28\x8c\xef\x9f\x08\x44\xd6\x56\x91\xb6\x4f\x62\x83\xea\x9b\xbc\x98\x38\x0e\x48\x2e\x31\x8a\x7b\x2e\x3e\xed\xad\x17\x50\x50\xae\xc0\x02\x35\xba\x70\xad\x7b\xba\xfb\xdc\x2d\xb1\x2e\xd8\xe1\x3a\x08\xe5\x3c\x55\xd9\x57\xdf\x06\x3a\xe7\x2f\x66\x97\x0e\xb5\x75\xed\x05\x1b\x53\xfc\xa4\x7d\xc7\x75\x6c\x5b\xdd\x96\x23\x77\x51\x14\xe7\x18\x18\x62\x74\xdc\x1d\xd5\x2f\x23\x7f\x8e\x4c\x06\xa1\xbb\xa5\x5f\xb0\xbd\x85\xa6\x1d\xc1\x20\x38\x1a\x49\x55\xdf\x6f\x5b\x3a\xc5\x6f\x93\x2f\x32\xa1\x20\xbd\x6d\x1b\xed\xa0\xb6\xe8\x95\x59\xbd\x94\x9b\x58\x51\x2f\xcd\x13\xef\xaf\xea\x0a\xb4\x22\x05\xae\x5d\x3e\x0f\x08\xa7\x28\xf3\x69\x7a\xc9\x0d\x4a\x2a\x45\xf5\x1a\x9d\x52\x04\x69\x10\xa9\x11\x43\xc1\x21\x4f\xf6\x15\x61\xf5\x7e\x56\xb1\x11\x01\xd8\x60\xce\xd9\xef\x41\x5f\x62\xf7\xc7\x0d\x27\x00\xc5\x11\xde\x09\x08\xb6\xaf\xaa\xe1\x60\x18\x06\x34\x3b\xed\x0c\x7c\x28\x8b\x8f\xde\x8e\x74\xf8\x86\x30\x64\x04\x2a\xa2\x88\x6f\xa5\xf5\x0e\x4a\xc2\x59\x2c\x5f\x4f\xa8\x32\x92\x20\xfd\xf7\x19\xcf\x38\x69\x3d\x88\x28\xb4\x34\x2a\xd0\x3e\x45\xf5\x56\x67\x63\x42\xd9\xac\xda\x2e\xa2\x34\xa3\xbc\xf5\xa6\x86\x52\xf5\xa7\x12\x86\x54\x42\x6d\xf5\x64\x55\xb7\xb9\x2a\xe6\xb6\x83\x43\x4c\x26\x22\x63\x8d\x0e\x41\xeb\x7b\xfc\xe1\x35\x64\x67\x8f\x58\x24\x3c\xa6\xb7\xf9\x77\x0f\xac\xff\x6d\x74\xc0\xa6\x48\x65\x60\xd5\x4a\xc7\xb1\x90\x60\x92\x71\xb7\xe2\x91\xbc\x34\x41\xd0\xfc\xc1\x34\x0c\x8d\xc3\xc8\x5b\x98\x06\xc8\x02\x57\xb3\xa5\x5f\xa4\x4a\x25\x6a\xe8\xf6\xe9\x91\x1e\xbf\x14\xa9\x4e\x6c\x1b\x57\x6b\xdb\xa5\x77\x5d\xa4\xde\x9a\x62\xde\xa1\x10\xa9\xd6\x24\x32\x86\x50\x17\x1f\xb4\x66\x75\x6f\x44\x7f\xc2\x2e\xec\x52\x03\x26\xe6\x73\x05\xb8\xbf\x59\xed\xf0\xa7\xd5\x4c\xe8\x11\x43\xd4\x97\x36\xfd\x61\x0c\x85\x2d\x98\xbe\x55\xaf\x0e\xbc\x45\x9e\xbd\xa3\x15\x48\xf0\x84\x71\xd7\xc0\xec\xa2\x03\x1e\x0c\xc0\x12\xc1\x85\xbd\xcf\xdf\xef\x7e\x8d\x57\x14\x82\xa7\x34\xb5\xbb\x44\xe3\x0e\xd5\x0b\x94\x79\x73\xfc\x99\x1b\x51\xf7\x11\x41\x3b\xcd\x13\xfe\xfb\x9c\xd7\xa4\x7a\x5c\xcd\x5b\x8b\x42\x68\xa4\x25\x72\xf3\x7e\xaa\x11\xfc\x4e\x20\x04\x26\xdc\x0c\x46\xb1\x77\x58\x3f\xe3\x8c\xa1\x24\x05\x30\x45\x51\xe9\x6a\xb3\x6b\xc7\xf3\x0b\x32\xae\x8d\x07\xd6\x3c\x98\xc9\xc2\x2e\x80\x87\xc4\x93\x2d\xcf\xc7\x07\x43\x69\x47\xb3\x2d\xef\xf2\xf2\xdc\xf7\x34\x05\x88\x30\x1e\xf3\xfb\xf5\xe6\x6d\x38\xd6\xe5\xf7\x03\x64\x71\x67\x01\xdf\x2d\x3a\x77\xb5\x7e\x98\x09\xd3\xb4\x37\x09\x5f\x5f\xcf\x59\x73\x52\x48\x9e\xc6\xa4\x96\x8b\x3a\x97\x79\x7b\x51\xf0\x16\x2a\xcc\xa8\xb2\x62\x01\x29\x77\x50\x3f\xe7\xe5\x1a\x8a\xe2\xa1\xbc\xc2\x17\x28\xcc\x83\x79\x42\x45\x1e\xe7\x17\xa9\xe2\x78\x13\x17\x2a\xb2\xa8\x13\xa7\xff\x4f\xc5\x93\xdd\x99\x9c\xf1\xbf\x56\x95\xc7\x62\x0a\xa5\x63\x6a\x75\x4f\x84\x82\x79\xe0\x8e\x6a\x2e\xed\x9e\x99\xd7\x64\x95\xd1\x73\x65\x7e\xeb\x07\x20\xc1\x67\xf6\x2f\x50\xbe\x9a\x73\x51\x0e\x7d\x54\xa1\xa5\xf6\x65\xcf\xed\x75\xff\x47\x34\x04\x99\x7f\xb1\xc0\x2d\xd7\x80\x1d\xe3\xc8\x84\x41\x8b\x93\xcb\x8f\xa7\xaa\xf6\x61\xd2\x45\x77\xc6\x4f\x07\x08\x02\xee\x8a\x2c\xea\xa7\x21\x15\x04\xa1\xcd\xe6\xf3\xe3\xa9\x70\xa1\xe3\x83\xf9\x5e\xd5\xaf\xa7\x2a\x2f\xdb\x7f\x76\x2b\xed\x6f\x7e\x28\x86\x5c\x8c\x39\x99\x4e\x6b\xc9\x1d\x0e\x83\x90\xfa\x6d\x1a\x9b\x13\xfc\x28\xbf\x14\xa0\xf3\x2e\x83\x5a\x95\x7a\xf5\xa3\xfb\x61\x17\xdc\x4b\x09\x61\x1c\x53\x75\xfe\xcb\x1f\x8f\x9b\xc3\x78\x5d\x84\x30\x06\xca\xde\x0e\x44\xea\xd9\xe7\x03\x1d\x04\xc2\x14\x68\x93\x23\xc7\x9a\x7d\xd5\x8b\xee\x4d\x7f\x58\x14\x45\x68\xed\x9b\x7b\xde\x13\x3d\xee\x0d\x75\xb8\xfc\xcb\x05\x51\x6c\xc1\x9f\x5d\xf8\xeb\x1c\x11\x2c\x50\x29\xe2\xbf\x90\x3d\x93\x10\xeb\x80\x54\x66\x7e\x50\xf1\x74\xbe\xf0\x42\x92\x82\xe8\xde\x2e\x6c\xc1\xa3\xf4\xb1\x19\x29\x93\x4b\x48\x32\xed\x2d\x5b\xbe\xd4\x70\xc2\x66\x5f\x5d\x9d\xf3\x42\x7f\xcf\x4b\xac\x7d\xc6\x08\x69\xc8\xc2\xc4\xbf\xc2\xfb\xa4\xff\x33\xb7\x48\xfa\x4d\x2b\xd5\x28\x47\x84\x2c\x88\x29\x77\xbc\xa9\xf1\xc3\x02\x2c\x9c\xcb\x87\x3f\x0e\x3a\xd0\x03\x20\xed\x06\xf1\x8f\x7e\x1d\x04\xce\x03\x7a\x13\xaf\x57\x4f\xbf\xdf\x3f\x5c\x6f\x0e\x37\x9b\xcd\xee\x70\xff\xed\x6e\xf3\xb4\xda\x3f\x3c\x0d\xc3\xb2\xb4\x97\x35\xe9\xee\xe7\x57\x28\xde\xf2\xf2\x79\xae\xdd\x27\x81\x8b\x50\xf0\x29\x19\x1e\x4e\xa0\x06\x60\x2b\x70\x6d\x48\x05\xd3\x31\x66\x46\xbd\x54\x10\x29\xb3\x74\x0e\xeb\xc8\x62\x0b\x86\xcb\xfd\x04\x00\x66\x88\xc0\x58\x93\xde\xcf\xf5\xee\x40\x3e\x38\x4d\x93\x57\xe5\xe3\x59\xfe\x8e\x1f\x83\xe5\x8c\x04\x10\x82\x12\x89\x1e\x0c\xe4\xfe\x2e\x21\xa1\xea\x58\x2f\x1a\xdd\x1f\x90\x96\x1c\x72\x68\xeb\x0f\x8b\x38\x58\x4c\xb1\x41\xa2\x88\xf5\x44\xff\xfa\xaa\xb2\xd4\xb2\xfe\x4c\x26\xa3\x64\xe1\x0b\xb6\xbb\xf3\xf1\x68\x81\xff\xb3\x99\xa3\x8c\x35\x40\xa5\x60\x1a\x6a\xed\xa2\xe4\x8b\xa8\x1b\x74\x9c\xd8\xe7\x40\x37\xa8\xfd\x44\x06\x79\x34\x1e\x8c\xe8\x13\xb0\xc9\x02\x03\x1a\xad\x94\x48\x8b\x70\x74\x61\xea\x3d\x79\xe6\xf8\x01\xa8\x05\x55\x2b\xf1\x1d\xd5\xb9\x45\x42\x05\xce\xd9\xfa\xe3\x1c\xeb\x1f\x17\x3d\x90\xc5\x7f\xf1\xff\x19\x0d\x4d\xff\xe7\xe2\x0c\x3f\x13\x60\x95\x60\x42\x8d\x2e\x83\xb3\xf1\xcb\xa2\xd2\x9a\x1f\xcc\x38\xb5\x2c\x7f\x1d\x94\x4c\x1f\xaa\x11\x09\x45\xf1\xdd\x5c\x29\x1c\x20\x77\xa2\xbc\x21\xc1\x80\x95\xa7\xc2\x63\xde\x5a\x21\x96\xb9\x81\xcf\xe4\x94\x32\x08\xd2\xc0\xd1\x28\xbe\x95\x44\xda\xd0\x53\x63\x38\x37\x2e\x64\x21\xd5\x0b\xd7\xeb\xed\x08\xac\x2f\x43\x88\x69\x57\xde\x61\xfb\xb5\x6a\xbb\x38\x6d\x0a\x25\x97\x51\x98\x86\x03\x55\xd1\xc1\x45\xfe\xb8\x60\x1f\x4b\x19\xb1\x44\x23\xad\xda\x6f\x58\x54\x27\xac\x7b\xeb\xa6\xc3\x66\xff\xd5\x7f\x5f\xc4\xad\x98\xfa\x35\xfe\x67\xbc\x4a\xcb\x48\x18\x0a\x6b\xf7\x79\xf9\x61\xb5\xe7\xba\xc8\x06\x5a\x2f\x3e\xd9\xbd\x36\x01\xed\x85\xf8\xff\x73\xf6\x25\xdd\x8d\xe3\x58\xd6\xff\xa5\x57\xb9\xa8\x05\xc0\x99\xdf\x4e\x93\x1d\xaa\xf4\x54\x96\x1c\x91\x59\x7d\xfa\xe8\x60\x78\x90\x58\xa6\x08\x15\x49\xd9\xa1\xfa\xf5\xdf\xe1\x03\xc0\x49\x94\x33\xba\x17\x5d\x19\x6d\x80\x14\x09\x62\x78\xc3\x7d\xf7\xca\x0c\xd9\xd9\x86\x8f\x19\x50\x13\x73\x65\x52\xbe\xea\xdc\x12\xc4\x38\x1e\xe8\xa6\x59\x61\xc4\x66\x67\x29\xf6\x8f\xe8\x13\x35\x3b\xba\xbb\x7d\xe0\xfb\x69\xdc\x96\x8e\x7c\xb0\x0a\x13\x86\xa7\x41\x5c\x80\x07\x51\x84\x3b\xe2\x72\x33\x32\xee\x86\x63\x1d\x28\x40\x9e\x9b\x47\xcc\xef\xbc\x66\xfb\x57\x28\x6a\x96\x57\x83\x37\x0e\xbd\x00\x75\xe5\x5e\xd8\xe9\x52\x9e\x51\x9c\x00\x45\x9b\xe9\x74\x9a\x9c\x87\x89\x44\xb4\xca\x15\xe1\xea\xf8\xbf\x83\x71\x09\x13\x85\xc0\x4f\xb3\xae\x1f\xb2\xe2\x7d\x18\xcb\xe2\x51\x92\xa2\x6e\xd2\x89\x5d\x5e\x41\xc2\xf1\x54\x5f\x95\xc5\xf2\x28\x65\xb4\x65\xe5\xfc\xd0\x99\x80\x6a\x7e\x19\xf2\x23\xfe\x6d\x22\x3b\xc5\x63\x42\x1c\x18\x7a\x71\xd0\x15\x14\x66\x1f\x98\xbe\xa8\xfb\xb9\xd8\xa3\x46\xfb\xcb\x26\x76\xdc\x88\xa1\x9e\x94\x2d\xc6\xcc\x8a\xfa\xb7\xc9\x8b\x13\x91\x62\x0e\x77\x77\x05\xcc\xed\x5c\x2d\x9e\x02\x41\x2c\x5b\x73\xda\xe1\x22\x93\x33\xf9\x91\x55\x4e\x6a\xb2\xe9\x00\xe8\x10\xfd\xf9\xf6\xf4\xc7\xfa\xc9\xfb\x35\x49\x14\xce\x59\x12\x63\xb8\x00\x59\x30\xeb\xac\x2d\xfa\xe2\x4c\x1a\x4a\x6c\xad\x79\xf6\x6f\xad\x47\x6b\x93\x07\x51\x6a\xf3\xce\x4f\x7a\x18\x3b\x72\x3d\x54\x10\x5a\xc4\x16\x56\x42\x93\xc7\xac\x18\x16\xa9\x73\x2e\xc2\x80\x77\x3c\x58\xb8\x7d\x99\xed\xfe\x07\xcb\xd0\xb4\xbc\xda\xf5\xb9\x08\x25\x72\x6e\xe5\xf0\xb1\xd5\x6d\xe6\x8f\x8b\x84\xa1\x41\x80\x3b\xb8\xd6\xf9\x9d\x2e\xef\x4a\xfd\x1f\x28\x06\xd6\x29\x17\xdc\xc3\x15\xf9\xb0\xba\x9f\x3d\xec\x56\x7f\xbc\xac\x9e\x36\xab\xcd\x6e\xb6\x5c\xbe\xb6\xe0\x61\x2e\x85\x87\x29\xb5\xbe\xad\xd7\x56\x72\x72\xf0\x89\x11\x83\x6d\xdc\x3f\x6f\x09\x4c\xf6\xaa\x4f\x39\x28\x2f\xb0\x54\x02\x4b\x96\xfd\xc8\xea\xc3\x55\x59\x34\x57\xb1\xe7\x75\xfb\x93\x71\x3d\xa6\x77\x6d\xae\xd2\xc0\xa1\x06\x6b\x5d\x64\xe7\xe1\x7a\x54\xca\x28\x1d\x3e\x7f\xa2\x5d\xe7\x82\x8a\x82\x8a\x14\x81\xde\xd6\x69\xba\xd3\xa5\xc1\x4d\x0c\x9f\x43\x78\x34\x26\x23\x4a\x48\x2f\x74\xf7\xf0\x58\xe0\xd2\xfa\x16\xa0\xba\x5d\x74\x6d\x3c\x0e\x91\x02\xc5\x28\x89\xb9\x52\xa7\xc1\x04\x10\xbe\x1f\xc7\x46\x95\xa5\x3a\xe7\xf5\x15\x61\x40\x1b\xd2\x69\xe7\xb8\xf0\x13\x81\x38\x26\x13\x7d\x78\x82\xcf\x45\x9e\x39\x78\x89\xf0\x79\x4b\x60\x69\xc2\x1b\x37\x92\xb2\x22\x20\xc6\xa1\xe0\xcd\x56\xfc\xa3\xcc\x26\xa0\x36\xfd\x15\x20\x82\xd0\xb8\xc6\xbb\xd2\xf8\xa7\xaf\x50\xc0\x67\x33\x9e\x2f\x06\x37\x37\x1a\xb5\x20\x34\x0c\x47\xf3\xd9\xd3\xef\xcf\x6b\x17\x6a\x12\x41\xc2\xd0\xb2\x3c\x36\xe6\x2b\x8a\x2d\x0d\x52\xdb\x22\x10\x1c\x77\xb5\x36\x04\xa8\x4b\x44\x0a\x4c\x7a\x26\x22\xa2\x1e\x9e\x39\x46\x97\x60\xbc\x8c\xc7\x43\x38\xe1\xa7\x8b\xc8\x97\xc8\xbe\x81\xb8\xac\xf5\xd3\x3d\x02\xe4\xdd\xc3\x44\x11\x20\x51\xaf\x84\x8f\x9d\x1a\x7b\xa4\x22\x62\x4a\x61\x35\x3a\x1a\x15\xf7\x86\xc7\xff\x5b\x56\xd5\xfa\x56\x09\x87\x88\x94\x51\x7c\x97\x59\xc5\xd1\x15\xb5\x7f\x4f\xd2\x58\x05\x3d\x91\xed\xa2\x86\x72\x7e\x31\x67\xf1\xf0\xab\x25\xdc\x44\x6a\x98\x94\x73\x7d\xe4\x36\xfd\x3c\xd8\xa2\xfb\x1b\xb5\x48\x44\x6c\x78\x9f\x50\x4a\x18\xa9\xf1\xdd\x8f\xa6\x3e\x43\xd0\x1d\x26\x52\x82\xd1\xcb\xa5\x90\x60\xa5\xab\x82\x5a\x1c\x8c\x1d\x77\xa7\xcb\x17\x76\x19\x6f\x60\x82\xc5\x26\xb8\xa5\xc0\x59\xdf\xee\x07\x98\x32\x32\xc6\xa7\xc6\x4a\xb6\x75\xfd\xb7\x18\x48\xb8\xe0\xb1\x12\xd0\x0b\xdf\x58\x77\xa8\x31\xc9\xb3\xe2\x8a\x29\xca\x5d\x94\xa6\xbe\xe5\x39\xce\x5c\xa6\x69\xf8\x78\x82\x52\x4c\x7b\xe4\xac\xaa\xed\x12\x73\x2d\x09\x43\x58\xf5\x83\xde\xaf\xce\xa5\xee\x22\xc6\xa6\x0e\xf0\x1a\x96\xe5\xae\xe3\x04\x19\x0d\x8e\x5a\x66\xea\xf2\xc8\x7e\x3a\x6f\xc3\xad\xb3\x51\x77\x21\x11\x3b\xc0\xf6\x60\x58\x49\x5d\xf5\xae\x90\x44\xba\x80\xd5\x13\x7c\xae\x0a\x39\xc5\x6d\x38\xfa\x71\x19\xa7\x18\x57\x82\x7f\x9f\xbb\x42\x8d\xe9\x05\x2b\x9b\xff\xc3\xf2\x8b\xfb\xbb\xbf\xbb\xdf\x04\xe2\x63\x74\xe3\x77\x5d\x02\x7b\x05\x33\x77\x3f\xaa\x7b\x28\x8f\xac\x68\x57\xa1\x22\x3e\x82\x82\x2b\xa6\x7a\x40\xcf\xbb\x52\x1f\xa7\x29\x7d\xb9\x50\xd4\xb0\x7e\x3a\x52\xda\x79\x57\xb6\x2a\x49\xc8\xf0\x41\xac\x8b\xf6\x9e\xa3\x5c\xd3\x34\xb2\xc9\x5d\x12\x09\x9f\xb7\x0b\xc2\x56\xdc\x19\xcb\x9e\xda\x2e\x94\x00\x46\x49\x14\xcb\xf2\x0d\x53\x30\x93\xf2\xc7\x01\x8a\x7b\xfc\x91\x72\x7b\x60\xc5\xba\xa8\x1f\x99\x2b\x32\x94\x94\x9a\xb2\x9e\xfb\x3f\x16\x1b\x28\xea\xad\xee\x6c\x57\x49\x93\x84\x59\xfb\xe3\xf7\x0b\x87\xf2\x09\xea\x4f\x5d\xbe\x4f\xbb\x91\x92\xb2\x24\x6d\x65\xac\x71\xda\x7c\xeb\x71\x18\x73\xe9\x79\x21\x98\xe4\x34\x9e\x88\x63\x08\xa1\xf4\x7c\x83\x99\xb2\x64\xc4\xf3\xcb\x57\x72\x23\x5c\x7a\x4c\xa2\x12\xb1\xd0\xf9\xf9\xd8\x9e\xd1\xd2\x13\x22\x54\x1d\x01\x39\xf2\xce\xc9\xb6\x11\x04\x37\x6a\xed\xcf\x85\x23\xb7\x98\x5f\xc6\xe9\x78\x19\xf8\x31\xc2\x09\xb8\x99\xb9\xcf\x6a\xc1\xf2\x7c\xf4\xb6\x41\x10\x3a\x55\x77\x24\x16\x5b\x42\xcd\xc4\xc1\xaa\x2a\x65\x3c\x87\x6a\x1c\x68\x94\x41\x1a\xe1\xca\x3a\xb2\x77\x28\x97\xb3\x67\xf7\x54\x21\x25\x44\x5e\xc9\x54\x98\x73\x73\xf4\xab\xa1\xf2\x31\xf7\x75\xd2\x7a\x40\xb4\x20\x23\x4e\x88\x71\xd0\x2e\xa7\x5a\x6f\xd8\x9e\x21\x61\xe2\x27\x3b\x3d\x42\x29\xce\x3d\xf7\xe8\x6b\xf6\x12\x19\x09\xee\x1b\x32\xcb\xb2\x32\x89\xb5\x57\x96\xf5\x86\x30\x52\x2a\x01\x47\xbb\x5c\x9b\xbd\x78\x80\xec\xb7\xfd\x62\xc2\x98\x33\x0f\xb4\xce\x87\x60\x35\x19\x07\x10\x7a\x8e\x12\xa4\x32\x7c\x9f\x77\x00\x12\xef\xd7\x7e\xcb\x38\x8d\xd0\x6a\x65\x52\xce\x8c\x4c\xce\xd7\x53\x22\x56\x89\xf1\xc8\xf4\xea\x78\x0b\x20\x20\x93\xd0\x8f\x95\xfd\x0a\x9b\xa3\x7e\x87\xcb\x51\x17\xfd\x4c\x51\xe2\x3a\xa6\xe0\xa8\xec\xd7\x8b\x67\xd4\xbb\x3e\xf7\xb4\x6c\xb9\x4c\xa4\x89\x4c\xf3\xf3\x65\x7b\x28\x9b\xb3\x76\x40\x13\x63\x7b\xa5\x7e\xc4\xb8\x05\x81\xec\xff\x72\xa1\x4f\x91\x21\xc8\x34\x4c\x9c\xcc\xb7\x8d\x04\xa1\xd9\x87\x83\x35\x2b\x24\x12\xaa\xe2\x08\x5e\xb3\x24\x72\xc9\xfc\x50\x1a\xf2\xc7\x47\x96\x61\x51\x67\xff\x43\xb0\x38\x71\x58\xb1\x59\x5e\x1b\x47\xb4\x1d\x7f\x1e\x02\x4b\x2c\x3f\xf5\x65\xae\xcb\xb2\xc3\x39\x8e\x9e\x90\x43\x84\x50\x0a\xdc\x07\x97\x25\xb0\x4e\x0a\x85\x4b\xae\x02\x44\x60\x59\xd1\xcf\xea\x4a\x78\x7c\x74\x33\x11\x4a\x3c\x81\xbf\x9d\x8f\xac\xc8\xfe\x3d\x71\x7c\x49\x49\x04\x02\x16\x8e\x13\xf1\xec\x71\x16\x7a\x74\x77\x49\xa9\xdb\xd4\x9e\x4f\x50\x4c\xfa\x09\x52\xd2\x54\xda\xe0\xc8\x22\xab\x2f\x37\x76\x3c\xe9\x05\xbe\x49\x23\x1b\x82\x47\xdc\x63\x7f\x4d\x5c\xf7\xfa\xad\x25\xf8\xd2\x7a\x3c\xab\xfa\xb0\xb5\x07\x6f\x29\x5b\x9e\x37\xdb\x0f\x7c\xdf\xf0\xa6\x65\xfb\x43\xed\x45\xa3\x07\x07\x19\x29\xcb\xf0\x36\x7b\xda\xde\x5a\xf3\xb6\xb3\x4a\xc3\xc8\xee\x61\xa8\x4e\x45\xa3\x41\x8c\x41\xaa\x94\x9b\x7d\x10\xf1\x68\x2f\xa5\xde\x33\xc7\xff\x04\x24\x49\x98\xd3\x03\x2e\x44\xc6\xf2\x67\xa5\x32\xd1\x51\x0a\xdb\x6e\x54\x86\xb8\x0d\x7c\xcf\xe0\xf3\x95\x7d\x3a\x53\x68\xf0\xd0\xe0\x05\x0c\x43\x7f\xc7\x73\x3e\xbf\xdc\x95\xec\x4b\x70\xaf\xbb\x86\x51\x4c\x44\xdf\x81\xc1\xae\x77\x7f\x36\xd2\xb8\x35\xab\xc1\x54\xea\x20\x98\x66\x14\x3e\x07\xdf\xa3\xa9\x3b\xca\x1f\xbb\xa8\x08\xf8\x92\xa0\x7c\x44\xae\xf7\xbf\x56\xce\x09\xbe\x54\x92\xba\x0d\x11\x33\x77\xd7\x58\x7a\x08\xa8\x1f\x59\xec\xd6\x53\x26\xde\x8b\xae\xb0\x0f\x82\xd4\xf7\xba\x54\xf1\x8b\xae\x6a\xae\x2f\x96\x5b\xfb\x4e\x97\x1b\x7d\x04\x5d\x5c\xdb\x3f\x83\x6a\x7b\x08\x2d\x01\xdb\x75\xd1\xd0\xd7\xb3\x0e\xa2\x10\x50\xcc\x69\x67\xad\x90\x8c\x1d\x75\x71\x55\x8e\x30\x0c\x8c\x4e\xfd\xc7\xdd\x4e\x84\xc8\x2a\x61\x10\x6f\x2d\x25\xc9\x78\xf4\x1b\x07\xc2\x01\xcc\x3a\x66\xfd\xdb\xda\x6c\xf6\xb2\x98\x10\x97\x86\x7c\xb1\xa0\x54\x17\x96\x73\x29\x87\xc4\x75\x0d\x23\x9c\xba\xa6\xa4\x05\x91\x3b\xe9\x6f\x6d\x5b\x62\xd0\x4e\x26\xd9\x76\xd7\x9c\x74\xab\xc2\xd0\x58\xbb\x2e\xdc\x64\xd7\x4b\x60\xf2\x07\xe4\x8a\x95\x30\x12\x4b\x77\x1d\x45\x0b\x7d\xcc\xaa\xc3\x77\x7d\x45\x8e\xd7\x74\x11\x98\xdd\x79\x78\x5e\xfc\xbe\x5b\x3d\x2d\xdb\xdf\x50\x94\xf5\x8c\xb9\xc9\x8d\x15\x62\x15\xa1\x79\x06\x45\x75\x2e\x01\x4f\xc1\x41\x4a\x6a\xfa\xaa\x84\x50\x44\xd0\x22\x21\xd3\x0f\xc8\xcc\x11\x6e\x04\x12\x5f\xf0\x38\x73\x0f\x91\xc6\x14\xcb\x2e\x66\xde\x6c\x5c\x9d\x0f\xa9\x0a\x51\xa3\x54\x37\xa7\x42\xf6\x1f\xd8\xed\x2d\x33\xf7\x24\xd0\x16\x18\x49\x90\xd3\xa1\x68\x33\x36\xee\x46\x2c\x91\x71\x87\x6e\xcb\x8a\xbd\xa9\x83\x1c\x0d\x25\x0f\x15\x32\xd4\x1c\x58\xf5\x8f\x73\x26\xde\xe7\xe7\x0b\xa2\x90\xfa\x41\x0b\xe0\x3c\x46\x1b\x6a\xa7\xb2\xdc\x94\xd7\xdf\x04\xed\xff\xda\x02\xe0\x3c\x56\x86\x99\xa4\xf1\x04\xab\x11\x30\x1e\x04\x61\x68\x57\xcd\x1f\xbe\xff\xee\xfe\x26\x53\xa3\xdd\x62\xd0\xb2\x6f\xa7\x69\x02\x3a\x90\xc0\xb8\xe3\xb8\xd8\x19\x16\xfb\xe1\x4f\x43\x1a\xc5\xbd\x84\xbf\xcd\x67\xd8\x46\x05\xb1\x41\x90\x30\x7b\xae\x5c\x91\x3f\x73\x45\x7c\xc0\xe8\x2c\x14\x72\xd7\xa3\x06\x73\xad\x51\x84\xb5\xce\x3b\x7e\x2e\x8b\x3b\x5d\xba\xbd\x77\x72\xca\x28\x22\x42\xe4\xa1\xfe\x70\xd0\x44\xf7\xf5\x14\x8d\xdb\x3c\xd4\xe6\x90\x9d\x6c\x5c\x63\xc5\xca\xe6\x4b\xce\x2f\x46\x63\xa4\x6f\x72\x28\x9a\x26\x18\xa2\x37\x7b\x8a\x2d\x66\xf9\xe5\x63\x11\x4b\xcd\x06\x53\x43\x79\x51\x8c\x18\x83\xac\x86\xae\x3a\xa2\xe3\x60\x76\xbd\x78\xc8\xd3\x2e\xd5\x5d\x8f\x80\xaa\xca\x03\x62\xf1\xf6\xab\xdc\xf8\xdc\x03\x4a\x1c\xe5\x7b\x11\xc1\x09\x98\xed\x0f\x50\xd5\x2b\x99\x35\x7d\x06\xa9\x1c\x15\x84\x3e\x66\x87\xed\xde\x61\xd9\x8a\x5c\x98\x49\x85\x9e\x0a\x4d\x91\x8a\x84\x13\x14\x12\x8a\xba\xb1\xce\xa0\xfc\xbb\xce\xa6\x74\xf7\x87\xaf\x19\x46\x46\xd2\x1f\xf5\x16\x59\x59\x5f\x39\xbe\x8e\xdc\x47\x45\x81\x8f\xe1\x2c\x97\x71\x58\x17\x0e\x01\x35\xf2\x65\x54\x1c\x98\x54\xea\x29\xab\xef\xc0\x2d\x6d\x15\x07\x02\xb7\xc7\x1d\x42\x98\xbf\x62\x04\x53\x71\x20\xd1\xa1\xe2\xe7\xf2\x32\xbe\x37\x27\x51\xcb\x7e\xb9\x39\x9f\x9a\xd3\xff\x98\x15\xd5\x23\x3b\x9d\x3a\xfb\x4f\xc5\x5c\xc9\x64\x48\x74\x36\x08\xc9\xab\x58\x25\xbe\xab\x73\xb4\x07\x41\x17\xd7\x6b\x6c\x7a\xe4\xc9\xd8\x96\x5a\x30\xf3\x0b\xc3\x9d\x43\x25\x8a\x23\xfa\x63\xbe\x98\x7f\x85\x3e\x51\x3c\x4c\x52\xb3\xe3\x7e\x00\xcb\xe7\x70\xc3\x45\x50\x3c\x09\xb0\xd6\xd8\xc9\x24\x94\x20\x5f\x4a\x50\xd9\xcf\xf1\xb9\x38\x7c\x0c\xe1\x4b\x2c\xba\x7d\x5c\x3f\xed\xde\x5e\xb0\x98\x71\xf8\x9e\x22\x4d\x9d\xe9\xd9\x13\x30\x1e\x0d\xaa\xe0\x91\xe1\xd7\x32\x64\x54\x1c\xa6\x51\x95\x4d\x3f\x95\xb8\x38\x33\x52\x33\x4d\x4f\x2a\x21\x62\x1c\x7d\x28\x64\x27\x52\x32\x91\xb1\x1b\xa4\x18\x7b\xc3\x2f\x84\x42\x87\xf0\x75\xf5\xfb\xf6\x9a\xb5\x76\x7a\xce\xc8\x50\xa4\x4e\xf4\xb5\xa8\xcb\xcb\xba\x58\xb2\xcb\x5f\x64\x41\x94\x14\xc2\x91\x13\xcf\xb5\xce\x3b\x42\xbd\xee\x59\xa4\x24\x51\xd2\xa9\x83\x5a\xbb\x7b\x2d\x47\xa7\xb2\x92\x8a\x43\xe4\x28\x38\x0b\x47\x4a\xf8\x02\xe5\x92\x8d\xe7\x30\x58\x3d\xa2\xe6\x6c\x62\x59\xf1\xa0\x45\xc7\x07\xdc\xca\xc1\xb8\xbe\x7e\xc8\x3a\x98\xee\x7b\x56\xec\xa7\x72\xd0\x0a\x02\xc2\x92\x4e\x29\xe7\x31\x1b\x63\x8a\x15\x30\x1f\x4b\x46\xd6\x25\x7b\x69\x29\xc6\x14\x70\x85\x4e\x87\xca\x54\x7d\xf8\x01\xf0\x6e\x40\x98\x3d\x37\x5f\x29\x42\x91\xdc\x99\x97\xba\xc3\x25\x28\xe5\x2b\xcc\xc2\xc0\x47\xb3\xdf\xb0\x1c\x56\x6d\xd2\x5c\x29\x91\xe2\x39\x22\xe1\x46\x28\x50\x29\x50\xaa\x33\x40\x7f\x2d\x4c\xa0\x94\x62\x18\xd8\x52\xcd\x94\x82\xd2\x64\x16\xaa\xa5\x0d\xe0\xda\x5f\x17\x84\xd0\x18\x69\x42\xef\x75\x2e\x33\xd1\xfe\x55\xf8\xe0\x12\xe6\x36\xbe\x67\x38\x14\x6d\x3b\xf5\x23\x74\xd1\x4d\x30\xe3\x43\xff\x84\xbc\x1a\x91\x0b\xf5\x17\xb6\x20\x34\x62\xbe\x21\xdc\xe2\x60\x27\x0e\xf5\x5c\x1b\x4f\xfc\xd6\xc3\xcd\xfb\x40\x15\xf7\x3d\x04\xf1\x42\xa2\x0c\x8a\xaa\xd9\xeb\x47\x70\x14\x41\xbc\x24\x06\xac\x4e\x29\xcb\x72\x14\xd5\x11\xc4\x13\x26\x1f\xdd\x6c\x16\x0a\xca\x5b\xb5\xa5\x82\xf8\xca\x48\xdb\xbb\x18\xfe\xae\xea\x81\x80\x04\x09\x42\x86\x2e\x74\xa5\x73\xb9\xd1\xe7\xfc\x4e\x0f\x0d\x24\x41\x82\x34\x72\xc7\xc3\xba\x86\x89\x82\x6a\x41\x02\x15\x1a\x14\xc6\xe9\xd4\x53\xc3\xb1\x8d\x21\x98\xb7\xdc\x43\x3d\x3f\x97\x85\x15\xfb\x7b\xcb\x8a\xba\x2f\xf5\x37\x18\xd8\x10\x68\x68\x82\x25\xc5\x99\xe5\xf9\xa5\x99\xcb\xd3\xa7\xc5\xe8\x65\xa3\x88\x18\xd1\x0b\x77\x8e\xb9\xa2\x09\xd7\x0e\xa6\xf2\x7b\x03\xf5\xf9\x74\x13\x55\xd0\x76\xe6\xa6\x16\x7c\xb9\xfe\xde\xb3\x06\x05\x49\x88\x61\xf1\xd8\x43\xbd\x04\x5e\x62\x64\xb1\x19\xd2\xbe\xe7\x9f\xb8\xbe\x01\x91\x66\xf3\xaf\xce\x79\x5d\x39\x62\x07\xd9\x21\x92\x05\x49\x13\x81\x98\x08\x26\xe5\xac\x28\x7e\x1b\x0c\x05\x23\x01\xee\xee\x55\xb6\x2f\xda\x32\xe8\x99\x34\x38\xfd\x7e\x61\x82\xeb\x1f\x7b\x48\x79\x87\x72\x43\x55\xed\x7e\x82\xf1\x20\x8e\x06\x3c\x2e\xb7\x64\x82\xc6\x06\x8e\x20\x9c\x1a\x33\xe8\x11\x32\xce\x8a\xfd\x4c\x88\xf3\x11\x61\x74\xba\x68\x9e\x07\x44\x66\xfe\x6d\xa0\x39\x7d\x1f\xfa\x56\x06\x57\x10\xce\x52\x6e\xd3\xe1\x6f\x9b\xe5\x62\xab\x5f\x4a\xfd\x91\x7d\x61\x57\xdb\xeb\x04\x25\x88\xa3\x60\xbb\x13\xcb\xd9\x47\xc9\xcc\xa0\x87\xae\x39\x34\x7e\x78\xdf\x4e\xea\x84\x43\x05\x11\xcd\xf0\x18\x04\xbe\xb6\x95\x15\xdb\x32\xdb\xef\xd1\x75\xb5\x7d\x24\x8f\x30\x11\xf0\x60\xb9\x74\xdd\x97\x54\xbe\x61\xdb\x7d\xd0\xfb\xb1\xe9\x3d\xfd\xac\x2a\x35\x4e\xbd\x21\xe9\x74\x93\xcd\xc8\xc8\x8e\x7a\x4a\x86\x65\xec\xc3\xba\xc4\xc1\x88\x51\x4a\x24\xba\x7c\x5b\xf6\xee\x26\x0e\xf5\x7c\xc3\x13\x8f\x75\x94\x2f\xec\xa2\xcf\xa3\x3d\x84\x7a\x89\xc2\x9c\x5c\xd9\x6c\x98\x26\xe3\x52\x8d\xbb\x70\x95\xda\xa3\x08\xad\x9c\x69\xc0\x81\xeb\xac\x7c\x9c\xaa\x27\x56\xd6\x05\x94\x74\xf7\xa1\x6b\x90\x3b\x43\xe2\xb0\x3b\x95\x50\x9c\xdd\x7e\x4a\x7d\x4f\x22\x58\xf5\xa5\xd4\x35\x6a\xfe\x1b\x1c\xd6\xd7\x5f\x98\xfa\x7e\x4c\x52\x07\x66\x40\xa0\xe0\x0b\x2b\xeb\x4c\x64\x27\x56\xd4\x7d\x8a\xf7\xc1\xd1\xd0\x5c\x27\x7d\x13\xf0\x3c\xe5\x1a\xab\xfc\x7a\xf3\x9f\xfa\x81\x20\x26\xa6\x88\x8a\xb5\x53\x35\x37\x82\xfa\x32\x65\x51\x57\x4f\x5f\x40\xe9\x16\xc9\xf0\xa4\x17\x34\xf0\x02\x25\x07\x22\x5a\x9f\x06\xa6\x3f\xee\x17\xca\x84\xb4\x51\x3f\x83\x23\x40\x1a\xaa\x7b\xf6\x97\x8a\xf0\x5f\x7a\x90\x82\x06\x22\xc2\x38\xb1\xdd\xe1\xa6\xc8\x17\x6f\x5c\x19\x52\x53\xcf\x6b\x54\x79\x4f\x57\xc4\x1e\x82\x86\x61\x8a\x64\xb7\x68\x61\x5b\xf9\xdd\x16\x3b\xd5\x34\x33\x84\x8c\x3f\xb2\xba\xbc\xf4\xab\x52\x05\x8d\x29\xc5\x63\xe9\x7e\x76\x3f\x7b\x75\x89\x66\x41\x63\xc1\x99\x91\x99\x38\xea\xa2\xea\x31\xd6\x2f\x4b\xdd\xce\x97\x58\x86\x24\xea\x53\xea\xe1\xf6\x36\xfd\xb5\x93\x30\xc2\x60\x0a\xd6\x21\x34\x7b\xe9\x03\xab\xb0\x86\xad\x5d\xc7\x34\x89\x02\x5b\xbf\x02\xac\x3a\x97\x17\x8b\x40\x1f\x4f\xff\x24\x0e\x51\x58\x43\xe9\x52\x34\x16\x4c\xc7\x7e\x25\x68\x22\x21\xe8\x54\xb8\x46\xec\x1c\xb6\x4f\x1a\x70\xcc\x7c\x9d\x4a\x58\x0b\x8d\xa6\xf5\xbc\x93\x74\x17\x34\x15\xb1\x2b\xb2\xfc\x1d\xe0\xb4\xaa\x0f\x9d\x97\x21\x28\xa3\xbe\x1a\x11\xf7\x0d\xe6\xc5\x35\x75\xdd\x60\x53\x60\x34\xc1\x28\xde\x4e\xb0\x5c\x20\x59\x44\xd9\x41\x55\x04\x65\x7e\x12\x59\xd2\x00\x03\x56\x9b\x62\x03\x10\x94\xc5\x14\xa1\x11\xcd\x63\x37\x06\xee\x95\x90\x82\xa0\x8c\x19\x68\x92\x60\x79\x6d\x26\xfa\x70\x14\x99\x8c\x31\x1c\x89\x8d\xe5\x3f\xce\x2d\x1a\x56\x50\x4e\x03\x65\x52\x63\xfa\xe7\x05\x53\x5a\xc3\x4b\xb9\x88\x91\xa4\xdf\x2a\x1f\xd8\x78\xd7\x84\xbd\x45\x05\x0d\xf0\x73\x34\x26\xa5\x8d\x07\x8c\x5f\x45\xf8\x46\xb1\x7b\xa0\x10\xee\x9e\x44\x70\x1f\xd9\x65\x9d\xfb\x3a\x3f\x5f\x4c\xc9\xa3\x6b\x97\xa9\x15\x83\x04\xb9\x13\x3a\x2b\xaa\xdd\x07\x3b\xe7\xb5\xe7\x3a\x48\x62\xa4\xa0\xcd\xa3\x5e\x95\x5c\xfc\xad\xf7\x61\x65\xa4\xc0\xeb\xf0\x7c\xdd\xd9\x38\x78\x77\x09\x80\x15\x92\xaf\x8d\x87\x7a\x1a\x38\xd2\x93\x79\x04\x41\x81\xc6\xd2\x26\xa7\x6c\x9e\x73\x38\x00\x10\xc4\x98\x83\x7f\x7e\x5d\xcc\xdc\x63\x43\x1c\x85\x6d\xcd\x18\xf2\x36\x66\x9d\x45\x3b\x79\xd8\xa8\x58\x20\x78\x1d\x37\x00\xac\x3f\x99\x39\x02\x4f\x7b\x53\x8f\xa4\x04\x85\xa7\x9e\x74\x79\x44\x40\x0d\x92\xda\xb7\xad\x96\x9a\x6d\xfb\xbc\x9d\x3d\xec\x90\xc4\x60\x31\x7b\x71\xad\x94\x08\xcc\x27\x7e\x96\x8d\xc5\x58\xb6\x7f\x8e\x98\xc3\x86\xa2\x5e\xbd\x81\x16\x77\x83\xea\xd1\x44\x44\x56\xd8\xae\x79\xe6\xf5\xe2\x79\x50\x56\x22\x3c\xca\x4d\x72\xbb\x73\x61\x1c\x6d\xd6\x60\x14\x3d\x8f\xa7\x08\x83\xdc\x1d\x41\xb2\xfc\x0e\x99\x1d\xc7\x5d\x04\x20\x0a\xce\x4d\x16\x64\xa6\x6e\x0f\x14\xcf\x27\x6d\x2a\xf1\x1b\x94\xfa\x89\x1d\xc7\x37\xf0\x3d\x3f\xb1\x94\x67\xb3\x0b\x2b\xea\x65\xa9\xb3\x7a\x25\x74\xa1\x8f\xd9\xbf\xcf\xb0\xb3\x0a\xc4\x91\xbb\x63\x10\x09\x0c\x47\x20\x29\xe4\xf6\x79\xb7\xd9\xce\x1e\x56\x8f\x2d\x37\x91\xf0\xc2\x08\xb0\x98\xfd\x35\x83\xf7\x0e\x5b\x2a\xbc\x50\x79\x91\x63\xa4\xab\xf5\xae\xd5\xe7\x1a\xce\x0c\x2f\xa2\x86\x01\x2a\x37\x5a\x32\xc3\x28\xe6\xf0\xd1\xa3\x38\x40\xe1\x9f\x0f\x9d\x9f\x8f\xb0\xbd\x9c\x20\x76\x3f\x16\x13\x81\x78\x73\x61\x4f\xc6\x37\xb7\x7d\x7b\x09\x11\x18\x07\x7b\x9c\xfd\xd1\x3c\xfb\xd3\x72\xf6\xba\xdc\x6d\x66\x0f\xab\xdd\xcb\x6c\xf1\xfb\xa6\xed\x46\x0d\xbd\xb0\x21\x50\x9c\x92\x4c\xbf\x3a\xb1\xbc\xc4\x0b\x30\x55\xed\xac\xd7\x39\x13\xef\x8f\xb3\xa7\xd9\x8d\xc7\x4f\x7c\x85\xf3\x7d\x55\x96\xba\x9c\xda\x49\xbc\x24\xf1\x13\x3e\xa8\x4b\xed\x47\x39\x84\x97\x28\xcb\xd3\x67\x12\xeb\x2d\x59\xdd\x20\x9f\x2c\xbc\x34\x96\x1e\xc5\xe8\x65\x21\x97\x59\x25\xae\x6a\x3e\x85\xc7\x44\x12\x59\xe1\xca\xcd\x11\xe9\x79\x4f\x3f\xdc\x07\xea\x19\x36\xd5\xcd\xa2\x57\xe1\x31\x50\xd2\xb3\x25\x5f\xd9\xfe\xab\xe1\x1a\x8d\x83\x48\x38\x6f\xe9\xab\x87\x09\x5a\xe1\xc9\x20\x8c\x6c\xdc\xc3\xe4\x5f\x17\x56\x86\xed\x9e\x55\xd7\x64\x5f\xc2\x93\xb1\x70\x54\x4b\x4f\xf0\xb3\x7e\x30\xc5\x08\xdb\xed\x0f\x4b\x98\x66\x30\x4b\x36\x54\x28\x3c\x20\x01\xfa\xbf\xed\x6c\xc4\x9a\xd8\xa9\xb7\xbc\x7a\x5f\x20\x51\xc0\x3b\xb1\xe1\xc5\x8f\x45\xf5\x02\x28\x6a\x33\x29\x35\x2c\x3c\xf0\x04\x5a\xe6\x7f\x7f\x7b\x58\xcf\x50\x96\xe0\x75\xb5\x69\x27\x9c\x22\xc4\x68\x21\xe8\x7c\x54\x73\x22\x7c\x12\x9b\xf2\x75\x8c\x93\xf7\xea\xec\x84\x4f\x24\x43\x39\x1b\x43\x8a\xf1\xcd\x08\xe1\xda\x36\xea\x11\x66\xca\xc9\xf6\x5f\x69\x9b\x7c\xfd\x75\x7c\x9a\x18\x5f\x65\x8e\xcc\xce\xbb\x39\x2b\xde\x77\x8d\x4b\xb1\x6b\xa5\xa4\x6d\x47\x9f\x1a\xee\x5f\x0c\x9a\xf6\xb8\x32\xc6\x2f\xe3\x47\x2a\x1e\xe6\xeb\x17\xba\xa8\xa0\xa8\xce\x03\xac\xb9\xf0\xc3\x10\x10\xd6\xb7\x6b\x0c\xc7\xea\xd4\x45\x7a\x84\x1f\x72\x89\xd9\x83\xea\xcc\x77\x95\x29\xc6\x98\x4a\xbb\x08\x3f\x14\x06\xaf\xe6\x96\x64\xf3\xe4\x08\x71\x84\x89\xd2\xa5\xc1\xe2\xf3\x23\x22\x31\xb4\x87\x2f\xf1\x63\x70\x04\xf8\x71\x18\xe3\xc6\x2c\xb3\x8e\x5b\x75\x72\x91\xfb\x71\x1c\x62\xcc\x5b\x65\xb9\xc1\x42\xb5\x4c\xe4\xa3\x61\x49\xc0\x18\x68\x46\x89\x58\xde\xe9\xf2\x1b\x2b\x64\x0e\xc3\x25\xef\xa7\x94\x60\xca\x98\xb3\x3c\xd7\xed\xd8\x0b\x2f\x16\xa6\x94\xaf\xd2\xf9\x87\x03\x8d\x9a\xe0\xfa\xa4\x9f\xe6\x8b\x20\x85\x56\x44\xb5\x7c\x6f\xfe\xf7\xbd\xcd\x4f\x9b\x1a\xea\xab\x00\x8a\x2f\xd2\xd4\xc8\x2f\xa3\xb8\x87\x1d\xd2\xf1\x8b\xbb\x05\xe2\x0b\x1e\x7b\x16\x76\x38\xbb\x41\x05\xeb\x7a\x4a\x65\xe0\xac\xb3\xa7\xfb\xd5\xea\x69\xb9\xa3\xc4\xbd\x99\x24\x61\x2c\x7b\x14\xac\x67\xb9\x87\xe9\x2c\x8d\xf0\x65\x48\x92\x1e\x6f\xba\x05\x29\x77\x11\x0c\x5f\x26\xa1\xa3\xb1\x5b\xfd\xcc\x8c\x12\xe5\xe8\x33\x48\x61\xa0\xd5\x5b\x5d\xea\xa2\xd6\xaf\xe7\xfc\x66\x35\x5c\xd3\x39\xc5\xe2\xc8\xaa\x35\xa7\xc7\xd1\x3a\x1f\x22\x8e\xc9\xdc\x1a\xaa\x7a\x83\x80\xee\x57\xc0\x13\xa9\x67\xa4\xf8\x10\x4b\xcf\x46\x84\x17\x07\x96\x15\x17\x74\x29\x06\xdf\x4b\x89\x00\xf9\x04\xf1\xe6\x16\x4b\xd1\xe3\xd6\x16\x01\xf1\x13\x2c\x1a\x33\xcf\x68\x44\x2e\x6c\x13\x4d\x0c\x2f\x6f\x9b\xa1\x9c\x74\x56\x02\xca\x03\xd4\xe0\x41\x52\xd2\x3c\x2b\xf6\xae\xa4\x6d\x72\xb4\x03\x4f\xf8\x60\x29\x79\xcc\xa1\x03\x16\xf0\xe4\xda\x81\xd9\x2f\xf7\x2f\x10\xfd\x98\xda\x64\x30\x2d\xf0\x94\x4f\xa8\x03\x36\xfe\xac\xef\x74\xd9\xb8\xc0\x68\xe7\xcb\xf6\x96\x2a\xc0\xfc\x26\xd7\x35\x16\x47\xb8\xbf\x07\x44\x52\x14\xbb\x6c\x9c\xe6\x19\x96\x5d\xba\xa6\x90\x50\x83\x55\x39\xe5\x59\x3d\x90\x5a\x77\x1d\x28\x4d\x9c\x78\x24\x3b\x5e\x67\xd9\xdb\x6e\x49\xd8\xc6\x30\x36\xb5\xf1\xcf\x0f\xd9\xa9\x3d\x2a\xbc\xee\x84\x88\x6d\xb6\xbd\xad\x2a\xb2\x02\xa0\x22\x08\x63\xa3\x44\xbc\xfa\x79\xd2\xd5\xb9\x84\xe7\x13\x14\xd7\xa2\xc2\x93\x3b\xf2\x50\x36\x5a\x04\x11\x91\x0e\x9e\x62\xb6\xd9\x5b\x74\x3d\xae\x3f\x33\x13\xfb\xf9\xe4\x28\x78\xa7\xa8\x5a\x45\x10\x29\xe6\x39\xbd\x8e\x55\x25\x4a\xfd\x79\x63\x44\xe2\xc0\x40\xb7\x56\x2f\xcf\x8b\x6f\xbb\x87\xd5\xd3\xbd\xc3\x46\x8a\x20\x0e\x13\xe4\x04\xdd\xb2\x77\xa6\xce\x0e\xa9\xdd\xfc\xdd\x54\x85\xa2\xdd\xdc\xac\x15\x7d\x6e\x27\x70\x1c\x31\x24\x21\xea\x6d\x47\x37\xb3\xd7\xa3\x27\x49\x13\x9b\xba\xac\xce\xb0\x80\xb2\xce\x14\x6a\x9f\xfd\x36\x09\xc9\x18\xdf\x73\x30\x0b\x13\xc2\x54\xda\x13\xc7\x29\x2b\xa7\xe3\x32\x3a\xc6\x82\xc4\xe3\xca\x6e\xb9\xe7\x23\xec\x5e\x5e\xd7\xdf\x67\xdb\xd5\xa6\xa5\x00\x16\x41\xc2\x25\x2e\x3b\xa8\x0f\x6f\x9b\x65\xfb\x57\x25\x90\x53\x1a\x59\x6e\x0e\x60\x39\x38\xb2\x96\x4b\x4a\x04\x29\xe1\x24\xb1\x7c\x33\x07\xd6\xfe\x55\xca\x50\xb4\x4e\x7e\x33\x76\xfd\x28\x95\xed\xc4\x62\x63\xce\x80\xd0\x8d\x99\xd0\x87\xc9\x8b\x80\x71\xe3\xc4\x1f\x58\xf5\xaa\xf3\xe9\xcc\x59\xd3\x8b\x61\x1c\xbd\xb9\xbb\xc5\x86\x74\xd8\x0f\x11\x70\x8f\xa3\x88\x74\x01\x9f\x1d\xe9\xef\xa8\xf6\xe6\x6f\x93\x5f\x89\x33\x53\x93\xdb\xec\xce\xce\x1f\x9a\xfe\x9e\x5c\x86\x18\x3d\xb5\x6a\x3c\x16\x0f\xe1\x1a\x41\x46\x49\x8b\xa4\xfe\xa6\xcb\x0a\x2e\xe3\xe4\xde\xc0\x29\xed\x63\xdb\x45\x20\xbc\x10\x03\xd5\x1f\x3a\x6b\xb7\x15\x91\x18\x45\x48\x56\xee\x17\xe7\xb2\x85\xff\x8a\x40\x40\x4b\x14\xea\x42\x12\x53\x69\x44\x11\x08\x65\xc8\xbb\x05\xcb\x85\x2d\x7f\x1c\x76\x90\x1e\x20\x7c\xd7\x04\x82\x8c\x02\x62\x09\xb0\x64\xed\xd7\x91\x09\xf3\xda\xac\xdc\xc9\x6a\xbc\xcf\xea\x5a\x8f\x8b\x5c\x44\x20\xd3\x08\xa7\x42\xa1\xeb\x7f\x42\xa9\x67\x85\x7c\xd2\xf5\xc6\x50\x7c\x8f\x7e\x56\xca\xd4\x4c\xd2\xba\xcc\xe0\x63\x8a\xca\x5a\x04\x52\x11\x2c\xea\x40\x61\xf2\x4c\x17\x7d\x54\xb0\x08\x20\x8a\xe3\x01\xcf\x47\x39\xa1\x81\x7c\x25\x51\x79\x95\x9e\x14\x01\xc4\xbe\x32\xe0\x00\x7d\xd2\x15\xbc\xc2\x07\x94\xd5\x58\xc3\xc7\xf5\x05\x25\xdc\xa6\xac\x73\xd9\x1c\x87\x83\xa8\x59\xa0\xb8\x67\xc1\x1d\xcd\x11\xd5\x58\x9b\x28\x0d\xdd\xfd\x5c\x48\x62\x43\x30\x80\x39\xb8\xac\xd8\x6f\x81\x1d\x4d\x74\x69\xb4\x92\x43\x92\x12\x47\x58\x6b\x12\x60\x98\x09\xae\x7e\xcf\x6a\x64\x0e\x9d\x9c\xa3\x21\x61\xa6\x42\x96\x43\xad\x74\xd9\xa3\x46\x68\x9a\xd4\x20\x89\xb1\xfa\xd9\x1c\x48\x66\xe8\xb7\xda\x51\x08\xbb\xce\xdc\x73\x02\x1d\xbd\x1f\x77\x95\x71\x93\xb3\x2d\xa4\xc4\xb8\xc8\x56\x1a\xee\x8a\x0f\x4f\x84\xd4\xa3\xe8\x5a\x5a\xb2\xba\x51\x89\xe0\xe0\x45\x28\xf3\x31\xf8\xb6\x3b\x17\x27\x86\x4a\x49\xd7\xe9\x9a\x90\x32\x83\x6b\xee\x9b\xd1\x26\xec\x31\x69\x1b\x84\x54\xfa\x68\x4a\x54\xc7\x2c\x87\x4b\x3f\xba\x15\x7a\x71\x8c\x31\xd6\x1a\xd8\xd1\xec\x4f\xd1\xa3\x2e\xea\x43\xfb\xec\xa1\x67\x2a\x95\x3a\xff\x60\x79\x7e\x07\x54\x9b\xea\x6f\xd5\x61\x18\xfa\x58\xfb\x71\x6a\x2c\x81\x61\xf5\x5b\xd3\x18\x32\x36\x10\xae\x1e\x0a\xcd\x88\x30\xf2\x22\xfc\x80\x46\x2f\xa3\x17\xa8\x08\xa3\x28\x0d\x7d\x57\xdf\xa8\xca\xf1\x58\x44\x22\x44\x80\xd3\x91\xbd\xc3\x12\x58\x7e\xa7\xcb\xed\xa7\x9e\x74\x3f\xc2\x48\xa5\x49\xab\xd3\xcb\xf2\x09\xb1\x4b\x11\x26\x49\x88\xa4\xcc\x12\x72\x76\xb1\xd9\x11\xd7\x94\x86\xca\x86\x9a\x37\x3a\xcb\xbf\x9d\x8f\x18\x13\xb3\xda\xae\x58\xf2\x5f\x8d\x5e\x2b\xa5\x10\x18\xfa\xc8\x1c\x04\x12\x30\xff\x6a\xdc\x7e\x6a\x21\x86\xa9\x97\x62\x00\xbb\xd9\x5d\x5e\x4a\xc7\x7f\x2d\x5d\xa8\x31\x4c\x01\x80\xdb\x30\xc9\xc7\xc0\x7f\x70\x7e\xd1\x23\x54\x15\xdb\x5f\xf3\xa0\x0f\x76\x0e\x77\x37\x45\xa4\xcd\x30\x7e\xa5\x6c\x69\x7b\x33\x66\x94\x3d\x6b\xbd\xd5\x35\x3c\x64\xff\x3e\x67\x92\xd5\xba\xec\x13\xbc\x8a\x90\xfb\xa9\x61\xa2\x41\xe5\xb0\x81\xd4\xed\x8d\xc9\xcb\x7d\x53\x3b\xf1\x98\x89\x03\x83\x9c\x12\x4a\x07\x33\x58\x24\x21\x86\x9d\xaa\x5a\x97\x80\x8b\xa5\xff\x0e\x22\x31\xb8\xb5\x0a\x0a\xd9\x66\xd3\xc6\x3f\x38\xfd\xc3\x22\xa5\x0e\x4c\x54\x38\xa8\x8f\x6b\x02\xe2\x9b\x49\x57\x96\x19\xdb\x03\xea\x64\x2f\xb5\x68\xdb\x55\x2b\x5d\xfe\x58\xed\x6d\x89\xe7\x68\xa2\x49\x4f\x62\xc1\x40\x7d\x39\x0d\x02\xce\xa1\x8c\x62\x0c\x68\x36\x47\xbe\xad\x7c\xad\x86\xfb\x89\x4c\xe2\x20\xb4\xa4\xa3\xcd\x87\xdd\x9c\x40\xa0\x82\xbd\x39\xec\xaa\xab\xf3\x60\x7a\xd3\x84\x38\x8d\xe3\x8e\x32\xa8\xdc\x1e\x4a\x68\x77\x42\x48\x28\xe2\x8a\x0e\xa6\x1a\xce\xae\x84\xe1\x74\x04\x91\x82\x83\xc6\xa2\xda\xb7\x0b\xcc\xf5\x36\x7e\x95\x52\x2b\xb7\x01\x1f\x99\x3e\x57\xa6\x32\xce\xbd\x4a\x44\xa2\x04\xa3\x4d\x59\xf5\xa4\x6b\x54\x84\x6a\x4f\x95\x88\xb0\x08\xe3\xb2\x27\x76\xb1\x95\xcd\xc3\x21\x8c\x08\xe7\x08\x43\x38\x57\xf6\x14\xdf\xd4\xac\x9e\x2e\xb8\x10\x11\x11\x69\x64\x11\x77\x68\x48\x3e\xb6\x1a\x44\x22\x22\x92\x21\xe8\xd3\xf0\xe6\x36\x56\xa3\xef\x9a\x28\xa4\xb8\xbf\xd8\xdd\xfd\x1a\x87\x35\x89\x09\xb4\x17\x7b\x81\x42\x0f\x5d\x38\xe2\x9c\xfe\x87\x8e\x3c\x69\x30\x58\x0e\x0e\xd7\x89\xd7\x55\x2f\x46\x29\x60\x2a\x0c\x19\x79\xe0\xe1\x01\xd9\x99\xd6\x99\x2e\x36\x50\x7f\xc5\xf2\x25\x22\xdf\x23\x18\x38\xda\xbc\xbc\x0e\x1e\xc2\x8f\x05\x82\x6a\x5d\xc9\xc7\x76\x94\xc4\x89\x02\x9a\x62\xd4\xf3\x75\xf3\xf2\xb0\xdd\xdd\xbb\xeb\x82\x30\x92\x06\xb1\x09\xf5\x1d\xcb\xf2\x9e\x6a\xc6\xc4\x40\x04\x51\x8c\x15\x48\xc8\x81\xe0\xb6\xab\x28\x8c\x22\xdf\x31\x6e\x1b\xb3\x1e\x99\x5c\x4f\xbd\x6f\xd8\x1b\xdb\xc4\x5d\xc5\x3d\x0c\x1b\xf4\x73\x98\xb7\xb6\xb3\xe1\x18\x44\x71\x6c\xca\x69\x90\x9b\x9e\xe5\xf9\x36\xdb\x1f\xea\xfc\xf2\xc2\x9a\x6d\xe8\xb7\x21\xeb\x84\x88\xe2\x24\x44\x7e\xa0\x59\x59\xf7\xa4\xfc\x45\x94\xc6\x0a\xe7\xec\xe6\xfd\xb2\xf9\xb4\x3c\x3e\x6d\x9b\x20\x88\xd5\x37\x19\x1c\x83\xb1\x1e\x46\x2d\x86\x8f\xc4\x3c\x43\x6c\xbb\xfb\x1c\x89\x02\xb9\xf6\x40\x46\xc6\x6e\xd2\xeb\x6e\xbe\xb2\x88\x38\x7a\x55\x9b\x10\xf0\x83\xb6\x4d\x79\xed\x21\x87\x70\xf6\xe9\xb1\xe0\xc4\xc8\x6e\xad\xef\x16\x0b\x77\x29\x4f\x00\x01\xc4\xce\xae\x78\xe8\x27\xde\x27\xbe\x2a\x6f\xf6\xde\x56\x4b\xf5\xd4\x8d\x90\x08\x3d\x57\x11\xff\x03\x9a\x31\x1e\xcd\x29\x49\x0c\x3f\xef\x09\x4a\xa5\xcb\xa3\x49\x62\x35\x1f\xe4\xc5\x09\x80\x34\x7d\x94\x61\xf6\x41\x4a\x3d\x5c\xb2\xa3\xb1\x91\x49\x2b\x6d\x30\xce\x08\x0c\x16\x8c\x64\x29\x26\x02\xfe\xfd\x09\xa5\xe8\x7d\x47\xa0\x1e\x66\x25\xda\x73\x61\x55\x48\x90\x96\x28\x0a\xfd\xe4\xe9\xa1\x03\x4f\xa2\xfa\x39\x9a\x99\x18\xfc\x69\xcc\x74\x76\x6a\xf5\x15\x44\x04\xdc\x68\x95\x2f\x32\xdd\xcc\x9c\xd5\xeb\xc2\x8b\xbe\x60\x1c\x1b\xff\x00\x24\xa1\x91\x8d\xfd\xbc\x67\xc5\x35\x3f\x78\xd3\x83\x99\x1a\x6b\x60\x47\xab\xae\x7e\x32\x54\x25\x6c\x0f\x3b\x4c\xc0\xb9\x47\x51\x40\x70\x1c\xb1\xf2\x4f\x96\xfa\x34\xfc\x16\x31\x21\x51\x14\x3a\x09\x2c\x5b\x24\x3c\x3f\x8f\x8b\x84\x9b\x7e\x10\xf5\xb4\x67\xf7\x03\x0b\x2f\x26\x89\x22\x43\xf9\x6f\x90\x18\x82\x43\x3e\x9e\xc1\xc3\xc7\x84\x51\xb0\xb3\x77\x6b\xd2\xec\xed\xc9\x1a\x13\x88\x84\xc9\xf9\x7f\x40\xbe\x4b\xdd\x5b\xb9\x66\x4a\x02\x27\x93\xff\xac\x26\xa2\x9d\xae\x1b\x15\x68\x33\xb8\x45\x85\xd8\xfc\x99\xe3\x50\x10\x31\x65\x5c\x5a\x42\x12\x5b\xbd\x32\x96\x31\x12\xb1\xe7\x99\x4a\xc7\x3d\x0c\x21\x02\xb1\x27\x4c\xfd\x4a\xe3\xb8\x5b\xaf\x69\x60\xf4\xc5\x9e\x90\xb8\x6f\xcc\x11\xf8\xb8\x1e\x7b\x9f\xb1\x0f\x29\xb6\xe7\x06\x7d\xe0\xaa\xba\x6c\x6b\xc0\x85\xa5\x6a\x51\xec\x9c\xd7\xc6\xf7\xf8\xfb\xb9\x74\xfc\x17\x22\x0e\x94\x87\x98\xcd\xb9\x6e\x5e\x0b\xce\xc7\x2f\x80\xc4\x22\x8e\x62\xc3\x7e\x5a\x43\x85\x1b\xf5\xba\x86\x23\x52\x80\x62\xf0\xb3\x2d\xc1\x71\xbd\x59\x80\xfc\xf0\x02\xc5\xdb\xab\xd9\x07\x94\x58\x56\xd9\x47\xc5\xbb\xae\x8a\xa3\x90\xc4\xbd\x91\x22\x75\x77\x88\x89\x51\xe9\x42\x3e\xaf\x23\xc8\x36\x30\x3d\xb9\x98\xe2\x38\xe1\x48\x7b\x67\xce\xd7\xbf\x0a\x17\xb9\x8b\x80\xa3\x03\xf4\xcf\x21\xcf\xa2\x88\x13\xaa\x90\xab\x6e\x5b\x9e\x2d\x80\x14\x99\x9d\xbf\x1c\xa0\x24\x05\xb4\xf3\xe6\x79\x56\xc8\x5b\xa5\x8e\xc3\x57\x4f\xa4\x30\xfb\x17\xbb\x20\xb5\x81\xfd\x73\xea\xb3\x88\x4c\xd9\x0a\xae\x3d\x31\xcc\x08\x82\xe5\x48\x29\x07\xb3\xb2\x6e\xb6\x87\x41\x60\x28\x4e\x13\xe9\xac\x2a\xcc\xb5\xec\x58\xc9\xb3\xba\xda\x55\x63\xda\x5e\x11\xa7\x2c\xe0\x76\x9f\x35\x41\x68\x13\xad\xc3\x7f\xeb\xb2\x1f\xff\x8d\x19\xe5\xa1\x31\x59\x7f\xb6\x39\x12\xd7\x14\x7b\x98\x94\x37\x51\xb6\xd5\xf6\x9b\x0d\x77\x2c\xa0\x15\x98\x16\x31\x4b\x43\x19\xb6\x95\xee\x9b\x43\xa9\x47\x34\x9f\x22\xe6\x69\x82\x85\x63\xb9\xae\xcf\x95\x31\xfb\xe3\xf0\x45\xb4\x8b\x97\x73\x8f\x77\x14\x09\xe8\x95\xb4\x60\x88\xf3\x95\xa4\x90\x88\x85\x64\xa1\xdf\x9e\xa5\x6e\xae\xce\xf5\x78\x3d\x49\x61\x52\xdc\xf3\xca\x9a\x04\xbb\xcd\xd3\xf3\xf7\xaf\xad\xfb\x18\x28\x38\x69\x0c\xdc\x1d\x5e\x4a\x2d\x00\x30\x5e\x7d\x1d\x30\x8a\x15\x31\xe2\x9f\xed\x97\xfb\xd1\x1e\x23\xb1\x4a\x0d\x40\x64\xf6\xb6\xfd\xb6\xdb\xac\xb6\x8f\xeb\xa7\xed\xec\xf1\xf9\xed\x69\xdb\xf6\x10\x1e\x6e\x9d\xc7\x5e\x74\x71\xf8\x34\x4a\x31\x44\xfd\x9d\x4f\xf2\x8a\x03\xe3\x86\x67\x38\xe5\x20\x26\x84\x70\xcc\x4b\xb8\x13\x7c\xc1\x0a\x56\x1a\xca\xca\x7e\x78\xdc\xf6\xf6\x3c\x1f\xe3\x51\x26\x6c\x63\xc4\x75\xdc\xb2\x1b\x6c\x69\x89\x17\x18\xb8\xf7\xe6\xdb\xea\x8f\xbf\x06\x6a\x26\x5e\x44\xb1\x52\x4f\x23\x61\xd1\x4b\xa9\xf7\x65\xbb\x4a\x12\x2f\xf1\xd0\xca\xd8\xc9\x7c\x5f\xbf\x0e\xa5\xa0\x45\xe2\xfb\xe6\x97\x90\xda\x38\x2b\x2a\x28\xeb\x9d\xca\x8c\x56\xc3\xb7\xac\xc0\x6c\x84\xb1\x17\xbe\xb5\xe4\x99\x22\xf1\x93\x38\xb6\x29\x1b\x66\x57\xf0\xaf\x96\xf0\x7c\xb1\x35\x24\x7e\x92\x60\xe0\x44\xb0\x3c\xaf\x0f\x59\xd5\xfe\x1c\x03\x64\x0c\xba\x9f\x3d\xf6\x15\x3b\x45\xe2\x43\x82\xa4\xf6\x73\xfd\xfe\x7e\x79\xd1\x7a\xce\x0e\xd5\xec\x5c\xeb\x42\x1f\xf5\xb9\x32\xdc\x34\xac\x3e\xe8\xa2\xe3\x8a\x13\x49\x00\x12\xe1\x96\xdb\x12\xa3\x7d\xad\x15\x91\x84\x91\x47\x6d\x10\xf2\xe9\x6c\x39\xe4\x9a\xe3\x79\xfb\xb8\xc2\xca\x14\xdb\x2d\x22\x0c\xa1\x79\x3b\x27\x94\x0c\x65\x7d\x99\x5f\x06\xc4\xec\x93\x4c\x99\x22\x89\x02\x0a\xd0\xd3\xd3\x6a\x9e\xef\x0b\xd0\x57\x12\x05\x09\xe6\x3b\x8f\x59\x51\xdf\x81\x0b\x60\x4e\x6d\xec\x49\x94\x0a\x47\x56\x6e\x52\x7f\x13\x80\xa7\x24\x89\x08\xc2\x3f\x9c\x64\xd1\xca\xb0\xce\x49\x64\xc1\x1d\xae\x91\x24\x11\x89\x34\x55\x5f\x65\xa6\x2e\xb3\x42\xba\x18\xc3\xed\x3a\x80\x5f\xca\xa9\x27\x89\x52\xe8\x87\x29\x68\x99\x32\x56\xf5\x61\x42\x0c\x4a\x24\x29\x31\xdc\x2d\xe7\xa2\x42\x88\xbe\xfe\x04\x89\x39\x83\x3e\xff\xc1\x68\x4d\x32\xcf\xa8\xb8\x9a\x31\x46\xf9\x94\x83\x15\x1f\x1b\x75\x0c\x93\x80\xb5\xfb\xa3\x81\x7e\x8e\x81\xf5\x09\x63\x1e\xfa\x4c\x83\xa4\xef\xf7\xf5\xcb\x6d\x28\x48\xc2\x80\x0d\xc0\xfc\x6f\x45\xe5\x38\xdb\xdd\x14\x6a\xfc\x7d\x4b\xe6\xf4\xa0\xbb\x93\xbe\x9f\x46\xf3\xc7\x69\x34\xdf\xdd\x5f\x46\x04\x4b\xcb\xcd\x73\xbb\xb4\xe2\xf0\xb1\x65\x14\xf9\x16\x8e\xf2\x88\xf4\x6e\x4f\x5a\x5e\x3b\x45\xa3\x0f\x23\x45\x84\x39\x8a\x9d\x04\xa1\xe5\x55\x70\x27\x81\x24\x41\x49\x49\x8b\x24\xde\xe8\xfc\x03\x0a\x71\x19\x7d\x33\x15\xfa\x58\x49\x05\x47\x28\xf7\x4d\xfb\xb2\x64\x37\x64\x30\x44\xa2\x98\x81\x88\xb6\x85\x0f\x1b\x76\x84\x9d\x8d\xab\xec\xb4\x42\xaa\xf5\xba\xda\xd5\x7a\x77\x64\xc5\x65\x67\xef\x02\x13\x50\x1c\x77\x47\x2e\x11\xfe\x67\x36\xad\xc6\x5b\xdd\xb2\x72\x3f\xb6\x0d\x52\x42\x04\xd2\xd2\x9d\x0b\x17\xda\x1f\xe2\x05\x6c\x37\x4f\x05\x98\xf0\x69\x76\x24\xc9\x6a\x26\x4e\x5f\x6b\x6e\x37\x57\x48\x87\xe7\xd9\xb0\xdc\x64\x8f\x6c\x41\xf6\xa8\x67\x40\x12\x53\x05\x00\xf5\x73\xf1\xa0\x3f\xbf\x65\xfb\x3e\xec\x34\x0d\xe3\x34\xec\x8f\xcd\xd2\x66\x28\xaa\x71\xc6\xd4\xf5\x67\x9e\x91\xd0\x30\xf6\xd0\x73\x99\xed\xb3\x82\xe5\x2f\x2c\x2b\xfa\xf1\xb0\x1b\xcf\x1d\x72\xc0\xcf\xd6\x1c\x04\x99\xb0\xe2\x14\x22\x8d\x7c\x82\xf4\x67\x27\x53\x13\x71\x5f\x32\x79\x66\x46\xe4\x9e\x55\x43\xc8\x4a\x1a\x05\x0a\x91\x56\xc5\xf9\xd8\x22\x3f\x5d\x53\x48\x64\x2b\x22\xd0\x0c\xa6\x79\x07\xb7\x66\xd2\x28\xf2\x11\x3e\x63\x54\x73\x61\x7e\x59\x4c\xfa\x96\x69\xc4\x08\x0a\x16\xde\xff\x79\xdf\xde\x5a\x44\xa1\x61\xf6\x30\x74\xdd\x43\xef\x20\x8d\x54\x8a\x05\x22\x2d\xf9\xa8\xcd\x90\x8f\x22\x1e\xc3\xa1\x8c\x13\x81\x2b\xa1\xb1\x36\xbf\x3d\x3f\x3e\xbb\xdf\x8a\xd3\x28\xe9\xd3\xed\xcf\x8a\x4b\x27\x65\xb2\xd5\x73\x28\x40\x65\x22\x63\x13\x8c\x84\xc3\xd1\x8e\x99\x4c\xd2\x1e\x75\x13\x06\x8d\x5b\x8e\xf5\xfa\x5c\x16\x37\xe2\x6a\x69\x12\x2a\x62\xea\xb7\x3f\x8b\xaa\x57\x36\x91\x26\xb1\xe1\x7f\x31\x36\xc8\xf7\xb8\xfd\x7b\xc2\x91\x56\x6c\xe7\x14\x24\xfa\xe8\x88\x34\xa5\x1c\xdd\x51\xa9\xcf\x3c\x87\x1d\x6f\x8c\xf2\x5d\x75\x60\x5e\x18\x7d\x55\xd1\x28\xd2\x34\x82\x18\x3a\xd0\xcd\x4b\x0e\x72\xdf\x16\x76\x8a\x34\x65\x0c\xc3\x7f\x36\x34\x8e\x36\x5f\x3b\x1b\x52\x20\x38\x53\xe7\x59\xbd\x3e\xb2\xfd\x20\x4c\x97\xa6\x2a\x46\x22\x9e\x5d\x65\x9f\xb7\x0b\xa9\x0c\x86\x90\x79\x21\xf2\xf5\x69\x67\x6d\xf5\x4a\x32\x47\xab\x98\x45\x21\x75\xfa\x0d\x1d\x69\x55\x73\xcd\x4c\xd5\x50\x3a\xb6\x39\xf7\x04\x3c\x8c\x62\x5b\x4c\xf5\xbd\x39\xfc\xb2\x29\xe2\xc4\xa6\x9b\xf0\xc9\xb5\x37\xa0\x00\x5e\xf0\x85\xd7\xc5\x0f\xc8\xfa\x4e\x41\x2a\x7c\x8e\xc1\x3f\x3b\x5d\xba\xa8\x41\x2a\x12\xc2\x94\x43\x35\x33\x69\xca\x8b\x59\xbe\x03\x47\xc6\x2f\x52\x21\xfd\xd0\xc9\x7e\xd9\x37\x5d\x17\x4a\x5f\xab\x45\x8b\x54\xc6\xc6\xd8\x2e\x59\x56\xc1\x87\x6e\xf3\xd7\x29\xa8\x04\x21\xc3\xc6\xc4\xc7\x93\xb4\xca\xf6\xb7\xa6\x9a\x22\x9e\xe7\xb5\x35\xc7\x35\xf4\x37\x27\xe5\xf1\x98\xdb\x8d\x71\x5c\x3d\x3e\x3d\xe5\x55\x2a\x51\xe6\xe6\x6e\xb6\xf8\x36\x5b\x3f\x0d\xa5\x19\xff\xd2\xc6\x65\x84\xa4\x46\x52\xd4\xb9\x04\xa8\x5f\x36\x00\x51\x30\x1a\x46\x91\x3f\x28\xa0\x72\x4c\x4e\x63\x72\xa0\xc1\xa3\x31\x9a\x7a\x18\x2e\xdd\xe5\x7a\x8f\x19\xc8\xd5\xcf\x1a\x8a\x2a\xd3\xc5\x77\x04\xd7\x0e\xcf\x0e\xe6\x35\x46\x73\x33\xf3\x0a\xd8\xd5\x9f\xba\x5f\x80\xc4\x7c\x0a\x11\x6d\xfd\x9c\x17\x47\x51\x30\xbc\x81\x1f\x08\x4a\x3b\x02\x24\x07\xa7\xb7\xad\x91\xc7\x42\x43\xc8\x59\x7c\x40\xd9\x98\x3d\xcf\xf9\x08\x4c\x38\x7a\xfe\x28\x62\x08\x46\x5a\x36\x86\x89\xfb\x5b\xcc\x12\x27\x09\x55\x3d\xdd\x6d\x51\xad\xe9\x30\x06\x59\xb3\x48\x49\x97\x6f\xfc\xbb\xe6\x3f\x74\xf9\x0e\xe5\x35\x4e\x9a\xc5\x1e\xc1\x99\x6b\x46\x73\xd1\x3c\xb4\xfe\x2c\xae\xf3\x79\x2c\x96\x02\x49\x29\x4c\x90\xac\xfa\x64\xa7\x5d\xd5\x77\xb7\x59\xac\xa4\xec\xc3\xd4\xac\xbe\xf6\x97\x73\x87\x25\x51\x8c\xdb\x7e\x05\xe2\x5c\xde\xc8\x5c\xb1\x44\xca\xc8\x9d\x60\xbb\xfa\x50\x02\xd8\xd2\xf7\xd5\xbf\xad\x08\x9c\xeb\x08\xa9\x74\xd5\xc4\x59\x9e\xa3\xe6\xf6\xe0\x24\x63\x2c\x4e\x84\xc5\xb0\x77\xbb\xca\xc8\x36\x60\x8c\xd3\xc4\xb2\x0d\x6f\xf4\x11\xee\x59\xfb\x05\x39\xf1\xa8\x8d\xce\x6d\x9f\x37\xa3\xcb\xb8\x0f\x18\x82\x6e\xbc\xfe\xac\xd8\x6f\xea\x92\xd5\xb0\x6f\xc7\x87\x73\x2e\xec\xae\xb2\xc9\xf5\xde\xe2\x68\x9d\xbf\xc6\xb8\xa4\xdc\xc2\xef\xef\x00\xfc\xd1\xe8\x0b\xc2\x53\xe5\x2a\x96\x7f\xbe\x60\xf6\x1d\xbf\xd8\xb8\x5f\xca\xb0\xdf\xb9\x90\xa5\x3e\x9d\xda\x78\x14\x93\xa9\xb1\x77\x0e\xe7\x23\x2b\xdc\x12\x9d\x5f\x6a\x58\xb4\x44\x38\x82\x49\x66\x0e\xf3\xcd\xdb\xd3\x3f\xfa\x5b\x37\x53\xc4\x8b\x93\x1e\xee\x1c\xeb\x42\x7b\xac\x4b\x83\x81\xe0\xc4\x0b\x6d\x19\x48\x33\xf5\x96\x50\x89\x32\xbb\x66\xdc\x6d\xfa\x29\xcc\x29\x7e\xd7\x35\xbc\x9c\x8f\xa7\x85\xce\x0a\xe2\x0e\x30\x4e\x52\x89\xf1\x3b\x05\xe2\xd0\xf4\x78\x3a\x1f\xef\x74\xd9\xd2\xcb\xb4\xdd\xb8\xa9\x73\xcb\xaa\x17\x9d\x67\xe2\xb2\xfa\x99\x55\x43\x29\x2b\xc1\x29\xf1\x43\xbb\x76\xcf\xa7\xe5\xb9\x16\x87\x76\xf8\x6e\x79\x3c\xbf\x04\xd1\xe2\x34\xa4\x18\xa9\x61\xc2\xe8\x93\xa1\x19\x37\xd4\x67\x1c\x8d\x4d\xb3\x8b\xa8\xde\x4e\x86\x78\xc9\x61\x17\x8f\xc9\xa8\xdf\xa5\xa5\x70\x10\xdc\x93\x46\x56\xde\x21\x13\xc7\x57\x2a\xc0\x22\x06\x2c\x35\x99\xe7\x4c\xbc\xa3\x32\xf9\x94\x07\xca\xfd\x54\xe2\x21\xd7\x05\xdf\xdb\xc9\xc2\x7d\x61\x0b\x79\xa1\xde\x7c\xb2\x51\xb4\x83\x07\x11\xc5\x8c\x55\xcd\x3e\xa0\x1c\x7f\xd3\x10\x42\x84\x10\x3b\xf6\xf9\x9c\x65\xc7\x5e\x59\xcd\xe4\x02\xe7\x91\x27\x71\x22\x88\x1c\x58\xb9\xd0\x85\xca\xdc\x92\xe6\x11\x8b\x86\xf2\x71\xaf\x48\x58\x6f\x09\x3a\x26\xab\x74\x78\x24\xa2\xd4\x42\xd8\x31\x7e\x09\x72\x81\x51\xd8\xd1\x7b\x44\x82\x61\xc1\xd1\x93\x3e\xb6\xa0\x29\x1e\x41\x84\x78\x25\x34\x5f\x30\x59\xf5\x45\x5c\x83\x47\x60\x0a\x69\x9b\x9d\xc9\xc2\x17\xbe\x0c\x0b\xf3\x48\xc5\x46\x0d\x12\xeb\xd5\xfe\x62\x58\xe2\x20\xc1\x04\xf6\xeb\x39\x87\xfa\x9d\x6d\xa1\xaa\xd7\xce\x7e\xe7\x71\x00\x06\x3c\xcf\x90\x9c\x01\xab\xc6\x6c\x53\x12\x7b\x98\xeb\xea\x58\xf5\xb7\xec\xe7\xaf\x55\x2d\xf0\x24\x49\x93\x0e\x3f\x32\xd8\x90\xdd\x56\xc5\x93\x34\xc0\x92\x08\x65\xae\x1c\x14\x55\xf1\x94\x78\xca\xc4\x5a\x84\x2e\xe4\x37\x43\xab\x32\xef\x06\x38\xf5\x95\x11\xeb\x6e\x9c\x38\x28\xbf\xe9\x73\x89\xf6\x54\xdb\x1e\x85\xae\x64\x63\x80\xb6\x1f\x7e\xbb\x54\x46\x2d\x84\xa4\x31\x25\x59\x21\x7b\x9c\x09\x82\x33\x30\x95\x68\x5b\xad\x6b\x2b\xeb\xd0\x69\xac\x08\xce\x83\x18\x57\x21\x5a\xaf\xc7\xec\x7c\x9c\x29\x95\xe5\xd9\x15\x6b\x95\xe0\x3c\x8c\x31\x26\xb4\x81\x7a\x36\x19\x0f\xb3\xfd\x84\x17\x63\x7a\xbb\x80\xcf\x09\x4d\xea\x71\x67\x5f\x21\xc7\xed\x3b\x5c\xee\x34\x46\xb2\xba\x0c\x10\x17\x91\x87\x3b\xf5\x56\xbf\x67\xf5\x12\xeb\x69\x6f\xee\x26\x82\x99\x33\xe5\xc4\x8a\xba\xbc\xb8\x38\x29\x97\x69\x18\xd9\x32\xf4\x17\x56\xbb\x08\x90\x2b\x3e\xe1\x92\x1b\x40\xb9\x55\xd7\xc1\x6a\xdd\xa9\x42\x2d\x2e\x2d\xd4\x1d\xb5\x21\x9a\xcf\x69\x88\x58\x5c\x2b\x98\x42\x54\xc1\x0a\xe3\x93\xcf\x99\x78\x37\xca\xc8\x33\xf9\xaf\x73\x55\x37\x37\x7e\x6d\xde\xcd\x5d\x01\x5e\x8c\x4c\x61\xf5\x21\xab\x76\x08\x15\xaf\x77\x1d\x2d\x9a\xe0\x2a\x35\xfc\x72\x50\x48\xac\xef\x6e\xff\xce\x19\x73\x49\xb1\xe7\xe7\x07\x43\x3c\xed\x93\xae\x59\x22\x70\xcc\x54\x38\xef\xa6\x26\x8c\x20\x1e\x35\xa4\xf6\x59\x09\xa2\x5e\xc2\x51\x8b\x92\x09\x77\x38\x0b\x12\x0a\x44\xf6\xda\xbd\xd2\x70\x3a\xba\x36\xe6\x21\x3c\xdb\x8e\xcd\xcc\x9e\x2e\xc3\x6f\x2a\x28\x51\x68\xfa\xd9\xa2\xa5\xaf\x23\x32\x82\x7a\x14\xe1\x9e\xba\xd8\xf1\x5e\xbd\xaa\xf0\x42\x82\x20\x81\x13\xc2\x44\x9e\xb4\xcb\x2d\x08\xdf\x93\xc8\xa7\xe8\x30\x0e\xeb\x93\xaa\x96\x5a\x5c\x67\x95\xbb\xb0\x8e\xf0\xb9\x8f\xd3\xa0\x25\xe5\xfd\xf6\x7d\xd1\xde\x4f\x10\x4c\xbe\x19\xa9\x35\x44\xc6\xb8\x98\xdd\xba\x1e\xc9\x7d\x0a\xe1\x83\x97\xf8\xa3\x60\x32\x1c\x4f\x75\x3b\x46\x8d\xe9\x63\x04\x74\x58\x7d\xb8\x63\xa2\xd6\xe5\x2e\x73\x6b\x5a\x84\x89\x29\x04\xd8\x99\xc8\xd6\xa6\x66\xe2\xfd\x30\x51\x3f\x29\x42\x46\xd0\xa5\xbd\x47\x48\x7f\xeb\xb8\x89\x28\xe1\x38\x11\xcf\x15\x94\xd5\x2b\xa8\xd1\x65\x51\xea\x45\xd6\x60\x5b\xe8\xe3\x89\x15\xd3\xa4\xd3\x42\xc4\xa9\xc2\xf0\xb6\x3e\x41\xf1\xc8\xb2\x51\xb1\x8a\x88\x95\xe1\xbe\xed\x61\xf4\x58\x0d\x75\x97\x54\x14\x89\xe7\x2b\xc7\x8b\x75\x2e\x7b\x73\x57\x24\x89\x20\x86\x05\x4f\xb0\x4b\x8b\xc5\xba\x65\x23\x89\x44\x70\x54\x9c\x38\x9d\xab\xc3\x16\xca\xe3\xc0\x4c\x15\x29\x89\x59\xda\xca\x67\xdf\xd2\xc9\x12\x22\xa5\x7e\x02\x1d\xb9\x51\x36\x42\x03\x8a\xd4\x4f\x7c\x77\x12\xec\x2c\x35\xcd\x80\xca\x67\x74\x3b\x5f\xa4\x7d\x4e\xa6\x56\x2a\xb6\xaf\xd0\x3e\x8a\x8a\x8a\x34\xe5\xe8\xd6\xb3\x3c\x7f\x2b\x7e\xbf\x08\x90\xab\x76\xe5\x0a\xe6\x09\xcf\x9a\x82\x77\x59\x79\xc4\x60\x88\x89\xd7\xd4\x97\xd1\x47\x64\xa9\x07\x3d\xb1\x29\x63\xd9\x76\x98\x5b\xdb\x8b\x7b\x11\x62\xad\x6c\x9a\x93\x8d\x20\x5d\x82\x07\x06\x41\xfb\xba\xde\x7c\x9b\xcd\xbf\x4d\xe2\xed\x5c\x57\xa9\x90\xff\x79\x5d\x2d\xcd\x41\xf9\x7a\x2e\x8a\xac\xd8\xdf\xb1\x7c\xbf\x73\xf7\x13\x01\x73\x6e\x9f\x4d\x8a\x59\x02\xd1\x45\xae\xab\x11\x8f\xe8\x68\x34\x65\xea\xe3\x91\x90\x09\x6d\xb0\xc7\x8f\x96\x50\xe5\xb7\xb6\x43\xe4\x71\x67\x82\x21\x71\xb1\xab\x67\xd3\xe3\xc4\x96\x80\x80\x53\xe2\x10\x50\x4d\x5f\x13\xfc\x7c\x05\xe3\xfb\xd9\x5e\x2a\x21\xcc\xec\xec\x39\x3b\x17\x4d\xcb\x15\x49\xf5\xff\x2e\xa6\x2f\x54\x12\x27\xc8\x15\x68\xb8\xd3\x4a\xa8\x60\x44\x8b\x2c\x84\x62\x81\x55\xc5\x34\xf9\x45\x44\xd7\xd3\xe4\x78\xd5\x0d\x50\x8d\x77\xa4\xa4\x40\x4d\x81\xb2\xab\x18\x94\x84\xb0\x50\xd8\xd2\xb2\xbe\xe6\x4e\xd3\x62\x74\x2a\x77\x70\xcc\x6a\x0c\x8f\x94\x97\xc6\x7d\x19\x1d\x5e\xd3\x6f\x22\x89\x67\xa2\x3a\x8e\x70\x7e\x72\x6a\x5c\xcf\x6f\x49\x02\x93\xaa\xd8\x99\xa8\x51\x75\xe5\xc7\x48\x4a\x42\x69\x90\xe6\xfa\x58\xc9\x16\xfb\x2e\x69\x4a\x63\xeb\xf1\xb1\x72\xef\xd4\x22\x84\xa4\xb6\xcc\xcf\x44\xdb\x1f\xb3\x22\x3b\x9e\x8f\x83\x5a\xc6\xe1\xfd\xbd\x30\x92\xbc\x57\x2c\x9a\xfd\x07\x1a\xcf\xad\x1a\x77\xb3\xda\xed\x15\x56\x2c\x65\x72\xfe\x69\xb3\xd8\xec\x3a\xfe\x2d\x3d\x48\x90\x75\xa0\x04\xa5\x1a\x03\x75\x3e\x5a\x8e\xd2\x27\x21\x06\x06\xfe\x95\x55\x87\xac\x3e\x67\x87\x33\xbb\x61\xfb\x48\x5f\x98\xf4\xa7\xc2\xf4\xd4\x28\xf1\xdb\x0b\xac\xc9\x20\xe6\x86\x3f\x46\xca\xd9\x59\x66\xf5\x73\xb9\x42\xfd\x47\x61\x22\x50\xe3\xa2\xfb\x51\xbd\xc3\x08\x84\xdf\xdd\x13\xfd\xbf\xc5\xf3\xa3\x51\xe8\xdf\xcd\x9f\xdf\x9e\xb6\x7f\xee\x36\xdb\xd9\xef\xae\x68\x45\x06\x31\xa4\xad\xe3\x74\x45\xf2\x7a\x6b\x49\xf4\x1f\x3d\x09\x31\xfc\x31\x67\x79\xd6\xc3\x3e\xc9\x80\x9b\x82\xea\x0f\x56\x70\xf8\xb9\x6d\xd1\xdf\x6d\x3b\x18\xf2\xae\xd9\x51\x97\x83\xeb\x20\x40\xbf\x66\x93\xe5\x1f\x50\xde\x65\xaa\x1e\xe0\xc9\x65\x98\x12\x84\x38\x58\x2e\x1d\xef\x0e\xb9\x46\xdb\x95\x2e\x43\x1e\x9b\x70\x41\xad\x4f\xb3\x76\x85\x84\x8a\x7b\xc6\x19\xfe\x27\x94\xfa\xb7\x89\x40\xbb\x8c\xac\x4a\x47\x73\x94\xbf\x15\x75\xe6\x22\x95\x32\x52\x24\x8d\xda\x0a\x9e\x52\x7f\x56\x6b\x85\x9e\x45\xf5\xa4\x4d\x70\xd5\x7a\x38\x79\x9b\x31\x95\x71\xe2\xf1\x76\x77\x44\x9e\x19\xdc\x24\xae\x10\xa6\x32\x4e\xc0\x67\x2d\xc4\x6c\x2d\x67\x85\xfc\x06\x63\x18\x86\x4c\x02\xc0\xd3\xe2\xe5\xc1\x71\x97\xc8\xd4\xb3\x50\x43\x9c\xca\xbb\x25\x88\x9c\x95\x70\xa7\xb1\x22\x79\x7a\xe3\x95\x69\x20\x04\x6f\xe7\xe3\x92\x5d\xaa\x3b\x5d\xb6\xfc\xa7\x42\xa6\xa9\x4f\xec\x7a\xfa\xa6\x3f\xa0\xdc\xc2\xcf\x36\x8b\xd4\x16\xb5\xc9\x54\x49\x0c\xa0\xab\x73\x41\x47\xcf\xc9\x08\x55\x8e\xaa\xc6\x00\x4c\x4d\xae\xb7\xf1\xd4\xa7\x97\x08\xf3\x4c\x7c\x96\x33\xd1\xcb\x58\x4b\xe6\x03\xce\x0e\x63\x3f\x5b\xfc\x44\x26\xa0\x33\xfc\x24\x8b\x62\x04\xd7\x6d\x67\xcb\x97\xe7\x87\xd5\x6e\xfe\xfc\xbc\xd9\xb6\x8d\x8c\xa0\x27\x76\x1a\xb0\x0f\x0d\x58\xfd\xc6\xdb\x19\x67\x31\xe6\xfa\x5c\x28\x67\x57\x9c\x1d\xa2\x40\x72\x96\x52\xd5\x2b\xbe\x5b\xfd\x3c\x21\x00\x6d\xe2\xbd\x86\x67\xa9\xc4\x42\x47\xab\x40\xd0\x1b\x69\x49\x03\x0c\x6d\x1f\xb3\x2b\x4c\xe1\x94\x3f\x2d\x65\x2a\x70\xef\xdf\x40\xdd\x17\x21\x9c\xa4\xe2\x16\x52\xf2\xc8\x17\x3d\xa5\x4f\x5d\xd6\xfb\x1e\x26\xff\xbf\xa3\xff\x99\x82\x7e\xdc\xda\x48\x24\x07\x8c\xed\x55\xfa\x08\x77\xe7\x02\xa7\xb2\x43\x2f\x4b\xf0\x0d\x37\xb8\x08\x84\x6a\xc3\x31\x12\x44\x4a\xac\x35\x38\x87\x7a\x2d\x67\xf5\x24\xdb\xa2\xed\xad\x02\x85\x26\x1f\x3f\x5f\x1a\x4f\xc9\xdd\x44\xd9\x10\x28\xfa\x01\xce\x06\x9f\xc3\xbe\xdb\x2b\x54\xec\x47\x5e\xe7\x12\xff\x5a\xf9\xa0\x54\x8c\xa0\xd3\xc4\x10\x51\xfe\xc4\x8e\x60\xd9\xea\xda\xdb\x72\x3f\x34\xf8\xbb\x32\xfb\x9d\x95\xce\x5a\x07\xaa\x18\x2e\x6a\x07\xfa\x1b\x96\xf6\x80\xe7\xc7\x2a\x44\xcc\xa9\xab\x06\x06\x9f\x24\xe8\x1e\x30\x5e\x3d\x66\x45\x17\xaf\x02\x3f\x92\xcc\x73\x9c\x22\xfd\x64\xf1\xa4\x45\x06\x81\x97\xf8\xbc\xef\x6f\x56\x5b\x8d\x58\xf6\xbe\x83\x0c\x41\x18\x22\xaa\x13\x0a\xb9\x5e\x3c\xa3\xfb\xef\x68\x3c\x20\xa4\x0c\x41\x73\x07\xc8\x4f\x50\x62\x92\x07\x95\x0c\x77\xbb\x51\xae\xe9\x6f\xed\x52\x19\xed\xf9\xd3\xcd\xee\xf6\x9e\x8f\xa8\x4a\x63\x7d\xda\x8a\x7b\x79\x3e\x4e\x7b\xfb\xc3\x0f\x02\x09\x01\xf4\x10\x70\xda\x3d\xc2\x51\x97\x97\x59\x59\xb6\xe6\x02\x30\xe6\x1b\x51\x2f\x13\x4b\xec\x00\xe4\xa3\xfb\xf0\xc4\x30\xc6\x5a\x42\xcc\x79\xa6\x07\xce\x03\x08\x62\x60\x5c\x15\xd4\x42\x17\xea\xff\xca\x74\xf5\x7f\xfd\xaf\x7b\x0a\xdf\x4f\x98\xab\x69\xa8\xb3\x8f\x7e\x92\x09\x44\x60\x58\x77\x6b\xc7\xa3\x37\xd0\xda\x1b\xdf\x29\x48\x12\x47\x6f\x5f\x14\xfa\x5c\x08\x0c\x59\x0c\x5f\x5a\xd2\x08\xed\xf4\x77\x80\x8e\xd0\x00\x64\x98\xfa\xa1\xc3\x77\x63\x58\x71\xaa\xe4\x06\xa4\xf0\x1d\x17\xed\x12\x84\x89\x88\x34\x66\x7e\xcb\x05\xd1\x7b\x74\x08\xcd\xe8\xb3\xac\x5c\x96\xfa\xf4\xc2\x2e\x8c\xe7\x03\xfa\x1d\x00\xc1\x91\xbc\x46\x66\x55\xd3\xb6\x81\x3c\xef\x92\x14\xa0\x68\x8a\x3f\x66\x13\x24\x8d\xc3\x9a\x43\x7d\x6d\xbe\xba\xee\x91\x91\x18\xed\x52\x5f\x5f\xa6\xbc\x40\xf1\x18\xf5\x41\xff\x7e\x96\x7b\xc3\xc3\xd6\x6e\x24\xa0\xa4\xef\x77\xb8\xca\x41\x24\x75\x70\x13\x45\xa4\x0c\x63\xa7\x9c\xb5\xcf\x74\xf1\x56\x8e\x7c\x65\x45\xd3\x18\x77\x89\xb5\xd0\x8d\xdf\x74\xe5\xdd\x28\xca\x89\xa1\xbf\xba\x54\x35\x1c\x27\x6a\xfb\x15\x85\x14\x21\x08\xfc\x7c\x79\xca\x8a\x7f\xb1\xe1\xf6\xae\x3c\x15\xc4\x9d\xe8\xd9\xb6\x64\xb2\x19\xcd\x3b\x91\xad\x0b\xab\x54\xda\xfb\x2e\xca\x0f\x0d\x29\xfb\x2e\xab\x1e\x58\x9d\xd5\x67\x09\x83\xc0\xa4\xf2\xed\x40\xe2\x5c\x40\xdf\xe1\xba\x22\x50\xf9\x11\x84\x56\x18\xfd\x85\x95\x57\x31\x63\xe5\xc7\x1e\x62\x4a\x37\x50\x1b\xf8\xcd\x84\x0c\xa5\x50\x01\x21\xdc\x73\xfb\x98\xa5\x2c\xaf\x30\x1e\x6f\x2d\x72\xfb\xcd\xdd\x40\x04\x5e\x82\xa0\x6f\x7e\xce\x72\xb9\xdc\x38\x5a\x89\xe5\xdc\x75\x08\x89\x51\xd6\xb3\x2c\xa0\x5f\x9a\x3f\x2a\x0c\x43\x6e\xd8\xf6\xf6\x4e\xf6\xec\x0a\x95\xad\x42\x11\x25\xa9\x2b\xe1\xc3\x30\xa0\x81\x99\xe3\x32\x29\x8f\x16\x8f\x32\xba\xb1\x50\x58\x69\xb5\x41\x9e\x51\x13\x12\x9e\xac\x61\x53\x51\x6c\x18\xdb\xdb\xf2\xcf\xbe\x70\x99\xeb\x23\x53\x3c\x0e\x17\xd6\x6b\xac\xcf\xe5\x0d\x07\x43\xc5\x0c\xd8\xf0\xd3\x19\x5d\xe0\x51\x2f\x41\xd1\x18\x32\x6e\xd5\xdf\x99\x78\x3f\xe9\x7a\xc8\x19\xa4\x12\xae\x3c\x97\xee\x2c\x20\x1f\x4c\xc7\x34\x00\x44\xe6\x2a\x4b\xc5\x33\xe6\xa6\x54\x69\x1c\x4a\x4b\xf5\xb4\xb8\x88\x7c\x9c\x7b\x6e\x7b\xb1\xc8\x78\x56\x5d\xfc\xfd\x6a\xf8\x19\xe7\xd0\xb9\x80\x36\xd8\xd4\x67\x26\x17\x8a\xd3\x10\x6b\xdf\xd0\xa4\xe8\x01\xdb\x15\xf7\x4c\x8c\xb0\x9f\x1f\x3a\x77\xcc\xc5\xdd\x37\x69\xfb\x1b\x8d\xa5\xec\x1b\xfb\x80\xd9\x1c\x5f\x6a\x99\x89\xf7\xa9\xa2\x28\xc5\x03\x8e\xf9\x8f\xe5\xfa\xfb\xfa\xed\xf1\xa7\xf3\x59\x95\xa4\x09\xd6\x8c\xdf\x3d\xbf\x3d\x2d\x67\xdb\xf5\xf3\x98\xe9\x47\x49\x3f\x64\x64\x90\x75\xe8\x2a\x40\x16\xec\x78\x62\xd9\xbe\xb8\x2a\xfa\x56\x32\xf1\x4c\x9a\xba\x64\x45\x7d\x03\x5f\xab\xa4\x92\x54\xb4\xec\x92\x37\x0c\xc9\xe1\x25\xe0\xc5\xa8\x09\xbc\xc9\xa7\x45\xd3\x86\xc6\x9f\x82\x98\x22\xc3\xde\x46\x64\x50\x20\x72\xde\xbd\x96\xf2\x8c\x16\x1b\x32\x14\x3e\x6d\xee\x7e\xfc\x76\xed\x1d\x2a\xa5\x7c\x53\x01\xa8\xf3\x7c\x39\xf6\x7e\x24\x21\xd4\xc3\xb8\x1a\xea\x08\x3f\x7f\x40\x49\x09\x69\x25\xb7\x24\x21\x5e\x8a\xae\xf6\x89\x5d\x6e\xf0\xf5\xf7\xc2\xba\x92\x10\x9f\x81\x75\x5f\x9a\xf3\xdf\x88\x69\x0a\xbb\x62\xaf\x60\xaa\x46\x66\x18\xdd\xeb\xf3\x95\x66\x86\x24\x24\x25\x91\x2d\x91\xf9\x9e\xd5\xcc\x72\x5b\xf7\xc7\xb2\xe9\x13\xb1\x41\x42\xd2\xd6\xc1\x2e\xce\x55\xad\x8f\xc6\x3c\xfc\x22\xd5\xff\xb7\xe1\x60\x50\x90\x18\x4f\xa9\xfc\xdf\x7a\x22\x66\x92\x78\xd4\xc3\xb4\xa2\x60\xa7\xac\x66\xf9\x13\x80\x74\x4b\x4f\x12\x2f\x34\x2c\x4c\xf3\xac\xbe\x47\xc9\xef\x96\x66\xcd\x76\xf0\x3d\x43\xc8\x59\x9d\x4f\x27\x5d\xd6\xaf\xc0\xfb\x0b\x5f\x12\x9f\x71\x2c\xbd\x37\x10\xed\x57\x60\xf9\xa2\xc7\x7f\x3c\x7c\xc2\x20\x50\x41\xda\xe7\xdf\xeb\x9e\x23\x08\x53\x84\xf8\x23\x36\x69\x28\xdd\x2a\x49\x20\x4d\x7a\x03\xd9\x7f\x4b\xc4\xc0\xfe\x4a\x85\xac\x24\x61\x4c\x10\xe1\x65\xbf\x68\xc1\x8e\x8d\x87\xeb\xb6\x97\x29\x50\xa0\x24\x31\x21\x08\x03\xc9\x84\x5e\x66\x15\x86\x5c\x5e\xda\xca\xa5\x07\xf8\x80\xdc\x73\xcf\x15\x7b\x1e\x5a\x5b\x38\x85\xb7\x2d\x8b\xdb\xaf\x3c\x59\x1c\x46\x89\xc9\xa3\xd5\x2c\x77\xc5\x61\xae\x2d\x32\x96\xc6\xeb\x6a\xf1\xfc\xba\x7c\x69\x05\x4f\x9b\x16\x43\xe5\x68\x10\xc6\x7f\xf5\x13\x11\x57\x66\x71\xf3\xf3\x7e\x77\x60\xd5\xc1\x0b\xa3\xa5\x41\xad\x09\x5d\x08\xe6\xf2\x2d\xbd\xff\xb5\x97\xa6\xc4\x30\xf0\xf6\xc5\x4a\xac\x5e\xdd\x53\x1b\x9a\x97\x24\xf5\x88\xd9\xf4\xcd\xd9\xb6\x6c\x3e\xbe\x39\x81\x33\x5d\xcc\x2f\x4b\x2d\x6a\x5d\xb6\x58\xce\x76\x59\x4b\x92\xfa\x81\x63\xc3\x35\x04\xb3\x46\x6b\x77\xf8\xfc\x2c\x4c\x44\xcb\xc9\x3f\x2b\xa4\x0d\x51\xd8\xb8\xfd\xb9\x93\x71\x92\x84\x45\x02\x63\x55\xac\xae\x9b\xf3\x25\xcb\x9b\xcf\x8c\x80\x85\xac\xd8\x23\x12\xbd\xb7\x8f\x0f\xb6\x18\x49\xb8\xc7\xc1\x38\xbb\x12\xe0\xd8\xdc\x3d\x2b\xf6\x95\x7b\x45\xee\x27\x4e\x79\x6d\x76\x3a\xad\x07\xa8\x17\x49\x78\x44\x90\x48\x68\xb9\xba\x9b\xbd\x3d\x6c\x57\xcb\xdd\x66\x3b\xdb\xbe\x6d\xda\xab\x45\xdc\x96\x36\x2d\x70\xc8\x8d\x7b\xf2\x4f\x28\xf5\x03\x14\x7b\x17\xcf\x97\x84\x03\xc5\x04\xca\x7f\xbe\xfd\xa3\xaf\x91\x21\x89\xf0\xa5\xb2\xd3\xd1\x2a\xfd\xcd\xda\xe9\x20\xfd\x98\xfa\x6e\x18\xeb\xfa\x32\x35\x8a\x32\x30\x95\xde\xdf\x58\xf6\x83\xf5\x30\xad\xd7\x67\x94\x24\x52\xc6\x06\xe4\x52\x41\x69\x79\xa0\xe1\xd3\xfd\x18\x90\xd0\xf9\x90\x2f\x1a\x6b\xa4\xbb\x9f\x73\x9b\x1e\x50\x9f\x9b\xc0\xfb\xdc\xf7\x06\xb3\x6b\xb8\xc6\x20\xe1\xb8\x2e\xf7\xd9\x07\x9c\x9a\x9b\x4d\x1b\xdd\x92\x40\x4a\x42\x0b\x98\xd8\x61\x5d\x9f\x35\x67\x7a\xdf\x4f\x79\x46\x43\x5f\xe8\xac\x4f\xef\x2f\x29\x49\x4c\x9d\xe9\x7c\xb5\xd8\xfe\xef\xb0\x73\xcd\xb5\x09\x9a\x11\x32\x93\x2f\xa5\xfe\x68\xef\x49\xa9\xc2\x23\x62\x79\xb7\xe9\x45\x15\x25\xa5\x42\xa0\x6b\x88\x8c\x7b\x0b\xda\xfe\x59\x41\x60\x0a\x8a\x3e\xf4\xfb\xb5\xe0\x90\xed\xe5\x51\xf0\x7d\x13\x10\x93\x77\x46\x02\xc0\xdd\xc0\x4b\xcc\x1a\x50\xba\x7c\xdf\xf6\x4e\x89\xbf\x84\xd7\x0c\x86\x91\x7a\x42\x90\x4e\x1d\xe9\x21\xe3\x25\x2b\x33\x36\x9d\xbf\x91\xd4\x07\x4e\xbc\xd6\x9b\xd9\x08\x56\x5c\x4d\x2b\x1a\x12\x03\xa0\x6b\xc1\x85\xdf\xc0\x42\xee\x96\xce\x4c\x69\x23\x0b\x92\x86\x91\x44\xfa\x56\x4b\x18\x6b\x39\x48\x66\x85\x5c\x09\x6d\xdc\x98\x89\xdc\x72\xe3\x79\x32\xcc\xd8\x3f\x5e\xb6\xd7\x3c\x60\x53\x9f\x2d\x21\x46\x21\x74\x87\x7b\xc6\xd7\xfb\x23\x4d\x12\x8e\x79\xb1\x66\xb6\xcf\xa1\x9e\xe2\x3c\x74\x3d\xd3\xc8\xb1\xdd\x43\x3d\x25\x77\x23\x69\xd2\x2c\xd5\xff\xfa\x7f\xff\xf5\xef\xb3\xae\xbf\x8e\xe9\x49\x9a\x7a\x1e\xb7\x05\xd0\x6b\x9b\xc2\xba\xc2\x05\x4a\x9a\x72\xe9\x59\x53\xff\xbb\xae\x61\xa1\x8f\x7d\x19\xc6\xd1\x1d\x21\x45\x5d\x9a\x9d\x60\x79\x6e\x99\x7d\xc6\x24\x61\xb7\x8c\x88\xab\xdd\x9f\x32\x1a\xf3\x60\x50\xb6\xbc\xb8\xaa\x34\x91\x94\xf9\x09\x56\x32\x5a\xf0\xfc\x13\x2b\x85\xfe\xed\xb6\xe5\x28\x29\x8b\xa5\xab\xc0\x9d\x6b\x3d\x54\x92\x97\x94\x31\x2f\xec\x8b\xf0\xbc\x15\x15\x38\x79\x84\x3b\x6d\xf7\x1a\xdb\x97\xfb\x29\x1e\x1f\xcd\x92\x67\xfb\x76\x71\x72\x30\xfa\xe9\x95\x56\xf5\x82\x9d\x70\x60\x5d\x9b\x08\x13\xcf\x24\x6c\x3f\xde\x5a\xa9\xcd\x29\x94\x53\xd3\x55\x22\xfc\xa2\x57\x0e\xb3\x28\x2f\x55\x8b\x3d\x96\x54\x12\x89\xf4\x89\xf0\x53\x4b\xa7\x39\x21\xa9\x04\x85\x94\xdb\x65\x0b\x4e\x9a\xf2\x63\x24\x05\x65\x2c\x2a\xa9\x8b\x77\xb8\x18\x65\xd2\x11\x00\x5b\x7a\xc4\xe7\xd2\x32\x56\x5a\xba\x9b\x49\x93\xca\x23\xb1\xd9\x90\xa0\x3e\x74\x8c\x45\xf6\x89\x3c\x1a\x1b\x02\xfe\x0a\x59\x27\x86\x17\x7a\x44\x60\x71\xac\x25\xcd\x7a\xe9\xe5\xb0\x5d\x0f\x4a\xd1\xbd\xe9\x02\x24\xef\x50\x4c\x6e\x3e\xa3\x3b\x07\x21\x46\x8f\xe7\xaf\xb3\xa7\xe5\xa6\xbd\x5b\x44\x11\x1a\x6d\xa5\x64\xef\x58\x9e\x63\xb0\x76\x74\x6d\x9a\x10\x83\xf7\x3e\x61\x5c\x73\xa1\xb3\xe2\x31\x2b\xea\x61\x96\x46\x7a\x9e\x10\x88\xcf\x11\xb8\x2a\x6a\x80\xbf\xeb\xac\x68\x96\x49\x39\x0d\xcd\x96\x9e\x27\x03\x77\x90\xef\x72\x56\xd5\xbb\xac\x86\xe3\x2e\x2b\x50\x38\x64\x58\x20\x2d\x3d\xdf\x0f\xd0\xe5\xaa\x4e\x68\x6c\x3c\x6a\x79\xce\xdb\x0f\xed\xf9\xb1\x99\x67\x78\x20\xe1\x91\x83\x92\x70\x6d\x33\x93\xa8\x3c\x30\x53\x65\xf6\x0d\x58\x5e\x1f\xba\x50\x91\xf4\x7c\x69\xaa\xd4\x33\x47\xab\xd7\x96\x98\x5e\xcd\x01\x1f\x08\xaa\x88\x7d\x83\x3c\xd7\xbf\x78\x72\x79\xbe\x32\xb0\x4d\xd9\xec\x18\x27\xdd\x32\x66\x75\xcd\x60\x34\x6f\xa0\x8b\x8c\xf5\xab\xa8\xbc\xff\x19\x7d\xce\x20\x96\x18\xa1\x3f\x41\x79\xcc\xaa\x4a\x17\x70\x55\x92\xee\x7a\xca\x10\xf1\xea\xdb\xd5\xe2\xdb\xd3\xf3\x7c\xbd\xed\x1f\x91\x5e\x28\x00\x43\x5f\x3c\x93\xcf\xc5\x84\x68\xab\xed\x16\x45\x46\xd0\x7b\xf6\x3a\xfb\x85\xb7\x8d\x94\x51\x71\xd9\x40\x9f\x76\x18\x6d\xd4\xf1\x24\x1d\x5c\x17\x73\x8a\x1e\x85\x21\xa8\x9f\x43\xfd\x5b\x5f\x02\x52\x7a\x89\x52\x58\xb6\xc2\x73\x26\xde\xfb\xac\xd3\xa3\x59\x95\x86\xdc\x1b\x12\x84\xac\x8b\xaa\x6e\x6e\xda\x8b\x80\x48\x2f\x15\x0c\x59\x89\x41\x57\x2d\x6e\x60\xa0\xed\x29\xbd\x54\x4a\xd6\xd5\xd6\x0d\xd2\x1d\xb6\x07\x23\x0c\x0b\x08\x76\x26\x6e\xb7\xaa\x1b\x87\x26\xdf\xd4\xba\x44\x44\xa5\xc9\xe4\x4c\x6e\x39\x1e\xf3\x53\xd9\x61\x07\x3b\x39\x34\xd7\x9c\x1a\x99\xe7\xc7\xf5\xd3\x6e\x31\x7b\x5d\xee\x5e\x5e\xd7\x8b\x55\xdb\xaa\x42\x23\x7e\x30\xa0\xbb\xbc\xfd\x4d\x9a\xa1\xed\x4a\x26\xa6\xc5\xbc\x9b\x5e\x40\x7c\xab\xeb\x94\xe5\xb0\x07\x39\x3f\x97\xe3\xc9\xc0\xbd\x88\x18\xee\x17\x91\x1d\x59\xfe\xe4\x32\x6a\xd2\xe3\xcc\x47\x2d\x24\xe4\xe9\xdc\xd4\xa5\xb7\x6e\x03\xd7\xa3\xa7\xe1\xb4\xcb\x02\x4d\x8f\x0e\xe7\x0a\x29\x51\x76\xc6\x05\x98\x5f\x1a\x4b\x4b\x1c\xe0\xe6\x11\x7a\xf3\xe8\xf4\x04\x35\x55\x84\xb3\x12\x0a\x76\xca\xd9\x65\xb0\x04\x24\xf3\xfc\xb4\x6f\x34\x35\x3b\xd6\x97\xe8\x8a\xe6\x1a\x86\x85\xdd\xa5\x8b\x56\xb5\x32\x13\xed\x5d\x81\x1a\xfa\x78\xcc\x47\x6d\x7f\x6e\x59\x35\xde\x56\x81\xca\x20\x75\xb4\xee\x59\xc9\xc4\xe1\x32\xda\xf1\x20\x62\xe8\x66\xb4\xf5\xa5\x46\x91\xb0\x9d\x9e\x90\x88\xd4\x5a\xff\x43\xee\x34\xe9\x81\x88\x91\x42\x0c\x27\xcd\x2e\x75\x7f\x56\x4c\xfa\x0e\xeb\x7c\x62\x9f\x85\x81\xfe\x19\xb7\x6d\xaa\x86\x4c\x7a\x0a\x58\xdc\x51\x56\x1a\x1e\xa6\xdf\xa6\x7a\xfa\x34\x16\x98\x8e\x3f\x66\x39\xb0\x3d\xa0\x3f\xd2\xb7\xfd\x7d\x9a\x72\xd6\x12\xda\x61\xc1\xd9\x6c\x5c\x1f\x37\x98\x26\x3e\x85\x04\x19\xab\x76\x35\x1b\xfb\x48\xb6\x87\x97\x44\xca\x22\x19\x87\x08\x97\x9e\x03\xe4\x7b\x2c\xc0\x88\x00\xe6\xa2\x7f\x11\x02\xef\x2e\x55\x29\xce\xe8\x23\x7b\x87\x91\x2c\x81\xf4\x7d\x3f\xe4\x2e\x4e\xfd\xf4\x34\x5f\xe0\x13\x4c\xce\x66\xdf\x0f\xa9\x6f\x38\x1c\x1b\x7f\xa2\x0f\xf4\x91\xbe\x0f\x1e\x95\x2e\xfd\x60\xf4\xd1\x0d\x2d\xdf\x60\xba\xf8\x81\x97\x72\xc3\xf0\xf1\x01\xb9\x3e\x1d\x5b\x43\xcc\xdd\x27\x08\x02\x0c\xc5\x9a\xca\x40\x5d\x5e\x36\x50\x66\x50\x39\xc1\x76\xbb\xa9\x27\x6d\x6f\x8e\xb7\xab\xf6\xb5\x2b\x0f\x70\xa6\x1c\x32\x73\x13\x34\xa5\xea\x92\xf5\x11\x1e\xd2\x0f\xa5\x40\xa4\xc6\xec\x7e\xf6\x7d\x35\xb5\xb6\xfd\x48\x84\xa9\xf5\x7f\xd1\x3e\x7c\x56\x2e\x1e\x3a\x9c\xdd\x7e\x4c\x02\xc7\x0f\x39\x3b\x9d\xf2\x4c\xb0\xa2\xae\x06\x0e\xb8\x1f\x07\x86\x5d\xdf\xc4\xb1\x10\x5e\x6f\xdf\xb9\xf3\x35\xfd\x38\xa2\xd4\x66\x31\x96\xf0\x31\xa1\x57\x27\xfd\x38\x25\x89\x65\xf1\xda\x40\x5d\x8f\x08\xb9\xa5\x1f\x8b\x80\x72\x77\xb2\x34\xc7\xbe\x63\x4d\xb6\xed\x09\x35\xaa\xfa\x1d\x54\x12\xcf\x82\x75\x65\x93\x7d\xae\x5b\x12\xc5\x6d\x45\x82\x0d\x89\xb4\x4d\x49\x6a\x41\x14\xa6\xa1\xf1\xb3\x0a\x5b\xb1\xde\x27\xda\x1c\x0e\x66\x92\x4a\xac\xb2\xc9\x2a\x04\x39\xcd\xe4\x07\x94\x15\xb3\x32\x95\xc9\x60\x96\x27\x5c\x79\x5d\x42\x60\xee\xce\xc8\x11\x16\x4a\xfa\x89\x8c\xd0\xc6\x6c\xd9\xf2\x07\xe6\xa9\x9f\x28\xce\xfa\x06\x26\x2a\x75\x4f\x07\x02\xfc\x34\x34\xf2\xf0\xce\x3d\xe8\x21\xfa\x5e\x74\x7b\xc7\x34\x34\xac\x43\x1d\x81\x87\x3b\x17\xd7\x4b\x93\x12\x1e\x3e\x20\x23\x21\xf2\xb3\xe1\x2b\xf4\xb7\x6a\x9f\x53\x1e\xc4\xbd\xdf\xbb\x83\x1b\x0c\x59\xd2\xe7\x8a\xe2\x5b\x9a\x05\x67\xdc\xc2\xe7\x8f\xee\x7b\x08\xc2\x31\x98\xb6\x78\x7d\xfe\xb1\x44\xe5\x88\xe5\xdb\x2b\x46\xfa\xdb\x1e\x09\xf7\x6c\xed\xf9\xe6\x3d\x3b\x5d\xe3\x7c\xa4\x2f\x52\xe2\x0a\xa4\x2c\x32\x66\x7e\x59\x8f\xe7\x9e\x90\x06\x2e\xe0\x6a\xce\xcc\xab\xa3\x35\x34\xf8\xd4\x12\x68\x20\x1c\x99\xfb\xc9\x3d\x05\x10\x90\x2e\xd4\xe5\x50\xfb\xc6\x97\x7c\xd1\xd5\x04\xd9\x80\xf4\x81\x1b\xb4\xff\x29\x17\xa5\xc1\x26\xb7\x8b\x17\x54\x80\x87\x12\xd2\x58\x36\x16\xf6\xb3\x00\x56\x58\xe6\x25\x3a\xfa\x0c\x2a\x8d\x3d\xe8\x84\xae\x0f\x59\x7e\xb5\x79\xba\x9e\xca\x47\xd3\xfb\xa0\xcf\x15\xcc\xf2\x4f\x76\xa9\x7e\x64\xed\xbe\x14\x10\x9a\x04\x5e\xab\xc1\x0e\x8f\x0c\x75\xbf\x46\xaa\xa0\x32\x20\x5e\x18\x99\x2d\x12\xe3\x35\xcd\xfa\xeb\xfb\x97\x01\x4d\xc0\x70\x65\x9b\x4a\xb3\x4c\x58\xa4\xc6\x60\x7f\x0a\x28\x8f\x30\xd8\xf0\xf8\x6d\xd1\x9f\x3a\x41\x10\x33\x6a\x0f\x5b\x1b\x0b\x76\xf9\x46\x19\x04\xa9\x91\xff\x2d\x31\x8c\x35\xd7\x65\xa9\x3f\xc7\xb1\x95\x20\x48\x7d\xd5\xae\x6d\x3c\xdb\xec\x1a\xec\x19\x08\xb4\xed\x2c\x3c\xa4\xc1\x7e\x3a\xcb\xd6\x13\x0e\x02\x88\x31\x56\x77\x2e\xae\x64\x53\x6c\xa6\x4c\x06\x21\xe1\xa8\xd5\x69\x5e\x0a\xf3\x7e\x37\xf0\x9e\xee\x02\xcf\x43\xcc\xd1\xdc\x20\x83\x0d\x87\x8d\x6b\x4b\x19\x4e\x4f\xbb\x65\xcd\xb2\x72\x50\x26\x27\x83\x28\x09\x92\xb4\xe7\x1c\x5f\xd9\x56\x37\x18\x81\xed\xe5\x31\x49\x92\x96\xd1\x6c\x67\x6b\xde\xbf\xf6\x43\x83\x38\x48\x55\xe0\x8a\xd3\xcc\xb2\xbc\xd3\x25\xf2\xb4\x6d\x6a\xb8\x91\xa3\x08\xe2\x80\xa7\xcd\x96\xb0\x2a\xf6\x25\xfb\x80\xb1\x6c\xdd\xdf\x26\xd8\x67\x64\x10\x87\xe6\x5c\x78\x79\x45\x46\xef\xdd\xfc\xf9\xe9\x6d\xb3\xfb\xfe\xbc\x5d\x3f\xdd\xbb\x11\x88\x13\x29\x59\x5b\x18\xd0\x9c\xa9\x6f\xa7\x13\x94\x73\xdd\xe9\x73\xc8\x20\xf1\x69\x62\x39\x49\x16\x8b\x6f\xa6\x1e\x83\x7a\x83\xd5\x1b\x24\x91\x6f\xe5\xaf\x1a\x63\x1e\xcf\xef\xc6\x9d\xaa\x56\xfd\xfb\xc4\x71\x4a\x5a\xfc\xfa\x74\xa6\x23\x48\x62\x23\x46\xfb\xa0\xf7\x56\x2b\xc8\x35\xc8\x08\x4b\x2e\x0c\x36\x70\x30\xb9\xd3\x20\x02\x68\x77\xd8\x1e\x7f\xeb\x93\x2e\xfe\x03\xa5\xb6\x33\xbe\x32\xbb\xed\x64\xb4\x2a\x48\x13\x81\x4e\xdb\xeb\x6c\xbb\xda\x3d\x3d\xef\x96\xeb\xcd\xa2\x63\x23\x92\x41\xaa\x42\x0c\x3c\x98\xc0\xff\x08\x94\x31\xbc\x15\x8b\xb9\x74\x54\xa4\x6d\xac\x68\x76\x9d\xad\xfb\x3f\xfe\xd7\xfd\x8a\xf0\xb1\x62\xf2\x41\x7f\xf4\x98\x7f\x65\xc0\xbd\x00\x97\x19\x3f\x5f\x9e\x8b\xc6\x60\x3d\xd7\x60\x15\x64\x06\xb3\x2b\xe9\x80\x83\xbd\xcc\x43\xc0\x3d\x81\xa0\x72\x3e\x26\xbe\xbb\x42\x17\xca\x80\x87\x21\x62\x90\x8f\xba\x68\x96\x0f\x32\x12\x6c\xf5\x44\xc0\x3f\x10\x24\x54\xd4\x01\x10\x2a\x7d\x2e\x05\xa2\x3a\x6b\x66\x43\xf5\xff\x1d\xfe\x8f\xdd\x41\xdc\xbf\x7c\xef\xbf\x43\xf7\x3b\x42\x12\xe3\x29\xd6\x32\xcf\xb8\x7b\x51\x29\x81\xf4\x13\x95\x6d\x3e\xf9\x59\xad\x6b\x38\x56\xd6\x09\x1d\x6e\xeb\x01\x78\x2a\xb6\x12\x13\xcb\x92\xed\x6f\x53\x1e\xb9\xfe\x7e\xaa\xac\x39\xf7\x60\xce\xb8\xe6\xe6\x03\x71\xc4\xe1\x05\x8a\x18\xf0\xeb\x12\x3e\xaa\x23\x33\x54\x65\x77\x9d\x91\x14\x12\xe2\xbb\xe2\xde\x2d\x08\xc3\x40\xed\x4d\x5a\xf7\x21\xf1\x3c\xb4\x45\x1a\x8f\xac\x6a\xaf\x8f\x08\xee\xd6\x3f\xf4\xe7\xe3\xb9\xca\xc4\x32\x63\x47\x5d\xc8\x6b\xa9\x13\x19\x92\x54\x58\x6c\xd8\xa8\xfd\x0b\xcc\xa8\x0c\x89\x94\xd4\xf0\x5b\xc9\x5e\x00\x0e\x91\x77\xee\x19\x7c\xdf\xc3\x5a\x06\xc7\xb6\x6e\x0e\x62\x53\xd9\x37\x7c\x04\x3f\x90\xe8\xc6\xe6\x7a\xdf\x0c\xc4\x6c\x0f\x23\xe1\xcd\x2b\xf7\xb5\x9d\x8a\xa1\xcf\x0d\xb4\x0d\x55\x73\x1e\xe0\xd5\xad\xc5\x30\x08\xa4\xe0\x03\x3d\x12\x84\xd4\xf6\x7c\x93\x30\x48\xa1\x97\xa3\x69\x83\x30\x8e\x15\xee\xfd\x22\xae\xc5\xbb\xfa\xbf\x1d\x52\x8a\x43\xbf\x73\xe8\xd8\x4d\x2f\x34\x35\xfc\x4a\x61\xaa\x6c\x1c\xa3\xc6\x02\xc8\xd2\x49\x51\xdb\xf4\xec\x70\x29\x84\x91\x97\x3a\xe6\x48\xcb\xdb\xfa\xaa\xf5\xb0\x86\x59\x86\x91\xef\x19\x79\xeb\x5a\x97\x30\x3b\xd7\x07\x28\x9a\x57\x68\xa5\xe4\x5c\xb7\x24\x71\x6c\x51\x16\x2a\xf3\x92\x89\xfa\x5c\xc2\xf4\x93\xc6\x96\x9e\x02\x2b\x6f\x97\x4f\x9b\x7f\xea\x62\xe4\x09\x84\x31\x33\x79\xf9\x73\x51\x42\x73\xad\xe3\xa1\x93\x61\x2c\x00\x03\xf0\x50\x1f\xee\x74\xf9\x98\xe5\x50\xd5\x2d\xeb\x96\x0c\x13\x16\xcb\x16\x05\x55\xd7\x58\x12\x3f\x56\x5f\x95\x61\xaa\x94\x34\x9b\xf8\x4f\x33\x67\x8c\xa7\x67\x5b\x19\x35\x3a\x39\xa7\x52\x1f\x75\x0f\x64\x27\x43\x96\x28\xcf\x3a\x30\xab\xc6\x03\x9f\x92\xe0\xb4\x5d\x79\x4c\xf1\x50\x3f\xb0\x6a\xae\xf5\xb5\x03\x10\xf2\x24\x8d\xa0\x35\x8d\x1f\x7b\xf5\x63\x13\x8b\x81\x2b\xd1\xf2\x00\x41\xf9\x91\x09\x14\x95\x9d\x5f\x9a\x13\xe0\xb7\x09\x00\x8e\x0c\x05\x8d\x92\x66\x83\xd1\x4a\x89\x03\xcb\x8a\xb7\x53\xae\x99\xfc\xe2\x27\x44\x10\x61\x30\xe5\x47\x07\x12\x09\x45\x44\x31\x41\x7a\x72\xc5\x0b\xbd\x78\x4e\x28\x64\x0a\x71\x4b\x20\xbb\x7d\x76\x17\x49\x2f\x89\xbc\xae\x8e\x0c\x23\x25\xc3\xb1\x91\x91\x8f\xe0\xca\x63\x56\x18\xa4\x43\x8f\xd7\x44\x86\x92\x71\x74\x7b\x59\x55\x41\x59\xff\xa9\xcf\x8d\x4f\xec\x90\x03\x93\xbb\x63\x73\x09\xfa\x2a\xff\x60\x35\x2b\x7b\xa7\x50\x08\x9e\xc0\x72\x2b\x26\xa5\xd3\x85\x9e\xfe\x5c\x10\x44\xc2\x0a\x7a\x18\x0d\x39\xfb\x77\xe5\x07\x26\x52\x73\x3e\x7e\x63\xa5\x5c\xb0\x93\x83\xff\x06\x6d\x17\xee\xea\x11\x40\x1a\x86\x17\xab\xfb\xd8\x9f\xf4\x11\x09\x03\x4c\x33\x3e\x6a\x21\x58\xef\x11\x23\x12\xc6\x5e\xea\x32\x4a\xed\x0e\xd1\x0f\x91\x46\x24\x12\x68\x8e\x4a\xf8\x18\xd2\x3f\xca\x88\x86\x2a\x68\x69\x63\x74\x85\x97\xb5\xc6\x7a\xe4\x51\x4e\xd1\x2c\x65\xfa\x91\xf5\x6d\x95\xc8\xf3\x24\xb1\x24\xaa\x06\x8a\x70\x2d\x4e\x3b\x78\x7c\x8f\x4b\x66\x83\x2c\xe8\x73\xdb\x00\x41\x1f\x69\x10\x79\x8a\xe2\x57\x40\x7e\x39\x5d\x4e\x5b\x38\x91\x4f\x19\x46\x3c\xe6\x0f\xcf\xbb\x97\xd5\xeb\xee\xc7\x6a\xed\x1e\xca\x67\x41\xd4\x62\x60\xde\xaa\xb6\x0c\xdb\x36\x07\x0c\x02\xde\xb3\x93\x31\xf5\x30\x3a\x58\xa3\x40\x99\x4a\xae\xc7\xf5\xd3\x7c\xb5\xdd\x29\x5d\x3e\xbf\xce\x16\x0f\xeb\x7f\xba\x98\x6d\x14\x7a\x02\x09\x3b\x10\x68\x5b\x38\xcd\xae\xb6\x35\xb4\x1c\xf7\x52\xce\x1c\xc9\x93\x5c\x63\xf5\xe9\x80\x93\xcf\x75\x97\xb1\x89\x5e\x37\xfe\xb9\x61\xe2\x69\xe9\x74\x4e\xe7\x6b\xbe\xf1\xe1\xd5\x91\x34\xb5\x27\xd9\xf1\x94\xef\x1a\x3b\x2d\x58\x66\x58\x9c\x34\x2d\x14\x25\xa3\x08\x0c\x4d\x11\xd4\x87\x6e\x4d\xd8\xb6\x38\x96\x38\xc3\xfe\xd5\x4c\xae\xc1\x76\x1a\x25\x11\xa1\xb4\x75\xad\xc6\xa5\x48\xae\x13\x70\xa3\x4d\x8f\xf4\xc0\x37\x16\x4a\x94\x46\x81\x93\xea\x9b\x43\x55\xcf\x8a\x3d\xe4\xc3\x69\x90\x0a\x86\x53\x05\x7e\x9e\x1e\xf5\xd7\x05\x72\x32\x62\x24\x44\xd0\xa6\x30\xac\xa7\x95\x29\xbf\x77\xaf\x84\x0e\xdf\x7f\xfd\xbf\xff\xfa\xa6\x65\x0e\xe5\x63\x3f\xb4\x1b\x31\x50\x88\xa7\x98\x03\xab\xad\xf8\x67\x2b\xc7\xdb\xdd\x81\x7b\x22\xb5\xeb\xe3\x21\xab\xfe\x42\x52\x7e\xf4\x6c\x3c\x34\xf5\xfc\x46\x39\xda\xb1\x4a\xb8\xc6\xd4\x70\xed\x1a\x94\x77\xcd\x44\x6d\x2d\x8a\xc1\xb2\x11\x49\x1c\xd9\x5a\x19\x57\xf1\x5e\x40\x5e\x0d\x56\xb7\x90\x34\x00\xc3\x0b\xf0\xa0\x8b\xfd\xea\x27\x94\x22\xab\x3a\xef\xaa\x9f\x81\x4a\xfe\xe7\xc6\xb3\xca\x94\xe3\x71\xd3\x7c\xf7\x66\x6e\x3c\x7f\x1f\xe6\x50\x22\xa9\x8c\x5c\x54\xb3\xcd\x98\xe0\xdc\xfa\xd6\x24\x03\x1a\x86\xe0\x8e\x73\x13\x27\x69\xc6\x76\xf1\x3c\x9a\x30\xc0\x0d\xef\x4b\x73\x28\x65\xc5\x3e\x87\xcd\x99\xa3\x3e\xd9\xe5\x2b\xb4\xb8\x8c\x40\x99\x10\x99\xad\x25\xd8\x5e\x4e\xd3\x32\x6a\x32\x52\x09\x51\xed\x2f\xec\x0b\x56\x77\x6c\xd3\x32\x26\x09\x25\xac\x95\x0d\xcf\x8a\x65\xc9\x3e\xaf\x0f\x9b\x98\x28\x03\x8c\xff\xc7\x39\x13\xef\xa6\x20\xc4\xb6\xd0\x80\xd0\x01\x09\xd4\x63\xe3\x6c\x3c\x9f\x6b\xa1\x8f\xd0\x38\x4b\x26\xba\x28\x7f\x1b\xdc\x8f\xc6\x51\x04\x2d\x3d\xfa\x06\xc9\x18\xe5\x38\x7a\x16\xd3\x18\xd0\x27\xd9\x39\x98\xd8\x3f\xce\x70\xb6\xa9\x2b\xd7\x85\x51\x24\x7e\x42\xf5\xd4\xb7\x97\x97\x87\x3f\x77\xcf\x77\xa6\x2e\xb5\xed\x22\xcc\x21\xde\xb2\x0a\x22\x1e\x64\x5a\x8b\xab\x3f\xef\x62\xcf\xf3\x04\x6d\xab\x7c\x8d\x8d\x83\xe9\xe9\xe1\xd8\x78\xbe\xc2\xc4\xda\xe3\xe2\x90\xb9\x58\x57\xec\x49\x81\x0c\x20\x08\x0c\x77\xa1\xab\x2e\xd0\xd9\x5d\xed\x53\x09\x5d\x59\xf4\x4b\x63\x2d\xb9\x28\x37\xcf\x6f\xaa\x94\xb8\x8b\x3d\x00\x66\x9d\x02\xb3\x5b\x79\xc4\xd9\x22\x71\x40\x29\x7a\xc1\x06\xc0\xff\x04\x65\x9d\xb1\xe9\xc9\x14\x07\x3e\x41\x12\x85\xd7\xd5\x62\xb5\xfe\xbe\x7a\x75\x6f\x11\x28\xc3\x64\xdd\x7e\xdc\x45\x9b\xcc\x1f\x07\x10\xe3\x30\x0c\xa4\xc5\xa5\x1b\x0c\xa0\x59\x20\x2b\x0b\x81\x3e\x77\x3c\x24\x32\x8e\x7c\x0f\xf3\x81\x0a\xb3\xee\x8e\xfa\xd4\x68\x05\x8c\x6e\x1b\xf9\xa9\x82\xff\x75\xfd\xe7\xe0\x3b\x46\x81\x87\x75\x1b\x4b\xc8\x4f\x87\xac\x7f\x82\xc7\x51\x10\x23\x84\xeb\xf9\x34\x28\x92\x1c\x4e\xc3\xd8\x4f\x90\xed\xbe\x99\x63\x46\x98\x79\xb6\x7c\x7e\xd9\xae\x96\xbb\xd9\x1f\xeb\x95\x03\x20\xc4\x89\x14\x46\x93\xa8\x39\x78\x7f\xb0\xa2\x60\xf3\xf3\x65\x90\x1e\x89\x13\xe5\x23\x58\xd9\x68\x81\x1b\x0a\xac\x1e\xcd\xa0\xa9\x0d\x9e\x8c\xa5\xc4\x69\x64\x64\x12\xac\x40\x87\x99\xea\xb3\x75\xfb\xa9\x52\x91\x7a\x6d\x9d\x6c\x9f\xfb\x67\x3a\xe4\x10\x33\x1a\x40\x3b\xb9\x4d\xca\xef\xe5\xcc\xf3\x4c\xf4\x10\x1a\x31\x0b\x15\x4a\x64\xb1\x73\xad\xfb\xb0\xab\xef\x19\x5b\x6d\xbf\xf5\x01\x4d\xed\x86\xc2\xa2\xd8\xe8\x4b\x36\xa3\x30\x3c\x5c\x63\x4e\x52\xcc\x92\xac\x8b\x0c\x81\x49\xb7\x06\x9c\x47\x09\x62\x57\x41\x66\xf5\xa0\xb2\x7e\xc2\xf0\x1e\x9b\xe0\x31\x8f\x8c\x95\xcf\x11\x02\xb6\x59\xad\x96\x9b\xac\xef\xcc\x8e\xe8\x49\x65\xcc\x99\x12\xb1\x2b\x75\x9c\x5e\x6e\xe3\x2b\x94\x44\xa6\xd2\x05\xab\x0e\xa2\xbf\x19\x8a\x28\x92\x06\x78\x95\xe7\xb3\x3c\x7f\xcc\xf2\x77\xd7\xd4\xf8\x4b\xa2\x8d\xb9\xe6\xac\x1b\x15\xa9\x48\x62\xa0\x26\x45\x75\x76\x10\xa0\x18\x08\x35\x3a\xda\x3a\x7f\xbf\x87\x02\xaa\xec\xda\xb8\x1c\x6f\x0e\xc3\x51\x04\x2f\x42\xea\x8d\xc6\x1a\x3f\x1a\x32\x9a\xc7\xac\x30\x44\xf6\xd5\x80\xa3\xf0\xc6\xee\x02\xcd\xfa\x37\x56\xdc\xdf\x35\xdf\xbc\x67\x79\x3e\x45\xed\xd0\x74\x14\xf8\x6e\xa6\x18\xf6\x91\x65\x45\x0d\x05\x73\xc5\xe1\xae\x53\xe3\x58\x36\x2f\x84\x29\x9a\x87\x96\x3a\x45\xc6\xc0\x43\x24\x8d\xc7\x0c\x7a\xd8\xfe\x55\xfa\x58\xee\x0a\x86\x10\xd9\x85\xbd\x46\xef\x28\x53\xcc\xd3\xae\x72\x38\x65\xfb\xc1\xd2\x06\x00\x83\x35\xc5\x87\x5a\xe3\x8b\x55\x9d\xc2\xc9\xdf\x46\xd3\x46\x11\xcf\x4c\x9b\x31\xfd\xc7\x7f\xd3\xe8\x7f\x46\x23\xab\x02\x42\x79\x67\x6f\x35\xd3\xb9\xb5\x69\x62\x95\xca\x38\x72\x6a\x5d\x86\xa2\x05\xc5\x24\xda\x15\xa2\x58\xe0\xdb\x6a\xff\x3a\x87\x3b\x00\x53\x31\x89\x30\xec\xe9\x0f\xa1\x98\xc4\x75\xc3\xcf\x57\x90\x6c\xd7\x43\x19\x42\xb6\x03\xab\x7e\xe8\xf2\x7d\x28\xc2\x25\x13\x62\x59\xbc\xff\x90\x4c\xf4\x07\x29\x21\xcc\x20\xf1\x8c\xb3\x50\x74\x15\x20\xd2\xd9\xd0\x55\xdb\x15\x54\x1a\xb8\x0d\xc3\xa5\x59\x47\x76\x42\x42\x89\x42\x40\x98\xe1\x88\x31\xb4\xa6\xa3\x1e\x09\x31\x4c\x9e\x07\xfd\x69\xc4\x8a\x5c\x83\x90\x68\x64\x7e\x64\x79\xce\xf6\xd0\x23\x52\x95\x09\x95\x11\x06\xee\xcc\x21\xb9\x34\xba\x10\x0f\x8d\xb9\xa4\x8b\xfd\x82\xdd\x56\x24\xfa\x72\x1d\x27\x54\xf9\xc6\x8b\x62\x65\x01\x97\x2a\xf8\xc6\xc4\x3b\x94\x9b\x13\x13\x30\x18\x25\x8f\x19\x06\x49\x04\x0c\x14\x2c\x37\xe7\xdb\x95\xde\xf0\x0d\x50\xe6\xe8\x47\x3d\x29\x98\xd3\xdb\xc4\xc2\xad\x03\xab\x0e\x0b\x5d\x96\x20\xea\xb6\x00\x57\x26\x7e\x42\x91\x30\xce\x20\x4d\x97\x50\xd5\x99\x89\xcf\xdd\x8e\xb6\x75\x61\x85\xc4\xe7\xa6\xf6\xe5\xde\x21\xdf\xfb\x07\x62\x12\x84\x66\xff\xaa\xb5\x39\x71\xdc\x9f\x81\xf2\x4e\xc6\xaf\x23\x0e\x18\xd7\x6f\x63\xb5\x3f\x8b\x9c\xc3\xcc\xf8\xe8\x13\x07\xc0\x10\x1b\x71\x34\xfc\x18\xee\xd0\x1e\x1c\x85\x49\x94\x02\x1e\x85\x3b\x0c\x4e\xfb\xbb\x4c\x68\x2b\x40\x33\x92\x2c\x96\x49\x24\x28\x96\xdf\xde\xb3\x23\x96\x5d\x66\x53\x1c\x5d\x89\xeb\x0c\x40\x0c\x0f\x53\x55\x3d\x77\xcf\x6f\x5b\x63\x6a\xf8\xb2\x8d\x4d\x34\x39\x6d\xda\x45\x13\xfb\xbe\xf1\xc4\x91\x93\x15\xae\xf1\x16\xd7\x87\x4f\x12\xa7\xcc\x78\x62\x0e\xf6\x35\xbf\xcc\x46\xa3\x93\x44\x3e\x22\xba\x76\x59\xd5\x98\xe3\x20\xcd\x07\x1a\x2e\xd8\x24\x55\x08\x5e\x7a\xdb\xac\x5e\x77\xdb\xf5\xe3\xea\xf9\xcd\x45\x4c\x93\x44\x26\x36\xab\x7d\xd9\x9d\x3a\x9b\xd9\x7c\x7f\xda\xde\x41\x85\xae\x32\xd6\x66\xa4\xd8\xbe\x19\xdd\x6a\x36\x4a\x56\x26\x29\x18\xdd\x78\xcb\x21\xfe\xc0\x0a\xd4\xb7\x74\x47\xe1\x84\x45\x95\xb0\xd4\x98\x3a\x58\x4c\xb3\x71\x73\x6c\x38\x47\x18\xf8\x88\xad\x3e\xe9\xf7\x69\x69\x57\x99\xf0\x20\xc2\x30\xc1\xe2\xf9\x71\xb5\x7d\x9b\xbf\xb9\x37\xe4\x51\x14\xc6\x1d\xf2\x77\x59\xea\xe2\x1a\xf2\x6c\x78\x47\xda\xf3\x25\x11\xbe\x90\x36\x35\xbb\x65\xc5\xfb\xe8\x69\x04\x10\x64\x22\xdd\xb3\xea\x05\xca\xed\x4f\x33\xde\xd6\x1e\x4d\xa4\x6f\x02\x57\x8b\xc5\xb7\xdd\x6a\xb9\xde\x3a\xc6\x17\x99\xc8\x50\x61\x40\xaf\x39\x85\x86\x6f\x31\x5a\xd6\xd0\x38\xed\xdd\xe2\x01\x76\x9c\x52\x60\x94\x09\x48\x1f\x0b\x9b\x77\xbb\x13\xe2\x95\x86\x8f\xa9\x42\x82\xbc\x04\xcd\xa5\xef\xed\x5e\xa0\x52\x62\xf8\x49\xb5\xce\x0d\xbb\x56\x0f\x32\x71\x63\x6f\x53\x42\x18\x5e\x07\x4c\xbc\x21\xaf\x70\xcf\x02\xea\x8e\xc1\x09\x43\x6a\x3c\xab\x53\x12\x45\x8e\xa5\x6b\x57\xeb\x5d\xcb\x45\x2e\x53\xea\x47\xbe\x03\xc8\x58\x72\xf3\x7e\xa2\x3b\xa5\xb1\x61\x9c\xc4\x00\xb9\x85\x95\x99\x0a\xd0\xc9\x73\x2c\xf5\x20\x88\xac\x83\xfd\x74\x3e\xce\x4d\xf0\xd9\x6d\x50\xa9\x1f\x19\xf0\xd3\xf6\x75\xf6\xb4\xb9\x5b\xbd\xee\x5e\x5e\x9f\xff\xf8\x73\xf7\xdd\x7d\xad\x34\x90\x29\x22\x09\xf5\x67\x51\xcd\xf2\xab\xa8\x72\xfb\x42\x51\x18\xab\x8e\x0d\xa0\x25\x8b\xa4\xc3\x69\x9e\x46\x11\xc3\x55\xb8\xb3\xc3\xb5\xd5\x96\xb5\x76\x30\x8d\xd3\xd8\x97\x4e\x7a\xc3\x14\xd6\x8d\xd7\x42\x1a\x47\xa2\x2d\x53\x67\x35\xdb\x79\xc1\x60\x43\x4e\xe3\x34\xa0\xb6\x8c\xac\xf9\xc6\x3d\x40\xc5\xf0\xab\xa6\x09\x70\x8c\xfa\x5b\x9c\x83\x93\x2d\xb6\xad\x69\x10\x21\xdb\x3b\x2b\xaa\x4f\x28\x97\x90\x67\x1f\x50\x5e\x16\x87\xc6\xe2\xea\x51\xa6\xba\x58\x48\x14\x7c\x39\x0f\x26\x31\xbb\x3d\xed\x03\x3b\xfd\x86\x9a\x71\x32\x65\xa9\xc2\x77\xd9\xac\x9f\xee\x1f\x56\xbb\xf9\xc3\xf3\xe2\xf7\xdd\x43\xeb\x8e\xa7\x8c\x2b\xdf\x46\x73\x3a\x1b\xe3\xcb\x18\x52\xca\x04\xe5\xc2\xc9\x70\xda\x12\x8f\x4c\x17\x0f\xfd\x7c\xcf\xf0\x0a\x1e\x18\xbd\xde\x1f\x23\x99\x83\x64\xfc\x1e\x57\xcc\x45\xa3\xfb\x24\x04\x63\x8b\xa7\x81\x4c\xfd\xa8\x8f\x04\x8c\xa1\x65\x95\x21\xd0\xea\xa5\xae\x52\xe1\x25\x44\x39\x02\x90\x0f\x78\x2b\xf3\xe1\x87\x97\x01\x67\x06\x4c\x8d\xd8\xde\x55\x7d\x18\xcd\x1c\xa9\x08\xd6\x8f\xa3\xcc\x3b\x46\xcf\x2c\xf4\x61\xd4\x0f\x7c\x40\xd5\xf8\xc7\x8b\xd7\x37\x5d\x52\x10\x34\xb6\x33\xef\xbe\x1c\x28\xdf\xca\x54\x79\x04\x4f\xf1\xc7\xf5\xd3\x00\x90\x9b\xaa\x94\x21\xc7\xa1\xc3\x26\xed\xce\x85\x30\x81\xbb\x1d\x1f\xa6\x10\xdc\x05\x3c\xc6\x60\x57\x0d\xec\xd8\x89\x73\x4b\x46\xa8\xc1\x01\xe1\x09\x54\x75\x8e\x25\x23\x34\x01\x9b\x43\x9e\x9f\xcb\xe2\x0e\x60\xc6\x47\xb6\x24\x23\x11\x45\x1e\x8a\xc5\x6c\xbb\x79\x99\xb5\x4f\xc7\x48\x24\x8d\x01\xe5\xb8\x41\x17\xba\x6a\xcd\x48\x46\xed\x99\xd2\x78\x2b\x9b\xcf\xac\x16\x87\xb6\x25\x6d\x39\xa6\x6d\x11\x94\x65\xa0\xb3\xe9\xbd\xd1\xcf\x53\xe6\x07\x6d\x4d\xce\x77\x5d\xc3\xef\x59\x21\x0b\xa8\xaa\x55\xb3\xa8\xda\x9b\xb2\x04\xe3\xbd\xdf\xdf\x5e\x30\x10\xbf\xda\x7e\xdb\xad\x17\xcf\xbb\xed\x7a\xf5\xea\xed\x5e\x67\xdb\xf6\xb1\x29\x8f\x31\x42\x89\x2c\x79\xe6\x87\xd7\x55\x75\x86\x1e\x4e\x9a\x51\xe5\x33\x03\x6a\x32\xd8\xc9\x5b\x12\xfa\xc3\x5d\x93\x79\x81\x44\xff\xeb\x77\xe0\x50\x9e\x8b\xfa\x5c\xec\x59\x31\x13\xcc\x79\x58\xcc\x13\x02\x64\xbb\xad\x72\x28\x11\x93\xd3\x69\xbc\x4b\x16\x04\x24\xb5\x08\x31\x4b\xb9\x3b\xd8\xe3\x58\x20\x88\x0b\x37\xb6\xd8\xd1\x36\x31\x35\xfd\x54\x21\x67\xc4\xb2\x9d\x3c\x69\x69\x34\x0e\xd6\x72\x74\xdf\x50\x28\x53\xad\xd0\xe9\x22\xcf\x3b\x5a\x4d\xc9\x22\x3f\x42\x43\x56\xe8\xe3\x89\x95\x60\xd5\x07\x26\xa2\x75\x2c\x0a\x63\x44\x4b\x59\x76\x8e\x9d\xcd\x5c\xee\x94\xfd\xff\xeb\xec\x08\x3b\x68\x23\x87\x2c\x4a\x0d\xc3\xc8\x8b\x2e\x32\x51\xdd\xa2\x7e\x1d\x85\xeb\x58\xc4\xa9\xa1\x13\x32\x31\x3a\x90\x8b\xae\xae\x96\x45\x10\x22\x51\xc5\xec\x2c\xea\x73\x65\x6a\xd0\x26\xaa\xd5\x58\x4c\x22\xf4\x1f\x9b\xf3\xf4\xc0\x4a\xb9\xcb\xaf\x48\x11\x24\x8b\x53\x8a\xde\xf7\x68\xbd\xdf\x72\x71\xec\x55\x49\xea\x63\x71\xf1\x51\x83\x1c\x24\xab\x58\xc2\x62\x24\x49\xb0\xf5\x31\x58\x17\x6c\x26\x83\x09\x19\x75\xee\x16\x4b\x84\x42\xae\x75\x83\xc1\x79\xcb\xc6\xbe\xb3\xeb\x06\x21\x52\x6a\xac\xab\x05\x2b\x9a\x6d\xb9\x9e\x21\x5e\xd5\x36\xa7\xa9\x99\xcc\x7f\xf1\x02\xb6\x37\xa3\x29\x86\x20\xb7\xf7\x8f\x75\xff\xb1\x99\x2f\x90\x2d\xd9\xc0\x66\xe7\xd0\xad\x74\x16\xfb\x98\x7d\x7b\x75\xa5\xfb\xbf\x94\x90\x60\x8c\x99\xb0\x68\x73\x98\x1c\x7a\x87\xf9\x08\x78\x35\x9c\x5c\x8c\x33\x8c\xf1\x22\x0f\xc0\x0a\x0d\xe4\x76\xd1\x72\x11\xab\x01\xdb\x09\x7a\x85\x2d\x02\xcc\x3a\x26\x4c\x70\x23\xdb\x82\x55\x63\x36\x87\xf1\xdb\x97\x3c\x79\xa3\x07\x17\xc2\x98\x19\xcd\x7a\xca\xc4\x7b\xd1\xab\x41\xb1\x3d\x24\x15\x98\x44\xfd\x9e\x55\x27\x28\x6d\x3d\xb5\x7b\x4c\x19\x24\x38\x90\x9d\x8f\x3f\x4a\xe6\x5e\x1b\x7e\x4c\x46\x12\x89\xa6\x7e\x3f\xff\x2b\x2b\x59\xc7\x7f\x26\x9b\xa3\x0d\x77\xb3\xac\x68\x6c\xa8\x0a\x1e\xd9\xcf\x5e\x59\xbe\xeb\xc4\xa9\x63\x25\xfb\x3b\x86\x6f\xc6\xcf\x2b\x0c\x45\xdc\xb9\xd0\x9f\xed\x07\x07\x92\xe0\x36\x6d\x6c\xb3\x75\x0d\xc7\xe9\x7c\x35\x03\x66\x94\xb3\xd4\x14\x14\xbe\x73\x0c\x98\xf2\x12\x69\x41\xc2\xe2\x60\x8b\x2a\x27\x4f\x72\xa6\x62\x81\x71\x47\x93\xa8\x19\x57\xb1\x30\x95\x08\xd4\x48\x16\x07\x56\xee\xe1\x79\x9a\xf3\x44\x72\x9a\xc4\x68\x0f\x20\xe1\xaf\xd3\x82\xea\x0c\x2d\xfc\x57\x38\x5c\xb6\x9c\x32\x89\xb8\x52\xac\xc4\xba\x6f\xb5\xa9\x46\x9d\x84\x8c\xad\xb1\xfd\x56\x9c\x98\x63\xe6\x96\x9c\xaa\xc8\xe5\xaf\x37\x42\xf7\x10\x23\x83\xbd\x96\x7b\xb1\x04\xe9\x0e\x4e\x43\x13\x9b\x1d\xc7\x21\x1c\xee\x81\x51\xd6\x75\xc1\x0e\x47\x85\xbe\x80\xb2\x87\xee\xbe\xf6\x80\xb8\x1f\x7b\xb1\x35\x62\x7f\x00\xaf\xb2\xfa\xca\xdc\xe1\x3e\x33\x9a\x42\x12\x98\xcc\xb3\x02\xb6\xfa\xae\x04\x90\x8d\xb7\x84\x28\x10\xdb\x2d\xf0\xa8\xdf\xa6\xb0\xbb\xfa\x1e\xd7\x1a\x30\xbf\x03\x87\xdb\xdd\x69\xba\xd4\x92\x07\x4c\xf9\x36\xcf\xf4\xc0\x90\x38\xf1\xd4\x49\x10\x48\x1e\xc8\x34\x25\xad\x16\x7b\x1b\xc3\xe3\x21\x89\xf0\x39\xef\x66\x8b\xed\xf3\xeb\x2e\x6c\xff\x1e\xfb\x98\xff\x6b\x41\xdb\x7a\x9a\xdf\xbb\xe9\x19\xc7\xd6\x91\x59\x96\xec\x13\xcf\x34\xb3\xdb\xce\x2f\x43\x62\x60\x77\x01\x0b\x10\x55\xd7\x18\xb5\x16\x0d\xfc\xc2\xb2\xeb\x6a\xc3\x89\x19\xce\x43\x16\x62\xb1\x19\x08\x61\x88\xd3\xbe\xde\x57\xdc\x55\x92\x61\xcd\xf4\x6e\x0f\xb5\x39\xf3\x5f\x58\x26\xdf\x4e\x23\xfd\x6b\xc9\x23\x4a\xd0\x48\xb5\x95\x9c\x4f\xba\x0b\xe9\xf3\x28\x16\x41\xf3\xd8\x7f\x64\xba\xd8\x2f\xb3\x87\xcc\xa9\xf5\x4e\x0f\x4b\x94\x84\x08\x55\x97\x48\xe6\xad\xcb\x76\xb7\x3c\xb0\x12\x1c\x9d\x51\x7b\x6f\x48\x90\xaf\xee\x1e\xea\x65\x56\xe5\xd9\xfb\xa0\xe6\x8d\x47\x2a\xf2\x55\x5b\xa2\x79\x84\xe2\x86\xf0\xb9\xe4\x71\x10\x21\x39\x35\xcf\x31\x52\xd1\xfe\x40\x1c\x87\x18\xaa\xc5\x64\xef\x03\xb0\xf7\x11\x8f\xba\xe4\x89\x17\xa4\xfd\x6d\xce\x11\x3c\xbd\x94\x60\x82\x37\xbf\x0d\xd8\x07\xbe\x3e\x7a\x78\x12\x24\xe8\x0d\x3f\xfd\x73\xb9\x7b\x3e\x16\x99\xd4\x79\xce\x9c\xf7\xc6\x93\x44\xf0\x76\xd6\x1b\xd0\xf4\xba\xf5\xb4\x79\xe3\x84\x03\xc6\x4a\x1e\x96\xeb\x1e\xb6\x9f\xb3\x30\x00\x57\xa9\xca\xb0\x3c\xa0\x93\x0b\x96\x5c\xa4\x1c\xda\x82\x9c\xaa\xc6\x5a\xd0\xe9\xfd\x94\xcb\x34\x0e\x4d\xe1\x68\x75\x76\xaa\xb2\x7d\x67\x9e\x4b\x16\x22\xc9\xf6\x87\xae\x61\xab\x7f\xcf\xc4\xbb\x56\xea\x09\x3e\xef\xb2\x4a\xb0\xfc\x4f\xe8\x5e\x45\x42\x8c\xa4\xad\x66\x89\xa2\x94\xc3\x2b\x2b\xde\x51\xda\x69\x53\xeb\xf2\x82\xdc\x80\x76\x9a\x52\xcf\x85\xae\xdc\xb9\xc3\xc1\x53\x46\x9d\x83\xeb\x12\x8b\x52\x86\x4f\x0a\x4a\x29\xbb\xaa\x5d\xe6\x0c\xea\xea\x4e\x97\xc3\x12\x94\xe1\x24\x50\x5e\xaa\x64\x9f\xd9\xaa\xf1\xc4\xef\x74\x79\xdf\x93\xd6\x19\x5f\x12\x06\x58\x2a\x63\x8d\x53\x9b\xcd\xba\xd3\xa5\x41\xbb\x64\xc5\xbe\x2d\x07\x32\x57\x08\xe2\xb1\xc8\x86\x02\x66\x55\x75\xa5\x48\xef\x7a\x05\x1e\xd2\x71\xf5\x33\x4e\x18\x7f\xf0\x12\xd7\x23\x12\x68\x81\x61\x70\xd4\x84\x9b\x1d\xf0\x79\x8c\xb3\x17\xd4\x4b\xc0\x94\xa2\xb5\x0c\xc6\x52\xd0\x20\x42\xe4\xea\x3f\x1f\x9c\xb8\xb9\x14\x94\xa7\xa8\xa9\x94\xb3\x6a\x04\xc4\x10\x54\x1a\xe4\x03\xc6\xbe\x7f\x5f\x3f\xf6\x2d\x47\x41\x55\x8c\x74\x0d\x0f\xac\x60\x8b\x03\x2b\x73\x80\x22\x71\x8d\x1e\xe1\x08\xcc\xb7\x52\xce\xa3\x48\xb1\xf0\x7c\x13\xc8\x14\xac\x30\x7b\xcc\x16\xca\x63\x56\x5c\x55\x44\x0b\x2f\x25\x9e\xd3\x97\x9d\x15\x72\xd3\xf2\x8f\xe1\x19\xd0\xb8\x33\x02\x4e\x37\xdc\x7d\xe1\x89\x14\x5d\x45\xe8\x4a\x14\x84\x9f\x70\x73\x8e\xd5\xa8\x3e\xb2\x75\xc5\x9f\xae\xb0\x41\x04\xb1\x9f\x5a\x9e\xc3\x1f\x0f\x93\xa5\x6e\x22\x50\x11\x56\x24\x2c\xf0\xc4\x5f\x15\x50\xee\x87\xda\x8a\x52\x84\x81\x55\x63\xe9\x91\x67\x7c\x89\x92\x13\x91\x0c\x70\x0f\xdc\xd9\xcc\x16\xee\x81\x6c\x28\xba\x3c\x7c\x8c\xd8\x97\x43\x52\xb6\xea\x59\x4d\x84\x5c\x45\x2c\x83\xc0\xb0\x53\xe4\xc0\x4a\x94\x97\x7a\x7f\xd0\xa3\x8c\xba\x48\x02\x86\xb6\xc6\xe6\xfb\x6a\xf0\x99\x93\xd8\x4c\x8f\xc6\x89\xff\xee\x64\xd9\xba\x68\x4b\xdb\x8d\x07\x86\x9b\xe0\x78\xd2\x9f\x50\x1a\x61\x89\xe1\x73\x24\x2a\x0d\xac\x89\xbd\xfa\x29\xf2\x73\x95\x69\xac\xeb\xc7\x3b\x1a\xad\x87\xeb\x69\x9c\xc6\xa6\x46\xa7\xaa\xd9\xfb\xad\xa1\x63\xbe\x07\xb1\x0b\x6a\x37\x9b\xce\xcd\xc4\xcf\x70\x72\xb1\x84\x89\xc8\x05\x90\xdc\x99\xd3\x49\x2f\x4f\x9e\x1a\xa2\x31\x30\x71\x7e\x64\x47\xc4\x3e\xc8\x5d\x75\x35\xbd\x39\x31\xbc\x18\x0f\xeb\x07\xe7\xe8\x0b\x21\x38\x6e\x5e\xcf\x3c\x2b\xdb\x7a\x62\x21\x3d\x53\xb8\x8b\xbe\x17\xb0\xe3\x10\x59\x24\x64\xc0\xac\xda\x5c\x21\x9f\x60\xcf\x9a\x5d\xef\xc7\xe1\xac\x54\xd6\x2b\x0b\xeb\xdb\x52\x42\xa6\x24\xb4\x18\x32\x2c\xee\xbf\x9e\x0e\x12\x08\xa2\x2c\x98\x91\x30\xff\x3d\x3b\x6e\x58\x0e\xfd\x32\x56\x01\xd4\x14\x66\x43\x51\xbd\x1a\xd5\xc0\xb2\x6d\x4a\x08\xfa\x8b\xc7\x4d\xdd\x2f\xb4\x11\x2a\x48\x7c\xda\x83\xd3\x18\x3e\x70\x83\xf7\x19\xc7\xf9\x7b\x46\x8a\x50\x61\x8a\x85\x1d\x59\x65\x4a\x29\xcb\xe7\xd3\x78\xb9\xa9\xd8\x90\x33\xc8\xac\x62\x79\xae\x3f\x5b\xc6\x2b\xa8\x3f\x01\x8a\xb7\xaa\x0b\x58\x48\x12\x7a\x8e\x43\x04\xc1\xc9\x4e\xb5\xcc\x35\x27\x0a\x41\x3f\x42\x67\x05\x1f\x27\x9f\x1a\x3f\x09\xc3\x83\x06\x4c\x31\x0a\x27\x2f\x9e\x9f\xb6\xaf\xb3\x85\xcb\xb7\x48\x8f\x29\xab\x9b\x88\xf4\xf8\x7d\x6d\x9b\xf9\xc5\xa4\x38\x27\x67\xab\xf4\x63\x4a\x88\x0b\x8e\x4b\x28\xbf\xb1\xea\x70\x8b\xb9\xe5\xaf\x32\x96\xc3\xb9\x29\x7d\xae\xd0\x42\x3e\x22\x75\xe7\xb6\x4f\xa0\x51\x6d\xf5\xda\x9a\xee\xbf\xe6\x11\x4b\x5f\x31\xbc\x59\x75\x60\xcd\xfc\xda\x59\xb6\xad\xf6\x93\xcb\x80\xb4\xe1\xa3\xdf\xe1\xb2\x5e\x3a\xa8\x51\x3f\xf1\x26\x03\x5f\xa0\xde\x0e\x72\x61\x6f\xf5\x69\xa9\xdb\x8f\x11\x44\x11\xd6\xa1\x88\x83\x42\x45\x75\xa7\xc1\xf7\xe3\x90\xe5\xd0\x47\x8d\xcb\x80\x2b\xde\xf1\x9c\xda\xa2\x8e\x71\xb2\xe3\x57\xfe\x97\x0e\xab\xd8\x64\x20\xe2\x24\x68\xed\xa0\x73\x3e\x8a\x6f\xc9\x30\xf0\x89\xad\x31\x30\xf1\xa7\xaf\x10\x45\x32\xb4\x04\x46\x55\x63\x80\x1c\xb3\xe2\x3b\x2b\x33\xc6\x73\xb8\x0d\xd1\x18\x8e\x78\x94\x48\x5c\xed\x06\x14\xf9\xac\xe6\x99\x94\x63\x49\x74\x29\xe3\x28\x35\xa9\x4c\xf4\x59\xc9\xaa\xf5\xbe\x9b\x16\xb4\xc8\x5f\x9e\x9f\xfb\x5b\xb8\x4c\xbc\xc4\x24\xd7\xeb\x72\xf5\xef\x33\xcb\xa7\x02\x65\x32\x09\xa4\xea\x8a\x38\xef\x35\xcb\x47\xbf\x9b\x06\x0a\x0b\xc5\xd7\xcb\xd9\xcb\xd7\x91\x47\x99\x26\x22\xb6\xd4\x91\xa7\xf3\xf8\x4c\x97\x8c\xca\xc0\xc4\x91\x04\x64\x1f\xb8\xd7\xf6\x03\x2e\x83\x4c\xde\x97\xd1\x21\x0c\x49\x05\x56\x25\xfb\x03\xaa\x9a\xb9\x37\x66\x02\x1c\x4e\xfe\x4f\xa8\xfa\xc5\x35\x92\x49\x82\x80\x85\xef\x0f\xcf\xf7\x0e\xa4\x25\xb9\x17\x60\x1e\xf0\x71\xfd\xb4\xdb\xac\xb7\xab\xdd\x7a\xd9\x36\x85\x54\xa9\xae\x02\x6a\x61\xc0\x1d\xae\x55\x86\x04\xa1\xaa\x08\x45\x1c\x89\x4d\x49\x29\x63\x23\xca\x73\xcc\x3a\x45\x2c\x29\x25\x67\xa2\x95\x09\xd9\x40\x8e\xcc\x85\xb6\x0d\xfc\x08\xa3\x04\x1c\xea\xc6\x6a\x6d\xff\x1c\x51\x8c\xa9\xed\xb2\xca\xb8\xaa\x1d\x7e\xfa\xc6\x2e\x03\x32\xf0\x23\x7b\x72\x34\x87\xec\x5d\x9f\xc7\x7c\xf8\x94\x8a\x24\x58\x45\xe8\xdc\x57\xe4\x2d\x98\x4f\x45\xf4\x81\x84\x1c\xa3\xa3\xe8\x5c\x21\x65\x2f\x22\x4c\x5d\x6b\x1c\xa3\x58\xff\xaa\x13\x46\x90\x40\xc0\xd0\x23\xbb\xbb\x33\xa7\x9f\x29\xc1\x53\xa6\xb8\x3a\xd7\xfa\xfd\x7c\x9a\xe5\xf9\x26\xbb\xfe\xc9\x20\xf2\x91\x4c\xb3\x67\x49\xfd\xa7\x1d\x18\x08\x7d\x13\x70\xba\x87\x62\x71\xc8\x4e\x15\x12\x25\x5e\x33\x7a\x4a\x08\x99\xa1\xe8\xfa\xf3\xcf\x3f\xfa\x6b\x03\x42\x20\x58\x90\x82\x4a\x48\x74\x87\xd1\x19\x3c\x89\x76\x0c\x49\x06\x5e\x6d\x8d\x4c\x67\xea\x40\x44\x00\x2d\xc4\xa3\x96\x99\xba\xf4\x7d\x21\x88\x82\x50\xb5\x01\xc1\x97\x03\xab\xc0\x6b\x9b\xc0\x88\x3e\x03\xfa\x38\x63\x34\x03\xc4\x34\x42\x88\x4c\x63\xf1\x7d\x34\x66\xc5\xac\xe4\x99\xa5\xcb\x9f\x22\x29\x83\x98\x99\x38\x6a\x6d\x98\x1c\x6d\x75\x43\x57\xaa\xd5\xde\x58\x4a\xa4\x6f\xc1\x3a\xa3\x75\x5b\x04\x3a\x3d\x6d\x80\xb1\x24\xa4\x4e\xee\xb8\xb9\x71\xa7\xda\x24\x81\x27\x12\x7a\x52\x6e\x93\xc0\x3b\xd7\x95\xf9\x88\x46\x38\xb1\x4b\x5b\x56\x31\x7c\x7e\xae\x22\x24\x8a\xcd\xaa\xbb\x73\xb1\xef\xa3\x5a\x6d\x07\x41\x62\x47\xa2\x89\xc6\xc9\x9b\x43\x6c\x41\xf9\x31\xde\x9c\x40\xf8\x0c\x13\x15\x66\x34\x74\xf1\x9f\x6c\x5d\xdc\x77\x94\x91\x20\x98\x11\xbc\x3a\xb1\x0b\x40\x8f\xa5\x5d\x02\xf8\x2a\xe0\x0e\x6c\x2e\x01\xe7\xf3\xf0\xde\x4a\xf8\x66\x04\xcf\x7c\x88\x7e\x70\xed\xd2\x10\xd5\xe4\x56\xf2\x7e\xe3\xd4\x0e\xa5\x22\x51\x6a\x90\xb8\x35\x2b\x6b\x23\x81\x36\xb1\xf7\x2a\x12\xc7\xa9\x91\x1d\x2c\x58\xfb\xe5\x14\x11\x46\xe5\x92\x49\xd9\x2f\x70\x73\xcd\xd4\xf7\x50\xd5\xf4\x98\x15\xd0\x8f\x38\x0d\x36\x5b\xe5\x05\xed\x37\x5b\xc2\xf1\x5c\x22\xb6\x14\x5a\x31\xa6\x3e\xb4\x45\x79\xb1\x87\x08\x9d\x81\x66\xff\x95\x09\xdd\xae\x29\xe5\x09\x60\xd2\x39\xac\xa3\x9f\x95\xc4\x1b\x50\xce\xe0\x81\xb8\xfd\x89\xc6\x8e\xeb\x03\x0a\xf7\xce\x57\xc8\xc4\x81\x2d\x9e\xd7\x4f\x6d\x8b\x4a\xe3\x91\x6e\x17\x9e\xf9\xf7\x59\x99\x5b\xc4\xdf\x80\xad\x52\x05\xc4\x2c\x06\xcb\x35\x6b\x23\x65\x03\xda\x07\x15\x44\xc6\x9e\x71\xd9\x7d\x93\x43\x5b\xb2\xe2\x7d\x10\x8d\x54\x01\xa3\x48\x9e\x88\xdf\xec\x15\x2b\xc8\xda\x5b\x28\x46\x2c\xf4\xd1\xc1\x97\x6e\x97\x39\x0e\x26\x91\x0a\x03\x30\x94\xe0\x63\x0d\xf9\xfe\x80\x86\xa9\x19\x91\x7f\x9f\xfb\xa5\xbc\x53\x33\x26\x6c\x8c\xd5\x66\x3b\x3b\x1f\xa1\xcc\xce\xc7\xfe\x9e\xa6\x42\x08\xb1\xfe\xf0\xa3\x17\xf5\x9b\x7c\xbc\xe4\x9a\x4a\x48\x45\x24\x30\x4a\x8b\xdf\x4a\x80\xe5\x7c\x70\xe3\x28\x09\x30\xc7\xfa\xf6\x30\x54\x7f\x18\xbe\x6a\x04\x01\x16\xcd\x9f\x8b\x17\x76\xae\x06\x98\x39\x15\x5b\x65\x09\x61\x19\xd3\x8d\xdb\xd7\x0b\xa7\xab\x38\x50\x22\x1d\x24\x24\x56\x0f\xdb\xc5\x23\xc8\xec\x7c\x1c\x7b\x87\x2a\x61\x06\x72\x09\xc7\xac\x46\x24\xea\xea\x83\xe5\x67\x56\xdf\xf8\x2c\x57\xa8\x98\xd1\x93\x27\x2a\x46\x1f\xfc\xe1\xf9\x7e\xe7\x26\x48\x63\x17\x76\x46\xaf\x4a\xa3\x18\xf9\x02\xeb\x92\xc9\x2e\x47\x42\xfd\x6e\x0b\xa4\xb6\xbc\x39\xf9\x6f\xaf\x43\xd4\x0c\xfe\xe9\x6e\xc5\x62\x0c\x23\x28\x5d\x7e\xb2\x52\x36\x27\x74\xe5\x6a\xab\x5d\x17\x21\x3b\xe6\xe2\x1f\x90\x75\x96\x82\x4a\x95\xc2\xad\xa5\x19\xbf\xf3\xe9\x79\x28\xa1\x27\x15\xa3\x0a\xe7\xdb\x4b\x86\xd4\x0a\x83\xc9\xc3\x12\xcf\xd2\x5b\x35\x9f\x00\x0d\xdb\xcd\x35\x1b\x9d\x62\x49\x10\x3a\x65\x21\xab\xf4\xb7\x2b\x74\xbd\x36\x08\x0b\xd7\x89\x01\x3a\xb0\x36\xd0\x03\xf2\xb9\xfd\xd6\xc2\x8f\x98\x4d\x4c\xcc\xaa\x0a\x8e\x3c\x1f\x45\x49\x94\x00\x43\x7a\x80\x98\xa7\xf9\xf9\x32\x1d\xa3\x53\x32\xf4\x11\x0a\x7d\x2a\x61\xbb\x1f\x78\x06\x4a\xc6\x26\x5d\xdb\x18\xe8\x65\x26\xf7\xf0\xa4\x25\x4c\x54\xfb\x2a\x69\xb1\x08\x58\x9e\x2e\x01\x8e\x36\x05\x83\xb0\xa3\xe9\x43\x45\x49\x41\x31\x56\x64\x99\x26\xe1\xf3\xbe\x87\xc0\xb9\xad\x07\x2a\x15\x50\x9a\xda\xe0\xeb\x49\x17\x18\x82\xee\xbb\x1d\x0a\x22\x8e\x2f\x64\x8e\xe3\x99\x6c\x67\x17\x88\x50\x39\x48\x2f\x8e\x85\x75\xa3\x94\xf2\x82\xd0\x39\x8d\xe7\x0f\x28\xeb\x73\x09\x3b\x50\x0a\xfa\xec\x3c\x4a\x85\x46\x8b\xf5\x85\x15\xec\xc8\x3e\xaa\xed\xb9\xc8\xaa\x8c\xb5\xcd\x10\x38\xdd\x31\xeb\x17\xbf\x9e\x7b\x46\x6b\x47\x2a\xfe\xab\xaa\x20\x52\x29\x15\x60\x01\xf7\x71\x87\xe0\xc0\xaf\xf6\x40\x20\x24\xa0\xcc\x84\x4e\xf6\x05\xeb\x73\xf5\x03\x21\x21\x43\xc7\x7c\xf5\xba\x88\xe3\x78\x09\x47\xfd\x85\xea\xea\x70\x0f\xb3\x77\xa0\x9e\x1f\xf5\x99\x73\xb6\xfa\x74\xa7\x07\x3a\x05\xa3\xa7\xa1\x81\x72\xa4\x54\x48\xbb\xce\x8e\x30\xbf\x4c\xc8\x3f\x00\xa1\x2c\x51\xc6\x60\xc7\x2c\xed\xf7\x56\xa7\xbf\x69\x32\x7c\x3d\xcd\x90\x96\xac\xb1\x7b\x1d\xbd\xa0\xeb\x20\x68\x60\x04\x26\x0a\xd9\xaa\xe6\x02\xa1\x52\x92\xe6\x4b\x15\xba\x86\x25\xe0\x80\xd4\x20\x5f\xe1\xa4\xcb\x76\x4c\x28\x48\x0c\x5f\x1a\x6f\xfe\x47\x6b\x3f\xdf\x59\x3d\x83\x1b\xef\xe5\x05\x02\xd3\x7e\x59\xb5\xd5\xa7\x4c\xd8\x68\x7a\xe8\x5a\x43\x22\x1c\xd0\x1a\x41\x65\xe7\x9b\xe2\xd6\x4d\x67\x53\xc3\x54\xc0\xe7\x7d\xa9\xcf\x27\xf7\x64\x5e\x94\xe2\xdf\xbf\x67\x65\x7d\x86\x17\xfd\x0e\x65\x57\x1f\x02\xc4\x03\x08\x0d\xd8\x56\xbc\x8f\x4e\x9f\xc9\xdd\xd8\x5e\xe6\x87\x09\xc6\x33\x57\x4f\x4b\x04\xb7\xee\x36\x33\x17\x3e\x03\x82\x1c\x4b\x6e\xa0\x33\x28\x64\x75\xd7\xec\x6c\x65\x35\xf9\xc5\x7c\x65\xb6\xd6\x7b\x5d\xec\x5f\x5c\xee\xc9\xb6\x05\x84\xbb\xef\xbe\xd3\xa5\x84\xf2\x46\x45\xdd\x8d\x49\x1c\x50\x8e\x6b\xfb\xc7\xeb\xc3\x28\x07\x09\x24\xf0\x7d\x5c\x7f\x52\xe7\xaf\xac\x9b\x24\x81\x0c\x42\xd9\xd9\xcd\x57\xa4\xbb\x40\xc2\x28\x70\x94\x15\x6d\x75\xc0\x88\xcf\x7d\x78\x41\x14\xa4\x41\x07\xca\xfe\xf6\x54\x5f\xbb\x08\x40\xa2\x30\x76\x52\x33\x12\x5e\x4a\x18\x72\x79\xfe\x05\x3e\xdd\xdd\x43\x50\x1e\xb7\x32\xf6\x37\x28\x0f\x80\xc4\x61\x68\xe4\xed\xf4\xa9\x1f\xb8\x76\xad\x09\xc1\x71\x39\x61\x06\x7d\x57\xf7\x4a\x8f\x81\x24\x3c\x41\xa6\xc4\xf9\xdb\x1f\x8d\x0d\xf8\xf8\xfc\xb4\xfa\x73\x18\x6c\x03\x92\xfa\x60\x9f\x02\x35\xa2\x6c\x98\xcd\xf1\xb8\xba\x04\x09\x90\x34\x35\x64\x79\x7b\xa8\x1f\x2f\xab\xe7\xcd\xef\x8e\x5f\x00\x08\x8b\x38\x3a\x80\x95\x2b\x76\xfc\x6d\x82\x52\x07\x08\xe3\x2c\xe9\x54\xb6\x06\x0c\xf9\x40\x78\x00\xb2\xa3\xef\x6c\xa5\x60\x46\x66\x09\x10\x1e\x73\xdc\x68\xeb\x4f\xfd\x03\xe0\xbd\x7d\x55\xce\x01\x23\x1f\x96\x48\xe8\x15\x44\x76\xea\x0b\x99\x77\x07\x16\x10\x0e\x01\x66\x50\x4c\x98\xe7\xa5\x84\xf5\xf6\x19\x61\x41\x0b\x76\xea\x09\x6c\x03\x91\x9c\xfa\xa2\x2d\xad\xca\x3a\xb5\x56\x20\x10\xfa\xb8\xab\x16\x06\xf3\x61\xcd\xe2\x0e\xb0\x01\x04\x92\x18\x83\x3a\x8b\x03\x88\xf7\x0e\xa2\xd8\x34\x28\x4c\xa3\xb6\x5c\x54\x0f\x68\x67\xb4\xcd\x4c\x62\xae\x2a\xab\x3a\x18\xb9\xf9\x2a\xc8\x9f\xd8\xde\x5f\x45\xd4\x50\x5a\x9d\xb9\x81\xac\xf5\x67\x0d\x25\x54\xf9\xd6\xc3\xd9\xf4\x27\xd5\xd7\x4b\x90\x92\xc0\x43\xfb\xb6\x75\x2e\xae\x0b\x0f\x81\xd2\xb8\xcd\xf1\xdf\x6d\xb6\x83\x92\x33\xa0\x54\xa8\xd8\x24\x35\xbf\x43\xa9\xb2\xf6\x79\x29\x05\x96\xf6\xb5\x58\x6e\x93\x82\x01\xf5\x42\x45\xc8\x58\x0c\xef\x2a\xd4\xdd\xff\x6f\x60\xaf\xf4\x83\x50\xb8\x04\x52\x0d\xe5\xc2\x78\x2d\xee\x19\xfc\x48\x46\x46\x8e\xbd\xac\x0c\x7b\x46\x47\xb1\x04\xd4\x07\x65\x98\x74\x59\x2d\x0e\x77\x03\x55\x77\xab\x0b\x62\x3b\x86\x9e\x09\x8e\xb5\x62\x0a\xc6\xab\xb8\x6d\xb7\x00\x0d\x03\x53\xa2\x81\x55\x12\x4a\xb9\x9f\x0c\x81\x27\x76\x28\x17\x50\x5a\x75\x92\x76\x2c\x23\x1a\x19\x4e\x09\x03\xe8\x9a\xf0\xbd\x80\x46\x29\x43\xf3\x05\xf1\xa2\x13\xfc\x85\x40\x13\xe2\xfb\xfd\xe3\x7b\xce\x2a\xc0\x40\xd4\x70\x4f\xa3\x09\x4d\xb1\x5e\x6c\x57\x41\xfd\xa4\x0b\xe4\xff\x93\x28\xb5\x30\xee\xa7\x30\xb2\xdb\xbc\xca\xf6\x50\xea\xf3\xfe\xb0\x1d\x21\x91\x80\x26\x89\xa9\x28\x6c\xb6\x95\xe7\x02\x6c\x8c\xba\x31\x63\x4b\xf7\xe4\x89\x32\xe7\x4e\x56\x55\xe7\x2b\xb6\x5b\xdb\x27\x25\x49\xcb\xbc\xb6\x19\x18\xd1\x40\x19\xe1\xc4\x24\x42\xcf\x85\x38\xf4\xb9\x1f\x81\x32\x1a\x62\xbc\xcc\x26\x06\x9b\x75\x69\x8b\x7c\xf5\x95\x40\xf4\xe8\x4b\xb1\xd0\x50\x65\x59\xd5\xfd\x55\x7d\xe8\x47\x9b\x80\xb2\x94\xe1\xec\x17\xac\xaa\xb7\xfa\xad\xcb\x28\xbb\x76\xa6\x78\x6a\x15\xe5\x4b\x90\x99\xa8\xef\x74\x79\x85\x2b\xed\xd9\x57\x94\x49\xce\x06\x15\xdd\x9b\x9a\xbd\xc3\x3d\xcb\x46\xb2\x52\x40\x79\xc0\xc1\xd2\x53\x99\x12\x67\x2c\x5f\xee\x9d\x07\x94\x47\x01\x09\x5b\xc5\xbf\xce\xfb\x03\xca\x81\x42\x30\x99\x55\x71\x3d\x44\x60\x04\x6e\xaa\x5a\x9f\x7a\x8c\x45\x40\x45\x1a\xe0\x0c\xda\x99\xa9\x5d\xdd\x0a\x75\x03\x15\x4c\xfa\xa6\xde\xf6\x34\x4a\xa2\x4d\xc5\xf5\x81\x4a\x6a\xea\x9a\x7e\x1c\x2e\x3f\x0e\x97\x6b\x0c\x16\x50\xe9\x93\xc0\xb7\x49\xd2\xe6\x75\x9a\xe7\x6e\xbf\x85\x0c\x38\x46\x98\xee\xd9\x91\xe7\x66\x92\xb5\x4d\x32\xb6\x12\xbf\x85\xc4\x86\xa1\xe8\x1a\x50\xf0\x8c\x88\xeb\xe3\xec\x7e\xbd\x68\x8e\x47\xb3\x26\x6e\x87\x06\x80\x42\x1a\xa1\x69\x50\xc0\x67\xcb\x97\xd5\x1c\xdd\xb6\x9c\x7a\x8a\x37\x08\xa8\xa2\x81\xa9\x6a\x62\x19\x82\xa7\x77\x3f\x20\x43\x76\xf1\x76\x67\x54\xa9\x31\x04\x5a\x91\xe3\x47\xf6\x73\x0e\x43\x8a\xfe\xd1\x24\x55\x3c\xa2\xcc\x15\x1f\xbb\x6c\x54\x4f\x8a\x1f\x3c\x42\x0c\x8c\xf3\x5f\x3a\xc3\x70\x1d\x9a\xeb\x03\x94\x92\xeb\xe8\x79\xc2\xfa\x3f\x16\xda\xf5\xc8\x7e\x0e\xa6\xb4\x47\x7c\xea\xd2\xe1\x96\x28\xbc\xcf\x7e\xe0\x3a\xc5\x81\xb0\x14\x24\x6d\xa2\xf7\x06\xd5\xdb\xf0\x65\x3c\xc2\x15\x0d\xff\x3f\x67\xef\xd6\xdd\x28\x8e\xb5\x8f\x7f\x97\xdf\x55\x5d\xcc\x85\x90\x00\xc1\xff\xce\x71\x9c\x2a\x77\xe7\x34\xb1\xab\xaa\x7b\x66\xcd\xf2\xd2\x61\xcb\x61\x82\xc1\x03\x38\x89\xe7\xd3\xff\x17\x5b\x12\x27\x93\x54\xcf\x7b\xf1\x76\xbd\x13\x09\x0c\x42\x87\x7d\x78\xf6\xf3\xf8\x2d\xac\xdd\x77\x57\x7b\x5f\x82\x02\x94\x86\xb6\xe0\xe5\x35\xd3\x50\xf6\x7f\x55\xb6\x72\x6e\xf3\x5c\xbe\x39\x15\xed\x79\x73\x8e\x52\x60\x78\x10\xee\xfa\x88\xd7\x46\x3d\x5b\x9d\xc1\x01\xb1\x01\xd0\x30\x35\x96\x96\x0b\xea\xa6\x2a\xcf\x3f\x9f\xa1\xc0\xf6\x9e\xf8\x13\x68\x08\x36\xd4\x8d\xe5\xe4\xd5\xdf\xdb\x5d\x1f\x9d\x33\xd7\x1c\x45\x8c\xba\xdd\x1c\xbf\xc5\xba\xbb\x79\xc4\xad\xd4\xca\x5b\x96\x6b\x25\x2a\x5d\xa3\xa4\xef\xf0\x89\x03\xff\xc0\x91\x89\x11\xdf\x70\x5d\xbe\x15\x16\x7c\xe0\xf2\x67\x63\x64\xcb\xe7\x07\x39\x8d\x69\x10\x84\x5e\x04\xbd\x9d\x76\x36\xcc\x37\xc8\x45\x03\x8d\x19\x67\xd6\x9d\x79\x38\x82\x8d\x87\xa3\xa0\x49\x37\x33\x69\x1c\x59\x9d\x6c\x1b\xa2\x40\x58\x11\xe8\xcf\x88\xc9\x81\x72\x1e\x25\x3d\xfd\xc8\xb6\xdc\x40\x3f\xc4\x1c\x18\xa2\x02\x2a\xc8\x4f\x3b\x17\x8e\x6f\xf7\xae\xd1\x93\x27\x32\xb6\x0b\x57\x98\xcb\x8a\xcf\x59\xd4\x81\xbf\x10\x52\x24\xc6\xc0\x9d\x02\xa1\x14\x83\x68\x3d\x50\x41\x14\x1e\x09\xbf\x9d\xea\x26\x2b\xea\xe1\xce\x47\x65\x08\x41\x3c\x22\xf8\x5c\x17\x4f\x70\xc8\xde\x27\x2f\x27\x23\x8d\x9f\x71\x2a\xab\xbe\xd0\xfa\x17\xa2\xea\x40\xa5\xa6\x52\x7b\xfe\x30\xef\xca\xfe\x95\x08\x27\x50\x15\x44\xc4\x3d\x1e\x4e\x49\xeb\x59\x3e\x18\x04\x67\x7f\x70\x49\x4a\xd1\x74\x7d\xc8\xcf\x87\xe3\xa9\xbe\x15\xb2\x5e\x96\xd5\x74\xcd\x2a\xa9\x30\x3a\xee\x15\x23\xfd\x78\x68\x11\x79\x76\xe5\xdb\xdb\x1f\x96\xb4\x92\x92\xae\xd5\x58\x19\xde\x1a\x9a\xf5\xa1\x75\xab\xa1\xba\x12\xc5\x8b\x6f\x06\x12\x61\x0d\x8a\x6a\x3d\x7a\x6b\xc5\xcf\x3a\x40\x14\x52\x86\xa3\x69\x00\x7a\x30\x2a\x50\x13\x58\x2c\x5a\x6f\x83\x22\x78\xcc\x09\x88\x8d\x5e\x93\x11\x6e\xf9\xfc\xd4\xee\x2e\x2b\xfa\x14\xcc\xba\xc0\xb4\xf7\x17\xdf\x4b\x33\xf4\x12\x17\x4f\xbf\xef\xb6\x4f\x0f\x5f\x6f\x1f\xf6\xbb\x60\x47\xfc\x0b\xb1\x80\x46\x96\x49\xe3\xb9\x7c\xdb\x76\x45\x2e\x79\x59\x67\xc5\x7e\x70\x84\xb2\x20\x35\x58\x37\xef\x0a\x37\x5d\xa0\x7a\x96\xad\x0d\x58\xa0\xc1\xd9\x01\x55\x31\x75\x67\x19\x8d\x29\x0d\x66\xa9\xd4\x83\xc9\x28\x31\xca\x19\xb5\xd6\x41\xd1\x6c\x3c\xcb\x77\xb7\x25\x31\x2a\x14\xd6\x1b\x6d\x57\x8b\xbb\x1d\x96\x7e\x79\x2e\xe2\xdd\xe3\xe2\x69\x4b\xbb\x7e\x8a\x61\x00\x3c\x17\xae\x0a\x7a\x67\x02\x94\xfb\x75\x4f\xed\xfb\x45\x2c\xc0\xfd\xf2\x2a\xfb\xcf\x69\x56\xa1\x62\x78\xb8\xb1\x88\xdb\x1c\x5f\x6d\x49\xc2\x27\x6a\x9b\xbe\x93\xa6\x78\x58\x0d\x68\x56\xae\x32\xed\xa3\x2e\xc5\xaf\x6a\xc9\xdd\x5d\xe2\x98\x63\x3c\x72\xf5\xf7\xef\xeb\xc7\xbb\xd5\xfd\x76\xf7\xb4\xfa\xb9\x78\xba\xde\xfd\x5c\xdc\xde\xae\xbc\x3f\xcb\x62\x15\x0f\xa4\x8e\xd0\x3e\x42\x48\xfb\xbc\x35\xe2\x2f\x32\x31\x96\x7e\xd8\xda\xe8\x70\x57\xf5\x46\x38\x4b\xa8\xc4\x88\x4c\x6b\x8f\x2d\x07\x8a\x7f\xc3\x04\x0f\xb0\x94\xf2\xd4\xc3\x89\xba\xa2\x72\x60\x92\x06\x5e\x49\xf5\xa9\x2c\x0f\x1b\x98\x11\xde\x01\x26\x79\xe8\x65\x7b\xef\xda\x1f\x39\x4e\xdb\xd3\x10\x45\x52\x77\xae\xc0\x7b\x48\x30\x06\x4c\x0a\x13\xfa\x5c\x51\xbb\x88\x47\xdb\x1e\x53\x71\xca\x3b\xbf\x7d\x58\x49\xd4\x3d\xa3\xa6\x1c\xc1\x26\x96\x03\xf8\xa6\xac\x76\xcb\xac\xc2\x95\xd7\xdb\x95\x4c\x47\x24\xe4\xbd\x54\xc5\xe6\x7c\x90\xe5\x08\x6b\x0e\x4c\xf3\x20\x26\x7d\xe5\xd0\xd5\xb9\x81\x39\x1b\x91\xe9\x24\x40\xd1\x55\x61\xcf\x9a\xdf\x4e\x55\x56\x6b\x9b\x07\x1e\xd3\x28\x00\x33\xa1\x88\x7d\xe9\xfe\x8e\xed\x0e\xd0\x3c\x7b\x81\x26\x60\x26\x09\x8d\xd5\x9b\x28\x4b\x33\x4e\x0f\x02\x33\x2a\xc1\xe9\x8e\xde\xb7\x27\x4f\x18\x3d\x6f\x48\xc2\x14\x0d\xc0\xcf\xbc\xb8\x7f\xb2\x31\x79\x09\x84\xc4\x38\xba\x95\x61\x78\x19\xc2\x20\x4c\x10\x3a\x92\xe1\x86\x88\x06\xe7\xe4\x64\x0c\x5b\x3b\x2b\xb5\x2a\xbf\xfe\x2a\xaa\x6c\x11\xa1\xdd\x4f\x90\x75\x09\x4b\xb2\x7c\x3b\x8b\x65\xe4\xd1\xf4\xd9\x21\xeb\xe2\x98\xe0\x00\xb1\x43\x4a\x2e\x08\x43\x0d\xe8\x47\xe0\x18\x6e\xcb\xef\xeb\x62\xa4\x07\xe8\x47\x35\x0c\x21\x09\x89\xaf\xb1\x5c\x7a\xec\x51\x6b\xe7\x44\xdd\x9e\x18\x46\x2c\xc1\x3a\x30\xcb\x1e\xb2\x6c\xbf\x69\x71\x1e\xe9\x9b\x43\x18\xf1\x84\xb9\x98\x7a\x47\xd5\x3b\x5a\x1e\x71\x38\x97\x14\x9b\x00\xe3\xdb\xfb\x68\x74\x8e\x7d\xb1\x4f\x4d\xfb\xc7\x48\x22\x1c\xd7\x5a\x3d\x83\x3e\xe5\x7d\x48\xb1\x6b\x17\x48\x15\xe4\x09\xa4\x4f\x97\xac\x92\x10\xc6\xb1\x96\x43\x0f\xf8\x11\x0a\x91\x37\xe7\xd1\x32\x0a\x63\xa0\xce\x63\x6d\x1e\xcb\xaa\x31\x65\x9e\x95\xd3\xba\x0e\xaf\x08\xea\xc3\x51\x21\x4f\x05\x56\xd3\x49\xa1\xbb\x45\xe1\x9b\x04\xb5\x99\x0a\x9c\x7a\xd6\xa4\x1f\xaf\xeb\x30\xe1\x5a\x68\x5f\xf1\xf8\xab\x08\xcd\xbc\x6d\x10\xa6\x41\x1c\x39\x3e\xb1\x45\xa1\x30\xbe\xe9\x9f\x20\x15\x1c\x0b\x83\x57\x3f\x3c\x13\x33\x84\x82\x5b\x45\x9f\x76\xb3\xe8\xc2\x7d\x37\x55\x79\x58\xbd\xcf\x43\xd8\xfc\x75\x89\x42\x1a\x6b\xb4\xd1\x6f\xcb\x72\x5e\xb7\x0c\x42\x21\x34\xa2\x6c\xf0\x28\xf5\x91\x1e\xd4\x13\xef\x06\x5a\x48\x8e\x33\xeb\xf1\xd4\xec\xae\x57\xd7\xeb\xdd\x3e\x33\x93\x28\x73\x28\x54\x8c\x4e\xf6\x66\xbb\xb8\xbf\x6e\x37\xf9\xab\xef\x7f\xfa\x24\x36\x84\x32\x90\x36\x0a\xde\x9e\x9a\x9e\xa9\xd8\xb7\x45\x0a\x77\x17\x57\x2f\x78\xed\x48\x76\xeb\x0f\x9e\x57\xf2\xd8\x0c\x34\xcf\x1e\xb3\x4a\x14\xcf\xe2\x33\x5b\x3b\x99\xf9\x5f\xce\x97\x0a\x15\xb5\x1c\xb1\xbe\x7a\x61\xbd\x7c\x50\xd3\xdd\x3c\x54\x11\x84\x2e\xb1\xb6\x69\x44\x75\xef\x9c\xc9\x0f\x1e\x50\x29\x8e\xd4\x0c\x68\x4d\xad\x44\x95\x9f\x3b\x4e\x2e\xd7\x43\x13\x63\xec\x19\x53\x10\x2c\xa1\xca\x8a\xfd\xd0\xce\x0f\x75\x20\x4c\xec\x69\xd3\x3f\x92\xc0\xf1\x7d\x43\x8a\xc3\x77\x6c\xde\xb7\x22\xeb\x26\xb3\x8e\x88\xf3\x5f\xec\x0a\x7a\x68\x37\xb8\x39\x34\xd3\x07\xb7\x05\x6e\xb4\x0d\x6a\xde\xd9\x08\xb1\xff\xbb\x14\xbe\x60\xed\x21\xd7\xab\x70\x3e\x1e\x18\x9a\xc0\x92\xec\x1f\x91\x30\x0b\x3f\xe8\x0d\xc0\x30\x56\x1b\x9a\x20\xe4\xf6\x25\x45\xa5\x9e\x91\x70\xd8\xb7\x48\x8d\x41\x93\x5b\x51\x37\x28\x84\x21\xfa\x28\x6a\x44\x02\xc5\x23\xcb\x98\xee\xe0\x0f\xce\xdb\x1a\xa0\x38\x26\xdb\x96\xbf\x52\xc7\x31\xf1\xd0\xe8\x76\x8f\xec\x43\xa5\x1d\x16\x72\x2e\x19\x13\x05\x84\x41\x62\x43\xf6\xad\xb1\x74\x53\x9e\xaa\xe6\x79\xf8\xc1\xa2\x20\xb6\x04\x92\xed\x75\x4b\xc8\x3e\x04\x5d\xfb\xee\x2a\xb4\x2e\x57\xcf\xfe\x04\x51\xa0\x25\x72\xb8\xfc\x80\x5a\x60\x30\x87\x3a\x36\x44\xd7\x4e\x09\x8d\xbd\x0a\xa9\x55\xd7\xeb\x5a\x1c\x47\xa4\x67\xfe\x7f\xfa\xc3\xd5\xc6\x0c\x86\x3b\x62\x24\x22\x6e\xb7\x74\x75\xbf\x73\xfc\x09\x10\x31\xcd\xb1\x9e\x67\xbd\x7c\xb0\x25\xef\xdc\xdf\x21\x24\xa9\x91\x8e\x80\xd6\x67\x66\xea\xf1\x01\x13\x45\x2a\x49\x1c\x5a\x05\xfd\xec\xe1\xf9\x1d\x45\x26\xb0\x98\xce\xaa\xf9\x59\x56\x2f\x56\xea\x60\x31\x38\x07\x66\xb1\x35\x10\xc5\x10\xc7\x8e\xf7\xd9\x62\x24\xa6\x51\x8a\x41\xdf\x34\xa4\x58\x16\x62\xf3\xf9\x8f\x56\x30\x6d\xa8\x1e\xed\x4f\x82\x28\x95\x3a\xf2\x34\xb2\x5d\xa8\x69\x76\x2f\x8d\x44\x10\xe2\xcc\xb9\x87\xb7\xeb\x6c\x9f\x35\x22\xb7\xa5\x2b\xb3\x73\x3f\x12\x01\x17\x7d\x74\x68\xf9\x2c\xaa\xac\x99\x52\x55\xfa\xae\xa1\xc0\xf2\xce\x83\x78\xbf\x6a\x0d\xd9\x05\x56\xd9\x0d\xd2\x2c\x91\x48\x25\x82\xb8\x4b\x74\xf8\xfb\x72\xb0\x4b\xb2\x97\x09\x7a\xa5\xbd\x54\x07\x9d\xb2\xbc\x85\x98\xe8\x41\x42\xaa\xee\x7e\x42\x8b\x8e\xdd\x6d\x5d\xb4\x93\xc8\x96\x80\x0e\x4d\x95\x48\xd2\x28\x74\x8b\x67\x71\x3c\x7e\x99\x86\xf4\xc7\xaf\x25\x63\x6d\x05\xf8\x4f\xf2\x90\x35\x9b\x06\xc4\xcb\x2c\x24\x0b\x22\x15\x24\xe8\xc7\x5b\xb6\xa1\xdf\xb3\xa6\x39\x5f\x2a\x3b\x4d\x78\x87\x20\x52\x34\x94\x2e\x6d\x89\x29\x97\x55\x0e\xc3\x31\x53\x8c\x63\x1d\x93\x1a\xb2\xef\x5d\x9d\xd7\x45\x03\x63\x58\x43\xdb\xd5\x04\x0e\xf4\xfc\x23\x3b\x5e\x55\xe5\x0b\x54\x9d\xc4\x19\x44\x8a\x47\x42\xf8\x30\x83\xde\xc3\xd5\xf9\x77\x4c\x90\x4f\x64\x5f\x00\xa7\xbd\xb6\xc8\xd8\xe6\x39\x26\x76\x9a\xfa\xbb\x68\xaa\xac\x4c\xa7\x17\x49\xc2\x57\xfc\x0c\x19\x0f\x91\x16\x1c\xe5\x0f\x77\x7b\x28\xb0\x3a\x07\xf1\x16\x1f\x0c\x7b\x8f\xb7\x21\x7e\x76\x6b\xa9\x43\x1b\x85\x83\xb7\xf6\x77\x77\x76\x97\x1c\x04\xbf\x22\x88\x6d\x52\xc4\x66\xf0\xec\x42\x16\x17\x72\x80\x10\x81\xa2\x60\x91\xf4\x8d\x7a\xee\x0a\x08\x20\x32\x11\xa1\xe0\x45\xfc\x37\xed\xa7\xc6\x95\x36\xbe\x3a\x26\x81\xcd\xf3\xad\x17\xd7\x58\x4a\xe6\xa7\x5d\x4c\x28\x45\x62\xba\xba\x11\xe8\x81\x61\xe9\x5b\x6f\xcf\xc6\x01\x91\xa1\x4f\x52\x8e\x02\x4e\x71\x60\x94\x95\xf1\xa8\xd1\x6c\x2f\xc4\xa9\xa9\xc7\x46\x45\x4c\x83\x48\xbb\x7d\x08\x7d\xe7\x6f\x90\xed\x9f\x9b\x01\xaf\x38\xc4\x94\xaa\x50\xfa\x8a\x97\x75\xf1\xfe\x73\x4a\x90\xef\xfb\x19\xcd\x1d\x6a\x70\xe9\x63\x73\x83\x7d\x3b\x66\x29\xa3\x69\x27\x3b\xf0\x79\xe4\x34\x66\x32\xc2\x35\xb9\xb8\xfe\xb1\xde\x3c\x3c\xfd\xb9\xbb\x7a\x68\x8d\x25\xac\xb2\xd8\xf8\x87\x0f\x89\xa5\xec\x3b\x62\x30\x71\x55\xe8\xae\x00\xaf\x3b\xdf\x4e\x63\x2d\xed\xb1\xd1\x7b\xc1\xd8\x32\x5a\x7b\xfe\x47\x58\x8a\x79\xb7\xf6\x38\x11\x39\x8c\x8f\x94\x38\x22\xd6\xbf\xee\x63\xb0\xdb\xcc\xb3\xd5\xb9\x2e\x71\x64\xc5\xaa\xee\xca\x72\x7f\x1a\x06\xe7\xe2\x58\xa7\x61\xe2\x99\xd9\x7d\xcc\x60\x3c\xa8\x3c\x0a\xa0\xb5\x6a\x57\x87\x2c\xdf\xa2\x32\x77\xd6\x5d\xce\x39\x41\x13\xe3\x1f\x47\xa8\x1e\xed\x91\xfb\xd7\xf0\x08\x31\x97\x21\x0a\x6f\xc2\x6b\x99\xbf\xc2\xe2\x3d\x9b\x2f\xe4\x84\x38\x51\xb6\x8c\x66\xa1\xf5\x53\xa9\x5e\x60\x64\x3d\x38\x1f\xa8\x43\x84\xfe\x8f\xff\x74\x97\xfb\xdf\x32\x32\x71\xcc\x7c\x3a\x6b\xb0\x8c\xf7\xb1\x2a\x5f\xb3\xe1\x5a\x99\x3c\x5e\x2a\x12\x2f\xaa\xf6\x0d\xb2\x6a\xb8\x11\xc7\xa9\x52\x58\xa9\xfb\xf5\x6e\xf3\xd7\xf4\x48\x21\x16\x41\x2a\x4c\xc7\xd2\xbb\x29\x73\x6d\x09\xa6\xba\x66\xc5\xfa\xad\xbd\x3d\x8c\xf5\x1c\x90\x24\x16\x34\x44\xe7\xf1\xdb\xc3\x66\xbb\x5b\x7a\xb6\x35\x88\x05\x27\x58\xb6\x64\xb1\x0c\x77\xd0\x08\xdd\xee\x32\xe3\x57\x92\x84\xa7\x03\x86\x6a\x4f\xcb\x34\x31\xdb\xe7\xb1\x4d\xee\x16\x8a\x48\x5f\x28\xe9\xa7\xd5\x55\x39\x91\xe8\x84\x58\x09\x81\x9b\xbf\x3c\x9d\xaf\xce\x57\xe5\xe7\xd4\xe8\x10\xeb\x44\x20\x86\xb1\xdd\x27\xad\x61\x77\x5b\x36\x0f\x66\x99\x8b\x53\x0d\xdd\x5e\xa5\x95\x40\x66\xfc\x9d\x70\xea\xd9\x9f\xa7\x24\x63\x08\x02\x6d\xc3\x20\xae\x94\x13\x3f\x55\xcf\xe8\x09\x31\x50\x6a\x02\x8f\x54\x18\xe6\xc1\x62\x13\x68\x74\x90\x8f\xe2\x2c\x64\x0e\x37\x59\x51\xc0\xf9\xc9\xd6\x87\xe8\xae\x53\x24\x91\xca\x6d\xa7\x10\xe1\x7b\xca\x1b\xab\xca\xbe\xae\x7f\x66\x1f\xcc\x2a\x4e\xa8\xc4\x1a\xa3\xac\xde\x9c\x64\xad\xaa\xec\x88\x09\x04\x8b\x9a\x9b\x23\x07\x00\x4e\x62\x92\x5a\xd5\x9d\xfd\xc0\xca\xfe\xac\x08\x6b\xb2\x23\x7d\xf0\x24\x09\xf0\x0e\xa6\xb1\x2c\x8b\x3a\xd3\x50\x81\xb6\x22\x0d\xc3\xc1\xe0\x81\x8e\x9c\x62\x53\xd6\x3c\x56\xa5\x02\xd0\xf3\x25\xec\xc0\x69\x60\xbd\x34\x03\x8d\x7a\xc6\x28\x76\x7d\x53\x56\x18\x8a\xbe\x3a\x5f\xd6\x60\x02\x0f\x93\x08\x3d\x89\xe5\xd7\xe5\xdd\x97\xee\x6f\x09\x73\xe0\xa3\x76\x5b\xca\x0e\x65\x71\x9e\x5c\x16\xa9\xd0\x58\xb2\xec\x37\x51\x69\x47\x90\xf4\x43\xb4\x83\xe3\x7b\x98\x14\xe5\x4c\x0e\xa5\x7a\xd9\x61\xa8\xc0\x32\x2b\x4c\xcb\x45\xe7\xdf\x23\x0e\x2c\x42\x6a\xb3\xfa\xa3\xaf\x1d\x01\x1e\xb3\xc8\xd6\x08\xa8\x72\x55\xe8\xef\x85\xa9\xca\xff\xc2\x28\x20\xc2\x63\x57\xb6\xb4\x5e\x3e\x8c\x20\x07\x9c\x47\x12\x99\x8f\x11\x70\x7d\x8d\x35\x23\x03\x27\x98\x73\x11\xa3\x21\xb0\x2f\x73\x3d\x06\x87\x70\xae\x28\x8e\x47\xa7\xcc\x31\xbb\x8a\x38\xd7\x11\x6e\xd9\x87\x9d\x7a\xce\xc0\x56\xde\xe2\x61\x71\xd5\x6d\x33\x3c\x49\x52\x2c\xad\x59\xac\xbf\x0d\x4f\x0b\x9e\x24\x12\x49\x16\xd6\xb7\x37\x6e\x57\x58\x8a\x42\x67\x3d\x09\x05\xf0\x34\x35\xa1\x18\x49\x89\xfe\x92\x87\x08\xb8\x08\x23\x29\xec\xa7\xfc\x07\x34\xcf\x3e\x0e\x05\x1f\xcd\x1f\x91\x30\x14\x21\x79\x3e\xeb\xaa\x1c\xb3\x62\x02\x17\x9a\x19\x17\xf0\xfd\x7e\xdc\x57\x42\x83\x90\x59\x9e\x35\xe7\xcb\x22\x63\xe0\x92\x30\xcc\x80\xba\xea\xe5\x11\x2e\xea\x83\x15\x21\x83\x18\xab\xa3\xaa\x53\xfd\xbc\xcd\x0e\xd0\x31\xd2\x59\x80\x48\x3d\xe2\x2c\x00\x2e\x59\x42\xad\xf6\x81\x0d\x56\xdd\x94\xd5\x6a\xfb\xed\xcb\xe4\x9e\xb1\x15\xe6\xb2\xcc\x1e\x59\x73\xd2\xdd\x80\xca\xd8\x2a\x1d\x17\x2e\x2f\xb5\x84\x3c\xc7\xa2\x53\x7d\x35\xcf\x9f\x0b\x5c\x11\x5b\x16\x26\x5a\xcf\x72\x91\xe7\xbd\x6b\xf5\xc1\x05\x9a\x10\x9c\x8d\xaf\xd6\x83\xcf\xc6\xb9\x4c\xae\x89\x25\x79\x15\x5a\xe3\x99\xf8\x8b\x01\x02\xca\x90\xfc\xa8\x6c\x77\x87\xd6\x5a\xa8\x1f\x47\x62\x31\x17\x5b\x17\x68\xe2\x05\x16\x6f\x45\xdd\x5c\x65\xfa\xa6\x6c\x67\xd6\xab\xa8\x87\x3a\x12\xc0\x4d\xa4\x71\x5b\x6c\xcd\x44\xeb\xf8\xf8\x14\x0c\x37\x22\x4a\x79\x97\x4d\xed\x79\x25\x83\x79\xe6\x5a\xe0\x46\x05\xb8\x5d\xed\x2a\x51\xe8\x19\x55\x0a\xdf\xcd\x08\x3c\x1e\xae\xb2\xe6\xcd\x57\xdf\x40\x12\x30\x5b\x27\x72\x10\x2f\x70\x95\xe9\x2f\x63\x1b\xaf\xeb\x64\xa9\xf4\xac\x12\xbc\x65\xcd\x77\xf4\x51\x03\x1b\x2a\x09\xa2\x04\xcd\xff\x4f\xaa\x27\xa6\x37\xe6\x1a\x39\x80\x34\x26\x80\x9d\x24\xde\xc8\x59\x4b\x82\x84\x79\x12\x9d\xc7\xaa\x34\x59\x3e\xa4\x5a\xf0\xf1\xf7\x7f\xf9\xce\x22\x42\xf3\xda\x08\xd5\x6c\x41\x1c\x1e\xcc\x97\xc9\x0f\x9a\x28\x70\x1c\xb8\x4e\x2f\x83\x7e\x3e\x07\x12\x4a\x2c\x46\x28\x43\x99\x94\xee\xbb\x8f\xfb\x18\xeb\xd4\x34\x20\x0e\x43\x91\x0f\x48\x18\x68\x4c\x9d\x7e\x13\xf5\xf3\x80\x40\x0d\x92\x90\x5a\xba\x2b\xdd\xe9\x3b\x41\x12\x11\x2d\xd2\x11\x1d\x1c\xaa\xb8\x7d\x90\xbc\x4d\x38\xb3\x20\x9e\xc5\x8f\xaf\x96\xce\x71\xb3\xa3\xe1\xb7\x2f\x5d\xab\xc1\x02\x30\x2f\x4d\x78\xb7\xf8\x63\xf7\xb4\x58\x6f\x56\x5d\x07\x63\x5d\x11\x8c\xd5\x6e\x1a\xd1\x78\x50\x7f\xdb\x64\xc1\xd1\x7b\x51\xe3\xf2\x41\xcb\x6d\xe7\x5b\x13\x1a\x06\x74\x50\xa2\x76\x9d\xbd\xd6\x8f\x55\xa9\x4f\xaa\x7f\xef\x84\x2a\xb4\x34\x30\x7b\xb3\x39\x82\xca\xa0\x9e\x04\xbd\x46\x0b\x37\x49\x63\x89\x7e\xdd\xf6\xd1\xc7\x6f\x93\x54\x50\xb4\x03\x0e\xe2\xfd\x1b\xf2\x56\x0f\x4d\xd2\x24\x15\x36\x71\xba\x87\x66\x55\xab\xaa\x7c\xbb\xbe\xb0\xff\x12\x11\x27\xb8\x27\xae\x2d\x51\xc8\x66\xc4\x5b\x0a\x89\xe0\x41\x42\xfa\x10\x6b\x6b\x81\x75\x19\xd8\xc9\x8d\x92\x38\xed\xeb\x9f\xad\xf5\xf2\x58\x59\xa9\x6a\xbd\xd2\xd9\x88\x24\xe2\x03\xea\xca\x0b\xc7\x68\xfa\xf7\xcf\xec\xd0\x44\xa6\xb6\x8a\x50\x9c\x9a\x72\xd3\x3a\x1a\x23\x7e\x94\x0f\xae\x51\x80\x4c\xf3\x47\xfc\x38\x4d\xb0\x3b\x96\xdd\xf0\x29\xad\xb1\x2c\x7c\x7d\xb5\xfd\x4c\x20\x1b\x12\x2d\x9c\x47\xdc\x1e\x42\x1f\xb2\x1e\xfd\xe2\x5f\x77\x2f\xa0\xd4\x72\x90\x1e\x44\xd5\xc0\xfb\x40\x68\xc0\x77\x60\x12\xeb\x96\x6f\xfa\x4d\x05\x0c\x20\xaa\xc8\xa6\xe8\x8a\x26\x6b\xce\x93\x1d\xc2\x04\x9a\xf6\x75\x65\x83\x23\x62\x12\xb0\xf0\x24\x5f\x61\xb7\x5d\x18\x6a\x81\x3a\x56\xef\x42\x4d\xd2\xef\x89\x89\xad\x76\xa9\xfb\xea\x85\xbe\x3a\xb5\x87\x90\xcd\x9c\x3e\x8a\xf3\x80\x16\xf4\xaf\x81\xb9\x53\xc2\x43\x33\x24\xf1\xda\x9c\xb0\xc6\x75\x00\x1e\x4a\x89\xa4\x41\x57\x28\xd9\xfd\x11\x52\xd3\xcb\xc7\x6e\x4b\xcb\x5c\xdf\x8e\x5f\x56\x9c\xba\x5e\x81\x8c\xd3\x5e\x80\xff\x09\xcc\x47\x68\xf1\x94\x4a\x4a\xc2\xde\xd3\xbe\x01\x18\xc0\xe5\x53\x06\x51\xc0\xba\x18\xcd\x83\x31\x50\xb5\xc7\x58\x3b\xf2\xe3\xdb\x84\x52\x1a\x57\xac\xba\x14\xd5\x35\x34\x22\xcb\xc7\x07\x5d\x1a\x82\xe5\x3e\xc9\x0e\x1d\x5c\xec\x6f\xe3\x7b\x80\xc2\x5d\xec\x98\x0b\x05\x57\x2e\x45\xd8\xe3\x41\xba\x1b\x45\xa1\x55\x36\xf5\x85\xd7\x03\x20\x4a\x1a\xc5\x29\xea\x3b\x3c\xde\x2e\xb6\xb8\x61\x3d\x60\x35\x78\xd7\x2c\x38\x1e\xb6\x5b\xa1\xca\x71\xa0\xef\xd3\xea\x16\x7f\xb5\xa2\x96\x52\xaf\xae\x4f\x70\x27\xc6\x0c\xaf\x90\xc6\xd2\x95\xb3\x43\xb5\x87\x6b\xe1\x89\xfd\xda\x06\x83\xab\x6f\x2b\x5e\xa0\x93\xaa\x86\x94\x47\x29\x4e\x01\xab\x9a\x7f\xf7\xfd\x76\xbb\x7e\xbc\x5d\xaf\x9e\x76\xeb\xe5\x03\xed\x3a\x25\x86\x24\x43\x7e\xb4\xed\x1b\x40\x7f\x0b\xad\x31\x35\xd0\x6e\xe9\xcb\x87\xbb\xbb\xf5\x66\xd3\x11\x4f\x41\x9a\xa4\x1a\xb1\xfe\xcf\xa5\x83\xf3\xb9\xbf\xa7\x49\x88\x3b\x88\x16\xe7\x4b\x5e\x4b\x48\xd3\x14\x14\xb8\x2c\x63\xf5\x3a\x4e\x82\xa7\xa9\x10\xcc\xc3\x03\xa0\x3d\x99\x50\x9c\x73\x72\x03\x43\xb0\xcf\xa6\x63\x7f\x1a\x9d\xd4\x9f\xfe\x7f\xee\x16\x82\xf0\x24\xea\x54\x8f\x8a\x02\xf2\xc7\xb2\x6e\x46\x9a\x18\xbe\x67\x4a\x51\x2a\xf6\xcf\xdf\x2f\x76\xaf\xcb\x58\x44\x2a\x40\xa0\x90\xd9\x41\xbc\xb7\x5b\xf6\xdf\x4f\xc2\xee\x23\xae\x59\x92\x28\x18\xd2\xc7\x6d\xca\x69\x7d\x48\xaa\x82\x14\x41\xaf\xbd\x0c\xf9\xe1\x70\x2a\xb2\xe6\x3c\xf8\xb2\x5a\x59\xe3\xaf\x6c\x17\xcc\xe6\xa5\xf5\x08\x1d\xd2\x65\x5b\xfa\x48\xfc\xa7\x71\x81\xd4\xa4\x31\x06\xc5\xdf\x30\x70\x58\x2f\x8e\xc7\xb2\x6a\x3e\x8c\xd8\x08\x12\x28\x4c\x00\xd9\x77\xdd\x3a\xd5\x80\x99\x4d\x5c\x90\x14\x62\xf0\x38\x3f\x73\x2a\xf4\x84\x44\x11\x04\x01\x16\xf5\xa5\x76\x43\xd9\x38\x10\x01\x4b\x6c\x41\xae\x30\xf0\x35\x7b\x85\xab\x73\xe7\xa9\xcc\xbe\x87\x08\x52\x86\x99\x57\xc7\x58\xb2\x2a\xf4\xcf\xb2\x7a\x19\x0f\xa9\x08\x52\x8e\x39\x55\x1b\x85\xc7\x52\x8c\xe6\xcb\x2c\x0a\xf8\xd3\x7f\xc6\x37\x65\x81\xe9\x6b\xd6\xcb\xd2\xcc\x8e\x06\x4b\x13\x34\x98\x5d\x58\xc8\xba\xad\x63\xc4\x80\x60\x42\x5b\x7c\xe1\x09\x3f\x82\x63\x55\xfb\xfb\xa9\xac\x4e\x87\xc9\x8b\x84\x84\x63\x91\x87\x23\xdc\xf7\x36\x90\x08\x99\xa0\xae\x58\xf9\x4e\xd4\xb5\xfb\x81\x6d\x79\x11\xf3\xf5\xf3\x5f\x84\x11\x95\x36\xc6\x7c\x95\x59\xda\x9c\xd3\x00\xf3\x29\x42\x67\x85\x64\x45\xbb\xab\x67\xaf\x59\x9d\x15\xfb\x95\x31\x65\xd5\xd4\x43\x89\x72\x10\x11\x97\x0e\xc5\x5d\x9f\x0e\xb0\x5e\x3d\x74\x0d\x32\xb6\x00\xa4\x32\xc7\x0c\xc5\xe5\x3a\x16\x31\xa1\x54\x75\xa7\xc8\xee\x30\x09\xad\x8d\x87\x32\x0e\x79\xcc\x1c\x18\x7c\x70\x74\x8a\x38\xd1\xe8\xb8\x6d\x9e\xc5\x0b\xe8\xf2\xad\x20\xef\x5d\x13\x04\x56\xfd\xf8\x74\x5e\x14\xe8\x59\x5d\x57\xa2\xd8\x77\x20\x22\xc1\x13\x8e\x00\x95\xfa\xb9\x7c\xcb\xe1\x15\x72\x8d\x07\xcb\x78\x07\x10\x49\x60\x33\x93\xbe\x50\xe4\x6e\x73\x37\x9f\xd5\x10\x89\x0e\xb9\x1a\x6e\xa6\xdd\xec\x1d\xd9\x11\x22\xd1\x4a\x39\xe2\x31\x3c\x25\xda\xb1\xb9\x13\xef\x68\xe3\xae\x0f\x8e\x61\x1b\x4b\x6f\x7d\xe6\xc3\x7f\xb7\x94\x26\x91\xb3\x88\xaf\xe1\x75\x94\x61\xf1\x3d\x62\x7b\xa4\xda\x03\x7c\x03\xaa\xb2\xe4\xd5\x58\x8e\x3f\x7e\xdc\x54\x86\xcc\x67\x11\xda\x63\x7e\x5d\xd4\x4d\xfb\xcb\xb3\xc9\x3c\x21\x18\x49\x03\xff\xd3\x22\x87\xca\xca\x8d\x9e\x9c\xfa\xf4\x20\xe2\x22\x84\x10\x24\xf1\x78\x08\x24\x9a\x9b\xe1\xb5\x00\x21\xa4\x65\xf1\x73\x59\xcf\xdc\x67\xf7\x85\xa4\xa1\xb6\xea\xf9\x56\xca\xbc\xb5\xfb\x7f\x66\xcd\xf3\xac\x18\x09\x08\xc5\x18\x96\x00\xb6\x8f\xf5\x29\x5d\x0d\x08\x15\x51\x2c\x43\xde\x56\x42\xa3\x12\x81\xe9\x26\x92\x8a\x98\x65\x1b\xcf\xb3\x83\x68\x60\x59\xf5\xf3\x44\x09\xea\x61\x4f\xf8\x8d\x7e\xc3\x22\x3b\x34\x75\xb3\x41\x2f\x1d\x47\x3e\xa3\xe3\x5a\x47\x67\x9b\xd0\x29\x84\xdc\xfb\x41\x8b\x42\x8f\x55\x48\x01\x69\x0f\xc3\xc1\xcf\xcc\x0e\x1a\x50\x2b\xd6\x71\x05\x0d\xbc\x42\xd1\x5c\x38\x12\x7f\xd5\x0b\x70\xf7\x33\x91\xb0\x95\x83\xed\x2f\xee\x72\x51\xe8\x5d\xdd\x31\x41\x83\x30\xad\xd3\xdf\x67\x7b\xbb\xd0\xd5\x07\xc5\x4f\xf6\x2a\x49\x88\xb1\x81\x82\x3d\x34\x4f\x42\x41\xb5\x14\x63\x11\x71\x90\x01\x8b\x22\x27\x0c\xf1\x8d\x8e\x20\x82\x92\xc6\x9c\x59\x20\x1d\xbc\x66\x79\xb6\x07\xbd\xf8\x0b\x72\xfc\x20\x29\xb7\x50\x4b\xa1\x35\xce\xf6\xe1\xe0\x4b\x6a\xec\x8b\xec\xa1\xf9\xfb\x30\x6a\xe0\x9a\x19\x27\x18\x2d\xf5\x8a\x04\x8f\x22\xd3\xd3\x2e\x20\xd1\xf6\xbb\x2d\xf7\x43\x4d\xb2\x47\x71\x2e\x4f\xf3\x24\x2b\x20\xc3\x90\x7b\xe9\x45\xe4\xab\xf9\x7e\x5c\x96\x1f\xf0\xcd\x81\x0c\x39\xa0\x2c\x69\x6b\x69\x7d\xbf\x5f\x6f\xff\xdc\x3d\x3e\x3c\xdc\xfa\x51\x09\x0d\xc1\xba\x4b\x4f\xc7\xbb\x7d\xbb\xc8\xc6\xb9\x9e\x51\x62\xd5\xa2\xda\xa3\xe9\xe1\xe1\xd6\x69\xfc\x47\xe3\xf1\x88\xe3\x14\x1c\x19\xca\x37\x97\xf9\x5c\xed\xf7\xbd\x9a\xa5\xeb\xc6\xa3\x10\xc9\x6a\xa6\x00\xf1\xf1\x6b\xf2\xd8\xd2\xfc\xcb\x4c\x7f\x19\x32\xbf\xfd\x6d\x60\x57\x4b\xae\x35\x3a\xc1\x3b\x55\x1e\x8e\xa7\x19\x29\xc1\x80\xba\xcc\x9f\xfb\x37\x24\xee\x1f\x77\x83\x24\xe0\x08\xcb\x83\x46\x8d\x0e\x21\x99\xa4\x36\xcd\xdd\x94\x4d\x77\x30\xc8\xc4\xa4\x58\x8f\xd8\x05\x60\x2e\xc2\x2f\xa3\x57\x48\x43\xe3\xb3\x7a\x37\x15\xc0\xa3\x50\x99\xe9\xc8\x0f\x40\xa6\x2a\x24\xe0\x34\x1e\x84\x3e\x6f\xad\x42\xea\x64\x86\x08\xa5\x91\x40\xf5\xf1\x69\xb5\xbb\x7a\xb8\xff\xee\x53\x9e\x52\x68\x26\xbc\x17\x24\x8e\x8d\xc8\x8a\x1e\x76\xdb\x8d\xcf\x00\x83\x70\x0f\x6f\x08\x20\xad\xb3\xfd\xe4\x7b\x28\xc2\x02\xd2\xad\xc7\x07\x7d\x29\x9d\xe1\x3b\x6a\x8a\xe1\xd1\x85\xd6\x9b\x52\x65\x22\x77\x95\x32\x17\x49\xf6\xf9\x15\xac\x99\x49\xe3\x9e\xb9\x6b\x7e\x00\xc7\x8f\xa6\x43\x4b\x1a\x5f\x3f\x97\xc7\x4d\x53\x56\xe0\x67\xaa\x1f\x05\x20\x14\xf7\xb7\x01\xee\xfa\x97\x12\x5a\xe3\x97\x82\x28\xc2\xd4\x31\x26\xb5\x5f\xa0\xb0\x06\xd5\xba\xf8\x20\xb9\x2d\x4d\x00\x4c\x3b\x08\xf0\xa9\xf1\xf9\x84\xd1\x3d\x15\xa1\x80\xba\x6f\x4e\x11\x7c\x40\x06\x62\xd9\x10\x47\x77\x54\x41\x1a\x60\xbe\xbf\xc6\xc9\xab\x27\xba\x4d\xa0\x02\xad\x93\x7e\xbf\xbc\x2f\x0b\x07\xdb\x77\x89\x07\x6b\x2a\x4e\x5f\xf6\x82\x0f\x6d\x44\xb2\x3d\x48\x6b\xab\x00\x00\x5d\xab\xcd\x76\xb1\xc5\x40\xdb\x8f\xc5\xed\x77\x1f\x68\x53\x94\x44\x22\xf2\xc8\x10\xa1\x9a\x5b\xac\x44\xec\xec\x44\x45\x63\x45\xc0\x57\xa7\x8b\xe2\x51\x54\xe2\x00\xcd\x00\x19\xfc\xcb\x88\xd2\x7c\x24\xc9\xdf\xde\xd8\x29\x87\xd5\xac\x3b\x04\xcf\xee\xf4\xa9\x1a\xe2\xb6\x15\x23\x5a\x05\x1d\x4f\xda\xfe\xb9\x79\x3c\x15\x99\x27\x0a\x02\xc5\x82\x04\xfd\x7c\x4b\xf6\x7f\x27\x70\xa3\x73\x73\xa4\x1e\xc0\x12\x14\x13\x12\x97\xda\xce\x9c\x9a\x53\x05\xa3\xfd\x40\x85\x40\x30\x8a\xec\xe3\xff\x8f\xa7\xe2\xc5\x43\xb9\xba\xc1\x88\x84\xf4\x9e\xef\x22\xcf\xaf\xc5\xf1\xe8\x4d\x72\x15\x47\x81\x91\x03\x69\x5d\x47\xf5\x88\xc2\xb6\xb3\x70\x7b\xc5\xa9\x46\x80\xcc\x66\xbb\xf8\xba\xda\x31\x7f\x23\xce\x65\xcc\x06\xd1\x14\xd4\xfc\x28\x86\x7a\xf7\x17\x84\x5a\xa0\xb8\x89\x10\x5d\xff\x5b\x79\xaa\x9b\x1e\xad\xa3\xb8\x71\x1a\x78\xe5\xe1\x88\x92\xba\x45\x03\x15\x4c\xe7\xbc\x4a\x8c\x80\x64\xe8\x41\x2f\x9a\xdf\x61\x72\xdc\xa9\x54\xa4\x49\x67\x8a\x8c\x13\x14\xe3\xbb\xa5\x2a\x4c\x9c\x27\x90\x9f\x34\xd4\x1b\x98\x18\xb3\x4a\x68\xbb\xe9\xed\x2b\x51\x60\x28\x7c\x98\xfe\x52\xc2\x84\x3e\x4d\x75\x57\x16\x70\xfe\x88\x99\xd2\x75\x97\x42\x88\xc0\x9e\xb1\xf3\xe7\xea\xb4\xbf\x8c\x70\xbe\xbc\x65\xae\xba\x2a\xf0\x3f\x2c\x0d\xc7\x6a\xdc\xdf\xb3\x5a\x88\xee\x71\x14\x00\x1e\xf3\x3b\x4f\x5e\xfa\xf9\x9e\xa6\xb4\xab\xdb\x1d\x60\x3d\x44\x3e\xca\x3e\x2a\x1d\x18\xd0\x1e\xcd\xfa\x31\xf5\x39\x28\x4d\x39\x32\xc6\xe5\x59\xf1\x82\xc9\x8c\x49\x73\x18\x5b\x26\x81\xd6\xe0\xb5\xc5\x45\x4b\x51\x48\xe8\x31\x26\xbe\xa3\x02\x70\xa1\x3d\xef\x89\xcf\x0f\x8e\xd1\x36\x7c\x8e\x84\x1e\x5e\xd1\x0c\x34\x0d\x42\xe3\xb5\xc7\xcb\x32\x07\x51\xdc\x89\xa3\x35\xe6\x27\x78\x85\x4b\x00\xa2\xa6\xa9\x26\x9d\xb9\x68\xb3\x77\xdd\x92\xd2\x14\xb8\x76\xe4\xd7\x5f\x61\x82\x94\xd2\x8c\xa5\x60\x3c\x3b\xdd\x37\x51\xb5\x86\x7d\x57\xe7\x77\x81\x02\xbe\x74\xbd\xfd\xae\x14\xfa\xb0\xfe\x70\xef\xd1\x2c\xb6\x52\xcd\xcf\xa2\xbe\x2b\xb5\x05\x13\xfa\xc7\x62\x69\xac\xe2\x2e\xfa\xee\x69\x85\x66\xc7\x4c\x33\xb0\xfe\xac\xc5\xb0\x2d\x97\x0f\x9f\x85\xac\x75\x98\x58\x06\xe9\x21\xf7\xf3\x7c\xa4\x42\x87\xc2\x16\x06\xb8\x03\x75\x54\xf0\x3e\x79\x86\x48\x59\x9d\x79\xc7\xa8\x77\x07\x95\x3a\xe5\x53\xb0\xbe\x8e\xa3\x80\xda\xba\xef\xdc\x96\x21\x8c\xe7\x93\x8e\x75\x82\x1f\xe3\x6b\xfb\xd6\x27\x63\xee\x4f\x87\xd9\xbd\x4b\xf3\x58\x78\xe3\xc4\xe3\x5e\xdd\xfc\x73\x66\xf9\xf8\xbe\x09\x15\x08\xc7\xad\xb3\x62\x87\xf5\x3d\x3b\x4b\xea\x38\x79\xbc\x84\x59\x8a\x17\x9b\x5c\xb4\xa4\xd8\x48\x77\xb8\x11\x39\x7c\x18\x98\xd0\x49\x6a\x57\xd3\xd1\xea\x9b\x4d\x12\xd5\x3a\x81\x34\x76\xa0\xcf\x55\xa1\x8f\x65\x56\xf4\x4d\x86\xb9\x58\x4b\x85\x04\xb3\x57\x59\x9e\x7f\x18\xd1\xd2\x22\x20\x08\x5a\x84\xe6\xb9\x86\xdc\x0c\xf7\x2c\x2d\x58\x84\x95\xb7\xcf\xa2\xbe\x9f\x6a\xac\x80\x16\x49\x84\x05\x37\xcf\x25\x42\x68\xc6\xb7\x95\x81\x42\xf5\x1d\x97\x1b\x9f\x3e\xbe\x4c\xac\x3e\xdb\x16\xa9\x4f\xba\xbf\xa6\x76\x41\xdf\x5e\xff\xb1\x1c\x81\x9e\x7c\xbb\xb4\x5c\x4f\x16\xf4\x7b\x5f\x36\x23\x31\x6d\xd0\x3a\x48\x2c\x1c\x27\x3b\xc0\x60\xcb\xf4\xad\x4c\x60\x6a\xd9\x89\x37\x6c\xb6\xcb\x61\xa2\x5a\x6b\x21\xd0\x69\xba\x86\xfc\xc7\x47\xec\x40\x5a\x0b\x99\x46\x9e\x89\xe2\x7b\x31\x9a\x16\xfd\xf9\x35\x19\x62\x6d\x62\x64\xba\x69\x9d\xfb\x21\x22\x4b\x43\x18\xe3\x99\x82\x76\xc2\x1c\x89\x84\x86\xc4\xb2\xb3\xbd\x3d\x8b\x66\x5d\xdf\x65\x75\xdd\x03\x33\xb5\x89\x18\xc2\x95\x33\x55\x76\xce\xef\x64\xa0\x81\xc4\x0c\x4d\xcd\xa6\xca\xd4\x4b\x0e\xdf\x8f\x5d\x83\xb0\xd5\x73\xc2\xb3\xaa\xde\x89\x1e\x02\x33\x7d\x05\x08\xc2\xc8\x38\xbc\x4c\x65\x19\x42\x07\x68\x70\x08\x64\x82\x87\xd5\x1f\x57\x9b\x46\x14\x5a\x54\xfa\x2f\x42\xd6\x20\xd0\x21\xfa\x72\x28\x78\x8c\x61\xc9\xac\x2c\x06\x89\x11\xa0\x51\x1c\x30\xcf\x16\x50\xa9\xc1\x56\xf1\xa1\xdd\x00\x34\xb5\x20\x5d\xd7\xe3\xa1\xb3\x67\x80\xb6\x53\xc8\x51\x65\x8b\xdc\x22\x36\xea\xab\xf3\x06\x2e\xa4\xb7\x01\x18\x4b\xc0\xc6\x5e\x0c\x54\x22\x5f\x68\x5d\x5d\x9d\x3f\xda\x3b\x80\xc5\x1c\xab\x33\xf1\x96\x1e\x5e\xf7\x28\xaa\xe6\xa1\x80\x8f\x2a\x3b\x7e\xc5\x70\x3d\xac\x63\x99\xfc\x6d\x60\x0a\x43\x48\x28\x66\xf0\x16\x5a\x7f\x1c\xf0\xf4\x7d\x55\x44\xe8\x98\xdf\xce\x8f\x0d\x27\x91\x67\x9d\xaf\x1a\x64\xd6\x18\x31\x77\x00\xe7\xb1\xb0\xed\x9d\xe6\xf1\xfc\xb6\x0d\x1c\x02\xac\xf8\x40\x7d\xb7\x01\x75\x1d\x40\xc2\x24\xca\x67\x6e\x17\x9b\x87\x6f\x0b\x44\xc3\x7e\x76\xac\x40\x12\x9a\xd8\x9d\xd0\x18\x39\x9f\xff\xbd\x44\x30\xe9\xbe\x37\xfd\xc0\x3d\xff\xd5\xbf\xee\x4e\x29\xd5\x18\x70\x71\x45\x6b\x57\xe7\x5b\xd8\x0b\x75\x01\x95\x99\x5e\x95\x84\x68\x40\xbf\x42\x55\x63\x80\x57\xc3\xfb\xd4\xbb\xf4\x5d\x53\xf0\x61\x4b\x2f\x8d\xe0\x5a\x64\x1a\x23\x78\xf3\x5b\xb6\x7f\xce\x05\x3a\x54\xae\x45\xa5\x12\x21\xe2\x5e\x53\xbc\xc8\x4c\x7b\x36\x8d\x18\x7f\x07\x96\x09\x68\x95\x22\x8e\x1b\xad\x9d\xab\x93\x77\x06\x00\x34\xd1\x8e\xa3\xe4\x8f\xf6\x45\x26\x53\xc3\xc8\xd4\x02\x43\x7a\x12\xca\xeb\xfb\xa7\xe9\xb9\xd4\x76\xc3\x70\xc9\x63\xf6\x0e\xf9\xf0\xb4\x30\x84\x10\x44\x6f\x95\xa7\xe6\x78\x9a\x04\xf7\x0d\x49\x62\xcc\x43\x63\x1e\x6c\x9b\x41\xc5\xba\x96\x94\x61\x16\xec\xba\xdc\x03\x1d\xdf\x10\x0c\x05\x3f\x59\x11\x5e\xb4\x79\x2e\x4f\xb9\xbe\x02\xd6\x19\x71\x26\x90\x29\x7a\xad\xd8\xa9\x79\xae\x00\xd6\x05\xf6\xbd\x11\x79\x0d\xab\xff\xdc\x7a\xf2\x75\x30\x34\x0a\x04\xf7\xf8\xd8\x65\xe3\x07\xd8\xb0\xc8\xf2\x24\x7e\x13\x85\xfe\x99\x15\xf5\x8f\x0c\xc6\xcc\xbd\x6d\x17\x88\x1d\xa9\xed\x1e\xe8\x80\xf8\xcd\x30\x4e\x07\x74\xea\xe8\x58\x59\xf7\xe6\x36\xc3\xaa\xa6\x75\xd1\xa7\x84\xbf\x17\x59\x33\xbd\xb1\x54\xbe\x78\xa3\x4f\xf3\x55\x87\x1e\x9f\x9f\xf8\x8e\xc6\x56\xdc\x2e\x6e\x9e\x3a\xd6\x58\x30\x61\x00\xcc\x15\x2e\xac\x1b\x38\xac\x75\xfd\x28\xf6\x42\x5e\x06\x41\x5d\xff\x48\x49\xc4\xf0\xfe\x58\x2f\x47\x43\x1d\x69\x4b\x99\xfb\x28\x8e\x97\x68\xdd\x0f\xb6\xa7\x7f\x8e\xc5\xe0\xc1\x70\x6a\xeb\x87\x6d\x42\x6b\xf3\xd6\x17\xd8\x5d\xec\x6c\xb3\xa7\xab\xe1\xb1\x46\xcb\xc5\x97\x88\xcf\x6a\x87\x4c\xde\x88\x0b\x9d\x2a\xaf\xf8\x35\xa4\x0f\x19\xe6\xc6\xfb\xee\x49\x22\xd0\x0d\xbb\xbe\xfe\x6d\xb1\x1d\x20\xa9\x4c\x22\x22\xb4\x2d\x36\xcb\xfb\x5f\x56\xd7\x9b\x34\xb2\xec\x06\x35\x34\xdf\xab\x79\x7a\x19\x93\x26\x4c\x3b\x14\x15\x16\x13\xb5\x96\x5f\xeb\xa4\x30\x3a\xc7\xf6\x62\x52\x67\xfb\xf4\x0c\xce\x60\x44\xc4\x99\xad\x7f\x29\x96\xa5\xee\xff\x1c\x27\x06\xcf\x7d\xb3\xf6\xbc\x20\x96\x9b\x7a\xfc\xaa\x82\x47\x48\x40\x55\x81\xd0\xbb\x13\xeb\x56\x8c\xe0\x3a\xf5\x4c\xc3\x13\xc6\x90\xc9\x0d\x84\xad\xbf\xb0\x3a\x9d\xce\xa6\x72\x6d\x32\x88\x11\x78\xe6\x75\xaf\x91\xf6\x56\x0f\x02\x13\x46\x52\x5b\x43\x8b\x94\x2c\xa8\x49\x34\xef\x10\x18\x19\x47\x48\xb5\x75\x74\x5a\x44\xe7\x55\xf3\xbc\x2e\x46\x00\x28\x23\xa5\xc1\x88\xf0\xd5\xe2\xfe\xf7\xa7\x87\xdb\xdb\xd5\x93\x6f\x51\xa1\x42\x56\x60\x51\xd7\xa5\xca\xc4\x80\x06\xa5\xeb\x91\x28\x04\x75\x9f\x8a\x1a\x90\x2d\xee\xe2\x3c\x9e\x84\x9b\xdc\x75\x9a\xd0\xd4\xe3\xf4\x7e\xf6\xe2\xc2\x60\x20\x02\xab\x33\x25\xea\xe7\x87\x93\xd5\xd8\x1e\x8f\x1c\xc4\x29\x9e\x5b\xf6\x98\x5c\x96\x79\x59\x3d\x66\x1d\x11\x87\x81\x54\xe1\x8e\x5e\x87\xc4\x51\x55\xfa\x06\x41\x30\x84\xd0\x1a\xb0\xad\x45\x34\x80\x1b\x1b\x42\x62\x0a\xb6\xb2\x2f\x47\xaa\x80\x11\xa7\xa0\x21\x44\x02\x3a\xb9\x3b\x5b\xa0\x32\x17\xa6\xec\xad\x06\x43\x02\x1e\xa1\xf8\xfa\x9b\xb7\x14\xe6\x8a\xed\x46\x6b\xcd\x90\x20\x09\x03\x97\xfe\x29\x3d\xcd\xd2\x30\x5f\xda\xf6\x88\x31\xed\x6f\xa1\x7b\x1b\x57\x1b\x3e\xf6\x31\xc7\x22\xcb\xee\x42\xca\x98\xab\x58\xaf\x8a\xcd\xb9\x68\x9e\x1d\x28\x31\x9c\x3c\x02\xd5\x16\x52\xe1\x8c\x78\xb4\x2e\x46\xa0\x59\x43\x18\xd1\x54\x79\xda\xdb\x11\x98\x7d\xee\x3b\x1b\xc2\x02\x2b\x1f\xe3\x94\x87\xef\xb2\xa2\xb1\xa4\xfc\xbf\xb0\x21\xfc\xe5\xa9\xb5\x8b\x1e\x6f\xaf\xb7\xdd\x23\x40\x82\x02\x42\x77\xa5\x7a\xe9\x70\xc4\xf9\x90\x16\xda\x90\x90\x07\xc4\xd2\x04\x1e\x6c\x01\x28\xed\x5a\x52\x40\x50\x62\x7b\xa4\xdd\x88\x2c\xdf\x21\x76\xc9\x08\x05\xbb\xd6\xc7\xed\xba\x69\x82\xfc\x50\xa3\x6c\xdf\xfc\x33\x46\x4c\xa2\x1a\xc6\xb2\x74\xe8\x74\x7f\x8f\xc8\x08\x17\x45\xc7\x87\xd4\x3f\xac\x09\xd3\x37\x2b\x0c\xdb\x1d\x4e\xf9\xb1\x7c\xa3\x5f\xc6\x77\x8d\x59\x82\xe5\xcb\xee\x5b\xdc\x89\xf7\x71\x05\xb4\x21\x3c\xed\x98\xd8\xbf\x89\x4a\xbf\x89\x0a\x66\x4a\x4e\x0c\xe1\x8a\x63\xe5\xe7\xa2\x6a\xba\x6b\x13\x42\x30\x97\x51\x08\x84\x49\xf7\x2c\x11\xc3\x6d\xb6\xb5\x2b\x74\xec\x0a\x95\xb7\xd0\x9e\xb8\xd5\xe4\x29\x13\x08\x84\xe7\x3e\x15\x95\xcc\x9a\x7a\xe7\x84\x5f\x77\xe5\x71\xc2\x6a\xd6\x1a\x23\x06\x8f\x93\xfa\x08\x2a\x33\x99\xc2\x72\x4d\x04\xc2\x4d\x6e\x9b\x86\x14\xf9\x0f\x76\x96\xc8\x51\xbd\x3c\x23\x60\x72\x72\x3b\x41\x38\xee\x6d\xcd\x37\x51\x7f\x3f\xbe\x96\x0d\xcc\x2b\x52\x98\xd6\x1d\x0b\x5d\x48\x1a\x25\xe1\xac\x27\xe4\x34\x33\xc7\x3f\x2d\x94\x15\x63\xb3\x65\x97\xf7\xf0\xde\x0c\x48\xe1\x0c\x91\xa1\x52\x8e\xa3\xd1\x89\x86\xf5\xa8\x13\x43\x24\xb7\xe8\xe3\xdf\xff\x5c\x4e\x92\x89\xdd\x5a\x94\xd2\xc8\x64\xa0\x6b\xd4\x05\x18\x2e\x8f\x39\x43\xa4\x96\x98\x3b\x6f\xca\x71\xec\xdc\x35\x2b\x92\x6a\x2f\x35\xf0\x5c\xd6\x50\x0c\x49\xec\x0d\x51\x29\x45\x4c\x24\x3e\xe6\x6e\xd3\xc9\x7d\xfa\x66\x03\x58\x6f\x20\xb4\x5e\x54\x4d\xa6\xca\xbc\x1c\x12\x67\x04\x64\xfc\xaf\xbb\x4a\x83\xcd\x82\xa1\x27\xf3\xb3\x6c\x6d\x69\xef\x16\xcc\x88\xd0\x19\xa2\x8d\x46\x4e\x03\xd9\x43\xc3\xfd\x03\x00\xb7\xaa\xe4\xb7\x20\x8a\x9e\x43\xd4\x10\x00\x4b\x38\x6c\xe5\x32\x7f\x8a\xaa\xca\xca\xaa\xde\x96\x57\xa2\x69\xf2\x0f\xd3\xb3\xe3\x55\x19\x10\x16\x0a\x57\x99\x68\x6d\xfb\xaf\x95\x28\x1a\x98\x77\x73\x4c\x40\x62\x89\x6b\xb5\xac\x84\xc2\xe4\xa9\xff\x3b\xe7\x88\x49\x3a\xec\xa0\x2b\x82\x9e\x5c\x29\x13\x65\x3a\xba\xd4\xb2\xf4\x38\x2c\x13\x10\x95\xe0\x3d\x9b\x53\x55\x74\xec\x97\x26\xa0\xcc\xa0\xba\x58\x7b\xf4\x79\x7e\xa7\xcf\x7c\x20\x13\xd0\x54\x2b\x6a\x33\x0d\x5e\x7b\xa9\xa3\xf7\x34\x01\x8b\x8c\x89\xa6\x56\xee\xd0\xbd\x34\x01\x8b\x35\x38\x28\x08\x2e\x37\xb4\x9b\xb3\x52\x4f\x5e\x85\x25\x04\x57\xf3\x0e\xb1\x01\xa7\xaa\xdd\x1d\x8a\xc6\x0e\xfb\xf4\xb5\x99\xb1\x2b\xdf\x58\x48\xd8\x30\x35\x62\x82\x30\x09\xb5\x67\x09\x40\x9e\xd8\xe3\xa9\xc1\x35\x77\x21\x03\x64\x82\x88\x2b\x4f\x76\x39\x4c\x78\xfb\x5b\xc5\x21\xc1\xe2\xe6\x47\xa8\xea\xd2\x99\x4a\x1f\x7c\xc3\x38\xe5\x78\x36\x1d\xb2\xc2\x63\x8d\x26\x07\x73\xc0\x43\x8e\x81\x19\xd5\x8e\xc2\x35\x78\x3a\x69\x6f\x2e\xfe\xf3\x5f\xe3\xe3\x2b\xe0\x1a\x90\xa9\xb1\x46\x92\x93\x9d\x7f\xa8\x34\x10\x98\x02\xcb\xea\x01\x7f\xa9\x4f\x44\x82\x5e\x14\x1a\x29\x17\xc6\xfb\x55\x90\x1a\xa2\xed\x41\x91\x15\xbe\x26\xf3\x57\x36\xfc\x5f\x71\xad\x4d\x20\x8c\x85\xb2\x18\x80\xab\x53\x55\x40\xf5\xb3\x12\xc7\xa3\xe3\x46\x1c\x9b\x6c\x26\x90\x91\x01\xb7\x32\x7a\x52\xc6\xf1\xfd\x24\xd7\x88\xcc\x42\x8d\xbc\xc9\x4f\xfe\x33\x74\x5b\x59\xa0\x48\x62\xd9\x87\xf5\x21\x2b\x2e\x62\x98\x26\x50\x3c\x0d\x6d\x04\x4e\x74\x31\xdf\x51\x16\xc8\xf7\xd3\xb1\x66\xee\x48\xa6\x13\x6b\xa6\xeb\x92\x1a\xc7\x05\xf7\xf5\xab\xf5\xae\x26\x7c\xd6\xae\xa3\x26\x31\xe6\xa5\x5c\xc1\x0c\xca\xa7\x5a\xee\x8d\xcf\x35\xb0\xc7\x77\x81\x20\xf5\x55\x3f\x4e\x09\xf1\xcb\x78\x5e\x00\x58\xba\xc2\x3d\x34\x57\xfa\xd8\xd1\x62\xfa\x02\x6a\xbf\xe9\x07\xb1\x1f\x2b\x63\x52\xb4\x93\x2b\xd1\xc0\x4d\x59\x59\x54\x82\x72\xd0\x6f\x1b\x62\x35\x94\xa4\x31\xba\x29\x77\x8b\x3f\x76\x8f\xdf\xaf\x6e\xd7\xcb\xdd\xe6\xe1\xd6\x29\x47\x19\x4a\x64\x8a\xaa\x9f\x07\xf1\x9e\x1d\x4e\x07\x47\xb9\xdf\x2e\xa9\x75\xb1\xda\x7e\xf3\xdd\x02\xc2\x90\x0f\x01\x29\xf7\x26\xc0\x48\x43\x69\x28\x31\x8c\x7b\x14\x55\x0d\x8b\x42\x63\x0e\x7d\x50\xd3\x6d\x28\x8d\x8c\x76\x63\xbd\xcb\x45\xdd\xec\x4e\x35\x54\xbb\x0a\x94\xa8\xc7\x59\x39\x43\xa9\xd1\x78\x02\xdf\x37\x43\x66\x41\x43\x19\x04\x26\xe8\x32\x92\x37\x65\x75\x97\x5d\x92\x7a\x8e\xe7\x30\x0d\x95\xe5\x83\xad\x6d\xad\xd1\x42\xcd\x21\x45\x07\x5e\x9d\xa1\xa1\xa6\x28\x93\xdc\x5a\x1a\x5d\x8a\xdf\xb5\x45\x44\x44\x30\xd2\x8b\x29\xf4\x58\xbf\x6e\x7e\x13\xa1\x51\x9a\x58\xb1\x11\x4c\xc9\xde\x9f\x0e\x3f\xb2\x3c\x17\x7b\x98\xcc\x00\x1a\x07\x09\xe6\xf8\x9a\xdd\xfa\x70\xc8\x85\x55\xe1\xc7\x3b\xbb\x3d\xbd\xac\xfc\x76\x48\x63\x06\x28\x41\xf2\xad\x3c\xc0\x47\x32\x04\xc9\xe4\x39\xe2\x94\x87\x51\x6f\x3c\x76\x2f\xc6\xa3\x14\x83\xc5\xad\x17\xf3\xbd\x68\xb2\x1c\x91\x6f\x8b\x76\xbe\x63\x68\x62\x34\x91\x29\x8f\x13\xb4\x11\xad\x78\xf1\x5d\xf9\x7a\x41\x7f\xe0\x3b\x26\xb6\xfe\xf8\x71\xf5\xb4\x7e\xb8\x76\xf5\x37\xdd\x6f\x2a\x4b\x7d\xb8\x01\x75\xaa\xb2\xe6\xbc\xfb\x26\xea\x47\x51\xd7\x6f\x65\xa5\x37\xcf\x82\x61\x35\x10\x40\x81\x84\x90\xed\x39\x5d\xbc\x78\x1c\x88\xbb\x43\x42\xac\x20\xb3\xb5\x35\xd7\x0d\x1c\x2e\x29\xb6\x0d\x4d\x12\x9b\x93\x76\x84\x6f\x2b\x5b\xa6\xe6\x95\xc1\xba\x7b\x89\xa8\xc7\x92\x59\xde\x04\x00\x3d\x04\x77\x19\x9a\xa6\x11\x1e\xbd\xdf\x44\x7d\x55\x96\xf5\x54\x13\xde\xd0\x14\xb8\xad\x15\x84\x83\xc0\xe3\xe2\xab\xa8\x87\x92\x66\xae\x9b\xe0\x06\x9f\xe8\xaa\x82\xb7\x4e\x15\xd2\x50\x19\x04\x18\x8d\xc3\xa0\xb9\x3d\xfa\xfe\x5a\x50\xbe\xbd\x34\xc5\xaa\xc3\x3b\x51\x1d\xca\xe6\x2f\x5f\x45\x01\xa7\xfa\x13\xfc\x28\xbb\x87\xe0\xb1\xb5\x70\xb2\xea\xba\x2a\x8f\xdf\xa0\x2a\x47\xfe\x22\x95\x86\x50\xc7\x49\x72\x27\x5a\x37\xa7\x68\x37\xcc\x3b\x51\xed\xb3\x62\x3c\x5c\x40\x93\xc8\xb9\x12\x57\x99\x1e\x69\xb7\x8c\x56\x1c\xd0\xae\xa2\xcb\x71\x0a\x95\xd5\xe5\xc6\x4f\x0d\x51\x98\x95\xdb\x58\xb0\xf1\xd2\xab\x96\x7c\x54\xf8\xec\x2f\x4b\x03\x2c\x9d\xd8\x1d\xa1\x32\x65\x75\x98\x0a\x7d\xfd\x6d\xf2\x2b\x22\x0d\xfa\x6a\x46\xbb\xa1\x66\x50\xa3\x81\xd3\xaf\x17\xa3\x5c\x0c\x30\x2f\xa5\xc8\xef\xb2\xc2\xbb\x51\x8b\x83\x7f\x7d\x46\x98\xc0\x54\x68\x2d\xf2\xd7\x8e\x77\x7e\x7e\x7f\x60\x24\x94\x42\xfa\x20\x73\xa6\xe0\xea\xbc\xac\x40\x43\xd1\x64\x22\xb7\x51\xc2\x59\x96\x16\xc3\x08\x84\xb8\xad\xde\x96\x7b\xfa\x21\x12\xe6\x33\x48\xb8\x33\xc7\xa7\xcf\x03\x6e\x3f\x70\x9b\x5b\x47\x6f\xf6\xd1\xf3\x03\x20\x0f\xff\xd7\x07\x7f\xae\xb0\x80\x18\xcc\x5b\xdc\x97\x96\x42\x62\x66\x73\xf2\x3d\xc3\x88\xa7\x68\xf7\x5c\x8b\x33\xb2\xc6\x74\xf7\x30\x61\x2a\xbd\x5b\xd0\x7a\x4d\x6e\x03\xc8\x8a\xfd\xc8\xe8\x67\x8c\xa4\x48\x2a\xf2\x0c\xa2\x6a\x24\x88\x66\x50\x05\x67\x18\x4b\x01\xc3\x30\xaa\x2c\x5e\xa1\x6a\x6e\xcb\xe6\xea\xbc\xd6\xe3\xad\x97\x31\x93\xa0\xf5\x85\xe9\x20\x2f\x6f\xfc\xd7\xdc\x02\x16\x31\xbb\x72\xd7\xf7\xeb\xed\x7a\x71\x6b\x49\x43\x76\x37\x4f\x0f\x77\xbb\xe5\xc3\xdd\xe3\xc2\x47\x7f\x0d\x8b\x62\xc0\x1d\xf1\x58\x41\xa6\xca\x59\xa6\x76\xc3\x22\x01\xd4\x33\x5d\xfa\x9d\x64\x58\x4f\x8e\x3d\x98\x73\x3d\x37\x42\xeb\x1c\x36\xcf\xe5\x11\x19\xb0\x60\xb2\xfd\xb1\x48\x32\x0b\x33\x79\x3e\x77\x57\x2b\x5b\x41\x61\x91\x4a\x3d\x46\xc9\x37\x6b\x81\x8e\x81\x1b\xae\x6d\xb9\xec\xb4\x81\x3e\x3c\x68\x59\xcc\x79\x82\xfb\xc6\x7e\x5f\xc1\xbe\x4b\x07\x1a\x16\x83\xe5\x5c\xb2\xa9\xab\xef\xb5\xd3\x2e\x9e\xc9\xa0\x1b\xc6\x83\x00\xd9\xab\x4d\x56\xe8\x21\x87\xff\xc0\x90\x60\x3c\x4a\x98\xe3\xc6\x6e\xad\xd2\xd3\xf1\xeb\xc5\x56\xc1\x78\xa2\xc0\x86\xa6\xa6\x9e\x38\x4b\xb4\xe7\x80\x13\xd9\xa1\x2f\x8f\x32\x2c\x4d\x63\x64\x28\x31\x48\x35\x81\xee\xf9\x50\x24\xc2\x30\x11\x5a\x0b\xf7\xf6\xe1\xe1\x6e\xbd\xd8\xb9\x7f\x9e\x56\x77\x8b\xf5\xfd\xf5\xea\x69\xb7\xb8\xbe\x7e\xf2\x7d\x95\x8a\x31\x45\x7f\x57\xbe\x67\xa2\xe8\x83\xd6\x86\xe9\x04\x42\xd6\x89\x8c\xb8\xa3\x3d\xcf\x5e\xa1\x9a\xa7\xb8\x32\x4c\x2b\x5b\x80\x09\xaa\xac\xcf\x75\x03\x87\xab\x53\x96\xb7\x36\xda\x30\xef\x6c\x18\x24\x22\xb4\xbe\xa6\x86\xca\xc2\xbd\xc6\x13\xdc\x10\xc0\x67\x52\xbb\x7a\x62\xbe\x31\x13\x50\xe9\x6a\x20\x8d\x25\x42\xc9\x8a\xfd\xc4\xc2\x0f\x49\xe2\xa8\xa3\xac\x68\xf1\xa9\x1e\x7e\x96\x90\x28\x70\x47\xdf\x6b\xf9\x02\xdf\x8b\x4c\x95\xd5\x18\x0c\x60\x42\xa2\x35\xc2\x0f\x16\x58\xcf\x37\xb4\xed\xc2\x20\x81\xb0\x8b\x00\xe2\xb7\x99\xf3\x25\x43\x4a\x95\xb2\xd5\xae\xd5\x0b\x34\x9d\xb4\x49\x3d\x76\xcb\xfc\x7c\x0a\xa9\x76\x01\x3b\xd4\xfe\x1d\x82\x88\x4d\xc8\x02\xe3\x45\x73\x87\xc2\x0c\x73\x15\x33\x26\x64\xc6\x96\x9b\x63\x44\x0a\x0f\xb9\xdd\x21\x2b\x4e\xf5\xae\x97\x18\x9d\x3c\x69\x98\x70\x6a\x8d\x55\x73\x2a\xf4\xdd\x07\xde\x65\x18\x42\x88\x60\xb6\xf2\x15\x2a\x5d\x09\xd3\xd8\xd7\xae\x47\x31\x97\x30\x0a\x82\x04\x86\x44\xbc\x96\x23\xff\x02\xe3\x64\xc2\x48\x03\x9e\x76\x3a\xab\xdb\xc9\xed\x29\x1b\xfd\x8d\x62\xa6\x2d\x4c\x1b\x8a\x46\x8c\x3e\x40\x9c\xc4\x09\xed\x34\x20\x17\xdd\x57\x8f\x5d\x3d\x04\x2a\x9b\x3b\xef\x68\x22\xe3\x66\x42\x1e\x59\x3d\x92\x76\x2c\x37\xd7\x8f\x70\x41\x79\x60\x42\xce\x23\xea\x96\xad\xe7\xa1\x79\x90\xff\x86\x71\x9d\x81\x09\xb9\xb2\x44\x74\x48\x8f\xdf\x3e\xb9\xe7\xe2\x1a\xdf\x2d\x09\x24\x3a\x64\x28\x6a\xf2\x99\xec\xd6\xc8\xe0\x09\x93\x44\x09\xe6\x65\xc7\xff\x73\xca\x6c\xf6\x63\x2e\xd8\x1e\x26\xa9\xe5\xa0\xdb\xb5\xbb\xd6\xac\x57\x18\xa6\x82\xe2\x2b\x5d\x43\xfd\x9c\x0d\xd6\x78\x98\x02\xa3\x0e\xaf\x6f\x6b\xb2\x2d\x84\x64\x7c\xb5\xa0\x69\x12\x0e\xbe\x69\xf6\x5f\xcb\xdc\x3d\x09\xb3\x87\x22\xa1\x54\x8f\xf9\x9e\x2a\x51\xa8\x67\x98\x1b\x17\xc9\x12\xec\xfc\x28\xfe\x73\x12\xbd\xe2\xe2\x2f\x4d\xc1\x50\x32\x25\x6c\x44\x3d\xb7\x4e\xc7\xe7\xc1\xa3\x50\x82\xa6\xb1\x8f\x7d\xba\x52\x5a\xd1\xc0\xd5\xf9\xc1\x31\x00\x5f\x18\x23\xa3\x9f\x53\x41\x08\xe0\x35\xa8\xb1\xdf\xc5\xa1\x30\x9c\xd5\x8a\x52\xcf\x5d\x78\x7f\x3a\x2c\x50\xf4\x68\xe6\x83\x28\xa6\x51\x33\xeb\xea\xb1\x34\x77\xe2\x05\xaa\xcf\x88\xdc\x4c\xa8\xe2\xc4\xc5\x41\x7b\xff\x0a\xf4\xf4\x9e\xa9\xec\xd8\x3a\xaf\x11\x42\x09\xc8\x82\x33\xb9\x95\x0e\x23\xee\xd5\xd2\x97\x42\x3d\x03\x5a\xb2\x59\x73\x46\x1e\x24\xd7\x4b\x73\x4b\x24\x7f\x9b\xc9\x4c\x97\x6a\x30\x63\x80\xe9\x91\xae\xcc\x38\x2f\xdd\xf5\x0a\x43\xac\xa2\xdd\x2e\xee\x7f\x5f\x3d\xed\xb6\x7f\x3e\xae\xba\xa6\x34\xd5\x2e\xcf\xd3\x9e\x87\x3d\x99\x9c\x09\x8d\x4e\xc1\x55\xfb\xe1\x43\xdd\x96\xea\x25\x2b\xf6\x0b\x27\x2a\x30\xde\x67\x07\x24\xcd\xff\x64\x6e\x0a\x46\x84\x18\xc9\x5d\x5a\xf2\xca\x7e\x4e\x17\xd3\x1d\x8d\x42\x44\xc0\x96\x79\x5c\xc3\xb5\xc3\x3f\xcf\x56\x3d\x99\x28\xe0\x5c\x06\xce\x8f\xbe\xc6\x42\x51\x9f\x2a\x35\x51\x90\x4a\x0c\x3c\xea\x12\x6a\x84\x9c\xaf\xde\x07\xd5\x64\x63\xf3\x37\xa2\x31\x41\x74\x50\x97\xef\xf4\x77\xa1\x46\x82\xa5\x03\x6e\xaa\x0c\x5e\x91\xa4\x1b\x07\x65\x7c\x3d\xd3\xca\x96\x7c\xba\xe7\x94\x42\xbd\xe4\x5d\xe9\x84\x89\x42\xb0\x58\x2c\xe7\x2f\xef\x6a\xc8\x27\x7b\x5f\x14\x49\x8b\xf5\xb0\xf6\x8d\x0d\xd7\x55\xe7\x9b\xaa\x3c\x6c\xc5\xbe\xbe\x2c\x73\x33\x51\x1c\x10\x6d\xc5\x7a\xb6\xcf\x59\xfd\x58\x81\x29\xab\x97\x71\x1a\x27\x8a\xb9\x95\xea\x38\x60\x50\xaf\x16\x39\x74\x84\xa1\x26\xe2\x21\xc3\xe0\xa6\xcb\x53\x4d\xcf\x03\xdf\x8b\x2b\x3c\x52\x4f\x58\xa2\x36\xc2\x7f\x99\x88\x6b\x6a\x73\xe7\x08\xfa\xa6\xa8\x64\xe7\xdb\x12\x97\x8d\x6b\x9d\x11\xe7\xd6\xa0\xbd\x3c\x5c\xc1\x51\x12\xf1\xd0\xc1\x18\xb6\x19\x54\x8f\xed\xe2\x19\xa0\x78\x7c\xaf\x34\xa4\xc1\x10\xe8\x39\x5d\x5f\x51\x92\x46\x9c\xf6\xf2\x9b\xcd\x5a\x6f\xab\xec\xd8\x07\x98\xc6\x33\x2c\x01\x2d\x1c\x17\x81\xf5\xcf\x2f\x04\xc6\x5d\xc7\x34\x91\xb6\x48\x38\x2b\x0a\xa8\x7a\x86\x93\xc9\x8c\x4d\x53\x81\xb8\xb3\x9d\xcb\x24\xce\x3b\x39\x7f\x9b\xdc\x5b\x71\x6f\x08\xfd\x00\x8c\x96\x39\xbf\x77\xfe\x37\x04\xd3\x32\xf1\x73\x34\x43\x61\xc6\x41\x20\xd9\x77\xe2\x31\x75\xe1\xf6\x1b\xc4\xc7\x9b\xf2\xcb\x78\xe7\x9c\x3c\x84\x24\x1d\x57\xf5\x9d\x0d\x6c\x4c\x32\x79\x91\x24\xb6\x56\xbd\x1d\x59\x7c\xbe\x2e\x10\x7e\x31\x5a\x52\x30\x34\x0b\x76\xe6\x23\xfd\x75\x13\xa9\xc0\xaa\xc4\xaf\x0b\x93\x15\x59\x83\x62\x2d\x56\x5f\xd7\x77\xa0\x69\xd4\x45\xc1\xef\xc4\xbb\xd7\x3f\x99\xdc\x26\x8c\x3c\x53\xcd\x8f\xb2\x19\xd1\x64\x99\x48\xc5\x06\x77\xe4\xfa\x5c\x34\xcf\x50\xf7\xa4\x3e\xff\x8c\xfe\x35\x19\x55\xe5\x4a\x05\xba\x50\xcb\x40\x34\xdc\x75\xd1\x21\x41\x20\x62\x53\x36\x60\x8f\xfb\x8e\xa6\x15\x23\x40\xc8\xbb\xea\x3b\x03\x70\x94\x49\xf3\xfc\xeb\x56\xae\xaa\x33\xc1\x62\x12\x06\x56\x8b\x4d\x95\x17\xf6\x73\x4c\x12\xe3\xe4\xb7\xb6\x0e\x06\x30\x79\xf9\xf1\x58\xc6\x44\x46\xc4\x58\x7e\xb3\x72\xac\x9f\x62\x62\xa2\x95\x95\xe2\x5c\xde\x3d\xfc\x31\x6a\x09\x68\xa2\xbc\xb6\x95\xcd\xd5\x8c\x86\x24\xa6\x82\xfb\xaa\x90\x65\x75\xae\x1b\x91\xff\x9e\x15\xda\x96\xaa\x4c\xbb\x2a\x83\x24\x75\x50\xe8\x2b\x68\xae\xf2\x53\xf7\x2a\x8c\xc4\xb8\x23\x9e\x6a\xa8\xac\xa6\xcf\xf8\xd1\x99\x63\x70\x3d\x8a\x53\x0d\x6a\xec\x22\xc4\x8c\x47\x4a\x77\x65\x60\x1f\x2c\xe2\x98\x69\x11\xb0\x61\x6a\xc9\x6f\x9a\xfe\x36\x21\xd1\x38\x3c\x5e\x88\xd4\xc4\x61\x9a\x62\x59\xa0\x25\x95\xb9\xce\xf6\xfb\xfe\xcb\x44\x2c\x41\x84\xa2\xa5\xbf\x2a\xf0\x7c\x1b\x93\xd8\x98\x38\x0e\x0d\x82\xae\xae\xb2\xe6\x45\x74\x8f\x1b\x27\x56\x49\x7c\x4c\xc5\x34\x7e\xd8\x58\x45\x4e\x89\x01\x9d\xe1\xfe\x0c\xf1\xed\x20\x31\xdf\x79\x5b\xee\x67\x25\xe4\x4d\xcc\x95\x46\x3a\xcf\x6f\x57\xa3\xaf\x99\x44\x21\x1a\xdc\x88\x87\xb0\x11\x4c\xbb\xf4\x86\x34\xe8\x26\x4e\xb4\x66\xc6\xf3\xdc\xd6\x70\x51\x8a\x6e\xe2\x94\x02\xf1\xdc\x4f\xa7\x3c\x77\x09\xe8\xcb\x08\x07\x26\xb2\x48\x97\x84\xf6\x5e\x27\x86\x42\x47\x62\xfb\xff\xa4\xff\x1a\x56\x2d\xc4\x61\x6b\x14\xf4\xac\xfd\x93\xe8\x92\xef\xfd\x11\xcb\xa9\x7f\x11\x41\x15\x46\x03\x7f\xdb\x2e\x97\xcd\x2f\xe0\x5a\x26\x16\xc6\x7a\xf0\x87\xcc\x33\xcc\x7a\x83\x38\x96\xc4\x42\x97\x47\xec\xa3\xd3\x1d\x7b\xc6\xd2\xfd\x3c\xdb\x15\x4b\x16\x07\x91\x2f\x25\x40\x26\x24\xab\x0f\x81\x02\x72\x9b\x4e\x48\xa2\xed\x68\xf9\x7b\x2b\x0c\x12\xbf\x65\xad\xa7\xed\x9b\x64\x82\xe6\xc2\xce\x49\x6f\x0e\x73\x71\xe3\x49\x21\xb5\x95\x84\xf0\x35\x66\xf5\x64\xd2\x28\x62\xe5\x71\x64\x31\x42\x7f\xc4\x8a\x11\x3c\x50\xef\xc4\xbb\xd3\xea\xd2\x57\x42\x75\xad\xdc\x20\x6c\xbd\x53\xaa\x9a\x26\x6a\x62\xa5\x29\xb2\x54\x58\xe1\xd0\x45\x51\xbf\x41\xb5\x28\xf4\x0d\x9e\x4d\xff\x9d\xc7\x20\x9a\x58\x13\x2b\x5a\xb7\x68\xca\x43\xa6\x36\x6f\xe2\xe8\x97\xec\xb2\x2c\xea\xa6\x3a\xa9\x3e\x4e\x12\x6b\x2d\x30\x16\x57\x3f\x67\xa6\xd9\xe5\x60\x3e\x38\x18\x63\x6d\x22\x84\xaa\xb4\x46\xef\xc7\x75\x2d\x26\x86\x38\x06\x1b\xe3\x54\x2f\xa7\x23\x8b\x0f\x93\xb1\x32\xcc\x52\x21\xd8\x25\x92\xa9\xa1\x60\xd5\xf8\x4e\x26\x8d\xbd\xbc\xcb\x13\x88\xbe\xbc\xd0\xc4\x46\x00\x2a\x03\x55\x65\x79\xe8\x94\x5d\x26\x9e\xe5\x04\x62\x6f\x62\xa3\x00\x4b\x68\x9e\xca\xb3\xc8\x9b\xf3\x00\x07\xea\xed\xde\xcd\x25\x15\xf9\xc0\xaf\x89\x0d\x24\xe0\xb1\xdd\x5f\x61\xf4\xa5\x79\xc0\x22\xac\x01\xc6\xba\x85\xfe\x8f\x16\x6e\xb9\xf9\xfe\xf8\x78\xfb\xe7\xee\xe6\xe1\x09\x95\x89\xee\x57\x4f\x9b\x6f\xeb\x47\x9f\x5a\xe1\x94\x02\xc6\xdc\x54\x59\x14\xa8\xd3\x38\xcf\xac\x68\x38\x4d\x63\x50\xc3\x53\xf4\x4a\x14\x2f\x55\xd9\x21\x96\x38\xe3\x5a\x70\x27\x64\xb9\xcc\x33\x28\x30\x8d\xf6\x28\x32\xfd\x34\xe5\x5a\x4d\xfc\x25\x89\x45\xec\xd7\xd0\xf4\x49\xab\x6b\xc8\x6d\x54\x70\xfc\xfb\x11\x25\x32\xf5\x51\x07\xaf\xb5\x30\xe1\xa3\x33\x3c\x12\x1a\xbd\x5a\xeb\x2a\x5f\x67\xf5\xf1\x74\x71\xa7\x38\x8e\x94\x2b\x8a\xc1\x9b\xdc\x74\xaa\x05\x86\xc7\xa9\x8c\xc2\x41\x34\xdb\x39\x90\x17\x89\x2d\x1e\xa7\x60\x69\x87\x10\x53\xeb\xff\xa8\x42\xed\xf2\x47\xa0\x77\x88\x38\xa9\xfb\x36\xa5\x79\xc7\x8d\x05\xba\xd3\x90\x5c\x5f\x4f\xa0\x0d\x9c\x13\x5b\x85\x8d\xb5\xa5\x6b\x27\x6a\x31\xe0\x9e\xf2\xdd\xe2\x30\xb5\xe7\xeb\x19\x09\xc0\xa6\x34\x1c\x7f\x9b\xdc\x55\x85\x68\x96\x1c\xdb\x0f\xd4\x7a\x7e\x53\x54\xa7\xe1\x1c\x2c\x80\xd8\xbf\x7d\xfd\x80\xb8\x91\xe1\x27\xe3\x26\x91\xee\xdc\xfe\xb1\x7e\x1c\xad\x45\xd7\x23\x49\x22\xc4\x6c\xb7\xce\xd1\xe6\x24\xef\x87\x94\xe7\xb3\xab\x96\x27\x46\x20\x82\xe5\x55\xe4\x27\x5b\xb6\x36\x45\x7b\xf0\x34\xa0\xb8\x93\xe3\x90\x6c\xc5\x4b\x37\x08\x69\xa0\x91\x51\xb5\x02\x55\xb6\x67\xd4\x75\xc7\xff\x67\x78\x1a\x0a\xb4\x8f\x9a\x53\x9e\x1d\x2f\xee\x28\xed\x46\x75\x97\x61\x92\xe0\xda\x46\xc1\xba\x89\x90\x1a\xa3\xbd\x71\xe3\x36\x79\xf4\x1d\x5c\xb3\x20\x56\xe8\xc8\x74\x62\xc1\xa3\x10\x2b\x17\x01\x8f\xfd\x46\x03\x8d\xb1\x99\xf2\x71\xec\x9e\x8b\x38\x88\x9d\x98\xc3\x9d\x78\xbf\x83\xba\x16\x7b\xa8\xbf\x62\x9e\xe8\xcb\x00\x7c\xc0\x25\xb5\x62\xd1\x03\x20\xe7\x88\x0a\x6a\x12\x07\xe2\x52\x19\xcc\x3d\xdf\x66\xfb\xf2\x57\x70\x67\xc3\xa5\xd1\xb1\xea\x9c\xfe\x13\x2c\x8a\xf3\x64\xa8\x54\x62\xab\xe4\x6d\xf0\x06\x4f\xe4\xab\x53\x55\xd8\x47\x99\xac\x0b\x4d\xec\xba\xa8\x6d\xcc\x15\x17\xd8\x74\xe8\x75\x90\x20\xba\x03\x71\x1b\x0b\xad\xd7\x83\xfa\xc3\xff\xe3\xbf\xfe\xce\xa1\xc4\x33\xef\xe9\x8f\xc7\x1e\xc6\x6f\xb8\x8e\x5c\x3c\xdb\x52\xf0\x1c\xc3\xe9\x03\xc5\x29\xaa\xb9\xad\x46\x59\x8e\xee\xea\xd8\x85\x02\x8f\x50\xe8\xf9\x00\x11\x87\x24\xc2\xe3\x74\xbb\x5c\x0e\xc2\x7b\x1c\x74\xaa\x2d\xd4\xea\xfd\xab\xe3\x7e\x1c\xe8\x79\x18\x6e\xb4\x76\xf2\x29\xcd\x5d\xa9\xb3\x5e\xb8\xd9\x24\x24\x8a\xa9\x17\xe1\x72\xc4\xd1\x48\xf7\xe1\x9a\x83\x54\x61\x89\xe0\x76\xbb\xfc\x2b\xdc\xea\x1f\xfe\x3b\xbb\xd9\x27\x81\xd4\x18\xf1\xde\xbd\x96\x88\x5c\x98\xc1\x48\x26\x81\x8a\x64\x3a\x60\x29\x98\x1f\x99\x84\x06\xa1\x2d\xfb\x5b\xdf\xad\x3d\x84\x36\xa1\x21\xf1\xfc\x67\xf7\xf0\xde\xdc\x97\x1a\xc6\x16\x68\x42\xa3\x08\x0d\x6e\xa7\xf9\x57\x95\xfb\x6a\x86\xef\xab\xeb\xac\x78\x6b\x47\x7c\xfb\xf7\xbf\x0f\xfe\x27\x18\x4f\x28\x74\xea\x6e\xad\xd7\xfb\x33\xab\x9f\xb7\xd6\xab\x9d\xbc\x0a\xe3\x09\x43\x5a\xe6\x1a\x77\xe5\xf9\x13\x30\x61\x86\x62\x79\xcf\x73\x56\xb7\xe7\xd4\xd3\x14\xb5\x94\x84\x9c\xda\x58\x55\x59\xd4\xa0\x4e\xe8\x7f\x80\x68\x9e\xfd\x8a\x4f\x42\x23\xd1\xfe\xf6\xb1\xbb\x99\x60\x80\x4f\x9e\x27\x11\xa3\xd0\xd9\x8e\xd7\x20\x74\xde\x89\xc7\x99\x24\x0a\xb5\x0c\x7a\x31\x37\x3f\x63\xaf\x4f\xed\xba\x1e\x2c\x27\xdf\x9d\x0b\x0c\x20\xa3\x81\xb0\xad\x84\x1e\x20\x84\xd8\xbf\x06\x3b\x48\x10\xfd\xab\x13\xdb\xa2\xff\xea\x2d\xf8\xcb\xff\xe1\xee\x1c\x53\x89\xa5\x33\xab\xed\xb7\x9d\x7f\xab\xc9\x8f\xf3\x50\xe0\x1c\xcf\xea\x11\x26\x6d\x32\xb8\x5c\x31\xb4\x61\xac\xf0\x99\x93\xde\x98\x76\xb1\xec\xa3\x19\x6e\xc7\x8d\x25\xe0\x1f\xea\x5c\x8e\x67\x50\x4a\x39\xd6\x4a\x7f\x85\xe6\x09\x44\x3e\x62\xa4\x39\x0d\xb6\xd7\x24\xe5\xa9\x57\x1a\x31\x59\x75\xc0\x4f\xe6\x07\x3a\x4d\x63\xe3\x14\x23\x1f\x47\x2a\x48\x93\x97\x4c\x53\x2b\x93\x78\xcc\xc5\xb9\x2f\xf2\x30\x89\x48\x42\x44\x1c\xf7\x84\xe1\x16\x06\x7a\x31\x0c\xbd\x63\xd4\x1d\xc7\x89\x30\xcc\xa9\x1b\x36\xad\x09\x15\x45\x91\xbf\xad\x24\xa0\x7a\xfa\xf2\xa7\x72\x80\xcf\x1d\x3f\x97\xe4\x91\x95\xc3\xb7\x64\x24\x8b\x42\x3f\x81\x3e\xa1\xcd\x33\xd9\x95\x13\x99\x06\xd4\x9f\xec\x18\x77\xba\x13\xea\xb9\x9d\x73\xe3\xaf\xa0\x82\xd4\x55\x3c\xb7\xa7\xda\x22\x1f\xf2\xde\x9b\x44\x47\xc2\xd2\x53\x22\xc1\x79\xeb\x4e\xd4\x8d\x38\x0c\x75\xad\x4d\xa2\xb9\x95\xfa\x46\xc9\xb7\xac\x68\xd6\x88\x5e\x30\x59\x5f\x9b\x34\x7a\x2e\x9d\x26\x08\x5e\xda\x8b\x03\xac\x0a\xfd\x98\x8b\xf3\x7d\xd9\xdd\x2b\x35\x6c\x50\xba\xda\x9a\x40\x22\x2b\xea\xf9\x60\x72\x02\x2a\xec\x19\x05\xbf\x0a\x4b\x55\xf1\x21\xa7\xe0\xfc\x88\x1a\x66\xa5\xee\x77\x46\xe4\xb9\x14\x9e\x81\xd8\x24\xc6\x89\x6d\x39\x52\x2c\x0b\xfa\xbd\xfc\xce\x93\xe4\xe1\xe0\x73\x1b\x43\x2d\x29\xe9\xa9\x70\x5c\xb8\xf3\x1f\x35\x25\xb1\x32\x6c\x40\xac\x36\xef\x38\xa6\x81\x4c\x91\x88\xeb\x7b\x51\x5b\x5a\x54\x73\xca\x17\x4d\x03\x87\xe3\x64\x5c\xd2\x40\x45\x46\xf7\x91\xb6\xaa\x5e\x3e\x97\x5d\xf1\xb4\x49\x03\x70\xa1\x73\x14\xe7\x1f\x72\x81\x9a\x94\x12\xab\xc0\xa8\xcb\xb7\x62\x9b\x4d\xd7\x6c\x4a\x45\x9c\x3a\x2a\x1b\xe7\x07\x8a\x09\x12\x2a\x65\x4c\x46\xc3\x84\x86\x9d\x4f\x93\x3e\x22\xb6\xc8\x55\xd1\xb4\xf6\xa4\x0b\x57\x44\xe3\x15\x9f\x32\x61\x69\xb5\x85\xfe\xf7\xa9\xb6\x55\xae\x57\xad\xdb\xfb\x50\x0c\xfc\xda\x94\x09\x83\x31\xf5\xcd\x73\x76\xc4\x58\xc6\x00\x73\x3e\xfa\xaf\xff\x42\xc3\xf4\xc5\x38\x7e\xf1\x41\xdb\xe8\xc2\x29\xbb\x8d\x49\x19\x30\x0c\xbe\x7d\x2b\xcb\x97\x59\x26\x8d\xc9\xe7\x0e\x83\x80\xfa\x8a\x91\x76\x56\x7c\x3d\x9d\x17\xa7\x6e\x8b\x4a\xc3\xd0\x52\x34\x5a\xca\xaf\x13\x16\xf6\x3e\x37\x5d\x6b\xaa\x4d\xda\xef\xbe\x98\xbf\x76\x4d\x71\x94\x60\x08\x4e\x9d\xea\xa6\xd4\x99\x28\x7e\x40\x95\x99\xf3\x64\xe8\x93\x84\x85\x81\xab\xd1\xbe\xcd\x8a\x97\x2f\x73\x10\x21\xdf\x37\x25\x56\xb4\xd5\x73\x42\x99\x34\x51\x16\xcc\xe9\x49\xee\xaf\xce\x48\xc2\x37\x7f\x90\xa7\x89\x71\x90\x0b\xa7\x66\x64\x0b\x24\xc6\x0f\x94\x0a\x46\x79\x17\x24\xff\x2f\x3c\x8a\xaa\x29\xa0\x1a\xd8\x7b\xa9\x60\x26\x75\xd4\x06\xcf\xe8\x7f\x8c\x9e\x52\x44\x81\x8a\x7b\x49\x2d\x44\x86\x8d\xc8\xb4\x27\x50\xc8\x54\xa4\x81\x76\x51\xfc\xeb\x4a\xbc\x41\x75\xb1\xff\xa7\xc2\x00\x3a\x57\xa7\xa2\x67\x42\xff\x60\xf5\xca\x20\xb5\x8a\x4b\xab\xcd\xea\xe9\xc7\x6a\xb7\xb8\x7b\xf8\xee\x95\x22\xdb\x56\x05\x43\x1a\x46\x8c\xb3\xd7\xbb\xa6\xdc\x39\xae\x88\xae\x63\x6c\xc5\x43\x64\xa6\x57\x77\x0f\xf7\xdb\xbb\xce\xea\x4c\xa5\x54\xb8\x45\x9d\x0a\x29\x0a\x87\x83\x9a\x4a\xa7\x99\x54\x45\xc0\x5d\x5a\x00\x33\xaa\x16\x68\x3c\x36\xc3\x52\x25\x13\x0c\x04\x3a\x3e\xef\x47\xcb\xf0\xf9\xd1\xab\x29\x99\x7a\xc9\xc3\xf6\xdb\x65\x15\xe8\xcd\x10\xc2\xed\xba\x69\xa3\x51\x99\xf8\xa6\x2c\xad\xe9\xb8\x72\xc0\x88\xd5\xeb\x20\xb6\x38\x7b\x32\x4e\x7e\x10\x20\xc1\x34\xee\xee\x54\x20\xea\x60\x32\x55\xc0\x68\xdc\xef\x77\xe2\x98\xed\x1e\x91\x10\xb9\x73\xd1\x52\xc3\x2c\x0c\xe5\x6a\xbb\xfc\xb1\x7a\xfa\xb1\xf6\x55\x87\x26\x6d\x7d\x58\xcb\x34\x5c\xbc\xfc\xfc\x88\xc3\xd6\xa4\x46\x25\x98\x61\xfa\xfe\x6d\xe9\xae\x14\x24\x50\xe8\xd9\x0c\xb8\xbf\x30\xad\x17\x76\x1d\x98\xc0\xc3\x4c\x97\x37\x22\xcb\xb3\x62\x3f\x71\x36\x04\x31\xee\xb4\x83\xe6\x7b\x56\x34\x16\xaa\xdf\x71\x30\x7e\xba\x51\x88\x80\x0a\xe4\x76\x44\x93\x71\x55\x68\x6f\x77\x8a\x80\x73\xb4\x02\x7e\x66\x79\x7e\x1e\xf8\x27\x22\xd0\xb1\xb2\x55\x90\x59\x61\x0f\xc1\x17\x28\x1c\x22\xdf\x75\xa1\x84\x0a\x0f\xb7\x29\x73\xf8\xe0\x68\x15\xd4\x15\xcd\x5a\xc4\x35\xe6\x2a\xc6\xc3\x25\x68\xca\xb4\xab\xa5\xb6\x3c\xfc\xfe\x17\x58\xc0\x1d\x1d\xae\x7b\x80\x7a\xec\x28\x0b\xc6\x6c\xc9\x92\x7a\x7e\xb1\x6a\x00\x57\xf3\xf3\x4f\x30\x11\xe1\x31\xb1\x81\x46\x67\xaf\x37\x03\xa1\xbd\x49\x3f\x0d\xb8\x3f\x38\x04\x52\x0d\xd5\x6d\xa6\xa0\xa8\x61\x02\xed\x71\xdd\x43\x22\x31\xe6\xf1\xfd\x7e\xbd\xb5\x72\x8a\xfe\xc9\xc2\xc0\x32\x78\xec\x06\xac\x32\xf6\x11\xc7\xa4\x32\xe3\x93\x59\x84\x8c\x2b\xe2\x72\x9d\x57\x42\xbd\xdc\x94\x95\xdb\xeb\x9e\x44\xa1\xcb\xc3\x78\x11\x8a\x28\x26\x92\x0c\xf6\x84\x6d\xb9\x5e\x2e\x1e\x97\x22\xcf\x3b\x25\x36\x23\x22\x20\xa2\x2b\x63\x41\x89\xfc\xc9\x4b\x47\x10\xa1\xa9\xae\x41\x79\x1c\xc6\x05\x48\x67\x32\x9e\x91\x09\xa3\x9e\xba\xf6\x1a\x54\x76\x10\xf9\xf4\xbb\xc6\x84\x30\x9f\x85\xc7\xbc\xac\x5d\xd2\xef\x53\x7e\x8a\xb6\xa7\x45\x30\xed\xa1\xb9\x2e\xd5\xa2\x46\x80\x40\x1c\x4e\xef\xa7\xac\x29\x6d\x09\xbd\x9d\xdc\x82\x7f\x4b\x4e\x25\x9a\xc4\xcb\xac\xd0\x0e\x48\xdf\x35\x09\x8a\x54\x9b\xd6\x63\x5c\x54\x4d\x56\x37\xb5\x87\x81\xcf\x5a\x48\x22\x25\x14\x13\xf2\x59\xbd\x38\x35\xe5\x4d\xd9\x1a\xd3\x1d\x05\x8b\x11\x29\x8b\x71\xde\x59\x46\x9a\x21\xca\xd0\x77\x48\x93\x98\x78\x2a\xd3\x17\x70\xda\x28\xf3\xdf\x3c\x15\x09\x66\xcb\x1a\x4f\x8f\x96\x7b\xd1\x10\x23\x52\x13\x20\xac\xb5\x29\x5b\x4f\xe5\x4b\xcf\x7a\x63\x84\x10\x71\xe4\x82\x44\xab\x42\xaf\x55\xe9\xf4\x44\xc7\x63\xd6\xee\x46\x29\xc2\x29\x30\x8a\x6a\x25\x10\xfd\xdd\x25\x95\x36\x47\x56\xb4\xdb\x6b\x59\x65\x50\x3f\x98\xeb\x81\x74\xfe\xd4\x80\xf1\x47\x84\x90\x9c\xe2\xf4\x5e\x15\x4d\x05\xc7\x0a\x0a\x38\x55\x9b\xe7\xf2\xd8\xdd\x19\x12\xd4\xb5\x5c\x2e\x6e\x6f\x7f\x19\x68\x12\x2a\x01\xc4\x7c\x54\xa2\x18\xe9\xa2\x78\x97\x57\x28\xb0\x72\x5a\xfd\x11\x3a\x55\xb6\xbe\xb0\x18\x04\x48\xe3\xe1\xad\xd7\x59\x7d\x6c\x1d\xdc\x5e\xad\x7a\xfc\x05\x8c\x93\xc4\x58\x9c\x74\xd6\x6c\x84\x81\xaf\x27\x51\x39\x53\x92\x12\xdf\x29\xe5\x08\x81\x39\xf6\x34\x4e\xc3\x59\x26\x49\x64\xb3\x31\x0d\x88\xc3\xf6\xad\xfd\x1a\x26\x7b\xef\x1a\xb5\xc4\x29\x58\xe1\x2a\x66\xfe\xcf\x41\x62\x0b\xee\x1c\x3f\xb6\x4d\x3a\x8c\xb6\x38\x49\x09\x43\x32\xa6\xdb\x93\x7a\x19\xa6\xca\x25\x73\x26\x55\xbb\xc1\xd4\x1b\x50\x65\xa1\xd1\xb0\x5d\x15\x1a\xf4\xd5\x79\x60\xd8\x4a\x26\x12\xa4\x06\xb1\x09\x9b\x49\x3d\xaf\x64\xc2\x1e\xf7\x9b\xc7\xd5\x72\xbd\xb8\x5d\x6f\xb6\xbb\x87\x7b\xbf\xae\x64\xc8\xa5\x1c\x70\xa3\x74\xe4\x62\x58\x04\xee\xfb\x68\x0a\x0e\x25\x70\xe7\xff\x16\x25\x3a\x48\x3c\x3f\x78\xa6\xe0\xa1\x80\xf1\x44\x18\x3f\x44\x9c\x24\xc2\x07\xc8\x3b\x0b\x56\xc6\x32\x45\x3c\xf5\x61\xf7\x2c\x2a\xdd\x09\x18\x1a\xc9\x21\x44\x42\x26\xa8\x4e\x28\x73\xb6\x7d\xae\xa0\x7e\xee\x78\x7b\x8d\x4c\x23\x40\xec\x4e\x5e\xee\x6d\xbd\xeb\x0c\x35\xf2\x68\x2f\x95\x29\x57\x78\xea\xe3\x32\xec\xe2\x26\x3e\xe5\xe0\x3a\x09\x08\x63\x3c\x16\x41\x67\xa7\xc3\x20\xa3\x27\x65\xaa\x43\x27\xb8\x18\x0c\xc8\x6f\x8c\x54\x21\x20\x2e\xf6\xe1\xe7\xfd\xea\xa9\x17\xd6\x33\x52\xe9\x00\xcf\x9a\xe5\xd3\xc3\xcf\xeb\xdd\xcf\xc5\x8f\x15\x1b\xb2\xa6\xb6\x1d\x52\xaf\xe9\x8b\x40\x89\x32\xcf\xc5\x8e\x90\xa0\xfd\xbf\xb9\xa2\x68\xa9\x99\xb4\x7a\xb3\x59\x71\xeb\xd9\xf2\x8d\xd4\x09\x41\x6d\xbe\xe5\x62\xfb\x84\xae\x39\xe8\x9b\xb2\xfa\x09\xd9\xfc\xde\x2e\xb5\x10\xc4\x96\x10\xae\x0b\x54\xd2\xb9\xc9\xf2\x8b\x32\x15\xa9\xb5\xb1\xd5\xea\xe5\x7e\x9f\xc3\x0d\x3a\x80\x6e\x69\xe6\x62\xdf\xfd\x36\x44\xaa\x17\xda\xd9\x96\xc7\x4c\x75\x03\x03\x22\x46\xff\x61\xb3\x5a\x8e\x16\x12\xa8\x04\xdd\xe5\xed\x33\x7c\xad\xba\xf4\xbd\x34\x5a\xa3\xc3\x78\x5f\x36\x65\x01\xfb\xb2\xf2\xae\xbe\x22\x81\xf2\x02\x35\x37\x98\x43\x19\xcc\x7d\x45\x64\x84\x7b\xcb\xb2\x3a\x1f\x9b\x92\x04\xa4\x6f\x30\x94\x0f\xca\x9d\x07\xee\xc0\x4c\x9a\xad\xed\x1e\xb2\x0e\x5c\x8c\x19\x85\x11\xc0\x66\x34\x86\x8a\x38\xcc\xd7\x48\x30\x20\xa0\x23\x77\x43\x05\xdc\x24\x36\xda\xad\xad\x69\x30\xe3\x1d\x24\xf3\xbb\x9b\xa2\xa1\xf4\x14\x9d\x4f\x1d\xd5\x42\xd2\x35\x02\xd3\x9d\xba\x83\x55\x1a\xb3\x69\xda\x2f\x93\xbb\x28\x57\x0e\xf3\x75\xd5\x49\x51\x1b\x45\x4d\x84\x31\x5e\x8c\x21\xae\x0e\xc7\xbc\x3c\x03\xdc\x65\xfb\xea\x63\x5d\x3b\xa3\x58\x1c\x48\xe5\x97\xcf\x4d\x85\x2a\x74\xbe\x49\x50\xa1\x7b\xc2\x80\x5d\x93\x41\x85\x24\xdb\x63\x2a\x0b\xc5\xda\x5d\xa0\xdd\x0d\xa1\x52\xf3\xdb\x84\x62\x8a\x05\xc6\x45\xfa\x3c\x49\xdf\xa8\x9e\x4b\x85\x09\x89\xbc\xa0\xbe\x43\xa1\xfa\x16\x91\x22\x58\xe2\x51\x34\xcf\x18\xf3\x1b\x9c\x34\x7e\x17\x50\x31\xb7\x19\x36\xdc\xb3\x1e\xa1\x5a\x0a\xd3\x4d\xa5\xd8\x00\x1e\x13\x77\xe2\x2c\xdb\xb6\x51\x25\x90\xeb\xc3\x23\x89\x7e\xc7\xe6\x2d\xab\xeb\x6d\x75\x1a\x13\x2f\x28\x9e\x72\xac\xda\xcd\x45\x8d\xc2\xc9\xb9\xe5\x9d\xf4\xad\x2a\xc4\x28\xf0\x63\x55\xae\x97\x0f\x03\x9a\x3a\xa3\x92\x20\x8d\x58\x97\xbe\xfc\xfa\x49\xea\x6c\x46\x1c\xdd\xa8\x84\x25\x84\xfa\xc0\x50\x23\xf2\x9f\x90\x6d\xcb\x2b\xb8\xee\x48\x9f\x26\x11\x6b\x95\x24\x01\x2e\xce\x9f\x13\x9e\x10\x87\x09\x1f\x6f\x06\x2a\x31\x12\x1d\xe7\x3b\xa8\x5e\x72\x58\xd8\xb2\xaf\x8f\xeb\x09\xe7\xd7\x8c\x60\x11\xc2\x35\xfe\x7e\x12\x23\x3a\x00\x25\x54\x14\x3a\xb7\xbc\x5d\x47\xb8\xeb\x8e\xf6\x6e\x25\x89\x46\x68\x0e\x4a\xdb\x7c\x19\xac\x04\x45\x22\xe5\x10\x59\x4f\xa0\xb3\x0a\x54\x33\xb0\x1c\x7c\xa7\x80\x62\x61\xa5\x6e\x0d\x29\xff\xa3\x2a\x89\x31\x38\xbd\xb9\x7b\xbc\xdd\x6e\xb6\xa3\x07\x52\xa0\x71\x70\x70\xe7\x46\xcd\xaf\xaf\x8b\x8d\xb5\x4a\xd7\xf7\xbb\x9f\xab\xf5\xee\x6e\xf1\x87\xef\xac\xa3\xd8\x9a\xca\xf8\xe5\xb6\x59\x0e\x97\x11\x85\xe1\x7f\xdd\xb8\xb8\x76\x27\x37\x1b\x87\x7f\x9b\x49\x93\x2b\x1d\x47\xb1\x03\x89\xf7\xb1\xd2\x9b\xaa\x3c\x6c\x40\x35\x1d\x27\xd9\x78\x98\x81\x6a\x4c\x40\x3e\x96\xde\x39\x55\x00\x21\xde\xe6\xfa\x54\xec\xa1\x2c\x9e\x4e\xc5\x22\x3f\x3e\x7b\xf0\xaf\x32\xd4\x60\xd4\x40\x8d\xb5\xce\x7d\xab\xd0\xb1\x3b\xfc\x7f\x2b\x65\x17\x07\x18\x7d\x20\x4d\x38\x24\xa4\x47\x1a\x16\xfb\x9f\xc2\x22\xc3\x1e\x8c\x8b\x2e\x8c\x3e\x89\x26\xa9\x74\xa8\x2a\xa1\xab\xd3\xb1\x13\xae\x32\x9a\x88\x04\x11\x82\xb7\x59\xdd\x64\xc5\x7e\x89\xf1\xa0\x1c\xe6\xb5\xf8\x8c\x26\xc6\xc2\xb9\x51\xb5\xc1\x79\x29\xc3\x4d\x58\x53\x02\x98\x3b\xb8\x7d\x58\xfe\x3e\x0a\xb8\x68\xca\xb8\x97\x21\xdf\xbe\x4f\x4a\x33\x34\x65\x1a\xa1\xab\x16\xfb\x1a\xec\x6e\xd6\xf7\xeb\xcd\xb7\xee\x52\x1d\x61\xb8\xe3\xe1\x98\x15\xad\x75\x32\x98\x3c\x9a\x19\x8e\x80\x8f\x5d\x56\x2f\xcb\xaa\x9d\x91\x7f\x3f\x89\xaa\x81\xea\xea\x74\xce\xa6\x3f\x13\x52\xa3\x5d\x94\x74\x99\x97\xa7\x89\x75\xfc\xb7\xcb\x89\xe4\xae\x8b\x02\x61\x11\x78\xe8\xf2\x0c\xd8\x27\x8d\x8e\x83\x0e\x99\x8b\x76\xca\x6a\xbf\x1f\xd2\x69\x1a\x1d\xcb\x98\xf0\x6e\xc2\x3a\xf7\x73\x51\x3f\xa2\x4c\x56\x9f\x5b\xee\xff\xbf\x0e\xd9\x32\x1f\xc9\x76\xb7\xe5\x92\x06\xe0\xe8\x9b\x45\x71\x5e\x8a\x63\xd6\x53\x45\x68\x2e\x53\xb4\xd7\x5a\x77\x32\x9f\x22\x8e\x34\x97\x06\x4d\x98\x62\xa2\xdc\x69\x34\xd7\x21\xa6\xca\x6f\x44\xe5\x76\x0d\x24\x20\x73\xad\x09\x25\x9e\x2e\x75\xa3\xca\xaa\xbb\x5f\x12\x05\x11\x74\xdb\xe1\xe9\x80\x86\xf3\xc4\x2b\xd0\x89\x4a\x70\xda\x63\x7e\xb6\x7c\x9f\x57\xce\x34\x3a\x31\x7a\xa0\xe7\x33\xb7\xe9\x8d\xfb\xa7\x34\xd2\x2e\x77\xd3\x2b\xa8\x79\xc1\xe4\x4f\x4d\x54\x9d\x26\x36\x1b\x5d\x79\xb5\x59\xbf\x08\xb5\xa0\x1a\x63\x31\xff\x16\xea\xe5\xb1\x6c\x96\xdd\xdf\xa3\x10\xfd\xd0\x3f\xaf\x47\x3b\x98\x16\x2a\x46\xcc\xf2\x7f\x2e\xa4\x20\x8c\x96\x24\xe5\xa4\x53\x3c\xb7\x41\x59\xdf\xa4\x43\x04\x37\x54\xb6\xbc\xea\x63\x12\x5f\xa3\x15\x4b\x90\xaa\xde\xce\xc0\x6d\xae\xb6\xf9\x38\xb6\x3b\x9e\xb0\x4a\xdb\x72\xf0\xa7\xc5\x3f\x56\xbe\xd0\x51\xeb\x50\x5b\xba\x7b\x7b\xa0\xe0\x59\x79\x81\x42\xfa\x90\x11\xd4\x68\x48\x62\xaf\x79\xf1\x4d\xd4\xcf\x17\xc5\xad\xbe\x9b\x34\xbe\xb8\xe1\x03\xda\x09\x6d\x04\x60\x97\xdd\xb1\x02\x57\x5f\x0c\x1d\x56\xfa\x53\xa4\xb7\x36\x32\xf1\x0a\x70\x3f\xa0\xd0\x65\x75\x59\x05\xd9\x9b\x99\x40\x08\x47\x9a\xe4\x5d\x8f\x33\xea\xd8\x06\x26\xd4\x65\x89\xbf\x04\x18\xb3\xf8\x2b\xcf\x65\x62\x79\xa9\x6f\xc1\xf8\x65\x02\x01\x05\x3e\x4c\xa5\xfc\xac\xca\x62\x3f\x4c\xae\x8f\x1f\x1a\x82\xd0\x52\x9f\xa8\x1c\xc4\x07\x16\x1f\x04\xdc\x65\x1f\xac\xee\x78\x93\xe5\xf9\xba\xb0\xf8\xba\xee\x67\x93\x30\x60\xfe\x5c\x9e\x17\xca\x9d\x9d\x3d\x10\xe8\x50\x75\xf4\x4e\xca\x22\xfb\xd8\x1c\xe1\x9e\x01\xaa\x80\x74\x65\xac\x39\x8a\xf7\xcc\x94\xff\x00\x4b\x04\xc2\x76\x8e\x48\xab\xfe\x13\x21\xfd\x17\x19\xbd\xcb\x39\x04\x21\xa7\x44\xf5\x7e\x0e\x20\x65\x87\x9e\x7f\x94\x38\x95\x18\x8e\xb3\x42\x5b\x17\x4a\x13\x1f\x25\xfc\x86\xbb\x2f\x70\x12\x7a\x60\x73\x4f\x30\x70\x53\x56\xdb\xf3\x71\x9c\xad\x80\x84\x48\x5c\xc3\x05\xbc\x2d\x0f\xa2\x9e\x7f\xa4\x44\x58\x20\x9d\x9f\x4e\xae\x10\xc4\x86\x61\xe7\xc7\x3e\x91\x71\x64\x4b\x77\x4f\x45\x53\x65\x50\x0f\xeb\xa0\x21\x0d\x6d\x98\xe3\xe1\xf7\xd5\x70\x47\x81\x34\x91\x10\x0c\x69\x2d\xd6\x17\x47\xf2\xd0\xbc\xe9\x7f\x2e\x55\x1c\x0d\xad\x3f\xd6\x5b\xbf\x6d\x81\x4a\x03\xe5\x9c\x69\x14\x65\xca\x7b\xfc\x15\x68\x1e\x63\x40\xa4\x29\x37\x79\x6b\x20\x8f\x5e\xd7\x10\x6e\x05\xc5\x55\x49\x1d\xd3\xb8\x1e\x52\x12\x81\x21\x40\xad\xa2\xdf\xd3\xef\xab\xed\xfa\xfe\xeb\xae\x1e\xf2\x03\x19\xc2\x12\x88\x1d\xdb\xde\x4d\x59\x3d\x74\x7a\xc4\xf3\x83\x65\x48\x6c\xd0\x48\xb0\x2c\x86\xd6\x1a\xb1\x00\xf3\xa1\x6c\xa8\xeb\x1c\xc4\x96\xfe\xba\x29\x37\xd9\x7e\x88\x00\x37\x01\xe7\xa8\x88\x65\x77\xcb\x99\xe2\xe6\xc1\x54\x36\x01\x10\xdd\x69\xcc\xd9\xd8\x78\xff\x86\x26\x30\x81\x0b\x35\x35\xe0\x03\x4d\x86\x06\x16\x5f\x92\x1d\x1e\x3c\x99\x63\xfb\x47\x15\x47\xa3\xf2\x8f\x55\xa1\xcb\xb7\x03\x4c\x31\xaf\x86\x32\x86\x97\x63\xe5\xf5\x0c\x93\x9b\x61\x82\x24\xbd\xc4\xdc\xcd\xe2\xf1\x83\xe1\x0a\xe3\xae\x52\xc7\x2a\xdf\xe1\xce\x30\x39\xd4\x4d\x28\x93\x30\x1d\x82\xfb\x2f\x99\x1c\x4c\xa8\x24\x12\x47\x6d\xbe\xad\x1f\x77\x9b\xdb\x87\xad\x0f\x9b\x98\x88\x73\x16\x0f\xc5\x7d\x6b\xb4\x88\x71\x9a\xcc\xb8\x23\xfe\x18\x30\x91\x36\x86\xfa\xd2\x07\xd0\x99\x25\xaf\x1c\x4e\x2f\x13\x81\x45\xd7\x68\xa8\x46\xda\x2e\xc6\xc4\x92\x41\xe2\x55\x10\x9e\x84\xfa\x00\x05\x6d\x78\xa8\x62\x3d\xd0\xb8\x72\xa5\xba\xfe\x36\xbc\x3d\x61\xed\x72\x55\x2f\x1b\xc8\x7f\xc1\xf0\x67\xb8\x11\xc8\x4a\xf0\xb5\xd4\xff\x6d\x0d\x9f\xf6\xdf\x51\x9a\x7c\x1e\xc6\x65\x12\x65\xa5\x84\xd6\x2f\xa7\x4a\xb8\x02\xa8\xce\x53\x36\xa9\xb4\x6a\xdc\x56\x6d\xf4\xfe\x72\x22\xa7\x90\x5a\x30\x6c\x79\x7c\x38\x36\x43\xea\xb1\xc9\xf3\xa5\x26\x24\xe8\x0e\x23\xc1\x80\x03\x54\x7c\xd0\x57\xc6\x14\xd3\xef\x7a\xa1\x2f\xb8\x3a\xbb\x2e\x9c\xda\xf4\x8c\xc8\xb3\xc3\xc1\x96\x3f\x4e\xba\xb4\x5b\xde\xff\xfb\xff\xfe\xdf\x62\x79\x3f\x0a\x2b\x19\x69\xa2\x94\x0d\xd1\x04\xef\xea\x22\x12\x6c\x14\x89\xd1\xf6\x29\x8f\x50\xb8\x1a\x2b\xdf\x22\x52\x44\x82\x39\x45\x76\xa7\xe3\x3a\x7e\x03\x25\x05\x66\xd3\xac\x29\x78\x0f\x6f\x77\x59\x81\x10\xe1\x61\x71\xb8\xef\xab\x00\x79\x60\x76\xa7\xe2\x28\xd4\x4b\x3b\x65\x2e\x74\x95\x8d\xd1\x44\x63\x6a\xcc\x31\x2a\xed\x5c\x4d\xca\xce\xe1\x46\x77\x4d\x76\x00\x5b\x4a\xe4\x9f\x13\x58\x8a\x36\x8f\x65\xea\xec\xfe\xaa\x09\x72\x97\x16\x65\xa7\xfe\x6f\x0c\x00\xb5\x15\xd7\x58\xcb\xb1\x6a\x9e\xb7\x65\xaf\x09\xfb\xf3\x9b\x27\x46\x9a\xca\x52\x8d\x35\xb9\x8d\x31\x8c\x99\xd0\x51\xd8\xda\x3c\xed\xdc\xd9\x9e\xf8\xde\x11\xf1\xd8\x56\x07\xe8\xbd\x29\x2b\x9b\x13\xab\xfb\xba\x65\xf7\x43\xfe\x14\x46\x8e\x2a\x17\x2a\xab\x06\x51\x1d\x49\x08\x89\x0c\xa6\x06\x90\x56\xcb\x9d\x6e\x4e\xdd\xae\xeb\xa2\x12\x94\x22\x5f\x17\x59\x73\xd5\xb3\xdf\x7e\x96\x33\x6d\xaf\xd2\x80\x95\x52\x56\x18\x0e\x8d\x9c\x5e\x19\x4e\x12\x12\x04\x0c\x3d\x40\x27\x57\xb8\x2e\xb6\x99\xdb\x0e\xb0\x31\x22\xa9\x3b\x0d\xed\x46\x37\x41\x06\xb4\x7d\x68\x88\x87\x1c\x1c\x4b\xe5\x54\x6e\xda\xbf\x86\x5d\x58\x1f\x51\x9d\xdd\x29\xd1\xb6\x25\xd2\xf4\x59\x37\xfc\x56\x13\x10\x83\x24\x84\xc5\x9a\x75\x01\xb0\xf3\x57\xd1\xc0\x9b\x38\x7f\x39\x0d\x6b\x71\x66\x1c\xb4\xf6\x42\xad\x31\x0c\x02\x85\x6a\x0d\xc3\x91\x21\x24\x09\x09\x09\x47\x91\xf0\xbc\xcc\x87\xce\x7d\xdb\xc2\x2c\x6c\xa5\x86\x46\x74\x64\xf4\xad\x7f\xbe\x6e\xe0\x80\x82\x39\xee\xec\x92\x84\xc4\x24\xf6\x12\x4d\x26\xab\x0e\x9f\x73\x9f\xf9\x6b\x68\x84\xc1\xfe\xdf\x95\xa8\x9f\xfb\x35\xdd\xb6\x48\x9b\x3a\xdb\x09\xad\x71\xdb\x83\xd3\xe1\x03\xb0\x96\xbf\x42\x03\xd1\x1d\x54\x30\x77\x79\xce\x9b\xb2\x5a\x8e\x34\xa9\xdb\x9e\x40\x6d\x6e\xf5\xfd\x79\x2c\xa6\x27\x09\xe1\x44\x20\xc9\x9a\x4b\x96\x42\x01\x26\x53\x99\x18\x14\x80\x8d\x7f\x95\xa7\x01\x4a\xdf\xa0\x20\xe4\x4e\xf9\x1a\xca\x49\xad\xab\x24\x24\x0d\x38\xa2\x45\x90\x80\x63\x85\xfc\x31\x59\x69\xa3\xf0\xe8\x0f\x8f\x07\x26\x55\x11\xbe\xcc\x35\xbc\xbe\x8f\xc6\x45\x10\x8d\x56\x1f\x46\x70\xdb\x17\xfc\x48\x67\xcc\xf7\x4f\xac\xe0\x93\x3c\x5d\x94\xb0\xfd\x05\x65\x58\x77\x13\x19\x50\x96\xf6\x99\xa2\x45\xa1\xa7\x1c\x92\xe3\xf9\x2f\x85\xe5\x36\xba\x16\x99\x2a\x5f\xcb\xb1\x86\xc4\x07\x4c\x3f\x78\x99\x46\x7e\xeb\xac\x0b\x78\xa1\x93\x5a\x9e\x9a\x0b\xe2\x2e\x49\x88\xd2\x1a\xf7\x38\x4b\x95\xb2\x2f\x9d\x9d\x24\x09\xd1\xa1\x42\x9a\xb4\x3a\x2b\xf6\x39\xdc\x66\x05\xa0\x53\xd4\x35\x73\x62\x35\x4a\xcb\x3c\x1f\xd6\x3d\xb7\x4d\x52\xc4\x43\x94\xdd\x70\xdf\x9e\x4c\x5d\x48\x62\x64\xb8\x55\xa2\xd8\x59\x5c\xa4\xbf\x09\xc8\x14\xc5\x3f\x0d\xc0\xd2\x99\xcc\x65\xb7\x7d\x98\x94\x77\xe1\x5a\x10\x87\x47\xa8\x4c\xd6\x2c\x26\xe4\xfd\x92\x04\x44\x27\xe8\xfb\x40\x51\x9f\x2a\x0f\x91\xe8\x2a\x8f\x46\x23\x11\x10\x9d\xe2\x7e\xa5\x44\xb1\x7a\xcf\x9a\xa1\x08\x97\xeb\x11\x50\x30\x74\xa0\x6a\x8e\x2f\xbd\x5c\x6c\xaf\xa1\x6e\x32\xcb\x01\x32\x93\x3f\x6d\x2f\x4c\x05\xb5\x96\x93\xd3\x13\xf7\x7f\x37\x0a\xf7\x66\x5d\x8e\xc2\xe4\x92\x04\x34\x51\x5d\x99\x29\x20\xdc\xc5\xb7\x30\xc9\x30\xc3\xb6\x83\xaa\x2a\x6d\x4c\xcc\xf3\x16\x0d\x67\x5b\xc0\x4c\xcc\x5c\x68\xe7\x3e\x53\x2f\x85\x38\xc0\xd5\x79\xfe\xf1\x98\x11\xa8\xdc\xfa\x9b\xd0\xe8\xf8\xd8\x08\xe4\xfc\xac\x0c\xc2\x28\x44\x2b\xe4\xb5\x52\xfe\x91\x22\x99\x20\x2a\x49\x38\xb6\x83\xad\x78\x81\x45\xfd\x34\x81\x2f\xb5\x1d\x15\x45\xdf\xe8\xe6\xf6\xe1\xe7\x70\x3d\x06\x71\x2c\x31\x06\x80\x02\xe3\x6e\x29\xb6\xef\x72\xf7\xd2\x8d\x55\x6c\x52\x1c\xfc\xed\x73\x56\xf9\x3d\xd4\x53\x86\xb8\x2e\x3c\x30\x22\x1c\xb1\x78\x7c\x85\xc2\x09\x48\xad\x75\xd7\x2b\xb2\xbb\x31\xae\x86\x2e\xe6\xe9\x1b\x15\x41\xdb\xb8\xca\xbb\xb7\xe3\x3a\xc1\xfe\xa2\xae\xa1\x6a\x56\xff\x19\x10\xd5\xcf\x6e\xc7\x41\x42\x88\x49\x86\x56\x0e\x5a\x37\x33\x9a\x7d\xf3\x24\x96\xed\x1d\x02\xc9\x1c\x72\xe8\xee\x6c\x03\xd7\xcd\x79\x5a\xaa\x3e\xfa\xda\x89\xb6\x95\xea\x07\xf1\xbe\x30\x26\xcb\x33\x9f\x93\x95\x24\x48\xa9\x49\xad\xa4\x0d\x86\x4a\x7c\x28\xcd\xb7\x1a\x5b\xa5\xdc\xb4\xe3\x7a\x9d\xd5\xe8\xd5\xfa\x4c\xb2\x24\x81\xe0\x81\xee\xf2\xd4\x16\x36\x1e\x4c\xe6\x8f\x90\x21\xda\xec\xd6\xc4\x98\x44\x7d\x7c\x1f\xa3\x45\x4f\xfd\x7e\x25\x6a\xe8\xe5\x81\xff\xc7\x6a\x15\x49\x02\x49\x18\xce\x97\x21\x2d\xca\xb0\xbc\x77\xe6\x0a\x9a\x7a\x44\x78\x0f\x38\xe9\x48\x1d\x7e\xf1\x6b\x4c\x62\x9d\xcf\xce\x29\x38\x7c\x26\xa6\x3b\x36\x20\xfc\x0d\x92\x84\xbb\x00\x9a\x33\x54\x6f\x4e\xe0\x5d\x76\x49\x02\x15\x13\xc9\x07\xcc\x74\xb3\xde\x82\x24\x81\x66\x1a\x4d\x8c\xd5\xfd\x76\xb4\x7c\x74\x14\x62\x70\xf8\xb1\xcc\xcf\x8b\xec\x57\x4c\x34\x78\x81\xd5\x1d\x3c\xba\x8f\x35\x45\x8b\x04\x93\x03\x3a\xd0\xdc\xf1\xec\x79\x12\xfd\x7a\x5b\xde\x64\x33\x8a\xbb\x9f\xc5\x70\xfa\x17\x81\xc4\xae\xc1\xdf\xca\x6c\x58\x7b\xdb\xb6\x08\x57\xf8\xeb\x14\x11\x1f\x7a\x33\xbd\x6d\x95\x02\x29\xac\xef\xd6\xf7\xbb\xed\xc3\x76\x71\xeb\x30\xa0\xbb\xaf\xab\xed\xce\x13\xa9\x4a\xd2\xba\xf8\x48\xec\x7e\x2a\x32\xd4\xfa\x5a\x39\xc8\x44\xdb\xc4\x02\xcc\xb8\x3f\x8b\x4a\x2b\x71\x5c\x17\x83\x40\xb1\x24\x94\x30\xc3\x3a\x4e\x68\x67\x76\x5f\x39\x5d\x38\x3a\xde\xce\x28\x91\x41\x62\x51\x4e\xaf\x90\x97\xc7\x0e\xa1\xd2\xdd\x4b\x73\x2c\x7f\xda\x79\x9d\xea\xb9\x64\xb8\x24\x34\x50\x02\xb7\xc5\xa7\x93\xec\x31\x86\x92\x50\x9a\x18\x44\x53\x66\xaa\x44\xe3\xcd\x15\x33\xe9\x3b\x87\x39\xf4\xfd\xc2\x90\xa3\xf3\x22\xfb\x2a\xf7\x2e\x39\xd0\x36\x0b\x89\xe9\xe5\xaf\xd6\x7b\xb9\x3e\x35\xea\x79\xaa\x07\xf4\x3f\x7e\xc6\xbf\xb6\x4c\x69\x28\x6d\x25\xce\xd7\x2a\xd3\xe7\xd1\xd0\x44\x01\xc4\xba\x27\x06\xb3\xe9\xfd\x8b\xb0\x64\xdb\x31\xb5\x1c\x2d\x9b\x6f\xeb\xc7\xf1\x1d\x84\xb4\xf5\x25\x0d\x1c\xc9\x53\xbf\xdd\xd1\x48\x29\xa4\x5f\xd5\xae\xf2\xa7\x9e\x7c\xb5\x98\x07\xc8\xaa\x24\xf4\x6b\x56\x97\xd5\xd9\x92\x80\x76\x1c\x80\xfe\x36\x3c\x20\x18\x5b\x7f\x45\x68\xf7\x4d\x96\x8f\xdd\x08\xca\x99\xc6\x78\x9e\xd0\xfa\xc7\xd1\x7c\x98\x6c\xfe\xe0\x5f\xef\x35\xb4\xe7\x3c\x32\xbd\xdb\xad\xc5\x52\xca\xcd\x5b\x96\x43\xcf\x72\x9c\xfa\xf4\xb7\xd2\x9c\x59\xcd\xfe\xce\x56\xf7\x0c\x19\xbe\x07\x80\x55\x0d\xa3\x72\xfc\x32\x29\x4b\xd0\x66\xc4\xac\x05\x66\x34\xda\x7d\xea\xc3\x54\xc2\xe4\x33\xa7\x8a\xaa\xa4\x37\x6c\x77\xa7\xe2\x0d\x2b\x75\x3c\x7c\xe1\x17\x57\xeb\xd4\xcb\x1a\x3f\xe6\xa2\xc9\x8a\xde\x45\x19\xed\x41\x54\x50\xa3\x83\x41\x80\xe2\x16\x0e\xa5\xc3\xcb\xfa\x1e\x9c\x89\x7e\x97\xba\x08\x0d\x0d\x5c\x45\x2a\x0c\x41\x16\x14\x69\x7d\xec\x4d\xef\xb8\x52\x19\xa7\x3a\x76\xe4\x87\x1f\x55\xcc\xb7\xdd\x4c\x88\xa8\x1a\x10\xd5\x6c\x05\x9f\x24\x54\x85\x56\xeb\xc6\x11\xdf\x4c\x67\xa2\x4a\x08\x46\x89\xfc\x0b\x4d\xd0\x89\x92\x50\x2d\x12\x3c\x7c\x75\x26\x0e\x65\xa1\x2f\x8a\x86\xdb\x2e\xd2\x09\x6e\x82\x38\x2c\xbc\x3b\xe3\x5f\x05\x92\x10\xeb\x4f\x8f\x55\xa9\xa0\xae\x37\xd0\x51\x57\xfc\x4a\xcc\x68\xb0\x04\xc1\x30\xc4\x85\x6c\x16\xb7\xab\x60\xb7\xba\xbf\xf6\x77\x37\x01\x20\x21\xb5\x85\xad\x62\xae\x6b\xc6\x36\xa1\x26\x62\xc2\xeb\x55\x2d\xcb\x42\x89\xc6\x91\x6d\xb3\xc0\xaa\x93\xda\x7e\x8c\xb0\x00\x4f\xc1\x9d\xa8\x5f\xfe\xde\x3e\xe3\x50\xf7\x73\x4e\x9b\xc6\x2d\x37\x6f\x78\x31\x12\x26\x38\xbd\xbd\xf0\x46\x96\x43\xdd\xf8\xaa\xe6\xb6\x3d\x62\x98\x3b\xb2\x6b\xcd\x25\xc8\x3f\x3f\xfb\x19\x0d\x34\xee\x26\xff\xf8\xed\xee\x43\xed\xd6\xb6\x5b\x6c\xe5\x22\x6b\x27\xed\x82\x46\xac\x18\x13\x61\x8f\x92\x6b\xfe\x3a\x63\x30\x36\xf4\x06\xd9\x9d\xe5\x06\x1f\xd0\xfb\x4a\xc2\x58\x64\x8c\x1a\x48\x93\xfe\x55\x7b\xc9\x5f\xce\x39\x02\xde\xa0\xd0\xde\x22\x16\xdd\xc1\xc0\x98\x20\x18\x2d\x3c\x8a\xf3\x75\xf6\x5a\x8f\x0d\xb2\xe1\x27\x64\x4c\x58\xde\x4e\xa7\xe4\x39\x3b\xdb\x19\x53\x02\x17\xc4\x6b\xd9\x40\x85\xd5\x0b\xdd\xa7\x0d\x49\x60\x37\x53\x0c\x19\x0e\xf7\x71\x16\x72\x85\x9a\x30\xed\xf7\x3e\x88\x06\x1e\xcb\xa6\xbf\x2c\x0d\x2c\x7d\x5f\x0e\xa2\x3d\xfd\xca\x4a\x77\xc0\x09\xbf\x83\xb2\x30\x4d\x91\x14\x75\xf9\x5c\x96\x35\x5c\xbd\x81\xe8\x2e\xd7\x11\x86\x8a\xac\x8a\xc6\xb5\x5f\x84\xbe\xd5\x30\x4c\xa1\x1d\xce\xb7\xa2\x9d\x9a\x57\x99\xdf\x01\x58\x14\x49\xfc\xe8\xb7\xa7\x6f\xa7\x91\xbb\x3d\xfe\xe8\x71\x68\xeb\xf5\x0f\xe2\x1d\x99\xd6\xbb\x5b\xc7\x42\x62\xe2\xa0\xdd\xa1\x3e\xb3\x16\x5d\x77\x0e\x21\xb2\xb1\xdd\x0d\x0e\x7f\x96\x24\x0c\xf1\x92\x15\x08\xbd\x15\xb5\x55\x81\x04\xfd\x50\x8c\x76\x6e\x96\x12\x86\x05\x68\xed\xef\xb7\x3e\x5e\xf7\x0c\x69\x68\xf1\x66\xba\x2a\x8f\x1d\x05\x6b\xfb\x77\x9e\x44\xd6\x16\x55\x65\xa1\x45\x75\xf6\xeb\xc0\xb5\x4b\x26\x88\x13\x9c\x78\x7c\x78\xb8\xdd\x81\xce\x9a\x5d\xc0\xc6\xbf\xaa\x42\xc9\x3c\xc7\xe3\xa0\xdc\x74\xb0\x6b\x30\x15\x73\xcc\x7e\x66\xc5\x41\xbc\xfb\x9b\x2b\x93\x62\x36\xa8\xc3\x41\xb5\x4f\x37\x97\x75\x96\x84\xe9\x20\x4e\x9d\x26\x04\x2c\x87\x6b\x42\x47\x0a\x53\x09\x8f\x3f\x96\xa3\x25\xe9\x9a\x0d\xb7\x22\xe7\xfb\xec\x15\x4e\xc7\x81\xae\x95\x6d\x0f\x49\x40\x10\x8b\x65\x4e\xb5\x1f\x94\x90\x50\x8d\x6e\xdf\x6d\xf6\x0a\xce\x34\x1a\x57\xd4\xfc\xa5\xe5\x16\x12\xce\x90\xde\xc6\x9b\xd5\x3f\x45\x05\x28\x03\xbb\x39\x8a\x8f\x85\x93\xfc\xc5\x8e\xcc\x54\x9e\xce\x3f\xca\x93\x7a\x1e\xa4\x5f\x7d\x0f\x1d\xe1\xb4\xb4\x08\xdc\xb2\x43\x73\x3c\xa0\xb2\xe0\x2f\xb7\x86\xd1\x30\x85\x41\x28\x7c\xd1\xaa\x4b\x6e\x7d\x15\xb5\x05\xc2\x8c\x7f\x35\xe0\x90\x26\x9e\x72\xec\x47\xd9\x19\x5a\x61\x90\x06\x78\xf2\xec\xf6\xd0\xdc\x37\xcf\xf7\x99\x94\x39\x3c\x98\xb1\xe2\xf4\x60\xb3\x0b\x29\xb3\x98\x39\x9b\x6a\xf2\x8a\x0b\xc3\x89\x15\xd2\x90\x83\x85\xe3\x17\x8d\x50\x65\x36\x42\x7b\xb7\xed\x89\xe5\xb3\xaf\x9f\x45\x05\xf5\x83\xb1\x4a\x60\xf3\x6f\xc8\x98\xc1\x7b\x61\x06\xb3\xac\x9a\x7a\xf5\xb4\x0c\xe2\x68\x3c\x5d\xc2\x30\x12\xe8\x9b\x3d\x3e\xad\xef\x56\xbb\x1f\xab\x0d\x26\x3d\xaf\x17\xdb\x95\xff\xcd\x30\x0e\xd5\x80\x01\xff\xd0\x3f\xf4\xe4\x0b\x86\x49\x92\x84\x83\xca\xfb\x4c\xb9\x80\x64\x40\xfe\x36\x8e\x2f\x0f\x8f\xad\x30\x0a\x88\x6e\x3f\xeb\xfb\x29\x6f\x06\x3b\x63\x18\xa5\x36\xd7\x75\x5b\x8a\xc2\x07\xff\x3e\x2c\xf1\xfa\x6b\x13\x34\xe6\x1a\x06\xc2\xf5\x93\x2f\xcd\x03\xed\x68\x93\xb3\x83\xa8\xce\xbb\xb7\x9e\x98\xa3\x6d\xd5\x1a\x79\x7e\xad\x51\xf7\x0b\x05\xc2\xb6\xbf\xa1\xa1\x67\x33\x19\x26\xb6\x82\xcb\x8e\xd2\x1a\x9f\x65\x39\xf9\xda\x09\x8b\xb8\x76\x68\x50\x8c\xf1\xee\x44\x10\xf5\x8d\x8a\x59\x21\xda\xbc\x14\x1f\xb8\xfd\x61\x12\x85\x28\x83\x75\x9d\xbd\x66\x7a\x36\xb1\x86\x9d\x38\x89\x07\x8a\x80\x3b\x51\x55\xc2\x27\x50\xc2\x34\xe4\xc8\x67\xe4\x90\x9d\x9b\x53\xa6\x32\xdd\x2d\x82\x54\x5b\x51\x57\x47\x46\x05\x79\xbe\x2d\xaf\x72\xa1\x5e\x6c\x56\xe3\x43\x28\x8b\x24\xa1\x08\xac\xcc\xf1\x57\x4c\xb9\xd4\x50\x34\xd7\x08\xc0\x6c\xdd\xea\xf1\x03\x0a\x66\x90\x2f\x7f\x55\xe8\xdb\xb2\x69\xa0\xea\x1e\x4e\x32\x83\xbb\x79\x56\x2f\x7d\x2d\xea\xbc\x85\x12\x2a\xc1\x51\x1d\x11\x4b\x7c\xf4\xa1\x3b\x68\x42\x1d\xc7\x68\x09\x1f\x30\x6f\x77\x2a\xf4\xc8\x02\x09\x81\x87\x18\x77\xfb\x0a\x55\x95\x35\xaa\x3f\xa1\x42\xe0\x2e\x76\x8b\x27\xd3\x52\xd4\x4d\x8e\x62\xf4\x97\x9c\x16\x7d\xd0\x6a\xe4\xb7\x7c\xf6\x8f\xff\x0d\x19\x63\xcc\xbc\x3e\x49\x47\xb7\x37\x6f\x7c\x84\x46\x85\xe8\x8e\xd5\xa7\xe3\x80\x11\xd5\x36\x46\x84\x44\x58\x3c\x81\xd4\x08\x27\x97\xaa\x9b\x42\xd9\x71\xa1\xc6\xa3\xa5\x19\x11\x69\x49\x08\x2c\x5b\xc0\x4d\x79\x2a\x34\x54\xf5\xa2\xd0\xae\x74\xb6\xee\x7e\xc1\x24\xcc\x25\x30\xda\xad\xe6\x23\xfd\x93\xee\x79\xa3\x40\x73\x6a\x1f\x49\x68\x57\xba\x36\xee\x40\x9d\x8c\xb8\xcf\x16\x74\x34\x08\xe3\xfd\x2b\x62\x94\xe1\x2e\xb1\xd3\x50\x37\x55\x79\x9e\xbe\x7b\x48\x22\x2c\x6d\x2c\x36\xd9\xbe\x98\xfc\x46\x18\xda\x30\x4c\x01\x6f\xb7\x2e\x83\x82\xa4\x03\xd3\x6e\x51\xc4\x9c\x88\x55\x6b\x3e\xd6\x9e\xd6\x51\x77\xbf\xc1\x35\x06\x2a\x6c\xb9\xd7\xe6\xb9\x3c\xde\x95\x7a\xe2\xbe\x45\x11\xb7\x0e\xbb\xdb\x1d\x45\x25\x0e\x1f\xf2\xdd\x4f\x06\x2b\x12\x31\xb5\xd4\xff\xcb\xa7\x3f\x1f\xb7\xdf\x56\xd7\x5f\x57\x1f\x17\x4c\xb5\x17\x68\x6b\xfc\xd8\x88\xf4\x63\xff\x51\x7c\xbb\xb1\xdc\x47\x59\xbd\x15\xd5\xbe\xdb\xe3\xa2\x98\xa4\xca\x2a\x07\x64\x0a\xf6\x15\x40\xb1\xaf\xe0\xdc\xb7\x02\x8a\xa4\x62\xf5\x93\x78\xac\xca\x57\x31\x79\xc7\x38\x8a\x31\x12\xde\x1e\x1f\x3b\x16\xec\xae\x57\xcb\x1d\x25\x94\x76\x77\x90\x32\x41\x96\x1d\xd0\x9b\xf2\xfd\x4f\x51\xbc\x00\xd4\xa1\xab\xb9\x90\x24\xe2\x4c\x43\xec\xd1\xb8\xa6\x3d\xdb\xda\x89\x96\x5d\x90\xd7\xb5\x5d\x23\x12\xdb\x6c\xd2\xb4\x21\x09\x9d\x4c\x5d\x53\x41\xd6\x65\x65\x22\x9e\x24\x48\xf5\x82\x48\xa7\x7c\x42\x13\x26\x49\x94\x86\xc4\xc3\x3b\x1e\x8e\x50\x38\x33\xa8\x9b\xe1\xa9\x0a\xf0\x9c\xdc\x91\x5d\x31\x01\x3c\x48\x12\x09\x42\x30\xe0\x76\xbd\xda\xfa\x0b\x44\xc8\xb1\xf6\xfb\x47\xa9\x86\x06\x7f\xa4\x13\x92\xc6\xde\xa5\xa9\x66\x4f\xd2\x08\x58\x4a\x44\xe7\x59\x22\x5e\x63\xee\x33\x83\x24\x96\x59\x36\xab\x6f\x41\x1c\xff\x04\x31\x39\xd2\x22\x23\x12\x66\x0b\xc8\x9a\xaa\x2c\xc4\xbe\x83\xd2\xdc\x94\xd5\x77\x67\x32\x8f\x2c\x90\xc8\x28\xfb\x91\x0f\xce\x5f\xf8\x39\x3c\x04\x23\x03\x26\x6a\x0f\xb5\x75\x5d\x9f\x3e\xca\x16\xc6\x84\x31\x1b\x61\xb2\x43\x38\x24\xf2\xf7\x3b\x4b\x4c\x42\x61\xb9\xbd\x9d\xc3\xf8\xa5\xff\x7b\xea\xc9\x8b\x96\xa2\x68\xae\x1c\x55\x6a\xbd\x2e\x36\x4d\x79\x3c\x82\x1e\x44\xfe\x62\x22\x79\xe2\x10\x4a\x3e\x83\xd4\x9e\x51\x0f\x47\x97\xf5\xb8\x01\xb8\x6e\x9d\x9b\xc5\x64\x57\x8f\x89\xb6\x02\xc9\x1d\x9f\x4e\x9e\x7b\xa0\x4a\x07\xa9\x72\x5d\x83\x14\xf0\x37\x9e\x45\xdd\xe3\x71\xe7\x6d\xf6\x98\x32\xc2\x43\xe4\xbb\x28\xff\x0b\xc5\x50\xf0\xcd\x75\x60\x41\x44\x6d\xf6\x1e\x13\x33\x96\x98\x69\x38\xfe\x71\x28\x25\xfa\x83\xbb\xbc\x29\xc5\x20\x33\x1e\x87\x4a\x60\xc1\x5c\xeb\xe9\xdc\x94\x95\x42\x00\xd9\x6a\xac\xfb\x23\x49\x1c\xf1\x18\x29\x3e\x30\x89\x3c\x0a\x98\x74\x6f\x14\x13\x85\xe5\x3f\x1d\x59\xdb\x38\x4c\x16\xc7\x5c\x61\x02\x07\xc1\xbf\x7d\x95\x49\xdb\xa2\x99\xe4\x03\x1e\x6a\x0f\x28\x9d\x3f\x94\xe2\x58\x2b\xac\x01\xbb\x5b\x3d\xfd\x63\x94\x98\x8f\x63\x30\xcc\xaa\x3b\x95\xb9\x2e\xdf\x3c\x7e\xd5\xb5\x72\xa2\x7c\x55\xd8\xae\xf6\x35\x74\xed\xdf\x03\x86\xdb\x87\xa3\xa4\xb0\x53\xf3\x52\x27\x6d\x26\xd0\x10\x73\xa6\x3d\x79\x3a\xa2\x0e\x7a\xed\xb0\xee\x57\x93\x38\x42\xf3\x35\x2b\xd4\xbd\x5f\xc5\x71\xc2\x39\x4a\xf6\xa2\xee\x89\x23\xe0\x9b\x8c\x78\x22\x23\xe9\x72\x95\x4f\xa2\x78\x21\x81\xbf\x36\x65\xa9\xb0\xa8\xf4\x66\xf5\x9f\x53\x7f\x74\x8f\xc0\xf1\xa3\x8f\x9f\x26\xdc\x66\x8e\x4f\x52\x97\x07\x91\x15\x18\xfe\x9f\x5b\xfb\x71\xaa\x5d\xfc\x17\x0a\x7d\x53\x95\x87\x8f\x50\x2b\x63\x42\x49\x49\x62\xa9\xa4\x27\x47\x76\xe6\x26\xd6\xa9\xcd\x2f\x65\xc5\x63\x4d\x7c\x3a\xe0\x2e\x2b\x40\x0f\xe4\x12\x25\x89\xb5\xb1\xa2\x11\x7e\x2a\xf9\x9a\xd8\xc9\x6d\xb4\xa1\x18\x02\xfb\x0a\xcd\xdd\xd9\xa9\x69\xb8\x26\x08\x80\xf4\x49\xe5\x2d\x88\xc3\x25\x80\xb0\xed\xd6\xce\x7f\x1b\x6b\xb0\xfb\xc1\xcf\x8e\xd0\xd3\xf7\x68\x7d\xdf\x76\x0b\xde\xac\x44\x7d\xbe\x3b\xe5\x4d\x56\x67\xbf\x08\x6f\xc5\x00\x24\x0c\x3b\x09\x4c\x51\x67\x6a\x5d\xa8\xf2\x62\xd9\x02\x68\x2f\x54\xf9\x04\x06\xaa\x4a\xe4\xf8\xdb\x97\x04\xa0\x92\xc4\x26\xd4\x08\x86\x5c\xac\x31\x9e\x31\x69\x4c\x34\xb3\x61\x0d\x0d\x70\x18\x6d\xae\xb1\xd1\x01\xa6\x0b\x96\x4f\x0b\x57\x36\xb4\xd9\x2e\x9e\xb6\xbb\xeb\xc5\x9f\x5d\x17\xb0\xdc\x64\x76\xb4\x6c\x56\xa4\x5d\x81\x37\x65\x65\xa7\xca\xe8\xd7\x38\x09\x13\x9d\x76\xeb\x15\x83\x34\xe3\x37\xe3\x24\x82\xd0\xe5\x8c\xef\xce\x9b\xb7\xb2\xf2\xbb\x00\x27\x52\x22\xb4\x4c\x97\x1e\x7f\x00\x4f\x65\x6f\xa6\x5d\x46\x4c\xe7\x72\x3b\x9c\x48\x8d\xd1\x06\x91\xe7\xbb\x52\xd6\x8d\x50\x79\x17\xa3\xe1\x81\x92\x78\xdc\xbb\x5c\x54\xf7\x67\x23\x70\x93\xdc\xac\xee\x97\xbb\x6f\x8b\xa7\xeb\xdd\x72\xf1\xe8\x1b\x29\x89\x31\xc8\xe9\x10\x6e\x77\x59\xd1\xf3\xe2\xb5\xcd\x52\x5b\xe5\xe2\xba\x9d\xaa\x87\xc3\x18\x9a\xc1\x19\xa5\x3c\xe9\xb8\x34\xd7\xcb\x87\xcf\x70\x90\x6d\x7f\xa0\x92\x7b\x06\x1d\xd1\x65\xd1\x38\x33\x11\xed\x49\xe6\x7c\x1e\x7e\x0c\x56\x1a\x8d\x43\x6b\x1a\x51\x5f\xcb\x69\x5d\x98\x11\xc6\x74\x2e\xa0\xcb\x23\x1e\x0b\x67\x57\xde\x75\x7e\x07\x8f\x52\xc5\xc0\x59\xf3\xeb\x02\x95\x88\xe1\xe2\xd8\xe2\x9c\x69\xd4\xfd\x3e\x8a\x33\x72\x77\xb5\x13\xc0\x13\x4d\xcc\xfa\xa1\x9c\x87\x81\xb1\x72\x06\xa6\x82\xfa\xd9\x92\xd5\xf8\x36\x45\x1c\xef\x85\xd0\x1b\xd1\x9a\xbf\x43\xe0\x19\x4f\x88\xd4\x89\xe7\x67\xb0\x48\x90\xf6\xd4\xef\x3e\x74\x12\x6b\x0c\x45\xdc\xc3\xb1\x39\x15\xa3\x2d\x84\x27\xc6\x60\x38\xeb\xca\x7a\x57\x5e\xd5\xc7\xb5\xa6\x34\x42\xc0\xa5\xec\x31\x54\x96\x18\xc6\xb7\xa7\x0c\x51\x3a\xad\x21\xd3\xd7\x4a\xb6\x0d\xca\x78\x1e\x4d\xeb\x5f\x5c\x57\x62\x5f\x4e\x96\x23\x17\xcc\xc6\x70\xb2\xda\x6b\x8a\x20\x13\x52\xb7\x08\x44\xec\xd8\xd9\x6c\x02\xe1\xd1\xd6\xf6\xbb\x24\xf6\x64\x29\x49\x09\x36\x14\x89\x73\xc2\x31\x62\xea\x59\xfd\xc8\xd1\x33\x48\x08\x4c\x2f\xbc\xb3\x7d\x86\x03\xe8\xcd\x11\x0b\x10\xa6\xb2\x33\xb3\xc7\x2c\x97\x40\x6d\x41\x96\x5f\xa7\x5b\xd4\xd6\x1f\x9e\xdc\x5c\x71\xab\x2e\x7a\x5b\xee\xf7\xa0\x6d\x38\xa0\x98\x96\x29\x8c\x52\xe5\x96\x35\xa7\x37\x40\x38\x84\x80\x5b\x97\x43\xa4\x2e\xcf\x2a\x1f\x83\x18\x7c\x3f\x6d\xeb\x68\x2d\x3b\xa9\x8d\xd2\xd9\x2f\x3e\xe9\x07\xc4\xf2\xc3\x57\x8a\x92\xed\xb0\xaa\x7e\xfe\x30\xe2\x86\x08\x8c\x9f\xc1\x3b\x54\x2a\xab\xa7\xbf\x6b\xda\x7d\xc3\x41\xf7\xfe\xcf\xac\x96\xf8\xd2\x93\x9f\x65\xc4\x32\xe1\x75\xd5\x9c\xab\xed\x37\x5f\xc8\x79\xf3\xfd\xfe\xba\xab\xe6\x94\x24\x09\x64\x2a\x3a\x47\xb8\x86\xdd\x60\xde\x8e\xa7\x4b\x12\x28\x83\x74\xf3\xbb\xc6\x73\x13\x3c\x74\xa9\x9a\x84\x72\x13\x52\x57\xc9\x55\x65\xaa\xf1\xb5\xdf\xd7\x7d\xa2\x37\xa1\x32\x55\x9d\x1e\xcc\x5e\x14\x59\xed\x68\xa1\x7b\x3b\x37\x61\x3c\xc2\x3a\xf3\x43\x56\xac\x95\x8d\x98\xf6\xc5\x7e\x92\x24\x21\x4d\x10\x0d\x8c\x52\xf2\x85\xc8\xdb\xad\x7e\x3c\xac\x49\x98\x10\x3c\x07\xec\x96\xb9\x81\xa6\xc9\xa1\x53\x40\x68\xdb\xd3\x18\x01\x51\xbb\x02\xde\x30\xce\x5b\x3f\x67\x47\xc7\x3c\xe4\x37\x1a\x6b\x15\xcc\xff\x33\xfe\xb5\x28\x20\x5e\x3d\x49\x67\x75\x5d\xe6\xaf\xa0\xd5\x0c\x71\x50\xdb\x35\x95\x18\xdb\x2a\xdd\xca\xb5\xec\xc4\xf5\x0c\xca\x2f\x89\x44\xe4\x15\x9f\xee\xce\x3f\xb3\x7e\x9c\x23\x47\x20\xb1\x7a\xb7\x9b\x9a\xfb\x73\xcc\x52\x60\xfe\xbc\x3f\x76\x88\xb9\x9b\xb2\x5a\xbd\x37\x95\xb8\x2a\x0b\xfd\x88\x75\x42\x75\x77\x05\x17\x58\xc5\xfb\xef\x32\x2b\x5a\xc3\x7c\x10\xd3\x48\x7c\x17\x97\x8e\xd9\x43\xf3\xbd\xca\x36\xd0\x8c\xbe\x14\x97\x89\x74\x98\xfa\x9f\x65\xf5\x62\xf2\xf2\x6d\xd4\x9e\x50\x15\x4a\x1b\xab\x58\x6d\xbf\x7d\xdf\x5c\xdb\xf7\x1c\xda\x84\x49\xc2\x02\x44\x41\x4b\xcf\xce\xd3\x17\xe7\xb5\xad\x91\xc6\xbc\xae\xee\x8a\xba\x31\x5a\xe5\xd6\x5c\x6b\x43\xfe\xd5\xd2\x39\x49\x92\x34\x30\xe1\x10\x4f\xb4\xd8\x0f\xa6\x44\x1a\x0a\xe1\xdd\x78\xd1\xc0\x83\x19\xa8\x29\xf9\x2e\x89\x15\xab\xc5\x8c\xfb\x4e\x83\xdd\x8f\x76\xa6\x9c\x98\x30\x89\x60\x71\x90\x0e\x68\x18\x7c\x55\xff\x28\x52\x9a\x08\xc3\xb4\x57\xf3\x3f\x8a\xaa\xc9\x54\x76\x14\x45\xb3\x2b\x4e\x87\x5d\x69\x76\xa7\x49\xf5\xa6\x24\x89\x64\x61\xe0\xcc\xe0\x4d\x53\x89\x6c\xff\xdc\x58\xb2\xfb\xf6\x43\x8f\x39\x98\xfc\x15\x22\xc6\xec\xfa\x6b\x06\x6f\x5d\x48\x23\x91\xd2\x18\xcb\x04\xd4\xfa\xd3\x53\x49\x8e\xd1\xe7\x51\x34\xc5\xf4\xc8\x6f\x8f\xbb\xb7\xac\x28\xb2\x62\xdf\xf1\xf2\xb6\xad\x9c\x23\x66\xd8\x00\x0c\x92\x94\x89\x4a\xa5\xf6\x1a\x6f\x35\x0c\x9c\xdf\x44\x19\x89\xfe\x8a\xd0\xba\x2b\x08\x02\x3d\xc1\x0e\x8c\xf7\xb2\x44\x53\x8e\x4e\xa4\xe3\xf5\x47\xd2\xe2\x8f\x88\x20\xdb\xee\xd2\x8a\x41\x35\x5d\x64\xda\xc2\xf7\xc6\xbd\x80\x58\xa1\x7c\x61\x81\x24\x23\x7d\x97\xfe\xfc\x48\x80\x98\xd0\x9a\xf0\xc5\x49\xe4\x9d\xbf\x9e\x4f\x3e\xb8\x49\x20\x70\x89\x19\xef\xd3\x7c\x2b\x73\xed\x6d\xac\x49\xe7\x34\xc6\x42\xdd\xcd\x66\xe1\x86\x25\x25\x8a\xc7\xee\xa4\xdb\x40\x0e\xca\xd5\xf2\x5d\x9c\xc1\xbf\x38\x21\xdc\xdd\x02\xce\xb0\x52\xbb\xfd\xe8\x0b\x63\xac\xc7\x31\x7a\xfd\x34\x10\xce\x87\x70\x2b\xc9\x26\x6a\x3f\x47\x7d\xa4\x34\x08\xf1\xc1\xdf\x2e\x24\xc9\xc6\x37\xa7\x5c\x63\x61\x69\x01\x6f\x4f\x70\x2c\x67\x13\xb1\x29\x63\x86\x5a\x49\xcb\xf7\x85\x7e\x1d\x0e\xd3\x28\x9a\x9c\xb2\x50\x73\xdd\xb9\x03\xed\x8a\xc7\x50\xfd\xed\xc7\x3f\x1f\xa6\x96\x39\xf7\x3e\x2b\x60\x0c\xc0\xfe\xc4\x72\x70\xd7\x46\x44\x62\x54\x54\x89\x62\x99\x97\xa8\x49\x04\x56\x08\xe4\x71\x54\x16\x3b\x8b\x22\x4d\x63\x92\x62\x56\xe8\xb6\xdc\x3b\xa2\xf5\xcf\xf3\x2d\x29\x97\x1a\x73\xab\x8e\xf7\xcb\xfa\x4e\xdb\xf5\xdd\x6a\xb3\x5d\xdc\x79\xf7\x21\xe5\xca\x2a\xe2\xd5\xd0\xac\x57\x0f\x9f\xd6\x02\xa4\x89\x4c\xd0\xf7\x2f\xdf\x8a\xfa\xa1\xda\x40\x9e\x4f\x34\x95\xb0\x8f\x96\x6e\x53\x5f\x1c\x8f\x30\x21\x39\x93\x24\x4d\x59\x82\xd1\x81\x1f\x65\x75\x10\xc3\x18\x48\x9a\x86\x96\x22\x40\x78\x7d\x29\x1b\xb6\x2a\x2f\xcb\x53\xdb\xce\x4a\x61\xe6\xea\x20\x5e\x90\x8a\x70\xd0\x24\x54\xec\x82\xb9\xed\x0e\xe4\x4f\xde\xf9\x51\x15\x3a\x41\xde\xb2\xd3\xf1\x08\x58\x28\xe3\x2d\xdd\x54\x18\xf0\xb5\xd0\x17\xa0\x75\xd7\x45\x06\x22\x72\x19\xda\x19\xed\xcd\xb6\x83\x62\xae\x98\xf4\xbc\x6b\xca\x5d\x1f\x58\x4e\x15\x31\x8c\x74\x89\x84\x9f\x00\x2f\xf9\xa8\xe6\xa4\x7b\x40\x45\x59\x64\x39\x54\xaa\xbd\x38\x0c\x00\x01\xa9\x96\x2c\xa5\x3d\x61\xef\xb5\x05\x1d\xf6\x91\x84\x54\x1b\x16\x8b\x4e\xde\xca\x86\x1e\x7d\x6c\xa8\xeb\x64\x02\x8a\x6c\xd1\xbb\xfa\x7c\x90\x65\xde\xff\x39\x4e\x3a\x8e\xb5\x07\x83\xbe\xf4\xd5\xf9\xa9\x75\xb2\x7f\x31\xed\x4c\x28\x30\x34\xe0\xc4\x7c\x11\x0e\xe0\x73\x29\xa3\xe9\x24\x48\x6c\xa3\xf8\x37\xeb\xa7\xcd\x16\xa7\xe8\xd5\x62\xb3\xda\x0d\x79\x41\xbe\xf8\xae\x49\xc2\x59\xc7\x47\x7b\x5b\x8a\xe2\xf3\x7c\x81\xbb\x2c\x90\x96\x73\xc9\x7a\x20\x37\x00\xb3\x9b\xa6\x08\x54\x8c\x63\x50\xc0\x5b\xbb\x1e\x3b\x26\xdb\x91\x80\x62\xdb\x0f\x28\x92\xb4\x69\x2b\x86\xb1\xf6\xc0\x27\x41\x99\xa5\x2c\x39\x5a\x65\x09\x0f\x88\x1d\x1c\x4e\x82\x46\xa1\x70\xf4\xca\x9b\x46\xa8\x97\x67\xd4\xa8\x1c\xef\x9c\x82\xc6\xb6\x1a\x17\x15\xeb\xb3\xe3\x11\x2e\x14\xa8\x27\x2f\x18\x39\x46\xf0\xed\xbd\xff\x9d\x48\x44\x48\x4e\x66\x9d\xa7\xd5\x01\xaa\x3d\x14\xea\xdc\x7a\x68\xee\x8c\xeb\x40\xce\xfe\x0a\x95\x22\x65\x1e\x32\xd3\x2f\x0e\x32\x83\xa2\xf9\x76\x3a\xe8\xe6\xbc\x7a\x6f\xad\x94\x21\xea\x6a\x38\x35\x45\x1c\x8b\x5e\x4c\xb3\xac\x86\x0e\xb0\x88\x85\x25\x9d\x5f\x97\x5b\x4f\xe7\xf1\x49\x7e\x46\xc4\xda\x12\x2c\x9f\x0a\xcb\x8c\x3c\xf5\xde\x05\xe7\x80\xda\xd8\xfe\x94\xdc\x96\x9b\x63\x59\xd4\x97\xa4\x76\xae\x7f\x12\x26\x88\x8c\x96\xcd\x59\xcd\x0a\xa8\x62\x9f\x14\x83\xd3\x47\x71\x06\x7f\x9c\xd6\xf3\x0c\x8e\x6d\x6f\x09\x98\x39\x78\x82\x3d\x92\x21\xb9\x3f\xa7\x41\x8c\x78\xcd\x9b\xec\xfd\x11\x85\x7c\xbb\x86\xd0\x3e\xf1\x75\x86\x48\xdf\xf1\xcd\x52\x49\xcc\x80\x03\x03\xc4\x61\xa6\x80\xe7\x93\xc3\xd9\xdf\x46\x71\x13\x7a\x28\x06\x5a\xd9\x50\x9f\xf2\x89\x9d\x26\x04\xb1\x95\x12\x9e\x9a\x74\xcc\x16\xd2\x76\x90\x34\x8d\xe7\x34\x04\x7c\x3b\x30\x5b\x8d\x25\xea\xda\xd7\xc7\xb9\x26\x29\x15\x97\x3d\xe5\xda\x8e\x8e\x81\x41\x42\x11\x57\x22\x63\xd1\x66\x7d\xa5\x77\xbf\x78\x54\xa8\x12\x67\xe8\xdf\x8a\xba\xe9\x54\x34\xdb\x26\x15\x31\x6b\xeb\x61\xd0\xea\xa7\xe8\x02\x57\x42\x69\x8e\x68\x02\x84\xe5\x58\x2c\xd4\xa6\x11\x4d\xa6\xc6\xb8\x75\x3a\xcb\x07\x86\xd7\x43\x30\xc2\x5a\x3a\x87\xef\x23\xbe\x85\x4b\x93\x5f\x68\x66\xf9\x4e\xe4\x29\xcb\xf5\x32\x6b\xce\x53\xe9\xa2\x5e\xa4\xeb\x9f\xb4\xbf\x48\x60\xb5\x79\x51\x0e\xcf\x2c\x01\x81\x8e\x5d\xd8\xd1\x83\x85\xaa\x45\x73\x41\x47\xd4\xf6\xd4\xb6\x26\x5e\x68\xfd\xdb\x69\x2f\xb4\x98\xb3\x3c\x2e\xdf\xd7\xf0\x38\x91\x03\xff\xe4\xea\x54\x15\xd3\xfd\x47\x12\xaa\x62\x07\xbd\xb5\xa4\xeb\xdd\x09\x3c\x6b\x10\xc8\x20\x89\xd0\xe3\x76\xe2\x09\x37\x65\xd5\x9e\x66\xf5\x28\x79\x21\x83\x24\xb5\x85\x61\x08\xc2\xed\x42\x6e\xb3\x33\x5a\xd2\x10\x90\x6c\x67\xf5\xb4\xfc\xe2\xff\x24\x2d\x87\x4a\x03\x75\xe3\xca\x4a\x8d\xc8\xf3\x5d\xc7\x18\x2f\x89\x64\x41\x04\xa3\x88\xcf\x9d\x78\x5f\x0e\xaa\x06\xbf\xd7\xba\xeb\xaa\x52\xf4\xc5\x56\xdb\x6f\xab\xa7\xc5\xcd\xcd\xad\xc7\xf5\xc8\x88\x30\xa4\xfe\xbc\x2b\x8b\xf3\xc8\x32\x91\x11\x13\xc8\xa2\xf6\x73\xf3\xfb\x9f\xa3\x86\x98\x48\x44\x8a\xfc\xe3\x8f\xaf\xa3\xbf\x73\xce\x70\x6a\xac\x36\x9b\x3d\x14\x50\x67\xfe\xbc\x95\x49\xc4\x2d\xa1\x76\xe9\xc3\xbb\x32\xa5\xb4\x2f\x8f\x6b\x44\xee\x0a\x10\xc6\x03\x93\xc6\x04\x25\x71\x7b\x6a\xdf\xee\xf2\x54\xf1\x5e\xa8\xe9\xb1\x6c\x44\x53\xfe\x6f\xd8\x2f\x29\x62\x8a\x69\xea\x4d\x29\x8e\x57\xa5\x47\xe7\x49\xc9\x38\xee\x6d\x7f\x3c\x2e\x90\x8e\x76\xfa\x4c\x2a\xd4\xb1\x65\xf8\xb4\xeb\xd3\xea\x2e\xff\x02\xdf\x2d\x95\x8a\xd1\xd1\x9c\x83\xc6\x8e\x1f\x4b\xe9\xc4\x38\xd9\xf6\x0e\xc1\x6e\xa3\xfa\xae\x83\x8e\x92\x24\x19\x78\x1a\xd5\x48\xbc\xb7\xed\x20\x94\x8a\xbd\xef\x94\xcd\x57\xe3\x49\x90\x36\x99\x01\x85\x5e\x2f\x1f\x8e\x3e\x5d\x25\x41\x13\x69\x27\x6e\x6e\xc6\x95\x65\x12\x74\x80\xf1\xdb\xcd\xdd\x66\x60\x92\x49\x43\x52\x97\xcd\x6c\x36\xa5\x69\x96\xe2\x88\xb1\xf8\xee\x71\x0c\x04\x98\xa3\xb7\xd9\x0a\x07\x77\x9c\xc1\xd8\x29\x12\x59\xb0\x87\x4b\xba\x3b\xac\xe7\xff\x86\x3e\x54\x01\xb3\x94\x87\x42\xeb\x6b\x8b\x05\x99\x2e\x78\x15\x08\xed\x29\xa9\x47\x61\xa2\x0b\x86\x70\x49\x14\x25\x10\x8a\x5e\x43\xa3\xd3\x0c\x19\xdf\x91\x8a\x20\x1e\x60\xae\xaf\x33\x63\x32\x75\xca\x9b\x73\x9f\x93\x50\x14\x24\x06\x86\xef\x45\xf3\x2c\xf2\x0c\xfe\xa2\x03\xa5\xa8\xb1\x94\x92\xb8\x09\x38\x1a\xc3\x71\xdc\x43\xb1\x48\x21\x17\xa7\x38\x35\xe5\x55\x56\x35\xcf\x7d\xcc\x5e\xb1\x54\x7a\xc1\x2d\x4b\xbf\xb9\x2e\x66\xf8\x42\x24\x51\x21\x8d\xb1\xfe\xd1\x66\xad\x6d\x4e\x8a\xfa\x23\x4f\x85\x92\xa1\x36\x42\xbb\x3f\xae\x54\xe9\xff\x1c\x05\x2c\xc4\xfa\x54\xbb\x09\xf6\x5a\x1e\x6d\x1b\xb7\x02\x2a\xc7\x76\x5f\x67\x7d\xbd\xd9\xba\xe8\x0b\x91\x54\xac\x39\xf2\x5c\x21\xb8\xf9\xae\x2c\xea\xa6\x75\x9d\x9b\x53\x55\x0c\xad\x56\xef\xbb\x2a\xce\xa4\xe7\xde\x5f\x17\xaf\x59\x53\x4e\xbf\x04\x0f\x43\x74\x31\x6a\x71\xae\xcb\x03\x34\xcf\x3d\xa8\x57\x71\xc3\xb1\xdc\x1e\x35\xa9\x4f\x4d\x79\x68\x4f\x4e\x47\xb5\x3e\x18\xb1\x84\xa4\xdc\x45\xae\x27\x96\xf3\x70\xb8\x12\x4d\x11\xf6\x6f\xad\xec\x3b\x18\x14\xf7\x8e\xbf\xa9\xef\x6f\x52\xec\x2f\xb4\x1e\x19\x0b\x2a\xf5\x5c\x90\xd0\x2c\xd4\x90\x6c\x62\x32\x13\x53\x63\x35\x5b\xae\x4e\x4d\x53\x16\xcb\x3c\x1b\x16\x0b\xb9\x3e\x82\x02\xa6\x3b\x7e\xac\xfc\x41\xa2\x04\x04\x88\x7c\xfa\x79\x7d\xef\x83\x23\x4a\x32\x9a\xa6\xde\x82\x5a\x9b\x87\xe2\x7b\xa1\xe6\x09\x37\xda\xce\xad\xa5\x84\xae\xcd\xf1\x8b\x35\x2e\x7c\x83\x4a\xa4\x63\x2f\xc8\x3b\x40\x89\x73\xb9\x2e\x8a\x6c\xa7\x40\xb3\xcf\x2a\x2e\xec\x7f\xc6\xa6\xe1\xac\x23\xab\x24\x50\xf4\x06\x77\xf0\xde\x40\xa1\xaf\x84\xde\xc3\xa7\x02\x2c\x92\x28\x45\x22\x6f\xf7\xb5\x9e\xf2\xc3\xb1\x79\x38\x7d\x10\xf8\x50\x8a\xa5\xe8\xeb\xda\x60\xd5\x0a\x59\xd1\xe7\x94\x47\x3f\x3c\x64\x94\x52\x52\xb1\xe1\xf2\x73\xf2\x27\x83\x99\xa4\x94\x42\x8f\x02\x0b\x47\x9d\x2d\xeb\x9a\x7c\x61\xf8\xfa\xb7\xee\x7b\x02\x44\x28\x11\xb0\x7d\xcb\x14\x2c\x5a\x1f\x7a\x98\x5f\xfe\x64\x1f\x31\x44\xab\x9e\xb4\x1e\x97\x23\x6a\x09\x7d\x7e\x70\x29\xc3\x22\x9f\xf4\xbe\x87\xb7\x1b\x27\x5a\xe3\x6b\xf6\x6d\x27\x4d\x12\xcd\xdc\x26\xb3\x7d\x5f\x8e\x98\xeb\x47\x77\xd3\x01\x0d\xb9\x97\xa2\xbb\x5b\x6c\xfc\xf5\x01\x4b\xc0\xd6\x21\x9d\x8a\xe6\xbc\x73\x1e\x65\xdf\x6a\x09\x53\xbc\xc2\xfa\x6a\x2a\x8b\xdf\xf6\x11\x34\x56\x7d\x3d\x5b\x6b\xe8\xa3\x13\xee\x9a\x69\x1c\x72\x57\xbf\xdb\x55\x12\xff\xff\x94\x7d\x59\x73\xe2\x48\xb6\xff\xd7\xe9\x87\x79\x50\x2e\xda\x1e\x01\xe3\x2a\xa6\x6d\xe3\xbf\xc1\x55\xdd\x33\x71\x83\xc8\xe5\x24\xd6\xb5\x90\x18\x49\x54\x95\xe7\xd3\xff\x43\x27\x17\x2d\xc6\xee\xbe\x0f\xbd\x84\x95\x08\x21\xa5\x32\xcf\xf2\x5b\xe6\xd3\xe4\x5a\xb5\x56\x53\x99\x23\x26\xfe\x50\xb4\xfb\x5f\x28\x4a\xdf\x27\x63\x8b\xe6\xd8\x5e\xa7\x31\x6a\x26\x18\x4e\xaf\xc5\xcd\xcd\x66\xbf\xd9\x3e\x2c\xee\xac\x5c\xf3\xe1\xe1\xf9\xde\x5f\x0d\x03\xc3\xac\x89\xf3\xf6\x8c\x06\x42\xd3\xd7\x58\x73\x63\xfc\x14\xbd\x17\x1a\xf6\x7f\xcc\x7e\x6c\xcc\x65\xd0\x3d\xb3\x22\x26\xef\x74\x43\x74\x9c\x68\x1b\xf1\x95\x70\x7e\x11\x55\xf7\x97\xe9\xa8\x4e\xfa\x3d\x0a\x25\xa1\x7e\x7e\xda\x0e\x98\xbc\x82\x3a\x89\x35\x32\x1c\xb0\xde\xfe\x71\x41\x57\x27\x09\xcd\xad\x38\xfb\xb1\x11\x1d\xc8\x37\x94\x9e\x99\xfd\xf0\x34\xe7\x79\x08\xad\xb7\xcd\x93\xeb\x7b\x05\x55\x61\xbf\xe3\xe9\xd4\x68\x64\x73\x3f\xc0\xcf\x0f\x18\x4c\x6e\x60\x46\x0c\xd6\xae\x51\x1b\xc3\x6b\xc2\xdf\x7e\x50\x18\xd7\x99\xc8\x10\x90\xb4\x6d\x4f\x45\x10\x5b\xd1\x99\x8c\x89\xeb\x1b\xf5\x81\x98\x8d\xb6\x36\x3a\x5c\x4c\x9e\x5b\x8c\x9f\x2c\xba\x2f\x98\x15\x4d\xc1\xa7\x3a\x37\x80\x21\xf6\x45\x9b\x6f\xcf\x8f\x23\x9d\x04\x3f\x40\x2a\x48\x49\x00\x03\x82\x38\x15\x5d\x40\xb0\x5e\x8d\xde\xb4\x22\xb6\x78\x73\x23\x26\xb0\x42\xad\x12\x86\x05\x42\x14\xfb\xf9\x5e\x54\x08\xdd\xc2\x52\xe0\xf2\xed\x09\x8e\x4e\x3f\xe2\x33\xb1\x8e\xc9\xdd\x53\xd2\x7a\x23\x9f\xc5\x5b\xff\x60\x1f\xef\x16\xfb\xd9\x63\xd5\x24\xc6\x69\x76\x16\x45\xd5\x1d\xce\xc5\x2f\x28\x67\x22\x17\xb3\x07\xa2\x69\x16\x67\x1e\xd4\xb8\xbc\xbc\x39\x31\x9e\x0f\xa3\xbc\xc9\x14\xd5\x3c\xcd\x84\x8f\x6c\x2f\x55\x17\x40\x63\x7d\xb6\x19\xff\x8f\x1f\x25\x34\xb6\x81\x90\x1e\xe1\xb7\xf0\xeb\xeb\x11\x44\xca\xc3\xa0\x7c\x2d\x04\xeb\xe0\xa3\x8e\x9d\x06\xa2\x10\xfd\x71\xbe\xc8\xb2\x68\x5f\x5c\x40\x32\xf2\x6e\xf2\xd1\x89\x06\x6d\x81\xb3\x06\xd4\xcb\xa2\x2c\x57\xa2\xd2\xa8\x01\x19\x66\x8a\x89\x0d\x42\xd7\x0e\xaa\x3e\x9d\xb1\xf5\x56\x1d\xff\xa2\x9c\xa7\x4d\x0e\x31\x0b\x32\x5b\x61\xd6\x41\xc4\x38\xaa\xda\x3c\x3f\xdc\x2d\xc3\xdf\x72\x81\x42\xc6\x98\x35\xe2\x7e\xb2\x7b\xa9\x2f\xa5\xde\xbf\x34\xf5\xcf\x30\x08\x0c\x86\x41\x3f\x43\x55\x09\x5f\x8b\x4f\x3a\x7f\xd3\x2b\x02\x42\x53\x12\xbb\x2a\xf4\xc4\x0d\xf0\xef\x75\x53\x80\x24\x4a\x41\x68\x40\xe8\xba\x53\x2f\x5d\x8d\x9e\x6a\xd7\x5f\x62\x20\x42\x88\x38\x68\xb5\x79\xf9\x26\xbc\xec\x65\x7d\x39\xbe\x7c\xb0\x7d\x03\x31\x31\xde\x3a\x6c\xaf\x78\x29\xe0\xe9\xcb\x09\x94\x33\xac\x41\xac\x04\x34\x97\xf6\x43\x27\x4a\x19\x01\x4b\x4d\x6a\xad\xb0\xb0\x68\x38\x5f\xbc\x80\xe7\x14\xeb\xa1\xcb\xd5\xc6\x47\x5a\x10\xf3\x14\x2c\x0c\x19\x13\xb5\xe6\x0e\x7e\x40\x49\x1f\x27\xfb\x1b\xc4\xa9\x65\x0e\xbb\x26\x64\x07\x47\x17\x65\x90\xd8\x8f\x10\x22\xcb\x3d\x4f\xd7\xb2\xf0\xad\x97\xc3\x4d\x28\x4a\x41\x12\xa7\x22\xf5\x96\xb2\xf7\x45\xd5\xa1\x72\x72\x34\x7d\x5f\x21\x49\x52\x61\xd7\x2a\x1d\xda\xf4\xb3\x21\x69\x9c\x22\x24\xe1\x8b\x38\xc1\x1f\x96\xee\xe3\xbf\x23\xe3\x56\x8e\x46\x5c\x54\x77\x69\xbf\xfb\xdb\x3a\x4d\x47\x20\x53\x12\x8d\x8d\xac\x18\x66\x58\xc8\x30\xb8\xbd\xad\x9b\xf5\x0f\x68\xde\x64\xad\xc3\x95\xe7\x82\x80\xdb\xce\xbe\xd6\xba\x84\x66\xee\xe4\x2f\x23\x10\xc4\xaa\xaa\x5b\x2c\xdc\xde\x47\x0e\x20\x32\x9d\x19\xdf\xa3\xd7\x00\xa7\xd0\xcc\x6c\x11\x21\xd4\x5c\xd3\x88\x93\x11\xc8\x98\x60\xa4\xac\xca\xba\x05\x2b\x90\x52\x8e\x2a\xd7\x20\x25\x4d\xc6\x34\xeb\x2f\x85\x09\xcf\x4b\x82\xb1\xa4\xc2\xd0\x42\xf7\x9c\x08\x2b\xa9\x7a\xd5\x5b\x77\x5e\x48\x03\x45\x25\xca\x55\xe0\xbb\x9a\x1d\x04\xde\x1e\xbf\xe3\x15\x75\x75\x78\xc6\x53\xaa\xba\x81\x85\xd6\x56\xe1\xf0\xd0\xbe\x7f\x9d\x95\xb2\x88\xf6\x50\x05\x42\x89\xb6\x85\xe9\xfa\x0f\xbf\xd4\xf5\x6c\x23\x06\xa5\x04\xde\xb1\xbb\xba\x7e\x5d\x60\xf1\xb1\xbf\xdd\x8f\xd0\xfc\xab\xae\xe6\x77\x5d\x73\x96\x7b\xcb\x0e\xf1\xcb\x56\x3a\xfc\xf7\xea\x24\xc6\x88\x0b\x7b\xf7\x9f\x8b\xc1\x80\xce\xd3\x94\x0f\xf0\x4e\xf1\x0a\xf5\xa5\xbb\x86\xf0\x04\x48\x2c\xf2\xe3\x20\xb4\x76\xa6\x4a\x7b\x68\x4e\xed\xfb\x2f\x18\xe5\xea\x57\x12\x77\x00\x30\xa8\xfc\xf8\xe7\xe2\xe1\xf7\xf5\x7a\x37\xff\x1a\x23\xa4\x93\x83\x5d\x34\xb2\xe8\x26\x1d\x37\x3b\xc6\x44\x29\x38\xee\xa9\xc3\x1c\x0c\x35\x5a\x13\xa9\x1c\xbb\x4c\x2f\x50\x96\xf5\xf4\xa6\x19\x42\x28\xf3\x60\x4a\x6b\xca\xbc\xaa\x4f\xa7\x4b\xe5\xcc\x3f\xb1\xdb\x7f\x75\x85\x31\x94\xe5\x90\x7b\x1c\xea\xea\x05\xfe\x13\x80\x6c\x86\x32\x8d\x34\xa9\x5d\xb0\x67\x5a\x79\xf9\x35\x32\xdd\x24\x0d\x95\x29\x75\x9b\xe4\xe1\xc7\x7b\x64\x96\x61\x14\x62\xeb\xe9\xe9\x72\x36\xa1\xba\xda\x89\x92\x8d\xe4\x96\x65\x64\x38\xd5\x56\x60\xb5\x7d\xbc\x34\x1f\xe4\x87\x86\xa7\xc4\x22\x7f\xfa\x08\xb0\xdf\x45\xde\xf9\xaa\x4e\x6f\x6b\x2c\x20\xa5\x23\x47\x3f\x8c\xe6\xb7\xd5\xd4\xd5\xc2\x8d\x4d\xf2\x98\x5a\x1d\x94\x6a\x92\xa5\x5d\xbf\x92\x94\x26\x48\x38\x3e\x5d\xca\xae\xd8\x15\xc7\x1b\xf8\x31\x05\x77\x9b\x54\xa7\x1e\xe7\x6a\x37\x8e\xf7\xe0\x7c\x93\xc5\x02\x2b\x75\xa2\x68\xd6\x95\xee\x86\x8e\x81\xc9\xb9\x24\xc1\x27\xff\xb6\x68\x5f\x16\xff\xb9\x88\xa6\x0f\x14\x87\xb7\x7c\x7a\xae\x5c\x0a\x9c\xf7\x8e\x95\xb4\xb6\xd5\x76\xcf\xf9\xf4\x83\x8c\xe5\xcb\x0a\x5b\xdb\x59\xf5\xef\x13\x68\xbb\x94\xf8\x31\x82\xe7\x48\x94\x90\x97\x37\xf7\x56\xf4\x0b\x69\x90\x7a\x31\x22\x8e\x90\x9c\x74\x73\x33\x0e\x07\x8d\x64\x11\x6a\xe2\xf9\x52\xa1\x47\xfc\x7d\x1a\x14\x19\x45\xb5\x95\x5f\xed\xd3\x43\xaf\x64\xa4\xaf\x3e\x20\x95\x4b\x2c\xdf\x94\x45\x59\x8c\x69\x9b\x46\x47\x2c\xb6\x95\x5b\x03\xdf\xaf\x18\xfb\xf6\x43\x72\x3b\xc4\xbf\x5f\x83\x41\x56\x51\x57\x37\x72\xf6\x4d\x86\x53\x7c\x2c\xcb\xc5\xad\xcb\x85\x49\x14\xf5\xef\x05\x2e\x16\x8e\x43\xed\xff\x2e\x34\x22\xa0\x8a\x4a\x35\x70\xc2\xf7\xc5\xaf\x5b\x24\xa2\xd2\x48\x18\xa2\xf9\x71\x07\x8f\x44\xd4\x21\x7a\xa1\xff\x84\x87\xe8\x8e\x0a\xfb\x24\x62\x52\xc6\x59\xc0\x35\x16\x27\x51\xda\xe2\xfe\x5c\x0f\xb7\x1f\xaa\xec\x9b\x81\x2b\xe4\xaa\x36\xfd\x26\x51\x8c\x25\xd9\xfb\x31\x60\x62\xa7\xa9\x67\xce\x57\xdf\x30\x12\xf1\x34\xf5\x44\x88\x45\xd5\xb5\xbb\xa2\x52\xd0\xaf\xdb\xae\x74\x35\xb9\x51\x24\xe2\xca\x8a\x4a\x82\x68\xca\x37\xdf\x78\x18\x83\x6d\x49\x14\x47\x1a\xe3\xa9\x0a\x7e\x86\xbe\xe8\xfc\xd5\x1a\xd7\x5d\xfc\xc7\x08\x4d\xbc\xad\xca\xf8\xde\x5c\x2b\xca\x4e\x7e\x40\x9c\x42\xae\x9c\x5c\x32\x9d\x5d\x6e\x2c\x01\x4b\x2c\xcb\xba\xae\xc6\xea\x38\x24\x8a\x95\x35\x36\x2a\xd0\x3d\xac\xd0\x9e\x0f\xde\xc7\x36\x1e\x9b\x4b\xa2\x84\x59\x0d\x72\x64\x70\x2f\xeb\x3e\x7e\xb0\x74\xe8\xe9\xd7\x24\x60\xb0\x08\xbd\xbf\x74\x75\x03\x3e\xb7\x23\x51\x2a\x85\x70\x9e\x61\xc5\xe9\x52\x2d\xf7\x2b\xdf\xad\x09\x23\x20\xc3\xd7\x53\x3a\x1e\xab\x47\x76\xff\x9b\xff\x4f\x18\x21\x88\x2b\x18\x3a\xbe\xda\xe2\xff\xdd\xcd\xe6\x42\xc6\x15\x8c\x5a\x82\x0f\x75\xd3\x82\x29\x9c\xd7\x40\x7f\x3c\x8e\x6c\xb3\x65\xf3\xf0\xe0\x9c\x24\x25\x89\xf2\x28\xc3\x8e\xe9\x62\xb5\x3d\x4c\xee\x4d\x4e\x00\xc5\x4a\xd7\xff\x0d\x7f\xc9\x19\x36\x93\xe5\xe5\xad\x9d\x4e\xb1\x5c\x06\x31\xe1\xe7\xb3\x85\xdf\x5c\x7c\xb3\x9f\xb8\x0d\x95\xf8\xe9\x9d\x43\x86\xf9\xb2\xc5\x23\x7c\x5b\x3c\x6d\x16\x4b\xdf\x2c\x22\x91\x4a\x63\xbf\x7e\xae\x4e\x7a\xf8\xab\xdd\x26\x6c\x65\xc9\x46\x2a\x21\xae\xcc\xfc\x20\x43\x11\x83\x7a\x69\xa1\xb1\xf6\xdc\x93\x8a\x84\x1b\xa5\x63\x86\x8d\xa2\x7b\x68\x8e\xe0\x28\x63\xe1\x90\x88\xe9\x20\xf6\xde\x6f\xa7\xa5\x0f\xa4\x67\x27\x49\xa2\xc4\x9a\x8e\xe2\x3a\x7b\xdd\x23\xf7\x5d\x88\xf6\x8f\x8f\xc4\x24\xfb\x13\x4a\x4e\x82\xf1\xe0\x65\x8c\x95\x70\x23\x80\x93\x94\x86\x94\xe6\x2a\xec\x86\x44\x20\x24\x26\x03\x8b\x9b\x9b\xed\xd0\x40\x21\x11\xa8\x0c\x01\x10\x77\xf5\xf1\xb1\x81\xb3\x68\x60\x75\x45\xfb\xf3\xd3\xa4\x8a\xf4\xb1\x1a\x9a\x23\xda\x89\x7c\x9a\xce\x61\x93\xc5\xd9\x60\xb3\xf0\x9e\x8e\x7d\xed\x72\x49\xc4\x28\x32\x58\xce\x75\x5d\xae\xbb\x97\xa0\x86\x47\x08\x89\x14\xcd\xa7\x66\x16\xcf\x4d\x31\x0e\x20\xfe\x31\x0f\x26\x08\x21\x34\x46\x7c\x3a\xe6\x30\xde\x90\xde\xbd\x2f\xfe\xc4\x94\x71\x1f\x6f\x1e\x4e\x6f\x07\x5d\x15\xfe\x08\x8b\x13\x44\x8a\xfe\xa8\x3b\x68\x37\xc3\x72\x4e\x98\xb6\x75\xf5\x77\x84\x7c\x77\x9c\x47\x19\x66\xef\xa6\x01\x20\x5b\x33\x9d\x2a\x84\x73\x95\x0b\xd7\xcc\x73\x4a\x51\x4a\xbc\x27\x9a\x12\xc2\x65\x8e\xd1\x6e\x09\xa6\xcb\xf3\xd9\x59\xe2\x24\x52\xf1\x04\x51\x17\x52\xa3\x19\xa6\x83\x90\x58\x53\x6c\xfc\x87\x2d\x59\xfc\xfa\x24\xeb\x24\x24\xe5\x96\x71\x7a\x57\x1f\x03\xbe\xd3\xf2\x38\x3e\xfa\x80\xb0\x1a\xe3\xaf\x45\x75\x5c\x8a\xea\xd5\xdf\xa8\x2c\x4a\xac\x03\x02\xce\xef\x3b\xa8\x8e\xdd\x84\x74\x48\x48\x96\x00\xb6\xce\x34\xa8\x00\x86\xf8\x5b\x5d\x37\x42\xb2\x94\x21\x3e\x75\xb9\xdd\xfd\x11\xbe\x30\xcb\x10\x69\x8c\x72\x96\x7d\xc6\xb2\x0d\xd0\xfe\xef\x2f\x50\x3d\xd4\x16\xc1\x50\x87\x47\x99\xe5\x1c\xf7\x39\xa1\xf5\xd2\x9b\x3b\x4d\x9f\x42\xce\x13\x9e\x0d\x2e\x0e\xdf\xa1\xc0\x3e\x62\x1f\x60\xd4\x97\xee\xf7\x3f\x57\xb3\x07\x93\x73\xa9\x1c\xce\xef\x4b\x59\x4b\x51\x3a\xa7\xbe\x79\xd7\x95\x90\x3c\x17\x59\xea\x40\x17\xdd\x3d\xcc\x9c\xec\x24\x21\x82\xe4\x60\x93\x5a\xa7\x11\x3f\x7d\x59\x04\x91\x59\x3e\xf4\x5c\x3f\xe2\xe1\xf9\xd1\x54\xe4\x4e\x0a\x71\x7d\xf3\x3c\x6d\x42\x5e\xbf\xc1\x82\x5b\xed\xdd\x85\x69\x6e\x25\x36\x5c\x8a\x6a\xbc\x23\x10\xc9\x23\xe1\xd7\xa8\x4a\xd0\xd9\x8d\x50\xdc\xe8\x6c\xa2\xba\xbb\x12\x65\x89\x8f\x79\xbe\xbc\x8c\x76\x7c\xa2\x54\x94\xdb\x52\x51\xf5\xd8\x04\x0a\x26\x21\x0a\xa8\x76\x4d\xd6\xcf\xea\x94\x84\xe8\x4c\x3a\x1a\xf6\x0f\x10\x25\xea\xa6\x7c\xfe\x3b\xb5\x8e\xf0\xce\xf4\x31\x86\x37\x95\xf3\xdf\x0a\x91\x50\x56\x89\xbc\x0f\x66\x06\x05\x5b\x7f\x98\x65\xb6\x48\x72\x29\x7d\x7f\x62\x5f\xcf\x68\xaf\xfd\x28\x89\xbc\x14\x07\x15\xfb\x31\xc6\xbd\x61\x1a\x39\x09\x60\xdc\x3a\xf6\x41\x09\x7c\x38\xa9\x62\x28\xc8\x72\xbf\x7e\xd8\x2d\xa6\xc2\xa0\x84\x46\xd4\x26\xbf\x85\xaa\xf9\xbd\x57\x01\x22\x34\x52\x24\xf1\x9d\xe5\xcf\x29\xb4\x84\x46\x10\x2a\x24\x96\x49\x23\xca\xc1\x95\xad\x98\xf1\x99\x08\x25\x71\x6c\x8b\x3c\x28\x1e\xd9\xaf\x8b\x74\x3e\x42\x10\x7c\xb0\xc1\x40\xe6\xd3\x2a\x3f\xa1\x54\x44\x78\x01\xff\x8b\x73\x1b\xb3\xd9\xee\x6d\x76\x4e\xc6\x78\x4c\xfc\x06\xdd\x9c\xae\x69\x68\x11\xca\x52\x40\x0e\x68\xa0\x5c\x3b\xb5\xdc\xab\xc9\x22\xa1\xcc\x58\x00\xcf\x5d\x7d\xbc\x3a\xc1\x68\x92\x32\x49\xfd\xf2\x4f\xa2\xfb\xb6\x83\x73\xe0\x09\xf6\x87\xe3\x34\x64\xd4\x83\x3b\x75\x68\xcb\x13\x9a\xe8\x08\x06\x35\xfe\x45\xa5\x77\x50\x96\x8b\xb2\xbc\x6e\xc0\xfc\xae\xc2\x79\xfd\x79\x25\x5a\xa1\x5a\x8a\xb4\xec\x3c\x8f\x67\x9a\xea\x7a\x10\x9a\x52\x8a\xad\xdf\xcd\x6a\x3b\xf2\xf4\xec\x0f\x30\x8a\xb5\xdd\x93\xe8\x13\x23\xbf\x6a\xb6\xeb\xaa\x9f\xef\x7a\x18\x65\x7d\x26\x30\x1f\xdd\xb9\x8e\x38\xfc\x8d\xe2\x13\xa1\x69\xec\xd4\x70\xb5\x7e\xef\xac\xd6\x1f\x4f\x04\x77\x30\x5b\x2b\x99\xa6\xde\xc6\x2a\xb3\x93\x97\xd8\x6d\xf0\x34\x63\xd6\x3d\xe8\x84\x9a\x2f\xed\x6c\x76\x64\x99\x42\xed\x54\x37\xaf\xf6\x7e\x19\xbd\x04\x07\xdf\x7e\x90\xb2\xfc\x19\x8b\x78\xed\x23\x8e\xbf\xb5\xfd\xd0\x9c\xe7\xa9\xe5\xdd\xbc\xf8\x05\x91\x8a\x8c\x0e\xc6\x43\xfd\x0b\xb3\xae\xf4\x80\xff\x23\x54\xa6\x04\xb9\x2b\x07\xa1\xf5\x07\xb3\x4f\x2b\x81\x7a\xc2\x7d\x30\x2a\xab\x62\xfe\x93\x34\xc4\xb1\x15\xf7\xfa\xe1\xcc\x9e\x2c\xa9\x79\x09\xa6\x6e\x3e\xd8\x9e\xa9\x36\x26\xb1\xb1\x42\x29\x7e\x39\x0a\xe1\x95\x1f\xea\x46\x03\xe1\x3c\x1f\xb0\x80\xeb\x56\x85\xca\x1f\xa1\xc0\x00\xe3\xdc\x1f\x75\xd9\x7d\x44\x9a\x9b\x9f\x8f\x07\xbe\xcb\xc4\x46\x78\xfa\xb6\x43\x6c\x3b\x04\xdb\x73\x6b\x75\x92\xc3\x94\x83\x5c\x59\xf1\xaa\x3f\x77\x93\x84\x84\x82\xce\x71\x81\xb8\x5d\x6d\x37\x0f\x84\x50\xfa\x49\xbf\x71\x76\x4d\x26\x07\x44\xcd\x9a\xa2\x12\x65\xf1\x5f\xd8\x79\xc0\x38\xa1\x06\x32\xa7\x52\xaa\xef\xeb\xeb\x4e\x41\xe1\x3c\x8c\xa4\x11\xc6\x1b\xb6\x64\x7d\x70\x5b\xdd\xa3\x78\x7b\x8f\xa4\x27\x8c\x12\xd0\xce\x53\x79\x7b\xe9\x5c\x1e\x11\x8a\x32\x84\xb1\xc8\x8a\x16\x60\x23\xcd\x79\x7c\x5c\x5b\xd0\x18\x33\x36\x63\x39\xb4\x2f\x17\x63\xca\xff\x8b\xa4\x0b\x61\x9c\x30\x74\x0f\x10\x36\xee\x04\x8f\xa1\xde\x83\x38\x2d\x2a\xfd\xd8\xd4\xff\x0b\xaa\xbb\x8e\x08\x21\x8c\x33\x80\x7c\xf0\x85\x6e\x97\x6f\xcf\x2d\x34\x9b\xa9\x32\x01\x61\x9c\x53\xdb\x5d\x2c\x45\x1b\xe0\x39\x84\xf1\x14\xd0\x9c\xfb\x54\x54\x5d\x7b\x91\xfe\xcf\x71\xc2\x33\xd7\x8c\x58\x57\x7a\x60\x1a\x12\x16\x4b\xeb\x5b\x55\xc1\x2f\x14\x50\xf4\x62\xe2\x84\x25\x89\xb6\x45\x8c\x2b\x52\x4f\x57\xf7\x13\x96\xa6\x11\x52\xf1\x74\x1f\x69\x9d\x8a\x6a\xbf\xb9\xb9\xfe\x06\xb0\x34\xb7\xa4\xbd\x2f\x37\x2b\xeb\xd3\xc3\xfc\xb7\x66\x3a\xb6\xf9\x89\x8b\xdd\x47\xd2\x1e\xfd\xc1\x8c\x79\xe9\x78\x17\xa1\xac\x45\x53\x61\xbf\xcd\x0d\xc9\xfb\x55\x70\x14\x89\x77\xf5\xec\xc6\xe5\x71\x12\xc9\x60\xf5\x83\xf8\xca\x7e\x65\x73\xeb\xc8\x88\x67\x4c\x58\x2e\x0c\x49\xfd\x74\x19\x1a\x2b\xfe\xa8\x49\xb1\x78\xfb\xf0\xb4\x3c\xf4\xbb\xa7\xef\xfc\x12\x26\x28\x60\xda\xaf\x5e\x44\x73\x84\xed\xcf\xa9\x1a\x05\x61\x92\x1b\xd4\xa7\xfb\x59\x9c\xc3\x77\xc9\xc4\x12\xe3\x0f\x1a\xfa\x4d\xab\x85\x77\xd6\xd5\x57\x57\x33\x26\xb5\x41\xe1\xcf\xa2\x5d\x74\xf7\x75\xfb\xfe\x51\x4d\xe6\xb5\x4a\x23\xac\x27\x58\xc2\xf4\xef\x45\x75\xdc\xc3\x7b\x82\xd0\x55\xc2\x3c\x61\x2a\x33\xa8\xc5\xbc\xdc\xdc\xdd\x6d\xb6\x0f\x87\xfd\xf6\xf7\xf5\x83\xdf\xdd\x98\x8e\x49\x16\x79\xf8\x91\x0b\x45\xed\x6f\xf8\x34\x1a\x65\x60\x18\x22\xe1\xbe\xc1\x48\xab\x91\x30\xa3\x29\xc6\x98\xbe\xb8\x79\xdd\xda\x80\xf0\x88\xd8\xce\x73\x09\x3f\xa0\xdc\x56\x30\xd2\x8d\x20\x3c\xe2\x24\x77\x7c\x31\x07\xe8\xbd\x82\x3c\x1c\x5d\x0c\x8f\x12\x81\x9c\x28\x79\x79\x7b\x10\x6a\xba\x7d\xf2\x48\x02\x06\x15\x7d\xea\x73\x2b\x8a\x72\x79\x79\xc3\x86\x0c\x32\xa0\xfc\x57\x92\x4c\x19\x87\xc4\xff\x5a\x5f\x86\xbf\xd3\x88\x68\xcb\x92\x41\x8d\xda\xdb\xba\x59\x34\x1d\x66\x7d\xc7\x3e\xe4\x13\x57\x15\x61\x27\xd3\x86\xd3\x3c\x43\x3c\x22\xf6\x96\xea\x0a\x6e\x45\xd9\xc2\x02\xa5\xfb\x1f\x6a\xd7\x94\xf0\x5f\xc7\xa8\x52\xd6\xfa\xba\xfe\x89\xb2\x3a\x07\xb7\x80\x3a\xa1\xed\x2b\x6d\x1a\xc2\x59\x0a\x68\x8b\xed\x44\x18\xbd\xb1\x58\x7f\x44\xa5\xd1\x60\x41\xbc\x14\xcd\xaa\xd6\xd6\xb3\x68\x7e\xc9\x57\x66\x1d\x67\x2a\x27\x0e\xf9\x82\x96\x16\x8e\x5e\x7b\x75\x69\xe0\x4c\x27\xc6\xa1\xbb\x9f\x2e\xd5\x20\x5b\x4d\x38\x17\x5c\xdb\x29\x31\xc4\xc8\x43\x77\xaf\x3f\xae\xad\x93\x89\xad\x83\x1f\x6a\x33\xfb\x7d\x31\x4b\x71\xad\x3b\x8d\x10\xd5\x21\x51\xe5\xb1\xb0\x5a\x2f\x45\xbb\xa9\x3c\x08\x8a\xf0\x58\x45\x56\x78\xb7\x9f\xd6\xf6\xca\xfd\xa1\x44\x8a\x6c\x10\xec\xf8\x7f\x17\x50\x1f\xe0\x72\xfb\xa1\x1a\x5d\xf2\xad\x94\xde\x4d\x71\x2c\x3a\x11\xe0\x75\x93\x7c\x9d\xa7\x09\x95\x0e\xc7\xea\xcc\x94\xc7\xd8\x92\xe9\x69\x53\xe7\xdd\xb2\xdc\xec\xaf\x33\x43\x08\xcf\x18\x61\xe0\x90\x3c\x15\xa0\x54\xa1\xdd\x8f\x42\x0b\xe0\xb7\x30\x12\xf0\x1a\x0f\xfb\xc5\x13\x6a\xce\x3f\x6e\x57\x5f\x0f\x8f\xeb\xa7\xc3\xe3\xfa\x66\xb3\xbd\xf1\xe3\xf2\x88\x23\x75\x68\xb9\x5f\x79\x45\x2c\xc2\xf3\xd8\x16\x6c\x5a\xe8\x6c\x29\x68\xe6\x90\xd5\x0f\xc9\xc0\xa9\xa6\xf6\x33\x76\xfa\xa3\x73\x50\xb8\xb4\xf4\x99\xc8\xa3\xef\x6e\xba\x10\x94\x0b\xce\x11\xd9\x7b\xb8\x54\xbe\xab\x60\xdf\x9d\xd9\x4f\x55\x26\x86\xc1\x99\xe7\x03\x5b\x55\x37\x56\xa7\x56\x51\x66\x59\x74\x6d\xdd\x47\x28\x61\x47\xe4\x1a\x24\xb8\x72\xe8\xba\x7b\x79\x7c\x29\x06\x05\x76\xc2\x21\x95\x08\x7f\x3d\x20\xca\x0b\x1b\x8c\xb7\x75\x13\x94\xcc\xde\xe9\x14\x4d\xbf\x15\x14\x45\x45\x0b\xe7\xb6\xf0\x15\x9a\xff\x1b\xbc\xbd\x3f\x83\x41\x92\x2f\x92\x3b\x77\x3f\x45\x15\x2e\x4c\x0b\x15\xfb\xa6\xd4\x45\x75\xb5\x3f\x60\xa8\x60\x03\x50\x7b\xdf\xef\x2d\x97\x99\x60\x01\xe1\x26\xe1\x38\xc8\x14\x55\xfb\x32\xb3\x43\x22\xdc\x64\x1c\xfb\x50\x2f\xc2\x8a\x33\xed\x2e\xb2\x55\x4d\x71\xbe\xf6\x8b\xed\x47\xe2\x28\xcb\xa5\x75\x29\xe8\x93\x25\x5c\x94\xa7\x5c\x80\xeb\xb1\x53\x4c\x54\x84\xa8\x89\xfb\x5a\x5f\x4a\xf0\x8b\xe3\x2c\x91\x89\x69\x44\x30\x3f\x44\xaf\x84\xcd\xfd\xfa\xb0\xfe\xe3\xf1\x6e\xfb\xe4\x2b\xda\x31\x65\x11\xd6\x7d\xde\x27\xc2\x57\xef\x6a\x4c\x53\x89\x58\xaf\xd5\x9f\xb7\xf7\xe1\x1c\x86\xf8\xaa\xe5\x6d\xd1\xb4\xdd\xce\x62\xfc\xfb\x2d\x08\xf5\x3a\x87\x71\x09\xc2\xf6\x70\x37\x3c\xec\x9e\x1f\x1f\xef\xfe\x1c\x8e\x59\x82\x77\x3f\xbe\xa8\x8e\x28\xe7\xe3\x8f\xb1\x24\x8a\x1d\x6a\xc8\x77\x6c\x2d\x0a\xf3\x43\xdc\xcd\x68\xa3\x8a\x39\xa5\x08\xd1\xf6\x90\xc8\xa0\x89\xf4\x61\x25\x3c\x7c\x50\xe3\x93\x76\x53\x70\xd5\x08\xf9\x97\x53\x70\x88\xb0\x63\x9e\x10\xec\x24\xf4\xdf\xbb\xac\xc7\xce\x53\x24\xe6\x1a\x10\x35\xf6\xf0\x7c\x77\x77\x58\x5b\x3d\xc3\x3e\x4e\x58\xdc\x7d\xd9\x3e\x6d\xf6\x5f\xef\x0f\x37\xeb\xdd\xea\x69\x63\xff\xfa\xfc\xb4\x39\x78\xe6\x14\x89\xb9\xe1\xa9\x95\xc3\xf9\xc1\x1c\x4a\xfd\xd1\xc3\x79\x48\x1c\xa7\x0a\xa9\x34\x25\xf6\xc7\xc6\x50\x1f\x12\xc7\x2a\xb5\xd2\x07\xf0\xc3\xa9\xc9\xa9\x9a\x86\x83\x9a\x63\xd7\xfe\x76\xf3\xb0\xdf\xdc\xde\x3d\xef\xbe\xfe\xbe\xf0\xc7\x92\x98\x60\x1b\x06\x9c\xee\xdb\x48\x53\x85\xc4\x89\xb1\xdc\x96\x5b\x40\x57\xd9\x70\xc2\x94\x4b\x36\xa0\x60\x2c\x07\x6c\xb2\x94\xc5\x69\x4c\x33\x17\x5f\x4e\x3d\x92\x3f\xcd\xe1\xe2\x54\x68\x74\xfb\xc6\xd5\xf3\x10\xbe\x4e\xc5\xca\x41\x70\xff\x79\xd1\xc7\x59\x19\x3c\xce\x92\x0c\x81\x81\x5f\xa0\xfb\x06\x4d\x3b\x60\x29\x49\x9c\xe5\xa9\x72\x0b\xb2\xe3\x21\x8e\x9e\x62\x26\x28\xae\x7e\xd2\xea\x21\x7e\x90\xd0\xcd\xb0\xda\xa3\x8f\xcb\x84\x39\x78\xce\xb2\x28\xcb\x11\x8f\x85\xc4\x79\x96\x5a\x45\x95\x4b\xd9\x5d\x1a\xd8\x37\xe2\x07\x94\x88\xa4\x09\x26\x52\x61\xa8\x54\xf8\x00\x56\xdb\xfb\xc7\xc5\xc3\x9f\x87\xc5\x6a\x15\x3c\xd8\xf1\x30\xe0\xb2\x7f\xbf\x79\xd8\xdc\x3f\xdf\x1f\xfe\xdf\xf3\xf6\xe9\x39\xbc\x9e\xb9\x4e\x88\x2b\x56\xee\xa0\x2c\xa1\xd9\x15\xc7\x2b\x62\x6a\x24\x16\x2c\xc1\x90\xb7\x43\x4c\xdb\x6c\x6a\xff\x9b\xfd\xcf\x3b\xbf\xa2\xd1\xd6\x13\x8b\x94\x62\xc8\xf1\xb3\xdf\x4a\xfa\x8d\x89\xf8\x44\x25\x16\x22\xf6\xc6\x36\xbb\xe2\x58\x0d\x86\x7d\x3e\x5e\x8b\x85\xd6\xe8\x6b\xdd\x87\xd8\xc4\x7f\x4c\x52\xdb\x65\xf9\x32\xa4\x30\xbb\x4e\x74\xb0\x16\x4d\xf9\xb6\xc7\xb4\x49\x74\xa0\x97\x6f\x7b\xa8\x44\xd5\xed\x40\xdd\x80\x4f\x39\x62\x9d\x18\x16\x0f\x41\xa4\x53\x6d\x46\x03\xb0\xf9\x12\xa9\x95\x05\x59\x9c\x8a\xea\xf6\x52\xe9\x4d\x35\x62\x71\xf4\x47\x15\x3e\x25\xeb\x01\x3e\xc9\xe6\xe8\x6c\x62\x1a\x69\xbc\x6e\xe7\x6d\x53\x3b\x0d\xff\x65\x5d\xbf\xce\x62\x9c\x24\xa2\x11\xf2\xcf\x77\xfb\xe5\x66\xbc\x2e\x24\x91\xb0\x5c\xfb\x16\xba\xdf\xdf\xd4\xfb\x1b\x95\x90\x28\xc2\xd4\xc1\x4e\x96\x87\xa0\xc3\xdd\x1f\xd1\xe8\x7a\xfe\x6d\x8b\xd2\xd5\x8f\xeb\xa7\x21\x10\x49\x28\xc9\xad\xda\x39\xc0\xf7\x31\xea\x71\x51\x96\x61\x08\xcd\x70\xbb\x6c\x6b\x13\x54\x24\x9f\x9c\xe0\xed\xec\x8e\x25\x54\x58\x2f\x08\xdb\x4e\x1b\xdb\xce\x4e\xe3\xf0\x84\x29\x85\x6b\x00\x76\x34\x46\x5c\x2a\x92\x70\x06\x08\xf1\x0e\x46\xa1\xeb\x6f\xdb\x29\xb6\x96\x24\x3c\x23\xbe\xe3\xb9\x44\x7d\xf2\x7b\xf1\xeb\x7a\x28\x9c\xf0\xdc\xea\x98\xdb\xa8\x71\xea\xa1\xfd\xd1\x7f\xa7\x97\x1a\x53\x89\xe4\x2b\x6b\x51\xfc\x54\x97\xe5\xcd\xb8\x2b\x31\xbd\x01\x71\x42\xad\x2d\x5d\x71\x6e\x9f\xbc\xc7\xed\xe4\xbc\x7e\xa0\x60\xcc\xe9\x6f\x0d\x35\x16\xdc\xe3\x6f\xeb\x66\xa3\x66\x19\x77\x92\x50\x1d\xc0\x15\xb8\xad\x5f\x29\xdd\x24\x49\x42\xa4\xaf\x45\x2f\x8e\x0d\xc0\xd0\x8f\x75\xe5\xfa\xab\x49\x51\x92\xc8\x38\x76\x6d\xd6\xe0\x73\xf3\x55\x94\x3f\x8a\xea\xd8\x87\x29\x85\x7e\x87\x66\xf0\x1f\x54\x44\x7a\x2e\xa7\xa3\x3b\x5f\x5d\x99\x93\x54\x59\x36\x54\x9f\xbd\xfc\xba\x46\x64\x25\x49\xaa\x63\xc4\x0a\x38\xf2\x28\x62\x39\xfc\x9c\x48\x8d\x6d\xea\xf7\xfb\xc1\xaf\x73\x59\x37\xb0\xe9\xe0\x34\x3b\x41\xa6\x45\x26\xbc\xbd\x9b\x13\xbb\x9e\x1b\x1f\x4b\x92\xe4\xb9\xc5\x4b\xae\x46\x8b\x79\x22\xb8\x6d\xa1\xdb\xdd\xef\xb9\xb2\x54\x2f\xff\xf5\x22\x4b\x70\x63\x6d\x2f\xa7\x93\xf0\xe2\xda\x24\x11\x92\x21\x22\x0f\x3c\xab\xde\xd1\x51\x7d\x05\xff\x7a\xd8\x9c\x08\x23\x50\x32\x65\xbb\x7a\x11\xa1\xd5\x9d\x48\x62\x8d\xb5\x07\xd9\xc9\xdb\x02\x4a\x4d\xc3\xf1\x8c\xa3\xcc\x6a\xdb\xdf\x02\xfb\x6e\x20\x71\x7b\xfc\x2b\xa4\x8e\x11\xc0\xe8\x45\x20\xcb\xba\x6d\xc7\xc5\x98\x44\x45\xb9\x89\x3c\xa7\x6c\xd3\xb6\x97\xfe\xa5\xc0\x14\x74\x7a\x89\x2a\x07\xac\xdf\x9a\x12\x7e\x15\xb2\x8f\x21\x07\xc8\x15\x49\x74\x94\x61\xf8\xf3\x54\xd7\x5d\x3b\x59\xa5\x74\x04\xf8\x56\x6f\x96\x5f\xae\x39\x50\xce\x26\x85\x26\x31\x8e\xae\xea\x7e\x61\xfd\x0e\x05\x76\x20\x86\xaf\xa1\x54\x38\xb0\xc2\xf9\x11\x0b\x79\xed\x70\xc8\x5b\xfd\x54\x15\x34\x56\xce\x2d\x1c\xcb\x12\x6a\xe9\xed\xbf\x36\xab\xed\x04\xde\x93\x68\x4d\x98\x15\x80\x6a\xe1\x77\x68\x2a\x08\x8b\x9c\x06\xcb\xe5\x5a\x41\xbf\x9f\x94\xe5\x1b\x2a\xf8\x4e\x5b\xad\xd7\x6b\xb5\xb3\x1f\x05\x42\x20\x39\xfe\x11\xba\xf6\x4a\xa3\x36\x31\x5c\xa0\xb2\xee\x97\x47\xe1\x0d\x45\x48\x1a\x45\x80\x98\x5a\xb4\xad\x76\x8f\x7f\xa6\xc8\x44\xd2\x28\x4d\xf0\x12\x6d\x8f\xfb\xb1\xa9\x6b\xe3\x94\x38\xb0\xa2\x36\x79\xa5\x53\x92\x71\x84\x32\x3e\x3c\xdf\x1f\x56\xdb\xcd\x03\xe6\xa0\x8b\x3f\x36\x3e\xbc\x4f\x89\x00\xc4\xf7\x43\xf7\x32\x98\x1b\x91\x94\x48\x92\xd9\xd2\x5f\x71\x3c\x42\x33\x42\x70\xf9\x01\x1a\xc0\x0a\x84\x40\xb7\x12\x1d\x1c\xeb\xa6\x80\x77\x75\xd8\xe9\x4d\x49\x29\x49\x90\x2a\x75\x2a\xaa\xce\x17\x91\x9a\xdf\xe6\x20\x8b\xe9\xcf\xa5\x8c\x22\xba\xa8\xdf\xf9\x1f\xa1\x69\x85\x73\x96\xf3\x17\xc2\x78\x82\xac\xd1\xa1\x38\x3e\xd6\x3e\x26\x29\x4f\x19\xb7\x22\x1c\xd8\x49\xc0\x1b\xe5\x23\x88\x34\x16\x56\x5b\xcf\x12\x90\xf6\x9b\xf5\xd3\x81\x1d\xee\x36\xf7\x1b\x1f\x39\xa5\x49\x64\x9d\x26\x54\xdd\x76\xe3\xaf\xed\x17\x59\x0c\x59\x84\x6d\x20\x3e\xd4\x77\x75\x75\x44\xc9\xe1\xb1\x95\x8b\x1f\x2d\x22\xcc\xf3\x9f\x84\x94\x45\xb7\x68\xa0\x9a\xbd\x6a\x69\x46\x35\xee\xae\xdd\xb1\xb1\x55\x5c\xff\x45\x39\xa5\xb8\x4c\xd4\x55\xf9\xf6\x54\x97\xb3\x7b\xec\x1b\x43\x69\x9e\x65\xb8\xbf\x3d\xad\x77\xeb\xa7\x6f\xeb\x9b\x83\xd7\xf7\x19\x7a\x7d\x69\x6e\x6c\xd1\xe7\x4b\xec\xff\x22\xf2\x0c\x2b\x9e\x23\x7d\xe7\x7d\x3d\x30\x94\x26\xb0\xf5\x7e\x34\x60\x87\xca\x99\x0e\xe3\xea\x7a\x9a\x11\xcd\x48\x2a\x04\xc1\x8d\xfb\xe0\xc5\x9b\x1f\xe0\xa7\x93\x79\xf3\x23\x94\xc6\x48\x5c\x05\x66\xe9\xac\x71\x94\xca\x9c\x63\x69\xa0\x83\xb6\xdb\xbd\xb5\xfd\x22\xef\x8e\x28\x66\x2c\x33\xd3\x5e\x83\x78\xdf\xdc\x4d\x55\x22\x64\x36\x78\x2d\x88\xd2\x76\x9d\x66\xa3\x74\x9c\xe3\xaa\x63\x5d\xbb\xc7\x36\xae\xb3\x49\xab\xb3\x84\x23\x4f\xec\x5c\xb4\xb5\xfe\xbc\x16\x92\x6a\xc3\x48\xe2\xc1\x76\xc8\xe3\xfa\x14\x4a\x4a\x52\xc8\x14\x37\x01\x9d\x73\x5b\x37\xe7\xf2\xd2\xd5\x55\xa1\xc2\x5d\x07\xe9\xca\x41\xd6\x9e\xe4\xa5\x28\xcb\xd9\x4f\x31\x91\x22\x6a\xdc\xc8\xfb\x0e\xc5\x00\x46\x4a\x4d\x6c\x43\x8c\x75\xd5\x41\xb3\x1a\x79\x52\xfb\xe3\x8a\x79\x93\x3d\x47\x4f\xf7\xe0\xa3\xe9\xc0\x2c\x22\xd6\x96\xe7\xe0\x44\x7c\xc6\x68\x05\x37\x84\x24\x06\x3b\x6e\xfb\xf5\xbd\x5b\x8e\x3f\x5d\x11\x32\x92\xc7\xd8\x07\x16\x5a\x2f\x3a\xc7\x15\xf8\x6d\x22\xac\xf9\xa1\x9b\x69\xff\xe1\xc4\x3a\xa6\x43\x05\xbf\x8a\xf1\xaa\x90\x11\x91\x19\xe5\xd1\x2a\xb3\x34\x37\x23\x9a\xa1\x66\xd6\x97\xfb\x5b\xff\x27\x9a\x00\xb8\x0c\x04\x19\x28\xcf\xe7\x5b\x80\xe5\x1b\xfe\xff\xec\x27\xd2\x3c\x65\xd9\x54\x78\xad\x6e\x5a\x1b\xf6\x5c\xad\x58\x66\x5c\x02\x92\x9a\x74\x23\x8a\x0f\x00\x0c\x59\x9c\x65\x66\x50\xca\xfd\xd2\x88\x1f\xa2\x13\xcd\xdc\x96\x9c\x64\xb1\xc8\xd0\xbc\xd6\xd9\x98\x4e\x31\xc7\xb3\x73\x26\x00\xd6\x16\x0e\x44\x09\x4d\x60\xc2\x90\x2c\x25\x56\x55\xf0\xd8\xd4\x3f\xbb\x97\x89\xf6\x2f\xc9\x52\x2e\xf1\x0d\xdb\x3c\x7c\x5b\xef\xf6\xf7\xeb\x87\xfd\xe1\x79\xb7\x7e\x22\xe1\x78\x9e\xe1\x8c\x75\x46\x27\xa1\xaf\xea\x0f\xcb\x44\x3a\x98\x0d\xd6\x76\x30\xf0\x98\xc6\xf6\x59\x2a\x35\xb5\x8d\x96\x47\x71\x19\xb6\xfa\x2c\x23\x14\x53\xa9\xdf\xd7\x7f\xee\xfe\x92\xb0\x4b\xb2\x4c\xa5\xe8\xdb\x6d\x00\xee\x6b\x1d\xce\x9e\xc7\x99\x4f\xd7\x3a\xac\xe5\x4c\xf6\xdf\x6b\x5d\x7f\xff\x41\xa1\xb1\x6f\xd4\xaf\x3a\xeb\xa6\xa9\x9b\xe7\x2a\x88\x8e\x69\x6c\x4f\xcc\x7f\x6c\x6e\x34\x6e\x2e\x68\x6d\x3e\x3d\x99\x88\xa8\x77\x19\xb6\x00\x82\x76\x5c\x88\xcd\x44\x4a\x7c\x24\xec\xee\xff\x7c\xa1\x08\x03\x33\x18\x29\x27\x2c\xa1\x9b\xf4\xf1\x32\x61\x38\x30\x07\x54\x98\x69\x9a\x7d\x56\x8a\x70\x9f\x96\x4a\x70\xbb\x14\x5f\xaa\x6e\x21\xdb\x0e\xaa\x11\x8d\x94\x64\x2a\xc9\x78\x1a\xf8\xdd\xcf\x63\x19\xe7\x30\x46\x47\x2a\x73\x2d\x73\x74\x3d\xfa\x5e\xe8\x6e\x7e\x37\x34\x24\xb8\xbd\xad\x2b\x1d\x3c\xfb\xdc\x21\x88\xec\x72\x7d\x5b\xd7\xd3\x4e\xca\xbb\xe7\x03\xdc\xc4\xce\xeb\x04\x2a\xfd\x3b\xbc\xd9\xa0\xf6\xda\xef\x02\x43\x10\x44\x68\x41\x6d\xe3\x08\x3b\x03\x63\x50\x3e\xe4\x8b\x55\x60\x59\x89\xae\x5d\x68\x0d\xce\xff\x2b\xfe\x37\x49\x1c\x06\x24\x33\x24\xc7\x76\x1a\x12\x71\x5b\x07\x08\xb4\xc7\xf2\x28\x4e\x69\x1a\xf2\x36\x57\xf6\x9a\xef\x0d\x93\x58\x2c\x8f\x92\x4c\x8d\x00\xa8\xdf\x07\x7b\x65\x92\x13\x6a\x6b\xbc\x08\x27\xb1\xdb\x6a\x57\x2f\xef\xae\xef\x32\x39\xc9\x18\xca\x27\x7d\xad\x75\xe9\xe4\xbb\xf4\x28\x01\xc8\x69\x64\x15\x52\xd0\x28\x18\x36\xaa\xb6\x36\x9d\xfe\xa8\xb6\xa9\xb0\xbc\x34\x61\x1a\xe5\x8c\x09\xdf\xca\x5d\x94\xe5\xee\x45\x34\xa0\x9d\x96\xc6\x0c\xfc\x90\x33\x4e\xb0\xda\x6a\xb7\x1b\x25\x4a\xb0\x04\x99\x70\xaa\x44\x21\x90\xd9\xb5\x9d\xb7\xd5\xb1\x1e\x3a\x4f\x39\x8f\xac\xfd\xe8\x11\xba\xe7\xd3\xab\xb8\xba\x62\xe6\x89\x10\xd2\xca\xf8\xa1\xd9\xe1\x52\xb4\x53\xc4\xaf\x1f\x66\x18\x32\xbb\x7e\x42\x71\x57\xfc\xe7\x12\x02\xe9\x3c\xa5\x31\x4a\xd0\xf4\x0b\xd0\x07\x71\x74\xde\x07\x65\xd6\xb1\x28\xdc\x84\x34\xcf\x53\x31\x71\x06\xff\x13\x44\x83\x7a\xfe\xb8\x86\x8c\x60\x28\xee\x13\x59\x6a\x55\x76\x1e\xea\x4e\x34\x6f\x8f\xa5\xe8\x4c\xdd\x9c\xc6\x5b\x51\x9e\xe5\x02\x19\x13\x81\x7e\x76\x2b\x34\xd4\x97\x6e\x5f\x87\xee\xcc\xf0\xae\xfe\x3b\xff\x1f\xff\x31\x30\xa8\x64\xe5\xfd\xd4\x8a\xea\x78\x5b\x5b\xe1\xd4\xd9\x2a\x94\xe7\x79\x8e\x1a\x64\xa5\x33\x37\xf1\xf8\x9a\xe9\xa5\x0a\x1e\xf3\x31\x94\x42\xaf\x87\xd9\x2c\x62\xab\x02\x7e\x2e\x85\x82\xed\x19\x2a\xdf\xd1\x9a\x14\x4a\xfc\x60\x19\x61\x92\xec\x83\x46\xac\x86\xdd\xe3\x02\x11\x52\xac\x5c\xc8\x9c\x3b\xd3\xc3\xe5\xa5\xa9\xf6\x5e\xbc\xd9\x1f\x97\x24\x46\x37\xaf\xdb\xa2\xea\x2c\x58\xbd\x7d\xbc\xc8\xb2\x50\x61\x00\xb5\xfc\x43\x6b\xf7\x7f\x2b\x8a\x12\xb4\xd3\xbd\x99\x2c\x80\xb9\x54\x11\x26\xf2\x5f\x9a\x42\x6b\x18\x7e\x93\x8a\x4c\x0c\x23\xf6\xcc\x6d\xdd\xac\xea\xd3\x19\x5c\x77\xe9\xaf\x8a\x3f\xd7\xe2\x96\x0f\x0a\x27\xb9\x26\x8c\x5b\xc1\xd0\x1f\x45\x0b\x0f\x97\xd3\xbb\x0e\xfb\x74\x25\xcb\x35\xcf\x49\x10\x20\x3a\x9d\x3b\x38\xd0\xc9\x36\x9f\xeb\x84\x59\xcf\x4d\x47\xa9\xbe\x26\xa5\x40\x72\xa0\x59\xe6\x0a\xd3\x87\x73\xbf\x93\xae\xbe\x8f\xcb\x19\xb9\x61\x11\x0c\xa6\x11\xbf\xff\xb9\xba\xfe\xb6\x19\xe1\xe2\x84\x7a\x77\x51\x0a\xa0\xcf\x93\x3c\xdc\xc0\x0f\xd1\x10\x8b\xb0\xa2\x4c\x91\xe0\xd3\xb3\x89\x28\xe2\x91\x2b\x72\x0a\xd5\x41\xa5\xcb\xf0\x2e\x88\x28\xb6\x3b\x76\xbf\x35\x2f\x37\x7f\xfc\x3d\xe4\xbe\x88\x5c\x70\x86\x72\x44\x10\xda\xae\xd7\xf0\x76\xfe\x13\x59\x84\x28\xae\xba\x9f\xbe\xc8\xc0\x6e\xa6\x8b\x98\x20\x44\xa1\x30\x4a\xd7\x88\xf6\x65\xaa\x0f\x45\x04\x61\x56\x12\xc6\xf2\x39\x67\xea\xa7\x7e\x8c\x64\x5e\x88\xfa\xa0\x5e\x9a\x11\x54\x42\x50\x69\x5b\x55\xd6\x7a\xdc\x36\xb3\x56\x8b\xc7\xc3\xf6\xf6\xd0\xa7\x64\x7e\x18\xa3\x39\x22\xac\x6a\x6c\xfe\xf5\x8b\xc1\x18\x27\x20\x18\x87\xc8\x85\xc6\xc8\x78\xfb\x1c\x38\xe4\xfe\x3d\x9e\x44\x82\xa9\xc4\x76\x97\xdd\x86\xfd\xae\x8b\x2f\xe2\x24\xc2\xf2\x80\xd0\xfa\xb0\x5d\xfb\x86\x80\x48\x92\x14\xd1\x95\x45\xdb\xbf\xbb\xae\x33\xe3\x8f\x65\x44\x59\xc0\x32\x82\x1f\xf0\xe5\x5f\x20\x0e\x4a\x8c\x89\x62\x22\x11\x06\x9b\x30\x1a\x54\x29\x9a\x91\x9a\x03\x11\xa9\x8a\x22\x67\x15\xf4\xe2\xf0\xe6\xa0\xdf\xe1\xf3\x3e\x9f\x13\x19\x05\x2c\x50\xfc\x53\x08\xdf\x3e\x14\x99\xa4\x38\x49\x9b\xb1\x3c\xd2\xbe\xbe\x17\x85\x97\x85\xf2\x23\xf3\x84\x60\xf1\xff\xe6\x7e\x7f\xc0\x9b\xbe\xbb\x0c\xe5\x21\xd1\xef\x02\x58\x32\xa8\x5f\x67\xd1\x98\xc8\xa5\xf6\x16\xfd\x4e\xdf\x7d\xd3\x4e\xa1\x15\x22\x37\x36\x42\x3f\xcc\x81\xf0\xff\xe6\x73\x2a\x8d\xfb\x84\x48\x34\xd6\x8a\x9c\xdb\x46\x55\x74\x63\x3b\x7b\x22\x84\x4a\xa8\x83\xfd\xef\xea\x4b\xa5\xd7\xc6\x80\x9a\xa2\x93\x32\x0f\x5c\x15\x32\xca\xf3\x7c\x48\x17\x7f\x2f\xd4\x6b\x6d\xcc\xff\xbb\xd4\x4d\xe0\x74\x09\xc5\x53\xbc\x79\x21\x45\x5f\x8a\xfe\xe7\xb8\xf2\xde\x65\x00\x78\x87\xd7\x45\x73\xc5\xb3\x20\x2b\x85\x8c\x39\x8f\x26\x6a\xaf\xa8\x80\x13\xa1\x15\x45\x1c\xa4\x7b\x0a\x37\x4b\xff\xdd\x90\x47\x24\x0d\xeb\x7a\x2b\x42\x83\x41\x40\x9e\x61\xa7\xb9\x14\x6d\xb7\x6f\x60\x80\xcf\x09\x03\xb9\xef\x7a\xdc\x8b\x5f\xfe\x02\xc6\x11\x81\x35\x37\x99\x4c\x11\x49\x05\x18\x8f\xf1\xd9\x20\x50\xc2\x05\xc8\x9b\xaa\xab\x57\xa2\xf1\xb3\x41\xb2\x28\x66\xc1\x0b\x4a\x28\x0b\xfc\x1c\xda\x20\xb7\x0d\xc0\x67\x79\x96\x64\xda\x8a\x5f\x63\xc9\xda\x9f\x34\x8e\x19\x16\x8b\x45\xff\xf6\x88\x0e\xd0\x07\x62\x76\x85\x49\x66\xd0\x72\xdf\xeb\x44\x8c\xc0\xfa\x32\x11\x09\x68\x1f\xd7\xc3\xa9\xa8\xae\xac\xb8\xb3\xeb\x48\x04\x20\xfc\x7f\x77\x77\x3f\x8e\x40\x64\x9a\x5b\xbd\xfb\x16\xba\xdb\xe2\xf8\xe2\xf8\xcc\xe3\x74\x44\xa6\x2a\xf3\x2a\x01\x6e\x89\xc5\x1e\xc4\xfb\xa5\x55\x66\x34\xc7\xba\xea\x01\x87\x5a\x22\x73\x3f\xec\x6b\xd1\x06\x92\xf4\xfc\xb5\xf5\xdf\x92\x27\x06\xc9\xb0\xc7\xe2\xc7\xec\x8e\xce\x63\x7d\x99\x43\x8a\x9e\x6d\x02\x25\xf1\xb7\xe6\xca\xca\xe0\x46\x8a\x44\x58\xa0\xaa\x35\x1d\xe9\xaf\x7d\x5a\xb7\x92\xfd\x6a\x64\x7f\x7f\xf3\xa3\x50\xf0\xa5\xa9\x2f\x67\x27\xdb\x70\x6d\xb7\xf7\x57\x2b\xb9\xf6\xa6\x26\xbf\xde\x26\xfe\x24\x93\xad\x44\xca\x38\x8b\x5d\xa8\x33\x29\x41\x4b\x19\x1b\x8d\x11\x88\x5d\x20\x6e\x40\x0e\x87\x52\x88\xfa\x3b\xf1\x03\x9a\xc0\xe8\x7d\x84\xa6\xa8\x75\x18\xa1\x6c\xad\xb4\xae\xca\xb7\x65\x7d\xa9\x14\x34\x3b\x34\x6e\x70\xca\xf1\xc3\x36\x2f\xa5\xe6\x56\xc5\x03\xcb\xe0\x57\xc9\xc4\x44\x2a\x65\x6d\xd3\x9d\xc9\xbc\x0d\xec\xdc\x31\x9d\x26\xc8\x7e\x3b\x89\x5f\x63\x13\x87\x51\x19\x55\xea\x54\x62\x92\x87\x28\x90\x71\xff\x53\x82\x64\x28\xa9\xf2\x50\xdb\x9d\x02\x7f\xcb\x48\xe5\xc8\x3f\xe1\x91\xec\x69\xfa\x3f\xd3\x70\x6a\x74\xcc\x9d\xd4\x44\xb1\x87\x61\xff\xb3\x96\xed\xb2\x1e\x2d\x4c\x76\x88\x8a\x20\xb2\x92\x82\x58\xe6\x0b\x5f\xc3\x86\xaf\xf1\xfc\x53\x15\x19\xaa\x5d\x43\xa4\xbf\xb0\x40\x13\x73\x3f\x41\x91\xc4\x86\xe8\xde\x44\x69\x0a\xc7\x54\x24\xb7\x64\x85\x3b\xe8\x36\x98\xcc\x3b\xa9\xbe\xfa\xe4\x11\x28\x8a\xb2\x14\xa9\xb8\xa7\xb7\x7b\xe8\x5e\x6a\x3d\xd1\xbb\xed\x0f\x2b\xac\x96\xf7\x81\xd3\x78\xd9\x6a\xc3\xe7\xe3\x18\x2b\x32\x83\x0a\xd3\xf5\xd9\xae\x58\x64\x59\xde\x2d\x74\xdf\x2c\xa6\xbe\xa8\x07\x11\x72\x67\x56\x44\x92\xf7\x24\xc3\xd1\xbf\x49\x38\x19\x95\x23\x7b\xa6\x45\x75\x84\xf2\xce\x7b\x9f\x26\x7c\xd4\x52\x54\x4c\xe5\xd8\x3c\x46\xc2\xb8\x68\x01\x37\xcd\xef\xd6\x9d\xc1\x1a\x0d\x4d\x2f\x93\x4b\x1b\xe8\xb9\x32\xed\x9d\xf8\x69\x2e\x65\x85\x40\xfa\x51\x55\xcf\x0d\x8e\x4d\x9e\xbb\x36\xee\xc2\x98\xa2\x2c\x44\x77\x25\xa8\x53\x09\x85\x6c\xd0\xb0\x76\x6b\x79\x51\x57\xcf\x55\xd1\x71\x7f\x23\x93\x98\xa4\x22\x88\x77\xd8\x52\xfa\xd6\xf8\x0a\x8c\x1b\x94\xb2\x98\x3a\xb9\x9c\xdf\x41\x29\xf1\x4a\xe3\x64\xf6\x65\x99\x50\x98\xe4\x9c\x8a\x0a\xe5\x42\xc2\x53\xf3\x6f\x84\xca\x23\x83\x64\x6f\x0c\xce\x8a\xea\x88\xf0\xa1\xc1\x34\x86\xa8\x5c\xa9\xc4\x45\x88\xbb\x25\xea\xb6\x85\x23\x06\x30\xbe\x42\xe1\x47\xff\x47\xc1\x24\x26\xc6\x87\xc2\x39\xd0\x84\xcb\x95\x91\x46\xf2\x14\xfc\x3a\x17\x41\xa3\x9d\x28\x49\x93\xd4\x77\x43\xc3\xdf\x38\xc5\xdd\x55\x0e\xc5\xc9\xe7\xc7\xe1\xa0\xd3\x9d\xb7\x98\xd4\xd0\x3f\xfc\x29\xce\x9b\xea\xff\x6a\x0d\x4e\x94\x8c\x53\xee\x76\x65\x44\x5c\x3c\x0e\x86\x22\xe1\x0d\xc3\xfa\xdb\xb9\x84\x99\xa2\xe6\x67\xd4\x1b\x25\x73\x4e\xe3\x61\x41\x3f\xbc\x16\x21\x46\x50\x8a\x68\xeb\xb2\xec\xec\x4d\x2a\xbd\xbc\xf4\x19\xc6\xec\xe9\x29\x96\x69\xf7\x96\xec\x5e\xea\xa6\x7b\xec\x07\x17\x75\xb5\xc6\x3b\xa8\xc3\xd9\x38\xc3\xa8\x06\xd3\xde\x71\x3d\x46\xa9\xd4\x4a\x1e\xf7\x89\x0a\x6a\x40\xcf\xc5\xba\x89\xd2\xd4\xaa\xe3\x5a\x8b\xba\x0f\xe4\x01\xfc\xd8\x34\xd7\x4e\x4d\xa5\x7f\xc3\xc5\x34\x0d\x9b\xbd\xe2\x5a\x02\x96\x21\xd7\x77\x7b\x2f\xe4\xa0\x20\x12\xb9\x74\xd4\x02\x8b\x9c\x1d\x03\xe7\x14\xc8\x14\x7b\x14\x76\xb7\xfc\x8c\x1c\xed\x3f\xa0\x35\x52\x01\x1f\xc5\xdb\x23\x34\xaf\xe3\x70\x41\x01\x30\xec\x8e\xa2\xbd\xf5\xd6\x38\x19\xa9\xb9\x5e\xa5\x1b\x6c\x78\xe4\x26\x81\xeb\xcb\xb5\xfb\x7a\x5b\xc1\x5c\xdc\x72\xf2\xed\x3a\x8a\x12\xc4\x99\x59\x51\xca\xcd\x6a\xfb\xdb\xfc\x78\xca\x86\x75\xe9\x5e\xfc\x7a\xb8\x9c\xee\x57\xf3\x41\x31\xc7\x40\x64\x07\x95\x5e\x9f\x44\x51\x5e\x2b\x04\xea\x28\x51\x78\x67\x4e\x88\x96\xf8\x2a\xfa\xc9\xd2\xcc\x39\xc7\x3a\x92\x16\x69\xd5\x42\x59\x4e\x48\xf5\x3a\x32\x12\xb1\xa0\x97\x46\x54\xc5\xe5\x74\x2e\x2f\x93\x56\xb7\x26\xc4\x2a\x6c\xf4\xeb\xb1\x43\xdd\xff\x45\x02\xf3\x09\x24\x50\x93\x54\x21\xc8\x7e\x10\x4e\xba\x22\x2a\x42\x34\x11\x04\xfb\xf2\xea\xd2\x3c\x81\x99\xf4\x0b\x35\x31\x80\xf8\xcb\x93\x43\x31\xde\xfc\xe1\x9b\x1c\x9a\xb2\x14\x97\xfb\x7f\x5e\x4e\xd2\x2e\x31\x9f\xcb\xcb\xfb\x8f\xa5\xc0\x1c\xb7\x72\x77\x12\x65\xf9\xde\x39\x8a\x68\x06\x02\x3b\xd7\xfd\x06\xd7\xce\xfa\x2d\x9a\xc7\x36\xcc\xfd\x5a\x57\xf0\x86\x12\xa4\xb3\x92\x92\x8e\x09\xc1\x3a\xfa\x57\xf1\xf3\x95\x7e\xa2\xc1\xd8\x8f\xd4\xa8\xfd\x7e\x16\x6f\x7e\x9b\x9a\x9e\x2a\x49\xa2\xc8\x7b\x52\x09\x0b\x10\x41\xe3\x4e\x7f\x58\x50\x13\xb9\x0b\x1d\x99\x31\x11\x9d\x02\xa0\x80\xba\x2e\x5a\x4c\x15\xdd\xca\x55\x0c\x77\x36\x27\x39\x46\xe4\x77\xf5\xd1\x29\xb1\x40\x73\x23\x5d\x23\xe6\x7a\xa5\x56\xe7\x09\xc7\x7d\x13\x54\xbd\xbc\x14\x83\x3a\x14\xd1\xfd\x8a\x8f\xbb\x83\x38\xc1\x17\xaf\xbe\x2e\xaa\xd7\xa6\x2e\xcb\xbb\x21\x36\xd1\x32\xb7\xa2\x93\xdf\xeb\x46\x8f\x34\x11\xb4\x94\x19\x6e\x74\x37\xeb\x6f\xeb\xbb\xed\xe3\xfa\xe9\x70\xbb\x5e\x1f\x1e\xd7\x4f\xab\xf5\xc3\x7e\xf1\x65\x1d\xc6\x81\xc4\xe2\xe0\xe3\x53\x58\x4d\xb4\x82\x88\x04\x89\xfa\x3d\x88\xd3\xbd\x38\x9f\xe7\xa6\x2d\x44\x6b\x63\xe5\xa6\x8f\xd0\xb9\xca\xdb\xf2\xed\x0a\x64\x47\x03\x37\x91\x9b\x20\x98\xb8\xde\x8b\x09\xdc\x69\x7a\x47\x20\xe5\xf8\xee\xdf\x6d\xbf\x1c\x76\xe7\xa2\xc2\xd9\x22\x8a\x0a\x1a\x7c\x4c\x73\xd0\xf7\xe4\x9b\x20\xe2\x31\xba\x27\xb4\xd6\xe5\x01\xf4\x3f\x85\x7a\x3d\xd7\xdd\xc0\x1a\x86\x28\xb6\x51\x02\xfc\xc2\x39\xb8\xb4\xe7\x9b\x72\xf5\xdd\x50\x92\x6b\xac\x51\x06\x73\xa1\xe5\xa5\xa9\x26\x32\x7f\xb3\xf1\xca\x82\x22\x84\xd6\xfb\xda\xd6\xfa\x4f\x30\xda\xec\xa6\x93\x1a\x88\x31\xb8\xa1\xe3\x76\x7b\x0f\x9d\xd0\x7d\x98\x36\x9e\xcd\x40\x63\x6e\x5b\x02\xb5\x7a\x3d\x20\x1a\xc7\xff\x0c\x2a\x08\x56\x08\x2d\xda\xac\xdd\xd7\x18\x71\x2d\xa1\x9b\xad\x05\x40\x95\xc4\xf9\x8e\xe6\xec\x23\xd3\x7f\x02\x14\x08\x36\x8e\xfb\x19\x35\xb6\x24\x0d\x87\xad\xce\xc2\x9f\xcf\x8f\x1b\x9c\x38\xe8\xd7\x37\x2a\x50\xf5\xdb\x80\xe3\x5e\x81\x7a\xbd\x2d\x85\x53\x62\x0c\x41\xa6\x1f\x16\x53\x4e\xbd\x9c\xd7\xf6\xd2\x6d\xcd\x57\x08\xba\x2d\xc0\xd2\x9c\x92\x89\xf6\x8b\xf3\x29\xba\xba\x9f\x00\xd3\xd6\x80\x58\xf8\x3c\xc4\x2e\x80\x93\x92\x2f\xc4\x51\x1a\xd1\xd0\x82\x35\xc5\x71\x07\xdd\xe5\x3c\x97\x14\xf0\x83\x9d\x37\x69\x7d\x86\x6a\x59\xcf\xe6\x2e\xa4\x69\x02\x6c\xb4\xd5\x34\xaf\xd0\xbd\x2b\xf3\x43\xc6\xb8\x0c\xfe\xbe\xe3\x1a\xa4\x85\x07\xf9\xeb\xca\x04\x58\x5d\x3f\x2c\x3f\x59\xa7\xfc\xf9\x99\x94\xc2\x21\xfd\xd5\x7c\xaf\x9b\xd3\x4b\x1d\x72\x2c\xc8\x69\x8e\xef\xdb\xa9\xa8\x46\x01\xe9\x6c\x12\xe6\xb9\xad\x0c\xa3\x66\xd2\xa2\xd2\xab\xba\xfa\x01\x4d\x37\xc2\x60\x8e\x14\x5b\xae\x06\x6e\x90\x4b\xcb\xaa\xb6\x3e\xfc\x8f\xf5\x2b\x9c\xe6\x20\x0a\xc8\x01\x12\x3e\xd8\x08\xd9\x55\xee\xc9\x62\x65\xe7\xcf\x4c\x28\x86\x8b\xdc\xff\xda\x97\x71\xfa\xac\x24\x55\x3e\x93\xbb\xad\x1b\x50\xa2\xbd\x6e\xba\x44\x40\x2a\x05\x9e\x1e\xff\x4b\xd5\xef\x11\xc6\xb3\x3b\xa1\xa4\x65\xbb\x35\xa0\xa0\xf2\x4d\xd6\x65\xb0\x7f\x20\xa0\xd3\x3c\x1e\x53\xe9\x0f\xa2\x2c\x0f\x43\x87\x00\x74\xa6\x72\x47\x61\x3d\xc2\x6d\x7d\x69\xd6\x55\x78\x94\x60\x94\x25\xa7\xd8\x18\x79\xc0\x57\x7d\x0a\x3d\x07\x43\xc1\xeb\x56\xfc\xf1\xf8\xb4\xbd\xdf\x1e\xee\x9f\xef\xf6\x9b\xc7\xbb\xcd\xfa\x69\xc2\xe4\x06\x23\x75\x62\x3c\x52\x04\x1b\x82\x98\x55\xc3\xe5\x14\xf4\x95\x66\xa7\x56\x29\x96\x19\x6a\xef\xda\x3e\xbd\xcf\x06\x00\x35\x43\x45\xdb\x16\xc7\x99\x01\x35\x31\x91\x48\xfd\x52\xbe\x43\xc0\x4b\x07\x1a\xb1\xd2\x4f\x75\xfd\x2e\xee\xf7\x9f\x01\x1e\x79\xda\x71\xe5\x82\x9b\xdd\x88\x02\x6c\x68\x6c\xeb\x5e\xdd\x0b\x84\x62\xe0\xd6\xfc\xf6\xce\x1b\xb4\x1f\x69\xac\x77\xab\x28\xd5\xed\xa5\xbb\x34\x80\xc5\x90\xab\xf7\xd0\xd0\xdc\x0a\x78\x5b\x49\x82\x4b\x59\x9c\x47\x0e\x8f\xc4\x50\x88\x99\xbb\xc5\x9b\x76\xe2\x87\x8a\xf8\xfb\x21\x9a\x32\x8c\x52\x8c\x15\xc4\xcf\x70\xc9\xfd\x5a\xe5\x1a\x2f\x0b\xd5\x5d\xac\x59\x77\x73\x75\x29\x32\x2c\x8f\xc1\x4b\x00\x88\x4b\x0b\xcd\x61\x3e\x40\x32\x24\xe3\xa3\xa3\x60\xe5\x3b\xfc\xc3\x0f\x61\xa0\xb0\xa0\xb9\x13\x06\x44\x3b\xd1\xee\x32\x9c\x5a\x19\xfe\x7f\x15\xdd\xef\xdb\xcd\xc3\xc0\x13\xfa\x8b\xdc\x6b\x76\x63\xb9\x31\x78\xaf\x4c\x51\x76\x43\x82\x6b\x62\x1a\x23\x9c\x5b\x39\x65\xb7\xe9\x75\xc5\x09\xc9\x6c\x29\x48\x5e\x8e\xcb\x4b\x98\x24\xb1\x4c\xb4\x18\x89\x68\xb4\xef\x3d\x28\x88\x49\xa4\x8e\x86\xc5\x63\x53\xfd\xa8\x0b\x35\x23\xe5\x9a\x8c\x44\x38\xc6\xb9\xbb\x3e\xc0\xcf\xed\x3b\x2d\x6b\x62\xb2\x84\x5b\x35\x9d\x42\x9c\xea\x4a\x63\x64\xb1\xaf\xdf\xfb\x73\x13\xe3\x89\xc8\xeb\x87\x7f\x1e\x9e\x1f\x02\x38\xcf\xe4\xb9\x42\x20\x0f\xaa\x48\xdc\xd4\x28\x2c\x23\x87\x94\xda\x88\x2c\xc3\x6c\xf1\xb6\xf8\x05\x7a\x0c\x02\x30\x2a\x4a\xb1\xe4\xb0\x59\x6d\x0f\x77\x7d\x04\x75\x88\xc3\xa1\x34\x4e\x82\x60\xaa\x75\x32\x9c\xc8\xd1\x12\xa3\x32\x8e\xda\xd2\xf7\x8b\x3f\x0e\x8b\x6f\x8b\xcd\xdd\x62\x79\xb7\x3e\xfc\x73\xbb\x79\xd8\x4f\x0a\x47\x46\x89\x3c\x4e\xac\x85\x48\xbf\x15\xa0\xde\xac\xc7\xd1\x18\x20\x12\x8d\x33\x7e\x7a\xc0\x6b\x9f\x07\xf9\x63\x0c\x50\x2c\x40\x5e\xde\x82\x26\xf7\x1c\x55\xf0\x79\x67\xf2\xb3\x7e\xa5\x81\xd8\x20\x8a\x7c\xb9\xb9\xb9\x59\xdf\x84\x2f\xcd\x99\x15\x5d\x47\x51\x40\xa8\x50\x2f\xf6\x74\xf6\x54\x93\x7e\x17\x18\xde\x43\x1a\x91\xc4\x1a\x9f\xab\xba\x2c\x45\x07\x8d\x93\x0f\x09\x87\x73\x89\x71\xd8\xfa\xd4\xe1\xe4\x9e\xd8\x5d\x7e\x1c\xe1\xd3\x88\x8a\x1c\x51\x5d\xeb\xa7\x15\xa5\xac\x0f\x16\x06\xfb\xcd\x6b\x60\xe2\xf1\xa4\xa2\x11\x93\x16\xbd\x24\x67\xa8\xbb\xe9\x28\x2e\x65\xdc\xff\xd4\x85\xd6\xe3\x92\x2d\x8d\xe2\x54\x38\x05\xbf\xff\x5c\x8a\xc6\x2f\x6b\x93\x2d\x8d\x46\xb1\x01\x99\x06\xa1\xa8\x7d\xfd\x5c\x54\x9e\x83\x79\x85\xb3\x4b\xa3\x24\x95\xda\x79\x0b\xb5\x7f\x09\x6b\xa2\x51\x02\xd2\xc7\x53\x88\xa7\xb9\x01\xcb\x10\x9c\x79\xbe\xd2\x28\x05\x1b\x0a\x74\x81\xbf\xf2\x14\xa2\x09\x1a\x65\x71\x8e\x81\xa1\xf3\xf5\x1c\xaf\xb5\x73\x1f\xf5\x7f\x4c\xcf\x9b\x89\x24\xb2\x15\xdd\x46\xfb\x86\x3c\x8d\xf2\x98\x39\xff\xc4\xdb\xa2\x55\xa2\x9c\xbc\xf3\x34\x12\x3c\x46\xb5\x84\x7f\xfd\xeb\x5f\x93\x79\x20\xb8\x85\x72\xf4\x59\x13\x22\x5b\x76\x9f\xad\x72\xd3\x0b\x11\x59\x6a\xc5\x69\xdc\x02\xff\xd8\xc0\x66\xb5\x75\xaa\x8e\x3e\xec\xa2\x91\x8c\xc0\x3b\x30\x84\xf2\xf5\x4a\xf4\xe9\xd2\xe8\xa1\xc9\x8c\x47\x43\xa0\x87\x45\xbb\xb9\x27\x00\x8d\xa4\x10\xf8\xcb\x3d\x65\x63\x8e\xfc\xfe\x6c\x31\xa6\x91\x34\x79\xec\x0a\x62\x7f\xa2\xb8\xe4\xf3\xee\x66\x27\xca\x91\xa7\xf5\xd5\xa8\x81\x46\x2a\x02\x8c\x64\x1e\xbf\x2e\x76\x6b\x72\x78\x5a\xec\xd7\xfe\xb2\x55\x6e\x9c\x41\x57\x59\xde\x5b\x34\xcc\x63\xdd\xb6\x45\x70\xdf\xf5\x05\x9a\xf0\x01\x65\x77\x4f\xc7\x9f\xb0\x90\xe1\xa1\xad\x41\x23\x05\x5a\x31\xcf\x30\x38\x8d\x00\x89\xd3\xe7\xa9\x59\x24\x72\x6f\xe1\x56\x94\x6f\xef\xf7\x82\x7e\x8c\x44\xe0\xe9\x0f\x1b\x1c\x04\x28\xd2\xdf\xac\x7c\xf8\xb3\x80\x45\x2b\xed\xd7\xab\xaf\x0f\xdb\xc9\xe4\xd1\x20\x91\x94\x77\x73\x51\xaf\x2a\x24\xbf\x34\x82\x58\xa4\x4e\xf0\x53\x83\x2a\x4e\xa2\x0c\xbf\xdf\x70\x22\x86\xda\x91\x45\x0e\x9d\xce\xa2\xc1\xde\xda\xf8\x7b\x49\x94\x59\x60\x6d\x33\x32\xfd\xef\x97\xbd\x47\xa1\x5e\xfb\x28\xe7\x32\x1d\xad\x85\x1a\x01\x8f\x47\xf6\x54\xbb\x62\xaa\x75\x46\x49\xff\x38\xd1\x0b\xdc\x99\xbd\xec\x5f\x1a\x2f\xd2\x45\x49\x64\x12\xa4\x4d\x78\xb0\xd0\xe2\xd2\xd5\x55\x7d\x7a\x1b\xe8\x7c\x94\x10\x6a\xfb\x05\x12\xa0\x99\x56\x53\x28\xa1\x59\x8a\x02\x51\x7e\xab\xf4\x7f\x16\x14\xc9\xe9\xd0\xbd\xb8\x94\x60\xe0\x5a\x53\xc2\xb2\x34\xe6\xbe\xdf\xf4\x36\xd7\x68\x9c\xc9\x75\x51\xc2\x74\x8a\xb0\x26\xd0\x45\xf7\x8e\x0d\x7f\x7d\x12\x13\x4e\x24\xf6\xbd\x05\xaa\x28\xd8\x9b\x3e\x77\xd6\x9c\x7f\x24\x4e\xbd\x7f\xb8\x6f\xea\x5e\xab\x30\x50\xc2\x93\x9c\x78\x22\x3f\x16\x6d\xde\x51\xb5\x7c\xd4\x47\x09\xcf\xb4\x17\x36\x59\x8a\xb6\x50\xd6\x8a\xbc\x7f\x1d\xba\x5b\x18\x84\xad\x28\xe1\xa0\xf4\xd0\x4f\x40\xfd\xf2\x4f\xf6\x25\xc2\x8d\xd5\xd8\x77\xa5\xe7\xd9\x23\x8f\x33\x82\x75\x50\x38\x75\xe7\xb7\x7d\x7d\x7d\xdf\x21\xb1\xc8\x70\xde\xaa\xa3\xbf\x88\x58\x53\x2f\x5d\xbb\x82\xa6\x13\x45\xe5\x1a\x1b\x1f\x72\x29\xfe\xba\x8e\x48\x49\x6c\x58\xa4\x02\xf0\xe7\x5d\x81\x62\x76\x55\x09\xe3\xc8\xd6\xeb\xa3\x28\xd0\x8b\x30\xd3\x12\x45\x62\xdb\xc4\x39\xbf\x3d\xd6\x67\x97\xfd\xf9\xa3\x69\xc4\x72\x3e\x18\x34\x3e\x8a\xb3\xb5\x43\xf9\x54\xd9\x8f\x92\x94\x09\xe3\xd0\xe6\xff\x0d\xd0\xbc\x45\xd3\x0c\x2a\x44\xde\x15\x91\x92\x2c\x8a\xb0\x8c\x3f\x44\xf9\xce\x10\xce\x1f\x8f\xa5\x74\xc0\xea\x9f\x6e\x9b\xf3\x47\x12\x89\x10\x93\x10\x57\x3b\x64\xfb\x13\x08\xf5\x02\x7a\x36\xbd\xb2\x9c\xa0\x8b\x90\x03\x5f\x8b\x21\x6b\xbf\x26\xc8\xd4\x8f\xd7\x08\x34\xf9\x62\x1d\x92\x1e\xd7\x77\xdb\xf7\x8e\xd7\x94\x64\xca\x90\x78\x84\x40\x73\x88\xbf\xe9\xa0\xdc\x09\x0f\x3e\x17\x95\xa9\xc7\x8b\x1f\xc9\x13\x12\x09\x1f\x88\x1e\x8b\x3a\x80\xf2\xfa\x47\x34\xbd\xa0\x5c\x65\xd8\xad\x42\x6b\x03\xcc\xd1\x3c\xaa\x25\xe4\x80\x94\x88\x4c\x82\xb5\x60\x47\x98\x57\xdb\x9a\x4b\xb9\xf1\x4e\x65\x94\x48\x05\x58\x83\xfd\x51\x77\x5e\xda\x72\x34\xa3\x14\xe5\xa9\xdb\x63\xbf\x43\x71\x5b\x37\xae\x0d\x1d\x0e\x0b\xbc\x83\x76\xc2\x2d\xff\xf5\x64\x99\x67\x57\x4b\x32\x94\x28\xb0\x1d\x1e\xe1\xb4\xed\xa6\x80\xc6\xfe\x38\xa4\x4e\x90\x97\x0c\x36\x28\x81\x52\x4e\x09\x70\x40\x26\x42\xd1\xc1\x29\xd8\x10\xdb\x85\xe3\xfa\xe2\x04\x9a\x23\xdc\xda\x19\x27\x4d\x9a\xdb\x94\x46\xb1\xc0\x25\xe3\x97\x82\xa6\xfb\xfd\xcd\x87\x3c\x94\x44\x0a\x2d\x79\x94\x68\x5f\xae\x8b\x82\x50\x4a\xd2\x58\x3b\xde\xf8\x5d\xf1\x0a\xe3\x98\x83\xd2\x98\x21\x52\xd6\xae\xba\xe3\x5d\x98\x52\x25\x23\xb7\xaf\x9b\x40\x10\x9d\x2c\x29\x94\xa5\x52\xb0\xe0\xac\x57\x4c\xa9\xa0\x94\x32\x4d\x33\xa7\x93\xd6\xef\xba\xdf\x44\x55\x74\x6f\xcf\x4d\x39\xae\x30\x52\xca\xa3\x18\x73\x95\xf5\xf6\x9f\xfe\xaa\x78\x62\xfd\xf2\x9c\x93\xd6\x67\x15\x57\x4a\xb9\xe2\x38\x09\x7f\x78\xae\xc7\x34\x58\xa5\x31\xcd\xbc\xc2\x47\xff\x2a\xa0\x5c\x64\xbb\x7c\xdb\xe8\x77\xeb\x97\xdf\x5c\x68\xac\x2c\x63\xde\x45\x62\x4d\xbf\xc9\xfc\x2d\xd4\x17\xa5\x31\x44\x98\x54\x04\xbf\x92\x41\xaf\x8e\xd2\x04\x1c\x1d\xbc\xfe\xf1\xd7\x51\x36\xcd\x22\xc9\xdd\x8c\x2d\x9a\x93\xa8\x66\xca\xb7\x94\x66\x84\x73\x1a\x40\x47\x0b\xd9\xfe\x5e\x54\x1a\x5b\xd8\xd3\x61\x59\x82\x02\x74\xa5\x2d\xbe\x4e\x98\x0e\x94\x8a\x54\x22\xb4\xcb\x99\x3a\x05\xe8\xfc\x6c\x6d\x0c\xf7\x46\x52\x99\xb8\xfa\xc4\xef\x7f\xae\x6e\x2f\x65\xf9\xdb\x7c\x88\x22\xae\x66\x7c\x29\xbb\xe2\x51\x34\xdd\xdb\x1c\x3a\xf7\xae\xa7\x4a\xa9\xce\x0d\xc2\x6d\xbf\x88\xb2\x84\xa6\xa8\xab\xa1\x95\x40\xa9\xd6\xc4\x22\x83\x5b\xf4\x57\x1a\x9b\x82\x84\x11\x14\xcd\x5a\x3d\x0b\x84\x52\x48\x0c\x78\x21\xe2\x73\x03\x87\xd7\x37\x75\x28\x54\x5d\x15\xff\x39\x58\xd9\x05\x0d\x55\x8d\x04\x7c\x0f\x0c\xa7\x2c\x4a\x38\x1d\x2c\x49\x27\xca\x27\x9f\x3e\x76\x16\xe5\x09\x04\xa5\xc2\x76\x0f\xe2\xb4\xb4\x7b\x55\xff\xf8\xdb\x4e\x9c\xce\xe1\x2b\x40\xa3\xc8\x2b\x96\xf4\xf6\x3f\xeb\xc9\x0a\xc8\x48\x1f\x1d\xdb\xe6\x51\xbf\x99\xb5\x1d\xe8\xdd\xe5\x1d\xb0\xd2\x0f\x06\xab\x17\xb1\xdb\x2f\xbe\xac\x0f\xb7\xdb\xe7\x87\x9b\xc5\x7e\xb3\x7d\xf0\x27\xa3\xd4\x3a\x23\x3d\x09\x89\x02\xbe\xa3\xa5\x9b\xc5\x4c\x27\x83\xc3\xf8\x53\x71\x7c\x09\x7a\xf0\x93\xd5\x83\xc5\xb1\xf4\x93\xec\x6b\x7d\x82\x8f\x22\x6d\x16\x27\x02\x93\xed\x2e\xb8\x99\xcd\x15\xf9\x28\x8b\x53\xeb\xfc\xfe\x00\x3f\xff\x9e\x75\x26\x65\x49\x14\x63\x7c\xfd\xb8\xb8\xc3\x8f\x0c\xc2\xcd\xd3\x5d\x9b\x25\xb9\x21\x2e\x27\xbd\xab\xd5\x6b\x60\x06\xf8\xc3\x82\xa9\xe1\xf7\x9e\x0a\x5f\x9b\x9c\xfe\x88\x44\x46\x49\xe6\x0b\x7b\x88\x66\xeb\x40\x4f\xee\x5b\x9a\x71\x64\x3f\xdf\x41\xd7\x4a\x57\x85\xfa\x08\xa9\xed\x3f\x62\x52\xcd\x27\x52\xae\xb3\x5b\x9c\xa5\xd4\xc3\x14\x1e\x2d\x07\xf4\xdb\xd8\xf3\x63\xf6\xd4\xb3\x5c\x63\x7d\x5e\xfa\xe5\xfe\xb6\xbc\x34\xb2\x9e\x9f\x53\xe8\xc8\xcd\xfe\x1b\xf1\xd6\x6e\xaa\xfb\xba\x72\x9c\x97\x09\xc4\x86\xb2\x9c\x47\x38\x4b\xfa\xb7\x7f\xff\x52\x58\x53\x7f\xff\x73\x73\xa0\xc6\xb2\x3e\xfa\x65\xf3\xd2\x84\xfe\xb4\x3b\x2e\x22\x89\xb9\xdc\x57\xa8\x4c\x73\xf1\xc8\x12\xca\x04\x23\x7e\xd1\x5d\x36\x85\x7a\x0d\x56\x6b\x94\x49\x96\xe4\x0e\x14\xe2\x0a\xfb\xef\x39\x6c\x94\x49\xae\x35\x1f\x97\x7a\xd0\xb6\x6d\xd1\x80\xb8\xbe\x7f\x32\xa9\x92\xd8\xad\x4b\xdb\x1f\xd0\xe8\x46\x98\xeb\x65\x63\xca\x14\x31\xe8\x37\x70\x2a\x9c\xa7\xde\xcc\xf3\x67\x36\x5c\xf7\xd3\x62\x30\x8d\xda\x8d\x67\xb4\xe6\x59\xcc\x47\x05\xc9\xcf\xa4\x94\x29\xd3\x92\x58\xcb\x9a\x8b\xec\x3e\xd4\x0b\xa7\x0c\x58\x8c\x28\x98\x06\x84\xbe\xab\x7f\xc0\x0e\x61\x8b\x56\xe4\xdf\x8f\x31\x2c\xc6\xd8\xd6\xce\x67\x34\x62\x9f\x7c\x17\x8f\x08\x10\x70\x78\x8c\x9b\xa2\x95\x97\xa6\x85\x81\x1e\x4d\x79\x94\xe4\x91\x6d\x2d\xd6\x5f\x45\xbb\x7f\x81\x65\x71\x3c\x42\xdb\xdd\x14\xbe\x3d\x41\x79\x94\xe6\xd9\xb8\x3d\xb1\x0c\x65\x28\x4e\x44\x84\x88\x4d\xd3\x00\x86\xa3\x77\x76\xb5\xfb\xf8\x57\x71\x22\x99\x74\xf1\xd9\x57\xd1\xf4\xb9\xd4\xd6\xf7\x09\x7e\x9b\x3a\x8b\xfa\x0f\x18\x83\xf5\x90\xb3\x68\xdb\x31\xf2\x90\x72\x9a\xda\x46\xc3\xa9\xa8\xac\x79\x99\xff\xbb\xca\x43\xe1\x00\x5f\xef\xa1\x4a\x12\x86\x40\xcc\xf8\xa8\x60\xf3\xbe\x6d\x32\x84\x94\x9c\xa5\x5c\xf4\x6b\x4a\x7d\xf2\xd9\x10\xe7\x5c\xa4\xae\x59\xf4\x28\xd0\x19\x7e\x3a\x71\x39\xcf\x35\x8a\xc3\xfe\xb9\xde\x85\xcf\x48\x8a\xab\xca\x0e\xa0\x84\xa0\xd1\xf7\xf9\xaa\xc1\xb9\x62\x58\x73\xd0\xda\x74\xb7\x97\x4a\x4f\xec\x3a\x29\x8f\x23\x49\x5c\xaf\xa5\xda\xd5\xe5\x84\x1e\x40\x79\xcc\x72\xe1\x72\xb6\x8d\xaa\x47\x21\x08\x8f\x73\x9b\x84\x23\x77\x62\x33\xcb\x11\x79\xac\x6d\x7d\x5d\xd5\x85\x6b\x1c\x0e\xe1\x37\x8f\x8d\x25\x24\x98\xa2\xd2\x0f\xf0\xab\x1b\x56\x94\xa9\x5e\x15\xe5\x09\xb1\x17\x77\x39\x1f\xfb\xc7\x33\xd0\xcf\x40\xef\x56\xd7\xb3\x2e\x9e\x50\xbb\x83\xf6\x09\xf4\xf6\x06\x7e\xa0\x7e\xea\x9c\x18\x35\xff\x4c\x9a\xe2\xde\xb4\x6a\xde\xce\x5d\xfd\xf8\x52\x43\x55\xfc\x82\x76\x55\xfc\x28\xca\xef\xe2\x7a\x7f\x9f\xf2\x94\x00\xce\xea\x5b\x31\x15\xa6\xa3\x3c\xcd\x94\xb1\x84\x1c\x55\xff\xe8\x67\xcd\x24\x60\xf7\x83\x54\x3c\x4a\x0d\x1e\xa0\x9f\xf5\xcb\x91\x53\x29\xe5\x29\xe8\x9c\x8e\x98\x6a\xc5\x79\xd7\x89\xce\xbb\xcb\xfb\x88\x87\x67\x24\xc2\xf8\xae\x82\x9f\x81\x04\x58\x29\x78\x08\x37\x3c\x03\x8e\xc6\xa5\x9b\x76\x59\x17\x25\x34\x16\x1b\xf6\xc1\xeb\x95\x01\xc7\xde\x24\x12\x4a\x1e\x9b\xa2\x6e\x8a\xee\x6d\xf6\x78\x73\xae\x3d\xeb\xce\x6a\xb3\x84\x09\x93\x67\xd6\x28\xbe\x0d\x22\x2f\xe4\x83\xef\xc9\xa5\x89\x88\x83\x53\x75\xf5\x6a\x36\xfb\x45\x6c\xf3\xa6\x43\x9f\x12\xd4\x25\xac\xc4\x59\xc8\xa2\xf4\x4a\xe3\xd9\x94\x12\xc2\xc7\x2f\x9b\x8c\x72\x4c\xbb\x6d\xda\x66\x55\xdd\x3f\x88\xb9\xfd\x27\x4c\x92\xc7\xd3\xe2\x4c\x3b\x4c\x19\x37\x48\x45\xc2\x93\xa1\x5d\x5b\x1c\xe5\x7d\xa1\x1b\x75\xc3\x3e\x8f\xe9\xb9\x62\xb1\xdf\xcc\xb0\x41\xb2\x84\x6e\xdb\x14\xc7\xe2\x2f\x82\x42\xae\x64\x46\x06\x47\x11\x24\xc6\xad\xaa\x01\x7b\x34\x4f\x6b\xa6\xcf\x4a\x41\x8c\x71\x79\xd7\x6f\xc9\xb8\xf1\x9c\xeb\x62\x58\xbe\x75\x64\x1d\x87\x85\xd6\x37\xa2\xbb\x02\x2c\xa3\x5c\x67\x1a\xb9\x55\x06\x99\x69\x7b\x38\xe1\x72\x7b\x69\xa0\x75\xd9\xb9\xdf\x4c\xb8\x56\xa0\x59\x30\xa3\xb5\xb6\xb1\x00\xf7\x45\x35\x7b\xba\xa0\x22\xdc\x09\xef\xea\xe3\xae\xbb\x68\xa8\x3a\x0f\x33\x7a\x2f\xb4\x7a\xf5\x57\xc5\x91\xb2\x18\xa6\xd5\xbd\x83\xfa\xd0\x98\x80\x2d\x84\x58\xd3\x19\x4b\x74\x9d\xbc\x71\x31\x65\x32\x49\x43\xbf\x0b\x1a\xa8\x14\x84\xe7\xbc\x35\xab\xe0\x74\x11\xbe\x86\xa6\x14\x73\xd7\x17\x10\x65\xf7\x82\x77\xcf\x7f\x1d\x35\xc6\xb6\x24\x5e\x1a\x80\xaf\x75\xf7\xb5\xbe\x34\x4e\xad\x30\x28\x12\xd0\x98\x45\x56\xd3\xe2\x7b\x51\x81\x8d\xd0\x6d\x73\x6e\x7a\x61\x8c\xd8\xfb\x71\xa3\xeb\x31\xe6\x8e\xc6\x3c\x21\x28\x06\x66\x91\xdf\xae\x2c\x85\x2d\xda\x30\x22\x4f\x89\xeb\x11\xaf\x44\x39\xe2\x3b\x84\x96\x87\x1b\x18\x47\x22\x76\xc8\x77\x24\x68\x38\x14\xc1\xaa\xae\xda\x42\x8f\x76\xb6\x38\xa6\x06\x8d\x32\x44\x55\x5d\x44\x19\x20\xa1\xee\x68\x42\xb8\xff\x3e\xd7\xcc\xff\x52\xcf\x0c\x7e\x69\x9c\x30\xe1\xd5\x8b\xdc\xa0\x11\x5c\x98\xc6\x89\x8c\x72\x36\x28\x99\xeb\xdb\xba\xf1\xae\x89\x61\x88\xd6\x88\x1b\xfe\xfe\x52\x63\x4c\x51\xb7\xed\x83\x67\x9c\xd0\x38\x8d\x6c\x35\x1e\x0b\x9f\x5d\x67\x7b\x20\x08\xaa\xfa\xf4\x45\x8a\x33\x10\xca\xf8\xb0\xdc\x3e\x8e\x4d\x78\x15\xe2\x9c\x13\x5c\x73\x76\x97\xc6\x3b\x05\xf9\x23\x89\xb0\x24\xdb\x3e\xc0\x6c\x67\x3f\x36\x4f\x84\x57\xdb\xc3\x62\x51\xf5\x21\xba\xd8\x7d\x40\x44\x11\x2e\x50\x95\xe8\x90\x1d\xb2\x6e\xd4\xb2\x29\xf4\x11\xda\x85\xed\x64\xf8\xaf\x15\xa9\xc8\xf5\x98\x4f\x3b\x04\x19\x7e\x44\x16\x61\x07\x71\xd7\xd5\xe7\xb3\x90\x25\x20\x9d\x19\x1b\x00\xd7\xe9\x26\x34\x16\xc6\x3a\x77\x89\xfe\xd7\xdf\xd6\xcd\xb7\xa2\x7d\x67\x57\xef\x86\x4a\x91\x88\x81\xc0\xf4\x97\x58\x5b\x1a\x4b\xc9\xf0\x03\x96\x46\x6e\xad\x34\x47\x55\xcc\x58\xf5\x69\xff\x60\x3d\x72\x5f\xbf\xd3\x34\xa1\xb1\x62\x29\x75\x81\x45\x59\x57\xc7\x39\x38\x9e\xc6\x4a\x2b\x7c\x88\xc6\x0a\xe6\x23\xb6\xc3\x7f\x01\x24\x04\xf5\x27\x9e\x2b\x51\x15\xa7\xfa\x82\xd3\x7b\xb4\x01\xf8\x3d\x33\x86\x2c\x4f\xfb\x29\x78\xb7\x7c\x08\x9f\x95\x12\xb1\x9b\x87\xa2\x0f\x58\x96\x45\x77\x12\xcd\xeb\xbb\x56\xf4\xd5\x1b\x65\x62\x96\xeb\x51\xf9\xf3\xb9\xbd\xa2\xb9\x76\xad\xbe\x1a\x9b\x24\x47\x04\xb4\x77\x0d\x58\x54\xfa\x0b\x04\xa3\xbd\x19\x3f\xe2\xfa\x4d\x37\x99\x35\xb1\x7f\x7c\x5e\xde\x6d\x56\x08\x6b\xdb\x1d\x88\x53\xbd\x3b\xac\x1f\x6e\xfc\x0f\x34\x22\xa7\xd6\x51\xe1\x84\x8a\xc3\xd8\x42\x9d\x5e\x9d\x1d\x99\x44\x9c\x60\x6d\xe1\x66\x7d\x77\xf7\x9b\xff\x9b\xe2\x78\xa5\x9e\xe5\x35\x7d\x2a\x09\x51\xd6\xd7\x6d\xd3\xee\x5f\x8a\x09\xc1\x99\x26\xc4\x64\xd4\x0c\xf5\xbb\xc5\x20\xeb\x32\xfd\x29\x09\x8d\x72\x5c\x2d\x1b\xaf\xc9\x86\x6c\xfe\x7d\xbd\xae\x3c\x21\xda\x9f\x92\xa6\x80\x54\x1c\xe9\xca\xa5\xa1\x94\x9f\x30\x15\x45\xae\x81\xf2\xed\xf0\x44\x67\x97\xc9\x4c\x82\xbb\x38\x2a\x13\x88\xd2\x26\x6c\x30\x55\xe4\xeb\x47\x65\x18\x7b\x5f\x5a\xfd\x08\xcd\xd7\x4b\xa5\x9b\x11\x89\xbc\x3f\x2e\x47\x75\xbd\xa5\x68\xc1\x5e\x44\xa5\xdf\xc1\xea\x66\xbf\x30\x49\x15\xd6\xf9\x9d\xc6\xc5\x5c\x6d\x8a\x26\x89\xcc\xb0\x2e\x70\xb0\x30\xf3\xbf\xd2\x01\x9d\x50\x62\x87\x20\x28\x49\x54\x92\x10\x2f\x42\x7f\x83\xbe\xd3\xd3\x0b\x49\x4d\x9e\x67\x03\xea\xad\xbf\xd1\x23\x11\x74\x9a\x64\x4c\xa0\x2c\x6b\xe5\x78\x25\xc8\x19\x68\xf7\xf5\x6d\x51\x89\xb2\x4f\x04\x82\xa4\x35\x4d\x32\x6e\x19\xf0\x97\x76\x9a\x90\x4c\xbf\x31\x4b\xac\xf7\x4d\xff\xc3\xac\x4a\xc3\xd5\x02\x4c\x92\x27\x99\xc3\xec\xcd\xcc\xd1\x69\x92\xeb\x38\xe3\x41\x0c\xfa\xdb\x3b\x43\x53\x9a\xe4\x20\x50\x1d\xb4\x38\x89\x23\x0c\x0b\x50\xbf\xb5\xdf\xdf\xc4\xfe\x3c\x92\x1b\x1a\x87\x1a\xbe\xad\xb7\x4f\x5e\x00\x95\xdb\x76\xbc\x1d\xf0\x4e\x54\x7f\x74\xa3\x75\x6e\x37\x2a\xdc\x27\x4f\xa0\x0b\xd1\x4d\x4d\x07\x67\x77\x01\xb8\x18\xac\x7e\x5b\xe8\x0e\x47\xe8\x0e\x48\x7b\xbc\x9c\xec\xee\x1d\x1e\x01\x08\x03\xde\xaf\xfe\xb9\xea\x8a\x72\x56\xe6\xf2\xc3\x80\x20\x36\xab\xe8\xaf\xc0\x08\x05\xb7\xa8\xdc\xfa\x09\xb7\xaa\xff\x4c\x6c\xbc\x3a\x61\xbf\x17\xde\x72\xff\xa5\x26\xb5\x62\x2e\x3e\x55\xff\xe7\xf6\xcf\x49\x4a\x98\x98\x14\x50\x6f\x08\x67\xd6\xa4\x81\x34\x7d\x9a\x7e\xa9\x4d\x23\x49\xd1\x41\x04\x0b\x99\xf8\x9a\xf9\xc8\x75\x6c\x22\xdc\x47\x5a\x04\x2b\xaf\x05\xbe\x13\xa0\xc7\xf0\x64\x3f\xc4\x58\x3d\x8f\x3e\xae\x78\xfb\x5a\x9c\xdb\x6e\xf8\x38\xcb\x63\x6b\x85\x50\xb4\x68\x7d\x51\x59\x83\xd5\x51\x3e\x95\x72\x92\x23\x64\x71\xb9\xd8\x3c\x85\xea\x66\xca\x81\x67\x30\x18\x89\x39\x52\x84\x25\x6f\x85\xe7\x9c\xc6\x19\x27\x0e\xb2\xd9\x9f\xfe\xa6\x68\xcf\xa5\x78\x9b\xab\x16\xd1\x34\x16\x39\x36\xb9\x5c\x6b\x7d\xd6\xd2\x4e\x63\x69\xc5\xf0\xfe\xc6\x4e\xe1\x3e\x91\x72\x89\x01\x97\x2d\x25\x6f\x9b\x1d\x84\x28\xfd\xda\x74\x48\xd3\x58\x46\x36\x69\xac\xfa\x85\x69\xc8\x18\xc3\xd3\x4f\xb3\x14\x46\x3d\x53\x1f\xa9\x63\xbb\x79\xb5\x98\xdd\xf2\x2c\xb3\x5a\x1a\x27\xa7\x7a\xb1\xb2\xa0\x80\x9b\xba\xba\xca\xcf\xfd\x0c\xef\x94\x66\x32\xd3\xc3\xb2\xf9\xad\xee\x00\x63\xb6\xe9\x17\xe6\x84\xe1\xc2\x73\x07\xfa\x08\x8d\xd5\xe1\xb9\xce\x39\xa0\x69\x4e\x33\x42\xbc\xca\x2c\x00\x4e\xae\xa6\xfd\x67\x2d\xfd\x6d\xff\x88\x75\x4b\x53\x41\x0c\x72\x2a\x5f\xea\xa6\x85\xdb\xdd\xec\x0e\xc9\xc8\x16\x86\x10\xdb\xb2\x2c\x1a\xdd\x4e\xca\xeb\xa9\x4c\x35\xea\x1e\xd8\x8c\xcc\x56\xf2\x46\x3d\xaf\x54\x66\x1c\x0b\x17\x5a\x14\xe5\xdb\x57\xd1\xbe\xac\xc7\x84\x36\x9a\x4a\x25\x10\x70\x89\x2f\xd1\x12\xba\x65\x90\xac\xa4\xa9\x8a\x14\x72\x9b\xd7\xfb\xc5\x6e\x1c\x85\xa6\x8a\x4b\x2c\x07\xc8\xcb\xdb\xea\x23\x53\xa1\x7e\x94\xd2\x0e\x1d\x81\x18\x5b\xfc\x81\xfe\x14\x9a\x11\x3c\x28\x2f\xe5\xab\x7f\xee\x96\xe2\xfa\x61\x43\x25\xd5\x42\x83\x83\x38\x2a\x68\xdb\xba\x99\x70\x8e\x69\x0a\x29\xe5\x3e\x83\x1c\x96\x6c\x9b\xe6\xe0\xbe\x34\x03\xae\xa5\x20\x22\x24\x3c\xdb\x1e\x47\xd0\x5f\xb5\xfa\x3d\xe1\xac\x92\xa1\x6d\x86\xb0\x6e\x06\x93\x3c\x33\x35\x19\xcd\x21\xdc\xfe\x07\xe8\x7e\xd6\xcd\xab\xcd\xfb\x66\xb3\xc9\x38\xb1\xb1\x7e\xcf\x29\x4c\xf7\x32\xaa\x49\x67\x51\x14\x5b\xd3\xe1\xba\x04\x84\xd5\x4f\x3f\x9b\x45\x22\x45\x31\x0e\xc7\x1d\x84\x6a\x2e\x10\xd3\x0f\xc9\x13\x08\xab\x02\xe2\x5a\x66\x03\x8c\xf5\x37\xb1\x9d\x4d\x8f\x4f\x1a\xf3\x54\xdd\x40\xc2\x6c\x2d\xd9\xaf\xbb\xc8\x5a\x1e\xed\xff\x93\x87\x9c\x91\x34\xb6\x66\x86\x43\xcf\x29\x23\x8a\x5b\xf3\x77\x1b\x5a\xac\xca\xcb\x68\x79\xcc\x28\x27\xc6\xa3\x2f\x8a\xee\xed\xb1\x3e\xf7\x19\xc5\xbb\xf0\x3b\x63\xc6\x15\xea\x95\x7d\xd8\x6f\x37\xa2\x13\xb3\x55\x2c\xe3\x3c\xc3\xb4\xe3\x01\x7e\xfa\x72\xe2\x47\x15\x90\xe9\xed\xe0\xb9\x55\xe1\x40\xb1\xba\xd0\x67\xc6\x8d\xbc\x0d\x27\x37\xca\x39\x3e\xb8\x52\x8c\x73\x9e\x18\x23\x53\x69\x16\x47\x1c\xa3\x84\x9d\xe8\xea\xf6\xa5\x08\x7f\xa6\x12\x13\xe6\x56\xfc\x80\xd5\x47\xee\xea\x34\x8b\x63\xc9\x5d\x99\xca\x69\xb5\xcf\x9e\x5b\x9c\x70\x2c\x6f\x96\x20\x34\x34\xb2\x16\x8d\xbe\x76\x23\x92\x88\xe5\xae\x59\x80\xaf\xf2\xec\x66\x26\x82\x21\x06\x7b\x57\x9c\xce\x25\x2c\x36\x7f\xb3\x59\x95\x25\x52\x20\x61\xe5\x05\xc4\x79\x57\xbb\xd3\x26\xdc\xbf\x92\x59\xea\xe8\x3c\x2d\x74\x37\x4f\xbb\xd5\x07\x06\x22\x34\xcb\x74\xca\xad\x82\x89\xbe\x28\x2c\x2d\x3a\xf6\xee\xec\x3a\x73\x26\x9d\x09\xf4\xaf\xee\x20\x27\xb1\x70\x96\xf3\x58\xb8\xef\xf2\x71\x90\x55\x67\x5a\xbe\x7d\x84\x7f\x19\xed\x9b\x99\x64\x02\xdf\x10\x23\x4e\x88\xc3\x47\xa1\xbf\x7d\xbd\xd1\x53\xad\x2d\x9a\x49\x69\xc5\x6f\xb1\x31\x6b\xcd\x7a\xdf\x5f\xa8\x34\x89\xf3\x8a\xb2\xe4\x6c\x04\x37\xb6\x73\xdd\xc9\xeb\xcf\x5c\xf1\x04\x8b\x06\x56\xa5\xe6\x69\xb1\x5f\x1f\x96\x8b\xdd\x7a\x8c\x41\xcc\x14\xcf\x10\xc2\xf9\x00\x4a\xb4\x2f\xe3\xd5\x37\x53\x29\xf7\x48\x8d\x1d\x54\xa1\xbe\x35\x41\x0a\x67\x10\x5b\x9f\xea\x3f\x4c\x19\x92\xf4\x0c\x40\x63\xb9\xe3\xae\xdf\xf1\xf5\xe1\xa1\xf6\x7c\xf6\x11\x7e\x70\xf2\xf8\x0d\xe1\xa8\xd2\xb1\xfc\xfa\xe0\xd6\xb6\xdf\xc2\x11\x80\x51\xe5\x64\x07\xa3\xcd\x7d\xbe\xc5\x65\x86\x5b\x66\x6f\xd1\xae\x4f\xe7\xee\xcd\x49\xb4\x5c\xd9\x98\x33\x13\x33\x03\x93\xa2\x4e\xc0\x62\xfb\x54\x74\xf6\x20\x4c\x62\x10\xb1\x51\xb4\xdb\xca\xa7\x66\x97\xc1\xcf\x90\x66\x46\xd9\x04\xdb\xfa\xa1\x7c\x00\x29\xc9\x8c\xe6\xa9\xe5\x9e\x8b\xba\xff\xc7\xfd\xce\x3c\x12\x80\xca\x4a\xed\x4b\x33\x7e\x08\x79\x24\x73\x05\x7e\xfd\x58\x94\x23\x0f\xd7\xd9\x74\xca\x23\xe0\xb8\xb8\x63\x52\xe3\xb8\x4b\x57\xe7\x45\x4e\x22\x6b\x2c\x67\xa5\xa5\xac\x7d\xda\x21\x6c\x76\xd3\x0b\xce\x09\x8d\x7c\xe0\xfc\x15\x44\xd3\x8d\xb1\x3a\x39\xc9\x6c\xb5\x10\x77\xd4\x42\xf9\x74\x31\xa7\x84\x4a\x8b\xa7\x2b\x17\x97\x31\x04\x64\x7a\x6e\xca\xac\xb3\xc1\x7e\xf1\xc7\x68\x4e\xe6\x8c\x44\xb8\xc6\xbc\x88\x16\xa7\xfb\x87\x3f\x84\x65\x29\xb8\x9e\xbf\x85\x88\x79\xa5\x32\xea\x4f\x15\x8b\xc8\x37\x73\xc7\x05\xb9\x3c\x61\x1a\xc5\x71\x55\x59\xb7\xb6\x33\x3f\xf6\x8c\xa6\x79\x9a\xc6\x48\x11\x2a\xda\x1b\xc7\x19\x1d\x89\x6c\xd3\x3c\x15\x0c\xd1\x73\x07\x47\x10\xff\xc0\xce\xe6\x5a\xce\xea\xce\x90\x51\x4b\x1e\x3d\x8e\xa0\x89\xfe\x10\xa3\x58\xd2\x29\x45\x73\x84\x95\x38\xe3\x85\xcf\x27\x52\x9e\x71\x6b\xe8\x55\xa8\x9a\xa8\x50\x7e\xcd\xf3\x48\x83\x97\xe8\x7c\xdb\xd7\xab\xf7\xad\xfa\x3c\x4f\x6d\x34\xa2\xdb\xb3\x33\x8e\xf1\x51\x5e\x2e\x22\x16\xa1\x4b\x58\x7d\x5c\x54\x75\xf5\x76\xaa\x2f\xed\x6f\x93\x84\xfb\x1d\xd5\xb2\xff\x50\x86\xc4\x4d\xbf\x38\xde\xbb\xc6\x95\xa8\xa0\x9a\xb6\x89\x72\xc1\x94\x71\x4b\xca\xe3\xe6\x00\xba\xe8\x0e\xde\x29\x82\xe6\x22\x21\xf6\x9e\x7b\xb8\xe8\x0c\x50\xe3\x87\x01\xf5\xae\x1a\x7d\x9a\xbf\x35\xbb\xe2\x58\x61\x75\xde\x9f\x48\xb2\xd8\x07\xc9\xc1\x8d\xee\xd9\x36\xd4\x2c\x74\xae\x2e\xf5\xf2\xed\xbe\xd6\xae\x77\x4e\xc6\x4a\x36\x34\x97\x31\xf3\x38\x9d\x27\xb0\x0c\x85\x81\x79\xd4\x1f\x96\x5e\x4e\xf6\xbe\xa8\x2c\xce\xfa\x5d\xbe\x3c\xbd\x64\x99\x64\xe8\x76\x5b\xb4\xdf\x45\xd3\x88\xaa\x7b\xc3\xf5\x70\x56\x8a\x9a\xac\x50\xb9\xa2\x1c\xd7\xd0\xee\xef\xed\xa0\xb9\x4a\xa8\xb1\x2a\x25\x13\x3d\x2c\x9a\x2b\xa9\x30\x40\xb8\xab\x8f\x96\x48\x80\xec\xe7\x5d\x71\x95\xa4\x49\x73\x9d\xe6\x84\x87\x96\x81\xc5\x91\xcd\xd2\xa9\x1c\xfa\xcc\x15\xa9\xba\x0d\x88\x77\xa9\xca\xfb\x88\x3a\x87\x3c\xc7\x8c\xb8\x5d\x7d\x13\x21\xdd\xcf\x4d\x94\xa1\x08\x8f\xae\x37\xe1\x6a\x0d\x05\x27\xc2\x55\xe9\xfe\x66\x15\x75\xf3\x17\xe5\xc0\xdc\xa4\x0c\x03\xa3\xc3\xa1\x2b\xaa\xb7\x6d\x23\x54\x09\x2b\x6f\x12\x74\xa5\xc9\x9a\x9b\xd4\x8c\x82\xe9\xed\xcd\xfa\xde\x8a\xb0\x5d\x6d\xbc\xe4\x26\xd7\x56\xb0\xa0\xb2\x06\x31\xee\xf6\x7e\x2f\xba\x97\x4f\x9a\xf6\x22\x4a\x29\xd2\xb4\xce\xa2\x6d\x9f\xab\x81\xf4\xaf\x47\x02\x3b\x54\x44\x19\x95\x56\xd1\xab\x50\xc2\x8b\x62\x51\x41\x38\x47\xa4\xc7\x50\x72\x12\x44\x44\xd4\xb5\x46\xbf\x88\xf6\x7d\x05\x47\x10\x65\xf3\x56\xb4\xf0\xee\x13\x83\xcd\x07\xcb\xa6\x20\x1a\xf0\x54\x81\x1b\x0d\x13\x3a\x85\xa0\x79\x42\x2c\xc0\xb6\x38\x77\xf5\x09\x74\xa1\x8a\x4a\x90\x70\x58\x70\xab\x3c\x58\x9f\xce\x65\x31\x2e\x6f\xf8\x11\xcc\x68\x6c\x4c\x7d\x1f\x54\x24\xa7\x33\x48\x70\x95\xe5\x43\x8e\xbf\x1f\xc4\xb1\xfa\x93\x1b\xc4\xaf\xdc\x2f\x76\xfb\xf5\xd3\x9f\x87\xfd\xd7\xa7\xf5\xee\xeb\xf6\xce\x57\x75\x45\x2c\x22\x42\x47\xc8\x91\x27\x94\x84\x7b\x27\x2a\x43\x45\x2c\x15\x22\x0e\xac\x67\xc3\x1d\x98\x70\x81\x89\x63\x79\x6d\xff\xb5\x7e\x98\x84\xa8\xfe\xb8\xa6\xd8\xce\xf1\x96\x3b\x4e\x79\xdd\x7f\x3c\xa5\xb6\xfa\xdd\xbe\x4e\x78\x51\x22\xcd\x22\xac\x5f\x2d\x37\xfb\xd5\xdd\xe2\xdb\xfa\xb0\xb8\x1f\x9c\x7a\xa8\x48\xb5\x95\x69\x5a\xb4\x7d\xf4\xec\x5c\x2e\x66\xfb\xad\xc8\x78\x84\x75\x5e\x40\xbb\xe3\xdf\xae\xd5\xd0\x45\x96\x1a\x44\x6b\x74\xfd\x0e\xd1\xed\xeb\x85\x7a\x29\xe0\x47\xb8\x83\x99\x48\x0c\xf3\x75\xc7\xbb\x77\xb0\x81\xf9\xc9\x8c\x15\x23\xb5\x01\xd0\xe1\x11\x9a\xc3\x4d\x5d\x96\x22\xcc\xd1\x9c\x70\xa4\x6d\x6f\x37\x8b\xf0\x27\x21\x73\x35\xaa\xa6\x2d\x1b\x71\x3c\x82\xfe\x56\x97\x97\x00\x98\x10\x22\xa3\x88\xb0\xbd\x5f\x6c\x1e\xa6\x72\xf5\x54\x88\xdc\xca\x0a\x4c\x34\x87\x5c\xc5\xe1\xfa\x65\x0a\x15\x63\x9f\xbd\xac\xeb\xd7\xcb\x19\xab\x48\x93\xe9\x2f\xc0\x0a\x0f\x1e\x47\x69\xd6\xec\xa9\xca\x98\xa2\x18\xba\x6b\xc6\xf4\xe7\x68\xe7\x7d\x12\x21\x63\x86\x11\x83\x77\xaf\x7c\x02\x9c\xda\x77\x7d\x2e\xdb\x3d\xc1\x8f\xa2\x2d\xea\xea\xa1\xee\xb0\x4e\x33\x9e\xb7\x32\x8d\xa4\x83\x74\xdf\x8b\x5f\x9b\xce\x15\x62\x5b\x6c\x91\x61\x1b\x33\x10\x69\xfd\x47\x14\x91\xd2\x16\x27\xde\x7c\xf5\x6e\x36\x1b\xfa\x77\x3a\x45\x39\xf3\x27\x7c\x3e\x33\x15\x62\x3f\x4a\x2a\xe2\x62\x53\xa4\x8d\x5c\x2b\x42\x08\x4d\x72\xdc\x50\xdc\xdd\x79\xf0\x92\x81\x54\x68\x16\xe3\x94\x0b\x8b\x54\xdd\x1c\xc4\xa4\xe4\x21\x34\xd3\x7c\x00\x4d\xad\xc2\x9b\x8f\x16\x15\x57\x39\xdf\x54\x80\xa4\x4e\x9a\xad\xfb\x5a\xf4\x4f\xea\xa6\xae\xde\x7b\x9c\x4e\x2f\xd2\xe4\x2c\xb1\x44\x34\xeb\xa0\x17\xb6\xf6\x2b\xeb\xb8\x8c\x28\x89\xf2\x6b\x9e\x8d\x33\x77\x7c\x2a\x23\x01\x58\x14\xb1\x60\x6d\x07\x15\xc4\xce\xe1\x95\x64\xe2\x3d\xc7\x7e\x72\xec\xc3\x40\x48\x12\x27\x7d\x73\xf6\x62\x49\x1d\x1c\x8a\xea\x20\x1a\x59\x60\x80\x8d\xda\xaa\x07\x85\x90\x1b\x7f\x65\x24\xce\x20\xf3\x20\x51\x54\x24\xbd\x82\xae\xec\x13\x64\xcf\x89\x1a\x12\x80\xcd\xcd\xf5\x70\x43\x32\x61\xa9\x13\x6e\x7f\x6b\xb4\x25\x6f\xa0\xf2\xc8\xe4\x11\x49\x1e\x6b\x64\xd7\x15\xd5\x28\x46\xbf\x12\x8d\x48\x2e\x00\xfb\x07\x45\xbb\xae\xba\xa2\x2b\x3f\x2a\x50\xca\x58\xe7\x4c\xb9\xfe\xec\xec\xcb\x62\x13\x61\x1b\x73\xb3\x5d\xfa\x25\x51\xc6\x26\xf3\x84\xdc\xbb\x5a\x09\x84\xbb\x84\x43\x12\xaf\xad\xbd\xc8\x9b\xa6\xae\xac\x1d\xd0\xa7\xb0\x16\x99\x80\x15\x2b\x38\x7c\xa2\xb2\x40\x65\xca\x39\xae\x14\x8f\xc5\x7f\xff\x2b\x1e\x45\x53\xce\x73\x1e\x99\xea\x08\x93\xae\xaf\xe2\x15\x4b\x20\x01\x4e\x2d\xb3\x34\xc5\x18\xf5\xbe\xe8\x5e\x9a\xa2\xfc\x26\xca\xd7\xb7\xa6\x08\xf3\x2c\x8f\x05\xd2\xce\xbc\x61\xc9\xd4\x79\xcc\x0f\x4a\x2c\x3f\xd9\x31\xa8\x77\x41\x6e\xf4\x83\xeb\xcd\x33\x40\x23\x93\x09\x0b\x46\xe6\x39\xa8\x7c\xa8\x08\xd6\x1a\x66\x3f\x42\x44\x96\xd3\x64\x00\xda\x47\x68\x48\x14\x45\x91\xff\xb0\xc8\x53\x6d\x17\x39\x71\x3a\x88\x4a\x1f\xfa\xcb\x2c\x0f\x12\x2a\x30\x85\x2a\x82\x01\x12\x95\x42\x46\x34\xd4\x6d\x31\xab\x0c\x47\xc0\x46\xd9\xfd\xdc\xd9\x15\x1d\x78\x28\xe8\xf4\xe2\x05\x68\x8f\x00\xea\xe7\x5f\x51\x1d\xe7\x40\x4f\x37\x50\x72\x92\xf7\x33\xc1\xe9\x0c\x7a\xb7\xf7\xe9\xd9\x64\x4a\xa5\xf1\xb8\x25\x0d\xbf\x06\xf5\x1f\x2a\xa5\x50\xa8\xaa\x82\x3c\x99\xef\x00\xaf\x96\x51\x8a\xe9\xf0\xba\xed\x8a\xd3\xd0\x35\x97\x52\x40\xe2\xcc\xc3\x6f\xeb\x06\xbd\x2e\xe6\x6d\xef\xd9\x17\x43\x8a\x72\x13\xbb\x4b\xd5\xbe\x14\x55\x38\x91\xa2\x06\x01\x8a\xbf\x17\x9d\xaa\x8b\xd0\x33\x92\x2a\x51\x58\xdc\x7c\x7c\xda\xac\xd6\x07\x42\xc2\xdf\x0d\x47\xe0\xd5\xc1\x76\x86\x45\xa0\x7a\xce\x1e\x9e\xce\xad\x11\xd0\x02\x45\xbf\xda\xdb\xe7\x87\x9b\xdd\x7c\x88\x4a\x24\x1b\x35\xb7\xef\xeb\xca\x12\xff\xae\x08\x3e\xf9\x3a\xb2\xd4\x46\xa0\xae\xdc\xa1\x1e\xf1\x0b\x25\x64\xb6\x66\xbb\xaf\x4f\x12\x0b\xed\xe1\xef\x22\xd2\x03\x01\xc4\x4a\xf8\x3b\x35\xa3\x4f\x28\xd8\x12\x44\xae\xc8\xd0\xfe\x0e\xdc\xa6\x8f\xaa\xbb\x12\x54\x6e\xbb\x8f\xa2\x7d\xd9\x5e\xba\x95\xf0\x88\x1e\x77\xdc\x87\xf8\xbb\xc7\xf5\x6a\xff\xb4\x3e\x2c\xfb\xb0\xea\xcf\xc3\xe2\xe6\xdb\x66\xb7\x7d\xfa\xf3\x70\xb3\xfe\x76\xd8\xaf\x17\xf7\x87\xc5\xdd\xdd\xd6\xe3\xa3\xa4\xd1\xb9\xa3\x81\x80\x7a\xb5\x4a\x5a\xae\x1c\xfd\x6f\xe6\xb6\x7b\x45\x62\x43\x07\x74\xfb\x9d\x70\xb4\x93\xab\x3b\x9a\x22\x3a\xc5\xd7\x7b\xf9\x65\x1c\xf6\x29\x4a\x72\x5c\xc4\xee\x7f\x3d\x81\xaa\x1b\xed\x65\xa3\xae\x99\x1e\x51\x45\x13\x33\xc2\x1f\x07\x48\x9d\xad\x2f\x5c\x9d\x7d\x8a\xe6\x56\x8e\x0e\xd9\x11\xf5\x2f\xff\xbd\x8c\x53\x0c\x43\xbf\xd5\x17\xf5\x32\x5a\xa5\x14\x4b\x22\x4c\x1f\x1e\x4b\x31\x61\x26\xa9\x38\xb2\x0d\x95\x06\xba\xc6\x95\x4c\xfc\x94\x55\xb1\xa4\x98\xfb\x1f\xac\xc4\xb2\x8d\xaa\xad\xf4\x73\x48\x7e\x55\x12\x11\x66\xf5\xe1\xab\x63\xeb\x2c\x1d\xc2\xa1\xc4\xc9\x55\xd8\xb5\xcf\xea\xda\x4f\x27\xad\x4a\xa8\xe6\x4e\x35\xc1\xe6\x5c\xfe\xef\x31\x0d\xf8\x4a\x04\x14\x0c\xfb\x32\xa1\x99\x7f\x58\x89\x4c\xb4\x6d\xcc\x20\x1c\x71\x96\x76\xa8\x54\xe5\x38\x5d\xa5\x7d\x19\x0f\xcd\xe0\x23\x4b\x95\x60\x19\xd6\xb1\xbe\x84\x20\x54\x09\x06\xb6\xa7\x00\xea\xd2\x14\xdd\xdb\x97\x4b\x70\x40\xa3\x4a\xe8\x5c\x8e\x5d\x63\x26\x13\x52\xc9\x48\xa0\x9e\xc2\xb7\xf5\x0e\x1d\x17\x71\xf2\xdd\x3c\x3f\x8d\x59\x24\x4a\x12\xcb\x64\xdb\xbf\x9d\x5f\xea\xd0\xd3\x57\x92\x26\xca\xf9\x41\x38\x35\x2d\x87\x5e\x1b\xbd\xb8\x24\x79\xef\xaa\xf6\xb1\xe4\xe7\x3f\x6c\x21\xf2\x1f\xe3\x7a\xa4\x92\x4c\x78\xb6\x80\x33\x3c\xc0\x80\x67\xf6\x40\x24\x03\x8c\x0a\x57\xdb\xdd\xee\x06\x4e\xe1\x76\xc9\xdc\x44\x36\x2b\xe8\x44\x79\x70\x3d\x8f\x00\xd4\x52\x2a\x02\x5c\x7c\xb0\xbe\xd2\x4f\xbd\xff\xab\x8b\x1a\x55\x8a\x25\xde\xc6\xa7\xab\x1b\xb0\xf4\xd2\x52\x4f\x27\x95\xe2\x24\x71\x51\x3d\xc6\x31\xd3\xc5\xf2\x5d\x9d\x6d\xfa\xdb\x94\xb0\x69\x1a\xca\xe7\xeb\x11\x96\x5b\x29\xc5\x85\xbb\x37\xb7\xe2\x04\xd7\xdc\x59\xa8\x52\x5a\x44\xe0\xf1\xaf\xc5\x49\x34\x6f\xde\xca\x7a\x36\x50\x27\x29\x2a\x7a\xfc\x5e\xc2\xf0\x0e\x6a\x11\xa1\xee\xee\xa3\x68\xdb\x55\x7d\x42\x59\x1e\x40\xa9\xae\xe9\x87\xc1\x68\x84\x0a\xdd\x15\xdd\x04\x82\xa7\x4c\x9e\x11\xcf\xb9\xee\x5c\xdc\xbf\xa9\x54\x7d\x9a\x5f\xa7\xd1\xc6\x4a\xbb\x38\xc9\x0a\x4b\xb8\xbd\x12\xc5\x69\x42\x08\xa2\x8d\x4e\xe2\x97\xaf\x21\x8c\xcb\x9a\x9a\xd0\x0c\xa7\x8c\x7b\xdc\x57\x93\x0d\x4d\x58\x86\xe1\x48\xd3\x9e\x77\xaa\x80\xa1\x71\xa2\x09\x8f\x31\x93\x34\xd6\x20\xd5\x2e\x66\xd4\x1f\x8c\x53\x5f\xb6\xeb\xf7\x92\x27\x51\xbd\xce\x4f\x6c\x72\x9f\x0d\xed\x3a\xd1\x7c\x46\xd8\xd6\x94\xc9\xd4\xda\x03\x75\xea\xa5\xdf\xbf\x1d\xe1\xd1\x1f\x4e\x33\x5c\xa6\x9c\x78\x81\xe5\x40\x8c\x26\x80\x66\xc4\xd6\x2c\xbf\xf5\x4b\xaf\xb0\x8c\xb9\xab\x93\x48\xb3\xd4\xce\x40\x0c\x80\x9c\xbc\xd9\x68\x45\xd4\x2c\x85\x3c\x0e\x71\xd8\xa1\x0e\x76\x64\x7e\xad\xd0\x0c\xb2\xd8\x2a\xee\xdb\xeb\x40\x23\xb6\x3e\x4d\x41\x53\xbe\xc9\x4b\xa1\x39\xe7\x08\x18\xd8\x6f\xee\x93\xbf\x2e\xfa\x69\x9e\x51\xe6\xf0\x8a\x06\x1a\x51\xa2\xa8\xf7\x18\xd5\xa4\xb9\x00\xfc\xf2\xc3\x41\xf9\x92\xd8\xc7\xb6\x5b\x54\xc7\x2c\xa1\x7a\x2e\x97\xee\x5f\x8f\xe9\x48\x01\x7c\xa8\x13\x0e\x74\x61\x1d\x43\x86\xd9\xc7\xb7\xc5\xdd\xf3\xfa\xb0\xbd\x3d\x3c\xef\x3d\x9f\x43\x27\x52\xe1\x4b\x81\xe8\x4a\x71\x2e\x82\x25\x02\xd5\x89\xd1\xd8\x4a\x28\xf4\xc1\x8c\xf2\xcf\x4f\xa9\x1e\x3a\x03\x63\xad\xec\x3d\x15\x1c\x65\xa2\xdc\xc1\x3c\x91\x99\xd5\xad\x34\x80\x25\x97\x20\xa5\x3c\xdc\x6f\xc1\x22\xc4\x34\xef\xfb\x68\x3e\x5c\x8b\xd0\x04\x9b\xb6\x5d\x53\x9c\xa6\xbf\x5a\x68\x1a\xbb\x88\xe8\x41\x9c\x60\x6b\xae\x16\x51\xb5\x80\x0c\xf9\xbb\xbb\x33\xa8\x42\x94\xf8\x46\x86\x47\x82\x6a\x9d\x16\x11\x73\x29\x45\x73\x2f\x7e\x3d\x42\xf3\x08\x4d\x1b\xb6\x08\xad\x63\x15\xa5\x23\xd0\xcc\x1c\xd8\xad\xb5\x48\xb0\xc1\x82\xb8\xde\x75\xf7\x12\xe4\x39\xdc\x71\x20\x82\x59\xcf\xe8\x87\xfd\xd3\x62\xb5\x3f\x3c\x3e\x6d\xbf\x6d\x6e\xd6\x4f\x87\xc5\xcd\xcd\xd3\x7a\x17\x9e\x88\xc9\xb8\x25\x7f\x9d\xeb\x6a\xd0\xc5\xf0\x56\x35\xfd\x71\x8b\x11\x9d\xe8\xaf\xf4\x91\xee\x6d\xdd\xf8\x6d\x65\x44\xeb\xd2\x46\x30\xd4\xe8\xf9\xd7\xd3\x1f\xce\x1d\xa3\xff\x42\x77\x14\x22\xa7\x8c\xa5\x8b\x1f\x23\x05\x0b\x88\xa8\xf1\x3b\xa2\x9b\x4b\xe3\x2d\x23\xf3\xa3\xa4\x00\x17\x83\xfb\x9d\x7f\x64\xa2\x3b\x9d\x19\x40\x59\xac\xd0\xfd\x11\x45\x2e\xfc\x93\x05\xaa\xc8\x88\xcc\xb8\xaa\x2b\x5d\x7c\xc6\x51\x9d\x6e\x59\x40\x95\xd5\xaa\xc2\xbb\xfe\x3c\xdc\x6e\x60\x11\xc7\xda\xeb\xcd\x45\x09\xd1\x85\xbf\x32\xe5\x85\xf7\xb1\xbe\x6a\x01\xe8\xcb\xb7\x7d\x23\xd4\xeb\x66\xf6\xea\x03\x8b\x53\x74\xf4\x28\xda\xbb\xa2\x7a\x9d\x35\xbe\xfc\x98\x14\xd0\x6a\x0b\x7e\x75\x37\xd0\x76\x4d\xfd\xf6\x50\x54\xff\x2b\xe6\x67\xd2\x14\x0b\xa4\x98\x22\x8d\xe2\x42\xe0\x8a\xe0\xeb\x77\x1e\x32\xa3\x29\xc8\x00\xb8\xb6\x8d\x2d\x8f\xce\xfd\x4b\xb9\x97\x0f\xfd\xc7\x28\xc4\x3c\x46\x15\x54\x5c\x43\xbe\x34\x00\x15\x8c\x08\xb9\x1f\x2e\x6a\x10\x6b\xe6\x0b\x69\xcb\x4e\x8d\xe7\x49\xa2\x00\x29\xad\x9d\x78\x1d\x21\xc3\xa7\x3f\x3e\x8d\x29\x82\x89\xee\x37\x0f\x73\xb5\x77\x0a\x69\xca\x31\xb1\xd7\x50\x16\x3f\xae\xf8\x91\x4c\xc2\x7d\x48\x15\xcd\x9c\x1d\x4a\x71\x2e\x70\xa6\x37\xc1\x0c\x84\x42\x16\x07\x72\x85\x7d\xb2\x0e\x48\x77\x35\xc5\x81\x9c\x03\x82\x55\x90\xbd\x4c\x0e\x16\x3c\xe1\x8e\x89\x28\xf5\x2a\xbc\x5f\xa0\x02\xb7\xad\xce\x75\x96\xa7\x53\x41\x44\x59\xa6\x83\x21\xca\x73\xd5\x06\x03\xa6\xfe\x98\x60\x03\x98\xf3\xbe\xa8\x3c\x78\xed\x0a\xfd\x18\x84\x4e\x11\x01\x80\x96\x1d\xdb\xcb\x70\x51\xc6\xaa\x75\xe2\x02\x3f\xb5\x73\x75\x23\x24\x10\xa4\x5c\x1f\x74\xbf\x8b\x9e\x8a\x0a\x56\x2f\xa2\x7f\x2d\xa1\xd9\xbf\x9d\x67\xd5\x78\xd0\x34\xb1\x4e\x1a\x9e\x7f\xc2\x66\x03\x20\x8f\x11\xb0\x83\xb4\x6a\xbb\x9e\x25\xfe\x62\x40\xd3\xdc\x15\xc0\x1e\xb7\xdb\x3b\xdb\x3a\xa4\x99\x3f\x6c\xa2\x2c\xb7\x0d\x36\x04\xc7\xdb\xed\x75\x10\x81\x00\xc3\x33\x6c\xb3\x04\xcd\x35\xb4\x0a\x80\x62\xfa\x7a\x99\x28\x26\xcc\xb1\x79\x0e\x9d\x75\x16\x9a\x0f\x48\x11\x79\x7a\x5b\xd7\xf7\x9e\x02\x3b\x91\x0c\x30\x51\xce\xb1\xb2\xb2\xec\xe3\x3d\xf5\xe2\x0c\x95\x66\xa7\x21\x51\x62\x0b\xae\xfe\xbe\x39\x77\x96\xc9\xf4\x33\x44\xca\xd8\x4a\x80\x95\xe5\x3d\x2c\x76\xa0\x1a\x98\xf6\x53\x0d\x31\x90\xe7\x81\xaf\x70\x2f\xaa\xb7\xb1\x92\xca\xac\x0b\x67\x28\x8b\x10\x8a\xb9\x6c\x40\xbc\xca\xa2\x6b\xd7\x4f\x2b\x1a\x8d\x83\x4e\x43\x39\x75\x62\xd9\xdd\xe1\x54\x54\x37\xeb\x7d\xbf\x42\xd8\x5c\xf0\xbe\x6e\x60\xff\x22\x66\xbd\x12\x43\xe3\xcc\xaa\x58\xd5\x4d\x77\x3d\xc9\x36\x54\x46\x58\x78\x3f\xd8\x76\x4f\x9f\xde\x4f\x79\xab\xd3\x77\xc5\x30\x46\x72\x2b\x83\x74\x3c\x96\xb0\x87\xb6\x43\x0f\xc8\x21\xea\x32\xcc\xcd\x87\xb2\x16\x7a\x64\x80\xd7\x1f\x00\xec\x1e\x89\xb2\x74\x89\xe4\xad\xcb\x47\xfd\xdb\x61\x78\x14\xa3\x74\x64\xfb\x72\xe9\x74\xfd\x73\x2c\x3e\x33\xdb\xc7\x0d\x97\x5a\x46\xa1\x4d\x35\x8e\x20\x4d\x2c\x62\xae\x66\x14\x3a\x7f\x2c\x85\x1c\x15\xd8\xdb\xfa\xd2\x28\x98\xa0\x89\x8d\x20\x2a\xb7\xd1\x20\x56\xd1\x21\xac\x6e\x46\xe4\x14\x21\x20\x96\xfa\x34\x20\x03\x8d\xd0\x0a\x97\x8e\xc3\x31\x20\x85\xfc\x21\xc9\x2c\x8b\xdc\x7e\xc6\xba\x39\x39\x74\xca\xf7\x17\xa8\x9c\x05\x67\x7f\x77\x79\xe4\x3e\xa2\x24\xc3\x80\xf5\x4b\x5d\x6a\xa8\x96\x97\xd2\x5a\x28\x4e\xa6\x81\x02\x8e\x68\x4d\xed\x1c\x9c\xb0\x42\x76\x6d\x9f\x35\xa0\x59\xec\x14\x99\xfa\x38\xeb\x14\xbc\x3a\xa9\x31\x69\xee\x31\x5b\x8b\xa7\xa7\xc9\x9d\x65\x51\x44\x6d\x17\x5d\x5e\x9a\xea\x61\xf7\x78\x7d\xd5\x64\x51\x14\x73\xe9\x58\xe2\x3e\x24\x3c\x7c\xd9\x5c\x67\xc2\xb2\x28\x4a\x35\xf6\x5c\x1b\xd1\xc1\xad\x2f\x03\xfe\xe6\x0e\x52\x10\x04\x3c\x30\xb1\xa8\x74\x53\x9f\xaf\x05\x6f\xfd\x40\xc5\xad\xaa\x9d\x7a\xb5\xdd\xd1\x49\xa9\x92\x45\x2c\x8a\xd0\x95\xe6\xe0\xbb\x57\xc8\x62\xfa\xd0\x08\x98\x45\x8c\xb3\x94\x60\x0b\xb9\x70\x72\x8a\x4f\x97\xd2\x6b\x72\x67\x57\x83\x0d\x16\xb1\x2c\x75\x26\xa3\x55\x34\x6a\xcf\xb2\x88\xe5\x91\x1a\x9b\xdf\x8d\x7d\xf2\xe7\x3b\xd9\x55\x91\x48\x16\x31\x65\xc9\x24\x42\x7b\x23\xc8\x27\x78\xb7\xdc\xb1\x88\x69\x85\x05\x0c\x54\x10\x08\x5f\x6f\x72\x93\x0e\xc5\xbd\xaf\xfb\xed\xb4\x6f\xe7\x86\x71\x96\xa2\x43\x86\x84\x63\xa8\x8b\xb2\x88\xa7\x31\xe2\x6e\x30\x82\xfa\x0e\x85\x0f\x73\xfc\x61\x49\x11\xbd\x12\x7c\x0c\xfd\x81\x38\x63\x58\x62\x33\x00\x83\x79\xd3\x2b\x54\x8b\xb2\x9c\x7d\x6f\x92\x68\x9e\x4f\x2d\x7c\x3f\xcf\x22\x58\x94\x46\x0a\xe3\x25\x57\x4e\x3c\x3c\xad\xbf\x2f\x9e\x6e\xfc\x57\xa7\xdc\x8a\x5d\xee\x9e\xa7\xb2\x47\xfe\x70\x6a\xdd\x3d\xcf\xe2\x0d\xd3\x7c\x64\x6b\xfb\x83\x19\xd5\xd4\x76\xd2\xdd\xba\xa7\xff\x92\x39\xfb\x5e\xf2\x8b\x45\x19\x27\x3a\x0f\xd1\x7e\x23\xc2\xed\xcc\x53\x81\x35\xbb\x17\x28\xf5\xc8\x60\x8e\x45\x42\x32\xee\xc1\xaf\x75\xd5\xc1\xac\xc0\xcc\x22\xa9\x84\xc5\x9b\xb9\x90\xcc\x9b\x8c\xb1\x48\x19\x8e\x75\x87\x4b\x85\x75\x93\x41\x34\x9c\x45\x9a\x48\xb4\x73\x45\x54\x54\x9f\x09\x8c\xb0\x0c\x2c\xd2\x79\x8c\x78\x46\xa7\x13\x85\x59\xe8\xdf\xfd\xb1\xd3\xa9\xaf\xa5\xc2\xc8\xea\x06\x1e\x60\x2c\xbe\xc2\x22\xe0\xd6\xce\x6b\xb1\x5c\xae\xc6\x07\x08\x61\x1a\x43\xa8\x17\xd1\xf4\x99\xe5\xa3\xf5\x17\x09\x47\xb5\xa4\xc6\x4b\x03\xe3\x7c\xc7\x00\xe5\xea\xdb\x4a\x08\x58\xb2\x80\x23\x01\xf6\x33\x74\x22\x21\xc0\x08\xd5\x4e\x3b\xca\x26\x40\xd6\xb4\xe3\x63\x4c\x28\x23\x2c\xe7\x18\x94\x1e\xb0\x14\xbd\x7f\x19\x74\x8d\x3f\x6d\xce\xf7\x1f\xb4\x82\x77\x36\x5f\xd9\x95\xa2\x7d\x99\xbf\xa5\x84\x13\x95\xd8\xbd\x50\x89\xb2\x7d\x82\xf3\x27\x90\xa1\x8f\x6b\x2a\x8c\x70\x91\x67\x5e\x6d\xc5\x62\xd4\xfd\xef\x8d\xb9\xdb\x06\x91\x0e\x7c\xf5\x25\x22\x71\x92\x22\x13\xfa\xae\x3e\x3e\x61\x29\xe4\xbb\xd7\x71\x9a\x65\x31\x8c\xc4\x79\x2a\xf4\xe0\xae\x72\x75\x89\x22\x31\x58\xe3\x2b\x94\x42\xf2\xef\xfc\xd4\xc5\xce\x4f\x59\x92\x90\x48\xcb\x51\x5b\x68\xf6\x7d\xa9\x8e\x70\xc3\xdf\xed\x17\xfb\xe7\xdd\xe1\x71\xb1\xf1\x2f\x37\xc9\x55\x82\x55\x5e\x55\xd7\x25\xc6\x02\x61\x87\xef\x43\x90\x1c\x79\xe4\x03\x76\xe7\x8a\xe3\xcd\xfc\x52\x04\x49\xd1\x83\xe2\xb6\x5b\xf9\xf3\x08\x1e\xa1\xcf\xf2\x41\x59\xed\xc6\x65\x79\x81\x73\x53\x4c\xb1\x71\x76\x98\x18\xe3\xe1\xab\x87\x3a\xa4\xdc\x8f\xa5\xa8\x86\xf3\x39\xf3\x48\xb7\x48\xba\x18\xf3\x3a\xfd\xe9\x4a\x69\x98\x11\x21\x09\xe2\x47\xd0\x0f\xa3\xaa\x40\xd9\xe2\xea\x55\x6a\xce\xfc\x4d\xbd\xfe\xf4\xa5\xb0\xca\xa4\x36\x11\xb2\xcb\xdd\x75\xf8\x11\x23\x2a\x56\x28\x3f\xff\xda\xaa\x1b\x87\x6a\x7e\x87\x9f\xbb\xbc\x47\x09\x33\xa2\x52\x2b\x9a\xe7\x45\x3b\xfc\x0d\x51\x12\x72\xe1\x55\x23\xe6\xfe\x25\x8c\x28\xed\xb4\x63\x30\x80\xde\x8b\xfe\x93\xd3\xb9\xa6\x8c\x9d\xf9\xd6\xf6\xee\xd8\x88\x93\x3f\xb5\x4e\x08\xce\xfc\x00\x95\x9a\x85\x0c\xe1\xb9\xeb\x34\xc5\xca\x86\xeb\xf2\xfb\xa0\x73\x64\x43\xc2\x88\xce\xac\x00\x71\x30\x1d\x9c\x50\xf6\x67\x77\x49\x2b\x81\x2f\x49\x57\x9c\x60\x5f\x3f\x57\x28\x83\x7d\xf3\xf5\xeb\xfd\xbd\x3f\x1d\x04\xbf\xa4\x51\x90\x36\x7d\x2c\x90\x51\x2c\x6f\x15\xed\xd4\x5c\x78\x3e\x2a\xcb\xdc\x96\x79\xcd\xe7\x69\x34\xdb\x47\x4b\x9a\xc9\xcc\x80\x4f\x6c\x07\x70\x15\xa3\x11\xa5\x08\x69\x08\x24\xee\xdf\x41\x0a\xb9\xbc\xbc\x59\x52\xc0\xf4\xe9\xd0\x88\xcb\x4c\x86\x2f\xbf\xa2\xff\x19\xc6\x29\xe5\x72\xb3\xbb\xa2\x82\xe7\xf3\x1a\x01\x52\x87\xf3\x48\x76\xf1\x1f\xb3\x53\xc7\xdc\xdb\x13\x78\xe3\xed\x77\xf4\x2b\x46\xa3\xc4\x2e\x34\x63\xf6\xa5\xd7\xd8\x08\x60\x13\x46\xa3\x9c\xa0\xa4\xc8\x77\xf1\x2a\xfa\x7f\x86\xba\x0a\xa3\x91\xe1\xf1\xd0\x8b\x5f\x16\x7a\xf6\x1b\x09\xb7\x48\xff\x61\x7e\xf9\xb2\xcb\x6c\x5c\xcc\xad\x3d\xff\xb4\x38\xc3\x7e\x0e\x61\x2c\x25\xb9\xb6\xec\x38\x7f\x77\x7d\x77\xf5\xea\x86\xeb\x3e\x44\x69\x82\x49\xc7\x17\x71\x82\xdd\x98\xb6\x31\x1b\xc7\x32\x82\x25\x36\xa1\xf5\xa9\xae\xe0\x1d\x16\xeb\xfa\x7e\x4d\xb9\x4a\x10\x24\x60\x84\xd3\x4a\x1b\xeb\x40\xfb\x31\x90\x45\x23\x77\x2f\xd7\xde\xbf\xfe\xe0\xb8\x91\xd6\x13\xb4\xbf\xd4\x7e\x49\xb6\xad\x7c\x7f\x0b\x62\x66\x0d\x16\x4b\xd1\x76\x3b\xf5\x02\xfa\x52\x82\xde\xd7\xe7\xe7\xb3\x1f\x91\x10\xab\x0b\xd6\x3d\xc1\xd1\x51\x1c\x9b\x30\x3f\x13\x45\x70\xba\xbf\x88\x76\x7b\xee\x03\x3a\x1f\xb5\x41\x33\x06\xf6\x13\x9a\xb9\x0f\x64\x51\xc6\x5c\xb4\x7c\x57\xc8\x46\x34\x85\x78\xa7\x5c\xe6\x86\xe6\xd4\x18\x37\x74\x77\x39\x43\x33\x51\x61\xf6\x63\xa4\x89\x07\x89\x8b\xf0\x4e\x4e\x96\x24\x2a\x69\xe6\xe1\x6c\x8b\xe6\xf4\x76\x7b\x29\xcb\x77\xe5\x6b\x46\x65\x92\x20\xab\xe7\xa7\xa8\xba\x4d\x77\x5b\x37\xfd\xd2\x32\x1f\x93\x01\x92\xe0\x95\xf5\xe2\xf9\x88\x3d\xc1\xa8\xe2\x44\xa7\xe3\x62\xfa\x1e\xe1\x85\xcf\xcb\x70\xe3\x55\x12\xa3\x3f\xb0\xef\x0e\x1c\x7e\x40\x33\x0a\x77\xa9\x4a\x04\x86\xbb\xce\x7e\x7f\xbc\x48\x53\x25\xa9\x37\x02\xc4\xa7\x31\x77\x06\x63\x54\x81\xc2\x7c\x71\xf5\xb4\xfd\x7e\x83\x80\xc1\xc5\x6a\x35\xe0\x27\x19\xd5\x52\x69\x97\x6b\x3e\x5c\x4e\xbf\x57\xc5\xf1\xc5\xcb\xd4\x31\xaa\x55\x8c\x98\x64\x6b\xe3\xd2\xbf\x10\xc4\x57\xbd\xc2\x18\x88\xec\xca\x74\x70\x06\x52\x8f\xe5\xa5\x7d\x12\x8d\xd7\xd8\x09\x37\x1f\x38\x8d\x9c\xe4\xc7\x7f\x27\x24\x12\x77\xdc\x90\x1c\x2b\x55\xed\x4b\xfd\xd3\x72\x8f\xf5\xc4\xca\x66\xfa\xbc\x0d\x97\xb8\x3d\x2d\x45\x23\x3d\x54\x88\x51\x23\x24\xaa\x96\xe2\x7b\x26\x83\xb3\x09\xeb\x43\x59\x44\xb5\xed\x8a\x0a\xfb\x03\x45\xf7\xb6\x87\xb6\x8b\xfd\x71\x16\x83\x37\xcc\xdd\xac\xb6\x3b\x4f\x77\x9f\xde\x4c\xc6\x32\x12\x5c\x39\xec\x55\x4d\x58\x8f\xd7\x5f\x64\xc6\x84\x36\x76\xae\x5c\x9a\x16\xda\x3b\xa8\x8e\x5e\x03\x80\x31\x26\x23\x5c\x1c\x0e\x2d\x9a\x42\x5e\xb3\x2a\x98\xd7\x07\x18\x63\xca\x06\x2b\x85\xaa\x6f\xd1\x02\xd9\x9f\x8d\xf3\xd8\xee\x1f\x8d\x40\x92\x96\x17\x6f\x62\x8c\x43\x1e\xd9\x2a\xaf\x3e\xd7\x25\x3c\xc1\x7f\xc2\x11\xa3\xa3\x01\x35\x7c\x5b\x54\x6a\xa6\x08\xe4\xc6\xc5\x91\xd5\x3f\x33\x75\x23\x0b\xad\x01\xcd\x4b\xc3\x34\x65\x31\x4d\x35\x0d\x59\xd9\x72\xb1\xbf\xbe\x0c\xb1\x24\xcf\x10\x25\x5c\xf4\x31\xa5\x43\x93\x12\x9a\xb9\x17\x87\xd0\x6c\xb4\x1f\xb2\x44\xe8\x8c\x79\xe2\xc5\x9c\x25\xcd\x58\x62\x32\xa4\x0f\x7d\x81\x60\x5c\xf9\x54\x1c\xfd\xcc\x64\x29\xa1\xd6\x8a\xce\x26\x5d\xb3\x24\x93\xa5\x82\xe2\x5d\xb4\xf8\xc5\xbb\x5a\xbd\x0e\xc8\xc8\xbf\xe2\x9e\x5c\xad\x08\xb8\xf3\xe6\x34\xc1\xbc\x04\xd1\x40\x87\x9f\xd7\xdc\x65\x19\x13\x24\xd2\x76\x2a\x35\xba\x3d\x74\x45\x87\x6e\x79\xf3\x41\x14\x70\x8b\xeb\xd7\x64\xe4\xbd\x1f\x7e\x90\xec\xab\x68\x5f\x0e\x6e\x9c\xff\x29\x22\x13\x9e\x56\xee\xd0\xdb\x4e\x97\x68\xfa\xd6\x30\xa1\x04\xb6\x36\xef\xd5\xb8\x37\xfb\x51\xd7\xa0\x9f\xb9\x12\x69\x9c\x5a\x34\x28\x2e\x10\xa6\x93\xe2\x12\x81\xc3\x50\xe9\x43\xe5\x15\x75\x18\x53\x32\xc3\x72\x74\x50\x91\x76\xb5\x32\x7f\x18\x24\xae\x9a\x0b\xad\xbf\xd4\x6d\x3b\x52\xb9\x9b\x7c\x2b\x64\x80\x0c\x24\x70\x7e\x9b\xde\x50\x71\x33\x6b\x61\x8d\x1a\x59\x8c\x19\xa5\xd0\xde\x0d\x53\x9b\xb0\xfe\xcf\x32\x09\x1e\x89\x3c\x75\x80\x7f\x31\xa2\x6b\x8e\xcf\xc4\x23\x9d\x29\xfb\xdb\x54\xad\xad\xac\xc3\x2d\xfc\xb5\x48\xbf\xff\xb4\xa1\xb6\xb8\xf6\x52\xff\xb4\x0d\x52\xe8\x44\x51\x4e\x89\x65\x8c\x13\xa6\x11\x99\x77\x30\x75\xd3\xa7\x5f\xa3\x7a\x2b\xe3\x24\x8f\x71\x5e\x6f\x56\x56\xdd\xbf\xdd\x38\x31\x83\xeb\xef\x14\xa7\x0c\xc0\x26\xd7\x08\x89\x0e\x86\xc6\xfe\x30\xe7\x1e\x0e\xbb\x5a\x7e\xd0\x03\xf6\x43\x63\x86\x61\x3d\x5e\xce\x44\x80\xc2\x0f\xd0\xa9\xb2\x51\x57\xb5\xde\xee\xfc\x37\xb0\x84\x4a\x18\x82\xdd\xbf\x5a\x12\x39\x4f\x4c\x36\x16\xfa\xb6\x19\xce\xe4\xe5\xe6\x3c\x15\x5e\xe8\xdd\x79\xd2\x39\x82\xef\xf4\x46\x72\x88\xac\xb5\x99\x28\x61\x5a\x51\xe0\x69\x64\xbd\xa5\x84\xd6\xfd\x4b\x03\x2d\xf1\xcd\x0d\xc6\x53\x0a\x3e\xbb\xbd\x17\xbf\x1e\x9b\xda\xcc\x7a\x38\x8c\xa7\x29\x45\x69\x39\x67\x9f\x2b\x34\x1a\x88\x4e\xae\x31\x8b\x18\x56\x09\xfa\xbd\xef\xbb\x28\xba\xa2\x3a\xe2\x7b\xda\xce\x4e\x95\x11\x40\x1d\x95\xf7\xf2\x98\xff\xb8\x0c\x22\x5b\x7e\x11\x0c\xa2\x7c\x8c\x67\xb1\x46\x35\x0b\x2b\x60\x30\x18\x49\x66\xff\x18\xef\xad\x3c\x4b\x45\xea\x09\x6a\xf6\x4a\xd6\xd5\x98\x13\xc3\x78\xa6\x35\xae\x37\xeb\xfd\xd7\x34\x8e\xea\x2a\xe6\xfe\x48\x1e\x49\xdc\x9e\xc4\xc7\xc9\x0c\xcf\x59\x8a\xcf\xc2\x00\xe8\x7b\x68\xdb\x91\xdb\xc3\xb5\xaa\x07\xcf\xa5\xa5\x6d\x1e\x10\x03\xed\xff\xa8\x25\x02\xfd\x2a\xd3\x3e\xd6\x75\xf9\xae\x58\x33\xbd\x65\xb9\x49\x50\xb5\x59\x74\x1d\x9c\xce\xdd\xee\x0c\xd5\x2c\x03\xe0\x88\xfb\x0b\xbc\x68\xcc\x99\xfc\xae\xc6\x25\x37\xf8\x64\xfe\x28\xaa\xa3\x7a\x81\x71\x25\x9e\x71\x45\x33\x0d\xe3\x70\x7f\x79\x69\xaa\x2f\x75\xa9\x47\x06\x27\x57\x4a\x86\x5c\xb1\x84\x44\xc1\xb1\x81\x84\xd3\x65\xc2\xc8\x60\xa0\x70\x0d\x7b\xca\xb8\xe6\x29\x82\x2d\xe5\xa5\x7c\xb5\x5b\xe4\x9d\x38\xc9\xfa\x33\x6f\x17\xff\x49\x90\xc2\x45\xb6\xcf\x2d\x3c\x81\xed\x7f\xcc\x4e\x0f\x91\xe2\xe9\x00\x04\xda\xa9\xba\x79\x37\x24\x95\xb9\x03\x1d\x1c\xc5\x09\xfa\x8d\xa7\x1c\x87\x22\x1c\xf2\x14\x1c\x4f\x31\x64\x61\xdc\x44\x39\x06\xc3\x9b\x87\xfd\xdf\xa3\x9d\xf7\x1f\xb1\xe8\x98\xd5\xdd\x62\x73\x7f\xd8\x0d\xde\x9a\x8c\x1b\x1e\xa5\x3a\xe8\x3a\x9a\xba\x39\xbd\x9b\x6a\x86\x33\x7c\xee\xbb\x6f\x03\x28\xff\x5b\x44\x22\x72\x20\xf3\x91\x71\xee\x75\x8a\x1f\xfc\x42\x3d\x9b\x21\x26\x95\xa8\xe2\x7d\x38\x5a\x0d\x1f\xb8\x29\x5a\x55\x9c\x4b\xf8\xdb\x9e\x3a\x2c\x8e\x52\x4b\x8d\x3c\x1c\x2f\xa2\x11\x55\x07\xfa\x5d\x2e\x1a\x47\x59\x12\x3b\xf1\x0a\x8c\x32\xea\x72\x64\x9a\x3b\x9a\x41\x71\x94\xa5\x18\xd0\x58\x14\xc7\xfd\xe2\x0f\x77\x67\x62\x92\x26\xc8\xff\xea\xb7\x8d\x83\x55\x4b\x3a\xd4\xe6\xa0\xc5\x5b\x7b\x68\x8b\x4a\xc1\x41\x8a\xea\xf5\x50\x9f\xa1\x0a\xdd\x72\x16\x53\x92\x60\xec\xf6\xc7\x9f\xab\xd5\x7e\xbd\xdb\x87\xbf\xa7\x56\x39\xf4\xb6\xee\x5f\xea\x39\x9a\x63\xf6\x03\x69\x46\xb0\xdb\x74\xb3\xd8\x7d\x5d\x2c\x37\xbf\xcd\x8f\x26\xa9\x13\xc2\xea\xa3\xf2\xf5\xaf\x0e\xaa\x36\xa4\xf3\x7d\xe8\x33\xfc\x3a\x16\x1b\xfc\x11\x07\x44\xf7\xd5\x3f\x0a\x6d\x8b\x03\xb7\x05\x94\xfa\x9d\x93\xd3\x55\xf9\x99\x7f\x5c\xd9\x91\x63\x96\x26\x5e\xab\xf7\xc6\x7a\x9f\x4d\x96\xe1\x98\xe5\xca\xc3\xa6\xee\x8b\xca\xea\xe7\x9d\xeb\x06\x51\x6a\x43\xed\xc5\x66\x5e\x16\x9b\x37\xf9\x89\x3c\xa7\x88\x46\x53\x75\x59\x7b\x07\xa3\x71\x73\x28\x8e\x73\x9e\xb8\x52\xc3\x20\x06\xb5\x2b\xfe\x3b\x9b\x6e\x71\x42\xad\x4d\xf9\x11\xba\x10\x01\xed\x8b\x59\x8b\x9f\xc5\x89\x60\x48\x22\x78\xbc\x5b\xec\x6f\xb7\x4f\xf7\x87\x2f\x4f\xdb\xef\xfb\xaf\x07\x8f\x7b\x1d\x13\xdc\x58\x9c\x46\xd6\xd8\x14\x9d\xb5\xcd\x03\xa8\x7e\xfd\x6d\xde\x66\xe7\x4c\x45\x84\x82\x5f\xbb\xd5\x66\xb7\xdb\x3e\xed\xc2\xa7\x45\x8c\x46\x17\xd6\xfd\xd2\x66\xe2\x83\x4b\xe8\xfc\x24\x32\xf5\x15\xfd\x7b\xf1\xcb\xb6\x7a\xb7\xc6\x40\x83\x12\xfe\x7e\xb7\x89\xb3\x84\xf8\xfe\x21\x36\xbb\x3f\xc0\x54\x7c\xf0\x3e\x65\x69\x1c\x7b\x2e\x18\x34\x2b\x51\x3d\xd4\xdd\x13\x40\x1f\x9b\x0f\x77\x3c\xcb\x99\x63\xdb\x75\xeb\x5f\xfd\xa3\x0c\x3b\x59\x9c\x01\x43\x63\x8d\x7f\xd6\xb2\xbd\x06\xa6\x64\x71\xae\x40\xbb\x95\x0e\x4b\xcf\x93\xb9\x22\xc0\xae\x72\xdf\x8a\x7a\xd2\x05\x89\x21\x0d\x6a\x18\xab\xa6\xe8\x0a\x25\xca\xe5\x05\xad\xce\xa6\xd7\x0f\x20\x11\x6d\xfd\x05\xaa\xaf\x50\x16\x75\x3b\x2a\x5a\x25\x24\x32\x2c\x75\x75\xaf\xa6\x7e\x5b\x79\xc2\x1f\x4b\x08\x49\x91\x7c\x60\xa3\x09\x92\xdd\x16\xe5\xa9\x1d\x77\xb1\x59\x42\x49\x82\xd5\x7e\xe1\xb1\x8c\x37\xce\xaa\xc9\x93\xb6\xbf\xc3\x38\x3b\x4f\x28\x01\xe2\xfc\x16\x3f\xa8\xa0\x26\xb4\xdf\xec\xfa\x88\xbb\xec\x9a\x4b\xd1\x9e\xee\x47\x94\x96\xeb\xcf\x27\xa1\x39\x45\x3c\xd0\x1e\x1c\xb3\x64\xf8\x75\x34\x37\x9e\x31\x75\xb0\x44\x1b\x51\x1e\xe4\xdb\x61\xce\x29\x61\x09\x67\xc0\x06\xab\xa0\x0f\xe5\xdc\x58\x92\xc6\xd4\x17\xc7\xfa\xa3\x5e\xc0\xd3\xa2\xaa\xfd\x98\xc4\x8a\xe5\x1f\xea\x9f\xf5\xd8\x58\x8e\x25\xa9\x91\x98\xf7\x9c\x9d\x35\xd4\xf4\x7e\x66\xa9\x8d\x5a\x6e\x1a\x71\xac\xab\xdf\xc7\x56\xe3\x93\x55\xe6\x0a\xf8\x3b\xdc\xc0\x4c\x49\x32\x54\x19\xdd\x8a\xf6\xa3\xe8\x40\x63\x61\xff\x6a\x7e\x9e\xe4\x39\xc7\x66\x17\x02\xfa\xd7\xfb\xaf\x8e\xc5\x33\x81\x85\xf5\xa3\x2c\x38\xd3\x67\x88\x80\xce\xd2\x2b\xe7\x40\xe9\x07\x09\x93\x12\x2f\xcb\xf6\x43\x94\x33\xfe\x25\x4b\x44\x64\xd7\x46\x07\xdf\xc7\x0e\xfd\x08\xac\xda\x0f\xb0\xea\xd7\x47\xe8\xfa\xfc\xd6\xa7\x23\x93\x4c\xca\x0f\xd5\x22\xa3\x6e\xa9\x29\xaa\xa3\x65\x7d\x87\xf3\x98\xc8\x09\xe3\x56\x97\xc8\x47\x8f\x89\xcc\x0d\x8a\x0f\xc8\xfe\xb2\xdf\xfc\xfb\xe8\x0f\x0a\x1a\x53\x2f\x76\x52\x96\x5b\xa7\x05\xad\x20\x5c\x9c\x22\x14\x9b\x04\xf7\xe2\xd7\x58\x1a\xab\x3f\xc0\xbd\x42\x46\xa8\x99\x8f\x5b\x29\x7e\x58\x66\x09\xdc\xcf\x53\x1e\xf9\x7c\x54\x9e\x5a\x95\x71\xf1\xb6\xbd\x74\x53\x7f\x3f\x37\x44\x67\xd4\x03\xfb\x7f\x16\x55\xbf\xc7\xba\xe3\x91\x0f\xf3\x12\x6d\x12\x84\xbe\xae\x7f\x81\xba\x20\x4b\x75\x19\xac\x33\x59\x02\x42\x60\x1d\xcd\xce\xf8\xfe\x52\xef\xe1\xf4\xfe\x5d\xbb\x42\x3d\x66\x89\xa1\x8a\x59\x75\xb4\x5f\xdf\xa1\x78\xae\xb0\x22\x51\x84\xbc\x39\x31\x19\x58\x1f\xed\x7e\x37\x9f\xdd\x63\x03\x26\x4d\x2c\xf1\xed\x54\xdf\x16\xed\xcb\xbb\x86\x79\x4a\x22\x81\x4c\xa4\xa2\x32\x8d\x58\x77\x2f\x63\x36\x00\x4b\x09\xcb\x21\x09\xea\x3e\xab\x9b\xeb\x55\xec\x94\x12\x8f\x9c\xe8\x9e\x44\xa5\xeb\x93\x73\xd1\x9f\x8d\x92\xd6\x6d\x1e\x5b\xe4\xfe\x3a\xdc\xf2\xf5\x7d\xbd\x19\xa8\x65\x2c\x65\x82\x67\xee\x8e\x6f\x2b\x68\xa1\x34\xc3\x11\x2b\xb1\x73\xee\xa7\x8a\xfd\xb2\xdb\x7e\xe1\xa3\x37\x20\x42\xb8\xda\x8f\x72\x82\xb9\x95\x9e\xb6\xe9\xfc\xcb\x9b\x32\x43\xb0\xe5\xdd\x7d\x90\x6a\x38\xc2\xa9\x7b\x26\x43\x20\x93\xf2\x58\x60\x97\xd2\x09\x37\xda\x9e\xe0\x8c\xa2\xc0\x52\x9e\x64\x7c\x02\x80\x9b\xf2\xdd\xfc\x28\x6d\x2b\x95\x2d\xa8\xba\xd2\x6d\xbf\x23\x59\x77\x02\xe7\xee\xed\x7f\x4f\xcc\x08\xc6\x72\xc7\x9f\x50\x2c\x97\x37\xf8\x9e\x6c\xaa\x60\xbf\xc6\xd2\x38\x89\x90\x05\xda\x08\x63\x4a\xf0\xba\x06\x2c\x8d\x45\x4a\x95\x77\x32\x68\x5f\x1e\x0b\x35\x2e\x61\xf9\x41\x32\x8f\x07\x22\xf5\x93\xa8\x5e\x8b\xea\xb8\x3b\xd7\x61\x37\x49\x93\x48\xe1\x2c\x41\xb0\xfd\xbd\xe8\xd4\xcb\x87\x01\xf2\x07\x7f\x9e\x2e\xaa\x63\x4a\xef\x64\x8e\x24\x24\xf2\xe8\xe7\xdf\xe1\x6d\x2c\x16\x42\xc2\x90\x8c\xe0\xaa\xb2\xf3\x28\xd0\xcd\xcd\xa4\x34\x3a\x0c\x34\x80\xb0\xd6\xc3\xa5\x6a\x85\x81\xcf\x73\xca\x34\x03\x4b\xc5\xb0\x09\xd8\xc7\x42\x13\x2c\xcd\x33\x86\x91\xec\x51\xb4\x4f\x80\xce\xa6\xe1\x76\xe7\x9a\x32\x17\x27\xdc\x96\xf5\xcf\xd0\xdf\xb8\x8a\x7b\x4a\x05\x63\xc9\x98\xd3\x74\xb3\xf9\x36\x92\x8a\x62\xa9\x88\x35\x42\xb6\xba\x97\xa6\xbe\x1c\x5f\xce\x97\x6e\x5f\x6b\xf1\x16\x0e\x27\x82\x7a\x3e\x8f\xd5\x09\xfa\x21\x3a\x78\x2c\x85\x1a\xb9\x67\xb0\x54\x2a\x8d\xf4\x37\xed\x74\x75\xc6\xfe\x14\x2c\x55\x24\x47\xe1\x85\x46\x54\xaf\xb3\xf7\x55\xa5\x1a\xcb\x39\xed\x45\x7e\xc4\xed\x65\xa9\x52\xd4\x44\x73\xcb\x2a\x57\xc6\x9e\xfe\x5a\x9d\x10\x13\xc8\x81\xf7\x53\x6f\x27\x96\xea\x3c\xc5\xad\x0a\x39\x5a\xd5\xdb\xbb\xd7\x55\x2b\x85\x37\xbd\x6b\x9c\x6c\x2f\x78\x70\x40\x11\xd6\xbb\x14\xb4\x35\x7c\xba\xb5\xba\xcd\xc8\x9c\x7e\x1b\x0e\x1a\xab\x40\xd4\x7f\xff\x6a\x30\x22\x5f\x34\xc7\x0f\xba\x78\xa9\x21\x29\x06\x20\xd6\x70\xaa\xa8\x8e\x36\xc2\x58\xd6\xf5\xeb\x07\x45\xb2\x2c\x62\xd6\xa5\xb8\xcf\xd5\xec\xf4\xbc\xbd\x94\x25\xe6\xdc\xb3\xc7\x9f\x45\x32\xd2\xdc\xd3\x9d\x6a\x53\x74\x23\x17\xa2\x6b\xb4\xc4\xfe\x13\x20\x94\x2f\xe5\x76\xa2\xfc\x5e\xfc\xf7\xbf\x8f\xa2\xd2\x62\xd8\xf9\xe7\x9f\xd0\x2c\x71\x6a\x78\x75\xf9\xa3\x4f\x71\xcf\x97\x0e\xfa\x0d\x77\x56\x52\xcb\x88\x32\x58\x58\x2d\xea\xee\xdc\xcf\xdc\x71\xfc\x9b\x51\x6a\x8d\x7c\x06\x74\x53\x3b\x2f\x9f\x66\x34\xb1\xba\x55\xd6\x90\xa8\x3a\x42\xb9\x12\x8d\xde\x41\x53\x84\x2d\x3d\xa3\x32\x42\xc2\xbe\x83\xa5\xfa\xa2\xfb\xfb\xca\xed\x27\x00\x88\x8f\xfe\xeb\xbe\xa2\x7f\xa7\x7c\x9e\x55\x5f\xf5\x4e\x62\x19\xe3\x16\xb3\x1a\xa8\x34\xe1\x0d\xce\x78\x14\x19\x47\x21\x58\xf7\x7f\xff\x22\x4e\xc3\xe5\x73\x12\x7b\xd2\x24\x8a\x94\x1e\xb1\xf8\xf8\xdb\x68\x45\xcf\xb8\x90\x48\x4d\x0b\x16\x6f\xef\x9f\x09\x87\x5c\x3a\xbf\x20\xa8\xba\xe2\x47\xd1\x62\xce\xd8\x4f\xda\x29\xee\x31\x8b\x23\x89\x6d\x5e\xbc\xa5\x87\x06\x23\xc5\x83\x18\x47\xb9\x59\x0c\x29\xce\xea\x33\xce\xb5\xc7\xa6\xf8\x2f\x7c\x00\xed\xcc\x52\xd0\x89\x0e\xfb\xef\x19\x3a\x64\x62\x58\x0c\xfd\xd6\x7c\xad\xcf\x60\x2e\x65\xf8\xee\x14\x0c\xb6\x0f\x1d\xe4\x6a\x64\x8f\xca\xb2\x2c\xe6\x58\xd2\xad\x7f\x56\x83\xe8\x03\xcb\x72\x9a\x61\x4f\xe5\x5b\x51\xc1\x9b\x68\x66\x28\xa4\x4c\x52\x9a\x38\xd2\x89\x53\xa7\x1b\x95\x0a\xfc\x18\x93\xf9\x66\x85\xab\x25\xb6\x3b\x74\xe0\xbf\x52\x52\xc8\x14\x89\x51\x0a\x6f\xbf\xdd\x2f\xee\x0e\x77\x4b\x5b\x38\xd9\x3d\x3f\x3e\xde\xfd\xe9\xaf\x49\xa5\x36\xd9\x40\x24\x6f\x53\x87\xf2\x48\xa6\x80\x81\xcd\xc6\x40\x6f\x66\x2c\x7a\x96\x69\x26\xf0\x19\x89\xae\x13\xea\x15\x00\x6f\xec\xd2\xb9\xce\x7f\xd0\x00\xf2\x1f\x85\x0c\xd1\xa2\x37\x50\x7e\xa9\x6b\xdd\x4e\x3a\x9d\x99\xc9\x53\x04\x1d\xc9\xcb\xdb\x6d\x5d\xeb\xd9\x41\x99\xa1\xac\x48\x68\x08\x6f\x86\x12\x69\x66\x14\xa0\x20\xac\xf0\x10\xa5\xfd\x0b\x9c\x40\xef\xce\x63\x56\x31\xcb\xa3\x4c\x23\xb5\x67\xf3\xf8\xc7\xf8\x15\xce\x23\x15\x21\x03\x53\x5e\x9a\x77\xec\x1b\x37\x84\xe4\x19\x53\x23\xed\xb6\x45\xa5\xaf\x14\xce\x72\x4a\x15\x5a\xd9\xd8\xdb\xbd\x79\xe8\xb7\xaf\xa1\xaa\x90\x53\x2e\xb0\x64\x84\x04\x94\xfb\x62\x54\x92\xca\x69\x6a\xe9\x24\xeb\x5f\x67\x18\xbd\x74\x39\x8b\x95\x10\x96\xfe\xf5\x03\x2a\xf8\xd9\xce\x3c\xe0\x58\xce\x12\x83\x18\x6a\x29\xda\xe2\x83\xd5\x3a\x67\x19\xe8\x41\x73\x78\xbd\xff\xfa\xbc\xbb\x99\x5d\x3a\x13\xb1\x74\xfb\x73\x9f\xf2\xe9\xfa\xf4\xff\x29\x7b\xb7\xee\x46\x71\x74\x7f\xf8\xbb\xec\xab\xbe\x98\x0b\x04\x92\x80\xf7\xce\x71\x9c\x54\xba\x73\x1a\xdb\xa9\x9a\x9e\xff\xda\xcb\x4b\x87\x47\x0e\x1d\x0c\x1e\xc0\x49\x79\x3e\xfd\xbb\x78\x24\x71\x32\x49\xf5\xbe\x99\xea\x09\x32\xc6\x20\xa4\xe7\xf0\x3b\xe0\x76\xdf\xbe\x7d\xe8\x66\xbb\x7e\xbe\xf8\x40\x8c\x40\x93\xec\x68\xea\xcd\x98\x0c\x10\xa5\x91\x11\x98\xed\x1b\x9b\x97\x8e\xa1\xb5\x29\x0d\x2d\x96\x77\xe0\x54\xe2\xcd\x17\xfa\x39\x9c\xd2\x58\x11\x67\x40\xa8\xb3\xf7\xaf\xcb\xbd\x29\x53\x32\xf2\x16\xd1\xbf\x42\x8a\x4c\x3f\x6a\x42\x84\xb4\xbf\x67\xf0\x81\x82\xe0\x68\xf3\xef\xe9\x03\x6e\x10\x67\x8e\x42\x5b\x3a\x65\xdf\xaf\x0a\xf9\x29\x67\x56\xe7\xcc\x2e\xa1\x36\xac\xc0\xee\x78\x7f\x0f\x38\xd7\x2a\x9d\xca\x9d\x7c\x76\xc1\x5f\x02\x33\x53\xae\x2d\x86\x71\x24\x58\x3a\xd8\x7f\xd2\x38\x30\x61\xdc\xf5\x51\xbe\x1d\xe5\x63\xa9\xe1\x0a\x63\xd5\x01\x9e\xca\x7b\x33\x4f\x5c\x9a\xa3\x34\xe6\xcc\xba\x34\x17\xba\x7d\xeb\x32\x91\x67\xff\x1d\x28\xc3\x47\x69\x6c\xac\xb7\xec\x61\x67\x5c\x21\xc2\x91\x4a\x87\x04\x81\x28\x4d\x58\x88\x50\x05\x67\x84\x3c\x54\x2f\xff\x3b\xff\x26\xfe\x34\x69\x88\x58\xb3\x75\x3b\x97\xdb\xb3\x3c\x5b\xb9\xc8\xf9\xb5\x3d\x4d\x20\x48\x93\xae\x3a\xb7\xda\x7e\x5b\x9c\x9a\x72\x68\xa7\x31\x59\xe0\xd2\x34\x8e\x03\x8b\x1e\xed\x85\x9d\xc6\x8f\x37\x15\xa9\x71\xa7\xbc\x39\x15\xfb\xcc\x17\x06\xbf\x62\x49\x45\x69\x2a\x03\xa9\x86\xfe\x0a\xe3\x4d\x20\x15\x9c\x2a\xdd\x41\x4a\x96\x6d\xb6\xd9\xcd\x16\xc1\x53\x6c\x6d\xfa\xa2\xc7\xf3\xfa\xe9\xfb\xe4\xb2\x45\x6c\x7c\x33\xd1\xda\xb2\x5c\x83\xca\x34\x54\xb3\x01\x76\x2a\x34\x47\xb6\x2a\xe2\x52\x4a\x2b\xd8\xde\xc6\x1b\xa3\xdf\xa9\xc2\x14\x0b\xc4\x95\x8b\xe5\x17\xa7\xe6\xb5\xac\xb2\xa6\x0f\x5b\x52\x95\xc4\x48\xef\xda\x34\x55\xf6\x36\xf8\xb3\x08\x59\x32\xd0\x4d\xd7\xc3\xba\xfe\x84\x0e\xf0\xb7\x70\x5d\xa9\xa6\xa9\x53\x49\xcd\xf3\x47\x71\x7c\xcb\x2e\x9e\x9b\xe6\x1c\xdd\x1d\xee\xb3\xec\x38\x28\xbf\xa5\x9a\xcb\xd8\x9a\xbb\xbf\x89\xf1\xd2\xa9\x95\xc4\xee\x52\x1b\x91\xba\x26\xe8\xb0\xfb\x97\x02\x09\xb1\xa5\xad\x3a\x35\xc9\x61\x0d\x21\x05\xa2\xb8\x1a\x3c\x94\xeb\xac\x02\xd5\x5c\x83\xcc\x26\x95\x94\x14\x62\x89\x3b\xcf\x1a\x44\xbe\xaa\x9b\x0b\x88\x4c\x6a\x28\x89\x49\x27\x02\xf3\xd4\x5c\x20\xab\x53\x43\x69\xe2\x4a\xbb\x23\xd6\xd9\xf0\x81\x89\x80\x43\xec\x74\xbb\x75\x55\x1e\x37\x59\xb1\x9f\x8a\xba\x8c\x6f\xab\x08\x24\xc1\xa0\xac\xdd\x3d\xd4\x5d\x61\xca\x5b\x68\xfa\x3a\x9a\x08\x80\x20\xed\x10\x85\x6c\xd6\x56\xf7\xd6\xa7\xe2\x7e\x0c\x89\x2c\xe2\xae\x0f\x4c\x7e\x1b\x2d\x8d\x7e\x18\x4b\xa8\x8d\xd8\x50\xf1\x79\x10\x19\x0a\x92\x70\xa4\xc8\x23\x98\x67\xf1\xe4\x59\x02\x17\x2d\x45\x2b\x25\x36\xdf\x0f\xf9\xb5\xcc\x43\x24\x88\xf3\x77\x75\xc0\xd8\x51\xe9\x4c\x10\x25\xb0\xea\xe6\x4b\xaa\xa7\x42\x5f\x67\xfb\xac\x11\x8e\xbc\xe5\xc7\x85\x3c\xc0\x47\x75\x9f\xfd\xe7\x04\x9d\xdd\xaa\x3f\x18\x27\x34\xf4\x31\x72\xe3\xc1\x5c\xfd\x15\x84\xc2\xb2\xed\x6a\xec\x10\x64\x2a\x13\xf9\x0f\x90\x75\xd6\x8c\xcb\xed\x22\x14\x29\xa2\x2f\x0b\xf8\xd9\xe1\x12\x44\x3e\x72\x8f\x8c\x44\xa4\x28\xc2\x46\x32\xdd\x06\xcb\x26\x6b\x33\x93\x35\x74\x69\xec\xf8\x9b\x23\xcd\x63\x17\x62\x76\x14\xa1\x76\xb8\xca\xe0\x7d\x9c\xd3\xfb\x75\x5f\x50\xa2\x30\x43\xc2\xa4\xe7\x6f\x2d\xd5\x6e\x89\x16\x8c\x07\xa8\x9c\x39\xd2\x3c\x18\x21\xb8\x04\x27\xb6\x6e\xd2\x54\xe7\x47\xf8\x89\x1d\x07\x5c\xd0\xbb\xe3\x3a\xc0\xbe\x6b\xb3\xaf\x36\xd0\xb4\x67\xa9\x9f\x45\xd5\x74\x0b\x77\xd9\xcd\xd1\x58\x49\xbc\x0d\xff\x5a\xaf\x7b\x9e\x65\x24\x12\x12\x20\x37\xa8\x29\x4f\x55\x21\xbc\xf9\x68\x55\x2f\x4f\xdd\xa3\x4c\x28\x15\xe0\x71\xc3\xcb\xbc\xec\xca\x92\x22\x15\xc6\x2b\xae\xfc\xf3\x94\xa9\xb7\xab\xd3\x19\x57\x86\xe1\xf2\x21\x52\xc9\xac\x84\x85\xcd\xb6\xcf\x5f\x87\x28\x42\x88\xd0\xde\x14\xcf\x67\xf6\xf7\x9b\xfe\xef\x74\x0d\xfc\x7f\x84\xfc\xef\xa4\xda\x36\x39\x17\x58\x18\xa8\x86\x63\x5e\x9e\x9f\xab\xf2\x2f\x18\x24\x8b\xa3\xa9\x24\x09\x33\xae\xdf\x3b\xab\x19\x12\x09\x19\x13\xe6\xfd\x48\xb2\x1c\xee\xae\xe5\xf9\xb9\x5d\x0b\x3b\xf4\xe9\xf8\xe1\x2a\x42\xbd\xe0\xe2\xf2\x54\x55\xe3\x6a\x85\x50\xb1\x35\xe4\x42\x18\xd7\x66\x00\x13\x59\xf8\x42\x7e\x9b\x50\x9d\xea\xa1\x65\x43\x24\x34\xe5\x01\x9a\x1c\x83\x5e\x8a\xea\x38\x66\xda\x08\xad\x62\xec\xe5\x65\xf5\x4e\x8a\xa2\x98\x92\x38\x84\x86\x38\xb6\x5d\xe0\xec\xf8\x5c\x95\xfa\xa4\x9a\x7a\x6e\xe3\x16\xda\x08\x6b\x4f\x74\x3a\x1c\xee\xa1\x7e\xcb\x3c\xd8\x47\x00\xd1\x0e\x99\x6a\x89\x90\x43\xee\xaa\x1f\xc2\x19\x62\x52\x33\x1b\x03\x5d\xf5\x51\x62\x37\xc2\x48\x6f\x5e\xbf\x14\xc7\xc9\x45\x1a\x4a\x11\x76\xf1\x97\x50\x6f\x47\xd7\x44\x6b\x43\x0c\xdb\xe5\xe8\xa9\xe5\x91\x30\x49\x62\x82\x4e\x94\x4d\xe4\xcf\x15\xd4\x13\xf9\xe2\x48\x18\xa0\xd8\x32\xdb\x3c\xaf\x96\x77\x8b\xfb\xbb\xcd\x76\xb7\xfd\xe1\xd1\xb1\x32\x50\x09\x76\xdf\xfd\xd6\xb4\x2a\x06\x84\xd1\xf6\xb0\x49\x38\x32\x83\xab\x81\xf9\xe7\x8c\x7f\x6b\x24\x03\x10\xc0\xbc\x55\x6a\xa6\xdd\x66\x32\xbc\x14\x49\x78\xa4\xbc\xae\x1a\x4a\x53\x7e\x77\x50\xdc\xe9\x8e\x3f\xf9\xff\xee\xe3\x61\x4a\xd1\x73\x04\xfd\xbc\x9f\xfc\xed\x46\x18\x6d\x60\xa1\xd1\x1b\x10\x93\x3a\x45\x1b\xd7\x21\x32\xf5\x26\xcb\x33\xd1\xc0\xce\xeb\x5c\x8d\x2f\x9e\xca\x10\x79\x96\xff\xfe\xf7\xbf\xdb\x88\xe0\xda\xb3\x67\xfa\xa7\x2a\x29\x28\x8b\x41\x40\x75\xb3\x65\x99\x9f\x50\xfc\xcf\x49\xbf\x4f\x3c\xdf\x22\x49\x8d\x46\xbc\xb7\x30\xc6\x7e\xf3\x98\xa4\x21\x19\x11\xc2\x0a\x6a\xa8\xb3\xca\x61\xf3\xd6\x03\x06\xff\x1f\x9b\xa0\x9c\x25\xa3\x09\x26\x7d\xf5\x49\x1e\xb2\x66\x94\x50\x4e\x47\x32\x85\x5f\xbb\xba\xdf\xa2\x17\x94\xf5\x67\x99\xfc\x5a\xa6\x2c\x28\xd6\x64\x79\xde\x35\x8e\xbe\x5e\x94\x24\x03\x7b\xbd\x3a\x7b\x87\x70\x7a\x3e\x50\x48\x70\x2b\x8b\xe7\x32\xcf\x1d\x64\xb6\x4f\xd0\x24\x33\x0a\x7b\x28\x7b\x68\xee\x0e\x62\x0f\xed\xfa\x5c\x5f\xaa\x7c\x47\x32\x26\x01\xda\xbd\x5c\x65\xcd\x33\xd4\xbe\x95\x21\xe3\x58\x30\xe2\x2c\x96\xe6\xcb\x7a\x32\x4e\x52\x5c\xbc\x6e\xdb\x9d\x76\xef\xc2\x8b\x41\x3b\x44\xc6\x89\x52\xa1\xaf\x0b\x6c\x44\x0e\xff\xfe\xa9\x46\xfb\xba\x4c\x88\xa5\xad\x75\x02\x04\x23\x2b\xbd\xf1\xd7\x25\x0c\x62\x63\x4b\x10\x8b\x66\xb0\x02\xc9\x24\xb5\x60\x0f\x27\xfd\x6f\x29\x30\xc3\x37\x2a\x51\x1c\x9d\x94\x33\x55\xae\x7b\xa9\xaf\x48\x4a\x96\x22\x35\xdb\xa9\x3c\xcc\x2b\xca\x46\x52\x26\x0a\xcb\x6e\x03\x54\xa8\x94\x89\xd5\x39\xc5\x39\x78\x0d\x26\xeb\x89\xaf\x52\xa6\x12\xaf\xa7\x0d\x42\x32\x7d\x0d\x87\x52\x55\x42\x9d\xa7\xa2\x57\xe3\x2f\x51\xcc\x36\x65\xdb\xd0\xd1\x9d\x6f\x94\x84\xcd\xc7\x4e\x9f\xb4\x2d\xdc\x39\x75\x12\x23\x0f\x6a\xa0\x33\x3a\x7d\x09\x4d\x10\xa3\x9f\x9d\xb3\xb6\x28\xcd\x66\xbb\xbc\x9e\x70\xb0\x55\xc0\x0d\x0b\x06\x3d\xa7\xa1\xff\xd4\xfc\xba\xa1\x02\x19\x63\xc2\xe3\x73\x0c\xec\xba\xce\xb6\xaa\xba\x8f\x90\x80\x22\xbc\xed\x35\x6b\x57\xe1\x65\x5e\x16\x5d\xca\xa2\x48\xc2\x84\x83\x3d\x3e\x7e\xdf\x36\xe5\x5c\x7e\xea\x87\xa6\x56\x53\x50\x3b\x11\xdd\x9b\x72\x24\xb3\x14\x29\x22\x18\x86\xcd\x47\x51\xd5\xf0\x50\xef\xad\x74\x5d\x1f\xf1\x2a\x02\x90\xf4\x5c\xca\x6b\xa8\x55\x95\x1d\x87\x26\xda\x93\xeb\x36\x80\x70\x32\xed\x58\x04\x17\xf5\x7d\x15\x06\x89\x93\xed\xc8\x73\x2b\x7d\x5c\xb7\x61\xd5\x7c\x2a\xaa\x42\x66\xd5\xce\x85\xd6\x23\xa2\xdd\x6c\x10\xed\x3f\x93\x26\xc8\xc3\x47\x79\xce\x89\xcc\x40\xa4\x42\x48\xb0\xf5\x07\xcd\xeb\xc0\x21\xb5\xfd\xbb\x50\xa4\xa3\x5a\x5c\x7a\x7b\x45\x2a\xe2\x29\x42\x7a\xed\x63\xb4\x3d\xbe\x81\xad\x64\xa4\x22\x29\xb1\x5a\x24\x31\x33\xe9\xbe\x91\x8a\xc8\x73\x0f\x4e\xc7\x51\x00\xeb\x07\x48\x86\x09\x47\x77\x8f\xc7\x94\xaa\x89\x18\x62\xa4\x28\x00\xd6\x9b\x4e\x35\x54\x08\xdf\x59\x22\x29\x66\x35\x2f\x88\x3a\xb9\x3b\xd4\x24\xa8\xcc\x7e\x5d\x9a\x51\xec\xa2\x58\x18\xe0\xcf\xcb\xb3\x43\xd6\x0c\xab\x26\x8a\xa5\x29\xaa\xa6\x94\x17\x04\x5c\x37\x80\x47\x1c\xf5\x20\x9f\xb7\x9b\xeb\xbf\x89\x22\x54\x9c\x26\xb1\xf4\x8e\xb4\x5f\x6d\x29\x2a\xa6\x96\x14\xbf\x7d\xda\xdc\x67\x4d\x93\xc3\xb7\x52\x0f\x24\x51\xfd\x55\xc6\x9c\x24\x2e\x38\x44\x6d\xb3\x5e\x2c\xe0\xf3\x9b\x11\xeb\x20\xb5\xdd\x39\xb8\x86\x89\x3f\x6d\xa4\xd2\x34\xf1\x75\xe7\x67\x51\xcd\xdb\x9f\x46\x4a\x04\x31\xd6\x74\xd1\x15\x03\x0d\x9b\x47\x5b\x44\xe2\x87\x49\xc1\x84\x37\x48\x30\x50\x55\x22\x9f\x2d\x78\x28\x99\x58\x19\xac\x36\xa3\x7a\x29\x34\x54\xba\xdc\x3b\xb2\xb4\x1f\x21\x92\x28\xea\xcc\x1c\xc4\x8e\x78\x9e\x80\x52\x84\x23\x48\x5e\x66\xfa\xae\x50\xd5\xb0\x87\xa8\x54\xc4\x30\x58\x6b\x50\x3a\x4b\xf9\x3f\xeb\x94\x21\x28\x29\x2b\xd4\x5a\x14\xfa\xb1\xec\x43\x64\xa5\x85\xc4\x36\xad\x39\x15\x6d\xb2\x3f\x68\x1f\x28\x10\x21\xce\xc1\x8e\x15\xac\x40\xa4\xd0\x03\xa0\xd6\x42\x5f\xaa\xd1\x7d\xfd\x30\x8c\x51\x88\xae\x53\x7e\xdb\x83\xab\xed\xd2\xbf\x45\x9a\xd0\xd8\x87\xac\x7d\x59\xc1\xfb\x60\x44\x9a\xb0\x14\x45\x6e\x37\x20\x2a\xf5\xfa\x70\xbe\xc9\x72\xa8\x47\xd1\x9f\x26\x31\x57\xe9\xb4\x30\x11\x45\x93\x41\x29\xc3\xb9\x6e\xf2\x53\x3d\xd6\xdf\x8f\x34\x91\x49\xe0\xc0\x0f\x78\x2f\x96\x9d\x2d\x43\x7b\x4c\x7b\x8d\x5a\x55\x56\xfa\x06\xe0\xd9\x9a\xc4\x4c\xce\x11\x4a\x4a\xf1\x1c\x95\x70\x52\x38\x93\xe7\xaf\x23\x0a\xd8\xcd\xf5\xd9\xf4\x35\xbc\x8f\x7c\x30\xfd\xb0\x14\x78\xe4\x88\xac\x18\xdc\x61\x04\x3e\x6e\xc5\xe8\x48\x5b\x6d\xe7\x46\xbc\xc1\xa6\x10\xc7\xfa\xb5\xf4\xf3\x41\x53\x08\x11\xec\x65\xcd\xeb\x84\x7a\x83\x0a\xc5\xae\xbb\xc3\x91\x41\xac\x90\x78\x83\xef\x50\xe8\xb2\xb2\xf6\x1b\xdd\x7e\xd5\x2d\x8c\x9a\x02\x45\xb2\xc8\xf3\xcb\x7a\xe1\x3f\xce\x43\xcb\x6a\x3b\x88\x46\xbd\x5e\x77\x0d\x6f\xcd\x81\x10\xc7\xbb\x7f\x03\x3d\xea\x63\xeb\x38\x8a\x69\x84\xf1\xf5\x4f\xb2\x69\x44\x45\xbb\x03\x9c\xb8\x5d\xea\xfc\x35\xf5\x5f\xc7\x42\x71\x31\xd8\x9d\xb1\x49\x56\xd8\xe6\x1c\xe6\xc5\xdd\x03\x4b\x02\x86\x9d\x34\x93\x15\xda\xd1\xd5\xc6\xf7\x2e\xa1\x02\x11\x97\x96\xab\xe6\xb2\xb5\xc9\x43\x48\x09\x50\xeb\x80\xbb\xbc\x7b\x58\xdc\xdf\x2c\x96\xdb\xa7\xb5\xff\x06\x41\x25\x46\xfe\x87\xac\x68\x56\x05\x54\xfb\xf3\xa2\xe9\xe2\xb9\x59\x70\xc2\x68\x85\xd4\x82\x03\x3a\xea\x2d\xf2\xfc\x74\x10\xdd\x59\x05\xc7\xea\xcf\xf2\xfe\xee\xe6\x66\xa2\x9e\xda\x1e\xb5\xba\x1b\x76\x2b\xb1\x9b\x9f\xcf\x7b\xc7\x97\x2e\x14\xc3\x08\xd2\x12\x2a\x5f\x8e\xaa\x3c\x64\xc5\xde\xfa\xe0\x8f\x47\x4a\x4a\x82\x0b\x02\x41\x1b\x52\xd6\x8d\x38\xf8\x7c\x43\x4b\x1a\x22\xdc\xc7\x51\x55\x6f\xca\x5f\xa8\x34\x68\x15\x00\x62\x1a\xfc\xa3\xda\x94\xb9\x46\x91\xbc\xf9\xc8\x53\x2b\xc5\x30\x07\x69\x6f\x27\xca\x6f\x77\xa8\x9f\x19\x78\x4a\xff\x31\x1d\x46\x88\x07\xbd\xda\x2e\x77\x9b\x97\xbb\xcd\x66\xb5\xdb\xde\xad\xd6\xbb\xd0\x5f\xb8\x66\x12\x51\x96\x3f\xc4\x3b\xd4\x57\x56\x05\x77\xb8\x31\x6a\x08\x48\xaa\x26\x36\xb0\xb3\x2b\x98\x06\xa6\x94\x83\xa3\x63\x9d\x68\x40\xf0\xd6\xc0\x2d\x1c\x6a\x82\xef\xd3\xa0\x2d\xb1\xf5\x6a\xb1\x1c\x7f\x2b\x44\x98\xf9\xaa\x32\xcf\x7d\xc9\xa4\x83\xd1\x0c\x77\x16\x6d\xc2\x18\x4d\x6c\x10\x14\xe1\x60\x13\xe8\xb6\xee\x8f\x33\x89\xc0\xd7\xf2\x67\x0e\xe7\x61\xb2\xa0\x4d\x12\x47\xd6\xb0\xdc\x34\x2c\x98\x5c\x98\x51\x1a\xb9\xe3\x9f\x67\x21\x40\x12\x40\x89\x15\xd3\x66\x5c\x18\x86\xfa\x03\x86\x85\xae\x06\xfc\x62\xc9\x79\x5e\xa2\xf6\x12\x33\x0f\x21\xe3\x18\xfe\x88\x03\x14\x7a\xd0\xeb\xbf\xf4\x3f\xc4\xb1\x1e\xca\x9d\x0b\x59\x56\x38\xc9\x1f\xa0\xda\xf7\x01\xf5\x28\x19\x70\x1f\x8b\x22\x81\xa6\xc2\x0e\xf8\x38\xb8\x3b\x10\x71\xee\x55\x6d\xef\x45\xdd\x3c\xb4\xfb\x46\x53\x16\xdd\x4f\x69\x37\x4e\xea\xe2\xd5\x6d\x79\x95\x0b\xf5\xe6\xca\xac\xb3\x73\x00\x22\x9d\x58\xf0\x74\x23\xaa\xe6\xa9\xfa\xd6\xce\x6a\x9f\xf2\xf5\x21\xa5\xfd\x9f\xcb\xb5\x14\x58\xa4\xf1\x05\x3e\x88\x9f\x4e\xa2\x62\x78\xff\x87\x45\x7f\x60\x8c\x78\x48\xe3\xd3\x11\x8a\xab\xac\x37\xcb\x1b\xdd\x33\x1e\x13\x44\x47\xde\x97\x7b\x6c\x6f\x7e\x61\xf9\x1b\x01\x57\x56\x51\xfe\xe9\xf7\xd1\x74\x84\x58\x59\xb2\x54\x1b\x36\x57\xe5\xa1\xfc\x06\xf9\x71\xe0\x04\xd2\x8f\x92\xba\x8f\xc1\xe6\xe3\x57\x48\xa2\x18\x41\x04\x7f\x38\x0d\xd9\xf1\xd1\x34\x31\x08\x52\x7d\xcf\xe0\x03\xaf\x57\xc8\x1c\x7c\x18\xef\xdd\x40\x9e\xcb\xb2\x7b\x82\x69\x2a\xad\xfb\xd1\xb9\x6e\xe0\x80\x1f\x59\xd8\xb6\xc2\xa5\xf4\x88\xff\x88\xb6\xe5\x35\x79\xaa\xb3\x02\xea\x1a\x1b\x81\x8d\xc8\xc7\x25\x42\x10\x51\x1a\x52\xec\xa5\x66\x45\x93\x43\x6d\xa1\xe0\x93\x20\x66\x26\xc4\x9d\xfc\x5e\xc1\x18\x86\xdc\xbf\x97\xe7\x41\xbb\x07\x04\xeb\x04\x34\xee\x2c\x59\xd6\x32\x18\x06\xad\xce\xc9\x79\x84\x88\x47\xb4\xa6\xe5\xb7\x5b\xfb\xbe\x6c\x4b\x3b\x33\xc6\xcf\x52\x40\x8a\x50\xa3\x1f\xa2\x7e\xcd\x8a\x7d\x53\x16\x2b\xc7\xb8\xf4\x97\x20\x23\x91\xb8\xc2\x08\x56\x95\xf5\x72\x96\x1b\x0c\x52\x45\xa8\x96\xfc\x01\xd9\x5a\x64\x28\x4a\xdf\xeb\x26\x41\x1b\x34\xb5\x0f\xe0\x65\x73\xfd\x30\x9a\x34\x3a\x0c\x10\x51\x6b\xb2\x9f\xa0\x57\x3f\x8f\x5b\xa8\x9b\x39\x60\x32\x68\x20\x98\x14\x0a\xad\xb7\x25\xe2\x34\x86\x0f\x18\x28\xe3\xb4\xa3\x65\x6d\x9a\x2c\xcf\x47\xb1\x88\x1f\xc6\xa2\xc0\x5a\xaa\x21\xc2\xba\xf6\xa6\xc0\xf3\xef\x29\xc4\x21\x4d\x7a\x47\xb4\x51\x5a\x0c\x00\xd6\xff\x3d\x53\xa5\x55\xcc\xf0\x8d\xe2\x87\xac\xe8\x5b\xe3\x60\x82\x80\x5a\xc7\x3e\x55\x6a\xd0\x6b\x2f\x79\xd9\x1d\x8f\x63\x2a\xbb\x46\xe9\x93\x71\x44\x57\x5b\x3e\x9c\xb5\x4c\x8c\x4c\x10\x70\x5c\xaa\x0c\xc0\x1a\x14\xa0\xe2\xa6\x3f\xc4\x24\x66\x2b\x66\x2c\xce\x17\x99\x20\x09\x10\x18\x20\xcb\xf2\x6d\x29\x8a\x77\x51\xf7\x89\xfe\x78\x0e\x19\xc2\x2c\x3d\x7b\x59\x95\xc7\x71\x25\xc2\x0f\x68\xdf\x74\x67\x7d\x5f\xec\x9f\xba\x85\xd0\x10\x15\xf8\xf0\x19\x2d\x2d\xaa\x09\xc5\xd1\x0f\x33\x11\x91\x8e\xfe\xb1\x06\x75\xaa\xda\x17\x62\x54\xc0\x30\x61\xa8\x3c\xbf\xe4\xfe\x65\xf9\xc7\xd4\xdb\x62\x7c\x3d\xa1\xb2\x17\xdc\x59\xd4\x3f\x19\x27\x4e\xb1\x47\xe7\x81\xee\xa4\x60\x5d\xf2\xa0\xd0\xde\x7d\x70\x50\xf6\x32\xa1\x11\xd8\xa7\xb2\x18\x2b\xcb\x3f\x70\xb8\xdf\x3e\xd3\x35\x11\xe7\x89\xeb\x18\x1c\xdb\x59\x38\xc2\x69\x99\x48\x48\xa6\x3a\xc5\x92\x61\x83\x67\x7c\xc9\x91\x56\xc6\x22\xae\xad\x2b\xdf\xe6\x24\x75\xf6\x5e\xcf\xc1\xd8\x4c\xbb\x3c\xe3\x4e\xf9\x91\x35\xea\x75\x14\x0f\x9b\x08\xec\xf6\xbc\x41\x5b\xb7\x76\xfb\xbc\x01\xf8\x85\x2e\x9b\xa1\x0e\xbe\xea\xc4\x7a\x8b\xf3\xaa\x79\xbd\xb0\xf9\x8a\x0c\x0b\x82\xb0\xdb\xba\x5f\x6d\x7d\x6d\xc2\x2b\x6e\xf7\x70\x44\x0c\x6a\x78\x3f\x41\xfe\x0e\xdb\x52\x8b\x7a\x71\x3c\x76\x0f\x92\xc5\xb2\x6f\x4b\xdd\x15\x2a\x3f\xe9\x69\x51\xcd\xb0\x84\xe2\x86\x62\x5b\xfd\xf1\x60\x79\x30\x4c\x48\x9c\xb6\x45\x9b\x73\xfe\xf4\x7f\xe5\x29\xc1\x42\xa9\x33\x9c\x72\xbe\x43\xcb\xb2\x6e\x4e\x87\xe9\xaf\x48\x28\x41\x78\xf0\xc1\xda\x91\x7a\x91\x80\x11\x4d\xc4\x24\x9c\x39\xed\x3d\xf9\x37\x1c\x60\x23\x93\x48\x40\x52\x7c\xb3\x07\xdf\xd0\xb3\x8f\x6e\xe9\x42\x31\x37\x2e\x8d\xb8\x71\x2d\xd4\xed\xf9\x08\x8f\xbe\x0c\xd7\xbd\x0a\x69\x62\x8d\x6d\x3a\x1c\x61\xe2\x0f\x48\x0e\x64\x04\x30\x9d\x03\x97\x1a\x11\x52\xf0\xea\xef\x58\xc7\xdd\x68\x9f\xb6\x1b\x21\x08\x6a\x8e\x23\x04\x68\x2e\x8f\x34\x42\x5b\xb2\x97\xee\x6c\x08\xbe\xca\x36\x8c\x0c\xac\x31\xfe\xe3\xf6\xfb\x4b\x5f\xc3\xb9\x44\x72\x7e\xf6\x2f\x06\x34\x73\xdb\x9f\x91\x84\x7a\x3c\x78\x3b\xcb\x86\xa2\xf3\x91\x91\xcc\x56\x28\x77\x58\x07\xaa\xf4\xdd\xa7\x3c\x7c\xf7\x01\x15\x58\x35\xf4\x5a\x18\xdb\xdc\xff\x64\x58\x44\x2d\x30\xd7\x8a\x89\x6f\x44\xf1\xd0\x8b\x87\x4d\xb9\x88\xe3\xeb\x55\x32\x41\x09\xd9\x36\x21\xd9\x0d\xf7\x33\xa3\x55\x6a\x2d\xec\xb2\x7d\x21\xf2\x6d\x25\x34\xdc\xcd\xe8\x04\x1a\xd0\x02\x39\xeb\x8b\xcd\x66\xb5\xdd\x3d\x2c\x1e\x17\xb7\xab\xf5\xee\xc7\xe2\xfe\x7e\xe5\x69\x7f\xa6\x5d\xe8\x51\xb8\xe5\x76\xd9\xfd\x89\x10\x12\x76\x12\x6f\xa3\xa4\xff\xf2\x76\x0f\xf7\x67\x63\xc2\x38\xd6\x9d\x42\x64\xbf\x9e\x99\x44\x62\x57\xe2\xea\xe9\xf1\x65\xb3\x63\xbb\xeb\xc5\x9f\x0e\xe3\x47\x83\x20\xb2\x26\x43\x76\x35\xbb\xa9\xca\x03\x3a\xa5\xd8\x57\xe4\x61\xd2\x15\xa4\x41\x10\x2b\x0c\x01\xe0\xd0\x46\xdb\x85\x3a\xdf\xe4\x62\xdf\x9d\x4b\x13\xcb\x94\x80\xe6\xa9\x18\x10\x47\x12\x77\x9c\x84\x56\xe0\x4d\x42\xdd\x58\x8d\x24\x7f\x80\x05\x18\x5d\xdb\x2c\xd4\xba\xfb\xe1\x8a\x7c\x75\xde\x4c\x65\xaa\x69\x40\x8c\x30\xc4\x93\x1d\x7f\x58\x1a\x4f\xed\x4f\x15\x86\x29\x16\xe6\x5d\xc2\xd4\x2e\x95\x77\xc5\x65\x58\x44\x83\x90\x5a\x69\x06\x04\x28\xba\x1c\xf2\xb1\xf4\x42\xbd\x23\xf1\x7e\xff\x09\x66\x1d\x60\xe6\x9b\xd8\xc3\x47\x41\x83\x90\x83\xc6\x0c\x25\x07\x51\x2d\x4e\x13\x08\x3d\x0d\xc2\x34\xb6\x5e\x5f\x4e\xce\xec\x0b\x78\x1e\x0d\xa2\x38\x46\x82\xcb\x12\xed\xcf\x5e\x8a\x0c\xb5\x83\x9a\xf3\xf6\x94\xf5\xdb\x16\x0d\xa2\x04\xbc\x31\xf3\x77\x8f\xba\xec\x37\x37\xb7\xaf\x5e\xee\x1c\xfe\xd3\x2a\x4c\x83\x39\x6a\x14\x0b\xfc\x17\x50\x08\x30\xfa\x5f\x3e\x3d\x3c\xdc\x6d\x36\x77\x4f\x8f\xbb\xe7\xd5\x7a\xb9\xf2\x2c\x56\x1a\x30\x12\x61\x6c\x82\xdf\xbd\x6a\x94\xfc\x65\x09\x98\x06\x4c\x31\x9c\x35\x1f\x56\x59\xc1\x9f\x8a\x13\x86\x82\xb4\xb5\x97\xac\xab\x07\xd1\x26\x0d\x78\x12\xe3\x94\x69\x77\x2a\x47\xf5\x72\x91\xce\x60\xc2\x71\x65\x10\xed\xe5\xed\x23\x50\x0f\xab\x8d\x1f\xf5\x64\x32\x70\xed\xd3\x6c\x94\x19\xbc\x29\xab\xe7\x2a\x43\xe8\xd8\x7f\x41\x47\x97\x9a\x85\xb3\x64\x98\x0b\x74\xc9\xac\x82\x2c\x0d\xe2\x28\xf0\x3c\xe3\x76\xe9\xba\xcf\xea\xe6\x1e\xe6\x55\xb1\x68\x10\x6b\x82\x82\x3b\x5e\xb1\x30\x76\xf3\x6e\xb0\x22\xd1\x20\x11\x0a\x1f\x0c\xbe\xf8\x4b\x51\xe8\xb3\x97\x04\xa2\x41\x9a\x1a\xdc\xf7\xfe\x73\x82\xea\x8c\x7d\xcf\x19\xfe\x12\x0d\xda\x5c\x88\x59\x59\x80\xeb\xf2\x84\xb9\x96\x86\x9f\xbf\x30\x30\xa6\x81\x60\x1c\xa1\x9a\x32\x1b\xfa\xa0\xd2\x40\xa4\x51\x40\x07\x97\x7d\x0d\xed\x06\xa7\xbf\x48\x3a\x69\x20\xc3\x08\x65\x9d\x10\xc6\x94\xfd\x17\xfa\x2c\x89\x06\xd2\x68\x8c\x67\x16\x39\xfc\x6c\xf3\x87\xe1\x31\x9d\x68\x6c\x2e\xbe\x96\x3a\xb7\x25\xa9\xf4\xc1\x1f\x03\x6a\xb1\x22\x87\x53\x1b\x29\x16\xe1\x8d\x98\x5a\xae\xb6\x63\x24\x78\x2c\xc5\xa9\x81\xa5\x38\xce\xee\x26\x34\x80\x98\x1b\x17\x67\xc0\x73\xf9\xfc\x25\xc3\x96\x06\x00\x11\xfa\xfc\x3c\xc2\xc7\xe6\x20\x2a\xb4\x10\x1a\x36\x2c\x3e\xa9\x86\x7f\x89\x0f\x1b\xbd\x38\x00\x89\x0f\xa0\x97\x15\xe8\x4b\x5c\xae\x1b\x67\x82\x88\x85\x9d\x28\xeb\x74\x9e\xb9\x6c\x98\x06\x86\x1b\x6a\xb3\xe1\xf3\xd3\x71\xa4\xe8\x3d\x3e\x1f\x09\x28\x45\xfc\x84\x6c\x94\xb5\x87\xfd\x6c\x9c\xb0\xab\x7a\x56\xd7\xa7\x76\x1d\x1d\x34\x9a\x29\x21\xce\x9d\x08\x11\xb8\x1d\x6b\xa2\x27\xe5\x0f\x38\x71\x94\x10\x60\xd8\x4f\xb4\x9b\xd4\x73\x99\x67\xea\x3c\xea\xb8\x0e\x76\x19\x42\xc0\x56\x14\x5f\x45\xfd\x3a\xac\xea\x53\x12\x46\x42\x76\x0a\x1e\x03\x34\xf1\x6c\x04\x48\x49\xc8\x02\xec\xd8\x35\xa7\xaa\xb8\x11\x27\x85\x18\x38\x7f\x49\x61\x12\x21\x3a\x16\x5b\xa6\x18\x03\x2c\xcb\xc3\x51\x34\x19\x5a\x5e\xf7\x2f\x16\x09\x45\x88\x30\x9c\x4e\x6d\xec\xab\x84\xb4\x1d\x4e\x11\xc9\x25\xea\x4c\x43\x9f\x6d\x5e\x77\x0d\x46\x4a\x42\x49\xc0\xf1\xb3\x6f\xda\x78\xb1\x19\xbe\x79\x24\x94\x14\xb3\xd1\x4c\x95\x98\x62\x46\xdd\x01\x4d\x91\xb1\xb3\x14\xa6\x7d\x1d\xdb\x4d\xc4\xe7\x8e\xed\x41\xfb\x1e\xe3\x37\xfe\xc8\x2e\x6b\xd2\xe3\xab\x8c\xa8\x95\x40\xc0\x05\x67\x8d\x81\x0a\xe8\x81\x1f\x12\x25\x91\x4a\x7d\xed\xcf\xe1\x30\xf5\x58\x8c\xe0\x53\xcb\x6b\x4a\x28\x95\x9e\x80\x8e\x77\xb6\xbe\x3a\xcf\x65\x85\x94\x50\x4d\x91\x32\x63\xaa\xf2\xbf\x50\xcc\xb1\x82\x29\x61\x81\xb1\xb0\x7c\xf4\x0b\xc3\xad\xd8\x1f\x51\x54\xf5\x9c\x1c\x79\xaa\x0a\xd0\xc8\x73\x47\xe6\xa5\x1f\xc5\xa5\x42\xb1\xb5\x6e\x3b\xfd\x18\xc4\x04\x24\xa6\x0a\x45\x4e\xab\x6c\xff\xda\x30\x32\xde\x56\x48\xcc\x1d\x82\x5c\x1c\xef\x9c\xde\x79\x77\xc7\x53\x6e\x39\x63\x36\xcc\xbb\xcd\x4c\xf3\xdb\x4c\xdc\x4c\x49\x2a\xad\x68\xa5\x83\x59\xf7\x4e\x89\x94\xa4\x5a\x63\xf4\xff\x8a\xb2\x47\x2f\xc3\x93\x1b\x8a\x42\x31\xff\xce\x8e\x93\x42\x76\x7b\x2c\xc6\x3a\x14\xe6\x55\x77\xcd\x14\xf5\xe4\x46\x09\x6e\x59\x7a\xb6\x52\xe4\x33\x20\xfc\x7d\x9d\x24\xee\xe8\xb5\x13\xa9\x41\x8e\x76\x37\x25\x0e\xb8\x88\xdc\xb9\x69\x31\x9c\x4f\x4e\x4c\x97\x12\x19\x06\xd8\xac\xbd\xbe\x7f\xf6\x57\x27\xa3\x14\x63\x9d\xc3\xee\x15\x3d\x5d\xeb\xc9\x2d\x95\x46\x60\x6b\x67\x71\x75\x7f\x29\x95\x48\x89\x4e\x13\x8c\xcd\xb1\xeb\x5f\x5f\x8b\xf3\xd2\xa9\x13\xaf\x8a\xee\xe6\x00\xe7\xd4\xb5\x40\x1f\x44\xf7\x49\x88\x53\x7c\x1e\x08\x1d\xb6\xf0\x2c\x84\xcc\xf9\xe3\x86\x11\x2b\x92\xd8\xce\xc8\x9e\xb2\xf0\xf5\x8e\x3f\xdc\x62\x89\x51\x16\x64\x2e\xbd\xc7\xf2\xb3\xc8\x72\x04\x45\x8c\x9e\x78\xd8\xe6\xe4\xb4\xa3\xdf\xd9\xfc\x57\x0f\x15\x11\x68\x18\xc4\x21\x50\x9f\x72\xfb\x72\x9e\xee\x8e\x1a\x40\x11\x0a\x68\x5e\x1d\x4c\x7c\xc4\x46\xa3\x21\x09\x42\xe6\xb0\x23\x96\x21\x31\xad\x5e\xd0\x90\x50\x95\x38\xeb\xfb\x01\xa0\x77\x76\xa1\x0c\xc3\xd0\x52\x7d\xad\xef\xb6\xbd\x77\xed\xff\x16\x90\xf7\xf8\x2b\x1a\x86\x51\x8c\xdf\x7a\x28\x75\x66\xce\x5d\x89\xfd\x72\x21\x1f\xce\xab\x30\x52\x11\xb1\xe5\xce\x46\xbd\xfe\x59\x9e\x3e\xb9\x86\x48\xa7\x58\x3b\xcc\x54\xf9\x52\x77\x77\x82\xca\x4e\x59\xf0\x5e\xd4\x56\xaa\xf9\x4e\x4f\x7e\x2a\x0b\x93\xd0\x65\xa6\x56\x3a\xb6\x2c\x47\xd7\xcd\x78\x82\x7d\xc7\xf2\x08\x03\x91\x6b\x1a\x32\xa9\x69\x34\x12\xb9\xc6\xa9\xb8\x2d\xbb\x50\x7b\xe1\x3b\x19\x68\x9a\x52\x9e\x9a\x6f\x65\x7d\x81\x71\xb9\x5c\x00\xc3\x98\x26\xd8\x8d\x7f\xde\xfc\xe9\x43\xeb\x30\x4e\xb5\x89\x7a\x38\xa7\xa7\xb4\x7c\x55\x06\xa2\x61\xac\x08\x1d\xe9\x09\x63\x0d\xbb\xb6\x13\x7b\x50\xa5\xa0\x61\x92\x58\xcb\x5b\x6c\xfd\xd9\x2a\xcd\xe4\x9d\x1d\xff\xe3\x3e\x96\xf2\xc8\x58\x57\x25\x50\x27\xbf\xb7\xf9\x74\xea\xc1\xd6\x63\x6e\xa0\x6f\x4c\x8f\x1f\x5a\x9a\x50\x0c\x39\x4e\x35\x54\x57\x97\x48\x59\x1a\xa6\xc2\x60\xf8\xe6\x75\xf1\x67\xab\x83\x38\x0c\xa4\x33\x06\x99\xea\x32\xf9\x21\x86\x33\x31\x70\xfd\x82\x6a\x59\x96\x6f\x19\xb4\x9b\x93\xa8\xd4\x6b\x5f\x69\xa6\xa1\x08\x42\xd9\x17\xcf\xae\xef\xae\x67\xc0\xb9\x34\x14\x84\x98\xde\x40\x66\x91\xe7\xcb\x32\x77\x16\x15\xdd\x89\x42\x6b\x7d\x2b\x45\xf1\x36\x7e\x81\x45\x22\xf1\xc3\xbb\x7e\xf2\xac\xe1\x1d\x8a\xd3\x3c\xc7\x68\xfc\x4a\x48\x62\x03\xb0\xeb\xe5\xe3\x4d\x59\xdd\x8a\xee\xbd\x96\x09\x63\x3d\x63\xe9\xb9\x9a\x15\xc0\x72\x63\x15\x97\xd4\x95\x95\x9e\x4f\x87\x63\x0f\xe8\xa5\xa1\xe6\x12\x73\x8e\xcd\xa9\xf8\x7b\x38\x1e\x1a\x6a\xe3\xed\x6e\xfd\x82\x1a\x02\x4d\xb1\x6e\x55\x21\x18\xf3\x1d\xe6\xde\xf1\xcb\xff\xf5\x1f\x4e\x6c\xf8\x70\x3c\xd5\xaf\x57\x8b\x97\xf0\x82\xa9\x39\xfa\x31\x51\x10\x93\xd4\x5a\x96\x75\x24\x56\x1a\x05\x5a\x60\x8e\x6d\x39\xdf\xf0\x0d\xaa\x79\xc7\x33\x1a\x11\xd7\x08\xfa\x5d\xbc\x0b\xc4\x74\xac\x7e\x0a\xd4\xdb\x76\xc7\x43\xc2\x11\x56\xa2\xde\xeb\xff\x9c\x44\x35\xb3\xfc\xfb\x81\x09\x60\xd1\xe8\x42\xc9\xf9\x6f\x17\xd0\x66\xdf\xe3\x28\x0a\x20\x1c\x76\xc9\x2b\xd0\xbb\x66\x90\x0e\x47\x51\x62\x65\x32\x9a\xbe\xd3\xbf\x30\x0d\x54\x23\xad\x44\x1a\x51\x9a\x70\x8f\x65\x42\xd9\x8d\xac\x86\x45\x81\x38\x95\x19\x55\x6d\x1a\xd1\x54\x0b\xd3\xf1\x72\xbf\x2d\x7e\xfc\x71\xf7\x78\xeb\x4f\xc6\x02\xeb\x04\xbd\x58\x5f\xdd\x6d\xd7\x8b\xdb\xf6\xd0\xf8\xb2\x19\x65\xb2\xd3\x48\xfd\x3e\xe1\x11\xb8\x31\x5c\x4b\x2c\x41\xdb\xaa\x8a\xc3\x31\xcf\x27\xc3\x51\x4c\xb8\x17\x03\x7f\x10\x7f\x95\xa8\xef\xfb\x5a\x41\xfd\xda\x19\x78\xd1\x28\xa6\x81\xb2\xb6\x3e\x35\xb2\x28\x20\xab\xca\x61\x88\x10\xc5\xcc\x32\x19\xd1\xfc\x79\x03\x8d\x6d\xed\x0c\xa8\x9c\x34\x4a\x82\x98\x77\x3b\x30\x7e\xf8\x9b\x0b\x46\xfc\x00\x11\x22\x77\x6b\x9d\xed\xef\x74\x3f\x4f\x12\x1d\xa0\xc7\xdc\xfe\x04\x75\x3d\xa3\x9c\x42\xa3\x94\xd1\x44\x7b\x12\xf3\x49\x77\x5d\xa2\xf6\x48\xea\xa9\x36\x0f\x80\x5c\xce\xd7\xec\xe8\x30\x88\x7e\x08\xd7\xc8\xd6\xd9\x2c\xfe\x58\x2d\x9f\xee\x1e\xbb\xbf\x4b\xc0\x78\x79\xf1\x6d\x39\xfa\xa5\x52\x07\x3c\xed\x42\xc7\x67\x51\xd7\x68\x72\xfa\xa9\xd7\x41\x7f\x99\x8a\xa4\x88\x71\x3f\x94\x85\x8d\x9a\x07\xcc\x02\x1a\xa9\x88\xe1\x5e\x71\xdc\xd9\x15\x72\x37\x36\xcd\xfa\x54\x4e\x77\xb8\x62\x44\x2a\x4a\x11\xbf\xba\xc3\x0c\xa1\x80\x0f\xe4\x9f\x5f\xf4\xc2\x69\xa4\x69\xe8\x64\x4f\xdf\xcb\x37\x9b\x44\x7e\x1f\x97\xd2\xdb\x31\x09\x42\xb3\x3b\x14\xc9\xa5\xad\x0e\x8d\x74\x0a\x1a\x3c\xb3\xf2\xe8\xfc\x83\x27\x43\xa4\x41\x95\xcc\xab\x53\x9e\x43\x93\x15\x57\xe5\x94\xfc\x4e\x23\x93\x08\xd7\xff\xd9\x67\x35\x5a\x59\xfe\xab\xe8\x35\x8b\x47\x3f\x92\x06\x61\x8a\x6e\x27\xed\x06\xd7\x5e\xf4\x10\x0f\xf3\x55\x81\x9b\xd2\x40\x32\x14\x48\x5c\x35\xaf\xcf\xe7\x4a\x1c\x32\x1d\x04\xff\x72\x3a\x82\xed\x51\x5b\xd8\x6a\x7f\x4a\x59\x40\xf3\x2a\x6e\x45\x03\x1f\x62\xf2\x93\x69\x60\x62\xe3\xa4\xde\x90\x32\x89\xdd\xf3\xaf\x9f\x3d\x0d\x89\x65\x3b\x67\xf5\x73\x05\xdd\x42\x66\xfd\xb1\x7e\xeb\xc6\x40\xac\x7a\x23\xa3\x9b\x2e\x89\xff\xfd\x61\x72\x05\x21\xa7\x18\x90\xdf\xe5\xf9\xe9\x90\x15\x03\xed\x7f\x4a\xc3\x38\xe4\x51\xb7\x5d\x0d\xdb\x35\x94\x46\x22\x40\xfc\xa3\x2c\xcb\xb1\x5e\x32\xa5\x91\xb2\x72\x88\x56\xd1\x79\x09\x75\x93\x99\x4c\x0d\x56\x96\xc9\x0f\xa2\x92\x07\xae\xbd\xfd\x58\x5a\xef\x23\x0b\xdf\xf1\xc7\x8d\xa1\x0e\xf3\x8b\xba\x5a\x88\xde\x6c\x47\x0c\x90\xa3\x6e\x28\x8b\x08\x06\x66\xed\x32\xbb\x3b\x3a\x68\x9f\x3f\x46\x43\x34\x43\x68\xfa\x22\xa3\x3b\xc2\x25\x13\x5e\xc1\xcd\x52\x52\xff\x0b\x17\x75\x18\x3f\x16\x62\xb4\xdb\x2b\x4f\x4d\x03\x15\xb6\x7b\xbc\x92\xbf\x3f\x5d\x1c\x5a\x35\xac\xc5\x6a\x39\xaf\xd6\x39\x9a\x82\x71\xa2\xb1\x29\xe0\x44\x69\x4f\x55\x51\xbe\xf7\x92\xf9\x93\x5b\x15\xa7\xb6\xf3\xd9\xae\x9b\x55\x1b\xb3\x7a\x90\xea\xfc\xc6\x49\x63\xa1\xac\xcf\x0b\x96\x0c\x37\xe5\x01\xbe\x7b\x2d\x3c\x4a\x63\x65\x30\xa3\x6a\x53\x8c\x7f\x9e\x84\xe5\x17\x0e\xed\xba\xdd\xb8\x24\x20\x88\x01\x3e\x62\x8d\xf6\x79\xbd\xea\xfc\x0a\x28\x4d\x49\x32\x40\xb2\x2d\xb3\x0a\xc3\xd8\x7e\x2d\xa2\x29\xb3\x6e\xc6\x0f\x77\x8f\xbb\x97\xcd\xf5\xee\xe6\xe5\xf1\xba\x3b\x96\x72\xd5\x41\xa2\x9e\xab\xb2\x34\x63\xc3\x9c\x3e\xee\x1e\x56\x38\xfd\x87\x15\x47\xab\x83\xf6\x51\x6b\xd1\x08\x7f\x52\xc1\x00\xf7\x06\x2b\x8a\xd0\x3f\x64\x19\x24\x91\x9b\x65\xab\x85\x87\xf8\xc1\x48\x33\x82\x52\x29\x62\x6c\xeb\xef\xe0\x67\x56\x37\xcf\x27\x99\x67\xea\x0f\x38\xcf\x22\x64\x28\x95\x9a\x11\x3d\x14\x29\x19\x95\xb3\xa8\xd4\xdc\x7b\x6c\xb6\x8f\xf4\xbe\xbc\x94\x12\x70\x23\x95\x50\x18\x4d\x09\xad\x7f\x2f\xe5\xe6\x58\x16\x75\x69\x69\x42\x5f\x2f\xd5\x73\xc8\x7a\x4a\x75\x1c\x59\xa3\x43\x94\xf3\xd8\x0e\x18\x10\xdf\x44\x7d\x59\x54\xfb\xec\x2b\xe6\x57\x1f\x6d\xe2\x50\x77\xde\x28\x23\x21\x06\x4a\x21\x14\xf6\xe5\x28\xf2\x33\x8a\x89\x54\x0f\x7d\x86\x4e\x41\xa5\x21\xf1\x86\x33\xf7\x59\xdd\x99\x98\x4d\x96\x24\x50\x0a\x03\x00\x3b\xdf\x06\x93\x0d\x74\x82\xb2\x66\x59\x7d\x2d\xb2\xfc\xfc\x72\x44\x10\xfc\x1a\xc4\xaf\x4a\x85\x14\x4c\x4c\xc2\x4e\xfd\xcb\xca\x28\xe0\x32\x62\x59\x48\x13\x98\x24\xa5\x26\x8e\x31\x0e\xdb\x42\xdd\x84\xe1\x70\x4d\x34\x71\x3a\x28\x75\xa2\xdd\x77\x39\x49\xc5\x12\x3f\x34\xb1\xbd\xb8\x4c\xa1\xc0\xf0\x38\xd4\x63\x24\x60\x58\x04\x38\xb6\xd3\x62\xd2\xe9\x1c\x4e\x23\x46\xc2\x14\xa5\x4a\xde\xcb\x06\x3c\xe7\x61\x6e\x71\x60\x84\x59\xd7\xf9\x0e\x83\x11\x76\xdf\x15\xa7\x58\xb9\x2f\x5c\xe7\x1d\xf3\x6c\xbf\x94\xb3\x28\x49\xb0\x29\x74\xb7\x7c\xda\x3d\x7f\x5b\x6c\x56\xd1\x48\xfb\x94\xb2\x28\x4d\xb0\xc4\xe5\xc8\xfd\xdd\x69\x23\x61\x64\xd2\x09\xbe\x5e\x67\xf5\x31\x17\xe7\xe1\xd2\xcd\x22\x23\xb1\xf1\x31\x80\xc9\x4c\xaa\xfb\x8c\x86\x22\xf6\xdd\x96\xfb\xef\x0e\x30\x9e\x76\x47\x15\x45\xd9\xc4\xaa\x6b\x98\x30\x0a\x3c\x74\x5a\x95\xb6\x12\xf0\xf7\x78\xff\xe3\x77\x97\x71\x6d\x71\xf0\x6d\x68\xf4\xde\x2e\x5d\x1d\xfa\xcf\x0f\x00\xa5\xac\xe1\x07\xea\xb9\x0d\x6b\xc6\x2c\x21\x49\x3a\xf6\x5c\xbb\x1a\xcf\x61\x96\x06\x0a\xc9\x44\xd6\xc6\xa2\x8f\x11\x59\x4a\x15\x2e\x43\xfe\x51\xfc\xf3\xd4\xee\x8f\x9d\x91\x07\x65\x29\x07\x0c\xed\x6a\x2f\xba\x66\xb5\x6e\xf3\x76\xc9\x5a\x68\x3d\xac\xf0\x8d\xe4\xc7\x29\x4b\x55\x84\xfd\x45\x5f\x0f\x7a\x29\xd4\xe8\xf5\x64\x22\xb4\x6f\xc1\x21\x2b\x9a\xa5\x38\xde\x15\x2f\x9b\xeb\xee\x98\x31\xc8\x89\x3d\x9e\xf2\x31\xbe\x8e\x32\x19\xa6\x81\x1e\x00\x9a\x9e\x2b\x68\xf6\xfd\x51\xc7\xba\xb3\x91\xc8\xc0\xf6\xfd\xeb\x94\x89\x49\xa7\x02\xd7\x94\xb7\xd9\xfb\x40\xc3\x91\x32\x45\x13\x6d\x7b\xaf\xea\xd4\xa6\x10\xbb\x85\xd6\xed\x86\xfd\x51\x56\x7a\xf3\x2a\xa2\xf6\x71\x6c\xcb\xab\x36\x67\x77\x15\xe5\xe1\xb3\x51\xc6\xa0\x91\xf5\x6b\x79\xaa\xa1\x1d\xb4\x2e\xbd\x47\x36\x65\x5a\xa6\x88\x65\x59\x42\xd1\xd4\xc7\xb2\xcc\xc5\xa8\xf0\xc6\xb4\x4e\x10\xe7\x63\x2b\x65\x57\xa7\xaa\x18\x59\xe2\x53\x66\xb8\x46\x34\x89\x2b\x3d\x08\xab\x53\x84\x80\x9f\xf1\xcb\x68\x64\x18\xb8\x08\xf0\x11\x3e\x1c\xd3\xd0\xa5\x1c\x73\xab\x36\x0f\x68\x42\x7a\xe7\x38\x44\x3e\xf9\xcb\xe2\x01\x0f\x85\x1e\x87\x89\x83\x7a\x00\x0f\x84\xc1\x82\xe4\xd4\xe4\x62\xfe\xce\x73\x12\x6a\x7b\x13\xae\x7f\x5d\x38\xe0\x21\xb1\xbe\x24\x28\x53\x74\x55\x36\x4d\x79\xf0\x5f\x1b\x26\x0a\xf7\xfe\xd5\xe3\x66\x8d\xb1\x76\xd5\xc5\x16\x3c\x0a\x02\x50\x4e\x16\xb2\xfb\x1b\x09\x0c\xf7\x8a\x22\xae\xc4\x3a\xbf\x21\xf2\x48\x58\x33\x62\xa1\xf5\x50\xa6\xdf\x1f\x95\x4a\x7b\xed\xe2\xed\x6b\x55\x7e\xd4\x9b\x36\x74\xec\x60\x02\xed\xb3\x7b\x2c\x87\x42\x5a\x94\x53\x16\x22\x6b\xd0\x75\x90\x87\x9e\x36\xd8\xca\x5a\x34\xeb\x19\x4f\x70\xff\x61\x6e\xd1\x72\x03\xd8\xe7\x74\x84\x66\x49\xe8\x43\x99\x6f\x28\x0f\x7a\xb6\x64\xdf\xdf\xa6\x03\x53\xb4\xab\xea\xfc\x9f\x56\x48\xec\xc8\xaa\xee\x36\xb1\x28\xc0\xd8\x1d\x79\xfd\xcf\xe2\xbc\x38\x34\xdd\x21\xaa\x51\x7b\xa6\xe9\x0b\x78\xa7\x7a\x84\x36\x1b\x5e\x3f\x09\xbd\x8e\xae\xff\x38\x30\x27\x2c\xdd\xef\x82\xcf\x25\xba\x2f\x75\x73\x89\x47\x44\x39\xcd\x47\x6f\x4e\xfc\x4d\xcc\x40\x5c\xfc\x70\x19\x5b\xf3\xd2\x36\xcb\xf7\xe7\x88\x03\x6b\x06\x61\x5f\x92\x55\xd1\xa0\x30\x5d\x5f\x4e\xed\xdf\x27\x1e\xa7\x32\x18\x6a\x1e\xb4\x6b\xd7\x5c\x62\xce\x93\xc0\xe2\xcd\x5c\x71\xde\x16\x32\x1d\x3b\x78\x3c\x3b\xd2\x48\x63\x30\x65\x6b\x92\x4f\x56\xaa\x7d\x99\x97\x98\x5c\x67\x9f\x90\x30\x29\x4f\xa5\xc0\x12\x8e\xbd\xe8\xe7\xf2\x0d\x0e\x9f\x9b\xe7\xfb\xcf\x68\xae\x7a\xe1\x1e\x9d\x15\xfb\xfb\xf2\x43\x89\x23\x86\x24\x53\x10\x03\x17\x89\xc0\xf8\xa7\x3e\x1d\x8f\x65\xd5\x6b\x37\xfb\xdb\x26\x95\xc6\x34\x04\xdc\x0d\xb3\x4e\x6d\xee\x20\xb8\x2c\xbb\x86\x66\x99\x9f\x80\x8e\x42\x4d\x0e\x00\x58\xc8\xb1\x42\x61\x37\x2f\xdb\x97\xf5\x6a\xb7\x5c\xf8\xae\x4d\x1c\x70\x23\x88\x8f\xda\xda\x5d\xae\x5e\xf6\x57\xe9\xc7\x08\x81\x6f\x95\x0d\xbb\xae\x4f\xd5\x30\x8e\x8f\x89\xb1\x47\x3b\x27\x9d\xee\xba\xe3\x48\x47\xd8\xe5\x5b\xfd\x25\xaa\x6c\x7d\x6a\x4f\xee\x0f\x51\x96\x5a\xb7\x76\xfb\xd6\x39\xcd\x8b\xeb\x93\x07\x84\xd2\x98\x26\x44\xa4\x08\x3c\xfc\xeb\x43\x0c\xab\x23\x31\x0b\x54\x57\x4c\xca\x8a\xec\x74\xb8\x2b\x8e\xa7\xa1\xa0\x0e\x8d\x19\x23\x88\xd4\x38\xbc\x61\x33\x79\xfa\xb0\x7c\x64\x30\xbc\x55\x31\x4b\x20\x09\xfd\xad\x58\xd4\x6d\x90\xdc\xe1\xad\x67\xdf\xed\x98\x09\x82\x4f\x79\x71\x7f\xff\xb4\xdc\x6d\x57\x0b\x8f\x5e\x88\x39\xd3\x32\x9e\xb0\x8c\xc7\x94\xa1\xf9\x33\x72\x0d\xa1\x83\x88\xe7\x2f\xeb\xfb\xdf\xbe\x90\x9e\x71\x9f\x88\xe3\x14\xa5\xee\x6e\xb2\x77\x5f\x0a\xa4\xab\xf7\xfe\x4e\xc4\x09\xd5\x3e\x1b\x72\x35\xf6\xeb\xac\x2e\x3f\x8a\xc9\x3a\x18\xc7\x10\x6b\x47\xd0\xbb\x39\xe5\xf9\x36\x53\x6f\xbd\x39\xce\x57\x93\x3d\x4e\x88\xe1\xfd\x7b\xb5\x53\x25\x8c\x49\x32\x34\x4e\x62\x8d\x21\x53\x9e\x15\x6f\x2b\xaf\x15\x3b\x4c\xda\xe2\x24\x49\x90\xce\x75\xac\xca\x03\x34\xaf\xcb\xb2\x9f\x08\x89\xa1\xa4\xdb\x1d\x6a\x58\xa2\x18\xa2\x9a\x14\x4c\x62\x11\x0b\x6c\x3f\xfa\xe6\xe8\xe8\x26\xc9\xd0\xfa\x2d\x54\xd0\x54\x22\x6b\x36\x8d\x28\xb4\xa8\xf4\x8e\xfa\xef\x90\xdc\x8a\xf8\x3b\x68\xb0\x38\xde\x54\x00\xb3\x2d\x8b\x58\x42\x04\xd4\x63\xdd\x2f\xfc\x22\x3f\xb9\x45\x8a\x10\xb0\xf2\x46\x7a\xb0\x55\xb8\x83\x3a\xa6\x18\x11\x68\xeb\x2f\xdc\x01\xcb\xfd\xe1\x24\xc5\x3d\xde\x3f\x0b\xff\x67\x69\xdb\xb6\x87\xac\x83\xa2\x8f\x3a\x15\xb1\x06\xab\x54\xf7\xd1\x83\xac\x2e\x2f\x4c\x9b\x80\xba\x9b\x7b\x5b\x89\xc2\xd5\x54\x07\x81\x4d\x0c\xd4\x8a\x4f\xed\xed\xba\xdf\x21\xca\x69\x6c\x12\x12\x3b\xc2\xa7\xc9\xaa\xc3\x22\xcf\xaf\x4e\xe7\xba\x3f\x1a\x45\x23\x0b\x3e\x0c\x21\xfa\x2c\x28\x36\x22\xb6\xca\x60\x36\xfd\xc1\x38\x62\x3c\x6f\x92\x20\x08\x22\x87\x45\xf8\x6d\xee\x9d\x4d\x02\x12\xa2\x20\xcb\x60\xe1\x48\x02\x10\xbe\x1e\xeb\x08\x19\xe3\x93\x12\x2e\x11\x85\x01\x85\x7e\x32\x4e\xfa\x7d\x69\x7f\xc2\xa8\x98\x9c\x90\x14\xbc\xec\x04\xbe\xbb\x43\xf6\xfc\xec\xeb\x9b\x10\x25\xf1\xab\xfd\x52\xf8\xbb\xf8\xab\xdd\x95\x66\xf0\xbd\x34\x09\x49\x18\xd8\xb6\xe0\x3b\xd4\xcd\x5d\xf1\xcf\x13\x9c\x3e\x59\x68\x92\x48\x05\xcc\x01\x86\x50\xb2\xeb\xa6\x3c\x94\x93\xd3\x51\x6d\xed\xd6\x31\x81\xc5\xda\x0f\x7c\xd2\xf5\x4d\xa8\xb6\xf6\x74\x2e\x81\x01\xfd\x50\xbe\xcf\x56\x41\x13\x0a\x2c\x72\x10\xe9\x87\xf3\x43\xed\x21\x7e\x09\x4b\x18\x6a\xb5\x2c\xb6\x0f\xbf\x8e\x14\x13\x4e\x14\x56\x9d\x1d\xff\x43\x14\x30\xa1\x34\xce\xbf\x34\x09\xe7\x1c\x65\x46\xea\x2c\x7f\x87\xaa\xdd\x9c\xec\x1c\x71\x87\xe3\x48\x28\x67\x58\xb8\x5c\x3d\x7d\x25\x89\x47\x93\x58\xf2\xd4\xb6\x0e\x34\x4a\x24\x7c\xda\xc1\x4d\x12\x21\x51\x62\x70\xf1\xb8\x18\x64\xf7\x49\x62\x82\x00\x57\x90\x53\x81\x1e\x97\xcf\x55\xf6\x9e\xe5\xb0\x87\xfb\x93\x7a\x3b\x5f\x77\xa8\x7b\x9a\xa4\xd4\x6a\xbd\xed\xc5\x71\x12\xe2\x25\xa9\xb4\x4a\xc0\xc2\xd7\x12\x37\xcd\xd4\x07\x88\x26\xa9\x62\x98\x74\x63\x09\xc3\x71\xc8\xfc\xb9\x05\xa4\x36\xa8\x72\x09\xd7\xda\xd7\x58\xdd\x3b\x95\x48\x1a\x06\x74\x60\xdc\x75\x61\x58\x38\x2e\x24\x4c\x6e\xb8\x8c\x23\xe1\x38\xee\xd7\xd9\xfb\xc8\x5b\xd5\x8f\x50\xd6\x0e\xc2\xef\x6b\xee\xdd\xad\xb7\xe5\x23\x7c\x5c\x8b\xe9\xa4\x54\x3c\x09\x5c\x2d\x1c\xaa\xfb\xac\x78\x1b\xee\xe3\x89\x8e\xac\x73\x0f\x6a\x9d\xbe\xc3\xf2\x55\xe4\x39\x14\xfb\x69\xc6\x94\x00\x08\x6a\xe1\x68\xdd\x72\x0b\x23\x87\x19\x9a\x18\x6a\x59\x98\xd6\x33\x15\x93\x38\xff\x2d\x46\x69\xbf\x1c\xd8\x5a\x9c\x8f\x5f\xfe\x8f\x0d\x3e\x7b\xba\x34\x48\x2d\x4b\xc9\x91\xf7\xe7\xe7\x5b\x1a\x40\x9c\xba\x9f\xb6\x7c\x2d\x6b\x28\xda\xfd\x04\xe7\xbc\xdf\x6f\xd3\x90\xd8\x8a\x22\x0a\x20\xb7\x61\x5f\x7d\x75\xb6\xff\x31\x6d\x6e\xa4\x61\xaa\xb1\xdb\x7e\xc4\xb2\xe3\x06\xba\xb4\x35\x0d\xa5\x8e\x9c\xc1\xe8\xc3\x29\x9f\x79\x62\x69\x24\x03\x6c\x78\xdd\xae\x36\xc3\x9b\x9f\xd2\x50\xe8\x61\xe3\xe5\x0a\xb9\x6d\x36\x22\xf8\x32\x46\x49\x29\x8d\xbc\x7c\x81\xad\x43\xac\x44\x75\xa1\x32\x49\x53\x2a\x6d\xff\xe0\x5d\x54\x19\xde\xf0\xe7\xaa\x94\x42\x7a\xbd\x1c\x9a\x52\x43\x8c\xec\x71\x47\x03\xa8\x99\xc3\x3e\x77\x11\x68\xca\x62\x2b\x99\xb2\x7c\x5a\xaf\x1e\x3d\x06\x9f\xa6\x2c\xb5\x75\x8d\xe7\xf5\xea\xe1\xee\xe5\x61\x87\xfe\xa9\xcf\x8b\xe5\x1f\xbb\x81\x85\x2a\x4d\x39\x89\x62\xab\xc6\x87\x05\x9d\x5d\xbb\x8a\x22\x75\xea\x66\xe2\x1b\x4b\x53\xce\xac\x4a\xe1\xcd\xe2\xb9\x8d\xdb\xfd\x19\xe2\x30\xc2\xf4\x6a\xb9\x5d\x5e\x0a\x80\xd0\x34\xd6\x04\x4b\xd9\xdb\x2c\x9f\x82\x04\xdd\x88\x24\xb0\x70\x0e\x5f\xdc\xd9\x34\xa2\xaa\xb7\xa5\xfb\xd5\xfe\x6b\x12\xca\x10\x5b\x80\x50\x8e\x65\x0e\x5d\xd6\x9c\x26\x2e\xe8\x78\x04\x5b\x28\x33\xbd\x6d\x23\x4d\xd3\x14\xb0\xe3\x02\x85\xbe\xd0\x0a\xa3\x69\x2a\x42\xee\xa6\xa2\x4b\x3f\xef\xc1\x34\xdb\xb2\xd3\xa8\x9a\xde\x83\x54\x86\x18\x51\xea\xb2\xcd\x9c\xdb\x2c\xfa\xa9\xc0\x16\xf0\x75\xf6\xee\x4f\xaa\x80\x20\xfb\xdc\xe1\x96\x8f\x75\x1b\xdc\xfb\x83\x3a\x12\xd8\x4f\xa9\x9b\xd2\xea\xa5\x74\xb2\x23\x6e\x00\x44\x92\xbb\x6d\xe5\x19\x8a\x36\x26\xfb\xea\x85\x74\x1f\x32\x54\x18\xdd\xbb\xb8\x0d\xab\x89\xa9\x61\xb1\xa7\xa8\xdc\x8b\xba\xb9\x87\x77\xf0\xaf\x88\x08\x52\x29\x2c\x94\xaf\x58\x28\x05\x75\xbd\xfa\xa9\xf2\x53\x3d\xc0\x35\xf8\x81\x82\x63\xd1\x72\xb3\x87\x5f\x4b\xef\x52\x11\x40\x48\x95\x57\xee\x2b\x1b\xb1\x6c\x13\x7c\xff\xa5\x24\xb6\x56\x41\xb6\x6f\x07\xae\x0a\xe2\xa7\xbe\x08\x43\x46\xc0\x53\x7f\xfd\x1f\xa3\x30\xc0\xaa\xc9\xe6\x65\x71\x3c\xfe\xb2\x3d\x24\x22\x16\x8b\xd0\x9b\xfd\xf4\x2e\x5a\x93\x1f\x15\xa5\xda\xdf\xb5\xe5\x6b\x96\xeb\x3b\x3d\x5f\x23\x16\x94\x58\x23\x84\xab\xbb\x87\xbb\xdd\xf5\xe2\x69\x17\x11\x7f\x61\x8c\x70\x2c\x3c\x0a\xad\xd7\xdb\xa7\xf9\x86\x92\x60\x8e\xa7\x7f\x40\x86\x25\x22\xfe\xf3\xf3\xd5\xf9\xaa\x6a\x23\xde\xc9\x45\x31\x30\x6c\x28\x4a\x84\x3e\x1b\x6d\x06\x5e\x9e\xe6\x34\x25\xa9\xe0\x9c\x63\x61\xea\xf1\x74\x68\x86\xcd\x46\x11\xc7\x12\xb7\xe5\xac\x7e\xa9\xa1\xba\xb2\xaa\x14\x93\x6f\x8b\x85\xed\xba\xed\xe4\xe9\x7c\x57\x5c\x8d\x9c\x33\x3e\x89\xda\xa7\xf0\x10\x91\x68\x8d\xf0\x10\xd7\x8b\xf3\x5d\x81\x61\x3c\x22\x12\x13\xa1\x51\x4b\x93\x1d\xe0\xc9\x0c\xbc\x50\xa8\x48\x23\x6d\x4b\x9a\x7e\xb1\x15\x75\xa6\xbe\x5e\x66\x45\x1a\x1b\x64\x56\x39\x7f\x75\x2c\xb0\xbd\x1c\xf1\x21\x7e\x9d\x6c\x88\x34\x15\x58\xd4\x1f\xa6\x77\x22\xd5\x84\xf1\x2e\x49\xfb\x21\x32\xbc\xe1\x2f\x45\x93\xe5\xbe\x2c\xfc\x54\x4d\x7d\x59\xdd\x67\x45\x48\xd1\x8c\xf3\x54\x60\x15\x0b\xf4\xcb\x71\x8f\x60\xca\xf1\x8d\x96\x61\x8c\x40\xcb\x7d\x66\x9a\x3b\xbd\x2d\x11\x1a\x3b\x3e\x93\xd4\xc2\x19\xdf\x17\xba\x93\xbc\x5b\x14\x7a\x29\xf2\x8b\x68\x75\x98\x1f\x0a\x09\xb6\x08\x73\xf5\xf4\x78\xed\x29\x50\x42\x31\x8a\xf8\x78\xf8\x09\x95\xca\x6a\x58\xbe\x6c\x56\xf3\x31\xaf\x50\x89\xd0\xa9\xdf\x6d\xdb\x3c\x0a\xbc\x9e\xe4\x27\x21\xa3\xd0\x01\xc1\x17\x62\x53\xaa\x4c\xe4\x99\xf1\x8b\x8d\xd0\x5c\x32\x79\x91\xdb\x7f\xda\x90\x1b\xfe\x0a\xe0\x14\xef\x90\xa8\x2a\x71\x1e\x4e\x1e\x19\xf0\x48\x3b\x06\xf5\xa3\xe3\xcd\xff\x2d\x9e\x41\xf7\x71\x2b\x90\xd0\xde\x72\xdf\x7a\xfb\x72\x92\xc8\x20\x8d\x11\x79\x67\xbf\xd0\xea\x60\x8d\xbf\xd0\x87\xc4\x32\x10\xd6\xfb\x70\x71\xfd\x72\xbf\x5d\xbd\xf8\x22\x87\x24\x94\x62\xca\x6d\x55\x05\xfb\x95\xde\x81\x4a\xbe\x9c\xde\x92\xc4\xa9\x76\xcb\xa7\xe7\xc0\xdf\x0e\xb1\x66\xff\xc7\x26\xe4\xa7\xff\x5e\xf0\x60\xfc\xf7\x4b\xde\x4f\x08\x55\x56\x56\x0a\xcc\x9b\xc9\x58\x28\x6c\xdd\xfd\x52\x9d\x2a\x1f\xf4\x5d\x26\x81\x6e\x50\x18\x4a\xc4\x0c\x66\xaa\xdc\x89\x09\x35\x99\xca\x30\x8d\x70\x75\xbf\xc9\x0a\x71\xec\x92\x7b\x19\xea\x08\xd3\x8d\x63\x9b\xbf\x47\xc3\x4d\x4d\x46\xd2\x5a\x06\x2e\x74\x7b\x39\x59\x31\x6c\x66\x48\x6a\x4c\xe0\x43\x75\xd1\x58\xaf\xff\xf9\xb7\x57\x32\x1a\x85\xae\x19\xb7\x50\xcd\x49\xe4\x43\x96\x32\x95\x2c\xb5\x5e\x09\xdb\xd5\xe2\x61\xd8\x84\x97\xac\x0d\x9e\x7d\x3d\xec\xc2\x87\x9f\x4a\x9e\x50\xe4\x9d\xf5\x58\xab\xa5\xf0\x9b\x99\xe4\x89\x46\x59\x0e\x07\x68\x84\xca\x79\x4d\xd5\x57\xe5\x64\x8b\x92\x31\xa1\x48\xfc\x43\xd7\x9c\x75\xbb\x82\x37\x37\x25\xa6\x7b\x56\xcd\x66\xf8\xe4\xbd\x34\x46\xe0\x3f\x1b\x5b\xdb\x56\xec\x7f\xbc\x0b\x8d\x35\x9b\xc9\xf9\x13\x16\xe3\x2d\x1e\x09\x6f\x8f\x87\xa4\x4a\x63\x40\xe2\xd6\xb5\x75\xb6\x1f\xb0\x67\x7d\x95\x5c\xa6\x9a\x18\x2b\x23\x59\xbe\x9d\x3e\xa1\x1a\x49\x11\x0a\xe2\x30\x11\x0a\x8a\x06\x31\xd2\xc3\x91\x49\x37\x0e\x30\xd7\x6a\x17\xf7\x61\xe9\x52\x8a\xc8\x12\xae\xeb\x9e\x52\x27\x45\x0a\xa4\x23\x4e\xce\x48\xf3\xf8\x61\x26\x45\xd0\xd0\xb7\xb3\xac\x32\xed\x31\x47\x52\x12\x89\x73\x25\xab\x57\xb5\xaa\xca\x8f\x11\x22\x48\x4a\x96\x18\xab\xcb\xf3\xf3\x93\x9f\x24\x8d\xc4\xce\x04\xbe\x21\x38\xc9\xb2\x5f\xc7\x6b\x52\x45\x56\xf5\x41\x97\x3b\x44\xd5\x4d\x66\x8f\x52\x61\x24\xbb\x27\x07\x97\xe8\x6a\x37\x4e\x33\x15\x33\xaf\xbe\x67\x21\x26\xe3\x10\x61\xf2\xb5\x3a\x05\xe4\xc3\x64\xf5\x53\x5f\x05\x95\xc0\x89\xe7\x48\xf6\x99\xd8\xb7\xf2\x54\xe5\xe7\xb5\x68\x2e\x6a\x8a\x93\x6b\x00\x6d\x03\xec\x0e\xa4\x06\x85\x86\xea\x59\x9c\xeb\x36\x83\xf8\x62\xc1\x97\x00\x09\xf6\xb0\xed\x7a\xf2\x5c\x96\xf9\xe3\x27\x88\x33\x09\xc6\xe0\x02\x71\x8b\x55\x6d\xa8\xee\x96\x4f\xa3\x04\x73\xf4\x33\x55\x40\x99\x4d\x08\xbe\x0d\x25\x3b\xa8\x22\x3c\xc5\x2f\xbc\xca\xf6\x6b\xd0\x83\x0a\x86\x22\x1c\xb0\x0a\xb3\x5c\xaf\x16\xdb\xd5\xf5\xee\x79\xfd\xf4\xe0\x01\x14\x2a\x14\x02\x3a\x25\x00\x5c\x85\x1e\xfa\x4f\x86\x10\xa2\x64\xf1\x0e\xd1\xa0\x4f\xe6\x5e\x14\xda\x57\x84\x47\x17\x45\x93\x00\x95\x87\x6b\x61\x46\x14\x0c\x45\xc1\x7a\x13\x0e\x29\xbb\xdb\x72\x81\x4a\xb8\x5e\xeb\xdf\x07\xc7\x8a\xb1\x4e\x1f\x73\xd9\xcb\x04\x6d\xcb\xa5\x38\x1c\x45\xb6\x9f\x77\x4e\xa1\x8a\xa9\xd4\xeb\xd6\x3f\x88\xac\xf8\xb3\x3c\x39\xbe\xff\x44\x9f\xe2\x73\x05\x86\x29\xb1\x4e\x71\x2a\x90\x23\x74\x5b\x7a\x8c\x81\xe2\x4c\x43\xd4\x4b\xa1\x9f\x47\x65\x08\xc5\x99\x41\x40\x14\x2a\x0c\x43\x7d\x75\x6e\xd7\xe6\xc9\xcc\x57\xb1\x90\x08\xcd\xfd\x70\x31\xd8\xfc\xa4\x53\x89\x62\xca\x56\x3d\x3a\x26\xc9\x5c\x3d\x5a\xa5\x84\xe3\xda\xf0\x01\x59\x9f\xd2\xf9\xd5\x5d\xa5\x91\xe9\x74\xe0\x0b\xb8\xad\xca\xd3\xf1\xf7\x32\x43\x79\xf2\x0b\x35\x0b\xaa\xd2\x84\xa6\x56\x5d\x04\x74\xd6\x2c\xea\x6c\x88\xfa\x53\xc2\x24\xd2\x56\xd1\x3f\x44\x85\x10\x8b\x11\xf2\x4f\x49\xad\x13\x2f\x09\xd9\x2e\x54\x16\xe8\x33\x7f\xd5\xd2\x98\xd0\x51\x30\xd0\x0d\xcb\x7a\x96\x58\xad\xb6\x91\x78\x0d\x55\x2a\x24\x09\xe9\x3c\xba\x8e\x50\x35\xe7\x2b\x50\xe5\x01\x2c\x0a\x6b\xa8\xac\xd5\xff\x12\x1d\xc5\x88\x2f\x41\xda\x84\x17\xc7\xb8\xdb\xde\x7e\xf2\x3a\xe9\x24\xe1\xae\xf9\xb1\xa8\xaa\xab\xb2\xcc\xd1\x13\xd9\xa7\x40\x4a\xeb\x08\xfb\x39\xf2\x74\x5e\x42\xd5\x88\xac\x98\xd5\x3c\xf6\xa3\xc1\x0a\x63\xdc\x8b\xaa\xbe\x05\x79\xaa\x9a\xba\x11\xfb\x7a\x5f\x9d\x3a\x40\x81\x82\x44\x60\xf5\xdb\xe1\xe3\xbc\xdb\xd0\xca\xe5\xf0\x93\x07\x03\x8a\x45\xdd\x5e\x7b\xd3\x86\xaf\xfa\x29\xb7\x11\x74\x67\x6c\x63\xf9\x2a\xfe\xfc\x86\x71\xac\x38\x3c\xaf\x57\x9b\xc5\xfd\xaa\xfb\xb3\x4e\xb1\x60\xbe\x7e\x7a\x79\xbc\xde\xd1\x9d\x3b\xbc\x43\x85\x81\x6e\x90\x49\x0d\xeb\xa5\x27\xda\xdb\x31\x7e\x7c\x3a\x08\xac\xa1\x5d\xbb\x7a\xab\x72\x40\xbc\xf5\xc7\x09\x24\x28\x71\x5a\xa1\x3d\xe4\x7c\xce\xa9\x83\x58\xc5\xae\x10\xfd\xa3\xac\x72\x3d\x96\x38\x6c\x8f\x43\xd2\x69\xba\xf6\x12\x7f\xfe\xa8\x52\xd2\x95\xe7\xbf\xb7\x09\xa4\x07\x40\x3c\x43\xd5\x09\x16\x52\x1d\x80\x35\x58\xae\x44\x65\x67\xd9\x30\xc6\xd2\x84\x98\x88\xf9\x28\x30\xb7\x34\xbf\xf1\x2f\x25\xa1\x44\xa0\xa4\x2f\xe9\x6f\x9a\x93\xce\xca\xba\x3b\x01\x8d\x43\xd7\xe8\x6d\x37\x92\x31\x5d\x4b\x13\x9e\x98\xd8\xf7\xd4\x0a\x3d\xf2\xae\x9e\xeb\x67\x68\xa2\x28\xee\x34\x27\xd4\x0b\xb1\x12\x12\xfe\x90\x8e\x51\xa1\xf2\x79\xb5\xbe\x7b\xf2\x41\x9a\x8e\x08\x45\xd8\x49\x86\x44\xa5\xac\x70\x7b\xe3\xf8\x37\x44\x8a\x60\x06\xbc\xfc\xd7\x3d\x26\xe6\x43\xdd\x6a\xaa\x23\xb0\xb8\x98\x5e\xb7\x53\xaf\xba\xd4\x55\xd3\x80\xa7\xd4\x13\x0f\xe0\x90\x4d\xad\x59\xa9\xa6\x3c\x44\xba\xb4\xbd\xe6\x76\xc5\x8b\xba\x0f\xa7\xb6\xd0\xb3\xc6\x1c\x56\x0f\x00\xf9\x93\x73\x30\x12\xa0\x25\x34\xa2\x76\xac\x42\xd0\x68\x6d\xd1\x3c\xb0\xf2\x40\x47\x54\x52\x75\x96\x56\x5f\xa2\x59\x34\x67\xb1\x52\x1d\x6b\xcd\x6e\xf1\xcd\x37\xa8\xca\xcf\x25\x00\xa9\xe6\xd2\x4a\x31\x5c\x9d\xce\x37\x65\xf5\xed\x8f\xdb\xb9\x8c\xe6\x6f\x55\x8a\x35\xd7\xd4\x27\x0d\xcf\x42\xbd\x89\x3d\xf4\xea\xcc\x7e\x71\xd3\x09\xe1\xc8\xc7\x2d\xca\xaa\x79\x15\xfa\x3d\xab\xbd\xdf\x04\xd5\x09\xe3\xa8\x6d\xa0\x41\x9f\x50\x10\xc3\x1f\x48\xc3\x18\x6b\xba\x28\xc5\xe1\xd6\x4c\x7f\x48\x29\xd4\xbc\x3d\xa2\x15\xc2\x75\x56\x1f\xa1\xaa\xbb\x38\x48\x0b\x1a\x78\xf7\xbc\x2b\xa1\xaf\xa0\x99\x6c\x4e\x5a\x50\xbb\x39\x3d\xfd\xb0\x9a\xb5\x8b\x4a\x76\x9f\xe5\xdc\x86\x01\x56\xc1\xde\x4b\xb9\x5d\x9c\x41\x5b\x49\xea\xe2\x74\x70\xda\x3f\x6d\x52\x05\x75\xb7\x34\x69\x61\x0c\xf1\x58\xec\xd1\x63\xe8\xee\x8a\x24\xb6\xf6\x61\xc5\x51\x97\xa2\xd0\x48\x40\xa9\x27\x56\x52\x7e\xb4\xe1\xc8\xae\x90\xa7\xf3\xc2\xb6\xad\xdb\xa8\x7b\xea\x6c\xe8\x06\xab\x48\xe3\x53\x39\x15\xf2\x54\xe8\x4f\x7c\xaf\xa9\x06\x4e\x11\x4b\xbf\x11\x95\x67\x8e\x6b\x30\x04\xed\xea\xbc\x75\x43\x87\xa0\xf5\xbf\x0c\x02\x26\x93\xb4\x57\x98\xd5\x9b\xd7\xec\xd8\x1f\x14\x22\xf2\xe0\xa4\xa5\xc8\xf3\x2b\x31\x5d\xe6\x21\x90\x96\xbe\x72\xc8\x8a\xcd\xe9\x60\x21\x82\x7b\x60\x3d\x1a\x0f\x48\x6a\x22\x57\x39\xbc\x82\xba\xb9\x6d\x23\xeb\x0d\xa2\x76\x30\x7d\xda\x42\xd1\x88\x36\xba\x77\xea\x2a\xf6\x21\x0e\xed\x08\x10\xb2\xe8\x4f\x26\xe2\xc4\x36\x70\xab\x0a\x54\xe3\xd1\x0e\xed\x42\x76\xb5\x5d\xfe\x5c\x6d\xbf\x4d\xae\x2f\x4c\xac\xc1\x38\xa2\xe8\xb7\x65\x55\x16\x4d\xb9\x1e\x94\x7e\x21\x0a\x63\x04\xa3\x3c\x88\xbf\xee\xb3\xba\x79\x2c\x9b\xef\x1d\x1c\x04\x22\xa1\x91\x9d\xb6\xf3\xd6\x93\x18\x9e\xf5\x5a\xe4\x7e\x98\xa2\x89\x2b\x37\x8e\xd8\x87\x64\x5a\x02\x71\xe3\x59\xa0\xb0\xb8\x36\x58\xbf\xe8\x78\x79\x01\x46\xac\x33\x53\x2d\xba\xee\x35\x30\x0e\x41\x67\x73\x58\xb5\xbf\xdc\x02\xbd\xfa\xd6\xe0\x20\xf7\x03\x9e\xb0\xc0\x95\x4b\x6c\x6a\x18\xb8\x44\xf4\x1f\x33\xe9\xe9\xf8\x9f\xfe\xf6\x71\xe7\x0b\xb8\x5a\x2f\xe3\x90\x60\x11\x70\x18\xbc\x03\x37\x69\x28\xed\xe2\xb3\xad\xca\xf2\x93\x14\x13\x62\x03\x48\x7a\x3b\xda\xd7\x0b\x7b\x19\x59\xb7\x04\x40\x42\x42\x04\x92\xee\x2c\xcd\xc2\x4a\x42\xb4\xd1\xda\x5d\xd1\x46\x4d\xf3\x13\x1e\x12\x15\xe0\xa7\x10\x6d\xff\x64\x7e\x80\x78\xbb\xe9\x13\x04\x48\x43\x13\x06\x5e\xec\xd0\xf1\x58\xc1\x09\xda\xc0\x50\x3f\x00\x52\xa1\x88\x5b\x62\xdc\x6e\x68\xf1\x64\x23\x36\xb9\x1b\xab\x64\x82\x6c\x77\xe1\xf8\x2a\xf5\x20\x82\xbd\x29\xe7\x43\x47\xd0\x11\xc7\xdd\xac\xa3\xc6\x5e\x83\x12\x67\xd0\xd3\xa6\xf2\xe4\x53\x31\xa8\xa8\x97\xb6\xb4\x77\xe5\x93\x1b\xac\x13\x69\x92\x89\x6a\x45\x47\x0c\x18\xeb\x6a\xb9\x4f\x00\x35\x18\xa9\x6c\xca\xe6\xcd\xe7\x0a\x00\x4a\xda\xae\xfd\xee\xf8\xe1\x03\x72\x30\x86\x63\x26\x6a\xd5\x5e\x73\x31\x8a\x69\x0c\xa1\x12\x67\x80\xb5\xc4\xaf\xaf\x50\xda\xe0\x37\x7f\x90\x45\xc4\xfa\x84\x7b\x67\x9f\x6f\x33\xe0\x26\x3f\x38\x21\xa8\xc2\x03\xcd\xeb\xb6\x7c\xa9\xf5\xf0\xe5\xf6\x27\x0c\x03\x81\xad\x11\xcb\x01\xce\xca\xe2\xe9\xd8\x4d\x46\x13\xc6\x21\x66\x3a\xdb\xa7\xe7\xbf\xc9\x25\x35\xa1\x94\xde\xdd\x14\xe7\x5b\x17\xbc\x98\x50\xdb\x48\xcf\x89\xc2\x7d\xb2\x77\x98\x10\x12\xe9\x61\x73\xf0\xc9\x93\x34\x11\x0f\xb1\xce\x66\x4e\x90\x4f\x30\xe3\x26\x92\x94\x45\xbd\x7d\x46\x9b\x5e\x0d\xf2\x50\x43\x03\x85\xca\xa5\xfd\x1f\x12\x08\x12\xbb\x5d\xfe\x05\xaa\xb9\x71\xae\x82\xbe\x1b\xd9\x0d\x03\x6b\x83\x2f\xb4\x5e\xe8\x43\x56\x5c\xc0\x7e\xfc\x5e\x64\x98\x08\x89\xe8\x3d\x8b\x3a\x93\x2c\x2b\xca\xd3\x0d\xb2\x0d\x95\x01\x74\xe7\xa9\x87\x55\x1b\x26\x53\x24\x4b\x78\xeb\x97\x8e\x29\x19\x75\x23\x74\x98\x84\xde\x10\xe5\xd0\x3b\xb3\xba\xc3\x9c\x73\xe4\x17\x28\x71\x1c\xae\x2f\x86\x0b\xc1\x78\xa7\x3f\xd2\x06\x59\xce\xed\x7f\x58\xe6\x32\x49\x00\xd2\x6d\x62\xcf\xd9\x4f\x98\x50\xbf\x4d\x12\x5a\x89\xee\x0a\x84\x46\xe5\x94\xe2\x3c\x84\x20\x98\x94\x5a\x7a\xf2\xae\xef\x2c\xbb\x0e\xcf\xb3\xa8\xac\xdf\xed\xe7\x19\xf8\x4c\xd5\xd6\x9f\x96\x85\xa9\xea\x42\x49\x4b\xb4\x9c\xcf\x9c\x4d\xca\x35\x82\xff\x76\xdd\x0a\x31\x6a\x8c\x4f\x5e\x94\x54\x5a\xa8\xe6\x5b\x96\xe7\x93\xfb\x28\xb4\x12\x16\x79\x9d\x8b\xf3\x03\x34\x62\xfb\xd3\xbd\xfd\x9f\x59\x0b\x0e\xaf\x58\x05\x11\xa5\x7e\x21\xb4\xe9\xf6\xd5\x79\x39\x31\x18\xa2\x46\x45\x10\xf5\x95\xd2\x8d\x7a\x05\x7d\x9a\xf1\x17\xf9\x32\xd6\x34\xca\xa4\x91\xf5\x98\x7e\x07\x91\x5f\x5d\xaa\x1b\x3b\xd5\xe2\xd1\xcf\x83\x28\x40\xf6\xc6\xcc\x6c\x9e\x9c\xde\x50\x13\x69\x6f\xf6\x60\x95\xf8\xba\x5f\xdc\x9e\x77\x3c\x38\x89\x31\x25\xd9\xb9\x97\x7d\x18\x41\xcf\xbf\xd1\x46\x80\x82\x39\xc9\x99\x36\x86\xb8\x14\x01\xbe\xec\xd2\x75\xaf\x9f\x31\xd6\x5b\xef\x90\x15\xbb\xf7\x7e\x57\x62\x41\x10\x50\xac\x40\xed\x33\xd3\x55\x47\x58\x10\xb4\x19\x57\x6f\xb0\xfc\x5c\x36\x9b\x63\xee\x9b\x32\x2c\x08\x94\xc2\xd5\xa1\x29\xaf\x44\x0d\x2c\x19\x2c\xd5\x2c\x20\xdc\x76\xbb\xfe\xc8\xf2\x3c\x2b\xf6\x58\xa2\x9f\x87\x78\x0e\x7f\x2c\x0b\x88\xb6\x95\x8f\xf6\x2e\xe6\x65\xd9\x7d\x59\x24\x42\x69\xfb\xd4\x0d\xec\xcb\xea\x7c\xd7\x5d\x65\x64\x14\x06\xed\xae\xd0\xde\x73\x51\x58\x40\x03\xdb\x06\x70\x8d\xef\x0d\x60\x91\xfd\xfb\xd0\xf8\x7a\xfc\xed\x94\xda\x52\xe6\xd5\x62\xfb\xd4\x9d\x84\x87\x24\xf5\x90\x96\x2c\x1f\x12\x75\x58\x40\x85\xc6\xb5\xe4\xfe\xe9\x76\x77\x05\xcd\x1c\x57\x6d\x0a\xab\x75\x9f\x64\xc2\x3a\x10\xb4\x9f\x74\x06\x18\x73\xa1\x07\x0b\x98\xe2\x56\x6f\xc0\x66\xe0\x13\x9e\xf3\xfc\x67\x62\x13\x63\x75\x6c\x57\x43\x83\x05\x93\xe1\x56\xe8\xc6\x24\x01\xc7\xc0\x30\x3b\x1c\x73\x5b\x80\x5d\xc3\x7f\xea\xdf\xc6\x57\x99\x08\x2d\xad\xd2\x1c\x96\xb7\x7b\xb7\x67\x16\xa4\x91\x41\xbc\xfd\x37\x51\x3f\x96\x83\x1a\x3d\x0b\x52\x66\xe5\x8b\xac\xec\xe1\x0f\xab\x7f\x77\x53\x56\x4f\xc7\x63\x59\x74\xcc\x52\x16\xa4\xd2\x7a\x9a\xb5\xfb\x6a\x9b\xcc\xdf\x08\xd5\x94\x1e\x06\xc0\x82\x54\x05\xbe\x2a\xdd\x6e\x16\xab\xe6\xf5\xfb\x70\xce\x8a\x20\x49\x2d\x53\x04\xfe\x5d\x1e\x64\x06\xd7\x85\x98\xfc\x44\x91\xa4\x38\x35\x1e\xce\x5f\x00\x06\x06\x7d\x07\x16\x48\x93\x28\xe9\x79\xec\xe2\x0d\xac\x58\x8f\xc3\x3f\x8a\x4b\x9b\x5a\x16\xa8\xd8\xbe\xcf\x59\x91\x35\x56\xc6\x36\x2c\x4d\xe4\x2f\x52\x87\x12\x57\x1e\xf7\x0a\xd9\x87\xb7\xee\x9c\x67\xdd\x28\xa0\x14\x37\xf6\xd5\xbf\x96\xdf\x16\x8f\xb7\xab\xfe\xef\x1c\x43\x9a\x0a\x50\x4e\x6c\x2c\x34\xe5\xc7\x48\x6b\x87\xf7\x07\x9c\x2f\xd5\x19\xc6\xb3\xdb\x84\x89\x87\x43\x0d\x31\x11\xbb\xe2\x74\xd8\x95\x66\x77\xaa\x27\x84\x08\x7f\x53\x8c\x48\x31\xba\x7f\x87\xca\x42\x9a\xfc\xf5\x19\x13\xe2\x75\xbf\x66\x5a\x63\x7f\x6b\x5b\x65\xfb\x7d\xaf\xbf\xc5\x48\xc0\x88\xa6\x3d\xb2\x10\xeb\x8d\x23\x32\xfc\x30\x44\x62\x24\xd0\xca\x7b\x98\xde\xa9\x72\x0a\x5a\x1c\xfd\x70\x12\x00\xc5\x84\x1b\x9a\xd7\x27\xf3\x87\x17\xdd\x64\x24\x30\x40\xad\xc3\xcc\xc7\x1d\xa6\x98\xfe\x00\xe1\x22\x8d\x3c\x5c\xf3\xe9\xe3\x13\xaa\x32\x23\x61\xa0\x22\xab\xb4\x50\x5c\x81\x15\x0e\xf7\xa7\x08\x19\xc5\x53\x94\xd5\x5e\x14\xd9\x7f\xc1\x9b\x78\x30\x12\x26\x06\x85\x9c\xdf\x33\xf8\x88\x92\xee\xaf\x90\x58\x6c\xc8\xbe\x59\x34\x85\xa3\xf2\xf5\x67\x33\x29\xb2\x92\xb7\x9b\x9b\xbb\xc7\xc5\xbd\xff\x73\x14\x11\x4c\x93\x45\x81\x26\xd7\x58\xc6\x0c\xfd\x41\xca\xac\xff\xae\x12\xc5\x58\xd0\x98\x11\x1a\x6b\xee\x77\x54\x4b\xf0\x5a\x96\x65\xa5\xc7\x09\x02\x23\x8c\x87\xc8\x66\xd9\x79\x5d\x20\xff\x79\x1e\x68\xee\xd8\x79\x37\x15\xb4\x41\x44\x77\x84\x52\xea\x05\x02\x77\xf5\x09\x71\x42\xe3\x85\x82\x70\x05\x28\x3e\x75\x40\x6f\xde\xf6\x71\x7c\xb5\x25\xb7\xe3\x0d\x42\xf9\x1f\x84\x73\x82\xeb\xc2\x54\x46\x62\xc6\x10\xac\xab\x9c\xe2\x12\xd8\xba\xd9\x6f\x23\x57\x81\xf1\xe9\x62\x66\xfd\xcf\xee\x96\x4f\xd6\x00\xe3\xe6\x6e\xbd\xd9\xfa\x13\x26\x22\x46\xa8\x72\x73\xe8\x26\x43\x1a\x13\xec\xda\x59\xd4\xad\x45\x27\x75\xe0\x66\x46\xd2\x94\x7b\x4d\x05\xfb\x52\x77\x37\x7b\x7c\x33\x53\x15\x0c\x90\x2f\x0b\xad\x31\x82\x13\xf9\xca\x35\x74\x67\xa3\xaa\xf6\x63\x06\x19\xb9\x95\x68\x2c\x6a\x17\xaa\x9d\xbf\x32\x21\x00\x15\x7d\xda\xbd\xbe\x71\x52\xff\xe3\x77\x9e\x08\x69\x90\x6c\x74\xb5\xbc\x42\xbd\x8c\xcf\xb1\x0f\x8c\x08\x15\xa1\x0c\xa9\xd3\xb4\x58\x54\x4d\x56\x37\xf7\xd8\xa3\xfd\xb4\x81\xc6\x88\xd0\x14\x63\xe1\xbb\xda\xa9\xed\x78\x35\x11\x77\x5c\x6a\xc1\xac\xce\x4f\x67\x88\xb2\x46\x72\xfd\x27\xe7\x93\x40\x10\x23\x93\x15\x66\x68\xd2\xc1\x88\x8a\x74\xe8\x1c\x21\xee\x0e\x87\xb2\x6a\x44\xde\x4d\x48\xd5\x06\xab\x9e\x27\xae\x61\xd3\x66\xf1\xe3\xdb\xaf\x69\x88\x28\x2f\x75\xaa\x9b\xf2\xf0\x0c\x7a\x20\x85\x33\x5c\x65\xfc\xf0\x34\x02\xd9\x43\xf2\x1f\xe1\x63\x84\xe8\xf4\xa3\x8c\x40\x68\xa6\x3c\x9d\x87\xa5\x60\x46\x4c\x62\x5d\x83\xdb\xeb\xa9\x94\x9f\x11\x9e\x4c\x69\x07\x85\x81\xb4\x52\x03\xbe\x22\x7e\x53\x56\x90\xed\x27\x20\xf7\xc1\x45\x85\x81\x8a\xc1\x15\x42\x7f\x00\xbc\xe5\x67\xeb\x1b\xe7\xcf\x47\x62\x85\x54\x20\x2c\x4d\x77\x8d\x90\xb1\x71\xba\x1f\xaa\x48\xd0\x39\x78\xf6\xe4\x34\x16\x12\x1d\x59\x81\x48\x75\x1c\x9b\x9c\xb0\x30\x8c\xa3\x54\x0c\x20\xd1\xbb\xa2\xd4\x23\x13\x64\x16\x46\x41\x84\x8c\xeb\xbe\x35\x79\x41\xfc\xf9\x0a\x4c\xc3\xc2\x28\x94\xce\x8c\xd3\x7e\xc7\x4b\x0d\xd5\xc4\x30\x65\x50\xdf\x64\x61\xa4\x09\x72\x23\xbe\x43\x55\x88\x43\xc7\x30\x1e\x24\x6b\x2c\xa4\x31\x49\x53\x97\x67\x3d\xb7\x29\xe2\x05\x04\x83\x85\x54\x48\xd5\xc1\x30\xdd\xa3\x1c\xad\x5a\x21\x0b\x19\x2e\x79\x57\x79\xf9\xb3\x2a\xbd\xd2\x99\xff\x0e\x26\x24\x8a\xda\xb4\xe1\xb2\xe3\xcf\xed\x4c\x59\xed\xe4\x60\xd5\x0c\x79\x62\x04\x8a\x56\x59\x7a\xca\x18\xcc\xc9\xc2\x58\x06\x9e\x96\x8c\x72\x23\x27\x75\x81\x8d\x61\x61\x42\x24\x2e\x07\x47\x97\xee\x3e\x9c\xdb\xdb\x94\x95\xa7\x7a\x75\x90\x79\xb7\x0e\x87\x69\x18\x89\x0e\xac\x7d\x38\x36\xb0\x23\x64\xfc\xac\xd2\x54\xe1\xd7\xed\xb3\x36\x0b\x14\xdd\xac\x14\x91\xc6\x9f\xd2\x46\x29\x4b\x71\xec\xae\x5e\x50\x1e\x3b\x71\xd4\xdb\x32\xd7\x93\xb6\xcb\x3f\xc6\x2e\x88\xd3\xbf\xf6\x73\x58\x30\xab\x53\x23\x4f\x55\xf1\x52\xd4\x9d\x6c\x11\x0b\x05\x17\xe8\x35\x21\x30\x02\xef\xa8\xd5\x37\x70\xe1\x4f\xc0\x42\x01\x91\x51\x43\x1c\x60\x2e\x7c\x97\x67\x7c\xbf\x64\x1a\x32\xdd\x91\x43\xca\xca\x3a\x1b\xfb\xd3\x48\xc9\x65\x3a\x12\xab\xfa\x45\x3e\xed\x3e\xa7\x02\x15\x39\x2c\xc5\xb3\x38\x3f\x21\xd8\x52\x41\xd1\x88\xfd\x50\x94\x87\x85\x8a\x58\xb4\x63\x97\x3f\x6f\xa0\x47\x34\x4f\x92\x43\x16\x2a\x6e\xfb\x1c\x16\x49\x76\x57\xd4\xa7\x0a\xeb\x70\x53\xea\xc1\xb8\x32\x3a\x9e\xa6\x5a\x46\xf8\x8b\xec\x12\x6e\x01\x59\x17\x3f\x6a\xf0\x38\x20\xd0\xca\x61\x9a\xb0\xed\xd6\x4c\x5e\x0c\xa3\xb5\xf4\x09\xab\x5f\x51\xe6\x77\xaa\x88\xd0\x04\x93\x7c\x17\xc0\xda\x36\xaa\xf7\x20\x40\xd6\x69\x39\x0c\x22\x22\x92\x46\x78\x13\x8f\x55\x79\x28\x97\x6d\xd2\x9e\x95\xc5\x00\xcb\xc7\x22\x22\x12\xec\xb1\x66\xaa\xdc\x34\xa5\xdf\x90\xa3\x30\xb0\xf2\x9d\xd6\x7b\x6e\x6c\x23\x3c\x0e\xd0\xa2\x30\x50\xa8\xf8\x8a\x75\xf6\x30\xdc\xd9\x3d\xfc\x56\xd4\x2f\xb5\xd8\x03\x09\x02\x94\x37\xea\x2e\x29\x04\xaa\x5c\x71\xfa\xa1\xd4\x33\xd6\xdb\x2c\x8a\x12\x8a\xa9\x6c\x1b\x0a\xa3\x4c\xf3\x24\xca\x8e\x22\xc7\x8e\x77\xda\xd6\xa0\x37\x4d\x75\x52\x08\x50\xd8\x96\x28\xd4\xff\xe5\xdc\x8a\xa8\x64\x32\x76\x9a\xc1\x9d\x62\xac\x3b\xc6\x42\x83\x88\x8e\x87\xd3\xc3\xe9\x57\xc0\x66\x16\x31\x4e\x41\x0c\x91\x41\x65\xcf\x95\xee\x3d\x75\xe6\xca\x00\xfe\x04\x92\x61\xa9\xf7\x55\xd4\xaf\xab\x9f\x59\xdd\x4c\x42\xb9\x88\xa9\x18\x75\x83\x0e\xe2\x0d\x9e\x72\x7d\x73\x52\x6f\x23\xb9\x17\x16\x71\xca\xb0\x84\x64\x55\xe0\xb1\x8e\x21\xf2\x9b\x12\x25\x17\xee\x85\x9c\xdc\x3b\xae\x6c\xa3\xce\x2a\xd1\xce\xb0\xbd\x58\xc4\x8d\xe0\x1e\x13\x7f\x5b\x09\x05\x43\x10\x1e\x8b\x62\x9a\xe0\x9e\x7a\x2b\x8a\x21\xd7\x95\x45\x71\x6c\x99\xd9\xcd\xc4\xb9\xf3\x53\x3c\xe4\xd8\xf5\x94\x45\xb1\x61\xd2\xbd\xf3\x4d\x0e\x57\x03\x22\xdd\xf8\x9e\x24\xa9\xf5\x8d\x69\xf0\x81\x5f\xc1\xb0\xf4\xcc\xa2\x44\x31\x70\x42\x48\x3f\xca\xea\x0d\xaa\xe7\x01\x26\x60\x32\x79\x13\x05\x56\x6d\xe4\x24\x31\xe8\xbd\x16\xd5\x5b\xbb\xe7\x4e\xd9\x16\x2c\x4a\xb4\x95\x62\x16\x5a\x2f\x2a\x99\x4d\x89\x2f\x2c\x4a\x95\x66\xcc\xbb\x69\x0d\x56\xc0\x48\x08\x49\xd5\x40\xe4\xb6\x7a\xcf\x14\x4c\x56\xb3\xfe\x7b\x64\x20\x10\x43\x66\x51\x26\x3f\xfd\x49\x24\x31\xa8\x7a\x61\xb2\x42\xaf\x45\xf1\x76\x75\x1e\x61\x62\xbe\x2c\xb9\xb1\x48\x46\x56\x7c\x0a\x09\x60\xdb\x0a\x7e\xa9\x18\xe8\x3e\xa7\x62\x22\x5d\x7b\xeb\x3e\x33\x0e\xe3\xf8\x29\xc1\xb7\x1d\x1f\x52\xf7\x00\x77\xed\x3e\xad\x3e\xf3\x73\x63\x91\x36\xda\x57\x6e\xb7\x20\x0e\x3d\x83\x85\x45\x90\x6a\xc7\x80\x75\x00\xd7\xe1\x59\xfc\x18\x41\x62\xdf\x58\xb9\xca\x0a\x0d\xfa\x2a\xcf\x0a\xfd\x4d\xd4\xaf\xd1\x9c\xc4\x31\x7e\x42\x5a\xda\xec\x31\x17\x0a\x93\xa2\xf9\x39\x01\x32\xf2\x7c\x28\xdb\xad\xac\xb7\xe5\xd2\xb5\x51\xed\x84\x24\x9f\xab\xcf\x8d\x7f\xa4\xa1\x1d\xf4\x64\x60\x03\x1a\x8e\xa2\x84\xc8\x18\x89\x71\x04\x22\xd6\x76\xed\x32\xda\xc9\x08\x33\x1a\x84\xb6\x15\x64\x33\xb9\xaa\x23\xae\x77\xc7\xa3\x40\x33\x27\xcf\x54\xe9\xc7\xaa\xfb\x3b\x0b\x50\x69\xc0\x25\x1a\xb6\x5e\x64\x56\x3f\x8f\x59\x5f\x0f\x40\x0d\x6c\x0b\x79\x50\x90\x1d\xbf\xe6\x05\x33\x4a\x62\x5b\xaf\x44\xf0\xed\xf7\xd5\x66\x7b\xf7\x78\x3b\x32\x1a\x61\x94\x88\x18\xc1\x44\x1b\x14\xb6\x44\xbf\xe0\xdf\x46\xe5\xe6\xc9\x16\x7b\xf9\x25\x51\x68\x94\xf2\xc8\x38\xfc\xc9\x8b\xfd\xd4\xf4\x84\xd1\x28\x0d\xf0\x6d\x40\x1f\xdc\x51\x50\x31\x39\x9b\xa6\x92\x7a\x29\xc7\x36\x8a\x1b\x07\xba\x6e\x14\x8d\x02\xe5\xb2\xf8\x4d\xb6\xf7\x53\x8c\x52\x0a\x58\x4b\x92\x08\xe0\x5a\x96\x65\x4f\x51\x60\x94\x72\x8a\x32\xc3\xb6\xeb\xbf\x2e\xcb\xc3\xd5\xd9\xf6\x4d\xc6\x57\x40\xa5\x41\xa4\x9f\xb7\x46\x1f\x08\x34\x31\xda\x86\xbc\x0a\xf7\x21\x64\x24\x9e\xbb\xbf\x6b\x8d\x98\xa6\x2e\xa6\xe9\xf0\x3e\x7e\x80\x09\x85\xad\xe9\x55\xba\xde\xc9\xfc\x34\x59\x45\x68\x2c\x62\x44\x37\x36\xa7\xaa\x78\x32\x66\xf2\x83\x63\x01\x58\x27\xad\x8f\xe2\xa3\xfb\xb9\xb1\x8c\x9d\xb6\xc8\xe1\x90\x35\x0d\x40\x3d\x35\x66\x61\x34\x21\x16\x55\x8c\x05\x46\x38\x78\x93\xe6\xb2\xba\xb4\x25\xff\x9b\xff\x76\x27\xb6\x76\xac\x30\xe8\xfc\xd9\x07\xef\x07\x44\x26\xec\x0d\xeb\x5d\x2d\xea\xf7\xf2\x6d\xba\x0c\xd3\x44\x71\xd4\x67\x19\x54\xf2\x89\x3f\x49\x1a\xa7\xb6\x35\xe0\x1a\x17\xc8\xe4\xb0\x02\x15\x63\xad\xb6\xd1\xbf\xc9\x64\x52\xa5\xd2\x56\x99\xff\x25\xde\xb3\x36\xff\xea\x77\x40\x9a\x2a\x8e\xf0\xa2\xae\x9f\xe4\x83\x82\x4f\xe6\xa7\x88\x53\x84\x9e\xdd\x97\xfb\x5b\x68\xbc\xb6\xd6\xf4\x35\x1c\xae\x16\x54\x12\x92\x38\x26\xb1\x6e\x40\x1c\x10\x4e\xd6\xde\x0f\x3a\xb9\x11\x92\x9a\xae\x35\x56\x65\x28\x53\x33\xfe\x72\x09\xe0\x59\x0d\xcb\xe5\x37\xa7\x59\x15\xf8\x9f\xa2\x62\x82\xd9\xf9\x07\x64\xfb\xd7\x06\xf4\xf7\xb2\x01\xdc\x72\xea\x8b\x13\x29\x11\x7b\x8b\x08\x2f\x40\xff\xc7\x74\x88\xa6\x98\x92\xd8\xd5\xe8\x26\x6f\xcf\xf9\x85\x0c\x18\xa3\x9a\x87\x51\x32\xa9\xb3\x4f\xce\x09\xb1\xc0\x3a\x58\x2d\x0a\x74\xf2\x18\xad\xaa\x14\x64\x12\x3a\x83\xa3\x01\xa2\xc4\x11\xb7\xfc\x8f\x04\xc3\xb0\xed\x25\x4f\x67\x2c\x30\xb7\x21\x74\xbb\xf1\x22\x92\x74\xb6\x6c\x4b\x4d\x48\x45\xea\x97\x94\xe3\x31\x2b\xf6\xbd\x72\xf3\xec\xdc\x66\x41\x18\xe3\x27\x0e\xe2\xe7\x43\x56\x9c\x1a\xa8\x9d\xcc\xca\x28\xac\x62\x01\xf0\x88\x7a\x06\x7f\x23\x9c\x9b\xfc\x01\x8a\xa6\x46\xea\x75\x37\x90\xa8\x28\x8e\x06\x03\xd7\x70\x3c\x59\x13\xf5\xb9\xac\x9a\x85\x21\x24\xa9\x87\x28\x8f\xa5\xea\xc6\xf7\x9c\x45\x84\xe3\x43\xc2\xd0\x43\x74\x1a\xc7\x8c\x45\x32\xb6\xfa\x65\x08\xa6\x1d\xe0\x1e\x5e\x8a\xcc\x43\xa5\x18\xa3\x2c\x45\x96\xee\x4b\x0d\xd5\x8e\xf5\x7f\xb5\xfa\xc8\x98\x6a\x5a\x74\x45\x77\xc8\x24\x76\x8a\xf9\xda\x4d\x9e\xff\x80\x6c\x3c\x8d\x59\xfb\x9c\x47\x0c\xde\xdf\x85\x7a\x3b\x96\x9f\xfd\x06\x96\x30\xde\x09\xa3\xcc\x97\x09\x19\x27\x09\x42\x89\x2c\x33\xbd\x86\x5e\xf6\x92\x31\x1e\x69\xac\x52\x5c\x65\x79\x6e\xb1\x7d\xdd\x11\x26\x84\x55\xad\xd4\xe8\x4a\x7a\x19\xd3\x30\x9e\x70\xe2\x22\xcf\x5d\xf3\xb9\x09\x0d\x63\x5c\x24\x88\x8f\xcc\x0a\x65\x21\x71\x96\x05\xe1\xe4\xd6\x67\xe0\xce\x8c\x71\x63\x70\x45\x7f\x84\x8f\xab\x4c\x7f\xa9\x54\xcd\x58\x4c\xe3\x44\x74\xaa\xe1\x13\x92\x95\x1f\x23\x88\xd7\x7d\x5c\xc3\x31\x3f\x8f\x90\x9e\x7e\x8c\x4a\xb1\x9c\x52\xe7\xe2\x1d\xec\xde\xd9\x23\x6a\xba\xe7\x98\x10\x8e\xf9\x82\xc8\xaa\xeb\x81\x13\xaa\x53\xf8\x98\xc9\x81\xfc\xe7\x28\xc3\x5a\x9b\x55\x4b\x1f\xd9\x85\x32\x96\xf0\x18\xa3\xf8\xdd\xbe\xcc\xf5\x4b\xe1\x90\x83\xe3\x9f\x99\x08\x16\x58\xfb\x80\x62\x0f\xef\x59\x73\xee\xf3\xe7\xf9\xfb\x92\x68\x02\xbd\xd0\xe7\xfa\x33\x35\x57\xc6\x12\x13\x39\x57\x99\xde\x64\x02\x89\x41\xcd\x9c\xb9\xdd\xf8\xb3\x29\xb5\x4a\x73\x47\x71\xfe\x9e\xd5\xf3\x56\xfe\x8c\xa5\x32\xc0\x20\xb7\xab\x4c\x56\xe5\xa1\x6b\x45\xcd\xf5\x96\x98\x88\x35\x06\xd7\x4e\x65\x2a\x83\xca\xcb\x69\xfb\x01\x3a\x8c\x3d\xde\x2e\xcf\x2c\x9c\x62\x04\xf2\x65\x4c\x06\x56\xaf\x4e\x66\xee\x3b\x9e\xa1\x1a\x76\x0b\x99\xd2\x56\x32\xbe\x86\x66\xf5\xb3\xa9\xc4\xd5\xc4\xc6\x70\x7c\x49\xca\x98\xd0\x0b\x82\xef\x9a\x8f\x12\xa9\xd7\xab\xff\x5c\xb5\x93\xc8\x9f\x51\x8b\x04\xe9\x7e\x16\x33\xb0\xf3\xc4\xf6\xaa\xf4\x1a\x6c\x8c\x41\x44\x4c\x6f\xba\xea\x74\x1d\x27\x71\xa3\x1b\x6a\x54\x84\xd5\x86\x97\xc2\xd7\x2f\xef\xc7\x60\x80\x3e\x9d\xe4\x81\xb4\xd0\x12\xab\x83\x67\x97\x2d\xd5\x04\x3f\x9d\xfc\xf7\x88\xee\xed\x2f\x97\x07\x8a\x6a\xf0\xc2\xdd\xae\x15\xec\x0f\x69\xe6\x11\x93\xed\x1a\x37\x76\x3c\x1f\xbd\x5c\x9c\x68\x86\x81\xc0\x53\xb5\x3f\x55\x62\x32\xb7\x79\x18\x0a\xcc\x25\x57\xa7\xaa\xbc\x2d\x73\x3d\xf4\xaa\x75\x43\x22\x19\x33\xed\x01\x19\x87\xac\xf0\xba\xfd\xee\x30\x65\x9c\xc0\x8c\x76\x86\x7f\xb7\x38\x4d\x29\x56\xc7\x3d\xfa\xca\x6a\x4c\xfb\x37\x30\x21\x7e\x1c\x8b\x62\xec\x67\x67\xf5\x6a\x81\x1c\x08\x3d\x2a\x2e\x70\xae\x03\x1f\x41\x0f\x4c\x48\xbb\x89\xea\x34\x3f\xc6\xaf\xba\xfb\x68\x4c\x15\x4f\x7c\xe5\xef\xf6\xf1\x69\xf2\x0b\x63\x06\xc8\x0a\x92\x65\xf9\xf6\x06\x70\xf4\x20\xe9\x64\x2e\xe8\xe2\x71\x1a\x7b\x6e\x78\xbb\x28\x7f\x2b\x4f\xd5\x63\xe9\xb3\x20\x1e\x0b\x8b\x76\xdd\xbc\x96\x47\xd7\x23\x1c\xfd\x8a\x04\xb8\x7f\x72\xdd\x12\x71\x29\x87\x34\x9a\x69\x3c\x0d\xad\x48\x93\x05\xd6\xad\x7e\xba\x55\x60\x0e\xe7\xc7\x78\x2a\x22\xac\x48\xfd\xb9\xd9\xfc\x79\xf5\xcb\xb2\x11\x17\xa9\xc1\xc0\xff\x15\x44\xd5\x5c\xf5\x95\x61\x2e\xc0\xe0\xf6\x55\x63\x02\xb5\x3d\x1f\xc7\xda\xbe\x8c\xcb\xd0\x5a\x28\xb5\x5b\x8c\x4d\x48\x66\xc3\x14\x2e\x23\x8e\xb6\x52\x07\x91\x67\x0a\x9c\x56\x87\xbe\x29\x2d\xef\x7c\xfe\x75\xe6\x92\xa5\xa8\x2c\x6f\x81\xc9\x6e\xb3\x9e\x9c\x7f\xfa\x11\x6e\x25\xbb\x2c\x37\xa6\xef\xa2\x73\xa5\x34\x36\x67\x45\x75\x59\x07\x1a\x5f\xaa\x8e\x94\x4b\xf9\xd0\xf1\xf4\xc2\xdc\xa6\x7f\xa1\x35\x8d\x11\x04\xd4\xfe\x84\x99\x5e\x11\x07\x22\x95\xf0\x8b\x97\x7d\xe5\x86\xe1\x39\x87\x50\xc7\xbc\xf3\x0b\x6e\x63\x99\xcd\x66\x14\x35\x72\x10\xcc\x5e\x8b\xb5\xf2\x74\x6c\xa6\xdf\x26\xa0\x91\x01\x74\x8a\x71\x90\x06\x11\xdd\xb7\x28\xfc\xed\xbe\x2a\x26\x51\x48\x11\x93\xfd\x2a\x2a\x58\x55\x2a\x0c\x7e\xfb\x5c\xed\x98\xc5\x61\x98\xe0\xf4\xb6\xa5\x56\xdf\xaf\xbc\xad\xca\x8f\xe6\x75\x59\x82\x31\x99\xca\xa6\xc6\x09\x2c\x0e\x19\xf5\xe5\x16\x8b\x11\x15\xf9\x0d\x80\x85\x05\xcd\x3e\xae\x38\x4a\x84\x4b\xd0\x9b\xf2\xa1\xec\xa9\x95\x2c\x8e\x04\x09\x68\x27\xab\x88\x58\x6e\xbc\x77\x3d\x06\x93\xc5\x34\x50\x58\x54\x38\xda\x2e\x24\xa6\x1e\xdd\x31\x4a\x22\x6f\xb4\x2c\x4e\x85\x7a\xbd\x9e\x1a\x01\xb3\x98\x51\xe7\x61\x8d\xa2\x6e\xb3\x65\x9a\xb8\x5d\x72\x1c\xac\xd2\x82\xa2\x66\xde\x9f\x38\xe6\x11\xb6\xe1\x7c\x9a\x75\x7b\xfd\x3c\x63\x30\xcd\xe2\x84\x1a\xee\xed\x37\x7d\x58\xe2\xf8\x0d\x7e\xc1\x8f\x93\x98\x2a\xa7\xc4\xdb\x7e\x72\x5b\x3e\x8b\x7a\x56\xe7\x91\xc5\x09\x58\xc8\xfb\x62\xf9\xf8\xe8\x3f\x9e\x92\x84\x9a\x41\x78\x3d\xe3\xd2\xcc\xe2\x34\xa2\x60\xdd\xe2\xf2\x66\xa2\xd1\xcb\xe2\x94\x86\xa1\x75\xfc\xac\x9b\xaa\x3c\x2f\x0a\xbd\x81\x42\x6f\xcb\x36\xea\x17\x7b\x18\x28\x23\xb0\x38\x4d\x6c\xa9\xe2\x58\xc1\x51\x54\xa3\xc6\xe3\xd7\x2d\xfe\x38\x95\x5c\xb1\x4b\x1f\xa1\x2f\x1a\xb4\x71\xaa\x63\xdc\x0a\xed\xab\xd2\x17\xa5\x62\xa1\x01\x22\xaf\x72\x57\xbc\x5d\xf6\x99\x27\xdf\xad\x58\x42\xdc\x26\xe2\xd4\x97\xeb\xa1\xee\x0b\x8b\x35\xd3\x76\x55\xc3\x00\x60\xa4\xdc\xcb\x62\x2d\xb5\xf2\x4c\xcd\xfd\x49\x54\xdd\x65\x00\x63\x4e\x4d\x12\x16\x79\x6e\xb3\x83\xee\xb1\x02\x87\x5e\x2c\xd2\xaa\x0f\xb7\x77\xe9\x41\xf8\x92\x6a\x6c\x0c\x4d\x2d\x53\x16\x61\x32\xcf\xe2\x54\xbb\x0a\xa7\x1d\x90\x04\xa1\x00\xdf\xf1\xee\x35\xe1\x97\xd3\xaa\x48\x12\xa4\x16\xd4\xbf\x7c\x7a\x7e\x5e\xad\x9d\xec\xf4\x6e\xfb\xbc\xed\x4e\x24\x62\xd1\x39\x67\xba\x5f\x37\x12\x1d\x67\x49\xa0\x43\xc4\xfc\x2d\x7b\xe0\xf3\xdf\x2a\xd1\xb6\xb1\x37\x56\xa9\x72\x51\x37\xeb\x1e\xa2\x97\x10\x19\x87\x43\x1e\xb0\x7d\xda\xb8\x70\x25\xf3\x6b\x79\x12\x82\xc2\x4d\xec\x2f\x7f\x0e\x9a\x58\x53\xff\xac\xf6\x9d\xd2\xe1\x5b\x98\xd0\x44\x63\x6c\xe0\x63\x0c\xcc\x1b\x1f\x60\x2f\x64\xf9\x73\x7e\xfd\x49\x58\x48\xb1\x5b\xb7\x53\x22\xcf\x2d\x35\xf9\xff\x8c\xaf\x65\x09\x27\x31\x6e\x3a\xcb\xe5\xba\x8f\xf8\xfd\xb1\x28\x46\x6d\x17\x0f\xe8\x2c\x51\x82\x6a\x7c\x15\x3c\x02\x1d\x4f\xde\xd9\xff\x2b\x67\x8a\x25\x3c\xe5\x68\x08\x8e\xc1\xef\xe6\xb5\x3c\xe5\x28\xf0\x7c\x75\x6a\xb0\x0b\xa7\x37\xe5\x8d\xc8\x72\x7f\x5d\x31\xb1\xea\xe5\xf8\x1c\x1e\xd0\x2c\xe8\x33\x6d\x3e\x86\x12\x94\xb1\x33\x03\xeb\xa4\xe3\x59\x12\x43\xe4\x59\x5a\x6b\x51\xbc\x05\x1e\xef\x94\x24\x84\xe2\x12\x72\x2a\xda\x97\xe4\xae\x5e\x35\xaf\x43\x9c\x34\x4b\x12\x69\xb0\x71\xf8\x51\x65\x0d\x38\x1d\xe7\xf1\xc3\x4c\x8c\xe5\x7b\x34\xe2\x0d\x1c\xf3\xcf\x16\x0b\x3a\xe9\x13\xff\x65\x42\x70\x09\x9e\x15\xd0\xdb\xb6\x0d\x05\x1d\x59\x22\x53\xcd\x94\x8f\xd7\xde\xe1\x53\xf9\x31\x96\x48\x61\x4d\x9d\xb4\x55\x5e\x77\xe4\x49\x77\x50\x85\x1a\x7b\xf1\x08\x66\xc7\x4f\x3d\x88\xe2\x24\xf2\xc9\x1b\xa8\x03\x5b\xb9\xc0\x4b\x42\xfb\xc4\x8e\x81\x7c\x53\x6e\x3f\x69\x47\xf9\xcf\xd2\x04\x51\xa6\xb6\x25\xbc\xad\x44\xd6\xb5\x38\xfa\xb5\x30\xd1\x40\xb0\xce\xfe\xfb\xe6\xe9\xf1\x28\x9a\xd7\xdd\xa5\xc3\xf7\xf8\x11\x6a\x63\x10\x12\xb1\x2f\xa6\xa4\x6e\xff\xdb\x80\x85\xa8\xe3\x29\xda\xeb\xc5\xb0\x6c\x20\x4c\x36\xb9\x48\xe0\x01\x22\x76\x9a\x57\xf8\x51\x76\x2b\x60\x02\x90\x22\x96\x43\x59\x6c\x7b\x17\x96\x5f\x74\xf3\x13\x43\xad\x26\xcd\xfd\xd3\x76\xbb\x5a\xff\x89\xe2\x19\xbb\xc5\xf5\xf5\x7a\xb5\xd9\x74\x63\x04\xc1\x25\xc3\x56\x80\x77\x50\xe8\x5d\xd3\x97\x46\x12\xa3\x22\x0c\xb2\xfb\x1d\xc4\x92\x74\x86\xf9\x63\x4a\x62\x8a\x01\xc6\xf6\xcf\xe7\xd5\xee\x66\xbd\xba\xbb\xfd\xb6\x5d\xad\xbb\xa3\xa9\xa4\x0e\xa4\x7c\x3a\x23\xa7\xcc\x1f\x30\x0a\x4d\x84\x86\xc6\x69\xc5\x98\x1f\xce\xd2\x30\x14\x48\x38\xb9\x7b\xbc\xdb\xde\x2d\xee\x77\x8b\xbb\xf5\xf5\xfa\xe9\xb9\x3b\xcc\xac\xec\xe1\xfa\x6e\xb9\xba\x5a\xdc\xdf\xff\xbb\x3b\x90\x50\x5c\xc6\x4e\x45\x9e\x15\x6f\xb3\x01\x7c\x1a\x4a\x89\x8f\x6b\xb3\xb9\x1e\x86\x8c\x69\xa8\x21\xb2\x21\x65\x8f\xb8\x1f\x3f\xe9\x34\x0a\x6c\x0b\xdd\x26\xc1\x50\x63\xe9\xac\x76\xb2\xad\xca\x09\x01\x5c\xa3\xf1\xd4\x01\x8a\x66\x51\xe8\x17\xaf\xa9\xc2\xd2\x88\x58\xdc\x6e\xfb\xde\x5e\x67\xef\xf3\xc5\x82\x34\x0a\x01\x55\x6d\x7c\x0e\x5b\x2f\xcb\xaa\x3f\x05\xd7\xc2\x02\x49\xa1\xdd\xa4\xfb\xfb\x45\x4d\x90\xf4\x32\x4a\xd7\x13\x2d\x41\x37\x88\x05\x0c\x9d\xb1\x96\xdb\xcd\x72\xf4\xcb\x19\x49\x88\xb1\x11\xec\x11\xea\xd7\xcc\x34\x57\xdd\xee\x92\xb2\x88\xc5\x72\xe2\x77\x10\xa6\xdd\xd1\x38\x4c\xbc\xa5\x82\x68\xd4\xeb\x95\x35\xf6\xf4\xa2\xb0\x03\xf8\x46\xca\x12\x5b\x34\x44\xda\x42\xf7\x79\x99\x60\x1f\x18\x2d\xde\x97\x65\x5e\x56\x93\x8b\xe6\x21\x41\xc0\x1b\xd2\x2b\xb2\xa2\x03\x02\x0f\x73\x47\x9f\x32\xa5\x3c\x06\x7c\xcf\x9c\x26\xb6\x0d\x13\x6e\xcb\x72\x32\x03\x62\x12\x8a\x09\x3e\xe9\xc9\xb4\x19\xd8\xe4\xbb\xe3\x90\xe2\x06\xf3\x08\x1f\xae\x8e\xfb\xcb\x3e\xf7\x6c\x8a\x96\xc6\x09\x45\xb0\xdd\x36\x3b\x40\x9f\x39\xa4\x31\xc4\x89\x0b\xa4\x7b\x17\x21\x6b\x54\x3c\xbe\x90\x24\x30\xd6\x73\xa7\xb0\xe4\xb9\xf9\x89\x9d\x08\x83\x78\x8b\xd2\x31\xef\x76\x68\xd1\xfd\xdb\x10\x4b\xf4\xff\xd8\xff\xfa\xc1\xda\x0a\xa3\xb5\x0f\xce\x6e\x12\x9f\x54\x30\xd3\xc4\x24\x49\xaf\x8e\xde\x65\x0a\x93\x9a\x55\x9a\xa6\x8a\x84\x1d\xcb\xea\xb5\xde\x64\x85\x82\x7b\x51\x37\xdf\x86\xec\x58\x3f\x58\x08\x8c\xe7\xb6\xaf\x70\x95\x35\xaa\xcc\x8a\x25\xa2\x18\x47\xd3\x32\x15\x46\x25\x5d\x2c\x05\x43\x5b\x62\x96\x0a\xc2\x50\xfb\xb0\x5f\xa2\x6e\xef\x17\x2f\x97\x25\xc8\xc9\x8f\x11\x44\x47\x4e\x31\x81\x4c\x7e\x80\x70\x0b\xef\xc1\x01\x63\x2d\xad\xce\x1d\x94\x81\x41\x60\xbf\x65\x6d\x0f\x3c\x9f\xe6\xbf\x46\x52\x8a\x6d\xbd\x53\xed\x66\xe1\x4d\x26\x87\x3f\x4d\x72\x81\x8f\xea\x16\x9a\xeb\x73\x21\x0e\x99\x5a\x8a\xca\x79\x7b\x0e\xab\x5c\x7e\xb8\x64\xe0\xa9\xc9\x6a\xa0\x49\xe6\x0f\xab\x28\x09\x3d\x51\xa5\x4d\xff\xb3\x62\x7f\x03\x48\x67\xab\x2f\x5e\x28\x25\xac\xab\x81\xaf\x27\x5d\xdf\x3d\xd6\xd6\x99\xa9\x2e\xf3\xf7\x5f\xc8\x6c\xb2\x54\x73\x6b\x25\xb2\xaf\x44\xd1\x6c\x9a\x99\x0a\xc3\xf4\x03\xb1\xc1\xd0\x1a\x97\x7a\x59\x36\x75\x6f\x9d\xc1\x52\xad\x13\x84\xbb\xde\x42\xd3\xde\x80\xbb\xc2\x94\xa3\x35\xc3\x10\x8e\x6b\xc6\x66\x00\x10\x99\xdd\x36\x53\x63\xb4\x8e\x7a\x29\x9d\x45\xd1\xbc\x66\x5e\x90\x94\x89\x80\xa4\xa9\xbb\x43\xd7\xd7\x37\xe3\xdb\x27\x82\x50\xcb\x2e\x66\xff\x56\x9e\x6a\x4f\x53\xae\xbb\x8f\x47\x01\x66\xaa\xed\xa6\xd2\xd7\xdf\xfe\xd1\xff\xd7\x78\xda\x25\xa3\x63\x93\x7a\x9d\x08\x68\x12\xa6\x3e\x7d\xae\xf6\xb0\x14\xc7\xae\x40\xf5\xdc\xb3\x03\xea\x4f\x68\x4f\x4c\x04\x2c\x45\x72\xbe\x06\x95\xb7\x99\xe1\x2b\x88\x66\x50\x46\xed\xbe\x88\x84\x31\xd2\x3c\x0e\x59\xf1\xcf\x53\x59\x9d\x7c\x11\x56\x10\xc1\xa9\x74\xc5\x15\xd0\x4e\x6b\x7a\xe0\x6d\x31\xbe\x3d\x61\x6c\x6d\x00\x72\x10\xef\xb0\x1b\x1b\x56\xfa\x21\xa9\x26\x43\x1c\xe5\x72\xbd\x99\x8c\x88\x48\xa8\x1c\xb7\xb0\xc9\xdf\xf3\xed\xa7\x36\xef\x4c\x50\xae\x91\x48\xf9\xf1\x5a\x0e\x13\x62\x41\x05\xa1\x36\x47\xc3\x0c\x0f\xd6\x85\xeb\x8d\xcc\x4f\x3c\x41\x21\xa0\x96\x6e\x58\xdc\x38\x61\x62\xf4\xae\xf0\xe7\x63\xd4\xd6\xd7\x50\xc0\x25\x3b\x88\xea\x7c\x2b\x0e\xe0\xa0\x08\x93\x29\xc2\x64\x62\x3c\x44\xd1\x56\x44\x66\xbd\xa0\x98\xe0\x41\xe0\xeb\x34\xbf\x97\xf2\x0b\xe2\xcb\xa5\xd9\x73\xd7\x84\xf6\xb3\xc8\x82\xa6\xa6\x4f\x95\xc7\x09\x66\x34\x7f\x96\xa7\xf5\xf9\x34\x6a\x5f\x7e\x4a\xaf\x11\x5c\x31\x8c\xf7\xe0\x27\x5e\xf4\xcd\xd0\xdf\xfc\x1e\x8a\xbd\x17\xd6\x60\x22\x4e\x6d\x68\x55\xb4\x43\xcb\x53\xa1\xeb\x32\xd7\x19\x54\x15\x1c\x73\x28\xb2\xfa\xb5\xea\xab\x44\x22\x49\x03\xaf\x4f\xf3\x52\x43\x35\x0a\xfd\x87\x29\x87\x48\x8c\x48\x82\xff\xf9\xff\xfe\xe7\xfb\x7a\x40\x48\x9b\xb9\xdc\xc9\x23\x4c\x83\x18\x2b\x8b\x2e\x7d\x9c\x6c\xae\xdd\x2d\x49\x13\xab\xd8\xdc\x64\x50\x45\x83\x16\x9f\x48\xb5\xb5\x95\x3f\x64\x05\x2e\x3f\xdd\xeb\xd5\xff\x04\x21\x03\x44\x20\xfe\x28\xe5\x70\xf3\x11\x02\xac\x39\xd5\xae\xee\x28\xb3\x1b\x50\xd5\x44\xb6\xbd\x1d\x97\x62\x23\xf0\x55\x14\x3a\x87\x9d\x76\x14\xe2\x4f\xde\x25\x19\x58\xa7\x4b\xdb\x32\xfc\x26\x2a\xdd\x89\xd3\x31\xd1\xa6\x12\x5e\x7b\xb0\xa8\x3f\x26\x8a\x79\x4c\xa8\x38\x41\x88\xd1\x51\x54\x4d\x01\x55\xbb\x58\x22\x2c\xfa\xd9\xfe\xff\x51\xcc\x7a\xc1\x05\xed\xce\xa1\x70\xd2\x1f\xc5\xf9\xa6\xac\xc6\x6a\x41\xf3\xaf\xa3\xd6\xb6\x12\x8b\x5d\xdd\xbf\x57\xa9\x10\x1a\x12\x54\x9b\xdb\x5d\xdd\x3f\x2d\xff\xd8\xec\x9e\x57\xeb\xdd\x7a\xb5\xb8\xfe\xfd\x65\xb3\x7d\x58\x79\x09\x64\x26\x80\x32\xe2\x34\xef\xcb\xaa\x86\x43\x2f\x90\xcd\x04\x70\x8b\x58\x3a\x66\x13\xc3\x42\x26\x40\x2a\x9c\x4d\xba\x2c\x7a\x7d\x48\x7f\x4c\x01\x7a\xb9\x58\x75\xf6\xab\xf2\xa7\xdd\x54\x1d\xb1\xd8\x9f\xc1\x50\x82\x11\xef\xe3\xbf\x56\xdb\xd1\x63\x37\x92\x84\xbd\xfe\xd1\x06\xd9\xb7\x7f\xef\x37\x1b\xcd\x89\x2d\xc3\xff\xbc\x29\x2b\x05\x4f\xc6\xd4\x5e\x44\xd2\x9d\x5d\x92\x10\x10\xf1\xd7\x8b\x67\xdd\x94\x9f\x94\xf5\x25\x89\xa8\x57\x23\x6e\xdf\x2d\xab\x90\x23\x72\x98\x44\x7d\x92\x18\x15\xb0\x41\xfb\xe8\xa6\x2a\x0f\x0f\xa8\x76\xbb\x14\xc7\x23\xe8\xe7\xaa\xfc\x79\x9e\x7c\x26\xe4\x0c\x3f\x73\xfd\xb2\x5e\x6c\xef\x9e\x1e\x51\xa2\x7a\xb3\x5d\xdc\xae\x7c\x86\x28\xa3\xc8\x01\x87\x86\x00\x9a\xd9\x19\x22\x23\xa3\x50\x7b\xfc\x36\x77\x6e\x98\xfe\x1c\x54\x07\xd8\xc1\x5b\x3e\xdd\xdf\x2f\xb6\xab\xf5\xe2\x7e\xf7\x6d\x75\x7f\xed\x0f\xb3\x30\x40\x9a\x89\xc9\x7e\x22\x30\xfd\xae\x58\xfe\x58\x76\x07\x45\x80\x75\x11\x9b\xd1\x38\xe7\x6f\x2c\x29\x5e\x24\x36\x92\x53\x8d\x19\xef\x2d\x34\x16\x58\xbb\x7c\xcd\x8e\x18\x46\xb9\x01\x71\xa4\x78\xd4\xdf\x4b\xdb\xfd\xba\x2e\xd5\x69\x38\xe3\x64\x1c\x6b\x54\x8f\x76\xde\xe3\x1b\x9b\xca\xd4\xb6\x4e\xf7\xab\x59\xf0\xf7\x2a\x49\x32\x4e\x09\x97\x3e\xec\xf6\xae\xbc\x98\x7a\x8c\x9f\x50\xac\x63\x6c\x49\xbd\x1f\x61\x77\x84\x6a\x07\x65\x77\x99\x09\xb7\x06\x66\xd8\xcd\xb7\x6e\x9a\xb3\x9d\x49\x99\xc4\x29\xd6\xf0\x0f\x8b\x1c\x7c\xfa\x2d\xd3\x40\x84\x0e\xe7\xd9\xdb\xc4\xf5\xd1\x89\x14\x71\x10\xdb\x76\xf8\x15\xe4\xe5\xc7\xc5\xcf\x1e\xbe\x6c\x52\xa4\x0c\xf1\x8c\xab\x1c\x54\x53\x95\x45\xa6\x1e\x4e\x75\xa6\x7e\xeb\x0e\x0b\xdf\xa5\xf6\x57\xea\x4a\xf2\x7f\x64\x7e\xf3\xf6\x43\x25\x4f\xdc\x4a\x8d\xa0\xf5\x67\xa7\x29\x8f\x1d\x8a\xfe\xc5\x95\x32\xb0\xb6\x3e\x62\x5f\x01\xae\x17\x73\x48\xea\x36\x5c\x86\xa1\xc1\x58\xfb\x3e\xcc\xfb\x14\xbb\x0f\xe8\xc8\x8a\x0b\x58\xe1\x70\x94\x99\xeb\xee\xb7\x21\xd6\x55\xc2\x38\x15\xb8\xae\x52\x24\x0d\x55\x78\xaf\xd6\xa8\x26\xf6\xc3\x1a\x9a\xf8\x63\x1c\x10\x83\x9a\x15\xaa\xc2\x0b\x1d\xd2\x97\xa5\xd1\x3a\x76\x06\x9a\xd7\x9b\xf2\x54\x29\x18\xa5\x69\x64\x7c\x79\x2a\x60\x2c\xb6\x3a\x6b\xfb\x7d\x0e\xf7\xa5\x7a\xbb\xf3\x2f\x99\x0a\x62\x40\x49\xd3\x03\x34\xa2\x0d\xad\x5f\xaa\xbc\x3b\xa4\x92\x84\x76\xd8\x90\xfb\xb2\x86\xaa\xbe\xca\x26\xf2\x16\x4c\x91\x50\x05\x69\x47\x1b\x76\xb2\x48\xae\x17\x39\x7a\xde\x8a\x84\x86\x3a\xfe\x42\x17\xb2\x7a\x6d\xda\xc1\x8d\x51\x84\x0a\xed\x24\xf7\xda\x98\x0a\xeb\xed\xe3\x01\x2c\xb0\xf4\xd4\x77\x91\xe5\x42\x76\x6d\xe5\xc9\x85\x71\x1e\xba\x86\xcb\x00\x2d\x34\xbf\x4f\x29\x92\x80\xb0\x30\xb2\xbf\x40\x59\x99\x7a\xec\x5a\x67\x0a\x36\x27\xe9\x69\x81\x17\xe4\x8d\xb9\x3a\x8f\x22\xa9\xc6\xa2\x83\xb4\xfc\xf5\xc1\xde\xa3\x88\x50\xc4\x5a\x79\x5f\x79\xba\xb0\x0a\x65\x82\x3d\xe7\x7f\x6d\xbf\x8f\xf0\xe9\x2a\x54\x3c\x40\xa5\x46\x31\x91\x75\x67\x2a\x12\x84\x90\x5e\xcc\x6e\x09\x9f\x2d\xaf\x8a\x12\x1a\x3b\x90\xf2\xbf\xcb\x02\x36\xaf\xe5\xd1\x4e\x77\xb7\xb7\x93\x6e\x60\x6c\xb0\xb2\x76\x80\xbd\x18\xf4\xf2\x14\xb6\xd4\xff\xe7\xff\xfb\x9f\xc5\xdd\x50\x94\x93\x29\x26\x78\xc4\xc6\x53\xb4\xdc\xb7\x17\xf0\x64\x5c\x81\x61\x51\xe8\xbb\x4b\xc2\xcb\xb0\xe4\xa2\x98\xe1\x58\x12\xfb\x98\x00\xb0\xe6\xd7\x3f\xc5\x09\x20\xb7\x7c\xbe\x36\xee\x07\x51\x26\x75\x87\x74\x1e\xbf\xdb\x8a\xb7\xf9\x06\x2a\x16\xd7\xaf\x37\xa2\x3a\x74\xaf\x9c\xe2\x10\xeb\x8e\xb6\x78\x2a\x9a\xfa\xea\x8c\xb2\xa6\xe3\xcf\xc7\x51\x82\x35\xa2\xc5\x66\xe3\x37\x1b\x15\x0b\xdb\xb4\xf3\xed\x0d\x0f\xc2\x9d\xc1\x22\xaa\x58\x12\x4b\x04\x6e\xe3\x21\x0b\x2c\x99\x61\x56\xa8\x24\x62\x98\x71\x96\xc6\x40\xe5\x16\xa9\xf1\x89\x12\x19\x60\x5e\x85\x1d\xcb\xac\xc0\x5a\xe2\xe8\xf9\x24\x26\xc2\xc8\x6b\x93\x1d\x8e\x39\xac\xd6\xcb\x30\x18\x1d\x4f\x83\x14\x8f\xdf\x42\xb3\xc8\x73\xbf\xc2\xf6\x7a\xa2\x7e\x98\x92\x12\x46\x36\x86\xbf\x78\x93\x52\x23\xbc\x88\xf3\x55\x7b\x1f\xcf\x36\x43\x9c\x73\xf4\x67\x4a\x08\x6b\x30\x89\xe4\xad\x4a\x1c\x7e\x2d\xa2\x32\xf9\xbc\x24\xaa\x93\x78\x7d\x80\x46\x68\xe1\xd6\xb1\xf5\x9d\xff\x05\x42\xab\x74\xe0\x85\x78\x53\x56\x7f\x4f\x7d\x63\xf0\x5f\xe3\x87\x23\x0c\xe5\xbd\x88\xfd\x22\xef\xba\xff\xee\xb8\x0c\xac\x78\xe9\x90\xa7\x65\xb5\xc8\xfd\x00\xc2\xbc\x82\x62\x1b\x50\x0c\x2b\x53\x4a\x72\x61\x03\x66\x71\xbc\x16\x67\xaf\x48\xa0\x54\x0c\x98\xf6\x9f\x0a\xbb\x91\x8c\x2d\x28\x06\x6b\xa3\x4a\x6c\xed\x08\x05\x24\x9b\xf2\x60\x93\xe0\xd1\x3a\xac\x52\x82\xe6\x57\xcb\xbb\xed\x9f\xbb\xe7\xf5\xdd\xb2\x5b\x8a\x34\x49\x6c\xb2\x2e\x6a\x2b\x40\xb1\x13\x41\xbb\xcf\xef\xdc\xad\xf0\xe3\x20\xb2\x2b\x53\xf3\x9a\x55\x16\x02\x30\x36\xd0\x63\xca\x24\xcc\x02\xbe\x6c\xcf\xf4\x9b\x97\x1a\x70\xc7\x75\x40\x88\xe9\x7d\xc0\x97\x0e\xbf\x3e\xed\x87\xeb\x20\xb4\xe2\x3e\x6d\x3e\xd9\xee\x93\xe3\xe9\xa3\x83\x28\xc6\x60\xe6\xcf\xf2\xd4\x9c\x24\x7c\xcf\xe0\xa3\xee\xbe\x41\xc5\xd4\x25\xe8\x8b\x63\xd6\x06\xa0\xf5\xb4\xbf\x32\xf9\x2e\x43\xb8\x8b\x37\x6e\x45\xbd\x51\x22\x17\xf3\x5a\xa8\x4c\x13\xa2\x11\x56\xe0\xdf\xf8\xce\xdd\x6c\x3a\x0c\x52\xaf\x2c\x37\xd0\xe0\xd0\x24\x0c\x03\x9b\xf5\xd5\xcf\x15\xbc\x67\xe5\xa9\xce\xcf\x2b\x54\xfa\xd4\x58\xc8\xd2\x03\x6e\x58\xf7\x19\x66\x48\x17\xfc\x43\xd1\x64\x0a\x96\xaf\x17\x78\x30\x4d\x18\x45\xd2\xd5\x72\xf9\x6d\xb7\x5e\xed\x48\xf7\x9d\xa9\x05\x1b\x16\xa7\x83\x65\x22\x76\x37\x8a\x08\x0b\xef\x5e\x3e\xdd\x3f\xad\x77\x7f\xae\xee\xef\x9f\x7e\xf8\x63\x61\x6a\x70\x42\x78\x73\x27\xeb\x79\x33\x74\x9a\x67\x3a\xa2\x31\x20\x24\xa5\x3a\x1f\x9b\x72\x99\x35\xe7\xe1\x3a\xa3\x23\x9a\xa2\xc4\x82\x55\xd2\x5c\x8a\x63\xd6\x88\x4f\x36\x2b\x1d\x09\x6b\x6a\xb3\x14\x85\xa8\xce\x5b\xa8\x9b\x02\xfa\xef\x11\x29\x16\x81\xf6\x55\x59\x5a\x19\x5e\xbd\xe8\x0e\x52\xca\x6d\x1c\xd3\x7e\xf5\xaa\x9a\x70\x8a\x35\xe3\x44\xda\xea\x6c\xbb\x67\xc0\xb8\x37\x38\x68\xdf\x69\xce\x0c\xbe\xdb\x28\xb4\x21\xf2\x35\xda\xd3\x4e\x61\x3d\x7e\xac\x92\xb8\x96\xdf\x6c\xbe\x79\x94\x87\x8e\x79\x80\x91\xf7\x22\x6f\xa0\xda\x6d\xab\x53\xdd\xe4\x50\xd7\x73\x72\x41\x83\x6f\x8d\xb5\x49\xed\x5a\xdd\xb1\x4a\x74\x0c\xaa\x4f\xf6\x77\x1f\xa2\x76\x0a\x83\x3e\x3c\xd0\x09\x23\x58\x87\x5b\x54\xcd\x6b\x76\x80\xa6\x8b\x9c\x75\xc2\x15\xf6\x73\x9c\xb4\x35\xae\x2f\xd5\xf9\xd2\x3d\x94\xe9\x24\xb5\x55\x2c\x5c\x2d\x70\x2e\x4f\x2b\xbe\x3a\x15\xca\xca\x23\x96\x57\x51\x38\x2e\x99\xf9\x11\x26\x09\x6c\xbc\x56\xbd\x43\xb5\x2a\x74\x1b\xb5\x2d\xcb\xc2\xe4\x99\xea\x22\xc1\xd3\x40\x7a\xbe\x5b\xcc\xe7\xd0\x52\x33\xbe\x5e\xf6\x4b\xa7\x41\xd7\xf8\x61\x88\x80\x10\x9b\x79\x3c\x9e\xba\xca\xad\x16\xa1\x46\xc0\xe8\x41\x54\x6f\x8b\xfa\xee\x60\xd1\x6d\xf3\xe5\x15\x2d\xb4\xc4\xa5\xf7\xc3\x07\xa7\x9d\x46\x99\x3f\x9d\x0c\x39\x2a\x38\x1c\x70\xfe\x3c\xbd\x43\x55\x65\x1a\x56\x56\x3e\xe2\x2a\xfb\x05\x06\x4e\x4b\x11\x21\xa8\xa1\x2c\xf2\x33\x26\xd9\x03\xc3\x78\xa6\x15\x0d\xbc\x98\xdf\x17\xca\x35\x5a\xa5\x11\x2e\x2a\x06\x1a\xf5\xfa\x2c\x32\x6d\x61\xb0\x37\x65\xf5\x2c\xce\x50\x5d\x9d\x31\x8f\x9f\x3c\x67\x25\xa5\x6d\x9b\x8a\x37\xf4\xed\x71\xd3\xd0\x07\x7f\x5a\x87\x01\xda\x07\xda\x29\x76\x57\xe7\xa2\xb8\xf0\xd4\xf9\x7a\x2b\xd6\x90\x68\x6f\x1d\xf4\x50\x0e\xd5\xbe\xfc\x71\x61\x15\x16\x76\xb6\x7f\x6e\x55\xfb\xbf\xdc\xee\x13\xff\x49\x29\x8c\x2d\x3f\x5e\x88\x47\x4e\xaf\x41\x6a\x8b\xd4\x69\x13\x31\x4f\x7a\xc6\xb2\xad\x5f\xa1\xeb\xbb\x62\x59\xf8\x22\xae\x06\x50\xc8\xe1\x6d\x23\x86\xb1\x9d\x11\xd3\x26\x02\xd4\x4b\xfc\x91\xe5\x9d\x99\xcc\xe4\x51\x18\xa1\xad\x89\xa7\x05\x01\x6e\xde\xb2\xc2\x71\xac\xef\xa6\x3b\x95\xd1\x04\x35\xfc\x2e\x4c\xab\xbf\x9c\x31\x10\x84\x80\x39\xd8\xea\x67\x59\xc9\xd3\x4f\xd5\x41\xa1\x81\x90\x84\x0c\xfc\x35\xbb\x82\x72\xbf\xaa\x00\x09\x2d\x1b\xc3\x83\xd8\x8b\xb7\xcb\xe6\x10\x10\x03\x56\xb7\xb6\xdd\xca\xf1\xda\x2f\x45\x15\x19\x84\x21\x41\xd0\x87\xb5\xdd\xbc\x6a\x77\xf3\xaa\x3b\x96\x86\xd8\x3b\x39\x56\xa5\x82\xba\xfe\x26\x0a\x84\x80\x0d\x2e\x24\x62\xb6\x96\xfe\xed\x74\x10\xc5\xbf\xfc\x96\x04\x11\x0b\xb1\xc9\x5f\xb7\x01\x44\xf8\x58\x36\x23\x8b\x5e\x06\x11\xa7\x64\xe8\x37\x3b\xdd\x13\x81\x6a\xee\x11\x79\xb6\x16\xd9\x49\xcd\xb8\x59\xdb\x79\x42\x87\xbe\xd5\xfb\x8f\xd1\xed\xa5\xa0\x80\x38\x35\xaf\x5b\x51\x63\xed\xc0\x93\xd8\x67\x67\x18\x30\x4a\x51\xac\x43\xb8\xc9\x75\xd7\x74\x3a\x0f\xc0\x62\x8a\x2f\xd1\xc6\x06\x10\x17\x70\x22\x60\x69\x84\xb0\xd9\xcd\xfd\xf3\x72\x77\x11\x91\x43\x4c\x78\x12\xf7\x4c\x57\x5a\xf4\xae\x0a\x7e\x44\x14\xa2\x2a\xcc\x21\x2b\x2e\xd9\x5f\x83\x1f\xef\x86\x27\x41\x8c\x98\x81\xdd\xa9\x38\x0a\xf5\xf6\x43\x54\x55\x56\x56\x77\x9f\xfd\xb6\x24\x4c\xbd\x2b\x45\xbb\x3a\x5d\x97\x45\xf7\xfc\x93\x38\x44\x61\x77\x1f\x71\xde\x00\x4e\x8f\x95\xad\x75\xfd\x62\xdd\x83\x44\x99\x20\x74\x54\x72\x9b\x0d\x4c\x6e\x4c\x4a\x92\xb4\x97\x0e\x1a\xf5\x05\xfd\x88\xc4\x9a\xd5\x48\x91\xe7\xa5\x03\xb1\xd6\xc3\xbd\xa5\xfb\xd1\x82\x11\x0c\xae\xfe\x7c\xba\xda\xfa\x14\x0d\x84\x52\xa8\x8b\x9b\x7d\x42\xb3\x9b\x5c\xb0\x4a\x98\x71\x92\x31\x4f\xb9\xbe\xb0\x6f\x77\xa3\x74\x98\x26\x4e\x96\xfa\x58\xd6\x30\x03\x34\x06\xe0\x56\x63\x30\xab\xbf\x97\x4d\x56\xec\x51\xf3\xa4\xf7\xf0\x60\x00\x60\x7b\x0c\x2a\x07\x51\x6c\x00\xf4\xcb\x04\x34\x08\x26\xe0\x3a\xe8\xc1\x19\xf0\x0e\x79\x79\x84\x6a\xb5\xfd\x76\x0d\x75\x93\xd9\x92\xe6\x6c\x44\x0b\x86\x5b\xb7\xc2\x5b\xf4\x49\x3b\xbe\xd4\xa0\x1f\x9d\x01\x9c\xbf\x5d\x26\x48\x05\x86\xb2\x6d\x70\x86\xda\x42\xfe\x99\x9b\xc0\x50\x2c\x49\x0b\x0b\x93\xea\x75\x64\xc6\xdf\x62\x48\x18\xa3\xc8\xee\x12\xd5\x7c\x7e\x25\xd9\xd6\xdd\x64\x43\xb8\x75\xcb\x6e\xd3\xa3\x31\x6b\xa1\x0d\xc4\xa9\xc3\xf6\x22\x2e\xfa\x75\x24\xaf\x3e\x88\x9c\x0c\x49\x62\x2b\x30\x88\x77\xe7\xe6\x54\x68\xcb\x3e\x22\x93\x8b\x0c\x03\x46\x5d\xe5\xd4\xb7\x67\x67\xcb\x9e\x26\x0c\x6d\x83\xec\x3e\xfb\xcf\x29\xd3\x59\x73\x1e\x92\x40\xfc\xf5\x85\x3c\x60\xcc\x39\xe1\x55\x99\x6a\x40\xe3\x9c\x45\x38\x2e\x1a\xa5\x4d\x4e\x1a\xd1\x04\x2b\x5f\x2e\x72\xb6\x84\xc6\x76\xe4\x06\x59\xbe\x93\xc1\x10\x7b\x72\xd8\xc2\x43\x8d\x71\x4f\xcf\x2f\x56\x6f\x43\x19\xa0\xc3\x56\x1b\xdf\x38\xe4\x84\xbf\x46\x16\x00\xaa\xe8\x61\xa5\x61\x77\xac\x3a\x31\x65\x66\x58\x98\x22\x77\xad\x6c\x17\xcd\xc7\xb2\xb1\x9e\x25\xdd\xc2\x6b\x58\xca\x11\x70\xb2\x5c\xdc\xdf\xef\x6e\x17\x9b\xdd\x72\x75\x77\x7f\xf7\x78\x3b\x7e\x6b\x0d\x4b\x05\x16\x29\xee\x5f\xbe\xef\xa6\xf0\x4a\xc3\x34\x43\x54\xc1\xf6\xb9\xac\x9a\xd1\xcd\xe3\x92\x18\x6f\x7d\x5d\x16\xa7\xba\x8f\xb2\xc6\xa7\x8f\x43\x8d\xe0\x20\x09\xfb\xac\x78\xb6\x5a\xb6\xeb\xf2\x54\xe8\x4f\x3c\xc4\xfc\xc7\x92\x71\x37\xd9\x41\x59\xfd\x51\xc3\x71\xb2\xf6\xfe\x4e\x9b\x3e\xbe\x33\x29\x49\xd0\x6b\x08\x5b\x97\x4f\xc5\xc8\x7b\x9a\x99\x34\xb2\x0f\x06\xb1\x91\x95\xeb\x7f\x8e\xb4\xa6\x4c\x2a\xad\x6f\xff\x55\xe9\x75\x80\xbb\x17\x2d\x55\xc2\x6e\xd8\x25\xd4\x6e\x1e\x60\x61\x67\x3e\x18\x35\x22\x0c\x90\x71\xba\x81\xe6\x59\x34\xb6\xbc\x76\x84\xaa\xc9\x60\x5e\xf3\x95\x19\x11\xc7\x56\xdd\xbd\xd3\xa8\x9e\x05\xce\x1b\x49\x52\xcc\xd7\xdc\x5f\x57\x4a\x75\x5a\xe7\xcc\x48\x65\x8d\x9a\xb2\x7a\x51\x81\xf0\xf2\x61\xc3\x4d\xc8\x28\x23\x91\xfa\xb0\x43\xc2\x70\xf9\x9e\x69\xa8\x6c\xcc\x39\xbe\x1e\x1d\x73\xcc\xb9\x16\x5a\xdf\x7b\x90\xe1\xe8\x44\x1a\x64\xe8\x95\xfd\xbc\x0d\x33\x33\x10\xa7\x5a\x7a\x51\x6e\x53\xa2\xed\x65\x77\x79\x20\x18\xe2\x57\x8f\xa7\xe6\xaa\x51\x96\x85\xab\x2e\xa1\xe9\x5f\x2b\x08\x5c\x8c\x1b\xb5\x3e\xfd\x37\x29\x2b\x27\x58\xe3\x8b\x6d\x1f\xf2\xf8\xf7\x19\x11\xe0\x0c\x77\xf0\x7b\xef\x91\x3a\xbc\xd9\x3c\x20\x81\xd5\x7c\x6b\x7f\x4d\x1b\x2a\x0c\x6e\x00\x0f\x48\xa4\x60\xe8\x7c\x3c\xfb\x60\x79\x40\x98\xf7\x3f\x46\x21\x42\xaf\x2a\xc8\x03\x92\x10\xf4\xa6\x29\xbc\x22\xda\xf8\xec\x90\xa0\x05\x59\x5e\x8a\xe2\x41\x34\xa7\xea\xe2\xe2\xc2\xd8\x5a\x1b\x2d\x9e\xfe\xf0\xa7\x0c\x85\xad\x0a\x3a\x52\x8c\xf7\x86\x6a\x44\x53\xf7\x11\x1d\x0f\xa2\x40\x63\xf1\xb7\xf0\x62\xf6\xe3\x2c\x85\x07\x51\xa4\x85\x2b\x3b\xb7\xb1\x44\xbb\xf5\x95\x1f\x36\x3b\xb9\xdc\xa9\x78\x10\xd1\x14\x09\x13\x3b\x28\x10\x69\x0d\x75\x73\x67\x1e\x01\xf4\x25\x89\xd2\x7f\x22\x8e\x59\xea\x6d\x54\x4e\x1a\x8a\xc6\x31\x05\x26\xc3\x94\xc6\x66\xef\x5b\x96\xe7\x0f\xe0\x7f\x25\x15\x09\xee\xba\x15\xd6\x6e\xb0\x57\x64\x6b\x74\xfb\xc1\x10\x6d\x75\x43\x30\x23\xfa\x0a\x6d\xf0\x8f\xf1\x4f\xa1\xa0\xc9\x90\xac\x7c\x75\xbe\xcd\xf4\xe4\xaa\x18\x23\x8e\x32\x86\x4f\x74\xf5\xb3\x81\xaa\x10\xb9\x95\x83\xa9\xfd\x25\xf0\xd0\x7a\x32\xa2\x3a\xe2\xd3\x1f\xab\xc7\x8d\x3f\x12\x07\x36\x97\x42\x4d\x4c\xaf\x3b\xde\xc7\xeb\x3c\x88\x49\x80\xac\xbe\xfb\x72\x6f\x73\x17\xb8\x28\xad\xfb\x91\x9c\x20\x34\x0d\x8d\x66\x0a\x68\x66\x68\x34\x3c\x88\x41\x20\x2e\xc5\x56\xad\xb3\x1c\xda\x74\xf3\x11\x3e\x5e\xea\x01\x70\x60\x00\xbf\x9f\xbc\x53\x64\x5a\x43\xe5\x41\xc2\xad\xed\xd2\x1e\x9a\x9b\xac\x7e\x5d\xa0\xfd\xed\xe4\x2e\x25\x2a\x1d\x52\xfb\x1f\xe1\xa7\x8d\x06\xa6\x73\x2d\xe5\x0a\xe3\xee\x55\x5e\x22\x41\xd2\xff\x59\x07\x08\x1d\xcb\x45\xed\xac\x91\xed\x2b\xea\x8f\x8b\xd8\xaa\x27\xb7\x09\x29\xbe\x3e\xbb\xc9\xa4\x14\x89\x0d\x7a\x85\xd6\x9b\x63\x59\xd4\xa5\x45\xb7\x7f\x15\x3a\xf2\x40\xe8\x14\x25\xdb\x2c\x8f\x72\x52\xb3\xf0\x63\x8c\x40\xb6\x74\x8f\x3e\xbc\x5f\xfe\x78\xfe\x05\xfa\x90\x07\x32\x52\x38\xe5\xcb\x46\xf9\x74\x76\x51\x68\x97\x48\xcf\x4f\x46\x19\x07\x89\xd5\x2d\xc8\xf2\xe6\xa9\xf0\x3f\x5d\xa6\x16\xeb\xf9\x57\x99\x15\xb7\x6d\x96\xf1\xc9\x17\xa6\xc6\x78\xb6\x64\xa7\xf4\xce\x03\xa5\x38\x2e\x3b\x0f\x77\x8f\xbb\x76\x6e\x6e\xee\x9f\x6e\x1f\x77\xcb\xa7\xfb\xfb\xd5\x72\xbb\xba\xee\x86\x01\x58\x42\x7f\xbb\x4d\x2e\xf2\x7c\x73\x10\x15\x3e\xc0\xac\xd8\x8f\xb5\x43\x79\xa0\xa9\x05\x02\xf7\xac\x7f\x1e\x40\x10\xc8\x41\x86\x8b\xbe\x2e\xfe\x50\x68\xdd\xba\xdb\xeb\x6f\x53\xa5\xcf\xf2\x8f\xc9\xef\x01\x2e\x55\xe0\x4b\x6a\x77\x7a\x5b\x7a\x1c\xc5\x1a\x54\x76\xbc\xe0\xcd\xf1\x00\xe2\x10\xb7\xba\xbc\xdc\xff\x36\x13\xc3\xf2\x00\x64\x12\x04\xfd\x5e\xba\x59\xba\xa7\xe1\x0e\x1b\x46\xb1\xfc\xb4\xb1\xa8\xca\x65\x99\x15\x75\x7f\x4c\xa6\xb6\xa0\x6b\xfd\xdd\xbb\xbf\x1b\x91\x2a\xef\x57\xef\xe7\xc7\xa5\xb6\x0d\x27\x01\x09\x85\x75\x00\x6f\x3f\x7e\xec\xc1\x49\x7a\x3a\x50\xc5\xd6\xc3\xd3\x77\xea\x7a\x7d\x99\xd1\xaf\x21\x44\x73\x4c\x2f\x6f\x1b\x40\xa0\x15\xa6\xa8\xee\xba\x48\x48\x89\x0d\x1b\x9c\x8f\xf9\x7c\x47\x7c\x3c\xff\x48\x28\x14\xb6\x2d\xd0\x89\x6b\x47\xd8\xee\x7a\xf1\xa7\x5f\xc5\x48\x14\x51\x49\x3a\xe5\xbe\xf2\xd4\xd4\x33\xaa\x3b\x9c\x44\x5c\x23\x59\x53\x78\x0e\x21\x27\x51\xc2\xd1\xde\xd1\xa3\x50\xbf\x21\x7c\x6a\xb4\xfd\x91\x28\xb5\xa0\x4d\xd4\x6e\xfb\xb2\x67\xc5\x49\xa4\x0d\x16\x72\x76\x26\x2b\xb2\xfa\x15\x05\xc5\x06\xe8\x39\x37\x8a\x86\x24\xd2\x5e\xb8\xcb\x63\xad\x6f\xaa\xf2\xf0\xd2\x99\x11\x71\xc2\x42\x1a\x39\xf1\x72\xe4\xc5\xcf\xb4\xf7\x38\x89\xc3\x38\xb0\xc5\x4a\x57\xe9\x6b\x13\x88\x4e\xb7\x7a\xf2\x54\xe2\xd0\xd6\xd7\x77\xcd\x45\x06\xf6\xc9\xcf\x89\xb9\x88\x1c\x3e\x60\x70\xda\x39\xd3\xa7\x7e\x4b\x27\xb1\xa0\x9d\xa9\x76\xde\xbe\x0b\x4b\xa7\xd9\xee\x7f\x59\xac\x2c\x7f\xd5\xf3\x9c\x27\x62\xa2\xe3\x4b\x48\x42\x42\x7b\x4a\xbd\xd3\x32\x9b\xdc\x85\x24\x4a\xe2\xa1\x88\xe9\xd5\xe9\xdc\xc5\x30\xa3\xfd\x87\x24\x4a\x22\x83\x6a\xf5\x7e\x5f\xee\xb3\xc2\x94\xf3\xa3\xb4\x15\xa1\x40\x72\x8f\x13\x8d\xf9\xfa\x46\xa5\xcc\x72\x51\xbd\x58\xd0\x21\x2b\xb6\x13\xbc\x3f\x27\x69\x1a\x42\x8f\xf4\x44\x45\x36\xec\x8d\x5d\x42\xed\x39\x11\xa9\x15\x22\xb7\x25\xb7\x07\x51\x55\x99\xd8\xc3\x7d\xa6\xa0\x50\x70\x77\x10\x7b\xb8\x7b\xbe\xd9\xbc\x8a\xfa\x75\x3c\x59\x55\xc0\x82\x08\x23\xc1\xca\x52\x0b\xef\xcb\x3d\xf1\x37\x5e\xc9\x80\xb9\x6c\x78\xf1\x2e\x1a\x51\x4d\x45\xe7\xda\x21\x0a\x6b\x70\x05\xfc\x6c\x6e\xa1\x28\x3d\xe2\x80\x13\x1d\xc6\x98\x6d\x39\x58\xd2\x65\xd5\xa8\x83\xd1\x70\xa2\x29\x23\xc4\x4f\x70\xb8\x53\xe5\x50\xf1\x90\x13\x3d\xf4\xd3\xec\x71\xd8\x9c\x40\xca\x05\x73\x3a\x6c\x80\x2a\x03\xee\x40\x9b\xc8\xbb\x08\x7f\x25\x2a\xcc\xba\x51\x63\xcf\x1f\x8e\xb8\x89\x87\xf2\x55\x3f\xf4\xcf\x9b\xcf\x35\xe7\xfc\xa7\x44\xac\x2c\x7e\xcf\xc9\x2c\x87\xd3\xa7\x3c\xc1\x3c\xf3\x30\xe0\xc0\xad\x3f\x56\xd6\x5c\x89\xa6\xc9\xe1\xf9\x7e\xb1\x5d\x96\x93\xee\x19\x0f\x49\x64\xed\x7f\x33\x2b\x5e\x72\x5d\x79\xa5\x4b\x1e\x12\x16\xe0\x7a\xdd\x86\x18\xe1\x20\xa1\xe5\x21\x91\x1a\xeb\xac\x08\x83\xdb\xad\xbc\xd9\x30\xaa\x37\xe0\x4b\x20\x4f\xe7\x36\x0a\xbb\x39\x15\xf6\xed\xb3\x4a\x52\x6e\x50\x14\x58\x97\x6b\x14\xd6\x6c\xe7\xec\x24\x91\x18\xcd\xf1\x30\x32\x16\x4e\x64\xe7\x38\x34\xcb\xb2\xfe\xd4\x90\x92\x87\x94\x24\xc2\xc2\x44\xdc\xca\xff\x74\x84\xc2\x5b\x0a\x4e\x7e\x3a\x35\x0a\x8d\x7d\x2a\x61\x3a\x06\x2f\x0f\x59\xc4\xb0\x48\x53\x00\xe8\xba\x93\x74\x19\xb4\x7a\x79\xc8\x52\x8e\x90\x8a\x76\xef\x76\xb9\x50\xa7\x35\xd5\x8d\xd1\xda\x97\x36\xed\xcf\xdb\x2e\x9e\x30\xce\xb7\xc5\x10\xd8\x64\xfb\x02\x53\x94\xa9\x78\xfc\xac\x17\xc9\x97\x28\x55\x1e\x72\xa2\xb1\x02\x68\x2d\xdd\x46\xe2\x72\x7e\x04\xb7\x95\x67\x0b\x6d\x1a\x8b\x40\xf0\x90\xa7\x04\x01\xc1\xf2\x74\xde\xc9\xde\x69\x87\x87\xb1\x32\x91\x95\xba\xca\x55\xff\x8a\x85\xb1\x31\xb8\x9a\x6f\x5e\x01\x8e\x73\x2b\x53\x98\x84\x1a\x9b\xaf\xed\x2a\x93\x3f\x15\x76\x0a\x4a\x2b\x77\xda\x7e\x35\xf7\x93\x21\xe1\x71\x28\x47\x48\xf1\x6f\xed\xb6\xd7\x2f\xd3\x61\x92\x30\x6c\x24\x68\x50\xd9\xc1\x5f\x41\x4a\x25\xe2\xda\x70\x05\xbb\x85\xde\x56\x8f\x87\xa9\xb6\xb2\xa0\x7e\xf3\x78\x29\xca\x8f\x02\xf4\x73\x2e\x0a\x98\x27\xff\xf3\x50\x05\x12\x3f\xd3\x66\x6e\x57\xe7\xab\xed\xd2\x71\xa6\x3e\x19\x1d\x06\x68\xa9\x6d\xfb\xbf\xff\x3c\x89\xa2\x39\x1d\xb6\x95\xd0\x59\xb1\xef\xd5\x1a\x79\xa8\x22\x81\x04\xf8\x9b\xac\x10\xb5\xdf\x19\xfd\x41\x4d\xa3\xc0\xc3\x59\xb2\x62\xbf\x81\xdc\x5c\x43\x8d\x6a\xad\xfd\x10\x5b\xac\x57\xa2\xb8\x17\xe7\xd5\x7e\xef\x6e\xdd\x3f\x2e\xab\xc0\x3c\x04\xa1\x88\x35\x7d\x75\x75\xa9\x4b\x20\x2b\x0f\x4d\x20\x10\x4e\xf9\x67\x79\xda\x9e\x24\x1c\x50\xf9\x6f\x0d\xff\xf1\xdf\x68\x94\x5d\x69\xe4\xe9\x1c\x0e\xa2\xf3\x39\xd4\xc8\x94\x7b\xcc\xa3\x20\xb0\xa4\x73\x9f\x07\xfe\x7e\xaa\xbc\x0b\x22\x8f\x82\xf6\xb5\x77\x21\xf4\x72\xfd\xf4\x03\xed\x4a\xb7\x77\x0f\xab\x6e\x00\xb5\x96\x0a\x7f\x3c\xdd\x3d\x2e\x9f\x1e\x57\x7f\x6c\xbb\x23\xb1\xb1\x10\x7b\xd4\xe8\xfc\x5e\x36\x1d\x97\x9d\x47\x81\x10\x8e\x36\xd9\xae\xdb\x1b\xac\x1a\x41\x5f\x95\xe3\x51\xa0\x63\x6c\x5f\x34\xaf\x59\x9d\xd5\x26\x2b\x26\x1b\x49\x44\x54\x82\xc4\xae\x9d\xe7\x49\x2c\x45\xdd\xe4\xb0\x99\x91\x1a\x9e\x5f\x9e\xa3\x50\xdb\xac\x69\x93\x15\xfb\x53\x2e\xaa\xac\xc1\x46\x7e\x17\x48\x46\x11\x0f\x03\x97\xbc\x7e\x12\x88\x46\x51\x4a\x89\xed\x0c\x95\x15\xcc\xe5\xf5\x51\x24\x43\xe1\xaa\x44\x6d\x5e\x88\x75\xc1\x89\x6c\x22\x8f\x22\x1d\x62\x0e\x0f\x87\xac\xf9\x51\x56\x6f\x6b\xa8\x4f\x87\x4f\x5a\x3b\x3c\x8a\x80\x62\xa9\x06\x93\xdc\xb9\xe2\x30\x8f\x68\x18\x09\xcf\xa4\x42\xf3\x81\xf2\xd4\x2c\x45\xe5\xa7\x68\x44\x43\x2b\xeb\xf7\xf4\xf3\xbc\xef\xe6\x76\x44\x8d\x8a\xdb\xc5\xef\x46\x34\xaf\xbe\x40\xfe\x19\xbc\x69\xfc\x7d\x8c\x87\x96\xae\x2c\xf2\x7c\xfb\x9a\x75\x00\x96\x91\xf0\x41\x3b\x2c\xfd\xff\x69\xfb\xb3\xe6\xc6\x71\x25\x7d\x1c\xfe\x3a\x7d\x31\x17\x5c\x01\xf0\x52\x96\x65\x5b\xd3\x5e\x34\x96\xaa\xea\xcc\x9c\x38\xa1\xc0\x92\xb0\x79\x4c\x91\x1a\x92\xb2\xcb\xf3\xe9\xdf\x60\x26\xc0\xcd\x92\xbb\x7f\xf1\xc6\xff\xa6\xdc\x2d\x80\x1b\x08\x02\xb9\x3c\xf9\x3c\x9a\xd6\x04\x97\x1c\xd8\xbb\xd3\x20\xc0\x7f\x39\x7b\x88\x54\x12\x34\xc7\xe4\x8d\xae\xca\x12\x34\x11\x29\x11\xc2\xf4\x5b\x7b\x29\x4e\x95\xf4\x7c\xca\x5e\xd7\x65\x1c\x22\x65\x31\x8b\xb5\x53\x6e\x7d\x3a\x4e\x29\x9b\x67\x4f\xc6\x84\x30\x8e\x19\xc2\x01\x0f\xbc\x52\xdb\xf4\x8a\x5c\x45\xcc\x71\xe2\xe5\x87\xd3\x01\x2f\x79\x7d\xea\x96\xd6\xdb\x93\xac\x65\xd9\x02\x98\x31\x3d\x5e\x77\x04\x89\xe8\x5c\xfd\xcf\x5f\xd1\xeb\xb0\x58\x58\x8e\x5f\xd9\x9e\x7c\xa8\x8b\x04\xa1\x2c\xce\xb8\x44\xe3\xb7\xa8\xda\x16\xea\xcf\xdb\xfc\x1d\xee\x46\xcf\x9d\xe9\x0c\xb4\xcb\x70\xb9\x34\xdb\x79\x8f\x3c\x96\x71\xaa\x70\xb5\xdc\xfd\x63\xdf\xe3\xa1\x58\x2c\x59\x88\xe3\x21\x4f\xed\x2b\xd4\xfb\xd3\xe0\x51\xc4\xd2\x28\xa7\x7e\x0a\xb9\xae\xfe\x9e\xab\x1b\x2b\x95\x22\x58\x66\xfb\xf8\xd7\xa3\xa0\x23\xa9\x3d\xf9\x6c\xf5\xe1\x2a\xaa\xe7\xc5\x49\x2c\xd6\x29\xb7\xc4\x16\xff\x79\x53\xd5\xae\xf0\xf2\xc2\x70\x69\x99\x79\x91\xe3\xbb\x3f\x6f\x27\xb5\x8e\xbe\x87\x8d\xd1\xab\x73\xe7\xb9\xce\xe5\xa1\xea\xf7\x8a\xd8\x80\x8a\xdc\x2d\x6d\x89\x47\xcf\xe6\x6d\x73\x26\x77\xc8\x62\x63\x23\x44\x91\x3b\x1e\x07\xbc\xf9\xaa\x28\x86\xc7\x18\x70\xa2\xee\x08\x08\xb4\x71\x79\xe7\xba\x9d\x6c\xfd\x31\x64\x31\x62\xa1\x10\x39\xb3\x2c\xe4\x87\xea\x6b\xcf\x59\x0c\x26\xf1\xb5\x12\xbf\x20\x9f\x7d\x83\x36\x30\x58\xfa\x51\xc2\x07\xda\x66\xe3\xdd\x2d\x89\x34\x47\x86\xab\xfd\x88\x54\x05\xe4\xe1\x2b\x40\x94\x25\x91\x49\x71\x37\x5d\x3f\xae\x77\xfb\xeb\xc5\xce\xef\x08\x49\x9c\xda\x20\x18\x40\x83\xcd\xe2\xa3\x57\x68\x22\x33\x7d\x57\x1d\xc3\x34\x18\xd9\x0a\x49\x2c\x02\x74\x81\x1f\x64\x99\x5b\x68\xda\x6a\x84\x34\x64\x49\x6c\x23\x9d\x39\xf6\xee\x6b\xb0\x75\xd5\x87\xce\x92\x04\x00\x0d\x00\x2f\xa4\xbd\x7a\xbc\x9e\xdc\x0b\xcb\x98\x17\xce\xdc\x40\xdd\xe4\xb2\x6c\x9c\x59\x5d\xe5\x7d\x49\x44\xd7\x8d\xbc\xa1\x7d\x4d\xd5\xa1\x8b\xff\x3d\xc9\x3a\x3f\x1d\x66\x8f\xcc\x74\x98\x79\x21\x42\x7a\x89\x33\x7b\x2d\xe1\x59\x86\xdb\x25\x86\x92\xba\x2d\xaf\xbf\x84\x08\x29\x07\x75\x8b\xe9\xd5\xc9\xa0\x67\x8c\x34\xfd\xdc\xa9\xee\x7f\xec\xb6\x7d\x0e\x8c\x25\x32\xc8\x38\x05\x45\x6c\x35\xc1\xf8\xb2\x44\x5a\x85\x36\xf6\x28\xa4\x72\x7e\x9a\x27\x2a\xc8\x0c\x61\xa0\xdf\xab\x37\xb8\x91\x45\x81\xf3\x65\x7a\xf3\x4a\x19\xd4\xac\x71\x65\x84\x03\x5f\x26\x4b\x74\x98\xa2\x83\xf0\x67\x21\x9b\x26\xd7\xbd\x2c\x7d\xd7\x02\xbc\xc7\x09\xdf\x54\xf5\x9c\xf2\x75\x7a\x09\x9d\x64\x41\xea\xc8\x07\x48\x87\xa4\x71\x55\x67\x97\x0e\xc8\x62\x8c\xfc\x3b\x89\xc8\xea\xe8\x58\x6f\xf6\x0a\x4a\xb0\xb9\xce\x65\xef\xf7\x27\x26\x49\x2c\x39\x3e\xf2\x70\x4f\xe4\x13\xb4\xe2\x86\xd1\x43\x55\xb6\xaf\xfd\xbb\x30\x5a\xa0\x69\x5a\x95\xcb\xea\x70\x84\xb2\x91\x67\x38\x10\x5d\x5f\x88\xa8\x22\x1a\xb3\x3c\xba\x38\x99\x79\x54\x37\x01\x21\xf1\x2b\xed\x66\x45\xcf\x52\xb1\x91\x75\xbb\xfb\xa8\xe6\x5d\x41\xab\xde\xc6\xa5\x08\x87\xab\x43\x18\xe8\x0f\x58\xd2\x2d\x38\xce\xee\xb8\xde\x6e\xa6\x70\x1f\x96\x58\x9b\x60\xa4\x4a\x57\x65\x03\x03\xbf\xa5\xc3\x9a\x74\xed\x82\x09\x5f\x28\xf5\x0e\x75\x9b\x77\x1f\xe1\x59\xa6\x07\x96\x06\x41\x82\x11\xd2\x53\x79\x94\x7d\x11\xb7\x5f\x8f\xce\xe7\xef\x58\x1a\x30\x1b\x39\xf8\xc5\x40\x95\x10\x4c\xe2\x04\x28\xff\xc6\x5d\x4c\xfb\x8b\xea\x39\x4b\x03\x57\x45\x4f\xb4\xcb\xa7\xc3\xbe\xfd\x80\xe2\x1d\xf6\x4a\xbe\xbc\xf4\x1b\x4a\x1a\x28\x85\x69\xa7\x46\x5a\x68\x3f\xd7\xe5\xbb\xac\x73\x59\x3a\x35\xa5\xe9\x3d\x85\x9c\xa3\xcb\xbf\x7a\x5e\x8a\x88\x3b\x25\xac\xfe\x44\xa1\x26\x5d\x6d\x69\xcc\xbe\xe8\x6c\x8f\xa9\xdb\xe6\x7a\x45\x9a\x08\x76\xbd\x07\xb2\xe9\x26\x72\xef\x06\x0f\xbe\x9d\xef\x6e\x34\x96\x6d\x6c\x9f\x6e\x76\xfb\xe5\x62\xe3\x2f\x96\x84\x91\x4a\x7b\x9f\x6d\x82\x41\xed\x1a\xa9\xc2\xb6\x96\x79\x03\x66\xad\xab\x91\xe6\x1c\x4b\x93\xcc\x72\x27\x24\x59\xbd\x0d\xbf\x2a\xa3\xba\x45\xec\x6e\x7d\xb5\xf0\xbf\xa5\x26\xf0\xd3\x12\x31\x61\x43\xba\x20\x4d\x21\xc4\x6c\x44\x53\xe4\xba\x77\x53\xbf\xc2\x21\x59\x9a\x5a\x7a\xde\x2b\x84\xaa\xf4\x87\x5b\x22\xdf\xa0\xc8\x50\xb7\x82\xdf\x9c\x8a\x02\x2b\x0c\xce\x26\x09\x52\x26\xd2\x40\xba\x34\xeb\xb6\x95\xdd\x67\xb7\x3a\x56\xfa\xd5\x9f\x90\x41\x66\x29\x86\xb8\x2e\x3b\x03\xfb\xa1\x32\xfd\xbd\x72\xa6\x8c\xed\x61\x9d\x27\xf8\x63\xfc\x3e\xb8\x04\x2c\x67\x03\x62\x0f\xbb\x58\xd7\xc4\x52\xae\x33\x2c\xb1\xd3\xb4\xa7\x4e\xd7\xb5\x54\x84\x29\xba\x58\xba\xae\x9a\xe6\xa6\xaa\xdf\xc6\x8a\xdc\xfe\x4e\x84\xb0\x18\x55\x34\xe0\xa3\x3e\xa9\x0c\x63\xcc\x4b\xa2\x8a\x96\x6c\x50\x3e\xa9\x6f\x8b\x09\xbd\xbe\x04\x6b\x3f\x8b\xf1\x72\x9e\x4a\xe0\x68\x09\x7a\x2c\xde\x96\x40\x77\x97\x6b\xc1\x59\xaa\x62\x8b\xc9\x3f\x4f\x16\xbe\x28\xcd\xf6\x38\x2e\xaf\x3d\x6b\xa2\xa5\x2a\xd1\x19\xb1\x9e\x63\xd2\x07\x0c\xc2\x14\x7a\x42\x30\x96\xaa\x8c\xd8\x74\x9c\x18\xf5\xf5\x28\x41\x38\xbb\x01\x0d\xb8\x0e\xf8\x4f\xdf\xa9\x0d\x19\x62\x0f\x9b\xf5\x05\x86\x31\x02\x47\xc4\x7f\x5f\xcd\x4a\x3e\x58\xaa\xa3\xbe\xae\xe0\x87\x2f\x03\x38\xef\x40\xa5\x3a\x52\x49\x30\x0e\xf9\x63\x21\x92\x43\x26\xfa\x3e\xb1\xc4\xca\x20\x2d\x0b\x4d\x56\xfc\xe2\xa2\x4c\x84\x3f\x44\x09\xf4\xd2\xb7\xa5\xcc\x8b\xbf\x27\xa0\xcc\x52\x13\x08\x2c\xf0\x5c\xca\xfa\x98\x57\xfe\xea\x46\x0b\x24\x72\xd7\xde\x41\x77\x69\xe2\xc1\x26\x4e\x8d\xb1\x91\x53\x80\xd9\xe5\x47\xdc\x04\x9d\x7f\x33\x7b\x5a\x08\xa5\x57\x58\xbe\xad\x0a\x73\xc8\xcb\xf6\x06\xc0\x2b\x7c\x4d\x6e\xc6\x76\x96\xf1\x10\x0e\xa5\x32\xdb\x4b\xf3\x61\xf6\xf4\x36\x0b\x88\xcd\x0e\x79\x13\x47\x11\x28\x36\x42\x0e\xb0\xd4\xda\x84\x80\x1e\xc8\xf8\xff\x98\xf7\x06\x24\x0b\xb8\x46\x6a\xbd\xc5\xc3\xfd\x7e\x77\xf7\xbc\xda\xde\x3d\xf9\x7a\x56\xc6\x02\x91\x50\x8c\x92\x6a\x87\xcf\x24\x3a\x59\x60\x08\xcf\xd7\x7c\xe4\xad\x7e\x7d\xd8\x3c\x9d\xdf\xdd\x59\x98\x4a\x42\x68\xe4\x8d\xe3\xb8\x3a\xff\x81\xb0\xd0\xa6\x48\x1e\xdb\x78\x9d\xae\xe6\x4e\xbe\xc3\x15\x40\x49\x35\xc0\xfe\xde\xa2\x48\x07\xb6\xbf\xb7\xeb\xaa\x9c\x15\x6a\x30\x16\x65\x06\x09\x55\x50\x32\xe3\x0a\xdd\xc3\xf1\xa2\xc3\xa2\x0c\xd0\x62\xf4\xa8\x9c\xee\x2b\xf6\xe4\x63\xc3\xfd\x44\x92\x63\xca\x90\x26\xf7\x8f\xe3\x4b\x2d\xfb\x45\x8d\x45\x86\xd8\xf3\x9e\x7e\x3d\xae\x9e\xf7\xdb\x1f\x9b\xcd\xfd\x7f\xf7\x6d\x60\x31\x69\xd6\x0b\x35\x91\x8a\xc3\x2c\xcd\xd8\x39\xb0\xe0\xa0\x47\xa7\x63\x2f\xd5\xe1\x1b\x8d\xc6\x05\xf7\xe9\x71\xb5\xff\xaf\x1f\xeb\xc7\xdd\xfa\xfe\x7e\xfd\xf4\xe8\x9b\x93\x24\xc0\xc5\x64\x71\xfd\xb0\x7e\xdc\xdf\xae\x76\xfb\x1f\xdb\xeb\xd9\xfd\xa7\x9c\x6a\xf0\x4b\xf8\xdd\x6e\x01\xb0\x46\xf6\xca\x9f\x80\x05\x12\x17\xec\x46\xbf\x02\xaa\xeb\x7e\x2d\x27\xec\x4d\x77\xc6\x13\x81\xaa\xe3\x57\xd0\x12\x4f\xed\x63\xe5\x70\x6b\x98\xef\x3c\xff\x3a\x79\x42\x82\xc9\x87\xbc\xdc\xf4\x3b\x0f\x13\x09\x71\x11\x60\x2d\xd9\x94\xe6\x6e\x76\xbc\x00\x8b\x99\x8e\xcd\x7a\xbf\xba\x5e\xef\xf6\x1e\x68\xc2\x32\xb7\x90\x1e\xbb\x57\xb7\x8f\xf6\xb5\xe7\x0f\xf3\xec\xe5\xae\x9f\x0c\x80\xe6\x53\xe7\x59\x0d\x85\xb7\x8c\xc9\x88\x85\x2e\xa9\xb9\x3d\xd6\x20\x67\x4e\x1c\x93\x71\x34\x90\xbf\xef\x5e\xeb\xaa\x9c\x66\xf3\x98\xcc\x12\xb4\x59\xa0\xd6\x51\xb0\x5a\xde\xed\x46\x44\x2f\x8c\x49\x09\x2c\xed\x53\x53\x77\x55\x61\x2e\x00\x4d\x98\xb4\x20\x5d\x46\xe2\xa9\x46\xa1\x2b\xb8\x01\xf8\x95\x97\xa6\xfa\xb8\xfa\xbc\xb0\x9c\x32\x0d\x1c\x3f\xa8\xf5\x4b\x99\x0f\x13\xc6\x08\xca\x5f\x75\x0f\xb5\xbb\xfd\xae\xb8\x88\x31\xa3\x8c\x4e\xa7\xa4\x51\x77\x79\xd3\x56\xf5\xe7\x98\x40\x83\x31\x63\x88\xb7\xa0\xa8\xf4\xdb\x4d\x5d\x1d\xb6\x50\xd8\xd9\x1a\xeb\x7b\x82\x12\xc1\x90\x8e\x2b\x3b\x5b\x76\x7a\x4d\x60\xc2\x7a\xbe\xb1\x9b\xbc\x6e\xda\xc9\x17\x09\x3c\x8d\x92\x9e\xd6\x9d\x12\xd4\x33\xae\x04\xc6\x2c\x97\xb8\x81\xe5\xcd\xaa\x8f\x93\xf7\xc3\xc2\x83\x20\x8b\x87\x5b\x18\xb1\xec\xf8\x76\x49\x09\xde\x13\x6a\xcb\x4d\x92\x49\x3c\x90\x19\x8a\xe4\xda\xba\x2a\x5b\x1a\x7f\xdf\x14\x46\x14\x28\x7e\x91\xa4\x5d\xef\x7d\x1f\xd7\x1c\x85\xca\x87\x2b\x1e\x72\x5f\x8c\x74\x53\xd5\x67\x58\x2f\x18\x8f\x52\x12\x13\x54\x79\xdb\x7c\xe4\x76\x38\x89\x4a\xb0\x84\xb8\x1b\x9b\xdd\x84\xf9\xd2\x77\xd0\x16\xad\x14\xd5\x83\x7f\x4f\x04\x24\x77\xed\xb1\x50\x98\x82\x3e\x52\x80\x75\x43\x3c\x13\xfe\xe8\x58\x72\x64\x35\xec\x77\xb7\x51\x32\x84\xc7\xc6\xa0\xaa\xd8\xab\x6c\x16\xc4\x84\x7f\x07\x4e\x01\x33\x9c\xd9\x22\x3c\x01\x4e\x88\xef\x4a\xbf\xa1\x4a\x92\xcc\xbf\xca\x48\xbb\xbe\x69\xc4\x91\xeb\xbb\x17\x53\x82\x6e\xcf\xd4\x55\x7d\x9c\x2a\xcb\xfb\xee\x69\x80\x06\xed\x1e\xe3\x3e\xce\x50\x3c\xbb\x30\xf0\x94\x2b\x1c\x8c\xe7\x4a\x13\xcc\x74\x62\x9a\xf1\x34\x0b\x24\xe6\xb9\x64\xab\x5f\x77\xb8\x66\xfb\x18\x79\x18\xfe\x6b\x14\x27\x1f\xfe\x4f\xfc\x33\xfa\xd7\x88\xdd\xe8\xcb\xff\xb8\x33\xb3\x90\xe8\x43\x8e\xa7\x82\xd8\xfe\xba\x6f\x62\xb6\xaa\x73\x1e\x66\xb8\xc0\x79\xcb\x70\xa2\x3d\x78\xde\xc6\xe3\x59\x18\x47\x03\xbc\x8b\x80\x0e\x7f\x69\xca\xf0\x2c\x94\xc6\x93\x9c\xbf\xca\x19\xe2\x91\x71\xc9\xb9\xe9\x96\xbf\xc5\xf3\x2e\x9c\x0d\xb6\x94\x51\xca\x47\xfb\xdf\x66\xa6\x0e\xcb\xb8\x0a\x25\x62\x84\x7d\xbe\x00\x1f\xf7\xa9\x2c\x3e\x47\x34\x46\x8c\x2b\x16\x20\x0e\xbe\xdb\x61\x36\x75\x7e\x80\xf9\x59\x78\x48\x12\x0b\xae\x24\x75\x72\xfb\x4a\x86\x68\xfc\xbc\xe5\x45\xe1\xa0\x16\xae\x45\x47\x02\xa9\x72\x7e\xe6\xad\x2c\xee\xab\x97\x97\x9e\x5a\x93\x71\x2d\x62\x8c\x48\xa1\xbf\xb9\xdf\xc8\xdc\xec\x9f\x4e\xc3\x91\x2a\x4e\xa9\x1c\x09\x4c\x38\xbb\x19\x93\x50\x95\xba\x03\x3f\xfe\xa8\xf3\x79\x87\x34\xf0\x3e\x1d\xd4\x35\xd4\x03\xd2\x7e\xba\x90\x74\x76\x4f\x4a\xea\x6b\x17\x66\xa8\x11\xc4\x0b\x89\x90\xe6\x3d\x1a\x7e\xc3\xa0\x75\x86\x64\x40\x7a\xa1\xfa\x6d\xbd\x7c\xea\x8c\x98\x81\xb0\x92\x71\x88\x02\x44\x1f\xe6\xe5\xbf\x41\xb7\xfd\x3c\x5b\xeb\xaa\xef\x91\x2a\xcc\xfc\x61\xc1\xa7\x07\x5f\x91\x82\xe2\xf4\x3e\x6c\x02\x96\xd4\x98\x3b\xdf\xea\x7b\xac\x18\xb7\x42\xe1\x26\x4f\xc6\x8a\xbf\x96\x95\xe4\xbc\x79\xee\x94\x73\xb8\x8d\xb9\x99\x3e\x5a\xd8\x45\x10\xa7\x58\xd4\xb4\x7c\x7a\x78\x58\x6f\xb7\xeb\xa7\xc7\xfd\xf5\xfa\xe7\xfa\xda\xb3\x6b\x32\x11\xc6\xca\xef\xc6\xba\xba\xf0\xcd\x8b\x90\xa5\x98\x0a\x3f\xba\x0a\x55\x5c\x8a\xa1\x9e\x3d\xb0\x08\x6d\xe6\x08\xe1\x9a\xd3\x01\xbe\x2a\xb0\x31\x11\xc5\x92\x11\xe4\xfa\x54\x97\xb2\x5b\xac\x1d\x67\x58\xdf\x41\x07\x68\x30\x1f\x73\xd0\xf0\x4b\x8e\x0c\x4f\x11\x19\x19\x03\xcd\xae\x06\xf9\xa1\xfc\xef\x20\x89\x22\xc8\xe6\x2f\xed\xeb\xaa\x84\xc3\x6c\xf3\x13\x71\x92\x62\xee\x67\xf5\xe4\xf1\x46\x22\x09\x03\x14\x32\x81\x43\xde\xf6\x95\x2b\x97\x46\x74\xfa\x94\x89\xd6\xd2\x81\x63\xae\x91\xc0\x1e\x9a\x5d\xb5\xad\x0a\x5f\xf4\xcd\x44\xea\x54\x8f\x47\xe5\xd9\xb3\x91\x62\x42\x52\x0d\xde\x2b\xf4\x48\x00\xdf\xe4\xb8\x14\x36\x55\xd3\xcc\x56\x37\xc1\x74\x86\xc2\x60\xc4\xaf\x71\x5f\x49\x1f\xdb\x5a\xb4\xa8\x23\x76\xf5\x79\x55\xd5\x75\xf5\x65\xeb\x13\xcc\x08\x64\x5d\x7e\xad\x0a\xd3\xd9\x8d\xf2\x37\x66\xfe\xdf\x65\xd1\x9f\x1a\x12\x2c\xd9\xdb\xde\x2d\xa2\x94\x55\x76\x51\x63\xa9\x83\x6f\x16\x69\x84\xfb\xf0\x3e\x6f\x96\x30\x43\xc5\x08\x91\x72\x84\xa0\x22\xef\xcf\x3e\xde\x6f\x77\x8b\xe7\x5d\x7f\x64\x46\xf5\x1b\x2f\x45\xa5\x64\xb1\x7c\xed\x6e\xfd\xb1\xea\x5b\x65\xcc\x3c\x7a\xcf\xff\x96\xc5\xc4\x51\xd9\xbd\xe4\x6e\x04\x30\x4e\x76\xa9\x38\xf0\xec\xf6\x27\x32\x21\x10\xa4\xfa\xbc\xa1\xa0\x35\x42\x66\x9d\x9f\xb0\xbf\x5f\x3f\xac\xfb\xdb\xcb\xb4\x64\xa1\x0b\x97\x36\x38\x28\x07\x30\xb9\x6c\xe1\xb6\xaa\x4c\xb7\x8b\x5c\x43\xe7\x19\x9c\xfb\xe0\xce\xb9\xf9\x22\x33\x29\x46\x16\x5f\x65\x3f\xa7\x33\x43\xe0\xeb\x1b\x40\xe9\x52\x30\x84\x40\x45\xc1\x13\xe1\x7c\xc7\x91\x05\x2b\x64\xe0\x38\xa2\x9d\x2d\x82\xfa\x7d\x7b\x24\x5c\xdb\xbf\xc8\x0b\x01\x1a\xa1\x99\x44\x8f\xf4\xd0\xea\xce\xc1\xef\x95\xe1\x98\xd0\x3a\xc0\x19\x85\xa2\xc7\x24\xe4\x3a\x3b\xd4\x12\xd0\x1f\x4b\x1d\x1c\x7b\x63\xff\xd9\x99\x50\x04\x99\xe7\x61\xef\x4c\xfd\xa1\xc1\x24\xa3\xda\x81\x75\xb9\xa8\x6b\x39\xff\xf4\x20\x4c\xcd\xf0\x29\x18\xe7\x87\x37\xf3\x5e\x51\x88\x83\x76\x83\x90\xbb\x7b\xca\xab\xf9\xeb\x00\xb7\x08\xd0\xc6\x44\xab\x6c\x30\xe6\xdf\xb7\x89\x34\xed\xf9\x2a\x5f\xf2\xaa\x7c\xea\xe5\x2d\xc2\x0b\xae\xbb\x00\xc1\x99\x93\x60\xbe\x2a\xbf\x28\x47\x8c\x37\x49\x01\x86\xc8\xbd\x9c\x76\xc1\x76\x6e\xb9\x66\x01\xa3\xc7\xf3\xd1\x88\xea\x2f\xad\x87\x99\x7e\x29\xcb\xc2\x84\xa3\x65\x7e\xa8\xca\xf6\x95\x6a\x81\x87\x0d\x37\x8b\x98\xc2\x07\x7c\x96\xd6\x16\x70\xdd\x8b\x38\xb2\x2c\xd2\x22\xf3\x52\x4c\x18\xe9\xf4\x0d\x71\xa4\x09\xa3\x56\x15\xb9\xce\x5b\xb9\x91\x2f\xb8\xd2\xfa\x6f\x2e\x4b\x0c\xc5\x3d\x6c\x5d\x1d\x70\x12\xee\xaa\x2b\x7a\xfa\xb1\x53\x90\xa5\xa0\x31\x5c\x77\x57\x95\xd0\xb4\x77\x30\x98\xb4\x19\x93\x4c\x9a\x1e\x4f\x79\xd6\xaa\xca\x78\x44\x24\x8b\x87\x53\xf1\x87\x2b\xbb\x1c\x1b\xcd\x19\x4f\x08\x06\x44\x6b\x59\xf7\x52\x6f\xaa\x7a\xd9\x39\xc9\x43\x9a\x2d\xe3\xa9\xc1\x02\x10\x92\x53\xdc\x96\xf2\xcd\x21\x33\xfa\x0e\x56\xa3\xb1\xb2\x79\xda\xed\xaf\x9f\x17\xeb\xc7\x31\x72\x22\x13\x91\xe6\xd6\xfb\xf8\xfb\x5a\x5e\x60\x59\x65\x99\x48\x02\xac\x4a\x5c\xfd\xd7\x8f\xef\xd2\xa3\x59\x16\x45\x89\xc3\x2e\x8d\xd0\x94\xfd\x74\xc8\xa2\x04\x93\xef\xb7\x84\x44\x70\x40\x2f\x73\x21\xca\x9f\x65\x89\xd1\x64\x4a\x1f\x64\x79\x2f\xcb\xe6\xad\xfa\xb7\x3f\x95\x8c\x49\xcb\x47\xfb\x44\xd2\x39\xc7\x2f\x93\x22\x0c\x1c\x1e\x71\xfb\xa6\x17\xa6\xbb\x99\xd9\xc7\x95\xa9\xb4\x0f\x15\x0e\xb4\xec\xf3\xe8\xd6\xec\x10\x99\xa0\x31\x72\x3c\xa9\x22\x6f\x5e\x1f\xa0\x95\xb8\xe3\x7e\x91\x59\x41\xd6\x20\x77\x90\x0e\x04\xee\x7a\x57\xb2\x81\xad\xb3\x57\xbe\xe7\x80\x65\x99\x8e\x42\x84\xcb\x39\x13\xd5\x33\x46\x9d\xcd\xa4\x64\xc0\x0d\xa7\x60\x71\x69\xaa\xaf\x04\x82\xe7\xaf\x00\x99\xf2\x8a\x65\xdb\x56\xb6\xb9\x5e\x15\x18\x04\x9d\x29\x6a\xb3\x0c\x64\x08\x14\x53\x2e\x61\x7b\xcc\xeb\xbc\x5d\x0e\x7b\x52\x06\x9a\x79\xaa\xd5\xab\xe3\x24\xce\xec\x3b\x40\x8a\xa4\xf3\xb7\x57\x8f\xcb\xf3\x1c\xef\xe3\x35\x3e\x03\x2b\x90\x63\x4a\x4d\x32\xc7\x99\x4d\x25\x72\xe5\x61\x68\xe0\x47\x03\x13\x5d\x74\x96\xd9\x2c\xe4\xc6\x6b\x10\x34\xbb\xea\x1c\x5e\x7f\x3a\x41\xac\x04\xf4\x6d\x5e\x65\xf3\x7a\x89\xd3\xfe\x3f\xce\x64\x2e\x64\x20\xc3\x30\xf3\x69\xd6\x51\x75\xa9\x9f\xeb\x32\x8c\x2c\x8b\x47\x94\xd3\x0f\x58\x76\xf8\x20\xdf\xbe\x51\x67\x98\x0c\x99\x8c\x54\x88\x6e\xff\xf6\x69\xf9\x8f\x2d\x94\xed\xae\x5a\xed\xee\xfc\xe9\xe3\x28\x41\xe8\x90\x3d\x95\xa6\x2f\xd6\x91\x09\x23\xdb\x7b\x52\x89\xe3\xdb\x04\xc1\xa4\xa4\xd2\xdd\x0e\x52\x0d\xd9\xff\xfe\xe8\x2c\x93\x24\x24\x51\x1d\x3a\xbb\x6d\xf3\x73\xe3\x00\x1a\x8b\x53\x7d\x5e\x73\x8d\xc9\x44\x12\x1d\xc2\x6d\xf5\x22\x27\x8b\xbf\x4c\x03\x22\xec\xbc\x3b\xc9\xf2\xee\x94\x8f\xdd\x60\x99\x66\x21\x67\x7d\x86\xde\x2c\xab\x1a\x26\xe9\x39\x99\x3a\x9d\x14\xcf\xa6\x32\x83\x17\x49\x96\x32\x4f\x88\xda\xbd\x65\xfc\xfc\xa6\x37\xc6\xb3\x24\x20\x38\xa6\xae\xab\x63\x55\xe4\x73\x73\x51\x72\x95\x44\x7d\x69\xd0\xae\x3a\xc8\xb6\xea\xb3\xe5\x52\x64\x31\x0e\xe5\xea\x1f\xcb\xbb\xc5\xe3\xed\x6a\x3f\xf8\x08\xbe\x4b\xc6\x00\xad\xa8\xab\xd3\xe7\x52\xd6\x3e\x46\x7a\x21\x80\x2c\x33\x20\xd9\x85\xce\x92\x5a\x0c\x99\x7f\xa9\x4c\x02\xe3\xd2\xfd\x3d\x0a\xf0\xfa\x56\x1d\x25\x66\x08\x27\x6f\x28\x6a\x00\x53\xaa\x2d\x26\x75\x92\x89\xc4\x83\xd9\x7a\xf9\x35\x5f\x92\xe8\x3b\x31\xe2\x46\x6f\xa0\xed\xdd\xff\x39\x3a\x5a\x6a\xa9\x90\xbd\x00\xa3\x31\x9e\x8b\xdd\xb7\x69\xe2\xcb\xe9\x8b\xac\x46\x39\x47\xa9\x4d\x16\x13\x1b\xcc\xe7\xf5\x62\xb3\xf9\x3e\xa6\x20\x4d\xc2\x1d\x61\x5e\x93\xbf\xd0\x1d\xeb\xca\xcc\xe3\x2e\xd2\xa4\x44\x34\x76\x94\x9f\x58\x12\x33\x50\x37\x4c\xf3\xa1\x5f\xf1\x85\xfd\xd0\x18\x13\x50\xee\xaf\xcc\xc7\xcc\x80\x4c\x1a\x08\x11\x24\x52\x56\x6d\x6e\x3f\x8b\xf7\x82\xa0\xfc\xcd\x39\x54\xaa\x84\x2c\xc0\x10\xd6\xcd\xa9\x3d\xd5\xe3\x28\x83\x04\x95\x60\xb2\x12\xa3\xad\x3f\x17\xcf\x8b\x71\xb4\x55\x02\x68\xe4\xf4\x5f\xde\x2d\x76\xbd\x66\x03\x93\x36\x66\x49\x3c\x7d\x15\xb2\xd8\x7d\x09\x51\x48\x6b\x22\x44\xfe\x14\x79\xe3\x59\x2c\xdd\x29\x54\x00\x12\x9b\xb6\x0f\xeb\xfb\xd5\xdd\x6a\xf0\x28\x54\x60\x39\x5e\x33\x47\xbd\x23\x54\xfe\x98\x0c\x89\x0a\x05\x39\xde\x96\xdc\xd4\xfe\x0e\x54\x01\x58\x74\xef\xd1\xf4\x2a\x04\x0a\x58\x50\xee\x6e\x3d\x06\xd7\xaa\x28\x0a\x03\xed\xa2\xaf\x18\x27\x1f\xb5\xc5\x11\xf1\x94\xfa\x80\x9f\x2f\x2f\xfe\x82\x0b\xf5\xfd\x53\x02\x1f\xe6\x4d\x4f\x76\x78\x81\x79\x86\xa9\xd8\xc4\x98\xfa\x7f\xcf\xe1\x23\xf1\x40\x49\x95\x44\x29\xc6\x7a\x4c\xb5\xcd\xcb\x97\x02\x06\x20\xd3\x64\x40\x55\x9a\x12\x70\xc0\x91\x01\xce\x5b\xb9\xce\x60\xc4\xba\x78\x9f\x37\x5f\x84\x46\xa6\x77\x93\x72\xc0\x42\x62\x5f\x96\xfa\xab\xaa\xdf\x88\x5f\x63\x0a\x49\x3f\x67\x2d\x29\x1e\xc4\x11\x09\x0e\x96\xad\x2c\x16\x5a\x9f\x0e\x08\xed\x37\xe3\x79\xaa\x38\x70\x54\x74\x6d\xab\xe7\xfb\x0d\x16\xc6\x8e\xac\x50\xc5\x81\xca\xe5\xb7\xb7\x3b\x5f\x66\x42\x4c\x39\xdf\xee\x2d\x4a\xe8\x98\xd8\x79\xf6\x9a\x4a\x57\x72\x68\x30\xc4\xdf\xe3\x6e\x55\x66\x52\x0e\x8e\xb2\x01\xea\x96\x94\xb8\x77\xd5\xd7\x95\x56\xc9\x50\x62\x42\xeb\x71\xfd\x70\xb3\x40\x0a\xe2\xd5\xee\x0e\x99\x6e\xfd\xb9\x24\x0b\x30\x5f\xd4\x4d\x96\xb9\x6a\x21\x53\xd2\x5a\x5f\xfa\x70\x9d\x5b\x9b\xeb\x53\xd1\xfa\x8d\x40\xa9\x98\xf2\x44\x1e\xb3\x06\x6d\x6e\x73\xfd\x95\xcc\xb0\xeb\x49\x8c\xa5\xa8\xe5\x39\x66\xd1\x1d\xe6\xdb\xb0\x4a\xf8\x63\xa4\x48\x98\x5b\x94\x69\xf7\xba\xa9\xea\xeb\xa1\xe6\xe4\x7b\xe8\xa0\x52\xd2\xe2\xc7\x3f\xe2\xae\xab\xca\x31\xb7\x20\x53\x4a\xdb\x94\x4c\xf4\x52\xbf\x1e\x64\xfd\x46\x1c\xa6\xbe\x59\xdb\x38\xf5\x61\x52\x28\x1b\x84\x6b\x8e\xf9\x86\x98\x32\xae\xf4\x07\xc5\xa8\xd0\x89\xeb\xf3\xd2\xca\x00\xd5\x7b\x3d\xc8\x97\x52\x52\x98\xd5\xb5\x40\x18\x09\x57\x5b\xb5\x79\xad\xda\x19\x0c\x48\x81\x4a\x70\xf1\x7b\x3c\xbd\xbc\x40\xdb\x4c\xee\xd8\x86\x04\xa2\xc4\xdc\x70\x55\xbb\x20\x0e\x3d\x22\x32\xa8\xce\xa2\x27\xca\xc6\x4a\x79\xe9\xb2\x42\x6a\xa4\xce\x21\x47\x6f\xfa\x82\x2c\x27\x4e\x17\x5d\xfc\x1f\x4b\x26\x60\x7e\x1d\xa4\x11\xb2\x44\xa8\x53\x5d\x4e\xc8\x41\xa6\x03\xae\x83\x94\x84\xe5\x6a\x68\x3a\xff\xe2\x8f\x69\x23\x68\x34\x1a\xef\xab\x17\xa7\xb3\x78\xfe\x24\xa1\x56\x58\x41\xe4\x77\xdc\x9b\xba\x3a\x74\x8b\xe0\xb2\x3a\x1c\xce\xe0\xc0\xce\x5a\x8e\x3a\x04\x29\x4d\x8f\xb1\xc1\x8c\x46\xbf\xd5\xea\x28\x26\xb1\x15\x4c\xee\xcd\xd6\x0c\x1d\xf1\x0c\xc0\x4b\x7b\x1f\x4f\xed\xf6\x62\x39\xbb\x8e\x23\xc3\xc3\x3e\x49\xe8\xe4\x6f\x46\xc9\x42\x1d\x73\x48\x47\x76\x72\xf3\x9c\x37\x6f\xba\xca\xe7\x55\x74\x3a\xce\x04\x5a\xc6\x9e\x85\xef\x4e\xd6\x4b\x39\x0b\xab\xeb\x18\x04\xa6\xee\x72\x27\x38\x4e\x08\x43\x59\x50\xbd\xf3\x05\x26\x3a\xa6\x93\x44\xa1\x74\xc4\xff\x74\xde\xa9\xbf\xb1\x84\x1b\xe9\xbc\xaa\xed\xe9\x08\xf5\x41\xce\x3e\x57\x9d\x18\x89\xae\xbb\x34\xe6\x27\x55\x32\x3c\x8f\x98\xb0\xbe\xff\xf0\x74\x2a\xa2\xd8\xd9\x8f\x43\x48\x63\x4a\x59\xc4\x34\x03\x6d\xfa\x75\x45\x16\x71\x2f\x3c\xe3\x76\x67\xcd\x05\xe9\x3f\xdf\x41\x51\xc8\x2b\x59\x7a\xbf\x5a\x0b\x91\x21\x0c\xdd\x2f\xeb\x38\xf9\x47\x05\xb7\x3a\xb3\x9c\x80\x1a\x6e\x77\xc0\xb5\xf3\x0c\xed\xad\xeb\x2e\x05\x45\x00\x3b\xc7\x44\xd6\x17\x95\xa6\xbf\x8f\xac\x6a\x29\x08\x63\xb4\x84\xee\xa2\x45\xf1\xb9\x6e\x9a\x93\xe7\x4e\x3d\xbf\xdf\x7c\x7f\x42\x15\x73\x7c\x4c\xdd\xb9\x01\xba\x5d\x7c\x89\x3c\x69\x95\x04\xa9\x1a\x49\xd5\x4a\x3d\xec\x10\x5a\xa5\x54\xf7\xff\x78\x33\x5e\x3f\xb4\xe2\x16\x11\xb1\xdd\x78\x35\x23\x3d\x4b\xa6\x95\xa4\xad\xac\x06\x5d\xbd\x43\x3d\xd0\x3a\x5d\x08\xda\x69\xad\x29\xd4\xd7\x19\x89\x3f\xc7\xac\x36\x67\x58\x2b\x2e\x94\x38\x69\x0d\x29\xea\x3c\x39\x88\xd2\x6c\xce\x9b\x80\x8a\xc4\x46\x7a\xe9\x74\x47\x4f\xbd\x58\xdb\x97\x23\x94\x70\x08\x9a\x0d\xd4\x4d\x55\xca\x62\xe0\xf7\xf6\x7d\xb4\x40\xbf\xfd\x20\xf3\xdf\xb9\xac\x5e\xa1\xfd\x7b\x00\x20\x0d\x69\x8a\x60\xf0\xf3\xca\x42\xf4\xe7\x9f\xe9\xac\x66\x4f\x83\x4a\x90\x16\xf9\xe9\xd7\xe3\xbe\x5b\x41\x67\x77\x6c\xc3\x04\x49\x4c\x1d\xf9\xd2\x43\x3e\x07\x54\x75\x9b\x10\x12\x17\x6e\x9e\x9f\x7e\xae\x3b\x17\x67\xfd\x78\xbb\x6f\xc6\x0e\x99\x09\x4d\x6c\xdc\x07\xbd\xc8\xeb\xa9\xcc\xa0\xef\x62\x7b\x9d\xeb\x7f\x6c\x56\xcf\xdf\x5a\x4e\x26\x92\x99\x72\x0c\x60\xa7\xe3\x25\x99\x8a\xfe\x0e\x4d\x1c\x9a\xcc\xc9\x0b\xee\xaa\x0d\xe9\x5d\x6f\xcf\x29\x0e\xfb\xad\xdd\xc4\x31\x55\x68\x2e\xfe\xdc\x41\x43\x99\xaa\x6f\x29\xf4\x2e\x7e\x26\x26\x4e\x2c\x41\x45\x3d\xb7\xf5\x5f\x74\xb7\x12\x71\x13\x2a\x47\xe8\xca\xa4\xea\xc3\x24\x11\xe8\xd8\x53\xad\x7e\xb5\xf8\x4d\x0a\x82\x0c\xb3\xbc\x6c\x7f\x94\xf9\xff\x9e\x1c\x7d\xed\x97\xfc\x98\xeb\xcf\x42\x96\xc8\x9e\x8c\xfb\x7c\xc9\xea\xfc\x10\x2e\x91\x83\xf2\x55\x36\x84\xb6\xfd\xe5\x1e\x49\x5c\x62\x7b\xf1\x07\x8a\x80\xe9\x21\x11\x3c\x65\x25\x3c\xeb\xe7\x19\x1e\xc4\xd2\xe5\xd9\x6d\x5e\x1f\x76\x3d\x95\xd0\x8c\x2f\x92\x19\x2e\xd2\x54\x7a\xbe\x6a\xc4\x7a\xfa\x06\xa3\x10\xe6\xb1\x5d\xb4\xd5\xe1\x1f\xfe\x57\x11\x71\x64\xcc\x19\x1c\x86\x7a\x39\x2d\xb2\x1e\xfc\x11\x23\x6c\x8a\xb1\xe0\x5f\x8b\xc7\xfd\xee\x69\xb7\xb8\x9f\x42\xa2\x4c\xc6\xa3\xd0\x07\x02\xa0\x7e\x2b\xe0\xb9\xaa\x50\x53\xae\x24\xe1\x1e\xf7\x0a\x47\x5f\xb8\xc9\xc0\xfa\x28\x39\xa5\x2b\xbe\xb8\xd2\x46\x1a\x4a\x4e\x3a\x32\xd2\x8d\xaf\xa0\x10\xff\x4c\x66\x0e\x90\x91\x06\x7a\x45\x70\x54\x67\x72\xd0\xac\xf9\x19\x41\x32\xb7\x8d\x2c\x5e\xa0\xd4\xb3\x6c\x82\x51\x9c\x54\x02\xf2\x86\x48\x86\xdc\xcf\x3a\x0c\x11\xbe\xe2\x65\xe2\x91\x44\xe0\xd4\x38\xa2\xe5\xd1\x38\xe9\x94\x7b\x1a\xf8\xed\x49\x35\xba\xce\x8f\xd3\x12\xf8\x73\x71\x47\xa3\x05\x38\xc9\x1b\xf2\x3f\xdc\x70\xed\x2a\x87\x81\x9e\x3d\x84\xd1\x26\x74\x45\xbc\x1e\x76\xe8\x5a\xc0\xa4\x9e\x39\xd1\x54\x1f\x04\x9c\x1f\xea\x6b\x8d\x4d\xb2\xc0\x6b\xd6\x3e\x11\x5d\xeb\xf4\xd4\x10\x08\x0a\x17\xdc\x9e\xca\xb1\x31\x0c\x61\x48\x81\xad\x1e\xa0\xb2\x2a\x29\x1f\xe1\xbd\x69\x88\xb3\x40\x52\xe1\x41\xdd\xb4\xfb\xa3\xfc\xdc\x2b\x24\xe4\x3e\x38\x91\xa2\xbe\x1b\x31\x16\x2c\xfe\x4c\x70\x41\xb9\x86\xe2\xab\x06\xe7\xdf\x5b\x55\x20\xd6\x12\x71\x5c\xae\x86\x79\x42\x25\x39\xef\xa9\x89\xe5\x0c\x63\x61\xe3\xc2\x14\x48\x52\x22\x8e\x7a\x81\xf6\xc7\x7a\xf4\x73\x66\x51\xcc\xf5\xbe\xd2\x4e\xfa\x11\x4e\x07\xfa\x60\xfb\x47\x4e\x13\xe5\xf8\xd0\xfe\x5d\xd5\x79\xef\x70\x01\x67\x82\x3b\xab\x69\xa1\xbf\xba\xd0\xc0\x4d\x86\xcb\x87\x81\x02\x5e\x70\x5e\x37\xcd\x79\x7c\x3a\x08\x46\x84\x99\xee\x03\xa8\xab\xdf\x9f\xeb\xc3\xf1\x2c\xf4\x1d\x84\x92\xe8\xc1\xcb\x52\xe6\xc5\xa3\x6c\x5f\x6b\xa9\x5f\x9f\xea\xf6\x55\x5e\xbd\xca\xbc\x59\x37\x57\x20\xdb\x57\x79\x5d\x2d\x5f\x41\x16\xd7\xd0\xf5\x3b\xbc\x7e\x25\x82\xf1\xeb\x3f\x64\x59\x84\x69\xbd\x6e\x57\xa7\xba\xc8\x59\x3e\x1e\x32\x1d\xf9\x2a\x87\x1f\x4d\x8f\xa8\x98\x06\x4b\x40\xb2\x08\xbd\xca\xb7\x4f\xed\xb9\xcb\xa7\x0f\xa9\x42\x0a\x3d\xbc\xbc\x13\xd5\x22\x2e\x60\xa1\x8f\x4c\x80\xe2\x06\x67\x96\xad\x01\xcc\xaf\xaa\x21\x44\xd0\xaf\xaa\xd9\x7e\x36\x3d\x21\x66\x67\xa9\x0a\x5c\x82\x7e\x0e\xd4\x2d\x60\x02\x16\x47\x7d\x0a\x68\x2a\x21\x34\x7d\x12\x13\xc7\x81\x18\xf1\x2e\x3c\x59\xda\xef\xce\x79\x2e\x60\x32\x8b\xc6\xc9\xe6\x66\x52\xef\x7d\x3e\xdc\x3d\xf9\xdb\x67\xa7\xc0\x48\x12\xbc\x90\x66\xb8\x5b\xcd\x10\xfb\xe2\x75\x64\x74\x5d\x6d\xe6\xf9\x4e\x30\x86\x27\xf1\x5c\x41\xb9\x99\xf1\x24\x32\x80\x44\x48\x17\xaa\xf4\x56\xc4\xf6\xcf\x73\x81\x39\x00\x41\x32\x42\x35\xa0\xa1\x6e\x56\xbb\xbb\xf9\xb9\x14\x7d\x22\x9b\xe7\xd5\xe6\xc7\xf3\xf2\x6e\xb1\xed\xe3\x70\x60\x93\x04\xbd\x6f\x3b\x09\x84\xf5\xad\x5c\xe8\x61\xfc\x97\x04\x94\xd9\xb6\x52\xbf\xcd\x33\x3d\x74\x80\x0d\xa2\x00\xb7\x2a\xac\x6a\x23\x29\x82\x75\x0b\x87\x66\x12\x88\xb7\x41\x9c\x85\xae\x70\xfd\x41\x9e\x2d\x82\xb7\x81\xa0\x39\x75\x6a\x00\x71\x20\xee\x03\x8b\x02\xdf\xee\xaa\x78\x3a\x2b\xe2\xe1\xfe\x5c\xd0\x6c\x58\xd5\x6d\x28\x33\x24\xae\x5e\x6e\x16\x13\x24\x93\x8d\xd2\x00\x24\x7e\xc9\x2d\xd4\x87\xbc\x84\x5f\x90\xbf\xbc\xf6\xf3\xcf\x46\x99\xc1\xc4\xbc\x44\x55\x7f\x28\x8a\x21\xfc\x68\xe3\x94\xe1\x9e\xa2\xaa\xd3\xcb\x6b\xeb\xf9\x83\xa7\x43\x6f\x63\x66\x88\x3c\xb1\x5b\xad\xe3\xfe\x50\x1d\xa0\x53\xbb\xfc\x5c\x56\xfd\x6f\x26\x42\xf2\xfa\xa2\xfa\x80\xa6\xbd\xca\xfd\xa2\x6f\x13\xa6\x10\x7f\x40\x95\xc6\x00\xb5\x1e\x11\x03\xd9\x84\x11\x91\xf2\xf3\xcd\x7f\xcd\x99\x0e\x27\xe3\x99\x70\x81\x1f\x71\x91\x5b\x70\xce\xe6\x98\xc1\xcc\x26\xc6\xc6\xc9\x14\x72\xea\x98\xaa\xa7\x4b\x86\x4d\x6c\x86\x3b\xb0\xa5\xc8\xf8\xdc\x8a\xb1\x69\xa0\x7d\x1e\x6c\xbd\x7c\x9a\x0d\x47\x1a\x65\x2e\x9a\x7d\x6a\xc0\xf4\x90\x61\x9b\x02\xb1\x6f\x35\xaf\xd5\x07\x26\xb4\x0a\xf0\xb2\xae\xae\x07\x13\xa4\xdd\x40\x26\xce\x34\x40\x72\xd6\x2e\xb4\x4c\x70\x49\x0c\x34\xdd\xcb\xfb\xb3\xea\x61\xb3\x96\x81\x90\x30\x12\x92\x1d\x91\x24\xd2\x6c\x76\xfd\x78\xac\x88\x53\x0a\xde\x4f\x50\xbc\xc3\x73\x55\xc0\x54\xfe\x87\x59\xce\x82\xc0\xf4\xc2\x18\x4b\xaa\x07\x1b\x81\x8f\x2c\x57\xc4\xe9\xb7\xb8\xfe\xb9\xde\x3e\x3d\x6f\x51\x1e\xd9\x37\x8a\x84\xa4\xff\x11\x56\xeb\x50\xd2\x3f\xbc\x73\x22\xc6\xbb\x83\xcd\xa2\x10\xa3\x2d\xf8\x65\x4d\x3f\xa7\x4c\x40\x1a\x7b\xda\x0d\xc4\xf0\x77\x9f\xeb\xb4\xe8\xc9\x66\xd6\x10\x43\x7c\x7e\x80\xea\xd4\x3a\x10\xc7\xf9\x44\xaa\x95\x9a\x76\x0e\xd4\x53\x27\xea\xc4\xab\xff\x4f\xa8\x13\x99\x95\xc0\x68\xd7\x1b\x55\xe4\x8e\xf2\x1b\xae\x97\x4a\x24\x9a\x4c\xb4\x8f\x3e\xc2\x87\xdb\x3b\xbe\x50\xec\xf9\xd3\x2a\x0e\x18\xd6\x04\x9c\xa5\xd3\xf2\x5b\xab\x32\x8a\x81\xd7\x48\xd8\x3f\xe4\x1f\x96\x50\xbb\xd8\xea\xbc\x44\xe7\x3f\xce\x6c\xd8\x56\x87\x01\x2e\xe5\x07\xf9\x06\x03\x9b\xb4\x38\xff\xf8\xe1\x05\x2b\xc8\xea\x88\x33\x57\xb1\x7d\x94\x14\xb2\x77\x86\xdf\xff\x9e\xf2\x23\x32\x70\xd5\x34\x33\x6e\x00\x9c\x18\x49\xde\x1b\x64\x56\xcb\xc0\x78\x0c\xa1\x03\x08\xcf\x1c\x4d\x6b\x24\x57\x72\x4e\xc6\x75\x53\xd5\x0b\x43\xa2\xad\xae\x1b\x08\xee\x78\xb2\x0e\x55\x0b\x4e\x5d\x79\x39\x4a\xc5\xd9\x6e\xb7\x98\x84\xc7\xea\xce\x9e\x9e\xa4\x6d\x66\x0f\x67\xd3\x00\x31\x1c\x94\x62\xba\xee\x0c\x98\x25\xee\x25\xc5\xa8\xc8\x9a\x07\x41\xc6\x42\x07\x5b\x9b\x88\xbf\x4d\x46\x3d\x19\x3a\x73\x52\x6f\x30\x23\x92\xf7\xaf\x44\x78\xce\x0e\xea\x0e\xd0\x24\x98\xd0\xca\x76\x4c\x9f\xc6\x83\xc0\x32\x0f\xca\x6f\x0b\x17\xed\x9b\x62\x0c\x3c\x57\x87\x7f\xbb\xfe\xd1\x78\x10\x66\x01\xa6\xb7\xbd\x71\x79\xbd\xbe\x9e\x96\x89\x76\x5d\x78\x42\x2a\x8a\x24\x4b\x7e\x6e\xa1\xe2\x41\x68\x48\xe6\x09\x45\x73\xf4\xdb\xaa\x34\xe7\xe2\x05\x3c\x88\x82\x5e\x59\x6e\x7b\x84\xfa\x50\x54\xb5\xe9\xf9\x47\x78\x10\x09\xc2\x69\x12\xb3\xca\x73\x6e\xe0\x9c\x60\xe7\x97\x88\x0b\x0f\x22\x29\x30\xf4\x31\x61\x9a\x9f\x5e\x3a\x96\x92\xf4\xca\xdb\xea\x78\x53\xd5\x7e\xdb\xe0\x41\xac\x79\xea\x83\xec\x94\xea\x72\x04\x1c\xae\x3d\x51\x0c\xcd\xb2\x0f\xc8\x77\x9e\x20\xea\xdc\x4c\xe1\x41\xca\x38\xa6\xb3\x51\x80\x08\xb5\xf2\x56\xcf\xcb\x90\xa5\x18\x7a\xb5\x52\xc3\x63\xb5\x94\xfa\x75\x56\x00\xe9\xe7\x04\x53\xb4\x90\xde\x41\x71\x1c\x50\x19\x3c\x60\x96\xa3\xd6\xdb\xfe\x30\xc8\xb2\x7d\x83\x06\xe1\x01\x8f\x4d\x44\x95\xde\x0d\xd4\xed\xf2\xfe\xb1\xad\xce\xe0\x16\x5c\x67\xd1\x2d\xef\x6e\x58\x2e\xd2\x41\xf0\x20\x0b\x22\xa5\x71\x1f\x51\xa7\x97\xe4\x8f\xfe\x57\x02\x59\x7d\x7c\x7c\xec\xe1\x37\x26\x98\xf6\xbe\xe2\x8d\x07\x59\x92\x61\xbd\x3d\x98\xbc\xed\x71\xb2\x55\x7d\x46\xa9\xf7\x9f\xff\xc2\xd9\x79\x5e\x8c\xc8\x9f\x4d\x48\xb4\xa3\xaf\xa0\x7f\x73\x99\xb1\x1e\x6e\x4d\x60\xfe\xef\xd2\x65\x3c\x90\x3c\xc5\x4c\xff\xed\xfa\x66\xf7\x37\xe6\x94\x84\x04\xab\x22\x5d\xe5\x5c\xe7\x4f\x1e\x46\x55\x8c\x13\xab\x91\x07\x2a\x23\xe0\xfe\x7b\x95\x9f\x29\x2c\xe1\x81\xce\x24\x5a\x51\x4d\x5b\x83\x3c\xfc\x31\x3d\xd8\x04\x84\xf8\x40\x13\x6b\x65\x86\xb9\x69\xe2\x00\xc9\x33\x6a\x68\x4f\xb5\x53\xce\x8a\x2e\xbc\x22\x63\x15\xee\x08\x5b\x28\xa0\xcc\x4f\x87\xe7\x5c\xbf\x4e\x40\xfb\xdf\x3c\xab\x0d\x88\x71\x6d\x3f\x48\x6d\x12\xbf\x81\xbf\x11\x9b\xa8\xb0\xaf\x5e\xec\xec\xa6\x29\x0c\x83\x07\x96\x91\x9e\xdc\x0b\xa0\xe9\x80\xbc\x08\x17\x3e\x13\x2b\xa9\x1c\xe4\xa5\xe7\x6d\xc6\xc2\x1f\x39\x61\x4b\xe6\x81\x55\x94\x7c\xb8\xad\x0a\x33\x5b\x95\xc2\x20\x0d\x31\x1c\x7c\x24\x91\x2d\xf9\x02\x43\x18\x61\x7a\xb5\x30\xe0\x26\x08\x3c\xb3\x46\x71\x06\xad\xe5\xfb\x81\x40\x71\x9b\x3d\x66\xa5\xea\xb6\x19\x79\x76\x3c\x0c\x21\xc4\x4c\xdc\x5e\x76\x66\xe5\x33\x58\xaf\x7a\x78\xf6\x5d\x84\x71\x6c\xa5\x17\x42\xea\x57\x77\x27\x26\xcf\xc3\x38\xb1\x18\x41\xcf\x75\xf5\x20\x7f\xf7\x05\xa0\x3c\x8c\xc1\x26\xd9\x84\xd7\xc6\x6f\x53\xfb\xe3\x17\x4a\x11\x1e\x26\x01\xf1\x5c\x7a\x3f\xec\x1a\xde\xe7\x92\x65\xb3\x03\x20\xc6\xdc\xd0\xa0\xa3\xfe\xdc\xed\x61\xb3\xd3\xa6\x41\x8c\xe5\x25\x88\xea\xbb\xee\x36\xee\x59\x21\x14\x0f\xd3\x2c\x14\x29\x19\xbb\x44\x71\xea\x27\x4a\xc8\x02\x83\x79\xb1\xe5\xcf\xe7\xfe\xa7\x50\x63\x44\xe8\x67\xde\xca\x83\x53\x33\x7e\x84\x8f\x6f\x30\x88\x3c\x64\x69\x2c\x7d\x85\x6b\xe7\xee\xd4\x9f\x9d\x95\x0e\x5f\x89\x55\x78\xc8\x38\xe1\x1b\x86\x2a\x20\x33\x2d\x46\xe1\x21\xcb\x84\x76\x68\xd1\xd3\x57\x89\x19\x1e\x32\x88\xad\xcb\x62\x4d\x69\x6c\x67\xa7\xb1\x09\xf1\x52\x4b\x0d\x4f\xa7\x76\x76\x12\x1e\x0b\x1b\x8e\x92\x10\xd7\xed\xeb\x6e\x32\xe1\x7c\x3f\x4d\x0a\xef\x9d\x95\x30\xd0\xf7\xf2\x90\x1b\x69\x06\xae\x21\xa7\x92\x76\x53\xcd\x0f\x17\x91\xca\x1c\x66\x0a\x47\x72\x84\x63\xe1\x61\x16\x67\x88\x05\x5d\x4f\x38\x56\x79\x98\x99\x00\x17\xcf\x63\x67\x2e\x6a\x68\x7a\x93\xa9\x6b\x0a\x4d\xe0\xed\xf7\x17\x94\x94\x9f\x5e\x50\x76\x4b\x9b\xdb\x1f\x31\xd2\xec\x98\x0d\x67\x8f\xaf\x13\xf2\x55\x1a\xe4\xe1\x30\xc3\x3d\x69\x60\xf8\x7e\x6e\x97\x0b\xff\x93\x09\x65\xe0\xd5\xa2\x37\x64\xde\x7e\x15\xf1\xe1\x21\x04\x14\x16\x28\xf2\x43\xde\x5e\xd5\xb2\xd4\xaf\x98\xfd\xf3\xcd\x69\x38\xc2\xc9\xdd\x0e\xe2\x21\xe3\x85\xce\xd9\xac\x2e\x47\xcd\x43\xc8\x74\x44\xf2\x2f\x43\x18\x8d\x87\x36\xd6\xe8\x5a\x56\xa5\xcb\x39\xcf\x6d\xe6\xe9\xb3\x5a\x6e\xd1\x4e\xc1\xa4\xe8\x4d\x7d\x1a\x30\x28\x67\x27\xb3\x15\x41\x18\x4c\x03\x21\xf1\xf4\x51\xa3\x40\x46\xdc\xf3\x81\x3f\xd9\xe1\xcd\x45\x61\xac\x0c\x61\xac\xa4\xb9\xaf\x66\x83\x1e\x85\x3c\x43\x10\xd0\x7b\x0e\x1f\x18\xf5\xbc\xaf\xda\x27\xdb\x47\x5b\x06\x0d\x3e\x1e\x45\xa1\x40\x7c\x86\x63\x7a\xbc\x23\xe6\x55\xdf\x28\x38\xf1\x5c\xe5\xef\xae\xca\xe7\xec\x83\x47\x91\xcc\xc0\xf6\xb6\x12\x96\xc9\x9c\xd1\xab\x70\x9d\xe3\x30\x91\x6e\xe2\xdc\xd6\xd5\xe9\x78\x0d\x43\x30\x7a\x7a\xda\x38\xd2\x86\x84\xad\x5b\x14\xdb\xb9\xa9\xea\x6e\x03\x9d\xf7\x52\x71\xe2\x44\x6f\xdb\xdd\x17\x5e\x28\xd7\x29\x09\x63\xe8\x41\x74\xd7\x79\x83\xb1\xe9\x4d\xbf\x4d\xcc\x6e\x31\x11\xa1\x15\x3e\x64\xe0\x75\x32\xfc\xa0\xa4\x46\x60\x39\x08\x2a\x06\xee\x7d\x30\x90\x47\x29\xa4\x18\xe6\xf8\xd1\x40\x8d\xc1\xb7\x99\x95\x1b\x31\x96\x60\x07\x9f\xeb\x1f\x25\x56\x79\xc4\x04\x20\x94\xad\x36\xf9\xbb\x2f\xb1\x9c\xc4\xe5\x78\xd4\x19\xab\x7a\x18\xe5\xd9\xd9\x79\x1a\x9b\x41\xe5\x08\xb1\x44\x67\x36\xf8\x68\x2c\xb8\xc6\x23\x9e\x69\xc9\x06\x7a\xda\x0f\x80\xa3\x4b\x63\x0c\x65\x88\xe3\xff\x9a\x5d\x52\x11\x61\x91\x9b\x3b\x98\xb1\x9e\x60\xf8\x79\x24\x04\x49\xde\x50\x0d\x84\xcf\x09\x8c\xee\x20\x0b\x99\x9f\x3a\x0f\xcd\x0b\xda\x6b\x57\x60\x7b\xba\x1a\x1e\x65\x5c\xa3\x7e\xc7\x8b\x3c\xf4\x62\xd2\x7d\x9b\x49\x50\x03\xcc\x9c\x9a\x76\x03\xc7\xf3\x70\x7c\x1e\xc9\xc0\xf1\xfb\x6f\x36\x93\x31\x97\x19\xc7\x25\x97\x86\x6c\x07\xf2\xf0\x73\x36\xa8\x2a\x25\x06\xe1\x47\xf8\xc0\x1d\xe0\x4c\x01\x29\x8f\x14\x18\x5c\x2a\xdf\x7b\x02\xb7\xd9\x0c\xd5\x92\x96\x11\x17\x08\xb8\xfa\x5c\x9c\x0b\xde\xf2\x48\x03\xf1\x37\xc8\xe2\x43\x7e\x36\x4e\x12\x98\x98\x4d\x91\x14\xd4\xdf\xb7\x09\x88\x98\xa9\x86\xf7\x4a\x77\x2f\x6e\x3e\xd3\x80\x13\x56\xda\xd6\xd5\xe1\xac\xc7\x15\xd9\x00\x30\xdf\x82\x94\xbc\x0d\x8c\x1c\x8b\xc8\xa6\x09\xef\x8b\xd7\x3d\xde\xf4\xd6\x47\x16\x79\x64\x05\x60\xcc\xd5\x49\xcd\xd4\xd0\x39\xd4\x93\xaa\x59\xea\x18\x07\x52\x62\xa0\x17\x77\xac\xbc\x7c\xd9\x2f\x65\x6d\x26\x16\xa0\xef\x08\x80\xdb\xd3\xa2\x84\x43\x95\xbb\xeb\xc4\x61\x18\x41\xea\x97\x47\x54\xee\x7b\x96\xe5\xbc\x16\x60\xba\x10\xc5\x61\x98\x60\x5c\xcb\x97\x97\x2e\xa1\x6c\x4f\xf5\x97\x37\x12\x87\x11\x41\x3c\xba\x01\xba\x83\xdf\xcb\xd7\xf9\xaa\x12\x87\x3c\xcd\x84\x8f\x4d\xae\xfb\x7b\xe2\x22\x70\xc4\x09\x2b\xbf\x22\xcf\x8e\x03\x81\x25\x5f\x05\xd8\x36\x8b\x67\x8d\x51\x62\xd1\x67\x73\x0e\xe5\xb2\x3b\xf7\xdc\x88\x8a\x63\x60\xf8\x4d\xde\xcb\x53\xa9\x5f\xe7\x24\x74\xa3\xaf\x37\x4e\x82\x14\xcd\x49\xac\x5d\x7a\xa8\x4a\xf8\xbc\xae\x3e\xca\xc7\x5c\xc3\x4c\xa4\x83\xc7\x89\x63\x8e\x6e\xa0\x5d\xeb\xea\x5a\xb6\x5f\xe5\x53\xbe\x4d\x69\xf1\x98\x69\x89\x32\x1f\xb9\x27\xbf\xbd\xe8\x57\xfd\xe5\xdf\xbf\x77\x41\x9e\x4a\x64\x45\x76\x83\xf5\xa3\xc4\xfd\x1e\x7a\x38\xd6\xac\xb7\x93\x9b\xc0\x92\x20\x04\xe1\x4d\x7c\xa9\x98\x5b\x52\x43\x96\xc6\x3c\x15\x66\x8d\xfa\x57\x13\x40\xd8\xf9\x9b\x10\x21\x43\x42\x0d\x05\xed\x53\xf9\x64\x90\xb1\xe6\x8f\x69\x19\x53\xd7\x49\x22\xd6\xbc\xac\x2e\xd1\xc1\xfb\x8e\x89\x45\xa2\x55\x37\x86\x4f\x0e\x08\x32\x5b\xd6\x62\xc1\x01\x2b\x45\x9f\x8e\x50\x5e\x55\xbf\x67\x4f\x2a\x44\xc8\x9d\x4b\xb5\x6e\xb6\x6d\x55\x23\xe3\xc0\x78\x21\x89\x33\x4e\x5b\xec\xdd\xfa\xf6\xce\x9f\x54\x66\x06\x5d\x75\x64\xb9\xea\x16\xa9\xe5\xa7\xee\x1d\xb9\x58\x5a\x48\xc8\xa3\xa4\x40\x9a\xff\x5d\x31\x81\x1f\x61\x51\x39\x2a\xbf\xaf\x05\xe5\xa3\x81\xd0\x4e\x81\xa2\xaf\xdd\x76\x64\xd7\xfe\x6c\x9a\x87\x98\x43\xe9\xec\xdb\x70\xb4\xe6\xc4\x5a\xa5\xe1\x20\x5f\xb5\xd6\xd5\x1c\xc0\xc6\x63\x03\xc6\xab\xb2\x39\x89\x64\xd7\x60\x83\x08\x5c\x90\x69\xa1\xdb\xfc\x1d\xee\x64\x43\x06\x61\x1f\x9c\x1d\xee\xd0\x86\x80\xc0\x34\x5b\x9d\xea\xf6\xd5\x29\x54\xf7\x67\x82\x28\xd3\x3d\x9d\x5f\x5e\x99\x5c\xcb\x62\xf1\x3c\x34\x67\x18\xa5\x2a\xab\x27\xfb\x4b\xbe\xc3\x70\x07\x60\x61\x10\x4d\xf7\x52\x30\x8b\xe6\x6e\x4e\xac\xcd\x93\x20\x16\xf8\xf2\x1c\xb9\x11\x48\x03\x75\xb3\x3f\x3f\x5d\x92\x50\xab\x98\x79\x6d\x17\xf9\x02\x43\xf4\xe0\x5c\x6c\x9b\x27\x51\x9c\x21\x4b\x45\x3b\xa6\x1e\x98\xc1\x45\xce\xfe\xea\x8e\x8f\x2d\x47\xb5\xfd\xce\xdc\x5b\xb5\xaf\xdd\xaa\x98\xb7\x3d\x81\x88\xeb\x94\x48\xaa\xe8\xec\xdc\xf4\xc6\x17\xc0\x5c\x11\x82\x78\xf6\xb0\x89\x89\x70\x7f\xfd\x35\x2e\xe5\x9f\x6e\x44\x49\x62\xa8\xe2\xfe\x3a\x7f\xc9\x11\x60\x3a\x9a\x16\x09\x8b\x04\x6e\xbf\x57\xc4\x9f\xfb\x57\x45\xca\xe7\x2a\x06\xfc\x99\x52\x52\x9d\xea\x86\xb2\xbb\x0a\x52\x47\x7e\x99\x64\x09\x03\x9d\x59\x9f\x8a\x40\x40\x8b\x53\x64\xf0\x77\xd4\x75\xe1\x94\xac\xa9\x8b\x7c\x8c\x06\xe6\x09\x87\x00\x23\x2d\xc8\x33\x22\xf3\xa2\x33\x85\x1e\xab\xc5\xc9\xa7\x67\x78\x22\xa2\x34\xc8\x46\x08\xf5\x29\xae\xcf\x75\xca\xba\x4d\x06\xa1\x25\x9e\x0e\xfe\x11\x3e\xee\xa0\xae\x36\xe3\xe2\xe6\xbf\xce\x4c\x7c\x89\xeb\x26\x59\x68\x30\x10\x79\x95\xcb\xf6\xb5\xa8\xca\xc7\x6a\x34\x4d\x2e\x62\xd9\x79\x92\xa9\x28\xa2\x22\xda\x53\xd9\x7e\x22\x19\xfc\xe5\x91\x96\x71\x84\x8b\x97\x87\x57\xee\xe0\x70\x2c\x86\x15\x25\x51\x9a\xa3\xd7\x83\xb4\xcd\xd7\xd5\x49\xf5\x45\x4a\x3c\x51\x26\x40\x8c\x7e\x5d\x9a\x5b\x79\xdc\x0f\x3f\x13\x1b\xb8\x96\x83\xd4\xf7\x69\x8c\x09\x9d\xda\x7b\x89\x02\xc0\xbc\xc3\x43\x6e\x7c\xd4\x31\xd1\x61\x6c\x43\x4f\xa5\xbc\x68\x5b\xa9\x5f\x71\xf9\x9f\x3c\xa8\xb6\xb1\x72\x1f\x1c\x12\x4a\x13\x1c\x63\x3a\x88\x26\x8c\x31\xdb\xe4\x05\x47\xbb\x99\xb2\xa8\x41\xfa\x0b\x99\x24\x0c\x5c\x2c\xfb\xa6\xaa\x3f\x64\x6d\x08\x04\x72\x03\xd0\xec\xfa\xdb\x31\x82\xb0\xbd\x2f\xd0\xfe\x99\xb7\xed\xe7\xf6\x2d\x2f\x8a\xad\xee\xec\xde\xd9\xe5\x14\x79\x80\x3f\xa1\xfe\x9c\xcc\x36\x88\x02\x34\xc3\x7e\x63\x54\xfc\x6f\x95\x9d\xf1\x04\x92\x34\xa2\x7a\x03\xe3\x6b\xa4\xbb\x1f\x79\xef\x57\xc8\xba\x6d\x9e\xec\x57\x09\x47\x9e\x80\x88\x30\xaa\x44\x1c\x0a\x8f\xd7\xfb\x9b\x1f\xdd\x3f\xcf\x8b\xe5\xfe\xea\x69\xe7\xcf\x65\x83\x10\x19\xb2\xae\x6b\x90\x87\x73\x51\xfa\xc9\x78\xdb\x38\xc4\x90\xb4\x53\xd9\xea\xbe\xb7\x41\xeb\x65\xb6\xc3\x27\x36\x8e\x28\x1a\x43\x6a\x07\x5f\xa7\xe0\xf9\x2d\x3c\xb1\xa0\x42\x37\xd4\x48\x8f\xfd\x0b\xb5\x5b\x37\xd5\xfc\xc5\x5a\x4b\x22\xb8\xaa\xaa\xde\x96\x52\x4d\x5b\xd3\x20\x4c\x74\xe0\xad\xe2\xb5\xae\x1e\x64\x5e\x0e\x60\x6d\x9e\x06\x59\x22\xa8\x66\xb5\xec\xd6\x16\xb7\xb3\x78\x26\x81\xb3\x6f\x23\x0d\xa4\xc6\x70\xd9\xfd\xd3\xed\xfe\xae\x3a\x35\x9e\x4e\xd1\x4b\xaf\x9e\x3f\x2a\x04\x8d\x71\x38\xaa\x48\x5f\x3f\x9d\x0f\x70\xa6\x11\x53\x3c\x1b\xa4\xbe\xaf\x4f\xe5\x0b\x7c\x85\x37\xba\xce\x71\x22\xd0\xd1\xd7\xc4\x96\x7a\xdb\x4f\xb3\x34\x16\x36\x1e\xb2\xd3\x54\x46\x35\x9d\x19\x69\x2c\x33\x04\x40\x1f\x4f\xcd\xeb\xf9\x9d\x2c\x4d\x02\x83\xeb\xaa\x2b\x85\xf7\x27\x67\x59\x88\xd8\xbd\xfd\x2b\x0a\xd7\xac\x4a\xa8\x5f\x3e\x77\xd5\xf1\xf4\xbd\xba\x14\x4f\x45\xa8\x91\x24\xee\x9d\xf2\xfd\x8e\x93\x63\xe0\x47\xf5\x17\xc8\x52\x13\x3b\xef\xf2\xaa\xaa\x8a\x9b\x1c\x0a\x13\xf6\x8d\x42\x63\x81\x45\xf7\xf5\x4e\x22\x88\x17\x2e\x9a\xd9\x0c\x01\x25\x9e\x53\x66\xda\x2a\x03\xa9\x59\x8f\x0e\xf8\x5a\x26\xcb\x53\x25\x25\x4e\xc4\x8f\xbd\x3d\x75\xee\x9c\x2b\x9c\x1f\x52\xd9\x3c\xd5\x51\x80\xec\xaa\x58\x78\x45\xd4\x77\xbe\x85\x13\x7b\xae\xa3\x9e\x03\x59\x0c\x1a\x31\xe7\xc7\x5c\x73\xa3\xd9\xc0\xf6\x39\x31\x87\x53\xcd\x81\x21\x25\x32\x18\x82\x02\x8f\xd7\x96\xd4\x70\xf0\x7b\x3c\x8a\xf7\x8c\x38\x47\x78\x0a\x1a\x48\x98\xa9\xfb\x12\x5c\x15\xe1\x28\xa5\x91\xda\x84\xb4\xb6\x48\x43\x88\x2c\xed\x21\x22\x90\xda\x4c\x61\xf4\x4e\x57\x07\x07\xb9\xdd\x2c\x77\x7d\xa3\xb1\x31\xd5\xc4\x39\xd5\xd1\x9e\x63\xc9\x0f\x04\x0b\x78\x82\x96\xea\xc3\x67\x9b\x17\xba\xca\x4b\xa7\xb5\xd1\xb7\xeb\x0c\xe7\x3d\x1e\x75\x5b\x13\x8d\xca\xd9\x11\x62\x01\x10\x43\xe9\x21\x2f\xf3\xc3\xe9\xe0\x4b\xd9\x48\xd0\xc6\xf7\xb1\xd2\x8e\xb6\xec\x19\x9a\x89\xb3\x30\x31\xc4\x38\xd0\xca\x37\x30\x57\x9f\xa8\x81\x34\xeb\x22\x24\x56\x4f\xd6\xef\xfe\x3d\xb3\x30\x63\xe8\x31\x34\xf2\x70\x2c\x28\xf5\xed\xbc\x0a\x67\xd8\x0d\x20\x89\xc4\x1f\x22\x43\xf4\x1d\xfe\xf3\xd4\xb4\x07\xf9\xd6\x19\x05\x9e\x51\x02\x03\x2f\x7e\x13\x65\x51\x66\xb4\x1a\x69\xfc\x36\x53\x03\x8e\x45\xc0\xd0\x5a\xc5\x78\x59\x7e\x80\x7b\x84\xc1\x7e\xff\xc1\xb1\xc8\x2a\xdc\x23\x9c\xd3\xdf\x5d\x56\xe6\xe5\x77\x28\x70\xce\xe2\x30\x0d\xcc\x48\xd7\x88\x84\x71\x2f\x65\x5a\x58\x12\x52\xc5\xdc\xf2\xa4\xe4\x7d\xae\xfa\x70\x07\x4b\xe2\x10\xcb\xd8\x9f\xd7\xbb\xf1\x2c\x65\x49\xac\x91\x5c\x6c\x54\xd2\xbc\x81\x76\x5c\xce\xec\x3b\xa6\x60\x06\x79\x23\xca\xad\xcc\x49\x0b\x39\x4b\x18\xc7\x7c\xc4\x9d\x2c\xda\x81\x9c\x9a\xb3\x04\x22\xc4\x4c\x5a\x99\x17\x5b\xf0\x90\xd5\xee\x77\xc7\xb5\x0b\xd2\xec\x11\x03\xed\xe7\x38\x4b\x59\x42\xce\xe6\xf1\x38\xfc\x24\x02\x3f\xea\x17\x27\x64\xca\x1c\x3b\xde\xa8\x78\x69\x53\xa3\x2a\x0c\x91\x28\x9e\x63\x4b\xfc\x3b\x88\x54\xce\x58\xac\x82\x9e\xec\x7d\xbd\x7c\xda\x7f\x44\xfe\xd6\x18\x67\x68\xb1\xdc\x56\x85\xe9\x4c\xb5\xbc\x94\x7d\x93\x70\x52\x52\xa4\x87\x5f\xbe\xe7\x2d\xac\xaf\x67\xef\x99\xa9\x94\x45\x23\x21\x5b\x07\x0d\x3e\x83\x57\xe3\x4c\x04\x31\xa1\xe8\x5e\xaa\xd9\xb4\x14\x91\x14\x8e\x56\xff\x56\x96\x5f\x89\x83\x38\x13\x2c\x42\x10\xa2\x63\x66\x00\xe3\x22\xb3\x68\x36\xcd\xd0\x5a\x9c\x09\xa1\x85\xcb\xa6\xed\x8f\x23\x65\x04\xce\x84\x36\x48\x2f\x71\xa8\x4c\x6e\x3f\x07\xa7\x6a\x76\x35\x0d\x2c\xf0\x09\x95\x56\x3a\x3e\xf1\xc9\x04\xcc\x22\x4a\x9f\xdc\x48\x0d\x9d\xd5\xd0\xff\x0e\x09\xbe\xc6\xfb\xea\x85\x20\x21\xde\x06\xf6\xae\xe1\xb7\xf8\x2e\xce\x54\x4c\xfc\x69\x6d\xe5\xe8\x60\x50\x2c\x6a\xde\x07\xe2\x01\x8c\xa6\xe6\x34\x8f\xf3\x33\x26\x00\x8e\x01\x5f\xbe\x40\xbd\x81\xda\xad\xbd\x6e\x81\x24\x22\xde\x73\xee\x08\x53\x5c\x58\x17\x58\x59\x14\x85\x63\x90\xf0\x4f\xaa\x2c\xc7\x45\x69\xc4\xe7\x3f\xec\x04\x4c\x47\x74\x8f\xf7\xff\xf5\x8f\xfe\xa7\x98\xd0\x0c\x84\xa5\xb8\x95\xa3\xce\x29\xb9\x5e\x88\xf6\x21\xf8\xce\x5c\x9a\xfa\xab\xb7\xc1\xb4\xa0\xd0\xcb\xf6\x28\xeb\x56\xee\xbc\xd1\xe9\x5b\xb3\x04\xfa\x6a\xa5\x19\xa2\x9c\x33\x0d\x11\xe2\xfd\x68\x4b\x6d\xaa\x42\x9d\x3e\xeb\xc1\x53\x61\x26\x00\x7c\x0d\xa8\x41\x76\xa9\x3a\xe9\x7c\x49\x16\xe1\xa2\x66\x2f\xc1\x58\x15\xf5\x59\x05\x02\xc5\xad\xcb\x6e\x7f\x2c\xdb\x5e\x5e\x8e\x33\x08\x63\x92\x7c\xe8\xe6\x25\x95\x9e\x95\x2f\x8b\xa6\xf9\x86\x58\xe3\xeb\xd7\x0e\x89\x40\xd2\xb2\xdd\x48\x86\x8c\x33\x48\x29\xe8\xdb\x59\x43\x8b\xa9\x41\xc0\x83\xc0\xc6\x5e\x84\xd8\x4d\x92\x93\x7a\x03\x7f\x5b\x3c\x88\x03\xe9\x92\x55\x3b\x79\x9a\xae\x00\xdc\xa3\x5e\x1f\xf2\x12\x16\xd6\x82\x6e\x2f\xa8\xcb\x70\x1e\x38\x4b\xb3\x21\xda\xea\x19\x5e\xa0\x6b\x66\xb6\xdf\xbc\xba\xa9\x76\x7b\xca\x0d\x38\xc9\x8b\xc6\x47\x12\xca\xbe\xbf\xe6\x94\x3e\xc8\x6d\xeb\xb4\x9c\x2e\x04\x05\xdc\x01\x61\x06\x96\x8a\xc4\xdf\x07\x74\xdc\x85\x7b\x4d\x22\x81\x09\x9b\x83\xb3\xf5\x8f\x43\xe9\x36\xe7\x89\x89\x51\x20\xfd\x4a\x96\x6f\x24\x9b\x7a\x0b\xed\x75\xe5\x98\x42\x26\xb0\x3c\xce\xd3\x34\x45\xc9\x44\x14\xb3\x24\x99\xda\xe5\x69\x9c\x7f\x9a\x5e\x38\xd5\x94\x4f\x83\xf6\xf7\x74\x95\xec\xcc\x1b\x5c\x03\xdb\xb1\x1f\xfc\xf5\x29\x59\x92\x60\xb0\x6c\xb5\xbb\xfb\xc7\xd5\xae\x3f\xd8\x6a\x62\x9c\x31\xe6\x9b\xfc\x90\xeb\xcc\x55\x18\xba\x4a\xd6\xab\x53\x5d\x12\xad\xe7\xb0\x92\x73\xae\x25\x3e\xbf\xab\xa2\xd8\xd4\xf9\xa1\x17\x4b\xe0\x5c\x44\x09\xd6\xfc\x9e\xca\x5c\x57\x75\x39\x7b\x0a\x11\xa5\x26\xf2\xaa\x07\x06\x7e\x23\xfc\x3d\x9a\x0d\x82\x10\x41\x36\x04\x4b\x5b\x98\x4f\x15\x61\x12\x95\x0c\xb2\xb8\xbb\x91\x4b\xcb\x05\xb0\x0c\xbc\x4b\xdb\xb4\xe4\xf2\xad\xca\xb6\xce\x7b\x8b\x9a\xcb\x48\x20\xe4\xcf\x0f\xe5\xa2\x34\x4b\x59\x14\x5f\x8a\xce\x5c\x77\x65\x19\x02\x46\x46\xe2\x0a\xa3\x6a\x0d\xce\xb5\x09\x35\x69\x19\xdb\x6e\x27\x3a\x27\x9c\xc4\xb9\x09\x08\xfb\xf4\x22\x0f\x70\x9b\xdb\x75\xf3\xd4\xcb\x08\x70\x6e\xc2\x14\xc1\x7c\xff\xb5\x18\x14\x30\x38\x37\x89\x40\x36\x15\x4a\xc7\x90\xa0\xd5\x45\x40\x16\x37\x32\x91\x81\x5f\x63\xae\xe1\x7d\xb4\x1a\x72\x48\x08\x9d\x71\xac\xab\x43\x85\xb3\x74\xf1\x2e\xf3\x62\x64\xeb\x70\x60\x81\xdb\x79\xba\xeb\xc8\x02\xb6\xa0\xab\xd2\x34\xbb\x6a\x44\xeb\xca\x39\x28\xad\x94\xcf\xec\xd4\x9f\x7b\x5d\x19\x18\x17\xb6\x73\x6e\x83\x00\xcb\xc6\x8f\xa8\x9f\x88\xcc\x13\xd8\xd9\x54\xc3\xb7\x6b\xe3\xcc\xc2\x50\x31\x3a\x31\xf3\xb9\xd5\x69\x32\x0e\x25\x2f\xac\xcd\x0b\x9a\x06\xde\x6f\xe8\xbb\x5a\x69\xd3\x21\x78\x8c\x2b\xc7\xe3\x4c\x5d\x85\x8b\x40\xd0\xfb\xc3\xa4\xcb\x20\xd3\x3f\xeb\x24\x09\x94\xa0\x11\x69\xe8\x08\x36\x7c\x1b\x58\x02\x43\xf9\x09\xf3\x5c\xa9\xea\x62\x41\xb9\x3b\x28\x8c\xe3\x34\x1d\x59\x11\x4b\xaa\xc6\x05\x33\xb8\x18\x22\x94\x06\xb3\x98\x8b\xfb\xfb\xa7\x25\x52\x2b\xec\x97\x4f\xcf\x8f\xab\xe7\xed\xee\xe9\x71\x35\xf4\xb2\x18\x9e\x58\xbd\x43\xfd\x7a\x6a\xde\xbe\x3c\xc2\xa5\x68\xa8\x3b\x3e\x4a\x29\x6c\x20\x8d\xd9\xc9\x66\xa8\x72\x18\x6f\xf6\x22\xb2\xc4\x2d\x8e\x72\xd4\x75\xe3\x02\xea\xd7\x27\x28\xbc\xb5\x28\xe2\x58\x6b\xb7\x51\xfc\xca\xdb\xb2\xfb\xaa\xa7\x8f\x1c\xa7\x01\x86\x03\x9c\xa8\xf7\xe2\xf4\x3d\x65\xe7\xec\x60\xce\x30\x83\x20\x8d\xd9\xc8\xcf\xb9\x2b\x25\xe2\x8c\xa1\x91\x70\x0b\xe5\x5b\xbe\x21\xd1\x96\xb1\x49\x26\x62\x43\x98\x6b\xfd\x2a\x8b\x02\xca\x17\x70\x10\x31\x39\x56\xda\x70\x7d\x93\x80\xa3\x5f\xf6\x8c\x58\x69\x9f\x8c\x99\x3d\x4d\x92\x84\xdc\x99\x81\x5b\x28\x8a\x1f\x65\xde\x36\xeb\xd2\x56\xf5\x61\x4c\x09\xd5\xf5\x93\x08\xb9\x78\x84\x53\x5d\x4d\x6e\x29\x49\x09\xa3\x9b\x37\xf8\x19\x9c\xdf\x6b\x44\x9a\x10\xe5\x7b\x23\x27\x94\x76\x5c\xf0\x80\xe8\x1c\xb1\x7c\xd0\x05\x84\xcd\x0d\xf4\xeb\x98\xe0\x2a\x0b\xc7\x6e\x96\xaf\x81\x70\x34\x64\xff\xaf\xfe\xc2\xec\xbe\x44\x67\x8d\xfa\x88\xb8\xb7\xec\xbf\x3a\xb9\x22\x8b\xa3\x90\xb0\xde\xb9\x06\x8c\xb3\x79\x38\xa8\xc8\x78\x22\xfc\x13\x50\x7c\xe9\xaa\xcf\x26\x0b\x29\xb9\x4d\xc6\x2f\x6c\xf9\x2a\xcb\x12\x8a\x29\x46\x79\x48\x52\x08\x09\xa4\x07\xd2\x9d\xad\xfe\x6c\x5a\x59\x34\x57\x9f\x7f\xe6\x17\x08\x21\xb8\x50\x69\x84\xf8\x29\x0f\x11\xbf\xd4\x8d\x11\x9c\xdb\x87\xad\x67\x6a\x59\x5c\x20\x1e\x85\x66\xe6\x0d\x80\x59\x7f\xd5\xae\xfb\x76\x1c\x95\x48\x50\x6d\xee\xed\x53\x41\xfd\x08\x23\x82\x51\x2e\x94\x49\x30\xa4\xac\x6a\x90\x6f\xcb\xaa\x7a\xcb\x27\xf4\x5e\x5c\x28\x10\x01\x09\xf8\x41\x8d\xb5\xa1\x7b\xbf\x2c\x9e\xdf\xff\x85\x02\x2a\x0b\xfa\x9f\xff\xfe\xab\x18\xac\xd0\x61\x1a\xd2\xbe\xd5\x40\xfd\x8e\x8f\x3c\xa8\x55\x76\xcd\xc2\xe9\x6c\x16\xd0\xc2\xd3\x47\xb9\x01\xa8\x9f\xe1\x3d\x87\x0f\xdf\xc5\x44\x1c\x59\x5c\x54\xf5\x15\x21\xe5\xbb\xc4\x11\x96\x8a\x5c\xad\x76\xfd\x51\x32\x16\xcc\x2d\xf0\xd7\x3d\x5b\xb5\x6b\x84\x44\x21\xff\xe2\xbf\x91\xf0\x07\x3f\xb8\xd9\x77\x09\x29\x20\xa6\x63\x5a\x6c\xd6\x39\xcc\x57\x98\xa5\xf8\xd6\x1f\x12\x56\xc4\x82\x34\xd5\x3b\x63\xec\xc7\xf1\x8c\xa2\x1a\x17\x36\xa3\xd0\xce\x28\xcc\x2b\xac\xe1\x6a\x6c\x34\xf4\xb5\x2d\xbe\xd8\xad\xfb\x34\x16\xa6\x42\x38\xd3\x57\xb7\x2d\x0b\xe2\x00\x3f\x93\xcd\xfd\xe3\xfe\xe9\x50\xe6\xa6\x2a\x0a\xe9\x2d\x80\x2c\x48\x88\x5f\x9f\xf4\x95\x6b\x30\x39\xae\x9d\xae\x60\xe1\x76\x24\x92\xe3\x0f\x48\x83\xd4\xd9\x95\x18\x05\x81\xb2\x69\xcf\x20\x50\xb2\x80\x11\x46\xea\x05\x5a\xc7\x22\x3f\x48\xfa\xf0\x2c\xc8\x44\x26\x46\x9f\x88\xd3\xb7\x75\x26\xcc\x18\x98\x3d\x20\x81\x66\x8e\x58\x16\x48\x22\xa6\x1a\x66\xe6\xd9\x91\xcf\x02\x1d\x47\x13\xab\xeb\x64\xf2\xb6\xaa\x9f\x41\x57\x97\x00\x96\x59\x98\x92\x1f\x49\x2e\x68\xf5\x01\xe6\xb1\x6a\xe5\xc8\x96\xcb\x42\x10\xe0\x18\x23\xf5\x0a\x1d\x90\xfc\x1d\xa8\x64\xb3\xb9\xa9\xea\xd5\xe1\x58\x54\x9f\x30\xfd\xf6\xfd\x3e\x90\x85\x36\xc6\x77\xea\x22\xe5\x54\xef\x76\x55\x55\x6f\xb3\x80\x56\x16\x09\x95\x58\x8f\x89\x94\xcd\x97\x51\x8e\x4c\x80\xf1\x44\xe4\x7f\x27\x51\x05\x62\xac\xda\x02\x18\xbf\x0f\x9e\x1c\xbc\x6a\xfc\x77\x06\x6d\xff\xfa\x5f\xfe\x02\xc0\x40\x3b\x93\xf8\xfc\x97\x96\x45\x36\x75\x3c\xd4\xed\xbe\x38\xbd\x15\xfd\x3e\x94\xc5\x41\x8a\x98\x97\x1f\x8f\xf7\x4f\xcb\x3f\x57\xd7\x23\xb6\x50\x9e\xc5\x11\x31\xe2\xe5\xba\x5a\x7d\x51\x10\xe5\x59\x9c\x5a\x5c\x74\xfb\x05\x68\x0b\xed\x35\x61\x33\xcf\x55\x07\xf3\x2c\x09\x02\xa4\xae\xfa\xef\xa7\x1f\xfb\xab\xd5\x6e\xff\xb0\x7e\x5c\xed\xaf\x9f\x96\x3f\x1e\x56\x8f\xbb\xfd\x66\xe1\xc9\x0e\x79\x96\x44\x06\x33\xe2\xcf\xf0\xf2\x8c\xe9\xf0\xd9\xa0\xa7\x69\xa0\x46\x56\xe2\x78\x99\xc8\x52\x63\xd1\x82\xf4\x70\x9f\x3f\xe1\x73\xba\xc7\x67\x4c\xc6\xb1\xb3\x27\x3c\x58\x7c\x5d\xb6\x15\x3a\x6c\x94\xb2\x3e\x3f\xe5\x98\xce\x10\x8a\x35\xf8\x88\xc5\x7c\xc0\xfb\xa9\xcf\x03\x43\x0a\x14\xe5\xcb\xd2\x31\x96\xde\xca\xfe\x1e\x79\x6a\x42\x3b\x10\x11\x4a\xd3\x37\xa8\x94\xa8\x8e\x5f\xc0\x6d\x8b\x1b\x59\xb7\x6b\x17\xb5\xf5\xbd\x84\x0a\xb1\xe8\xd0\xef\x4b\x2b\x59\x17\x9f\x57\x79\x3d\x0c\x42\x16\x69\xac\xd9\xf6\x3d\xe2\xbe\x41\x49\x24\xf9\x5a\xca\xa2\xaa\x73\xc2\x78\x7d\x6b\xad\x66\x32\x25\x95\xeb\x63\x4d\x81\xae\x6e\xe5\x6b\x96\xf2\xf8\x0c\xb2\xb3\x26\xfc\x89\x25\x8b\xd0\x70\xda\xe5\x50\xef\xaf\x64\x93\xeb\xbe\xc5\x66\x43\x88\x63\x7b\x84\x12\x05\x70\xa6\x43\xab\x53\x4b\x60\x64\x94\xbd\xc6\xa2\xea\x9b\x4b\x7c\x4e\x3c\x03\x15\x63\x04\x72\x51\x38\x1d\x1b\xa9\x5b\x17\x99\x98\x87\x64\x2e\xfc\xf5\x27\xd2\x41\xe4\xa0\xe3\xf7\xf0\x0e\xc5\xe9\xd8\x13\x36\x50\x0f\x19\x44\x29\x86\xfa\xd5\xff\xfc\xde\x55\xc1\xef\x99\xbf\x29\xc3\x38\xc3\xa2\x0b\xdb\x19\xc6\x68\xe1\x38\xff\xbd\xef\x20\xad\xed\x5e\xe8\xf5\x62\xf9\xe5\x58\x4d\x94\x46\xf7\xd5\x0b\x25\xd2\xd6\xcd\x46\x7e\x76\x9e\x97\xe7\x71\x1c\x3c\x6b\x19\x9a\x00\xe3\xb1\x5b\x40\x37\x87\xea\xd4\xfe\x66\xda\xdf\x9d\x22\xd2\x4a\x7b\x02\x3f\x30\x3d\x69\xa4\xbf\x9d\xc8\x64\xd9\x58\x63\x61\xd1\xdd\x08\x82\x33\x7c\x07\x08\x31\xd7\xaa\x4e\x9f\x17\xe2\x4e\x7f\x85\xf1\xa2\x9a\x66\x77\xba\x38\x0c\x71\x3b\xdf\xe5\x87\xca\xdb\x3e\xdf\xd8\x24\x32\x4e\x88\xd4\xa6\x2a\xcc\x20\x85\x30\x99\x45\x32\x09\x6c\x14\x8e\x85\x24\x26\xc1\x1f\xd7\x29\x4d\x93\x98\x80\x39\xa8\xc7\xf4\xad\x16\x2f\x97\x2c\xa3\x88\xce\x83\xfc\xbd\x95\x65\x2b\xc9\x28\xd8\x4c\x04\x51\xb8\x64\x8a\xa1\x1f\xb6\x58\x3f\xaf\x36\xfe\x47\xce\xc2\xc8\x29\x09\x5c\xb5\x7a\xd5\xbe\x7e\x61\x7a\xe0\x92\x8b\x2c\xf4\xd2\xde\x98\xf1\xf1\x5b\xa0\x77\xad\xa4\x10\x01\xea\x5a\x55\x47\x28\xa7\x49\x35\x99\x05\x1a\xe7\xe6\x55\xde\x2e\x1a\x98\xc5\xc7\x2f\x57\xf0\xc8\x2c\x89\x13\x35\x72\x0e\xb6\x47\xf9\x51\xf6\x42\xef\xff\x31\xb9\xc1\x8c\xc7\xca\x78\xc0\xe5\xe1\xd8\xc2\x3e\x8c\xff\x98\x9e\x8d\xcb\x88\x64\x70\x50\xac\xd8\x9b\xea\xd3\xe7\x54\x89\x51\x69\x5f\x7e\x95\x1b\x89\xc5\x5d\xbe\x91\x13\x8f\x5f\xd3\x6f\xe5\x73\x80\xa3\x5f\x56\xa5\xb2\x0c\xa3\x95\x14\xa6\x47\xb6\x8b\xbc\xfd\x9c\xde\x90\x4e\x0d\x6e\x5b\x07\x2c\x64\x73\x42\xeb\xd3\x60\x93\xd4\xca\x20\x65\x15\x7a\x30\x54\xeb\xd3\x6b\x26\xcf\x26\x95\x36\x04\x87\x96\xc6\x5c\xc1\x85\x1d\x56\x9a\x28\x41\x47\xc0\x83\xc3\xcd\x50\x30\x20\x8d\x0a\x59\xe6\x11\x64\x98\x19\xed\xec\xc1\x22\x6f\xda\x51\x97\x0c\x01\x1d\x45\xfe\xf2\x8a\x5a\xad\x97\x98\x89\xcf\xf9\x69\xf3\x55\x4d\x02\x4f\xf0\xcb\xba\xa9\x61\xba\xc0\xff\xbf\xad\x17\xa0\x19\x7a\x20\x5e\x6b\x63\x52\xaa\x7a\x99\x33\x42\x7c\x3d\x8d\x0a\xfb\x3a\x4e\x9d\xdb\x5c\x13\x31\xc9\x39\xed\x8e\xb3\xeb\xbd\x0a\x92\x08\xfd\xa4\xb1\x89\xe3\x9a\x42\x1e\x29\x2a\xa5\x6d\x5e\xab\xd3\x79\xd1\x7e\xae\x42\x95\xc5\x63\x66\x9e\xfc\xb7\x9b\xa1\xbe\x3a\x7b\xf2\xef\x78\x36\xa9\xd0\x70\x4b\x9e\x3a\x06\x57\xba\xdd\x8f\x02\x20\x7f\xf8\x0e\xae\x50\x0a\x11\xf8\xc4\x9c\xd9\x53\x66\x5e\xa8\x82\xe6\x2a\x92\x81\x17\x11\x58\xca\xda\xf8\xea\xff\x53\x5f\xd2\xcd\x55\xa4\x14\x82\x4b\x28\x4e\xb9\xfd\xab\x20\xb6\x8a\x34\x71\xe1\xa0\xa1\x79\x93\x17\xc4\x1f\x32\x18\xea\xe9\x58\x6c\x88\xfd\xeb\x4b\x45\x65\x6f\x7c\x9e\xc1\xf8\xfb\x4b\x40\x8a\x12\x87\x07\xf9\x86\x79\xbf\x26\x57\x2e\xd4\xd4\x17\x24\xa8\x38\xa6\xc2\x56\x0f\x54\xcb\xab\xf2\xc9\x4e\x8a\xf3\xb9\x8a\x65\x8a\x0a\x06\x9d\xed\x66\x8b\xea\x63\x5f\x20\x8a\xcd\xb7\x2a\x91\xc9\x7e\x9f\x1a\xf1\xc9\x71\x15\x03\x11\x8f\x82\x2b\x2a\xcc\x95\x6f\x49\xd2\x14\x97\xc9\xfb\xea\xa5\xf7\xd2\xd7\x2e\x48\xfc\xc5\x85\x98\x8d\x5c\xc2\x01\x4d\x17\x1c\x39\x7a\xb9\x25\x34\x8d\x97\xd8\x3b\x63\x82\xfb\x03\x45\x2c\x9c\x0c\xef\xee\x75\x44\xbb\x3b\x13\x4f\x98\x4e\xa8\x44\x03\xce\xd8\xe5\x66\xb9\xea\x55\x74\xb8\x4a\x2c\x51\xe7\x78\x2a\xda\x6e\x7d\xb8\x86\x43\xa5\xcf\x64\x4c\x55\xca\x03\x1c\x22\x82\xce\x74\x0e\xee\xf9\x5e\xda\x03\x5d\x3a\x2b\xb2\x84\xfa\x01\x9a\x66\x54\xd9\x72\xe1\x73\x4b\x41\xf8\x5a\x59\x17\x4e\xa3\x3a\x1f\xd7\xcc\x78\x80\xb6\x65\xe7\xee\x53\x95\x17\xe1\x21\xa7\xeb\xa6\x62\x90\x11\xaa\x15\x39\xb5\x6e\xaa\x7a\x4a\x93\x3b\xbd\x24\x4f\x48\xc4\xa8\xdb\x07\x9d\x33\xfa\xa3\xc9\xcb\x97\x6b\x40\x27\x6d\x5e\x42\xaa\x44\x1a\xc7\x54\x70\x7b\xcc\x6b\x58\xd8\x21\xa1\xa5\x32\xc6\xb1\x6a\xab\xee\xd6\x52\x3e\x5b\x2e\x32\x03\x48\x2b\xf1\xf0\xb9\x30\xef\x9d\x0d\x31\x29\xb8\x51\x32\x50\x94\xd0\x7a\xad\x3e\x10\xc8\x4a\x39\xd0\xb3\xc8\x5a\x25\x59\x80\x80\x18\x87\x8f\xa2\x0a\x3b\x6b\xa1\x7b\xd7\x93\x70\x9d\x92\x90\x61\x15\x2b\x20\x43\xcc\x1f\x5f\xe2\x57\x4a\x05\x21\x02\xc5\x68\xac\xf2\xf2\x05\xd5\x98\xfc\xe1\x2a\x0a\x30\x6b\xfd\x9f\x95\xca\x27\x91\x4d\xa5\x23\x2d\x48\xe7\xf6\xe6\x04\xc5\x70\x41\xcd\x59\xea\x26\xd3\x1e\xc9\x47\xae\x57\xbb\x91\x35\xa9\x34\xd7\xe8\xc9\xd8\xfc\x37\x98\xd5\xef\x19\xe2\x55\x19\x49\xcc\x3e\xad\x9c\xa5\x9a\x94\x71\xa9\xb5\xc6\x8b\x9f\x10\x46\xea\xfc\x00\x81\x91\x36\xf4\x24\x45\xa4\xf2\x36\x9d\x22\x36\x4e\x11\x93\xd9\xca\xc6\xb1\xe7\x4c\x3d\x35\x1d\xc4\x14\x68\x75\xbe\xd0\xb8\x48\x4d\x87\x89\x41\x32\x83\xa3\xfc\x7c\x3a\xb5\xff\x29\xf5\xdb\xd1\xeb\x3a\x72\x1d\xa5\xa1\x0f\x48\x53\x24\x17\x0c\xa1\xb7\xbf\x30\x57\x4d\xef\x59\x47\x5a\x2b\x97\x0e\x7d\xac\x8c\x2c\x14\x82\xdc\x7b\xd7\x77\xfc\x25\xeb\x58\x98\xc0\x6b\x08\x3a\x72\x7d\xe7\xe0\xcb\x03\xac\x8f\xb6\xb9\x93\xcd\xeb\xa2\x34\x8f\xd5\x90\xf5\xd3\x49\xa4\x6d\xd0\xab\x39\x62\x80\x68\x4e\x1c\xc3\x75\xa2\xb8\xc7\xb5\x3f\xc8\xdf\x9d\xe3\x78\x76\x1b\xd1\x89\xb2\x2e\x4e\x27\xcd\xe7\x0f\xef\x99\xeb\x34\x12\x08\xa7\x92\xc6\x6c\x89\x50\xc3\x9c\x57\x52\xe6\x3a\x4d\x34\x73\x6b\xc4\xdd\x9f\xb7\x4f\x68\x07\xfa\xa6\x34\x4a\xa9\xd2\xce\x4c\x74\x15\xbe\x5d\x4c\x75\xaa\x42\x84\x6c\x78\xb6\x30\x73\xd1\x96\x39\x9f\x69\x9c\x7a\x6a\xb3\xe7\xe5\x81\x8e\x09\xd6\x8f\x2b\xfc\x28\x91\xa5\x79\xa2\x31\xc6\x31\x20\xa4\x37\xa3\x22\x7c\xe1\x7b\xb1\xd8\xdb\xa1\x2e\x91\x33\xbb\x40\x26\xfc\x70\x10\x0f\xc2\x7e\x59\x1d\x0e\xa7\x32\x6f\x7f\x94\xa7\x06\x26\x6a\x37\x5c\x73\xd0\xca\x19\xae\xbb\xbc\x3d\x15\x32\xaf\x61\xef\xcc\x64\x36\x3b\xb3\x48\x59\x68\x7b\x3d\xc8\x6b\x68\xda\xba\xfa\x92\xcb\xd0\x82\x91\x13\x46\xf6\xed\x6d\xf5\xde\xfa\xf2\xb8\x59\x3f\x49\xa2\xff\x4e\xe0\xf2\xb7\x2e\x4e\x9d\x5b\xd8\xed\x04\x78\x8b\x44\x64\xd8\xcc\xed\x67\x9d\xc5\x31\xaa\x52\x3e\x03\x31\x3b\x23\x94\x6e\x8c\x07\xd0\x59\x12\xe0\x38\x6e\xab\x42\xd6\xd7\x92\xd2\x16\x43\x5e\xe9\xff\x09\x60\xa4\x33\xee\x45\x30\xc9\xd3\xc0\xe0\xe7\x79\xb0\x42\x7f\x84\xc5\x15\xf8\x6a\xf5\xd8\xdf\x91\xa1\x7a\x3b\x75\xfa\xdc\x9d\x8a\xfc\xd8\x8c\x2d\x37\x9f\x5c\xd4\x32\x0e\x04\xeb\x73\x32\x76\x9c\x86\xd5\x32\x0d\xc1\xe3\x9c\xc6\xeb\xa7\x96\x96\xf2\x06\x6d\xae\xdf\xa0\x6d\x1e\x4f\xbe\x88\x5f\x77\x7b\x3b\xf2\x65\xaf\x9e\x7f\xf8\xdf\x74\x14\x23\x2d\xa8\xaa\x14\x26\x0c\x1b\x3f\xc3\x2e\x11\x03\x9d\xf7\x7f\x03\x7f\x3a\x9d\x20\x28\x7e\x44\xc8\x3e\xbe\x69\xad\x35\x0a\xc8\xab\x3a\x37\x2f\x30\x78\x4d\xc8\xaa\x37\xae\xe4\xd6\x1a\xa2\x94\x88\x79\x7e\xe7\x87\xd3\xc1\xa3\x90\x71\x0f\xf2\x7d\x8c\x21\x00\x20\x2e\x3b\xab\xbe\xfa\x40\x83\x25\x10\xee\x4d\x21\xdb\x95\xac\xfb\x06\x13\x44\x01\x92\xb9\x18\xdc\x81\x2f\xf1\xb5\xce\x8c\x7d\x13\xb0\x48\xa8\x41\xa5\x63\xbc\x60\x9b\x30\x0e\x30\x1b\x96\x37\x0b\xaf\xf1\x61\x9c\xe4\xee\x64\x72\x9b\x28\x83\xac\x5b\x42\x1e\xe5\x01\x3c\xec\xf9\x5c\x66\xd2\xc4\x92\x32\xe7\x63\x9b\x69\xf1\xf2\x05\x8c\x6c\x62\xad\x48\x5a\x09\x85\xbc\x8b\xc2\x43\xae\xfc\x87\x6c\x92\x34\x91\xae\x5c\xe8\xb1\xea\xeb\x1b\x31\x09\x3e\x59\x2e\x4d\x62\x74\x40\x1b\x75\x43\x2a\xf8\x13\x7b\xc6\x57\x8e\x9b\x04\x52\xeb\x44\x76\xfe\x31\x83\x30\x98\x34\xa6\x3a\xac\xee\xc0\x5e\xaf\x61\x7a\xbf\xa9\x21\x5c\xf9\x31\x7f\x79\xf9\x1c\x68\xaa\xbb\x06\x8e\xf0\x04\xc7\x6b\xb9\x68\xc9\x4e\x38\xbb\x95\x99\xd4\x18\xed\x82\x5b\x68\xcb\xe0\x9c\x9d\xae\x7a\xe7\x0c\x54\x93\x82\x20\xea\x02\x5c\x5b\xfe\x38\xcd\xc8\xa6\xba\x0e\x16\xe3\xb8\x57\x0b\xa2\x56\x42\x8e\x68\x0f\xb3\x30\x2c\x35\x21\xf7\x4a\xec\x24\x1a\xb4\xa9\x2b\x43\x91\xee\x11\xa1\xd3\x5f\xad\x24\x83\xb9\x62\x98\x25\xef\x5a\xa1\xee\xca\xd9\x62\xb3\xf3\xdb\xb9\x61\x96\x21\xde\xf9\xd7\xdd\xe2\x7e\x35\x1b\xe5\xce\x4b\x96\x5e\xab\xec\xef\x91\x07\x19\x2e\x35\x90\xdd\x49\x0c\xe9\xb7\xb9\xfd\x1a\xcd\x34\x22\x4b\x50\x96\xd0\x19\x4f\xf7\x79\xe3\x6b\x4a\xc6\x4f\x25\x54\x48\x95\xec\x87\xbc\xfd\x55\xd5\x6f\xb3\x1a\xc6\xd9\x93\x64\x69\x92\xe9\xb1\x6a\xfd\x14\x9d\x3e\xbd\x81\xcc\x70\xd5\x17\x81\xee\x3e\xaa\x31\x25\x31\x37\x32\x64\x08\xd0\x43\x96\xa0\xef\x7d\x01\x23\x53\x85\x13\x7e\xd7\x19\x36\xff\x37\xda\x70\x8d\xd4\xca\x5b\x77\x57\x52\xbf\x0d\xf0\x7c\xd7\xae\xb8\x0d\x7c\x8e\xf5\xe3\x6f\x07\x34\x46\x56\xb1\x51\x82\xe3\xb2\x8d\xb5\x53\x55\x45\x72\x7a\xae\x4d\x47\x12\xd7\xad\x0f\xc8\x1f\x08\xa9\xdd\xb7\xc4\x54\xda\xa1\x4e\x9f\x67\x2b\xaa\x8d\x4e\x35\xba\x37\x98\x95\xee\xa3\x3e\xa6\x3f\xde\x91\x07\x61\x48\x17\x97\x5d\xfc\xc8\x26\x44\x4f\x46\x67\x06\xd3\xd7\x4f\xcf\xd7\xab\xe7\xfd\xf5\xd3\xe3\xea\xe2\x93\x8d\x6b\xae\xce\x6f\x7a\x46\x5b\x26\xb3\x31\x6d\xea\xa1\x72\x98\x90\xde\xc1\x16\xd3\xe5\xf6\xef\xed\xbf\xc6\x84\xf4\x2d\x52\x92\xec\x19\x3a\x97\xbd\x2a\x47\xcf\x33\x33\xb8\xbb\x4d\x02\x73\xc4\x48\x43\x25\xd1\x15\xee\xf7\xfe\xbf\xa2\x9d\x9f\xef\x05\x90\x70\xcf\xc6\x3f\x29\x04\x9c\x77\x93\x31\x82\xff\x5e\x3b\xef\x7b\x0b\x60\x66\x19\x36\x03\x3a\x44\xef\xe9\x76\xf5\xb8\xda\xae\xb7\xfe\x15\x80\xa1\xbc\xa8\x0f\xf6\xf6\x3a\xd1\xc3\xa9\x6d\xc0\x25\x1b\x50\x27\xe4\xac\x8e\x69\x4b\xa6\x13\xc3\x72\x40\x86\x07\x67\x72\x79\x32\xe8\xd9\xed\xd8\x2c\xc2\x34\x71\x0d\xfa\x7d\xfb\x5a\x8f\x8c\xf7\x0b\x2f\xc1\x6a\x21\x07\x12\x06\x1c\xc5\x0d\xd4\x13\xbe\x56\xea\x09\x41\x1c\xa0\x1b\x88\x33\x73\xdb\xc2\xd1\x47\x81\x21\x48\x23\xce\x47\x8c\xce\xd7\x50\x74\xfb\xeb\xd5\xbc\x44\x1d\x82\xd4\x60\x3a\xb2\x84\x0f\xbf\xcb\x15\xd5\xcb\xc4\x6f\x81\x20\xe3\x9c\xd2\xf7\xef\x3b\x90\x87\x67\x20\x60\xa5\xbf\x56\x98\x85\x18\x4a\x41\xbc\xd7\x88\x57\x9a\x43\xe8\xc2\x94\x64\x3d\xcf\xae\x1c\x2a\x92\x59\x74\x78\x90\xfa\x7c\xdd\x92\xef\x0c\x1a\x1c\xf1\xf4\xa2\x6d\xa1\x34\xb2\x6c\x17\xe5\xe0\x2b\x4c\x67\xd7\xb0\x68\x42\x14\xb1\x58\x8d\xb0\x53\x9e\xd1\xd2\x37\x27\x54\xe8\x31\x8d\xc8\xf8\x46\x21\x89\x04\xa6\xe7\x3d\xec\x76\xa4\x31\xe1\x33\x87\xc8\xa6\x01\x79\xd4\x1b\xd2\xb8\xbc\xc1\x0c\xda\xe0\xcc\x43\x9c\x51\xc2\x17\xd7\xbd\x2f\xc9\xf0\x59\x88\x08\x92\x58\xa2\x87\xee\x6c\x33\xaa\xca\x78\x46\x58\x05\x18\x04\x0e\xf9\xf3\x26\x69\x8c\x56\x9c\xad\x6a\x95\x1b\x2c\x21\xfc\xe2\x9f\x40\x22\x53\x4c\x03\x5d\x7b\x06\xd7\xfd\x33\x34\xa7\xe2\x02\x7d\x16\xa4\x5a\x12\x2d\x43\x2f\xe5\xd0\x90\x80\xde\xd4\xad\x07\x16\x91\xbb\x8c\xd6\x61\xe7\xc0\xc8\xf2\x73\xe2\xea\x00\x53\x26\x4e\xfc\xb8\x1f\x73\x4d\x03\x1b\xa6\xbe\xd9\x90\xa2\xcf\x2d\xb4\x8b\xe3\xb1\xc8\x75\xf7\x3e\xa7\xd7\x10\x51\x8a\xe0\x8c\xdb\x5a\x7e\xaa\xd3\xef\xb1\x1d\x0e\x22\x8e\x31\xa1\xb9\xfa\x7d\xac\xea\x76\x2c\xf9\xcc\x21\x0b\x22\xac\x24\xa8\xab\x02\x70\x36\xce\xce\x9b\x45\x80\xd9\x83\xee\x83\x7a\xae\xaa\x2f\xc9\xdb\xbf\xb7\x54\x42\x66\xc3\x2c\x76\xe2\xe1\x23\x10\xb0\x6b\x55\x11\x85\x99\x91\x23\x9b\x0a\x6c\x50\xc5\xc5\x37\xa7\x80\x7e\x04\xc5\x6f\xce\x56\xbe\x80\x8e\xc8\x41\xc1\x8f\x7b\x40\xfa\x81\x4e\x08\xb2\x2a\x9b\xcf\x52\x7f\xd9\x27\xa7\x37\xa9\x95\x94\xd0\x9b\x66\x83\xcd\x7b\xf6\x82\x10\x91\x16\xec\x7a\xf9\x44\x04\xb4\xfe\x8a\x20\x23\x4c\xa2\x54\x47\x28\xef\xc1\xbc\xf4\xdf\xaa\xef\x60\x53\x4b\xc8\x89\x6e\x3a\x78\x41\x6a\xf2\xb6\xe6\x7c\x2f\x60\x75\x88\x28\x9e\x5e\xb7\xef\xc1\x53\x0f\xf6\x67\xb3\x94\x19\x3e\x2f\x71\x81\xf3\xe8\x9f\xf1\xbf\xfa\xce\x36\xc4\x59\xb2\x78\x5c\x6c\x16\x3b\x4f\xb2\x61\x83\x50\x21\x52\xb1\x1d\xac\x61\x1b\x26\xc2\xab\x77\xdd\x57\x0d\xf8\xcc\xeb\x64\xc8\x6c\x08\x4c\x3a\xc9\x5a\xd4\x51\xc7\x08\xbe\x83\x33\xf8\x13\x45\x36\x8e\x27\x00\x9e\xfc\xe5\xb5\x5d\x5b\x4f\x6f\x37\x0d\x9d\xb8\x63\x62\x4e\xd2\xd3\xb8\xbb\x79\x5c\x3a\x21\x56\x3a\x7b\xef\x1e\xca\x97\xde\x99\xb2\xb1\xa5\x01\x75\xa2\x7e\xf8\x09\x42\x37\xa1\xcf\xbf\x67\x9b\xc4\x12\x59\x05\x3a\xdf\x0f\x7e\x56\x1e\x55\x65\xd3\x58\xa3\x67\x44\xa4\x97\xdb\xbc\x18\x90\xc2\x36\x4d\x52\xad\xa7\x0e\xdb\x5c\xd0\x64\xb4\x90\x5a\x16\xc4\xe8\x8d\xdd\xe7\x07\x35\x7e\x5d\x96\xc5\x24\xb4\xd8\xb6\xd3\x9f\x25\x51\x5f\xfe\x63\xb3\x98\x1a\x02\x7f\xeb\xf3\xb2\x0c\x78\x42\x8e\x13\x06\x77\x5d\xac\xe2\x7b\xe3\xd3\xf2\x2c\xc6\xfd\xe6\x3a\x2f\xcc\x04\x3f\x69\x45\x22\xb1\x76\x25\x77\x38\xe2\xee\x6d\x4e\x15\xbc\xb9\xcd\x02\x52\xf1\x30\xe0\x2c\xe6\xb1\x7b\x6d\xb3\x88\x78\x7e\x36\xcf\x4f\x0f\xab\xdd\xdd\xea\xc7\x76\xff\xf3\xe9\xc7\xf2\x6e\xf5\x3c\xd6\xc3\xee\xfa\x29\xa4\x34\x23\x28\x1c\x8c\x60\x70\x36\xd3\x09\x86\x4a\xf2\xce\xcd\x91\xc7\xe6\x34\x87\x0e\x5b\x19\x31\x1c\xb4\x01\x00\x35\x7a\x03\x4a\x26\xde\x3e\x42\x9f\x7e\xfa\xf9\x5a\xcd\x18\xde\xbe\x9f\x94\x0f\xb2\xfc\xbc\xbc\xd1\x58\xad\xe3\x68\x98\x1a\x77\x55\x31\x29\x4b\xb2\xda\x92\xc0\xba\x44\x4f\xc0\x63\x36\x31\x5e\x34\xab\x1a\x70\x07\x98\x84\xa4\x25\x28\x57\x37\xb0\x8c\x59\x23\x05\xda\xc7\x34\x97\x6f\xa1\xc4\x0c\xcd\xa2\x34\x0f\xb2\xb9\xe0\x8a\x5a\x03\x99\xf1\x0a\x63\xcb\xb1\x5a\xd5\xac\x9f\x0d\x43\x0c\xa8\xe5\xcd\x42\x6b\x38\xb6\x60\xae\x75\x55\x1f\xcf\x31\x2c\x59\x1b\x49\x18\xe3\x15\xa6\x4a\xab\xe7\xfc\x22\x11\x04\xa9\xc5\xdc\x3f\xfc\x06\x4d\xec\x7d\xbe\x41\x45\x08\x1a\xba\x5a\xfd\x8f\xd7\xc4\x17\x41\x60\x14\xe2\xb4\xf7\xfb\xbc\x21\xfd\x9b\x75\xf9\x5c\xcd\x5e\xb2\x08\x42\x1e\x45\x2e\x5d\xb2\x3f\xca\xba\xfd\x8c\xf6\x13\x15\x5b\x11\x24\x46\xa7\xcc\xab\x72\x6b\x59\x14\xe7\x96\x2a\x11\xa4\x41\xa6\x3d\x26\x16\xb7\x98\xab\xcf\xb5\x99\xf7\x49\x02\x0c\x0d\x2c\xcc\xbf\x4f\xa6\x33\x61\x06\xe4\xc2\xd7\xa2\xf7\xfe\x18\x86\xb4\xf6\x50\xba\x20\xf8\xc2\xdf\x58\x2a\x53\xac\x76\xbe\x85\x76\xe9\x55\x90\x9d\x2f\x20\x02\xc6\x14\x86\x8c\xa0\xb3\x54\x47\x93\x49\x04\x4c\x48\x34\xd9\x97\x8b\xdd\x16\xea\xf7\xbc\x67\xdf\x76\x5e\xcb\x8c\x88\x50\x04\x3c\x65\x76\x4a\x5f\x41\x05\xa6\xe7\x0a\x22\x44\xc0\x39\x07\xe9\xb8\xbb\x47\x88\xb3\xae\x01\x22\x57\xb5\xbf\xfb\xfd\x54\xe7\x2f\x79\x7f\x4b\x3c\x33\x8e\x0e\x53\xe5\x2d\xb1\xde\xdf\x3f\x3c\x7e\x31\xcd\x7d\x6f\x30\x58\x3f\xb1\x5d\x3c\xfe\xb9\xfa\xef\xed\xd3\xfd\x8f\x5d\x2f\xf3\x2a\x02\x11\xa5\xb8\x34\xee\x5e\xe1\x2a\x6f\xdb\x3a\xef\x6f\x40\xf0\x24\x1d\x6f\x14\x17\xa5\x30\xba\xae\x12\x5f\xd4\x4b\x25\x8b\x07\x0f\x6d\x16\x41\x16\x90\xba\x39\x26\x26\x8e\x27\x02\x66\x4e\x06\x37\x0b\x23\xee\x60\x99\xff\x75\xca\xf5\x1b\xba\x83\xe8\xb2\x4d\x17\x38\x11\x64\x31\x09\x9a\x12\x13\xdf\xa9\x6c\x3f\x2f\xc5\xe8\xdd\x01\x32\x0e\xd0\x93\xda\xf7\x9b\x56\x45\x2f\xd6\xc5\x07\x66\xbd\x35\x47\x90\x34\x89\x81\x6e\xea\xaa\xb2\x7f\x7c\xc9\x0d\xfb\xbe\x60\x6c\xaf\x3b\x4f\xc6\x2d\xd9\x8f\xf7\xa3\xa2\x99\x8b\xb8\x83\x7e\x51\x14\x81\x36\x14\xc6\xa7\x42\xf1\x21\xee\xec\x9b\x81\xb4\x64\xee\x37\xdd\x32\x32\x19\x37\x13\x53\xe2\x41\x96\xe5\x49\x16\x23\x45\x4d\x11\x00\x8b\xf1\x49\x14\x96\x04\xbd\x41\x79\x7e\xde\x01\xc4\x6c\x70\xc3\x97\xb2\x36\x37\x55\xbd\xd0\xc8\xb8\x66\xc8\x79\x3c\x1b\x6f\x11\x81\x8d\x53\x5c\x13\xe1\xb7\x7e\xed\xdc\x89\x01\x48\x2b\xc2\x20\x03\x44\xf7\x3e\x00\x82\x51\x9a\x55\xd9\xf6\xe2\x2b\x22\x0c\x14\xc9\x80\x6c\xf2\xdf\x48\xab\x3d\xfc\x6e\x31\x22\x79\x7b\xbd\xfc\xbb\x94\x5a\xfe\x48\x13\x21\xba\xe7\x74\x34\x0f\x79\xe9\xeb\xd7\xef\xf3\xc3\x0c\x3b\x21\xc2\xc0\x2a\x24\x74\x97\xa3\x30\xd5\xb4\x47\x18\x85\x29\x0c\xdc\x54\x3d\xfd\xac\x08\x43\x26\xd0\x6a\x5d\x3e\x3e\xba\x11\x1d\xe1\xd1\xce\xc4\x06\xdc\x61\x51\x18\x13\x19\x6c\x5b\x1d\x09\x79\xd5\xa3\xe9\xbb\x46\x8b\xa4\x4d\x98\x58\x86\x16\xad\x04\x2c\x73\xae\x67\xb7\x15\x31\x89\xfc\x13\xd2\x98\x6d\x6e\xc0\xad\x41\xe7\xbf\xf5\x30\x92\x0c\xa5\x14\x0a\xd9\x50\xb8\x74\xff\x1e\x86\xfe\x92\xb1\x66\x11\x1f\xea\xc5\xcc\x58\x93\x5a\x84\xb1\xc9\x62\x4f\xcd\xbb\xb7\xd5\xa9\xc6\x70\xd0\xea\x7f\x51\xb3\x60\x72\x91\x24\x91\xdc\x7d\xd6\x57\xb2\x7c\x7b\xc6\x02\xcd\xe9\xf4\x0a\x13\xc6\x02\x40\xd4\xe2\x28\x20\x86\x10\x26\x7f\x3d\x16\xb3\x01\x95\xe4\xc5\x94\xa6\x27\xe1\x09\xc3\x01\xdc\x8f\x6c\x73\x1e\x85\xe7\x02\x1a\x22\xe4\x40\x8c\xfd\xff\x59\x29\xca\x66\xf9\x0b\x09\x9b\xe1\x48\x2b\x92\x97\x1e\x0a\xcb\x47\x7b\xc9\x25\x53\x43\x84\x99\x10\x98\x9d\xdc\x22\x3f\xf5\xd7\xaa\x6c\x11\x4a\x1b\x67\x24\x19\xa4\x8b\xbc\x84\x87\x41\x1d\x7a\xd2\x4d\x05\x0a\xf3\xbf\xf8\x2c\x7f\x9c\x05\x4d\xfc\xc7\x25\x40\xe7\x78\x56\x29\x25\xd2\xa1\x22\xdd\x13\xda\xcf\x3e\x8f\xc9\x23\xf5\x90\x8e\xb3\xe3\xa6\xa3\x14\x1d\x8b\x0d\xfc\x1e\x24\x2e\x45\xa8\x59\x82\x1e\xfa\x7b\xd5\xfa\xa0\xdc\xf4\xe5\x68\x49\xd0\x03\x87\x95\xef\x96\x28\x0f\x08\x18\x2f\x55\xa1\xd6\xc6\xa4\x0e\xb4\x94\x17\xa4\xa2\x3e\x9d\x79\x1a\x04\x02\x0a\x51\x55\xc7\xb1\x89\x37\x93\x0a\x11\x11\x1a\x45\x46\x95\x34\x58\x7b\x83\x6c\x8b\xa8\xa3\x36\x4e\x33\x89\xd0\x58\x9e\x38\x42\x8b\xab\xd3\x27\xad\x03\xae\x09\x62\x85\x04\x58\x4a\x96\x6f\x48\x15\xd8\x37\x24\x44\xeb\xfc\xe2\x10\x10\x83\x3c\x9b\x08\x41\x13\x41\xc6\xe6\x79\x45\x75\x69\xd1\xaf\xd5\xea\xcf\xfd\xd5\xd3\xe3\x0f\x6f\x39\x85\x36\xce\xa4\x07\xc6\x54\x6e\x43\xe8\xdb\x6c\xe2\x15\x26\xdd\x32\x7c\xf5\xe9\x93\x9c\xe3\xb7\x10\x05\xa9\x41\x55\x8e\x75\xa9\x61\xe2\x52\x8a\x28\xd0\x09\xae\x9a\xb9\x86\xc9\xef\xa1\x63\x16\x27\xa5\x8b\xa9\xc5\xec\xbb\x18\x49\x62\x3c\x27\x75\xc8\x51\x78\xe6\xac\xd1\x14\x85\x96\x14\x1d\x8f\xf2\x73\xff\x81\x10\xac\xe9\x1c\x8f\xa2\xd4\x00\xc1\x3b\x0b\x8b\xe9\xdc\x93\x6e\x07\xc4\x91\xef\xa4\x48\x95\x77\x58\x7c\xa4\xb8\x93\xcd\xeb\xde\x9d\xcb\xf7\x8b\x25\x89\x61\x41\x69\xd6\xcb\xa7\x19\xd4\x5e\x44\x31\x64\xe4\xf7\x55\xa7\xba\x81\xe5\x38\x7e\xe5\xbb\x24\x81\x44\xb7\xcd\xa9\x8b\x7d\x65\xbf\x16\x51\xc2\x52\xac\xa3\x73\xd5\xb9\xeb\x52\x57\xb3\xe2\x11\x11\x25\xc2\xb8\x24\x1d\xae\x75\x5f\x49\x9f\x44\x94\x26\xa4\xa0\xf9\xef\x93\x79\x81\x5f\xf9\x79\xfa\xa0\xae\x9b\x40\x04\xfc\xf6\x54\xd7\xa7\x99\x14\xbf\x88\x58\x68\x11\x62\x72\xf8\xa4\xfd\xf0\xeb\xe6\x13\x31\xc3\x10\x7a\x7b\x9d\xbf\xe4\x9b\x53\xd1\x4c\x5f\xb5\x48\x23\x18\xc8\x47\xdc\x1c\x5b\x2f\x1e\xae\xb1\xd2\x0d\x87\xe6\x5c\x58\x44\x44\x82\x25\xe0\x8a\xf7\x90\x5f\x69\x65\x5e\x7a\x2d\x3f\x31\x7b\x06\xa1\xad\xa1\xb9\xfe\x73\xf7\xf7\xd0\xb5\x22\xca\x42\x85\x9f\xe5\xa6\x3a\xfc\xdf\xf0\x7a\xb2\x34\x42\x96\x4f\x47\xde\x70\x5f\xbd\x9c\x5d\xb2\x23\x19\x68\xcc\x79\xa8\xaa\x3c\x35\x43\x8c\x42\x44\x92\xa5\x6a\x30\x1c\xab\xba\xed\x17\x95\xd9\xf2\x1c\x49\x1e\x63\xfc\x56\x3b\xe4\xc2\xe7\x38\xfb\x23\x22\x15\xc9\x80\x3b\x10\x5f\xcf\x3d\x31\x4f\xf2\x89\x08\x58\x82\x81\x18\x53\xed\x48\x42\xe7\xa6\xaa\xaf\xc1\x52\xa8\x76\xf6\xa6\x40\x65\xa8\x3e\xb3\xf7\xa4\x84\x67\xac\x8d\xc8\x2a\x8e\x35\x8b\x0d\xc5\x5f\x7c\xee\xd2\xb7\x6a\xe3\x44\xcf\x3b\xab\xd1\x91\x36\x41\x67\x80\xed\x40\x1e\x16\xa5\xf1\xab\xc8\xf4\x65\x5a\x13\xf1\xb4\x0f\x88\xdd\xd4\xd5\xff\x41\xe9\x43\x1f\x36\x7f\x39\xd5\xae\x20\x73\xbe\x0a\x58\x30\x6a\x0c\x81\xfe\x82\x0a\x3a\x57\x2f\x20\xe2\x20\x25\x8b\xe9\xae\x32\x0e\xea\x73\x91\xfe\x7b\x3a\x93\xe2\x80\xf5\xbe\xdd\xb6\x85\xc3\xd8\x3c\x8d\x03\x15\x07\xae\xed\x88\x02\xb3\xa3\x40\x85\x88\x03\x9d\xc6\x84\xa3\x93\x4d\x93\xbf\x90\x07\x3a\xbf\xcd\xc9\xa8\xc4\x61\xa2\x71\x89\xfe\x78\x95\x05\x3c\xc8\xdf\xfe\x54\xa1\x09\xb1\x6e\x13\x8b\xb8\x91\x49\x6a\xdb\x93\xa3\x88\x38\x72\xe5\x39\x9e\xbf\x71\x5d\xda\x0a\x59\x35\xa1\x85\xba\x79\x06\x69\x3e\xfb\xae\x8c\x67\x0e\xda\xfe\xe7\x61\x83\xe1\xc1\xe9\x1d\x44\xd6\x60\x50\xf6\xf1\xe9\x71\xff\x73\xb5\xdd\xad\xae\xf7\xbb\xd5\xe2\x61\xdf\xcb\x42\x6d\xef\x16\xcf\x2b\x7f\xba\x58\x6a\xb4\xc2\x36\x95\xe7\x9c\x9a\x9e\x2d\x09\x59\xe4\x79\x72\xf2\xf2\x65\x83\xf5\xe3\x37\xe8\x21\xf8\x53\x24\x96\x59\x42\xa1\x3f\xc8\x7c\x2c\x06\x29\xe2\x34\x60\x28\xa7\x61\xc0\xca\x53\xd1\x5e\x9d\x3e\x1f\xab\x8f\xc9\x0b\x48\x23\x2a\x4c\xc7\x54\xe5\x5a\x57\xab\xdf\xf9\x88\xd6\x40\xc4\xa9\xe4\x18\x1d\x78\x3e\xa9\xfc\x6d\xac\x9d\x2e\x62\xc6\x48\x0b\x7b\x59\xd5\xf5\xe9\x48\x04\x00\xc3\xa5\x79\x42\x81\xc5\x6f\x9e\x9d\xcb\x58\x09\x47\x71\x42\x81\x41\xc7\x6b\x71\x95\x1f\x9b\xbe\x93\x4e\x71\xf5\x38\xca\x4f\x4f\x17\xd8\xfd\x98\x61\x22\x62\xb1\x5d\x5d\x4d\xee\x49\xa4\x54\xdf\xe4\x8b\x7f\xb6\x5f\xd8\x24\x44\x2c\x98\xc5\x5c\xc8\xfe\x45\x1e\x54\x31\x86\x04\x9c\xc3\xf2\x89\x58\x08\x89\x91\x02\x9b\x97\xe6\x0a\x1a\x2a\x15\xfc\x2e\x7a\x27\xe2\x0c\x02\x1c\x1a\x27\xa9\x4a\x9f\xf4\x40\x2c\x20\x62\x19\x2a\xac\x11\xed\x36\xc7\x87\xbc\x84\x5a\x16\xb4\x7b\x8d\xd6\xbd\x58\x26\x86\xe4\x31\x10\x59\x0f\xf9\x50\x78\x29\x62\xa9\x81\xb9\x14\x74\xbf\x94\x7f\xcb\xd7\x26\x62\x95\xa4\x98\x69\xc0\x92\x31\x6f\xf9\xd6\x9d\xb7\x8a\xd0\x84\x26\x7f\x39\xef\x46\xc4\x3a\xca\xc4\xc0\xb5\x76\x55\x55\x85\x63\xe8\xfd\xe3\x2c\x0c\xe1\x2b\xb0\x42\xc4\x26\xb6\x58\x10\xe2\x03\xe1\x5b\x84\x60\xf9\x87\x31\xd6\x78\x30\x8b\xf7\xcd\x11\x47\xfe\xfd\xba\x02\x21\x39\xc4\x4b\x52\x60\x7d\x83\x72\x5c\x87\x7d\xc6\xc3\x8e\x21\xe1\x98\x22\x7b\x2a\xdb\xaa\xa8\x5e\x3e\xcf\xee\x6b\x93\xfb\x86\x8c\x61\x06\xa6\x5b\x0c\xfa\x68\xa1\x6b\xb3\x9a\x21\x5e\xb2\xf7\xd4\xb1\x32\x69\x16\xb5\x4a\x02\x46\x55\x67\xbd\x1e\xab\xdb\x06\x1f\x4f\x87\xe9\xa7\x9e\x04\x32\x34\x13\x99\xdf\x39\xef\xe1\xf0\x24\x49\xa0\x12\x0c\xbc\x51\x24\x48\x16\x3f\xf3\xba\x3d\xc9\x62\xee\x57\x26\x61\xaa\x82\x9e\x9c\x6e\xe0\x92\xec\x9b\x19\x69\x20\xc1\x6f\xd0\xe7\xeb\xc7\x7c\x47\x1e\x81\xcb\xa6\xdf\x85\x57\xb9\xe9\x45\x11\x44\x12\x09\xa2\x0d\xba\x3a\xe5\x1e\xad\x2e\x92\x08\xc0\x7a\x7c\x68\x10\x5d\x9d\xc6\x7c\x7a\x22\x89\x53\x07\x1f\xf6\x23\xa7\x69\xe4\x7c\x73\x16\xfa\xa2\x98\x2b\x24\x16\xff\x42\x47\x25\x92\x24\x54\xe0\xf9\x77\xfa\xd2\xd9\xf6\x75\x60\x72\x3a\x37\x6a\x49\xa2\x43\x97\x67\xd4\xf0\xb3\xca\xcd\xb3\xec\x27\x61\x92\xaa\x14\x09\x5e\xd6\xeb\xcd\x19\xbf\x2e\x49\x75\x86\xc2\x1d\xbf\x56\x6b\x7f\x04\x0f\x03\x74\x48\x37\xcf\xeb\x9f\x8b\xdd\x0a\x3d\x82\xed\x6e\xf1\xbc\xdb\x5f\x2f\x76\xab\xbe\x57\x4c\xfa\x9e\x5e\x2b\xb4\xdc\xc8\xcf\xd9\xb9\x85\xca\x08\x70\x56\x51\x3d\x0e\xb1\x64\xfd\xe1\xd5\xe4\xbe\x4b\x37\x84\x53\xb5\x52\x91\x64\x19\x27\x21\x4b\xe2\x8c\xba\x1f\x0c\x8d\x44\x32\x91\x0c\x41\x1e\xdc\x05\xcf\x3d\xa9\x94\xc4\x23\x87\xc9\x03\xd9\x38\xb1\x34\x59\xf4\xcc\x6b\x7f\xab\xa8\x46\x4c\xe6\x8f\x0a\xc8\x84\x7b\x84\xf6\xf3\x54\x7c\xc5\x54\x5e\x3a\xd3\xd9\x38\x4f\xa2\x22\xce\x68\xbb\xd6\x55\x69\xf6\x1f\xfe\x83\x41\x47\x32\x1f\xa6\xa6\x12\x0a\xa9\x37\xd4\xe9\xf3\xb6\xaa\x7c\x89\xa8\x48\x74\x18\xa2\x9d\x4a\x03\x31\xc7\x75\xcc\x21\x8d\xd3\x6b\xeb\x38\x55\x2e\x72\xb4\xac\xcc\x5c\x3d\xd0\x77\xe2\x89\x4f\xd5\x3f\x83\x85\x1a\x4a\xed\x44\x79\xce\x3f\x90\xee\x3c\x14\x47\xc7\xfc\x79\x50\x3d\x52\xd4\x37\xeb\x00\xb1\x2c\x87\x4f\xaa\x46\x98\x5e\xcc\x44\x21\x91\xf0\xbf\x9e\xa6\x62\x8a\x22\x31\x46\x22\x88\xbc\xfd\x00\xf9\x36\x42\x24\x8a\xc4\x58\x65\x28\x6a\xa9\x4f\x75\xde\x4e\xbf\x4f\x08\xe3\xa8\x27\xb9\x58\xf7\x42\x29\xce\xec\xbb\x83\x7a\x66\x8b\x26\x90\x24\x52\x79\xb8\x7b\xf5\x9e\x1b\xa8\xef\xa5\x7b\x1f\x9f\xeb\xeb\xf3\x6e\x52\x02\xca\x60\xe5\x2b\xbd\x86\x07\xd0\xaf\x57\xbb\xe5\xf9\x30\x63\x02\x10\x7a\x98\xa2\xff\xde\x29\x73\x74\xba\x48\x7c\x2c\x12\x1b\xc6\x88\x87\x5a\x18\xf3\x08\x1f\x84\xa4\xd7\xf3\x0a\xce\xc9\x48\x5b\xe0\xf8\xe2\xde\xab\x16\x16\x33\x74\x66\xd7\x6a\xb0\xe8\x25\x6f\x1e\x30\x9b\x33\xad\xd4\xa3\x4e\x69\x10\x40\x3a\x2e\xc2\xa6\xc4\xe8\x00\xb0\x15\x69\xc0\x24\x16\xa7\x90\xc1\xbf\x81\xfa\x17\xe4\xbc\x6f\x94\x80\xa5\xb1\x79\xf3\x0c\x2f\xa7\x62\x86\x72\x11\x69\x08\x26\xe3\xde\x4b\x72\x35\x83\xfe\xd8\x28\xa2\xa0\x97\x13\x79\x46\xc7\xd2\x35\xc5\x09\xa0\x45\xe2\xe1\x10\x93\x34\xb0\x48\x13\xce\xf1\xaa\xdd\x7a\x7d\x25\xcd\xaf\xbc\x7d\xed\xbe\x98\x5e\x92\xef\x52\x72\x69\xfa\x46\xbb\xd3\x68\x62\x13\x93\x45\x37\xdd\x7c\xe5\x8c\x48\xb9\x64\x38\x74\xab\xf6\x75\x3f\x71\xca\x52\xa1\x62\x84\xb3\x6d\x5e\xab\xb6\x5a\x18\x73\x81\xe8\x57\xa4\x59\xc4\x70\xc9\x77\x46\xf5\xe2\xe1\xe9\xc7\xe3\xce\x9f\x25\xe3\x31\xb2\x55\x56\xef\x50\xab\xdc\x3c\x0e\xac\x0f\xc2\xf7\x10\x36\x23\x79\x7e\x64\xc7\x7c\x3a\x62\x36\x76\xa4\x95\x15\xfa\xa7\x90\x4c\x62\x0d\x41\x79\x3a\x2c\xab\x03\xc6\x9f\xfc\x65\x94\x25\x8f\x04\x25\xe8\xb6\x14\xf1\x84\xba\x39\xe3\xf4\xa5\x3a\xb2\x3c\xea\xa3\x2d\xab\xb2\xad\x3f\xff\xaa\x6a\xd9\x1f\x69\xd3\x04\x7a\x3d\xdb\x4d\x55\x15\x23\x66\x34\xd7\xc7\x30\xf2\xfe\x9e\xd1\xfb\x7b\xa8\xcc\xb4\x94\xd7\xf7\xb2\x0a\x03\x11\x4a\xea\xb7\xb9\x00\x8f\x48\x21\x48\xb0\x88\x63\x71\x44\x25\xc5\x66\xbd\xb8\xfa\xa3\x6f\x22\x9b\xb7\x80\x17\xa9\x3f\x9f\xe1\x38\x0b\x62\xa4\x90\x66\x18\x23\xea\xfc\x85\x4d\x91\x97\xa8\x1c\x7b\x5f\xcd\xd8\x8f\x44\x0a\xdc\x8c\x0a\x61\xba\x35\xbf\xbb\xd7\xfe\x2c\x82\xd0\xbe\x18\x4f\x21\xb8\x51\xdb\x53\x16\xfc\x33\x8c\xcf\xab\xee\xf4\xed\xc1\x10\xa0\x75\x55\xeb\x22\x05\x49\xe0\x04\x52\x34\xaa\xea\xd6\x56\x45\x5e\x7d\x79\x74\x15\x65\xa9\x5f\xe1\x30\xd2\xd3\xbc\xe6\xc7\x45\x69\x1c\x05\x58\x5e\x9c\xe1\xd7\x1f\x5d\xc4\x90\xa0\x0c\x06\x52\x0a\x03\xf5\x8c\xf0\x7f\x36\x73\x2d\x8f\x30\xd8\xbb\x94\xcd\xeb\xb0\x3d\xb1\x50\x41\xd4\x4b\x68\x0f\x96\x4b\x73\x7e\xfe\xb3\x28\xe4\x58\x94\x92\x37\xcd\x09\xba\xf5\xec\x62\x36\x59\xb0\xc8\x08\xc4\xae\x1e\xf2\x92\xd4\x68\xfc\x35\xe3\x8c\xa3\x21\x77\xb8\xf9\xf1\x78\xbd\x7e\xbc\xdd\x2f\x7f\x3c\x3f\xaf\x1e\x77\xfb\xeb\x1f\xcf\x8b\x51\x26\x90\xc5\xca\xa0\xc3\x5c\x93\x7a\xc8\xf4\xf4\x49\x24\x32\x86\x7c\x7a\xdb\x33\x4e\x2b\x4b\x2c\x09\xb1\x50\xfa\xec\x62\x15\xa1\x60\x29\xcf\x70\x55\x78\xf8\xef\xed\x8f\xcd\xea\x79\xf7\xf4\xe7\xaa\xbf\x01\x16\x42\x64\x7a\x00\xe7\x0e\xe4\xa1\x59\xf7\x5b\x38\xe3\x82\xfc\xd6\x1a\x1a\xc7\x02\x77\x75\xaa\xfb\x0a\x1e\xc1\x38\x08\xc4\x38\x48\xad\xeb\x13\x78\x92\xc1\x6e\xb1\xfd\x07\x76\x5f\x79\xc6\x0d\xc1\x04\x8f\x30\xa5\x82\x5e\xe8\xe0\x1a\x33\x21\x23\x8c\x07\x92\xdb\xf3\xe5\xdb\x9d\x56\x88\x0a\x96\x71\xa3\xdc\xfd\x76\x46\xd7\x39\x09\x08\xc1\x32\x4b\x8a\x8c\xc4\x6a\xb6\xd8\xec\xd7\x8f\xfb\x1f\xdb\x6b\x7f\x49\x19\x5a\x45\xa4\x4a\x87\x9c\xe8\x72\x7c\x43\x9c\xa2\xda\xcc\x6a\xb7\xbc\x8b\xcd\xcf\x7e\x18\x54\x98\x68\x17\xb8\xe8\xdc\xd2\x70\x76\x39\xa5\x39\xfa\xc9\xcb\xd5\xf3\x6e\x7d\xb3\xf6\x62\xf0\x82\xe9\x24\x83\x70\x5c\xec\x83\xe2\xed\xf3\x94\x3b\xd3\x4c\x71\x35\xaa\x68\x85\x25\x14\xc5\xd5\xe9\xcb\x42\xe6\xbb\x67\xc4\xcd\xf5\x90\xb7\xaf\x75\x5e\x6c\x3f\xaa\x1e\x66\xc0\x8c\x54\x09\xf3\x71\x71\x0f\x2f\x3a\x1b\xa6\x64\xc6\x66\xe8\x08\x51\x30\xe0\x19\xf4\xa7\x2e\xfe\x3a\xda\x34\xbb\x17\x08\x58\xca\xfb\xf0\xd8\x16\xea\xf7\xe1\xc3\x83\x38\xc2\x18\xba\xc7\x4f\x38\xba\xa3\xe9\x5d\x80\x8e\x31\x4c\xfb\xbc\x5a\x3f\x5c\xfd\x78\xde\x2e\xae\xee\x57\xfd\x09\x40\x61\xba\x94\x14\x20\x76\x83\x92\xba\xef\x60\x59\x40\x04\x08\xb8\xf8\x53\xf9\xe7\x50\xd5\xc5\x92\xf1\x9f\xcb\xcf\x60\x99\x94\x9e\x8b\xaa\xed\xa9\xf2\x06\xb2\x33\xc1\x83\x90\x39\x44\x6e\xf7\x94\xb7\x45\xa5\x90\x43\xb4\x69\x6b\x99\x97\xdd\x8a\x3b\xd7\xc0\x3d\xb7\x3e\xf1\x00\x88\xbf\xb0\xdb\xfd\x1f\xab\xfa\x20\x8b\x31\xbe\xae\xbf\x96\x25\xe9\x66\x75\x49\xe0\x58\xf0\x90\x11\x5f\xf9\xbe\x05\x79\xf8\x16\xd0\x27\x78\xc4\xe2\x8c\x26\x4b\x9f\x51\x9c\xf5\x88\x45\x82\x15\x69\x88\x7e\xdf\xc8\xa6\x71\x89\x08\xf1\xcf\xec\x5f\xbe\x0b\x64\x38\x42\x6d\x7d\x6a\x5a\x30\x7d\x78\x78\x23\xeb\x36\xd7\xf9\x51\x96\xed\x5f\x15\xe1\xb9\x33\xa5\x32\x45\xeb\xa2\x96\x2d\xec\x5e\xf3\xda\x20\xa5\x89\x7f\x76\x16\x48\x04\x2c\x1d\xe5\xe7\xb6\x95\x6f\x24\xd1\x7d\xd6\x7b\x11\xc1\xf8\xcf\xd7\xb1\xc6\x53\x75\xab\x0a\xb5\xee\xaa\x66\x06\x27\x16\x5c\x44\x04\xe8\xd8\xdc\x2d\xb6\xab\x68\xff\x3c\x38\x93\x5c\x88\xc4\xd5\x3b\x51\xa1\xd3\x1e\x2b\x27\xae\x07\xc3\x9e\x4b\x30\xda\xd3\x0d\x96\x4e\x8a\xb2\xb9\xa9\xab\xde\xe0\xe2\x2a\x93\x88\x78\xed\xde\xf6\xea\xb7\x4b\x22\xcc\xf9\x39\x04\x57\x92\x80\xa9\xdd\x12\x01\x87\xaa\xfe\xdc\xd5\x52\xc3\x03\xb4\x72\xd6\x51\x07\x21\x01\x60\x7f\x6e\x56\x7b\x39\x86\x53\x76\x6d\x31\xe2\x6f\x0e\xa7\xa2\xcd\x17\x5a\x43\xd3\xd0\x6e\x3b\x3f\x07\x37\x89\xab\xda\x5d\xb5\xaf\xce\x40\x9c\x75\x51\x12\x13\x73\xaa\x0c\x23\xb1\xc7\x3d\x73\x7f\x94\xf9\xb8\xa6\xe7\x9f\x61\xe4\x27\x86\x11\x1c\x21\x64\xcf\xa7\x02\x1a\x1f\xeb\xdf\xe2\xd7\x78\xa6\xd0\xe4\xff\xdf\xbf\xfe\xa2\xca\x22\x0e\x83\xe4\x1b\x7a\x8a\xce\xef\xe3\x72\xdc\x18\x83\xb8\x8f\x96\x2a\x8a\x88\x31\xe9\x6b\x18\x0b\x57\x8f\x73\xde\x26\x87\x84\xe1\x72\xd6\xe8\x5a\x1e\x27\x24\x3c\x82\x03\x4b\x10\x02\x70\x8d\xd3\x01\x6d\x81\x53\x31\x73\x59\x38\x40\x66\x9c\xfb\x79\x7f\xff\x73\x0f\x26\x6f\xf7\xc9\xc4\x05\xe5\x36\x53\x48\x3f\xb0\xa7\x5f\x77\xd5\xd5\x67\x0b\xb3\x2e\x2a\x36\xca\xc7\x9a\xf6\x6a\x94\xe2\xe0\x56\x71\x0c\x57\xdd\x57\x2f\x8f\xf0\xd1\x4b\xe0\xcc\x57\xf4\xe9\xe9\x6c\xd4\xaf\x0f\x7f\xad\xe7\x2d\x44\x10\xf3\xb8\xe7\x5a\xda\x9f\x1a\xa8\xf7\xd0\xbe\xee\x75\x0f\xdc\x10\x01\x4b\xf0\xd3\x3b\x62\x14\x06\x69\xbf\x9b\x3e\x54\x26\x42\x46\x39\x00\xb7\x61\x20\xf6\x69\x7a\x85\x24\x30\xb1\xdb\xe1\xaf\xeb\xd3\xcb\xbc\x95\x71\x1d\x4d\xa8\x03\x08\x3f\xe8\xf7\xb8\x89\x67\x2e\x12\x0e\x58\xed\xfa\x2a\x8b\xf6\x19\xde\x41\x16\x84\x4f\x9b\x75\x4b\x03\x12\xd1\x5c\x74\x9b\xcb\x62\x60\x4c\x73\xe1\x89\xaf\x51\x8a\xe9\x6a\x23\xd2\xd0\x52\xd1\x56\x69\xba\x45\x62\xc4\x5a\x2b\x44\x1a\x71\xf4\x8e\xdb\x01\x8f\xf1\x06\xa6\x5b\x39\xcf\xaf\xd8\x22\xe5\x19\x3a\x89\xa6\xdd\xe2\x67\xfa\x9d\x8a\xb2\x10\xa9\xd4\x46\xf4\xd2\x62\xbf\x00\x48\x30\x6d\x6c\x62\x89\xd4\xa4\x48\x2a\x2f\xf3\xfa\x1a\x8a\xfc\x1d\x6a\x12\x03\x2d\xaa\xf2\x32\xcb\xb9\x10\xcc\x31\x68\x1e\xb1\x1e\xd4\xce\x5e\x04\x0f\x2d\x4d\x55\x8a\x2b\xac\x4c\x3e\x66\x00\xfc\x12\xde\xb9\x14\x72\x9a\xff\x7e\x49\x35\x54\x08\x1e\x59\x45\xdb\xb4\xab\x26\x99\xbe\x03\x1e\x07\x58\xc0\x72\xd7\xb9\xab\x7f\xb5\xa0\xcc\x0e\x4d\x98\x0a\x08\xc1\x8d\x2a\xb2\xd7\xb5\xfc\xc8\xcb\x97\xe5\x38\x5c\x2a\xb8\x08\x7b\xe5\x61\xa8\x9b\x5c\x96\x0d\xa9\x92\xa3\xb6\x64\x73\xf5\x39\xbb\x1f\xc1\xa8\x80\x9a\x28\x2c\x3d\x2f\xc6\x74\x0c\x85\x4c\x32\x04\x19\x37\x8f\xf0\x41\x1c\x17\x9b\x91\x68\x40\xd7\x81\x0a\xe9\xda\xb7\x76\xf2\x46\xb3\x20\x46\xce\x18\x7c\xd7\x63\x69\xac\xd9\xec\xc8\x12\xaa\x9a\xe8\xd5\xfa\x77\xd5\xd5\xe9\xf3\x4c\xf8\x7e\x76\x98\x49\x92\xc0\x11\x1c\x11\x76\xa4\x2a\x66\x46\xab\x90\x31\x55\x8a\xae\x64\x5d\xae\xca\xea\xf4\xf2\x3a\x06\x78\x08\x99\x46\x9e\xd3\xd7\x71\x2b\x7c\xdd\xfc\x84\x14\x41\x64\xa7\x65\x00\xfd\xf1\x8a\xa1\x26\xcd\xee\xea\x1f\xe3\xa0\x99\xd0\x59\x98\x38\x84\xe6\xcd\x8c\x49\x49\x08\x13\x10\x11\xd2\xfa\x71\xbd\x5b\x2f\xee\xf7\xab\x87\xf5\x76\xbb\x7e\x7a\xdc\xdf\x2c\x96\xbb\x27\x6f\x96\x0b\x93\x58\x8a\x7c\x4b\x0b\xe7\xb0\x49\xdf\xd4\x0c\x0a\x61\x7a\x6b\x11\xb5\x99\x27\x68\xa1\x0b\xc3\x09\x22\xc5\x25\xe0\xa6\x38\x51\x88\x12\xeb\x7e\xbe\xdf\xaf\x04\x64\x0c\xc7\xa6\x79\xad\x3e\x7a\x26\xc9\xbf\x38\x04\x6c\x1a\xf7\x39\xe7\xfa\xd3\x27\x90\x5d\xb3\xcd\x32\x2f\xec\xf7\x90\x97\xbb\xc3\xcc\x3a\x10\xd6\x84\x48\x9a\x63\x06\x85\xa0\x2f\xc4\x56\x22\x0b\x42\x89\x10\x32\x79\xd8\xaf\xf7\x67\xea\xd7\x44\x16\xa4\x0c\x0d\xab\xbf\x8e\x3f\x9f\x5d\x4d\xb3\x80\xf1\xd4\x01\x63\x7c\x98\xf3\xcb\xab\xce\x02\x03\xf4\x65\x74\x46\xe4\x7d\x5e\xc2\xaf\xba\xf2\xac\xd9\x22\x0b\x80\xaa\x27\x5d\x19\x83\x7c\x91\x4b\x59\x9b\xed\x87\x3c\xfe\x84\x3a\xfa\x2b\xbc\xa3\x3b\x49\xc8\x88\x44\xa8\x7d\xcd\x9b\x83\x2c\x3f\x71\xaf\x6d\xda\xbc\x28\xda\xd7\xe6\x78\x32\xa4\x33\xfd\x91\x97\xfd\xd8\x84\x82\x54\xe6\x6e\x64\xf9\xb2\x93\xe5\xcb\x65\x1a\x5c\x1f\xbc\xff\xa6\x74\x73\xfa\x72\xb3\xd8\x80\x67\xb9\x5a\x56\x25\x5a\x95\x93\xe0\x62\x96\x06\xb1\x75\x61\xc9\xeb\x5c\xc3\xaf\xbc\x9c\x1a\x78\xb3\xf3\xa5\x59\x82\xec\x26\xff\x29\x4b\xd3\x93\xf4\x89\x2c\xd5\x22\x1c\xe6\xd0\x5a\x57\x67\x9d\xc7\x8c\x85\x54\x2c\x7c\x75\xff\x63\xd5\xe3\xd9\x33\x1e\x11\x09\x5b\x03\xe5\x98\xf6\x46\x64\x3c\x26\x66\xe0\x91\xe8\xf8\x8c\xda\x5f\x64\x9c\x85\x8a\xa8\x97\x74\x65\xc0\xec\x4d\xaf\xfe\x24\x32\xae\x12\x24\x5b\xef\x0c\xdc\xc5\x25\x25\x36\xd7\x37\x0b\xad\x55\xbd\x2e\xe6\xfe\x38\x22\xe9\x18\x6d\x4c\xbe\x33\x50\xe9\xe7\xbe\xc1\xba\xb2\x2f\xfc\x4a\xd3\xa7\x96\x3c\x26\x91\xa3\x8b\x42\xe3\x22\x53\x96\x23\x31\x76\xb7\xb8\x0c\x65\x5e\xc9\xac\x97\x4e\xb3\xb8\x87\x33\x23\x9a\x10\x83\x9b\x3d\x00\x7b\xfa\x48\x9a\x13\x26\x7f\x08\x10\x54\x88\xb5\xbb\xf0\x6a\xb5\x21\xd5\xd9\x5c\x57\x8e\x96\xe9\xfc\xf6\x90\x41\xc0\x48\xb2\x70\xfd\xb8\x5c\x6c\xf6\x18\x18\xda\xee\x37\xcf\xab\x7d\x5f\x8e\x21\x32\x10\xe4\xb6\x62\x96\xc5\xf1\x0e\x6f\xa1\x28\x26\x5c\x81\x22\xb3\x31\xe9\x50\xd2\xe6\xbc\xfa\x7d\xc1\xbc\xc9\xac\xee\x6b\xaa\xfa\x4c\xe9\x25\x28\x55\x66\x0d\xe0\xa6\x4b\x7a\x87\x07\x95\x43\xd9\x76\x76\xed\xea\xb7\x86\xe3\x98\x5c\xdd\xd9\x69\x74\x98\x0c\x53\x85\xef\x40\x55\xea\x41\xbe\x41\xb3\xaa\x75\x14\x5c\xe2\xd2\x98\x24\x64\xa3\x60\xb2\xf8\x3b\xbe\x05\x21\x43\x20\x46\x7d\x53\x5d\xcd\xf8\x1e\x85\x0c\xad\x51\x6c\x2a\xe9\x70\x53\x03\xfc\xdf\x58\x36\xe9\xbb\x6f\xdc\x85\xce\x65\x94\x44\x69\x1f\xa8\x3c\xa2\x55\x31\xbb\x52\x94\x86\x5e\x4f\x74\x1c\xe6\x1d\x3e\x22\x19\x31\xa1\xfd\x2a\xd1\x99\x2f\x37\x85\x1c\x97\xa8\x0a\x19\x47\x1a\x13\xe5\xc4\x0e\x94\xff\xd5\x36\x24\xe3\x54\x20\xa4\x4f\xcb\xb2\x73\x11\x7e\xb4\x67\x63\xb6\xbe\x73\x46\x50\x93\xea\x08\xe5\xb2\x3a\x1c\x1d\xc4\xfa\x0f\xdf\xac\x19\x9a\xc9\x7f\x6e\x96\x5b\x2c\xb4\x24\x8e\xfc\xaa\x9e\x78\x38\x32\x91\x01\x73\x8a\x77\x85\x3c\x35\xb0\x94\x5f\x71\xfa\x32\x51\x02\x75\x11\xd6\x8f\x3f\x57\xdb\xdd\xd3\x73\xd4\x37\x18\x25\x1c\xfb\x05\xe9\xba\x8f\x73\x79\xb3\xfb\x4d\x6c\x26\x1d\xcc\x7b\x5d\xde\xa0\x3c\xde\xea\xf7\x51\x96\x0d\xd5\xed\x4e\x09\x07\x84\x4c\x63\x86\x58\xcb\x17\x22\x1e\xa9\xe7\x13\x21\x4d\x04\xe6\x65\xb6\xcb\x71\x69\xab\x90\xa9\x88\x30\x50\x8b\x15\xd9\x63\x2b\x09\x5b\x2c\x22\x58\x5e\x72\xfd\xb3\x33\x2b\xab\x59\x94\x57\x32\xae\x70\x17\xba\xcd\x27\x0c\xff\x5d\x83\x46\xe8\x0f\x31\x94\x8d\x82\x13\x92\x89\x04\xcb\xcc\x87\xdd\xaf\xdb\xf9\x36\xf7\x8b\xdd\xdf\xdb\xf9\x24\x67\x36\x75\x69\xc0\xf5\xe6\x66\x7b\x27\x9b\xd7\xe9\x2b\xe2\x9a\x0b\x12\x59\xf7\x08\xc0\x89\x91\x20\x45\x20\xbd\xb8\x27\x6a\xbe\x9c\x9f\x2e\x82\x33\x2c\xb0\xfa\xaf\x53\xde\x0e\xe2\x23\x42\xca\x40\xfa\x52\xe0\x2d\xc8\x62\xfc\x68\x32\x31\x1e\xf7\x4b\x35\x5b\xbb\xea\x6a\x3b\x1b\x31\x29\x01\x77\xb6\xcd\x3f\x26\xa6\xa3\x94\x9a\x34\x54\xc9\x61\x59\x94\x66\x9b\xbf\x94\x57\x57\x4f\xd7\x95\x3e\x0d\x2b\xc3\x54\xb1\x78\xbe\xbb\x48\x95\x45\x41\xdc\x27\xc5\x31\x7a\xf5\x20\x3f\x7d\x29\xca\x00\x7d\x96\x2a\x13\x22\x1e\x3e\x34\x44\x38\xae\x4a\x03\x98\xf5\x7b\xa8\xde\xbf\x70\x9a\xcd\x2f\x24\x85\x26\x69\x87\x0f\xbf\x72\x9d\x1f\x45\x65\x42\x91\x8c\xeb\x44\xab\x7a\xc4\x48\x3d\x59\x61\xb4\xcc\x90\x58\xcf\x59\xe4\x83\x10\x96\x90\x26\x92\x0a\x7c\xe0\xd8\x6b\x18\x5e\xb8\xa2\x89\xac\xee\x51\xf5\x0f\x30\x3a\x89\x94\x61\xd8\x6f\xbd\xb3\xaf\xc3\x86\x14\x67\x6c\x4e\xaa\x39\x5c\xf8\x20\x6d\x14\x2a\x4a\xbe\x38\xfc\xce\xc4\x07\x93\x96\x29\xed\xd9\x26\x5e\xa0\x6c\x9b\x49\x8e\x53\x5a\x09\x48\x08\xb8\xde\x3c\x44\xcb\xa7\xf5\x63\xff\xbb\x21\x89\x1b\x02\xf4\xe1\x3b\xbb\x95\x87\x01\x27\xa6\x82\x24\x40\xc6\x9c\xdf\xf2\x58\xf5\xbf\xd9\xd4\x4b\x53\xed\x15\xcd\x4f\x38\x1d\xf6\x3e\xb3\x3b\x0b\xc1\xa9\x30\x26\x7b\xf4\x81\xca\xf0\x49\x22\x72\x08\x03\xa8\x50\x50\x26\xcf\x07\xc3\x69\x59\x9a\x4c\x5c\x15\x66\x19\xe2\x9e\x31\xac\xd2\x4d\xce\x1f\xc7\xb9\xd8\xe6\xb0\xd4\xab\x30\x23\x4c\x23\xc2\xca\x9e\x3e\x90\xd1\xb9\x37\x8a\x42\x36\xf8\xf3\x21\x73\x1e\xbd\x8a\x82\xd4\x13\x06\x5f\x24\xdc\xf2\x5d\xe3\x30\x72\x20\xe6\x6e\x0f\x19\x7b\x9f\x2a\xe2\xc4\xc0\x79\x94\x9f\x44\x6e\xd0\xcd\xce\xab\xca\x7c\x9e\xad\x3a\x54\x91\x32\xd2\x78\xa5\xbe\x81\x9e\x6b\xf4\x28\x91\x49\x50\x38\xcc\x02\x6c\xa0\xde\x82\xf6\x57\x8a\x8d\xf0\x50\xfe\x1b\x14\x5b\x3d\x5b\x57\xa5\x92\x34\x43\x2e\x7d\xcc\x00\x38\x7c\xfa\xec\x26\x12\x1b\x12\xf1\x62\xfe\x52\xce\xb2\xac\x2a\x8d\x18\x6e\xbc\xa4\x2d\x9a\xbf\xbc\xb6\x8b\xf3\x79\xa8\xc4\x1f\xc0\x03\x4c\xb7\x8e\x65\x83\x5d\x13\xcb\x02\xcc\xfc\xed\xf7\xad\xac\x51\xc9\x94\x42\xbf\x9e\xa3\x7d\x76\x5b\x3c\x13\xca\xd5\xe2\xfd\x37\xc8\xba\xf8\xfc\xb1\xbd\xde\xca\x02\x65\x06\x30\xe1\xe1\xcf\xcb\x3b\x63\x75\x60\x1a\xb9\x14\xf5\x9f\x5a\x33\xfe\x58\x30\x98\xef\x7a\x95\xcd\xeb\x78\x45\x54\x22\x10\x9e\x59\xd6\x2d\xe0\x9d\x1b\xec\x88\x68\xa6\x37\x2a\x52\x81\x94\x1e\x1e\x6f\x41\x5c\x39\xb3\x3e\x26\x16\x04\xa0\xf9\x05\x39\x6e\xbe\xfd\x85\xac\x8e\x9d\x7c\xca\x66\x4d\x91\xcf\x28\xf0\x8d\x32\x89\x30\xcd\xfb\xdc\x59\x84\xfd\x62\xa2\x64\x1a\x47\x76\x70\x47\xa1\xa6\xe3\xca\x6e\xd1\x1a\x6f\x46\xaa\xdb\x8d\x06\x80\xcb\x2d\x94\xc1\x58\xf5\x20\x9a\xb0\x06\x4f\xfe\xf5\xc7\x83\xc1\xaf\xa2\xb3\xae\x91\xc9\xf0\x06\x9c\x38\x6a\x1f\x11\x9b\xc7\xc6\x94\x8a\x39\x1e\xb3\xd8\xac\xef\x40\xbe\x0f\x43\xaa\xa5\xc4\xca\x9b\x3d\x65\x74\x37\x5f\x5f\xb9\x06\x66\xba\x99\xd8\xcd\xd2\x95\xae\x9c\x66\x73\x18\xf5\x67\xb0\x0c\x61\x9a\xb9\xae\xa2\x69\xae\x54\x99\x98\x40\xe5\xc8\xda\xf8\x46\x6e\xf1\xf4\xe4\xc6\x08\x43\xc4\x0a\x55\x03\x63\xc3\x4f\x19\xcb\x91\x5a\xb7\x17\x36\x73\x44\x92\xdf\x48\x39\x4d\x4f\x0d\x3c\xc6\xdd\xba\xb2\x56\xbf\xca\xbc\xfc\x71\x2c\x2a\x69\x66\xd4\x0e\x42\x81\xb4\xc4\x12\x7c\xfa\x24\xf1\xca\x0b\x89\x76\x65\x03\x8a\x10\x15\x7f\xa7\x80\x73\x7a\x2b\x36\xb0\xa1\x9d\xb9\x24\x08\xf6\x6f\x7e\x94\x6d\xee\xd4\xf3\x7d\x58\x5c\x07\x69\x88\xf6\x40\x73\x2c\xf2\xce\xed\x7c\xfb\x4b\x75\x22\x77\x60\xc4\x0c\x6d\x97\x6e\xbd\xe8\x76\x6e\xc4\xab\xcf\x16\x6e\x1d\xc9\x3e\xcf\x7b\x95\xbb\xf4\xd8\xcc\x76\xd7\x31\x4f\xd1\x4b\xf8\x25\xdf\x61\x82\xf0\xd6\x89\xb0\x42\x7b\x5c\x2e\xd6\x75\x6d\x64\xb7\x3d\xfb\x40\xfc\xe4\x8f\x3b\x26\x0d\x04\x6e\x15\x0f\x4f\x57\x4f\xf7\xfe\x44\x69\x94\x60\x08\x74\x0f\x6e\xd1\x39\xbf\xcb\xea\x94\x73\xeb\x08\x66\x6e\xeb\xea\xa3\x7d\x9d\x94\x65\xeb\x54\x84\xbd\x66\xc1\xa8\x68\x66\xfe\x0d\x68\x96\x26\x88\xda\x3d\xd6\xb0\x5e\x3e\x75\x33\x69\xbc\xe3\x69\x26\x19\x7a\x1a\x07\xf9\xdb\xb1\x92\x8f\xd2\x85\x4d\xdf\xcb\x44\xe8\x5f\x5c\xd5\xd0\x8e\x80\xed\x9a\xd9\x94\x3b\x57\x67\xa6\xe5\xe5\x3a\x70\xc6\x08\xd6\x3e\x40\x82\x7d\x8b\x88\xb3\x70\x28\xb9\xec\xf6\xc5\xf3\x7c\xfe\x42\x23\x39\x14\xad\xfc\xbd\x1e\xc6\x76\x26\xe2\x26\x34\x87\x18\xcd\xe1\xb6\xfe\xdc\x55\x9d\x5f\x53\x00\x72\x6c\xa0\x91\xe3\xfa\x08\x26\xa5\x63\x87\xc4\xa5\xd1\x61\xb7\x1d\x79\x8e\xef\xc4\x65\xe0\x01\x88\xdd\x15\xe3\xbe\xc1\x2a\x5c\x5d\x9b\xaa\x78\xff\x9b\xdf\xa3\xce\xa2\x14\xa1\x23\x12\x89\x0c\xae\x72\x73\x53\xd5\x73\x52\xaf\x73\x67\x99\x9e\x24\xa6\x68\x05\x49\x16\x52\xd6\x70\x9a\x1c\xd1\x19\x8b\x89\x9e\xbe\x9d\x89\x53\x08\x9d\xe9\xc4\x10\x6d\x5e\x5d\x7a\xc2\x4f\x07\xf2\x9a\xdf\xac\x89\xd1\x64\x78\xed\x0f\x85\x04\xcc\xc0\xf4\xd4\xff\xca\x32\x67\xcb\x3e\x4b\x0d\x0f\xa7\x91\xae\x50\x7f\x43\x2a\x4a\x30\x41\x04\x03\xc9\xfb\x25\x4d\x4a\xa1\x55\x12\xf8\x62\xac\xd1\x6e\x3d\xde\x5a\xb5\x62\x29\x0c\x9c\x37\xce\x75\x9b\xde\xbe\x8e\xb5\x63\xfa\x70\x7a\xdc\xdb\x93\xa2\xcc\xf5\xac\x9f\x32\xe1\x00\x87\x18\xc1\xa4\xc7\xe6\x83\xd6\x9a\x21\xcc\x44\x23\x84\xe0\xa4\xdb\x1f\x75\x71\x96\xe1\x58\x68\x6d\x13\xcd\x7d\xf1\x06\xf2\x9a\xbc\xc3\xaf\xd7\x93\xb5\xf9\x68\x5d\x1d\xef\x86\xda\x04\x0a\x87\xf0\xba\x9a\xc0\x92\xb5\x49\x24\x96\x17\xfc\xbb\xca\xcb\xa5\xac\xdf\xe1\xc7\x71\x37\x07\x25\x6b\x23\x42\x7c\x2b\xb5\xb4\xd6\xf1\x7b\x4c\xc2\xf2\x1a\x18\x47\xc4\x53\xf7\xc6\xbf\xa7\xc2\xd0\x36\x4c\xd0\x12\x22\x60\x0f\xe1\x14\x5d\x8d\xbb\xef\x11\xa5\x68\x13\x3b\x7e\xeb\xce\xc2\xab\x7b\x46\x51\x61\x82\xc0\x24\x44\x41\x8b\x01\x32\x0c\xe2\xfc\x3d\x98\x81\x09\x12\xeb\x95\xa7\x9e\x89\x95\xa7\x3e\x1b\x60\x32\x81\x20\xd3\xc8\xad\x15\xe3\xba\x28\x13\x68\x8b\xd7\xf7\xe5\x4a\xb8\x15\xcf\x15\xbc\x85\x09\x43\x6e\xb5\x87\x8a\xae\x4a\xd3\x24\x7f\xf4\x2d\x59\xd2\xf3\x9c\xdd\x56\xfd\x8c\x33\x21\x33\x68\xaf\xe6\xcd\x3d\xc8\x63\x67\xf8\xcd\xce\x19\xd9\x14\xeb\x7c\xcb\x6a\x2f\xad\xf5\x87\xc5\x2c\xc1\xed\x5f\x16\x45\x37\x97\xf3\x72\xa4\x5f\x91\xfe\xcb\x77\x52\x94\xf2\x79\x00\xd9\xde\xd6\x39\x06\x77\x17\x4d\x53\xe9\x5c\x7e\x27\x84\xf0\x7d\x8a\xcc\xc4\x26\x40\x87\x1f\xe1\x21\xed\xea\x7f\xa3\xcc\x15\x01\x67\x2e\x6e\x96\xb9\x8e\x49\x10\xe0\x92\x60\xeb\xea\x80\xf1\x8e\xd9\xa7\x64\x92\x30\x45\xf3\x46\x95\xed\x27\x16\x1f\x93\x18\xd9\xd8\xce\x31\x09\xd3\xbe\xfa\xeb\xc9\xd9\xf3\x84\xef\x8d\xce\xa2\x8a\xe7\x95\xdc\xa7\x01\x18\x3f\x2f\xb0\x33\x89\x62\x49\x34\x52\x24\x1f\x05\x17\x4c\x02\x16\xc3\xd7\xef\x44\x85\x0b\xfb\xe3\xc8\x9f\x71\xd6\xa2\x49\x53\x49\x95\xb2\x9b\xfb\xf1\x2e\x6e\x52\xc5\x6d\x30\xf0\xb0\x4d\xda\x78\x1c\xa2\xed\x85\xa1\x1a\x7c\x0d\x63\x91\xcf\xae\x9d\x4a\x06\xee\x2b\xaa\xb8\x74\x04\xf5\xe7\xd1\x09\xfe\x98\xc4\x26\xaa\x27\x0c\x43\x2a\x9b\x8b\x4c\x1b\x46\xa4\x26\x8a\x3d\xe2\x6d\x0b\x67\xf9\xbc\x84\x11\x3c\xc0\xf4\xd9\x9e\x96\x2f\x27\x80\x70\x6a\xab\xf9\xf4\xcc\x92\x00\xeb\xbf\x3e\xea\xbc\x85\x8d\xa3\x5b\xfa\xe3\xdc\x06\x63\xb2\x44\x21\xbe\x40\x9d\xf2\xc2\x5c\x6f\x1f\x4f\x45\xf1\xd0\x63\x05\x4c\xa6\x95\x8f\x3a\x4c\x29\x78\xbe\xdf\xfb\x8c\xb4\x21\x26\x43\x34\x96\x70\x60\x31\x5e\x91\x97\x6f\xbe\x30\x7f\xfa\xca\x95\x25\x2d\xdb\xb1\xbe\xfd\xa4\xec\xf8\xc2\x22\x62\x62\x8d\x31\x5f\x54\xd9\xaf\x0f\x6e\x47\x77\x7c\x83\xb3\x11\x31\x5c\xa2\xa3\x5a\xa2\xef\xf4\x64\x7f\xc9\x17\xa8\x9b\x5d\xe5\xa8\x43\x5d\xfc\xc7\x3f\xb6\xd1\x09\xd2\x85\xdc\x6d\x16\x7b\xc2\x49\x3e\x2f\xa3\xe0\xbb\x12\x29\x63\xc0\x22\xc9\xc7\xda\x80\x1c\xd9\x49\x06\x62\x91\xb8\xca\x42\x7a\xf3\x63\x61\x00\x61\x40\xa4\x08\x0f\x38\xee\x1b\x82\x51\x3f\xd9\x55\xfb\x7a\xfe\xf5\xdb\x90\x66\x30\xe1\x49\x1d\x2f\xc6\x34\xbf\x79\x8e\x23\x21\x9a\xcb\xb2\x8c\x3c\x7b\x63\x53\x8d\xab\x51\x45\xd2\x67\x63\x85\x3f\x77\x8b\x10\x84\x81\xaf\x43\xea\x7f\x4a\x18\xc2\xe8\x1f\xf2\x12\x7e\x57\xd7\xf9\x4b\x3e\x6c\xd7\x10\x18\xe2\xb0\x44\x9e\x5a\xd9\xc0\x9d\xac\xcd\x52\xce\x50\x24\x10\x58\xab\x7a\x2d\x66\x62\x37\x18\x33\xa6\x09\x88\xb4\xf5\xf9\xb4\x87\xbc\x7c\x90\xbf\xd7\x23\x8e\x4a\x01\x71\x08\xc0\x07\x90\xe5\xad\x3c\x95\x6d\x31\xdc\x61\x2c\x42\xb4\xbf\x9b\x93\x6a\x74\x9d\x1f\x47\xaa\xac\x02\x62\x23\xb0\xc4\xfa\xbe\x37\xcd\x21\x06\x66\x48\x4b\xc0\x99\xc0\xed\x40\x7b\xba\x28\xfa\x67\x4b\x42\x91\x0d\xe2\xf0\x77\xf9\xcb\x2b\x34\xed\x43\x5e\x40\xb3\x3f\x6f\xdf\x40\x12\x05\xff\x3f\xd6\xde\x6d\xb9\x71\x1d\xc9\x02\xfd\x9d\xfd\x30\x0f\x24\x48\x90\xc4\xa3\x2c\xcb\x55\xee\xed\xdb\x58\x72\x55\xf7\x4c\x4c\x28\x12\x40\xc2\xe6\x98\x22\x35\x24\x65\x97\xfa\xeb\x4f\x30\x01\xf0\x26\xba\xf6\x3e\x27\xce\x43\x77\x75\x9b\x20\xc5\x0b\x90\xc8\xcb\xca\xb5\x62\x1b\xd6\x79\xab\x65\x55\x59\xae\xd0\x54\xf3\x06\x12\x8c\xe3\xcc\x55\x18\xa0\x7e\x75\x9e\xce\x4d\x55\x0f\x49\x1c\x7f\x1f\x49\x10\x27\xdd\xd3\xdf\x3d\xaf\xef\x73\xbd\xc3\xfa\xf0\xbd\x2a\x3a\x17\x7e\xde\x8d\x31\xbb\x9b\x04\xe2\x28\x72\xa1\xb4\x65\x6d\x5e\xd0\xb8\xcc\x50\x30\xfb\xc9\xe5\xe9\xbc\x23\x62\xf4\x1d\x36\x2d\x1b\x87\xab\x28\x62\x6e\xfc\x16\xd0\xcd\x9d\x87\x5c\xcd\xd5\xbb\xfc\x48\xb0\xd4\x4f\xa0\xb5\xc5\xd6\x78\xae\x87\xd3\x98\x40\xe3\x3f\x66\x77\x00\x8a\x0a\x4b\x57\xb7\xeb\xbf\x6c\x4f\x44\xa1\x18\xf3\xde\xc4\x82\x96\xeb\xa4\x8a\xeb\x4e\x01\x63\x7c\x66\xa5\xac\x34\x1e\xbb\xa8\x71\xf6\x31\x64\xe8\xa9\x6f\xec\x3c\xbe\x76\xbd\xe4\xb3\x77\x25\x23\x1e\x5b\x39\xf8\x5f\xc4\x64\xee\xff\x2c\x04\x39\xc1\x4f\x2f\x57\x77\xb7\x4e\xbf\x99\xea\x77\xfb\xf5\xea\xa9\x1f\x84\x56\xe5\x90\x94\x4a\x6e\xaa\x9a\xca\x8b\xd8\x2c\xd0\xf5\x65\xa8\xb8\x65\x6c\x71\xe9\xaa\xaa\xa8\xea\xc7\x9a\x2c\x9d\x1b\xa0\xb5\xa6\x20\xd7\x93\x85\x3c\x7e\xce\x2b\xff\x68\x02\xeb\xf2\xed\xe9\x4d\x95\x7a\x9e\x4b\x9a\xbd\x24\xc3\x2d\xcd\x77\x89\xbf\x2c\x99\x3b\xe2\x54\xdd\x2e\x43\x23\xec\x7b\x54\x50\x7b\x20\x82\xd3\xf1\x98\xfc\xb2\x61\x81\x22\x3e\xf4\xc3\xb9\xa7\x4c\xf5\x47\x62\x81\xbe\x47\x72\xf7\x56\x57\x9f\x24\x64\x6e\x09\xbc\x6e\x4b\x55\xd5\x35\xaa\x96\x44\x97\x26\x79\x0c\xc3\x12\x61\x79\xa9\xb1\xe9\xd5\xf3\x07\x6e\xbe\xcc\xb0\x8c\x13\xe9\x64\x59\xb5\x9b\xff\x3b\x41\x71\xb1\x99\x8c\xa7\x90\x61\x82\xd3\xa3\x82\xd6\xd4\x73\x7b\xd1\x66\xf1\x5b\xd3\xfa\xe5\x46\x68\x98\x94\x54\x68\xb1\x72\x0e\x9d\xc3\x72\x68\x2e\x8a\xd8\x93\x33\x22\x99\x72\xeb\xc1\x9f\x7f\xe6\x5f\x6c\x05\x26\x4e\x63\x2a\xa2\xf9\x6c\x35\xf9\xde\x37\xd5\xdc\x89\x5e\x5e\x5c\x26\xce\x2c\x82\xcf\x8a\x8b\x50\x9c\xb4\x9d\x6b\x5c\x67\x86\x47\x26\x72\x13\xfb\xc9\x92\x0e\xbb\x14\x42\x3f\xe5\x0c\x47\x4e\x4d\xaf\xd7\xb8\x2e\x4e\xf2\x77\x6b\xd4\x24\x8a\x51\x69\xd4\xe7\x27\x3b\xbf\xae\x59\xe8\xbb\x34\x89\x8e\xd0\xcc\xf5\x57\xe8\x9b\x4c\xaf\x87\x36\x47\xe2\xfa\x49\x09\xbd\xef\x7a\xad\x46\xde\xa0\x49\x43\x43\x9c\xb3\x5e\xc2\x6c\x2c\x39\xb6\x68\xb0\x4d\xca\xad\x70\xa6\x05\xb5\x4f\xa8\xed\x33\x93\x26\x3c\x71\xb0\x80\x1e\x3b\x30\x4a\xeb\xfb\x51\x69\xe0\xe9\x1c\xfe\xf3\x84\x27\x9c\x6c\x6c\x26\xcd\x42\x5a\xf4\x36\x1d\xfa\x00\x07\x5c\x75\xb1\xe3\x08\xff\xbd\x08\x6e\x30\x29\x58\x5a\xce\xbc\xb9\xeb\xc5\xc7\x32\x93\x9a\x98\xfa\x75\x75\x7d\xec\x37\x2c\xeb\x8b\x0f\xe4\x7a\x6e\xa8\x60\xc2\xe6\xf9\xbb\xf5\xe5\x91\xed\xfe\x20\xa4\x69\x6a\x71\x8a\xf5\xfe\xa3\x6a\x87\xf5\x29\x65\x4a\x0d\x28\xeb\xc7\xfb\xfb\xc7\x87\xfd\xcf\xdb\xdd\xf7\xeb\xe7\xd5\xcf\xfd\xf6\xe5\xe9\xe9\xee\x5f\xc3\xa8\x8c\x72\xc4\x79\x1f\xcb\xf4\x6d\x0d\x37\xd5\x45\xec\x3f\x7b\x32\x89\x31\xe5\xce\xd7\xe7\xd7\x5e\x65\x2a\x33\x2a\x95\x3a\x18\x8a\xe9\xdd\x02\x6f\xf1\x1a\xef\xb1\x81\x1f\xb6\xa3\xe6\xaf\x96\xe2\xc4\xcd\x34\xca\x88\xc8\x66\xbf\xc7\xbe\xbf\xd1\x21\x12\x26\xc8\xb5\xf5\x3b\xeb\xb4\xdc\xd5\x68\x74\x68\xc5\x3c\xdd\x5f\x77\x15\x85\x50\x97\x96\xd6\x60\x62\x88\x4c\xb8\xad\xf3\xd7\x57\xac\x97\xa6\xdd\x74\xda\x1b\x25\x12\xe6\xe8\x2b\x7e\xd9\x2e\x0a\xbb\x5b\xfa\xfb\x34\x9a\x7b\x2d\x2f\x5a\x83\x94\xcb\x23\x80\xc7\xf4\x31\x8d\x4e\x28\xee\x78\xaa\x3e\x07\x5e\x36\x3a\x26\x82\x80\x61\xc2\xc6\xd2\x3c\x37\x9f\x33\x6e\xdb\xc9\x5d\x89\x20\x80\xcc\xeb\xdc\xaf\x8e\xc7\x1a\xcb\x36\x57\xb8\xee\x9c\x9e\x51\x3c\x28\x82\x40\x43\x28\xc6\xf8\x17\xaa\x9e\x8d\xda\xf5\xa6\x57\x0d\x45\x4c\x5f\x02\xf3\xee\xed\x7d\x87\x0f\x5c\xb5\xbe\x25\x7f\x6e\xb9\xc6\x0f\x27\x02\xc6\x90\x5a\xc4\x3d\x8d\x2e\x4e\xe7\xf2\x50\x14\xee\x37\x4e\x11\x30\xe1\xa8\xad\xc9\x52\xfc\x44\xd9\xe4\x53\xcc\xb6\x08\x98\xca\xc8\x2d\x6a\x3e\xf3\x56\xbd\x19\xaf\xb3\x2b\x82\x28\x48\x68\xc9\x5c\x9d\xea\x72\xf6\x10\x51\x2a\x09\xe8\x6c\x19\x9f\x7b\x5f\x6d\xc9\x5e\x8b\x20\x02\x46\xa5\x6d\x2a\x5b\xcc\x73\x24\xb3\x1a\xb6\x08\xe2\x20\xcb\x70\x44\x19\xde\xb3\x0b\xfb\xdb\x8a\x23\x16\xf1\x01\xdb\xbb\x68\xc9\xba\x51\x09\x49\x09\xdf\x5f\xed\xfa\x13\xb9\x22\xc2\x48\x7b\xc9\x21\x4e\x11\x41\x8c\x36\x99\xa2\xb1\x78\xb9\x2d\x5b\x5b\x1d\x9a\xbe\xfc\x24\xd3\x84\x0c\xd2\x7d\x9e\xce\xca\x2e\x7f\xb1\xb8\x67\x77\x93\xc8\x94\x90\x5c\xf2\x54\x97\xc3\xcc\x08\x83\x83\xbf\x83\x34\x4b\x88\x6f\x08\x7f\xa1\x3a\xb5\x38\xd5\xac\xfa\x1d\x1e\x56\x04\xa9\x10\x84\x93\xba\xa9\xea\xce\x9b\xc5\xfe\xfb\x65\x82\x65\x81\x8f\xab\xf7\x1a\x8b\xd9\x77\xc9\x64\x10\x64\x7d\x48\xb5\xeb\xfb\xd4\xfe\x9b\x0d\x25\xa5\xc9\xff\xfc\xf2\xc0\xdf\xff\x9f\xe1\xff\xb8\x1f\x17\x91\x51\xae\x17\xec\xb6\x33\x6e\x23\xdc\x8e\x1f\x91\x49\x9a\x97\xef\x1e\xff\x27\x02\x88\x6d\x27\xe9\xea\x78\x6a\xde\xfe\x51\x9d\x9a\x76\x42\xf7\x31\x3d\x1f\x90\x43\x38\x00\x4e\x81\xc8\x21\xfc\x95\x64\x10\xd2\xb3\xe7\xaa\x2a\xd5\x24\x71\xdc\x1d\x13\x2a\xe8\xdb\x1e\xf7\xd2\x4b\xd6\x67\xfe\x78\xc8\x62\x4b\xa3\x4b\xa7\xd9\x18\xd9\xd5\x29\x86\xcf\x22\x05\x10\x9e\x68\xf3\xf8\x97\x4e\xbc\x08\x54\xa8\x3d\x8c\x8d\x4a\x5f\x79\x55\x0e\xb9\x1f\x11\xa8\x8c\x27\x56\x95\xea\x70\x2c\xe0\x7d\xf8\xb3\x15\xce\xb8\xab\x5e\x1f\x1d\xa9\xca\x7a\xac\xca\xbd\xa0\x1a\x24\x02\x25\x18\xb9\x9c\x37\xe7\x26\x57\x50\x8c\xb6\x03\x11\x28\x54\x44\xaa\xb0\xd2\xfa\xd1\x98\x5c\xe5\x50\xac\x8e\xc7\xf9\x7a\xd6\x91\x26\x42\x11\x3d\xe2\x67\xf1\x87\xb2\x84\x20\x12\x70\x6a\x2b\xd2\x26\xf8\xa3\x3f\x20\x6c\x85\x9b\x1a\x43\x1a\xa2\xb8\x58\x9c\xdf\xfd\x82\xd3\x10\x8b\xc4\xc7\x35\xe5\xfb\x2e\x6f\x8b\xb9\x29\xd5\x4a\x11\xcc\x6a\xbb\xba\xd9\xfc\xe6\x1d\xff\xc7\xf8\xe3\x61\x22\x29\xe7\x70\x6a\xb0\xb6\x49\xf2\x25\x37\x51\x04\x26\xb4\xea\x7d\x56\xfd\xfd\xa5\xcc\x7f\xf9\x47\x31\x09\x27\x16\x10\x05\xa5\x25\xe9\xb8\xf2\x91\xb7\x08\x83\x28\xcd\x5c\xe1\xe0\xea\x76\x6a\x41\xc2\x20\xca\x28\x5b\x3e\x8a\xb2\xa7\x6f\x2f\x0c\x22\x74\x22\x69\xe6\x54\x6a\xd7\xea\x31\xbb\x48\xa2\xb5\x18\x89\x05\xdb\x7e\xaa\x4b\xa2\x13\x11\x06\x69\x40\x71\xfe\xb1\xae\xba\x21\x1b\x2f\x53\xdf\x99\x2d\x57\xd6\xb5\x90\x13\xbf\xcb\x8a\x30\x14\x56\x28\xca\x26\x91\xb6\x9f\x70\x3c\x2e\xa7\xa6\x45\x18\x1a\x66\x5c\xb1\xb7\x2d\x70\x0d\xa5\x3e\x7f\xc3\x76\xda\xea\x2a\x42\x26\x78\xe0\x42\xe9\xdb\x16\x0f\xcf\x36\x71\x4f\x41\xf5\x6c\x64\x94\xd8\x2e\x87\x93\x55\x1d\x7d\x46\x72\x3d\xfd\x8d\x45\x19\x27\x14\xd1\x35\xa2\x1e\xb0\x58\x22\x8c\x83\x98\x31\x27\x00\x78\x0f\x79\x71\x75\xb6\x82\x1d\x93\x05\x10\xce\xb6\x86\x30\x8e\x15\xcd\x2c\x9a\x32\xf7\x79\xd9\x5e\xd2\x99\xf8\x91\xdc\x92\xb2\xf4\x49\xa7\xdf\x10\xe4\x88\x30\x56\x86\x98\xe7\x0a\xfc\xc0\x70\xf6\xbe\x78\x62\x05\xd5\xde\xa0\x79\xaa\xf3\xaa\xbe\x3e\x91\x4c\x44\xbb\x48\x1e\x22\xc2\x24\xb1\x6e\x72\xee\x30\x53\x36\x22\x9c\x5d\x33\x51\x96\xa8\xd9\xd2\x3d\xae\xab\xd3\xb1\x1a\x6a\x43\x93\x45\x1f\x26\x1a\xb9\xf0\x5d\xa4\x33\x3a\x38\x11\x26\xc8\xb5\x25\x6b\x2e\xb4\x23\x90\xbb\xed\x27\x45\x62\x32\x0a\x5e\x35\x79\x19\xf7\xce\x87\x73\xd8\x53\x11\xa6\x4c\x8f\x88\x08\x07\xae\xad\xcc\x1f\x8f\xad\xe4\xde\xab\xaa\x96\x77\xea\x30\x4b\x74\xda\xcb\xbe\xcc\x3a\x79\x44\x28\x24\x92\xe9\x3b\x35\xe8\xd4\xb3\x90\x40\x7b\x7f\x11\x81\xce\xde\x27\xa0\x26\x72\x92\x69\x9f\xd3\x45\x73\xff\x1c\x4a\x21\x42\x29\x23\x4b\xb5\x59\xe6\xad\x43\x7d\xfd\x16\x93\x2a\x42\x69\x22\x72\xa9\x3d\x69\x30\x65\xb3\x6e\x90\xb4\x06\x67\x1f\x50\xa5\xa9\x5b\xef\xa4\xc5\xee\x74\xc2\xfe\x16\x0c\x52\x84\x3a\xb4\x04\xf0\x4e\x35\x09\x9a\xe6\x58\xd5\xcb\x48\x72\x11\xea\x08\x94\x4b\x65\x5f\xe3\xc7\xec\x36\x74\x1c\x04\xa3\x92\xf4\x80\x9b\xee\x0e\x01\xa9\x58\x99\xba\x2a\x5b\x2b\xec\xbd\xd2\xff\x7b\x72\x72\x0f\xdd\x3e\xd5\x8f\x44\xa4\x68\xf8\xb9\x9b\x61\x2f\x7d\x55\xad\xbf\x12\x46\x76\xa9\x1e\x6b\x3c\xe4\x27\xca\xd8\xf5\x87\xe2\x80\xcc\x0e\xe5\x08\x9d\xb9\xc1\xb9\xc1\x31\x98\xf8\x8a\xc2\x1d\xf4\x2a\xb9\xa3\x4d\x92\x05\xb1\xa6\x4f\xb5\x43\x38\xfc\xc0\x86\xc2\x83\x11\xe8\x51\xb0\x40\x20\x39\x14\x79\x43\x21\x54\x3e\x8b\x5b\x04\x0b\x54\x4a\xa1\xd8\x6d\xd9\x9c\x88\x8d\x7a\xf1\x0b\xb3\x90\x59\x42\xb0\x26\x8c\x1c\x3f\x93\x3f\x80\x21\xe9\x56\xf8\xa4\x99\xeb\x07\x9f\x9e\xcd\x22\xcb\x16\x89\xa5\xfe\x51\x0d\x77\xcf\x62\x4b\x0d\x7d\x57\xb9\xb2\xfc\xcf\x09\xeb\xea\xd7\x3a\x71\x83\x01\x62\x2c\x13\x4e\x9e\xb6\xd4\x05\x9a\xf6\x40\x68\xde\xc5\x55\xc7\x22\xae\x03\xdb\xf6\x93\x1f\x8f\xa8\x17\x85\xd2\x27\xf7\x1d\x49\x16\xf0\x99\xda\xa0\xbf\xf9\x38\x4d\x52\xa7\x51\x79\x47\xb5\xbf\xd7\xc5\x8a\xb1\x60\x3c\x31\x04\xbb\x28\xf1\x93\xb6\x81\xfa\x3f\x4f\x58\x9f\x1d\x0e\x61\xca\xbd\xe4\xcf\x00\x13\xa7\x7e\x9a\x57\xb5\xc5\x9d\x4d\x62\x7b\xc1\x12\x16\x50\x4b\x81\x05\xb5\x39\x5b\xe9\x8f\x49\x4d\xa8\x86\xa7\x1a\x7d\xf6\xe5\xf7\xe4\x55\x21\xcb\x66\x37\x9d\x32\x0b\x1c\xdd\x5b\x43\xbb\xd2\xd5\xb1\x0b\xf0\x7f\x8d\xab\xdc\xa7\x0b\xfa\x54\xc1\x52\x34\x54\xfd\xf8\xf0\xe2\x95\x5b\x2b\x0f\x74\x1e\x51\x7f\x76\x2e\x3a\xa3\xe4\xdb\x98\x09\x88\x22\x48\xc6\x03\x3f\xa6\xdb\x49\xbd\x11\x3c\x3f\x16\xfa\x61\x06\x33\x13\x4c\xb0\x90\x7b\x6d\x00\x4f\x9f\x3b\x5b\x42\x4c\x38\xd9\xec\x57\x6c\x9f\x1e\x1f\xef\x2c\x62\x2d\xec\x7f\xc3\xe1\xb2\x2d\xc0\xb6\x07\xdf\x0a\x06\x91\x20\x9a\x41\x57\x08\x27\xa7\xe9\xea\xa4\x5f\x87\x77\x0c\x3c\x91\x16\x0c\x07\xed\xdb\x35\xb4\xb0\xff\x08\xfb\x7b\x07\xcc\x52\x5b\x4e\xde\xda\x72\x84\xbc\x58\x77\x52\xe8\x44\x8d\xec\xe0\x49\x16\x9d\x5f\x52\x3f\xbb\x56\xb1\xd9\x70\x25\xb9\x74\x30\xeb\xab\xfa\x32\xf3\x3e\xef\xd2\x9c\x4e\xab\x79\xbc\xc9\x94\xb2\x50\xe6\xdc\xe6\x6e\xe7\xa2\x53\x82\x29\x9d\x91\x27\x58\x75\x1e\x31\x14\xae\xd6\xe0\x1f\x4f\x61\x08\xe9\x40\xbe\x4d\x21\x43\x67\xf3\x41\xf5\x22\x4e\x82\xe9\x44\x11\x5a\x70\xf7\x73\x3d\xf6\xb7\x99\xd6\x96\xff\x80\x72\x91\xc4\x4a\xfc\x54\x7d\x62\x6d\x4e\xc5\xd0\x36\xd1\x8d\x42\x1c\x80\x39\x36\xef\x71\x3b\xda\x4e\xa7\xb7\x8b\xc2\x72\x1c\xd5\x04\xf4\xfa\x09\x4d\x17\x12\xf4\x3e\x1e\x43\x6d\xe3\xae\x07\x57\x0b\x74\xf8\x25\x1f\x62\x31\x13\x0a\xd2\x69\xba\xbd\xbf\xde\xfc\xf3\xf7\x75\x9b\xe9\x0f\x47\x81\x8b\x90\x6d\x7a\x82\xa6\xe8\x42\xb6\x59\x44\x61\x66\xf9\x08\xf7\xb2\xaa\x97\x13\x42\x22\x0a\x65\x4c\x0e\x9f\x27\xd7\x20\x00\x3b\x1a\x3f\xe3\xa2\x50\xa2\xe2\xd3\x96\x2d\x8b\xc0\x58\xd2\xe6\x71\xe7\xb0\xd8\x76\xc2\x38\x17\x93\x7a\xee\xde\x72\x9c\xf5\x8e\x8a\x28\x0a\x32\x66\x79\xa2\x7f\xbd\xd8\x03\xfe\x57\x79\x98\x52\x76\x14\xb4\xde\xbe\x55\x47\x5b\xa6\x5d\x08\xe7\x22\xce\x2c\xe4\x97\xd6\xb4\xf5\x77\xc7\x29\xa3\x88\x67\x12\xac\xcc\xda\xaa\x73\xb1\xa7\xf3\x3b\xe2\xc2\x36\x8a\x7e\x83\xb3\x6d\x4f\x87\x62\xe5\x59\x6f\x44\x94\xc4\x59\xe4\x65\x52\xc0\x96\x9f\x66\x0f\x90\xf0\x90\x82\xc9\xfd\xbe\xf3\x41\x6e\x4e\x7d\x0a\x2c\x4a\x32\xdb\x83\xef\x88\x28\x9b\xe7\xbc\x79\x57\x55\xdf\x23\x28\xa2\x2c\x48\x3c\x89\x5b\xb7\xff\xe4\xe5\xab\x17\x4a\x5c\x72\x2b\xa3\x2c\x34\x91\xf2\x4d\x41\x6b\x38\x36\xab\x52\xbf\x2c\x52\xe5\xf8\x13\xa2\x68\x94\x8e\xb2\xe5\xb7\x05\xa6\x07\x11\x65\xb1\x55\x2f\xea\x19\x13\xd7\x70\x9c\xa3\x5b\x44\x94\xc9\x98\xde\xd4\x16\x5b\x7b\x2d\x72\x11\x57\x97\xc3\x8c\x85\x55\x60\xa9\x9d\x52\xc8\x64\x93\x89\x44\x16\x11\x30\x75\xdb\x56\xbf\xb6\x87\x6e\x89\x51\x5f\xf1\x6f\x14\x9f\xdd\x89\x10\xc7\x41\xd6\x77\xad\xb6\x37\x84\x06\x2a\xd5\x6c\xcf\x8f\x80\x07\x14\xdd\xb8\x46\x3e\xa2\x52\xbc\xa9\xea\x11\xbb\xdc\x28\x72\x8b\x40\x86\x09\x9f\x74\x27\x93\x68\xa3\x3b\xaa\xc2\x40\x18\xcf\x71\xe0\x6b\x66\xfd\x07\x54\x91\x46\xc7\x40\xf0\x3d\xef\x22\x87\x33\xd9\xeb\x81\x06\x4e\x44\x2a\xd5\xee\x6d\x14\x85\xaf\x1d\xb9\x9c\x14\xc5\x71\x7e\x9c\x06\x19\x78\xa6\x7a\x1c\xab\x47\x89\x48\xab\x2c\x60\x3d\x55\xc7\x1f\x6e\xdb\xfc\x6f\xc7\xbc\x21\x22\x0c\x90\x20\x18\xcf\x8f\xeb\x3f\xfd\x39\x08\x59\xe8\xb8\xd0\x6c\xb6\x65\xc1\xc9\x88\x50\xa6\xe4\x41\xfd\x5a\x3c\x6a\x84\x0c\x60\x82\x08\x9f\xbd\x67\xa3\x99\x1c\xc0\xd6\xeb\x53\xd3\x56\x87\x55\xeb\xa8\xab\x1c\xd5\xce\x25\xd4\xda\xef\xf8\xfe\x5f\x3f\x2d\xe2\x20\x8b\xc8\xad\x79\xd9\x5e\xef\x9f\x36\xcf\xfb\x9e\x30\x4a\xc4\x81\x96\x21\xb8\x97\xb8\x2a\x8a\xeb\xaa\x58\xb5\x8f\x83\x4b\x12\x87\x91\x22\xb7\x85\xbe\xd2\x33\xb6\x44\x4c\xb5\xae\xbb\x2d\xd7\x0f\x61\x81\x0d\x14\xda\x7e\xae\xf9\x03\x91\x88\x75\xdf\xcc\xdf\x7d\x17\x36\xb5\x10\x31\x4b\xfa\x1d\xd0\x23\xc8\x96\x8d\x5e\xcc\x84\x45\xcd\xe4\xcd\x0d\xd4\x87\xb9\xa9\x89\xa3\x34\x44\x57\x09\xee\x9d\xba\x91\xb8\xb6\x88\xe3\xd4\x3a\x6c\x8a\xde\x25\xb5\xe7\x53\xa9\x76\x4e\x6b\x25\xe2\x18\xad\x2d\x70\x71\xcf\xae\xb6\xc8\x67\x7f\x21\x1e\x32\xca\x7e\x5c\x8d\x75\xeb\x45\xcc\x85\xf4\x39\x76\x37\xd7\xef\x4e\xea\xfd\xbc\x6d\xab\x12\xc7\x26\x33\x4e\x02\x1d\x0c\xc9\x6f\x6b\x53\x2d\x8f\xc9\xa2\xa5\x89\x93\xc4\xb6\xab\xe4\x9e\xbe\x70\xf7\x06\x9f\x0e\x3e\xb9\xb8\x96\xe3\x24\xb3\x8f\x2a\x47\xa2\x08\xc3\xaa\x8c\x13\x15\x12\xfa\xa1\x86\x92\x2a\x72\x53\xb8\xa9\x88\x13\x03\x04\xd9\x38\xc0\x2f\x6b\xd1\x5c\x82\xde\x1f\x4f\x63\x41\x21\xf8\x3e\xb7\x95\x3f\xcb\xd3\x5b\x2d\x77\xbf\x8a\x38\x4d\x42\x52\x98\xd9\x62\x7b\x3a\x52\xaa\xe7\x4b\x9e\x0d\x11\xa7\x69\x42\x90\x85\x43\xee\x75\x5b\x29\x88\xfb\x6d\xde\x38\x4e\x33\xa0\x93\xae\xcf\x05\x94\x5f\x37\x83\xbb\xd1\x59\x14\x67\x63\xbd\xd9\xa5\x2c\x4e\x9c\xc5\x31\xd9\xd1\xd5\x6a\x35\xf6\x73\xe2\x2c\x16\x9c\x4f\xbb\xc0\x46\x72\xc6\x22\xce\x32\x0b\x23\x20\x20\xce\x58\x07\x5e\xc4\x42\x28\x42\xec\xdf\xe7\xfa\x33\x37\xfd\xdb\x94\x01\xf8\x9e\x8d\x9b\x53\x61\xf2\xa2\x98\xf4\x51\x4f\x6f\x4b\x82\x55\x54\x6f\x70\x92\x2f\xf6\x41\x7e\x2c\x95\x25\x38\x3f\xd6\x55\x65\x1e\xcd\x16\x8a\x76\xa1\x43\x4d\xc4\x2a\x8a\x79\x48\xd5\x7a\xf5\x76\x75\xf2\xd0\x47\x11\x2b\xc5\xc9\xbd\x3b\x40\xfd\x3e\xcf\x10\xb9\x21\x18\x71\xca\xef\xef\x56\x7f\x8e\xa7\x3f\x8a\x84\x81\xa3\x5e\x57\xfd\xbc\x9e\x99\xb5\x18\x31\x20\xb8\xc9\xae\xce\x4f\xe5\x47\x5e\x8f\x32\x87\xfd\x33\x18\x0e\xd4\x89\x89\x1f\x58\xb6\x4f\x79\xfd\xef\xe9\xe7\xf7\x8f\x60\x44\xe2\x74\xb4\x7d\x59\xe5\x6a\xb7\xf6\x77\x63\x20\x88\x8c\xc3\xb4\xe6\x35\x6a\x4b\x92\xbf\xab\xae\x90\xd4\xe2\x1c\x08\xce\x0f\x96\x31\xa1\xd3\x7f\xc2\xf9\x3d\x1f\x3f\x93\xd1\x00\x56\x81\xa9\xa8\x40\xef\x5f\xeb\xea\x74\xdc\xbf\x0f\x81\xa8\xa7\x50\x14\x44\x6c\xe3\x31\xac\x6f\x79\xf9\x4a\x9a\x1b\x63\xf4\x41\xbf\xfa\x78\x00\xc8\x64\xef\x0f\xec\xaa\xe3\xa4\x02\x3d\x79\x5d\x3c\x30\x01\xf4\x34\x5e\x39\xd6\x0e\xc8\x2e\x38\xe3\x56\xb1\x90\x24\xe1\x5d\x36\xe7\xf9\x54\x8e\xc1\x76\xa3\x9f\x64\x60\x89\xef\x4e\x25\xb5\x12\x7a\x49\x2f\x32\x7f\x76\x0e\x4f\x8d\x29\x8f\x42\x4d\x1c\x07\x45\xf5\xd9\x2d\x3f\x0a\xe2\xc6\x09\x08\x1e\x81\xf0\x8d\xa7\xbe\xad\xd3\xd3\x52\x8d\xe7\x3c\x8f\x43\xdb\xa6\x43\xd9\x3a\x4b\x1e\x3c\x4b\x15\xf3\xd8\x01\x62\x0e\x95\x3e\x15\xd8\x07\x4a\xfe\x68\x12\x18\xdf\xea\x3c\x3f\x51\x59\x3a\xe0\x06\x5b\x05\xc7\xce\xbf\xbe\x6c\x40\x9e\x2e\x1f\xce\x45\x4c\xa6\xb4\xc8\x4b\x7c\x34\x8e\x4e\xec\x8f\xf9\x18\x2b\xcc\x44\x39\x1f\xcb\x87\xe9\x6f\x86\x4b\xc1\xdd\x53\xff\x99\x97\xfa\xd1\x3c\x81\x7a\x87\xd7\xf9\x13\x71\x4c\x08\xd2\x42\xa2\xed\x04\x79\x98\xfe\x42\x02\x19\x21\xfd\x11\x9a\xf3\x7d\x5e\x8e\xe5\x50\x04\x4f\x03\x45\x29\xac\x51\x97\x3b\x55\x42\x16\x31\xaa\x7e\x51\xf2\x14\x50\x26\x03\x57\x2e\x25\x9d\xe7\x18\x27\xc1\x53\x99\x51\x44\xd4\xb4\xa0\xde\x1f\x8d\x69\xe6\x66\x8f\x67\x2c\xa4\x30\x6e\x7b\xf3\xcf\xc9\x5d\x65\x99\x20\x56\xc9\x7f\xee\x7e\xac\xf2\xfa\xba\xae\x8e\xc7\x3e\x10\xe3\x59\x06\x5a\x8d\x4a\xda\x7d\x15\x78\x8c\xe1\x10\x3c\x03\xee\xbb\x77\x9e\xde\xaa\x12\xaf\xce\x8b\x09\x79\x9e\x81\xd4\x2e\x22\x5a\x4d\x52\x03\xbc\x0b\x09\x9d\xb3\xf6\xed\x7e\x76\x96\x10\x96\xac\xcf\x60\xab\xde\x5e\xca\xa1\xb8\xe9\xc4\x18\xfc\xcd\x42\x2c\xa9\x15\x5c\xc3\xb9\xd9\xe6\xa5\xc2\x3b\x38\x95\x7d\x75\x87\x43\x66\xc9\xa2\x0f\x84\x44\xf9\x56\xc3\xd1\x43\x28\x04\x07\x93\x11\x3d\xa1\xab\x43\xf8\xfa\xef\xae\xba\x5d\xaf\x9e\x5c\xe6\x67\x9e\x55\xbf\xdc\x7e\xb9\x94\x36\x3d\x71\x9c\x73\xf5\x0a\xae\x58\x4a\x84\x40\xf2\x74\xfe\xe3\xb2\xc3\x50\x70\x25\x91\xb6\x10\x97\xc0\xd8\xfc\x3a\xe6\xf5\x79\xaa\x26\x28\xb8\x66\xc0\xad\x2a\x38\xea\x97\x3a\x9f\x7d\x61\xc3\x24\x15\x53\xf6\x2e\x47\xfa\xa3\x3a\xa9\xb7\x11\x9b\xee\x74\xc5\x24\x01\xc4\xa4\x10\x79\x2a\x49\x7a\x78\x57\x9f\xb0\x67\xf8\xec\x8e\x26\xba\x5b\xbb\xb7\xbb\x5d\xaf\xba\xe0\x0e\x85\x71\x6c\x06\x02\xb2\x6e\x52\x96\x43\x26\x26\x09\x79\x96\xba\x24\xcf\x77\x04\x3d\x6b\x86\x11\x49\x98\x86\x49\x8f\xba\x6e\xf3\x0f\xb2\x7e\xfd\xc9\x32\xa4\x5e\x93\x16\xe1\xf0\x00\x87\xbc\x7c\x75\x0a\x48\xee\x38\x13\x29\xe1\xcb\xdf\xf3\xa2\x38\x43\xff\x57\x8d\x94\x33\x7a\xaa\xab\xa6\x73\x58\xfe\x9e\x0c\x90\x48\x22\x66\x49\x29\xcb\xd3\xc1\xf6\xc6\xfa\xf9\x90\x44\xdc\x5a\x8a\x7f\xac\xfe\x31\x5e\x2c\x49\x84\xa1\x76\x9e\xe0\xd3\xa9\x3e\x56\x43\xd8\x9a\xc4\x49\xe0\xab\x6a\xfb\x9a\x7c\xe9\xbd\x3c\xef\x0b\xfc\xc0\x29\x17\x89\x48\x62\x81\xdc\x13\xb0\x91\x9d\x7a\xaa\x7c\x20\xfb\x7b\x23\x97\x70\x66\xcb\x1c\xc7\x93\x9c\x60\xed\x44\xc2\xa3\x88\x1a\x62\x4c\x5e\x37\x8e\x01\x6b\x63\xa9\xd4\xfa\x11\x99\xa5\x02\x7e\xb9\xda\x8e\x36\xc2\x84\x0b\xdb\x22\xd2\xe4\x56\x62\xc4\xfd\x39\xc9\x50\xb2\xbe\x74\xf6\xe2\x77\x97\x27\xa7\x32\x6a\xfb\x03\x97\xfb\x12\x45\x92\x98\x88\xf7\x41\xc3\xbd\x15\x84\xd9\x50\x77\xb5\x37\x2c\x49\x1a\x31\x2a\x11\x0e\x2b\x6d\xbb\xda\x55\x9b\xd9\x9b\x4a\x13\x24\x6a\xea\xed\xd3\x6e\xf2\x19\x52\xe0\x0c\x87\xcc\x0a\x28\x0a\x3e\xeb\x83\x45\x7f\x4e\xbe\x71\x16\xc7\x14\x8e\xdd\x38\xa1\x95\x65\x2d\xb1\x6e\x5c\x96\x60\xdf\x37\x5f\x51\x0e\x6b\xb8\xdd\x4c\xd8\xf6\x76\xb0\xcc\x39\xed\xf8\x66\x32\x61\x81\xcc\x43\xc0\x87\x23\xe1\xf1\xee\xb8\xa2\x1d\xb7\x17\x91\x70\xf4\x3b\xb3\x2f\x98\x01\x8f\x9c\xa9\xbd\x3a\xd5\xe5\x50\x62\x70\xc7\x85\x8e\x84\xf0\x9a\x6c\x54\xcf\xac\xaa\x42\x57\x9f\xd3\x52\x57\x02\x91\x90\xa3\x8a\x8b\xed\x16\x9a\x25\x1b\xa7\x4f\x2e\x33\xd4\x03\x4e\xcf\xdd\xdc\x7f\xb6\xb3\xf4\x40\x22\x0d\xa3\xa5\x87\xbf\x8e\xdd\x8d\x3d\x63\xe7\x38\x3d\x9c\x0e\x5b\x54\x5f\xcd\xda\xcb\x52\x55\xa2\x82\x8c\x2a\x65\xca\xf5\x00\x5a\xc6\xd9\xc9\x17\x53\x61\x40\xa0\x98\xbd\xd5\x52\xfa\xaa\xd2\xe4\x46\xeb\x24\x36\x03\x99\xe3\xff\x9d\xf2\x7f\xef\x5f\x87\xc4\xf3\x74\xbd\x6b\xc5\x98\x25\x19\xec\xe6\xe2\x1d\x1c\x64\x35\x7b\x48\xad\x44\xe2\xea\x88\x83\x82\xdb\x34\x8b\x9d\xa0\xc8\x32\x39\x20\xcc\xae\xf2\x42\x56\x75\x75\x7a\xf5\x1b\x4d\x62\x78\x4c\xd8\x7b\x93\xff\x42\xfd\x8c\x1f\x58\x0f\xba\x9b\xff\x1d\x06\xfe\x55\x98\x0c\x28\xff\xf0\xa3\x6a\x87\x85\x97\x06\x18\x91\x85\xf9\xc7\x6a\xd7\x33\x08\x89\x34\x4c\x92\x54\x8d\xe1\x5b\x1b\xd7\x16\x37\xed\xb5\xfb\x7d\x81\x31\x0d\x53\xc9\x1c\x79\xe9\xa3\xfe\x92\x5b\xd4\x0f\x86\x90\xf6\xb2\x1f\xf9\x07\xbe\xef\x3c\x7b\x75\x7f\x43\xd2\xba\x5b\x0d\xb6\x0f\x55\x4f\x5d\x4b\x7e\xee\x58\xda\x50\xa4\x2c\xd5\x33\xb6\xc9\x75\x91\xcf\x19\x0e\xba\x61\x86\x4c\x46\x03\x1f\xd8\xbd\xb2\xf2\x64\x75\x3f\xc6\x04\x47\xcb\xfb\x58\x1a\x65\xb6\xd5\xa1\xee\xb5\x7a\x9f\xea\x4a\x16\x78\x68\x96\xc3\x9c\x34\x92\xcc\x66\x8f\x0f\x2d\xc2\xbf\xfd\x13\x51\xb4\xe6\x5a\xc3\x7a\xde\x2c\x91\xc6\x5a\x2b\xbf\x5d\x95\xf9\x01\x8a\x0b\xc1\x67\x91\xf2\x00\x94\x19\xcb\x0c\x56\xde\xc9\x4d\x79\xc6\xb5\x53\xe1\x78\x2c\xf4\x43\xae\xde\xcb\xaf\x72\xce\x29\x57\xc8\xbc\xa1\x28\x07\x39\x47\x91\x72\x2d\x94\xe7\xfe\x5a\x7f\xb7\x25\x91\x88\x4d\x66\x65\x9a\xc8\x88\xdb\x80\xa6\x2a\xff\x56\x8b\x9f\x48\x13\x13\x5b\x96\xa0\x53\xfb\x56\xd5\x79\x83\x1e\xf6\x3f\x59\x61\x69\x1a\x1b\xcb\xad\x6d\x9b\x78\x9c\x5a\xdb\xf4\x52\x69\x12\x59\xd7\xb6\x9b\x27\x96\xe2\x78\x42\x0b\xe8\x86\x65\xc2\x56\xd1\x2d\x76\xe3\x1a\x81\x78\xe7\x2e\x26\xe2\xe4\xc1\x20\xb1\x8d\xa3\xb6\xae\x75\x53\xd5\x4b\xdc\xc9\xfe\x07\x20\xd5\xcc\x75\xbf\x0e\xdd\x82\x22\x05\xc3\x54\x36\xea\x43\xbc\x46\xd5\x7d\xca\xf9\x53\xc8\xd8\x2a\xeb\xf8\xd2\xe8\x85\xa0\x0c\x91\x68\xfd\xed\xfe\xbf\xd3\x4c\x5d\x46\xa4\x52\x68\x5a\x53\xab\x97\xd5\x68\x0f\x4e\x15\x48\x4b\x9f\x50\x95\x1f\x58\xb7\xec\x09\xab\x72\x66\x7e\x53\x85\x56\x89\x5e\x8f\x16\x44\xe7\x25\xcd\xe0\x31\xa9\x8e\xac\x5a\xee\xae\x6a\x26\x0b\x56\x9b\x34\x18\xb7\x62\x4e\xa9\xc4\xa7\x46\x35\xc5\x48\x7a\x96\xe3\x6e\xfb\x26\xa6\x98\x4b\xdc\x67\xef\xf7\xa6\x46\xdb\xee\x7d\xe7\x78\x2e\x01\x41\xb2\x90\x69\x5f\xd8\x7b\xc0\x5f\x83\x40\xa2\x2d\xd8\xff\xe1\x47\x25\x9c\x9c\xd2\x6b\x94\xbe\xda\xd4\x1f\xca\x24\xfd\x88\x41\x1c\x67\xff\x32\x86\x5c\xf9\xb9\xb7\xd2\xda\x75\xca\xfb\xa3\x71\xa4\x52\xd7\x05\xf3\x52\x82\x15\x4d\xe8\xf3\x5d\x59\x1c\xeb\x64\xa0\xce\xdf\x76\xeb\xb7\xae\x8e\x1e\xbd\xfb\x35\x23\xf2\xef\x0d\x6d\xc6\xb9\xa2\x7e\xb9\x1a\x69\x5b\x1a\x33\x92\x8a\x8c\x67\xc0\x32\x2f\xcc\xf3\x9b\x5e\x20\x91\x25\x32\x09\xc7\x3d\x04\xce\x27\x70\xc5\x8b\xf9\x58\x49\xfd\x46\xdb\xdd\x6a\xf7\xb2\xdd\x5f\x6f\xb6\xbb\xe7\xc7\x7f\x6d\xbc\x3f\x9f\xa5\x21\x8f\xdd\x12\xd8\x93\xfb\xd2\xd3\xef\x2c\xd9\xa2\x2c\x15\x31\xd9\xe3\xf5\xf3\x66\xb5\x7b\x7c\xde\x8f\x14\x0f\x44\x96\x02\x52\x66\xdd\x9c\x4a\x3d\x10\xf4\x4d\x27\x6c\x96\x4a\x4d\x79\x04\x8a\x61\x2c\x8f\x56\x7f\xbe\xb1\x1a\x2b\xaf\xd8\x52\xea\x79\x4d\xea\x84\xee\x60\x16\xc9\xc8\x38\xe6\xf0\x71\x27\x7c\x36\x49\xb3\x67\x59\x26\x84\xf1\xda\x5b\x65\x4e\x38\xc0\x79\x11\x36\xcb\x14\x27\x38\x40\x89\x9f\xbd\x8c\xe6\x7c\xd5\x8e\x2b\xaf\xff\x31\x76\xa5\x3a\x9f\x2f\x8d\x5d\xb2\x98\xf2\x24\xd8\x4c\x6c\x6e\x26\x44\xc8\xbd\x38\xde\x4b\xd3\x39\xc7\x9b\xf6\xcd\xd9\xb6\xc1\xf3\xce\x84\x4a\x5d\x77\x7c\x17\x15\xdc\x96\x6d\xc4\xfe\x18\x65\xf0\x33\x61\x0c\x78\x4e\xa6\xba\xcd\x67\xdd\x97\x22\x03\x1e\x13\xf9\xa9\xf5\x87\xd0\xd5\xa2\x76\xd5\xaa\x7c\xc5\xe2\x02\x7a\x9c\x01\x28\xea\xe6\xaa\xb1\xad\x31\xff\xc0\xef\x75\x3b\xbd\x6d\xc9\x0d\xa5\xd7\x8a\xbc\x69\x9f\xea\xb3\x6a\x2b\x5f\x5f\xcf\x24\x58\x5e\xd7\x67\x32\xb6\xce\x59\x9e\xf5\x39\x88\x4c\x2a\x13\x26\x3e\x0a\x92\x7f\xe2\xf9\xea\x4c\x04\x67\x76\xe7\x77\x49\x81\x4c\x89\x80\x76\xfe\xcd\xfa\x71\x3b\xfb\x2e\x4a\x72\xca\x62\xd7\x79\xf9\x8e\xd2\x6f\x96\x99\x8e\x05\x78\x01\xce\x63\x55\x36\x15\x89\x9d\xac\x2f\xf7\xa4\x4c\x4b\xc9\x87\x96\x80\xa3\x75\x2c\xfa\xf6\xaf\xc5\xed\x2e\xd3\x98\xfa\x5d\x74\x68\xcf\x10\x19\xb2\x94\x8a\x0f\xcd\x3b\xb6\xea\xed\xa1\xba\xab\xca\x57\xaa\x1f\x8c\x89\x5d\xfc\x58\x13\x50\xfa\x47\xe7\x8d\x2a\xaa\xe6\x54\xe3\x85\x26\xae\xc8\x4c\x20\x28\x95\x61\xcd\xec\x9f\x3c\xf8\x2f\xff\x53\xc6\x51\x56\xba\x54\xce\xe6\xd7\x71\xf6\x58\x06\x38\xd5\x0f\x56\x5a\xef\xaa\x4f\x57\x33\x75\xa9\x86\x70\xa2\xa3\x76\x01\x08\xf1\xff\xf8\x2b\x49\x0b\xe0\x7f\xc5\x16\xdb\xb7\x53\x33\x87\x33\x64\x46\x2b\xea\x1d\xba\x55\x55\x59\x1d\xf2\xbf\x0c\x99\xa7\x2f\x53\x04\x41\x14\xb9\x08\xec\x01\x3f\x9f\xbd\x44\xeb\xb2\x32\x99\x3f\x87\x21\x21\x7f\x9e\xa1\xc5\xec\x0f\xff\x47\xc7\x8d\x49\x48\x7a\x28\x6e\x4b\x9d\x7f\xe4\xfa\x44\xea\x10\x83\xe7\xe7\x06\x87\x81\xa2\xdd\xe1\x1f\xf9\xaf\xea\xaf\x8a\x01\x22\x8c\xb8\xc3\x74\xac\xac\xc4\x9c\xdd\x10\x1b\x2b\x9a\xe0\xc4\xe4\xfb\x2b\x73\xa6\x83\xb1\xfa\xe1\xa5\x5c\x8c\x10\xa1\x54\x24\xe4\xa8\xf3\x1a\x55\x17\xe5\x1b\x42\xd7\x5f\x34\x09\xf8\x68\x47\x84\x26\x21\x1d\xdf\x2b\x28\xdf\x97\xe3\x4e\xc1\x12\x4d\xf4\x21\x45\x7e\xc8\xdb\x11\x21\xa9\x3f\x9c\x85\x14\xe9\xbe\x41\x73\xdb\x34\xa7\xf9\x67\x14\x51\xa8\xa3\x60\x9c\x4b\x18\x3e\xa4\xb7\x1f\x22\x8a\x25\x61\x1e\xa8\x70\xf1\x8c\xcd\xe9\x80\xb3\xba\x90\x88\x52\xcb\xed\xf5\xcd\x76\xf2\xb4\xf9\x2b\x52\x39\x77\x7a\x33\x11\xf0\xc8\x96\x20\xa8\xd1\xcc\x77\xe2\xcc\x38\x61\xba\x71\x82\x20\x83\x87\xfc\xd5\xae\x48\xe7\x58\xd2\x4a\xee\x37\x6e\x11\xa9\x8c\x3a\x48\x1f\xbe\x8d\x3d\x15\xc1\x65\x40\x6f\x79\x8f\xbf\x8e\x45\x55\xe3\x4b\x93\x97\xaf\x9b\x43\x75\x49\xa6\xb7\xbc\xfb\x0a\xde\xf9\x4a\xbd\xbd\xb5\x2d\xfd\x4b\x95\x58\x91\x84\x91\xf7\xed\xbb\x97\x67\x9b\xb2\x1e\xaa\xdd\xa9\x2e\x27\xb2\x9e\xd3\xa7\x4b\x85\xed\x4d\x06\xa5\x6e\x2a\x4a\x1b\xf9\x3b\xcf\x82\x88\x60\x5c\x2e\x8b\xb8\x7a\xfe\x78\xc6\x8f\x9b\xaa\x46\x05\x7d\x65\x5b\x64\x21\xd0\x46\x4d\x99\x9a\x65\x56\x1d\x21\x44\x9a\x51\xbb\x8e\x97\xef\x9a\x4a\xa7\xfa\x55\x2e\x04\x48\x82\x70\x6c\x8f\x55\xef\xd3\x08\xc8\x80\x3a\x48\x3c\x85\xd1\x5e\x55\x48\x38\xf9\x61\x8f\x10\xa0\x32\xa2\xeb\xa7\x3c\x76\x3e\x9f\xe7\x92\x59\x79\x88\xc3\xd9\x16\x6e\x3b\x4f\xd9\x1f\x12\x3c\xd4\x3d\x27\x23\xad\xa7\xcd\x38\x15\x2c\x14\x93\x54\x7e\xda\xbf\x12\x3a\x63\x84\x9b\xb8\xac\x69\xb3\x2f\x75\x65\xbe\xf8\xb2\x1a\xc3\xd0\x29\x20\xd1\x2a\xfe\x89\xe8\x21\x6a\x42\x1b\x0c\x33\xdf\xae\x6e\x73\xf7\xd3\x93\x51\x09\x72\x40\x57\x27\x9d\x53\x5b\xb5\x2d\x47\x3c\x5b\x3c\xd7\x17\xae\xb0\x40\xa5\xc8\xbb\xdc\x1e\x8b\xbc\xfd\x89\xf9\xeb\xdb\x9c\x19\x4f\x08\x13\x6a\xf2\x87\xe8\xa5\xac\x8b\x2e\xfc\xe9\x53\x89\xc2\xb0\x98\x62\x9e\xcd\xf3\xb7\x81\x51\x51\x08\x13\x67\xda\x49\x03\x1c\xf2\x06\xf5\x53\x75\xec\x0f\x25\x01\x55\xf4\xc9\x4d\x7b\xea\xf1\x80\xf6\x28\x04\xa1\xdd\x3b\x1b\x47\x93\x44\x65\xee\x49\x33\xd0\x72\x21\x01\x02\x48\x09\x06\xd2\xf9\xc9\x16\xf0\xeb\xc8\x1f\xbd\xc8\x51\xff\x0b\xca\x41\x73\xc0\x1e\x78\xae\x64\xd5\x2e\x23\x34\x21\x94\x3a\x4b\x46\x22\xdd\xae\x0f\x75\x62\xbc\x17\xb7\x63\x60\x61\x14\x8e\xa9\xc1\x76\x5b\xdf\x03\x05\x4c\x58\xf0\xc7\x2b\xb6\x7f\xe2\x47\x1f\x27\x01\xd3\x18\x39\x91\x88\x19\x3f\x9d\x1b\x10\x05\x40\xc9\xa0\xef\x58\x14\xd5\xb7\xaa\xd0\x8b\xe8\x98\xc5\x0f\x0d\x71\x18\x07\x94\x5f\x53\xc7\x59\x55\x07\x62\x6e\xb9\x58\x3f\x47\x62\x43\xf5\x72\x47\x03\xc4\x60\xa9\xd7\xc1\xb4\x58\xbb\x37\xbb\x5a\xba\xd7\x58\x23\xd5\x73\x5d\xb1\x90\x50\xa1\x8b\x55\x13\xe0\xcc\x11\xa6\xc2\x07\x3e\x3f\xcc\x2e\xc3\x59\x2a\x2d\x08\xad\xfa\xcb\xc8\xd4\x9f\x12\x07\x09\xf3\x9a\x5a\xd4\xbf\xf6\xb3\xce\x5b\x6c\x9e\xb0\xde\xb6\xe8\xa7\x21\x70\x21\x33\x8b\x44\xde\x94\xaf\x79\x89\x58\xcf\x76\x0d\xe0\x60\x93\xb8\x9e\xb2\xc3\x4f\xa4\x6d\x8b\xf0\xde\xf4\xa3\xd0\x4e\x67\xdf\xc1\x84\x93\xf4\x28\x24\x41\x30\xc8\xa1\x8c\xba\x30\xfb\xf3\x93\x2c\x22\x7b\x66\x61\x76\x8f\x65\x91\x97\x38\x81\xcf\x42\x82\x96\x25\x88\xc8\x10\x0a\xfc\xa3\x57\xda\xec\xe7\x7e\x62\x52\xc2\x36\x5d\xed\xbe\x5f\xf9\xb3\xb2\xc0\x66\x0e\x57\x75\x5d\x7d\xee\xa6\xcd\x76\x90\x31\x93\xb9\x72\xcd\x13\x1e\x67\xa6\x04\x44\x10\x1b\xe1\x96\xd2\x4b\xe9\xf2\x27\xff\x46\xbd\x25\x14\x12\x78\xfb\xe3\x46\x43\xc6\xa2\xa4\x7f\xdf\xab\xd7\x6a\x68\x5c\x00\x00\xa4\xd8\xe0\x58\x1d\x29\xaf\xb7\xcb\xdd\x16\xde\x3f\xbe\x0a\x38\xa5\x34\x72\x65\x5b\x59\x9f\x2d\x7d\xe5\x98\x80\x4b\x80\x72\xda\xbd\xdd\x0d\xed\x47\xd1\xce\x8a\xf0\xdb\x43\x38\x0c\x0a\x25\x61\x97\xae\x3c\x6f\xc4\x4b\x83\x13\xa5\x9d\xd9\x5c\xd1\x91\xed\x95\x3a\xd6\xd5\xf1\x0d\x55\xde\xcc\x5a\x0e\x41\xa7\x69\xa8\x46\x06\xe0\xfb\xcf\xf5\xcf\x7c\x1a\x70\x00\xc6\x52\x3b\xea\x23\xd7\x78\xfc\x74\x92\xef\x78\x9e\xed\xc7\x80\x69\x44\x09\x29\xaa\x47\xf9\x15\xee\x8e\x99\x2c\x10\xd8\x93\x8d\x58\x5e\xa4\x8b\xd8\x07\x8c\x4e\x5c\x22\xa2\xdb\xfa\xd7\x6f\x79\x31\xea\x71\x76\x9c\x80\x93\xc5\x25\xc3\x84\xa9\x68\x9c\x59\xdd\x55\x47\xfe\x1d\xeb\x0a\x1b\x82\xb9\xfe\x3e\x87\x26\xc3\x2e\xca\xa1\x12\xf7\x07\xee\xaa\x2d\x18\x6c\xcf\x93\xc9\x29\x59\x64\xe5\x76\xac\x6a\x52\xe7\x2f\xe8\xfe\x50\x62\xb5\x6d\xfd\xbb\xbb\xaa\xab\xf7\xde\x9b\x90\x0c\xa2\xc8\x01\x42\x56\x4a\x0d\xf2\x9f\xc3\x8f\x33\xc8\x44\xd0\xeb\x6f\x5e\x43\x5e\x9c\xc7\x11\x83\xff\x46\x92\x49\xae\xb4\x5f\x62\x37\x88\xbd\x42\x9b\xff\xa9\x48\x23\xdd\x88\x2d\x1a\x78\xbc\xdd\xb2\xc7\x2a\x63\x96\xd0\x6e\x87\xed\xdb\xf3\xd4\x03\xf6\x03\x22\x03\x83\x6a\xf1\x2d\x9d\xdb\x8c\x10\x13\x53\x27\x59\xc6\x89\x85\x73\x1e\xce\x77\xd5\x07\x12\xec\x7c\x0c\x34\x90\x89\x10\x1e\xe2\xd7\x45\x4d\x57\xd8\x36\xb7\xe5\xea\x19\xfe\x7d\x5b\x36\x2d\xe1\x8d\x96\xef\x33\x51\x4c\xbb\x5c\xa0\xdd\xe7\xa8\x09\x7c\xa9\x73\x5f\xc8\x94\x45\x3e\xa7\xef\x71\x13\x14\xf1\xdf\xfa\x46\xd8\x25\x9c\x8a\x4c\x79\x22\xac\x98\xc1\x37\x38\xe0\x5d\xf5\x9a\xab\x99\x89\x94\xa9\x4c\x32\xe5\xdd\x7b\x59\x23\xbc\x5b\xfe\xe3\x5c\xfa\x11\x59\xcc\x7c\x26\x9d\x90\x8d\x77\x50\xce\x9c\x7c\x99\x81\xa1\x37\xf0\x06\xc5\xe8\xa3\x65\xca\x6a\x31\x4f\xb5\x7c\x66\x2f\x21\x43\xc6\xf5\x8c\xe7\xd3\x85\x41\xd5\x40\x86\x22\x08\xc3\x94\x3a\x40\x76\xd3\x60\xd3\x5c\x55\xd5\xfb\x02\xfd\xbe\x1b\x0e\x4c\xb0\x64\xe0\xd2\xd5\xdd\x8c\x82\x16\xeb\xde\x22\x49\x50\x9c\x52\x9d\x56\xdf\x84\x48\x45\x47\x3d\x3b\x52\x99\xcc\xf3\x8f\xee\x0a\x22\x5f\xe8\xc1\xf8\x52\xc7\x86\xb2\x67\x25\x7e\x7e\x49\xae\x3a\x6b\x63\x90\x1a\x18\x35\xc1\x35\xa7\xc3\x50\x36\x91\x5a\x4a\xf2\x64\x6e\x6e\xef\xee\xff\x66\x51\x58\x22\x68\x62\xb4\x27\x37\x09\xca\xd6\x6b\xc2\x37\xb7\x25\x91\x8f\x8f\x40\x90\x12\x51\x52\xcd\xf7\x1a\xda\xdc\x6a\x95\x8c\x23\x19\x69\x82\x24\x73\x36\xeb\xa5\x54\xd5\xe1\x88\x65\xd3\x59\xbf\x11\x2d\xd8\x32\xaf\xbe\x50\x41\x20\x28\x89\x63\x41\xcb\xc3\xf8\x25\xf6\x66\xa1\x02\xcd\x28\xe9\xab\xd1\x74\xb6\x7c\x37\xea\xd2\x70\xf7\xa2\xc2\x80\x2b\xff\xc2\xa1\x79\x77\xa8\xe6\x52\x3b\x46\x8e\x89\x51\x57\x21\x24\x94\x2c\x46\x55\x95\xcf\xd8\x60\xfd\x81\x2b\x0b\xfe\x1a\x2c\xb2\x62\x2a\x71\x2a\x21\xa4\xec\x6b\x71\x57\xd3\xeb\x30\x44\xaa\x4a\x7b\x34\x7b\xf7\x1c\xd5\xb8\xab\xd6\x8d\x8b\x22\xc1\xfd\xcd\x0d\x0c\x6c\x97\x1a\xe2\x42\x45\xdc\xa6\xdc\x3e\x68\x57\xb3\x00\x82\xd9\x8f\x46\x22\x20\xf3\xd3\x19\xe3\x7a\xa3\xba\xa8\xae\x97\xd4\x14\x2a\x82\x8c\xc2\x84\xdd\x66\x75\x3f\x61\xc8\x10\x2a\xd6\x01\xe5\xe1\x3a\x9b\x66\xeb\x92\xd3\xdf\xe6\x91\x45\x77\x6e\x37\xeb\x91\xab\xa0\xb8\x44\xc2\x0a\x78\x78\x9c\xf7\xd8\x7f\x8f\x6c\x54\x1c\xa5\x18\x52\x58\x0e\xab\x71\xdf\xbe\x5d\x88\x3c\x09\x95\x2a\x24\x72\x3b\x8b\xa6\x6e\x9a\x13\x4d\xb6\xd9\x8a\x53\x59\x68\x28\x34\xb3\x5f\xa2\x79\xcb\x8f\xfd\x91\x38\xa1\x80\xd8\xf5\x82\x93\x2e\xe7\xf4\x17\x32\xce\x49\xe5\xed\xb9\xa2\x36\x80\xaa\x2a\xdc\x67\xbf\x39\xcd\xad\x91\xca\x84\x31\xa9\x9f\x49\x35\x19\x96\xa3\x65\x77\x59\xc3\xb1\xdb\x3b\x9a\xbe\x27\x56\x89\x14\x68\x59\x5a\xbc\xe7\x62\x7d\x49\x09\x61\x75\xc8\x5d\xb7\xdc\x4b\x69\xea\xea\xdf\xf8\x45\xd8\xa0\x00\xa5\x89\x6d\x85\x76\x76\x1d\x19\x65\xdc\xb2\x9a\x7d\xe4\x2d\xea\xdb\x32\xff\x22\xaf\xae\x24\x97\x34\xdd\xbe\x43\xab\xde\x36\xaf\xaf\xde\xd7\x52\x52\xca\xc4\x33\x1d\xdd\x96\xf8\x7f\x27\xd2\x79\xee\x3c\x08\x3f\x42\x65\x92\xd2\xe8\x95\x6b\x65\x7f\xec\xa7\x81\x02\xbb\x87\x92\x0c\x65\x03\xfd\x35\x15\x5a\x9e\x6b\xd0\xda\x4a\x89\x54\x55\xd1\x83\xd0\x15\x86\x01\x85\x81\x37\xe7\x62\x56\xb3\x5e\x32\x73\x0a\x53\xbb\x50\xec\xd6\xfa\xa3\x6a\x67\xc5\x73\x85\x8e\xe7\xc3\x21\x90\xbb\xc5\xe4\xf8\x6b\x26\x7a\xfd\x13\x93\xa7\x4c\x10\x12\xba\x61\x0d\xb5\xce\xab\xa2\x7a\xf5\x19\x59\x65\x84\x55\xf8\x74\x45\x1b\xcb\x0e\xbf\xc0\x66\xf0\x1f\x8b\xd1\xa1\x0e\x20\x21\xdf\xfe\xaa\xf6\xb9\x7f\x1d\xea\x98\xf6\xcc\x83\xa5\xf5\x9b\x36\xc9\xe9\x10\x2d\x1a\x05\xdb\x37\x37\x1d\x66\xce\x85\x0e\x8d\x26\x25\x3e\x43\x89\x8b\xd7\x7b\x0f\x64\x9e\x0d\x63\x06\xa8\x01\x45\xe7\x0d\xc8\x82\xa6\x71\x5e\xbe\x5a\xcf\x6c\x7e\xc9\x88\x87\x9e\x59\x6a\xf3\x81\x65\xbb\xab\xc6\x8f\xe8\x07\x25\x29\x95\xc4\x08\xda\x45\xac\x84\xb3\xbc\xaf\x8e\xc3\x58\x3a\xce\xa6\x2d\xaa\x53\x9d\xfb\x9e\xa0\xa5\x72\x98\x8e\x53\x43\x7d\xd1\x87\xf3\xf6\x24\xb5\x97\x7d\xf6\xef\x81\xb3\x80\xcc\xdc\x76\xb5\xfd\xde\xff\x2d\x36\x89\xe9\x8b\x72\xde\xca\x5c\x2a\xba\x0b\xcd\xb5\x85\x0a\x13\x34\xb3\x7b\x96\xa7\x5c\xb5\xa7\x7a\x8a\x63\xd0\x09\xe3\x94\x98\xb8\x26\x79\xbd\xa7\x41\x57\xc0\x1f\x4f\x53\x0a\x72\xf6\x5d\x0c\x54\x57\xc7\xdf\xe3\x05\x74\xd2\x85\xdf\xbd\x72\xd5\x97\x13\x64\x54\x0e\xd5\x29\x8b\xb0\xc7\x6e\x3c\xe0\xe7\xa4\x4e\xa6\x53\xa3\x4d\xec\x59\x61\xbb\xb8\x68\x14\x35\xea\x2c\xb2\x4d\xfb\xaf\xd8\xfe\xc4\xfc\xa6\xae\x0e\x2f\x8d\x5e\xe3\x5c\xf0\x47\x68\xc1\x34\x65\xeb\x7a\xff\x7e\x76\x1c\xe2\x80\xfa\x6d\x89\x6d\xfe\xea\xbc\xc5\x79\x76\x47\x43\x1a\x10\x32\xa8\x73\xcc\xb6\xbf\xd3\x62\x9b\x9d\x96\x45\x89\x6f\xa7\xf1\x80\x9d\xdf\x55\xfb\xb4\x0c\xb9\x8c\x7b\xa4\x04\x35\x59\x4f\xaf\xd8\xc5\xb1\xda\x7f\xd6\x55\x51\xf8\xf2\xb4\x7f\x27\x8a\x71\xea\x37\x73\x69\x1b\x4d\xb3\xd8\x1d\xd3\x90\x52\x33\xc6\x9e\x78\x32\x67\x5e\xaa\xc6\x50\x11\x05\xa2\x3c\x9d\xbf\xa6\x3f\xd0\x28\x53\x66\xdb\x34\x7c\x6d\xdf\x82\xba\xfa\xab\x68\x65\x91\xd2\x6f\x50\x5f\xca\x2b\x2c\x9a\x73\x6d\x98\x66\xac\x77\xa1\x9f\x4f\xe5\xa8\x1d\x43\x9b\x2c\x14\x66\xf0\x32\x6f\xc6\xb1\xc6\x57\xd7\x03\x8b\x15\x6d\x5c\x33\xdb\xfa\x0d\xca\x12\x8b\x7b\xf8\x75\xc1\x9f\x26\x30\x08\x81\xe6\x9f\x3c\x9d\xb7\x47\x50\xd8\xed\x99\x2f\xd6\x55\xf9\x63\xa1\xb8\x92\xf9\xd3\x62\x24\xd2\x14\x5f\x96\xdd\xb6\x27\xf5\x6e\x69\xa6\xcc\xd4\x18\x4d\x6f\x0e\x43\x6e\x53\xbf\xaa\xca\xcb\xd5\x2b\x7e\xcd\x06\xe7\xc7\x27\xd2\xf1\x89\x35\x27\xbc\xc6\x9e\x26\xf3\x0f\x7f\x1c\x20\x88\x06\x4e\xed\x65\xb8\x0b\xb2\x80\xc3\xd0\xf2\xf8\xa5\x90\xb2\x40\x26\x02\xe3\x68\x3b\xa6\xf9\xc4\xe9\x5d\x45\x2c\xa3\x1a\xe1\xb7\xdb\xeb\xdb\xeb\xd5\x3f\xfd\xcd\x44\x60\x75\x13\xf2\x66\x5d\x1d\x8e\x8e\xd1\xf6\xb1\x2c\x88\x23\xef\xaa\xb3\x54\x16\x92\xed\x87\x23\xd3\x72\x80\x0c\x8c\xea\xa5\x18\x21\x06\x4e\x7f\xea\xa1\xd2\xb8\xab\x2e\xe8\xa3\xdc\xc0\x38\xce\x08\xb9\xf6\x78\xb4\x91\xf5\x1f\x4b\x5c\x32\x18\xeb\x40\x64\x7d\xa9\xca\xa3\x22\xa7\x8f\xce\x33\x90\x3d\x93\x59\x75\xc4\xba\x3d\x13\xc6\xa0\x5b\xef\x34\x8f\x5c\x5e\xf3\xbe\xd2\x56\x10\xcc\x4d\x8b\x0b\xeb\xe6\x79\x2c\xfd\x5c\xe1\xc8\x54\xec\x60\xfe\xd6\x21\xbf\x2d\x9f\x88\xed\xdf\x3f\x6d\x12\x72\x6a\x1a\x70\x45\x83\xd9\x23\x26\xa0\xac\x88\x27\x48\xa2\x5b\x72\x45\xac\x2f\x26\x4c\x82\xda\x02\x91\x42\x3e\x69\xfa\xc7\xc4\x84\xda\xed\xe3\x7b\x18\x29\xfe\x08\x4c\x03\xec\x25\x95\x2b\x28\x49\x9c\x01\xdb\x31\x6a\xf8\x6f\xd2\x29\x2e\x9b\x41\x4c\x19\xa3\xdc\x83\x82\x09\xdc\x11\xd3\xd4\x4a\x5c\x3e\xfe\xb8\xdd\x5e\x3d\x3e\xfe\xb9\xb9\x76\xe2\x79\xfd\x00\x30\x04\xeb\xda\xef\xed\x86\x5a\x63\x0b\xf5\xf9\x1b\x96\xe4\xf3\x4e\x9f\x3b\x55\x41\x62\x21\x20\x87\xe3\x37\x6c\xaf\xa1\x85\x5d\x65\xc1\x3a\x5f\xdc\x15\x32\x9a\xea\x57\x88\xf5\x88\xab\x05\x33\x9e\xc6\xbd\x2c\x06\x39\xc0\xfa\x1a\x9b\x36\x2f\x29\xf2\xa1\x92\xd8\xf4\x97\x05\xb7\xb8\xdb\xa6\xad\x6a\x9c\x94\xdd\x50\x08\x46\xf9\x9b\xcd\xe6\xde\x5f\x5e\xe8\x90\x42\x13\x43\x42\x69\x63\x14\x0b\x76\xb3\x39\x1c\x55\x6d\xac\xeb\x30\x00\xe9\x67\x0e\xd6\xec\xc3\xcb\x20\x26\x8c\xe9\x1b\x34\x6f\x13\x36\x69\x9b\x07\x4d\x62\xcf\x32\xe3\xc7\x73\x1e\xba\xdc\x92\x57\x93\xe1\x93\xdd\x1f\x15\x04\x04\x99\x7a\xbd\xbd\xde\xfb\x7b\xd4\x89\x85\x2f\xf5\x9c\x96\x9d\xcd\xeb\xf6\xde\x9e\x9c\x6a\xfa\x96\xb5\x88\xd0\x19\x94\x9f\x90\x53\x4b\xb8\xd5\x18\x99\x8f\x33\x82\xee\xc6\x6d\x5c\x57\xa7\xe2\xfd\xeb\xa2\x2a\x9a\xd4\xf6\x16\xe7\xa5\x41\x35\xc3\x4a\x98\x30\x60\x84\x3e\xa7\x5b\x7b\xaa\x51\xe7\xaa\xf5\xa4\x48\x26\x8c\x39\x27\x3e\xfd\x52\xc2\xac\xe6\x65\x42\xe3\x5c\x7f\xb7\x6f\xb9\x05\xef\x67\xc1\xcb\xcd\x6e\xd9\xa8\x1b\x16\x64\x84\x67\xa7\x27\xfb\x09\xfe\x83\x1a\x16\x5b\x22\x3c\x53\x23\xfe\x1b\x89\xab\x60\x76\x22\x4f\x94\x9e\x82\x53\x6e\x6d\x62\xf3\xb7\x18\x15\x7f\x76\x16\x50\x92\xe4\xcd\x36\xd0\xde\xea\x5f\xb3\x07\x62\x9a\x13\x0c\xe1\x00\xbf\xa8\x33\x0f\xb5\x7d\x96\xbc\x7c\x1d\xd1\xfe\xb9\xc1\x51\x90\x19\x17\xbc\xd8\x8f\x5a\xd5\x0b\x2a\x0e\xc2\x44\xa9\xa2\x72\xcf\xb3\xa7\x2b\xf3\x17\x88\x13\xeb\x4c\xba\x4f\xb8\x6f\x7f\x2d\x75\x39\x98\x38\x53\x4e\xd9\xbc\x36\x55\x7d\x58\x4d\x64\x49\x96\xf8\x0d\x4d\x2c\xb9\x62\x3d\xdd\xd4\x48\x1e\x45\x98\x24\xe4\x9a\xf8\xea\xa0\x7c\x7f\xae\x8a\x62\x4c\x3f\x2d\x4c\x22\x12\x3d\x20\x54\xf1\xb7\x7c\x63\x26\x0d\x05\xe9\xe5\x1d\xeb\xea\x50\x51\xf5\xe1\xd1\xac\x0b\xc8\x0f\x30\x8f\x2c\x4c\xaa\x59\xcc\x1c\xb6\xab\xaa\x71\x55\x14\x24\x66\xdd\xb4\xd8\xcb\xbf\x4f\x9f\x20\x13\x29\x9f\xa0\xb8\x9a\xb5\xa5\x09\xf1\x77\x2a\x12\x46\x6d\xb8\x5b\x2c\x8a\xb9\x6a\xd2\xf4\xb7\x85\xb6\x00\x19\x4a\xf3\xe7\x65\x83\x75\xbb\x37\x79\xa9\x1f\xaa\xef\x79\xd9\xae\xda\x7e\xe9\xbb\xf1\xc0\x02\xcb\xbf\x0e\xc7\xa1\x2d\xd8\x80\xe2\x24\x4c\x76\x75\xfb\xe2\xff\x24\x03\xab\x15\xe3\xbd\xb6\x7d\x65\xf6\xae\xac\x31\xa7\xbc\x33\x32\x32\x64\x05\xae\x1e\x1f\xff\xb5\xfa\xbe\xdb\xf4\x75\x3b\x23\x53\x99\xa9\x21\x92\xdf\xd7\xae\x7a\xdc\x1f\x47\x9b\xd1\xb6\x1e\x3d\xc1\x63\xa0\xc5\x3b\xfc\xc0\xe2\xb1\xec\xe7\x22\x42\xe4\x25\x9a\x3a\xb7\xe1\xd2\xe8\x1a\x44\x49\xb0\xae\x6f\xc4\x2e\x80\xaf\x55\x7d\xb6\x19\xe3\xc9\x37\x35\xdc\xf8\x8c\x17\x49\x3d\x5d\x61\x7b\x8d\x2d\xe4\xc5\x85\x31\xf5\x27\x28\x9e\xda\xc9\xfd\x01\x45\x55\xb5\xdb\x4f\x4f\xb3\x0f\x41\x10\x6a\xb4\xa2\xbe\x1f\xd5\x3b\x5e\x8d\x18\x1f\x16\xcd\x02\x04\x41\x92\x10\x29\xd1\xf1\x24\x8b\x5c\x79\x94\x5c\x7f\x39\x90\x49\xd0\xb3\xef\xaf\x5c\x01\xc9\x41\x6b\x67\x26\xde\x19\x3e\x08\xc2\x54\xc8\x11\x9b\xfe\x1f\xd3\x1f\x64\x01\x0b\x75\x8f\x93\x9d\x3a\xf0\x93\x07\x85\x80\x09\x45\xc9\xde\x4f\xcc\xbd\x86\x18\x04\x4c\x59\x0e\x9b\xfb\xc7\xe7\xdd\x4b\xff\x47\x14\x64\x17\xd6\x55\x5e\xaa\xbc\xa6\x08\x2a\xaf\x4a\x52\xaf\xea\xc7\x98\x80\x50\x0f\x7b\x55\x95\x0a\xda\x85\x0c\x03\x04\x51\xa0\x68\x66\x60\xa9\x6d\xcd\x20\x2f\x5f\x27\xea\xb7\x10\x44\x91\x41\x17\x83\xac\x4a\xfd\x95\x26\xcd\x82\x3a\x1b\x04\x71\x18\x98\xa1\xef\x72\xf3\x6b\xea\xe0\x66\x7e\x54\x6c\x89\x93\x1a\x6c\xaf\xeb\xea\x68\xb1\xea\xbe\x70\x0b\x01\x4f\x33\x4a\x69\xdf\x5f\x8f\xfb\xe3\x20\x48\xb8\xe5\xbb\xb3\x22\xa1\x7a\xf6\xd6\x93\xd4\x70\xe1\x61\xb5\x5b\x2c\xf5\x40\x00\x02\x41\xca\x35\x58\x02\x52\x8d\xf5\x21\x2f\x91\x3c\xe3\xd2\xa3\xdf\x67\x12\x3f\x10\x64\xa1\x4d\x27\x3f\x7d\x7f\xdc\x3c\xdc\xfe\x73\xff\xf4\xe8\xe9\xef\x21\xc8\x12\xab\x80\x6e\x19\xce\xc6\x30\x10\x08\xb2\x54\x52\xf6\xae\x07\x2f\xad\xda\xdd\xf9\xf8\xfb\x04\x24\x04\x59\x16\xd0\x59\xcd\x9b\x6d\x05\x25\xa9\x9b\xe9\x44\xc9\x0c\xa3\x57\xa6\x3b\xf7\xeb\x40\x06\xce\x65\x20\xb1\x1e\xd5\x68\x20\x10\x5c\x84\xe8\x73\x1f\x45\x71\x53\x54\x33\xc5\x0b\x08\x80\xa5\xe4\xe7\xce\xeb\x98\x4f\x35\xde\xe4\x75\xd3\x0e\x79\x75\x08\x20\x56\xc4\x19\xb9\x6f\xc0\xe0\x37\x68\xb6\x2d\xb4\xb9\x9a\x34\x4b\x8e\xbf\x3f\x88\x08\xb2\x81\x85\xf1\xb1\xc4\xb1\x4a\x0e\x04\x52\xa4\x99\x87\x7f\xe7\xed\xa9\x80\xbc\xc6\x7d\xf7\x2d\x5a\xdc\xa7\xb3\xdb\x94\x60\x28\x0a\x77\x7d\x78\x63\x74\x32\x04\x52\x42\xec\xc2\x84\x53\x6f\x1a\xa4\x62\x26\x1e\x71\xa9\x41\x3d\x96\x9c\x83\x40\x9a\x80\x42\x80\x4f\xcc\x7b\x8d\x84\xa1\x66\xd9\x1d\xb7\xb4\x67\x87\x89\x10\xe4\xa4\x3b\x08\x02\x15\xa6\x24\x4c\x86\xaa\xea\xbe\x53\x18\xf5\x07\x84\x24\x65\xad\x83\x1a\xc6\x1a\x9e\xd9\xfe\x93\x52\x5f\xe7\xcd\xf1\x34\x03\x0b\x43\xa0\x99\xb0\xd8\x0b\x68\xde\xee\x7d\x9e\xd0\x9f\xae\xe3\x84\x7c\xc9\xab\x6a\xd6\x49\xe7\x8f\x8b\x98\xde\xf6\x95\xca\x5f\x61\xe4\x3d\x43\xa0\x4d\x6c\x35\xca\x4f\x87\x81\x22\xaf\x37\x5f\x18\x18\x3e\x12\x89\xb2\x5d\x02\x4b\x29\x61\x08\x30\x51\x4a\xf4\x43\xe7\x44\x68\x33\x6b\x86\x22\xa2\x62\x85\xf7\xdc\x3c\x6c\x7c\x3a\xca\x70\xe9\xd5\x38\xaf\xa1\x7e\x2f\x2b\x8d\x57\xd5\x2c\xb7\x0d\x81\x91\x86\x00\x9e\xfb\x06\x0a\x1c\xd7\xe1\xa1\x73\x2c\xa9\x72\x8e\xdd\xe4\xb5\x6b\xdd\xa7\xf9\x28\x77\xe6\x87\x25\x56\x91\xf7\x68\x61\xe8\x63\x79\x55\x08\x03\x2d\xe3\xb1\x8e\xca\xa6\x7d\xfb\x0e\xa5\x2e\x6c\x28\x40\x29\xfb\xa5\x98\x1b\xc2\x90\x69\xee\x26\x5e\x17\xdc\x6c\xfe\xef\x94\x4f\xb1\xa3\x10\x86\x09\xd3\x2e\x2d\x7f\x73\x18\xf3\x99\x43\x18\x0a\xe4\x54\x11\xd9\x5c\x8d\xa9\x9d\x20\x0c\x51\xe9\x11\xa0\xaf\x8b\xa3\xfd\x21\x16\xc7\x14\x84\xdf\x50\x32\xfe\xdb\xa9\x57\xb0\x82\x30\x02\x4e\x5d\x79\x85\xa3\x1a\x74\x7f\x8e\x75\x42\xfb\x40\xfb\x55\x35\x12\x42\x1e\x02\x85\xa1\x9e\xab\x64\x84\x2a\x87\x90\xa7\x3a\x76\x91\xe8\x4f\x94\xdf\x72\x63\x5d\xd1\x05\xe6\x1d\x08\x39\x72\xaf\x27\x41\xfe\xc1\xb8\xe7\x08\x42\x6e\x14\x85\x59\x3b\x32\x5a\xba\x3a\x35\xed\xf8\xa9\x13\x40\xe2\x4b\xff\x79\xb5\xd9\xf5\x7f\xd3\x09\x81\x4c\x0e\xf9\x44\xae\x0b\xc2\x04\x03\xcb\x0e\xea\xb4\xa9\x02\xee\x8f\xa4\x68\x1d\x6c\xe7\xcb\x12\x86\x26\xf4\x07\xb3\x20\x52\xa1\xd7\x89\x3d\x1f\xdb\xea\x1f\x79\xf9\x5a\x7c\xc1\x5a\x0e\x61\x16\x82\x4a\xe6\xbc\x75\x8b\xd3\x3d\x04\xc6\x7c\x6f\x86\x6f\xc5\xec\x6c\x86\xe5\x91\xe9\x6d\x5e\x08\x3a\xa6\xd4\x7b\x89\x9f\x73\x8d\x4b\x08\xc1\x64\xd6\x39\x79\x83\x06\xe3\xb1\xb5\x0a\x65\x1c\x6b\xd7\xa6\x41\x7c\x0a\xcf\x54\xda\xfc\xe2\x7b\xca\x84\xb1\xd0\x25\x57\x5f\xca\x7b\x68\xde\x51\x7f\x3b\x6d\xa0\x2e\xf3\xf2\x75\xb9\xb4\x09\xa1\x0a\x98\x95\x72\xfa\xb0\xae\xc0\xc5\x36\xb5\x94\x54\xf1\xe7\x46\xd2\xb7\x89\x53\x6a\xc6\x26\x8c\xbf\xf8\x1d\x25\xd1\xcd\x91\xed\xe9\x78\xac\xea\x16\xf5\x73\x45\xdf\x60\xb4\x24\x95\x16\x84\x72\x3a\x95\x79\xcf\x6a\xdc\xbd\x30\x77\x58\x67\x3a\x1e\x0a\x2e\xab\x53\x5b\xd5\xb9\x06\xbd\x29\x50\xb5\x55\xe7\xda\x2e\x69\x64\x41\x68\xb2\x94\x32\x97\xc7\x41\x96\xc1\x5f\xd1\x68\x41\xdb\xc5\x67\x4e\x0e\xe1\xfc\xa1\x27\xd7\x61\x81\xb0\x94\xa0\x56\x0e\x7a\x68\x49\x9c\xc3\xc9\x80\x05\x5a\x43\xec\x89\x90\x4a\xf4\xfd\x10\xd3\xcb\x85\xda\x32\x79\xac\xab\xc3\x61\x04\x33\x18\x6f\xa6\x2c\x0a\x33\x92\xa6\xa6\x62\x23\xe9\x49\x10\x41\xe4\xba\xf7\x85\x59\x94\x80\x17\x06\xba\x3f\x0f\x18\xcf\xc9\x34\x65\x9c\x2b\x4a\xdf\x14\xf9\xff\x9d\x72\xed\xaa\xc7\x43\xb6\x18\x18\x07\x4e\x65\x53\x2a\xb9\xb8\xac\xeb\x0e\xca\xf7\x45\xaf\x25\xf3\x27\x69\xcb\x75\x5b\x54\xe5\xeb\x45\x42\x14\x58\x9a\xa1\x67\xba\x1a\xc8\xf7\x17\x67\x07\xcb\xb8\xa1\x6a\x21\xd5\xa1\xa0\x70\xab\xe8\xb6\xec\x4b\xe6\xc0\xb2\x04\xc9\xe7\xef\x0c\x9a\x47\xb8\xcf\x96\x19\x13\x01\x73\x45\xf0\x37\x28\x47\x7b\x21\x83\x34\xf2\xa8\x15\xb7\x95\xdf\x41\xd3\x4e\x5b\x77\xa6\x2b\x9b\x81\xb0\x41\x38\x29\xcf\xfe\x57\x55\xe2\xf6\xad\x72\x1b\x82\xff\x80\x20\x03\x8a\xd3\x9c\xa7\x4b\xe2\xb6\x1f\x33\x11\x5a\x3f\x14\x91\x39\xee\xf2\x6f\x90\x7f\x15\xa7\x30\xcd\x15\xf9\x46\xf7\xb7\x0f\x57\x9b\xdd\xfe\x88\xf5\xee\x9f\xfe\x19\x30\xb3\x30\x37\x1b\xc3\x74\x5b\x62\x33\x9a\x06\x28\xb9\xd5\x4d\x6a\x36\xce\x35\x9e\x3e\x0e\x22\x27\xc7\xf9\x76\xfd\xe8\x52\x7b\xfb\xd5\xfd\xe3\xcb\xc3\xae\xbf\x00\x26\x54\xe4\xb2\x8e\xcf\xf0\x57\x29\xe3\xd1\x1e\xe9\x40\x03\x23\x57\x9d\x19\x10\x7c\x60\x72\x68\x17\x32\x1a\x10\x05\xa1\xa0\xad\xcd\x7c\x6a\xf7\x6d\x57\x8e\xb1\x63\x61\xd2\x47\x01\xe3\x84\x15\xc2\x63\xde\x5d\x07\xeb\xfd\x67\x55\xbf\x37\xd4\x23\xe5\xaf\xc8\xa2\x38\x73\xc4\xd7\xe6\x65\xb6\xfb\x46\x2c\xb1\x10\xc4\xb7\xea\x73\xc0\x06\x40\x14\x81\x15\x4e\xfb\x71\x35\xde\x77\xa3\x98\x71\xf2\xbf\x4e\x8d\x26\x81\x8a\xb1\x05\x8e\xe2\x38\x22\x98\xc1\xdd\x59\xe7\x30\x9c\x12\xdb\xfa\xe3\xbe\x86\xcf\xbf\x55\x5b\x81\x28\x4e\x34\xa5\xd5\x56\x35\x96\x30\xf2\x51\xa2\x58\x59\xb2\xc8\x06\xdb\x7a\x9e\x0b\x87\x88\x47\x82\xf1\x41\xa5\xe8\xda\x56\x50\xfd\xb9\x3c\x8d\xa9\x79\x48\x53\xd5\xf0\xd1\x98\x91\xc2\xd9\xf4\x95\x70\x19\x52\xc7\xe2\xee\xd7\x3d\x36\x0d\xcc\xb4\x74\xb3\xd9\xcd\x72\x15\xc8\x01\x0e\xbb\xc5\xce\xc0\x92\x90\x38\xbb\x46\x68\xdf\x96\xf7\xcd\x88\x9b\x88\x22\x26\xcc\x8f\x83\xb2\x25\x75\x9c\x7e\x05\xfa\x9d\xfe\x6a\x12\x44\x44\xa8\x70\xa2\xee\xad\xfb\x4d\xef\x33\x45\x89\x89\xad\xde\x5f\xeb\xb7\x8a\x28\x0d\x53\x15\x78\xeb\x52\xdf\x84\x37\x6c\x29\xd6\x8d\xd2\x44\xd0\x99\x6b\xfc\x77\x7f\x66\x9a\x46\xe1\xb0\x15\x15\xe7\x19\x8c\x67\xf6\xe6\x52\x05\x64\xcb\x7d\x2e\x78\xdb\xc2\xb6\x95\xcb\x86\x2c\xca\x12\x0b\x0e\x3b\xba\xba\xc5\xad\xde\x55\x4b\xe8\x68\x88\xb2\x34\x8e\xba\x91\xdf\x6a\x90\x2f\xa5\x87\xab\xe8\x91\xcc\x38\x44\x99\xe2\x14\xf1\x41\x59\x56\xa7\x52\x79\xb4\x19\x44\x22\x94\xd2\x79\x3b\x83\x94\x67\x7f\x50\x80\xb6\x55\xbc\xdb\xb2\x0b\x4f\xb6\xe3\x95\x28\x93\xc0\x29\xa2\x7e\xfe\x18\x64\x6b\x20\x52\x41\x90\x78\x1c\x49\x75\x5c\x62\xec\x81\x48\x07\x4a\x5a\x92\xa1\x16\xcb\xee\x91\xee\x87\xb5\xa5\x95\xed\x89\xa7\xea\x71\x67\x03\x48\xa0\xc7\x1d\x44\xc9\xc9\xc3\xf1\xba\x07\xbd\xc5\x8e\x10\x0d\x55\x49\x0f\xf0\x8e\xa3\x60\x6c\xfa\xbb\x26\x0e\xc9\x0b\x92\xf8\x9a\x97\xeb\x4a\xa3\x33\xdc\xfe\x30\x4f\x28\x05\xe6\xe4\xee\x4b\x28\xe8\x89\xd9\x70\x1c\xc2\x1e\xf3\xe9\x18\xc1\xf3\xe1\x16\x4c\x66\x98\x1a\xc1\x9d\xbc\x2c\xea\xcf\xcd\xed\xfc\x3e\x32\x43\x13\xc7\xb6\x2b\xe5\xe5\xeb\xd6\xa9\x24\xdd\xe5\x25\xc2\x00\xc8\xfe\x5d\x0d\x06\x22\xa3\x42\x4a\x03\x52\x37\xc9\x65\xc3\xe6\x6c\xf6\x19\x9d\x11\xbe\xa7\x8b\x80\xd7\x6f\x70\x38\x0e\x1b\x6c\x64\xb4\x24\x1b\xe8\x64\x4d\x56\xf5\x17\x29\xa6\x38\x00\x00\x67\x62\xbe\xe5\x1f\xb8\xfa\x9c\x49\xdd\x43\x1c\xc6\x86\xa8\x92\x0c\xe4\x3d\x2f\x08\xc4\xa1\x56\xdc\x25\xff\x3e\x09\x36\xf1\x58\xce\x82\xd7\x98\xf1\x88\xf6\xc0\x5b\x55\xed\xad\x5f\x84\x7a\x9c\xf9\x83\x98\x09\x43\x35\xfd\x57\xcf\xb8\xd9\xbb\xdd\xd4\xa6\x38\xbb\x9c\xb2\x3a\xe0\x35\x92\x74\xf4\xf6\x74\xc4\x9a\x30\x4c\x3f\xaa\xb9\x69\x8c\x99\xd1\x84\x86\x7e\xa3\xa0\xad\xdb\xd0\xfb\xb6\x52\x37\x22\x4a\x25\xb9\x15\x7f\x3e\xfe\xb9\xf6\x7f\x8b\x43\x4e\xc9\x3e\x22\x00\xd5\x88\x87\x8b\xda\x2b\xc4\x71\xcc\xc8\xd1\x7b\x46\x68\x9a\x1e\xa3\xb9\xbc\xe4\xe3\x98\x8b\xc8\xf5\x34\x2f\xdb\xde\x38\x96\x56\x22\xeb\xa5\xc1\xda\x6a\x33\xf6\xd2\x53\x5f\x5d\xd3\x24\x64\x73\x9e\x37\xbb\xef\x9b\x07\x1f\xc7\xc4\x9c\x09\x8b\xea\x68\xab\xa3\xf3\x35\x9e\x0a\x50\x23\xa9\x43\x88\x79\x6c\x21\x39\x5e\xe8\xeb\xd7\xa6\x6c\xeb\x7c\x86\x31\x83\x98\xa7\x9a\x3c\xc2\x2b\x2a\x88\x8c\x76\xc9\x98\xcb\x80\xc0\x09\xed\x17\xfb\x9a\x1b\x96\x84\x7d\x11\x93\x72\xf3\x63\x3f\x3e\x4e\x22\x50\x63\xa6\xf9\x49\x07\xd0\x45\x8d\x72\xa1\xa7\x11\xe2\x24\x0d\x68\xd1\x57\x65\xe1\xaa\xbf\x9d\xef\xf6\xb1\x00\xdf\x81\x38\x01\x4d\xd0\x01\xfc\x85\xb5\xca\x1b\xbc\xab\x86\x20\x69\x2c\x25\x93\xfe\xcf\x98\x06\x20\x62\x1e\xf9\x05\x71\x1a\xa4\x14\xa0\x79\x96\xd9\x6e\x22\x3b\x81\xd4\x3f\x2e\x23\x9f\x38\x75\x78\xda\xbc\x74\xc1\xfa\x18\x2c\x03\x71\xc6\x22\xca\x9e\x6e\xab\x53\x49\xea\x13\xcd\x65\x03\x23\xc4\x19\xcf\x6c\x4d\xea\x54\xaa\x7d\xb0\x0e\x36\xfd\xe9\xa9\x95\x9d\x2a\xf1\x73\x0d\x87\x23\xe4\xaf\xe5\x18\x49\x2e\x96\x9a\x4c\x21\x16\x81\xc5\x1f\x6c\x8f\x27\xbd\xab\x9e\xab\x16\xda\x4b\x25\x31\x3f\x16\x99\x07\xfc\xae\xda\xb6\xb2\xf3\xdb\x71\x50\x5a\xa0\xea\xf4\x63\x00\x4f\x85\xad\x1b\x97\x57\x9d\x15\xb8\xd4\x0a\x87\x58\x2a\x4d\x89\x08\x97\xab\xb3\xb2\x1a\xee\x98\x62\x16\xb5\xe3\x84\x78\xc7\x91\x93\xa7\xb5\xa3\xce\xf4\x12\x8a\x45\xdc\x04\xc4\x2a\x63\x94\xaf\xda\x7f\x35\x2d\x17\x02\xd4\x58\x07\x8a\xf6\x4f\x4b\xe5\xd0\x5c\x6c\xc2\xb1\xe6\x29\xb5\xb7\x83\xd6\x5b\x2c\x26\x3e\xce\xef\xad\x78\x8c\xa1\xa2\x09\xe3\x38\x88\x28\x15\xfb\x9f\xad\x4f\xbf\xc4\x06\x61\x44\xfc\xb3\x69\xd4\x09\x0b\x58\xfe\x18\x3c\x30\x82\x80\x25\xa0\xb5\xb5\xe4\xa7\x7a\x59\xa2\x0a\x78\xc8\x04\x99\x3c\xb4\xc8\x54\xdb\xdd\xee\x77\x32\x1e\x42\x32\xe2\x0e\x7a\xb6\x94\x8c\x97\xfb\x29\x0f\xa5\x25\x0a\xf5\x49\x8b\x09\x18\xd1\x8d\x61\x51\xe4\x29\xa7\x9e\xa0\x6e\x4b\xac\xff\xf3\x54\x8d\xfc\xf5\xe9\x15\x59\x92\x65\xa3\x82\xe3\xfa\xac\x26\xe9\x7c\x1e\x69\x61\x22\xdf\x4b\x0e\x75\x0b\x65\xf3\x58\xee\xde\xd0\x42\xb1\x0c\x51\x6a\x4f\x9f\x94\xc7\x51\x3a\x22\x6f\xad\xa1\x54\x13\x30\xee\xec\x06\xb8\xb0\xcc\x2e\xa5\x53\xaa\x6e\x9c\xd3\xd5\xef\x65\x3c\x49\x2d\x8f\x74\x67\xaf\xde\xf2\x42\xd7\x58\xba\xbc\xdc\x64\xa2\xf1\x24\x4d\x22\x17\x4f\x5f\xe5\xba\xef\xbb\x75\x3c\x04\xc0\x13\x93\xd8\x44\x46\xbf\xdc\x79\xca\x2c\xac\xff\xae\x7a\xed\x0d\xfb\xa6\xd4\xe3\x17\x90\x72\x4b\x2f\xf4\xe7\xe3\xf3\xe6\xcf\xf5\xf7\x95\x6f\x3d\x04\x2e\x20\xa5\x89\x2d\xcb\x90\x65\xfb\x03\x1c\xf7\x6d\xb5\xff\x16\xce\xee\x4a\x98\x94\xd8\xcd\xd7\x6f\x5d\xec\x5a\xb5\x9e\xbe\x81\xba\xbe\x68\x7b\xc5\x5f\x79\x7b\x21\x18\x02\x1c\x24\x8c\x9d\xa3\xd7\xb7\xf6\xea\x62\x66\x8f\xc4\xfc\x81\xcb\x00\x89\x99\x70\xfd\xb4\xde\xdc\xaa\xca\x4b\x77\xbb\xa3\x2a\x02\xa1\x67\xc4\x27\x17\x5d\xf7\xc0\x95\x90\x7a\xd4\x7b\xfb\x8c\xcb\x6d\x11\xcb\x6b\x8b\x2b\xc9\x28\x65\x6e\x6d\xde\xca\x6d\xab\x17\x83\x04\xad\xed\x67\x84\x82\x56\x9f\x93\xce\x70\x87\x91\x65\x9e\xd8\x6e\xfb\x96\x1f\x1d\x86\x6f\xbc\x49\x71\x54\x96\xcb\x51\x56\x75\x5d\x7d\xe2\x22\x9a\x1f\xb8\x89\x30\x4e\xc6\x3d\xdd\x57\x36\xeb\x3b\x1d\x96\x84\x81\xb5\xa8\x0a\x0a\x65\xa1\xf2\xfe\x00\x8b\x45\x34\xa1\x2b\xf6\xc2\x2b\xd4\xa2\xf2\xc3\xd9\x25\x3f\x3a\x0b\x03\x35\x80\x30\x7f\xb5\x4f\x6f\xbd\x1e\x21\x24\x21\x08\xda\xdb\x2d\x95\x62\x3f\xb7\x13\xc6\xb2\x2c\x76\x62\x88\xe5\xc9\x00\xe1\x4b\xeb\x69\xd1\x22\x61\x4c\x7b\xf6\x48\xfb\x20\x96\x41\xa9\x99\x3d\x08\xe3\x86\xa4\x03\x7e\x52\x85\xac\x37\xe1\x09\x13\x61\x38\x6e\x1c\x0c\x59\xb7\x6f\x75\xdf\xdf\x3b\xda\x49\x94\x84\x94\x7e\xa1\x58\xb5\xff\xa3\xd0\x94\xee\x6e\xe8\xf3\xd0\xc6\x11\xf6\xc7\xc0\x4e\x93\xee\x96\xac\xf7\x8f\x7a\x7b\x3a\x5c\x9d\x27\xfb\xcb\xd4\x06\x26\x91\x46\xfa\x95\x51\xea\xff\x1f\xa0\xde\x8f\x95\xff\xb0\x49\x9c\x89\x9e\x03\xce\x56\x34\xe6\x94\xd7\x6e\x20\x37\xc0\xb8\x47\x89\xd7\x9d\xd9\x6c\x49\x49\x42\x11\x8b\x86\xdd\xc1\xa6\x67\x24\x3a\x05\x5b\x97\xfc\xf3\x76\xfd\xf8\xa5\x47\xb3\xe8\x32\x75\x96\x85\x6a\x4b\x1e\x7b\xe0\x26\x5c\x17\x21\x6f\xdb\xaa\x86\xd7\x19\x13\x00\x24\x59\x22\x68\x7f\x7a\xca\xcb\xff\x7a\xcb\xc7\x9f\x43\x44\x16\xfb\x01\x5a\x37\x07\xa8\x7b\x4d\x83\xd5\x04\xc2\xe8\x07\xbb\x14\xbc\x4d\x13\x58\xad\xfe\x4b\xc5\x42\x48\x20\x45\x2a\x19\xad\x1e\x57\x57\xab\x87\x3f\xfd\x6f\x81\x51\x3c\xf0\xf9\x7d\xd5\x85\x7e\x1f\xd8\x8c\x52\x18\x89\x64\x19\x7d\xe3\x12\x4f\x75\x45\xea\xf5\xcb\x9a\x3c\x90\x48\x6e\xbc\x44\x1b\x59\xe1\xbf\x4a\x37\xfb\xd3\x24\x7a\x36\x68\xfb\x81\xb6\x7d\x45\x68\x35\x65\x11\x82\x44\x25\xb1\x6d\xe5\xb0\xac\xd6\x08\x6e\x47\x18\x95\xb7\x13\x05\x09\xf9\x4a\xab\xbb\xeb\xbf\xd7\x89\x04\x89\x52\x09\xed\x1f\x44\x90\x3b\xf3\xf3\xc7\x0d\x7e\x90\x68\xc5\x6d\xe9\xe5\xad\xae\x3e\xb7\x05\x1c\x0e\x58\x53\x5e\xf5\xe2\xb4\xd9\xc3\xf6\x74\x74\x90\x98\x28\xc0\xd8\x91\xc5\xaf\xb1\x6c\x4f\xf5\x57\x52\xa8\x90\x98\xd8\xc2\x25\xe5\xa9\x2e\xd7\x50\xcb\xce\xa7\x2a\x0a\x58\xa6\x09\x87\xc4\x98\x8c\x50\x3f\xcf\x83\xdc\xe9\xec\xe9\x2f\x34\xf0\x20\x0d\x74\x40\x00\xc1\xeb\xaa\xec\x22\x4d\xad\x2f\x0b\x80\xd3\x9f\x49\x03\xcd\xa9\x79\x60\xb5\xde\xdd\xfe\xd8\xec\x2d\x13\x92\x7b\xff\x69\xa8\x52\xc3\x47\xc0\x60\xb2\x5b\x50\x14\xe7\x89\x13\x92\xb2\xc8\x58\x90\x40\x5b\x1d\xaf\x72\x6f\xee\xba\x3f\x7b\xc5\x82\xce\xc9\xc1\xa6\x1d\x08\x6f\x16\x60\x4b\x90\x32\x65\xe9\x55\x5a\x84\xc3\x5d\x2f\xa4\x03\x69\x14\x20\xf7\x6e\x09\x16\xc5\x65\x57\x27\xa4\x51\x18\x13\x5e\x77\x55\x2a\x82\x18\x7d\xc7\xa2\x78\x18\x25\x4e\xd2\x88\x71\x69\x69\xca\x34\xfe\x7a\x34\x0b\x6d\x23\xa3\x8b\x25\x40\xcf\x43\xdc\xb9\xd4\xbe\x71\x75\xbe\x25\xd2\xa6\xee\x3f\x4f\x63\x76\xc8\xc9\xb2\x49\xa3\x34\x22\x40\xd7\xaa\xd4\x79\xd5\x2c\x91\xad\x5c\xce\xd8\x34\x8e\x38\x45\x68\xef\x65\xb7\xed\x6f\xfe\xef\x94\xf7\xfe\x69\xca\xa5\xd5\x34\x24\x95\xae\xfe\x8f\x3a\xf0\x9c\xf0\xf9\xe1\x74\xf8\x7e\xd6\x75\xb5\x6d\xe1\x1d\xaf\xbd\xfe\xed\x00\x62\x87\x34\x09\x6c\x2d\x6e\xa5\xf5\xfe\x09\xda\x7c\x81\x4c\x7d\x36\xa1\x26\x77\x97\x04\x29\x09\x2f\xdc\x55\xaf\x57\xb9\x5e\x29\x85\xc7\xf6\xb2\x23\x74\xae\xed\xbc\x48\x66\x03\x69\x22\x6c\xc7\xa8\x85\xf7\x79\x9f\x65\x36\x46\x1a\x12\x54\xa5\x26\xbe\x21\xef\x32\xd8\x8f\xe9\x2b\x4f\x30\xa4\xd6\x18\x4a\x57\xe1\xe9\xe0\xe2\xed\x71\xe6\x38\x4d\x83\x90\xc7\x43\x33\xac\x6b\xec\xb8\x3a\xf7\x2c\xbc\x93\x27\x4e\x03\x0e\x0e\x0d\x7f\xfb\x74\xb3\x9d\x51\x7d\x4d\xdf\x4e\x1a\x59\xce\xed\x5c\x55\x34\x2b\xf7\xfd\x4f\x6a\x4d\xc5\x78\x27\x15\x70\x41\xa4\xea\x86\x65\x41\x4a\x48\x18\xba\xfb\x6d\xe7\x6d\x7c\x99\x72\xf8\x2d\x13\x03\xa4\x19\x88\x8c\x2a\x50\xf9\x01\x3b\x83\xba\x29\xf5\xc8\x92\xa6\x99\x4a\x53\x8b\x7a\x57\x45\x5e\x62\xb7\x4a\x47\x33\xd2\x7b\xcd\x29\x64\x21\xd9\x0f\xba\x02\xa1\x41\xa1\x9f\x8b\xd2\x29\x80\xfe\xf9\x76\x3a\xfd\x39\x6c\x71\xa9\x74\x51\x7d\x89\xbf\x5a\xef\x26\x2d\x06\x87\xa9\xd4\x0c\xc6\x3d\x00\xbf\xcb\xd7\xa4\x52\xdb\xbd\xa4\x1d\x9c\x46\xcb\x5a\xdf\xff\xae\xb1\x52\xe9\xa0\x29\x76\x37\x7d\xfd\x31\x55\xb1\x75\xa6\x2d\xee\xec\xfe\x7c\xab\xa7\x1b\x68\xaa\x54\x42\x19\x42\x1b\xf6\xfd\x99\x97\xaf\xba\x3a\x2c\x9b\x84\x4b\xe6\x3e\x48\x15\x66\xf4\x96\xba\x67\x78\xf2\x1a\xb2\xc3\x9d\xeb\x40\x52\xa6\x69\xb3\xf3\xa9\x82\x54\x27\x4e\x62\x62\x60\xd7\x69\x3a\x7f\xe2\x7b\x45\xbd\xf6\x84\x3f\x84\x62\x89\x70\x07\x52\x0d\x29\xb3\xcd\x7b\x1f\x3f\x5e\x9e\x46\xc8\xea\xfe\xe2\xca\x72\x52\xef\x6d\xd8\x6e\xe5\x27\xe6\x02\xa3\x90\x62\x6c\xe5\xc8\xf2\xe6\x96\x94\x4f\x7b\xbf\x34\xc5\x54\x81\x1c\xe4\xb0\xab\x0f\xcf\x5a\x3f\xbd\x11\xd4\xcc\x0c\xbd\x54\x5f\xa5\x81\x53\x34\x4a\xeb\x89\x10\xc1\x88\x2a\x1f\x52\x23\x43\x6d\x26\x35\xbe\xf1\x5a\xcd\x02\x26\x3c\x90\x91\xaa\x91\x97\x45\xba\x2c\x10\x11\x79\x0e\xbd\xd3\x08\x9a\xbc\xe8\xaf\xc0\x2e\x59\xa0\xd3\x2c\xf5\x3e\xb1\x6d\x09\xee\x7f\x0e\x03\x52\x57\x2b\x80\x90\x27\xd7\x79\x43\xd7\xdc\x1f\x8f\xca\x0f\x09\xc3\x8c\xe4\x3f\x5e\x2b\xa2\x60\x24\x97\xd7\x1f\xe2\xcc\xc9\x43\xfc\x22\x24\xf3\x75\x9d\xf7\x40\xb6\x2c\x4c\xac\xcc\x6d\x01\x4d\xcb\x83\x63\x71\x6a\x48\xf3\xbf\xec\x7f\x3b\xcc\x8c\x8d\xc6\x8d\xc9\x8b\x1c\x5a\x1c\x4a\xe8\x19\x4b\x2d\x60\xe1\x5f\x50\xbe\xde\x43\xf5\x5f\x6f\x27\x28\x5f\xff\x75\x82\xbf\xb1\xa1\x64\x4c\x5a\xa5\x20\x99\x97\xfa\xd4\x60\xdd\x56\xc7\x2f\x5e\x0c\x53\x19\x61\x1a\x6d\xf4\x6e\xd3\xbe\xd3\x56\x89\xe9\x9b\x67\x86\x53\x04\x8d\xed\x5b\x53\x29\x85\x75\x9c\xf9\x1b\x8e\x32\x49\x00\x85\x8d\x9e\x75\x74\x43\x16\x29\x41\x46\x92\x4a\xb4\x43\xff\x3c\x64\x91\x4e\x22\xdd\xc7\xf0\x37\x35\x22\x39\xda\x33\x10\x5c\x16\xa7\x9c\x33\xc7\x49\xa6\xeb\x35\x94\x6b\x28\x8a\x2d\xd6\x1f\x5f\x6c\xc3\x59\xac\x2c\x1b\xe2\x7d\x25\xf3\x02\x57\x47\x5f\x7d\xcd\x38\xb7\xbc\x1b\x7d\x6c\x75\x5b\x9a\xea\x82\x77\x7f\xf6\xd0\x49\x12\x12\x20\xb1\x57\xdf\xf3\xe5\x84\x59\x98\x92\xa5\x91\x49\x02\x2f\x42\x61\x49\x3b\x16\x6c\xe1\xd4\x26\x66\x69\x9c\xca\xc8\x0b\xfe\x4c\x74\x3e\x17\xf6\x9b\x2c\x8d\x85\xe7\xb3\xfe\x06\x07\xb4\x1c\x33\xd3\x00\x32\x4b\x51\x92\x98\x3f\xe9\xbc\x35\xe8\x54\x7f\x66\xb7\x6a\xb4\xa7\x79\xe8\x02\x33\xac\xd7\x79\x9b\xcf\xa3\x80\x2c\xe3\xb1\x45\x5e\xf9\xd6\xf8\x79\x3f\x3b\x64\x99\xe6\x44\x99\xb7\xef\xaf\xe4\x7a\xe3\xa7\xef\x10\xc2\x98\xc2\xee\x0d\xf1\x5a\x0e\x9b\x47\x06\x59\x42\x48\x75\x62\x09\xba\xcb\x09\xdd\x66\xef\xc1\x8b\xec\x4c\x6f\x09\x74\x64\x19\x4d\x6a\x20\x36\xc7\xa2\xa8\x3e\x69\xe9\x8d\xf1\x36\x83\xa9\xce\xc0\x24\x9c\xf7\x86\xd7\xa5\x4e\x0b\xd4\xaf\xf8\x45\xdc\x9a\xc9\x34\xa4\xd9\x46\x57\x7d\x34\x77\xb9\x99\x38\x13\x99\x14\x29\x95\xa9\x48\x7b\xdd\x82\x71\x7e\x87\x69\xce\xa4\xb4\xfc\xd9\x77\xb7\xcf\xab\x7f\xce\x5e\x8b\x0a\x94\xd0\x7d\xf7\x22\x55\x22\x07\xc0\x43\x3d\xc1\xab\x66\x2a\x11\x99\xd3\x19\xfe\xd6\x3d\xfc\x54\x1f\xda\x0f\xd2\x48\x78\xb6\xab\x59\x1f\x22\x64\x3a\x88\xb9\x45\xa8\xc8\xd3\x85\x72\xe8\xec\x96\xd1\x58\x5e\x88\x57\x6c\x37\x1f\x50\x9c\x06\xe8\x8c\x77\x14\x32\x23\x39\xd5\x21\x2d\x55\xeb\x1b\x34\xc8\xa6\x3f\x28\x82\x18\x71\x10\x3c\x18\x7a\x1f\x26\x37\x2c\x82\x94\x21\x78\xfa\x66\x1c\xbb\x2c\x22\x48\x65\xea\x39\x25\x6e\x20\x2f\x08\x68\x84\xd6\x03\xaf\xb1\x6c\x9b\x2d\x1c\x48\x31\xd8\x13\x03\x81\x08\x34\xf7\x81\x82\x0f\xb4\x9b\xab\x33\xc1\x7a\x67\x37\x67\x02\xea\xa0\x3c\x54\x3a\x37\x8e\xc3\xee\x8b\xf0\x6a\xc6\xce\x38\x7a\x09\x22\x8c\x02\xf0\xd2\xfe\x16\xe3\xb2\xdc\x95\x31\x7d\xbd\x22\xd4\x59\xea\xba\xb9\xdb\x9b\xaa\xfe\x59\xd5\xef\x97\xed\x2b\x6e\x2c\x63\x48\xb8\x86\x3f\xa1\x3e\xc0\xec\x21\x98\x76\xf2\x05\xa4\xa8\x7d\xee\xb9\x69\xdd\xe1\x28\x4c\xa4\x2b\x15\x6f\x7e\x5d\x34\x22\xfb\x41\x51\x0c\x81\x27\xee\xa8\x0e\xb2\x73\x2d\xaa\x7a\xb8\x86\xc8\x70\x00\xb3\x74\x7b\xb1\x85\x21\x43\xde\x93\xab\x81\x88\xb4\x9d\x99\xcd\x27\x1c\x47\x68\x48\x11\x87\xd6\xed\x2e\xf1\x73\x07\x47\x5f\xf4\xeb\xdc\x9e\x75\x75\x38\xc2\x8c\xad\x19\x44\x1c\x87\x96\x65\xe2\xfe\x9f\xdf\x8a\x4a\x7a\x05\xfb\xdf\x07\x2b\xa3\xe8\x57\xf0\x48\x52\xfb\xd5\x9f\x50\x12\x71\x46\x6f\x66\x04\x97\x8c\xda\x9f\x1a\x38\x3f\x54\xfd\x1f\x75\x42\x6d\xaf\x05\x9a\x96\x5c\x4b\x72\xe1\x9f\xa1\xc5\x47\x73\xeb\xd8\xac\x87\xb1\x46\x64\x43\xe7\x25\x85\x11\x36\xd2\xb8\xea\xfb\x32\x2e\x2c\xc0\xd4\xb2\x88\x24\x05\x4a\xff\x11\x5f\xce\x25\xcf\xc2\x57\xe9\x86\xc9\x0e\x20\xd2\x04\x90\xf7\x30\x1e\xfa\x5d\x16\x84\x7e\x1b\x16\x19\xb3\x4d\xc9\xd6\x64\xbf\x94\x4d\xaf\xc6\x0c\x42\x24\xa0\x60\xbc\xfb\xdd\x5d\xe8\x6c\x80\x10\x3a\xa4\x39\xfd\xbc\xda\x6d\xf6\xd7\xab\x7f\xed\x7d\xaf\x83\x80\x20\x21\x61\xbc\xed\x6e\xf5\xbc\xeb\xff\x18\xeb\xc4\x51\x6d\x3a\xbb\xfd\xa3\x22\x1e\x89\x2b\x28\x0a\x47\x80\x37\x2f\xb4\x0a\xc8\x64\x94\x0e\xd4\xdd\xb9\x74\x49\xa2\x71\xda\x57\x80\x08\xa9\x6d\x67\xbb\xba\x1b\x7e\x4d\xa0\xad\x9d\xd9\x34\xdc\x44\x1e\x03\x04\xa8\x28\x25\x6f\xec\x54\xfc\xb1\x50\x79\x13\x52\x66\x94\x36\x5b\x3f\x3e\xec\x9e\x6f\xaf\x5e\x76\xb7\x8f\x0f\xfb\xfb\x3e\xc5\x2f\xa4\x49\x79\xda\xbf\x9f\xd6\x54\xf5\x94\x69\x01\x84\x8a\x13\x4f\x10\x7b\x7f\x26\xe8\x44\xbf\x52\x74\x60\x59\x1b\x06\x72\x9f\xd1\xb3\xe8\x38\x48\xc1\xf6\xde\xb8\xb7\x74\x75\x26\xae\xfa\x89\x2f\x20\x74\xac\x02\xdb\x39\xf0\x71\xc2\xe2\xa3\xf3\x5c\x08\x4b\x35\x1d\x85\x81\x20\x7e\xd4\x7f\xfe\xe3\xc6\x5f\x1f\x05\x50\x96\xb1\x5b\xbe\xf5\x79\x8b\x50\xab\xb7\x9b\xaa\x5e\xbf\x41\x51\x60\xb9\x50\xd2\x9d\x9a\xa7\x9e\x65\xca\x5f\x0e\x62\xca\x21\x7b\x45\xb8\x75\xd5\xb4\x37\x39\xcc\xb6\x14\x08\xc2\x2c\xb4\x1d\x14\xad\x7a\x5b\x53\x53\x8e\x15\x93\xed\x6b\xba\xfc\x7f\x46\xad\x88\xc9\xff\x5c\xf4\x25\x02\x04\x32\x0b\x12\xe7\x9a\x5f\x84\x12\xc0\x22\x70\x3c\x92\xa8\x72\x28\xae\x6b\xf8\xcc\xcb\xd7\xe7\xfc\xf5\xcd\xbf\x5a\x60\xb1\x51\x96\x15\xf9\xf5\xad\x1d\x43\x65\x80\x65\x29\x6d\xe4\x45\xde\xb4\x17\xb9\x39\x3f\x46\x04\x94\x7b\xb9\x5e\x3d\x6c\x17\x7b\x84\xbf\x6c\xd8\xfd\x2b\xfc\xed\xa2\x39\x07\x86\xdc\x47\x22\x26\xaf\x0f\xcf\xa8\x70\x8c\xc5\x04\x86\x1a\x4c\xbf\x7c\xaf\xa1\x85\xa7\xba\xfa\xc8\x07\x95\x1d\x00\x66\x4c\xe0\x60\x51\x7b\x0a\x28\xde\xa0\x79\x9b\x3d\x56\x14\x58\xf5\x81\xff\xb5\x09\xf7\xf1\x5c\x84\x28\xb5\x6a\x3c\xd7\xf9\x6b\xfe\x74\x2a\x7a\x13\x07\x91\xb1\x8c\xdb\x4e\xb5\x66\x46\xaf\xda\x1d\x57\xf1\x84\x14\x62\x7f\xec\x4c\x7a\x6d\x63\xd7\xbd\xe5\x53\xfb\x7d\x39\x16\xe2\x40\x91\xdf\xe9\xb6\x3e\x67\x42\x69\x6e\x2d\xbf\xb0\x38\x40\x2f\x31\x46\xd0\x92\xb1\x2d\x84\x38\x4c\xa8\x32\xb4\xae\xea\x06\xea\xfc\x74\x58\x8f\x34\x8c\x17\x26\x5b\x9c\x48\x8a\x4c\xf7\x9e\xb2\xad\xbb\xda\xd7\x40\xa0\xf9\xad\xa4\x89\xb0\x6c\x59\xf2\x90\xb7\x56\xe9\x7b\xb2\x32\x81\xa3\xe4\x96\x3c\xf9\xba\x39\x7a\xf0\xeb\x1c\xe2\x09\x49\xa8\x4d\x2f\xf4\xe3\xdd\x94\xf5\x40\x0d\x3b\x1f\x0e\x92\xaa\x6c\xc4\xa1\x72\x75\x9e\x20\x18\x20\x0d\x80\x12\x6a\x77\x57\xdd\x6e\xf7\x8f\xdf\x65\x35\x21\x15\x5a\xbb\x5e\x8c\x47\x9d\x53\x17\x21\xeb\xaf\xa3\x43\x2a\xfc\xde\xbf\xdc\xed\x6e\xb7\xb7\xdf\x06\x41\x54\x80\x2c\xe2\x49\xe6\xb4\x03\xc9\x4b\x28\x4e\x77\x95\x82\xe2\x01\xdb\xcf\xaa\x7e\xef\xbb\x30\xe6\x00\x4b\x7f\x3a\x67\x94\xfa\x78\x1d\x91\x4e\x4d\xf7\x03\x10\x41\x44\xfa\x36\x79\xb3\x7b\xc3\x1a\x49\xe6\x61\xd5\xae\xab\xaa\xd6\x9d\x3f\xe2\x40\x31\x33\x73\x0e\x82\x41\x30\xb8\xf6\x0d\x05\x1f\x72\x62\xaf\x41\x44\x92\x18\x7b\xc9\xbb\xbc\x35\x37\x94\x76\x9c\xdd\x9f\x80\x0c\xfa\x14\x9c\xac\xda\x86\x26\x91\x3f\xa8\x21\x24\xbf\xa1\x2a\xc6\xdc\x91\x00\x02\x79\x14\xf6\x04\x9c\xb6\xed\xbc\x3a\x8d\xec\x12\x61\xe6\x5c\xf3\x49\xde\x58\x6e\x88\xe6\x8f\x45\xd7\x72\x21\xd0\x83\x2e\xce\x20\xf6\x47\xd5\x9e\xa0\xf8\x56\xb5\x8b\x73\x03\x14\xa7\xa2\xe5\x5d\xf5\xfa\xb3\x8b\x18\x76\x35\x5e\x40\x12\x66\xb3\x40\xa6\x56\x5e\x33\x6f\xb6\x27\x8a\x20\xae\xab\xd2\xc9\x36\xf8\x11\x99\xd0\xae\x88\x73\x47\x3c\x74\xdb\xb6\x3e\xa9\x76\x46\xd2\xb1\x7c\x75\xc5\x42\xea\x24\xbf\x7f\xb8\x1b\x8b\x4f\x75\x07\x52\xaf\x7c\xeb\xd1\xe0\x8b\x75\x5c\x50\x71\x14\x26\x3d\x23\x8e\xe5\xdc\xbb\x5f\x56\x47\xed\x1e\xdf\xb2\x9c\xda\xf5\xec\x60\x81\xd5\xaf\xf3\xec\x9a\x3a\xc8\xd8\x80\x1a\x1a\x08\xd5\x6e\xcb\x2b\xdf\x91\xba\x0c\x95\x05\x1d\xf2\xa8\x67\x7d\x6d\xd5\x9b\xcb\x3a\x4c\xef\x42\x27\xca\x0b\x6b\xdd\x96\xa6\x22\x69\xb6\xc9\xc7\xd4\x52\x91\x93\xdd\x39\xc2\xb9\x7a\xc7\xfa\x3f\x4f\x58\x9f\x67\xbc\xef\x6e\x2c\x86\x96\xf9\xca\xea\x43\xd6\xd8\xbc\x75\x1f\x61\xf9\x5d\xe1\x00\x0f\xea\xc2\xc6\x07\x47\x5f\x31\xf6\x89\x01\x51\x49\x57\x14\xbc\x60\xbf\x01\x40\x83\x5c\x7a\xe3\x72\x5b\xfa\x9c\x17\x18\x66\x3b\x38\x3c\x8a\xe7\xb1\x5b\x1c\xc4\x82\xf3\x9b\xf4\x10\x98\xd8\x71\xd5\x6f\xb6\x9b\xe7\x1f\x9b\xed\xfe\xfb\xe3\xdd\xf5\xe6\xd9\x5d\x54\x86\x5a\xd8\xc6\x97\xa2\x6a\xd0\x15\xd9\xc7\xa0\x57\xc9\x38\x27\x12\xf3\x6f\xcf\x2f\xe3\xc9\x23\x99\x53\xd1\xea\x9c\x04\xc8\xcb\xe6\xb1\x2c\xce\xab\xe2\xf8\x06\x0f\xa7\x03\xd6\xb9\x9a\x28\x4c\x74\xc3\x6d\xbe\xc8\x21\x9c\x2c\xca\xc5\x1d\x8b\xc3\x90\x1a\xd1\x5b\x78\xef\x99\x86\x67\xc9\x0a\x19\x87\xcc\x43\x01\xac\x1c\x70\x51\xc0\x3e\x08\xc2\x7d\x10\xb0\xe9\x2f\xc5\xcc\xf6\x11\x52\x6b\xb9\x72\x18\xb0\xe7\x53\xd1\x3b\x21\x32\xc6\x48\xba\xdd\xfa\x91\x02\xdc\xaf\x5f\x9f\xe4\xb1\x49\x9c\x8e\xf0\xe6\x97\x2a\x4e\x7a\x5e\x2e\x90\x3c\x0d\x63\xe5\x17\x07\xc2\xc1\xa6\xc5\x7f\x7b\xcd\x0c\xa9\x0e\x71\xa4\x6d\xe3\x76\xf7\x68\x75\x4c\x3c\x78\xd6\xdf\x26\x97\x49\x4c\x53\xf8\x48\x66\x74\x9a\x51\x92\x1c\x19\xf8\x1a\xd0\xee\x3b\xf1\xb7\x53\x4a\xc0\x82\xfc\x2c\xba\x69\xb6\xcb\xc9\x44\x87\xe4\xa6\x58\x2e\xc6\x7e\x77\xbb\x3a\x5f\x2a\x4c\x83\x4c\x8c\x90\x76\x22\x97\x58\x53\x26\xf2\xa3\x7a\x47\xaa\x69\xdd\x54\xb5\x2b\x6b\xe5\x55\xb9\x55\x6f\x78\x80\xef\x23\x87\x67\xf6\xb8\xa9\x64\xd1\x48\x9c\xbb\x18\x85\x70\x32\x4b\x10\x3c\x95\xf7\x12\x06\x5d\x66\xd2\x52\x15\xaa\x02\xa1\x5e\x15\x85\x2b\x5a\xf6\xaf\x21\x33\x18\x07\xde\x41\x02\x39\xeb\x75\x94\x82\x01\xf3\x74\x31\x04\x1a\xde\x1f\x0b\x28\xe7\x9a\xbf\x20\x45\x6c\x77\xbb\xd5\xf1\x68\x13\x3d\x7a\x5e\x62\xfa\x1a\x2a\x27\x05\xd7\x56\xe7\xed\x15\xdb\x1b\xc4\x55\xa9\x1f\x3c\x53\xeb\xfc\x67\x84\xe5\xb9\x5d\x3f\x55\x45\x51\xf5\x37\xa9\x02\x02\xae\x90\x16\xfe\x36\x7f\x2d\x2d\x8c\xcd\x1f\x35\x2a\x89\x7e\x93\x72\xb1\xff\xfd\x50\xb5\xb7\xe5\xcb\xf0\x62\x21\xce\x42\xcb\x1f\xac\x72\xf4\x8c\x53\xee\x98\x0c\x42\xca\x70\x61\x09\xaa\xdd\xdb\xbe\x26\xfa\x94\xfb\x62\x21\xe3\x3a\xfb\x9a\x32\xc2\x40\x0e\x24\x4c\x8e\xe6\x71\xe9\xd3\x49\x99\x52\x2a\xbd\xf5\x30\x82\x31\x9d\x30\x48\xa5\x82\x58\xf9\x2d\xed\xb5\x79\x38\x1d\x86\x23\x3c\xb2\xf4\x5c\x8e\xef\x63\x36\x8d\x35\xb3\x19\x7e\xf0\xa5\x8a\x3b\xa8\x71\xa0\x97\x9f\x0d\x4e\x03\x9b\x1a\x24\x86\xcd\x09\xd0\x49\x6a\x2d\xe9\x16\xba\xb7\x63\x55\xe3\x2f\x1e\x7e\xf4\x99\x51\x44\xe4\x6b\x6e\x26\x92\xb8\x7f\x91\x30\x70\xe7\x1a\x26\xa9\x53\x73\xd3\x74\x6e\xcf\xfd\x99\x1c\x9b\x4d\xd9\xe6\xed\xf9\xfa\xca\xdf\x8e\xe1\x68\x43\x70\x5a\xbc\x37\xf5\xbc\xdb\x51\x05\x2c\xa1\x58\x54\x9e\xce\x1b\xa8\x8b\xf3\x32\x9d\x14\xa8\x20\x52\xba\x5f\x71\x7e\x17\x9d\x86\xcd\x2a\x90\x01\xad\x8c\xab\xdc\xd4\x38\xc9\xa6\xaa\x40\x32\xea\xf5\xf1\x8d\x15\xbf\x6b\x64\x53\x21\x4b\xa9\x02\xb9\x45\x55\x95\x3e\x4f\x3c\xfb\xad\x90\x5b\xde\xf7\x53\xf9\x04\xa7\x66\x8e\xd4\x51\x61\x66\xc8\xaf\x7a\x83\xce\xbd\xb8\xca\xdb\x03\x1c\xc7\x0c\x44\xa0\x42\x64\xe8\x33\x62\x57\x79\xdb\xac\x4a\xed\x3c\xa5\xfe\x1a\x28\x4c\x0f\x8e\x21\xa6\x34\xa2\x49\x5b\x34\xc0\x8a\x85\xc0\xd8\xb4\x8c\x39\x2e\x87\xa9\x28\x65\x34\x01\x41\x6b\xcb\x07\x4a\xb4\x1b\xbf\xa3\x38\x03\xc5\x83\x84\x6e\xb1\x36\xfe\x2a\x9c\xa3\x76\x34\x8a\xd7\x65\x73\x5d\x1d\xa8\x79\xed\x6b\xff\x52\x25\x81\xa5\x58\xce\xcb\xff\x45\x35\x0d\xbe\x42\xe6\xdf\x77\xc2\x6c\xd6\xfe\xae\xaa\xde\x9f\xf1\xe3\x37\xfb\x8c\x4a\xb9\xe5\x10\x77\x59\xfb\xc5\xcc\x9d\x1f\x2a\x12\x1e\x8e\x60\xad\x5f\x24\xce\x55\x2a\xa5\x30\x7e\x07\x99\xe6\x36\x55\xaa\x98\x4d\xd2\xef\xd6\x61\xf0\x5e\x95\x3c\xf6\x47\x44\x9a\xc4\xa9\xd3\xf6\xc6\x2d\x18\x7c\xa8\xfb\x43\x5a\xda\x76\x81\xc7\xbb\xcd\x7e\xfd\xf8\xe8\xff\x2e\x91\x11\x84\xdd\xf2\x8a\x5c\x76\x30\x28\xc5\x52\x4a\x2b\x7f\x90\xa0\xe3\x17\xb7\xab\x98\x22\xcf\xe2\xe8\x05\xf6\xfe\x3f\x0a\xa1\x81\x52\x3c\x73\x14\x3d\xea\xfd\x1e\xca\x53\x33\xe2\xbc\x02\xa5\x94\x60\xb6\xe9\xe1\xb5\x8b\xc2\xab\xfa\xd6\xa8\xd9\x9a\xd4\x0c\xc8\xf4\x1f\x68\x55\x5d\x9d\xf4\x2b\x7e\x11\x5f\x2b\xcd\x90\x2a\x80\xf8\x0b\xd5\xa9\x9d\xa6\xad\x94\x4e\x03\x0b\xc5\x80\xa2\xd8\x56\x87\xce\xb2\x13\x92\xf0\x47\x0e\xb7\x65\xd9\xcb\xaf\x83\xd2\x99\xb6\x5c\x11\x55\xa1\x3d\xf7\xb7\x3b\x84\xb1\xa2\xc5\x32\xd1\xa4\x3c\x4d\x35\x99\xa6\x77\x8f\xc6\xca\x08\x8f\x9c\xfa\x66\x31\x8f\xa8\x4c\x64\x12\x0b\x4f\xea\xec\x81\x8d\x8c\x1f\x4d\x4f\x13\x07\xca\x70\x43\x19\xd7\x3d\x68\x7d\x05\x0d\xc5\x39\x53\xbc\x41\xf6\xdf\xd9\xff\xf8\xc1\x5a\x4b\x17\xbd\x5b\x60\xca\x92\xb0\x04\xe8\x40\xc4\x94\x25\xec\xec\x43\x34\xca\x74\xf5\xd9\x06\x3e\xeb\x5e\x98\x3a\xf8\x3a\x4c\x82\xc8\x76\x80\x5e\x15\xa0\xde\xff\x17\x7a\x9c\x93\x0e\x05\x12\xe4\x4b\x55\xc7\x33\xd5\xb6\x5e\xca\xbc\xfd\x4b\x9d\xd2\xe9\x17\xd5\xa1\x09\xa8\xdb\x88\x00\x70\xe3\x21\x73\x34\x8e\x66\x3a\x71\x4c\xfa\x07\xe2\x90\x07\xf5\xfe\x75\x0b\xbd\x8e\x75\xe2\x75\x50\x57\x45\xbb\x88\xdd\xd1\x3c\xb1\xa5\xf2\x6e\xde\x7d\x76\xab\xe9\x4a\x55\xa7\xe3\x02\x3d\x8f\x1b\x9f\x08\x1e\x0c\x3a\xa7\x94\xe7\xea\xb6\xf8\xef\x96\x9e\x6b\xd9\x7e\xe8\x44\x46\xa3\x76\xde\xf5\xcb\x76\x03\x8b\x1f\x2a\xe5\x21\x7d\x4f\xd7\xdc\x82\x58\x3f\xe3\x47\x8e\x9f\x17\x8c\xa2\xa3\x9e\x56\x9d\xa6\x2c\x51\xde\xe8\x78\x4e\x7f\xdf\x0b\x3b\x83\x30\xea\x54\xc7\xc4\xdd\x69\xdd\x24\xdb\xd6\x39\xda\xaf\x74\x16\xc7\x14\xcb\x62\x91\xbf\xe6\xb2\x40\x9b\x9e\x9c\xde\x65\x16\x73\xc2\xf1\x5a\xcc\xa7\xc3\x3f\xf7\x4d\x16\xd3\xa9\x93\xc5\xca\xcb\x39\x3c\x9c\x88\xad\xc8\x1b\x44\x2d\x12\xdb\xa6\xe8\x12\x20\xfb\xcf\xbc\x9e\x90\x27\x69\x90\x40\xc9\xef\x23\xa8\xf7\x1d\x3d\xc4\xf4\xad\x02\x0a\xe9\x8a\x13\xab\xfa\xf5\x64\x79\x6b\x9c\x07\xfc\x92\x97\xed\x1f\x4b\x19\xe4\x8b\x29\x25\x99\x25\xcd\x70\xad\xe9\xcf\xf9\xeb\x66\xf7\xdd\xbe\x93\xf9\x48\xe1\xd1\x3b\x87\xbc\xbc\xea\xdc\xa1\xd9\x71\x00\xdf\xae\xb5\x9e\xa8\xcb\x82\x96\xd2\x10\xef\xd8\xf3\xd5\x6a\xdd\xf9\xa6\xe3\x16\x16\xad\x04\xf0\xbe\x3c\x3b\x0b\x4d\x66\xb3\x4f\x41\x48\x2b\xf1\x3d\x2f\x8a\x3d\x94\x7a\xef\x71\x49\xb3\x4f\xa4\x4c\x24\x42\x17\x75\xdd\x43\xee\xbe\x4a\x38\x76\xd8\xb4\x32\x92\x78\xb3\x7a\x7a\xd3\xb2\xfa\x34\x05\xbc\xe3\xbc\x69\x75\xfa\x94\x1a\x91\xe8\x89\xbb\x75\xe7\x5a\x1e\xa9\xa4\xd9\x8c\xd8\xcc\x16\xad\xa4\xc6\x50\x71\x47\xbe\x76\xac\x1a\x7c\xc6\xa3\x27\xa1\x74\x94\x58\x7f\x2c\x25\x01\x35\x86\x68\x39\x1c\xbb\xf9\xf1\xf7\x70\xfe\x1a\x13\xcb\xf6\xeb\x7e\x6a\x09\xe6\xaf\x31\x4d\xa9\xaf\x94\x7c\x98\x4b\xcc\xe9\x5f\x65\xd5\xa7\xf3\x1c\x95\x25\xf5\xfd\xfe\x67\x98\x64\x23\x7e\x00\x6d\x22\x4d\xe5\x48\xed\x44\x0b\x6f\xaa\xfa\x6a\x39\xfc\xd1\xc6\xd5\x98\x76\x9f\xd5\x0d\xd5\x47\x57\xa7\xf6\x6d\x29\x76\xd0\x06\x78\xda\x1b\xb6\xa2\xea\x1b\xc5\x7b\xbc\xc7\xfc\xca\xa8\x1d\xed\x5f\xb9\x69\xdf\x9a\xe7\x4b\x29\x6f\x3b\x10\x83\xd4\x2e\x7f\xea\xc6\xfa\x01\x45\x6e\x83\xbd\xd9\x20\xc5\x23\x07\x10\xdf\x42\x81\x13\xd5\x58\x37\x24\x0c\x33\xe3\xfa\x80\x48\xd2\x6c\x20\x6f\x19\x11\x8c\x2e\x25\x93\x30\xcc\xb2\x2c\xf0\x08\x5c\x85\xf9\xf1\x0b\x37\x00\xc3\x0c\x94\x7b\x07\x6e\xe9\x5e\xf0\x9f\x60\xa8\x42\x12\x74\xd2\x84\xe5\xef\x16\xde\x10\x3f\xfe\xf6\xbb\xce\xfe\xdf\xb0\x6a\x30\x54\x8a\xba\x87\x0e\xdd\xd4\xdf\x9e\xe4\xcf\xd9\x02\xf4\x99\x7b\x64\x69\x48\x9b\x5a\x37\xe0\xa1\xf2\x06\x6a\x5d\x95\x0d\xe5\x26\x7b\x3c\x17\x32\xad\x29\x55\xf4\xcf\xab\xef\x9e\x91\x01\xa3\x34\xf3\x75\x3d\x87\x8a\x7c\x34\x5b\x6c\x9a\x05\xa8\xf6\xb0\xdc\xfa\x73\x2d\x47\xd7\x27\xe6\xcd\x77\xa8\xf5\x40\xe5\x80\x91\x0a\x12\x9f\xa9\xf4\x06\xbb\xf8\x62\xd3\xc2\x48\x31\xaa\x4d\x7e\x62\x3e\x76\xff\x31\x36\x71\xd2\x6b\xca\xfd\x89\x67\x6f\xd0\x91\x63\x42\x49\xa8\xa3\xed\xea\x6a\x2e\xa0\x37\xc8\x8d\x20\x9f\xdf\xa6\xb2\x2e\x31\x64\x98\x84\x69\xe8\xe6\xcd\xed\xfa\xf1\x27\xe2\x7b\x74\xa9\x0e\x01\x98\x28\x46\x5e\xc7\xff\x9d\xf0\x84\x03\x5d\x38\x60\xa2\x13\x66\x55\x26\xcb\x13\x14\x8f\x1f\x58\xd7\xb9\xee\x8f\xa6\x41\xe6\x59\x65\xee\xcf\x56\xd1\x74\xce\xeb\xf2\xd5\xbf\xfe\x0a\x8c\x27\x36\x81\x0f\xfa\xb7\x10\x2c\x4c\x99\xf5\x2b\x48\x8f\xf8\xad\x2a\x2e\xd9\x88\x01\xd3\x4c\xa7\xd2\x7f\xe5\xb6\x9e\x81\x0b\x30\x0b\x62\xd2\xa9\x68\x47\x7c\x07\x16\xb0\xf4\xc5\x6f\x76\x2e\x6d\x36\x90\xd8\xd4\x2d\x9a\x39\x59\x2b\xa0\x88\x63\x4a\xc7\xbc\x12\x5e\xc1\x0a\x36\x8c\x30\x2c\x28\xd2\x10\x1d\x92\xe6\xe7\x98\xff\xd5\x9a\xac\x31\x89\x00\x0a\x81\x46\x39\xe6\x8f\xfb\xd5\x3f\xf7\xeb\xd5\x93\x3f\x04\x41\xec\x99\x10\xee\x9b\xd7\x6e\x2b\x5c\x99\x5e\x12\x12\x10\x22\x60\x8e\xfa\x79\x44\xfb\x3c\x6f\xd4\x74\x83\x65\x90\x86\x99\x77\x70\x7a\xcb\x8a\xd2\x71\x8c\x5a\x37\xe4\x5b\x5d\x9d\xbe\xc0\x0c\xa2\x14\x21\xe0\xa0\xa0\x33\x89\x18\x51\x2a\x30\x41\x8f\x24\xfd\xe2\xcd\xaa\x50\xa1\x1e\x18\xb8\x5d\xc8\x48\x8c\xd7\x34\x3d\x7f\x9b\x14\x42\xc5\x38\x95\x29\xff\xeb\x5f\xdf\xc7\x99\x04\x54\xda\x2e\x98\xa1\x70\x40\x2f\xe9\xea\x74\xfe\x8b\x0b\xea\x4c\xfa\x14\xad\x87\x30\xd8\x62\xcd\x74\xb6\x62\x28\x08\xac\xe8\x8b\x08\xa7\x6e\x92\x4d\x84\x04\x66\xd7\x45\xad\xe9\x83\xbe\xc8\x02\x9a\x81\x9f\x74\x29\x1c\x47\x93\x5a\xd2\x5f\xe2\x4b\x3c\x0f\x3c\x70\xf6\xb0\x09\x02\xe3\xa4\xb1\x3b\x4f\x7d\x55\x14\xdb\x93\x7c\x69\x86\xa2\xb0\x09\x22\x9e\x25\xe3\xda\x6c\x17\xed\x7c\xc3\xcb\xd2\x66\xcf\xb5\x3d\xba\x38\x07\xaa\x49\xbf\x55\xba\xd8\xe7\xdd\xac\x19\x0a\x04\x26\x0c\x2d\x34\x98\x08\xca\x0f\x79\xdb\x7e\x85\x9b\x33\x21\xe3\x89\x99\x80\xbb\x1d\x9f\xe0\x74\x58\x14\x04\xbc\x07\xa8\xec\x73\x2b\xcf\xea\x8f\x65\x11\xf9\x6e\xf2\x74\xde\x9b\xea\xe2\x4c\x88\x75\xec\x7a\x1a\xaf\xf3\x8f\xe7\xa1\x64\x65\x22\xcd\x12\x0b\xd1\x54\xef\xd8\x36\xfb\x6d\x55\xe8\x45\xff\xc7\x44\x68\xc2\x68\x90\xb8\x78\xa8\x7a\x83\x66\xe2\x38\xa6\x28\xff\xe6\x54\xce\x19\xf6\x96\x33\x6d\x26\x16\x49\x30\x6a\x9f\xa7\x6c\xef\x57\xe5\xb7\xbf\x17\xbd\x99\x18\x15\xdd\x84\x95\x64\xa2\xea\x48\xd4\xdf\xa0\x49\x2c\xb9\x37\x96\xa4\x86\x84\x4d\x7b\x6b\x1e\x10\x35\xea\x6d\x0b\x05\x1e\x46\x6f\x84\x47\x02\x07\x66\x98\x6f\xd0\x5c\x4a\x5e\x80\xe1\x46\x92\x0f\xfe\x54\xe3\xad\xaa\x3c\x59\x5b\x3f\xa9\x12\xce\x4c\xcf\xe2\xb6\x7b\xab\xb1\xe9\x4c\xef\xc0\xf5\x64\x12\x23\x08\x50\xd4\x2d\xdf\xbc\x19\xf5\xd1\x9a\xc4\xe8\xc8\x6d\x0e\x34\xa3\xda\xcb\xbe\x7a\x93\x46\x8a\xd8\x46\xba\x8b\xe6\xe5\x6b\xf3\x68\xf6\x57\x2f\x77\x77\xf3\x51\x02\xc9\x17\xb4\x53\xff\x1a\xa1\x98\x06\x47\xbe\x1c\x6c\xb2\x2c\x10\x23\x6e\xfc\x65\x72\x4e\x93\xa9\x84\xd2\x71\xfb\xed\xcb\xb4\xee\xe7\x8e\x0b\x19\x51\x0d\xe6\x58\x79\x45\x71\x7f\x40\x71\x42\x01\x3b\xc2\x4a\x9b\xc9\x7b\xba\x60\x2a\x33\x42\x07\xa9\x13\x45\x9b\x30\xd4\x2e\x5b\xd3\x6e\xb8\xe7\xdb\x25\x64\xf9\x8a\x20\xd8\x34\x8d\x1f\x4e\x33\xb6\x5a\x03\x81\xa0\xf9\x46\x92\x68\xa7\x2f\xcc\xab\x01\x61\x41\xa5\xd4\x45\x8c\xb5\xaf\x31\x4c\x07\xc9\x0c\x89\xc1\xcd\xc2\xc8\x26\xa9\x6a\xa3\xc2\x5e\x06\x7b\xc8\x74\x4f\x4f\x57\xa9\x21\x7b\xf5\x6f\xac\xab\xbd\x41\xb4\xed\xfe\xa0\x96\x9e\xf4\x8b\x99\xae\x10\xc8\x5e\x68\x68\x61\x5b\x9d\x6a\xd5\xd9\xab\x7f\x61\xe7\x81\x8f\xa4\xed\xc1\x68\x16\xc7\xae\x90\xbe\x3a\x48\x68\x1a\xd0\x17\x12\x10\x7e\x28\x58\xb2\xcc\x7d\xaf\xb2\x64\x51\x1a\xd3\x1f\xd6\x28\xfb\x26\x77\x2a\xe7\xfa\x8b\x8d\x2d\xb2\xc1\x24\xa6\x8a\xc2\x15\xd6\x79\xfb\x36\x6e\xe5\xf2\x03\xb4\x6d\xd6\xec\x8c\xbb\x13\x06\x1b\xd3\x56\x1a\x13\xdb\x04\x3a\xb9\x04\x24\x63\x58\xd5\x64\x6e\x7e\x6f\x00\x0c\x88\xc0\xdf\x1d\x61\x6b\x07\xca\x20\x19\x04\x31\x48\xe5\xc4\x4c\xea\x0f\xf4\xa4\x9d\xfe\x28\xd7\xfe\x4d\x59\xd3\xfb\x8c\x0d\x41\xc1\x16\x27\x8a\x0c\x82\xd4\x12\xb3\xbc\x12\x2f\x20\xd4\xe7\x11\x08\x6f\x69\xb6\xca\x20\x50\x99\xe9\x15\x96\xef\xf3\xb2\x1d\x3f\xb2\x0c\x02\x63\x01\x86\x64\x30\x02\x36\xfc\x59\x11\x06\x5b\x56\xd5\x7b\x4f\x73\xe8\x8e\x85\x11\x0b\x5c\xf8\xf3\x80\x9f\x03\xe3\xc4\x25\xf5\xf8\x78\x37\x96\x41\x98\x70\xef\x11\x0e\x2d\xb5\xf6\x33\x2e\x6d\x4f\x32\x08\xc1\x76\xf6\x9f\x4a\xf7\xf2\xc6\x59\x7f\x19\x84\x46\x5a\xde\xb5\x6e\x43\x72\x50\xe7\x45\x8c\x83\x0c\xe2\x48\x93\x89\xbe\xef\x49\xf0\x46\x7e\x9c\x0c\x78\x14\x67\xb1\xef\xc2\x25\x5b\x91\xff\xbb\xf3\xca\x9f\x88\xb9\xf4\xb6\x5c\xb5\x6d\x85\xed\xdb\xf4\x9c\x24\xb5\x18\x1f\xb7\xdc\xbe\xc1\x97\x92\x2d\x8b\xff\x2e\xe7\x1a\x65\xc0\x53\xc5\x71\x88\xdc\xf5\xed\xe1\x58\x10\xd3\xc4\x28\x90\x90\x01\x57\x36\x65\xf2\x8f\x09\x68\x56\x06\x49\x68\xa4\x23\xbc\x20\xaf\xf2\xcb\x44\x64\x6f\xf8\x65\x90\xf2\x94\xe4\x76\x3e\xaa\x16\x77\x95\xb5\x3d\x4f\x35\x96\x9e\xf9\x57\x06\x59\xa4\x28\xaa\x68\x4e\xb2\xf1\xca\x6a\x8b\x1e\x94\x0c\x32\x69\x39\xde\x9b\xb7\xea\xd3\xb3\x73\x8d\x16\xa9\x0c\x32\xdf\xec\xbb\xd7\xd8\x80\xc9\xa1\x6c\x5d\x7a\x22\x8c\xdd\x10\x11\x25\xa6\x57\x0e\xdf\xd3\xcc\x9c\x88\x79\xc8\x40\x80\x96\x0e\x03\xf1\xf1\xad\xf2\xae\x8f\x0c\x20\x66\x44\x91\x7b\x5a\x90\xee\xf2\x43\x92\xd8\x52\x13\x40\xab\xde\xe6\xf8\xa7\x31\x00\x6d\x76\x9e\x54\x76\xe3\x5d\x69\xfd\x54\x55\x85\x93\x01\x9c\x56\x81\xfd\x50\x34\xa4\x4d\xf6\xe1\xf2\x07\x37\xf9\x82\x98\xd2\x10\x58\x8f\xbf\x85\x0a\x32\xe9\xea\x54\xd7\x28\xf3\xf6\xa1\x2a\xd5\x14\x72\x2a\x03\x95\x31\xc2\x35\xbb\x5e\xd2\xe9\x7a\x56\x59\x46\x2e\x35\x15\xbc\x5f\xca\x1a\x3b\xcf\x72\xde\xed\x30\x7d\x32\x85\xa9\xe5\xaf\xab\x5a\x28\xbe\x57\x85\xee\x42\xd7\xc9\x45\x75\x62\xe8\xae\xca\xea\xb2\xc7\x4c\x06\x3a\xb5\xf5\xb9\x2e\x82\xd9\xad\xd7\xfd\x49\x92\x73\x17\xe2\xec\x23\x36\x66\xd9\xe9\x9f\x04\x83\xd0\xd8\xf6\xb6\x4d\x5d\x57\xe3\x44\xac\x0c\x03\x06\x08\xd3\x22\x5c\x1f\xc8\xcb\x30\x90\x8c\x98\xfd\x9e\x9e\x37\xfb\xed\xea\x6e\xb3\xbf\x7a\x7c\x78\xd9\x12\xd7\xee\x7a\xe3\x99\x17\x65\x18\x0a\x93\xb8\xc5\x64\x73\xb4\x33\xa9\x7f\x19\x86\xa8\x53\x27\x21\xa6\x4e\xe8\x05\x30\x7d\x5e\xef\xa9\x2a\x8a\x51\x5e\xcf\x9d\xc3\x32\x9e\x72\x0b\x69\x3e\x0e\xbd\x51\x32\x8c\x98\x6d\xea\xd3\xa8\x88\xfe\x61\x4e\x88\x26\xc3\x28\xb2\xc2\x00\x2d\x91\x42\xcf\x2a\x9d\x32\x8c\xb3\x8c\x5a\x87\xf7\x25\x7e\xce\xa8\xed\x7e\xeb\x83\xca\x90\x67\x91\xb1\x85\x90\xab\x6e\x5e\x7b\xff\xbc\x3b\xa0\x35\xf7\x81\x26\x3d\x9e\x05\x88\xcd\xd2\x35\x32\xe4\xa0\x32\x74\x91\xfd\x55\x55\x4d\xf3\xd8\x32\x4c\xa2\xc0\x0b\x67\x74\xb1\x4c\xde\x6f\x07\x61\x22\x34\x81\xbe\xaf\xf3\x63\x51\x1d\x60\xef\xda\xf2\xf6\xc7\x1e\x25\x24\xc3\x94\xa7\xe4\x32\xd1\xac\x5c\x48\xe2\xcb\x30\x05\xe1\xd4\xb1\x9f\x8b\xe3\xec\x1b\xa5\x2a\x53\xca\x27\x5c\xd8\x40\x78\xea\x0f\x63\x40\x1c\x0a\x0f\xa7\xa2\xc8\xcd\xf9\x6f\x95\xdc\x65\x98\xa5\x56\x79\x6e\x2f\x4f\x79\xa1\xb7\xd8\xb6\x05\xfa\xa6\xd3\xc9\x9d\x09\x1e\x99\x41\x56\x8a\x74\xd3\xdc\x11\x88\x53\x4a\xe0\xff\x78\xbc\x7b\xb9\xdf\xec\x19\xef\x0f\x70\xa0\xc8\xdc\x14\xf9\xb1\x6f\x23\xde\x7e\xe6\x9d\xc5\xa9\x06\x9f\x5b\x86\xa0\x13\x8a\xe3\x5e\xa1\xc5\x3f\xf1\xdc\x9f\xaf\x0d\xf9\xc5\xd7\x2f\xcf\x2b\x42\xbc\x5f\x6d\x6e\x1e\x9f\x37\xfb\xe7\xcd\x76\xd7\xfd\xfb\xf2\xb0\x7d\xbc\xbb\xee\x47\x9b\x8c\xac\xf3\x8e\xaa\x5b\xee\x8f\x92\x85\x14\xb0\x3f\xa3\xa1\x28\x70\x31\x75\xe6\xc7\x0a\x41\x78\xec\xbc\x71\x08\xaf\x2e\x4e\xa5\x0c\x3d\xf5\xff\xf4\xa9\x3a\x19\x2a\x11\xf1\xb0\xd7\x5e\x78\x80\x36\xff\x70\x75\xe3\x25\x94\xa8\x0c\x95\x0a\x28\x5d\xd4\x45\x87\x45\xf5\x41\x5d\xce\x94\xb2\xbf\x7b\xfc\x31\x13\xb1\x5a\xe8\x11\x19\xee\x50\x87\xca\xea\x90\xe7\x58\xef\x6b\x68\x71\xdf\x3f\xa8\x8e\xb9\x71\x45\x07\x42\xbc\xcd\x58\xd1\xff\x63\x6c\x53\x74\x6a\xa8\xcd\xee\x13\x75\x37\x45\x07\xa6\x43\x19\x6a\x83\xd6\x0f\xea\x66\xc3\xad\x8e\x96\xfd\xaf\x10\x79\x4c\xde\x9c\x75\xbb\xfa\xbe\xef\xe9\x53\x23\x4a\xde\xcb\x98\xfe\xc4\xdc\x1a\xd3\x2e\xe2\xf0\xfe\x55\x68\x92\x80\xf0\x87\x37\x90\x17\x79\xf9\x7a\x8d\xc7\xa2\x3a\x0f\x5c\x73\x92\x05\x5c\x79\x97\xe4\xba\xfa\x2c\x7f\x54\xad\xcd\x5f\xb8\xad\xd2\x79\x0d\xa1\x5b\x9e\x2c\x0c\xa2\xb4\xaf\xca\x61\x33\x6f\xc0\x95\x8c\x85\x8a\xfa\x6c\xbe\x83\xc6\x86\xf2\xf3\x93\x7b\x66\x2c\xc4\x98\x14\x84\x4f\x58\x8c\x72\x34\x92\x31\x9d\xd2\x3a\x79\x7a\x7e\xbc\x7f\xa4\xc9\xf8\xf4\xfc\xf8\xed\x79\x75\xef\x07\x44\x18\x11\x18\x17\xea\xfa\xb7\x7e\x72\x37\xd2\xa4\x2e\xb9\x49\xe5\xf1\x6e\xc2\x5a\x9f\x6a\xf4\x91\x58\x1c\x64\x54\x5d\x7b\xda\x3c\x77\xa6\x7c\x7f\xbd\xb9\xbb\xbd\xbf\xdd\x79\x4c\xa2\x64\x31\x67\x99\x73\xb7\x49\xd8\xf4\xda\x55\x16\xc8\xdc\x5e\x39\xe5\xac\x91\xb3\xc4\x62\x13\x10\x3d\x4f\xe5\xbb\xac\x9b\x31\x6d\xbc\x64\x9c\xdb\x98\xd8\xc5\x89\x8e\xbc\xc3\x12\xc8\xe0\xd8\x9a\x32\x9e\x18\xc2\x55\x93\x92\xfc\xda\x71\xba\x3d\x39\x41\x33\x3f\x46\x86\xd4\x06\x7c\x5d\xc3\xe7\x33\x82\x3e\xef\xaa\x27\x38\x57\xa7\x76\xbc\x05\x66\x0b\xff\x3d\x31\xb8\x8c\x4b\x1d\x7a\x4f\x2e\x5f\x86\x70\x48\xc6\x8d\xa6\x14\xf5\xf6\xf1\xfa\xf6\xe5\x7e\xc4\x32\x2f\x59\xc2\x02\xaa\x23\xfc\x03\xea\x6a\x5b\x20\x2e\x87\x9e\x92\xa5\x18\xfa\x02\x65\x31\x5a\xc7\xd3\x9b\xc9\x02\x45\x39\x53\xaa\xc9\xab\xf7\xb1\x6a\xda\xf2\xa7\xce\xd2\x84\x0a\xbe\x07\xc8\xcb\x1b\x90\x75\xae\x26\xf8\x44\xc9\x32\x15\x19\xe6\x55\x8b\x3a\x1f\x67\x69\xdd\x33\x21\x44\x86\x33\xaa\x7d\x77\x08\x78\xa8\xc3\xa9\x0a\xa9\x25\xef\x9f\x0d\x4b\x75\xe0\x54\x69\x7f\x50\x1b\x7e\xcf\x2c\x3a\x7f\x82\x8b\xe6\x03\xc9\x00\x25\x11\x63\xbb\x7c\x72\x43\x8c\x6d\x43\x0b\xc1\xcc\x56\xfd\xf7\xff\x0c\x5d\x39\xb3\xe7\x90\x1a\xa9\x81\xa3\x1b\x9f\xb7\x67\x0b\x51\x9d\xec\xfd\x4c\x71\x20\x04\xc9\x1b\x34\xcf\x50\xea\xea\xd0\x1f\x40\x46\x84\x2e\xd7\x88\x7a\x5d\x54\xcd\x30\x1b\x15\xea\xd0\x7a\xc1\xf8\x91\x57\xa7\x86\x50\x9e\x7d\x86\x91\x8e\x13\x07\x93\x6d\xf8\xac\x46\xa2\x22\x93\x1d\x78\x94\xec\x5f\xfe\x98\x3a\x0d\x23\x74\x8c\x39\xcd\xcc\xae\x68\x95\x25\x63\xee\xb7\xcb\xe8\x5d\x32\x8d\x21\x55\x98\x5d\xaa\xcf\x81\xee\xed\xa4\x9f\xa0\x98\x86\x37\x8f\x89\x20\x5c\xe7\x5b\x75\xc4\x25\x4e\x96\xb1\xbf\xcd\x50\xc6\x04\x8a\x78\x7c\xd8\xec\x9d\xd5\xf8\xa3\x3f\x24\xa8\xdf\x32\x3f\x1c\x7d\xbb\x4b\x63\x6b\x8b\xc3\x08\x43\xd6\x64\x5d\x35\xdd\x13\x4c\x97\x49\xbf\x00\x4c\xc8\x5d\xa6\x0a\xf4\x3e\x8f\xbc\x1d\x67\x26\x62\x04\x53\xdf\x3c\xae\xb7\x8b\x74\x47\xe3\x1b\x8d\x02\x8e\xde\x89\xba\xaa\x4a\x6d\x31\x42\x93\x77\x15\x05\x59\x4c\x72\x91\x36\x93\x58\xcf\xb3\x40\x32\x0a\x74\x2a\x92\x21\x67\x36\xaa\x31\x4d\x26\x7e\x14\x26\xa6\xef\xd2\x22\x10\xcf\x82\x0c\xa7\x1b\xca\x64\x62\x26\x7d\x70\x3f\xd7\xcb\xc6\x22\x8a\x82\x94\x99\x5e\xa4\x6c\x57\x59\x42\x89\xfe\x65\x46\x91\xb6\xca\xa9\xa7\xf2\x08\xa7\x66\x94\x64\x93\x51\x84\x29\x11\xac\xde\x57\x1f\xb8\x1c\x8e\xcc\xea\xa2\xee\xbc\x38\x10\x94\x93\xe9\x16\xce\x13\xaa\x93\xf7\xb6\xa3\x98\x47\xb1\x1a\x60\x9e\x8f\x66\xea\xb1\x46\x31\x72\x2a\x6f\x13\x74\xec\xea\xe5\xd9\x5b\xc6\x88\xa7\x19\xb9\x6d\x87\xea\xe3\x82\x98\x7a\xf6\xbc\x5c\xda\x46\x98\xfb\xbc\x6c\x6f\x1f\xae\xff\x6a\xb4\xeb\xc6\xaa\x49\x5c\x7c\x57\xc3\x07\x16\xa4\x05\x78\x7e\xc6\x86\xd2\x65\xcb\x0e\x58\x94\x84\x21\x52\x0b\x78\x17\xea\xfe\xf4\x6d\xf5\x17\xb4\x32\x7e\x34\x30\xaa\xed\x2b\x6a\xca\xb8\x20\xed\x9c\x0d\x46\x4e\x96\xc7\x76\xdc\x6c\x7e\xd9\x3c\xac\x43\xc7\x34\x93\xf6\xfb\x51\x1c\x1a\x25\x68\x7c\x4a\xf4\x1e\xca\xf3\xae\xfa\xf3\xac\xe6\x21\x43\x94\x06\x92\xdc\xdc\xaa\xd6\x58\xff\x84\x86\xea\xe5\x7f\x2f\x60\x89\xd2\xd0\x78\xf4\xe3\x3d\xfc\x5a\x82\x26\xc9\x28\x85\x30\xb1\xf0\xbc\xf3\x4a\x53\xd7\x29\xd5\x4f\xa6\x9f\x39\x13\x82\xb3\x9e\x93\xcc\x99\x40\xff\xa9\x33\x89\x21\x75\x71\x54\x6d\x6e\xce\xeb\x37\xa8\xfb\x98\x24\x12\x69\x98\x0c\x84\x32\x0f\x55\xf9\x8c\x47\xb4\xd2\x0d\x3f\x8e\xc6\x1a\x89\x79\xc3\x47\xff\x30\xd3\x8d\x22\x12\x8e\x3d\xb0\x25\x49\xdd\xf9\x7c\x5e\xfe\x32\x42\x65\xdc\x78\x72\xec\x16\x8a\xc7\x4f\x17\xa7\x3f\xe3\x11\x72\xbd\xab\xee\x6c\xa9\x73\xfa\xb8\x02\x81\x7e\xe9\xfe\xf6\x61\xbf\x5a\xaf\x37\x4f\xbb\xfd\x66\xf7\xbd\x77\x8e\x22\x88\x02\x9f\x50\x74\x5a\xe0\x94\x51\xa7\xef\x3b\x5d\xf5\x90\xa6\x54\x14\xa4\xf5\xb1\x7a\xbe\x1a\xb9\x58\x91\x64\x56\x55\xdc\x17\x86\xf6\x71\x7f\x24\xd3\xbe\x21\x79\x94\xf9\x1b\x48\xc2\xdc\x30\x85\x56\x99\xdb\x7d\x58\x9b\x55\xf0\xd7\x50\x86\x93\xc6\x93\xd7\x8b\x20\x0a\x89\x2f\xe6\xaf\x0e\x23\xe5\xdc\x20\x07\xc7\xf8\x8a\xab\x48\x46\x9a\x03\x99\xd7\x6f\x97\xbc\xc9\x32\xd2\x22\x22\x99\x88\x7f\xed\x7c\x86\x22\xc2\x38\x10\xe0\xf0\xd2\xaf\xaf\x5f\x64\x21\x23\x8c\x2d\x4c\xeb\xc6\xaa\xad\x0e\xae\x71\x84\x5c\x06\x30\x15\x17\x8d\xe2\x49\xb6\x2b\x32\x81\xe5\xbd\x39\xe4\xe5\x3e\x2f\x3f\xfc\x99\x86\x47\x91\x5d\x95\xdd\xb4\x1e\xa1\xef\xbb\x43\x92\xf8\xc8\x6c\x97\x9a\x5f\xdc\xfe\xa0\x09\x88\xfb\x76\x77\xbb\xdb\xae\x1f\x7d\x1b\xb4\x8c\x43\x13\x53\x39\xf9\x08\x67\xac\x27\x68\x4e\x19\xb3\xd8\x16\xfd\x5d\xba\xa8\xdb\xe7\xfa\x43\x1a\x05\xf3\x74\xfd\xb2\x51\x75\x2e\xad\x0e\x05\x01\x35\x86\x97\x17\x47\x10\x86\xe8\x5d\xee\xe6\x6d\xd6\x67\x2a\xe3\x38\x90\x96\xd6\xe0\x54\xae\xab\xc3\xf1\xd4\x22\x55\x46\xc6\x89\xf0\x38\xe6\x81\x8f\x68\x9e\xaf\x7b\x1d\xf8\xd9\x75\x44\x9a\x31\x9f\x22\x3e\x1c\x4e\x9d\xb3\xb4\xa4\x9c\x25\xe3\x18\x03\xca\xf5\xdb\xa8\x9c\x7a\x98\x1f\x4e\x94\x92\x9b\xcc\x9f\x98\x33\x24\x0c\x41\x25\xff\x17\x55\x7b\x5d\x9d\x64\xdf\x63\x20\xbb\x1d\xc4\x84\x7e\x0b\x51\xf5\xe9\xaf\x1b\xfc\xfb\x13\x2d\xf3\xe6\x7a\xa2\x33\x25\x63\xae\x03\xa1\x07\x46\xd2\x6f\x70\xb0\xc8\x1f\x77\x38\x0d\x75\xda\xf3\xb5\x43\x61\xe3\xc2\x09\xbe\x63\xd9\x5a\xc6\x29\x63\xa1\xf0\x8a\xe8\x24\xb1\xda\x1f\x50\x94\xee\x93\xd8\x32\x8d\x45\x0b\xb3\x3a\xb4\x8c\xd3\xc4\xf6\xbf\x6b\x2c\xf2\x0f\xa7\x69\xd0\x4c\xf8\x37\x67\xbf\x95\x85\x9c\x10\x92\x8e\x7e\x7b\x44\x9e\x24\xe3\x2c\x65\x44\x63\xd7\xb4\xd5\xf1\x38\xc0\x2a\x65\x9c\xe9\xd0\x32\x43\x3a\x7d\x9b\xea\xa9\xc6\x43\x7e\x3a\x4c\xad\x57\x2c\x59\x64\xd1\x97\xcb\xce\xd2\x69\x4e\x8c\x24\x63\x99\x4a\xda\xbf\x8a\xbc\x69\x6f\xaa\x7a\x4c\x2d\x35\x5d\xfd\xb1\x0a\x82\x11\x0c\x14\x0b\x6c\x2f\xa8\xe7\x64\xac\x84\x15\x91\xb0\xe8\x25\x2c\xf5\x97\xad\xc7\x32\x56\x52\x5b\x65\x9b\x1a\x94\x63\x21\xdf\xb6\xd5\xd1\x7a\xb8\x6e\x8c\xd7\x6d\xb8\xd9\xae\xa3\xfe\x6f\xb1\xf4\xfd\x27\x2e\xe4\x98\x97\xa6\x97\x3f\xb2\x4e\xad\x92\x50\x0b\xaf\x7f\x2c\xb9\x42\xb1\x16\x48\x85\xd0\x1e\x76\x61\x6f\xca\x9b\x8e\x18\x23\x43\x0d\x9b\xa0\xf5\x08\xbf\xe9\xe2\x6a\x1e\x30\x49\x58\xb0\x4d\xfb\x26\xb1\x7d\xac\x41\x15\xe3\x16\x88\xc5\xc9\xc0\x03\xa6\xb5\xf0\x2f\xd5\x4b\xaa\xf7\x2a\x53\xd3\xaf\xcb\x83\x38\x0a\x69\xaa\xe5\x4b\x8c\xc4\x7e\x90\x4a\x52\xcf\x1e\x43\xde\xcd\x44\x0b\x5f\xf2\x30\x00\xda\x1c\xec\xb6\xec\x9a\x35\xbe\xb8\x56\x98\x24\xe8\xab\x9e\xd6\xa3\x59\x92\x83\xf4\x83\x45\xe2\x05\xc0\x49\xfc\xfb\xff\x5d\xb9\xe6\xff\x87\x7f\xfd\x7d\x68\xa4\xaa\xd6\xed\xf5\x66\x75\xd7\x3f\xb5\x89\xa8\x01\xa8\x47\x62\x20\xf8\x00\x90\x33\x05\x5e\x45\xe3\xb1\x7e\xa5\x9d\xad\x59\x5f\x9a\x44\x1e\xa5\x16\xa3\x73\xa0\x0c\x70\x73\x8d\x85\x27\x02\x94\x3c\x0e\xd8\xd0\xfb\x7c\x03\x75\xdb\x78\x59\xca\x7e\x04\x43\x13\x8c\x92\x33\x0b\x6a\x00\x92\xf3\xc8\x4a\x3c\x5a\xab\x3b\x61\xd0\xff\x92\x85\xe7\x2b\x8b\x3a\x9e\xda\x3c\x81\xc4\xe6\x74\x4e\x50\x43\xd9\x22\xea\xab\xd3\x19\xeb\x49\x83\xb6\xe4\x29\xcb\x84\x8b\x69\x9a\xca\x2a\xb4\x3a\xdd\x0b\xc7\xc8\xae\x6f\x20\xef\xf3\x3a\x3c\x8d\xac\x84\x8f\x55\xb1\xe8\x4c\x87\x75\x0b\xa0\x28\x24\xa8\x0b\x01\x2e\x7f\x16\x8f\x22\x0b\x4a\xa2\x9c\xe9\x84\x94\x51\xf2\x8c\x69\x2a\x85\x1c\x5e\x0f\x97\xf2\x95\x92\x67\xb1\x6d\xd5\x26\x52\xda\xb5\x13\xbd\x9d\x26\xf2\xa7\x6f\x54\xc8\x98\x9a\x7a\x8e\x70\xee\xcc\xd5\x4f\xcc\xe7\x1f\x46\x68\xdb\xf6\x73\x0d\x75\x0e\xcf\x55\xfb\x5e\x8d\xb7\x1c\x0e\xa1\xa5\x7f\x3c\x9c\x89\x89\x19\xfb\x3b\x85\xd8\x50\x7c\x74\x2c\x40\xe1\xd5\x02\xae\xe8\x6f\x54\x23\x39\xa4\xb6\x0d\x1a\x7f\xb5\x58\x6a\x7a\x2a\x0a\x4b\x2d\xe5\xef\x12\xa0\x5c\x72\xd0\xc6\x63\x18\xa9\xb3\xfb\xbe\xd7\xfb\x5c\xec\xd8\x96\x5c\x46\x48\xf9\x39\x3c\x60\xfd\x8a\xa5\x3a\xf7\x98\xd2\xcb\x6a\x25\x97\xdc\xb2\x8f\x5b\x25\xa3\x3f\x47\x92\x37\x92\xcb\xc4\xea\x09\x1d\xce\xd4\xeb\xe2\xa3\x74\xae\xa2\x8c\xf5\xb3\x7f\x7f\xbb\x7e\xdc\x37\x23\xf4\x84\xe4\x3a\x92\x4a\x0e\xa4\x69\x5e\x1b\xbb\x3f\x1c\x07\x68\x01\x55\x36\xc2\xf1\x7f\x4e\x04\xb8\x15\xb3\x19\x3a\xb7\xa6\x8f\xa6\xb5\x0c\x8c\xc7\xa1\x3b\x75\xa8\x85\xf2\x07\xc7\x20\xa1\x99\x7d\x57\x95\xaf\x3b\xac\x0f\x4e\x8e\xbd\x8b\x3b\xbf\xa6\x03\x9e\xbd\x77\x8c\x34\x39\xaa\xba\xda\xbd\x75\x06\x75\xb2\xc0\x90\x67\x54\xb3\xba\x2d\x1b\x1c\x57\x8c\x39\xa6\x19\xbd\xb3\xef\xd0\x6c\xf3\xd7\xd2\x6a\x8c\xf9\x7a\xc1\xf4\x61\x50\x68\x74\x86\x28\x0a\x56\x35\x51\x49\x34\x63\xc6\xb3\x6e\x08\x12\xf6\xac\x7d\xcb\x6b\xfd\x13\xd1\x6f\x94\xdc\xc4\x09\x65\x06\xaa\x09\xdb\xcc\x6c\xb6\x19\xc1\x29\x6a\xb8\xdb\x6e\x46\xb7\x98\x04\x0c\x29\x95\xf9\xa3\x2a\xde\x1b\x35\x3a\x10\x8a\x4c\x6b\x6f\x19\xd7\xa0\xde\xd0\x42\x48\x2c\x2b\x1f\xd6\xdf\xa0\xe9\xdc\xdd\xe6\x27\x34\xdd\xa2\xef\xd7\x54\x12\x31\xcb\x96\x26\x5b\xaf\x26\x2b\x93\x98\xf9\xce\x24\xd4\xb6\x3b\x64\xdc\x59\x25\x93\x58\x59\xb0\xd2\x9f\xb7\xf7\x9b\x7f\x2e\x97\x52\x93\x58\xa5\x94\x4c\xb5\x74\x3e\x14\xfb\x13\x7f\xa4\xf5\x4c\xc7\x1f\x24\x89\x31\xf6\x3a\xad\xbb\x01\x88\x73\x75\x1e\xfd\x9f\xdb\x59\xee\x27\xe1\x51\x4c\xa9\x76\x2b\x2f\xb7\xf7\xed\xe4\x55\xdd\xdf\x64\x2a\x91\x1e\x62\x75\xf3\xf2\xb0\x6c\xdf\x92\x4c\x66\x89\x23\xc0\xf4\x64\x0d\x7d\xa3\x97\x37\x1e\x89\xe0\x31\x95\x84\xae\xaa\x53\xdd\x8c\xdb\x3f\x65\x22\x44\x42\xf5\xbe\xe6\x13\x8e\x3f\xf3\x72\x94\xc2\xba\x44\x2a\xca\x04\x82\x8c\x90\x17\xdf\x6a\x44\xfd\x94\xf7\x37\x0a\x81\x21\x46\xa4\x16\x9a\xf7\x66\xf2\x9e\x21\xb4\xe2\xba\x2d\x36\xed\xee\xad\xae\x3e\x9f\x91\x12\x98\x9b\xd2\x54\xb5\xc2\x67\xfc\xc8\x1b\x92\x0f\xf7\xe3\x39\xa7\x98\x68\x7f\xc8\x9d\x30\xfd\x17\x0f\x0e\x3a\x41\x33\xa7\xb2\xbd\x78\xc7\x60\x22\x6d\xab\xd9\x87\xbc\x15\xfd\x8f\x18\xee\xc5\x48\x1d\x23\xfe\x13\x9c\x2f\xe4\x8d\x64\x22\xc3\x88\xe4\xa0\xda\x1c\xeb\xd0\x9f\x2c\xa3\xcc\xf3\xa3\x92\xe3\xed\xf6\x8c\x9b\xaa\x5e\x57\x6e\xa5\xcd\x02\xa1\x44\xc6\x49\x68\xdb\x66\x4b\xbd\xd9\xad\x67\x47\x55\x68\x29\x3b\x9e\xbd\x14\xbf\xff\x25\x15\x5b\xba\x2c\x79\xaa\xcb\xdd\x5b\x3e\x4b\xd6\x26\x3a\x08\x09\xe2\xb7\x29\xf5\x7e\x6e\xe5\x12\xcd\x02\xdb\xbd\x73\xc4\x05\xad\xd2\xc5\x4d\xe2\x77\x5b\x47\xa2\x33\x95\xa6\x23\x55\x83\xa7\xea\x13\x6b\xd4\x2f\xbe\x86\x9f\x60\x6a\x3b\x43\x1c\x34\x72\x94\x0c\x4f\x4c\x60\xc8\x6c\x12\x9b\xf7\xaa\x28\xd6\x50\x6a\x82\x52\x34\x57\xe7\x6d\x09\xc7\xe6\xad\x5a\xc0\x89\xc9\xc4\x84\x29\xe5\x54\xb6\xf9\xe1\x58\xe0\xea\xff\x4e\x40\x21\x28\x39\xbb\x5f\x24\xdf\x12\x93\x28\x2a\xb4\x1c\xeb\xaa\x25\x8d\xad\x6b\x2c\xab\x83\xe3\xeb\x7d\x34\x8f\x75\xfe\xda\x5b\x9c\x34\x60\x82\x56\xe0\x2b\x1c\x90\x48\x26\x8e\xbe\xa7\xbe\x3b\x66\x2b\xe8\x3a\x6f\x54\x2f\xac\x2b\xd3\x20\x0d\xa8\x1a\xe8\x04\x5c\xee\xa1\x3c\xcf\x33\x69\x69\x00\x96\xff\x73\xaf\x6c\xf4\xfc\xf4\xe3\x69\x24\x6e\x3a\xef\xeb\x90\x69\x98\x65\x94\xbb\x6a\x5c\x2d\x63\xac\x18\xfe\xdf\xcc\xd5\x21\xe2\x51\x2b\x47\xe6\x12\xec\x7d\x90\x93\xf8\x9f\x0e\x21\x55\xd1\xa5\x4c\xdc\x5f\xf9\xc6\x93\x09\x99\xb2\x24\x0b\x54\x9f\x1f\xb8\xdc\x40\x96\xb2\xe1\x29\x93\x21\xf9\xbc\x55\x61\x33\xe1\x4f\x75\x65\x7a\x03\x91\x46\xa1\x65\xef\xdb\xfc\x52\x50\xe4\xf2\x54\xf7\x07\xd2\x20\xb2\x28\x8b\xe2\xb9\x2a\xf0\xa6\xaa\x5f\x9a\x2f\x90\x38\x69\x1c\x25\x90\x0e\x2c\xe2\xcd\x75\x5d\xe5\xba\xb9\xed\x43\xa6\x34\x06\xde\x73\x29\x0e\xf9\xa5\x47\x63\x13\x05\xc3\x30\x19\x53\x4d\x92\x2a\x6c\xfb\xed\xcb\xd3\xd3\xdd\xbf\xf6\x8f\x3f\x1f\xfa\x8c\x59\x1a\x6b\xa5\x2d\x47\x8f\xe5\x17\xfd\xa2\x83\x4d\xa6\x3c\x60\xb4\x06\xa9\xdf\xd2\xf9\x7a\x53\xd8\xb4\x4c\x39\x30\x9a\x65\x24\x73\x70\xdf\x4f\xb0\x44\x67\x64\x79\x7b\x9c\xac\xfb\x7b\x9a\x06\x54\x84\x78\xfa\x7f\x68\x7b\xb3\xe5\xc6\x91\x24\x0b\xf4\x77\xea\xa1\x1f\xb0\x04\xb6\x47\x8a\xa2\x52\x9c\x92\x44\x36\x49\x65\x56\x75\xdb\x18\x2d\x16\x0f\x11\x2d\x10\xe0\x00\xa0\x94\xac\xaf\xbf\x06\xf7\x08\x6c\x04\x95\xd5\xd7\xee\x9d\x87\xc9\x6a\x21\x00\x62\x89\xf0\xf0\xe5\xf8\x39\x9b\x05\x3a\x37\x84\x85\xd9\x2d\x9f\x17\x6d\x99\x3c\x8a\x22\x96\x0c\x98\xc0\x96\xea\x76\xaf\xb9\x88\x22\xe1\x62\x8b\x13\xd1\x61\x58\x17\xd6\x1e\x54\x11\xc2\x54\xe6\x45\x7e\xce\xff\x66\x20\x1f\xc5\xcc\x45\x26\x8e\x59\xc9\xdf\x0a\x3a\xab\xf1\xc8\x9f\x7b\x8b\xf8\x2a\x61\xfa\x55\x60\x16\xdb\xeb\x06\x09\x46\xe0\xc4\x96\xb2\x3b\x74\x1e\x70\x14\x07\x9a\x68\xf4\xd3\xf2\xbe\x2c\x4e\x6b\x7e\xb9\x4b\xeb\x6a\xe3\x5e\x2d\xbf\x58\xb9\xfd\x25\xda\xa1\x8c\x8b\xec\x1a\x32\x14\x25\xcc\x43\x87\xbc\x31\xff\x46\x2e\x71\xc4\x3f\x3e\xf5\x46\x93\xd0\xc7\x5a\xe2\x81\x57\xb3\x52\xa4\x35\xa0\xee\xde\x34\x32\x5f\x44\x3c\x24\xce\x90\x0f\x4a\x20\x34\xce\x99\xa9\x06\x99\x01\xd2\x0d\xd0\xd1\x32\xb4\x68\xc5\xdb\xb4\x75\x8b\x64\xe8\x49\x61\x53\x4e\xa4\xd4\xd2\x67\xbf\xb4\xa3\x44\x8c\xa9\x0e\x55\x16\xa7\x95\xd6\x55\x9b\x22\x8b\x94\x13\x62\x3e\x99\x9f\xeb\xe2\xd8\xf8\x44\x43\xc6\xe3\xf6\x15\x2a\x46\xde\xd3\x72\xbe\x7a\x78\xd8\x3e\xae\x36\x8b\xf6\x0a\x91\x4b\x4a\x87\xb8\x89\xd7\x87\x5d\x31\x87\xbc\xae\xba\xb7\xd7\x23\xfb\x11\x91\x52\x11\x1a\x05\x9d\xe6\x69\x75\x68\xfc\xdf\x34\x7f\x23\x36\x2b\x3b\x44\x73\xc6\x65\x2b\xe0\x81\xf8\x89\xf6\x90\x70\x62\xd1\x23\x93\x35\xc4\xe1\x93\xfe\x40\xa4\x15\x44\xae\x21\xb6\xbb\xd9\x0d\x37\xf8\x86\x1a\x02\x64\xe6\x79\x22\x41\xf8\x6b\x15\x1b\x11\x69\x9d\x24\x5e\xc7\xbc\xb6\x85\x2c\xd3\x45\x69\x3b\x6a\xdb\x1f\x8f\x9d\x90\xc4\x06\x0c\xe6\xc0\x3c\x40\xec\xfa\x9c\x9c\xcc\xf7\xf7\x76\x89\x4c\x4f\x91\xd8\x65\x11\x32\x3d\xa3\xec\xf0\x8f\x55\x7b\x05\x06\xe8\x82\x1a\x55\xb6\xc5\xcf\xb4\xaa\x47\x35\x93\xd8\x8d\x81\x13\x82\xf7\xa3\x09\x51\xd5\x4b\xef\xfe\xa6\x26\x6f\xec\x26\x1e\x42\x44\xf7\x1c\x71\x78\x57\x80\x22\x33\xcc\xf3\x42\xa4\x77\x6b\x8d\x8c\x95\x87\x81\x2b\x68\x88\x3d\x23\x84\xc0\xe9\xb1\xb1\xcf\xd0\xd0\xd8\x79\x19\x7b\xb1\x76\x2d\x64\xd8\x12\x63\x9a\x88\xdf\x66\xb9\x87\xd7\xf3\xb9\x83\x98\xe0\xe7\xcb\x6e\xf6\xd4\x77\x8d\x62\xe6\x53\x0a\x55\x66\x45\x95\xe6\x6f\xf7\xbc\x06\x53\x20\x69\x47\x28\x1f\xcb\x4d\xd5\x29\x4b\x6b\xda\x8c\xbe\x2f\xd7\xfb\x22\xcf\x2e\xfb\x7b\xb0\xb9\xfb\x38\x70\x00\x59\x92\x5a\xb9\xbc\x96\x4d\x6f\x95\x4f\x75\x2e\x0d\xbf\x5a\x90\xf8\x58\xb3\x87\xed\x6e\xb6\x5b\x6c\x26\x49\x62\xcc\xd0\xd0\x0b\xb0\x9b\xad\x99\xcc\x8b\x5d\xb8\x95\x45\x09\x77\x17\xe3\xb0\xb6\xdf\x32\x54\x31\xc6\x4c\xf3\xf5\xb7\xf5\x62\xb3\xf8\xb6\x59\xbe\x2c\xf6\x0f\xbb\xa7\xfd\x76\xbd\x58\x58\x8c\x58\x1c\xc5\x1a\x19\xad\x2d\xa3\x2f\x51\xef\x7f\x35\xd9\xe3\x48\x90\x10\xe3\x1b\xd4\x6b\x28\xab\x82\xc4\x5f\xeb\xf3\xc8\x55\x8d\x23\xe9\xf6\x90\x81\xc5\x27\x49\x99\x4c\xb7\x05\x8a\x38\x4e\x7c\x24\xbb\xfd\x57\x2a\x4c\x32\xda\xde\x62\x2c\x1d\x97\xba\xea\x89\xc6\xb7\xe5\x3d\xfb\xb2\x8c\x16\x27\xb1\x67\x35\x50\x67\xad\x8d\x88\xb9\x49\xab\xdc\x65\x67\x90\x87\xd4\xfa\x9c\xb1\xf0\x04\xeb\x39\x04\xad\x91\xb8\x0a\x76\x63\x21\x24\x71\x31\x19\xd7\x74\xf1\xb0\x6b\x2f\x22\x25\xb3\x14\x85\xd8\x01\xdc\x01\x53\x63\x01\x4e\x48\xe1\x74\xa9\x3e\x79\x39\x08\x9d\x62\x01\xb4\xe8\xb1\xe8\x59\xd5\x50\xe6\x85\x82\xd6\xb7\xb5\xa3\xa4\x47\x09\x78\x90\x36\x91\xfb\xcb\xa4\x62\x2c\x23\x89\x4d\x8b\xfd\x07\x6a\x13\x49\x83\x22\xef\x2f\xae\x13\x87\xa4\x46\x49\xbd\x4a\xab\x8f\x36\xb9\x12\xcb\x24\x42\xda\x11\xc4\x70\xd2\x22\x1c\x44\xb4\xb1\xf2\x03\x8c\x19\x8f\xa0\x52\x91\x0e\x02\x93\x58\xc9\xc8\x37\x04\x85\x08\xf7\x41\x36\xe9\x12\x56\xed\x7b\x83\x58\xb3\xd0\x88\xac\x83\xc4\xfb\xb7\xec\x4e\x66\x84\x76\x14\xa2\x3c\xd6\x45\xfe\x57\xda\xd8\xd5\xee\xd6\x74\xe4\x7a\x7d\x2e\xb2\x6f\x3d\x9e\xde\x2b\x99\x9b\xff\x5f\xb2\xba\x89\x13\xba\x11\xa5\x90\x5e\x97\x2f\x3b\xd7\x1d\x52\xab\x8b\xc4\x91\x20\x2d\xde\x09\x3e\xfb\x45\x95\xc4\x75\x43\x0c\x85\x4f\x64\xd1\xa6\xc5\x55\x44\xe2\x7a\x2c\x30\x69\xb5\xdf\x5f\xe6\xd4\x9a\x70\x1d\x81\x26\xae\xaf\x71\x81\xed\x2b\xa8\x47\xbd\x03\x83\x09\x9e\xb8\x3a\xc6\xfa\x2f\x36\x86\xd8\x42\xe3\x2c\xcb\xfa\x19\xb5\xc4\x0b\x24\x5a\xcd\x7d\x85\x42\xe5\xc3\x78\xdf\x8c\x61\x7e\xe2\x81\x75\x31\x8e\x3c\xcd\xad\xac\xef\x43\x51\xce\xca\x3a\x6d\x76\xf7\xfe\x44\x49\x58\xe0\x62\x64\x48\xa8\xec\x31\x1a\x64\xfa\xe9\x59\xe0\xa3\xef\xcb\xab\xaa\x25\xde\x1f\xab\x1f\x88\x24\x50\xb4\xfb\xb6\x24\xbb\x23\xa2\x40\x91\x84\xbe\x24\xcd\x1d\xf3\xc0\x4f\xa9\x68\xed\xb7\x01\xff\x0e\x2f\x19\x26\xae\xa5\x93\x7c\xe2\xb9\x5a\x54\x35\x39\xcf\xa3\xcb\x26\x0c\x1b\x94\x5a\x61\x75\x91\x44\xae\x83\x7c\x60\xe4\xc9\xcc\x48\xcc\xb4\x6a\x8f\x26\xd2\xea\x68\x3c\x16\x35\x64\xd5\xdd\x65\x84\x5c\x35\x03\x13\xdf\xc3\x10\xc6\xfc\xd5\x24\x06\xfb\xdd\x5f\x22\x49\x42\x07\xb3\x13\x04\xf2\x58\xd7\x5b\xae\xe1\x8f\xa7\x1e\xd8\x21\x69\xfe\xaf\xc5\xad\x3e\xa5\xf9\x7b\xbb\xae\x92\x44\x01\x12\x36\x3f\x17\x99\x1a\x40\xad\x86\xf7\x21\x1c\x0f\xa9\xf8\xe0\xa3\x09\x3d\x9a\xad\x73\xda\xc2\x27\xc2\xf5\x55\xdc\xc3\x35\x60\xef\x1f\x54\x23\x32\x52\x3b\x98\xc7\xe8\xee\x3d\x64\x45\x99\xfe\xe7\x4b\xf4\x54\x22\x7d\xed\x19\x0e\xfe\x1f\xbd\x1e\xaa\x44\x86\xd2\x37\x1e\x4f\xaa\x2f\xc3\xa9\x06\xae\x49\x2d\xd7\x87\x3b\x5e\x8d\x99\x3d\xec\x20\x3f\xa0\x9e\x15\xc3\x6e\x85\x25\xf2\xe1\x43\x81\x1f\x61\xea\x73\x97\xd6\x99\xd9\x99\xc6\xc8\xac\x04\xb4\x22\xb9\xd1\x73\xf6\x7e\xbb\xac\xd8\x0c\x93\x8d\xa5\xfb\xe7\xeb\xec\x77\xfb\x08\x5a\x26\x58\xba\xb1\xb3\x72\x5b\x1f\x4f\xd5\xae\xc0\x99\x79\xa3\x78\x48\x67\x72\xc7\x13\xb8\x4b\x3f\x5d\xce\x3b\xa4\xba\xea\x8c\x2e\x77\x18\x6d\x37\x58\x35\x5e\xfc\x3c\x65\xa9\x4c\x6b\xe2\x8d\x25\x17\x82\x94\x11\xfe\xd1\x5b\x70\xf4\xbf\x4c\x6c\xc5\x3d\xdf\x45\x8b\xbe\x4f\xab\x35\x1f\xbf\x13\xee\x01\x91\x9a\x9f\x4a\x38\x51\xf5\xad\x25\x32\x10\xdc\xf7\xb9\xb4\x98\x41\x28\xe7\x67\xbb\x33\x73\x16\x90\x1c\x74\x05\xf5\xea\x08\x6f\x7c\xba\x26\xc0\x99\xa1\x5c\x7a\x5a\x3d\xac\xda\x53\x79\x1c\x85\xad\xce\x90\x25\x83\x6e\x36\xbb\xd6\x89\xe3\x4c\xf8\x88\x54\x10\x69\x59\x1f\xfa\xa5\x5a\xce\xa4\x87\xd8\x82\x0d\x4f\xd1\x3c\x54\xf3\x8c\x57\x55\x2a\xdb\xe3\xc0\xa4\xd3\xa1\x52\x1e\x8a\xd2\x70\xfe\xb5\xc7\x13\xa1\xda\x84\x6d\x3a\x00\x48\xf0\xc0\x0b\xdc\x56\x76\x65\x67\xf4\xbc\xda\x83\x91\x63\x63\xb0\x7b\x5e\xbf\x6e\x9e\x06\x73\x94\x07\x5c\x61\x13\x40\x89\xec\xd3\x2f\xfc\x08\x7f\xa4\x93\xad\xd0\x82\x07\xc2\x63\x34\xc5\x2e\x3d\x92\x2d\xfb\xb9\xc2\x00\x14\xd1\x54\x89\x1b\x1d\xee\x82\x47\xdc\xb5\xba\x51\x78\x85\xef\x45\x76\x3e\x82\xe0\x15\x28\x8c\x0b\x9b\x1d\xe5\xa1\x28\x51\x1e\xc4\x1d\x7d\xf0\xd8\x49\x90\x4e\xea\x58\x9d\x85\x25\x11\xf8\xc7\xb9\x47\x26\x20\x78\xcc\x09\xf0\x9f\xe6\x15\x94\xf5\x75\x15\x9a\xc7\xc2\x47\xca\x35\x83\x52\x7f\x4e\x15\xfc\x1c\x4c\xda\xc4\x71\xb0\x2d\x9e\x4a\x8c\xb3\x5c\xed\x7a\xec\x0f\x57\x9b\xc4\x28\xf0\x1e\xde\x6f\xe2\x82\xcd\xfe\x3c\x16\x47\xe0\xea\xe3\x9a\xc8\x14\x15\x0a\x90\xed\xec\x2f\x28\x8b\x07\x80\x6a\xdc\x13\x36\xed\x77\xf2\x44\x6a\x64\xcf\xab\x8a\x4c\xdd\x81\x2e\x4a\x20\xe5\x86\x31\xe9\x87\xe0\x89\x92\x08\xd9\x52\x80\x24\x93\xd8\x5d\x47\xc4\x59\xa3\x39\x9f\x68\xe2\xc5\xef\x95\x00\x1e\x78\x9a\xfd\x42\x0f\x52\x70\x1e\xf9\x2c\x68\x1b\xc7\xef\x53\x9b\xc4\xb3\x79\x43\xb7\x1b\xc8\x2d\xab\xca\x23\x94\xc5\xac\x36\x59\xff\xd1\x26\xc9\x39\x37\xe2\x5b\x96\x35\x75\xe0\x42\xda\x41\xd2\x85\xd8\xf4\xe0\x99\x86\xea\x49\xd9\x50\xa4\x71\x8d\x4c\x8b\xc6\xf6\x2c\x46\xbd\x9f\x70\xa3\x2d\x8d\xcb\x88\x48\xbe\xd1\x8f\x39\x9e\x11\xcd\xd1\x6d\xd5\xc3\xb1\x8a\x25\x98\x2f\x3e\x35\xd3\x76\xef\x53\xcf\xa0\xfd\x79\x15\xba\xd8\x1b\xb1\x9c\xaf\xfe\xd5\xfe\x4d\xc4\xf8\xca\xce\xa6\xdb\x11\xdb\xc3\xa6\xb2\x58\x37\x3d\x3e\x0e\x1a\x90\xeb\xb0\x71\x1a\xfa\x40\x27\xae\x0d\xd9\x19\x5d\x1b\xfb\xb1\xba\x9e\xa5\xc9\x6b\x09\xc7\x95\xb8\x3d\x9b\x77\xb9\x94\xc5\xb3\x45\x6b\xf5\x02\x14\x3b\x58\x3a\xe8\x08\x6a\x03\xf7\xfe\x8e\xe2\xbe\x06\x00\xd1\x0e\x52\x01\x26\xa3\x0d\x6f\xfe\x0b\xa4\x6f\x07\x51\x94\xd5\x6f\xad\xe1\xb7\x11\xa4\x70\x1d\x86\xcd\x59\x0f\x67\xf9\x4e\x79\x21\x5b\xf6\x10\xae\x24\x9b\x68\x4b\x26\x0f\x45\xf9\x90\x7e\xc0\x9f\xc0\xed\xee\x2b\x3c\x57\x22\xe8\x04\x7e\x9e\xb2\xa2\xbc\xf5\x80\x5e\xcc\xc3\x60\x28\xe7\x56\xed\x65\xcf\x82\x0a\x3f\x22\x25\x2e\xdb\x4f\xfb\x84\x12\x71\xc3\x89\xd9\x0c\x32\xa4\x1a\x44\xd4\xbf\x4b\xa1\xf4\x06\xe1\xa6\xdd\x66\x05\x63\x49\x9c\x58\x8f\xc7\xfb\x76\x37\x9c\x31\x22\x70\x04\x96\x50\x3e\x4a\xde\xe7\x9d\x15\x22\x0c\x02\x2c\xf0\xef\x11\x69\x55\x5d\x0b\x97\x0a\x11\x79\x01\x7e\xad\x16\xa0\x3b\x49\x29\xf2\xff\x6d\x80\x21\x22\x1f\xd0\xcb\xf9\x06\xf5\xdd\xf9\xd2\x9f\x70\x22\x52\xbe\xeb\xd8\xac\xd7\xf1\x54\xc3\xde\x6d\xbf\x60\x04\x22\x6c\x05\x6c\x3e\x20\xaf\x8b\x32\x85\xaf\xf9\x09\xad\xb9\x10\x71\x12\x72\xd5\xef\x0b\x9b\x48\x78\x35\x91\x0f\x36\xeb\xee\x8a\xe3\xb6\x25\xa7\x69\x22\x87\x10\xed\xfc\x5d\xd1\xec\x96\x0a\xfa\x8a\x81\xe8\x1e\x10\xc6\x82\x6b\x28\xf7\x4d\xc0\x2f\x8b\x8f\x0e\xeb\xfa\x55\x5d\x49\x48\x47\x63\x6b\xfa\x1e\x09\xd0\xf7\x75\xf1\x9e\x63\xd6\x1b\xbb\x85\xed\x0f\xc8\x30\x52\x8e\x45\x06\x19\x72\xcf\xbc\xbe\x12\x62\x14\x42\x46\x91\x51\x3e\xac\xa1\xac\xce\xa2\xbe\x5d\x40\x14\xca\x4b\x88\xe8\x83\x14\xc4\x3f\x49\x62\xff\xef\x45\xe8\x42\x81\x46\x45\x3d\x14\x34\x28\xf2\x41\x62\x40\x80\x4b\x30\xd1\x37\xa8\x17\xc7\x53\x56\x5c\xa0\xfc\x9f\x42\x34\x3e\x48\xa7\xb0\xb7\xcc\x3f\xd2\xfa\x1a\xaf\x35\xfc\x1a\xc0\x25\xce\x7a\x4a\x2f\x1c\xd3\xbc\xd9\x8f\xd2\xe6\x7c\x14\x77\xae\x0e\x69\xfe\x86\x4c\x41\x83\x9f\xd7\xb1\x16\xf4\x12\x28\xf5\xf2\x03\x52\x23\x17\x35\x7c\x06\x9d\xf8\x08\xe1\xbc\x9b\xed\x76\x4f\x8b\xfd\x7c\xb6\x7d\x9d\x3d\xed\x96\x8b\x6d\x7b\x21\x49\xdd\x0b\xc7\x73\x56\x1d\x6f\x98\x02\xad\x99\xee\x18\xa2\x9f\x53\xa3\xf0\xf6\x03\xd2\xf1\xaf\xe9\x20\x72\xdb\x6d\xed\x77\x18\xba\xf6\xd2\x71\x5c\x2c\x5c\x21\x61\xea\x6f\xf6\x8f\x92\x84\xff\xb8\x52\xab\xf2\xed\x8b\x0a\x87\x74\x40\x20\x7f\x79\xb3\x67\xa3\x59\xeb\x66\x8f\x74\x1d\x85\xb2\x49\xad\x14\x3f\xc0\x5d\x5a\xcb\x22\xcd\xe7\xbc\x3a\x6c\x8f\xfd\x6a\x9b\xb1\x37\xd2\x63\x0e\x46\x32\x38\x39\x6e\x40\xf7\xa5\x97\xc4\xa1\xec\x89\x33\xff\x36\xac\xca\xd9\x51\x5a\x62\xc7\x0f\x55\x9b\xd6\x8b\x4d\x27\xed\x21\xa4\xef\x70\x1b\x5e\x7d\x6b\x0c\x57\x89\xdd\x44\xa3\xdf\xf1\xbd\x18\xc1\x05\xfc\x5c\x17\xad\x1c\xac\x90\x7e\xc2\x45\x68\xba\x58\xe6\x07\x5e\xa6\xf5\x08\xbf\x24\x99\x47\x32\x8c\x08\xd3\xd8\x15\x76\xaf\x2e\x46\x86\x58\x32\x5f\x31\x03\x38\x6e\x3d\xc1\x01\xa6\xc3\xb5\x03\x13\x97\xda\x3e\xd2\x0c\xaa\xba\xc8\x61\xbf\x3a\x41\xbe\x3b\x34\x7b\xdc\xf0\x7b\x06\x3e\x39\x7e\xb2\xfa\x98\x17\xb9\xe4\xf5\x57\xca\x1b\xf6\x1c\xce\x03\x61\xb0\x0c\x36\x83\x71\xcd\x2c\x28\x64\xa0\x7c\x65\x7c\x89\x7f\x9e\x53\xf9\x3e\x27\x15\xab\xb1\x07\x26\x43\x87\x25\xca\x0a\xe0\x6f\x4f\xad\x39\x93\xa1\xe7\xf0\xb8\x4d\xdf\x58\x7c\xd2\xad\x44\xb8\x0c\xfd\x00\xa3\x90\xe7\xe7\xe7\x79\x7b\x09\x16\xc4\x5e\x27\x8b\x33\x84\xf0\xb5\x46\x63\x60\xeb\x64\xa8\xb4\xef\xf4\xa8\x66\x48\xfb\x72\x79\x3f\xfe\x39\x10\x56\x54\xe2\x1e\x34\x3f\x67\x35\x8a\x89\x77\x66\x4e\x46\xca\x11\x49\xcb\x1d\x93\xe6\x6f\x9d\xc6\xbc\x90\x91\x76\xd0\x19\xfa\x57\x13\xfa\x76\xcf\x1c\x33\x5a\x05\x1f\x45\x0d\x3f\x8a\xb2\xcd\x6c\xc8\x38\x8a\x11\x05\x48\xad\xf9\x50\xf2\xd3\x21\x3d\xb6\x53\x28\x4e\x18\x42\x20\xbe\x9d\x8b\xc1\xd5\xc0\xc7\x20\x48\xa5\x15\xef\x53\x36\x5e\xed\xdc\x32\x61\x5a\x71\x2b\x70\xb1\x2e\x8b\xb7\xd2\x10\xff\xd9\xe3\x9a\x60\xfb\x27\x7e\x59\x1b\xa6\x3d\x7b\x88\x3b\x1c\xcd\x9f\xdc\xc3\x00\xb6\x27\xb9\x24\x63\xf1\x91\x9e\xee\xca\xe2\x1d\xca\x2e\x54\x95\x82\x01\x62\xf6\xd0\x24\xa2\x60\x86\x0d\x8f\xa7\xa6\x9c\x90\x80\x8e\xd5\xf3\xf2\x65\xff\x6d\xf5\x74\xbf\xdf\xad\xf6\xaf\xeb\x6f\x9b\xd9\xfd\xa2\xbd\x20\x04\xe8\x70\xde\x28\x01\x4b\x01\x5a\x91\x8c\x7e\x57\x68\x93\x32\x4c\xae\xd1\x29\xd5\xdd\xc5\xb6\x58\xb5\xcf\x28\x63\x89\xc4\x08\x5b\x9e\x6e\x79\xfa\xcb\xa6\x33\xa9\x1c\x8d\x84\xbd\x90\xab\xa2\xac\x08\x02\x39\xbd\xb4\xbe\x42\x68\x4a\x15\x08\x01\x83\x24\xc9\x54\xdc\x2e\x95\x72\x7d\x5b\xd7\x5a\x34\x2e\x61\x5b\xd1\x47\x9d\x4b\xab\xdd\x17\xf9\xa3\x29\x0c\x9e\x44\xec\x70\xc6\xab\xfa\xae\x8b\xba\x25\xf8\x5a\x7a\x9d\x5e\xca\x5d\xf7\xc2\x20\x8c\xa4\x25\xf3\x59\x67\xfc\xd2\xff\xdc\xa0\x1c\x65\xd5\x5b\x8a\x53\x2a\x87\x96\x06\xb4\x8b\x58\x38\xc8\xd5\x9e\x3a\xd9\xf7\xa7\x9e\x44\x93\x50\x8e\x4c\xf0\x21\x2c\x1a\xa3\xef\x03\x0e\x6d\xb5\x72\xc1\x8d\x0d\x19\xce\x73\x81\x6d\xa5\xfd\x9f\x6a\x0e\x63\x77\x3a\x90\x5e\xf4\x0c\x55\x06\x86\x8f\xae\x3c\x70\x28\x65\x01\xf5\xb0\x31\xb9\x39\x82\x75\x69\xec\x5e\xb4\xb9\xa1\xe7\xed\xf2\xeb\x78\x50\xf9\xae\x42\x7d\xda\xe2\x04\xf9\xac\xa5\xa7\x50\xbe\xa7\x80\x6a\x6d\xd5\x55\x90\x3b\xee\x58\x55\x7e\x18\xb3\x1e\x6d\x91\xaa\x81\x1f\xeb\x9e\xcf\xa0\xfc\x88\xd4\x08\x36\x2d\x77\x37\xfe\x4d\xb7\xfd\x0d\x28\x33\x96\xbf\xf5\xdc\xaf\xd1\x73\xfb\x09\xc7\xe0\xa2\xd9\x57\x4d\x62\x6e\xdc\x58\xa2\x7c\xe1\x61\xe8\x98\x15\x1f\x80\xe8\xd3\xdf\xba\x03\x44\x72\x97\x97\x86\x17\xd4\x2e\x10\xc5\x5c\x6a\x20\x27\x7d\xcc\x66\x27\x31\xda\x83\xec\xee\xd2\x6a\xcd\x09\xc5\xbc\x00\x45\xad\x05\x54\x75\x27\xbe\xdf\xfc\x3d\x72\x4d\x07\xd5\x86\x32\x10\x18\xbd\x7d\xdd\xa1\xa1\x58\xe8\x23\x07\x94\x41\xc8\xa3\x44\xce\xb9\xcf\xa1\x7c\xeb\x3c\x88\x31\x47\x97\x9f\x8f\xa6\x57\xaa\xbb\x41\x50\xc8\x97\x64\x94\x9e\x79\xf3\x36\xad\x10\x53\xdb\x97\xd6\xc6\xe3\x8a\xe9\x18\xc3\x42\x71\xb6\xa2\xeb\x43\x6f\x7a\xfa\xf7\x03\xdf\x41\x23\xbf\x57\xf0\x51\x77\xa0\x73\x15\xf8\x82\x38\x78\x78\x5a\x36\x8e\xcc\xde\xc0\xa3\xd2\x22\x5f\x3d\x3c\xb4\xa3\x94\x8b\x1d\xfd\x4f\xc5\xdb\xb7\x4e\x94\xff\x8b\x1d\x5b\x85\x4a\xb1\xb8\x2b\xc0\x11\x06\x2f\xd7\xc5\x28\x05\xa1\x22\x16\xe1\xb8\x45\x7d\x28\xb9\xd6\x19\xec\x3f\x98\xb0\x3f\x1b\x8b\xd0\x72\x90\x13\xb4\x6b\x75\xae\x65\x71\xb4\x8f\xfc\x8f\xd1\x8e\xa2\x92\x40\xfa\x44\x04\x37\x2b\x4b\x7e\xe9\xc0\x0b\xa3\x97\x91\x44\x0c\x89\x46\x8e\xfc\xa7\x29\x3e\xed\xf8\x3b\x94\x77\x50\x57\x6b\x28\x9f\xcd\x7f\xdb\xbb\x48\x78\x80\xa0\x2d\xd4\x35\xbe\x89\x79\x32\x83\xb9\x0b\xb8\x69\xdd\xa5\xf2\x22\xb3\x81\xf7\xaf\xb8\x4f\xde\x89\x51\x88\x7e\xe9\xfa\x7b\x14\x07\x81\xba\xe0\x7d\x0a\xd4\x31\x4b\xe8\x0d\x2b\x20\x7c\x17\x37\x5c\x79\xa5\x28\x79\x9d\xcc\x51\x22\x20\x14\xd8\x80\x15\x69\xb5\xd9\x6e\x6f\x27\xb2\x55\x63\x68\xc8\x6e\xb5\x48\xb5\x59\xae\x88\xa5\xba\x27\xbd\x7b\xe5\xd5\x28\xe9\x78\x18\x25\xbc\xf1\x23\x60\xc3\x46\xfb\x77\x66\x5d\xdb\x7b\xe0\xc4\x1f\x3e\x3a\x33\x8a\xb0\x19\x18\x9d\xec\xfb\xb4\x3a\x75\x90\x55\xa5\xfc\x10\xcb\xa6\xf7\x8b\xf9\xf2\x79\xf6\xb4\xdd\xa3\x30\xde\xfa\x69\xd9\x82\xb4\x94\xe2\x92\xfb\xad\x50\x17\x82\x61\xa6\xb7\x68\x05\x5a\x20\x64\x73\xf6\xe3\xf9\x7b\x71\x96\x5d\x45\x4c\x69\xa1\x11\x99\x63\xfa\xa9\xda\x3a\x0a\x38\x0e\x47\xaf\xbd\x7b\x1d\x76\x25\x83\x1b\x2b\x66\xba\xb4\x06\x1d\xfc\xe0\x89\xa8\xc5\x6b\xfe\x38\x14\x19\x0c\x94\x51\x04\x30\x2f\x8a\x5a\xf9\xad\x7b\x18\x07\x64\xc0\x7c\x07\xfb\xb1\x78\x9b\x72\x9b\x7c\x1c\x60\x7e\x84\x08\x76\xc8\x55\x13\x2a\x7f\x7a\xed\x0f\x68\x15\x38\xb6\x2e\xfb\x69\xff\x1a\x84\x1e\x0a\x90\x1d\x0d\x81\x91\xe4\x53\x54\x44\x76\xb0\x4a\x94\xc9\x30\x6c\x4f\xfc\x7a\xa3\xec\xe3\xdc\x21\x74\x23\xeb\xd0\xee\xd1\xac\xf0\x52\xa4\x75\xb5\xaf\x3b\xa1\x3e\x01\x91\x4b\x68\x24\xc8\x3f\xd2\x62\xaf\xd2\x1c\xca\xa2\x3d\xe6\x79\x38\xe9\x30\x40\x11\x45\xf1\x3e\x82\x8e\x42\x1c\x42\xc8\x47\x62\x74\xab\xfc\x46\x53\x10\xc4\x3c\x11\xfd\x84\xd2\x16\x64\x09\x35\xe6\xec\x7e\x1b\x4a\xac\x0a\x48\x7c\x85\x9c\xf2\xc7\x73\x66\x99\xf5\x07\xd7\x4a\x64\x84\x0d\x46\x35\x7f\x6f\xdc\xd6\x63\x9a\xdd\xc2\x9c\x42\xa2\x93\x84\x32\x2b\x3b\xe0\xc7\x21\x97\x98\x19\xc2\x15\xb1\xfb\xa6\xb9\xa5\x11\xfb\x5e\x60\x2f\x59\x3d\x91\xc4\x06\x11\x50\x6a\xfe\x3f\x45\x9a\x3f\x00\xec\xed\xdb\x10\x51\x28\x4c\xc0\xd9\x72\x5a\x75\x1b\xf2\x95\x40\xd0\xbf\xff\x17\x8d\xc2\xf5\x62\x07\xe9\x47\x61\x47\xad\x8c\xfd\x96\xc3\x12\xc0\xb8\x9f\x64\x78\x7f\x32\x01\x84\xbd\x58\xc9\x84\x54\xc2\xbc\x71\xbd\xf2\x3a\xe5\x99\x11\x04\x1f\x2c\x75\x90\x20\x31\xfd\x8b\xde\x62\x3c\x7a\x5c\x15\x51\x05\xd9\xe0\xbc\x20\xaf\xa7\x99\xdf\x05\x80\xcb\x51\x0f\x45\x17\xe5\x5b\xfa\x01\xcb\x91\xbf\x0a\x3a\xf6\x2d\x99\xa7\x9d\x49\x8d\xfd\x45\x9c\xcd\xf0\x86\x74\x1c\x0a\x44\x59\xf2\xcb\x43\x51\x6e\xa1\xfc\x68\x1e\xe2\xf1\x69\xf8\x83\xda\xf1\x04\xea\x1b\x66\xf0\x01\xd9\x3e\xde\x9f\x06\xdd\xb8\xda\xd1\x54\x20\x79\x07\x38\x75\xc5\x62\xed\x32\x85\xda\xec\x75\x0a\xa5\xdf\x3d\x8b\x3d\x0a\x21\xba\xb3\x5b\xa8\x9f\xb1\xbc\x4e\x2a\xca\xf6\xb0\xc7\x13\xde\xf9\x1e\x33\x29\x3b\x91\x13\x3b\x02\x00\xeb\x46\x08\xb1\x32\x11\xff\xf0\xb6\x7d\x0e\x24\xcb\x28\x6d\x97\x5f\x47\xd6\x2b\x34\x8b\x15\xf6\x0c\x18\xf5\x67\x83\xfe\x30\x07\x83\x98\xda\x0e\xdb\x7c\x74\x13\x80\xb6\x07\x13\x4e\x89\x02\x03\x21\xea\x04\x1b\xcc\x80\x90\x85\xe8\xe0\x43\x7d\x68\xee\xcc\xfe\x39\x0a\x62\x2b\x22\xdb\x97\xa1\x99\x8d\x9c\x48\x1d\x85\x31\xba\x02\x36\x6d\x6c\x6a\xb3\xa3\xe7\x8f\x62\x07\x9b\xbf\x9b\x17\x88\x8b\x0d\x61\x9d\xe3\xfd\x73\xf0\xbd\x75\x9c\xc4\xe8\xd1\x71\x45\xbd\x68\xa3\x4b\x26\x52\x21\xd4\x70\x31\x9b\xf7\xc2\x5c\xcd\x43\x37\x68\x5d\x60\xa3\xf6\x43\x9a\xdd\xc3\xd3\xb9\xf2\x82\xae\xcc\x35\xb2\xeb\x5a\x78\x3a\xe2\x2d\xfd\x7d\xdd\x45\x36\x5a\x70\x6e\x51\x59\x3f\x8a\xf2\x9d\x64\xb5\xaa\x65\x6e\xe3\xe4\x76\x1c\x90\xce\xae\x4a\x2b\x4c\xb3\x83\xa2\x99\x73\x9f\x6a\x9d\xca\x73\x56\x5f\x46\x37\x24\x25\xf5\x55\xbd\x41\xfd\x98\x56\xf5\x24\xb8\x44\x43\x28\x28\x72\x32\x3c\x12\x7d\xdc\xf9\xd0\xde\x4f\xba\x9b\xd2\x71\x5d\x17\xf3\x28\x18\x1e\xe6\xd5\x26\x7d\x43\x8a\x31\xf3\xd9\xa5\xe3\x32\x81\x79\x0a\xe0\x65\x76\xb1\x54\x43\xf6\x58\x02\x60\x0a\xb0\x2d\x75\xfe\xe0\x21\xa4\xe3\x8a\x08\x97\x91\x46\xd5\xd8\x36\xc5\xf0\x9a\xd7\xe9\x50\x34\x5d\x3a\x5e\xcc\x30\xc0\x31\xb2\x83\x06\xb7\x32\x1a\xe4\x7b\x49\x18\xd9\xaf\x59\xf3\x34\x83\xf2\xee\xf2\x95\xd0\x97\x74\x7c\x4e\x5e\x51\x75\x3e\x5d\x91\x91\x99\x21\xcc\x21\x80\x17\x31\xf1\xdd\xf3\x0b\xa1\xf1\xbe\x02\xc0\x34\x27\x91\xde\x22\x12\xf9\x61\xe9\x77\xaa\xfb\x4e\x3a\x2c\x08\x3d\x22\x7e\x23\x51\xe8\x21\x81\x84\x74\x98\xa4\x8e\xb4\x87\xc5\xe2\xde\xb5\xaf\x96\xa9\x08\xd1\x4b\x8a\xd7\xbc\x82\xfa\xf1\x2c\xec\x91\x20\xf0\xd0\x43\x41\x94\xd0\x4a\xaf\xd3\x92\xe7\x07\x3e\x7a\x4d\x41\xe0\x21\x6a\x75\xcb\x33\xb8\x07\xae\xb2\x34\x87\xf6\x02\x71\x82\x1b\x07\x4d\x74\xec\x4c\xeb\x3b\x76\x57\xa4\x49\x71\x6c\x4f\x54\x4e\xaf\x2c\x8e\xed\x01\x13\x45\x3a\x33\x38\xf4\x01\xc3\x98\xe7\xd9\x1f\xfb\x87\xc5\xc2\xfe\x78\xc8\x5a\x76\x22\xa3\x8b\xd3\x72\xe0\x40\x3b\xaf\x22\xc7\xf0\x2a\x53\xc9\xed\xee\x7c\x59\xe6\xf6\x58\xcc\xa8\x47\xa5\x4d\xe8\x5a\x82\xe8\x6b\xc2\x95\xbf\x55\xc7\x91\x4e\xcc\x35\x3a\xfb\x3f\x40\xac\xf4\xae\x3c\x57\x5f\xf4\x2c\x49\x27\x11\x01\xe2\x4e\x34\xb2\x29\x60\xd2\xd4\x1c\xe1\x5c\x5b\x02\xad\xbf\xee\xe8\x0d\x8e\xbe\x34\x97\x3c\x34\xe0\xd9\x07\x00\x03\x23\x71\x47\x73\x91\x43\x88\xd3\xf5\x1b\xff\x0b\xee\x9a\x01\x97\xce\x9a\x49\x47\x30\x0a\x71\x56\xdb\xf5\x8b\xfd\x9b\x8c\xa9\x1f\xb5\xaa\x0b\xf9\x5e\x8d\xf8\x06\xa4\x23\x55\x8c\x6c\xa2\x77\xab\x55\xc7\x50\x21\x1d\x88\x38\xfa\xfc\x6d\x57\x57\x75\x9f\x56\xc5\x67\xfe\x52\xd4\x3d\xa9\x34\xe9\x00\xd7\x0e\x37\x10\x62\x4a\xe5\xce\xa6\xa1\x0c\xd2\xd1\x09\x91\xbd\x36\x9f\x64\x7b\xa6\xb6\xa5\x36\xa4\x91\x8e\x16\xd4\x9e\x79\x2a\x41\xa5\x63\xe8\xda\xf4\xc7\x71\x1d\xd7\xa7\xfa\x05\x39\xa4\x8d\x85\x85\x72\x5d\x14\x59\x0f\xec\xd1\x8c\xd2\x08\xb9\xad\x3f\x21\xaf\x2f\x06\x88\xdc\x69\x21\xd8\x51\x4c\x7b\xcc\x24\x91\x78\x89\x12\x41\xdb\xac\xb8\x01\xef\x93\xae\xc3\x43\x34\x35\x70\x2e\x0b\x2a\xbe\xb4\x89\x15\xe9\x3a\x12\xb0\xf0\xb2\x83\xca\xaa\x3a\x99\x23\xae\x47\xec\x94\x69\xf5\xba\xc4\xbf\x63\x17\xcb\x32\x0f\xd9\xf0\xbb\xb8\xae\xa7\xd1\x49\x98\x3d\xcd\xf7\x0f\xaf\x2f\xf7\x44\x2c\x39\xbb\xbf\xdf\x2c\xb6\x5b\xfb\x3b\xae\x26\x25\xe3\xfb\xd9\x5d\xd7\x67\x29\x5d\xcf\xd1\xd8\x67\xff\x69\xfd\xc5\x1b\xdd\x2d\xd2\xf5\x42\xc1\xdb\x4e\x5b\xc4\xf9\xb7\xd7\x48\x3c\xfc\x1c\xf8\x8e\x48\xe4\x69\x74\x87\x5e\xc2\xb1\x45\x85\x4b\xb3\x63\xb5\x08\xf8\xee\x22\x8a\xa4\x49\x8f\xfc\xe7\x9c\x9f\x8c\x78\x34\xd1\x1d\xda\x11\xe0\x2b\x63\xb1\xfb\x8d\xd7\x21\x33\xc7\xfd\xc0\x15\x24\x26\x59\xed\x6d\x67\xda\xbe\xea\xf7\x56\x48\xd7\x07\x9f\xb7\xd4\x59\xa8\x3a\xed\xd9\x43\xcc\x71\x43\xd1\x57\x75\x58\x9d\xda\x9b\x63\x31\x01\xfe\xd6\x45\x55\x0f\x2c\xba\x39\x1e\x04\x31\x66\x50\x9f\x67\x2f\x8f\xb3\xdd\x6e\xf6\xb2\xde\xac\xfe\xf8\xd3\xdf\xdc\xcf\xbe\x5b\x83\xe5\x06\xdc\xc3\x72\xe4\xdd\x62\xf6\xc7\x9f\xed\x1f\x9b\xd8\xc3\xf2\x21\x63\x1d\x60\x5e\x54\xc7\xa2\x59\x41\xb2\x3f\x2f\x03\xa0\xf6\xd9\x26\xb8\xca\xe1\x67\xbd\x27\x89\x93\x3d\x3f\xab\xb4\xde\xab\x42\xa2\x02\xcf\xd0\x4a\xb8\xa1\x47\x0d\x17\xa6\x61\x81\x24\xf0\x0d\x7f\xe2\x68\x64\x4c\x88\x68\x44\x96\xae\x1f\xb6\x1d\xe9\x4f\x9b\x2a\x37\x23\x23\xa6\x30\x0f\xb8\x2e\x8b\x42\xaf\xf4\xbc\xbc\x9c\xea\xe2\x25\xb5\x88\x28\xe9\x46\x49\xe2\xd2\x8f\x36\x16\xd9\x46\xbd\x5d\x29\x20\x74\xba\x08\x64\xf4\xdf\xf6\x0a\xdc\x41\x8d\x81\xf5\x6c\xbb\x6b\xaf\x2a\x88\xcb\x77\x0b\x99\xbe\x07\x92\x19\x4a\x6f\x05\xc5\xd2\x8d\x20\x0c\x49\xc0\x23\xad\xe1\x7f\xce\x6f\x5c\x8d\xf4\x2b\xa4\x1b\x9b\x2e\x0d\x22\x97\x32\xb7\x39\xa5\x87\x2c\xdd\x58\x53\x28\xff\x46\x45\xb9\x87\xf4\xa3\x9d\x93\x49\x24\x91\x2a\xbc\xc8\x17\x9b\xb9\xeb\x06\x01\xc6\x97\x57\xf0\xec\xd1\x0e\x30\xe0\xa2\xee\x62\x68\xe9\x26\x42\x52\xe5\xf2\x2c\x8e\x69\x7d\xc7\xb3\xac\x40\xeb\xb3\x7e\x9f\x64\x6f\xc4\x13\x80\x44\x7b\xaa\x22\xfb\xa0\xfc\xd2\xe0\x7b\x71\x3f\x46\x00\x41\x7d\x80\x2c\xff\xe4\x05\x96\x81\xda\x79\xcd\x75\xe4\x52\x83\xad\xe9\x18\xde\x16\x19\x6e\x46\x9d\x7d\x92\x8e\x83\x76\x43\xf2\x2c\x6b\x97\xd5\x8d\xd7\x2e\x13\x12\xe9\x99\x13\xbc\x71\x3b\x22\x99\x90\x2e\x24\x94\xa5\x79\xdd\xde\x23\x99\x33\x56\x40\x7b\xdc\x96\xd2\x05\xee\x84\x46\x43\xdf\x06\x6d\x2d\x32\x88\x4c\x0b\xd1\xb8\xd7\x57\x6b\x50\x47\x2e\xa2\xb6\x8c\x8e\xcd\xef\xb9\x7c\x28\xb0\x16\x34\xb9\xfd\x7a\x8e\xeb\x60\x42\x50\x03\x54\xa6\x90\xd7\xfc\x31\xd2\x14\x18\xfc\xe7\x5c\x51\x1d\x77\xa5\x8d\xb8\x0c\x91\xf8\x93\x8c\xcd\x8f\x91\xfe\x40\x73\x26\x4f\x0c\x41\x8b\xed\xdb\x1e\xdc\x9e\xe7\xc4\x0e\x02\xb4\x20\xaf\x7f\xb5\x57\x79\x6e\x20\xd1\xc3\xbf\xbb\x23\xc2\xd2\xe2\xa7\xbd\x41\x57\x02\xfe\xcc\xec\xed\xad\x34\x2a\xdc\xf6\x90\xa7\xb4\x6b\x28\xaf\x30\x59\xd3\xbc\x31\xa3\x1e\x46\x93\x27\xe8\x47\xf3\xb1\x3d\x4b\x07\x88\x5d\x38\x15\x45\x56\xed\x0a\xea\x8e\xb7\x97\xf4\xdd\x04\xdd\xa7\x1d\xd8\x80\x55\x7a\x8c\x49\xea\xdb\x39\x9c\xeb\xc9\x5e\xff\x66\x88\xa6\x5e\x88\x4b\x55\xc3\x71\x8a\x98\x50\x7a\x2c\x74\x69\x5a\x59\x1c\xda\x10\x43\x6c\xda\x5c\xdb\xc1\x1c\x5b\x16\x0f\xbc\x3a\x10\xc8\xf5\x17\x0e\x9a\x3d\x4f\xc5\xb1\x45\x95\xf2\x2e\x4c\xf8\xef\xdc\x3a\x2f\x60\x6e\x20\x3b\x4c\xfb\x60\xd3\xf1\x02\x4e\xeb\x2b\xeb\x89\x9b\x8c\x5e\x47\x00\x1e\x52\xa1\x9f\x8a\x66\x4a\x15\x85\x1e\xac\x50\x2f\xf4\x3c\x2b\xf5\xf8\x3b\x18\xf1\x82\x5f\xf2\x26\x4b\x2f\x8c\x18\x96\x10\x9e\x8a\x37\x1b\xd6\x7f\x99\x35\x96\x5e\x24\x23\x4c\x7c\x8a\xf3\xe5\x5f\x05\x32\x9e\x0e\x9b\xc7\xa4\x17\x4b\x6d\xf5\xb1\x88\xd0\x73\x7b\xad\x54\x3b\xba\x68\xac\xe2\x88\x08\x26\xff\x03\xb2\xb6\x3d\x48\xa3\xc5\x91\x30\x6e\x51\x82\xf3\xc5\x6a\x7a\x42\x70\xa6\x30\xc5\xa6\x8a\xe9\x82\x91\xf4\x44\x98\x90\x58\x50\x91\xf3\x1a\x10\x91\x64\xd2\x54\x1d\xa3\xff\xad\x2c\x97\xf4\x84\xe0\xd6\x7b\x78\xbe\xbc\x14\x16\x19\x19\xb2\x7f\x0c\xbe\xa7\xf4\x39\x8a\x86\xa3\xaf\xd5\xc3\x33\xfe\x02\xa9\x29\x3d\xe5\x3a\x48\x38\x46\x3d\x01\x8b\xfa\xf0\xcd\x96\x13\xa4\xa7\xe2\x08\xf3\xc7\xcd\xeb\x9c\xac\xcb\x9a\x71\x20\x7c\xc3\xd6\xd9\xb8\x20\x28\x4f\x32\x69\xf6\x3d\x0d\x24\x6b\x63\x6b\x07\x73\x5e\xaa\x2b\x00\x65\x7f\x9d\xfb\x8e\x03\xca\xe4\xc7\x29\x16\x18\xbe\x5c\xdf\x61\x10\x10\x45\x46\xf9\xd1\xf5\x8c\x7c\xfd\xcc\xbe\x63\x1a\xb4\xf8\xb9\xd9\xea\x5b\xa1\x9f\xdf\xec\x61\xa0\x6e\x4e\x2e\xe4\x53\x51\xd7\x45\xfb\x77\x4d\x8f\x79\x2c\x54\xaa\x1b\xbb\x5a\xeb\xa2\x44\x3b\x31\xba\x29\x5f\xc7\x40\xb9\xa9\xe3\xb1\xc8\x37\x20\x3a\xdb\xe4\xb3\x00\xd0\x0e\x8d\x45\xfb\x07\x6b\xb0\xab\x83\x48\x9f\x85\x0e\xfa\x38\xf7\xe9\x5b\x7a\xe2\x97\x5e\x99\xa6\x39\x46\x20\xcd\x59\x5d\xf3\x91\x48\x91\xf4\x99\xf6\x1c\xb3\x2a\xd6\xfe\xfd\x20\x8d\x2f\xfd\x20\x04\x2c\xd9\x7f\x6f\xb7\x30\x3f\x88\x98\xc9\x9a\x37\x9b\x88\x69\xe7\x18\xbe\xb8\x20\xa6\x88\x9f\x60\x40\x0f\xcb\xcd\x76\xb7\x5f\x6f\x96\xf3\xc5\x7e\x33\xdb\x2d\xda\x0b\xc5\x1c\xa9\xd1\x51\x3f\xae\x86\x2b\xd4\x95\x49\xc7\x0e\xef\x36\x90\x41\x64\x6a\x9c\x2d\x00\xcb\xa3\xa6\xa4\xe1\x3d\x84\x2e\x09\x16\x16\x39\x62\xe9\xb1\x7a\x31\x7a\xf2\x90\xa9\xa8\x25\xcf\xb1\x84\x67\x7d\x54\x91\xf4\xc3\xc8\x8f\xfa\x0d\x16\x77\xe7\x32\x37\x89\xba\x0d\x54\xf0\xf7\x58\xf7\xa4\x1f\x85\x04\x41\xb0\x54\x9f\xd3\x8d\xbd\xd2\x8f\x62\x6e\x69\xf6\xac\xad\x19\x14\xd6\xa5\x1f\xa9\x48\x18\x38\xcf\x77\xc0\x26\xd0\x09\x45\x93\xd1\x55\xe3\x44\x60\x0f\x6c\xe3\xe3\x8c\x09\x8a\xec\x10\x9e\x60\x85\x00\x65\xbe\x08\x01\x6f\x8e\x24\x8a\x61\x87\x5a\x95\xbe\xf5\x40\x88\x03\x68\xbb\x19\xc9\x23\x0f\x1b\x9d\x16\xbb\xc7\xc7\x5f\x81\x3b\xa4\xcf\x85\xc0\x80\x15\x01\x4b\x6b\x14\xf8\x69\x63\x69\x5f\x38\x0a\x7b\x28\xb6\xbb\xf9\x5d\xfb\x37\x19\x23\x39\x13\x6d\x06\xbb\x22\x83\x92\xf7\x24\x46\x46\xcf\x2c\xbd\x98\x85\x5d\x70\xf0\x0c\x2a\xe5\x3d\x30\xd8\x3f\x46\x15\x45\x73\x96\x4a\x08\xcd\x78\x2a\xd3\x9c\x68\x3a\x30\x54\xb0\x47\x15\xe0\xab\xf8\xf9\xf3\xe7\x68\x26\xe9\x88\x68\x98\x8e\x45\x06\xf2\x9c\x35\x31\x99\x3c\xe4\x45\x56\xbc\x5d\xfa\xfd\x4e\xd2\xd7\x89\x6f\xf1\x4e\x7d\xe9\xf7\xe1\x6d\x30\xc7\x09\xd1\xa0\x42\x29\x23\xcf\x7d\x86\x9a\xab\x56\x91\x58\x32\x27\x0a\x31\xb3\x63\xa2\x4d\xcb\x87\xd6\x78\x19\x8f\x90\xa9\x76\x58\x0c\x88\x75\x5a\x64\xe9\xcf\xb4\x7c\xdd\xde\xb7\x07\x44\x80\x1d\xb5\x44\xae\xdd\xf7\x86\x99\x23\xb8\x34\x22\x2e\xf3\xf2\xa2\xca\xef\x29\x7c\x4e\x08\x56\x49\xe6\x6a\x52\x72\xb1\xfa\x84\x36\xdc\x9c\x49\xd9\x4f\x30\x76\xf6\x89\x79\x91\x90\x66\xe2\x22\x90\x14\x1a\xf7\xb5\x30\x7d\xcc\xe3\xfa\xee\xe0\x5b\x32\x2f\x06\xf0\xec\xbe\x7d\x84\xd5\xb9\x9e\x9d\xeb\x03\xe4\x75\xda\x6f\x57\x90\xcc\x77\xe9\x9b\xbf\x41\x7d\x67\x60\x8a\x23\xc0\x99\x64\x8c\x45\x60\x3e\x00\x6a\x90\x3f\xa5\x55\x3d\x6c\x0e\x1e\x7d\x0b\x16\x71\x5c\x3c\xf9\xf9\x78\x4f\x04\x10\x97\x53\x1b\xd6\x33\x16\x77\xb4\x9f\x6d\xa2\xed\xab\x2c\x2b\x63\x10\x59\xa2\x4d\xc4\x5a\x50\x76\xa7\xea\x41\x2e\x86\x2e\x2c\x63\xc0\x13\xc3\xd5\x7a\xc7\xf3\x69\xee\x37\xc9\x02\x37\x46\x5e\x28\x62\xd0\x68\xe5\x37\x6c\x9e\x94\x05\xa1\x44\x54\x33\x7d\x30\xab\x31\xfe\xe5\x9d\x06\x2a\x8a\x93\x56\xf5\x4a\xa7\x6f\x7d\x65\xee\xc9\x55\xc7\xc2\x90\x8b\xae\x57\x74\x31\x36\xca\x2c\x8c\xb8\x6f\x3b\x37\x47\xd4\x39\x92\xc5\x8d\xbf\x4e\xb3\xde\x73\x7a\xea\x60\xf6\xb0\x66\x02\xba\x76\xc6\x61\x21\x73\x74\xeb\x49\x42\xb6\xc2\xb6\xd5\xae\x4b\xd0\xe9\x4f\x68\x62\xbf\xf4\xc8\xdf\x86\xba\x44\x38\x9c\x72\xf7\xf5\xc1\x7b\x7e\xd9\x0d\xa7\x3a\xf7\x1c\x5b\xf8\x35\x60\xf2\x7e\x79\xe1\x6b\xe7\x9a\x71\xed\x25\xe8\x77\x9c\xf8\x67\x8e\x4e\x69\x63\x80\x31\x0c\xb9\xde\x04\xae\xfe\x1d\x3e\x14\xd7\x1c\xf3\x6c\xcf\x77\xbb\xf9\x17\x99\x57\x26\x7c\x3f\x34\xc4\xc3\xc4\xcf\x7b\x6b\x18\x0b\x4d\xc3\xb4\x4e\xcb\xe3\x3f\x1b\x33\x69\xdf\x75\xe3\x4d\x76\x00\x9e\x79\x51\xd5\x63\x1e\x08\xc9\x64\x90\xb0\x76\xf7\x34\xe5\x82\xe1\xee\xc9\x54\x14\x62\xf8\xbe\x68\x91\xbc\x92\xa9\x44\x04\x86\x57\x18\x4a\xaa\x23\xf4\x25\x9b\x24\x03\xdf\x45\x2a\x06\xda\x2b\xcd\x15\xef\xcf\xcd\x17\x59\xee\x56\x37\xe6\xaa\x0e\x03\x6e\x4a\x5e\xf3\xb4\xbe\x5c\x09\x56\x0f\x6f\x5d\x4b\xc9\x78\x2b\x06\x03\x6a\x36\x4a\x2d\x31\x0d\x2e\xe6\x63\xcc\x8f\xec\x8a\xd7\x5b\xb2\x5c\x32\x70\xa4\x83\xb4\x15\xa7\x8c\x5f\x66\xf9\x65\x57\xa6\xa7\x6c\xd4\x97\x24\x03\x37\x22\xf5\xf7\x4f\xec\xd8\xf8\x4e\x0c\x17\xe6\x89\x03\xcf\xf5\xb1\xd2\xbb\xaf\x26\xa7\x98\x1d\xe5\x7b\xc8\x43\xb7\x3d\x14\xa7\x7b\xf8\xd9\x9e\x1c\x84\xc8\x22\x5e\xc3\xf1\x94\xf1\x71\x47\x94\x0c\x3c\x61\xb4\xfa\xcf\x97\x34\x9f\x8d\xc2\x92\xc0\x8f\x04\x37\x8b\xea\xb9\x31\xac\x2b\xfd\x08\x25\x6c\x31\x41\x6e\x7f\xc1\xe7\xa4\x45\xbb\x60\x7d\xa7\x32\x60\xdc\xc5\xf2\x48\xdb\xd1\xb7\xca\x2d\xe2\xf3\x0e\x0e\x3c\xd3\x84\x45\xb8\x85\xc2\x91\x01\xd3\xa4\xe1\xda\x98\x75\x73\xf3\xf7\x58\xaa\x6a\x7f\x39\xf4\x44\x42\xc5\xdf\x0a\xb6\xa7\x22\xaf\xcc\x06\x6e\xbf\x53\x10\x72\x0f\xa9\x79\xe8\xb5\x62\xff\xf7\x30\xab\x1a\x84\x10\x31\xb3\x59\xc2\xe9\x2a\x80\x1b\x7d\xca\xc8\x8b\x10\x94\xbd\xa8\x0f\xf3\xbc\xdf\xa9\x22\x83\x28\x71\xb1\xa6\x8a\xe9\xe1\x35\xbf\xb4\x39\xd7\x20\x52\x01\x6e\xd6\xf5\x54\xb7\xdf\xdf\xac\xb4\x98\x4b\x25\x91\x4a\xf4\xd0\xfd\xeb\x01\xae\x47\x63\xb9\x46\xac\x60\x25\x79\x3e\x64\xe6\x32\x30\xf6\xf6\x3d\x27\x8a\x21\xe5\x73\x89\xb9\xf9\x56\x51\x55\x06\x22\x0a\x50\xea\x1d\xdf\xdb\x8f\xa2\xcc\xd4\xdc\x2a\xe7\xc9\x40\xe8\x40\xe8\x4e\xad\xc1\xb8\xc7\xc3\x8e\x77\x33\x54\x3a\x32\x34\x4e\xf2\x7d\xf1\x99\xd7\xbd\x6e\x31\x3b\x42\x93\x58\x24\x62\x64\x8b\xfc\x5c\x19\xc6\x6b\x73\x58\x39\x61\x08\x3d\x6f\xe2\x78\xe2\xf9\x65\x48\xe3\x3a\xfa\x52\xca\x21\xd2\x1e\x01\x6f\x69\xde\xf2\x2e\xb4\xd7\x93\x66\x6a\xda\x50\x9b\xec\x8c\xf7\xe7\xe8\xc6\x95\x56\x91\x1a\xb4\x1f\x79\xbe\xbd\x06\x30\x81\x79\x8b\xfd\x81\x57\xdb\xf7\x34\xcb\xaa\xf9\x01\x46\xb4\x6d\x32\xd0\x3a\xc0\xac\x5c\x61\x48\x89\xf7\xff\x77\x86\x8e\x7b\x9f\xfe\xf9\x37\x1b\xa2\xf5\x64\xe8\x78\x04\xed\xa0\x40\x98\x44\x53\xb0\xa7\x77\x30\xbb\x43\x27\x22\x29\x03\x7d\xce\x65\x33\xab\xe6\x36\x99\x1f\x3a\x71\x44\xea\x32\x48\x0b\x6a\xd5\x2f\x06\x52\x83\x32\x74\xb8\x6f\x14\xcf\x31\xe3\x8f\xfc\x7d\xa6\x23\x7b\x72\xfa\x87\x0e\xa7\x76\xcf\x6d\x0d\x7a\x10\x40\x86\xae\x9f\xa0\xc1\xd4\x69\x96\x11\x82\xc6\xce\xb6\xa0\x97\xe2\xfe\xdf\xae\x90\x6e\xf9\x3a\xa6\x5b\xa1\x64\xe8\x46\xae\xb2\xec\xa2\x8b\xdd\xe3\xae\x40\x8c\xcf\x36\x1d\x95\xb1\x43\x4f\xc6\x09\xef\x5a\x97\x73\x28\x17\xbc\x1c\x36\x72\xc9\xd0\x53\x24\x3e\x77\xe2\x65\x35\xcc\x0f\x87\xbe\x47\x6a\xe5\x08\xfe\x69\xe2\x96\x66\x6e\x0e\xcf\xf6\x19\x17\xb6\xc7\xd9\x14\x1a\xda\xd8\xcb\x3e\xbf\x1f\x46\xd8\x30\xbe\xa7\x5e\xc1\xee\x52\xe7\xb1\x16\x92\x3d\x41\x52\xc5\xa1\xf1\xb1\x71\xf5\x56\x0f\x05\xd1\xed\x8c\x7e\x9d\x39\x24\xcf\x02\x26\xc9\x85\x6b\xf1\xa1\x28\x1f\xf9\xc7\x07\xe4\xd5\x6c\xd2\xd9\xb0\xe7\xfa\x4a\xbb\x56\xfc\x53\x66\x67\x75\xdd\x1e\x67\x47\x26\xc4\xa8\x4b\x80\xcf\xa9\x1e\x5e\x19\x06\x2c\xd6\x6d\x40\xd6\x43\xc2\xc8\x30\x08\x74\xc0\x5a\x4c\xc7\x3d\xaf\xc1\x6d\x0f\xc9\x00\x71\xde\x27\xac\xf0\x4e\xb0\xf0\x4d\xdf\x4f\xa0\x42\x1d\xde\xa0\xef\x7f\x24\xf2\x0b\x3b\x12\x12\x5c\x60\xeb\x7e\x87\x87\x0c\x43\xdf\xd7\x91\x4d\x7d\x66\xd0\x51\x03\xb8\x3d\xca\x5d\x19\x46\x91\xc0\x88\xe0\x23\x85\xcf\x7e\xb1\x36\x8c\x74\x6c\x25\xa3\x0d\xb9\xed\x50\x9e\xdf\x0c\x8b\x5d\x37\x36\xfc\x97\xf7\xf0\x01\xe5\xc5\x14\x99\xc6\x48\x0a\x3b\x5c\x73\xac\x90\x8b\x73\x99\x0f\x13\x29\x61\x12\xf9\x48\x47\x62\x4a\xf5\x9d\xf4\xa7\x0c\x13\x45\x9d\x6f\xc8\x9b\x78\x99\xf3\xea\x40\x6b\xef\x3a\x3d\x1a\x8f\x5e\x23\x67\x04\x9f\x7a\xe2\xe7\x5c\x1e\x36\x28\xde\x42\x58\xf3\xfe\xeb\xef\xb3\x25\xd8\x44\x60\xc8\xa5\x8b\x89\xc0\x96\xf0\xaa\x79\xb2\x22\x37\x22\xb2\xcd\x3b\x5d\xa7\x3f\x21\xa3\x3d\xd0\x2e\x76\x37\x1c\x5b\x32\xe1\x7a\x04\xd8\x57\x60\xf3\x00\xa1\x74\x88\xdb\xfc\x5b\x51\x28\x9d\x42\xa6\x08\x80\xf2\x55\x36\x20\x94\x4c\x21\xb6\x03\x0d\x1a\xee\x79\x0f\x45\xd9\xf1\x0b\x0d\x7f\x54\x85\x31\xf4\x74\x0d\x69\x02\x9d\x26\xd5\xa0\xaf\x78\x5d\x65\xa8\x62\x47\x1b\x93\x42\x3a\x25\xe4\x7e\x3e\x14\xe5\xd2\x34\x11\xae\x8b\x8a\x7a\x1e\xea\x29\xae\xe8\x7f\x0c\x6c\x34\x84\x21\x66\xcf\x30\xd5\xb5\x1d\xb6\xbc\xc9\x50\xbb\x61\x62\xa8\xbb\xe4\xfb\xa9\x68\x67\xb5\x8e\x5c\x0c\xc1\x67\x75\x0d\x95\xe1\xb8\xe9\xe1\xe2\x47\x76\x59\x27\x0e\x1a\xb1\x5e\xed\xb8\xbb\x92\x0a\x71\xca\x3d\x2f\x5f\x96\xcf\xb3\xa7\xfd\x8f\xc5\xd2\x1c\x8a\x1c\xae\x70\xca\x2d\x9f\x17\x7f\xfc\x61\xff\xe8\xfa\x1a\x4b\x62\x46\x0c\xd6\x94\xb2\xa6\x28\xa0\x65\xe4\x0a\x07\xab\xc9\xf7\x30\xc7\xb2\xce\x24\xe5\xd7\x97\xd4\xce\x32\x72\xa5\xc2\xcc\xc8\xdd\x6c\xa8\xb8\x24\x23\xcf\xf1\x30\x63\xbd\x37\x9f\xb1\x99\x72\x53\xed\x2a\xa3\x9b\xf2\x19\x11\xac\xe6\xf0\xb3\xde\x02\xaf\xda\x5d\x3f\xf2\x03\x95\x58\x1e\x78\xd4\xcb\x2b\xae\x13\xbc\x9d\x6d\x88\x7c\x1e\x61\x35\x60\x7f\x2a\xc1\x10\x68\x82\x55\x20\xff\xda\x7c\x45\xbe\x4c\x10\xdc\xbc\x4b\xa1\xbc\xe3\x55\x2a\xad\x2a\xc8\xa4\x59\x88\x98\xeb\x0a\x13\x7b\x97\x6f\x80\xfe\x4f\x6b\xe0\x22\x16\x70\x94\x59\x6f\x9e\x07\x0f\x6d\x6b\x38\x51\x5b\xb6\x19\x11\x78\x02\xd1\x30\x8d\xa3\x8d\x65\x8b\x1b\x5d\x00\x32\x0a\x15\x71\x9e\x7f\x2b\xc8\x79\x5a\x97\xc5\x7f\xa0\x0d\xb0\xa3\x48\x24\x44\x89\x74\xbc\x6c\x2f\x47\x61\xdb\xe8\x64\x14\x69\x86\xcd\xe9\x8b\xef\xf3\xf9\x81\xb7\x56\x36\x8a\x39\x95\x7f\x2b\xa8\xd7\x6d\x6e\xdf\x1c\xe3\x21\x20\x2f\x16\x41\x10\x2c\x62\x61\xb0\xcb\x47\xc2\xd7\x58\xa0\x7a\x81\xcf\xc7\xf4\xed\x00\x55\x7d\x97\x5e\xa3\xc5\x06\x97\x15\xa1\x0a\x3d\x0b\x74\xc7\xa2\x6f\x39\xed\xad\x44\x22\xa6\xe6\x23\xde\x38\x36\x94\x26\x47\x1f\xd6\xb2\xec\xda\x87\x90\xbe\x87\xa5\x38\xcc\x03\x40\xd9\xf9\xbf\x91\x0c\x02\x84\xe5\x65\x69\xd5\x11\xb1\xc8\x48\x46\x9e\x2d\xa5\x1c\x69\x6f\xd0\x65\x71\x54\xc5\x47\x6a\xad\x79\xa4\x62\x89\xce\xe1\xe2\x75\xb3\x1d\xac\x0a\x7b\x5c\x48\xfc\xa8\x17\x44\x03\xb6\x1d\x7b\x32\x52\x12\x1c\x53\xb2\x5b\xec\x1e\xaf\x5b\xf4\x65\x04\xb1\xf2\x49\x0f\xf7\x1e\x0e\x45\xa6\x3a\xb8\xac\x8c\xb4\x17\xd8\x02\x96\xed\x02\x18\x97\x91\x22\xed\x0b\x8b\x8b\xbf\x87\x0c\xde\xba\x9a\x42\xa4\x83\x58\x18\xd1\x98\xd9\x5b\x09\x30\xd8\xa8\xfb\x56\x6e\xa8\x76\x2c\x63\xc7\x93\x58\x28\x3d\x57\x2d\x30\x70\x94\xbc\x89\x1d\x01\x10\xb7\x90\xad\xb2\x67\xb4\xff\xed\x9b\x40\x24\x76\x03\xc2\xe8\x10\x12\x1b\x69\x9c\xb7\x12\x7a\x08\xf7\x2b\x55\xc2\xc1\xab\x89\xdd\x88\xf8\xbf\xb9\x52\x86\x09\x74\x9e\xa5\x5f\x51\xfe\xf6\x67\x56\xec\xca\x84\xbc\x69\x12\x2e\x25\xb2\xdb\xe9\xdc\x48\xec\x6a\xd7\xf2\x2a\xed\x53\x59\xe4\xe9\xff\x59\xb8\xff\x09\xca\x3d\x7a\x48\xbf\x8d\xcf\xf0\x4c\xca\x96\x57\xf0\x8c\x91\xef\x70\x80\xa7\x19\x56\xa8\x88\xeb\x69\x71\xe4\x69\x36\x4e\xbf\x0d\x6e\xd7\xe7\x21\xb9\x63\xef\xef\x05\x66\xa2\xdd\x29\x92\x8f\x78\x74\x92\x72\x90\xe1\xd1\xda\xa3\x07\x2e\x5b\x8a\x4e\x19\x33\x27\x41\xc2\xfc\x14\x2d\x71\x9f\x3c\x42\xc6\xcc\x0f\x1c\x52\x7e\xbd\xbb\xb4\x33\x26\x66\x3c\x12\x66\xaf\xac\x8a\x23\x60\xaa\xe7\x46\xda\x29\x0e\xdc\xc8\x8d\x4d\x15\xfb\x89\xb7\xb9\xa4\x38\x08\x1c\x9c\xf2\x5b\x9e\xd7\xb6\xeb\xd3\x1e\x92\x0e\x56\xe5\x30\x68\x5a\xac\xb6\x7d\xfd\xd2\xe9\xc0\x2f\x0e\x0c\x4b\xe1\x11\x1a\x4b\x9d\x8f\x9e\x22\xe4\x9e\x6f\xd4\x3e\xd7\x65\x7a\xe4\x8d\xc3\x26\x8b\x72\x9a\x30\xf8\xab\x7f\xcc\xf5\x22\xd7\xf1\x79\x1b\x42\x3d\x9c\xfb\x2e\xe2\xe8\xc6\x22\x97\x14\xc1\xdf\xc0\x00\xf6\x86\x85\x9b\x38\x12\x11\xee\x5b\x45\xa6\xa0\xaa\xbf\x75\x2f\x21\xe6\x4a\x9a\x45\x8d\x68\x6d\x0b\x29\x5a\x69\xcb\x5d\x71\x36\xd4\xa2\x5d\x84\x7f\xf5\x5f\xe6\x5a\x49\xe2\x20\x23\xf8\x9c\x9f\x4e\xa0\xda\x8c\xf4\xf2\x78\xba\x8d\x0e\x98\xfe\x9a\x9c\xc7\xe8\xb9\x7c\x22\x4f\x45\x77\xb7\xc2\xf7\x31\x6b\xf8\x92\xe6\xd0\x03\xda\xc5\x42\x01\x7e\x17\x62\x6d\x69\x77\xf9\x58\x72\xce\x22\xcb\xe4\xd5\x8a\x67\xcd\x8d\xd7\xd9\xc5\xec\xb1\x14\x3e\x56\x03\x95\xe5\x02\xab\xd0\xc4\x75\x41\x58\xac\x22\x1e\x50\xb8\x73\xac\x56\x7a\x22\x98\x8a\xc1\x25\x01\xdb\x13\xe9\xda\xf6\xd8\x88\x7e\x1b\x42\xbb\x07\x46\xcf\x73\xec\xe9\x89\xc4\x9e\x24\xb2\x4f\xdf\x20\x77\x1e\x8b\x26\xa2\xfc\x2f\x71\x15\xa3\x6f\xa2\x8d\x44\xc7\xbf\xa0\x2c\xee\x8b\x2c\xe3\xe5\x63\x71\x84\x75\xab\x31\x2e\x63\x2d\x88\x09\x2d\x3f\xbf\xdb\xbf\x25\x8e\x2f\x45\x3c\x4c\x05\x5d\x11\x3a\xcb\xc4\xf5\x08\x3c\xfc\xe3\x71\xb9\x5b\x3c\x2d\xb7\x3b\x92\x94\xc7\x5a\xab\xbd\x92\xcb\x22\x5c\xf5\x58\x6c\xe9\xbf\xf2\xc4\x0d\x39\x6e\x15\x07\x5e\x75\x82\x9e\xae\xbd\xb6\xe7\x2a\xcb\xda\xb8\x3c\xf2\x37\xe8\x93\x35\x8c\x1a\x67\x6c\xaa\x29\xf1\x04\x70\x43\x96\x49\x59\x8d\x65\x0d\xc7\x69\x03\x97\x30\xa6\x30\xb9\x97\xc3\xe7\x53\xf1\x09\x55\x3d\xab\xde\xa7\xb7\xfa\x24\x70\x22\x27\x6e\x11\xef\x04\x31\xcd\xfb\x18\xcd\x24\xd0\xa4\x2b\x70\xe4\xef\x37\x40\x05\x49\xc4\x62\x04\x78\x9e\x8a\x76\xab\x4f\xa2\xd8\xb7\x40\xe3\xb2\x06\x7e\xc4\xb0\xf7\xba\x52\x9f\x44\x3c\xc6\x52\x7f\xa7\xa0\x50\x58\x5e\x38\x99\x44\x5a\x39\x5d\x43\x84\x6d\x56\x42\x6e\x1f\xd3\x6e\x72\x33\x07\x9a\xc4\x22\x16\x56\x4b\x63\xb7\x9b\xf8\xc2\x89\xc3\x10\x46\xdd\xd2\x3d\xe9\x34\x9b\x12\x62\x91\x49\xe2\xb1\xc4\x30\xac\x4d\xd4\xdf\x92\x24\x8c\x91\x5f\x44\x59\x05\xdf\xa2\xe3\x21\x95\x49\x22\x09\xe1\x59\xf3\xf7\x36\x8b\x3f\xea\x58\x69\x06\x49\x6c\x9c\x3e\xf2\x9f\xa3\xde\x7e\x99\x24\xca\xc1\x0c\xc3\x9f\x9b\x7f\x7e\x15\xe8\x25\x5c\x40\x18\x19\x6c\x71\x06\x35\xa8\x87\xcc\x88\x86\xb5\x13\x8f\x03\xf5\xa7\x90\x15\x58\x56\xd5\xf9\x76\x8b\xc1\x75\xc6\xa9\xbb\x5d\x11\x51\x12\x9f\xc0\xb6\x63\xcf\x7e\xd2\xec\x25\xd2\x8b\x50\x9c\x6f\x29\x8b\x31\x4d\xc0\x7f\x97\xcb\x4d\x64\x10\x6b\x82\xe2\x9e\xf3\x9a\xa4\x18\xda\x97\x25\x85\xb4\xb5\xd0\xe5\xd1\x24\x29\x1b\xb7\xff\xe1\x9c\xcb\x41\x18\xdb\x3a\x42\xb7\xff\xc3\x5e\x52\xba\x5a\xb4\x5c\xc6\x02\xea\xbb\xcb\xb7\xfa\x72\xea\x0b\x94\xcb\x44\xc5\x2a\xe4\x1d\x25\xc1\x60\xef\x4c\x14\x0f\x99\x85\x00\xec\x8a\xd7\xe6\x34\x7b\x08\x9c\xd8\x01\x0b\x3a\x28\x53\x9d\xde\xe8\x0f\x49\x20\xa4\x16\x8d\xfd\x1b\xd4\xe4\x9b\x35\xbf\xb3\xe6\xa9\xda\x5c\xb5\xbc\x24\xda\x77\x91\x57\xfe\x58\xc8\xf7\x3d\x0a\x06\x2c\xf5\x4b\x51\x6f\x70\xaf\xbd\x01\xd3\x4e\xb4\x0e\x70\xfe\x50\x2b\x31\xd4\x3f\x80\x67\xf5\xc8\xd7\xe2\x6e\x92\x60\x4b\x18\xee\x5c\x8f\xbc\x54\x92\x9f\xcc\x3c\x6a\x47\x50\xa4\xb4\x9b\xcd\xb6\xfb\xf9\xea\x65\xb7\x99\xcd\x77\xed\x41\x1d\xbb\xd2\x80\xde\x56\xa7\x76\xef\xe3\x9e\x48\x98\xdb\x03\x83\x4c\x87\xab\xc3\x5b\xf1\x84\x40\xaa\x00\xcc\xeb\x3d\x17\x8a\x5e\x5e\xd1\xf2\xa9\x4a\xee\x87\x49\x8c\x45\xb2\x9f\xa7\xa2\x3a\x97\xb0\x85\xba\xce\x3a\x85\xba\xe9\x89\xca\xfd\x58\xf5\x58\xf4\xbf\x9d\x7b\x7d\x71\xd3\x7e\x4d\x2f\x1b\x7b\x6b\xe6\xf6\x3b\x5a\xec\xcf\x80\xf0\xcc\x26\x30\x9f\xad\x86\x1f\x90\x07\x4e\xe0\x8e\x2b\x1f\xeb\x12\xb6\xe9\x5b\x6e\xef\xff\x6f\x09\x22\x74\x4f\x15\xb8\x1c\x8b\x0e\x7b\x05\x35\xc8\xba\x23\x23\xe8\x0d\xf1\x35\x7e\xb9\xd9\xf2\x71\x07\xfc\xf8\x54\xc8\x51\x23\xad\xe4\x41\xac\x78\x07\x4e\xd8\x8b\x8e\xd1\x52\xf2\xd0\x21\x86\xa2\x66\x9d\xb4\x31\x90\x3d\xe6\x83\x2d\x4d\x12\x01\x6c\x7b\x20\x60\xd8\x3c\xf6\x9f\xf3\x5b\xdb\xf0\xc5\x43\x88\x41\xb6\xed\xba\x63\x3d\x8c\x1b\x9f\x2d\x72\xa8\x96\x66\x7b\x09\x79\xb6\xee\xf1\x77\x48\x1e\x79\x22\x48\x8c\xbc\x2a\x25\xc2\xc6\x0a\x0d\xa3\xeb\x85\x54\x57\xfc\x56\x10\x54\x5d\x14\xf5\xbc\x28\xa1\xbd\x5c\x24\x11\x75\xf8\xe7\xeb\x5d\xdf\xf1\xe6\x11\x4f\x10\x51\xd1\xbc\x99\xe1\x01\xa1\xe2\xa0\x35\x23\x58\x36\x29\x3b\x1d\x50\xc9\x23\x48\xb0\x8b\x20\x07\x50\xd5\x43\x9a\xf3\x2c\xfd\xab\xef\x53\xf0\x38\x4c\x62\x4b\x61\xb1\x85\xba\xad\x27\xf1\xc4\x0d\x64\x34\x0c\xfe\x08\x72\xfc\xdf\x76\x23\xdd\x78\x13\x49\xc4\x10\xc6\xaa\xd2\xea\x94\xf1\xcb\xbe\xee\xa5\xee\xec\x10\x1e\xc8\x60\xc0\x55\x36\x9e\x5c\x09\x57\x88\x0e\xf9\x40\x62\xc2\x96\x0e\x72\x04\xde\x1d\xae\x82\x04\x02\xd6\x23\xed\x68\x36\x56\x82\x19\x23\xb2\x9d\x37\x1e\x3c\xfd\xff\x97\xa2\x5e\xe6\xaf\x55\xfb\x71\xb8\xe7\x62\x11\xe7\x78\x79\x28\x8b\xbc\x5e\xd8\xae\xef\xf6\x78\x4c\x34\x1f\xa4\x2e\x40\x58\x9f\x89\x9d\x9d\x8b\x88\x23\xbd\xf8\x2e\x3d\xc2\x3d\x48\x7e\xb1\x75\xba\x3b\xf4\xf8\xca\xcb\x2f\x1d\xd8\xe1\x03\x09\x11\xe0\x56\x4e\xf8\xc5\x56\xcd\xb6\xef\x9c\xfc\x3a\x74\xe2\x42\x68\x4c\x36\x10\xe1\xc1\x80\xd4\x49\x72\x70\x13\xac\x3c\x0a\x5e\x41\x10\xdb\x38\xb8\xe7\xcd\x70\x48\x88\x78\xa0\x3e\x00\x4a\xf1\xb5\x67\x2a\x8e\x3e\xfa\x76\x37\x7b\xb9\x9f\x6d\x2c\xa8\x89\x6b\x48\x5a\xce\x4d\x93\xc6\xdd\xc0\xa9\xfd\x82\x0f\x45\xb9\xf8\x59\x97\xfc\xae\xc8\x15\x79\x6f\x55\xaf\xe3\x4a\x38\x9e\x40\x36\x90\xe6\x1b\x3e\xf0\x34\x5b\x9f\xab\xc3\x8f\x03\xe4\xdb\xba\x68\x02\xa9\xdf\xec\x30\xc3\x2e\xba\xaf\xa0\xde\xca\x03\x64\x98\x48\x68\xde\xf2\x14\x0c\x52\x38\x92\x12\x49\x14\x3d\x6e\x1b\xdf\xea\x40\x72\xd2\x83\x17\x2e\x1c\x19\x49\xd2\xfa\x3e\xde\xe2\x9c\x91\xc2\xd1\x81\xdd\x7c\x16\xd8\x62\x9a\x96\xea\xfe\x5c\x0e\xf8\x0d\xcc\x50\x17\x18\x16\x47\xbe\x01\xaa\x78\xd8\xe9\xf0\x9a\xa7\x75\xbf\xa6\x2d\x7c\x2f\x46\xf5\x1d\x30\xfc\x1f\x43\xf4\x86\xf0\x93\x90\x6a\x67\x14\x86\x0e\x92\xad\xc2\x17\x81\xf2\x5a\xe6\x0f\x91\x01\x8a\x61\x8f\x6e\x24\x48\x7c\x2c\x50\x55\x67\xb1\xca\xc9\x98\x4f\x9a\x45\x11\x3a\x1a\xbf\x1e\x9a\xea\xdd\xcf\xfe\xa7\x09\xfd\x18\xc3\x27\x2c\xee\x2d\x8f\xa7\xd2\x72\xe6\x9c\xa9\xa8\xd1\x9b\x34\x22\x12\x0e\x42\x53\x51\xc2\x7f\x39\x5f\xb5\x8f\x12\xe9\x18\x75\xf8\xee\x77\xf3\xf9\x7e\xf9\xb4\xfa\xb1\xb7\xa5\x54\x11\xfb\x0c\x8d\x3e\xd9\xa5\x67\x5e\x96\x69\x17\x9a\x89\x24\x16\xbc\x83\x4d\xcd\x0f\xfc\x78\xaa\xb0\x0b\x65\x2a\xc5\x24\x9a\xcd\xa9\x0b\x82\x61\xa0\xf3\x75\xb5\xe8\xa6\x52\xee\x82\x87\xc4\xdf\x64\xb7\x54\x24\xf5\xfa\x02\xec\x83\xca\x7d\xb8\x41\x17\xba\x9e\xf3\xd3\x32\xef\x9b\x73\x21\xdd\x20\x26\xc6\x49\x7e\xd9\x14\x17\x9e\xd5\x97\xf6\x50\x14\x20\x9d\xfc\x36\xfd\xb9\xad\x79\x63\x27\xd4\xdf\x13\x44\x92\x4d\xe4\x18\x91\xee\x18\xa1\xaa\xfa\xed\x54\x66\x88\xf2\x85\xc4\xce\x1b\x50\x69\x2b\xc2\xf1\x72\xbd\x9d\xd9\xe1\xb1\x47\x7d\x3e\x86\xc3\xb9\x0f\x4a\x14\x2a\x89\x6d\x16\xfa\xa1\x4c\x21\xc7\x8d\xe7\xad\x89\xae\xae\x4a\x43\x42\x09\x8d\x80\x10\xd4\x7f\x86\xea\x7c\xec\x16\x2f\x70\x97\xab\x11\xa8\x7c\x77\xd5\x4a\x6f\x06\xeb\x40\x24\x4e\x4b\x14\x87\x8b\x9b\xee\xab\x87\x2d\x11\x3a\x22\x44\x0e\xe6\x36\x9a\xbd\x7a\x02\xa7\x21\x34\x30\xcc\xe7\x16\x27\xea\x08\x9c\xdb\xc0\xc7\x5c\x45\xba\xbe\x72\x55\x9f\x60\x36\x2d\xf2\xe7\x36\xb1\x82\xcd\x79\xd4\x56\xda\x82\x6e\xa7\xb8\xe0\xa5\x74\x8d\xe0\xe9\x1b\xd4\x1f\x3c\x3b\x8f\x81\x40\xd2\xf3\x5c\x4b\x2c\x8a\xd9\x53\x6a\xc5\x30\x07\x7d\x87\x39\x49\x97\x39\x99\xac\x83\x8c\xaa\x8f\xd2\x8f\x14\x01\xc1\x0d\xa9\xfc\x94\xdc\xb9\x94\x7e\xec\xb8\x04\xfa\x47\xfa\x20\x13\x11\x8f\xae\x14\x2b\x53\x45\x2e\x7e\xa6\x6d\x69\x44\xfa\x9c\xfa\x50\x0f\xbc\x42\xc5\xa9\x55\x3e\x2f\xf2\xaa\x4e\x6b\x7c\x47\xeb\x22\xcb\x4c\xfd\x7d\xf8\x8b\x8c\xf1\xc8\xeb\x5a\xf4\x70\x56\x77\xdd\x03\x76\x50\x48\xad\xd3\x5c\x29\x54\xc3\xab\xa1\x1c\xf7\x75\x48\x06\xcc\x32\x8e\x1b\xf8\x4b\x7b\xb6\x76\x40\x75\xba\xaa\x77\xe7\xab\x3d\xd6\x0c\x0c\x42\x07\xd9\x43\xee\xf8\x7b\xfd\x80\x74\x94\x97\xab\x8c\xfb\xf0\xee\x03\x45\x2d\x6f\x55\xdd\xac\xaa\xe1\xd5\x42\x27\xc1\xb2\xe1\xf3\x05\xc3\x09\x84\x83\xda\x43\x91\x8f\x44\xa8\xdf\x10\xf1\x98\xdd\xac\x20\x9b\xe1\x91\x93\x20\xf9\x04\x19\xaa\x5b\x2e\xd8\x38\x03\x2f\x23\xc6\x7d\xd2\x93\xed\xcb\x41\xa2\x52\xd3\xe8\xb3\x47\x89\x83\xba\x7a\x5b\x6c\x92\xda\x75\xd8\x42\x19\x29\x81\x70\x24\x99\x01\xcf\xcf\xa7\x45\x59\x16\x28\x37\xff\x75\xcd\x4d\x26\xae\x32\xa9\x9a\x5c\x91\xd0\xc7\xcd\xac\x8a\x4c\x98\x2b\x42\xbb\x7a\x2d\xc0\xb6\x3d\xe6\xe3\x4c\xb7\x85\x6f\x03\x29\x9b\x66\x19\x93\x32\x01\xe2\x0f\x79\x9e\xfd\xb1\x5f\xcf\xfe\x5c\xbd\xee\xf6\x0f\x9b\xd9\x7c\xbf\x5b\xad\xed\x15\xb9\xab\x55\x47\x62\x42\x5c\x37\x9b\x73\x36\xc1\x55\x3c\xb8\xb2\x08\x5d\xec\x98\xdb\x80\x82\x23\x56\xaf\x29\x1e\x1f\x75\x7c\xd8\xd1\xb1\x46\x1f\xe1\xa3\x4d\x8f\x5e\xbd\xaf\xbf\x93\x22\x31\x57\x93\x71\x00\x84\x8e\xc7\xa8\x85\xb4\x35\x8a\xe2\xbf\x63\x82\xbe\x81\xed\x91\xaa\xed\x19\x7b\x4b\xe5\x88\x33\xdd\xbe\x33\x08\xdc\x40\x19\xc5\x89\xe7\x34\x1f\xab\xb2\x49\x09\x10\x60\x5d\xfd\xb8\xb7\x75\xb2\xa7\x54\x43\xc7\x27\x22\xa5\x76\x12\x5c\xe6\xf0\xd6\x57\x63\x92\x52\x07\x24\xa5\x9c\x36\x01\x3f\x1e\xe9\x51\xf1\x0f\xdf\xaa\x72\x84\xe7\x99\x84\x08\x96\x0d\x07\x29\x7b\xe5\x48\x40\xff\xc8\x30\xe8\xbe\xe6\x4d\x80\x57\xb5\x61\xa1\x72\x1d\x97\x87\x2d\x94\xbb\xac\xef\x79\x4b\xd2\x27\x95\x17\x11\x15\x14\x57\x6a\xd0\x6c\x35\xba\x03\x4f\x83\x46\x2e\xbf\xb4\xa8\x8b\xf2\x2e\x2d\x90\xe3\xb0\xf7\x3c\xca\x4f\x42\xe5\xda\x3a\x27\x32\x52\xf7\xea\xbf\xc3\x35\x10\x5f\x47\xf0\xca\x57\x31\x92\x4d\x36\x56\x0e\xe4\x54\x4d\x7c\x30\xe1\x95\xaf\xb5\x45\x7d\x37\xab\xd2\xc0\x2e\x07\xac\x33\xc3\x13\x98\xcb\x10\x07\xfc\x96\x7e\x00\x6a\xe5\xda\x1b\x67\x01\xc7\xaa\xf2\x23\xfa\xbc\xdf\xb9\xbc\x9e\xd6\x8a\x45\x89\x6f\x4c\x7c\xf3\xec\x50\x97\x56\xd6\x42\xaa\xc0\x89\x62\x43\xa4\xb3\x7f\x4f\xf3\xb7\x3d\x1f\xcc\x21\x15\xf8\x3e\x37\x09\x64\x2a\xe6\xb5\xe8\xce\x76\x00\xb3\x70\xca\x39\x3f\x71\x99\xd6\x23\x0f\x5d\x05\x89\x17\xba\xb6\x58\x8a\x7d\xb5\x3d\xe1\x8d\xe6\xb0\xf0\xa9\x5a\x8b\x5c\x35\xd8\x1b\x4b\x94\x8a\x66\x40\xe8\x68\x64\x45\xfe\x4c\x73\xd4\x9f\x9e\xec\x0f\x54\xa1\x2b\x6d\xda\xed\x5b\x51\x28\xf2\xc1\x07\x6b\x46\x45\x71\x82\xed\xba\xd4\x19\xdd\x5e\x67\xd8\xa3\x7e\x2b\x99\x62\xae\x11\x07\xd4\xe6\xd3\x6c\xf0\xc8\x3f\x33\x21\x7a\x26\x55\x1c\x13\xb7\xc6\x47\x0a\x9f\x36\x8b\x6b\xeb\x32\x1d\xb5\xae\x54\x89\x24\x30\x20\x75\x3e\xce\xa1\x4e\xb5\x6d\xb7\x18\x5e\x90\x87\x24\x5c\xb7\xe6\x79\x2a\xdf\xaf\xbe\x30\x97\x21\x1a\x50\x14\xd1\xb5\x17\xe7\xc0\xcd\x8b\xad\x57\xa7\x6f\xfc\x6b\x56\xf7\x2b\xa3\xac\x04\x63\x86\xcb\x00\xc9\xd7\x17\xdd\x92\x55\xa1\x8b\x31\x8b\xe5\x03\x6f\xa5\xd8\xbe\x7e\x75\xaa\xf1\xdc\x87\x44\xba\x37\xac\xab\x3d\x41\x85\x48\x4b\x35\x7f\x5c\xcc\x7f\x5f\xaf\x96\x2f\xbb\xfd\xef\x0b\x4b\x7b\xa0\xc0\x8d\xa9\x59\x92\xda\x5b\x06\x53\x06\x62\x22\xb4\xc3\xbd\x89\x12\x0b\x2b\xbd\x03\x4e\x0a\xee\x46\xbe\xbb\x1d\xcc\x43\x9d\xf4\x9a\x45\x8c\xb6\x42\x3f\xa9\xab\xb4\x17\xe2\x1c\x5c\x9c\x0e\x65\x91\xef\x30\x0b\xd1\xba\x8f\x4a\x33\x1f\x65\x84\xb8\x52\xfb\x13\xb9\xaf\xb6\x94\x5d\x15\xd9\x8d\xfa\xb7\xd2\x41\x88\xa8\x44\x4d\x19\x9e\x1b\xc5\x58\xa5\xc1\x51\x8d\xaf\xf2\x08\x59\x66\x53\x44\xe0\x40\x1c\x19\x92\xe3\xe2\x5c\xaf\xae\x33\xef\x83\x9f\x02\x47\x0b\xec\xfa\x68\xa2\xe3\xd6\x4b\xfb\x91\xd6\x87\x01\x55\xc1\xe8\x24\x57\x2a\xe9\xf7\x94\x9a\xd0\x21\x58\xe9\x59\x96\x61\x34\x6e\x4d\x04\x78\x8c\x88\x12\x28\x02\xef\x7b\x19\x76\x80\x20\x04\x9d\x25\xe1\x5a\xbc\xbd\xb5\xe7\x0a\xc1\x6c\x6b\x4f\x91\xe6\xf8\x3b\xd5\xb4\x15\x07\x4f\xb9\xb8\xf4\xde\x0b\xd0\xf6\x7c\xdf\x53\xb8\x0f\xcd\x72\x75\x28\x79\xdf\xa4\x83\x2f\x09\x30\x6d\xeb\x9c\xc4\x77\x34\xf2\x8a\x81\x31\x7a\xbb\x34\x6a\xb4\x91\x6e\x6f\x41\xa3\x81\x25\x1c\x43\x97\xdf\x7f\x9f\x4f\x40\x53\x80\x29\x87\xf5\x5a\x3b\x9a\x40\x22\xbb\xd1\x22\x02\x01\xf7\xd0\x57\x42\x0a\xa5\xca\xab\x27\xfd\x0e\x3b\x56\x4b\xa4\x0f\x7b\x5d\x12\x7b\xce\x2f\xc3\x48\x08\xdd\x00\x6b\x2d\xeb\xab\x76\xdc\xe1\x95\x43\xe6\x73\xe2\xad\xfc\x80\xac\x38\x41\xb9\xcf\xe1\x73\x5f\x11\x82\x69\x70\xc5\xc8\x89\x4d\x4b\x42\x9a\x35\x0b\x6f\x59\xa1\x76\x80\x1c\xbd\xd8\xd8\x57\x9e\xe9\xa8\xba\xe2\x11\x9c\xa2\x90\x96\x90\xb0\x90\x25\x6d\x5d\xf3\x0d\x5e\x37\xcb\xd1\x35\x13\x0e\x98\xd8\x7d\x81\xcf\x7b\x98\x90\x7e\xfc\x9b\xa8\xb9\xff\x77\xc9\x4f\x48\xa4\xc4\x06\xa6\x6f\x50\xcf\xd3\xba\x15\x1a\xbf\xf1\x42\xb9\x1f\xe2\xbd\xbe\xa7\x59\x76\x63\x42\xf3\x08\x30\x98\x44\xc8\x5a\x9a\xbf\xf5\x6c\xb4\x1d\xa1\x42\x6c\xe5\xca\x08\x37\x6b\xff\xaa\x09\x05\x31\x7f\x5a\xbd\xde\x3f\x34\x8e\x7d\xbb\x16\xa5\x4b\xd4\x2a\x9b\xd5\xd3\x62\x7f\xbf\xdc\xee\x36\xcb\xbb\xd7\xdd\x6a\xd3\x1e\x17\x32\x34\xd9\x59\xc2\xe2\x56\x8d\x5d\x1f\xde\x96\x04\x40\x9e\x98\xa1\x54\x81\x33\x1e\xa5\x89\x90\xe8\x5c\xa9\x5d\xb1\x18\x57\x87\x40\x79\x12\xfd\x0a\x2c\x21\x71\xd9\xb6\x35\xcc\x6e\x18\x1b\x95\x48\x42\x76\x9c\x71\xdd\x5d\xad\x53\x25\x48\x1a\xe1\xc4\x2f\xff\x3c\xf3\xb2\x86\x12\x13\xe3\x13\x8a\x83\x12\xc0\xa3\x98\xf9\x0d\x61\x52\xc6\x27\x6b\xed\x3d\x40\x08\xf8\x1d\x2d\x71\x26\x39\x02\xa0\x76\x8d\x69\x87\xe9\xa0\x62\xfa\xa6\x41\x78\xcc\xef\xd8\x8a\xb7\xdb\x39\xa8\x33\xed\xdf\xb6\xc9\x66\x30\xc3\x01\x9c\x80\xd8\x98\xb6\xe7\x13\x94\xe7\x6a\xec\x2b\x03\x80\x40\x28\xfe\x16\x78\x29\x0f\xcb\xf5\x66\x12\x34\x0a\xda\x4f\x10\x32\xd3\xf6\x5e\x10\x94\x7c\x72\x1b\x05\x1d\x13\xcb\xc3\x1b\xd4\xcf\xfc\xe7\xcd\x30\x1a\x34\xd7\x5c\xf4\x79\x22\x91\x5e\x8b\x2e\xf5\x50\x94\xe8\xa4\xc2\xc8\xb6\x6b\x47\x29\xca\xaf\xa3\x72\xc0\xdf\xeb\xf9\xd7\x0e\xb8\xd8\xf0\xbe\x83\xb2\xe4\x65\x7a\x3e\xf6\x36\x53\xed\x46\x01\xd6\x6d\xdb\x6e\x0f\x29\x86\x71\x8d\xf6\xc0\x47\x36\xd3\xaa\x28\xeb\x5e\x16\x53\xb3\x44\x12\xb1\x3e\xb4\x4c\x54\x5f\x36\x5f\xea\x20\x49\x34\xd1\x51\xbd\xe6\xe9\xcf\xeb\x62\x86\x0e\x5d\x07\xf9\x51\x5f\xf3\x0a\xea\xd9\x1b\xe4\x8a\x4f\x7e\x10\x1d\x06\x41\x2c\xbb\x46\x9e\xe7\xd4\xce\x36\x1d\xc6\x84\x7f\x34\x17\x18\xd9\x00\x1d\xc6\x1a\xb3\xdd\xd8\x3e\x6f\x05\x63\xdb\x73\x85\x8f\x09\x3e\xfa\x22\x77\xbc\x02\xca\x27\xfd\xad\xd9\xa9\x23\x83\x88\x9d\xdf\xfd\xd1\xdf\x18\x75\x24\x42\x2c\xd9\xc3\x31\x6d\xd6\x47\x35\x37\x1b\xe3\xf4\xb7\x8a\x84\x72\x84\xe9\xf1\x4e\x4b\x58\xe4\xc5\xf9\xed\xb0\xf8\x79\x7a\x28\xca\xbb\x26\x10\xb9\x62\x45\xd4\xb1\x1f\xfa\xb6\xee\x20\x8b\x36\x27\xa1\x79\x1c\xd9\x6c\xf6\x5d\x71\xce\xab\x05\x2f\x1b\x7f\x7e\xe4\x3b\x6b\xce\xa9\x77\x97\x0a\x84\xd7\x9d\x50\x5a\x38\x24\x15\x6f\x35\xea\xb0\x57\xe6\x9e\xd7\xfc\xb1\x97\xcc\xe9\x12\x16\x57\xa1\xfb\xe8\x6a\x0c\x10\xb1\xf2\x9c\x66\x59\x57\x3c\xd1\x22\x21\x3c\xf0\x47\x61\x0d\x44\x6f\xbf\xe9\xcd\x39\xa1\x18\x0b\xda\xde\x99\xb1\x24\x95\xd4\xb2\x09\xb0\x9a\x97\xd1\x2c\xa6\x14\xaa\xdf\xc1\x26\x87\xb5\x14\x0e\x1a\x77\x4e\x92\x70\xf0\x40\x04\xa9\x83\xfa\x94\x56\x10\x59\x07\xe9\x91\x97\x6a\xce\x4f\xf3\xc7\x87\xd1\x6f\x80\x43\xa8\x37\x64\xe7\x26\x67\xe3\x76\xde\x46\x43\xac\x11\x56\x3b\x2b\x3b\xb6\x05\xfb\x6b\xc0\x7d\xc4\xbe\xde\x3d\x3d\xcf\x2d\xbe\x5e\xeb\xc8\x41\x61\xcd\x66\x17\x58\xf3\x73\x5b\x5b\xd3\x5a\x73\xa2\x49\x38\x14\xa7\x6d\x5d\x94\xf0\x02\x3f\xeb\xa5\x99\xf9\xca\x71\x84\x23\xbb\xb4\xfe\x3d\xa8\x71\xd3\xb6\x19\xe7\x3a\x8e\xd1\xa1\x24\x26\xc7\x61\x2f\xfc\xe4\x67\x53\x8e\x2b\x23\xf4\xdb\x5a\xbc\xf6\xae\xb8\xef\x31\x2e\x4c\x46\x14\xca\xf1\x02\x1e\x25\xb6\x89\xee\x0d\x46\x37\xe2\x25\xc4\xc2\x60\x3f\xc8\x4c\x7d\xa4\x55\x71\x43\xab\x5a\x39\x9e\x72\x6c\x95\x1b\x9b\xb6\xfb\xa6\x43\x39\x1e\x30\x82\xa6\xf0\x4c\x12\x4c\x8b\xda\xf1\x66\xb9\xfa\x06\xf5\xba\x84\x2c\x3d\xa6\x39\x2f\x2f\x8d\xc3\xbc\x81\xaa\x6f\xbf\xcf\x5d\x13\x49\xe3\x48\x92\x82\x5a\x33\x13\xaf\x2b\x93\xca\x61\x9e\xc4\x04\xc9\xb7\xf4\xad\x9f\xd3\x50\x0e\x4b\x3c\x8c\xb7\x86\x89\xea\x49\x63\xa1\x1c\x8b\x12\x6d\x8c\xe0\x1d\xd4\x9f\x00\x79\x73\x63\xd5\x6f\xed\x71\x81\x77\x41\xb9\x4c\xeb\xd0\x20\xa3\x48\x6f\x8b\x53\x4e\xc8\x39\x52\x11\xfe\x68\x6b\xef\x43\xe0\x80\x72\x42\x88\x90\xed\x63\x3b\x5f\x6d\x16\xfb\xcd\x62\xbd\xda\xec\xf6\xdb\xdd\x6c\xb3\xdb\xef\x96\xcf\x0b\x3b\x2c\x0a\x04\x5e\xa8\x2f\xbf\x6f\xe6\xb0\x72\xa2\x84\xc5\x66\x87\x3f\x16\xa8\xf4\xbb\x4d\x73\x09\x4f\xbc\xaa\x1f\xfb\x0d\xb1\xed\x70\x8e\xe9\xf1\x3f\x77\xeb\xd9\x9f\x5f\x20\xa7\x94\x13\xc7\x91\x67\x7f\xf5\xbe\xb0\x34\xa5\xca\x49\x22\xf0\x6c\xb0\x39\x7e\xa0\x44\xbb\xa8\x4d\x02\xa9\x2a\x4c\x4f\xc0\xde\x1e\xe3\x0e\xc4\x44\x89\x53\x93\x62\x9d\x28\x7a\x99\xf9\xd1\x37\xe0\xc0\xb0\x29\xbb\xf9\xd2\xe5\x10\xd5\x36\x1e\xa9\x63\xcc\xec\x9d\xf8\x65\x72\x6b\x53\x8e\x08\x09\xc5\x5e\x9d\xc5\x7e\x5a\x2e\x54\x39\x32\xf4\x9d\xc8\x16\x45\x16\x3f\xd3\x71\x82\x50\x39\x92\x4b\xa4\x4b\x3a\x9f\x28\x6d\x71\x5d\xa1\x50\x8e\x94\x0c\x1b\x85\x4a\xf8\x80\xb2\x82\xed\x29\x33\xe2\xde\x94\xca\xe9\xd3\x33\xff\x36\x3c\x13\x02\x85\xbf\x6f\xd8\xd6\x98\x7d\x69\x10\x72\xb4\x67\xe8\x80\x2e\xe7\xab\xdf\x7a\xb3\x5d\x2b\x4e\x7d\xd2\x79\x9d\xd6\x97\x1e\x77\x81\x72\x1d\x8f\x21\x87\x80\xc8\xb8\x7c\x47\x1a\xca\xb2\x3b\x94\x20\x45\xa2\x01\xfb\x62\x98\xff\x3a\x41\xad\xac\x5c\x37\x21\x4a\xdf\x26\x94\x2f\x51\x53\x63\xfa\x63\xb9\x2e\x24\xc8\x5b\xf4\xd9\x6c\x61\xf8\xbc\xf4\xc5\xaa\x75\x9f\xd1\x5b\xb9\x5e\x22\x48\x73\xba\x99\x97\x0f\xb6\xb5\xb3\xea\xed\x53\x68\x37\xec\x2b\x77\x3d\xee\x38\x2d\xf6\x4a\x73\x09\x4b\xb5\x5f\x6c\xe6\x57\x14\x25\xca\xf5\x5d\x8e\x5b\x0b\xf2\x3e\x5a\xfc\xf2\xe2\x67\xdd\x78\x29\x22\x83\xb6\x6e\x6d\x86\xb3\xc4\x48\xe6\x16\xc6\x15\xbf\x81\x33\x18\x3e\x26\xd3\xa4\x2b\x68\xe1\xab\x43\xee\x11\x33\x28\xf0\x25\xe2\x92\x1b\x8f\xa2\x75\xb4\x95\x1b\x40\x82\x0e\xe5\x81\x57\xcf\x69\x7e\x77\x56\x6f\xb7\xa9\xc0\xda\xe7\x0f\x9d\x08\xfd\xa5\x66\x33\xdf\x9c\xab\xc3\x2f\x3b\xf4\x94\x1b\x2a\xc0\xd8\xb5\x30\x84\x81\x8d\x97\x0b\xf5\xe8\xc3\x86\xda\xc5\xc8\xe8\x9c\x13\xfb\xf3\x14\x4d\xa3\x72\x23\xcf\xc7\xc2\x10\xce\xa1\x96\x33\x4f\xb9\x51\xc8\x90\x11\x89\xf6\xb2\x56\xad\xec\x8b\xaa\x86\x72\x23\x9e\x60\xc7\xac\x30\xd8\x92\x01\x67\x4b\x7f\xaf\x70\x23\x15\x76\x12\x53\x46\x8d\xe6\x26\x32\xf2\x6a\x67\x1f\x17\xbb\xaf\x2a\x51\xca\x8d\x7d\x5a\x1a\xb3\xb2\x5e\x5a\x93\xee\xc6\x41\xe8\xf6\xca\xee\x50\x9a\xec\x23\xa0\x1f\x35\x2e\xa0\x0d\x9f\x2d\x8e\xc0\x17\x3d\xa6\x13\x03\xa8\x40\x4d\x5a\x80\x87\xa2\xdc\xf0\xbf\x6e\x2c\x9c\x38\x09\x43\x6a\x78\x43\xc6\x6c\x85\x99\xc0\xe7\x42\xbe\xdf\xac\xa4\x29\x37\x71\x7c\x4c\xee\xa6\x6d\xef\xeb\x9c\x9f\x96\xb2\x40\x1d\xe2\xdd\x67\xb1\xee\x25\xa4\x94\xcb\xa3\xc8\xa8\xb1\x65\xd9\x0b\x97\x5f\x12\xdf\x28\x97\x37\x9b\x1b\x91\xe0\x6d\x28\xd5\x79\x21\x92\xc8\x6b\x3e\xb0\xe1\xac\x17\xbe\x87\x10\x9e\x17\xf8\x7c\xee\x77\x72\x2b\x57\x44\x61\x6c\x71\xa2\xb6\x6e\x4b\xa7\x42\xb5\xd2\x4f\x43\x45\x85\xd1\x45\x39\x20\x63\xd3\x36\x7d\xcb\xcf\xc7\xe1\x55\x25\x47\x08\x34\xe2\x3e\x4b\x2e\xae\x84\xfd\x94\xab\x7c\x86\x1d\xb7\x0f\xab\xd7\x97\xfb\xc5\xc6\xf2\xf7\xba\xf6\x12\x0a\x2c\x66\xb3\xe6\xd9\x4a\xeb\xce\x42\x6a\x26\x90\xe1\xc2\x62\xe6\x16\xa5\xbc\xce\xcf\xda\xb1\x91\xc2\xb1\xdf\x1a\x47\xbe\x68\xec\xec\x7d\xcf\x2c\x69\x2e\xf1\x37\x88\x97\x6c\xbe\x7a\x7e\x7e\x7d\x59\xee\x4c\xda\x56\x79\x6e\xcc\x12\xdf\xc2\x46\xb1\x05\x6f\x0d\x65\x1f\x24\xab\x3c\x97\xc7\x68\x4e\xee\xd3\xb7\xb4\xe6\x59\xe3\x57\xa7\xf9\x1b\xc6\x88\x83\x97\xe5\xb9\x9a\xfa\x1e\x0c\x49\x53\xcb\x13\x6b\x0e\x7b\x82\x24\x6e\x8e\xe4\xda\x53\x5f\x40\xcf\x54\xb7\xe3\x94\x13\x59\x8e\x0c\x9e\xbf\xdf\xd1\xc7\x1c\x89\xf8\x2b\xcf\xd3\x2e\x46\x63\x88\xba\xc3\x12\x42\xc7\x5b\xa5\x3c\xdf\xf1\x50\xca\xcb\x22\x1f\x86\x75\x92\xe6\x78\x84\x29\xfa\x27\x7e\x14\x45\xff\xbb\x7a\x3e\x08\x82\xa3\x34\x7f\x7c\xe0\x59\x26\xb8\xad\x8e\x28\x8f\x79\x24\x69\x93\xe6\x69\x7d\x57\x88\xe9\x35\xe5\xb1\x44\x6b\xcb\x20\x09\xea\xae\xf1\x31\x10\x7e\x30\x08\x9c\x95\xc7\x04\xe9\x9e\xfd\xeb\x71\xb5\x99\xb5\x7f\x54\xe0\xb5\xb0\xa0\xfb\x33\x64\x77\xf0\x96\xb6\x37\xc7\xb4\x83\x08\x96\xb4\x5a\xda\xa6\x21\xea\x9b\x9c\x9c\x1a\x5e\x10\x3a\x98\xd2\xda\x37\x2b\xb5\xac\xe0\x9b\x89\xd1\x46\xe0\xbe\xe1\x49\xa1\xc7\x3d\xd3\x53\x6a\xf8\xd3\x2d\x82\x46\x79\x91\x47\xa0\xa2\x95\xe9\x3e\x6c\xdb\xfc\x94\x17\x07\x0e\x6e\x2f\xc4\x74\xf5\x4b\x04\x79\xdf\xcf\xf3\xe2\x00\xd0\x44\x60\xfb\x4b\xaf\x89\xa7\xbd\xb6\x0a\x91\x85\x76\xf7\xb0\x9a\x7d\xe5\x30\x7a\xb1\xa6\x12\xea\xde\x8a\xc1\xc1\xd7\x52\x60\xca\x4b\x1c\x42\xde\x1b\x58\xc3\x13\xe4\xf5\x61\xe0\x43\x7b\x49\x40\xb2\x8e\xdf\x8a\x42\xed\xca\x22\x9f\x6c\x09\x36\x63\x05\x23\x96\x0b\xb3\x56\x4c\x7b\xff\x20\x10\xf0\x44\xc8\x18\x1b\x35\x71\x1e\xd2\x1a\x9e\xa6\x52\xb2\x9d\xaf\xe5\x49\x07\xb8\x6a\x13\xfb\x8f\x03\x54\xdd\xe8\xa1\xa4\xc7\x30\xb3\xd5\x29\x54\x1b\xdc\x6a\xeb\x0d\x78\x12\x88\x4d\x44\x9a\x19\xbe\x7f\x28\x4a\xd3\xe3\x31\xaa\xc0\x75\x68\x33\xe5\x29\x00\xd9\x41\xb0\xaf\xf0\xda\x57\x66\x74\xb8\xb3\x7a\x5a\x6b\x6c\x9d\x7f\xc8\xd2\xd3\x8b\x9d\xf2\xbe\xeb\x31\x94\xba\x43\xb1\x84\x0e\xe0\xa1\x7c\xcf\x51\x08\x7c\x44\x97\x8a\xe4\x0a\x50\xc6\xe9\x32\xfd\xd8\xbe\xe7\x89\x88\x08\x79\x11\xc1\x7a\x4a\x87\x06\xca\xf7\x38\x67\xcc\xac\xde\x94\xd7\xd0\xa7\x9e\xb6\xbf\xe9\x87\x01\xc6\x32\xf8\x9b\x7b\x93\x40\x1a\x9a\x1e\xdf\x8f\x09\x31\x7c\x01\x5e\xae\x72\xdb\xfe\x92\xb6\xe6\xdb\xf7\xa5\x44\x6a\xc1\x96\xa6\xbb\x0d\x54\x48\x4d\xdb\x8e\x63\x01\x58\xa5\xd3\xc5\xee\x71\x32\x2c\xf0\x03\x5f\x82\xdd\x0a\x4a\xfe\x79\x0f\x1f\xf6\xec\x20\xd0\x98\xef\xe4\xa6\xa2\x76\xc7\xdf\xaa\xf6\x58\x18\x8a\xa8\xc7\x06\x36\x89\xa7\x9b\x5a\x42\x7e\xa0\x88\x3e\xf8\xdb\x6c\xbb\xdf\xad\x9a\x1d\x63\xfd\xb4\xd8\x2d\xf6\x8b\x3f\x16\xf3\xd7\xdd\x72\xf5\x62\x7f\x22\x0c\x95\xa2\x24\x1b\xd6\x72\x16\xf5\x21\x95\x8f\x67\xb1\x03\x7e\xec\xcc\x82\x1f\xf2\x00\xcd\x74\xd7\xf1\x6e\x4a\xb4\xf6\xb8\x24\xa4\x1b\x4e\x94\x5d\x31\xc0\xc5\xf6\xa7\x9e\x1f\x4a\x89\x3b\x95\x38\x97\xf9\x30\xab\x32\x5c\x83\x7e\xa4\x01\x13\x18\xeb\xb2\xa8\x81\xdb\x65\xe7\xc7\x9e\xb0\xa9\xa1\x1f\x69\xae\x8a\xcf\x99\xfa\xcf\xa6\x71\x91\x1e\x08\x8b\xd3\x6d\x30\xbd\x45\xe7\x73\x0f\x10\xde\x48\xb7\xbf\x52\xaa\x9a\xfe\x4a\x3c\xf0\x9c\xb8\x27\x72\x97\xfe\x05\x58\x96\xfb\xc6\xab\xde\xcb\xe0\x09\x35\x3a\x1b\xb0\x64\x9f\xf3\xde\xbb\x52\xb2\x37\xe7\x08\x13\x96\x1d\xf7\x27\x22\xbf\xb4\x17\x13\xa0\xb1\xaa\xf5\x02\x9f\x43\xf9\xf5\x2f\xe9\x09\x94\x2f\x25\x71\x39\x37\x2f\x02\xe0\x3d\xbb\xf4\x7a\x06\xbf\x17\xd9\xf9\x88\xbc\x20\xbd\x1f\x92\xe0\xfa\x7d\x59\xbb\x67\x9e\x9f\x79\xd6\x41\x7f\x47\xef\x5f\x39\x64\x23\x72\xf8\x7c\xb9\x92\x19\x34\x63\xc0\x4d\x6c\x4d\x60\xde\xe6\x24\x95\x0f\x11\x73\x0c\xec\xf1\x7c\xda\xf6\x14\x99\x47\x3f\xa1\x9d\x04\x8d\xd7\x2c\x2d\x39\xb1\xc7\xa0\xc3\x39\xf5\x4b\x1a\x82\xd0\xb3\x65\x2c\xc5\xcb\x6a\xd9\x7a\xa6\xcc\x89\x98\x6e\xb7\x7a\x64\xdf\x18\xa6\x7c\x15\xf3\x5d\x86\x67\xdf\x9d\x2f\x77\xdb\x5d\xdd\xcb\x05\x2a\x16\xb8\x44\x22\xbd\xfe\xb6\xee\xdb\x77\x16\x44\x0a\x17\xec\xef\xb3\x35\x76\x8b\x7e\xb1\xd8\x58\x14\x6b\x29\x8c\xc6\x33\xd2\x1d\xf1\xf2\xc6\xb6\xcc\x22\x23\x96\xdd\x78\xb1\xe4\x60\x35\x1b\xc6\x13\xe4\x6f\x07\xfb\xfe\x58\xa4\x8c\x68\x6b\x21\xdf\xb7\x00\x6a\xd4\xb2\xa6\x58\xcc\x42\x87\x80\xfb\xf2\x30\xf0\xf2\x58\xac\xb9\x43\x74\xad\x88\x24\xde\xfb\xf6\x40\x92\x70\xed\x77\x2b\x00\x51\x5b\xd5\x57\x9c\x30\x8a\x25\xda\xa1\xbe\x5f\xac\xa1\x12\xd2\xaa\xbf\xb9\x0d\x1f\x8c\xfb\x81\x65\x87\x7c\xe2\x8d\x37\x67\xa9\xe2\xa6\xa0\x56\x8a\x89\x50\x88\x3e\xa6\x75\x2b\x8b\xf3\xa9\xb8\x51\xa3\x55\x4c\x98\xf4\xba\x1d\x4e\xb9\x90\xe6\x5d\xff\x9e\xe6\x6f\x3f\xd2\xfa\xd0\xf8\xf6\xbc\x3e\x97\x37\xd5\xda\x7f\x59\x98\xec\x99\x29\x26\x9d\x08\x33\x77\x3b\xa8\xea\x30\xb6\x2f\x51\x6a\xae\x8c\x4f\x8b\x2f\xa5\x8f\x2d\x32\x43\x94\x74\x30\xd7\x95\xf1\x5c\xd9\xd7\x6b\x4f\x07\x87\xd2\x7d\x9b\xc5\xc3\x62\xb3\x99\x3d\x11\xc1\xfe\xb6\x3d\xac\x42\x83\xa4\x39\x9a\xac\x34\xa1\x89\x0d\xe0\x5b\x05\x8e\xe7\xf2\x36\x85\x63\xc3\xaa\xe1\xef\x07\x8e\xcf\x10\x95\xb5\x41\x82\xc0\x5f\x75\xa8\xd8\x93\x84\x8f\xd9\x6b\xfb\x76\x67\xb9\x7a\xea\xd3\xa6\x0f\x47\xbb\xbe\x80\x96\xd9\x0a\x78\xd5\xbc\xf3\xc1\xc7\x0d\xdc\xc0\x43\xc7\xa5\xbe\x9c\x7a\x6c\xe1\xe3\xcb\x84\x01\xa2\xaf\xaa\x43\xf1\xd9\xc2\x42\xaf\xe1\xc1\xcd\x40\x70\x98\x05\xbc\x1e\x05\x27\x5f\xb0\x15\xc1\xf3\xe2\x7f\x8c\x7e\x3d\x09\x51\x5e\xce\x34\x98\x5d\x6b\xa4\xde\x08\xf1\x6f\x6c\xab\x16\x96\xe6\x11\x83\xf9\x60\xe5\x07\xae\x0a\x94\x69\x44\x1e\x77\xff\x8f\x9e\x56\x73\x66\xb8\xea\x4f\x45\x35\x4d\x24\x6f\x86\x7a\x51\xe0\x19\x0a\x87\xa7\xa7\xef\x88\x43\xdf\xbb\xfe\x6f\xc3\x31\x2a\x26\x09\x59\x38\xa6\xf5\xa6\xc8\x60\xdc\x7b\xd8\x0b\xf4\x03\xdf\x61\xd8\xae\xd8\x73\x5d\xcc\xcd\x8e\x63\xf2\xe1\x3d\xfb\x52\x24\x61\x9b\x8f\x78\xcd\xd3\xba\x7a\xad\xa0\x9c\xf3\xfc\xee\x7c\xa1\x80\x65\x78\x02\x6b\xe2\xfe\x2e\xf7\xb8\xa8\x24\x3f\x81\xa1\xf2\xb4\x43\x02\x8d\x60\x0b\x89\x7b\xff\x6c\x9c\xb9\xb3\xa3\x84\xc4\x7c\xd5\x53\xf1\xf6\xb2\xd7\xb9\xbc\x95\x38\x19\x7c\xa3\xe1\x42\x76\x47\x0f\x13\x38\x31\x2e\xcc\x7d\x05\xf5\x9a\x5f\x76\xa3\x85\x1b\x04\xa1\x87\xf1\xf7\x7a\xb3\xd8\x2f\xe7\xab\xfd\x7a\xb1\x59\xae\xee\xed\x6d\xc7\xae\x1b\x0f\xaa\x18\xf9\x1b\x64\xd3\x68\x56\x7b\x86\xe7\x22\x7a\x71\x5f\x0e\xe8\x3a\xba\xa3\x58\x24\xb5\x65\xe1\xfa\x6c\x90\xcf\x83\x5a\xa4\x1d\xec\x0b\xad\x7b\xb5\x9c\x51\x07\xeb\x70\x57\x0d\x12\xe6\x33\xd5\xc1\x20\x27\x80\xe6\x2a\x48\x34\xb9\xe4\xcb\xdd\x59\xd8\x5d\x32\xe0\x52\x28\x2b\xc1\x93\xe6\xe7\x09\xc1\xc9\xee\x96\x38\x24\xe8\x86\xbd\x14\x0a\xb6\x9f\xfc\xd4\x6d\xb9\xbf\xb2\xb2\x37\x0a\x87\xbf\x82\x99\x98\xdf\x15\x11\x21\x6f\x56\xa2\xe6\x69\x3e\x3f\xa4\xa7\x3e\xf1\xa0\x0a\x44\xc2\xf0\xf8\x7c\xfe\x48\xdd\x32\x36\x4b\x13\x48\x06\xf8\xfd\x77\xcb\xe7\xc5\xea\x75\xb7\xbf\x5f\x6c\x77\x9b\xd5\x9f\xed\xe1\x80\xd9\x70\x79\x20\xc6\x38\x7d\x1b\x92\xfb\xa4\xfe\x68\x5b\x02\x7f\x5e\x90\xa9\x62\xf8\x96\x55\x24\xb0\x3f\xe2\x61\xb1\x78\xea\x74\xb9\x54\xa0\x40\x22\x05\x75\x2b\xcb\x38\xaa\xc4\x04\xe0\x73\x8c\xcf\xbf\xad\xd7\x8f\xb3\xcd\x33\xe9\xb0\x4c\x9a\xee\xd0\x09\xbc\x48\x0c\x3a\x03\x5b\x82\x9b\xab\x99\x79\x55\xb7\x54\xa1\xeb\x4a\xa4\x6d\xdf\xad\x76\xb3\x27\x9c\xf7\x83\x3d\x29\x74\xb5\xc6\x86\x19\x79\x3c\x4d\x6b\xd1\xaa\xd0\x73\x42\xec\x26\xa5\x70\x2c\xbb\xe7\x97\x49\xa6\x76\x15\x7a\xae\x63\xab\xae\xaf\x39\xf2\x28\x13\xd1\x75\xbe\xf8\x59\x98\xa5\xd4\xff\x05\xfb\x4d\x43\xcf\x57\x88\x8d\x82\x5c\x16\xaa\x23\x73\xe8\x4d\x4a\xfa\x97\x04\x23\x98\x33\x3a\x3b\xd0\xae\x21\xc2\x83\x11\xab\xb3\x0a\x9b\x50\xd6\x37\x9c\x20\xd6\x44\x85\xbe\x07\x88\x02\xc7\xe2\x02\xf9\x5e\xd7\x95\x5f\x3b\xd6\x0f\xf1\x99\x9e\x21\xad\x2a\x3e\xb7\xb2\xcf\x7d\x4f\x32\xf4\x13\x2f\x30\x9e\x3a\x65\xfb\x1b\xdb\x31\xbf\x6a\x38\x51\xa1\x2f\x7d\x3f\x26\xdb\x68\x76\xf7\xd1\xed\xb2\xd0\x0f\xc2\x3e\xf5\xdd\xbc\x38\x9a\x0e\xb8\x5d\x31\x78\xeb\xed\xe3\x07\x8e\x8b\x38\x15\x93\x18\x69\xbb\x06\x42\x36\x34\x09\x61\x10\x2a\x74\x2e\x1e\x8a\x63\xe1\x59\xbb\x17\x06\x49\x14\x33\x1b\xd4\x3f\x8d\x9b\x25\x54\x18\x68\xc9\x48\x98\x4e\xd8\x53\xc2\xc0\x8b\xb9\x15\x90\x19\x3a\x06\x61\x14\x48\x07\xda\x26\xe1\xe7\xe2\x63\x68\x2f\x06\x30\x3b\x15\x46\x09\x71\x72\xdb\x27\xfb\xc6\x5b\x26\x02\x3c\x88\xd6\xaa\x09\x24\x89\xde\x7c\xb4\x89\x84\xb1\xeb\x71\x66\xa9\x5b\x1b\x5f\x7a\xcf\x1d\x7b\x76\xcc\x62\x0b\xd9\x9a\x9d\xeb\xc3\xdd\x65\x7d\x28\xf2\x01\x03\xa7\x0a\xe3\xd8\xa5\xf2\x44\x06\xbc\xdc\xcc\x9e\x67\x59\xd6\x9e\x0e\xc2\xa7\xcd\x04\xd9\xb1\x7f\xa6\x37\x42\x9c\x90\x27\x44\xd1\x79\xe0\xd5\xbc\xb9\x0c\x42\xad\x7b\xc4\x84\x43\xd7\x25\x14\x42\x62\x39\xa9\xb9\x65\x03\xb1\xea\x8a\x4d\xa1\xd0\xd4\xcc\x2d\xb9\x49\x38\x19\xbe\xd9\x29\xf4\x8c\x0a\x25\x0b\x11\x6c\xa1\xa1\x05\x30\x64\xa0\x68\xbb\xa5\x2c\xd1\x08\x28\xa5\x42\x19\x46\x66\x7e\x95\xaa\xea\x97\x01\x43\xc9\x25\xd2\xe0\xa6\xd5\xba\x4c\x9b\x93\x47\x62\x1c\x2a\x54\x40\x3c\xd6\xea\x05\x7e\xd6\xfd\x2c\x78\x08\x41\x14\x73\x4b\x08\x83\xb9\x83\xc6\x23\xe8\x8e\x02\x89\xf8\xf3\x4c\x2e\xe7\xab\xaf\xf3\x7c\x21\x28\x61\x69\x5a\x1a\x57\x64\x94\x9c\x0e\xb5\xf2\x1c\x65\x51\xf1\xa0\x3a\x51\xdf\xfe\x87\x8d\x9c\x98\x09\x13\x83\x35\x37\xfb\x52\xb4\x6c\x97\x2a\x72\x92\x00\x4b\x05\xdf\x88\x58\x17\x6a\xe4\x53\x24\x17\xa6\xbf\xb0\x22\x47\x06\x58\x5e\x7a\xfa\xf3\xa1\xbf\xda\x23\x47\x4b\x48\xba\x32\x05\x72\xfd\x43\x5b\xaf\x05\x45\xb0\x85\xe1\x54\x8d\xdc\xd0\x13\x06\x55\xde\x23\xaf\x3c\x77\x54\x35\xee\xe8\x45\x44\x6e\xe4\x2b\x23\x6b\xf5\x74\x96\xef\x17\xd1\xef\xd8\xb4\x63\x12\xdf\xa7\xcf\x99\x77\x37\xb0\x01\x54\x92\x19\x74\x6c\xab\xc8\x05\xe2\xd1\x6b\xab\x7d\x69\x7e\x67\x85\x8f\x47\x57\xf5\x98\x8f\x18\x8c\xcf\xf4\x04\x77\x6d\x55\x78\xb2\x87\x4e\x45\x5e\xa0\x91\x1f\xf9\xf5\x6e\x3b\x78\x4b\x5e\xec\x60\x13\xdb\xf6\x50\x7c\x5a\x98\xb5\xba\x09\x3d\x9d\x9c\x0b\x91\xef\x2b\x4b\x1c\xf2\x9a\xe6\x35\x95\x52\xe7\x37\xfb\xdd\x55\xe4\x27\x1c\xa1\x28\xf0\x33\xad\xea\x8a\xbc\xa8\x0e\x78\x30\xb9\x80\x23\x9f\x27\xc2\xd0\x48\x34\xb3\x89\x4d\x3b\x04\x11\xf3\x22\x24\x42\xd2\x45\x29\xc1\x10\xb4\xd9\x43\x11\x43\x47\xf0\x4c\x92\x5f\xf7\xd0\xec\xd2\xa4\x61\x70\x4c\x47\x38\x2c\x15\x31\xc9\xc0\x38\xff\xb3\xda\x7c\xb2\xeb\x74\x72\x3f\xa4\x1e\xdf\x89\x92\x89\x32\x7a\x41\xa9\xb4\x7a\x09\xc8\xdd\x7f\xe0\x65\xda\x6a\x67\xde\x6a\x69\x56\x51\xe8\x6b\xdc\xaf\xb8\x52\xc4\x73\x70\xc5\x9f\x74\x9d\xe5\x32\xe8\x9a\xe1\x3f\xf6\x7a\x01\x73\x8c\xfe\xd9\x32\x9f\x42\x3b\x44\xa1\xd0\x6e\xd2\xa6\x8e\x9b\xd8\xa2\x9a\x16\x20\x55\x51\x14\x6b\xf4\x5c\xe7\x45\x9a\x37\x8b\xd7\xbe\xe5\x88\x4b\xcf\x90\x28\x88\x73\x39\xce\xf5\x46\xb1\xa3\x1c\xd5\xf1\xc7\x18\x39\xa1\xe9\x9f\x88\x63\x89\x65\x0a\xeb\xeb\x7f\x59\x04\x31\x31\x56\x94\x78\x4a\x18\x19\xa7\xa5\x2c\x26\x13\x2a\x51\x12\x01\x66\xe0\x28\xea\xb2\x44\x0e\xd7\xba\x69\xf1\xf0\xca\x9c\x79\x04\x22\x97\xe9\xb1\x89\x12\xd6\x25\xc8\xb4\x82\x7b\xfa\xdf\xa3\x07\x4d\x54\x98\x78\xbd\x10\xac\x09\xab\x77\xc5\x00\xc9\x6a\x46\xf2\x44\xab\xe6\xba\x39\x42\xa5\x4c\xa6\x62\x78\xc3\x5c\x0b\xac\x62\x75\x3b\xa8\x76\x23\xfb\xc6\x85\x93\x20\x18\x86\x64\x47\xd3\x3a\xfd\xab\x67\x4f\x44\x14\x33\xf3\x45\x1f\xb8\x9c\xcc\x1e\x46\x02\x5c\x97\x3a\x9e\x3f\xa0\xc3\xaa\xaa\x48\xba\x3e\x4a\xb9\x9c\x1a\xa3\xe0\x3e\xf3\x9f\xf8\x10\x73\x7e\xb2\x03\x94\x1f\xa3\x5d\xc3\x14\xd7\x38\xd9\x17\x3b\x2e\x60\x52\xf2\x92\x56\x87\x34\xeb\xd3\xf6\xa9\xd8\x51\x0c\x6f\x2b\x87\xcf\xd5\xef\xf6\x8f\xae\xe7\x86\xb6\x19\x0e\x99\x02\x5a\xbe\x08\xdf\xfb\x77\x92\xfc\xaf\x1d\x16\x70\xbc\xdd\x0d\xb5\x03\x97\xbf\x12\x0a\x52\xb1\xe7\x50\xbd\x2b\x3f\x1f\x2d\xad\xab\x7d\x41\xb1\x17\x6a\xc4\xff\x19\x8a\x82\xbc\xc7\x2a\xaf\x62\x3f\x12\x78\xd0\xf4\x27\xef\x8a\xf5\x39\xcb\x56\xe7\x71\xfb\xe4\xe4\xf2\x8d\x7d\xe0\xb1\xba\xa6\x05\xf8\x8a\x39\x70\x78\x01\xa6\x88\xff\xc9\xca\x9b\xa7\x1f\xb0\xcc\x55\xfa\x91\xaa\x33\xcf\x46\xfc\x7c\xd3\x4b\x28\x0e\xfc\x04\x5b\xb0\x78\x55\x41\x59\x2f\xfe\xcf\x65\xe4\x08\xba\x86\xf5\xc0\xfe\x6b\x77\xd3\x38\x88\xbd\x98\xf0\xc9\xaa\x89\x6f\x7b\x24\x94\xed\x6a\xfb\x45\x1c\x79\x9e\xea\xeb\xfc\xc7\xf0\xae\x12\x66\x54\x94\x79\x59\xbf\xc0\x27\x89\x6f\xd9\x83\xc2\x31\x05\xe3\xb6\x6f\xfe\xb7\xd1\x43\x81\x8b\x0a\x98\x0f\xab\xd7\xcd\xee\x71\xff\xba\x5d\x6c\xf6\xf3\xd7\x9d\xbd\x40\x18\x28\x5c\x2c\x90\xab\x3d\x3f\xf7\x1d\xb7\x38\x4c\x22\x2c\xaa\x1e\xf9\x3b\x3c\x20\x3e\xa3\x87\xbe\x8a\x63\x1d\x3a\xfe\x98\xae\xce\x06\x1c\x3d\xe2\xea\x91\x23\x60\x63\xb8\x38\x89\x42\xe4\xf4\xfd\xfd\xcf\xcd\x72\x35\xd8\x66\xe3\x44\xc5\x98\x28\xbe\xec\x77\x69\xdd\x2d\x11\x1e\x25\xca\x78\x51\x0f\x45\x96\x15\x9f\x69\xfe\xd6\x51\x56\xdb\x41\x3c\xc2\x20\xf4\x73\xdc\x68\xd2\xfe\xb0\x60\x81\x87\x98\x67\x5e\xbf\xe6\xa9\x2c\xca\x76\xfd\xc7\xd2\x55\x3e\x75\x16\x83\x7c\xef\x4b\x6e\xed\x8a\xe5\x7c\xb6\x6e\xb6\x23\xaa\x12\xe7\xd7\xbe\xf0\x64\x71\x39\x96\x41\x88\x65\x32\x95\x56\x5c\x64\xf0\x5c\x7c\x74\xb5\x8d\x58\x72\x62\x5f\xaa\xa0\xfe\x9e\x96\xf5\x99\x67\xc6\xcd\xb1\x49\xb9\xe1\x97\x94\x22\x94\x1d\x39\xe6\x3a\x3b\xbf\xa5\x37\x4a\xc1\xb1\xf2\x19\xe2\x51\x9b\x1d\xfd\xa1\x28\x77\xc0\x8f\xf6\x47\x55\x10\x63\x96\xf3\xc5\x12\x3e\x34\x7f\x92\x18\x32\x18\x8b\x55\xd6\x90\xf5\x0e\x41\x57\xe6\x9b\xf4\xc2\x62\x15\x87\x96\x50\x33\x83\x0f\xb8\x62\xbe\xb4\xc3\x12\x0f\x7b\xc8\x4c\x5d\xf2\x3e\x3d\x65\xc5\x91\x2f\xf2\xfa\x9a\x30\xc7\x9c\x01\x4e\x82\x20\xc8\x4f\x48\x77\xc5\xc0\x70\xd9\x01\x2c\xf2\x9a\x01\xcb\x9f\x69\x9e\x9e\x8f\x0f\xed\xac\x06\x66\xa9\x2b\xeb\xf9\x6c\x85\x95\xb6\xf6\x50\x18\x53\x85\x0e\xf5\xf1\xb6\xbb\xd9\xb7\xc5\xbe\x59\x1b\xf6\xb8\x0e\x5d\x84\x6a\xad\xa1\xd4\x20\x7b\xbd\x7d\x2a\xd6\x49\x12\xc9\x5e\x17\xdc\x3f\xeb\xcb\xf2\xa4\xab\x91\x4c\xbc\x4a\x1c\x4f\x61\xb1\xdc\x18\xc2\x6d\x9a\xbf\x11\x3f\xe1\x70\xa3\x4a\x1c\xa5\xb1\xda\x59\xf3\x12\x6b\x51\x03\x2c\x69\xe2\x86\x0c\x53\x7b\x18\x91\x5a\xfa\xe1\x9e\x6e\xb8\x4a\x3c\x97\xf4\x44\x0e\xc4\xf5\xbc\x17\xa9\x6a\x5b\x83\x54\xe2\xfb\x01\x76\xb0\x57\xf2\x00\xea\x9c\xc1\x23\xcf\xdf\x90\x87\xc7\x1e\xd7\x84\xbe\x79\x9a\xbd\xbe\xcc\x1f\xf7\xf7\xad\x52\xa0\x4a\x58\x40\x18\xb1\xd5\xeb\x6e\xf9\xf2\x6d\xb3\xd8\x2e\x36\xdf\xbb\x83\xc2\x71\x82\x36\x17\xda\xcf\x9e\xd9\x01\x9a\x23\xfc\x65\xbd\x59\x20\x3b\xe6\x7c\xb6\xb6\xe7\x06\x9e\xdb\x93\xf7\x9c\x91\xab\x32\x6e\x71\x6d\x86\x85\x26\x3e\x2f\x26\x2a\x23\x63\x6b\xf9\x5f\xfe\x6b\x7f\x23\x22\xaa\x16\x05\x32\xe3\x25\xb4\x7b\xc3\xa2\x35\xae\x49\xa0\x12\x27\x31\xe0\x31\x22\xa0\xc3\xde\xd7\xee\x15\x07\xda\xe6\x86\x72\xb5\x81\x63\x13\xe8\xef\x8a\x9e\xee\x81\x4a\x42\x9f\xe1\x88\x03\xcf\x55\x66\x5c\xec\x0d\x2d\x80\xd1\x33\x87\x31\x60\xf2\xb8\x3c\xe7\xb0\x2b\x7e\x40\xda\x9f\xb5\x49\x28\x7c\x16\x63\x80\x77\x67\x20\xb5\xf6\x48\x24\x01\x23\x3a\x93\xfd\x33\xf3\x64\x74\xf1\x38\x72\x1c\x43\x80\x68\x22\x9e\x65\xf5\x52\xd4\x0f\x65\xf1\x17\xe4\x0f\x45\xb9\x81\xfa\xdc\xc9\x7c\xf4\x6a\xd0\x49\xe2\x6a\x69\x50\xcb\xdf\xca\xe2\x7c\xda\xa4\x6f\x87\xb1\xea\x68\x7f\xb8\xcf\xa8\x13\x17\x81\x38\xe3\x96\x9b\xe1\x3c\x49\x7c\x8d\x04\x9a\xf3\xd5\x66\x51\x1f\x06\xf9\x4b\x3b\x22\x56\xd8\xff\x83\x62\x92\x3d\x6f\x29\xe1\x8e\x1b\xc4\x5d\x7c\x83\x34\x25\x3c\xbf\xa1\x98\xaf\x12\x6e\xb8\x82\xb1\xbd\xb6\xaa\x7b\xbf\xc0\x03\x66\xe1\x79\x18\xbd\x56\xdd\x81\x10\x53\x8c\x5f\x0a\xcd\x04\x66\x4f\x49\x04\x4b\x08\xf1\x50\xf0\xac\x25\x9c\xe9\xb5\xb6\xab\x44\x84\x2a\x0e\x3b\xf5\xaf\xc1\x24\x11\x21\x21\xc3\xb1\xc4\x8b\xdb\x4e\xd6\xbb\x45\xe9\xfb\xd8\x78\xb4\x57\x56\xc4\xbd\xe7\x67\x27\x32\x20\x6f\x4d\xb5\xa1\x72\x5f\x9f\x72\x38\x0b\x24\x67\xd8\xfa\x3b\x5b\x12\xeb\xfc\x17\x5e\x60\xa2\x42\x81\xdc\xa3\x33\xa5\x5e\xe0\xd3\x10\xf1\xac\xb9\x7c\xb7\x0c\x81\xe3\xd8\x3e\x51\xa1\xc2\x5d\xe4\x08\x47\xb8\xc6\x23\x26\x10\x0a\xb4\x0a\x8d\x37\x71\x77\xbe\x50\xae\xa5\x9f\x9b\x48\x80\x2b\x6c\x6c\xef\xf2\x84\x56\xcc\x79\x04\x80\x1f\x3e\x15\x08\x2d\x44\xdb\x76\xb6\x05\x5b\x9c\x79\x29\x76\x87\xb2\xe8\xda\x40\x06\xd8\xea\x04\x24\xc3\x88\xe3\xc8\x7f\xa6\xc7\xf3\x71\xb0\xac\x41\x33\x9f\x72\x05\x75\x0e\x55\xb5\xd2\xa3\x47\xd1\x71\x82\x28\x7f\xdb\xad\xbd\xc8\xe9\x26\x75\xaf\x64\x94\x68\x01\x36\xc5\x7d\x0f\x1a\x79\x6e\xff\xf9\x64\x0e\x72\xc7\x89\xad\xf3\x6e\x5b\xd2\x5f\x73\x42\xec\x4d\xf4\x39\x29\xee\x78\x24\x7b\x28\x46\x7f\x77\x03\x87\xf5\xfc\xf1\x6d\xfa\x97\x9d\x36\xdc\xd5\x3e\xee\xf3\x0f\x19\x9c\x6d\xbf\xbe\xe2\x1e\xe7\x58\xc8\xaa\xa1\xaa\x5f\xf3\xea\x92\x4b\x50\xbd\x15\xc7\x3d\xa0\x40\xec\x3e\xcd\x8b\x8a\x9f\xcb\x07\x5e\x1e\xa1\x7c\x81\x4f\x3b\xc0\xf7\x1d\x4d\x1c\x6b\xfd\x66\xfb\x8e\x27\x44\x71\x3f\xf1\x55\xab\xdc\xa5\x2c\x03\xb5\x3d\xca\xa4\x46\xff\x6c\x7f\xd2\xe9\xb8\xbe\xc4\x99\x56\x71\xeb\xcd\x62\x43\x89\x39\x10\x48\x43\x1a\x66\xa7\x86\x65\x50\x98\xc8\xc0\xb7\xdf\x89\x07\xc0\x49\x43\xec\xfd\xb3\x4b\xc1\xf2\x30\x64\xc4\x8a\x8f\xe6\x06\x6f\xdf\xe6\x37\x2b\x2c\x0f\xfe\xa2\x3f\x86\x87\x92\x25\x11\xf6\x71\x95\x65\xf1\x09\xc6\x78\xde\xf7\xde\x62\xe4\x28\x13\xce\x56\x75\x59\x5c\x56\x99\x22\x99\xfc\xe9\x5a\xad\x3d\x29\x0a\xfc\x5e\x71\x4d\x9d\xb3\x9a\x32\xc4\x1d\x2b\x67\x6c\x87\x4a\x1f\xfb\x2c\x94\x11\x1c\xf8\x55\xaf\xe5\xe8\x01\x62\xd7\x41\x5b\xf4\x9f\xaa\xc8\x37\xc0\xd5\x54\x9c\xcb\x63\xa1\x3b\xc8\x12\xae\x83\x1f\x90\xf6\xf0\x32\x3c\xe1\xd4\x26\x84\x5c\x09\x70\x9a\x10\x4d\x53\x3c\x11\x44\x12\xd9\x7a\xe3\xcf\x30\xa8\x82\x4c\x53\xda\x28\xce\x63\x47\xa2\xe0\x47\x59\xe4\x7f\xd8\x1f\xe4\x92\x0b\xe2\xb0\xb9\xfc\xd1\x84\xff\xdd\xdf\x49\xec\xb7\x9d\x1c\x98\xa2\x7a\x18\x91\x4d\x2a\xce\xc1\x85\x68\x58\x61\xff\x45\xb9\xcf\x9c\x28\x02\x8d\xa4\xd1\x3a\xad\x0e\x4f\xd6\x63\x19\xde\xb0\x04\x9f\x12\x3c\x07\xa8\xaa\x79\x76\x16\x4f\xe9\x07\xd0\xff\xe8\x1c\x48\xae\x7c\x85\x29\xdc\x3d\x35\x34\x7e\xc1\xf6\xa5\xb8\x62\x44\xb9\x30\xce\xe7\x5c\x97\xc3\xb8\x8a\x49\x5b\xe8\xc0\xab\xc3\xac\x7c\x43\x49\xad\xe1\x64\x33\xe5\x25\xf3\xcf\x55\x61\x94\x83\x20\xac\xee\x71\xdf\xbc\x96\xc7\xc6\x8f\x6c\x6f\x5a\x7b\x1a\x69\x5f\xb0\x1d\xac\x38\x37\xdb\xff\xf0\x64\x1d\x91\x90\x15\x99\x04\xf4\x73\xa7\xbf\xaa\x96\x0a\x59\x07\xb3\xe2\x0d\xd5\xd7\x52\x39\x59\x03\x10\x8e\xe3\x72\xe2\xbd\xce\x2d\x94\x5c\x38\x8e\x16\x89\xed\xc6\xf8\xcf\x44\x1a\x6c\x7c\x0d\x93\x2d\x1f\x76\xae\xff\xe9\x0e\x2d\x8e\x70\x9d\x18\x23\x88\xe7\xd5\xea\xfb\x35\x89\x42\x7f\x41\x08\x37\x20\x72\x06\xcc\xbf\x7f\x4e\x72\x11\x9b\x91\x5e\xe4\x46\xa6\x2a\xfb\x54\xc8\xf7\x74\xac\xd6\x39\xbc\x05\xdf\x8f\x90\x6f\xe8\x8d\x1f\x61\xf5\xd1\xee\x42\x82\x29\x19\x1a\xa9\xc8\xbb\x32\x95\xef\x3d\xe3\x2e\x98\xf6\xb1\x07\xad\x6d\xfa\x26\x05\xc9\x99\x5d\x9c\x22\x88\x00\xf1\x91\x06\xe2\x3e\x85\xaa\xb1\x23\x15\xc7\x50\x71\xf5\x91\x8e\x30\xe2\x22\x0c\x3d\xca\x58\x9d\xab\xc3\xfd\xc8\x90\x8b\x50\x48\x14\x20\xc9\xd2\x26\xa4\xed\xab\x2e\x2b\x11\xbb\x1e\x1a\xde\x1c\x3e\xbf\x95\xfc\x0b\xc1\x90\x5b\xff\x76\x1e\xa5\x48\xa4\x8b\x5e\xc1\x35\x86\xea\xef\x59\x3b\x91\x68\x2f\x36\xc8\x02\xe3\xc6\x4c\x7f\x07\xce\x01\x13\x25\xc7\x4e\x75\xd7\x1c\x11\xb1\x87\xc9\xe9\x03\xcf\xb0\x07\x6d\x78\x9e\xd0\x8c\x32\x28\x95\x2c\x8b\xcf\xc7\xb4\x1a\x90\xce\x4d\xdf\x93\xd0\x12\x23\xc4\xaa\x31\xed\x7d\x39\x56\x25\xa4\x91\x14\x31\x84\xbe\x58\xff\x6c\x15\xe4\xda\x31\x2e\xee\x2f\xc8\xf1\x43\xde\xc7\xcd\x0e\x95\xd1\xba\x00\x15\x79\x5e\x4b\x38\x6c\xba\x1b\xda\x8f\xaa\x99\x83\x2b\x94\x3a\x80\x6e\x40\x9d\x85\x8e\x14\x86\x67\xf7\x0b\x04\xe7\xbe\xcc\x9e\x17\xfb\xcd\xea\xc9\x46\x88\xd2\x09\x42\x8c\x3c\xef\x78\xfe\x9e\x73\xd5\x0f\x57\xa4\x13\x2a\xcc\xbf\x6e\xbf\xed\xac\xc7\x7f\xbd\x6d\x0d\x6e\x59\x3a\x82\x23\xaf\x80\xcd\xa1\xf0\x34\xaf\x21\xef\xc4\xde\x94\x74\x74\x82\xd0\xd6\xbc\x50\xb0\x97\xd7\xfb\x90\xf4\x62\x12\xbc\x7c\xe6\x88\x44\x49\x73\x35\xcb\xb2\xb4\x7f\x09\x4f\xbb\x38\x9d\x8f\xe7\xac\x4e\x3f\xa0\xaa\xef\xce\x57\xfd\x94\x5f\x6d\x59\xd2\x77\x69\x3d\x6c\x8a\xba\xf0\x3a\xa5\x0e\x25\x7d\x3f\x41\x56\xb3\x53\xc6\x25\x60\xa3\xd9\xae\xb0\xad\x40\xa3\xdb\x64\xcc\xb5\x25\xbe\xc6\xfb\x99\xd8\x51\x25\x8b\x99\x6f\x51\x96\x56\x37\x40\xd7\x50\xde\x92\xea\x55\x32\x54\xd4\x7a\x67\xf3\x00\xa3\x82\xb3\x8c\x18\x75\xab\x9c\x4f\x6a\x86\xa2\xad\x48\x1e\x0c\xbd\x5c\x9f\x8c\x18\x20\xcb\xc2\xde\x0a\x7d\x50\x4f\x67\x55\xf5\x33\x50\xc3\xab\xc6\x81\x83\x85\xee\xd9\x13\x66\x53\xed\xcb\x88\x21\x08\xa8\xb0\xbf\x9c\xaf\x7a\xd6\x4e\x26\x81\xf0\xbd\x1e\x5a\x68\xa9\x00\xdb\x3a\xbf\x80\x9c\xc9\x24\xf4\x95\xc1\x3d\xbf\x2e\xf3\x9a\x40\x48\xc3\xaf\x92\x24\x2e\x26\x51\xf0\x8e\xf7\xee\xfe\x2b\xb1\x1b\x25\xb9\x88\x12\xa3\xe4\x8c\xe2\x80\xa9\x4c\xf9\xed\xb5\xfc\x85\xd5\x92\x5c\xcb\x20\xe8\xf4\x12\xaf\x9c\x11\xd9\x04\x4c\xcd\x8b\x38\x14\x9f\xcf\x67\xac\x74\xff\xd1\x02\xdd\xe0\xa5\xf8\x1c\x1a\x19\x89\x3e\x70\xf3\x3a\x29\x7a\xb7\x0e\x5f\xb5\x3b\xf0\xcf\xde\xda\xef\xdd\x81\xf4\x99\x6f\x6a\x19\xfb\x23\x4e\xfb\xd1\x25\x65\xec\x58\x9d\xf3\x0d\x75\x1a\xd8\xc2\xfc\xc4\xf3\x48\x45\x20\x4e\x7c\x8f\xa6\xfd\x63\x72\xe3\x95\xca\xf1\x10\xb5\xcc\x95\x32\x5a\x40\x57\x79\x98\xee\xb2\xca\x73\x91\x71\x01\x01\x09\x1b\x2e\x81\xe0\xdd\x57\x7b\x7b\xff\x14\xdf\x89\xa8\x77\xf5\x0d\x93\x61\x4f\xab\x5d\xc7\xe8\xf8\xb5\xd9\x95\x8d\x2d\xe9\xc4\x3d\x30\x87\xd7\x32\x56\x4f\xef\xe5\x12\x58\x88\xce\xa5\x01\xfd\x10\xcb\xd9\x98\x23\x7e\xf8\x06\x40\x79\x98\x9c\xf8\x0e\xf9\xed\x92\xc3\x64\x25\xa0\xf7\xb3\x40\x54\x1b\x6f\x1f\x03\xeb\x09\x5a\xe0\xcb\x7d\xd8\x6c\x77\xfb\xf9\xe6\xc7\x3d\x26\xd8\x50\x7b\xde\x0e\xd1\x82\x44\x43\x66\x2f\xcf\xcb\x5c\x93\xe6\xcf\x80\x4d\x55\x29\x27\x8e\xb1\xd8\x9f\xa5\x75\x9d\xc1\x73\x91\xf7\xfa\xa3\x95\xc7\x09\x71\xc6\x95\x95\x14\x98\x7a\x2f\xca\x53\x1e\xc6\x10\xaa\xe4\x9f\x23\x5e\xf9\xc1\xdb\x50\xbe\xc3\x48\x81\xed\x8c\x6d\xaf\xfa\x9c\xb5\x90\x1f\x3b\x22\x6c\x51\xf2\xf8\x45\xef\x2c\xb2\x7b\x96\x2b\x6a\xcc\x9d\x7c\x47\xca\xe7\x82\xa4\x18\xff\x53\x64\x79\x5a\xfe\x00\x51\xa5\x6d\x0c\xa6\x7c\x4d\x8c\x4a\x15\xd4\x7b\x5d\x94\xfb\xea\x2a\x51\xa9\x98\x4b\xfb\xd8\x9a\x63\x9c\x45\xac\x63\x63\x06\x2f\xa5\x02\x27\xc1\xe4\x99\x49\xe7\xda\xdb\x1f\x3a\x4b\x2a\x10\x80\x65\xfa\x13\x94\xba\x28\x8f\xbd\xed\xe3\xdf\xf1\xa4\x66\xef\xa0\x1e\x3b\xbd\xa9\xa8\x40\xc7\x58\xed\xfc\x84\x74\x0d\xe5\xf6\xcd\xa6\x26\x55\xe8\x09\xcc\x2e\x28\xd0\x20\x9b\x0d\x6b\xac\x9a\x69\xc6\x45\x81\x87\x3d\xec\xab\xf5\xeb\xd3\xe2\xc5\x8a\x14\x29\x15\x25\x8e\xcd\x7b\x3d\xa4\xd5\xa1\x79\x03\xc7\xdb\x54\x47\xc3\xf7\x11\x49\x0f\x41\x87\xa8\x80\x00\x55\xc5\x9f\xd2\xff\x3b\xa7\xaa\x17\xe8\xa8\xd8\xe7\x8a\xf8\x7a\x4d\x8e\x17\x94\xeb\xb5\x07\xb9\x4f\xc9\x0f\xb7\xfd\x8b\x76\x70\x57\xd8\x1e\x79\x59\xaf\xfa\x33\x5e\x25\x9a\x90\x05\x06\xd6\x96\x43\x39\x0e\x76\xaf\x58\x39\xaf\x89\x74\x95\xe2\x92\x88\x19\xb6\x36\xe1\x32\xd9\x49\xa3\x38\x30\x2b\xbc\x82\x20\xb5\xba\x1e\xb1\x1c\x29\x25\x38\x43\x3e\x41\x94\xf6\xdd\x14\xd9\x58\x4d\xcf\x0e\x03\x8f\x99\xa2\xc8\xfe\x23\x95\xb0\x3f\x19\x5a\x34\x13\xc3\x2b\xa9\xa9\xa3\xee\x99\xbf\x83\xa1\xae\xfa\xd2\x78\x29\xe5\x50\xf8\xbb\xf8\xc9\x8f\xa7\x0c\x26\xea\x21\x4a\xb9\x80\xfd\x06\x3f\x96\xbb\xc7\xfb\xcd\xec\xc7\xec\x69\xbf\x78\xb9\xef\x73\x69\x28\xe5\x7b\x48\x44\xbc\xaf\xcb\xcb\xae\x4c\xdf\xde\xc0\x76\xde\x4d\x25\xf5\x9a\x45\x86\xcc\x8f\x55\x0d\x27\x5b\x43\x57\xa0\xa5\x13\xf6\x90\xa0\x13\x72\x41\x83\x77\xa1\xc3\x50\x6b\x5b\xc9\x78\x4e\xdf\xca\x2e\x55\x02\x6e\x1c\xe3\x36\xb5\x7a\xfc\xf6\x3d\x6d\xb6\x7c\x9e\x77\xc7\x34\xa5\xe8\xfb\x76\xd4\x56\xa6\xc0\xf3\x43\xc4\x54\x61\xad\x0e\x33\x85\xc8\x03\x91\xf5\x14\x46\x14\x78\x91\x26\x1d\xed\xa2\xfc\x44\xfa\xf1\xc7\xc2\xaa\xf0\x0c\x9e\x13\x3c\xa5\x34\xbe\x16\x33\x92\xa0\x53\x83\x2f\x0f\x0c\x22\x24\xb1\xc1\x34\xed\x4c\xa9\xae\xb7\x0a\x02\xc9\xb0\x3f\x66\x5f\xd5\xc0\xb3\x39\x2f\x15\x32\x2a\x8e\xfc\x3b\x08\x1d\x8e\xb5\x27\x45\x1e\xd6\xf9\x1a\x76\x02\x61\xe8\xa3\x31\x34\x5d\x5a\x2f\x69\xfe\x9f\x6b\x14\xcb\x97\xeb\x13\x42\x1e\x70\xab\x8a\xdc\xd3\x1f\x50\x10\x01\xc9\x83\x6e\x2f\x64\xe7\xc6\xad\xae\x10\x69\x1e\x75\x5d\x9e\x6d\x63\xe8\xd8\x4f\x85\x98\x79\xdc\x14\xc2\xfe\xa7\x10\xa6\xa7\x6e\x72\xd6\x42\x1c\x2a\xe5\xda\x97\xb6\xf8\x79\x4a\x47\x62\xde\xbd\x91\x3c\xf1\xcd\xda\x6b\x02\x87\xb2\xc8\x46\xc8\x64\x88\x25\x69\x26\x36\x11\x9a\xf5\x0f\xf1\x41\xac\xf0\xe6\x75\x10\xf4\x85\x71\x85\x58\x2a\x84\x9c\xa7\xb2\xe8\x88\x58\x15\x24\x11\x43\xd7\x6d\x3b\xa7\x8c\x6e\x4f\x9a\x5b\x81\x70\x7d\xa4\xd9\x56\x85\x81\x28\x7d\x9d\x86\x00\xc1\x02\xe4\x45\x82\xe6\xc9\x61\xa9\x5f\xa0\xd9\x04\x79\xdb\x5d\x03\x22\x21\x0a\x26\x6a\xef\xea\xeb\x67\xf4\xea\x1d\x20\x03\x29\x01\x9d\x9e\xba\x86\xf2\x82\x10\x80\x8e\xd8\xbe\x6f\xfa\xcd\xc3\xb2\xd1\x67\x50\x8a\x1a\x10\x2b\xa8\x9f\x2f\xcb\xf9\x6a\x92\x86\x50\x01\x78\x2e\xae\xd4\x26\xf8\xdc\x17\x39\xe9\xf4\xce\x10\x0e\xf1\xc0\xb3\xaa\xbd\x1f\x1d\x11\x07\x31\x4e\xaf\xdd\x67\x71\x4f\xa1\x99\x39\xac\x5d\xcf\x75\x4d\xea\xc2\xe0\xb6\x3a\x66\x29\xa5\x5d\x88\xa4\x6e\xa5\xf6\x30\xb0\xfd\x8a\xe1\x46\x7b\x11\x29\xac\x36\x01\xfc\x6a\xf5\x44\xad\x25\x9e\x3b\x40\x47\x6a\x8f\x3b\x6d\xc5\xfb\x9e\x17\x0f\x45\x39\x3d\x21\xb5\xef\x27\x68\xe2\xd1\x6e\xac\x3f\xf3\x1e\x5f\x81\xf6\x63\x86\xad\xe0\x27\x80\x77\xcb\x09\x63\x0f\x25\xae\x34\x53\x7e\xcd\xd3\x11\xc4\x59\xfb\x92\x71\xe2\x49\xec\x4a\x3e\x9a\x31\x87\x58\x47\xe7\xb3\xed\xe3\xcf\xf6\xaf\x09\x09\xac\xdf\xf3\xd3\xe9\xb1\x8b\xfb\x35\x13\x02\x0b\x4e\xf7\xbc\xde\x15\xf7\x75\x29\x5f\xce\x47\x23\xaa\x6c\x47\x40\x84\x08\xa3\x1d\xaf\xde\x37\x26\x4c\xfa\x3a\x74\xd6\x81\x16\xe8\x5f\xb7\xd4\x0b\x7b\x7c\x83\xb3\xfb\x7b\x5b\xef\xd6\xa1\x2f\x51\x54\x6a\xb3\x5d\x3f\xed\xf6\x0f\xed\x9f\x13\x0f\x6b\xcb\xeb\xb2\x38\x41\x59\xa5\xed\xfd\x87\x5a\x04\x61\x57\xc6\x6f\xf9\x4f\x46\xeb\xc1\x8c\x8e\x1c\x27\x8e\xac\x64\xbe\xd1\xa3\x1e\x4c\xd7\x76\x9c\xc2\xb7\xb2\x3d\x15\x65\xdd\xe7\xa8\x53\x3a\xf2\x3c\x47\x5b\x57\x25\xe7\xd9\x0e\x1a\x57\xc5\x1e\x0c\x38\xb2\x81\x50\x35\x7f\x33\xdb\x2d\xf6\x0f\xcb\xcd\x76\xd7\x1e\x8f\x5c\xcb\xd1\xfc\x52\x28\x78\x04\x2c\x5f\x0e\xec\x80\x8e\x12\xc2\x1e\xce\x14\x3f\xfd\xfa\x95\x46\x3c\x46\x2a\x77\x9e\x96\xaa\x2c\x4e\xe3\x28\xc8\x26\x65\x75\xa4\x3d\xf2\x07\xcf\x25\x1c\x79\x6a\xcd\x8b\x8e\x3d\x81\xc0\xb8\xf7\x34\xcb\x1e\xca\x2e\x9f\xae\xe3\x90\x93\x5b\xd4\x78\x73\xc3\xdf\x8c\x63\x85\xc0\xed\xaa\x2e\x4e\x1d\xb5\xbf\xd2\x09\x63\x08\xdf\x33\xb0\xb9\x99\xd6\x69\x96\x8e\x45\x3a\x94\x4e\x12\xa1\x88\x19\xb7\x5e\x43\xbd\x83\xce\x7d\xb0\x03\x74\x88\x92\x4a\x2a\xad\x4c\x66\x62\x74\x03\x9c\xfb\x18\x54\x10\x89\x72\xe3\xd2\xd9\x53\x05\x8b\x49\xdf\xfc\xee\x7e\xf1\xb4\x9f\x3d\x3d\xad\xe6\xb3\x5e\xa3\xb6\x16\x5c\xd8\x4a\x57\xab\x2f\x3a\xbc\xb6\x74\x02\xcc\x48\x11\xa1\xcb\x5d\xe3\x9c\xdd\x48\x3c\x69\x15\xc4\x88\x30\x7b\xe0\x69\x86\x35\x61\x63\x9c\x7f\x95\x5e\xbc\x71\xb5\xd0\x0b\x0c\x68\xb5\x89\x8e\x5e\xf8\x11\x48\x59\x61\x2a\x29\xad\x95\x08\x08\xed\x89\x39\x92\x29\x95\x30\xb7\xbd\xb0\xd0\x66\x89\x70\xb5\x3f\xbb\xe1\x9e\x97\x25\xb7\x16\x5f\x43\xa4\x98\xa1\x95\x32\xb0\x91\x81\x21\xd3\x71\x80\xd6\x71\x56\x96\x5f\x95\xea\x87\x8f\xa2\x13\x2d\x79\x0b\x5c\x6a\x3e\xd2\x9a\xa7\xad\xed\xd2\xca\xc3\xea\xe1\x76\xf9\x2f\xe3\x07\x82\xe3\x30\xaa\x2a\xd3\x56\xff\x9c\xe6\x35\x94\x53\x3c\x48\xe0\x38\x91\x4f\x5a\x3e\xfc\xa4\xf8\xe9\x25\x3d\x8b\xd4\x5e\xc4\x15\x12\x57\xb7\xe4\xe5\x8e\xff\x4c\x5b\x7f\x62\x10\x1a\x81\xe3\x09\x49\x12\xdb\xa8\x21\x88\x2c\x2e\x7f\xbf\x5c\x05\x8e\xef\x08\x4c\xf3\xec\xad\x0e\xe0\x60\x02\x81\xe3\xc7\x0c\x41\x25\xa6\xad\x09\x4a\xd3\x5c\x72\x13\x38\x32\x3a\x5d\x86\xe8\x11\xe3\x9e\xf7\x66\x9b\x92\xc1\x61\x0e\x55\x7d\x4a\xca\x9e\xdb\xbf\xba\xa1\xcb\x2c\x34\x45\x35\x9b\xc7\x32\xbf\xbb\xb4\x3a\x04\xe0\xb0\x58\x39\xcc\x36\xe3\xbf\xf1\xdc\xe8\xb5\xf1\x6c\x0e\xa5\xe5\x20\xbd\xbb\x2c\xef\xfb\x5f\x1d\x9a\x25\x80\x34\x14\xa9\x0d\xd9\xed\xe5\x42\x3f\x44\x94\x0e\xbe\xbb\x23\xa8\x94\xab\xa2\x9c\x21\xc9\xfa\x9a\xbf\xf1\xc6\xe4\x16\x5d\xaa\xae\x19\x1f\x63\x7e\x95\x74\x1a\xb7\x07\x6e\xc5\xe9\xc0\x09\x39\x60\xad\xe3\x7b\x5a\x56\x97\x1e\xcf\x2a\x38\x21\x30\xcc\x5d\xa6\xf9\x01\xca\xb4\x46\x78\x39\x02\x2a\xec\x80\x38\xf2\xb0\x91\x70\x8f\xc9\xa2\x63\xf1\xc1\xb3\x6b\x2d\x75\x70\x62\x15\x61\xd0\xb3\x7b\xf8\x45\xf3\x39\x38\x49\x02\xe8\x6a\x42\xae\x3a\xe1\x28\x70\xb8\x62\xe8\x2e\xb6\xb5\x3c\x0a\x4e\xbe\xf3\x32\x6d\x1c\x8c\x76\x9c\xe4\xa4\xf3\x82\x52\x40\x6d\x03\xd3\xe8\x76\x14\x23\x46\xf0\x53\x59\xa8\xb3\x84\xc6\x79\x2a\x88\x79\x71\xd2\x37\x00\x47\x71\x0f\xe3\xd0\xf9\xec\x65\xbe\x78\x7a\x5a\xdc\xef\x1f\x16\x8b\xfd\xc3\xd3\xec\x9b\xfd\x5d\x48\x14\x36\xb3\x18\x0f\xb9\x28\xdf\x6f\x24\x3e\xc0\x01\xa9\x30\xa3\x59\x5d\xf2\xfa\xb0\x34\xac\x1f\xca\x26\xbd\x87\xf0\x41\xf6\x8f\x01\x4a\x81\x8d\x2e\xa5\x1d\xde\x7a\x40\xcd\x6b\xdf\xd6\x70\x0a\x46\x0f\xab\x3d\xf2\xaa\x08\x5a\x45\x66\x74\x52\x85\x03\x1c\x1d\x92\x42\xf2\x22\x57\xae\xe9\x2d\x02\xd7\x61\x84\x7d\x9e\x9d\xeb\xa2\x4c\xff\x1a\xb4\x03\x80\xeb\xc4\xa1\x67\x54\xc1\xea\x16\xb9\x02\xae\x23\x7d\xdf\x74\xbc\x5a\xac\xf0\xa6\xab\x34\x99\x41\x6e\x28\x7d\xd1\xe1\x16\x51\x5d\x6e\x34\x42\x52\xee\xe4\x98\xe6\x8b\xfa\x30\xef\x09\x33\xd9\x1f\xf2\x22\x57\xb2\xde\x1b\xe8\x85\xd2\xe0\x32\xc7\x47\x1a\x0f\xa4\x4d\x59\x34\x8e\x6d\x2e\x61\x57\x58\xbe\x0f\x78\x7d\x59\xfe\x61\x2f\xc4\x20\xc0\x6c\xf7\x62\xf7\x18\xf8\x4e\x91\x33\xaf\x7d\x03\x01\x23\x6a\x48\xa4\x30\xe3\x59\xdc\xbe\x3d\x73\x3c\x74\x38\x56\x5d\x90\xa5\xac\xfe\x5b\xda\x5d\xe0\x86\x9e\x83\x98\x62\x64\x98\x1e\x05\x5c\xe0\x86\x3e\x4d\x27\x3c\xda\x12\xf7\x0f\x3e\xac\x1b\x06\x41\x18\xf6\x54\x50\x6d\x70\x64\x8d\xec\xf9\xaa\x53\x16\xdc\x30\x89\x83\xd0\x1a\xa1\xf4\x2d\xcd\x27\x4d\xbb\x1b\x2a\x49\x34\x56\xc5\xb1\x30\x7a\x1c\xf6\xce\xa2\x88\x34\x34\xb8\x52\xff\x53\xa4\xf9\x8c\xbc\x9d\x7f\x5e\x01\xd7\xc0\x8d\x78\x8c\xbd\x7a\xaa\x98\x9f\xab\xba\x38\x9a\xa1\xe3\x55\x71\x55\xb7\x06\x37\x12\x10\x28\xeb\x55\x60\x4d\x1c\xda\x09\x17\x27\x8e\x1f\xb4\xa2\x88\x03\x24\xf7\xa4\x73\x00\x6e\xcc\x29\xa5\xa5\xd3\x3c\xad\x0e\xaf\x27\xc2\x49\x5f\xe7\x23\xc0\x4d\x1c\x87\x38\x45\xd2\x23\x54\x27\xde\x4e\xb2\x44\x25\x5e\xf3\xd6\xee\xca\xb4\x4e\xab\x43\x57\xc4\x01\x97\x0b\xea\xe0\x3a\xf1\x4b\xa1\x75\xbf\x62\x07\xae\x88\x04\xa6\x11\xd1\xf1\xdc\xbf\xbe\x3c\xad\xe6\xbf\xdb\x63\x32\x0a\x43\x93\x67\xeb\x6b\xdd\x80\x0b\xa0\x11\xfb\x7b\x28\x6a\xe4\xcb\x6d\xff\xae\x03\x44\x3e\x8c\x92\x8d\xd3\x36\xc6\xd5\x9c\x63\x5a\xde\x38\x80\x73\x64\xa3\x68\x13\x63\x5e\xf7\xca\xa3\xff\x1d\x86\xc2\xff\xf6\xec\x47\xd0\x9a\x5e\x5b\x25\xa6\x36\x57\xcf\x51\x1e\x76\xfd\xce\x7e\xa6\x30\x90\x63\x03\xcf\xd1\x89\xcd\x02\x6c\xb3\xa2\xbe\x12\xd3\x06\xcf\xf5\xa5\xa7\x6c\x11\x9e\xb0\x03\xc8\x2d\xda\x6a\xe6\x0c\xcd\x5e\xab\xa2\x03\x9e\xe7\x78\xc8\xdf\x7d\x28\xce\x15\x0c\x13\xc6\xe0\x79\x9a\x14\x40\x15\xef\xf7\x49\x34\x7f\x0f\x91\xfc\xf1\xe9\xf5\xcf\xd5\x78\xa9\x79\xbe\xf2\xfa\xb4\x48\xeb\x32\xbd\x41\x42\x06\x1e\x73\xe3\x88\x8a\x54\xbb\x9f\xe4\x11\xf6\x03\x06\xf0\x98\xef\x10\x2b\x3e\xe4\xea\x3b\x31\xea\x9a\x23\x81\x47\xf4\xcb\x07\xde\xb1\x55\x0e\xaf\x1d\x28\x47\x1a\xd5\x70\xec\x0e\x79\x4c\xdf\x0e\x3d\xf0\x19\x78\x61\xe4\x5a\x86\x1c\xec\x15\xc4\x8c\xf8\x04\xc3\x44\x33\xd2\x47\xb7\xea\xf7\xd4\xb6\x78\x82\x17\xc6\xd2\x6f\xf9\x9f\x89\x99\x6e\x04\x80\x07\x2f\x0a\x42\x74\xe8\x50\xfb\x06\x3d\x25\x14\x5d\x1e\xde\x67\x24\x3c\x42\x49\x75\xfd\xb0\x3d\xaa\x11\xf0\x62\x4d\x1d\x87\x47\xfe\x0e\x7d\x38\x38\x78\x89\x1b\x33\x3d\x62\xeb\xb5\xb0\x13\x3b\xc4\x0b\x02\xd3\x53\xdd\x78\x9e\x5f\x31\xb3\x83\x97\x44\x01\x82\x91\x1b\x87\xa5\x83\xfd\x80\x97\xa8\x18\x81\x01\x77\x9b\xa7\xfd\xea\x98\xa7\x0a\x39\xfd\xec\x51\xee\x69\x3d\x64\xac\xb9\x23\x7c\xdd\x75\x66\x0f\x3c\xe1\x3a\xe8\x92\x1f\x0a\x95\x41\xb9\x4b\x8f\xd0\x93\x90\x01\x4f\x04\x09\x32\x4a\x28\xa8\x90\xae\x85\x00\x46\x37\x6e\x57\xc5\x02\xe7\x3c\xd6\xe6\x07\xd3\x53\x09\x22\x0e\xde\x70\xad\xbb\x79\xa9\xa4\x42\x35\x03\x71\xbe\x3c\x3f\x4c\xc2\xc4\xcc\x40\xe0\x1c\xa3\x38\xf8\x79\x42\x0d\x83\xae\xbb\x73\x50\x21\x03\x0f\x74\xa2\x9d\x56\x45\x89\xd2\x9d\x03\x26\x5a\xf0\xb4\xef\x60\xb3\xdc\x46\xaa\x6f\xd0\xfd\x55\xb9\xb8\xae\xb8\x52\x48\x2b\x36\x02\x2a\x7f\x99\x76\x04\x4f\x6b\x86\x69\x47\x9b\x15\x46\x32\xb5\xc1\x23\xf8\x0e\x90\x50\xf4\x2d\xc6\x96\xc9\x07\xf7\x1b\xf7\xc7\xb6\x99\x9a\x2d\x72\x1a\xa7\x67\xc6\xbb\x11\x65\xc1\x97\xf3\x95\x69\x58\x68\x7e\xe4\xd5\x34\x62\x81\xef\x8a\x10\x59\x29\xe7\xb3\xcd\xae\xfd\x9b\xd6\x88\xbe\x9e\x0d\x5a\x51\xc0\xf7\xa4\x8e\x89\x81\xfe\x67\xfb\x27\x00\xc1\xbb\xd2\xc9\x52\xdd\x5d\xd6\x45\x35\x7a\x52\xe6\x38\x98\xf7\x33\xdd\x8b\x73\x5e\x1d\x7a\x0e\xb7\xcf\x14\x17\x46\x0d\x11\xb1\x3d\x37\xa8\x5e\x46\x5c\x2e\x66\x01\xfb\x01\x4b\x58\x62\x2b\xb7\xf8\x80\x15\xea\xed\x92\x67\x49\xab\xd1\x64\xb9\x07\x9f\xc8\x0f\x02\x2f\xb0\x50\x18\xac\xd9\xcd\xb4\x5e\xde\xdf\x78\x8d\x41\x14\xba\xfd\x2c\xff\xb8\x86\x0d\x7e\xe8\x6a\x23\x59\x55\x97\x29\x7c\x18\x5e\x16\xfb\x8c\xa1\x0f\x46\x73\x2a\x57\xcf\x45\x0e\x97\xbb\x96\xcb\x12\xfc\x10\x42\xec\xdc\xdd\x42\x3d\x09\x16\x03\x3f\x6e\xec\x30\xc6\xdb\x75\xfa\x81\x21\x91\xb5\x30\x7e\xe2\x7a\x9a\xf7\xb0\x02\x6b\xf4\xef\x6f\x8b\xe9\x5d\x59\x2f\x3f\x61\x44\x89\x4d\xb2\x20\xbf\x98\x7f\x49\x20\x95\xc9\x9d\xae\x8b\x2c\xad\x53\xd9\xbc\xee\xff\xe1\xf2\xfd\x54\xd4\x3d\x01\x61\x52\xe4\xed\x16\xa2\x2f\x7d\x92\xa7\xfd\x17\x94\xc5\x1f\xfd\xcf\x2f\x63\x86\xa0\xed\x53\x09\x1f\x69\x71\xae\x10\xe1\xb9\xac\x46\x3c\x89\xe0\xcb\xc4\xb3\x33\x1f\x67\x3c\x35\x21\x8c\xdc\xc4\xd1\xdd\x4a\x1e\x5b\xe9\x9c\x07\x42\xe8\x4e\xdb\x13\x5f\x0a\x81\x81\x6a\xfa\x83\xe7\xf5\x1f\xff\xd3\xd3\xb9\x33\x03\x14\xd7\x84\x61\x38\x14\xe7\x4c\x51\x91\xef\x0b\xe2\xc5\xff\x96\xb9\xca\xfe\x8a\x22\x45\xf5\x23\xd5\x85\x06\xe6\xb9\x9d\xf1\x0a\x14\x87\x16\x1b\xdb\x89\x8b\xde\xa0\x46\x9a\xb4\xcc\x3e\xf8\x3e\x7e\xc7\x53\xc6\x2f\xa6\xb1\xcf\x1e\x61\x44\x37\x21\x9a\xcd\xf6\xa1\x89\x22\x76\x9f\xc5\x3d\xbf\xb4\x33\x0e\xb8\xc4\xd0\xd9\x7a\x22\x16\x73\x65\x0f\x43\xe2\x1b\xdc\xc8\x3c\x4b\x21\x1f\x37\x48\x7c\x4d\xe4\x74\x1e\x35\xcf\x82\xaf\x7d\x16\xb9\xad\x63\x5c\x97\x5c\xb5\x2e\x46\x73\x0c\x53\xba\x92\x88\x16\x96\xb9\x2c\x46\x2a\x5b\xc0\x1c\x87\xe0\x65\xbf\x9f\x55\x51\x4d\x49\x93\x0e\xe2\x95\xd1\xb9\x01\x43\xa0\xa5\xc4\xfa\xe7\x06\xf8\xd4\x14\x9a\xaa\xf3\x01\x73\xe2\x18\x63\xfa\xea\x7c\xbc\x87\x93\xd1\x01\x6a\x77\x7d\xe6\xc4\x3c\xd0\x46\xbc\x0f\xca\xfd\xa9\xeb\xe8\x36\x03\x5c\x87\x31\x83\xe7\xc1\x18\x6b\x79\xd5\x5b\x6f\x06\x7a\x91\x70\xa5\x51\x28\x4e\x73\x05\xe5\x95\x6d\xfa\x7f\x58\xfb\xb3\xee\xc6\x71\x64\x0b\x14\xfe\x3b\xf5\x70\x1e\x38\x80\x20\xf8\xa8\xc9\x4e\x75\x79\x50\x4b\xca\xcc\xaa\x3e\xeb\x2c\x2d\x0c\x01\x9b\x65\x8a\x54\x73\xb0\x53\xf5\xeb\xbf\xc5\x00\xc0\x49\x74\x66\x7d\xf7\xde\x97\xce\x6a\x13\xa4\x38\x00\x81\x18\x76\xec\x4d\x82\x24\xc1\xa5\xf3\xc8\x7f\x54\x03\x6c\x22\x10\xe2\x87\x18\x00\x22\xca\xa9\x28\xc3\xee\xef\x31\x11\xa4\x57\xe4\xbd\xbd\x22\x81\x40\xd9\x98\x4a\xc1\xa5\x2e\xe1\xbf\xb6\x1d\xc3\x1e\x8f\x62\x0f\x4b\xcc\x4e\x4b\xc8\x04\xd0\x3d\xc1\xdb\xc0\xff\x9e\x3c\x4e\xc4\x03\x6a\xd4\x19\xc6\x59\x0e\x12\x71\x43\xb2\xb9\xcd\xf3\xe2\xbd\x23\xd2\x74\x07\xa5\x12\x26\xed\x65\x3d\x5d\x1b\x1d\x66\x3d\xac\x0d\x48\xa4\x08\xee\x85\x08\xc0\x7e\xe5\x8e\x7f\xad\x3b\xac\x15\x1d\xb2\x2b\xde\x7c\xe7\x81\xd1\x24\x34\x30\x22\x25\x58\x6c\x3d\x1d\xf7\x8b\xd5\x29\xf1\x5c\xf4\x4c\x28\x0d\x71\x5e\xbe\x3b\x59\xfe\xae\x95\x0d\x08\x15\x09\x46\x48\x28\x45\xf5\xfb\xd3\xf3\xf7\xa7\xd3\xf3\x7e\x7b\xef\xb8\x85\xda\x01\x1a\x21\xc4\xef\x50\xa6\xfa\x6a\xab\x5c\xbf\xcd\x14\xef\xdc\x78\x48\x30\xdf\x59\x59\xf4\x7e\x77\x1d\x00\x9c\x62\x97\xa2\xaa\x9f\xe0\x63\x91\x57\x1f\x9f\xa0\x91\x81\xc4\xbe\x87\x84\x65\x59\x6b\x59\x61\xd0\x8c\x0d\x24\x56\x92\xdb\xf6\x41\x93\x2f\x7a\xd6\x66\x5d\x77\x5f\x86\x05\x52\x5a\xf7\xd2\x0a\x09\xd8\x9b\x6e\x83\xe5\x4e\xfd\x16\x08\xe3\x12\xf3\x16\x28\x67\xbb\xd9\x1f\xb6\x0b\xc7\x52\x04\x84\x29\x86\x55\xb2\x1a\xf8\xf9\x64\x79\xab\x27\x7e\x04\x49\x3c\x8e\x46\x7a\xc9\xf3\x7c\x0e\xe7\x05\x24\x21\x51\x6c\x15\xf5\x5c\xdf\x68\x4f\x5e\xe7\xc6\x44\x3e\xd8\xec\xc9\xb2\x2c\x3e\x4d\x59\x11\xee\x25\xbe\x67\xb7\x6c\xe3\x46\xe0\x5b\x99\xdd\x3f\x08\xf7\x84\xef\x9b\x4d\x6c\x51\xb5\x8e\xf1\xe4\x47\x39\x89\x71\x91\x9e\xe1\x5c\x94\x57\x23\xc6\xec\x1e\x9d\x53\x81\x06\x2a\x87\x0f\xc3\xd7\xf5\xd3\x0c\x30\xe1\xb1\x8f\x8e\x86\xcc\x8a\x0a\x46\x2a\x12\x83\x17\xc1\x13\x0f\x81\x19\xf7\x45\xc9\x4d\x76\xf3\x97\xd9\x19\xc2\x05\xf7\x3a\x12\xce\x3d\x75\xb7\x27\xfc\x38\x1e\x32\xa0\x8f\x9b\xe6\xc7\x8f\x29\x44\x88\x9c\x76\xdf\x17\xe7\xcc\x51\x93\xdb\x43\x32\xe4\x9e\x74\x44\xa3\x66\x45\x98\xbe\xaf\xd1\x3d\x48\x12\xa9\xa8\x57\x76\x6a\xae\x1d\xdb\xce\xf8\x25\xc8\x04\x30\x0a\x39\xee\x9f\x9f\xb6\xab\xee\x37\x04\xc7\xd6\xb6\x7d\x2a\x5f\xef\x8b\x4c\x8d\x4c\x84\x94\x01\x26\xc6\x2c\xfe\xdc\x94\x34\x3f\xf9\xf6\x12\x0c\xf7\xfd\xbf\xbe\x3e\xfc\xe9\xce\x57\x9e\xe5\x76\x1c\x72\xfa\xd1\xf1\xed\x2b\x21\x22\x18\x57\xf8\x96\x57\x03\xc5\x1c\xff\x40\x1b\xfe\x58\xfb\x89\xa1\x18\x4e\xd5\x8e\xf6\xcb\x62\x0a\xed\x58\xe0\x91\x63\x83\x5b\x3b\x15\xc2\xd9\x78\x9a\x80\xf0\x60\x10\x2e\xdf\x95\xc5\x79\x02\xbb\x68\xc7\x28\x24\xf9\x59\x3e\x7f\x7d\x3a\xfe\x79\x3a\x7c\x59\xec\x5d\x1d\x84\x68\xa2\x95\xb6\xe2\xe5\x65\xda\xc6\x55\xc3\x9c\x79\xe4\x71\x8d\xcd\xe2\x38\x41\x6e\x92\x31\xa3\x9f\x89\xfc\x84\xa1\x31\x6d\x37\xb6\x75\xf1\x31\x89\xa8\x23\x5f\x48\x24\x14\xb9\x6b\x72\x39\xfc\x4a\x51\x10\x4a\x44\xd7\xaa\x26\x7f\x81\x22\xdf\x95\x70\xe1\x03\x94\x84\x1d\x15\x7a\x0c\xf9\x2b\x97\x69\x7d\xc9\x9a\x6a\x3c\x25\xc7\xbf\x14\xb2\x18\x23\x70\x38\x43\xf9\x02\xb9\xbc\xde\x61\xd7\x29\x62\x3c\x55\x77\x3d\x9d\x50\x36\xe2\x37\x1a\xc6\xbc\x11\x91\x11\x1e\xee\x2c\xec\xf8\x27\x88\x0e\xb0\x0c\x72\x2e\xf2\xfa\x75\x92\x9f\x89\x68\xc8\x10\x45\x90\xda\xf9\x70\x92\x45\x5e\xf3\x29\x6b\x0c\x44\x94\x30\xa7\x2a\xba\x87\xaa\x38\x5e\x2f\xdd\xd3\xc6\x3e\xe0\x7b\x5f\xa6\x2f\xa2\x38\xcf\x3e\xec\x3f\xe6\xe2\x9b\x9d\xef\xed\x2f\x30\x3d\x90\x0e\xbb\x11\xe4\x98\xbc\xd4\x38\x30\x4a\x07\x5c\x29\xec\x4c\x9b\xf3\x80\xa2\x98\x86\x28\x57\x30\xce\xf9\xdf\x41\x57\x1d\x9f\xcf\xfa\xdb\xb3\x93\xc0\x84\x05\xce\x83\x40\x06\xe3\xc1\xb6\x17\x25\xb1\xc6\x04\xd7\xc9\xe4\x38\x8f\x9d\xeb\x14\x25\xc2\x08\xfb\x9d\x8b\xaa\xdd\xe3\x51\x15\x23\xcb\xba\x05\x15\x71\xad\xad\xa8\x35\xfe\x7e\xc8\xdd\x01\x91\xc8\x18\x37\xa8\x36\xe0\x3f\xa4\x2f\x26\x6e\x7c\x1c\x44\xe5\x13\x2c\x1d\x44\x82\x0b\xdc\xfb\x10\xff\x57\xdc\x83\xab\xc6\x43\x24\x03\x82\x33\x59\x23\x5b\xc4\xb7\x76\x33\xb7\x1a\xc6\x87\x8c\x57\xaf\xa3\xb4\x69\xa4\x34\x95\x36\x5f\xab\x1e\xd0\x29\x19\x7f\x20\x88\x4d\x49\xcc\x80\x75\x97\xbc\x82\xd9\x9e\x9b\xf9\x2d\x23\x02\x1e\xa2\x4b\x2e\xac\x2f\x39\xda\x3a\xa7\x63\x05\x71\xda\x8d\x07\x59\xa6\x97\x7a\x21\xfb\x16\xaf\xe9\x58\x30\xe9\x9d\x76\x6c\x21\x53\x98\x48\x5c\x43\xa4\x43\x85\xcd\x58\xae\x6f\xeb\xe8\xf8\x9d\xad\x84\x98\x7d\x7c\xea\x79\x01\x46\xc0\x67\x47\x27\x67\xcb\xc7\x78\x04\xdf\x2f\xfc\x80\x09\x85\xa8\x1b\xe0\x7b\xda\x49\xea\x77\x42\x77\x1d\xfe\x67\xfa\x5e\xc6\x19\xd6\xf9\xd9\x4d\xbd\x84\x31\x6b\xc5\xad\x23\x83\x35\xca\xa6\xef\xcf\xc5\x31\x89\x25\xef\x5a\xf1\x72\x24\x24\xc5\x66\x23\x1d\x77\x9e\x00\x7c\x52\x7c\x13\x06\xfe\xd7\x57\x76\xa8\x07\x31\xc6\x3a\xff\x59\x3c\xfe\x67\xe1\xfe\xe8\x53\x40\xa2\x2d\xeb\x8c\x3b\x02\x01\xa0\x81\x1f\xe3\x02\x43\x81\xbd\x0e\x04\xe3\x0e\x42\x82\x0f\xf1\xb8\x7d\x3a\x59\x7a\x87\x85\xeb\x4a\x01\x1a\x7a\xb1\xb4\x06\x6f\x3d\xa5\x79\x04\x1a\x12\x93\xb0\x31\x55\x88\x75\x5a\x82\xac\xbb\xa0\x81\x86\xd2\x88\xba\xef\xa1\x4e\xbb\xcd\x81\x86\x3a\xc6\x45\x77\x2c\xc4\x1b\x1f\x6c\xfc\x94\x78\x49\x60\x72\xcd\x2f\xad\x11\x70\x24\x63\x3f\x79\x47\x91\x0a\x10\xe1\x81\xfe\xc1\x69\x42\x70\xdb\x8f\x41\x82\xed\x77\xde\x64\xf5\xb8\x5c\x43\x69\x98\x24\x96\x4a\xe4\xb9\x79\x87\xb2\x8d\x38\x4e\xa0\x1d\x38\x78\xfc\xac\x31\xe5\x08\x24\x72\x5e\xff\x49\x38\x42\xba\x49\xdc\x4d\xe3\x76\x7b\xc4\xb6\x83\xba\xe1\x19\xee\x8c\x8e\xc6\xd5\x8e\x60\x71\x80\x15\x08\x0c\x55\xbb\xb9\x7e\x28\x32\xd5\x8d\x48\x28\x5a\x79\x44\x12\xb5\x36\xe9\x15\xb8\x3a\x34\x97\x4b\xd1\xed\x36\x34\x09\x24\xf6\x0c\x43\xc9\x2b\x38\xf5\xca\x56\x40\xb9\xa2\xa8\x14\x79\x57\x94\x12\x86\x89\x72\x2a\xa8\xe0\xd6\x9f\xb0\xf8\x76\x4c\xa3\x74\xfc\x63\xd5\xb0\x46\x48\xa5\x17\x6a\xcb\x42\xfd\x06\xea\xae\xe8\x45\x59\x3e\x43\x09\x8c\xa2\x05\x2a\xa3\x08\xf7\x54\xac\x31\xae\x5e\x41\xbe\x5d\x8a\x34\xaf\x07\xf8\x4a\xa0\x92\xfa\x88\x41\x6b\xf2\x0a\x3a\x80\xe2\xbc\xbb\x45\x25\x8b\xd1\x03\x4e\x6b\xf8\xbc\x91\x0d\x6d\xd5\x70\xe5\x4b\xd0\xe8\x43\x9c\xab\x97\xcd\x0f\x7e\x4e\xfb\x52\x2c\x55\x5e\x14\x71\xb3\x64\xfa\xfa\xea\xe8\x64\x95\xf8\xe0\x1c\xb0\xae\x6f\x70\xa0\x26\x0c\x54\x4b\x9f\xf9\x5d\x5a\xcc\x82\xc2\xcd\xb1\x36\x5a\xc2\x74\xfb\xa9\x8d\x37\x73\x2b\xb4\x32\x9a\x57\xb1\xef\x33\x6e\x04\x48\xb2\x66\xae\x1b\xc3\x0d\x0b\x08\xb3\x82\xe5\x16\xf8\x6c\x0f\x84\xb1\x8e\x0d\xc0\xf6\x70\x6e\xb7\xa1\xaa\xc6\x19\xf7\x35\x9f\x50\x36\x43\x1c\xb2\x08\xac\xc5\x36\x89\xcc\xc3\x85\x4b\xa8\x5e\xd3\xcb\xc4\xc7\x88\xc3\x84\x85\xdc\x02\x05\xca\x77\xd8\xed\xbb\x1f\x53\x0c\xf5\x1f\xff\x2a\x52\x0b\xe0\xb8\x49\x13\xc6\x24\xa0\x44\xf5\xef\x63\x94\x43\x8f\x49\xc8\xc6\x74\x05\xf6\xf8\xf4\x0e\x48\x28\x71\x9f\x7b\x5c\xad\x76\xce\x8e\xc5\x11\x11\x08\x4d\x10\xcd\x35\xf0\x86\x93\x28\xa6\x9e\x71\x02\xf8\x28\xa6\x9a\xbc\x42\x16\x68\xc7\x7f\x81\xca\xab\xad\xa3\xe8\x30\xdc\x6e\xca\xc6\x8c\x86\xe8\x43\xe5\xd5\xc4\x5a\xc4\x8c\x41\xec\x75\xbd\xdd\x46\x9c\x51\x64\x30\xce\x1d\xc4\x4c\x08\xb4\x37\xce\x4c\xb4\x1e\x45\xa7\x2f\x0d\x31\x03\x1a\x51\xdb\x8e\xdd\xde\xa5\xfb\x7b\x22\x39\x0a\xa1\x5c\x8c\x57\x89\x05\xac\x70\xb4\xf5\xc7\xdc\x8f\x88\xc5\x33\x64\xef\xd9\x93\x9e\xe6\x5a\x62\x1e\xfa\x94\xf4\x5c\x97\x8b\x46\xa5\xb5\xab\x46\xb8\x21\x3c\xc6\xc6\x1c\x44\x0c\xb6\xae\xeb\xd0\xa7\x8e\x05\x61\xf8\x82\xd2\xea\xf9\x02\xf9\x30\x64\x34\xb8\x31\x37\x4e\x7a\x54\x18\x35\xb1\x74\x40\xc9\x01\xb1\x0c\x12\xe9\x77\xcd\xbe\xeb\xc5\xf3\xb0\xda\xde\xdf\xa7\x94\x2a\x06\xa7\x19\xf1\x98\xe6\xe9\x5c\x57\xb9\x1b\xab\x14\x92\x2d\x1e\x3f\x8a\xb5\xfb\x19\x08\x18\x66\xbc\x0e\x28\x0d\xfe\xca\xd3\x7c\x08\x7e\xe8\x5e\x35\x28\x10\xf6\x67\xbe\xee\xb7\xcb\xbe\x03\xc9\x1e\xd7\xed\xf6\x31\x84\x94\x99\xb2\xc0\x8d\xdb\x1e\x6b\xc5\x85\xd9\x98\xea\xa6\xcc\x31\x2b\x3f\x9e\xad\xcc\xf3\xe2\xd0\xa8\x4e\x8f\x3a\xd4\x27\x83\x02\xed\xd9\xd6\xff\xad\xb4\x2c\xc8\x03\x93\xcf\x3c\x65\x14\xbc\x75\x56\xf0\x7a\x23\x8b\xbc\xc8\xdd\x56\xca\x7c\x15\x61\xe1\x7b\xb5\x7f\xfe\xbe\x3e\x7d\xdf\x6c\x7e\x0f\x47\xac\xe5\xd0\xce\x6d\xac\x99\xab\x92\xa7\x3f\x11\x3c\x6a\x07\x6a\x6d\x55\x73\x77\x45\x96\xb9\xd7\xc5\x42\xea\x21\x67\xcd\xe9\xcc\xd3\xbc\x3e\x6d\x72\xb5\x2b\x8b\x73\xd1\x1d\xe6\x14\x33\x7d\x87\xd7\xb4\x5e\x65\x45\x0e\x55\x56\x94\x6a\x0f\xff\xed\x06\x08\x43\xe5\xf7\x50\xbc\xdc\xa1\xa3\x3d\x68\xfa\xfd\x79\x54\xc1\x42\xad\xd1\x71\x79\x4f\x2f\x3d\xad\x06\xb0\x88\x28\xc0\x28\xb3\x10\x3b\x9e\xd7\xe5\xf5\x38\xbf\xb0\x59\x24\x34\x62\x65\x06\x04\x98\xed\xea\xbc\x49\x3e\x4c\x4f\x03\x02\xda\xb2\x59\x6f\xf2\x97\x34\x87\x6e\x2a\x33\xaa\x22\xdb\x4d\xff\xd6\x37\xcf\x98\x9d\x74\xfe\x62\x54\x99\x72\xe7\x61\xfb\x74\xff\x60\x7c\xa8\xd3\xe3\xd7\x87\xe3\x76\xf7\xb0\xdd\x38\xfb\xc9\x62\x6a\x10\x41\x69\xfe\x9e\x22\x99\xb8\x4e\x27\xe5\x26\x16\x0b\xa9\xa5\x8b\xef\x70\xbb\x9f\x5d\x19\x2c\x96\x3e\x17\xdd\xac\x9c\x14\xbb\xff\x11\x8a\x81\xb1\x40\x25\x56\xbc\x05\x31\x2a\x46\x7c\xf0\x93\x07\x64\x4c\x28\x23\x36\xfa\x5e\x03\x3f\xdb\x1a\x9a\x7b\xb0\x24\xf1\xb0\xf5\x6e\xb7\x7d\x76\xbe\x23\xe3\x24\x46\xfc\xeb\x47\x27\x65\x7b\x24\xc7\xee\x60\x14\x21\x4b\xe7\xcc\x2c\x71\x23\xa4\xc2\xaa\x3c\xf2\x04\x56\x23\x20\x08\x13\xc4\xf0\x6c\x7c\x69\xaa\x6a\x28\x1d\x08\x4c\xa8\x10\x53\x13\xdb\xac\x39\xff\x31\x3a\x22\x7d\x81\x79\x19\xac\xf2\xaf\x07\x60\x9b\x5b\x90\x0d\x93\x2a\x46\xc7\xf6\xd2\x09\x33\x3a\x1c\xc7\x53\xe1\x22\x76\xa6\x44\x28\x0d\x8e\x84\xab\x2c\xcd\x01\x13\x34\x4f\x03\x76\x47\x60\x4a\x91\x84\x0f\xe2\x65\xd4\x54\x68\x8d\x7a\x3f\x04\x24\xe8\x01\xc3\xdb\x42\x29\x63\x53\xdd\x4b\x19\xda\x2c\x06\xa0\x99\x53\x13\xbd\x40\xde\x99\x64\xa6\x43\x1f\x91\x47\x35\x54\xf5\xb9\x72\xa9\xdd\xa4\x8d\x22\x3a\x5e\xeb\x5d\x51\x64\x55\x2f\xca\x0b\x89\xef\xc7\xf8\x46\x64\x53\x96\xd7\xd5\x6b\x2a\xdf\x20\x1f\xbe\xb2\xc4\x0f\xb8\x67\x6f\x7f\x71\xe5\x79\xbd\x2e\x8b\xd4\x98\xa6\x73\xfa\xdf\x06\x4e\xab\xe2\x7c\xa9\xe1\x14\x77\xe3\x43\x81\x39\xf9\xcd\xf1\xcb\xe9\xee\xeb\xd3\x7a\x3c\xb5\x13\x9f\x1a\xb2\x16\x04\x8d\x3e\xbf\x43\x79\x48\x7f\x74\x24\xb5\xdd\x35\x14\x20\xd9\x8e\x46\xec\xee\x27\xc9\xd9\xc4\x07\x81\x3a\xa3\xf5\x4b\x79\x30\x48\xe4\x6a\x65\xb9\xbc\xcc\x86\xf7\x8b\x80\xf7\x9f\xd5\xd9\x92\x40\x1a\x9b\x5c\x41\x6d\xbb\x35\xa6\xc2\xa8\x90\x04\x3a\xc4\x28\x84\x57\xf5\xd0\x85\x4f\x88\x1f\xa2\x09\x39\x19\xce\xb7\x51\xd7\xdb\xf8\x61\x22\xf0\x7c\xeb\xdb\x39\x7f\xe4\x26\x65\x9a\x50\x2f\xc4\xc4\xf7\x05\x5d\xb7\x74\x2a\x47\x03\x09\x15\x46\x28\xf7\x94\x56\x77\x4d\x96\x3d\x97\x4f\x4d\x36\x4f\x2b\x08\x09\xd5\x1c\x09\x89\x16\xdf\xff\x7c\xe4\xf9\xef\x00\x17\x43\x6e\x65\x0f\xc7\x91\x46\x90\xf7\x0a\xc1\xc1\x87\xe3\x7e\xde\x26\x24\xcc\xd7\x7a\x28\x26\xd3\xd5\x18\xef\x8a\xf2\x1b\xcf\xd3\xfa\xfa\x75\xff\x30\xb9\x4d\x46\x8d\xfa\xc2\x7f\x1b\x5e\xd6\x7d\xd2\x3f\x69\x0d\x9a\xef\xba\x63\xd6\xf0\xeb\x9e\x61\x48\x18\x53\x08\xc7\x5e\x96\xc5\x20\x90\x4c\x92\x24\xf6\x6c\x61\x71\x04\xf7\x70\x87\x79\x9c\x58\x04\xfb\x13\x7c\x74\xe1\xf0\x1c\xec\xf6\x7f\xa6\x67\x26\xcc\xe9\x2c\x5a\xcf\x66\x5a\xd6\xed\x53\xeb\x49\x22\x23\xcf\xf6\x32\x60\xe9\x79\x6b\x81\xdc\x9f\x7c\xdf\x04\x14\xd5\x2e\xef\x8d\xcb\x8a\xf8\xee\x89\x38\x8d\x4c\x51\x79\x90\x6c\x4c\x78\xc2\x03\xe6\x36\x0a\x9c\xf4\x3f\xe9\x29\x83\x84\x73\xc6\x65\xdf\x5c\x7f\xab\x1c\x31\x3f\x37\x85\x17\x63\x2f\x88\xc9\xcb\x99\x42\xfb\xf8\xc2\x22\x34\x40\x79\x59\x14\x6f\x5f\x2f\x5d\x7f\x5f\x7b\x00\x18\x1f\xc9\xcd\x4d\xcf\xe4\x89\x21\x3f\xe3\x3f\x86\x1e\xdc\xae\x27\x7d\xb1\x03\xa5\x6f\x3a\x63\x5f\x21\x53\x9f\x59\x04\xc5\x12\xf4\x5f\x0c\xa0\x1d\xcd\xd8\xb1\x78\x44\x7a\x33\x77\x19\xa5\x0c\x5e\xe5\xa5\x7d\x05\x98\x27\x7e\xe0\x55\x3d\x94\x26\xb0\x03\xc1\xf7\x0c\xdf\x96\xa1\x27\xb1\x7e\xc5\x86\x97\xf9\xb0\xac\x3b\xe5\x30\xfd\x2c\xc5\x3a\x98\x13\x10\xc6\x98\x38\x54\xc0\xeb\xd7\x35\xaf\xf9\x49\xfb\xcc\xdd\x1e\x10\x9a\xd8\xb6\x9f\xb5\x65\xad\x6b\x3d\x0f\xf9\x0a\xeb\x5b\x12\x3b\x48\x74\xa0\x90\x30\xe4\xb5\x68\xca\x5d\x51\x7f\x49\x5f\x5e\x2b\xd9\x83\x22\x13\x1d\x77\xaa\xa0\xdb\xbc\x82\xb2\x5e\xf1\x72\xda\xf0\x3c\xfb\xaf\x3f\xaa\xae\xdf\xfe\xaf\xbb\x3e\x67\xc8\x96\xd3\x7a\x45\x3f\xfe\x1f\x75\x93\x00\xf7\x08\x35\x75\x79\x5e\xbd\x3e\x37\xf5\x61\x22\xf2\x02\xdc\x8b\x08\x06\x3d\xbd\xf0\xb8\x9b\xe1\xf6\x36\xb8\xef\x85\xb1\x95\x65\x32\x39\xdc\x91\xe8\x82\x1b\x14\x10\x4c\x7b\x18\x3e\xc2\x41\xcc\xfa\x3f\xa3\xdb\xf1\x95\xc4\x68\xa3\x6e\x27\x24\x22\x05\xba\xd4\x23\x0f\x48\x1c\xf6\xf3\xeb\xc4\x4f\x39\x7c\x9c\x0c\x7d\xde\xaf\xb8\x2e\xdc\x15\x18\x47\x4c\x5e\x93\xab\xe2\x38\xb4\x98\xee\x27\x42\x3f\xc0\x15\xfd\x2c\xd2\xb2\x39\x6f\xab\xaa\xe9\x36\x78\x1e\x4a\x86\xe0\xa7\x1d\x2f\x55\x53\x3d\x41\xfd\x51\x94\x0e\x18\xc4\x89\x67\x2a\x83\xb2\x38\x5f\x8a\x0a\xfe\x85\xdc\xa9\xa3\xbb\x0a\x83\xff\x8d\xfe\x6f\xf0\x5f\x33\x90\x86\xff\x0d\xbc\xff\x73\xd7\xb3\x58\xa1\x3d\xa8\xe5\xd7\x3f\xba\x5f\x09\x43\xc4\xaa\x1d\xcb\xb4\x39\x7f\x29\xb2\x5e\x71\x10\x38\xe1\x80\x01\x78\xeb\x22\xad\x1b\xe8\xfe\x6c\xb5\xed\xdb\x39\x68\x17\x2e\xf9\x29\x51\x1c\xf0\xc8\xe3\x10\xba\x6e\x72\xa4\x7d\xe4\xd6\x28\xa4\xc5\xc4\xf4\xf0\xc8\x07\x4c\xfa\x1e\x9a\x3c\xbf\x76\xf7\x19\xf9\x9a\xf9\x8e\x62\xfe\xf7\x3f\x57\x37\x5a\x26\xc0\x23\x9d\x48\x5b\x4a\xdd\x15\x6f\x70\x2e\x6e\x0b\x25\xe3\x5f\xa2\x71\x8c\x16\xe8\x71\xe5\x2a\xd1\x9c\x26\x02\x31\x1f\x4b\xa7\x51\x0c\x3c\xf6\xa2\xd8\x95\x87\xba\xa6\x4b\x9f\x76\x87\x03\x53\xcc\x52\xd5\x42\xa9\x79\x33\xcd\x63\x6a\xda\x7e\x54\x5a\x5d\x9a\xda\xfa\x94\x53\xa4\x1c\x8f\xa5\x8f\x01\xe7\x0b\xaf\x70\xba\xdf\x15\x25\x4a\x58\xe4\x15\xbe\xac\x45\xfd\xa5\x38\xc3\x21\x55\xdd\x87\x60\x42\x61\xdd\xde\xd4\x05\xbe\x19\x97\xe9\xa6\x9f\x18\x78\x42\x98\x34\x94\xa9\xf5\x7d\xaa\x9d\xe5\xe4\x9c\xc4\x34\xea\x5a\xfc\xb1\x83\x76\x50\x45\xe6\xc2\xa3\xa8\x66\x63\xa4\x8a\xa7\x5c\xfa\xe3\x5f\x10\x61\x84\x51\x41\x5a\x21\x24\x62\xd0\x89\x3b\xf4\x74\xb9\x48\x6c\x90\x0f\x99\xce\x32\x28\xaf\xc8\x08\x53\x34\xb9\x1a\x71\xdf\xfe\x63\x72\xac\x7f\xf2\xaf\x33\x29\x82\x4b\xc9\xe6\x00\x1e\x9f\x3c\x91\x30\xa5\x07\x4c\x22\xce\xd0\x5a\x02\x17\xca\x10\x4f\xa4\x15\x36\x5a\xd5\x83\xfe\x63\x3b\x42\x12\x81\xf9\x5e\xe4\xb9\xff\xba\x71\x61\x12\x97\xda\x54\x25\xd1\x65\x4e\xd1\x8c\x9f\x74\x9a\x63\xa7\xfc\x17\x4c\xa5\xc2\xbb\x73\x96\x3a\x5b\xa1\xbc\xc8\x6f\x2f\x96\x01\xd2\xed\x9f\xcf\x4d\x3e\xc8\xa9\xba\x41\x81\x8f\x26\x11\x39\x91\xea\x41\xd1\x94\x2b\x12\xc9\x01\x3e\xfe\xc4\x87\x69\x28\xae\x94\xa1\x29\xb3\x9c\xac\xdf\x79\x59\xf2\xfc\x67\x94\x43\xc0\x95\x4e\xa2\xb8\x23\x3f\x36\x3d\x2f\x53\x36\x40\xe0\x10\x18\x15\x71\x74\x72\x16\xe3\x46\x51\x3b\x44\x47\x94\xf7\x2a\x75\xdb\xbc\x6a\xa6\xac\xbd\xc0\x35\x0f\x70\x5b\xaa\xb8\xfc\x15\x6d\x3f\x08\x8f\x71\x5c\xc3\x97\xb2\xf8\x0b\x64\x3d\x14\xd8\x04\xe1\x71\x62\xb0\x9c\x43\x8e\x14\x10\x7e\x10\x63\x7e\x13\xfb\xca\xf2\xb4\x4f\xe8\xba\xe8\x51\x04\x22\x42\xc4\xa8\xad\x10\x7c\xe1\x62\xda\x21\x20\x02\x61\x24\x8d\x0e\x5f\xb6\x47\x97\xdf\x14\xa1\xcf\x78\x5f\xbc\x43\xad\xe3\xb2\xb8\x60\x82\xde\x28\x47\x4c\xa9\x83\x41\x84\x4c\x10\x6b\x2d\x2d\x3a\x6f\xd2\xa9\x27\x42\x1e\x32\x93\x71\xbd\xac\xf9\xd5\xb9\x94\x82\x78\x0a\x73\x7d\xb8\x23\x9a\xea\xfd\xf8\xbc\x48\x53\x1c\xd0\xee\x29\xfc\x96\x50\xda\x8e\xa2\xc4\x34\xec\xb6\x86\x21\x6b\x60\xd4\x5f\x0e\x22\x56\xe0\xf7\x4a\xa4\x2b\x7e\xf9\x9c\x2d\x65\xf4\xa1\x45\xac\x15\x01\xdb\x3a\xf7\xc8\xf3\x4f\xd9\xa4\x46\xe4\x25\x83\xd7\x92\x04\xda\x31\x49\xd9\x92\xee\xf8\xb6\x93\xc8\xc0\x6c\xda\x78\xdc\x09\xa7\x82\x48\xa8\x09\x2a\xad\x86\xf4\x5d\xf1\x49\xb2\x47\x24\xb6\x41\x5a\xf2\xfc\x31\xed\x96\x86\x48\x64\x82\x39\x8d\x0f\xfe\x0e\xd5\xfd\xf7\xee\xcf\x2a\x88\x8d\xb6\x37\x5c\x8a\x0b\x66\xbd\xa7\xb7\xa3\x0c\xc7\x84\xfe\x50\xc7\x62\xf3\x74\x18\xd6\xaf\x85\x83\x0c\x1d\x24\xcf\xb2\xe2\xf2\x39\x39\xd2\xfc\x17\xe2\x01\xc3\xc9\x68\x95\xc5\x77\x19\x97\xc8\xf6\xe1\x78\xc4\xf3\x97\x61\xc8\x2f\x38\x27\x81\xcd\x09\x1d\xcb\xa6\x9a\xb6\x19\xd8\x51\x22\x36\xea\x51\x7b\x90\x29\xbc\x83\x42\x5c\xe0\x1c\x95\xd4\x68\x3a\x88\x18\x10\x91\xf4\x56\xc9\x65\x53\xe6\x23\x3a\xc2\xd9\x13\x64\x28\x2c\x49\x26\xc6\x37\x5d\xda\x3d\xfb\xc5\x69\x89\xb2\xc2\xd3\xd7\x55\x71\xb9\x96\xe9\x80\x7e\x73\xd6\x0c\x48\xe9\x11\x43\x6b\x5e\x61\x29\xfb\xc6\x38\x09\x15\x30\x02\x03\xf4\x74\x1b\x6f\xb6\xfe\x7b\x70\x73\x27\xe3\x17\xa5\x78\x84\x06\xe6\xbb\xe3\x72\x75\x0c\x09\x93\xdb\x99\x9c\xa5\x22\xac\x9c\xde\x43\x0e\x65\x2a\xfb\x4f\xfe\x8f\x1c\x4d\xc4\x4a\x63\x35\xc4\x14\xcf\x2b\xe3\x3b\x8d\x32\x68\x02\x88\xc6\x29\x7c\xa8\x79\xae\x78\xa9\x4e\x51\x77\x44\xc4\x61\xaf\xa9\xba\x2f\x7a\x05\xab\x29\xc4\xfe\xff\x93\x1c\x8b\xd0\xbe\x87\x50\xae\xef\x45\xf9\xa6\xb3\xe2\xe3\xd0\x53\x8d\x83\xd0\x8c\x24\xac\x2f\x9f\x1f\x8b\xa9\x7c\xcd\x7c\x69\x5e\xe8\x76\x37\xc1\xe0\x5b\x64\x69\xf5\xfa\x08\x55\xd5\x2b\xa3\x98\x31\xd2\x53\x71\x92\x74\x2d\x96\xcb\xa2\x98\x74\x5e\x48\xdf\x93\xc8\x4f\x9b\x5a\x06\xb3\x43\xcd\xdf\x3e\x29\x54\xb4\xfe\x98\x36\x0d\x7d\x4b\xd3\xa4\x84\x7a\xe7\xc6\x24\xff\x5c\xe5\xca\xc9\x7e\x39\xc8\xaf\xf4\x63\x4d\x13\x2b\xc0\x06\x5b\xe9\x52\xf0\x32\x20\x1c\xcd\xcb\x85\x5f\x2d\x8e\xde\xef\x0e\xc5\x01\x52\x5e\x6d\x8b\x9a\xf7\x80\xb6\xd1\xa4\x92\xa1\x1f\x21\x87\x07\x66\xb1\xa1\x39\x2f\xcb\x14\xe9\x1c\x9d\xf9\x92\x21\x50\xcc\x44\x16\xef\x50\x4e\xe9\x93\x41\x86\x9a\x23\x52\x77\x4c\x29\x3a\x6f\x20\x65\xe4\xc5\xd8\xb0\x55\x7d\xa4\xb5\x7c\xd5\x8d\x33\x2f\x32\x82\x18\xc9\x1a\x2f\x9d\xda\x94\xe5\xbb\xfb\x7f\x35\x87\x24\xf5\x04\x16\xbc\x8d\x63\x70\x42\xe0\xd9\xe9\x72\x8b\x07\x94\x54\x48\x6a\x78\x04\x0a\x5c\xe6\x36\x73\x62\x13\x39\x91\x1b\x05\x02\xe9\x3d\x44\x73\xbd\xcf\xb8\x4a\x79\x5d\x94\xab\xd7\x41\x5a\xd1\x8e\x8b\x63\x29\xfc\x81\xdc\x63\x3b\x45\x27\xa6\x52\xc6\x5c\x68\xe5\x88\xda\x9a\xbc\xb2\x59\x84\x6a\x9b\x9b\x5e\xcb\xf9\x17\xc8\xbc\x04\x95\x36\xeb\xe2\x5c\xac\x8a\xfc\x1d\xca\x7a\x50\x1a\x91\xcc\xf7\x30\x73\x0f\x3f\x40\x36\xb5\x29\xf1\xaf\x21\xab\xf9\xb2\xb9\x11\x79\xff\xf4\x15\x0e\x8f\xdf\xca\xe9\xcc\xae\x2b\xc9\x02\x53\xe5\x59\xa6\xb5\x2c\xd2\xfc\xbe\x84\x6e\xeb\x90\xdc\x8f\x12\x31\xb0\x91\x43\xf1\x8e\x5f\x98\x0c\x77\x05\xe2\x61\xf2\x7e\xb7\xd9\xaf\xac\x3a\xe9\xe9\xf8\x7c\x5a\x6f\xbe\x75\xbf\x41\x0c\xad\xe9\x11\x32\xb8\x1f\x54\xda\x25\x8f\x4d\xa2\x00\x8d\x7d\x14\x4c\x3e\x94\xf0\x35\x06\xef\x69\x75\x57\x94\x6f\x7d\xdc\x2a\x05\x21\xb8\x70\xcc\x8c\x69\x6d\xec\x09\xfd\xcf\x93\xe8\x75\x08\x40\x4a\x25\xb0\x3a\x9b\xf1\xaa\xbe\x03\xa8\x6c\x72\xa0\xf3\xb8\xa5\x54\xa6\x92\xe2\x3c\x37\xb9\x83\x72\x79\x23\xd3\x07\x52\x79\x11\x26\x96\x2e\xfc\x6a\xe5\xba\x6c\x31\x7f\x76\xf7\x90\x2a\x60\xa1\x23\xfd\xb1\x59\xc4\x81\x54\x23\x48\x15\x1b\x34\xb6\xab\xb0\x74\xf2\x7a\xa3\xe6\x42\xa9\xb8\x87\x28\xc8\xba\xc9\xa7\xeb\x01\x7c\x81\x3c\x22\xf7\xfc\x3c\x12\x23\xea\xdb\xa7\x06\xff\x35\x76\x73\x25\x04\xc0\x3b\x96\xaa\x9e\xea\xb1\x75\x2e\xba\x90\x58\x82\x34\x9e\x9c\x0b\x3c\x07\xe8\x36\x93\xcb\xb9\xcd\x92\x49\x80\x08\xa3\xcd\xfb\x42\x19\xb5\xb0\x59\xcf\x46\x6a\x8f\x04\x74\x30\xdf\x7a\x26\x17\x37\xc0\x12\xea\x61\x87\xca\xb8\xcc\x20\x75\x62\x14\x3f\x6d\x95\x1b\x13\xc5\x7b\x90\x90\xbe\x4f\xb3\x8f\x52\x27\x12\xfc\x6e\x9f\x68\xbd\x96\x81\x9c\xff\x64\xb5\x6b\x61\x6c\xf7\x05\xe0\xed\x81\x57\x43\xc1\x49\x50\x5e\xa8\xb1\xfd\xd3\xf4\x72\x1c\xa0\x9d\x43\xe3\xef\xa1\xbc\xc4\xc3\x48\xda\xbc\xae\x47\xc0\x62\xd2\x4f\xc3\x4f\xe5\x71\x66\x4a\x21\x50\xd5\x2e\x9b\x7d\xf8\xe0\x25\x26\x5c\xdd\x18\xe5\xa3\x1b\x82\x20\xc9\x1b\x26\x91\xf1\xf5\x7c\x96\x38\xf2\x99\x8e\x2d\xeb\x2e\xe3\x2f\x43\xae\x3b\xbf\x1b\xcc\x93\xa0\x53\x86\xdb\xae\x9e\x87\x94\xd6\xa0\x7c\xc1\x6c\x5b\x0c\x5a\xb0\x63\xb1\xed\x00\x5d\x6e\x84\xd4\x52\xb9\x5c\x4d\xdf\xa2\x34\x7a\xa9\x2a\x08\x3d\xd4\x1a\x17\x0d\x9a\xce\x47\x9e\x0f\x15\x4b\x41\x05\x51\x84\x7a\x31\x45\x6e\x99\xbb\xf1\x33\xde\xf2\xeb\x0d\xbc\x6a\x15\xb0\x04\x3b\x86\x57\xbb\x22\xcb\x8a\xa1\x0b\xac\x42\x3f\xd2\x16\x27\xb2\x77\xbc\x40\xdd\x03\x87\xa1\xe4\x16\xf3\x67\xf6\xf8\x36\xdc\x5f\x4c\x3f\x63\x48\x04\x22\x24\x6c\xf0\x74\xc0\x47\xae\x66\x24\x03\x40\x85\x54\x03\x4c\x22\xfc\xbc\xe9\x9a\x93\x15\xf1\x7d\x0c\x0a\x11\x3e\xb5\x2b\xdb\x78\x73\xfc\x76\x48\xa8\x31\x59\xd7\xae\x14\xf4\x14\x47\x0f\x43\x62\x40\x1e\x98\x6a\xeb\x8c\x95\x8a\x3c\xc0\xe7\x83\x73\x8a\xd6\xac\xaf\x97\xcf\x4f\x88\x28\x34\x42\x30\x66\xcf\xae\x0c\x2a\x65\x92\x91\x52\x11\xe1\x38\x11\xa0\x2b\x50\x28\x1a\x7b\x88\xf5\x69\xad\xe6\x07\xc0\xdb\xc9\xcc\xfb\xc0\x1d\x8f\x49\x18\xdb\xd8\xf1\xcb\x55\x95\xe6\x23\xcc\xc6\x1b\x8a\x51\x8a\x3a\x75\xca\xc6\x19\xd5\xd8\x3d\x57\x09\xf1\xc8\x08\x56\xd4\xad\xd0\xff\x36\xa9\xba\x49\x7e\xa8\x24\x62\x6c\xa0\x27\x1a\x44\xf4\x91\xbb\x5e\x55\x95\x24\x2c\x72\xd3\x6d\xb0\xe9\xaa\x24\x51\x60\xd8\x7f\x90\x95\xfa\x00\xb2\x29\xd3\xfa\x6a\x61\x42\xb3\xba\x8a\xa0\x12\x15\xfb\xd6\x33\x29\x5f\xe0\x5f\x4f\xc7\x5f\xac\xe6\x44\x31\x94\xf2\x75\x26\xdd\xf8\x9c\xf6\x20\x0f\x29\x02\x1d\xd4\x35\xe7\xe7\x54\xee\xe1\x1d\x06\xfa\x97\xce\x30\x2b\xce\xa8\xe8\x1d\xdb\xae\xb4\x52\xf4\xda\xfb\xfd\x50\x4e\x03\xd7\xe4\xf2\x9f\xfd\x8f\x19\xbf\x51\x09\x46\xb5\x55\xd5\xde\xf1\xa6\x1a\x26\xfe\x94\x10\x3e\x32\x3c\x54\xbc\x91\xb0\x2b\x8a\x0c\x69\x94\xdc\xed\x4a\x3f\x06\x57\x94\xbe\xe3\x69\x76\x80\xfa\xa9\xef\x45\x57\x32\x8e\x93\x4e\x88\x76\x65\x04\x5d\x56\x9f\x49\xd6\x80\x92\xdc\x8b\x08\x16\x25\xa7\xd1\xd0\xfc\x9b\x94\x82\x68\x5b\x9f\xc0\x34\xcc\x2c\x7b\x1f\x28\xa9\x3d\xcc\x67\xe1\x5d\x8c\xc1\x5c\x4a\xf9\x01\x8f\xfa\x4c\x58\x51\x76\x96\x4d\x71\x3f\xb4\x73\x17\xcb\x38\xe3\xc4\x87\x52\x4a\x60\x07\x93\xe2\xe5\xdb\x80\x11\x43\x29\x1d\x61\x26\xec\xe9\xf9\xe1\xe1\x4f\xd4\x89\x1f\xdf\x0c\x04\x12\x8b\x74\x7f\x15\x69\x3e\x90\x5e\x9c\x2e\x36\x20\x86\xdc\xa9\xf5\x30\x9a\xcb\x44\x6a\x07\x14\x48\x43\x35\x5a\x01\xaf\xc7\x96\x12\x2c\xf8\xc7\x39\xac\xf8\x39\xc6\xb7\xa0\x3d\xc3\xfe\x79\xa8\x0b\xd7\xfc\xad\x34\x03\x64\x5c\x79\x82\xfa\xda\x64\x3f\x0b\xa5\xc1\x0b\x0d\x12\xcf\x50\xe5\x1f\x0e\x2e\xb9\x05\x1e\xa5\xd8\xc6\x8e\x8e\x55\xf5\x35\xaf\xd3\xec\x7b\xf7\x62\xc0\xf7\x69\xec\x00\xe0\x1f\xcb\x26\x57\x59\x6b\xe8\x9b\xac\x4e\xeb\x1b\xca\x56\x00\x3f\x8c\xb0\x16\x7e\x7a\x81\xfa\x5f\x7f\xee\x56\x03\x81\x37\x00\x9f\x88\xb0\x13\x86\x7e\x1f\x7f\x51\xf0\x69\x6f\xbe\x0b\x35\xc3\x07\x0b\x10\x78\x1e\x42\x0f\x9b\x5c\x41\x89\x1d\xc4\xf3\x76\x11\x02\xdf\x88\x05\x5d\x4a\xd0\xe9\x0f\x50\x5f\x7a\xfe\x0a\x37\x22\x94\xc4\x94\x46\xb1\x95\x63\x00\x38\x19\xbd\x73\x08\x98\x91\x44\x7b\xf8\xe6\x8a\x18\x10\x80\x8f\xa8\x02\xa8\x5f\xa7\xde\x26\x84\x54\x63\x0a\xdd\x71\xfb\xa7\x79\x7a\xf8\xe0\x97\x87\xde\x63\x05\xe2\x71\x4e\xfa\x04\x18\x76\x89\xcc\xfa\xdc\x40\x62\x8a\x93\xa5\x40\xca\x1b\x4b\x51\x55\x2d\xaf\x87\xcb\xc8\x33\x75\xa3\x85\x00\xd1\xa1\x75\xab\x65\x73\x5d\x5e\x17\xf5\x44\xe4\x1a\x80\x48\xe9\x18\x5c\x96\x8b\xe5\xb4\x4a\x6e\x07\x45\x96\x51\xbb\xcb\xa9\xb4\x7b\xc7\xe7\x7a\xc7\x00\x91\x54\xb2\x53\x17\xc7\x84\xed\xf2\x3a\xed\x5b\x82\x08\x38\x26\x36\x76\x4d\xf9\x32\xd0\x9a\x05\xa0\x1e\x01\x4b\xce\x73\x3f\x98\xf6\xb3\xa5\x7e\xa0\xa1\x85\xdb\x1a\xd4\x0f\x72\x7d\xd8\x43\xb1\x6f\x62\x6d\xd1\x5c\xff\x53\x4c\x1d\x6a\x48\xa8\x42\x4c\xb9\x71\xe0\xda\x58\x7c\x56\x5d\x0e\x20\x61\x4a\x5b\xdf\xde\xf9\x05\xa3\x0b\xf1\xd8\xe4\xbe\x72\xf8\x38\x34\x42\x15\xe7\x76\x02\xcd\x36\x24\xcf\x9a\x4b\xe0\x8c\xc5\xd2\x79\x66\xdf\x56\xc3\x37\xc1\xc1\xb4\xf9\x2e\x10\xcf\xf6\xb3\xd5\x2c\x6c\x41\xcb\xf5\xf7\x9a\xde\x78\xa3\x6b\x6a\x50\x7e\xfd\xac\x14\x1e\x37\x84\x79\x30\x84\xf5\x83\xf0\x05\xe6\x1f\xad\x18\x26\x4f\x2b\x50\xdb\x4a\x76\x87\xa9\x62\xc3\x10\x06\x4f\xb5\x8d\x3e\xb3\x21\x28\x08\xd0\x3a\x76\x61\xc7\x4d\x8b\x08\x48\x5f\x62\xbb\x4f\x5a\x55\x0d\x18\x49\x8e\x54\x0e\x92\xe7\x73\x8f\x09\x11\xc3\x36\xa5\xe2\x72\x29\x72\xc8\xeb\x11\xf0\x16\x20\xe1\xb8\x14\x8f\xdb\xcd\x9e\xd8\x3f\x6a\x3f\x06\xf4\x49\x0d\x84\x1f\xf8\x79\xb0\xcd\x76\xda\x20\xa0\xfd\x84\xa3\xa3\x91\xf3\x52\x16\xd5\xf2\x6a\xc2\x0d\x39\xaa\xe4\xeb\x20\x34\xdd\xfc\x96\xbe\x78\xd9\x94\xf9\x43\xf1\x89\xd5\xd1\x01\x8b\x91\x21\xe2\xab\xd1\x18\x37\xa2\xe6\xc5\x6d\x8e\x5b\x07\xe0\xe1\x26\x81\x34\x70\xdd\xd3\xe8\x30\x32\xc8\x6a\x9b\x53\x45\x64\xaf\x25\x55\x76\x23\x92\x84\x86\x7d\x1a\x7c\x1c\x4c\xea\x90\x1b\x39\x77\x05\x5c\x3d\xa4\x1d\x98\x4c\x13\xa2\xfd\x61\xd1\x6c\xf5\x9a\x66\xbf\x94\x79\x77\xe7\xb2\x98\xf6\x2c\x54\xdd\x94\xd2\x44\x27\x66\xee\x64\xbc\x3c\x4f\x36\x41\x1d\x05\x41\xa8\xa7\xfd\xa6\xc7\x02\x6b\x84\x5d\x4d\x5d\x47\x91\x83\xd7\x71\xd5\xb3\xd6\x82\x8e\x28\x35\xe0\x52\xf3\x1a\xee\x8a\xb2\x6f\xb2\x19\xbf\xc7\x48\x18\x16\x60\xa4\x89\x44\x1b\x3f\x07\xcd\xd3\x71\xa0\xb9\xb3\xf5\xe6\x7b\x3c\x14\xc5\x5b\x73\x19\x78\x3c\x3a\xe6\x01\x92\xcc\xf4\x20\x19\x1d\x4b\xa3\x7b\x50\xa7\x98\x74\x2b\xeb\xdb\xa2\xac\x66\x5e\x88\x6b\xe4\xf7\x3f\x57\x37\xce\x8f\x1b\xa2\x63\xf4\x54\x9a\xaa\x0b\x5f\x17\x4a\x4d\xbb\x61\x74\xe2\x89\x84\x98\xf2\xee\xe1\x35\xbd\x54\xcb\xeb\x08\x6c\xe8\x46\xc5\xa1\x23\xfa\xf8\x9a\x4b\x53\xa5\xbd\x1b\xd4\x33\x75\x12\x1b\x0a\x4b\xf7\xad\xab\x31\xb5\x83\x4e\x80\x48\xe8\xda\x24\x91\xad\xc3\x62\x5d\xc7\x0f\xc6\x7d\x43\x61\x87\x8b\x68\x09\x5d\xa7\xb8\xe6\xb1\x8a\x78\x8f\xcd\x6e\x7f\xbc\x6b\x69\xed\x07\x81\xe1\x81\x3b\x40\x96\x9d\x7a\x69\xc4\x4f\xd3\x4b\x5a\x50\xc0\xaa\x85\xe4\x59\x2f\x81\x3c\x7e\x74\xc1\x01\x5b\xc7\xa5\x8d\x7c\xb7\xb2\xd8\xf1\xb2\x76\x31\x8b\x96\x21\x04\x62\xd8\xb8\xdb\x3f\xb4\x8c\x64\x18\x0c\x7c\xab\x6a\x5b\xc3\xf9\x36\x45\xa0\xa5\x0c\xb1\x7e\x68\x73\x45\xe9\x4b\x0e\x6a\x0d\x3c\xb3\x9e\xda\xfc\x0a\x51\x3c\xd0\xae\x47\xbf\xbd\xa7\x2e\x15\xa4\x8a\x0f\x67\x6a\x35\x78\x80\xdd\x19\x69\xde\x2e\xa4\xfa\xda\xfd\x9d\x06\x89\xe1\x36\xbf\x1e\x76\xdb\xdf\x37\xdd\xdf\x15\x41\xa7\xeb\xf0\xfb\x2f\x2b\xa5\x5a\x53\x25\xb4\x7b\xf0\xaa\x41\xb6\x40\x7b\xc7\xa3\x50\x4c\xeb\x38\x66\x4e\xb5\x7f\xc9\xff\xe6\xbd\x9a\x3b\x68\x9d\x78\x58\x9b\x4d\xab\x6f\x50\x56\x69\x91\x77\x1d\xde\xe5\x43\xf1\x92\xca\x6e\x9c\x34\x95\xd7\x0a\xea\x93\x7d\x1f\xc1\x7c\x54\xa0\xb5\xa6\xdc\x3a\xe2\x5f\x2b\x58\x6f\x1e\x36\xf7\x8b\xe3\x66\xb5\x78\x78\xe8\xe3\x14\xed\x05\x4a\x18\x9e\x47\x9e\xab\xa7\xc6\x65\x0d\xb5\x17\x82\x87\x98\xc9\xd6\xdf\x76\xbf\x74\xba\xf0\x9b\x1c\x6a\x37\x5c\xc7\x0e\x0e\xca\xd3\xcc\x20\x8f\x8d\x8b\x38\xfc\x5c\xda\x23\x2c\x40\x38\x34\x4e\xec\x87\xa2\xd7\x39\xd6\x5e\xe4\x19\xb8\x68\x09\x55\x91\xbd\xc3\xda\xe2\x3c\x9a\x6b\xdf\xac\x3d\xfe\xd1\x28\xe0\xcc\xe4\x12\x9a\x7c\x04\x89\xa9\x26\x3f\x1a\x25\x0a\x71\x08\xa7\xbc\xc8\x25\xf8\xdd\x0f\x4a\x81\x1d\x4c\xaf\xbc\xba\x2b\x9a\xf2\x50\xc3\x65\xdc\x7b\xac\xbd\x48\x51\xc4\xdc\x42\xae\x9c\xea\xc9\xf8\x1e\x28\x31\xd4\xe5\x48\x84\x90\x8f\x99\x2a\xb4\x17\x73\x8e\x72\x13\xab\x7f\x1f\x7f\x49\x1f\xa0\x3d\x16\x00\xa6\xb8\xee\xb7\xab\xa3\xbb\x02\x23\xc4\x48\xed\x22\xf9\xda\xae\x2c\x0a\x3d\x9a\x56\xda\x63\x71\x00\x9d\xa9\x18\xe1\xe1\x3e\x61\x56\x69\x4f\x89\x8d\x06\x3c\xc0\x22\xcb\x0c\x30\xbb\xfb\x0c\x09\xa1\x08\xb7\xe4\x4a\xa1\x9a\xf6\x36\x27\xdf\x01\xde\x4c\xa9\xec\x56\x74\xf2\xa6\x01\x56\x7b\xdc\x8b\x85\x8d\x33\xbe\xf0\x52\x75\xd3\x5c\x7b\x3c\x0a\xb1\xa5\xed\xa9\xa8\x39\x26\x6c\xc6\x8f\xc2\xb9\x15\x8f\xfb\xfe\x64\x9b\x16\xb1\xe4\x75\x32\x54\x6b\xc3\x69\x2b\x3c\x89\x7e\xc9\x8e\xa7\x15\x1f\xa4\x75\xb4\x27\x48\xec\x2c\xec\xf7\x34\x7f\x28\x2a\x2b\x88\xb6\xbc\x2e\x0d\xb6\x07\x4d\xd0\x36\xbf\xe7\x67\xd1\x86\x52\xad\x11\xfb\x6c\x56\x0b\xc6\xd0\x63\x5a\xf1\xfc\x4f\xbe\xe6\x45\xf7\x1b\x22\x08\x4c\x39\x1c\xe9\x4f\xec\xb6\x72\x57\x16\xe7\x9e\x9f\x65\x8a\x27\xfc\xac\xd0\xf5\xd9\xdf\x67\xab\x0e\xf6\xf7\x25\x09\xad\x0c\xbc\x55\xd1\x3b\x89\xeb\xa9\x6e\x23\x99\x9b\x9c\xb1\xf6\x24\x18\x72\xb6\xb4\xda\x17\x45\xbd\x68\xea\xd7\xa2\x9c\xe6\x7d\xb4\xa7\x08\x51\x2e\x57\x6a\x1d\x27\x83\x71\x6e\x57\xc4\x8e\x97\x90\xd7\xd5\x5d\x51\x42\xfa\x92\x3f\x15\xf5\x36\xff\xea\xd8\xfb\xdb\x53\x35\xe6\x09\x36\xef\x90\xd7\x0f\xed\x66\xf4\xf5\x32\xec\x21\xee\xfe\x71\xe3\x23\x5f\x18\xa1\xe6\xed\xd3\xc3\xe2\x7b\x77\x19\xe9\x23\x6a\x73\xbb\x5d\xfd\xca\xe8\x6a\x4f\x69\xa3\xe8\x89\x8e\x41\xe8\x2e\x01\x24\x41\x2a\xb6\xd6\x98\x15\xe7\xf6\xce\x4d\x96\x79\x3c\x3d\x81\x86\xd8\xaf\x71\xc7\xab\xfa\xbe\x2c\x3e\xea\xd7\xd1\x04\x82\x44\x51\xbf\x8b\xa5\x0a\x3d\x93\x9b\xd4\x9e\x8e\x08\x4a\x7b\xbd\x17\x59\x93\xd7\x00\xe5\xf7\xb2\x03\xc2\x68\x4f\x33\x86\xb1\xf4\x7d\x51\xbc\x38\x1a\x18\xed\x7b\xbe\xd1\x24\x4b\x2b\x97\x67\xb6\x1f\xe3\xef\x5b\xa5\x09\x77\x4a\xe8\x2b\x8b\xc2\xb9\x14\x15\x20\xd7\xfa\x67\x9c\x1b\xda\xf7\x84\x61\xbd\xef\x5b\x08\x87\x49\xd1\xd9\xad\x5f\xfb\x7e\x14\x60\xea\xfd\x52\xfe\x52\xf7\xd5\x9d\xa1\x09\x26\xee\x44\x73\x5d\x95\xa0\xd2\xba\x5a\xe4\xea\x70\x81\x5c\x2d\x72\xe5\x18\x81\x66\xaa\x5a\xec\xb3\xb9\x6f\xaf\x1b\x78\x1c\xd3\xf5\x46\xec\x7b\x66\x2a\xfb\x81\x4f\x31\xaf\xa0\xd3\x2c\xfb\x7a\x39\x64\xc5\x7c\x0b\x90\xf6\x83\x48\x22\x6b\x99\xc5\x19\x6d\xab\xff\x40\x59\xcc\x79\xa7\xda\x0f\x84\x26\xbd\x20\x64\x51\x9e\x27\x36\xdc\x0f\xa9\xe1\xc5\xac\xa0\x7e\x37\xec\x9c\x3f\x63\xe3\x9a\x99\x2c\x7e\x18\x1b\x1d\x38\xc9\xf3\xc3\x85\x7f\xe4\x8b\xca\x2d\x8f\xd9\xf7\x40\x98\xc1\x98\xbe\x40\x6d\x59\xa5\x9c\x6d\xf6\x89\xf4\x91\x35\x1e\xb9\x94\x47\xb6\xd3\x27\x4a\xa2\x1b\x62\x89\xbc\x0e\x35\x7f\x4b\x73\xa3\x69\x36\x0c\x53\xb4\x1f\x05\x06\xb1\xd8\x3a\xc4\xa3\x1c\x90\xf6\x23\x4e\x89\xed\x0f\x38\xe5\x76\x57\x18\xbf\xd8\x48\xb1\x20\x76\x31\xe4\x71\xbd\xf9\x49\xad\x5b\xfb\x11\x90\xa0\xcb\xbf\x23\xf1\xe7\x0c\xb8\xb6\x1b\xcb\xe3\x61\x13\x79\xd9\xba\xcd\x3d\xf6\x4e\xfb\x14\x12\x24\x15\xdf\xc9\x21\xdd\x49\xfb\x77\x89\x2e\xdc\xa9\x75\x4c\x9b\x1a\x56\x4e\x7b\x28\x70\x97\x8e\xa9\x0c\x2d\x15\x97\x4e\x11\xb6\xe3\xce\x8d\x93\x40\x18\x6d\xe9\x2f\x13\x32\x63\xed\xb3\xd8\xd0\xc0\x57\xaf\xa9\xae\x4f\x19\xe8\xda\xc6\x82\x93\x87\x64\x4a\x1b\x45\xb7\x57\x9e\xd7\x8e\x5b\xc4\x1e\x4b\x3c\x89\x1e\xdf\xfd\x62\x35\xfa\x3b\x0f\x00\x77\xaf\xa7\x46\x66\xd0\x54\xdf\xd2\xd6\xe3\x33\xaf\xf2\xd1\xd0\x16\xcf\xbf\x50\x11\xfa\xe8\xc7\x1c\x5f\xd3\x52\xe1\xc6\xb5\xcb\x78\xdd\x4e\xda\xe1\x53\x89\x48\xfb\x43\xe6\x4c\xd7\xf8\x63\x27\xdb\xf8\x8a\xa2\x53\x5d\x5e\xad\xbe\x58\x58\x2e\x71\x57\x92\xa1\x51\x41\xe1\x97\x4b\x66\x6b\x93\x6d\xd0\x76\xe4\x3d\x05\x9c\x1b\xc9\x3c\xf4\x4b\x91\x52\x09\xc9\xaf\x86\x88\x41\xed\x4b\x65\xfc\x56\x63\x6f\x77\x45\x91\x9d\xc6\x0c\x32\xda\x57\x44\x62\x75\x2d\xe3\x55\x57\xd3\x6d\x27\x40\x55\xf3\xf3\xa5\x1b\xa4\x05\xe3\x5d\x5c\xc4\xeb\xba\xa3\x37\xd3\x3e\xc4\x49\x62\x23\x90\xf6\xbc\x6c\x40\x3a\xe2\x46\x30\x23\xb5\x7d\x29\x01\xc3\xc5\xc7\x71\x83\xac\xbb\x90\x06\xe2\xfa\x03\xee\x2d\x8c\x78\x3c\x39\x02\x2f\x02\xec\xaf\xc9\x1a\xf9\x76\x1d\x36\xb6\xe9\xc0\x63\xe0\x79\x1d\x19\xad\x91\xc0\x04\x65\x7c\x90\x6d\xee\x38\x8f\x27\x97\x4b\x22\x9b\x93\xcc\x32\x23\x59\x98\xcd\x6b\x56\xe8\xc0\x0f\x68\x68\x5b\x21\x1e\x79\x5d\x16\xf9\x24\xcd\xa7\x03\x1f\x08\xa6\x06\x0c\xe2\x03\x9f\xb3\xfd\x1e\x6b\xde\x71\x18\x4c\x2e\x19\x48\x12\xc5\x9d\xfc\xd2\xe4\x6a\x81\xa2\xd8\x44\xd0\x5a\xe1\x15\xcf\x50\x6d\x6f\x81\xfa\x13\xed\x5f\xfe\x97\xfc\x9f\x1b\xa7\x29\xe6\x96\x77\xbc\xaa\x3e\x8a\x52\xf5\x24\xfa\x68\xa6\x02\x6f\x44\x80\xa0\x83\x50\x10\xc4\xee\x41\x51\xed\xf6\xdb\x6f\x8b\xe3\x66\xde\x94\x07\x84\xc7\x89\x0d\xb9\x1f\x8b\xaa\xfe\x56\xd4\xa0\x9e\x2f\x83\x7e\xe6\x76\x08\x57\x4e\x9b\xef\xcc\x7f\xac\x37\xc7\x6a\xe7\x74\xd4\x1f\xa0\xaa\x8e\xaf\x3c\x9f\x3c\x16\x51\x80\xb7\xdb\x63\x76\x26\x64\x15\x3a\x88\x7c\x81\x80\x0e\x6d\xd2\x26\xae\x4c\xfe\xac\x07\x95\x9c\x76\x94\xe9\x23\x3c\x3e\x1f\x17\x0f\x27\xec\x42\xc6\x0e\x57\x6c\xf2\x73\x63\x48\xe2\x5b\xcc\xe5\xe9\x9e\x4f\x4c\x6a\x10\x45\x09\x76\xbe\x98\x8c\xe8\x4c\xa9\x4c\x07\x91\x30\xb4\x51\xd0\xba\x2a\xb6\x92\x7b\xdb\xc9\xe7\x06\xcb\x08\x27\xf9\x37\x28\x73\x7e\xbe\xcd\xe3\xeb\x80\x7a\x5e\x18\x0f\x73\x08\xad\xc3\x6a\x82\x76\x77\xcb\x34\x49\x30\x70\x69\xa3\xe5\x6f\x86\x3f\xa8\xf8\xb9\x94\x8d\x0e\xa8\x30\x2c\x02\x8f\x48\xf1\xf4\x7b\x31\x14\xf7\xb4\x43\xe2\x38\x41\x4e\x2b\x31\x90\x43\x75\x0e\xee\xe8\x16\x63\xab\xd5\x86\xeb\x7c\x08\x41\x50\xdd\xa5\x34\xc7\x2c\xee\x73\x9f\x52\xd5\x01\xf3\x3a\x22\x07\x1b\xae\x39\x30\xe7\x27\xf4\x11\x3a\x60\xd4\xc3\xb5\xe7\x08\x76\xd0\xe7\x1b\xed\x98\x01\x53\x31\x38\xcc\xed\x73\x53\x23\x43\xe6\xe8\x1a\x09\x67\x58\x80\xe3\xa2\x68\x6a\x43\x4d\x77\x35\x62\x0e\xd3\x8f\x9d\x88\xc4\xe3\xbd\x2a\x7f\x55\x15\x32\xbd\x4d\xad\xe9\x40\xc4\x11\x56\x1f\x4d\x2a\xa4\xb5\x97\x36\xc8\x58\xf1\xcb\x31\x85\x32\x98\x5c\x57\xfa\x06\x98\xef\xe2\x6f\x5b\x7a\x9d\x89\xc0\x03\x19\x2a\x6c\x89\x71\xde\xde\x01\xb2\x6c\xf1\x02\x79\x7d\x48\x6b\xd8\xc3\x3c\xbf\xab\x0e\x64\x2c\x71\x9f\x2b\x79\x0d\x5d\xb7\xb2\x0e\x54\x02\x7d\x3c\xbf\x87\x77\xc8\x5d\x8f\x8b\x0e\x80\x26\x44\x8f\x93\x5d\x53\x0e\xe8\xf1\x53\x43\x1c\x60\x37\xc0\xf2\xf9\xe9\xeb\xe1\xf4\xb0\xf9\xb6\x79\x38\xb9\x68\x3d\xf4\x42\xe5\x93\x1e\x32\x81\x19\x96\xf2\x6a\x15\x90\x0d\xe5\xc6\xb8\x86\xab\x43\x4f\x25\x18\x27\x99\xb7\x8d\x5c\x2b\x01\x71\x70\x97\xd1\xe3\x85\xbe\x9f\x60\xd4\x5b\x68\x0d\xe5\xae\xc9\xdf\xac\x64\xda\xb1\x98\x50\x35\xcc\x3b\xaf\xa1\x4f\x28\xa2\xac\x72\xf8\xd8\x43\x55\x58\xc6\x92\x19\x6f\x30\xf4\x95\x61\x58\xac\x20\x57\xa7\xba\x38\x29\x5e\x56\xaf\x4e\xd0\x49\x87\xbe\x96\x56\xee\x15\xe7\xaf\x91\x98\x9e\x56\x68\x07\x4e\x71\x18\xd0\x00\x27\x5f\x93\x9b\x30\xd9\xc8\x26\x4c\x52\x97\x3a\x0c\x38\x11\x43\xfe\x65\x0c\x83\x27\xd3\x28\x0c\x84\x4e\x62\xab\x88\x74\xdf\x5c\x8f\xae\xf4\xaf\xc3\x30\x62\xb8\xb9\x9a\x44\xfc\xf6\xcc\x5f\xa0\x97\x8e\xd2\x61\x28\x20\x89\x87\x0a\xf2\x86\x87\xd1\x1e\x25\x1e\x41\x7c\xe6\xc9\x96\x8b\x1d\xd0\x72\xf2\xeb\x24\x26\x98\x62\x84\xfc\xa5\xe4\xef\x30\x84\x6b\xe8\x90\x80\x11\x13\x3c\xf3\x37\x58\xf2\x5a\xbe\x4e\x38\xd0\x6e\x7a\xd5\x75\x18\x91\x90\xb5\x8e\xd0\x06\x29\x7a\xdd\x1f\x2d\xc0\x01\xb9\x00\x0d\x3e\x61\x2a\x71\xa5\xc3\x88\x6b\x2c\x25\xbc\x9b\x8f\xf0\xfc\xd1\x01\xe3\x74\x18\xa9\x08\xb1\xaf\x77\xe9\xcb\x6b\xfb\x69\xf0\x85\xdc\x42\x6a\x26\x17\x54\x09\xe6\xf1\x1f\x06\xc8\xb7\x5f\x31\x1c\xdb\x53\x69\x28\x46\xe5\x83\xcf\x88\x08\x74\x48\x59\x88\xae\x70\x06\x5c\x41\x29\x0a\x5e\x4e\x7c\x83\x90\xca\x08\x45\x88\xcc\x2c\x4f\x41\x76\xca\x80\x93\x71\x4a\xa1\xbb\x96\xca\xa2\x4b\xbd\x0f\xfd\xb0\x30\x0e\x08\x26\x17\xf5\x74\x06\xc5\x91\x16\xb8\xd7\xa5\x2f\xf9\x5d\x51\xf6\x0f\x3b\xda\xfe\xc3\x98\xb2\x44\x1a\x32\xe8\x0f\x74\x27\x86\x18\x6c\x1d\xc6\x82\x19\xcc\x30\xbc\x3f\x7f\x74\x36\x3f\x64\xbe\x4e\xfa\xf5\xec\x2c\xfc\x18\x17\x33\x59\x97\x2c\x92\x9e\x6d\x82\x3c\x34\xba\xdd\x73\x20\xaf\xed\xd4\xe9\xfa\x8e\xe7\x5f\x67\xe2\x85\xe8\x1b\xb7\x7b\xe0\x8a\x57\x69\xee\xf2\x3f\x61\xe2\x47\x24\x72\x45\xdc\xaf\x5f\x6f\x7a\x9d\x27\xd7\x89\x94\x2b\xbb\x1f\x5e\xd3\xcb\x90\x5e\xbc\x7b\x1f\x09\x33\xc4\x31\xd8\x59\x90\xb5\x3e\x4b\xfb\xb5\x39\x12\xc7\x55\xa7\xc1\xff\xb1\x92\x73\xee\x34\xc1\xb1\x17\xcc\xba\x50\xe8\x79\x1c\xbe\xee\x76\x8e\x73\x53\x87\xc2\xf7\x8d\xfe\xbf\x9d\x3d\xc6\x2d\x9f\xc7\x93\xe9\x50\x84\x49\x2c\x3a\xf9\xc8\x63\xe1\x16\xea\x69\xf2\x95\x45\x62\x32\x95\x9f\x6a\x89\xba\x71\x52\x12\x23\x7d\xf1\x58\x74\x5f\x51\xfa\xbe\x73\xaf\xd1\x6c\x1b\x76\xcf\x21\x39\xbd\x1b\x48\x59\xd4\xfb\x56\xdf\x16\x0f\x5f\x37\xee\x1a\x8a\xfa\xc4\x77\xd0\x9b\xa1\xd8\xb0\x35\x03\x6c\x4e\xbc\xb7\x33\x0c\x2a\x49\x30\x20\x2f\x70\x42\xf0\x6c\xa4\xf5\xac\x43\xc5\x99\xe9\xe9\x93\x48\x93\xdb\x3a\x66\xd8\xa1\x63\x0f\x43\x98\x20\x70\xd3\x59\x52\xe3\x39\xf5\x3a\xb1\x3a\x84\xd6\x69\xc5\xc0\xb7\x84\x23\xf0\xf3\x22\x57\xb6\xf8\x56\x8d\xc2\xa2\x10\x68\x8c\xa0\x81\xc3\x1b\xeb\xc1\x30\x3a\x04\x30\x9f\xd5\x76\xa6\xb4\xfe\xcf\xa8\x8e\xa4\x43\x4d\x12\x4c\x4a\xa0\x74\xc4\xa8\x9e\x35\x9e\xff\xc4\x13\x89\xd3\x0f\x33\x6d\xb3\x06\x7c\x3b\x5a\x8d\xc4\xd3\xdc\xd1\x13\xb9\xd5\x34\xdc\xb2\x88\x1f\x0b\x2c\xdd\x3f\x6e\x9f\xb6\x4f\xf7\xe3\x19\x46\xfc\x24\xc1\x62\xd3\xe3\xf2\x61\x68\xb0\x89\x0f\x3e\xed\xbf\xde\x80\x25\x55\x93\x80\x49\xdf\x3a\xa0\x38\xe1\x6d\xad\x96\xcb\xd9\xa6\x1a\x4d\x42\x46\x11\xe9\x77\xe6\x3f\x0c\xf0\xd3\x7d\x0b\x12\x26\x80\xb0\xe1\x73\x9a\xd7\x77\x45\xb9\xe1\x65\x76\x75\xbc\xb1\xd5\xe7\x5b\x03\x09\x21\xc1\x36\x27\xf7\x0d\x17\x5a\x1b\xed\xbf\xd1\xfc\x25\x21\x18\x4d\xd7\xd6\x09\xdb\xe6\x8e\xf1\x4a\x93\x50\x1b\x82\x69\x14\x6d\x40\x95\x28\x69\xb8\x4b\xb6\xea\xae\x2c\xce\x6b\x7e\x9d\x5c\x88\x70\x1e\xdb\x39\xdf\xfa\x5b\xa8\x06\x6d\x54\xe5\x26\xe3\x40\x60\x2e\x35\x73\xf0\x3c\xcb\x26\x33\x9a\x36\x24\x52\x02\x23\xfc\x45\x59\xdf\x63\x13\x97\xdb\xdd\x08\x0d\x43\x5c\x17\xf7\x50\xb7\xf7\xdb\xd7\x75\xdb\x43\x31\xa6\xd7\xfe\xb2\x4a\x03\x43\xd4\xaf\x6e\xbd\x97\xc4\x73\x71\x25\x52\xf2\xad\x9a\x4f\x22\x0c\x42\xa9\x41\x51\x61\xc5\xab\xc6\xe5\xbb\xbc\xfe\x0e\xd7\x39\x77\x87\x50\xae\x50\xd1\xd1\x2a\x10\x1d\x2e\x45\x5e\x15\x98\xdd\x69\x83\xcd\x5f\x64\xc3\xbb\xef\x45\x2d\x79\x8d\xe4\xf9\xe1\x83\xdf\xc8\x64\xda\x51\x31\x89\x31\x85\xf0\x57\x91\xe6\xf7\x1d\xdb\x69\x37\xcd\x59\x04\x89\x35\xdb\x1b\x23\xec\xfc\x30\x89\x0d\xdc\xc0\x98\x79\xfe\x98\x69\xb9\x27\x57\x70\x63\x14\x13\xae\x91\x0e\x5b\xf0\x2b\x18\x74\xe1\xce\xcf\xe3\x84\x12\x74\xa2\xee\x79\xc6\x6b\x5e\xf1\x4e\xc6\x51\x93\x44\x19\xa3\xc8\x95\xda\xc3\x7b\x0a\x1f\x3f\x23\xf8\xd0\x84\xfb\x2c\x12\x48\x9e\xde\xee\x67\xe8\x6c\x61\xfa\xfd\xb7\x71\xeb\xc2\x28\x11\x46\x78\x44\x8c\x00\xf6\x8f\xf6\xc1\xdf\x96\x93\xf4\xa9\xef\xbe\x2f\xa7\x21\xc2\x60\x3b\xa4\xe5\xf3\x6a\x32\x4d\x79\x9c\x60\xe5\xac\xf5\x0b\x06\xfc\x28\x9a\x70\x6e\xfa\xf5\xd6\xa0\xdb\xe5\x64\x98\x4f\xd7\x90\xf1\x6b\x67\xbb\x08\x07\xa3\xa5\x63\x48\x5d\x4c\x5d\x69\x93\x77\x87\x45\x1c\x60\x0c\x77\x86\x9a\xbb\x18\x65\x04\x2e\xf8\xe9\x96\x43\xa4\x67\x89\x13\xd0\x47\x78\x28\x5e\x6e\xeb\xf8\x9a\x28\x8f\x63\x30\xf3\xc4\xeb\x62\x24\x74\xe2\x6e\x42\x45\x1c\xf9\x5b\x34\x4f\xb3\xa6\x9c\xc0\x0c\x35\x51\x2c\x11\x46\xbf\xab\x44\xfa\x92\x39\x32\x69\x4d\x20\xa1\x7e\x64\xf3\xf1\xa6\x19\xbd\x2c\xce\x96\xb9\x7c\x3c\x52\xc7\x12\x6b\x1f\x45\x9e\x5d\x51\xbf\xcb\x19\xb8\xc8\x0b\x39\x05\x47\xcb\xdf\x7a\x6a\xbb\x89\xce\x81\x8e\x3c\x2a\x50\x6e\xc8\xa1\xc5\x8e\x7f\x1c\xe6\xd7\x47\xe4\x7b\x86\x54\x7f\xf1\xf5\xf8\xe5\xb4\x5a\x3c\x3d\x6e\x9f\x5c\x20\x17\xf9\x01\xc1\x24\x8a\x4a\xab\xd6\x5d\x5e\xdd\x38\x8f\x51\x40\x42\x9c\xbd\x4b\xf8\x9b\xe7\x86\x06\x77\xca\x1d\xa7\xa3\xd0\x4b\xa8\x15\x93\x79\xe0\x02\xb2\xc9\xd1\x20\x42\x98\xee\xd3\xe2\xb8\xfd\xb6\x39\x2d\x0e\x87\x4d\x77\x03\x61\xec\x83\x8b\x8b\x9e\xf3\x11\x3d\x9f\x8e\x42\x26\x90\x3f\x7a\xf9\x3c\xa4\xae\x6a\xff\xae\xa9\x53\x87\x42\xba\x74\x27\x62\xed\x8e\x27\x31\xa6\x99\x44\x63\x4a\xd2\x95\x4b\xc0\x8d\x5f\x4c\xa8\x14\x7e\xa9\x2f\xcb\x9f\x94\x9e\xc6\x5f\x37\x0a\x21\x44\x97\xed\x95\x97\xed\x7e\xf3\xef\xa6\x28\x9b\xf3\xd8\xaa\x46\xa1\xe6\x58\x4b\x1a\xfa\x67\x9b\xa7\xf5\x69\xbd\x38\xba\xcd\x30\x22\x31\x4b\x86\x54\x41\x18\xdc\x4c\xee\x8f\x08\x81\xfd\xa1\xcb\xb4\xae\xa4\x43\x74\xe9\x28\x0a\x02\xe4\xcd\x38\xd9\x74\xc2\x98\xab\xf4\x66\x6d\xb4\xe3\x0d\x40\xaf\xdd\xac\x52\x18\x63\xc5\x75\x14\x11\x86\x41\xca\x91\xe7\x57\xde\xfd\x46\xa2\xf0\x0d\x62\xf3\xcf\xb1\x68\xca\x9c\x0f\x5c\x9d\x88\xd2\x08\x63\x0e\x73\x07\x8f\x57\x04\xf5\x8c\xbe\x39\x8d\x0d\x48\xde\x8c\x38\x80\x9c\x59\x90\x11\x65\x1c\x25\x1d\x20\x57\x5b\x59\x2c\xaf\x7d\xcd\x38\xa2\x5c\x32\x7f\xbc\x55\x9b\x66\x96\x39\x19\x33\x1d\x51\x29\x3d\x36\x64\x2b\x5f\x65\xfc\x43\x70\xf9\xb6\x19\x62\xfa\xec\xe0\x38\x0e\x10\x0f\x0e\x95\xe4\x16\x07\x3a\xa9\x56\x46\xac\x8d\x03\x0c\x64\x9c\xa7\xb9\x6b\x0a\xee\xd6\x27\xe3\x5c\x0d\x5c\x35\xcb\x7d\xee\x8e\x26\xb2\x83\x32\x7e\x19\x91\x56\xea\x88\x93\x08\x25\x47\x75\x51\xc2\xbb\xed\x89\x32\x09\x6d\xbb\x77\x58\x7a\xfd\x6e\xb8\x42\x4a\xdb\x26\xcf\xd2\x49\xb7\x9d\x8e\x5a\x73\xec\x50\xbf\x07\xf9\x0a\x59\x96\xe6\x2f\xd8\x44\xb7\x86\x9a\xa7\x59\x35\x1d\x2f\x34\x2e\xb5\x43\xda\x2e\x97\x55\x91\x57\x03\x91\x99\x59\x3f\x32\x12\x81\x11\x57\x7c\xdc\x3e\xad\x4f\x77\xcf\x5f\x9f\xd6\xa8\xcb\x7c\x5a\x3c\x3e\x7f\xed\x8d\x88\x20\xd2\x49\x14\xec\x00\x11\x91\x9b\x1f\x97\xac\x28\x47\x1d\x54\x6e\x2c\x35\x25\x03\xae\x3a\xef\x6f\x16\xe6\x11\x09\x6a\xc8\x8c\x75\x9a\x65\xad\xf3\x34\x96\x78\xf8\x47\xbb\x42\x24\x44\x68\x48\xf1\x6d\x9b\xc4\x63\x3f\xbf\x64\xac\xd1\xac\x81\xf5\xc8\x9c\x88\xfc\x10\x1f\xae\x23\xc9\x0c\xce\xa3\xc8\xe1\x03\xe0\xad\xfb\xb3\x8e\xb1\xbd\x6d\xb1\xdd\xaf\xf7\xcf\x3b\xd7\x9a\xf7\xf4\xf5\xf1\xe0\x86\x40\x44\xb0\x03\xd3\xa4\xf2\x70\xf6\x6c\xcf\x17\xd4\x0b\x9c\xd6\xfa\x47\xb7\xac\x3d\x1f\x2d\xa9\x82\x2c\x7d\x87\xb2\x8d\x23\xc6\xd5\x36\x37\x2e\x10\xd4\x42\xce\xda\x17\x7e\xc3\x02\x35\x79\x9b\x9a\x80\xb2\xf0\x8e\xc7\x22\xc7\xe4\x52\xc6\xab\x6a\xf3\xa3\x86\x5c\x0d\x57\xc0\xa7\x2c\x47\xb7\xff\xeb\x2e\x9d\x84\x98\x34\xae\x3f\x8a\x2f\x98\x1c\xa9\xea\x65\xaa\xaa\x75\xaa\x35\x94\xd0\x2e\xd5\x91\x61\xd0\x32\x70\x14\x38\x98\x64\xa8\x26\xcd\x42\x9a\x7a\xc4\xf3\x4d\x97\x54\x9a\x23\x45\xf7\x40\x53\x40\x53\x8f\x9a\x84\xa0\xd9\x30\xc0\xb6\x0d\x7e\x29\xba\x9a\x21\xf5\x7d\x89\x35\xbc\xe7\x73\x9e\xae\xe1\x47\xf7\x67\x11\x61\xf8\x71\xb7\xd9\x9c\x0e\xdb\x87\xe7\xee\xef\x40\xb0\x05\x77\x51\x35\x7b\x9e\x9e\x1b\xf7\xf7\xc0\xe3\x18\xee\x23\x21\x88\x25\xdf\x9e\x0d\xf5\x69\xe0\x9b\x7a\xfd\xa1\x2e\xd3\xcb\x6d\xcb\x88\xa6\x01\x09\x30\xf9\x07\x3f\x2e\x69\x79\x5d\xf6\xad\x94\x9a\x86\xbe\x29\xee\x9d\x2e\x65\xf1\x62\x60\x8a\x33\xa5\x27\x1a\x06\x80\x9f\xbb\xaa\x79\x0d\x03\x88\xab\x3d\x1c\x85\x31\x86\x4a\x9d\x8c\xcf\x72\x90\x6a\x77\x63\x08\xc7\x5e\x8a\x33\xff\xd1\xf3\x10\xf7\x0e\x05\x8d\xa8\x99\xd4\x2f\x58\xc2\xb2\x15\xb2\xee\xa0\x22\x08\x0c\xbb\x4b\x33\xe8\x11\x9c\xed\xdf\x8d\x3e\xf1\x09\xd1\xa0\x8b\x5c\xad\x78\x96\x4d\xe4\xdf\x67\xfa\xcd\x34\xa5\x84\xe1\x05\x77\x8b\xfd\x61\xb3\x3a\x9c\x76\x9b\xfd\x69\x73\xfc\xb2\xd9\x9f\x96\x8b\x83\xdb\x25\x29\xe5\x91\x36\x08\x3e\x53\xcd\x1a\x32\x10\x6b\x1a\xfb\xa1\xb6\x11\x09\x92\xf3\x8c\x5f\x59\xec\xc7\x88\xbf\x7e\xe5\xb9\x42\x06\x1a\x28\x87\xc2\xf1\xf3\x26\x83\x32\x4a\x10\xfa\xb5\x5b\x3c\xb9\x9f\x61\xcc\x70\x00\x7d\xdb\x1c\x8e\x9b\x75\x7b\xa7\xab\x4d\x67\xfc\x28\x4b\x28\x06\xf3\x55\xfa\x92\x2f\x5e\x4a\xc0\x08\x63\xbc\xc5\xd2\x44\xc5\xb6\xfb\x3e\x7f\x6b\xd7\x86\x3b\x97\xfb\x9e\x1a\xaa\x3d\x0d\x30\xd3\xb3\xb7\x79\xd3\x95\xdc\x5d\x87\x20\xaf\xc8\x2b\xaf\x0c\x7e\x72\x32\xff\xb8\x0a\x31\xcc\x30\x0d\x67\x03\xa6\x68\x73\xc8\xc6\xb4\x2f\xed\x45\xbb\xbf\x6b\x81\xa9\x3e\xa4\xf0\x4e\x6f\xf2\x0c\x93\xb7\x26\x88\x71\x31\x1b\x03\xc2\x5e\x95\xd7\xaa\xe6\xd9\x63\x07\x87\xd6\x54\xd0\x08\x73\xab\x07\x6e\x37\x1f\x83\x73\xec\xb9\xd8\x35\x95\x41\x1c\x77\xe4\xa0\x35\xcf\x16\x52\x42\x55\x15\xe5\xf5\x00\x65\xda\xf9\xc6\x54\x12\x85\x6d\x12\x39\x7c\xec\x1e\x56\xfb\xef\xa9\x43\xf2\x34\xbf\x82\xda\x51\xc9\xfd\x90\x39\x1c\x83\x6a\x8d\x5f\x99\xf3\xcc\xe2\x16\xbb\x1f\x50\x89\x41\x2a\xf5\x42\x6c\xff\x68\xb7\xa1\x2a\xe1\x08\x80\x33\x29\xf9\xb1\xf0\xb3\xa6\x0a\x8c\x8e\xb8\x49\xa5\xa3\x8c\xf8\x88\x78\xcd\x50\x23\x78\xe3\x7f\xed\xb9\xc0\x65\xd0\xf1\xce\xff\xe2\x53\x80\xf0\x30\xe7\xf0\xb8\xf8\xe3\xb4\x78\x78\x78\xfe\xbe\x59\x9f\x0e\xc7\xc5\xfd\xe6\x14\xb8\x5b\x01\x19\x63\xfb\x76\x7b\xb5\x81\x44\xd9\x78\xcb\xa0\xa0\x04\x5a\x35\x4c\xb2\x20\xf9\xe8\x27\xe6\x4f\xc7\x31\x66\x4c\x7b\x57\xb6\x1a\xa8\xeb\x99\x41\xb1\x17\x46\x4e\xa6\x65\x48\xb7\xb8\x1e\x94\x06\x1e\xd3\x89\xdd\x8c\x3d\x9e\x60\xe8\xba\xdb\x5b\x27\xfa\xf8\xe5\xb4\x7d\x3a\x7d\xdf\x6c\xb1\xd2\x7a\x7a\x5c\xfc\xd1\x5d\x5f\x18\xf0\x73\x55\x17\x17\x43\x13\x71\xaa\x6a\xb8\xb8\x67\x8e\x7d\x1a\xa3\x83\x88\x5b\xb5\xcd\x65\x9d\x0e\x9b\x76\x3d\xdb\x8b\x3f\x6c\x1f\xb7\x6e\x55\xc7\xa1\x97\x60\x65\xc3\x28\x47\xdf\x37\x73\xa5\xa0\xd1\x5b\x88\xc3\x10\x82\x04\xfb\x86\xb8\xcc\xd2\xbf\xe1\x94\xc3\xc7\x1e\x11\x69\xeb\xc3\xbf\x1b\xa7\x44\xd6\x99\xc1\xe9\xd9\x91\xc0\x15\x6c\x66\x07\x3a\x93\x73\xdd\x1e\x3a\x0e\x2d\xd4\xdc\x32\x5e\x7c\xff\xac\xc2\x19\x13\x8f\x61\xc1\xe2\xb8\xf8\x97\x7b\x28\x12\x28\x8b\xf7\xce\x37\x86\x28\x61\x51\x8a\xb4\x2e\x79\x79\x5d\x15\x8e\x1b\x4d\xc7\x84\x51\x93\x01\xaf\x6c\xc6\xdc\x75\x51\x4f\x58\xba\xda\x91\x40\x2c\x86\xe0\x74\x29\xe1\xf4\x76\x95\xa7\x54\x16\x79\xfa\xdf\x13\xf6\x98\x9f\xf2\xe6\x6c\x04\xdd\x27\x1f\x36\x22\x9e\x0a\x5c\x79\x3f\x87\xeb\xd0\xe9\x8a\x23\x12\x59\xa6\xa5\xfc\xdd\xc0\xa2\xc7\x78\x7a\x1d\x47\x51\x84\x74\x6f\x15\x97\xbc\xfc\xbe\x59\x74\x7f\xd7\x0a\x03\x74\xcb\xd3\xfa\x5a\x94\xf5\x22\x4b\xf9\x24\xe2\x89\x63\xce\xfd\xbe\x27\xe9\x21\xad\x86\xda\x44\xb3\x5d\x36\xed\x39\xa6\x57\xdd\x98\x0a\x9b\x9f\x9b\xc4\xca\x71\x12\x98\x46\xa2\x12\xe9\xce\x2c\x0d\xb2\xbb\x39\x2e\x00\xac\x5a\xe9\xa2\xa9\x27\xb1\x5e\x2c\xa8\x71\xe6\x2f\xfc\xba\x06\x51\x4f\x8f\x72\x1f\x31\x55\x0f\xcd\x05\x90\x9c\xea\x93\xc2\x47\x2c\xe3\x90\x40\x87\x43\x69\xfd\xe6\x4f\xa6\x87\x8c\x63\x04\xd5\xed\x37\x87\xcd\xfe\xdb\x66\x7d\xb2\xff\x61\xa5\xc7\x4f\x8b\x6e\x29\x40\xe0\x63\x3d\x97\x77\x18\x52\x77\x80\x78\xc8\x37\x70\x49\xff\xfe\x9b\x9f\xce\x5c\xbe\xa6\xf9\xa7\xca\x3a\xee\x9c\x58\x23\x14\xe0\x91\xff\x30\x3a\xe3\x6e\x8e\x7d\x3d\xac\xbb\xeb\xf2\x00\xb3\xb4\x5c\xa9\x8e\x26\x68\xdc\xf9\x7f\x9b\xda\x8d\xb5\x6f\xe4\xb4\x7b\x98\xe5\xe1\x35\xbd\x0c\x62\xd6\x58\x87\xd2\xf5\x7a\x7e\x2b\x6a\xa8\x76\xd0\xcb\x77\xb8\x21\x4c\x98\xd2\x61\x6b\x8e\x72\xa8\x57\xbc\x7a\xed\x8e\x69\x23\xb4\x27\xd2\xfa\xa3\x28\x55\xd7\x25\x9e\x8d\xd8\x11\x34\xf3\x23\x03\xbc\x35\x93\xeb\x6b\x9e\xa2\x84\x87\x4e\x0d\x3e\x6a\xa6\x34\xcf\xfc\x98\x46\xe6\x79\x4d\x56\x1f\xd1\x19\x48\x60\x68\x42\x93\xee\xd2\x61\x1c\xe2\x40\x13\x53\x67\x17\x3f\x19\x4f\x13\x46\x42\x8e\x84\xae\xcb\x46\xbe\x5d\x07\x08\x09\x16\x45\x44\x5b\xe1\x11\x78\xce\xb1\x37\x24\xcd\x5f\x9c\x42\xcc\x27\x33\xdf\xbd\x5b\x16\x49\x19\x58\x86\xe0\x3a\x83\x95\x56\x63\xa8\x1d\x8b\x80\x06\x9d\xcc\x97\x03\xcc\xcf\x7e\x7f\x46\x15\xc5\x84\x73\x5a\x1d\x5e\x9b\x41\xb3\x86\x66\x14\xbc\x81\x05\x44\xae\xfd\x61\xaa\x72\xfc\xa0\x71\xc0\xc1\xd0\x4f\xbd\x17\x6f\x30\x6c\x02\xf8\x6d\xc6\xd9\x64\x31\x0b\x51\x05\x4a\xb6\xce\x69\xae\xee\xa1\x36\x30\xa1\x31\xbb\xc7\xe4\x56\x19\x91\xda\xe4\x4d\xd3\xfa\xf8\x9a\x56\x5b\x59\xdc\x15\xe5\x17\x9e\xe9\x67\x83\x14\x19\xfa\x51\x8c\x45\x86\x08\xc6\x4a\xc8\x61\x91\x11\x26\xbd\x2e\x9a\x31\x6a\x32\x88\xf7\xa8\x9e\xd2\x9d\xcb\xa9\x36\xbd\x57\x1f\xbc\x54\x28\x74\x36\x80\xa2\x32\xa6\xa5\x97\x74\x0f\x6b\x76\xd6\xc9\x75\x93\x00\x38\xef\x3a\xdc\x27\xd5\x95\xe9\x58\x4a\x51\x7c\xca\x18\xa9\xd6\xae\xba\x1f\x4a\x98\xc1\x62\x67\xa0\xeb\x90\x4e\x66\x29\xd7\x91\xab\xbd\x3d\x14\xf2\x6d\xdf\xbe\xed\x4f\x3e\xb2\xa0\x04\x13\xf2\xdc\xcc\xb4\xef\xb0\xe2\xed\x26\xa2\x9b\x0e\x3d\xce\x44\x6c\x98\x4a\x9f\x2f\x90\xf7\xc4\x9a\x9a\x09\x1e\x3a\x51\x88\x76\x4b\x3a\xd4\x45\xe9\x88\x97\x06\xd7\x97\xe0\x94\x28\x1f\xf9\x8f\xb9\x25\x25\x94\x29\x6d\x61\xe1\xa5\x7c\x9f\x12\xe0\x6a\x86\xb3\x16\x61\x87\x86\x26\x04\x41\x89\x48\x29\x51\x35\x67\x77\x33\x32\xf2\x8c\xdc\x8f\x7c\x05\xd5\x64\x30\x28\xc8\x76\x43\xa8\xc0\xde\xc0\xb4\x3a\xa9\x94\xbf\x14\x39\xcf\x7e\xeb\x63\x63\x26\xc1\x30\x3a\x9f\x5a\x57\xcb\xfb\x81\xd1\xec\x67\xd5\x8f\xff\x8d\xfe\x6f\x60\xd7\xe8\xff\x39\xaa\x19\x7b\x29\x15\x29\xc7\xc2\x71\x4c\xe5\x1b\x94\x87\xeb\x59\x14\xe3\x4c\x2b\x53\x0a\x88\x1a\x62\xc1\xd5\x1e\xe7\x94\xbb\x5d\xf0\x00\x9d\xd0\xac\x78\xb9\x4f\xdf\xa7\x3d\xbf\x6e\x10\x07\xdc\xff\x8d\x79\xb8\xe7\xd5\x1e\x9a\xb4\x9c\x6e\x76\x0c\x89\x60\xec\xbe\xe0\x0c\x69\x67\xaa\x40\x29\xe6\xe4\xae\x0d\x13\xce\x80\xee\x7a\x32\x5d\xb4\x97\x60\x07\xa6\xa5\xc3\xbc\x91\xf2\x74\xfb\x36\xd3\x9c\xe3\x2f\x2e\x1e\x1f\xe6\xf4\x88\xa7\x3b\x4f\x8f\x96\x61\x5a\xd2\xb8\xd7\x24\x5d\xbc\xbc\x94\xf0\x32\x32\x17\x66\x5c\xe2\x79\x11\x52\x5a\x1c\xa1\xaa\xa9\xf3\x9b\x12\x2f\x36\xc2\x1b\xa2\xb9\xde\x17\xd9\x94\xa0\xf5\xd7\x50\xf0\xc4\x93\x04\x53\x24\xbb\x3f\xf7\x58\x5d\x77\x17\xf6\x43\xe9\x64\x2f\xef\xf8\x19\xd4\xa1\xe6\xe5\xf2\xfa\xc8\x27\x12\x31\x3a\xf1\xa5\x40\xbb\x71\x4e\x73\xd8\x56\xcb\xf4\xa5\x13\xcf\xd2\x89\x0f\xa6\xd1\x14\x33\x9f\xcb\xa2\xa8\x4c\xfd\x6f\x7c\x81\x20\x08\x30\xcf\xbf\xee\x02\xd7\x24\xe4\x4c\xcc\xc9\x61\xcf\x3a\x16\x09\x89\x4d\x4b\x30\xd2\x15\xb8\x5a\xeb\x6f\x93\x31\x0a\x0c\xb7\x87\x31\xe1\xc5\xc0\xf9\x98\x75\xaa\x92\x28\x32\xec\x3e\xff\x6a\xd4\x8b\x89\x9b\x7f\xea\x3d\x24\x34\x08\x3d\x27\x9f\x98\xd7\x47\xfe\x32\x84\x11\xba\x69\x92\x50\x0e\xb8\x26\xdb\x88\xdc\x09\xf6\xeb\x84\xf9\x49\xd2\x59\x16\x0b\x22\xd3\xc5\xe4\x35\xb1\xd0\x68\xb6\xb6\x21\x8c\xab\x10\xed\xdb\xc0\x7c\xbc\x53\xba\xd1\x49\x4c\x3b\xaa\x1a\xd9\xa0\xa3\xbb\x2e\xa0\xfa\x06\x75\xd1\xfd\x6c\x22\x28\x74\xf4\xcd\x3f\xa7\x98\x9f\xbc\x72\xc6\x8d\x24\xc8\xbd\x61\xf2\x4e\x2f\x13\x4b\x9e\x24\x94\xa2\x96\xde\x1a\xde\x71\xbf\x44\xd8\x88\xa1\x78\x4f\xf3\x97\x21\xf5\x90\x4e\x12\x69\x48\x9b\xba\x92\xc8\x7c\x76\x26\x0c\xdc\xae\x9f\xf0\x48\x2b\x18\x10\x4f\xbf\x34\xe5\x68\xc9\xdc\x3a\x61\x09\xa7\x89\xf1\xdc\x71\x02\xb4\x5e\x56\xf9\x9c\x6f\x32\x90\xa3\x9d\x79\xfa\xd4\x3f\x59\x38\x5c\x78\x2e\xb3\x7c\x04\x7e\xde\x41\x39\x6d\x9a\xd5\x89\x60\x02\x27\xd1\xaa\xbc\x5e\xde\xd3\xca\x32\xf1\x4d\x5e\x95\x10\x80\x02\x81\xc7\x0e\x8e\x90\x08\xd0\xa2\xd3\x47\x47\x5a\x19\x67\xbd\x12\xe9\x29\xd2\x9a\x49\x13\xbf\x3d\x80\x7a\x81\xd2\xed\x23\x6e\x48\x98\x60\xaf\x89\x79\xd4\x3b\xde\xc8\xae\x50\x9f\xc8\xc8\xc3\x42\xb2\xf1\x98\x27\x7b\x75\xa2\x42\x15\xba\x5a\x59\x9a\xc3\xd7\x8b\x09\x6e\x26\x4f\x05\x54\x20\x3b\x21\x3e\x0c\x16\xbf\x67\xfd\xf8\x04\x62\x81\x71\xef\xda\xe4\x8b\x41\x2d\x8f\xab\x4f\x86\x6a\xcf\xc7\x1d\x44\x34\x57\x83\x2f\x7c\x2a\xd4\x67\x45\xa3\x44\x4b\x02\xc1\x10\xda\xb7\x2f\x44\x31\x91\x25\xd3\xdc\x13\x7e\x18\x1a\x9a\x73\xf7\xf4\xdc\xd3\x32\x09\x7b\x3f\x7b\x0f\xd5\x0d\xc2\x82\xfb\x89\x87\x5d\xe8\xe7\x7f\xd6\x7c\xc4\x7d\x61\x24\xc6\x31\x01\x62\xb9\x90\xbf\xbf\xa6\x19\x3c\x98\x1e\xc1\x9f\xb6\xd3\xd9\x6b\x84\xd2\x28\xd7\x3d\x5e\x0f\x73\x6c\xb1\xbf\xfa\x77\x6a\xc9\xe6\x6f\x34\xf2\x95\x49\x58\x56\xf6\x2e\x2f\xd3\x64\x1c\x8f\xc2\x48\xc6\xb6\xbd\xe2\x3a\x5b\x42\xe6\x11\x11\xd8\xca\xbf\x7c\x58\xba\xb7\x1a\x69\x5f\xdb\x50\xfb\x81\xe7\xea\xcc\xcb\xb7\xc9\x3b\x65\x3e\xc1\x3d\x42\x37\xb9\x74\x67\xb1\xd8\x00\x65\x6a\xc8\x32\x07\xc6\x9d\x77\x0b\x39\xe3\x0a\x13\x74\x9d\xff\xdd\xb7\x9c\x8e\xb3\x8d\x9c\xfb\x31\xda\xd7\xbb\xc5\xd1\x45\xde\x9c\x2b\x46\x84\xbb\x3d\x54\xde\x28\x9f\xf5\xa2\x42\x09\xc3\x11\xe6\x8d\x8b\x50\x89\x64\x44\x70\x31\x82\x5a\xb8\x0b\x0a\xe2\x4b\x2b\xc9\x7c\xe4\xa5\x93\x7b\xee\x8f\x6a\x26\x2c\xc2\x0c\xab\x19\x8b\x66\xe8\x96\x71\xa1\x62\x44\xc7\x3a\xa6\xd2\x9f\xe5\xaf\xb8\x00\x2a\x8d\x94\x17\x7f\xe3\x59\x5a\x54\xc3\x5a\x33\x97\x9e\x47\xe8\x50\x25\xd0\x82\x72\xc6\xd7\x50\x3e\x45\xe4\x40\x0e\x1f\xa7\x62\xae\xf5\xde\x8e\x83\x40\x7b\x36\xb7\x58\x22\x8a\xcb\xfd\x0c\x30\x46\xdd\xf7\x2d\xe4\x5b\x0f\xbd\x1c\xda\x43\x0e\xd2\xc3\xf0\xde\xd2\xb8\x8e\xe0\x73\xdd\x1b\xd6\x9c\xe1\x44\xe7\x8d\x4a\xeb\x23\xfc\xb0\xe4\x1a\x23\xcb\xca\xb5\x30\x50\x28\x5b\xc1\x6d\xc3\x71\xd0\xe6\x01\xef\x8a\x72\x33\x8b\x53\xe2\x1a\x12\xcc\x43\x9e\x44\x73\x45\x1a\x9d\x02\x89\x60\xfe\xe1\xd2\x31\x17\x11\x9e\x6f\x04\x1a\x45\x73\x6d\x63\x68\x07\x5c\xde\xaa\xd1\xa3\x0a\x8f\x48\x2c\x7e\xdb\x26\x48\xd3\x52\xd3\xce\x90\x45\x65\x93\x01\xa3\x7b\x13\x5e\x64\x20\xe9\x0a\x64\x96\xe6\x80\x38\x5d\x53\x88\xe8\x25\x66\xdc\x50\xc5\xb0\xb1\xe2\x74\x6a\x03\x42\xc1\x7b\x64\xdc\x14\x81\x24\x7c\x6d\x82\x40\x75\xce\x3e\x86\x60\x2c\x11\x68\xae\xe2\xae\xff\xda\x64\x31\x1d\xdd\xbf\x1b\x43\x02\xca\xac\xbb\x62\x01\x08\xb3\x3a\xf5\x6e\x34\xf5\x2c\xfd\x8f\x61\x5d\x3c\x80\xe5\x5d\xd9\xc3\x7f\x67\xfc\x6f\x41\x62\x88\x7b\x05\xe5\x43\x53\x5e\xca\xb4\x0b\xb0\x04\x51\xa6\x9f\xfb\xd0\xa8\xbf\x9a\xdf\xfb\x54\x80\x20\x60\x5a\xff\xef\x0a\xe7\xa3\x88\xc8\xe7\xb8\xd6\x30\x7e\x1f\x89\x0f\x8e\x26\x96\xa0\x91\xc9\x1b\xf3\x2c\x6b\x57\xed\xd0\x95\x71\x23\x98\x01\x68\x5a\x26\x26\xe3\x69\x4c\x32\xe1\x22\x8e\x3d\xc4\x2f\x2c\xf7\x8f\xdd\x9f\x58\x82\x24\x45\xcf\xff\x1e\xae\x3d\x11\x27\x1e\x8a\xec\x7d\x00\xbc\x65\xd7\x5b\xc4\xb6\x88\x65\x80\x99\x09\x47\x86\x51\x7c\x82\xe1\xf8\x85\xc3\x75\x2b\x4d\xa3\x45\xac\x12\x2c\x2e\x99\x2b\xf0\x5c\xe1\xbb\x70\x77\xc6\xbc\x08\x33\x9f\x4d\x6e\xfa\x56\x67\x91\x5f\x82\xf1\x70\xd4\x93\xc7\xb3\x59\xea\x27\x2d\x98\xa4\x21\xf4\x22\x02\x6b\xe0\x1d\x57\xb2\x1d\x91\x78\x09\x36\xb8\xe3\xae\x71\x07\x83\x0e\x85\x59\xe7\x51\x24\xda\xb3\x9c\xd7\xca\x79\xeb\x43\xee\x8d\x6e\x82\x73\x1f\x18\xc2\x94\xf9\x19\x76\x43\xc0\x96\xe0\x91\x42\x4a\x7e\xf8\x6f\x33\x23\x70\x3b\x5a\xab\x3c\xf1\x30\xf7\xfd\xca\xab\xd7\x25\x06\xe5\xdd\x45\xac\x06\xff\x63\x5a\xbf\x96\x69\xf6\xc8\x3b\x0b\x2f\xb8\x62\x56\x6b\x00\xf3\xdd\x98\x73\x33\x74\x48\x6e\x84\xa0\x1c\xcb\xf7\x1f\x29\x46\x8f\xf3\xcb\x46\x28\xc2\xac\x3b\x35\xde\x0b\xe6\x3f\x49\xbb\xa6\x55\x47\x14\x60\x9a\xf8\x96\xd7\xcf\x9b\x8a\x85\x0c\x63\xdc\x78\x7f\x7f\x3e\x7c\x71\xc2\x85\x5a\xc8\xd8\x20\x71\x6d\xfb\xe9\x13\x3f\xc3\x5d\xf3\xf7\xdf\xd7\x29\xe7\x99\x16\x32\x21\x88\x71\x71\x2c\xd4\xa3\x80\x5c\x48\xa9\xb1\x67\x5c\x1a\x3d\x9f\x55\x91\xe6\x95\xed\x2d\xf0\xd9\x1a\x64\x7a\xee\x83\x6a\x21\x75\x90\x38\x29\x98\x57\x7e\xbe\x6c\x56\x9f\x7c\x7c\x15\x79\xb1\x85\xff\x7e\x4b\xb3\x8c\xa7\x13\x43\xde\x86\x5e\x68\x04\x06\x7a\x7e\x43\xe1\xc1\xc9\x60\xce\x30\xdd\xf2\x36\xde\xa2\xa5\xc7\x43\x43\x33\x8a\x72\xd3\x59\xc1\x87\xa4\x38\x5a\x7a\x52\x46\xd2\xc6\xdc\x1b\x59\x54\xd7\xca\x44\x24\x63\x31\xce\xd1\x4f\x49\x0f\x18\xe9\x2c\xd1\x13\xfc\xa8\x37\x25\xbf\xe1\x54\x18\x9d\xe1\x6b\xc2\x0c\x85\xca\x8a\x5f\xee\x4a\x98\x24\x7a\x64\xc0\x69\xdc\x97\x04\x56\x25\xa8\xe2\x93\xdf\x0e\x38\xc7\x1c\xbb\x25\xf8\x19\x85\x4f\x32\xf4\x42\xec\xce\xb6\x9d\x59\xed\xf6\x2b\x87\x61\xf6\x68\x3d\xc8\x90\x45\x58\xdc\x36\x19\x8d\x6d\x0d\xe7\xdb\x6e\x0b\x19\x72\xd0\x4e\x3d\x0d\x05\xb6\x5b\xa7\x69\x3a\x46\xaa\x40\x0f\x18\x23\x57\xc8\x9a\xf9\x58\x94\x70\x7c\xe5\xb9\xad\xb3\xab\xee\x26\xad\x13\xd6\xf1\x88\x48\x12\x73\xee\x75\xc8\xfe\x9e\x2c\xc9\x1d\x56\x3e\x3a\x01\x55\x23\xfe\x55\x08\x0b\xd2\x45\x01\xe4\x09\xca\x6a\x3e\x1e\x97\x11\x61\x81\x69\xec\xfb\x45\xe4\x2e\x23\x1a\x20\x8b\x62\x0e\x1f\x4b\xae\x16\xbb\xc7\xa9\x6f\x39\x63\x82\x25\x95\x4a\xb5\xbb\xc9\xba\x79\x83\xf7\xea\x77\x9e\x57\xbc\x9b\x5d\xb1\x67\xb4\x41\x4a\xd4\x04\x7d\xe4\x59\x2a\x5b\xe7\x76\xf2\xf5\xe3\x24\xc2\xf7\x57\x34\x75\x55\x73\x84\x26\xed\x10\x7f\xda\x5d\x87\x85\x06\xf2\x59\x19\x3a\xf2\xda\x4c\x4f\xeb\xe3\x8d\x2f\xc6\x48\x84\x69\xee\xbf\x9a\x54\x5e\x07\x14\x8b\x5a\x32\xa1\xd1\x38\x5b\xfa\xf1\x61\x9e\x70\x36\x7c\x18\xc6\x25\x32\x49\x74\x64\x29\x04\xb9\x06\x64\x94\x98\x36\x9f\x8d\xef\x83\x87\x21\x5a\xa4\x55\xd1\x94\x3f\x69\x84\x92\x5c\x58\x6e\x00\x74\xf1\xee\xc0\x52\xa2\x1c\x5f\x4b\xa8\x5e\x8b\x6c\xe2\x4f\x48\x0e\x11\xba\xf5\xca\x16\x20\x37\xb9\xea\xa7\x96\x24\x5c\x0c\x09\xe5\xd3\x33\x12\x83\x9f\x2f\xf3\x56\x53\x4a\x26\x70\x43\x47\xdb\xf0\x6c\x1d\xcb\xc9\x0f\x2a\xc1\xc1\x6e\x00\xdb\xd5\x73\x4f\xf6\xe5\x0e\x4b\xd3\x0e\xb1\xe2\xa6\xff\x77\x40\x04\x23\xc1\x13\x56\x29\x2f\xcd\xbb\xcd\xa3\x47\x0f\x4a\x20\x31\x1e\xd7\x45\xd9\x5a\xdb\xb9\x0f\x32\xfc\x04\xc0\xcc\x9b\x2a\x41\x01\x9c\x17\xaa\xc0\xe6\xed\x1f\x29\x7c\x8a\x16\x99\x3c\xae\xf6\x88\xec\x2b\x8a\xdb\xee\xb5\x69\xcf\xa0\x28\xda\xf5\x7b\xc8\x52\x09\xc7\xc2\x70\x1f\x77\x03\x68\x88\xad\x59\x4e\x11\xf0\x33\xef\x50\xea\xd8\xa0\xac\x0c\x5d\xe8\xb1\x78\x48\x9d\xd8\xac\x56\x5e\x2c\x31\x03\xf2\x50\x7c\xd8\xb2\xf0\xa8\xff\x56\x79\x3c\x42\x4c\x4b\x75\x01\x39\x6a\x29\x50\xbe\xc7\xb0\xb6\xb7\x4c\xeb\x27\xde\xd4\xa9\xec\x0a\x6e\xe3\x6f\xa5\xfc\x30\x40\xf0\x14\xd4\xaf\xae\x25\xd7\xb9\xb4\x5d\x85\x53\xf9\x31\x43\xde\xbe\xfd\x66\xb5\xd9\x7e\xdb\xec\x4f\x8b\xf5\x7a\xbf\x39\x38\x4c\x9c\x0a\x3c\x23\x6d\x8f\x5a\x2a\x5d\x5b\xdb\x2f\x0a\xeb\x2a\x08\x4d\xaa\x1e\xa9\x50\x67\xa4\x0e\xb5\x0a\x08\x43\x8d\x16\x5c\x93\x9f\xea\xc1\xb8\xc1\xa0\x30\x39\x83\x68\xd8\xb1\xd8\xaa\x56\xa1\x8c\x34\xef\x6a\x23\x83\x69\xb3\xd0\x35\x94\x1b\x84\x6f\x4d\xde\x4c\xa8\x39\x2a\xcd\x0a\x90\xc5\x19\xee\x78\x5a\x5e\xcf\x98\x5d\x71\xd7\x24\xa1\x8f\x56\xcc\x68\x60\x1d\x8d\x1e\x46\xd5\x1d\x8d\x8c\x8a\x79\x1b\xde\x7e\x49\x2f\x45\xf7\x77\x15\x23\x64\x27\x75\x6d\x2d\x96\x9a\x63\xf2\xeb\x44\x49\x30\x7a\x2a\xbc\xde\x56\xc7\x57\x58\x22\x79\x5f\xa1\xb6\xf9\xf1\x15\xbe\x17\xa5\xd3\x5f\xd5\x2a\x0a\x22\xa4\xbd\xa8\xea\xe2\x82\x5a\x8f\xc3\xde\x3b\x45\x41\x87\xc6\x84\x21\x72\xf3\x17\xdf\x24\x26\x51\x48\x46\x5a\x9b\xf3\x9e\x88\x8a\xa3\x90\x18\xed\x2c\xcb\x56\xd7\xb1\x8a\xe9\xa2\x3c\xad\x7f\x9b\x8e\x36\x18\x99\x63\xd9\x40\x5f\x10\x56\xcc\x0f\xc0\x6c\x53\xd5\x05\xf2\x21\x23\x94\x62\x41\x60\x36\xed\x57\x90\x6f\xd6\xb5\x9a\xbf\x65\x16\x7a\x9e\x72\x86\x3e\x6f\x2a\xac\xd0\xdd\xc4\x86\x8a\x45\x0c\x71\x22\x46\x6e\x77\x0e\x7a\xa9\x18\xf7\xa8\xcb\xda\xa7\x39\xcf\xbe\xa7\x79\x9e\xe6\x2f\x46\x9d\x7a\xac\x1f\xa4\x15\xeb\xb3\x61\x26\xc5\x6e\x5f\xfb\x28\xb2\x52\x89\x47\x42\x4b\xc1\xd2\x7a\x15\x15\x7c\xf6\x3e\x13\x22\xd1\xdd\x71\x58\x9b\x6d\xb5\x68\x97\xc5\x34\xc9\xa4\x92\x38\xa0\xd6\xcd\x7d\xcc\x4d\x60\x3a\x0b\x9c\x56\x3c\x14\xa8\xb5\x5b\x41\x8d\xc0\x02\xe5\x4a\x6e\x93\x61\x2a\xc1\x2f\x63\xe0\x65\x2e\x67\x63\x9a\xa7\x86\xae\x8f\xe2\x4a\xfa\x3d\x32\x7c\x46\x73\x44\x2b\xc1\x0c\xcf\xf5\x0b\xd4\xbb\xa2\xc8\x5a\xdf\x79\x79\xdd\xae\x27\xa3\x64\x18\x69\x43\x62\x3f\x76\x3b\x95\x94\x09\x12\x4b\xe6\xcd\x79\xd9\xc8\xb7\x8e\x25\x51\x2b\xa9\x88\xcd\x76\x21\x75\x3c\xa2\xea\x5c\x65\x6a\xed\xb2\xd7\xdd\x58\x61\x6c\x51\x23\xde\xe0\x13\xda\x0d\xa5\x7c\x23\x19\x3a\xd6\x2f\x8c\xdd\x35\x80\x18\x30\x43\x87\x51\xcf\xb2\x4d\xfd\x6a\x79\xfb\xbb\x41\x52\xe3\x17\x73\xb2\xb7\x06\x0a\xdc\x51\x82\xb8\x51\x4a\x61\x01\xd7\x7e\xcd\x21\x3f\x09\x56\x25\x47\x93\xda\x56\x17\x95\x8e\x4c\x76\x4f\x3a\x49\xbb\x5d\x51\x9f\xec\x15\xc1\x93\x46\x65\xeb\xc5\x75\x2a\xc9\xeb\x18\xa9\x00\xbe\x97\xa0\x3f\xa3\x8c\xe4\x43\xd3\x89\x7b\x6a\xf0\x83\x04\x97\x55\x77\xa8\xb5\x16\x0a\xca\x65\x31\xe3\x70\x8c\x5f\x1a\x84\xd4\x10\x42\xb4\xa1\x50\x1b\xcf\x0c\x97\x03\x84\xb1\x87\xa0\x32\x9c\xfe\xb6\x81\x3f\x0c\x06\xfa\x5e\x1a\x42\xa6\x74\x34\x80\x01\x2e\xbb\xed\x0a\x42\x4e\x69\x8f\xa1\xfb\x54\x06\xea\x7f\xd9\xff\xb9\x13\x64\x88\x15\x92\x7f\xfd\xf9\xfb\xf8\x36\xc0\x43\x00\xd1\x39\x55\xf7\x25\x57\xf0\xa5\xd3\xa9\xd6\x40\x88\x74\xa9\xcc\xaf\x15\x94\xa6\x4f\xd5\xd1\x99\x8c\x1f\x95\x30\x82\x25\x92\xbf\x1a\xf5\x32\x48\x9a\x14\x45\x36\xce\x9c\x00\x01\x85\x94\x40\x7b\xfe\x77\xd1\x8b\x7c\xd9\x83\x51\x08\x18\x28\xbd\xe2\xa6\x6d\x81\x25\xc5\x47\x35\xdd\xe7\x20\x4a\x62\x8b\x60\xc9\xa1\x4a\x2b\xcc\x88\x0e\x91\x53\x40\x59\x82\x6e\x88\xa1\x04\xc0\x3b\xaf\x16\xb9\x42\xaf\xea\x1f\x39\x32\x40\x85\x8f\x20\x61\x8e\xe9\xb6\x9e\x44\xd4\xbf\x19\x28\x3d\xcc\x62\xbf\xa7\xf0\xc1\xfd\xc9\x8d\xc6\x5e\x10\xf9\x1d\x2a\x78\x48\x3a\x3c\x02\x5a\x98\x97\x44\xdc\x49\x7e\x88\xed\x09\x75\xd9\xc0\xa0\x2d\x16\x62\x08\x10\x60\xbb\x5c\x2d\x57\x7f\x0e\x40\x2d\xc0\xa8\x10\x5d\x32\x54\xde\x77\xed\x7d\x3f\xdf\xbb\x80\x25\x21\xb5\x35\x25\x4c\x50\xdb\x66\x89\xaf\xfb\xed\x6f\x93\x81\xd2\x47\xd4\xae\x80\xfa\x39\x5f\x63\x02\xd9\x7c\x5a\xf7\x3f\x76\x5c\x22\x62\x65\x84\xad\x5b\x53\x52\x39\xea\x0a\x48\x20\xc6\xd0\xe2\xc2\x7b\x4a\xa2\xa1\xdb\x09\x89\x0e\xb0\x4b\xd7\x11\xfa\xad\xae\x72\xc4\x7e\x05\x3c\xa0\x0e\x11\x6b\x8d\xe0\xb1\x40\x81\xbd\xf1\xeb\xe6\x2c\x46\x50\x0d\x60\x21\xe9\x60\xd1\x0a\xdd\x62\xe6\x8a\x60\xa2\xe5\xcc\x7f\xb4\x73\xab\x68\xea\xce\xcb\xdb\x59\x55\x22\x3b\x52\x78\x04\x0b\xec\x48\xaf\xf1\xac\xad\xc8\xf0\xba\x67\xc6\x04\x21\x12\x9b\xf7\x12\x19\x97\x6f\xe8\x29\x8e\xa7\xba\x64\x21\xa6\x8d\xf6\x05\xf6\xb4\x0c\x8a\x33\xc3\x7d\x02\x24\x13\xe8\x86\x19\x85\x8f\x83\x2d\x11\x8e\x2f\x05\x61\xe4\xba\xca\x8e\x1d\xcf\x66\x91\x6d\x07\x5a\xef\xbf\x98\xce\x3a\xa1\x0e\xb9\xe4\x48\xb4\x9b\x69\x03\x83\xf6\x88\x51\x1a\x6f\xb7\x8d\x5d\x51\xd5\x97\xa2\x73\x69\xb5\x17\x71\xd0\x0e\x9b\xe5\x3c\xb8\xd9\xf2\xe9\xe8\x87\xb5\xa7\x85\x60\x43\x20\xc6\x23\xf0\x89\x4f\xad\x7d\x8f\xf9\x46\x4d\x21\x83\x1a\x86\x6b\xcd\x0d\x88\x13\x69\x63\xd3\x7f\x71\x23\xfd\x33\x64\xb4\x73\xa3\x98\x69\x77\x50\x70\xc9\x8a\xab\xe5\xa1\x71\xf7\xef\xeb\x04\xba\x22\x67\xfb\xa9\x9d\xf5\xd7\x81\x34\x98\x71\x53\xda\x1e\x37\xaa\xff\x34\xfe\xd4\x61\x44\x7d\x36\x76\xe3\x91\xe0\xa2\x5f\x12\x9a\xf8\x80\xc5\xa4\xef\x9b\xed\x69\xbf\xd8\x1e\x36\xeb\xd3\x6a\xb1\x73\x3f\x4d\x88\xf6\x54\x9f\xed\x74\x1c\x37\x78\x23\xf3\x7e\x8f\x26\x89\xcf\xbc\x81\x6c\x52\xae\x8a\x12\x19\x8a\x7e\xbb\x45\x7b\xe8\x08\x3c\x8c\x07\x76\xcd\xf9\x32\x34\xfb\x3a\xd2\x02\xf7\x0f\x7e\xb9\x3c\xa5\xf2\x2d\xef\x1b\x19\x74\xa4\x25\x0a\xef\x9c\xaf\xdf\xd3\xea\xb5\x4b\xf4\x6a\x1a\x51\xca\x9c\xf8\x5c\xbb\xd9\xd8\xd0\x6a\x7c\x7b\xb1\xd2\xb1\xec\xe2\x86\xf5\x88\x0a\x5c\xeb\x18\x7c\x24\x06\x38\x37\x59\x9d\x3a\x92\x33\x5b\x15\x9b\x30\x17\x0c\xff\x1d\xae\x17\xcd\x42\x83\xc2\x3c\x60\x7a\x75\x57\x54\x7f\x88\x1b\x3d\x2d\xad\x19\x0f\xd1\xed\x53\x56\x02\xd7\xe2\x54\x27\xa3\x92\x98\x00\xeb\x1b\x9d\x11\xe1\x7b\xc9\xd2\x69\xbf\xab\x4e\x12\x49\xa5\xcb\x1e\x8d\x02\x47\x9d\x00\x23\x81\x83\x73\x9f\x2f\x19\x54\x77\x45\x39\xd3\xe2\xa7\xb9\x17\xa8\xc8\x66\x01\x77\xe1\x7a\xde\xd1\xd2\x9c\x00\xe9\x7b\x4f\x6c\xdd\xa3\xab\xde\xcc\x4f\x09\x1e\x45\x78\x65\x0c\x9d\xcd\xd2\x9c\xfe\x76\x62\xb8\xc4\x79\x55\x59\xd0\xc7\x64\x80\xf0\x3d\x65\xab\x71\x86\x6b\xbe\x29\xe7\x31\x51\x5a\x00\xc5\x4c\x59\x5e\xa8\x89\x6b\xac\x65\x10\x46\xdc\xe2\xe4\x41\x3d\xdc\xc4\xce\x5a\xaa\x18\x6f\x23\xe7\x95\xe2\xff\xfd\xa4\x44\x61\xc7\xaa\x24\x42\xc7\xcb\xf9\xf7\x8f\x3c\x45\xa9\x8c\x9b\xf7\xaa\x74\x88\x5c\x29\x47\xa8\x6a\xc7\xdc\xd7\x9a\x7a\xb4\xbd\x67\x27\xe1\xcf\xc6\x5b\xed\xcf\x9a\x48\x34\x00\xf5\xac\xb5\x3d\xbc\xa5\xd9\xe7\x9d\x32\x93\x6f\xa7\x83\x10\x1d\xf5\x15\xbf\xb4\x77\xfa\x7b\x5a\x77\x10\x61\xad\x43\xa3\x0d\xdc\x69\x02\xd5\x4d\x99\xc3\x0d\x0d\xbe\x1b\x0d\x06\xa5\xf5\x91\xe6\xaa\xf8\xf0\xc7\x19\x21\xe9\x79\x9e\x17\x0b\xcf\x45\x9d\x1f\x03\x65\x1c\x77\xdc\x8f\x59\x27\xa0\xb3\x1c\xe2\x3b\x07\x77\x2c\x3d\xcf\x0f\x3c\xac\x63\x75\x32\x05\x0e\x6c\x29\x3d\x2f\x90\x44\x51\x47\x27\xd8\x46\x17\xee\x40\x18\x25\xc8\x41\xf8\xc7\xe6\xa9\xfb\x13\xf5\x91\x51\x0d\x7f\xcf\x10\xba\x0f\xf3\x09\xed\x08\xe1\x31\x87\x73\xbf\x9a\x24\xd8\x76\xdd\x1d\xd4\x26\xf4\xaf\x64\x71\x93\x26\x1c\xdf\x30\xa1\x11\x17\x43\xa9\x9f\x71\xc3\x4b\x33\xa2\x59\x45\xf7\x64\xfc\x62\x08\x67\xf8\xc0\xc8\x6a\x89\xed\xe4\xce\x08\xd9\x01\x11\x35\x82\xdc\xc6\xbc\xba\x6e\xb7\xc9\x6c\x99\xb8\xb5\xed\x69\x92\xe2\x0b\xef\xfb\x97\xce\x97\x76\x23\xe9\x5e\xea\xf8\x31\x22\x25\xf1\x57\x5e\x8b\x3c\x10\x5c\xbe\x35\x17\xf7\xfb\xb1\xef\x99\xf4\x7a\xd5\xb3\x5e\xb5\x06\xf7\x86\x60\x69\x8e\xe0\xc5\x5d\x23\x32\xd8\x2d\x84\x1c\x16\xe7\x62\xe8\x32\x4c\xd4\x20\xa4\xe7\x31\x6a\xc8\x34\x96\xab\xdd\xaf\x1a\x87\xa4\xe7\x25\xc4\x74\xf8\xad\x8b\x73\x8a\xdc\xac\xee\xc6\x13\x41\x22\x0b\x34\x45\x26\x06\x93\xc9\x37\x7e\xe2\xe8\x0a\x5c\x19\x0b\x67\xab\xbb\x6e\xe3\x1c\xf7\xc9\x48\xcf\x13\x1e\x75\x88\xa7\x45\x59\x2e\x8b\x22\xbb\x4b\x21\x53\xa1\x3b\x2e\xfd\x18\x6d\xf2\x7d\x71\xff\xdc\xfd\x2d\x90\x60\xd0\x10\x7b\x93\xc0\xb4\x29\x01\x77\x98\x40\x82\xc8\xf5\x61\x8b\xf9\x34\x5f\xdc\x8e\xe3\x21\xb3\xa9\x8a\x89\x0e\xc2\xe4\x4d\xab\xc8\x80\x74\xbb\x56\x97\x0a\xea\x27\xa8\x3f\x8a\xf2\xcd\xfd\xa6\x62\x3a\x54\xbd\x50\xca\x43\x51\xd7\x50\x5e\x07\xb5\xaf\x76\x0c\x07\x6d\xf9\x0d\xa1\xbc\x1b\x70\xdb\x8e\xdf\x1c\x90\xd0\xf1\x8e\x58\x87\xd4\xd4\xd9\x71\x8f\x68\x77\x1d\x6c\x02\x75\x17\x05\x6e\x74\x2c\x76\x45\xc6\xcb\xb4\xb2\x7f\xf6\xfd\x80\xa2\x93\xc4\xcb\x01\x8f\x6c\xfb\x77\x2a\xb1\x8e\xa7\x0a\xa7\xb0\xfe\xe9\xfb\xf1\x7d\xa9\x7c\xfb\x69\x56\x59\xfa\x63\x74\x9d\xc0\x6d\xf1\x69\xee\x7a\x9a\xdc\x2a\xb2\x23\x42\x8f\x63\x03\x09\x57\x8a\xab\xbf\xb8\x84\x5c\xba\x1d\xd7\x77\x93\x79\xf4\x1f\xf6\x3c\xe2\x69\x4c\x1f\x8a\x54\xfd\x8c\x71\xaa\x1d\x49\x28\x01\x97\x0b\x33\x2d\x9e\x69\xa1\xf6\x45\x96\x21\x37\xb3\x1b\xc5\xe2\xc8\x71\x27\x7c\x76\xc1\x3e\x4a\x91\x9e\x1f\xd1\x44\x5b\xb5\x04\xe4\x0e\x73\x17\xa2\x2c\x52\xad\x33\x75\x77\xfc\xfd\x38\x7a\x17\xb1\x47\x95\x1a\xb9\x17\xcb\xeb\x9e\xe7\x6f\x3f\x73\x99\xdb\xd3\x7c\x1f\xd1\xa3\x75\x07\x7d\x69\x3a\x15\x16\xe9\xf9\x4c\x79\x60\xa7\x41\x57\xca\xb8\x25\xb7\x6d\x07\x6a\x30\x89\xbe\x46\x9c\x2a\x40\x18\x0b\xcc\xc0\xac\xa4\xe7\x73\x5f\x46\x1d\x87\xfe\x01\x21\x52\x83\x6c\xd5\x74\x30\x93\x8c\xf4\x4e\xeb\x4c\x49\xc1\x0d\x84\x08\x7b\xf6\x7f\x31\x9b\x44\x68\x14\xa9\x0e\xc7\xc5\xfe\x88\xfc\x4a\x4f\x0b\x2b\x45\xd1\x1e\x95\x09\x0b\xec\x92\x36\x0a\x39\x30\xd9\xed\x7c\xe9\x4b\x1e\xf6\xfe\x8f\xe5\x29\x70\x17\x90\x9c\x74\x52\xa9\xb8\xef\x18\x19\xe9\xf1\x25\x94\x6f\x30\x36\x2f\x36\xc0\x1a\x42\x5e\xdd\x85\x14\x0b\x98\x1d\x73\x12\x93\xaa\xe0\x70\x9d\xfa\x0a\x88\xa9\xf7\xd6\x45\x09\xcb\x9f\x57\x04\xa5\xe7\x43\x68\x51\x4a\x4a\xd9\xea\xd0\xcf\xa7\x07\x84\xa6\x17\xf0\x50\x37\x17\xe4\x48\x1a\xcd\x39\x60\x02\xb3\xf0\xff\x49\x5f\xd2\x6e\xc9\x69\x62\xa6\xfa\x09\xd5\xf8\x81\xb7\x37\x6b\x3e\xf1\x0c\x1c\xb9\x1d\x1f\x51\x04\x49\x63\x28\x76\x2c\xd6\x69\x25\xd3\xcb\x7c\x21\xa1\x1d\x9d\x40\x18\x77\x00\x25\x9e\xad\x5d\xbf\xd7\x68\x58\xe0\x11\x81\x7b\xf7\x86\x57\xd7\xe7\xea\x9c\x36\xe7\x71\x19\xb6\x1d\xa2\x34\xe9\x45\x4e\x27\x5c\xb1\xd2\x0b\x82\xc0\x8f\xe4\x20\x23\x36\x6c\x83\x6e\x0f\xc7\x02\x27\xdc\xa9\x2e\x8e\xfc\x07\xdc\x9c\xcd\x4d\x9a\xe4\x1e\x6a\x87\x92\x6b\x3a\x40\x5e\x7b\x1c\x34\x09\x7b\x02\xe5\x07\xd0\xf5\xb1\x78\x32\x6c\x41\x3c\x33\x45\x51\x2b\xb9\x36\x08\x4f\xa5\x17\x84\x3c\xc0\x72\xcf\x32\xad\x0f\xc7\xf5\xb7\x14\x3e\xc6\xd3\x2b\x88\xfc\x88\xdb\xc4\xc3\xd1\x8a\x53\x75\x89\x36\xe9\x05\x34\xf4\xb1\xe0\xb8\x38\x1e\x27\x27\xd2\x30\x88\xfb\x76\x96\x25\xcf\xdf\x6e\x08\x6d\xa5\x17\xc4\x21\x53\xdc\xa6\xc3\x90\x9f\x14\x71\x82\xbf\x0e\xcf\xa5\x17\xb0\xc4\x54\x8f\x2f\x45\xcd\xeb\x41\xbe\xb6\x3d\x24\x29\x62\x27\x50\x38\x99\x05\x93\xdf\x64\x4a\x1b\x75\x38\xad\x07\xa7\x40\x28\x0d\x61\x41\xa9\xfe\x98\x9c\x90\xc4\x02\x9b\xc7\xd7\x25\xf0\xf3\x1f\xee\x0c\xce\x9d\x54\x70\xcd\x33\x73\xc7\x96\x92\x71\xdd\x98\x59\x8a\x78\x0c\x3b\x5a\x78\x04\xd9\x46\x4a\xa8\x64\x03\x0f\x45\xd5\x3a\x38\x17\xf8\x44\xc1\xa2\x3d\x21\x0a\x11\xeb\xfe\xb4\x78\xec\x2f\xa2\x09\x3a\x16\x88\xd1\xb0\x33\xe8\x73\x02\xcb\x4f\xde\x9b\x64\x09\x6e\xd9\xbb\x12\x52\x59\x18\xad\x2c\x77\x48\x26\xc8\x27\x8d\x7c\xab\x6b\x5c\x86\x43\xf3\x10\xa8\x76\x2b\xb3\xfa\x01\xae\x4a\xc3\x3e\xc5\x7e\xb7\x27\xf8\x60\xc0\xfe\x27\x55\xc8\xe6\x3c\x21\x6f\x95\x5e\x00\x11\x43\x2c\x65\x59\x20\x53\x5e\x37\xaf\xb4\xc7\x4c\x49\xa3\xf5\x76\x97\xa9\x13\x33\x1f\xed\x12\x81\x56\x11\x32\x44\x6e\xc8\x03\x7f\xe7\xf6\x54\xa4\x31\x8a\x4d\xf5\xc2\xf0\x58\xcf\x81\x65\xdb\x71\x8a\x09\xe6\xe4\x04\xcb\xd9\x4e\xab\x76\x94\x0e\x11\x43\xdd\xe9\xe5\xcf\x35\x00\x4a\x2f\xf4\xb9\xef\x4c\xac\x61\xb4\x1d\x79\xd9\xa1\xcf\x63\x04\xbb\x22\x0f\x9e\xe2\x59\xb5\x34\x41\x94\x3d\x1c\x10\x19\xc7\x73\xa4\x88\xe3\x6f\x17\x06\x8c\x38\x0d\x42\x77\xbf\x56\x72\xda\x0d\x48\x38\x96\x00\x11\x7c\x63\xdd\xa1\xbb\xb2\x4f\x57\xff\xcf\xcd\x66\xe6\x4e\x54\x12\x01\x7d\x16\xfe\x30\x3f\x29\xc3\x90\x71\x6f\x58\xba\x3a\xa6\x19\x52\x63\x99\xd5\xd7\xb9\x3f\xe3\x93\x48\x28\x5c\x50\x6a\x95\x81\xb0\x6e\xa7\xb9\x9c\xec\x65\x61\x14\x9a\xf9\xed\x8a\x31\x96\x42\xb8\x3d\x02\x86\xbb\xa2\xc8\x5f\x8b\x4c\xd9\x44\x6a\x35\x39\x9d\x06\x51\x60\xb1\x55\x4e\x49\x6e\xec\x02\xcf\x24\x21\xda\xd3\xa4\x8f\xd3\xa8\xb5\x97\xf7\x90\x7f\xb9\x5e\xdc\x82\x08\x63\x66\x3a\xde\x1f\xaf\x26\x39\x61\x8a\x65\xe3\xd3\xe3\x24\x42\x36\x29\x05\x17\x5e\x22\x99\x64\x39\x29\xa7\x3a\x84\xaf\xcd\x6e\xb5\xe7\x70\x88\x06\x74\x14\x86\x8a\xe7\x84\x7c\x8b\xdd\x4f\xab\xc4\xa9\xe1\xd8\x9c\x38\xca\xd4\x60\x5a\xf7\x96\xee\x48\x7a\x21\xe3\x21\xd6\x27\xd0\x1e\x75\x13\x82\xf5\x2d\x7f\x9d\xc1\x99\x6f\xb9\xba\x01\x41\x49\x2f\x4c\x22\x83\x58\xbf\xe3\xd2\x12\x19\x0e\x77\xec\x30\x89\x4c\x4b\x53\x5a\x59\xaf\xfe\xb9\xdc\xf1\xaa\x36\xa0\xe8\xf1\x5b\x4a\x04\xc3\x12\xda\xe9\xcc\xdf\xe0\x70\x01\x99\xf2\x6c\x7b\x0b\xfa\x1f\xaf\x9a\x44\x8c\x85\x14\xcd\x0e\x54\x16\xe7\xdd\xdb\x2c\x8f\x4b\x7b\x8a\xa2\xe8\xa2\xef\x1a\x43\x48\xd0\xdd\xaa\xe2\x08\x05\xc5\x3c\x18\x02\xc9\xd2\x22\x7f\x4c\xbb\x47\xe1\xc4\xf3\x6d\x3e\x0d\x99\x02\x30\x41\x3d\x7a\x17\x9c\xcb\x98\xf7\x44\x90\x6b\x9b\xf0\xef\x49\x58\x1c\x0d\x03\xb3\x27\x88\xd8\x53\xae\x08\xd6\x94\x39\x3a\xf0\xe3\x97\x22\xb8\x87\x1f\x67\xf9\xb4\x9a\x1e\x51\x82\xdb\xc6\x9d\xbd\x1a\xf2\x3b\x8c\x9f\x56\x86\x46\xe8\x37\x75\x22\xf5\xbf\x8d\x0f\xc7\x81\xd5\x8d\x34\xfc\x54\x6b\x90\xa9\xea\xdf\x89\x04\x1f\xf7\xa4\x65\x81\xa8\x2a\xcb\x1e\x39\xb9\x13\x09\xa6\xd2\xdb\xd1\xd8\x1d\x3a\xc2\x99\xf6\xa8\xf6\x3b\x51\x83\x2b\x36\x72\x74\x57\x57\x9e\xe9\x0f\xe1\xa7\xf7\x14\x50\x03\xd3\xc0\xf1\x16\xb9\xb2\x9a\x9b\xbf\x0d\x56\x84\xf2\x0d\xa6\xf3\x1d\xca\x54\x5f\x57\x50\xd6\xdf\xd3\xfa\x75\xbb\xbe\xc1\x98\xcd\x80\x6f\xdb\xd3\x99\x81\x10\x5a\x8a\x71\x2c\xe1\xae\x60\x22\xe9\x2d\xbd\x10\x02\x83\x12\xea\xaa\x27\x83\xed\x73\xa8\x87\x35\x79\xcf\x10\xb2\x60\xa4\xc5\x8d\x75\x76\xfb\xa4\xed\xcc\x61\xba\x47\xc1\xb6\xaf\x61\x63\x2b\x76\x6e\x04\x0d\x8c\xac\x7f\x93\x77\x7f\x02\x2a\x6c\xc3\xf5\x4b\x3f\x0e\x04\xc8\xbe\x6e\x79\x48\xff\xee\x0e\xf9\x41\x88\xc4\xa5\xd2\x68\xa6\x1b\x7f\x15\x29\x1f\x3e\xc9\x3b\xcd\x05\x82\xc4\xa7\x51\xa0\x1c\xcd\x7e\xae\x8a\x72\xd1\x0b\x84\x98\x9d\xe4\x58\x72\x57\x91\x1c\x4e\x7f\xe2\x27\x4c\x5b\x17\x73\x93\xab\x75\xaf\x3e\x6a\x8f\x07\x91\x71\xd4\x37\xc7\x2f\x98\x23\xbf\x64\x69\x37\x17\x48\x18\x19\x62\x0d\x2c\xd5\x21\xbf\xe4\x5d\x99\x42\xae\xaa\xbb\x34\x7f\x81\xb2\x9a\xc2\xc2\xdb\x53\xa4\xa9\x32\x77\xcd\x0d\xe9\xb9\x39\x9b\x28\xa3\x1a\x39\xbf\x24\x54\xa6\x3a\x6f\xa6\x8e\xeb\xe9\xef\xf5\xbc\x6e\xca\x76\xd2\x23\x84\x11\x6d\x1a\xa8\x2b\xe8\xd9\xa4\xc7\x77\x10\xc5\x61\x20\x3b\xe8\xff\x56\x16\x8e\xc1\x76\x84\xbf\x6e\x07\x26\x0c\x99\xf4\x2c\x51\xea\xae\x84\x31\x83\xcf\x4f\x1d\x33\x36\xba\x2f\xea\x45\x66\x56\x14\xba\x7b\xcd\xee\x50\x00\x32\x1c\x23\x15\x8e\x8e\xec\xd9\xc6\x7c\x3f\xeb\xc0\x6a\xaf\x10\x1a\x4a\xc5\x8c\x57\xf5\x80\xa3\x0e\x8f\x30\xdf\x43\x0d\x90\xec\x3c\xb4\xf0\x84\x46\x1a\x8b\xec\x46\xd6\xb1\xaa\xa1\xfc\x9e\xe6\x55\x77\x54\xd2\xc4\x77\xb8\xed\xf6\xc1\x91\x1f\xfb\x58\x7c\x7f\x1d\x78\x1c\xb3\x9e\x04\xa1\xca\x74\xd1\x8b\xa2\x2c\x8b\x8f\xcf\x06\x8f\xde\x4d\x1c\x30\x44\x89\x5b\x9c\xf5\x76\x9d\xf7\xf2\x2d\xed\x61\x69\xac\x59\x3d\xe0\xdf\x36\x53\xda\x3e\x6b\x6f\x6d\x08\x4b\x8c\x5c\x9d\x53\x08\x71\xaa\x33\xce\xdf\x20\x4c\x69\xfc\x0e\x17\x57\x4b\x1c\xbf\xc9\x84\x42\x64\xfd\x35\x23\x88\x57\xe1\x0a\x1a\x18\x6a\x37\x90\xf9\xa1\xd5\x5c\xde\x22\x23\xfb\x8b\x4d\xe9\x4c\xc6\xf1\x88\x20\x23\x9a\xc5\x58\xb5\xa6\x7c\x50\xac\x69\x07\xf0\x04\x6f\xa8\xbc\x14\x1f\x8e\xba\xe1\x7f\x86\xc9\x15\x22\x44\x12\x19\x11\xc6\xbf\x4c\x25\xd6\xb4\xf7\xdb\xa3\x32\x4a\x1c\xcd\xcb\x3d\x3f\x43\xf7\x09\x25\x65\x20\x7a\x59\x8b\x2c\x2b\x3e\x3a\xf2\x8d\x7a\x30\x43\x24\x03\x8c\x30\x0f\x4f\x07\xd4\x78\x77\x7f\xe6\x46\x16\xf0\x64\xc2\x3c\x54\xa3\x18\x6f\x20\x44\x4a\xc3\x4d\x69\xe5\xad\xea\xdb\xf0\x96\xa8\xc4\xc3\xa0\xdd\x24\xfd\xaf\xbd\x8f\x33\x18\x02\xa1\x29\x58\x66\xbc\x7a\xb5\xd5\xc6\x87\xf4\x0d\x5a\x33\x99\x8f\x99\x2b\xa5\x47\x40\x2a\x61\x35\x9e\x6f\x93\xc8\x76\x8c\xf6\x7c\xd4\xd2\xbf\x14\x1f\xf3\xad\x5e\xed\x18\x69\x38\x22\xb7\x4f\xdb\xe3\x76\xf1\x70\xb2\x8c\xd8\x3d\x8b\xb6\xf4\x22\x8f\x1a\x8e\x32\xab\x74\xbc\x28\x4d\x12\xf5\xd6\xc9\x9a\x6e\x5a\x91\xa7\xa9\x72\xa4\x21\x68\xef\xc7\x6f\x2e\xf2\x63\x89\x55\xa9\x3f\x34\x94\x48\xb1\xd3\xf5\x05\xbb\xdf\xf6\xb5\x31\xba\x95\x61\x8f\x3c\xf3\x39\x19\x1a\xe9\x45\x01\x0b\xb5\x01\x95\xbc\x18\x1e\xa3\xd9\x5d\x34\x0a\x43\xab\x6b\x7d\xb9\x58\x31\xd3\x87\x01\x38\x60\x3a\x38\x26\xe8\x1b\x2e\xd2\x72\xf5\xea\x0c\x46\x14\x26\x1e\xfa\x59\xbb\xfd\xf6\x3f\x9b\xee\x8f\xca\x48\xa7\xa3\x47\xb6\xe4\x2f\x55\x77\x00\x84\xee\x28\x06\x0c\x79\x23\x06\xa4\xb3\x00\x40\xe9\x45\x34\xa6\xc8\x7e\x54\x35\x02\x83\x9f\x9b\x05\x17\xc5\x54\x20\x4d\xdf\xd9\xf4\x91\x54\xd3\xc3\xc2\xe8\x59\x1c\x2e\x3c\xcd\xdf\xab\x7d\x53\x55\xa9\x8b\x1c\x23\x46\x00\xeb\xc4\x03\x0a\xb7\x6a\xd0\x42\x20\xbd\x28\x89\x79\xe4\x84\xee\xd4\xf7\xa2\xda\x15\x45\x76\x57\x94\xa8\xea\x35\xf4\x8b\x22\x1e\x7a\x88\xd7\x38\x0d\x54\xc6\x3f\x09\xea\x22\xce\x80\x39\xd9\xc2\x36\xa2\x77\xd9\x1d\xf6\xbf\x7e\x4c\x27\x71\x5a\x24\x62\xa9\xad\x8c\xac\xf3\x62\x6f\x65\x88\xdb\x71\xcc\xa3\x6e\x5c\x71\xbe\xd4\x70\xf2\xd9\x68\x8d\x44\x12\x3c\x36\xf2\x69\x76\x45\x3a\x70\x98\x26\xbf\xab\x7c\xd3\xf4\xe8\x98\xb6\xfe\xf5\xbc\x7d\x3a\x1a\xce\x4c\xf7\xcc\x4a\x45\xca\xf0\x02\xd5\xf2\x75\x21\x8a\xb2\x86\x89\x99\x8b\x20\x8a\x51\x2b\xee\x25\x7d\x87\x7d\xfa\xf2\x5a\x1f\x0b\x84\x85\xcf\x06\x66\x91\x26\x0c\x41\x9a\xeb\xcd\xb7\xf1\x9a\xa3\x1e\x97\x88\x86\xb6\x90\xae\x0e\x91\x6d\xff\xbf\x1d\xe5\x47\x1a\x03\xcf\xd5\xee\x7e\xb7\xd9\x6f\xee\xf7\xdb\xa7\xcd\x69\xf3\xc7\x71\xbf\x58\x21\x03\x6a\xc7\x52\xd8\x8e\x4d\xa4\xa3\x79\xdf\x95\xe9\x99\x97\xd7\x59\x77\x98\x06\xd4\x64\x86\x2d\x7c\x6d\x10\x84\x8f\x4d\x10\x0d\x94\x49\x4c\x5b\xc5\xf1\x01\x85\x6c\x7b\x10\x0c\xd9\xf6\xc9\xe8\x5d\x9e\xe0\x7c\xa9\xaf\xa7\x4e\xef\xc8\x8d\xd2\x46\xa9\xde\xaa\x2a\x0f\xe6\x17\x0d\x7d\x81\x89\xf6\x73\x6b\x16\x46\x3b\x05\x25\x91\xe7\xbb\xe9\xc4\xab\x1a\xc9\x64\xc7\x9f\x81\x92\x98\x80\xd7\xe5\xe6\x8c\x2f\x3b\xeb\x32\xd0\xc8\x63\x68\xa2\xfe\xbd\x3c\x22\x6c\x6b\xfc\x32\xa2\x40\x62\x59\x61\xa3\x20\xdb\x17\x55\xdd\x9a\xd9\x2e\xa4\xa2\x51\xe2\x23\x0c\xb7\x97\x8c\x4a\xa1\x1a\x20\x96\xdb\x21\x20\x91\x42\xe6\xbf\xad\x51\x42\x75\xf5\xc9\x71\x2d\xb5\x3f\x64\xb8\xda\x2d\xf6\xc7\xa7\xcd\xfe\x70\x3a\x6c\xd7\xdd\xb7\xa3\x42\xf9\x56\x59\x7b\x5b\xc3\xf9\x26\x69\x3d\xbe\xe9\xd8\x0b\xd4\x80\xd5\x78\xf8\x56\x63\x4f\xa1\xc7\xd7\x2d\x89\xb5\xc3\x4e\xb6\xcb\xcc\xca\xe8\xba\xb1\x91\x88\x6d\x73\xde\xd2\xf1\x31\x38\x1c\xf5\x5c\xa5\x82\xc6\xb1\x16\x96\x3b\x6c\xdb\xf1\x49\xdd\xc8\x03\x8d\xef\x95\x25\x80\xee\x7a\x0e\x1f\x98\x71\xb6\x81\xd3\x8a\x9f\x2f\x3c\x7d\xf9\xa4\x36\x4e\x19\x70\xfc\xbc\x17\xf4\x96\x4f\x76\xe3\x3d\x7d\x18\x8c\xf3\xc4\x24\x52\x1e\x04\x08\x71\x53\x45\x96\xf1\xb2\xba\x2b\xca\x61\xe0\x4c\x85\xa7\x1c\x30\x5f\x8d\xdb\xbe\xe6\x6f\x59\x44\x01\xb3\x24\x15\x7f\xb4\x1b\xf3\xbf\xf7\x3f\x23\x10\x91\x1e\x95\x84\xb8\x46\xb7\x93\x30\x59\xb1\x51\x16\x80\x4a\x4a\x65\xc7\x7d\x7d\xc5\x22\xa3\x3d\xa2\xfc\x20\x0e\x5c\xb6\xcb\xf8\xe8\xfd\x21\x82\x78\xba\xe2\x62\xb2\xa4\x8b\x3c\x2f\x9a\x5c\xc2\x6d\x0e\x92\xaa\x38\x26\xf6\x06\x16\x59\x86\xae\xfb\x90\x42\xb8\x1d\xc1\x05\xb2\x2e\x9c\xa0\x6a\xc3\xe0\x2f\x45\xe5\x84\x68\x36\xbc\xcc\x07\xd2\xd2\xd3\x47\xbc\xf5\x67\x27\x9a\xcb\xd2\xa3\xda\x37\x39\xbd\xd6\x97\x6c\xce\x5b\x03\x79\x36\x3b\xfd\xf4\x53\x69\x5f\xc8\x5e\x5b\x0c\xb9\x39\xb0\xc9\xfc\x93\x79\xa0\x89\xf4\xdd\xec\x71\x33\xe6\x17\xe1\xf4\x3f\xe9\xff\x6e\xaf\xcc\x42\xe2\x75\xcd\x71\xb6\x24\xb1\xbc\x9a\xc4\xcf\xe4\x26\xb8\xc2\x6c\x7b\x5a\xc3\xb9\x5b\x3c\x5a\x6b\xdc\x07\x6c\x63\xf8\x8e\x37\x95\xe5\x67\x19\x78\xe9\xed\x42\x4d\x4c\xce\x28\xed\xbe\x45\xec\x25\x31\xf2\xf3\xc9\x22\xcd\x55\x59\x5c\x2a\x1b\x6e\xa7\xf9\xcb\xa2\x1b\xe4\x47\x56\xba\xa2\x42\x64\x22\xd7\xa3\xeb\xfa\x3a\x14\xba\xe7\x67\x76\x40\x0a\x35\xa0\x10\x95\x5e\x1c\x90\x00\xd7\x5e\xcf\xb6\x32\xf7\x71\x67\x91\x38\x78\x76\x12\x77\x9d\x88\xbb\xac\xa8\x1f\x4d\x50\x8c\xaa\xcc\xc3\xae\xc3\x01\x06\xfb\x17\x24\x44\xed\x55\x95\xc4\x20\x7c\xf3\x63\x44\xc1\xea\x6e\x39\xe4\x3a\xb2\xd4\x64\xb6\x89\xa8\xcf\x70\xc5\xc4\xf3\xb5\xd5\xa9\x38\x16\xad\xe3\xd2\x1f\x90\x48\xe7\x9d\x37\x67\x97\x69\x7c\x56\xaa\x3b\xea\x9b\xad\x16\x01\xf9\x88\xc2\xb2\x3e\xe6\x70\xab\x8a\x49\xe8\x11\x62\x9b\x51\x7b\xe1\xbe\xc9\xfc\x8d\x49\xe8\x87\x26\x51\x92\xca\x36\x0e\x42\xc6\x96\xee\x12\xdc\x80\xdd\x9d\x62\xf2\xa0\x38\x3b\x5b\xda\x1e\xbf\x19\x1a\x85\xd8\xa5\x75\xcf\xdf\xd3\x7c\xac\x51\x36\xfb\x26\xa9\x64\x18\x0f\x3d\x15\x65\xfd\xba\x2b\x32\x58\xdc\xb9\x1b\x89\x89\xc2\x97\x2c\x79\x7e\x67\x7a\xcf\xe6\x52\x08\x71\x1c\x1b\x29\x29\x5b\x50\x5d\xac\xbb\xf3\x85\xa7\x2d\xed\xc5\x62\xef\x90\xbc\xee\x60\x42\x7c\x27\x62\xd6\x3e\xa1\x7c\xfd\x0e\xe9\x6f\x93\xba\x72\x9c\xc4\x1c\x7c\x47\x95\x52\x6e\x73\x59\x9c\xed\x2e\x3d\x9e\x64\x89\x34\x41\x11\x57\x7f\x35\xd5\xad\x33\x1c\x73\x5f\x7b\x3d\x41\xc4\x97\xa2\xa9\xb0\x85\xd0\x22\x43\x47\x4b\x3a\xe6\x61\x80\xb6\x05\x9b\xdf\xaa\x07\x78\x99\xe6\x43\x5a\xd7\x17\x73\x7d\x8f\x69\x5e\x77\xcc\x00\xed\x74\x46\xe5\xdb\xb2\x5b\x38\xc2\x67\x68\xaf\x77\x4d\x96\x59\x33\xf9\xe8\x78\x3f\xda\xc3\x41\x84\xbe\xcf\x61\x71\x87\x91\xe4\x2f\x91\x3b\xb1\x90\x1a\x9d\x10\xc7\xf5\x79\x46\x8c\xd6\x9a\x5f\xe7\x6b\xc0\xb1\x92\x51\x32\x2c\x23\xec\x8a\x71\x2e\x2b\x56\x92\x25\xc6\xd9\xcb\xb4\x23\x46\x5d\x6f\x9f\xa6\xd3\x55\x29\x03\x90\x14\x8d\x85\xe4\xba\x47\x80\x30\xec\xf3\x1e\x39\xd4\xaf\x7c\xda\xc8\x3f\xb0\x36\x9a\xc4\x88\xb1\x30\x34\x75\x36\xae\x72\x57\xd2\x71\x1c\xf2\x71\x11\xd1\x2e\x9f\xae\x38\xc4\x3c\x6d\x1d\x75\x94\xc8\xf8\x61\x00\x78\xc7\xeb\xc5\x49\x59\x0e\xeb\x0b\xa3\x17\xc7\xfc\x24\x41\x11\x8b\x81\x42\x68\xfb\x57\xd0\x48\xac\xf7\xca\xab\x03\xb4\x11\xf1\x12\xa0\x93\xbb\x1d\xcf\x0a\x16\x92\x08\xbd\x58\x03\x8f\x6b\xea\x8e\x13\x71\xf4\xa6\x58\x18\xf9\xc6\xc8\x57\xdf\x0a\x9c\x1b\xe3\x89\xca\x88\x1f\x21\x4f\xd3\xf3\x7e\xbd\xd9\x9f\x76\x0f\x8b\xd5\xe6\x36\xf5\x3f\x93\x7e\x1d\x7f\x58\x46\x22\x40\xfc\x9e\x6c\x23\x0c\xcb\x14\x30\xa1\x99\x1b\xbf\x00\x42\x4d\x41\x13\x3d\x9a\x35\x64\x35\xff\xac\x8d\x4a\x7a\x2c\xf2\xc1\xb3\xeb\x16\xd5\xa8\x46\x28\xdf\xfe\x26\x28\x31\x40\xbc\xda\x95\x7c\x87\xa5\x67\xc6\x3c\xcf\x49\xc6\x3d\xa6\x79\xd7\xa7\xfb\xac\x71\xb7\x9e\xcc\x30\xc6\xe2\xc4\xf1\xb5\x3f\x5f\xa0\xbc\x51\x34\x6a\x87\x28\x8d\x86\xea\xb0\x59\xed\x37\xc7\x93\x11\xd8\xbc\x5b\xac\x8e\xcf\x7b\xf7\x9b\x9c\x51\x7c\xbb\x90\x2b\xa3\x9d\x74\xe3\x64\x30\x29\x3d\x97\xf7\xed\x73\xc7\xbd\x87\xc3\x94\xaf\x51\x62\xaa\x4e\xcf\xb6\xbc\xe9\x0e\x28\x1f\xd7\xde\xf6\xf9\xeb\x67\x1a\xe0\xd2\x63\xe0\x45\xa6\xd0\x20\x8b\x7d\x93\xc1\x0a\xdd\x82\xc9\xb3\x02\x70\xa3\x02\x9a\x15\xf9\x08\x9e\xd8\x0d\x49\xbc\x48\x83\x05\xbc\x1c\x6a\x2e\xdf\x6c\x37\xcd\x6f\xee\xb0\x20\x46\x4a\x0a\x63\xaf\x3d\xc8\xa2\x54\xb7\xca\x55\x38\x90\x21\x84\xda\x0c\xfc\x3d\xcd\x5f\x54\x71\xfe\x44\x25\xe3\x97\x9e\xcf\xec\x54\x4c\x3c\xc5\x91\x4a\xf6\x3f\xaf\x90\xe7\x45\xef\x01\xda\xc3\xbe\x47\x90\xb2\xc0\xda\x3f\x9b\x5a\x4f\xcf\x6d\xbc\x71\x9e\xe5\xe7\x6b\x4f\xa2\x24\xec\x09\xab\x57\xaf\xc5\xa4\xef\xae\x1d\x22\x4d\x93\x61\x39\xc2\x4a\xdf\x42\x93\x12\x1f\x48\xc4\x6d\x3b\x74\x6e\x10\x8f\x6e\x0f\x4a\x02\xaa\xd0\x7b\xfb\xb2\x7c\x1e\x26\x7b\x93\x20\x09\x11\x9e\x63\xe1\x51\x28\x9b\x36\x7d\x4b\x63\xb6\xa2\xc9\x4b\x09\x40\x62\x28\xe1\x1a\x9c\xbf\xf5\x56\x27\x09\x89\x74\xca\x8b\x4f\xf0\xa3\x6e\xa7\x49\xf7\x61\x43\x26\x5d\x03\x23\x42\xc7\x5f\xfa\x4a\xd6\x0d\xa7\x80\xf4\x12\x12\x28\x9b\xbc\x37\xa6\xfb\x89\x9f\xe1\x8f\xed\xda\xe8\xb7\x5d\x2e\x9f\x3a\xe3\xc3\x4b\x50\x85\xc9\xd2\x45\x5d\x9c\x07\x31\x6b\x42\x64\x8c\xf5\xf3\x6f\x50\xa6\x35\xaf\xa0\x19\xa5\xc3\x13\xa2\xb4\x11\x40\x7c\x4d\xf5\x27\x15\xc8\x24\xa2\x5a\x25\x0e\xe1\x6c\x8d\xba\x8d\xfe\xc7\x03\x69\xa8\x92\x78\x80\xdc\xaa\xc6\xa3\x26\x93\x83\x52\x8a\x4d\xa8\xfb\xa2\x38\x3f\x15\xad\xc3\xa1\xd4\xb0\xdc\x98\x50\xce\x31\xf0\xd2\xf8\xc7\xd1\xa1\x58\x51\x57\x7e\xd9\x6d\x4d\x07\x64\xe8\x8d\xb6\xc4\x84\xf9\x01\x7e\x7b\xd1\x5c\x3b\xd2\xe2\xaf\x79\x5a\x77\xdf\x88\x05\xde\x80\x70\x1b\x0d\xea\x22\x57\xf5\xed\xd3\x4d\x5e\x47\x12\xd3\xc8\x64\xb6\xab\xda\x24\x76\xc7\xcf\xc5\x09\xe8\x7e\x7b\xdc\xd4\xaf\xc7\x1f\x43\x05\xa9\x76\x04\x4b\x90\xde\xe6\xb0\x3b\xba\x5c\x53\x22\x02\x8e\x91\xfa\x07\xa4\x8f\x86\x3e\x60\xf2\x72\x85\x32\x61\x87\x0d\xd9\x7e\x5e\x19\x49\x14\x33\x72\x01\x83\x5c\x58\x93\x2b\x5c\xb0\xd5\x8d\xfa\x90\xf4\x12\x1d\x06\xd8\x7d\x81\xa2\xf9\xff\x6e\x6f\xf6\x06\x43\x98\x68\x50\xc1\x90\x52\xbf\x9d\x9e\x6e\xe3\x99\xfd\xc4\xdc\xa3\x80\x24\xaa\x69\xae\x0b\x57\xc6\x22\xbf\xb9\x83\xc2\xb4\xb5\xbf\x40\xfd\x7b\x9a\x65\xa0\x8c\x96\xfb\xe8\x37\xb9\x4f\x4c\xf3\x75\x5a\x1d\x81\x9f\x1f\x90\xe6\xd3\xe4\x2d\x9e\xdf\xa1\xdc\x6a\x94\xb4\x9c\xb8\x2a\xe3\x7b\xf0\x23\x4f\x98\x69\xf6\xce\xff\x53\xe4\xb0\x1c\xce\x7f\xee\x73\xc3\x98\xf8\xc3\x8f\xba\x3f\x89\x38\xe8\x3c\x18\x93\x2d\x6d\xef\xfd\xb9\xa9\x7b\x7a\x8d\x76\x18\x44\xf8\x36\x8c\x49\x5e\xf3\x62\xf7\xfc\x70\xf8\x7d\x51\xdf\x34\x67\x4b\x8f\x07\x81\x87\x8b\xd0\xf4\x95\x7d\x72\xa3\x41\x98\x60\xab\xe1\x3b\xcf\x1a\x8c\x25\x06\x15\x59\x1e\x30\xcf\x0a\xcc\xd4\xc7\x12\xe0\x50\x97\x8d\x1c\xd5\x02\x27\xd7\x52\x09\x3e\xf4\xa6\xaa\x20\xaf\x53\x3e\x7a\xe6\x30\x32\xbc\x85\xa2\x29\xf3\x09\xe5\xf4\xf8\xe5\x87\x11\x30\x31\x5c\xcf\xe8\x17\xab\xc5\x64\xdd\xf3\x90\x86\x24\x1a\x8c\x43\xff\xc1\xc0\xaa\xc7\xad\x07\x3c\x4c\x34\x36\x4b\x88\x91\x18\xc5\xf8\x6a\xc4\x37\x44\xcd\x88\xc0\x3e\x60\x87\xef\x27\xf7\x47\x02\x85\xce\x46\x57\x19\xb5\xb9\x06\x47\x07\x2f\x3d\x1e\x09\x29\x54\x2f\x02\x68\x2a\xe8\xf6\x58\x4c\xc3\xa4\x83\x26\x6f\xb5\x9d\x46\xdb\x0a\x4b\xe9\x0f\xa3\x52\xba\x3b\x43\x1b\x7d\xb4\xc7\xc5\x37\x64\x61\xff\xa5\xa7\xcf\x99\xd5\x20\xe9\x71\xe2\x5f\xab\xf6\xdd\xe8\xd1\x5c\x62\x34\xc1\x8e\x94\x27\x7e\x6e\x7d\xcd\xae\x1a\xd4\x67\xde\x7a\x4b\xcf\x59\x92\x60\x6b\x8b\x5b\x86\x8b\x0a\xf3\x8c\x9f\x56\x1c\x7f\x52\x3d\xe7\x4c\x9b\xe2\xc2\x5d\x96\xbe\xbc\xd6\x28\x8e\x78\x53\x57\xe2\x89\x47\xad\x60\xf4\xcb\x37\x9e\xb5\xf3\x29\x07\x6b\xd1\x9c\xe2\xf4\x6c\xa0\x3f\x3f\x35\x93\x88\xf9\xca\xf6\x5e\xdd\x04\x78\x3c\xa1\x06\xb5\x98\x17\x35\x96\xbe\xf3\x4f\x01\xff\x3c\x49\x38\x76\x06\x14\xb9\x6b\x5f\xff\x5a\xa9\x36\xf8\xb4\xc7\xb9\xcf\x90\x9c\xe4\x4b\x5a\x75\xcd\x87\xed\x9f\x43\x81\xe9\x3f\x0c\x00\x46\x09\x12\xce\x63\x08\xa0\x67\x48\xca\xdf\x8b\x01\x2c\xd7\x8d\x91\x03\x91\xf9\xdf\xd3\xba\x4e\xbb\x5d\x9f\x8b\x28\xf6\xec\x22\x75\x84\xf3\xff\xa0\x5b\xa9\x3d\x91\x51\x9c\xa5\x87\xe5\xc1\xca\xb5\xf7\xd7\xd4\x0c\x77\xba\x29\xcc\xe7\x31\xcd\x20\x70\x83\x64\x68\x9a\x00\x76\xfb\xcd\x69\xbb\x7a\xb6\x3e\xf5\xde\x29\xfb\xb5\x23\x92\x04\x5f\x16\x5e\xe6\xeb\x7e\xbb\x2b\x41\xa7\x3f\xdc\x51\x15\x13\xd3\x91\xea\xba\x78\x46\x45\x22\xae\x44\x8c\xa6\x6e\xd1\xd4\xaf\xd6\x13\x9e\xff\xb6\x4a\x12\x1a\x8d\x66\x3b\x4e\xf3\x01\x72\x9b\x03\xe5\x18\x1f\x36\x59\x9d\x9e\x79\x0d\xcf\x4d\x2d\x8b\xb3\x83\x17\xba\x41\x60\x10\x68\xc7\x2f\x8b\xef\xa7\xd5\x9f\xab\x87\xcd\xe9\xeb\x61\xe3\xc2\x03\xe1\x13\x05\xb1\x13\x76\xcc\xd5\xd0\xbd\x17\x81\x47\x30\x9b\xd6\x6e\x0c\xb6\x6f\x74\x58\xa8\x10\x01\xf1\x91\x22\xb1\x75\xec\xfb\xdb\x12\x61\x18\x60\x08\x79\x2e\xde\xc1\xf0\x59\x75\x47\x22\xc3\x67\x5c\xd9\xce\xec\x5d\x59\xfc\x98\x54\x23\x45\xc8\x62\x8f\x0f\xe2\x73\x9b\xab\xea\x2e\x91\x98\x32\x5c\x93\xeb\x34\xe7\x59\x8f\x81\x11\x21\xd7\x98\x99\xd9\x3e\xad\xf6\x9b\xc5\x61\x33\xfc\x66\x22\x54\x1c\x8d\xf8\x1a\xde\xd3\xac\x12\xbd\x03\x21\x88\x22\x6e\xa2\xdd\x97\xc5\x07\xaa\x4d\xe2\xaa\xc5\xee\xb4\xa9\x7d\x16\x04\x28\x06\x8d\x5f\x8a\xfc\xe5\xad\xc8\x5f\xa0\x1c\x78\x88\x82\x68\x8e\xb1\xc5\xa9\x1c\xb5\xaf\x39\xc7\x5b\xd0\x98\xa2\x67\x72\xd8\x3e\x20\x7d\x8e\x81\xf6\xfd\xb1\xeb\xbf\x07\xd5\x1e\x16\x3d\xd0\x0d\x6e\xfd\x8c\x45\xae\xb0\xf1\xa8\xea\x47\x44\xd4\xb7\xfa\xe5\x69\xfb\xd5\x5d\x87\xd1\x94\x6a\xd7\x8e\x8f\x23\x11\xab\xce\x7f\x1e\x12\x4f\xcc\x39\x9e\x22\x06\x81\x5e\xc2\x0b\x3f\xc3\x89\x67\x93\xb2\x93\x60\x41\x84\x3d\xcd\x2f\x7f\xc3\xd7\x4a\x75\x7f\x25\x42\x5b\x44\xda\x14\x8f\xc6\xdc\x10\xce\xb0\xb8\xba\xfa\xb6\xc8\xe0\x2f\x9e\xab\xd2\xa5\xe3\x45\x12\x50\xbf\xe7\x9e\xda\xa5\x93\x78\x49\x24\x22\xa4\x7d\x8e\xdf\xd8\x99\xe5\x67\xbd\x4e\xa3\x3d\x43\x24\x82\x49\xe8\x0b\x6d\xc7\x62\xa1\xde\xd3\xea\x56\x7d\xcb\x0d\x07\x29\x2d\xd0\xef\x89\xcf\xe4\xce\x27\xc3\x39\xe5\xca\x84\xa4\xe7\x35\x68\xc8\x2b\x58\x75\x92\x36\xee\xe1\xb8\xf4\xb9\xe9\x2f\x7e\x4c\x5f\xca\x5b\x0b\x6f\x87\x89\xc0\xe3\x74\xc0\x5e\xf3\x33\x0a\x63\x77\x0a\xed\x54\x3b\xb0\x6b\x60\xd7\xfe\x70\x55\xcf\x00\x90\x85\x60\xc6\x0f\x70\x8e\x23\xb2\x32\xd9\x63\x2a\xd4\x18\xf0\xa9\xe6\x7c\x19\x31\xde\x8d\x2f\xa1\x58\x18\xf9\x3d\x46\x64\xdb\x7d\x7b\x08\x21\xe9\xb1\xfc\xcf\x5a\xa3\x72\xb0\xdd\x77\xe1\x06\x10\x25\x80\x08\x7b\xa1\xfc\x3b\xd2\x7e\x1e\x40\x16\xb9\xda\x95\xe9\xdf\xf0\x3b\x5c\x6d\x75\x9b\x74\xc3\x63\x8e\x35\x55\x4b\xc3\x69\x52\x03\xeb\xb4\x84\x41\x5d\xac\xdf\xd1\xa5\xef\x53\x87\xab\x34\x65\x5f\x43\xef\x31\x7a\x16\xe9\x87\x21\x7e\x93\xf5\xe2\x68\x8c\xfc\xe6\xc9\x25\x68\xa5\x9f\x28\xdc\x24\xce\x85\x7c\x3b\x65\xc3\x82\xa3\xf4\x85\xe1\x8b\xb0\x84\xfa\xb6\x39\xee\x9e\x57\x37\x82\x7e\x66\x30\xb3\x10\x5d\x0b\xc6\x47\xc0\xde\x68\x66\x4b\x5f\x9a\x9c\xbc\x05\x56\x2f\x66\xda\x8d\xa4\x0f\x20\xa4\x4b\xcd\x0f\x4b\x6c\xa3\xcd\x54\x06\xd2\x63\x36\x60\x44\x12\x5a\x03\x52\xb5\x07\x43\x65\x84\x15\x06\x7e\xb8\x21\xd6\xf6\x5d\xd5\x5c\x12\x42\xbc\xce\x55\x37\x96\xe1\x59\x77\x9d\x2c\x2e\xdd\x55\x75\xc3\x63\x23\x05\x80\x8f\x37\x26\x33\x6d\x8f\x2a\x86\x2f\xf8\xae\xc9\x55\xc9\xd3\xea\x1f\x08\x7b\xce\xa6\xf1\x67\x8a\x65\x3f\x5d\x13\x32\x0a\x85\xe1\x8d\x46\xe3\x98\x0d\xde\xf8\xbc\x0b\x25\xa9\x17\xa8\xce\x27\x58\x54\x95\xc1\xe6\xb9\x83\x81\x51\xb1\x5a\x97\xce\x31\xfa\x59\xd9\x40\x52\x4e\x0c\xef\x2d\x57\xc7\xb2\xc8\x67\x0b\xa2\xdd\x50\xca\x5c\x52\x03\x3f\x04\x72\xbd\x3c\xdd\x30\x80\x49\x4f\xc6\x34\xc1\xf5\x79\xa8\x8b\xcb\x65\xb4\xdd\xc8\x38\x0e\x42\xea\x80\x8a\x96\xb7\x60\xb0\x16\xe2\x58\xc4\xbd\x66\xf6\xb0\x32\x63\x52\x4e\x77\x45\x79\x5f\x64\xaa\xf3\xd1\xe7\xd6\x13\xf3\x8d\xf0\x73\xdd\xb9\x32\xe9\x14\xa1\x25\x59\x28\x3d\xe5\xe6\x82\xa8\x97\xd7\xad\x9a\x8e\x60\x81\x3f\x48\x01\x5a\xcc\xdd\xff\x7f\x9f\x96\x89\x88\x0e\xf5\xb0\x07\xac\x33\x23\x1d\xf1\xf1\xb2\x60\x52\xe2\xc6\xbf\x2b\xe1\xcb\xe6\x61\xeb\x1a\x74\x64\xe2\x03\xed\x53\xb1\xb8\x80\x0f\x7d\xc7\x96\x4c\xa2\x04\xe9\xf0\x96\x65\x9a\xbf\xfd\x3d\x72\xe1\x64\xc2\x0c\x9d\x88\x71\x60\x0a\xfd\xdb\x64\xca\xda\x61\x5c\x04\x08\x47\xfa\xcf\x7f\xbe\x7f\x19\xc6\x8c\x92\x2b\x23\x72\xd1\x37\xd5\x3e\x4d\x31\x6a\x52\x86\x34\xb2\x9b\x36\x92\xd2\xe1\x57\x43\xd0\xf0\xf8\xa5\x48\x0a\xc2\xef\x70\x7d\x36\xa1\x68\x16\x23\x73\x43\x24\xc3\x2e\xac\x27\x2e\xa7\x6d\xdb\xbf\x5c\x84\xe3\x1f\x53\x3e\x48\xdb\xe2\x5c\x94\xea\xa1\x78\xf9\x25\xba\xb8\x19\x73\xb1\xb4\xd7\x08\x20\xb4\x7b\x7d\xf9\x02\xdf\x7b\xde\xe7\x59\x1c\x99\x54\x11\x41\xd5\xa5\x7b\xb3\xeb\x60\x61\x63\x3c\x42\x7b\x34\x36\xb4\xe0\xdc\xd4\x4e\x4f\xef\xb1\x7b\xd3\x3a\x08\xc0\x31\x1e\x40\xae\xee\x53\x5d\xcf\x99\x6a\xcd\x63\x88\x1c\x52\xc0\x76\xa1\x8c\x87\x28\x8f\xfa\x98\x88\x72\x1d\x30\x9f\x58\x2b\x37\x9a\x73\xa3\xf1\xcb\x0b\xac\xec\x56\xa9\x03\xe5\x29\x3f\x48\xb0\xe0\xb3\x6c\x5d\xab\xba\x0d\x1d\xa0\xc4\xb4\x42\xd6\x8d\x08\x8d\x0f\xf9\xb8\x7d\x3a\x2d\xbf\xfe\x69\x44\x53\xdd\xc1\x80\x26\x48\x56\x6f\xa0\x41\xd6\x5e\xcc\xfa\x32\x2a\x60\x21\xd2\x5c\xb5\xef\xe4\x50\x34\x65\xd7\xd8\xab\x42\x1d\x22\x3a\xa5\x32\x9d\x16\x16\xcb\xd4\x5a\x80\x47\x7e\x99\x3c\x38\x89\x3b\xbf\x64\xb5\xfa\x62\xd2\x83\x41\x38\x9a\xac\x8a\x68\xd3\xf8\x03\xe7\xb4\xee\xda\x92\x1d\x1f\x9b\x59\xeb\x13\x83\xa0\x68\x44\x31\x6d\x77\xb7\x59\x1c\xbf\xee\x37\xa7\xe3\x7e\xf1\x74\xb8\xdb\xec\x5d\x0e\x4f\x51\x69\x34\x5e\x2e\x4d\xfe\x56\xed\x7b\x91\x6e\x63\xa2\xdd\xa8\x38\x22\x58\x84\xb3\xa2\x8f\x8b\x07\xe7\xf0\x2b\x46\x24\x7e\xd3\xe3\x20\xc1\xf6\xf3\x3c\x9f\x62\xc2\x73\x3d\x5f\x3b\xa8\x17\x4d\x69\xfb\x34\xe9\x88\x53\x68\x38\x9b\x55\xe2\x7b\x52\x39\x11\x83\xfc\xad\xef\x74\xea\xaf\x9a\x68\x23\x34\x89\x29\x86\x0b\x94\x3d\xca\x5f\x71\x11\x59\xa9\xec\x73\x9a\x8f\xb3\x3b\x4a\x10\x85\xb1\x15\xbe\x18\x0b\x49\x6b\x67\xc4\xf6\xa9\x9d\x10\xdd\x28\xa6\x10\x82\x8a\xd4\x99\xc7\x02\x59\x7a\x66\x37\x1c\x25\x35\x0d\x4d\xb7\xc7\x03\xaf\xea\x3d\x97\x70\x97\xe6\x55\xfa\xda\x6d\x76\x0a\x42\x65\x14\x54\xfa\xda\xba\x09\x50\x33\x50\xdb\xd5\x62\x77\x83\x70\xb8\x55\xf5\x96\x9e\xd2\x71\xac\x3a\x0a\x0f\xfd\xc4\xa7\x16\x0b\x3c\x6a\xba\x9a\x3f\x5c\x93\x85\xf5\x14\x27\x0a\xfe\xff\x33\x39\x2b\x31\x6c\x28\xff\x3f\xd2\xde\x6c\xb9\x71\x1c\x5b\x17\x7e\x9d\xba\xe8\x0b\x02\x20\x09\xf2\x52\x96\xe5\x4c\x77\x7a\xda\x92\x32\xb3\xea\x74\x74\x28\x30\x2c\x58\x6c\x53\xa4\x36\x07\x0f\xf5\xf4\x7f\x70\x01\xe0\x24\x3a\xb3\xcf\x7f\x62\x47\xec\xec\x32\x41\x8a\x23\xb0\x86\x6f\x70\xac\x35\x8f\x97\xb8\x4c\x00\xdc\x78\xc2\x55\x6c\xd5\x53\x8a\x5d\x03\xe7\x3d\xd4\xcd\x68\xe1\x04\x92\x44\xc8\xe6\x7f\x7c\xd8\xec\x6f\xef\x37\xbb\xc7\xbb\xeb\xd9\x69\x92\x94\x91\x41\xba\xeb\xa6\xb2\x37\x64\x68\x7b\x2f\x4f\x91\x40\x80\x7a\xef\x83\x21\x5e\xe8\xc9\x58\x8b\x48\x5f\xa0\xd4\x20\xcd\xd6\x2a\x52\xda\xa5\x79\x2a\x0d\xa7\x02\x60\xc4\x59\xce\xbc\x8a\x46\x5c\x52\xa9\x47\x19\x3f\x30\x12\xa1\xe4\x81\xc3\x1e\xec\x5a\xf9\xeb\x17\x1f\x18\xe1\x46\xfa\x08\x73\x2c\xc6\xd8\x6d\x63\x14\x7b\x55\x67\x57\xe0\xb1\x91\xa1\x17\x80\xef\x06\x70\x49\xc6\x95\xec\xb1\x25\xfc\xe2\xe9\x45\xa9\xb5\x30\xcb\xf1\x3d\x6c\x5c\x30\xd0\xad\x6d\x37\x65\xe5\x95\x0c\xff\x18\x94\xe3\xba\x5d\x8c\x44\x74\x9c\x35\xde\xbd\xb0\x42\x77\xa3\x38\x31\xd8\x4c\x68\xca\x6f\xf0\x61\xc3\xfe\x85\x28\x0d\x38\x4b\xb0\x8f\x58\xb7\xa7\x93\xcb\x06\x7d\x54\x0b\x3c\x49\x95\xc2\x47\x31\x26\xa0\x4c\x20\x94\xc0\x53\xa6\xc6\x35\xc3\x41\xe1\x63\xe9\x83\x00\x9e\x0a\xe2\xe0\x00\x0b\x4a\x9e\x2a\x80\x44\x68\xcc\x87\xee\x3e\x74\x26\xc6\x18\x49\x48\x89\x4d\x21\x5e\xb2\x3c\x5f\xe5\xf9\x9f\xab\xdb\x3d\xca\x8f\x0c\x35\x59\x48\x89\x35\x7e\x36\x59\x91\xd5\xc7\xa7\x1f\x1b\x9b\x17\xcf\x1a\x7e\x90\x12\x2b\xb4\xf6\x65\xbb\x1e\x87\x22\x20\x82\x54\xdb\x98\xaa\x2f\x88\x80\x88\x18\x2e\xa8\xc2\xe5\x00\x36\xdf\x7e\x2a\xcb\xfc\xba\x1f\x12\x1b\x44\x66\x37\x50\x37\xec\x50\x83\xa8\xd4\xb1\xdf\xa6\x01\x63\xe6\x93\x78\x01\xcc\x0c\xfe\xcb\x28\x6f\x5e\xe9\x9c\xfd\xe7\xf2\xe7\x26\x29\xc3\x6a\xda\x92\x81\xdf\x24\x1e\x9c\xef\xa7\xac\xee\xde\x2e\x3b\x9d\x91\xb4\x66\x1d\xc0\x0a\xf0\xab\x30\x48\x2d\xc5\x80\x8e\x00\x8d\x46\xd6\xd6\x89\xe3\xd7\x45\x01\x50\x51\x24\x5c\xb3\xec\xa9\x7c\x81\xd3\xb2\x81\xaf\x0a\x40\xa7\x71\x3a\x48\xce\x5f\x09\xf5\x02\xc5\xfc\xe5\xd0\xdd\xe1\xac\x30\x90\x68\x32\xf1\x5a\x5f\x43\x81\xd6\x40\x6e\x3b\x04\x32\x11\x3e\x3c\xbf\xf1\x66\x27\xbf\xfa\xfc\x20\xe2\x78\x7a\x88\xb2\xb6\xea\x61\xfb\x45\xc5\xfc\x6e\x6c\x6c\x99\x12\x07\x6c\x31\x7c\x26\xeb\xaf\x02\x30\x82\xc4\xc4\x67\x00\x4e\x08\xd8\x5b\xe8\xba\xcf\x75\x5c\x59\x34\x81\xb2\x0e\xb0\xf6\xd2\xef\x9d\x7c\xc0\x42\xe5\xc2\x04\x90\x52\x97\xcf\xbb\x15\x92\x4d\x6f\x91\x21\x44\x10\x37\x7b\x75\x7f\xc5\xce\x17\xba\x97\x64\xc5\xa8\xf8\xf0\x8f\xd9\x4e\xb1\x11\x3d\x61\x6e\x41\x93\xf5\x97\xe9\x6a\xe2\x0f\xc2\xb5\x53\xd8\x83\xba\xee\xad\x64\x55\x60\x58\x4c\xe9\x70\x79\xdd\x24\xf7\x4b\x0d\xec\x6e\x0f\x21\x11\xf3\x78\x45\xaf\xba\x19\x60\x86\xdd\x33\x61\x40\x9c\x0b\x65\xdd\xc2\xcd\x20\xa7\x30\x3b\x4a\x98\xc6\x28\xee\x09\xe8\xc6\xd0\x58\xa1\xa0\x49\xfd\xce\x84\xd2\x60\x79\xaf\x90\x16\xde\x53\xf7\x1b\x34\x4d\x65\x6f\xff\x39\xb5\x5a\x9d\xfd\x8a\x09\x09\x8c\xd2\x4a\x53\x41\x7d\x44\xa5\xef\xd9\xb3\x8b\x78\x84\xa5\x14\x68\x8e\x87\x1a\x40\x1f\xc4\xb8\x7c\x6c\x22\x61\x6d\x21\xad\x3c\xe2\xfe\xd8\x63\xf4\xbd\x47\x5d\x37\x46\x46\x86\xfb\x08\x5e\x95\x85\xc6\x9a\x68\x17\xc4\x8f\x2c\x68\xfd\x58\xad\x52\x3e\x2d\x72\x7c\x2f\xac\x52\xaa\xff\xc9\x38\xb4\x52\x18\xa2\x69\x84\x3a\x62\x0d\x7a\x76\x90\x38\xe2\x6c\xd0\x41\x46\x99\x03\x91\xdb\x81\xe3\x55\xc4\xc4\x49\x12\xa5\x7d\xfe\x98\x9d\xda\xd3\x97\x4a\x28\xcf\xdf\xf2\x83\x04\x33\xa9\xcb\xcf\xab\x57\x40\x82\x78\x17\xee\xf4\xdb\xbb\x20\x70\xdc\x14\xec\xa2\xd4\x91\x8f\x66\x3f\x8c\x4b\x57\x95\xbc\x75\x9d\xdd\xf9\x6b\xb9\xb0\xd0\x19\x1e\x68\x44\x79\xdc\x3e\x7e\x9f\x24\xb0\x86\xab\x30\x1d\x5c\xfc\x0e\xe7\x5c\x14\xfd\xf2\x66\x12\x6a\x7d\xa3\xb5\x55\x4d\x7d\x34\xb3\x93\x49\x52\x4b\xc3\xd7\xa0\xbc\xa5\x78\xf7\x57\x6d\xd3\xba\xfa\x58\xb6\xb9\xde\x1f\xab\xf2\xed\xb1\x58\x35\x0d\x9c\xce\xcd\xbe\xf4\x41\xf8\xbe\x7c\x68\xf3\x89\x9f\xb2\x0a\x4c\x1a\x13\x14\x9b\x1a\x5b\x80\xab\xc0\xe8\x90\xc9\xd0\x85\x09\x08\x69\x98\x7d\xf6\x5a\x0a\x04\x2d\xfd\xb5\xbe\xba\x1d\xaf\x69\x06\x62\x95\x5a\x65\x1d\x6b\xee\x8f\x1a\xa5\x57\x60\xca\xcf\x3a\xbc\x06\xa4\x35\xcc\x35\x6d\xa1\xad\x41\x8d\x13\xe9\x40\xdd\xd9\x51\x59\xc0\x00\x00\xe6\x1b\x9b\xaa\x2a\xab\x69\x37\xcb\x18\x66\xeb\x74\xb7\x77\x37\x9e\x1d\x82\x5b\x48\x10\xa4\x06\x67\xa8\x06\x51\x0e\x58\x98\xb2\x96\x83\x93\x58\x8b\x04\x84\xc5\x23\x77\xc5\xc9\xdb\xb9\x88\xa9\x21\x01\x25\x01\x92\x4b\xaf\xaf\xae\x7f\x8c\x6e\x02\x09\x58\x4a\x31\x2a\x73\x51\xf5\xe6\xbd\x01\x74\x7b\x98\xee\x1e\xb2\x08\xc3\x9d\xee\x1e\x6f\xaa\xf6\xec\x8b\x0c\x56\x9d\xc9\x0d\x8a\x89\xed\x37\xd4\xc7\xb6\x39\xf4\x86\xce\x8a\x04\x9c\x52\x0c\xa2\xdb\x22\x53\x65\x55\x5c\x55\x00\xba\xa7\x9f\x91\x80\x47\x8c\x8e\xbd\x91\x2c\xcb\x69\x69\xe2\x22\x01\x4f\x63\x2c\xa4\x1f\xce\x50\x99\xb2\x3a\x0d\x2f\x4c\x97\x79\xfc\xcc\x9a\xe3\xd6\x26\xca\x97\xd2\x3e\x4b\x69\x08\x09\xb8\x10\xb1\x95\x75\xd5\xab\xba\x2e\x55\xd6\xe5\xa0\x9f\x80\x1b\x26\x73\xfc\x05\x64\x7b\x7e\xa6\xd2\x52\x2d\xd7\xfb\xf5\x55\x7f\xa5\x40\x10\x1b\x28\xb4\xf6\xea\xac\x8b\x27\x95\x50\x85\x5a\x12\x7f\x5d\x89\x42\x14\x62\x08\xf5\x48\x90\x08\x2d\x64\xef\xfc\x53\x0c\x7a\x01\xc3\x2f\x27\x3a\xc2\x77\x4f\x8f\x68\x27\x37\x18\xf6\xf9\x8f\x86\x04\x69\x62\xbb\xae\x8e\x6c\x7e\x93\x55\x75\xe3\x5d\x33\xba\xcd\x10\xd0\x1e\x82\xa5\x33\xe3\xff\x2e\x82\x04\x4b\x8c\x36\xbe\x59\x7b\x6d\x14\xbf\x59\xb2\x00\x6d\xa3\x6d\xf8\x3d\x43\xc4\xaf\x73\x91\x9d\xfa\x91\x29\xc3\x37\xb8\xb6\xf6\x22\xfd\x9f\x21\xc2\x3e\xf1\xb3\x38\x8f\xb1\xb2\xdd\x06\x83\xfe\x32\xeb\xb2\xd0\xc8\x6d\xab\xa7\x8a\xc2\xd3\x3b\x80\xcd\x0a\x4b\x54\x44\x1a\x99\x16\x1f\xd6\x7c\xb2\xfe\xc3\x2a\x58\x8f\xa6\x3f\x12\x28\x16\xe2\x9a\x89\x0c\x6d\xe4\x1e\xff\xf1\x89\x8f\xf0\xff\xe3\xbf\xfd\xef\x45\xa1\xab\x94\x6c\x26\xb0\x22\xbf\x1d\xa8\x0c\xa6\xfc\x21\x63\x7c\xd6\xbf\x7c\x48\xdd\x45\x37\xf8\xc8\xb5\x7d\x2b\xd6\x65\xde\xed\x59\x5d\xfa\x8c\xcd\xf7\xd4\xa1\x77\x2b\x77\xdd\xc3\x7e\x65\x9d\xbd\x94\x10\x19\x6c\x00\x7f\x81\xd3\xf8\x85\x04\xae\xb1\xa3\x27\xad\x95\x42\xd6\x0c\x2f\x19\xa4\x52\x04\xa3\x09\x16\x09\x4b\x5b\x2c\x40\x82\x9e\x65\x65\x24\x00\x49\x30\xdd\x3b\xf8\x79\xa0\x3f\x8c\xb1\xd6\x47\xaa\x3c\x9d\x45\x05\xfe\x49\xba\xad\x86\x08\x9b\x77\x56\xe5\xfb\x44\xf3\xb8\xdb\x16\x05\xb8\xed\x5b\xab\xcb\x1a\x5d\x88\x17\xc0\xa7\xbf\x79\x5a\x46\xc4\x88\x95\x54\x36\xec\x7f\xf2\x3e\x59\x85\xd3\x91\x6d\x07\xf6\x74\x37\x98\x27\x53\x9b\xb7\xfa\x47\xd9\x7c\x42\xad\x21\x81\x91\x96\x0e\x59\xc1\xf5\x70\xbd\x24\x10\x06\xc5\x82\x7e\xf9\xc8\x49\x00\x31\xde\xdc\xaf\x20\xf2\xe6\x38\x7a\x22\x84\xb0\x18\x5b\x1b\xaf\x16\x0e\xe1\x8a\x62\x4b\x68\x65\x42\x68\x48\x30\x44\x3b\xa8\x5c\x54\x99\xf9\x78\xfa\xf1\x34\xe5\x1a\x10\x42\xe3\x80\x8c\xd5\x7a\xee\x32\x39\x64\xb2\x4b\xc5\x58\x42\x28\x37\x88\x8c\x77\x8b\x0a\xd2\x44\x7e\x95\x0b\x11\x42\x45\x80\x50\x09\xdf\xab\xb7\x6f\xf1\x83\x97\x65\xee\x46\x68\x63\x45\xee\x70\x4b\x6f\x88\x36\x84\xd9\x84\xb0\x80\xe8\xd0\x4b\x11\x0f\xbc\x16\xab\x06\x86\x00\xbc\x7b\xf1\x3e\xbb\x01\x4c\x13\x14\xc8\xfa\x73\xb3\xfe\xcc\x49\x3c\x99\x9d\x6b\x18\x30\xa4\x7c\x9f\xc4\xfb\x5d\x86\xb7\xd8\x46\x9c\xfe\x95\x24\x21\xb3\x77\x2c\x53\xe5\x53\x2e\x9a\x6e\x9d\xf2\xfd\xd4\xe9\x54\x4d\x22\x19\xa0\x86\xe7\xfa\xaf\x9b\xf1\xaa\x4c\xe2\x30\xea\xdd\x82\x0e\xcd\xb1\x02\x8f\xb2\x5a\x21\x15\xe9\x46\xe4\x75\x7f\x63\xe2\x88\xa3\xad\xdc\xe1\x60\xb3\x88\x83\x17\xe3\x9c\x5d\x69\x1c\xf1\x84\x4c\xa3\xde\xc7\xa2\xe7\xba\x11\xc2\x19\x57\xdc\x9b\x99\x54\x75\x83\xee\x34\xb3\x63\xf0\x90\xa0\x8e\x5b\xdd\xca\x53\xd6\x6c\xe1\x35\x83\xb7\x21\xf2\xf0\xcd\x20\x42\xb8\xb2\xaf\xf0\xfe\xad\xbc\xce\x4e\x50\xd4\x03\xba\x86\x90\x24\xf0\x6a\x6d\xcd\x4d\x5e\xf6\x73\x3c\x49\x42\xcb\x0c\x51\x6e\x06\xfb\xbf\xf0\xc8\xee\xf6\x16\xa9\xf6\x6d\xd4\xac\x56\xb6\x24\x31\xbb\xdd\x29\xb1\x2d\x00\x2b\xf9\xf0\x68\x36\xef\xea\x78\x5b\x6c\xea\x2e\xad\x7f\x10\xf5\x55\x29\x97\x3f\x54\x92\xea\xc0\x7a\x99\x58\x12\xa4\x6f\x9f\x2c\x0f\x16\xa1\x44\xac\xfd\x63\x95\x3d\x0f\x5f\xa5\xa4\x14\x6d\xd3\xe1\x7f\xdb\xec\x3c\x4d\xdb\x08\x91\x3a\x8c\x3c\x70\xfe\xd1\xdc\x89\xba\xf9\x2a\xf2\xd7\x21\x46\x22\xd2\x84\x88\x53\xfc\x44\x58\xeb\x42\x0c\x37\xf9\xd7\xbf\x07\x1b\xef\xa9\xa1\x37\x1e\x2d\x41\x69\xe3\xf5\xdd\x9f\xbf\x6b\x56\x12\xa2\x02\xa5\x5c\xca\xee\x1a\xf0\x96\xe1\xed\x36\xeb\x54\xa7\x4e\x45\xd4\x7a\x6f\xd9\xe4\xb8\xdf\xac\xc1\x9b\xed\xdc\x8b\xa2\x35\x02\x11\x94\xf3\xf7\x0a\x88\xf1\xb2\x30\xf7\xfd\x8b\x0d\x46\x69\x27\x63\x63\x83\xed\xbe\xec\xd7\x8c\xf8\xb6\x84\x98\xd0\x62\x38\xb1\xff\xf1\xb0\xd9\x8f\x49\xde\x84\x18\x49\x10\x06\xda\x54\x6d\xdd\x40\xef\x02\x33\x6d\x4d\x12\x1a\x84\x4a\x38\xb9\xed\x41\x0c\xe7\x5f\x84\xf4\xab\xe0\xbf\x42\x7f\x67\xe9\x70\x43\x1d\xf8\x80\xd0\x80\xc7\x58\x76\xb6\x5c\x83\x2f\x55\xd9\x9e\x1f\x46\xba\x22\x84\x06\x9a\x60\x3a\x5d\xb6\xdd\x84\xe1\xf2\xbc\x69\x58\x4f\x89\xb4\x05\x4f\xa7\x82\x61\x7f\xb7\xbb\x6b\x83\xf2\xb9\x1b\x49\x79\x84\x37\x1d\xd3\xfc\xaa\xe7\x17\x83\x1e\x81\xad\x09\x65\x94\x21\x98\xe3\x59\x9c\x60\x9d\x97\x05\xc6\x8a\x7e\x5b\x62\x9b\xc5\xf2\xf4\xf1\x5b\x44\x25\xa1\x4c\xd8\x84\x43\x96\x65\xdd\xe0\xa1\x2c\xb5\x74\x76\x13\x43\x66\x7d\xf1\x84\x2d\xbe\x3b\x6e\xc5\xf4\xd4\xc3\xd8\x99\x9e\x67\x27\x8b\x91\x16\xcd\xf1\x4d\x7c\x20\xae\xb9\xa7\x78\xfb\x15\x9c\x86\x40\xa1\x77\x75\xba\x82\xc6\x9a\x6f\x8c\x26\x7d\x1a\x71\x29\xb4\xf7\x6c\x10\x75\x9d\x15\xcf\x2b\xff\x90\xfd\x51\xa2\xc4\xd8\xde\xf4\xfb\x85\xf6\xbb\x22\x34\x66\x36\x05\xea\xe3\xad\x47\x89\x42\xeb\xfa\x9f\x8f\x7f\xcd\x2e\x30\x8e\xad\xcb\xec\xb9\x7c\xa3\x57\x08\xee\xfe\x63\xba\x3d\xa5\xba\xd7\xc9\xc7\x97\x76\x79\x8e\xa0\x9c\xa4\xc2\x51\x8a\xb0\xd1\x78\x0d\xe7\x2e\xef\x2a\x96\x4c\x75\x86\x79\x95\x72\x16\x63\xf5\xc7\x58\x06\xb7\xad\x5a\x0c\x12\x51\xdd\x00\x1b\x72\xe5\xd9\x0b\xac\x21\x07\x59\x65\x23\x6d\xc8\xd9\x39\x88\x5e\x6a\xbf\x07\xf3\x7e\xed\x8b\x53\x84\x72\x45\x71\x1e\x13\x5a\x3b\x9f\xe5\x69\xc9\xd5\x0f\x03\xc0\xca\xf2\x0e\xab\xbb\xdf\xeb\x81\x0a\xbb\x50\x55\x27\x34\x51\xa9\x0b\x23\x9b\xab\x36\xcb\xbb\xcb\x58\xea\x04\xb8\xd1\x29\x55\x28\x57\xd4\x25\x9e\x1e\x49\x44\x68\x1a\x52\x6a\x79\xa2\x1f\xa5\x99\xc5\x91\x34\x8d\x42\xe7\xdc\x86\x6d\xda\xfb\xac\x18\xb4\x4e\x08\x4d\x13\x8a\x4b\xc0\xa1\x86\xc6\x09\xc8\x65\x8d\x6d\x02\x50\x32\x7b\xda\x22\x30\xae\xe8\xdd\x7d\x8f\x5b\x78\x85\xaa\xb6\x8a\xb8\x53\xa8\x12\xa1\x02\x22\xec\x1f\x5b\xca\xca\x6d\xe1\xf3\xa9\x71\x95\x87\x50\x61\x08\x62\xcc\x4c\x76\xae\x3d\x61\xf0\x8f\xcb\xd2\x2b\xa1\x92\x46\x58\x2f\x14\xd8\xc3\xdc\xb5\xf2\xaa\x2a\x5f\x46\x63\xa7\x17\xac\x68\x40\xdd\x3c\xf9\xa5\x12\x67\xa8\x77\x59\xa1\xc0\x2e\x22\xd5\xeb\x48\x42\xb0\x1f\x0f\x88\x74\x10\xb2\xc6\x45\xa8\x17\xdf\x20\x54\x31\x82\x0b\x03\xb6\xdb\xf2\x1c\x99\xd8\xfd\x74\xa2\xb9\x35\x6a\xb1\x35\x8d\x76\x10\x80\x25\x54\xa7\x1c\x17\xdf\x6b\x78\xfd\x92\xbd\x02\x62\x54\xc6\x12\xdf\x84\x6a\x50\xf8\xd9\x1f\x0c\x34\xea\x68\x81\x47\x37\x65\x75\x0f\xdd\xab\x72\xf1\x49\x02\x8f\xad\x39\xfa\x73\x05\x28\x0d\x89\xc0\x1a\x7f\x2c\x90\x04\x21\xe8\x8e\x44\x82\x2c\xbb\x21\x2c\x1f\x8c\x0b\x97\x5f\x29\xd0\x1a\xe5\x86\x37\xdf\xb7\xb6\xf7\xe3\xfe\x6e\xc2\x04\x97\x91\xd5\xc0\x4e\x86\xea\xc2\xb4\xe6\x1f\x8b\xb2\x87\xfe\x10\x42\xe1\xa4\x5a\x16\xf0\xb5\x2d\x74\x05\x7a\x7f\x2c\xdb\x5a\xf4\x09\x2e\x0b\x68\x6c\x73\x3b\x8b\x60\xb4\xf1\xf1\x7a\xd6\x4c\x27\x2c\x88\x2c\x60\xf6\x19\x9a\x35\xe4\xf9\x08\xa2\x45\x58\x90\x0a\x70\xe1\x13\xca\x13\x97\xd5\x6c\x67\x12\xa4\xd8\x27\xb2\xd5\xa1\x07\x78\x73\xb0\xb2\x45\x2d\x7e\xc2\x88\x50\x58\x52\xe9\x3e\x48\xa8\xbd\xbf\x4e\xaf\xfa\xef\x46\x51\x42\x7c\x77\x0a\xd5\xe9\x2c\xde\xed\xbf\x4a\x78\x19\x95\x0a\x09\xc6\xae\xcf\xf8\xb9\xe2\x0d\x61\x54\x6b\x34\x37\x11\x6d\x73\x2c\xab\xec\x6f\xd0\x16\xed\xee\x35\xca\x9e\xaa\xec\x55\x5c\xc2\x2a\xdc\xde\x8c\x48\xe5\xa4\x3b\xaf\xbc\x29\xd1\xee\x3c\x61\x33\xf8\x91\xcc\xe2\xdc\x6a\x68\xfc\x6c\xe5\xcc\xd5\x4f\xbd\xde\x5f\xb2\x14\x5d\xb9\xfd\x43\x69\x6b\x87\x47\xc8\xfd\x2a\xc3\x22\xc2\x61\xb8\xef\x33\x78\xc8\xf8\xfb\x66\x91\xa0\x3a\xf1\x6e\x4e\xea\xe5\x19\x75\x6b\x2f\xf1\x87\x84\x45\x2a\xc0\x17\xea\xf9\x6f\x78\x82\xaa\x17\xb7\x27\x8c\x87\xb6\x64\x8b\x21\xd7\xf7\xdd\x35\x2e\x22\x93\x92\x09\x4b\x48\x1a\xb9\x2c\xc4\xe6\x3e\x59\x31\x54\x78\x58\x42\x00\xd3\xa9\xeb\xb6\x51\x47\xaf\xfc\x76\x09\xb3\x26\x2c\x89\xed\x0a\x8c\x78\x53\x51\xe9\xad\x68\x46\x15\xf5\x7f\x8c\xdf\x91\x34\xa1\xd0\x73\x3b\x46\xbf\x95\xa6\x14\x2b\xb4\xf7\xd0\x08\x9d\xb5\xbe\x08\xc4\x04\xb1\x7e\x29\xd6\x81\x1b\xed\x61\xb1\x06\x31\xa9\x97\x12\x26\x64\x80\x15\x86\x9f\x8f\x77\x37\x61\xbf\xaf\x11\x38\x07\x94\xf2\x3f\xa0\x9a\xc3\xb2\x56\x00\x61\x92\x52\x30\x23\xe3\xa8\x91\xdb\xe8\x4a\x5e\xa6\x16\xb3\x9d\x5d\x46\xe4\xbc\x5c\x6b\x5c\x01\x1a\xd0\x4e\x96\x71\x0b\x42\x0d\x25\x35\x26\x59\x92\xba\x06\x14\x8a\xbf\xce\x8e\xc5\xa9\x48\xc6\xa0\xb4\xeb\xa7\xd9\x08\x15\x27\x38\xe9\x1f\x84\xd6\x5e\x49\xee\x93\xf7\x5c\x09\xc6\xc3\xa1\x2b\xd9\xd7\x9d\x09\x03\x9a\x20\x1c\xec\x24\xde\xf7\x55\x26\xf2\xeb\xaa\x3c\xfb\x09\x9c\x99\x50\x60\x8f\x04\xd5\x24\x26\x87\x26\xd4\x3f\x43\x23\x03\x2c\x1e\xc8\x0a\x40\x3f\x16\x63\x9d\x70\x1f\x8b\x4c\x02\x93\xa5\x94\x21\x0c\x62\x86\x46\xc6\xa2\xd5\xd9\xec\x69\x86\x41\xa2\x7c\xf6\xd7\xad\xfb\xdd\xe4\xbe\x24\x25\x40\x42\x02\x31\x0e\xdc\x6c\xd7\x9c\x12\xe7\x35\x5b\xa1\x06\x80\x33\xf0\x1a\x02\xa3\x90\x80\xc6\x3b\xd2\xc7\x70\x08\x48\x5d\xc0\xad\x93\x90\x86\x09\xba\x46\xe6\x95\xda\xf5\x38\x1a\x12\xd2\x54\xe1\x04\x87\xa0\xe4\x5d\x23\xaa\x71\x42\x1e\x32\xc1\x10\xae\x31\x7d\x89\x7e\x07\x15\xea\xf6\x93\x56\x0b\x68\xd0\x3d\x2d\xcf\xfd\x41\x0d\x0f\xc8\xc4\x3b\xf5\xa6\x2d\x34\xce\xf5\xd3\xa3\x84\x01\x41\x44\x23\xb2\xbf\xad\x1e\x8f\x3f\x46\x48\x88\xf7\x3a\xc1\x29\xef\x26\x17\xcf\x9e\xf9\xb8\x38\x1b\x87\x21\x67\xa1\x57\x07\x3d\xe7\xa5\xd0\xfb\x8f\xf3\x0c\xa9\x49\xc2\x30\xa1\x49\x38\x88\x51\x7e\x52\x68\x0d\x43\x11\xa1\xe2\xe3\xea\xfa\x7a\x7b\xf8\x79\xbb\xff\x7a\xbd\x5d\xfd\x5c\xdd\xd1\x3f\x86\xed\xa8\xa3\x7b\xf5\xd1\x40\x0e\x56\xae\xf5\x17\xb9\x66\x18\x6a\x8e\xf1\xb3\x6c\x3f\xee\xbd\x80\xbe\x7b\x33\xc3\x98\x59\x67\x65\x2c\xe6\x59\xc2\xcc\x02\x0c\x68\x1a\x1b\x85\x71\x12\x21\xd8\xf9\x24\xb2\xe2\x6d\x84\xce\x20\x61\x0c\x12\xc1\x95\xdf\x1f\x1e\x9f\x36\x0f\x9f\xa8\x19\x5f\x86\xe0\x61\x12\xd8\x68\xcb\x32\x4d\x6d\x04\x3e\x5e\xc2\xc2\x04\x28\xc6\x2e\x37\xeb\x4f\x2b\x4a\x9f\x1c\x3a\x8d\x12\xec\x73\x3e\x67\xaf\xf0\x7d\x99\xde\x4d\xc2\x34\x25\xd8\xc9\x39\xb4\x85\xaa\x40\x4f\x25\xff\x66\x8f\x47\x50\x5b\x56\x90\x22\xbf\x16\x59\xfe\x71\x57\x36\x8d\x8f\x23\x42\xc1\x24\x0a\x9e\x9e\xb2\xa2\xf1\xf3\xcd\xe7\x6a\xa3\x7e\xa7\x38\xc0\xda\xf5\xb9\x7b\x07\x67\x55\x8c\x50\xa4\x0c\x0b\xb5\x16\x1b\x3d\xfe\x4a\x76\x1e\xd7\xd8\x0d\x32\x41\x34\x16\x56\xff\xdd\x2f\x4a\x8e\xf8\x8a\xa7\xee\x62\x55\xb3\x3f\xc2\x4d\xdb\x65\x2a\x6b\x31\xf6\xf2\x19\xaf\x43\xa1\x14\x46\x7a\x85\x52\xbf\xba\x8f\x92\xa4\x50\x1a\x8b\xdc\x3f\x8a\x7a\x95\x57\x20\xf4\x47\xf7\x61\x2d\x7a\x51\x29\x12\x2a\xa2\x30\x2e\x74\x7a\xdc\x53\x48\xb2\x1f\x13\x45\x38\xfd\x7c\x29\xf3\x4b\x35\xea\xe5\xa3\x72\x89\x11\x9e\xeb\x63\x6d\x41\x68\xe2\xcf\x4f\x53\xdb\x1c\xc9\xc6\xd4\xf9\x69\x7d\x67\x8a\x99\x9d\xbd\x47\x9a\x09\xe4\x21\x3b\x17\xc8\xf6\xec\xbc\x1d\x2f\x50\xdb\x24\x84\x28\x50\x8e\x8f\xf3\xc3\x59\x37\xcd\x42\xa5\x10\x62\x82\xbc\xb0\xf2\x15\x2a\x5d\x09\x63\x39\x24\x7f\xf4\x5b\x95\x1e\x02\xda\x45\x17\xc0\x6e\x14\x17\xcc\x78\x1d\xc1\x32\xc7\xe6\x60\x3b\x98\x89\xf6\x8b\x03\xa4\xd6\x31\xd6\xd6\x17\x31\x8d\xf8\x0a\x02\xd1\xea\x43\xf8\x14\x82\x16\x88\x1c\x6a\x40\x9c\x86\xda\x87\x3f\x23\x13\x52\xe4\xf5\x9f\xee\x4a\xa1\x57\x85\x76\x6c\xdb\xe9\x2a\x64\xa4\x46\xff\xbf\x5a\x34\x65\x7d\xcc\xee\xcb\x3e\x4b\x8b\x48\x12\x79\xd7\xd9\x55\xb7\x7e\x5d\x02\x81\x49\x44\x84\x45\xdb\x38\xb5\xce\xfb\xf2\x35\x83\xb9\x32\xc4\x6c\x0f\x15\x09\x3d\x24\xdb\x50\xed\x51\xe0\xc4\x6d\xa5\x69\x28\xfa\xd0\xf1\x8b\x38\x4d\x5c\x53\x26\x67\x1e\x51\xcd\xc0\x35\x00\xbf\xfd\xb5\xde\x83\x38\x4d\x9f\x57\xc4\x08\xa8\x41\xae\xe7\x16\x2b\x44\x0b\x8f\x3e\x8a\x88\x41\x0a\xd3\xff\xb4\x42\xaf\xcb\x0a\x70\xe1\xf3\x27\x14\x85\xae\xc3\xec\xaa\xed\x98\x40\x94\xd5\x25\xf0\x86\x44\x51\x62\x9d\x06\xef\xda\xf5\xc7\x14\xfa\xb3\x50\x4f\x9a\x4c\xf7\x51\xa4\x0c\xa6\x8d\x87\x73\x05\x5e\xb0\x66\xd9\xb5\xc3\xed\x10\x07\x56\xfd\xe3\x28\x2a\xbd\x16\xe7\xdb\xc2\x7b\x83\x77\xdb\x68\x14\x72\x1f\x7d\xf6\x5e\xa6\xdd\x06\x30\x48\xa5\x75\x0f\xeb\x49\xb8\x8a\xc0\x7f\x81\x45\x5f\x9e\x93\x22\x2e\x13\xc7\x75\x40\x2f\x4d\x1b\xba\x3f\x9a\x5e\x4b\xd9\xff\x32\xd7\x1c\xd7\x8a\xac\x81\xd3\xa2\x57\xe9\xe8\xad\x8e\xd2\xd8\x3a\xa9\x0b\xad\xbd\x59\xe3\xac\xdf\x3c\x3c\xbb\x34\x31\x48\x74\x2b\xe0\xed\xa7\x70\x86\xc3\x3e\x19\x8f\xd2\xd4\x4a\x37\xaa\x9e\x62\xb6\x15\x0d\x3c\x1a\x2b\x2f\x39\xbd\x92\x34\x95\xc8\x6a\xf9\xd3\x9f\xb2\x88\xb9\x8d\xab\x0b\xd8\x1d\x4b\x1b\x34\x6f\xd1\x93\x20\xbb\xa0\x1c\x91\x48\x00\xc3\x7a\xd4\xa1\x3e\x8a\x0a\xd0\x28\x67\x40\x46\xcd\xa6\xd3\x4f\xee\xa5\x00\x15\x86\xfe\x5e\x7e\x11\xf5\xf7\x26\xcb\xb3\xbf\x87\x8a\x4d\xa4\x02\xab\xf1\x8c\xe0\xe7\x43\x0d\xcd\x01\x5c\xba\x72\xa8\x2e\x2f\x48\x07\x92\x38\x58\xf1\x5d\x29\x0a\xe7\xd9\x3c\xdc\x39\x4d\x22\x8c\x2a\x0f\x59\x8d\x13\x5e\x5f\xf9\x5a\xa1\x4e\xb6\xb8\x14\x14\x1a\x3d\x22\xcd\xa5\x72\xb9\x10\x6a\xc3\x7b\x4d\x60\xcf\xe4\x9b\x9e\x0a\x84\x5c\x85\xe3\x86\xca\x98\x89\x38\x5d\x0e\x22\x88\x09\x76\xce\x57\x2e\xef\x1d\x41\xb1\x48\x64\x82\xc8\xc8\x51\xd1\x00\x85\x45\x57\x95\xcc\x9a\x0a\x1d\xe8\xa6\x87\x32\x31\x41\xa4\x9f\xb7\x19\xf7\xd8\xc2\xe9\xc9\x99\x38\x41\x1d\xb7\x2d\x34\x59\xd5\x27\x31\x91\x49\x08\x72\x40\x0f\xd9\xe9\x5c\x56\xcd\x21\xab\x73\x51\x5c\xd8\x8d\xfd\x8b\x0d\x19\x31\x1f\xfe\x67\xf2\xef\xfe\x28\x9c\x3b\xcc\x53\xf7\x69\xbf\x66\x65\x5b\x1f\xba\x8f\xe0\xd0\x3d\xc1\xee\x35\x3c\x98\xaa\x3c\xe1\x9f\xe6\x5a\x82\xf6\x10\x31\x09\x53\xec\x56\x39\x62\x29\xdc\x2d\x46\x27\x7e\x70\x94\x86\x4e\x00\x78\x65\x4c\x96\x67\x23\x51\xd5\xe9\xdd\x89\x49\xa4\x30\x20\xbc\xde\xdc\x6c\x1f\x77\xfb\xc3\xd3\x66\x7b\xfb\xe8\xe7\x90\x98\xe8\x08\xf5\x3e\xb0\x7d\x2e\xa7\x9e\xe5\x8a\xc4\x54\x0a\x0c\x70\x6c\x24\xd9\xd7\x23\x63\x2a\x55\x60\x0d\xb8\x40\x54\x7d\xf1\x79\xfa\xc3\x4c\x4a\xac\xf8\xa2\x47\x75\x7d\x5c\xaa\x8d\xc6\x0c\x34\x26\x68\x8e\x9f\x6d\x93\xe1\xa5\x4a\x53\xdc\xe5\x69\xe0\x08\xf5\x1a\x25\xd9\x66\xe9\x53\x1c\x06\x29\xa6\x93\xdb\xcd\x7e\x75\xfb\xb0\xb9\x3e\x8c\x65\x76\x49\x1c\x33\x82\x42\x2c\xa6\x02\x70\x9e\x7c\xd3\x2e\x66\x1c\xab\x30\x4a\x06\x17\x01\x2f\x3e\x70\x59\x40\x8f\x63\x00\x86\xab\xf6\x1b\xc0\x79\x62\x76\x47\x62\x1e\xd0\x88\x3b\x05\x21\xe8\x3d\x36\x77\xde\xbb\xef\x93\x89\x3e\xe6\xa1\xc4\x80\xca\x4a\x2f\x76\xd1\xd1\xc7\xde\xb9\x0c\xcd\x06\x6a\xe2\x89\x15\xab\x57\x91\xe5\x2e\xe2\xe9\x41\x6c\x24\x4e\x42\xab\x57\x7f\xb2\xac\xda\xfd\xa5\x56\x48\x37\x26\xc5\xcf\xcf\x92\xd7\xd6\xfd\xae\xdc\x8a\x74\x0d\xe2\x8d\xf3\xb5\x62\x76\x18\x08\xbc\x8f\xc5\xba\xad\x9b\xf2\x04\xd5\x53\x05\xa7\x6c\x50\x11\x74\x03\x53\x62\x94\x83\x9c\x1c\x10\x38\x31\xdf\x1e\x4a\xec\x64\xfb\x78\xca\x39\x93\xcf\x71\x29\x9f\xa4\x14\xb3\xea\x74\x9c\x46\xa9\xa4\x36\x65\x38\x0b\xf5\xe2\x38\x1d\x59\x3d\x51\x90\xf4\x63\x53\x81\xe9\x05\x8a\x06\x4e\xca\xd7\x71\x9a\x4a\x2f\x1a\xed\xe7\x20\xf7\xac\xa7\x77\x21\x05\xe5\x5b\x7e\x57\xed\xdf\x7f\xaf\x85\x99\xb5\xa2\x63\xa1\x02\x04\x5d\xad\xef\xfd\xb1\x05\x30\x8c\x43\x0f\xce\x15\x73\x92\x5a\x4f\xcf\x50\x86\x11\xbe\xb9\xd6\x52\x7e\xc8\x33\x7e\x9d\x89\xc7\x32\xb5\x35\x93\x0a\x9e\xdb\x5c\x54\x1b\xa7\x72\x36\x1e\xec\x30\x5c\x76\xd5\x1f\x7c\xee\xff\xf1\xcb\x67\x2e\x95\xc0\xef\xec\xfe\xf6\xe1\xb0\xfa\x7e\x7d\xbb\x3f\xec\x6f\xef\x37\xfe\xba\x50\x10\xce\x26\x59\x59\xf1\xfc\x58\xc0\x0e\x72\x8f\xa6\x8a\x35\x61\xf8\x7a\xdd\xee\x0e\xeb\x87\xeb\xc3\xfa\xf1\x01\x45\xa5\x0f\xf7\xab\x2f\xb7\xeb\xc3\xc3\xf7\xfb\x2b\xcf\xe7\x22\xb1\x66\x2c\x0c\x7b\x72\x7e\x76\x6a\x4f\x58\xfc\x5d\x08\x4e\x63\x1d\x11\x2c\xab\xb9\x78\x67\x0d\x45\xd3\x56\x73\x49\x38\x12\x43\x14\x60\x69\xcc\x5b\xb6\x8e\x43\xec\xd8\x84\x7d\x4f\x61\x73\xce\xea\x52\x43\x3f\x2f\x18\x48\x03\x2f\x38\xb5\x24\x26\x43\x78\xc0\x8d\x55\x0d\xef\x66\xfa\x1d\x8a\xd2\x4d\x9c\xe6\x08\x0f\x8c\x15\xce\x92\xce\xb6\x3b\x0c\xdc\x06\xc2\x43\x2e\x67\x0e\x2c\xf7\xf3\x3e\x23\x27\xdc\xa0\x4d\xd6\xd5\x9a\x8e\xe7\x67\x4e\x94\x11\x0e\xcc\x74\x85\x09\x4d\x0b\x57\x1f\x5f\xc4\x49\xe6\x63\x13\xe4\xc4\x8f\x36\x32\xb5\x2c\x45\x03\x55\x05\xd5\x1d\xbc\x42\x4e\x26\xf4\x2a\xc2\x69\x90\x44\x30\xe6\x09\x8f\x57\x66\x4e\x13\xa2\x83\x5e\x48\x0d\x9b\x10\xe2\x53\xa8\xcb\xf4\x85\xe4\x54\x08\x88\x3c\x58\xd7\x29\x39\xcf\xef\x24\x35\xa9\x4a\x07\xaf\xd8\x0b\x1f\xec\x79\x88\x35\x59\x43\x39\x63\x1c\xa9\xd7\x7d\x31\xfd\x13\xdc\xc2\xec\xc4\x18\x33\x71\x32\x02\x1b\x8f\xf1\xcc\x84\xb3\xc8\x16\x08\x6d\x53\x6c\x5d\x16\x05\xa8\x45\x20\xfc\xec\x5c\x62\x8a\x00\xbe\xc6\xd9\xff\xed\x9e\x76\xbd\x01\x20\xe1\x2c\x95\x18\x50\xdf\x16\xa6\x12\x8f\xe6\xc2\x3e\x5c\x75\xef\x45\x94\x78\x2a\x09\x2e\x8c\xbe\xc8\xc4\x23\x92\x06\x16\xed\xa7\x5e\xae\x2a\x10\x2f\xfd\x86\xd8\xca\x7b\xd5\x50\x68\xab\xbf\xb5\x38\x35\xf0\x28\x31\x58\xb7\x7e\x85\xba\xa1\xa7\xbc\x27\x26\x2c\xab\x5b\x11\x1e\xc7\x56\xda\x43\x68\x8d\x12\x0c\x37\x65\xe5\x79\x66\x5f\x9d\xd6\xe0\xa7\x9d\x03\x1e\x4b\x6b\x30\x62\xc1\xec\xf8\xfd\xde\xea\xd7\x69\x7a\xca\x63\x1d\xa2\x1c\xd6\x83\x78\xfd\x92\x97\x52\xe4\xfb\xb2\x1d\x11\xba\x09\x8f\x21\xc6\x76\xda\x59\x7c\x94\xed\x42\xd3\x78\xf8\x39\xe0\xac\x7b\x5c\xe7\x97\xfe\x95\xe6\x8a\x06\x38\xfb\xe6\xd9\xe4\xeb\xe1\x90\xa0\xc0\xc9\xcf\xcd\x66\xdf\x4c\x36\x18\x4a\x6d\xdf\xb2\xd0\x4e\x06\x11\xab\x2f\x7a\xfa\x66\x24\xa1\x40\xd7\xd9\x5a\x18\x78\x81\x8f\xd9\xab\x9c\xc4\x02\x17\xa1\xf3\xdc\x4b\x67\x1e\xfa\xf1\x44\x50\x5c\xfc\xbc\xf0\xce\xac\xcc\xc4\x13\x63\x43\x38\x5f\xd3\x1f\xdb\xfe\x4c\xe2\x29\x9e\x06\x16\x91\x7c\x40\x52\x88\xd5\xcb\xa0\xb3\xf3\x4a\x89\xb5\x07\x70\xd0\x9e\x9f\x33\x79\xf3\x4f\xbe\x91\x34\xa2\x08\x6e\xb7\x00\xee\x69\xcc\xc3\x45\x90\x22\x43\xe2\x6c\xdb\x7b\xf8\xb3\x36\x7e\x18\x21\x35\xfa\xc1\x49\xea\xf0\x29\x4e\x59\xea\xfb\xfe\x11\xef\x3e\x99\x77\x99\xb9\x8c\x44\x6a\x29\xea\xa5\xc9\x9a\xde\xae\xc7\x6f\x4d\x39\x7a\x0f\xe4\xe5\x33\xb5\xb8\xaa\xc9\x19\xab\x20\x8c\x7a\x4b\xf4\xf5\xe6\xd1\xef\xa6\x98\x85\xdc\xa2\x30\x40\x5b\x39\x92\xf5\xf4\x6a\x95\xb2\xf6\xff\x1e\xd6\xe8\xd9\x12\x93\x6c\x97\xeb\x84\xd3\xa0\xc7\x6a\x88\xe2\x65\x11\xdc\xcc\x35\xb0\xd0\x52\x54\x76\x8d\xa8\x26\x4c\xd8\xd9\x48\xa0\x42\x10\xa7\x99\x36\xcf\xad\x39\xc4\x09\xe1\xee\xe3\xde\x8d\x42\x8c\xd9\x83\x82\x94\x3a\x46\xa0\xef\xbc\x20\xd2\xc4\x77\x07\x67\x93\x0c\x68\x8e\x9a\x50\x3e\x77\xda\x65\x79\x6f\x98\x4c\xb8\xa1\x0c\xdc\xc4\x88\xec\x12\x6f\xe0\xde\x2d\x47\x89\x97\xf2\xc5\x89\xe6\x06\xe0\x7e\xa6\x61\x4e\xb8\x31\x42\xd9\x53\x71\x0d\xe6\xb2\x70\x56\x9f\xcb\x95\xfa\x24\x00\xbb\xba\x7c\x59\x3f\x8d\x3f\xd4\x84\x10\x8e\x60\xc9\x9b\x0a\xe0\xef\x5e\x43\xb9\xdf\x4a\x2d\xcf\xb2\x82\xb2\x7a\x16\x45\xf6\xb7\x13\xfe\xf1\xdb\x69\xac\x79\xe2\x72\x1c\xe8\xbf\xaa\x84\xa6\xb6\xb4\xd2\xcd\xaf\x37\x22\xcb\xf7\x65\x79\x03\x6f\x6b\x2b\xe2\x39\xec\x6c\x22\xa4\xa0\x7e\x81\xa6\xfb\xf5\x91\xc6\x3f\x49\x58\x6c\x0d\xcb\xad\x92\xd7\x3f\x4b\x79\xa1\x22\x30\xfe\x38\x13\xc6\xad\xf3\x6a\x0d\xfe\xd1\x7e\x1e\xf4\x25\x2c\x09\xc1\xf5\x6b\x3f\xb1\x41\xee\xc6\x40\x4a\x47\xd2\xdf\xbd\x2a\xde\x7c\x5c\x4a\x31\xb1\xb9\x2b\x9f\x71\xcc\x5c\xa1\x77\xf6\xd3\x61\x20\x2d\x72\xc1\xbb\xcb\x6e\x91\x52\x3f\x9d\xb1\x93\x88\x4b\x33\x36\x19\xbc\xe9\x5e\x10\xb1\xa4\x3b\xee\x77\xd0\xd6\xa4\x1e\x9c\x4c\x26\xf6\x10\x66\x79\x40\xe2\x0d\x2b\x1d\x4c\x1f\xfb\xe5\x36\xe4\x73\x03\x62\x6d\x9d\xe8\xac\xd6\x6d\x93\x29\x64\xfd\xec\xfa\x1e\x6b\xc2\xbb\x6c\xdc\xde\x94\xbc\x2c\x9e\x85\xf3\xa0\x38\x65\xcd\x30\x07\x25\x9c\x81\x35\x96\xb3\xe2\x47\xeb\xb2\x02\xd4\x78\x9c\x4c\x6b\x49\x92\x1a\xd4\xc0\x3b\x8b\x2e\xf0\xdf\x8b\xf7\xd9\xc9\x26\x26\x0c\x1d\xbf\xee\x3c\xc5\xd1\x2f\xa6\x2d\x6e\xaf\x94\xd8\xaf\xc2\xd9\xbd\xc1\xd3\xa8\x34\xe7\x67\xbe\x24\x4d\x95\xe0\x43\x0d\xfe\xa0\x9d\x6d\xe2\xec\xc9\x8a\x30\xc0\x86\x2d\x1e\x0b\x53\xe3\x4b\xa0\xa4\x1b\x2a\x43\x82\x8a\x28\xab\x95\xcf\xf6\x12\x19\x59\x9a\xca\xb7\x9b\xaf\x93\x0f\x4a\x26\xda\x12\x8c\x2c\xd8\xb7\x9e\x3d\x79\x99\x72\xb4\xce\x46\xac\xae\x15\x9b\x3c\x74\x2b\xe5\xcf\xac\x39\x7e\xcd\x8a\xe6\xa9\x82\xd7\x6b\xb0\xbe\xaf\x7a\x32\x27\x27\x52\x89\xa8\x2f\x8b\xe3\xd7\x98\x95\xc5\xaf\x94\x35\x49\xa2\x44\x84\xdd\xbb\x3e\x0c\xfa\x63\x39\x49\xf9\x45\x97\x2d\xd1\xdc\x92\x5a\x07\xd9\xd3\xb1\xeb\x05\x49\x20\xb1\x01\x15\x96\xe4\x7e\x42\x36\xa6\x3a\xdd\xae\x1f\xc3\x7e\x5c\x1a\xe2\x8d\xf9\x06\xd9\xdf\xc3\x34\x00\x5a\x5b\xd9\x79\x91\x43\x79\x06\x54\x63\x18\x9a\x2f\x89\x09\x13\xe6\x27\xf5\x1b\x80\x6b\xaf\x2b\xdc\x03\x17\xd2\x20\x61\x78\x43\x6d\xfa\xb2\x29\x9a\xea\x63\xa9\x5a\x92\x06\x92\xd8\x36\x0e\xc6\x5c\x23\x9f\x31\x92\x12\x1a\x32\xcc\xaf\x51\x8f\x7c\xd5\x85\xe6\x17\x32\xef\x13\xcc\xec\xf8\xb1\xa4\xdd\x95\x05\x76\xef\xee\xfd\x77\x0f\xa4\x9b\xab\xcf\x65\x51\xc3\xf0\x2b\xca\xf6\x70\xba\x6f\x65\xae\xba\xde\x4e\x8f\xa8\x19\x96\xd5\x36\xb5\x12\x67\x2c\xfc\xff\x12\xcc\x9c\x52\x4e\xf1\xbb\xdf\xdf\x6e\xb6\xc4\x2a\x0b\xfa\x1f\xa5\xa9\xc6\xb6\xdd\xea\xfa\xc7\xed\xee\x71\x7b\xd8\x7f\xdd\x6e\x36\xfd\x46\x25\x52\xab\x21\xb6\xde\x4d\xbf\x8d\x94\xd1\x04\x6f\xc9\x49\xbc\x3b\x6d\x84\x11\x66\xca\xcf\xef\x29\x8b\x12\x29\xa7\x46\xaf\x77\xbd\xcf\x9f\x07\x7d\xcd\x4e\x96\x19\xeb\x6b\x72\x6e\xeb\xa3\x25\x1d\x2e\xb2\x02\xd2\x30\x8a\xb0\xe1\x30\x6d\x0f\xae\xbb\x68\xe1\xb7\xa2\x4f\xb3\x5e\xc8\xec\xc8\x51\x04\x28\xae\x5a\x9f\x61\x70\x29\x9a\x46\x95\x69\xa4\x55\x8f\x76\xec\xa6\xda\x89\x2f\x22\x49\x63\x9e\x68\x0b\x02\x2d\x5c\x39\xec\x0a\x36\x16\x6c\xad\xfb\x31\x32\x42\x70\x92\x1c\x9b\x21\x4d\xa7\xf5\x94\x13\x6a\x45\xd2\x44\x96\x7f\x7c\xa9\xca\xb7\xe6\xe8\x84\x4d\x0e\x7a\xf4\x73\x5c\x70\xe9\xce\xa6\xbb\xbf\xbb\xa6\xac\xc4\x73\x97\x9f\x8d\xcf\x89\x2b\x0d\x23\x92\x96\xa5\x3e\x83\xf1\x13\x72\x9a\xa4\x14\xab\xef\xf7\xe2\xfd\x76\xf0\x45\x21\x69\x4a\x1c\x6a\xa8\x57\x84\xfc\x51\x76\x33\xd7\x35\xd4\xaa\xca\xce\xa3\x04\x36\x15\x49\x80\xa0\x15\x9b\x8d\x7c\x5f\xd0\xdf\x72\x03\xa5\x34\x51\x5f\x57\xc7\x8e\x77\xd3\x7e\x32\x47\xa5\x2a\x15\x18\x52\xae\xd7\xfb\xaf\xa3\xa4\x25\xd5\x3c\x41\x2b\xa7\x7b\x71\x12\x57\x30\x45\x58\xa4\x3a\xb5\xce\xa4\xf5\xf8\x3b\xd6\x22\xc6\xa4\x41\x89\xe2\xaa\xfd\xf8\xe4\xe7\xb4\x52\x98\x51\x7d\x13\x45\x53\x95\x0d\x28\x64\xc3\x90\x5f\xf7\xdd\xfd\xbe\xda\xca\x22\xd8\x98\x65\x96\x1b\xa4\xc0\x6c\x55\x6a\xfd\x78\xfb\xe0\xbc\xc3\x50\x05\xee\xe9\xeb\x6a\xb7\x39\x04\xfe\x2c\x81\x4b\xa4\xeb\xfd\x84\x6c\x2d\xce\x96\xba\x32\x9b\x01\x44\x10\x6b\xec\x22\xa3\x98\xab\x7f\x52\x82\x50\x1d\xf7\xb6\xb8\xdd\x84\x89\xa5\x92\xa1\x5d\x21\x28\x91\x86\xb9\x20\xa9\xa7\x81\x7e\x8a\x5b\x9a\xde\x18\x41\x45\x62\x85\xd4\x4b\x51\xf5\x75\x5d\x41\xa5\x90\xca\x63\xed\x4f\x12\x2a\x84\x8b\x4e\x67\x0b\xc1\x12\x8e\x35\x80\xdd\x7e\xb5\xdd\x7f\x7f\xf2\xfb\x32\x29\x83\xd8\xaf\x0c\x07\x09\x4d\x4f\xd6\x2a\x86\x21\x1a\x65\x03\xac\xf0\x10\xfa\x04\xf6\x71\xb2\x88\x41\x61\xdf\xca\x4d\x5e\x7f\x1d\xf6\x9b\xd5\xfd\xe1\xe9\x71\xbb\xbf\x7d\x7c\xf0\x83\xb8\x96\x58\x03\xba\x6f\x94\x45\x2d\x64\xa7\xcc\x91\x1d\x67\x37\x35\xa1\x4a\xdb\x5a\x04\x02\xe1\x3f\xf3\xfb\xbd\x94\x70\xff\x6f\xb6\xfa\xdf\x88\x00\xb5\x77\x3e\x5b\xde\x1f\xe0\xdd\x4d\x8f\x7b\x91\xf9\xb6\xb8\x48\xd3\x08\x1b\xde\x98\x0b\x6d\xcb\x17\xec\xd3\xba\x6d\x22\x08\x53\x57\xb2\xbe\xad\x7b\x92\xe4\xec\x01\x08\x12\x60\x32\xdd\xbd\x10\x5b\xac\xfe\x4e\xa2\x69\x32\x5c\xc4\xc2\xd2\x28\x44\xa4\xd3\x64\xac\xc1\x78\xf5\xb1\x08\xb2\x12\x82\x53\x14\x06\xee\xf2\xb9\x95\x69\xa0\xb2\x74\x83\xfc\xe3\xbe\x37\x4b\x22\x42\x08\x8e\xa9\xd6\xc1\xea\x6a\x4e\xca\xeb\x42\x12\x89\xa5\xbc\x2d\x48\xec\xba\xf4\x9f\xbb\x90\xd2\x36\x29\x85\xd6\xff\x29\xb3\xa2\x0b\x9f\x0e\xf0\xfa\x89\x34\x04\x11\x8a\xa7\x08\xc8\x39\xe7\xe2\x63\xa2\xe5\x4a\x84\x8e\x24\x58\x4d\x22\x6d\x3b\xd1\xfd\x06\x6e\x45\x1f\x3c\x6d\xcc\x5b\x42\x4f\x2f\x52\xcb\x04\x53\xec\x07\x50\xa2\x3e\x3a\xef\x8e\x9e\x40\x25\x80\xc5\x16\xc2\x20\xaa\xb9\x9c\x0e\x11\x10\x5a\x4b\x22\x4f\x40\x58\x97\xb9\x03\xdc\xba\x32\xa2\x30\x11\xc7\xc2\x14\x14\x0d\x54\x6e\xed\xf0\x87\x36\x5a\x87\xd6\xbc\x2e\x2f\xdf\x76\xdd\xc5\x5f\x41\xbf\xd8\xca\x20\x22\xa8\xa4\x68\x4b\x3c\x57\x6d\x9d\x15\x50\xd7\x3b\x14\x64\x18\xc6\xc4\xf8\x80\x9e\xae\xf7\xe3\xe9\xb2\xfb\xbb\x74\xf3\xf1\x43\xa9\xa1\x5b\x16\xac\x22\xf5\xa8\x8a\x2b\x83\xd8\xe2\xc8\x7d\xea\x3b\x41\x57\xfa\x50\x58\x06\x5c\x12\x31\x14\x19\xab\xc7\x1e\x69\x2d\x83\xc4\x66\xcf\xf8\x79\x79\x85\x97\x7e\xa3\x56\xd8\x0d\xbb\x2b\x9f\x9f\xca\xfc\x03\xf9\xbd\xb3\x16\xdd\x6f\xc8\x95\x92\x44\x80\x77\xf7\xe0\x45\x6f\xc6\xba\xf6\x7e\x4c\xac\x64\x6f\xeb\xba\x42\x9a\xf6\x54\x63\x81\x48\xaa\xad\x17\xcd\xb3\x38\xc1\x97\xcc\x34\xf7\xe2\x7d\x2c\x40\x4c\x24\x8b\x43\xe4\x65\xfe\x4f\x9b\xa9\x97\xef\x45\x97\x03\x89\x8f\x31\xe0\x41\x32\x88\x91\x57\x2d\x6d\x65\x63\xc8\xa0\x64\xc8\x84\x2b\x34\xa8\xb2\xd0\x5f\xb3\xe7\x23\xd4\xcd\x55\xa6\x7b\x0b\x74\x1c\x82\x11\xd0\xed\x93\x72\xe8\xc1\x42\x8b\x4a\x2f\x72\xab\xda\x0b\x76\x8d\x0c\xe3\x18\x51\xf7\x3d\x78\x31\x78\x97\x8d\x72\x88\xc7\xd9\x42\x22\x43\x21\x22\x1f\x3f\xfb\x29\xa1\xfb\xea\x66\xa9\xa3\x8c\x12\x83\x35\x1b\xcb\xc5\x5e\xa1\x30\x90\x03\xc9\x0e\x92\xab\x6e\x6c\x1c\x87\xda\xa1\x80\x30\x36\x5a\x5f\xc2\x26\x65\x1c\x27\xc2\xf5\x74\x11\x07\x3c\xc1\x33\x4c\xbe\x19\x19\x27\x82\x2b\x64\x03\xc8\xac\xb1\xd4\xdf\xc7\x8b\x25\x46\x72\x16\x90\xc1\x3e\x12\xcd\xdb\xaa\xc3\x7c\x4c\x68\x9d\x73\x5d\x4a\x7f\x21\x72\x30\x1b\x2d\x12\x8c\x9a\x57\x75\x36\xe6\xcc\xcb\x24\xb1\x4d\x05\xe4\xa0\xbd\xdf\x00\xfc\xec\xe9\xb9\xb3\x8b\x4c\xa4\x15\x13\xb7\x88\x5f\xfb\x5d\xde\xcf\x13\x5d\x99\x06\xca\x73\x48\x0a\x3d\x6b\x0c\x4e\xcf\x28\x4d\x13\xec\x3d\xfa\xe2\xde\x53\x95\x9d\xca\x4a\x67\xce\xd0\x63\x79\x26\x94\xa9\x21\xb6\xed\x88\xd3\xad\x07\x83\xb8\x8d\x22\x65\x98\x5e\x69\xf9\x72\x3d\x99\x0c\xa5\x4c\x23\x9c\xc7\xfa\xc8\xda\xd6\x6e\x7e\x87\xe9\x93\x52\x49\x6c\x04\xdd\xdf\xae\xbf\x61\x93\xf8\x57\x10\x4d\xa9\x68\x8c\xc8\xa9\x75\x0e\xa2\xfa\x91\x81\xa7\x2d\x4b\x4d\x00\xe7\xc1\x97\x2c\xcf\x6f\xa0\x8f\x9a\xa5\x66\x71\x12\x0d\xcf\x70\x57\xe6\xaf\x9f\x94\x5a\xa4\xe6\x31\x95\xd8\x5f\x2f\x9a\xfb\x8f\x71\x71\x49\xea\x84\x24\x93\x48\xe9\xec\xa4\x5d\x96\x6f\xa1\x4e\xbc\x09\x86\x97\x77\xed\x15\x6a\x3f\xdb\x23\x95\x5e\xa7\x16\x4d\x20\x7c\xd6\x57\x95\xa7\xdb\xf9\x37\xa8\x8d\xc1\x7a\x49\x59\x3c\xc0\xdb\x5d\x29\x2e\xb0\x2e\x6e\x1c\x84\x01\xe6\xba\x7f\x8a\xb6\x6a\x4f\x88\xae\xdf\x6c\xd7\xd4\x07\x8e\x12\x24\xc1\x67\x79\xdf\xbd\xfb\x53\x97\x18\x22\x0d\xd1\xca\xf8\x92\x97\x55\x64\x5d\xc2\x71\x49\x43\x29\x7e\x98\x7f\xae\xbe\x8f\xf7\x57\x01\x15\x08\xd5\x5c\x35\xb9\xa8\xfb\x3f\xb2\x00\xcd\x14\x70\x25\xb8\x12\x4d\x93\xc3\xe3\x50\xe1\x54\x01\x58\x78\x67\x05\xb5\x6a\x67\x65\x6d\x15\x40\xaa\xbc\xb4\xa5\xff\x1b\x71\x36\x05\xcf\x68\x10\x8c\xdc\x89\xf5\x78\x1f\x42\x54\x1a\x7b\xf2\xe8\x92\xab\xc4\xef\x32\x3e\x7f\x1c\x4d\x91\x42\x72\xf5\xe8\x05\x98\x89\xa2\x89\xc6\xa4\x5a\x89\xfc\x01\xde\xa6\xdf\xa1\x1b\xc2\x78\x2a\x7a\x3e\xde\xfe\x2d\xeb\x16\x67\xbf\x3b\x03\x85\xf7\xd7\xd1\xe4\x6d\xaf\xfb\xb6\xb8\x2f\x8b\xe6\xd8\xdf\xaf\xb0\x5b\x39\x9c\x3c\x88\x5a\x92\x3a\x72\x9c\xd0\xf8\xdf\xd3\xff\x41\xe2\x8b\x3f\x5d\x5e\x54\x18\x73\x6c\x3d\xb8\xd9\x46\x9c\x60\x5d\xce\x4c\xd1\x88\x8a\x92\x14\x0d\x0d\x57\x8f\xf7\xaa\xcc\x8a\xf1\xfb\xa3\x22\xc1\x70\x79\x5e\x8b\x73\xd3\xad\x3b\x03\x19\x45\x45\x1a\x42\xcb\x67\xfd\x98\x4e\x13\x2a\x0e\x41\x39\xc2\xae\xc5\x36\x5e\xb5\xc6\x0c\xb7\x25\x56\x1c\xcd\x59\x6c\x73\xa1\x27\x53\x39\xe2\xcd\x2c\xef\x1b\x5e\x43\x15\xeb\x10\xdc\x9d\xea\xbe\x08\xaf\xa4\xd1\x2e\xc9\x1a\x8e\x6f\x47\x17\x86\x0f\x47\xe1\x94\x61\xca\xe2\x9b\xd2\x16\x4c\x03\xfa\xbe\x2c\x44\xa5\x8e\x28\x08\x30\x8a\x70\x14\x0f\xb5\x45\x10\xd6\xd0\xfc\x42\x37\x46\x71\xa9\x62\x77\x76\x37\x15\x16\xe7\xa1\x12\x39\x76\xed\x66\xcd\xb3\x21\x30\x52\x09\xe5\xdc\x9a\x2f\x23\x63\x62\x50\x3d\xf0\xdb\x65\x82\x81\xfc\x16\xe3\xca\x5f\xcd\x9a\x4a\x4a\x5b\xc0\x54\x5e\x3a\x6c\x16\xe5\x28\x29\x21\x56\xa3\xde\x42\x0f\x66\x99\x04\x11\x7e\xb0\xb6\x74\xe9\x53\x59\xc1\xfe\x28\x8a\x5d\x69\x9a\x91\x6c\x1a\x51\x2a\xf0\xdf\x71\xd3\x56\x05\x22\x05\x26\x42\x15\x4a\x05\x9c\x4f\x38\xaf\x37\x00\xd7\x1f\x85\x38\x65\x6a\x79\x6e\x56\x2a\x4e\xb1\x6a\x9e\x03\xbc\xec\x1a\x10\xf9\x97\xb2\xff\x35\x01\x28\xb7\x72\x16\xcf\x70\xd5\x7e\x58\xda\xef\xd5\x1c\x1d\xf2\xc9\x47\xa0\x09\x47\x7d\xac\xdd\x39\x53\xf0\x24\x3e\xaa\x32\x9f\x41\xa7\x94\x16\xa9\xd7\x41\xde\x57\x42\xc3\x08\x39\xab\xb4\x10\xae\x27\x63\x8b\xf3\xbf\xd4\xec\xb9\xfc\x75\x88\xac\x96\x43\x05\x06\x9b\x21\x93\x87\x06\x51\x0c\xd2\x7f\xfc\x8b\xd7\xe2\x07\xc6\x31\x42\x4f\x4f\x99\x93\xbd\xdc\x97\x5f\x60\xec\x5c\x44\x94\x91\x69\x2a\xbc\x3f\xf1\x84\xf6\xad\x03\x96\x48\xbf\xf2\x74\x8b\x67\x97\xad\xa1\xc7\xd5\xaa\xd0\x88\x49\xb8\xc4\x2e\x68\x42\x2c\xd2\xc8\x4e\x1d\x17\x1a\xfa\xd3\x75\x48\x13\x13\x21\xbc\xe9\x2a\xf3\x41\x69\xbf\x41\x98\xc1\x87\x7c\x4c\xf6\x09\x03\x4f\x0c\x9a\xfc\x1b\x06\xb3\x43\x53\x1a\x62\xad\xf8\x50\xb7\xb2\x5b\x2b\x11\x74\xf1\x15\x16\xac\x71\x86\xaf\x5c\xd3\x48\xa1\xbd\xa1\xb3\x66\x9a\x54\xb0\xfd\x90\x34\xc1\x78\xdc\x49\x05\xd7\xd7\x65\x21\x9a\xcf\x00\x80\x9a\x51\x81\xd5\xbb\x11\x1a\xfc\x93\x81\xa1\xc4\x44\x60\x6c\xa7\xb5\x2a\xf4\x5a\xe4\x17\xf6\x2a\x4b\x20\x5d\xcd\x22\xde\x17\x4f\xb2\xc2\xe9\x01\x5e\x65\xb3\x00\x41\x87\x71\x4a\xc4\x44\x07\x66\xef\xbf\x16\x1d\x72\x5b\x1d\xb3\x18\xf7\xa9\x12\xf7\x04\x0d\xaf\x43\xa9\x30\xd4\x2a\x51\x48\x42\xe4\x93\xa5\x55\x87\x86\x07\x2e\xc7\xbf\x7f\x1b\x1b\x9e\x13\x1d\x45\x36\x1f\x91\xed\xc7\xa7\x28\xdc\xd1\xe3\x88\x38\xc5\x36\x44\xaf\x45\xfb\x4b\x24\x95\x8e\x20\x09\x9d\x64\xd6\x03\xbc\x8d\x6b\x86\x6e\x40\x1c\xb0\x58\xfa\xc9\x4e\xa8\xbe\x53\x3d\xa6\x4e\xfb\xa1\x4c\x21\x19\xd7\xd6\x1f\xb1\x7a\x7c\x65\x63\xfb\x45\x57\x56\xa2\xe3\x38\x4c\x50\x1c\xa7\xac\x9b\x93\xe8\x5f\xe4\x58\x48\xe6\x30\x01\xb7\xb5\x13\x75\x84\xea\xa6\xb4\x86\x5e\xf6\xaa\x46\x57\x1c\x2b\xe9\x09\x98\x4f\x48\xa7\x42\x4d\x8b\x09\x46\x49\x73\x57\x74\xb8\xbd\xf2\x28\x35\x9d\x02\x45\xe7\xa6\x02\xde\xb1\xfd\x39\x79\x1e\x82\xa5\x14\x6d\x65\xd6\x8f\x48\x3c\x1f\x35\x3d\xb4\x94\x06\x29\xd7\xfe\x7d\x58\xe5\x79\xf7\xe6\x6d\xcb\xbe\xc6\xa1\xbb\x00\x74\x02\xd6\xf9\xe4\x0d\x96\x26\x02\x33\x80\x81\xf7\xbb\xab\xc5\xca\x8e\x86\xc0\xda\xce\xfe\x6f\x2b\xaa\x06\x2c\xd5\xd6\xff\x16\xa4\x0c\x29\xbf\xce\x98\x78\x21\x43\x18\xbf\xf3\x90\x82\xf1\x37\xab\x0b\x24\xb2\xb2\xe8\x3e\x70\x77\x53\xc7\xc5\x32\x6d\x84\xf2\x53\xd9\xff\xb4\x22\x47\x48\x53\xed\xf4\x42\x6c\x58\xe4\x80\x5e\x10\x40\x3c\xca\xb4\xbe\xd7\xfa\x09\xaa\xfb\xb9\xa2\x21\x01\x12\x18\x34\x37\xea\xb5\xcc\x00\xae\xb2\xa6\x0b\x84\xd6\xa2\x3e\xde\x03\xd2\x49\x67\xbd\x3d\xc0\x86\x80\x3d\x0b\xb7\xc9\x94\xaa\xad\x95\xa8\x74\xa6\xe9\xf2\x1c\x09\x44\x32\xca\x3d\xcc\x7c\xed\x75\x5e\xea\x66\x77\x2c\xcf\x83\x5b\x3c\x01\x46\x00\x27\xa6\xdd\x66\xfb\x63\xb3\x45\xb0\xdf\xe3\xf7\x7d\xbf\x55\x6a\xe6\x7e\x7a\xd2\x5e\x99\x5e\x55\x48\x0c\x02\x66\xd7\x8f\xf7\x4f\xab\x87\xbf\xa6\xd0\x5c\x08\x23\x8e\x7d\x12\x78\x3f\x43\x95\x41\xa1\x00\x3d\xc2\xfa\xcd\x9c\x4a\xe8\xd7\xf6\x87\xb2\x99\x77\x8d\x21\x4c\x92\x50\x8f\xb5\x30\x31\xa9\x47\x9b\xa2\x7a\xe6\x53\x44\x20\xd4\x46\x8b\x1e\xd5\xa9\x60\xe4\x24\xed\x46\x44\x81\x41\x99\x68\xf4\x67\x2e\x44\xbe\xd2\xda\xeb\x16\x4e\x6f\x61\x44\x03\x6a\xcb\x74\xdd\xa4\x70\x2f\x5e\x10\x08\xe1\xe5\x1a\x17\x5f\x67\x88\xa8\x0d\x44\x84\xd6\x7d\x2b\xb0\x5b\x83\xdc\x7c\x38\xfb\x01\x16\x60\x50\xbb\xee\x99\xed\x23\x49\xa5\xf1\x3b\x0b\x51\x2a\xb0\x5d\xe1\x2c\xce\xc3\xc9\xc2\x0e\x31\x09\x30\xcf\xbc\x6b\x8b\x8f\xea\x97\x53\xde\xec\x6c\xe3\x48\xc9\x6e\xf9\xb8\xda\x6f\xfb\xc7\x15\x27\x31\xa7\x7d\xb7\xd4\xc7\xcb\xa0\x7d\x2d\xb2\x1f\x06\xa1\x15\x31\x75\xe8\xb2\x83\x3d\xa5\xc3\xf5\xec\xdc\x94\x85\xa0\x5b\x68\x02\xc2\xc3\x8a\xd1\x33\x99\x9d\x10\x0f\xac\xfa\xbd\x95\xba\xc0\xda\xad\x03\xed\xce\xc6\x39\x8c\x1c\x52\x4d\xad\x7e\xda\x52\x37\x1e\x38\xb3\x25\xc9\x3a\x7b\x2e\x36\xab\xc9\x84\x08\x3c\xb4\xba\xef\xa7\xac\xf0\xc2\x05\x23\x21\xdc\x71\xb6\x0e\x69\x2a\x10\x9e\x9e\xd5\x4e\xc6\xd2\xaa\x23\xcf\xb9\x0a\x90\xaa\x08\x3f\x17\x5f\x36\x6d\x2f\xe5\xb6\x40\x24\x12\x51\x4f\xe7\x6a\xc8\xe1\x27\x85\x48\x10\xca\x9a\x9a\xae\xaa\xac\x1e\x17\x7e\x40\x12\x2b\x57\x88\xed\xa3\x6a\xf8\x33\xb3\x4c\x1b\x89\x06\xd0\x59\x17\xae\xa1\x44\x99\x0b\x74\x2e\xc4\x94\xf0\x6f\xc3\xbe\xa1\xfb\x5c\xf2\x52\xbd\x74\x71\xc3\xf4\x74\x65\x14\x60\xa4\x7f\x97\x15\x62\xa4\xaa\xbb\xfc\xf6\xcb\x48\x6b\x74\x4a\xdc\xfc\xe8\x4f\x2e\x51\x4e\x42\xee\xd8\x8c\x54\xf0\x40\x91\x00\x33\xa3\x6d\xf6\x5c\x22\x31\xae\xdf\x10\x0a\xfc\xea\xbc\x64\xc5\x0c\x2e\x07\x3a\x24\xa8\x87\x22\xd0\x92\x45\x7b\xf9\x7c\xbf\x35\xb2\xcc\xb3\xac\xbe\x72\x14\xc0\x8b\x0c\x77\xfc\x5d\x01\xa5\x78\xc2\x9b\xfb\xdb\xdd\xee\xf6\xf1\xe1\x70\xf3\xb8\x45\x3b\x85\xdd\x7e\xf5\x65\x13\xf9\xa3\x02\x63\xf6\xab\x6e\x9b\x5e\xd3\x75\xe5\xa9\xc4\xcb\x6f\xb2\x09\x52\x6b\x69\xdf\x94\x15\x38\xe1\x92\xde\xcd\xfa\xea\x63\x8b\xb0\xed\xee\x0d\xfa\x54\x87\xc3\xc5\x0a\x0e\xb8\x3d\x53\x79\x34\x41\x68\x67\x31\x91\xe7\x3f\x21\x7b\x3e\xf6\x65\x78\x13\xc4\x90\x0c\x19\xef\x5f\xdf\xef\x1f\x17\x57\x54\x13\x68\x81\x55\x66\xec\x04\xe5\xa2\x7a\x86\x6b\x78\xcd\xf0\xfc\x1e\xca\x66\x0e\xaa\x31\x01\x50\x35\xc4\xd6\x5d\x76\xbf\x1d\xf7\x8d\xdd\x28\x12\xc4\xf1\x24\x32\x50\xaa\xb5\xc2\x48\x1a\xbd\xb7\xa6\xa7\x40\x62\xe9\x25\xb1\x7e\x42\xb6\x28\xe9\x67\x48\x62\xd9\x18\x59\x8d\x86\x30\x30\x69\x09\x18\x92\x52\xeb\x3d\xdc\x9e\x4e\x88\x51\x82\xaa\xf6\xc4\x53\xd3\xe5\x15\xf1\x68\xa6\xff\x51\x5e\xfa\xad\x2c\xcf\x8c\x86\x05\x1c\x91\xca\x87\xac\x1e\x05\x3e\x26\x8c\x20\x09\xbc\xf1\x64\x59\x3d\x55\x70\xbb\x7e\x5c\xfe\x18\x4c\x44\x6d\x48\xf0\x66\x21\x98\x63\x9c\x93\x89\x38\x43\xe6\x95\xcc\xf4\xed\x85\x28\xc1\xf2\x19\xc5\xd4\x3a\xa0\x58\xdd\xb2\xaa\x9b\xf8\x5e\x41\xe4\x8e\x54\xda\xbd\x01\xd3\xe0\xc5\xc4\xa1\x6d\x34\xd4\xed\xf9\x5c\x56\x0d\xe8\x6d\x99\x5b\xbb\xa3\xe9\x81\x39\x67\x56\xc5\xd5\x99\x40\x3d\x21\x06\x77\x22\x56\x4c\x0c\x57\x11\xa2\xc6\xb2\xc2\x31\x48\xfd\xdc\x68\x92\x20\xb2\xd1\xb1\xcd\xb9\xa6\x36\x0d\x4b\x64\x1f\x93\xf2\x54\xb8\x3c\x14\xf9\x11\xf3\xda\xbc\x11\x04\xb0\xf2\x6b\xd9\x32\x9b\xff\x9d\x73\xaa\xa6\x5f\x82\x00\x1a\xc9\x11\xa8\x3c\xab\xae\xab\x5e\x94\xc0\x48\xae\x70\x72\x3c\x9e\x1c\x80\x71\x94\x02\xfa\x21\xa9\x4c\x61\xb2\x94\x7d\x2d\xdf\x0e\xfb\x72\xb2\x90\x19\x65\xac\x9d\x50\x77\xff\x4b\xd3\xbc\x89\x0a\x01\x15\x4e\x14\x6c\xbc\xb2\x18\x4d\x23\xfb\x96\x9c\xa1\xd0\x5d\xb4\x70\xa8\xc7\x3d\x46\xa3\x43\x86\x37\xd3\xb1\x6d\xad\xf4\xd8\x67\xbe\x5f\xd3\xaf\x01\x22\x9a\xf8\x45\xcb\xb5\x5a\x1f\xfa\xde\x8e\x31\x49\x80\xee\x32\xf6\xd3\xbf\xba\x64\xe2\x18\xa3\x02\x6c\x67\x3b\xd2\x05\xae\x72\xd0\x9e\xec\x7a\xd6\x65\x6e\x33\xdb\x9a\xc9\xa3\xa3\x41\x10\x0b\xe2\xac\x62\x0e\x26\x7b\xc7\x8f\xfa\xb6\x58\xff\x5c\xff\x31\x1d\x47\x68\xca\xe4\x80\x04\xb3\xd2\xad\xdd\xa2\xe4\x67\xf3\xa5\x29\x89\x06\x24\x8a\x30\x90\x87\xe6\xd8\x25\x57\x0e\x12\x4f\x03\xa2\x0d\x2a\x9c\x7f\x2f\xee\x4a\xf5\xb2\xbc\x2f\x25\x1a\xc5\xa6\x4f\xe2\x7d\x0f\xe2\x84\x17\x7f\xe5\xc5\x42\x68\xc0\x98\x05\x89\x6d\x0a\x6d\x0b\x71\xa3\x65\x83\x06\x2c\x89\x62\xfb\x5d\x37\x8e\xac\xf6\xc7\xa8\x99\xee\x07\x69\x5b\x3f\x73\x9a\x41\x96\x73\x74\xe1\x4d\x45\x83\x30\x0a\x90\xb0\xe2\xa1\xa7\x5b\xc0\x4b\xbe\x43\x85\x85\x2d\xbc\x66\x75\x56\x16\xd7\x25\xd4\x45\xf3\x55\xa0\x30\x5e\x66\x3d\x56\xfc\xb6\xfe\xa4\xc3\x38\x44\xc4\xbf\x13\xa0\xbb\xc4\xc5\xfb\x71\x92\x26\x49\x6f\xda\x50\x56\x1e\xb3\xb1\x94\x1a\xd0\x20\x34\x29\x8a\xfb\x1d\xc6\x55\x03\xab\x38\x7d\x01\x65\x9f\xfe\x4e\xe4\xaa\x23\x67\xf1\xf1\xd8\x36\xfe\x2c\xa3\x90\x4b\x36\x74\xe7\x17\x54\x4a\x68\x10\x09\xa3\xad\xe1\x39\x92\x53\x34\x92\xee\xc7\x61\x0f\x0d\x22\x88\x43\x5b\xbb\x7a\x2d\x5f\xe0\x16\x6b\x29\x68\x7a\x3f\x25\x91\x4e\xaf\x25\x26\x11\x68\xdf\x4d\xfd\x39\x05\x6f\xd0\x20\x8e\xa8\xb7\xe7\x5c\x9d\xb3\xe5\xf7\x26\x61\xd6\x8a\x30\x17\xea\xa5\xb6\x35\x57\xb7\x25\x25\x3a\xe8\x93\x9f\xa6\x9a\x71\x4e\x69\x90\x1a\x09\xc3\x42\x7b\x28\xca\xa6\x9b\xe1\x47\x93\x06\x0d\x04\x0d\xb4\x77\xb7\xcc\xb3\xb3\x75\x92\x59\x3c\x0d\x11\x0b\x3c\xd8\xe6\xfa\xfe\xf3\x5e\x1a\x0d\xd0\x32\x01\x3b\xf0\x4d\x7d\x53\x56\x43\x3d\x6d\x34\x84\x68\x84\xeb\x17\xf0\xe6\x6f\xc8\xba\x3c\x39\x58\xee\x6c\x2c\xb0\x10\x99\x6b\x6d\x71\x83\x26\x3c\xbf\xfa\x69\x50\x11\x2e\xd6\x5e\x6d\xf4\xc6\x7a\xc5\xf8\xbb\x65\x52\xdb\x3a\xf9\x8e\xe9\xac\xfb\x2b\x09\x12\x91\xd2\x71\x61\x76\x6e\xf6\x3e\xf9\x0d\x12\xa8\x98\xba\x57\xe9\x1b\x7c\xd4\xe3\x69\x95\x12\x92\x12\x01\x08\xd6\xc6\xb6\xf4\x7a\xf4\x33\x94\x83\xcf\x07\xee\x3f\x76\xc7\x2a\xf3\x32\xee\x94\x50\x69\x6b\x69\x68\x9f\x54\xa2\x12\xf0\xdc\x0f\x9b\x12\xaa\x0c\x06\x95\x0f\xdf\xbf\x3c\xde\x5d\xfb\x5d\x23\x9a\x62\xf6\x60\x0d\x8a\xbe\x17\x4d\x36\x2d\xe5\x52\xd2\x85\x03\x18\x91\x3b\x1d\xcf\x56\xda\xa0\xc8\x6d\x8e\x89\x62\x64\x6c\xca\x89\x7a\x84\xe3\x37\x84\xc4\x09\xa8\x41\x24\xb3\x8b\xde\x17\x99\xbe\x94\xc4\x2a\xd0\x8e\x63\xb9\x46\xa1\x94\xd9\x1b\x44\xb8\xe0\xa8\x22\x88\xab\x4e\xf7\xe4\xbf\x88\x7a\xce\x02\xff\x3c\x16\xa6\x84\xab\x00\xbb\x77\xeb\x3c\x53\x2f\x5f\xc0\x76\xef\x46\xfd\x19\x4a\xd2\x40\xa5\xe1\x08\x7f\xb1\x83\xa6\xc9\x51\x61\xcc\x55\xe3\x17\xe1\x9f\x94\xa4\x8a\x22\xc6\xf3\x15\x61\x7b\x93\x8f\xc0\x8f\xd0\x8c\xc6\x83\x8a\xd2\x81\x84\x7e\x8b\x10\x14\x42\x2c\x90\x7d\x15\xd5\x7f\xfa\xbf\x4a\xab\xba\xd2\x88\x46\xe4\x9b\xe6\x88\x24\x88\xb6\xd7\x11\xa2\x44\x18\x11\xb9\x75\xae\xfb\x4d\x97\xe0\x6f\x71\x6a\xd1\xb3\x1b\x27\x8c\xb5\xf4\xf4\x66\x3a\x18\xdf\xd8\x75\xb0\xde\x96\x79\x3e\xd7\x07\xbb\x7c\x6d\xa5\x04\x24\xa3\xec\xa0\x69\xcf\xd7\xbd\xb4\x1f\x25\x2a\x8c\x10\x26\x97\x29\xab\x5a\xd0\xff\x3d\x02\xbc\xd7\x26\x7b\x47\xd5\x46\xaf\xf6\x35\x7a\x25\x55\xaa\xb0\xae\x8a\xad\x23\x8b\x74\x71\x5b\x74\x40\x31\xb0\xdc\x41\xb3\x79\x15\x79\x3b\x72\x11\xf4\x72\xb9\xff\xb0\xcf\xc3\xa5\x79\x94\xe8\x48\x48\x57\x4f\x7c\x28\x35\xcc\x6e\x80\x96\x01\x63\xfd\x3b\xe8\xcc\x2e\x97\x91\x93\x94\x68\xa0\x48\x3c\xf5\x8b\x87\xd3\x91\xc4\x6e\xb0\x05\xf4\x8b\xaa\xf9\x58\xa2\x70\xb9\xfe\xe1\xe7\x4a\xbe\x94\x40\x64\x29\x7e\x27\xf1\x02\x77\xd9\xff\xb6\x99\x5e\x97\xfd\x33\x05\x61\xf3\xe2\xaa\x5b\x4f\xb3\xc6\xc3\x52\x0e\xac\x1f\xa0\x52\xcf\xf2\x44\x54\xcd\xed\xd9\x4c\xe3\x1f\x4a\x40\x13\xd7\x16\x2f\xa0\xce\xea\x1f\x59\xd5\xf6\x2f\xa1\x91\x04\xd1\x57\xf8\x44\x4c\xa6\x2e\xe8\x89\x8b\xf3\x62\x17\x19\x22\xd2\xf3\xfa\xf6\xaf\x7d\x2b\x47\x90\x31\xda\xad\x69\xf8\x98\x0f\xae\x0a\xea\xfd\xab\x28\xa5\x54\x62\x88\x88\x9d\xb8\x5d\x2b\x7b\x24\xab\xef\x6e\x4e\x7e\x83\x52\x30\x28\x4a\x72\xc6\x62\xc8\x14\xb2\x4f\x29\x0b\x0d\xea\x69\xad\x1f\x1f\x7e\x6c\xb6\x98\xc7\x5e\x6f\x1e\x1e\xef\x6f\x1f\x56\xfb\xc7\xad\xff\x49\x16\x01\x0f\x3d\x0f\x72\xec\x75\x7b\x14\xcd\x3d\xd4\x35\xf2\x35\xfc\xd8\x58\x52\xb7\x6e\xdd\xae\x1f\xd9\xd3\xb1\xc7\x97\x51\xca\x52\x2d\x5c\xc9\xa0\x86\xdc\x74\xf3\xaa\x58\x58\xf2\x69\xb7\xae\x72\x9b\x01\x9f\xb7\x48\x97\xef\xcb\x47\x94\x86\x89\xa5\xa2\xa3\x64\x60\xb5\x2e\x35\x74\xdf\xbd\x2d\x40\x4f\x2f\x2e\x4c\x14\x1d\x4c\xb2\x1f\x5d\xa1\x76\x3b\xf1\x19\x77\x43\xa3\xc0\x92\xbd\xfd\xab\xb9\xeb\x72\xef\xa1\xcd\x39\x1b\xcc\x23\x7c\x59\x1e\x0b\x54\x67\x57\xf6\xc1\x2d\xc9\xa5\x2f\x7e\x07\x34\x4a\x13\x54\xed\xb9\xca\x9a\x75\x0e\xa7\x93\xbf\xb2\x48\x9a\x80\x79\x6f\x5a\x3f\x97\x5f\xc3\x39\x2f\xb1\x33\x32\x00\xa2\x29\x8d\xb5\x65\x68\x38\x12\x74\x17\x1f\x6f\x74\xd6\x1c\xf8\x64\x89\xa0\xb1\x4e\x11\x37\xad\xcb\x7d\x6f\x57\x46\x29\x8f\x83\xd4\x85\xac\x4d\x8e\x02\x3b\xc3\xe4\x41\xb9\x02\x08\x9c\x77\xc9\xfe\x28\x9a\xdd\x31\x6b\xae\x7b\x0b\x13\x4a\x93\x34\x42\xa8\xf5\x4a\xeb\x7d\xd6\xe4\x73\xbe\xe1\x2f\x54\x41\x29\x4d\xa4\xf2\x16\x0b\x37\x59\x9e\xff\x28\xf3\x16\xbd\xf7\xcb\x32\x9f\x7a\x8e\xcd\xf6\x4b\x53\xc0\x59\xa6\x3b\x27\x5d\xbe\x15\xd3\xbc\xc7\x0d\x12\x24\xc4\xbe\xb1\xa5\xe4\xcd\xf3\xc8\xd9\xd8\x94\x31\x47\xa2\xba\x12\x35\x2c\x7f\x39\x42\x86\x10\x0c\x56\x44\x7a\xec\x69\x47\xa9\x30\xdc\x20\x77\xb4\x3c\x9d\xdb\x06\xae\xda\x8f\xd9\xee\xca\x19\x27\x75\x3b\x67\x6a\x56\x9a\xa6\x54\xc7\xca\x9f\xc2\xaa\x82\x42\xdc\x16\x0d\x54\x46\xcc\x8a\x18\x94\x9a\x00\x60\xec\x9d\xe7\xd6\xa3\x7a\x3e\x8c\x28\x04\x9f\x1e\x06\x9c\xcf\xbc\x53\xfb\xab\xb2\x05\xa5\x26\xa1\x58\x27\xb6\x6d\x08\x3f\x43\xf6\x02\x83\x83\xb7\x20\xa5\x46\xb1\xc4\xc2\x5f\xb2\x66\xa7\x3c\x9c\x97\xb2\x20\x54\xa1\x83\xb9\x6e\xde\xcf\x79\xa6\xb2\xbe\x4d\xe2\xd1\x0f\x43\xe7\x9d\x32\x12\x4a\x5c\x9f\xd7\x8f\x0f\x37\xb7\x5f\x0e\x37\x9b\xcd\xee\x70\x7d\xfb\xc3\x1f\x8d\x48\xe1\x05\xb9\xac\x0d\x7c\x56\x16\xd6\xc0\x60\x7a\xe9\x8c\xd2\x00\x93\xf0\xc3\x2b\x54\x99\xf9\x98\x3d\x79\x3f\x28\xb1\xc6\xa1\x3a\xab\xbb\xb4\xda\x81\x38\x86\x76\x06\x65\x34\x05\xec\xfd\x1d\xb2\xfa\xa1\x6c\x1e\x8b\x31\x1d\xd1\x0d\x61\x90\xf0\xc0\x39\x82\x5a\x95\xed\x46\x1d\xf7\x15\xc0\xa2\x74\x0b\x65\x11\x4b\x49\xe2\x31\x41\x17\xd3\x1c\x8b\x62\x8d\x21\xeb\xa9\x0b\xdd\x8e\x30\xd3\xe9\xf5\xb2\x0b\xe1\xf8\x9f\x71\xef\x9b\xb2\x48\x44\xde\xa8\xa0\x4b\x9f\xb0\xaf\x31\xff\x0d\x48\x10\xac\xf0\x03\x0a\x5d\x56\x9f\xbc\x64\x2c\xa6\x5a\x47\xde\xd5\xe8\x5c\xaa\xe3\xa8\xae\x4a\x59\x9c\x32\xfc\x10\x90\x4c\xb6\x52\x0a\xea\xda\x49\xc4\xea\x61\x08\x17\x89\x07\x07\xcf\x0f\xae\x54\x6c\x0d\x89\x11\x6a\xb2\xec\x64\xed\xc6\xf2\x40\x20\x7f\xa5\x3c\x43\x81\x85\x42\x2c\xd1\x2f\x55\xe8\x29\xe3\x49\x9a\x38\xf4\x38\xce\xd4\x2e\x3f\xb8\x2d\xee\xb3\xdc\x11\xba\xfd\xaa\xc4\x12\x42\x11\x7d\x25\xe1\x39\x2b\x9e\xfa\xd9\x8c\x25\x91\xd5\x49\xa8\xb2\xe7\x63\xc3\x93\xd9\xcd\x4b\x52\x4b\x5f\xd6\x59\x9d\x67\x2f\xb0\xaf\xc6\x4e\x81\xd3\x47\x9d\x6a\x83\xf7\x08\x8b\x9f\x98\x2f\x4d\x6c\x79\xdc\x28\x41\x23\x29\x46\xd8\x96\x2b\x68\x9c\x37\xc2\xf2\xed\x10\x3c\xc4\x56\x9c\x2b\xf7\x38\x62\xe0\xcf\xec\x25\x7b\xc2\x35\xd7\xde\x0f\x1f\x03\x31\x19\x4a\xac\x67\x39\x74\xfa\x51\x54\x7e\xc1\x60\x2a\xe1\xf8\x84\xcf\xb9\xf8\x18\x4d\xf7\x4c\x0b\x26\xd2\x01\x1e\xb8\xb3\x2e\x44\xa3\xa5\x86\x69\x48\xf1\x91\x5c\x83\x41\x33\x36\x67\x73\x9b\xe7\xc3\xd3\x07\xa2\xb0\x41\xbc\x9b\x35\x24\x28\x03\xc5\x50\xd8\xf3\xdb\x6e\xa7\x32\x6d\x31\x95\x6e\x93\x09\x02\x54\x2f\x91\x9f\x50\x39\xfc\x30\xd0\x5e\xd1\x08\x39\x63\x30\xd6\xf4\xb4\x33\xca\x00\xa0\xb2\xfb\x84\x01\x0f\xb0\x8e\xbd\x6e\x2b\x6f\xba\xe4\x7e\x35\x24\x81\xf5\x99\xee\xde\xef\x75\x59\x37\x4f\x50\x7d\x2d\xdb\xaa\xdf\x4c\xad\xac\xfc\x64\x1f\xca\x0d\xf7\x62\x1a\x99\xbe\xbd\xfe\xac\xd4\xf1\x4b\xe4\x1e\x0d\xa9\x30\x68\x65\x22\xe1\x53\x37\xf1\x91\xa6\xe1\xe2\x6b\x16\xb2\x90\xa1\x4b\xcd\xaa\x10\xf9\x47\x93\x29\xab\x53\xec\x37\xc6\xb1\x09\x7a\x41\xbc\xa7\xaa\x7c\xcd\xe6\x7a\xcf\x34\x64\xd2\x52\xa9\xb2\xda\x2a\x34\x3c\xbe\xf5\x19\xd5\xbc\xbe\x3d\xdd\x31\x0a\x42\x4c\x04\x7c\x49\xfc\xaa\x97\x02\xfa\x65\x90\x1b\x46\x8a\x20\x50\x04\xeb\x2c\x57\x6d\x55\x4c\xee\x2d\x67\xd6\x58\x5b\x95\x45\x5d\x56\x4d\xd6\x9e\x9e\x72\xa1\xc0\x32\x19\xfb\x41\x31\xf5\x6e\xf9\xab\xaa\xc9\xea\x66\x0c\xb9\x76\x63\xd2\x40\xc4\x83\x44\xfd\x5a\x54\x7a\x20\xd4\xfb\x25\x27\x4c\x69\xe8\x8b\x2a\xc8\xc7\x99\x5b\x86\xd1\x30\x0d\x35\xd2\x88\x7b\xab\xda\x62\xb2\xec\x87\x29\xe7\xca\xfb\xd1\x78\x09\x6e\xbf\x29\x91\x88\xe0\x50\x65\xf1\x9f\xb6\x02\xc7\x2d\xf4\x5b\x45\x60\xb0\xab\x03\x93\xaf\x2b\x14\x49\x8a\xd8\x15\xc4\x65\x1e\x5c\xb5\xee\xa0\x8a\xe6\x70\xf2\x86\xc1\x34\x14\x69\x8c\xf1\xb7\x27\x77\xa0\x1f\xf5\xa8\x5a\x10\x0a\x6d\x8d\xbb\xb6\xa8\xbe\xd2\xf3\x45\x68\x28\x41\x79\x3b\x91\x6e\xa7\x7d\x36\xdc\x54\x45\x22\x84\x1e\x09\xad\xb7\x4b\x34\xbe\xdf\x31\x0f\xdd\x61\x34\x23\x08\xdd\xfc\xfe\x70\xbb\xbf\x6e\x4f\xa7\x0f\x87\xe3\xf9\x22\x1a\x78\x13\x1f\xb3\xa7\xa4\x21\x00\x2b\x5b\x88\xa6\x2e\x5d\xfa\x92\xe9\x59\xe4\x14\x6a\x50\xc9\x60\x51\x7e\xf5\x7d\x77\xfb\xb0\xd9\xed\xfc\x79\x03\xb1\x14\x07\x64\x62\x68\x4b\xc1\xd9\x76\xd1\x81\x1f\x60\x80\x5a\xef\xc0\x91\x04\x67\xeb\x9f\x43\x14\x50\x8d\x55\x7d\x4c\x9f\x0e\xe7\x2e\x61\x3f\x9c\xca\x02\x3e\xfa\x01\x31\x80\x8b\x3b\x1e\xa7\xc6\xa9\x34\x0a\xb8\xf0\x0e\x30\x23\x6b\xe7\xe9\xe9\x47\x01\x07\x24\xc0\xf7\x2a\x8b\x85\x16\xbf\xbb\xb9\xff\xa2\x53\x93\xb1\x2e\x21\x61\x56\xb2\x46\x35\xd9\x2b\xf4\xec\xb2\x01\xf1\x47\xa3\x00\x8c\xc3\x36\x1a\x47\x95\x59\xaa\xfc\xd3\x88\xa4\x0c\x15\x37\x73\x75\x5a\x40\x98\xd1\x88\x88\x10\x0b\x88\x5f\xe8\x77\x33\xbc\x54\x11\x55\xd6\x4f\xec\xd9\x01\xf8\xbc\x1e\xd0\xf4\xe0\x54\x27\x61\xe8\x4c\x26\x0e\x4d\xdf\xf0\xa2\x11\x0b\x83\xa0\x7b\x0c\xdb\xa7\xdd\x6c\x17\xd6\x25\x3a\x18\xf8\x3d\xde\xad\x1f\x6f\xfd\x8a\x10\x85\x10\x22\x89\x6d\x77\xb3\xf7\x7f\x8a\xba\x2f\xae\x7b\xd8\xa7\x73\x7e\xb0\xd2\x51\xd3\xd9\xd7\x8f\x63\xa1\xd5\x0e\xc1\x00\x71\xd0\xbc\xa4\x51\x64\x44\x38\xc4\xb5\x23\xc5\xd6\x6e\x93\x24\xbc\x37\x5e\x5f\xea\x21\xd2\x28\x26\x16\x30\xf8\x9f\x32\x2b\x1e\x0b\x98\xb0\x9a\x68\x14\xeb\x88\x27\xc3\xe7\xe5\xda\x71\x3f\xb3\xa2\x1e\x7d\xe3\x51\x0c\xc2\xeb\xc7\x79\x55\x2f\xe7\x8b\x2c\x45\xf1\x32\x7b\x7b\x38\x11\x58\x39\x3c\x43\xa5\xbe\x9f\xe7\x1b\xa9\x42\xca\x8b\x70\x26\xdc\xab\x42\xbb\x46\xa2\x1f\xa0\xac\xca\x56\x5f\x34\xc5\x36\xcd\x22\x81\x86\x46\x1c\x04\x52\x9c\xa1\x1b\xf3\x24\xb2\xfe\xc9\x73\xc3\x84\xc3\xb2\x3f\xb8\x92\xed\xee\x98\x9d\xeb\xab\x0f\x3b\xa7\xba\x61\x89\x31\x38\x2d\x61\x67\xd0\xfd\x2d\x8d\x25\xf1\xe6\x53\x95\x78\x2e\x8b\x89\x2e\xd7\x74\x69\x88\x04\x4f\x63\xf7\xa9\x7d\x15\x95\x56\xed\x79\xe4\xe7\x45\x23\x21\x13\x6c\x43\x66\x8f\xbb\x51\x69\x24\x12\x4a\x20\x4e\xe7\x2a\x73\x2d\xa8\x7e\x03\x04\xe8\x05\xd4\x5d\xb3\xc8\x1f\xca\xea\x64\x03\x9a\xdf\xc9\x50\xfd\xf6\xdf\xe9\x2b\x21\x59\x88\x4d\x9a\x1f\xd9\x2b\xbc\x6c\xcb\x63\xd6\xfc\xc8\xe4\x51\x7c\x8c\xd7\xb5\x48\x51\xeb\x00\x50\x37\xe2\xd9\xc6\x44\xf7\xed\xac\xdc\x1e\x29\x43\x46\x8a\xc1\xdd\x34\xb5\x80\x58\xa1\x91\x0e\x5c\xb7\xfd\x19\x76\xd0\xa0\xf0\xc2\x93\xa8\x9a\x1e\x48\xe2\x86\x41\x6c\x57\x92\x2e\x48\x3c\x89\x06\x5c\x37\x6a\x56\xf1\x89\x0c\x49\xad\x2b\xbe\xd6\x13\xff\xe0\xc5\xfc\xbd\xdf\x47\x60\x33\x04\x59\xff\x65\xb5\x10\xd9\x46\x86\x47\x08\x1f\x3e\x0b\x54\x29\xf0\x7f\x05\xeb\xf5\x64\xaf\xb0\x0b\x38\xb2\xe2\x79\xae\x97\x41\xe3\x20\xd6\x58\x7d\xb9\xba\xdd\xef\x37\xeb\xb1\xe6\x04\x8d\x83\x84\x11\x57\x7b\xfa\x67\xd1\x5c\x18\x23\xd1\x38\x30\x31\xf6\x35\x6f\xeb\xab\x32\xcb\xa1\x9a\x40\x37\xdc\x18\x12\x58\xa9\x7d\xdb\xfe\x1e\xfb\x51\xd1\x98\x24\x04\x23\x77\x05\xdd\xb5\x2d\xcb\x43\xd3\x98\xa4\x02\x1f\x3a\x1a\xc1\x20\x05\xa5\x99\xdd\x88\x7f\x2c\xec\x45\xd3\x44\xf4\xb5\x2a\x67\xc1\xbf\x85\x3a\xd3\xad\xc8\xaf\x54\xd9\x9e\x87\x8e\x5d\x4c\x05\x63\x72\xe0\xb8\xa3\xc4\xe3\x00\x20\xa0\x31\x95\x29\x2e\x08\x4e\xcb\x4e\x9c\xce\x22\x7b\x2e\x66\x42\x88\x63\x3d\xd2\x0b\xb2\xc5\xc5\xbf\x6e\xdf\xc9\xad\xa2\xda\x60\xbc\x9d\xd5\xdf\x8a\xf2\xad\xf0\xd1\xf6\x62\x4c\x18\x33\xc2\x75\x77\xef\x31\x80\xb0\xa8\x02\x4c\x42\x3f\xeb\x02\xc7\x2c\x21\xa8\x9c\x92\x67\xa7\xac\xd9\xec\xbf\xfa\x8b\x0b\x79\x82\xdd\xa4\xb3\x68\x6b\x6b\x9a\x33\x7d\x48\xa1\x08\x26\xe0\x90\xcd\xbb\x1a\x7a\x00\x71\x28\x38\x57\x1e\xe6\xd7\x34\x39\xde\xb7\xb2\x9d\x2d\xcc\x71\x14\x87\x08\x5a\x5d\x6f\x1f\x7f\x5e\xef\x56\x77\x9b\xc3\xdd\xed\xfd\xad\x5f\x6b\xe2\x48\xc4\x38\xd5\x7f\xdb\xae\x9f\xdc\x33\x98\xcb\xf6\x2c\xdf\x85\x98\x30\xcc\xad\xee\xca\xe7\x2d\xc8\xe9\x32\x32\x27\x27\xff\x32\x45\x88\xe3\x30\x0e\x06\x57\xc1\x5d\x23\xd4\x8b\x8d\x84\x17\x5d\xfa\x87\xf7\x8c\x87\x1c\x6b\xc2\xa6\x02\x50\xe5\xe9\xd4\x16\x59\xf3\x31\x6a\xa6\xc5\x3c\x06\xc4\x0d\xfc\x58\x4d\x3e\x2e\x0e\xa1\xb4\xac\x42\x2b\x4d\x3b\x82\xd2\xb8\x11\x09\x8f\xc4\xd4\x4e\x02\xf2\x2e\xf4\xb7\x86\x1b\xb3\x1b\x9c\x00\xe7\xae\x57\x80\x7c\xf5\x2e\xb3\x1a\x84\xb2\x5d\xd5\x22\x4e\x03\x12\xca\x31\xed\xfe\x76\x36\x99\xc4\x69\x24\xb0\x9c\xbe\xed\x56\xca\xf1\x65\xa4\xa9\x24\x7a\xea\xcc\x68\x8f\x3f\x99\xe3\xe2\xd4\x50\x7c\x5b\x9e\xb6\x9b\xfd\xf5\xc6\x85\x88\xe8\xfd\x39\xd4\x91\x63\xc1\x18\x1e\x0b\x55\x47\xfb\x64\xc9\x6f\x14\x4c\xf9\x34\xf1\xbb\x35\x6b\x9e\x5d\xab\x0c\x09\xf4\xd6\xe9\xdf\x37\xfb\x7a\x50\xf1\xa3\xb1\xe4\x0a\x23\xaa\xb5\xa8\x8f\x7b\xc8\xe1\x7d\x72\xd7\xa5\x50\x9a\xf4\xa9\xca\x75\xd5\x5d\xe5\xec\x0e\xa0\xb7\x93\x87\x0f\x97\x55\xbf\xc6\xc5\x8a\x87\x88\xb1\x74\xd6\x28\xfb\x12\xa1\x4d\xb3\x08\x3a\x56\x83\x48\xd4\xd5\x6d\x3f\xc3\x4f\x86\xe8\x20\xc4\xe9\xc4\x01\x26\xc8\x1f\xfd\xdf\x15\x16\xb7\xe1\x94\x35\x3f\xcb\xea\x05\xe9\xa8\x9f\x7d\xce\x3a\x4e\xb1\x4b\xf1\x58\x80\x8b\x0e\xbf\x64\x5e\x95\x83\xc6\x5a\x13\x4c\xc3\xff\x33\x32\x12\x74\x9b\x0c\x70\x05\x83\xce\xd2\x0f\xa8\x1b\x2f\xa2\x76\x33\xc3\x46\x52\x1e\x28\x89\x37\xe3\xaa\x51\xfb\x63\x7b\x92\xbf\x25\x12\x77\xbb\x00\xfa\xef\x55\xda\x01\x98\x71\xb2\x1e\xf5\x0d\x79\xa0\xb9\x92\x63\xe0\x3b\xce\x61\x4e\xf4\x6e\xec\x3c\x32\xfd\xd8\x39\x09\x52\xcb\x0a\x13\xb9\x42\x8a\xc7\x13\x58\x68\xfd\xf2\x2d\xe2\x24\x14\xa9\x97\x48\xdc\xae\x66\x57\x46\x94\xc0\x4a\x7c\xd1\x9e\xee\x4b\xe4\x0c\xce\x9c\x3a\x29\xa7\xd4\x8a\xd8\x63\x23\xb8\xec\x0b\x3a\x9c\x32\x8d\x52\x84\x36\x71\x6c\x7e\x23\xfd\x3a\x0e\x96\x39\x35\x1c\x83\x65\xd9\x56\x45\xaf\xfa\xed\x50\x2b\xff\x25\x69\xe8\x57\xed\x60\xce\x12\x8a\x52\xea\xb2\xfd\xe8\x02\xd4\x5c\x7c\xa0\xc0\xec\x2f\xa3\x2a\xce\x64\x60\x15\xa0\xce\x50\x34\x4f\xa2\xaa\x41\xf5\xcf\x2a\x0a\x52\x4c\xba\x33\x0c\x79\xae\xb3\xaa\x57\x6b\xa3\x3c\x0a\x53\x9d\x7a\x72\x68\xf7\x89\xa3\xea\xe4\xf2\xb3\x88\x03\xbb\xca\xb8\xc4\x0c\x89\x79\x50\x5d\xe0\xa7\x26\x93\x09\x8f\x89\xa5\xae\xbe\x7c\x76\xd0\x48\xfa\x49\xef\x0e\x9e\x67\x7c\x66\x3f\x26\x8d\x51\x04\xa3\x11\xb2\x7e\x2c\xba\xa0\x7c\x8d\x3a\x2e\x43\xe4\xce\x79\xc4\x90\x39\x75\x14\x79\x53\x23\xb9\xab\xbf\x7c\xce\xad\xef\x86\x83\x0a\xd8\x90\x5e\x34\x70\x5b\xac\xa1\x57\x2c\xa2\x9c\x1b\x82\x14\x4f\x73\x49\xd4\xed\x36\xda\x3e\x33\x2e\xb0\x7f\x8c\xfc\x8a\xdc\xf6\x84\x01\x6a\xb0\xbe\x66\xf0\xb6\xf6\x16\x3d\x77\xd9\xab\x1b\x3b\xac\x35\x3c\x09\x53\x2c\xe7\xee\x5f\xca\x0b\x83\x39\x37\x24\xd5\x41\xe8\xf4\xe7\x74\xab\x9a\xf0\x50\xf7\x7c\x4c\xca\x45\x1c\x61\x38\x6b\x63\x42\x6f\xfb\x88\xe5\x18\x8b\xee\x9f\x9e\xb8\xe0\xa1\xd3\xa4\x68\x9c\x7a\xdf\x74\xbb\xa4\x8a\xea\x41\xb5\x72\x23\x2a\xab\x5a\xe9\x37\xab\x18\x43\x03\x55\x16\x26\x7b\x6e\x2b\x18\x81\x43\xfe\x31\x7d\xde\x93\x72\xde\x98\x8c\xd9\x1d\x85\x23\x9b\xc3\x94\x55\x93\x19\x2b\xf0\x50\xcf\xaa\xf5\x4b\x3e\x95\x94\x2b\x46\x39\xf4\x57\xfb\x00\x6f\xdb\x56\x42\x8d\x80\x10\x8b\x96\x9c\x5d\x8e\x26\x16\x00\x88\x6a\x16\x55\x0d\x26\xab\x60\x84\xff\xa4\x5c\xc7\x01\x52\xee\xb1\x54\x8f\xda\x6f\xa3\x6d\x9c\xd3\xc1\x77\xcd\x1f\xf9\x5f\x24\x20\xff\xf6\x35\x62\x0e\x9c\x79\x41\x14\xab\x24\xdf\x2d\x23\x5d\xd4\xfb\xa9\x8c\x01\xe5\x46\x31\xc4\x4c\x18\xbf\x4a\x24\x41\x14\x12\xf5\x09\xaf\x6a\xf2\xf9\x24\x41\xa2\x91\x00\x76\x9f\x15\xbd\x94\x04\x4d\x08\x35\x0e\x0a\x90\x3d\x3f\x4f\x1d\xd9\x68\x42\x98\x6d\xe8\x18\x80\xbd\x78\x81\xfe\xcf\x5d\x6e\x69\x67\xd2\xdb\xd3\xc9\xb7\x84\xa6\xaf\x5e\x42\x44\x80\x42\x1f\x37\xb6\x54\x26\x64\x3e\xe2\xbb\xb7\x8b\xdc\xdb\xd9\x01\x34\xc1\x1f\x57\x72\xba\x60\x24\x8c\xd2\x58\x0f\x1c\x58\x57\xfb\x5c\x48\x97\x12\x46\x43\x16\x4c\x14\x10\x2b\x03\xd9\x9c\xb3\x97\xcc\x7e\x38\x64\x56\x76\xb2\xbb\xbc\xe2\x35\x6b\x30\x93\x69\x3f\x9d\x36\xe7\x7b\x87\x0a\x61\x88\xdd\xb2\xfd\xcf\x52\x5a\x6f\xba\x2f\xd9\xeb\x6f\x08\x1d\x89\xdf\x3d\x22\xd8\xd2\x73\xd2\x4e\x37\x8f\xdb\xc3\x76\x73\xb3\xd9\xae\xee\xfc\xe5\x87\x42\x22\x2c\x06\xee\xfe\xfa\x9f\xeb\xfe\x8f\x4a\xab\xc8\x8a\x60\x7a\x49\xad\x49\x03\x3a\x89\xa8\xe5\xf7\xe0\xb4\xb3\x68\xbb\x48\x93\x28\x56\xd8\x82\x38\x57\x50\x97\xb9\xbe\xef\xeb\x9e\x49\x24\x68\x68\x05\x13\x1c\xf6\x0f\x1b\x0c\x77\x7f\x9d\xa1\x1a\x72\x87\x24\xd2\xc2\x20\xed\xbf\x34\x79\x66\xfa\xd7\x25\x36\x0c\x17\x86\x9d\x7d\xd1\x17\xb1\x73\x09\x4f\x28\x56\x5b\x5e\xb2\xa6\x81\x62\x1c\xc3\x25\xdc\x08\xee\xf1\x67\xd7\xd9\x6b\xb6\xe8\xe8\x31\xbd\x92\x44\x48\xaf\x67\xd4\x7d\x51\x4e\x72\xec\xde\x8a\x61\xdf\xf6\x47\x4e\xc0\x56\x18\x8b\xf2\x6d\xac\x2b\x4f\x93\x94\x5b\xcb\x8e\xba\xe9\x8d\x32\x69\x92\x0a\x6d\xc4\x08\x9a\x32\x14\x54\xe6\x78\x64\x9a\xa4\x5a\x22\x07\xd8\x74\xc1\xf1\x50\x33\x9c\x15\x1e\x12\x11\x59\x8f\x66\xab\xc9\x04\x0a\xb2\x73\xf3\x54\x95\xa5\x99\xa9\x45\x0d\x99\xe4\x05\xa4\x35\x11\x29\x89\xac\x23\x40\x9e\xd7\x27\x51\x37\x68\x8c\xe0\x4f\x5a\x38\xe3\x29\xa1\x7d\xdb\x7c\xa9\x2b\x9b\xc8\x90\x61\x37\xe6\x39\x33\xcd\x5a\x54\xcb\xc6\x53\xdd\xb0\xc8\x2f\xb1\x43\x7f\xed\xea\xc3\x2d\x72\xc9\x6c\xc6\x91\x06\x26\x20\x5a\xcb\x91\xda\x89\x13\xdc\x9e\x4d\xfd\x55\xd4\xc7\x55\xa1\x1f\xca\x61\xde\x4c\x14\xe7\x81\x98\xcc\x89\xf8\x71\x3f\x4d\xdd\xa2\xfc\x60\xd0\x58\x52\xbf\xde\xdc\xfb\xc5\x3b\xd1\x2c\x11\xbd\x48\xd8\xed\xc3\x97\xc3\x6e\xb3\xb9\xde\xf5\x5b\xa3\x18\x4b\xa4\x77\xe5\xf3\xbd\xd3\x26\x58\x6c\x95\x24\x5a\xc6\xa1\x25\x50\x59\x15\xb6\x3f\xe6\x9b\x15\x7e\x4c\xcf\x95\x28\x1a\xdb\x87\xbd\x29\xc7\xda\x71\x34\xd1\x40\x11\x13\xd8\x9e\x9f\xbb\x10\xa2\x7f\x89\x20\x0a\x2c\x14\xc6\xae\x92\xab\x42\xbb\x36\xec\x94\x31\x48\x13\x70\x89\xe2\x16\x74\xab\xb0\x42\xdf\x25\x4f\xa3\xf2\x5b\x02\x42\x26\xd1\x44\x7f\xdf\x5a\xd0\x81\x23\x00\x11\x7f\xba\xa0\x52\x67\x1a\x5c\x9f\xcb\x42\xef\xcb\x75\x6f\x74\xe6\x5f\xac\xf4\xdf\x53\xe5\xb1\x7f\xfd\x5f\xfd\xf7\x1c\x03\x96\x98\x88\x23\x37\xe2\x76\xfd\x68\x1d\x06\x45\xe5\xe3\xc4\xc4\x24\xc4\x23\xbc\x9e\xc4\x87\xea\xc2\x84\x46\x0c\x1b\x01\xf3\xee\x4c\x95\x37\x6d\x31\xba\x6f\x26\xd5\x86\x0c\x72\xab\x3f\xac\x42\xc6\x1e\x1d\xd4\x07\x7c\xd0\xdc\x78\xc1\xee\x9c\x06\x2c\x46\xd4\xf7\x39\x17\x1f\xd7\x99\x82\x75\x79\x92\x8e\xd5\xf7\x6b\x55\x6d\x9a\x06\x3a\x46\x19\xe5\xf3\x3c\x1e\x4a\x89\xd0\xd8\x12\x7e\x28\xbb\x48\xe4\xe0\xca\x24\x4b\x70\x9b\x94\x48\x0b\xfd\x5a\xb5\xcd\xf1\x5a\x9c\xcf\x53\xb5\x8a\x7f\x8c\x82\x95\x51\xc4\x92\x12\x6d\x30\x52\x14\xc6\xb8\x9c\xee\xe0\xee\x46\x4a\x69\x88\x7d\x5e\x74\x69\xed\x3e\xad\xee\x4b\x19\xdf\xe5\x94\x0a\x81\xa1\xea\xbd\xaa\x6e\xca\xea\x8b\xa8\xed\xa8\xe5\xf7\x3d\x65\x81\xc1\xab\x94\xa2\x86\xef\x45\xd6\x1f\x85\xb1\x04\xe3\x7d\x55\xfe\xfd\x31\x46\xc9\x2f\x2f\xd9\x29\x33\x2a\xb0\xd5\xbd\xe6\x4a\x14\x2f\x28\x2e\x54\xa8\xec\x2c\xf2\x05\x1a\x1d\x4d\xc3\x80\xba\x67\xda\x85\xae\x5f\x2c\x9c\xaf\x7b\x5f\xea\x45\xa6\x35\x4d\xc3\xd0\x9a\xa6\x1f\x10\x00\xb1\x83\x42\x8f\xcb\xe0\xdd\x66\x2e\x7a\x6c\xeb\x57\xa7\xc1\x0a\xe7\x5f\xad\xf6\x69\xa8\x2c\xcd\xa1\x4b\xeb\x56\x0f\x13\xed\x6f\x37\x22\x0a\x8d\xb1\x58\xcd\x05\xe5\x88\xd1\x4c\x9c\x46\x91\xd4\x8e\x5c\xd0\x4d\x57\xbd\xa2\x37\x68\xa7\x51\x32\x7a\xb8\x31\xb3\xc4\xd4\x1e\x82\x59\x96\xb3\xe0\x3d\x8d\x8d\x0d\x22\x0f\xb2\xfd\xb8\x13\x48\x56\x5a\x8b\x42\x7f\x7c\xf2\x0c\x39\xb5\xe5\xd3\x1a\x0a\x8d\x40\xa6\x4f\xf1\x9b\xbe\x0b\x9b\x72\x23\x50\x76\xff\x7a\x73\xb3\xfa\x7e\xb7\x3f\x5c\x7f\xdf\xae\x06\xd9\x43\x9a\x26\x91\xed\xaa\x98\xd2\xf7\xf4\xd2\x94\xb2\xc0\xb5\xb6\xd7\x2e\x79\x9b\xdb\x7d\xd0\x34\x4d\x12\x2d\x27\x14\xe9\x4d\x77\x9f\x3e\xe3\x3e\xa4\xa9\x60\xa9\x2b\x2d\x3f\xc0\x7b\xb3\x15\xc5\x0c\xba\x92\x8a\xb8\xa7\x04\x5b\x38\xf3\x74\xb3\x66\x11\x5e\x48\xcf\x72\x9f\x89\xe6\xd1\x54\xa7\xd6\x8d\xd5\xb2\x52\x11\xbf\x21\xea\x7a\x99\xb9\xb7\xac\xd2\x39\x3d\x1e\x24\x96\x4a\x54\x43\x73\x7b\x3a\x5b\x04\xf5\x88\x26\x3c\x4a\x62\x16\xa3\x71\x11\xd0\xd4\x43\x04\x6e\xaf\x0f\x28\x4b\x50\xce\x96\x19\x41\x22\x2d\xad\x4b\x9c\x8d\x5f\x6e\x55\x89\x28\xce\x91\x8a\x47\x37\x08\x30\xaf\xb1\xc0\xec\x4d\xa1\xeb\xdb\xe2\xeb\xd7\xfb\x7b\xbf\x9d\x86\x12\x21\x7b\x4f\x65\x3d\x5f\xfb\x27\x21\x80\xa0\xce\xe7\xe4\xec\x73\x0b\xc1\x58\xe8\x17\x98\x2d\x3c\xb3\xd9\xd9\xb1\x34\xc4\xba\x8d\xeb\xb5\xed\x5a\x5c\x07\xcd\xd0\x5c\xf9\x2c\x50\x9e\x3e\x7c\x11\x26\x8a\x07\x3d\x67\x04\x7d\x9d\xca\x1c\xe6\xdd\x90\xc9\xdd\x17\x61\x4a\x51\x5b\xe1\x64\xd5\x42\xbd\x5c\xfb\xec\x0c\x23\x88\x94\x17\x69\x71\x42\x4b\x93\x2b\x8e\x19\xf8\x4f\x7f\x73\x3a\xe7\xe5\xc7\x44\x3e\x81\x8a\x24\x61\xd8\xb1\xbc\x06\xec\xfd\x0e\x8d\x44\x91\x80\xc2\xe4\x50\x5a\x8d\xf3\xfe\x61\xa4\x91\xc2\x6a\xa5\xeb\x71\x76\xab\x93\xef\x14\x2d\x7f\xb5\x22\x8d\x03\x24\xbb\xa2\xab\x3e\x14\xfa\x26\x2f\xdf\x46\x95\x90\xe9\xab\xb8\x04\xa5\x24\xf1\xc5\x11\x15\x16\x10\x36\xb5\xaa\xca\xb7\x1f\xa2\xcd\x67\x13\x8b\x48\x13\x89\xba\xc3\xa7\x8f\x13\x34\xc7\xa1\xcd\x35\x7d\x1f\x84\xb1\xda\x5a\xae\x51\x3a\x17\x42\xa0\x42\xc6\x31\x12\x6f\x8f\xa2\x5e\x35\xee\x3b\x27\x57\x6d\xf3\x50\x36\xfd\x7f\xd3\x8b\xf2\xfb\xf4\x33\x50\x81\x44\xa4\x62\xd6\x45\xe7\xef\x7f\x4c\x8e\xaf\x98\x30\x4e\xd4\xa3\xb7\x19\xa7\x42\x85\x09\x26\xbc\x3a\xab\xc5\x38\xe2\x12\x4a\x45\xbd\x88\xd4\x14\x0f\x73\xe1\x41\x42\x85\xd6\x31\x1f\x27\xdf\xd5\x25\x90\x45\x68\xc3\xf0\xdc\xb0\x2e\xfd\x13\xb2\xb1\x7e\x23\x15\x40\x44\xc4\xdc\x74\x3b\x6e\x0a\xcc\x6b\x58\x93\x4b\x02\x0e\x64\xe4\x61\xfc\x24\xb2\x7c\x02\xd3\x9f\x3c\x00\x90\x0c\x13\xbd\x2f\xdb\xd5\xfd\x6a\xdf\xcf\xca\x32\x88\xad\xdc\x5d\x0d\xcd\xf5\xac\xa3\x2f\x03\xc5\x43\xc7\xee\xda\xec\xbf\xee\xcb\x39\xf6\x68\xf9\x1b\x94\x84\x0a\xee\x5d\xea\xa7\x5a\x27\x6e\x00\x35\x12\xf5\x2b\xc0\xf2\xdc\x36\xef\x59\x3d\x93\x90\xa0\x92\x71\x26\x6c\x72\x00\x1a\x49\x32\xee\xef\x61\xc8\xd1\x84\xe1\xe6\xf6\xe1\x6e\x75\x75\x78\xda\x6e\x76\xab\xbb\x4d\xbf\x95\x73\xe1\x84\x8a\xac\x60\xd4\xd5\xc7\x1e\x4e\xe7\x7c\x6e\xf9\x41\x65\x28\x64\xa8\x47\x20\xce\x4b\x6e\x24\x95\xa1\xd6\x5e\x36\xd2\x89\x1d\x78\xad\x87\x61\xed\x95\xb1\x8c\x90\xcb\x92\xd5\xd8\xdb\xf3\x31\xa6\xe4\x41\x82\xc8\xdb\xff\x69\x45\xd1\x64\xf7\xa5\x2e\xc7\x2f\x98\xe4\xd2\xca\xee\x0a\x8d\x60\x17\xe4\xe3\x2e\x2a\x35\xb8\xf1\x89\xd1\x58\xd8\xbf\xff\x6b\xdb\x3f\xbb\x34\xa1\x69\x34\x60\xed\x1e\xcd\x43\x59\x7c\xfb\x6b\x3d\x7b\x8a\x22\xe4\x56\xe1\x55\x14\x28\x7a\x3b\xdb\x1a\x49\xaf\xa5\xfd\x24\xd4\x8b\x78\x46\xdc\xfd\x64\x6a\x93\x22\x89\xb8\xbb\x0f\xff\x2c\xe5\x0a\x35\xe7\x87\x0b\x15\x22\x49\x7a\xe7\xa3\x2e\xbb\x5a\x7f\xbd\xf1\xdb\x14\x05\xe3\xc2\xf3\xd9\xef\x6a\x99\x20\xfe\xd0\xa2\x7b\x31\x4d\x7d\x34\xf8\xea\xe3\x3b\xb1\x7a\xae\x00\x2e\xbc\x9c\xe2\x70\x5e\xcd\x1d\x23\x6d\x06\xc0\xf9\xac\xea\xe7\xf2\x68\x69\x08\x97\x76\x71\x50\xe5\xeb\xac\x42\x9c\x2c\xcf\x29\xd2\x10\xeb\x29\x6f\x2a\x80\xbf\xbb\xcc\xc9\x06\x5f\x76\xab\x0a\x62\x83\x6c\xf3\xc7\x5c\x6f\xcb\xf3\xd8\xa7\x84\x2a\xc2\x04\x2e\x45\x77\x8f\xeb\x6f\xdf\x9f\x0e\x3f\x57\x77\x77\x1b\xdf\x95\x54\x4c\x6a\xd4\x0e\x3e\xbc\xfa\xbf\x84\x82\x51\x37\x89\xdc\x7a\x4e\xf5\x1f\x0b\x57\xa1\x42\x61\x01\x69\xab\xdd\xee\x69\xf2\x83\xa1\xf2\x25\x58\x50\x2f\xe7\xb2\x17\x38\xa6\x2a\x22\x21\xb3\xc2\xee\xf2\x5e\xbc\x40\xbd\x69\x8e\x1e\x1c\xbf\x18\x58\xd0\xc0\xef\x48\x03\x9c\x35\xd6\x47\x71\x3a\x67\x65\xd1\xe3\x91\x3f\xeb\x1d\xa9\x28\x8c\xa5\x75\x38\x3e\x75\xf9\x5a\x23\x9e\x21\xee\x4d\x6c\xa9\x8a\xa4\xa5\x9a\x76\x91\xca\xe0\xfd\x38\x3d\x02\x58\x21\x7b\x67\x60\x3a\xad\x60\x8c\xdf\x4b\x15\x99\x04\x91\x21\xf8\xed\xae\xde\x04\x9a\x66\x2b\x27\xa3\xb0\xf8\x19\xa9\x98\x68\x8b\x93\xe8\xde\xaf\x7d\x89\x15\xf9\x3f\x66\x43\x68\x14\x53\x1f\x94\xba\x1a\xe3\xd8\x48\x70\x39\xb7\x53\x71\x62\xa9\x3d\x56\x8f\xb6\x3b\xf0\xd0\x95\x54\x5c\x09\xec\x4a\xc2\x7b\x53\xd9\x85\xa6\xee\xbe\x45\x6f\x3a\x31\x25\x1f\x2b\x6e\x0c\x66\x3e\xfb\xf2\x0c\x23\x57\x2c\xaa\x12\xa3\xf1\x63\xcd\x0a\x6b\xb7\xf1\xb3\xac\x72\x3d\xf1\x2c\xfe\xe4\xe4\x44\x10\x59\x1e\x78\x0e\x62\x48\x25\xee\xc5\xf9\x3c\x3a\x49\x99\x24\x68\x0e\xf4\x9c\x19\xcf\xff\xe9\x37\xa5\x29\xb5\x49\xff\x98\x65\xf3\x09\xf2\xc0\xef\x23\xd8\x20\xf4\x32\xad\xba\x2a\x29\x29\x42\x43\x3c\x32\x52\xb4\xcd\x27\x55\x6a\xa5\x44\x8c\x19\xbe\xcf\xc6\x51\xda\xb0\x76\x74\x1f\x3f\x46\xda\x42\x4d\x56\xbb\xe2\x9c\x23\x49\xe0\x3d\x9e\xe5\xef\x4a\x07\x10\xf4\x48\xc3\x07\x78\xb3\xe2\xc2\xf3\x4b\x9a\x5c\x8a\xe6\x31\xa3\x56\x72\xc2\x85\x76\x9f\x9c\xac\x16\x86\xf6\x89\x01\xf1\xf8\xba\xac\xf4\xde\xe7\x54\x69\x69\xf0\xd7\x77\x1f\xf9\x64\x41\x50\x86\x5b\xc6\xe3\x51\xd4\x83\xb0\xed\x92\x0e\x30\x55\x26\x95\x18\xca\x3f\x95\xcd\x53\xd9\x08\x6f\x79\x4f\x75\x90\x12\xec\x84\x21\x73\x14\x1a\xa1\x17\x0c\x7f\xdd\x50\x12\x69\xcc\x07\xb1\xd1\x7d\x5b\xd7\x6d\xb7\x82\x20\xda\xed\x15\x2a\xf1\x0c\x53\xc0\x80\xa6\x0c\x42\xe7\xb9\xdc\x64\x45\x5b\xb6\xf5\x95\x50\x2f\xc3\xcb\xa3\x69\x44\x10\xa8\xab\xba\x45\xf0\x56\x95\xbd\xc8\x36\xd5\x8c\x87\x38\xb3\x8d\x0a\xe7\x3f\xb3\xe2\x22\x35\xd6\x21\x89\x90\x13\xb3\x3e\x66\x6a\xb8\x31\x3a\xa4\x80\xe0\x12\xdb\x57\xf7\xf4\x97\xd9\xae\x21\xc5\x09\x0e\xde\x55\xde\x6a\xf8\x79\x1c\xe1\xc3\xfa\x21\x76\xb2\x38\xbb\x20\x86\xf6\xc7\x37\x33\x70\xdd\x14\xdb\x36\x3d\x4a\x44\x63\xe4\xba\x1d\xaa\x0b\x8c\x9f\x8e\x18\xa0\x5d\x4c\x56\x64\xcd\xb8\x94\xa0\xa3\x38\x10\x4e\xfa\xe5\xfc\x58\x09\x95\x67\x7f\xf7\x37\x27\x92\xb6\xcc\xfd\xcf\x7f\xfa\x9a\xbc\x4e\x18\x47\x7e\x89\x75\x18\x18\x94\xf5\xbb\x2d\x80\x7e\x6f\x5d\x5e\x83\x8a\x3e\xcb\xcf\x36\x89\xad\x6b\xf5\x03\xbc\x5d\x97\x45\x79\xa9\x49\x3b\x3d\xef\x44\x03\x92\x8c\xce\x55\x79\xca\xea\x1e\x7a\xa6\x53\x16\x63\xa9\xdd\xd2\x06\xbf\x7d\xef\xff\xae\x08\xb2\x2e\xce\x15\x64\xaa\x3c\xe0\xbb\x3e\x78\x7f\x50\x2d\x62\x8b\xd4\xad\xa1\xb9\x87\xc6\x6b\xcf\xf9\x73\x98\xfc\xb4\x90\x04\xe7\xda\x53\x56\x40\xb6\xac\x3e\x49\xb5\x0c\xac\x24\xde\x33\x34\x28\x6d\xbe\xa0\xf6\x3f\xbb\x01\x92\xc6\xc6\x6a\x83\xdb\xf0\x62\xc9\xc7\xb5\x1b\xa5\x6c\x3f\xd3\xe9\x66\x2c\x64\x7d\x5a\x46\x09\xb6\xf2\x65\x05\xa0\x57\xef\x19\xfc\xa6\xc4\xd7\x85\x35\x78\xef\xaf\xf2\xb2\x9c\x70\x14\xb4\x4c\x81\x46\xbd\xb4\x22\x54\x5f\x2d\x58\xba\x0b\x6e\x47\x4c\x60\xad\x82\x10\xc3\x86\x6f\x59\x9e\x83\xde\x67\x79\xfe\x50\xbe\xf5\x1b\x53\x61\x46\xfe\xf0\xa3\xc0\x58\x2b\x6d\x64\x78\xd1\x55\xc1\xa5\xe6\x0e\x4c\xe3\x9d\xd8\xfc\x68\xd0\x98\x8d\x5b\xee\xfe\x35\xa8\xec\x24\x72\x92\xf8\xcd\x40\x53\xac\x9c\x76\x9f\xab\xb5\x03\x73\x5f\xac\xdf\x9e\xa4\xd2\x1b\x01\xe7\x90\xe9\xfe\xb8\x60\x98\x74\x2a\xea\x8f\xce\x9d\xad\xdf\xc9\x24\x09\x1a\xb7\xad\x74\x31\x10\x5f\x21\x10\x06\xc3\x53\x5d\xde\x97\xaf\x97\xf2\xa6\x93\xbb\x0b\x84\x1a\x6f\xe6\xe7\x88\x2b\xdd\xb2\xa0\x8e\x43\x91\xcf\x27\x65\x40\x38\xc1\x3a\xf5\x4e\x78\x6d\x71\x0a\x34\xd1\xda\xed\xbe\xcf\x9a\x36\x17\x59\x05\x87\x75\x79\x3a\x37\x70\x98\xb1\x84\x80\x0a\xc6\xc6\xb3\xd6\x16\xfe\x03\x6a\x08\x7b\x71\x3b\x0c\xdd\x0b\x51\x80\x4b\x39\x6e\xca\x6a\xff\x71\x9e\xb4\x25\x87\xa3\xb2\x30\x46\xce\xc3\xaa\x78\x7f\xcf\x7c\xa1\x1a\xc2\x38\x20\xbe\x19\xe4\xfd\xbd\x2f\x6c\x0a\xbb\x61\x8c\x8f\xe9\xac\x57\x48\x08\xfa\x5d\x7a\x0a\xa1\x4c\x90\x8f\x6c\x07\x7e\x77\x3d\x84\x4f\xcd\xe8\x28\x44\x94\x06\xf1\x18\x44\x33\x2e\x64\x40\x14\x69\xc1\x06\x18\x00\x3b\x0c\xc4\x04\x88\x74\x8a\x49\x8f\xa7\x34\x68\x4b\x5d\xe8\x37\x83\x0a\xc2\x41\xe8\x76\x31\xa1\x82\xc8\x00\xfa\xe1\x7f\x83\x8f\x2d\x9c\x73\xa1\x3e\xd3\x2d\x81\x98\xc6\x08\x65\x5f\x3f\x8e\xbd\x23\x28\xf0\xc4\x60\xae\xa4\xe1\xc7\x84\x3b\xe8\x36\x27\x41\x80\x12\x21\x59\xed\x5b\x97\x96\x6f\x33\x1b\x95\x10\xfc\x42\xd6\x1f\x12\xaa\xfb\xb6\xce\xd4\xe4\x37\x52\x23\x50\xe3\x64\xd7\xca\x11\x2e\x1d\x04\x35\xa9\xb2\x78\x0f\x63\x8d\x89\xe7\xc7\x15\x91\x4a\xc1\xc7\xf9\xaf\xd6\x4f\xca\x6f\xea\xb2\x74\x5c\x64\x91\x7c\xba\x7f\xbf\x20\xb2\x80\x50\x09\xb7\x55\x34\xd5\x56\x8b\xae\xa0\x14\x24\x09\x84\xe7\xcc\x5f\xb5\x85\x9e\x03\xfa\x40\x69\x93\x40\x6f\x95\x39\x60\x25\x41\x53\x89\x88\x00\x5d\xaa\x16\x71\x4b\xb3\x1d\xb5\x36\x48\x71\x7e\xb1\xf7\x24\x6f\xb2\x5d\xf6\x3c\x61\xd2\x80\x06\x15\x78\xa1\x9f\xa3\xa8\xb2\xe6\x03\x95\x6d\x2f\x94\x46\x00\x02\x11\x79\x10\x6d\x17\x31\x8f\xe0\xe6\x00\x4c\x20\xe8\xf9\xf1\x61\xd3\xff\xc9\x04\x09\xb8\x35\xf4\x4e\xa0\xdf\xed\x68\x3e\x33\x01\xb5\x85\xc9\x3e\x62\xe7\xbf\x85\x87\x2f\xbe\x53\x26\xe8\x42\x53\x37\xb3\x89\x4a\x7b\x63\xf2\x76\xa0\x6e\xce\x1a\x0f\x26\x50\x01\xba\x55\x8a\xe2\x19\xf2\xc7\xe2\x0e\x84\x86\x0a\x2d\x89\x26\x2c\x25\x13\xe8\x14\x63\x94\x4c\x95\x2b\xd9\xcd\xa9\x45\x3f\x99\x98\x40\x4b\x0c\x7d\x10\x83\xe0\x2d\xd5\xfd\x17\x4d\x87\x4f\x9a\xff\x7b\x9a\xac\xfe\x8b\xba\x8f\xdc\x10\xc6\x6d\x62\xf5\x26\xce\xdd\xe2\xe8\x8f\xcc\x14\x60\xf3\x79\x75\x7d\xbd\xdd\xec\x76\x13\x6c\xac\x61\x9a\xa3\x4c\x50\x05\x42\x1f\xac\xe7\x91\x5d\x10\x0e\xa5\x39\xf8\x65\xd1\x07\xed\x26\x24\x11\x7e\x98\xeb\xfd\x55\x29\x9a\x89\xbb\xf8\xe2\x3c\x62\xc2\x34\x00\x07\xaa\xcb\xa1\x3a\xf4\xc7\x49\x79\xec\x85\xff\xb1\xe5\xd4\x4d\x16\x3b\x55\xba\xf7\x99\xcc\xa0\x5a\x26\x34\x76\xd1\xdb\x43\xdd\x3c\x56\x17\xdc\x37\x13\x13\x91\xba\xe3\xf9\xe8\x0a\x71\x47\x38\x0b\x8f\xbf\x0c\x13\xc7\xb1\xb0\x06\xb3\x28\x3b\x69\x93\x28\x7f\x5a\x5c\x45\x98\x75\xdd\x64\xc5\x88\x0d\xe8\x36\x8a\x38\x46\xbc\x5f\x37\x9b\x55\x22\xab\xa1\x5a\x8b\x3c\xc7\xb4\xd0\x8f\x48\x24\x22\x96\x9e\x4a\x6f\x2b\xed\x37\x08\xdb\xf4\x5b\x97\x45\xdd\x54\xad\x6a\xca\x6a\x99\x5d\xef\xc6\xcb\x88\x25\x83\x6a\xfe\x8d\xe8\x76\xf8\x58\xd6\x80\x31\x32\x31\xe8\xf2\xb8\xcf\x8a\x8f\xaf\xed\x49\x5c\xc2\x42\x66\xe3\xc1\xca\x3b\xf7\x42\x4f\x30\x3c\x5e\x15\x84\xc9\xb8\x89\x84\x21\x2c\x16\xfd\x7a\x2e\xa2\x51\xd2\x60\xa9\xdc\xe5\xe6\xc8\x83\xaa\xc4\x09\x9a\x4f\x9a\x95\x46\x01\xf7\x5c\xe9\x27\x51\x35\xb5\xf3\xbe\xfe\x99\x35\xc7\xac\xd8\xa2\xe5\xd5\x2f\x83\x53\xa3\x03\x0b\xfa\xcd\xea\x7d\x95\x9d\x73\x70\x9d\xd1\xe9\x20\xa0\xb6\x0f\xfe\x0c\xcd\x4d\x89\x9a\xd5\x73\x26\xbd\x01\xc6\x30\x72\x78\xda\x6e\xd0\xe2\xac\xaf\x80\x1a\x90\x10\xa6\xbe\x50\x37\x6d\xbc\x77\xdb\x4c\x34\x32\x03\x6f\x91\x06\x31\xfd\x71\x13\x18\x0c\x6b\x1e\xe0\xcd\x22\x46\x47\x6a\x42\xd3\x27\x6b\x18\x43\x92\xda\x7f\xda\xd3\x79\x7e\x10\x2e\x98\xd5\xef\xff\x4f\x5b\x7b\x56\xc1\xba\x2f\xe4\xcc\xaf\xc6\x28\x6e\x6d\x0c\xbb\x7c\xe5\x93\x06\xa7\x31\x46\xc7\x7e\x2a\x46\xe0\xc1\x7c\x39\x61\x41\x90\xc6\x56\x6c\xd9\xe5\x3e\x59\x59\x74\xf9\x86\x4b\xaf\xfb\xe9\xdf\x85\x12\x2c\x20\x9c\x06\x83\xa7\xcd\xaa\xae\x4b\xd5\xc5\x2a\xda\x87\xe3\xbf\x9a\x5b\x59\x40\x79\xe4\x23\xe0\xc7\xb7\x7e\xf6\x63\x01\x15\x61\x24\xc7\xde\x27\xbb\xa6\x3c\x9f\x47\xdb\x0d\x47\x10\xe5\xb9\x2c\xf3\x49\xa9\x84\x05\x2c\xb2\x7d\xa3\x1f\xdf\x9f\xac\xca\xb0\xb7\xb1\xdb\xdf\x6e\xb6\xac\x1f\x95\x10\x99\x7a\x26\x41\x9e\xaf\xcb\xb6\xaa\xe7\xb7\x82\x29\x0b\xf7\xb7\xb2\xc3\x88\xc6\xdc\x97\x9e\x8d\x53\xf7\x47\x52\x11\x13\xd3\x5c\x76\xff\x56\x62\x5f\xd8\x8d\x08\x25\x43\x27\x06\xfb\xf9\x6a\x67\xa6\x3b\x7a\x0f\x58\x10\x1a\xa3\x7a\x03\x70\xb8\x5d\x6f\x16\xe3\x30\x16\x44\xa9\xc2\x77\x5f\xb6\x1f\x2e\x6a\x1b\xa3\x69\xdc\xa0\x38\x61\x68\xa4\xf6\xb4\xbd\xfd\xb1\xda\x6f\x0e\x73\x06\x04\x0b\x62\x25\x53\xdf\xcb\xbd\x86\xd7\x31\x95\x9b\x05\x9c\x44\x3e\x24\x7e\x68\x4f\xee\xb9\x7f\xaf\x41\xdf\x0c\xd8\xea\x5f\x3f\x55\x4e\x12\x44\x27\x35\x50\x37\xb7\x0e\xe4\x5b\xf5\x87\xe7\x8a\x78\x51\x92\xf7\xf3\x0c\x24\xc6\x02\x6e\x62\x39\xbe\x9d\x3f\x65\xf3\xb9\xe2\x18\x0b\x12\x0a\xa9\xa7\xbb\x43\xf5\xd8\x36\xe7\xb6\x59\x35\x5d\x7e\x34\x3d\xa5\xc4\x44\xf8\x42\x19\x91\xe7\x52\xa8\x97\x8b\x2b\x98\x1e\x56\xa4\x56\xd6\xcb\x33\x3b\x91\xe9\xba\x3e\x8a\xa2\x80\x0b\x4c\xcf\x6c\x57\x19\xc4\xd6\x15\x24\xb7\x66\x1b\xcd\xe4\xe6\x4a\x92\x50\x70\x77\xfe\xc7\xc3\x66\xff\xc9\x65\xc9\x24\xc1\xda\xc9\x49\xbc\x3b\x6c\xc6\x13\x54\x36\xf2\xee\x8f\xa4\xac\x2a\x3a\xe6\xa1\xdd\xec\x89\x97\xe4\x4c\x0c\xc2\xc0\x8f\x32\xa1\xb6\xd6\xd7\x1a\x36\x79\xf6\x9c\xc9\xe1\x4b\x51\xdd\xff\xf9\xea\x70\x17\xb2\x2e\x27\xcf\x2c\xd0\x01\x20\x99\xf7\x7c\xcc\x86\xbc\x94\x05\x5a\x18\x3c\xf6\xc1\x26\x4f\xcd\x87\xcf\x28\x71\x9e\x9b\x5e\x90\x36\x04\x95\xfb\xf2\xf2\xb9\x37\x9f\x5e\xbe\x74\x6d\x22\xb4\x3d\xfa\x3f\xab\x5b\xff\x43\xa0\x03\xe4\xa6\x7c\x81\xe6\xad\x1e\xec\x3a\xdc\x56\x13\x5a\xc6\x96\xd3\x55\xdf\xde\x4e\x3e\x2d\x12\xd0\x44\xdb\xf8\xbb\x46\x2a\x89\x2b\x18\xd4\x8b\x52\x1e\x8c\x04\x11\x41\x0a\x5c\x03\xe2\x64\x0b\x75\x63\xa3\x81\x6e\x3b\xc3\xea\xff\xc3\xc3\xbe\xff\x93\x4c\x11\x97\x61\x9d\x5b\x50\x2d\xfc\xb2\x18\xbe\xa4\x4f\xc3\x08\xd1\x41\x98\x8e\xe9\x4e\xb3\x2e\x28\x23\x54\x87\x71\xe2\x5e\x98\xa7\x5f\x7c\x09\x84\x1a\x83\x39\x4c\xaf\x50\xfd\xb9\x0b\xd6\xff\xdf\x7f\xdd\x2f\x85\x94\x0a\x35\x2e\x8f\xcd\xe4\x01\x66\xa3\x99\x81\x68\x40\xad\xac\xc5\xf9\xb3\x81\x91\xed\xef\x1d\xda\xe2\x2c\xd4\xcb\xaa\x69\x84\x7a\xc1\x60\xa2\x9e\xdd\x93\x30\x4e\xb0\xcd\x79\x86\xe7\xcd\xfe\xeb\xf7\xdd\xf5\x6c\x7b\xc4\x12\xe6\x0b\x1f\xd9\x7b\x97\x72\xda\xee\xce\x62\x57\x67\xfa\xae\x93\x28\x64\x4e\xd1\x7d\xdc\xd9\xf0\x1b\x23\x8a\xa5\xda\x3f\xdb\x7c\x0a\x36\xfe\x1d\x99\x94\x91\x28\xa5\xc2\xd9\x96\xff\x35\x92\x27\x66\x24\x12\x01\xd6\xb2\xbe\x6d\xfb\x17\x2a\x4e\x7d\x7d\x13\x01\x75\xf3\x5f\xf8\x57\xf8\x6f\x3f\x50\x59\x05\x69\xfb\xea\xf7\x0c\x98\xe9\xdc\x47\x38\xe3\x3c\x1c\x9a\x82\xfb\x63\x05\xf5\xb1\x07\xc0\x32\xc2\xc3\x18\x1b\x9f\x96\xaa\xfc\x15\x44\xd5\x1c\x77\x4d\x2f\x51\xc7\x08\x8f\xa8\x0a\x26\x40\x86\xea\x9f\xa5\x9c\x3e\xf0\xc4\x8d\x4d\xa8\xb5\xb2\x7e\x06\x04\xca\x5c\x36\x51\x19\x49\x89\x61\xc4\xe5\x18\x3f\x21\x37\x83\xf5\xd8\x7c\x20\x55\xbe\xcc\xa7\xda\xaa\x7a\x68\x4f\x8f\xc6\x2d\x7b\x7e\x42\x25\x69\x4c\x12\x77\x5f\x57\x79\x7e\xff\xe1\x5a\x96\xb7\x7a\x18\x91\xa4\xf8\x61\xec\xab\xb2\xf8\x32\xba\xec\x54\x04\xd8\x46\x40\x49\x98\x34\x99\xff\x36\x58\xda\x94\xe8\x82\xc7\xb1\xea\xbb\xdf\x5d\x04\x29\xc2\x86\x1f\xab\xf3\x11\xda\x7a\x5b\x7e\x88\x7c\x97\x89\xd3\x56\x64\xf9\x9b\xf8\xe8\x7f\x5e\x68\xae\x9d\xb2\x21\xfc\xd5\x4b\xb9\xb8\x8d\x92\xa6\x48\x8f\xfa\xb2\xba\xdf\xcc\xe0\x51\x8c\x48\x49\xb1\x4a\xf3\xe7\x66\xdc\xd5\xeb\xfe\x9e\xa0\xb8\xc5\xd9\xae\x0c\xfb\x72\x2f\x5e\x60\x55\x6f\x7b\x08\x3d\x23\x2a\x90\xb1\x6d\x4f\x58\x7a\xe3\xe9\x9c\x43\x33\x6c\x8d\x28\x46\xbe\x0e\x26\xb0\x73\xe9\xc9\xda\xa2\x84\x10\xaa\xe0\x47\xc6\x49\xe4\x80\xd9\xdd\xbb\x8e\x4f\xd3\x7e\xed\xde\xfb\xd2\x0f\x84\xd4\xbb\x40\x78\xef\x93\x2f\x55\xd9\x9e\xeb\x61\x80\xc4\xef\xca\x4b\x83\xae\x9a\x06\x0a\x0d\xc3\x83\xd4\x81\xa5\xdf\xe0\x87\x75\xd3\x16\xfa\x7a\xf5\xf8\xc7\x67\xc4\x2f\x46\x34\x0b\x52\xa7\x41\xe5\xa8\xab\x43\x74\x32\x7d\xfd\x35\x13\x56\x18\x4f\x7c\xcc\x83\x37\xa2\x19\x60\x66\xd5\xad\xb3\xad\xcc\x33\x35\x54\x10\x18\x81\x20\xc2\x20\xf3\x7f\xdb\x4c\xbd\xac\xcb\xe2\x15\xaa\xde\x4c\x8d\x11\x88\xa1\xc7\xc3\xd9\x5b\xb2\x2f\x77\x56\x02\x6c\x76\x02\x86\x45\x6c\x50\x2c\xb9\x2a\x17\x95\x8d\x19\xe9\xd6\x3d\xdd\x1b\x33\x77\x27\x32\x53\xfd\xf6\xe3\x84\xad\x2e\x78\xf5\xc2\xf1\x6d\xa1\x01\x21\x88\xfb\x6a\x0b\x6c\x4f\x43\x17\xbb\x6f\x41\xc1\x39\x83\xa2\x19\x89\x3d\x31\x1a\x84\x29\xd6\xf8\x95\x6d\x2d\x8d\x30\x26\x57\x1f\xf7\xa0\x33\xd1\x94\xd5\x45\x7a\x40\x03\xc5\x29\x9f\x5a\xf4\x75\xbb\x5c\x0e\x24\x01\x60\x3d\xd8\x79\x20\x8e\xea\x85\x8c\x92\xc4\x3a\x6b\x63\x9f\x60\x2a\x90\xee\x47\x68\x65\x45\xa4\x8f\xe5\xdb\xc8\x55\xe4\x27\x64\xb3\x81\x94\x12\x44\xe5\x1c\x0a\x78\xdb\xc2\xd9\x0b\x72\x4f\x27\x5f\xca\x38\xd7\xce\xd6\x0c\x5e\xcb\xcc\x0a\xf3\xcb\x45\x9b\x82\x8b\x3d\x2d\x38\xd3\x99\x32\xd9\x88\xc0\xc1\x3a\xa6\x17\x1c\xd2\x18\xb1\x59\x0e\x12\x33\xfe\x62\x69\x18\x07\xd8\xdb\x77\xf7\x7a\xd7\x88\x17\xb8\xe4\xfb\xce\x8e\x27\x62\x04\xa3\xfa\xa2\xcb\xae\xcc\x75\xf6\x19\xe5\x8d\xd1\x48\x00\x06\xfd\x12\xf2\xb2\x78\xae\xf7\xe5\x05\xa2\x9d\x21\xe7\x5b\x0f\x4b\xf1\x60\x1a\xed\xb6\x27\x4c\x27\xac\xd7\xa2\x15\x85\x5e\x24\x72\x30\x9a\xc4\x76\xa5\x86\x57\xa8\x3e\x48\xe4\xaf\x32\x65\x91\xf6\xf5\xbb\xf6\x03\x2b\x2a\xdd\x12\x50\x5f\x7d\x5c\x28\x60\x33\x9a\x42\x88\x2a\xe3\xe8\xac\xea\x3e\x88\x4f\x34\xa9\x67\x8f\x44\x78\x2e\x01\xce\xf8\x3b\x74\x3b\xa9\x6f\x4a\x5b\x9d\xf8\x63\x3e\x56\xf1\xc1\x39\x66\x5d\xbe\xcc\x4f\x43\x44\x81\xe9\xf3\xc0\x8b\x67\x2a\x62\x0b\xac\x6e\xca\xef\x59\xd1\x4c\xbf\x34\x91\x24\x02\x06\xe8\x88\x97\xc3\xb9\xce\x9e\xa1\xbe\x90\x6a\xef\xf7\x01\x8b\xe0\x2d\x4f\x70\x8f\xd8\x38\xf2\x3b\xc1\x18\xbf\x67\x6a\x0d\xd7\x75\x79\x40\x56\xc0\xa1\xf9\x45\xcc\x45\x85\x10\x89\x2b\xd7\x3f\x88\x13\xfc\xac\xb2\x06\xd9\xd7\xd3\xc7\x2d\x93\x38\xe9\xed\x1a\xca\xca\x4d\xa3\xdd\xd4\xdb\xe3\xdc\x7f\x99\x25\x51\xb4\x87\x71\x65\x36\xef\x5b\x31\x9b\xd5\xa8\x52\x31\x26\xd1\x96\xd2\x79\x53\x56\x84\x3a\xbf\xc9\x5f\xa6\x51\x54\x81\x24\xe1\x48\xc1\xe9\x76\x9c\x7e\x2e\x86\x6e\x54\x27\x09\x96\x40\xec\xf2\xe3\xe0\x2c\x0b\xca\x3d\x8c\xea\x34\xf4\x5a\xa9\xa6\x74\x73\xdf\x7f\x47\xaa\x65\x54\x03\x30\xd1\x9b\x23\x1f\x10\xbd\x77\x10\xa7\xf1\xfc\x06\x24\x46\xca\xf8\x76\xf3\x3f\xdf\x37\xbb\xfd\x61\xbd\x7a\x58\x6f\xee\x36\xd7\x87\xab\xbf\x0e\x77\x9b\x87\xeb\xcd\xf6\xb0\xdb\xaf\xf6\xdf\x77\xfd\x0e\x54\x62\xdf\x11\xc1\xe9\x28\x68\xbe\xc5\xb5\x42\xcf\x6e\x26\x40\x94\x12\x57\xfa\x72\x16\x23\xd6\x8f\xed\xb3\x4f\xe6\x93\x07\x67\xe2\x34\xf4\x12\xff\xc5\x33\x2a\x84\xb7\x17\x61\xf9\x7c\x1f\x19\x81\xf0\x20\xea\xb7\xde\xba\x7a\x4c\x6c\x62\xd4\x98\x10\x4f\xb0\x5b\x08\x7b\x09\x4b\xb7\x11\x73\x2b\x3e\xd2\xd9\xb4\xab\xe6\x35\x52\x2d\xec\xbb\x73\xd7\x4f\x99\x8c\x44\x12\xc5\x03\x36\xa2\x76\xcb\x36\xf5\x13\x0d\xa3\x49\x82\x48\xb9\x6e\x71\x5b\x39\x85\x9c\x71\xcf\x81\xb1\x6e\xae\xc3\x1a\xc6\x31\x43\x40\xcb\xa0\xd2\xd3\x6d\xe3\xcc\xa1\x79\x1e\xe0\xbd\x59\xa4\x2c\x2f\xde\x02\xc6\x62\x15\x8c\x35\xc3\xbc\x4e\xdf\x6e\x54\xf8\x9e\x81\xcf\x19\x0b\x03\x6b\xd1\x7c\x57\x22\x52\x0c\x46\xb6\xfe\x89\x1f\x12\x5a\x68\xb4\x7b\xad\xf7\x16\x06\x32\xff\x5e\x59\x08\xb6\xd3\x73\x16\x1f\x57\x1f\x9b\x4a\xd1\xe0\x8f\xd9\x4f\x81\x48\x8c\x77\x7d\x6e\x60\xa5\xbb\x88\x25\xab\x11\x35\x77\xd1\x3c\x64\x2c\x0a\x2d\x86\xe5\x70\x76\x91\x89\xf5\x60\x9c\x8f\x32\x36\xf9\xde\x7e\xfb\x32\x5e\xd3\x58\x9c\x32\x6e\xad\x40\x27\x82\xd9\xd3\x6f\x92\xc5\xa9\x0c\xb4\x87\xd6\xcc\x8c\xa3\x97\x6f\x72\x0c\x1c\xa3\xde\x87\x52\x42\x3e\xf9\xc5\x24\x90\xdc\xa5\x03\xd7\x60\xa0\xa8\x2f\xe4\x38\x67\x87\x4a\x48\x62\xfa\x94\xb8\xc4\x8e\x83\x9b\x41\x68\x7f\x4c\x9a\x70\x97\x3e\x7c\xdf\x5d\x8f\x08\xb8\x8c\x25\x69\x80\xf8\x60\xcc\x01\x1f\xe0\xed\xb6\x71\x53\x9c\x1f\x90\x52\x83\xc5\xcb\xa7\xed\x7a\x4f\x82\xe0\xb0\x3d\xec\x37\xab\x7b\xbf\x55\x84\x0a\x3d\xcd\x5c\x79\xf2\x57\xa6\x19\x8c\x89\x48\xa2\xad\xed\xf6\x6e\xfd\x34\xe2\x3c\x32\x26\xe2\x18\x06\x55\x2b\x3c\xbf\xcd\xf5\xe6\xcf\xd9\x33\x12\x89\x95\xe0\xb2\xe5\xaa\xaf\x90\x6b\x0b\x61\xf2\x9b\x05\xb7\x1e\x07\xa8\x36\x72\x95\xe9\xc9\x4a\xc6\x84\x61\x11\xbe\x07\xcf\x88\x6a\xbd\xb0\x43\xfd\xe4\x41\x49\x1e\xa3\xc8\x6f\xd5\x65\x1f\x63\x30\x17\x63\x52\x02\x46\xce\x77\xc3\xed\x50\x06\xb0\x2f\xf1\xad\xcc\x5f\x8e\xe2\x12\x58\xc1\x98\x96\x1c\x55\x24\x0e\x8e\x2b\xec\xcc\x33\xca\xb6\x2a\xc4\xa9\xd7\x36\x67\x4c\x9b\xd0\x6b\x6b\x62\x46\xb8\xcd\xd4\x8b\x25\xe3\xf4\xbf\x0f\xc4\x6a\x95\x5d\xed\xef\xd7\xfd\xdf\xc2\x40\xb0\x41\x0a\x78\x64\xd1\x37\x9c\x02\x84\x69\x68\xdb\xc4\x06\x75\x32\xcb\x62\xf6\x09\x1a\x69\x35\xa9\xcf\x55\x39\xe8\xd2\xb0\x30\x60\xda\x9a\x92\x14\xfa\x07\xf2\x24\xfa\x0d\x11\xb5\x9a\x43\xd6\x9f\x71\xf6\x7b\x21\x09\x18\x76\xf9\xf7\x50\x37\x23\x85\x2b\x16\x12\x99\x9a\xd8\x63\x4c\x3d\xc2\x69\xdc\xd1\xef\xbb\xe3\x2c\x64\x81\xc4\x1c\x12\x55\xe0\x91\xa9\x7f\x87\xa4\xa0\x79\x9d\xcd\x0f\x0f\x93\x84\xcd\x18\xdd\xfd\x3a\x37\x3a\x2a\x07\xec\xf8\xbb\x1c\x51\x5b\xe9\xfc\xe9\xa1\xc2\xc0\x36\x59\x46\x16\x70\xd3\x17\x21\x0c\x53\x2a\xf8\xc8\x67\xb3\xbe\xfa\x78\x3c\x4f\xc2\x84\x25\x78\x1d\x0b\x43\xa9\xf0\x05\xfa\x5a\x16\xdd\xf2\x50\x3f\x40\xf3\x56\x56\x2f\x78\x8c\x9f\x59\x05\xec\x8f\xd1\x40\xb4\x02\xdb\xac\xee\x86\x92\x8c\xdf\xa8\x34\x36\xa7\x4b\x63\xa0\x72\xbf\x6b\xf3\xb8\x7a\x4e\x28\x67\x61\x94\x24\xd2\xc6\xe8\x28\x79\x7e\x0d\xd0\x97\x10\xc2\x28\xd1\x98\x8e\x28\x91\xe7\x5b\x50\x19\x66\x53\x9f\xae\xb9\x93\xa8\xc1\xff\xff\xe1\xce\x46\x32\x42\x53\xb9\x43\xdd\xca\x6b\x91\x2d\xc2\xca\x58\x18\xa9\xc8\x9a\xe7\x95\x3b\x61\x60\x07\xc5\x32\xb7\x8e\x85\x31\x4d\xf0\xdc\x9e\x6e\xd6\xb3\x2b\xe2\x71\x68\x19\x0b\xe2\x65\x30\x3e\x41\x7a\xd3\x2f\xea\x88\x21\x37\x40\x1c\x2d\x62\xbd\xd9\x87\x0b\x5c\x7a\xff\x35\x84\x29\xb5\x4a\x64\x57\xab\xdd\x06\x6d\x21\x0f\xfb\xc7\xc3\xfa\xf1\xf1\x9b\xbf\x6f\x82\xda\xde\x88\x12\x95\xbe\x11\x0a\x5e\x7b\xa2\xbb\x5b\xfa\x42\x19\x0b\x97\x45\xa3\xbd\xe8\x3c\xac\x19\xdd\x36\x29\x18\xa4\x63\x4d\x8f\x53\x76\x59\x43\x9e\x5d\x8b\x0a\x12\xac\x3d\xc2\x3b\xa8\xb6\x97\x50\x63\xa1\xa2\x1c\x85\x12\x67\x14\x3f\x16\xaa\x30\x74\x21\x8a\xb5\xaf\xc0\x76\xee\x28\xfa\x0b\x55\x6c\xad\xf9\xac\x0b\x05\x8c\xf5\x63\xdc\x08\xed\xc2\x8b\xfb\xd5\x9f\x87\xf5\xe3\xfd\xfd\xed\xc0\x7b\x3b\xdc\x3e\x1c\x76\x9b\xf5\xe3\x83\xa7\x0c\xb3\x50\x0b\xc2\x2d\x57\xe0\xaa\xad\x86\x06\x58\xa8\x25\xb1\xd5\x90\x9d\xd7\xa8\x9a\x06\x53\xa1\xd6\x04\xe1\x97\xae\x08\x74\xa8\x40\xbb\x6a\x81\x1f\x00\x94\x5a\x3a\x43\xf1\x0d\x3e\xea\x2d\x2c\xdb\x5c\x77\x03\xa5\x1a\x8c\x95\x6d\x93\xe1\x67\xf6\xd9\xeb\x01\x31\x20\x94\xef\xb1\xc8\x3f\x46\x93\xcd\x85\x1f\xb3\x1f\x6e\x52\x61\xe6\xd1\xb2\x6e\x27\x0b\x69\x68\x88\xc1\xd0\xf2\xbb\x2b\x5a\xb8\x98\xfd\xd7\xcf\xd6\xc4\xd2\x6b\xc5\x3e\x55\x3d\x7c\x92\x85\x86\x27\x56\xee\xd4\x3a\x11\xc2\xe4\x5d\xbf\xe0\x2a\x8e\x5a\x99\xa1\x49\x62\x54\x81\xfe\x51\x8e\x17\x6a\x6c\x66\x2c\x10\x68\x58\x68\x64\xa4\xec\xdb\x5d\x94\x45\xf6\x37\xe8\xbe\xf3\x3d\x60\xdc\x58\x14\x04\x3c\xb4\x5d\x44\xd3\x16\xfa\xae\x54\x2f\xa3\x60\x34\x0a\x88\x31\x56\xda\x53\x83\xf3\x53\x59\x9e\x10\xa2\x80\x46\xd8\x37\xb3\xc6\xb1\x9b\xe6\xe8\xb3\xe5\xc5\xdb\x13\x05\x89\x8e\x92\xfe\x67\xbd\xa0\xe3\xec\x90\xd2\x45\x1d\x65\xad\x84\xe5\x3d\xb6\x9f\xc2\x10\x58\x44\x18\x61\x56\xa9\xb4\x5b\xfb\xf0\x5c\x2f\xea\x3e\x11\x31\xda\x53\xf8\xbf\x88\x1a\x03\x96\x27\xd5\x3c\x1a\xeb\xb5\xd8\x2e\x0c\xf7\x25\x89\x2b\xd1\xa8\xa3\x6b\xe6\x7f\x06\x5d\x63\x11\x25\xd2\xfa\x4c\x97\xf9\xcb\xa0\xea\xce\x22\xaa\x05\xb8\xe0\xd0\xa6\x02\xa3\x32\x66\x44\x8d\x44\x7a\x27\xa6\xce\xd6\x54\x20\x2b\x9e\x17\x61\xde\x6e\x0f\x26\x92\x74\x90\x73\xb1\xf2\x65\xcb\x21\x6e\xc4\x14\x45\x4e\x50\x5b\xa0\x84\x96\x25\xc9\x0f\xab\x50\xc4\xb4\x44\x89\x04\x6c\x20\x3f\xe5\x6d\x3d\x08\x9d\xb1\x28\xa4\xca\xce\x44\x96\xc6\xfe\x0c\xdf\xcf\x7f\x2c\x3e\xcf\x30\xb1\x86\xeb\x35\xa0\x32\xf7\xeb\x72\xd9\x2d\x8a\x02\xab\x6d\x67\x75\x01\x46\x70\x3a\xbf\x5d\x92\x00\x41\xd9\x0f\x99\x82\x2f\xed\x47\xff\x77\x10\x9e\x2f\xba\x69\x8e\xd8\x27\x70\x22\x90\xf6\x6e\x2e\xa2\x4d\x58\xc4\x43\x5b\x3e\x39\x8b\xaa\x29\xa0\xa2\x87\x2e\x54\xf3\xc7\xe4\xb1\xe5\x01\xd6\x4e\xb7\xbd\xfe\xc4\x63\x8a\x45\x9c\x5b\x4b\x4e\x34\xe1\x9a\x39\xaa\x0c\xdf\xeb\xb0\x18\x44\x3c\x49\x51\x2c\x0b\x2b\x71\xfe\xf7\x92\x50\x27\xde\x1e\x5c\xbc\x4f\xfa\xf5\xfd\x10\x65\x6d\x03\xb3\xda\x8a\x18\x8e\x5c\x4b\x58\x94\x0a\x2a\xc2\x11\x97\x62\x52\xf5\x5f\x7e\x4d\x44\xa8\x51\x99\xf7\xba\x95\x22\xfb\x52\x01\x14\x58\x63\x5d\x1f\xc5\xf0\x88\x55\xe0\x48\x14\x9e\x3d\x52\xb6\xd5\x48\x8d\xca\x8f\x62\x14\x6b\x29\x45\xf9\xda\x9e\xa6\x51\x54\xa4\x84\xc4\x22\x64\x9e\x35\xcd\x3a\xef\x62\x8f\xdb\xfe\x81\x6a\x62\xb9\x0b\xdb\x0d\xda\x33\x4f\x8c\x95\x59\xa4\x95\x49\x5d\x37\xa6\x0f\xd2\xfa\xc3\x02\xb1\x08\xb9\xfb\xdd\x66\x3b\x9d\x79\x96\xbe\x7e\x30\x36\x8f\xed\x0e\x55\x65\x8d\x2d\xed\x35\xe2\x74\x9e\x5d\x88\x09\x2d\x15\x61\x0c\x9e\x3f\x95\x95\xce\x44\xee\xf2\xe5\x6c\x54\x58\xfa\xaf\x52\x8d\x38\xa0\x56\xb4\x4a\x43\xb7\x3a\xf9\x82\xff\x12\xbe\x88\xa1\xf4\x57\xe0\x30\xf7\x4b\x6a\x8a\xb3\xd1\x2a\xb6\xa5\x84\xac\x69\x3e\x2e\x3a\xd3\x93\x97\x3d\x26\x91\x95\xcc\xa8\xa1\x39\x88\x5f\xa0\xcd\x59\xcc\xe2\x60\x50\xbf\x74\x10\x6a\x16\x87\x8c\x01\x9d\x44\x30\xe5\x75\xd5\x3e\xff\x57\x76\xa3\x2c\x0e\x23\x1e\xa5\xa3\xb7\xd3\xca\xd4\xa8\xe6\x27\x7c\xb6\x06\xc4\x5d\xfc\xa5\xbd\xec\x6e\x7d\x5c\xc2\xd2\xb1\x38\x0a\xac\x39\xbf\x16\x85\x73\x30\xb1\x65\x95\xf1\x1b\x18\x47\x9c\x6a\x47\x45\xd9\x14\x7a\x5e\x27\x8d\x23\x6e\x52\xef\x61\x57\xbe\x0f\x16\x18\xbd\x31\xad\x1f\x27\x62\xfc\x5c\x0e\x35\x34\xdb\xac\x7e\xe9\x17\xcc\x4f\xaa\xda\x71\xa4\xc3\xfe\x61\xfe\xcc\x74\xdf\x86\x8f\xe3\x20\x04\x7b\x69\x73\xa1\x57\x16\xc7\x34\xa2\x96\xfb\xd3\x1b\xf0\x2e\x2a\xbf\xf9\xe1\x8c\x62\x3c\x7e\xab\xca\xc1\xac\x8e\xc5\xb1\x24\x68\xa6\x76\xd5\xe6\x2f\xe3\x32\x44\xcc\x63\x11\x58\x30\x6d\xf1\x0c\x3f\x8f\x99\x73\x4c\xf5\x4f\x6f\x98\xa5\x62\x0e\x8a\x0c\x1c\xa9\x55\xab\xb3\x31\xd2\x6f\xf9\x85\x4c\x82\x00\x35\x10\x6f\x35\x14\x4d\xd6\x7c\x58\x44\xd0\x6f\x0b\x7c\x7e\x6f\x12\x20\xd8\xf8\x54\x16\x5d\xf8\x7a\x38\x9e\x67\x4f\x2a\x21\xc0\x06\xfb\xcf\xc3\x99\xcd\xb7\x53\x6b\xc6\xd2\x64\x27\x38\x40\xa1\x0f\xa3\x7c\x2a\x4e\x22\xab\xf0\x2f\x33\xfd\x58\xfc\x2c\x0b\x3d\xdc\xf3\x24\xb2\x8e\xc2\x42\x6b\x4f\x14\x9b\xc6\x4c\x93\xc9\x24\x4e\x52\xcb\x79\x6a\xa0\x6e\x5c\x75\x66\x07\xcd\x43\xd9\x38\x23\xcc\x6e\xcd\x7a\x28\xc7\x9c\x19\x16\x27\x92\x60\x67\x59\x67\xb5\x6c\x2b\x5b\xd5\xf2\xdb\xd2\x84\x98\x70\x84\xa3\x78\x10\xea\x01\x1a\xb3\x85\xa1\xf4\xb3\x1c\x56\xc5\xa9\x0a\x94\x63\xdd\x3a\x00\x63\x56\x16\x5d\xc8\x8d\x46\xb7\x17\xf4\xf2\x65\x08\xc1\xf4\x8b\x12\x5c\x86\xd1\xa0\x0e\x85\x52\xe4\x9b\xe6\x68\x5d\x90\x76\x22\xd7\x53\x26\x38\x8b\x85\x4e\xd0\x9c\x44\x43\x0e\x68\xc9\x53\xcd\x9e\x8a\x30\xa1\x6f\xaa\x5b\x43\x1a\x7f\xdd\x2a\x20\x91\xfb\xa9\xc3\x39\x17\x05\x34\x87\xec\x22\x25\x89\x55\x90\x82\x17\x2a\x40\x45\x1b\xdd\x25\x3e\xf3\x70\x30\x56\x0a\xb0\x53\xed\x52\xfe\x3e\x08\x23\xf1\xbf\x3f\x79\x59\x35\x30\x24\xa9\x7b\x8f\xd8\xfe\xbc\x34\x44\x98\xbe\xd4\xa7\x2e\x7a\x40\xd0\x0d\x76\x22\xfc\x76\x88\x2d\x28\xe4\x4f\x95\xb7\x75\xf6\x3a\x72\x44\x63\x31\xa4\x11\x4e\x12\xbb\x1f\x77\xfe\x4f\xc6\x90\xb8\xd7\xf2\x47\x0f\x67\x0b\x4c\x1c\x7f\x96\xc6\x18\xcc\x77\xc4\xab\xc8\xf2\xee\xfd\xf1\x85\x86\xc9\x29\xf3\x20\xe6\xa8\xb2\xa5\xcb\x62\x64\x8a\xe7\x37\xca\x00\xf1\xcc\x57\x63\x8f\x36\xc6\x03\x65\x3b\xb3\xb5\x6b\x94\x3f\x8c\x81\xce\xe3\xf7\x9a\x07\x3a\xc1\x4a\xdb\xe6\xfd\x2c\x0a\x2d\x0a\xed\x6c\xbd\x67\x27\x41\x03\x6a\x97\xe5\xec\x15\x5f\xb4\x47\x63\xfc\x6f\x51\x67\x7a\xde\x25\x98\x0e\x73\xdf\x8d\x58\x9e\x1f\x39\xa5\x12\x93\xf5\x55\xdb\x94\xbb\x5e\x7b\x91\x71\x16\x5b\x2d\xb1\x43\x7d\xcc\x4c\xb3\x1d\x5b\x3f\xcf\x8e\xc0\x78\x10\x0d\xca\xdd\x2e\xc9\x1c\x4b\xd1\x32\xce\x54\x00\xde\xd4\xb6\x11\x95\xf5\x27\x1b\x17\x02\x78\x44\x38\x42\xe4\x4f\xd6\xfa\xe7\xd7\x88\x20\x1e\x49\x91\x78\x15\x2e\xf1\x2a\x9e\x84\x7a\x81\x66\xff\x71\x86\x63\x4f\x5e\x62\x3c\x52\x14\xcc\x08\x67\xbb\x14\x7e\xf2\x98\xa6\xc8\x1e\x81\xe6\x88\x10\x6c\x1f\x15\x71\x9e\x52\x19\x39\x0f\xbf\xee\x7c\x76\xa0\xda\x2a\x73\xcc\x98\x65\x55\x96\x61\xde\xe6\x09\x4f\xe2\x11\x8b\xde\x7a\xdf\x5e\x14\x2c\x79\x22\x12\x66\x5b\x14\x55\x73\x1c\xbf\x8b\x3c\x01\xe1\x8d\x64\x90\x54\x33\xdb\xcf\x10\xcc\x89\x6d\x8f\x67\x35\x3c\xb5\x34\x21\xc8\xf6\x38\x89\xf7\x9b\xec\xdd\x7b\x5e\xf4\x5b\x53\x02\x6c\x04\x33\xdb\x14\x8b\xca\x1a\x8c\x8b\x98\xa3\x41\x9a\x40\x5a\xfe\xfd\x45\xd9\x91\x8b\x18\x90\xfb\x8b\x66\xde\x15\x39\x9c\xdd\x11\xfd\x2f\x89\x84\xb9\xd2\x81\x85\xe3\xa3\xda\xd0\xcc\x94\x75\xfa\x20\x64\x20\xac\xca\x42\xa9\x91\xbb\x8f\x22\x58\x13\x68\xf4\xec\x1d\x90\xca\xda\x07\x58\x6e\xf4\xf5\x20\x4c\xcc\xb8\x92\xd6\xc3\xd5\x31\x81\xeb\xdf\xb0\x99\x18\x57\x5a\x19\x6b\x7e\x77\x9d\xd5\xe7\xb6\xe9\xd2\xb5\xb2\xfa\xd8\x82\x18\x65\xf1\x8b\x2f\xbf\x26\x0a\xf1\x53\x8d\xc3\x6f\xa0\x1a\xc2\x6c\x48\x22\xb0\x83\x9c\x15\x1a\xde\xb7\xd0\x45\xaf\x3e\x44\xe0\x3a\x0d\xac\x8e\xc2\x20\xc3\x99\xf8\x4d\x92\x46\x16\xa4\xfe\x50\x36\xff\x07\xaa\x72\x89\xaf\xce\xb8\x36\xca\xc2\x52\xb3\x3c\xb7\x44\x86\xe5\xdb\x05\xdc\xf2\xbc\x06\xc5\x23\x8f\x7a\x9e\x3e\x07\xe0\xa1\xea\x9d\x2e\xfc\x6c\xcc\x21\x51\xa8\x6a\xda\xad\x1c\x9b\xf7\x73\x59\xf5\x7e\xc9\xc3\x17\x63\xba\xff\xb3\x0e\x82\xae\x06\x77\xfb\xa9\xa2\xa4\xdf\xc5\x09\x2f\xd6\xc7\x0b\x26\xbc\x1d\x91\x04\x01\x45\x46\xcf\x4a\x6b\x2b\xa5\x33\x83\x67\x5c\x96\x4c\x47\xc8\xd1\xd1\x17\x99\x04\x81\xc1\xa5\xc9\x91\xb9\x2f\xa5\x77\x59\x12\x90\x94\x25\x1e\xbc\x20\x1a\xf8\xff\x68\xfb\xb3\xe5\xc6\x75\x2c\x7b\x1c\x7e\x9d\x73\x51\x17\x24\x01\x70\xb8\x94\x64\x39\x53\x95\x9e\xca\x92\x33\xeb\x74\x45\x85\x02\xc3\x86\xcd\xb2\x44\xaa\x39\xa4\xad\x7e\xfa\x2f\xb8\x31\x70\x10\xe5\x53\xbf\x2f\xe2\x1f\xd1\xd1\x59\xc7\x04\x49\x08\xc4\xb0\x87\xb5\xd7\x42\xc6\xab\x71\x77\x48\x10\x9b\x32\x5a\x50\xad\x04\x44\x61\x4c\x5b\x50\x95\x5a\x13\x1f\xed\xf3\xaf\x63\x50\x29\x11\xa1\x01\xdd\xb7\xc7\x63\x59\x84\xc1\xf6\x3d\x2f\x16\xa7\x13\xf0\xea\x42\xc0\xd8\x71\x37\x92\x94\x40\x80\x0c\x11\x30\xc0\x57\x8c\x7f\x0a\x65\x11\xee\xea\x38\x2d\x57\xfc\x84\x5e\xea\xee\xc3\x85\x33\x52\x2a\x42\x2c\x08\x6d\x80\x1f\x8d\x7b\xee\xf2\x59\x29\x4b\x01\x21\x73\x6d\x61\x42\x98\xcd\x46\x96\xb3\x70\xa3\x34\x4e\x22\x1e\x0c\xf0\x3f\xdd\xbb\xae\xa2\x51\xd2\x38\x49\xa5\x95\x16\x5e\xb6\xb9\x91\x77\x28\x4d\x96\x77\xf4\x33\xd3\x7f\x85\xc1\xbf\x67\xff\x97\xab\x4f\xf2\x7f\x75\x4f\xd6\x3a\x51\x0e\x85\x7c\xdb\x16\xb3\x34\x37\xb6\x6d\x92\x66\x18\xa3\x87\x4f\x3e\x64\xa5\x1f\x6f\x46\x69\x22\x4c\xd2\x61\x69\x54\xfb\xcc\x6c\xbe\x32\xd4\x69\xac\x63\xcf\x90\xf1\xab\xe7\xd1\x9c\x9b\xa0\x97\x76\xdf\xec\x5f\xdd\x93\x53\x93\x96\x71\xc9\x62\x33\xc0\xa5\xcb\x19\x5f\xcb\x17\xa7\xa9\x34\x65\xf3\xb5\xc1\x6e\x2c\x0a\xb5\xcb\xe5\x7b\xbf\x74\x86\xfb\x47\x9a\x4a\x89\x96\x63\xb7\xb2\x97\x79\xb3\x30\x6c\x7d\x98\xc6\x7d\x7c\x5c\xba\x49\xc1\x03\xc3\xbb\xa0\xe0\xf7\x2d\xc0\x77\x7e\x51\x00\xd8\x35\xd1\x58\x35\x71\xff\xed\x6e\x20\xde\x46\x52\x9e\x72\x8c\xcf\x1d\x0d\x03\xe4\xd2\x6f\x2a\x29\x57\x51\x62\x8a\x3e\x73\x09\x7d\xc6\x32\xe5\x2a\x66\x96\xf5\xea\x3b\x54\xe5\x53\x59\x5b\xbc\x9b\x6b\x20\x84\x81\xc3\x75\x6b\x8c\xb7\x35\x4c\xc9\xeb\x48\x2a\x03\xed\xd4\x34\x9e\x78\x85\x34\xe1\xe7\xb2\x6d\x86\xc4\xac\x7d\x9d\x33\x49\x25\x4b\x43\x32\x08\xda\xa3\x74\xc7\xe4\x3b\xcb\xcc\xa8\x70\x63\xcd\xb2\x9f\x0b\xa3\xb1\x94\x9c\x0b\x8b\x66\x41\x32\xb3\xd1\x45\xb0\x10\x58\x63\xa2\x3f\x01\x8a\x1a\xe7\x30\x29\x33\x48\x21\x36\x44\x71\xc6\x9a\xc2\xc3\xd3\xc5\xed\xc7\x0d\x75\x90\x98\xd8\x58\xc1\x4f\xf5\x5b\x69\x64\x14\xbe\x95\xe5\x33\xd4\xc0\x2b\xf9\x66\xd9\x85\xdc\x4f\xd4\x21\x47\xb5\xb2\x0f\x9e\x37\x9e\xb3\xb4\xc7\x5d\x64\xa1\x0c\xb1\xef\x26\x86\x3f\x8a\xf5\xce\x6f\xde\x59\xa8\x58\x6a\x15\xae\xfe\xf9\xf4\xfc\x78\xff\xb8\xbf\x7f\xb9\xdb\x6d\x9e\xee\x36\xeb\x67\xf7\xd4\x28\x48\xb2\xa1\x0d\xe6\xc5\x6f\xdd\x75\xa9\xa9\x01\xf2\xfe\x06\x3e\xd6\x3d\x27\x59\xa4\x43\x57\xe7\xd5\x59\xa6\x3d\x51\xce\xb8\x1f\x91\x66\x3c\xf0\x68\x2e\x8b\xde\x7d\x36\x6a\x01\xdd\x47\x9e\x20\x66\x33\x92\x9a\xd4\x0d\x2e\x58\x4f\x6f\x8a\xa1\x53\xd7\x6d\x1a\x9b\x52\xf5\xce\x5c\x7f\x83\x1f\x79\xf1\x5a\xff\xa3\x2d\x1b\x18\x3f\x88\xea\x18\x67\x7c\x5b\x48\x03\x65\x1d\x55\xc1\x64\x2c\x24\x36\x71\xd1\xdc\xc0\xa9\x02\x89\x5e\xf8\x1c\xba\x30\x63\xcc\x08\xd2\x72\x7f\xa8\xee\xca\xed\x09\x7c\x6c\x3a\x63\x3c\xc4\xb2\xab\x03\x16\x82\x2e\xf3\xfe\x82\x26\x24\xee\xd3\xc9\x3e\xfe\x34\x7b\xda\x64\x31\x25\x88\x7f\x40\xd8\xe4\xac\x94\x9b\x6d\x98\x70\x93\xa3\x79\x2b\x0f\x65\x7d\x5b\x56\xbf\x20\x9f\x8c\x7a\x1a\x50\x2e\x07\xf6\xf1\x53\x05\xf9\x91\xbf\xce\x03\x61\x52\x77\x53\x96\x59\x41\xb6\x1b\xe0\xea\x90\x17\x30\x7d\x2a\xcf\x10\x10\x51\x1b\xfa\xaa\x7a\xfd\xbc\x0a\x63\x36\x99\x17\xa9\x0e\x90\x34\x1b\x3e\x4f\xf9\x44\x4c\x21\xbd\x24\x7d\xb5\x37\x65\x84\xb8\x64\x0f\x62\x90\x2d\xa4\xd0\x5d\x55\x89\xb4\x5e\xb0\x4d\x95\x9b\x20\x3c\x52\xe7\x8d\xdf\x9e\x81\x74\x31\x62\xc7\x77\x64\xaf\xf0\x4c\x65\x89\x2b\x39\x43\xa6\x84\xf3\xc9\xbf\x81\x6b\x81\x00\x8b\x65\xde\xc8\x32\x37\xb5\x60\xee\x9a\x48\x32\x85\x8a\xbc\x2e\xc9\xbf\x9f\xbc\x53\x8a\x00\xcb\x7c\xd7\xcf\xab\x34\x4a\xfe\x32\xd2\x9a\x49\x01\xba\x27\xce\x7f\x18\xe2\x93\xc6\xed\x20\xc5\xf4\xcd\x6d\xc5\x8b\xf7\x43\x5e\xe0\xbf\xae\x57\x52\x1b\xd5\xbf\x02\x09\x86\xb4\x3e\x40\x31\x0c\x92\x65\x90\x18\x4e\x4c\xae\x94\x85\x19\x0f\x09\x74\x48\xa6\xb5\x44\x1f\xe8\xdb\xcf\xdb\x7f\xda\xbf\xf1\x20\x51\xda\xb1\x00\x78\x7a\xe6\xda\x5f\x15\x86\xe4\x0d\x23\xe0\xb7\xf9\x01\x6a\xb3\xf5\x0d\xe2\x34\x3c\x0c\x8d\xae\x99\x51\x22\x33\x35\xb7\x2f\xb5\xf2\x97\x59\xa8\x60\x40\x33\xa0\xbe\xf1\xa3\xcd\x48\xfa\xd7\x84\xa9\x42\xc9\x13\x5f\xdd\x66\xaa\xfb\x6c\x35\xb3\x6f\x05\x09\x26\x08\xb0\x84\xf9\xd7\x7a\x63\xd2\x00\xde\xdc\xe5\x11\x93\x54\xf6\x85\xf5\xab\xa2\xa9\x4c\xd6\xf1\xa5\xce\x8b\x57\x74\x49\xc7\xab\xcb\xc5\x30\x79\x14\x27\xa2\x97\x6a\x5d\x37\x6f\xdf\x0e\xa5\xe0\x87\x1b\x38\xc0\xeb\x18\x51\x3c\x9a\x05\x3c\xe2\x71\x6c\xab\x09\xab\x1c\x7e\x5f\x29\x7f\xe2\x11\xcf\x08\x77\x2c\x74\xe6\x98\xf2\x3f\x3d\x92\x01\x1a\x61\xb5\x7c\x03\xd5\x1e\x60\xc5\xbd\xef\xc8\x09\x4b\x5d\x25\x25\x62\x55\xe7\xdc\x0d\x4e\x32\x46\x69\x2f\x02\xbb\x2a\x8f\x27\x5e\x9c\x8d\x87\xb5\x30\xf9\xd2\x3e\x2d\xcb\x09\x40\x1a\xb8\x83\xba\x6a\x10\xdf\x7e\xb8\xa0\xdf\xb4\x8d\x69\x6a\x0e\xb4\xde\x43\xd9\xfd\xb8\x7b\xb8\x66\xe5\x70\x0a\x02\xcb\x68\xf7\x48\x31\xfc\xf8\xdb\x4f\x4c\x4e\x75\x8a\x47\xd9\x5b\x2e\x26\x4a\xdd\x84\x33\x2d\xb1\x52\x65\x23\xcb\xa2\x0f\x03\xb9\x3b\xe3\x88\xc7\x69\x9f\x9b\x37\x43\x10\x06\xee\x6a\x66\x54\x0e\x55\x8e\x62\x0a\xaa\xf6\xe6\x84\xc7\x05\xf0\x18\x8c\xe5\x68\xc5\xa3\xcd\x52\xed\x0d\x13\x9e\x50\x40\x1c\x37\x72\x50\x74\x83\x71\x2b\xf3\x91\xdb\x66\xdb\xa5\x84\x3b\x5d\x3d\x73\xaa\x2c\x5c\x50\x6a\x57\xde\x4f\x7c\x36\x9e\xc6\x19\xb2\xb7\xbd\x96\x07\x05\x05\x1a\x7b\xcd\x25\xeb\x2d\xe1\xa9\xe2\x4c\x0f\x82\x6d\xf7\xbc\x72\xab\x9d\xa7\x9a\xe1\x41\x52\xd5\xad\x51\xcd\x99\x52\xc6\x13\x9e\x89\x10\x37\xc9\x9a\x9f\xbf\xc3\xe1\x50\x8e\x4e\x43\x9e\x09\x85\x9e\xf0\x91\x7f\x7a\xa6\x6f\x3f\xef\x32\x01\xae\x6c\x18\xf9\x4c\xbe\x5d\xdb\x92\x78\x26\x33\xdc\xdc\x51\x1d\x68\x1a\xe8\x1e\xff\x6c\x1e\x68\xb0\x39\x83\x4d\x03\x47\x7c\xb0\x15\x8e\xbb\x32\xc5\x04\xa4\xa9\x2b\x85\x43\xdb\xbe\x9f\x5d\xb6\x85\xcc\x08\xe2\xb0\xfe\xb1\x7a\x9c\x65\x4e\xfc\xab\x7f\xed\x63\x14\x03\x27\x19\xb4\xfb\x00\x98\xce\x42\xa0\x04\x4d\x16\xd1\x9e\xc3\x20\x68\xf0\x83\xf9\xb1\x02\x2e\xd5\xc0\x02\x6c\x0f\x53\x48\x04\x07\x61\x29\x67\x98\x9d\xa1\xee\xef\x4a\x61\x82\xcd\xd8\x70\x9b\x1a\x99\x4a\x72\x50\x9b\x62\xd9\x1e\xde\x27\xd8\x2f\xff\x93\x35\x49\x31\xd2\x67\xde\xb7\x29\x74\xf9\x52\x1d\xe6\x3f\x8e\x4e\x02\xab\x24\xd4\xf0\x83\xb6\x34\x83\x44\x04\x3a\xc3\x6a\xf5\x1f\xb9\x1c\x25\x3a\x44\x18\x10\x84\xa5\x22\x29\xc8\xb6\xcf\xe7\x8f\x87\x43\x84\xa9\xc6\x63\xc8\x0a\xca\x9f\x0e\x97\xdc\x73\x7d\x4b\x1d\xb9\x0e\x98\xe0\x96\x17\xc6\x21\x22\x54\x2c\x12\x06\x50\x6f\x00\x56\xbb\xb2\x9b\x46\x1b\x75\x25\x8e\x28\x42\xad\x11\x8b\x63\xe2\x5c\x23\xf6\x89\x49\xd8\xc7\xde\x10\x51\x81\x60\xa3\x3b\x70\x86\xb5\x88\x18\xc3\xd0\xee\xa1\x2c\xdf\xdb\xd3\x10\xea\x23\x22\x45\xd0\x4f\x71\x4a\xfb\xa3\x68\x9c\x20\x51\x12\xaa\xa1\x8c\xfe\x57\x14\x0e\x44\x10\x66\xc2\x48\x2e\x41\xb1\xbb\x20\xb7\x9b\xfc\x38\x22\x63\x64\x67\x7f\xcf\xe5\xfb\x63\xdb\x60\x31\xd5\x95\x71\xa0\x4a\x44\xac\xaf\x65\x9f\xee\x46\x82\xb1\x98\x30\x53\x7b\xfb\xc7\x45\xb0\x53\xb0\x84\xeb\x3e\x6e\xf2\x0a\x63\xc0\xfc\xfc\x0a\x11\x71\x2c\xc0\x83\x6f\x4c\xf0\xf0\x67\xd9\x60\x8a\xff\x02\x6d\x2f\x62\x9d\x61\xde\xf4\x38\x9a\x5d\x09\x4b\xb0\xfc\xce\xd5\x2e\x7a\x68\xc0\xa8\xe6\x6b\x60\x7f\x8a\x84\x09\x07\x6f\x46\x0d\x4d\xc3\x36\x84\x68\x08\x74\x22\x3d\xc1\xd2\xe0\xd7\x25\x60\x64\xa7\x3d\x73\x37\xfe\x46\x17\x2e\x11\xa8\x21\x31\x70\xd2\x37\xfa\xa1\xfc\x7e\x3b\x5e\xb0\x22\x0b\x95\x61\xa9\xca\x97\xbd\x81\x25\xb2\x84\xa2\x91\x7d\x5f\x2a\x5c\xa6\xff\x8f\x05\xa1\x22\x83\x08\x87\xf0\x54\x7e\x18\x74\xde\x7d\xa9\xda\x43\xfb\x17\xf0\x68\x91\xe9\x08\x03\xa7\x27\xea\x3a\xc2\x23\x43\x2f\xe0\x7e\xc3\xfa\x79\x95\x44\xe1\x6c\x7e\x42\xf0\x98\xf5\x62\x76\x23\x56\x3d\x22\x78\xc2\xb0\x4c\xf4\x98\x17\xcd\x6d\x59\x21\xb8\x66\xdc\x65\x9e\x11\x8c\x1b\xff\xfd\xe9\xcf\xfd\xe3\xb1\xc8\x55\x79\x38\x70\x77\x78\x0a\x11\x1b\x32\xff\x0f\xc8\x6b\x83\x50\x82\xfe\x5a\xaa\x41\xf4\x32\x70\x43\x3b\xc2\xb6\x90\xc2\x94\x7d\xd7\xe5\x41\xa1\x74\x93\xfd\xbb\x0a\x04\x46\x83\x57\xfc\x84\x75\x0a\x43\x88\xb6\x50\x32\x8c\x07\x8c\xf8\x48\xec\x3d\xcd\xd8\x8d\x22\x38\xf6\x3e\x88\x18\x3a\xb6\xab\xb2\x28\x40\x36\xb9\x2d\x6a\x9c\x74\x09\x88\x44\xea\xc6\xbd\x93\x14\x3e\xbd\x9c\xfc\x41\xee\xba\x00\x36\x96\xbe\xb5\xc9\x11\x14\xeb\xbb\x7b\x0a\xa7\xcf\x4a\x8d\x98\x48\x67\x6e\x6b\x3d\x0d\x4b\xbb\x46\xdc\x80\xe5\x8c\x69\xf9\x0d\x8a\x60\xb6\x02\x50\x68\x12\x61\x26\xc0\xd5\x52\x7e\x87\xaa\x5c\x1d\x78\xed\x99\x79\x88\xd0\x2c\xa0\xdc\xd1\x8b\xca\xe6\xa2\xae\x5c\x06\x61\x96\xca\x5e\x6d\xa6\x9e\x45\x88\xc9\x40\x00\x82\xf1\x55\x7b\x3c\x0d\x51\x76\x32\x24\x11\x86\x94\xf7\x18\x17\x47\x46\xd6\xcd\x18\x56\x2e\x43\x65\x62\xd1\xfd\x96\x67\x82\xec\x93\x57\x44\x71\x8a\xde\xb3\x95\x43\x35\xf1\xcc\x49\x94\x40\x46\x3a\x40\x2d\x32\x81\x15\x8c\xa3\x51\x93\x84\x25\x88\x41\x6a\x1c\xf0\xca\x95\xbb\x3a\x63\x5f\xb2\x20\xc2\x57\x28\xe3\xf1\xfd\x5a\x6f\xfa\x2b\x04\x8d\x79\x01\xb2\x3c\x82\x11\x95\x30\x1a\x37\xbe\x45\xc8\x1d\xc8\x4f\xc2\xc1\x53\xc1\xf7\x56\x9f\x65\x73\x22\x92\xc5\x04\x33\x77\xbf\x2d\x0f\xce\x5c\xe5\x91\x64\x19\x47\x0d\xa4\x0f\xfc\x99\x33\x52\x02\x44\x32\x6e\xca\x4e\xf3\xfa\xd9\x06\xb4\xa6\x75\x40\x92\x09\x1a\x58\xa6\x39\xac\x13\x55\x6a\xfa\xe1\x62\x62\x72\xb9\xdd\x62\x5e\x72\xf5\x3a\x39\xb4\x65\x0c\x11\x82\x18\xf0\xf3\xa1\x62\xfc\x5b\x05\xdc\xa3\x1f\x64\xac\x03\xe9\x48\xaf\xda\xba\x29\x8f\x50\xed\x3e\x3d\xe4\xc7\xd6\xba\xfd\xf8\xf5\x36\x5d\x6e\xf6\xf6\x84\x30\xb4\xa0\x96\x9b\xdd\xcd\xf3\xe6\xe7\xda\x3d\x36\xa1\x12\x53\xe3\xbc\x3b\x4a\x6f\xcb\x6a\x05\x55\x93\xeb\xdc\xfa\x1d\x5f\xb2\xd1\xcf\x81\x7d\x64\xc2\x80\x59\xfd\xcb\xb5\xa1\x0e\xef\x5c\xb7\x6d\x37\x51\x2f\xce\x0f\x99\xa6\x86\x72\xd7\x59\xf7\x93\x22\x37\xd7\x4a\x86\x91\x35\x76\x7f\xe6\xa7\x91\x58\xda\xb8\x61\x16\x80\x49\x4a\x1b\x71\xa5\x21\x0d\xae\x6b\xc1\x64\xe2\x04\x50\x11\x74\x38\x99\xb9\x9c\x48\x74\x27\xb6\x79\xf1\xda\x1e\x90\x1a\x6d\x07\x75\xe3\xc0\xed\xb2\x33\x44\x13\x6b\xf0\x42\x75\xbf\xd9\x4d\x9e\x2f\x68\xc8\xec\x47\xda\xac\x1e\x07\xb2\x0d\x44\x0a\x16\x80\x4b\x59\xe7\x36\x96\x31\x07\xff\x91\x22\x95\x58\x67\xe7\xf8\xf9\x0c\xa1\xbf\xbb\x28\x23\x9c\x05\x08\xa0\xdf\x72\xd9\x19\xa4\x7e\xf7\x95\x42\x11\x3a\x50\xa1\x9b\xda\x5e\xb3\x96\x83\x54\x59\x86\x50\xa1\xd5\xdd\x62\xbb\xdd\x2f\xfe\xf1\xb2\xd8\x6d\x5c\x8d\x86\x04\x61\x2c\x85\xdf\x39\x7c\x30\x87\x9b\x92\x1a\x02\x0c\xaa\xae\xd7\xcb\xa9\x8d\xd5\x5e\x14\x86\xab\x20\xa4\xca\xfa\x15\x9d\x03\x0d\x03\x5f\x78\xf4\xcb\x55\x90\xea\x20\xbe\x14\x9b\x1a\x52\x11\x8c\xc5\x5c\x88\x0a\xb8\x51\x11\x7b\x80\x8f\xb1\x7f\x31\x63\xf2\xa9\x80\xb3\x98\x8e\xa2\x52\x2e\x87\x3a\xb0\x32\x55\x44\x0c\x1b\x1b\xce\xa2\x3e\xbc\xae\x22\x69\xd8\xf9\x6b\x68\x7e\xc0\x79\x3c\x71\x14\x89\x8c\xc8\xe3\x53\xfe\x09\x87\x95\x17\x0b\x25\x8a\x50\x26\xed\x3b\xbf\xf3\xe2\xb5\x6c\x9b\x31\x90\x4b\x91\xd4\x1c\xb3\x05\x7c\xac\xca\xf2\x3d\xf7\x77\x52\x95\x30\x1f\x77\x38\x76\xbe\x18\xaf\xdf\xe6\x0b\x2d\x15\xa3\x12\x6b\xef\x4f\x3c\xc7\xe8\x8e\x65\x27\x9e\xd5\x27\x71\xb7\x30\xae\x46\x9c\x21\xcb\xf6\xfc\xad\x3c\xa8\x01\x82\x75\xbc\xbc\x14\x4b\x15\x32\xfb\x54\x6d\xd1\x3b\x09\x8a\x65\xa6\xf8\xb7\xf3\x1a\x65\x79\x93\xd7\x38\xb0\x96\x23\x87\xbf\x42\x3d\x5c\xf7\x97\x36\xa4\x62\x5a\x11\x57\x3c\xac\x8e\x79\x31\x40\x09\xab\x38\xe5\xc8\xef\xd8\xc0\xf1\x54\x56\xbc\x3a\xff\xc8\x0f\x93\xa8\xb6\x8a\x33\x15\x74\x47\xef\x03\x6a\xa9\xba\xc8\x98\x4a\xb8\x95\x7f\x81\xc2\xd7\xdd\xa8\xaf\x40\x10\x2a\x01\xc2\x82\x6b\x1c\xc6\x93\xf1\x4e\x65\x80\xdc\xd8\x50\x28\xc7\xa0\xee\x6a\x21\x55\x96\x70\x2c\xc8\x97\xdc\x19\xdf\xee\x42\x1a\x05\xa6\x3e\xcf\x24\x97\x87\x24\xc3\x44\x65\x92\x22\x37\x6c\x3d\x54\xb4\xb5\xd7\x38\x8d\x90\xb0\x5d\xba\xc6\x9c\x85\xcc\x16\x3d\xac\x9b\x37\x5e\x35\x8b\xaa\x19\x45\x0b\x15\xe7\x02\x57\xb5\x3b\xeb\x97\x03\xda\x12\xd7\x44\x66\x88\xf1\x45\x64\x99\x28\xdb\xd7\x37\xdf\x55\x41\x32\xcc\x3d\xb7\x45\xdd\xf0\x77\x78\x32\x3a\x7a\xd3\xd5\x3b\xb5\x8b\xf1\xef\xe9\x64\x58\x05\x03\x4c\x0f\xbc\x54\x6d\x31\x00\x4a\x29\x19\x18\xd2\x04\x8d\x45\x65\x37\xc0\xaf\xc4\xb1\x94\x0c\x03\x24\x54\x2f\xbb\x03\x7e\x53\x34\x50\x15\x83\xb6\xe3\x49\xad\x22\x82\x53\xf4\xc8\x3f\x57\xfc\xb4\x6e\x9d\xd1\xa0\x20\xe4\x86\xf3\x96\x1f\xc1\xea\x2a\xbb\x2b\x89\x14\xba\x3f\x34\x14\x1c\x11\xa5\xf4\x2b\x2f\x54\xf9\x71\xa5\x4b\x00\x46\x5e\xcc\x98\xa1\x8b\xc3\xc1\x56\xbb\x21\xb7\xdc\x70\x02\x83\x16\x49\xe0\x63\x01\xf8\x62\x77\x49\x67\x99\x75\xd2\x7f\x97\xc6\xdb\x9a\xd9\x18\x27\x3f\x4f\x0b\x93\x51\xc7\xa9\x79\x5b\x56\x4d\x5b\x78\x03\x53\x69\x01\x58\xb3\x61\xf4\x39\x1d\x1c\xc1\xee\x70\x17\xb8\xd8\xbf\x4d\x22\x35\x4a\x2b\x6e\x82\x5e\xfc\x38\xa2\x4a\x80\x20\x4c\x50\x54\x47\x3d\xc0\xa7\x71\x48\x47\x50\x23\x08\x18\xc1\xcc\x85\xad\x7b\x59\xb6\xe7\x25\x97\xef\xdd\xf9\xd6\x27\xc8\x21\x88\x85\xa9\x15\x32\x41\x18\xa3\x30\x33\xd6\x27\x74\x2d\x39\xc4\x86\xc5\xb1\x5b\xcf\x26\x1a\xb9\x3f\xf9\xed\xc4\x3f\x50\x08\xae\xfa\xa8\x6c\xf7\xe2\x33\x06\xe6\x87\x3b\x3e\x84\x2a\x62\x83\xbe\xd5\x8f\xfa\xa9\x2a\xff\x03\xb2\x99\x10\xb0\x40\x14\xa4\x4e\xc7\xbe\x8f\x91\xdb\x68\xec\xf8\x91\x51\x92\xd1\xd4\x43\xf7\xe0\xa5\x56\xb7\xbc\x36\x79\xd3\xc9\x2f\x89\x74\x14\x83\x21\x13\x05\x35\xd4\x92\x21\x40\x52\x0e\x8e\xe4\x60\xfd\xe3\x65\xbc\x30\x81\x64\x81\xf3\x04\xf6\xa7\x0a\xf6\xef\x67\x69\xeb\x74\x8a\xf6\x08\x15\xbf\x20\x14\x02\x22\x2d\x67\x24\xf0\x71\xa4\x10\x58\x10\xe0\x6e\xa4\x00\xd7\x6f\x77\x2a\x4c\xde\xc6\x52\xc0\xf0\xbd\x38\x70\xc3\xf0\xba\x45\xca\xa2\x81\xe2\x4b\xea\x26\x09\xc4\xc0\x11\x45\xb8\x7c\x7c\x78\xd9\x3a\x7c\x10\xa4\xda\xe8\x93\xd4\xc7\xce\xdd\x1a\xce\x9d\x2c\xd2\x58\xb4\x71\x53\xf1\x8f\xbb\xb2\x69\xa0\x3a\xcf\x62\xc4\x21\x23\x1a\x6b\x41\xad\x43\xf0\x1d\x0e\xa7\xc9\x26\x08\x3c\xd0\x68\xf7\x9f\xaa\xf2\x58\xae\x9b\xb7\x41\x80\xc2\xb5\xc8\x02\x13\x01\xea\xee\xdb\x95\xdb\xc6\x5b\x92\x8e\x83\x95\x80\x08\x92\x88\x98\xe2\xef\x07\xf8\x98\x45\xa1\xfd\x55\x15\xe1\xe0\xf4\x02\x25\x28\x2e\x0e\x67\xac\xad\x6c\xd0\xaf\x6e\x11\x70\xd2\x73\x77\x12\x80\x98\x84\xa1\x15\xb6\x5f\x14\x0a\x53\x05\xa3\x99\xa5\x69\x42\xba\x0f\x81\xbb\x88\xd9\x51\x4c\xe1\xd3\x1c\x26\xc7\xdd\xc3\x52\x34\x58\xbf\xf1\xa3\xf0\x99\x33\xd0\x29\x41\x6e\x75\x53\x65\x97\x97\x85\x75\x6b\x46\x03\xaa\x83\x30\x40\xe2\xb4\xa2\x3d\x7e\xe3\x47\xdf\x51\x1d\x10\x8d\xa7\xcd\xff\xb6\x50\x9d\xb7\x27\x90\x39\x3f\x3c\xf3\x06\x6e\x2f\xf8\x7c\xc6\xa7\xa2\x0e\x12\xc1\xad\xe0\xfa\x50\x50\x02\xea\x69\x58\x58\x07\x8a\x23\x50\x29\xaf\x2d\x3e\xd1\x47\xfc\x75\x98\x70\xb0\xd1\x2f\xb3\x66\x76\xe5\xa6\xae\xa7\x65\x4a\x3a\xe4\x49\x18\x78\x8a\x66\xa8\x9b\x41\x52\x4b\x87\x22\x00\x3e\xd8\x6d\x4c\x71\xc2\x95\xbd\x75\xc2\x03\x37\x0f\x4c\xd3\x84\x84\x41\x0f\x4c\x7b\xd4\x98\xec\x98\x7a\xe7\x9a\x50\x8e\x36\xc4\x0d\xbf\x0a\x54\xfa\xef\x0a\x2c\x34\x11\x29\xa2\x40\x8f\xfc\xf3\x01\x51\x1e\xfe\xf3\x50\x6a\x34\x17\x2b\x38\xf0\xf3\x3d\x34\x7c\xf7\xf9\xc7\x3c\x18\x66\xe4\x09\x4e\xbe\x15\x0b\xcd\x6a\xca\x8b\x1c\x25\x38\x30\x82\xf2\xd5\x8c\xef\xbb\xc6\x08\x60\xa2\xd2\x50\x53\xf7\x8a\xcc\x8b\xc2\x52\x89\xdf\x96\x97\xea\xad\x44\xb3\x2c\x4e\x93\x21\x57\x03\x7a\xf5\xf5\x5b\x7e\x9a\x34\x8c\x23\x23\xd9\x2e\x0d\x37\xf5\xaa\x6d\x2e\xa6\x6e\x9c\x48\x35\x0c\xde\x6e\xb1\x98\xd1\x8d\x50\x0c\x06\x73\xdf\xd9\x7e\x8f\xc5\xe1\x8c\x86\xf3\x70\xa9\xe9\x04\x64\x66\x67\xea\x5d\xf9\x3a\x34\xff\x75\xa2\x43\x63\xcf\xba\x22\xdf\xf1\x9b\x53\x4a\x94\x55\xaf\xfa\x09\xd5\x48\x22\xac\xbb\x28\x03\x9f\x51\x9c\xe8\x15\x8f\x7f\x63\x16\x18\x6f\x5f\xbb\xa0\xa1\xce\x02\x93\xb4\x36\x07\x9a\xce\x5f\xfd\x05\x1a\x18\xea\xe4\xfc\xb5\xb0\xd9\xee\xff\x42\x15\x89\x68\x4e\x75\xe4\x7c\xd5\xa7\xf2\x03\x86\xac\xb9\x44\x73\x66\x42\xf5\x98\x1b\xde\xda\xf4\xe5\x95\x82\x3a\x2d\x48\xc8\x0d\x33\x55\x79\xb8\x69\x8b\x57\xf0\x7b\xae\x16\x0c\x58\x1f\x21\xfb\x69\xe9\x6a\x6e\xaf\x0b\x5a\x4c\x26\x93\x90\x86\xf2\x62\xb3\x7a\x7c\x6e\x8b\xa2\x47\xd8\x68\x49\x13\x9c\x2f\x6e\x6b\xbd\x2d\x7d\x76\x4d\x2b\x01\x18\x22\x37\xca\x28\x05\xee\x98\x0a\xd5\x36\x6c\x03\x20\x60\x94\x9a\x7a\x88\xbb\xd6\x81\xa1\x51\x7d\xed\x6b\x62\xfe\xa7\xe7\xd7\x48\x5d\x2b\x92\x62\x7c\xda\xa0\xdf\xca\x0a\x6b\x10\x7a\xfd\xdc\x39\xdf\x81\x06\x21\x8f\xec\xf1\x55\x37\x55\x79\xd6\x65\x65\x99\xf7\xa7\xa1\x42\x1a\x84\x2a\x46\x81\x2b\xec\xba\xa7\x29\x1b\x64\x32\x68\x10\x85\x12\xe1\x53\x4d\x79\x6a\x4f\xeb\x02\xaa\xd7\xf3\xf2\x3c\x5b\x21\x3e\xe9\x46\x14\xab\x44\x78\x17\xe6\x06\x7e\x8f\x56\x16\x0d\x22\xa0\x08\xe4\x5f\x7f\x9e\xba\xbf\xee\xb7\xbc\xc9\x6b\x6d\xe0\x85\x7b\x43\x31\x06\xea\x1a\xe4\x90\x06\x84\x2b\x99\x0e\x32\x5b\x86\x5a\xf4\x8b\x6d\x93\x06\x44\x1a\xbe\x26\x5b\x0c\x77\xb3\xdf\x3d\xee\x16\x77\xfb\xc5\xfd\xe3\x8b\xa3\xeb\xa4\x41\x37\xf9\x75\x8f\x2f\xee\x81\x24\x34\xa0\xa1\xc0\x1c\xe9\xef\x1c\x3e\xf8\xec\x78\x52\x42\x31\x8b\x7f\xff\xe7\xfa\x9f\xab\x01\x52\x8e\x06\x54\x10\x04\x47\x58\x31\x4d\xab\x42\xe1\xae\xb2\x88\x61\xa8\xe6\x8d\x57\xfc\x47\x5e\xe5\xfd\xdf\x39\x7e\x7f\x9e\x57\x77\xb9\x6e\x06\xd1\x6d\x1a\xb0\xc4\x68\xbb\x98\x7c\x36\xdf\x53\x7f\x21\x0d\x14\xf8\x81\x37\xb5\x95\x91\xbf\x28\x0c\x03\x1c\x57\xea\xef\xa5\xf8\x8b\x4f\xc8\x14\x09\x1c\x1d\x6d\x74\x74\x85\xb1\xb3\xeb\x92\x06\x0c\x42\xcc\x78\xec\xb9\x52\x8b\xa2\xc6\x35\xfe\x3d\xaf\x9b\xb2\x3a\x5f\x55\x25\xbd\x30\x22\x68\x10\x67\xd2\x31\x61\x5a\x68\xc7\xf2\xbc\xab\xb8\x7c\xdf\xa8\xc9\x60\xc7\x8a\xfa\x96\xf9\x27\x0c\x45\x38\xa9\x6d\x92\xc4\x49\x60\x60\xcb\x45\x39\x14\xa5\xe8\xae\xa4\x88\xc1\x3f\xf1\x79\x45\x5b\x1a\x24\x32\x56\x66\x82\x95\xa7\xe1\x86\x4d\x83\x94\x09\x6d\xeb\xd4\x2e\x35\xbc\x07\xc0\x24\x1a\xa4\x71\xea\xf8\x00\x8c\xa2\xb8\x8b\xf1\x8c\x87\x2e\x05\x2d\x0c\xab\xe8\x3d\xfa\x4b\x79\x59\x20\xa8\xf7\xf1\xe4\xf6\x48\x1a\x64\xd4\x54\x7e\x20\xa0\xf2\x09\xaa\x97\x22\x97\x65\xd5\x5f\xe6\x0a\xc9\x16\x3a\x2b\xeb\x8f\x21\x4e\x6a\x6c\xed\xd0\x80\xeb\x28\xf3\xe8\xe1\x1d\xf0\xa3\x53\x13\xac\xdc\xa3\x44\x94\x60\x3e\xff\x8d\xd7\x5b\xfc\xd9\xf6\xd7\xff\xeb\xdf\x7f\x1b\x0d\x83\xa0\x06\x6e\x71\xcc\x8b\x6d\x7b\x34\x44\x7d\x5e\xb9\x8d\x06\x22\x09\x63\xeb\xc5\xdc\xdd\xfd\xdc\x83\xca\x9b\x7d\x48\xc7\x23\x29\xd2\x34\xee\x17\xf1\x04\xb4\x3e\x41\xf2\x77\xad\x15\xa6\x90\xda\x5a\xed\xca\xef\xfc\xf7\x68\x39\x08\x65\x8e\xbb\xbd\xd5\xe8\xbe\x2b\xf9\x95\xe8\x0a\x0d\xa4\xa6\x98\x6f\x32\xa8\x73\x8f\xf7\xb4\x57\x55\x98\x71\x87\x17\x33\xb7\x6f\x7d\x68\x84\x06\x8a\x86\xc8\xb1\xbd\xf0\x55\x1d\xe3\x67\xab\x38\xc2\x72\x03\x4b\xfc\xd9\x17\xfc\xae\xf2\xe6\xbc\xcd\x9d\x36\x13\x0d\x94\x4c\xc1\xa4\x1d\x66\xd0\x72\x34\xd0\x4a\xa2\x61\x73\x63\xa9\x53\xa6\x97\x41\x22\x10\x48\x97\x95\x84\x47\xad\x6b\x68\xd6\x68\x60\x77\x66\x7e\x4f\xc3\x4c\xc3\x20\x4b\x51\x93\x13\x53\x12\xf5\x3d\x6f\xba\xe3\xf5\xea\x82\xfc\x2a\x43\xde\x3d\x4b\xa1\xbb\x29\x9c\xf8\x51\x6d\x61\x41\x2e\x82\x41\xc3\x10\xa8\xb2\xe2\x91\xab\x4b\xf1\x7a\x1a\x46\xa9\x88\x07\xca\xf4\xc3\x35\x19\x92\xc0\xb0\x7d\x38\xa4\xee\xfa\x37\x0c\x2e\x72\x1d\x39\xf9\x1c\x9c\x6a\x83\xe2\x6c\x1a\x12\x6d\x12\x68\x0d\xd4\x16\x0e\xec\xae\x50\x05\xb8\x1b\xa2\x51\xd9\x5c\x99\x11\x21\x0b\x53\x53\x92\xdb\xca\xf7\xf3\x9f\x65\x3b\x30\x4f\x68\xc8\x58\x86\x38\xfe\xf5\xee\xbb\x57\xce\x1c\xaf\xe0\x90\x89\x0c\x7d\x7b\x0d\x03\x9e\x5d\x7b\x2d\x26\x2c\x4c\xed\xea\x2e\x06\xfb\xa7\xbb\x4c\x49\xdc\x53\xe0\xd9\x0d\xe2\x9e\x7f\xfa\xdb\x63\x40\xad\xba\xc7\xe5\xb7\x01\x08\x6b\xf2\x0c\x1e\xa0\x21\x08\x47\xa8\x5e\xa1\x90\xe7\x2d\x34\xcb\xe5\x2d\xb7\xfe\xf5\x38\x50\x4d\xc3\x24\x4a\xad\x56\x6a\xd7\x4f\x3c\x21\x56\xfd\x88\x25\x84\xe1\x57\xb6\x29\xb7\xe7\x41\xe9\x14\x0d\x13\x01\x12\xcf\xd0\xd5\x68\x88\x52\xaa\xb0\x1e\x6b\xb9\x5a\x8e\xff\x2e\x53\x4c\x11\xa0\x6e\xe2\x17\x41\xf1\xf9\x03\x28\x4c\xa5\xe1\x8d\xe5\x4a\x3d\x16\x26\xdc\xf3\xe5\x89\x15\x66\x69\x18\x87\x1e\x94\xe6\xaa\x87\xe7\xbf\x39\x27\x71\xc0\x7b\x75\x81\x6a\x32\x53\x79\x66\x2a\xda\x85\xaf\x9f\xe8\xfe\xa6\x70\x71\xbf\xf1\x7a\xff\x9f\x32\x2f\xfa\x71\xe1\x4a\x21\x2e\xad\x80\x8f\xfb\x52\x0d\xbd\x48\x1a\x8a\x80\x43\xe2\x29\xa9\x04\x54\x8f\x05\x2c\xaa\xd7\x71\x72\x8c\x4e\xbe\x91\x0c\x33\x65\x95\x37\x90\x5e\xd6\x1b\xf1\xd7\x7e\x0e\x52\x75\x79\x1a\x2f\x6f\x24\x9a\x54\xa4\x39\x0b\xda\x5e\x12\x75\xa0\x8c\x3a\x3f\x92\x92\x08\xa7\x65\xbb\x6c\xcf\x79\xf1\x3a\xa7\xc0\xef\xda\x66\x1c\x47\x7d\x80\x31\xb0\x2c\x42\x97\xa1\xbe\xf1\x9d\x10\x2a\xaa\x2d\x1d\xce\xc3\xcb\xfd\xfe\x61\xf1\x73\x33\xe4\x28\xa0\x21\x68\x08\xac\x0b\xbe\x84\xba\x19\x9a\x79\xb6\x85\xa6\x29\xda\xbb\x37\x79\x51\xd6\xbc\xad\xba\x69\xef\xe5\xfa\xba\xcb\x12\xb1\xf9\x0d\x7f\x87\xca\x82\xcc\xc7\x43\xad\x33\xaf\x17\x77\xc3\x0d\x75\xc1\x64\x2e\x68\x21\xf0\xeb\x72\xa5\x26\xbe\xf6\xfc\xe8\x45\x41\x16\x61\xde\x7f\x5d\x48\xa4\xcd\xde\x8d\xc8\xea\x68\x14\x68\xc3\xb9\xe6\xad\x9c\xed\x5b\x7e\xea\x26\xce\x61\x79\xde\x8c\x74\x80\x68\x14\x46\x14\xf3\x29\x75\xeb\xec\xc2\x28\x64\x24\xc3\x25\xea\x59\x89\x47\x89\x1c\x1a\x85\xa9\x42\xf2\x86\xd2\x06\xf6\x47\xea\x8c\x34\x0a\x35\x1f\x48\xc6\x20\x36\xa5\xf3\x95\x7b\x98\xcc\xb5\x0a\xf4\xee\x56\x89\xd6\x81\x35\x64\x71\x51\x7a\xb5\xd3\xd4\x36\x8a\xa2\x8c\x08\x1f\x4f\x77\x6a\x91\xee\xed\x91\x0a\x90\x49\xc7\x86\x00\x07\x65\xdc\x34\x8a\x40\x85\xb6\x52\xfc\xb6\x02\x58\xc2\xbc\xc8\x1f\x8d\x48\x2c\x6d\xca\xa8\x91\x6f\x86\x88\xbd\xf2\x3f\x9f\x51\x93\x5a\x5d\x95\x15\x0c\xa9\x1f\x69\xc4\x32\x88\x7a\xe6\x16\x7c\xf5\x90\xa5\xe9\x6f\xed\x1c\x4a\x6b\x26\x81\x47\xa3\x98\x26\xa4\xa7\xd0\xd9\x72\xed\x7f\x5f\x2c\x42\xc3\x69\xff\x56\x7e\x58\x18\xb9\x81\xbb\x8c\xa6\x5d\x14\x4b\xe2\x38\x69\xd6\x9f\x48\x77\xad\xbc\x72\x79\x7d\x5b\x3a\x41\x87\xf1\xcf\x8e\xb5\x21\xe5\x19\x8a\xcd\xe2\xaf\x37\xec\xcd\xe3\xc6\x49\x60\x30\x3b\xad\x41\xbf\x1c\x6e\xae\xe9\x54\xd2\x28\xc9\x4c\x59\x25\x72\x34\xb4\x45\x33\x83\xf7\xa0\x51\xc2\x63\x84\x81\xae\x3f\x9b\x0a\x8e\xb0\x85\xa6\x3d\x8d\xa6\x75\xc2\x35\x7e\xd9\xb2\x6d\x64\x79\xb4\x18\x87\x7e\x0f\x18\x77\x0e\xe2\x2c\x9b\x40\x99\x1f\xb5\x7b\x52\x9a\x1a\x10\x4b\x37\x38\xbc\x3a\x9c\x17\xc8\x2a\xf4\x23\x6f\xea\x67\x38\xf2\xbc\xf7\xcd\x69\x94\x66\x81\x1f\x12\x5e\x37\x87\xf9\x72\x60\x1a\x65\x81\x70\x65\xb7\xa6\x63\x33\x05\x5d\xa3\x9d\x25\xca\x58\x8c\x24\x0f\x05\x7c\x7a\xde\xf2\x67\xe4\xf5\xea\x1c\x75\xd7\x28\xd5\x58\x14\xb8\x58\xdd\x4d\x5f\x08\x14\x37\xa6\xdd\x7a\x71\xbf\x5f\xdc\xdd\x3d\xfe\x5a\x3c\xac\xd6\xee\x3e\x1e\x24\xc8\x2d\x02\x48\xd5\xf9\x5f\x9c\x86\x91\x60\x1a\xc2\xa1\x7d\xf4\x69\xf3\x4f\xee\xba\x08\xc1\x72\x76\xe3\xef\xdf\x43\xf3\xb6\x37\xa4\x6a\xae\x85\x0a\x30\x8d\x5b\xb8\x0c\xb5\xfd\xbb\x8c\x48\xc2\xcd\x7a\x69\xe0\xb3\x2f\x6e\xa7\x91\xcc\x32\x1b\x45\x32\xef\xfc\xc3\xea\x3d\xff\xcd\xa4\x5d\xf0\x93\xd2\x7f\xd1\x7f\xf7\xff\xc3\x5c\xe8\xfe\xd7\x58\x61\x91\x46\x52\xa4\xb8\xb6\x5f\xcb\x83\x5a\x96\x9f\xe6\x23\x8c\x74\x26\x69\x24\x25\x24\x1e\x85\xba\x1f\xa1\x67\x69\x24\x95\xc1\x90\x61\x7d\x80\x81\x92\xce\xfa\xa2\x91\xd4\x8c\xd8\xf4\xf8\xb7\xf2\x37\x54\x45\x39\x9d\xca\x10\x50\x3c\x15\xf0\x51\x5e\x7b\x96\x46\x10\x1a\x86\x8b\xdd\x8f\x27\xff\x27\x95\x66\x74\x50\xef\xbc\xe3\x95\xd3\xa0\x1b\x26\x9f\xba\x86\x0a\x8f\xc1\x13\x3f\xdf\x02\xd4\xbb\xf2\xf5\xb5\xff\x61\xa0\x34\xc2\x93\x0f\xf0\x1b\x9e\x7d\xee\x88\x46\x3a\x36\x44\x22\xcf\x6f\x5e\xf1\x7d\xdc\x53\xad\x0c\x80\xef\xd9\xb3\xc3\x5e\x55\xee\x30\x77\x90\x80\x71\x04\x07\x7c\x60\xda\x10\x81\x1f\xf7\xfe\x8b\x92\x40\x48\x64\xbb\xfa\x70\x8c\x3f\x8e\xf6\x7e\xfc\x5e\x12\xd2\x04\xeb\x79\x36\x06\xdf\x9a\xff\x1f\xdc\xf3\x22\xd7\x5d\xd3\x2b\xb3\xd5\xe8\xa9\x7b\x57\x9e\x84\x34\xc5\xb0\xee\x91\xbf\x83\xc3\x81\xfe\x31\x3f\xc3\xaf\xa1\x21\xff\x36\xe9\x53\x26\xd0\x27\xf7\x6a\xef\xdf\x79\xfd\xb6\xf6\x3f\x2d\xd4\x69\xca\x5c\xcc\xff\x52\x95\x81\x92\x28\xe4\x4a\x78\x5b\x7b\x53\xec\xde\x60\x7b\xae\x1b\x18\xa7\xa1\x28\x89\x32\x6e\x80\x9f\x06\x08\x89\x83\x8e\x31\x06\x37\x15\x09\x49\x32\x2c\xa0\x31\x41\x96\x4b\xaa\xbb\xc9\x60\x12\x30\x43\x51\xe1\xe6\x75\x9f\xdb\x1a\xa4\x61\xc4\x96\x12\x1a\x45\xc8\xb4\x8a\x1a\x5d\x8d\x8b\x83\xda\x1a\x36\xdf\x28\x66\x28\xcb\xb3\xc7\x98\xe0\xa5\xbc\x1d\x25\x2c\x93\xa1\x01\xeb\x57\xef\x86\xb7\xdc\xf7\x9a\x71\x08\x7c\x66\xf1\xf3\x5b\xc9\x27\xee\x19\x61\x2a\x42\xc8\xe4\xb7\xe7\xf5\xfd\x70\x87\xe8\x2e\x98\xc4\x6a\x67\x71\xd4\x6f\x16\xbe\x60\xd5\xd9\x1c\x35\xf0\xec\x49\x4d\x98\x8a\xd1\xd8\x70\x78\xc4\x49\xe1\x0a\x25\x71\x1c\xa2\xcc\x4d\x89\xc9\xee\x11\x0c\x66\x02\x2e\xa1\x48\x37\x81\x5f\x26\x97\xef\xcf\xf0\xbf\x6d\x5e\x01\x46\xcd\xbf\x34\x5a\x48\x92\x1a\xa2\xd5\xff\xc9\x47\xe7\x15\x49\x44\x86\x05\x47\xcb\x73\x03\xf2\x6d\x07\xf2\xad\x28\x0f\xe5\xab\x0b\x7e\x92\x34\x0a\x39\xb7\xfc\xc4\x28\xb0\x66\x8c\x1e\xdb\xc5\x6d\xaf\xb9\xe8\xdb\x13\xdc\xa1\xff\x53\x97\xc5\x0f\x38\xdb\xb4\xe5\x8c\xf5\x40\xd2\x24\xc3\x92\x0c\x50\xaf\xf0\x94\xbf\x76\x73\x79\xe9\xde\x9a\x71\x8d\x46\xf1\xaf\xc5\xcf\xf5\x21\x6f\x60\xd4\x65\x1e\x73\xac\xf5\x37\x9c\xf5\xf5\xee\xa3\x7c\xe0\xc7\x2b\x1c\x4f\x94\x70\x4e\x70\xcb\xf5\x00\xe7\xbd\x7f\x0e\x64\x08\x79\xf8\xf6\xfc\xf8\x6b\xf7\x7d\xbf\x7c\xb9\x77\x1b\x1e\x11\x49\x46\xac\x28\xf9\x2b\x5c\x62\xfa\x29\x11\x82\x59\xd3\x07\x43\x2d\x26\xc4\xf8\x96\x9f\x2e\x98\xd2\x47\xc7\x29\x91\x31\x41\xab\xb0\xa9\xb0\xd0\xf1\x0a\x18\xc0\x35\xce\xc0\x28\xac\xf8\xfc\xdd\xa0\x6c\x77\xd2\x56\x05\xcc\x88\x9c\x0e\x2b\x9f\xac\x57\x35\xee\xb9\x62\xf1\x80\x04\xfe\x70\xa2\x93\x0f\xa8\x32\x6e\xfc\xd5\xd5\x7a\xe7\xf1\x21\x94\x40\x00\x58\x5b\xb9\x77\x39\x9e\x2b\x1d\x81\x8c\xc6\xd1\xe0\xa8\x18\x8b\x0f\x4e\xfa\x02\x22\x00\x57\xdb\xfa\x9b\x37\x7c\xcc\xf9\x46\x09\xa8\x48\xf6\xc2\x70\x83\xbc\x10\x25\x3a\x8a\x10\xc8\x95\xd7\x6e\xf3\x9e\x30\xbd\x9b\x76\x34\x08\x8c\x08\xaa\x36\x4e\x4b\xdd\x53\x22\x76\xd7\xc0\xe5\x78\x9e\xaa\x52\xdb\xb2\x8c\x31\x62\x86\xd2\x80\x99\x62\xeb\xbd\xa1\xcd\x7b\x36\x59\xb0\xb7\x81\x39\x4f\x83\xd4\xf0\x68\x1b\x1e\xab\x97\xa2\xb3\xd1\x78\x03\x4f\x50\xfd\x09\x0e\xff\x4d\x69\x60\xe9\xc9\x15\x28\xb0\x7c\xbd\x63\x9f\x85\x86\x19\xc1\xfa\x35\x84\x13\x3e\xb5\xc5\xbb\x33\x0d\x66\x87\x8f\x46\xc4\x28\xe7\x60\x94\xc8\xea\xfe\x6c\x07\x09\x3c\x67\xa1\x0c\xfc\x12\x1a\xc5\x1c\x0f\x61\x5e\x89\xbc\xa9\x86\xb0\xc4\x29\x2e\xbc\x3f\xc6\x68\x94\x65\xd2\xb0\x3a\xc3\xe2\x70\x7a\xe3\xc3\xb0\x23\x25\x91\x51\x2b\x7a\x22\x37\x93\x9f\x43\x78\x86\x6e\xdb\x7d\x2e\xcb\xbc\x18\x52\x14\x7f\x51\x0a\x42\x29\x0d\x8d\xe1\x5b\x21\x71\x3a\x1e\xde\xab\x0a\x54\xde\xf4\x31\xa7\xc9\x40\x30\x22\x54\x30\xf4\x25\xef\xf3\xc2\x53\x1b\x4d\x06\x80\xd1\x0c\x8b\xf6\xb4\x29\x3d\x6f\xf9\xe1\x70\x25\xfe\x4d\x59\x62\x58\xba\x0f\xa5\x25\x4a\x49\xfb\x32\xbd\x4b\xb4\x55\x3f\x5c\x0c\x0c\x35\xcf\x73\x77\x64\x1e\x46\x6e\x2f\x8d\x53\xed\xf0\x79\x0f\xf0\xf1\x54\x36\x43\x95\x70\x4a\x93\x84\x23\x2a\x61\xc9\x8b\xf7\xa2\xbc\x04\x8d\xba\x66\x59\x8a\x5b\x83\xe8\x5c\x3f\xc7\x98\x30\x66\x85\xbd\xe0\x81\xa1\x34\x8d\x52\xe1\x2d\x4b\x2f\x50\x30\xbf\x90\x69\x9a\x85\x98\xd1\x5f\xbe\xfc\xf9\xf8\xb2\xdb\x3f\x3d\x6f\xbc\xe1\x4e\x53\x6d\x80\x80\x79\xdd\xf9\x41\x7c\xc8\x3b\xe0\x9a\xf0\x88\xe3\xed\x26\x2b\x8d\x9f\xcf\x87\x8a\xa8\xb0\xf4\x4e\xae\x50\xa5\xac\xbb\x5b\xc3\x59\xa3\x2e\xfd\xff\xf7\xbf\xdc\xbb\xc2\x40\x19\x06\xce\x73\xd9\x36\x8f\xca\x9b\x02\x54\x46\x80\xab\x56\xb4\x55\xf1\x74\xf7\xb2\x7b\xd9\x9a\x7c\xd5\x78\xa8\xa5\x48\x11\xbc\xf1\x3b\xef\x3c\x86\x86\x1f\x4c\x70\x75\x57\x5a\xe7\x74\x3c\x6a\x52\x51\x23\x60\x02\x85\x7a\x86\x09\xb3\xe2\x14\x8b\x4b\xa9\x04\x85\xb6\x7e\xf9\x7f\x7e\x06\x28\x12\x03\x18\x5c\x4d\x83\xea\xe9\x17\x47\xca\x6c\x64\x9a\xaa\x58\x63\x7e\xf6\x69\xf1\xe4\x08\x0a\x28\x85\x38\xa6\x6e\x83\x35\xe9\xba\x61\xb8\x99\x42\x62\xc8\xfd\xeb\x5c\xc1\x12\x9a\x27\x3e\xc6\xd1\x52\xaa\x93\xd4\x41\x74\xbd\xd3\xd9\x9d\xa1\x9b\x62\x98\xe2\xa7\x2c\xe0\x01\x32\x56\x21\x46\xc5\xe4\x79\xc6\xc1\x2f\xdf\x2e\x62\x7a\xa0\xbe\xb4\x97\xe3\xcc\x03\x0b\x94\x11\x6c\xb3\x28\xdb\xb6\xc8\x9b\xf3\x33\x9c\xda\x66\x26\xe6\xcb\xa2\x48\x66\x91\xb7\x40\xb7\x0d\xd7\x7a\xda\x82\x05\x78\x80\xe4\xb2\xc4\xd3\x88\xb8\xf7\x10\x12\x20\xbc\xb3\xf2\xbf\xaa\xfb\xb4\xb8\xd7\x38\xe4\x0d\x65\x44\x2a\x77\x3e\xdc\x9f\x7f\xe6\x45\x7f\x85\x12\x82\x28\xe1\xdd\xcb\x66\xb8\xba\x19\x65\x80\xb1\xfd\x7d\x65\x64\xd8\xb1\x64\x69\x92\xeb\x62\x2c\x4a\x50\x03\xe4\x54\x95\x9f\x39\x4c\x87\x28\x0e\x8d\x0b\x65\x03\x47\x0e\xd9\x4b\x59\x4c\x18\xb5\xf1\x89\x75\xa1\x6c\xa9\xd6\x44\x15\x97\xb2\x38\x63\x81\xed\xf3\x8f\x56\x95\xf5\x34\x4e\xdf\xf9\xf3\xce\x97\x43\x7b\x7e\xc6\xba\x61\x49\x6c\x54\x67\x7f\xad\x57\xee\xed\x89\x16\x24\x19\x54\xec\xce\xdd\x96\xd2\xcc\x40\x13\xcb\xd1\x8e\xf0\xa5\x61\xca\x52\x60\xda\xcb\x90\xdf\x96\x95\x84\xce\xec\x18\x8d\x6a\x16\x28\xa2\x07\xe5\xb5\xf3\x64\x98\x94\x65\x31\x45\x53\xef\x98\x17\xcd\xb6\x3c\x7c\x85\x2f\xa6\x2c\x4b\x23\x84\xa0\x1e\xb9\x52\xb3\x15\xc1\x94\x65\x22\x40\x2c\xf3\x62\xb7\x7b\xde\x3f\xad\x9f\xef\x17\x0f\x6b\x9f\x26\x67\x99\xc8\xf0\x98\xba\xe7\x9f\xdb\x86\x57\x68\xff\x4f\xaa\x9f\x28\xe3\x96\x7f\x50\x1b\x4d\x6a\xff\x67\x1a\xe0\xc9\x22\x2c\x03\xcf\x70\x7d\x5f\x9e\x31\xee\xa6\x58\x63\xc8\xd3\x50\x82\x5d\xf2\xe4\xb8\x66\x3c\xc0\xca\x7d\x83\x17\x7b\xe3\x95\x55\xd2\xaa\x07\x21\xf0\xc1\x43\x95\x51\xde\x32\x01\x85\xbc\x90\xc0\x02\xd7\x4b\x41\x43\x06\x1e\x4c\xe2\x70\x5b\xee\x7d\xf4\x82\xf4\xf0\x5f\x61\xf8\xef\xb9\x24\x30\x93\x54\xb3\xb4\xe7\x8b\x0b\xdd\x0b\xa4\x32\xca\xa4\x79\x91\x37\x7b\xdd\x5b\x66\x4c\x85\x99\x1a\xf2\x8e\x2d\xe1\x19\x8d\xfd\xa9\x79\xc7\x14\x89\xa4\x9e\x6c\x50\x9d\x2b\x53\xdf\x01\xb2\x3b\xff\x4f\x3d\x04\x63\xf9\x9b\x4c\x21\xb1\xf4\x52\x07\x9e\xfb\xd7\x77\x80\x19\xba\x1f\x54\x2a\xe6\xaf\x70\xbd\x78\x71\xd2\x9f\x94\x3b\x76\xc2\x5f\x79\x81\x73\xe2\xb6\x2a\x8f\x08\x79\x9a\x75\x09\x98\x4a\x0d\xc5\xda\xb7\xea\x7c\x7a\xf3\xe7\x27\x53\x4a\x19\x78\x16\x86\x5a\x1c\x8e\x1f\x19\xc2\xa9\x6f\xa3\x0d\x7b\xff\xea\x71\xbb\xf9\xf6\xb0\xbf\x5f\xfc\x13\x45\x06\xdc\x65\xa0\x1c\x43\xc0\xdb\x8f\x5c\x37\x37\x3e\x5c\xc7\x40\xa6\x88\x67\x7d\x6a\xc7\xf5\x36\x94\x81\x36\x95\x55\xa5\xd6\x87\xbc\x80\xee\xad\x28\xdf\x53\x1e\xd4\xd7\xab\x38\x0e\x12\xa3\xfa\x7a\xf7\xb2\xfa\xd3\xe5\xbf\xe3\x20\x23\x98\x40\xd9\x07\x9f\xf7\x65\xc1\x3b\x23\x70\xb8\xae\xe3\x30\x0d\x6c\x12\xce\xf9\x93\x8f\xda\x54\xab\x5e\xd7\x5f\xe8\xee\x32\xcc\xe3\x8f\xef\x77\xf9\xef\x69\x99\xfd\xe8\x78\x8d\xc3\x34\x43\xf0\xc8\xfd\xe6\x61\xbf\x79\xf8\xb9\xde\xee\xf6\x8b\xd5\xce\x97\x5b\xd1\x38\x0a\x18\xfa\xdd\xff\xdb\xf2\xf7\xe9\x59\x1e\x47\x31\x60\xf7\x9e\xda\xe3\xe9\x7b\xa9\x0e\xfe\xa6\x94\x21\x3f\x99\xe4\xf5\x5b\xd9\x36\xeb\xc7\xed\x12\x6b\x1b\xdf\x27\xfa\x3d\xae\x39\xa7\x98\xbe\x39\xf2\xcf\x81\x52\xdf\xf0\x1c\x8e\x23\xa1\x42\x9b\xb3\x6b\x4f\xa6\x24\xde\x5e\x21\x71\xe4\xe8\xdf\xf7\x98\xd9\xdc\x77\x9b\xdb\xbe\xf1\x12\xa5\xe3\x77\x11\x6e\x98\x13\x57\xfc\x94\x37\xfc\x80\xb9\xee\xd1\x90\x13\x11\x04\xa6\x16\x16\x25\x64\x9c\x6d\x61\xf2\xcc\x5f\x26\xaa\x62\xaa\x9d\x98\x99\x35\x69\xaf\xec\xac\x31\x83\x04\x45\x62\xac\xa2\x8f\xd1\x6a\x2a\x74\xf9\x55\x01\x0c\x8d\x63\x12\x22\xdc\xf6\x5b\xe7\x65\xe5\x03\x82\x78\x1a\xc7\x34\xc6\xaf\x74\xbb\xf9\xe7\xfa\xe6\x79\xfd\x6b\xf1\x7c\xb3\xbf\xbf\x77\x57\x93\x24\x30\xe4\xa3\x9d\x83\x6f\x22\xe5\xaa\x3c\x0d\x72\x21\x71\xc2\x09\xd2\x0c\xf7\x8a\x8f\xfe\x8a\x30\x12\x46\xfb\xd3\x81\x5f\xaa\xbd\x7c\x99\x1e\x8c\x33\x0a\x48\x8c\x0b\x72\x8c\x17\x8b\xb3\x24\x46\xc8\x3c\xa2\xb2\xf7\xbf\xee\xfc\xdf\x41\x60\xb8\xdf\x50\x64\x75\xdb\x82\x0f\x9a\xcd\xdb\xe0\x31\x8f\x08\x8f\x1c\x0f\xa5\x5a\xfc\x86\x8a\xbf\x82\xa3\xbf\x1f\x75\x86\x47\x99\x2b\x71\xbf\x47\x8a\x3d\xe4\x88\xbf\x2c\x36\xa7\x31\x27\xdc\x08\x4e\xc9\x12\xf1\x03\xa1\x35\x26\x5c\x2f\x79\x1c\xa1\x03\xdf\x8d\x08\xe6\x6c\x7c\x46\x22\xe6\x5c\x63\xd0\xe3\xe9\x8d\x57\x47\xfe\x0d\x8a\xb2\xbf\x4d\x44\x2a\xc3\xda\x41\x28\xce\xcb\xb6\x50\x87\x3e\x3d\x11\x8b\x98\xa2\x54\xcb\x03\x7c\x18\xf6\x8e\xf1\x74\x6b\x67\x4b\x91\x68\x2c\x89\x34\x61\xdf\x56\xeb\xd1\x24\x96\x5c\x72\xe8\x59\x5a\xf6\xcd\xa0\xfb\x12\x98\xd3\x59\x7d\x2c\x00\xad\xba\x5b\x80\xda\x42\x12\xa6\x20\x92\x58\x45\x91\x0d\x93\x57\xbf\xa1\x5a\x17\x48\xa8\xb3\x2a\x0b\x7d\xc8\x65\xb3\x39\x9e\x0e\x23\x17\xd2\xd8\x07\xfd\x84\x18\x1b\xe2\x57\xff\x9d\x3d\x2a\x62\x45\x25\xb2\x18\x35\x6f\xfc\xc3\xb1\x32\xd9\xe5\x38\xb1\x09\x63\xa5\xcd\xaa\x35\x45\xb1\x98\x6b\x1c\x37\x00\x02\xe8\x90\x75\xf6\xf2\xb7\xb2\x7c\xba\x82\x76\x8c\x21\x0e\xa9\x89\xe6\xad\xee\x57\xce\x92\x89\x41\x51\x3c\x86\x35\xc0\x45\x69\x07\x8d\x35\x01\x9c\x5a\x07\x5e\x37\x26\xec\x31\x92\x4c\xa0\x49\x10\x06\x68\x1a\x72\x3e\x94\x82\xa1\x49\x10\xa5\x18\x3e\x47\xaf\x6a\xff\xbc\xd8\xad\xf7\xab\xe7\xc7\x5f\x37\xdb\xc5\xdd\xda\xdf\x4b\x42\x47\x04\xf3\xa3\x9b\x54\xee\xef\x61\xac\x0c\x4f\x5c\x2f\xd6\x3d\x10\xc6\xb6\x8d\x22\xc6\x92\xc4\x2b\x9c\xc8\xff\x4e\xa5\x8e\x26\x91\x4c\x1c\xb1\x0a\xce\x8f\x5f\xd3\x88\xd6\xf4\xa8\x9b\xd2\x6d\xd1\x84\xb0\x30\x32\xdf\x2e\xaf\x94\x49\x89\xf4\x73\x30\xa1\x01\x37\x95\x79\xa3\xd2\xb5\x71\xdf\x69\x16\x60\x10\xd3\x54\xd4\xdc\xe4\xbf\xf3\xa1\xec\xc3\x95\x9e\xd3\x4c\xa0\x52\x42\xfd\x56\x7e\x6c\x86\x60\x19\xff\x66\x48\x2c\x18\xbd\xb3\x96\x6e\xdb\x42\xd5\xb7\x65\x75\xcd\x54\x4c\x58\x94\xf4\x14\x85\xdb\x06\x4e\xce\x3f\x4a\x18\x17\xda\x30\xdb\x15\x30\x5f\x76\x45\x13\x26\x95\x66\x4e\xba\xee\xa1\x6f\x66\x2f\xc7\x4a\x51\x83\x65\x3a\x95\x55\x73\xcf\x0f\xb9\xcc\xcb\xf6\x52\xd7\x6a\x38\xae\x89\x8a\x88\x2f\x19\xde\xe8\xc5\xa1\x02\xae\xce\x18\xe2\x87\xce\x39\xb8\x19\xec\xd2\xe3\xf1\x4c\xa9\x56\x56\x0e\xf3\xbe\x7e\x1d\x61\xec\x92\x34\x05\x0d\x56\x57\xd1\x7c\xf2\x9f\x65\xe3\xcf\xd8\x24\x15\x2c\x42\x79\xfa\xbb\xc5\x6e\xf3\xf0\x72\x6f\xe1\xb0\xfb\xdd\xd3\xce\x37\xd1\x12\xa7\x38\x6e\x88\xbf\xde\x00\x2e\xaa\xe3\x86\x3b\x57\x92\x85\x34\xea\x09\xca\x56\x65\x79\x50\xe5\x47\xe1\x36\xda\xae\x25\x35\xe9\x43\x1a\xb8\x3b\x58\x8a\x99\x70\x23\x32\x33\xea\x7d\xc6\x25\xc4\x63\xea\xc2\xfa\x1a\xfb\xc8\xc4\x77\x48\xff\x35\x48\x41\x4e\x93\x91\x09\xd7\x0c\x6d\xe7\x95\xed\xe5\x84\x85\xbb\x6b\xe0\x85\x20\x9f\xad\x24\x65\x6f\xc4\xfa\x70\x57\x22\x64\x10\x58\xf4\x3e\x1a\xf1\x7e\x60\x25\x95\x8e\x6c\xd7\xa6\xd0\xec\x74\xed\x8b\x88\x67\xcf\xbd\x44\x6a\xe6\x68\xce\x46\x8a\xa6\xf6\xb2\x62\x42\xa4\x76\xb7\xab\x8d\x66\x7e\xb1\x6c\xcf\xe8\x1b\xae\x9d\x04\x02\x4d\x20\x11\x68\xc3\xd7\xa5\x6e\x24\x3f\x91\x67\xe0\x88\xfc\x73\x97\x33\x66\x75\xbc\xfe\xd3\xd6\x98\x29\x9e\xfc\x7c\xc8\x8c\xea\xd2\x30\x8d\x66\x2a\x2a\xae\xcc\x41\xd0\x26\xc0\xcb\x7b\x1b\xd6\x8f\x85\xb6\x85\x5f\x96\xb5\x74\xfc\x89\x75\xe0\x55\x48\x5c\x71\x6c\x7f\x23\x07\xcc\xd9\xf3\xb6\xc1\x90\xd3\xb2\x6c\xfc\x25\x19\x21\x5b\x19\xaa\xf6\x78\xe9\xee\x29\x1d\xb4\x69\x9c\x06\x91\x29\x68\x58\x28\xaf\xc6\x3d\x51\xed\x19\xfe\xf8\x34\x88\x95\xee\xa9\x9b\x4d\xaa\x6b\x80\x52\x49\x03\x60\xa9\x0d\xd2\x42\xd5\x5c\x8b\x51\xd9\xc6\x61\xc8\x03\xab\x22\xbe\x59\x3d\xee\xba\x4d\x73\x64\x32\xa5\x21\x11\xc8\x75\xb3\x6d\x5e\x1f\x0b\xc0\xe2\xba\x75\x3f\x91\xd2\x90\xc9\x2c\xb6\xf5\x74\x0b\xf5\x7b\x34\xb2\x69\x98\x72\x93\x71\x2a\xf3\xe2\x29\x47\xc2\x95\xd9\xa8\xa0\x6f\x6e\x50\x33\xfb\x0b\x20\xe3\xf8\x6b\xa6\x51\x94\x65\x43\x31\xd3\xc5\xcb\xee\xd1\xf8\xa3\x61\x70\x31\xba\x91\x04\x6e\xf6\xcb\xce\x28\x71\x5d\x23\x54\x92\xc0\xd7\x01\x36\x63\x8a\x24\x9a\x12\x91\x84\x12\x23\x08\x93\x93\x2d\x25\x02\x34\xbf\x0a\xe2\x9b\x45\xe6\x7c\x99\x10\x4f\x69\x68\xca\xc2\x4f\x86\x98\xa2\x5e\x7a\x2d\x97\xea\x8f\x51\xd0\x23\xa5\xc4\x80\x31\x3b\x8f\x1a\x53\x1d\x43\x0b\xa8\x7f\x20\x0b\x09\xa7\x5e\x0a\x1b\xc5\xa2\x8a\xba\xe1\xde\xa7\x49\x59\x94\xa1\xf7\x89\x5c\x6a\x36\xc5\xec\x2e\x65\x01\x96\x5b\x3e\x2d\x9e\x77\x0f\xeb\x67\xcb\x50\xe8\xaf\x72\x99\x59\x53\xd6\x00\x97\x6e\xcb\xca\x7e\xf1\xd9\x84\x68\x1a\x93\x00\xb3\xbd\x0b\xa4\xb9\xaa\x1d\x4c\x65\x32\xa4\x31\xd5\xc8\xac\x61\x2e\x9a\xb6\xbe\x69\xbf\x9b\xa5\x71\x4a\x31\x05\x7d\xaa\x60\x23\x4b\xe3\x8e\xba\xae\xc5\x2a\x44\x4c\x19\x9e\xd9\xa1\xdb\xd3\x7a\x5a\x09\x9a\x26\x61\x40\x32\x4f\xab\x08\xb9\x81\x8e\xde\xb4\xdd\x08\xa1\xb9\xed\x40\x79\x69\x1a\x01\x2e\x5e\x4b\xb6\x81\x46\x44\xe0\x2f\xaa\x58\x1b\x26\xd3\xf2\xf4\xa8\x35\x54\xbd\x35\x9d\x66\x89\xb1\xa6\x5d\x24\x6e\x02\xa8\x9f\x0c\x4e\xc6\x8d\xef\x64\x6b\xa3\x4d\x49\xc7\x64\x68\x78\xa0\x10\x09\x62\x04\x21\x86\xa6\x76\xca\x89\x29\xc7\x36\xd2\x06\xf2\xfd\xa9\x99\xc0\xb1\x52\x27\xc0\xea\x69\x9c\xf3\x23\x1c\x30\x02\xfc\x35\x46\x23\xe5\x09\x8b\x03\xeb\x4f\x6e\x25\x3f\x4e\xfc\xe6\x54\x84\x52\x07\x16\xd0\xbc\x67\x7b\x23\xaa\xf6\x0c\x46\xd4\x27\x2f\x8b\x3d\x4a\xa9\x74\x3b\xd8\xbe\xf3\xc3\x0f\x6a\xf7\x56\x95\x1f\xae\xe3\x32\x4e\xc1\xe2\x66\xbb\x3e\x58\xcc\x62\xed\x62\x27\xa9\x62\x1c\x2d\xe1\xfd\x9c\xcc\xe7\x97\xb1\x8e\x54\x65\x04\x21\x18\x7f\x6f\x2b\xfe\x97\xd9\xac\x54\x65\x19\xe2\x1e\x3a\xab\xfd\xa6\x3d\x9e\x06\xe3\x32\xae\x74\x74\xed\x05\x41\x26\x9f\x85\xae\x72\xc9\x7b\x29\x34\x9a\x2a\xc9\x90\x6b\xe8\xef\x5c\xbe\x9f\xca\x66\xf1\xc1\xab\x81\xd2\xd0\x95\xce\x42\x68\x4a\x14\xf2\x23\xd2\xda\x9b\x36\xc3\x12\xd0\x69\x79\x44\x0a\x0c\x1c\x45\x86\xdb\x23\x6e\xa0\xe1\xf9\x3c\x21\x00\x4d\x21\x0d\x33\xe9\xbe\x53\x79\x82\xc2\xb0\xf2\xf8\x60\x67\x0a\x5c\xc8\x60\x00\x73\xb3\x47\x69\x5f\x1f\x46\x53\xd0\x46\xe5\x51\x1f\xca\xb2\x72\xda\x5d\x34\x0b\x32\x9e\xd8\x52\x1d\x5b\x84\x37\x1b\x3b\xc8\x02\x1e\xe1\x98\x35\xe5\xcb\xc6\x55\xed\xbb\x4b\x4a\x23\x01\x78\xee\xe9\x02\xbf\x34\x3d\xb2\x50\x1b\x25\xd3\xdb\x03\x7c\xe6\x8e\xe2\x72\xcb\xbf\xa8\xc6\x1c\xdf\x4f\xb8\x46\xa3\x4a\x1e\xca\x1a\xac\xb5\x60\x2f\x51\x1e\xa4\xbe\xd4\xcc\x66\x8f\xdc\x25\x69\xc2\x67\x0d\x1c\xd0\x5a\xfe\x51\xa0\x22\x49\x3b\xc0\x56\x65\x54\x27\x28\xec\x77\x07\xea\x15\x0c\xfb\x58\x7b\x21\x3d\xea\xb1\xcd\xf6\x26\x96\x1a\xe0\x7e\xc5\x1b\x78\xd9\xde\x48\xcf\x43\x4e\xb3\x38\xf3\x6c\x71\x86\x15\x6f\x51\xa8\xc5\xf1\x0a\xd8\x34\x4b\x92\x34\x48\xbc\x62\xc7\xff\x41\x31\xeb\xd6\x64\x29\x31\xac\xb8\x56\x2b\xd3\x68\x08\x4f\x9a\x68\xa9\x2d\x55\xc0\x4b\x91\x3b\xa5\xea\x8d\x55\xed\xfa\x0b\xb8\x74\xc6\x43\x53\xcc\x60\x69\x05\xdf\x78\x05\x46\x36\xf1\x4a\x73\x22\x30\x1d\xe2\xe8\x3d\xec\x24\xa8\xa6\x6b\x70\x76\x6a\x67\x3c\xd5\xd2\x24\x6b\x65\x5b\x59\x85\x6a\x74\x46\xd0\xb3\x1a\xd9\xc2\x7f\x9b\xa4\x10\xa6\xff\xda\x27\x8a\x8c\x42\x36\xd8\xbc\x77\x9f\x13\x17\x3d\x93\xc4\x90\x11\xbe\xda\x30\xc9\xa3\x01\x92\x6e\xea\x2d\xcc\xd3\x46\xd2\x4c\x11\x81\x96\x8a\x29\xe6\xc1\xf0\x80\xbb\x92\x69\x6d\xab\x8b\x1a\x2b\x3b\x35\xd9\x66\x33\x00\x26\x3c\xbf\xd1\x4b\x71\xea\x49\x31\x68\xa6\x33\x83\xcc\x5b\x6f\x9e\x92\x30\xba\x79\xbc\x5f\x6c\x1e\xf6\xbb\x3f\x9f\xd6\xdf\x17\x5b\x3f\x8f\x34\x70\x27\x68\xf9\x93\x57\x79\x77\x98\x5d\x25\x99\x99\x74\x5c\x83\xc6\x75\x7b\xe4\x9f\x8b\x22\x3f\x72\x0f\x2e\xe3\x41\x6c\xea\xc9\xf3\xfa\xc7\x9f\xab\x27\x5e\xd7\x57\x04\xd4\x29\x0f\x14\x57\xae\x86\xa1\xf3\xce\x7a\x15\x25\xca\x43\xa2\x91\x5d\x80\x6b\x9d\x1f\x72\xde\x18\x30\x81\x25\xc3\xf1\x8d\x00\x4c\x66\x8b\xd7\xe8\x41\xb8\x70\x80\xa3\x67\x70\xcd\x34\x60\x66\xd7\xc9\xcb\xfd\x02\x78\x3f\x9c\x07\xd5\x99\x46\xbe\xca\x70\x69\x0c\x38\x5a\xed\xed\x91\x8c\x71\x98\x2d\x77\x4b\x44\xb6\x9e\xff\x9c\xf2\x48\xc5\x31\x75\x24\x16\xe6\x18\xbd\x05\xac\x80\x99\x3c\x04\x62\x43\x28\x65\x25\x29\x2e\x4b\x43\x87\xde\x34\x8f\xb4\x01\x10\xd5\xd0\x38\x49\xe7\xf1\xf3\x48\xc8\x50\x7e\xe4\xc4\xe5\xfb\x25\x84\x9e\x93\x34\x14\xe9\x40\xd6\xe9\x79\xa2\x6b\x44\x39\x95\x02\x73\x92\xb8\x15\xdc\xe7\x87\x77\x77\x2b\x85\x08\x63\xa0\x1f\xc0\x4f\x9d\x49\xe1\x85\xe6\xc6\x1d\xa0\xda\x88\x3a\xa2\x7a\x82\x61\xb4\x99\x00\x09\x38\x0b\x28\xda\x5c\x6d\x61\x49\xe0\x41\x19\xb0\x8e\xef\x26\x23\x0c\x23\x9a\xc6\x55\x79\x80\x8f\x89\x7c\xc1\xe8\x3c\xe6\x4c\x84\x18\xc4\x74\xba\xdd\x5f\x47\x7d\xec\x4d\x49\x16\xcb\xd0\x79\xc2\x1a\x2a\x98\x58\x97\x3c\x0d\x99\xe3\x08\xb9\x3f\xef\xda\xaa\xf1\xd1\x6b\x9e\xb2\x0c\x11\x48\xcb\xc5\xc3\xea\xf1\x79\xff\xcf\xfe\xef\x02\x9f\xc9\x0f\x87\xf2\xc3\x80\xbb\xa7\x0f\xcd\x00\x33\x1d\x07\x28\x5e\x9b\xb7\xbe\xea\x7e\xbc\x8a\x78\xca\xe3\x24\x18\xec\x18\x73\x94\x1e\x94\xa7\x82\x25\x16\x73\xa1\x3a\x7f\x04\x79\xcc\xba\x0f\x4e\x26\x6f\xcd\x68\x24\x0d\x40\xac\x2d\xde\x07\x75\x7f\x3c\x8b\x13\xe6\xea\x50\xce\x26\x80\xdd\xfd\x4b\xa2\x71\xfd\xbb\x6d\xcd\x33\xca\x87\x8c\x47\xd7\xc6\xf9\x12\xa7\xc2\x15\x89\x04\x0c\xc8\xf7\x77\x15\x4c\xb7\x2d\xae\x04\x45\x72\x32\x24\x13\xbc\x81\xba\xc9\x0b\x7e\x29\x67\x46\x39\x84\x31\x4f\x87\xd0\xa0\xcd\x24\x85\xc8\x81\x84\x86\x1e\x14\xc1\xca\x03\x52\x20\x2a\x02\xa6\xa9\x2d\xc5\xd8\xbd\xf5\x65\xa0\x5f\xd4\x44\x88\x20\x96\x98\x83\xde\x02\xa8\xed\x54\x7f\x88\x8a\x90\x42\x60\x8d\xf7\x6d\xfe\x5a\x20\x49\xd6\x38\x09\x27\xc2\x8c\x61\x48\xb4\x8a\x26\xf7\x46\x94\x63\xb9\xf8\x90\x4f\xcf\x5d\x4a\x29\x7a\x92\x7b\x54\x27\x52\xd0\xed\x61\xeb\xe6\xed\xda\x98\xbb\xbb\x32\xa2\x6c\x67\x96\xed\xf9\xb9\x1b\x3f\xff\xc0\x2c\xe6\xc9\x90\xcf\xa3\xac\x86\x90\x7f\x11\xf1\x18\x07\xed\xdb\x81\xff\x5e\x55\xe7\x53\x83\x47\xbd\xbf\x0a\x52\x5a\xb2\x6c\x03\x4a\x9a\x57\xbf\xa6\x82\x30\x8d\x18\xe2\x9b\xcd\x4f\x77\x2f\x49\x32\x34\x85\x80\x57\x45\x5e\xbc\xd6\x8f\x7a\x64\x2a\x09\xc2\x59\xd8\xb3\xd2\xd9\x58\xf5\x80\x3e\xfc\x82\x3a\x95\x0a\x1a\x68\x24\xb1\x6c\xde\xe5\x78\x87\x13\x54\x69\x8c\xc1\x3f\xf1\xf3\x40\x92\x96\x0a\x46\x19\xa2\x62\xef\x17\xff\xdc\x6f\x3b\x37\x75\xe1\xcb\xb1\x04\x93\xca\x84\xea\x7e\x1b\x7a\xa5\x0b\xc4\x9d\x4d\x10\x38\x1b\x4c\x30\x9d\x22\xde\xe3\x6e\x37\xaa\x0c\x14\x71\x64\x84\x60\xad\x6b\x66\x9e\xb0\x85\xa6\x19\x32\x7c\x4f\xad\xa1\xb9\x39\x17\x27\x60\xf5\xe2\xcc\x7a\x79\x46\x1b\x32\xfa\x63\x80\x58\xeb\xc3\x7e\x22\x16\x0c\xed\xaf\xbc\x18\xd4\xc8\xf9\x3e\xc9\x08\xd1\x18\xa2\x91\x46\x9a\xba\x2a\x7f\xe7\xaa\x1f\xfd\x58\x83\xb5\x88\x0a\xf5\xd3\xd7\x5d\x88\x24\x94\x58\xc9\xbb\x59\x3d\xee\xef\xd6\x3f\xd7\x77\xfb\xd0\x5f\x4a\x43\x9e\x8e\xbe\x57\x5f\xc3\x79\x8d\xdc\x8e\x8a\x44\x1a\x69\x7e\xe9\x40\x40\x3f\xcb\x66\x40\x6e\xe0\xdd\x75\x91\x06\xda\xb0\x3a\x15\xd2\xcc\x93\xc7\x8f\xcb\x3d\xdd\xb6\xcd\xa2\xc8\xe1\x48\x7e\xe2\x8e\xf1\xea\x10\xe6\x7f\x45\xb5\xf2\x05\xda\x4f\x64\xa9\x09\x74\x6c\xf8\xeb\xd8\x79\x16\x9c\x33\x1b\x5e\xc7\x83\x2b\x9a\x32\xb5\xb9\x98\xac\x6b\xae\x29\x86\x54\x36\xff\xd8\xed\x6f\x5f\x1e\x6e\x8c\x24\xfe\x48\xb7\x81\x0a\x11\x84\xf8\xcc\x37\x5e\xbf\xed\xeb\x37\x4e\x66\x77\x7b\x21\x99\xe2\x26\x05\x51\xb7\x47\x98\xd4\x77\x0b\x99\x08\x77\x16\x18\x71\x06\x5b\x6e\x37\xfc\x59\x2a\x05\xe4\xb0\x2a\xda\xe3\xde\xaa\xa5\xfa\x65\xa3\x80\x61\xc8\x0d\x3d\x19\x4b\x24\x35\x94\x98\xa5\x02\x84\xb2\xf1\xa6\xb6\x86\x3b\x5e\x1b\xee\x5f\x77\x55\xeb\x30\xb2\xda\x1a\xcb\x03\x97\xef\x58\x83\xd1\xc0\x04\x4b\x2e\x83\x38\xc3\x12\x42\x77\x84\x6c\x8a\xb5\xab\xee\xb5\x4f\x92\xa1\x20\x08\x31\x6d\x3c\x26\xc9\x46\x65\xf6\xbe\x85\xcc\xa8\x09\xf3\xaa\x69\xd4\x4e\x86\x2a\x45\x5b\xbb\x33\x99\x1d\x93\xf0\xac\x95\x29\xa3\x08\x10\x7b\x83\xfc\xba\xc8\x7a\xf7\xdb\xcf\x7e\x19\xd1\x08\x8f\x89\xa6\xad\x8a\xee\xb7\xfa\xbf\x43\x82\xac\x32\x86\xf7\x69\x6c\x3a\x49\x12\xa4\xf6\x90\x6b\x96\x50\x80\xce\x65\xce\xab\xf3\xca\xcb\x36\x51\x49\x92\x10\x91\x21\x35\x6f\xca\xfa\x2d\xdf\x8b\xe6\x6d\xaf\x40\x0e\xed\x64\x49\x32\xc3\xf1\xb4\xfd\xb5\x78\xda\xaf\x16\x0e\xc0\xde\x39\xa2\x4e\x9a\x62\xc5\x4f\xfe\xaf\x3c\xc5\xe2\x34\xd1\x9e\x1f\xe0\xe3\xa6\x2a\xa7\x35\xf7\x92\xaa\x00\xcf\xa7\xd5\xf3\x72\x87\x73\xf9\xae\x0f\x7f\x49\x0a\x04\x1d\xf9\x6f\x8f\x77\x37\x2e\x49\xb2\xfd\x71\xd7\x5f\xa6\x68\x59\xb9\x8a\xcb\x3d\x22\x90\xa6\xc1\x11\x9c\xf1\xff\x22\xee\x13\xb0\x80\x1b\x00\x4f\xae\x9b\xaf\x50\x05\x92\x65\x12\xdd\x0c\x68\xde\x36\x8e\x53\x44\x76\xc7\x87\x41\x77\x57\x20\x39\x2e\x69\x54\x3c\x77\x07\xa3\xec\xdc\x08\x83\xf1\x3c\x9b\xd4\xf3\xd7\x19\x36\x19\x27\x31\x76\x67\xf7\x3c\xda\xab\x65\x9c\x0a\x4a\x9d\xdf\xe6\x03\xb9\xb7\x65\xe5\x89\x63\xfb\x67\x24\x94\x89\x78\xa0\xc5\x73\x8b\xd8\xaf\x2b\x3f\x2b\xa5\x11\x1e\x77\x7b\x38\xe6\xcd\xdf\x4b\xb1\xcc\x87\xf2\xd1\x33\xfb\x8d\xcc\x02\x85\x8b\xd7\xad\x8a\xef\x65\x5b\x43\xb7\x93\xfa\xeb\x9a\x4a\xb7\x24\x5e\x6a\xa8\xea\x2d\xff\x3d\xb1\x43\x24\x87\x34\x8d\x3d\xc1\x5e\xcb\x0f\x3b\xa3\x86\xef\x40\xf4\x83\xf7\x89\x28\xb3\x4a\x94\x27\x9e\xfb\x81\x15\x82\x65\xa1\xd5\x87\xf1\x19\x09\x29\xac\xb6\x59\x5e\xef\xca\xb6\x7a\xb1\x28\xcf\x89\xd5\x2f\x85\xe6\x46\x65\xa5\xc6\xa0\x71\xd5\x0e\xb8\x02\xa4\x0c\x63\x8c\xe6\x76\xe7\xf8\xb6\x18\x84\x9d\xdc\x75\x66\x04\xc9\xb9\x52\x5b\x84\xd4\x8d\xe7\x97\x6b\x15\x03\x32\x72\xee\x5e\x01\xbd\x42\x23\x98\x35\xd8\xf1\xfd\x96\x38\x3f\x0f\xa4\x8e\x81\x0f\x2b\x25\x4d\x94\x77\xdc\x48\xa7\x1c\x33\x9c\x36\x47\x62\xd8\x1c\xc6\x85\x97\x7f\x79\xa0\x4c\x2a\xc6\xa4\xce\x08\x66\xf2\xef\xa1\xe1\xf7\x65\x75\xf2\xbb\x81\x96\x0c\xf7\x8b\xa7\x6f\xeb\x20\x7c\x70\xd1\x72\x15\x84\xd4\xc9\x94\x3d\x55\x60\x30\x70\xab\x32\xf7\xe9\x11\x15\xa6\x02\x03\x5a\xbd\xdc\x7c\x59\xbe\x2d\x2f\x83\x9e\xb6\x79\xc4\x22\x4c\xea\x1a\x3a\xef\xb1\x69\xaa\x22\x96\x71\x8b\x46\xda\xd4\xe3\x72\x94\xfe\x27\xa8\x28\x49\x0d\x92\x67\xb7\x9b\xc4\x9b\xc7\x9b\xaa\x8a\x84\x29\x35\xc1\x14\xc1\x70\xb9\x29\x92\x45\x88\x4a\x94\x03\x39\xcb\x8d\x1a\x1d\x31\x8a\x46\x11\xa2\xf8\x9e\xa1\xce\x55\xcb\x0f\xdb\x21\x53\xeb\x9c\x9d\xa4\xa8\x56\x2e\x10\x89\x9f\xd3\xb2\xe8\xed\xf2\x23\x2c\x79\xbf\x69\xa8\x38\x56\xc8\x79\x97\xfb\xba\xbf\xf1\xea\x51\x49\x12\x60\xbe\xae\x28\x15\xf4\xa6\xed\x78\x20\x13\x91\x61\x78\x0d\x8b\x5b\xdd\xb4\xd8\x7e\xe4\x03\x59\x96\xf9\x10\x97\x4a\xb9\x59\x1e\x3f\xa1\xe0\x83\x42\x54\x95\x85\x41\xa4\x5d\xe9\xc0\x67\xb3\xb9\xf1\x3f\x76\x74\x7b\x96\x50\xdc\x1f\x8c\x00\xde\x33\xd4\xd7\x37\xbd\xc9\x8b\x39\x8f\xd0\x65\xc3\xf4\xc6\xed\x85\xcf\xa5\x84\x8e\xa3\xc8\x6c\xa6\x33\xf0\x5f\x25\x43\x86\xa4\xcb\x8e\x21\xec\x69\xa4\x9a\x4b\x95\xe4\x2a\x74\x52\x89\x03\x0e\xa5\xf1\x43\x14\x11\xe8\xee\xa3\x93\xd3\xed\x5e\xbd\x9b\x34\x13\xb2\xeb\xe9\x02\xbf\x60\x0d\x4c\xdd\xa3\x19\x47\xc9\xab\xbc\xee\x0e\x69\x24\x7d\x5f\x5f\xab\xad\x51\x4a\x81\x52\x7d\xfe\xc0\x05\x8f\x47\x79\x5b\x05\x8a\xba\x02\x6e\x93\x28\x5a\x42\x53\x8f\xcb\x30\x6c\x4b\x4d\xc2\xc0\x00\x6f\x3a\xd7\xcc\xe2\x20\xd1\x10\xc6\x98\xd3\x78\x24\x21\x0c\x25\x6e\xae\x5e\x3b\xe5\x1a\xe4\x19\xc2\x08\x06\x2a\x2b\xf7\x79\x81\x14\x95\x73\x38\x44\x08\x63\x81\x3a\xa2\xbe\xea\xf5\x0b\x90\x25\x84\x49\x86\xa6\xf2\xbe\x2c\x1e\x7f\x83\x5d\x22\xd6\xb1\xba\x16\xd7\x4b\xff\x45\xfe\x8d\xff\x17\xda\xc3\x1d\xa2\x0c\x62\x7b\x12\x62\xd8\x74\x04\x83\xbd\x92\xb7\xb8\x96\x84\xb1\x8f\x24\x54\xa1\x13\xdc\xd9\x61\xb8\x88\xc7\xbf\x75\x7e\x49\x01\x49\x02\x97\x53\xdc\x1a\xba\x80\x66\x98\xf4\x03\xc2\x63\xcb\xd6\x50\xd5\xcd\x50\x39\x92\x02\x0d\x45\x14\x5d\x9c\xfc\xee\x2a\x13\x09\x26\xea\xcc\x11\x60\xb2\x8a\x8b\x42\x3d\xf1\xb3\x0b\x8f\x38\xd8\xf5\x4c\xb8\x63\x1a\xf8\x00\xa6\x15\x26\xd5\xf7\x35\xd7\x9e\x7e\xbf\x7b\x90\xe7\x59\xbe\x76\xac\x0c\xfc\x08\x88\x23\xc3\x10\x7c\xe4\x9f\x38\x38\x43\xa8\x29\xc4\x9c\xf3\xd8\x97\xde\xa0\x17\xb6\x51\x23\xcb\x14\x62\x19\x63\xcc\xbc\xec\x0e\xce\xb1\xc3\x0c\x49\x60\x92\xe2\xc7\x52\xbe\x7b\x30\x8b\xbf\x33\x09\x0d\x89\x39\x0e\xa3\xd5\xa8\x1c\x00\xa3\x20\x51\x21\x9a\x26\x08\x48\xb2\x12\xfb\xe3\x0f\x95\x32\x81\xdc\x52\xfa\xd0\xd6\x6f\xa3\x3c\x3f\x64\xc4\xb0\xab\x89\xbc\x50\x7f\x2f\x45\xb7\x8e\x96\x25\xaf\xae\xd4\x7d\x42\x96\x1a\x82\x90\x6d\x7e\x3c\x1d\xc0\xe6\xa4\xfa\x0a\xc3\x69\x6b\x48\x03\x2b\x6a\xe0\xa5\xe2\xc7\x2d\x38\x37\x58\xe2\x3d\x82\xa5\xf6\x68\x5d\xed\x37\xab\x47\x97\x51\x04\x11\x09\x62\xea\x83\x9b\xce\xe0\x1a\xa2\xf4\x26\xde\xbb\xbb\x21\x05\xfc\x4e\x2e\x73\xba\x87\x21\x45\xc6\xa4\x83\x52\x0b\x3c\xfe\xef\x8d\x2b\xb6\x7a\xe3\xc7\x53\x5e\x16\x17\x7c\x9d\x14\x00\x40\x64\x56\x1e\x03\xab\x76\xc5\x94\x2f\x06\x74\x68\x6a\x9a\x30\x9c\x59\xf4\xa5\x41\xe6\x90\x9a\xad\xdf\x06\x9d\x45\x98\x0b\x78\x3c\xe6\x35\x7c\x7b\xfc\x56\x1e\xfc\x12\xd1\x56\xb9\xcf\x3a\x27\x4f\x15\xc8\xbc\x27\x02\xa6\x3a\x88\x05\xcf\x6c\x15\x7c\x35\x21\x0f\xa5\x3a\x48\xa4\xd6\x0e\x32\x6f\x95\x50\xfa\xc0\xf6\x46\x5d\x0a\xfe\x4c\x6c\x26\x1d\xf0\x00\x09\xbe\x96\xbb\xd5\xb0\x32\x51\x87\x51\x88\x94\x54\x47\x53\xe8\x6d\xf1\x3f\x8b\xc6\x5f\xa7\xa1\xb6\x07\xea\x2f\xc8\x9f\xa0\x5a\x7d\xbf\x9d\x74\x2e\xa4\x12\x93\x9b\x95\xcd\x3b\xcf\x5b\x32\x3a\x94\x80\x68\x3e\x79\x00\x5e\xad\xda\xca\x48\xc1\xcc\x7e\x49\x1d\xf1\x18\x1d\x52\x74\x25\x7f\x71\x8f\x16\xd1\x11\x4f\x10\x43\xf2\x0d\x0a\xd8\xca\x1c\x2e\x58\xf2\x34\x61\x0a\x09\xe5\x7a\xda\x8e\x19\xfe\x35\x4d\x62\x22\xec\x80\xfe\x34\x61\xff\x6e\x1f\x9a\x36\x92\x41\xe6\xb1\xf7\x75\x2e\x9f\xf9\x45\x13\x46\x59\xec\x7d\xde\xa6\x15\xb0\xe3\x63\x60\x9d\x66\x52\xa5\x91\x5b\xef\x53\x7d\x44\xaa\xe3\x28\x20\x8e\x8a\x0a\x63\x33\xb3\x28\x4d\xdb\x38\xd1\x21\x86\xd5\x6a\xc9\x0f\xa0\x4c\x78\xf3\x69\xc4\x92\x4a\x75\x1a\x85\x88\x23\x1a\xed\x8f\x57\x86\x39\xe5\x0a\xc1\x67\xb2\x2c\xea\xf6\xb0\x2f\xfc\x2e\xa4\x53\x91\x61\x1e\xbd\x01\x54\x5e\xfe\xda\x23\xd4\xa9\x26\x4e\x10\xc1\xc6\xaf\x26\x15\xd3\x3a\x63\x61\xe0\xc8\x6e\x5e\x8a\x13\x3f\x83\x72\x29\xa6\x49\xc3\x34\xe1\x3d\x2e\xf4\x57\x59\x5d\xd4\x1c\xe8\x2c\xe3\xd8\xc4\xd0\x1a\x39\xd4\xdd\x78\x13\xd6\x3c\x33\x04\x44\xaf\x3d\x2e\x0f\x87\x69\x10\x06\x1f\x81\xca\x47\x8b\x5f\x73\x9e\x21\x29\xf2\xb2\xca\x8b\xf9\x6a\xdc\xf6\xa2\x50\x51\x0b\xc5\xcd\x22\xcd\xc5\x1d\x3f\x8a\x72\x62\x5c\x68\x49\x38\x1e\xa0\x27\x43\x60\x68\xb2\xe6\xc3\x93\x52\xcb\x34\xc3\x98\x91\x68\xc5\x00\x3c\xac\x25\xb0\xcc\xb0\xf8\xb5\x55\xf3\xe6\x58\x80\xf0\x64\xef\x4e\xea\x21\x0c\x4c\xab\x28\x8e\xb8\x2b\x15\xf3\xb4\x3f\x33\xde\xf2\xfc\x97\x54\x3c\x22\x30\x2a\x60\xd8\xc8\xb2\x5b\x4a\x98\xd2\x99\xe8\x33\x77\xbe\x42\x8c\xd9\x2f\x0c\x61\x6d\xa4\x0b\x8d\x6b\x88\xe2\x84\xf9\xaa\xf1\xa6\xdc\x28\xcb\x06\x3b\xa5\xe7\xd4\xa0\x12\x9c\x68\x5c\x29\x74\xd2\x4d\x19\xec\x95\x00\x87\xd6\x24\x46\xa1\x99\x31\x0d\xff\x95\x6a\x30\x16\x04\x49\x84\x80\xc2\x9b\xdd\x60\x89\xb0\x20\x00\x8e\xac\x0a\x6d\x0d\xd5\x13\xa0\x46\xf6\xaa\xe2\x0d\x58\xdf\x69\xf8\x13\x59\x10\x06\x11\x15\xbe\x6a\x60\xd5\x9a\xfa\xa2\x3f\xc6\x2f\x0a\x59\x80\x0e\x24\x72\xf8\xdc\x3f\x3e\xec\xbe\x3b\xac\x16\x0b\x42\x61\x0b\x48\xa1\x31\x3f\xee\x5e\xce\x9d\x1e\x2c\x20\x61\x10\x82\x8b\x47\x15\xc8\x52\xdd\xdb\x5f\x2c\x20\x49\x12\x29\x8f\x5b\x7e\xe9\xe6\xdf\x80\x4d\x8b\x05\x84\xa7\x4e\xb9\x74\x07\xfc\x78\x3b\xc9\xbf\x61\x8e\x90\x12\x2b\x4d\xb2\x05\x57\x54\x3d\x67\x42\xb2\x80\x52\x81\x15\x0e\x79\x7d\x03\xb5\xac\x72\x44\x3d\xdd\x5a\xa7\x45\xb9\x9f\x46\xb3\x04\x8b\x0c\x86\xe0\xb4\xee\xaf\xa6\x30\x4d\xc1\x6f\x38\x94\x27\xa8\xf6\x66\x99\xf8\x42\xd6\xfd\xef\x19\x4f\x81\x05\x54\x18\x12\xf7\x55\x79\x28\xab\xfa\xde\xa7\x1a\x58\xc0\x82\x54\x0d\x8a\x19\xec\x59\x7c\xd3\x56\x83\xad\x94\x05\x4c\xa6\x08\x90\xfc\xbf\x4f\xb9\xf5\x27\x2f\x0b\x18\x18\x0d\x7d\x28\x54\xcf\x78\xc9\x82\x98\x2b\xec\xbb\xd5\x9e\xf0\xd0\x50\x2c\x45\x9b\xe2\x7c\x59\x90\x44\x21\x72\x3b\xfc\xa7\x45\x99\x2b\x07\xa2\x62\x41\xca\x88\x66\x9e\xb6\xef\x09\xf7\x24\x9b\x65\x73\x2d\xd2\x18\xdf\x84\xe0\x9f\x55\x59\xd4\x50\xd4\xe7\xfa\xa1\x6c\x46\x60\xdb\xee\x37\x1a\x76\xc9\x0a\x40\x41\x05\x47\x63\x63\xd7\x93\x8e\x64\x31\xc7\xa8\xb1\x06\x18\x52\x56\xcf\xad\x17\x16\x64\xd2\x14\xaa\xe0\xf4\x77\x22\xf2\xee\x9a\x12\xc4\xee\x90\xf8\x3d\xce\x58\x22\x32\x9e\x06\x1c\x38\x66\x10\x51\xdd\x1c\x83\x07\xf3\x4e\x16\x0b\x84\x30\x3c\xcd\xdd\x30\x40\xdb\x54\xfc\x70\xef\x0a\x92\x07\xe6\x2f\x0b\x84\x8a\x90\x7d\xaa\x31\xd4\xc6\x37\x50\x94\xc7\x6e\x3f\x2e\x7d\xbf\x04\x04\x68\xde\x1e\xcf\x4f\x07\x5e\x40\x33\xda\xa6\x27\x2f\x05\x4f\x1e\xfb\x64\x0f\x03\xb4\xa7\x27\x43\x26\x29\x75\x05\x90\x76\xea\xcc\x48\x5c\xb2\x40\x66\x89\xea\x95\x4f\xb6\x4d\x59\xf1\xd7\xe9\x80\x48\x91\x99\x6f\x69\x0f\x56\x23\xca\x71\xc1\x69\x33\xe9\xa7\x4a\x8c\xa6\xc7\xcd\x62\x35\xda\x88\x54\x4a\xb1\xb4\xfd\xe9\x71\xbb\x72\x7f\x03\x19\xda\xf2\x84\x53\xb9\x38\x9d\x36\x7e\x7a\xe8\xd0\xe4\x50\x2c\xc7\x3c\x12\x5b\x8d\x60\x1a\x2c\xd0\x69\x84\x4c\x6e\x9b\x5f\xbc\xbe\xed\xec\x8d\x2d\x54\xbf\x73\x09\xa3\x97\x6a\xcd\x70\x7c\x25\x2f\xb6\xad\xb8\x24\x0b\x1d\xf7\x3d\x0c\xc2\x14\xfb\xf8\xfb\xa4\x47\x6a\x4e\xb3\xbf\x34\x0c\xa8\x24\x36\x7e\xe1\x80\x71\x8b\xa3\xeb\x5f\x18\x30\x43\x90\x88\x4e\xe2\xfa\xe6\x65\x78\xfa\xb1\x30\x90\x59\x10\x5f\xa2\x7a\x1e\xda\x23\x54\xb9\x9c\x9f\x77\x61\xa0\xb8\xe3\x52\xa9\xa7\x0e\x49\x77\x55\x60\x19\x62\x6b\x00\xf0\xdb\x26\x3f\x1c\x96\xed\x79\x90\xf6\xf5\x0d\x8d\xb6\xa4\x29\x77\x75\xe6\xfd\x2d\xd6\xe3\xf9\x63\x26\xfd\xb7\x6b\xad\x13\x93\x65\x36\xf2\xdd\x07\x90\x73\x45\x7b\xff\x72\xcd\x43\x12\xe2\x19\x27\x79\xb1\x84\xed\x44\xc1\x8d\x85\x21\x27\x66\x91\x3a\x74\x28\x96\xb3\x5e\x8f\x3c\xb0\x30\x14\x01\xc6\x77\x9d\xe6\xdb\xcd\xee\xe7\xbc\x54\xf1\x75\xd9\x3b\x16\x86\xa0\x4c\xe5\xf2\xa1\xac\xc1\x4a\xcb\xd9\x4b\x51\xc8\x10\xc7\x63\xb9\x5d\xbb\x15\xd8\xbb\xa8\x2c\x8c\xa2\x58\x10\x03\xf9\x2a\x91\x0e\xf2\x15\xee\xf3\xa2\xc9\x8b\xd7\x9b\x7e\x83\x0d\xa3\x8c\x20\x41\xec\x16\xc0\xf8\x83\xfe\x82\x0a\x91\xd4\xbe\xdb\x0f\x57\x2e\xe2\xba\x69\xe0\xe8\xe7\x7a\x48\x22\xce\x2c\x54\x64\x85\x63\x6c\xfa\x77\x03\x35\x46\xba\x3a\xdb\xd7\xb0\x51\xdb\x0f\xf5\xb3\xa7\xaf\x63\x21\x21\x29\xa6\x94\x50\x83\xb4\xe2\x26\xd2\x3b\x3f\x90\x84\x09\x6e\x88\x4e\xe4\xfb\xb9\x68\x8f\xfe\x11\x36\x7f\xfd\xe3\x26\x1c\xae\x9d\x90\x28\x86\x20\x7b\x43\x7e\xb8\x50\x6a\x40\x92\x3c\x3c\xcb\x42\xa2\x63\x4c\xb9\xae\xef\x9f\x76\x7f\xee\x9f\x16\xcf\x8b\xfb\x7d\x0f\x08\x63\x21\x65\x81\xe4\x03\x8c\xdb\x46\x2d\x9a\x9e\xd8\xbf\xef\x60\x67\xf2\xa0\x6c\x1d\xaf\x9b\xbc\x2f\x0e\xbe\x1e\xc1\x65\x21\x8b\x02\x66\xb1\x83\x38\x2c\x91\x7b\x27\x8b\x23\x5c\xc9\x6a\x86\x6c\xf2\x4b\xb3\x90\x85\x71\xb7\x0b\x38\xd6\x80\xce\xa0\xa4\xee\xa1\x71\x04\x88\xb8\xfc\x0d\x85\x9a\x88\x80\xb1\x30\x26\x0c\xe3\xbb\xc2\x0d\x57\x6f\xa1\xb3\x30\xc9\x4c\xb5\x47\x03\xfc\x18\x58\x14\xa4\xbd\x94\x86\x91\xa1\xad\xce\x0b\x5e\xc8\xbc\x78\x1d\x86\x9b\x58\x98\x05\x19\xd6\x51\x62\xa9\x43\xe1\xb8\x56\xfd\xdd\x59\x67\xe1\xa1\x28\x6e\x83\x9b\xe4\x7e\xd2\x2b\x1e\x65\x10\x8c\x29\x25\x31\x43\x65\x2f\x0b\x30\xd4\xfe\x98\x99\x43\x2a\xa7\x6f\x16\xf5\x36\x3f\xec\x93\xa1\x12\xda\xd0\x62\xad\xd6\x9b\xbb\xcd\xc3\x37\xf7\x54\x29\x59\x16\x8d\xe1\x6b\x3d\xbb\x4c\x6f\xe5\x85\x52\x31\x54\x1e\xec\x46\xf9\x17\xaf\xea\xe7\x5d\x2d\xbd\x36\x5f\x77\x39\x76\x1a\x52\x77\xa5\x7c\x9f\x00\x4c\x27\x5d\x91\x10\xe2\x89\xb1\x83\x03\xbc\xf2\xc7\xb6\x99\x6c\x7a\x52\x87\xc6\x23\xe7\x07\xb9\xe4\x98\x20\xbb\x2d\xab\xf1\x31\x6f\x9b\xaa\x30\x16\xb1\xa7\xba\x73\x85\xa2\xbf\x20\x77\x1d\x53\x32\x43\x0e\x7b\xf8\x3c\xe5\xd5\x79\xf5\x06\xf2\x7d\x64\xdd\x45\x01\x8d\x8d\x0d\x57\xdf\xc0\xe9\x50\x9e\xbd\xdd\xd3\xf9\xab\x48\x8d\x89\x75\x5d\xdb\x86\x17\x6a\x18\xb1\x9a\x80\x4f\xa7\xda\xd3\x2c\x0a\x69\xa8\xb8\x8b\x86\x6f\xf3\xd7\x31\x03\x0a\x8b\xc2\x98\x62\x0d\x72\xd5\x53\xa4\xb8\x2b\x89\xc9\x8c\x7e\xae\xcc\xae\x7f\xdd\x9f\xf8\x52\x69\x87\x45\x24\x34\x47\x2a\x57\x6a\xa8\xfc\x78\x61\x56\x47\x44\x31\x65\x93\x43\xc8\x0c\xf9\xc4\xab\xc6\xe1\x0a\xc6\xff\x8c\x5e\xe8\xee\x06\x8d\x25\xf0\x3f\x1f\x6e\x30\x07\xfe\x57\x2e\x29\x8b\x68\x08\x51\x36\xe6\x1f\xb4\x3c\xf1\xae\x41\xc4\xa5\xf5\x6e\x5c\xc0\xe4\x92\xd2\x95\x45\x34\xa6\xcc\xd5\x53\xe4\x47\x03\x11\x9d\x91\xa6\x65\x51\x12\x98\x7c\xfc\x7f\x14\x3f\xc0\xef\x1a\x4b\x5a\xea\x1e\xa0\xcf\xa2\x84\x18\x85\xb1\xa7\x5b\xac\xd9\xb8\xca\xac\x35\xb7\x1f\x39\x88\x30\x8b\x92\x44\xe1\x38\xe6\xf5\x93\x65\x1a\xac\xae\xe8\xdc\xb2\x28\x8d\x74\x32\x44\xfe\x18\xb7\xf6\xb6\xac\xac\x90\x80\x5d\x43\xd3\x6a\x30\x16\xa5\x1a\x90\x90\xfb\x66\xc4\x62\xce\xa2\x2c\x92\x71\xe2\xc5\xce\x1d\x62\xa3\xfb\x3b\xa8\x6c\x98\x45\x5c\xbf\xbe\x0e\x83\xa4\x93\x49\x93\xa5\x09\x5a\xa5\xdd\x07\x7b\x87\x41\x50\x8e\x45\x99\x30\x91\x56\x67\x65\x76\x9f\x66\x14\x2b\x9d\x4c\x4b\x7b\x1b\x17\x49\x92\x0e\xb0\x14\x5f\x1a\xa5\x11\x57\x1a\xd7\xcd\xb2\x14\xf5\xc3\x4f\xfe\xea\x5e\x2e\x54\x4a\x6c\xf4\xfb\x86\x9f\x4e\x66\x3a\xcc\x55\x15\xb1\x48\x66\x24\x96\x7e\x7a\x2d\xcf\x1b\xe5\xcf\xaf\x7e\x0d\xb9\xb6\x96\x28\x06\x9f\x67\xb9\x6f\x8c\xfd\xb7\x77\x6f\x96\x0a\x1c\x78\xf2\x19\x14\xc0\x91\xbb\xe2\x82\x1a\x85\xe1\xaf\xf4\x02\x68\xa0\x82\x41\x3d\xd1\xfa\xf3\x64\xca\xd8\xed\x75\x1d\x44\xe8\x00\x2e\xef\xb6\xfb\xa7\xe7\xf5\xde\xf3\x05\xb1\x48\x67\xa6\xf2\xc1\x22\x8e\x3d\x45\xe1\x05\x95\x89\x69\x4f\xc2\x28\xc4\xa4\xd3\x2f\xc8\xf1\xe8\x28\x0f\x33\x0a\x44\xd7\x75\x4b\x18\x09\x65\x84\x15\x56\x60\x38\x1f\xc7\x0f\x57\x0c\x45\x83\xb7\xbb\xe7\x97\x51\xc0\x82\x90\x24\x73\x87\xc7\xb2\xac\xeb\xef\x4f\x37\xa0\x51\x62\x77\xdc\x3b\x92\x18\xae\xbe\x8a\x17\xaa\x3c\x46\xfe\xee\x2c\x24\x91\x2d\x4e\xc7\x18\xa3\xf2\x57\xb4\x74\x21\x03\x7b\x9a\x0c\xa5\x8a\x6d\x23\x1a\x28\x69\xe2\x0e\xa8\x80\xa8\xf6\x1f\x90\xe3\xb1\x68\x04\xfe\xdc\xb3\x68\x6c\xa6\xb3\x55\x67\x37\xfe\x98\x53\x74\x1c\x24\xa1\x2e\xf6\x58\x7f\xbf\x16\x61\x8f\x39\xde\xe3\xa6\x71\xb1\xdb\x13\x2a\x38\x15\xbd\x6c\x91\x87\x46\x7d\xa9\x94\xca\x08\x0b\x08\x8e\xfb\x3d\x7f\x85\x4f\x2f\x3b\xc7\x08\x0b\x63\xa6\x6d\x89\x26\x3f\x98\xac\x54\xe9\x38\x5f\x86\x9b\x2f\x89\xa9\x40\xde\xc1\x6f\xd0\x23\x02\x7f\x41\xfe\xfa\xd6\x80\x32\xb0\xf6\xc9\x99\x49\x62\x99\x31\x47\x18\x5f\xe7\xb6\x44\xff\x4a\xff\x62\x50\xd8\x0f\xd1\x9e\x6f\x8e\x07\xcc\x68\x8f\xbf\x42\xc2\x23\x04\xfb\x9f\xaa\xbc\x90\xf9\x89\x1f\x1e\xdb\xa6\xee\xce\x4a\x5f\xf5\xc6\x48\xa2\x33\x46\x7d\xb5\xae\x39\x66\x9f\xb1\x76\xef\x4b\xeb\x8e\xa4\x84\x38\x9a\xf9\x3b\x5e\x37\x63\x24\x1c\x23\x59\x1c\x24\x4e\xdb\x31\xb7\x49\xb6\x3d\x06\xbc\xf7\xc5\x00\x6d\xc0\x08\x0f\x0c\xda\xc0\xc1\xff\x1f\x4a\x5f\x76\xcf\x08\x17\xe6\x28\xc2\xa4\xd0\x63\x71\x38\x9b\xfe\x19\xd1\xca\xda\xbf\x8c\xab\x04\xa9\x65\x7f\xf0\x4a\xf1\xfa\x2d\xe7\x45\x7f\xc5\x84\x57\x07\x4e\xcf\xaf\xb2\x7a\xaf\xdf\xca\x93\x6b\x22\xc2\x08\x55\xdc\x8f\x9d\x87\xe7\xe9\x72\xfc\xd5\x4c\x06\x56\x9f\xae\x3b\xc4\x0c\x0e\xc4\x5f\xe4\x5a\x08\x27\x1c\x92\xe3\x6d\xb3\xb5\xa3\xb6\xb9\x8c\x4c\x1e\xbf\xb7\xdf\x6f\xab\xf2\x28\x96\x4f\x6f\x13\xe1\x36\x46\x64\x1c\x62\x75\x19\x7a\x7f\xc3\x23\x78\xdc\x0a\x02\x34\x1b\x71\x13\xbb\xa9\xb8\x8b\x2f\x11\x15\x4b\xb0\xe0\x95\xc5\xe1\x30\xa5\x43\x75\x8d\x52\x9a\x12\x9f\x64\x6f\xf9\x61\xd7\x4b\x75\xf9\x07\x09\x8d\x89\x08\x95\xd7\x9d\xcb\xd7\x56\x60\xfc\x97\x6b\x26\xce\xe8\x5f\x27\xf9\x1d\x8e\xff\x73\x52\x65\xc6\x88\xd2\x51\xe0\xc8\xf4\xaa\xea\xa5\xf3\xc0\x72\x38\xa8\xd0\x77\x42\x67\x58\x48\xd2\x16\x28\x1a\x6c\xe3\x13\xf3\x1b\x3b\x01\x4a\xd0\xeb\xd8\x7c\x7f\xbc\xb9\x1b\x6d\x88\x00\x04\x53\x00\xfb\xda\x97\xcd\xaf\x78\xa5\xfa\xdc\x89\x37\x15\x88\xce\xa2\xd8\x7e\xd8\xe5\xb9\x2d\x5b\x8b\x42\x18\xd8\xdc\xdd\x2e\xc8\xbc\xd8\x51\x7d\xe3\xc2\x96\x7e\xe4\xb4\x36\x29\xfa\x1f\x79\xb7\xdd\xff\x7a\xf3\xb4\x3b\x8c\x06\xa1\x91\xe4\xaa\xa1\xf9\x47\xcb\x8b\x26\xef\xdc\x9c\x63\x8e\x13\x7c\xfe\xdc\xa7\x01\xd3\xc8\xb4\xe3\xb8\xd2\x5f\x6a\xa8\x0c\x72\xea\xca\x39\xe2\xee\xd3\x19\x1e\xa0\x76\x5d\xc3\x81\x9f\x7d\x2f\xb4\x88\x7b\xfa\x83\x65\x7b\x7e\x68\x8f\x33\x05\x07\x8c\x86\x61\x80\xde\x85\x2d\x03\x7e\x58\x6c\x6f\x16\xff\x18\xcf\x25\x1a\x86\x09\x72\x38\x3f\xaf\x6f\xbe\x6d\xee\xee\xdc\x3b\x42\x8b\x58\x9a\x8a\x54\x5d\xa9\x0d\x67\x34\xe4\x4c\x28\x5f\xfd\xbe\xb8\xbf\x9b\xbc\x27\x8a\x0d\xc0\xd5\x9a\x51\xe3\xcd\x93\x46\x71\x82\xd1\x09\x3d\x41\x94\x31\x4a\xb2\xc4\x28\xfb\x99\x22\x65\x57\xb6\x34\xbf\xb1\x52\xc2\x0d\xc8\x0d\x7e\xf3\x43\xcb\x1b\x58\x54\xc0\x67\x58\x75\x06\x37\x08\x8a\x6e\xe9\xa6\x68\xc0\xaa\x6c\x3d\x6a\x13\xb8\x77\x43\x41\x64\x86\x70\x07\x05\xbf\x3d\x2f\xca\xf8\x21\x34\x0a\x6d\xc8\xd7\x89\xdb\x3e\x94\x8d\x27\xfc\xf3\x07\x30\xa5\x91\x4e\x94\x2b\x24\xef\x0e\x6d\x33\x79\x5d\x55\xfe\x78\xc0\x28\xd5\xb8\xbb\x89\xf6\x3c\x73\xd6\xb9\x3a\xba\x41\x27\xe2\x34\x12\x9e\x71\xf7\xb6\xac\x96\x6d\x55\x4c\x3b\xaa\x53\xb4\x59\x31\xe0\xf6\x8c\x66\x1c\x82\x32\x78\xd3\x4c\x24\xb6\x2c\x54\x9f\x51\x46\x0d\x11\x97\xcb\x06\xb8\xdf\xc2\x64\x90\xa9\x11\x88\xee\x4b\xbe\x99\xf1\x6f\x8b\x03\x48\x42\x67\xfa\x75\x06\x44\x67\xfa\x8d\x3d\x8c\xe9\x1d\x8c\x63\xdd\xda\xef\xb2\xc9\x8b\xd7\xba\x67\xe3\x61\x34\xe6\x59\xe4\x02\xee\x3e\xa8\x86\x23\xf6\x52\xe7\xc5\xeb\x33\xff\x40\xea\x67\xdb\x3a\x09\x28\xf4\x68\x8f\xf7\xad\xe3\xc0\x9e\x8c\x54\x12\x64\x91\xcf\x03\x1d\xa0\x6e\xa6\xc0\x60\x46\x13\x6e\x76\xd8\x7d\x63\xf8\x53\x5a\xf9\x06\x55\x3d\x0a\x72\xd2\x44\xa5\x3a\x1c\x18\xab\xe6\x37\x6e\xf9\x01\x88\x6f\x02\xe6\xc0\xa8\xa1\xf9\xce\x1b\xf9\xe6\xf2\x1c\xcb\x73\xd7\x2d\x47\xd8\xeb\xdc\x14\x9a\x12\xb3\x1e\xe0\xb3\x1b\x88\x36\x77\xe0\x68\x46\xd3\x24\x8e\x1d\x89\xe6\xb9\x1f\x88\xcd\x6a\xf1\xe4\x53\x7a\x30\x24\x51\x1f\x3b\x94\xf6\x29\x19\x15\xf8\xab\xb6\x2b\x17\xbd\xa2\x59\x0a\x8e\x66\x73\x67\x62\x30\x0b\xf5\x3b\xaf\x4b\x2c\x8f\x35\x70\xc6\x8b\x6a\x96\x2b\xbb\x5a\x96\xc5\x22\xf1\xfa\x28\x43\xc9\xf7\x69\x43\xa0\x56\x7f\xfa\x60\xf8\x38\x17\x13\xf3\x97\x66\x10\x23\xa8\xe3\x66\xf1\xe7\xd6\xf7\x14\x12\x0c\xf0\x59\x00\x2f\xa6\x41\xf2\x6e\xa6\x23\x27\x7c\x6d\x8b\x8f\xe7\xb7\x0e\x1e\xc4\xae\x5e\xcd\x32\xba\x1b\x55\x8f\xa1\x9c\x46\xd7\xca\x70\x25\xe3\x89\xbb\x5f\x17\x4d\x95\x3b\x62\x12\x46\x45\xc4\x50\x39\x13\xf3\x27\x46\xe9\xec\x60\x8f\xdc\x70\xfa\x03\x05\x8b\x99\xa9\xb1\x1a\xf1\xb9\xfc\xed\x92\x91\x92\x51\x99\x06\x18\xae\x7e\xfe\x34\x3c\x63\xee\x7d\x52\x91\xcc\x76\x79\xcb\x0b\xf5\x91\xcb\xb7\xce\xa2\x5f\xf1\x43\xd9\x75\xeb\x12\x91\xc8\xa8\x62\x46\x52\xbf\x2e\x9a\x3d\x76\x73\xea\x40\x53\x95\xc6\x81\x3d\xe3\x56\x25\xba\x48\xd1\xa4\x05\x24\x04\x88\x57\x5d\x43\xbf\xa9\x3f\x5e\x29\x64\xa1\x1c\x88\x5a\x62\xcc\x63\x7e\x32\xe8\xc0\xa9\x16\x60\xd0\x77\x24\x5b\x70\xad\xa6\xfc\xeb\xc8\x25\xd5\x84\x06\x16\x9a\xf0\x8d\x1f\x61\x7d\xf5\x6b\x6b\x46\x10\x51\xfa\xa8\xb1\xcc\xe0\x60\x52\xcc\xdd\xa7\xb0\x83\xcb\x02\x62\xe2\x54\xdc\xaa\xd9\xd9\xfc\xb8\x9d\x0f\xfd\x79\xef\x9a\x33\x43\x9b\xd6\x94\x26\xd2\xfa\x65\x3f\x59\x14\xab\x70\xaa\xd8\x33\x23\x36\xcf\x18\x09\x02\xc4\xf8\x7f\xe4\x07\x25\x79\x65\xf3\x83\xa1\x7b\x0e\x49\x28\x3a\xc3\xae\xc0\xe0\x66\x60\x27\x30\x1a\x31\xdc\xea\x70\xae\xe2\x97\x1c\x6d\x4e\xdd\xe1\x87\x07\xdb\xa9\xfc\x80\xea\x86\x9f\x9f\xa0\x7a\x82\xaa\x2e\x8b\x15\x3f\x6d\x8a\x3e\xda\xc7\x68\x6c\xf4\xdd\x9a\xd1\xee\xba\x2b\x07\xe4\x8d\x97\x90\xa4\x2f\x4f\x00\x46\x33\x23\xc0\x75\xcc\x8b\x1b\xa7\x75\xe8\x2e\xf1\x18\x8d\xca\xbc\xc8\x2d\xb1\xae\x51\xa2\x9c\x9d\x44\x2c\x8e\x15\x97\x23\x1d\x35\xbd\x2a\xdb\xaa\xf6\x8f\x4b\x18\xe8\xc0\x05\x0c\x87\x08\xc2\xaf\x93\xa9\x2c\x11\x99\x61\xf4\x96\x3e\x84\xc8\x12\x15\xe1\x82\x5b\x9e\x1b\x40\xb3\xc8\xcf\x96\x04\x18\x7a\x7f\xfb\x57\x68\x7e\x61\xde\x75\xdc\xcd\x94\x03\xda\xa5\x13\xf8\xf7\x05\xe2\x91\xb1\x2c\x08\x08\xf1\xfc\x22\x4d\x3b\x27\x15\xc1\x58\x16\x09\x88\x3c\x0f\xc4\xa8\xb6\x77\x7e\x9c\xb2\x84\x12\x43\x2c\x2b\x0f\xad\x9a\xae\x7a\x96\x49\x82\x70\x50\x91\x37\x1f\x65\xa5\xea\x55\xdb\x3c\xb6\x4d\xa9\xc3\x20\x70\x3f\x91\x07\x11\x6e\xae\x5b\x47\xf8\xcb\x98\x88\x85\xb0\x90\xa9\xeb\x52\x0c\x8c\xc9\x50\x62\x38\x19\x63\xec\x0f\x5f\x06\xd9\x67\xb6\x3f\x26\x69\x18\x76\x7d\xbb\x5d\xaf\xf7\xab\xef\x8b\xe7\x6f\xeb\xe7\xfd\xcd\xfa\xe1\xf1\x7e\xf3\xb0\xd8\x3d\x3e\xff\xe1\x9b\x69\xa4\x6a\xcd\xeb\x1e\x0d\xd3\x62\x11\xb1\x6e\xdd\xfe\xcd\x54\xa0\x9d\x27\x67\x77\xf9\x99\x5d\x92\x29\x62\x04\x2b\xad\xde\xef\xb7\x5f\xfe\x76\x0e\x18\xfa\xf5\x62\x97\xfe\x82\x32\x32\xf7\x79\x7d\x07\xaf\x9e\xcb\xe2\x8a\x92\xa6\xbd\x07\x02\x40\x21\x11\x61\x4b\xf0\xf3\x52\xb9\xc3\x7f\x53\x7c\xef\x26\xb1\x7b\x3a\xd0\x18\xe3\x19\x77\xeb\xdd\xe3\xa0\x94\x81\x31\x27\x43\xe4\x2a\x5f\xf6\x4d\xb9\x2f\x7b\x52\x2a\xc6\x00\x22\x3c\xd5\x0a\xf8\x6c\xb6\x50\xf7\x18\x44\xc6\x74\xa8\x91\x94\xb4\xc9\x8f\x38\x99\xb1\xfc\xfe\xaf\xd1\xb4\x8c\x69\x22\xa8\xe5\x25\xdd\x14\x9d\x25\x59\x56\xf3\x7a\x01\x8c\xe9\x38\x30\x82\x6c\xdd\xe2\x5b\x14\x56\xb6\xe6\x12\xe0\xcd\x98\x16\x04\x61\xb4\xdb\xc5\xed\x7a\xff\xb4\x7e\xde\x3c\x5a\xd2\x5c\x16\x47\x81\x82\x6e\xfb\xb9\x2b\x5f\x97\xed\xc5\x9b\xe6\x77\xd8\x98\xb0\x50\xf6\x25\xf0\x7d\x84\x6f\x78\xf7\x25\x11\xe5\xd8\x12\x1f\x7f\xaf\x98\x64\xa0\xd0\x34\x7a\x59\xce\x3b\x7b\x31\x63\x21\x4e\xf4\x53\xe9\xbe\x50\xcc\xb2\x04\x65\x7c\xf7\xbf\x23\xff\x27\x10\x96\x80\xc5\xf0\x24\x7e\x94\x9d\x41\x68\x93\x5e\xe3\x07\xc6\x8a\x12\x39\xf0\x1e\xc7\x0c\xfb\x63\x6f\x3c\x4e\xc2\x10\x53\xb0\xc7\xf6\x10\xbb\x8c\x5d\x9c\x48\x15\xc5\x03\xe0\x7c\xab\x06\xf5\xf0\x73\xc9\xcc\x38\x01\xb3\x53\xd4\x6f\xe5\xc7\xfe\x08\xfb\xe6\x0d\xf6\xc7\xb2\x80\xb3\x7f\xa4\x26\x18\x59\xb1\xb1\xbb\x85\x52\x16\x73\xe7\x25\xff\xfa\x1f\x90\x46\x86\x90\xcd\xb8\x6f\xbb\x5c\xbe\xcf\xac\xb7\x38\xcd\x88\x16\x03\x6f\x73\x28\xcb\xdc\x5d\x85\xc4\x10\xa9\x7a\x76\xd8\x59\x35\x37\x16\x67\x84\x19\xc4\xe4\x5b\xf9\x61\x39\x81\x1e\xe0\xb3\x79\x76\x1e\x58\x9c\x65\x1c\x01\xc6\x92\x17\xcf\x08\x00\x82\x97\xa2\xee\x79\xd1\x7d\x2b\x85\x81\xd2\xbd\x2c\x8f\x27\x5e\x79\x7e\x59\xb3\x39\x8d\x7a\x9e\x09\x2b\x4f\x9b\xbf\xbe\x35\x19\x99\xfc\xae\x4c\x0b\x1f\x5c\x37\x69\x58\xa4\xf8\x19\x77\x9a\x07\x1a\xe3\x71\x75\x7b\x3c\x5e\x44\x23\x62\x4e\x20\xb5\x42\xb1\x23\x40\x4f\xec\xa8\x08\x57\xbc\x28\xb8\xe0\x85\x83\x94\xc4\x22\x52\xf8\x1b\xad\x9a\xee\x53\x59\x5c\xd2\x39\x0d\x96\x73\x2c\x68\x84\x7b\xc8\xde\xe2\xad\xee\xf3\x7e\xe8\x85\x50\xdc\xd4\xa5\xf9\x34\xa6\xf9\xe8\x93\x1f\x2a\x80\x3b\xba\x8e\x41\x8c\xf6\xa5\x9e\x9e\x83\xb1\x4c\x33\xe4\xef\x5d\xbd\x41\xa1\xe0\x57\x59\x79\xe4\x56\x2c\x75\x24\x22\x1f\xfa\x42\xf2\x8d\x21\x03\x0a\x8b\x55\xa0\x30\x13\x63\x02\x37\xdb\xf2\xa0\x26\x24\xe5\x2c\x06\x92\x62\xdd\xa9\x45\xf9\x4e\xc2\x6e\x31\xc4\x06\x2d\xfb\x0a\xcd\xba\x96\x55\xf9\x31\x22\x0b\x65\x9d\x99\x83\x24\x73\xfb\xbc\x7e\x2c\x26\x60\xa0\x18\x74\x80\xcf\x86\x4f\x90\xcb\xf6\xbc\xe4\x13\x69\x45\x16\xeb\x90\x61\x46\xe6\xe5\xff\x78\x3e\x84\xe9\xb2\x58\xcb\x0c\x99\x2d\x9e\x0c\xc4\xe2\x32\x36\x90\x04\x60\xc2\xc7\xab\xb6\x6e\xca\xe3\xd3\xe3\xc2\xdc\x3f\xcf\x68\xf7\x5f\x6d\x81\x49\xc8\x4c\x98\x50\x58\xb1\xb7\x4b\x2e\x11\x96\x84\x71\x64\x44\x31\x71\x7d\xde\xf3\xbc\x98\x33\x43\x93\x28\x36\xc9\x0a\xe5\x3b\xde\xb9\x94\xdd\x5a\x6d\x4f\x7f\xb5\x21\x4f\x7a\x15\x49\x23\x83\x62\x35\x13\x4a\xd9\x56\xa8\xda\xf6\x57\xf5\x81\xee\x76\x25\x25\x71\xac\x4b\x00\xf7\x79\x7f\xd8\x25\x11\x64\x98\xde\xdc\x2b\x90\xa5\x82\x65\x7b\xc6\x1d\x69\x30\xd9\x13\x92\x06\x3c\x1a\xa0\x01\x30\xa5\x33\x86\x2a\x24\x24\x0b\x22\xe5\x98\x1e\x74\xf9\xc4\x0b\x38\xf8\x6b\x10\x63\x98\xab\x1f\x88\x8d\x7e\x00\x50\x57\x2a\xec\x59\x42\x29\xc1\x29\xf5\x3f\xcf\xff\xdc\xaf\xff\xb9\xfa\xbe\x78\xf8\xb6\xc6\x0a\x76\xf7\x44\xca\x19\x6e\xf1\x5c\xa9\xbf\xb7\x55\x5e\xab\x7c\x04\x2f\xfa\xd7\xbf\x31\x1f\xe2\xcc\xc3\x84\xaa\xd0\x19\x30\x9d\x87\x33\x9e\xc0\x09\x8b\x82\x40\x39\xd7\xac\xdb\x47\x9a\xf3\x12\x64\x79\xb4\x09\x9a\x35\xaf\x8a\x97\xa2\xb1\x15\xa4\xe1\xb5\x4f\xc4\x64\x44\x52\x4b\x69\x70\xa9\x3e\xc8\x92\x38\xc9\xb4\x39\x95\x64\x7e\xca\xa1\x68\xee\x37\xce\x24\x4c\x12\xca\x2d\xa3\x00\xa8\xa1\x92\x1d\x4b\xd2\x44\xa3\xf2\xe5\x29\x97\xe5\xa9\xde\xe7\xdd\x41\x94\x37\x57\x2c\x87\x24\x15\x91\x93\x0d\x30\x5b\x4f\x59\x1d\x0d\x54\x6a\xaf\x6c\x3a\xcc\xb5\xd4\x46\x12\x6b\x0b\xcd\x2a\x6f\xce\xc8\x76\x34\x7b\x40\x26\x19\xc9\x12\x47\xd5\x60\x30\x0b\x5f\x66\x58\x93\x8c\x66\x78\x9c\x78\xe8\x86\x21\x1a\x9b\xb7\x72\x93\x2c\x0d\x85\x35\x53\x5d\xd7\x78\xc0\x70\xbf\xd1\x3c\xaf\x78\xa1\x80\xd7\x67\x7f\x89\x72\x0c\xfb\x18\x2a\xe8\xa7\x97\xe5\xdd\x66\xb5\xdf\x2e\xee\xd6\x7d\xcd\x3a\x4b\x78\x9a\x46\x3d\x77\x98\x63\x91\x9b\xc5\x13\x27\x3c\xcb\x8c\x3c\x21\xd4\xcd\x2d\xcf\x0f\xcf\x80\x27\xe4\x1d\xea\x06\x3e\x83\x61\x53\x5e\x17\xa8\x0d\xef\xfe\xd3\x4f\x79\x49\x0c\x8d\x32\x57\x0a\xe5\x87\x0c\x5b\xf6\x0c\x9b\xda\x90\x6a\x82\x25\xb2\x33\xf0\xac\xab\x86\x15\x4c\x9d\xed\xa9\xae\x25\xfd\x12\x99\x18\x98\xf1\xf1\xbd\xd9\xd4\xf5\x15\x86\x32\x96\x28\xa2\x9d\x57\xf1\x0c\xb7\x6d\x31\x2b\x9f\xc8\x12\xc5\x34\x38\x2a\x9a\xf2\x0a\xe5\xe3\xf4\xc9\xc0\x51\x12\x5d\x40\x53\xdf\xf5\x69\xa8\x44\x0b\xc3\x36\xdb\x78\x4e\xa7\xd1\xab\xd2\x20\x4e\x95\xcd\x9c\x9a\xd4\xcf\xb6\xa9\x46\x27\x4b\x1a\x64\xc4\x11\x4b\xdd\xdd\xfd\xdc\x83\xca\x9b\x7d\x94\x8e\xdb\x84\x2c\xb6\x52\xf6\x48\x82\x3d\xaf\xdb\xce\x52\x42\x09\x78\x01\x0f\x23\x30\x32\xfa\x15\x29\x49\x92\x10\xf1\x27\x7b\x38\x62\x75\x81\xd9\x2b\x98\xbb\x2c\x04\xc6\xc0\x9f\xff\x7c\x70\x99\xef\x94\xd1\x10\x6f\xf1\xb1\x4c\x5b\x82\x7f\x9e\xbc\x9b\xa5\x81\xd1\x36\x94\x2e\x2c\x15\xfa\x47\x08\x91\x91\x81\x29\xba\xa8\xcd\x26\xf3\x79\xf1\x0c\x05\x68\x0b\x74\xe3\xe8\xa2\x9c\x69\x9c\x52\xee\x12\x6e\xbc\xad\xc1\xd1\x56\x40\xdf\x20\x61\xc6\xd2\xd8\x1b\x6e\x7f\x77\x21\x01\xa2\x3c\x16\xe9\xb9\x97\x9d\x67\x69\xa2\x8d\x10\x7c\x5d\xea\x66\xc5\x4f\x68\x33\xde\x94\x1f\xc5\x2e\x3f\xfa\x33\x21\x4d\xad\x62\xcb\xe9\x8d\xd7\x40\xd7\x85\x32\x1a\xad\xee\x6a\x66\xb8\xf1\xa1\x50\xbd\x9e\x26\x4b\x53\xc1\x43\x6f\x8f\x7e\x40\x8d\x5b\x6d\x77\xe2\x95\x6d\xf3\x8f\xb6\xac\x3c\x74\x30\x4d\x25\xc7\x85\x83\xf5\x3e\x97\x5c\x6a\x2c\xcd\x88\x51\xd5\x7e\x2c\xec\xd9\xbf\x6c\xcf\x06\x48\x0c\x45\xcd\x9b\x6b\xe7\x46\x9a\xe9\x10\x69\x67\xbc\x7c\x7a\xf3\x06\x55\xbd\x2b\x6f\x78\x39\x99\x0e\x9c\x90\xc8\xd6\x14\x19\xce\x2c\x7b\xb0\xcd\xae\x85\x74\xb0\x7c\x53\x4e\xa8\xb4\x80\xea\x6e\xcc\xca\x76\x3a\xd3\x78\x2c\xc1\x1d\x04\x4f\x86\x27\x77\x3e\x5e\x9b\x72\xce\x6d\x58\xfd\xa0\x6f\xc0\x30\x18\x0c\x48\x3c\xdc\x68\x08\x46\xdd\xdc\xc6\xf9\xd3\x6b\x5b\x4f\xde\x2c\x65\x80\x3b\x8b\x19\xd7\x6e\xc8\xdc\x5e\x95\x4a\x88\xa2\xc0\x19\xd5\xd6\x5c\x1e\x2f\x34\x15\x88\x1e\xf2\x77\x3c\x41\x93\x23\x0a\x1c\xa3\x29\x8f\xda\x15\x3e\xf6\x08\xc4\x54\x65\x31\x26\x18\x3f\x9c\x7f\xb1\x7e\x5e\x45\x11\x99\x4c\x6c\x1d\x19\xee\xab\x37\x5e\xbf\xed\xce\x27\xc7\xe9\xe7\xae\xb2\x08\x81\x84\xf5\x1b\x47\x6a\x5b\xcf\xe5\xc9\xb2\x20\xe1\x98\xed\xfd\xc1\x8b\x7c\x80\x8e\xca\x02\x99\xa1\xe5\xed\xb4\xbf\x86\x5e\x4f\x16\x26\x31\x46\x64\x7e\xc0\xef\xd5\xe0\x9e\x50\x10\x84\x92\xe6\x0d\x1c\x57\x1c\x8b\x9b\xe7\x67\x50\x16\x4a\x23\x81\x6f\xec\xe9\xbf\xe7\xc5\xeb\x01\xea\xc7\x81\x8c\x08\xcb\x22\xc6\xac\x7b\x8e\xd6\xdf\x28\xd1\x91\x7e\x6d\xc7\x65\x91\x24\xe8\xd8\x72\xa5\x1c\x1f\x44\xfb\xfa\xd6\x2c\xea\x09\x87\xf6\xf8\x2e\x42\x4c\xd8\xdb\xcb\x55\x1f\x79\x7e\x98\xf2\x8f\x0e\x3f\x66\x46\xe2\x50\x64\xce\x1a\xab\xdb\x6a\xb4\xcd\x4f\x1e\xae\xb4\xf0\x58\xce\xce\xf4\xc3\x42\xe1\x2b\x2b\x2c\xa3\x54\x13\x6f\x88\x5e\x6b\x93\x48\x15\xbb\xbd\xf8\x54\x56\xc8\x90\xd4\xf4\x3b\x45\x46\x79\x88\xb6\x22\xaf\x80\xab\xff\x70\xe9\x56\x88\xb5\xad\x5c\xa0\x36\x73\xe4\xd0\xb6\x2a\x1d\x73\x3b\x9d\xa3\x35\xb6\xdf\x32\x96\x0a\xc5\xfd\x11\x71\x9b\x1f\x86\x12\x9f\x2c\x63\x1a\xc0\x30\x7d\x1c\xf3\xc2\x25\x23\x4d\xbc\xd9\xb6\x88\x03\x19\xd9\xac\xe1\x0f\x38\x1b\x56\xf9\xf1\x34\xce\xe2\x24\x74\x1a\x43\x7b\x55\xe4\xe3\x85\x97\xa5\x81\x70\xac\xa6\x37\xcf\xdb\x6e\xe6\xdd\xe4\xbf\x3b\x5b\x4d\x4d\x1b\x86\x69\x16\x0d\xf3\x93\x17\x31\x16\xdb\x30\x4b\x4d\x24\x06\x73\xaa\x73\x73\x6a\xae\x7a\x7e\x34\x05\x32\x91\xb8\x9a\xaa\xce\xa5\xfc\x56\x95\xed\x3c\x81\x06\xcb\x32\x65\x30\xc8\xf7\x8b\x7f\xee\x1f\x5e\xee\xf7\x4f\x0b\xd4\x6a\x5c\xec\x76\xeb\xfb\xa7\x9d\x4b\x14\x65\x3c\xa3\x51\x3a\x8c\x68\x57\xc0\xeb\xb6\x32\x70\xb0\x49\xff\xb9\xe4\x58\xc3\x72\xa8\xa4\x1b\x72\xbf\x1a\x45\x04\xb8\x17\x3d\xac\x7f\x2e\xfc\xdf\x18\x8b\xed\xc0\xf4\xd8\xb3\x4c\x86\x21\xa5\x6e\xd7\x42\xfb\xf5\x07\x9c\xaf\x6d\xd1\x73\x60\x8b\x4c\x45\x09\x9e\x24\xbf\xe1\x2d\x97\x07\xb8\xe9\x0c\xbb\xe5\xb9\x33\x79\xff\x98\x34\xa4\x29\xed\x11\x8b\x7e\x97\xcb\x14\x63\x5c\xf5\x98\x2d\x5f\x2d\x3a\x82\x0e\x5c\x7b\x39\x8b\x09\x19\x53\x20\xcf\x04\x72\x32\x15\x73\x47\xe1\xb4\x28\x5e\xe1\x80\x65\x6d\xf5\x1f\xc3\x8c\x72\x06\x81\x48\x13\xc7\xb2\x2b\xcb\x42\x19\x8f\xd3\x9d\x9b\xe3\x07\x02\x4b\x22\x43\xd6\xbd\x98\x4e\x40\xe0\x91\xd1\x0d\x2d\xca\x0f\x7d\xe0\xef\xde\x17\x1a\xcd\x1d\x80\x10\xb7\xb8\x0a\x69\xc7\x47\x1e\x49\xa6\x09\x77\x50\xa7\x55\x59\x28\x3c\x25\xea\xd1\xf2\xd6\xb1\x11\x44\xc6\x42\x3e\xfe\xb9\x69\xe0\x38\xda\xf5\x33\x9d\x12\xc4\xc1\xed\x5f\xa1\x79\xd0\x57\xe2\x52\x3c\xe0\x8c\x59\xb2\x85\xcd\x91\xbf\xa2\x25\x5f\x0e\xaa\x23\xc7\xbb\x0e\x0f\x24\x4f\xb5\x35\xab\xe7\x32\x05\xf3\x39\x15\x1e\xa8\xd0\x68\xd2\x7a\x12\xc0\x7f\xb4\xbc\x6a\xa0\x72\x36\x1c\x0f\x03\x8a\xf9\xff\x43\xb1\xd7\xf9\x27\x28\x72\xa5\x03\xa1\x4a\x30\x67\x72\x84\x86\x2b\xde\xf0\xef\x9e\x83\x8b\xf1\x48\x11\xc3\x06\x6f\xa0\xb8\x53\x40\x91\x6d\x45\xe2\x4c\xd0\x11\x46\x7a\x50\x59\x38\xfa\x42\x9c\xc6\x66\x53\xfb\x7d\x59\x69\xc9\x29\x08\xcc\xaa\xd9\xd0\x94\x21\xe0\xe3\xf9\x64\x2a\x70\xc6\x42\x16\x8d\xbc\x72\x53\x2d\x7d\x81\xf2\xe5\x71\xa0\xb0\x5a\xf1\x34\x00\xfe\x5d\x2b\x6f\xe2\x71\x42\x30\xea\xb1\xcf\x6b\x0f\x02\xac\x16\x4d\xc3\xe5\x3b\xd6\x5b\x5d\x19\xbd\x24\x8b\xb9\x35\xab\xf6\xf6\xfd\xfb\x45\x95\x17\x17\xe4\x07\xb6\x7d\x4a\x64\x24\x1c\x65\x2c\x9a\x45\x6e\xc9\xf2\x34\x35\x80\xa3\x01\x13\xc0\x83\x37\x3e\x79\xca\x23\x2e\x06\x25\x6c\x98\x2d\x1a\xed\xac\xae\xa1\x32\xea\x2b\xcf\xa5\x7c\x87\xe6\xb6\x85\xa1\x02\x2f\xe3\x59\x4a\x88\x29\x73\x6b\xeb\x06\xc0\xf3\xa0\xf6\xd7\x53\x69\x22\x5f\x4d\x67\x08\x1a\x3b\xd6\x66\x2c\xba\x6e\x4d\xbe\x06\x0f\x0c\xe4\xc9\x08\xfa\xda\x38\xec\xc5\xce\x3f\x1e\x03\xae\x88\xdb\x38\x3c\xab\xbe\xbd\x24\x68\x1c\x44\x3d\xdc\xe9\x6b\x47\x6f\x60\xde\x72\x19\x46\x16\x8a\x57\xbf\xed\x4a\x2f\x83\xc2\xb8\x4c\x8d\xef\x7d\x00\xdd\x60\xfd\xc3\x10\x8e\xcd\x25\x27\x18\x87\x7c\xf8\xf3\x9f\x37\xd0\x2d\xa4\xca\x94\xc1\x6e\x30\x60\xa1\x6d\xbd\xa7\x73\xcd\x66\x92\x73\x5c\x02\xa5\x5e\x44\xe8\x16\x40\x6d\xcb\xb6\xea\x5f\xa0\x32\xca\xb3\x9e\x48\xc7\x54\x60\xac\x2e\x28\x72\x18\x87\x18\x30\x7c\xf0\x63\x08\x41\xe0\x90\x30\x47\x6e\xdb\x7d\x87\x5b\x53\x35\xc3\x0f\x3d\xcb\x35\xe3\x9a\xa4\x81\xa5\x98\xfc\x7b\x31\x32\xc4\xc7\x6f\xd0\x59\x80\xb9\x56\x57\x12\xe1\xfe\x2c\x03\xb4\x87\x0d\xf2\xff\xb2\x66\x70\xae\x14\x86\x6b\x09\x58\x0c\x00\x9d\x95\x06\x1b\x47\x87\x3e\x2c\xe8\x34\x2d\x45\x40\x19\x08\x5f\x51\x86\x49\x90\xb1\xd7\x24\x02\x4b\x69\x66\x48\x81\x2c\x0f\xa1\xbd\x16\xb2\x00\x29\x9a\x6d\x46\x03\x9a\xe6\x80\x01\x44\x3b\xff\xfb\x09\x20\x42\x26\x8d\xf6\xdf\x66\xf9\xb8\xf5\xb7\xdb\x78\x9b\xad\x8b\xfa\xc3\x22\x1c\xed\xae\xea\x4e\x29\x11\xaa\x0c\x3d\xe1\x02\x3e\xb0\x83\xfe\x76\x48\x10\x16\xf0\x52\xd4\x30\x4d\xb9\xda\x26\x11\x21\xc4\xad\xff\x1a\x3b\xb5\x6f\xeb\xb9\xe2\x87\x11\x69\x07\x13\x11\x8d\x10\x52\x75\xc2\x85\xf5\x54\xc1\x66\xf7\xb8\xef\x69\x1c\x5f\xb6\x2e\x23\x26\x08\x33\x78\x54\x91\x7f\x0e\x17\xb2\x20\x9c\xe2\x69\x69\x61\x19\x1e\xdc\x64\xa2\xbb\x93\x5d\x53\xd0\x30\x41\x8a\x52\xd1\x9e\x9f\x0e\x97\x2b\xd4\xb5\x22\x12\xd9\x1e\x56\xe7\xd3\x1b\x54\xff\x74\xaf\x62\xc4\xf8\x34\x7b\xc3\x0f\xf3\x56\x56\xdd\x1a\x79\x2a\x3f\xa6\x85\xb6\x22\xa1\xa9\x34\x61\x0f\x05\x47\xdc\xff\x87\xcb\x4d\x24\x2c\xc5\x9c\x3a\x8a\x15\xde\xe7\x45\xfe\xcd\xd3\x95\x33\x91\x08\x40\x2e\xb7\x5d\xd5\xca\x77\x94\x54\xf1\x9e\x90\x48\x24\x0b\xcd\x56\x6e\x51\x08\x0d\x8c\x54\xf4\x5c\x33\xcd\x84\xee\x79\x18\xf6\xd0\xbc\x0d\x84\x55\x99\x48\x19\x60\x1d\xfa\xcb\x72\xbb\xf1\x7f\x53\x09\xa2\x64\xe4\x59\x1e\xa0\xc6\x61\x44\xc4\x80\xbb\xac\x93\xc4\x94\xcb\x23\xaa\xe2\x8a\x08\x3b\x13\x19\x09\x10\xc2\x57\xa3\xef\xd5\x94\xc5\xb0\xa4\xd6\xb5\x91\x0a\xf9\xe8\xb7\xf7\x8b\xe7\xdd\x6a\x35\xfc\x81\x5c\x9a\x5d\xfb\x54\xb5\x45\x5f\xb1\x7e\xe5\x33\x71\x2d\x50\xa3\x02\xca\x7a\x52\x77\x2c\x84\x55\x60\xdd\xdc\xdf\xac\xff\x89\x10\x5a\x94\x63\x42\x1d\x69\x83\xde\x9f\x49\x3d\x0a\x29\x29\x42\xd7\x4e\xbc\xea\x16\x57\xc1\x4f\xdb\xb7\xb2\x19\x46\x4f\x84\x4a\x29\x4e\xc3\x1d\x7f\x87\x47\xad\x31\x9b\xf3\x2b\x57\xfe\xeb\xa9\x2c\x48\x33\xfb\xe5\xe1\xb8\x2a\xdb\xd3\x94\x8d\x9a\x09\x25\x0c\x77\xe3\xb1\x3d\x34\x97\xe5\xe1\x02\x12\x43\xa5\xbf\x47\x00\xf1\x0d\xfc\x5e\x4d\x83\x14\x02\x74\x8c\xc1\xbb\x3d\x60\x4a\x67\x40\xca\xdc\x5d\x4b\xa8\x3d\x56\xba\xb1\xbf\xd4\x53\xff\xaf\x32\x29\x42\x47\x86\xce\xd4\xa8\x0d\x0e\x5d\x32\xa1\x89\xc7\x60\xdd\xf1\xba\x79\x28\x0b\x57\xa3\xe4\x67\x98\xe6\x99\xb2\x87\x38\xa2\x7f\x2d\x92\xb6\x18\x95\x64\xba\xb6\xb6\x64\xcc\xb0\x97\x54\x1e\xec\x2e\x34\x68\x5c\x86\xc8\x51\xdc\xed\xab\xd5\x15\xc4\xb1\x0c\x02\x8e\x00\xac\x02\x40\x79\x92\x36\x77\x2d\x0c\xd1\x66\xc6\x7c\xfc\x48\xb5\x62\x12\x5d\x95\x01\xe1\x18\x7f\xda\x1f\x4b\xff\x41\x65\x90\x99\x02\xeb\x1d\x86\x94\x65\xf9\xfb\x0a\xd0\xe9\x8a\x17\x21\x03\x91\x32\xcf\x81\x7b\xcf\xeb\xc6\x3b\xae\x32\x50\xc2\x08\x3a\xbe\xf9\x75\x26\xc3\x34\x41\xb2\x85\xbb\xf2\xd5\xe9\x77\x7e\x1d\xe0\x95\x91\x8e\x5d\xe4\x67\x57\x9e\x4c\xb6\x7c\x2b\xcb\x8b\x0a\x47\x49\xa9\xf1\xdb\x57\x07\xe0\xc5\x92\x17\xef\x50\x99\x6d\x7e\x60\x36\x49\x9a\x50\xcb\x1b\xda\xf0\x83\xd1\x2d\x72\x5d\x63\x21\xc1\x92\x65\x59\x9d\xeb\xc6\x1a\xa6\xfe\x5a\x9c\x20\x09\xe6\xf3\xe3\x72\xb3\xde\xf9\xbf\x66\x04\x91\xfd\xe5\x09\x8a\x6e\x8b\x7b\x86\xba\x33\xb3\x0a\xf5\x00\x1f\xb8\xe5\x5d\x4b\x9f\xcd\x68\xe2\x30\x19\xa7\x81\x09\x0f\x42\x8d\x93\xca\xbd\x25\x16\x61\x64\x70\x28\x3d\x49\x79\x9f\x25\x1d\x7f\xe2\x24\x64\x30\xc8\xe3\x2f\xf9\x80\x88\xf1\x12\x98\x24\x93\x48\xe0\x36\x52\xf3\xf3\xa2\x38\x37\x03\xf6\x77\xd7\x20\x4e\x51\x3e\x0e\xb9\x3c\x26\xaf\x4a\x23\x0c\xfb\xfc\x59\x5a\x5a\x4b\x7b\x42\xe1\x98\x47\xff\x2d\x76\x6c\x7c\xce\xca\x34\x08\x11\x22\xdf\xfd\xb4\x5b\x2e\x61\x57\x76\xff\x7f\xd1\x74\x46\xea\x20\xba\xd7\xb5\xb3\x14\xac\x0f\xe5\x15\x0f\x4d\xa6\x49\x34\x62\x7a\xe8\xb6\xfb\xe7\x52\x94\x5f\x4b\x00\x77\xf7\x29\xab\x9a\x9f\xe3\x78\x1b\x51\xee\x2b\x05\xa1\x32\xe5\x81\xa5\x25\x6f\xd6\x9f\xa7\xdc\x60\x7d\xba\x03\xba\x7b\xdd\x6c\x96\x43\x66\x91\x81\x34\x6c\x9b\xb2\x82\xb1\x8e\x10\x93\x19\x11\xe8\xdc\x2e\xf3\xaa\xb7\xc2\xe7\xf7\x30\x99\x31\x89\x3e\xa8\x2b\x5c\x78\xf1\xaa\x6c\x4c\x66\x60\xac\x6f\x83\xe8\x3c\x71\xd3\x31\x73\x2c\xec\x2a\xa3\x21\x7e\x0b\x60\x55\x33\xf3\xe9\x11\x2f\x33\x1d\xa3\xc5\x6f\xf6\x47\x97\xfe\x92\x5c\x12\xa4\xd4\xfd\x47\x67\x29\x0f\xd2\x4d\x52\xb2\x08\x13\x88\xdd\x5e\x7d\x2c\xf2\x1a\x5f\xb7\x67\xfe\x32\x08\x24\x56\xab\x8f\xdd\xf3\x0c\x47\xd6\x0a\xa1\x18\x78\x34\xcc\xff\xbe\xce\x81\x90\x2e\x54\x67\xd2\x5b\x08\xa0\x6e\xf8\xf1\x64\x76\xec\x28\x98\xde\x92\xa6\xe8\x0c\x1e\xf3\xba\x3b\xa2\x51\xc2\x66\x57\xae\x0b\x35\xb6\x38\x25\x90\x2c\xb4\xc8\x6a\xd5\xca\xc6\x13\x17\x48\x9d\xca\x04\x46\x68\xb2\xef\xf9\xeb\xdb\xb0\x84\x5b\x05\x44\x1b\x25\x31\xdd\x40\x81\x8c\xfa\xc3\xb3\x59\x05\x32\x4e\x2d\x21\x92\xdd\x0f\xdb\x39\x12\xcf\x51\xcd\xef\x57\xff\xdf\x33\xed\x8f\xac\x59\x15\xd2\x0c\x3f\x3e\x66\x41\xf6\x91\xe5\xea\x1b\xf2\x34\xa8\x28\x02\x0c\x46\xa3\x66\xfa\xe3\x6e\x71\xe7\x45\x3f\x1f\xf7\xcf\xeb\xd5\x7a\xf3\x73\xbd\xf7\x5a\x49\x4c\x45\x2c\x49\x0c\xb0\xec\xa3\x0f\x24\x75\x06\xed\xff\x13\x46\x41\x45\x99\xa9\xe6\x7c\x7e\x79\x68\xfe\x8a\xeb\x40\x91\x8c\x63\x10\x2a\xaf\xd7\xbc\x19\x10\xa6\xda\xcb\x94\xc5\x18\xac\x3d\x96\xbf\xe1\x52\x54\x75\xfc\x5e\x1a\x2b\x9c\x81\xb2\x3c\x9e\xda\x06\xf0\x8c\x98\x3c\x8e\x85\x2c\x35\xbc\x9a\x17\x30\x16\xc5\xb2\x2c\xe9\x03\xe7\xdb\x56\xbc\xcc\x18\xf8\xb6\x6d\x1c\x72\xfc\x89\xc5\x64\x9f\xf7\x1a\x49\x7d\xaf\x62\xa6\x90\x5e\xc1\xee\xc8\xdb\xce\x5e\x2a\x2b\x2e\x0e\xf0\xf7\x52\xfc\x31\x69\xcb\x13\xb4\xcf\xbe\x55\xc0\x1b\x59\xe6\x05\x16\xd4\x8f\x26\x57\x2c\x13\xe4\x86\x78\x6a\x0b\xf9\xb6\x1a\x58\x6e\x2a\x49\x03\xac\x99\xf8\x3f\xff\x07\xa5\x90\x87\x06\xed\x3b\xd9\x57\xb5\x7d\xa5\x06\xc5\x54\x1a\xa6\xa6\xc6\x2e\x2f\x9a\xed\x72\xf3\x45\x24\x5d\xa5\x24\xc9\x7c\xfc\xb3\xce\x5f\xa7\x5f\xda\x35\xe3\x0a\x21\x1c\x68\xc9\x4f\xd2\xd0\x63\x96\xdb\xbf\xfa\xe7\xfa\x9c\xcb\x3a\xdf\xc5\x82\xaf\xcd\xaa\x35\x7c\x23\x17\x84\x7f\x4c\x65\x5c\x61\xd3\xcd\xe2\x61\x34\xb2\x99\x4c\x62\x9b\xee\xdd\x9f\x2a\xd8\xbf\x9f\xe5\x3e\x97\x65\x91\xff\xaf\x29\x93\xdd\xab\x81\x29\x3b\x3f\x20\x5c\x6a\x57\x8d\x8b\x5e\x44\x1f\x9f\x50\x22\x8a\x30\x0b\x70\xe0\xb5\x35\xb8\x47\x8b\x59\xf0\x14\xb7\x23\x55\xda\x2a\xa2\xfe\xcc\x9e\x7f\x95\x8c\x05\x63\xae\x5e\x50\xf6\xdc\xdd\xf3\xf3\x55\x42\x8a\xa4\x3e\xb6\xe2\xea\x69\x77\x59\xfb\x6c\x5b\x2a\x61\xf8\xd9\xb0\x8f\xdd\xee\xb9\x29\x64\x2b\xba\xdf\x3c\x1a\x2c\x25\x78\x10\x39\x0f\xef\x86\x37\xe0\xe2\x91\x0a\xa4\xc2\xfa\xc0\x5c\x96\x04\xed\x2b\x77\x41\x47\x09\xe6\x09\xd7\xbb\xef\xd2\x91\xf5\x33\x08\x52\xc3\x9a\xf9\x0a\xcd\xbe\x2c\xf7\xa5\x1e\xf7\x07\xc2\x28\xc5\x2c\xb7\x68\xab\x62\x71\x38\x38\x0b\x68\x5c\x3e\x65\xdb\x46\x59\x80\x59\x09\x4c\xd5\x6f\x0a\x5d\xa2\xb4\xf9\x70\x2e\x42\xc4\x13\xd5\xab\x91\xdc\xdb\x58\xe8\xf4\x39\x9a\x22\x17\x9c\x15\xad\x34\x9e\xb6\x3b\xe8\x80\x30\x83\xb1\xfd\x06\x48\x98\x23\x51\x51\xe5\x8b\x2d\x0e\x48\x2c\xf0\x44\xe9\x46\xf4\x9e\x17\x13\x38\x25\x10\x6e\x04\xa6\x51\xc8\xda\xbf\x44\x84\x86\xa4\x1a\xb0\xa2\xc3\x97\xb5\xff\x31\x4b\x04\xed\x6e\x02\x82\x06\x64\x1d\x85\x36\x04\x62\x2f\xd0\x30\x42\x1c\x89\x01\xce\x6e\xf9\xe1\x92\xc1\x7d\xba\xbc\xfa\x18\x06\xd0\x88\x10\x87\x94\xb0\x75\xc1\x86\x23\xb8\xe1\xef\xb0\xe2\x07\xcf\x73\xc8\x80\x32\x23\x43\xd1\x79\x7e\x39\x16\x00\x5c\x33\xff\xc6\x3d\x8f\x09\xf5\x9c\x62\x88\x48\x6c\x55\xfe\x95\x50\x02\x83\x44\x50\x6d\xcd\x9b\xf6\xf4\x84\x2a\xa6\xf3\x46\x04\xa4\x22\x45\xec\xc2\x1b\xaf\xd7\x45\xd9\xbe\xbe\x2d\xb7\xbb\xaf\x4b\x9a\x20\x63\x21\x66\xf6\xf8\x2b\x14\x86\xd3\xb9\xbe\xa2\x4b\xc5\x20\x4b\x28\x5c\x14\x52\x5c\x43\x89\x4f\xef\x4d\x39\x3a\x23\x66\x36\x6e\x0a\xd9\x4d\x29\xab\xa9\x3c\x03\xa8\x86\x2c\x33\x2a\x33\xa8\x2d\x8c\xae\xa6\x69\x65\x2f\xf3\x20\xc4\x98\x2e\xc2\x85\xa2\xc9\xbd\x3c\x10\x28\x05\x2a\xda\xf3\xf6\x7f\x5b\x47\x22\x9f\xce\xc7\x6e\x81\x5b\x85\xc3\x23\xff\xf4\xa6\x11\xf0\x38\xc2\xd8\x00\xa0\x32\xfe\x16\xe5\x02\xef\x7b\x57\x12\x78\x6a\x68\xba\x9f\x41\x1b\x50\xf8\x1f\xf3\x27\xcd\x64\x14\xb8\x88\x53\x3a\x2c\x3b\x74\xd9\xc9\x2b\x71\x11\xe0\xd2\x68\x2b\x7a\x8e\xef\xce\xcc\x5e\x14\x6a\x39\x5b\x56\xd9\xdf\x27\x80\x9b\xe0\x58\x59\x55\xe5\xa4\xe0\x13\x64\x60\x04\x83\x6a\x2b\x9d\xb0\xe5\x57\x58\xd3\x19\x48\x62\xaa\x8d\x5f\xdb\x5c\xd9\x20\xce\x11\x0a\x04\x3e\x70\xd9\x80\xc2\xe8\xef\xae\x7c\xf2\x65\x3b\x20\xb5\x8c\xc3\x21\x48\xd5\x42\x87\xc7\x9b\x93\x4a\xc2\xd8\x13\xcd\x0e\xe3\x7d\xee\x31\x2a\x95\x99\xe1\x27\x29\x2c\x83\xcf\xe4\x47\x28\x45\x91\xf5\xf4\xc4\xcf\xb7\xe5\xc4\xa2\x07\x60\x71\x9a\xba\x2a\xb0\xe3\xa9\x81\x7d\xc4\xc6\x1d\xd0\x54\x5a\xee\xd0\xbf\x24\xd3\xff\xff\xfa\x5f\xd7\x23\xce\xf1\x5c\xf4\x73\xc3\xf0\x84\x0d\xda\xba\x23\xb4\x6b\x8a\xc0\x16\xd1\x9e\xbf\xa2\x20\x65\xa0\x81\xbb\x53\x1a\x2b\x5c\x6c\x90\x79\xb4\x00\x74\xa0\x88\x45\x09\x14\xf0\x23\xf7\x1b\xb3\x26\x61\x60\x23\x9f\x06\xec\x60\x37\xda\xc8\x5d\xce\x24\xa2\xd1\x2a\x0c\x63\xcb\xb2\x50\xbb\xdc\x7b\xf2\x9a\x06\x86\x6e\x5f\xe5\x35\x1e\xd9\xa0\x6e\x80\x1f\x46\x09\x4c\x4d\x05\x41\x43\xc1\x72\x03\x97\xe5\xf4\xba\xcc\xd2\x3e\x41\x74\x63\x9f\xb4\x6d\xe0\x34\xfe\xdc\x9a\x49\xc0\x50\x23\x37\x85\x9d\xb8\x32\x2c\x10\xd8\xb6\x88\x83\x18\x43\x3f\x60\xe9\x56\x26\x24\xf3\xfd\x11\xa0\x93\x20\x4e\xa3\x61\x09\xfe\xea\x92\x39\x48\x27\xa1\xc9\x9b\x9e\xda\x61\x0a\x71\xf0\x10\x50\x58\x68\xf3\x00\xf2\x7d\x10\x13\xd5\x59\x68\xc8\x2b\x24\x3f\x1c\xd6\x9f\x39\x86\x65\x5f\x8a\xf7\xa2\xfc\x28\xe6\x3d\x7b\x9d\xb1\x98\x1b\xd1\x72\x4c\xf1\x4f\x78\xc9\x74\x96\x1a\xbc\xea\x11\x5e\x5d\xf6\x44\xf3\x30\xc3\x5a\xf5\xfb\x7b\x97\x35\xd0\x02\x92\x88\x58\xf5\xa8\x43\xb3\x3f\xf1\x73\x53\xba\x6b\x92\x12\xb4\x59\x1f\xe0\x03\x2a\xff\x10\x99\x99\xa4\x99\x01\x78\xee\xbe\x6f\x9e\x6f\xf6\x37\x9b\xed\x0a\x7d\xaa\xfb\x97\xbb\xdd\xe6\xe9\x6e\xb3\x76\x30\x60\x0d\xdc\x40\x29\x9f\x9e\xd7\x06\x06\xba\xdd\x2d\x9e\x77\x4e\x34\x8c\x69\x80\x04\xb3\x1e\x96\xed\x07\x0f\x9a\xc9\xb6\xad\x75\x14\x60\x74\xef\xbe\x2c\x7b\x91\x5e\x7f\x2d\x32\xc5\x7e\x07\x7e\x7e\xb0\x5d\x8f\x83\xc0\x66\xc7\x0d\x73\xaf\xce\xc7\x83\x17\x07\x61\x18\xbb\x62\x34\x94\x06\x81\x2b\x8c\xa0\x71\x10\x26\x1c\xa1\xaa\x27\x8c\xb9\x3d\x97\x03\x22\xa4\xc9\x23\x45\x82\x01\xef\x5c\x96\x28\xff\x1d\x0e\x76\xad\x38\x88\xc2\x10\x45\xaa\xef\xf3\x02\x6e\xf3\x62\x10\x47\x8d\x83\x28\x95\x68\xb2\x60\x2d\x93\xd9\xee\x5c\x15\x78\x1c\x44\x19\x24\xc2\x42\xd5\x96\x4f\xeb\xed\xa3\x11\x93\x2d\x31\x66\x31\x44\xc1\x5c\x44\xb6\xe2\x80\x70\x0a\x64\x20\x68\xf0\xfd\xe9\xea\x8e\x36\xfa\xcd\x84\x03\xda\xbf\xff\x29\xe5\x3b\x9c\x6f\xb7\x7f\x8c\x87\x84\x08\x95\x18\x13\x73\xf0\xcd\xae\x1b\x51\xd3\xe2\x92\x38\x20\xd2\x70\x80\x3e\xc0\xc7\x53\x0e\xea\x29\x3f\x41\xb5\x1a\x10\xe5\x5c\x44\x05\xfa\x5b\x69\x48\x8c\x68\x88\xdb\x0b\x7f\x14\xe5\xc7\x01\xd4\x2b\x2c\xdb\xb3\x11\x00\x98\xf4\x96\xc6\x3a\x71\xa4\x7f\x8b\x42\x5d\xe3\x12\x1f\x94\x8e\xc4\x01\xcd\x32\x64\xc6\xec\x0e\x1f\xa7\x1c\xff\xdc\x1b\xf8\x71\x40\x85\x11\xc7\xeb\xec\xa9\xcf\x06\x8a\x7a\x0a\x77\x8d\x03\x0a\x19\x56\x75\x28\x38\xdc\xe6\x87\x66\x12\x5b\x8a\x03\xa6\x13\x64\x9d\x7a\x83\xc3\xa1\x1c\x14\x8c\x74\x1b\x92\xe1\xe8\xa9\x91\xde\xd5\x16\x77\xcf\x4f\xba\x24\x49\x71\xbb\x31\x8d\x26\xb0\xda\x59\x83\x2b\x0e\xd2\x40\xe0\xce\xf0\x23\xbf\x79\x73\xb1\xa0\x38\x48\xd3\x00\x23\xcc\x8b\x3e\x78\x1d\x07\x19\x17\x51\x3c\xc0\x77\xb8\x02\xf2\xaf\x60\x1e\x71\xc0\xb9\x51\xe2\x2a\xe0\xe3\xb6\xac\x5e\x3b\x3b\x7b\x32\x36\xc2\x6a\x4b\x18\x38\xd8\xd0\x3f\x9d\x3c\x4a\x24\x09\x9a\x45\x88\x7c\x5b\x3f\x6e\x3d\x16\x6b\x06\x64\xe4\x6e\x51\x72\x08\xaa\xaa\x67\xb7\xcf\x38\x90\xa1\x71\x96\x91\x01\xc8\x7a\x8f\x63\xad\xe7\x71\x4f\x24\xe1\x88\x4f\xec\x36\xe8\xdb\x4b\xe7\x77\x76\x1a\x49\x6e\xc8\x82\xcc\x04\xb2\x61\xc7\xfc\x32\x24\xee\x9a\x4b\x81\x69\xf1\xce\xa5\xa8\x96\xed\x19\x21\x13\xee\x53\x48\x88\x90\x5a\x42\xe7\x85\x7a\x80\xcf\xe6\x3e\x2f\xda\xc1\xb0\x8d\x5e\x0b\x0a\x13\x88\x77\xd0\xd4\xdf\x4a\xa3\x76\xf9\x65\xd4\xe3\xbf\xb2\x43\xe2\x40\xb3\x18\x01\x04\x98\x36\x58\xc8\xb2\x72\x81\xcf\x38\xd0\x31\x8d\x0d\xe9\x73\xb7\xa3\xe6\x2e\x20\x13\x87\x81\x30\xb0\xbb\xce\x33\xb8\xc6\xe0\x1f\x87\x21\x89\x02\x36\xe0\x21\x5a\x9e\x4d\xb6\x6b\x5c\xc7\x37\xbd\x89\x72\x3c\x00\xad\xe3\xf0\xf4\x78\x09\xdc\x8a\xc3\x30\x31\x9e\xf8\xa7\xd1\x98\xb8\x05\x23\x24\xee\xba\x17\x2a\x30\xa6\x8a\x29\xf4\x33\x87\xff\xe8\x24\x8d\xc3\x28\xe3\x8c\x9b\xb2\x50\x5b\x7e\xe5\xaf\x48\x69\x35\x91\xb1\x9c\x0e\x91\x6b\x16\x4d\x7d\xfd\x33\x87\x24\x48\x33\xed\xe4\x00\x9b\x7a\xfd\x1b\x8a\x45\xa1\x1e\x6f\x6e\x26\x5d\x27\x11\x20\x3f\x6d\x93\x1f\x61\x09\xcd\x07\x40\xe1\xd0\x3f\xae\x45\x92\x19\xa1\xbc\x43\x8e\x31\x19\xd8\x1e\x79\xe5\x33\x01\xcb\x73\x03\x2b\xef\x99\xc4\x21\x15\x2c\xea\xeb\xd0\x7a\x93\xfd\x89\xcb\x77\xfe\x0a\x9b\xfe\xb9\x54\x71\xdc\xba\x74\x05\x30\xb2\xed\xe2\x90\x59\xb3\x7f\xdd\xbc\x2d\xa1\xe9\xb7\x8a\x90\x65\x9c\xd8\xb2\xf2\x2f\xe5\x1a\xe2\x30\xce\x00\xd3\x29\x28\x5a\xd3\x56\x05\x37\xe4\x59\x05\xea\x01\x54\xbe\x13\xb1\xa6\xa1\x9f\x6d\x2e\xb8\xef\x2e\x26\x29\x47\xd7\xac\xaf\x71\xec\x6d\x82\x38\x4c\x34\xc4\xe0\x72\xf8\x9e\x9e\xf4\x2b\x37\x34\x0e\xd3\x40\x21\x61\x4e\x9d\x1f\x7e\x43\xb5\x2c\x3f\x07\xa9\xaf\x38\x4c\x23\x43\x67\x2d\xdd\xfe\x73\xaa\x72\x39\x23\x6d\x35\x7d\x28\x0f\xd1\xa5\xff\x8d\xcc\x6a\xfe\x61\x2a\xc4\x31\xb4\xe0\x14\x53\xde\x5f\x0f\x8b\x1d\xe2\x30\x63\xca\xf0\x0c\x3e\xac\xf7\x37\xeb\xd5\xe6\x7e\x71\xb7\xff\xc7\xcb\xe2\x61\xf7\x72\xbf\x5f\x2c\x57\x7b\x5b\x5e\xf3\xbc\x59\xad\xff\xe8\x6f\x71\x45\x99\x28\x68\x3e\xaf\xbb\x15\x87\x59\x26\x62\xe5\x82\xfb\x75\x53\x1e\xa1\xb2\x04\x56\x93\x89\x9f\x09\x93\xae\xf8\x06\x8d\xc1\x3f\xd8\xbf\x8b\xc0\x30\xc1\x4b\xe3\x7e\xe5\xe2\x00\xb8\x5c\x77\x86\x56\x63\x32\x8d\x45\x6a\x34\xce\x0c\x7f\xcf\x37\x43\x5f\x89\x1a\x34\xdd\x61\xdd\xf8\x51\x91\x44\x52\xab\x58\xd9\xcd\x48\xd4\x35\xde\x7d\xef\x61\x2f\x71\x08\x34\xb2\x5c\xf7\x03\xb8\xfe\xe8\x5d\xc0\x04\x42\xee\x24\xaf\xd4\x16\x9a\x7a\x53\xac\xf2\x0a\xed\x84\xa9\x22\x7a\x1c\x02\x4f\xf0\x00\xc0\x23\xa5\x3b\x3d\x3d\x4d\xe3\x7c\x20\x6b\x00\x3c\x8b\x43\xd0\x0a\x5f\x74\x5f\xbf\xae\x8b\x57\x17\xe3\x71\x57\x75\x68\x12\x78\xda\x52\xfa\x76\x9b\x41\x77\xcc\x44\x7f\xf8\x06\x84\x87\x9e\xaf\x54\x55\xfc\xe3\x1b\xaf\xff\x7f\xac\xbd\x59\x73\xe3\x38\x96\x3d\xfe\x75\xea\xa1\x1f\x48\x82\x04\xc0\x47\x59\x96\x9d\x9a\xf4\x36\x92\x32\xb3\xaa\x3b\x3a\x14\x58\x2e\x64\xb6\x29\x52\x4d\x52\x76\xba\x3e\xfd\x3f\x78\x01\x70\x13\xed\xcc\xf9\xc7\x6f\x22\x26\x2a\xdb\x04\x29\x2e\xc0\xc5\x5d\xce\x3d\x67\x72\x7f\x86\x08\xd4\x01\xd0\xd5\x69\x90\x75\xa4\xa1\x91\x04\xf3\xe3\xf7\x65\x67\x88\xa2\x80\x45\xd8\xc1\x5d\x98\x72\xdf\xcc\x48\xc5\x4f\x1d\x82\xb9\x36\x32\x1a\x05\x32\x31\x8e\xdb\x56\xbc\xdb\xc0\xad\xfb\x01\x50\x08\xc1\xfc\xfa\xd7\x72\x07\xe2\xe8\xff\x1c\x46\x11\x02\x9e\x16\xed\x0c\x1e\xde\x65\x14\x9a\x94\x5a\x96\xe6\xf6\x1b\x5f\xaf\xaf\xbf\x94\xb9\x9e\x24\x5a\x69\x14\x05\xc6\x75\x1d\xda\x64\x47\xd7\x3f\x6a\xdb\x1a\xaa\x01\x5f\x37\x8d\xa2\x90\x63\x17\xea\xa9\x2a\xff\x03\xaa\xf1\xf3\xa7\xbb\xc7\x28\xb6\x91\x44\x56\xd7\x67\x70\xc0\xe7\x4b\x24\xf2\xe4\x06\x84\x91\x41\x07\xc2\x87\xca\x8a\x5b\xdf\x94\xd5\xc3\xf9\xf8\x49\x1a\x85\x46\x24\x31\xdc\xf6\x6e\xe7\x36\xc9\x7e\x2f\x5e\x3e\xa8\x94\xd0\x88\x50\x86\x19\xc1\xec\x64\xea\x1e\x72\xda\xfe\xdd\xf2\x83\xfb\x74\x0b\xf2\x39\x8d\x98\x22\x26\xe8\x83\xf1\x3d\xc4\x01\xc1\x69\xb6\x85\x66\x71\xfe\x79\x49\x78\x4b\xa3\x84\x18\x74\xe4\xff\x74\xff\x17\xf0\xf1\x24\x8b\x12\x69\xad\xde\xb0\x3c\x7c\xb5\xf9\xf3\x49\xcc\x43\xb8\x07\x27\x42\x2a\xc3\x11\x8b\xd7\xac\x83\x1a\x51\x12\x22\xe2\xee\x2e\x53\xad\x97\x5c\x1c\x46\xb3\x84\xd2\xc8\x78\x3a\x69\xa4\x64\x16\xa7\xac\x11\x79\xf6\xf7\xcc\x82\x8d\x28\xa5\xa9\x2f\x6f\x94\xd5\x45\xf6\xd6\x8f\x52\x49\x64\x27\xf1\xad\x98\x08\x41\xd0\x88\xa5\x02\xef\xfa\xb5\x6c\x00\xd5\x63\xfd\x8d\x30\x1d\x18\x9f\x16\x12\xc7\x93\x18\xd6\x71\xc6\x77\xc1\xb5\x46\xe7\x7c\xb7\x58\xdf\xf9\xb3\xd3\x80\x62\xce\x0f\x7e\x3a\x5a\xc9\x4e\x17\xd7\x72\x98\x5e\x6f\xf7\xa7\xaa\x2c\x0d\xa2\x56\xde\x87\x84\x48\x1e\x49\x32\x4c\x96\xd3\x28\x0d\x23\x0c\xca\x5b\xab\xb4\x1b\x90\xe7\x5e\x12\x91\x4c\x6e\x2e\x55\x1a\xa1\x0c\xce\x32\x3b\x16\x50\x7f\x10\x18\x22\x92\x74\x59\x94\xd5\x5d\xd7\x5c\x4e\x23\x21\xa8\xa7\x6f\x7b\x28\x35\xac\xf5\x1f\x63\xbb\xa0\x12\x4b\xb1\xdb\x46\x01\xaa\x44\x84\xf0\x0f\x80\x97\x8b\xb2\x12\x8d\x94\x11\xa1\xbb\xd2\xfd\xfb\x43\xe9\x8e\xbb\xec\x14\x8d\x34\x8b\x03\xeb\x57\x94\x7f\x43\xe1\x29\x2d\x69\xa4\x95\xf6\xbc\xcc\x5b\x28\x9a\x81\x26\x58\xdd\x0d\x01\x60\xad\xc1\xfd\x72\x3e\x8a\x02\xeb\x32\xa3\x89\x04\x42\x39\xd8\x0a\xcc\x90\xe8\x75\xef\x7a\x74\xb3\x46\xc0\x88\x61\xfe\x82\x34\x96\x92\x20\x8c\xbc\x9d\x6e\xd7\xed\x53\x86\xea\x94\x73\xe9\x7b\x4a\x02\x63\x99\xd5\x94\x28\x56\x45\x03\x55\xdf\x28\x85\xc7\x90\x25\xe7\x9f\xbf\x27\xc2\x44\x49\x18\x4b\x44\xd8\xa1\x67\x59\xbc\x4f\x05\xb7\x28\x09\x99\x41\xbf\x16\x2f\xb8\x6f\x9d\x1f\xdd\x1d\x92\x96\xbf\x14\x15\x11\xbe\x23\xaf\x5c\x77\x08\x18\xc2\x55\x50\xbc\x6c\x53\x4e\x5a\x5a\x28\x89\x42\xdb\x48\xec\x57\xf5\xd3\x94\x0b\x80\x92\x08\x28\xf6\x33\xee\xdb\x28\x65\xa3\x07\xba\xee\x6e\x00\x09\x78\x6c\x5c\xc2\xe2\xb6\x02\x18\x16\xb4\xc7\x0f\x49\x12\x17\x5d\xb6\x96\x7e\x5d\xbc\x8a\x7a\x66\xcf\xf2\xc9\x0c\x42\x40\x3a\xa2\x45\x2f\x7d\x8f\x2e\xbb\x7f\xb4\x38\x4e\x8c\xb3\x0e\x37\x00\xf8\xf2\xc7\xf7\x15\xeb\x80\x78\x3d\x85\x4b\x2d\x35\x4a\x62\xa7\xc8\x88\x3d\x48\xdb\xae\x9b\xe5\x23\xe1\x7a\x4a\x92\x38\xc1\x3e\xdd\x5e\x20\x08\xbb\x63\x1b\xf8\xd9\xec\x0d\x40\xfd\xc7\xe8\x61\x93\x58\x62\xce\x14\x89\x8d\xce\x43\x7e\x35\x4a\x12\x26\x6d\x8f\xe8\xf1\x94\xef\x4d\x59\x1d\x7e\xe9\x59\x92\x44\xa4\x68\x39\xef\xb3\x22\x3b\x9e\x8f\x3e\x95\xee\x8f\x4a\x83\xd5\xaa\x17\x78\xbf\x6d\xa6\x82\x1e\x7e\x8c\xa6\xd8\x40\xea\xa9\xea\xc7\x45\xee\x4f\x32\x31\x7d\x3a\x93\x12\x1a\x46\xd4\x27\x57\x1e\x0b\x68\xcd\x82\xbf\x07\x4a\x15\xd8\x3c\xe1\x6e\x71\xb7\x5f\x2f\x1f\xfb\x06\x70\x4a\x28\x0f\x31\xc9\xae\xb3\xda\x63\x02\x10\x4b\x7a\xc1\xac\x41\x09\x4b\x9c\x02\xbd\x33\x84\x9e\x9a\x6d\xd6\x02\x12\x1e\xd2\xd8\x95\x52\x97\xcf\x5d\x8f\x10\x25\x3c\x0e\x58\x67\xf9\xfb\x54\x32\x25\x3c\x89\x2c\x3f\x0f\x66\x0a\x5b\x37\xa4\xea\x0e\x71\x40\x12\xdf\xfd\xa2\xc9\xdb\xf0\xa3\x1e\x9a\x1c\x92\x12\xb0\x4d\xdf\x99\xe3\xd7\xdc\x42\x63\x55\x2a\xa7\xd4\xb3\xa3\x97\x38\x7e\xb8\x34\xe5\xd0\x8b\xba\x7e\x2b\xb2\xa6\x7e\x2c\x60\xd5\x3c\x2f\x45\x31\x50\x6e\xee\x46\x1b\xc5\x3c\x5f\x6c\x03\xc7\x87\xb2\x75\x55\xb6\x53\x82\x6f\x4a\x44\x0c\x3e\x9e\x5e\x8a\xaa\xb9\x83\xe2\xe0\xab\xf0\x94\xa8\x50\xe0\x9e\xaf\x44\xae\x6e\xb2\xc3\xf3\x1c\x75\xff\xe5\x84\x53\xca\xea\x2c\xf9\x64\xbb\xbf\x9a\x0e\x62\x14\x59\xb1\x32\xcb\x60\xa0\x1a\x70\xd7\x7f\xca\x79\x41\x89\x76\x12\x5b\xc2\xc2\x92\x1e\x3a\x80\x34\x25\x10\x81\xf4\xba\x95\xad\x17\x6d\x93\xa9\xf3\x97\x81\x24\xf2\x5a\xf7\x33\x6d\x0b\x94\x80\x54\x48\x8a\xec\x78\x01\xf1\x2d\xfb\xdf\x31\x71\x8a\xad\x26\x77\x67\xf5\xf2\x7e\xdd\x47\x7c\xc4\x68\xeb\xf1\xe2\x49\x93\x1e\x61\x3f\xc4\x70\xac\x64\x28\xab\x71\xd6\x67\x60\xe2\x76\xdf\xa0\x18\xe1\xb5\xa6\xe4\xb2\xb9\x78\x74\x7f\x71\x10\x73\x9b\x4f\xb5\x79\xa2\xbb\xf2\x90\xa9\xcf\x14\x3a\x69\x1c\xb0\x24\xea\xa7\xcd\xbc\xd7\x19\x87\xc2\x66\xac\x84\xd6\x4f\x55\xf6\xea\x8a\xde\xab\x42\x5f\x5f\x6c\xdc\x71\xc4\x62\x94\x5c\xaa\xcf\xf2\x98\x0d\x37\xe0\xcf\xd2\xa4\x71\x24\x6d\x9c\xe3\x4b\x10\x3e\xce\x19\xc7\x91\x71\x64\x02\x8b\xc0\x7a\xdc\xf9\x3f\x91\xc0\x66\xc6\x0e\xd0\xec\xb1\xd2\x87\x97\x9d\x3c\x25\x89\xa9\x65\x61\xa8\x77\xe2\x05\x9e\xa0\x3a\x66\xcd\x67\x1a\x80\xbf\x42\x68\x4d\xae\xce\x19\x3a\x8a\x27\xfb\x6d\x77\xe5\x78\x5f\x9f\x8c\x8e\x03\x69\xab\x82\x67\x39\x66\x8f\x70\xc7\x13\x16\x21\xda\xfe\x98\x15\x56\x18\x75\xd8\xd8\x40\xe3\x04\x94\xb2\xf5\xf7\x42\xe7\x60\xc1\x94\x57\xd6\x3c\xf8\x21\x34\xa4\x91\xef\xa5\xfb\xbe\xdf\xc4\x93\x2f\xc4\x62\xa2\x13\x8f\x49\xb9\xcf\x3a\x22\x01\x1a\x33\x6a\xf9\x22\xb2\xda\x6d\x06\xeb\x62\xd0\x3a\x4b\x63\x26\xa3\xc0\xd3\x9c\x8a\x9f\x1f\x15\x3a\x62\xa6\x08\xa2\xb9\x9b\x7d\x58\x37\x7b\xac\x41\xac\xba\x00\x30\xe6\xdc\x92\x67\x39\xf6\xcb\xfd\x5b\x6f\xe9\xe3\x34\xe0\x8e\x22\xb2\x11\xb9\x85\xe0\x75\xdf\x5e\x44\x04\x3d\x8e\x7d\x83\x1c\x27\x03\x98\x3d\x8d\x05\x89\x48\xda\xcd\xe2\xd5\x4f\x50\x93\x09\x20\x84\xc2\x9c\xb4\xa3\xab\x5b\x96\xc5\x7f\xce\x55\xff\xe0\xd2\x44\xb8\x0a\xb6\xe7\xe3\x11\xaa\xd6\xd7\x28\xfa\x43\x04\x05\xd4\xfb\xc6\x39\x7b\x5f\xfe\xb8\x66\x04\xb1\xe4\xff\xd3\xd7\xe0\x68\x0c\x01\x41\x0e\x9d\x9b\xc5\x93\x1a\xfd\x99\x23\x3f\xa0\x0f\x0c\x9e\xc4\xb9\xd6\x93\xaf\x03\xdc\xee\xee\xae\x22\xf2\x30\x39\x6c\x22\x8e\x54\x2e\xd6\x3d\xc5\x54\xfa\xec\xfe\x1e\xce\xff\xc7\x5f\x25\x8d\xb1\x21\xc0\xbe\x2f\xcb\x89\x50\x56\xef\x77\x3d\x90\x6a\xb0\x35\xc7\x46\x38\x89\x3a\xa4\x62\x77\x01\xb6\x53\xc5\xf1\x43\xa4\xd5\x14\xdc\xb7\x5b\x81\x25\x92\xcf\x8a\x83\x25\x6f\xeb\x03\xef\x24\x88\x12\x5b\xd9\xaa\x31\xbf\xb8\xb5\x44\x00\xab\x62\x20\x1b\xd5\x8d\xd4\x88\xcd\x90\xa2\x06\x6f\x33\xdd\xa1\x30\xb2\x18\xc7\xe5\xc3\xf2\xd7\xfe\x6f\x12\xc7\x80\xfe\x7c\xa6\xca\xed\x09\x14\xe6\xb3\xaa\x63\xf7\xe9\x93\x98\x07\xcc\x52\xcd\x61\xe7\x41\x4f\xcd\x35\x6f\x0b\x93\x84\x70\x44\x3d\x08\xd3\x40\xb5\xdd\xad\x2e\x88\xaa\x68\x92\x68\x26\x6c\x8b\x3a\xe2\xff\x47\xec\xb5\x23\x05\x1b\x9a\x24\x46\x47\x6e\x73\xda\xe6\xe5\xdb\xf5\xf9\x38\xae\x3b\xd3\x84\x06\x3c\x19\x90\xc5\xba\x5e\xc1\x01\xf9\x28\x4d\x28\xb3\xab\xc6\x1a\x7d\xec\x4d\x9c\xa1\xa8\xa2\x09\x0b\x80\x3a\x75\x5b\xdc\x11\xca\xca\x87\x84\xfb\xad\xc2\xd6\x93\x79\x57\x28\x61\x69\x8a\x00\x1e\x6b\x6d\x5c\x6d\xe8\xc3\x37\xc4\x03\xdb\xfe\xfa\x05\xaa\x12\xa1\xd1\x70\x51\x73\xfa\xed\xb2\xc1\x05\x02\xb4\xbd\x3c\xf7\x6c\x07\xdb\x93\x57\x93\xe9\xe6\x0d\x4f\xac\x4b\x62\x67\xf6\x43\xd9\x88\xac\x82\xd9\xad\x2f\x49\x15\x78\x02\xeb\xab\x91\x1e\xd7\x64\x98\xb6\xad\x8a\xe7\x2a\x9f\xcc\xd1\x54\x2b\xb0\xa8\xf9\x5e\xc0\xd3\x1d\x12\x81\xd1\x7d\x45\xe1\x29\xfb\x09\x79\xaf\x66\x36\x59\x8d\x89\x88\x03\x4b\xa6\x87\x38\xaf\x3a\x3b\xcc\xea\x8d\xd3\x44\xa8\x04\xa1\x72\xad\xd3\xfa\xad\xc0\x0e\x91\xee\xf7\x34\xb7\xb3\xbc\xde\x80\xd0\xef\xbb\xd2\x7a\x39\xe3\xfb\x95\x61\x94\x98\x2e\xad\x8b\x6a\x73\xf3\xbe\xc1\xe4\x83\xca\x38\xf5\x9c\x70\x57\x42\xbe\xdf\x8b\x97\xac\x98\xa9\x90\x24\x8a\x82\x00\x8f\x2f\x17\x98\x05\xbd\x24\x54\xa3\x89\x4a\x13\x2b\x17\xd4\xb5\x78\xcc\xef\x23\x89\x52\x2a\x70\x5d\xb2\x77\x8d\x7e\x12\x95\x38\x7e\x48\xa2\xeb\x4f\x01\x45\xa2\x8e\x3d\xdb\x15\xb8\x7d\x6e\xfa\x43\x5f\x72\xfc\xb8\x3a\x4c\xa4\xed\xc9\xf2\x74\xe0\xfe\x80\x00\x34\xdf\x9e\xef\x58\xd3\xfb\xb2\x68\x9e\xbd\x11\x4c\x8c\x24\xdc\x7a\x19\xdb\xae\xda\x46\x83\x30\xf2\xbd\xa8\xf7\xef\x6b\x05\xd7\x95\x38\x74\xef\x82\x06\x31\xc3\xfa\xf5\x2d\x34\x17\xd4\x90\x94\x86\x81\x46\x5b\x83\x7c\xa5\xb6\xbf\xcb\x9f\x18\x6a\x90\xb1\x4f\x51\x7e\x11\x95\x56\xe2\x34\x2f\x79\x38\xb9\x24\x00\x36\xf6\x62\x16\xa9\xef\x60\xa6\x34\x34\xa0\x2d\x72\xdc\x51\x97\x8f\x97\x01\x8d\x82\x84\x07\x83\x26\xc1\xd1\xe6\x4c\x49\x0c\x88\xba\x54\x50\x35\x99\x99\x44\x1b\x94\x70\x8d\x39\x88\xbb\xf2\xb0\x83\xe3\x29\x47\xba\x51\x10\x33\x26\x64\x64\xbb\x69\xcc\x13\x19\x8d\x18\x21\x36\x50\x97\xf9\xeb\x34\xb2\xa3\x09\x09\xe2\xd0\xcb\x16\x59\xba\xe5\x71\x23\x08\xa5\x54\xb1\xd4\xe5\xe5\xbc\x60\x34\xbe\xaf\xa5\x98\x58\x5c\xca\x58\x12\xa6\xfd\x0e\xbc\x85\x06\x09\xf5\x2d\x6e\xf5\xff\x2f\x90\xcb\x5f\x5b\x48\xcf\xcc\x83\x25\xe2\xee\x2e\xc7\xcf\xc3\x13\xea\x24\x31\x54\x59\xcd\xb3\xb3\x50\xca\x79\x8c\x94\xb7\xf6\x95\xed\xca\x6d\x76\x28\x56\x3f\x05\x02\x17\xfc\x10\x6d\xb0\x28\xa9\xcb\x09\xab\xf2\x3f\x2e\xa0\x1e\xfe\x0c\x00\x84\x36\x97\x27\x2c\xae\xd8\x96\x8f\xb1\x17\x4e\xb9\x61\x58\x15\x86\x9f\xea\xf9\x06\xba\x1f\x4b\x53\x89\x5b\x76\x1b\x25\x88\xf7\x5d\xbb\xfc\xff\xf8\xc4\x15\xf9\x8d\xff\xf8\x0b\x2b\xdb\x9a\x91\x79\x44\x67\xbd\x2e\x3e\xc6\xaa\x50\x11\x93\x50\x4f\x88\x9f\x3f\xd5\x72\x19\x00\x4b\x47\x06\x93\x0a\x61\x2c\x61\xd1\xd9\x3a\x48\xfe\x49\xa5\xa6\xb8\xc1\x3b\x77\xb3\x79\x5e\x2f\x1f\x77\xcf\x15\xd4\xcf\x65\x7e\x09\xb3\xfc\xc5\x94\x50\x51\x82\xc5\x36\xdd\x55\x3b\x07\xc2\x84\x1f\xac\x62\x45\x99\xe3\xfe\x1f\x8b\xb9\xd7\x73\x14\x21\x94\x42\x1c\xa4\xae\xa2\x3a\xd6\x32\xa2\x14\xd2\x08\x23\xa3\xd5\x76\xd9\xb3\xd3\xf8\x63\x9a\x1b\xe6\x90\xd6\xb7\x50\x40\x9d\xd5\xeb\xe3\xa9\xac\xba\x98\x97\x05\x91\x95\xc1\x5c\xde\x2d\xd6\xf7\xfb\xed\xfa\xf6\x61\xb5\xd9\x7f\x5d\xfd\xd5\x1d\x4f\x04\x36\xcf\xd7\xd9\xa1\x38\x9f\x10\x44\x61\x85\x07\xf2\xc9\x8c\x67\x61\x68\xa9\x43\x3d\x4d\xb3\x17\x68\x3e\x5f\x10\xc9\xb7\x63\x6d\xd3\xe3\xba\x78\xc5\xfc\xe8\xa9\xca\x6a\x18\xd8\x32\x16\xc6\x96\xac\x0a\x7b\x38\xf7\x12\xe6\x71\x2c\xdc\x8f\x4e\x0c\x76\x50\xe7\x60\x9a\x38\x9e\xfe\x16\x4d\xd0\x53\xbe\x2e\x5f\x33\xb8\x12\xd5\x7d\xd6\xfc\xfd\x2a\x7c\x06\x84\xc5\x61\xe0\x69\x79\x2d\xa8\xfc\xae\x14\x13\x88\x0a\x8b\x43\x9b\x4f\x3c\x66\x05\x2c\x6d\x33\xe4\xa4\x42\xc7\x62\x08\x94\xfb\x9e\xa3\xc2\xfb\x80\xb0\xc2\xdf\x2d\xe5\x09\x22\xfc\x5b\x4f\xec\xd1\x98\xa5\x28\x2c\x38\xb8\x23\xfa\xba\x47\xd7\x7b\x58\x66\x65\x2c\x66\xc2\x51\x97\xdf\x9e\xb3\x7c\xb2\x9e\x19\xa3\x36\x7a\xba\xca\x3a\x4a\xcc\x61\x7e\x8a\xb5\x61\x1f\xb3\x0b\x6a\x65\x75\x2e\x27\x04\x56\x43\xa3\xcd\x38\x05\x04\x39\x38\x41\xb2\x09\xbf\x08\x65\x5c\x89\xd0\x25\xa4\x5b\x4f\x7c\x8d\x9a\x18\xe3\xd7\xc1\x81\x86\x9e\x54\xad\xe3\x56\x72\xc7\xd2\x84\x07\xb6\x2a\x73\x5f\xea\x73\x0e\x5f\x30\x0e\x9e\x6c\x08\x2c\x4d\x24\xda\x46\x4b\x1c\x2e\x9a\x06\xaa\x62\xfa\x2b\x29\x4b\xf1\xad\x3c\x89\x97\xac\x6e\x44\xb1\x39\x9f\x3a\x63\xc6\x52\x6e\x39\xe6\x35\xe8\x0c\xf7\x7a\xe4\xf1\x9b\xbc\x38\xa1\xac\x03\x88\x79\x07\x1f\xe7\xd6\x0b\xbf\xb8\x98\x07\x27\xd9\x60\xed\x87\x13\x28\x98\x83\x71\x7b\x5b\xc7\x64\x92\xa6\xa2\xdf\x66\xef\x7b\xd9\xe8\xee\xa2\x52\x79\x99\xa0\xef\x43\x30\x00\x6b\xdd\x2f\xf4\x67\x9b\xd2\xea\xf5\x0d\x80\x0c\x4c\x01\xc5\x35\x73\x93\x67\x87\xe7\x06\x45\x10\x1e\xe0\xed\xa9\xcc\x33\x35\x5d\x8a\x9a\xb0\xae\xaa\x9f\x97\x35\xe8\xa5\x28\x74\xd6\xce\xb1\xee\xc1\x21\x26\x2a\xf4\x9b\xa9\x45\xbb\xae\x26\xf4\x57\x94\x19\x22\xb1\x2c\x7e\x2b\x8a\xbb\xec\xcf\x4c\xfc\xd1\xfd\xdd\xa2\x36\x5c\x38\xd9\x85\x4f\xd9\x20\xa6\x61\x86\x69\xaf\x22\xef\x32\xd2\x33\xfc\x1f\x94\x07\x84\x22\x12\xe5\x4d\xd4\xc3\xd6\x09\xca\x83\xd4\xea\xf8\x9c\x50\xae\x01\xeb\x81\xab\x42\x77\x9f\x86\x87\xb1\xc0\x08\x5d\x95\xa7\xf7\x27\x71\xfa\x08\x62\xc2\x43\x4d\xb1\x3a\x2b\x85\x3e\xc0\x85\xc2\x93\x1b\x14\x85\x5c\x87\x5e\x90\xa0\xba\x09\x6f\xa2\x1b\xf2\xc7\x5c\x7b\xa2\x1f\x1f\x11\x8c\xe9\x9c\xac\xc7\xa2\xae\xff\x18\x77\x6e\xfd\x06\xd0\x9f\xf2\xc8\x81\xe3\xec\x45\x36\x65\x39\x47\xb5\x42\x79\xa4\x03\x69\x53\xa3\x9e\x82\x62\xef\x78\x41\x44\x6e\x2b\x55\xf3\x97\x27\x41\x8a\x24\x68\x48\xd2\x95\x97\x67\xbd\x05\x55\x2f\x0e\x22\x2b\xea\x66\x98\x15\xe2\x84\x92\xc0\x6a\x8f\xce\xb7\x51\x53\x4e\x98\xe0\x6c\xf4\x31\x61\x37\xd0\xd6\x9f\xfe\xb0\xe6\x98\x6e\x70\x7d\x11\xfd\x24\xe6\x71\xc4\xe9\x90\x1a\xef\xaa\x2a\x5f\xa6\x4b\x9f\x27\x21\x47\x4a\x85\xed\x87\xa9\x7d\x9e\xf0\x10\x5c\x3e\x13\x09\xe4\x66\xb2\x08\xf3\xdd\x47\x94\xd3\x24\xf1\x74\x09\xc3\x2a\xdf\x38\x84\xe0\x8c\x27\xac\xef\x44\xb1\xe8\xbb\xd9\xab\xce\xe2\xd1\x38\x53\x90\x3a\x8e\x62\x27\xe6\x36\x2a\xc9\x7f\x30\x1f\x38\x37\x58\x62\x3c\xda\x1e\xe4\xc9\xae\xc9\x79\x1a\x60\x1a\xda\x4a\x9d\xdd\x9e\x45\xa5\x33\x51\x58\xd1\xd9\xf1\xc8\x34\x0c\xd0\xfc\x36\xe2\xe5\xa2\x44\xe9\xcd\x38\x17\x44\x85\x2e\x17\x38\x4a\x05\x71\x91\x10\x34\x1f\xb7\xd0\x60\x2a\x7c\x8c\x34\xe3\x42\x07\xe8\x25\x7e\x29\xf3\xcf\x93\xfb\xdc\x9f\x00\xd6\x17\x6e\xe7\x6f\xeb\xfe\xa9\xb9\xb2\xec\xfc\x1b\x91\x3c\xb2\xac\x4c\xcd\xf3\x9d\xa8\x1b\xd7\x45\xe3\x0f\x1a\x82\x93\x00\xc6\x15\x2f\xae\x74\x8c\xfd\x65\xcb\xc7\xf5\xc3\x7e\xfb\xed\xe9\xe9\xee\x2f\xac\x39\xed\xd6\xab\x8d\x07\x9b\x53\xae\x00\x02\xcf\xde\x55\x35\x59\xdd\xec\xca\xce\x97\x9f\x3a\x95\xf3\x37\xa7\xc1\xf6\xb1\xd5\x36\x95\xde\x77\x62\xbb\xe3\x40\xac\x54\x12\xa6\x16\xde\x87\xbc\x28\x2e\xcd\x35\x5b\x8c\xe3\x90\x44\x3a\xed\x19\x4b\xb7\x78\xc9\xd9\x59\x06\x90\x2a\x3b\xcb\x44\xa5\x2e\x7a\xe3\xbb\x41\xd2\x03\xbf\x1d\x64\x77\xd7\xd1\xed\xac\x8b\x25\x74\x24\x02\x94\x9b\x48\x68\xd7\xba\x7f\x5d\xaa\x59\x5b\xd4\x5a\x75\xe5\x5a\xaa\xf6\xcf\xa2\x46\xf2\x3b\x5c\xe5\x38\x85\xf6\x7f\x43\x55\xf6\x7f\xc3\xf9\xe7\xcf\xd4\x24\x60\x3e\x2b\x7e\x3e\x0e\xf3\x0a\xae\x8c\x67\xa1\xf2\xdd\x78\x08\x94\x15\xa6\xb5\x7b\xd8\xba\xf0\xdd\x08\x34\x0d\x88\x65\xda\xc5\xbb\x88\xc2\xbd\xa8\x6b\xa8\x9a\x5b\x51\x7f\xab\xc5\x01\x92\x00\x6b\x6f\x75\x37\x5a\x59\x37\x61\x71\x2a\xf3\xbc\xbb\x46\x18\x09\x62\xbd\x18\xcc\x27\x6e\x40\xcb\x73\x9e\x63\x1b\xff\xd8\x1e\xa5\x91\xb2\x9e\xed\xe9\x5c\x3f\xf7\x04\x54\x34\x8d\x74\x8a\x62\xdb\x77\xe5\xe1\x01\xce\x47\x51\xbd\xd4\x48\xf9\x7c\x11\xee\x8d\xbf\x48\x1a\x99\xd8\xe9\xca\x16\xe5\xb9\x50\xb0\x38\xf4\xb9\xd1\x34\x4e\x09\xa6\x28\xea\xb3\x1c\x18\xce\x34\x09\x02\xa3\x3b\xe4\xdc\x10\x93\x33\xbe\x76\x62\xac\xa0\xb6\x05\x9b\x2c\x9e\xd6\xfb\x73\xe5\xa1\x07\x29\x0d\x34\xb6\xd7\xbd\x65\x45\x01\x55\xa6\xbb\xbf\x33\x85\x0b\xf4\x1a\x5e\xb3\x1a\x66\x0a\xe2\x69\x7b\x2e\x5a\xf4\x63\x66\x0b\x9b\x3e\xfa\x9f\x18\x97\x8b\x70\xec\xb3\xb4\xa0\xbb\x36\xa3\xae\x74\x66\x13\xe2\xc5\x0b\xec\x2a\xa1\xad\xde\xd6\x07\x6f\x90\xa5\x0a\x21\x98\xdd\x76\x35\x09\x8a\x52\xa6\x2c\x51\xc2\x1e\xf1\x04\xa8\x8f\xd1\x13\x5c\xd1\x34\xe5\x5e\x3e\x02\x93\x7b\xa2\x6a\x0a\xa8\xc2\xfd\x6b\xf9\x36\xae\xd4\xa7\x22\x08\x3a\xd2\x08\x38\x1c\x40\xcf\x67\x68\xe6\xbf\x85\xe0\x80\xad\xba\x50\xa9\x28\x70\x9e\xc7\x4d\x59\xcd\x26\x29\x53\x49\x52\x42\x3b\x8d\xa7\x6d\x76\xa8\xc7\xb9\xbf\x54\x26\x1a\xab\xfc\xa7\x0a\x5e\xf7\xcf\x3d\x72\x0c\x0f\xc8\xce\xcc\xf4\x1c\x4a\x13\xb7\x3d\x95\x8c\xa2\xd7\x86\xa0\x86\x3d\x32\xa3\x3a\xbb\x39\xbe\x13\xc5\x6c\x87\xcd\x31\x2b\x1a\xeb\x58\xcd\x18\x82\x54\x69\xab\x8d\x28\x2b\x68\x1d\xbf\x43\x9f\x46\x48\x21\xa0\xba\xd3\xfa\x76\xd8\x1d\x27\x51\xea\x47\xe8\x04\x9f\xc5\x25\x68\x86\x35\xc6\xf1\x43\x9b\x38\xe6\xe1\x44\x73\xc3\xd7\xdc\x06\x53\xc8\x70\x8a\x20\x29\x65\x51\xb4\xdb\xec\x50\x88\x7c\x57\xde\xdb\x02\xdc\x64\x2e\x1b\xc1\x85\xb3\xaf\x1d\xa9\xd7\x07\x1f\xc5\x48\x83\x6a\x33\x12\xb3\xcb\x4f\x55\x79\xa8\x3a\xc0\xa3\x08\x02\x82\xef\xe9\x6e\xb3\xbc\x69\x27\x97\x15\x35\x52\x20\xcb\x9f\x17\xdd\xc4\xa3\xcb\x8a\x20\x51\x01\xb5\xe5\xc6\x47\x47\xf5\x34\xc1\xf3\x89\x20\xd5\x18\xf0\x1f\x2a\x51\x38\xca\xeb\x8f\x2e\x26\x43\x6c\xe1\x50\xa8\xc5\x67\xb9\x8f\x97\x95\x18\x53\x29\x50\x11\x38\xc8\x0c\x9a\xcc\xe6\xb9\x02\x58\x17\xaf\x22\xcf\xf4\xea\xbf\xae\xf8\x78\x0f\x75\xdd\x37\x1b\x89\x30\xe4\xba\x03\xa2\x78\xc0\xc5\xfd\xf6\xf3\xbc\x86\x08\x99\xc6\x94\xfc\xa9\x7c\x0b\x83\x3f\x66\xbc\x01\x11\x45\x94\xbb\xd6\xcf\x41\xb2\xaf\xcf\xad\xd3\x78\xf2\x80\x51\xc2\x6c\x42\xab\xb0\xa6\x69\x5d\xac\xce\x55\x1f\x68\x88\x48\x18\xd1\xc1\x9f\x56\xcb\xe5\xe2\x37\x8a\x4a\x22\x66\x01\x78\x25\xeb\xac\x46\x7a\x8c\xe6\xa2\x14\x2e\xe2\x94\x22\xaf\xda\xa2\x6a\xde\xca\xea\xe5\x03\x55\xc9\x79\x4f\x70\xf2\x14\xb1\xb6\x72\xdd\x35\x34\xf7\xe2\xa7\x6d\x7a\x9d\xfe\x9a\x89\x85\x19\xeb\x76\x95\xd6\x47\x75\x03\x92\x28\xb5\x4c\x99\x52\x74\x7f\xd2\x89\xee\x13\x59\x58\x52\xad\x9f\x50\xe9\x6e\x72\x71\x9a\xa6\x24\xec\xac\xc4\xb2\x3c\x1e\xb3\x71\xb3\x7b\x1c\x4c\x00\xa6\xb3\xde\x89\x60\x61\x82\x7d\x06\x3f\x56\x5f\xbf\x5d\xea\x66\x50\xc1\xa2\x04\x65\x04\xdc\xb6\xba\x9b\x41\x20\xf7\x0b\x57\x30\x4d\x84\xf1\xa0\xcf\xf6\xf3\xfd\x54\x98\xa3\x9d\x9f\x5c\x3c\xe4\xae\x3f\x30\xab\x5d\x34\x59\x5f\xbd\xaf\x27\x61\xab\xe0\x29\x57\xa8\x28\xe1\x5f\x52\xca\x14\xa6\xc8\xb6\x65\x7e\x1e\x01\x77\x44\xca\x13\x2c\x0d\xad\x97\x8f\x0f\xeb\xe5\xfe\x61\x7d\x31\x77\x46\xb3\x46\xc6\x49\x18\xbb\xb4\xc6\xa6\x94\xe7\xfa\x43\xbe\x00\x7f\x42\x62\xc9\x0a\xbf\x96\xcd\x6a\xe7\xcb\xfb\x42\x26\xca\x52\x92\xb7\x8e\xcd\xd5\xf9\xbd\xff\xbb\xc6\x54\xd5\xdb\x50\x82\xd7\xaf\x1b\xc9\x63\x2e\x7c\x51\xa3\x12\xf9\xba\xa8\x9b\x9e\x56\x9b\x0a\xa9\xa2\x94\x77\xad\x24\x8b\x8b\x3b\x73\xc3\x54\x42\x6c\x5b\xf7\xaf\xd1\x1d\x48\xdd\xd8\x97\x3a\x85\x0e\xc3\x14\xd1\xe6\xef\x8f\x6f\xc5\xa0\x58\x2e\x74\xa2\x31\x58\x82\x9f\xa7\xac\x82\xab\x4c\x4f\xe6\x04\x10\x89\xdf\xcd\xb6\xe8\xc3\xf9\x98\x97\x4d\x03\xd5\xfb\x03\x7c\x64\x21\x81\x32\xa4\x71\x36\xe7\x42\xab\xea\x3c\xfa\x66\x86\x84\x28\x0d\x8d\xb9\xc1\xeb\xf2\x2c\xa7\xd0\x45\x61\x62\x62\x7a\x30\x41\x97\xd7\x7d\x80\x37\x4f\x7a\x34\x7e\x27\x26\x66\x9e\x23\xf9\x8f\x19\xb9\x30\x2a\x8c\x4e\xdd\xbb\xc7\xc2\xa9\x6d\xd6\xa8\x2f\x2e\x24\x83\x88\xfa\x7e\x71\x2b\x46\xb3\x14\x27\x21\xb3\x7c\x28\x01\x83\x3f\x30\xac\xce\xcb\x40\x84\x28\x9f\x83\x0f\xe4\xe9\x7f\xe7\x29\xa0\xa8\x0c\x34\x60\xd0\x51\x75\xca\xc6\x9d\x60\xd8\xfc\xbb\x94\x81\x31\x3a\x70\xaa\x13\x56\x2b\xd0\xbd\x49\x19\x05\xd6\x0d\x6a\x77\x02\x95\x95\xdd\x9f\x85\xe5\xe7\xb3\xaf\xcf\x99\xa2\xa1\xac\x26\x95\x44\x30\x74\x61\xdf\x4e\xf9\xf9\x03\x10\x89\x24\x42\xbb\x6e\xd5\x66\x77\x91\x57\xb8\xcc\xfa\xcb\x58\x68\xac\x4f\xa9\xe6\x3c\xd4\xf7\xa3\x32\x89\x19\xd0\x2e\x2c\x39\x1f\xa1\x68\x1e\xc4\x44\xcd\x98\xca\x24\x85\x14\xfa\x06\x3b\x51\x89\x23\x34\x30\xe1\x92\x9c\x6c\xb3\x92\x06\x01\xa2\x8d\x77\xf7\xdb\xbf\x3e\x77\xed\xe6\xdf\x2d\x95\x21\xf6\xd8\xaf\x97\x8f\x2e\x8d\x3f\x7e\x4f\x54\x2a\xa2\x1c\x5b\x4b\x97\x06\x1c\xdf\x02\x4f\xec\x8e\xb9\x68\xca\x63\xa6\xfe\xf4\x67\x4a\x49\xc1\x0c\xf5\x89\xea\x5d\xc9\x7e\xf7\xee\x3e\x77\x4c\xa5\xe2\x1a\xbc\x9a\xb4\x4b\x4f\x44\xa5\x21\xfe\xa7\x95\x4e\xb0\x6a\xb0\x7e\xd8\xad\x6e\x37\x8f\xc3\xc5\x27\x15\x18\x64\x4e\x29\xdb\x95\xfc\x54\x96\x56\x96\xdf\x1f\xd5\x49\x1c\xda\x72\xcb\xe9\x54\x56\xa8\xa4\xfc\x79\xb9\x57\xea\x44\xa0\x8f\xec\xbb\x3e\xea\x27\x91\xe9\x27\xa8\x6c\x67\xde\xf8\x65\x6b\x1a\xf9\x8c\xe2\x1e\x8d\xff\x22\xcf\x6d\x2b\xc9\x4d\x59\xb9\xd6\x6e\x3f\x34\xb5\x65\x0d\xb4\xb0\x96\x31\x75\xb4\x8d\x49\x50\xa9\x15\x00\x6c\xe3\x83\x3b\x6b\x8e\x26\x1f\x06\x0c\xe8\x3e\xf7\xfb\x54\xe6\x13\xf4\x80\x34\x01\xd1\x3d\x89\x90\xe3\x19\x75\xed\xa3\x1f\xac\x45\xc3\x62\xee\xd5\x99\xee\xce\xfa\x7c\xdc\x95\xf7\xa2\x78\xff\x78\x55\xa8\x20\x8d\xbc\xe8\xaa\xc5\x3a\x0f\xda\xf8\x54\xc8\x01\x37\xf5\xa7\x21\x19\x2a\x55\x21\x44\xe8\xb6\x3a\x6e\x29\x2f\x83\xe3\x8e\x46\x81\x60\xc9\xa0\x13\x7c\x29\x2a\x6d\x59\x24\xfc\x80\x44\xdb\xcc\x48\xd5\x7c\xab\xf2\x41\x77\x80\x8a\x98\x42\xe4\xec\xbe\xce\xab\xab\xf7\xea\xee\xd8\x2c\x9f\x2f\x05\xa6\x66\x1d\x20\x15\xa5\x94\xea\xbe\x70\x8a\xa8\xa1\xd7\xcf\x67\x87\x22\xc4\xf6\x84\x38\x56\xd1\x55\xf3\x6c\x13\xe6\x5b\x91\xeb\x0f\x32\x77\x8a\xa4\x56\x5e\xe2\x3c\x05\xd0\x22\xde\xc7\x3f\x09\x91\xb6\x3b\x0c\xfb\xc7\x3e\x5d\x2d\x8a\x18\xbb\x9b\xd4\xd0\x7c\x7d\x97\x50\x5d\xea\x01\x51\x15\x53\xdb\xc0\xad\x7c\x53\x74\xdd\x89\x77\x51\x15\x4b\x13\x77\x95\xfe\x9b\xf2\x42\x32\xd5\x0d\x4b\x12\xc6\xb0\x9b\xa4\x3c\x9d\x3a\x85\x63\xaa\x92\xd4\xca\xea\x39\xaa\x2a\x8b\x90\x9e\xa4\x4c\x15\x4d\x42\xdb\xef\x77\xca\x34\x54\x1b\xf8\xaf\x3f\x9b\x72\x90\x2e\x71\xbb\x78\x17\x45\x73\x5d\x95\x59\xb3\x52\x65\x51\x1e\xb3\xff\x9e\x61\xef\x89\x4f\xba\xf1\x92\x20\x08\x79\x8e\xed\x65\x72\xbf\x4c\x87\x31\xe9\x02\x8f\x4d\xc7\x7c\x3c\x27\xe8\x44\x15\x33\x89\x55\x5d\x6a\xc3\x09\x81\x0c\x1e\x8f\x06\xd9\x02\xfe\xf7\x0c\xfd\xdc\xe3\x89\x12\xbd\x1a\xd8\xae\xd3\xaa\x1a\x5f\x8c\xf3\x88\x28\x4f\xf6\xd5\xb3\x2d\x0f\xf7\x6c\xc5\x95\xc6\x6c\xe9\x5d\x89\x15\xf0\x8f\x7b\xfd\xbb\x8d\x58\xa5\x29\xc3\x0f\xd5\x04\x61\x1b\x1f\x7f\x85\xb1\xea\x04\x55\x42\x58\x07\xbc\x86\x3c\xdf\x94\x7d\x3f\xc4\x64\xc6\x48\x26\x52\x8a\x8a\xd5\x1a\xaa\x7b\xd1\xa8\xe7\x1d\x5c\x32\xe9\xff\xe3\x83\xd4\xc8\x47\x29\xd5\xe9\x4f\x48\xef\xed\xb5\xb7\x88\x0b\x78\x92\x32\x50\x52\x25\x91\x75\x5b\x5e\xcb\x17\x58\x22\xb2\xc3\x66\x5f\x27\xe3\x74\x82\x52\x08\x42\x8a\x42\x97\x05\xe8\xb5\xf2\x62\x63\x93\x88\x58\x29\x6a\xb1\x5b\x57\xe7\xf7\x6d\x53\xaa\x17\xcb\xb6\xef\x51\x02\x93\xb1\x10\x01\x56\x9f\xa7\x41\x82\xd2\xa1\x9d\x0c\xb6\xf9\x07\xf1\x6e\xde\x29\x51\x9a\x59\xd6\x5a\x0d\x39\x1c\x44\x03\xdd\x97\x5b\x14\xfa\xa1\x44\x6c\xca\xaf\xc0\xbd\xb3\x49\xa9\xc9\x37\xd2\x12\x12\x4b\xb2\xd2\xc0\x01\xa5\xe4\x27\x73\x4c\x2b\x6a\x28\xea\xda\xd5\xcd\x7a\xf9\x38\x3d\x6a\x18\xba\x61\x4e\x80\xf4\x07\x34\xcf\x93\x67\x84\x88\x76\x72\xa1\xa2\x50\x65\x35\x8f\x14\x51\xc0\x43\xab\x43\x81\xa5\xf2\x6d\xb7\xdd\xff\xc2\x2a\x81\x30\xce\x3f\x68\x6e\x00\x66\xe5\xe3\xa8\x02\x99\x04\x08\xd4\x07\x35\x50\x19\x6d\xff\x0e\xd2\x15\x08\xf7\xd9\xa0\x80\xe4\x0f\x6b\xab\x09\x71\x80\xe6\x47\x59\xbd\x20\x71\x42\x0f\xf3\x57\x26\xb4\xac\x0a\x5d\xf7\x0d\xe6\x1a\x9f\xa0\x32\x65\x75\x1c\x84\x24\xca\xc4\x56\x51\x73\xe0\x67\x2c\xfa\x63\x5a\xa7\xfd\x0b\x7c\x2c\x00\xdb\x2d\xff\x09\x55\x3f\xf5\xec\x50\x1d\xc4\x14\x69\xd8\xaf\x44\x9d\xa9\x4b\x95\xe3\xd1\x23\xeb\x40\x5a\xf5\x6a\x70\xe2\x6b\xef\x4b\xe8\x4b\xaf\xba\xf5\x85\x85\x15\x2b\xcc\x41\xef\xe0\x88\x20\x99\x73\x05\xf5\xa8\x2f\x42\x87\x3a\xc2\x9c\x03\x56\x38\x9f\x90\x53\x44\xdf\x00\xd4\x8b\x89\x59\xd3\x91\x92\x54\x78\x6a\xec\x57\xb1\x7b\x3f\x81\xbe\xf6\x6a\x22\xbf\xf0\xc6\x3e\xaf\x7d\x68\x12\x71\x6c\xdc\xd1\x20\x1a\xcc\x3b\xef\x3b\x17\x4d\x13\x21\xd3\xde\xf5\xb0\x44\x38\xef\x47\x59\x8e\xd8\xfd\xa8\x8e\x43\x86\x19\xea\x07\x78\x1b\x49\x46\x8e\x07\xc5\x80\x0a\x69\x7b\xcf\xb8\x80\x1f\x7b\x57\x5e\x9d\xdf\x51\x06\x10\x99\x47\x26\x8f\x1d\x27\x14\xf3\xab\x3f\xb2\xa2\xc8\x8a\xc3\x7e\x55\xf4\x40\x2d\x1d\x73\x08\x7c\x33\x9d\x0d\x93\x46\xf3\x47\xd3\x54\x90\xa0\x03\xa1\x5f\x9a\x77\xcd\x68\xa8\xe3\x6e\x67\x59\xd5\x4a\x9c\x60\x04\x12\xd5\x8c\xa5\x3e\x24\xb0\x6c\x50\x96\x94\xee\xa6\xbc\xcc\x7c\x68\xc6\xad\x02\x9c\x85\x62\x34\x68\x56\xc6\xeb\x44\xf3\x30\x89\x99\x5b\x27\x48\xaa\xdb\x31\x0b\xcd\x6e\x7d\x9a\x8b\x28\xe8\xda\x4f\x7d\x2c\xd8\x3e\xc8\xec\x32\xd4\x5c\x5a\x40\x05\x52\x0f\x23\x57\xc0\xb6\x69\x17\xce\xa1\x7b\x65\xdc\x04\x2a\xee\xc5\xa1\x27\xb6\x48\xa7\x01\x20\x04\xd1\x56\xfe\xea\x6b\x91\xe5\xef\x9b\x32\x9b\xfc\x4c\x1a\x5a\x5e\xec\xfb\xc5\x9f\xfb\xeb\xc5\xfa\xee\x2f\xc7\x0c\xb0\x7c\xdc\xae\x6f\x1f\xf6\xdb\xa7\xd5\x83\x6f\x42\xd0\x69\x92\x20\xa3\x82\x67\xb4\xb1\x35\xa1\x33\x52\x11\xcd\x1a\x1c\x2d\x74\x80\x94\x57\xc7\xbe\xa6\xa3\x05\x58\x75\xf7\xdd\xfa\x7e\xb5\xdf\x3d\xee\xbf\x2c\x76\xcb\x2f\xfb\x70\xfb\xd0\x37\xc4\x6a\xa9\x0d\xb5\xc4\xc2\xd9\x51\xf4\x93\x44\x11\x8a\x04\xe2\x8b\xac\xba\xae\xca\xd3\x93\x78\xbf\xca\x9a\x7a\x13\x4d\xd3\xd6\x5a\xc5\x04\xc3\x48\x99\xe9\x7a\x9f\x1d\x8a\xb2\x02\xbd\x1f\xb6\x1d\x69\x25\x42\x6d\x33\xe3\xe5\xa9\xac\x5d\xb1\xf6\x13\x4e\x57\xaa\x75\x12\x60\xae\xe4\x1a\xfd\xe9\xac\xe8\x8d\xca\x47\x4b\xf3\xb7\xc2\x41\xad\x13\x8d\xf2\xa8\x98\x58\x15\x1f\xb1\x21\xfd\x02\xc4\xfa\xd1\x3d\x73\x5b\xd3\x5d\xbe\x1f\x3a\xa1\x14\xaa\xb5\x32\x18\x80\xa2\x52\x91\x6a\xd7\xea\x30\x12\xd0\x5a\xdb\x52\xfa\x4d\x59\x41\x76\x28\xae\xaa\x4c\x1f\x2e\x26\x75\xf7\xaa\x21\xb4\xdb\x45\x5d\xe6\x7a\xad\x41\xf4\x49\x56\x0d\x09\x0b\x52\xd7\x28\xb6\x3f\xd9\x82\x89\x87\xaa\x8d\xdf\x01\x80\x33\x4d\x83\x02\x9f\x9d\xb7\x1d\xb6\x43\x1b\x4a\x31\x65\x6b\x89\xfd\x5a\x67\x77\xb6\x30\x6a\x47\x43\x10\x04\xf8\x56\x8f\x45\x33\xa2\x3f\x80\x80\xd8\x7e\xbd\x3b\x51\x7e\x39\x67\x5f\xce\xd9\x67\xc9\x3b\x08\x62\x0b\x04\x6b\x57\xde\x17\x51\xe9\xee\x2a\x8e\x71\x75\x95\x67\x87\xa3\xe8\xa6\xc2\xa4\xa4\x04\x81\x4a\x91\xbc\x1f\xb3\x34\xbb\x41\x8f\xfc\x8f\xac\x79\xde\x74\x48\xe3\x8f\x3e\xee\xf8\x56\xb4\x42\x46\x04\x8b\x48\xf5\x17\x73\x58\x31\x37\x26\x54\x21\xb3\xdc\x96\x80\x55\xf8\xc7\x62\xa8\x93\x47\x81\x88\x14\x29\x61\xf6\xb6\xd5\xa6\xfd\x66\xfe\x54\xa2\x43\x84\x16\x9f\xaa\xf2\x58\x62\xf9\xe5\xd1\x7c\x29\xa7\x75\x4d\x20\xc0\x8d\xef\xd0\x46\xe7\xe3\x6a\x0a\xa0\xff\xc7\xe4\x04\x63\x94\x85\x54\x35\x50\x1d\xb3\x02\x9e\xd6\xde\xa0\x40\x1c\x52\xfc\x48\xee\x8c\x5b\x91\x4d\xe8\x68\x29\x24\x49\x8c\x41\x52\xdf\x88\x33\xa1\x0b\x18\x4d\x78\xa0\x3c\x40\x67\xfb\x1a\x7a\xed\x95\xc9\x15\x29\x07\xec\xad\xb3\x21\x7a\xcf\x20\xf3\xa9\xe6\x15\x05\x2a\x24\x9a\x6f\x0f\x03\x5f\x8a\x42\xbf\x8f\xd2\x3f\x97\x81\x38\x50\xc9\xf1\x24\x5b\x91\xe9\xa6\x05\x0b\x6d\x4b\x6a\x05\xea\x59\x54\x87\x09\x16\x01\x78\x68\x39\x8f\x2a\xdf\x51\xe3\x32\x90\x88\xad\xf5\x63\x64\x8c\xf0\x42\x97\x68\x40\x98\x5a\xa1\x91\x00\x62\x3a\x9b\x86\x13\x20\x8d\xa9\xb6\xd4\x31\x48\xef\xfd\xf4\x2c\x2a\x51\x3e\xf7\xb1\x1f\xa4\x69\x8c\xd8\x61\x84\x9d\x7b\x69\xad\xee\xa0\x02\x2c\x14\x3f\xfc\xf3\x7a\xbf\xbc\x5b\x2d\x36\xdd\x01\x63\xb0\x01\xd9\xee\x0b\xd8\xca\x39\xa4\xe2\x98\xdd\xe1\x40\x90\x00\x5b\xd0\xf7\x3d\xa3\xee\x2f\x41\xb4\x93\x2b\x68\x6e\x29\x0c\x71\x4a\x5c\x9d\xab\xce\xbe\x83\x80\x00\xf3\xf9\x79\x76\xcc\x9a\x8e\x42\x9a\x82\xf4\xc4\x3f\x8d\x38\x40\x74\x05\x87\xac\x18\xb4\x2a\x81\x26\x96\xb5\xd8\x02\x51\xb3\xa2\x79\x2a\xbb\xd9\xaa\x79\x9a\x06\x5e\x57\x79\x38\x07\xbb\xe3\xe0\xc5\x71\x5d\xc4\x6d\xe1\x83\xdd\xea\xd4\x82\x60\x77\x3c\x2e\xbe\x7f\xee\xbe\xa2\xd4\xb6\x75\x45\xba\x31\xc0\x82\xb0\x43\x1a\x0d\xff\x6c\xc9\x5c\xee\xb2\xe2\x45\xc8\x8f\x1c\x59\x00\x90\x98\x85\xc9\x3c\xc5\x70\x76\x84\x2b\xbf\x7d\x9a\x20\x64\x60\xc9\x2c\xf5\x63\x75\x98\x22\x56\x4d\x40\x84\x10\xbe\x91\xc3\x11\x73\xce\xd8\x44\x13\x24\x09\xb3\x2a\x7c\x35\x54\x8d\xa8\xee\xa1\xa8\xc5\x7f\x2e\xf0\x54\xe3\x73\x28\x43\xac\xdc\xfd\xf7\xa7\xa1\x35\x36\x44\x70\x2c\x59\x42\xa1\x91\x17\xa2\xe7\x38\x1b\xa2\x62\x4c\xcc\x62\xee\x5c\xb7\x2f\x59\xdd\x94\x55\xa6\xbc\xb6\xc8\xe8\x1b\x98\x98\x47\xc2\x32\x84\x57\x07\x58\x8a\x13\x42\x1e\xbb\xab\x70\x4e\x69\x47\xed\xf1\xf8\xda\x4b\x3c\xfa\x01\x20\xd1\x3c\x96\xfb\xd6\x50\x55\x42\x4f\xe8\x5f\xa9\x49\x62\xdb\xb4\x5d\x0e\x37\xe9\x7f\x45\xfd\xca\x8f\xff\xed\x47\xca\xa0\xd7\xda\x75\xbb\xda\xe5\xe5\x74\x1a\x7a\xd9\x5f\x7b\xad\x3e\x31\xef\x86\xd0\xd0\x36\x29\xfa\x6a\x6a\x05\xba\x03\x48\xfb\x21\x34\x16\x1d\xb4\xb2\xd3\x82\xbd\xc9\xcb\xb7\xba\x1b\xa2\xad\xd4\x8e\x2b\xa2\x0c\x5d\x6b\x43\x4d\x14\xd2\xae\xca\xf8\x04\xd5\xee\xe7\xe4\x36\x59\x40\x5c\x37\x8b\x0b\xde\xca\xf2\xf8\x90\x1d\x9e\xc7\x3c\x08\xbf\x6c\x8a\x18\xbf\x6c\xce\x25\xe2\x31\x10\x11\x54\x56\x15\xa8\x66\x4a\xba\xe3\x46\xa6\x3c\xd4\xae\x23\x68\x57\x4d\x1b\x37\x4c\xaa\x01\x59\x87\xcc\xb9\x8d\xc9\x56\x3f\x4f\xa2\xa8\x07\x8d\x47\x46\x68\x4b\x83\x66\x40\x3d\x2f\xf2\x7c\x7b\x3e\x3e\x9c\x8f\x37\x65\xb5\x2a\x54\x79\xae\xc4\x61\x3a\x85\x84\x61\x98\x16\x73\x38\x8f\x76\x3b\xb4\xac\xf0\xe3\x61\x2a\x92\xd8\xf6\xb4\x58\xae\x56\xff\x3d\x67\x1e\x3c\x3d\x5f\xe5\x1d\xd4\xe4\x8c\x8e\x6c\xd3\xb3\xed\xf2\x58\x1f\xe5\x44\xb8\xef\xb3\xf8\xce\x68\x80\x84\xba\x7e\x9d\x4f\x76\x5d\x03\x24\xc4\x35\xea\x9b\x03\x8b\xac\x79\xff\xb6\xb9\x1b\x45\x7a\x06\x58\x94\x52\x4f\xba\x87\x40\xaa\xcb\x2e\x86\x11\xa0\xa6\x4f\x7b\x19\x43\x04\x22\xc4\x56\xcd\xf3\xbd\xa8\x7c\x4b\xae\x31\x71\x80\x85\x7a\xa7\xce\x56\xaa\xa9\xd9\x67\x41\x90\x18\xb4\x51\xfd\x8e\xbe\x2e\x2c\xed\xcd\xaf\x26\x92\xbb\x40\x48\x19\xf6\xe6\xee\xed\x1b\xf4\x40\x30\x5f\x29\x99\x8b\x44\x58\x10\x85\x2a\x85\xae\x84\xf9\x84\x8f\x3c\x4d\xef\xf9\xa1\xb1\x4c\x79\x47\x3d\xf5\xe5\x5d\x56\x99\x9e\x63\x14\x62\x41\xc4\x48\x64\x3b\xa7\xaf\xca\xba\xfe\x21\x8a\x42\x2c\xdb\xc5\x35\x74\x02\x59\x10\x71\x83\xaf\xd9\xb1\xef\xdf\x81\xf1\xac\xec\x7e\x80\x26\xe8\x7a\x7d\x2b\x3c\xc4\xf5\xd7\x0c\x08\x1f\xbc\x1b\x42\x58\x14\xba\x95\x5a\x67\x35\xc2\x83\xfd\x21\x4e\x30\x4b\xda\x88\x17\x40\x60\xe9\xf6\x39\x3b\x4d\x1e\x28\xa6\xa1\x53\xa8\x2c\xf4\xa2\xbe\xcd\xcc\x7c\x45\x98\x05\x31\xb3\xf8\x09\x2f\x84\xfa\xad\xca\x9f\x2a\x30\xd9\x4f\xff\x6b\x31\x04\xb1\xe8\x66\x79\x56\x1c\x6c\x7a\xbb\x7e\x34\x57\xd0\x69\x0b\xfe\x63\xac\x31\xc8\x9d\xdf\xc4\x82\xd8\x30\xcc\x28\xe7\xa5\x7a\xe9\x59\x1d\x58\x90\x08\xcb\xdd\xde\x7a\x9f\xd0\x7e\xef\x42\x67\x93\xe2\x18\x0b\x12\x08\x85\xf7\xd4\xde\x3e\xed\x8e\xeb\x95\x06\xff\x31\x9e\x02\x2c\xb4\x1c\xde\xb6\xab\xc2\x62\x59\xe7\xb4\x02\x59\xc0\x52\x82\xb9\x9c\x2d\x54\xa7\x0e\x91\xc7\x02\x26\x05\x74\xf5\x92\x53\xfb\x08\xdd\xd7\xe6\xa0\xbd\x30\xda\xd3\xda\x52\xbe\x84\x89\x3f\x98\x86\x0a\x33\x8c\xeb\x87\xf5\x6e\xbd\xb8\xdb\x6f\x77\x8b\xdb\x55\x77\x90\x71\x4c\x44\x7d\x2b\x32\x55\x56\xc5\x95\x43\x51\x4d\xa6\x6f\xca\x0c\x6e\x51\x79\x56\xbc\xcc\x39\x5e\x2c\x48\x39\x60\x4d\x5e\x83\x2a\xb5\x8d\x37\xad\x9e\x64\xa1\xd7\xf5\x94\x35\x84\x05\xa9\x62\x92\x7b\xd5\xce\x6d\x03\x27\xe6\x6f\x48\x44\x76\xe3\xd9\x3c\xde\xad\xf6\x0f\xab\xd5\xf5\xfe\xee\x71\xf9\x75\xff\xed\xa9\x1b\x40\x0c\xea\xb6\x20\xc9\xfc\x17\xd1\xbd\x1e\x91\x46\xc8\x8f\x7b\x8b\x9b\x63\x0d\xc5\x65\x1f\x24\x0b\x84\xb6\x75\xd6\x0c\xf5\x45\x9b\xf7\x7d\xbb\xf1\x77\x60\x23\x16\x48\xa9\x2c\x54\xee\x98\x35\x1b\xcc\x56\x5f\xb8\xf0\xe3\xe7\x56\x2a\x41\x48\x47\x7b\x1d\x78\x12\x75\xfd\x56\x76\x7d\x19\x7e\x88\x16\x88\x44\x79\x16\xf5\xf3\x95\x50\x2f\x0d\xd4\xcd\x53\xeb\x9b\x67\x5e\xa1\xcf\xb2\x40\xd1\xb8\x9b\xab\x0a\x0c\x56\x05\x7f\x88\x5c\x1c\x45\x0f\x71\x60\x81\x0e\x29\x46\xb5\xa2\xa8\xdf\xb0\xc0\x32\x22\xd7\xed\xdd\x72\x16\x68\xcd\xa5\x15\x46\x2d\xd5\xb9\x82\x19\x61\x0e\x16\x00\xb7\xc9\x0f\x5b\x07\xc1\xf2\x44\xc7\xa4\xc7\x02\x30\xa9\x17\x36\xf5\xb3\x8a\x90\xf1\xb3\x99\xc4\x26\x5e\xe4\xf9\x7d\xd9\x86\xb2\xe3\xb7\x6d\x84\x41\xef\x76\x55\xe8\xd6\xef\x6d\xe7\xd5\x64\x00\x50\xcc\xff\x5a\xbe\x1a\x98\xa0\x22\xc6\xaf\x3a\x0c\xa2\x14\x42\xdf\x3c\x5c\xbc\xb8\x67\xaf\xe7\x20\xc9\xed\x60\x8d\xb5\xe3\x7d\xfb\x85\x4f\x03\x8a\x07\x16\x06\xc2\xfa\x73\x47\xe4\xc8\x3b\xe5\x42\xc1\x5e\xf5\xb2\x2b\x6e\x54\x18\x04\xd8\x0a\x8f\x18\xf8\x6d\x76\xf0\x71\xcb\x40\x16\x6f\xfc\x8b\x51\x20\x11\x2a\x82\x6b\xc4\x15\x5f\xcf\x03\xc0\xd7\xd0\x79\x6d\x47\x6b\xe6\xad\xe2\x2c\xc5\xef\xef\x19\xe7\x30\x32\x04\xbf\x32\x42\x55\xbd\x22\x04\x0b\x09\x31\x89\x4b\x0c\xba\x7b\xd9\x8e\x3f\x7d\x48\x04\xc5\x74\xd6\xb1\x44\x1c\x43\x69\xbb\x51\xe6\x7f\x84\x08\xe1\xf5\x84\x56\x85\xee\x55\x72\x06\x23\x64\x88\xfd\x8d\x59\xbd\x15\x47\xd8\x66\x87\xe2\x8f\xcb\x6a\x51\x3b\x4c\x77\x2d\xcc\xf8\xf6\xa1\xda\x74\x40\x7a\x16\xc6\x44\x61\xf3\x6d\x51\x36\x78\x19\x00\x3d\x13\x2d\xb0\x30\x8e\x23\xda\x73\x18\xfb\xb6\xda\x7d\x59\xe4\xef\xfb\x6b\xf8\xb0\x98\x3b\xe9\x93\xfa\xf4\x30\x1f\xf8\x57\x2c\x4c\x08\x0f\xad\x3c\xd5\x1b\x54\x0e\x59\x31\x7e\x01\x49\x62\x65\x9d\x45\x9e\x5b\xa9\xc7\x3e\x02\x64\x21\x4d\x23\x69\x29\x40\x51\x11\xc5\x0b\xd5\xb3\x90\x4a\x2b\xbd\x2b\x74\x79\x6a\x66\x38\x5c\x58\xc8\x22\x16\x62\xb3\x74\x79\xae\x61\xd2\x57\xc9\x42\xc6\x23\x62\x21\x35\xd7\x70\xaa\x00\xdb\xcb\xba\x63\x90\x62\x4b\xd9\x6b\x99\xe9\xc7\x6a\x03\xa8\x39\x3c\xbe\x69\x2e\x23\xd4\x56\xbd\xc9\xcb\xb2\x13\x43\x1b\x4f\x13\x2e\x23\xec\xf9\xf9\xeb\x5c\x5c\xa2\xec\x58\xc8\xb5\x8d\x48\xf6\x35\x34\x37\x15\xc0\xdf\xa0\xa7\xa2\xd1\xf3\x53\x2a\x8d\x14\xee\x3b\x88\x89\xb0\xed\x14\x3f\x44\xbd\x81\x8e\x5d\xba\x1d\x02\x5e\xc5\x1f\x65\xc8\xc7\xbf\x9c\x92\x18\xe5\x16\x6a\x61\x00\x83\xde\xc9\xb3\x09\x26\xb0\x29\xa3\x77\x09\xf5\xb8\xc1\xf5\x1a\xea\x26\x2b\xd0\x05\xab\xef\x7c\xf4\xc8\x42\xa1\x39\xb6\xb5\xbf\xc2\x73\x05\xf5\xa9\x2c\x2e\xb9\x7d\xba\x24\x88\x77\x5d\x59\x28\x13\x4e\xa4\xc7\x79\x78\xab\xec\x8f\x89\x30\x08\xba\xea\xe7\x47\x9a\xda\xe3\xa7\x93\x00\x88\x90\x7f\xbc\xb7\x42\x5f\xc8\xa7\xf2\xc1\x50\xc3\xa5\xe8\x9b\x75\x32\xa8\x1e\xcd\x80\x27\x98\x85\x2a\x90\x68\xe4\x91\x8d\x7d\x20\xac\xd9\x3a\x24\x06\x29\xb9\x64\x2e\xd4\xcb\x1d\xc2\xd7\x8f\x27\x51\x74\x2c\x70\x2c\x54\x3c\xc5\x80\xea\x0d\xe0\xe5\xa6\x3c\x57\x03\xfd\x00\x16\x2a\x19\xa0\x8f\x29\xcf\x59\xae\x77\xd9\x6c\x93\xb6\x57\xca\xeb\x4e\xb1\xb2\x02\x9e\xd0\xe4\x13\x90\x0a\x0b\xb5\x50\x4a\xfa\x4c\xa7\x7f\x6f\xfe\x98\x96\x8e\xad\x1d\xd1\x2e\x13\xff\x38\x84\x98\x6b\x17\x7f\x3e\x9e\x1b\x55\x1e\x61\xda\xb8\xed\xf7\xda\x10\x38\x43\x1e\xc4\xef\xab\xed\x6e\xfd\x70\xbb\xbf\xfe\xb6\x59\xec\xd6\x8f\x0f\xfb\xe8\xaf\xee\x6a\x60\x90\x30\x48\xb4\x0b\xff\xc6\x49\x76\x3c\x16\x70\xed\xf3\x00\x2c\x34\x3e\x74\xd3\xfa\xf1\x04\x85\x4d\xb8\x8f\x56\xb2\x21\x61\xe8\x08\x5a\x6e\x16\x57\x0b\xc7\xa2\x68\xe7\xe2\x0c\xc9\x0a\x0b\x4d\x1c\x25\xa4\x43\xe2\xcb\xf6\xbb\x7e\x2f\x9b\x49\x7d\x98\x45\x21\xb5\x5c\xc6\x1d\x30\x67\x5f\x9f\x40\x65\x22\xdf\x3f\x97\x55\x7d\x49\x49\x3f\xdb\xa1\xce\xa2\x50\x92\xd8\x73\x98\x88\xa6\xc9\x67\x4b\x48\xed\x30\xbb\x63\x63\xf6\xf1\x3b\x92\xb7\xcc\x73\xd2\x7e\xda\x71\x31\x91\xe3\x66\x51\xa8\x0c\x58\xb6\x0d\x6c\xda\x19\x7f\xec\x28\x34\x01\xb6\x4e\xa2\x94\xb2\x4f\xeb\xb9\x63\x11\x89\xf0\x58\xdf\xee\x7d\xef\xb9\x4f\xfc\x08\x08\x43\x9b\xa0\x76\xb1\xd9\x75\xf6\xfa\x39\xfb\x47\x7b\x8e\xe5\x8e\x6f\x5d\xaf\x3f\xfd\x85\x08\x17\xe8\x53\x00\x16\x02\x07\xf6\xc3\x0f\x88\x19\xc3\x8c\x1a\x76\x54\x17\x6b\x55\x76\x07\x38\xc5\xca\xd0\xb7\x02\x7e\x9e\x90\x31\xa2\x3b\x22\x94\xf4\xc4\x77\xd7\x99\x31\x99\x3a\xe7\x9e\x52\x9c\x45\x09\xd7\x36\x2d\x86\x94\x42\x1d\x78\xf1\x03\xc2\x1c\x16\x51\x15\x79\x46\x1b\xef\xb1\x45\xb1\xbf\x18\xd5\x80\x81\xce\x11\x5b\xae\x17\x55\x35\xa9\x50\xb2\x88\xb1\x30\x4c\x50\x54\xb6\x10\x5d\x8f\xc9\x47\x59\x07\x16\xb1\x94\xa3\x71\x38\x89\x77\x9f\x6d\xfe\xa0\x84\xe4\x4e\xe0\x01\xc1\xeb\x7f\x2b\xba\x16\xd2\xdd\x05\x33\xbb\x1f\x4b\x45\x14\x76\xf8\xd2\x11\xfb\xcb\x78\x60\x1a\xda\xee\x37\x0d\xb5\xaa\x32\x44\xfe\x7c\x11\xf5\xb3\xcd\xe9\x4d\x9f\x30\x15\x96\x31\xc6\xcf\x16\x74\x79\xcb\xf9\xa9\x2e\xda\xa9\x85\x5c\xf7\x50\xed\x71\x61\x85\xfe\x55\x8a\xd8\xb6\x8e\x5f\xdf\x8a\x23\x5c\x4a\xf6\x79\xdb\x12\xc9\x24\x64\x2e\xc7\x78\x5b\x95\xe7\x93\xb7\xab\x91\x4c\x00\x09\x49\x4f\x50\xb5\x91\xca\xc0\x09\x8a\x24\xd8\x72\xfb\x41\x60\x19\x79\xf9\xe0\x0f\xa8\x30\xc4\x46\xf2\xbb\xf2\xf0\x59\x55\x91\x45\x8a\x25\xac\xe7\xb9\xde\x63\xcc\x7a\x81\xcc\x98\xcc\x1c\x08\x13\x46\x5d\x17\xa2\x3d\xf0\x91\x96\x31\x8b\x20\x61\xca\xb3\x39\x40\x6b\xf8\x73\x7f\x8b\x40\x2d\x43\xfc\x69\x8f\x7c\x12\x66\x42\x22\x31\xb9\x4f\xe0\x12\x43\x3d\x64\x8c\xdf\x93\xee\x22\x29\xf8\x0e\x85\xd5\x01\x2a\x38\xcc\x7f\x1e\x13\x58\xe0\x86\x15\x9e\xde\x7f\xc9\x9a\xc7\x0a\x79\x43\x2f\xf1\xfd\x8c\x04\xc4\xea\x7c\x79\x0c\x65\x3d\x52\xf8\x62\x24\x88\x2d\x75\xad\x03\xed\x7a\xa6\x56\xce\xfd\x71\x29\x31\x86\xab\xd0\x4f\xc9\x7a\xfe\x5a\x46\x02\x6d\xd0\x43\xfa\x01\x6d\x40\x31\xc8\x44\x33\x12\xaa\x24\xb0\x34\xf3\x18\x1e\x8e\xfd\xfc\xd9\x25\x42\x42\x08\xa3\x9e\x99\xbe\xce\x07\x68\x10\x46\xa2\x20\x32\xed\x0b\xfb\xcf\xc9\xbd\x58\x71\x40\x4d\xb6\x8e\x50\x84\x91\x48\x47\x41\xd8\x03\x00\x07\x49\x59\x46\x48\x20\x0d\x1d\x37\x4f\xcf\xb4\xc2\x33\x12\x13\x96\x78\x10\x00\x20\x42\x72\xdd\xc0\xd1\x01\x53\x26\x43\x19\x47\x96\x24\x51\xbf\x17\xea\x02\xda\x36\xff\x88\xb1\x49\x31\x21\xe4\xe0\x0d\x9f\x2a\x33\x30\x42\x93\x14\x3b\xdf\x36\xf0\x73\x9c\x0d\x1d\xdf\x08\x85\x10\x8b\x2c\xf2\xf0\x73\xa8\xa5\xc5\x08\x63\x16\xcd\x7d\x55\x9e\xab\x02\x10\xf5\xff\x49\x55\x81\x11\x26\x99\xa2\x03\x54\xea\x2e\x53\x2f\x30\x51\x6c\x67\x84\x87\x09\xf2\x7e\xe3\x5e\x73\x1c\x71\x58\x4c\x88\x70\x18\xe1\x89\xb1\xa4\x8e\x55\x59\x9a\xb5\x9e\xec\xdf\x84\x0b\x4e\x68\x37\xf5\x56\x58\x91\xf3\x6b\x70\xac\x80\x36\x9c\xd0\x69\x12\x26\x61\xaf\x97\x29\x7e\xfa\xd2\xb6\xe7\x38\x98\xfc\x4a\xca\xb5\x8e\x87\x02\x0b\x03\xa4\x2d\x23\x69\x6a\x79\xf9\x9e\x45\xed\xcb\x4c\x93\x07\x4e\x53\x26\x7b\xf4\xe7\x95\xa8\x9d\xe0\xdb\xa7\xdb\x28\x49\x35\xf1\x3e\xcf\x80\xee\xd3\xf6\x99\xce\x3c\x94\x88\x34\x26\x53\x74\x56\xa3\x61\x9c\x4d\xb4\x5d\x94\x44\x19\x11\x02\x7c\x29\x67\xef\xe0\xcf\xfe\xc9\x64\x68\x79\x4c\x3d\xfb\xf9\x7d\x56\x2c\x45\x9e\x4b\xa1\x5e\x6e\x45\xdd\x8d\x22\x81\xff\x44\xff\x01\xd5\xd4\xa3\x65\xa3\x22\x26\xd5\x88\x8a\x7c\xfc\x90\x2a\x12\x68\xaf\x7e\x54\x59\x03\x57\xd9\xaf\xc8\x8a\x46\xb3\x4d\xa5\x04\xf1\x5d\x36\x11\x78\x75\xae\x8a\xab\xb2\xb5\x12\x8f\x27\xa7\x48\x61\x31\xe3\x9f\xbf\x65\xdd\xde\xbf\xab\xf8\x60\x93\x47\xef\xc0\x13\x0d\x06\xe9\x14\x57\xbb\xe5\x17\xf7\x02\xfd\x21\x10\x84\xba\x12\xc8\x43\xe6\x72\xa2\xa3\x9b\x03\x65\x95\x14\x8e\x19\x0a\x63\xb8\x94\x55\xd7\x60\xc9\x88\x09\x54\x18\xba\x2c\xf4\x6d\x5e\xca\x9b\xb2\x40\x18\xcb\xe4\x05\x99\x28\x00\xe2\x71\xc7\xe2\x38\x7c\xb7\x46\x01\xfa\x7d\xcb\xbb\x07\x2b\x5d\x3a\xe8\x5a\x60\x71\xc0\xac\x24\x05\x46\x55\xe3\x09\x19\x07\x52\xa5\x0e\x77\x78\x57\x16\x87\x06\xaa\xe3\x7d\x56\x34\x1f\xd9\x91\x38\x0c\x02\x4c\x3d\x58\x80\x8a\x44\x17\xb7\x1e\x44\x33\x71\x18\x5a\x1e\xb4\x4e\xc5\x6b\x51\x34\x83\xc4\xe5\xf4\x72\x8c\x62\x80\x56\xe6\x7a\x15\x77\x97\xd0\x2c\xb0\xcd\xd1\x4d\x95\xc1\x2b\x60\x3b\x66\xdd\x1d\x05\xee\xd1\x57\xfb\x93\x6f\x0b\x99\xcd\x5e\xc5\xa1\x09\x8c\x15\xd7\x7d\xbf\x5a\xdf\xdd\xf9\x2b\x44\x81\xb0\xcf\xdc\xee\x26\x7f\x8c\x28\x61\xe7\x89\x0f\x86\xee\x5a\x1c\x11\x0b\x1c\x30\x28\xf5\xb6\xb1\x11\x58\xf7\xae\x23\x62\x1c\xf1\x79\xd5\xee\x53\x23\xf8\x00\x8b\x23\x4a\x31\xcd\xf4\x45\x14\x7f\x8d\x54\xd5\x59\x1c\x49\xab\x5f\xf0\xfd\xdb\x93\xc3\x79\x39\xaa\x83\xdd\x7a\xb5\xf1\x1e\x53\x4c\x82\x14\x57\xd8\xf0\x8d\xfe\x9f\xca\x10\x48\xcf\x8b\x65\xf4\x2a\xcb\xf3\xac\x2c\xb2\x9f\xf3\xae\x4c\x4c\x42\x93\xf4\x7a\xe1\xab\xdd\x9f\xb3\xfe\x43\x4c\x92\x08\xbd\x8f\x9b\x2c\x87\x2d\x54\xaf\x50\x59\xb7\xb7\xea\x6e\x99\x05\xd8\x3e\xfc\xe9\xb6\x16\xf3\x61\xd2\x35\x8e\xe3\x08\xf1\x80\xde\xbf\x7c\x80\x9f\xd9\xf9\x38\xfd\xe9\x38\x51\x5e\xf5\xe8\x49\xd4\xf5\xa9\xac\x9a\xf5\x07\x2e\x7d\x1c\xd3\xc4\x83\x0b\xaa\x0e\xee\xc1\xe2\x24\xb5\x6b\xea\xae\x3c\xf4\xaa\x49\x1f\x4c\xfd\x44\x09\x64\x02\xf2\xf1\xcf\xd5\x80\x41\x7f\x3e\xff\x10\x27\x5a\x60\x20\x81\x0a\x22\xde\x59\xb0\x6d\x73\xe3\xc5\x1d\xd3\x18\xb0\x25\xad\x7e\x2e\xdf\x2c\x00\xf7\x07\x76\xf5\x77\xd3\x9e\x0a\xcb\x0b\xdd\x0e\xb8\xd4\x9f\x9a\xdc\x2a\x95\x11\x0a\xa9\x3e\x6d\x97\xa3\x49\x46\x15\x37\x9e\x24\xc3\xba\xb3\x5b\x54\x66\x9a\xbc\x58\x06\x06\xbd\xd8\x85\xcc\xd0\xdb\x9a\x3a\xe4\x31\x33\x21\xb2\xe6\xd9\xb2\x76\x6b\x8f\xaa\x65\x99\xb7\xab\xbd\x12\x79\x56\x0f\xa3\xb9\x98\x07\x04\x41\xab\xfb\x0c\xf5\xda\x2c\xfd\xe8\x18\xca\x3d\x0a\xa1\x63\x9e\xc6\x71\x67\xae\x86\x0a\x2c\xe3\x67\xe4\x32\xc1\x48\xfb\x09\xa0\xb2\xbe\x4a\x3d\x95\x93\x67\xb1\x88\xe2\xd8\x29\xca\xb6\xa1\xdf\x02\xd3\xfd\x48\x0a\x31\xd3\x22\xe9\xcf\xa1\x69\xa0\x7c\x51\x65\x9f\x15\xfb\x37\x8f\x9b\x63\xb1\xe0\x11\x73\x3b\xf1\x7d\x59\xd4\x0d\x54\xc8\x9c\x70\xc1\x02\x30\x99\x07\x22\xa5\xe0\xb2\x02\x5f\x6e\x77\x93\xb7\x2d\x24\xc4\xc4\x13\x52\xda\x2c\xc0\xd0\xab\x88\x65\x08\xe8\x8b\xe2\xd4\x75\x25\xd5\x41\x5a\x34\x96\x89\xc0\x9c\x69\x79\x82\x22\x59\x3e\xf7\x29\xb3\x58\x45\x89\xa3\x08\xd0\x5b\x61\x20\xff\xc8\x0a\x2b\x9e\x60\x2d\x28\x6b\x7f\x38\xd3\xbf\x5c\x09\x4a\x58\x06\x8d\x73\x81\x58\xa4\x41\x63\xc5\xe4\xb9\x15\x30\x5c\x75\xbb\xd5\x76\x87\xff\x7f\x99\xfb\x8c\x21\x0d\x30\x83\xae\x2e\x7b\x98\x2f\xef\xd4\xa8\x00\xf3\xfd\x87\x33\x32\x82\x4c\x0e\x6a\x81\x35\xdf\x7d\x9f\xac\x74\xd4\x99\xf5\x25\x09\x06\x4b\x02\x6a\x9f\x62\x7f\xb2\xc5\xf0\xed\x2f\x4b\xd5\x49\xc0\x41\xb1\x3e\x9a\x46\x72\xf8\x4f\xf3\x41\x49\x90\x12\x8e\xc5\xed\xe7\xcc\x34\x4a\xd4\xcf\xc3\xe9\x99\x04\x8a\xa0\xd1\xf7\xc8\xb5\xd5\x90\x9d\xb9\x3d\x2c\x59\xea\xb1\x35\x87\xf6\xcb\x5e\x65\x5a\x4f\x57\x42\x12\x68\x83\x9d\x46\xb6\x80\x3e\xa5\x58\x74\x83\x42\xaa\xb1\x2c\xbc\x5c\xef\xfe\xda\xaf\x1f\x96\x9b\xd5\x62\xbb\xda\x6f\x16\x3b\x5f\xc3\x4c\x42\x08\x90\xa9\x17\xdb\x00\xfb\xfa\x55\x12\xb1\x18\xd1\x8d\x08\x1c\xb0\x0d\x7a\x96\x27\x66\xea\xdd\x26\x91\x48\x53\x2b\xe6\x5a\x80\x53\x19\xa9\xca\x63\xf9\xcb\xfe\x7d\x96\x44\xc6\x56\x46\xd1\xa0\x7c\xb3\x3d\x04\x3e\xb9\x93\x10\x4a\x30\xef\x7f\xb5\xba\x5d\x3f\xec\x77\xeb\xfb\xee\x96\xe3\xc8\x20\xb3\xe4\xed\x72\x64\xe7\x92\x76\x9e\x38\xe6\x4b\x4c\x18\x7c\x6e\x2e\x93\x24\x8c\x11\x75\xeb\x45\x4f\x4f\xb6\xa6\xf8\x09\xe6\x93\x25\x49\xaa\x91\x82\xd9\x1d\xdc\x95\xd8\xb7\x33\xf9\x32\x8c\x00\x8f\x06\xfc\x58\xdb\xe6\xac\xa7\x10\x5b\x96\xb0\x98\x3b\xea\x9a\xe3\xf1\x5c\x64\xcd\xfb\x28\xf4\x4a\x18\x05\x6e\x50\x6d\xe3\x6a\xf4\x90\x8c\x02\xc6\x22\x26\x2b\x84\xf5\xc9\x9d\x5a\xc5\xbc\x11\x4a\x18\x8f\x2c\xf9\x49\x6b\x47\x06\xef\x64\x3c\x8a\x53\x85\xe6\xda\xaa\xff\x7e\xdb\xae\x36\xfb\xe5\xb7\x9d\xff\x4d\x2e\x39\x26\x01\xc5\xb9\xc6\x17\x3b\x55\xaf\x61\x49\x1a\x44\xd8\x4a\x9c\xbd\x35\xe6\x5c\xe8\x21\x2b\x2d\x4b\xd2\x50\x93\x8e\x07\xf2\xf6\xdc\x7b\xd1\x49\x4a\x0c\x1a\xb9\xed\xd7\x3b\x5f\xbe\x74\x47\x84\x34\x51\xec\x95\xf0\x7f\xf1\x21\xa5\x8a\x8d\xf4\x78\xa9\xd6\x8d\x2d\x44\xa1\x00\xb3\xfe\x7d\x7c\x94\x48\x45\x91\xf4\xfc\x5b\x91\xbd\xb6\xf1\xd1\xf6\x39\x83\x7c\x9e\x0a\xc6\x9d\xa1\x53\x1d\x59\x83\x97\x97\xea\x65\x4c\x00\xc8\x12\xe0\x3a\x49\x3c\xf9\xa7\xca\x4e\x19\x14\xcd\x16\xe7\xca\x28\x10\x48\x8c\x64\x58\x41\x58\x55\x95\xef\x1a\xf4\x47\x54\x84\xb8\x19\x53\x01\x0c\xa8\xdc\x18\x0d\x02\xfb\x35\x0e\x1d\xf1\xd8\x06\x5a\x3f\xa7\x67\x38\xf1\x03\x23\x82\x25\x30\x0d\xa7\xbc\x7c\x1f\xfd\x2e\x0d\xe3\x18\xbb\x67\xef\x17\x7f\xee\x97\x9b\xc7\x1f\xd7\xfb\x9b\x6f\x0f\xd7\xeb\x87\xdb\xfd\x6a\xf7\xc5\x5f\x20\x14\xb6\x1b\xb7\xc2\x0a\xd7\x0d\xc0\xd2\x3b\xf0\xfa\x26\x17\x87\xc1\xfb\xa3\x51\x12\x33\x3d\xa0\x2d\x77\xe4\x41\xc3\x68\x8f\x46\x2a\xc6\xbe\x9d\x23\x72\x8c\x8e\x27\x3c\x8d\xb4\x65\xfa\xea\x62\x84\x8d\x23\x41\x18\xa1\xb9\xc6\xdf\x96\x46\xae\x8d\x19\xd9\xc1\xab\x0a\xe9\x34\xc7\x97\x25\x71\x80\xe9\x44\x28\xf4\xa9\x82\xb5\x2a\x87\x37\x4d\x20\x11\x2e\xf2\xee\x60\x00\x34\x8e\xed\x76\xde\xfb\x43\x9f\x52\xbd\x30\x1a\xeb\x18\x1b\x3b\xbc\x63\xda\xe9\xfd\x0c\x57\x26\x8d\x01\x90\x20\xe1\xfb\xfa\xc7\xe3\x3f\xfd\x1f\x13\x6a\x28\xf4\xdb\x38\x46\xc8\xdd\x31\x0d\xc6\x35\xd3\x5e\x41\x01\x26\x53\x99\xa8\x26\x1c\x03\xde\x92\x53\x4a\xad\x30\xb0\xf7\x43\x6d\xd9\xee\xd3\x64\x11\xa5\x29\xc1\xc4\x5c\xbb\x24\x3d\x86\xe0\x83\x91\x0a\x82\xc8\x51\xf1\x09\xd5\x09\xe7\xec\xca\x8b\x34\xe6\xe4\xd5\xf0\xc0\x3a\x11\x87\x5c\xf8\xc7\xe2\x22\x56\xba\x6f\x0a\xdb\xbe\x0d\xb8\x93\xbb\x21\x2a\x08\xbd\xe1\xb7\xe0\x00\x78\xf3\xe7\x8b\x58\xe2\x72\xae\x20\x17\xef\x1b\x50\x90\xbd\xba\x8e\x59\x71\x89\xa5\x9e\x01\x6f\x50\xc1\x9c\x82\x4d\xd6\xd4\xbd\xee\x03\xa3\x92\x13\x6e\xfb\xf8\xf3\x97\xad\xa7\xac\xe7\xff\xfa\xb7\x3d\xd9\x83\x9e\x48\x34\xf8\x87\x3b\x53\x85\x52\x38\xcd\x70\x05\x57\xf0\x61\x4e\xe1\x23\x84\xe5\x3f\x46\x9d\x11\xfe\xa2\x94\x6b\x2b\x43\x91\xab\x5d\xa9\x3e\x37\x72\x54\xa5\xb6\x6c\x0f\xcd\xf3\xf7\xde\xd9\xa3\x3a\xb0\xe9\x46\x93\x89\xa6\xf5\xea\x3f\xf7\xa4\xa8\x06\x82\x8c\xc5\xb6\x14\x39\x93\xc2\xa3\xda\xc4\x9e\xd9\x67\x51\x1d\xdf\x2f\x05\x40\x19\x05\x66\x48\xd4\x77\x09\xec\xca\x27\x64\xf7\x5c\x4f\xbf\xb2\x09\x34\x6e\x1b\xcb\x47\xef\x03\xfa\x03\x3c\x40\xf5\x0c\x07\x34\x5f\x8a\x53\x1b\x20\x8c\x4d\xf1\xf0\xfe\xbb\xba\xfe\x67\xff\xb1\xd7\x66\x51\xc8\x10\xfd\xf3\x54\x95\xf5\x69\xa4\x61\xc9\x58\x94\xc4\x5e\xfd\xba\xeb\x46\xb8\x9f\x55\x0f\x63\x2c\x12\x06\xb7\x67\x59\x76\xe6\x96\x11\x2a\x90\x49\xe8\x2d\x2b\x74\xf9\xf6\x78\x1a\x01\x15\x58\x12\x33\x34\x55\x47\xf1\xb3\xfd\x33\x82\x28\x5f\x45\xfe\xe5\xca\x0f\xa0\x81\x0c\xdd\xab\xcd\xe1\x15\xf2\xf1\xeb\x62\x94\x50\x64\xe5\x7b\x12\xe7\xda\x02\x02\x17\xfa\x98\x15\x03\x73\xc6\x28\x8f\xb1\x8b\x7d\x99\x67\x27\x2f\xb1\xfe\x49\x3e\x96\x51\xa5\x50\xaa\xe0\x66\xb3\x5a\x5d\x3f\xde\x0f\xb0\x50\x8c\x25\x41\xe8\xc9\x52\x73\xf1\x0a\x73\x55\x54\xc6\xc3\x00\xdd\x9d\xa7\x0e\xb5\xc8\x78\x1c\x59\xe8\x8b\xf7\x3b\xec\x0e\xd5\x4c\xdd\x42\xc6\x69\x84\x0c\x05\x57\x59\x23\x8a\xfa\x5c\x76\x17\x10\x31\x96\x8c\x75\xf9\xd4\x91\xeb\xce\x59\xa6\x11\xf8\x85\xa5\x9c\x23\x44\xce\x46\x4a\x2e\x4f\x39\xdf\xe5\xc6\x98\x08\xac\x98\xeb\xcf\x29\xa9\x26\x63\x22\xa4\x60\xb3\x4c\xf5\xf9\xd8\x35\xed\x74\x5f\x58\x40\x2a\x4d\x27\x7b\x2d\xfe\xfe\xbc\x26\xc7\xa4\xe6\xd8\x95\x28\x30\x7f\x8c\x9f\x6b\x57\x76\x4f\x2a\xb5\x4d\x1f\xca\xac\xf8\xcc\xcf\x60\x2a\xb0\x5a\x95\x6d\x28\xf7\x00\x6f\x57\xf0\x8b\x78\x88\x69\xe7\x37\xd7\xcf\x55\x76\x3c\xbd\x57\xe2\xe8\x69\x00\x19\x83\x76\xe7\x1f\xa4\xe0\x3d\xf4\x6a\x31\x4c\x1d\x32\x30\xa9\xe4\x1d\xc4\x09\xea\xba\x93\x4a\x1b\xdf\x9a\x49\xac\xce\x4d\x47\x1d\x96\x15\xe7\x7a\x59\x1e\xb3\xba\x9e\x63\x1b\x1a\xdf\xa6\x81\x18\x71\x04\x9e\x30\x3e\xab\xb3\xe2\x30\x4a\x52\xf2\x50\x33\x64\xd7\x1c\xe6\x0d\x3b\xd3\xdc\x5d\x89\x87\x26\x65\x72\x44\xaa\xb5\xac\x84\x1c\x02\x35\x78\x94\x28\x64\x50\x7b\xaa\xce\x20\x45\x9e\x75\x24\x91\x8c\x47\xc6\x32\x47\x1d\x50\x73\xa0\x12\x13\x14\x89\x1b\x45\xb4\x05\x24\x9f\xce\x79\x3e\x93\xab\xe1\xc4\x48\x04\x13\x61\x5b\xe0\x3c\x05\x31\xe3\x31\x8d\xb9\x23\xbd\x5f\x6b\xac\x12\xaf\x1b\x38\x7e\x10\x53\xcc\xb1\xce\x32\x1e\x33\x6d\x89\xb9\x2d\x29\x71\x51\x94\xbf\x60\x52\x64\x3c\x61\x4e\xea\x1a\x55\x3a\xa7\xa9\x68\x4e\x05\xb5\xb2\x77\xae\xaf\xc7\x89\xd3\xfe\x2e\xe8\xc0\x5f\x05\x24\x76\x8c\xdc\x95\x87\xa7\x0a\x4e\xa2\x02\x2f\x6f\xf2\x01\x4d\xf2\xec\x64\xe7\x8c\x02\x9a\x14\x54\x14\x1a\x7e\x40\xc6\x8d\x70\x0d\xc5\xa8\x09\x9a\x35\xef\xc3\x2c\x94\x1b\xc5\xb9\x08\x3a\x15\xb7\xed\xf9\x04\x95\x55\xf2\x58\x1d\x0e\x7e\x11\xf3\x34\xb4\x04\x5f\xa6\xac\x9a\xe7\x1f\x00\x2f\x6d\x54\xb0\x5e\x3e\xa2\x9f\xb9\xaa\x9b\xec\xd8\x57\x8c\x79\xca\x62\xef\x6b\xef\x91\x56\x4f\x8b\x46\xec\x47\xa5\x43\x9e\xf2\x48\x27\x5d\x0f\x10\x5a\xf5\x65\x09\xa6\x75\xd8\xba\x3e\xb5\x68\xf2\xba\x52\xb0\x64\xcb\xd6\x34\xf4\xdc\x82\xe3\x4f\x23\x08\x41\x58\xe6\xb5\x65\x69\xb7\x05\x8b\x59\x5b\xd3\x7a\x55\x88\x82\xcf\x54\x39\x02\x22\x71\xc1\x35\xf6\x5b\x7c\x15\x95\x16\x45\x57\xcd\xe4\x42\x33\xe6\xca\xe4\xae\xdc\xd9\x1d\x31\x91\x61\xc3\xee\x4e\xb8\x7a\xc7\xce\xa8\x0b\x3f\x78\x7c\x0b\x32\x0a\x30\x47\xe6\xad\x81\x90\x39\x92\x57\x0d\x11\xa2\x5c\xd2\x10\x1b\x04\xd1\xb7\xbb\xcb\x6a\x84\x17\x76\x07\x75\x40\x03\xd7\x7f\x3c\x48\x38\xb9\xa3\x2a\x08\x09\x77\x02\xf9\xd8\x6e\xb4\xf7\xc1\xc6\x7e\x58\x6d\xe0\x8a\x08\xee\x72\x67\x4f\x15\xe8\x6c\xa8\x2c\xcb\xb8\xd2\x86\x7a\x56\x18\x2f\x60\xf7\x01\x9d\xab\xf7\x1a\xb8\x66\x56\x33\x66\xf9\xb8\x7e\x58\x2d\x47\xde\x0a\xd7\x3c\x46\xce\x9b\xa7\xdd\x72\xfc\x77\x45\x5d\x03\x62\xb3\x97\xe7\xf7\x65\x2f\x9e\xfe\x01\x49\x88\x3b\x0f\x42\x92\xba\x52\x86\xcf\x79\x7c\x26\x0e\xc8\xb8\x21\x60\x79\xf8\xdb\x77\x00\xfd\xb4\x34\xca\x46\x78\x59\xa1\xe1\x27\xe8\xab\xf7\x59\x7a\x6a\x3b\x38\x0d\x49\x48\x9d\xd6\xba\x63\xee\x19\xed\x08\x69\x28\x35\x42\x46\x16\xc5\x01\x86\xed\xc7\x2c\x0d\x95\xb2\xba\x04\x8f\xab\x39\x87\xe3\x32\xaf\x93\x86\x10\xe2\x16\x7f\xca\x05\xf6\xca\xc3\x63\x25\xd4\xb4\x19\x97\xa5\x51\x10\x61\x4b\x42\x93\x59\x24\xeb\x24\x8f\x92\x92\x98\x20\x66\x3f\xab\xb7\x7f\x3d\x20\xbf\x88\x3f\x93\xa4\x06\xc9\x24\x4a\xad\x6b\xcb\x5d\x35\x6b\xb3\xd2\x38\x20\x18\xde\x22\xcb\xda\xb9\x2a\x84\x02\xc4\xb5\x8f\xab\xa1\x5d\xbf\x03\x96\x45\xb1\xa6\x7a\x59\x27\x4d\xe3\x50\x04\xa9\x57\xc1\xc9\xe1\x20\x74\x79\x0d\xab\x5a\x9d\x21\x17\x17\xc2\x26\x17\x05\xa4\x34\x4e\xe2\x14\xfc\xe9\x75\x76\x28\x04\x82\x2a\xdb\xb0\x7e\xe0\xe1\xa5\x31\xe5\xe8\xb1\x7d\xdb\xdc\xf5\x88\x62\x7f\x0c\x8c\x85\xb3\xba\x4c\xc4\xb2\xf4\x14\xf0\x93\x71\x26\x41\xcf\xab\x5d\x64\x8b\xa2\x38\x8b\xdc\x2e\xb5\xc9\xb0\x84\xf2\xd8\x17\x7e\x51\xce\x67\x62\x6b\xd3\x44\x6b\xcc\xc1\x88\x57\x91\xe5\x9d\x98\xbe\xdf\x3d\x47\xb5\x32\x77\x06\x25\x02\x53\x6a\x3b\x21\xfd\xee\x9b\x52\x1e\xf6\x62\x82\x1e\x8b\x77\x63\x75\xf4\xfd\x18\x2e\x13\xe5\xba\x60\x6d\x2e\x6c\x34\x01\xd3\xc0\x60\xf5\x11\x35\x7c\x5f\xbd\x7e\xaf\x87\x45\xa6\x69\x22\x90\x0b\x7e\xef\xf3\x6d\x76\xbf\x1c\x04\x07\xfd\x33\x0b\x17\x45\x3b\x12\x87\x99\xfe\xaa\x19\x37\x3a\x95\x22\xc2\xd4\xc7\x4b\xad\x86\x3d\xe3\xbf\xd3\x26\xce\x52\x29\x6d\x47\xe5\xf6\x76\x31\x85\x20\xa7\x52\xcb\x98\xfa\x1c\x12\x72\x42\x7f\x86\xf9\x49\x55\x1a\x22\xe4\x54\x59\xe2\x25\xcb\x4e\x38\x25\x38\x62\x29\x08\x81\x15\x32\x2f\x6d\x99\xda\xeb\xa4\xfe\x32\x26\x21\x51\x0f\x7f\xc0\x0d\xcf\xdf\x90\x61\x0a\x09\x69\xf6\xa7\xb2\x6e\xbe\x3b\x02\x84\xcf\xd3\xe3\xa9\xe1\x12\xbd\x51\xc0\x04\x97\xff\xa3\xa2\xb8\x5a\xdc\x29\x4b\xf7\x77\x11\x44\x01\xed\x22\x7f\x9c\xbc\xce\x6e\x76\xfb\x99\x08\xb8\x35\x6b\xfb\x31\x35\xcd\x75\xe1\xef\x52\x84\x94\x23\xd3\xc7\xd6\xbf\x36\x44\x92\x8c\xa7\xb7\x08\x69\x8a\x55\x88\x76\x53\xff\x96\x4d\xc4\x78\x98\x08\x39\x4d\x9c\x8d\x9a\xbc\x3f\x11\x9a\x28\x1a\xf4\xcc\x4d\x29\xd6\xdb\x01\x12\x51\x27\x4f\x9b\xd5\x7e\xbb\xb8\x5b\xf5\x42\xc8\x4c\x44\x71\x8c\xbb\xc2\x3a\xcf\xcf\xc7\xac\xe8\xc9\x00\x98\x88\x78\x84\xb7\x8d\x4d\x15\xe7\x77\xaf\x9d\xdf\x1f\x17\x94\x7a\x92\xf7\x52\xc3\x62\x7e\x3b\x10\x24\x22\xc6\x36\x3a\x22\xd2\xd6\x77\x26\x5d\xad\xaf\xaf\xd7\x0f\xb7\x7f\x74\xa3\x18\xc6\xba\xe8\xa2\x4d\x27\x9e\x20\x8c\x26\x8e\x51\x6c\x69\x2c\x26\x23\x8c\x78\x77\x90\x61\xea\xb9\x93\xa6\x2b\xf3\x0d\xa0\xe5\xbe\x6b\xad\x74\xb3\x81\x57\x24\x58\x79\x28\x2d\xf8\xbc\x6f\x83\x67\x22\x16\x26\x4c\x06\x0b\xec\x8f\xde\x12\xf6\x3f\x10\x2b\xc3\xb5\x4f\x08\x3f\x62\xf1\xf8\xa7\x9a\xf4\x91\x32\x11\x43\x8c\xd0\x91\xef\xeb\xa7\xe5\x97\xc5\xfa\x61\x68\x13\x44\xa2\x23\x9e\x58\x85\xfe\xa1\xc3\xe2\x8e\x52\x15\xdb\xf6\xf7\x4b\xfe\xda\x6e\x04\xc5\x34\x7a\xeb\x13\xeb\xac\x99\x87\xe1\xba\xb1\x9c\x6a\xdd\x13\x8d\xaf\x0a\xa8\x0e\xef\x7f\x5c\xa6\x20\x86\x27\x00\x82\x0d\x5b\x33\x0f\xda\x81\x82\x3e\x4d\xd8\xcd\x27\x8e\xc6\xae\xb3\x48\x69\x1a\xb9\x76\xa9\xd3\x7a\xf9\xb8\x8f\x82\xfd\x3d\x6a\x06\xf8\xe3\x82\x62\x6d\xd4\x31\x82\x3f\x40\x63\x36\xf0\x0a\xc5\x79\xd2\x90\x27\x52\x4d\x75\x97\x94\x5c\x2f\x1f\x27\x6f\x4f\x44\x0c\xab\x57\xa7\xb2\xcc\x7b\x26\x72\x7f\x50\x70\x62\xe5\xa1\xcf\x45\xf3\x1e\xfc\x1c\x7d\x15\xa9\xe2\xc8\x75\xac\x1f\xc4\x11\xd4\x45\x57\x93\x50\x41\x8a\x76\x61\xa1\x35\xe8\x19\x3a\xa3\x8b\xe8\x61\x72\x7a\x18\x63\xe9\xcc\x33\x4d\x2e\xcf\xcd\xd3\xd4\xbd\x15\x4a\x40\xe4\x5c\x7a\x8b\x4d\x18\x67\xcd\x85\x26\x21\x06\x9d\x77\xe5\xe1\x4b\xa9\x73\x5c\x21\xdb\xcb\xa0\xdb\x8f\x96\x96\x71\x3d\xb3\x99\xf8\xec\x6f\xd8\x55\x80\x48\x1d\x9f\xce\xfd\xe8\x5b\xce\x06\x40\x42\x83\x89\x5c\xcb\xe4\x32\x6b\x84\x25\xdb\x43\x7d\xb9\x39\xb9\x49\x26\x80\x08\x0c\x3e\x4c\x96\xe7\x57\xe7\xf7\x1e\x1c\xff\x61\xa8\x26\x80\xc5\x89\xe3\x15\x18\x45\x14\xfe\x70\x4a\x31\x7f\xf7\xf3\x97\x70\x43\x61\x42\x6e\xb0\x40\x03\xfa\xa9\xdc\x8e\xbe\xb5\x21\x5a\xf7\xbb\x48\xeb\x8b\x74\x47\xc0\x4a\xd9\x7b\x3e\xe8\x4f\xab\xe4\xc2\x98\x40\xb3\x8e\x3a\x2d\x7f\x77\x4d\xca\x9f\x90\x1a\xdb\x13\x65\x10\x11\xb4\xe0\xd7\x4f\x4f\x53\xfb\x26\x03\x13\xa0\x54\x76\xeb\xfb\x8f\x25\xd9\xba\x01\xb6\xaf\xf3\x5c\x83\xc6\x10\x7d\x7c\xed\x30\x34\xca\xb6\xb9\x65\xc5\xbd\xf8\x79\xa9\x9f\xc9\x64\x48\x2d\xc2\xc5\x27\x5a\xbc\x6b\xe3\x9e\x16\x6a\x97\xba\xd6\x8e\x1c\xa9\x3b\xcf\x68\xec\x68\x39\xd7\xed\x6e\xbf\x6a\x9e\xef\xca\xc3\x36\xfb\xbb\xbb\xf5\x88\x80\xa2\x6e\xbe\xe1\x74\xb3\xd4\x10\xfe\x28\x13\x28\x2a\xbd\x7e\xc4\xcb\x9f\xba\x4d\x49\x92\x10\x74\xd7\x4c\xf9\xa9\x9d\x71\x8e\xe9\x30\x67\x2e\x89\x0c\x3a\x88\xa3\x6d\xae\x40\xce\xf2\xd1\xc6\x28\xe3\x50\x08\xaf\xf9\x6a\xf5\xd1\xb2\x6e\xf7\x92\x31\x31\x81\x95\x03\x38\xb5\xbf\x78\x75\x7e\x7f\x38\x5f\x0a\x85\x7a\x77\x5a\x26\x2c\xa4\xbd\x60\xc4\x16\xf2\x7c\x9e\x67\xe9\xd3\x99\x2e\x69\xc0\x11\x49\x26\x85\x7a\x81\x42\x5b\xe4\x5f\xe7\x85\x48\xaa\x94\x70\x20\x89\x66\x38\x79\x25\x35\x1a\xbb\x84\xeb\xb3\xbc\x16\xef\x1f\x14\x9f\x24\x4b\x53\x3c\xdd\xdd\xd3\xcd\xb9\x50\xf3\x93\x58\x32\x4d\x95\xf0\x9c\xe2\x60\xa5\x5c\x16\x85\x76\x6a\x70\x83\x18\x57\xf2\xd0\xc4\xb6\x2b\x61\x75\x2a\x15\x52\xc2\x6d\x61\xe2\x9c\x48\x9e\x04\x48\x4a\xfb\xd6\x37\x2d\x0c\x38\x2b\x26\x0e\x81\xe4\x4c\x33\x57\x2b\x7d\x74\x15\xcd\x59\xcf\x41\xa6\x2c\xe2\x7c\x40\x98\xb2\xf2\x79\xbc\xcf\x5f\x72\xca\xad\xfe\x69\x95\x1d\x9e\x9b\x70\x72\xab\xa9\xb4\x69\xb3\x59\xb6\x85\xf3\x47\x2d\x9c\x32\x55\xc4\x57\x4f\xb7\xa0\xca\x42\x63\x72\x66\x4e\x37\x91\x49\x11\x59\x47\x00\x73\x3e\x8b\x42\x5b\xb6\xb6\x19\x16\xea\xc9\x7d\x8b\x34\x42\xf2\xc6\xaf\x8b\xbb\x78\xf4\xf5\x25\xe1\xe0\xf2\x65\x2e\x08\x9e\x35\xbd\x52\xc6\x36\x4f\xb2\x5b\x2d\xee\x03\x7f\xb2\x62\xb6\x0e\xea\x71\x8a\x36\x28\xfa\x45\xea\x44\x2a\x88\x10\xee\x73\x0f\xc5\x39\xf0\xdd\xe5\x52\x4b\x89\xb1\x81\xed\x8c\xf7\xba\x93\xa8\x60\xf8\x9c\x9d\x06\x71\xa1\xd4\x4a\x63\xe1\x66\xfd\xd7\xe2\xeb\xda\x77\x35\x48\x88\x63\x24\x1d\x97\xa2\xb0\xc5\xd4\x69\x02\x57\x02\xb3\xb4\x10\x96\xa4\x73\x94\x7c\x95\xa0\x48\xc8\x3b\x5c\x8b\x6b\x27\x9b\x9d\x39\x2a\x88\x53\xac\x4d\xb4\x36\xf6\xb6\xf4\xcc\x65\x4c\x05\x2a\xc1\x7c\xf9\xb1\xd4\x99\x79\xbf\x17\xd5\x4b\x56\xcc\xeb\x26\x33\x15\x52\x82\x2d\x59\x6f\x90\xed\x6c\x0a\xcb\x5f\x25\x12\xd6\xa8\xfd\x10\x55\x95\x95\x55\x7d\x25\x5a\xab\xfd\xa5\x3c\x7e\x68\xc7\xba\x13\x01\x9f\x6e\x20\x2f\xe7\xaf\x49\x22\xca\xbb\x96\xac\x1a\xbe\x55\x23\x56\x45\xa6\x08\xb5\x2c\xb0\xb7\x67\x29\xa1\x6a\x57\x68\xeb\x88\x36\xcf\x55\xf9\xf6\x41\x9e\x5e\x11\x19\x5a\x12\x5f\x51\xec\x90\x3a\xab\x4f\x23\x2a\x22\x23\xad\x3d\x44\x0c\x3b\x3b\x90\x95\xb9\x8b\x6d\xc6\xf7\x1d\x07\xb6\xed\x01\x35\x5a\x2d\x86\xf1\xae\x3c\x64\x9d\x5a\xd3\xf8\x77\x63\x63\x62\xda\xfb\x75\x9d\x79\x53\x49\x6c\x55\x84\x9b\x67\x58\x5d\x2d\x7f\xad\x98\xc1\x54\x62\x12\xec\x80\x37\x65\x65\x1d\x38\x7f\x29\x1a\x25\xc8\x26\x5e\x89\x69\xca\x55\xd1\x94\x20\x3f\xc2\x5d\x59\x1c\x9e\x72\xd1\x27\xce\x87\x34\x3b\xfc\xdf\xc3\x4d\x85\x44\x83\x63\xee\x32\x8c\x44\x1d\x8f\xe8\x12\xc5\x42\x6c\xdd\x68\x5d\x28\x4b\x36\x33\x68\x4c\x53\x0c\x52\x70\x8e\xa4\x2b\xd1\x7f\xf0\x4d\x78\x40\xb1\xcd\x51\x1c\xa5\xa8\x6b\xa1\xcb\x89\xb3\xa7\x78\x60\xb7\xa5\x06\xc4\xf1\xae\x54\x2f\xdf\xba\x19\xc2\x09\x0f\x9c\xd9\xbc\xc9\x0a\x51\xa8\xac\x38\xd4\x0b\x3d\x7d\x7c\x2e\x2d\x52\xed\x6b\x96\xe7\xdb\xb7\xac\xe9\xfc\x6d\xc5\x55\x8c\xf9\x11\xe4\xb9\xaf\x3b\x4e\x2b\xa6\xb8\x31\xc4\xe5\x8b\x1f\xe0\xdc\x54\x22\xbf\x3f\x5b\x4f\x0f\xdd\xa4\x41\xc6\x44\x89\x80\xe1\x4c\xf8\xdf\xb3\x40\x4e\x85\x85\xcf\xb5\xf8\x6b\xc9\x34\xc6\x29\x7e\x0b\x85\x6d\xd6\xd9\xb4\x17\x9a\xb7\x32\x4a\xca\x74\x58\x58\x5d\x54\xe0\x63\x66\xa5\x08\x43\x03\x34\x90\xe3\xed\xb5\x5a\x99\x52\x31\xa0\x7d\x41\x34\x67\xf7\x47\x4a\x3c\x01\xd5\x15\x34\xbb\xac\xe9\x6f\x4b\xa9\x24\x19\x30\xbf\xee\x55\xbf\xf2\x34\x09\xb5\x33\xed\x77\x77\xdf\x5d\x23\xdd\x98\xfa\x40\x41\x40\x91\xa4\xd0\x02\xca\xaf\x41\x9f\x95\x6f\xab\xf9\xe0\xd1\x40\xa8\x34\x1d\x56\x8a\x6c\xa3\xe5\x55\xe9\xdf\x68\xf8\x81\xc3\xad\x40\x31\x2c\xaf\x39\x86\xcf\x31\xbf\x32\x53\x60\x24\xba\xb8\xeb\x6b\x8f\x8a\x51\x26\xe2\xc6\xd2\x0a\x17\x08\x79\xdb\x65\x47\x28\xcf\x4d\x77\x98\x0a\x8c\x72\xee\xfe\x67\xe4\x11\x2b\xc3\x03\xcf\xc9\xde\x7d\xc6\x6b\x78\xbd\xe9\x34\xab\x98\x0e\xe2\x18\xd1\x58\x8b\x73\x53\x2e\x9f\xc5\x18\x0d\xae\xc3\xc8\x0a\x58\x56\x20\xf4\xc8\xa7\xfc\x56\x43\xe5\xb3\x30\x13\xd3\xac\xa3\xc0\x70\x57\x8d\xbf\x87\x06\xaa\x53\x39\x64\x43\x1f\xbe\x43\x1d\x45\x29\x02\x9a\x24\x34\x8f\xa7\x0f\xb9\x91\x66\xb6\x6b\x1d\x51\x48\x7d\x97\x84\xb2\x2a\xcc\xef\xf8\x6a\xac\xeb\x44\x63\x37\x2e\x36\x94\x7b\xed\xf9\x52\x96\xcd\x4d\x59\xb5\xf7\x7e\xf5\x6e\xa5\x81\x66\x3f\xad\x4e\x38\x45\x7d\xc0\x93\xad\x41\x3e\x55\x65\x69\x1e\xcd\x8f\xb2\x9a\xb4\xa5\xeb\x44\x52\x13\x76\x94\xb2\xe8\x33\xa2\x6e\xa2\x3f\xac\x02\x04\xa5\xff\xf9\xfd\x11\xb1\xf4\xdd\xdf\x75\x88\x84\xf7\xaa\xac\x9b\x8d\x63\xf8\x9b\x5e\x59\x6b\xcc\xe8\x78\x96\xfd\xd9\x99\xa4\x29\xa4\xe8\x3f\x99\x73\xa1\x71\x97\x1e\x41\xf6\x34\x35\x02\x6f\x0f\x44\xdd\x46\x31\xa7\xf2\xa3\x94\x99\x66\x2c\x65\xc1\x00\x21\xd8\x06\xc2\x7f\xb6\x43\x6f\xaa\xf2\x78\x2d\x4e\xa7\x29\x08\x68\x72\x23\x4c\x26\x48\x99\xd8\xc6\x84\x23\xb7\xf9\x5f\x49\x6f\x92\xe9\xc4\x24\x8f\x01\x45\x3a\xa5\x24\x70\xfc\xbc\xf7\x28\x8b\xdb\x3c\x7f\xcf\xc4\x94\x45\x64\x7c\xdf\xa9\x89\x71\x82\x0e\x0b\x40\x1f\x94\x42\xb5\x48\x09\x36\xe7\xba\x86\xea\x0f\xa9\xdb\xe7\x7f\x49\x08\xc0\xf6\x58\x24\x17\xbd\xa9\x00\xba\xc6\xca\x76\x1e\xf9\x41\x32\xc6\xaf\xf6\x8a\xdd\xc4\x87\x01\x18\x43\x0b\x05\x16\x63\x8b\xe5\xb7\x36\x18\x29\xdf\x2e\x45\x36\x99\x96\x81\xa5\x57\xdc\x42\x6e\xb0\x08\x77\x56\xcd\xb8\x95\x41\x4b\xa9\x30\x6d\x57\xc0\xcf\xc6\x36\xb4\x75\x47\x94\xc5\x56\x3a\x35\xc4\xa7\x52\x0f\x02\x39\xad\x63\x89\x9e\xfe\x41\x1c\xc1\x53\x6c\x32\xad\xb5\x15\x33\xcf\x1a\x38\xba\x36\xdb\x69\xa2\x5f\x43\x64\x81\x33\x3f\x86\x2a\xdc\x17\x2f\x6e\xfc\xba\x41\x30\xc4\x48\x8b\x0a\x1e\x73\x6d\x79\x92\xbe\xc2\x7b\xfd\xbd\x1c\x2a\xfc\x4d\xce\xd1\x36\x51\x7c\x5d\x9e\x7d\x47\xa6\x36\x81\xb0\xa4\x8a\x79\xbe\xef\x6b\x4d\xda\xa4\x81\x6f\x6b\xbc\x3a\xbf\x7f\x2b\xb2\xa6\x6e\x03\xc4\xea\x28\x86\xb5\x37\x6d\x84\x44\x40\x84\xef\x54\x19\xbb\x1f\x10\xc4\x74\xd0\x47\xd4\x6e\xf8\xbd\x8c\xe5\x1f\x7e\x0c\x25\x49\xeb\xa2\x2c\x6e\x57\x0f\xbb\xfd\x76\xb7\xd8\x7d\xdb\xce\x03\xcd\x21\x48\x3b\xe6\xa6\x6d\xa6\xa7\xf5\x23\x08\x23\x86\x82\x72\xab\x4a\x45\x01\x92\xf7\x7f\xd8\x8e\x0d\x51\x18\x20\x2b\x6a\x89\x28\xe0\xa7\xb2\xcc\xad\xb8\x76\x7d\x87\x19\x84\x46\xe4\xd3\x09\x0e\x51\x24\x94\x0f\xbb\xb0\xbe\x75\x2b\xa6\x77\x10\xf1\xd8\x13\xfc\xb7\x93\xf3\x0e\x8c\x9f\x3b\x10\xa5\x04\x3b\x70\x3d\x08\xfc\x37\xfa\x5b\x81\x24\x02\x9b\x73\x90\xd4\x69\xbb\x5b\x6c\x3c\x42\x17\x88\xa4\x58\x78\x11\x59\xa5\xab\xf2\xb4\x28\xf4\xb0\x5e\x06\xc4\x18\xcc\x0c\x9e\x2a\x38\x14\xa2\xf0\x5d\x0c\xfe\xb3\x41\x1c\x48\x04\x4d\x6d\x1b\xd1\xfc\x39\x40\x09\x41\x1c\x52\x64\xed\xbc\x7b\xbc\xdd\x6f\xad\xee\x90\x39\xe7\x73\x40\x33\x7f\x82\x89\x13\xe2\xc3\x41\x67\x4d\xd7\xc7\xd3\x04\xeb\x04\x49\xa0\x95\x25\x6a\xbb\x7b\x5c\x4e\x8f\x45\xb1\x95\x10\xb2\x61\xde\x5f\xe5\xb9\x1a\xe5\xc9\x21\xa1\x16\x51\xbb\xc7\x7a\xfc\x70\x5f\x99\x5c\x88\xd3\xd8\xcd\x59\x2b\x6c\x3a\xc4\xaa\x42\x92\x12\xac\x21\x36\xe5\xe1\x90\xc3\xa2\x69\x84\x7a\x06\xbd\x6a\x27\xb5\x02\xcb\x3f\xdb\x85\x5f\x90\x18\x85\x14\x25\xb7\x79\x29\x45\xbe\x03\x35\x42\xf4\x03\x65\x04\xcb\xda\xb7\x8b\xed\xfe\xea\xdb\xcd\xcd\x6a\xd3\x1d\x49\x23\x2c\xbb\xee\xdd\x97\x19\x28\xed\x30\xa0\x3a\x40\x0b\x81\x0e\xe4\xb2\x2c\x4c\x76\x89\x82\x1a\xbf\x5e\x46\x84\x36\x17\xba\x7b\xdb\xf2\x5c\xf5\x0b\x88\x13\x9b\xfd\x3b\x8a\x46\x3d\xdf\x5b\x62\x13\x4b\x2a\xe6\x37\x6b\x17\x31\xf7\x9c\x59\x90\x46\x0c\x2b\xef\xf7\x99\xaa\xca\xab\x9d\x2f\xd7\x40\xca\x12\x4b\x35\x66\xc9\xa2\xa3\xfd\x6b\x6b\x4e\x9c\x72\xf5\xfe\xd8\xc6\x6b\xe2\x00\xfb\x7a\x40\x7a\xcc\x20\x15\x02\xf7\xe1\x7d\x56\x6f\xb3\x76\xa5\x3d\xb5\xd1\x52\x33\xb4\x43\xe3\xa7\xf2\x4e\xf0\x16\x44\xde\xb3\xb6\x4f\xd7\xc2\xff\x29\x33\x04\x82\x0b\x14\xa9\x5e\x3d\x8e\x9c\x34\x90\xca\xfa\x76\x07\x68\x1c\xef\xfd\x87\xec\x1b\xee\x0c\x1d\x76\x0d\xb2\x0f\xe5\xa3\xb9\xaf\x0f\x13\x17\x0c\x74\x9c\x60\x32\xc3\x79\xb0\xdb\xbc\x6c\x2e\x46\x68\x3e\x66\x4d\xfe\x7e\xff\xab\xfc\x05\x68\x61\xb0\x8c\xb0\x7b\x86\xdb\xf2\xfa\x90\x0d\x66\x8e\x36\x1c\xaf\x77\xfd\xf8\x63\xbf\x5d\x74\x66\x00\x82\x20\x01\x47\xd3\xde\xcd\x07\x08\x95\xd7\xca\x7e\xaa\xe0\x35\x2b\xcf\x35\x92\x43\xf9\xc3\x29\x47\xfd\xb0\xa6\x3a\xd7\x0d\xe8\xab\x73\x55\xcc\xb0\xe9\x32\x30\x31\xc3\x9d\x32\xab\xbf\xf6\xa4\x05\x60\x04\xe5\x3e\x25\x28\x72\x98\x12\xf7\x33\x30\x32\xa4\x51\x07\xe4\xff\xcd\x6f\xda\x9d\xcb\x51\x21\x18\xa5\x1b\xaa\x79\x60\xb4\x09\x62\xc0\x3a\xdf\x69\xa8\xcc\xd5\x1d\x0d\x89\x85\xee\xfc\xef\x59\x54\x8d\x43\x4c\xfa\x43\x5c\x63\xfe\xd8\x4e\xe6\x21\xdf\xdd\xef\xc1\x7a\x87\xf9\x53\x13\xc5\x1d\xb6\x73\xb9\xfc\x62\x83\x1e\xee\x7f\x29\x52\xd6\xd6\xaf\x44\xed\xa4\x5d\xc3\xa0\x3b\x06\x54\xd8\xd2\xb7\xc7\xe2\x38\x3c\x51\xe0\x06\x90\x20\x40\xc4\x22\xe6\xb8\xdb\x77\xbc\xbf\xc7\x64\xcb\xaa\xd0\xd7\x53\xd5\x05\x86\xb2\x7a\xba\x0b\xd9\x3e\xd4\x95\x6f\x07\x1a\xec\x2e\xff\x22\x0a\xfd\x63\x4a\xf3\xcd\x0c\xa1\x41\x18\xf8\xcf\x66\x5b\x9e\xc6\xe7\xc7\x11\x51\x2e\x87\x76\x07\xc2\x8c\x59\xf4\xba\xd7\x1f\x47\x8a\x5a\xb4\x57\x1b\xac\xf5\xdd\xcf\x26\x76\x6a\x82\xbb\xf5\x6a\x13\x0d\xea\xa7\x26\xa6\x1a\x23\x7f\x5b\x68\x7c\x13\x95\xbe\xda\x8e\x23\x36\x93\x18\xab\xd7\xd6\x31\x5a\xc3\x03\xfc\x6c\x1e\xe6\x66\xad\xa1\x26\x0e\x7a\x09\xf8\xaf\x7f\x2d\x1d\x2b\xc0\x74\x94\x40\xfb\xbd\x5a\x5f\xdb\xc4\xe8\x66\x19\x75\x5f\x88\x85\x96\x1f\xd6\x9c\x9b\xea\x3e\xeb\x24\xed\x98\x61\x31\xc3\xed\x18\x71\x9f\xb6\xe3\x68\xe8\xed\x18\x96\x70\x4f\x8e\x69\xc3\x81\x89\x8a\x2d\x33\x4c\x42\xe2\x1a\x0b\x6f\x7f\xa2\x86\xc1\x24\x8b\xe8\xc6\xf1\x98\x62\xe1\x7f\xbf\xdf\xbb\x80\x7b\x57\x4e\x87\x50\x45\xa6\xe4\x2c\xf5\xa6\x7b\xad\xdc\xd8\x55\x82\xfc\x7f\xe8\xb0\x77\x18\x5a\x37\x42\x84\x1a\xdd\xdc\x2f\xed\x62\xeb\xfe\x98\x44\x1a\x3c\x40\xc1\x2a\xdf\x60\xd6\x60\xfc\xdb\x42\x70\x5b\xcf\xb5\xe9\xae\xa1\x8a\x1b\x33\x32\x15\xb8\x88\x75\x56\x9f\x72\xf1\x7e\x1c\x13\x0c\x19\x29\x2c\x76\xb1\x82\x57\x10\xf9\x90\x22\xcb\xa8\x54\x20\x7e\xf6\x47\x59\xe5\xfa\xa1\x53\x4c\x63\x46\x29\x4d\x6c\x0e\xbd\x27\x95\xf7\xcc\x52\x1f\x99\x18\x77\xaa\x06\x1e\xf6\x3c\xbc\x4f\x8f\xeb\xc9\xa3\x40\x18\x76\x75\xe1\xff\x47\xd0\xf4\xfe\x73\x03\x58\x65\x49\x3b\x19\x07\xbc\x35\xc6\x84\x09\xb7\xea\x62\x5f\x44\xde\x63\x21\x8c\x09\xa5\xc3\xcb\xfd\x5c\x8a\xd3\x06\xd0\x47\xe9\x0e\x46\x81\xdf\x98\xda\xf9\x05\x55\xf3\xbe\x2c\xf3\xb2\xaa\x1f\xcd\xc6\xe9\xd2\x86\x43\x7c\x0e\x0f\x82\x38\x42\xe6\x8d\x5c\xd4\xcd\xd7\xa2\x7c\x2b\xfc\x79\xa3\xa4\x19\x0f\x82\x34\xc6\x8e\xf5\x76\x11\xae\xfe\x7b\xee\x44\x87\x78\x10\x52\x85\x75\xf7\xfb\xc5\xfa\xc1\x62\x1f\xae\x1e\x1f\xbe\x6d\xf7\x4f\xab\xcd\x72\xf5\xb0\x5b\xdc\xae\xf6\x4f\x5f\x16\xdb\x55\xe8\x4f\x88\x58\x84\x86\xe4\x5e\xe4\xe2\xbd\xce\x04\x61\x41\x77\x88\x4b\xcc\x39\x8a\xb3\xce\x9a\x81\xb4\x92\x3b\x4c\x62\x4e\xe5\x24\x9d\x32\xf2\x92\xfd\x38\x01\x98\x8e\x79\x79\x57\xcb\xf2\x78\xca\xc1\xbf\x56\x1e\x10\x93\x72\x9b\x30\xa8\xc6\x86\x92\x07\x71\x92\xc6\x3d\x27\xc7\x75\xcf\x7f\x34\xd3\x15\xc1\x83\x98\x72\x37\x4b\x6d\xc0\xde\xee\x92\xd3\x0b\x8a\x84\x43\xe7\x4f\x6e\xc0\x58\x94\x9d\xbf\x95\x24\xe4\xdc\x82\xd9\xda\xa8\xce\xad\x74\x57\x52\xdc\xa0\x5c\xae\x1f\xc8\x03\x34\xcc\xdf\xcb\xec\xb4\xeb\x1c\x17\x1e\x24\x69\x18\x0b\xbf\x14\xdb\xa0\xba\xd9\xc0\x7f\xcf\x59\x05\x7a\x57\x6e\x40\x55\xe7\xac\x99\xdc\x51\x22\x29\xd6\x4d\x9e\x36\x2b\xfc\x52\x96\x60\xe0\xcb\x62\x73\xdd\x1b\x5c\x1e\x24\xa6\x4b\x94\x6f\x90\x9c\x7d\xfc\x76\x69\xc4\x3b\xc5\x3f\xe4\x28\xbc\x64\x08\xe2\x01\xa5\x0c\x93\x94\xe2\x74\x82\x42\x7f\xc3\x96\x8a\x51\x2f\xdc\x3f\xc6\x77\x46\x59\xe2\xcc\x4a\xa1\xaf\x33\x71\x2c\x07\xf1\xc4\x58\xbb\xd5\x33\x12\x4f\x2f\x20\x52\x6c\x01\xb5\x8f\xb4\x7b\xdc\x2d\xee\x86\xcf\xc4\x62\xa2\x2c\x02\xee\x67\x1b\x98\xdb\x92\xd8\x00\xee\xc8\x83\xd6\xf2\x72\xdb\x35\xd6\x46\x66\xed\xbe\x1a\x75\xc7\x94\x0c\x2c\xe1\x58\x56\xfc\xc7\xa6\xef\xc7\xef\x84\x01\x45\xd2\x92\xff\x59\x2d\xbf\x2e\xac\x5f\xef\xcf\xe5\xa1\xd4\x51\x2f\x32\x7b\x7f\x6e\xce\x22\xff\x9f\x52\x2e\x31\x65\x95\x8b\x5e\x1e\xfd\x32\x5f\x39\xeb\x05\xf1\x80\x73\x8e\x0c\x25\x7b\x25\x8a\x27\xf1\xfe\xe8\xc8\x58\x26\x1f\x9b\x2b\x83\xc6\x00\x9c\x16\xd0\x17\xc8\xa1\xc8\x06\x7c\x3d\xe3\x47\x48\xe3\x18\xb1\x95\x48\x3f\xb8\xc9\x0e\xcf\xf3\x79\x57\x1e\x88\x84\xa7\x72\x44\x11\x37\x83\x01\x1c\x5f\x5b\x4a\x89\x1c\x45\x8e\x32\xb2\xcf\x7f\xf2\x40\x82\xc2\xa6\x5e\x40\xa6\x9e\xa7\x6a\xc0\x46\xc7\x03\x15\xc6\x22\xe9\x39\x6a\xdd\x8f\xfc\x58\xad\x7b\xf9\x6c\x1e\xa8\x88\x8b\x68\x4c\xec\x37\x88\x84\x3a\x3b\xa5\x09\xb5\xac\xab\x22\x87\x1f\x90\x75\x85\x21\x1e\x68\x69\x5d\xe7\xd6\x63\x55\xcf\x90\xe7\x59\x71\xb0\x24\xf5\x53\x3e\x71\x1e\x40\xa0\x6d\x55\x47\xbc\x5a\xc9\xce\xf3\x25\xc2\x8f\x07\x40\x00\x25\x22\xb6\x59\x71\x38\xe7\xa2\xca\x9a\xf7\x1d\xd4\x4d\x44\xfc\x4f\x82\x4a\x30\xcf\xe2\xdf\x61\xb7\xa6\x4d\x2a\xe2\x61\x53\xdf\x53\xf9\x02\xc7\xcb\x56\xde\xf1\x27\x09\x83\x24\x80\x4e\x3b\xf9\xaa\x12\x85\x7a\x5e\x17\xab\x53\x56\x0f\xef\x70\x7c\x4a\xc8\x24\xfa\xba\x0e\x2e\xd5\xe5\xec\x86\x82\x69\x3c\x0c\x53\x8a\xbc\xa2\x85\x7b\xb1\xf7\x59\x0e\x75\x53\x16\x9e\x11\x87\x87\x24\x91\xd8\x4f\x89\x3a\x4e\x1a\x54\xf5\x7e\x6a\xc6\x4a\x4e\x3c\x24\x8a\x04\x5e\x98\x76\xf7\x5c\x95\x6f\xdb\xf2\x08\xad\xc9\x3b\x74\x23\xc0\x32\x06\xed\xb3\xfa\x0e\xc4\xe9\x2f\x10\xd5\x10\xd2\xc9\xc3\x98\x44\x58\xd6\x6f\xb2\x23\x5c\x95\xe7\xc1\xec\xf4\x03\x92\x00\x9b\x05\x36\xc2\x98\xd6\xd8\xa2\x52\xe7\x47\xf8\x9b\x59\xef\xdd\x79\x93\x3c\x8c\xb9\x25\xa3\xb1\xfd\xac\xcb\xe7\xec\xf4\x21\xbf\xe1\x3f\x2e\x4d\x5f\x18\xa7\x4a\x7a\x6e\x08\xdf\x12\x35\x6e\x3d\xe6\x61\x92\x6a\x07\x60\xad\x32\x81\x3a\xd2\xfe\x80\x4a\x11\x6e\xb9\x83\xaa\x12\x2b\x55\x0e\x22\x55\x1e\xd2\x28\xa0\xae\x47\x67\x07\xe2\x78\xe1\x77\xb5\x23\xe2\x94\x61\x8b\xfc\xee\xcf\xee\x2c\x2a\x90\x52\xa4\xa3\xbb\x70\x7f\x67\x9a\x61\x5a\xed\x57\x3c\x63\xf3\x46\x28\x64\x60\x99\x5d\x85\xd6\x73\x4c\x8a\x83\x87\xe5\x4c\x99\x70\xa8\x2f\x64\xbd\xf8\xf1\xca\x0a\xb9\x50\xb6\x05\xc1\xbe\xf5\xbc\x2c\x60\xde\xc9\x9a\x43\x12\x5c\x10\xc4\xf3\x90\x1b\x01\xbd\x9f\xaf\x27\x12\x7f\x3c\x4c\x09\x8f\x1d\x24\x6a\x5b\x9a\xe6\x4d\x54\xe0\x64\xed\x26\xe0\xab\xb9\xda\x35\x0f\xd3\x34\x22\x3d\x05\x9e\xf7\xd2\x77\xe5\xb4\xf9\xa5\x1b\xce\x23\xab\x30\xf0\xee\x29\xd0\xfc\x11\x43\x6d\x9d\x0d\x5e\x47\x1f\x5b\x24\x31\xa6\x10\xba\x25\xb7\x5f\xe6\x65\x0d\xbb\x67\xec\x68\x1e\x9a\x9b\x50\x30\x8d\x1e\xd5\xf2\x5c\x55\xef\x7d\x40\xdb\xee\x3c\x61\x40\xed\x2e\x5c\x95\xaf\xf0\x00\x6f\x8f\xbd\x02\x37\x0f\x55\x92\x7a\x45\x3f\x04\xde\xba\x0d\x71\x7c\xe7\x4a\x08\xe8\xdb\x56\xee\x47\xe4\x6c\x33\x95\x21\x1e\x2a\xa9\x30\x84\xb9\x5f\x6f\x77\xdd\x2f\x19\x46\xe3\xa1\xb0\x1f\x36\x89\x9c\xdf\x2f\x67\x9d\x3b\x41\x87\x36\x14\x6f\x3d\xd9\x73\xf1\x32\xb9\x27\x08\x12\x24\x07\xff\xfa\x78\xfd\xe8\x7f\x02\x34\x20\xff\xd6\xa9\xcc\xf3\xd6\x19\xfb\xdf\x7e\x51\x99\x76\x49\x0e\x80\x59\x43\xfe\xe3\xf1\x77\x8a\x42\x6a\x33\x2c\x07\x68\xee\xb2\x02\xbe\x9d\x2c\x83\xdc\x5e\x83\xe9\xd3\xa7\x3c\x8a\x28\x20\x68\xd9\xdb\x6f\xcb\xac\x38\xbe\xcb\x28\x92\x9a\x0c\x75\x61\xb0\xd4\x3b\xeb\xbd\x44\x91\x66\xc6\x32\x4f\x6f\x7a\x7d\x89\xe1\x5b\x8d\x48\x2c\xb0\x90\xeb\x35\xb1\x5e\xa0\xf8\x56\x65\x93\x5f\x8c\x29\xc3\x24\xaa\xd3\x8e\x9a\xa6\xd2\x79\x14\x73\x8b\xb3\x75\xbc\xd9\x1f\x25\x5f\x66\xbf\x49\x14\x8b\x08\x37\x2d\x61\x2b\x42\xf5\x24\xff\xcd\xa3\x84\x58\x59\x07\x57\x6b\x9e\xa7\x9f\xff\xd0\x84\x4e\xae\x25\x52\xec\x31\x71\x4e\xf3\x06\x85\x5e\x7c\x67\x8f\x85\x06\x21\x18\x75\x7d\xb5\xf4\x0f\xc7\x84\x4d\x1a\x62\x8c\xf2\x73\x2c\x58\xf2\xaf\x28\xf8\xb7\x1b\xc6\xa3\x14\x5c\x22\xa3\x5d\xf8\x5f\x44\xa5\x97\xe2\xd2\xc4\xfb\xd1\x84\x79\xb5\x27\x0c\x45\xfb\x92\x12\x8f\x38\x50\x80\x51\x13\x62\x6e\x6b\xa0\xed\x94\x71\x8b\x69\xfc\x54\x69\x60\x1b\xfc\xff\xee\xd6\x79\x94\x86\x1a\x29\x80\x51\x10\x6a\x44\xb6\x33\x39\x35\x4d\xd0\x4b\xc9\xea\xf5\x11\xa9\x1f\xe6\x01\x10\xed\x40\xdb\x96\x78\x28\xfd\xc4\xeb\x7e\x2a\x05\xa4\xdd\x44\xc9\xec\x51\x0a\xe7\xb7\x52\xa8\x3c\x4a\xa5\xa5\xc9\xba\x5f\xfc\xb9\xbf\x5b\xfc\xb5\xda\x6c\xfd\xa5\x85\xb0\x25\x31\x0b\x74\xbb\x7a\xdf\x89\xc3\x28\x47\xc3\x23\xc9\x01\x3d\x70\xb4\x34\xd7\xa2\x3a\x1f\xc5\xff\x35\xa1\xeb\xaf\x24\xad\x74\xe4\x53\xd9\x6c\x4f\xf9\x0c\x4d\x6e\xbf\xf7\x44\x52\x47\x98\xe5\x58\xce\xc9\x16\x7e\xea\x65\x47\x8a\x11\x04\xf7\x74\x42\x3e\x5b\x98\x7e\x4e\xa5\x39\xfa\x5d\x3d\x67\xed\x06\x9a\xac\x9a\x86\x07\x91\xe6\x21\x7a\x8d\xb7\xeb\xe5\x62\x68\xe4\x23\x2d\x63\x0c\x2c\x30\xdf\xbf\x75\x65\xa3\xec\xef\x61\xe1\x68\x72\x57\x26\xb2\xf2\x67\x56\x19\xc4\x52\x67\x7f\x2e\x0f\xc2\x23\xc3\x35\x22\xf2\x26\x0a\x7d\x9f\x3b\x95\x24\xa0\xdc\x93\x55\x3d\x55\xbf\xd6\x7d\x9b\x9e\xac\x9c\x22\x7e\xb3\x17\x95\xcc\x9a\xcf\x2b\x59\x9c\x04\x92\x23\x0e\xc9\x25\xa1\x50\xc2\xd3\xc9\xb9\x7c\x70\x82\xa2\x09\x1d\x08\xa9\x61\x49\x21\xcf\x3b\xd4\x37\x27\x61\x64\x3b\xbb\x7d\xd7\xc8\xf7\xb2\x81\x9b\xb2\xb2\xbd\x5a\xed\x44\x68\xbd\xfd\xa3\xd5\xf4\x3d\x8f\xf1\x22\x73\xd5\x45\x4e\x42\x12\x60\xe9\x26\x53\x25\xca\xb6\xa1\x15\x7a\x16\x35\x44\xab\x2e\xa0\x21\x21\xb1\x81\x68\xbb\x73\x95\x65\xfe\xf8\x0a\x55\x2e\x4e\x7d\x19\x98\x93\x88\x86\xb8\xe2\x11\xbd\x68\xcb\x62\xe5\xc4\x91\x23\x11\x0f\xd1\x2b\x40\xb6\x32\x47\xeb\x3e\x75\x48\x3e\xf8\xaf\xbf\x82\x0c\x02\xed\xe5\xf5\xf0\x75\x56\xe5\x9b\xfe\x01\xf0\xe2\xa3\x10\x42\x12\x2b\xf5\xbe\xc8\xe1\xa5\x86\xec\x9f\x22\x6b\x14\xbc\x0e\xa8\x45\x3f\xfc\xe8\xe3\x9b\x6d\x63\x00\x67\x51\xd7\x45\xd6\x6c\x2f\x62\x51\x42\xb4\xe5\x3b\xbd\xca\x0e\xb2\x3c\x0e\x90\xab\x13\x31\x35\x4e\x62\x1d\x10\x2b\x18\x50\x65\xe6\xbd\xd7\x39\x1b\x42\xcb\x46\xff\xfc\xf0\xc0\xef\xff\x93\xb8\xad\x81\x24\x01\x13\x03\xfc\xa3\x7e\x9d\x7c\x15\x1a\xa5\x0e\xb1\x26\x8e\xae\x1a\x3c\x1d\x01\x06\x5d\x8d\xfd\xa9\xab\x70\xb9\x23\x8c\x07\x18\xa6\xaa\x5e\x89\xf4\x5c\x74\xd0\x2a\x4e\xb8\xb2\x81\xf0\xc1\x77\x13\x36\x5d\x90\x45\xd2\x20\xe0\x2e\xe9\xfa\x94\xfd\x84\xbc\x4f\xee\xcd\x24\x87\x39\x49\xc3\x10\x5b\x06\xff\x13\x8e\x70\x4a\x9c\xa4\x91\xcd\x82\xa0\x38\x93\x95\x85\x6a\x17\x59\x01\x23\x28\x64\x3b\x8e\xe1\x07\x3d\xe9\xb2\x3b\x95\x58\x39\xd5\xcc\x81\xf4\x7e\x21\xe0\xc2\x49\xca\x53\xdc\x11\x1c\x75\xf2\xb6\x69\x5d\x02\xd5\x64\xaf\xdd\x3a\x48\x55\x80\x39\x1f\x1b\x67\x39\xe7\xdb\xf1\x70\x8e\x6e\x47\x30\xc0\xd0\x7d\xb1\x1a\x1a\x4f\x22\xd2\x18\xf5\x36\x7a\x25\x6d\x11\x86\xfd\x41\x8e\x49\xb3\xf2\x04\x45\x4f\x40\xed\x0f\x4a\xab\xe1\xd0\xa1\x6d\xca\x66\xc8\xb3\xf3\x21\xec\x89\x13\xa1\x12\xac\x52\x58\xdb\xd4\x75\x27\x5a\x3a\xb4\xf9\x0d\x99\x48\xe0\x08\x12\xaa\xb3\xe2\x90\xc3\xbe\x9d\x5a\xe3\x5e\xc9\x61\x46\x96\x28\x69\xbb\xa5\xf7\x45\x39\x28\x38\x73\x02\x22\xc5\x2e\x81\xba\xcc\xf5\xf5\x6a\x77\xb1\x79\x8d\x56\x7f\x1c\x84\x96\x99\x5d\x42\x23\xcf\x6d\xbc\xb1\x7b\xf3\x9f\x32\x0e\x64\x88\xed\x74\x87\xb2\xd4\xf5\x43\xd9\xf8\xb6\x84\xf1\x9a\x8d\x43\x6d\x71\xe9\x87\x8e\xe3\xb0\xfd\x86\xf5\x64\x54\x14\xe8\xc8\x56\xab\xba\x66\x67\xac\xc0\x27\xfe\xd7\xa2\x48\x21\x61\xa5\x2c\xcb\xba\xa9\xc4\xe9\x49\x54\xcd\x3c\x9c\x8a\xc7\xad\x21\x89\x6c\x2c\x04\xf9\xa3\x0b\x00\x1f\xce\x47\x7f\x2d\xa2\x2c\x4d\x0c\x52\x24\x2e\xf2\xac\x9b\x0b\x71\x4c\x8c\xd0\x9d\x2a\x88\x97\xbf\x9e\x58\xd5\x38\x4e\x25\x7a\x03\xb7\x9d\xaa\x2e\x8f\x69\x1c\x18\xa7\x70\x8b\x2d\x88\x4b\x51\xe9\x59\x32\x66\x3f\x9e\xa6\x08\x54\xf4\xdd\x3f\x9e\x57\xd9\x1d\x66\x51\x92\xf6\x74\xa9\xcb\xfc\x2c\x27\xf7\xc0\x62\x8e\x8c\x2d\x15\x34\xe7\xaa\xb0\xea\x36\x37\x15\xb8\x44\xb6\x1b\xc4\x45\x80\x39\x84\xa2\x6c\x32\xf3\xde\xeb\x3f\xcf\xda\xdf\x98\x1b\x21\x2d\x64\x09\xf2\xdf\xd9\xda\xe3\x34\x0a\xd0\x4a\x7d\x93\x59\x5d\x7a\x04\x0a\x8f\x05\x0d\x71\x59\x5c\x09\xf5\xa2\xcb\x12\x73\xda\x83\xd6\xa2\x8f\x40\xc4\x3c\x16\x9c\x51\xda\x17\x85\xca\x62\x7d\x14\x07\x2c\xa0\x2e\xf3\xf2\x7c\x29\xf9\x32\x97\x34\x8b\x85\x14\xa9\x6d\x56\x3b\x9e\xab\x4a\x1c\x3e\xd2\x76\x71\xc3\x65\x60\x4b\xec\xcd\xe8\x79\x67\xd6\x6c\x2c\x43\x85\x11\xec\xd3\xb7\xab\xbb\xf5\x72\xbf\x59\x6d\x1f\xef\xbe\xaf\x36\xfb\xbb\xc5\xd5\xea\xce\x3f\xbb\x8c\x19\xa2\xb0\x30\x2f\xde\xd7\x2e\xba\xc3\x82\xc7\xa2\x63\xfb\x05\x3d\xe6\x7e\xe3\xb1\x0a\x02\xbc\x79\xdb\x6f\x32\x75\x00\x63\x95\xa4\x94\x78\xf1\x9d\x73\x0d\xcb\x73\x53\x1a\x83\xb1\xc4\xf8\xcb\x28\x9a\x46\x96\x82\x73\x57\x09\x8d\x05\x0e\x95\xad\x8b\x2d\xd8\xb6\x0c\x3f\x2a\x05\x9c\xb3\x77\xa2\x6e\x7a\xf1\x3d\x1e\x2b\xc1\x29\x1b\x05\x24\x18\xfd\x2d\x9a\xa6\xec\x7a\x9e\x3a\xf5\x6f\x1e\x2b\x2d\x02\xd7\xfb\x8c\xa5\xa7\xb9\xcc\x45\xac\x13\xea\xc3\xa5\x0d\x88\xfc\x38\xe7\x17\xb8\xa1\x20\x53\xdb\x9e\x6f\x9b\xcb\x47\xce\x94\x1b\x62\x12\x8d\xcc\x23\x9b\xf2\x4d\x14\x83\x54\x45\x12\x04\x11\xfa\xa8\x76\x59\x58\xbf\xb6\x6b\x7b\x70\x63\xc2\x98\xd9\x24\x3e\xe8\xec\x7c\x1c\x60\x77\x78\x12\x32\x19\xa3\x8c\xfa\xc3\xb5\xe5\x6a\x18\x31\x2e\xf3\x24\x94\x14\x5d\x9d\x1c\x0e\x50\xe8\x21\x4d\x1b\x4f\x42\xd0\x96\xcc\xb5\x8d\xef\x1e\xe0\xad\xf5\x13\x67\xf3\xba\x49\x14\x84\x98\xf4\xe9\x36\xbf\x0e\x96\xcd\x93\x88\xc4\xb6\xfc\xed\xe8\x59\xd7\xcb\xc7\x6d\x23\x0e\xe0\xbd\xad\x84\x28\xeb\xd9\x14\xf0\x76\x5d\x89\xb7\xf1\x16\xf0\x2f\x72\x81\xf9\x98\xf7\xac\x93\x38\x06\xee\xf2\x56\xb7\x56\x42\xf2\x49\x64\x1e\xb8\xc5\x93\x58\x4b\xa4\x45\x7a\x15\xe7\xbc\xd9\x57\x58\x74\x1a\x4f\xc6\x24\x09\x42\xe9\x88\xc8\x77\xcf\x15\xd4\xcf\xbd\x35\x4c\x12\x6d\xd1\x1b\xf6\x33\xdc\x95\x45\x27\x17\x31\x2b\xe5\xfe\xaf\xe8\xdf\xfe\x44\x70\xc1\xb7\xf3\x67\x77\x20\x8e\xb7\x95\x28\x7a\x0f\x28\x61\x3c\xed\x18\xd2\xe1\x0d\xbb\x5f\x3f\xda\x33\x13\x26\x6c\x4e\xde\xa6\x12\x5a\x4b\xe2\x65\xa0\x7e\xab\x44\x92\xf0\x28\x41\xdf\x40\x18\x93\xe5\x19\x66\xe8\x8e\x13\x8e\x22\x3f\x92\x08\xe4\x24\x1a\x4a\x7b\x3a\xa1\xcc\x99\xde\x8b\x76\x3c\xd0\xb4\x4b\x9a\x7d\xab\x75\x5f\xb5\xe5\x09\x57\x01\x16\x3a\x1a\xa8\x9b\xfb\xfa\x60\x59\x95\xd7\x45\x3b\xa3\xfa\x4f\x94\xaa\x18\xf1\xd9\xed\x7b\x9f\xc7\xca\xf2\x44\x18\x83\xf3\x19\x5f\xe7\xc3\xe2\x3b\xc2\xb0\xbe\x6d\xaf\xfd\x35\x24\xb3\xc5\x4a\xdf\x35\x7f\x25\x8a\x97\x36\x02\xed\xf6\x72\x3f\x4e\x06\xce\x9e\x74\x35\x91\xa1\x70\xe0\xe4\xd9\xa4\x0c\xad\xcc\x9f\x2e\xef\xc5\x69\x71\x6e\xca\x89\x61\xf5\xe3\x94\x55\x3c\x46\x5f\xd5\x54\x65\xdd\x58\x60\x9f\xff\x55\x15\x86\x18\x3a\x3a\x02\xf3\xd5\xf2\xf1\xe1\x7a\x6f\x75\x49\x7a\xa6\x59\x9e\x28\x96\xc8\xc8\x12\x9e\x62\x91\x76\x59\x6a\xb0\xe2\x65\x7e\x84\x96\xc2\x1b\x34\xf7\x4d\xce\x9d\xc0\x63\xff\xb1\x21\x60\x48\xaf\x3d\x10\xa4\x6e\xff\x28\xc1\xc1\x8c\x2e\x44\xf2\x79\x02\xa1\xe5\xca\xc5\xf7\xb7\x01\x25\xf2\xbc\x7f\x69\x00\x31\x22\x67\x6f\xb2\x1c\xdb\x7a\x97\x6d\x84\xe8\x8e\x19\x2a\x10\x8b\x08\xf3\xb3\xc9\xe8\xd8\xf0\x8e\x7f\xf3\x43\xc9\x9f\x7f\x8c\xa7\xd6\x4c\xfe\x9a\x06\x24\xd5\x56\x9e\x55\x03\x1c\x41\x0f\x3b\xb5\x38\x0d\x23\x19\x19\xff\x86\xb7\xfb\x9b\xc7\x0d\xd6\xde\xbb\xc3\xc6\x36\x97\xed\x0f\xd0\x5c\x4a\x23\xb7\xc7\x09\x3a\xf8\xcf\xe5\xb9\x86\x6d\x23\x5e\xfc\x1b\xa7\x11\x27\xe8\x62\xf5\xd5\xbd\xf9\xb9\x42\x23\x11\x22\x5a\xd2\x00\xb8\x26\xbd\xbd\xbf\x46\x4c\x24\x02\xc8\xee\xb3\xa2\x99\x48\x2f\xfc\x56\x86\x87\xc6\xc0\x68\xd0\x49\xd3\xf6\x4b\x77\x25\xaa\x62\xea\xa7\xd2\x24\xb4\x4d\xee\xed\x63\x64\xc5\x01\x77\xbc\x1b\x98\xd1\xe7\x1d\xdf\x7f\xa2\x22\xdc\xb1\xbf\x94\x27\xdc\x4c\xba\xad\x88\x26\x4a\x68\xe9\xa9\xd0\xda\x80\x05\xdd\x41\xfb\x1a\x7b\x87\x9c\x52\x1a\x09\xd7\x3f\x83\x3b\xd5\x7e\x3c\x15\x28\x63\x29\xf2\x5a\xe5\xa2\x6e\x90\x0f\x69\xff\x1a\xc6\xfe\x37\x98\xb2\x62\x6c\x73\x4a\x4c\x9f\xa7\x61\x29\x03\x81\xbe\x44\xeb\xc4\x2e\xcb\xa2\xe8\xf8\x43\x39\x65\xc6\x32\x5f\x5f\x95\xe5\x0b\x22\x96\x56\xcd\xf3\xf7\xf0\x14\xfa\x26\x06\x37\x8c\x87\x04\xc3\xdc\x27\x51\xd7\x3e\x84\x2c\x3d\x83\x79\x37\x28\x31\x51\xe8\xd9\xcd\xbe\xd5\x50\x15\x13\x1a\x31\x4e\xb9\x48\xa8\x63\x55\x47\xa5\x5b\xfc\x30\x71\x30\xfa\xa8\xfd\xff\x74\x27\xa5\x41\x84\x19\xf6\xd3\x59\xbe\x4c\x88\x4a\x38\x4d\x43\xe9\xe9\x02\xe6\x14\xa7\x38\x4d\x13\xc0\x2e\xa3\xcd\xd3\x3c\x04\x9c\x53\x91\x06\xc6\x23\x09\x46\xec\x44\xd3\x61\x16\x55\x96\xd5\x5f\x33\xf5\x52\x1a\xe3\xa4\x62\x26\xbf\x27\x59\x80\xbc\xa4\x15\x32\x8e\x3c\x56\x87\xc5\xd3\xfa\x2b\x74\x6f\x52\x25\x81\xe9\x85\x8e\xb0\x31\x6d\x40\x62\x35\x98\x2c\x3a\x88\x10\x82\xdb\x2e\xc8\x76\x6b\x6c\x57\x73\x59\x35\xe3\x8a\xcb\xe4\x4d\x69\x25\x12\x7b\x8b\xab\x9f\xa7\xbc\xac\xa6\x82\xaf\x9c\x42\x94\x20\x02\x13\x77\x89\xe5\xa8\x12\xe5\xee\x90\x05\x51\xa4\x89\x77\x4b\xee\xcb\x42\x54\xea\xf9\xfd\x56\x4c\x1d\x4f\x16\x24\x09\x42\xa3\x4f\xe2\x7d\x84\x8b\x60\x01\x18\x86\x40\xe0\xf5\xc3\xfa\xe1\x76\xff\xf4\xf8\x78\xb7\xff\xf2\x78\x77\xed\x11\xcd\x9c\x85\x84\x22\xcb\xf6\x97\xd5\xdd\xfa\xcf\xee\x8f\x09\xc7\x46\xd4\xbd\xd0\x56\xe2\xf4\xa9\x2a\xf5\x59\x0d\xc2\x89\xd1\xf7\x60\x11\x49\x30\x33\x2e\xcf\x55\xb1\x81\xa3\xc0\x76\x85\x3f\x26\x63\xb4\x20\xad\x53\xf0\x75\xfd\xe0\x37\x42\x46\x38\xb1\xca\x3d\x59\xd1\xf4\xc2\x9b\x17\x2f\x93\xc5\x71\x4c\xfc\x6a\xf4\x15\xcf\xff\x3d\xc3\x19\x06\xfd\x23\x9c\x25\x81\xe6\x1e\x6b\xf8\x25\xc3\xfa\xc0\x12\x55\x46\x7b\x2a\x01\xce\x12\x6a\xc2\x68\x50\x4e\xda\x9e\xca\xa2\x2e\x87\x9e\x2a\x4b\x64\x68\xe4\x28\xe3\x8a\xe6\xa3\xcb\xe8\xb0\x44\x87\xe8\x07\x2f\xaa\xe6\xf9\x6c\x85\xb6\x44\xa5\x7f\xd9\x32\xed\xce\xa6\x89\x41\x3e\x85\x36\xd4\xe8\xf4\x4f\x39\x63\x71\x8c\xa8\xd2\xbd\xab\xf7\x21\x04\xee\x77\x54\xa4\x38\xe3\x21\xc1\xd2\xb2\xb1\xaa\xa3\xf7\x65\xdf\xa1\xce\x19\xe7\xd6\xd4\xeb\xac\xc6\x4c\x64\xeb\x20\xf5\x45\x25\xc6\x79\x12\x3a\x40\x90\x9d\x83\x83\x89\xcf\xb8\x16\x78\x4f\x88\xf2\x73\x78\xa1\x1e\xe6\x6c\x99\xb5\xdc\xd0\x94\x5a\x9f\xcd\x81\x06\x6f\xa0\x7f\x5d\x82\x84\xc8\x20\xdc\xb7\x37\x4d\x16\xff\x6f\xb7\x39\x71\x26\x89\x4d\x0b\xeb\xac\xc6\x6e\x25\xab\x77\xeb\x7f\x49\x26\x14\x53\xf5\xb8\xa4\xbe\x6d\xd6\x93\x65\x22\x21\x14\xa6\x57\xdc\xfc\x22\xea\xe7\x6d\x76\x28\x06\x37\x34\x88\x76\x98\x0a\x98\xb6\xd2\x71\x4e\x4e\xf6\x1e\x72\x80\xed\x59\x36\xef\x27\x18\x66\xa4\x98\x32\xe0\x03\xc4\x21\xee\xb8\x7b\x37\x90\xd0\x90\x78\x46\x73\x4b\xb1\x82\x84\x41\x93\xdb\x03\x2e\x91\xf2\x21\x53\xe5\xa6\x3c\x17\x9a\xfa\xc7\x32\x29\xe1\x9e\xe8\x36\xcf\xd7\x0d\x1c\x5d\x2e\x6e\x3a\x2d\xfa\x4f\xc7\x83\x58\x62\x9d\xe5\x7a\xeb\x4b\x6c\x3c\x48\xb9\x27\xf2\x18\xf8\x93\x56\xc5\x68\x74\x27\x3c\x30\x56\xc7\x46\x23\x19\xe3\xae\x02\x51\x7b\xd9\x6c\x7f\xb1\x90\x18\xa3\x3d\xf9\xc0\xf7\xf5\xd3\xdd\x80\x54\xda\x3f\x38\x0f\x25\x51\x01\xe6\xa8\xb1\xe9\xf7\x56\xd4\x38\xf7\xac\x9b\x38\xb1\xd6\x3c\x0a\x13\x60\xc3\x96\xd0\xd5\x4f\x05\x75\x3d\xd2\xbf\xe4\x3c\x12\x4a\xf1\x4e\xd0\xcf\xe6\x71\x1f\x8d\x85\xeb\xce\xae\x0e\x1e\x01\x60\x34\xd2\x31\x47\xcd\x99\x18\x1e\x81\x49\xdb\x97\xd3\x5a\xd7\xc7\x13\x5c\x78\x2a\x9c\x04\x1a\x7b\x35\x56\xcb\xea\xfd\xd4\x8c\xb0\x1d\x9c\x10\xab\xae\xb0\xb7\xd8\x4d\xa4\x5e\x5d\xd7\x37\x65\xb5\x99\xd2\x1f\xb4\x63\x4d\xe2\x3e\xe6\x2e\x83\xaa\xee\x40\xdd\xbc\x5b\x03\xff\xfe\x8d\x7f\xf1\x2e\x7a\xe3\x44\x13\xb4\xd6\x42\xeb\x7b\x71\x3a\x65\xc5\xe1\xa6\xac\x6c\x77\xf1\xfa\xfa\x73\x75\x4f\xce\xe3\x38\x15\xdd\xde\xe6\xd9\xd0\x60\x52\x00\x9d\x9c\x93\x44\xd2\xd7\xf7\xaf\xb2\xaa\x79\x5e\x9e\xa7\x0f\x99\x30\xad\x9c\x55\x71\x49\x95\xfb\x0e\xf0\xcb\xdb\x10\x24\x19\xba\xa9\x0e\x52\xe2\x8f\x42\x1a\x79\x66\xfa\x21\x71\x27\xe7\x34\x30\x71\x38\x6a\xf6\x58\x3e\x97\x99\xfa\x20\xa3\xc1\x69\x92\xc6\xba\x17\x2b\x73\x3e\xc2\x58\x47\xae\x1b\xaa\x02\x18\xb4\x6f\xe9\x28\xbe\x2f\x8b\xe6\xb9\xee\x7e\x1a\x94\x47\x5b\xf8\xe5\xf0\x54\x95\x52\xa0\xc6\xd8\xfb\xae\xb5\x08\x23\x43\xc5\xb9\x11\x76\x4b\x14\x45\x2f\x1b\xf4\xd4\x55\x0c\x38\x37\x4a\x79\xd2\x4b\x0c\xfd\x86\x98\x27\x37\x26\x8d\x05\xa2\xdd\x7f\xdc\xcf\x82\x69\xfc\x28\x1a\x62\xac\x61\xa3\xed\xaf\x59\x71\xd0\xe5\x71\x12\xfe\xce\x7b\xa3\x3c\x4d\x29\x86\xcf\xf7\x50\xd7\xe2\x00\x4b\x91\xe7\x43\xa2\x1e\x9b\xcd\xff\xa0\x7c\xf4\x8f\xcb\x2c\xf8\xe5\x27\x48\xc1\x56\x09\x6c\xe6\xcd\x81\x2b\xaf\xde\x83\x55\xff\x51\x25\x65\x49\x27\xf7\xf0\xb3\x83\x06\x6f\x4f\xe5\xf4\x75\x48\xc6\x30\x99\x85\x7a\xbb\x16\x43\x85\xc2\x30\x97\x82\x34\xed\x58\xe5\x8b\x2e\x96\x5f\xa4\x9e\x35\x74\xd2\x30\xf4\xd2\x50\xcd\x18\x49\x2c\xea\xa9\xf5\xe6\x2a\x09\xd1\x8b\xcc\x1c\x77\xd6\x5e\x62\x30\xe1\x8f\x2a\x2a\x1c\xfe\x70\x09\x55\x93\x99\x4c\x89\x0b\x65\x56\xce\x81\x52\xc4\xc8\x81\x83\x36\x6c\x45\x0e\xf3\x04\x65\x9c\x1b\x4d\xa0\xcf\x42\xaf\x55\xb9\x99\x36\x86\x70\x6e\x20\x34\xa2\x43\x92\x23\xeb\xf9\x18\x2f\x90\x06\x94\xe0\xa3\xd9\xea\xb4\xb8\x24\x08\xf6\xe3\x4c\x84\x0a\xa9\xb7\x50\x2c\x9f\xb3\xd3\xd5\xfb\x0f\x40\xfc\xe8\xec\xe7\xf5\x2f\x25\x0d\x45\x94\xba\x05\xde\x11\xdf\xfc\xaa\xca\xfc\x41\x67\x14\x4f\xa3\x28\x48\x9c\xb6\xc5\xb7\x7b\x27\x99\xe6\x1f\x23\x22\x21\x62\xd7\x8f\xad\x8b\x58\x56\x9e\xc0\xec\xf3\xf2\x7f\x1a\xd1\x94\xf8\x49\x55\xce\x92\xa0\xf0\x34\x52\x06\x0d\xba\x55\xe1\xdb\xf4\x1c\xbc\x3c\x25\x61\x47\x67\xf3\xf8\xb0\xf3\x05\x89\xcb\xcf\x90\x12\x01\x96\xf8\xa0\xd9\x95\x4f\x4d\x57\xa5\x49\x63\x08\xc1\x5d\x60\x60\x54\x67\x2e\x90\x90\x00\xe3\xdf\x02\xde\xae\x45\xb9\x39\xe7\x50\x4f\x9b\x4b\x7e\xdd\xbe\x34\xc8\x3f\x7c\xf0\x3e\x92\x98\x19\xcb\xdf\x78\xcc\x8a\x2d\x34\xbb\x9f\x37\x00\xeb\xe2\x35\x6b\xe0\x32\x9c\x48\x93\x24\xc0\x10\xf3\xea\x7e\x8d\x41\xd8\xac\xf1\x48\x69\x90\x60\xbd\xe7\x7a\xb5\xb8\x5b\x6d\x7e\x78\x1a\x9b\xd6\x1e\xd9\x46\xcd\x73\x71\x25\x26\xeb\x20\x4d\xa3\x18\x8d\x15\xa6\x6e\x6c\x5a\xfb\xa6\xc4\xe9\x79\x7d\x6e\x0d\xd6\x7a\xf9\xe8\x81\xdb\x69\xca\x42\x0c\x62\x4d\x59\xb5\xfb\x83\xad\xb1\x8c\xef\x34\x35\x02\x93\x3d\xcf\xa5\xce\xa1\x42\x87\x1e\xe3\x7d\x72\xef\x2f\x22\x48\x24\x64\x2f\x8e\xbe\x13\xd5\x01\x66\x14\x02\x78\xda\xfa\x15\xd4\x85\x9e\x73\xd9\xef\x54\x26\x81\x72\x18\x47\x9d\xcd\xd0\x15\x75\x6b\x43\x32\xed\x84\x29\xde\x97\xe5\xf1\x58\x16\xbb\xdd\x8f\xab\xf7\xd5\xee\xcb\x7c\xf4\x94\xca\x94\x63\xf6\x3c\x77\xe4\x66\xe3\xee\x8d\x54\x0a\x63\x7c\xdd\x0b\x8a\xdb\x3e\xc1\x96\x2a\x10\x69\xda\x55\xd4\x7a\xb8\x74\xaa\x69\x80\x0e\x29\x82\x14\xa6\xfc\x3d\xa3\xa9\x72\xe1\x67\x4f\x34\xe1\x79\xaa\x95\xa5\xbd\x3f\x0e\x79\x28\x66\x61\x95\x29\xc4\x84\x86\xce\x37\x3b\x0c\xee\x13\x92\x88\xdb\xf2\x00\xe6\x37\x97\x43\x84\xd9\x4d\x55\x1e\xad\xfe\xf6\x07\x31\xce\x87\x56\x03\x14\xb5\x6a\x7b\x6d\x70\xdc\x49\x38\xce\xcf\x55\x13\x29\x14\x75\x35\x83\x3a\x5d\x6a\x92\x10\xe1\xba\x4e\x08\xb9\x2a\x8f\xe5\x46\x48\x79\x89\x49\xf2\xe3\xb9\xc1\x50\xb9\x75\x24\x6f\xa1\x19\x68\x5d\xfb\x01\x42\xb8\x18\xa8\xe7\xa9\x34\x50\x8d\x38\xe3\xe7\x52\xb2\xa9\x91\x09\x22\x08\xa1\x79\x3e\x17\x27\x71\xee\x4a\x53\xa9\x51\x56\x6e\xbf\x6e\x7d\x98\xd7\x4c\xc1\xf5\xb9\x38\x00\xaa\x73\x8c\xde\x86\x08\x25\x58\xec\xc2\xb1\xf5\x5b\x76\xa5\x45\xd3\x8f\x52\x3e\x22\x84\xd0\x35\xf9\x15\x1a\x99\xcf\x0b\x91\xe7\xef\xf3\xfb\x82\x88\xda\x38\xc0\xed\xa0\x22\xcf\xb7\xcd\x50\x29\x71\x3a\x54\x05\x36\x4d\x51\x65\x2f\x50\xd5\x1e\x9e\xf0\x87\x3f\x0e\xb6\x20\x2a\xb4\xb6\x82\xbb\x50\x6d\xe0\xbf\x8b\xe5\xf2\xf7\x92\x66\x22\x4e\x54\x1c\xfb\xb0\xee\x5e\x34\xe7\x2a\x6b\xde\x9f\xa0\xca\x4a\x6f\xb1\x45\xcc\x35\xeb\x25\xd2\xb7\x0d\x9c\x3c\x58\xd3\x0f\x10\x0a\x4b\xbb\xc7\xf3\x3c\xbb\x34\x17\xb1\x62\x98\xae\x7e\xc9\xd4\x0b\x66\x2d\x9b\x06\x10\x76\xf4\xc7\xe4\x6e\xb4\x46\xcf\x0d\x45\x25\xae\x44\xa3\x9e\x61\x9e\x0c\x91\x8b\x18\x6c\x02\x6a\x25\xaa\xfc\xdd\x57\x1d\x17\x47\xab\x7a\x3f\xfe\xf5\x04\xa8\xcd\x06\xf9\xed\xe2\x5c\xe8\x45\xa1\x57\x85\xbe\xed\x6b\x84\x82\x92\x44\xba\x2a\xcc\x0f\xc8\x2e\xf7\x13\x41\xb5\xad\x26\x23\xf7\xbd\x2d\xe7\xd8\xb0\xdd\x1d\x67\x21\x20\x99\x3e\xfa\x30\x5e\x1d\xaa\x5d\x86\xc3\x12\x80\x60\x04\xd4\x50\x25\x13\xe9\x65\xfc\xb1\x98\x44\xa6\xcb\xea\xaf\x55\x39\xe5\x13\xf6\xe3\x68\x8c\xb8\x8f\x2b\x4f\xb0\xc1\x05\x0f\x38\xba\x9b\xe2\x55\x34\xe2\xd7\x90\xf5\x81\xf1\x15\x3c\xb4\xd4\x0b\x48\x20\x82\x84\x05\x23\x77\x5b\x70\x12\x48\xe7\x0f\x4d\xde\x08\x27\x04\x7b\xf1\x90\x94\xed\xea\x5c\x79\xe2\x01\x2e\xd2\xc0\x2a\x64\x3e\x8b\x42\x63\xf7\x4a\x2d\xa6\x15\xf8\xf1\xa5\x52\xe8\x50\xe7\x7e\x1e\xb7\xe6\xeb\xeb\x5f\xcb\xc9\xb3\x0b\x23\x71\x8a\xb4\x61\xc7\x97\xbe\xfe\x20\x14\x0b\xf0\xed\x3b\xa5\x6a\x68\x5f\x5c\xd1\x5c\xbd\x5b\x65\x98\x4f\xca\xe0\x42\x47\x0c\x68\xe7\x48\x3f\x55\xdd\x07\xd5\xa9\x6d\x5e\x5a\x17\xad\xd3\xfe\xda\xc1\x59\x36\x76\x76\x5e\x4a\x63\x70\xa1\x41\x27\xce\x77\xbb\x76\x49\xa1\x81\xd7\x3b\xdd\xce\x04\x70\x86\x7c\x84\x96\xb4\xff\x1e\x0e\x42\x96\xd3\x97\x0c\x26\xc1\x0c\xc7\xa9\x82\xf6\xe3\xec\x3c\xe5\x40\x7b\xc4\x0a\xef\x64\xb5\x55\x01\xf5\x7f\x37\x61\x82\x14\x05\xc6\x29\x50\x3f\x89\xf7\x1e\xeb\x24\x4c\x4c\x9d\x00\x71\xb1\x28\xde\xcb\x02\xe5\xa0\xdd\x41\x19\xf0\x30\xea\xc0\x03\x75\x9f\x6f\xf4\x87\x81\x72\x17\xaa\x2d\x57\x3e\xbd\x26\x43\x6e\x63\xd6\xb2\x00\x8c\xec\xba\xbf\xa7\x06\x7d\x9d\xac\x1c\x72\xdf\x72\x19\xb6\x6b\xcd\x0b\x88\x3e\x0d\x5b\xcd\xb9\x8c\x42\x63\x61\x9c\x3e\x41\x98\x61\x7e\xb0\xba\x71\xf8\x82\x6e\x1c\x65\xac\x4b\xdf\xae\x8a\x76\xb3\x18\x64\xe6\x64\xa4\x94\x74\x71\xfb\xb6\xa9\x86\x6a\xfd\xd3\x6d\x76\x38\x15\x24\x89\x02\xac\xf2\xe2\xed\xde\x65\xff\x3d\x67\x3a\x6b\xde\xdd\xdb\xfd\xad\x12\x8d\x24\xb1\x75\x8a\x30\x80\x9f\x54\x98\x25\x49\x14\x6b\x6f\xeb\x6a\xf1\xb0\x78\x58\xf8\x9b\x25\x29\x48\xe7\xd1\xae\xf4\xb2\xac\x60\x1e\xbe\x26\xe3\x90\x08\x3d\xe2\xd7\x1d\x92\x19\x4d\xf7\xf6\xb0\x07\xf2\x0d\x97\xbb\x8c\x89\x0a\x03\x57\xf9\x3c\xd7\xa0\x27\x8c\xb0\x5c\xc6\xca\x32\x59\xd8\xc7\x1e\xa7\x5e\xc7\xcf\x1a\x83\xc4\xdc\x8c\x4f\x36\xf8\x7c\xf0\xf8\xb6\x93\xc8\xaa\x94\x79\x68\x58\xfd\x41\x5e\x5f\x26\x54\xa2\x03\x7b\xee\x2a\xce\x9d\xaa\xc5\xd8\x24\xc9\x44\x0b\xc4\xd5\x38\xfe\xd4\xa6\xe9\x20\x20\x92\x0a\x2b\xac\xb7\xd8\x7a\x55\x46\x2e\x59\x60\x29\xd8\xf6\x58\xfa\x28\x5a\x03\xbe\x36\x0f\x00\xba\x9f\x4f\x4c\x11\x84\xac\xdf\xaf\x77\xc3\xe9\xc8\x80\x2b\xdf\xde\x7b\x2f\x5e\xa0\xb7\xb8\x92\x47\x51\x34\x65\xa6\x5a\x3f\xcd\xf5\xc4\xca\x34\x4c\x10\x1e\x71\xbf\x7e\x78\xdc\xec\xbf\xaf\x36\xdb\xf5\xa3\x77\xe9\xa5\x64\x04\x4c\xef\xfa\x5c\x65\x4d\x7d\x23\xb2\x1c\xd3\xef\x8f\x8f\x57\xfd\x30\x6d\xf3\xf9\x45\xd6\x6c\x44\x05\xb7\x55\xf9\xd6\x2f\x35\x15\xc5\x49\xeb\x1e\xdd\x9d\xff\x27\x13\xff\x3c\x67\xa3\xf5\xa6\xe2\x28\x15\xdd\x06\x7e\xed\x08\xa1\x9f\x44\xf3\xfc\x26\x3e\x70\x51\xa4\xa2\x56\x63\xc6\x06\xc1\x7d\x4e\x41\xea\x30\xb6\xb7\x8b\xd2\xc6\xc5\xeb\xa8\xfc\x2a\x75\x68\xf9\x98\xbe\xaf\x36\xeb\xfb\xd5\x64\x22\x68\xc2\xb0\xbe\xff\x58\x3f\x43\xe5\x70\x38\xeb\xe5\xe3\x30\x67\x2e\xb5\x34\x72\xa8\x6c\xfd\xad\xa8\x4b\xc7\xd4\x5a\x77\x63\x94\x8d\x16\x36\x88\x69\xbb\x7e\xdc\xcd\xe5\x98\xa5\x21\x84\xf3\xee\x46\x37\xcb\x85\xcf\x3f\xf9\xcb\x18\x23\xb0\xc5\xbb\xc9\xa0\x0a\x7b\xa0\xb2\x0a\x42\x91\x24\x7d\x63\xea\xfc\x0b\x52\x01\x17\x68\x2a\xf6\x59\xfd\x88\xfa\x36\x22\x5f\x9c\x4e\x93\x40\x58\x05\xd2\xf2\xc8\x4a\xa4\x90\x6c\x1d\x8f\x11\x65\x16\x57\x81\x92\x52\x7a\x7d\x79\xf5\x02\xfa\xff\xe3\xed\x5f\xba\x1b\xd7\x91\x2d\x71\xfc\xbb\xf4\xe8\x0c\xee\x80\x04\x1f\x20\x7a\x26\xd9\x72\xa6\xfa\xf8\x75\x2d\x39\xf3\x56\xf5\xba\x4b\x2b\x00\x04\x2c\x96\x29\x52\x4d\x52\xce\x74\x7d\xfa\xff\x62\x00\xa0\x48\x8a\xf2\x39\xf7\x3f\xf8\x4d\x2a\xeb\x98\x20\xc5\x07\x10\x88\xc7\x8e\xbd\x1d\xa8\xb9\x07\xa0\xbc\x36\x13\x77\x46\x85\x10\x13\xe0\x31\x2f\x4d\xb5\x90\x9d\x4b\x76\xf4\xa2\x63\x99\x62\x61\x42\xae\x81\x8b\xc9\x96\x9f\x84\xb5\x99\xdc\x15\x43\x9d\xf4\x4e\xdf\xa2\x69\xf2\xb7\xb2\x33\x9e\xce\xeb\xee\x2f\x65\x30\x3d\x4b\x76\xd9\xfb\x1e\xd8\x58\x15\xa5\x89\xb1\x58\xbc\x5f\x1a\x3e\xfb\xbf\x66\x16\x1d\xff\x82\x6f\xcb\xa1\x12\xc2\x6c\x51\x52\x45\x52\xb0\xf4\xdc\x5b\x5e\xc3\x5b\x75\x0b\xd5\xe4\x76\x93\x30\xf2\x09\x91\xd7\x06\xeb\x5b\x4b\x8f\x30\x8b\xc0\x50\x29\x57\x30\xe4\x5d\xa3\x90\x55\x5e\x52\x31\x64\x8a\x87\x82\xfa\x8f\x1f\xa0\x7c\x03\xb5\xbf\xe0\x2e\xf8\x5b\xfe\xb3\xe2\x4c\xd2\x6e\xba\x5d\x2d\x1e\x76\x2f\xab\xcd\xea\xe5\xc7\x6a\x77\xd7\x37\x19\x2a\x1e\x0b\xb4\x62\xd9\xb8\x7d\xc3\xc9\xc7\xe7\x49\xea\x9a\x43\xda\x1f\x58\xe7\x26\x9f\xe2\xe3\x14\x17\xa9\xe7\xa2\xec\xb6\xe9\xbc\x7c\x7b\x80\x2b\x2e\x14\x05\x49\x76\x1b\x51\x35\x6d\x3e\xd3\xc9\x28\x64\x48\x18\x8c\x66\x5f\x9d\x0a\x4d\xbf\xf8\xb9\xc1\xb7\xc3\x8c\x8c\xc6\xff\x9d\x6e\x1e\x2e\x20\x75\xf4\x85\x99\x12\x9a\x93\x6f\xd4\xed\xcd\xf7\x55\xf5\x7e\x3a\x4e\x66\x29\xa4\x71\xe2\x7c\xd9\x81\xce\xd6\x7f\xcc\x41\x87\x14\x68\xa0\x52\x6a\xe5\xba\x3c\x76\xff\xef\x84\xe7\x0a\xf7\xa8\xbf\xbd\x4f\xcd\x2b\x99\x06\xb4\x72\x2c\xc5\x61\xb7\xd7\x8e\x91\x58\x16\x0f\x73\x2e\xdb\x28\xc9\x35\xd1\xf8\xfd\x59\x93\xd4\x92\x0f\xa1\x94\xcc\x52\x4a\x74\x78\xf0\x9a\x17\x19\x3f\x1f\x07\x9e\x0c\xca\x78\x97\x19\x32\x3f\x50\x64\x89\x93\x6d\x2d\xbc\x95\xf5\x17\x51\x89\xd2\x23\xbf\x06\xff\x91\x63\x31\x5d\xda\x4a\x28\xe5\x2a\xa8\xab\x62\xd4\xf4\xe4\x07\x00\x52\xb8\x87\xbf\x5b\x8a\x74\x88\x2b\xad\x97\x94\xca\x94\x0e\x2c\x0f\xb7\x8f\x8f\x2d\x66\x8b\x1a\x0a\x1b\x57\x0a\x98\xbf\x77\x9d\x26\x68\x7d\x32\xe2\x94\xff\x8a\x61\x34\x53\x5a\x6b\x2b\x4d\xd2\x45\x42\x84\x83\xd8\xd0\x94\x5a\x62\xb4\xf3\x6d\x27\xd4\x08\xf2\x19\x05\x41\xe0\x59\x2c\x14\x86\x96\xd7\x96\xba\xb1\xff\x0f\xa8\xf7\x63\x35\x7d\x3e\x64\x86\x96\x4b\x91\x1b\x6c\xf3\x03\xba\xfb\xe8\xbf\x05\x46\x01\x09\x12\xc8\xa2\x52\xef\xcd\x5d\x45\xa8\xcd\xf1\xcd\x21\x00\x31\x45\x53\x52\xc5\x4f\x89\xf9\xfc\x7a\x7f\x06\x52\xdd\xba\x85\x0f\xac\xcb\x09\x50\x40\x99\x98\x33\xf7\x4d\x1c\xd4\xae\x19\xf5\x82\x2b\x93\x72\xdb\xe9\x7d\xfa\x24\xae\xf7\xcd\xb1\xe7\x8c\xca\x94\x91\x41\xe4\xce\xb6\x65\xa3\xe5\x9c\x2d\x32\x3a\x26\x2a\xc1\xd7\x47\x22\xac\xeb\x8c\x89\xbb\x80\x0e\x50\x05\x0e\xee\x74\x52\x16\x49\x31\x07\xfe\x1d\x3f\x92\x0e\x39\xd3\xa9\x2f\xc5\xbf\x63\xb9\x2e\x4d\xf5\x58\x9d\x6b\x7d\x3a\x74\x80\x3c\xd0\xfa\x75\x5d\xb6\x16\xd8\x3d\x9b\x7a\xd2\xa1\x32\x56\x7c\xaa\xef\x9a\xbc\xab\x6a\x27\x14\xe7\x2f\x17\x69\x99\xb1\x3e\x72\x25\xad\x4a\xf8\x3d\x50\xe9\xcf\x74\xcc\x0d\x09\x30\xd7\x48\xd2\xb0\x96\xc4\x79\xf4\x16\x74\x2c\x23\xda\x52\x5d\x95\x7e\x51\xea\x1b\x28\x8a\xe7\x1a\xa9\x92\xec\xd6\xf7\xbc\x9e\xed\xbc\x33\xae\x93\xc0\x82\x2d\x68\xa2\xe6\x65\x83\x75\xbb\x33\x79\xa9\x1f\xab\xef\x79\x69\x25\x59\x70\x0b\x79\xf1\xc7\xe4\x2c\x8b\x7b\x2d\xf1\x77\xbb\x04\xf5\xfe\x93\x44\x4c\x17\xfa\x5f\x27\x8b\x5f\xb1\xbc\xc2\x7e\x30\xb3\xc4\xda\x16\x51\x7a\x8d\xbb\xd3\x0d\x4e\x43\x91\xf5\xa6\xe4\xf3\xd8\x56\x8b\xb7\x8b\x35\xae\xd3\x4c\xc8\x70\x24\xba\x4c\x2b\x7c\x7c\xa5\x2c\x0e\xe8\xc9\x08\x3d\xb6\x3a\x60\xfd\x86\xa5\xa2\xbe\x97\xbc\x3c\xbf\xf4\x2c\xc5\xc8\x72\x57\x14\x43\xa5\xb2\x4c\x67\x59\x46\x80\xa8\xaa\x29\xf2\xf7\x7c\xa0\xb9\xe7\x8f\x2b\x63\xf9\xef\x8f\xc7\x21\x0e\x44\x8b\x98\x51\xa8\xb2\xad\xe1\x03\x0b\xac\x07\xaa\xc1\x99\x16\x2a\xa0\xf6\x1a\x97\x7e\x74\xb2\xd7\xff\x03\x8a\x00\x2d\x50\xaa\x5e\x92\xf3\x00\x6d\x35\xc4\x02\xe8\xce\xb7\x67\x36\xd3\x68\x7f\x00\x88\x92\x62\xf2\xfa\x64\x0a\x46\x9c\xf5\x19\x5a\xdc\xf5\xe8\x32\xad\x52\x2b\x76\xf1\x81\xfb\x5c\x15\xd8\x2c\x3f\x6f\xf2\x76\x82\xb5\xd2\x8a\x63\x28\x7a\xb9\xf2\xaa\x54\x04\x94\xcd\xab\xf2\x82\x44\x2c\xd3\x3a\x8d\x09\x2d\xa5\xe1\x47\x5e\xaa\x7c\x9c\x5e\xd6\x3a\xb5\x00\xfb\x7e\xf1\xdf\x62\x0b\x79\x31\xd9\x97\xb5\x86\x88\x52\x59\x3f\x9e\xb6\xeb\xc7\x6f\x96\xae\x72\xb7\xec\x2c\xc1\xe3\x4b\x7f\x29\xe0\x96\x84\xcc\xa2\xbf\x7c\x99\x7f\x8c\x4c\xf7\x79\x05\xad\x8d\xd5\xb1\x7c\x78\x98\x52\x27\x67\xda\x24\x9a\x3c\xfb\xe5\xd3\xe6\xfb\x7a\x10\xeb\x60\x60\x6c\x31\xae\xdb\xd2\xbb\xdb\xf5\x7f\x0f\xc3\x84\x6a\x05\xdb\x3a\x3f\x2e\xf3\xa1\x3a\x44\x86\x61\x64\xdd\x9f\x9e\xc5\x2a\xc3\xd0\x60\x64\xfc\xfb\x77\xea\xdf\x4f\xe6\x06\x0e\x47\xc8\xdf\xca\xf1\xbb\x46\x16\xda\x4e\xfb\x9d\xdd\xc5\x7b\x50\xe4\x3c\x86\x0d\x99\x51\x60\x15\x41\xbe\xd6\xed\xf8\xea\xdf\xa1\xbb\x88\x11\x0b\x78\x3c\x6c\x3a\xb9\x50\x20\x75\x03\x63\xc1\x03\xdb\xed\xdf\x52\x17\xe0\xea\xf7\xb1\x22\x19\xf8\xf1\xb7\xc4\x18\xac\x2c\xd8\x71\x60\xec\x2f\xea\x63\x98\x24\x3c\x98\x71\x78\x46\x3e\xd2\xff\x0d\xff\xdb\x8f\x4e\x53\xd2\x39\x91\xd8\xae\xcb\xe3\xa9\xdd\x56\xcb\x4f\xaf\x01\xe8\x60\x84\x57\xfe\xe9\x2f\x20\x20\x3b\xcb\x21\xfd\xd1\xff\x19\x28\xaf\x7d\xb7\x78\xee\x22\x13\xb7\xd7\x86\xfd\x61\x93\xc4\x16\x8a\xa5\xa0\x84\xd1\x67\x4f\x59\x4a\x9e\x24\xed\xe4\xb7\xf9\xc7\x04\x49\x82\xa9\x64\xf4\x83\x45\x45\x54\xc3\x84\x3f\x9e\x6a\x77\x74\xa3\x20\xfe\xff\xba\xa5\xd1\xbf\xd3\x54\x71\x82\x5f\xe5\x87\xbc\xf4\xa8\x95\xd1\xcd\xf1\x20\x45\x36\x10\xf1\x1f\x12\x58\x67\xc8\x43\x4b\x68\xff\x50\x51\xd7\xf6\xe3\x82\x68\x53\xfb\xa3\x59\x46\x1d\xd2\x2f\xab\xfb\xd5\x62\xb3\xda\xad\x9e\x9f\x6e\xbe\xf7\x07\x15\x78\xcd\xa5\x87\xe6\xed\xf6\x9c\xcb\x47\x8e\x89\xe5\x38\x21\x92\xa6\xc7\xd7\x07\xcb\x43\xe5\x7b\xc9\x31\x53\x16\x0b\x55\x9d\xda\x86\x78\x4c\x6f\x6c\x31\xe4\x71\xc0\x66\xe3\x87\x6a\x8b\x3e\xd8\xee\x6d\xd6\x75\xd5\x5f\xc3\x58\xc9\xb8\x43\xde\x34\x68\x63\x00\x57\x55\xdf\x14\xbe\xdf\xf7\x6a\x72\x0b\x85\x51\x99\x67\x12\x78\x03\x6f\xe7\x10\x02\x45\x9b\x51\x67\x4d\x0e\xf0\x3e\x42\x33\x21\x84\x86\xc4\x55\xbd\x26\x58\xdb\x59\xdc\xb9\xd8\x62\xe6\xbf\xfd\x25\x62\xdb\x03\xa3\x8a\xaa\xc1\x1b\x7d\xfc\x8b\xbb\x04\x99\x10\xc1\x9f\xc5\xa6\x7a\x47\xf3\xe4\x02\x82\xc1\x2f\xf4\x66\x48\xf2\xd8\xe6\xe5\x62\x36\xba\x77\xc5\xd0\xa6\xc2\x5e\x97\xab\xff\xea\xff\x98\x70\x3c\xb7\xd4\xb9\x6f\x30\xb1\x6b\x3a\x65\x44\xee\x6b\x03\x3e\x3d\xba\xa8\x46\x4e\xee\x66\xf7\xa6\xea\x66\xf1\x81\x35\x50\x01\xfc\x62\x2b\x43\x6d\xd2\xc4\xe2\x07\xda\x45\xa9\x5f\xc8\x03\xbc\xc3\x6e\xdb\xba\xab\x61\x44\x22\xe1\x4e\xc0\x40\xa5\x43\x0a\xaa\xe5\xe7\xe6\x24\xcf\x7c\x6d\xb3\xae\xd3\x24\x07\x8a\xc8\x34\x64\x7e\xfb\x3b\x3a\x35\x86\xf5\xcb\x63\x37\xcb\xec\x2c\x1f\xff\xa6\xc9\x24\xa5\x23\xac\xd4\x3b\xb3\xc8\xcf\x61\x52\x08\x8d\xe6\x60\xbc\x07\x4d\xfa\x99\x75\xcf\x6f\x99\x99\x80\x73\xa2\xfc\xe9\x76\xf5\xed\x1e\xda\x17\xfc\xc0\xba\xf7\xf8\x4d\x20\x52\xc2\x58\x7e\xe4\x0d\x10\x2d\x79\x5e\xbe\x79\x07\x7c\x74\x23\x26\x10\x96\xcd\xc4\xf1\x3e\xae\x3e\xf2\xe2\xa1\xba\xda\x53\x69\x02\xcd\xa9\xe2\x40\xed\x92\x77\x50\x1f\xfa\xb8\xdc\xb0\x50\x93\xcb\xbf\x85\x37\xd0\xb0\x6d\xaa\xbc\xa4\xff\x19\xec\x96\x86\x65\x51\x32\x24\xa4\xea\x1c\xc5\xf9\xbd\xc3\xb0\x2c\x83\x73\xe7\xfb\xe4\xae\x23\x10\xe8\x80\x57\xf7\xd0\xb4\x2f\x55\x51\x3c\x9d\xda\xe3\x69\xe2\x15\x9a\x08\x6d\x1d\xd3\xf2\x19\xc3\x01\xdb\x6e\x7b\xb1\x4a\x13\xa3\xb9\x67\xe2\x90\x13\xb9\x0d\x15\x3b\x9f\x07\xcd\x78\x26\xe6\x19\x5a\x8d\xb2\xd6\x26\x63\x9f\x0b\x68\x4d\x55\x1f\xee\x0a\x78\x1b\x80\x53\x4d\x2c\x6c\x3f\x69\x79\x3a\x3c\x99\x25\x14\x45\x55\x95\xcd\xf6\xf3\xd8\x03\x4f\x4d\xa2\x22\xf2\xb2\xee\x1f\x6f\xbe\x5f\x74\xbe\x85\xec\x02\xb4\xd4\xff\x7d\xe0\xb1\xfc\xff\xf9\x9f\xfe\x0e\x74\x46\xa1\x20\xe5\xf7\x76\xea\x2c\xb0\x95\x99\x2c\x88\x8c\x9b\xc2\xaf\x65\xde\xfe\x1f\xd0\xb8\x69\x11\x3a\x67\xd1\xb1\x3c\xe7\x7f\x83\xd6\x69\xf0\x3e\x32\x6e\x45\x0f\x7a\xe1\xd4\xf9\x32\xb6\xc9\xb2\x80\xca\x5e\xbe\x09\xe6\x01\x9a\xa7\x12\x09\xc2\x36\x83\x69\x38\xe3\x01\x26\x13\x26\x73\x0c\x54\x8e\xe8\xda\xe6\x33\xc6\xbf\x24\x32\xed\xf9\xd2\x1d\x5e\xef\x6e\x28\xdb\x98\x19\x29\xb5\x76\x1d\x03\xdf\x9e\x37\x53\x8a\x16\xa3\x20\x4a\xb0\x2f\x53\x7c\x9f\x33\xfd\x7f\xf1\x7e\xdc\x85\x74\x24\x08\xe9\xff\x8d\xda\xbe\x36\xfb\x9e\xe0\xcf\xe8\xd4\xca\xac\x9d\xca\x86\x1a\x69\x66\x8a\x11\x46\xab\x8c\xba\xf2\x7a\x1e\x35\x0b\xc4\xef\xbf\xa4\xd6\x92\x2a\xe5\x76\xf3\xb8\xc7\x43\x45\x8b\xf0\x5c\x99\xda\x56\x67\xc5\xb8\xcc\x68\x93\x92\xe2\xd4\xbe\x2a\xf4\x10\x6d\xf7\xe5\x7e\x61\x90\x05\x9e\xf1\x75\x43\xad\xe8\x4b\x6c\xd7\x2d\xba\x46\xca\xc9\x58\x60\x54\xcc\x70\x58\xec\xaf\xc3\x70\x83\x3a\x32\xc3\x6c\xf6\x0d\x34\xfb\x4b\xae\x3f\x63\xb2\x80\x32\x08\x4d\xdf\x51\x7e\x53\x40\xd3\xf8\x2d\xeb\xea\xc4\x14\x41\x10\x58\xed\xd2\x2e\x54\xa5\xca\xbc\xfb\x7b\x18\x08\x73\x4e\xf9\x6f\xaa\x03\xde\xfc\xbc\x69\xae\xfa\xb7\x22\x08\x33\x61\x51\x1c\xa8\xf6\x8b\xa2\xf8\x51\xb5\x8e\x2b\xae\x0b\xbf\x5b\x78\xc3\xe5\xa7\xd5\x2e\x1f\x9f\xc6\x54\x44\xf9\x26\x89\xed\x58\x2d\x46\x04\x4c\x87\x94\xc9\xdf\x91\x93\x78\xd3\x59\xd9\xb6\x0b\xe4\x2f\x32\xc2\xe7\xf9\x20\x82\x2e\x98\x4e\xfb\xfa\xe3\x59\xe2\x67\x38\xf9\x45\x10\x05\x48\x61\x00\x09\xb9\x8c\x78\xb7\x06\xaf\x26\x06\x86\x0e\x5c\xe3\xc2\x68\xfb\xe6\x2d\xcb\xfa\x48\x08\x53\x04\x29\x24\xe0\x13\x05\xb7\x04\x7f\xa6\xd6\xc4\xfe\xb0\x04\x6a\x69\xfa\xb6\xb8\x39\x7f\x37\x11\xa4\x2a\xa3\x22\x24\x51\x89\x4c\xea\x68\xdd\x51\x4d\xad\x03\x77\x15\xb9\x6a\x79\xf9\xb7\x5a\x0e\x44\xc0\x93\xc4\x35\xe8\xa9\x1a\x5b\xa8\x3f\xbf\x11\x4f\x4b\xe1\xaf\xcb\xd3\x88\x76\x82\xe6\x24\x5d\x4d\x63\x8a\x89\x14\x01\x17\x29\xf7\xf4\xb5\xbb\x23\x7c\x1e\xb0\x6c\x77\xbd\x58\x7c\x7f\x25\xc1\xd1\x6a\xfb\xe5\x2a\xd7\xf3\x65\x47\x11\x70\x9d\x44\x9e\x25\x0c\xde\xb1\xef\x3e\x9e\x42\x3e\x45\x90\x25\x19\x73\xb8\x96\x1d\x61\x23\x1d\x50\x64\x1c\xc6\x89\x20\x33\x51\xc0\x7a\x52\xa4\xe7\x53\xdd\x74\x3e\xcd\x5c\xa8\x24\x02\x11\x28\x72\x1f\x89\xfa\xe0\xce\x2b\x1c\xf4\xdc\x07\x22\x10\x22\xca\x1c\x4f\xc1\xe2\x78\x2c\x3c\x46\xf4\xaf\x94\x7a\x44\x20\xa4\xd5\xf8\xe9\xbc\x4a\xa7\x89\x62\x81\x2f\x3d\x25\x84\x08\x20\x05\x82\x57\xfd\x15\x89\x6f\xec\x4f\x50\x2c\xa0\x5a\xf8\xcd\xfd\x62\xfd\xb0\x5b\x3c\x3c\xbd\x3e\x6e\x77\xab\xed\xf7\xfe\x78\x92\x51\x2d\xee\x69\xf1\xd2\xff\x49\xc4\xa2\x4f\x8b\xde\x55\xb5\xef\x88\x99\x33\x56\x22\x50\x46\x06\x0e\xd5\xd8\x59\xfc\x99\x7a\xa3\x08\x74\x90\xb9\x9c\xa1\xdd\xad\x6c\x8b\xe1\x70\x9d\xe9\x30\xb6\x15\xc9\x7f\xdc\x2f\x36\xdb\x81\x06\x90\x08\x34\x53\x14\x19\x59\xe8\x16\x6d\xfe\x97\x4c\x52\xb3\xbf\x8a\x8c\x04\x8d\x6f\x3a\x3b\xe1\x49\xce\xfe\xce\x26\x22\x02\x13\xc5\x34\xa5\x97\x79\x4b\x05\xfd\x7c\x9a\xfb\x1f\xfd\x90\xe1\x82\xc8\xa1\x1d\x83\xca\xe2\xad\xc6\x41\x61\x4a\x04\xa6\xf3\x62\x2d\x2c\xe5\xc2\x1b\x15\x81\xd1\xe0\x44\x33\x4e\x65\xfb\x32\x86\x97\x88\x30\x08\xa4\xa7\xc4\xbb\x19\x22\xfc\xfc\xe1\xd0\x50\x4d\xcc\x67\xb9\xad\x62\xf1\x00\x50\x3a\xbb\xa4\xc3\x80\x05\x34\xd5\x76\x3e\x1f\xeb\x36\x38\x11\x86\xa9\xa4\x56\xc1\xc3\xe7\x28\x84\xee\x0e\x20\x65\x5d\x3f\x11\xea\xed\xbe\x46\xa4\xdb\xf1\x89\x65\x11\x86\x32\xb1\x9c\x4b\xcd\x00\x2c\x37\xe7\xe9\x8a\x30\x92\x49\xe2\x92\xb3\x3f\x46\xca\x5e\xfe\xb8\x89\x88\x84\xb0\x33\xa7\x55\x55\x3e\xd7\xf9\xbf\xb1\xa7\x86\xb9\xf8\x58\x61\x8c\x86\xaa\x87\x1b\xa7\x38\x37\x79\x83\x49\x1c\x98\x74\xc4\xb5\x70\x53\x1d\x8e\xd8\xe6\xdd\x7c\xa0\x94\x70\x33\x84\xce\x89\x30\x31\x4a\x58\x80\x0b\x09\x41\xbd\x5a\xf7\x7d\x72\xd5\x34\x0c\xd4\x90\x33\xd0\x51\x01\x4d\xf8\xa1\x44\xc8\x13\x46\xad\xd3\x6f\x79\x5d\xac\xf5\xb6\x9a\x90\xed\xb9\x51\x59\x18\x29\x6f\xee\xb7\xd5\xb2\x7b\xd6\xe1\x0b\x11\xc2\xb5\x49\x90\x93\xbc\xac\xab\x77\xac\xd7\x87\xe3\xe4\xa7\x64\x10\xc6\x2e\x4f\x78\x26\xfa\x9c\xdb\x8a\x42\x19\xdb\x04\x0e\x61\x46\xbf\x63\xed\xcd\x4b\x28\x55\x96\x8c\xfc\x03\x2f\x50\x21\x42\x95\xda\x6a\x9e\xef\x01\x1f\x4d\xe2\x50\x41\xaa\x46\x0d\x3d\xcf\x88\xf5\x78\x66\x29\x2d\xc8\xfd\x72\x92\x4b\x0e\xb4\xe8\x0e\x6a\x8e\x5e\x0f\xa8\x33\xe3\x63\x60\xaa\x08\xb5\x48\xd2\x9e\xaa\x75\xca\x61\xec\xc6\x60\xac\x3c\xe7\x4c\xe7\x2c\x35\x4b\x6a\xd5\x58\x38\xbd\xaf\x39\x8e\x00\x11\x1a\x95\x86\x62\xd0\x21\xf8\x34\x09\x73\x04\x0b\xc2\xc4\xcf\x1e\x57\x09\x7f\x2d\x49\x9a\x38\x3f\xe0\x74\x68\x6a\xbb\x86\x1a\x12\xd4\xf8\x80\x37\x1c\xba\x0a\x83\xf7\xcf\x42\x01\x1c\xfa\x44\x13\xa9\xa6\xcd\xe7\x9a\xae\x24\x8d\xb2\xff\xf6\x17\x32\xb6\x60\xfb\x2d\x37\x16\x29\x77\xcd\x57\xfe\x82\x9a\xdb\xc1\x82\x59\x6c\xc3\x9a\x74\xf8\x4f\xff\x76\x19\x4b\x43\x8f\x09\x9a\x14\xb1\xfc\x00\x13\xc7\x36\xd4\x70\xb9\xff\x9f\xde\x34\xb0\x28\x50\x14\x3e\x40\xd3\xe0\x80\x06\x45\xb0\x98\x07\x89\x45\xf6\x74\x33\xb5\xac\xb4\x63\x9c\x25\x89\xf1\x6d\x65\xff\x63\xb8\xf2\xfd\x79\x2a\x61\x56\xbf\x49\x55\xa5\xbe\x80\x08\x0a\x16\xeb\x98\x62\x69\xdb\x07\x44\xf3\xf0\xcc\x83\xe5\x67\x24\x4b\x82\xd0\x23\x2c\x37\x6d\x75\xbc\x60\x79\x11\x2c\x8d\x23\xa2\x48\x25\x08\xe5\x99\xcb\x5a\xb0\x14\x80\x30\x7a\xef\x8d\xda\x60\x51\x5c\xdd\x56\x86\x86\x85\xf1\x20\x4d\xd8\x80\xb3\x03\xca\x99\xbc\x81\x60\x9c\x65\xb6\x4d\x4b\xd2\x5e\xd7\x59\x8d\xee\xa5\x35\x47\x98\xce\x79\x26\x12\xa9\xdc\xec\x7c\xaa\xdf\xe8\x06\xc7\x73\x52\xa4\x9a\x50\x88\x8d\xda\xa3\x3e\x15\xf8\x85\x36\xf7\x17\x98\x4c\xc1\x84\xd4\xe0\x78\x8e\x20\xaf\xdc\x4a\x68\xa6\x3f\xa6\x94\x89\x06\xea\xe1\x13\xe0\xb2\x60\x42\x27\x14\xe4\x55\x1f\x58\xd7\xb9\x63\x45\xb4\x18\xc6\xe6\x2a\xc8\x5e\x30\x08\x41\x67\xfe\x2b\x50\xc1\xef\x16\x8b\x16\x9e\xb1\xfe\x5e\x9d\xbc\x09\x61\x10\x22\x73\xcd\x76\x6d\x2f\x65\xeb\x8f\xa1\xa2\x3a\x8e\xda\xe7\x7e\xb8\x84\x4c\x3a\xf1\xc5\xd1\x9b\x70\xf1\x8d\x4f\x19\x84\x2c\xeb\x4f\x90\xa4\xa0\xb7\x59\x6f\x1f\xaa\x73\x6e\xc5\x1d\x55\x3a\xd6\x91\x17\x0e\x1d\x51\xad\x4f\x28\x43\x04\xd3\xcc\x3a\x88\x3d\x75\xb8\x2f\x28\x76\x51\x6f\x5e\xbe\x75\x33\xd5\x91\x68\xfc\x0f\x6b\x0a\xfe\x07\x22\x24\x0a\xb8\xc5\x01\xfe\xed\x03\x70\xc1\x48\x30\xef\x7f\xfd\xef\xff\xf5\x03\xca\x87\xbc\xdc\x8f\x5a\xee\xaf\x75\x30\x0b\x86\x51\x9a\xb8\xfa\x81\xc2\xe5\x25\x1d\xef\xfc\xac\x19\x9b\x06\x13\xd9\xde\xb6\x6f\x70\x38\x77\x41\x0b\x66\x32\x41\xfb\xb6\xdf\x6c\xa6\x97\xf6\x74\x7f\x22\x62\xca\x72\xbb\xbe\x6e\x6e\x87\x8c\x40\xdd\x01\xf0\x12\x45\xcb\x53\x4e\xf3\x68\xd6\x6b\x8f\xa2\xc0\x62\xfe\xb0\xdd\x6f\x6d\x3f\xe7\xb9\x55\xcc\x5f\x2c\x8a\x83\x24\xec\x19\x3b\x17\x9d\xb1\x6a\xa6\x3b\x51\x14\x25\x16\xa4\xff\xab\xaa\x0b\xfd\x2b\xd7\xf8\x96\x9b\x56\xf5\x0d\x8f\x22\x4a\xc2\x84\xd0\xe9\x24\x7d\x72\x73\x3a\x8e\xee\x37\xcd\x12\x9f\x25\xf9\xcf\x53\x55\x9f\x0e\x23\x6d\x7b\x11\x71\x19\xd0\x97\x3b\x16\xd0\xe6\x65\x1f\x53\x44\x5c\x43\xc8\x7c\x07\xee\x33\x49\xf0\xf5\x5b\xfc\xe4\x49\x39\x06\xc2\xe6\xd4\xba\x58\xe6\xb5\xc1\x7a\x7d\x3b\xf2\x6f\xa2\x2c\xd0\xe4\xae\xde\xa2\xca\x1b\xb7\x4b\xfb\x1f\xca\x5c\xcb\x2d\xf9\xfe\xab\xdf\x79\xd3\x36\xdd\xf6\xa9\x9f\x5d\xb1\xc4\xe1\x6d\x44\x24\x22\x45\x6f\xfe\x11\x7f\x11\x63\xe0\xa0\x30\x2a\x22\x91\x32\x0a\x3a\xee\x4f\xea\xfd\x06\x9a\xfd\x39\x14\xbd\x36\x6b\x66\x1d\xc5\x48\x18\x9d\x58\x48\xa3\xcb\xae\xac\x9b\xe6\xd4\x59\xf4\xc7\xea\x30\x15\x3e\x12\x11\xa4\x2a\x73\xaa\x7e\xb7\x96\x05\xfa\x22\x22\x8c\x00\x54\xd6\x27\x93\x0b\x84\x2e\xd0\xda\x38\xdb\x38\xbd\x9c\x8c\x09\x6a\x49\xaf\x62\x5b\x23\x36\x3f\xc1\xf2\x3d\x4f\xec\x53\x24\x05\x4f\x3c\xc2\x83\x0a\xe8\xcd\x1f\x33\xd9\x38\x11\x29\x96\xa6\x67\x11\x19\x5b\xc0\x99\x9f\xae\x0a\x45\x60\xb5\x6e\xd0\x58\xb9\xd2\x33\x8b\x63\x3f\x04\xed\x97\xb2\x89\x1f\x8f\xef\xb9\xb8\x92\x31\xf4\x52\xce\xd0\x18\x1f\x55\x8f\xfd\xfb\x48\xeb\x28\xa4\x92\x43\x01\x87\x03\x0c\xea\xe8\x22\x42\x96\x44\xb6\xbf\xd5\x19\xb4\x25\x34\x13\xb0\x84\x88\x90\x87\x99\x1c\x50\x72\xd2\x31\xa4\x14\x8f\xd7\xf6\x6f\x26\x4d\xe3\x22\xc2\x2c\xa3\x59\xe4\x72\x32\x70\x9c\x5e\x34\x93\xa1\xd7\xe5\xa5\x36\xf8\xe5\xe9\x73\xa0\x87\xd7\x7f\xd7\x38\x48\xad\xd2\x5b\x4f\xda\xb9\xea\x9b\x7f\x44\x1c\x28\xbb\xcf\x0f\xb0\xfc\x94\x60\x9c\xa3\x1d\x10\x71\x18\x48\xca\x99\xce\x86\x8d\xe3\x5f\x65\xc2\x4a\x54\x6d\x4e\xef\xf0\x09\xfe\xe7\x62\x88\x28\x46\xbf\xd9\x43\x5d\x7c\xde\xe7\x06\xef\xab\x5e\x4d\x65\x74\x7e\x92\x26\x91\x67\x13\x27\x5d\x98\xce\x05\xb9\xab\xcf\x1e\x52\x9c\xc8\x84\x8a\xd7\x45\xd5\xb6\xd5\x5a\x63\xd9\xe6\x26\xef\xdd\xe6\x38\x35\x11\x55\x32\x3c\x2f\xc5\x2e\xf2\x47\x38\xe3\x3e\x3d\xff\x33\x2f\xbf\xe8\x9d\x16\x31\xd7\x32\xb3\xe2\xb7\x75\xf1\x79\x9e\x68\x77\x88\xcf\x1e\x75\x24\x62\x91\xb1\xd4\x36\x50\x34\xfb\xdd\x11\x9a\x86\x6c\xde\xf8\xcd\x09\x47\x0c\xe8\x76\xbf\xa6\x7f\x0a\xa1\x02\xa2\x3b\xdf\x11\x8d\xd1\x74\x43\x8c\x21\xcc\x08\x1c\xff\x7e\xfc\xfc\x56\x41\x31\xd2\x4a\x12\x31\x24\xb6\x13\x63\xb9\xde\xfe\xb0\x6a\xb1\xfe\x88\x0c\x80\xca\x9a\xae\x4b\x7f\xa0\xf0\x2d\xe2\x2e\x1a\x8d\x6c\x2f\x42\x5e\x4e\x05\x98\xba\xc3\x8a\xa6\xb4\x02\x29\xe1\x6d\x58\x20\x14\xb1\x34\x5a\x86\x03\x37\x66\xa8\x30\xf4\x95\x7f\x17\xab\x94\x67\x03\xdd\xdc\x39\x87\xdc\x8f\xe4\x82\xc8\x2b\x88\x63\x7b\x5b\xb5\xfd\x54\xd5\x01\x52\xaa\xa0\xd2\x7a\xf5\x71\x85\x47\x52\xc4\xda\xed\x87\x1b\x68\xab\xb3\x4b\x13\x63\x1a\x13\xed\x8a\x6d\x9a\xb6\xc1\xd7\xfc\xc4\xc5\xd4\xb2\x8e\x1a\x6c\xd5\x9e\xf2\xa8\x13\xbb\x11\x23\x97\xe4\xf9\xe6\x4e\xda\x62\x14\xee\xc5\x86\x69\xca\x12\xac\xef\x9f\xb6\x63\x7c\x9a\x88\x0d\x17\x59\x44\x73\x32\x2f\x8a\x6d\xf5\xad\x9a\x2c\x55\x23\x75\x6c\x01\xb9\xe8\x60\x82\x22\x09\x43\x99\xb8\xd0\xd5\x59\x8e\x59\xec\xab\x1b\xcd\x04\x23\x6f\x6e\xd5\xee\xc9\x20\xdd\x2e\xfd\x75\x22\x16\x68\xcb\x98\xe7\xf4\x3c\x06\xe5\x26\x91\x44\x3c\x8b\xdc\xee\xbb\xfa\x7d\x24\x79\xa0\xb9\xae\x19\x91\x24\x91\x95\xd0\xa3\xec\x6b\xdf\xf8\xd1\x4f\xbc\x24\x89\x13\xee\xb5\xb2\xa9\xa6\xbb\xa8\x65\x7e\x4e\xcf\x26\x89\x4c\x42\x97\xc0\x70\xea\x41\xa8\x67\xc1\x6c\x22\x49\xb9\xa4\xba\x55\x75\xc4\x72\x5b\x83\x1e\xfc\x4a\xaa\xad\x46\xc8\x1e\x8b\xe3\x25\x8b\x6f\x3f\xc8\xaa\xf1\xfd\x7c\xba\xbf\xf3\x8b\x3f\xe1\x41\xc8\xac\x0a\xfa\x71\x92\x05\x4f\xb2\xa0\x97\xce\xb7\x72\xe0\x1e\x02\x3c\xbe\x6c\x16\x07\x41\x36\xc8\xd8\x91\x16\xc6\x15\x39\x89\xb1\xfd\x4c\x44\x9c\x72\xe9\x49\xa6\xbb\x0d\xb3\x69\x6f\x97\xf3\xf3\x30\x11\xa8\x12\x57\xac\x79\xa9\xd4\x3b\xc5\x61\x2e\xa7\x1f\xfa\x31\xa0\x80\xd6\x0a\xb6\x7b\x6f\x8d\xfd\x11\x0c\x32\xb7\xc6\xb1\xdd\x57\x1e\x9d\x66\x9f\xd8\x39\x2a\x89\xd4\x56\x09\x9f\x6a\xf5\x53\x57\x7b\x9a\xfb\x77\xe7\x28\xc7\xfe\xdf\x38\x52\x36\x1b\xf2\x4f\x94\x49\xba\x61\x86\xfb\x44\xf4\x39\xae\x5a\x4f\x3a\x97\x45\xa2\x42\x2b\x14\x99\x4f\xf4\x00\xfc\xe1\x94\x6b\x12\x23\xbc\xfd\xb1\xde\x3c\xbd\x6c\x5c\x57\xfc\xee\x7e\xfd\xb0\xf6\xe9\x97\x44\x09\xc8\xac\xa2\x68\x5e\xbe\x0f\x7d\x77\x77\x5c\x67\x48\x94\xb0\xea\x5c\xd7\x70\x47\x30\x10\x81\xf0\x3d\x8c\x16\xf6\x35\xb9\x01\xcc\x42\xca\x31\x3e\x7c\x2e\x9d\x9b\x97\x4d\x56\x9c\xe1\x42\xf6\x2f\xf1\x1e\x41\x63\x2d\x2b\x2f\x0d\xd3\x7f\x29\x93\x59\x4a\xcb\xed\xa0\xaf\xf1\x8a\x05\x4a\x8c\x48\xa4\x3c\x2b\x60\xe8\x6f\x90\x97\x0d\x35\x39\xce\x8e\x4f\x03\xc6\x89\x1b\x00\xdb\x3d\xd5\x91\xbd\x25\x4f\xc3\x88\x47\xd1\x99\x14\xf4\x77\xbb\xaa\xe1\xa2\x0d\x7a\xe2\x6d\xce\xfe\xa7\xbf\x9e\x36\xb4\xd1\x79\x9c\xcd\xee\x38\x68\x3e\x15\x29\x0b\x2c\x3a\x40\x57\xc3\x76\xd1\xf9\x40\x2c\xed\xfc\x3d\x67\x70\xa8\x95\xa0\xbc\x1b\xd2\x2d\xb8\x41\x51\x10\xd3\x20\xe7\x5d\xf9\x00\x66\xb0\xeb\x38\xaa\xc5\xe1\x5e\x93\x46\xb1\x89\x58\x8f\x29\x71\x4d\x44\x70\x85\xa2\x4c\xa4\x71\x2c\xb9\x55\xc1\x6b\xf3\x1a\x17\xbf\xf3\x19\x31\x38\x91\xc6\xce\xb0\x6e\x9a\xa3\x33\x0b\xd3\x12\xcc\x78\x5e\xa4\x31\xc6\xc2\x45\xbd\x9b\x23\x28\x24\x6a\xad\xf1\x2f\x27\x21\xa7\x54\x33\x75\x73\xde\xe7\x25\xfe\xac\xab\xde\xc6\xa5\x49\x24\xa9\xe2\xf3\x00\x79\xe9\xb9\x17\xfa\x63\xc2\x72\x1f\x6e\xf7\x18\x06\xab\xed\xf7\xe7\xcf\x1a\x0e\x79\xff\x25\x12\x0c\x29\xe2\x56\x55\x69\xc5\xdf\x17\xcf\x6b\x42\x22\x9c\x07\x68\x5a\x9e\xe4\x40\x0f\x79\x67\x44\x9a\x06\x9a\xd0\x73\x5e\xce\x61\xa5\xdf\x90\xa4\xfc\x16\xa5\x76\xdd\x89\x5f\x86\xd8\x69\x9a\x59\x24\x4c\x59\xb9\x1d\x60\xf2\xd4\x5c\x58\xc8\xcf\x77\x30\xf9\xbf\x87\xde\x45\x9a\x89\x80\xea\x47\xb4\x49\x77\x0e\x0d\xea\xf9\xad\xfa\x2f\xff\x1d\x7c\xb8\x0c\xc0\x32\x67\xc0\x3b\xbe\x76\x5f\x8c\x18\x89\x87\x31\x59\x9a\x81\x4a\xcf\x05\xfa\x51\x30\x97\x8a\x28\x0e\x5d\x33\x7f\xfe\x41\x09\x89\xce\x85\xbe\x3b\x61\xe1\xf6\xc7\x2f\xb2\x33\x29\x68\x19\x38\xc0\x48\x17\x6d\x2e\x27\xe2\x1b\x22\x55\x49\x0c\xfc\xac\x70\x7e\x79\xa9\xff\x18\xde\xa7\xca\x80\x48\xca\xe8\xd3\xdc\xe7\x4d\xfb\x00\xd3\x29\xa5\x74\x4c\x68\x52\x57\x26\xf4\x6f\x56\x21\xf0\x73\x6d\x7e\x8e\x09\x51\xa4\x9a\x69\x03\xbd\x4a\x4c\x4b\xdf\x9b\xd2\xaf\x23\xd4\xb6\x1b\x8c\x49\x4a\xd2\x91\xe5\xe9\x30\x50\xfb\xf1\x07\x79\x96\x98\x69\xb6\x7d\x5e\xea\x45\xa4\x98\x45\xe4\x97\xd0\x22\x18\xa8\x2a\xac\xcf\x97\xcb\x0c\x39\x7e\xcb\x53\x3d\xdf\x02\x27\x52\x13\xb1\xa8\xff\x82\xd6\x1d\xf8\x82\x96\x50\xa4\x26\x09\x7c\x0b\x33\x85\x3b\x33\xac\xd1\x82\x87\x71\xcc\x5c\xe2\xfd\x76\xe9\xdd\x50\x1e\x02\x10\x97\xcf\xdd\xfa\x71\x71\xbf\xd9\x6e\xb6\x2b\x2f\x11\x25\x78\x28\x43\xea\x9a\xd8\x91\xfa\xe5\x60\xea\x8f\x37\x51\x1e\xc5\x48\xea\x19\x3f\xa1\x55\xfb\x7b\x68\xda\x61\xdb\xaf\xe0\x51\x92\x51\xb6\xfc\xdb\xb7\xe7\x9b\xe1\x02\xe1\x91\x63\xa9\x7b\x7f\x80\xdf\x03\xc6\x53\xc1\x23\x61\x0b\x08\xbb\xbc\xb1\x29\xfd\xd9\xd7\xc4\x23\xc5\x30\x3a\x07\xc6\x55\x3d\x02\x41\x0b\x1e\xc7\xb6\xf6\x65\x5b\x03\x0e\x79\x9f\x65\xe1\x71\x1a\x85\xd2\x65\x5f\x4c\x55\x1f\xce\x4e\x97\xe5\x69\xe9\x3f\x3e\x8f\xbb\xa8\x89\xa0\x24\xe4\x18\x8c\x63\x78\xbf\x32\x78\x17\xde\x69\x1b\x9d\xd5\xed\x4d\x2f\x1e\x27\x78\xca\x4c\x46\xc0\xca\xaa\x5a\xe6\x96\x08\xf5\x36\x37\x66\xfe\x3b\xf2\x54\xc6\xe4\x22\x36\x45\xf5\xeb\xf6\xd4\x57\xcb\x79\x2a\x6d\xab\xde\x4e\x55\x87\x23\xd4\xf8\xc7\xf0\x33\x8c\xb3\xf3\x3c\x55\xb6\xbe\x72\x3c\x6b\x86\xdc\xe7\x87\xbc\xff\x1a\x1c\x38\x70\xdf\xd2\xa6\xb7\x15\x05\x26\x57\xc9\x70\x04\xcf\xb2\x94\xea\xb5\x12\x4b\xa4\x66\xc3\xfa\x73\x08\x48\x15\x3c\x03\x2e\x6d\x61\xf2\x23\x1f\x0a\xe6\x0a\x9e\xa9\xd8\xb7\xa4\x3f\xe2\x2f\x47\x47\xc5\x46\xcb\x94\x67\x68\xd9\x43\x4d\x75\xaa\xdb\x3d\xe1\x3d\x1e\xf2\xb2\x73\xc1\x6f\x07\x57\x12\x61\x18\xa9\x1e\x6c\x02\x6f\xb8\xf2\x5c\xbf\xfd\x00\x0c\xf4\x99\xa4\x63\x59\xc9\x75\xa9\xf3\x1a\x55\x37\x17\x27\x4f\x04\x41\xaa\xd0\xe9\xf8\xd6\x5a\x4d\x23\x46\x0e\x80\xd4\x51\xf2\x78\x2a\x9a\xff\x19\x0d\xa4\xe0\x20\xb9\xb2\x04\xa1\xeb\x9b\x27\x52\x87\xeb\x2f\x2b\x13\x46\xad\x66\xff\xf5\x8f\x7f\x6e\x50\x9d\xea\xbc\xcd\xb1\x9f\xaa\x32\xd5\xe1\x19\xaa\x4a\xfc\x13\x7f\xd8\x9c\xb4\x33\x9e\xe7\xff\x97\x8d\xe0\x5b\x83\xff\xd7\x6f\x12\x5c\x62\x48\x85\xe6\xa2\xba\x44\x06\xce\x6f\x73\x5c\x85\x49\x60\x5b\x4f\x41\xbf\x4c\x7d\x10\xae\xd2\x28\xf1\xcd\xc8\xdf\xb1\x28\x7c\x75\x84\x53\xb3\xdd\x39\xd1\x85\xf9\x33\xd6\x3f\xf7\x95\x67\x5c\x98\xfc\x86\xea\x85\xbb\xbc\xe3\xf8\x02\xbf\x46\x6c\xe6\x7e\x24\x1a\x4a\x54\x6c\xf6\x58\xb4\xe7\x92\xde\xe8\x9e\xb4\x0a\x2d\x17\x22\xb4\x50\xa3\x13\x90\xf5\xf7\x85\x59\x4c\x6f\xc0\x93\xd6\x5c\x6d\x8f\x99\xfd\x77\x9e\xa7\x52\x70\x54\x41\x14\xf5\xd5\xd9\xa7\x0f\xac\x57\x2f\x37\x8c\x65\x57\xb3\xf7\xa3\xbd\x81\x9b\x2c\xf2\x8c\x92\x14\x6c\xcc\x66\x04\xb3\x20\x94\x94\x0a\x35\xbb\x23\xa5\x7f\xff\xf0\x7f\x8f\x42\xd9\xbd\xbd\x7d\x5e\xb6\xaf\x2f\xf7\x7f\x8c\x4d\xf1\xe8\xdd\x64\x81\x4a\x7d\x85\x84\x74\x1f\xfe\x98\xcb\x62\x64\x61\x9a\xc8\xf4\x2c\x60\x47\x24\x4a\x7f\xf4\xc7\x52\xe5\xc8\x6b\x86\xe4\xb3\x22\x0b\x33\xce\x32\xdb\xfc\xa8\x3f\x7b\xc9\x56\x91\x85\x42\xd3\xc7\xfd\x76\x82\x5a\x83\xd3\x89\xae\xc6\x31\x69\xc6\xd0\xce\xa3\x89\x1a\xc2\x1f\x33\xee\x41\x16\x65\x22\xea\x55\x0e\x0c\xd6\xb5\xa3\x96\x9a\xc7\x0a\x65\x89\x62\xcc\x39\x27\x3b\x28\x8a\x1d\xa1\x76\xfc\xfa\xca\x52\x65\xa8\xb1\x4a\x5b\x6e\x74\xc7\x31\xd7\x8c\xea\xd6\x19\x07\x4e\xdc\x43\x8b\xf5\x66\xdd\xff\x4d\x25\xe0\x5b\x53\x16\x7a\x12\xd0\x65\x99\xb6\x12\x15\xdd\x9e\x0a\xf9\x39\xa7\x36\xb4\xb8\x99\x08\x2d\x57\xc9\x33\x92\x6e\x5e\x91\x97\xd8\x6c\xab\xce\x41\xee\x7f\x99\xd2\x54\xd4\x07\x38\x6c\x5d\x13\x19\x70\x61\x64\xaf\x08\x5f\x54\xed\x7d\xf5\xf6\x38\xb9\x07\xc9\x03\xf2\x5d\xe4\x9b\xec\x22\x98\xdd\x9f\x58\xf5\xd7\x95\x9a\x6b\x70\x82\xd6\xe5\x50\x38\x64\xb4\x30\x33\xa9\xad\x62\xcc\x27\x42\x9d\xdc\x0f\xf6\x39\x77\x5c\x45\x36\xfc\x7e\x3a\xb5\xaa\x3a\x8c\x72\x68\x99\x4a\x91\xf2\x07\x3d\x4b\xf1\x5d\x55\xdf\x57\x50\x2e\x5a\xdb\xbe\x35\xff\x8b\xca\xd8\xa4\xdd\xcd\xd3\x72\x74\x35\x1d\xc5\x94\x26\x80\xa2\xc8\xaf\x2a\x8d\x88\x4c\x0b\x99\x45\x83\x26\xc3\x9e\x33\x7b\x72\xe3\x18\xf7\x40\x09\x47\xa1\xe8\x79\xb7\xc7\xd7\x33\x81\xa5\xc4\xed\x3c\x5b\xda\xe8\xfb\x7c\x91\xfd\x92\x93\xd1\xca\x92\xfa\x7a\xde\x35\x07\x96\x9d\x1a\x81\xc9\x49\x68\xd0\xed\x50\x1f\x58\xb7\x03\x7d\xb1\x4b\x2e\xac\xf1\xa9\x22\x48\x42\xad\xbc\x3b\x58\x68\x05\xb5\x1e\x10\xa4\x0c\x03\x73\x11\x32\x46\x05\x8a\x37\x78\xf3\x36\x5a\xb0\xc4\xf2\x4d\xff\xab\xca\xcb\x21\x2f\x9c\x33\x75\x83\x35\x27\xa2\xcc\xa6\x6f\xdf\xb0\x3d\x2b\x94\x58\x71\xdf\xf5\xb9\xe9\x52\x88\xd8\x60\x14\x7a\x22\xc6\xc3\x11\xca\xcf\xd9\xe4\x92\x48\x52\x16\x59\x8e\xb0\x0f\x84\xe2\xa1\xfa\x98\xef\xf4\xec\x06\x4a\xda\x7e\xee\x1e\x46\x2e\x62\xe7\x7f\x51\x4b\xc0\xb1\xc6\xce\xf1\xf9\xd9\xd3\x7d\x58\x36\xbd\x6f\xf9\x07\x96\xa4\x38\xe8\xff\xd2\xfb\xd9\xdd\x96\x46\x60\xc6\xc3\xa9\x08\xb3\xf9\x69\x28\xb2\x98\x19\x31\x54\x08\x51\xd5\xd7\xe1\xa0\xc8\xd0\xe6\x73\xed\x16\xd0\x85\x1e\x7f\xe2\xe7\x5d\x5d\x1d\xa6\x5c\x65\x6e\xbc\x08\x43\xaa\x31\x80\xd6\xc4\x07\xd4\x59\xc5\x4b\xf0\x90\x00\x61\x71\xd7\xd5\xb1\x5d\x97\x77\xaa\x7c\xe8\x3e\x95\x9f\xc6\x02\x30\xf3\x3e\xdb\x1d\xaa\x3d\x6c\x27\x7c\x48\x42\xc8\xd0\x90\x55\xce\x55\xf5\x13\xf1\x3d\x5e\x9e\xd9\x2c\x85\x90\x8c\x53\x17\x80\xdd\xa4\xef\xba\xc8\xc4\xb9\x70\xe3\x9b\x50\xae\xd2\xd7\x59\x67\xa8\x2d\x3b\x78\x3b\xd0\x74\x11\x42\x67\x82\x88\x17\xc8\x6a\x3f\x95\x8e\x7d\xb5\x3f\x2a\xd0\xf4\x7a\x2b\x6b\x55\x0d\x3c\x38\xa1\x65\x48\x79\xa5\x5d\x8f\x1b\xb2\xa4\x13\x03\x40\xec\x70\x22\x6a\xa5\x7c\x2b\x65\x4f\x0e\x39\x7e\x62\x13\x45\x64\x29\x6e\x5f\x16\xeb\xc7\xdd\xed\xea\x7e\xf1\x0f\xff\x5b\xc6\x58\xaa\x42\x9d\x17\xa7\xa9\x3f\x0b\x41\x8c\x49\x32\x30\xd9\xab\x76\xff\x5c\x57\x66\xba\xc8\x21\x40\x46\x10\x8e\xf5\xcd\xd3\x48\xbb\x7c\x3c\x2a\xd4\x59\x26\xfb\xa2\xb9\xcb\xa9\x9d\x91\x35\x67\x9f\x0c\x18\x48\x02\x20\x01\xa5\x87\x6e\xf1\x83\xfa\x01\x9a\xdc\x27\x48\x20\x0a\xac\x06\xc9\xf2\x54\xd3\x5b\xed\x4b\xa9\xd7\x24\x2b\xce\xcf\x14\xa5\x09\xcd\x0f\xd3\x77\xd3\x16\x7d\x67\xbe\x80\xc8\x30\x9a\x1b\x9b\x9b\xfb\x73\x79\xf6\x8a\xb1\x9a\x5c\x38\x8e\x24\x45\x80\x87\x5d\xe3\x04\x99\x27\x6f\x33\x36\x00\xdd\xf4\x5e\x68\xfc\x7d\x2d\x83\xf4\xb7\x34\x44\x05\x24\x41\x40\x3e\x7e\x01\x63\x1f\x13\x12\xa6\x99\x83\x84\x51\xf7\xe1\xb8\x63\x7c\xe0\x36\x42\x92\xda\x6c\x6e\xb7\x5d\x62\xdb\x52\x8a\xa2\x0b\x25\xd6\xa5\xa9\xd8\xe4\xcb\xa5\x22\x25\x94\xe3\x99\xd2\xe8\xe9\x57\x79\x89\xf8\x06\xdf\x50\xd8\x2d\xe0\xd3\x97\x98\xfe\x79\xeb\x0d\x29\x5a\x57\xb4\x3d\x17\x57\x3a\x7b\x41\x62\x3b\xfe\x11\x79\xa2\x85\xf3\x75\x9e\xd7\x3b\xd4\x79\xbb\x63\xc1\xc8\x05\x07\x9e\xb2\x08\x6c\xaf\xbf\x97\xd4\xf8\x63\x30\xbd\x38\x47\xab\x6c\x5c\xb5\x50\xe0\x43\xd3\x4f\xab\x2c\x4c\xa4\x0b\xc2\x36\x47\xeb\x81\x8c\xf6\xb4\xc9\x57\xc8\x18\xd0\xe3\x1e\xa0\x7e\xbf\x19\x94\x58\xcf\xd5\x0a\xc8\x24\x10\xf2\xfe\xf0\x49\xa6\xe4\xbe\xf2\x5d\x10\x02\x20\x08\x23\xe9\xe3\xe0\xa4\xff\x6b\xac\x8c\xa7\x58\xfc\x0e\x63\xa7\x0b\x80\x87\x1e\x28\x71\x57\x74\x8f\xf6\x5a\xe6\xaa\xaa\xcb\xb1\xbc\x91\x4f\x60\x81\x4c\x18\x05\x4a\x0b\xad\x97\x55\xf5\x3e\x0d\xc9\xc6\xaf\x5e\x65\x51\x3a\x84\x6e\x3e\xe3\x7c\xdb\x44\x7f\x75\x05\x92\x5c\xb5\x02\x4d\x9b\x88\xc9\x5c\xd7\x89\x05\xc6\x59\x09\x1d\x07\xb0\x5e\xdf\x3c\xed\x36\xdb\xc5\xb7\x55\xb8\x7b\x7e\x59\x11\x50\xdb\x17\x67\x00\x13\xcb\x88\x43\x10\xaa\xef\x9e\x0a\x2c\xf3\x59\x03\x30\x41\x26\x8c\xc7\x74\xf5\xd2\xf6\x85\x7e\x2d\xf3\x0f\xac\x9b\x49\xd1\x15\xbc\xce\x2c\x55\xd0\x5f\x8f\xf3\x15\x0d\x19\xa4\x40\x45\xb7\xc5\x8a\x84\xde\x86\xbb\xa9\x0c\xb4\xe0\x8e\xb8\xc4\x89\x03\xf6\x47\x10\x4d\xec\xdb\x82\x71\xdd\xfe\xe7\x1c\x0d\xca\xac\x09\x1a\xcf\x1f\x19\x86\x81\x47\x31\x5b\x77\xf0\xc9\x0c\xf1\x78\xb3\xbe\x91\x0c\x21\x21\x4a\x88\xcd\xbe\xfa\xb5\xbb\xad\xd4\x85\xb5\x97\xa1\x64\x34\xe7\xb0\xdd\x63\xfd\xe7\x54\x76\x43\x48\x96\x98\x60\xd8\x13\x47\x59\x0d\xff\x70\x0c\x12\x5a\x81\xaf\xdb\x4b\x50\xb6\x64\x98\x78\x92\x8d\xcd\xe7\x41\x56\x93\xb2\x9b\x8c\x42\x5b\xc4\x3c\x87\x2c\x1b\xea\x8e\xf0\xe7\x47\xc8\xa3\x21\xdf\xc5\x06\x8b\x62\xc0\x2b\x25\x64\x1c\x67\x14\x98\xdc\xad\x5f\x56\xdb\x97\xc5\xed\x6a\xd3\x1f\x49\x65\xaf\x8e\x1d\xec\x40\x0f\x16\x99\x8c\x95\xb4\x44\x8b\xeb\xe5\xdf\xcc\x3d\xc8\x58\x6b\xc9\xce\x84\xac\x8e\xd4\xe9\x3a\xe5\xbb\x90\x09\x5a\xc1\x3e\xda\x37\x28\xbe\xe9\xdf\x59\xca\x6d\x46\xf4\xb1\x2a\x17\xb6\xf1\x3c\xaf\xca\xcb\xda\xe4\x18\xab\x3a\x0e\x9e\x07\xc7\xdc\x45\x39\xc8\xcc\x4b\xc8\x57\x54\x23\x98\x74\xf5\xc8\x2c\x60\x94\xc7\xe9\x5c\x08\x09\x23\x21\x47\x21\xb3\x54\xc7\x36\xf7\x5d\x9e\xa0\xb0\x60\x24\x77\x48\xc4\x48\x7a\x53\x45\xee\xc8\xdb\xef\xf2\x92\x8c\xfa\x04\x98\x28\x21\xd0\x84\x8d\xab\xc5\x24\xc8\x91\x10\x31\x5a\x02\x37\x4f\xcf\xcf\xab\x17\xbf\xbe\x1f\x6f\x6f\xfa\x01\x3c\x02\x17\x74\x1c\x3e\x8f\x03\x32\x39\x7f\x5c\x44\x12\xbd\xcf\xa2\xf1\x37\x91\xe0\xba\xdf\x98\xdd\x1a\xa4\x04\x46\xeb\xd1\x3e\x90\xcf\x69\x79\xd9\x1b\x3f\x48\x65\xca\xd6\xa1\xca\x77\xfc\x24\x50\xed\xf8\x2a\x2a\xc8\x28\x18\xea\x49\x46\xeb\xea\x70\x57\xd5\x2a\x97\xc5\x55\xfe\x5d\x7f\x2a\x93\xe6\x9c\xbe\xd9\x94\xf9\x91\xba\x85\xfe\x2a\x29\x28\x55\x62\x15\xd2\x1d\x51\xd9\x0d\xe6\x05\x29\xc2\xe7\xcd\x74\xa4\x66\x19\xd5\x8d\xcc\x20\xdc\x95\x28\xed\x76\x47\x99\xff\x45\x91\xf7\x9e\xae\x0a\x32\x69\x99\x4e\xa9\x0a\x3d\xfe\x42\x2a\x10\xe0\x54\x22\xca\xcf\xe5\xa9\xd4\x7d\x57\x65\x7b\x99\x6c\x52\x81\xe2\x84\xbc\xd6\x8e\x4f\x68\x18\x26\xa9\xc0\x30\xdf\x83\xb8\x28\x8a\x9f\x55\xfd\xde\x8b\xc1\x09\x15\x6a\x49\x9e\x41\x01\xa7\x52\xed\xa9\xeb\x6a\x7c\xe9\x10\xb5\xf0\xd9\x30\xd7\x02\xe1\xab\x06\xde\x07\x5a\xeb\xc5\x1b\xf4\xb8\xaa\xee\x0c\x0a\xfe\x56\xcf\xff\xb8\x79\xf2\x9c\xda\x42\x31\xa6\x51\x9e\x95\xec\x6f\xf3\xa6\xed\x62\xce\x75\x79\xff\xb9\xdd\x57\xa7\x06\x4a\xdd\xee\x9b\xa1\x63\xac\x58\x96\x7a\x1c\xf0\x2b\xf1\xf1\x19\x53\xa0\xad\xf5\x4e\x8a\xd1\x2a\x8a\xad\x06\x1b\x7d\x4c\x3c\x1d\xbc\x7a\xeb\x1f\x57\x4d\x88\x8a\x63\xd7\x43\x04\x75\xfe\x88\xed\x73\x9d\x7f\xe4\x05\x5e\xe4\x8f\xa6\x27\x39\x06\x7f\x6c\xbb\xf0\x92\x9a\x38\xe6\x0d\x8e\x8a\xb9\xa0\x6c\xfa\xc0\xa3\x5e\x9c\xda\x7d\x55\x9f\x53\xe6\x2a\x09\x13\xca\x93\xca\xd3\xe7\xb2\xae\xca\x7f\xcf\x43\x09\xaf\xa4\xe8\x54\x12\x31\xaa\x96\x92\x1f\x44\x45\x05\x3d\xad\xe6\xab\x24\xca\x6c\xcb\x5d\xb5\x93\x79\x09\x13\x45\x2b\xa1\x12\x99\x10\xb5\x88\xc5\x96\x8c\x53\xa1\x2a\x0d\x39\x35\x28\x2c\x73\xbd\x39\xc9\x89\xe4\xdc\xfc\xa6\xa8\xd2\x34\xb5\xc8\x04\xcb\x43\x09\xb5\xa6\x9a\xba\xf3\x74\x46\xf4\xe0\xa3\xa5\xad\xb8\xc8\x64\xe4\xd1\xa0\x77\x35\x22\xe5\x24\xea\xc5\xc7\xdb\xb8\x6b\x7f\xcc\xfe\xed\x4f\x56\xd2\x52\xbc\x4a\x2f\xdf\x79\xa5\x44\xaf\x38\x1a\xe2\x5e\xf5\xf8\xdc\xb6\x6f\xd7\x15\x2a\x0b\x20\x49\x7d\xb2\xa3\xd9\xe7\xc7\x7b\xfc\xc0\xb1\xc2\xb4\xff\xc1\x2c\xc9\x08\x24\x77\x80\x77\xa4\x86\xf9\xab\x64\x0b\xd7\x22\x82\x2f\xad\x95\xca\x12\xb4\xcd\x2c\x76\x1f\xee\x26\x1b\x71\x7a\xfa\xc3\xc6\x10\xad\x9e\xa3\x5c\xb2\x6d\x52\x04\x79\xb2\x1d\x28\x51\xc0\xbc\x18\xb5\x50\x82\x29\xcb\xbc\xe5\x8c\xe6\xcf\xbc\xc4\xce\x70\xfe\xc8\x4b\xfc\x84\x5a\xdf\x60\x51\x40\x7d\x1e\xad\xbd\x4a\x77\x4f\xe4\x3f\x97\x78\x55\x10\x64\xb4\x7f\x75\x1b\xc0\x00\x58\xa9\x64\x10\xd0\xd6\xd5\x58\x91\x31\xfb\xc9\x87\x79\x55\x25\x03\x24\x48\x1d\x1e\xf2\xf6\x11\x7f\x11\x9f\xd7\xa5\x06\x86\x50\x32\x35\xd4\x08\x72\xa6\x73\xbb\xcd\xbb\x77\x8d\x65\xef\x70\x8d\xbf\xf5\x65\x21\x57\x49\xce\x02\xcb\xe5\xdf\xf4\x42\xa3\x42\x49\xc5\xc8\x13\x7a\xce\x15\xb5\x65\x5c\x4c\xea\x59\x87\x53\x49\x93\x51\xce\x88\x02\x85\xc1\x96\xe1\xdd\x60\xa5\x82\x58\x64\x3d\x73\xfe\xa8\x6e\xa3\x54\x80\xda\x35\x9b\x50\xe2\x38\x87\xf2\xaa\x9a\xad\x50\x2a\x84\x60\x88\xa7\xb7\x0f\xba\xad\x06\x75\xd6\xc9\x52\xd6\xb1\x95\x78\xff\xb0\x78\xc2\x95\x25\x05\x9a\xbc\x52\x0d\x22\x34\xfd\xf2\xfc\x62\x39\x62\xa8\x58\xf7\x15\xff\x7c\x5d\xfd\x89\x8f\x56\x36\x7b\xf4\xf9\x31\x65\x44\x5c\xd3\xd9\x2e\x50\xef\x83\x8e\x5d\x65\x82\x48\x61\xcf\xd6\xf5\x50\x95\xf8\x79\x57\xd5\xaf\xcd\x59\xa7\xca\x0f\x64\x3a\xc6\x5e\x2e\xd6\x6d\x5f\x53\x28\x91\x32\x90\x52\x3e\xc5\xaa\x47\x4d\x5a\x71\xaf\xad\xaf\x99\xa9\x60\x40\x39\xca\xd1\xee\xb6\xac\x87\xab\x2e\xea\xd2\x93\xef\x60\x90\x3b\x25\x8d\x52\x5b\x9a\xd4\x79\xc3\xa2\x83\x80\x53\x7f\x1f\xbd\x53\x4f\x29\x3e\xe5\x8e\x9a\xff\x11\x1d\xf0\x94\xea\x20\x8f\xd8\xbe\x53\xbb\xfd\xdf\xf2\x82\x75\xc8\x34\x21\x1c\xce\xfd\x95\x7f\xaf\x97\x42\xb3\x88\x47\xd2\x45\xbe\xd8\xfe\x59\x56\xbf\x0a\xd4\x3d\x46\x45\xb3\x24\xa5\x08\xc4\x86\xf1\x50\xe0\x3d\x7a\x99\x6e\xa1\x19\x07\x52\x38\xfc\x18\xea\x14\x9f\xa3\x73\xcd\xb8\x54\x86\x7c\xb8\xdb\xbc\x39\x9e\x48\xe2\xaa\xaa\x3f\x2d\x2e\x6f\xd3\x39\x51\x83\x2e\xb7\xf1\xfa\xd2\x4c\x33\x0a\x8e\x6c\x74\xd1\x0e\x81\x53\xa3\x29\xa1\xa3\x38\xa5\xf5\xab\x73\x63\x6e\xe1\xf3\x4a\x1b\xaf\x8e\x53\x46\x40\x63\x2c\xdf\xf2\xb2\x7f\xbc\x84\x47\xcc\xc6\xfd\x25\xbc\x39\x87\x62\xbc\x96\x74\x9a\xa6\xe4\xb5\xbd\x90\xfc\xe9\xac\x78\xa8\x1f\x99\x39\x3a\x3d\x8b\x03\x39\xf6\xa1\x98\xe6\xda\xc2\xc0\xbb\x5d\x86\x40\x63\x0b\xd3\xe2\x59\x11\x6f\x18\x8c\xeb\x8c\x25\xa9\xfd\xbd\x5f\x50\x6b\xca\x68\x9e\x3b\xa5\xff\xe8\x07\x29\x91\xda\x34\xdd\xee\xf6\xf5\x65\xb1\xed\xf9\x8d\x85\x16\x69\x44\x7e\x9a\xf5\x6e\xbf\x61\xf9\x03\x06\x72\x4c\x93\x7b\x16\x8a\xd1\xa6\xaf\x11\x5a\x12\xbe\xd9\x41\xe0\x2f\x04\x32\x26\x3c\xc6\xe6\x24\xeb\xaa\x81\xfe\xcf\xae\xe4\xb4\x3c\x35\x4d\xe7\xde\xee\xba\x9d\x7d\x3a\xb9\xe7\x12\x13\x5a\x86\x52\x3a\x48\x49\xaf\x4b\x5d\xb7\x17\x2c\x6f\x42\x4b\x26\xa5\x13\x64\x73\xe5\xa3\x59\x79\xd2\xf9\x47\x92\x8a\x51\x6d\xdd\x5b\xe5\x8d\xc5\x4d\x0f\xe6\xa5\x02\x87\xf6\x3b\x5b\xbe\x87\xbc\x6c\xa7\x79\x7c\xad\x23\xe7\x04\x94\x5d\xa0\xe2\xc1\x9e\x8e\xc5\x70\x10\xa2\x69\x2d\xc2\xc4\xf8\x1c\x85\x07\x5d\x4c\xae\xa5\xc3\x73\x1a\xe3\x19\xeb\xa6\x2a\xa1\x98\xd7\x97\xa4\xc1\x5e\x97\xa0\xa7\xf3\x7a\xea\x66\xf7\x6a\xea\x95\x6b\x8c\xac\x0e\xc6\xea\x69\x74\x47\x28\x2d\x00\xda\x81\x44\xf2\x6a\x48\xee\xe0\xc6\x18\xe0\x54\xce\x28\xae\x31\x84\x0b\x0c\x42\x8b\xf8\xf6\x30\xd9\x85\x57\xb1\x9e\xa5\x57\x19\x5a\x24\x0c\x78\x42\x6e\x4b\xb3\xaf\x7e\x75\x41\xf9\x78\x0d\x4f\x7e\x86\x5b\x45\x00\x59\x9f\xe1\x4e\xc8\x02\x4e\x68\xcb\x9d\x6f\xaa\x9c\x73\x3d\x90\x25\x56\xcf\x54\x9e\x3e\x07\x9f\x18\x23\x30\x7c\xd0\xb2\xbe\xc4\x76\x58\x9c\xc4\x08\x53\xd7\x6f\xab\xaa\x52\x53\x52\xf2\x58\xe5\xbe\x2e\xeb\x06\xc5\x41\x18\xf8\xc6\xea\xaa\xb3\xf7\x16\x71\xdd\x39\xfa\x93\xf6\xbf\xf1\x3c\xc7\x38\xb2\x2b\xe4\x61\xfd\xb8\xfb\xd9\x53\x11\x60\xac\x33\x4a\x7c\xe4\xcd\x06\xeb\x8f\xfc\x5a\x99\x0f\x13\x96\x10\x72\xc8\xaf\x68\x4c\x12\x49\x7b\x23\x39\xa3\x77\xf9\xef\x07\xf8\xed\xb2\x39\xe3\xd7\x98\x4a\x9b\xce\xda\x61\x67\x62\xfa\x87\xe5\xc6\xe6\x72\x36\xd5\x87\x2d\x25\x4f\x88\x33\x30\x8b\x23\x6a\x6d\xa5\xfe\xc3\x7b\x5b\x41\x1e\x5f\x59\x04\xb1\xc4\x81\xca\x37\xc5\xbc\xde\x1a\xa1\x30\x31\x55\xea\x74\x55\xd2\xca\xb8\xaf\xda\x16\xbd\xca\x6f\x77\xd8\x50\x26\xfb\xe6\x79\x39\xc2\xd0\x20\x70\xc5\xcf\x5d\xcf\xf9\xe1\x74\xe8\x8c\x63\x5e\xbe\x7d\xab\x60\xd2\x12\x8b\x52\x26\xe8\x75\x41\x1f\xd0\x43\x9a\x50\xa2\x04\x5f\xf2\x7f\xbe\xdb\xf4\x4c\x4d\x73\xd8\x09\x54\xa9\x32\x69\xaf\xe4\x57\x12\x50\x85\x3a\x2c\x5d\x68\x75\x9e\x3e\x4a\x25\x04\x92\x75\x9b\x77\x5e\xbe\xf5\xd8\xeb\xf3\x20\x0d\x56\xd3\xa9\x73\x46\xea\x1a\x3e\x29\xfd\x31\x4b\xec\x3a\xbe\x0d\x64\x56\xef\xec\xdb\xab\xa7\x9a\x13\x88\xc0\xe9\x55\xec\xac\xd5\x1e\xcd\x43\x93\x24\x5e\xe8\xfd\x47\x55\x9c\x0e\x56\xc2\xd5\x77\xd6\x8d\x5f\x93\x81\x88\xa4\x1f\xe9\x53\x3e\xe4\x05\x36\x6d\x75\x4e\x41\xa0\xd1\x40\x9f\x42\x41\x49\xb6\x77\x0c\x38\x37\x81\x08\x68\xaf\x3b\x56\x47\x2a\x56\x75\x3b\x94\x72\x8c\x76\x4d\x3f\x08\x02\xe6\x05\x72\x27\xe7\x87\xa9\xa3\x29\x6c\xff\x1d\x31\xc7\xa6\xe3\x0f\x49\xdb\xaf\xb3\x45\x18\x61\x56\x0c\x0b\x2d\x03\x71\xf7\x16\x4f\x3a\x27\x83\x57\x4d\x44\x18\x85\x89\xc2\xd4\x17\x83\x09\x16\xd1\x79\x0e\x37\x95\xc6\xe6\xc9\xcc\x3a\xad\x26\xd2\xa9\x67\xfd\x3b\x57\xf5\x56\x50\xf7\xc5\xe3\xfe\xce\xd2\x2c\xa0\x30\x70\xf1\x30\xba\x2f\x1e\xc5\xe4\xc4\x11\x21\x7f\xa9\xf3\xee\xb3\x4c\x1b\x7e\x4d\x16\x63\x08\x3d\x4e\x6e\x43\xd6\xe4\xd9\x42\xd0\xfc\x75\xb2\xcc\x50\x4a\x31\x2f\x1d\x7b\x1d\x65\x4a\x46\xc0\x1f\x93\x29\xc3\x02\x7f\xb3\xe5\x07\x34\xd8\xfc\xcc\xdb\xfd\x06\x8b\xc2\x46\x94\xe7\x59\x67\x20\x0c\xad\x76\x67\xe7\x89\x10\xdb\xa8\xff\x25\x48\x04\xa5\x31\x2c\x7e\xbc\x6f\x95\x32\x90\x19\xa6\xbd\xc6\xfa\x1d\xe2\xf7\xaa\xd0\xd5\x47\xef\x9d\x18\x00\x4e\x61\x5e\xde\xb8\x9c\xe7\xd4\xed\x36\x52\x70\x02\x6a\xf8\x22\xc5\x66\xc6\xf7\x9d\xdf\x8d\x8d\xd4\x2a\xb2\x34\xc4\x16\xcc\xb2\x33\xd8\xbf\x1a\x89\x16\xaf\xb3\xfd\x85\xdd\x67\x25\xec\x8c\xb7\x1a\x46\x41\x46\x7c\x0c\x75\xfe\x81\xed\xbf\x5f\xa6\x3c\x60\x7f\x11\x43\xbb\x8b\xe8\x50\xf8\xb2\xa7\xeb\xad\xb2\x16\x68\x48\x28\x2d\x8c\xce\x22\xaa\x99\x17\xd0\xb4\x77\xe8\x5c\xad\x09\x83\x97\x30\x26\x8a\x71\x00\x31\x1c\x1d\x92\x16\xd7\x41\x7c\x13\xcf\xd4\xe8\x41\xa1\x8e\x3d\x0e\x41\x10\x0a\x12\x95\x5a\x94\x2d\xd4\xaa\xcd\xcf\xbc\x76\x10\x04\x00\x16\xe6\x4d\xad\x07\xce\x72\xce\xd8\x0d\x08\xc2\x84\x2b\x7d\xce\x38\xad\x27\xbd\x90\x10\x84\x32\x22\x23\x72\xbb\xd8\x0c\xa6\x72\xf7\x77\x88\xac\x01\x29\x49\xbf\xd4\xad\xe7\xe1\x87\xea\xd6\xb4\xa4\x67\x70\x9c\xdb\x47\x5b\x1d\x76\x07\x23\xee\xe4\xc5\x7d\x19\xfb\xa6\x3a\x1c\xab\x53\xd9\x37\x5b\xce\xfa\x0f\x10\x44\x1a\xe4\x30\xc5\xb2\x39\x49\x9d\x7f\x34\x63\x58\xaf\x1f\x6b\xac\xce\xea\x66\x5f\xfd\x5a\xdc\xfe\xf0\x3f\x1d\x6b\x96\x0e\x6b\x1c\x2f\xe8\xc0\xdf\x73\xae\x04\x04\x31\x5a\x46\xb8\x37\x6c\x09\x44\xfb\x9c\xff\xc6\xe2\x66\x58\x0d\x70\x03\x93\x30\x8b\x87\xdd\xd9\xbe\x53\xea\xaf\x92\x36\xd3\xff\xb6\xc0\xea\xf3\x6a\x86\xa0\x0b\x99\x7a\x39\xe1\xaf\x90\xef\x6e\x7c\xca\x18\xd5\xeb\x56\xaa\x3a\x82\x7a\x57\x83\xc9\xc1\x59\x98\x39\xe3\xb8\x9e\x3e\x00\xe7\x86\x14\xda\xbc\xce\x6b\xfc\x5c\x57\xff\x42\xd5\x8e\x3e\x3d\xcf\x42\x08\x7d\x27\x17\xc1\xc1\x6f\x7c\x27\xaa\x1f\x21\x14\x55\xfc\x5f\x8f\xfa\x4a\x59\xf1\xca\x6d\x67\x5c\x52\x0c\x72\x57\xe0\xef\xbb\xbc\xb5\xf1\x4a\xe3\x2f\x2b\xa2\x8c\x1a\x91\xdf\xba\x99\xda\x6c\x4e\xa5\xae\x7e\xf5\x77\x25\xe2\xd0\xb1\x18\x97\x7a\xad\x97\x9f\xdf\xab\xa6\x7d\xae\xea\x76\x0e\xc2\x0d\x01\x08\x41\xa6\x7c\xfd\xf1\xf9\x27\x91\x42\x0e\xfb\xf1\xba\xc3\x8a\xcc\x1b\xf5\x06\x34\xd7\x9a\xb8\xdc\x60\x19\x66\xdc\xd5\xb5\xed\x4e\x3d\x3f\x8b\x64\x6c\x69\xfd\x49\x8d\xf0\x06\xea\x66\xad\x7f\xfb\xdf\x53\x01\x10\xba\xaa\x7b\x32\xdb\xb4\xbb\x69\xeb\x17\x34\x7f\x8c\x7e\x48\x85\x98\x32\x47\x27\x43\x91\x6f\xfd\x5e\xe0\x98\xf8\xf6\x3f\x7a\xc7\x79\xfe\xcf\xfe\x4a\x2c\x60\x36\x2f\x5b\x5a\x09\xf8\xfe\x46\xd2\x20\xb4\x89\xc7\xdf\x9d\xc3\x34\x80\x2a\x41\xa0\xb8\x75\xd8\xe4\xe9\xf3\x0b\xa5\x51\x3f\x58\x58\x1c\x5e\x37\x64\xc8\xa0\x41\x5c\xb9\x7f\x91\x5c\xf1\x97\xd0\x5c\x05\x9e\x01\xb2\xdb\x0b\xef\xa1\x9d\x84\xd2\x10\xe8\x20\x24\x67\x6d\x47\x1c\x4b\xbf\xaa\x61\x49\xb2\x3b\xaa\x3d\xa5\x7d\xef\xb8\x9c\x05\xa5\xfd\xa0\x14\x63\xa7\x95\x94\xf7\x22\x44\x10\x68\x91\xa4\xf1\xa0\x39\xfb\x90\x97\x33\x22\xde\x10\x68\x65\x49\xf1\x0f\x39\xb1\xca\xf7\xaf\x12\x13\x45\x9b\xf4\x8f\x1c\x7f\xb9\x65\xd4\xcf\x64\x13\x5a\x9a\x2d\x07\x99\x70\xfa\x9e\x03\xf6\x76\x08\x0c\xa6\x0c\xfa\x46\xdd\x07\x3c\xe0\xf9\x6c\xe4\x14\x9f\x34\x14\x85\xbe\x40\xf9\x9e\x97\x6f\xae\xb8\xe1\xaa\xf0\x7f\xe3\x1f\x7b\xb1\x30\x8c\x85\x1e\xb4\xa2\xac\xca\xb6\xfe\xb4\x1a\xd0\xfd\x0f\x86\x51\x18\x7b\xf2\xd7\x87\x33\x60\xca\xbf\x81\x30\x92\x59\xe8\x08\x02\x1c\x8f\x65\xe7\x91\xf5\x27\x1b\x49\x05\xe5\x43\x5e\xda\x39\x73\x83\xbd\x14\x27\x84\x89\x6b\x9a\x24\xea\x88\xc9\x32\x0c\x13\x23\x3d\xa9\xe3\x0d\xb1\xda\xfc\xba\x02\xbc\x84\x30\x8d\xb8\x71\x43\xbf\xdd\xe2\xa1\x52\xcd\xa3\xbf\x4a\x2a\x90\x1c\xef\x1f\x55\xa5\xdf\xc1\xff\x95\x2b\xf0\xcf\xbd\xac\x7e\x5f\x82\x67\xcf\x97\xce\x92\x80\xb2\x41\xae\xb6\xdb\x90\xf4\xe0\xb0\x9e\x06\x61\x96\x86\x60\xb5\x36\xab\xce\x10\x92\x98\x89\xeb\xba\xff\x12\x05\x07\x61\xa6\x21\x72\xf9\x8b\x6f\x58\xfa\xf1\xa3\x4c\x1c\x84\x19\xda\x24\xc7\x91\x32\x1c\x03\x47\x1e\x42\xc1\x04\xfd\xf2\x7d\xf5\xb6\xc4\x6e\x27\xd3\x88\x07\xd4\x53\x48\xc3\xe4\x57\x45\x94\x91\x52\x08\xb9\x6f\x37\xa7\x76\x4a\xa6\x08\x21\x30\x24\x73\xda\xed\x03\xc5\x33\xe4\xe8\xc4\x85\x4c\x5e\x1f\xc6\xec\xee\xc3\x1c\x1b\x84\x10\x05\x44\x2a\xe0\xb7\xd6\x9b\x7d\xae\x48\x65\xb1\xba\xd4\xf8\x1c\xdf\x13\xc4\x82\x94\x01\x68\x63\x5d\xfd\x46\xd5\xbf\x5d\x10\x71\xe4\x6a\x37\xff\xcc\xf1\x1d\xcb\xfd\x29\x9f\xf8\x29\x21\x80\xed\x8d\x3c\x27\xf3\x1d\x47\xe7\x48\x77\x0a\x42\x90\x8c\xf8\xb9\x35\x71\x3f\x2c\x3f\xff\x89\xf5\xb8\xd9\x1a\x42\x50\x89\x95\x0a\xb5\x68\xee\x9f\xfb\x2e\xac\x9d\xdf\xbe\xfc\x19\x3a\xf2\xb8\xaa\x67\xa8\xdb\xce\x45\x70\x91\xd4\x70\x7c\xe8\x87\xcb\x20\x25\x78\xc1\x82\x2c\xa2\x8b\x77\x9e\x0b\x98\xef\x18\x84\x50\x26\x00\xdc\x4b\x34\x5a\x6a\x35\x22\xeb\xf1\x0e\x3c\x84\xd2\xa4\x84\x7f\x31\x75\x75\xa5\x62\x08\xa1\x8a\xa4\xf4\xb5\xd6\xc7\xaa\x24\xa2\x92\xbc\x7c\xfb\x51\x51\xb7\xc1\xdb\xbe\x5f\x75\x2a\xcb\x44\xe2\x53\x6a\xb9\x42\x57\x06\x99\xbc\x25\xcd\x02\x12\x74\x32\xd3\xaa\x2e\x84\x3a\x35\x44\x5c\xa9\xab\xce\x0e\xb8\x26\x94\xc9\xf7\xc2\xc4\x96\xa7\x3b\xab\xe9\xc0\xb1\x9f\xab\xed\xf7\x95\xd3\xff\xbe\xf2\x0c\x28\xb8\x6f\xe7\x7a\x76\xc2\x83\x43\xd7\x24\x44\x60\xa4\x53\xaf\xa1\x85\x07\xdf\xcf\x7e\x0d\x45\xd7\xdb\x2f\x94\x19\x6d\x6c\x36\x5f\x0d\xc3\x84\x02\xb0\x40\x58\xba\xf4\xe5\xa9\x28\xf0\x77\xee\xff\x1c\xc6\x16\x28\xd8\xb9\xdd\xdf\xab\x7e\x74\x98\x04\x41\xd2\x23\x17\xba\x39\x76\x02\x07\x62\x99\x7d\x22\x16\x26\xa9\xab\xff\x6b\x2c\xab\x43\x5e\x4e\x33\x97\xc0\x42\xce\x69\xca\x3e\x6e\x9e\xef\x9c\x1a\xe4\xd7\xde\x1f\x0b\x85\xa4\x2d\xe9\xbf\x2c\x39\xe7\xf0\x15\xb1\x28\xe4\x03\xd8\xad\x5b\x24\xdd\x77\x7a\x41\x85\xc7\x7c\x2a\x65\x02\x2c\x62\x4c\x59\xaa\xf3\x66\x72\x25\xc1\x1c\x43\x73\x51\xfc\x31\xa8\x24\xdb\xbb\x19\xd3\xb3\x03\x8b\x83\x88\x32\x46\xe7\xac\xf0\x47\xc8\xfd\xa5\x12\xc6\xc9\x1e\x49\x68\xd5\xde\xe7\xb0\xd9\x74\xab\x65\x49\xca\x89\x27\xe8\x17\x75\xc7\xbc\x6e\x6e\xf3\x72\xfb\x6d\xd5\x5f\x84\x87\x60\x5c\xaf\x0e\x6a\x17\x97\x37\x13\xe6\x0c\x60\x89\x34\xe4\xfc\xaf\x4b\x75\x92\xd0\x56\xf5\xb7\xa2\x92\x50\xf4\x20\x61\x60\x09\x0a\xe5\x17\x80\xab\xb4\x90\x5c\xcc\xf5\x42\x20\xb0\x34\xb2\x1e\x9c\xcf\x6a\xde\x56\x87\x2e\x8c\xa6\x17\x32\xb6\xe6\x2c\x4d\x94\x6f\x75\xf0\x38\xa8\xe3\x40\x54\xdb\x8f\xe2\x16\x87\xfc\x66\x15\x4c\x6a\x3d\x80\x0f\x03\xe3\x71\x26\x87\x78\xbc\x45\xa9\x9d\x90\xed\xdf\x2c\xd5\x4c\x66\x0c\x4f\x15\x35\xf7\xda\x54\xd1\x36\xc7\xda\x65\xcf\xe6\xf7\x44\xc6\xb3\x84\x76\x24\x53\x9c\x9a\xfd\x77\x97\x04\xe8\x5f\x20\xcf\x0c\xa1\x31\x7e\x40\x99\xb7\x9f\xaf\x2f\xf7\xfd\x01\xc9\x88\xe4\xe1\xfe\xa4\xde\x9b\xd1\x64\xe2\x28\xc9\xf1\xb4\x36\xf7\xde\xda\xa6\x6b\x81\x93\x3b\x27\x0b\x8d\xb6\xef\xbc\xac\x4e\x94\xbc\x19\x68\xdf\x01\xcb\xb4\x45\xba\x6d\x56\x7f\xde\xc0\x31\xf7\x82\xea\xfe\xb0\x60\xa9\x87\xab\x39\xe4\xfd\xa8\x7c\x08\x4c\x28\xb0\x4d\xe6\x27\x63\xb0\x1e\x5b\x05\x60\x46\x58\xe5\xc0\xd2\x46\xe5\xe3\xd7\x03\xca\x18\x33\xe4\x0a\xb5\xd1\xe9\xcf\xbc\xdd\x57\x27\xdb\xb2\x34\x39\x43\x9a\x80\x8a\xd1\xc7\x1a\x75\xae\xda\x67\x50\xef\xd3\x21\x2a\x8c\x3c\xdf\xa3\x9b\x37\xff\x79\xca\xd5\x3b\x09\x73\x0f\x50\xea\xc0\x94\x16\x3a\x3a\xdb\x33\x8a\x27\xfa\x63\x68\xc8\x77\x7c\xa0\x1a\xc1\x4f\xa8\x27\x3e\x17\xd3\x49\x12\xc1\x90\xec\xc2\xbf\xd5\xeb\x00\x09\x60\xda\xe8\xe0\x4c\x55\xed\x74\xf0\xea\xc9\x8c\xd6\xc6\x98\xd0\xf6\x7f\x9b\xaa\x7e\xf7\xb9\x5e\x60\xc8\x4c\xdc\xb7\xbb\xdb\xf6\xee\xfb\x4a\xbd\xbf\x1e\x87\x75\x7d\x60\x98\x29\x5a\x96\xdd\x63\x4d\xfd\x1c\x37\xc4\xb0\x8c\xba\x51\xef\x1e\x6e\xbe\x00\xda\x00\x33\x09\xd0\x74\x7f\x3e\xc9\x17\xfc\x17\xb1\x9a\x4c\x42\xbc\x7e\xa0\x22\x37\x68\x07\x5a\x93\xd4\xea\xf4\xa1\x4c\x6a\xb5\x38\xfe\x89\x6d\x0b\xdd\xfc\xf1\x77\x6b\x74\x92\xc5\xfd\xf4\x3a\x40\xe7\xdb\x3d\xf7\x1b\x45\x14\x24\x16\xbf\xb3\xac\xaa\x03\xa1\xfc\xa9\x85\xbc\x8b\xb6\xce\x36\xe6\x5a\x98\x74\xde\xf8\xa3\x00\x18\x77\x6d\x39\xdb\x37\x5c\x34\x5d\x24\x61\xf5\xa8\xdc\x80\x30\x4a\x28\x4f\xb3\x7a\x58\x6f\x36\xeb\xa7\xc7\xdd\xdd\xd3\x0b\x61\x6b\x09\x6a\xcb\xfa\x61\x89\xb2\x39\xef\x02\x9a\xfd\x66\x44\xf5\x3e\x7a\xde\x28\xcc\x42\x0c\xa6\x72\xf7\xa7\x11\xc7\x79\x3f\x92\x93\x83\x40\x09\xac\xeb\xd4\x34\x10\x31\x96\x91\xb4\xb7\xcf\x53\x5b\x08\xd6\x43\x5e\x8c\xf9\x02\x21\x62\x49\x4c\x49\x6b\x4d\x69\x37\xda\xdb\xc7\x7e\x78\xc4\xd2\xd0\x62\xba\xf2\x0f\x74\x70\xa8\x7f\x5f\x52\x6b\x43\x14\x05\x49\x1a\x39\x12\xa9\xb9\x89\x14\x45\x90\x51\xa9\x78\xf7\xe6\xb0\x14\x3f\x90\xb2\xb0\xd7\x82\x84\x28\x8e\x34\x73\x00\xb4\xf5\xcd\x93\x6d\x4a\xbc\xde\x68\x0e\x51\x0c\x81\xe5\x5a\x6a\x29\x7d\xb6\x2b\xf1\xf7\x24\x79\x15\xc5\x18\x92\xfe\xcb\xcf\xbc\xc4\xb1\x7c\xb1\x1b\x90\x30\xab\x27\x55\x9e\x0e\xb7\x28\x87\x64\x61\x7e\x80\x34\x86\x79\x8d\xfa\xe3\x45\x19\xfb\xeb\x3d\x21\xf2\x39\x24\xbb\xa8\xfb\x0a\xcf\x97\xf4\x16\x10\xa5\x49\x8c\xfc\x0c\x68\x1c\x1a\xa6\x28\x4d\x45\xa2\xfa\x8e\xe9\x67\x02\x17\x4f\x1e\x3a\xcd\xac\xee\x75\x0d\xa5\xf6\x11\x5c\xc4\x41\xa0\xec\x65\xdd\x9f\xb1\xbe\x99\x56\x29\x20\xe2\xda\x50\x6b\x8e\xaa\xab\x66\x2c\x65\x04\x11\x37\x5c\x7b\x3a\x97\xfa\x63\x62\xcb\xa3\x2c\x8d\x45\xea\xbd\xf7\xa6\xf9\x55\x9d\x4b\xcf\x43\x5b\x10\x09\xa6\x7c\x0b\x5c\xb7\x54\xb7\x4f\x93\xb7\x2d\x9c\xf4\x8f\x19\x12\x96\x4c\xde\x29\x44\xc6\x6a\x65\x1d\xe1\x93\xf8\x81\xda\xe5\xa7\xf7\x54\xae\xac\x38\x80\x94\x6c\xd5\x3d\x96\x43\x0c\x3a\x44\x32\x51\x54\xcc\xdc\x43\xf3\x82\xc5\x20\x28\xfb\x8f\x91\xc8\x9e\x1b\xad\x78\xe2\x69\x7b\x5f\xd0\x98\x0b\xf4\x2b\x44\x24\x13\xd6\x99\xa4\x97\xa7\xc7\x7f\xae\x2e\x60\xbb\x10\x29\x11\xc6\x3d\x03\x88\x13\x31\xa3\x7c\xc1\x95\x87\xd5\x3a\x24\xd1\x4d\xaf\x05\xd8\xe3\x13\xc7\xbf\x8b\xae\xb1\xeb\x16\xaa\x97\x53\x81\x8d\xc7\x85\x4d\xf6\xbf\x08\x43\xcb\x5a\x93\xab\x2a\x1c\x05\x75\x11\x26\x91\x3d\xd2\x5c\xa8\xf3\x42\x64\x54\x40\xe5\xab\x1b\x5b\x48\x77\x38\xcc\x85\x22\x52\xe6\xbc\xd9\x1f\x2e\xe6\x52\x1c\xb0\x8c\x9a\x3d\x97\x20\x3f\x97\x55\x5d\xce\xe6\x10\xe3\x30\x0e\x02\x37\x6f\xc8\x9f\x0d\xc3\x51\xba\x2e\x0e\x75\x48\x8e\xe6\xe6\x61\xdb\x05\x49\x84\xcf\x70\x36\xde\x8d\x60\xcc\x8a\x81\xdf\x2f\xb6\xeb\x87\x55\xff\x57\x30\xbd\xea\xc7\xaa\x56\x2c\xd8\x56\x36\xa3\x31\x7e\x6f\x71\x94\x05\x54\x28\xda\x60\x61\x6e\xb1\x51\x44\xe8\x92\x57\xd3\x64\x66\x1c\x89\x0c\x2d\xb9\x18\x21\xf1\xfe\x1e\xfc\x07\xe2\x48\x86\x34\xbd\xa0\x3e\x7c\x6e\xa0\xc5\x22\x6f\xb1\xb9\x94\xd3\x80\x38\x0e\x42\xda\xd7\x73\x97\x11\xec\xf6\xca\x17\x34\x76\xe5\xcf\x46\x3d\x71\x1c\x4a\xa2\x73\xb5\x4c\x3c\x84\x2c\xa4\xda\xc8\xf4\xca\xa9\xd6\x63\x8a\xb3\x59\x4d\x39\x88\xe3\x0c\xb2\xac\x97\x73\xa2\x5c\xd2\x6c\x7b\x24\xc4\xb1\xca\xd0\x73\x3b\x5a\xe8\xd0\xba\x6c\xf1\xad\x9b\x96\x34\x41\x62\x2b\xcb\xe6\x46\xa7\x18\x13\x9e\xed\xe6\xe5\x69\xb3\x58\xbf\xec\x7e\x3c\xbd\xde\x7c\x5f\xbd\x0c\x69\xa6\x20\xe6\x31\x33\x3e\x1f\xfe\x38\x79\x82\x8c\x31\x4a\x22\x7e\xc3\xd6\x09\x1b\x94\xed\xb0\x54\xd8\x8d\xc8\xc8\xaa\xec\x4c\x5e\x8e\x3b\x2a\x20\xce\x92\x8c\x22\x1a\xfc\x00\x75\x3a\x17\x59\xc6\xcf\x9e\xc9\x80\xa2\xd7\x06\x5b\xcf\x9c\x7a\x25\xe0\x75\x27\x88\x28\xa3\x56\x68\x2a\xbc\xdb\xa8\xc1\xbb\x62\xb1\x70\xb9\xae\x5f\x98\xdf\xd5\xd5\x61\x4c\x2f\x04\x31\x04\x4c\x58\x6c\xd3\xef\x45\x5e\x9f\x55\x5b\x20\xee\x3c\x58\x6e\xb9\x4d\xed\x5d\x52\x3d\xef\x4a\x81\xc3\x9f\x13\x69\xe2\x3e\xfe\x95\x97\x45\xd5\xf4\x3f\x22\x59\x90\xd9\x48\xf1\x03\x8b\xaa\x87\x3c\x41\x2c\x63\xa3\xd3\x7e\x43\xfa\xe3\x82\xba\xc1\x0f\x53\xa9\x4f\xb4\x2f\x4f\x75\x9d\xb7\x15\x25\x9d\xc7\xbf\x2d\x75\x42\x22\xe7\x04\x9d\x7a\x21\xc8\xde\xa4\xc3\x01\x62\x95\x19\xf2\x26\x9e\x4a\xdc\x12\x40\xbd\x2f\xa2\xc4\x4a\x9a\xd4\xa9\x42\xbe\x0e\x3d\xa1\xd1\x0a\xd2\x61\x4c\xca\x9d\xdf\x7e\x7e\xbb\xfb\xca\x1d\x8d\x31\x60\xc4\xd2\xf2\x7f\x4e\x67\x82\xfa\xf9\x4d\x39\xc6\x38\x4b\xad\x38\xfb\xcd\xf6\xe9\xe5\x9f\xeb\xfb\xfb\x85\x97\xac\xf6\xf7\x66\x02\x41\x76\xdc\x65\x0b\x4f\xcd\xfe\xca\x2a\x34\x26\x25\x5e\x80\xa3\xd3\x83\xdd\x4c\x9a\x47\xa1\x73\x30\xa8\xd4\x63\x4e\xa5\x72\xc1\xcb\xa2\x7e\x3b\x1d\x06\x19\xdc\x84\x29\x45\x19\x3f\xd7\x07\x95\xcb\xc2\x42\x96\xbf\x50\x0d\x9d\xbd\x9d\xa4\xf3\x55\xc1\xba\x96\x3b\xd9\x6f\xcf\x49\x24\xb8\xa3\xc9\x2f\x15\x16\xe7\xfa\xf5\x70\x15\x25\x71\x12\x10\x26\x14\xca\xcf\x9d\x72\x7c\xa5\x5e\x33\xa5\xd9\x7d\x9e\xaf\x16\x27\x31\xb1\x0a\x39\xa6\x06\x1f\x3e\xf7\xf2\x13\x57\x6e\xd5\x9f\x8d\x40\xa8\x19\x02\xf6\x3c\x99\xf1\x7c\x49\x92\x38\x24\x6e\xcd\xce\x97\x7b\xa9\x4e\xa5\x13\xab\xf1\x13\x3b\x49\x12\xe3\xd3\x84\xeb\x32\x1f\x6b\xc5\xf7\x63\x32\x49\xc8\x81\x6e\xca\x76\x86\x9c\xea\xfa\xe3\x9b\x48\x44\x12\xab\x41\x9f\x94\x25\x03\x9f\xdc\x4b\x1a\x06\x84\x46\xb2\x9d\x15\x47\x6f\x52\x92\x34\xb4\x5d\x3b\x7f\xe6\x78\xd8\xd6\xf0\x08\x87\xc7\xfd\x09\xca\x61\x53\x07\x24\x5c\xa4\x94\x8a\xfd\x56\x57\xa7\xe3\xf2\x34\xd9\xb0\x93\x2c\xe1\x04\x87\xb7\xe5\xb9\xbb\xaa\x3e\x1d\x26\xbf\x9e\x65\x26\xb4\x10\xc0\x82\x0a\x27\xf3\xbe\x62\x92\x81\xbd\x49\x0b\x95\xac\xff\xec\xab\xdb\x49\xa6\x2d\x86\xf0\xee\xf5\xf1\x76\x73\xfe\x23\x84\x30\x4d\x5d\x4d\xee\x4d\x98\x98\x00\x0b\xe7\xd2\xae\xea\xfc\xb9\xc9\xb6\x31\x99\x79\xc2\x40\x46\x5e\xd9\x39\x7b\xac\xb7\xd5\x6c\xf2\x36\x81\xc8\xf6\xb4\xe4\x8d\x83\xef\x9c\x49\xa5\x67\x57\x6c\x02\x91\xf1\x39\xcb\x5b\xf8\x6c\x3a\x17\x13\xf5\x26\x2f\x15\x92\x56\x1c\x99\x1e\xa7\xd0\xe2\xcf\xc8\x04\x05\xfa\xbe\xf3\xa2\xd9\xa3\x63\x58\xeb\x17\x1d\x68\xd0\xea\x2c\xf5\xbd\x6a\xf7\xcf\xa7\x22\x57\x0e\xeb\x34\x79\x27\x32\x66\xe4\x41\x16\xd5\x5b\x36\x5a\xde\x32\x66\xc4\xa9\xf4\x5c\x15\xb9\xc2\x9d\x8f\x06\x13\x99\x01\xd5\x6f\x5f\x56\xdf\x5e\xef\x17\x2f\xbb\x9b\xc5\x76\xf5\xed\xe9\xe5\x1f\xfe\xb8\x0a\x12\x7a\x5f\xae\x22\x62\x0d\xbe\x9d\xce\xaf\x65\x9b\x17\xfd\xb8\x30\xf1\x49\x8d\x2e\x30\xa5\x26\xd7\x61\xf5\x22\x51\x1c\xa2\xd8\x0b\xe7\x95\x7a\x46\xc4\xb3\x1b\x63\x19\x12\x6d\x5a\x6f\xb4\x41\x26\x3a\xc8\xa8\x1f\x11\x46\x9b\x51\x82\x32\xc1\xd0\xb3\x5a\x5b\xda\x9a\xc9\x2b\x31\x31\xa3\xc2\x20\xd8\xbc\x0c\x94\x6d\xbf\x07\xa6\x01\x57\xb4\xc8\xfd\x14\xda\x91\x3e\xe8\xd7\xd5\x8b\x34\x30\x31\x31\x46\xba\xcc\xcc\x5a\x0d\xf1\x56\x90\x86\xcc\xe2\x68\xec\xd6\x75\xf7\xb2\x18\xdf\x4f\x1a\x26\x69\xea\x3b\x2e\xee\x20\x2f\x6c\x0f\x6b\x67\x72\xef\xaa\x1a\xf3\xb7\xf2\x19\xba\xcb\x3e\x56\xed\xba\x7c\x6d\xce\x97\x4d\x32\x2a\x55\xe4\x2d\x1e\xd6\xfd\x03\x84\xca\x0a\x0f\x74\x17\xdb\x9c\x64\xff\x67\x14\x54\x00\xb0\x0a\x1a\xdf\xa1\xd9\x0f\x58\xf3\xc7\xba\xfb\xb3\xb5\x9d\x94\x85\x40\xec\xde\xb7\xab\x1f\xab\xfb\xa7\xe7\xd5\x8b\xdf\x79\x6e\xfd\x4f\xb0\xd4\xf6\x0c\xa1\xf3\x1b\x16\x1a\x8e\x2d\xd6\x63\x8f\x3c\x65\x99\xa2\x82\xb9\x87\x49\x0c\xa3\x9a\x34\x62\x36\xcb\x23\xbb\x0f\xf3\xf9\x0c\x79\xff\x58\x91\xb0\xa0\xaa\x37\x6c\x1f\x4f\xff\x82\x31\xb8\x07\xd2\x08\x92\xc4\x45\xe0\xdf\xab\x16\x8b\x91\xc2\x3b\xa4\x91\xb4\x34\xf2\xa6\x73\x78\x08\xfd\x7b\x81\xdf\x48\x23\x13\x58\x26\x84\xf5\xe6\x86\x82\x1f\x4a\x92\xec\x9e\x1e\xfd\xde\x9a\xc6\x22\x20\xf8\x39\x5a\x65\xff\x3b\xa7\x62\xdd\x1f\x76\x38\xb6\x09\x00\x64\x62\xc1\xbb\x61\x54\x61\xf9\xc8\xf1\xd7\x63\xb7\x59\x10\xad\x3a\x5e\x8c\xd2\x99\x8b\xd8\x1e\xab\xf6\x19\x3e\x49\x97\x63\x2a\xb8\x01\x69\xac\x74\x14\xf7\xe9\x3e\xe2\x6d\xee\xdf\x59\xc2\x32\x35\xd4\x3a\xf2\xfa\x0a\x3d\x39\xfa\xdf\xab\xc5\xa7\x69\x6c\x53\xe2\xf3\xcc\x27\x7e\x50\x86\x54\xd7\x7a\xf8\x5c\xbd\xdc\x74\x61\xcb\x55\xb6\x85\xe9\xd5\x41\xd0\x16\x2f\xbb\x35\xde\x9e\x24\x5e\x17\x5a\xf8\xc2\x8d\x4a\x79\x60\x75\x17\x9c\xf0\x5c\x8d\x77\x75\xf5\xef\xf3\xcc\xe2\xa9\xb5\x76\x47\x47\xd5\x88\x07\xdb\x90\xef\x8f\x67\x22\xb5\x1c\xe4\xbd\xca\xc1\x0b\xb4\x17\xdf\x2e\x03\x4b\xc5\xe6\x12\xd5\xd0\xb4\x3f\xf3\x81\x98\xc9\xdf\x6e\xf0\x86\x54\x64\x56\x79\x8e\xf6\xff\x7e\x17\xf1\x26\x3e\x15\x42\x5b\xa1\xcf\xce\x2b\xd3\x76\x9f\xb0\xb0\xfb\xf1\x0d\x09\x8c\x98\xcd\xf6\xfe\x1e\x2d\x24\xd0\xa1\x18\xea\x53\x13\xa7\xb7\x2d\x1f\x7d\x83\x66\x64\x9d\x40\x87\xe8\x08\x8e\x2d\xd9\x7b\x3f\x60\x7c\xc7\x92\x33\x62\x85\xf8\xaf\x2e\xbe\xac\x46\x9a\xe4\x90\x2a\x1e\x07\x81\x77\xbb\x3f\xb1\xde\xe4\x6f\x25\xb4\xa7\x7a\xd4\xf5\x07\xa9\x32\xdc\x66\x5b\xba\x78\xef\x67\x5e\x5e\x68\x66\xcf\x11\x73\x74\xa7\x69\x5a\x32\xae\x28\x3b\x9c\x5b\x6e\x84\x4e\x2c\x9c\xf3\x42\x50\xb0\x3f\xae\x03\xe7\x36\xd9\xad\xca\x6e\x5b\xeb\x92\xbc\x9c\xdd\xbc\x8f\x9c\x9a\x8c\xd1\xef\xbe\xdc\x0e\xc1\xf0\xc0\x83\xd8\x2a\x1d\x74\x4b\xb7\x6c\x0b\x9b\x27\x6f\x54\x8e\xa5\x42\x36\x1e\x99\xb1\xc8\x69\xe3\x96\x58\xf4\x7f\x15\xe0\x8d\xd9\x1d\xe2\xe8\x84\x30\x08\x28\x34\xd9\x83\x75\x31\xba\x05\xbb\xad\x5e\x50\xe5\xf8\x31\x09\x01\xc7\xfe\x14\x0f\xe3\x80\xf2\x09\x56\xb8\x9c\x34\x0b\xbb\xc5\xea\x11\xfe\x97\x82\xae\x5f\xe5\xff\x38\x63\x4a\x3b\x77\xb5\x2d\x7a\x4a\x96\x69\x5b\x0d\x70\x16\x05\x28\x26\x5d\xd3\x3d\xb6\x72\xf6\xad\x72\xc6\x13\x32\x4b\x9b\x63\xae\x08\x2e\x3d\x59\x65\x3c\x8a\x54\xe4\xa0\x4e\x07\x98\xc2\x2d\x78\x14\x87\x02\x3d\x15\x10\x1d\xc1\x66\x5b\x2d\x0b\x50\xef\xc5\x0c\x44\x87\x47\x22\x00\x69\x09\x8c\x6e\xf3\x8f\x1b\xcc\x2f\x64\xd1\x26\xf7\x17\x07\xb6\xe8\xbb\x76\x66\xd3\xfb\x55\x57\x46\x87\x2c\x76\x33\x8f\xc0\x62\xd7\xc2\x9e\x19\x9b\xc5\xe3\x28\x20\x32\x5f\xff\xf2\x4e\x03\xc2\x19\xe0\x49\x66\xc8\x11\x6f\x5a\xf5\x00\xbf\x67\xea\x46\x3c\x91\x56\x10\xe6\xf9\x65\x45\xd2\x86\xdf\x9f\xee\x6f\x57\x2f\xfd\xf9\x4a\x52\x37\x55\x73\x92\x87\xbc\xfd\x4a\xc8\x68\xfc\xfa\x13\x6d\x19\x9b\x0f\x3b\xcb\x1a\xea\xfe\x9c\x06\x01\xa1\xd3\x7b\xa9\xb3\x3d\x1c\x8e\xf3\x69\x4b\x9e\x86\x91\xc7\xee\xdc\xa2\xac\xf3\x31\x0b\x49\xe6\x47\x61\x42\xd8\x2b\x9b\xfa\x7f\x41\xdf\x83\xda\x1d\x51\xca\x45\xf1\xe4\x07\x2f\xab\x52\xdf\xe6\x1f\xd3\xe7\xe7\xcc\x4a\xd7\xee\x8e\x50\x37\xb8\x2e\xdb\x4d\xb7\x06\xdb\xdc\xe4\xea\x27\xe6\x23\x0b\xc1\x39\x58\x6a\xe9\x3d\x94\xba\xc0\xc5\xfd\xeb\x1f\x5f\xaf\x83\x2b\x93\x83\x83\x45\x25\xf5\xc0\xd5\x3f\xce\x07\x32\xf0\x7a\x46\xbf\xdb\xbb\xdc\xcb\x3a\xfb\xe3\x12\xa8\x39\x86\x9e\x87\x64\x59\x4a\x85\xce\x61\x74\x1b\xf3\xc6\x33\xab\x02\xe7\x68\x2d\xc4\xc0\xe0\x2d\x3f\x17\x83\x0d\x69\xae\x13\x00\x78\x86\x69\xe2\x80\x30\x9d\xbf\xf0\x40\x84\x08\xc5\xe7\x43\x8f\xb3\xf0\xd7\x17\x41\x44\xbe\xf3\xa2\x69\xa1\xad\x9a\xcb\x0e\x59\xe0\x82\xf1\xc4\x56\xbf\x9a\x66\xa8\xfa\x3a\x7e\x1f\x02\x19\x55\x19\x0e\x79\xd9\xde\x57\xe5\xdb\x16\xeb\xc3\x17\x4d\xd2\xc0\x85\x11\x94\x3c\x01\x59\xd5\xed\xba\xb4\x05\xca\x4b\x9a\x6f\xe0\x10\x64\x94\x51\x57\xd5\xe1\x88\x65\x73\xe1\xc6\x73\x19\x26\x1a\xfc\x8e\xdf\xed\xd6\x89\x7f\x3a\x69\xac\x7e\xda\x5d\x5e\xd2\x5b\x26\x50\xfb\x57\x0b\x51\xc5\x5a\xba\x8f\x47\x6d\xfe\xc3\x0d\xb2\x0b\x08\x28\x93\xf3\x74\xc0\xb2\x1a\x19\x6b\x95\x59\x56\xec\x07\xd4\x0a\x06\x99\x96\xf1\x7d\x92\xaa\xd8\x70\xca\xdc\x51\xbe\x89\xe0\xa2\x74\xb9\xf9\xbc\xdd\xdf\xca\x9b\x70\x25\x12\x7a\xff\x9e\x35\x67\xc7\x02\xa7\x70\xfa\xe0\x09\x12\x80\x53\xb4\xd7\x07\x20\x53\xc5\xdd\x91\x3d\xd7\x61\x46\x46\xe3\xe6\xe9\xe5\x19\x3e\x07\x59\x2f\xae\x55\x22\x43\xef\x81\x5b\xb1\x67\xc2\xd9\xf7\x73\x0a\x23\xcb\x29\x44\x9b\xfb\xd2\xb6\xee\xde\x0e\x56\x08\x66\x99\xef\xb5\x75\x0c\x88\x73\x56\x21\x0b\x64\x9c\x89\x1e\x14\x77\x45\x46\x15\xb2\x90\x71\x1d\x5b\xdb\xd9\x59\xe7\x3b\xc4\x87\x4a\x53\xe5\xf9\xca\x06\x99\x85\x42\x47\xc9\x19\xec\xb8\xbe\x5d\x7e\xce\xf0\xb7\x41\xc6\xba\x0f\x6b\x91\x05\xad\xbb\xe6\x24\x39\x98\x31\x69\xd5\x86\xbb\xbd\x76\x79\x1c\x52\x4b\x40\x16\x2b\x5b\xd1\xa0\x8e\x19\x9f\xf7\x3f\x77\x47\x41\x16\xeb\x90\xaa\xbf\x47\xf8\xb4\xca\x00\x8b\x52\xdf\xe2\x87\x3f\x9c\x24\x40\x71\x08\xb1\xdb\xe2\xea\xed\xad\x3f\xa0\x25\xb1\xc6\xfd\xbf\x53\xae\xde\x37\x96\xeb\xc2\x2b\x4d\xf7\x59\xeb\x2c\x65\x36\x4b\xbb\xcc\xdb\xce\x4b\x23\x55\xad\xfe\x98\x48\x20\xf6\xca\x06\x7d\xb2\xd6\x1f\xe5\x59\x4a\x1d\xe8\x12\x14\x94\xea\x73\x38\xd3\x33\x2e\x38\x31\x8e\xca\x53\x5d\x3e\xf4\x4f\xc2\x95\x24\x98\xea\xc3\xcb\xb8\x41\x20\xe3\x98\x72\xec\x95\x1d\x47\x71\xcb\xe4\x33\x72\xb4\x34\xad\x1b\xac\xe6\x0d\x46\x96\x45\x29\xf1\x11\xe4\x8d\x6b\xdd\x9c\x7c\x8b\x2c\x49\x98\xf6\xf0\xcb\xc9\xa7\xcc\xb8\x56\x71\x4f\x50\xd2\xb9\x43\x9b\x16\xda\xbc\x69\x3d\x1f\x2c\x64\x19\x70\x52\xa1\xdf\x35\x7b\xa8\xc9\xd5\x32\x58\x5f\x27\xb8\xf5\x67\xc9\x88\xa2\x1d\x8d\x8e\x4a\xbf\x28\xfa\x0b\x4a\x9d\x48\xd7\xfd\x42\xde\xfd\xd2\x26\x2f\xa6\xb7\xa6\x2c\xa1\xd8\xee\x8d\xb4\xfc\x8b\x02\xcb\x37\xdc\x9c\x08\x75\xf1\xb5\x83\x92\x01\x53\x04\x9b\xb5\x9b\xc3\xaa\xa1\x46\x48\x0f\x49\x3a\x83\xc0\xc7\xbf\x07\x52\x44\x7d\xc0\xb1\x76\x0a\x00\x55\xdd\x7f\x7d\x19\x09\xd5\x0b\x7d\xbd\xe5\x55\x49\xb7\x6d\x7b\x53\x07\xdc\x1f\x93\x5b\x91\x31\x43\xd7\xd4\xb4\xcb\x89\xa8\xd4\x1d\x40\xe4\x09\x38\x22\xe4\xdd\x29\xdb\x41\x5d\x83\x8f\xd6\x33\x93\x19\x63\x4b\x76\x04\x44\x9c\x7c\x50\x23\x52\x42\xa9\x7c\x54\x2d\xd6\x3f\xaa\xd6\x49\x3b\x8f\xdf\x9f\x60\x2c\xa0\x3c\x82\xb1\xde\x99\x4d\x5f\x8f\x6c\x99\x60\x02\x07\xe4\x14\x55\x7d\x18\x38\xc2\x99\x1f\x03\xa1\x6b\x27\x6a\x4e\x45\xbb\xdb\x77\x66\xdc\x1d\x8a\x03\xe9\x37\x85\x67\x68\xda\x81\x0f\xec\x07\xc4\x6e\xe6\xe1\x59\x3b\xfc\x1a\x41\xb2\x3f\x25\xb5\xc2\xb4\x20\xf3\x73\x88\xe4\x8f\x09\x4b\xe4\x2f\x3b\x57\xf6\x5f\xa0\xde\x6d\x43\xc1\xf0\x6e\x63\x10\x04\x2b\x77\x7d\x53\x36\xb5\x72\xb8\x80\xed\x89\x24\xb6\xa9\x88\xd5\xef\xa3\xcb\x94\x78\x12\x0e\x10\x69\xa2\xa2\x61\xff\xcb\xcd\x6a\x52\xcb\x16\xa9\xe6\x64\x68\xd4\x50\x3f\xf9\x3f\x66\x6c\xb5\xe0\x81\x84\x73\xa3\x26\x79\x68\xfe\x08\x53\x3a\x1e\x40\xe2\x1e\xf1\xd7\x38\xd9\x2d\x38\x30\x8b\xbc\xaf\x3e\xf0\x05\x49\xff\xf8\x6a\xd1\xc0\x9f\xa2\x19\xe5\x9e\x4f\xe7\x8e\xe9\x26\x9a\x43\x12\x08\x11\x64\x89\xe7\xac\xef\xe2\x21\x7d\x21\xf5\x09\x42\x70\xe6\x63\xd6\xbb\xaa\x46\x05\x0d\x95\x72\x2f\x1e\xd8\x4b\xa0\x0f\x1f\x1c\x82\x94\x9a\xe6\xba\x3d\x7d\x82\x35\x9e\xbf\x75\x10\x51\xe6\xda\x88\x1e\x73\xf5\x5e\x0e\x2a\xf0\xe3\x85\x4a\xdc\x44\x1e\x9a\x56\x7f\xea\x7a\xa0\x0e\xed\x47\xc4\x32\xb2\x31\x62\xab\xf6\xe7\x0d\x42\x28\xa5\x23\xdd\x37\x21\x53\x11\xe2\xdc\x54\x06\x42\x07\x5c\xda\x25\x69\xf2\xa2\x98\xbc\x30\x1d\x18\xca\xea\xba\x9c\x32\x9b\x77\xec\x85\x46\x23\x7b\x14\x80\x9f\xeb\xff\xdc\x7e\xbf\x32\xdd\x31\x14\x44\x1d\xb0\xf3\x93\xcd\xdf\x0b\xaa\x90\xf2\xe2\x6d\xb5\x6a\xf7\x56\x61\xc8\x11\xdb\x7f\x87\x66\x6f\xcb\xb0\x03\xef\x59\xa0\x51\x56\x0e\x1f\x4d\x9b\x85\x93\x7b\x37\x41\x46\xdd\x70\x0e\xe1\xa1\x7d\x77\xca\x24\xae\x14\x06\x62\x8a\x1c\xf7\x50\x98\x4f\xec\x36\x4f\x38\x74\x77\xa6\x71\xa7\xcf\x7e\x0a\x04\xcc\x52\x31\xff\x22\xae\xe7\x21\xf2\x12\x82\x28\xd1\x23\x96\xba\x6e\xc5\x7f\x1e\xcf\xa7\x46\x10\xe1\x60\xda\xd5\x6b\x3d\x8a\x42\x20\x30\x01\x15\x75\x35\x7e\x38\xbe\x11\xd7\xfa\x5d\x3e\xe4\xe5\x69\xce\xbf\x1f\x3d\x2a\x04\x46\xb0\x41\x94\xe1\xdb\xc6\xdd\xd1\x30\xc6\xc8\x81\x12\xbe\xe5\x1f\xb8\xcc\xeb\x76\x4f\xb7\x77\x06\x8d\x01\x4b\x78\x92\x0e\x16\x66\xcf\x4f\xfb\x15\xb0\x07\x22\x99\x92\x9d\xdf\xe6\x6a\x0b\x6a\x5b\xf5\x4f\x1c\xe9\x84\x16\xda\xf6\xe5\x66\x44\x74\xe6\x0e\xc7\x41\xec\xb9\xea\xdd\xf2\xbf\x64\x82\x06\x88\x55\x42\x25\x50\x68\x9a\xd3\x61\x82\xe4\x84\x04\x24\xd8\xd6\x80\xd2\xe4\x6f\xa7\xba\x0b\x6c\xfa\xb6\xec\x2b\xcb\x0d\xd2\x38\x93\xf1\x40\xa7\x7a\x40\x07\x0e\x90\x72\x9b\x7b\xb3\x79\xf6\x3f\x6f\xb7\xf3\xb3\x17\x52\x83\xe4\x2e\xf5\x0a\xcd\xfe\x02\x3c\x11\x04\xe4\x79\x58\x3f\xee\xd6\x8f\x3f\x56\x9b\xed\x6e\xf9\xb4\x78\xb9\xed\x8f\xf3\x98\x1a\xf6\x8e\xd8\x3e\x95\x03\xf5\xa7\x66\xc8\xcc\x01\xc0\x65\x4c\x59\xe9\xc5\xdf\xe4\x26\xec\xce\x40\xca\x0e\xdd\x90\x68\xd5\xb3\x2d\x71\x5e\x52\x88\xb8\x2d\x6e\x54\x4a\x01\x6e\x74\x90\xf6\xa5\xd4\x65\x7e\x69\x6c\x07\xb3\x24\x63\x40\xfe\x8d\xe3\x62\x2c\xf5\x1d\xe4\x13\x93\x01\x19\xb7\x10\xdb\x5d\x0b\xef\xb8\xb8\xae\xe9\xdc\x0f\xe7\x84\x0d\xb3\x1d\x64\x57\xe6\x59\x86\x41\x66\x39\x87\x3f\x5c\x8d\x77\x04\x24\x07\x60\x01\x09\x25\xb8\xb3\xb6\xd5\xe3\xe9\xb0\xad\x7e\x4d\x71\x11\x00\x4a\x86\x3d\x7f\xd9\x5d\x55\x5b\xc4\xab\xff\x3e\x32\x00\xe5\x6b\x24\xdb\x7d\x5d\xfd\xb2\x33\xe1\x05\x69\x09\xf4\x09\x74\x90\x2c\x24\xd7\xf3\xa9\xdf\xa4\x41\x62\x46\xd1\x49\x5e\x9e\xf9\x82\xee\x2b\x62\xe0\xe8\xe9\x54\x00\x54\xc6\x75\x70\x66\x6e\xe9\x6c\x81\xdf\x19\x41\x27\x32\xf4\x05\x90\xdb\x1a\x7e\x59\x8e\xcd\xf1\xbb\xd2\x68\xcb\x19\x0b\xad\x6b\xdf\x54\x42\x5d\xc0\xfe\x22\xa8\xa3\xc0\x92\x54\xfe\x0b\xd5\xb9\xbd\x6d\x72\x19\x44\x11\xfa\xd6\x94\xba\xfa\xfd\x39\x52\x81\x71\x63\x0c\xd3\x9a\xfb\xa6\x05\x6a\x48\x5b\x94\xcd\x2f\xac\x5f\xc8\x21\x9a\x5c\xd0\xa4\x9a\x72\x40\xe5\xe9\x70\x5f\x7d\x20\xc9\xc6\xfb\x5b\x32\x10\x50\x6b\xf4\xcb\xd3\xeb\xe3\xed\x8e\xef\x7c\x52\x8a\xa2\xd1\x7e\x90\x0a\x09\xc1\x70\x6d\x9b\x19\x4f\x07\x19\x84\x82\xb2\xf6\x78\xc8\x5b\xcf\x52\xf5\xd4\xbd\xaf\x71\xe0\x36\x6f\x2c\x65\x90\xda\x1e\x42\xcf\x4d\xdc\xe0\x75\x5d\xdd\x2b\xbf\x2f\x18\x8f\xfa\x90\x51\xbb\x05\x37\x2a\x43\xca\xc0\xa4\x36\x5b\x69\xc9\x61\x8e\x55\xd9\x20\xce\x71\x08\x80\x0c\x39\xa3\xb6\xfc\x1f\x55\x8b\xcd\x23\x76\x6f\x00\xfa\x1a\x96\x8c\x52\x14\x6c\x20\x3f\x34\x97\xe1\x91\x11\x4f\xc8\x8f\x38\xda\x59\xe1\x2b\x39\xd3\xf0\x42\x46\x42\x13\x6b\xa1\xc7\xd5\x92\xac\xe3\x79\x81\xcb\x08\x2c\x1b\xb4\xcd\x15\xac\x6f\x9e\x76\x3f\x57\xab\x3f\x07\xd5\x2e\x19\x73\x4d\x4d\x2e\x2f\x8b\xed\x8a\x80\xc3\xdd\x00\x5f\x25\x96\x49\xac\x09\xf7\x44\x64\xc4\x79\xeb\x42\x5c\xdb\x4f\xda\x2b\x40\x62\x3f\x5a\x05\x34\xda\xf2\xc9\xd1\x3b\x3c\xd3\x8e\x82\x4c\x03\xe6\x01\x35\xc4\x46\xe7\x13\x25\xba\x1b\x35\x49\xfa\xc9\x34\x4a\xd3\xd0\x37\x68\xc8\x22\x6f\xf6\xd3\x39\x2d\x53\xb4\x6a\x4c\x3b\x0a\xcf\xaa\xcf\x5b\xec\xd7\xb4\xe4\x18\x11\xac\xec\xe8\x9a\x3b\x6e\xe0\x72\x13\x19\x58\x42\xc9\x4d\xd0\xdb\x8a\x5d\x5e\x36\x58\xb7\x3b\x93\x97\xba\x7b\xf3\xdf\xf3\xb2\xb5\x25\xbc\x43\xf5\x81\xbe\x82\xdd\x9f\x98\xb0\xb0\xe7\x69\xf0\x3f\x9f\x09\xc7\x3b\x31\x62\xdd\x03\x29\x58\x42\xac\xa8\xcb\x53\x5d\xbe\xa0\xc2\xfc\x38\xcf\x0a\x05\x52\xa8\x88\x81\xeb\xbc\xb1\x9b\xe9\xfc\xec\x07\x16\x90\x37\x78\x5f\x7d\x42\xd1\xf6\xb3\x4c\x46\x10\x79\x08\xc3\x71\x0f\x8f\xa7\x03\xd6\xb9\x1a\x79\x29\x52\x05\x26\xb6\xf1\x99\xe3\x0f\x78\x3a\xf6\xb1\xbd\x54\xdc\x92\x02\xec\x40\xeb\x07\x68\xa6\x2c\x47\x20\x3b\xf3\xeb\x76\xf3\x4a\xe5\xbe\x92\xdd\xe7\x43\xbd\x2d\x97\x9a\x71\xfa\x4a\x0f\xd5\x25\x48\x5b\x6a\x1e\x11\x05\x9c\x35\x70\x93\x33\x31\x88\x93\x9e\x61\xff\x70\x84\xfc\xad\x9c\x8e\x60\x8a\x7a\x12\x48\xbe\x64\x55\xea\x41\x1e\x4a\x1a\xce\xa8\xdf\xe8\xe7\x66\x79\x33\x48\x70\x49\x93\x59\x6d\x3e\xaf\x2b\xb8\xb6\xea\x93\x75\xdc\x0f\x90\x22\xb2\x31\x0d\xf1\xd4\x4f\xee\xd8\xe8\x90\xba\x62\x60\xe8\xd7\x4d\x2c\x80\x0a\xb8\x6d\xe6\x3c\x63\x4d\xb6\x08\x87\x9b\x53\x4b\x6b\x73\xfc\x05\x55\xc8\x34\xd3\x3e\xc1\xf9\xcd\x72\x2d\xe4\x55\x79\xee\xb5\x57\x51\x12\xba\x6d\xee\x1d\x4b\x5f\x48\xf6\xc7\xb8\xb1\xf4\xaa\x95\x6f\x7e\x69\xbc\xb5\x28\xfb\x31\x68\xd9\xdb\xad\x64\xf7\x20\x83\xa3\x22\x63\x93\x41\x47\xac\xd5\xd3\x85\xd0\xd6\xe4\x46\x53\x96\x60\x3a\x25\x14\xa4\xcd\x86\xf4\x0d\xe7\xfc\x82\xb0\x3f\x57\x73\x27\xed\x85\xbf\x07\x5f\x43\xa5\xa8\x35\x65\xe1\xf2\xb7\x7d\x3b\x22\x00\x02\xc5\xb9\xb6\x79\xff\xdd\xb0\xec\xb4\xad\xd6\x37\x8b\xe7\xee\x19\x7b\x46\x97\x6b\x9d\xb0\x23\x9b\xaa\xb8\xb6\xa9\x7b\x57\xc2\xd9\x56\xf7\x53\x95\x78\x50\xdc\x28\xea\x3e\x83\xe2\x42\xe2\xef\x5a\x6b\xa1\xca\xb4\x85\xb3\x37\xd8\x52\x4d\x7c\x56\x72\x07\x94\x60\x86\x6a\xbd\x0b\xac\xab\x12\x4f\x17\xad\xb2\x7e\x58\x62\xdd\xad\xbc\xf9\x41\xaa\xe4\x0e\xe8\xb6\xfd\xed\x76\xa5\xce\xcb\xb9\xf9\x39\x9f\xd6\x55\x22\xd3\xa9\xa3\xfa\xb8\xb9\xf9\xee\xa8\xf1\xfd\xc4\x56\x02\x04\x81\x5e\xec\x16\x66\xf7\x56\xfa\x7c\xb3\xdb\x18\xf1\x93\x10\x02\x28\x2f\x0a\xe2\x28\x42\x3d\x70\x27\xcf\x83\x48\x9f\xef\x54\xf6\xd5\xed\xf9\xab\x41\x9a\x8e\xba\xd9\x9e\x9d\x98\xdc\x70\xea\xb8\xa1\x92\x71\xcb\x47\x75\xbb\x6b\x08\x10\xdf\x2d\x9e\x55\xbb\x9f\x80\x9e\x95\x62\x31\xca\x49\x51\xf2\x47\x0e\xe4\x03\x5d\xfb\x6a\x93\x29\xad\xa0\xd7\x0e\x5c\x42\x83\x73\x04\x23\x8a\x30\xb1\x67\x88\xfb\x88\x7e\x6f\x30\x4a\x73\x9a\xac\x3d\xa2\x75\x5c\xcf\x54\x4a\x67\xd4\x35\xaa\xa1\x7a\x7e\xba\xdf\xfc\xb9\x68\x87\x59\x59\xa5\x39\xa4\xbd\xba\x94\xcd\x5b\x8f\x8c\xb5\xc2\xd8\xe6\x5a\xcf\x10\xc9\xbf\x6a\xf5\xf0\x27\x72\xa9\x7b\x92\x19\x0b\xe7\xfb\x73\x72\xef\x98\x19\x52\xe5\xd4\xa4\xb6\xf1\x2d\xaf\x0b\xb7\x12\x6d\x05\xc0\xdf\xa3\x09\x31\xf0\x61\xaf\x83\x5d\x0e\xc3\x66\x65\x12\xb0\xb9\x47\xbf\xb1\xdb\x3e\xaf\x51\x87\x97\x32\x69\x0a\xd2\x91\xca\x34\x79\xd3\xf3\xd4\xf5\xc7\x81\x91\xad\xda\xe5\xcd\xf2\x94\x4f\x5d\x53\x65\x64\x42\xd9\xfd\x53\x79\x04\xf5\xbe\x98\x26\x38\x94\xd1\x19\x15\xaa\x8f\x05\x7c\x76\x31\xf1\xc4\xad\xd0\x01\x17\x14\xb3\x59\x20\x3b\xea\xd7\x8d\x0f\xe7\x74\x90\x09\xe2\x94\x6d\xae\x75\x44\xea\x50\xa5\xa9\x17\xe4\xda\xe7\x85\xb6\x02\xfe\xc3\x46\xf9\x8b\xcc\xa3\x0e\x75\x24\x3c\x8b\xbb\xa3\xef\x5b\xd8\x70\xc1\x12\x5e\x9c\x5f\xc0\xac\x3d\xd0\x2c\x88\x89\xd3\xef\x89\x3d\xcd\x86\x8f\xc3\x49\xa2\x19\x07\xb2\x31\xf5\x59\x80\xd2\x71\x41\xf8\xdb\x61\x99\x15\x8f\xa5\x70\x64\x89\xed\x7a\x92\x15\xd4\x91\x66\xb1\x1e\x7e\xc4\x65\x05\xed\x1d\x4e\x62\x0e\x1d\x87\x56\x50\x46\x43\xfd\x5e\x56\x1a\x97\xd5\xb4\xbb\x55\xc7\x69\x88\x30\xec\xe8\xe9\xde\xf5\xe4\x2a\x80\x34\xf1\x76\xc4\x79\x73\x51\xdc\x77\xa3\xd2\x40\x53\xa3\x16\xc1\xba\xf0\xab\xfc\x9b\x4e\x53\x4e\x52\x78\x8f\xa7\xc3\x93\xd9\xb4\x27\xdd\x4d\x52\x47\x4d\xe4\xd7\x9a\x4e\xb5\x95\x0f\x6c\x4e\x07\xdb\xab\x31\x98\x04\x9c\x85\xf4\xf8\x0d\x39\xff\x94\x5c\xf3\xf6\x53\x67\x81\x65\x54\x21\xbd\x8b\x6c\xf2\x28\x22\x4c\x89\xe6\xc9\x01\xe7\x76\x37\x8b\x67\x7f\x9e\x88\x52\xea\x5c\xd8\x62\xd3\xb2\xe9\x69\x69\x44\x1d\x74\xb7\xab\xff\xfa\xb3\x1f\x9f\xc6\xbe\xcf\xec\x05\x3b\xe7\x64\xb8\xca\xb4\xc8\xf8\x80\x85\x7e\x71\x3c\xd6\xd8\xb9\x5f\x79\x55\x6e\x5a\xf4\xcb\x48\x77\xa1\x31\x35\x20\x4f\xde\xa5\x0c\x43\xb2\x33\x87\x4a\xe7\xe6\x93\x6c\xf6\x98\xf1\x64\xe0\x14\x6b\x19\x05\xb6\x98\x6d\xb9\xd5\x3c\x36\x54\xcb\x38\x23\xe7\xda\x6b\x41\x53\x5c\xed\x6b\x09\x83\x5c\xa4\x96\x09\xa3\x4c\x55\xb7\xd6\xb6\x95\xb3\x88\xab\xdf\x63\xd4\x2d\xcb\x06\xcb\xc6\x6f\x65\x5a\x22\x68\xa7\x03\xd7\xc2\x80\xdb\x48\x2b\x91\x90\x27\xd1\x45\x57\x4f\xa5\xb7\xc6\xb6\x4a\x36\x9d\x82\x0a\xb8\x6f\xfb\xda\xec\xa1\x46\x0b\xa3\x6e\x46\x5e\xd8\x64\x06\x29\xa9\x28\x05\xd6\xc5\xe3\x37\xd5\xe1\x58\x60\xef\x52\x6a\x9d\x65\x59\xff\x61\x7e\x5d\x08\x5d\x8e\x2f\x84\x11\x50\x75\xda\xa1\x99\x88\x50\xca\x0e\x8d\x7d\x33\xe5\xf8\x66\x31\x36\xf4\xb6\x1d\xf7\x26\xea\x9d\xea\xe2\xd8\xdd\x47\xde\xf6\x7d\xeb\x1a\x39\x37\xbe\xe0\x32\xbb\xd1\x6a\x54\x21\xe5\x74\xce\x15\x81\xc9\x71\x9d\xda\xd9\x0f\x85\x6d\x79\xef\x2f\xad\x39\xf5\x14\x34\x27\xd9\x05\x02\x2f\x55\x75\x98\x01\x50\x6a\x13\x45\xf4\xfe\x3f\xa0\x38\xe1\x14\x1f\xaf\x0d\x8f\x89\x13\x6d\x77\x2a\x69\xc3\x41\xed\xd8\x41\xa6\x3d\xfa\x18\x44\xc2\xd3\xf9\xff\xcc\x9b\xfd\x25\xe8\x11\x03\xae\x29\x04\xb2\x12\x32\x9b\x9b\xc5\xbd\x8f\x5a\x31\x4c\x82\x24\x3c\x7b\xc4\x24\xe1\x31\x4f\xab\x0c\xc8\x02\xe9\x8b\x04\x8b\x32\x3f\x40\xb1\xd6\xe4\x22\xf7\x14\xb1\x4d\x7b\xea\xa7\x2c\xb2\x30\xb1\x50\xae\xce\x21\xfd\x27\xd6\xd5\x43\x55\x52\xf4\xe3\x8f\xf3\x40\xa6\x9e\x11\xe1\x4b\xe7\x02\xa3\x98\x11\x6f\xa4\xae\xca\x76\xb3\xaf\x7e\x3d\xe0\xba\x9b\xaf\x3d\xe4\x00\x23\xc5\x08\x7b\x61\xa5\x2b\x1d\x00\xe9\x62\x4d\xfa\xc1\xda\x2a\x5e\x7d\xe0\x3e\x57\x45\x5f\x09\xc6\x38\x46\x12\xb4\xf0\xc2\x05\x03\xef\x1a\x63\x9d\xf2\xd4\x51\x4f\x5b\x74\xe1\xe4\xa2\x09\x8b\x94\x8f\xef\x3b\x57\x50\x6f\xeb\xcf\xc5\xa9\xdd\xbf\x96\xe0\x5a\x6b\xfb\x90\x1a\x13\x2e\x42\x4f\xaf\xff\x6b\x42\xa8\x82\x89\xca\x08\x2b\xb7\x78\x7e\xde\x6d\xb6\x4f\x2f\xfd\x97\x4a\x83\x98\x74\xbd\xd7\x8f\x3f\x56\x2f\x9b\xd5\x6e\xb9\xd8\xac\x37\xbb\xe7\xa7\xf5\xe3\xb6\x1f\x12\x6a\x22\xea\xaa\xa8\xe7\xe3\x0a\xdd\xf5\xf8\xbe\x53\x69\xb1\xaa\x2d\x1c\x9f\xab\xbe\x28\x8b\xa9\x31\x94\x74\xdb\xfc\xf9\xdc\x5f\x9d\xf3\xd8\x69\x80\xff\x26\x2a\xde\x0f\xe8\x87\x67\xc8\x28\x0d\x59\x62\xaf\x91\x77\x05\x78\x33\xf6\xb3\x31\x43\x49\x9b\xb2\x6a\xeb\x11\x6f\x1a\x8a\x34\x0d\xbb\xd9\x43\xf5\xf8\x9f\xb9\xc9\xcf\x07\x04\x71\x16\xe6\x8d\xb5\x07\x13\x4d\x3b\x40\x91\x69\x1b\x09\x87\xd3\x03\x10\xf0\x33\x99\xc7\x18\x66\x8d\x42\x01\xad\x03\xdf\x7e\x59\xea\x1b\x28\x2e\x1f\x62\x50\x63\x41\x30\x98\x5a\x1e\x23\x78\xc3\x09\x5b\x21\xa0\x64\xb6\x97\xfc\xd9\xc2\xf9\x2f\x1a\x43\x50\x32\xa4\x8c\xd2\x0e\x0f\x79\xbb\x79\xcf\x8b\x62\x51\x23\x34\x9b\xcb\x34\x9d\x3f\xc1\x41\x07\xfb\xc4\x7e\xf7\xec\xfe\x98\x64\x54\xa5\xe8\x9e\xad\xc4\xc2\x3d\xdc\xf2\xd3\x76\xf7\xcd\x3a\x44\xa8\x22\xe1\xbd\xd0\xbc\x34\x55\x01\x66\x6a\x59\x54\xa4\xb8\xf0\x4e\xfd\x80\x6c\xe4\xda\x05\x95\x45\x79\xb4\xa7\xba\xb4\xc4\xee\xfe\xf6\x74\x6c\x88\x72\xe7\x16\x5a\xf0\xdc\xbb\xfe\x50\x16\x68\xd3\xd7\x57\x2e\x68\xf2\x01\x31\x88\x89\xc2\x70\xa1\xb5\x4d\x76\xb5\xf8\x56\xd5\x23\x06\x7c\x40\x0c\x35\xd5\x89\x94\xdb\x40\x5f\x80\xf6\xb4\xc1\xf7\x40\x96\xda\x7e\xa2\x6e\xfb\x6a\x5e\x50\xcd\xef\x36\x88\x51\x44\xe1\x45\xcf\xaf\x40\x5f\xb6\x67\xf3\x05\xc4\x18\x69\x69\xdc\x54\x87\xc3\xa9\xcc\xdb\x4f\xca\x4e\x4e\x56\x31\x72\x8b\xda\x27\x11\xfe\xc6\xa6\xcb\xfb\xb7\x61\x58\x48\xbe\xd5\x37\xcb\x2e\x4d\x5a\x32\xc7\x22\x9f\x46\x42\x68\x12\x8d\x0e\x84\xbb\x39\xc9\x67\xf8\x44\xdf\x53\x3a\x5e\x44\x26\x05\x5a\x7d\xab\xed\xf7\x87\xa7\xc7\xd5\x3f\xfa\xdf\x91\x5c\xe0\x5f\x77\xb4\xfb\xd1\x2a\x21\x4d\x84\x0d\x1e\xcc\x18\x1d\x8d\x46\x4b\x9a\x79\x77\x3f\x6f\xbb\x6f\xb3\xf2\x94\xca\x60\x82\x44\xd9\xce\xfc\x66\xd3\xda\xbc\x7d\x7f\x24\xcb\x68\xb5\x35\xc7\xe2\x32\xe5\x36\xfe\x69\x13\x0a\x4c\x2c\x32\x6d\x8b\xbf\xdb\x41\xda\xd5\x84\x52\x52\xf2\xac\xc6\x63\xb5\x3c\x27\x6b\x0c\x13\x9c\x60\x85\xcf\xab\x97\x9b\xd5\x23\x35\x1e\xdc\xae\x7f\xac\x37\x4f\x1e\xcd\x69\xa2\x20\x25\x26\x9e\xba\x73\x19\xb0\xfe\x89\xf9\xba\x7c\x80\x7c\xc0\xd1\x67\xe2\x48\x50\x43\x48\x67\x0e\x8a\xe5\xa9\xbe\x82\xd9\x33\x71\x9c\x66\x9e\x0c\x6a\xe2\x76\x9a\x44\x70\x82\x66\x74\x56\x79\x06\x15\x68\xd2\x34\xa4\x3c\x88\xcc\xdf\xc8\x07\x7e\x80\xdf\xf4\xef\x63\x8f\x5d\x34\xa9\x92\x04\x30\xb0\x2d\x09\xb7\x68\xe0\x54\x74\x81\xc2\xf7\xfc\x6d\xdf\x8f\xc1\x50\x39\x90\x97\x95\xf7\xf6\x50\xc5\xe1\xcb\x4a\x8d\x25\xc3\xb5\x41\x8b\x05\x83\xb9\x43\x3c\xe4\x94\xa1\xb4\x2e\x14\xf5\x05\x12\xdf\xda\x35\xf0\xdc\xc9\x29\x7e\x7b\x6f\x36\xf9\xef\x01\x8d\x4f\xfa\xdf\x23\xd6\xf1\xd3\x75\x75\x70\xff\xeb\xc2\x92\x56\x9c\xfb\xcc\xde\xbc\xa0\x61\x38\xd9\x90\x0c\xef\xbe\x7a\x67\x16\x0f\x76\x59\x7c\xde\xa2\xea\x7c\x0d\x7a\x6b\x7f\x31\x8f\xb2\x80\x53\x07\x26\x51\xb9\xae\xfa\x76\x16\x23\x42\x19\x0d\xca\x4b\x43\xfe\xa5\x09\x50\xe3\x7c\x2d\x21\x4d\x92\xf5\xe4\xe3\x3d\xf7\x7d\x33\xe3\xc9\x19\x08\x15\x65\x66\x9f\xe1\x5f\x9d\xd3\xc0\x58\xe4\x7f\x19\x18\xd3\x4e\x42\xf5\x1e\x4d\xbb\xbe\x79\x9a\xe3\x7e\x35\x20\x39\x85\x9b\x1f\x39\xfe\x7a\xc6\x36\xa7\x20\xa4\x33\x54\x7b\xf2\xb3\x3b\x27\x6b\xd6\x47\x35\x80\x9a\xb6\x2d\x8d\xa0\x8b\xbc\xc4\x5e\xe1\x68\xd0\x68\x63\x24\x63\x54\xfc\xf2\xa1\x7a\xff\x77\x15\x8b\x73\x77\x86\x2b\x6c\x4f\x58\xde\x67\xe1\x95\xd9\xe4\x5d\x49\xa5\x32\x2b\x6a\xb9\x2e\x4b\xac\x37\xaa\x3a\x5e\xc1\xaf\x19\x15\xd8\x5c\x58\xde\xbc\xe0\x9b\x2d\x5a\x4c\x1e\x49\x47\x3a\x71\x3c\x1c\xaf\xc7\x09\x55\x3a\x18\x0c\xd0\x4b\x56\x76\xb1\xf4\x5c\xfb\x83\x41\x66\x42\xe1\xa1\x59\xa0\xf6\x37\x70\x3c\x9e\x9f\xda\xc4\x32\xb0\xcd\x08\x0d\xd5\x9e\x66\x7b\xdf\x65\x10\x08\x5b\xf0\xf9\x13\x8b\xa2\xfb\x02\x45\x91\xc3\x61\x3e\x5a\x96\x41\x80\x9c\xd8\xbd\x1e\x6e\xb6\x3e\xb7\x36\x8e\x68\x86\x8f\x28\x83\x90\x73\xca\x1d\x38\xd8\xf1\xb9\x32\x6a\xe1\x93\xf6\xff\x37\x77\x55\xbd\xea\x59\xa2\x65\x10\x8a\x04\xcf\x49\xc7\x5b\x9f\x1d\xdb\xe2\xe1\xd8\xbd\x46\x9b\x1c\x1a\x15\x38\xfc\x89\x20\x2c\x21\x22\x7c\xbe\x60\x39\xfd\xc0\x7e\x90\xe2\xd4\xf0\x81\xc7\xbc\xa9\x34\x36\xbd\x7d\xea\x0e\xe9\xc0\x71\x9a\x35\x76\xaa\x5c\x79\x0b\xa1\x09\x89\xb1\xe4\x1b\xb6\xf7\xd5\x9b\xc3\xa7\xfc\x74\x94\xdf\xfd\x98\x98\x62\x33\xdf\x80\xd3\x6c\xab\xce\x3d\x5a\x5b\x32\x78\xed\xbc\x25\x3f\x9a\x85\x01\xbd\x28\x8f\x78\x3f\x9e\xda\xc1\xcc\x96\x01\x13\x9c\xa8\x11\x16\xc7\x7d\x5d\xe9\xbc\x3d\x9f\x28\xc1\xea\x8a\x74\x46\x64\x83\xe5\x45\x77\xbd\xb3\x4d\x32\x88\x30\x26\xfd\x15\x1b\xd1\xdc\x55\xd5\x90\x37\x44\x06\x71\x80\xc1\xa0\x05\xda\xbd\xec\x3f\xc6\xce\x2c\x85\xfa\x53\x9d\xa2\x79\x9b\x3a\x79\x65\x89\x14\x1e\x00\xd3\xdb\x2b\x19\x70\x29\xbc\xf8\xa3\x6d\x7b\xed\xcc\xa5\x87\xad\xc8\x40\x80\xb4\x5b\x1b\x36\x55\xf1\xd1\x2d\xdc\xe3\xe4\x93\x0b\x19\xe8\xb3\xd2\xdd\xf3\xda\x9f\x09\xcc\x36\x06\x7d\x87\x66\xdf\xc2\xdb\x25\x55\xa1\x0c\x20\xca\xb2\x01\x71\x8b\xaa\x2e\xb9\x26\x64\x00\x32\xf6\x0d\x39\xeb\xe7\xbb\xcd\xf7\x01\x98\xdb\x8d\x90\x69\x48\x55\xc7\x9d\x45\x7c\x0d\x2a\x2d\x32\x90\xdc\xae\xc0\x66\x6c\x5a\x27\x24\x6a\x6e\xb0\x42\xdd\x0b\xb5\xe6\x25\x92\x3a\xc2\x3c\xe7\xbc\x0c\x74\x14\x46\xee\xc2\xab\xa6\x8b\xf9\xbb\x09\x45\x64\xb2\x7d\x0d\x62\x7e\xe6\xea\x48\x64\xa1\xa7\xbe\xa5\xd2\x80\xcd\x17\xe5\xe5\xdb\x40\x33\x6e\x0b\xf5\x1b\xb6\x03\x68\x8c\x0c\xd0\x58\xe0\xc2\xfe\xad\xb5\xfd\x6f\xe3\xeb\x9a\xcc\xe6\x68\x49\x3b\x7d\x47\x40\xc5\xe9\x08\x19\xf8\x98\xda\xe6\x88\xb7\xbf\xaa\x45\xfd\xd6\x8c\xeb\x12\xf1\x6c\xbd\x5d\x86\x01\x06\x5e\x20\xac\x9b\x28\xb7\x27\x2c\x9c\xd4\x98\x0c\x03\x03\x36\x64\x05\x83\xdb\xea\xe1\x74\x91\xe6\x76\xe3\xc2\xc4\x32\x17\x1d\xaa\x8f\xf3\x3a\x0d\x43\x6e\xc8\x1e\x8c\xe3\xa1\x45\x73\x81\x7b\xba\x8c\x8c\x64\xc8\x18\x04\xe2\x6c\xa4\xcf\x69\x53\x19\x32\x19\x53\xd2\xc3\x3b\xe6\xdd\x5f\x30\xb3\x0c\x0c\xd5\x01\xdb\x3d\x9e\x9a\xcd\x3e\x3f\x92\x1e\x8c\xee\xc7\x18\x15\x5a\xee\x97\x87\xdb\xd5\xe3\xee\x76\x75\xb3\x7e\x58\xdc\x6f\xfc\xe1\x88\xc7\x04\x79\x3a\xb3\x67\x5d\x67\x1f\x94\x61\x9c\x66\xd4\x6f\x2f\xa1\xc1\xd5\xf6\xfb\x88\xfe\x48\x86\xb1\x90\x74\xef\xb6\xb7\xc8\x6a\x34\xce\xc6\x3b\x32\x8c\x21\x51\x16\x19\x8a\x78\x8b\x2d\xe4\x13\x16\x1e\x19\xc6\x32\xa4\xd6\xa0\xcd\x49\x36\xaa\xce\x8f\xce\xc6\x9f\x0a\x5c\x1f\x8e\x45\xff\x93\x5a\x44\xbe\x19\xb7\x5b\x49\x23\x46\xa2\xc9\xd7\x4a\xb8\xa0\x98\x80\x2a\x90\xe4\xc3\x51\x64\xe6\x7f\xf7\xff\xc6\x99\x7f\xcc\x44\x07\xdc\x5d\x95\x38\x20\x66\x4a\x32\x32\x4c\x43\x43\x3b\xf7\x42\xeb\xdb\xfc\xc3\xdf\x50\x1a\x5b\x39\x9d\x2e\x84\x6b\xb6\x95\x85\xc1\x4c\x4e\x4c\x02\x02\x8c\x39\xbb\xb8\xaf\x11\xe6\x88\xa0\x64\x98\x6a\xfb\x6d\x1a\x2c\xf5\x08\xba\x33\x79\x99\x29\xa6\xb4\x92\x10\xea\xe2\x73\xb0\xe8\xce\x8c\x01\xe3\xf1\x3c\xe0\xd1\xb9\xe3\x67\x59\x55\x45\x33\x24\x39\xa9\xaa\xa2\xff\xe0\x9d\x2b\x17\xb9\xb4\x31\xe5\xb9\x12\xff\xa0\x10\x31\x42\xac\x41\x35\x52\x24\x90\x21\x70\x19\xf6\xa5\xe4\x5b\x2c\x66\x78\xb8\xbf\x72\x9d\xcf\xef\x09\xc0\xb6\x31\x0d\xc8\x12\x76\xb6\x5b\xbb\xff\x29\x19\xc5\xde\xa3\xa1\xfe\x9b\x1c\xc6\x3c\x10\x6e\x9c\xcc\x98\x74\xa0\x8f\x53\x83\xb5\xab\xba\x5f\x99\x9a\x12\x52\xa2\xcd\xfc\xa0\xdc\xee\xca\x49\x10\x5d\x7d\x86\xf9\xb9\x26\x91\x59\x0a\x09\x97\x70\xc0\x99\xf6\x0f\x19\x2a\x66\xc9\xcb\x1f\xd6\x8f\xbb\xcd\x76\xf1\xe7\xca\x3f\x98\xca\x24\xe5\x47\x3c\x72\xe4\x16\x0d\x96\xfd\x2e\x10\xea\xcc\xea\x4a\x5b\x38\xf1\x7b\x5e\xbe\x39\xde\x36\x7f\x5c\xe8\xd4\x1b\xf3\xc7\x6f\x7d\xb4\x3d\x6b\xf9\x43\x8d\x41\xc6\xa7\x62\xb4\x9b\xed\x97\x79\x45\x19\x62\x6c\x05\xc3\xf2\xe6\x01\xfe\x45\x6c\x5b\x8e\xb4\x19\xf5\x1f\x43\x7b\x66\x80\x87\x8e\xe3\x74\x93\x97\x6f\x05\xf6\x0d\xe1\xe3\xeb\x19\x00\x4a\x02\x16\x68\x5a\x9b\x15\xf0\x07\x14\xe3\xe9\xd9\xd3\x86\xa6\xe9\x76\x97\xe5\x0c\xc0\xac\x1b\xcb\xe5\x99\xd0\xe2\xdf\x20\xab\x75\xb9\xcc\x3d\xb1\xbf\x64\x01\xb7\x85\x87\xfb\xdc\xe0\x1d\xa8\xb6\xaa\x77\xfd\xca\x65\x8c\x2b\x4f\xe7\xf3\xfc\xf4\x74\x6f\x0b\xd7\x61\xd6\x1f\x56\x01\xb8\x4a\xd2\xf2\xa4\xdf\x70\x96\x8b\x47\x32\xa6\xad\x88\xcd\xaf\xbc\xd4\xd5\x2f\xd2\x34\xa6\x8a\xc4\xf8\x71\x19\xd3\x31\x11\x48\x96\xa7\xc3\x12\x4b\x34\xb9\xca\x81\x12\x38\xfe\xb8\xd1\xc9\x79\x1b\xb8\xd9\x77\xdb\xe7\x10\xd1\x29\x59\x94\x19\x97\x84\x6f\x4f\x75\xd9\x19\xbf\xfb\x6a\x20\x2f\xea\x8d\x5a\xe4\x56\x32\x8b\xc3\x80\x50\x5a\x4e\xd1\xb4\x2a\x5b\x2c\xdb\x21\x61\xd1\x78\x3b\x72\x19\x12\xc9\xe2\xd8\x50\xba\xe0\xbd\xaa\x11\xca\x9b\xbc\xcd\xfb\x56\x77\xc9\x62\xcc\x28\xe2\xbc\xab\xaa\xfa\xe8\xff\x98\x68\x41\x66\xeb\xff\xdc\xdd\x0e\xfd\x41\xc6\xa5\xa6\x4f\x5c\xe3\x07\x42\x71\xeb\xc2\xae\x3f\xc6\x3f\xc7\x0d\x23\xab\x8a\xa5\xa6\x00\xe6\x2c\xc8\x28\x59\xc6\x58\x12\x0d\x94\x9c\x7a\x0f\x08\xcf\x43\x24\xd0\xc2\x59\xac\x67\x1c\x34\x96\x29\x1e\x9e\xe7\xd2\x9f\x9f\x6a\xa4\x12\xf0\x65\x2f\xfd\x7c\xc3\xbd\xfb\x67\xce\x7c\x31\x11\x21\x07\xd7\xdb\xd5\x05\x0f\x24\xfc\x31\x47\x2b\x26\x99\x88\xad\x58\xe9\xeb\xfd\xf6\xe5\xe9\x71\xf5\xfa\xe0\x1f\x47\xf0\x90\x1a\xe1\xd0\xf5\x4d\x8e\xea\xf9\xdd\x61\x24\x61\xa2\xdd\x11\x6b\x53\xd5\x87\x17\x2c\xf1\x17\x5c\xf1\x56\x98\xc8\xb2\x01\xf5\xed\xea\xed\x6d\xa3\xf6\x78\xd9\x2d\xf5\x97\xff\x92\xc7\xde\xe7\x4e\x24\x13\x88\x96\xaa\x13\x75\x33\x80\x2b\x4a\x26\xa3\x58\xa7\x7d\x6b\xd6\x54\xb5\x57\x32\x99\xa4\x69\x67\xc6\x56\x3f\x96\x03\x31\x20\xc9\xa4\xb0\x25\xbf\x1e\x79\x6b\x41\xfa\xb3\xe6\x9a\x49\x04\xa7\x6c\xd9\xae\x3c\x78\xda\xea\xbd\x5f\xf1\x58\x99\x0a\x12\xc2\xc5\x7d\xe4\xf8\xcb\xe1\x50\x3d\xc9\x37\x25\x0e\xfc\x6d\xa8\x8c\x33\x57\x6b\x78\x6d\x49\xa2\xdc\x31\x20\x8d\x6f\x00\x03\xeb\x13\xe5\x79\x3e\x3d\x12\x6a\x4a\xc4\xe7\xaa\x1a\x16\x71\x25\xc3\x38\xa5\xcc\x17\xda\xae\x89\xba\xff\xbb\xb2\x8c\xe8\x5e\x01\xfb\x0a\x9b\xd0\xf0\xe5\x1b\x2e\xb3\x33\xa1\xf2\x10\xc8\xec\x6b\x9a\x21\xcb\xfa\xb1\x96\x58\x72\x0f\xcd\xfe\x36\x37\x26\x57\xa7\xa2\xfd\x9c\x2c\x40\x83\x09\x01\x47\x6b\xaf\xef\x67\x3b\x82\x4f\xb5\xaf\xfe\xca\x28\x94\x29\xa9\xdd\x50\x84\xb8\x1d\x6c\x1b\xd3\x4f\x74\xe9\x41\x46\x2c\x88\xc1\x6d\x5d\x7f\x7e\xaa\x21\xf8\xd4\x0d\x88\xb2\x38\xb2\x05\xab\x0d\x51\xa1\x56\x26\x9f\x30\x53\xc9\x28\x42\x5b\x80\xd4\xd5\xb6\x06\x7d\xb1\x91\x8f\xbf\x77\x94\xa0\xa5\xc3\xd2\x78\xe8\x36\x96\xfe\x31\xd2\x8c\xdb\xc6\x9a\xaa\xfe\xcb\x45\xe0\x4f\x11\xb1\xef\xd3\xb2\x59\xc4\xbe\xff\x63\x50\x1e\x97\x11\x77\x29\xd6\xb6\x01\x27\x32\x36\xbe\x4c\x16\xca\xd4\x56\xbc\xe0\xb0\xda\x7e\xb7\x20\x0c\x1f\x7d\x44\x59\xa8\x22\x07\xa5\xfe\x06\x4d\x3c\x63\xc8\xa2\x2c\x93\x04\xe8\x20\xa4\xa8\x82\xa2\x58\xf7\xbf\x9d\x29\xee\xdb\x11\xce\xe2\xff\x17\xa5\x3c\x19\x89\x08\x29\x83\x7b\x9b\x2b\xdf\xcd\x2c\x23\xe1\x04\xf1\x35\x5a\x3e\x82\x05\x85\x30\x50\xfc\x75\x4d\x47\x46\x02\x80\xe8\xfe\x3e\xa0\xc8\x6d\xca\x81\x10\x0f\xbd\x67\x99\xfd\xf7\x50\x6f\x68\x74\x2a\x84\xa1\x11\x83\x7e\xff\xd7\x06\xeb\xcd\x11\x15\xf5\xc3\x12\x73\xde\x5c\x45\x2e\xf3\x67\x4b\x46\x79\xe2\x9f\xff\xf8\xcf\xbf\x42\xa7\xc8\x88\xca\xb6\xff\xeb\x7f\xff\xaf\xe7\x02\x3e\x4d\x55\xcb\x53\xf1\xde\x0e\x36\xa9\x48\x06\xb6\x6e\x73\x5f\x0d\x8b\x6a\x32\x92\x8a\x51\x3b\x9c\xd3\xbf\x58\x56\xa7\x21\xf9\xea\xf8\xd5\xaa\x6e\xa3\x71\xfd\xc2\x97\x44\xe9\x7f\xe5\x04\x4f\xae\x25\x03\x4a\xd3\xf8\xb7\xba\xfd\xf2\x9a\xd7\x66\xf1\xf0\xf8\xd5\xec\xed\xf4\x97\x91\xa5\xa4\x56\xb0\xa3\x54\x88\xdf\x74\x22\x65\x84\xb0\x32\xfd\xaa\xd2\x6e\x47\xfb\xdb\x7b\xc7\x78\x1a\xeb\x54\x26\xae\x45\x69\x8b\x70\xe8\x5d\x43\x77\x18\x23\x11\xeb\x89\x67\x4a\x00\x5f\xbc\xba\xe4\x27\x3f\x80\x69\x4c\x44\x32\xa7\x72\x0f\x45\xbf\x44\x50\x22\x25\x81\xe8\xb9\x6e\x49\xa0\xa3\x77\x32\x22\x44\xa5\x7c\x56\xa1\xdb\x1f\xac\xc0\xff\xf9\xa8\xb5\x25\x50\x14\x36\xbe\xed\x5f\x8b\x51\x32\xf1\x0d\x51\x75\xf5\xab\xb5\x1a\x06\xb3\x52\x87\x32\x0e\x93\x08\x3d\xc3\x74\x5d\x7d\x3e\xe6\xe5\xbf\x60\x32\x84\x85\xc0\x6c\x7a\xba\xc4\x03\xbe\x53\xee\xc0\x3f\x41\xcc\x62\x45\x28\xa0\xef\xff\x7c\xb9\xac\x9c\xc8\x98\x01\xa7\xf8\xd5\xce\xfc\x6d\xe5\x3e\xf4\xb0\xee\x27\xe3\x88\xa5\x42\x7b\x20\x89\xa5\xb8\xea\x22\x6b\x82\xcc\x0f\x33\x85\x71\x94\x06\x84\xb4\x19\xa1\x8d\xbf\xec\x87\x90\x71\x84\x01\x2d\x23\x5d\x43\x5e\xee\xe4\x99\x6b\x44\xc6\x31\x0b\x43\x4f\xaa\xe2\xcc\xcb\xe4\xf6\x63\x99\x10\x9c\xfc\x05\x9b\xaa\x38\x59\xe1\x52\x4f\xd5\xeb\x86\x24\x5c\x13\xe3\xdb\xa9\x2c\xf2\x43\x7e\x76\x00\xe3\x04\x98\x70\xe6\xcf\x4a\x1a\x0e\x1b\xcf\x65\xcc\x43\x4e\xc0\x94\x8d\x95\x85\xc7\xfa\xbc\xff\x7d\x3d\x57\x63\x1e\x59\xf6\x03\x6c\xda\xfc\x00\xad\xb5\x4b\x79\xf9\x36\xcf\xbe\xfd\x3f\x5b\x08\x31\x17\xc2\x78\xfd\x28\x6c\x41\x0f\xdd\xf2\xd1\x47\xe3\x90\x11\x5b\x09\x15\x3e\x89\x16\x65\xf0\xa1\x38\x48\xc5\x07\x9d\x68\x3d\x77\xc2\x99\x8f\xa5\x7f\x11\x19\x86\x24\x51\x68\x19\x37\x36\xb6\x21\xfd\xa2\xbc\x22\x63\x08\x13\x72\x4d\x29\x69\xb2\xa1\x5b\x71\xe1\xfe\x17\x9c\x53\x32\x96\x41\x48\xa5\xe0\xd7\x72\x7f\x4d\x6b\x5c\xc6\x32\xe2\xa1\x0b\xdf\x37\x6d\x75\xdc\x60\x51\x9c\xd3\x68\xb1\x14\x9a\x7c\xdf\x95\xda\x57\xe4\x1e\x0e\xed\x71\x2c\x15\x73\x64\x40\x9f\x70\x6a\xf7\x58\xb6\x79\x37\x37\x87\xb1\x67\x2c\x75\x96\x45\x83\x14\xb8\x99\xcd\xdf\xc7\x12\x03\xe9\xb2\x3d\xdb\x53\xdd\x16\x78\xa0\x56\x83\x17\xfc\x7f\xfe\xc7\x54\x96\x52\xfe\xc0\x35\x80\x9f\xff\x9c\x51\xc4\xf8\x80\x3a\xef\x66\xc4\x00\x07\xd6\x9e\x9a\x29\x9f\xc3\xc0\x6b\x8b\x55\x86\x04\xf0\xca\x9b\x97\xcd\xf3\xc6\xb2\x39\xf9\xab\xea\x48\x53\x87\x0a\x29\xfa\x0f\x89\x37\xe7\x5f\xa2\x46\x41\x4e\xf4\xfa\xe6\x69\xb7\x5c\x6c\x56\xbb\xe7\x97\xf5\xcd\x6a\xb7\x7e\xdc\xfd\x5c\xf9\xe4\x75\x8c\xdc\xaa\x16\x35\x07\x59\x9c\xff\x66\xc8\x0d\xce\x55\xb5\x6e\x5e\x4e\xe5\xa0\xd4\x10\x9b\x50\x67\x2e\x39\x4a\x9c\x8d\xde\xf3\x1d\xbc\xdd\x24\x88\x02\xa7\x1f\xda\x54\x05\xe1\xc0\xdc\xd9\x49\x18\xa0\xe0\xae\xb2\x3d\x45\x46\xc8\x24\x54\x36\x79\xb1\x6b\x2b\x3b\x9f\xa6\xc7\x0d\xe7\xbc\x47\x5c\xd9\xa7\x79\xec\x43\xa2\x84\xa5\x8c\x09\x32\x0e\x24\x7f\xbf\xef\xbc\x8c\xe5\xe7\xa5\x23\x99\x30\xc1\x52\xf0\xc2\x5b\xdd\x6e\x4d\x80\x0e\x2b\x78\x31\x1b\x4a\x24\x4c\xb1\x04\xcf\xa8\x46\x5a\xd8\xbd\xcc\xf5\x5d\x55\x6f\x06\xdd\x5c\xee\x94\x24\x02\x5b\x5c\xfe\x85\x78\xfc\x99\xff\x1b\x6a\x7d\x53\x1d\x0e\x79\xd3\x5c\x78\x7d\x49\x02\xda\xb8\x79\xb6\xe9\x8c\x39\xbe\x59\xe2\x8b\x45\xa9\xad\x30\xd2\xd2\xca\xf0\xce\x87\x2d\x49\x1a\x80\x8a\x5d\xaf\x70\x5e\xbe\x0d\xa0\x0f\x7e\x00\x33\x04\x32\x7a\x2d\xf3\xaa\xdf\xcf\x92\x54\x5b\xa1\x52\xcf\xf8\xb8\x2c\x2a\xb9\x69\xab\x1a\x1f\xab\xd6\xb3\x67\xe1\x60\xb4\xf6\xb0\x15\xca\x5d\xd8\xde\xa9\xc9\x8d\x60\x1c\xf8\xf5\xd2\x79\x23\xf5\x30\x4b\x9d\xf0\x58\x92\xec\xa3\x3c\x7d\x5a\x09\x29\x3f\xb1\x13\xce\xe3\xcc\xd2\x00\xe3\x11\xea\xe9\x55\x33\x26\x28\xdf\xff\x82\x1f\x79\x73\x36\x6a\x49\x96\x44\x14\x30\xd8\x04\x35\xfc\xbe\xfa\x7e\xb2\xc4\x76\x16\x38\x8e\xce\xcd\x1e\x74\xf5\x6b\x20\x65\x2a\x93\x2c\x65\x5e\x93\x84\xa2\x71\x7a\x85\x15\x21\xce\x86\x5b\xda\x39\x6a\x99\xcc\x0f\x99\x4a\x34\x03\xc1\xaa\x4d\x8b\xc7\x6c\xf2\x18\xd2\x08\xaa\xb9\x50\xbe\xb6\x19\x6a\x4d\xcb\x44\x99\xd8\x6a\xb0\x59\x5c\x2f\x82\xee\x6f\x4d\x07\x29\xc9\x58\xbb\xe6\x36\x46\xac\xd6\xee\x18\xc6\x16\xb5\xff\xf8\x41\xf0\xbc\x33\xb6\x4e\x26\xc8\x6d\xdb\x4e\x89\xbf\xe6\xa8\x76\x58\xf0\x1f\xc3\x9c\x51\x82\x99\x20\xd8\xe5\x8e\x44\x57\x48\xfe\xf1\x52\x8b\x5b\x26\x26\xcc\xb4\xfb\xc0\x3b\xe8\xb3\x67\x89\x81\x34\x72\x7a\x42\x14\xce\x4e\xa9\x10\x64\x62\x74\x40\xd7\xdf\x12\xd4\xf6\x0b\x86\xf0\xc9\x8b\x35\x18\x91\xab\xf9\x63\xb5\xd9\xae\x1f\xbf\xed\xd8\xee\x76\xb1\xf5\xc9\xd0\x34\x30\xb6\xc1\xba\xc1\xa2\x98\x60\xc5\x64\x1a\xc6\x8c\x16\xa0\xc5\x65\x2f\x8a\xc2\xf5\x7e\xaf\xcb\x3e\x1b\x70\xc6\x79\xc8\x34\x4c\x18\xb3\xed\xd4\xf7\xf7\xeb\x27\x4f\xf9\x2b\xd3\x50\xc6\xf4\x77\xbb\xf4\x69\x3b\xfc\x1a\xf4\x43\xa7\x10\x44\xa8\x7b\x99\x2f\x43\x7d\xf8\x59\x3b\x9d\x32\x11\x52\xbc\x45\x4e\xe7\x06\xcb\x39\x7d\xd5\x49\x89\x33\x8d\x02\x9b\x5e\x73\x95\xa4\x1f\x96\x2d\x72\x6c\x2f\xd3\x28\xe5\x24\x30\x68\xe9\x56\x7b\xaa\x8f\x09\x0f\xda\x17\x20\x13\x99\x46\xdc\x9a\x7b\x47\xa6\x6a\xdf\xe0\x44\xe8\xdd\x0f\x15\x11\xb3\x05\x54\x28\x46\xb4\xd3\x32\x8d\xb4\x25\xad\x5e\xdc\xdf\x3f\xdd\xec\x5e\x56\x9b\xf3\x01\x4d\x70\xd5\x03\xbc\x63\x8f\x71\x9c\x7b\xde\x98\x85\x64\x21\x5c\x27\xe9\x63\xa5\xf1\xbb\x95\x8c\x1b\xe5\x28\xd2\x38\x01\x74\xed\xab\x4f\x65\x1f\x68\x8e\x6f\x34\x86\x88\xcb\x01\x6c\x87\x9a\x24\xac\xe2\x8c\x1f\xa1\x39\x85\x17\xd8\x2d\x55\xab\x9d\xac\x7a\x45\x1b\x99\x26\x29\x38\xa8\xe9\x47\xde\xc5\xa3\xe7\x15\x99\x26\xa0\x29\x8f\xfc\x50\xc9\xbc\xe8\x82\xe4\x61\x9b\xae\x24\xdd\xad\xa1\x72\xf0\x0e\x7f\x2b\x6c\x9a\x5d\x3b\xe3\x60\xa5\xa9\x6b\xc9\x72\x48\xe5\xfb\x29\x49\x8d\x4c\xb9\x61\x54\x90\xe8\xb6\x1f\x5b\xea\xbf\x18\x20\x2c\xb9\x9d\x6d\xe6\xb8\x6c\x06\x94\x69\xc6\x33\xba\xc6\x37\x92\x8d\xb9\xe0\xa9\x97\x69\x26\x82\x5e\x02\xc1\x91\xa7\xcc\xcf\x63\xd0\x19\xe5\xdb\x8a\xea\x2d\x0c\x6e\x30\x27\x97\x6d\x3c\xc2\xc4\xea\xfc\xe6\x6f\x2c\xac\x72\x14\x7b\xa4\x32\x34\x64\xd2\x94\x61\xb6\x30\xc2\x9e\x55\xff\xe2\x25\x4b\x28\x3b\xf6\x51\xd9\x7c\xff\xc5\xf3\xca\x2c\x15\x9e\x71\x65\x6d\xf3\xf4\x49\x7f\xb2\x01\x2a\x90\x2f\x1f\xd7\x43\x7f\x31\x95\x46\x53\x32\xef\xe6\xb3\xa7\xd8\x9f\xa4\x09\x4e\x53\x0e\x04\x99\xaa\x30\xa5\x67\xb5\x1f\xee\xae\xaa\xc3\x55\xbb\x7f\xf6\x89\x9a\x54\xa1\xf2\x58\x83\xf5\xd1\x58\x02\xae\x6d\xde\x4e\xba\x4f\x65\xaa\x03\x95\x38\x65\xd2\xfc\x70\x3a\x78\x05\xd6\xb5\xed\x55\xf0\xf6\x35\xd5\x20\x2c\xc9\x1c\xbc\x8f\xb8\x40\x64\x8a\x91\x01\xfa\x38\xfb\xea\x54\x68\x4b\x94\x44\xcc\x6e\x93\x5c\x24\x0f\xb4\xa0\x46\x6a\xbb\x90\x5f\x1b\xac\x6f\xb0\x6e\x2d\x2e\x66\x72\x57\x3c\x64\xb6\x8b\x69\xd4\xd8\xf8\xb5\x11\xe3\x21\x13\x10\x0d\xe1\x13\x79\x55\x2f\x7b\x5e\x36\xc9\x59\x1c\x33\x4f\x2f\xfd\x0c\x9f\xa3\xd8\x8b\x47\x22\xa6\x4a\xce\xc3\xe2\xdb\x6a\xd0\x7f\xd9\x1d\xb0\x42\x75\x67\x4e\x8f\xfb\xaa\x99\xac\x13\x1e\x07\x8a\x72\x66\x04\x0b\xfd\x12\x7c\x37\x38\x87\x45\x04\x44\xfb\xc8\xeb\xf6\x04\xbe\x9b\x72\xd2\x05\x20\x79\xc2\x52\x72\x7a\xe4\xe9\xf3\xdc\xbc\xfa\x5c\x4d\xf7\x45\x9e\x70\xdb\x35\xff\xb2\xfa\xf6\xe4\xef\x3d\xc9\x80\xea\x60\xa0\x75\xb7\xaa\x9e\xab\xbc\x9c\xe7\x2f\x95\x3c\x15\xb6\x9b\xd9\x91\xc2\x75\xef\xad\xdb\xc9\x36\x2d\x1c\x8e\xeb\x72\xf1\x02\xff\xee\xb3\x0d\xf3\x8f\xc3\x99\xd5\x5b\x6b\xf6\x79\xe9\x8d\x0d\xe7\xb1\x8d\x84\x89\x0a\x2f\x2f\xdf\xd6\x67\x6a\x2c\xc9\x79\xa2\x13\x57\x86\x6c\x4e\x07\x1c\x09\xdb\xfa\x21\x68\x59\x9d\x77\xa4\x75\x59\x7d\xe4\x1a\xeb\x39\xaf\x80\x67\x12\xa9\xb8\xf6\xba\x59\xbd\xec\x96\xaf\xff\x18\x8a\x93\x48\x9e\x29\x41\xa5\x08\x53\xe4\xc7\xfe\x8b\x8b\x04\x48\x95\x04\x2c\x83\xfd\xf2\xd4\xdf\xb5\xd0\x09\x77\x80\x78\x27\x8a\x37\xc4\x86\x70\x81\x11\x95\xc7\x3e\x88\x92\xeb\xa5\xdb\x02\xa6\x02\x8b\x92\x43\x00\xa9\x19\x32\xe0\x6c\x8e\xa0\xb0\xd9\xe7\xc7\x25\xb4\x6d\x81\x0f\x95\xc6\xe5\xe7\x7a\x62\x3d\x38\x80\x0a\x71\xda\x41\xdc\x74\x93\xdf\x01\x5e\x86\xba\xbb\xf3\xcb\x00\x94\xd5\x8b\xd9\x57\x05\xf8\x5b\x96\x91\x09\x7c\x53\x8c\xeb\x4c\x74\xa6\xaf\x19\x0c\xa1\x12\xdc\x9f\x79\xf9\x76\xca\xcb\xb5\xaa\xfa\x23\xb1\x6d\x34\x52\x50\xde\x3c\x5b\xc8\xf3\xba\xb4\x15\xca\x8b\x2e\x52\x7f\x4a\x96\x72\x57\xe3\xa5\x27\x18\x51\xe2\x8c\x6f\x57\x3a\x0d\xfd\xce\xda\xc0\x5c\x0d\xb8\x1b\x91\x3a\x20\xc9\x07\xce\x61\x11\xb8\x0a\x12\xa2\x54\xb1\x5e\xc6\xee\x8c\x50\x97\x5c\x31\x1b\x36\x75\x4e\xcd\x6e\x5b\x9f\x1a\xa2\x29\xfe\x82\x04\xd6\x9f\x17\x05\x96\xcf\x73\x77\xbb\xeb\x6d\x81\x8e\x32\x50\x67\x8a\x8b\x6e\x52\x7b\x60\xdb\xf8\x6c\x9d\xa1\xd5\x1c\x3b\x42\xed\x73\x4b\x1c\x79\x40\x85\x81\x7e\x25\x3f\x95\x3e\x43\xbf\xc4\x3d\x14\xe6\xca\xad\xfc\xff\x48\x7b\xb3\xe5\xb6\x91\x2c\x7f\xf8\x75\xea\xa2\x2f\xb0\x23\xf3\x92\xa2\x28\x9b\x5d\x92\xa8\x21\x29\xbb\xea\xdf\xd1\xc1\xc8\xe5\xa4\x84\x11\x09\xb0\x01\xd0\xb2\xfa\xe9\xbf\xc0\x39\x99\x89\x85\x90\xab\x26\xbe\xb9\x68\xd7\x08\x20\x08\x02\xb9\x9c\xe5\xb7\x00\x27\x41\x76\x5d\x34\x67\xd1\xaa\x57\x9f\x54\xe5\xc0\xa5\xa1\xa6\xe5\xbb\xa8\xb5\x35\xa3\x7a\x10\xe7\xcd\xa7\x97\x32\x19\x16\xaf\xba\x05\xce\xd9\x9c\xfc\x9f\x0b\x42\xb9\xd1\x9c\xec\x43\x5e\x41\xbd\x7d\x83\x5a\xa8\xa2\x1d\xe1\xf6\x25\x0b\x22\xe5\x88\x60\xeb\xf2\x47\x55\xa8\xc9\x02\xcf\x02\xa9\xb3\x80\x4a\xd6\x94\x2c\x77\xe9\xdf\x27\x0c\x25\xc9\xc2\x00\x68\x8f\xf1\xa1\x29\xf5\xeb\xc7\x56\xf3\x9f\x36\x78\xdc\x55\x0c\x28\xe7\x8d\x6a\xe3\xb2\xe1\x4e\xc6\xa2\xd0\x04\x23\x7a\xee\xb2\x0b\x7b\x5c\xe2\x3b\x7f\x67\x91\x4e\xad\x00\x5a\xf9\x20\xde\xe0\xb1\xba\x83\x6b\xed\xbb\xd1\x78\x66\x09\x64\x0e\xbe\x6f\xb1\x94\x0f\xe2\xe7\xf2\x55\xa0\xe6\x4e\x3d\xd9\x5a\x58\x1a\xc5\xe8\xbf\x23\xb4\xb6\x5e\x1b\xe3\xe9\xc1\xd2\x2c\x72\x22\x10\xe4\x63\x84\x51\x9a\x3b\xc8\x55\xc0\x7b\x45\x11\xb4\x16\xf3\xc7\x0c\x39\x93\x79\x3e\x55\xaf\x18\x86\xe5\x9d\x59\x0c\x01\xcb\xb4\xc1\x36\xe0\xa9\xfa\x41\x33\xe0\xf6\x6a\x4e\x33\x16\x05\x2e\x17\xfd\x5e\x17\x2d\xca\x7f\x4d\x51\x94\xe3\xe1\xc0\xac\x3b\x47\x6f\x8c\x6b\x5c\xd4\xc4\x58\x2a\xb0\xe9\xd6\x63\x86\xff\x6e\x47\x61\xfe\x95\xf1\x94\x8c\x3b\xbc\xdf\xcd\x57\xd1\xbc\x6e\x2f\xee\xeb\x38\x27\x12\xab\x06\x53\x57\xcd\xa8\xd1\xc2\x44\x96\x23\x39\x9a\x9a\x0e\x77\x55\xbd\x1c\x38\x43\x49\x26\x13\x89\x35\x3d\xeb\x02\x84\x62\x07\x93\xb7\x25\x39\xc7\x1a\xef\x41\x68\x8d\xae\xf6\xa2\x6c\xef\x6a\xf1\x42\x6e\x42\xf3\x37\xac\x22\xee\x0d\xfc\x3f\x7e\x07\x29\x64\x5f\xda\x67\x2a\xc9\x49\xb4\x01\x53\xe6\x41\xf6\xc9\x94\x4c\x84\x25\x63\x7f\xa9\xc4\x71\xb2\xac\x32\xa5\x73\x35\x12\x07\x00\x38\xb8\x8f\xea\xc0\x60\xc6\xdf\x36\xad\x33\x14\x91\xcc\x98\x04\xb7\xb4\xb7\xaa\x28\x55\x55\xc2\x9b\x1b\x65\x3c\x60\x1a\x59\x31\x36\x35\x72\x44\xbb\x81\x7a\xb0\xe4\x61\x64\xac\xe1\xd6\x1b\x94\x4b\xca\xe1\xfc\x05\x42\x96\xc5\x56\x7b\xff\xb6\x16\xef\x4f\xe3\xf1\xc4\x43\x91\x39\xc5\xdc\x2f\x70\x7a\x42\x5f\xde\x69\xac\xc0\x43\x01\xae\xc0\xdc\xcd\x03\x8c\xa6\xbc\xb1\xeb\x27\x55\x35\x1e\x9a\x10\xbb\x2d\x67\x94\xad\x22\x47\xc3\x03\x0c\xf5\x02\x25\x8f\x82\x24\x52\x5e\x35\x98\xba\xf0\xe3\xab\x44\x31\xc3\x6c\xac\x1b\x9c\xda\x7f\x4c\x1a\x41\x48\xd9\xea\x74\xbe\xb4\x4e\xe3\x7a\xd6\x3f\x73\x7e\xa1\xe5\x91\x8a\x98\xf6\xeb\xfb\xea\x07\xd4\x1f\x61\x10\x04\xdd\x23\xca\x7f\x9b\x9e\x2a\x71\x15\xb0\x7a\xc3\x23\x70\xef\x27\x57\x8f\x03\x92\x71\xf9\xbd\x3a\x17\xaf\x45\x2b\x4e\xc3\xa1\xce\x63\x21\x71\xa0\xde\x3c\xff\xb9\xda\x1e\x76\xfb\xd5\xd3\x21\x1c\xaf\xe1\x3c\x86\x18\xa3\x3b\x1c\xc7\x55\xb7\xbe\x34\x23\xa8\x17\x8f\x0d\x99\x76\xbb\x5c\xf3\x16\x7e\xdc\x81\x7f\xae\x49\x02\x38\xd1\xac\x60\xd2\x73\xe3\x1f\x5d\x92\xc6\xa1\x8b\xd4\x57\xff\xb9\x38\x3e\xa2\xe4\x09\x8f\x1c\xc3\x92\xc0\x17\xce\x9a\x5a\xcf\x25\x96\x3c\xe1\x90\x86\xce\x2c\x98\x64\x42\x26\x67\xa4\x81\x8a\x7b\x84\x02\x0a\x8a\x3c\x2c\xe7\x10\x95\x3c\x65\x01\x02\x49\xb0\x79\xd1\x3b\xb2\xc8\x2e\x8c\x44\x12\xeb\x0d\xa1\xff\xc6\xd7\xcf\x82\x30\x02\x8b\x6a\xd8\x57\x51\x9a\x4d\x1e\x61\x96\x0a\xb0\xed\xab\xdf\xc1\x69\xa3\x49\x9e\xc9\x40\x53\x36\xf2\xc7\x61\xf5\xc7\xf2\xeb\xe2\xf1\xcb\xea\x70\xb7\x5a\x1d\x7a\x5e\x94\x3f\xd5\x84\x88\x68\xdc\xa0\x5d\x87\x77\xb0\x97\x3c\x4f\x33\xf4\x41\x90\x97\x8f\xe5\x11\xbb\x42\xdd\xae\xdf\x2c\x5e\x44\x51\x36\x24\xef\xed\x4e\x65\xa9\xc5\xd9\x12\x4a\x6e\xf7\xee\x94\x75\xba\x43\x39\x8a\x40\x3a\x5f\x43\xca\x88\xc7\x50\x1f\xce\x52\x8d\x55\x9e\x87\xc5\xf6\xf7\xd5\xfe\xb0\xfb\xba\xd8\xfa\xfb\xe3\x41\x82\xd1\x0b\x31\x5e\x1a\xdc\x4d\x8b\x19\xc4\xf6\xa0\x03\xc1\xb9\x22\x39\x55\x4c\x1b\x76\xe8\x56\x3a\x79\x1b\x22\x22\x20\xfc\xc3\xfa\x71\x7d\xf8\xb2\x78\x58\x1d\x16\xb7\xb7\x87\xfd\xfa\x61\x75\xb8\x5d\xdd\x2d\x9e\xef\x5d\xec\xcf\x45\x4c\x75\x55\x74\x16\x2c\xfe\x0b\x0f\xa2\xfc\xb0\x60\x35\x57\x62\xea\xce\xc1\x7e\xd3\xb9\xae\x4e\x15\x69\x39\x9d\x0b\x50\xe0\x08\x7e\xc3\x28\x81\x8b\x14\xd0\x3b\x5e\xfc\x10\xc5\x51\xc8\x23\xa0\x69\x93\x3b\x28\x14\x26\x15\x97\x06\x9a\xfb\x42\xd6\x5e\xd6\x4c\x72\x01\x39\x19\x50\x89\x6e\x58\xf7\x10\x17\x52\xcc\x73\xf4\x7c\x7b\xb2\x8c\x45\xac\x26\x3a\x35\x89\x3f\xa8\x4d\xe2\x33\xff\x5d\x65\x5a\x25\xce\xeb\xa6\xb9\xf4\x1f\x57\x2c\xc5\x12\x46\xfb\x5a\x57\xef\x6b\x43\x91\xaa\x68\x48\x82\xb9\x1d\xac\x6d\x3a\x23\x91\xee\xfb\xea\xe5\x16\x90\xc9\x3f\xbb\x05\x71\xcd\x32\x2c\x6a\xdd\x50\xec\x64\x9d\x02\xc7\x63\x5d\xeb\x50\xd8\x8e\xd9\xc3\x10\x73\xce\x21\xca\x53\x42\x0e\x75\xdf\xb0\x2a\xdb\x2e\x5c\x1c\x5d\x5f\x04\x21\x39\xc7\xdf\x5f\x4a\x51\xdf\x17\xa5\x0b\x9a\x45\x00\x9c\x67\x56\x22\x59\x1d\x2f\x57\xdf\x2a\x42\x23\x5c\x9f\xee\x50\xa8\xaa\x2c\xfe\x73\xb0\xde\x36\x87\xea\x3c\x28\xf2\xf6\xc3\x4b\x44\x29\x60\x4a\x6d\xcf\xfb\x2a\x6a\xad\xfc\x88\x17\x91\x1a\x02\x90\x9f\x2e\x75\x33\x32\x6f\x91\x22\x49\x9d\xe6\x6d\x53\x94\xd5\x2f\xc5\x74\xdc\x27\xa4\xc2\xbe\xef\xa1\x81\xf6\x6b\xf5\xde\x0d\x41\x52\x85\xba\x05\x55\xe8\x49\xf4\x24\x12\x93\x11\xa7\x0f\x63\x0b\x22\x6b\x5c\x27\x4e\x22\x0d\x8c\x0e\xad\x4e\x4c\x2d\x5a\x2c\xa8\x78\x0b\xdc\xd9\xb7\x28\x52\x26\xb0\xd6\x69\xf9\x49\x23\xc6\xae\x14\x29\x67\x88\x22\x21\x33\x70\xff\x57\x99\x20\x5c\x08\x4a\xfd\x19\x47\xc0\x9e\x99\xa5\x0c\xd7\xba\xd5\xf1\x58\x9d\x8a\x8b\xdb\x49\x44\x96\x45\x88\x6a\xb9\xdb\x7f\xfb\x7b\x25\x77\x91\x65\x80\xa8\xb5\xe6\x58\x28\xb8\xa1\x66\xc1\x18\xcb\xe1\x4e\x14\xb1\x05\xa1\xb7\xde\xc5\xb0\xa7\xe5\xff\x32\x0c\x14\x79\xa2\x85\x73\x2c\x85\xa6\xba\xd4\xea\x8a\x32\x36\x0e\x52\x05\x63\x2c\x8f\x9c\x74\xb8\xae\xde\xfd\x2f\x64\x3c\x08\xa5\xd7\xfd\xa9\x2e\xed\x60\x2d\x17\x4c\x82\x13\x9f\xa4\xa5\x6c\x06\x04\x2e\x78\x28\x70\xd0\xd5\x28\x56\xfc\x5e\x0d\xe2\x0f\xc1\x45\x8e\xa3\x87\x1c\x3b\xb6\x08\xa9\xbd\xa9\x9c\x30\xac\x14\x5c\xd1\xce\xe4\x86\x3d\xae\x9a\x23\x58\x83\x10\x01\x19\x2a\x92\x27\xce\xa2\x6d\x07\x84\x95\xc9\x63\x11\x81\x44\x22\x82\x38\x41\xa9\x29\xcb\xb2\x12\x98\xc4\xea\x1c\x4d\x05\x29\x72\x2c\x8e\xad\x16\xce\x20\x59\x0a\x15\x85\xd8\x64\x1a\x85\x54\x27\x51\x94\x4b\x71\x5e\x97\x5e\x49\x46\x0a\xc5\x18\x02\x5e\xbd\x6f\x45\x14\xf8\x43\x82\x86\x0c\x89\x88\xec\x86\x54\x63\x77\x86\x8c\xd0\x06\xbd\x0b\x50\xd1\x12\x06\x2b\x35\xc5\x8b\x7f\x27\xca\x18\xec\x62\xa3\x70\x0e\x72\xac\x6f\x26\xc8\xfa\xf1\x05\x75\x9c\xbb\xe6\xa2\x97\x53\x1c\xbb\xab\x49\xa1\x33\x2b\x6d\x71\x46\x5a\xc4\xa0\xb3\x28\x74\x2e\x31\x0a\x50\x57\x28\xe7\xf9\xe8\x4b\x68\x2d\x11\xb2\x7d\x33\x70\x12\x90\x02\x02\xd2\x05\xc5\x42\x4d\xd5\x14\x43\x7c\xde\x3f\x46\x9f\x87\x80\x63\xcc\xfd\x08\xef\x5b\x2a\x78\x7e\xc2\xc0\x10\x10\x26\x59\xee\x97\xdf\xc5\xf1\xb8\xf8\x21\x5a\xe1\x33\x08\x01\x42\x3b\x50\xde\x76\x58\x48\x98\x0c\x51\xd0\x9a\x90\x7f\x47\xd1\xbc\x76\x8b\x0d\x6a\x77\x0f\x9a\xee\xc2\x24\x39\x1a\xf5\x6c\x9e\x56\x28\x96\xb9\x7b\x7e\x7a\xba\xff\xd3\x7d\x8d\x49\xc3\x20\x21\xdd\x2a\xdb\x28\x18\x7d\x36\xcd\x32\x3d\x80\x43\x94\x2d\x2a\x95\xff\xfa\x19\x1a\x00\xe6\x9d\x4f\x9a\x7d\xf5\x50\xf8\x6d\x5a\x06\x21\x63\x2e\xa5\x20\xea\xb5\xed\xea\x8c\x7e\x95\x0c\x12\x85\xbc\x55\x0d\xb2\x1d\x44\x75\x32\x48\x53\x5c\x0c\x11\xce\x8d\x23\xf7\x3b\x14\xfe\xa0\xe2\xa9\x18\x16\xf7\x1c\x38\xcc\xba\x98\x8f\xc7\xaa\x0c\x03\x52\xcb\x7e\x84\xf7\x81\x0d\x85\x94\xa1\xce\xb3\xb0\x0f\xbb\x6e\xb0\x3f\xe6\x80\x0c\x53\x1c\xb6\x8c\x8c\x46\xb9\x9c\xfd\x76\x3f\x0c\xd4\x65\x1c\x6a\xac\x8d\x9c\xc4\xdb\x34\xbc\x95\x49\x1c\xa3\xc2\xd4\x2d\xc0\x79\xf4\xa1\x24\x0d\x11\x48\xbb\xdf\xec\x17\xf7\x87\xef\xeb\xc7\x5d\x7f\x24\x49\x9c\x37\xb4\xaf\xbe\x1f\xda\xea\xe0\xb4\x8c\x0e\xef\xe4\x81\x7b\x30\xd6\x48\xcd\x7d\x32\x0d\x34\xb2\xb1\x5b\x10\xa7\x9e\xfa\xea\x95\x93\xe7\xe7\x9d\xcc\x20\x55\x7c\x54\xf1\x3c\x23\x17\xf0\xb6\xea\xd6\x8c\x5e\x3c\x71\xfe\xa1\xe4\x81\x72\x5a\xb1\xf7\x9b\xe5\xe4\xd7\x33\x19\x62\x85\x7d\xbf\xda\x39\x65\x03\x29\x39\x0b\x11\x02\xd0\xad\xa2\x07\x73\x14\x2f\x87\xcd\xa3\x3f\xa6\xa5\xe4\x3d\xc4\x79\x59\x5d\xce\xfd\x5e\xfa\xaf\xa8\x07\x0c\xb3\x7f\x8f\xd1\x8a\xff\x8a\x6c\x28\x29\x45\x6c\xb0\xed\x72\xbb\xdc\x8d\x1e\xb8\x50\x3a\x21\xa4\x40\x61\xcc\x24\x4f\xe9\xe6\x16\xee\x1f\x45\xa9\xa0\xec\xd2\x78\xaf\x1c\x5b\x54\xa5\x53\x16\x70\xf3\x55\x76\x2b\x1f\x73\xe5\x37\x94\x04\x9b\x34\xc5\xec\x79\x2a\x94\xc6\xd3\x31\x1b\x1c\x5a\x36\x6e\xbf\xab\x6a\xf4\xe8\x9a\x9c\xcf\x52\x9c\xa0\x5f\xca\xaa\x29\x9a\xbd\x38\xfa\x37\xab\x18\x89\xa8\x34\xe4\x10\x50\xbc\x94\xb7\xa2\x38\x7e\xcc\x90\x92\xa5\xd2\x06\x01\x32\x42\x6b\x4a\x78\xd5\x24\xd4\x93\x9a\x05\x7c\xc0\x40\x74\xd5\xec\x75\x79\xff\xbc\x9f\x9e\x2a\x02\x54\x32\x79\x1a\x20\xa3\xa5\x56\x54\x0e\x22\x00\x07\x12\x17\xc6\xbf\x03\xa2\x10\x3b\x70\x0b\xd5\x5e\xac\xe2\xe7\x48\x14\xa6\x3b\x23\xc5\xcd\xe3\xa6\x7a\xa9\x7a\xe5\x2c\x29\x21\x0e\x10\x3c\x72\x57\x55\xde\x2a\xca\x1f\xe3\x39\xbe\x58\xea\x63\x3e\x97\xc5\xcf\x2b\x33\x0e\x29\x41\xc4\x89\x05\x90\x3f\x54\x1a\x50\xca\x65\xd1\x8e\x80\x33\xf6\x4c\xc3\x72\xae\x3c\x3f\x94\x8c\x4d\x3f\x51\xcb\x73\x9f\xe0\x49\x14\x8c\x18\x67\xdf\x56\xbb\x19\x58\xc8\xe4\x7b\x20\xcc\xec\x1d\x91\x32\xc4\xec\x1e\xa1\x02\x2b\x3a\xe8\x67\x3c\x9e\x4c\x00\x95\xf9\x4f\x84\x91\x0e\x6d\x93\x64\x5b\x94\x2f\xbb\xe2\xbf\x6e\x13\x53\xa1\x32\x28\x17\xee\xf5\xe2\x0f\xef\x63\xf0\xac\x8a\x92\x08\x53\xff\x87\x4b\x33\x94\x5b\x95\x2a\xca\x12\x2c\x9c\x97\x28\x68\x80\x5e\xb9\x8b\xe3\x71\x5f\x4d\x75\x0c\xbb\x33\x53\xa1\x3c\x61\x67\x07\xea\x0d\x26\x6c\x01\x15\xcb\x3c\x06\xbb\xf1\xbd\x88\x16\xbe\x0a\x92\x0c\x9d\x38\x8e\x48\x15\x1b\x19\x90\xe3\x48\x51\xea\x43\xf3\x2a\xba\x44\x7d\xac\x93\x60\xcf\x4c\x12\x86\x71\xda\x53\x97\xc5\x3d\x78\x31\x5d\xa9\x92\x8c\xa3\x54\xc4\x6e\xbf\x1d\xfd\xa0\x34\x22\x30\x1d\xe6\xdb\xeb\xe6\x28\xfa\x89\xac\x52\xce\x10\xbe\x58\x34\x54\x71\x98\xd4\x77\xc7\x6f\x52\x65\x56\x0a\xe7\x44\x44\x66\x5b\x69\xf9\xe4\x5c\xae\xb0\x70\xb4\xab\x54\x21\x8e\x08\x01\x1c\xdd\x55\xa6\x48\x68\x1a\xfe\x17\x4a\xf3\x3e\x62\xc6\xab\x3c\x4f\x53\x35\x74\x2c\x11\x27\xf8\xa3\xdb\xeb\xef\xea\xea\x74\x2b\xce\xe7\xcf\x4a\xb9\xff\xf0\xa2\x71\xcc\x5d\x8a\xa5\x09\x0c\xda\x40\x9f\x54\xe1\x14\x4b\x32\xd7\xdf\xbf\xa9\xaa\xa6\x85\x89\x65\x45\xb7\x34\x29\x9e\x7b\x03\xa3\xa5\xa8\x75\x83\xc5\x79\xa2\x8a\x69\x3f\xb5\x15\x13\x80\xed\x6c\x2b\x89\x86\x11\xc8\xc1\x6b\xc3\x48\xc5\x83\x08\xa3\x18\x53\xd5\x0a\xb6\x5e\x19\x4b\x2a\x1e\x02\x67\xa3\x16\x03\xb6\xcc\x6f\x2e\x1f\xab\x9f\xbf\xf6\xa3\x97\x8a\x2b\x86\x93\x19\x6f\xe9\xb0\xdf\x2e\x96\x87\x98\x05\x2e\x9a\x55\x22\x88\xb0\x35\xda\xd6\xa2\x29\x6d\x2f\x7b\xc4\x10\x9c\x5c\x4e\x08\x25\x7c\x7f\xc5\xe5\x35\xf3\x7a\xbe\x97\x19\x1c\xae\x12\x52\x85\x7d\x02\xf9\xa0\xdb\x7d\xb7\x23\xcf\xf5\xd6\x94\x8c\x49\xc6\xc6\xca\xc4\x0d\x21\x33\x4a\x65\x29\xea\xcf\x2d\x96\xf7\x87\xc5\xd3\xd3\x61\x7d\xeb\x8f\x18\x8e\x01\xcd\xae\x40\xf9\xbf\xe1\xe8\xd1\xa9\x46\xdf\x34\x0f\x63\xc3\x6a\xca\x68\x80\x69\x45\x5e\x49\x6e\xa9\xb1\x71\xf9\x2c\x1f\x59\x41\x64\x94\x6d\x25\xd0\x24\xb9\x11\x0d\xe8\x91\x09\xe4\x95\x68\xcd\x80\xd2\xa3\x4c\xa2\x31\xf3\x29\x54\x65\x77\xc9\xe9\x23\x30\x0c\x14\x8c\xc0\x25\x74\xf5\x5f\x66\x8f\xca\x70\x06\x59\xdf\x0a\x44\x34\xb7\xa8\xe7\x8c\xd4\xa4\x32\x46\xa3\x18\xda\xee\xb5\x7a\x1f\x45\xb5\xc3\xb7\xa6\x83\x3c\x43\xad\x11\x1b\x7c\x4c\xf6\xe8\xf1\xd7\xeb\x20\x37\xa8\x0a\x7d\x16\x85\x76\x24\x81\x71\xfb\xc0\xad\x82\x3a\x60\x0a\x03\x1e\x62\xfb\xfe\xbd\xca\xb3\x0e\x65\xce\x22\xcf\xe1\xe9\x86\x35\xd6\xbd\x0f\x65\x45\x89\xb6\xaa\xfa\x39\xa7\xa3\xd0\xa0\x81\xd0\x3f\x6f\x50\x12\x72\xa8\x41\x2c\x75\x94\xc4\x98\x5d\xec\xa0\xfd\xfe\xfa\xf1\xdb\xe8\xd6\x22\xa1\x70\x73\xb2\x01\xb0\xa7\x84\xa3\x8e\xbc\x38\x8e\x97\x73\x1d\x49\x6d\xb4\x5f\x03\x16\x97\x11\x66\x5c\x47\x2a\x47\xb2\x7d\x17\xe8\x74\x0f\xee\x77\xf8\xb0\xcd\x99\xd1\xcb\xd0\x11\x28\x1d\x0d\x46\x9f\x77\x97\xfd\xf5\x0b\xd7\xb1\x4c\x02\xdb\x4d\xb9\xbf\x4c\x0c\xd6\xa4\x8e\x8d\xc0\x4a\x37\x59\xa9\x6f\xde\x41\xdf\x55\xf5\xe2\x5c\xdc\x55\x35\xfa\x00\xcf\x6f\xa2\x3a\xe1\x09\x7a\x1c\xa1\x8c\x73\xff\x40\xd3\x90\x10\x06\x28\x64\x53\xd5\x76\xbc\x0f\x65\x82\xa5\x4e\xf3\x90\xaa\xf7\xfb\xe5\x70\x76\xe9\x54\x4a\xd4\x46\x6d\x2c\x10\x72\x98\xa5\xea\x4c\xa9\x2c\xb7\xdd\xf0\x5b\xd1\x8a\xbf\xe7\xb7\x22\x35\x4b\x15\x79\xf9\x75\x2f\xc4\x52\x1e\x93\xb9\x8a\x8c\x66\x2c\x27\xc7\xbb\x56\xbc\xc1\x43\x51\x2e\x7c\x77\x4c\x33\xc8\x9c\xc4\x0f\x41\x8b\xf1\xf7\x3c\x41\xfd\x15\xea\xa2\xbd\xb6\x42\x99\x5e\xd9\x98\xdc\xca\xe4\xf9\xd8\x78\x5f\x3d\xd5\xc5\x7f\x61\xc0\xc3\xd5\x3c\xe5\xa8\x4f\xf6\x05\xca\xe5\x6b\x41\xb9\xc4\x01\xf9\x5a\xd7\xdc\xd3\xc9\x37\x70\x1d\x61\x21\x65\x5d\x22\xa1\x69\x29\xd0\x6c\x6a\xfc\xc6\x84\x05\x9f\x5b\xb4\xfd\x97\x4a\x1c\xbf\x8a\x5a\x7b\x2d\x7a\xa9\x65\x94\x60\x70\x89\x98\x15\xa0\xc5\x64\xec\xd4\x24\xb5\x4c\x0c\x56\x92\xbe\x40\x4b\x16\x36\x63\xb1\x0a\xad\x52\x81\xfa\x05\x36\xb1\xad\x85\x06\x0c\x74\xed\x61\x1d\x47\x36\xa8\x43\x89\x68\x12\xe8\x6f\xc6\x62\xac\x52\xeb\x8c\xcb\x1e\x20\x66\xed\xc1\xec\x31\x88\x0c\x22\x62\x8a\xe6\xb9\x24\x74\xea\x04\x89\xa2\x4d\x10\x19\xe9\x8d\x07\x86\x48\xad\xd9\x3d\x5c\x9b\x98\x91\x32\x5e\x75\xd4\xf8\xd0\xf1\x87\xaf\x9b\xe7\x1e\x63\xac\x0d\xcb\x30\x5b\xbb\xaf\xd4\xdb\xc5\x3d\x30\x08\x44\x48\xf2\x82\x8e\x39\xfd\x2a\x88\xb2\x6f\x55\x5e\xfd\x79\x90\x20\xb7\xcb\xd6\xb9\xbe\xd4\xa2\x6c\x01\x9a\x07\x71\xc6\x72\xdb\xe8\xf6\x21\x0a\x43\x2a\x63\x69\x6c\xb8\x7d\x07\x70\xd9\x0c\x44\x71\xa0\x62\xeb\xfc\x80\x01\xd7\x0c\x4b\x09\xa2\x98\x64\xb0\x1b\x68\xd7\xaa\x72\x86\x27\xc8\x9d\x18\x40\x76\x21\x8a\x25\x4f\xbc\x10\x0c\x55\xde\xf0\x77\xf8\x2f\xe3\x26\x4e\x1c\x50\xb3\xaa\x9b\x11\x18\x13\x22\xe0\xce\x1f\xd2\x99\x32\x8e\xaf\x1f\x47\x09\xae\xf3\x87\x06\xda\xdd\xe5\xe5\x85\xf4\xc2\xf5\x6c\x13\xd1\x7d\x24\x4e\x55\x0f\xb9\xbd\xad\xd4\xe5\x34\x54\x87\xea\x27\x6d\xe8\x3f\x91\x03\xee\x91\x37\x7f\xde\x0c\x97\x12\x88\x45\x90\xdb\xe4\x7a\xb4\x6e\x43\x2c\x89\x43\xf1\x3b\x9c\x8f\x50\x0f\xd0\x72\x90\x04\x59\x64\x0b\xb2\x97\x79\xc3\x83\xfe\x46\x93\x38\x92\x96\x81\x1c\x8f\xc0\x78\x90\x24\xc6\x95\x75\xfd\x9e\x30\x89\x8b\xfd\xcd\xa7\x49\x90\x98\xd1\xf6\x6d\x0d\xef\xaf\x0b\xff\x90\x66\x31\x25\xa7\x27\x28\xf5\x7d\xf5\x59\x0d\x14\xd2\x2c\xd3\xe0\x2b\x66\x4b\xd1\x28\x31\xad\xd2\x43\x2e\x88\xab\x49\xf6\x74\xe7\xb6\x7a\x18\xea\xb5\xb8\x93\x24\x43\xf5\xfc\x3f\x2f\xe5\xef\xa2\x18\x3e\x28\x16\x24\xf8\xe6\xbb\x0d\xf6\x1b\xd1\x27\x7b\x5e\x01\xb0\x2c\x8a\xc9\x1e\xe3\xc7\xf3\xf9\x93\x9b\xe4\x60\x10\x38\x75\x23\x9a\x42\x8d\x30\xa3\xe3\x91\x2c\x92\x24\xb4\xe8\x81\x75\x0b\x27\xa7\xf0\x3c\xbe\x98\x4c\x73\xec\xbf\xec\x5e\xab\x1a\xfe\x1e\x00\x15\xa4\x4a\xb3\xd8\x1a\x13\x5f\x90\xfc\x59\xb4\xbb\x5f\xf1\x95\xed\xe7\x54\x40\x38\x50\x34\x86\x0d\x1c\x60\x15\x54\x92\xa6\xc6\x6a\x66\x17\xe5\x05\x26\x12\x71\x12\x54\x1e\x61\x3d\x03\xc1\x17\x5f\x05\x25\x00\x30\xe6\xd0\x81\xca\x19\x96\x70\x6a\xc2\xf7\xd0\x44\x99\x13\x44\xb0\xe7\xeb\x30\xc5\xa5\x14\x5d\xd4\x4f\x45\xf9\x89\x2c\x0d\x68\x69\x52\x61\xd3\x83\x21\x6f\x03\x40\x64\x18\x5e\x9d\xa1\x1e\x18\xba\x4d\x45\xc3\xec\xc9\x06\x28\xb7\x52\xe2\xa8\xf6\xae\xec\x6d\xaf\x64\x02\xce\x02\xa7\x6c\x39\xc5\x13\x9a\x40\x06\xe8\xe1\xf4\x56\x1c\x8f\xd3\x43\x46\x58\x7b\x94\x56\x1c\xbf\x8b\x17\xa8\x29\xfa\x98\x0b\xf8\x4d\x18\x07\x88\x2b\x97\x53\xf3\x8e\xd1\x3b\x32\x61\xcc\x30\x64\x35\x15\x22\x79\x77\x6d\x55\x8b\x17\xf8\x86\x65\x54\x77\x4a\xca\x43\xed\x0a\xac\xe5\x87\x8f\xfb\xfa\xf9\x66\xa2\x90\xc5\x96\x6b\x35\xa2\xcf\x99\x28\x53\x58\x68\xb9\x85\x1f\x85\x82\x81\xbd\xba\x34\x91\x20\x2c\xb4\x72\x8a\x2d\x37\x1f\xfe\x90\x8c\x82\x78\x16\x08\xf4\x57\x80\xa0\xff\xbf\xff\x0e\x7e\x53\x9c\x64\xe8\x83\x74\x68\xe0\x78\xc4\x3b\x99\x9f\x77\x26\x49\x63\x7c\x3e\xda\x85\xe7\x36\x7e\x1b\x9f\x95\x65\x22\x88\x06\x10\x89\xed\xa5\xf4\x03\x22\x33\x06\x99\xe7\x68\x1f\x36\x2a\xa6\x9b\x5c\xd1\x1c\x2a\x1a\x8c\x75\x3f\xd4\xe4\xb2\xb9\x52\x11\xad\x60\xe7\x63\xf5\x71\x57\x94\x45\xf3\xea\x77\x52\x93\x9b\x00\x51\x61\x77\x8b\xa7\x3b\x7a\xc1\xee\x08\xe3\x80\xfb\x8d\xcb\x29\x6e\x29\x19\xb9\x2e\x4a\xfc\x3a\x7f\x30\x3c\x48\xbd\xe3\x5a\xdf\x4d\x79\x17\xb5\x7e\xaa\xaa\xe3\xbc\x34\xa3\xe1\xb1\x42\xe1\x00\x4a\x38\x56\x3f\xcf\xc7\xaa\x46\x6f\xb5\xe7\xa6\x28\x5f\x56\x0f\xd5\x35\x95\xd5\x7d\x32\x4f\x71\xa7\xfa\x5a\x9c\xbb\x74\xf3\x4e\xd4\xbd\x70\x85\xe1\x22\xc4\xed\xed\x3f\x17\xa8\x3f\x96\xaf\x85\x2c\x16\x7a\x12\xed\x18\x2e\x33\xed\xf9\xc6\xaa\xaa\x75\x6f\x4f\x32\xdc\xf9\x8c\x08\x19\x88\x81\xb0\xbf\xc5\x2e\x4e\x9e\xaf\x88\x15\xd6\x03\x1a\x25\x86\xa3\x5e\x8a\x00\xd9\x14\xee\x5d\xdf\x81\xed\x9f\xd8\xf0\xdc\xa8\x30\x42\x9c\xd3\xae\x2a\x0b\xc7\xef\x34\x3a\x24\x70\x06\x69\xa0\xef\xc4\x11\x46\x31\x84\xd1\x39\xc7\xd6\xbc\x35\xcd\xb8\x13\x6e\x17\x31\x90\xe9\x04\x59\xda\x36\x06\x40\x93\xe1\x66\x9c\x55\x19\x90\xd2\x41\xaf\x56\xfb\xaf\xdb\x4f\x55\x20\x8d\x09\x49\xd7\xa2\x0b\x45\xac\x8a\xdb\xfc\xc0\x37\x91\x42\xdb\xdc\x83\x13\xd5\x1b\xcb\x83\x4d\xae\x9a\x59\x2c\xe9\x20\xaa\xff\xc4\x65\x59\x1a\x23\x43\xd1\x73\x20\x97\x55\x69\x8e\x85\x6a\x7b\x26\xf6\x68\x12\xa8\x20\x60\xd6\xaa\xc2\x0e\x42\x85\x7a\x69\x9f\x7b\x85\xa9\x20\x50\xe4\x94\xdc\x40\x7b\x10\xb5\x2c\xda\xe6\xd0\x23\x09\xfc\x22\xa0\x82\x10\x62\xd4\xbd\xf6\x18\x10\x9a\xdb\xfb\xca\x06\xad\xbf\x8d\x2f\x1b\xc5\x4c\x5a\xf5\xa6\xe6\x72\xd2\xa2\x15\xd1\xe8\x2d\xa8\x20\xca\x89\xd8\xef\x8a\x6e\x7f\x25\xcc\xe0\x3e\xa6\xf3\xd8\xb8\x12\xff\xb1\xaa\x67\x9d\x95\x54\x10\x27\x39\xe6\x44\xe5\x43\xf3\xd2\x7c\x17\x45\xeb\x07\xa5\x0a\x62\x15\x27\xf6\x27\x3b\xc7\xa1\xb9\x9d\x43\x05\xa9\x66\x58\x77\x87\x9f\xa0\x2e\x2d\x50\x35\x79\x28\x90\xf9\xaf\xb8\x2f\xbf\x24\xe3\x7a\xf4\x95\xac\x83\xbd\x66\x16\x49\xec\xd0\x40\x49\x78\x84\xc1\x26\xa1\x82\x4c\xc5\x29\x35\xb6\x7e\x62\x42\xe1\xff\x6e\x52\x10\xde\x30\xa6\xa8\xb4\xb3\x37\xb0\x49\xd4\x5d\x35\x9f\x6e\xab\x20\x0f\xc9\x14\xc1\x29\x97\x7d\xaf\x5c\x8f\x43\x05\x79\x6a\x44\x6e\x1b\xca\x7b\x10\xa7\x7d\xcf\x0e\x55\x41\x2e\x48\xec\xc1\x5a\x55\x3c\x54\x12\x5f\xd2\x2f\xa4\x74\xfb\x97\x9f\x6b\x0b\x31\x43\x7c\x86\x81\xba\x16\xc7\xe6\x3b\x14\xb3\x79\x94\x0a\x18\x50\x23\x99\x82\xca\x5d\x97\xd9\xfd\x3f\x77\x1b\x5c\x65\x48\xa2\xdd\xfc\xb1\xf9\x85\x8e\x88\x0a\x44\x94\x21\x34\xc4\x42\x0e\x1f\x8a\xd2\xad\x4d\x2a\x90\x91\xc2\xa1\x8b\x59\xe1\x5c\xcd\x4d\x05\x32\x15\xa9\xf1\x4e\x4a\xd3\x67\x39\xb9\x5f\xc9\x13\x27\x5f\x67\x29\x05\x2e\x8b\x19\xbd\x69\xc9\xb5\x31\x14\x67\xad\x7e\x16\xed\xbe\xfa\x9f\x0b\x5c\xe0\xb3\x6b\x7f\xf2\x28\xa5\x64\x60\x71\x5a\x95\x39\x54\xe6\x40\x6b\xe2\xe1\x0d\x3e\x22\xf7\xfb\x74\xa0\xb0\xca\x70\x73\xbc\xc0\xbe\x68\x45\x59\x5c\x4e\xcb\xa3\x68\x1a\x67\x75\xaf\x02\x08\x63\x5c\x31\x69\xd4\x3d\x88\x6e\x31\x2b\xfb\xf4\xbb\x3b\xc1\x20\x85\x0e\xf3\xb9\x8d\xd7\xea\x55\x01\x44\x09\xae\xe0\xcb\x57\x50\x6f\xb7\x9b\xfd\xe4\x47\x02\xcf\x15\x71\x19\x5e\xba\x90\x7c\x58\x08\x53\x81\x09\x73\x74\xac\x34\x00\x56\xfa\xba\xf1\x87\xb2\x14\xad\xb1\xbe\xe0\xca\x0a\xf5\x50\xf9\x8b\x4e\x09\x83\x30\xc1\x77\x82\xc1\xef\xf7\xab\x60\x41\x85\x41\x94\xe3\xac\x38\xf4\x12\x37\xdd\x58\x9b\x14\x30\x54\x18\xa4\x09\x6e\x0a\x0f\x0f\x9b\xbe\xf5\xa5\xc2\x40\x93\xac\xc5\xba\x79\x12\x6d\x31\x75\x52\x57\x61\x00\x49\x10\x7a\x54\x94\xd7\xc9\xf5\x4b\x62\x18\x46\x9c\xc1\x10\x45\x30\xaf\x70\xa5\xc2\x28\x24\x31\x3d\xa2\xe6\x53\xf4\x3e\x08\x2c\x55\x18\x71\x83\x93\xad\x76\x79\xe7\x54\x2c\x4a\x75\x41\x2c\x96\x27\x77\xcf\x8f\x7f\xb8\x8f\xc5\xa1\xa4\x77\x83\x77\xf8\x08\xef\xb7\x53\x21\x3f\x15\xc6\x69\x8a\x48\x34\x45\x13\xe3\x0b\xf4\xcf\x2f\x89\x62\x49\x7e\x05\xa8\x69\x7b\x73\x91\x83\x5c\x58\x85\x49\xac\x10\xa8\xf9\x08\xef\x7f\x6c\x49\x55\x1b\xd9\x48\x93\xa4\x74\x3c\x39\xc2\x24\x8f\x71\x73\x3d\x8b\x8f\xc5\xf1\xe8\x9e\x8b\x3b\xc8\x24\xba\xb8\x89\xee\xaf\x57\xf4\xaf\x41\x23\x45\x85\x89\xc8\x11\xca\x7d\x16\x85\x1e\x61\x2f\x55\x98\x86\x8a\x45\x03\x0c\x04\x6a\xc0\xf7\x63\x39\x4c\x25\x00\x45\x8a\x16\x2b\x8b\xda\xb7\x17\x5f\x95\x51\x61\xaa\xa2\x4c\x0d\x79\x29\xa3\x3e\x80\x0a\x53\x1d\x30\x9b\xe9\xae\x4e\x5d\x38\x09\xb0\x2e\xbb\x7d\x42\x5c\xa9\x47\xa9\x30\x0b\x22\x4d\x1c\x0b\xf4\x47\x5b\x56\xb5\xbf\x4e\x06\x19\xbe\x20\xc2\x1c\x6c\x57\xbb\xd5\xf6\xdb\xea\x70\xf7\xfc\x78\xeb\xcf\x30\x29\x06\x03\x9f\x6a\xf6\xab\x30\x17\x24\x00\x5d\x5e\x4e\x0b\x5d\x9d\x5b\xd0\x8b\x9f\x05\x4c\x99\xca\x83\x71\xc9\x42\x85\x14\xfd\xb7\x7e\x67\x09\x19\xd7\x58\xb0\xa6\x61\x37\xff\x45\x9c\xc5\xf8\xab\x49\xae\xb1\x3a\xea\xdd\xb1\x7a\x29\xfd\x63\x97\x59\xac\x9d\x74\x64\x2b\xde\x06\x3e\x21\xe3\xcb\x48\xa6\xb1\x4f\x60\x6a\x00\xfd\xbd\x6a\xba\xf0\x97\xfc\xfa\xfc\x95\x54\x9e\x58\xea\x83\xd5\xb0\x99\xdf\x19\x42\x15\x70\xdc\x48\x1e\xe1\x52\xdb\xbe\xb6\xbb\x86\x0e\x52\x6c\x60\xe2\x82\x85\x18\x4d\xd2\x26\xf3\xc7\x43\xf2\xb6\x38\x20\x12\x1a\xc7\x3e\x7e\x7e\x80\xd0\x57\xa1\x4e\x14\xa6\x22\x8a\x6a\x7d\x13\xa4\xa5\x0a\xc1\xd0\x38\x68\x1c\xef\x69\xbf\xe9\x35\xbd\x55\x14\x24\x0a\xa1\xf4\x54\x02\xb7\x1e\x9b\xf0\x3e\xbe\x48\x14\xe8\x20\x4f\x47\xdb\xc5\x7a\x1e\xa8\x67\x87\x7e\x14\x46\x02\x5b\xea\xba\x68\xe4\xa5\x6e\x80\x14\xb7\x46\x0f\x39\x0a\x05\x89\x3a\x1e\xde\x01\xde\x06\xdb\xbf\x3b\x0c\x1c\xb3\x83\xe7\xdd\x61\xfd\xb8\xdb\xaf\xf7\xcf\xfb\xf5\xe6\x71\x71\xef\xee\x3c\x4e\x00\x2c\xbc\x61\xbd\xdc\x38\xb5\x91\x7e\x0c\x45\xb1\xa0\xca\xb5\x5d\x1b\x30\xa8\x8d\xfc\xa7\x65\x8e\x1e\xd5\x5f\x17\xdb\xdb\xc3\x72\xf1\x74\x58\x3f\x1e\xb0\xfb\xe8\x4e\x48\x22\x83\x42\xb0\xd8\xb5\xdc\x82\xd0\xfe\x80\x49\xf3\xb0\xbf\xec\x1e\xca\x11\xcb\x5b\x45\x69\x2a\xb1\x7c\xd4\x42\xd3\xde\x88\xff\x3e\x40\xfb\x5a\xe9\xb5\xff\x7c\xaa\x01\xa5\xee\x76\xe2\x74\x3e\x02\x06\xb7\xe3\xde\xec\xff\x89\xd7\xa5\xa2\x8c\xc5\x3c\x76\x19\x7d\xa3\xa0\xd4\x62\xba\x0f\x44\x79\x16\x0a\x0f\x0f\x3a\xc1\x6f\xa3\x0b\xe4\x86\x23\xad\xfd\x7e\xf7\xe7\x93\xbb\x49\xc6\x89\x1e\x8c\xd8\x48\xf4\x6a\xb6\x0b\x98\x0d\x13\xc6\x97\xe7\xb1\x70\x96\x78\x56\x2f\xb2\x59\xd6\xa0\x8b\x76\x61\x4c\x71\x2c\x44\x0b\xcd\xf5\xfb\xe5\x49\x84\xdc\xe4\x1d\xb4\x8b\xd5\xd1\x78\x49\x59\x94\xd0\x68\x8a\x97\xf9\xf9\x14\x71\x11\x8c\xdd\x5a\xf7\xd6\x2a\x61\x4e\x51\x77\xfc\x8d\x82\x87\xb6\x90\xfd\xf2\xbd\x28\x4b\xa8\x11\x3a\x36\xbe\xbc\x10\x11\xf2\x51\x1e\x17\x0f\xeb\xc7\xcd\x76\xed\x1e\x88\x8c\x02\x43\x1b\x4d\xf7\xc2\xb0\x4a\x7e\x77\x29\xaf\x95\xf8\x54\xa4\xa2\x20\xb5\xb5\xa9\xdd\x19\xbf\x66\xaa\x6b\x34\x17\x2e\x0d\xcd\xe2\x98\xbf\x92\xc4\x2e\x2a\x59\x0c\x3b\xee\xe6\x9c\x5c\xa8\xfb\x40\x9a\xa4\x96\x68\x71\x68\xde\xab\xda\x6e\xc4\xee\xce\xb4\xd2\x58\xbd\xb4\x94\x98\x42\xc3\x44\x90\x61\xf2\xbc\x20\x60\x2e\x64\xdf\x82\x1a\xb0\x2f\xaf\xc8\xfe\x2a\x82\x30\x55\xce\x1d\x87\xfa\x5f\x5d\x94\xf6\xcf\x4a\x4e\xc7\x0a\x08\x25\x43\x37\x56\x28\xae\x1e\x0a\x9a\xf9\x9b\x35\x69\x80\xa2\x3c\x4e\xb7\xa1\x85\x91\x8c\x95\xf5\x7f\x1c\x9c\x1e\x62\x9c\xf6\x57\xf6\xb6\xee\x74\x4d\x48\xba\x4b\x59\x19\x54\xca\x3d\xa2\x40\x60\xf1\x52\x3e\x9f\x87\xb8\x71\x15\x07\x09\x47\xd0\x8b\x2b\xc9\x13\xc9\x6e\xa6\xce\xea\x9f\x45\x1c\xa4\x02\x87\x68\x97\x3b\x2c\x50\x0c\x6b\x45\x1a\x68\x57\x25\xd6\xd1\x4d\xc5\x01\x13\xe8\x9b\xf6\xee\xaa\x99\x3b\xbf\x31\xd8\x61\x18\x87\x69\x82\xed\x66\xd1\x22\x80\x02\x9a\x9e\x36\xa8\xe2\x28\x23\xcc\xb2\x8d\x93\xd0\x35\xbd\x2f\x55\xaa\x38\x62\x06\xcb\x83\x32\x8d\xc3\x2c\xc9\xa5\xff\xbb\x61\x62\x28\x8a\x87\x95\xd2\xbb\xaa\xde\x8b\xe6\x6d\x67\x93\xf4\xa9\x5c\xa2\xfd\x68\x2c\x34\x06\xa0\xb7\xbb\xa7\x5f\xe5\x36\x71\xac\x58\xee\xbb\x5a\xc3\x6e\xba\x3d\x9e\x84\x09\xa2\x10\x55\x55\xd5\xba\x28\x11\x81\xf5\x52\x43\x97\x15\xae\x9c\xf4\xd1\xf8\x61\x25\x11\x60\xd5\x65\x5b\x35\x30\xdc\x55\xe3\x24\x0d\x89\x85\xd3\xad\x23\x3f\xa0\x9e\x1e\xce\x43\x02\xe4\x88\x9f\x44\x14\x1d\x3e\xde\x84\x25\x38\xe8\x56\xed\xeb\x49\xcc\x18\xe1\xfd\x1d\x90\xb0\x8a\x13\x11\x61\x6c\x50\xa8\x6a\x45\xa4\x34\x74\x42\xdd\xb5\xe2\x05\x42\xff\x55\x86\x21\x03\x62\x71\x3c\x36\x6d\xa5\xde\x9a\xd1\x5d\x66\xa1\x52\xc9\x40\x77\x0d\x17\x9c\xb1\x9a\xac\x8a\xb3\xc4\x38\xdc\xda\x16\x7b\xe6\xe3\xdb\xc8\x58\x80\x39\xa3\x01\x38\x9c\x9a\x17\xff\x29\x11\x47\xcc\x02\x3e\x83\xff\xb9\x78\x63\x6a\x15\x67\x86\x11\x74\xa4\x6e\xfb\xa6\x87\x8a\xf3\x98\x04\x9c\x5c\x01\xac\x57\xa3\x9a\xec\xe8\x31\xcb\xa8\xc0\x52\xc2\xfb\xfe\x52\xc2\xe6\xec\x97\x47\x5b\x35\x1c\x82\xf4\x9d\xe4\xef\x3f\x86\xc9\x82\xd5\x15\x52\x31\x53\x0c\x69\x29\x45\xd9\x5c\xea\x6e\x46\x3b\xb4\xa4\x3d\xce\x63\x66\x48\x7b\xfa\xed\xbe\x52\x6f\xa0\x17\xf3\x8b\x58\xcc\x73\xd0\xce\xdc\x96\xe6\xc5\xdd\xc4\xa4\x4e\xc5\x22\x20\xe0\x95\xb2\x74\x33\x47\x7c\x9f\x55\xc8\x1f\x0f\x6c\xa1\xb9\xa0\xbc\xe8\x49\xa8\xb7\x27\x51\x0f\x6c\x69\xec\x29\x92\xb1\x20\xb3\x77\xd0\x37\x64\xbb\xd5\xac\x5b\x47\x47\x16\x62\xf3\x05\x97\x58\xca\x98\xa4\xdf\x5d\x09\x9d\x88\x82\xee\xa8\x06\x9c\x83\x14\xa1\x5b\xf0\xd4\x40\x49\x41\xc5\xd2\x70\xa0\x3a\x95\x06\x38\xcd\x82\x72\x55\xac\x22\x15\x58\x66\x05\xb6\xb6\x8a\xf6\xe3\xa6\x2a\xf5\xdd\xb1\x72\xc6\x76\x2a\x56\x29\xc7\x55\x1e\x3b\xab\xca\xff\x35\x0f\x08\xda\x4a\xee\x03\x54\xa2\x20\xa4\x5b\x14\x44\x61\x7f\x5a\x22\xac\x22\x00\xea\xf5\x3c\x56\x7d\xc2\x13\x2b\x65\x90\x70\x76\xae\xe1\x47\x51\x5d\x1a\x52\x08\x75\x47\x75\x94\xa3\x72\xe5\xa9\x28\xc7\x8a\x9e\x2a\xd6\x29\x21\x3c\x57\xd4\x76\xbe\xa9\x50\x2f\xad\x6c\xeb\x6a\x88\x03\xb8\x66\x97\x4f\x7e\xbd\xe6\x99\xf3\x67\xe8\x76\x02\x67\x20\x31\x39\xc9\x90\x18\x55\xd1\x34\x17\xb8\x16\xd1\x55\x31\xc4\x39\xb3\xc4\xc1\x55\x59\x5d\x5e\x5e\xef\xc8\xb3\x61\xf4\xbe\xba\x1d\xd0\x59\x41\xd4\x42\x1d\x8b\xff\x82\xe7\x57\xaa\x18\x8c\xce\xba\xa3\x4f\xcf\xbf\x0f\x27\xa1\x49\x12\x69\x1c\x2d\xf8\xa8\xad\x1e\x20\x15\x74\xc7\x37\x69\xd2\x90\x4c\x50\x8a\xf6\xa9\x6a\x9f\xea\x4a\x75\x79\xe7\x20\xf5\x9f\x4c\x10\x23\x02\x04\xe8\x3c\x56\xf2\x08\x28\x68\xd7\xcc\xb5\x12\x47\xa3\xde\x68\x9d\xd8\xe4\x73\xaa\x72\xa4\x92\x50\xc4\x48\xfe\xaa\x45\x0b\xb8\xe6\xc5\xfe\x88\x8e\x25\x29\x3d\x99\x4b\xa9\x89\x23\xe5\x8e\x45\x11\x25\x22\xaa\x02\x2f\x90\xb7\x70\x53\x76\xb0\x8b\x25\x51\xac\x22\xeb\x4b\xbf\x53\xaf\x54\x7c\x5c\xfd\x3c\x8b\x72\xa8\x8f\x37\xfe\x8d\x49\x04\x2c\x16\x83\x25\xec\x3b\x09\xde\xb9\xbc\x30\x89\xb3\x90\xf8\x6a\xa4\xdd\x8d\x6f\xcd\xda\xe4\xdc\x42\x59\x9d\x68\x47\xea\xcf\x06\x2c\xbe\x9e\x50\x1f\x6d\xdd\x90\xee\xd9\x00\xb2\xa3\x92\x24\x52\x58\xe2\x5d\x2f\x37\xa4\x37\x98\xb8\x0f\x27\x69\x16\x0e\xab\x99\xe3\x62\x54\x92\xc8\x30\x95\xae\x36\x3c\x90\xe5\x9d\xeb\xbd\xa8\x24\x31\x3a\x92\x13\x13\xcd\xd3\x55\x19\x28\x49\xc3\x94\x85\xa3\x35\xf0\xa6\x78\x79\xaa\xab\x53\x45\xa0\x39\x77\x1a\x0b\x94\x73\x8d\x87\xb6\x19\x7a\x70\xa8\x24\xe5\x19\x3e\x22\x45\x32\xff\x03\x72\xa5\x4a\xb2\x8c\xfc\x2e\x0f\xdd\xa4\xfb\xb4\xe7\x34\xbb\xc6\x7d\xf2\xc3\xf2\x28\xc0\x30\xdc\x8b\x3a\x0c\x8c\x89\xc7\x25\x2a\xf7\xc4\x73\x41\x12\x82\xb5\x2d\x83\xcc\xee\x06\x49\xae\x01\x25\x4e\x70\xc0\x68\xb7\x40\x26\x3c\x80\xcc\x49\xbc\x9e\x8f\xc5\xf8\xd7\xf1\x24\xe2\x36\x62\xfd\x67\x25\xaf\xd7\x16\x77\x1a\xe7\x2e\x5a\xde\xd7\x42\xa3\x6e\xce\x34\xce\x49\x38\x68\xb0\x75\xd7\x6f\xd0\xb4\x53\xa9\x4a\x95\x08\x11\x04\x36\xd3\xbe\x25\x25\x5f\x52\x8e\xc3\x8a\xef\x40\xd0\xa6\x3b\x33\x42\xe0\x3f\xe9\x15\xd8\x3f\x4a\xce\x89\x5b\x53\xb4\x47\x58\xfb\xaa\x55\x22\x4d\x86\xa5\xa8\x13\xe9\xaf\xfb\x40\x23\x51\xa1\xc2\xef\xdb\xbd\x7f\xb4\xea\x75\x18\x83\x24\x4a\x05\xb6\xb5\x8f\xdd\x91\xd1\x31\x1d\xc5\x08\xc8\xdd\x82\x15\x19\xf3\x07\x58\xc8\x55\x0f\x5f\x72\x44\x6f\x7f\x58\x30\xac\x9e\xad\x7e\x40\xd9\x7e\x2f\x4a\x7a\xad\x9f\xbc\x2c\x08\x02\x64\x31\xef\x0b\xf5\x06\xd3\x31\x6d\x04\x43\xb4\x1d\xd8\xbd\x7a\x69\x47\x4a\x75\xd5\xb3\x9a\x5c\xd5\x48\x85\x44\x4d\xa1\x14\x9c\x6d\x41\x85\x80\x42\x9f\xb6\x6f\x46\x17\x48\x83\x2c\xc4\xc4\xf5\x47\xd5\x82\xc3\x7b\xce\xd5\x11\xd3\x40\x0b\xd4\x6a\x90\x97\x8f\xa5\xa8\x87\x2d\x49\x95\x06\x86\x56\xb1\x53\x51\xb6\xe8\xdf\x5b\x8a\xe3\x6f\xbf\xfc\xda\x38\x67\xb8\x07\xca\xcb\xc7\x23\xfc\xec\x22\x3e\x17\xb6\xa6\x31\x07\x49\x25\x89\xf3\x51\xf4\xa1\xd2\x6c\xea\x93\xa6\x91\x62\x16\xbd\x64\x31\x70\x53\x03\x7b\x95\xa6\x71\x80\x91\x20\xca\xe5\xa3\x54\x0e\x2e\xe4\xee\xfb\xf2\xdc\xc4\x36\xc5\xb5\xea\x92\xe3\x2e\xf9\xe4\xce\x73\xa0\xa4\xa5\x28\x49\x02\xfe\xa9\x86\x97\x52\xd8\x35\xc4\x6f\xf2\x29\x93\xca\xb0\xd1\x2a\x45\x0d\xa4\x5f\xbe\xce\x54\xe4\xd4\x1d\xb2\x0d\x4e\xa4\xb8\x3c\x41\xff\x56\x86\x67\xb2\xc0\x96\x75\xab\xcb\x14\xda\xfe\xc9\xc5\xa5\x40\x3e\xd9\xb2\x2a\x9b\xb6\xbe\x74\x09\xf8\x1e\x9a\xeb\x3c\x6e\x66\x8f\x4c\x65\x18\x63\x04\xfb\xb4\xf8\x73\xf3\xbc\x3f\xdc\xae\xee\x17\x7f\x1e\xd6\x8f\xfb\xd5\xf6\x9b\x2f\x62\xa5\x32\x8a\xb0\x24\x71\xeb\xe1\xc3\x3d\x2e\x78\x7c\x2b\x32\x4d\x10\x1b\xd0\x56\x37\x3d\xd1\xc8\x4f\xac\x54\x05\x1c\x31\x2a\x27\x8b\xe0\x1e\x76\x9b\x55\xaa\x2c\x73\xa3\xb1\x6a\x33\x68\xef\x43\xe4\x9a\xf1\xe0\x50\x89\xc0\xe8\x43\xb4\xad\x50\xaf\xf6\xe5\x7e\x32\x90\x94\x90\xe8\xef\x46\x2d\xb2\x6e\x1e\x0f\x18\x00\xff\x18\x8d\x76\x05\x80\x4a\x56\x7e\x39\x77\x62\x23\xde\xe3\x7c\xfe\xf9\x9b\x80\x3b\x7d\xdb\x47\x69\x8d\x62\x9a\x7b\xcb\x51\x1b\xe5\xe9\xa9\x51\x81\xee\x35\x21\x48\x12\x67\x84\xcf\x54\x59\x10\x03\x56\x7f\xed\x82\x36\x54\xd8\xb4\x67\x84\x3a\x50\x83\xfd\x74\x10\x6d\x8e\xee\x2b\x8b\x82\x1c\x87\xd2\xff\x56\x45\xb9\xaf\xf6\xb5\x50\x6f\xe3\x7d\x3c\x8b\xb2\xcc\xf1\x94\xbf\x8a\xe6\x95\x58\x18\xad\x98\x06\xfa\xf6\xec\x38\x48\x41\x7b\x5e\x11\xad\x77\x83\xc5\xf3\x97\xbd\xbc\x2c\x4e\xb4\xb0\xa5\x97\xc3\x9b\x03\x4c\xaa\x2c\xce\x82\x84\x9e\x79\xb9\xa2\xe6\xef\xe4\x47\xc4\x0c\x10\x98\x53\x5f\xe4\x51\xfc\x73\xf5\x34\x58\xdf\xb3\x98\xf3\x0c\xdc\xed\x17\x76\xe3\x99\x7c\x5c\xc4\xce\x04\x97\x64\x28\x27\xcf\x32\xb1\x01\x5d\x79\xf1\xe8\x35\x77\x44\x19\x25\xdd\x1e\x87\xad\x09\xfd\x20\xea\xba\x10\x2f\xd0\x9f\x03\x91\x1e\xf8\x96\x90\xf6\xed\xe4\x1b\xd2\x3c\xe3\xae\x01\x27\x5a\xf5\x3a\x0a\x58\xb2\x34\x87\x2c\x1a\x52\x43\xe6\xc7\x58\x96\xb1\x14\xe7\x06\x21\x2f\x47\xf4\x5d\x97\x93\x8e\xff\x71\x9f\xd3\x31\x86\x28\xf2\xf2\xb1\x2a\x5f\x8a\x12\xfa\x05\xe7\x5f\xd6\xf6\x4d\x65\x19\x28\x2c\x05\xec\xa1\xae\x05\xf9\xe9\x8c\xc2\x13\x7b\x5a\x9e\x93\x5c\x60\x03\xed\xea\x61\x41\xfd\xf1\xc9\x02\x90\xe5\xdc\x20\x40\x63\xff\xfc\xb4\x74\xbf\x31\x97\xa1\xcb\x0a\x1c\xe3\xa4\x0b\xc6\xdd\x61\x1e\x30\x44\x59\x3e\x7d\x5d\xec\x56\x87\xe5\xfd\x66\xb7\xba\xf5\xc7\xc2\x1c\x71\x80\x7e\x74\x3b\xe2\xda\x64\x68\xaa\x20\xc4\x26\xc5\x62\xff\xd0\x25\x1e\x7f\x89\x30\x54\x99\x62\x80\x5e\x3b\x8f\x77\x7f\x2c\xab\x91\xc6\xba\xca\x94\xc8\xb1\xef\xdc\x10\xb4\xfb\x46\x34\x70\x2f\x3e\xa6\x4b\x75\xa6\x0c\xb9\xb0\xdd\xac\xb6\xfb\xe5\xfd\xf3\xcd\x72\xb3\x76\x85\xf9\x4c\xe7\x0c\x21\x9c\xf2\x52\x97\xeb\xfb\xbb\xf9\x3d\x27\xd3\x4c\x0a\x8a\xe8\x5f\xa1\x2e\x5a\x27\x91\x35\x65\x67\xbb\xb3\x45\x8c\xe5\xa9\x1a\x54\x71\x2e\xa0\x6c\xbf\xad\x9f\x26\xaf\x48\x4b\x02\x3a\x76\x51\xa0\x50\x6f\xe7\xaa\x45\xeb\xc0\x49\x80\x97\x41\x98\x42\xea\xaa\xf1\x47\xf1\x61\x91\x8e\x96\x59\x3b\xad\x3c\x64\x90\x19\x44\x39\xb9\x75\xc6\xa9\x8e\xaa\x0c\xf2\x00\xd0\xc4\x76\xb7\x1f\xfe\x7a\x60\x29\x56\xfb\x8f\xe2\xbd\x5b\xe2\xab\xba\xa5\x9e\xd1\xb8\xbf\x98\x81\x8a\x11\x75\xdd\xbc\x17\x18\xd6\x7d\x11\xa7\x91\x1e\x46\x77\x06\x68\x4a\xb8\x0b\x05\x1b\x83\xbd\xad\xf1\x4f\x31\x01\x60\x22\x79\x53\xd4\xed\xab\x16\x1f\x4b\x51\x3a\x75\xe9\x2e\xe3\xe7\x58\x74\x40\x83\xc0\x7d\x71\x82\xfb\xbe\x8c\x96\x07\x52\x86\xc2\x81\x9f\x9a\xd7\xd9\x92\xf5\x78\x11\xcb\x03\x4d\xde\x31\xcd\x6b\xf5\x3e\x62\xf2\xd8\xe3\x21\x63\x28\xf6\x72\x29\xef\x8b\xf2\xad\x5b\x4e\x89\xa3\x34\x43\xdd\x51\x79\x94\xc8\x88\xba\xa7\x7b\x1b\x64\xbb\x03\x8a\x63\x47\x0d\x41\x65\x18\x52\xf7\x22\xf3\x2a\x8f\x40\x21\xb4\xd9\xa5\x66\x57\xe5\xd7\x3c\x09\x95\xe3\x7f\xde\x16\x9a\xea\x87\x55\xd5\xeb\x07\x8d\x07\x61\x9e\xc4\x02\x8b\xd2\x94\x05\x6e\x1e\x36\x87\xed\xea\xfb\x62\xeb\x34\xa2\x55\x9e\x40\xa4\x04\xed\xda\x07\x4a\x8a\x87\x0a\x10\x2a\x4f\x83\x98\xa7\x4e\x9c\xa5\x6c\x5f\x37\xe7\xeb\x65\x6c\xd0\x38\xb8\x5a\xdc\xf2\x34\xa1\xc6\xeb\x7a\xb9\xf1\xbd\x4e\x22\xd8\x8c\xb1\x74\x2a\x4f\x53\x99\x0f\xba\x65\x04\xc7\x1e\x6f\xa0\x79\xca\x93\x94\x54\x81\x2d\xce\x73\xf2\xdc\x53\x6e\x18\xf3\x0d\x86\x89\x0b\xa4\x3b\x47\x28\xb4\x83\xf6\xec\xd2\x85\x31\xdf\x3c\xd1\x7f\x70\x3f\x2a\xc1\x98\x56\x48\x75\x75\x84\x00\x87\x3b\x28\xf5\xa9\x2a\xe1\x03\x7d\x84\xc6\xe7\x64\x09\xc7\x27\x6f\xa5\xcd\x4e\x02\xe3\xc2\x3f\x0b\x38\x4e\x7f\x77\x9e\x64\x8c\x2c\x90\xcf\x96\x8a\x51\x54\x25\xd9\x5c\xdc\x55\x1e\xb3\x31\xf9\xa1\xb9\x64\x08\xde\xbd\x59\xad\xee\xfe\x1c\x2e\x70\x39\x8b\x55\x6a\xa3\xeb\x1b\x51\xbe\x51\xa6\xe8\x40\x25\x9b\x72\x22\x7e\xad\x72\xa6\x14\xf7\xd6\xc8\x4d\x97\x95\x83\xe7\x3d\xaa\x9c\x27\x1c\xa1\x73\x28\x30\x72\x18\x16\x40\x73\x9e\x6b\x17\xc6\x3f\x88\x9f\x24\x0e\x82\xb4\x9a\x39\x7b\x18\x95\x73\xc6\xb0\x19\x8a\x23\xdf\x73\xea\xdc\x41\x21\x02\x9b\xfe\x7a\x31\xed\xd9\x40\x25\xe7\x20\x8c\xc3\xcf\x57\xc7\xaa\x1e\x01\x2d\x55\x2e\x02\x32\xba\x44\xfd\xeb\xc6\x73\x41\xfc\x17\x75\x29\x2b\x77\xb0\x6b\x2c\x21\x8f\x38\xde\x2a\x97\x91\xc5\x3d\x94\x45\x6b\xa1\x91\x8b\x52\xaf\xba\x45\x06\x97\x50\x7f\x5e\x12\x42\xaf\xe9\xb9\xad\x8e\xc7\xe7\x52\x4f\xb7\x91\x5c\x66\x01\xd2\x1a\x0f\x70\x2a\xda\xef\x55\xfd\xe6\x21\x9f\xf3\xb3\x45\x25\x0a\xc1\xf9\x2f\x55\x4b\x0d\x42\xf7\x75\x4a\x73\x4c\x4d\x2c\x7f\x68\xd5\xbe\x7e\xa9\x1c\x5b\xa4\x3b\x4a\xa6\xc8\xba\xf8\x01\xf1\xe4\xfd\xea\x50\x90\x10\x31\x65\x34\x5f\x8b\x97\xd7\x2e\x30\x75\x92\x15\x2a\x87\x50\x72\xdf\x3b\xd5\x70\xc2\x9a\xf9\x2c\x96\x2f\x87\x28\xc2\x7c\x98\x40\x7c\xee\x8f\x09\x8f\xa8\xa9\x67\x8a\xe3\x91\xe4\x7e\x11\xe9\xf9\xe4\xc5\x66\x54\x0e\x3c\x0e\x88\x4d\x78\x3a\x15\x2d\xaa\x16\x0e\x30\x2b\xe3\x6f\x31\x71\x86\x99\xc4\xb7\xfb\xc5\xed\xe2\x7e\xfd\xb8\x70\x17\x31\x29\x77\x26\x62\x5b\xf8\xcf\xa5\xa8\xbb\xb0\x8d\x8c\x3a\x27\xcf\xdd\x64\x01\xd3\xde\xa5\x0f\xf6\x1f\xd6\x80\x7e\xd8\xe4\xbc\x76\xc7\x71\x1f\x66\x11\xc2\xb8\x6a\x10\xfa\x50\xb0\x83\xa8\x6b\xe1\xb7\x1d\x23\x38\x01\x49\x24\xae\x87\xcd\xd3\xe0\x10\xc4\x4c\x8d\x92\x52\xb7\xe9\xff\x3a\xc9\x63\x81\x21\xeb\xbc\x6e\xeb\xf9\xcd\xff\x8d\xe3\xee\x8b\x55\xe8\x8d\x59\x4f\x12\x64\x16\x6a\x89\x2c\xad\xdb\xd5\xdd\x76\xb3\xdb\x1f\xee\x16\xcb\xfd\x66\x7b\xd8\xaf\x16\x0f\x8b\xc7\xdb\xc5\xed\x37\x77\xa1\x28\x32\xd8\xd3\xa3\x81\xfa\x67\x97\xb9\xcd\xbe\x5c\x16\x65\x61\xe6\x4d\xc2\x9b\xd7\xe2\x7c\x9d\xe4\xb1\x08\xf2\x08\xac\xd5\x90\x45\x7d\x0e\x31\x3d\xc3\xfd\x9d\xc5\x31\x20\xa1\x8d\x10\x89\x25\x9e\xf1\xdf\xdf\xae\x0d\x29\xd9\xa7\xf6\xb3\xb3\xc3\x83\xa5\xa1\xc2\x6c\x63\x07\xea\x52\x17\x6d\x01\x04\x03\xbb\xe9\xcb\x11\x2c\x8b\x49\x3c\xde\xad\xf0\x24\x26\x32\xe8\x5c\xb1\x2c\xcd\x10\xbc\xd4\xc2\xe9\xfc\x50\xbe\xd4\xfd\xdf\x99\x24\x0e\xf4\xdb\xc8\xe7\x65\x72\x0f\x59\x2a\xf3\x21\x24\x1b\x29\x93\x83\xc2\xdc\x6c\x89\x9f\xe5\x91\xcc\x32\x57\xbd\x9f\xbc\xcf\x3c\xd3\x98\x80\xc9\xaa\xfe\x24\x4f\x60\x39\x68\x84\x6c\x21\xbf\xfb\xf1\x72\x5a\x5e\xa1\xe5\xd8\xaf\x50\xb3\x8c\x85\xcc\x64\x6e\xfa\x60\x12\x60\x2e\xe5\x64\x37\x62\x4c\x02\x0a\x42\x3e\x5e\xaa\x1b\x31\xf4\x28\xfa\xcb\xb0\x9b\xf1\x30\x40\x0a\x86\xcd\x98\x30\x1e\x1b\x3f\x00\x9e\x25\x5e\xd0\xac\x0b\x08\x07\x18\x49\xc6\x33\xce\x94\x6b\x38\x9e\x0b\x35\xac\x80\x32\x9e\x03\x86\xe3\xab\xc7\xdb\xc3\xee\xf7\x4d\x78\x78\x7e\x5c\xef\x77\xfe\xa8\x4e\x79\x36\xe0\x54\xcd\x69\xa3\xba\x53\x81\xa1\xe0\x37\xa8\xaa\xf9\x68\x5a\x38\x0d\x69\x40\x8a\x09\x96\x61\xc9\xe4\xcf\xe8\x50\x0f\x4d\xea\x15\x13\x86\x56\x72\x4b\x65\x7d\x5e\xbb\x9e\xd9\xc0\xf4\x4f\x31\x19\x27\x48\xc1\x47\x82\xc7\xa0\x7b\xc2\x24\xcf\x2c\x04\x75\xe4\x13\xf3\xc9\x10\x97\xc2\x60\x6a\x74\xa2\xbc\xd6\x4f\x44\xdf\x01\x60\x52\x07\x99\x25\xc5\x3e\x97\x45\xdb\x6c\x4a\x58\xb5\xaf\x4b\x51\xde\x5c\x26\x6b\x21\x53\x81\x21\xe4\xae\xcd\xcf\xa8\x5b\x39\xbb\x24\x31\xf7\x91\x58\x25\xa9\x7b\x17\x6f\x50\xae\xf5\xb8\x16\xcf\x54\xc2\xc9\x38\x58\xfd\x15\x31\x7c\x32\x86\x95\x26\xeb\x2d\x2f\xed\x59\x8b\x97\xaa\x6c\xee\x8a\xe3\xc9\x5f\x1b\x22\x04\x89\xd0\xba\x81\x7e\x60\x4d\x7f\x8c\x61\x4a\x6d\xc5\xd7\xbf\x88\x66\x08\x45\x63\x90\x48\xcc\xf8\xef\x37\xcb\xdf\x17\x0f\x9b\xe7\xc7\x7d\xec\x0f\xc9\x04\xf3\x9c\x12\xde\x2f\xcd\x27\x1a\xcb\x8a\x99\x40\x8e\x16\x8e\x59\xb7\xd2\x4f\xe6\x17\x0f\x82\x14\x65\x67\xbe\xf8\xf2\xe1\xb6\xaa\x4e\x8b\x52\x13\xa1\x7a\xf4\x4d\x3c\xc8\x22\x6c\x1f\x3b\x7d\x49\x97\x3d\x2f\x5f\x8b\xa3\xae\x61\xa0\x60\xe4\x3e\xa0\x05\x22\x03\x90\xfe\xf6\x78\x39\xf9\xbf\x43\x8e\x3f\x0c\x77\x1d\xd4\x7a\x9f\x93\x20\x41\x9d\x0a\xc4\x66\x60\xf9\xad\x67\x05\x2b\x1e\xa5\x1c\x1b\x9f\xc7\xea\x65\xa1\x86\xad\xba\x39\xbc\x05\x8f\x24\xa9\xba\x53\x5c\xfb\x24\xd0\xa9\xfb\x4a\x66\x50\xf1\x08\x24\x42\x3a\xac\x61\x86\xa7\x5e\xfd\xd5\x70\xf9\xe5\xda\xcf\xe3\x5c\x21\x74\xed\xb6\xfa\xe1\x2b\x35\x3c\x06\xc0\xc4\xc1\x54\xf5\x3b\xf6\x5e\x8b\x29\x2e\x80\xc7\x26\xc3\x6a\x12\x56\x62\x2e\x28\x41\xf6\x09\x29\x48\xf1\x24\x4c\x75\xe0\x43\x95\xcd\x24\x53\xe7\x49\x94\x62\x01\x61\xb3\xdc\x2f\x68\x88\x0e\xc3\x6f\x9e\xf0\x1c\x4b\x42\x96\x28\xe7\xf1\x67\x13\x66\x9e\xe2\x89\xe6\x44\x58\xa3\x9e\xf5\xe7\xca\xf2\xff\x98\x8e\xc1\xf9\x47\x93\x80\x33\xd6\x6f\x89\x7c\x22\xc6\xbb\xfc\xe4\xf4\x34\x61\x88\x3f\xa2\xb0\xe0\xce\x6a\x72\xd9\x2a\xf0\xe4\x27\xa7\x9a\x21\x2f\xa0\x89\xad\x0e\x6d\x68\x0f\x64\x41\xc8\x2d\x26\x0d\x71\x54\xf8\x24\x6c\x42\xec\x4e\x91\x1c\x9b\x1d\x95\x31\x50\x13\x1e\xa3\xd9\x57\x0e\x10\x3c\x29\xd6\x4e\xfe\xe9\xa1\x94\x3c\xcf\x32\x82\x4b\x35\x9a\x18\xe9\xdd\x5b\x3e\x61\x87\x5f\x89\xf3\xa0\x3b\xcb\x73\x19\xb3\xee\x9e\x6e\x16\x8f\xcb\xcd\xf6\xf0\xc7\xe1\xf9\xe9\xcb\x76\x71\xbb\xda\xfa\x13\x40\x63\xc9\x4a\x9e\x0a\xf7\x27\xa6\x18\xa7\x9d\xeb\x07\x1c\xab\x33\xd4\x07\x37\x1d\x0f\x3e\x1a\x9a\xbc\x3e\x66\x4c\x34\x4c\xd5\xbf\x15\xc7\xa3\x98\x22\x60\x38\x0f\x35\x76\xc3\x6e\x7a\xf7\xa8\xbf\xdc\x47\x39\xcf\x48\xd6\x4b\x7a\x97\x77\xc5\x45\x1c\x5a\xe2\xde\x16\xce\x35\x34\x50\x5e\x95\x72\xb8\x60\x0c\xeb\xa1\x4a\x90\x70\xda\xf8\x61\x8e\xee\x4b\x48\x12\xf2\xb1\x1d\xa4\xa5\x28\x35\x82\xff\xc7\x35\x64\x2e\x54\x9c\x5b\x11\xf9\xe1\x6e\x3e\xbf\xb6\x73\x01\xb1\xc9\x9c\xde\xb8\xed\xab\xd9\x43\x32\x0e\xf1\xd6\x5c\xaf\xec\x0e\x60\x5d\x62\x46\x32\x89\x3f\xb8\xcc\xc3\x84\x34\x71\x40\xa0\x28\xe7\xe4\x47\xca\x9c\x94\xb7\xf7\xa2\x79\x1b\x6c\xb0\x5c\xe6\x2c\x72\x56\xa5\x17\x41\x1c\xff\x5f\x3a\x5e\x28\x2e\x45\x86\x60\x00\x79\xf9\xd8\x82\x71\x17\x52\x01\x8f\x3d\x89\x03\x74\x97\xb4\xf9\x48\x83\xab\xc4\xdb\x9d\x1c\x46\x6c\xbf\xbf\xc0\x65\x4d\xbe\x59\xe7\x69\x68\xc1\xad\xfb\x02\xea\xeb\x36\x2d\xd7\x8c\xc4\xe6\x2d\x10\x80\xf4\x24\xbb\x41\xf4\x15\x8e\xe7\x7e\xfb\xfa\x0c\x4d\xc2\x35\x44\xa8\xfa\xe7\xc2\x15\x3a\x69\x20\x9d\xa8\x38\xe4\xb1\x35\xaa\x55\x35\xf6\xec\x6f\x07\xb3\xc8\x44\x1e\x79\x49\x02\xbf\x7a\x0f\xe2\xe4\x87\xa3\xd1\x1c\x95\x97\xaa\x72\xd7\xc5\x5c\xa0\x8b\x4f\x5a\x6f\x22\xc8\x4d\x62\x1b\x3f\x56\x4d\x03\x89\x74\x7f\xd1\xf7\x12\x01\xd3\xc8\xb8\xa0\x6d\xa6\xa9\x8e\x8d\xa9\xea\xd7\xc2\x07\xf0\x22\x30\x20\xfb\xfa\xca\x5e\x8c\x85\xd2\x94\x08\x03\x29\x6c\x08\x83\x38\xbc\x5d\xf1\x32\xae\x25\x89\x28\x8c\x45\xd8\x8b\xc0\xaa\xd7\x21\x0c\xdf\x55\x8b\x44\x14\xf2\x44\x79\x47\x0a\xcc\xe6\x86\x4a\x22\xe3\xd1\x29\xa2\x8c\x87\xf9\xc0\x4e\x6e\xaa\x1d\x3a\xff\x8c\x62\x60\x31\xe2\xd0\xe5\xac\x99\x8f\x12\x49\x10\x22\x64\xe3\x50\x83\x7a\x15\xf5\xcb\x27\xe0\x02\x91\x84\x59\x3a\x30\x99\x7f\xaa\x8b\x1f\xa2\x85\x01\xda\x5e\x24\x79\x80\x32\x36\x58\xcf\x71\x3f\xa8\x1b\x7f\x37\x1f\x63\xe2\xaa\x5b\x36\x26\x37\x62\x62\x1b\xbe\x95\xe3\xb2\xd4\x27\xbf\x2c\x0d\xa2\x40\x3a\x36\xc4\xfd\xcd\xae\x3a\xea\xc3\xd3\x76\xfd\xcd\x3b\xe1\x29\x91\x6a\x25\x29\x29\x72\x6b\xee\x0a\xf9\x55\x6e\xed\x10\x59\x6c\xb0\x87\x20\x2f\x1f\xa8\x27\xf6\x49\xef\xd3\x9d\x2d\xc0\x19\x39\x7e\x79\xda\x3d\x14\xa5\x57\x2f\x51\x22\x4f\x48\x81\xf9\x05\xda\x45\x59\x5e\xc4\xb1\x47\x3d\x89\x9c\xe9\xd4\xa2\xf4\x08\x4d\x73\x5f\x34\xed\x28\xe8\x15\x39\x4f\xb4\xb3\x13\xf8\x2f\x60\x8d\x78\x53\x5e\x79\x9b\x29\xc1\xc3\x14\x7b\x29\x4f\x47\xa1\x60\xc6\x5e\x5f\x09\x9e\x07\x18\xb3\x1d\xce\x50\x77\xd9\xf3\x7e\x62\x06\x7d\x2d\xd8\x35\x9d\x2d\x73\x21\x9e\xe0\x3c\xc1\xfa\xc8\x3b\x14\x91\x2b\xe3\x0b\x91\x86\x28\x3d\x77\xbf\xbe\x5b\x0d\xea\xf8\x42\xa4\x0a\x05\x9a\xef\xab\x13\x1c\x8b\x61\x0c\x23\x84\x0c\x95\xb0\x0a\x0d\xa2\xfc\x18\xa3\xab\x84\x00\x92\x11\x77\x3b\x9f\xf5\x3a\x5a\xe8\x1f\xbf\x42\x6c\x09\x19\x4a\x2c\xac\xed\x2e\xd2\x56\xde\x16\x88\x7f\x98\xc2\xc7\x84\x64\x09\x6e\x7f\xba\xf8\x61\x1c\x20\x61\x76\x8d\x90\xca\xe0\x6d\xfe\xf1\x70\xff\xe7\x8d\xd0\x1e\x1d\x20\x54\x9e\xa3\x57\xdd\x97\xaa\xba\x17\x97\x52\xbd\x22\xd2\xa8\x17\xca\x50\x42\x87\x1c\x12\xdb\x9a\xc3\xce\x5e\xf7\xe4\x17\xfa\x4a\xaa\xda\x9d\xae\x33\x2c\x05\x4b\x68\xc3\x8d\x99\xbc\x6e\x0d\x26\x4c\x6d\x52\xbb\x59\x3e\xed\xc9\xa8\x62\xf6\x3a\x90\x73\xec\x88\x36\xaf\xd5\xfb\xdd\xd3\x30\xc3\x15\x00\x1c\xc3\xfb\x7f\x16\xaf\xd5\xc7\x84\x03\x28\x4c\x22\x03\xcb\xb0\x58\xd7\x30\xd6\x89\x55\x32\x08\xe2\xa4\xaf\xf0\xac\xda\x66\xb6\xbe\x23\x83\x5c\xa1\xd6\x94\xc7\x70\x5a\x39\x5d\x77\x98\x51\x3f\xa5\x68\xba\xdc\xd6\x2e\x1d\xee\x60\x18\x93\xdc\xed\x81\x30\x2b\x8b\x52\xbd\x56\x56\x90\xda\x9d\xa1\x02\xd7\x6e\xfe\x9f\x0b\x34\x57\xe5\x20\x19\x2a\x29\xd5\xd0\xb3\xf5\x52\x97\x8f\x15\xee\xf0\xf6\x8c\x28\x00\x2c\x28\xef\xda\xaa\x3e\xdd\xd4\xf0\x3e\xd8\xdf\x65\x14\x41\x4c\x74\xa7\x46\xd5\x05\xc6\x91\xb1\x3f\x06\x1c\xc9\x25\x45\xd9\x40\xed\xad\xfe\xc6\xbe\xc8\xbf\x42\x4a\xc8\x38\x21\xdb\xcb\x47\x78\x77\x70\x12\x2f\x44\x3b\xbf\xd4\xca\x34\xa0\x74\x6c\xb7\xfe\xf2\xb0\x38\x3c\x2c\xfe\x38\x2c\x17\x5b\x67\xa1\xa6\x64\x1a\xc7\x38\xbb\x30\x8a\x58\x2f\x37\x08\x85\x77\x07\xb3\x00\x62\x42\xc3\x96\xed\xe6\xd2\x5a\xd7\xdb\x4f\xfd\x69\xdc\x5e\x24\xb3\x50\x0b\x32\xfa\x5c\x6e\x37\x87\xdb\xcd\xfd\xfd\x62\xbb\x3b\x3c\xad\xb6\x87\x9b\xc7\xfd\x9f\x87\x87\xc5\xfa\x71\xb7\xb8\x5f\xf9\xaf\x49\xb8\xb5\x2c\xbe\x59\xde\x0e\xd5\xbe\x94\xcc\x94\xc4\xea\x62\xa1\xaa\x9b\xaa\x6d\xab\xd3\xba\x6c\xe1\x05\xea\x61\x36\x2d\xf3\x2c\x17\x63\x53\xb1\x59\x6c\x85\xcc\x59\x6c\x5d\x96\xba\x25\x77\xcc\x68\x0b\x67\xc8\x25\xd7\x44\x13\xd9\x85\xd3\xb6\xb2\x6b\x01\xeb\x93\x31\x2e\x14\xc7\x29\x5d\x8b\x52\x57\x27\xea\x8e\xb8\xfb\x14\x90\x92\x86\x36\x66\x52\xab\xa6\x1b\xe0\x7f\x25\xf1\x61\x3f\x2a\x13\x82\xaa\xee\x37\xae\xa3\x2d\x65\x1a\x19\x1b\x38\x7c\xa9\xab\x0b\xe6\x16\x93\x74\x52\x4a\x41\x64\x58\x44\xfc\xbc\x78\x98\xa9\xbb\x84\x4e\x43\xac\xa1\x49\xdb\x7f\xb9\x81\x12\x90\xe3\x51\x7f\x0c\xc5\xd8\x94\xd4\x8c\x54\x06\xd1\xbf\xa6\x3a\xcf\x18\x88\xd0\x39\xdc\xe1\xd9\x48\x82\xdb\x7f\x5c\x10\x93\xa0\x27\xc5\xdd\x7c\x3c\x4e\xfb\xac\x52\x43\x82\xd1\x05\xa9\x12\x1d\x94\x8f\xf5\x87\x2f\x00\x22\x91\x31\xa7\x13\x83\x07\xfe\x15\xe6\xd9\xbf\x47\x2f\x09\x12\x72\xe5\xc6\x96\x94\x78\x17\x57\x40\x4b\x7b\x9e\x51\x19\x90\xfd\xcc\x8f\xea\x0d\x7a\xd5\xd4\x41\xf0\xa9\x02\xc6\x51\x6b\x72\x0b\xdd\xbd\xf6\x72\x5d\x78\x24\x4f\x7a\x6d\x2b\x0b\x6d\xed\x53\x41\x15\x06\x0c\xfb\xc6\x35\xa0\xbc\x82\xfb\x6b\x68\x30\x44\x7a\x15\x0d\x42\x88\xc9\x5f\x6f\x8a\x5e\x75\x27\xc7\x0c\x8d\x02\x4e\xe2\xe7\x6f\xe3\x39\xa6\x62\x2e\x53\xaa\x30\x50\xc5\xda\xaa\x05\xf9\x80\xfb\xd7\x6a\xce\xf3\xc3\x4c\xa5\xa1\x40\x14\xd1\xb1\xaa\xde\x2e\xe7\xbb\x02\x21\xc3\xdb\x01\xf6\x72\x7a\x7e\xa2\xb1\x74\x7e\xbf\x59\xfe\xfe\xfc\x74\x88\x1f\x0e\xeb\xe5\x06\x6d\x4a\x76\xfb\xc5\x83\xe3\xc8\xa9\x34\x0d\xd1\xa7\xf1\x51\xcc\x71\xcf\xdc\x49\x9a\x40\x94\xdd\xba\xfb\x48\xb5\x8a\xe6\xb1\x5a\x8a\xa3\xe7\x91\xab\x2c\x24\x0f\x68\xea\x0d\x1f\xbe\xaf\x1f\x0f\x0f\xcf\xf7\xfb\xf5\xd3\x3d\x3a\xc7\xf8\xd3\x22\x89\x72\x14\xa2\xe9\x96\xd9\xd5\x7f\xac\x18\x85\x2d\x83\x4d\xaa\x61\x2a\x4b\xe2\x01\x1c\x0a\xbb\x30\xc5\x75\xf0\xe6\x4e\xd6\xda\xf4\xc5\x10\xdc\xae\x9f\x06\x93\x78\xde\x96\xff\x93\x87\x9d\x47\x31\xf2\x51\x17\xcf\xb7\xeb\xfd\xea\xf6\xb0\x78\xbc\x3d\x6c\x57\xff\x5c\x2d\xf7\x1e\x7b\xa2\x98\x24\xf4\xa8\x8b\x29\xff\x67\x3b\xde\x2c\x15\x8f\x12\x7c\x24\xf4\xbc\x9e\x4b\xa7\x05\x7c\x5d\x37\x9d\x7c\x2e\x8f\x71\xf8\xac\xb6\xcb\xdd\x59\x9c\x4e\xd7\x02\x26\x73\x1b\x90\xe2\x2c\xc7\xe6\xe8\x04\xe6\xa5\x44\x18\xa1\x3a\xe5\xbb\x28\x06\x0e\xd1\x5d\xa2\x41\x79\x28\xea\x2c\xe1\xdb\xc7\x41\xef\x0e\x4b\xce\xf2\xa1\x81\xd2\xfe\xbd\x5f\xd6\x95\x0a\xa2\x81\x33\xe9\xda\xd1\x5b\xee\x00\x9a\x5e\x49\xda\x9d\xcb\x0c\xb7\xbb\xfa\xad\x38\x9f\x3d\x87\xb4\x9b\x28\x59\xef\x87\xbb\xb0\x51\x41\x97\x70\x23\xba\x45\x1c\xd1\x7c\x12\x05\x1f\x87\x65\xf2\x31\xbf\xd4\x4f\x3a\x1d\x81\x60\xbe\xfd\xab\x2f\xaa\xbd\x96\x32\x50\x90\x84\xa4\xd4\xf9\x71\x92\xd5\x71\xb2\x24\x2b\xc8\x08\x19\x40\x37\xf4\x7b\x51\xbe\xe8\xea\x34\x5f\xc9\x1c\xd4\x95\x14\x00\x60\xc1\xf7\xe8\x5c\x6e\x0e\x3f\xc2\xaf\xa2\x79\x3d\xd8\x73\xdd\xef\x35\xb1\xc0\xce\xc5\x8b\x40\xfb\xb6\xfb\xcd\xb3\x1f\x4b\x26\x17\x8e\x72\x31\xbe\x27\x1d\xa6\x3c\xb2\xe9\x98\xb7\x19\x29\x51\x1f\x72\x5e\x2e\x4c\xe9\x50\x64\xee\x13\x2f\x17\x68\xa6\x17\x8c\x03\x91\x59\x4d\xb6\x81\xc0\x9d\x0d\xf7\xa6\xbb\x94\x8e\x63\xc2\x66\x49\x74\x98\x1a\xed\x3c\x3a\x66\xa9\xb1\xf1\x89\x31\x87\xd8\xff\x99\x27\x4c\x7a\xfc\x44\xb7\x38\x8b\x4b\x7d\xc5\xe6\xd5\x31\x4f\x29\x18\x2b\x8e\x97\x4f\xbc\x7f\x94\x4e\x82\x28\x20\xaa\x4e\x43\xd4\xb2\x2d\x60\x73\x6b\x7c\xa9\x24\x13\x18\x89\xdf\x5c\x3e\x08\x75\xf8\xdc\xc0\x08\x8d\x31\xb9\x6a\x96\x46\x43\xa2\x44\xf1\xdf\xbf\x5d\x52\xf6\x17\x48\x11\xbc\x51\xc2\xfb\x16\x83\x89\xd1\x6e\xa9\xb3\x54\x05\xde\x17\x0f\xc5\xba\x8b\x72\x90\x40\xeb\x8c\x19\x1a\x85\x2d\xf6\x25\x26\x37\x27\x14\x06\xa2\x67\x0b\x59\x46\x79\x5f\xaf\xf1\xa9\x74\x1e\x02\x75\x88\xeb\xd3\x47\x97\x07\x89\xba\x28\xa1\x59\x5e\xef\xfa\x3a\x4f\xe3\xcc\x4b\xe7\x57\xeb\xab\xe3\x8c\x13\x87\xdb\xe3\x59\x1f\x44\xf9\xd1\x0d\xdc\xcf\xf9\x46\x9f\x68\xbd\x2b\xcd\x84\x0e\x94\xb3\xc9\x2b\xaf\x83\x2f\xcd\x14\x51\x5b\x6f\x41\x16\xad\x47\xd4\x7d\x21\x15\xd1\xc9\xfb\x64\x10\x21\x65\x78\x51\x9e\x46\x49\xa5\x66\x20\x74\xee\x8c\x55\x96\xa2\x85\x97\xaa\x2e\x20\x9a\xdf\xb5\x34\x8f\x39\x77\xcc\x42\xdb\xea\x1f\xb8\xc0\xbb\x93\x52\x91\x06\x43\x80\xe5\xbe\xc2\x58\x1a\x21\x55\x33\xbf\xdf\x7d\x2c\x13\x88\xb2\x52\x45\x5f\xf0\x1c\x2d\xc7\x9a\x0b\x8a\x86\xce\xe8\xd4\xfd\xfb\x9f\xcb\xc9\x8f\xe4\x3a\xc0\x1a\xf3\xc3\xfd\x7a\xf3\xec\xee\x46\x24\xd2\x39\x78\x13\xe3\x9e\x30\xab\xa3\x0b\x8b\x8c\x67\xde\x30\xbf\xb9\x32\xfc\x1c\x3f\x76\x01\x74\x9f\x2f\xd0\xee\x41\xbd\x62\xc1\x21\x9e\xbc\x1a\x19\xa4\xd8\x8e\x79\xac\xde\x2e\xe4\x55\x47\x6c\x8c\xbf\xd1\x66\x77\x57\x88\x29\x9d\x2f\xe1\x7d\x0c\xe1\xd3\x52\x1a\x5a\x23\xa8\xd1\xee\x7c\xa4\x87\xe5\x7d\xad\xd2\x18\xd1\x46\x08\xfb\xbf\x81\xf6\x5b\xf8\x6b\xb4\xbc\xd6\x21\xc7\xe2\x08\xc1\x8d\x86\xfe\x1e\x57\x2f\xcc\x7d\x22\xe1\xa8\xed\xbf\xb3\x77\xf0\xc9\x88\xd1\x9c\xdc\x52\x6c\xdf\x76\x55\xfe\x6f\x51\xa2\x20\xd3\xb0\xc1\xab\x4d\x37\x7f\x31\x27\xda\x5c\x5a\x55\x9d\x60\xd7\xff\x16\xa3\x0c\xce\xde\x1a\xad\x92\xb0\xf2\x7a\x57\xd5\x0b\xa7\xf5\xae\x20\x88\x92\xc4\xa3\x4a\x0c\x5c\xf9\x5a\xf5\xfb\x0a\x04\x82\x4a\x28\x45\x63\x13\xca\x1d\x2a\x9b\xba\xa3\x8a\x2c\x7d\xc9\xeb\x7f\x00\x8d\x1c\xff\x74\x08\x14\xcd\x4c\x84\xe4\x7d\x83\xba\xe9\xb7\x66\x08\x03\xd2\xfd\x76\x12\x62\xf7\x45\xdb\xfa\x65\x0a\x42\x4d\x5e\x0a\xd6\x9e\x9d\xfa\xc8\xa8\x3d\xe8\xce\x88\x42\xc0\x6a\x96\x87\xfb\x3b\xa4\x99\xb8\x96\x6e\xfa\x5b\x81\x17\x44\x51\x1e\x08\x2b\xdb\xd8\x2d\x7c\x98\x13\xdd\xd9\xfe\xa6\xf6\xdf\x9b\xe7\x21\x78\x2a\xe8\xf3\xfe\x8f\xcd\xd8\xb6\x62\xdc\xf6\x72\xff\xeb\x2d\x02\xe6\x7b\xaf\x10\x71\x10\x79\xbf\xf2\xae\x86\x56\x9c\x0a\x22\xc3\x20\x76\xc8\x09\x3b\xca\x1f\x8a\x06\xd5\x6c\x46\xa3\x08\xe2\x34\x93\x36\xfb\xfb\x5a\xe9\x63\x8f\x19\x87\x98\x07\x38\x75\x5f\x85\x7f\x52\xe5\x56\xbc\xf9\xef\x48\x18\x60\xc6\xff\x05\xc0\xbb\xf1\xbb\x43\x52\xa7\xc4\x3a\x44\xae\xd2\x5d\xef\xca\xa2\x20\xd7\x24\x65\xd6\xbc\x17\xe7\x09\x34\x0f\x72\x20\x41\x7e\x79\xf9\x04\xdf\x09\x2c\xe4\x88\x33\xc5\x1a\xd6\x6d\x71\x5d\x30\xb4\xe7\xf1\x90\x7a\xbc\x6d\x77\xc3\x83\x3c\x0c\x78\x2c\x50\xc3\x84\x10\xdf\x13\x60\xe6\xe4\xcb\x64\x16\x67\x04\xae\x44\xca\xc4\x1c\x29\x0a\x24\x8f\x42\x9b\xbd\x59\xa5\xf5\xb1\xac\xd7\x30\xa1\x04\xa9\x04\xe6\x6c\x77\x55\x75\x45\x33\x1c\x5f\x56\x85\x49\x46\xd4\xa3\xe3\x1b\xfe\xd6\x1d\x09\x9f\x7f\xba\xc8\x83\x52\x79\x38\x32\x52\x47\x17\xfb\x89\xbc\x18\xe8\x48\x4a\xeb\x63\x88\x0d\x77\x54\x90\xbf\x1a\x14\x9a\xcb\xcc\x96\xdf\x6e\xa0\x69\x47\x8a\xbd\xf3\x51\x06\x68\x91\x22\xbe\x68\xb9\x78\x7a\x5a\xdd\x8e\x54\x38\x15\x68\x13\xeb\xc8\xe7\xed\x45\x89\x3c\xcb\xe1\x3e\x01\x10\x87\x60\x29\xa6\x8f\xd2\x06\xb3\x8d\x47\xb1\x0d\xa7\xe6\x60\xcd\x41\x71\x60\xfa\x50\x7b\x84\x21\x26\xf5\x93\x9b\x34\x99\xc6\xdf\x85\xd6\x5a\x05\x94\xe8\x64\xf5\x3c\xe9\x74\x9a\x20\x8d\x51\xe7\x80\xd8\xdd\x43\x83\x8c\xdf\xdc\x19\x99\x90\x56\xf8\x6d\x59\x9d\xce\x55\x33\x5d\xce\xfe\xf5\xef\x7f\x4c\xae\x99\x67\xc4\x12\xb4\x3b\xe0\x95\x17\x81\x3d\x2f\x8c\xe2\xc0\x0e\xa7\xc3\xa9\x98\x46\x41\x26\x4c\xd2\x44\xf4\xfd\x8e\x8d\x19\x3d\x45\x13\x0a\x89\xa1\xde\xa5\xb9\xd4\xe7\x61\x5e\x63\x42\x60\xd8\x25\xf8\xe7\xf3\xa3\x2b\x97\x99\x28\x20\x9b\x3e\x7c\x25\xbf\x0f\x0c\x6c\x66\x12\x36\x13\x25\xa4\xd0\x4c\xd9\xed\x48\x0d\x6f\x7e\x9f\x35\x51\x2e\x9c\xa9\x09\x56\xd9\xa2\xc9\x6f\x89\x24\xcb\xa5\x0d\x66\xba\x05\x86\x4c\xb9\xff\x5e\x1d\xcb\x24\x61\x82\xb1\x07\x6e\x76\x4e\xa7\xe5\x2f\x3b\xcd\x26\x11\x3c\x71\x8c\x7b\x28\x75\x55\x2f\xce\xe7\x63\x31\x43\x6e\x32\x89\xa4\xb5\x7d\xbb\xd8\xaf\x1c\x9f\xde\x24\x26\x09\xed\xbc\xd8\x5d\xa4\xed\x52\x8a\xa9\xbe\xa1\x3d\x39\x8d\x05\xb3\x10\xdf\xbb\xe2\x38\xaa\x3e\x99\x34\x09\x70\x4f\xc0\xf5\x19\xcb\xc7\x93\x71\x90\xaa\x54\x99\x81\xce\xe5\xb2\x2a\x9b\xcb\x69\x12\x39\xb9\x59\x6d\xb2\x24\x46\x87\x40\xb2\x2d\xdc\x56\xc7\x63\xb7\x34\x92\x29\xe1\xe4\xa9\x67\x79\x60\xec\x44\x43\xae\xdf\xf3\xf9\x0e\xae\xce\xe1\x80\xc3\x88\x6a\x8f\x93\xda\xbc\xc9\x24\x21\x06\x97\xcb\x9e\x6b\x32\x9f\x76\x7e\x32\x3e\x7e\x69\x3b\xae\x4c\x2e\x09\xbf\x5b\x83\xaa\x7e\xb8\x0a\xed\xfc\x10\xcb\x75\xa0\x93\x6b\x2f\x9a\x89\x22\xb6\x32\xb9\x01\x64\x4b\xff\xf3\xd2\xb4\xdd\xea\xe3\x77\x2a\xc3\x22\x81\x54\xfc\xef\xa2\x15\xf0\x73\x18\xbf\x1b\x26\x95\x89\x07\x53\x76\xf3\x6d\xbd\xbb\xa9\xaa\xb7\xb1\x92\xb6\x32\x0c\x08\x3e\xb3\xbc\x5f\x0f\xe5\xac\x0c\x03\x83\x2c\xa7\x8b\xaf\xa5\x7c\xab\x7c\x83\xc1\x70\x43\xcd\x68\x14\xb5\x6b\x86\x9d\x11\x23\x18\xe4\x36\x27\x46\x8c\xe7\x44\x3d\x73\x34\x4c\x85\xc8\x23\xe3\x75\xa0\x5a\x71\xc4\xc7\xf5\x04\xf5\xd7\xea\x32\xc1\x66\x1b\xa9\x25\x07\x87\xd5\xeb\x82\x86\x5b\x71\x5e\xfa\xe2\xaa\x51\x41\x80\x0d\x41\x57\x43\x79\x58\xdf\x4f\xd2\x3d\xa3\x42\xc0\x29\x6d\x83\x8e\xef\x50\xf4\xb9\x9e\x51\x2c\x0c\xe5\x60\xc8\x3e\x89\xba\x2d\x54\x71\x16\xfd\x2f\x53\x2c\x8f\x86\xea\xad\xdd\xb4\x1f\x87\xb8\xb3\xeb\xb6\x51\x3c\xc5\xf7\xf7\xbc\xbb\xc5\xc5\xea\x6f\xcc\x74\x25\x35\xd6\xee\x94\x28\x1f\xc4\x1b\xd4\x7b\xa8\x51\x53\x60\x82\xf8\x30\x5a\x09\x07\x06\x7f\x28\x1c\x2d\x79\xae\x2e\x6d\x20\xc9\xb0\x34\xb4\x6c\xcd\x68\x9c\x80\x8e\x91\xcf\xbd\x7c\xb8\x1d\xfd\xdd\xc4\x19\x6e\xc8\x8b\x42\x16\xad\x14\xe5\xdb\xf8\x68\x12\x21\x16\xa3\x20\xab\xad\x85\x16\xe7\x76\xd2\x36\xd5\x41\xc0\x4c\x68\x41\x09\x0f\x85\x93\x60\xd4\x41\x00\xd0\xab\xd8\x0d\xae\xaa\x83\x28\x97\x90\x7a\xeb\x97\xea\x7d\x46\x4a\x5b\x07\x71\x12\xc5\x89\xd7\x84\xd8\x92\x00\xbc\xbb\x42\xcc\x38\x4e\x88\x93\x95\x7e\x1a\x5d\x3e\x96\x01\xb7\x3d\x63\x4b\x85\x22\x77\x7f\xc4\xaf\x0e\xd7\x4f\x1d\x24\xa1\xb0\x02\x28\x5d\x80\xb1\xac\xaa\x63\x6f\x04\xab\x83\xc4\xaa\xfd\x35\xd0\x7e\xaf\x6a\x3d\xf9\xa8\x22\x5d\xe4\x12\xde\x1d\x37\x62\xd5\xbe\x3e\xef\x6e\x51\xbb\xc3\x3f\x85\x54\x51\xe4\x45\x1b\xf4\xdd\xe6\x79\xbb\xff\x4a\xca\x0f\x87\xad\x6f\xb7\xeb\x20\xd5\x21\x58\x9a\xd3\xf9\x49\x78\x0a\x86\x0e\xb2\x28\x8f\xed\xfa\xdc\x85\x0e\x8b\x9b\xf5\xa4\x72\x6f\xc7\x88\x0e\xb2\x24\x06\xb0\xc1\x24\x41\x08\x08\x69\xeb\x0e\x67\x46\x67\xbd\xbe\xff\x9a\x0a\x35\x23\xeb\x09\x77\x26\x27\x55\x98\xcd\x07\x4e\x90\x1a\x9e\x40\xd4\x47\x7f\x1d\x91\x5b\x65\x4d\x5c\x13\x06\x74\x62\x1d\x38\x38\x18\xc6\x04\xd3\xc9\x42\x6d\xa7\x5f\xff\xef\xf8\x46\x58\x92\x1a\x02\x5f\x57\xc7\xa8\x69\xeb\xbe\xdd\xa0\x03\x1e\xc4\xb8\xfa\x3f\x89\x8f\xbb\xaa\xbe\x3b\x8a\x97\xf1\xeb\xe1\x51\x86\x42\x1b\xb5\x68\xe1\xd0\x56\x7e\x05\xd0\x81\x88\xc3\x84\x8a\xb7\x5d\xc6\x3c\x42\x9f\xe8\x40\xa5\x0c\xeb\x58\x48\x54\x99\xc0\x44\xdc\x29\x2c\xc7\x71\xfd\xc7\xe2\xc9\x7d\x0a\xf2\x2c\xd4\x23\x86\x3a\x3a\x99\xfd\x1c\xb3\xef\x74\x00\x8c\xa3\x52\xe5\xed\x0a\x79\x01\xfe\xcf\x40\xb5\xaf\xc3\x59\x7c\xdc\x7c\xac\x6a\x15\x05\x93\x57\x62\xa2\x4c\x65\x53\x32\xc8\x55\xa2\x3b\xbe\x4f\x93\x0a\x6c\x0e\xdf\xee\x97\x4b\xf7\x4d\x46\xab\xc8\x11\x7a\x44\x51\xb6\x45\xf9\xb2\xa8\xdb\xa2\x69\xd7\x7a\xfa\x8d\x46\x63\x78\xf9\x78\x79\xeb\x41\x72\x74\x2c\x0c\x62\x89\x09\xf7\xd6\xa9\xfa\x8c\x3f\x1b\x86\x79\xec\xbc\x04\x28\xc8\xef\x36\xa4\xb9\xee\xb7\x0e\x43\xc5\xb0\x30\xdf\x16\x27\xd8\x17\xc7\xe3\x63\xf7\xd0\xc8\xd0\xd8\x9e\x11\x81\x71\xe2\x23\x0d\xe6\xaf\x13\x2c\x90\x0e\xe3\x48\x60\xff\x15\xa1\xb6\x3d\xb4\x66\x7c\x4f\x71\xac\x98\x83\xab\x14\x7a\x7a\x30\xe5\x11\x22\x2b\xba\x3c\x90\xf6\xcd\x9b\x0f\x54\x0a\xb0\x27\xa4\x11\x95\x1f\xb1\x12\x0e\xbd\x29\xf5\xdc\xca\x15\xa6\x89\xb2\x4a\xd7\x54\xa3\x74\xaa\x51\x3d\x1c\x52\x87\xa9\x22\x87\xc6\x87\xc5\xe3\xe2\xef\xa3\x70\xe7\xf6\x1d\x1d\xa6\x46\xe1\x4e\xec\xc6\xc3\x1d\x0c\xeb\x71\x3a\xcc\x40\x49\xbb\xfb\x3e\x5e\x4e\x93\x9f\x9e\xab\x04\x53\xad\xf2\x72\xda\x98\x61\xc8\xa0\x43\xd6\x0d\x97\x51\xa3\xb9\x3b\x4a\x90\x0c\xb2\xbf\xf9\x15\x90\x4f\x87\x2c\x4c\x34\x25\x3e\x47\x63\x35\x4b\xfa\xec\x5f\x87\x2c\x0f\x10\x82\x7a\x40\xa6\xa9\x2d\x85\xac\x97\x9b\xd0\x9f\xa0\xc8\xec\x72\x2f\xde\x60\xd5\x23\x0e\xa7\xdf\xa2\x53\x2c\x0f\x89\xa2\xbe\xad\xab\xf3\xe4\x5d\xf0\xdc\x18\x92\x69\x56\xaf\x5d\x60\xb3\x2e\x4d\x75\x57\xd5\xdd\x7f\x4e\xb6\xb1\x50\x24\xe0\xca\x48\x5f\x3f\xce\x5d\xf2\x43\x12\xa5\x56\xdc\x6f\x66\xf0\x8a\x54\xe1\xc0\xeb\x16\xd1\xa2\x7c\xd9\xb5\xdd\x62\xf3\xf2\xf1\xb7\x5f\xe3\xf8\x87\x08\x46\x95\xd8\xd5\x97\x2f\xbb\xc3\x7e\x73\xf8\xba\xd8\x2f\xbf\x1e\xc2\xdd\xe3\xe2\x77\xb7\x4d\x84\x92\xc7\x98\x9a\xab\xd7\x6e\xf1\x1a\x48\xbb\x0d\x1b\xa0\xa3\xff\xfc\xf4\xc0\xdf\xff\x4f\x37\xcf\x14\x64\x4e\x24\xd7\x0e\x80\x69\x50\xae\x43\xad\x52\xc7\xb0\xc5\xc6\x38\x3d\xaf\xc5\xb1\x06\xa1\x3f\xd6\x04\xcb\x1a\x3f\x44\x08\xe2\x34\x75\x58\x34\x32\x60\xf0\xf3\xca\x9f\x92\x7b\xf8\x1e\xc5\x01\xfd\xcc\x84\x84\x25\x03\x79\x9f\x5d\x2b\x70\xaf\xbf\x16\x42\xd7\xa1\xc9\x62\xad\x7c\x9c\x32\x60\x64\x4c\x5e\x84\xb1\xc2\xa9\xc7\xea\x65\x18\xf2\xea\xd0\x70\x91\xf6\x2e\xd2\x76\xb6\x8d\x34\x0c\x74\x68\x14\x75\xa4\x6e\x56\xfb\x47\x68\xdf\xab\xfa\x6d\x68\xd7\xe8\x4e\xd2\x0a\x83\x02\xb2\xc6\x20\x4c\x6e\x14\xfc\x36\x13\x3b\xeb\x28\x48\x73\x0c\xdc\x8d\x28\x8e\x83\x1a\x91\x8e\x02\x19\xe1\x2f\x6f\x44\xd5\x88\xca\x02\xcb\x74\x14\x29\x85\x10\xd1\x2f\xe2\x44\x8e\x98\x73\x29\x2a\x1b\x17\xf5\xdc\x47\x4d\xe2\x75\x85\x51\xe0\xfa\x47\xd1\x14\x55\xe9\x85\x0a\xc7\x65\x9a\xee\xfc\x34\xce\x3c\xc7\x41\x5f\x54\x7b\xf3\xb1\x85\x17\xab\xb6\xf3\x2b\x80\xcf\x4c\xf2\xae\xa3\x38\x00\xa9\xbd\x44\x10\x76\xf8\xd1\x8c\xc1\xf4\xaf\x3b\x8a\x63\x32\xb7\xaa\xac\x40\xda\xe1\x45\x34\x47\xb4\x80\xb0\x27\xa4\x79\x64\x11\x0c\x5d\x44\x67\x15\x33\xc6\x03\x21\x4a\x4d\x8a\xb4\x03\xc2\xbd\xaf\x7e\x42\xad\x8a\x66\xbe\x5f\xa6\xa3\x0c\x42\x6c\x82\xee\x56\xcb\xe7\xed\x7a\xff\xe7\x61\xb5\xff\xba\xda\x1e\x96\x7e\xf7\x8f\xf2\x30\x41\x76\x73\x09\xef\xdd\x72\x6f\xe9\x1e\x53\xbe\xc6\x4c\x25\x59\x47\x79\x0e\x99\xe5\x26\x3a\x41\xcd\x59\x6e\x8b\x7f\xe4\xc8\x1b\xf5\xec\xde\xad\x28\x1a\x98\x49\x03\x74\x94\x9b\x50\x13\xe8\xfc\x7c\xb6\xa9\xe0\x50\xf9\x45\x47\x5c\xe5\x18\xb4\xbb\x08\xfa\xd9\x47\x78\x91\x08\x14\xe6\x3f\x0e\x49\x88\x8c\xec\x03\xb4\xaf\x7f\xbb\x00\x3d\xaa\x1a\xba\xab\x86\x21\xa6\x3a\x04\x23\x25\x3f\x86\x3e\x9e\x8b\x44\x46\x66\x00\x2e\xaf\xbb\x29\x8e\xc7\xa2\x2a\x1b\xa2\x8d\xb8\x93\x72\x41\xf5\xc6\xba\x12\x5a\x09\x14\x42\x6d\x61\x34\x2b\x84\x24\xcc\x18\x5a\x96\x39\xa6\x35\x0a\x29\x19\x31\x0d\xe5\x22\x99\x0a\xa4\xee\xbd\x43\xb1\xaf\x7a\x5e\xa5\xfb\x3a\xa5\x35\x6a\xae\xe1\x2c\x75\xcc\x9f\xfe\x20\xb5\xa8\x85\x0b\x06\xd6\xaa\x42\xa5\x73\x7b\x5c\xa7\xa4\x0e\x46\x61\xa6\x5d\x30\xfd\x41\x46\x26\x4f\xaf\xe4\xcd\xef\x1a\xf8\x3a\x02\x15\x23\x9f\xad\xbe\x94\x84\x85\x5d\x97\xe6\x38\xa8\x91\xe9\xc8\x04\x79\x18\xf4\x06\x60\x37\x1f\xd3\xd0\x2d\x32\xa9\x21\xf1\xb7\x23\x88\xfa\xae\xaa\x16\x3d\x51\x56\x47\x26\x8f\xed\x1a\xf6\x06\xe5\x67\x9d\xae\xc9\x28\x35\xb9\xc2\xb1\xb2\x84\xb2\x71\xaa\x70\x3a\x0e\xb2\x30\xce\x07\x2d\xdf\x06\xbe\x1c\x2b\xe9\x7d\x10\x74\x1c\x06\x84\x86\xc0\x06\xfe\x4e\xbd\x82\xbe\xcc\x28\x2f\x8e\x83\x99\x38\x8c\x05\x0e\xdc\x63\xd1\xb4\x1b\x73\x2d\x0f\xae\xe3\xd0\xc4\xf8\x60\x77\xc5\xcf\xd6\x81\x60\xb7\x97\x23\x4c\x76\xe7\x38\xca\x52\x61\xcb\x60\x64\x2e\x0e\x7b\x51\xbf\x4c\x4a\xe3\x3a\x8e\xf2\x98\x33\x67\x65\xa1\x80\xa8\x30\x7d\x05\xdb\x9d\xc5\x63\x0d\x03\x15\x39\xfb\xe7\x38\xcb\x83\x1e\xf4\x34\x44\xa0\xfb\xa7\x90\x44\x84\x3d\xbf\x87\xa6\xf9\x04\xb6\xa8\xe3\x54\xa5\x98\x72\xad\x2e\x75\xd5\xd6\x4e\x53\x5c\xc7\x59\x4a\xfc\x12\x57\x07\xc3\x66\xe3\x3f\x9f\xfe\x5c\xfe\x55\x8c\xe1\x3e\x9f\x13\x6b\xa2\xdb\x55\xd7\xcb\xcd\xe4\xa7\xe7\x5a\x21\x3f\xfd\x0c\x7d\x7a\x14\x33\x46\x02\x3b\x4d\x2b\x5e\x20\xf1\x7f\x15\x82\xa1\xee\xde\x6b\x55\x35\x30\x24\xc1\xeb\x98\x27\x02\xcb\x95\xab\xfd\xd7\x30\xf8\xdd\xff\x35\x15\x98\x49\x79\x0f\xf2\x45\x39\x66\xab\xfc\x72\xcc\xc5\x22\xd4\xf8\xc0\x1f\xc4\xcf\x05\x45\x76\x7f\x0c\x14\x30\x74\x2c\xe2\x3c\x13\x03\xc7\xde\x2b\xe1\x3d\x1d\x8b\x3c\x45\xbd\x99\x63\x25\x74\x17\xf0\x75\x71\xc1\xa0\xdc\xf3\x0d\x75\x7d\xae\x14\x56\xfb\x02\xa8\x8e\x65\x10\xa3\xb3\xd6\xd2\xa2\x87\x5d\x45\x4e\xc7\x2a\x0e\x42\x5b\xa2\xb5\x8e\x58\x18\xda\x8e\xf6\xc7\x58\x41\x1c\x64\xbe\xa7\x46\xa2\xb1\x73\x8d\x14\x1d\x6b\x60\xf8\xd0\xcf\xe2\x63\x5f\x0d\x08\xcb\xf6\x30\x04\x21\xc6\x48\x37\x97\x6e\x3b\xb3\xb1\x34\xe8\x59\xe3\x2d\x1d\x43\x42\x64\x4e\xa2\xec\x86\xc1\x03\x34\x4d\x2f\xa1\xa4\x63\x93\x53\x7f\xde\xb2\xca\x1e\xf6\xcf\x93\x19\x66\x20\x72\xe9\x2c\x8a\x0c\x13\xae\x13\x53\xb9\xf9\x26\x94\x4e\x82\x30\xce\x8d\x9d\x1f\x08\x89\xda\x81\xd3\x41\xd0\x49\x10\x11\x20\xae\x9b\xd3\x07\x53\x1c\xfd\xad\x24\x81\xd5\x9c\x23\xe9\x35\x74\x9d\x1f\x3d\x98\x24\x10\x89\x55\x0c\x28\x75\xf8\x50\x1c\x27\x87\x43\xa1\xc5\x80\x59\xe1\xfa\x15\x23\xcb\x0b\x9d\x44\x61\x8e\x1e\x25\x64\x8d\x3a\xa1\x71\xe8\x24\x8a\x95\x43\x08\x0c\xb8\xf5\x9b\x1a\xa6\x9a\xe1\xee\xfc\x8c\x20\xd9\x3f\x0a\xd5\x56\x75\x01\x97\xd3\x30\x3b\x4e\x62\x0d\x58\x91\xb5\x08\x3b\x52\x52\xdf\x3b\xd7\xd6\x19\x56\xce\xf4\x05\x26\x31\x48\xc3\xbd\x59\xc5\x59\x94\x6f\x68\x4a\xa1\xfd\x37\x00\xe0\x0d\x17\x8d\xe7\x31\x3e\xd5\xd5\x4b\xed\x5c\x28\x74\x92\xc6\x79\x46\xd8\x91\xe3\xf1\x7b\x51\x4e\xa2\xf4\x24\x85\x14\xf7\xd1\xe5\xd7\xdd\xe8\xd6\x53\xa3\xd0\xb1\xe3\xee\xe7\xcf\xb7\x68\x74\x24\x13\x12\xf1\x40\x9e\xa0\x6d\x17\xde\x2e\x67\x6c\xfb\x37\x9d\xe9\x1c\x77\x71\x71\x3e\xd7\xd5\x0f\xb8\xf9\x58\x97\x1a\x7e\x4e\xbe\x3d\x4f\x64\x60\x81\xf1\x45\xd9\x6b\xe9\x0c\xd1\xc3\x3a\xc9\x15\xb9\xab\xa9\xaa\xda\x5a\xd4\xd3\x8f\x02\xde\xa7\x93\x3c\xc9\x4d\x6c\xcd\x1c\x1a\x75\x81\xfb\xaa\x69\x7f\xff\xd0\x1f\xb3\x4c\x7f\x9d\xb0\x48\x73\xdb\x7d\xbc\xbf\xff\x76\xe8\xde\xc4\x21\x72\xdf\xc8\xd2\x9c\xd0\x23\xe2\xa7\x27\xa7\xe8\x84\xa7\xb1\x13\xf9\x7c\xac\x4a\x42\x76\x0d\x9d\xbc\xdd\x69\x19\x20\x9d\xe3\x47\xd5\x82\xd3\x92\xea\x29\x09\x93\xf7\xcb\x73\x6e\xdf\x9f\x15\x5a\xfc\x52\x75\xa9\x8f\x50\xaf\xfd\x3b\xe6\x3c\x8d\x9c\x88\xde\x30\x6b\x9a\x5c\x4a\x80\x46\x7d\x74\xa8\x6b\x12\xa5\xb1\x93\xdd\x5d\x46\xc6\x0a\xb7\xfb\x2e\x36\xbd\x48\x5d\x9d\x44\x31\xed\x83\xcc\xee\xc3\x89\xcc\x78\x98\x78\x0d\x71\x5d\x4d\xea\x06\x89\x0a\x12\xac\x48\x2d\xce\xe7\x6a\xd0\x01\x9c\x5c\x45\x25\x2a\x50\x63\x81\x59\x5c\xc2\xdc\xed\xe9\x20\xcd\x6d\x30\x23\x2f\x1f\xe5\x40\xd8\xd6\x9d\x10\x66\x28\xc0\xba\x52\x55\x59\x9d\x3e\xb6\x20\x11\xed\xf9\x8b\x64\x62\x94\x53\x24\x3a\x91\x09\xca\xff\x6f\x1e\x9f\x77\x83\xa0\x3d\xd1\x19\x43\x05\x25\x52\x77\x5b\xad\x9f\xfa\xfc\xcb\x9e\x01\x11\x93\x36\xdd\x7d\x84\x9f\xed\x4d\xa1\x57\x3f\xcf\x45\x0d\x38\x58\x2d\x05\x69\xfc\x4c\x20\x26\x18\xd1\xf3\x6e\xb5\x3d\x2c\x96\xff\xf3\xbc\xde\xad\xf7\xeb\xcd\xa3\xfb\x4e\x93\x02\x8e\xd5\x87\xfd\x68\x6e\x19\x19\x63\x64\x5c\xc2\x7b\x17\x40\x76\xe1\xf1\xe6\x7c\x2d\x3e\x3a\xd3\xb6\x9a\x24\x70\x69\x10\x4a\x74\x9e\xc2\x12\xf1\xb1\xf9\xdc\x59\x73\xf6\x9d\xa7\x41\x4c\x3e\x9e\x04\x87\x00\x87\x11\x4d\xdc\x61\x9d\x20\xe3\x0b\xed\xb2\x3c\xdf\xf5\xe4\x39\x48\x3a\x0d\xa5\x12\x4e\xe4\xe8\xf2\x61\x73\xf5\x91\x43\x9f\x3b\xd1\x04\xd8\x75\x44\xc0\xd5\x81\xd6\xe5\x43\x0b\xb5\x5b\xc0\xd2\x88\x65\xda\x0e\x0c\x82\xd0\x0e\xdf\x6a\x1a\x8b\x18\xc9\xde\x27\xf1\xd6\xdb\x67\xd1\x79\xe3\xef\x89\x05\x29\x26\x3c\x2c\x1e\xbf\x2e\xf6\xfb\xc5\xe3\xd3\x76\xf3\xc7\x9f\x77\xb7\x5b\xf7\x3d\xdd\x66\x99\xf6\xe0\x09\x62\x1d\xb9\x83\x49\x90\x81\x9d\x03\x76\x2b\x58\xb4\xbb\x52\x9c\x9b\xd7\x6a\x12\x45\xa6\x89\x4a\x5d\x1b\x79\x59\xd4\x88\xfd\x2b\xaa\xb2\x0b\xab\x66\xe7\x6d\x9a\x06\x0a\xab\x9a\x7f\x38\x5b\x85\xeb\x2a\x41\x9a\x46\x01\xa6\x1f\xbf\x57\xed\x6a\xef\xff\xc8\x69\xe9\x46\xbb\xbc\xbe\xee\x90\xa6\x4a\x0b\xa2\x13\xb4\xd8\x43\x22\x84\x8f\x45\x53\x4d\x9e\x4a\x16\x44\xb8\xd2\x2d\xea\xff\x1d\x0e\xc4\x34\x0b\x48\xc6\x61\xf5\xff\xa2\xb4\xe7\xa4\xe9\x34\x0b\x73\xac\x11\xee\xf6\xcb\xfe\xc9\x65\x69\xea\x68\x77\x4f\xc5\x4f\x38\x92\x1e\xda\x65\x0a\x6a\x9c\xff\x2f\x7f\x0d\xa9\xd2\xe1\x4d\x2f\xcc\x40\x52\x67\xf2\xc8\x32\x16\x62\x8c\x74\x2a\xca\x76\x0b\x66\x52\x8c\x48\x33\xa6\xb1\x21\xdb\x5c\x64\x37\xde\x7a\x77\x60\xe6\xff\x27\x1c\x91\x12\x75\x9a\x99\xc0\xf1\x7d\x6f\xc1\x88\xcb\xb1\xc5\xa2\xc3\xe4\xd5\xe6\x91\xc0\x18\xff\x66\x73\xe7\x7e\x7b\x9e\xaa\xd8\xc2\xb8\xda\x2f\x70\x9a\x6b\xf4\x79\x2b\x83\xf1\x8f\xc8\x33\x8d\xe3\x7a\xfd\xb4\x58\xfa\xab\xe5\x39\x38\xf5\x0c\xe5\x4a\xea\xcd\xbe\x72\x3c\xd0\x4f\xea\xab\x69\x2e\x12\xcc\x40\x77\xef\xe2\x7c\xd5\x0b\x98\x9e\x9a\x61\xc8\x77\x23\x9a\xe2\x68\xeb\x52\xee\xeb\x59\x12\xe0\x1c\x21\xff\xbc\x05\xee\xdc\x7e\x47\x4f\x59\x46\xc1\xe2\xa6\x3c\x16\x13\xd5\x46\x9d\x32\xc1\x32\x4a\x01\x49\xa8\x98\x4c\x4d\x7e\xad\xa0\x3b\x1f\xef\xa7\x0c\xc8\x77\xe9\x2f\x16\xc1\xd9\xd5\x6f\xfc\x56\x79\xc8\xd0\xb4\x7c\x29\x4a\x51\x7f\x7c\xcb\xef\x84\xef\x1b\xa6\x5c\x9a\xd4\xe9\xc6\x56\xef\x77\x75\x75\x1a\xb8\x15\xeb\x54\x24\x8c\x6b\x4b\xb7\xb9\x76\x40\xd6\xa9\x48\x73\x35\x6c\x1e\x6f\xce\x45\x39\x14\x97\x1f\xdd\x87\xe0\xd2\x62\x1a\xed\xd6\xb7\xa9\x9f\x44\xe3\x78\x70\x28\xd1\x3f\x89\x22\x52\x21\xb3\xd0\x52\xdf\x57\xa7\x73\xfb\x81\x13\x6b\x51\x83\xf8\x7b\xe9\x5e\x2a\xba\x8d\x8d\xe6\xe4\xef\x70\x9d\xda\x0c\xea\x24\xa9\x4c\x04\x74\xef\xf5\xbf\x5f\xff\xc7\x2a\x39\xbb\x87\x20\x19\xb3\x28\x72\x17\x0b\x7f\xd9\xae\x56\x8f\x33\xdc\xf6\xf1\x97\x4b\x91\x23\x9c\xce\x14\x75\xd3\x22\xc9\xf6\xa9\xf2\x0f\x5e\x0a\x9e\xb3\xde\xed\xff\x00\x63\x45\x43\x9d\x4a\x43\x60\x2e\x32\x82\xd1\x1b\x33\x99\xde\xd2\x50\x00\x6a\xab\x0d\xdf\xa0\x69\x47\x45\xe2\x54\x45\x11\x62\x0c\x4e\xcd\xcb\x83\x38\x4f\x56\x3c\x95\x28\x8c\x33\x88\x6c\x45\xef\x7c\xfc\xe8\x75\xa6\xb0\x68\x22\xa1\x5d\x97\xa6\x5a\x37\x56\x8f\xc7\x1d\xe6\x29\xae\x2e\x7b\xf1\xb3\x18\x4d\x01\x2d\x05\x62\x64\x10\xf8\xbf\x3a\xc2\xf9\x55\xf4\xf7\xa4\x35\xf1\xd8\x9a\xd7\xea\xfd\xa1\x79\xb1\xe8\x38\x7b\x10\xa2\x80\xec\xc0\x0e\xeb\xd3\xe9\x48\x2d\x6c\x9b\x92\x55\xb5\x73\xc0\xd4\x29\xc4\x0a\x3b\x64\x28\xa1\xef\xfe\x26\x35\x56\xa8\x3d\xcc\xbc\xcb\xb8\xaa\x8b\xff\x5e\x50\x1a\x65\x88\xda\x57\x9b\xaa\x97\xc3\xd8\x3a\x35\x09\xc7\x95\xd4\x65\xe6\xce\xc9\xf0\x97\x19\x79\x6a\x52\x95\x10\x38\xec\xe3\x0b\x58\x1e\x67\x68\x5f\x4f\x16\x08\x81\x42\xa9\x24\x9b\xee\x2c\x0c\x7e\x79\xc1\x2c\x30\x14\x33\x3f\x2c\xfe\x38\x20\x8a\xcd\xde\x5f\x16\x72\x92\x5e\xc4\x89\x72\xe8\xa2\xc2\xc6\x1f\x12\xdc\x1a\xb7\x1f\x8f\x24\x77\x37\x7f\xed\x50\xc9\xd8\xee\x4e\x78\x4b\xb6\x02\x34\x79\xeb\x59\x24\x63\x72\x9e\xbc\x94\x5d\xf0\xd0\x4f\xf5\x2c\x4e\x78\x44\x6a\xb2\x1f\xf7\x20\x3e\xff\xa2\xd8\x4a\x8e\x61\x24\xb3\x7b\x2d\xce\xd3\x9a\x9a\x3b\x8f\x53\xa5\x77\xd5\xa2\xf7\x87\x3f\x6b\x72\x35\x4e\x4c\x04\xf7\x66\xba\x04\xca\x6a\xc0\xff\x0a\x8e\xa4\xb3\x58\x28\x4c\x19\xe5\xe5\x63\xf9\xda\x03\x25\xb2\x58\x73\xcc\x0f\xfc\x64\xb6\x51\x89\x3d\x9c\x48\x62\xa1\x1f\xac\x38\xd8\x2c\xcc\xc5\x9d\xab\x39\xd1\x27\x2f\xc5\x51\x2f\xab\xb2\x84\x79\x6f\x35\xf7\xef\xaf\x56\xaa\x2c\xcd\x32\x04\xd1\x4b\x81\xf0\x68\xf2\xcd\xa6\x05\x2a\xfd\xc7\xe8\xff\x73\x1f\xe0\x01\x83\x9e\x1e\xf5\x74\xb7\x1b\x85\x84\x59\x2a\x25\x6e\x45\xdf\x0a\x78\x1f\x4e\xd0\x2c\x4f\x73\x14\x58\x22\x8a\xf4\x27\xbf\x2d\xe7\x04\x99\x5b\xec\xbe\xde\xaf\xfe\x3c\x2c\xee\xef\x37\xcb\xc5\x20\x74\xcf\x72\x48\x11\x50\x7f\xbf\xdb\xa3\x5f\x28\xd4\xdf\x57\x6b\x7f\xd0\xc4\xc8\xa1\xee\x22\xdd\xf2\x65\x50\x26\xca\x58\x18\x60\xfe\x73\x14\xcd\x04\x0b\x90\x71\x96\x62\xa1\xba\xdb\xe3\x41\xbb\x8e\xaa\x3f\x2a\x72\x13\x52\x65\xfa\xe5\xb5\x6d\x16\x08\x63\x29\xaa\x72\xec\x35\xab\x33\x91\x2b\x2c\x10\xa2\xf2\xd6\xac\xa6\xc5\x6c\xa8\x9f\xa9\x44\x4a\xef\xfe\xb8\x43\x64\x6a\xb7\xcf\x3e\xa1\x0e\xda\xb0\xde\x9c\x29\x16\x27\x4e\x81\xa1\xb5\x1b\x02\x51\x28\xe6\x1f\xa5\xce\x0d\x4e\x5e\xc2\xb8\x90\xfe\xa1\xbb\x96\x56\x19\xcb\xc7\x2c\xa1\x4f\x2e\xa2\x04\x3e\x9c\x6e\x5f\x22\xa8\xfa\x00\x13\xfe\xc9\x14\x80\x20\x85\xc8\x55\x4d\x9e\xaa\x76\xf1\x2e\x3e\x7a\x67\x4e\x9d\x41\x42\x34\xed\xfb\x9b\xe5\xe7\x84\x05\x9d\x01\x63\xa9\x93\xd6\x05\x6d\x51\x97\xcd\x70\x69\x00\x49\x3d\x65\x09\x76\x0b\x5a\x74\xc1\x84\xff\x1a\x08\x50\x09\xe7\xfb\x7a\x77\xbb\x79\x70\x7f\x35\x09\x81\xa1\x74\x2d\x5e\xaa\x61\x53\x31\x33\xb9\xc2\x00\xeb\x0b\x94\xf0\x78\x79\x79\x81\xb6\x19\x8d\x5f\x93\x1b\xac\xc9\x88\xf3\xf9\xf8\xf1\xbb\xa8\x4f\xe2\xb6\x30\x66\xfa\xdc\xfe\x15\xfd\xdb\x9d\x2f\x0c\x26\x02\x7f\xd8\xff\x0b\x12\x7f\x25\x15\x69\x5b\x2c\x7b\x40\xbb\x8f\xef\xa2\x26\x65\xd8\xaa\x1a\xeb\xe4\xea\x3c\x48\x94\xb4\xa9\x4f\x77\x63\xb5\x38\x6e\xe1\x28\x06\xb6\x5d\xf6\xbc\x50\xc4\x48\x66\x77\x0e\xfa\x99\xb1\xe6\x87\xae\x8b\x9f\x87\x22\x19\x69\x32\x3e\xbc\x7d\x32\x09\xf3\x28\x22\xdb\x53\xe4\xa0\x4c\x97\xd1\x1e\xab\x7c\x9d\x47\xe4\x11\x63\x61\xea\x11\xaf\x2e\x72\xeb\x09\x78\xa3\x37\x9c\x47\x3c\xc2\x1e\x5a\xb7\x50\x36\xf7\xe4\x6c\xfb\x9b\x3f\x26\x38\xd9\x76\x1d\x71\xff\xc7\xb4\xcc\x8b\x0e\x8c\xf0\x11\x79\x24\x24\xd2\x81\x11\x2b\x84\xad\x38\x17\x2e\xe4\xb1\xb6\x26\xbc\xdd\x55\x9a\x27\xa8\x6f\xfb\x72\x68\x1e\x6b\x93\x33\x0f\x7f\x7b\x6e\xba\x2c\xae\x1f\x5e\x79\x12\xf0\xcc\x69\xfc\x88\x56\xd8\xfe\xf2\x16\xcc\xb5\xfc\xb5\xce\xd3\x54\x12\xe5\xfd\x22\xe7\x25\xc5\x74\x9e\x85\x12\xb5\xa9\xbf\xd4\xc2\xaf\x3e\x79\x16\x31\xec\xd3\xff\x6f\x55\x94\x48\x74\x99\x7f\x25\x59\xb7\xbf\x59\x11\x8d\x21\x7d\xcb\x1d\x16\x22\xcc\x06\x85\x62\x2f\xec\x8b\x83\x24\x4b\xa6\x77\x62\x04\x32\x97\x8e\x45\x63\xd5\x5c\x56\x2f\x2f\xfe\x96\xf2\x28\x51\x76\xa1\x59\xb5\xaf\x7b\xe2\x44\xaf\xcb\xf3\xa5\x9d\x01\xa9\xe5\x79\x1a\x85\x76\x83\xbf\xdb\xed\x67\xf1\x19\x79\x2e\xc8\xb7\xc8\x35\x32\xf7\x57\x6e\x04\x3a\x67\x41\x8a\x6b\xf7\xb9\x40\x8a\xc5\x5f\x24\x2d\xee\x43\x21\x85\xf6\xe7\xcb\xf1\xb8\x2a\xdb\xfa\x63\x72\x73\x2c\x21\xa9\xb0\xa2\xd9\x5d\xce\xd6\x73\x64\xf2\xb5\xb6\x82\x71\x26\x1b\x2e\xc4\xdc\x0e\xc6\x00\x37\x2c\xd3\x3e\x99\x7d\x7a\x7b\x41\x0e\xe1\x4c\x81\x2b\x17\x91\x42\xe2\xe3\x16\x9a\xcb\xa9\x97\x88\xd6\xb9\xcc\x72\x94\x1f\xe9\x46\x20\x35\xe6\x86\xcb\x4a\x2e\x05\x33\xba\xd7\x1f\xc6\xec\xbd\xfb\x92\xa5\x8f\x1d\x72\xc5\x23\xa4\xe7\xd4\x54\xc7\x99\x7b\x0b\x3a\x95\x68\x53\xb2\xdb\x2f\xb6\xfb\xf5\xe3\x97\xc3\xee\xfb\x66\x7b\xeb\x2e\xa0\x05\xc3\xcc\xb2\x7d\xad\xab\xf7\xe6\xfb\x2b\x94\x96\x76\xd4\xad\x3d\x45\xfb\xba\x2e\x55\x55\xd7\xa0\xda\x3e\x22\xc9\xb5\xa0\xba\x63\x0d\x65\x75\x29\x15\x2c\x6a\x59\x5c\x25\x4a\xb9\x36\x22\x0e\xbd\x5f\x73\x6d\xb5\xb0\x26\x37\x07\x71\xe8\xa0\xed\xb8\x61\xd1\xfc\x99\x9c\xc3\x0d\xda\x01\x6c\xc1\x54\xa5\xfe\x0b\x7f\x33\x9d\x83\x50\x18\x56\xbe\x56\x97\x06\x0e\x06\xe0\x70\x56\xfe\x79\x81\x0a\x71\xa5\xeb\xe5\xea\xe8\xb3\x87\xe5\x6f\xe3\x8b\x28\x8d\xeb\xcf\x4b\x2d\xba\x1d\xb7\x3a\x55\x4f\x62\xa2\xe2\x66\x1b\x50\xb9\x61\x29\x32\xd2\xe4\x45\x0f\x14\xb3\x66\xcd\x47\x74\x6e\x04\x39\xde\x35\xd0\x3e\x01\xea\x51\x53\xcd\xdc\xdd\x9f\x91\x24\x84\x6c\xc1\xbc\x0f\xa2\x45\xf3\xf0\xe2\x93\xd0\x36\x37\x86\x78\xd2\x74\xf3\x58\xc9\xf7\x54\x8e\xd1\x63\x61\x81\x16\xbd\x6b\x39\x09\xfa\x8e\xde\x17\x0b\xb9\xd4\x36\x31\xed\x0e\xdc\x7d\xbf\x9d\x9c\x10\x89\x1c\xd7\xc4\x03\x06\x32\x5d\x3a\x73\x9c\xe9\x15\xda\x93\xe3\x0c\x70\xb9\xdf\x7d\x5d\x6c\x6f\xbb\x51\x47\x0a\x09\xbf\xb9\xc3\xcc\x04\xb6\xca\xff\x28\x4e\x3e\x77\x60\xb1\x4c\xb1\x1f\xbd\x17\xaa\x1a\x04\x69\x2c\x51\x06\xbd\xa7\xde\xdf\xdd\x1e\xf5\x3e\x79\xb4\x2c\x8d\xe2\xd8\x66\x03\x77\x75\x75\xda\xd7\x97\x2e\xfd\xef\x16\xf5\xbf\x6a\x9e\xb3\x34\x09\x90\xbf\x22\x6c\xab\x66\xff\x5a\x43\xf3\x5a\x1d\xb5\xdb\x21\x59\x9a\x06\xd2\x92\x1d\x68\x88\xf6\x0b\x01\x4b\x81\xe3\x14\x5a\xb5\xe2\x58\x8d\x8a\x2f\x2c\xb3\x50\x18\x0c\xe1\xd0\x2e\xba\x28\x5f\x26\xf7\x9d\x65\xe4\x85\xfd\x20\x7e\x16\xa7\xe1\x6f\xce\x58\x96\x30\xaf\xec\x32\xec\xbf\x4c\x2e\x00\x00\xfe\xcd\xa2\x17\x7f\x51\x95\x0f\x45\xf9\x50\x1c\xc1\xff\x80\x3c\x94\xb8\x0d\x9c\x44\xab\x5e\x6f\x28\x6d\x7f\xaa\xc1\x14\x3f\xc7\x25\x88\x31\x87\xd0\x7d\x38\x25\x53\xd4\x8d\x31\x5f\xea\x42\x3f\x89\x5a\xe8\xa2\xa7\x2a\x8d\xc6\x19\x0b\x24\x26\xdb\x6f\x4a\xbd\x45\x69\xd6\xb4\xb5\xd0\x7a\x8e\xd7\xa2\x19\x0b\x73\xf4\xe2\x6b\x3d\xd7\xd4\xfa\xf6\xb9\x3d\x9a\xb1\x38\x8e\x81\x5c\x7f\xf4\xae\xad\xea\xc9\xda\xc6\x58\x9e\xc7\xb6\x3a\xb8\xfa\x79\x86\xba\x2d\x1a\x98\x62\x2d\x18\x93\x42\x25\xa3\xaf\xb9\xaf\x3c\x97\xd1\x7d\x13\xcf\x65\x3e\xc4\xb6\xec\x2e\x92\xb4\x67\xc7\xd7\x12\x22\xc2\x91\xb2\x56\xa2\xf6\x30\x0b\x26\x83\x08\x37\xb1\x2d\xfc\xa8\x3c\x4e\x99\xc9\x40\xe4\xb9\x97\x66\xf8\x5f\x50\xed\x3f\xbb\x25\x62\x72\x45\x15\x64\xb1\x1c\x89\xb8\x2d\x48\xa1\xd7\x5d\x46\x29\x66\x37\x09\x8c\x82\x06\x76\x94\x9a\x29\x4d\xa2\xae\x7f\x14\x85\x57\x53\xd7\x4c\xc7\xe4\x94\xa1\xc4\x51\xdd\x5f\xd4\xdb\x47\x37\xaa\x48\x49\x67\x52\x7c\x67\x9a\xd1\x3a\xd7\x12\xfb\x89\xa4\x4c\x1d\x18\xf6\x2f\x66\x8d\x96\x44\x34\x2f\x1a\x5b\x12\x19\x95\x97\xdd\x49\x86\x81\x1a\x88\x02\xdc\x8b\xa6\x1d\x54\xb2\x18\x44\x29\xa2\x76\xcd\xd0\xb3\xa2\x99\xf6\x7f\x19\xe8\xcc\x58\x18\xdb\x03\x09\xe7\x5e\x55\xce\x46\x5f\x6b\x98\x44\x95\x12\x6a\xf0\x3e\x58\x18\xf5\xcb\xb0\x4c\x39\x98\xc1\x46\x01\x5a\x1b\x2c\xab\xb2\x19\xe0\xf1\x79\x90\x6a\x43\x9e\xa1\x5e\xde\xc3\x87\x88\x3c\xc8\x48\xb3\xd3\x1a\xb7\xcd\x04\x2e\x3c\xc8\x32\x14\x01\xa5\xc7\x79\x3c\x87\xd3\xe3\x92\x63\x2d\xb3\x39\x8b\xf7\x92\xe4\xff\xaf\x0d\xbd\xe7\x9f\x3e\x0f\xb3\x1c\xe1\x49\x58\xca\x43\xbe\xf0\xad\x68\xa1\xed\xc1\xbb\x3c\x64\x19\x06\xa9\x07\x5c\x7d\x08\x6b\xd8\x8d\x68\x7b\x38\x0a\x73\x6c\x44\xc1\x0f\x28\xdb\xfb\xa2\x69\xa1\xaf\xb2\xf2\x88\x99\xac\x77\xf0\xb6\x23\xd2\x0d\xd0\x66\xe6\x19\xf2\x48\x83\x0a\x88\xff\x04\xf5\x03\xb4\x50\x2f\xd4\x54\xb3\x42\xa3\xb6\x31\xc7\xfd\x57\xb6\xf7\xa0\x5f\xa0\x1e\x0a\x05\x6a\x1e\x47\x64\xd2\x72\x16\x75\x03\x1e\xd4\xf8\x24\xea\x29\x40\x90\xc7\x71\x90\x0b\xc7\xdf\x85\xcb\x69\x77\xea\xe6\xc5\x2f\x02\x03\x1e\xa7\x09\x29\xd7\x5d\x50\xab\xf9\x7a\x94\xf1\x98\x05\x54\x74\x83\xa6\x4b\xb8\xed\x68\xdc\x41\xdb\x10\x30\x6f\x79\x39\x61\xd7\xe8\x07\x78\x90\x1e\x8f\xad\x03\xc1\x0e\xd0\xb5\x01\x43\xcd\x3b\x98\x65\xa5\x6b\x9e\xc4\x80\x8e\x02\x3d\x5c\xfb\x2f\xc5\x61\x35\x4f\x12\xc0\x15\x62\xf5\xc7\xd3\x6a\xbb\xdf\x1d\x9e\x36\x1b\x4b\x26\xdd\xb9\x9b\x48\x44\x24\xa8\x57\x37\x8a\x20\x79\x1a\x53\x80\xf9\x02\xed\xff\xdb\xff\x8e\x4d\xc1\xf9\xfd\x9a\xa7\x09\x53\x48\xe9\x22\x49\xc2\xe7\xed\xfd\xdc\xea\xce\xd3\xd4\xa0\x7a\xf9\xab\x68\x76\xa2\x6c\x05\x41\xff\xc6\x97\xca\x72\xae\xb5\xd3\xea\x7f\xda\xae\xf6\xb7\xab\x71\xbb\xc1\x9e\x97\x27\x29\xaa\x13\x58\x25\xdd\xa1\x8e\xf3\xf8\x01\xb0\x24\xf7\xfa\x77\xa4\xb3\x6d\xe1\x37\xee\x67\x32\x19\xb9\x46\x38\x59\x17\xe3\x2e\x58\xd5\x7d\xd1\x04\x55\x73\x17\x6d\x5b\x41\xfb\x4a\x2a\xc8\xee\xb3\x3c\x17\x22\xee\x53\xb9\x43\xec\xb6\x4c\x2e\x42\x2a\x77\x6b\xf8\x31\x66\xa0\x70\x11\x52\x44\x8a\xc5\xcf\x8d\x21\xd8\xa1\x3f\x18\xe5\xc8\xca\xd0\xd4\xae\xda\xc2\x4b\x97\x95\x8a\x9f\xfe\x78\x4c\xae\x31\xa2\xfc\xc0\x28\xe2\x5f\xf9\xbf\xdd\x91\x5c\xa4\x99\x57\xff\xa2\x25\xa7\xaa\x6f\x3e\x48\x63\x15\xe6\x71\x49\x5c\x46\x26\xb0\x2a\xe6\x1e\xdc\x36\x68\x48\xfd\xeb\xdf\xff\x18\xdb\xf8\x68\xae\x98\x66\xdd\x54\x45\x74\x55\x01\x7a\x5d\x9a\x0a\x93\x97\x51\x39\x9f\xeb\x30\xc2\xf7\x53\x28\xf2\x40\x7e\x2e\x0b\xff\x23\x74\x94\x83\xf6\x56\x59\xf0\x22\x74\x75\x6b\xad\x0d\xdb\xea\xaf\x51\x5b\x1c\x44\x6c\xb7\xfe\xa6\x7d\xa8\xb4\x7f\xb2\x26\x48\x31\xce\xb2\x72\xae\x38\xb9\x67\x13\x47\x11\xa4\x39\x76\x73\xe1\x54\xb4\x8f\xd5\xa9\x28\x9f\x71\xa9\xd2\xd3\xd3\x00\x70\xc0\xbe\x88\x53\xb7\x0d\xdc\xc0\xb8\x25\x21\xc2\x30\x26\xf7\x3e\x4c\xbf\x6e\x3c\xec\x41\x44\x99\xad\x62\x9f\xab\xb2\xf9\xdc\x87\x64\x3c\x57\x45\x9c\x92\x4d\x03\x4a\xcd\x8f\xb6\x1d\x77\x42\xc6\x30\x83\xee\x82\x91\x6f\xfe\x8f\x2a\x70\xf6\xdd\xcf\x65\x53\x1d\x35\x69\x0a\xb8\xc3\x49\x9c\x62\xaa\xfa\xad\x80\xf7\x1b\x68\x6f\x3e\x26\x96\x26\xdd\x19\xa0\x52\xaf\xbf\xf1\xb5\x9e\x22\x12\xdc\x69\x12\xac\x8e\x25\x4a\x4f\x5d\x46\x93\xed\x93\x5f\x94\x31\xc0\xde\xc6\x7d\xf5\x72\x0b\xe4\x01\xba\x9c\xf6\x6e\x44\x06\x44\xce\x41\xfa\xec\x2f\xf4\xd8\x27\xcb\xf3\x20\xc6\x14\x39\xd3\x88\x89\xbf\xc5\xcf\x9f\x2b\x1f\xe4\x08\x16\x07\x68\x0e\xe0\x85\xc5\x75\x37\x4f\x61\x28\x75\xab\x05\xcb\x21\x76\x56\xf1\x55\x69\x8a\x97\x9b\xaa\x3a\xfe\x77\x08\x3b\x16\x3c\xa5\x61\x3f\x46\x9e\x09\x99\xc7\x88\x21\x91\x47\xa1\xde\x10\xc6\xe3\x0e\x70\xe9\xec\x9c\x9f\xea\xea\x47\xa1\xa1\x7e\x1c\x8a\xe8\x8e\x1e\xad\x14\x39\xb3\x01\xca\xcd\x14\xe2\x20\x74\x6a\xb8\x63\x17\x0f\xe0\xd0\x93\x4e\xe9\xec\x7c\x99\x15\xed\xd0\x42\x67\xe9\x20\xb2\xb8\x21\x99\x2a\x9b\x86\xcf\xc2\x7c\x84\x96\x24\x9c\x52\x17\x2f\xaf\x6d\xca\x26\x77\x08\x32\xc9\xb5\x27\x59\xda\x19\xd7\x3b\xb5\x4d\x26\x95\x49\x82\x88\x39\x96\xc6\x0b\x05\x46\xc3\x82\xa9\x0c\x40\x65\xb6\x87\x7b\x5f\x94\x6f\xa0\x49\xfa\x66\x32\x87\x65\x60\x00\x81\xc4\xf7\xc5\x0f\x68\xfb\x8e\x88\x8c\xe2\x00\xd1\x36\xb7\x5f\x17\x0f\x8b\x6d\xff\x57\x15\x59\xc8\xe3\x43\x55\x8a\x5a\xbd\x7e\x38\xbe\xbe\x3b\x83\x91\x11\xbc\x12\x25\x56\x6b\x66\x9f\x84\x8c\xb8\x95\xfb\xef\x16\x35\x2c\xfa\xcd\x2e\xac\x32\x0e\x12\x16\x39\x3b\x30\x8a\x4b\x9f\x77\xb7\xbf\xae\x70\xcb\x38\x4e\xc8\xb9\x13\xa7\xd8\x97\x5a\x90\xec\xe4\xcc\x5e\x2a\x63\x46\xea\xcc\x67\xb4\x0d\xa3\x52\x5a\xb7\x65\xea\x21\x5c\x4f\xa6\x71\x24\xb9\x6f\x8b\x2e\x5f\xc5\x95\x67\x93\x96\x29\x03\xac\x02\xdc\x3e\xdf\xb8\x86\x87\xcc\x42\x92\x68\xbf\xab\xea\xb7\x5b\x38\xf6\x9a\x70\x9f\x32\x03\xc6\xbf\x3e\x8b\x72\xfc\x7c\xf3\x5a\xbd\x6f\x41\x89\xc6\xce\xab\xc6\x7f\x41\xa4\x5c\x61\x71\x29\x9a\xd7\xcd\x65\x8e\xec\xac\x65\x96\xa7\xb1\x9d\x45\x8f\xe2\xc7\xa8\x32\x2d\x73\x8b\x82\x7f\x84\x53\xf5\xc7\x1f\xc3\xc8\x45\xe6\x19\x47\x36\xf5\x49\x94\x17\x71\xdc\x8f\xe8\x6d\xfb\xea\x7b\xd1\xbe\x8e\x4a\xad\xbf\x5e\x96\x65\xce\x04\xae\x4f\x2f\xc5\x0f\x78\xfc\xa9\xe6\x2b\xa9\x32\x07\xe3\xac\xd6\x1f\x8a\x72\x71\xd1\x05\x15\xd4\x1e\xfc\xe6\x2d\x59\xa0\x9c\x63\x31\x62\x46\xfd\xdf\x99\xd0\xb6\xd8\xf5\x24\x2e\x68\x3f\x38\xaa\x16\x4a\xce\x32\xa5\x06\x99\x6a\x01\x7d\x3c\x21\x39\xe7\x88\x61\x36\x4d\x3b\x60\x47\x3e\x51\x3b\xe9\xf1\x72\xa2\x40\xc0\x9d\x2d\x40\xe3\xce\x74\xb0\x45\x22\x9b\x7d\xe1\x04\xac\xff\xcf\xcc\xb6\xc9\x33\x90\x41\xe4\x84\x51\xed\x2a\x30\x9a\xd8\x4a\x19\xec\x84\x5c\x4a\x0b\x08\x83\x52\x1f\x74\x4f\x9a\x94\x0a\x02\x04\xde\xa2\x1e\xc5\x10\xb8\x21\x95\x31\x99\x76\x32\xc7\x55\x2b\xfc\x40\xd2\x81\x09\xc0\xc1\x18\xdb\xa2\x9a\x86\xe5\x52\x87\x01\x56\x12\x55\x2d\x4c\xbb\x7f\xaf\xae\xdd\x9b\xfa\xfb\xd7\xb1\x41\xbb\x04\xd9\xbf\x33\x9d\xa7\x38\x50\xb1\x6c\x45\xa5\xfc\xc9\x54\x70\x91\x91\xd4\x2a\xc7\x38\xfa\x16\x7e\x80\x1a\x81\x08\xa4\xd6\x29\x66\x44\x3b\x68\xbb\x1c\x76\xce\x9f\x66\x82\x78\x19\xbc\x7d\x6d\xf9\x10\x47\x30\x6d\x9c\x4c\x66\x88\xe1\x0a\x63\xa1\x13\x89\x19\x7f\x84\xf1\xf4\x04\x4d\x20\xa2\x13\x9c\x24\xd4\xf7\x95\xb5\xc4\xd4\x2a\x48\x78\xd6\x97\x58\x5b\x68\x26\x00\x10\xd6\xff\xeb\x3e\x91\x66\x58\x1c\xb5\x18\x0f\x12\x17\xec\x5f\x9f\x0a\x32\x2a\x02\x2e\xeb\x8f\xf3\x8f\xa2\x81\x7a\xc0\x48\x98\xc8\x8b\x69\x15\xe4\xa4\x4b\x7d\xd0\x84\x76\x9f\x9f\x56\x2a\x64\x09\x12\x9a\x5d\x69\xc5\x0f\x09\x15\xa5\x54\x7c\x26\x2c\x22\xce\xb5\x49\x9a\xa7\xa2\x4c\x23\x9c\x47\x57\xb5\x12\xa3\xae\x9b\x8a\x18\xd9\x66\xbf\x00\x95\xd6\xdc\xdf\x63\x6e\x9c\xb4\x4d\x37\x52\x76\x70\xed\xf9\x3d\x2a\x72\xf5\x42\xd7\x33\xe5\x5d\x15\x43\x80\xe8\x54\x1b\x91\x3e\x88\x9f\x23\x92\x96\x4a\x73\xa3\xd1\x70\xaa\xd2\x85\x21\x99\xb5\x99\x2a\xbc\x4a\x55\x8e\x95\x1a\x4a\xa8\xbb\x4d\x11\x23\xee\xc9\x8d\xd8\x93\xb3\x48\x05\x36\x98\xb9\x03\xb0\x6d\x96\x65\x55\xfe\xb0\x3a\x66\xe3\x4b\x67\x91\x8e\x69\xc8\x1f\x8f\x55\x7b\x0b\xad\x28\x8e\x23\x6f\x47\xad\x32\x26\x59\xea\x77\xa5\x83\xf0\x30\x15\x95\x07\xb9\x9b\x95\x0f\xc5\xd1\x41\x7d\x14\x0b\xc9\x0e\x0a\x1b\xb5\xeb\x12\x65\x25\x1b\x7f\x30\x03\x2a\xa8\x4d\x0a\x8e\x0e\x08\xe6\x4e\xe3\x09\x62\xc8\xd1\x30\x21\xed\xc5\xad\xed\x61\x19\x13\x90\xdd\x8b\xaa\x8f\x9f\xab\xcc\x89\x0c\xae\x7a\xf9\x6f\xad\x24\xcb\x2d\x8d\xef\x27\xb9\x44\x78\x1b\x02\xad\xa4\x50\xd8\x9a\x3c\x77\x1f\x88\xf1\xeb\xba\xe0\xdb\xdf\x8e\x4a\x39\x32\xf8\xff\xbc\x94\x65\x31\xa2\x03\x28\x95\xea\x18\x06\xa6\x5d\xd4\xcf\xdb\x77\xa9\x54\x5f\xf0\x51\x3a\xcf\x15\xe1\x21\xfe\x6b\x9f\xee\x60\x8a\x77\xf1\x25\x72\x10\x6f\xab\x17\x58\x0e\x5f\xed\xcc\xd6\xaf\xb4\x4c\x32\xfb\x82\xb7\x45\xf3\xf6\x24\x6a\x71\x82\x16\x9b\x8c\xa3\x81\x00\x51\x82\xd8\x84\xef\x08\x76\xeb\x61\xe1\x97\x6b\x30\xa3\x1b\xaf\x90\x46\x81\xdd\x96\xbb\xb5\xce\xdb\x5d\x69\x65\x02\x02\x07\xe9\xa2\x39\x5f\x5a\x98\xad\xc9\x2a\x93\x90\xf0\x13\x12\xbe\x6f\xa1\xac\x50\xeb\xc4\x6f\x3e\xca\xa4\x39\x4f\xdc\xfa\xee\xc5\x38\x66\x6b\x0a\x3a\x0c\x25\x8b\xdd\x00\xc0\xa0\xe6\x7b\x51\x96\x45\xe9\x63\x08\x1d\xc6\x29\xa3\xa1\xdb\xaa\xd7\x9e\xd8\xd1\x6d\xef\x63\xda\xfe\x75\x43\x59\x87\x71\x96\xc7\x5e\xe4\x62\x0b\x9a\xd2\x99\xc1\x6a\xa6\xc3\x38\x77\x79\xd5\xea\x07\x94\xe8\xe6\xde\xaf\x30\xff\x8a\xd2\xcc\x5f\x4c\xa6\xae\x90\xbc\x83\xff\x5c\xba\xcd\x79\x5c\x6b\x9f\xfc\xb4\x28\xc8\x72\xe8\xe5\x9f\xba\x81\x86\xf7\xbb\xab\x26\x26\xb5\x5a\x47\x49\x8e\x25\x2f\xb4\x71\x5a\x7c\x42\xce\xd1\x11\x18\x52\x12\x6d\x45\x7d\x73\x71\xb3\x40\xc7\x69\x6e\xc3\x49\x37\x49\x26\xbe\xc6\x5a\xc7\x82\x64\xf0\x84\xd6\xb7\x03\x04\xd1\xae\xba\xd4\x0a\xae\x58\x72\x3a\x89\x23\x1d\xf8\xc7\x36\x0d\x2e\x74\x16\x93\x23\x02\x32\x73\xab\xc9\x4f\xc9\x74\x80\x0a\x94\x24\x04\xd0\xdc\x55\x58\x48\x99\xff\x41\x79\x14\x39\x57\x10\x64\xf2\xfb\x77\x9e\xc7\x1c\xeb\xa6\xb4\x7a\x88\xf3\x5d\x55\x0f\x8d\x73\xb5\xce\x65\x88\x6d\xcf\xa2\x2c\x3e\x5f\xb9\xc7\xaf\x83\xe5\xa9\x0b\x21\x6e\x2f\x70\x4d\xf3\xd2\x4c\x92\x48\x8e\x43\x85\x0e\x74\xe5\x7f\x9b\x5c\x4a\xa9\xc4\x56\x28\x2f\x2f\xb6\x3b\x38\xea\x0d\x6a\xa6\x13\x54\x98\x3b\xbd\x9c\x5a\x82\xe5\x59\xa2\x4d\xcf\xe9\xd0\x3c\x30\x52\xba\xea\x2c\xae\x54\xdf\x1f\x6e\x8b\x66\xe0\x02\xac\x35\x8f\xe3\x38\xf2\x06\xf0\x1a\xd5\x09\xfa\xda\xbe\xe6\x79\x8e\xe8\xcf\xee\xf6\x76\xa3\x68\x53\x8b\x2c\x12\x64\x71\xd4\x5e\x2c\xd9\x01\x35\xeb\xe6\x11\xb8\xbe\x58\x8b\x44\x81\x7f\x5c\xa7\x9e\xee\xdf\xf0\x93\xa0\x50\x0b\x9e\x29\x2f\xe9\x8d\xbb\xdb\x6a\xff\xd5\xdf\x8c\x89\x10\xde\xd0\x63\x51\x6d\x82\xed\xd4\xad\xc6\xd7\x92\x09\xb8\x92\xe4\xad\x68\xc5\xb8\x0d\xa3\x65\x4a\xaa\xdd\x94\xd7\xee\x41\x9c\xc6\x26\xe1\x93\xf7\x2e\x19\x50\xb9\xa5\x8b\x1e\x90\xdd\x3e\x1f\x83\x68\x09\xa4\x17\xf5\x22\xa6\x48\x7b\x2d\x8d\xc1\x96\xe3\x72\xfb\xe7\xd3\x7e\x73\xfb\x7c\xb3\x70\x39\x94\x56\x41\x84\x9a\xce\xd8\x57\x5d\x9d\xce\x45\x0d\xc3\x7d\x43\xab\x98\x48\x6b\x2e\xb2\xb9\xab\xea\xfd\x7b\xf5\x27\x08\x3f\x9d\x14\x30\xec\x01\x59\xed\xbf\xaf\x8b\xed\xea\xb0\xb9\x3b\xdc\xaf\xbe\x2c\xee\x5d\xf5\x56\x43\x4a\xc8\x36\x6b\xc8\x54\x90\xde\xfb\xae\x15\x27\xaa\xb3\x84\xee\x56\x21\xcf\xb0\x64\xff\x2a\x9a\x45\xf9\xb1\x68\xdb\xba\x19\x47\x10\x6e\xb8\x03\x8f\xf0\xb9\x88\x1f\x2f\x64\x2c\x57\x94\x84\x07\x73\xc7\x85\x74\x14\xf5\xeb\x88\xe5\xd7\x19\x82\x36\x52\x08\x52\xa3\x42\xca\xe7\xe2\x6e\xff\xfb\x0e\x7e\xf8\x87\x02\x41\x24\x23\x2f\x16\xa1\x8b\x1f\x45\x69\xd1\xf2\x94\xdc\xfa\xd3\x44\xe2\xe4\xe3\x7a\x3d\x82\xd1\xdb\x85\x90\x05\xc2\x71\x12\x1d\x60\xe8\xe6\x03\xad\xfb\x61\x3d\x96\x7a\x82\x50\x73\x6c\x07\x90\x0e\x27\x7e\x21\x06\x2d\xb3\xc5\x43\x88\x52\xc3\x2c\x7e\xe7\x7b\x51\xce\x81\x8d\x21\x52\x31\x66\x59\xb4\x4e\xde\x54\x52\xdc\x74\x81\xc8\xe8\x59\x40\xa4\xf3\x48\xf4\xd4\x94\x9b\xfd\x72\x4a\x05\x9a\x4e\xc9\xd1\x4d\x47\x40\x7e\x0c\x8b\xa8\x17\x98\x79\x12\x75\xdb\x67\x4d\x90\x04\x21\x62\x2a\x17\x2f\x75\x81\x8a\x65\x28\xef\xee\x0f\x4a\xec\x3b\x62\xb5\xf1\xae\x5b\x6a\xbe\x03\xbc\xf9\xa3\xb1\xc1\x2a\xcd\xa9\x28\xdb\xf1\x54\xfc\xc7\x78\x11\x1d\xbf\x60\x48\xc0\xe0\x63\x37\x47\x67\xa1\xa9\x21\xe5\x54\x4d\x78\x12\x93\xf5\x12\x52\x93\x32\x72\x40\xb8\x5f\x2d\x76\xab\xc3\xfa\x71\xbf\xda\x7e\xf3\x40\x61\xc8\x58\x90\x58\x77\x89\x27\xef\x1c\x3e\x3f\x9d\x21\x4f\x00\xb3\xeb\x63\xa1\xa0\x6c\x60\x12\x0d\x41\xae\x09\xc0\x8c\xdc\xa7\x85\x42\x68\x04\x6a\x17\x6d\x2e\xed\xc6\x5c\xa9\x6f\x6b\xc8\x0d\xc7\x8a\x5f\x23\x7e\x4c\xc3\x9d\xc9\x6f\xe6\x31\x60\x9b\xf2\x11\xde\x71\x98\xce\x2f\x23\xc0\x79\x8e\x90\x2c\x0f\xea\xde\x6e\xdc\x62\x01\xdc\x44\x58\xc0\xc4\xb2\xd2\x20\x25\x06\x91\x67\xa8\xea\x25\x2f\x1f\xf7\x55\x6f\x5c\x31\xa3\xe4\xd2\xfb\x61\xc4\x76\xbb\x06\x19\x26\x18\xb9\x9f\x44\x73\x25\x7a\x3d\xe2\xed\x8c\x1f\x95\xcc\x25\x3a\x3d\x3f\x08\xca\x62\x1d\x54\x1d\xa4\x61\x78\xbd\xed\x67\x8c\x8d\xab\x09\x0f\x4a\x87\x38\x4a\xef\x9e\x1d\xd4\x16\x74\x46\x16\xfd\x87\x17\x68\x6f\xea\x42\xdb\x19\x77\xa5\x35\x03\x3a\x33\xe8\x25\xf7\x4f\x68\x2e\xcd\x44\x4d\x51\x83\x16\x01\xe2\x38\x0f\xe4\x8b\x31\xa8\x97\x00\x44\x21\xd2\x2c\x96\x1f\xd2\x96\x7d\x7e\xf3\x47\x08\xcf\xd4\x5d\x48\x1d\xab\xa6\x28\x5f\x06\x69\x05\x80\x85\xc0\xd7\x42\x81\xd3\xd5\x1c\x95\xb9\xc7\x43\x0e\x18\xc7\x28\x72\xf7\x8e\x2a\x1c\x9f\xbc\xf7\x2e\x7d\x0f\xc9\xbf\xc3\x91\x67\x5c\x7b\x66\x32\x1d\x0c\x4f\x06\xde\xa4\x7f\x85\xf4\xfd\xa5\x90\x25\x1b\x2f\x16\x86\x1b\x62\x78\x15\xa7\x73\x17\x07\x5e\xa1\x21\xc0\x88\x00\x59\x50\x77\x55\xa9\x2b\xc7\x20\xfa\x45\x1a\x02\x46\x24\x48\xe0\xef\xf2\x8f\xdb\x68\xdf\x57\x60\xc1\x40\x1e\xd8\x5d\xfa\x7e\xb3\x94\x57\x1d\x07\x13\x84\x19\xaa\x74\x5b\x95\x6c\xaa\x40\xff\xe6\x0e\xa6\x42\x3a\xa6\xed\xf5\xb4\x34\x51\x00\xa4\x59\x4a\xb8\xb6\xdd\x47\x89\x18\x5e\x18\x6e\x51\x26\x8e\x94\x90\x7d\x06\x4a\x10\xec\xef\x50\xf8\xe3\x52\x65\xc4\x66\xff\x51\x34\xfd\xa7\xa4\xc6\x4f\x7d\x81\xf6\xe1\x83\x1a\xd0\xf6\x48\x92\x52\x4e\x7d\x57\x5d\xea\x7b\x10\x66\x79\xac\xbc\x85\xb6\x36\x49\x66\xc3\xde\xe2\x9a\xcd\x39\x43\xea\xcc\x92\xf1\x3f\xee\x2a\x3a\x93\xc9\x20\xca\x1c\xc8\xdf\xbb\xf8\xdb\xa4\x79\x82\xa8\x71\x07\x78\x1c\x6f\xe0\xb9\x3d\x2b\xeb\x02\x25\x07\x9b\xe8\x3d\x80\xd1\x0b\x2b\x9c\x3c\xce\x3c\x49\x64\xe4\x0c\x0f\x2e\xa5\x86\xda\xd9\xce\x8d\xcf\xe3\x01\xa0\xbb\xcb\xb6\x3a\x42\x13\xdd\x17\xb2\x16\xf5\xc7\xa2\xd4\x28\x7b\xef\xfe\xdf\xb1\x7a\xe4\x78\xb2\x18\x1e\x2b\x44\x6d\x61\x5b\x6e\x98\x84\x18\x6e\xc1\xf9\xfe\x4e\xff\x8e\x9a\x6b\x3f\xdd\x0d\x97\xb9\xcb\xa7\x88\x89\xa5\x26\x35\x6e\x23\x03\x11\x11\x66\xfd\xdb\x7e\xc4\x88\x37\x32\x92\xd4\x09\xc4\x8e\x50\xef\x0f\xe2\x0e\xa7\x64\x11\xd9\x00\x51\x07\xa7\x3b\xbd\x91\x2a\x89\x73\xaf\xd7\xd3\x77\x08\x67\x57\x43\x23\x15\xc3\xf7\xf7\xb0\x7e\x5c\x3f\x2c\xee\x0f\x4f\xcf\xdb\xe5\xd7\xc5\x6e\xe5\xbf\x0e\xa2\x88\x10\x7c\x8b\xd2\x01\x69\xa6\xdf\xa8\xa2\x40\xd8\x0a\x55\x97\x92\x7a\x75\xea\xf1\x8c\x37\x3a\xe2\x18\x0c\xdf\x6c\x9e\xf7\xbb\xa7\xed\xe6\x40\xc6\xdc\xee\x9b\x74\x1e\x81\x83\xf9\x74\x91\xf2\x4a\xd4\x94\x5c\xcf\xdf\xb8\xce\x13\x74\x87\xda\x6d\x1e\xd7\xcb\xd1\xeb\x99\xfb\x6a\x99\x6b\xf2\x0a\xa1\x96\xdf\xe2\x8a\xbb\x30\xbb\x9c\x1a\x88\x08\xe5\x4d\xcb\xdf\xb7\xe2\x8a\x5b\x3b\xbf\xc7\x18\x13\x12\x75\xec\x2c\x2e\x0d\x0c\xe4\xf4\xe7\xc7\xa1\x49\x59\xda\x1b\x24\x59\x87\x56\x1f\x2d\x5c\xd5\x0a\x20\x08\x74\x82\xb0\x12\x2f\x74\x82\x56\x91\x73\x0b\xf4\xf0\xb6\x20\x08\xf3\x08\x4b\xb3\xf4\x45\xeb\xe5\x66\xe0\xf2\x06\x41\x08\x21\x58\xf7\x8f\xb1\x24\x35\x04\x51\x18\x23\xae\x95\x48\x5d\x1b\xb3\xb5\x36\xcf\x4b\x24\x4a\x0d\x7f\x0d\x04\x49\x9a\x1b\x6b\xa1\x47\x81\xe8\xb4\x11\x38\x39\x5d\x30\xec\xf5\x16\xcd\xed\xe2\x7c\xde\x82\xd0\x1f\xee\x86\x12\x15\x62\x1a\xfc\x5a\xbc\xbc\x0e\x85\x6e\x16\x68\x28\x3c\xbe\x4c\x1a\x65\x49\xdf\x0b\x46\x0a\x93\x82\x73\x5b\xa1\x9f\x23\xd9\xc8\xb8\x33\xe3\x8c\x44\x9c\x09\x9c\x37\xa8\x90\xf9\x33\x98\xc6\xd2\x1b\x05\xdf\xf7\xab\x3f\x86\xc2\x72\x93\xef\xcd\xc2\x1c\x1f\x1a\x61\xf7\x9f\xcb\xb6\x38\xba\xcb\xe4\x51\x88\x55\x31\x45\x10\x75\x5b\x4e\x6c\xfc\x61\x1d\x49\xb2\x88\xa9\x7e\x7e\x5c\xc9\x22\x4d\xc7\x59\xdf\xf9\x85\x80\x33\x52\x9b\xa5\xdf\xda\xce\x2c\x4d\x33\xb5\x30\x08\x44\xc8\x1d\x7e\xdd\x52\x10\xbc\x44\xc8\xd5\xf2\x0a\x81\x4c\x25\x82\x87\x54\x37\x4d\x7a\x9b\x22\x54\xc6\xe8\x7b\x8c\xee\x64\xc9\x55\x62\x6d\xcd\x9a\x1e\xf4\x09\x81\xd4\x29\x6a\xfd\x4a\x51\x2a\xf4\xcb\xfd\x01\x75\x0b\xf5\xa8\xd1\x09\x81\x04\x63\x45\xbd\x4f\xa2\x18\x51\x1e\x20\xd0\x29\x51\x17\x84\x76\xf6\x46\xfb\xea\xe6\x28\xd4\xdb\xd0\x34\x69\xf2\x4b\xb5\x21\x87\x06\x52\x4e\x77\x36\x90\xe3\x73\x20\xe4\x88\x6b\xe9\xe2\xa4\x52\xef\xae\x0a\x23\x10\x18\x16\x60\x83\xf6\x41\x88\xff\x76\xa9\x90\xfb\x33\x8f\xa4\xcd\x5a\x5f\x89\x0f\xd8\x97\x20\xc6\x1b\xe9\x67\xeb\x03\x04\xc6\x30\xdd\xfd\xa8\xe5\x6e\xd7\xce\x79\x81\x0f\xef\x23\x0c\x18\x19\x61\xbf\x9f\xac\xb7\x71\x18\x51\x57\x26\x8c\x98\x3b\x85\x87\x28\x2d\xe1\x58\xd1\xb7\x15\x34\x58\x22\x5c\xfd\xec\x9e\xd2\xe8\x65\x85\x81\x32\x8c\x8d\x7a\x62\x73\xa2\x29\x10\x86\x26\xc2\xa2\xcf\x8f\x41\xef\xd9\x2d\x41\x61\x14\x90\x91\xdd\xa1\x11\x06\xdc\xe8\xed\x86\xf8\x75\x1c\x6e\x3f\x11\x73\xeb\xd7\xa4\x2a\xdc\xf7\x5d\xfd\xa8\xaf\x36\x59\xa8\x12\x84\xb1\x34\x32\xf7\x63\xef\xbe\x12\xa5\x07\x1b\xbb\xf8\x83\xf7\xab\x62\x4e\xff\x19\x47\xff\x4a\xfe\x3d\xf9\xce\x24\x01\xec\x36\x37\xe7\x42\xc1\xf3\x79\xf4\x7e\xc3\x24\xd3\xf1\x50\x73\xe8\xbb\x97\x7d\x83\x2e\x4b\x41\x11\x90\xfd\x7a\xb5\x8d\x57\x8f\xb7\xfd\xdf\x55\x48\x1e\x7a\xa7\xb3\x9f\x3d\x45\xa5\x37\xc6\x9f\x21\x12\x54\xfa\x23\x4e\xd8\x00\xf8\x02\x61\xa2\xa9\x83\xf0\x54\xd0\xaa\x73\xe3\x5b\x01\x10\x26\x00\x88\x14\xba\xe9\x92\xce\xaf\x8b\xed\xed\x61\xb9\x78\x42\x47\xcf\xed\xe6\x79\xf0\xfd\x26\x0c\xc8\x12\xb7\x21\xbc\xc8\xf8\xf7\xa6\x59\x92\x0b\x67\x14\x24\x48\x25\xc0\x8d\x91\x94\x49\xc4\x09\x58\xa1\x1c\x67\xd6\x7b\x65\x6f\x6a\x4f\xcf\x02\xb0\xf8\x79\x51\xab\xd7\x45\xa9\x6f\x8a\xf9\x62\x2f\x84\x59\xc8\xb1\xf6\x71\xe8\x16\x41\xbb\xcc\xfd\x9a\x91\xef\x3f\x28\x71\xe3\x5b\x94\x2f\x70\x9c\x68\xfe\x42\x98\xa5\x0c\xab\x3e\xb4\x5b\xad\x7e\x9e\x91\xe7\x63\xa3\x99\x31\xaa\x64\x74\xd5\xdc\x90\x87\xc0\xd7\xea\xff\xe3\xec\xdd\xba\x1b\xc5\xb5\xb6\xd1\xff\xf2\x5d\xd5\x45\x5f\x08\x01\x02\xf6\x9d\x4f\x49\xf9\xed\x38\xce\x1b\xbb\xaa\xba\xd7\x1a\x7b\x78\xe8\x30\xe5\xd0\xc1\xe0\x06\x9c\x94\xfb\xd7\xef\xc1\x94\xc4\xc9\x24\xd5\xfb\x5b\x37\xd5\x2b\x92\x31\x06\x69\x6a\x1e\x9e\xf9\x3c\x55\xdd\x6b\xf8\x06\x2f\x06\x41\x84\xe3\x19\xf3\x96\xc0\x55\xd6\x92\x87\x83\x97\x04\x1e\x9e\x0b\x75\x73\x1f\xd8\x3e\xb2\x83\xfa\xb1\xa8\x11\x88\xd5\x3c\xec\xc7\xa2\xee\x55\x80\xc1\xe3\x11\x41\xa8\x9d\x89\x60\x9e\x4a\xd8\xdf\xaf\x86\x9a\x00\xe0\x71\xae\xb1\xc8\xf2\x3d\xcd\x87\x34\xfa\xe0\x71\x2d\x10\x28\x7f\x18\x90\xdd\x7e\x7e\x82\x7b\x82\xc4\x98\xe9\x71\x29\x3a\x27\x4e\xd9\x2e\x5c\xa1\x22\x2c\x41\x38\xf6\x5b\xa7\x27\x0d\xd0\x33\xcb\x9e\xf4\x42\x3f\x76\x60\x87\x52\xcd\xaf\xb7\x29\x23\xf0\x64\xe2\x63\x66\x8c\x0b\x9e\xab\xa1\x0c\x04\x78\x52\x53\xa3\x7a\x8b\x3f\xbe\x6d\x13\xe9\x49\x42\x81\xa7\x18\x18\x34\x36\x54\xf5\x0c\xcd\xac\x81\xfe\xb9\x71\x50\x5e\x6c\x33\xc6\x0f\xbc\xaa\x37\x69\x06\x55\x5d\xe4\xa6\x28\x50\xcd\xea\x6e\x9e\x31\x44\x73\x40\x9d\xa6\xbf\x2f\x69\x59\x42\xb6\xbc\xbc\xb6\xef\x4e\x87\x0c\x3b\x6e\x5f\x8a\x4c\x35\x01\x34\xff\x39\xec\x5a\x05\x4f\x6b\xa9\x92\x4e\xe3\xbd\x53\x17\xef\xa2\x74\xa0\xc4\x37\x15\x9e\x42\x63\x32\x1d\x1b\xe5\x76\xe9\x31\x6f\x2d\xc7\xf0\x9c\xa1\x24\x10\x78\x36\x29\x30\x78\xef\x2f\x37\xc3\xe8\x5b\x9b\x6c\xe9\xc3\x76\xf1\xfb\xfa\xf1\xbe\xd9\xd3\xeb\xad\xdb\xd0\x94\x68\x85\x9e\xd5\xdf\x17\x28\xaf\x4e\x46\xb3\xff\xca\xa9\xc7\x4d\xe7\x57\x05\xb9\xb2\x70\xba\x1e\x08\x75\x5f\xec\x97\x2b\x77\x31\x4f\x0b\x6c\x2b\xb9\x2f\x32\xe8\x97\x04\x81\x52\x02\xd2\x69\x7f\xce\x94\x53\xa3\xbf\xe3\x69\x56\xcd\x44\xf1\x06\xdb\x37\x28\x75\xe6\x5a\x4a\x81\xd2\xc4\xc7\x78\x78\xb5\x9e\x4f\x2a\x88\x0d\x56\x25\xf5\x09\xf1\x49\xdb\xc2\x88\x0d\x68\x4d\x14\xab\x0c\x97\xe2\xf0\xa1\xf8\x7e\x80\x3d\xdd\x48\xa1\x6a\xdb\xf6\x7b\x5d\x24\xe3\x2b\x43\x6c\xfa\x9c\xd7\xff\xfb\x6d\xbd\xc4\xfe\x68\x8b\x15\x46\xdb\xd8\xe6\xed\x81\xfa\xda\x94\x44\x72\x78\x6f\x0e\x8c\x49\x4e\xd3\xff\xbf\xf8\x11\xa0\x81\xa7\x30\x9b\xfe\x50\x1c\x77\x50\x4f\xec\x12\x1a\xc4\x71\xe0\xb7\x50\xb3\x6d\x0e\xa3\xf1\x30\x14\xc2\x7a\x5d\xcd\x51\xf9\x0a\xc3\x48\x10\x28\x63\x1c\xad\x67\x5d\x9c\xdc\x6f\x61\x91\xc0\x44\x12\x48\x55\x71\x0b\x3f\x1d\x94\x3d\x3e\x01\xd3\x01\x8d\xa2\x08\xed\xd2\x3c\x3d\xca\x17\x5e\xef\xa7\x1c\x8c\x9b\x18\x09\x68\xc4\x69\xe7\x1e\x1e\x8b\xdb\xaa\x3f\xd0\x38\xa1\xb8\x58\x9f\xa1\x6a\x1c\x6a\xc3\xc7\x60\xc7\x78\xa2\x59\x5b\x62\x5f\xd5\x2f\x5d\x63\xa6\x9d\x20\x19\x57\x61\x4f\xeb\xe8\x0e\xa0\x47\x13\x0a\x54\x82\xaf\x2d\xfe\xe1\xc1\x1d\x49\x76\x48\x79\x91\x6f\xe9\xc4\x77\x90\xe9\xad\xd6\xed\x88\xaf\x91\x8d\xcf\x20\x45\x7f\xff\xbe\xdf\x17\x7d\x1b\x4d\x95\x56\x48\x7f\x6f\x5c\xe5\xbb\xa2\xa8\x45\x63\xa2\xca\xc6\xc4\xfc\xab\x02\x01\x50\x2d\xe3\xc8\x92\x7a\xce\xca\x3a\x95\x19\x7c\xbd\xad\x87\x77\x73\x51\x1e\xde\xf2\x50\x2d\xc6\xb1\x4f\x3b\x0d\x9c\xf9\x75\xc6\x68\x9d\xeb\x62\xda\x71\xf2\x49\x92\x20\xd4\x11\x75\x7b\xe7\x85\xc3\x89\x83\xef\x45\x81\xe4\x9d\xbc\x72\x2b\xa7\x3f\xed\x15\xfb\x34\x31\xcc\x67\xe2\xfa\x0f\xcf\xeb\x34\x37\xb2\xef\x56\x2f\x7a\xe8\x23\xfa\x41\xc4\x51\xc3\x4c\xbb\x9e\x21\xcf\xdd\x4d\x90\xc4\xe8\xa8\x2c\x9d\x0e\xee\x5a\x41\x5e\xa7\xf5\x30\x91\x0e\x7e\xc8\xc0\xb7\x49\x81\xc6\x15\xa1\x5f\xa6\x12\x4d\xbf\x0d\x2e\x1d\x79\x01\x02\xa3\xd0\x16\x4e\xd8\x0e\x3f\xf2\x05\xba\xb9\x2f\x50\x16\x5b\xbd\x7f\x81\x27\xc7\xc2\x0c\x7e\xc4\x0c\xf0\x5d\x5c\xae\x07\x6c\xa8\xb1\x7f\x8f\x89\x61\xf5\x3b\x15\x45\x8e\x84\xa6\xed\x80\x0f\x32\x42\x4e\x45\x78\x67\x71\xfb\xd7\x04\x5c\x9d\xd7\x45\x7d\x4d\x70\xe8\x86\x93\x80\xa1\x13\xdb\x66\xcc\x17\x45\x35\x9d\x5a\x01\x3f\x49\x42\xca\x3b\x5f\x6d\x07\xf2\x52\x42\x87\x0e\x6f\x26\xb4\x60\x95\x6f\x65\x36\xab\x5d\xbf\xe3\xa7\x2e\x80\xcf\x23\x82\x58\xd9\x05\x3a\xc7\xc5\x07\x31\x90\x2f\x48\x60\xaa\x0b\x18\xc4\x3e\x19\xfc\x83\x2c\xb9\xe9\x43\xa1\xb3\xdb\xce\x04\xf0\x05\x30\x3c\x68\x9d\x77\x61\x8e\x73\xe7\x96\xfb\x52\xfa\xbc\x23\x40\xdd\x17\x19\x94\x83\x1c\xca\x14\x37\x68\xf3\x29\xed\x18\x69\x2e\x99\x7a\xc6\x8d\x6a\xb9\xaf\x46\x8b\x0e\xdb\x17\x5a\xfc\xd7\xb1\xaf\x0c\x05\xbe\x04\x6d\xb5\x5d\x8a\xf3\x9e\xbf\xf6\x2b\x97\xe0\xab\x84\x62\xce\xeb\x94\xe6\xf5\x86\x97\xc7\x36\x88\x1c\x9d\x02\x2e\x56\xe8\x89\x76\x1b\xb5\x6e\xe4\xcd\xea\xe9\x0c\xda\xeb\x42\x6c\x1a\x51\x7e\x2f\xca\xd7\xc1\x17\xea\x98\xa1\x4a\x91\x8d\xed\x47\xcf\x51\x6b\x8d\x1c\x27\xdb\xc7\x3d\x46\x16\x7d\x28\x10\x04\x5e\x48\x50\x78\xe5\x64\x04\xe3\x4d\x8b\xc7\x3a\xbf\x2b\x8b\xd3\x2e\x15\x59\xb7\x76\x03\x2f\x89\x0d\xd3\xcb\x19\xf2\xdf\xff\x5c\xb4\x7f\x56\x11\x62\xd8\x1f\xe1\x7d\x9d\xd7\x8d\xe7\x2c\x5f\x36\xa0\xd2\xa1\x4e\x32\x04\x34\x0c\xb0\x09\xa6\xb6\x12\x3f\x96\x58\xdd\x5d\x86\x26\x81\x29\x22\x23\xdb\x42\x0d\x18\xcc\xce\xaf\x1b\x68\xce\xe4\x89\x72\xca\x87\x9c\x87\x10\x50\x21\x1c\x37\xad\x21\x31\x5a\xc2\x5b\xb3\x81\xfb\xcd\x09\x10\x50\xcd\x31\xf0\xdc\x43\x26\x1b\x67\x74\x78\xb7\x7e\xa8\xb1\x97\x78\x07\x75\x8f\x32\x77\x76\x2c\xa7\xc4\x6c\x87\x06\x35\xf0\x05\x91\xd6\xcc\xab\xb4\x2e\xca\x69\x21\x64\x08\x7c\x49\x1c\x46\xa1\xf1\xed\xf2\x1e\x0d\x41\x37\x03\xd7\xe0\xa2\xe4\x28\x1c\xd9\x6f\x68\xb2\x53\x82\x30\x42\xcb\x76\x0f\xf9\xe2\x25\x3d\xcf\xaf\x86\xad\xf2\x07\xf2\xa6\x7c\x19\x82\x15\x46\x61\x73\x10\x72\x8a\x34\x49\x8b\xf2\x7a\xae\x8b\x65\xef\x6d\x84\x3a\x41\xb4\xee\xa6\x28\x66\xea\x6d\xf2\xd0\x1e\x3c\x72\x16\x27\xc8\x39\xe6\xa2\x87\x05\xb7\xdb\x29\xfc\x54\x46\x0c\x02\x66\x11\x80\x69\xf5\xc4\xaf\xe8\x01\xdb\x81\xc8\xe3\xa8\xe6\xf3\x5a\x9c\xce\x69\x0d\xf2\xa5\xbf\xe2\x83\x48\x80\x6e\x91\xb0\xc5\xa5\x89\x1b\x06\x14\x89\x10\x44\xc0\x88\x6b\x0b\x98\x65\xa9\x84\xf9\x98\xb2\x65\x24\xb7\x03\x41\xec\x1b\xac\x68\x85\xd2\x90\xeb\x2f\xed\x9f\x01\x17\x0a\xa6\x6b\x9b\x68\x72\x7b\x86\x1c\x73\x7a\x50\x8d\xf6\x5a\x10\xf3\x30\xb0\x46\xf4\x2b\x94\x85\x31\xf1\x93\x26\x31\x48\x22\x53\x03\xef\xa0\x1d\xb3\x2c\x4b\xf3\x74\x90\x70\x0a\x38\xd3\xa4\x05\x38\x2d\x78\xfe\x86\x42\xdf\x28\x5b\x5f\xb8\x1c\xe0\x65\xc0\xa1\x3b\xfa\x1a\x9e\x18\xc8\xda\x09\x21\x84\x78\xdb\x2d\xbb\x1d\x04\x1c\x0c\x04\x0a\x81\x02\xef\xbc\x54\x43\x5a\xb6\xd1\x03\x92\x01\xc7\x2c\xf7\xbe\xbc\xc0\x5d\x96\x9e\x6f\xdb\x32\x21\x90\x3a\x90\x26\x43\x86\x84\x3e\x3d\xb8\x3d\x04\x8a\x78\x78\x2a\xbe\xf1\x2c\xc5\x22\xee\xf0\xf2\x8a\x31\xcc\x8f\x20\xa4\xed\x96\xac\xa0\x99\xa0\x15\x52\x9c\xf1\x32\x6d\x0c\x99\x91\xf0\x74\x83\xc2\xf4\x93\x0e\x64\x81\x6d\x91\xb2\xb5\x76\x4a\x19\x4d\x20\x87\x06\x39\xc1\xf3\xe2\xf3\xb4\x40\x00\x01\x45\x55\x4c\x53\x85\xdb\xf0\x9c\x8f\x6b\x0e\x10\x40\xc8\xd1\x32\xeb\x34\x57\x9d\x14\xa7\x1b\x8c\x03\x13\x99\x3b\x8e\x88\xc5\xd7\xf5\xa2\x55\xa0\x6b\xc6\x0d\xbb\xbc\xf1\x0a\x1f\xe1\x67\xfd\x54\xc2\x29\xbd\x9c\x5a\x15\x9f\x78\x7c\x4b\x82\xf5\x52\xf4\x7f\x2c\x9f\x9f\x6f\x1f\x26\xe8\x30\x6a\x79\xee\x2b\x9b\x58\x01\x75\x57\x94\xb3\x1b\x88\xf6\xff\xed\xbf\xed\x57\x01\x3a\xdb\x69\x8e\x85\xe6\xcb\x10\x76\x3b\x34\x8e\x21\x89\x02\x84\x0d\x3a\x01\x8b\x7b\x5e\xf5\xf3\xfe\x21\xd1\x91\x6b\x44\x99\xbd\xf1\x34\x6b\x6c\x82\x0d\x10\x6f\x9d\x91\xf6\x33\x09\x65\x6d\x6f\xc1\x43\x27\x87\x01\xa1\x47\x14\xda\x97\x1c\xa0\x95\x55\xe9\xaf\xc9\xd0\xf3\x05\x96\x3a\x9d\x97\x81\x36\x68\x78\x79\x4a\x03\x8a\xf5\xb3\xa2\x96\x2f\x69\xcf\x35\x6e\xc7\x35\xed\x0a\x19\x56\x6e\x6f\xf0\x36\x42\x2a\x83\x5e\x73\x98\xf5\x56\x27\x9a\xb8\xda\xe9\x1a\x43\x1b\xc8\x65\xa1\xd2\xfc\x78\xd0\x45\x79\xe2\xed\x8f\xf2\x01\xf0\x19\xbd\x15\x35\x3c\x62\x97\xeb\xfc\x3a\x53\xa7\xf4\x17\xf9\x9a\x30\x88\x62\x1e\xb4\xe5\x81\x05\x3f\x37\xbb\x68\xd4\x11\x00\x61\x90\x04\xa2\xe7\x11\x8c\x46\x43\xc6\xa4\xc9\xc4\x57\xd3\xe8\x44\x08\xc3\xc8\xb4\x14\x0c\x68\x67\xaa\xf1\x75\x22\x02\xa6\x94\x37\x04\xa1\xd9\x61\xe6\x13\x24\xee\x9f\xf3\x0a\x46\x69\xac\x90\x85\x09\x86\xe1\xd6\x99\x34\x98\x1e\x3a\xbe\x80\x0c\xc2\x3e\x30\xde\x10\xdb\x4e\xda\xc8\x90\x69\x1f\xd3\xc7\xa7\x22\x87\xeb\x47\xaa\xc6\x10\x46\x91\xa1\x7c\x76\x72\x77\x83\x03\x27\x8c\x62\xa9\x0c\x09\x44\x63\x21\x4e\x56\x03\xad\xc7\xc3\xe4\x6e\x3f\x52\xb1\x0b\x3d\x8d\xf6\xa7\xe3\x39\x1d\xfd\x82\xc4\x23\x86\x47\xdd\xb4\x83\xb8\x8f\x27\x34\x8c\xad\x14\x1a\x52\x69\xf4\x40\xb1\xa3\xfb\x4d\x58\x8c\x0c\xb5\x88\x1f\xaf\xbf\x7c\x82\x4b\x82\x30\x89\x3c\x4c\x31\xe7\xcd\x42\xcb\x96\x70\xba\x94\x25\x3f\x4e\x69\xab\x40\xc8\x43\x85\x48\x39\xb3\x98\xbf\xe5\xe9\x4d\x2f\x3a\x84\x9c\xf9\x68\x8d\xdd\x1a\x18\xd0\x17\x8c\xbe\x9b\x4b\x1f\x97\xf3\x5d\x5a\x9e\x78\x07\x72\x87\x50\x92\xc8\x57\xad\xea\x63\x3d\xd1\x2e\x07\xa1\xa4\x12\x7b\x13\xcf\x50\x36\x9b\xe4\xa3\x46\x67\x08\x65\xa0\xb1\xca\xa1\xad\xf2\xf7\x6e\x42\x70\xcc\x4d\x0d\x29\x31\x3d\x31\x8d\x5f\x74\xac\x46\x2f\x50\xc5\xc4\xc8\x22\xd6\xc0\xb3\x05\x2f\x51\x17\x77\xc4\x8c\x01\x21\x78\x26\x3e\xe9\x94\x9e\xcb\x42\xa7\xe3\x75\xde\xb8\xd5\x16\x2c\x68\x81\xbf\x87\x33\x94\x07\xe8\xaf\x56\x37\x95\x19\x59\xa6\xfa\x58\xee\xa0\xbe\x4b\xf3\xb4\x6a\xf9\xd2\x21\x74\xa7\x8c\xe3\x82\xe8\x65\x12\x43\x48\x34\xae\xef\xc5\xf6\xf9\x79\xb5\xe8\x68\xfd\x20\xd4\x89\xd9\x25\xf9\x10\xaa\x0c\xa1\xe6\x1e\x98\x0c\xa5\x2c\x72\xd5\x57\x70\x1b\x54\x11\x42\xad\x22\x5c\xa4\x58\x12\x19\x6d\x54\x46\x18\x20\xca\xd6\x91\xa3\xf5\x93\x21\x8c\xe8\x08\x95\x0d\xcc\x2a\xda\xf0\xb2\x4c\x9b\x28\xab\x2f\xaf\x3e\x38\x49\xfa\xa1\x10\xa3\xd4\xf4\xe4\xf2\xdc\xb0\x24\x59\x41\x8e\xfe\x86\x64\xd4\x37\x28\x9a\x23\x18\x90\x70\x9f\x0c\x01\x18\x8d\x04\xa6\x60\x4f\x69\x0e\x86\xa5\x0c\xf9\xbd\xdc\x68\xc2\xb1\x66\x77\xb0\x6a\x91\xfb\xe2\x82\xfe\x79\x5e\xcf\x8b\xa2\xfe\xb0\x0f\xcc\x7e\xda\x27\x8c\xb9\xfc\xe6\x81\x1d\x04\xaf\x52\xd9\x36\xd8\xba\xaa\x3f\xee\x88\x6a\x7e\xf5\x08\x21\xee\x6b\xfd\x80\x6a\xc7\x35\x28\xd2\x81\xb2\x3e\x30\x5f\x4a\x4c\xa6\x9f\x8b\xaa\xde\xf3\xea\xf5\x73\x00\x88\xfd\x50\x90\x08\xdf\x66\x9a\x1d\x99\xc3\xad\xb3\xc0\xc2\xd0\x50\x5b\x1e\x4c\x8d\xeb\x46\x3e\x10\x18\x0b\x15\xee\x9e\xed\xdd\xdd\xce\x91\x71\x03\x8b\x84\xc2\x5e\x7d\x4c\x06\x15\xe7\x2f\x43\x04\xe4\xf0\x0a\x31\x83\x00\x99\x9f\x65\xf1\x19\x7e\x65\xf0\x0a\x63\x66\x3c\x8b\x7f\xc3\x88\xdc\x27\x9b\x1e\x5e\x25\xf1\x0c\x60\xf7\xb5\x6b\x5f\x00\x96\xf8\x3e\x5a\x61\x0d\xb5\x7c\x79\xe2\xa9\xc2\x80\xd3\x48\xa4\x5c\xbb\x55\x9a\x84\x0a\x75\x3d\x0e\x5c\x29\x24\x22\x9e\x34\x9f\x2c\x49\x8c\x04\x8c\x2d\xe3\x7f\x47\x40\xd5\xd4\xb9\xc7\x12\xa9\x90\x57\x75\xb3\x7e\x3c\xcc\xd7\x2e\xf3\xce\x78\x22\xf0\xf4\x38\x97\x45\xa1\xf7\xd7\x33\x1c\x0c\x83\x87\x1b\x17\x7e\x80\xf4\x9e\xed\x71\xf6\x53\x62\xf1\xf9\xc6\x01\x67\x92\x08\xb4\xe4\x07\x97\x34\x32\xbd\x16\x5d\x57\xe7\xf0\xce\x25\x35\x5d\x22\x07\x38\xa5\xb5\x91\x6e\x9d\x52\x9b\x07\x26\x13\x8e\x13\x8d\x25\xd8\xa4\x79\x7a\xe2\xd9\x0f\x48\x47\xd7\x53\x7e\x88\xcd\x9a\xd6\x7b\xf8\x98\x69\x12\x98\x0a\x3c\x65\x71\x49\x03\xd5\x06\x60\xc0\x41\x87\x1d\x3b\x67\x63\x82\x3a\x5e\x9b\x66\x58\x23\xd9\xeb\x9f\xdb\x6f\x87\xf9\x6a\x7f\xd8\xac\x1f\x57\x87\xe5\x76\xf1\x6d\xb3\x7a\xdc\x1f\x76\x5f\x67\xa1\x47\xdb\xb9\x5a\x20\x6e\xcf\x9c\x64\xe8\x1b\x7e\xa8\x37\x69\x3f\xa2\x3d\x03\x68\xf9\xb1\x5a\xfd\xbe\x3b\x50\xe6\x2e\xa5\x63\xc3\x28\x83\xb5\xec\x87\xe2\xd8\xf3\xb7\xfa\xeb\x2d\x22\x89\xb4\x6d\x3e\xc6\x4f\xc0\x2e\xae\x5b\xac\x1e\x44\x44\x73\xf4\x81\xec\x41\x9a\xd5\xe9\x09\x33\x1f\xa8\x9f\x3b\x8d\x5a\xfc\xd4\xf0\x44\x9e\x88\x91\x99\x67\x9f\xf2\xfc\xef\x54\x70\xb3\xd3\x10\x83\xf6\x59\xf8\x1e\x79\xd2\x04\xdb\x7f\x5d\xca\x6b\x8b\xbd\xb4\x63\x94\x9b\x24\xe3\x7a\xb1\x3d\x3c\xad\x9e\x17\xab\xc7\xfd\xec\x7e\x75\x70\x79\xb8\xc8\xe7\xcc\x89\x9d\xb6\xb8\x0c\x14\x8a\xe0\xb7\x87\x70\xe4\x8b\xc0\xb3\x79\xd8\xf9\xe5\xea\x78\xa9\xfe\xee\x4b\xab\x7f\x6a\xcf\xa2\x80\x52\xf4\xb5\x77\x8b\xd9\xf3\x6c\xde\x87\xdf\x42\x14\x04\x02\xf1\xb0\x3b\xc8\x32\xd3\xb4\xf8\x11\x7e\xe5\xf3\xa7\x18\x30\x42\x83\x4e\xda\xbc\xbd\x3c\xa3\xf6\x48\x44\xce\xbd\xe6\x5b\x26\xa1\xfd\x6e\x7a\x62\x54\xe4\x14\x4a\x3a\xba\x8b\x44\x81\x29\x4e\x95\x3c\xad\xb0\x08\xda\x1c\x3b\x23\x68\xec\x38\x69\x19\x45\x52\x63\x62\xe2\x99\x6b\x9d\x81\xec\x4a\xa7\x51\x4c\x81\xa0\x53\x93\x15\x45\xf9\x50\x1c\x0d\xce\x74\xf8\xe9\x38\xa0\xd8\xa2\x5b\xc9\x92\x9f\x7b\x0d\xc7\x38\xa2\x0d\xb3\x85\x01\x50\x19\xfb\xd0\x0e\x1a\xd0\x41\x13\xd3\x3a\x45\x97\x75\xbe\xe1\x3f\x57\x3f\xcf\xa6\x54\x32\xfa\x1a\x61\xe8\xcf\x67\xd6\x01\x51\xb8\x4d\x7a\x6e\x48\x94\x78\x11\x62\x9d\xef\x57\xdb\x4e\x5d\x01\xa2\x24\x30\xe6\x19\x5b\x74\xab\x56\xdc\xd9\x8d\x26\x82\xf4\x74\xae\x6a\xfe\x6a\x74\x64\x27\xd3\xbb\x51\xc2\x15\x5a\x9f\x63\xfa\x36\x19\x38\xba\x69\xca\x43\x46\x06\x04\xfa\x56\x97\x93\xe2\x35\x9f\xa4\x54\xb1\xe8\x53\x88\x38\x61\x98\x89\x3b\x38\x50\xcb\xfe\x08\x3b\xa8\x1f\xd2\xb7\xf6\x4e\x39\x15\x08\x01\xb5\x94\x96\xe3\x73\x6a\x78\x07\x9c\x11\xc4\xd2\x9a\x22\xe5\x94\xd0\x32\x44\x3c\x09\x30\x35\xbb\xc3\xf4\xd5\xb5\x06\x9f\xf6\xd0\x3d\x2e\xa2\x8e\x38\x8f\x50\xd4\xe7\xe9\x8f\xcd\xe2\x5f\x96\xd7\x22\x2e\x98\xd3\x55\x3b\x94\x56\x73\xb4\xff\xaa\x04\x4f\x70\xcd\x1c\xd2\x3c\xad\xe7\x5c\x1d\xe1\xdf\xb1\x01\x40\x24\x29\x97\x86\xda\x80\x97\x63\x34\x5e\x24\xed\x69\xea\xd2\x84\xc8\x73\x7a\x2b\x55\x0a\x91\xe4\x0c\xa1\x8e\x88\xb9\x45\x43\x32\xf4\xc1\x9b\x09\x58\x12\x3a\x81\x6a\xd6\x6d\x51\xb5\x8b\x5a\x2a\x21\x2c\x33\x1c\x96\x30\x9e\x8b\x62\x94\xda\x8f\x94\x6f\x1a\x12\x67\xdf\x37\x4b\xd3\xaf\xf9\x64\xde\x99\xbb\x06\x50\x1f\xb1\x02\xdf\x72\x97\x48\xfa\x3c\x49\x14\x41\xe8\x21\x55\xa8\xfd\xeb\xbe\xb0\x10\xae\xe1\x2c\xcd\x00\x21\x06\xcd\xbe\x7f\xba\x64\xd5\xa0\x6c\x10\x69\x49\x89\xf1\xe0\xe5\x5d\x51\x76\xcc\xcd\x10\x13\x9f\x63\xad\x2c\x2f\xb6\x7a\x07\xbc\x45\xed\xc5\x84\x79\x91\x8d\x05\x7b\xc5\xeb\xee\x3d\xc6\x24\x01\x84\xef\xae\xf6\x5f\x0f\xcb\xd5\x62\xbd\x99\x3d\xec\x06\x9c\xd4\x10\x7b\xbe\xc2\x1e\x13\xae\xd4\xfe\x52\x96\x26\xdf\x6d\xbc\x04\xd7\xda\x0e\xb1\xc7\x22\xcc\x22\xfe\x11\xcc\xfb\xf7\x1c\x7b\x31\xa0\x17\xb5\x4b\x9b\x9f\xbb\x68\xd6\xb2\x63\xbe\x99\x74\x94\x62\x0a\x02\xc3\xb5\x54\x16\x41\xdf\xdc\xc4\x3e\x31\xca\x14\x07\xb3\x23\x26\x3c\x9b\x38\x08\x95\xd7\xa7\x6c\xed\xf3\x46\x41\x1c\x42\x8c\x41\xdb\x66\xf6\x87\xd5\x97\xdf\xcd\x1e\x56\xed\xa8\x16\xc8\xe3\xf8\x57\x51\xfc\x95\xe6\xae\xcb\x07\x62\x46\x38\xb3\x39\xf8\xdd\x4b\x7a\x5e\xab\xca\xc1\x4f\xdc\x84\x84\x1b\x33\x88\x8d\xdf\xf6\x8f\x11\xf5\xb0\xbc\xaf\x78\x61\xf1\x7c\xa3\x95\x1e\x37\xc7\x62\x8f\xdf\x16\x21\xaa\xe3\xd8\x35\x8e\x22\x23\xdd\xfc\x9e\x7e\x48\x14\x34\x8c\x84\xdc\xe7\x34\xa3\x3d\x76\xbc\x1f\xe9\x3f\xbc\x54\xcf\x4f\xa3\xab\xc7\x24\x90\x49\x2b\x57\x0c\xe5\x2d\x81\x31\xc4\x71\x6c\x50\x35\xe7\xa2\x1e\xf7\x97\x40\x1c\xf3\x44\x42\xcb\xd1\x63\x5b\x80\xdd\x23\x88\x85\x17\xd8\x2c\x86\x83\x34\x0e\x3f\x9d\x70\x8a\x08\x2f\x27\x50\x58\xd7\x37\xf8\xe9\xd8\x4d\x15\x21\x3a\x82\xe2\xd2\x44\x43\xee\x1b\x12\x19\x63\xd7\xae\xe4\x99\xfc\x1d\xae\xd5\xb3\x95\x28\x9a\x3e\x6f\x63\x2e\x89\x23\x29\x9a\x19\x5e\x98\xe1\x4f\xe5\x90\x98\xd8\x2a\x7d\x03\x93\xeb\xfe\x60\x89\x8a\x50\x30\xe2\xa0\x07\xf2\x15\xe5\x77\x37\xc8\x94\x92\x5d\x31\x91\x82\x91\xc6\xf0\x23\x91\x87\xbd\x55\x69\xf5\xf5\xee\x4b\xfb\x37\x83\xba\x96\x45\x5e\x5d\xb2\x9a\xe7\x75\xd5\x83\xb7\xb9\x49\x02\xb0\xcc\x24\x0a\xb1\xe1\xaf\x50\xa1\xf6\xbd\xe5\x1c\x19\x1f\x71\xc3\x6a\x13\x25\xc3\x13\x25\x16\x92\xa3\x09\xe2\x59\x86\xd5\xea\x05\xcf\xe7\xf0\xcd\xd2\x78\xbb\xef\x53\xc4\xc8\x34\x1d\x50\x1e\xf6\xb1\x58\x58\x56\xca\x6e\x3c\x61\xaa\x55\x6c\x6c\xc2\x18\x14\xab\x9d\xd8\x8c\xca\x4b\x50\x86\xd5\x68\x65\x95\xc5\x69\x07\x6f\x50\xf2\x6c\x9c\x62\x6b\x4d\x88\xf2\x63\x8c\xf7\x6d\x01\xba\xe5\xf0\x75\xc3\x91\x11\x18\x2d\x0e\x19\x17\x8d\x35\xa9\x8b\xd1\x82\x52\xd2\x37\x05\xbb\xed\x7e\xf6\x60\x80\x88\x3b\xf7\x69\x84\x80\x22\xd3\x32\x7f\xef\x98\x14\xdd\x20\x35\x99\x9f\x1d\x4f\xf3\x7a\x56\xe6\xc5\x25\x53\xff\xc2\xa8\xc7\x10\x7a\x06\xa2\x70\x29\x73\x50\xb8\x0e\x9a\x28\xa4\xef\x42\xc5\x90\x84\xaa\x83\x05\x1a\x3e\xba\x8f\xf6\xf2\x7f\x5d\x65\xd7\x45\xaa\xf1\x7f\x3d\x1a\xdb\x3f\x0e\x9f\x2e\x08\x23\xfa\x7f\xe2\xaf\xb0\x93\x2f\x45\x91\x0d\xcc\xae\xd6\x14\x23\x8c\x7d\x2a\xf7\x5c\xee\x0b\x98\xa9\xbf\x2e\xd8\xe7\x53\x7c\xa8\x2f\x3b\x9d\xf8\x4b\x08\x25\x18\x32\xd8\x44\x47\xe7\xd5\xba\x71\x26\x91\xe8\xb2\x71\xeb\x9f\xca\xab\xac\x9d\xd2\x36\x24\x24\x31\x1d\x80\x58\x84\x73\x0a\x2c\x83\xdf\x91\x10\xc1\x0d\x5a\xa4\x38\x7f\x3b\x9b\x38\x64\xc2\xd3\xf5\x12\x7b\x32\x27\x1e\x65\xd8\x7f\xe6\x6a\x21\xef\x1f\xfe\x9a\x4f\xbd\x90\xc4\x63\x0a\x3b\xf1\x52\x9b\x6c\xe8\x8c\xc7\xf0\xfe\x3c\x08\x84\xdf\x2a\x63\xf2\x21\x36\xbb\xeb\xa1\x81\x84\xfa\x11\x8d\x1d\x27\x1f\xcf\x36\xc8\x16\xf3\x71\x21\x65\x78\x37\x54\x49\xe4\xc1\xcb\xe1\x7d\x9e\xaa\xa1\x33\x92\xf8\x82\x40\xd0\x82\x86\x66\xae\x6c\x36\x05\x58\xb5\x9f\x08\xa9\x1f\xd8\x1f\x67\x04\xa7\x5c\x4f\xb8\x6d\x14\xfb\xe0\x53\x9c\x63\x1d\x2b\xad\xb6\xf9\xa2\xe4\x1a\x09\x3c\x2e\x13\x99\xd2\x24\x14\x06\xac\xd1\xc9\xbe\xcd\xaf\x33\xe3\x7d\x4d\x3a\xb3\x09\x93\xb1\x21\xff\x84\xda\x09\xa9\x1c\x4e\x53\x85\xb2\x84\x59\xee\x32\xac\x37\x8e\x45\x62\x20\x89\x28\x09\x5b\xc6\xdc\x43\x51\x2a\x28\x77\x2f\x00\x63\xb9\xd0\x76\xb6\x46\x8b\xbf\x81\xfc\x42\xbc\x0f\x7e\x76\xa4\x99\x01\x92\x21\x93\xfc\xbe\x31\xe2\x9f\x67\xef\x92\x98\x52\x84\xe2\x6c\xf8\x31\x95\x1e\x99\xae\x19\x24\x89\x17\x22\xae\xf7\x7c\x78\xef\xc3\x4c\x13\xee\x0b\x23\xc3\x76\x06\x99\xb6\x65\xa6\x84\x33\x6e\xa9\xf8\xeb\xed\xad\x81\x18\x5e\x9a\x03\x43\xdf\xe1\xe9\x85\x97\x27\xfe\x23\xed\xae\x0d\x89\x67\x41\x69\xb3\xe7\x8f\x0e\xc2\x84\x6b\x43\x6a\x96\x56\x6e\x5d\x8c\xdb\x73\xfb\x0c\x81\xed\xd3\x14\x81\x8f\x3d\x60\x3d\x30\xd1\xc9\x41\xb8\x86\x5f\x20\xfd\xc4\x38\x16\x35\x9c\xf7\xef\xc5\x88\x7c\x06\x12\x60\x11\xb6\x56\xe9\xa2\x6c\x62\x2f\x8d\x1c\x6f\x55\x2a\xef\x00\x7a\x19\xb8\x04\x98\x71\xd4\x0d\x05\x77\x73\x81\x35\x92\x61\x1e\x61\xd4\xf0\x93\x68\x1a\x28\x89\x5e\x66\x06\x79\xfd\x58\xd4\xbc\xbc\xfe\x5a\xdb\x71\x74\x0d\x41\xcc\xe9\x61\x4f\x87\xc6\xd0\x21\x79\xe4\x67\x9b\x86\x13\x1a\xa8\xc4\x2d\x48\xb4\x8b\x2d\xe7\x0b\x70\x12\x33\xf3\xc4\xd0\xc3\x59\xf2\x34\xbb\xde\x6a\x3d\x02\xf7\x08\xb7\xc4\x02\x25\x62\x50\xd3\xfc\x78\x5f\xb4\x2b\x83\x7b\xa1\x71\xad\x97\xbc\x7c\x2d\x21\xcf\xb8\xa5\xe1\x77\xc3\x4c\x22\x0a\x18\x72\x85\xe2\x01\xf6\x01\xb9\xd1\x24\xc6\x65\xf5\x50\x1c\xe7\xa9\x32\x20\x2c\x18\x59\x18\x4e\xa9\x30\xde\x89\x2c\x0e\x55\x47\xa4\x01\x9c\xc6\x09\xb2\x04\x21\x1d\xc7\x7a\xec\xc1\x71\x0a\x0a\xa9\xb1\x4c\xfe\x4a\x3d\x59\xae\x27\x17\x13\xf3\x40\x18\x35\x1b\x47\xbb\x54\xd5\x56\xd7\xc0\xea\x7c\xdd\x64\x68\xa7\x42\x76\x1e\x12\x1f\x0f\xa0\x83\x95\x59\xf8\xcc\xf4\xf1\x50\x18\x47\x0b\x41\xda\x02\xb2\x9e\x2c\x84\x9b\xa1\x98\x11\x01\x78\x49\x75\x7d\x28\x6f\x50\x30\xdd\xb5\x98\xef\x23\xc1\x57\xdd\x95\x8c\xec\x0a\xdd\xb8\x07\xc4\x42\xc0\xa8\xdf\xde\xcc\xba\x9a\xc0\xdc\x72\x16\xb5\x32\x0b\x5f\xaf\xaa\x2c\xd6\x37\x42\x3d\x76\x62\x14\x86\xa1\x18\x20\x3e\x70\x3d\xf0\x32\xe5\x98\xd7\x70\x0e\x0b\x8f\x3d\x2e\xbc\x1e\x16\x6a\x51\xe4\x35\x54\xf5\x5d\x51\x76\x95\xe3\x9d\x7c\x81\x13\x1f\xa0\x91\x46\xcf\xd9\x5d\x2c\x62\xc2\x72\x39\x1b\x58\xc2\xf0\x29\x24\x81\x0f\x36\x09\x6b\x9c\x9b\x5c\xa7\x0e\xf2\xc5\x93\x88\xb8\x0e\x8e\xcd\x75\x9f\xca\x57\x40\x32\xeb\x2f\x83\x5c\xfb\xe8\x7a\x09\xc5\xc3\xe3\x85\x57\xeb\x3c\xad\x37\xbc\xac\x3b\x33\xc8\x13\x11\x61\xbc\xb1\x5e\x6c\x0f\xab\xed\xee\x30\x5b\x3f\x2f\x9f\xb7\x4f\xed\xb0\xa2\xb6\xef\xb8\x92\x97\x51\xdd\x78\x7a\x5f\x23\xd0\xd7\xd2\xb4\x7d\xe7\xb7\x27\xb2\x9d\xc5\x43\xa2\x82\x0e\xdc\xff\x84\x72\xdb\x56\xbc\xc8\xc8\x65\x3b\x23\xcb\x39\x50\xc4\xb3\x9d\x78\x55\x99\x9e\xbb\x7e\xa7\xbb\xc1\x9c\xdc\x15\xe5\x7d\x91\x29\xcc\x77\xf6\xc5\x89\xad\x87\xe7\xae\xa4\x8d\x24\xd7\x2c\x2f\xf2\xeb\xa9\xb8\x38\x2a\xf7\x0f\xd6\xb6\x20\x89\xb2\x2e\xc6\xe1\xdc\x61\xce\x7e\x95\x77\xe9\xb9\x93\xee\x42\x01\x60\x72\xe7\xfb\x76\xbb\xdc\x6e\xdd\xef\x92\x94\x43\x27\xa9\x72\x38\xdb\xf4\xd4\x64\xbc\x39\xca\x82\xdd\x04\x1f\xed\xe2\x92\x32\x42\x42\x9f\xe6\xd0\xb0\x2a\x8f\x9b\x34\x6f\x9c\x1c\x3b\x41\x51\x69\x61\x7d\xf5\xe1\x5c\xcb\x83\x98\xca\x74\x71\x15\x30\x2c\x8a\x9c\x2f\xf5\xbc\x46\x02\xca\x5d\xe7\xfe\x7f\x64\x3f\x3e\x7e\x20\x1f\x72\x23\x03\x57\x2a\x41\x83\xa9\x8a\x9c\xd7\x30\xab\x9a\xef\x42\xea\xee\xea\x72\x1a\x42\x47\x9d\x95\x03\xdf\x30\xec\xd9\x3b\xdf\x15\x59\x36\xba\x7b\x88\x34\xa6\x08\xea\x97\xb4\x54\x68\x9f\x2d\x39\xb1\x7b\x08\x9a\x08\xac\xbf\x72\x75\x9a\x7d\xe8\x62\x72\xed\x19\xbe\x9d\x5e\x0b\xce\xa8\xcb\x73\xb4\x60\x74\x12\xa2\x7c\x6b\x0e\xa0\xf6\xc5\x3d\xd4\x77\x25\xb4\xb6\x5d\x0b\x2f\x56\x5d\x53\xcd\xf0\x96\x9b\xb3\xd0\xe1\xd4\x76\x45\x76\xb9\x49\xd8\xb8\x17\x2c\x3c\xa2\xd1\xe5\x38\x97\xcd\xe9\xdc\xea\xd4\x80\xa0\x5e\x80\xce\x97\x4b\xf7\xfe\x2a\xec\x70\x1f\xa3\x1a\x33\x6b\xc8\xc8\x06\x6a\xc5\xcb\x91\x77\x21\x68\x10\x25\x36\x7f\xf7\xfb\x55\x0e\x10\x74\x6e\x46\xe4\xa3\x4b\xe7\xb0\x05\x8b\xb2\xf3\x2a\x84\x1f\x1a\xff\xab\xeb\xd0\x9c\xec\x96\x11\x01\x89\xb1\xe1\xb5\x89\x84\x5d\x44\x23\x02\xcf\x8f\xad\xe7\xdb\x58\xd6\x07\xd0\xf5\x13\x57\xed\x68\xa0\x48\x4b\xcf\xb6\x3b\x67\x69\xe3\xb7\x8c\xee\x3e\xf4\x34\xb1\x80\x3a\xa3\x24\xfb\x01\xed\x05\x08\x46\x58\xe8\x14\xc6\xca\xe2\x32\x42\x0c\x09\xa6\x84\xe1\xb2\x4e\x4f\x70\x28\xb4\x01\x07\x1c\xaa\x77\x7e\x3e\x40\x5b\x4e\x10\x51\xe2\xa1\x7f\x82\x8c\x72\x3d\xe7\x4a\x44\x42\xc6\x2d\xfc\xab\xed\xbb\x2a\x8b\xd3\x87\x35\x91\x51\xbc\x2e\x22\x08\x7c\xd9\x36\x66\x6e\xf3\x45\x71\x3a\x67\x60\x4b\xc7\x0e\x25\x2f\xe2\xd8\x68\xc7\x54\x50\xf7\x9b\xa2\x3f\xf8\xcd\x31\x00\x72\x3e\xa9\x8b\xb1\xa6\xeb\x7c\x93\xe6\x97\xba\x3d\xf9\x44\x12\x2b\xf4\xbd\x2f\xb9\x70\x3c\x6d\x20\x12\x1e\x6a\xbb\x58\xef\xf9\x09\xac\x9d\xc1\x9a\xfe\x18\x75\x21\xb8\x67\x28\xf4\x36\xb3\x3f\x0e\x0f\xdb\xd9\xe3\xa0\xad\x1f\x04\xf7\x89\xd1\x34\x97\x2f\xa0\x2e\x19\x4c\xf1\x69\x0f\x32\x6e\x37\x5d\x9c\x82\x87\x04\x2d\xda\x66\x3b\xef\x68\x85\x47\x2b\x94\x4b\xc3\xee\xfe\xf0\xbc\x78\x28\xf2\xe3\x1e\xca\xd3\x57\xd3\x0c\x76\xa3\x53\x3c\xfa\x20\x84\x78\x7a\xde\x3f\xcc\xbe\xb9\x7b\x16\xb1\x91\x2a\x6c\x5c\x00\xcb\xcd\xff\x0c\x58\x19\x5d\xe5\xe8\x62\x3f\xc3\x5b\x5a\xf5\xda\xee\x84\x10\x12\x9a\xab\x20\x25\xc3\x2c\x2d\x55\x59\x4c\xeb\x70\x83\x90\x9e\x29\xc8\x29\x78\xeb\xe7\x35\x84\x4c\xb8\xeb\x86\x5b\x42\xd6\xf6\xc5\x08\x09\x06\x9e\xd7\x35\x0a\x3b\x77\x50\x28\xdf\x13\x76\xc1\x38\x82\xc8\x7e\x26\x41\x00\x31\x61\xc3\xdf\x97\xa2\xcd\xbf\x0a\xed\x9b\x20\xe0\x94\xe6\xa8\x20\xd7\xfe\x9d\x33\x0c\xaf\x4e\x45\x5e\xbf\x78\xb1\xb4\xca\x09\x79\xaf\x83\x52\x12\xea\x21\xb3\xe4\x57\xe0\x59\xfd\xb2\xe4\x35\xc7\x56\x9e\xcf\x2a\x9d\x92\xe8\xc8\x0f\x86\x9d\x77\x83\x9a\x89\x9d\xe6\x11\xe9\x59\xaf\x02\x75\xe0\x3f\x8d\x18\xa5\xe7\x33\x84\xf2\xee\x5e\x8a\x72\x42\xee\x1d\xa4\x17\x71\x43\xb8\xf3\x52\xa6\xd5\x1c\xb2\xec\xd7\x25\x1a\xe9\xfb\x3a\xb0\x8e\xd9\x13\xaf\x8d\xcc\xc2\x08\xbf\xfc\xdf\x70\xb4\x38\xa5\xcf\x7c\xb4\xfa\xdf\x8b\xe6\xf1\x2f\x5e\x9a\xd0\x34\x6f\x1d\x7e\xe9\x33\x69\x39\x54\xf4\x25\x57\x4f\xc5\x7b\x63\x83\xbf\x39\x9b\x2e\x03\xee\x49\xe9\x88\x22\x9e\x4d\xdd\xb2\x3b\xa0\x64\xc0\x8d\x90\xde\x7b\x5b\xe6\xcd\x7b\x88\x6d\xc9\x7c\x89\x1c\x4d\x8f\xfc\x54\xf4\xb3\x55\x92\xc5\x31\xed\x33\xb7\xdc\x5d\x1c\x45\x2a\xc8\x88\x32\x22\x2c\x25\xe2\xe1\x54\xe4\x95\x23\x59\xf7\xd8\xa0\x1d\x47\x46\x91\x69\xd8\x42\x69\xd2\xc3\x6c\xf9\x7d\xbd\x6b\x6b\x18\x32\x12\x86\x35\xd0\x39\x58\x63\xa7\xe5\x32\x01\x0b\x91\xb1\xa2\x88\x90\x55\x80\x38\xaf\xd1\xfe\x1f\x4c\x4d\x42\xce\x6d\xd8\x61\x55\x94\x9a\xe3\x01\xb1\x22\xf2\xb5\x09\xa8\x26\x04\x49\x40\x26\xc2\x80\x3e\x0f\xf0\x13\xe4\xa5\x86\x0f\xb1\x69\x32\x51\x3a\x4e\x86\x4d\xf0\x50\x23\x05\xa4\xa9\xa1\x8e\xba\x07\xa7\x16\x36\xf7\x28\x6e\xcc\x01\xfe\xab\xcb\x37\xba\x59\x11\x20\xe3\x59\xf3\x6a\xa7\xd4\x51\xdc\x34\xed\x63\x6b\x13\x4a\xdd\x1a\xa0\xd2\x17\x93\xae\xb3\xd4\xac\xd8\x6b\xe7\x66\x0b\xc2\xb0\xa7\xe6\x94\xe6\x03\x88\x97\x94\xbe\x0f\x91\x13\x2b\x31\xe1\xc3\x2f\x9a\xb0\xa5\xb4\x2c\x1b\xcd\x09\x6c\x84\x1f\x1f\xf9\x09\x7a\xd0\x2c\xa9\x08\x45\x6f\xcb\x3e\x54\x57\x66\x1d\x3c\x0c\x45\x0c\x47\xd2\xc1\x96\x5f\x30\x21\xde\x76\x95\x4e\xff\x66\x95\x28\x0c\x11\x0e\x69\xf5\x88\x60\xe1\x47\x78\x1f\x88\x63\x82\x54\x92\x21\xa4\x6f\xbf\x9a\xb9\x10\x51\x91\x24\x54\xac\xd5\x46\x40\xa2\xfd\xfe\xad\x28\xc2\x7d\x6e\x69\x98\xbf\x16\xc5\xab\x43\x57\x8c\xcf\x01\x37\x5b\x48\x3c\xf5\x37\x3c\x3f\xf2\x5e\x1a\x40\x11\x69\x54\x55\xab\x8b\xa8\x64\x99\x9e\x87\x6c\xac\xa0\x88\xf2\x1d\x0a\xc3\xa5\x59\x7e\xe5\x26\x4f\xbe\x00\xe5\x79\x06\xa6\xc5\x95\xda\xc0\xa9\x28\xaf\x5f\x6e\xf4\x24\x40\x79\xdc\xec\xda\x73\x51\xfc\xe5\x4c\xb9\xa2\x89\x91\x38\x7f\x28\x8e\x77\xd8\x80\xfc\xb1\xaf\xab\x7c\x2a\x88\x74\x3d\x94\xf9\x58\x97\x1a\x94\x9f\x84\xc8\xbb\x2a\x2e\xd7\x07\x3e\x76\xb2\x94\xaf\x8d\x21\x4a\x1d\x32\x73\x76\xa9\x5f\x8a\x32\xfd\x67\x9c\xdf\x55\x41\x10\x08\xed\xda\x27\x9a\x53\x69\xb2\x79\xe2\xc3\x54\x9c\x0a\x24\x61\x7d\x14\xf1\xbe\x98\xf4\x26\x55\xa0\x03\x2b\x61\x97\x65\x06\x69\x6c\x07\x58\x98\x08\x66\x6b\x08\x9b\xd7\xda\x48\xfa\xd8\xb1\x88\xea\x38\x6a\x99\xa8\xdb\xbf\xc6\xa0\xac\xad\x59\x9f\x8c\xf2\xd4\x50\xfe\xde\xed\x3b\x15\x29\x82\x52\x64\x25\x34\xeb\x7b\x7e\xdd\xe2\x17\x0f\x6f\x2c\x26\x1c\x41\x90\x56\xab\xcb\xb0\xa0\x8f\x49\x44\xbb\xe8\xb5\xab\x54\x4c\xfc\x97\xbb\x64\xc0\x23\x2b\xa3\x3b\x46\x2e\x7f\xb0\xa6\x12\xca\x22\xd2\x41\xc7\xcc\x4d\xa4\xe3\xa2\xbf\x4a\xb4\xe1\x80\x3e\x21\x6a\xad\x78\x1c\xd3\x89\x82\xe2\x01\xc7\x12\xf9\x63\xf1\x96\xa2\x84\xe1\x61\xbf\xda\x39\xe7\x4e\x71\x65\x7e\xeb\x2e\xcd\x8f\x97\x0c\xb5\x1c\xf6\x50\xd5\x0e\xbf\xa5\x84\x00\x4c\x75\x98\xe2\xc2\x14\x3a\x4f\x49\xe2\x71\x70\x55\x4d\x34\xa4\x63\x58\xb6\x92\x54\x82\xd7\x32\x5a\x75\xc5\xa6\xe1\x9d\xca\x88\x3a\x7d\x3a\xc7\xbe\x3e\xbe\x8e\x50\x09\x82\x10\x10\x90\x7b\x98\x7f\xfb\xf3\xb0\xbd\xbb\x5b\x3d\x1f\x66\x8b\xc5\xea\x69\xbf\x72\xd0\x40\xe4\xc6\x26\x98\x4e\x75\x58\x88\x49\xfd\x4b\x40\x62\x5c\xd6\x67\x3f\x1b\x59\x7f\xa5\x14\x41\xd8\x8b\x70\xb0\x98\xb6\x3c\x38\xbc\x35\x4d\x29\x35\xca\x80\xf9\xb1\xf9\xb3\xa9\x76\xb4\xc2\x8d\xf6\xc6\x80\xd8\xb4\xec\x11\xea\x47\x4b\xc5\xf4\xbd\xe8\x9c\x79\x20\x94\x23\x52\x7d\xb7\xbd\xdb\x2f\x66\x4f\x87\xd5\xfe\xeb\xe1\x61\xbd\x59\xef\xdb\x09\x22\x40\x72\xa6\xc5\xf3\x7e\xb7\x9f\x3d\x1c\x36\xeb\xc7\x1b\x4e\x02\xf0\x7c\xc0\xca\x4b\x8f\xa2\xfd\xdf\xd6\x84\x3e\x33\x74\x40\x03\xc0\x2e\x85\x23\x3f\x89\x0c\x4a\x87\x67\x03\xca\x0c\xa4\xa1\xd9\xca\x37\xef\x15\x28\x4f\xa4\x51\xad\x9b\x46\xed\x43\x40\x3c\x3c\xf4\x0d\x61\x5a\xcb\xbc\x0c\x10\x26\xae\x31\x4a\x75\xfd\xa4\x1f\xd9\xe3\x1b\xea\x1e\x7b\x11\x26\x08\xc6\x7b\x33\x14\x73\xaf\x76\x97\x3c\xbf\x8e\x3a\x1f\x80\x89\xb0\x27\xcf\xf7\xc0\xad\xd6\x70\xea\x28\x04\x01\x18\x98\x8e\x6f\xee\x20\xc1\x56\xfe\xf0\xb1\xcd\x82\x01\xd3\x26\x8e\xda\xad\x7e\x5f\x6d\xba\x3f\x26\x2e\x24\x34\x4d\xf7\x5b\xdd\x5c\xfe\xae\xe5\x32\x05\x88\x7c\xe6\x84\x42\xf7\x4f\xfb\xc9\xdf\xf8\x01\x53\x00\x44\x81\x69\xeb\xe8\x6c\x2d\x36\x70\xe9\x9e\x50\xe4\xd0\xea\x42\x4c\xfc\xd0\xf6\xb6\x05\x67\x4c\xe9\xb9\xdb\x88\x69\x02\xbc\x75\x74\x37\x3c\xbf\x7e\x19\xc5\xb7\x10\x6b\x8e\xe4\x39\x36\x25\x7f\xb0\x08\x85\x83\xe4\xd5\x8b\xe0\xf2\xf5\x80\x91\x77\x17\x6b\x43\xe2\x03\xb2\x4f\xa6\x95\xd1\x6e\x76\x7d\x77\x83\x17\x94\x30\x1d\x58\xd0\x05\x7a\x3d\xca\x74\xdb\xa2\xf6\xc6\x68\x29\x71\xdf\x28\xfd\x66\x45\xf1\x7a\x39\x7f\xab\xa0\x74\xfc\x29\x5f\xd3\x66\x61\x5d\xe7\xd7\x05\x3f\x9d\x79\x7a\xcc\xd7\xcb\xd1\x3b\xe6\x2a\x10\xcc\x85\xdd\xa7\x73\x0d\x07\x8f\x0c\xfc\x0e\xe0\x5a\x21\x58\xb5\xa5\x4f\x6e\x5c\xa0\x99\x7a\x6b\x36\x7e\x0f\x2b\xf2\xc1\xe6\x10\x11\x61\xf6\xfa\xff\x53\xa4\x37\xdc\xa3\x00\x02\x68\x6c\x80\x02\xe7\x02\x9b\x0a\x35\x97\x30\x04\xac\x83\x8c\x75\xac\x5b\x32\x0a\xc7\x21\x3d\xe1\xbc\x02\x04\x9e\x97\x74\x9d\xb0\xd5\x33\x57\xbc\xac\xd6\xaa\x35\x25\x90\x30\xf4\x07\xca\xa2\xe6\x35\x7c\x96\xd6\x07\xe0\x04\x5f\xbd\xb4\xf9\x8a\x59\x5d\x73\xf9\x3a\x2c\x89\x80\xf6\x63\xc3\xc4\xe0\x8a\x5d\x88\x45\xda\xa7\x50\xfe\xef\xa5\xa8\xd3\xae\x07\x05\xb4\xaf\x0c\xbd\x99\x95\x99\x8c\x46\x6f\x42\xb3\x20\x30\x9c\x20\x77\xab\xf5\xe3\xf7\xf5\x72\xf5\xdc\x7e\x54\x38\x4c\x37\x3c\x61\xfa\x6c\x95\xab\x96\x47\x46\x13\x3f\xd2\xaa\xcb\x9c\xa4\xf9\x05\x8b\xef\x5d\xda\x50\x13\x46\x91\x83\xa2\x34\xa7\x75\x9f\x37\x4e\x13\x48\xc0\xc6\xe7\x77\x3c\x93\x45\x7e\xc2\xe6\x98\x67\xf8\xdb\xcd\xa0\x81\x44\x96\x5a\xd7\xf3\x76\x37\x16\x5c\x05\x4d\x93\xd0\xd2\x3e\xae\x17\xab\xc3\xe6\xdb\xc3\x7e\xfd\xf4\xb0\x5e\x3d\x1f\xd6\x8b\x6d\xd0\x5e\x07\xc2\x30\x31\x4d\x97\xaf\x50\x23\xe0\xe8\xd0\x2c\xcf\xae\x8e\xa4\x03\x4a\x5d\x2a\x6b\x90\x04\x1a\x7e\x5b\x20\xc0\xb7\xf2\x93\x75\xca\x33\x4c\x4e\x4c\xfb\xe2\x3a\x0c\x39\x9e\xb1\x39\xbc\x37\xcb\xbb\xdf\x7a\xaf\x43\x50\x2c\xe9\xe1\x8a\x90\xbc\x7d\xa0\x3e\x6a\x27\x32\xee\x27\x5d\x5f\xe5\x26\xcd\xa1\x9c\x0d\x30\x4c\x9a\x49\x8d\x30\x2e\xae\xd4\xbe\xe8\x92\xf9\x53\x1e\x9e\x8e\x42\x85\x28\xcb\xd3\x75\xc1\x4b\xb5\x4c\xdf\x52\x05\x79\xbb\x40\x75\xc4\x03\x8c\x81\x1e\x8a\xe3\x1e\x4e\xe7\x66\x49\xed\x6e\x99\xd5\xc7\xd7\x84\x08\x91\x46\x69\x9e\xe2\x13\xe1\xe7\xf6\x7a\x71\x1c\x61\xd2\xa7\x79\xd2\xa6\x55\xa4\x39\xf4\x9b\x7d\x68\xc2\xd3\xc1\xe3\x8a\x95\x1f\x58\xb6\x09\x23\x3e\xdd\x2f\x0d\xd8\x39\x49\xe0\xe3\x77\x99\x53\x41\x1b\xa3\x67\xeb\xae\xa3\x17\x95\x30\x62\x68\xc5\xd2\x13\xec\xd3\x2c\x7b\x84\x9f\xf5\xae\x6e\x05\xfc\x41\x27\xd2\x74\xc7\x34\x1e\x01\x2c\x1f\xac\xac\x52\x3b\xaa\x04\x62\x88\x2c\x2d\xfb\xb7\xa7\xa7\x87\x3f\x0f\x08\xda\x71\x33\x38\xa3\x81\xe8\xb7\x46\xd9\x1c\xd5\x3d\x3f\x19\x77\x77\xf8\x98\x78\x4c\x70\x1f\x68\x43\xc0\x5a\xf5\xa0\x91\x9a\x0b\x1e\x19\x9d\x2f\x39\xfa\x15\x5c\xf9\x86\x46\xd9\xa2\x3a\xb6\xaf\xfc\x6a\x32\xfd\x5f\xa6\x10\xbe\x5a\x10\xe3\xa9\x23\xeb\x72\xf1\x6a\x49\x50\x86\xd7\x14\x3e\x43\x39\xc8\xb7\x66\x2b\xee\x8b\x01\xc1\x94\x96\xe0\x61\xd2\xaf\xf9\x15\x4d\xac\x39\xb0\xc7\x5a\x51\x8a\x98\x53\x03\x6f\xac\x27\xd9\xb5\x86\x3f\x5b\x29\xc5\x4d\x1d\xff\x1e\x72\xa8\xac\x20\xd5\xad\x47\xaa\x95\x96\xda\x1f\x27\x08\x31\xba\x7c\x2c\x6a\xfb\x5f\xbd\x44\x8d\x06\xea\x23\x99\xda\x57\x5e\xfe\xd5\x8b\x31\x35\x08\xc3\x80\xbf\x81\xea\xe5\xa9\xc0\x86\x3b\x83\xe1\x18\x3c\x03\x50\x21\x82\x0f\x67\x75\xc6\xf3\x3a\x55\x63\xcd\xbe\x81\x65\xd7\xda\x0b\x12\xd1\x6f\xc2\xba\xc8\xd7\xeb\x53\x31\x4a\x90\x69\xcd\x34\xb0\x96\x63\xcf\x66\xce\xef\x5a\xea\x84\xf1\x6c\xc1\xb5\x67\x11\x0e\x98\x8d\x69\x53\xed\x38\x41\x13\x42\x7d\x6c\xac\x38\xbf\xd5\x87\x73\x76\xaa\x0f\x27\xfe\xf3\x90\xe6\x87\x96\xe2\x58\x13\x12\x05\xb8\x1f\x72\xf8\x59\x0f\x4c\x91\x1b\x97\x9e\xa1\xff\x68\x7c\xb5\x6d\x0e\xab\xbc\xbb\xba\x34\x04\xff\x26\x31\xf2\xf7\x85\x97\x8d\x19\x4a\xa1\x9a\xb5\x33\x54\x20\x6c\x5a\xfe\x1f\x78\x2a\x8a\xcc\xb1\x5a\xda\x71\xcf\x13\xf8\x0c\xe1\xa7\xcc\x2e\x0a\x54\xc7\x10\x31\xbc\x09\x2a\x38\x1e\xe2\x05\xc6\xfb\xd5\x13\x94\x66\x7f\xdb\x61\x3f\x10\x18\xf4\xd7\xbd\xfc\xbe\x91\x66\x57\x37\x79\xe6\xfe\x13\xd4\xc4\x07\xd3\xf5\xf3\x6c\x53\x72\xbd\x2a\xc5\x84\xf5\xd3\xc4\xd7\xa1\x0e\x7a\xd9\x25\xd3\x8a\xf9\x3b\x5c\x47\x37\x1c\x28\x85\x54\xc3\xcb\xd9\xd3\x0e\xf7\xbf\xbb\xd5\x40\x0b\x2b\x6d\xd3\x58\x6d\x2b\x8e\x5a\x8e\x3e\x1d\x06\xc6\x1e\xbf\xf0\x52\x2d\xf8\xb9\xcf\xd7\xa1\x09\x8b\xa9\x71\x0f\x0d\x13\x6f\xfb\x67\xe1\x05\x96\x3d\x1c\xca\x7a\xf5\xb7\x17\x59\x26\xa8\xe8\xb7\xc1\xbf\xf6\xe8\x6f\x3e\xe0\x63\x3d\xfc\xf7\xed\x7a\xbb\xfb\x17\x4c\xca\xf6\x63\x91\x47\x70\xeb\x57\x2f\xc5\x3b\x96\x90\x8b\x22\x9b\x22\x61\xd5\x24\xd2\x02\x0d\xc9\xd7\x6f\xbd\x2c\xa8\x26\x31\x35\x58\xed\xd5\xfe\x6b\x13\xdf\xb4\x4f\x26\xf6\x43\x23\x5f\x96\x56\xf5\x2c\xcb\x66\x75\x0d\xb9\xe2\x2d\x35\xab\x26\x31\x8b\x58\xd8\x26\x82\xcb\x22\xef\xab\xc6\x69\x92\x04\x01\x2e\x54\x01\xf5\xf0\xef\x92\xe1\x2e\xcf\x78\x65\x34\x6d\x0e\xda\x23\x5f\x79\xf5\x72\xb0\x3f\xac\x9d\x08\x44\x75\xac\x54\xad\x87\xd2\x0c\x30\x3c\x85\x77\x50\xcf\xd3\x9b\xca\x45\x3b\x29\xc6\xd2\xad\x11\x62\x3f\x43\x59\x1b\xfc\x34\x8a\xec\xb5\xed\x31\x9e\x7b\x8c\x9c\x18\xe5\xc3\xc5\x4b\xf1\x71\x20\xe7\xe6\x86\x04\xd5\xbf\x96\xc5\x19\x06\x8f\x92\x83\x22\xd0\xf6\x05\x23\x45\xfa\xe5\x6a\x08\xce\x87\x2f\x4d\x0a\x86\xcc\xd9\xd8\xf3\x6b\x82\xdd\x96\xdb\xd6\x4e\x51\x42\x52\x1b\xa8\x7f\xa5\xf3\x54\xa9\x6e\x08\x02\xc3\x6d\xa4\xd3\x5c\x8d\x2b\xb1\xc3\x68\xa2\x99\x2b\xb0\xe4\x02\xc7\x63\xb5\x46\x62\x9b\x5d\x66\xad\x5c\xec\xa6\xc4\x44\x3b\x1a\x6e\xe4\xca\x56\x53\x6d\x1f\x9a\x68\x12\xa2\xc7\x59\xbd\x64\x71\x8f\xfe\xc1\x5d\x46\xfb\x81\x0c\xda\xfc\xc3\xf2\x32\xd1\x67\xa5\x89\x8e\x19\x16\x0f\x04\xaf\xeb\x0c\x1a\x8f\x65\xad\x9e\x79\x5b\x09\xd0\x44\xcb\x08\xa3\xdc\x03\xf6\x3f\x5a\xb2\x9d\x35\x76\x32\xb7\x94\x3b\x93\x96\x40\x2b\x2e\x9d\x41\xc7\x14\x0b\x7a\xce\x13\x0f\xdf\x23\x84\x62\x7a\xeb\xcc\xaf\xfb\xc2\x1d\x25\xc3\x29\x1e\x0d\x90\xdf\x4a\x72\xab\x30\xdc\xb8\x1a\xcd\xf9\xb9\xce\xd3\x9a\x67\x46\x53\x78\x97\xfe\xe3\x6e\xdb\xa3\x81\xc0\x2e\x67\x3c\x3f\x9b\x25\xb6\xae\x86\x8d\xd0\xda\xa3\xa1\x81\x51\x08\xae\x8e\x70\x28\xc4\x5f\xed\x40\x14\xa3\x3f\x78\x86\x52\x6e\xf5\x64\xf4\xa0\x3d\x2a\x22\x1a\x8e\xf8\x98\x07\xfe\x8d\xf6\xa8\x4a\xd0\x13\xfc\x59\x94\xf0\xb3\x6a\xff\x0a\x31\x66\x69\x8e\xe9\x1b\x18\x1d\xed\xe1\x6b\xf5\xfc\x80\x13\xe6\x28\xe9\x1e\x8c\x08\x87\x6d\xda\x80\xf6\x2a\x3e\x0b\xf0\x60\x58\xf3\x63\x91\x8f\x38\x48\xb5\x17\x90\x10\x57\x10\x0a\x1f\x2d\x5d\x51\x4e\x7b\x81\xf0\x12\xaf\x6b\x58\xb3\x6b\x75\xab\x77\xe9\x31\xff\x45\x17\xdc\x74\x30\xae\xbd\x40\x82\x1c\xd4\x7a\x36\xfc\xe7\xbe\x78\x9d\x0c\xc4\xb5\x17\x46\xb1\xcb\x04\xe1\xe6\x37\x74\x69\xed\x60\x82\xdd\x6b\x8d\xbb\x9c\x1e\x7b\xb6\xdb\x0b\x63\x6d\x3a\xea\x26\xaa\xb1\x9f\x65\xa9\xb5\x17\x8a\x18\x33\x59\x6b\x59\xb8\xba\x74\xbb\x00\x18\x91\xda\x7a\xf5\x9b\x42\x0d\x85\x24\xfa\xce\x89\xf6\x98\x30\x62\xb5\x87\x33\x97\xaf\xc6\x13\xed\xbb\x9f\xa3\xef\x64\xd2\x20\xf1\x9c\x2b\x63\x04\xa5\x46\x73\x20\x09\x4d\xe1\xe4\xba\xcd\xe7\xf0\xc2\x33\x3d\x5a\x06\x71\x44\x31\x9d\x75\x30\xe6\x76\xf1\xd2\x09\xd8\x4e\x7f\x6d\x1c\x29\x6d\xd3\xad\x26\xad\xee\xf4\x72\x3f\xb8\xcd\x38\xf6\x3c\xed\xe8\xfc\x1a\x5f\x00\x0c\x9d\xb2\x1b\x4e\x0c\xce\xbe\x31\x51\x73\x5e\xf5\x3c\x05\x3b\x21\xf1\xc2\xc0\x68\x98\xd5\x25\x4f\xeb\x5d\xcd\x73\xc5\x4b\x75\x08\xdb\x09\x01\xf3\x2d\x9a\xf9\xa9\x78\x85\x53\x91\x4f\x10\x33\x68\x2f\x09\x3d\xec\xc7\xf9\x8f\xc4\xa2\x6c\xfb\x57\xc0\xfa\x6b\x6a\xc5\x78\x97\xbd\x8d\xd5\x84\x05\x58\xfc\x58\x6f\xf7\x2d\xbc\x73\x1a\xd1\xa5\x3d\x41\xfc\x48\xf6\x8a\x8a\x6d\x27\xc3\x68\x9a\xe7\x41\xdc\xd2\xe0\x3c\x41\xf9\x03\xd2\xa7\xec\x52\xdd\xb6\x42\x6b\x4f\xf8\x1a\x9b\x29\xbb\x04\xd4\x79\x3c\x23\x08\xb1\x3c\xf3\xad\xfa\x40\xc6\x41\x7b\xd2\xf3\x5d\xd3\x0c\x7e\xc7\x73\xef\x07\x4a\xdf\x63\xb6\xfb\xf5\x83\x8a\x85\xf6\x64\xa2\xb1\x8d\x12\x6b\xb0\x4b\xd7\x6a\xaf\x3d\xa9\xa8\x4d\x2c\xc9\x4b\xe3\x6f\xe6\xe3\x0f\x2a\xea\x61\xf6\x1c\xfd\x8b\xc3\x6c\xb9\x7c\x5e\xed\x76\xee\xd3\x2a\x64\x91\x61\x88\xab\x4e\xa9\x5c\xb6\x55\x79\xed\xa9\x98\x5a\xf9\xec\xfa\xc9\xe8\x96\xf6\xf8\xce\x3a\xbd\x87\x09\x80\x9b\xf6\xc0\x17\xd2\x36\x3a\xff\x05\xb2\x1e\x68\x7f\x6b\x0f\x04\xc7\x7a\xd0\xb9\x2c\x4e\xc5\x86\x9f\xbf\x0c\x2d\x0c\xc8\x10\x33\x48\x97\x4a\x3d\x61\x27\xe0\x43\x71\x1c\x3d\x6e\x50\xda\xa4\x72\x9a\xb0\x6d\xad\x1f\x50\x8a\x2d\x9f\x4f\x36\xa8\x6b\x0f\xf3\x93\xff\xe7\xff\xf9\x3f\xdb\xef\xeb\xdd\xf3\x6a\xb7\x7a\xfe\xbe\x5a\x5a\x7a\xd6\xf6\x96\xc0\x28\xec\x9a\xc3\xa6\x79\x35\xb7\x89\x03\xed\x69\xdf\x0f\xc1\x52\x87\x3d\xa4\x7f\x5f\x52\x95\xd6\xc8\x00\xf9\xc1\x8e\xd3\xbe\xc2\xbe\xd6\x0c\x3b\xf6\xb1\x6c\x61\x46\x28\x21\x90\xe8\x01\x92\xbe\xda\x61\x5a\x79\xf8\x43\x29\xa1\x46\xfa\xe8\x74\x45\xd3\x5e\xf7\x8c\x3e\x25\x5c\xe2\x7e\x94\x69\xcd\x15\x64\x83\xae\x37\x4d\x3d\x02\x9e\x69\x05\x6b\x8c\x08\x52\x52\xcb\x76\x2f\x53\x8f\x51\xd2\x91\x40\xed\x8b\x0f\x89\xfd\x27\x21\xa4\xbd\x92\x9f\xa6\x5e\x12\xe1\x7e\x1b\x88\xb8\xfc\xaa\xb4\xd8\xb7\xb6\x94\x86\x1e\x69\x65\x20\x2d\xf8\x7a\xb4\x05\x29\x95\x31\x16\x78\x56\x19\x98\x63\xe0\x46\x76\x62\xfa\x40\xa0\xbe\x67\xfc\x99\xc6\x3a\x66\x45\x3d\x54\xb7\xd2\xd4\x0f\x23\x34\x2d\xef\x13\x0b\x7a\x58\xdf\xd2\xd4\x67\x1e\xeb\x24\x4f\x1a\x3b\xd9\xe7\xae\xb1\x93\x42\x30\x88\x03\x57\x28\x82\xf9\xa5\x4a\x73\x8c\xe1\x9e\xa0\x6c\x45\x47\xba\x0f\x30\x2e\x93\x9e\x6a\xfb\x2d\x90\x58\xd3\x28\xf4\x93\xe6\x8b\x1f\xe6\x0f\x9f\xc4\xd4\x9a\x46\x71\x80\x39\xf6\xea\x9c\xa5\x23\xd8\x42\xcb\x41\x3e\xfc\xf2\x28\xd1\x26\x60\xce\x2b\x28\xd3\x72\x7b\x79\x4b\x55\x51\xa6\xfc\xb1\x58\x70\xc5\xab\xba\x2c\x3e\xb8\xcc\x18\x4a\x39\xbc\xaa\x22\x1e\xb3\xb5\x90\xfb\x92\xcb\x01\x35\x8c\xa6\x31\x8d\xa3\xde\x49\xf7\xd8\x72\x8d\x6a\x1a\xc7\x11\x7a\xcb\x1d\xd2\xf1\xd6\xb1\x1e\xfd\x84\x58\x18\xad\xb6\xf3\xc1\x64\xb0\x2c\x5b\x8e\xe9\xe4\xeb\xf8\xcd\x46\x4f\x3d\x09\x79\xe8\x56\xed\x47\xc4\x4e\x9a\x26\x89\x01\xf6\xfd\x55\xa4\xf9\x53\x1b\x5e\x53\x1e\x33\x44\xed\xd4\xef\xc5\xe8\xb2\x5c\x6b\xd9\x35\xa5\x3f\xc3\xdf\x97\xb4\x6c\xa2\xf8\x53\x0f\x7d\xd4\x91\x78\xda\x0f\x09\x8f\x61\xed\xe6\x7e\xcc\xf3\xa8\xa9\xf0\x45\xd0\x31\x2a\x3d\x17\xc5\xe9\x7f\x2f\xa9\x03\x3a\x69\x2a\x62\x49\x42\x57\x77\xe1\x59\x5a\xa1\xcb\x7f\x00\xad\xc1\x54\x22\xec\x3c\x19\x52\xa3\xe7\x3c\xc2\x19\xf7\xef\x42\x11\x1f\x2b\x9c\xa7\x34\xff\x9f\xcb\xe9\xec\x3e\xaa\x7c\x4f\x8b\xde\x71\xfa\x65\xa8\xde\xec\x66\x85\x0a\xcb\x02\x8d\x67\xba\x83\x4c\x2f\xcb\xe2\xdc\xf7\x50\xa9\x0a\x01\x01\x46\xeb\xc5\xf6\xb0\x7f\x5e\xdf\xdf\xbb\x6c\xb8\xa6\x2a\xa1\x48\x9b\x6c\xa1\x3b\xbb\xc3\xec\x71\x79\x58\x6c\x1f\xf7\xcf\xeb\xf9\xb7\x3d\xfe\x61\x70\x66\x51\x20\x1e\x42\xc0\xb2\x34\x7f\xfd\x32\xb8\x0d\xf0\x0c\xc1\xfa\x72\xfb\xe3\xf1\xf0\x8e\x41\x42\xd5\x7e\xca\x07\x4c\x16\xde\x37\x26\x37\x7f\xb5\x18\x84\x91\xd5\x84\x98\xa0\x77\x7b\x30\xf8\x83\xfa\x19\xde\xe0\xb6\x75\xb1\x77\xd4\x51\x1d\x87\x68\x14\x8e\xdd\x3a\xdf\xa4\x08\xac\x74\xd7\xd4\x09\x47\x2a\xc5\x01\x81\xfe\xa2\xcf\x7c\x54\xbd\xf4\x24\x7b\x86\x0b\x40\x8b\x48\x5a\xd8\xe8\x72\xbd\xfc\x50\xe1\x45\xfb\x84\x30\xee\xb5\x7c\x3e\x18\x60\xaf\xf3\x65\x91\x65\x7c\x74\xa6\xf8\x24\x21\xb8\x7a\xfb\x0d\xa0\xda\xf7\x08\x43\x67\xfc\xa9\xc8\x52\x09\x8e\xc5\x43\xfb\x5e\x20\xd0\x35\x79\x43\x7e\xef\x0f\x91\x1b\xda\xf7\x22\xe1\xc4\xa4\xcc\x51\xb6\x1e\x13\xe2\x69\xdf\x83\xc4\x45\xba\xdb\x4b\x7d\xbe\x20\x98\xb6\xfd\x26\xad\x63\xd6\x07\x6f\x60\x5a\x73\x74\x05\x2a\x08\xb6\x65\x2b\x2b\x8b\xe0\x5e\xaf\x4f\x45\x82\xd4\x87\x8d\x2f\xb0\xce\xdf\x20\xef\x94\x5b\xb4\xef\x0b\x8e\x29\x22\x83\x7e\x43\xff\x7c\x6c\x11\xfc\xd0\x93\x3d\xa0\xcc\x27\x4f\x3a\xa4\xbe\x91\xb1\x2c\x8a\xe3\x50\x3f\x5b\xfb\x21\xd3\x18\x0a\x9c\x79\x29\x21\xbb\xff\x07\x5a\x76\x9d\x6d\xfe\xd0\xca\x63\x69\x3f\x8c\x7c\x66\x0b\x23\x18\x62\xe3\xb9\x30\x38\x99\xfc\x50\x28\xcc\xbe\xf0\xaa\x82\xf1\x71\xe8\x87\xda\x34\x53\xf4\x13\x7c\xd8\x2a\xa2\xd2\x4a\x5c\xca\x0a\x69\xe6\xf4\x87\x9e\x89\xcf\x7c\x22\xac\x73\x67\x92\xf8\xae\x53\x6b\x34\x4d\x1b\x54\x58\xdb\x85\x5c\xbf\x38\x58\xd5\x18\x7a\x66\x7b\x8f\xed\x07\xa3\xc0\x47\x46\xbc\xe5\xa5\xaf\x26\xa1\xfd\x58\x30\xd2\xc2\x92\x17\x2f\xa9\x70\x69\x57\x3f\x89\x0c\xb5\x1a\x57\xca\x70\xf3\x36\x9f\x9b\x0d\x6e\x7f\x74\x78\xf9\x89\xd0\xc8\x52\x82\x79\xfc\x7a\x5f\xec\x2e\xa7\x53\x91\x3f\x5e\x46\x19\x5b\x5f\x78\x09\xeb\xe4\x60\x5b\xb6\x83\x6f\xeb\xc7\x7d\xec\xbe\x5e\x44\x86\xba\xcd\xb6\x34\xad\x67\x9b\x0f\x9e\x9c\x64\x46\x79\xbe\xeb\xd5\xb1\xf2\x6f\x9f\xb4\x27\x69\x5f\x72\x82\xed\xae\x48\x28\xb6\x2c\xea\x7b\x5e\xf5\xd8\x28\xb5\x2f\x85\x8f\x36\x10\x7e\xca\x4e\x4a\xf5\x83\x6b\x29\xcf\x94\xcb\x2a\xc3\x66\x83\xe2\x20\x1f\xcc\xb4\xc5\xee\xdd\xe3\x7e\x33\x26\x08\xd6\xbe\xf2\xe3\x20\x69\x51\x1a\xeb\x1c\xc9\x57\x0d\xcd\x73\xbb\xab\x54\x4c\x21\x6c\x73\x4a\x08\x4f\xf0\xba\x66\xf5\xa7\x66\x93\x5b\xb0\xc3\xf0\x9b\xc1\x8b\xa8\xe8\xf1\x93\x0f\x78\xe3\x87\xeb\x1c\xbc\x04\x3b\x0e\xda\x8a\x6b\x07\x03\xc2\xce\xea\x09\x78\xc7\xe8\xbb\x42\x8a\x10\x2b\x5b\x05\x81\x1f\x45\x99\xa9\x5d\xce\xcf\xd5\x4b\x51\xaf\x2d\x2b\xcb\xf8\xfe\x42\x6a\xdb\xf7\xce\x86\x24\xc1\xfd\x60\xb0\xad\x13\x59\x29\x4d\x5a\xf0\x09\xca\x4d\x91\x3b\x7a\x38\x1d\x10\x61\x84\xbf\x2d\xd7\x04\x76\x27\xf6\xc2\xe8\x80\x68\x8a\xbc\x7d\x86\x0b\xea\x22\x5f\xaf\x06\x02\x63\x22\x8b\x9b\xd6\xcc\x7e\x06\x2f\xf0\x62\x26\xcd\x59\xdb\x44\x4d\x48\x29\x30\xe9\xd4\x06\x9e\x62\x3a\x76\x99\x5f\xd7\x53\xa3\x03\x4a\x63\x7c\xdf\x69\x85\x09\x1e\x35\xbf\xce\x1c\xa0\x56\x07\x34\x60\x48\xc9\x06\x16\xda\x41\xbf\xed\x96\xe7\x0e\x86\xdd\x4c\x10\x36\x62\xc0\x0c\xd7\x5d\x51\xee\xe0\x83\x26\x05\x1d\xd0\x48\x79\xa2\x7b\x0c\x4f\x90\xf3\x6c\x44\xae\xaf\x03\xdf\x0b\x91\x30\x74\xb3\x7e\x9c\xaf\xf6\x87\x33\x94\xcf\xdb\x87\x07\xf7\x7d\xbe\x0e\x0c\x68\xd2\x14\x26\x5e\x10\xac\xdd\xb7\x16\x41\xa0\x43\xdd\xf5\x11\xfe\x0e\xd7\x0d\xaf\x5e\x3f\xc4\x5c\x8f\xee\x30\x64\x31\xeb\x44\xf1\xac\x8e\xd0\x24\x97\x4f\xef\x33\x3a\xc6\x06\xd5\xcd\x6c\x39\xb8\x11\x46\x8c\xa0\x2a\xc2\x0b\x3c\x36\x5c\x4c\x01\xa3\xcc\xba\xbb\xdf\x01\x5b\x1d\x77\x23\xd6\x52\x1d\xb0\xc0\x72\xc6\x73\x0d\xb3\x91\xec\xaa\x0e\x58\x4c\xdb\xa3\xb3\xe6\xaf\x69\x7e\xdc\x40\x13\xb4\x55\xd3\x5b\x26\x60\x42\xd1\xa0\xd7\xb2\xfa\x2f\x9d\x89\x80\x29\x81\x7d\x86\x29\xba\xc5\xef\x76\x35\xc6\x37\xb3\xa4\xa3\x00\x32\xd0\x8c\x5e\x58\xd8\xbb\xe9\x28\xf6\x10\xa9\xa9\x00\xc1\x14\x86\x59\x63\xf8\x60\xa2\x38\xa1\xd6\xa6\xef\x4c\xd7\x73\x73\xb2\xf2\xd7\x5b\x3d\xc3\xd1\xe7\xa4\x6f\x69\x7b\x6d\x9b\x63\x79\x3d\xd7\xd5\x75\xf0\x4a\xe2\xd8\xc7\x6e\x8b\xf9\x7a\xbf\x98\xed\xbe\xfe\x52\xfe\x45\x07\xb1\xf2\xb8\x85\xae\x7c\x2f\x7e\x8e\x5e\x10\xf7\x8c\x4b\xff\x59\xc6\x71\xb2\x0f\xc4\x7e\x5e\x70\x8e\x95\xeb\x57\x38\xe5\xfc\x38\xb8\x53\xe9\x03\xef\xa1\x35\xd4\x0f\x48\xab\x76\x4c\xc6\xe8\x5d\xcf\xd3\xc6\x13\xcd\xba\xa2\xab\x0e\xb0\x81\x14\xa9\x64\x2c\x08\xe5\xf3\xcc\x67\xa0\x7c\x43\x5b\xff\x04\xc5\x39\x83\x66\xeb\x5a\x1e\xdf\xfe\x45\x15\x93\x88\xcf\xb5\x30\xb1\xaf\xd7\x33\x94\xcb\xf4\x6d\xe4\xe2\x04\x10\x26\x7e\x9f\xa2\x54\x35\xa1\xc9\xff\x70\xf9\x7a\x2e\xdc\x91\x15\x40\xc2\xd0\xad\x95\xbc\x54\xbb\xba\xbc\x48\xc7\x0d\xd4\x8e\x83\xb4\xfd\xc9\x0b\x9e\x65\x96\xcc\x6d\x39\x26\x0e\xd6\x81\xe6\x02\xf3\x92\x4f\xab\xe7\xbb\xed\xf3\x66\xf6\xb8\x58\x1d\xee\x56\xab\xc3\xf3\x6c\x6f\x59\x7a\x74\x48\x02\xd3\x71\x6c\x13\x4a\x3d\x9c\x55\xfb\x00\x42\x92\x08\xac\x89\xf6\x3c\xf1\x41\xa1\x30\xf4\x00\x22\xde\xc2\x8e\xb0\x32\xd1\x3d\xd8\xd8\x4d\xd2\x21\xf6\xb7\x3c\x5e\x64\x06\x97\xea\x3b\x36\xd0\x58\xd5\x75\x77\x21\xca\x4d\xad\xea\xdd\x21\x43\x26\x1d\xc5\x90\x72\x23\xe4\xd5\x67\xab\x98\x7c\x77\xa1\x4f\x7c\x04\x0f\x62\x3e\xab\xad\x33\x85\x3e\x31\xad\x5e\x0f\xdb\xfb\xc3\x23\xbc\xcf\xe1\xe3\x04\xcb\xc0\x40\x84\x7e\x12\x9a\xfa\x2f\x54\xf5\xa1\xec\x75\xa9\x36\xe7\x70\x79\x32\xbc\x59\x52\x5e\xba\xfe\x38\x1d\xfa\xca\x00\xf4\x8e\x50\xcf\xa1\x6e\x26\xce\xc7\x02\xc4\x3a\x0c\x38\xe7\xc4\x75\xff\x58\xe9\xaa\xe1\x8f\x66\x9e\x69\xf6\x68\x22\xc1\xdf\xfb\xfb\x20\x64\x81\xc1\xde\x1f\xa1\xfe\x0e\x2f\xa9\xcc\x90\x3d\x62\xea\xc1\x45\x9e\x8f\x85\xd2\xf7\x17\x5e\x57\x9b\x6b\x2f\x71\x16\xc6\x31\xa1\x36\x71\xb6\x7d\x83\xf2\x2d\x85\xf7\xe9\x33\x32\x8c\x39\x09\x0c\x11\x58\x73\xfc\x3a\x52\xc1\xf6\x3a\x5a\x80\x93\x51\x3b\x18\x7e\xf2\x83\x4e\x73\xac\x73\x7d\x4d\x73\xf4\x8a\x6d\x36\xd1\x9c\xdc\x7b\xee\x24\x33\x75\xc8\x21\x44\x83\xff\xc4\x2f\x55\x87\xe4\xd4\xa1\x08\x39\x62\x7b\x91\x7b\xec\x5b\x6e\x74\x1d\xdb\xc1\xd8\x80\xb2\xab\xcb\xe9\xd4\x04\x0d\x45\x59\xb7\x54\x34\x3a\x14\x09\xd1\xc4\xa6\x16\x07\xce\x9f\xcb\x3e\x85\x82\x87\x7e\xc7\x14\xfe\xa5\x17\xba\x87\x42\xc5\xe8\xbc\xae\xea\x17\x2c\xe8\xae\x7e\x9e\xb3\xa2\xec\xd6\x91\xf4\x44\xd8\x6a\x15\x97\x03\x7e\xe3\x7e\xc3\xb6\x9b\x4d\xb9\x69\xb5\xab\xd4\x02\xf2\xba\x1a\x86\xc8\xa1\x8c\x05\xc2\x93\x17\x17\x2c\xa0\x3c\x5f\x26\x52\xf1\xed\x4d\x4b\xe1\x39\x25\x8b\x0e\x51\x30\x33\x11\x8d\x9d\xa2\x02\x40\xff\x6f\xde\x04\x65\x65\xcf\x58\x85\x2a\x8c\x90\x85\xc0\x25\x53\x90\x9a\x69\x78\xaf\xe0\x33\x65\x97\xc3\x0f\x48\x5b\x8c\x19\x38\x35\xa0\xe1\xd1\x16\x6a\x6a\x82\x8c\x4b\xbe\x49\x73\x50\x4f\xdd\x96\xd6\x71\xa4\x3a\x14\xd4\xa2\xc8\xab\xcb\x09\xa1\x31\x9f\xf8\x6b\x8c\xf8\x0c\x91\x7a\x99\x21\x10\xee\x09\x4d\x69\x46\xa9\x49\x8b\xa2\xfc\xcf\xa8\x94\xc2\xa8\x0a\xa0\xc3\x0e\x1a\xfd\xe3\x65\x71\x11\x19\x2c\xc7\x72\x56\x9a\xf9\x8d\xf1\x33\x86\xf4\xa9\xb4\xe8\xf4\x96\xf3\x54\x33\x3f\x60\x36\xd7\x8e\x49\xfa\x4d\x9a\xf7\x14\xbd\x35\xf3\x85\x11\x8b\xcb\xe1\x7a\xe2\xe5\x57\x5e\xa1\x90\x83\x1a\x7f\x07\x28\xe0\x2e\x1f\xbc\x56\x46\x8f\x73\x38\x25\x90\x01\xd5\xd6\x9e\x0f\x95\xb1\x7b\xa5\x1a\x16\x28\x03\xbb\xfa\xba\xfd\xbe\x7a\x5e\x3c\xcf\xee\xf6\x87\xfd\x9f\x4f\xce\x8e\xb3\x90\x2a\x17\x64\x5b\x71\x9d\x79\xf1\xd3\x38\xc8\xa3\xaf\x0b\x83\x38\x66\x63\xc1\x8c\xd1\x94\x24\xa4\xc6\x03\x71\xe8\x93\x25\xbc\x8d\xf1\xf4\x9a\x31\x2a\x30\x6b\xff\x3f\xf7\xcd\xe2\xda\x3a\x98\xba\x66\x2c\x0c\x02\xdf\x22\x7d\xd0\xd9\x76\x7f\x67\x26\xe5\xd5\x04\x46\xbc\x39\x68\x70\xc1\xba\xd1\x28\x26\x98\x39\xdc\x5c\x4e\xd5\xfe\xa5\x89\x36\xda\x0b\xc6\x54\x60\x64\xf6\x7d\xf3\xbd\x6f\x6c\x58\xe2\x7b\x98\x31\xc8\x40\xd7\x8c\x8c\x7e\x45\xe2\x07\x68\x17\x0e\x35\xf0\x93\x3b\x63\x47\x53\x82\xb6\xe3\xd6\xf6\xb8\x7e\xab\xc0\x28\x68\xd8\x5d\xe1\x26\x2a\x4d\x6d\x5c\xb0\xe4\x35\xb7\x67\x6e\x9f\xdf\x5a\x33\x1e\x47\x48\x94\x6a\x4e\xc1\xb9\x39\x37\x86\xb9\x07\xc6\x55\x1c\xf5\x50\x57\xc7\x12\xa0\xa3\x5f\xd7\x4c\x78\x04\x45\x60\x50\x13\xf8\x1e\x19\x7b\x5a\x26\x53\xcd\x84\x1f\xe3\x17\xfc\xe0\xb5\xec\xf4\xd5\xee\x00\xaa\x75\xbe\xfb\x87\x8b\xa2\x9d\x18\x11\x69\x54\x3b\xf2\xab\xa3\x1d\xa8\xda\xc1\x58\x60\x83\xce\x1f\x7f\xee\xdb\x3f\xa9\x18\xc1\x53\x28\x85\x45\xdd\x5f\x95\x4d\x7c\x75\xa9\x10\xf8\x20\x1e\x66\x10\x04\xb1\x89\xdd\xaa\xba\x50\x29\xcf\x1d\x8d\xc3\xdf\xa3\xb2\x00\x03\x2d\x5c\x6c\xbc\x50\xbd\x4a\x1d\xd3\xbe\x46\x46\xa3\x26\xfc\x6f\x1e\xce\x41\x95\xe9\x5b\xf7\xa6\xb5\x30\x3e\xc8\xe6\xb3\x62\xc8\xf0\xab\xb4\x00\xb3\xf5\xf8\x2b\xcc\xde\xf9\x75\xda\x77\x67\x5a\x9a\x66\xdf\x36\x4c\x9e\xbd\x41\xc9\x8f\xf0\x94\xfe\x84\x4f\xe8\x66\x75\x44\xbc\x58\x05\x8e\xed\xef\xdb\xf3\xfa\xcb\x54\x0d\x26\x22\x82\xfb\xcc\x19\x80\xff\xb8\xbe\x68\x1d\x79\x44\x98\xb6\xd8\x97\xe2\xbd\x83\x57\xe2\xdf\x23\x07\x2d\x3c\xd8\xec\x40\xfa\x0f\xd8\x1c\xbc\x9b\x45\x49\x8c\xfa\x53\x0a\xb2\xf4\xcd\xa5\x48\xe6\x48\x36\xf2\x61\x99\x25\xa2\x24\x41\x0a\xf7\xdf\xaf\x02\xca\xaf\x3c\x57\xd9\xb8\x20\x12\xd1\x80\x20\xf5\x70\x8f\x2e\x74\x8a\x74\x6b\xf8\x20\xa8\x08\x9d\xfa\x93\xa5\x36\x6d\x39\xa9\x9a\x0f\x1c\xf8\xad\xa4\x81\x8e\x7c\x2f\x94\xcc\x15\xbd\xa5\x4d\x7b\xb9\x34\x57\xe4\x7b\x02\x0b\x7c\x7b\x38\x1d\xa1\xcd\xf8\x46\x3e\x37\x0d\xcf\x96\xea\x6a\xc0\x50\xaa\xa3\x90\x25\x28\xbb\xa5\xc0\x28\x5e\x01\x66\x09\xbe\x17\x3d\x77\x20\x62\xbe\x32\xec\x0a\xe8\xc6\xf6\x53\x45\x11\xe3\x3e\xee\x02\x7c\x98\xbb\x7a\xdc\xd0\x17\xbb\x69\x52\x20\x10\xa2\x4a\x4f\xeb\xbc\xaa\x79\x96\x99\xed\xd5\xf3\x1b\x22\x06\x42\x1b\x92\x8e\xb2\xba\x4f\x75\x07\x95\x88\x22\x9f\x68\xaf\x8b\x59\xee\x2e\xb9\x1a\x24\x3a\xa3\x28\xa4\x88\x67\x90\x48\x0b\x73\x29\x61\x59\x9c\x78\x9a\xdf\x15\xe5\x97\x69\xb4\xdc\x34\x94\x2b\x8a\x64\xac\x2c\xef\xd7\x4c\xeb\x34\x4b\x2d\xab\xcd\x87\xad\xf0\x3a\x8a\x49\x10\xa8\x36\x27\x75\x2b\x09\xad\xa3\xd8\x57\x68\x6f\x79\x96\xb5\x2c\x9c\x6e\x88\x07\x61\xa7\x01\x3a\x9f\xff\x3e\xfe\xa8\x34\xfa\x6d\xee\x1e\x6c\x3e\x70\xb4\xfe\x92\x90\x21\x49\xef\x6e\xbd\xfa\x98\xc7\x5c\x47\x89\x32\x54\x12\xae\xe3\xe0\x19\x85\xc3\xd3\xfc\xd8\x97\x72\xd2\x11\x8f\x13\x16\x3a\xd9\x88\xf6\x8f\x20\xa0\x5f\x35\x98\xe5\x75\xfa\xf7\xe5\x46\xc5\xce\xce\x16\x7e\xcc\x8d\x51\xaf\x2e\x27\xb0\x46\xb7\x7f\x06\x45\x22\x96\xb8\x15\xcf\x88\x66\x39\xc8\x5e\x60\x14\x09\xe1\x19\x72\x3d\x9e\x63\x12\x19\x8f\xff\x9e\x8c\xf5\x6f\x53\xb4\x3e\xd3\x66\x6d\x14\x74\x47\x92\x26\xb1\x4d\x20\x5a\x8c\x3d\xda\xaa\xdb\x5e\xf8\x66\xaa\x30\xea\x30\xe6\x24\x18\x71\x33\xeb\x48\x11\x1f\x8b\x71\x8d\x6d\x6d\x5c\xb3\x07\xfe\xcf\x75\x51\xb8\xcc\xab\xfb\x2d\x8a\xfa\x08\x04\x73\xad\x70\xb7\xe1\xfb\xf0\x5b\x95\x94\x48\x28\xdc\xe5\x73\x57\xf5\xb4\x7e\x8d\x8e\x80\x78\x88\x10\x5d\x2f\xb6\xde\xa0\xa4\x19\x01\x31\x4e\x58\x05\xf5\x82\x9f\xb1\xff\xbb\xc5\x4a\x4c\xb6\x51\xba\xcf\x31\xa3\x49\x6d\x1c\xc1\x45\x51\x64\xaa\x78\xcf\xbb\x35\x1d\x90\x7e\x67\xa7\x8e\x20\xa1\x81\xf5\xa7\xdb\x53\xb9\x5d\x47\xcd\xa1\x85\x6c\x68\xaf\x50\xcb\x17\x93\xc9\x75\x63\xda\xa3\x60\x23\xfa\x79\xaa\x10\x0f\xda\x84\x02\x38\x13\x90\xec\xc6\x74\x55\x0f\x9f\x79\x4c\x62\x82\xed\x30\xe9\x0f\x9e\xd7\x7f\xfc\x0e\xd7\x51\x21\x22\xf6\xfc\x08\xcd\x0c\x14\xd5\x72\xb6\xfb\x3a\xfd\xe0\x62\xcf\x07\x5f\x77\xc2\x7b\x6d\xa5\x21\x76\xe3\x49\x14\x9b\xc4\xa7\x4c\xcf\x29\xe4\xf5\x66\xbd\x1f\xdd\x89\xa7\x29\xee\xfa\xe6\x4e\x72\xfe\x90\x22\x0a\x1c\x5a\x16\x76\x1d\x53\x12\x18\xd6\xae\x9f\x6d\xcf\xac\x8e\x29\x23\x9e\x68\x9d\x9d\xc6\x10\xa6\x35\xb6\xa0\x18\x97\x6e\xa2\x88\x1e\xd3\xc8\x77\x30\xa9\xa7\x54\x8e\x7e\xae\x4f\x25\x76\xd7\x14\xef\x39\x94\xc6\xed\x31\xf0\xb0\x5f\x09\xf9\xba\xcf\x47\x9a\xab\x9e\xf0\xc9\x43\xcb\x5a\xa1\xe3\x80\x44\x48\x83\xd1\xb1\x21\xb4\x3e\x55\x1c\x06\x09\xf6\xb6\x34\x01\xbb\x2b\xcd\xc5\x8c\x29\x24\xc5\x42\xd4\xb1\x93\x14\xe0\xf9\x32\xad\x64\xe7\x13\xc6\x8c\x27\x61\xdf\x90\x18\x21\xb7\x7e\x96\xd0\x4e\x8c\x98\x88\x6c\x94\x68\xad\xe6\xb7\x72\x20\x65\xa4\xe3\x28\x81\xd8\xb7\xf8\xfa\xb7\xe2\xf5\x86\xdb\xc7\x4e\x8b\x3d\x8e\xd9\x75\xfd\xad\x82\x41\x0a\x26\x8e\x01\x44\x07\xa1\x98\x5f\xae\x73\x2e\x5f\x51\x6c\x74\x78\x85\x24\xf4\xb0\xd7\xb9\xb1\x64\xbc\x86\x92\x67\x2e\xd7\x39\x0e\x5d\xe2\x24\x0a\x02\x8d\x9d\xf1\x4d\x14\x65\x82\xf5\xf1\x94\xc4\xd4\x68\x51\xc9\x7e\x04\xa0\xb8\x8c\x09\x36\x74\xcc\x69\x80\x48\x38\x38\xa1\xa3\xe5\xb0\x98\x9f\xc2\x25\x6f\x5f\xb5\x90\x89\xe7\xc4\xcb\x5b\xcc\xda\xc0\x15\x8f\x65\x22\x65\xdc\x51\x50\x4e\x50\xce\x7c\xea\x42\xda\xab\x28\x66\xc2\x20\x74\xdd\xf0\xbc\x1a\x50\x00\xe8\x58\xc5\x12\x93\x36\x86\x8f\xb2\x97\x4d\x89\x21\x49\xd0\x8f\xda\x5c\xb0\x62\x7b\x97\x96\xa0\xc4\x35\x6c\x57\x18\x88\x10\xd3\xd6\x76\x3d\xac\xab\xbb\x5b\x01\x71\xdd\xbc\x53\x4c\x5f\x57\x17\x31\x02\x2e\x8f\x1e\x89\x0e\x54\xe0\xb6\x56\x67\x1f\x87\x52\x7c\x3a\xd6\xb1\xc6\x54\xac\x46\xfc\xee\x7a\xb1\x6d\x6b\x38\x6e\x02\x80\x73\xe4\x90\x3e\xf2\xb9\xcf\x32\xd5\x65\xa8\x13\x12\x00\xda\x26\x05\xd9\x02\x59\xae\x4f\x23\x35\x4f\x9d\x90\x30\xc2\x0a\x83\x4e\x73\xf5\x08\x3f\xeb\x3f\xa1\x27\xb8\xdc\x63\xfb\x6a\x66\xc6\x58\xf7\x79\xe1\xd5\x58\x4a\xf8\xb7\xd1\x35\x85\xc6\x7d\xbc\xe4\xf5\x13\x1f\x64\x9d\x12\x02\x11\xf6\x24\x58\x40\xdd\xa7\x1c\x03\x3a\x69\x7c\xef\xc8\x0a\xb6\x18\xf1\xce\x16\xf5\x64\xc9\x87\x62\x37\xd3\xe7\x60\x53\xf6\xbf\x17\xa9\x53\x9d\xfd\xe0\xaa\x01\x47\xf4\x35\x9a\xb0\x9d\x49\xa3\x95\xa9\x9a\x7c\x82\x1e\xf8\x78\x24\xbb\xcd\x67\xfb\x8d\x46\x0f\x91\x82\x87\x08\xa6\x13\xff\xd9\x18\xc3\x66\x67\x23\x54\xdb\x99\xa0\xc4\x0f\x14\xa6\xb2\x73\x78\x37\x47\xdb\x64\xf5\x25\xf1\x03\x6d\xb9\x12\x72\xb5\x2f\xe6\x90\x03\xea\xdb\x97\xd7\x51\xfa\x24\x09\xc0\xb0\x90\x54\x50\x1f\x5e\x8a\xea\x3c\x19\xd2\x24\xa1\x27\x11\x63\x97\xe6\x69\x6d\xcc\xfd\x24\x76\x6a\xf4\x21\xdf\xf4\x3c\xd4\x9d\x20\xee\xd8\x11\x49\xc2\x48\xa2\x7a\xd5\xf3\x76\xb7\x98\x0d\x38\x69\x68\x3c\x7e\x95\xf6\xcc\x77\x07\x78\xc2\x22\x26\xbd\x4e\xb9\xcc\x46\xe8\xdf\xb0\xa7\xaa\xfb\x1d\xb7\x26\xaa\x7b\x4a\x4c\x02\xf1\x1d\x6f\xc8\xa5\x82\x95\x3a\x82\xeb\x22\x1a\xce\x8c\xa2\x44\x2a\x57\x1f\xc7\xf3\x7e\xea\x1d\xc7\x81\xf6\x9c\x54\xd3\x1d\x4f\x3f\xa7\x90\xd2\x09\x32\x6a\xf7\xe3\x50\x2c\x0a\xf7\xf8\x9c\x74\x92\x78\x14\x1b\x43\xe7\xcf\xb3\xc7\xa5\x41\xef\xb4\x43\xdc\xd0\xa6\x8a\xcb\x55\x70\xf9\xba\xbf\x9e\x61\xff\x5e\xb4\xa3\x52\x21\xbd\x40\x5a\x63\xd9\x67\xff\x52\x16\x97\xe3\xcb\xee\x9d\x97\xd3\xfd\xa0\x3a\x49\x94\x89\xa5\x9c\x76\xdb\x5a\x3f\x82\x84\xaa\xe2\xad\x39\x49\x38\x33\x0c\x8f\xab\xfd\xd7\xc3\xb7\xdd\xf2\xb0\xfa\x63\xf1\x75\xf6\x78\x6f\xea\x0b\x87\xf5\xe3\x61\xb1\x7a\xdc\xef\xda\xd9\xd2\x00\x2e\xb3\xe2\x38\xe0\x66\x98\xf6\x1e\x13\x2e\x13\x4c\xb8\x08\xa1\x7c\x16\xc4\x81\xbb\x8c\x60\xa6\xbe\x8c\x15\xb9\xae\xa7\xc0\x8d\x26\x80\x5c\x70\x77\xcb\xc5\xc0\x3c\x28\xdf\xc7\x0e\x85\x7b\xc8\xd3\x8b\xe5\x11\x68\xc7\x74\x88\x09\x6b\xab\xa5\xf9\x11\x4e\x73\x7c\x60\x4c\xa1\xf7\xba\x1b\xd1\xbe\xc2\x42\x86\xb5\x47\x28\x7b\x8a\x8e\x28\xba\xa3\x37\xb5\xdf\xf1\xa7\x43\x40\x5a\x89\xcd\xec\xf1\x87\xbb\x4d\xcd\x35\x26\xf8\x9c\x75\xb9\xd1\x14\xd3\x9c\x78\x3e\xd3\x03\x60\xf1\x54\xb7\x69\x33\x4f\x18\x09\x82\x12\xce\xbc\x6c\xdc\xbd\x15\x2f\xb3\xeb\x9d\x79\xd5\x3d\xb6\x7c\xcd\x49\x98\x38\xae\xd2\x75\x55\x5d\x9a\x23\x68\xad\xaa\x11\xd3\xd1\x64\x14\xe3\x2e\xc0\x22\xf4\x73\x51\xec\xca\x74\x69\xcc\x87\x0c\x18\xc3\x80\x8b\x93\x38\x10\x64\x48\x17\x76\x53\x7d\xb5\x53\x3d\x1a\x7a\xa4\xe5\xf1\xee\x13\xb3\xfe\x97\x76\x11\x41\x64\x43\x02\x4e\x03\x00\xbb\xbf\xef\xd2\xe3\x0b\xe6\xc4\x4b\x98\x2c\x94\x70\x5f\x68\xc4\x94\x1f\x9c\x70\x6e\xe3\x4f\x5e\xce\xb8\x25\xdd\x8e\xe5\xbe\x34\x39\xf8\xe6\x21\x62\x58\x35\xfc\xe9\x41\xc0\xb0\x25\xb2\xc5\xf3\xbb\xcc\x1a\x0f\x58\x92\x90\x0e\xd1\x65\xf5\x1c\xef\x2e\x23\x79\x23\x37\x9b\x1b\x7c\x41\x73\xb8\x17\x45\x36\xca\xa8\xf1\x40\xfb\x10\x3b\x82\x6f\x04\x18\x8c\x3e\x1f\x7a\x91\x4b\xe5\xe3\x93\x9c\x5f\x67\xa8\x24\x36\x62\xf2\xd3\x3c\x94\x06\x81\x63\xc9\x4a\xd6\x39\xd6\x96\x75\x2a\xf7\x63\xe6\x18\xcd\x43\x15\x62\x41\x1f\x71\x37\xf5\x45\xc0\x0d\xd0\x79\x3c\xdf\xa8\x7b\x57\xef\xfc\x3c\x6b\x05\x0e\xdc\xa0\x26\xa8\x94\xef\x40\x3a\xab\xfd\x57\x37\xc4\xa2\x50\x5a\xae\xe2\x37\xe0\x59\x8f\xcc\xfd\xc3\x1d\xf9\x0b\x17\xcf\x5e\x38\x22\x11\xde\xd0\xfc\x72\x7d\x36\x5d\x21\xb8\x31\x3f\x98\x1c\x2a\x4c\x68\x2b\x78\x83\xac\x38\x43\x79\xe0\x4a\x1d\xcc\x29\x72\x98\x0f\x5c\x79\x1e\xfb\x24\xb2\x32\x87\x5f\xcf\x4b\x50\x17\xd9\xa5\x7f\x78\xcc\x62\xac\x9d\x3d\xa3\xda\x43\x9a\x1f\x51\x63\xbc\x97\x85\xe2\x89\xe6\x18\xd7\x9f\xcd\xc9\xc3\x8f\xf0\xf5\x72\xe2\xb9\xc3\xc3\xdb\x59\x9c\xfa\x18\x91\x1e\xd2\xea\xb1\xa8\x37\xe9\xcf\x9e\xf4\xcd\xe8\xde\x79\x14\x62\xe6\xf4\x6c\x7a\xaa\x0c\xe3\x77\x9f\x3e\x5c\x73\xce\xa9\x01\x99\xfe\x62\xc3\x71\xad\xf1\x5b\x67\xcb\xff\x88\xcb\x3f\xff\x2c\x8a\xd3\xe9\xd2\xe9\xf5\xd8\x49\xc2\x27\x48\x11\x72\xbc\x98\xfe\xda\xc1\xcd\x88\x20\xa2\x86\xcc\xe5\x5b\x05\xa5\x61\xb3\x53\x77\xb7\xe4\x5c\x43\xd7\x8a\x0b\x16\x22\xdd\x41\x75\x39\xad\x32\x1b\x9b\x9b\xd3\xdf\x05\xfc\x5c\xc4\x31\xe2\x17\xcf\x5a\xda\x8e\xec\xac\x0d\x61\xb9\x00\x16\x09\x73\x60\xc3\xb9\xb6\x60\x12\xdb\xab\xd3\xfd\x58\x3b\x59\x52\x1a\x9b\x4c\x56\xfa\xf7\x05\xfe\x07\x05\x63\xc7\x9b\x4e\x85\xd4\x6a\x3d\xd7\x3c\xeb\x7a\x89\xed\x28\x50\xc9\x6c\xea\xe3\x0c\xb9\x93\xe3\xdd\x17\x0e\xd3\xd5\x7e\x60\x6e\x7b\x28\x3f\xcc\x63\x70\xf0\xa9\x87\xcd\x92\x25\xb4\x39\x07\x0e\x21\x05\xaf\xad\x58\xde\x0d\x7b\xd3\x38\x28\x0f\x43\xe9\x53\x9a\x5b\x34\x0a\x96\x9d\x57\x6d\x78\xc4\x31\xfb\x6a\xd6\xfe\xea\x78\x6c\x6f\x5b\xc7\xdc\xf7\x2d\xfe\x6d\x9f\x8e\x04\x29\xb5\x20\xc4\x10\xf1\x6c\x45\x09\xaa\x45\x5a\x08\x12\x25\xa6\x67\xf4\x0f\xf7\x17\x1a\x11\xa4\xe7\xae\xde\xd3\x5a\xbe\xb8\x12\x7f\xe7\x19\x09\x9f\x05\xf8\x3a\x30\xb0\xb2\xfa\xe7\x6e\x88\x07\x89\xef\xf8\xaf\x2d\x51\xfc\xf0\x36\x7c\x61\xea\x57\x7f\x71\xf9\x7a\xc8\x8b\xae\x80\x2a\x82\xd0\xe0\xf7\xac\xa6\xa6\x21\x7e\xeb\xb5\x34\x0c\x37\x86\x08\x3d\xe3\x62\x98\xdd\xbb\x2f\x5c\xc5\xa6\xbf\x9b\x45\xc8\x43\x07\x08\x1b\x10\x3d\xd8\x61\x16\x28\xc4\x3e\x73\xa5\x16\x97\xaa\x2e\x4e\x06\x31\xfa\x54\x16\x6f\xa9\x82\x72\x22\x32\x12\x0c\x12\x3c\x7d\x1f\x8a\xe3\x27\xb8\x03\x3b\x39\x0a\x25\x26\x10\xab\x8c\xbf\x41\x3e\xeb\xa7\xbb\x45\x24\x12\xec\xe5\x7b\x7a\xde\x6e\xdc\xdf\x12\x2f\x30\x59\x23\x53\xa8\xbe\xe3\x55\x0d\xf9\x6a\xff\xb5\xcb\xdc\x88\x04\x0c\xe3\xb7\xc1\x44\xd5\xb0\xd5\x4f\x59\x9b\x61\x17\x9c\x50\xb4\x5e\x2f\xbc\xda\xbd\xa6\x1d\xf1\xf2\xe7\x31\xb9\xe0\x34\xe0\x86\x1f\xce\x90\xcb\xcd\xd3\xe2\x84\x48\xab\x87\x3e\x16\x5a\xf0\x40\xa3\x83\x8f\xaa\xed\x53\xad\xb8\x82\x27\x89\xeb\x6b\xfc\xdf\x4b\x51\x0f\x2a\x84\x42\x50\x62\x40\xfb\xa6\x56\xb7\x3b\xf1\xb2\xde\x9d\x01\x94\x2d\x74\xba\x69\x81\x40\x14\x97\x41\x2b\xb7\x7f\x8d\x94\x29\xc4\x00\x3f\x0d\xa5\x70\xb4\x10\x89\xc6\x80\x70\xb9\xfd\x71\xd8\x7f\xfd\xd6\xfe\x59\x28\x6c\x0f\x79\x9a\xb5\x18\xf9\xe6\x4f\x84\x5a\x37\xfd\x47\x6a\xa5\x3e\xab\xe1\xa2\x11\x8a\x5b\x15\x65\x78\x35\x44\x09\x6d\x8c\x2d\x54\x10\xc7\xa6\xdd\xf5\xad\x78\x85\xa1\xf8\xbf\x9d\x02\x54\xa2\x44\x8a\x49\x2b\x7c\x40\x61\x3e\x7a\x01\xa0\xa2\x30\xec\x91\x4f\x5f\x3a\xa2\x0d\x2d\x40\x33\xbb\x2a\x7a\xb5\x96\xd1\x05\x74\x42\xb9\x03\xad\x16\xca\xc8\xfe\x8d\xee\x4b\x27\xa6\x94\x65\x80\x2c\xcf\x20\x8b\x31\x6c\x40\x92\x50\x84\x4e\x2a\x1b\x8d\xde\xae\xc8\x14\x6a\x2f\x8c\xe6\x49\xe9\x07\x6e\x11\x36\x21\xc9\x71\xb4\xcd\xa5\x97\x44\x56\xed\xa8\xa8\x60\x53\xbb\x97\x2b\x29\x25\x08\x61\xd9\x9d\xa1\x3c\x3d\x70\x51\xb5\x03\x3c\x41\x6e\x5a\x65\x89\x62\xb0\x63\xb4\x9a\x83\x6e\xf6\x81\xe5\x31\xc1\x5f\xd5\xa7\xb4\x6d\x3e\x66\x44\x5a\x1c\x24\x0e\x81\x4b\x77\x05\x46\xe4\xa3\x5b\x0a\x3c\x69\x9b\x7e\x85\xfb\x74\x10\x12\x6e\x2a\xad\x3f\x8d\x71\x6f\xce\xa6\x75\xde\xb1\x5e\xc8\x20\x64\xf8\x3b\x36\xfc\x35\xcd\x55\xd1\xfe\x99\x6b\x6c\x30\x11\x8e\x60\x08\xff\x84\xaf\xb0\xe6\x97\xf6\x4f\xca\x48\xb6\x3b\x34\xfb\xc0\xc7\xed\xa8\x68\xff\xcb\xec\x71\x21\xc3\x20\x0e\x5c\xa4\xdf\x4b\xb7\xbb\x51\x6e\x92\x9d\xf8\xfe\xf7\xc5\xb7\x34\x1f\xea\xf4\x69\x19\x42\x24\xe3\xce\x33\x5d\xf4\x7b\x12\xec\x94\x88\x12\x62\x52\x22\x99\x56\x50\x21\x40\x6d\x3c\x05\xa8\x72\x22\x06\x69\x3e\x48\x54\xca\x44\x0a\xc4\x31\xdc\x15\xa5\x3d\x86\x6f\xa4\xae\xb4\xe4\x7e\x84\x50\x80\xc7\xa2\xe8\x54\x47\xec\x98\xa0\x26\x29\xe6\xe0\xa7\xed\x59\xff\x2f\xfd\xbf\xcf\x2d\x99\x14\x2c\xc1\x04\xe9\x1e\x32\x38\x96\xfc\xb4\x6f\x79\x23\xa4\xe0\x54\xc7\xae\x19\xdc\xe4\xa8\x71\x91\x99\x7e\xf8\xc6\xa1\xaa\x6a\xde\x36\xf8\x48\x49\x12\xdc\x51\x55\x7a\x3a\x1b\x5e\xba\x29\x28\xe5\xe8\x2e\x07\x3c\x90\x83\x1b\x93\x61\xc4\x8d\x4a\xc2\x4f\x6c\xf6\xde\xbf\xf0\x1a\x7b\x33\xdb\x82\x8c\xd5\xd1\x6b\x77\x84\x8c\x22\x6a\xe2\x23\xf9\xc2\xcb\x23\x3c\x17\x62\x8c\x80\x90\x52\x0a\x8c\x61\xa0\x92\x65\xf1\xde\x57\x56\xb0\x13\x54\x1c\xe0\xaf\x90\xa6\xf4\x95\x8a\xcc\xc0\xb2\xf7\xc5\x44\xac\x22\x55\x2c\x91\x13\x37\xcd\x3f\xb6\x58\xbf\xae\x77\xf5\xd4\xb9\x7a\x09\x15\xa9\x14\x78\x49\x4b\x9e\xf5\xf4\xbc\x9a\x7f\xfb\xf3\x30\xdf\x3e\x7e\x73\xc6\x59\x11\x12\x22\xd4\x2e\xad\x9c\x43\xe9\xf0\xda\xb6\x31\x7f\x8a\x60\x41\x11\x9e\x20\x91\x40\x13\xe6\x2c\x32\x5e\x55\xa9\x74\x6c\x53\x93\xd1\xa1\xf2\xa8\x29\x2e\x21\x53\xcd\xae\xd0\xb5\xe4\x7d\xc6\x2c\xad\x68\x9c\x30\xe6\x36\x00\xaa\x32\x6f\x2f\xf5\x12\xd7\x3b\x7a\x24\x7d\x20\x91\xa2\x60\x20\x11\x28\x8d\xba\x28\x9c\x02\xd0\x64\x1c\xa5\x7c\x6a\x70\x82\xa6\xee\x72\x87\x66\xed\x4b\x3b\x06\xda\x90\xff\x1a\xfa\xc8\xe9\x08\x5b\xf9\xd2\x48\xb1\xda\x53\x14\x8b\xe4\xbb\xba\xc8\x61\x70\x8a\xaa\x20\x30\xda\xb1\x46\x11\x7a\x0c\x6d\x73\x93\x2c\x2f\x95\x2b\xbb\x1c\x4e\x2a\x6c\x2f\x00\x0a\xfd\xc5\xa7\xb2\x28\xf4\x56\xbb\x3f\x87\x21\xc1\x3a\x22\x0a\x92\x3c\xce\xe6\x0f\xab\xe7\xdd\x61\x31\x7b\x6a\xc7\x19\x47\x06\x91\x43\xe3\x86\x7e\x7e\xea\xa9\x50\x8a\xc8\x20\xea\xa0\x34\xac\x73\x1b\x43\x68\xbd\x58\x1a\x0d\x6b\xb7\x17\x14\x0b\x35\x96\xc3\x5b\xd2\x9a\xc4\xa2\xca\x12\x4b\x5a\x93\xb8\x89\x00\x58\xf0\xfd\xdf\x65\x0f\x31\xa7\x22\x2e\xd0\xf4\xef\xf6\xb3\xe7\xfd\x7e\xbd\x59\xb5\x03\x02\x88\xd1\xaa\x90\xaf\x8f\xf0\xfe\xb5\x38\x43\x8f\x90\x59\xab\x48\x1b\xc8\xd3\x41\xbe\xbc\xce\x2f\x57\x28\x1f\x4e\x75\x35\x43\x9b\xf1\xab\x1f\x17\x73\x0f\x5b\x91\x04\xd4\xfd\x2c\xa0\x8a\x15\x93\xa4\x85\x91\xa3\x9f\x39\x5a\x9f\x89\x1f\x63\xc4\xdf\x04\xb5\x39\x0c\x4b\x4d\x2a\x09\x04\x42\xf5\xde\x10\x17\xf1\xd0\x06\x6e\x2a\x01\xe2\x2a\x99\xe8\x18\xde\x15\xe5\x6d\xf2\x48\xf1\xc8\x73\x52\x65\xb3\x52\xa4\x35\x94\x77\xe0\x6a\x51\x03\xb8\xc4\x74\xee\x5d\x71\x69\x54\x0c\x9b\x6f\xe9\x15\x49\x4d\x77\xfe\x97\xf1\x5c\xd3\x12\xb2\x83\x1a\x91\xea\xc5\x27\x70\x1c\xc5\xb5\x32\x92\x68\x53\x1c\x25\x4a\x50\x40\xd6\x7b\x5d\x02\x18\x92\xfe\x26\x34\x9a\x90\x2a\xd6\x4a\xf8\x21\x58\x18\xc4\xc3\xef\x8b\x95\xcd\x49\xdc\xe6\xdb\x94\xe0\xbe\x23\xe2\x31\x00\x04\xe3\xec\xde\x5e\x50\x1b\xb2\xbe\xcd\xec\x8f\xc3\x7c\xb6\x5f\x7c\x3d\xec\xd6\xff\x69\x57\x90\x0a\x42\xbc\x4a\xf5\x52\xbc\x5b\x10\xda\x3c\x55\x03\x0b\xd1\xf8\x76\x11\x16\xed\x2e\x79\xbd\xd5\xb3\x8c\x57\x35\xbf\xf2\x7e\xd8\xad\x54\x04\x31\x1f\xc6\x84\x4d\x7c\x5e\xe4\x8d\x33\xe3\x14\xb4\xb4\xd2\x7e\x28\x58\x6b\x3f\x1e\x8a\xe3\x60\x71\x00\xf1\x0c\xe3\x26\xcf\xaf\xb3\x8b\x4a\x5d\x1a\x1d\x65\x8c\xa0\x9a\xb0\xf8\x40\x78\xa8\xda\x22\xd9\xef\x05\xb8\x7d\x0e\x44\x05\x58\x0e\x69\x76\xc6\xe5\x7c\xb0\x45\x27\x59\xa0\x66\x90\x9b\x03\xe6\xad\x0c\x6d\x4c\xcb\x13\xf7\x5b\xdf\x8b\x05\x2f\x66\xa2\x2b\x5f\xdd\x8f\xb9\x8a\x9b\x09\x71\x64\x9a\x71\xb3\xe6\x20\x7b\x86\xbf\x3f\x80\xcc\xd8\xf9\x54\xf8\x91\x6d\x01\x5d\xe7\xf5\x9d\x37\x2b\xcb\x79\x51\x64\x77\xd4\x5a\xfd\x3b\xef\x4b\xcf\xe2\xfd\xf7\xff\x1d\xae\x64\xa0\x3a\xc0\x38\xfb\x31\x95\xaf\xed\x2f\xf2\x49\x82\xa4\x73\x2f\x58\x41\x30\xc4\x59\xdd\xa0\x30\x4d\x09\xd5\xfe\xf5\x83\x7e\x36\xf0\x95\x87\x54\x7e\x87\xb6\x2d\x78\x32\x23\x02\x3e\x30\x2c\x18\xdf\xff\x98\xf7\xec\x14\x04\x5a\x60\x5f\xe1\xf7\xd5\x62\xbf\x7d\xfe\xcf\xfa\xe1\x61\x76\xb0\xcc\x0c\x87\xef\xff\x71\xe0\x33\x08\xa9\x50\xca\xba\x89\x86\x39\x66\x78\xf5\xd0\x0f\x82\x8e\xc3\xfa\xb1\x78\xe3\x93\x07\x21\x30\x62\x34\x4f\x1e\x8a\xe2\xf5\x19\xde\xfa\x0b\x12\x58\xe0\x73\x47\x5d\x9b\x1e\x5f\x50\xf5\xa9\xc8\xda\x24\x09\xb0\x28\x74\x5c\xdc\x3f\x00\x5e\xb3\x6b\xe3\x70\x7e\x2f\xb2\x4b\x9b\x97\x02\xa6\x29\x6e\x8d\x05\x94\x75\xaa\x53\xc9\x6b\xe8\x72\x2d\x83\x43\x0d\x22\x61\x28\x9b\x3b\x90\xbd\xbb\x48\x04\x11\xef\xc8\xb6\x1e\xf8\x49\x14\xbb\x89\x12\xa1\x9d\x1d\xcb\x10\xeb\x1e\x48\x2a\x94\x1b\x1c\xfe\xe5\xb6\x97\x07\x12\x1e\x89\xb6\x51\x0c\x15\x09\x6e\xc8\xb3\x35\x70\xdf\xf0\x92\x55\xef\xfc\x7c\xd3\xad\xe7\xe6\x44\xa1\x43\x45\xac\xab\x59\xd6\x96\xe3\xab\x41\xe4\x0c\x9c\x87\xc0\x7b\x24\x27\xb7\x9e\x1a\x70\x2e\xb9\xa3\xf0\xb4\x2c\xb6\xbf\x80\x8c\xd9\x0f\x8a\xc4\xe7\xb1\xd9\x37\xb3\xb9\x1d\xba\x01\xf7\x8c\x3f\xc2\x13\x5b\x17\xdd\x5d\x04\xe2\xf1\x6d\x32\x73\x10\x79\x82\x48\x00\xcf\xaa\x39\xc6\xea\x68\xd4\x16\x69\x69\x71\x96\x7d\xb4\x3a\x08\x11\x3b\xa4\x0a\x6f\xd6\x41\x0d\xfb\xc2\xe0\xfc\x7b\x79\x4f\x10\x32\xf6\x3a\x7c\xf7\xea\xe7\x39\xe3\x69\x3e\x34\x61\xc2\xe2\x59\x0c\x83\xdf\xd8\x18\x83\xa4\xc6\x89\x3f\xa5\xf9\xae\x35\x8b\x20\x99\xe4\x7e\xbf\xf8\xf6\x54\x16\x3a\x45\x62\xac\xfd\xf5\x0c\xde\x07\xab\x45\xc6\xca\xec\x42\xc3\xa2\xfb\xb4\x7a\xd8\xda\xa3\x70\xf4\xa5\x89\x8f\xfb\xa9\xbc\xe4\xe3\x78\x06\xa4\x8a\x30\x59\x80\x50\xcb\x75\x2e\x87\xdc\x57\xa0\x12\x0f\xbb\x02\xea\xf4\x04\x4f\x8d\xf7\x32\x0a\xb9\x41\x49\x82\xd7\xce\xe1\x0d\x4a\x95\x0e\x32\xeb\x00\xb1\x41\x01\x62\x14\x8d\xe7\x5e\xfb\xc0\x35\xe7\xf8\xc0\x57\x46\xd5\x41\x4d\x29\x6a\x68\xd0\xc2\x47\x96\x0f\x4b\xf6\x3c\xdc\x74\x5a\x6a\xac\xd5\x34\x6f\x4b\xdd\x15\xa5\xc3\xca\x4c\x17\xc8\x41\x43\x80\xdf\xe8\x00\x33\xad\xd0\x71\xf5\xd8\x69\x44\xb4\x73\x43\x4e\x3b\x4f\x3e\x15\x06\x16\xf6\x7c\xc9\x7b\x74\x56\x48\xa0\x89\xad\xdc\x26\xc7\xd8\xcb\x69\x6b\xc2\x62\x7c\xa3\xa5\xa9\xef\x7f\xb0\x03\xfa\xc5\x7e\x4d\xa2\x28\xb2\xf0\x87\xd5\x1b\xcf\x2e\xe8\xaa\xf7\x19\xfe\x34\xe1\x02\x61\x1d\x67\x5e\xf2\xf6\x49\x6a\x8f\x46\x6e\x33\xac\x65\x81\xd0\x7d\x7f\x7a\xc1\x68\xcf\x07\x3c\x01\x70\x8f\x96\x03\xa1\x07\x2f\x72\x73\x04\x43\x3e\x73\x63\x7c\x31\x85\x38\x66\x83\xd6\x9a\x26\x0a\x3b\x24\x04\xf2\xe7\x55\xe3\x51\xcd\x11\xcd\x76\x30\xa5\xb1\xb1\x8e\x4d\x37\xd1\x8f\x29\x72\x53\xcc\xd6\xc6\xc1\x72\x3f\xc9\x57\x81\x6a\x23\x1c\x87\x5a\xd1\x81\x67\x9a\xdb\x57\x3f\xdb\x7a\x05\x76\xbe\xa9\x76\x81\x20\x74\xde\x0d\x85\x82\xe2\x61\x74\xf7\xf0\xcd\xe5\x86\x35\xf3\xb4\x51\x67\x68\x3c\x0a\xe7\x5b\x8d\x5b\x72\x74\x44\x01\x71\x0d\x56\xe7\xd3\x55\x5d\xaa\x67\x07\x63\x1b\xae\x16\x1d\x31\x83\x83\xc0\x74\xfc\xaa\x7e\x99\xf3\xfc\xb5\x2c\xb2\xac\x99\x0f\x1d\x4b\xa9\x8e\x29\x50\x8b\xf2\x33\xe2\x28\x13\x09\x0e\x9d\x50\xd3\xa3\xd7\x38\xc8\x7d\x7f\xc4\x2d\x7b\x9d\x04\x1e\x26\x7d\x17\x0e\xa2\x3b\x2d\x3f\xa9\x35\x0f\xfc\x00\x9b\xf5\xd7\xab\x7d\xef\x94\xd6\x32\x31\x4d\xab\x3b\xa8\xe7\x97\x14\x55\xaa\x6e\x34\x27\xfe\x2f\xfe\xb5\x57\x57\x32\xc1\x1e\x03\x97\x17\xe8\xf1\xc3\x0d\x27\x02\xa1\xd2\xd6\x8b\x5b\xab\x74\xeb\xe6\x6a\x88\x18\x56\x7d\xd6\x79\x75\x69\xa9\x5a\x34\x80\x6f\xb2\xe7\x17\x2c\xea\xea\x4b\xb6\x04\x9e\xb5\x7b\x42\x53\xd3\xa1\x6c\x7a\xe0\x2d\x4f\x55\x37\xca\x7c\x24\xdf\xe0\x28\xa6\xbc\x01\x95\xde\x90\xec\x6a\x8d\x08\x34\xcb\x24\xb3\x2f\xd6\xb9\xce\x2e\x90\xcb\x09\x95\xd3\xbe\xf9\xd7\x9a\x13\x4c\x01\x64\x3c\x97\x2f\x07\x5e\x73\x93\xe9\x53\x84\x90\x90\x73\x17\x20\x54\x86\x4a\xce\x8d\xc4\x1c\x9d\x2e\xae\xd4\x23\xbc\x8f\x82\xe7\xde\xc3\x68\xa6\xf2\x00\xe3\xbd\x1e\xd3\xfe\x0d\xda\x45\x11\xe2\x05\x14\xb1\x81\x82\xe7\xaf\xd4\x7d\x8d\x17\x86\x58\x0b\xb7\x25\xfc\x26\x3e\x75\x70\x0a\x45\x08\x0d\x18\x15\xae\x83\xe7\x9c\x15\x88\xd5\x1d\x6d\xfc\x66\x1a\x0f\x9c\x22\xf1\xb7\xfc\x19\xb0\xdb\x4d\x59\xff\xdc\x5d\x2a\x20\x31\xba\xd5\xae\xf2\x7c\x93\x62\x6b\xe6\x04\x1a\xb9\x19\x0f\x47\x30\x29\x80\x87\x5e\x67\x52\x67\x16\x9b\x99\xa1\x8f\xd8\x2a\xdc\x5c\x9b\x34\xaf\x7b\x09\xbd\x66\x38\xe2\xa6\xd9\xe4\xa3\xce\x0c\xb3\x6f\x9a\x99\x9a\x60\x7e\xa2\x71\x87\x3e\x78\xbc\x81\xf6\x63\xa7\x56\xcd\xeb\xcf\x65\xc0\x14\x21\x2c\x90\xf8\x44\x4f\xfc\xe7\x12\x44\x7b\x4b\x2c\xd6\x31\x71\xbc\x9f\xe9\x08\xbf\xa3\x08\x89\x28\x20\x8e\xc6\x02\x71\x1a\x13\x39\x7a\x3a\x91\x64\x41\x60\xac\x1a\x82\xe4\x60\xe8\x6d\x35\x33\xb4\x2d\x68\xbf\x14\xef\xb6\xb9\xa8\xdf\xcf\xa7\x08\x89\x13\xc3\x93\x5b\xbc\x81\x42\xcd\x7e\x53\xce\xe2\x1f\xab\xc3\x35\x1f\x52\x11\x9e\x7b\xf3\xa2\xea\x0e\x72\x45\x48\xe2\x99\xac\xc9\x15\x78\x99\x5d\xf7\xc0\x4f\xe6\xe4\x44\x96\x82\xe1\x25\x92\x50\x4a\xdb\xe4\xdd\xcb\xe8\x28\x42\x78\x42\xc2\xb8\x05\x02\xf4\xa0\xf2\x8a\x10\x29\x01\x6f\xb6\x2c\x32\x83\x52\xef\x97\x34\x14\x21\x8a\x12\x1d\xf4\x78\x27\xaa\xd6\x62\x28\x77\x09\x00\x8d\x84\x36\x38\x7e\x5f\xf2\xbc\x9e\x00\xba\x0c\x2e\x0a\x3a\x8e\x6d\x26\x03\x8b\x6b\x53\xdc\x30\xbf\x0d\x1e\xbb\x47\x13\x43\xe9\xc4\x95\x32\xfd\xa7\x53\xbe\x86\x22\x9e\x4f\x08\xf2\xa1\xec\x2e\x02\x13\x53\x13\x04\x97\x6e\x26\xf7\x9c\xee\xde\xae\x31\x52\xa5\x33\xc9\x3f\x80\x9f\x47\x9f\x8a\xfb\x1b\xc3\x0b\xa8\xc4\x72\xd4\xfa\x74\x86\x32\xe5\xd9\xa2\x04\x95\xd6\xfd\xd7\xe6\x05\xd2\x10\xbb\xc3\xb8\xcc\xd3\x8c\x29\x23\x3a\xfe\xc7\x62\xb9\x77\xf3\xc3\x58\x60\x50\x84\x1c\xb1\x46\x5c\x3a\x03\x85\xb9\xff\x26\x8e\x77\x44\xb1\xf3\xeb\x4d\x65\xb1\xf9\xb0\x8a\x5d\x65\xcf\xd1\x65\xd6\x55\x7b\x65\x6d\xc8\x89\x1f\x8b\xb2\x7e\x79\x2a\x32\xe8\x37\xcf\x28\xe2\xb1\x28\xc6\x3e\xd9\x92\xa7\x15\x2c\xf9\x95\xb6\x03\x89\x34\xa4\x50\x85\x7c\x35\xd5\xb8\x9e\x13\x88\xe3\x06\x14\x80\x31\xfc\xe1\x69\xbb\xdb\xbb\xc6\xdd\x66\x10\x0c\x95\xde\x5b\x7a\x36\x14\xef\x4e\xcc\x5b\x11\x2f\x92\x54\x74\x32\xfc\xae\x46\xde\x63\x78\xc7\x39\x26\x87\xc8\x25\x12\x7e\xdd\x8d\x62\xac\x66\x06\x50\x62\xe0\x0d\xa8\x3b\xd6\x6f\xae\xf8\xd4\x76\x78\x91\x36\x3c\xe9\xff\x73\xa9\xea\x6d\x6e\xd6\x5e\xfb\xa3\x63\x66\xd0\x8a\x69\x9b\x48\xda\xb5\xe7\x5c\x76\x6d\x67\x71\x42\x8c\xdc\x86\x02\x38\xcd\xa1\x43\xab\xbb\x09\x4a\x60\x4d\x8a\x1b\x45\x8c\xe1\xeb\x4a\x62\xe9\xdb\x52\xf7\xdd\x25\xc7\x25\x6a\x00\xb0\xc8\xd3\xdd\xdf\x28\x5e\xa2\x28\x32\x10\x6f\x9e\xdb\x95\xc2\x99\xd1\x76\x44\xab\xdc\x41\x3a\xd3\xf6\x14\xf0\x78\x62\xa8\x7e\xe7\x69\x3d\x4b\xcb\x61\x3b\xcd\x2f\xf9\xb7\x9b\xcf\x0b\x8a\xcd\xcf\xae\x9c\x5e\xaa\x4f\x98\x6d\xff\xdd\x33\xe7\xc2\xe8\xc8\xae\x17\xdb\xfe\x01\xec\x89\x30\x0c\x6d\xca\x0d\x59\xac\xf9\xc5\x6a\x29\xb9\x71\xa1\xa4\xd5\x78\xd9\x96\x5c\x66\xe0\xb8\x47\x5b\xba\x9f\xe1\xf7\x48\x92\xe0\x29\x7d\x77\xf9\x2b\xcd\xeb\x62\x88\xda\xfd\x00\x9f\xae\x88\xd7\xac\x8a\xd0\x66\xe2\xf9\xd1\x36\x2b\xdf\xec\x5b\xc5\x04\x02\x10\x4c\x5b\xdb\x56\xbb\xfe\xeb\xf6\xc1\x03\x55\xd8\xfd\xe5\xd4\x01\x78\x9a\x77\x63\xd2\xa0\x17\xd2\x53\x73\x72\x5b\x98\xde\x94\x8e\xab\x9d\xaf\x03\x83\xb5\x7d\x29\x2e\x65\xb5\x4b\x73\x09\x5d\x9d\x69\xf8\x9b\x75\xa0\x91\x02\xac\xaa\x8b\xb3\x71\x2e\x76\x2e\xca\x6c\x46\x99\xaf\x6d\xda\xb6\xa3\x18\x35\x63\x94\x04\x1e\xaa\x19\x70\xf5\x96\x56\x45\x59\xdd\x50\x3c\xe0\x1c\x6a\xc2\x29\xc8\x52\x9b\xe3\x6b\xfe\xca\x8d\x74\xdd\xb1\x89\x93\x9b\x85\x78\xdf\x9a\x3e\x4a\x94\xf4\x7b\x9c\x3b\x50\x55\x7d\x09\xa6\xfe\x73\xa7\x5e\xe0\x83\x72\x89\x54\xbd\x2f\x2c\x98\x7f\xf2\x04\xa0\x1e\x53\x08\xcd\xfb\xc3\xfe\x8f\x44\x5f\x46\x13\x54\x8c\xd5\xc7\xc6\xe3\x16\xbc\x72\x8f\x80\x52\x22\x3c\xe9\xdc\x5d\xcb\x04\x7c\x3a\xdf\x78\x58\x94\x86\x80\x55\x7f\x14\xb4\x7d\x5e\x1c\x96\xab\xa7\xed\x6e\xbd\x3f\x3c\x8d\x48\x5e\x15\xa1\x7e\xc4\x31\x0b\x84\xb1\xfb\x43\x5a\xf7\x49\xcb\x9a\x61\x45\x85\x93\xd1\xcd\xb8\x71\x72\x17\x2f\x50\xf5\xf2\xf9\x38\xcb\xa7\xf6\xbe\x56\xb9\x42\x6a\x26\xf3\xfe\x46\xf7\x15\x44\x2c\xd6\xb6\xe9\xed\x82\x19\x0a\xe4\x7e\xef\x09\xf2\x0f\x9f\x6a\x20\x15\x22\x15\xd0\x30\xdb\x1e\xb1\x65\x5a\x82\xbc\x95\x20\xef\xff\xcb\x82\xd1\x03\x0f\xa9\x21\x41\xb8\x07\x4b\x14\xae\xe0\x27\x54\xfb\xe2\xc9\x58\x5c\xf7\x33\x22\xea\x61\xa7\x96\xe3\xf2\x6d\x6b\x13\x76\x3c\x26\x04\x31\x16\xe2\x72\xb5\x9c\x8d\x93\x4c\xd8\xcd\x4c\xc6\x85\xed\x97\x59\xd9\x6a\xd8\xb8\x10\xd1\xcc\x8a\x42\x74\xc0\x5c\x98\x63\x99\xf5\x9a\x11\xce\xa8\xe9\x03\xe5\x46\xa4\xf6\xf0\xe6\x75\x83\x92\x62\x4c\x86\xbc\x45\x7f\xb7\x7f\xd5\xa1\x0b\xfd\xd1\x58\xdc\x15\x25\x36\xe5\x0e\x9f\x44\x12\x09\xf4\xac\x5a\x76\x81\xf4\x74\x39\x7d\xa4\xbf\xd3\xcc\x8f\xa9\x95\x2e\xb3\x31\x85\xfb\x3b\x0f\x9d\x64\x97\xc5\x7e\xa2\x28\x3a\xcf\xd5\x75\x74\x05\x1e\x68\x84\x52\x09\xd9\xee\x2b\xce\x14\x3a\xf7\x78\x9f\x0f\x45\x7e\x5c\xfd\x84\x52\xa6\x55\xe7\x6c\x0d\xd1\xaf\xbf\x0d\x1e\x75\x6f\xec\xb7\xd1\x57\x25\xb1\x53\x44\x5d\x22\x2c\x08\x6b\x08\x8e\x95\xce\x4e\x12\x1e\x0b\xfd\xb6\xcd\xc8\xa6\xaa\xda\x04\x5d\x33\x21\x89\x90\x7b\xaa\xb7\x0a\x4e\x45\xdd\xfd\x74\xa1\x3d\x84\xe9\x55\xe7\x34\xdf\xbf\xc0\x8f\x17\x80\xac\x1b\x8b\x31\xa4\xb4\xda\x68\xc6\x23\x18\xf8\x03\x54\x06\x86\x22\xd0\x32\xc5\x62\xa7\xae\xa1\xfc\xe8\x1d\x17\x54\xc6\x12\xeb\x5f\xe6\xe0\xc2\xe0\x68\xf4\x5c\xa5\x64\x89\x6b\xda\xfc\x31\xa4\x57\x52\x84\x2a\x12\x5b\x55\x8c\xce\xcd\x1d\x14\x94\x9a\x39\x9e\xef\xdc\x46\xd3\xa8\xd6\xc2\x6e\x62\x37\xc3\x8f\x11\xbb\x35\x3b\x17\x59\x56\xec\xe0\x5c\xc3\x69\x8e\xe2\xe9\x2e\x03\x38\x6d\xe0\x54\x60\xc0\x8e\x26\x61\xfd\x11\xf1\x75\x33\x31\x34\x82\xf3\x15\xd4\xb3\xb2\x5e\xbd\x4d\xb4\xdd\x35\xb3\xb8\xa9\x8b\x1d\xbb\x72\x21\x66\x3d\xba\x77\xa2\x94\xc4\xbe\x20\x8b\x80\x37\xd9\xa8\xdf\x3a\xd2\x0d\x45\x28\x78\x01\x02\xeb\x5d\x3b\x80\x7d\xf3\x55\x77\xc2\x50\x08\x25\xa6\xb6\x4e\xb5\x5c\xf2\x34\xbb\xee\xce\xbd\x75\x03\xb1\xc6\xf4\xfc\x66\xfb\xf8\x6d\xb3\x7a\xdc\x1f\x16\xeb\xfd\x9f\x87\xbb\xd5\xaa\x9d\xc0\x0d\x13\xef\xf2\x22\x5f\xfb\x1e\x34\x05\x29\x90\xdc\x66\x2b\xd2\x1a\x79\x05\xd2\xfc\xe7\x60\x82\x0e\x03\x86\xcc\x90\x69\x96\x71\xe3\xe6\xdc\x71\xd9\x92\x54\x36\x33\x62\x91\x38\xe6\xe0\xf3\x39\x4b\x0d\xc7\xde\x0d\x07\xd8\xe8\xe9\x6a\x69\x7a\xed\xde\x55\xfa\x66\xc0\xa6\xb6\x09\xc5\xa3\xf6\x0d\xfb\x84\x92\xd0\x00\x82\xde\x79\xa9\xfa\x8a\x33\x8a\xf8\x9e\x1f\x11\xd1\x75\x7a\xdb\x70\x6b\xb0\xd0\x7c\x2f\x64\x61\x1f\x5d\xb8\x74\xbd\xb2\x56\x72\xb2\x3b\xeb\xdb\xbe\xb4\xe6\x53\x82\x23\x83\xc3\x43\xfa\x3a\xb1\x98\x3e\xf5\xc0\x7c\x4f\xc5\xe8\x49\x1e\x5c\x12\xb6\x2f\xf6\x3a\x55\x1f\x50\xc4\xa7\x1c\x30\xa1\xa4\x0a\x87\xe5\x1c\xe4\xeb\x14\xf1\x7d\x19\x20\xec\x8b\xab\x1b\xd9\x8e\xfe\x5a\xf4\x7d\x2b\x00\x8d\x29\xa9\x47\x7e\x6a\xb7\x93\xef\x03\xc3\x46\x83\x73\x09\x8e\x59\xf8\xb3\xf2\x78\xf3\x09\x9d\x78\x03\x71\x00\x00\x85\x67\x61\x3f\xe7\xe0\x07\xa1\xcf\x4c\xf4\x72\xbc\x4b\x33\x58\x64\x05\x86\x08\x23\xc7\x77\x62\xdf\xf8\x21\xd3\x58\x15\x31\xdb\xd0\x62\x86\x31\xac\x75\x47\x9e\x1f\x0a\xc0\x0e\x18\x6c\x12\x98\xd4\xff\x69\xef\x23\x84\x00\xbb\xc4\xb1\x4c\x7a\x80\x4a\xf2\x33\x0c\x4f\x17\x9f\x11\x93\x95\x50\x25\x4f\xf3\x41\x67\x56\x33\x48\x19\x06\x92\xc6\xe9\xc4\x12\x10\x8c\x57\x13\x13\xa6\x87\xf6\xd0\x56\x31\x26\x17\x5d\xc4\x28\x16\x2d\x8a\x3c\xbb\x3a\x19\xa7\x6d\x69\x1b\x6a\x26\x1b\xdc\x7e\xeb\x6c\xab\x1f\xc5\x8a\x38\x0d\x6f\xe0\x95\x13\xb6\x9d\x0e\xae\xfd\x38\x21\x98\x13\xb8\xcb\x8a\x92\xdf\xa5\xb2\xbf\x73\xfd\x24\x11\xe8\x3d\x41\xae\xc6\xd5\x5c\x45\x7c\x11\x78\x08\x3c\x12\x98\x35\x19\xe6\x56\x7c\xa1\x8d\x7c\xe1\xf3\xec\xf1\x7e\x85\xa0\x8c\x43\x7b\xc4\xfb\x32\x36\x8a\x07\xcd\x6a\xcc\x8f\x90\x8d\x9e\xb3\xd4\x3a\x31\xbf\xe0\x6d\x83\xa4\x01\xcf\x6e\xfb\xae\xf6\x5f\xe7\x2d\x36\x50\x11\x5f\x85\x14\xbb\xf4\x4a\xae\x75\x06\x4b\x07\x18\x6d\x46\x12\x86\x01\xc6\x89\x57\xaf\xeb\x49\xc9\x27\x45\x7c\xf0\x08\xb2\xf4\x6d\x9f\x67\x8b\x87\xf5\x7f\x56\x87\xfb\xd9\xce\x60\x97\xee\x7f\xac\xfe\x74\x97\x02\x9f\xe0\x6b\xaf\x8a\x13\x6c\xa0\x7e\x29\xd4\x4d\xf1\x60\x7c\x5d\x16\x23\x26\xfc\x7b\x91\xbd\x56\x35\xb4\x8e\xbc\x0f\x89\xc0\x66\x89\x87\xe2\xf8\x0c\x12\x52\x03\x10\x1a\x96\x9a\xe3\xf1\xc5\x12\xad\xcd\x49\x78\xa9\xf6\xc5\xa5\xbc\xa9\xe5\x75\x53\xb5\x36\xc5\x0b\xb3\x23\x1c\x2e\xd5\x0c\x06\x5e\x10\xa3\xf4\xe2\xc9\xa9\xbf\xb9\x01\x4a\x18\x46\x17\x8b\xe7\xed\x6e\xe7\x8a\xd1\xed\x20\x8f\xb0\xe1\xf0\x74\xc9\xea\x74\x07\xb9\x9a\x4d\x2f\xa4\x80\x4a\x40\x27\xd9\x41\x7f\x6b\x6e\xb9\x5c\xab\x79\x71\x39\xbe\xd4\x1d\xe3\x99\xfd\x80\x4f\x8c\x36\xdc\x2c\xcf\xe1\x27\x1c\x76\xdb\xc3\x72\xfd\x7d\x76\xd8\xcd\x76\x56\x57\xa3\x99\xe3\x49\x0c\x8a\x0e\xc5\x19\xf2\x79\xf1\x73\xf8\x7b\x03\x3f\x94\x58\xde\xb2\x98\x22\x43\x2f\xdd\xda\xdb\x0f\x0a\xa4\xd3\xef\x2c\xf0\x1b\x27\x13\xf7\x3f\xc2\xcc\x83\x2f\x3d\xbe\xff\xd1\xd4\x10\x3c\x7c\x23\x87\x14\xf9\x59\xdd\x9a\x0f\x18\x61\x48\xb7\xc4\x95\x9a\xc3\xad\x0f\x3f\xb9\x06\x83\xc8\x03\x6c\x15\x78\x00\xc3\x6a\x53\x8d\x6d\x77\x10\xf9\x11\x06\x29\x7f\x5e\xfe\x79\xb9\x94\x3c\xfb\xa7\xc8\x8a\xba\x38\xb8\x54\x48\x10\x25\x86\xe2\x59\x5c\xca\xfc\x5b\x5e\x15\x99\x9a\xb2\x2a\x41\xc4\x4d\xc6\xe4\xd8\x38\xed\x50\x1e\x21\x97\x57\x57\xcb\x1e\xa9\xe2\x0c\x3f\x18\x93\x08\x61\xec\x5f\xa1\x2c\xf2\xb4\x4d\x0f\x05\xb1\xa7\x63\xeb\x84\x59\xed\x9e\x3d\x94\xa7\x6a\x4c\x34\xea\x66\x0b\x83\x44\x48\x73\xdc\xf2\x3d\x12\x89\x66\x50\x99\x7e\xdf\x23\xd4\x5b\xad\xad\xff\xe3\x06\x79\xe0\x39\x99\x80\x25\x1c\x4b\x80\x61\x0e\x27\xe0\x01\x13\xa4\xc5\x4a\xd4\x97\x12\x56\x3f\xcf\x3c\xaf\x9a\x33\xfa\x93\xae\x6c\x45\x02\x41\xbc\xc4\x36\xcf\x19\x2f\xf6\x19\xaa\xe2\x52\x4a\x98\x80\xbe\x37\xd3\xb5\x4c\xcc\x83\xbe\x42\x79\x38\x73\xe7\xbf\x04\x32\xf1\xbc\xd0\x91\x3c\x5c\x79\x56\x5f\x51\x2b\xb0\x1a\x7d\x5e\x8a\x00\xb9\x20\x9c\xeb\x7d\xe0\x59\x76\x98\x94\x3d\xb4\x1f\x50\x94\x61\xc6\xc0\x14\x1a\x77\x75\x69\xc2\xee\x89\x1a\x40\xa0\xa8\xa9\x8f\xcf\x33\x2e\x5f\xb3\xb4\xea\xb7\x99\x8f\x6e\x43\xc5\x26\xad\xc9\x5b\xbd\x95\x43\x89\x50\xf1\xa7\x8c\xd7\xba\x28\x4f\xae\x17\xa1\x99\x2b\x54\xcb\x69\x88\x77\x1a\xb8\x11\x08\x43\xcc\x93\x6c\x56\x33\x27\x64\x65\x47\x34\x31\x08\x8d\xa7\xb4\xaa\x53\x29\xd3\x85\x63\x3a\x6f\xc6\xc0\x23\x51\x5f\x23\x62\xa6\x9c\x41\x08\x49\x90\x60\x35\xd2\x21\x00\xa9\xdd\x83\x34\xf8\x6d\xf0\xaf\x7b\xf1\x21\x09\x43\xa3\xdd\x7d\xc9\x5e\x5d\x8e\xe7\xa9\x98\xdd\x30\xdd\x4e\xec\xe1\xd0\x0b\x02\x87\xa3\xde\xf0\x57\xe8\x2f\xb8\xd0\x63\x0c\x99\x72\xf4\x4d\xcb\x3f\x0e\x0a\x5c\xf5\x27\xfe\xd3\x26\x87\x06\x79\x98\xd0\x53\xa6\x47\x0f\x75\x0e\x6f\x50\x1a\x76\x12\xd5\x42\x3b\x8a\x37\x23\x6c\x3c\x51\xdc\x57\x24\xf4\x13\x4f\x19\xdd\xa6\x53\x9a\x1f\xfa\x94\xe7\x9f\x75\xe7\x2a\x12\x06\x24\x42\xc7\x67\x07\xf5\xae\x86\xb3\x4b\x5f\xfe\x28\xf9\xf9\xfc\x51\xb8\x12\x06\x94\x61\x22\xf9\xe0\xa0\xf6\xa6\xf5\xbe\x97\xbf\x70\x13\x99\xe1\x93\x3d\xa5\xd8\x5b\x6d\x8a\x5c\x69\x7e\xec\xaf\xb9\xcf\x8c\x5e\x18\x24\x8c\x7c\xc4\x39\xfb\xaf\xdc\xe4\x30\x90\xca\x82\xd7\xd4\xbc\xe0\xa5\xda\xb5\xcc\xec\x1e\xf9\x6d\x58\x11\x98\x5c\x0e\xbf\x9a\x65\xbf\x86\x25\xc2\x2d\x93\x1f\x69\x6e\x14\xbe\x47\x86\x35\x64\x4d\xac\x6a\xd2\x38\x35\x2c\x0a\x35\x3a\x95\xc3\x28\x36\xd9\xc6\xdd\xe6\x7e\xe1\x56\x49\x1c\x11\x44\x75\x23\x9d\x4f\x7d\xc8\x3a\x72\x0c\x45\xc2\x84\x08\xae\x7a\x1d\x0f\x36\x35\xb7\x2f\x1a\x33\x3d\x6d\xca\x42\x11\x49\xac\x9d\x5e\xb0\x16\x8b\x12\x5a\x13\xce\x44\x28\x78\xa0\xac\xdc\x92\x15\xaa\xda\x17\x56\x62\xb9\x0f\x58\x1a\x7d\x4a\x46\x26\x61\x57\x71\x0d\x9b\x4b\x36\xed\x01\x84\x32\xf1\x0d\xa6\xa1\xd9\xdc\xfb\x41\x0c\x18\xca\x84\x2b\xdb\x76\x82\xd5\x66\xa3\x50\xf2\xc6\xd3\xac\x79\x00\xb7\xaa\xa6\x53\xa8\xa6\xe6\x32\x22\x0c\xc2\x96\x28\xa6\x9c\x14\x2f\x51\x24\x54\x49\x82\x75\x96\xfd\x1f\xcb\xd5\xc3\xcc\x39\x72\x21\x48\x26\xad\x99\x46\xff\x3c\x18\xbd\x28\x00\xd3\x01\x5f\x03\x3f\xcd\x06\x3e\x52\x08\x5a\x61\x1e\x55\x61\x7a\xae\x28\x67\x76\x80\x11\x12\x22\xc0\x65\xb6\x6c\xff\xc2\x29\x32\x66\xab\x62\x77\xe2\x59\x86\xe1\xd8\xbf\xc0\x05\x28\xc2\x3c\xc2\x31\x89\x8e\x2d\x47\xe7\x22\x1b\x13\x9c\xfd\x8b\x2b\x44\x1a\xbb\x37\xb7\x9b\xf5\xaf\xfd\xa0\xc1\xa3\x65\x54\x46\x48\xec\xb5\xc8\x80\xe7\x73\x9e\xbf\x42\xb9\xe0\xb9\x4a\x5b\x52\x19\x7b\xd2\x30\x9f\x78\x68\xe0\x0e\x87\x12\xaa\x22\x7b\x1b\x2d\x77\xe6\xeb\xd0\x06\x52\x0f\x69\x5d\x63\x8b\x7b\xca\xf3\x1e\xea\x4c\x11\x16\x50\xa6\x2c\x87\xda\x1b\x94\xf5\xb7\x4a\xed\x0b\x4c\xd1\x8e\xae\x15\x44\x1a\xf3\x70\x07\xe7\xd1\x8a\xfa\x63\xbf\x8c\x85\x41\xe0\x3c\x9c\x45\x91\xb6\x75\xca\xbe\xe9\x62\x61\x1c\xa3\x6d\x7f\x30\x3c\x5f\xcb\xb9\xbd\xb1\xc9\xcc\x2a\x63\x32\xc6\xa2\xab\x65\xff\x98\x5f\xae\x98\x18\x76\x36\x7b\x72\xf5\xb1\x88\x11\x65\xb8\xe8\x1b\x7b\xb8\xd5\xdb\xf2\xf8\xa5\x1d\x62\x58\x90\x6c\x39\x8b\xb2\xa2\xfa\x80\x19\xff\xa6\xdf\x62\xf4\x25\x49\x8c\xde\xb3\x2e\x2e\xe5\x3b\xc0\x6b\xd5\x7e\x45\xa2\x0c\x6d\x21\x4c\x4b\x60\x28\xc2\x62\x3f\x40\x57\x17\x0c\xb0\xec\xf9\xd2\x6c\xff\xd9\xe8\xd1\x27\x34\x32\x30\x72\x7e\x82\xea\x01\xf4\xc8\x8b\x60\x49\x6c\x78\xf2\x1e\x8a\xe3\xd7\x42\x65\x56\xbe\xf3\xf3\x63\x89\x25\x31\x75\x89\xe3\x25\x9c\x2e\x65\xe3\xf0\xce\x6e\xc8\x07\x9b\x89\x89\xc4\x8c\x50\x13\x28\xdf\xc1\xaf\x60\x06\x8c\x13\x1d\x3a\x68\xc6\x35\xe7\xa7\x54\x2e\x20\xc5\x5f\x75\x8b\x8a\x6d\xa6\x87\x46\x49\x1c\x05\xe5\x66\x59\x66\xfd\x65\x7c\xcc\x83\xd5\xc2\xe3\x84\x9b\x28\xf2\xe7\x43\xdf\x44\x33\xe1\x83\x21\x16\x7a\xe1\xf2\xb5\x39\xf9\x8a\x22\x6b\xc7\x82\x00\x4f\xc7\x3f\x7f\x5f\x4c\xd6\xb5\xa6\x4e\x7a\x26\x98\x8e\x3a\xfd\x56\x57\x6b\xed\xe3\x60\xdd\x44\x6e\xb4\xe7\x7f\x94\x50\xd5\x19\xb4\xa8\x25\x45\x98\x0c\x03\xdd\x35\x51\x3f\xc2\xcf\xba\xeb\x74\x68\x86\x23\xc3\x81\x5f\xa5\xc7\x9c\x67\x7d\xf3\xcc\x64\xe2\x61\x0a\x12\xa3\xbc\x2a\x3d\x9a\xbd\xe8\x06\x39\x65\x1d\xa7\xa3\x32\x9e\x72\xbb\xde\xa4\x92\x48\x87\xd9\x13\x7c\xb0\x02\xf4\x6e\x86\x0a\x0c\xc1\xfc\x5f\x2d\xd2\x87\xe9\x16\x08\x5e\xd5\x65\x71\xdd\x5c\x07\x0f\xca\x4d\x4a\x22\xbb\x92\xeb\x7d\x09\xbc\xba\x94\x13\x74\xfc\x8a\x44\x24\x92\x48\x7f\xf6\x04\x65\xe3\xbd\x36\xbb\xba\x2c\x46\xc5\xb7\x88\xc4\x80\x99\x82\x65\x21\x2f\x27\xc8\xeb\x05\x94\x75\x81\xc9\xca\x36\x91\x33\xc5\x8d\x33\x58\x0e\x91\xa7\x23\xd1\x13\x15\x1d\xc6\x21\x91\x2f\x43\xfc\x8a\xf5\xc6\x89\x28\xb7\x03\xa6\xdb\x74\xf7\x6d\xb1\x58\xed\x76\x87\xbb\x87\xd9\xbd\x1b\x0b\x02\x13\x13\x2c\x81\xd7\x2f\x26\x2d\x7a\x48\xdb\xc1\x88\x27\x16\x4a\x74\x5f\x64\x0a\xdd\x2d\x80\xe1\xd1\x14\x05\xdc\x8f\x1d\xd0\xd0\xa5\x05\xdc\x90\x82\x58\x5a\xef\x3d\x95\x45\xfb\x67\x4d\x31\x5c\x79\xfa\x3a\xdb\xad\x0e\xde\x01\x53\x1e\x6e\x30\x94\x1e\x16\xe1\xde\x52\x78\x7f\x2c\x72\x59\xf1\x56\xf4\x64\xb4\x8d\xa2\x28\xd0\x88\xff\xba\x5f\x3d\xee\xd6\x3b\xa3\x67\x7f\x58\x6c\xbf\x3d\xba\x1a\x78\x14\xc5\x1e\x96\x80\x54\xfa\x36\xef\x0a\x7d\x51\x1c\x1a\x75\x40\x83\x3d\x13\x50\x62\x8b\xf3\x15\xca\x6a\x9d\xdb\x0e\x8b\x7b\xde\xfd\x8c\x98\x31\xf4\x82\xab\xf4\x1f\x18\x92\x78\x28\x12\x25\x89\x00\xbb\x71\x9e\x8b\x0c\xa6\x32\xec\x11\x8f\x0d\x59\xe9\x73\x5a\xb5\xfd\x8c\x6e\x48\x1a\xe9\xe0\xa2\xe4\x32\x4b\xff\x81\xc3\xdf\x17\x28\xaf\xe3\x2d\x8b\x2f\xda\x51\x4f\x75\xdf\xcd\x15\x17\x7e\x2b\xea\x34\x88\x03\x22\xa1\x35\xb1\xef\x0e\x09\x4e\x47\xb7\x2d\x43\x43\xf4\x5e\xbf\xa4\xb9\xa1\x81\xb3\x03\x10\xa9\xc8\x16\x1b\xf7\xfb\xc5\x47\x62\x4c\xcd\xc4\x44\x3b\x8e\x92\xff\x29\x44\xd5\x8f\x60\x22\x4d\x13\x14\xaf\xe1\x4a\xd9\xce\xda\x96\x0d\x74\xd2\x30\x37\x6e\x03\x06\x24\xf7\x25\x40\x8e\x32\x32\x77\xbc\x3c\xb5\x97\xf3\x39\x16\x36\x9f\x0b\x61\x3c\x83\xa1\x6f\xf9\xdb\x44\x40\x1a\xe9\xd8\x43\xa6\x64\x97\x86\xb4\x75\xaa\xea\xd3\x88\x3c\xd2\xca\x00\x96\xb7\xb2\x2e\x04\x94\x1e\x3d\x50\xe2\x45\xf6\x3e\x62\x4f\xb0\xd8\x74\x46\xbd\x57\xdd\xdf\x12\x4c\x11\xe5\x50\xbf\x17\xe5\xab\xa1\x85\x75\x63\xda\xe8\xe3\xcc\x9b\x35\xe9\xdc\xc0\x98\x7a\x02\xa5\xb2\x05\xd4\x7d\xc7\x26\xa6\x51\x88\x27\xda\x8f\x22\xd3\x25\x3f\xcd\xb2\xf3\x0b\x6f\x3f\x13\x25\xc2\x50\x4e\xe0\x99\xb1\x2f\x2e\x65\xce\x7b\x75\xb7\x98\x02\x8f\x5d\x8d\xd8\x82\x66\x27\x5f\x5b\xec\x27\x61\x68\x08\x09\xfe\xba\x54\x86\x09\x0b\x71\x74\x76\x38\xd0\xcc\xb5\x49\xd8\xfe\x02\x13\xae\xd8\x07\x14\x87\xb1\x6f\x38\x0d\xd3\x13\x3c\x74\x99\xd0\x38\x14\x31\x7a\x7e\xfb\xf5\x66\xb5\xd8\xae\x1f\x47\xdf\x1a\xca\x18\x9f\x04\x82\x3a\xfa\x45\x8c\xf6\xf3\xc0\x30\x0d\x7f\x6f\x08\xea\xa6\x18\x19\x14\x89\x99\x1f\x22\x1e\x0c\x49\x65\xaa\x96\xd4\xd5\x5d\x84\xc5\x94\xfa\x2d\x60\x68\xb6\xff\xc3\x90\xb6\xb4\x3f\x8e\x71\x43\x42\xdf\x7c\xec\xd0\x18\xa4\xc9\x45\x10\x47\x8a\xc6\xb1\xeb\x74\xef\x72\xca\x71\x4c\x22\xd2\x6a\x9f\xde\xe8\xb0\x8e\x2e\x12\xeb\x90\xa8\xd6\xc6\x40\x59\x2c\x20\x53\xbc\xbd\x95\x24\xa0\x98\x63\x5e\xcd\x9e\x1f\xfe\x3c\xac\x1f\xbf\xaf\x76\xfb\xed\xf3\xe1\xc7\xec\xe1\x61\xb5\x6f\x27\x45\x3e\xba\x6b\x90\x1f\x4b\xfe\x06\x23\x01\xc0\x81\x71\x70\xa7\x40\x9c\x80\x87\x08\x1a\x9b\x64\x1d\x50\xfc\x29\x12\xf3\x28\xc6\xed\x6d\x3f\xb4\x2f\x76\x78\x91\x61\xce\xc2\xce\x15\x71\xa2\xad\xe0\x56\x13\x25\xed\xea\xe2\x7c\xee\x3d\x6d\x21\x4d\x9f\x77\x56\x1c\x9f\x41\x7f\xf0\x18\x84\x06\x6a\xd4\xbd\x6c\x38\x80\x2e\xe7\x4d\xa7\xa8\x22\xb1\x64\x46\x67\xd4\xa8\xda\x3c\x41\x59\x8d\xcb\xe5\xb1\x62\x86\x30\xc9\xf5\xb8\x0c\x38\x98\xdb\x39\x11\x16\xa0\x4f\xaa\x36\x61\xde\xc0\x2c\xc6\x40\x7d\xac\x9d\x1e\x8b\xcc\xd5\xe3\xf8\xb1\x7d\xc3\x9a\x4a\x16\x0d\xf2\x22\xb3\x91\x67\x98\x10\x42\x10\x94\xb5\xd8\x3e\x6c\x1f\x57\xcf\x7d\x63\x9e\x78\x5e\x82\x80\xb5\x53\x51\xd6\x47\x7e\x1c\xe5\xef\x12\x2f\x90\x78\x52\x3e\x43\x36\x90\x11\x6f\x86\x44\x88\x61\x41\x0e\x06\x8d\xdd\x85\x3e\x76\x82\x1f\x85\xae\x44\x89\x9e\x0e\xee\x00\x3c\xd3\x06\xaf\x3f\xf1\x93\x18\x8f\x23\x97\xab\x59\x2c\x9f\xa6\xdf\x4c\xe2\x03\xc1\xb3\xf1\xcc\xaf\x13\xdc\xf7\x8a\x24\x01\xe1\x88\xb9\x12\x5d\x01\x21\x09\x98\x42\x3c\x6d\x65\x7a\x7a\x36\x69\x0e\x25\x1f\xd5\x4f\x92\x20\xd1\xd8\x91\xf2\x6d\xfd\xb8\xa7\x21\x3b\x6c\x66\x7f\xb4\x9f\x57\x8a\x5a\x18\xc5\xc3\xc3\xf7\x03\xa8\xb4\x3e\x78\x2e\xa7\x97\x84\x91\xa9\x61\xb9\x04\xe5\x23\xd4\xeb\x5c\x16\xed\x49\x9c\x84\x2a\x48\x8c\x88\x5d\xa1\xd3\xda\x07\xc7\x4d\xd3\x0c\x81\x21\x54\x4b\xf3\xb4\x4e\xb1\x04\xbd\x29\xd4\x25\xeb\xf5\x83\x8d\xf2\xda\x09\x8b\x0c\xed\xd5\x9e\xe7\xaf\x3b\xc8\x32\x2b\x99\xed\x46\xe3\x50\xb8\x74\x75\x5e\x97\x29\x0c\x4e\xb8\x84\x89\xd8\xaa\x86\xd4\x97\xf3\x33\x96\x7f\xdc\x50\xe4\x73\x6c\x20\x1a\xa8\x4e\x56\x77\x65\x71\x9a\xac\x00\x76\x0f\x3c\xf6\x0c\x6b\x4f\x05\x4d\xdc\x7a\x82\x9b\xdd\x9b\xc4\x54\x43\xcb\x8b\xd3\x98\xdf\xe5\xa5\xe4\x3d\x33\x9a\xc4\xbe\x01\x1d\xe3\x84\xe7\x66\xa8\x7d\x40\x71\xec\x61\x17\xf9\x66\xf6\xf8\x75\xb6\xdf\xcf\x1e\x9f\x9e\xb7\x7f\xfc\xb9\x99\x2d\xd7\xbb\xed\xe3\xac\xad\xb8\x24\x49\xe8\xe1\x4a\x33\x46\x74\x93\xe6\x63\x76\x0e\x9c\x23\x7c\x63\x68\xf5\xa5\x25\x6a\xb9\x7d\xc2\x9c\x71\xc4\x72\xb8\x27\xd1\x23\xd6\x50\x24\x11\x84\xa3\xd3\xff\x0c\x3c\x5b\x55\xbd\x73\x33\x91\x22\x26\xa6\x4f\xdd\x7a\x63\x03\x30\xeb\x30\x46\x4e\x14\x10\x44\x7c\xa4\xb9\x2c\xa1\x77\x24\x26\x40\x3d\xdc\x0a\xe9\x31\x2f\x4a\xbb\x4f\x82\x9e\xc5\x49\xc0\x0f\xa9\x4d\x0a\x35\x96\xe4\x52\xad\x47\x0b\x19\x38\x98\xf6\xe2\xc5\x6c\x33\xd8\xae\xa0\x34\xba\xda\x6d\x0a\xbb\x5d\x36\xa0\x69\xe0\xf5\x08\x39\x46\x0f\x4e\xc7\x21\xf6\x35\xa0\x46\x5d\x9a\xb7\xbf\x58\xc7\x11\x12\x9c\x7d\x87\xfc\x52\x7d\x12\xb5\xb5\xd3\x05\xa2\xe0\xb9\x52\x7f\xfc\xf9\xef\xb2\x3b\x09\xd2\x1f\x59\x30\x88\x2d\xea\xba\xf5\x58\x4d\x84\x35\x89\x16\x12\x1f\x1f\xb2\x8b\x19\x3f\xd0\x78\xe2\xc5\xc7\x4c\x1a\x93\x6f\x88\x93\x50\xbb\xd6\xc4\xf5\x61\x37\x7c\x22\x9c\x30\x8d\xa4\xfa\x32\x2b\x72\x40\x88\xcc\xe4\xe6\xe0\x1e\x57\x3a\xb0\x44\x02\x88\x97\x9c\x40\xa1\x70\x1a\x05\x56\x1b\x81\x9f\xcc\x62\x73\x35\x5f\x4e\x15\xc7\xec\xfe\x31\x7d\xbb\x05\x0e\x4c\x3c\x63\x4e\xb5\x81\xd4\x1e\xa1\x9e\x65\x99\x63\xe6\x72\xdb\x89\x07\xa1\x01\x5e\xa1\xa6\x12\x8a\x24\xae\x4f\x67\xb3\x6b\xf9\x20\x8f\x3c\x29\xd7\x39\x4e\xf4\xf2\x80\xc7\x9e\xcd\x20\xec\x91\x11\xb8\xf1\xc9\xcb\x71\xd3\x8b\x22\x3c\x64\x14\x4d\xe0\x3d\x18\x6a\xd5\xfd\xf5\xec\x04\x29\x10\x19\x3b\xee\xc0\x6e\x3e\x12\x25\x56\x48\xd8\xc9\x0b\x22\x9d\xe3\xba\x47\xc1\xf1\xdf\x51\x68\xc1\x43\x10\x81\xcb\x07\xf0\x34\xb7\x20\xab\xe1\xad\x30\x2f\xb1\x64\xb0\x59\x76\xf8\xe0\xb5\x31\x1a\x22\xd1\x05\x37\x4b\xce\x60\x03\x3f\x7a\xc7\xcc\x67\x88\xd4\x69\xb7\x32\x42\x77\xe7\x25\xcf\xa5\xcb\x7c\x70\xa6\x8d\x98\xd3\x43\x71\xb4\x76\x67\x31\x68\x11\x9b\x5e\xfd\x9c\x69\x1e\xb6\x20\xa7\x54\xc2\xfc\xba\x56\xc3\xa3\x93\x47\x22\x60\x91\x43\x4b\xf1\x63\x91\x2f\xe1\x6d\x63\x13\x12\xa3\x5f\x1e\x53\x53\xb2\xae\xa0\xfe\x91\x66\x4a\xf2\x52\x0d\xd2\xd7\xb7\xdb\x89\xc7\x7e\x88\xe4\x92\xe2\x72\xdd\xbd\xa4\xe7\x01\x08\x85\xc7\x32\x46\xc7\x54\x57\x48\x21\x66\xff\xca\x89\xef\xd9\x6f\x59\x14\xa7\x73\x0d\x07\x3f\x1e\x64\x13\x39\x0f\x48\xd4\x3f\x30\x4d\xde\x64\xe4\x3b\x8f\xff\x75\xe6\x99\x73\x19\x22\xfa\xb0\xd9\x2d\xd8\xce\x3a\x4e\xf6\x70\x41\x08\x63\x2e\x0d\x96\xc1\xcf\x54\x64\x13\x6a\x50\xcd\xc4\x20\x06\x03\x36\x9f\x3b\x49\x9b\x2e\x7b\x88\xff\x6f\xf8\x00\x45\x1c\xf8\xb4\x2f\xfe\xde\xd3\xa8\xba\xe9\x8f\x55\x84\x4b\xe2\x71\xeb\xf9\x61\x81\x76\xf5\xf3\x9c\x96\x23\x2c\x24\x97\x94\x86\xae\x51\xe3\x25\x3d\xdb\xe6\xfa\xe1\x93\x56\x91\x61\x3a\x16\x97\xab\x69\xf0\xfb\xd2\x3e\x95\xd1\x2d\x2a\x88\x90\xa9\xc6\x95\x03\x2f\xae\xd3\xfb\x76\x71\x41\xe0\x87\xcc\xc1\x93\x91\x0f\xc1\x9c\x27\xd3\x27\x16\x87\x84\x3b\x37\x76\x93\xe6\x96\x6c\x76\x78\x45\x6d\x09\xb9\x50\x25\xd8\xb4\xed\x3a\x63\x3d\x19\xd6\x09\xe2\x01\x43\x2d\xa3\x43\xe3\x1c\x77\x04\xce\xe3\x69\xd4\xd4\xea\x4d\x3e\xdb\x88\x4c\x36\xd6\xea\x5b\x9e\xd6\xfe\x17\x37\x89\x69\x74\xfc\x32\x5e\xd5\x4e\x3c\xd5\x0d\x49\x82\x89\x73\x23\xe2\xb1\xb4\x1d\xfd\x03\x50\xb3\xf0\x62\x8d\xe8\x33\x77\xea\xcf\xaf\x77\x45\xf9\x39\x9f\x6f\xf3\x29\x61\x68\x3f\xee\xfe\x18\x24\xaf\x04\x15\x61\x64\x90\xfd\xa0\x7a\x38\x52\xe1\xb3\x18\x33\xa0\x5c\xa9\x7d\x61\x0f\xb4\x71\xcf\x7b\x33\x4d\x71\x34\x97\x7f\x15\x23\x1d\x78\x3b\x1e\x44\x26\x1c\x46\x4a\xe2\xff\x8f\xb3\x2f\xeb\x6e\x1b\xc7\xba\xfd\x3b\xf5\xd0\x0f\x04\xc0\x09\x8f\xb2\x2c\x3b\xbe\xf1\xf4\x49\x4a\xd2\x75\x7b\xf5\xd2\xc2\x70\x60\xf3\xb3\x44\xaa\x49\xca\x8e\xea\xd7\xdf\xc5\x83\x81\x83\xe8\xa4\xfa\xbe\x94\x53\x22\x44\x71\x00\x0e\xce\xb0\xcf\xde\x9b\xc5\xfd\x6a\xb3\x5d\xdc\xae\xfc\xae\x21\x13\x4a\xfc\x9b\xbd\x3b\x9a\x66\x48\xaf\x35\x7e\xa9\x32\xe1\x39\xfa\xae\xd8\x48\xfd\x5c\xc3\xdd\xf2\xe9\xf9\x24\xf7\x85\xf2\xa7\x4a\x73\x0b\x8e\x39\x57\x95\x14\xa3\xbc\x8a\x1f\x20\x05\xfa\x00\x9e\xb7\x27\x1c\xc8\xe2\x3c\xc2\x55\x88\xb4\x24\xe1\xd3\x84\x39\x1b\x84\xea\x64\x9d\xf1\xb7\x9a\x8a\xf3\xd7\x97\x29\x81\x14\x21\xb6\x59\x72\x46\xe3\xf8\x1f\x83\xc2\x86\xfb\x4e\xce\xb4\xe4\x01\xf7\x39\x02\x9a\x8e\x4c\xa7\xcc\x53\x8d\x19\xbd\x1b\x51\x0b\xbd\x42\xa6\x28\x7f\x99\x9c\x38\x4d\xd3\xd7\xea\xe3\xea\x54\x97\x9d\xd7\x51\x4c\x53\x79\x92\xbb\xde\x84\x0f\x90\xec\x7b\x01\x1f\xeb\x6a\xbf\xff\x4c\x31\x76\xde\xc2\x4b\xce\xc1\x82\xdb\x7a\x3d\x91\x7b\x51\xea\x57\x14\xd7\xd8\x8a\x09\x76\x47\x72\x48\xd0\x85\xda\x34\xc7\xcf\xb8\x45\x2f\x10\x3b\x43\xdb\x2b\x39\x64\x9c\x06\x3f\xf9\xaa\xaa\xeb\xea\x03\xf4\x2a\xe4\xe8\xa5\x24\xb6\x66\xe7\xfa\xf9\x46\xf1\x83\x54\xc4\x6a\x86\x0a\xad\x1f\xaa\x12\x26\xa6\x4c\x2a\x9e\xb9\xf6\xa2\x1e\x5f\x7c\xda\x7f\x52\xf9\x94\x0a\x6c\x95\xd8\x51\x70\x5d\x09\xf5\x16\x16\x33\x72\xe9\xa1\x02\x83\xed\x78\xf6\x9f\x83\xe2\x99\x2d\x81\x9d\x90\x4f\x66\x98\x8a\x92\x26\xd6\xb8\xb3\x6f\x0e\xd5\x1b\xf8\x7c\xd2\x72\xb8\x84\x7e\x03\x6a\x9a\x5c\xa0\xe1\x09\xd6\xdb\x65\xab\xee\x83\x51\xf1\x57\x62\x8c\x05\xc9\xb6\x9d\xdd\x04\xdf\x24\x79\x2d\xdd\x71\x15\x31\xc3\x92\x41\x71\xe0\xbb\x38\xed\xdb\x70\x50\x31\x4c\x51\xe3\x6d\x8c\x71\x47\xe3\x05\xa0\x88\xca\x63\xe7\x01\xa0\x5b\x01\x3e\x6e\x19\x33\x40\x74\x23\x35\x41\xf8\x5c\x17\x9d\xba\x35\x7a\x0d\x8d\xaa\x8b\xe3\xc8\xb1\xbb\xa4\x0a\xd3\x91\xa2\x31\x70\xb7\x67\x3f\x56\xf6\x46\x51\xcc\x70\xa0\x5e\xa5\x23\xc5\x22\xe6\x64\xe5\x30\x7e\x76\x34\xa6\xfe\x20\xd5\x58\xe0\xac\x5a\x15\x04\x30\xe6\x6f\x89\x51\x40\x04\xe4\x06\x44\xad\x5e\x17\xf7\xf7\x37\xc5\x1e\x46\x85\x22\xc5\xb8\x21\x31\xba\x4b\x08\x99\x9f\xdc\x69\x4c\x28\xee\x44\xab\xc7\xeb\x27\xdf\x76\xea\x0f\xd1\x14\x9b\x3a\xe4\xa9\xee\x1c\xff\x90\x6b\xbb\xbb\x5a\x86\x21\x59\xe2\xb3\xbc\x96\xeb\x71\xd3\xd6\x85\x9a\x6c\x65\x2a\x51\x49\xee\xab\xde\xdd\xb9\x86\xe9\x18\x95\x28\x1e\xa7\x7d\x20\x79\x9c\x69\x44\x56\x59\x62\x09\xb7\xde\xa1\x2e\xcc\xd9\x72\x16\x0d\x01\x1b\x53\xf3\xf0\xd9\xd4\xfc\xec\xf3\x0b\xbb\xa7\x32\x19\x61\xc5\xe8\xb8\x17\x0a\x7a\xe4\x69\xfc\xbb\x2a\xf8\xe7\x05\xd4\x39\x9f\x5f\x65\x2a\xb5\x13\x1b\x4d\xf2\x16\xc4\x61\x51\xea\x85\xeb\xb1\xf2\x4f\x28\x17\x99\x15\xc0\x16\xa5\x7e\x09\xdb\xa2\xe2\x52\x3a\xeb\x83\x3e\xfd\x76\x79\xbf\x2e\xca\xbe\xeb\xd7\x0f\x13\x84\x7a\xdd\xa4\x1d\xa2\x60\xfb\x03\xdc\x77\x27\x04\x0b\xf3\x99\x54\x7c\x37\x3c\xb6\x15\x13\xec\x4c\xf7\x0d\x35\x13\xdd\xfd\xd9\x7d\x5d\x89\xc4\x4a\xff\x5a\x8f\x03\xbf\xb2\xad\xac\x42\x12\x8d\x68\x14\xae\x27\x63\x9e\x14\xbb\x5d\x83\x81\xba\x16\xfb\x11\x9f\xee\x67\xa7\x57\x1c\x7d\x3e\x14\x64\xb0\x40\x30\xef\x22\x28\x99\x67\xb1\x18\xf4\xec\x5c\x9d\x1f\x8a\x12\xee\x3c\x52\x42\x29\x13\x0f\x9c\x21\xd4\x6a\x2b\x15\x5c\x6c\x3b\xa3\x27\x72\x81\xe6\x99\x3f\x3a\x3b\x01\xdc\xcf\x42\x9a\x60\x6b\xc9\xe6\xa3\x68\xff\x82\x7a\x2f\x4a\xfd\xde\x2c\xab\xa6\x15\xeb\x42\xf9\x8c\xbf\x82\x8c\xa5\x81\xde\x34\xec\x50\xe3\x9b\x37\xb1\x25\xf8\xfd\xab\xea\xac\xea\x1a\x4c\x0d\x96\x66\xd2\x9d\x44\x47\xa0\x91\x44\xd4\xc7\x07\x43\xd3\xa9\x09\x03\x84\x30\x35\x07\x51\xb7\xfe\x17\xee\x9a\x89\x4e\xad\x1f\x0c\x22\x0b\xac\xfb\x48\x8b\x3d\x5e\xa5\x9a\x42\x66\x45\x7f\x45\x79\x12\xfb\x29\x71\xc7\xf8\xad\x69\x96\xcb\x34\xf1\x4c\xfb\x75\xd3\xae\x45\xf9\x76\x53\x59\x01\xc9\xde\x39\xd3\x8c\x47\xe8\x49\x7e\x39\xc9\x19\xc3\xa0\x99\xe4\x98\xc0\xbb\x33\x36\xd5\x67\x63\x88\xe9\x20\x93\xc8\x5e\x7a\xfa\xb1\xaf\x74\xe9\x38\x56\xca\xa5\x25\x9e\x9f\x9e\xee\x6d\x32\x92\xc5\xa3\x08\x4b\x27\x84\x18\xee\x4b\xa0\x62\x3f\xda\xc4\x75\x42\x39\xfa\x36\xd5\x11\xca\x1f\x45\xa9\x83\xd7\xa3\x93\x84\x6a\xdf\x79\x83\x2d\xd1\xe3\x8b\x4a\x73\x9b\x25\x92\xd0\x2e\x3a\x7b\xfd\x1a\x4e\x99\x33\x8a\xd8\xab\xce\x1c\x62\xa7\x75\x17\xdf\x87\x83\x5c\x59\xf1\xda\xd3\x01\x05\x92\x0a\xdf\x35\xb2\xa9\xf6\x7e\xd6\x6b\x9e\xe6\x2a\x72\x86\xfb\xa6\xae\x0e\x13\xfc\xbd\x1f\x95\xd3\x2c\x0d\x2c\xc3\x18\x53\x4d\xae\x91\x03\x45\x3d\x09\x38\x14\xed\x52\x1c\x85\x2c\xf6\x45\x7b\x5e\x68\x3d\x55\x66\x88\x87\x75\x37\xcd\x8d\x42\x0e\x07\x04\xde\x77\x36\x67\x3b\xc8\xff\x6a\xc1\xc0\x6b\xcb\x3e\xc2\xcf\x76\x51\xb6\xc5\x1a\x8e\x7b\x71\xde\x8a\x97\xc9\x15\x0a\x9d\x81\x2d\xd6\xfc\x5c\x8a\xe3\x83\x08\x38\x03\x2d\x93\x08\xfb\x13\x5e\xb1\x6f\xcb\x7d\xa8\x22\x81\x80\x7b\xb1\xdf\x5b\xb4\xce\xa9\x86\x66\x67\xaa\x7a\xd7\x1c\x41\x15\xd3\x5e\x08\xad\x12\x4b\xc1\x6e\xb1\xad\xdb\x5e\x74\xc6\x9f\x50\xb3\x5c\x04\xc1\x5c\x44\xb2\xdf\x0a\x5c\xa6\x43\x4f\x49\x43\x26\x51\x0c\xff\x01\x5a\xa1\x8b\xd3\xc1\xb5\x81\xfc\x0e\x45\x38\x08\x41\x34\x98\x04\x73\xe2\x23\x7e\x8c\xe1\x24\x84\x28\x4b\x50\x17\xfa\xaa\x68\x55\x55\x94\xcf\xa7\xfa\x18\xd2\xcd\x10\xe5\x04\xd9\x68\x8e\xb6\x91\x6e\xfc\x16\x21\x92\xc2\x0b\xf6\xdc\x4d\x82\x76\x88\x20\xc7\xa2\x6b\xe1\xa8\xc4\x2c\x5d\x8d\x3f\x2f\x95\x80\x19\xee\xa2\x2c\x5a\x0b\x0c\x18\x47\xfe\xbf\x76\xf9\x80\x6a\x95\xc6\xae\x81\x0e\xc5\x55\xdd\xe7\x2c\xd2\x98\x57\xd7\xa3\xee\x00\x60\x4c\x12\xaf\x0a\x8e\xba\xb6\x16\xe9\xe8\x8f\x2a\x29\x61\x24\xc3\xbb\x75\x44\x3e\x21\xf3\x0a\xcc\x04\xb8\xc6\xf3\x49\xbe\xc1\x79\xb4\x90\x21\x4e\x52\x04\xb8\xa0\x60\x31\xdc\xd6\xd5\xe9\x18\x4e\x1f\xa7\x14\x37\x62\x79\x3a\x2f\x11\x18\x58\xea\x0d\x94\xfa\xb6\x30\xed\x25\xb7\x5b\x37\x3e\x23\x08\xa8\x58\xae\xbc\x2f\x04\x49\x62\xb1\x7b\xd6\xec\xe1\x7a\x1a\x36\x48\x4c\x1e\x4e\xaa\x0c\xfa\x5d\xb6\x75\x05\xd7\xf0\xa8\x8d\x11\xb2\x88\x63\x79\xde\x55\x33\x3e\xd3\xce\x98\x9c\x36\x13\x09\x76\xd8\x76\x96\xec\x53\x26\x4c\x1d\x01\x4f\x34\x58\xad\xdc\xf6\xb5\x2e\xf6\x4f\x21\xe5\x04\xdc\x58\xc2\x82\xab\xc7\xed\xb8\xa1\x06\xa4\x96\x5e\xe8\xca\xe3\xad\xc7\x0f\x45\x45\x49\xe6\xde\xd1\x25\xe1\x67\x3f\xdd\x41\x91\x14\x93\xfb\xb6\xf7\xf2\xb9\xda\x4f\x8a\x0b\xa0\x13\x85\xa5\x64\xcb\x6e\x3e\xe9\x73\x02\x6d\x38\xfa\x66\xce\x9f\xf8\xfb\xc0\xdd\xc9\x33\x00\x16\xd2\xbb\x9b\xf3\x41\x56\xfb\xce\x56\xce\xe6\x56\xc0\x90\x08\x39\xb3\xbd\x1a\x98\xbf\x14\xc3\xd2\xd0\x5e\x19\x40\x2a\x9f\x12\x20\xcc\x5f\x86\x31\x39\xf2\xc6\x7e\x40\x31\x0b\x41\x34\x51\x1c\xe1\x75\x62\xd1\x19\x6b\x83\x81\x98\x74\x7c\x99\x26\x02\x83\x6f\x5f\x9e\xce\xcf\x35\xe8\x42\xb5\xff\x2c\x3b\xdf\x75\xe8\x93\x38\xb3\x65\x08\x4b\x99\x23\xb9\x2b\x0e\xa7\xc3\x73\x0d\x47\x51\x68\x07\xa2\x1b\xf7\x29\x1a\xe2\xda\xdd\xed\x0c\xed\x9c\xbf\x8b\xfe\x8d\x30\x34\xd3\xb8\xaf\xa9\x41\xcb\xb3\xeb\x82\xf6\x43\x68\x44\x30\x60\x7b\x15\xcd\xa7\x02\xae\x3a\x32\x8c\x32\xcc\x41\x05\xd0\xf9\x62\xcc\x8a\xd3\x27\xac\x87\xbe\x95\x61\x42\x20\x40\x40\x74\xcf\x68\x40\x6f\x60\xe2\x54\x45\xae\x89\xe3\x5b\x03\x75\x33\x99\x56\x26\x36\x1c\x2f\x0b\x11\xa5\xcf\xa7\xbf\xfe\x9a\x7a\x40\x26\x31\xb1\xd2\x5e\x9d\xf2\x27\xec\x97\xd5\xbe\xb2\x2f\xcb\x6b\x90\xf9\x91\xa9\xb1\x9c\x26\xff\x73\x12\xa8\x56\x67\xad\xe7\xe6\xf3\x96\x1c\xf7\xbd\x2c\xb5\xed\x6e\xab\x52\xfb\xf0\xdd\x64\x22\xc5\xcc\x30\x74\x53\x63\xdd\x47\xcd\x26\x27\x56\xa2\x1f\x0b\x4d\x2f\x03\x02\xcc\xe6\x82\xb2\xac\x1b\x9d\x2a\xae\xfb\xdb\xff\x63\x74\x67\x79\x0a\xc2\xf7\x22\xc0\xa1\xaa\xcf\x6b\x10\xb3\x42\x37\x38\xd6\xb8\x88\xf1\xeb\x30\x4d\x67\xf2\x4c\xa1\x79\xb0\xb2\xc9\xcf\x35\xdc\x6d\x9f\x76\x5d\xc8\xb8\x14\xc7\x9e\xee\xbe\x1b\xc8\x55\xea\x16\x0d\x42\x28\xae\x84\x7a\x83\xba\xb9\x3a\x0f\x93\x77\xff\xfa\xb7\x63\x54\xf5\x5f\x52\x19\x71\x0d\x7b\x17\xe1\xde\xc0\xf1\xf6\xb3\x3b\x87\x14\x61\x93\xd7\xb0\x87\x17\x5c\x95\x7e\xa2\x7e\x42\xc5\xa6\x23\xc3\x53\x8e\x4e\x85\xaa\x0e\xb8\x31\xcd\x43\x9f\xf3\x30\xda\x20\xad\xf5\x75\xf1\x52\xb4\x62\xff\x2c\x34\x56\x36\x87\x3b\x8e\x11\x3c\xc5\xc2\x64\x43\x5c\x23\x09\xf1\x07\x64\x8c\x93\xf4\x00\x7e\xb3\x35\x32\xe7\xc8\x46\xe4\xe4\xf4\x2f\xc1\x6e\x46\x42\x86\x19\xb2\x90\xb8\x6e\xfe\x98\xe4\xf3\x8d\x22\x56\x75\xb1\xb3\xc0\x35\xfc\xe7\xd4\xad\xd0\x71\x8d\xc3\x28\x9a\xd9\xee\x11\x97\x4b\x99\x78\x45\x46\x31\x5b\x12\xf0\xc4\x60\x37\x55\xdd\x79\x9a\xfe\x32\x55\xce\xb9\xf5\x35\xc0\x06\x8c\xae\x28\xb6\xda\x7e\x99\x5c\xae\x12\x11\x3a\xd7\x2f\xd5\x4b\x35\x82\x4c\x4f\x6a\xc4\x06\x18\x38\xb9\x0b\x1b\xc8\x3a\xe4\xe9\xe4\x74\x20\xb5\x17\x9f\xf8\xa4\x30\x66\x40\x42\xec\xba\xa3\x46\x31\xb0\x01\x93\x21\x7a\xec\x7b\x17\x57\xfb\x0f\x0d\x28\x21\xfc\x34\x14\x7b\x78\x98\x24\x08\x49\x14\x31\xea\x85\x46\xba\xf3\xf5\x6b\x8f\x44\x84\xd9\x45\x00\x56\x3d\xad\xb3\x33\x24\x1c\xd3\x0c\x71\x08\x6d\x71\x00\x9c\x13\x7f\xdb\x13\x24\x11\x4d\x05\x2e\xc4\x3f\x57\xc3\x1c\x38\x89\x68\x46\x90\xb8\xf5\xe9\xe7\x73\x5d\xb5\x95\xf2\x58\x5f\x12\xb1\x38\xe6\x4e\x5e\xe6\xdb\xfa\x7e\x38\xff\x48\xc4\x32\x81\x62\x9d\xc8\xa6\xf6\x59\x12\xe4\x77\xbb\xd5\xf0\xd5\xf5\x86\x96\x44\x31\xb5\x78\x56\x67\x50\x9c\x6b\x38\x57\xff\xea\xff\xe3\xbf\x9a\xc5\x5e\xda\xc3\xf5\xe1\x0f\x82\x2a\x82\x9d\x7a\xbc\x6f\x8b\xff\x8e\xd2\x56\xdf\xd6\xf7\x4e\xbc\x60\xce\x43\x26\x51\x2c\x48\x50\x1e\x09\x40\x4f\x12\xc5\x52\x09\xea\xb9\xf0\x8a\xb6\x59\x8c\x68\x96\x66\xb7\x64\x12\x25\x44\x60\x29\xc5\x21\xb9\x47\x6f\x22\xa1\x0c\xb9\x35\x6e\xab\xbd\x86\xf2\xbe\x78\x79\x6d\x11\xc4\xfb\xf7\x08\x84\x48\x94\xb0\xc4\x6f\x43\xd6\xe7\x9e\x83\x23\xe6\x7e\x70\x4c\xb0\x25\xc2\xfa\x94\x5e\xfb\x74\xd5\xbe\xce\xb9\x29\x24\x4a\x72\xdb\x1e\xae\x1c\x7b\xb9\xbf\xe6\x8c\x49\x2f\xf4\x7e\x55\xb4\x1f\x55\xad\x9b\xe5\xa9\x9d\xcc\xf6\xce\x75\x54\x8e\xfe\xfc\x2f\xb8\x70\x31\x26\x8f\x28\x27\x59\xd6\x07\xd5\xab\xc3\x71\x5f\x9d\x27\x19\x01\x12\xe5\x69\x22\x2c\x7a\x4d\x5b\xba\x9a\x1f\x00\x6f\xfe\xa2\x72\x69\x1b\xc4\xbe\x9e\x25\xd4\x81\x21\xa5\xaa\x27\xdc\x43\x24\xca\x8d\x51\x91\x47\xb4\x6c\xab\x6e\x27\x19\x5f\x0b\xa7\x12\x86\x70\x1b\x27\x69\x75\x8d\x30\xb2\xc9\x25\xf1\x94\x24\xd6\xd8\x20\x5b\xd8\x53\xf0\x6f\x49\x24\x12\xc0\x70\xd7\xe2\xaa\xec\x4b\x99\x59\xa2\x42\x65\x88\xc0\x91\x3e\x77\x8c\x7a\x0c\x45\x55\x5e\x57\xe5\xf4\xd7\x84\x36\x5e\x4f\xb0\xf3\xc6\x03\x74\x8e\x44\x02\x80\x2b\x07\x44\x74\x2a\xd6\xee\x88\x54\x9c\xda\x28\x06\x5c\xa4\x33\xd2\x33\x77\xa3\x14\xd3\x78\xb1\x4e\xe4\xa1\xae\x0e\x77\x36\x50\x70\x21\xec\xf8\x09\xa9\x24\x42\xf1\xdf\x57\xd1\xec\xde\xab\x89\xa6\x7e\x77\x1c\x64\x9c\xf9\x3a\x73\xd9\x54\x7b\xab\x63\x6c\x9b\xa4\x66\x04\x4e\x35\x89\x74\x4c\xc1\xee\x7f\x56\x06\x63\x72\x46\x2d\x18\x62\xf9\x5c\xdf\xcc\x7d\x51\xbe\xec\xab\xf2\x65\x29\x5a\x4f\x5a\xf1\xdb\x9e\x93\x5f\xaf\x51\x2d\x2d\x54\x4a\x68\xbd\x14\xf5\x4c\xff\x3a\xf1\x23\x81\x44\x92\x79\xae\x2d\x51\x3a\x0d\x4b\x58\x95\x1a\x06\xfc\x57\x24\x02\xca\xb0\x86\xb2\xdc\x57\xed\x6b\x51\xbe\xf4\x8d\x0d\x24\x82\x8c\x89\xbe\xaf\xfd\x57\x22\xc4\xdd\x60\xce\x71\xa3\xc6\x70\x7e\x9c\xff\x75\x23\x4c\xaa\x31\x6d\xb7\xab\x5d\xb1\xb8\x78\x29\x31\x5f\x11\x44\x86\xf3\x7f\x0f\x8d\x2d\x89\xa2\x14\x83\x84\xab\xaa\x7a\x5b\x0a\xe3\xaf\xb9\xb3\x6f\x58\x29\xd8\xdc\xaf\x97\xe1\x33\x13\x61\xde\xfe\x7e\x75\xbb\xb8\xf7\x1f\x76\x73\xc0\xd8\xbd\xf1\xa1\x50\x75\xf5\x15\xce\x56\x79\x5e\x94\x7a\x16\xb3\x4e\x08\xa1\x99\x8a\x5c\x11\x18\x39\x0f\x76\x86\xe4\xfe\x7c\xd4\x05\xf1\x4d\xf1\x17\xd0\xf0\xa1\xb2\xcd\x52\xcf\xcb\xc7\xc1\xc3\x23\x71\x96\x10\xdf\xe4\x0c\x9d\xc1\x44\x9d\xd3\x5f\x36\xd4\x10\x92\x30\x43\x6d\x44\xfe\xd2\x17\x7d\x09\x49\x78\x66\xfb\x97\xd6\xab\xbb\xe5\x53\xd3\x33\xc4\x11\x92\x28\x81\xd4\x4b\xff\x5b\x75\xd6\x38\xc0\xa3\x27\xa7\x35\x11\xd6\xf4\x6d\xd2\xe7\xa1\x28\x67\xc0\x0c\x84\xa4\xca\x52\xa0\x38\x97\x64\xc4\x70\x44\x48\x46\x88\x70\xa2\x9e\x76\x5d\x06\xbf\x80\xe4\x91\xed\x1a\xba\xaf\xda\x4a\xf6\x50\x37\x42\x72\x46\x14\x1b\x74\x54\x7e\x09\x2d\xc9\x84\xf0\xc8\xea\x1d\x59\x2b\x1f\x3a\xe2\x5b\x38\x22\xbe\xba\xb7\x3d\x84\x27\x2a\x1e\x5a\xba\x47\xd1\xbc\x3e\x9d\xe6\xd1\x84\x84\x70\x2d\x63\xe7\x1a\x6c\x54\x55\x7f\x62\xca\x89\xd4\xb6\x97\xb6\x81\x12\xf1\x60\x45\x89\x91\xdd\xa0\x00\x4d\x88\x04\xc0\xac\xc0\x66\xbb\xd9\xae\x36\xdb\xd4\x7f\xae\x74\x3c\xa0\xbb\x42\x6c\xf7\x25\xfe\x88\x10\x2d\x73\xe6\xc5\xc7\xa1\xc4\x26\x91\x3e\x6c\x0f\x3f\x02\x59\x66\xe1\x80\xab\xbb\xe1\x96\x4b\x0c\x61\x98\xe5\x2d\x7d\xa7\xc6\xc0\x1e\xfe\x10\x45\x77\xc1\x37\x55\xfd\x6c\xe9\xc7\xfd\x77\x12\xc9\xad\xcb\xd7\xf9\x17\x05\x9c\x0e\x8f\xf0\x71\xb7\x7c\x1a\x9f\xd8\x28\xb7\x19\xb8\x72\xc3\x20\xfd\x47\x68\x94\x0a\x4c\xec\x59\xa4\x83\x9d\x27\xf8\xf5\x07\x51\x9e\x27\x48\x47\x42\x23\x41\x3d\x1a\x0c\xe9\x1b\x3a\x93\xec\x95\xdf\xd0\x28\xfd\x8b\xf5\x43\x63\xe3\x7a\xd0\xbe\x95\xc8\xb5\x64\x85\xf6\x8b\xbf\x40\x3f\x77\x91\x47\x80\x73\x12\x4a\x88\x40\xd6\xb1\x4d\xb5\x17\x35\xfc\xf4\x1f\xd3\x34\x49\x2d\x53\x5a\x17\x91\xcf\x00\x66\x08\x65\x99\x55\x46\xb8\xaf\x5e\xee\xc6\x70\xab\x38\xf7\x43\x78\x86\xeb\xb5\x33\x54\x4e\x68\xd3\xff\x00\x93\x29\xd6\xd2\x01\x19\x9d\xd7\xf0\x82\x64\x31\x13\x2b\x4f\x63\x02\x1e\x2d\xed\x90\x24\x77\x7a\x82\x97\x26\x34\x11\x19\x84\xe5\x22\xf6\x56\x15\x6b\x32\x26\x8d\x00\xb3\xe5\xa7\x06\xea\x89\x9a\x9d\x1f\x21\x00\xab\xd8\xdb\xf5\xfd\xf2\xe9\xee\x71\x77\xbd\x5a\xde\x3d\x2c\xee\x37\xfe\x82\x53\x2d\x6c\x96\x44\x34\xaf\xd5\xe9\xb2\x92\x3f\xfe\xbd\x8c\xdb\x80\x77\xa1\x35\x16\x33\xe6\x97\x06\xcd\xa4\xe4\x03\x1d\x24\x27\x2c\xea\x7f\x32\xe7\x14\x5c\xbe\xf1\xb6\x30\x18\x96\x0c\x16\x2b\xcd\x0d\xd5\x10\xd2\x5c\x83\x46\xb8\xee\x90\xa2\x3e\x49\xa1\x02\x09\xcf\x4d\x55\xbb\x5e\x19\x3f\x8e\x27\x60\xc1\xa2\x8f\xd7\xeb\xaa\x6a\xfb\x8f\x0d\xc2\xc2\xae\xb7\xeb\xc5\xf2\x6b\xf8\x14\x00\x33\x3a\x96\x2b\x1b\xf4\x60\x89\xed\xba\xa8\x01\xec\x3f\x87\xaa\x47\x9a\x50\x11\x09\xab\xfb\xad\x2a\xd7\x0b\xea\x0f\xa4\x51\xec\x08\x35\x7f\x40\xd1\x59\xa2\xe9\x37\x33\x19\x4f\x10\x5c\x98\x3b\xa9\x27\x6f\x4e\x26\x04\xf7\x11\x6b\x23\x50\xd4\x55\x9f\x56\x3f\x8f\xa3\xc0\x94\x50\x99\xe7\x68\x86\x36\xb0\x2f\x0e\xc3\x65\x4a\x55\x94\x63\x11\x68\x75\x7b\xbb\xd9\x6d\x9f\x76\x5f\x50\x20\x87\x5c\x7d\xbb\xef\x5f\xbf\x22\x60\xc5\xc0\x85\x7e\x81\x66\x52\xd0\x27\x54\x65\x12\x8b\x84\x3f\x1c\xfd\x97\xff\x9a\x4e\x2c\x3f\xaf\x2d\x38\x82\x46\xfc\x8c\x7d\x1b\xab\x43\xd1\xce\xd0\x13\xfb\x2f\x72\x2b\x2c\x7d\x7d\xb3\xbd\x1a\x9d\x11\x22\x89\x18\x1e\xc4\x0d\x3e\x7d\xe0\xaa\xf2\xc7\x4c\xca\x99\xe5\x8b\xaa\x3e\xd0\xf5\x70\x20\x31\x7f\x38\x8b\xd0\xe0\x60\x99\xf6\xee\xf1\x76\xd8\x16\x47\x58\x44\x22\xec\x75\x7b\xa9\x85\xc3\x39\xcc\x6a\xf0\x76\x23\x39\xc1\xe4\x6e\x09\x1f\x88\xdc\x1e\x38\x12\x8c\xc4\x00\x5e\x04\x05\xd9\x76\xfd\xe9\x49\x02\x56\x73\x6b\xb3\x5e\x84\xcf\x84\x6d\xc8\xb8\x81\x56\xbd\x76\x6e\xc0\x17\x4c\xd5\xf4\x87\x25\xee\xeb\x0e\x21\x16\xe4\x4b\xea\x83\xcd\x83\xce\x38\x15\x8c\x08\xeb\x22\x1c\x6b\x50\xe8\x35\x3f\xd8\xfc\x63\x38\xa7\xb6\xe8\x3c\x5f\x17\x44\x16\x1f\xdc\x57\x9a\xa9\x61\x61\x34\xe2\xc6\x1a\xe8\xd7\x50\xfd\x22\x8c\x32\x4e\x44\x4f\x14\x3b\xa3\x6f\xde\x0d\x12\x39\x62\x89\x2d\x35\xee\x38\x5f\x40\x18\x05\x19\xd1\x41\x93\xb4\x13\xd5\xf8\xa5\x49\x61\x8c\x70\x9f\x4e\x1e\x6c\xee\x2c\xa6\x3c\xc9\x1d\xbe\xa1\x81\xaf\x67\x35\x79\x59\x71\x9c\xe1\x26\xfd\x51\x94\xbd\x10\x50\xf7\xb9\x89\x85\x6d\x35\x12\xfb\x3d\x94\x2f\x80\x42\x7e\x6e\x89\xe9\x51\x9c\xcf\x12\x02\x3c\x1e\xf0\x9c\xd9\x80\xa2\x73\xf1\x26\xb7\x9d\xc4\x26\xb5\x80\x7b\xa4\x7e\xda\x16\xc7\xf9\x76\x3c\xc2\x12\x01\xd8\x8d\x55\x34\x5e\x1e\x6f\x5b\x85\xad\x91\x25\x4a\xc5\x43\x22\xcf\x81\x10\x4d\x77\x54\x1b\x34\x0c\xcb\xa7\xc7\xd5\xad\xef\x7a\x23\x2c\x4d\x0d\x71\xaa\x90\x7b\xa8\x1d\x4c\xd2\x12\x58\xfb\x24\xea\xac\x3f\xcd\x52\x61\x01\x80\x18\xd6\x3a\xe0\xb2\xaa\x0e\x20\x3d\xa1\x13\xde\xf4\x27\x37\x92\x25\x06\xcb\x9c\xb8\x69\x6c\xbe\x3d\x3f\xdf\xff\xb9\xbb\x5b\x3e\xd9\x5e\x51\x7f\x69\x59\xaa\x85\xf0\x6c\xf0\x48\xff\x76\x1f\xa0\xf9\x84\x65\x39\xc5\x30\xb6\xf3\xa3\x5a\xf1\x3b\xcf\x95\x65\xb9\x95\x0d\x7f\x81\xf6\xba\x68\x06\x9d\xb2\x84\xe5\x34\xe2\x34\xb4\x84\x4d\xd0\x13\xe3\xb3\xe4\x31\xb8\xfa\x4f\xd3\x16\xed\xa0\x53\x8e\x30\xce\x2c\x29\x8f\xaa\xca\x12\x94\xed\x32\xb0\x5e\xd7\x6f\x72\x39\xfe\xfb\x99\x25\xd8\x2c\x54\xf5\xf4\x0e\xf5\x7b\x01\x1f\xfe\xd4\x82\x31\xac\xce\xfa\x17\xdb\xad\x20\x1a\x0e\xa6\xb1\x76\xcd\xa6\x7f\x8a\x72\x59\x81\x31\x85\x1a\x72\xe7\xe3\xef\x78\x83\xce\x44\xc6\x70\x41\x78\xb7\x6d\xa0\x8c\xaf\x09\x93\x49\x2c\x9d\xeb\x70\x2b\x0e\x30\x76\x61\x26\x17\x2c\x4d\x96\x5a\x32\x7e\xab\xd1\xda\xb9\xa6\x5b\x97\x5d\xa3\x23\x0c\x25\x61\xca\x71\x91\xfb\xad\xd5\x51\xe4\xcc\x3f\xeb\x4f\x1e\x90\x92\x56\x91\xaf\x73\x54\x70\x4d\x8e\x0f\x6b\x22\x90\x5e\xd8\x73\xc7\x2c\x85\x87\x2a\x0e\x48\x21\xc8\x54\xe3\xee\xef\x14\xa5\x08\xd3\x42\xe0\x5c\xdf\xfa\xfe\xb0\xd5\x7a\xe9\x31\x32\x84\x41\x94\x47\x39\x5a\xf6\x9f\x4e\xba\x6d\xbb\xb5\x7d\x29\x77\x3a\x0f\x83\xa8\x40\x42\xbd\x1f\x50\xec\x02\x68\x6b\xb7\xad\x70\xda\x2f\xc5\x31\x8c\x4b\x72\x44\x5e\x61\x5e\xe5\x0b\x82\x24\x87\x69\x38\x06\x19\xf7\xca\xb2\xdf\x36\xd7\x6b\x51\xf4\xce\x01\x03\xc1\x3d\x72\xe2\xa1\x28\xbd\xec\x9b\x3b\x68\x22\x4e\x7d\x43\x34\xf6\x45\x5d\xf2\x6f\x13\x66\xb8\x15\x8a\xe9\xbb\xb5\xfe\xab\xba\x59\x77\x02\x9d\xd8\xb6\xdb\x8f\xbb\xd6\xcb\x78\x4f\xf2\x6f\xb3\xc4\x3b\x7d\xfb\xe4\xec\x89\xe3\x28\x93\x78\xdf\xdb\x5a\x28\x18\x6b\x31\x69\x12\x13\xc2\x72\x18\x6a\x01\x20\x78\xf3\x6a\x02\x5e\x20\x31\xe1\x16\x77\x55\x9e\x0e\xcf\xa2\x16\x07\xe8\xe9\xbf\x49\x4c\xa4\x53\xfc\x45\xce\xdf\x6e\x0b\x47\x91\x86\xcb\x24\x46\x7f\x3e\x9a\x5b\x14\x15\xde\xe8\x4d\x55\xff\xda\x08\xc5\x54\x2a\x44\x35\x17\x25\x8a\x1d\x9f\xc4\xfe\x07\x14\x4b\x8b\x0e\x9d\xba\xf1\x31\xd3\xc2\xd3\x96\x74\x76\x6f\x73\x3a\x4c\x6e\x26\xa6\xe0\x25\xd7\x37\x6d\x7d\x53\xc0\x5e\x7b\xab\x10\x67\x34\x72\x6c\xc9\x78\xf2\xe5\xeb\xa7\x9b\x4a\x9c\x65\x76\x8b\x6c\x8a\x97\xd2\xd5\x4d\x26\xdc\x07\x61\xa0\xc9\xa4\x97\xdd\xb3\xf5\xef\x6e\x92\x5a\xc5\xc3\x53\xcf\xe3\x42\xe2\x8c\x27\x16\xc4\x8a\xc2\x0a\xaa\x2a\x4a\x9c\x6c\x77\xe5\x4d\x2d\x94\xbf\xc4\x9c\x66\x98\x3d\xb1\x41\x7f\x50\xeb\x08\x47\xf3\xdc\x69\xdc\x74\xab\xa0\x28\x5f\x1c\x35\xdc\xf8\xe2\x85\xca\x6c\x80\xe1\x9d\xb7\x3e\x45\xea\x46\x48\x6a\xb8\xeb\xc9\xea\xfd\xc8\x4f\x1e\x85\x4c\x39\x71\x22\x7e\xdd\x32\x71\xa5\x8f\xce\x51\x19\xbf\x1a\xa5\x29\xf6\xd9\xe1\x22\xdd\x1c\x6b\x10\x7e\x0d\xc6\x40\xb2\xdc\x09\x90\xa0\x0e\x4c\x55\x63\x7a\x75\xfc\x3b\x90\x52\xef\x4f\x2d\x2f\x58\x4e\x48\x0c\xd2\xf2\x07\x3c\xfe\x73\xb5\x1b\xa4\x6c\x62\x43\x32\xc4\xf0\x88\x8b\x9a\xeb\xf8\xf2\x4c\x92\x62\xc7\xfa\xa1\x7a\x07\xcb\xfc\x17\xce\xc0\x29\xb1\x2a\xf1\xde\xb7\x4b\x22\x93\x23\xc8\xc2\x45\x53\xd7\x55\x39\xe8\x5c\xec\x0e\x4b\xcc\x5b\x39\x4a\x9e\x6d\x75\x17\xd2\x3e\x09\x01\x45\x03\x59\x9a\x86\xed\x3f\x6f\x2e\x62\xc8\x84\xe6\x69\xe2\x33\xeb\xa2\x69\xaf\xef\xbe\x5f\x0f\x39\xfe\x48\xc2\x58\x8c\x40\x4a\x14\x67\xfe\x0e\xcd\x88\x2f\x81\x24\x2c\x4b\x71\x9b\x1f\xe6\xbb\xe2\x70\x90\x5b\xde\x18\xa7\x07\x83\xaf\x6b\xf2\xfb\x4c\xc8\xd8\xf5\x23\xa0\xf3\x7f\xdc\xc3\xb6\x80\x9a\xb8\x45\x3e\xcd\x18\x24\x4c\xa6\x18\xd1\x1e\xd1\xcb\x04\x3d\x8c\x10\x13\xa6\x09\x36\x39\x3d\x9c\xaf\x7b\xcb\x9a\xc4\x84\xa6\xb1\x7f\x0c\x08\xc1\xb8\xa9\xea\xcb\x6a\x2f\x49\x92\xc4\x58\x2e\x58\xdb\x16\xd1\xed\x15\x05\x0a\x8f\x4f\x71\x24\x7e\x7c\x2e\xb1\x29\xdc\x66\x42\xb0\x3a\x3e\x78\x32\x09\x8f\x7c\xb3\x61\x15\xdc\xa2\x24\x31\x60\x0b\xc1\xba\x68\xaa\x72\x30\x7b\x92\x34\x89\xb9\xf1\x54\x04\xc7\xa2\x06\xbd\x28\xf5\x48\x50\x5f\x93\x24\x23\x1c\x85\xd2\x7c\x21\x72\x74\xfb\x19\xb5\xa5\xbc\xa6\x67\x44\x9c\xb0\xa3\x8c\xaf\x3f\xcb\x52\xec\xd2\x38\x3a\xb8\xf4\xa4\x7c\x48\x92\x0c\x72\x82\x64\x81\xb8\x1b\xae\x7e\xb6\x50\xea\xcf\x79\x8f\xfc\x97\x0c\xcd\xbc\x06\xa6\x47\xe5\xda\x1c\xd1\x25\x18\xb1\x1b\x9d\xc6\x0e\x68\xe5\x12\x86\x68\x69\xde\x27\xbd\xb3\x24\xe1\x71\x8c\x61\x95\x05\x4a\x6e\x47\x4d\xc2\xdb\x0b\x4a\x82\x4f\xae\x4d\x26\x11\xd6\x9f\xf1\x6b\xeb\x27\x9f\xfd\x4d\x24\x4f\x70\x5f\xd5\xb6\xf2\x0d\xd7\x6f\xfb\xab\x42\x3b\x6e\xff\x8b\xfb\x1d\xf7\x69\x0d\xd3\xe6\x89\xe4\x29\x56\xdc\x6f\xa1\xbd\xaf\x5e\x1c\x03\xdc\xaa\xae\xab\xf0\x92\x14\x21\x88\xfe\x3e\x3a\xce\xf0\xf5\x84\x13\xcd\x0f\xcb\x29\xb0\xbe\x9c\xf7\x20\xca\xf3\x18\xa6\x3f\x40\x72\x4c\xbe\x69\x04\xe6\x80\x97\xaf\x75\x55\x56\x0f\xc5\x25\xa9\xdf\x6c\xc0\x90\x68\x6a\x91\xa8\xcb\xfb\xd5\xee\x0a\x5a\xb1\x7b\xb6\x59\x40\xbf\xff\x26\x3a\xb5\x1e\x3d\x6e\x78\xb2\x16\x93\x46\x32\x92\x68\x99\x38\x4d\x66\xab\xa4\x70\x25\xd4\xdb\x4b\x5d\x5d\x1a\x1d\x88\x52\x27\xb6\x6d\xbb\xd7\x82\xbf\xf0\xa9\xaf\xe9\xbf\x48\x22\x62\x89\x9d\xea\x37\x08\x22\xf7\xcd\x08\x79\x43\x12\xe0\xb1\x65\xfe\x6d\xab\x63\xe8\x63\xef\x15\xf4\xba\x11\x4a\x2a\x4b\x4d\x73\xb0\x29\x3a\x34\x5d\x43\x55\x27\x92\x00\x70\xe3\xd6\xa3\x85\xbe\x88\x72\x5b\x8b\x51\xb6\x2a\x31\x8a\x63\x7b\xa4\xc5\x5c\xed\xc6\x5e\x75\x1a\x25\x56\x2e\x1a\xb5\x4c\xcf\x18\x71\x7c\x9d\xb4\xac\x90\x94\xb0\x88\xa5\x93\x42\x7e\xb0\x37\xfd\x4f\xa5\x84\x65\xb6\x77\x5a\x1f\x8a\xf2\x16\xc6\xa2\x58\x24\x25\xb1\x36\x6c\xe4\xba\x3c\x20\x88\x24\x1c\x4f\x98\x65\x20\x68\x45\x8d\xba\xb0\xdb\x8f\x2a\x1c\x93\x09\xfa\xbe\xb8\x5d\x36\xdd\x8c\x01\x7d\x7d\xea\x0c\x46\x50\x1c\x22\x29\x23\x0c\xe9\x9a\x0e\x4d\x14\x3e\xa2\xc6\x32\x92\xa2\xda\x5c\xb7\xb9\xb8\x10\x79\x9e\x92\x96\xa4\x2c\xa1\xc2\x84\xcc\xe7\xb0\x22\x9f\x32\x99\xa1\x91\xae\xab\x8f\x61\xe7\x21\x49\x99\x51\x42\x8e\x30\x8c\x5f\xa0\x0e\x97\x9e\x44\x26\x33\xae\x4c\xb5\xab\x4a\xf8\x2e\xf6\x85\x5e\xfd\xc7\xb2\x73\x3c\x56\xf7\xd5\x4b\x18\x49\xb2\xdc\x92\xad\x97\xa2\x05\x27\x0f\x31\x09\x52\xd2\x84\xe6\x39\xf4\xd0\xb4\x0f\x6b\xf8\x86\xaf\x21\xd1\x99\xd2\x83\xa9\xfb\x28\x0e\x80\x78\xb1\x9b\xba\x3a\x5c\x8b\xe3\xf1\xa2\x81\x79\x94\xb0\x4b\xd3\xc8\x92\x3c\x34\xc2\xc0\x05\x3c\x71\xfe\xa9\xa5\x09\x43\x0f\x69\x77\xb0\x92\xf7\x93\x6b\xce\x08\xc5\xc4\xd5\x41\xfc\xbc\xad\xc4\x7e\x0d\x42\x05\x39\x05\x92\x66\x39\x45\xb0\x6a\xf7\x80\x1e\x00\x3b\x45\xfd\xa1\x9c\xa6\x38\x25\xc6\x6a\x76\xbf\x2d\xc6\xa7\x79\x92\x2a\xe1\x49\xe9\x87\x04\x03\xe3\x51\x69\x82\xa9\xb1\xe7\xf5\xdd\xd3\xfa\x6e\xfb\xa7\x97\x78\xd9\xdd\xdf\x6d\xb6\xe1\x12\x4c\x6a\xbb\xb2\xf7\xef\x7f\xe3\x87\x79\x1e\xb3\x28\x80\xaf\x3d\x01\x9c\xa3\x8e\x1f\x19\xb3\x94\x8b\x08\x73\xc5\xf0\xfe\xf0\x72\x68\xef\x9a\xe6\x04\x57\x3d\x68\xf4\xc2\xca\x5c\xf4\xb6\xf4\x2f\x9c\xab\x1c\xc3\x68\x28\xf5\x93\x71\x0d\x83\xfe\xf2\x45\x26\x30\x69\x61\xf5\x74\x3d\xc1\xd7\x10\xc5\xe1\x07\xe6\x06\x61\x5e\x6f\x85\x7a\x1b\xcb\x20\xfa\x01\x3c\xc5\xfa\xf5\x47\x51\x5e\x15\xd8\x0d\xf7\xb7\xb2\x12\xa9\x8c\x62\x2b\x12\x78\x46\xea\xc4\x97\x70\x69\x32\xb5\x2d\xfd\x2f\xd0\x3e\x95\x23\xa3\xb2\xad\x7a\x0d\xf4\x6e\x20\x64\x0e\x41\xec\x9b\x60\xae\x61\xdf\xad\xe1\x7e\xa2\xa8\xd8\xd2\x79\xdf\x3c\x7d\x7b\xbc\x5e\xad\x3d\x66\x27\x05\x62\xf1\xb0\xae\x1e\xeb\x7f\xe0\xae\x85\x4b\x9e\xdb\xd1\x8b\x84\x38\x76\xd8\x6b\x78\x2f\xaa\x53\xe3\x00\x67\x21\xcf\x91\x02\xa7\xba\xaf\x1c\x5f\x72\x62\xfe\x7f\xc3\x72\xfa\x57\x02\x5a\x61\xef\xa5\x7a\x15\xf5\x0b\xdc\x00\xf4\x5c\x80\x24\x35\x79\x8a\x2f\x5d\x8d\xe9\x77\xfc\x51\x63\x49\x88\x31\xa1\xe0\x19\x67\xee\xfc\xe3\xca\x22\xc2\x90\xa3\xe8\x66\x5f\x1c\xc9\x30\xcd\x9d\x51\x6a\xb1\x51\xcb\xc5\x76\x0c\xa4\x24\x19\x8d\xf3\x9c\x8c\x52\xcc\xa3\x09\x92\x51\x4e\x90\x4d\xbc\x50\xd5\x50\xab\x17\x8f\x88\x58\x38\x7f\xcb\xbe\xc0\x07\x74\x91\xf6\xf3\x44\x97\x24\xa3\x3a\x45\x99\xd5\xe3\x5e\x9c\x6f\x44\x08\xe9\x32\x16\x03\x36\x8b\x17\xcd\x5d\xf9\x08\x3f\xdb\x5b\x5b\x75\x9d\x6a\x67\x91\x8c\x65\x11\x7a\x78\xaf\xa2\x79\x7e\x3d\x37\x85\x12\xfb\x59\x68\x4d\xc6\x72\x99\x61\xb1\xa3\xae\xaa\xc3\x8f\xee\x3f\xe1\xb7\xb4\x25\xdd\x5b\x1c\xc4\xfe\x45\xf4\x1f\x43\x92\xe5\xa3\x10\xb6\x47\x08\xdf\x57\x13\xa5\x37\x92\x31\xa3\x72\x57\x13\x74\x9d\xc1\x33\x7c\x27\xf3\xee\x4e\x16\xa7\x96\xd2\x3a\xcc\x7b\xa4\x7d\xf1\x17\x12\x2b\x96\xe7\x61\x4b\xc4\x54\xd8\x53\xfb\x0a\x75\xb7\xca\x46\x0d\xbd\xe3\x47\x9b\x38\x69\xca\x83\x68\x9a\x55\xfb\x3a\xa8\xc1\x67\x09\x4f\xf2\x5e\x3b\xc7\x75\x5e\xdf\x54\xf5\x62\x02\xe4\x26\x59\xa2\x2d\x33\x60\x50\x9b\xb0\xfd\xc9\xc3\x5d\x31\x4b\x25\x60\xc9\xfc\xba\x2a\xab\xfa\xf3\xf5\xf1\x89\x7d\x73\x27\xc9\x52\xeb\x52\x9c\x9a\xce\x2a\xac\x2b\x59\x7d\x42\x34\x47\xb2\x2c\x07\x6c\x64\xfb\xb6\x6f\xeb\xe2\xe7\x20\x6c\xc9\x32\x48\xb1\x02\x65\x8a\xfd\x6f\xa4\xec\xc6\x67\xcc\x53\x9b\xcd\xf1\x5d\x66\x13\x56\x32\x92\xe5\x9c\x60\x0e\x7a\xf1\xd0\x53\x13\x92\x8c\x83\xc4\xd2\x2e\xf2\x9e\x68\xa4\xd4\x76\x47\x04\xb1\x3c\x99\x1b\x68\x17\x28\x29\x88\x2d\x40\xa3\xa7\x26\x32\xae\x82\xe2\xea\x63\x55\x1f\x5c\x2f\x44\x9f\xe2\xf1\x03\x45\x8e\xc9\xf8\x5b\x68\xaf\x8b\xf7\x67\xfb\xde\xef\x3b\x43\x11\x46\x48\x86\x35\x7c\x53\x03\xd0\x09\xbb\x21\xc9\x24\x10\x2f\x41\xb8\xd8\xef\xbf\x54\xa7\x66\x70\x63\xca\x50\x6e\xd5\x0d\xdb\xba\x80\x77\xf8\x21\xea\xba\xa8\xea\xf9\x8e\x40\x57\x75\xce\x74\xa4\x6d\x99\xeb\x6e\xeb\x9b\xc4\xea\x87\x21\x4e\x72\x7e\x96\x6b\x9a\x60\x39\x75\xec\x30\x8f\xfd\xd4\x0c\x62\xeb\xb7\x37\x94\x0d\x11\xb7\xdd\x01\x2b\x5d\xa5\x41\x55\x1a\x85\xd1\x26\x0e\x53\x66\x12\x8d\xb5\xde\xce\xed\x54\xb0\x7b\x2f\x4a\x55\xb4\x55\x1d\x1e\x93\xc9\x48\x4c\x07\xbd\x32\xbf\xb3\xe0\xfe\x6b\x3a\x61\x08\xf5\x29\xe1\x23\x64\x9e\xfe\x66\x4e\xf8\xd7\x21\x60\x1e\x51\x1d\x3a\x26\x57\xb7\x0b\x5f\x0b\xcd\xa3\x94\x8d\x1c\xbb\x01\x5e\x62\xf1\x02\xd3\x5c\x41\x1e\x71\x03\x79\xdf\x8f\x73\x5f\xfc\xe7\x84\xdb\xc0\xf6\x75\xb8\x91\xe4\x91\xb4\xf0\x38\xaf\x54\xd6\xd7\x58\x67\x77\xc6\x3c\xd2\x11\xf6\x56\xee\xb4\xdd\x84\xc7\x19\x78\x3f\x08\x24\x3a\x60\x56\x3a\xeb\xce\x33\x84\x92\x9c\x50\xdb\x6c\x52\xc2\xc7\xf2\xd4\xb4\xd5\xc1\xea\x2a\xf8\x26\xe6\xbf\x65\x15\x72\x92\x26\xe8\x31\x3e\xad\x1e\xc3\x79\x73\x01\xda\x23\xf2\xa0\x29\x34\x94\x2d\x5c\xc3\x03\x34\xe2\x77\xac\x29\xfe\x0c\x8a\x61\x97\xcb\x23\xa8\xba\x1a\xee\x89\x39\x95\x31\x86\x59\xd6\xb9\x57\xe7\x2f\xa0\xc3\x2a\xcb\xa9\xa6\xc8\x4a\x77\xb7\x7c\xda\x21\xed\x29\xd9\xdd\xdf\x3d\xdc\x79\x6b\x90\xb3\x98\xc5\xba\x67\xed\x6b\x02\xa5\xd6\x6c\x68\x9c\xb3\x44\x22\xdb\xe3\x1e\x4c\x4b\xc9\x78\x2a\xe7\x31\xe1\xe8\xcc\x6d\x0e\x3e\xdb\x92\xc7\xdc\x76\x53\xa0\x84\x85\x3c\xbd\x84\xcf\x85\xc6\x47\xd4\x53\x26\x6c\xab\x10\x68\x2e\x4a\xc7\xc5\xd2\x5c\x36\x5d\xf8\x34\x56\x1e\x4b\x1b\x68\x60\x5f\xa0\x6b\x23\x71\x15\xf4\x77\xf8\x44\xef\xf9\xf2\xa9\x26\x2a\xb1\x8a\x43\xc3\xf6\x62\xe4\x5d\xf6\x03\x0c\xc3\xfd\x74\x57\x7d\x94\xcd\x2c\x39\x24\xc9\x53\x42\xb4\x0d\x40\x1d\x8a\x3e\x3c\xfd\x34\x8d\x88\xe3\x4c\xf2\xa5\xfe\x61\x86\x2b\x4f\xd3\x84\xeb\x5e\x54\xfa\x4e\x55\x0f\xa2\x28\x2f\xba\x60\x49\x9e\x3a\xfc\x7b\xd1\xf9\xe1\x8b\x52\xdf\xcf\x00\xbc\xdd\xd0\x2c\x4e\x71\xaa\xe1\x9e\x67\x29\x8a\xf4\x9c\xc8\x02\xc9\x73\x63\xb9\xff\x1a\x2f\x14\x67\xfd\x95\xfd\xfd\xfb\x90\x1b\xdc\xd9\xcf\x9c\x33\x8d\x1c\x97\xd5\x5e\x9f\x1a\x68\xe6\xb5\x14\x48\xce\x25\xc7\xbd\x17\xb3\x9d\x4e\x8c\x6d\x98\x67\xf6\xc3\x14\x41\x20\x5f\x2f\x25\x77\x75\x5e\x1d\x44\xf1\x29\xf9\x86\xfb\x9e\x48\x92\x94\xf5\x56\xa3\xd9\x20\xae\x7a\x32\x46\xc7\x1a\x86\x02\x78\x0b\x33\x01\x66\xe4\x32\xca\x30\xaf\x1a\x3c\x04\x4c\x55\xa2\xa0\xe3\x6c\xff\x09\xc9\x25\x67\x56\x73\x16\x27\xc2\x2f\x77\xe6\x5c\x25\x1a\xf3\x3c\x37\x75\xf5\x72\x2d\xea\xd3\x41\xfc\x96\xe1\x63\xfe\x44\x9a\xc7\xb1\x2b\x48\x7c\x11\xb5\x5e\x8a\xe3\xe4\x56\xb5\xe1\x48\x51\xfd\x2e\x4e\xfb\x76\x67\xb5\x07\x2d\xd2\x29\xcc\x60\x6d\xac\x42\xed\x51\xd4\xf5\x84\x6a\x91\xe4\x10\x31\x2c\x5b\x5a\x8a\x83\x6b\x98\x94\xf8\x73\x20\x31\xe2\x16\x17\x65\x59\x9d\x4a\x85\x38\xa4\x66\x7a\x8e\x9c\x48\xd6\xe7\xd7\x87\x6f\xd9\x18\x99\xdb\xcd\xed\x1d\xea\xa6\xaa\xef\x9a\x0b\x24\x02\x8f\x22\x86\xe9\xbc\x9d\x8f\x0f\xfb\x94\x09\x8f\x5c\x6f\xed\x76\xbd\xbc\x68\x94\x25\x9c\x48\x86\x89\x9f\x05\x32\xca\x5e\x79\x40\xda\xe4\xfa\x38\xd1\x19\x82\x2e\x9e\x9e\x57\xeb\xc5\xf6\xee\xe9\x71\xb3\xdb\x7c\x59\xac\x57\xe1\x34\x40\x2c\xa6\x59\xb4\xb0\x39\x37\xc3\xd8\x6b\x7c\x22\xca\x52\x2c\x0f\xd5\xa8\x0e\xe2\xe1\x2a\x9c\x26\x12\xbb\x6a\xfe\x5c\x2c\xbf\x78\xbb\xca\x19\x13\x18\x14\xbe\x54\x62\x8f\x39\x73\x44\x70\xf5\xd1\x13\x67\x59\x24\xbd\x08\x5f\xfb\xf5\xcf\xe5\xe4\xa9\x30\xd7\xc6\xd2\x1c\xf7\xdd\x2c\x2f\xca\x97\x4b\xe7\xd4\x0d\x8d\x23\x81\x39\x66\xe1\xde\xd1\xe4\xf6\x13\x29\x91\x39\x69\x71\xfe\x10\x6f\xf0\x79\xeb\x1b\xe1\x09\x18\x34\x86\xdd\xc6\x8e\x81\x80\xf5\xb1\x43\xd2\x8f\x27\x46\x63\x39\xc4\x49\x65\x5d\xef\x2c\xbf\xf0\x6e\x73\x77\x1d\x9e\x66\x96\x8a\xd4\x6b\xc1\xee\xa1\x85\xa1\x7e\xda\x3f\x26\x19\x8a\xf1\xcf\xe7\x09\xc3\x66\x63\x70\xde\x99\x23\x27\x99\x7f\x17\x79\x26\x68\xee\x69\x01\x84\x06\xf4\xbd\x27\xcf\x30\xcf\x65\x2a\xfa\x5a\x7f\x90\xe0\xeb\xcf\xc2\x89\x6d\xa4\x54\xb6\xff\xf0\x57\xc8\x08\xce\x55\x8e\xd3\xc4\x12\x4f\xfd\x2a\x56\xf8\x2c\x27\x32\xbb\xa5\x72\x99\x5b\x41\x17\xcb\x44\xe2\xea\x2b\x53\xce\x2d\x3f\x96\x73\x94\x9c\xb4\x04\x99\x98\xcb\x7a\x32\xc6\x1f\x55\x8c\x27\x36\x40\x3a\xda\x65\xb4\xad\x85\xef\x3d\x73\x43\xba\xe9\x1e\x24\xe5\xf7\xc6\x76\x23\x87\x2e\x88\xee\x09\x84\x91\x39\x20\x9e\x09\xdd\x7b\x38\x1d\x24\x86\x50\xee\x20\x44\x5c\x81\x6f\x51\x37\x9d\xed\x71\xa9\x9b\x50\xc5\xdc\x40\xdb\x22\x86\xc1\xf2\xcf\xfc\xe3\x6f\xff\xf1\xbf\x40\x04\xb6\x69\xf4\x8a\x81\x8f\xf0\x31\x83\xf1\xe5\x40\x59\xea\x3a\xf4\xb0\xb2\x37\x2b\xd5\xef\xc7\xa6\x0a\x3b\xcb\xed\xae\x78\x0d\x42\x23\xde\xe6\xb3\xf7\x37\xb7\x69\x8a\x48\xd9\x0a\xb7\x53\x75\xf7\x18\xed\x5f\x26\x20\x45\x04\xb9\xf2\xf0\x32\x80\x35\x48\x81\x44\xc3\x6a\xea\xa8\xb8\xbd\x56\x10\x46\x0d\x0f\x62\xb2\x8f\x95\x76\x14\x13\x43\xce\x55\x22\x88\x04\xcb\xfa\x5b\xcc\xf8\x3b\xbd\xa9\x11\xc4\x31\x51\x08\xad\x37\x55\xf9\x72\x2d\x5a\xf1\x5b\xce\x7f\x22\x68\x66\x3b\xbc\x7e\xaf\xe3\xf9\x37\xf7\xb4\xc9\x33\xa1\xd2\x60\x2a\xdb\x76\xf7\xee\x5c\xb6\x62\x37\x32\xf1\x82\x6a\xa3\x6d\xf4\xb3\xfa\xe9\x84\x4b\x44\x2b\x06\x62\xf4\xa3\xdc\xb0\x60\x9a\x89\x21\x75\x1e\xb7\xc7\xb9\x9d\x5b\xdc\x8f\x32\x12\x53\x9b\xb6\x2e\x8f\x5d\x64\x98\xb9\x98\x5d\x9f\x22\x8e\x14\x76\x7c\xec\xac\x96\xea\xf7\x01\xd5\xc1\x27\x6f\x3b\x16\x1c\x9d\xe4\x2b\x70\xbc\x09\xbf\xcf\xcc\x8a\x94\x44\x58\x73\x6a\x3b\x63\x76\x55\x55\x6f\x53\x2c\xa9\x48\x59\x8c\x0e\xc8\xd3\x77\x5f\x74\x13\x29\x8f\x13\xc7\x70\xb4\x83\xb2\xd2\xb0\x93\xe7\x9d\xcf\xff\xf7\xd7\x93\x25\x80\x8c\xe0\xdf\x9f\xb6\xab\xdd\xcd\xd3\xfa\x8f\xf0\xb9\xa5\x47\xf5\x1d\xed\x20\xda\xb3\xc3\xc7\xfd\x31\xbc\xc4\xc9\xed\x65\x9a\x08\x5b\x23\x7e\x2e\x4a\x17\x60\x6d\xa1\x69\x3d\x34\x43\xe4\x3a\x8e\x5d\x99\x0b\x95\xde\x24\xb4\xbb\x77\xb1\x3f\x05\xaf\x5a\xf0\xd8\xf2\xdb\x6e\xff\xf9\xd4\x0e\x42\x19\xc1\x41\xa2\xbf\xfc\x11\x88\x7e\xbc\x21\xb4\x65\xda\xf1\x85\x70\x93\x20\x39\x83\xbd\xfe\x9b\x62\x0f\x28\x56\x5d\x95\x2d\x7a\x29\x13\xb4\x8d\x6f\x71\xf9\xf7\xe4\x76\x84\xb6\xbb\x04\x42\x15\xf6\xd5\x69\xc8\xf1\x9f\x8f\x56\xa5\x8c\x62\x64\xb2\x5b\x74\xeb\xc8\xb4\x1f\xa2\x9e\x56\x87\x3f\x01\xfe\xf8\xef\x6b\xab\xc9\x8e\xf5\x25\xb8\x06\x55\x1c\xc4\x3c\xb3\x1a\x11\x4a\xc6\x68\xd6\xac\x1e\xbc\xbe\xaf\xc4\xa7\x14\x68\xee\x1b\x10\xc5\xf9\xb0\x49\xe3\x0a\x94\x38\x35\xf0\x64\x16\x2f\x2f\x35\x26\x87\x7f\x99\xb4\xef\x3d\xed\xcb\x60\x4b\x00\x4f\x52\xe3\x94\x7d\xce\x30\x29\x46\x0a\xe0\x96\x58\xe1\xfe\x66\xb3\xfd\xf3\x7e\x18\x9b\x0a\x10\x49\xcc\x2c\x7e\xa1\x5b\x3c\x23\xd1\x4f\x37\xc4\xe4\x02\x89\xfd\xef\x8b\xf2\x0d\xea\xd5\x4f\x71\x08\x1c\x23\x44\x18\xe1\x00\x05\xba\x0b\x3a\xea\xf6\x02\xa9\x22\x8c\x96\xb9\xa5\x0b\x3b\xbb\x06\x3c\xf7\x5d\x49\xa8\x65\x92\x85\x9f\x4e\x55\xff\xaa\xfa\x7d\x0a\x64\x74\x72\x49\x04\xa5\xce\xff\x9e\x4c\xa7\xe1\x43\x1a\xfc\xcb\x36\x8f\x4f\x9f\x9f\x24\x32\x4d\x2c\x8a\xaa\x7c\x81\xd5\xf6\xcb\x08\x01\x22\x59\xb7\xb8\x71\x1e\x9f\x8f\x6d\x25\x45\xf9\x36\x2b\x25\xd9\xb9\xbb\x11\xf7\xf2\xb1\x98\xa0\xab\xea\xb9\xed\x43\x32\x26\x8c\x18\x6d\x9e\xd7\xe2\xfc\x2c\x82\x1f\x21\x19\x17\x60\x75\xe8\x71\x0e\x3e\x19\xd3\x40\xb8\x9c\xd8\x58\x45\x1e\x44\x48\xd8\xdf\x59\x63\xbd\xe8\xfa\x8f\x39\x3d\x6a\x22\x13\xa0\xb8\x0e\x5b\x68\xda\x1b\x51\xec\x3d\xa5\x6a\xa0\x76\xd2\x8b\x97\xc0\xa2\x43\x64\x1a\xe7\x98\x27\x52\xee\x30\x32\x9e\x88\x70\x6d\xa9\x48\xf0\x95\x1b\xcc\xcd\xac\xda\xd7\x5b\x18\x52\xd6\x13\x99\x6a\xcd\x06\xf4\x86\x13\x01\x26\x37\x28\x53\x12\x4b\x7e\x61\x35\x20\x65\xcf\x04\x0b\x23\xf3\xcc\xb2\xc7\xbe\x40\x5b\x23\xf1\xcb\x78\x66\x4b\xae\x6c\xbd\xec\xe9\x39\xa4\x72\xa4\x48\x13\x44\x40\x38\x06\x8b\x50\xb3\xe9\xb9\x06\x88\x14\x39\x45\x4b\xb1\xb9\xfb\x67\xf8\x48\x98\xc4\x52\x25\x1e\x0e\xa7\xb2\x68\xcf\x56\x1a\x1a\x65\x29\xfa\x8c\x81\x14\x32\xc6\x76\x58\xd9\x5d\xaf\xcb\x71\x4f\xd7\xed\xfc\xdc\xf3\x27\x50\xb6\x06\xe1\xda\x59\xae\xba\xd9\x34\xbb\x4d\x49\x19\xc5\xcc\x0a\x36\x62\x49\xce\x01\x01\x1c\x92\x25\xac\x22\x99\x28\x0b\xb5\xc2\xfc\x27\x12\xd3\x4d\x2a\x2f\x52\x66\x32\xe1\x21\xd5\xff\x0c\xf5\x0f\x28\x30\xfb\x40\xbc\xf2\x31\x91\x32\x4f\xd1\x3a\x21\x1f\xdc\x20\xfa\x92\x52\xa4\xd8\x23\x6a\x5b\xfa\x07\x7d\x2e\x52\x51\x85\xc8\x37\xff\x0a\x91\x15\x67\xd6\xf6\x49\x15\x13\x7c\xde\x5f\x45\xf9\x7f\x3b\xdf\x2e\x9c\x22\x51\x98\x24\xfa\x8a\x2b\x6b\x9c\x37\x93\x2a\xb5\x8d\x32\x56\x09\xc3\x95\xe6\x36\xbb\x6f\x9b\xeb\x30\x22\x4b\x85\x93\x3d\x2a\x8e\xc5\x65\xe8\x2b\x95\x34\x18\x7e\xef\x8a\x66\x0d\x42\x7b\xb7\x45\x6a\x46\x11\xb9\x84\x4e\x33\x36\x14\xf4\x39\x46\xa9\x93\x14\x73\xe8\xdb\x1a\xb1\x5a\xe1\x63\x93\x62\xc6\x56\x89\x5a\x37\x3b\xb9\x17\xea\x6d\x87\xdc\x2b\x93\x99\x0d\x99\x7d\x2c\x88\x6a\xa9\x9f\xab\x7a\xc4\x6a\x49\xa4\xe1\x31\x76\x82\xd4\xd5\x5b\xff\x91\xb0\xa0\x50\xf8\xd9\xae\x4f\x01\x4a\xa5\x22\x22\xc7\x1a\x19\x7f\xaf\xf2\xa0\xa2\x54\x22\x51\x8e\xf0\x3a\x86\xbe\x7d\xcc\x2f\x62\x45\x3a\x0f\xd6\x35\x35\xdf\x95\x4e\xc5\xea\x1c\x8e\x32\x21\x75\x60\x30\x5d\x43\xd9\x03\x4b\x14\x49\x04\xd6\x63\x9f\x7e\x3c\x76\x6f\x63\xf1\x78\xbd\x7b\x5e\xac\xb7\xf8\x3f\x16\x47\x1f\x46\x72\x83\x99\x5e\x9f\xb6\xfb\x94\x01\xc7\x8f\x37\x04\xab\x06\x5d\x20\xb1\x17\x17\x81\xe5\xc0\x63\x56\x54\x0a\x0c\xce\x91\x6e\x66\x7e\x87\x56\x8c\x18\x12\x0d\x25\x11\xbe\x1d\x07\xf1\xbd\x62\x8c\x62\x34\x7b\xf4\xda\xf9\xdb\x6a\xa1\xfe\x73\x2a\x44\x89\x64\x7f\x0d\xae\xfc\x41\xae\x44\xc5\x2c\xb1\x3e\xd1\x2b\xac\x7e\xb6\xb5\xa8\x6a\x5d\x94\xa2\x3e\x6f\x8e\x02\xf3\x2e\x61\x5c\xca\xc9\x00\xee\x72\x59\xd4\x53\x71\x1e\x63\x72\xd5\x23\xfc\xd6\x56\xb5\xeb\xfc\x15\xce\xae\x0d\xf2\x5b\xd9\x16\xe1\x89\xc7\x8a\x46\xa9\x17\x92\x3a\xb5\xc1\xa7\xb9\xac\xc2\xab\x04\xac\xb8\xf9\x0b\xb4\x0f\xe7\x45\x59\x75\xb1\xe1\x35\x52\x96\xfb\x93\xa5\x19\xb3\x7c\xdc\xbe\x29\xbe\xd4\x88\x53\xff\xb4\x9e\xdc\x37\x09\xa9\x94\x33\xd4\xaf\xb0\x7a\x5a\xdb\xa7\xaf\xab\xc7\x4d\xe7\xaf\x8e\x1a\x92\x54\xca\x39\x36\x4d\xc0\x4f\xa8\x55\xd1\x40\x10\xed\x25\x2a\x95\x91\x87\x87\xa3\xfd\x99\x51\xd8\x23\x2a\x35\x31\x36\xb3\x7a\x54\x2e\x86\x1d\xeb\x0b\x54\x88\xca\xa8\xc2\xd2\x4d\xd1\xdc\x95\x68\xab\xb7\x1f\xd5\x40\x64\x89\xa8\x8c\x31\x4a\x03\x90\x5d\xd4\x5a\x89\xe3\x18\x3b\xa2\x32\x91\xa2\x31\x5e\x04\x76\x15\x3f\x59\x7b\xed\x92\x7f\xd1\xde\x88\xe7\xff\xfe\x64\xc5\x65\x12\x30\x4d\xbf\x3b\x9e\x9a\x57\xd4\x61\x41\xce\xcc\xe1\xe0\xfc\x93\x69\x9f\x27\x31\x66\xb0\x6f\x6f\xd7\x95\x7a\x83\x09\x07\xf3\xac\x34\xdf\xf4\x0c\x90\x81\xeb\xb6\xad\x8b\xf6\x3c\x01\xd0\x2a\x11\x51\xc4\x8c\x62\x6e\x7a\x0c\x81\x99\x3f\x9f\x8c\x4c\x64\x42\x6d\x6f\x5b\x1d\x64\xb0\x1b\x92\x53\xe4\xa7\xfd\xf2\xed\xf1\x7a\xbd\xba\xde\xde\x3d\xac\x36\x93\xf7\x22\x39\x47\x0e\x34\x6c\x48\xfb\x0d\x5f\x84\x92\x46\xa5\xa9\x07\x71\x58\xb2\xbd\x1b\x80\x26\x08\x41\x4d\x7d\x59\x25\x0d\x78\x82\xc8\x35\x18\x73\x21\x32\x43\x94\xe2\x3c\xb3\xe4\x75\x5b\xa8\x0f\x45\xd9\xb3\x94\x13\xa5\x09\x57\xd6\x5d\x45\xd4\xe6\x32\x34\x06\x2b\x9d\x49\xe3\xdb\xc3\xbe\x59\xbd\xf6\x09\xf9\xb3\x1f\xa8\x0c\x96\x67\xad\x1c\x3f\x92\x82\x77\x7b\xd3\x7a\x77\xf5\xf4\xf8\x6d\x13\x4e\x67\x00\x41\xd8\x38\xcd\x77\xcf\x55\xf5\x29\x53\x9b\xfb\x02\x44\x24\x73\x5d\x15\x8b\xab\xbb\x2f\xa2\x79\xbd\xa9\xea\x87\x6a\x2c\x45\x40\x14\xb0\x14\x17\xd7\x09\x2d\xda\x9d\xf6\x9d\xbf\x0a\xd2\x04\x41\x64\x45\xb3\xc4\xbd\x74\x5d\x1d\x90\xe5\x7a\x89\xac\x45\x98\xa5\xb8\xd9\x86\xc1\x8a\x89\x90\x3a\x40\xdf\xa2\xc7\xbd\x2b\x43\x08\x9b\xb8\x97\x9b\xee\x61\xbb\x2d\x76\xf2\x38\x0c\xa4\x48\x9e\x8c\x45\x9d\xa5\xed\x3b\xdf\x7e\xea\xd3\x68\xd2\x6d\x1f\x1e\xcd\x66\xaa\x53\x7d\x57\xbe\x5b\x40\xdb\xb7\x1e\xc6\xe9\xc7\xaa\x5c\x00\x76\x10\x20\xf0\xdb\x77\x4d\x0f\x2c\x92\x26\xc6\x02\x9f\xbb\xb7\x76\x92\x81\x89\xd9\xf5\x4f\x5a\x7e\x99\xe1\xf3\xd3\x54\xda\xee\x90\xe0\x78\x23\xe7\xc0\x90\x19\x99\x68\x26\x72\x44\x1e\x38\x8e\x0a\xdf\xdd\x3b\x9f\x1b\x9d\x5f\x42\x9a\x39\x16\x5e\x47\x5d\xfd\xfc\xf6\x12\xce\xae\x6d\x3f\xeb\x43\x51\xb6\xf7\xd5\x05\x1f\xa4\x1b\x15\x53\x0b\x6a\x43\x6c\xe9\xa8\x60\xf6\xaf\xf4\xdf\x21\x54\x4e\xff\xed\x87\xa7\xda\xc7\x41\xcb\x57\x68\x06\xcd\xf6\x64\x7a\x65\xb1\xb2\xad\xf9\x8d\x30\x70\x5d\xbc\x7b\xe4\xec\x68\x4c\x42\x38\x42\xd0\x07\xed\xfb\xe3\x65\xa8\x13\x16\x7b\x36\x6b\xa4\x71\x13\xfb\xde\x3f\xec\x36\xcd\x6d\x0d\x0d\x76\x5f\x4e\xbe\x96\xa6\x76\xfd\xb9\x2e\x2c\xdc\x48\xe7\x2a\xc0\x3a\xc9\x69\xec\x30\x7f\x57\xd0\x6e\x5f\xdd\xf9\x9e\x83\x57\xab\x93\x5c\x62\x46\x06\x73\xc3\xd8\x4e\x3b\xfe\xad\x34\x4b\x7c\x1b\xb6\x63\x9a\x43\x7e\xf9\x67\x98\x4a\x3a\xfb\xf1\xda\xfa\x77\xab\xa6\x2d\x0e\xa2\x85\x3e\xe4\xd1\x29\xc4\x08\x40\x3a\x8a\xa2\x6c\x6f\x6b\x61\x4c\xd1\x16\xd3\x09\x31\x4c\x17\xe9\x3c\x32\xda\x41\x6b\xbb\x5f\x9b\xdc\x5c\x6e\x34\x1a\x31\x6f\x13\x46\xc4\xf7\xc3\x48\x51\x73\xc6\x48\x1e\x52\x28\x8b\x77\xd1\x8a\x7a\xb6\x58\xa8\x45\xc4\xc1\x45\xd3\x18\xd3\x1d\x8e\x55\xdd\xde\x00\x2c\x11\xfd\x35\x9e\xe1\x22\x8f\x59\xea\xaf\x0e\xd3\x8d\xbf\xba\x17\x49\xac\x43\x7b\x8f\x72\x6e\xb6\xf7\xed\xe9\x08\xe5\xd4\x36\x6b\xc9\x2d\x37\xe5\xdd\xe3\x7a\xf7\x74\x28\x0b\x5d\xed\xf7\xc2\xa3\x8d\xb5\x54\x3a\xb3\xcc\xf5\x8f\x95\x86\xed\xfd\xf5\x93\xf1\x49\xd3\x30\x46\xb1\x0c\x5d\x1d\xfc\x29\x04\xda\xea\x01\x83\xd8\xe4\x8e\x55\x46\x11\x63\xfd\xb0\xda\x2e\xbe\x2c\x36\x5f\x50\x5d\xd0\x1d\xd3\x34\xc3\x48\x5c\x9e\xce\x3b\x28\xf5\xae\xed\x1d\x39\xad\x25\xc5\xbc\x43\x8d\xd4\xe4\x96\x50\xf4\xd7\x20\x13\x0d\x49\x44\x1c\x76\xcd\x63\x20\xc7\x76\x05\x12\x4e\xc5\x84\x87\x6e\x32\xc2\x18\x64\x77\xd8\x81\x3e\xa9\xd0\x17\xed\xaf\xc9\x10\xab\x50\xd2\x3d\xf6\x2b\x08\x14\x4d\xda\xb0\x28\x55\x8e\xb3\xf7\x17\x7d\x43\xda\xe4\x24\x00\xb1\xb1\xa4\x8a\xee\x87\x3f\xa8\x15\xe6\x7f\x8e\xa2\x85\x12\xbb\x9f\xbb\x25\x7a\x0d\x7b\x4f\xbe\x4a\x20\x62\x29\x6e\xda\x9e\x97\xa7\x72\x45\xdb\x01\x8f\xf5\xe8\x07\x21\x8a\x23\xec\xf2\x70\xc6\xd9\x66\xe6\x40\x5f\xbd\x4d\xba\xce\x21\xca\x24\x92\x4f\x56\xe5\xfe\xbc\x44\x91\xff\x87\x9e\xff\x04\x48\x12\xb9\xe6\x88\x52\x5f\x89\xc1\xe7\x9c\x88\x78\xa8\x5f\xd3\xf9\xc7\x48\xbf\xd3\x8f\x10\x58\x21\xee\x11\x0a\x41\x2f\xd9\x65\x25\x2d\x6f\x94\x1f\x4f\x41\x26\xe0\xf5\x00\x3c\x3f\x9d\x3f\xc8\xe2\x0c\x43\xed\xdb\xe5\xd3\x3f\x17\x4b\x27\xe9\x75\xe9\x7a\x4d\x9a\xef\x20\x8e\x22\xac\x5c\x82\xaa\x6c\x61\x72\x5c\x0e\x82\x58\x5a\x79\xfa\x02\x17\xe3\x84\xd1\xcb\x8d\x49\x72\x4b\xa1\x72\xac\xe1\x4e\x55\x03\x32\x39\x48\xb9\xa5\x52\xda\x8b\xa6\xbd\xaf\xda\xb6\x1a\x44\x23\x90\xba\xb0\x7c\x0f\xa6\xf5\xc4\xdc\xee\x50\x06\x56\x70\xa4\x81\xbd\xb9\x1f\x3c\xeb\x9c\x59\x6d\x30\x5b\x5d\xf9\xdb\xa0\xa3\x3e\xbc\x80\x5c\x28\x2c\x68\x2c\xae\x96\xbf\x4f\x99\x03\xcf\x29\x55\x7d\x35\x72\x24\x61\x49\x80\x73\x0b\x14\xb8\x5a\x2c\xbf\xde\xaf\x16\x37\xe1\x73\x21\x91\xc4\x62\xf3\x51\x98\x36\x7c\xa8\x95\x34\x21\xa6\x46\xd5\x98\x5b\x71\x80\xd5\x67\xed\xdd\xc0\x4d\x96\x78\xd6\xe0\x2f\x45\xbb\xa9\x4c\xdb\xb7\x0a\x80\xa0\x16\x29\x5f\x75\x0e\xe4\xe6\x0d\x5a\xf5\x3a\x21\x37\x9f\x9c\x4e\xe4\x12\x63\x8d\xff\x79\xdc\x7e\x6b\xf4\xf0\x25\x09\xa9\xd0\xd0\x2c\x3f\x83\x97\x7f\x5e\xc1\x01\x99\xc6\x58\x3d\xd7\xce\x61\x47\x72\x98\xc9\xf4\x90\x82\x2b\xee\x01\x3a\xc8\xa6\xe6\x9b\x76\xc2\x2c\x53\x8c\x3a\xec\x12\xf2\x70\x6c\xab\x2f\x7d\xbf\x1d\x28\x91\x5b\x71\xb7\x6e\x13\xbf\x53\xd5\xa8\x7e\x0f\x4a\x03\x3a\x03\x87\x1d\xe6\xef\x07\xc0\x1a\xd0\x4c\x0b\x87\x0c\x42\x6d\xae\xf9\xcc\x0e\xe8\x2c\x16\x7a\x00\xf5\x1b\xdb\x45\x00\x2a\xb1\x50\x56\xa8\xca\x37\xbd\x0f\x67\x31\x30\x8a\xf4\x47\x7d\x68\xd2\xdc\x54\x75\x77\x81\xe3\xe7\x6f\x62\xc0\x4e\xcd\x77\xdf\xfe\xfc\x1b\x84\x07\x98\x2c\x41\x5c\xc4\x73\x35\x23\xbe\x15\x02\xe7\x4f\xda\x80\xff\x3f\xff\xfa\x9f\x96\x09\xa6\x4f\x77\x2f\x9d\x33\x26\x0e\xc7\xe9\xbd\x68\x16\xb9\xd7\x55\x87\xa4\xae\x89\xa4\xc4\x0b\x3e\x56\x47\xf4\x4b\x5d\xae\xfc\xa6\x86\x20\xb3\xe2\x5f\x8d\x21\x60\x02\xa1\xb5\x05\xf0\x0c\x96\xbf\x21\xc6\x18\xc7\xe0\xeb\x2c\xce\x4d\x55\x6f\x7f\xf6\x61\xb8\xa1\x59\xaa\x59\x9f\xa1\xb0\xe0\x3f\x7f\xcc\xb1\xf2\x14\xcd\xb7\x06\xea\xe7\x6a\x5f\xa8\xf3\x02\x65\xdb\x43\x14\x65\x28\x18\x44\x2c\x14\x4d\x40\x43\xf9\x23\x86\x5b\xec\x6a\xc8\x6b\x17\xef\x3e\xe9\x6a\x58\x2c\xb1\xb5\x69\xb7\x3b\xa1\xae\x05\xf2\x21\x8d\x1f\x8e\x61\x79\x84\xc8\xf2\xe5\xf6\x76\xb8\x3f\x9a\x38\x25\x3a\xe9\x59\x25\x7d\x3b\xca\x6c\x19\xd9\xc4\xda\xd8\xfa\x56\x17\x81\x0e\x9a\x22\xa6\xe3\x92\xc4\x76\xe4\xa0\xb6\xda\x24\x69\x6a\x12\xee\x24\x8e\x9a\x7b\x81\xad\x25\x45\x59\xd5\x5b\xd4\x21\x98\x7b\xed\x26\x25\x0a\x03\x21\x8c\x61\x8b\xbf\x20\x70\x97\x98\x94\x00\x5e\xbb\xae\xab\xa3\x4d\xe0\x9c\x06\x90\x5d\x93\xc6\x34\xb6\x80\x8c\xd2\x14\x2f\x4e\xb6\xf3\xef\x17\x75\x2f\x32\xcd\xff\x18\x27\x1d\xc6\xcf\x37\xe5\x3c\x72\xf8\x82\x2f\x50\x57\xcb\xbd\x68\x9a\x09\xfd\x3b\x31\xa9\x4e\x31\x82\xee\xf5\x7d\x3e\x91\x41\x9a\x5d\x7b\x26\x8b\xb2\x34\x0a\xbe\x2f\xe6\x1d\x5d\xa3\xb6\xd3\x3a\x3d\x1c\xaa\xb2\x0b\x89\x67\xb4\x03\x89\xc9\x44\x0c\x71\xdf\x18\xd1\xd3\x17\x0f\x03\x3f\x93\x0b\x1a\xe5\x81\xe7\xf0\xa9\x7e\x11\x65\xd1\xcc\x20\xf9\x0d\xa7\xb6\xb9\xaa\x73\x00\x6b\x38\x1d\xae\x61\xdf\x0a\xff\x66\x78\x42\xd1\x00\x1f\xeb\xea\x08\x75\x7b\x46\x43\xb7\xad\x66\x6a\x99\x86\x2b\x1b\x8f\xbc\x88\x03\x0c\xb3\x4c\x86\x1b\x86\x5e\xa8\x2c\x5a\x5d\x8e\x38\x41\x8d\x60\x16\xe6\x6e\x11\x29\x6d\x55\x4f\x95\x7f\x89\x11\x59\x8c\xf5\xf3\x4d\x71\x38\xee\x61\x28\x90\x45\x8c\xe0\xb1\x76\xcf\x11\x69\x96\xfa\xa0\x36\x0c\x50\x68\x7b\x9f\x45\xdd\x96\x3d\x8d\x80\x11\xc0\x90\x72\x7e\x59\x39\x66\x8c\xcd\x47\xd1\xaa\x57\x18\x07\x92\x6e\xb0\x64\x39\x96\x57\x77\xb5\x53\xea\x11\xcd\x2b\x68\xc7\x9a\x36\xff\x82\x65\x92\xc6\xa3\x86\xbe\xc9\x29\x55\xa4\xb5\x73\x69\xde\x9f\x6a\xa1\x7a\xfb\xa0\x72\x85\x3d\x7c\x50\xea\xeb\xa2\x39\x9e\xfa\xc7\xa8\x94\x41\x2e\x71\xcc\xc8\x83\xf6\x65\x8e\x70\x4f\x9a\xa6\x11\x78\x7e\xd4\xb6\x85\xba\x80\x66\x42\xfc\xea\x47\x32\x89\x10\x9a\x5d\x5d\x75\xef\x69\x29\x4e\x7b\x5d\x3b\xd8\xa0\x0b\xab\x0c\xc4\x0c\x13\xee\xae\xdf\xec\xba\xdb\x7c\x1e\xab\x35\x74\x6e\x5a\xf8\x49\x10\x4c\x87\x54\x13\xde\xa9\x1e\x3e\xfd\xce\x9f\x84\x20\x4b\xbd\xa8\x6b\x71\xbe\xb2\x16\x21\x9c\x40\x89\xd4\x13\xc4\x1c\x6d\x62\xd7\x97\xef\xc7\x97\x6c\x12\x86\x9b\xf4\xf3\xb7\xf5\xf2\xcb\x62\xb3\x5a\xef\x1e\x16\xff\xb4\x09\xd6\xdd\x72\xf1\xec\xcf\x67\x72\x92\x90\x9e\x26\x46\x94\x6f\xe1\x5a\x0d\x4f\xa3\xc4\xaf\xb9\x43\x51\xde\x00\xcc\xf2\x73\x1a\x23\x33\x6c\xaf\xde\xdd\x5b\xb8\xc6\x1a\x17\xd0\x38\xcd\x44\xa3\x28\x36\xb9\xcb\x46\x75\xde\xe2\x27\x7a\x01\x34\x8a\x92\x1c\x31\x22\xab\xcd\xf2\xca\xf1\xb0\x1f\xfb\xa5\x33\x72\x15\x68\x14\xe5\xb6\x77\x7d\x5f\xbd\x3c\xd7\xd5\xa1\x40\xf5\x1a\x53\xd4\x87\x49\x20\x49\x23\x4a\x12\x5c\x38\x6f\x70\xfe\x22\x9a\xe7\x53\x7d\xac\x1a\x98\x05\xf7\xd2\x88\xe5\x3a\xb6\x78\x56\xcb\xdf\xe9\x5a\xf3\x69\x94\x10\x83\xb5\x25\x9b\x47\x7e\x16\x4d\xf3\x51\x0d\x44\x2a\x3e\xf5\xcb\x68\x94\x08\x8d\xdd\x3f\x2e\x3f\x7f\x5d\x34\xc8\xae\x34\x30\x40\x34\x4a\xa4\x92\x36\x9a\x75\x29\x7b\x37\xd1\xc7\xb7\x9c\x18\x02\xe9\xa0\xf2\xba\x6b\xa0\xdd\x1d\xeb\x42\xc1\xae\x8b\x6c\xaa\x53\xbb\x1b\xe0\x2b\x68\x94\xc6\x40\x8d\x27\xd4\x98\xba\x0e\x34\xca\x32\x4b\xd2\x6d\xcd\xb2\xa7\x4a\xea\x4b\xd5\x34\xca\xb8\xb2\xd1\x04\x06\x81\xcd\x30\xec\xa7\x51\x06\x59\x12\xb4\x9a\x36\xd0\xe2\x25\x17\x7f\xc1\x46\x18\xcc\x76\x0c\xb6\x25\x1a\xe5\x91\x42\x37\xe6\x28\x4e\x0d\x4c\xc8\x77\x69\x94\x33\x4b\x94\x85\x6b\xc3\xb6\x77\xff\x4a\x86\x92\x46\xb9\xd1\x69\xe4\xa9\xe4\xb1\x67\x7c\x03\xe5\x54\x06\x99\x46\x5c\x58\x55\xd8\xab\xe7\xdd\xf3\x6a\xbd\xb9\x5b\x3c\xfa\x5f\x14\x40\x65\xe2\x4b\x1b\x3f\xaa\xfa\xad\x99\xdd\x88\x69\xa4\x98\x45\x17\x6f\xc5\x79\x5f\x0d\x69\xdd\x68\xa4\x74\x8e\x65\xf5\x8d\x25\xcb\x9a\xcd\xb1\xbb\xa1\x3a\xb5\x95\x94\x81\x3a\xd5\xb7\xba\xb8\x84\x9e\x5c\xc0\x50\x68\xa4\x65\x8c\x05\xa0\x9d\x63\x59\xf0\xb6\x6c\x3e\xf5\x4b\x23\x0d\xb6\x23\xa2\x84\x9f\x43\x4e\x5f\xeb\x75\xbb\x31\x90\xc4\x88\xe9\x41\x37\xfe\x0a\xda\xc9\x63\x33\x89\xa5\x88\x73\x79\x6d\x47\x55\x37\x8a\x46\x29\x89\xb2\x0c\x8d\xaf\xa8\xad\x8a\xa4\x37\x6a\xdb\x6a\x28\x0b\xea\x06\x93\xd8\x52\x73\xae\xab\x3d\x78\x1b\x31\xd3\xcf\x41\x09\x31\xda\x66\xa8\xc4\xb1\x08\x65\xc2\xee\x63\xab\xe7\x53\xa8\x6a\x55\xea\x3e\xfd\x42\x09\xa5\x11\x82\xaf\x71\xe2\x93\xf0\xa9\x48\x11\x40\xbf\x33\x21\x06\xa1\x84\xc5\xb6\xfe\x09\x3f\x8f\xdb\x9f\xbf\x2c\x5a\x50\xc2\x12\x2b\xb5\x5a\x34\xd8\x21\x3d\xc7\xc5\x41\x09\x03\x6d\xc9\x25\x10\xc5\xe9\xd5\xae\x1f\x0a\x04\x46\x5a\xad\xa8\xcb\xe6\x56\x4a\x98\x21\x11\x77\x6e\xed\xe2\xd0\xae\xa1\xcf\x39\x8e\x66\x39\x89\xa3\xcc\x88\x21\x19\x4c\xb3\x74\x30\x5b\xed\xef\x29\x66\x14\xa1\x3a\xb7\xd0\xfe\x28\xca\x7e\xdb\xa6\x24\x96\xa0\x1c\xab\x77\xb7\x8e\x3c\xdb\xc6\x04\x68\x46\x49\x4a\x52\x0f\x48\xdd\x83\x6a\xed\xe6\xee\x4f\x92\xc6\x2c\x72\x84\x24\x2f\xf0\x03\xc4\xb1\x2a\x9f\x4f\x35\x5c\x8b\xc3\x2f\x18\xca\x26\x8f\x32\xe5\x1c\x83\x67\x0d\x2d\x56\x50\x06\xed\x79\x73\x83\xb5\x37\x59\x0f\x55\xd9\xb4\x50\xdf\xc3\xbb\xa3\x6e\x73\x74\x3c\x38\xc8\x68\x4c\x05\x6c\xbf\xad\x1f\x77\xd7\x8b\xed\x2a\x5c\xb0\x88\xd1\xd8\xea\x2e\x1c\xea\xa2\x11\xfb\x52\x3e\xab\x4b\x0e\x6c\x30\x49\x45\x8e\xc9\xb1\x23\xca\xa9\xa2\x73\x83\x85\xbc\x30\xd5\x52\x9d\x60\x77\x0b\x6a\x64\x20\x28\x7c\xf5\x13\xd4\x2f\x3b\x18\x28\xc9\xa2\xc4\x18\x4f\x43\xb0\xc3\x3d\xa0\xee\xcb\x69\x94\x64\xb9\x8c\x1c\xe7\x0c\x0d\x9f\x49\x2b\xa1\x6f\xe7\x55\xfd\xad\x0c\x70\x1d\x8a\x18\xfd\x78\x52\x72\x78\x0b\x89\x2c\x4a\x72\xc3\x31\xf2\x43\x2c\x41\x51\xb6\x9e\x9f\x81\x12\x6e\x48\xc4\x7a\xf5\x4e\xd4\x10\x85\xfa\x22\x49\x40\x89\xd0\x96\xd9\x31\xfc\x84\x9d\x59\xcb\x4f\x3c\x38\x4a\x64\x1e\x8b\x5e\xe0\xee\x11\x3e\xae\x17\x4f\x93\x73\x4a\x6e\xd9\x75\xbf\x9c\x8f\xfd\x82\x94\x3c\x45\x6f\xba\x5b\xff\xaf\xa2\x79\xf5\xb6\x7f\x62\x69\xa4\x06\xf4\xe1\xaf\x8a\x16\x89\x71\xfc\xe7\x8a\x71\xc4\x6b\x08\x0c\x28\xa7\xd0\xdc\x4f\x22\x9b\xc9\xa5\xab\xcc\x0a\x11\x35\x6d\x75\x1c\x1a\x77\xa2\x84\xd2\x66\xc0\x55\x73\xb1\x6e\x94\x34\xc6\x39\x35\x77\xe6\x7b\x35\xa8\x2d\xfe\x63\x32\x10\x24\xba\xf4\xa1\x61\xd3\x9a\x53\x4f\xfd\x30\xb9\x59\x65\x6c\xfc\xd6\x40\x6b\xdb\x00\x7c\x09\x79\xaa\x1c\x41\x89\xa6\x4a\x77\xf7\xbf\x2f\x0c\x3c\x57\x45\xe0\x6d\xa7\x44\x67\x3c\xe9\xc9\x50\x6f\x45\x83\x74\x55\x4f\xa6\xdb\x9a\xbb\x8d\x72\x72\x22\x20\x19\x16\x91\x76\x47\x71\xf6\x00\xf0\xe9\x10\xa3\x90\x55\x09\x4a\xfd\xfc\x1a\x94\x0f\x28\x31\x22\x06\x32\x40\x77\xed\xc4\xbe\x78\x87\xdd\xa9\x6c\x8b\xfd\xae\x7d\x2d\x9a\xdd\x80\xa0\x9a\xd2\x88\x28\x26\x03\xce\xf1\xfe\xdb\xe3\x6a\xbb\xf9\x65\xee\x85\xd2\x28\xc9\x04\x1f\xf4\x19\xce\xa2\xd2\x28\x8d\xa4\x15\xc6\xf2\x6c\x9a\x5b\xb1\xdf\x17\x83\x77\xf2\x59\x1a\x92\x52\x9a\x58\x79\xcc\x17\xe8\xb6\xc2\x16\xea\xc7\xd3\xe1\xc9\xfc\xf0\x4c\x99\xe3\x9f\xa1\x3c\xc2\x4c\xb2\x01\xb8\x2a\xbc\xb2\x17\xb6\xa9\x47\x71\x4f\xf8\xaf\x2d\x9d\xe5\xf8\xd5\x52\x46\x38\x3a\x01\x03\xca\x5c\x5b\x01\x01\x7d\x75\xb6\x7c\xba\x97\x8c\x6b\xfe\xbb\x31\x11\x43\xa8\xec\x75\x67\x15\xbb\x30\xf3\x79\xd2\x07\xd1\x0d\x95\x2c\x1b\x0c\x15\x7b\x1a\xae\x20\xe1\xae\x16\x69\x9b\xaa\x4f\xf3\x8a\x56\x93\xf3\x71\xbb\xc5\xc8\xd3\xf9\xaa\xaa\xf0\x15\x8c\xaf\x2d\x26\x04\x3b\xb5\xb1\x2d\xaf\x86\xeb\x40\xbf\x44\x69\xac\x98\x23\x82\x2d\xa3\x4d\x0b\xc7\xf0\xb9\xb1\x26\xe6\x58\x57\x3f\x8b\x39\x29\x21\x4a\x93\xd8\x72\xbf\x5f\x5f\xaf\x86\x0b\x93\x26\x9c\xa8\xdc\xf3\x9f\x55\x6f\x7f\xcc\x34\x97\x50\x9a\x6a\x62\x51\x85\xb6\xe0\x59\x68\x08\xd4\x2f\x94\xa6\xc6\x60\xb3\x0e\xf6\xa5\x0f\xbd\x0f\x9a\x31\x83\x8f\x6e\xe7\x48\xd2\x4f\x25\x3c\x1d\x03\xa5\x91\xb3\xed\x43\x4d\xa0\xa0\x3b\x82\xc5\x51\x9a\xf7\xff\x93\xc6\x93\x37\x98\x53\xad\x5c\x4c\xf5\xcd\x1e\x98\x3c\xc6\x5c\x19\x15\x2a\x90\x5f\x2a\xbd\xb7\x64\xe0\x37\x13\x05\x1a\x4a\xb9\xe0\x58\x3f\xec\x16\x56\xc8\x72\x6e\x6b\xd1\xc5\x0d\x56\xf1\xf4\x22\xc5\x32\xfe\x25\x41\x08\xb6\x30\x75\x41\x4e\xe9\x74\x1b\x07\xca\x62\x7e\x94\x8a\xf0\xbd\x7b\xc7\xd3\xa5\x13\x66\xb7\x39\x2a\x89\xb0\x76\x14\xb3\xc6\xdf\xad\x34\xbd\xa5\xd3\xf5\x23\x18\x45\xa8\xd0\x6b\xf1\xde\x05\x93\x03\x4d\xbd\xee\x98\xc2\x5a\x02\x86\x12\x8b\xfa\x70\x9e\x9b\x10\x92\x69\x70\x65\xc6\x6d\xd1\x9e\xf6\xa2\xa8\x61\xd7\x39\x44\x2d\xec\x48\x34\x79\x98\x32\x8d\xbd\x22\x8b\x07\xb0\x5c\x9d\x27\xb1\xc4\x64\xce\x48\x4e\x32\x87\x63\xbf\xeb\xdc\x9b\x6e\x37\xaa\xca\x49\x3a\x8b\x52\xa9\x95\xd5\xff\x76\xda\x92\x96\xac\xd5\x1d\x54\x8e\x16\x18\x51\x08\x56\xf9\x1e\x31\x59\xdb\xd7\xba\x2a\x61\x7d\xda\xc3\x85\xe3\xf3\x6b\xef\x89\xaa\x2c\x37\x79\x28\xc5\x95\xd0\x5e\x43\x2b\x8a\xfd\x27\xfe\x13\xd5\x4e\xf6\xca\x82\x33\xef\xca\x6f\xc1\x54\xd3\x6e\x17\xcd\xfd\xfc\x7a\xae\x2b\x33\x61\xcb\xa4\x14\x32\x89\x2c\x1e\xe1\xea\x3b\x4f\xa8\x79\x1d\xca\xb1\x77\xd3\x7b\xb8\x64\x58\x94\x98\x28\x0b\xa4\xb6\xa5\xcd\x5c\xf4\x9c\x5b\x7e\x14\xe4\x48\xa0\xf8\x20\x7e\x0e\xc8\x54\x28\xa3\x19\x77\xd9\x6b\x64\xd3\xb3\x8e\xc6\xdf\x6a\xe6\xa5\xc8\xae\x1c\x88\xf6\xf0\x2d\x84\x9a\x0c\x65\x2c\x4b\x3d\xad\x68\x2f\xba\xea\x89\xf6\x28\x63\x90\x20\x5b\x78\xf5\x73\x42\xb0\x46\x19\x33\x56\xc1\xcd\x47\xc5\x16\x4c\xe7\xbf\x98\xd2\x1c\xf1\xb1\xcb\xb3\x84\x7a\x2d\x8a\xfd\xa3\xaf\x41\x51\x96\xe6\x96\xf7\xf8\xaa\xd8\xef\x3b\x8f\x6c\xfe\xb2\x33\x11\xe3\x46\xb5\x0d\xdf\xcb\x64\xcc\xac\xab\x81\xaf\xc6\x53\xd1\x39\x48\xef\x64\x07\x62\x99\x54\xd9\x80\x90\x71\x53\xfc\x05\x4b\x7f\xa6\x5c\x69\x62\xbb\x0c\x35\xc0\xe1\x7b\x75\x52\xaf\x50\x4f\xba\x09\x7f\x85\x9a\xa4\x2c\x07\xc5\xbb\x07\xf3\xe5\xc7\xed\x10\xda\x4f\x19\x4f\x34\x06\xf0\xbd\xec\xd5\x2f\xb7\x6d\xc6\x41\xe4\x8e\x86\x6a\xa3\x5e\xe1\x20\x9a\xa1\x00\x2d\x65\x42\x33\xdf\x0b\x6d\x53\xb8\xd3\xfb\x94\xb9\xc1\xce\x2b\xdc\xed\x44\xb1\x3f\xbb\xc9\xe1\x0e\x6b\x65\x29\xc6\x77\x5e\xeb\xc2\x06\xd5\xeb\xbb\x3f\xe6\x3b\x3f\x28\xd3\x86\xa2\xbb\xb4\x5e\x3d\xae\xfe\xb9\xdb\xac\xb6\xdb\xfb\xd5\xc3\xea\x71\xbb\xf3\x4a\xcd\x94\x41\xc4\x8d\x6d\xcb\x29\xaa\x71\x06\x9f\x32\xc8\xe3\x7c\x08\x75\xec\x79\xd1\xc7\x3f\x03\x82\x20\x3c\x1a\x6e\xab\xbd\x56\xaf\xa2\x28\x37\xbd\x7e\x08\x65\x60\x98\x4f\x67\xfb\x84\xb8\xd3\x3d\xa8\xea\x99\x0c\x36\x65\x26\xb2\xe0\xd4\x71\x51\xcb\x11\x0e\x4f\x7e\xdb\x10\x69\x91\xbf\xd5\x15\x04\x6f\x90\x99\x38\xb6\x8d\xdf\xaa\xaa\xe1\xba\xfa\x98\xcc\xf8\x98\x24\x89\xf2\x70\x04\x84\x50\x62\x80\xd6\x97\x25\xbb\x11\x39\xe2\x09\xb6\xaf\x58\x82\x29\xfb\x03\x20\x74\xee\xd9\xb2\x8a\x72\x8d\x08\xdf\xa8\x73\x59\xed\x3f\xfd\x38\x1a\xc7\x98\x01\x6c\x7b\x7d\xbc\x09\xe7\x2d\x8d\x69\x62\x95\x60\x24\x8c\x28\x33\x69\x4c\x33\x2d\x13\x1f\xd2\x60\x41\xc4\xe5\x93\xc7\xb7\x41\xa5\xd5\xf7\x77\x0c\x80\x3f\xc4\x3b\x02\x0f\x4e\xde\x26\xc4\x0c\x14\xc6\xff\x47\x71\xbe\x86\x77\xff\x69\x1c\x25\x98\x2a\x40\x81\x81\xfb\xa2\xb1\xaa\xfd\xfe\x68\x22\x22\x44\xde\xcd\xf8\x6c\x0b\xd3\x42\xed\xf3\xce\xb3\x8b\x20\x4e\x84\xe0\x56\xdf\xc2\x12\xe6\xe1\x83\x65\xe1\xdc\xda\x36\xb5\xda\x94\x22\x52\x8e\x3f\x8b\xda\xe5\x6b\xfa\x1c\xd9\x2f\x17\x6c\x9c\x66\x56\x20\xed\x16\x5b\x3c\xf7\x3e\xbc\x70\xed\x46\x7e\x0e\xc4\xa9\xc8\xb1\xf0\xbb\x17\x4d\xfb\x88\x62\x85\xef\xf0\xbd\x6a\xfb\xc0\x31\x4e\xa5\x55\x46\xef\x03\x4b\x78\x87\xf2\xf4\x6b\x1e\x72\x1a\xa7\x3a\x46\x2c\x0b\xea\xf7\x6b\xed\xd7\x67\x9c\x91\x34\x12\x3e\x58\x6e\xab\x16\x9c\xc7\x3a\xa4\x07\xf5\xd9\x0c\xff\x9d\x3c\x4b\xa5\xe7\x6e\x5f\x3e\x6c\xb1\x8d\xa4\x69\x2f\xd5\x4a\x69\x9c\x2b\xdb\x28\x74\xbd\xd8\x7c\x59\x5c\xdd\xfd\x02\x70\x44\x63\x9e\x67\x3e\x50\x7b\x04\x2b\x26\x7f\xd9\x59\x4a\x63\xce\x2d\xd9\xf4\x0b\xb4\x6f\xc5\x7e\xef\xc8\xce\x2d\x20\xa5\x29\xaa\x32\x54\x3c\x69\xcc\x45\x42\xfb\x5c\xf0\x1f\x23\x7a\xcb\x8b\x1e\x0d\x1a\x0b\x95\x79\x3e\xd5\x35\xfc\xaf\x15\xc8\xb8\xa4\xc9\xa5\xb1\x8c\xec\xed\xd7\x2e\x0c\xf6\x19\xd9\x53\xd3\x56\xba\x10\x61\x31\xc9\x28\xc7\xa6\x11\x25\xf6\xfb\xa6\xad\x6a\xd0\x62\x14\x68\xc4\x32\xa5\xc2\xa6\xc6\x91\xc7\xa4\xf3\xf0\xc2\x84\x96\x59\x84\x06\x3e\xc4\x7a\x0b\x2c\x9e\x38\xd0\xcb\xf4\x8a\x32\x4b\x07\xdd\x19\xab\xf6\x75\x00\x03\xa4\xb9\x1f\xa1\x24\xb2\x82\x9d\x1a\x40\x5b\x37\x94\x17\xee\x8e\x9a\xc4\xdd\xf9\x80\x51\xff\xea\xf7\x8c\xfa\x34\x56\xb9\xc1\xa0\x7f\xd7\xf3\x18\x0e\x3d\xad\x58\x13\x82\xd5\xaa\x2b\xd1\xb6\xfb\xce\xcf\x42\x72\xd0\xdf\xb9\x0e\x9f\x4c\x62\xad\x95\x17\xbd\xfc\x5a\x34\xcd\xd5\xd6\xef\xa8\x31\x28\x45\xbc\x3a\xb5\x25\x10\xff\x6f\x7a\xc1\xfd\x49\x4c\x8c\xa9\xd2\xe7\xfb\xc5\xf6\xe6\x69\xfd\xb0\xbb\x5e\x7d\x5f\xdd\x3f\x3d\x77\xbb\x8f\xff\x21\x93\x0b\xd4\x2d\x70\xbc\xc4\x9b\xd7\xaa\xf6\xa8\xae\x66\x5b\x79\xba\x9c\xa2\x1a\x4b\x00\xda\x2f\x27\x51\x14\x21\xe0\x68\x7d\xb7\xf1\x99\xb0\x24\xe2\x11\x26\x9e\x7c\x18\xb8\x1c\x68\xe5\x4e\xbe\x4e\x08\x57\xce\x87\x7b\x68\x5e\xb0\x71\xfe\x17\xc9\xec\x84\x92\x88\x39\x52\xd1\xba\xb0\xc2\x19\x41\x5f\x84\x26\x34\x8d\x49\x1e\xf4\x99\x27\x6d\xcf\x6e\x0c\x23\x09\x4e\xc2\xe5\xe2\x71\xb9\xba\xdf\xad\xfe\xb9\x5d\x2f\x76\x81\x5b\x88\x26\x2c\xcd\x3d\x1e\xd4\x2b\xbf\xf9\xec\xe6\xcc\x32\xb3\xe9\xf2\xe9\x7e\x9f\xc4\x39\xe3\xcc\x11\x96\xd1\x88\x70\x0b\xc3\xb6\x0d\x96\xfe\x87\x92\xd8\x86\x52\xb6\xf0\x7b\x57\xbe\x43\xd9\x56\xf5\x58\xcd\x94\x26\x49\x16\x21\xd8\x6e\xb1\x2f\x14\xcc\x3d\xff\x24\x37\x68\x3b\xf0\x18\xbb\x0e\x67\xe7\x09\xbe\x96\x1f\x5d\x9c\xa5\xa0\x19\x3a\x54\x49\x1a\x27\x44\xf5\x64\x30\xbd\x43\x7f\xe1\xbf\x78\x43\x92\xa4\x2a\x13\xc9\x80\xbe\xad\x09\x71\xd4\xec\xb4\x4e\x32\x12\xa5\x34\xb0\x73\x7a\x87\x26\xbc\xa9\x2c\xb3\xf2\xa2\xa8\x37\x5d\xed\xa1\xd7\x87\x9b\x42\x5a\xc6\x6f\x2f\xd7\x99\xf4\x65\xa8\x5d\x3c\x76\xc0\x9a\x85\x52\x75\xd5\x34\xb8\xdd\x35\x76\x8b\x84\xa6\xad\xab\xf3\xae\x28\x6d\x4a\xd6\x1e\xba\x3a\x93\x28\x8a\xfc\xa5\xe4\x86\x62\x01\x68\x0b\x5b\x18\x3d\x25\x4e\x22\x14\xc9\xdc\xde\x2f\x5d\x68\xfb\xdf\x72\xb7\x4d\x9e\x09\xa7\xd4\xb2\xff\x35\x4d\xdb\x86\x5f\xc9\x55\xac\xc2\x34\x40\x86\x89\x7a\x50\xe1\xa5\x09\xe7\x0c\xab\xc0\x9d\x19\xd8\xbc\x8a\x1a\x43\xb9\x18\xe3\x23\x55\xb4\xe7\x70\x1e\x9d\x21\xe7\xab\xf5\xeb\xb0\x74\x3a\x8b\xfb\xa7\x89\x20\x14\x4f\xe8\xa8\x39\x5b\x67\x7f\x6d\xde\x68\x8c\xdd\xfd\x4c\x57\x60\x90\xbb\x4e\x04\x61\x32\xf6\x00\xef\xed\x47\x75\x35\x48\xba\x25\x22\x91\x18\x79\xbb\x0e\xca\x0b\x6a\x15\x9a\x48\x06\x98\xc5\x5b\x28\xa1\xe1\x50\x2c\x43\x12\x20\x91\xb1\x41\x24\x6a\x78\xec\x5e\x01\x90\x26\x2a\xca\xb0\x1e\x5d\x34\xc8\x53\xef\x72\x49\xee\x20\x52\x35\x58\x72\xb9\xed\x6b\xad\x2f\x2b\xeb\x34\xd1\x69\xc4\x54\xaf\x5c\x55\xcf\x99\xef\xbf\x63\xce\x3f\x7b\x40\xfe\x67\x54\x84\x95\x9c\x36\xd0\x79\x4e\xa2\xcc\xd9\xfd\x27\x01\x16\xc7\x56\xa9\xe8\xfe\x17\x40\x3c\x37\xd8\x44\xb9\x0c\x5c\xc3\x0b\xad\x07\x90\xb3\xbf\xbb\x13\x5d\xf4\x15\xfb\x53\x13\x9b\x78\x5d\x3e\xdf\x3e\xaf\xd6\xab\xdb\xf5\xdd\xe3\x0a\xeb\xf9\xcb\xc5\xfa\xf6\xc9\x3f\x6e\x93\x5b\xf0\x72\xe7\xc2\x3b\x32\x7d\x7f\xc4\x30\x24\x94\x7b\x78\xfc\xe7\x70\x61\xa5\x11\xe5\xd8\xeb\xba\xae\xd4\xdb\xb3\x38\x42\xbd\x51\x45\xd3\x54\xa1\x7e\x94\x46\xcc\xaa\xc2\x1e\x5f\x45\x03\x74\x85\x55\xe9\x90\xcd\x49\x89\xb6\x32\x60\x8f\xdf\x97\xdb\xd1\x79\x89\x91\x98\xd9\x73\x4f\x75\x29\xf6\xfb\x2e\x1c\xb0\x69\x01\xdf\x74\xe0\x44\xea\x68\x4a\x23\xc0\x6a\xc5\x6b\xb5\xd7\x4f\x66\x6c\x76\x53\x9a\x18\xa4\x1d\x39\x0e\x4b\xe2\x57\xfe\x87\x18\x81\x78\x58\xbd\xfe\x10\xb5\xa7\x53\x19\x4f\xb4\x94\x49\xab\xa5\x8a\xd9\xa5\xce\xb7\x0b\xa7\x90\x36\x23\x72\x38\x5b\xb7\x25\xdc\x3b\xd3\x54\xb8\x7a\xf4\x8f\x62\xaf\x2f\xd0\x98\x6e\x58\x2c\xf2\x2c\xf7\xda\xe8\xb6\xf8\x6d\xe7\xd6\xb6\x38\xc0\xb0\xcb\x9a\xa6\xb1\x32\xc8\x64\xda\xad\x4b\x87\xf9\x9e\x56\x14\xd2\x18\x22\xc4\x6d\xb8\xee\x79\xff\xd5\x24\x32\x58\x66\x5e\x63\x50\xff\xb7\xe8\xce\xc6\x73\x39\x4d\x48\x9e\x24\xe1\x51\x59\xad\x97\xf1\x4f\x27\x31\xf5\x9d\x7e\x9e\x57\xee\x1a\xca\x6a\xd4\xef\x44\xd3\x24\x8d\x30\x3f\xb4\x39\x88\x3a\xe4\x18\x77\xbe\x0f\x7f\x72\xc6\xcc\xd6\x84\xba\xf8\x5e\xd4\xfa\x19\xea\xb7\x2d\xfc\x9c\xf6\xbd\xb8\xc1\x29\xe4\xcc\xc6\xb8\xae\xe2\x36\xbb\x26\xd3\x2c\xb2\xac\x19\xeb\xd5\xff\xf8\x4b\xca\xd2\xcc\x43\xe9\x97\xd5\xe1\x80\x35\x3b\x4b\x6d\x37\x02\x2b\xa4\x39\x17\x58\x15\x07\xa5\x1b\x61\xe9\xaf\xfe\xbb\x44\x5c\xca\x05\xe0\x43\xec\xd6\xde\xe2\xfe\xfe\xe9\xc7\xea\x7a\x28\xef\x44\x53\x95\x0b\xd4\x61\x57\x55\x80\x4a\x86\x43\x12\x88\xeb\x3d\x0a\x8d\x68\xff\xa5\xa7\xfa\x7b\x40\x35\x4d\x95\x01\x01\x41\x2f\xc7\x06\xd1\xf1\xfa\x82\x4f\x9e\xa6\x5a\x30\x6e\x75\xb7\x5c\x8c\x71\x53\x57\x07\xb4\xd1\x4f\x35\x92\x5e\x7f\x85\xf3\xe4\x7d\x6a\xa9\xa9\x98\xb6\x8f\x5f\x17\x8d\x3c\xd5\x4d\x3f\x43\x00\xa2\xd4\xa7\x12\x7c\xb7\x30\xa2\x03\x6e\xaa\x7a\xfb\x0a\x5b\xf0\xd4\xb5\x34\x35\x5c\x21\x43\xaa\x14\xea\xad\x32\xa6\x50\x60\x27\xf8\xe4\x52\x8d\xc9\x51\x22\xac\x39\xc9\x2e\x2c\x9f\x05\x69\x64\x51\x64\x61\xc9\x42\xeb\xc7\xea\x06\x60\x92\xe8\xed\x05\x45\xbc\x2b\x95\x45\x32\x87\xc0\x57\x1b\xe2\x9f\xa2\x2a\xbd\x92\x9b\x1f\xa7\xa4\x70\xc5\x8f\xc5\x62\x19\x3e\x85\x0c\x6d\xe3\x41\x0c\x36\x78\x77\x8c\x44\x96\x5f\xcc\xef\x37\xe8\xa0\x35\xe1\x68\x22\x52\x97\x16\x5b\x1d\xe4\x1e\x0e\x03\x41\x0a\x9a\x91\xdc\x48\xf7\x02\x2d\x82\x7a\x2f\xc6\x69\xc4\xdc\x0f\xe4\x11\xe6\x4d\xf7\x45\xf9\x36\xef\x61\x64\x84\x6b\xec\x57\x95\xad\x1a\xa4\x72\x32\x22\x23\xdc\xb5\xf7\xe5\x1f\xc3\x40\x2e\xa3\x19\xd8\xde\xf6\xaa\x04\xa7\xb1\x17\x18\x0e\x68\x46\x73\x83\x0e\xfb\x55\x75\x7a\x79\x6d\x2f\x72\x89\xa3\x57\x96\x31\x9a\x27\x3d\x19\xb5\x1e\xdb\xd6\x8c\x39\x52\x2b\x5c\xa5\x81\x04\x72\x13\x4c\x65\x16\x13\x9b\xba\x75\xab\x74\x58\x6f\xc8\xff\x95\xfc\x7b\xf2\xea\xe3\xdc\x9a\x6a\x4c\x9d\xce\xb8\x19\x59\x2c\x29\x1b\x6a\x27\x0c\xea\x29\x7f\x8b\x96\x8f\x66\xb1\x11\x08\x17\x17\x07\x28\xf5\x1a\x5a\x28\xe7\x54\x2e\xdc\xe0\x24\x05\x34\x48\x1e\x40\xe6\x34\x12\x26\x83\xf2\x84\xf5\x7d\x58\x4f\x25\x5c\xd7\x45\xf9\x36\xaa\x45\x65\x69\x24\x31\x6b\xb0\x2b\x9a\xab\xd3\xb9\x4f\xd4\x64\x29\x4d\x11\xfd\x70\x3c\x35\xaf\xa3\x26\x9e\x4b\xd0\xae\xff\x06\xd7\x98\xb4\x76\x60\x16\xdb\xc4\x59\x0c\x6f\x62\x1a\x3c\x65\xa9\x60\x56\xf8\xda\xba\x75\x08\x16\xf0\x17\x90\x73\x21\x12\xaf\x4a\x50\xbc\x17\x7b\x78\x71\x20\xd6\xd1\x0d\xf0\x9c\x45\x4e\x18\xf8\xa1\xd8\x43\xd3\x56\x9f\x93\x6f\xf9\xaf\x28\xc2\x89\x7f\x99\x63\xad\x7f\x37\x42\xc4\x0c\x3b\x19\x2d\x57\xc2\x8f\xe2\x82\x26\xc7\x8f\x4b\x0d\xe6\xd6\xfe\xef\xf9\xf9\x79\xf1\xdb\x98\xc1\x7f\x49\x10\xc4\xf8\x6d\x40\x9d\xea\xb0\x62\xa4\xb1\xca\x22\x7d\x22\xe2\x7e\x5c\x29\xcb\x90\x92\x22\x20\xfc\xc4\xbe\x19\x0a\x63\xd0\x4c\x33\x40\x32\x0c\x79\xda\xbf\x6d\x06\x22\xe6\x97\x11\x5e\x66\x62\x82\x59\xf6\xa5\xed\xbd\xbe\x2b\x9f\xeb\xea\xa5\x1b\x3b\xca\xab\x64\x46\x19\x04\x1e\xbd\x1c\xda\xce\xba\x8e\xeb\xcc\x99\x31\x80\xaf\xfb\xe9\xfe\xee\x66\x54\x3b\xcd\x69\x9e\xa6\x2e\xd7\xa9\x5e\xb7\xc5\x84\x4a\x93\xe6\x54\xcb\x08\xc9\xaf\x3e\x2e\xfa\xd6\xdd\x08\x96\x28\xa4\x2d\x78\x8e\x9f\xfd\x49\x59\xce\x98\x2d\x39\x81\xaf\x45\xf6\x66\x3e\x67\xb9\xe5\x3c\xb5\xa1\xd5\xd5\x5e\x4c\xf8\x0b\x68\x1e\x47\x0c\xa3\x54\x94\x47\xb0\x80\xb3\x5f\xd7\x16\xf2\x38\xa6\x60\xbc\x43\xe7\x2a\x59\xfe\x50\xaa\x32\xeb\x49\x3c\xd7\xd5\xcf\xf3\xc4\x38\xe7\x89\xcc\x30\x4e\xda\x57\x21\x9d\x96\xa7\x5a\x1a\x1b\xdb\xb5\x50\x97\x62\xff\x08\x1f\xa3\x3d\x73\xf2\xe3\x19\x21\x88\x8d\x75\x15\xb6\xa6\x39\x81\xbe\x3a\x6f\xb6\xde\x17\xcf\xb3\x18\xe2\x61\xa9\x7e\xd6\xda\x5c\x06\x2d\xb3\x9f\xfa\x53\x72\xdb\x82\x80\xc9\x30\x77\x4b\xf8\x62\xc7\x7e\x46\x9e\xa7\x20\x55\xdf\xd7\xb0\xe9\x9c\xdd\x49\x5d\x25\xcf\x95\x75\x5a\x91\x72\xe4\xbe\x68\xda\x19\x7f\x30\xe7\x42\x3b\x35\xe5\xf3\x0d\x4c\xb2\x82\x39\x07\x89\xb8\x51\x79\x3a\x7b\x09\xaa\xbb\x16\x0e\xcd\x30\x62\xce\xb9\x21\x08\x2b\xdb\x79\x9d\xb2\x79\x9f\x2e\x17\xb1\x45\x6a\x37\xd0\x7e\x3d\xcb\x4b\x2a\xc4\xf1\x75\x09\xe0\x60\x5c\x92\xda\x6a\x8d\x60\x34\x3e\xa1\x7e\x98\xfc\x84\x4c\x98\x93\x04\x6d\x97\xe2\x70\x14\xc5\x4b\xf9\x3b\x16\xe6\x71\x85\x7f\x92\x0c\x1b\x9f\x1c\x32\xee\x72\x67\x9b\xd7\xc2\xd6\x40\xf7\xd8\x08\xfa\x1f\xff\x56\x14\x4d\x90\xdc\xd0\xa1\x71\x6a\x40\x62\xf1\x91\xb1\xcc\x15\x15\xd8\x89\x6f\x8a\x9f\xbb\xa3\xa8\x87\xe4\x33\x03\x0f\x2f\x57\x32\xc3\xcd\x33\x50\xb1\xcc\x95\x8c\x72\x25\xad\xce\x04\xbe\xd9\xbf\xa7\x52\x42\x73\x1d\x5b\xe9\xeb\xff\x9c\xa0\x3e\x2f\xf6\x7b\xef\x47\xfb\xbb\xd0\xb9\xad\x01\xed\x4a\x11\xdc\xa3\x5c\x2b\x8d\x9c\x72\xaf\x62\xdf\x7a\x60\xaa\x3f\x06\x31\x43\x87\xd9\x66\xc9\x97\xb3\x7d\xd5\x34\x87\x3c\x47\x72\x18\x83\x92\x20\xd7\x48\x71\x39\xb9\x1d\xc3\x2d\xa1\x61\x6f\x94\xfa\xcd\x28\x37\x82\x63\x3d\xcd\x1f\x44\x0a\xba\x01\x23\x2e\xcd\x8d\xd6\xd0\x97\x59\x46\xa9\x7f\x6f\x77\x79\x44\x9c\x42\xf3\x62\xbb\xda\x6d\x9e\x3c\xb7\x01\xe5\x51\xe7\xd1\x86\x3c\x8d\x25\xbf\x73\x9a\xa0\xf3\x13\x9a\x13\x23\x72\x57\x90\x79\x28\x4a\xa8\x27\x82\xc2\x94\xd3\x28\xc7\xe9\xf0\x20\x2c\x6b\x96\xa7\xca\xa2\x9c\x26\x24\xd1\x9e\x6e\xff\xa1\x28\xdb\xc7\xd3\xa1\x09\x07\x25\x47\x1a\x43\x24\x64\x10\xa7\xda\x12\x82\xf6\x9d\x7b\x94\x53\x48\x11\xf1\xb9\x6b\xa0\xd4\x78\x9f\x8e\x2a\x68\xfe\x42\x63\x25\x11\xb2\xe1\xb8\xc0\xe7\xfa\x49\x29\x8f\x4d\x84\x49\x54\xdc\x91\xfb\x86\x3e\xca\x13\x66\xb0\x30\x26\x9a\x06\xda\xab\xf3\xb8\xa9\x6f\xfc\x43\x49\xcc\xd0\x87\xbe\xa9\xf6\x45\xf5\x58\x94\xff\x2b\x66\x69\x69\xe7\x8d\x3d\x4f\xf3\x84\x89\xa1\x00\xb8\xd3\x94\x99\x82\x39\xfa\x55\xc2\xb3\x88\xd0\xc8\xd3\x9e\xb6\x2d\x16\xc5\x8a\x03\x54\x27\xab\xb8\x37\x4e\x33\xf0\x2c\xe2\x46\x06\x7a\xa2\x89\x2e\xfc\xe4\x62\x32\x66\x7c\x62\xba\x33\xb0\xa8\x98\x30\x3f\x32\x67\x16\xa3\x7a\x5f\x09\x0d\xda\xc9\xd1\xcf\x0f\xe5\x5a\xd8\xc2\xe7\x5e\xbc\x01\x95\x17\x22\xaf\x1e\xf7\xca\x65\x62\xc1\xb1\x87\xa2\x6c\xd7\x70\x3c\xb5\x63\x39\xd2\x49\xd6\xd6\x7d\x49\xe5\x0a\x7d\x05\xe7\x8d\xe3\x13\x78\x2a\xad\x56\x5f\x63\xb1\x7c\xb3\x2e\x14\x57\xc2\xa0\x0b\xf8\x7f\x8b\xfd\xbe\xf8\x8f\xf8\xbc\x5f\x9c\x72\x25\x7b\x38\xbe\x45\xed\x5e\x89\x06\x7d\xc2\x66\x84\xdc\xe5\x3a\x8e\xb1\xcb\x65\x77\x59\x45\x1f\xff\xb8\x4e\x6c\x72\x50\x68\x6d\x45\x63\x67\x5d\x82\x7c\x72\x1d\x9a\x13\x5f\xc3\x7b\x14\xb5\xaa\xbe\x54\x07\x08\xce\xda\x64\xa8\xcc\x6c\x7d\xc9\x33\xbb\x7a\xeb\x35\x7f\x87\x5a\x67\x88\xab\x09\xb3\x10\x93\xbb\x93\xed\x89\x03\xcd\xb0\x95\x09\x79\xd3\x76\xf2\x74\xde\x55\xb5\x4f\x25\x93\x0b\xae\x8f\x99\x4c\x22\x07\x46\x90\x86\xd5\x76\xeb\xdc\x2d\x9f\xd8\x90\xc0\x9f\x72\x48\xad\x58\xba\x6d\xf7\xec\x25\xc0\x29\x07\xa9\xb1\x28\x79\xb4\x3d\x9c\x4f\xc6\x40\x77\xde\x51\xa2\x97\x9b\x24\x26\xae\x0d\xf7\x79\x12\x02\x8c\xdf\xbe\x88\xb8\xb4\x9d\x3d\xd6\x6c\x5a\x3e\x7b\xf1\x19\xee\x48\x90\x8c\x27\x7c\x94\x65\xf5\x0d\x7a\xdf\xc5\x90\x10\x61\xf2\x2d\xb0\xfd\xfa\x37\xa7\x2b\x1f\x6a\x0a\x6a\x00\x77\xc2\xcd\x76\x7d\xe7\x3f\x63\x54\x61\xb6\x1c\xdb\xb9\x76\x62\x88\x0e\x10\x2c\xe7\xf8\xc4\x8e\x4e\x31\xee\xd7\x3e\xbe\x60\x92\x60\x24\xbb\x59\x0c\x3d\x63\x91\xa4\x1c\x5b\x87\xb1\x23\x62\x9c\x42\x15\x69\x4a\xb9\x0a\x5d\x30\x36\x43\x75\x2b\x0e\x97\xe2\x7b\x7e\xbc\x32\x98\x8d\xf0\x0e\xa5\x55\xc1\xfb\xff\xc9\xeb\x7c\xd6\x63\xec\x7e\x28\x23\x39\x28\x97\xc6\xe9\xec\xcb\x50\x20\x9d\x8a\x2c\x61\xb6\xf5\x11\xf3\xeb\x57\x03\xe5\x5f\xef\xfc\x58\x30\x63\x6f\x38\x45\x96\xc6\x3a\xa0\x79\x31\x4f\x75\x57\x5e\x3d\x5e\x85\x33\x72\xc0\x8e\x9f\xb6\xf8\xe9\xf0\x27\xde\x5a\xfa\x01\x9a\x61\x0a\xec\xe1\xee\x71\x77\xf3\xed\xf1\xfa\xee\xf1\x76\x37\x94\xa3\xa1\x22\x03\xe1\x7d\xb1\x0d\xec\xcd\xa2\x5b\x77\x80\x3e\xdc\xab\x5d\xe6\xc3\xd5\x20\xf2\x94\xe7\x48\x16\xff\xb4\x5e\x7c\xf5\xa7\xe0\xd2\x2a\x1e\xbc\x40\x6b\x11\x0c\x17\x08\x49\x21\x68\x2c\x53\x9f\x15\x2c\xdb\xba\xda\xdf\x95\xa6\x7a\x10\x3f\x9f\xa1\x46\x03\x78\x77\x90\x76\xbb\xbb\xef\xbb\x90\x84\x4c\x25\x1a\xbc\x26\x30\xd4\xe4\xfe\x48\x96\x0f\x65\xc4\x1f\xc5\x84\x97\x94\x0a\x15\x19\x2b\xa1\xe8\x3a\x61\x67\x73\x32\x42\x11\x4b\x50\xd8\x85\x3a\xae\x5b\x64\xd6\xcf\x15\x8a\x6a\x7c\x90\xaf\x80\x79\xf1\xc9\x41\xa9\x22\xed\xa8\x03\x77\x07\x68\xc5\x7e\x77\x28\xca\xf1\xaa\x50\x4a\x60\x53\xb6\x47\xb2\x7e\x96\x7a\x15\x0a\x22\x04\x13\xec\x4a\xf8\x70\x80\x10\xbb\xf3\x8c\x46\x41\x62\x90\x62\x06\x6c\x15\xdf\xd2\x5d\x38\x15\xa8\x5e\xb1\x9b\x0a\xc8\xc1\x4b\xdc\xdf\x42\x09\xcd\x88\x4b\x82\x0a\x90\x3c\x32\x21\x18\x7c\xae\x3e\xa0\x3e\x35\xd3\x8c\x8d\x00\x88\x22\xaf\x60\x28\xca\x45\xdb\x0a\xf5\xe6\xb6\x95\xbb\xe0\xd6\x09\x23\x72\x65\x93\x1a\xab\xf5\x32\xa3\x24\x7c\x0e\x00\x7d\xf6\xe9\xaa\x12\xf5\x05\x87\xca\xaf\xf3\x3d\x32\x8a\xac\x30\xfb\xf3\x7a\xf5\x70\xf7\xed\x61\xb7\xfd\xf3\x79\xb5\x5b\x0e\x66\xb1\x8c\x28\xc5\x5e\x4e\x57\x99\xe8\x59\xde\x9a\x71\x40\x26\x23\x9d\x78\x00\xc4\x75\xd1\x58\xde\x79\x9f\x17\x90\x24\x92\x08\x8a\x5c\x14\xf5\x75\x5d\x1d\x3f\xeb\x8b\xf6\xa3\x93\x94\x43\xc0\xf6\xd9\xe4\x08\xe8\xc5\xcf\xe2\x33\x3b\x24\x99\xb1\x7a\xda\xce\x82\x77\x31\x2d\x62\x9b\xc6\x5d\xf2\x54\xc6\x34\x52\x36\x1b\x8c\x9b\xc6\x06\x91\x07\xd3\x31\x22\xf6\x3b\xfc\xff\x11\xea\xed\x58\xb5\x17\x71\xa1\x4c\xa2\x0c\x4b\x66\xd7\x4f\x3f\x76\x37\xc1\x78\xcb\x44\x51\x04\x3c\x2e\x9a\x42\xbb\xbc\xf1\x17\xf1\x0e\x57\x00\xa5\x03\x1d\x5f\x66\xc3\xfd\x57\x35\x07\x0b\xe9\xb2\xdc\x6c\x3d\x06\x47\x66\x4c\x81\xf0\x1c\x3a\x9d\x45\x9e\x06\x8e\xe3\x33\x65\xb1\xc9\x82\xf7\x5c\xdd\x74\x8b\xa5\xf1\x3d\xd4\x7e\x48\x22\x71\xc8\xee\x74\x6c\xa0\x9e\xa7\x58\xef\xf1\xdd\x83\x53\x67\x96\x35\xec\x58\xed\xf7\x0f\xe2\x38\xf6\x2e\x65\x96\x27\x94\x0f\x4c\x91\x50\xed\xe3\x44\x8c\x94\xca\x4c\xf3\xc4\x6a\x21\x80\x3a\xb5\xe0\xe5\xfd\xd4\x6f\x5a\x96\x64\x1e\x31\x24\x1a\xc6\x34\xc3\xfc\x64\xce\x39\x41\x18\x25\x92\x93\x5c\xec\xf9\xa7\x11\x9e\xdd\x7f\x45\xe6\x98\x22\xd6\x95\xef\xa9\x19\x1f\xe7\x8c\xa1\x0f\xb2\x72\xdb\xdb\x60\x1f\x95\x3c\xa5\x98\x4c\x71\xc4\x3f\x85\x90\xc5\xbe\x68\xcf\x43\x9f\xd6\x8f\xd4\x02\x03\x88\x27\xcc\xfd\xcf\xd0\xe3\xf4\x3f\x28\x62\xbb\xc5\xdf\x6d\x76\x9b\xbb\xdb\xc7\xc5\xf6\xdb\x7a\xb5\x1e\x1b\x0d\x29\x92\x04\xa1\xfb\xe5\xc9\xca\x46\xd9\x78\xb3\x8f\x5f\xa5\xc8\xa3\xcc\xc9\x5d\xc8\x42\x87\x4f\x9d\x1c\xb8\xa5\xf5\x5a\x56\x96\x86\x73\x0a\x84\x92\x32\xb5\x1c\x15\x6d\x71\x40\xb9\x6d\xdf\x51\x21\xa5\x16\x94\x4f\xe4\x4d\xa7\x8c\x9a\x43\x4b\x2a\xa5\x49\x3d\xb5\x12\xc6\x4c\x77\x17\xdb\xb2\x1b\xa8\x99\xd6\x1c\x75\x46\x7c\xa6\x4d\x82\xa2\x88\xa2\xc4\x0d\x6a\x59\x0b\xd3\x99\xeb\xcf\x44\x97\xe7\xa7\x83\xc9\x32\xee\x7e\xfe\x6b\x51\xbe\xe8\xea\xd0\xed\x8c\xf5\xc1\x45\x92\xa3\x4b\x35\x9a\x7a\x39\x9a\x17\x71\x80\x6e\xbb\xf9\xaf\xbd\x98\xd1\xaf\xab\x88\xa9\xc8\x66\x95\xdb\x6a\x37\xcd\x8f\xf9\x31\x10\x31\x07\x5a\xf9\x15\x0a\x49\x91\x1c\x70\x97\x10\x47\xef\x3a\x2a\x92\xdb\x4d\x18\x90\xc8\xb5\x54\x67\x5f\x0f\x76\xc7\x19\x03\x2b\x03\x84\xe9\x65\xdc\xb8\x7e\x40\x31\x6f\x6f\x15\xcb\x52\x4a\xfa\x5c\x5a\x17\x46\xec\x47\x39\xb7\xc9\x70\x41\xd0\x17\xb3\xc6\x16\xa1\x6a\x17\x9c\x9d\xfd\x83\x88\x09\xd1\x36\xac\xae\x1a\xb0\x64\xd5\x93\x01\x5c\x66\xee\x3d\x75\xa1\x2b\x32\xb8\xae\xa6\x75\x3c\x95\x10\x65\xf5\x22\x8b\xf6\xf5\x35\xd0\xf4\x50\x95\x28\x96\xe6\x23\x8a\x6e\x9c\x32\x8f\x95\x25\x0f\xc6\x34\x4c\x18\x6a\xf1\xa3\xa8\xc5\x56\x1c\x60\x80\xe1\x54\x19\x73\xc1\x7f\xdf\xb5\x3c\xaf\x14\xd6\x0d\x25\x38\x5b\xb7\x50\x1f\x9a\x27\xd3\xb7\x1d\xa8\x3c\xcb\x8c\x13\xc3\xb8\x46\x06\xb7\x0b\xf2\xd5\x6e\x8c\xc4\x36\xd3\x87\xab\x4f\xd9\x75\xe6\x5f\x12\x67\x29\x82\xdc\x9c\x18\x11\x26\x1a\x6d\xc3\xa8\x1f\x10\x03\x36\xd5\x2c\xe3\x9b\xa1\x9d\x52\x82\x58\xd4\x6f\x17\xca\x7d\x2b\x55\x55\x1a\xa8\x01\x95\xd0\xfc\x00\x4a\x88\xdd\xe2\xeb\xa2\xd2\xa3\x62\xb2\x12\x9a\x62\x66\xeb\x4a\x94\x6f\xbf\xcc\x17\x28\xa1\x53\xa4\xec\xc2\xc0\x65\xe9\x91\xb5\x93\xbb\x17\x00\x08\xd7\x14\xd5\xe1\xa4\xfa\x74\x50\x17\x7f\x23\x38\x42\xec\xf7\x8b\xa6\x81\xb6\x99\x7a\x82\x4a\x2a\x10\xce\xcf\xdd\x6c\x9e\x27\x07\x55\x16\xd9\x3b\xe8\x82\xd1\x87\xea\x1d\x86\x2e\xad\x52\x99\x6d\xda\x12\x4a\x9d\x9c\xa6\xf7\x5d\x79\xf4\x0c\xa6\x54\x29\xd0\xdc\x23\x4a\xca\xf2\x24\xf6\x53\x86\x2f\x37\x4e\xf3\x14\xcd\xaa\xcf\x59\xf5\x85\xaa\xee\x90\xd4\x21\xef\xf9\x3f\xa7\xaa\x9e\xb6\x15\x2a\x6d\x92\xdc\xa1\xe1\xbf\xfe\xb9\x3c\x8a\xa6\x99\x02\x09\x14\xe4\x1c\xe1\x0f\xfb\xea\xa5\xfa\xb6\xf6\xd5\x76\x65\xb2\x0c\x3b\xee\xae\xd0\x43\x84\xc3\xf1\x37\x40\x69\x65\x20\xc1\x46\xf1\x63\xd5\x34\x83\xa7\xac\x23\x0d\x9a\x0c\x1a\x3d\x71\x0e\x8d\x04\xd2\xa9\x8e\x20\x42\x1e\x01\x3d\xff\xb2\xff\x71\xea\x25\xed\xa9\x26\x11\x49\x3d\x56\xcc\x42\x46\x7f\x5b\x6f\x9c\x9d\xdc\x9a\x44\x12\x13\x97\xdb\xdb\xd5\x0c\x85\x9c\x1f\x94\x30\xac\x7f\xde\xd6\xa2\xd4\xbb\x4d\xb5\x17\xf5\xee\xc1\x72\xd5\xfb\xab\xa7\x29\x58\x15\xdd\x7d\x75\xd2\xc3\x5b\x67\x32\xc7\x1e\x0a\xcb\xcd\x7a\xc1\xad\xfb\x69\xf5\x5c\xc7\x34\xca\x3c\xae\x77\xc2\xea\x33\xae\x45\xe9\x38\xe6\xb8\x54\x96\x28\x78\x29\x02\x49\x1e\xd5\xb1\xd4\x99\xeb\xd0\x5a\xd6\x55\x63\xfb\x0d\x2e\xdc\x04\x9d\x88\xc4\xfa\x2f\x1f\x25\xd4\xdf\x6d\x63\x52\x7f\x92\x8c\x32\x62\xc6\xa0\xf5\x8f\xc1\x36\xe5\x47\x71\x82\x09\xb6\xa3\x38\x5b\x5b\x3b\x03\xb1\x9c\x0f\xb5\xdd\x09\xf2\x44\xa1\x57\x53\x57\x55\xdb\x3c\x0c\xb5\x05\x26\xaf\x2c\x57\x12\x5d\x27\x9b\xbe\x19\x10\x59\x53\x9d\x1b\x1d\x39\x2c\x75\xbb\x87\x61\xdb\xf5\xfc\x84\xd5\x9c\x1a\xea\x1e\x72\x68\x06\x58\x95\x6d\x7d\x9e\xdc\x1d\x67\xb6\x36\x0f\xed\xeb\xa0\xd0\xaf\x79\x66\x4d\xcf\x07\xc8\x63\xef\xe5\x6a\x9e\x69\x6e\xf9\xa1\xf6\x7a\xec\x00\x6b\x2e\x73\x95\x86\x96\x9c\x63\x0b\x3b\x1a\x8f\x3c\x02\x8d\xf9\xbb\xce\x68\x74\x0f\x79\x5b\xb4\xa2\x2c\x4e\x97\xb7\x31\x7e\x24\x82\x5a\x70\xf1\x6b\xd5\x4c\x27\x87\xa4\x1c\x13\xc3\x36\xb9\x8c\xd2\x9b\xfd\xc6\xa1\x55\x64\x85\xc4\x85\x9e\x0a\x1a\x4e\xd8\x56\xc6\xbf\xa7\x34\x67\xc1\x20\xd9\xec\xd7\xc2\xb2\xc4\x8d\x1f\x9b\xce\x2d\xa0\x45\x9c\xda\xd7\xaa\x2e\xfe\x02\xed\x52\x5d\x4b\x51\x6b\xab\x32\x31\xa5\x76\x9d\xfc\x92\xe6\x26\x1b\xe6\xbc\x46\x99\x2e\x3f\xc6\x10\x84\xe4\xb8\xf6\xcc\x9b\xaa\x9e\xf2\xf5\x50\x0d\xa9\xf2\x59\x4b\x84\xc9\x61\x87\xdc\xd5\xf9\x2b\x9c\x67\x57\x3c\xa4\x76\x4b\xd3\x17\xa8\xfd\x79\xaf\x4b\x03\xe7\xd8\xb9\xd4\xb4\x15\x2a\x85\x55\xca\x3f\x62\x43\x13\xc4\xbd\x7e\x40\xb1\xad\xbe\x6d\xae\x27\x8f\xc8\x70\x4a\xa9\xa3\x36\x7d\x87\x7a\xd3\x56\xea\xad\xbb\x2a\xab\x79\x4b\xc3\x28\xa5\x42\xda\xa4\x7b\xd0\x5d\xc4\xff\x58\x5d\xf5\x0a\x62\x14\x22\xc2\xd0\x3d\x58\x61\x80\xd3\xb9\xab\xbf\xe0\x33\x9c\x73\xf7\x20\x22\xd2\x13\x43\xdc\x57\xea\x2d\x44\x32\xa3\x47\x09\x51\xca\xb2\x81\x0e\x7a\x28\x95\xb6\xa3\x79\x0c\x24\xca\x33\xee\x3b\x32\x14\x14\xc7\x76\x5d\x4d\xc4\x12\x29\x10\x4d\xd1\x59\xed\x76\x5e\xfc\xf2\xdc\xdb\x00\x2a\xac\xd6\xfb\xee\x58\x57\x3f\xcf\xbe\xb3\xc5\xa2\xf4\x3e\x4d\xed\x0d\x1d\x7d\x60\x69\x8c\xc8\x9b\x0a\x3b\x8d\x1b\x47\x81\x1a\xbc\x56\x88\xb3\x18\x05\x17\x9f\xd7\x4f\x0f\x4f\xdb\xa7\xf5\x66\xf7\xfc\xf4\xe4\xf7\x41\xc8\x98\xc6\x72\x6e\xdf\x18\x8e\x5b\x54\x55\x8f\xc4\x77\xc6\x33\x02\xb2\x5c\x60\xc4\x8f\xd0\xec\x93\x6b\x48\x19\x55\xca\x21\x8f\x62\x1e\x7b\x63\xe0\x7b\x60\x2e\x5d\x37\xc8\x89\xa3\x64\x2c\x0b\xc7\x15\x3b\x79\x25\x39\x8b\xb8\x97\x8b\xd9\x1d\x86\x64\x3d\x2b\x5f\x21\x05\x1e\x69\xc7\xc2\xe0\xa6\x50\x20\x95\xa4\xc0\x89\xcc\x1d\xda\xa4\xc7\x53\x02\xa7\x2c\x95\x8e\xe9\x75\xd5\xbe\xda\xa6\xd2\x91\xe9\x9e\xdc\x32\xe7\xb6\x8c\xe4\x29\xad\x2e\xac\x56\x9f\x06\x05\x91\x19\x74\xbe\x97\x35\xe8\xa2\xbd\x5e\x3c\x0d\x8b\x37\x6e\x8c\x4c\x63\x54\x4f\x5c\x7d\x7f\xb8\xf6\x09\x52\x50\x32\x0e\x0f\x63\xa4\xc5\xee\x07\x74\x9b\xae\xf3\x77\x7e\x54\x75\x33\xca\x32\x82\x16\x11\x66\x01\x10\xda\x72\x55\x55\xfb\x3f\xac\xbe\x90\x3b\x0c\x20\x10\x30\xf7\x2c\xda\xba\x50\x6f\x5b\x24\x6b\x0a\x9b\x39\x98\xc8\x4a\xf0\x6b\x28\xcf\x96\x67\x7d\x7e\x8f\x02\xc3\x64\xa4\xfd\xc6\xdb\x2d\x13\x4c\xbf\xa2\x87\x61\x21\xf6\xc3\x0e\x5d\x30\x19\x43\xca\x00\xf5\x2a\xf6\x7b\x28\x5f\xfa\x03\x00\xd8\xd4\xd2\x59\xb6\x2e\xa0\x70\xe1\x81\x3d\x6a\x22\x26\x2d\xe3\xb8\x8b\x8b\x7f\x14\xed\xeb\x80\x7b\xd9\x8f\x92\xc0\xc3\x3a\x34\x17\x38\x45\x43\x0c\x41\xcb\x75\xb7\x7c\x1a\x6f\x1d\x86\x98\xcc\x2b\x1b\x7e\xaf\x5a\xdf\x18\x12\xe0\x6c\x86\x66\xca\x33\x4a\x2d\x61\x0f\xb2\x2e\xda\xf3\xa8\xf4\x3b\x9e\x1e\x86\xe6\x56\x88\x7e\x46\x43\xfe\xc2\xf0\x1b\xaa\x13\x44\x78\x2c\xef\x9f\xbb\xb7\xf0\x38\x52\x2c\xa2\x86\x51\xcd\xdd\xc6\xbd\x53\x3d\x90\xd7\xb0\xd8\x2a\x5e\xb6\xc5\x01\x7e\x14\xa5\xf6\xdc\x7c\xd4\x30\xc9\xad\xcc\xad\x68\xbb\xa9\xbf\x2a\x35\xf4\xdf\x02\x11\x3b\xf8\x91\xaf\x51\xcd\x08\x5d\x50\x13\x47\x96\x9a\xf0\x05\xda\x9b\x53\xd9\xad\xe9\xc7\xbe\x50\x6f\x62\x91\xa0\xf7\xf1\x31\x02\xe3\x99\x34\xb1\xa2\x2a\x0d\xb4\x0f\x95\x7a\xf3\x8c\x73\xb8\x80\xe2\xb1\x9d\x32\xa9\x49\x91\x5a\xe7\x60\xf9\x8d\x26\x06\xc3\x64\xd4\x8a\x5e\x79\x3d\xcf\xf0\xb9\x4a\xb4\x74\xd2\xf0\xd8\xba\x3e\x99\x03\x99\x61\xd8\x76\xdf\xd9\x07\x2f\x25\xf5\x58\xa8\x37\x8b\x6c\xe8\x2b\xfd\x26\x8f\x14\xc6\x33\x42\xeb\xeb\xe2\xbd\xe8\xec\xd1\xff\x39\xd5\x45\xa3\x0b\x9b\x00\xe9\x9d\xba\xe1\xb2\x31\x39\x8d\xb0\xeb\xf3\x3f\xa7\x42\xbd\x6d\xaa\xba\xbd\x2a\x42\x12\xd9\xe4\x5a\x63\x01\xea\xe9\xa3\x9c\x06\x1e\x46\x10\x83\x1d\xcc\x68\xd8\x7b\x06\xc1\xf1\x43\x11\xa9\xe5\xda\xb3\xf9\xa3\x5b\xd1\xcc\xb4\x16\x1a\xc1\x2d\x73\x5f\x10\x52\x1d\x88\x9d\xdc\x7c\x5b\x6f\xbf\xac\xd6\xbb\xed\x6a\xf9\x65\xa6\x2f\xcc\x08\x29\x30\xaf\xf0\xfd\x6e\x84\xb3\x37\xc2\x50\xa4\x05\xf3\x76\xff\xea\x34\x30\xbd\x43\x91\x91\xec\xdf\x63\x68\xd1\xbf\xe8\xbf\xc3\x29\xac\xfc\x5e\x13\x1a\x6e\x67\x77\x0b\x23\x19\x55\x34\x24\xf5\xa3\x27\xf9\xbf\x21\xb3\xe1\x0b\xbb\x46\xe6\x99\x63\x91\x52\x55\xad\x51\xbd\x71\xa8\xad\x40\x8d\x94\x0a\xbb\x73\x17\xd7\xdf\xef\x36\xdd\x26\xe6\x9e\xc1\xf3\x6a\xbd\x1c\xdc\xae\xd4\x91\x25\x06\xf9\xa4\x9a\xe7\x86\x99\x44\xc7\x8e\xf9\xff\xc7\x6a\xfb\x45\x7a\x19\xf3\x8b\xd0\xc5\x8f\xcf\x8d\x76\x7a\x54\x16\xb7\xb5\xe9\xb3\x25\xc6\x28\x61\x29\x93\x9c\xa2\x71\xe7\x38\xae\x7e\xaa\x81\xb5\x31\x3a\x41\xeb\x10\xa4\x72\x97\x58\x53\x9b\x35\xb0\x2c\x8a\xe2\x0c\x17\x95\xd3\xc4\x46\x7f\x68\x55\xea\x5e\xf7\x8b\x45\x51\x6a\x71\x33\x68\x6a\x6f\x1c\x54\xd4\xd5\x29\x72\x3f\x26\x8b\x91\x7f\xe3\x78\xf2\x4c\xe4\x3d\xa5\x39\x8b\x22\x61\x9b\xf0\x2a\xd7\x78\xb0\x43\xdc\xce\x1f\xc3\xde\x20\x77\xf7\xdd\x58\x9e\x5a\xc9\x16\x44\x36\x16\x8e\xc0\xf6\x8f\xf1\x65\x93\x8c\x60\xb6\x47\x68\xfd\xed\x33\x7a\x39\x16\x11\x95\x27\x01\x7b\xe7\xf3\xf7\xa1\x2d\xfd\x7e\xd0\xb0\xfc\x0b\xdd\x32\x16\xd1\x8c\xa2\x38\x62\x53\xbc\x94\x0b\xcc\xd5\xfd\x31\xfe\x1d\x2a\x4c\x6c\x25\xd0\x5d\x35\x76\x6c\x6f\x58\x44\x65\x84\x51\xed\xa9\xbc\x41\xe8\xd0\xe4\xfb\x4c\x66\xd8\xf4\xbe\xac\x4e\xc7\x19\x8a\x9b\xc9\x60\x60\x36\x31\xd8\xed\xbc\x0f\x85\x2e\x1e\xab\x16\xec\x36\xd8\x6f\xd0\x2c\x4a\x22\xc2\x13\x2f\x0a\x3e\x92\x20\x9e\x9c\x2f\x61\x9c\xbb\x26\x98\x6d\x75\xd9\xc9\x7d\xba\x54\xd2\x60\x51\x92\x64\xa8\xc3\x77\xbb\x19\x13\x36\xf8\xc3\x69\x86\xcc\x22\xd7\xa2\x1e\x68\x97\xce\xde\x4d\x92\xe5\xbe\x16\xef\xea\xce\x79\x67\x10\xfc\xfa\x8f\x47\x02\x44\xfe\x65\xa5\xfe\xcd\x24\x9c\x62\x14\xb8\x6b\xeb\xe2\xf0\x09\x3e\xb8\x1b\xa5\xb8\xd5\x89\xfb\x19\x5e\xfe\xb2\x3a\x1c\x44\xa9\xfd\x0b\x4a\x44\x9c\x68\xc7\x89\x04\x8d\x6f\xe4\x0c\xef\x2f\xa5\xd2\x87\xb7\x77\xa5\x2e\x14\x34\x28\xe7\xe9\x61\x62\xe1\xac\x68\xd8\x2e\x56\xf6\x6c\xcc\xcc\xa2\x34\xb5\x8e\xbd\xb7\x8a\xdf\xa1\x69\x2f\x58\x9c\x58\x94\x72\x2b\xed\x3d\x6a\x09\x3d\x5d\x42\xe4\xa6\x5b\x3f\x8b\x32\x4e\x11\xbc\x65\x89\x65\x9b\x07\x71\x7c\xae\xc6\x7b\x42\x37\x26\x45\xee\x19\xc4\xb6\x5c\x08\xf5\xcc\x5f\x78\xa6\x74\x82\xf5\x5a\x19\xcf\x09\x72\xb0\x28\xcf\x0c\xc6\x19\xe8\x22\x3f\x1d\xa1\x7c\x3e\xf6\x7d\x0a\x2c\xca\x73\x89\xe8\x3c\x1f\x8b\x76\xcf\xd2\x31\x63\x2e\x4a\xed\xba\x3c\xa6\x90\xa9\x59\xe0\xd0\xe0\x84\xe8\x03\x43\x23\x8a\x7a\xd8\x94\xc9\xa2\x9c\x5b\x2d\x14\x0b\x88\x20\xe1\x63\x25\x81\x0e\x1e\xfe\x43\x55\xc2\xf9\xea\x6c\xdd\xed\xf9\xc7\xc9\x69\xa4\x86\xf4\x61\x68\x7b\x6d\x7d\x19\xc2\x44\xe2\x79\x6e\x85\xca\xe1\x20\x91\x55\xde\x1f\x10\x84\xa0\xea\xe3\xd8\x69\x1b\xe7\xa9\xc3\x50\x46\x03\x87\x84\xe7\x08\xc3\x6d\x0a\x99\xa1\x06\x21\x1d\x8b\x44\x42\x10\x49\x23\xa1\x7d\x2a\x97\xd5\xfe\x74\x28\x9f\xea\xeb\xea\x2f\x28\xff\xe8\x6b\x80\x21\x5c\x60\x9d\x75\xc5\x5c\xf2\x1a\x5b\x27\x2f\xf5\x7f\x87\x98\x4b\xf7\x15\x99\xb0\x3c\xed\xf1\xb5\xd3\xba\xf4\xf8\x21\x49\x69\x01\x8c\x16\xf2\x5e\xd5\x6f\x45\xf9\x72\x57\x9a\x5a\xcc\x6e\x8e\x2c\x92\x60\x8c\x55\x75\x7a\xad\xf6\xfa\xb6\xdb\xe9\xe6\x27\x9d\x34\x8c\x3a\x34\xdb\x56\x34\x6f\x36\x77\xf6\x2c\x0a\x3d\x99\xd0\x4a\x68\x74\xd1\x50\x50\xb0\x3a\x95\xfa\xfa\x34\x94\xa6\x66\x11\xd0\x28\x1a\xf0\xb7\x56\xe5\xb7\x7a\xac\x74\x9b\xff\x8b\xd0\xfc\xdf\x61\x74\x8a\x8e\x55\xd3\xcb\x50\x42\xfd\xad\x2c\x82\x69\x00\x6e\x59\x27\xf5\xa0\x2f\x67\x18\x5e\xb0\xc8\xf0\x38\x71\xd1\xdc\x23\x7c\xcc\xb5\xfd\xb1\xc8\x08\x8e\x60\x2c\x73\xda\x9b\x62\xbf\xbf\x86\x7d\xf1\x0e\x35\xd6\x3e\xc6\xb7\xd7\x39\x1d\xda\x69\x18\x6d\x4e\xd2\xee\x32\xf3\x8f\xd6\xa8\x1c\x29\x07\x31\xb8\x5e\x68\x3d\xa9\x93\x33\x12\x45\xb6\xb3\xe3\xcf\xa7\xfb\xa7\xe5\x62\xf3\xe5\x0f\xff\x39\x17\x18\x2d\xe9\x5a\x14\x7d\x63\x0d\x23\x91\x54\x8c\xf6\xe4\xd7\x83\xf2\xa1\x1b\x40\x88\x46\x72\xa0\x9d\x4b\x7c\x80\x9e\xf8\x6a\xa3\x9b\x26\x24\x49\xd0\xaa\xee\xe4\xb1\x55\xff\x15\x4d\x01\x23\xc4\x49\xf3\xa2\xb6\xba\x9a\xc9\x76\x30\x42\xb8\xc6\x4c\xea\xa1\x28\x2d\x7b\x64\x55\x8f\x71\xc2\x8c\x10\x19\x23\x83\x32\xbc\x43\x7d\xbe\x2a\x74\xbf\x5e\x09\xcd\x63\x0c\xda\x4f\x65\xf1\x9f\x13\x0c\x54\x55\xc2\x97\x99\xa1\xd8\xed\xda\x7a\xad\xb5\x5e\x7e\xdf\x8d\x88\x23\x81\x48\x14\xd7\x3a\x73\xb4\x62\x8c\x8b\x52\x5f\x7f\x06\xb5\xef\x5f\x4e\x9c\x0a\x9c\x11\xb8\xc9\xec\xb6\xeb\xc5\x72\xc7\x53\xdf\x84\xce\x48\x0a\x56\x2d\xdf\x52\x70\xdf\xd6\xa2\x6c\x61\x5c\xe6\x63\x24\x67\x79\x3a\xa2\xdf\x74\x08\xf8\x02\x6a\x6c\x76\xbf\x3a\xd5\xf3\x20\x49\x46\x78\x42\x72\xa7\x71\x5f\x3e\x56\x1f\x61\x63\x08\x87\x55\x6e\x67\x42\x17\x08\x0f\xf8\x66\x86\x3c\x33\x53\xd0\x05\x23\x5c\x58\x10\x09\x36\xe3\x58\xb3\xe6\x3d\xa5\x2a\x00\x0f\x07\xf5\x09\x46\x44\xee\x60\x4e\x5d\x68\x5c\xb6\x17\x24\x02\x7e\x98\x89\xf1\x72\x6d\x52\x74\x44\x59\x3c\x01\x11\x31\x22\x19\xf3\x80\x5b\x84\xc5\xda\xfe\x31\x53\x4d\x1e\x9e\x22\x09\x82\x3a\xbd\xdb\x88\x52\x11\x56\x3f\x46\x5f\xe2\x78\x19\x51\x06\x74\xda\xa7\x53\x1e\xaa\xb2\x7d\xf5\x58\x9b\xc9\xd5\xea\x4c\x62\x7c\xfb\x50\x55\xe5\x52\xb4\x6b\x68\xd4\x29\xcc\x19\x30\x2a\xeb\x95\xc3\xbf\x40\x5d\x0d\xf7\xd8\xf0\x7c\xc6\x8f\xc9\x44\x06\x57\xf2\x5a\x1c\xa0\xec\x13\x2d\x8c\x18\x6d\x8c\x63\xae\xfa\x22\x0e\x87\xa9\xdd\x21\x06\x00\x6d\x84\x9d\x9b\xe5\x0b\xbc\x07\x86\x00\x46\x8c\x21\xac\xd7\x42\x1b\xcb\x9d\xcf\xe0\x05\x18\x8d\x84\xc2\xcd\xc5\xb3\xd8\xb9\xfc\x1e\xe8\x18\xeb\x10\x45\x39\xaf\xf9\xc6\x28\x31\xe0\x81\x27\x43\x3a\x25\x46\x69\x64\x19\x64\x4b\xf8\xc0\x60\xf5\xda\x51\xe5\x0e\x93\x7b\x93\x73\xd1\x34\xc6\xdd\xf3\xfa\xf4\x20\xca\x97\x6a\xf0\x34\x68\x4c\x38\xb1\xca\x4d\x1a\x7e\x36\xad\x28\x75\xc8\x78\x30\x9a\x10\x21\xa8\x47\xc5\xed\x8f\xdd\xf7\xe6\xf0\x6e\x8c\x26\x99\x8d\x66\x16\x2f\x75\xb1\x7c\x15\x45\xb9\xec\x96\xd5\xfb\x70\x93\xa1\x49\x2e\xb9\x4d\x5a\xbe\x5f\x57\x75\xd5\xbe\x9e\x87\xd7\x91\x28\x0a\x56\xc2\xe1\x1d\xea\x76\x8a\xe6\x75\x83\x52\x92\x20\x1f\x93\xae\x8b\x63\x5f\x2b\x61\x34\x65\xd4\xe8\x40\xe0\x5f\x54\xe5\xed\xe0\x60\x96\x50\xe6\xd2\xf3\xe8\x9e\x3c\x3a\x84\x09\x42\xcb\xbc\xe5\xa2\x5c\x01\xc6\xb7\xda\x13\x73\xee\xd4\x59\x5d\x0a\x6e\xb8\xd1\x22\xb3\xec\x65\x76\x71\xdd\x8b\xcb\x6e\xa3\xf9\x48\x85\x0a\xae\x34\x0f\x55\xa4\xd9\x76\x58\x46\x85\xa4\x88\xf2\x7d\xaf\x5a\xb8\xa9\x3e\x53\xb8\xef\xc6\x89\x98\x7a\xdb\x81\x78\xce\xcf\x74\x54\x19\x95\x69\x84\x8a\x92\xcd\xe9\xe0\x24\x0c\x3d\xc3\xbb\x8f\xe9\xa8\xcc\x13\x34\x45\x3b\x0b\xa2\x1d\xe3\x52\xdc\x18\xc5\x63\x66\x09\x57\x90\x04\x7f\x19\xb2\x8a\xe3\x3b\x50\x32\x32\x30\x50\x7d\xfd\x23\x7c\x6e\xc9\xd0\x16\x4d\x98\xce\x40\xe3\x44\x0e\x00\x56\x76\x47\x09\x64\xbb\x4b\x71\x9c\x5c\x02\x50\xae\x5d\xca\xc6\x81\x30\x2f\xac\x2a\x85\x38\xc7\x7d\xae\xdb\x5b\xba\x75\x3c\x99\x47\x60\x88\x6d\xc9\x7f\xad\x74\x55\xce\x04\xd3\x2c\xe2\x22\xb3\x68\xec\x4a\x9f\x54\xbb\xad\x0b\x39\xde\xd8\x19\x61\x39\x3a\x39\x68\x7b\x85\x31\x7b\x70\xdd\xd4\x93\x9e\x3b\xc6\x88\x00\xc9\x82\x80\xea\x4d\x21\xda\xc1\xee\xd0\x0c\x08\xfb\x19\x23\x32\xb5\x60\xff\xea\xd0\x6d\x17\x9d\x3b\x71\x73\xfa\xeb\xaf\xf3\x17\xd1\xbc\xae\xb6\xe3\x0b\xa0\x84\x63\x2f\x5c\xeb\xfb\x59\xdc\xe7\x4c\x67\xa8\xaa\xa8\x2d\x6f\x8b\x6d\xb0\x9a\x9f\xc7\x8c\x81\xb2\xa4\x61\x56\xda\x11\xea\xf7\x42\x81\xd7\xb4\x1b\xdf\x45\xac\xad\x86\x16\xfc\x3c\x16\x35\xdc\x87\x06\x3c\xc6\x52\xa6\x31\xb1\x5d\xa8\x2a\x28\x33\x0e\x99\xd2\x18\x4b\x63\xcb\x51\xfe\xbc\x5e\x6d\x16\xf7\xa8\x93\xba\xde\x86\x83\x49\x8a\x6b\xe9\x58\x17\x07\x51\x9f\x9f\x8e\x50\xf7\x25\x62\xc6\x52\xa1\x72\xb7\x37\x3d\x43\xdd\x54\xe5\x10\x96\xe3\xc6\x64\x29\x49\xc1\x51\xc7\x39\x41\x10\x6f\xb1\x59\x26\xad\x64\xd6\xe1\x6c\xf9\xcf\x9b\x70\x40\x59\x4e\x7a\xa1\xf5\x73\x5d\xfd\x2f\xa8\xff\x4a\xd4\x93\xb1\x0c\x32\x0c\x33\x70\x02\xe0\x1c\xa2\xfe\xd4\x39\x15\x58\x35\x0f\xdd\x06\x03\x63\xc5\x38\x4d\xac\xc8\xdd\x51\x7c\x94\x77\x6d\xdf\x31\x3f\xef\xd6\x31\x21\xb5\x2d\x88\xee\x68\xa9\x77\x88\x4c\x5a\x85\x28\x9d\xc9\x8c\x6b\x57\x65\xbd\x12\xfb\x7d\xd5\x2e\x4a\x8d\x19\xf5\xc7\xea\x79\xdc\x29\xc3\x98\x8a\x44\xac\xbd\x68\xc2\x12\xf6\xfb\xf0\x2c\x54\x1c\x3b\x58\x59\x23\x0e\xed\xed\xa9\x7d\x15\x32\xc4\x8b\x4c\x89\x88\xda\x57\x6f\x11\x83\x7f\x53\x22\x9a\x31\x65\x38\x46\x32\xe8\x64\x6d\x8a\x97\x87\xe2\x62\x5a\x69\x22\x84\x6b\x79\xfc\x01\xf0\xb6\x3f\x87\xc4\xc1\x0f\x90\xdd\x46\xd9\x8c\x76\x3f\xa6\x13\x83\x7a\xb4\xcb\xfb\xa7\xcd\x6a\xb7\xbd\x7b\x58\x85\x23\x69\xc6\xe8\xb8\x70\xdc\xfd\xde\xc4\x4f\x63\x3a\xb5\x50\x68\x17\x4f\x5c\x0a\x8b\x4f\x72\x33\xb3\x7f\xc6\xf7\x00\x44\xc4\x96\x47\xa4\x5c\x3f\xde\xce\x22\x29\xba\x95\x66\x00\x7c\x8c\xd5\x9c\x42\xe8\x1f\x47\x91\x20\x81\x96\x7e\xdd\x6d\x5f\x37\x55\x3d\xa0\x15\x60\x71\x14\x5b\xc2\xa6\xc3\xe0\xf1\x8d\x58\x84\xfc\x1b\x8e\x23\x21\x63\x4b\x64\xa3\x3d\xca\x1b\x57\xe2\x5d\x39\x4f\xfa\xe9\xbf\xa6\x2d\x5c\xbd\xb3\xc1\xcb\x2f\x8e\x6c\x95\x85\x9f\x87\x3c\x20\xc0\x06\x11\x9d\xc3\xd8\xfc\x42\x48\xc0\x7d\x9f\xd0\x1c\x53\x5f\x8b\x7b\x1f\x4e\xc5\x24\x37\x08\xc8\x57\xe2\xf8\x64\x2e\x08\x8d\x58\x4c\xb8\xc4\x70\x0b\xc5\x51\x9a\xfe\x53\x8d\xf0\x05\xbc\x97\x45\x31\x62\x44\xfb\x9b\xb8\xb3\x59\x90\x03\x8b\x09\x44\x98\x7e\xf9\x3f\xd5\xf9\x56\x1c\xe0\x1a\x0e\xd5\x7c\x80\x16\x53\x9a\xf9\x82\x81\xef\xed\x1e\x1b\xa3\x98\xaa\x04\x2b\x6e\x57\xd5\xe9\x8f\xc9\x77\x21\xc6\xa2\x56\x7d\x2a\xef\xca\xa7\x12\xae\x45\xb8\x61\x96\x49\x04\x14\x3e\xd7\x55\x65\x9e\xcc\x06\x31\x7e\xd8\x8c\xda\x8f\x30\x68\x26\x45\xd3\x40\xdd\xde\x0c\x63\xdc\xc1\x92\x8b\xe3\x34\xb7\x74\x49\xd5\x09\x75\xd1\xca\xf6\x59\x9c\x02\xc2\x9f\xc5\x31\x44\x48\x31\x8b\x84\xf9\xc3\x66\x1f\x3f\x20\x21\x96\x47\xd2\xb5\x5b\x56\x1f\xd3\xc8\x22\x4e\x52\x42\x2d\x9f\x82\x15\xcf\x9c\x64\x76\xe3\x94\x52\xcc\x5f\xbe\x56\x5d\x64\x7f\xfe\x05\xee\x90\xc5\xa9\x01\x99\xf7\xfe\x34\xd4\xed\xd5\x84\x10\x9d\xc5\x19\x89\x30\xa8\xfc\x2a\xea\x83\x18\x5d\x6b\xa6\xa8\xed\xe5\x76\x37\x32\xa8\x63\x0e\x27\xba\xab\x72\xb0\x38\xd3\xe0\xba\xaf\x5c\xad\xfb\x16\xb9\xcf\xf6\x4b\xed\xaa\x21\x0e\x50\xed\x86\xe7\x44\xa2\xe4\x96\x3c\x9d\x6d\xe3\xe1\xfc\xfc\xce\x63\x45\xfa\x9e\xaf\xcd\xb7\xe7\xe7\xfb\x3f\x77\x0f\x8b\xbb\x47\xdc\xeb\x06\xed\x5f\x2c\xce\x65\x1c\x8d\x48\x3a\x6d\xb9\xc9\x1f\x05\xe0\x96\x81\xa6\xae\x41\xb5\x4e\x8b\x76\x10\xd4\xc4\xdc\xe4\xb8\xe7\x3f\x54\xb2\xd8\xc3\x6d\x35\x7a\x1a\x82\xe6\x1e\xa1\xf4\x5c\xbb\x22\xe3\x7c\xbf\x17\x8b\x45\x4c\x50\x8d\xb3\x41\xb9\x10\xa7\x41\xd1\x0c\xe3\xcd\xfc\x1f\x83\x47\xf2\xeb\x3f\xfe\x9c\x4a\x63\xfc\x6d\x6c\xf9\xb2\xec\xb6\x89\xe9\xe2\x90\xc4\xc2\xbc\x0f\x45\x79\x73\x72\x1a\x58\x03\x0d\xfe\x6e\x80\x00\x13\xba\x39\xbf\x95\x4d\xb5\xd7\x1b\x61\xe0\x5e\xd4\x2f\xe1\x41\x49\x1a\xa3\xb3\x7e\x75\xaa\xeb\xa2\xad\x7c\xb4\x70\xa1\xe0\x30\xb9\x69\x99\x2a\x5c\x64\x57\x57\xd7\xbf\x14\xbe\x9f\x7e\x2d\x83\x3e\xf7\x38\xa0\xac\xf0\x8e\x73\x2c\x65\x86\x50\xb8\x55\xa9\x9b\x45\x08\x88\x27\x27\x81\x44\x06\xe5\x4d\xdb\xa8\xe3\xf8\xf6\x27\xb3\x5d\x29\x32\x58\x7f\xd7\xe2\xa2\x17\x69\x14\x5f\xc6\x3a\x07\x2c\x2f\x63\x1d\x09\xee\xda\xff\x19\x96\x91\x26\xa9\xf0\xf1\x15\x69\x4d\x4c\xe4\xd2\x66\x3f\x2e\xf8\x22\x26\x83\x21\x96\x3e\x43\x60\x29\xb2\xbe\x14\x0d\x32\x2d\x4e\x86\xe9\x88\xbb\x6c\xc6\xa6\x2a\xf6\x5b\x38\x1c\x57\x3f\x15\x1c\x87\x05\x5e\x3b\x34\x89\xd2\x14\x91\xfb\x75\x53\xbf\x6f\xab\xcd\x94\x0c\x99\x25\x84\x98\xdc\x45\x37\x98\xb4\xbc\x82\x76\x4c\xc6\x32\x7f\x5f\x09\x49\x65\xe6\x2c\x74\xe7\x08\x5d\xb6\xe1\xb3\x84\x26\xc2\xeb\x71\x3f\x40\x2b\xb4\x68\xc5\x7c\x28\x96\xd0\xd4\x52\x55\x60\x95\xa3\x3b\xcd\x43\x08\x59\x13\x9a\x6b\x3e\xe8\x54\x82\x76\x81\xd4\x89\x1e\x51\x6c\x51\x56\xce\x3a\xcf\xfc\x9d\xbf\x7a\x2a\x72\x44\x9f\x62\x7d\xee\xc9\x6c\x3f\x8a\x16\xfb\xa6\x26\x0f\x87\x25\x71\xe2\x38\x1c\x66\xa1\x54\x2c\x61\x82\x60\x37\xb9\x29\xca\xa2\x79\x9d\x7c\x3d\x89\x35\xf6\x43\x3c\x16\xb0\x79\x2d\xd4\xab\x18\x59\x92\x24\xe1\x11\x56\x8c\x9b\xce\x5f\x1e\xf0\x79\xf8\xc3\x86\x30\xde\x57\x86\x10\x93\xd9\x05\x04\x93\xc5\x9e\xa4\x09\xc7\xac\xc0\x9f\x8b\xc7\x5b\x7f\xea\x6e\x7b\x8a\x9c\x05\xbc\x1e\xf1\x66\x4e\xbe\x2b\x28\x26\x99\x85\xd6\x9b\xd5\x7a\xf1\xfc\xe5\xee\x61\x72\x15\xa9\xb0\xb5\x22\xdb\x8c\xe6\xbc\x2d\xdf\xc9\x3e\x3e\x59\x26\x04\x42\x0f\x6a\x51\x34\x40\x4b\xbd\x38\x1e\xc1\x8b\x53\xb1\x24\x33\xb6\x7f\xca\x72\xd2\x3c\x17\x3f\x61\x7f\x0f\xa6\x9d\x9e\xc3\x18\x8c\x61\x9a\x0f\x80\x23\x4e\x48\x4f\x76\x36\x98\x58\x5c\x46\x08\x11\xf9\x27\x94\xc5\x68\xab\x4a\xb8\x04\xec\x4e\xea\x51\x7f\x2b\xe7\x4d\x4f\x7e\x87\x9b\x9c\xf6\x8d\x08\xab\x2e\xda\x9a\xac\xb2\x44\x68\xc1\x1c\xe3\xca\x40\x21\x6c\xde\x61\x49\x24\xd7\xb9\x95\x0d\xd2\xb0\x98\x6c\xad\x89\x54\x26\x77\x62\x1c\xcb\xd5\x36\x76\x19\x81\xcf\x6d\xfd\x38\xd7\x36\x93\x93\x48\x54\xc6\xd0\x16\xb6\xaf\xb0\x84\xe2\x53\x1e\x7d\x96\x28\x2e\xa2\xa1\xcc\x89\xe3\x81\x99\x35\x3f\x89\x32\x9c\xb8\xe6\x1f\xa7\x91\xf7\x89\x2b\x9b\xe8\x88\x11\xcb\x01\xb4\xdf\x43\x3d\x4d\x4e\x8e\xef\x5e\xf3\x08\x89\x29\x1e\x9e\xbf\x8e\xde\x15\x50\xae\xb3\xa9\xbf\x3d\xf4\x0c\x12\x88\x73\x34\x5e\xcf\xf7\x57\xe3\x6f\xa6\x76\x7b\xbb\x7b\x7a\xbc\x5b\xa0\x3f\x30\x38\x62\x73\xe7\x8d\x6d\x32\xda\x8a\x1e\x11\xee\x86\x98\x58\x20\x9a\x0a\x7f\xf6\x57\x1b\x59\x62\xa4\xb4\x94\x07\x08\xd4\xf9\xa5\x39\x4c\xa3\x58\x62\xfc\x7b\x86\x66\xe2\xa8\xa5\x24\xce\x7d\x77\x23\x16\xf9\x50\x7d\xbf\xad\xea\xd5\xf6\x4b\x18\xe2\x18\xa4\x1f\xe6\x20\x07\x29\x11\x96\xe3\xaa\x81\x12\xb5\x89\x7f\x15\x64\xa4\x34\xd5\x91\x4b\x68\x9e\xbb\xc8\x44\x07\xef\x37\x65\x04\xa2\x28\xe4\xce\x6d\x3f\x87\x55\x82\xf4\x03\x32\x45\x5d\x8a\x61\x24\x50\xe1\x0e\x27\x91\x41\x2f\xd2\x29\x9d\xd4\xcd\xf4\xb8\x88\xb0\x6f\xf7\x80\x94\x1d\xe3\xc0\x2c\x4d\x8d\x25\x2f\x14\xfb\xfd\xa6\xd0\xd0\x3c\xef\x41\xbf\x84\x32\x4d\x18\x24\x85\xf4\xdb\xb7\xcf\x30\xfc\x37\x24\x34\xee\x3c\x59\x64\x35\xd3\xaf\x8a\x16\x79\x06\xf7\xc2\x69\xc0\xf8\x1f\xca\x08\xc1\x56\x05\xef\xd3\x6c\x4e\x88\x05\x34\xa7\x4f\x76\xe6\x34\x13\x16\xe0\xf7\xf8\x7d\xdb\xf7\xfe\xb0\x94\x27\x24\x25\xa1\x18\x32\x95\xca\x61\x29\x17\x19\x66\x91\x97\xcb\xd6\xab\x68\x4f\x5e\xae\x20\x06\xdb\x5a\x16\xf7\x5f\x17\xcb\xa7\x3b\x3f\x93\x53\xd1\xad\x5d\x7c\x14\x75\xf1\xff\x38\xfb\xb2\xee\x46\x71\xf4\xef\xaf\xd3\x17\x73\x01\x48\x02\x74\xe9\x38\x4e\x95\xa7\x93\x38\x13\xbb\x96\xfe\xcf\x99\xe3\xa3\xe5\x91\xc3\xc4\x06\x0f\x4b\x52\x9e\x4f\xff\x1e\x1e\x49\x6c\x26\xe9\x9e\xf7\xa6\xab\x4f\x90\x31\x06\x21\x3d\xcb\x6f\x79\x85\xb2\xba\x11\x15\x4c\x67\x96\x48\x2d\x68\xeb\xe9\xa5\x80\x3c\xfb\xd5\xfd\x19\x22\x7c\x09\x54\x71\x3a\xd9\x6a\x05\xc6\xbf\x7d\x3f\x2d\x16\x46\xe0\xc6\xf4\x22\xaa\xa9\x86\x21\x89\x25\x8f\xd1\x44\x49\x59\x4e\xf8\x11\xca\x3b\x91\x1d\xfb\x59\x22\x39\xd8\xe6\xce\xa0\x33\xf5\x84\xfc\x9f\x6a\x75\x14\xe7\x6a\x30\x12\xb4\x27\x87\xb5\xf9\x5e\xbf\x79\x4c\xf6\xd9\x58\x1a\xdb\x30\xf4\xe2\xc7\x7d\xa0\xb4\x7c\x69\x72\x5f\x73\x8b\x35\xb7\x50\x2c\xb7\x23\xee\x95\x38\x1e\xa5\x70\x19\x43\xea\x07\x49\xe5\x05\xd5\x7e\x64\x39\xf8\x52\xd7\x87\x68\xea\xe1\x34\x0a\xc7\x1d\x9b\x18\x02\x83\x5b\xf0\x6a\xfd\xe4\x25\x82\xfc\x11\x2e\x50\x09\x41\x62\xf8\x3c\x48\xfd\x62\xe0\x32\xb2\x7d\xee\xbc\x16\xc7\xc5\xa1\x04\xac\x03\x77\x87\x4d\x84\x4c\x72\xeb\xf2\xfd\x24\x8e\x8f\x50\xbf\x17\xe5\xeb\xb5\xf9\xf4\x47\x15\x93\xff\xcf\x7f\xdd\xf7\x9b\x00\x90\x25\x0a\xae\x31\xe9\x34\xd4\xfc\xe5\x19\xa6\xec\xfe\x5b\xa3\xc1\xe1\xb8\x1e\x33\x78\xc3\x4c\xcc\xc1\x2b\x34\xd6\x2f\xeb\x1c\x7b\x64\xee\x24\x49\x10\x1a\x24\x82\xec\x0a\xe7\xb3\xd0\x1d\x48\x42\xec\xb6\xec\x6d\x34\x81\x45\xd3\xbb\xb2\x38\xdd\x8b\x6a\xd2\xdd\x99\xbd\xf8\x24\x48\x69\xea\x74\x11\xd6\xb9\x29\x16\xb2\x3d\xc9\x79\x82\x49\x27\x49\xc8\xa9\x61\x83\x5e\x84\xf7\x88\xb1\x8b\x0d\x46\x1d\x7e\xa4\x66\x2c\xf4\xaa\x6a\xf8\xcd\xbb\x62\x29\xce\xe7\x4e\x71\x00\x26\x51\x59\x12\x81\xb5\x9e\xce\xaa\x65\x79\xd1\xe5\xf7\x0c\xde\x67\x9b\x35\x09\x89\x62\x6c\x1b\xdc\x89\xaa\x7e\x06\x71\xcc\xaa\x3a\x53\x4f\x97\x52\x9c\x3c\xaf\x96\x24\x84\x05\x89\xec\xa4\xc7\x8b\xf7\x76\x3b\x1d\x04\x3a\x09\x89\x03\xfc\x32\x30\xef\xfe\x23\x94\x0b\x6f\x25\x50\xee\xd5\x78\x41\x48\x98\xe4\xf8\xc2\xa1\x9e\xca\xb7\x6a\x68\x96\xf9\xcf\xb4\x07\x34\x79\x14\x53\x92\x30\x82\xd6\xf1\x2f\xa2\xda\x97\x80\xdc\x0b\x7f\xaa\x44\x2a\x44\xb6\x1c\xb1\x9b\x8e\x20\x15\x1f\x6b\xfb\x11\x1a\xf4\x00\x10\xf8\x98\x29\xf8\xd2\xf8\x89\x94\xa4\x86\x62\x21\xe5\x71\xb3\x79\xf6\x7f\xe3\xdc\x86\x80\x95\xd5\x3d\xb0\x6f\xe5\x16\x44\xe5\x80\xf5\xb8\xd8\x4c\x9e\x25\x97\x10\x75\xd2\x4a\x5d\xb1\x2e\x11\x5c\x4a\xbb\x97\xb5\x2f\xac\xea\xea\x8f\xdd\x1c\x14\xc6\x0c\x6c\x7b\x9d\xf8\x7e\x33\x84\x78\xba\x81\x92\x50\xab\xb0\xda\x6e\x12\xa8\x59\x33\x57\x98\x4f\x64\x2a\xb8\x23\xb7\x1d\x8b\xb9\xd4\x2f\x9d\x23\xda\x90\x44\x69\x47\xf9\x14\x47\xc8\x2d\x14\x7d\x3a\xc7\xe7\x69\x3b\xe3\xdb\xa0\x13\x86\x00\x87\xea\x7c\x7d\x02\x37\xc4\x38\x61\x2b\x07\xf3\xdc\x98\x1f\xd6\xed\x78\x2c\x6f\x65\x07\xa7\x41\x62\x50\x9d\xb2\x0d\x92\x6c\xf8\x36\xda\xb8\xd2\x00\x02\x62\x4d\x5b\xcb\x57\xa8\x6f\xc1\x88\xe6\x58\xdf\x01\xdc\x7b\x38\x36\x49\xc3\x50\x05\x93\xf4\xae\xdd\xa4\xc6\xe7\x09\x19\x97\x9e\x63\xfb\x24\xba\x70\x20\x0d\x53\x66\x95\x37\x64\x73\xf9\x99\x5d\xf7\xf5\x46\xcf\x28\x0d\xa5\x48\xbc\x0b\x40\x51\xd4\x23\xe0\x65\xff\xba\xa4\xa1\x8a\x13\x2f\xd8\x9b\xd7\x23\xad\x75\x92\x12\x63\x0d\xd4\xd1\x21\xc8\xff\x91\x06\x09\xa2\xb5\xf7\x48\x31\x9e\xfa\x63\xf8\x41\xc2\xe6\x24\x98\xb8\x9c\x8b\xb3\xe8\x3e\xad\xad\x17\xda\x8b\x78\x03\xe7\xb0\x5f\x82\xc9\x7e\x21\x0f\xf9\xff\xa0\x2c\xe6\xd3\xdd\x94\x45\x1c\xb5\x20\x5d\x00\x66\xf5\xd2\xba\x2a\xe1\x4d\x51\xbc\x76\x02\x23\x13\x21\xfb\x3f\x57\xe7\xf8\xdf\xb6\x83\x94\x11\xdb\xc6\xda\x21\x91\xcb\xdd\xb1\xb9\x19\x98\x32\x23\x30\x20\x91\xef\x5d\x6e\x9e\xc6\x01\x47\x26\x47\x93\xbf\x88\x63\x7d\xf7\xb3\xfb\x7b\x68\x45\x4d\x57\xb9\x2a\x2f\xe7\xc9\xf2\x9c\xc6\xa9\x35\x71\x6f\xf2\x76\x71\xf9\x72\x2c\xe4\x48\x1e\x81\xa4\x49\xa4\x99\x13\x92\xb9\x17\xb9\x9e\x58\xec\xf8\x41\x3c\x49\x75\x27\xdc\x73\x84\x79\x85\x00\x92\x26\x8a\x7a\xdf\x26\xc4\xaf\x4f\xa2\xe7\xf1\xa3\x4e\xa9\x22\xbd\xf4\x8a\xeb\xd4\x8d\x4b\x2a\x69\x9a\x30\x70\x01\xc6\x2d\x88\xe3\xd5\xd4\x9d\x0f\x2f\xe6\x1a\x09\x69\x0a\xd6\xb5\x1a\xe5\x39\x70\xd5\x41\x05\x29\x71\xac\xac\x2a\xd8\xf8\xe2\x78\x60\x39\x0e\xb7\xa2\x58\x8a\x2a\xcb\x8b\xcf\xcb\x6b\x93\x0f\x33\x0b\x45\xed\x20\x15\x1f\x91\x95\x48\x2a\x14\xc3\x66\xd1\x0f\x71\xb9\x99\x04\xce\xa9\xd4\x1c\xcb\x59\xb9\xf3\x08\x1a\x76\x50\x52\x09\x80\x55\xf1\xa7\xa3\x50\x80\x7b\xd9\x5f\x8c\x65\xdc\xe7\x15\x89\x10\xde\xe9\xbc\xd2\x8f\xc6\x33\xaf\xfc\x17\x28\x6a\x39\x80\xf6\xf1\xb4\x91\xc3\xe8\xdd\xb9\xcd\x2a\x61\x65\xd6\x3f\xd8\xbd\x53\x25\x05\x8a\x35\x38\x5b\x38\x8b\xe5\x73\xe8\xba\x32\x2b\x30\x12\x9a\xbf\x36\x1d\x98\x81\x0d\xd5\xf6\x7c\xcc\xa6\xd3\x1a\x98\xc0\x6e\xcb\xf0\x6a\x3a\x09\x01\x92\x82\xe4\xb8\xe2\x01\x1a\x44\x8e\x98\xad\xe3\xf3\x18\x22\xe3\xd4\xbb\xb6\x23\x1d\xb8\x97\x2f\x24\xa9\x01\x6b\x83\x87\xab\xee\x49\x5a\x59\xb8\x59\x21\x25\xc2\x83\x20\xf2\x3a\x66\x6d\x84\x85\x12\x09\x78\xf9\x3e\x00\xe1\x01\xa4\x18\x51\x6b\x7b\xad\x1e\x3e\x33\x49\x34\x78\x18\x84\x78\xdb\x9e\x37\xf7\xab\xfd\xe2\xf6\xa1\x4b\x53\x78\x28\x78\x12\x8c\x9e\xc8\xdc\x4b\x36\xfa\x81\x3c\x54\x36\xdb\xed\x42\xde\xe9\xd7\x45\x89\xe5\xb0\x94\x90\x9d\x50\x39\xbd\x3b\xa0\x98\xf7\xab\x7c\x6c\x4e\xd6\x74\x14\x81\x30\xfe\xf6\x70\x42\x42\x4c\xb6\x1f\xfe\xb8\x9f\x07\x98\xfa\x71\x2a\x4d\xc2\xa1\x5f\xee\x7c\x33\xba\x1b\xad\xc1\x76\x9a\x8b\x23\xdc\x67\x39\xfc\x28\x8b\x2e\x54\xe2\xc4\xc4\x51\xdf\x5d\xb9\x85\x53\x53\xb6\xe7\xba\x03\xb8\x56\xda\x26\x9c\x12\x9e\x78\x35\x82\x2f\xcb\x76\x2b\xab\xae\x46\x08\x49\x7d\x94\x5b\x2f\xca\x79\x7a\x47\x3b\x4e\x61\xcd\xc9\x8b\xb9\xf8\xac\xa9\x6b\x38\x73\x1a\x83\xb0\x1e\x44\x79\x23\x8e\xc7\xcb\x2a\xd7\xe3\x5d\x91\x53\x61\x51\xbc\xd6\x91\xd4\xe1\x5b\x06\x56\x7c\x84\xb3\x20\xb2\x60\x92\xf5\xcd\x7a\xb7\x5b\x2d\xbf\x76\x07\x48\x1a\xb9\x87\xb1\x7b\xc9\xc6\xc6\xf7\x84\x33\x00\x1f\x1d\xfc\xa3\xc9\xd4\xeb\x4d\x73\x79\x12\xf5\xcb\x6f\x63\xce\x09\xe1\x31\x55\x98\xfa\x15\x3e\x4b\xab\x56\xf5\xcb\x50\xc7\x99\xf0\x04\x38\xf4\xf2\x50\xe7\xa6\x06\x3b\x73\xd0\xff\xb1\xec\x46\x99\x14\x53\x71\x04\x2c\xda\xf9\xb7\x3f\xf6\xa1\x3e\x4f\x03\x8d\xbb\x38\xae\xb0\x90\x7b\x8b\xa2\xf9\xd5\xba\x27\x67\x8c\x1f\x4d\x9a\x06\x28\x70\x68\x57\x81\x87\x2c\xff\x7b\x73\x9a\x20\x67\x38\x27\x0c\x5f\x96\xdf\xff\x58\xee\xbf\x6d\x6f\xf7\xf7\x0f\xbe\x31\xc5\x85\xb0\x32\x43\xfb\xf6\x9e\xb9\x65\xe2\x0e\x60\x1e\xab\x3a\x79\xda\x32\x50\xf8\x1c\xf0\xe1\x84\x1e\x8e\xc9\x65\xa8\xe9\xb4\x6d\x3c\x47\x7d\x23\x5c\x26\xe0\x3d\xb3\x6f\x9e\x66\x73\x16\x2e\xa5\x41\x1d\xd7\x87\xc5\xcf\xfd\xfa\xf1\xfb\x6a\xbb\xeb\x82\x77\xae\x92\xd4\x8b\x50\xb8\x0f\x6f\xcc\x40\x3a\x77\x7c\x22\xc5\x05\x42\xc5\xf0\x05\xf8\xbd\x33\x13\x21\x5c\xc9\xd0\x3b\x51\xa0\x79\xd7\x7a\x82\xa2\xe6\x4a\x41\xa8\x86\xbd\xbb\xad\x38\x82\xb3\x49\x9c\xdb\x3d\xa6\x0c\x11\xae\x20\x45\xec\x94\x5b\xe2\x1f\xb2\x5f\xf0\x21\x6c\xac\xfb\x88\x55\xa3\x97\x90\xab\x97\x29\x15\xe1\x9a\x96\xc3\x75\xea\x2c\x57\x06\xaf\xcb\x3e\xde\xdf\x82\x82\x5e\xd1\x9c\x70\x0d\x31\x78\x6c\x61\x47\x9f\xef\x77\x26\x37\x0a\x68\x8c\x15\xda\xfb\xe2\xb0\x56\x85\x37\xfb\xeb\x56\x68\x90\x24\xf0\x37\x6c\x98\xc4\x0c\x4a\x1e\x1c\x24\x44\x2e\x3c\x6e\xce\x73\xc7\x55\x88\x38\x31\x4f\xdd\x02\x6b\xb6\x30\x3f\xcf\x0c\xb5\xb6\xfa\xe6\xd7\xf9\xa1\xb9\x8e\x6e\x26\x83\x19\x41\x52\xd8\x56\x18\xf8\x92\x99\x2b\x6c\xcf\x70\xcd\x15\x01\x4b\x94\x25\x58\x2d\xdb\xc0\xf7\xd0\x94\xdd\xcf\x14\x01\x4b\xb1\xa0\xbd\x68\xea\xe2\x4e\x94\xe0\x55\x60\x3a\x84\x92\x08\x74\x80\xb5\xc1\x67\x27\x2f\x34\x50\x64\x9d\x4b\xc6\xfa\xb4\x40\x44\x3a\x40\x92\x53\x1b\xb0\x89\x5a\x4c\x1b\x8b\x82\x04\xd6\x3c\x63\xa1\xea\x62\xa0\x34\x4c\x04\xe1\x71\xea\xc3\x33\xf7\xbe\xcc\x06\xf4\x82\x85\x31\xee\xed\x6f\x19\xbc\x6f\x9b\x33\x8c\x80\x25\x82\xc5\xa0\x2c\xcc\x02\x35\x54\x1d\xcd\xe4\xf3\x3b\x2b\x58\x62\xe1\xff\xd8\x03\x99\x77\xfc\xed\x46\x4a\x44\x15\x55\x2f\xc5\xfb\xb3\xfe\x51\xe4\x8f\x13\x01\x19\x22\x98\x56\x98\x2d\xaf\xfe\xf1\x6d\xbd\x7b\x5e\xdc\xae\xfc\x5b\x2d\xe2\x40\x62\x25\xd0\x0b\x94\x7c\x88\xd3\x99\xac\x8c\xe3\x75\x51\xc4\x61\xc8\xdc\xe2\xd0\xde\x62\x29\x2a\xb4\x50\x3d\x16\x42\x7f\x2b\x8f\xa3\x94\x50\xc4\x9c\xa3\x7a\xff\x13\x3c\x89\x5b\xe8\x2e\x44\x82\x15\x8f\x29\xf2\xa2\xfe\xf9\xf3\xe7\xad\x38\x9f\x87\x91\xa7\x88\x55\x84\x6d\x2e\x09\x23\xfb\x44\x22\x92\x40\x4b\xe1\xe9\xd1\x42\x63\x1b\x6f\xfc\x78\x12\x62\x5b\xe6\xa7\x42\x67\xe6\x82\xca\x47\x4b\x71\xae\xae\x26\x42\xca\x08\x52\x92\xdd\x7b\x62\x8b\x9a\x96\xfd\x54\x1c\x8f\xa0\xfa\xd7\x52\xa4\xb1\xa5\xa6\x9c\xac\x88\xcc\x4d\xd6\x1f\x49\x42\x7c\xeb\x9f\x57\xab\xfb\xd1\x0f\xe0\x61\x8a\xd9\xe9\x29\x6b\x5f\xc1\xd3\x79\xa8\x71\x34\x35\xde\x9f\xcf\x29\xfc\x89\x38\xc1\x76\xd2\xdf\x95\xa8\x5e\xbe\x9d\x0f\xa5\xd0\xd0\x61\x32\xc6\x0b\xb1\x10\x51\x64\xd9\xd4\x3e\xbd\xbc\x5f\xcc\x79\xc1\x13\x21\x52\xab\x11\xd3\x26\xea\x36\x84\x2b\x2f\xed\xaa\xe5\xaf\x5e\x81\xb0\x86\xde\x72\x46\xd8\x8b\x08\x88\xd2\x90\xda\x55\xac\x13\xb5\xf5\x54\x20\x3f\xc4\x58\xc9\xc9\xb3\x68\x2a\xf8\x96\xe3\x3f\x9d\x82\x01\x11\x86\x6a\xbc\xd2\xcf\xdf\x12\x3b\x58\x06\xda\x96\x1f\x6d\x2b\x63\x24\xe2\xe0\x46\x84\x4c\x23\x2a\xfe\x21\x1b\xcc\x15\x19\x72\x6b\xe1\xa6\xb3\xea\x98\xbd\xc2\xbe\x0d\x3b\x5f\x87\x65\x32\x37\x2e\x22\xd4\xbb\xa1\x2e\xea\xba\xf0\x06\x93\x37\x70\xd7\xbe\x8e\xdd\xab\x2d\x23\x1a\x6b\x8b\x50\xc6\xa7\xb0\x7a\xcb\x8e\x0f\x45\xd9\x95\x53\x65\xc4\x2c\xd2\x14\x49\x86\xeb\xbc\x06\x34\xb4\x72\x07\x49\x10\x41\x62\xfb\x29\xc7\xcb\x5d\x51\xf6\xf1\xfc\xe8\x85\x91\x24\x0d\xb0\x64\x6b\xad\xe5\xbf\x14\xc5\xb5\x62\xc5\xec\xbf\xd3\xad\x51\x12\x50\xca\x19\x48\x3d\xef\xfa\x68\xc1\x4f\x5d\x49\x25\x60\xf9\x70\x23\x6b\xc8\xa1\xdc\x5b\xf5\x6c\x75\xd5\xf5\x96\x8c\x04\xcc\x6d\x38\x1d\x16\x7d\x08\x5a\x9b\x0e\x8f\xb9\x1f\xee\x1d\xc0\x96\xae\x74\xff\x45\x54\xd6\x49\x78\x7c\xa5\x2c\x0d\x90\xa0\xf3\x0c\x67\x10\xd6\xdb\xf5\x34\x46\x50\x49\xa6\x02\xcc\x9d\xad\xe5\xd1\xb6\x38\x8e\x3c\x3b\x47\x6f\x8c\x64\x5a\x11\x4b\x52\x07\x85\x94\x78\x7f\x92\x98\xa6\xb1\x03\xf3\xdc\x83\xa8\xd0\x27\x64\x72\x29\x71\x1c\x23\xc5\xf6\xec\x5a\x45\xbb\xb2\x38\xbf\x5c\xa6\x83\x84\x42\x7f\x03\x0d\xa6\x0d\x2d\x1d\xf6\xfb\xe6\xb2\x6d\x64\x7d\x39\xc3\x4c\xb7\x5c\xc6\x46\x62\xf7\xff\x61\xf3\x7d\xbd\x5a\x3e\xaf\x6e\xd7\xbb\xad\xbf\xac\x84\x25\x71\xdf\x9d\xfe\x6d\xb6\x28\x26\x13\xa9\xd0\xc0\xe4\x5c\xc2\x54\x42\xa3\x3d\x68\x30\x87\x30\x16\xfe\x33\x0e\xce\x65\x02\x56\x7b\x79\xbb\x5c\x7d\xb6\x63\x4b\xc1\x19\x06\x3a\xf5\x4b\x59\xbc\x57\x3f\x5e\x20\x77\x2c\xec\x2c\x3f\xac\xcd\x63\x51\x23\xe4\xb4\xca\x7c\x2a\x24\x85\x8a\xc1\xb6\xc1\x9d\x44\x64\xc7\x7c\x1a\x02\xb0\xa5\x94\x11\x46\x02\x32\x24\xbb\x02\xe5\x14\x5c\x6d\x99\xb8\x01\x2a\xe5\x98\x4b\x7f\x81\xfa\x4b\xe3\x3b\x67\x8f\x85\xff\xbc\xe2\x42\x39\x0e\xd6\xb2\xc0\x04\xf1\x83\x5a\xea\x67\x3f\x4e\x89\xd4\x6a\xf3\x23\xa6\x77\x4e\xd3\x6b\xf2\xfa\x28\xd0\x18\x66\x75\x62\x02\xd7\xf2\xae\x44\x6a\x66\x2b\x0c\x08\x92\x6e\xb3\xbb\xa7\xb2\x38\x15\x23\x6f\x0f\x3f\x32\xb6\x95\xed\x1c\xde\x6d\x56\x7e\xc5\x7e\xf5\x03\x93\x24\x24\xde\x99\xe3\xbc\xa8\x3b\x5e\xe1\xe4\x9b\xa5\x46\xad\x3a\xd0\x59\xfd\xa7\x56\x42\x9f\xee\x30\x52\xeb\x08\x7b\x17\x59\xf5\x50\xbc\x65\xf9\x61\x95\x0f\x2a\x19\xd2\x04\x0a\xdb\xf2\x0b\xaf\xb9\x49\xa4\x81\x24\x16\xbd\x51\x27\x36\x88\xc5\x07\xcc\x7f\x15\x24\x21\x62\xdc\xdf\xa6\xb8\xa1\xd1\x45\xa8\x90\x28\x04\x84\x7d\x59\x6e\x7e\x2e\x9e\xee\x3f\x4a\xd7\xc6\xea\xf6\x44\x85\x29\xf1\x76\x83\x16\x7d\x58\xcd\x49\x51\x12\x15\xaa\x14\x99\x4b\x52\xd4\x73\x41\xbf\x1b\x45\x88\x42\x04\x50\x76\x76\x72\x50\x44\xd1\x80\x21\x63\xfb\xfb\x7a\xb7\xea\xfe\x16\x6a\x14\xb0\xba\xcb\x72\x37\x23\xdb\x00\x75\x93\xaf\xf5\xb6\x6e\xf4\x54\x1c\x96\x28\x16\x53\xa1\xbd\x3d\xce\xff\xdd\xfb\x04\x51\xb1\x38\xb1\x4c\x5f\x2c\x6a\x7e\xb7\xcc\x94\xa5\xc8\x75\xd6\x4e\x90\x9b\x8b\x35\x77\xfe\xb4\x49\xa6\x18\x08\x44\xbe\xaf\x97\x9b\xfd\xd3\xd7\xc5\x76\x45\xf6\x4f\xab\xe7\xf5\xe6\xd6\x7f\x49\x1c\xc5\x89\xdd\x1a\xc5\x29\x1b\xae\xa9\x2a\x66\x04\x5f\x89\x81\x03\xdf\xa8\x41\xaf\x62\x96\x20\xf2\xa2\x6a\x4e\xeb\xe5\x06\xaf\x86\x7e\xdb\xf6\x67\x4e\x09\xd6\x49\xee\x37\x5f\xf6\xb6\x69\x3c\xe2\x1b\x8e\xaf\x33\x16\xb1\x8e\x3d\xd8\xad\xce\xa1\x1a\x91\x34\x54\x12\x53\xe3\xb1\x57\xd9\x2f\x38\xce\x62\x43\xe7\xfb\x05\x2a\x49\x03\x9e\x78\x1c\x81\xdf\x98\xfa\xd5\x51\x25\x42\x63\xdd\xfa\xef\xd9\x49\x0c\xe4\x81\x88\x4a\x54\xe4\x3d\x9e\xb7\xcd\xf9\x3c\x70\x97\xee\x47\x08\x54\xd8\x5a\x1c\x8f\x59\xde\x03\x87\x55\xaa\x35\x0a\x0b\x3d\xa1\x2d\x4d\xf7\x57\xe0\xc8\xc6\xda\x57\x2f\xa2\x84\xdb\xac\xc2\xb5\x70\x2c\xb1\x33\x9e\x96\x5c\xe8\xd0\xaa\xa0\xdc\x2c\xee\x17\x8f\xcb\x6e\x8a\x71\x65\x7d\xf9\x0f\xde\xd6\x78\x32\xa5\x04\x00\x42\x8e\x95\x73\xa6\xdc\x15\x63\x2f\x8a\x29\x20\x6e\x00\x67\x56\x2a\xd5\x36\xe9\x3e\x8a\xec\xd4\x9b\x12\x6c\xe1\x0d\x4a\x71\x74\x25\xa3\x6a\x51\x8d\xe5\x53\x06\x8a\x87\x7d\x8a\x3c\xf9\x39\x0a\x42\xed\xb8\x6d\x9b\xa3\xf6\x85\x3e\x4c\xc3\xc6\x03\x75\x6c\xb1\xe1\x23\x86\x66\x3b\x1d\xc6\x4f\x56\x4b\x9e\xd8\x20\xb2\xb4\xca\xc0\xbb\xc2\xe6\x5a\xe3\x9b\xa1\x21\x14\xbd\xab\x8e\xb7\x65\xf8\x60\x22\x6a\xb0\xc2\x87\x5e\x6c\x78\x91\xeb\xe5\x0b\xa8\xd7\xb5\x71\xa6\x9d\xbb\x02\x3d\x8c\x7b\x7c\xdf\xf4\x04\x26\x46\xad\xb9\xae\x66\x61\xa1\xf3\xd7\x6e\x4b\x2e\x21\x57\x90\x84\xda\xf9\x25\x2e\x8b\xff\x5e\x7b\x6c\x0e\x5d\x0d\xba\x8f\x24\x98\xc3\x3b\xbe\xd1\x67\x05\x56\x05\x22\xf1\x6d\x72\x7f\xc7\xb7\x50\xbe\x41\x89\x40\x18\x54\xda\xb8\xcf\xaa\x1a\x7d\x59\xe6\x7a\x3d\x0a\x94\xa2\xda\x77\xbc\x9c\x3a\xc4\xb2\xc8\xf5\x0c\x02\x52\x81\x76\x8c\x8b\xea\x3c\x7c\x7f\x75\xe8\xea\x6d\xf8\x78\x3c\x42\x6c\xce\x2a\x9b\xe8\x30\x4d\xb1\xd9\x78\x46\xa7\xe8\xfb\x8f\x5c\x83\x88\x0e\x39\x47\x56\x89\x85\xdb\x2c\xcb\xa2\x39\x67\xd3\x02\xab\x8e\x42\xcb\x18\x42\x86\xca\xbe\x84\xde\x25\x96\x68\x92\x08\xe2\x58\xbd\x5b\x71\x84\x2b\xda\x5b\x9b\x5a\x58\x94\x79\xf1\xfc\x99\x36\xdd\xf8\x1b\x89\xa6\x5e\x66\xeb\x8b\xa8\xa7\x9e\x3b\x6e\x10\x25\x60\x44\x07\xb9\xbe\x2f\x44\x3e\xa8\xe7\xf4\x17\x40\x29\xa4\x0e\x58\x81\x2b\xde\x72\xce\xb2\x6b\xbc\xdc\x69\x46\x2d\xac\xa2\x82\xfa\x69\x39\xff\xed\x8c\x51\x2b\x52\xdc\x4b\x80\xb6\xa1\xe1\x27\x8e\x60\x44\xc7\x82\x27\xcc\xa5\x84\x3b\x8c\x00\xfd\x36\xf9\x58\xd4\x36\x24\xe8\x6e\x6c\x12\x28\xa2\x3c\x2a\x3e\x7b\x83\x23\x1c\xbc\xa7\xe5\xe4\x4a\x92\xc4\xf0\xd4\x4f\x4e\x30\x66\x50\xaf\x0a\x23\x8f\x75\x9c\x2d\xb3\xe8\x34\xb6\xb8\x8e\xac\x72\xa8\x76\x24\x1d\xfa\x83\xc2\xb2\xc1\xd6\x5f\xfa\xbf\x28\xd3\x29\x42\x3c\x5c\xdc\x3c\xb6\x59\xbd\x1f\xc3\x21\x41\x2a\x0f\x56\x6d\x06\x3b\x81\x16\x3c\x42\x75\xbb\xac\xf2\x72\x5b\x1f\x01\x1c\xb5\x10\x29\xda\x39\x20\x45\x0d\x4e\x45\xee\x05\xe1\xff\x27\x76\x8c\x96\x91\x05\x63\xdc\x7e\x5d\x6e\x87\xbb\xb2\x96\xca\x56\xb6\xd7\x48\xf0\xee\x28\x6e\x5a\xf1\x04\xcb\x15\xce\x5f\x61\xf7\xab\xea\x8e\xa8\x30\xb1\xef\xc9\x5b\xef\x32\xd8\xfe\x59\x5a\x49\xfa\xbe\x6c\xfb\x49\x3c\x75\xd5\xb4\xfb\xb0\x20\xaa\x95\x66\xa8\x89\xd0\xce\xae\x7e\xfb\x58\xd5\x13\x40\xb4\xd6\x5c\x84\x0e\x08\xfb\x20\xf2\x4b\x57\x15\x9d\x91\xff\xe9\xce\xad\x41\x62\x0e\xb2\xdd\x2d\x76\xab\xfd\xcd\x6a\xb7\xbf\x5d\x6f\x17\x37\xf7\x2b\x1f\x75\x68\x60\x29\x56\x86\x5c\x13\xeb\x0e\xd0\x51\xe3\x63\x75\x26\x0d\x60\x5d\xa7\x1e\x16\x8f\x5f\x17\xbb\xdd\xe2\xf1\xe9\x79\xf3\xf3\x8f\xe8\xf1\x76\xeb\x03\x31\x6d\x22\x1d\x38\xe5\x9e\x6f\x95\x9e\x25\x51\x40\x10\x18\xea\xd0\x8a\xa7\xf3\x4d\x56\xf6\x3f\x77\xfc\x64\x21\xe0\x1c\xa3\x63\x2f\xab\xa2\x1b\x55\x7f\x81\xbc\xc9\xf2\x3f\x49\x39\x20\xa4\x21\xa2\x68\x8e\x60\x6a\xf6\xdb\xe4\x18\x4b\xa8\x5b\xe5\xef\x8b\x89\x49\x25\x81\x28\x8c\x70\x4f\x92\x99\xee\x6a\x7b\xb3\xaf\x39\x44\xd4\x0a\x97\xed\x3d\x1c\xa1\xa7\xcd\x7e\xf0\x7b\xa2\x94\xe2\xef\xb9\x5f\x3f\xfe\x8e\x19\xb3\xfb\x3b\x89\x23\x4c\xb3\xd1\xff\xe4\x46\xa8\x57\x28\xaf\x31\x57\x10\x33\x1a\x8e\xf0\x83\x2e\xc4\x1a\xaf\x13\x10\x33\x89\x39\xb0\x6c\x2e\xbb\x4c\xbd\x42\x7d\x73\xd9\x0c\x05\x18\xae\x00\x11\xa3\xb5\x02\xe2\x58\xf0\x8e\x09\xb2\x2c\x4e\x67\xa8\xb3\x41\x82\x0c\xb1\xd6\x22\xe9\x1b\x97\xc5\x54\xbb\x92\x40\x6c\x2c\x5b\xb3\x5d\x01\x84\xbe\xec\x8a\x9b\x12\xa6\x84\x13\x48\x08\xc1\xa5\x5f\x78\x8f\x0e\x57\x20\xf2\xaf\x22\x24\xda\x0a\x7d\x58\x38\xf5\x4d\x53\x62\x77\xb4\xee\x70\xf1\x90\x46\x56\xbf\xfa\x80\x4e\x78\x4f\xd6\x97\xaa\xdd\x9c\x6e\x3a\x30\x15\xa4\x24\x51\x0e\x27\x86\x91\x49\xb5\x19\x56\xd6\x20\xa5\x29\x56\x02\xaa\x4b\x55\xc3\x69\x9c\xeb\x43\xca\xad\x04\xe7\xb9\x38\x66\x2a\x83\xc9\x7e\x03\xa9\x8c\xb0\xfd\xd0\x23\xe6\x7f\x64\xf5\x4b\x3b\xa1\x9a\xf3\x9f\x55\x99\xdc\x29\x78\x28\x70\x45\x77\xa1\xc9\xc2\x0b\xb1\x4d\xee\xa7\x20\x04\xfb\x85\xed\x76\x72\xd3\x64\x47\xfb\xd4\xb7\x78\xcd\xcb\xa2\xa3\xaa\x83\x0c\x43\xed\x54\x7f\x8a\xa6\x1e\x79\xba\x12\x90\xb1\x85\xf8\xdc\x64\x87\x9b\xa2\x90\xd5\x70\xa1\x04\x19\x9b\xd8\x9a\xdd\x7c\x29\xc4\x71\xf2\xb6\x4a\x1d\xa1\x12\x9a\xaf\x84\xde\x95\x33\x7c\xc6\xf1\x0f\x93\x86\x32\x5b\xd4\x44\x24\xb2\x15\xf5\x19\x26\x34\x56\x01\xd2\x8d\x56\x92\x23\x62\xee\xdd\x67\x8a\xa0\x03\xf0\xc2\x0e\x76\xa9\x9b\xad\x4e\x81\x56\x56\x95\x63\x8f\xed\xe5\xb9\x77\x41\x2b\xd9\xb1\xf7\x51\x6d\xb5\x28\xa7\x7d\x24\x80\x34\xc6\x6a\xe2\xe9\x24\x6c\xa9\xc9\xef\xa6\x5e\xee\x93\x00\x00\xc3\xac\xb3\x8d\x2b\xee\x8a\xf2\x56\x5c\x3e\xe0\x85\x80\x11\x96\xdf\x68\xbf\xed\xa6\xa3\xd6\x81\x91\x1a\xb7\x45\x6b\x44\xd9\x35\xee\x87\x86\x2f\x76\x17\xf9\x67\x2f\xa5\x36\xf8\x3f\x7b\x16\x13\x84\xc6\x6a\xde\xfb\xfd\xe2\x37\x7f\x80\x32\x4c\x17\xc6\x1a\xb9\x8e\x15\xf0\xf1\x3f\x57\x3f\xc0\x04\xb1\x46\x46\x51\x73\x3e\x16\x42\xdf\x65\x33\xae\xc6\x93\x75\x63\x74\xc1\xe3\x93\x85\x31\xc7\x4a\x44\x05\xf5\x2d\xbc\xcd\xd4\x2b\x4d\x98\x72\xfc\x41\xcb\xcd\xc3\xc3\xb7\xc7\xf5\xee\x8f\xfd\xe2\xf6\xf6\x79\xb5\xf5\x15\x3d\x13\x8a\x24\xed\x2b\x7a\xb7\x70\x14\x97\x2b\xb5\x6d\x62\xda\xdb\x92\x0c\x04\x2f\xaa\xda\x7a\x05\xcc\x0c\x8d\x08\x71\x96\xeb\x65\xde\x3b\x1e\x4c\x2e\x3c\xe2\x09\xbe\x4a\x98\xd7\xdd\x67\xff\x69\x32\x9d\xd5\x97\xe7\x61\x48\x6c\x22\xc9\xb1\x44\xfd\xb4\xfb\x3a\x57\x45\x1b\xf9\x9f\x12\x13\x81\xc5\x8b\x95\x4d\xde\x5e\x98\xb5\x00\x76\xc7\x88\xb4\xd3\x7d\x28\x48\x85\xc8\xd7\xff\x76\x6f\xa1\xa1\x81\xb0\xa2\x55\xbd\xfe\xee\xfc\x03\xa4\xc6\x4a\x78\xe0\xa5\xaf\x7b\xa5\xe0\x1a\x23\xab\x99\x7a\x9e\x89\x83\x38\x76\xad\x0e\x84\x1b\xdc\x88\x8f\xb8\xa4\x26\x0e\x34\x57\x43\x25\x65\xfc\x1d\x5e\x58\xc0\xc4\x22\x64\x6e\x67\xf5\xb6\xec\xb3\x21\x9b\x89\x25\xe0\x16\x71\x5f\x1c\x26\x0e\x17\x7e\x80\x22\x08\x0d\x59\x3c\x6c\x86\xd0\x4f\x7f\x54\xdb\xe2\xd2\x67\xac\xc2\xd1\x4f\x4c\x42\x50\xca\x07\x12\xeb\x6a\x93\x5f\x13\xfa\x4c\x42\xa4\xa6\x3d\xde\xad\x5c\xae\x7c\x8b\xc5\xa4\x69\xec\x73\x8b\x3b\xc4\xd0\x5f\x09\x4a\x9a\x54\x29\xa4\x16\xc2\xaf\x17\xd1\x54\x35\xaa\x2a\xdd\x35\xd5\x27\xd6\x39\xee\x83\x3c\x8a\xb0\x29\xd5\x65\x97\xfe\x4b\xb9\x14\x58\x18\x71\x7d\x9d\x4d\x0e\xcb\xe2\x24\x45\xfd\xdb\xe8\x35\xf6\x83\x8d\x22\x1d\x02\xec\xd9\x0a\xaa\x7f\x96\xea\x1a\x21\x00\x2b\xc1\x55\x61\xea\xa5\x38\xaf\xc7\x0a\x68\x46\x1a\xc2\xbd\x1a\xef\xe3\xdd\xee\xb1\xa8\xbd\xd7\xda\xdc\x4a\x6c\x14\x09\xed\x4a\x2c\xb4\x5e\xfd\xaa\x4b\x81\xba\xe7\x6f\xd3\x14\xd3\x28\x6e\xf5\xad\xae\xa8\x4b\x57\x67\xd4\x24\x44\xa2\x54\x6d\x95\xed\xf7\x1a\xda\xc8\xea\x6d\x80\xc1\x32\x9a\x03\xf6\x2f\xfd\xc6\xe4\x11\x3a\x9f\xee\x4d\x06\x42\x81\x9d\x2c\x87\x44\xb1\xc0\x83\xbf\xb4\x5f\x1b\x13\x70\xe1\x96\x33\x8c\x44\x76\xa2\x7a\xb5\xbd\xa5\xd1\x64\xa0\x41\x10\x25\x88\x74\x6c\xf7\x8b\xa2\xa9\x87\x99\x13\x0d\x42\x0d\x58\x90\x68\x13\x55\x51\x65\xea\x4a\xc9\x8a\x06\x51\x44\xc1\x6e\xb9\xd9\xe1\x00\xf6\xbe\x77\x61\x0b\x0d\x22\x69\x8d\x12\xd1\xa6\xba\xd0\xe0\xcf\x1c\x99\xd4\xa3\x7d\xf1\xfa\x3e\xe1\xac\xd1\x80\x04\x21\x46\x93\x48\xe5\xdf\x66\xff\xed\xce\x42\x38\x45\x2a\x30\xd6\x77\x17\x5a\x77\x19\x06\xe8\x0f\xaa\xbd\x34\xa0\x3a\xc6\x50\xf8\xdc\x54\x2f\x56\xed\xcb\x1f\x00\x81\xb5\xfa\x17\x51\xbd\xfc\x0e\x17\xff\x67\x26\x02\x9c\xdb\x87\x52\xe4\xf5\x7a\x2a\x67\x5e\x75\xc3\x74\x8c\x8a\x04\xa8\xe3\xd3\x7d\x38\x0e\x2d\x34\xda\xc9\x81\x55\x5b\x25\xf2\x1c\xca\xaa\x73\xef\xa3\x41\xcc\x12\x54\xbc\xb6\x35\x83\x4e\xad\xc7\xa2\xf1\xfd\x18\xa0\x98\xd4\xa1\x72\x3c\x2e\x68\x37\xbd\x4e\x0d\x0d\x12\x1d\x85\x9d\x9b\xd3\xdf\xfd\x5f\xd3\xc4\x46\xf0\x5f\xfa\x0a\x51\x4f\x6b\xa2\x41\x9a\x02\x21\x5d\x36\x7f\x2d\x07\x8e\xff\x3a\x46\x3a\x0d\x78\xa4\xb5\x2f\xdd\x6d\x36\xf7\x56\xd8\x22\xe2\xfe\x64\x5c\x58\x12\xfc\xef\xbd\xa9\x0a\x0d\xb8\xd6\xba\xcb\x99\xb3\xff\xe2\xfd\xfa\x56\x67\xc7\xee\xa7\x8b\xc4\xda\x0b\x56\x35\x9c\x43\xff\x47\xc9\x35\x52\xf7\x71\x61\xfb\x0a\xa2\xac\x25\x0c\x8d\xf1\xdc\x30\x15\x08\xb4\xdf\xaf\xc4\x1b\xb4\xf9\xef\xf6\x0c\x1f\xc8\x36\xd3\x40\x91\x20\xf5\x8d\x32\xd4\xb2\xed\xae\x40\x53\x8d\x65\x72\xb0\xca\x33\x5b\xc8\xf5\x8d\xc8\x5f\x9f\x0b\x8f\x66\xa2\x81\x56\x29\xa2\x1f\x1f\x16\x3f\x47\x0e\x9e\x34\x00\xc2\xf0\xf7\x79\x3f\xa0\x7d\xaf\x4d\x43\x03\xe0\x29\x76\x10\x34\xa8\xe2\x74\x2e\x2a\x98\xbc\x77\xc0\x25\x6e\x4f\xa5\x78\x05\xf4\x48\x40\x40\xad\xb5\xfe\x1c\x45\xf7\x34\x30\x22\x95\xed\x0e\xf4\x7f\xcf\x3f\xbb\x3f\xb5\xaf\x90\x15\x8e\x14\xe5\x65\xdb\x55\xa3\x69\x18\xf0\x04\xbb\x73\x3a\xab\xa4\xc8\xf5\x6e\xf2\xbe\x86\x6d\xca\x18\x77\x40\xc6\xf6\x71\x64\xf5\x65\x8e\x0e\x41\xc3\x36\xbd\x6c\x6f\xf1\x3e\xcb\x2b\x28\x6d\x45\xba\x23\x79\xcf\xac\x84\x34\x24\x49\x8c\x0b\x96\xef\x9e\x5d\x83\x83\x87\x09\x1c\x0d\x49\x6a\x2d\x93\xd6\xaf\x4d\x29\xc6\x1a\x1a\x9f\xad\x8c\x34\x24\x52\x23\x92\x64\x63\xcc\x31\xcb\xc1\xab\xe2\x7c\x54\x8d\x99\x44\x7b\x34\xa4\x5a\x44\xc2\xf3\x7e\xdb\xc0\x3f\x6f\x5f\xcf\xb1\x75\xf7\xf8\x52\x59\x4a\x11\x9a\x74\x5f\x1c\x96\x50\xd6\x99\xc9\xda\xcd\xab\xcd\x2b\x27\x33\x33\x8c\x15\xc7\xc6\xc4\xde\xde\x9a\x6a\xf5\x9f\x46\x8c\xe0\x31\x34\x8c\x75\x88\x6e\x55\x47\x51\xd5\x5e\x5d\xe6\x49\x64\x7a\xd3\x8c\x83\xce\x76\x24\x45\xf9\x96\x0f\xba\x97\x7e\x14\x18\x54\x96\xd7\x0e\xdb\x7b\xf5\xd4\x13\x13\xa6\xda\x37\x16\xce\x99\x7a\x14\x27\x70\xf2\x46\xd5\x62\xfa\x9d\x69\x2c\x11\x51\x8a\xab\x4d\x91\x03\x7a\x0d\xad\xfe\xb3\xce\x6b\xe2\x67\x19\x4f\x12\xa5\x07\x6a\xb5\x9d\xb4\x25\x0d\x39\x18\x8c\x97\x7e\x64\x33\x72\x60\x34\x94\x71\x8a\xf8\x6f\xc8\xeb\x4f\xad\xac\x87\xff\x25\xd1\x3f\xc3\xf0\x5f\xfe\x04\x4a\xa2\xab\xfc\xf9\x45\x54\xb0\xca\xf5\x55\xdc\x4c\x43\xa9\x01\xf3\x7e\x4b\x3e\xb8\xf2\x3c\x1d\x3f\x58\x09\xdc\x72\x0c\x50\x7b\xe0\x16\x64\xfd\x19\x68\xf4\xaf\xfe\x3b\xfe\xd1\x2a\x65\x58\x17\xde\xef\xad\x67\xa9\xbf\x57\x4a\x11\xdc\xd8\x70\x01\x70\x28\x9f\x9d\xc8\x5f\xe7\x92\xa2\xd4\x7d\x06\x48\x84\xbf\xff\xb6\x50\x0d\x82\x1f\x87\xce\x7e\x34\x0a\x02\xd3\xb9\x95\xd8\xc4\x2e\xab\x67\xa1\xe3\x34\x0a\x08\xc3\x54\xba\xee\x51\xaa\xe3\x1b\x19\x05\x60\x09\x5e\x37\x4b\x21\xb6\xdd\x37\x00\x43\x06\xf1\x4d\x73\xb1\x26\xaa\x3d\xad\x71\x2e\x16\xa1\x51\x18\x59\xf7\xd5\x76\x96\x83\xdb\x41\x51\x78\x74\xf4\x33\xc3\x81\xb4\x76\x8f\xec\xa3\x51\x48\x75\x28\x7b\x5d\xd8\x6f\xb9\x65\x89\xe9\x9b\x76\xc5\xba\x4c\x7e\x52\xc8\x42\x04\xc1\xdd\xdd\x2d\x87\x26\x01\x34\x8a\xb8\x44\xe5\x24\x71\x3e\x23\xac\x70\x34\x07\xa2\x48\x19\xdc\x4c\xf2\xe6\x74\x5f\xa8\xd7\xaa\xfb\x94\xfb\xfd\xb5\x78\x45\x69\xbc\x4f\xc2\xc0\x76\x70\x1a\x06\x03\xdb\x87\xbd\x2a\x4e\xa7\xac\x6a\xe3\xea\xfd\xfb\xa0\xc0\x41\x23\x92\xd0\xc0\x95\x7a\xea\x49\x5b\xab\x3d\xc8\x1c\xb8\x00\x8b\x56\x42\xd5\x9e\xb2\x74\x57\x16\xa7\x6b\x09\xf5\xf1\x0d\xa0\x0c\xb0\x8a\xe0\x9f\x69\x7b\x7d\x53\xb7\x11\x1a\x51\x87\x66\x77\xc8\x91\xab\x4a\x0a\x8d\x62\xce\x3d\x2c\xf2\xa9\xf9\xef\x7f\x8f\x43\xf9\x77\x1a\xc5\x32\x40\xf9\xa8\xa3\x28\x0f\x5e\xbd\xb6\x13\xac\xeb\x4e\x21\x25\xd6\x2e\x7d\xd9\xec\xae\x28\x07\x95\xaf\xc9\xaf\x4e\x02\xeb\x90\x77\x23\x6a\x4f\x72\x6e\xff\x68\xcd\xf4\x4b\xeb\xff\xea\xff\xaa\x94\x74\x42\x22\xf8\xde\x8c\x77\xcb\x28\x51\xe0\x1d\xd9\x6e\x2e\x47\xf1\x5e\x39\x49\xba\x5b\x2b\x47\xd9\xbe\x32\x03\xec\x3b\x8d\x52\x69\xb0\xa0\xb9\x85\x5a\x67\x6f\xf6\x22\xd5\xf4\xf2\x78\x08\x48\x76\xca\x9b\xd3\xfe\xa5\xa8\xea\xee\xdb\xb8\x34\x62\x08\xbb\x45\xbe\x8c\x31\x50\xf6\xb7\x52\xb0\x20\x74\xfd\xa8\x27\xa1\x5e\xfb\xd2\x42\xe8\xcf\x2e\xb8\xd5\x10\xe9\xba\xf9\xe1\xa8\x9b\x4f\x23\x21\x22\xe3\x9e\xc6\x57\x10\x47\x57\x84\x4e\xff\x19\x26\xf1\xbf\x86\x8b\x43\x24\x74\xec\xbd\x80\x1f\xb2\x7c\xd1\xe8\xcc\x06\x77\x9d\xd6\x0a\x8d\x24\x09\x25\xf2\x73\x6f\x41\xb5\x7b\xe7\x3a\xaf\x9a\xb2\xb7\xe0\xa5\x91\xd4\x29\x2e\xff\xa5\xcd\x8b\xf4\xb7\xd5\xce\xc6\xa6\xf3\xd1\x55\x24\x8d\x45\x2f\xeb\x62\x67\x73\x80\x11\xaa\x90\x46\x8a\x10\x6a\xd5\x4a\x31\x7b\x7e\x40\xe5\x80\x0f\x96\x24\xa5\x02\xb4\x20\x7c\x3a\x8a\x1c\x6a\x71\x28\x8b\xfd\x14\xb5\xea\x47\x6a\xcb\x91\x6d\x53\xe0\x1c\xd5\xe9\xda\xb9\xe8\x1c\x7b\x46\xd7\xa7\x8c\xa2\x93\x65\xee\x16\xf2\xe2\x64\xa1\x4b\xfe\x2a\x75\x64\xd1\x80\xa2\xbd\x67\x63\xb2\x0a\x8d\x34\x55\xf8\x6a\x3f\x2d\xb6\xdb\xd1\xb2\xa2\x53\x40\x93\x8e\x5a\xcc\x8b\xcf\xd2\x48\x3b\x97\x7d\x47\xc5\xea\x4b\x7a\xd3\x5d\x69\xfc\xf3\xb4\xb2\x9d\x2e\xc4\x95\x63\x31\xb0\x9a\x4c\x49\x88\x62\xdb\x28\xeb\xcc\x15\x1d\xb3\xe3\xae\xc9\x35\xca\xb3\x7c\x28\xef\x33\xb9\x44\x48\x13\x70\x95\xba\xe3\x26\xdf\x66\x87\xfc\xdb\xd9\xff\x40\xd0\x09\xae\x8c\x0f\xd9\xaf\xc9\x46\x03\x20\x91\x6a\x80\xd1\xfd\x6d\xd9\x1c\xfc\x3b\x41\x82\x20\xc2\x52\x9a\x6d\xf5\x7e\xe9\x3d\x9e\x47\x3f\x91\x04\x24\xc5\x85\xfd\x24\x2e\x45\xb9\xc4\xd4\xd3\xab\xe0\xb9\x11\x21\xe1\x94\x75\x0a\x71\xb8\x06\xae\xf3\xb7\xac\x06\x6b\xcb\x31\xed\x61\xf5\x9b\x06\x09\x65\x28\x7c\xab\x52\x34\x55\x7f\x46\x29\x52\x70\x81\x17\xa6\x50\xfb\xb7\xd4\x1f\x8b\x44\x8a\xf6\x5a\x3e\x78\x75\x75\x7e\x47\x96\x6a\xf2\xce\x88\x8c\x12\x12\xaa\xc8\xb7\x98\x1b\xb9\x2b\x9a\x12\x9d\x37\x86\x55\x3c\x9f\x39\x11\x12\x19\x84\x4d\xdb\x59\x7c\xf3\x24\x66\x7a\xb7\x94\x10\x26\x7d\x7e\xb5\x85\x37\xc8\x07\x6d\x76\x4a\x08\x08\xcc\xe4\x96\x0d\x58\xd7\x6e\x7f\x80\xc6\x41\xe8\x26\x57\x1b\x90\x76\x49\xef\x67\x9e\x8a\x9f\x4f\x06\xc2\x02\x82\x71\xee\xb6\xc9\x3b\x93\x31\x4a\x58\x12\x62\x07\xc1\x9d\x6b\x5f\x17\x4e\x3b\x66\x7f\x2e\xe1\x6d\xff\x0e\xf0\x1a\x4e\x7e\x11\x4b\x6d\xf6\x60\xf7\xb1\xc7\xcd\xb6\x5d\xfc\x06\x12\x87\x6e\x58\xcc\x24\x6e\x77\x3f\x40\xbc\xf5\x37\x38\x96\x31\x74\x92\xb0\x0b\xfd\x36\x58\x9f\x48\x12\x5a\x0f\x17\x24\xb0\x3c\x3c\x6c\x9e\x77\x8b\x7b\x1f\x9c\x90\x94\x86\x98\xde\x7c\x93\xf0\x6b\x44\x9d\xf4\xc7\x8d\xc6\x7d\xa6\xb0\x89\x43\xbb\x13\xcd\x57\x27\x29\xe1\x84\xe3\x9a\xff\xb0\x7e\xdc\x3f\x7d\x7b\x5e\xb6\x0b\xb3\xff\x1a\x4e\x53\x80\xc1\x9a\xf2\x45\x64\x39\xe8\x61\x39\x81\x70\x30\x8c\x4d\x2a\xa5\x23\x3b\x52\x4a\x44\x20\xd1\x74\xf0\xa5\xd0\xc7\x36\xef\xa9\xc5\x11\xd7\x2f\xfe\xd0\x8d\x48\x14\x02\x60\x8d\x33\xc6\x71\x1b\xe8\x5a\x75\x53\x40\x11\x29\x1d\x01\xe5\x56\xd4\x62\x4f\x82\xee\x08\x65\x72\xe8\x87\xb7\x6d\xca\x73\x99\x55\xf0\x34\x91\x05\xa4\x44\x31\x41\x1d\x42\xb6\x4d\xa5\x47\xee\x8d\xa3\xe9\xd3\x4d\x6a\x10\xd6\x8e\xfe\xd8\x6e\xaa\xbb\x77\x0b\x43\x7a\xec\x7f\x19\x98\xd8\x6e\x32\xfb\x53\x73\x3c\x15\x7a\x68\x67\x3a\x40\x25\x51\x62\x22\x2a\x7b\x6e\xa1\x53\x21\xd6\x53\xe1\xcf\xd1\xe5\xd2\x80\x50\xac\x5f\x6e\x7e\x3c\xee\x11\x68\x7f\xfd\x9c\x69\xa0\x62\xe3\x94\x82\x7f\x14\xe5\x2b\x94\x0b\x63\x40\xd5\xe2\x0a\xdc\x42\x69\x08\x02\x75\xc2\x96\x47\x10\x79\x9b\xfd\x23\x9e\xd3\x64\x43\x4b\x3a\x4a\x49\x20\x2d\xc8\xde\xcb\xf0\x6f\xf2\x43\xd1\x69\x29\x50\x4a\xc2\x84\x0c\x3c\x5e\xbe\x39\x2f\x9e\x49\x66\x3d\x8a\x18\x29\xa1\xc4\x8a\xf9\x16\xc7\x0b\x92\x82\xb2\xc1\x3c\xa7\xc4\x58\x50\xb2\xa5\x1e\x59\xa5\xd3\xfd\x53\xd9\xe3\xe9\xdb\x21\x0a\x97\x2c\xa1\x14\x9c\xeb\x2f\x8d\x28\x75\x26\xf2\xef\x30\x01\x38\x53\x4a\x03\xce\x9d\xa9\xdb\xf1\xca\x87\x65\x3c\x94\x85\x91\x85\xf7\xe2\x7a\xd5\xee\x29\x75\x36\xdd\x7d\x29\x13\x46\x5b\xbb\x4c\x78\x0d\x07\xca\x8b\x94\x32\xa5\x10\x9a\xd9\xe4\xb6\x7d\x34\x16\x8d\xa5\x34\x61\x01\x6e\x5b\x68\x1b\xb3\x3f\x0f\x3f\x9a\x46\x09\xe2\x4b\x4e\x59\xde\x06\x8b\x0f\x22\xbf\x0c\x70\x68\xe3\xfe\x12\xa5\x29\x89\x62\xd2\xb1\x1a\xb1\xb8\xff\x20\x2e\xc3\xd0\x8e\xf2\x48\xb1\x64\xac\xe1\x8a\x5e\x06\x7f\xa9\x86\x4a\x29\x4f\x6d\x5b\xf7\xa7\xcc\x6a\xf3\xae\x87\x1b\x3f\xe5\x22\x25\xb6\xc7\xa1\xb2\x93\x38\x4e\xa7\x28\x57\x80\xe5\x4d\x2f\x06\x35\x88\x07\xa9\x88\xd2\xb8\xbf\xc1\x5e\x09\x60\x9c\x67\x0e\x52\xa1\xd9\x72\x04\x15\x42\x9b\xc4\xed\xfe\xcf\x9b\x6d\x77\x6e\xb0\x24\xa0\x4c\x15\xa1\x2d\x14\xea\xbe\x26\x45\x65\x60\x9d\xd9\x87\x3a\x85\xab\xe7\x65\x12\x85\x57\x77\x64\x36\xbb\xa0\x52\x05\xa9\x2b\x67\xee\x44\xf5\xba\x9e\x4e\x33\x65\x08\x4e\x8b\xbd\x2f\x2a\xde\xf5\xe6\x0b\xd7\xf7\x57\x13\x4b\xc5\xf9\xb1\xbe\xf5\x32\x59\x94\x6a\x29\xb1\xe7\x25\xb4\xde\xe2\x2d\x69\x5f\x0c\x51\x66\x55\x2f\x7b\x38\x4e\xe4\x43\xff\x41\x1d\xa7\x96\xe0\x77\xc8\x72\xdb\x07\x1b\xa0\xe5\x29\x35\x91\x26\xda\x23\x00\x31\x64\xea\x15\x88\x6e\x3b\x90\x27\x65\x01\x89\xf1\x45\x7f\xcb\xe0\xbd\x5d\x0d\x87\xcd\x06\xca\x82\x34\xb6\x7d\xf0\x32\x7b\x83\xa5\xf0\xd3\x9a\x45\xd4\xfa\xcf\x5b\x16\x2e\x6e\x04\x9d\x3f\x83\x1f\xe2\x14\x6b\x94\x55\xe3\x59\x9c\xea\x5d\x31\x52\xe6\xa1\x8c\x84\x29\x2e\x9b\x95\x2a\xda\x9f\x3e\x36\x97\xa1\x8c\xa4\x01\x2a\xd9\xec\xe1\x94\xd5\x5f\x87\xa5\x42\x6b\xc0\x32\x09\x25\xc7\xb7\x9b\x51\xc3\x11\x33\x77\x7a\x6c\x4e\xce\x29\xd2\x1d\x61\x01\x18\x67\xd2\xb5\xca\x0f\x59\x0e\x50\xfe\xa3\x99\xba\xf3\x52\xc6\x24\x4f\xc8\x50\x6e\xe5\x00\xc3\x32\x34\x8b\x19\xc7\xcd\xca\x77\x3f\x9c\xe2\xfb\x78\x8e\xb0\x24\xb6\x25\xf1\xc7\x68\x12\x65\xb3\x34\x92\xb8\x77\x8f\xea\x2f\x57\xfd\x49\xca\x52\x9e\x12\x1b\x16\x1e\x91\x89\x93\x75\xf5\x5c\x96\x2a\x86\xf8\x83\x73\x2f\xe6\xb7\x14\xe7\x5d\xd6\x79\x33\x51\xc6\x43\x8b\x2e\xed\xc1\x10\x8b\xfb\xa5\xe3\x1b\xd6\xea\x65\x72\xb5\x9c\x09\xc4\x7d\xc9\xf6\x87\xa2\x84\xe0\xe8\x89\xf0\x98\xe1\x1a\x5d\x83\x7a\x71\x60\xe2\xee\x50\x42\xb0\x21\x50\xb7\x99\x61\xfd\xe7\x6c\x91\xf6\x13\x02\x69\xd2\xb8\xc5\x58\x6e\x15\xaa\x8c\xf4\xee\x56\x94\x89\x24\x4c\x2c\xf0\xf1\x8c\x24\xa1\xb5\x5f\x56\x98\x0c\x05\x32\xa8\xb7\xce\x79\xc2\x3b\x30\x5e\xb7\xb2\x29\x93\xcc\x24\x8e\x70\xba\x56\xc5\xb6\x86\xf3\x74\x80\x00\x8c\x02\x7d\xc7\x73\xb0\x13\x32\xa9\x04\xe2\xd7\x51\x47\xa7\x4b\x67\xe6\x60\xc2\xcd\x08\x42\x46\x99\x0a\x25\x52\x8f\xdb\x4d\x76\x54\x10\x65\x2a\xa2\xa1\x5b\xfa\x07\x6e\xc9\x94\x29\x4a\x89\x57\x79\xca\x4e\x80\x28\xac\x71\xed\x86\x41\xc0\x3d\x9c\xfe\xf3\x9d\x8d\x81\x53\x44\xb3\x4a\x1c\x88\x45\x47\x41\xa2\xd9\x50\xc7\xfd\xda\x38\x48\x02\xe4\x5e\xcb\xe6\x72\x57\x94\xab\x37\x28\x2f\xb2\xd0\xfe\x8d\x8d\x43\x16\x62\xcf\xff\xdc\x2e\x79\x28\x78\x3d\x47\xdc\xa0\x71\x18\xf3\x38\xe9\xa4\x85\x96\x85\x86\x81\x27\x24\x8d\xa3\x20\xa0\xee\x81\xdc\x65\x65\x65\x65\x5a\x9f\x6d\xc5\x6b\xf0\xf8\xe3\x88\x09\x24\x3e\xc3\x7f\x1a\xd1\xf5\x51\xe2\x88\x0b\x84\x85\x68\x6d\xea\x1e\xab\x45\x63\x12\x04\xc6\x2d\x79\x8b\xee\x6f\x61\x80\x6a\x10\x7b\x07\x9a\x1a\xe6\x35\x31\x49\x29\xa6\xf2\x45\x0e\xeb\xd3\x79\xdd\xdb\x33\xb5\x87\x0c\x56\x16\x0a\x67\x2a\xf0\x8c\x85\xcc\x1b\xf4\x79\x56\x2f\xf0\xd1\xda\x73\x1d\xf2\xc5\x44\x59\x80\xa0\xc9\x72\xbd\xad\xce\xe3\x45\x26\x26\x60\x2d\x1e\xb0\x14\x27\xba\x85\x37\xa6\x2c\x0a\xac\xa6\xda\xfb\xcf\xee\x6f\xdc\x68\xe8\x8c\x14\xc6\x28\xec\x4f\xa1\x63\x34\x66\x44\x60\xd5\x67\xf5\x73\xb8\xad\xc7\x4c\x48\x6c\x35\xe7\x45\xbd\xce\xad\x3e\xe2\xf8\xf2\x62\x11\xa0\x34\x87\xca\xea\xec\xbf\x90\x57\x13\x6d\xe8\x7e\x14\xea\x10\xdd\x17\x87\x9b\x4c\xe3\xb2\x01\x63\xc2\x6a\x3b\x46\xc6\x9d\xde\xc6\xcd\xe6\xdb\xe3\xd2\x33\x76\x69\x9c\x28\x15\x04\x23\x24\xef\x47\x8e\x34\x38\x16\xfb\xd4\xb7\x45\x23\x8f\xb0\x29\x1f\x8b\xfa\x25\xcb\x0f\xeb\xd3\xd9\x57\xcc\xe2\x94\x18\x54\x34\x58\xb4\x8b\xe2\xc7\xbe\x6c\x7e\x74\xcc\x10\x6a\x79\xff\xc7\xe3\xba\x9b\x36\x22\x08\xbc\x23\x56\xd7\xfd\x9f\x43\x5f\x4e\x2e\x4e\x30\x8d\xcb\xd5\x35\x0d\x68\x32\x4e\xc4\xa1\xd3\x07\x5f\x3b\xef\xe5\xc9\x2d\x95\x11\xc7\x58\xf9\xbe\x79\xab\x87\x4f\x4c\x72\x89\xbd\xbd\x63\x66\xe0\x71\xfa\x19\x11\xa0\x9c\x91\xf3\x03\xc8\x2a\xd0\x4f\x50\xce\x20\x96\x69\xac\x02\x43\x83\x4e\xe3\xd7\xa5\x59\xd8\x92\xeb\x85\xfd\x68\xac\xb4\xd6\xd6\xf3\xea\xec\x8a\x2d\xfe\x88\x0e\x08\x77\xf9\xc6\x23\xfc\x72\xde\x6f\xdd\xe2\x1c\xeb\x40\x44\x0e\x25\xf6\x7d\xbf\x9d\x5c\xa6\x4e\x38\xaa\x3e\xf8\x44\x6d\x71\x6c\x03\x88\xc9\x05\x6a\x69\x35\x34\x3a\x57\x1d\x4f\x2f\x76\xe0\x4b\x5c\xe5\xfd\x58\xcd\xf0\x84\xd5\x4b\xf1\xbe\xb4\x85\x49\xc7\x2e\x77\x03\x40\x50\x2c\xf1\xad\x7e\x3e\xed\xc3\xb4\xfb\xab\x0c\x71\x69\x78\x2f\x85\xaf\xff\xc4\x26\x05\xe9\xa5\x09\x50\x8b\xe3\x33\xbb\x7a\xff\x19\x13\x19\xf7\x99\xdd\x3b\x40\x5d\xdd\x66\x0e\x02\xde\xfd\xe6\x24\x08\x38\x06\xc8\x47\x51\xd5\x28\x48\x5e\xd5\x5f\x37\xb7\xf7\xdd\x2b\x90\x04\xa1\x22\x6c\x10\x4c\xec\x5f\xb3\xe3\x71\x6f\x45\xd6\x47\x7b\x47\x12\x44\x0c\x7b\xb8\x63\x66\xc6\x55\x56\x3f\x9e\x71\x49\x44\x05\xe6\x06\x23\x71\xa1\xbb\xa2\xf4\xe4\xdf\xbf\x14\x10\x27\x91\x8e\x7d\x2d\xda\x16\x44\x66\xa9\xd3\x34\x89\x8c\x40\x62\x4f\x1b\x45\xd8\x6f\x2c\x6e\x07\x82\x6d\x1f\x5d\xa3\x81\xa4\x63\x39\xd8\x5f\xb5\x5e\x6e\x7c\x24\x93\x10\xa6\xd1\xc3\xa9\xdb\xf6\x66\x4b\x89\x09\x49\x74\xd8\xf1\x21\x4e\xe7\x23\x58\xb0\x7b\x39\x59\xda\x12\x14\x84\x6b\x77\x86\x3e\xa7\xfe\x28\x4f\x1a\xdd\x7f\x1a\x48\x4f\xc6\xb3\x73\xd1\xba\x8f\xfc\x36\x00\xfd\xd0\x84\x26\x06\x51\x37\xeb\x7f\x2c\xfd\xe5\x53\x41\x10\x19\x65\xc9\xbd\x18\x49\x7e\x45\x6e\xff\x6f\xd7\xae\xf5\x34\x61\x61\x80\x04\x9e\x6f\x8f\xeb\xe5\xe6\xf9\x71\xbf\xf6\xc5\xf1\x84\xb1\x08\xdd\x81\xf3\xe6\x64\x65\xa4\xdb\x6d\xb8\xea\x8e\xca\x10\x23\x19\x6c\x17\xb2\x61\xaa\x9a\x30\x69\x65\x59\xd1\xd6\x7a\xd9\xd3\xa2\xe6\x5b\x2b\x49\x4c\x12\xe3\x15\xcb\xb2\xba\x16\x06\x6d\x33\xa0\xa7\x2f\x4d\xae\x38\x8e\xa3\xc0\xbe\xd6\xed\xab\xd7\x23\x4a\x92\x38\x61\x96\xc4\xf9\x0b\xc3\x5f\x21\x8f\x70\x55\xfb\x4c\xe2\x94\xdb\x3e\x5e\x71\xd4\x6b\x0d\xe2\x07\x64\x4f\x45\x55\xf7\x95\x9f\x24\x01\x62\x17\xa3\x17\x50\xaf\x0b\xad\x11\xf1\x3f\x79\xa6\x89\x09\x98\xe9\x50\x8d\x93\x83\x69\xc2\xb4\xe3\x44\x6d\x55\x51\x4e\xe7\x6c\x9a\x2a\x94\xb4\xf8\xfa\x65\xb7\x7f\x86\x0a\xca\xb7\xee\xe2\x52\xc3\x10\x3b\x82\x4a\x5c\xbe\xf4\x39\xf9\x38\x27\x82\xcb\x7e\x45\xfc\xd2\x40\xd5\x47\xab\x09\x4f\x49\x94\x78\x2f\x22\x6c\x42\xdd\x88\xba\x6e\xe7\xe6\xbb\x28\xb5\x63\x09\x8e\x4f\x28\x22\x5b\xec\x94\xb9\xb4\x6b\xb9\x3f\x97\xa4\x14\x2f\xf4\xae\x28\x8e\xdd\xdf\x64\xc2\x3a\x27\x09\x7b\x67\x3e\xd9\xf3\x12\x15\x18\xcc\x9b\x8b\x7c\x9d\xab\xa2\x8b\xb7\x12\xc5\xad\x6a\x0c\x88\xaa\x16\xba\x1a\x51\xb8\x69\xbb\x4b\x63\xf9\xa5\x12\x27\xe8\x8b\x5f\x89\x52\x56\xf4\x1a\x23\xac\x7d\xfd\x02\xfb\x52\xf4\xb3\x4e\x19\xe6\xb9\x31\xb7\xe2\xb2\x7b\xc9\xca\xee\x87\x68\x12\x05\x03\x0b\xcc\xf5\xe3\xc2\xad\x15\x3d\xc1\x83\x26\x9a\x29\xc4\x64\x55\xef\xa2\x3c\xed\xca\xae\xf1\x9e\x68\xce\x51\xe2\x44\x68\x8d\x1d\xd9\xeb\x2e\x5b\xa2\xa5\x06\xc7\xb7\x84\xf2\xae\x0f\x31\x67\x39\x00\x34\x81\x34\xc4\x94\x79\x5b\xc3\x1b\xf4\xc4\x19\x3c\x80\xd2\x0c\x98\x15\x6d\xd1\x80\xed\xe4\xa9\x54\x63\x2f\x0b\x9a\x80\xb4\xa5\xd2\x37\x71\xcc\x34\xfa\x1d\x8d\x42\x43\x3f\x4a\x89\xa0\xa3\x4f\xdc\x66\x6f\xdd\x37\x41\x8c\xd1\xbd\xd7\xbf\xba\xc7\x15\x42\x16\xa2\xd4\x8e\xf9\xeb\x47\x9a\x28\xe6\x0e\xab\xf6\x55\x4c\x0b\x60\x69\x90\x18\xf4\xb5\xee\xbb\x25\x03\x58\x2b\x4d\xc3\x40\x62\x2b\xfc\xe9\x79\xb5\x5f\x2f\x37\x43\x5b\x2d\x9a\x46\x61\x80\x2e\xe6\x67\x28\x6d\x7b\xa9\xfb\x3b\xc5\x1a\x10\xe4\xda\x13\x65\xfd\x5e\x9a\x52\x2e\x10\x86\x99\xc3\xfb\xaa\x7e\x41\x9e\x84\x46\xa7\xaf\xe1\xaa\x98\x52\x11\xe1\x04\xea\xbe\xf6\xfe\xcb\xe3\xfe\xbe\x83\x14\xd3\x94\x71\x0e\x0e\xa4\x85\x95\x0a\x7d\x1a\xbf\x14\x29\xe3\x1a\xaf\xed\x5b\x9e\xbd\x41\x59\x89\xe3\x9d\xb3\x0c\x41\x7f\x73\xf8\xed\xd3\x58\x78\x3e\x36\x6e\xcf\xa9\x58\xcf\xb5\x99\xf3\x94\xa5\x69\x9c\x30\xe3\x74\xe4\xbf\x14\x9e\xe9\xd0\xfe\x39\xe6\xbd\x57\x26\xea\x5c\xcc\xee\x6d\x69\x9c\x52\xdd\x0b\xaa\x8d\x92\xd4\xab\x91\xca\xb9\x51\xbd\x42\xee\x16\x22\x4d\x7c\x66\xea\x07\x69\x4b\x8f\x73\xaf\x8e\xe3\x81\x4d\xae\x39\x09\x19\xf2\x6e\x6f\x76\xcb\xfb\xa2\xae\x8b\xf9\x3c\x31\x4d\x12\x86\x1e\x4e\xa6\x28\x0f\xd9\x1b\xb8\x5e\xed\xdf\x46\x4f\x2e\x49\x15\x36\x98\xf6\xbe\x03\xb0\x7c\xc9\x8e\x57\xe4\xb1\xe9\x89\x65\x64\x41\x08\x55\x05\x75\xb5\xef\xc5\xb7\xfd\xaf\x48\xa9\xad\x80\xf8\xd6\xf6\xaa\x9f\xa1\x3c\x49\xbc\x89\xe5\x72\xb5\xa3\xeb\xdc\x14\x9d\xc8\x76\x77\x55\x5c\x04\x8e\x7b\x75\x42\x7f\xc9\x1f\x45\x79\xec\x84\x0f\xfc\x18\x99\x60\x8e\xd7\xae\x4e\xab\xfa\x65\x80\x59\x4b\xb9\x4c\x89\xd5\x87\x11\xa7\x4d\x0e\xce\xef\xce\x1f\x54\x81\x0f\x75\x6e\x9a\xcb\xcc\x02\x9d\x72\x08\x7b\x7f\x39\x5c\xd3\x9f\xda\x14\xb3\x14\x35\xdc\x43\x7e\xe8\x3a\xc2\x29\x37\x0a\x5f\x8e\x7d\x53\x81\x17\x0b\xf1\xc7\x44\x68\x9c\x01\x5d\xdd\x94\x79\xe7\x47\x33\x6c\xad\xa4\x82\x13\x0c\xd6\xb7\xe2\xcd\x35\xc4\x86\x49\x5c\x2a\x23\xc0\xb8\x68\xad\x21\xaf\x33\x73\xe9\xfe\xce\x18\x5c\x53\x78\x37\xf9\xf1\xb2\x85\xe3\x71\xa6\xed\x9f\xca\x44\x20\xb4\xd8\x7e\xc9\xc3\xe5\x47\xd1\x2d\xd6\xa9\x94\x04\x7b\x80\x39\xfc\x72\x11\x80\x7b\x8f\xfe\xc2\x3f\x74\x32\x31\xa4\x51\x22\xf1\x2e\xf9\x57\x98\xa9\x54\xd1\x10\x93\x0b\xf1\x29\xc2\x75\xbc\x78\xa7\x3a\xb0\x98\x81\x36\xab\xc8\x72\x8b\xd4\x99\xfc\x3c\x88\x49\x67\x56\x56\x82\x18\x54\x6a\xbb\x01\x02\x5b\xb4\xbb\xd5\xe2\x61\x8f\x5b\xe9\x76\xff\xb4\x7a\x5e\xae\x3a\x10\x64\x0a\x5c\x61\x51\x65\xf3\xf0\xa5\xfb\x93\x60\xdc\x4d\xd5\x1b\xc8\xc1\x64\x2a\x13\xe5\xe5\xc6\x92\x21\xe6\xdf\x0c\x13\xa4\x30\x58\x72\x9e\xe1\xe0\x84\xc1\xc6\xbf\xc9\x24\x21\xf2\x18\xf2\xe6\xf4\x15\x7b\x66\xdd\xec\x34\x32\xc5\xfd\xfe\x6e\xfd\x7d\xb5\xff\x63\xb5\x78\xde\xff\xbe\x5a\x3d\xad\x1f\xbb\x8b\x32\x10\xe1\xe4\xdc\xfc\xee\xfe\xc2\xc3\x48\x60\x6a\xb3\x7d\xdc\x61\xa2\x67\x0b\xaa\x0f\x43\x66\xf2\x07\xff\xfa\x13\xd0\x18\x5f\xe7\x2f\x79\x51\x65\xfe\x4a\x78\x14\xd9\x97\xc8\xa6\x2a\xc8\xda\xeb\x1b\xd3\x3c\x22\xd6\x78\xcd\x01\x82\xd1\x56\x67\x7c\x56\x22\xb9\x18\x72\x98\x16\xf9\xe5\x5a\x82\x6f\x7e\x81\xe1\x54\x59\xd5\xa8\x0a\xe1\x1f\x37\xcd\x65\x46\x24\x90\xf2\x38\x0a\xb0\x0d\x80\x3b\xa0\x13\x7b\x99\x90\xde\x28\x8f\x89\x85\x49\x57\xde\x9d\x92\xf2\x58\x50\x63\x2b\x6d\x15\xee\x68\x88\x1e\xec\x0e\x4a\x0d\x56\x86\x32\xc3\xf6\xd8\xa0\x6a\xc5\x63\xc3\x3b\xc6\x8f\xe5\xe9\xbb\xaf\xbb\x86\xfa\xa5\x93\x7b\x9c\x84\x31\xea\xa2\x7c\x6d\xbf\xd3\x22\xbe\xfc\x11\x96\x22\xef\xa5\xa9\x60\x2f\xf1\x88\xcd\xc0\xe6\x67\x18\x4f\x98\x4e\x7a\x6d\x5c\xac\x7f\x5f\xdd\xcc\x61\x48\xc8\xd3\x90\x23\x46\xea\x47\x51\xbe\x6e\x4a\x3d\x83\x37\xf8\xe8\xdf\x49\xa0\x39\x3f\x79\x38\x63\x9e\xee\x85\x15\x3f\x9b\xba\xdc\x36\xe0\xb7\x52\xce\x53\xeb\x22\x50\x01\x8a\x76\x6e\xbd\x29\xed\xb8\x2f\xe6\x07\xcb\xc8\xea\xcf\xbd\x4e\x5e\x72\x2e\x64\x84\xf6\x14\xeb\xe5\x66\xb0\x78\x4c\x26\x9d\xd0\xd6\xe3\xc2\x2f\x40\xb7\x50\x8b\xec\x78\x65\x35\x37\x5f\xdd\x9d\xd6\x79\xb9\x62\xa1\xf5\x24\xb4\x48\xbd\x87\xdf\x27\xdf\xa6\xc0\xca\x3a\xff\xc8\x0e\x87\xa1\xb7\x0f\xe5\x3a\xb4\x2a\x01\xc5\x19\x72\x38\xcc\x1b\xde\xb4\xa3\xe4\xe8\x15\x69\xdf\x8f\x88\x7c\xf8\x7c\x66\xe2\x4d\xae\x59\x88\xdd\xa2\x87\xc5\xcf\xee\xbb\xa5\x64\xbe\x06\x6d\xb7\xcc\x5d\x81\x02\xc7\xfe\xb8\xe6\x22\xed\x55\x1a\xa1\x30\x93\x06\x46\x3b\xc2\x96\xe0\x8b\x3c\x87\x81\xe6\x08\xe5\xa0\x25\x46\x3b\x47\x51\xd5\x4f\x65\xf6\x5f\xf8\x92\xbd\x75\xbf\x5a\x04\xc4\x20\xce\xcd\xb6\x71\x17\xba\x38\x5b\x5a\x95\x55\x47\xc3\xcb\x66\x7e\x28\x35\xd8\x55\xc8\x4e\xe7\xa2\xac\x51\x8b\x77\x26\xec\xf8\x53\x18\xb4\x7f\x54\x22\x8a\x62\xeb\x71\x81\x6f\x90\x0b\xf5\x86\x32\x5f\x93\xdf\x28\x22\x6a\xe1\xb2\x5e\x68\x71\xf8\xce\x88\x88\x5a\x6d\x51\x4b\x82\x86\xd2\xc1\x1f\xab\xee\xc3\x69\x8a\x14\x8b\xd5\x66\xbb\x9d\xe2\x45\x3d\x95\xf1\x4a\xe1\x2c\x1a\xb7\x7f\x44\x64\x88\x12\x5e\x5e\x34\x3b\x3b\x2a\xcd\x2a\xaf\xbd\xb0\xb3\x0f\x87\x04\xa1\xcc\x9a\xea\xb4\x89\x18\xc1\x97\xc7\xf2\x5b\x3c\x8e\x59\x10\x6a\x19\xc4\xb5\x9d\xf4\xb6\x97\xdb\x13\x99\xa9\x20\x60\x73\x39\x25\xce\x75\x1b\x4f\xbb\x3f\x53\x12\xe3\xbb\xb9\xc7\xee\xfe\xcd\xd5\xd6\x2a\x28\x0b\xd1\x5c\xd5\x9c\x55\xbd\x3f\xb7\xe1\x7f\xbd\xaf\xfa\x30\x47\xc4\xa1\xc6\x17\x6e\x93\x1f\xb3\x1c\xac\xd4\xf7\x60\xc2\x88\x98\xd8\xb2\x85\xbf\xfd\xf7\xc5\x01\x23\xc2\x89\x5b\xc7\x27\x39\xad\x88\x13\x4e\x02\xf7\x2e\x75\x3c\x63\x2a\x62\xa3\xf1\xca\x5e\x04\x82\x77\x2a\x71\x04\xdb\x0b\xe8\x12\x6a\x91\x6a\x2e\x2d\xb1\x41\x16\xbf\xc6\x4f\x98\x73\x1e\x9a\x1e\xe6\x70\x9b\xbd\x65\x1a\xf2\x8e\xcd\x22\x38\xb7\xbf\xcb\xd6\x51\x3b\x67\x58\x77\x54\xc4\x12\xfd\x2c\x6f\x9a\xba\x76\x2d\x92\x3f\xb1\x45\x1c\x2d\x1c\x42\x24\xb6\x63\xfc\x45\x9c\x9c\xdd\x83\x33\x3e\xe8\x77\x58\x21\x12\x8d\x9a\x4f\xcb\xa1\xce\xf7\xdc\xfd\x11\x10\xa8\xf6\x64\xaf\x50\xe6\xdd\xaa\x2b\x24\x15\x29\xb7\x55\xb0\x43\x1b\xb9\x3e\x17\xb2\xa8\xc7\xf7\x40\xc5\x02\x1b\xb9\x0f\x8b\x9f\xfb\xe7\xd5\xdd\xea\xf9\x79\x71\xef\xa2\x23\x7f\x16\x25\x0c\x12\xdb\x41\x95\x96\xe0\x86\x52\x3b\xd9\x61\xdc\xc2\xf6\x83\x8d\x08\x26\x7d\xbf\x6d\x96\xab\x51\x73\x55\xe8\x38\x49\x5d\x76\x8f\x4e\xc7\x43\xa9\x9f\xfe\x9f\xc1\x7d\x80\x30\x88\x43\x8f\xe0\x2d\x2b\x98\x2c\xe9\x6e\x54\x1b\x89\xc7\x36\xdc\x2e\x33\x78\x83\xd5\xf3\x72\xbc\x58\xcb\x80\x68\x42\xfb\x8d\xb3\x4d\x80\x6d\x8b\xae\x19\x09\x49\x8c\x4e\x2b\x83\x34\x45\xf1\xa5\x0e\xd1\x1a\x8d\xb9\x33\x32\x10\x56\x46\x60\x18\xd2\xce\x36\x11\xfd\x78\x15\x63\x80\x68\x1f\x84\x13\x94\x0b\x83\xd1\x83\x91\x01\xf0\xb8\xe7\xb6\x6c\x3b\x95\xeb\xf9\x6b\x0c\x99\x75\x9e\xbf\x2f\x0e\x56\x28\xe5\xf3\x6a\xac\x0c\x13\xa6\x1d\x21\xf0\x33\x7b\x2e\x2a\xc3\x34\xc2\x81\x58\x1d\x99\xa7\x93\xc8\x50\x50\x04\x1d\xdd\x17\x87\x9b\xa2\x39\xbc\x4c\x62\x34\x19\x2a\x8d\x0b\x4c\x56\x3d\x5b\x7f\xf8\xf2\xae\xb8\x8a\x40\xfc\x58\x1d\x72\x33\xab\xe1\xe2\xe4\xe9\xfd\x8b\x2d\x23\x4e\xb0\xcd\x6a\x41\x4c\xab\xd5\xad\xea\x2a\xfd\x32\xd2\x0c\x55\xff\xb7\xff\x78\xde\x0f\xfc\xd6\xa8\x24\x86\xc9\xd8\x7f\xa8\x03\x35\x7c\x7e\xaf\x58\x12\x21\x31\xef\x79\xb5\x5d\x3d\x7f\x5f\xf9\xdc\xc1\x3a\xba\xfa\x13\xc7\xd4\xf8\xe6\xee\x8d\xf7\x33\x79\x28\x34\x22\x19\x7f\x40\x97\x2e\xca\x24\x14\x68\x56\x75\x12\xbf\x5c\xd7\xa5\xef\x4b\xca\x84\x33\x2f\xec\xe4\x5a\x1d\x18\xd6\xae\xf2\xba\x5b\x76\x64\x4a\x38\x26\x84\x35\x42\x84\xbb\xbf\x8a\xd8\xb8\xba\xf8\x1d\xc0\x56\xbd\x80\x6e\x66\x28\xe4\xf3\x3f\x90\x03\xc5\x62\xa4\x2a\xb2\xbe\xaf\x22\x45\x68\xc9\xf7\x28\x8e\xf1\x24\xca\xcc\x83\x10\x7e\x40\x36\x2c\x3d\x4b\x91\xc4\x5c\x79\xd5\xfe\xf6\xb9\x2d\x8b\xd3\xb9\xc8\x7b\xda\xb3\x1f\xa7\x8d\xd3\x90\xab\x9b\xd3\x54\x01\x92\x4a\x19\x44\xd0\xbf\x9b\xcf\xe8\x82\x3b\x83\xae\x97\x32\xb4\xc6\x06\x77\xcb\xcd\xfa\x31\x24\x34\x1e\xbb\x4a\xcc\x52\x5d\xdc\x47\x55\xc0\x51\x26\xd0\x37\xa7\x30\x5f\x07\xab\xc6\xea\x87\xa4\x89\xa5\x71\x3b\x49\xdd\xf6\x87\x5a\x31\x28\xe7\x32\xea\xc7\x19\x83\x57\xbb\x90\xbf\x2e\xff\x2e\x2e\x83\xed\x4e\x6a\x26\x02\xed\xc5\x1e\x8f\x47\x21\x8b\x72\x98\x8e\x4e\x26\xbc\x96\xd6\xaf\xb2\xc3\xe2\x7d\x15\xd5\x1d\x6e\x38\xfd\x54\xd7\x8a\x62\xe5\x5b\x17\xef\xf9\xa8\xfb\x38\xfa\x75\x1a\x48\xe8\xb8\xc8\xe3\x32\x89\xd4\xc6\x1a\xe9\xad\x76\xcb\x8f\x12\xed\xc9\x9d\x02\x66\x10\x97\xba\xd8\xdd\xb7\x49\xf2\x7e\xb1\x7b\xf2\x27\x83\x98\x60\x5d\x47\x34\xf5\x0b\xe4\xb5\xf3\x7b\xb0\x6b\x78\xea\xc7\x24\x09\x72\x81\x64\x51\xe6\x77\xe2\x04\xba\x5d\xbb\x26\xcf\xd1\x18\x81\x5d\x58\xab\x93\xb3\x7e\x5c\xef\xd6\x8b\xfb\xfd\xcd\xfa\xf6\xb6\xcf\x74\x55\xa0\xac\x98\xce\x63\xf1\x26\xda\x7b\xfc\x39\x2a\x42\x85\x41\x8a\x75\x7a\xac\x15\x3d\x83\x2a\x4a\xfd\xdb\xc4\x8e\x66\x74\xf7\x55\x44\x35\x46\xf7\xb8\xb6\x3a\xba\xde\xb6\x6f\x85\xaa\x48\xc6\x98\x57\x57\xee\x8d\x1a\x6a\xcd\x8c\x16\xc3\x6e\x91\x67\x13\x7a\x9e\x22\x81\xf2\xce\x63\x77\x00\xe3\x27\xa3\x08\x00\x1a\x66\xd5\x1d\x5e\xd6\x1f\xa1\xb1\x41\x5a\x1d\x76\x3b\xce\xc7\x02\x15\x9a\x70\x3a\xfe\x01\xd3\x7b\xa9\x28\x0f\x2c\xfa\x2c\xab\x5f\x4a\xf1\x7e\x0b\x6f\xc3\x4c\x44\xb1\xc0\x04\xfe\x05\x7f\x82\x72\xd5\x2d\x47\x8a\x31\x83\x0f\xf3\xfd\x75\x94\xbb\xa8\x58\x73\xe1\xd0\x16\x12\xea\xd2\x5a\x4e\x8f\x56\x7d\x95\x44\x80\xca\x1a\xd8\x90\x2e\x8e\xc7\x41\x79\xc4\x9f\x25\x89\xad\x36\xd8\x83\xf8\x35\x3a\x7b\x1a\x00\xca\xc9\x59\xab\xf0\x1f\x6d\x98\xde\x4d\x76\x95\x1a\x2b\x4d\xd9\xae\x8d\xab\xbe\xd9\xed\x0f\xf3\xf6\xfd\x77\x65\x01\x91\xe5\x13\x54\xed\xe4\xf1\x8a\x38\x05\xab\x61\x76\x3e\x0a\x05\xd6\xc3\x6e\x37\xae\x95\xa6\x7e\xac\x24\x38\x77\x10\x7e\xf6\xd4\x86\x3a\xa7\x53\x56\x9f\x3e\x64\xe2\x2a\x01\x16\xd7\x7d\xe8\xfd\xa4\xbe\x3d\xdf\xcf\x35\xfc\x94\x30\x91\xf0\x44\xb6\x42\x5b\xda\xf7\x78\x84\x66\x0c\x6d\x30\x97\xcd\xb1\x6e\x4a\x71\x6c\x27\xfb\x87\x5c\xb4\x21\x95\x6e\x00\x53\xf9\x1f\x41\xf2\x93\x6b\xd4\x20\x89\xdd\xa5\xd7\xf9\x18\x10\xa0\x20\xa4\xa1\x95\xe7\xaa\xa1\xb7\x2e\x7b\x76\x56\x66\x7f\xc6\xfd\xa7\x0a\x18\xc5\x57\xbd\x14\xb9\x2e\x4e\x93\x79\x64\x82\xce\x4b\x79\xeb\x02\xa2\x6d\x76\xc0\xcd\xf9\x77\xe8\xd4\x25\x86\xe7\xd3\x81\x50\x96\xa9\xe2\xae\xe4\x49\x94\xf5\xc6\x58\x57\xf0\xcf\xa2\x19\x1d\x68\xeb\x2e\x2d\xb4\xde\x95\xcd\x75\xed\x40\x07\xc0\x49\xe8\xd5\x70\x17\xc7\xe3\xb0\x2c\xa4\x43\x99\x68\xd1\xfb\x89\xf6\xc2\x61\x8b\xfc\xd2\x5e\x6e\x7b\xd9\x02\x33\xab\xff\xdf\x27\x32\x88\xa4\x75\x14\x25\x08\x08\x7a\x1a\x7a\xc9\x52\x1d\x09\x83\x39\x6b\x05\xc7\x63\x07\x7f\xf1\xec\x2b\x1d\x41\x84\x0f\xb1\x8d\x03\xed\xcd\x1e\xf6\xaf\x34\x09\x24\xee\x6e\x5f\x4a\x80\xfc\xe7\x47\x97\xe9\x07\x13\x50\xde\x9d\x4c\x66\x65\xfd\xe2\xd4\x25\xe7\x43\x50\x4d\x92\x34\x25\xae\xc4\xb3\x6d\xca\xf3\xb1\xa9\x46\x70\x53\x4d\xa3\x98\xa5\x03\x41\xd0\x76\x8b\x1f\x96\xc2\x35\x8d\xac\xe5\xd3\x16\xea\xe6\xfc\x70\xff\xd7\xa2\x17\xcd\x34\x89\xac\x3d\x3e\x4a\xde\xf7\xec\x5d\x1d\x53\x13\x49\x2f\xb4\xff\x56\xbc\xb6\x5b\xeb\xcb\xdc\xfb\xa9\x63\xa1\x31\xf0\xda\x66\xc7\x4c\x15\xf9\xcf\xc1\x76\xae\x63\xa5\x15\xed\x4a\x25\x07\x18\x88\x61\x51\x1d\x6b\x82\x51\xfa\xc9\x2f\x00\xe5\x71\xdb\x18\xd3\xd1\xfe\x74\x6c\xac\x77\x98\x53\x80\x7c\x11\x79\x9b\x9f\x7d\x7e\xe3\x93\x20\xc4\x08\x07\x37\x85\x4e\xda\x16\x6b\x0f\xe3\xcb\x4e\xa2\x14\xdb\xa7\xeb\x6a\x69\xab\x53\xe3\x57\x4b\x27\x32\x44\xf9\x81\xac\xb2\xf5\xe0\xc9\x64\x4f\x43\x81\x01\xc3\xf2\x58\xbc\xe7\xcb\xa2\xab\x08\xe8\x34\xb2\x4b\xf0\xc3\xf2\x2e\xab\x3f\x5f\x85\xae\x02\x1a\x9d\x52\x8d\x6a\x1d\xbe\xfc\xb6\x7d\x29\xae\x84\xb9\xdc\x50\xee\xcc\x1c\x1e\xd6\x8f\xeb\x87\x6f\x0f\x1d\x33\xc5\xe5\x57\xfb\xf5\xe3\xfe\xc7\x6a\xed\xaf\x8a\x87\x52\x5b\xef\x3b\x64\x37\x6f\xce\x59\x3e\x30\x7f\xfb\xe0\x1b\x22\x19\x7a\xe1\x13\x94\x36\xc8\x3f\x50\x55\xa5\x9a\xc7\x02\x3b\x85\xe6\x28\x0e\xa3\xc0\x55\xf3\x84\xe2\x2b\xf7\x08\xa3\xde\x8c\xe6\x52\x23\x71\xdc\xad\x07\xfd\xec\xea\x1e\x00\x37\x0c\x6b\x04\x43\xa4\xd9\x42\xeb\x2d\x78\xb3\xbf\x8d\xfc\xf7\xe7\xd9\x87\x96\x24\xe1\x61\x2f\x47\x33\x58\x7c\x3f\x22\xb6\x8c\x39\xc7\x5a\xa5\x80\xef\xa5\xa5\xed\x62\x6f\x04\xb6\xb9\xf8\xa0\x97\xa9\x95\x88\x71\x1b\xac\xa7\x16\x49\x54\x2b\xa9\xb0\xb4\xa7\x2d\xd9\xb2\x53\xcd\x1e\x9f\x40\x87\x6c\xd0\x35\xbd\x17\xb9\xad\xad\x8d\x6b\x3d\xa3\xfb\xab\xa3\x18\xa5\x33\xb2\x3c\xab\x7f\xff\x63\x39\xe4\xc3\xf9\x11\x4c\x63\x17\xe6\x3e\xab\xc1\x82\x1c\x27\x4d\xd1\x3f\x5f\x59\xfb\x1b\xa2\x93\x20\x31\xbd\x07\xc2\x3e\x2f\xf4\xf5\x8a\x3d\xbe\x40\x1e\x61\xd2\xb6\x03\x71\x9d\xb8\x68\x30\xd6\x2f\xdc\x1a\xa5\x8d\xf5\x97\xa9\x36\x81\x8a\x75\xaf\xe0\xea\x9e\xfb\xa7\x61\x8b\x36\x61\x27\xb1\xb7\xda\x7d\x7d\x04\xd0\x4f\x62\xde\xe7\x8d\x6a\x13\x87\x5e\x87\xd8\xf3\x42\x26\x6e\xf7\xd3\x0f\xa4\x1c\xc3\x96\x13\x54\x95\x38\xc0\x4d\x21\x4a\x1d\x8e\x27\xbc\x11\xda\xb7\x47\x1d\x7e\x71\x72\x7d\x8a\x22\xb4\x1f\x29\x60\xe2\xf8\x20\xf2\xa6\x52\x65\x76\xae\x27\x1e\x90\x76\x38\x84\x91\x41\xb0\xbe\x7b\x4f\xba\x1f\x3d\xbc\x2c\x08\x13\xc0\xfb\x84\xc6\x96\x37\xcd\x65\x50\x06\x83\x90\x4b\x64\xd2\x7e\x5d\x3c\xef\xf6\x8f\xab\xdd\x8f\xcd\xf3\xef\x3d\x68\x0a\x48\x40\xb1\xcc\xf5\x08\xef\x7f\x14\xe5\xeb\x60\xf1\x06\x12\x71\x2c\xa0\x55\x8d\x6c\x3e\xd2\xd7\xa4\x40\x93\x10\x51\x57\xfb\x0a\xea\x41\x5f\x61\x88\x09\xf5\x23\x53\x1a\x76\xea\x88\xbb\x62\x55\x77\x4a\xec\x9b\xa6\x3e\x37\x7f\x4d\x80\x97\x42\x9c\xa4\x32\xed\xec\x40\x66\x04\x2c\xdd\xb8\x84\x11\xa4\xd7\x3c\xc2\xaf\x7a\xe4\x57\x31\x19\x96\x84\x08\x61\xda\x42\xae\xbb\x98\xe0\x4a\x78\x6e\x7c\x09\x49\x1a\x21\xc9\xe3\xb6\x67\x75\x40\x22\xb9\xea\xe3\xf2\xc5\x9b\xc8\x8e\xd6\xa7\x65\x29\xaa\x97\xa2\xf1\xd5\x06\x48\x23\x22\x48\x27\x33\xf1\xdd\xf6\xc7\xb1\x92\xf7\x3f\x85\x9c\x90\xca\x04\xad\x9b\xce\x58\xc8\x5e\xef\x36\xfb\x77\xc8\x9e\x46\xbe\x19\x14\x52\x08\x2c\x37\xaa\x4d\xd1\x90\xf2\xb4\x18\x67\x9e\xe3\xdf\xc5\x03\x88\xac\x83\xf9\xce\xa3\xf3\x80\x93\x88\x0f\xf3\xfe\x6e\xff\x06\x91\xc8\x20\xf5\x2c\x14\x14\xcd\x56\x4b\x71\x16\x12\x95\x64\x26\x92\x28\x43\xf5\x44\x0a\x42\x70\x33\x58\xfc\x17\xf9\x87\x78\x20\x90\xa1\x17\xf5\xc2\x2a\xec\xb6\x2b\xdb\x80\x8c\x42\x63\x10\x08\x9e\x6b\x28\x17\x59\xa9\xcb\xe2\x3c\xfa\xf5\x92\x86\xa9\x4b\x03\x6f\x82\x5f\x57\x14\x85\xcf\xbb\xba\x20\x29\x43\x70\xc1\xcd\xfd\x66\xf9\xfb\x6e\xfd\xb0\xda\x7c\xdb\xf5\x67\xb6\xf6\x3e\x56\xc0\xbc\x0d\xec\xbf\x16\x4d\x79\x38\x8a\x81\x6b\xd4\x20\x3f\x02\x29\xac\x5c\x9d\x5d\xd7\x6d\x42\xfe\x09\xb3\x11\xa4\x62\xf8\xdb\xde\x8a\x1a\xbe\x4d\x38\x19\xa0\x03\x49\xdd\xcf\x5a\x3e\x8b\xd9\xcf\xeb\x48\x59\x8a\x91\x77\x13\xd8\x65\xc7\x63\x47\xa0\xf7\x83\x52\xce\x83\xee\xa2\x9e\x8a\xe2\xe8\x2e\xa6\x63\xca\x8c\xbf\x17\x82\x88\x19\x1f\xdf\xfb\xa6\x94\x3f\x16\x6a\xee\xac\x42\x07\x76\x58\x14\x80\x5a\x3e\x83\xa5\x75\xde\x0c\x0b\xa1\x7e\x04\xb7\xf9\x91\xd0\xba\x03\x79\xcc\xaf\xbe\x00\xdc\xd8\xcd\xe2\x57\x56\xb9\x09\xf7\xbb\x77\xaa\xbe\x7a\x47\x41\x31\x61\x3b\x88\xf5\xa6\x7f\xfb\x8c\x32\xde\x5e\xd0\x31\x32\xd7\xb9\x29\xca\xd3\x0c\x55\xc3\x04\x34\xc2\xa5\xd1\x3b\x94\x1e\x17\xe5\xe9\x83\x9d\xc4\x04\x71\x84\x60\x3e\x67\xb9\x89\xd9\xf5\x9c\x96\x92\x09\x94\x40\x54\x40\x91\x1f\x2f\x3b\xa8\xea\xed\x90\xd0\x32\x39\x27\x48\xf0\x9e\x09\x20\xce\x45\xfe\x28\x3f\x90\x7b\x30\x61\x48\x85\xc3\x43\x6c\xcc\x0d\xb2\xd5\xcb\x9e\x0d\x65\xc2\x50\x20\xe8\xcd\x3e\x69\x24\xd2\xe5\x97\x39\xf8\xbb\x89\x20\x46\x38\x76\xa6\x3e\x00\x45\x99\xc8\x84\xbd\x98\x17\x34\xa7\x47\x91\x7b\x24\xaa\x21\x3c\x91\xae\x90\x7b\x5f\x14\xb5\x0f\xac\x67\xd7\x71\x43\x74\x2c\x7b\x93\xd5\x95\xd5\x9b\x47\x99\xfa\xf9\x5b\x4c\xb4\x46\x80\xff\xfe\xd0\xd9\x89\xfb\xef\x65\x81\x95\x19\x3f\x40\x3d\x6a\xe8\xbb\xc3\x31\xe1\xb6\x92\xd1\xe4\x91\xff\x48\x2c\x84\xff\x08\xc2\xce\x9d\x8c\x77\xdf\xd1\xe8\xbf\x38\x21\x11\xf7\x5e\x5e\xf5\x35\xc5\xd8\x24\x54\x1a\xe7\x24\x36\xf0\xc0\xf1\x5f\x94\x24\x12\x4b\xed\xff\x2e\xb2\xfc\x8b\xe8\xb0\x10\x86\xc7\x02\x8b\x16\x87\xec\x0d\xc4\xbb\xb8\x0c\x24\xd9\x8c\x48\x89\x72\x68\xbf\x6e\x4b\xdd\xfd\x9a\xfc\x2a\xc1\x03\xc4\x1d\xdd\x82\x6e\x54\xbd\xb8\xd9\x7e\x70\xdf\x84\xa2\x4c\x8f\xaa\xeb\xf3\x91\x93\x91\x81\x44\x88\xe5\x59\x5c\x36\xd7\xbb\x71\x37\x48\x63\xe7\x16\xf3\x2b\xc4\xf2\xfa\x8b\x96\xdc\x75\xaf\xac\xfa\xa1\x13\xbc\xf7\x07\xc1\x6a\x5b\x6b\x78\x1b\x04\x81\xf3\x33\x4c\x82\x0c\xf9\xc0\xae\x75\x0c\x78\x19\x46\x47\x46\x31\x6b\x4b\xda\xc6\x27\x3f\x20\x1b\x69\xbf\xb9\x21\x5a\x2a\x5c\x4a\xbf\x67\xf0\xee\xbb\x94\xed\x5a\xb7\xea\x0b\xd7\x06\x4c\x82\x78\xc0\xc5\xd3\xf2\xb3\x4e\xa1\x31\x71\x80\xd2\xcc\xdf\x9e\x6f\xfc\x47\x4d\x9a\x62\x1a\x66\xd3\xb5\x0f\x0b\x5e\xc6\xe8\x50\xf6\x66\xa2\xdb\xba\xdd\xcc\x0e\x1f\xf4\x25\x27\x80\x91\x11\xc4\x62\x98\x23\xb1\x20\x70\xd1\xe1\xc1\xa9\x27\x0e\x91\x7a\x2c\x08\x48\xe0\x0b\x91\x0f\x97\x49\x87\x96\x05\x01\xb3\xc4\x8a\xe5\x66\xfd\xf8\xfd\xb9\xfb\x2b\x67\x29\xf5\xe1\xeb\x40\xe7\x83\x05\x81\x12\x58\x08\x15\x55\x95\x1d\x72\xa7\x2b\x3b\xf7\x63\x59\x10\x68\xed\x34\xd0\xdb\x35\x26\x3f\x20\x08\xa8\x18\xcc\xa9\x2b\xcf\x0b\x16\x04\xce\xd2\x55\x36\x17\xd4\x37\xb2\xab\xd3\x28\x24\xe8\x7e\x76\xc8\x19\xe2\x91\xcf\x45\x71\x1c\xda\x6f\xb8\xc3\x51\xa0\x30\x05\xd0\xe2\x52\x3d\x64\x79\x53\x43\xb5\xcb\x8e\xc8\xbe\xba\xf4\x70\x24\x16\x44\x2c\x8e\xac\xe7\x41\x79\xea\x6e\x4b\xa4\x25\x4f\x7a\x1f\xc8\x61\x70\xcf\x02\xd2\xae\x7f\x7d\x9f\xc5\xf2\x27\x70\x2e\xdb\xe9\x3e\xcf\x7f\xf4\x1f\xd6\x04\x97\xfe\x87\x4b\x3b\xff\x46\xc5\x6c\x16\x10\xe0\x34\x1d\xd2\x7a\xac\xb2\x62\x0d\xbf\xea\xbd\xf3\x1d\xdc\xdb\x50\x6f\x72\x45\x60\xb8\x5b\x72\x97\xed\x94\x2a\xca\xcb\xea\x4d\x1c\x9b\xd9\x17\x6c\x36\xa2\x66\x01\xe5\xcc\x50\x5f\xd9\xeb\xc3\xe9\x3e\x0c\x63\x01\x55\x12\xcd\x38\x5c\x6b\xe7\x06\xba\x9b\x4d\x41\x78\xdf\x69\xcb\x93\x73\x7f\x6f\x4f\x4b\x7c\xb4\x3f\x10\x2d\x1e\x7f\x35\x53\x21\x46\xcd\xed\x79\xff\x2e\xd4\xeb\xb9\x68\xcf\xed\xd3\x13\x16\xc4\x84\x31\xe5\xcb\x50\x76\xb3\xee\x0e\xd1\x00\xed\x89\x6e\xb2\x5a\x15\x59\xfe\x7d\xe0\xf5\xc6\x82\x98\x05\xdc\x79\x54\xba\x10\x1b\xbb\x14\xb3\x02\x97\xee\x23\x49\x64\xbd\x59\x51\xf8\xc7\x4f\x58\x77\x2c\xe5\x84\x5f\x31\x92\x3f\xf4\xa5\x62\x01\x97\x21\xb6\xfd\x6b\xa8\xea\x31\xfd\x1b\x8f\x61\x4b\xfc\x98\xbd\x7e\xe8\x08\xf0\xb7\x19\xdb\x46\x16\x88\x80\xe2\x73\xd2\xa2\x16\x4f\x50\x7e\xab\xb4\x3f\xa7\x20\xd6\xad\xec\x3c\xd0\xd5\x9a\x7f\x35\x25\x09\xe2\x61\x85\x69\xba\x25\x4c\x46\xc7\xac\x67\x30\x60\xf4\xf6\x6f\xe1\xa1\x08\x2c\x90\x49\x18\x79\x35\xd2\x7b\x4f\x68\xaa\xee\x8a\x72\x67\xb7\x80\x6e\x9c\xb4\xde\x15\xed\x1c\xed\xda\x9b\x7f\x25\xcb\x61\x81\x92\x69\x6a\xcd\xfc\x32\x65\xd5\x1d\xcf\xc7\xac\x5f\x93\x34\xb5\xeb\xbf\xb5\x22\x7b\xf2\x64\xef\xab\xd4\x86\x05\x40\x52\xd5\x3e\xc1\xb5\x1c\x7a\xdc\xb3\x00\x52\xbb\xb9\x57\x50\x6f\xeb\xe2\x7c\x06\xdd\x27\xcf\x2c\x30\xb1\xc4\x5e\x78\x07\x30\x9b\x28\xa8\xb5\x23\x34\x71\x20\xa4\xf6\xeb\xa7\x16\xe0\x2c\x30\x89\x42\xb2\xfc\x40\x69\xc8\x1b\x3a\xb3\x30\x88\x92\xc0\x2b\x2c\x3e\x43\x8e\x68\x96\xae\x96\xc8\xc2\x80\x10\xed\x8a\xb0\xbb\xe6\x7c\xec\xfe\x1e\x72\xab\xfa\xf9\xf4\xed\xe6\x7e\xbd\xdc\x6f\x17\xf7\xab\xed\xde\x3b\x7f\xed\x57\x8f\xb7\xdd\x40\x09\x88\xf0\xf4\x73\x70\xbd\xdc\xac\x44\x99\x67\xb9\x17\x69\x62\x61\xa8\x14\xe6\x91\xb7\x8b\xf5\xfd\x1f\x7d\x15\xf1\x7e\xfd\xe0\x85\xe0\x59\x18\x9a\x18\x4b\xbc\x76\x1a\x34\x17\x6c\x34\x60\xa1\xe6\x4a\x0b\xbe\x7b\x74\x21\xa5\x56\xad\xd9\xee\x78\xdf\x2a\x28\x6f\xb2\x62\x46\xcc\x9b\x85\x4c\x86\x58\x2c\x47\x76\xcb\xe8\xee\x85\x4c\x02\xe1\x83\xba\xf7\xa3\xf8\x00\x3a\xcc\xc2\x38\x91\x51\xec\x29\xff\xe2\xd8\xce\xc1\x71\xa3\x88\x85\x49\x60\x10\x4c\x81\x51\x9e\x07\xbc\x2e\x0e\xc3\xe9\x38\xfe\xfa\x24\x64\x38\xc3\xa1\x69\xb3\x3c\x71\x92\xdd\xba\x17\x26\x52\x61\xdd\x43\x89\xa3\x7a\x2a\xb2\xbc\xde\xbe\x88\x53\xf6\xd7\xa4\xb6\x58\x98\x46\x12\xc5\x64\x11\x1a\x32\xc1\xdc\xb2\x30\x65\x21\xe6\x44\xa6\x28\xdb\x5d\x76\x9e\x8d\x36\x39\x23\x0f\x22\x5c\x49\x8d\x33\xdb\x1c\x85\xa1\x2c\xe4\x24\xc2\xdd\xbe\x0d\x62\xdb\x67\xe1\xc1\x85\xc3\x82\x1b\x0b\xb9\xd4\x6a\xac\x89\xb0\x7d\xb8\xbf\xde\xd2\xfc\x68\x63\xf9\x21\xe2\x58\x43\xf9\x25\x7b\x83\xdf\x45\x79\x12\x53\xf5\x48\x16\x0a\x69\x3b\x27\x4e\xbe\x5a\xfc\xda\xfd\xfa\x22\xaa\xc9\x20\x15\x59\xff\x85\xaa\x86\xf3\x26\x1f\x49\xb7\xb1\x50\x39\xbf\x03\x67\x39\xbc\x0f\xa3\xd1\x2e\x18\x62\xcc\x8c\x45\x1c\xd5\x94\x59\x9d\x41\xb5\x27\xfe\x37\x41\x68\x6d\xec\x54\x09\x30\x94\x75\xfd\x8b\xfd\x25\x7f\x16\x2d\xb0\x1d\xb0\x78\x58\xfa\x13\x1b\x26\xac\x54\xe1\xea\xe7\xc3\x27\x38\x0a\x3b\x3a\x8a\x88\x45\x99\x5d\x37\x26\x6e\x2e\x5b\xc8\xa7\x1d\x06\x16\x11\x26\x02\x3a\x90\x56\x1d\xfa\x32\xb2\x88\xc6\x56\x48\xfc\x3f\x0d\x94\x17\xd7\xae\x72\x87\x58\x40\xe2\x8e\x0f\xf8\xa3\x14\xe7\x33\x94\xe3\x68\x23\x62\x2c\xc0\x9e\x2a\x5e\x76\x1b\x8d\x7c\xda\x55\x61\x11\x13\x02\xa9\x37\xca\xfb\x82\x09\xab\x1e\x94\x0d\xa4\xaf\x59\x14\x07\xe0\x45\x07\x5d\xb3\xc6\x57\x37\x46\x77\x22\x96\xd6\x3f\x61\x8f\xac\xc1\xee\xc3\x2a\x40\x5c\x5b\xf3\xd6\xff\x85\x22\xd3\x7f\xaf\x21\xbf\x38\x53\xb6\x2d\xa8\xb2\x7b\x07\xa3\x58\x13\x12\xf9\x7c\xf3\x90\xa9\xf1\x94\x8a\x62\x10\x1e\x3d\xf0\x20\x7e\xb5\x21\xd4\x33\x08\x5d\x3d\x41\x89\x4a\x17\x6e\x54\x1a\x28\x2b\xdb\xdf\xd9\xb6\xdb\x3a\xff\xfc\x32\x13\x71\x11\x24\x8e\x3a\x37\x2d\x44\x5b\x18\xc7\x74\xbc\x06\xcb\xc1\x6e\xe4\x26\xff\x5a\x1c\x27\xef\x7a\x24\x08\x8b\x5c\xf0\xb5\x18\xc4\x5d\x03\x52\xd6\x44\x79\xf6\xe3\x25\x37\x12\xcc\xe0\x1c\x43\xad\x69\x0b\xb9\xf5\xbf\x52\x24\x56\x2c\xb3\xb3\x39\x08\x27\xd3\x4d\x24\x90\xc6\x7e\x7e\xda\xe8\x1e\xf4\xe2\x57\x06\xd5\x60\x43\x8c\x24\x49\x55\x9f\xc6\xb4\xa1\x55\x51\x2e\xce\xe7\xa3\xab\x27\xba\xa4\xef\x13\x6a\xf8\xec\xbb\x21\x99\x42\x03\xdb\xbd\xd0\xfa\x1e\x0e\x59\xfd\x2c\x26\xcc\x69\x16\xc9\xc4\xce\x9a\x9f\x3b\xbf\x2d\x45\x32\x15\x81\x83\x42\x7e\xcf\x72\xb8\x88\x52\xaf\xda\x0b\xaa\x60\xe8\x1b\x31\xba\x6f\xb3\xdf\xce\x81\x06\x03\x86\xb9\x4d\xe5\x2c\xc1\xdc\x0d\x51\xed\xec\xf4\x05\x4b\x27\xfb\xac\x06\x52\x0c\x6e\x18\xd0\x18\x6b\xc9\xa6\xa9\x9b\xd2\x12\x0b\xed\xfa\xea\xe9\x95\x6e\x9c\x49\x42\x0c\x5b\x4e\x17\x2b\xcd\xdb\xfd\x9d\xdb\x5a\x7a\xd5\x79\xd0\xf7\x0d\xc4\xd9\x17\x93\x04\x01\xb5\x74\x49\x9c\xb2\xee\x43\xd8\x4c\x9b\x83\x1b\x32\x12\x24\x32\xb0\x7a\x5d\xd9\xc0\xf7\xf3\xb7\xc9\x49\xd3\x04\xcb\x45\x7f\x5f\x3c\x7e\x73\x48\x56\x46\x42\x00\x14\xc0\xc9\x94\x35\xb8\x0d\xfd\x81\x28\x20\x41\xd0\x59\x7b\xda\x1a\xb1\x3c\x3a\x39\x82\xc5\xe3\xd3\x6a\x3b\x39\x7d\xc4\x63\xa4\x3d\xef\xd5\xcb\xeb\x16\x8e\x47\x28\xef\x4f\xf5\x3c\xea\x80\x91\x48\x1b\xef\x35\xb7\x2c\x85\xa9\xe7\x7b\x40\x7e\x30\x50\x04\xf3\xfb\x27\x69\x31\xb4\x73\x85\x38\x46\x88\x0e\x30\xb6\x72\xfa\xe7\x15\x94\xf7\x22\x3f\x2c\x6c\xf5\xfa\xb7\xf1\x5d\xa3\xa9\x85\x4b\x56\xcd\x69\x63\x7e\x40\x76\x78\xf1\xc2\xaf\x8c\x50\x1e\x07\x71\x57\xe1\xbc\x05\xa1\x77\x4d\xe9\xba\xcd\xa1\xff\x15\x2c\x8a\xb1\x0b\x7a\xf3\xed\xff\xfe\xcf\x7f\x90\x91\x84\x3b\x30\x8e\xbf\x6f\x5f\x44\x85\xe6\x48\x7d\x69\x8f\x11\x16\xcb\x44\x7b\x02\x33\xb2\xae\xf6\x9d\x09\x6b\x7b\xd4\x40\x0f\x19\x76\x5b\xff\xe7\x91\x02\x61\x3c\x40\x92\x99\x76\x0a\x35\x1e\x2a\xe8\x0e\xc7\x34\x42\x18\x87\x29\x4a\x05\xda\xca\xbb\x7c\xf0\x70\x62\x45\xb0\xd7\x8d\x52\x5b\x4f\x68\x98\xfd\x5e\x8c\xdf\x09\x92\x04\x3c\xf0\x15\xd7\xbe\x29\xf2\x3a\x52\xb6\x64\x24\x61\xc2\xe7\x79\x5f\xb3\xc3\x0b\x94\xeb\xbc\xaa\x07\x3b\x16\x49\x14\x41\x02\x2c\x06\x4c\x6d\xb2\x61\x79\x32\xdd\x61\x37\x4d\xac\xa9\xe9\x7b\x56\xd7\x50\xae\xf5\xda\x3c\xb6\x7b\xbe\xde\xbd\x40\xbe\xad\x41\x1c\x97\xa2\xd4\xed\xcd\xee\x46\x5c\x71\x45\x9a\x59\x9e\xec\xe4\x27\x41\x48\xc2\x21\x7f\xf0\x41\xd4\xea\x05\x73\xcb\x7d\x17\x2c\x85\xb4\xaf\x00\x84\xa9\x2b\xd7\xfe\x33\xfd\xd7\xdf\xae\x14\x10\xaf\xff\xeb\xbe\x27\x25\x0c\x73\x93\x65\x71\x86\xa3\xf0\x14\x50\x46\xd2\x44\x60\x94\x26\x9b\x0b\x1d\x04\x67\x1f\x96\x8b\x3e\xfc\x02\x2e\x02\xec\xf0\x6f\xb7\xb7\x6e\xd1\xf3\x30\xe0\xf6\x58\x84\xe1\xb4\xa8\x2a\x28\xeb\xd5\x7f\xc2\xc0\x41\xcd\x83\xbf\x8d\xfe\xed\x5e\x12\xc1\x25\x72\x98\xad\x1e\xe8\x13\x94\x4b\xc8\xfb\xd7\x44\x08\x40\x1a\x99\x7a\xda\x75\x7f\x92\xd6\xc4\xb6\xaa\x8b\xb3\x25\x61\xf7\x1b\x0d\x91\x51\x8c\xd0\xce\xce\x41\x65\xef\x3f\x26\xa9\x90\x36\x2e\x3a\x9d\x9a\x3c\xab\x2f\xd3\xae\x32\x23\x92\x5b\x58\xcb\xd9\xaa\x29\xf4\x3c\x0e\x46\xa4\x8c\x91\x32\xb4\xaa\x5f\x6e\xb2\x5a\x74\x7f\x56\x71\xe0\xed\x2f\x31\xcd\xf4\x19\x5f\xb7\xcc\x49\x00\xec\x1c\x64\xd5\xc6\x29\xc9\x87\xee\x88\x8a\x43\xbb\xb5\x1e\x45\xf5\x32\x31\x6d\x60\x44\x09\xa2\x7c\xe8\xea\x2c\x81\x27\x06\x2e\xe3\xca\xe6\xdf\x06\x37\x41\x01\x67\xae\xd3\xb3\x39\xbb\x9a\xf7\xfc\xca\xa7\x25\x60\xf4\x74\xb6\x61\x52\x9f\x22\x13\xe0\x31\x91\xde\x7e\xb6\xfc\xa0\xf8\x41\x4c\xa8\xa4\x2f\x12\x67\xfa\x2a\x84\x27\x26\x8d\x02\x2f\x14\x2e\xca\xcc\xdf\x37\x1a\x2a\x81\xc5\xe5\x9b\xcd\xe3\xb7\xed\xfe\x69\x89\xb8\x93\xf5\x72\xf3\xb8\xfe\x07\xa6\xa5\x7e\x5c\x14\x68\x5b\xba\x28\xc5\xfb\xae\x18\xf2\xf2\x87\x8d\xd6\xee\xfb\x68\xc4\x98\x15\x26\x13\x55\x91\xdf\x34\xc6\x4c\x85\x31\x18\x25\x86\xeb\xb8\x17\x2b\x7d\x82\xd2\x64\xb3\xed\x34\x46\x29\x89\xd1\x98\x27\xcb\xdb\x7d\xb2\xf2\x84\xe6\xd9\x9c\x8f\x52\xb0\xf2\x12\x4e\x89\xd4\x46\x85\x13\x81\x79\x46\x59\x2c\x55\x3c\x4a\xeb\x45\x48\xdb\x8d\x77\xef\xce\xea\x2f\x93\x25\x29\x96\x68\x6d\xc4\xd4\x81\xb7\x3e\x45\xae\x30\xca\x00\x22\x24\x1c\x37\x55\x5d\x9c\x66\xca\x4e\x6e\x5c\x1c\x50\xe1\x7a\x13\xfb\x81\x88\xbb\xff\xf2\x98\xc5\x9a\x75\xde\x57\x98\x11\xff\x4f\x69\x0f\x8d\x95\xb5\x85\xb5\x21\x7d\x9b\x86\x40\x69\xed\x85\xc7\x13\x84\x26\x91\x60\xe0\x2a\xf1\x36\x7a\x74\xdb\xee\x67\x3d\x87\xf6\x63\x46\xf5\x22\xf7\x1d\xce\xe7\x03\x32\x33\xa3\x49\xa2\x49\xe2\x4b\x49\x47\x67\x3a\x3b\x7e\xe3\x68\x4a\x38\xbe\x8f\x77\xab\xd5\xfe\x76\xf5\xdd\xff\x59\xc4\xd2\x38\xb1\xfd\xaf\x27\x35\x3f\x51\x84\x0a\xa8\x7b\x0d\xf6\x27\xd4\x27\x1f\x47\x02\x54\xe8\xc8\x49\xf3\xd5\xce\xbb\xc0\xa3\x6b\xdb\x63\xcc\x4b\x3f\x1d\xc4\x09\x94\x28\x75\x96\xd7\xe5\x64\x43\xa4\x32\x88\xc0\x85\x60\xbb\x62\x69\x81\x77\x37\x17\x8f\x3f\x99\x5c\x90\x0c\xe2\xae\xca\x30\xc3\xe1\x65\x54\x05\x04\xe1\x35\x8f\x9b\xcd\xf3\xb0\xb0\x45\x55\x24\xb0\xf5\x9f\x9d\xb0\xc7\xde\xee\x7c\x9f\x2a\x21\x31\xaa\x68\x12\x59\x22\xad\x38\x40\x6f\xd2\xc8\xa8\x4a\x02\x44\x10\xed\xbe\x8f\x49\x80\xed\x11\xab\xfd\xbd\x77\xae\x4f\xcb\xa2\x38\xea\xe2\x3d\x9f\x5e\x64\xaa\x50\xb3\x0b\x4e\x59\xbd\x98\x00\x59\x26\x71\xea\xf4\x9a\xc0\x9a\xb7\x29\x91\xf7\xf1\xaa\xbb\x11\xb3\x31\x09\x55\x60\xd4\x50\xe5\x7d\xbe\x78\x72\x5d\x9e\xa7\x5a\x31\xcc\x16\x9f\x57\x5f\xd6\xdb\xdd\xf3\x62\xb7\xde\x3c\xee\x97\x1b\x6f\x13\xcb\xa8\xd6\x96\xcb\x54\x1d\x33\x05\x74\x06\x0b\xc9\x28\xb0\x94\x88\xb1\xef\xe4\x87\xfa\xdb\x33\x97\x60\xa8\xc6\x25\x6d\x07\x55\xfd\x1d\x4a\x64\x46\xf8\x3a\x06\x0b\xc2\x04\x37\x35\xd4\xf8\xbe\x6c\xb3\xc3\x10\xa9\xe2\xdc\x1f\xfb\x47\x3b\xee\x9b\x4c\xef\xee\xf8\xae\xcf\x27\xfd\x2c\x20\x1a\xfb\xfd\x67\x71\x19\x97\x0f\x58\x10\xc7\x0e\x47\xdb\x2b\xe4\x7f\xf4\x0d\x93\x73\x9a\x80\x3a\x30\x37\x22\x62\xef\x0b\x25\x8e\x23\xc4\x12\x63\x61\x90\x22\x67\xe8\xef\x9b\xfb\xdb\xd5\xe2\xc1\xef\x21\x2c\x4c\x8d\x7d\x40\x16\x7a\xe0\x5e\x1d\x44\x26\x9a\xab\x7c\x91\x85\x26\xc6\x76\xe4\x5e\x34\xf5\xcb\xfe\xd4\x59\x8e\x31\x16\xa5\xd4\x5a\xf9\x66\x87\x7c\x57\x36\x70\x2c\xde\xe0\xe6\xb2\xdc\x6c\x26\x08\xac\xd1\x4a\xcb\x48\x14\x6a\x27\xe4\xf2\x65\x58\x84\xfc\x73\x7b\x98\x6b\x72\x7b\x37\x61\xda\xb8\x36\x70\x77\x12\x7d\xc1\xa6\x26\xe5\x8c\x11\xa1\xb1\x04\x6d\x30\x97\xb1\x7c\x9b\xf1\x2f\xa5\xd4\xf8\xf2\x3a\x1e\x5e\xe4\xba\x8b\xb4\xa7\x43\x13\x86\x2f\xe2\x33\xa0\xaa\xed\x5c\xd1\xaa\x19\xe8\xac\x4e\x1e\x1e\x95\x02\x4b\x04\x65\x1b\xac\xed\xe5\x1e\xc3\xfe\x7d\x2f\x2c\xcc\x18\x35\xa9\xec\x79\x48\xb7\x70\x8b\xf5\x6c\x71\x98\xb5\x49\x67\x8c\x85\x0c\x65\x4a\x96\xe2\x9c\xd5\xe2\xe8\xfc\x2f\x3f\x52\x7d\xfd\xff\xb4\xe0\xf1\xdf\x15\x33\x9c\x79\x85\x31\x9d\x9e\x3d\x63\x71\xc4\x83\xb0\x23\x98\x74\xdc\x2f\x7f\x94\x18\x1b\xe8\xdb\xec\xba\xb9\x86\x99\x31\x16\xab\xd4\x30\x2f\x37\x54\xbd\xac\x6f\xe7\x33\x6f\x96\x44\xd2\xd9\x73\x16\x15\x60\x5a\xef\xbf\x25\x8d\xa2\xc0\xef\xb1\xce\x51\x4a\x6f\xeb\x46\x43\x5e\x2f\xea\x6b\x7d\xd8\xf6\x03\xd6\x19\xbf\x0d\x9c\x1f\xb2\x2e\x89\x62\x22\x49\x22\x3d\xa2\xc0\x59\x2c\xce\x68\x1e\x0b\xc5\x51\x6b\x1e\xf7\xda\x9b\xe6\x78\x1c\xda\xea\x32\x26\x93\x04\x1d\xe6\xce\x9d\xc0\xfc\xb2\xcb\x09\x98\xe4\x06\xb7\xc7\xdb\xf5\x76\x89\x20\xe3\xa7\xe7\xf5\xf7\xc5\x6e\xb5\x7f\x7a\x5e\x0d\xa2\x3d\x26\x55\x60\x3d\xa3\x6f\x57\x3f\xbb\xbf\x69\xc5\x8c\x6f\x54\x9e\xce\x22\x3b\xe4\x98\x31\xa1\x78\xcd\xf8\x56\x29\x2a\xd0\xcb\x7d\x7f\x26\x1a\x15\x59\xfa\xd8\x6f\x7c\x23\x14\x4f\x03\xd3\x29\xc7\x59\xaa\x9f\x5d\xd1\x46\x3f\x59\x71\x95\xba\x4a\xaa\xc9\xca\xd3\x50\x02\x91\x31\xa5\x08\x42\x3a\xff\xbe\xdd\x3c\x9e\x45\xfd\xb2\x2f\xc5\xfb\x5c\xa8\xc5\x74\x68\x90\x38\xb1\xfa\xf2\x65\xbb\xdf\x6d\xf6\x5f\x17\xbb\xe5\xd7\x7d\x78\x5b\x8a\x43\x97\x79\x30\x88\x23\xd1\x07\x8f\x73\x3c\x09\xc6\x20\x89\x98\xec\x25\xa8\x06\x14\x3a\xc6\x40\xc5\x58\x05\x7f\x6f\x23\x49\xb4\xf7\x69\x06\xae\xbe\x78\x9c\x27\x3d\xfe\xb6\xfb\x98\x56\x08\xa8\x73\x4e\xbd\xf8\xf6\x55\xbb\x62\x4e\xfd\x88\x31\x03\x2c\x45\x09\xac\x6a\x51\x55\x85\xca\xae\x4c\xf5\x58\x1c\x98\x98\xc7\xbd\x8a\xd2\x73\x31\xd0\x48\x1a\x3d\xab\x38\x94\x80\x17\xec\xe1\x8c\xf8\x85\x7e\x53\x68\x53\xed\x65\x81\x99\xbc\x77\xf5\xf8\xb3\x96\xf4\xf8\xad\x8d\x43\xb0\x34\x84\x4e\xc8\xa4\x2f\x2d\x8d\xe7\x42\x1c\x89\x30\x0a\x47\xb6\xf4\xd3\x01\x1a\x02\x7b\xdb\x6d\xa4\xe5\xdc\xec\xe6\xc3\x88\x76\xb4\x67\xd6\x2c\x8c\xc9\x8e\xed\x5d\xea\xe8\x11\x2c\x26\x81\x15\x4e\x5e\x1c\xcf\x90\x2f\x45\xf5\xd2\x1d\x60\x94\x76\xbd\xce\xe6\xdc\x61\xec\xdd\x61\x16\x2b\xe5\x4e\xfb\x63\x00\xae\x88\xe3\x58\xe2\xdb\xe1\xdc\x61\x86\xd6\x54\xb3\xec\x3b\x16\xc7\x89\x4e\x07\xed\xb5\xed\xed\x8f\xd5\x7a\xf2\x8b\xe3\x54\x70\x6b\xf6\xfe\x02\xea\x75\xd0\xda\x9f\xac\xc3\x71\x12\x18\x84\xda\x7f\xcf\xaa\x46\x1c\x97\x2f\xc2\x5b\xb6\xf9\xe3\x2a\x80\xa1\xe0\x8b\x2d\x81\x4d\x4e\x92\x26\x56\x3c\xbc\x43\x2c\x6d\x51\xd8\x6e\xcc\x17\x9b\xdc\x65\x9e\xda\x90\xf3\xbe\x38\x6c\xa1\x7e\xca\x54\x51\x59\x8e\xdd\x34\xbf\x88\x45\x20\x50\xd1\x46\x66\x67\xd0\xe2\xf8\xef\xa2\x7b\x14\x82\x32\xe6\xcc\x61\xee\xb3\xbc\x73\x01\xfe\x67\xf4\x2f\x3f\x20\x8e\xfc\x3d\xf7\x08\xc3\x0f\xaa\x8d\xb1\xe0\xd6\x87\xcd\xc7\x6f\xfb\xab\xca\xd7\x68\x4d\x88\x65\x94\x22\x44\xd0\xaa\x1c\xf8\x2b\x92\x09\x4b\x10\x99\xf0\xb0\xef\x3c\x1a\xda\xbf\x26\x08\xdb\xec\x54\x35\x5d\x00\x93\x4d\xe7\x88\xd4\x21\xf5\x16\x9b\x16\x95\xe6\x97\x87\x58\xe9\x84\x3b\x0e\xd6\x23\xbc\x2f\x8b\xa6\xac\xb0\x53\xd6\x6b\x63\x7c\x52\x66\x8f\x75\x14\x21\x96\x36\x37\x13\x63\x23\x16\x6b\x88\x41\x77\x82\x61\x6d\x64\x36\x88\xf7\x62\x20\x41\x9c\x0e\x60\x46\xb7\x45\xde\x9b\xda\xb2\x18\x84\x35\x5b\x3b\x8b\xa6\x02\xa7\xf8\xd5\x1d\x33\x42\x5a\xd7\x64\xf5\xda\x95\xfe\xfc\x41\x13\x25\xdc\x21\x4a\xb3\x43\xbe\x79\xcf\x6d\x65\x04\xd5\xe2\xec\x90\x24\x48\x35\x13\xdd\x02\xf0\x59\xe4\x9f\x84\x69\x8f\xd3\xb3\x2b\xc0\xae\x58\x95\xe2\xd8\xe5\x56\xfe\x36\x26\xa1\xe0\x98\x34\x7d\x15\xef\x22\xcb\xba\xbf\x6a\xab\x26\x63\xcd\xb5\xf4\x00\x6b\x92\x84\x10\xa3\x01\x11\x6a\x17\x62\x8b\xfe\xa6\x31\xa6\x3f\xaa\xa5\xab\x80\x7b\x8c\xed\x97\xb2\x68\xce\xd5\x50\xed\x8c\x25\x51\xc0\x50\xd1\xac\x86\xaa\xee\xa5\x1b\xfc\xc1\xc8\x86\x42\x6d\x20\x98\xe5\x75\x65\xed\x9c\x47\xbf\x76\x3a\x13\xfb\x90\x39\x89\x88\x44\x49\x52\x3b\x0f\x31\x3e\x9d\x8d\x82\x92\xc8\x68\x2f\xc9\x65\x65\x13\xdb\xbc\xb0\x1a\xd2\xb3\x59\x42\xa5\xd2\xf6\xa9\xdc\x17\x42\xff\xcc\x87\x67\x1b\x2d\xfe\x09\x13\xc6\x5b\xac\x6d\x1b\x69\x69\x0c\x28\x39\x58\xbe\x65\x0a\xa6\xfb\x7a\xc2\x8c\x6d\xd7\x39\x18\xaa\x8b\x02\xc6\xcb\x48\x12\x47\x91\x55\x2b\x79\x83\x72\x5b\x8b\x57\x58\x1c\xe0\xa6\x29\xfd\x9c\x49\xe2\xc4\xa0\x0a\x01\xa2\xce\x7b\xbc\xb9\x35\x3e\x18\xa3\xcd\x07\x10\x59\x96\xc4\x5a\x21\x83\x0e\xeb\xe8\x58\x9b\x1a\x61\x1c\x92\x84\x19\x5f\x81\x76\xc1\x53\x2f\x06\xe7\x87\xa4\xb6\xf8\x70\x2e\xdb\xb8\x68\xd4\x39\x4f\x92\x14\x8c\x63\x64\x6f\xbf\x0e\x27\x79\x92\xa4\x26\x48\x86\x3a\x5e\xfa\x0d\x6d\xf0\xf4\x6e\xb1\xb9\x2f\x0e\xc5\x87\x78\x74\xff\x79\x2e\x91\x72\x93\x9d\xc4\x01\xbe\xa1\xc5\x3d\x7a\xc4\x40\x5f\x44\xfa\x67\x18\x4f\x7a\xf3\x49\x22\x2c\xc0\x40\xf8\xae\xa6\x35\x7d\x76\x8f\x66\x72\xcf\x13\x9d\xa4\x6e\x09\xfd\xfb\xd3\x1f\xcb\xc9\xd1\x34\xe6\x28\x63\x61\xb2\xdc\x33\x3f\xa7\xae\x6d\x93\x4b\x4e\x41\xc5\xaa\x33\xe4\x47\x0a\x93\x77\x6d\x09\x83\xe0\x5f\x7e\x94\xa1\x28\x28\x32\xaa\x1d\x7e\x7f\x5e\x6d\xec\xd3\x41\xb9\x90\x7d\xe4\x6f\x23\x37\x1c\x7a\x9d\xc8\x9b\x2c\x17\xe5\xd8\xcf\xbc\x1d\xa2\x71\xef\x75\xb4\x82\x47\xf8\xe5\x02\xe0\xf1\xd5\x89\xc0\x2e\xcf\x28\x66\xe7\xbe\x7c\xf5\xbc\xef\xc5\xec\x58\x22\xc2\xc8\xf8\x72\xf0\xb2\xdd\x3c\xb7\x59\x87\x98\x49\x04\x07\x2c\x7a\xdc\x2f\x76\xab\xe7\xfd\xe2\xdb\x72\xb7\xde\x3c\x6e\x3b\x16\xbe\xd3\xc5\x5b\x7c\x59\x75\x1f\xd0\x0c\xf7\xae\x17\x51\xbd\x58\x82\xee\x7e\xf2\x66\xc8\x94\xe3\x9b\x81\xd1\x96\x45\xc9\x7f\x94\xd5\xfc\x15\xe9\x4e\x96\x48\x0d\x58\x3e\x7f\xc9\x0e\x2f\x50\xd5\x37\x99\x5f\xac\x13\x15\x04\x96\x1a\x2b\x2e\x77\x45\xe9\xe6\xc3\xca\xfb\xae\xb0\x44\x85\xd6\xd8\x5f\x68\xbd\xae\xaa\x66\x12\x72\x27\x2a\x62\x18\x9b\x7f\xcb\x35\x94\x25\x4e\xe3\xe1\x64\x37\x71\x64\xfc\x5e\x8b\x68\xc5\x7b\xc4\xb7\xb8\xfa\xc1\x47\xd2\x25\x2c\x0d\x23\xeb\x70\x8e\x5a\x9e\xd8\x93\xea\xdf\xbb\x34\x24\xc4\xe2\xcc\xda\x90\x77\xb2\xa8\xa4\x24\xb6\xd9\xbc\x8b\x88\xb7\x75\x69\x17\xdd\xd1\x65\xa7\x24\xed\x84\x15\x7b\xe2\xc0\xf8\x12\x68\xa2\xb1\x79\xab\x8a\xdc\x45\x61\xcf\xa2\x86\x6a\xb2\x53\xa6\x4c\xa6\xc8\x19\xbb\x5d\x6c\x86\xbf\x3c\x8d\xa5\x15\xf4\x43\xeb\x5d\x78\x22\xb7\xdd\x01\xed\xb4\x39\xda\x3b\x70\xf4\xbc\x89\xd9\xe5\x39\x6d\x77\x5a\x5f\xee\xb3\xf2\xf1\x88\xb2\x75\x47\x13\x2d\xb1\x00\xe5\x6c\x45\xab\x33\xa8\xcc\x64\x6a\x2f\xb4\xbe\xcc\xef\x89\x69\x2a\x14\x22\x02\xb0\x2f\x66\xf3\xeb\xf1\x39\x53\x99\x5a\x49\x14\xac\xa8\x5c\x85\xd5\x69\xaa\xad\x3c\xeb\x8b\xa8\x7a\x8e\x66\x18\x0c\x97\xd6\x94\x13\x89\xfd\x62\x7c\x3e\x4e\xaf\x74\x20\x37\xc3\x52\x99\x46\x98\x71\x94\x56\x68\xf0\x6d\x20\x0a\x88\x07\xa5\x1c\x27\x86\xb7\x22\x3b\x5e\xec\x14\x18\x3f\x23\x69\x02\x6e\x35\x09\xb0\x2b\x39\xf5\x9a\x68\x77\xc4\x7f\x52\xb7\xbe\xa4\x8a\xda\x86\x54\x95\xd5\x30\x46\x43\xa5\x3a\x64\x48\x3d\xae\x1a\x59\x65\xfa\xf2\x55\x1c\xdf\xb2\xfc\x80\xa5\xa4\xb7\xae\x7a\x9e\x42\x68\x3d\x0f\x3d\x64\xe7\x0d\xca\xfa\xbe\xa8\xab\x9b\x29\xf2\xc3\x8e\xe7\x41\x12\xe0\xbb\xd1\x06\x20\xcb\xe2\x9c\xc1\xea\x17\xa8\xa6\x2e\xb2\x72\xec\x33\xcb\x78\xc0\x43\x04\xdd\x2d\xa1\x94\x50\x36\xd5\x23\xd4\xef\x45\xe9\x81\x95\x3c\x90\x06\x0f\x3b\xe2\xb3\x98\x98\x86\x33\x1e\x68\xe3\x8d\xda\x50\x34\xd0\xbe\x6b\x57\xc5\x23\x1e\x46\x51\xd8\x29\x02\x8d\x0c\xb8\x18\x0f\x49\x8a\x19\xce\x49\x94\xaf\x0e\x9f\xa0\xbb\x63\x71\x62\x62\x3f\x6d\xda\xdd\xa6\xa9\x07\x4a\x25\xe3\xb5\x86\x87\x3a\x49\x5c\xf0\x21\x3c\xb7\x14\xd9\xde\x7e\xc5\xe4\x91\x8a\x28\xda\x7b\x57\x55\x33\x87\x36\x9d\x2f\xd9\xf0\xc8\x30\xa3\x1d\xe1\xa8\x7c\x83\xbb\xe6\x78\x7c\xc8\xf2\x7a\x1a\x9e\x72\xa2\x38\xb3\xce\xf9\x6f\x90\x37\xb6\xbb\xe3\x34\x5f\x33\x28\xef\xb3\x89\x81\x11\xe3\x94\x4b\xd4\x2c\x76\x00\xee\x02\x57\x5c\xd5\xa6\x3d\xfe\x94\x4c\x11\x62\xd1\xe8\x65\xbe\x6d\xce\xe7\xe3\x64\xaf\xe1\x31\x77\xfc\xf8\x52\xe4\x63\x68\x16\x8f\x55\x1a\x5b\x9d\xe2\xc3\xe1\x08\xb6\x81\x3e\xea\x56\xf3\x24\x4e\x91\x03\x68\x03\xa1\x71\xfb\x82\x27\x32\xc6\x6d\x71\xe5\x39\x78\xed\x9f\x52\xe5\xe2\x6f\xf4\x94\x9d\xcc\xa6\x44\xc5\xf8\x06\x79\x66\x0c\x6c\xcf\x42\xf5\x9a\xcb\xe1\x64\xb1\xe5\xa9\x00\x9c\xa7\xbb\xd5\x76\x68\x8e\xcc\x78\x2a\x23\xc5\x3a\x77\x70\xc7\x13\xda\x76\xd8\xdf\x6e\x98\x12\xa8\xc1\xb5\x58\xee\xd6\xdf\x57\xfb\xfb\xcd\xe2\x71\xbf\x5c\x3c\x2e\x57\xf7\xab\xdb\xfd\xcd\x1f\xfb\xfb\xd5\xe3\xed\xea\x79\xbf\xdd\x2d\x76\x1d\x7e\x84\xa7\x3a\x12\xb6\x7a\x3b\x22\x0e\x7c\x00\x7c\x1e\xdf\xec\x54\x53\xf4\xef\xa8\x5c\xf4\xe2\xfe\xcc\x23\xb0\xce\xa7\xd5\xb6\xc9\xea\xb1\x94\xa8\x1f\x12\x33\x44\xca\xee\x5e\xe0\xe1\xfe\xe1\x16\x4e\x3e\xa4\xe7\x02\x2c\xa4\x27\x2f\x6a\xa8\x7a\x7c\xba\x3b\x2a\x59\x27\xcf\xea\xfd\xb5\xd7\xda\x95\x33\x6a\xc8\xb1\xd4\x37\xca\xda\xb8\x14\x81\x36\x5d\x9f\xd7\x76\x2a\xfa\x76\xce\x20\x58\xe7\xca\x84\x18\xd0\xfd\x80\xc5\xd3\xe6\x87\xdf\x78\x39\x90\x10\xb4\x5f\x6d\x56\xbb\xaf\xdb\xce\x42\x99\x71\x88\xa9\x97\xe5\x7c\x2e\x8a\x7a\xf2\xfc\x4d\x98\x52\x8f\x14\x84\xbc\xde\xdb\xae\x53\x77\xd0\x20\xeb\xe0\x5c\x16\xe7\xa2\x12\xc7\xea\xe6\x82\x2f\xc8\xcb\x48\xd5\x60\x72\xc3\x4d\x94\xa2\x2a\x7f\x66\x8b\x83\x36\x8a\x9a\xdd\xb9\xb9\x21\x09\x74\xd6\xa3\x97\xa5\xc8\x2d\xf3\x13\x95\x52\xa7\xc2\xd4\x8c\x1b\x0a\x71\xea\xfd\x58\xb3\xbc\x5d\x2a\x16\x65\x9d\x0d\x36\xc4\xd1\x4d\x35\x4c\x61\xca\xb4\x39\xc1\x41\x3c\xf6\x35\x7c\x6e\xb8\x52\x89\xaf\x79\x1f\x3d\xce\x10\x5f\x75\x3f\x42\x03\xe2\x72\x96\x25\xe8\x62\x7d\x4d\x67\x1b\xff\x62\x11\xb0\x18\xf7\xb9\x85\xd6\x9b\x32\x3b\x64\x93\xb4\x44\x84\x29\x50\xe5\xa5\x73\xf2\xab\xed\xf6\xe3\xa6\x8e\x88\x02\x8a\x28\xb5\xc5\xef\xce\xcd\x93\x09\x12\xda\xbe\x7e\x6f\x0c\xbe\xf8\x40\x9d\x8e\x09\x42\x35\xb6\x2d\xbf\x3f\x2d\x83\x5f\xdd\x09\x64\x42\x3c\x13\xc0\xda\xb1\x8c\x17\x11\x41\xc3\x18\x69\x21\x06\x6a\xf5\xf2\xbd\xa8\xe1\xb1\x39\xdd\x15\xe5\xd2\xf3\x41\x6f\x2e\xdb\x5c\x9c\xab\x97\xa2\x1e\x71\x32\x27\xdf\x4d\x93\x28\xb6\xd8\xc5\xd3\x7a\xb9\x89\xba\x93\x0b\xa2\x9c\x19\xa9\x7e\x06\xe5\xf8\x20\xe3\xfb\xc5\x82\x58\x07\x8e\xc4\x55\xe4\xab\x5f\x28\xeb\x37\xc4\x44\x09\x46\x34\xf6\x41\x17\x18\x3f\xef\xb7\xab\xfb\xfb\xfd\xe6\xee\xae\x0d\xa9\x97\xcb\xd5\xd3\x6e\xe5\x23\x28\xc1\xd2\x08\x41\x06\x8e\x7c\x82\xe5\xa1\x71\x47\x4a\xc4\x24\x92\x9e\x45\x6a\x61\xf8\x5b\x71\x84\x19\x8a\x23\x13\x71\x4a\x10\xcc\x2e\xb4\xee\x39\x51\xe3\xdf\x1d\x2b\x9e\x88\x09\xff\xee\xa1\xd0\xd6\xf0\x6a\x46\x00\x89\x89\x84\x18\xed\x4a\xef\xed\x0e\x08\x7a\x5c\xa9\xf0\xa3\x24\x43\xa8\x5c\x55\x18\xb4\xa3\xb3\x4d\xd3\x6e\xdb\x15\x69\x48\xa3\xd4\xe9\xd3\x60\xf8\x33\x70\xde\x62\x22\xa5\x96\x38\xd2\x6e\xfa\xa2\x51\x50\x77\x4e\xeb\x5b\x50\xd3\x9f\x90\xd2\x34\xf1\xca\x40\xff\x69\x44\x09\x3f\xb2\x6b\x2b\x9c\x6e\x2c\x07\xee\x49\x36\xed\xea\x3c\xe7\xd3\xcc\x44\xaa\x02\x2b\x80\xf3\xa2\xde\xed\x66\xd9\x7c\x8c\x77\x16\xdc\x58\xa9\x33\x0c\x3d\xe0\x74\xf6\x7d\x4c\x21\x42\x6b\x81\xd3\x7e\x5b\xd1\xd4\x56\xd0\xa9\x3f\xa6\xdc\x8d\x3f\x59\xfb\x59\xe4\x60\x8d\xaf\x43\x24\x29\xb6\x28\xb2\x0a\xf9\x87\x50\x6d\xce\xdd\x16\x26\x84\xd0\xba\xd7\x1d\x7d\xb0\x4b\x8c\x0b\xba\x51\x1b\xc7\x0f\x94\x89\xc1\x3a\x83\xf2\x08\xcb\x6d\x83\x5e\x70\xa6\x39\x76\x43\x84\xc0\x55\xf0\xef\x45\x96\xef\x5e\xe0\x6e\xea\x02\xc6\x84\x04\x89\xed\xa3\x93\xf8\xe5\xa2\x04\x77\x40\x69\xc0\x90\xd8\x7b\xde\x2f\x8b\xf2\x5c\x94\x1e\x00\xf2\xc1\xeb\xa6\x40\x08\xd5\xc9\x38\xa0\x0d\x0a\x1a\x5c\x8c\xdf\x1b\x1d\x59\x41\xba\xd3\xfe\x5d\x61\x29\xaa\x9b\x3e\x9a\x08\xed\x48\x4f\x2e\xaf\x5b\xf6\xce\x02\xe3\x0b\x87\xd0\x3a\x96\x38\x42\x7a\x9b\x29\xb7\x0b\xf6\x28\xe6\xfe\x08\x22\xe2\x4e\x61\x52\x13\xf5\x95\xff\x45\x8e\xad\x9a\xc5\xf1\x68\x67\xfe\x4d\x73\x19\x78\x57\x7d\x08\xb6\x9f\xbf\x11\x46\xc7\x68\x66\x81\xb0\x95\x0e\xf9\xe4\x7e\xa6\x0c\x42\x8a\xe1\xcb\x43\x51\xe4\xbb\x52\x64\xc7\xfe\x80\xc2\xe2\x16\xf2\xc3\xd7\x7a\xe1\x0b\x39\xdf\x6d\x3a\x37\xde\x35\x65\xa0\x02\xc4\xc6\x78\x47\x11\xaf\xa4\xea\x0e\x87\x34\x40\x4a\xd5\xf7\xac\x74\x9e\x4b\x03\x90\xa4\x8c\x88\xb5\xcc\x69\x67\xf7\x1e\xa3\x64\x8b\x29\xda\xc3\xe9\x5c\x5f\xec\x5b\xf4\x54\x14\xc7\x7d\x66\x55\x67\x54\xbb\x7a\x74\x1f\x16\x01\xea\xc5\x23\xb1\xbc\x6f\x2a\xc8\x48\x85\x41\xe4\x54\xa0\x50\x8a\xe2\x53\x18\xa2\x24\x71\x4a\x1d\xb8\xe7\x00\x64\x60\x97\xd8\x1e\x02\xb0\x7a\xfd\xa3\x5a\x94\x24\x92\x20\xd1\xf5\x64\x59\x91\x75\x2f\xc7\xc4\x24\x0d\x28\x6e\x98\x15\xfa\xbe\xdf\x15\x5e\x52\xa1\x3b\x29\x8d\x28\x16\x9f\x01\xa3\xdd\xed\x4b\xf1\x6e\x45\xf7\xfa\xd0\x46\x52\x10\x11\x9a\x33\x6d\x6f\xd5\x50\x7a\x8e\x49\xa6\x2d\xcd\x48\xd9\xa0\x72\xe4\x23\xc4\x64\x1c\x6a\x6c\x9b\x3d\x3d\xaf\x6c\xf1\xe7\x61\xfd\xb8\x5f\xed\xbe\x7a\x1b\x30\x26\x13\x1a\x73\xcb\x9a\x93\xa5\x28\x2f\xa1\x71\xf6\x26\xfe\x78\xca\x64\xe4\x1a\xe9\x37\x8b\xc5\xb7\xab\xd4\x70\x76\xa2\xc9\x94\x4b\x0c\xac\xff\x2c\x31\xf1\xc3\x45\x8a\x8d\xc4\xc5\x76\x8b\x28\xc7\xf5\x72\x33\x7e\xaf\x24\xd7\xc6\xba\xd3\xad\x16\x6d\x08\x7c\xb7\xf2\x45\x20\x29\xa8\x8e\x7a\xdd\x79\x24\x02\xcc\x7d\x59\x3a\x53\xde\x95\x82\x99\x34\xf2\x14\xee\x76\x59\x58\x0e\x42\x68\x3f\x46\x5a\x4e\xec\xaf\x61\xae\x37\x7a\xf8\x32\x31\x03\x11\x8a\x3b\x40\xb9\xb5\xc9\xbe\x21\x55\x20\xb0\x5a\x79\xff\xc7\xcd\xee\x4f\xf1\x01\xfe\x33\xa0\x84\x6b\xd2\xdd\x83\x38\x34\xf0\x5c\x54\x35\x94\xed\x92\x20\x8e\xed\xca\xb0\x03\x71\xfa\x40\xf0\x62\xbe\xe8\x29\x95\xb1\xc9\xa9\x33\xd3\x7c\x6e\xf2\x3c\xcb\x0f\xc3\xa9\xa6\x09\xc5\x9c\x32\x87\xf7\xcd\x79\x96\xec\x3a\x1c\xcc\x12\x11\xfa\x1a\x43\xa9\x2b\xaf\x81\xec\x0f\x43\x8a\x85\x5d\xcf\x38\x7f\x2a\x16\x53\xe9\xcb\x06\xa5\xe0\x5c\x78\x87\xff\xf3\x11\x7c\x13\xed\x3d\xdc\x89\x81\x86\x98\x99\x22\x59\x64\x72\xa7\x41\xa5\x98\x62\xbc\x43\xf6\x94\xfd\x82\x51\xa9\x59\x02\x70\x4c\x6d\xac\xea\xdf\x38\xb8\x93\x26\xb4\xbe\x34\xc2\x37\x26\x87\xac\x38\x3f\x26\xd2\x12\x3a\x51\xdb\x27\x51\x8a\x13\xa0\xd5\xef\x5f\x42\x4b\x48\x43\x35\xde\x30\xd8\x65\xea\xb5\x83\x4b\x48\xc3\x8c\xf2\x3a\x75\xd6\x85\xc1\x6e\x7b\xd7\x66\x25\x4c\x05\xb1\x26\xce\x82\x7a\x5c\x0e\x52\x21\x25\x3c\x9c\x40\xc2\xe7\x7a\xba\x2a\x8c\x63\x6f\xd4\xba\xfa\xa5\x5e\x0e\xcb\xe2\x94\x55\xf9\x43\x73\xbc\xb9\xec\x5e\x8a\xa6\xea\x31\xd1\x2a\x0a\x15\x35\x7d\x9f\xa8\xd1\x59\x3d\xde\xcc\xc6\x67\x8e\x74\x84\x5d\x04\xac\x01\xaf\x1f\x97\xab\xc7\x36\x95\xdd\x8e\xc4\xa9\x99\x8a\xc0\x2a\xcc\x6b\xa8\xea\xb2\xb8\x74\xa5\xc0\xe1\xec\x57\x11\x00\xbe\xd8\x2f\xa2\xba\x17\xf9\xa1\x11\x87\x3f\x59\x46\x14\xa1\x09\x76\x2c\xef\x8b\xc3\xa2\xa9\x5f\x3e\xa3\x1b\x29\x1a\x58\x99\x7d\xbb\xe8\x3e\x43\x5e\x34\xb9\x02\x4c\xc8\x06\x6d\x32\x45\x69\xca\xd3\x81\x70\x58\x55\x5f\xdb\xd8\x30\x45\x63\x8e\x3b\x67\x56\x3d\x45\xdb\xaf\x63\x04\xdb\xe4\x7b\x19\x51\x98\x53\xde\xae\x76\x1d\x86\x43\x31\x9d\x62\x95\xf6\x02\xf5\x22\x2f\xda\x30\xfc\x6e\xbc\x0c\xab\x38\x50\x88\x4f\x68\x77\x07\xb4\x26\x2a\x8a\xe3\xe0\xad\x55\x71\x48\xac\xe9\x90\xb8\x8c\xef\x62\x1c\xa6\x48\xdd\xb0\xbf\xd3\x13\x22\x8e\xdd\x79\x19\xc3\x0a\xc0\x51\x54\xd6\x71\x1c\x61\x31\xee\x60\x22\xac\xd8\xe2\x12\xca\x1a\x8d\xd6\x6f\xb1\x6e\x36\x59\x21\x55\x22\x15\x2e\xf6\xaa\xc8\x72\x2c\x6d\xeb\x55\xad\xfc\x39\xd2\x80\x62\x8d\xb9\xcd\x86\xbc\xa5\xd4\x8c\x20\x17\x53\x69\x68\xad\xcd\x2b\x64\xae\x98\x6e\xf7\x56\x3c\x96\xc4\xc5\xb5\xb6\x60\x28\x4a\x3d\x50\xa5\x65\x8a\x27\x61\xe4\x8d\x93\xda\x33\xdf\xaf\x3e\x7d\x02\x3c\xd5\xd2\xc9\x52\x3f\x95\xc5\x19\xca\xfa\xd2\xe7\xe1\xd3\x9a\x8e\xe2\xdc\x3e\x5a\xdc\x22\xf2\xff\x0c\xbe\x55\x46\x9e\x41\xbb\x38\x1e\xb7\x2f\xfd\x86\xae\xb8\x0a\xf1\x19\x6f\xdb\x45\xb6\xba\x03\x78\x86\xec\x24\x9b\xb2\x9a\x12\x52\x95\x20\x0c\x03\xb2\xf7\x3f\x51\xfd\xfe\x9c\x46\xe1\x4e\x26\xa9\xf0\x8c\x90\xa7\xde\x9e\x7b\x0e\x9e\x30\xf9\x8d\x2a\xd4\x94\x77\x6d\xa5\x79\x17\xf8\xab\x6f\x53\x69\x1a\x76\x12\x58\x59\x7e\xc0\xf7\x62\xe3\x7b\xb7\x4a\x81\x95\x57\xad\x5e\x8a\x77\xd9\x5c\x86\x8b\xb0\xd2\xc4\x96\x2d\x85\xb6\x72\x66\x9f\x86\x63\x4a\xeb\x08\x4b\x12\x4e\xde\x0c\x39\xc1\xb3\xf4\x92\xfe\x23\x40\x88\x85\x0f\x94\x1d\x7b\x53\x01\xa5\xaa\x43\x18\xaf\xea\x97\x36\xc1\xce\xde\x40\x67\x83\x54\x50\x41\x9c\xa0\x44\xca\xe2\x03\xbd\x92\xc9\x8d\x83\x58\x58\x27\xdf\xe2\xe0\xb6\x12\x0b\x40\x10\xe7\xa5\xa7\xb0\x5c\x83\x83\x47\xb3\x1e\x78\x88\xa5\xd8\xac\x7a\x76\x7b\xe4\xb0\xdb\xda\xbf\xdf\x00\x0a\x29\xa0\xab\xe7\x65\x92\x24\xb7\x70\x2a\x3e\x92\x4c\xb8\x9e\xf0\x60\xac\x12\x9b\xb3\x94\x70\x5a\xfc\xee\xa0\x61\xd6\x57\xbf\xcd\x6d\x6c\xf6\x3c\x99\xa2\x46\x70\xdc\x4e\x31\x18\xc7\x55\x60\xbc\xc0\x18\xa1\x3d\x86\xa1\x7d\x98\x3d\x89\x2f\x2b\x3a\x97\x9b\xf1\x07\x54\x80\xf4\x94\x76\x45\x70\x77\xed\xe6\xf2\x7b\xdf\x1d\x9d\xdc\x63\x03\x80\x76\x1a\x67\x6c\xab\xaf\x67\xee\x93\x1d\xa8\x83\x38\x91\x41\x97\x37\xb9\xd4\x74\x51\x3d\xb5\x1f\x5b\x8c\x14\x81\xff\xf9\xaf\xbf\x75\x55\xa5\x4f\xc0\xc3\xa3\x27\xa5\x03\x27\x0b\x94\xf5\xdc\xc1\xbb\xc6\x9b\xd7\x30\x1d\x68\x81\x8a\x96\xbf\x67\xf9\xa1\xda\x5d\xa9\x19\x31\x1d\x4a\xce\x44\xd7\x06\xab\xad\x03\x57\xb9\x2b\x6c\x4e\xf3\x89\x42\x30\xd3\x21\x24\x49\xd0\xe3\xec\xa6\x9b\x94\x8e\x42\x40\x8c\x83\xfd\xe5\x0e\x03\x33\xea\xae\xe9\xc8\x30\x57\x01\xa9\x7b\x92\xd8\x07\x75\x0b\x4d\x89\x2d\x0b\x6f\x0b\x95\x89\xe3\xcf\xa1\x2d\x14\xb3\x4a\x8c\x6d\xe8\x65\x6b\x19\x5f\xb3\xaa\x2e\xca\x8b\x43\x64\x8c\x9f\x08\x63\x56\xb8\x78\xb5\xfb\xd9\xf3\x2d\xbb\x63\x0a\x63\x2d\x8f\x1c\x5a\xda\xdf\xd6\x05\x33\xd8\x48\xf1\xb8\x81\xe5\x57\xab\xda\x12\x75\x07\x95\x45\x05\xd8\xde\x9f\x8d\x53\xad\x87\x94\x7f\xc4\xa4\x7f\x90\x83\xff\x8d\xfe\x35\x78\xa9\x34\x33\x34\xe6\x73\xc5\xe8\xf5\xd3\xdd\x56\x67\x25\xa8\xf6\xa7\x5d\x95\xa4\x75\x1c\x07\xf8\xbb\x7e\x74\x4f\x20\x61\x4a\x58\x19\x58\xcc\x42\xe6\xea\x63\x3a\x15\x09\x0b\xd1\x5b\xa5\xdd\xe0\x2e\xfb\x87\xe6\x8f\x6c\xff\x58\xf8\xfa\x8d\x16\x1c\xd2\xc8\x99\x03\xa2\xea\xc7\x5f\xc0\xba\xbb\x8f\x4a\x62\xc0\x99\x5d\xfc\x75\x32\xca\x04\x38\x3d\x75\xbc\x19\x7f\x41\x12\x61\xde\xeb\x97\xa9\x52\x4c\x0a\x1f\x5a\x72\x2b\x3a\x6c\x9f\x08\x7a\x0c\xd4\x50\x3a\x3a\xbb\x99\xc2\xce\xb4\xe4\xd6\xde\xc1\x42\x2a\x9d\xd6\x5f\x56\xe4\xd8\xc0\x1c\x5e\x65\x07\xd1\xd4\x52\x86\x78\x8f\xd1\xad\x63\x50\x18\xf5\x7b\xa2\xa7\x6f\x7f\xb0\x3d\x6a\x09\xb6\xff\x83\x64\xa5\xf6\x59\x5b\x65\xa7\x99\x26\x94\x56\x49\x88\x7b\xfb\x56\x95\xa2\x67\x2b\x6b\xa5\x62\x14\xee\xdc\xd6\x65\x91\x1f\xbe\x8a\x1e\x5f\xaa\x95\x09\x23\xc7\x46\x5b\x4c\xe1\xb4\x5a\x33\x7b\xf0\x64\x85\x9f\x1e\x8b\x7a\x0b\xf5\x3a\x5f\x9c\xbb\xf9\x03\xc4\x5a\x43\xc3\xdb\xc3\xe1\xe4\x34\x53\x9f\xca\xe2\xdf\xa0\xae\x81\x9d\x1f\xa7\x63\x1a\x92\x54\xba\x77\x06\x45\x29\x3b\xd7\x8f\xc9\xc3\x32\x89\x95\x00\x76\xdc\x5a\x37\xf7\x27\x57\x6d\xda\xb8\xce\x26\x82\x77\x45\x51\x4b\x71\x3c\x22\x1f\x73\x3c\x0c\x02\xa6\x70\xaf\xcd\xaa\xae\x3b\xf6\xcd\x42\x06\xbc\x34\xb7\xf5\xd7\x1a\x12\x29\x52\xff\x59\x19\x87\x2e\xb4\x5b\xe4\x97\x95\x35\xb9\x9d\x28\xc5\xfa\xa1\x3a\x35\x9e\xaf\x5c\x9c\xc6\x70\x86\xd9\x55\x0c\x02\xc7\x26\xc5\x0d\x7f\xa1\xdf\xb2\xaa\x28\xab\x51\x35\x11\x48\x6a\x7d\xc1\x8e\xe7\x3b\x80\x9b\x73\xf7\x67\x63\xfb\xee\x67\x71\xe9\xe3\xd0\x36\x9e\xc1\x15\xde\x7f\xf7\x9f\xbf\x97\x40\x05\x89\xad\x5a\xb9\xe3\x02\xfb\x7c\xdb\x1f\x97\x84\xda\x06\x3f\xfc\xd2\xf0\x56\xbd\x14\xe7\x1f\x22\xab\x41\x87\x7f\x80\xe8\x60\x75\xc0\xc0\x2a\xc4\x9f\x4b\x50\x59\x05\xdf\xf2\x8e\xd9\x0e\x29\xb1\x3c\x9e\xe7\xac\xca\x5e\x07\x06\x57\x0c\x38\xd7\x58\xf4\x44\x77\xd0\xa2\x4b\x72\x81\x0b\x89\x11\xc7\xa9\xa9\xea\xdf\x2f\x6a\x3c\x33\x80\x83\xc4\xf3\xad\x9f\x7c\x53\x05\x04\x89\xb1\x3c\x5e\x18\xf3\x20\xb2\xbc\x86\x7c\xd0\x20\x00\x19\x58\xfd\x83\xac\x03\x74\x3c\x41\x79\x12\x53\xa7\x15\x06\x8a\x06\xc2\xd8\x94\xbd\xdf\x1e\xe7\x85\x60\x19\xa8\x04\x50\xfc\xea\x08\xa6\x8e\xa2\xc9\x54\x50\xa9\xc6\x85\x72\x0f\x15\xb2\x54\x0e\x50\x6e\xff\x53\x4e\xcc\x91\xff\x36\xfe\x88\xb2\x2a\x71\x67\x71\x6e\xfc\x95\xeb\x28\xe5\x1e\xd5\xdf\xc6\x36\xcf\x57\xba\x03\xa0\xb9\x92\xae\x6c\x7e\x2f\x72\x3d\xeb\xeb\xce\x40\x2b\xc1\xbc\x69\xd6\x07\x5b\x2a\x40\x62\xe5\x56\x6b\xcf\x53\xec\x83\x4e\x13\xd0\x20\xe8\x0d\x9c\xdb\x4b\x99\x27\xcc\x5c\x51\xba\xae\x15\x51\x99\x09\x12\xab\xa8\x85\xd0\xe4\xb5\x41\x37\x48\x98\x14\x31\x4c\x18\xa5\xa1\x0f\xfa\xce\x70\x6d\xcc\xe4\x87\x25\xda\xd9\x5a\xa0\x88\x7d\x76\x78\xa9\xa3\x5b\x10\xb6\x59\x3b\x88\x2e\x4c\x08\xa9\x03\xb3\x94\x7a\x29\xce\x03\x01\x7d\x66\x22\x9a\x60\x3f\xf8\x50\xd4\xe2\xd5\x4f\x1b\x43\x12\x2b\xaf\x56\x65\x87\xfc\x2a\x42\x1e\x5f\x2c\xe1\x34\xb5\x0a\x6e\xe7\x63\x71\xe9\x4f\x4c\x03\xaa\xfa\xb2\xdb\xfe\x5c\xbc\x0f\x8e\x25\x02\xf7\xda\x55\xfd\x52\x0a\x63\x8e\xb0\x7f\x23\xb2\x3b\x98\x42\xd2\x6f\x55\xdb\x4b\x5e\xbf\x40\x95\xfd\x37\xcb\x0f\xb3\x4c\x14\x43\x4d\x20\xc9\x40\xda\xcb\xbf\x4a\x86\x45\x1a\xbf\xa5\xcd\xde\x6e\x4b\xf1\xfe\x30\xe1\x73\x19\x26\x13\xbc\xf4\x93\xf8\xb5\x14\xe7\x5e\x5e\xc0\x30\x6d\xa2\xce\x8d\xfb\x2e\xab\x94\x38\x8e\xab\xe8\x26\x96\x8c\xa4\x83\xd9\x69\x1d\xdb\xef\x8a\x72\xdb\xc6\x24\xae\xa6\xee\x07\x27\x91\x8c\x9c\x60\xc7\xff\xd6\x44\x35\x89\xb4\xa9\xea\x5e\x36\x65\xfe\x49\x0f\xc5\xa4\x51\x82\x21\xc6\xee\xa6\xec\x79\x49\x26\x8d\x53\x99\x74\x1b\xc9\x33\xbc\x41\x59\xc1\x90\x86\xeb\xc7\x25\x11\x2e\x74\x96\xf4\xbe\xce\x1d\xde\x77\x70\x26\x2e\x14\x25\x13\x86\xdf\x4e\xe4\x87\x4c\x1e\x61\x51\x55\x50\xcf\x19\x88\xf9\xcf\x4a\x8d\x46\x53\x36\xb2\xc5\x20\xf8\x0a\x08\xe1\x87\x42\x8c\x93\xc6\x6d\xae\x8f\x9d\x70\x28\x33\x22\x92\x41\xd0\x8b\x84\xcc\xca\xdf\xb6\xa3\xac\x93\x40\x0e\xef\x16\xf9\x39\x99\x2c\x32\x14\x28\x69\x71\x73\x69\x97\x5d\xf5\x0a\xe5\x48\x3b\xd2\x48\x08\xd0\x26\x77\x7f\x00\x74\x9f\x1e\x7d\x58\xa9\x44\xc6\xbe\x34\x01\x43\x79\x12\x37\x40\x33\x82\x33\xce\xd7\x71\x5c\xfe\xe4\xb8\x9f\xd7\xe8\x8f\x3e\x36\x30\x5a\x12\xe2\xaa\x03\x9b\x33\xa0\x64\xea\xba\x8b\x5f\x8c\x36\xd6\xe6\x1c\x15\x88\x51\xc5\xff\x63\xbc\xbb\x81\x38\x40\x20\x8e\x15\x85\x68\x2a\xfd\x54\x16\xbf\x2e\xd3\xb4\xc4\xb4\x4b\x3e\x82\xea\xa5\xee\x45\x5d\x26\x96\x83\xcc\x98\x00\x12\x39\xe2\x95\x7e\x04\x82\x1d\x43\x35\xfd\xc7\x49\xea\x88\xda\xa8\x63\x7d\x23\xaa\x4c\x21\x30\xf6\x4f\xea\xb1\xff\x7f\x6c\x37\x63\x58\x8c\xe5\x20\x94\x58\x5a\x0e\x64\x9f\xe3\x20\x88\x09\x4a\xc0\xf8\x62\xf7\x3a\xaf\xea\xac\x6e\xea\x19\x3f\x88\xe1\x1d\x68\x3f\x08\xce\x54\xb8\x9f\xe1\x73\xf6\xaf\x83\xe1\x60\xa3\x81\x6d\xdf\x5e\xfd\x4b\xd0\xaf\x38\x08\x54\x8a\x64\x89\xbf\x67\xf9\xe1\xbf\x2f\xd9\x78\x21\x8f\x83\x28\x48\x3c\xfc\xe3\xbe\x78\x87\xaa\x6e\x63\x0d\xdb\x31\xd7\xbf\xda\x57\xb2\xf3\xb9\x8c\x83\x28\x16\xca\xfb\x1f\x7a\x5d\xa3\x6d\x73\xba\xb9\x58\xcd\x89\xb9\xc5\x3c\x0e\x48\xa0\x19\x52\x38\x36\xdf\x1e\x77\x7f\xec\x97\x8b\x87\xa7\xc5\xfa\xcb\xe3\x7e\xfb\x75\xf1\xbc\xf2\x67\x26\x5c\xd0\x2e\x72\xab\x3a\x84\x70\x1c\x90\x76\x21\xb1\x31\xc4\x53\x09\x1d\x07\xa4\x3d\xa0\x23\x7f\x0b\x77\x85\x7b\x2b\x50\x90\x64\xc6\x12\x7b\x72\x4b\x68\x6c\x2d\x71\x3d\x75\x76\xc4\x9a\x8d\x03\xaa\xe3\xce\x95\xf6\x35\x3b\x1e\x9f\xc5\xff\xe2\xf1\xd0\x9d\x24\xd5\xa1\x5f\xef\xaf\x3c\x39\xe2\x80\x25\x29\xbe\x04\xa5\x8f\x0d\xe3\x20\x26\x11\x8a\xa8\xfe\x5e\xff\xfa\xd3\x56\x51\x1c\xc4\x86\x20\x5a\x57\x41\x5e\x37\x93\x08\x25\x0e\x12\x4a\xa4\x55\x0b\x17\x7a\x8f\x77\x75\x6f\xbb\xb3\xfb\xc2\xec\x9b\x0a\xca\xfd\x79\x4a\xe0\xf1\x9f\x4c\x38\x46\x0a\xcf\xcf\x43\x16\x7c\x1c\xa4\x92\x58\x68\x2a\x56\x64\x5f\x04\x2a\x39\xb8\x63\x1c\x04\x77\x95\xc1\xd7\x2c\x3f\xac\xce\x85\x7a\xb9\x6d\x86\xbd\xe6\x38\xe0\x06\x30\x03\xd9\xac\x36\x9f\xa0\x1d\xe2\x40\x1a\x4b\xdf\xd8\x41\x55\x93\xc9\xb5\xe9\xc4\x72\x9e\xdb\xa4\xbb\x1c\x4a\x87\xc4\x81\x56\x12\x91\x2d\x43\xb5\xa9\x38\xd0\x86\x61\xef\xe6\xd7\xa9\xf4\x7f\x82\x90\x52\xcc\xdb\x30\x2f\xb8\x81\xff\x3e\x16\x47\x1f\x99\xc5\x81\x09\x00\x6b\x36\xd8\x03\xee\x44\x14\xfe\x52\x1f\x3f\x0e\x4c\x04\x56\xc4\xa7\xb9\x3c\xdd\xec\x76\x8b\x83\xc8\xf2\xaa\x1e\xc4\x46\x71\x60\x62\xa5\xb9\x9b\xb6\x8e\x2b\x32\x2e\x42\x4f\xde\x1e\x23\x12\xec\x93\x7e\x2f\x32\x05\xaa\x0b\xf6\xe3\xc0\xe8\x10\x7f\xd9\xd7\xe2\x3c\xfc\x7b\x18\x10\xab\xdd\xb8\xcf\xe1\xfd\x09\x7a\x09\xf0\x7f\x46\xbe\xe1\x36\xf9\x67\xf4\x7d\x61\x10\x5b\xba\x62\xef\x51\xb0\x3f\x8a\xaa\xde\xbf\xa1\x18\x78\x37\x48\x12\xf7\x3b\xc7\x4d\xcf\x38\x0c\x23\xcb\xc8\x44\xd7\xc1\xeb\x1e\x4f\x1c\x86\xdc\xc6\xe5\xbd\x2e\xe2\xf7\x36\x32\xc8\xea\xcb\x4d\xe1\x6b\x94\x71\x18\x49\x40\x20\xac\x1e\xda\x10\xc4\x61\xa4\x0c\xf6\xf2\xce\x9d\x0f\xf2\x48\xa0\x6b\x12\x2d\xbb\x0f\x11\x61\xfd\x9c\x64\x73\x91\x42\xbd\xee\x2e\x67\xd8\xe4\x7e\x0d\x0f\x89\x04\x94\xfd\x42\x8d\x26\xbb\xbc\xfb\x0b\xef\xb7\xb7\xf1\x3d\xa2\x91\xc2\xdf\x68\x8b\x6f\x4f\x65\xf1\x96\x69\x28\x7f\xbb\x56\x45\x9b\x61\x5b\xa7\xd7\x82\xcd\x71\xc8\x38\x0b\xb4\x57\x94\xec\xc5\x4d\x26\xb7\x36\xa6\x09\xc6\xe6\xbd\xae\xb1\x3d\xef\xfe\x50\x1c\x8b\x6a\x7c\x97\x13\xa1\x13\xed\x1b\x03\x35\xe4\xe8\x47\x35\x9c\xbc\x61\xfc\x4f\xf6\x2f\x37\x38\xe5\x1c\xb1\x69\x45\xa9\xa1\x5c\xf5\x0f\x81\x47\x96\x7b\xf2\x52\xe8\xa3\x63\x10\x4d\x16\x8b\x90\xeb\x28\x1c\x79\xdd\x7a\x8e\x56\x1c\x72\x13\x4b\xdf\xe0\x5c\xe7\x3a\x7b\xcb\x74\x23\x8e\x63\x30\xd7\x55\x78\x1a\x87\x82\x5a\x11\xbf\x0a\x6a\x9d\x55\x58\xf9\x11\x33\x10\xf1\x38\x94\x3a\x35\xd2\xb7\x3e\xbd\x5c\x77\xbf\x8a\x87\xea\xff\x91\xf6\x27\xcd\x8d\xe3\xd8\xfa\x38\xfc\x5d\x7e\xab\x5a\xf4\x82\x04\x48\x00\x7c\x77\xb6\x2c\x67\xea\xa6\x6d\xf9\x5a\xca\xcc\xaa\xbe\xd1\xa1\xc0\x70\x60\xb3\x4d\x91\x6a\x92\xb2\xad\xfa\xf4\x6f\xf0\x00\xe0\x24\x39\xab\x3a\xfe\x9b\x72\xa5\x08\x4e\x20\x86\x33\x3c\xe7\x79\x24\x77\x1c\x07\x7f\x7c\x0d\x8f\xa4\xb5\xc5\xc9\xf4\x74\x75\x7d\x35\x19\x57\xc0\x09\xe6\xd2\x02\xa5\x38\x52\xef\x4d\x7b\x1f\x32\xc2\x7d\x86\xa7\x77\x1b\xfb\x21\x66\x33\x22\x3d\x5f\xc9\xff\x54\x4e\x0d\x70\x76\xba\x55\x11\x3a\xcd\xdd\xf5\x43\xa5\x14\x23\x91\xe6\x98\x47\xbb\xab\x9e\xb1\x08\xd1\xbb\xd3\x1e\x5f\xfa\x57\x90\x9f\xfe\x22\x12\xe9\xe4\x9c\xb2\x12\x5a\xd1\x20\xf7\xe1\x16\xb1\x12\xd4\x0e\x72\x55\xdf\x4e\xe6\x4c\x78\xe1\xb3\xd4\x53\xb8\x82\x16\x5c\x0c\xf4\x27\x7b\x28\x67\x35\x8f\x8c\xc4\xe0\x32\x43\xae\x6c\x61\x9c\xa2\x66\x84\x50\x8a\x35\xf9\x1e\x18\x3f\x54\x2e\xfe\xfa\xae\x24\x91\xcc\x7f\x5e\xcc\xe9\x6f\xe1\x63\x1a\xae\x62\x84\xd2\x24\x24\xbf\x1f\x65\x6e\x7e\xbb\x90\xb0\x61\x84\x32\x87\xe4\xba\x87\x36\x6f\x86\x68\x09\x23\x49\xea\x81\xf9\xb2\x18\x4b\x5e\x32\x92\x58\x83\x26\xb9\xaf\x7d\x3a\x93\xdf\x61\x24\x95\x1c\x35\x22\xae\xd1\x6f\x38\x97\x65\xf8\xb5\x69\x40\x52\x5f\x99\xee\x0d\xd8\xbb\xaa\x09\x5c\x0d\x4f\x70\xd8\x56\x3f\xf3\x72\x20\x6f\xf0\xa7\xb0\x44\x21\x79\x50\x30\x99\xaf\xe5\xa8\xae\x69\xfa\x70\xcc\x28\xee\xb1\x8d\xae\x3e\xa7\xc7\x5d\xf6\x8c\x7c\xfd\x24\x21\x3c\xe6\x84\x0f\xb2\x5e\x3e\x8c\x77\xd1\xe9\x62\x44\x40\x84\xaf\xfd\x53\xb6\xfa\x65\xe2\xf7\x76\xc7\x34\xd2\x5b\xef\x8f\x45\x9b\x63\x77\x5e\xe5\xf5\x4d\x3d\x68\xae\x9d\x4f\x75\x92\xc5\x96\x39\x3d\x81\x56\x16\xdf\x20\x58\x13\x24\x53\x1a\x2d\x90\xfc\xc1\x26\xfb\xb1\x0d\x41\x64\xb7\x98\x77\x4e\xfe\xc7\x8b\x3c\x36\x4e\x4b\x7f\xf8\xa2\x92\xbb\xa0\xeb\x33\xb4\xdd\x9e\x95\xf7\x43\x50\xea\x54\x20\x3e\xd6\x87\x04\x3d\xae\x35\x18\x99\x44\x91\x34\xf5\xa8\x9b\x49\x95\xdb\xc4\x30\x21\x8a\x59\x54\xaa\xb9\x97\xc3\x2d\x35\x73\xac\xc6\xa1\x22\x09\xa1\x58\xbf\x4a\xed\x30\x62\xa8\x63\x24\xc6\x32\x21\x87\x57\xf0\x47\x6c\x64\x49\x50\xf2\x3c\x3d\xe5\x43\xe7\xda\x38\x61\x6a\x58\x9e\x3a\x9b\xf4\xe2\x1c\xf6\x88\x3b\x46\xa3\x88\x04\x2e\x8e\x19\x59\x40\x68\xa0\x0c\xa2\x69\x0e\x05\x98\x67\x08\x44\x42\x93\x07\xa5\x91\x89\xa3\x68\x60\x2e\xb8\x32\xfb\x70\xad\xd0\x00\x6c\x88\x3d\x5f\x15\x05\xc6\xd6\x1f\xeb\x1e\x82\xca\x68\x4c\x12\x27\xf4\xdf\x99\xc0\xf7\xb9\xc9\x1f\xaa\x16\x1a\x37\xd7\x70\x2f\x0c\x23\x81\xc6\x00\xd8\x32\x58\x1d\xcb\xf6\xe5\xb6\xaa\xcf\x14\xd8\x18\x8d\x2d\xc3\x02\x4a\x07\x4b\x08\xf1\xf2\xf1\x67\xa2\x24\x89\x71\x94\xa2\xd9\xb5\x78\x81\x3e\x81\xdf\x1d\xca\x50\x05\x71\x87\x32\xac\xd7\x70\x9e\x54\x1e\xfc\x4c\x46\x89\x65\x98\x12\xd8\x8d\xa9\xe0\xfb\x63\x06\xa3\x95\x8f\xab\xc7\xf0\x53\x92\x39\xc6\xa1\x1a\x2c\xd4\xb5\x2c\x7a\x44\xf4\x2c\x16\xcf\x68\xa2\x24\x7e\x67\x25\x9b\x89\x9c\x33\xa3\x69\x9c\x50\xbf\x8f\x3c\xe5\xfa\xe5\x82\x15\x40\x53\x9a\x72\xf0\xe6\x71\xbf\x0c\x9f\xe7\x99\x19\x4d\x13\x8e\x21\xe4\x2f\xdd\x9e\x00\xb0\x18\xbe\x5b\x2a\x62\x03\x21\xe6\x90\x6b\xc0\xfc\x7a\xe3\x7d\xf5\xfe\x9b\xa4\x82\x63\xf5\xa2\xc3\x4d\x3d\x1c\xf7\xf3\x07\x51\x2c\x73\xd5\x10\xce\x82\xeb\x4c\x21\xef\x52\xcc\x5b\x5a\xcd\x68\x2f\x80\x09\x75\x9f\x82\xf1\xc7\x19\x81\xa0\x13\x71\xdf\x4f\x2d\xca\x23\x57\xd8\xb5\x83\xba\xae\xea\xab\xd2\xf8\x2c\xf6\x85\xc4\xb7\xf0\xa7\x88\xc8\x3a\x7e\xea\x50\xd4\x7b\x71\xfd\xa5\x82\x4b\x0a\xfd\xfd\xa0\x6e\xae\xda\x69\x68\x3a\xb4\x33\x19\x02\x69\x36\x79\x89\x99\xdb\xbc\x45\x9d\x21\x92\x84\x47\xcc\xa2\x28\x80\xaa\xb6\x79\x01\x77\x81\x3b\x71\x94\xf7\xf8\xcc\xb0\xa7\x59\xec\x34\x5e\x70\xda\xec\x1c\x2a\x76\xd2\x2b\x99\xb2\x18\x36\xba\xce\xdb\xa6\xad\xf4\x6b\xb3\x77\x1a\x78\xfe\xb0\x8c\x1d\xe0\xa1\xb3\x19\x6f\x01\x6e\x0b\x39\x1c\x62\xda\x31\x0b\x07\x55\x03\x46\xa5\x80\x38\x0e\x41\x8c\x59\x1e\x9d\x51\x05\x06\x2b\x32\x76\x0d\xae\x17\xde\xb4\x0e\xa2\x25\xbf\xb4\xae\xa9\x49\xa4\xf5\x15\xfb\xb8\x76\x4e\xd7\x3e\xdf\x08\x98\x46\xd2\xf1\xc0\x1a\xe8\x8a\xec\xc2\xc3\x01\xd7\x4e\x2d\x07\xa3\x0e\xbd\x8b\x4f\x41\x01\x16\x54\x6e\x5a\x38\xfc\xb7\x42\x8b\xf3\xbf\xc3\x9e\x47\x01\x24\x46\x26\xef\xaf\x7e\xdf\x3d\x7c\xbf\xbf\x5e\x3e\xed\xae\x97\xdb\xed\xf2\x69\x13\x6e\x6c\x21\xc6\x98\xc8\xf6\xea\xe9\xcb\x72\xbb\xdb\xae\xb7\x57\x77\x13\xa1\x7d\x96\xc4\x19\x0b\x05\x8a\x2e\x77\x07\xe6\x2e\xdf\x87\x2c\x0d\x4b\x62\x4b\xb1\x54\xf5\x50\xc8\xd3\x25\x12\x81\x69\x64\x2b\xf4\x66\x42\x28\xc1\x8a\x0a\xc7\x28\x1f\x47\x65\x1f\xad\x64\x09\x49\x00\x0b\x6f\x7b\xae\x54\x6f\x4b\x8f\x26\x84\x57\xd8\x65\x09\xe1\x1a\xad\x68\x37\x79\x1d\x3f\x41\xb8\x4e\x92\x41\x9c\xf6\x7b\xd6\xf6\xf7\x77\xac\xc5\x32\xd3\xc2\x4a\x96\x24\xd2\x62\xf4\x30\xac\xc9\x08\x4b\xef\x9d\x83\x04\xa5\xc1\xbb\xc3\xc7\x8f\x5c\xde\x23\xc1\xdf\x08\xf1\xc3\x92\x04\x5c\xd1\x42\x3e\xd1\x80\xfc\xa5\xff\x9c\xa4\xc6\xd8\xc0\xeb\xf1\x79\x34\x92\x25\x8c\xba\x98\xd5\xe0\x43\xfa\xc5\x76\x66\x21\x26\x9d\xd9\xe4\x77\x28\x47\x8f\xbc\xb6\x17\xd6\xd4\x84\xa7\x9a\xba\x5a\xd8\x36\xc4\xc4\x9b\xdb\xaa\xbe\xf9\x44\xed\x92\x25\x5c\x29\x5c\xc1\x1d\xa7\xe4\xc8\xfd\x4e\x38\x10\xd4\xf4\x42\x34\x7b\x03\xed\xee\x19\xda\xdd\x53\xde\xbc\x8e\x70\xa3\xbe\xa9\x88\x53\x8f\x51\xc7\x05\xfa\xcf\xbc\x7c\x9e\xd1\x33\x89\xd0\x52\x32\x0c\x59\x78\x5a\xca\x79\x19\x21\x4b\x84\xe1\xd6\xa9\xf8\x34\x97\x29\x3d\x58\x92\xa5\x0c\x53\x20\xa8\x30\xe8\xb8\x50\xfa\x52\xd5\x69\x4b\x15\x3b\x92\x97\x6e\x7e\x7c\x7f\x58\x2d\xd6\x4f\x0f\xc8\xd2\xf4\x65\x75\x1b\x1c\x97\x44\x69\x1d\xcb\xc1\x36\x98\x71\x38\xb0\x44\x93\x28\x70\x70\x3c\xc0\x47\xbb\xda\xcb\x67\xd4\x14\x99\x26\xfa\x2f\xfd\x19\x19\x88\x89\xa6\x89\xd5\x21\x36\xa9\x5f\xc7\xd2\x44\x2c\x31\x31\x45\xa5\xce\x77\x4c\xcb\xce\x55\x10\x58\x62\x58\xc6\x84\x07\x30\x74\x3b\xf2\xdc\x8a\x4f\x8c\x76\x94\x29\x2a\x37\x37\xaf\x97\x0d\xaa\x7e\x82\xce\x3a\x13\x12\xc7\xb7\xfb\xf8\x6d\x5c\xf5\xc9\x12\x00\x61\x90\x96\xa3\xc4\xcf\x33\x73\x93\x12\x9b\xc6\xa8\x1c\xb1\x2a\x67\x8f\x62\x85\x53\x05\x29\xe1\xa3\x07\x9c\xdf\x42\x67\xdf\x1c\x66\x6f\x65\x21\x0d\xc2\x00\x8e\x0f\xc0\x01\x4f\xfa\x4f\x39\xb9\x6e\x1a\x69\x97\x25\xb2\x55\xfd\x9c\xbf\xc1\x7d\x98\x9d\x29\x11\x31\x62\x61\xff\xf9\xc7\xfd\xf8\x05\x52\x22\x1c\x63\xf5\xed\xd5\x62\xbb\x7e\x0a\xca\x0f\x2c\x4d\x52\x40\x93\xe1\x45\xb5\xe3\xe6\x69\xca\x04\x1f\x3c\x99\xce\x60\xc3\x48\x7c\x38\xac\xb9\x18\xd2\x6e\x88\xd6\xe9\xd5\x8f\x71\x7c\x47\x2e\x1a\x32\x2c\xce\x29\x93\x4e\xe0\xa6\x69\xab\xc3\x6d\x55\xf7\xeb\x49\xca\x25\x60\xac\x5d\xea\xf6\x28\x8b\x31\x90\xc3\x37\x10\xc4\x44\x0e\x57\xf7\x13\xe0\x75\x34\x77\xc3\x71\x43\xb0\x34\xeb\x45\x36\x2f\xd0\x4c\x17\xbb\x54\x18\x0a\x26\xe0\xee\xcd\x33\xd4\xce\x4a\xbd\x1c\xc4\x9f\x0e\x86\x34\xcb\x52\x47\xf8\xd3\xb6\xb0\x3f\xb4\xd7\xf0\x9c\x97\x77\x95\x2c\x2f\x31\xce\xb1\x34\x93\x9e\x74\xa5\xf3\x46\x1d\xc5\xe7\x13\x48\x33\x8b\xdf\xa6\x99\x09\xa3\x77\x57\x1d\x86\x0e\x97\xb1\x1b\x28\x79\xb3\x2e\x61\xf2\xe5\x64\x12\x8b\x24\xa4\x9b\xb1\x58\x60\x54\x27\xcd\x52\x29\x9d\x22\x5d\xbb\xdb\x14\xf2\x4d\x92\xfe\x77\x95\xba\x84\x2f\xca\x9a\x0e\xbb\x4d\xaa\x12\x8e\xc1\x9f\x2f\xd5\x5b\xf7\xc1\xfa\xa2\xec\xee\x88\xc0\xc5\x26\xc0\x29\x2f\x7b\x3b\x97\x4c\xea\x54\x47\x11\x4e\x00\x4f\x08\xec\x5a\xa0\x46\x59\xf0\x51\x2f\x3b\xb5\xa9\x16\x2e\x14\x85\xf9\xa7\x9b\x5c\xee\x2b\x9f\x6f\xe8\xe3\x98\xbe\xa1\x15\xcc\x27\xb0\xdb\x3b\x80\x89\xc2\x17\x63\x51\xe2\x90\xd1\xef\xe1\x6e\x18\xe5\xed\xe6\xd1\xc4\x20\x61\x51\x4a\x30\xa3\x67\x1c\x7a\x19\x23\x5f\xbf\x9d\xa7\xa2\x18\x8b\xb4\x40\xcb\xb5\x7d\x81\xce\x5e\xef\x55\x3c\x19\x8b\x40\xd2\x29\xa9\xf1\x5b\x1c\x8e\xc5\x59\x4a\x64\xdf\x0b\x8f\x75\xfe\x96\x17\x70\x99\xd8\xb1\x6b\x6c\x31\xcc\xd5\xad\xfd\xcd\x4e\x8e\xcb\x17\x18\x8b\x0d\xc1\x7c\x5b\x20\x4c\xb9\x5d\x7f\x77\xf5\xe2\x63\x5b\x85\xc5\xc6\xe0\xa4\xbe\xff\x7e\xb7\x5d\x3d\xde\xad\x96\x4f\xbb\x9b\xd5\x8f\xd5\x66\xfd\xd4\xb7\xb0\x24\x50\xad\x3d\x55\xd5\x7e\xc8\x91\x32\x46\x19\x8d\xbc\x6e\x15\x6a\xc6\xae\xdf\x7a\x4b\xa2\xdb\x54\xb4\x8f\x32\xf6\x48\xa0\xc7\xba\x32\x47\xed\x91\x56\x55\x61\xae\x4f\xf7\x95\x81\x62\x5c\x78\xd7\x9d\xe8\x14\xea\x1c\xc0\xd7\x2f\x78\x6d\x75\xb5\x58\x5c\xde\xbd\x58\xa2\x0d\x5a\xbb\xb2\x79\x9d\x13\x5b\xb1\xae\x8f\x32\x17\xf1\x40\xc9\x1a\x07\x36\xc1\xea\xfe\x5f\x58\x8c\xe1\xdc\x84\xa5\x4e\x53\xaa\x34\x9d\x81\xbd\xad\x26\x15\xda\xbe\x15\x37\x2e\xba\xf1\x52\x1d\x1b\x58\x9a\x3e\x03\xc8\x44\x24\xd9\x00\x09\xef\x16\xb7\xa2\x3f\x44\xa2\xc8\x7b\x35\xdd\xbc\x7a\x38\xee\x37\xb9\x99\x15\x09\x31\x26\x12\x8e\xb5\xee\x83\x29\x73\xf5\x34\xd9\x53\x98\x90\xae\x60\x1d\x1a\x2d\x0f\xf0\x15\xf1\x58\xc3\x82\xc9\x04\xb8\x60\xd2\x5d\x15\x42\x48\x38\x2b\x2f\x97\xa3\x33\x96\xc5\x4e\x39\xef\xb1\x6a\x37\x87\x22\x9f\x19\x4c\x2c\x13\x59\xa6\x7d\xd0\xf6\xee\x68\x8e\xfb\x6d\xd5\x79\x3f\x43\x56\x7a\x9e\x9b\x64\x59\x66\x51\x6d\x4f\x1a\xf3\x58\x15\xb9\x3e\x8d\xa8\x03\x66\xfe\x19\xcb\x20\x46\xef\xbd\xb3\x2c\x16\x57\xc1\x73\x66\x2a\x52\x98\xe2\x7e\x9d\x2a\xad\x30\xa6\x08\xc1\x2e\x74\x92\xe6\x61\x9c\x20\x9b\xd8\xe5\xb7\x53\xc6\x05\x8f\x3d\xcd\xc5\x7c\x2e\x69\x6e\x31\x52\xba\x5a\xac\x1d\x27\x12\x1d\x13\x57\x31\xa6\x33\xad\xc9\x28\xca\xe6\xc4\x84\x1e\xe5\xa9\x99\x87\xcf\x87\x5b\x6a\xa9\xc9\xc0\x85\x38\x83\x38\x8d\x56\xa8\x7e\xec\x6b\x95\x81\xcb\xcc\x95\xf0\x8e\xbc\xaf\x25\xd4\x87\x1e\x0e\x39\xfb\x20\x26\x03\x84\xa7\x17\x20\xfb\xc5\x9c\x41\xca\x43\xdd\xef\xcf\x3a\x1f\x12\x33\xcc\xc6\x09\x33\xbd\xa0\xf7\x63\x55\xf4\xa3\xd1\x52\x89\xf0\x59\x69\xcc\x72\x8f\xa8\x9a\x33\xde\xdd\x60\x7d\xd1\xf9\x27\xb6\x26\xc6\x9d\xf5\xae\x7a\xfe\x51\xcd\x80\x1e\x8c\xc7\x49\xe6\x8a\x57\x83\x5b\x82\x52\xee\x1b\x3d\x62\xc8\xf7\x2d\x49\x1c\x45\x51\xc8\x0d\x85\x72\xfd\x6d\xe5\x69\xee\x7a\xc5\x93\xa2\x99\x04\xd7\x39\x11\x0e\x73\x33\xe4\x3d\x96\xdf\x1e\xfc\x7b\x71\xaa\x33\xe4\xe4\x6f\x70\x30\xff\xad\xf8\x2b\x4f\x22\x03\x41\xc0\x6b\x67\xab\x7a\xd7\x7a\xe7\x32\x1c\x37\x0c\x2b\xb6\x9e\xf2\xfd\xb1\x7a\xcb\x1f\xe0\xb9\xfa\x33\x97\xe5\xd9\x9b\xa7\xa9\x63\xdd\xaa\x61\x2f\x91\x0f\x68\x21\x0f\xa3\x32\x73\xc6\x53\x6e\x5d\x04\xc9\xc9\x2c\x17\xb2\xb5\x55\xbd\x9f\x9a\x1e\x3c\x05\xa7\x17\xd0\x4d\x20\xcf\x14\x3b\x23\x30\x9f\x3d\x3e\x8b\x62\x19\x4a\x7a\x9b\xa7\x70\xef\x6d\x75\x85\x6a\xa2\xe1\xde\x9c\x13\xd3\x2d\x6c\x8f\x50\x96\xa7\x71\x0a\x92\xf3\xcc\x55\x5a\xbf\xbb\x38\x73\x83\x60\xa3\x33\x86\xe3\xae\x9d\x61\x0e\xe7\xf7\x53\xd6\xb5\x2c\xdb\x13\xc6\x79\x26\x5b\x2a\x17\x9c\x24\x76\xb2\xca\x61\x05\xf0\xb2\x6c\x51\x35\x79\xfa\xe4\x82\x73\x8c\x42\x28\x47\xf0\x1b\x1e\x48\x28\xe9\x05\x3b\x71\xbb\xbd\x7b\x5a\x84\x23\x19\xe3\xc8\x1e\xe0\xe9\x0a\xb6\xf9\xf0\x16\x99\x70\x3c\x82\x9d\x8f\xa5\x2f\x71\xa5\x33\x9e\xe9\xc4\x92\xc1\x68\xf0\x82\xb5\x33\xf5\x03\xc6\x65\xc4\x71\x49\xbc\xa9\x87\xc0\x2e\x97\x71\x84\x22\x29\xd0\xf5\xdc\x0d\x14\xbd\x51\xcb\x65\x1c\x27\x3e\xe0\x81\xf2\x16\x3e\x10\x3e\x5b\x6b\xb8\x8c\x89\x09\x84\x7e\x5e\xa2\xf6\x6b\x6e\x0c\x94\x0e\x03\x35\x1d\x03\x32\x66\x81\x77\xda\x41\xef\x17\x2f\x18\x5c\x9f\xbe\x8f\xe4\x80\xcc\xa6\x3e\x0c\x9c\x3f\x97\x60\x6e\x40\x16\x0e\x28\xb6\x2a\xaf\x8f\xc5\xeb\xe7\xe1\x76\x2e\x21\x45\xca\xe1\xe5\xf7\xa7\xd9\x85\x55\x4a\xb1\xe0\x03\x29\x6c\x0b\xc7\xf7\xd3\x6d\xa3\x0b\x59\x9b\xd5\x65\x09\x71\xc6\x55\x26\x71\x4b\x5e\x3f\xdc\xfd\xc1\xa2\x68\x14\x88\xe7\xca\x3a\xdc\x76\xe7\x18\x5f\x1f\xeb\xf2\xfe\xb5\x1d\x0e\x51\x9e\x85\xca\xad\xf3\xd4\x0a\xd7\xb1\xc4\x2f\xee\x48\x07\xb0\x86\x60\x14\x77\xe5\x3a\x49\xd0\xe0\xda\xf9\xe4\xcc\x1c\x6b\x7e\x39\xd8\xc6\x35\xb7\x68\x77\x1e\x76\x1e\x3a\xb8\x7f\x42\xac\x95\x97\xc1\x9c\xef\xf7\x5c\x67\x19\x73\xfa\xcd\xcd\x7c\x0c\x6b\x05\x3a\x1b\x3c\xdf\x0b\x0b\x7e\x80\x69\x92\xc8\x9f\x62\x22\xa5\xb2\x60\xed\x60\xc8\x1f\xa3\x6b\x1f\x3d\x1d\x34\xe3\x86\x3a\x9e\xe6\x29\xb3\xd9\xe5\x97\x31\x9c\xc2\x48\x55\xc3\x45\xf4\x7e\x49\x23\xd8\x9d\xe3\xc4\xc6\xba\xa5\x37\xd0\x20\x9c\x3d\xf5\xf9\x9f\xe1\xb5\x6d\x62\xd0\xe3\xdd\xe6\x6d\x7b\xba\x95\xf5\x7e\x98\x89\xd6\x88\xa0\xfb\x59\x1d\xdb\x91\x6d\x22\xa2\xd4\x91\x6f\x95\xd5\x9b\xec\xbf\xd4\xc5\x45\x4d\x44\x59\x8c\x83\x73\x73\x77\x75\x3d\x36\x7f\x44\xcc\x5c\x70\xd0\xe6\x1f\x9b\x03\x68\x5f\x66\x34\x80\x6e\x47\xb7\x8b\xb3\x0c\xeb\x09\x9f\x51\xfc\x53\x06\xae\x57\x26\x62\x6b\xa5\x37\xc5\x6e\xc0\x22\x59\xf4\x7c\xa3\x15\x24\xe2\x28\x22\x8e\x3b\xf2\x36\xdf\xc3\x36\x84\x03\x05\xa1\x49\xea\xf7\x8b\xff\x3d\xca\x12\x5d\xc3\xfe\xda\x44\x39\x72\x7c\xd4\xba\x3d\xfb\x0a\x13\xdc\xee\xf8\x59\x69\x24\x2d\x0d\x04\x13\x6d\xb7\xfb\x6c\xaf\xd6\xab\x99\xff\x2e\x68\x9c\x80\xec\x31\x7a\x9d\x49\xe3\xf9\x82\xc7\x1b\xa4\xa0\x29\xc1\xa8\xc3\x35\x48\x57\xea\xb3\xd2\x15\x4a\x48\xc5\x18\x29\xea\x53\xb1\x82\x9a\x18\x43\xfa\x8e\xa7\xcc\x74\xde\x6a\x5e\x95\xb7\xc7\xc2\xe6\x45\x31\xa3\x03\xec\x2c\x53\x6d\xc4\x4c\x8d\xac\xe8\x7c\x56\x17\xa8\x1a\xfc\x25\x91\x12\x86\x69\xec\x10\x2a\xfc\x02\xfb\xfd\xe9\xfe\xd8\xe4\xfa\x93\xaf\x9d\xb2\x18\xf3\xe5\xbb\xdc\xb1\xb3\x9e\x8b\x1a\xcf\x4f\x10\x22\x8d\x1c\x49\xf4\x8b\x54\xa8\x95\xf0\x36\x62\x9c\xf6\xad\x38\xa1\x69\x60\x7d\xc0\x2d\xef\x5e\x96\x47\x59\x14\xa7\xbf\x87\xdf\x11\x3c\x4d\x89\x9b\x59\xb8\x65\x7c\x2f\xdf\xbb\x5d\xdf\x7c\xc9\x83\xe8\x11\x13\x5c\x66\x88\x6a\xd8\x39\x42\xb9\xe0\xb3\x4d\x7b\x8e\x2b\x97\xa3\xc9\xcb\xd6\x19\x91\x9f\x74\x43\xa6\x9d\xe4\xd8\xae\x81\x76\x51\xe4\x50\x62\x1e\xfb\xfb\x61\xfb\x89\x7d\x2b\x64\x66\x95\xff\x24\xb7\x35\xb8\x00\x40\xe3\xc2\x62\x6b\x7b\xbe\x9a\x0a\x9d\x31\xa4\xae\x91\xc6\xf4\xd5\x8a\xd7\x52\xbf\x2e\xcb\xf9\x48\x33\x19\xc3\x80\xde\xd3\xda\x51\x46\x04\x9b\x58\x40\x64\x91\x0f\xf7\x26\x14\x6e\xe7\x97\xf1\xc2\x4c\x40\xc2\x48\xa8\x6c\x7d\xb9\x40\xca\x10\x9a\x65\x0a\x15\x84\x1c\x1e\xe1\x0b\x94\xd1\x10\x92\xf5\x8e\x82\xb0\xd4\xe9\xaa\xd5\xa0\xab\xda\xdc\x57\xfb\x5f\xd0\x9d\x87\x53\x98\x63\xd3\xdc\x7c\xbd\xfa\x2b\x05\xd1\xae\xb1\xa3\x87\xe9\xf6\x80\x7a\xb6\xc2\x0b\x9b\x51\x33\x28\x93\x63\x88\x60\xb0\x64\xce\xf7\x55\x61\xa5\x46\xa3\xfb\xb5\x3c\xea\xd7\x31\x25\x24\x13\x56\x41\x1a\xc4\xab\x17\xb2\x2c\xab\xf6\x8b\xaf\xc6\x6b\x56\xe5\x43\xd5\xae\x90\xb7\xbe\x85\xf1\x1e\x97\x45\x8c\x20\x50\x3e\xcc\xa6\x45\x51\xf9\x58\xcf\xcc\xc6\xc8\xe2\x28\x73\xe2\x5c\x35\x98\x5c\xb7\xcb\x8f\x43\x51\xd5\xe0\x1f\x61\xf2\x52\x59\x9c\x90\x98\x87\x48\x78\xfd\x06\x98\x5c\x75\xf1\xa9\x8b\x9f\x29\x8b\x99\x46\xe3\x56\x4e\xd3\xf8\x23\x8c\x6a\x6f\x69\xf8\x33\xa8\xd0\xb1\xab\x95\x92\xcf\xa0\x0a\x98\x15\x00\xb2\x8c\x1a\x2d\xc9\x08\x76\xb9\x28\x9b\x4f\x17\xcc\xb3\x05\xb4\x5f\x3a\x33\x0a\x8e\xf4\x2d\xf7\xa1\x44\x9c\x60\xce\xe9\xbc\xfc\x2a\x49\xa4\x31\xfd\xbf\x73\x7c\x6a\x06\xe3\xc5\x8e\xdf\xef\x02\xd9\x45\x38\x29\x75\xb9\xbd\x06\xda\xef\xdf\x57\x37\x09\xd6\x99\x8f\x78\xa6\x59\x96\x08\x9d\xf0\xc1\x8e\xde\x82\xdc\xaf\xc2\x97\xcf\x52\x1e\x21\x78\x3e\x28\x03\xae\xad\xb3\xfb\xa6\x37\x61\x91\xd3\x20\xf0\x65\x9e\x7d\xfe\x34\x1c\x4e\xdd\xdc\x6b\x86\x52\x73\x96\x31\x21\xb0\x8c\x72\x79\xc8\xd1\x38\x3d\xeb\x66\x2e\x33\xc4\xc6\x2f\x2a\xac\x0e\xfa\xcb\xd9\x90\x65\xb4\x47\x2f\xdd\x1d\xae\x73\x33\xce\xe3\x64\x99\x76\xa5\x2a\xc1\x27\xfe\x09\xf9\xb6\xf2\xd5\x8e\xd3\x97\xc9\x2c\x50\x1f\x43\x7d\x1c\x67\x81\x7f\xed\x8d\x65\x32\x32\xa1\x96\xff\xbe\x6a\xba\x41\x0c\x65\x93\xbf\xc1\xa2\x3e\x1d\xda\xaa\x73\x2a\x82\xa5\x91\xc9\x58\x06\xe1\x8b\x07\xf8\x68\x1f\xe5\xa9\x3a\xb6\xcb\xa6\xcd\x27\x28\x91\x4c\x31\x8d\x0a\x69\x2b\x53\x15\x63\x5b\x22\xd3\xd4\xf1\x68\x94\xf0\xd1\x3e\x54\x03\x7a\x25\xd3\x19\x41\x78\x0d\x7c\xb4\xb5\xec\x39\x07\xf3\xaa\xc4\x9c\x85\x6f\x64\x44\x86\xba\x5c\x0f\xdf\xef\x77\x4f\xcb\xcd\xf2\xe9\xc7\xf2\x66\xb7\x58\xaf\x1e\xfa\x06\xca\x86\x3c\x77\x60\xc1\xc1\xd0\x5f\x67\x4d\x34\xad\xdc\x1f\xa6\xdb\x44\x66\x74\x86\x85\x05\xbe\xae\x76\x37\x9b\xdd\xc6\xc4\x41\xb2\x6e\x85\x1d\x16\xd2\xfc\xe3\xee\x93\x11\x51\xda\x83\x46\x9c\x47\xe0\xe9\xc3\xd5\x90\x69\x92\x11\xcd\x30\x47\xfb\xbf\x6a\x18\x5c\x32\x12\x31\x12\xe4\xf6\xa8\x33\x3f\xf8\x4c\xdf\xc0\x00\x52\x58\xaa\xe3\xc9\x51\x97\x5c\x9f\xd6\x63\x39\x81\xbf\xc5\x9f\xcc\x64\x9c\xba\x94\x42\xd7\x2b\x1a\x90\x0b\x7e\xb6\x8e\xc9\xd8\x32\x5c\xee\x55\x0d\xf2\x75\x65\xbe\x97\xf9\x7f\x8e\x50\x42\x73\x4e\xb1\x32\x3d\x8f\xc8\x34\x73\xc4\x84\xc1\x4d\xf8\xe5\x1e\x21\x69\x64\x55\x12\x82\xdd\xbb\xff\x1c\xf3\x3f\x77\xce\xd0\xbe\x30\x2b\x24\xcd\x1c\x15\x7d\xf7\x05\xbf\x1f\x46\x66\xad\xa4\x8a\x21\xe8\xe7\xeb\xfa\x61\xfd\x74\x75\x7d\xb7\xdc\xdd\xad\x37\x1b\xc7\x7f\xfd\x5b\xdf\x46\xc7\x9e\xd8\x4f\x06\x5c\x90\x9f\x35\xa1\x85\xa5\x08\x28\x34\xde\x31\x7d\x1a\x90\x40\x32\xa1\x0e\xa1\x30\xc9\xc7\xf7\x14\x90\xe2\xc2\xaa\x28\x93\xd4\x3d\x54\xb7\xb8\xba\x9a\xa6\x26\x00\xf1\x46\xad\x52\xe2\x40\x91\xcd\x8b\xac\x21\x04\xa4\x65\x9a\x02\x96\xe6\x36\x47\xb5\x93\xb5\xca\xdb\x5f\x2b\xa4\x33\x99\x66\x29\xee\x9f\x07\x79\x6a\x2b\xd2\x5f\x06\xd2\xc4\xa5\x18\xa1\x7e\x86\x52\x9f\x1c\x62\x63\x96\x05\x93\x2c\xce\x60\x5c\xf7\xb3\xb2\x8f\xc7\x3a\x6f\x65\x99\xeb\x01\xf3\x18\xda\x92\x04\xbd\x7c\xbf\x40\x3e\x0d\x09\xda\x79\xc1\xdc\x67\xf2\x5c\x7f\x6b\x11\x92\x5d\xcf\x44\x98\xb8\x33\xd5\xf7\xb1\x20\x0c\x93\xcc\xb8\x6f\xd1\x19\x03\x45\xaf\x7f\x30\x49\x77\x4a\x9e\xba\xfa\xc4\xf3\x90\x4a\x68\x20\x22\x24\xea\x50\xc7\xba\xec\x43\x36\xe1\xa0\xa0\x0c\xd1\x93\xde\x6b\xdc\x56\x1b\x7c\xa5\xdf\xfc\xbf\xa7\xde\xa4\xcc\x22\x85\xe9\x59\xf4\x26\xd1\x81\x6d\xf2\xe7\xe9\xd0\xca\xb4\xc0\xb8\xa9\xc7\x7c\xde\x54\xcf\x7f\x17\xf2\xf9\x8f\xe3\x65\xe2\x2c\x26\x33\x03\x69\x3c\x4e\xa5\x4f\x57\x7f\x99\x41\x86\xf5\x0e\xad\x13\x90\x9c\xc6\x58\xa4\x54\x51\x9c\x86\x00\x47\x79\x6c\x50\x28\xdd\x1f\x53\x10\xe3\xe8\xc3\x17\x9a\xd0\x49\x31\xa9\x09\xc5\xc0\xc8\x01\x97\xfa\x3e\x30\x36\xbd\xb5\x89\x22\xd4\xa0\xb8\x59\xff\x4f\x88\x1c\x49\xac\xa1\xfd\x7f\xff\xbf\xff\x77\xbf\x7a\xe8\x49\x30\x77\x3f\xae\xee\xbe\x87\x92\x13\x09\xa9\x25\x59\xcf\x62\x61\xfc\x1c\x9d\xe4\x14\x25\x58\xc5\x3c\x71\xcc\xb5\x6c\xf5\xcb\x99\x13\x7b\x56\x75\xc5\xa4\xcd\x12\x0c\x72\x3d\x55\xc7\x02\x7a\x38\xb4\xb4\x3a\x53\x01\x92\x57\x57\x36\xef\xc7\x86\x8a\x2c\xc5\x6d\x63\x7d\x38\x36\xe7\xec\x4f\xdd\xf1\x44\xb8\x85\xa2\x41\x42\x9f\x3e\x55\xe6\x8f\xc7\x06\x70\x32\x7e\xdb\xae\xe7\xb6\x80\x8a\x21\xc1\xae\x51\xc7\x93\x83\x3a\x75\x9e\xdc\x20\x0a\x13\xd2\x66\x8a\x10\x17\x2a\xf3\x3b\xab\xcb\x1d\x5e\x1f\x4f\xe1\x73\x4c\xb9\xbb\xc2\x49\xca\x95\xf8\x3d\x81\x2c\xf2\x3f\x67\xb6\x8d\x22\x40\xb0\x92\xf6\xf1\xea\x69\xb3\x5c\xec\x16\x4f\xcb\x9b\xd5\xd6\xe9\x03\x8c\xe8\xe8\x98\xa2\xd4\x29\xe6\x4c\x6e\xdd\x0d\xb1\x5f\xde\x3b\x49\x04\x9e\xd5\x78\x9d\xb1\xef\xa5\xa9\x56\x33\x8b\x44\x25\xe0\x80\xa4\x9d\xdf\x2f\xf3\xe2\x34\xb8\xb1\x63\xac\x8e\x4a\x89\x41\x2a\xf4\x83\x83\x85\x2e\xb7\x5f\x9d\x09\xdd\x4c\xf1\x8e\x2a\xa5\x31\x5a\x09\x0e\xa2\xdf\x0d\xe1\xc1\xa6\x13\xa1\x4d\x26\xd0\x08\x42\xcc\xe3\x2f\x34\x56\x98\x4a\xa5\xc2\x40\x12\x8a\x57\x3e\x56\xe5\x9f\xf9\xe5\x40\x9b\x62\x89\x63\x0c\xaa\x61\x64\x28\x87\x63\xd6\xd9\x7a\x0d\xe8\xaa\x34\xbf\x3f\xb9\x02\x86\x31\x36\x44\xf1\x44\xa0\xc4\xd9\x7b\x37\x80\x7b\x5b\x4a\x71\x2d\x10\xc1\xe8\xe2\x8d\x8e\xc4\xe9\x93\x27\x15\xcc\x21\x09\xc1\x2b\xb2\xfc\x92\x8a\x87\x29\x21\x01\xb3\x13\xff\x86\x8f\xc3\x67\xeb\x4e\x68\x0a\x9a\xf9\x32\xf7\x6e\xd4\x0e\xd5\x03\x2a\x23\x31\x22\x0b\x76\xcd\xa9\xd4\x0e\xe9\xe0\xb9\xa4\xbc\xbf\x3b\xb5\xa5\x54\x46\x0d\x16\x93\xda\xbc\x40\x11\xc4\xe0\x9c\x88\xc1\x5f\xf3\xc2\x1e\x97\xc9\x22\x98\xca\x12\x89\xe3\x75\xbb\xdd\x5e\xe0\xd8\x11\xb3\x27\x97\x5a\x45\x1e\x43\xb8\xfd\x38\x23\x92\x66\x4a\x5a\x89\x70\x85\xe5\xa2\xda\xef\xbb\x61\xe4\x31\x37\x9b\x53\xd3\x42\x00\xe7\x2b\x15\x49\x74\x32\xfa\x79\xfb\xe5\xb8\xdf\x9f\x45\x2b\x42\x63\x9a\x62\x15\xe0\xdd\x51\xbf\x9e\xae\xa5\x3a\xf5\x57\xc9\x20\x28\x45\xdc\xcb\xba\xcd\x1d\x61\xd6\xf6\x74\x80\x95\xb9\x1b\xe5\xd4\x7d\x73\x1d\x2b\x9a\x8d\xe0\x9f\xae\x6a\xe2\x1f\xf3\x46\x80\x55\x7b\xb6\xae\xf6\x3f\x21\xff\xb5\x3d\xa0\x0c\x8b\x02\x73\xcb\x27\x22\xb5\xb3\x77\x31\xcc\x21\x7b\x10\x26\xf5\x0c\xed\x0e\x3e\x0e\x79\xcf\xbf\xca\x94\x11\x3c\x40\xb9\xbf\xd7\x61\xa7\x50\x10\x73\x44\xad\xd4\xae\x48\xe3\x19\x48\x7f\x84\x29\xec\x48\x95\xd7\xed\xac\xd2\x4e\x81\xf4\xdc\xf7\xdd\xd8\xdd\x56\xa1\xba\x62\x75\x33\xeb\x17\xd0\x8e\x0c\xb7\x81\xce\x09\xe9\x9e\xe6\xaa\x34\x3f\x67\x34\x5d\xa1\x2d\x38\x95\xa0\x40\x6d\xd0\x74\x6b\xda\xa7\xe9\x27\x7c\x9e\xb0\x42\x58\x22\x10\x19\xb8\x6b\xa0\x34\xf7\x55\xe9\x91\x73\x7f\x9e\x4d\xab\xd0\x9e\xa7\x34\x48\x22\xb5\x2f\x7e\x12\x4c\x68\x0c\x99\xb2\xda\x25\x1b\xaa\xd3\x6b\x55\x35\x2f\x21\x01\xa5\x23\x0d\x52\x8d\x42\x19\xdd\x54\xbf\x01\x69\x8a\xbc\xfc\x04\x1c\xab\x63\x62\xb1\x34\xf5\x50\xe7\x3a\x2f\x9f\x1f\x0b\x19\xdc\x27\x1d\x0b\x96\xa1\xf1\x48\xe9\xa4\xf6\x4e\xc7\x99\xc5\x88\xb4\x3a\xe6\x85\xb9\xcc\xc4\x36\x7d\x29\x1d\x7b\x68\xe7\xb3\xdc\xc3\x52\xd6\x68\x34\x85\xdb\x90\x84\x98\x51\xfd\xc5\x8f\x1c\xde\x3f\xa1\x4c\xef\xda\x72\x5c\xba\x51\x2a\xa4\xb3\x79\xa7\x1d\xa3\x69\x92\xe2\xc0\x94\xc6\x74\x7b\xb7\x7e\xc1\x52\xf5\xab\xd2\x4c\x75\xed\x2e\x2f\x4f\x3a\x4d\xdc\x57\xf6\xa4\x85\x97\xf5\x6f\xe7\xe7\xc8\x04\xc3\x5b\x6d\x0e\x35\x1d\x8a\xa9\x74\x67\x21\x7a\xe7\x70\xa3\x73\xa7\xa8\x30\x29\x5b\xf6\xed\x98\x4d\x44\x90\xde\xba\x7a\x1e\x14\xcb\x98\xe6\xa9\xd3\xff\x42\x34\xa1\x9b\xb8\xd3\x64\x4f\x4c\x7a\x44\xbd\xe6\x2a\x91\x2e\x13\xec\xe0\x00\x71\x7f\x15\xc5\x42\x81\xde\x24\x91\x3e\x1f\xbb\x63\x5f\x48\x8b\x8c\xb3\x61\x1c\x0d\x74\x53\xe7\x7c\xc8\x4c\x0b\x9b\xf5\x2c\x4e\x3e\x2f\x77\x01\x07\xa5\x33\x43\xb8\x0c\xc9\xe0\x23\xea\x4d\x5e\xfe\x08\x52\x68\xd4\xb5\x36\x79\x53\xbd\x97\xbf\x4d\x8c\x61\xad\x52\xc7\x93\x72\x9b\x37\x2f\xa3\x0c\x94\x56\x99\xd3\xc8\x7f\xcb\x87\xb2\xaa\x11\xf9\x00\xd3\x5a\x39\x01\xad\xdb\xe5\xcd\x5f\xd7\xda\x6a\x6d\x79\xd0\xbc\xc1\x97\x3f\xe3\x2c\x1a\x1e\xd7\x24\x12\x51\x9d\x58\x70\x33\xf9\x7e\x36\x16\x08\x82\xf6\x65\x83\x79\x2d\xcb\x17\x39\xf1\x23\xb4\x4d\x09\xc6\x83\xaa\x5a\xea\x02\x56\xed\xa6\xb3\x89\x46\x7a\x26\x4c\x5b\xd0\x4e\xdd\xa7\x86\x11\x4d\x31\x33\x11\xd1\x8e\x98\xe2\xa5\xca\xa7\xb5\x80\x26\xa6\x12\x31\x63\x0e\xef\x71\xce\x20\xc2\x4c\x9c\xc4\x28\xc1\xe8\x65\x34\x87\x78\x45\x38\xae\x04\xaa\x62\x6c\x17\x77\x93\x9a\x60\x13\x5b\x8a\xf0\x97\x2d\x34\x6d\x32\xfd\xc0\x26\xb6\x1a\x83\x93\x9b\x6a\x33\x62\xa9\x61\x86\xc4\x06\x97\xe3\xf7\x97\xaa\xff\x89\x58\x99\xb8\x1a\x2d\x39\x69\x9a\x46\x91\xa3\x99\x2c\x9c\x54\xdc\x9d\xec\xcd\x5e\x43\x23\x47\xf8\x11\x30\xe5\xff\x23\xf5\xeb\xa1\x9a\x6d\x76\x86\x12\xc1\xdc\x68\xec\xd7\xfd\x6e\xd4\xcf\x1b\x65\x98\xa0\x6b\x5e\xf2\x43\x33\x31\x8c\x0d\x4d\x34\x22\x88\xb5\xc7\x05\x85\x9f\x21\x46\x9c\xcc\x4d\xfe\xec\x8b\x97\xba\xe7\xfe\x16\xa0\xeb\x26\x89\x29\xeb\xd9\x3e\x1e\xab\xfe\x33\xa5\x5a\xe0\x3e\x75\xb3\xbc\x7d\x5a\x6f\xb6\xbb\xfb\xf5\xc3\xf6\x6b\x08\x1a\x18\x96\x5a\x3a\x55\x9d\xbd\xcf\x8b\xce\xe3\x29\x61\xc4\xd2\xc9\x30\x3a\xe9\x04\x92\xfa\x88\xe1\x2f\x03\x1f\x86\x47\xbe\x60\x4d\x36\x28\x23\x3c\x81\x0e\x1a\xce\x20\x48\xdb\xb7\xc7\x66\x1e\x8a\xed\x1b\x59\xe4\xfd\xb8\xaa\xdb\x81\xf0\x0f\xce\xe2\xb6\xbf\xaa\x7f\xbd\x54\x9f\x67\xb8\x49\x89\xf7\x0c\xc7\xd1\x55\x23\x22\x8b\x1a\xa3\xa3\x42\xe4\xce\x3e\x3f\xed\x64\x67\x2f\xf4\x1d\x2a\x18\xc3\x98\x43\xb0\xc9\x8b\x5c\x9f\xdc\x44\x9f\xa1\x5b\xc6\x93\xdb\x9f\x9b\x45\x64\x50\x74\xda\xbe\xd4\x55\x89\xb2\x5a\x13\x21\xef\xd0\x94\x30\x26\x03\x9e\xf9\xfd\x7b\x33\xfd\x1e\x99\xb0\x68\xcd\x2c\xaa\x66\x9f\xeb\xe5\xc7\x01\xea\x1c\xca\xbe\xb0\xc6\xb7\x92\x91\x88\xd2\x11\x5b\x04\xa2\xec\xa6\x9d\x2c\x4d\x82\x6b\xdd\xf5\xe2\xd6\xd1\x3f\xff\x77\xa4\x03\x46\xf1\x18\x31\xae\x58\xe6\xe1\xeb\x65\xa6\x2f\xa2\x44\x8a\x9c\x4c\xb6\x96\xdd\x83\xfe\xbd\x18\xad\x51\x42\x22\x68\x35\xc4\xaa\x5c\xe4\x75\x96\x38\x31\xca\xc6\x21\x14\xf9\xb8\x5e\xdf\x39\x02\xbf\x2c\xbc\xbe\x89\x6d\x88\x37\x96\xa0\xdb\x3b\x90\xf6\xf2\x12\x6a\x8c\xa4\xd4\x04\x0e\xad\x7d\xde\xd7\x6a\x1b\xa3\x0c\x32\x93\x07\xea\x82\x2b\xf3\x76\xf6\x02\x17\x42\x79\xc6\x18\x82\xc9\xeb\xb7\x5e\x51\xa9\x6e\xcf\x16\x39\x10\x46\x27\x83\x9e\x23\xfa\x50\x93\xea\x2c\x63\x95\x43\xa3\x3c\x83\x43\xf6\x5e\x2c\x63\x75\x6d\x21\x52\x2e\xba\x80\xab\x46\x60\xc1\x0d\xc7\x0c\xc7\x1d\x12\xb7\xf8\xf0\x23\x89\xa4\x17\x32\xc1\x48\xd7\xb7\x99\x76\x20\x03\xa2\x34\xea\x72\x6c\xde\xab\xda\xb8\x82\x8b\x70\x2e\x25\x29\xf2\x0e\xfc\xbb\xca\xcb\x45\x71\x54\xfd\xef\x22\x46\x0d\x56\x69\xcc\x5c\x56\x84\x01\x55\x2a\xf3\x07\x91\xe3\xf9\xb2\xd7\x01\xd4\x18\xac\xc4\xf7\x41\xea\x66\xb5\x3f\x54\x75\x0b\x75\x80\x86\x43\x62\x0c\x86\x89\xab\x69\x22\xf7\x4c\x48\x91\x41\x6a\x21\xf3\x45\x01\x08\xa9\x7d\x82\xff\x1c\x73\x47\xcc\xe7\x05\x4d\x88\x08\x86\x8c\x3f\x85\x71\x12\x7b\xee\x9d\x85\xfc\xf7\x71\x80\x57\x02\x17\xa0\xa2\x40\x6b\xde\xdc\xe7\xb3\x7c\x3e\x08\x1e\xa3\x53\x54\x54\xcd\x67\xa0\x03\x10\x99\x40\x23\xa9\x1b\x17\xa4\x05\x79\x46\xee\xd6\xb7\xd3\xd6\xdf\x2b\x44\x80\x2e\xd5\x88\x83\x90\x11\x3e\x53\xcf\x37\x78\x9d\xcf\xf2\x70\x90\xa5\x96\x3b\x39\xa0\x0d\x14\xc5\x28\x44\x08\x99\x8a\xe2\x40\x4d\x99\x37\x87\x63\x0b\x23\x28\x3d\xc8\xd4\xf1\x79\x38\x0b\x0c\x19\x4e\x67\xdf\x53\xa6\x12\x3d\x52\x33\x4a\x5f\xa0\x8e\xf7\x62\x54\x35\x01\x52\xe8\x2c\x42\x93\x56\xe7\x7b\x59\xac\x8d\x69\x6e\xab\x7a\x7d\x6c\x75\xb5\x9f\x44\x32\x40\xaa\x2c\x20\xa9\xbf\x56\x0d\x12\x08\x4c\x5f\x45\xea\x04\x31\x25\x9d\xd5\x80\x53\x01\x09\x08\x9b\xfe\x4e\xd6\xe0\xe6\x1d\x22\x34\x0b\x59\x14\xd3\xed\x62\x54\x5a\xd1\xbb\xd7\x41\x73\x8e\x81\x8a\x15\x9a\xbb\x5e\x76\xf3\xac\xb8\x01\x14\x4f\x44\x4f\x60\x54\x4c\x73\x79\xd3\x96\x3a\x8a\x30\x04\xb2\xf8\x1a\x72\x35\xa0\x15\x15\x0e\x67\x54\x37\xed\x08\x88\x7e\x13\x28\xc7\x66\x57\xb0\x16\xf1\x07\xbd\x16\x5a\xb0\xeb\xc1\x08\x9b\x7a\x91\x47\xaf\xf2\x30\x21\x0c\x99\x76\x99\x51\x51\xe2\xed\xc8\x2b\x27\x67\xe2\x73\x4c\xeb\xcf\xfc\x31\xb0\x24\x35\x5e\x8e\x27\x88\x6f\x38\x03\xe5\xff\xe8\xbf\x2e\x61\xec\xc1\x52\x03\xae\x6a\xae\xd2\xaf\xfd\xd7\xb0\xdc\x95\xe9\x85\xed\xd4\x47\xb8\x3e\x79\x4e\xab\x22\x1a\x0d\x40\x8a\x73\x82\xa6\xd0\x4e\x0b\x4c\x27\xb8\xd2\xc4\xeb\xe3\x09\x6b\x3c\x9a\x69\x86\x28\xf8\x24\x60\xad\x44\xa8\xec\x6a\xb1\x7e\xef\x41\x92\x36\x52\x2e\xbc\x89\xe1\xd7\x7a\x59\x9a\xbe\x5c\x2e\x58\xa9\xb3\xf2\xa0\x7f\x7c\x92\x7e\x9a\x47\xa5\x2e\x74\x8e\x8d\x89\x64\xb2\x07\xc8\x6e\x93\x00\x73\xb0\x71\xea\x88\x61\x1b\x7c\x8d\xf3\xcc\x89\x25\x04\x02\xd2\x1b\x65\x4c\x9b\xe3\xfe\x51\xe6\xf5\x78\x72\x59\x4a\x38\xf2\x67\x36\xef\xf2\xb0\x90\xb5\xb9\xad\xea\x99\x46\xdb\x68\x82\x59\x9a\x82\x4a\x66\x7a\xcc\x98\xc4\x9a\x7c\x0b\x4b\x75\x92\xda\x01\x3d\xe6\x03\x45\x03\x76\xcc\x26\x24\x42\xde\xb8\xc7\x17\xc4\x09\x4c\x3d\x60\x9b\x24\x1c\xf7\xcc\xeb\xed\x62\xb3\x7b\x5c\x3f\xa1\x42\xd4\xfd\xd5\xef\xfd\x71\x4d\x68\x1a\xb2\x8c\x4d\x5b\x1f\x75\x5b\xd5\xf3\x22\xdb\xf1\x6e\x6a\x13\x70\xe2\xcb\xb2\x70\xd9\xd5\x66\x90\x57\x63\x36\x8d\xc0\x57\x41\x7b\xd2\xd8\xab\xc3\xe1\x5c\x5c\xd2\x2b\xd8\xfe\x2b\x9c\xc4\x33\xe2\x36\x7c\x6f\xf6\x7a\x8d\xc9\x27\x90\x66\x3e\x15\x6d\xaa\x33\x0c\x5f\xb5\x79\x58\x3a\x2d\x53\xcc\x79\x56\xdd\x62\x7f\x2b\xf3\x02\xcc\x8f\x0a\x05\xd1\x46\x01\x1c\xdf\x96\x1b\x63\x1d\x18\xef\xf0\xfd\x0c\xd5\xe0\xdb\x08\x1a\x71\x3b\xd0\x67\x77\x23\x7a\xfa\x0c\x22\x65\x88\x88\x0e\xb3\x69\x37\x04\xfa\xad\x00\x2d\x5d\x00\x60\xdf\xc7\xa7\xac\xa4\x8e\xbd\xb8\x76\x5b\x9e\xe9\xac\x8f\x6b\x68\xdf\x01\xca\x9b\x5a\xbe\xf7\x5f\x4b\xc5\x8c\xfb\xb2\x52\x64\xca\x98\xa4\x23\xac\x62\xce\x4f\xc1\xd0\xd1\x4f\x04\x8e\x07\xaf\x67\xfa\x7c\xca\x92\x88\xcc\x99\xda\xc3\x55\x34\x01\x46\x7c\x14\xcd\x57\xd0\x6f\x30\x7c\xdc\x2d\x44\xa7\x4b\x0e\xa2\x35\xb1\x45\xbb\xb2\xf1\x75\x45\x7d\xae\xdd\x1a\x21\xb0\x12\xb2\x7d\xa9\x01\xb5\x48\x3f\x59\x52\x2c\x50\x83\x28\x19\x69\x5b\xa8\x6f\xab\xfa\xf5\x09\x1a\x7d\xec\xb9\x76\xa6\x74\x12\x16\x24\xc5\xc2\x96\x77\xc8\x57\x8b\xf5\xbd\xfc\xc8\xf7\xc7\x7d\x7f\x50\x19\xd4\x2f\x56\xc7\x4f\x62\x06\x16\x40\x63\xb9\x5a\x0d\xed\xae\x08\x8e\x0e\x8f\xa2\x88\x23\xc8\x69\x9f\x97\x55\xed\x49\x20\x26\xd3\x85\x47\x11\x25\xc4\x55\xf0\xe5\xed\xa2\x0a\xde\x26\x8f\x22\x30\xd4\x73\xde\x22\xa6\xae\xc6\x14\xdf\x6c\x4f\xe2\x51\x1c\x09\xe9\x91\xf9\x8b\xbd\xd9\x69\x17\x24\x09\x17\x21\x91\x53\x12\x43\xd0\x9f\xae\x7d\xc6\xbe\x9e\x5d\x83\x44\x2a\xf2\xfb\x9a\xac\x9f\x77\x74\xb2\x1e\x74\x87\x0d\xfa\xd5\x3e\x3c\xe6\x29\x09\xbd\xe2\xd2\x2f\x4b\xd5\x78\x44\x14\x43\xcb\xda\x56\xf5\xae\xa8\xca\xe7\x16\xea\x7d\xff\x70\x46\x61\x71\xd4\xf7\x06\xea\x27\x68\xf3\x1a\xbe\x56\xa6\x98\xdf\x1c\x28\x4b\x7a\xba\xc2\xd5\x62\xdd\xcd\xfd\xa9\xe0\xc8\xec\x96\x29\x01\x04\x1e\x7d\xa9\xda\x4f\x0a\xc5\x66\xed\x3b\x9f\xd0\xb3\x6c\xfc\x2a\xa5\x3f\x3b\x8d\xa5\x5c\x4e\x23\xd0\x5f\x9d\x2a\x63\x38\xce\x9d\x95\xaa\x03\x54\xe0\x51\x1e\x7b\xac\x03\x8f\x58\x96\x62\x84\xa3\x79\x97\xf5\xfe\x09\xc6\x36\xd4\xc5\xf1\xcc\x23\x66\x2c\x5a\x1f\xd7\x79\xb5\xe9\x23\xfa\x3c\xe2\x89\x44\xff\xea\x8b\x93\xc7\x19\x03\x35\x79\xc4\xd3\x04\x75\xfa\xca\x5e\x7e\x91\x47\x3c\x03\xe0\x61\xaa\x3a\xc2\x96\x66\xb4\x09\xcc\xee\xca\x4d\x82\x09\x13\x14\x43\xdb\x56\xae\x16\xea\x93\x27\x14\x31\x44\xe3\x3c\xfb\x2f\xb2\x51\x3c\x12\x29\xa0\x73\xba\x91\x16\xc6\x88\x45\x7f\x38\x8b\x1c\xd3\xbe\xad\x01\xfe\x84\x40\xb3\xe7\xfc\xa7\xcb\x17\xcc\x48\x8a\xbb\x5b\x67\x56\x77\x26\x84\x7f\x88\x5e\x6f\x3d\x34\x4b\x04\x7a\x35\x3e\x55\xbd\x33\xf5\xf1\xf9\x6c\xbf\xb8\xdc\x17\x99\x88\xd3\xde\x7d\x9f\x44\xd0\x7d\x03\x69\x25\xc2\x43\x6e\x97\xcb\xdd\xd5\xcd\x7d\x00\xea\xf0\x48\x31\x47\xc2\xec\x8a\xf7\xfb\xac\x13\x8f\xb4\x8d\xb1\x17\xf6\xd5\x1b\x7c\x96\xc8\x98\xde\xc3\x10\x97\xec\xba\x41\x2c\xd6\xf6\x23\x5c\xc9\x50\x97\x33\x5b\x1f\x5a\x30\xab\xcb\x86\x29\x8f\x4c\x4a\xd1\x22\x3a\x38\x0e\xb1\xab\x73\x5e\x47\x11\x5a\x66\x04\x5f\x36\x6f\xae\xa1\x5d\x74\xfb\x5c\x3f\x76\x4d\xc6\x10\x5b\xd0\x8d\xea\x7e\x1d\x33\xca\x22\x01\xd8\x55\xb7\xe1\xb4\xb2\xff\x1d\x22\xeb\xec\x7f\x97\x4c\xbe\x3a\xb6\x55\x7f\x88\x39\xc6\xf7\xa2\x7a\x1f\xa5\x47\x79\xb7\xf2\xa1\xa9\xdc\x2b\x96\xfc\x95\xc1\x75\x31\xfd\x31\x80\xa0\xcf\x74\x8f\x79\x04\x56\x0a\x57\x14\x8b\x4c\xc9\xb7\xb2\x28\x96\xd6\x82\x6e\xdd\x83\x5c\xfe\xfe\x16\x5c\x75\xd8\xa8\xba\xb8\x59\x97\x5e\xc1\xea\xe2\x29\x71\x94\x65\xc8\xc9\xbc\xc9\x8b\x5c\x57\xe5\x0f\x59\x14\x2e\x72\xf7\x5b\xdf\xc0\x18\x39\x89\xc0\x75\xbd\x7a\x23\x4f\x7d\x03\x20\x36\x58\xc6\x48\x7a\x73\x2e\x8b\xdf\x35\x72\xf0\xd2\x07\x78\x9f\xea\x02\x5c\xcc\x86\xf1\x38\x16\x0c\xf7\xf5\xdb\x63\x69\x76\x53\xb8\x0c\x8f\x49\x6c\x91\xe7\xf1\x6b\x55\xe4\xaf\xd5\xa1\x9d\x48\x91\xf1\x98\x50\x63\x47\xfc\x5e\xd7\xc7\xbc\x30\x79\xf9\xd7\x80\x8f\x4f\xf2\x33\x03\x92\x81\xc7\x44\x44\x91\xdf\xae\xee\x2a\xfd\xea\x4a\xa2\x7f\x91\x27\xe0\x31\x31\x11\x33\x03\x94\x03\xb3\x26\xe7\x69\xe5\xd9\x39\xa0\x50\x80\xfb\xad\x6a\x03\xba\xdd\x1f\xa1\x11\x0b\x90\x93\x45\xde\x4e\xeb\xb9\x79\x4c\x63\x57\x0d\x33\x92\xc0\x38\x4b\x4c\x9f\x07\x83\x78\x4c\x69\x1f\xa5\x42\xe3\xdd\x91\x63\x5c\x9f\xb6\xb5\xd4\xaf\xab\x29\x08\x9e\xc7\xa9\x16\xc8\x7a\x89\xd1\x0d\xaf\x7c\x71\x2e\xee\xce\x63\x46\x08\x82\x9f\xf3\x66\x57\x7d\x2a\xf1\xcb\x63\x06\x99\x96\x41\x16\xba\x95\xc5\xaa\x7c\xab\x30\x93\xe3\x8f\x77\x63\xc7\xe9\x7e\x1c\xcb\xf6\xaa\xf5\x25\xa1\xdb\xd3\x61\xd4\x44\x45\x18\xfc\x0d\xd9\xf8\xf1\x5c\x8d\x45\xe4\x2a\x2c\x9f\x9d\xe2\xc4\x26\xff\xe8\x8f\x10\x87\xa0\xaf\x06\x92\x16\xef\x82\xf6\x2b\x49\x2c\x98\x53\xe2\xfe\xf6\xb0\xdd\x4e\x06\x99\x00\x8e\x10\x95\xdb\xbc\x94\x45\xfe\xa7\x9c\xa0\x7b\x2f\x8f\xe9\x8c\xc4\xd4\x73\xd6\x5e\x7b\x31\xa0\x38\x5c\x2e\x13\x09\xb5\x41\xe2\xd5\x53\x5a\xc0\xe1\x5c\x66\x8b\xc7\x32\x32\x18\x7e\xff\x5a\x15\xf2\xa5\x3a\x7c\x4c\x9e\x4a\xc7\x09\x96\x73\xee\xf2\xe6\x6a\xed\xd5\xa4\xbf\x37\xf2\x19\xfb\x6b\xf6\x1d\x75\x12\x21\x5d\xec\xcd\xd3\xe3\xa7\x4f\x3e\x5b\x2c\xb4\x31\x68\x8b\x23\xae\x6f\xf7\x75\xb5\xfb\xdf\xed\x1f\xfd\xad\x6d\x0c\x3e\x58\x38\x0a\x8c\x9c\xad\x84\x97\xbb\xc6\x50\x85\xf1\xbf\x1e\xb6\x38\x66\xb6\xe5\xb1\x61\xda\xe1\x2e\x0b\x28\x8d\x92\xfa\xb5\x1d\x0a\x4b\xff\xef\x5f\x83\xf3\x34\xfa\xbf\x63\x50\xd2\x9b\xbe\xb4\xc9\x00\x57\x6e\x75\x3c\xdd\x16\xd5\xfb\x0c\xb3\xc5\x63\xa3\x84\x94\x63\x54\x96\xa7\xae\x9e\x2d\x67\xc6\x72\xd4\x4c\xc0\xac\x54\xfe\x27\xec\x4a\x78\x7f\x42\x62\x99\x9b\xcd\xff\x1e\xe1\x3c\x73\x37\xeb\x48\x48\x85\x63\x50\x36\xfb\xbc\x44\x52\x94\x30\x76\x77\xf5\x08\x13\xed\xdd\x41\x1e\x83\x20\x99\xa7\x8d\x58\x4d\xdd\x37\x1e\x43\xe6\x28\x97\x3b\xb3\x22\x94\x34\xbc\x57\xfd\x51\xc5\x30\xdf\x5d\x83\x3e\xd6\x4d\xfe\x06\xbb\x6e\xc2\x4e\xa2\x09\xc3\x63\xd9\x58\xa1\xab\x7a\x57\xb5\x2d\x34\xa7\xa9\x23\x10\x5b\xad\x20\xa4\x4c\x7c\x4d\xde\xa5\x18\x08\x27\x11\x25\x18\x47\xfd\x27\xd4\xd5\xef\x83\x2d\x41\x22\x16\x07\x22\xcb\x80\x5b\xeb\x56\xd1\x21\xa6\xc0\x49\xac\xbc\x40\x82\x6c\xf5\xcb\x32\xa0\x6b\xa6\x49\xdd\x51\xc7\x90\x58\xbb\x0f\x81\x68\x1d\x57\xee\x09\x70\x57\x49\x33\xd4\xee\x4c\xd6\x3a\x42\x84\x42\xeb\xca\x54\xc8\x19\x0d\xdd\x54\x9b\x88\xcc\xf8\x76\x94\x03\xc2\x2c\xf3\xf2\x2d\x6f\xc1\x5c\x9f\x90\x32\x45\x16\xa3\x14\x23\x27\x54\x70\xcc\x79\xe5\xba\x5a\xbf\x41\x4d\xfa\xdf\x95\xe2\x74\x2c\x90\xbd\x2a\x6d\x75\x5b\xd5\xdd\xff\xd6\x7f\x47\x1d\x9b\x93\x84\x53\xac\x86\x9a\xb2\x29\xce\xd8\x37\x7a\x73\x62\xe8\xc0\x34\xa2\xca\x0f\xf0\x85\x9c\x2d\xc9\x24\x95\x0e\xf5\xdc\x9b\xfc\x72\xf2\x85\x49\x6a\x5d\x59\x73\x37\x54\x3e\x59\xc5\x08\x8b\x9c\x1c\x84\x8b\x17\x8d\x89\x9c\x42\x03\xee\xa8\x03\x3b\x8b\xf1\xb6\xa8\x66\xd8\x44\x4e\x98\x75\x54\x45\x7b\x99\x23\x57\xe1\x06\x55\x68\x46\xf5\xb8\x9c\x70\x96\x60\x49\xa4\x42\x3d\xd2\x66\x94\x67\xe4\x84\x1b\x96\xf8\xe4\xf7\xe1\x88\xfc\x0b\x6d\x01\x66\x0b\xf5\x3e\x2f\x47\x65\xa4\x33\xf8\xe6\xf4\x5f\x67\x84\xb3\x9c\x88\x4c\xa3\x71\xde\x19\x1c\x8d\x03\xd5\x7e\x82\xfe\xe2\x44\x28\x66\x54\x10\xfc\x6c\x91\x56\xc1\xa3\x0f\x42\x03\xed\xf4\xc4\xca\xea\x0d\xb3\xb7\xd3\x89\x44\xb2\x28\x76\x72\x84\xfb\x43\x7b\xfa\x59\x57\x81\xd9\x72\xfa\x44\x59\x16\x45\x99\x0f\x01\x35\x6d\xb5\x87\xfa\xab\x6c\xae\x16\x0b\xc4\x1f\xdd\x9d\x35\x06\xc4\x65\x1c\x3a\x1f\x2e\xd0\xe6\x8f\x86\x85\x34\x04\xc1\x81\xc7\xb2\x1b\x73\xf8\x92\xb3\x2b\x48\xc3\x48\x4f\x49\xe7\xd8\x81\xc6\x95\x3b\x9c\xa8\xd8\xd1\x14\xd7\xe7\xd0\x6d\x4e\x14\x33\x58\x74\xbe\x78\x5a\x5e\x61\x3c\x6d\xc4\x22\xc0\x89\x32\x1a\x29\x25\x7c\x36\xbd\xf3\x4b\x7e\x91\x8b\x9c\xf5\xb6\xf6\x92\xea\x9b\x7d\xf5\x0a\x61\x49\xe8\x7a\x75\xd8\xb5\x3e\xb3\xdc\xfe\xc2\xb2\x0b\x37\xc8\x9c\x62\xa8\xcf\x33\x8d\xb4\x02\x37\xf9\x73\x78\x05\x13\x25\xc6\x83\x44\xbe\xcc\x05\x51\x39\x31\xc2\x31\x1d\x96\xc7\xbd\xd7\x47\xc9\x87\xd1\x60\x40\x23\x85\xa1\x7b\xf2\x1f\x52\xeb\xbc\xf4\x76\xd3\xec\x32\x40\x14\xee\xaf\x4d\x55\x78\x38\x4e\xb7\xd8\x57\xc7\x76\xb2\xea\x00\x35\x08\x78\x70\x66\x9e\x1b\x1c\x0e\xab\x2b\x2f\x19\xfa\xff\x15\xee\x9b\x13\x48\x62\xc6\x83\x31\xb8\x3f\xb4\xb0\xa3\xa2\xbf\xb3\x54\xca\xc7\xe2\xf2\xbd\x1c\x57\x92\x70\x62\x79\x96\x0a\x17\x48\x69\x8f\x25\xec\xb0\x72\x61\xe7\xcb\xd4\x7d\x23\x1a\xc5\x4e\x0c\x3e\xd7\x15\x06\x8d\x6e\x7a\xfc\x09\xa7\x11\x05\x5c\xfa\xcb\x5c\x57\xc5\xf0\x6b\xa2\x70\x16\xe8\x02\x64\x79\x3c\xac\x8d\xe9\x8f\x28\xa7\xf7\xf5\x24\x95\xca\xdb\x91\xcb\x42\xe3\x38\x43\xdb\x6c\x1f\xa2\x4d\x45\xbf\x7c\xd0\x38\x35\x2c\x0a\x9c\xed\xbe\xbc\xbe\x37\xf7\x68\x2c\x39\x1f\x34\xa1\xb6\x4f\x57\xd3\x0f\x44\x89\xa4\x18\xb4\xec\xb6\xfb\x09\xc1\xff\xc4\xca\xa0\xc4\xd0\x00\x85\xfc\x22\xf7\x0a\xcb\x43\x65\xdd\x9e\xce\x80\x16\x5d\xd3\x0c\x2b\x69\x0d\x38\xcc\x46\x78\x92\x84\x3b\x0b\xe1\xd8\x74\xb6\xe9\xc3\x71\xbf\xad\xde\xcb\x69\x55\x25\xa7\x69\x9c\x44\x2e\x78\x75\xac\x5b\xc7\x8d\x19\x26\xc8\xd3\xa8\x67\x53\x4a\x11\xcc\xf2\x08\x50\xdf\xe5\x1a\xca\xa6\x87\xda\x73\x9a\x26\x2a\x09\xe5\xe7\x79\xdd\xbe\x0c\x9e\x1d\x4d\x05\x77\x04\xf2\x43\x71\xc8\xf3\x85\xc2\x10\x4e\x53\xa3\x11\xbb\x86\x54\xb7\x3e\xe7\xf3\xf9\xa6\x4d\x53\x2b\x11\xe0\xf0\xfe\x52\x15\xc8\x21\x8a\x7e\xd4\x1d\xd8\x7e\x9c\xb0\xd4\x22\xae\xae\xa7\xe4\xbf\x1f\xf1\x0d\xf9\x36\x3c\xa2\xf8\x74\x2f\x18\xd5\x6a\xdc\x14\x19\x05\x08\x28\xcf\x08\x22\xbd\x6f\x97\xcb\xdd\xcd\xf2\x61\x7d\xbf\x7a\xb8\xda\x06\x86\x9f\xee\xb0\xe3\xc8\x19\x98\xd3\x3d\xe9\xa5\xf8\xc7\xf4\x3e\x9a\x84\xb4\x6a\xb0\x77\xf0\x3b\x5e\x0c\xe1\x7b\x18\x16\xa7\xdc\x44\x6e\x97\x6b\x9e\x1d\x67\x4a\xb8\xad\x48\xa5\x53\x61\x0a\x84\xab\xe1\x8e\x6e\xdd\x9b\xdb\x64\x34\xe3\x32\x68\x53\x7e\xaf\x8b\x5f\x3a\x8e\x34\x93\x32\xe8\xb4\xa2\xb4\x49\x69\xab\xbe\x44\x66\xb8\xa2\x24\x0e\x69\xaa\x65\x79\xdd\x8b\xe1\xf6\x93\x47\x76\xdb\x93\xcf\xc1\x20\xdd\xa5\x41\x86\x93\xf1\x62\x11\xa7\xa3\x3a\x1b\x4e\x55\xa4\xad\x17\xa4\x40\xcd\x5e\xf3\x34\x22\x02\x18\x6e\xab\x62\x83\xe8\xee\x30\xd2\xb1\xe0\xf1\xaf\xe3\x49\x54\x51\xc9\xf8\x14\xf6\xd2\xd9\x94\xd3\x46\x9a\x70\xee\x18\x40\xaa\x5a\x3e\xc3\x40\xd7\xc4\xa9\x56\x1a\x91\x7a\x9d\xcf\x70\xd7\xaf\x57\xdd\xcf\x68\xc7\x18\x89\x69\xd8\xf0\x2b\x18\xf4\x16\x37\x8f\xcb\xc5\xf6\xe9\xfb\xfd\x3f\xc3\x01\xe3\xb7\xc7\x80\xad\x72\x04\xc1\xf2\xec\x83\xf8\xe6\x10\x39\x41\x38\xf4\x23\xaa\xd7\x51\x4e\x8c\x53\x1b\x29\x1c\xfe\x45\x55\xbd\x1e\x0f\x0b\xb9\x3f\xc8\xfc\x19\x73\x9e\xf1\xec\xad\x2c\x4d\x30\x61\xbc\xc9\xf7\x07\x4f\xcd\xd0\x6d\x49\xb3\x6d\xac\x9f\x57\x16\xa2\xe0\xbc\x8c\xf5\x76\x38\xb5\x36\x32\x6a\x50\x4b\xb9\xb6\x3d\xf1\x8a\x6b\x90\x44\x69\xc2\x03\xc4\x12\x27\x52\xcf\xf8\x38\xd1\xf3\x0a\xad\x39\xc3\x74\x57\xd7\xa3\x0f\x8e\xe6\xb0\x67\x22\xb2\x0f\x55\xdb\x2b\xf1\xf8\xf6\x31\x10\x4c\x30\x1d\x02\x41\x15\x4f\x68\x14\x3b\x21\x50\xdc\xc3\x50\xdb\xe8\x51\x76\xae\xc0\x34\x90\x76\xe6\xd2\xcd\x87\x7c\x42\xb5\xc4\x54\x5f\x09\xef\x2e\xfd\xf3\x19\x14\xff\xf2\x76\x97\x24\x31\x4f\xbd\xd9\xb3\x3d\x1d\x72\x2d\x8b\x55\x0b\x7b\x9c\x35\xd3\x8c\x5f\x68\x6f\x5d\x65\xe8\xbb\x2c\xdb\xfb\xd3\x39\x75\x66\xd7\x82\x52\x97\x18\x5f\x14\xf2\x0d\x16\x2f\x32\x9f\x99\x76\x49\x62\x13\x1c\xad\x6f\x9e\x25\xf8\x1e\x9a\xce\x49\xbf\x24\x0b\x7f\x19\x9b\xdf\x5d\x42\xe3\x56\x8c\x49\x97\x5b\x00\x4c\xd5\xbb\xaf\x7e\x5d\x1d\x03\x21\xc2\xf0\x54\x69\x42\x9d\xe9\x5f\xed\xf7\xc7\x32\x6f\x4f\xdd\xc6\xd2\xf4\x39\x53\x9e\x30\x9a\x72\x3a\x48\x23\x75\x6e\x51\xde\x4f\xa2\x84\x49\x2a\x54\x20\x08\xd6\x75\x75\x5f\x99\x63\x01\x5d\x37\x5d\x18\xb7\x09\x8f\x25\xd2\x2f\x94\xb0\xaf\x06\x2a\x50\x9e\x88\x48\x22\xaa\xf1\xea\xa8\xdb\x63\x83\x26\xff\xdf\x64\xb1\x0d\x17\x30\xb1\x75\xb9\xd4\xb7\xce\x18\x34\x79\x5b\xd5\x4f\xf9\xf3\x4b\x3b\xb3\x66\x13\x99\x31\xdc\x81\xaf\xbf\xdc\x6e\xff\xaa\xdc\xb7\x6b\x9d\xe1\xac\x77\xa3\xf1\x2f\xd1\xaf\x3c\x91\x90\x09\x97\x4d\x33\x00\xfb\xcd\x4b\x7e\x98\xf5\x80\xb4\x12\x09\x93\x4a\x78\xaf\x46\xde\x4b\xa2\x08\x27\x24\x20\x34\x3a\x07\x6a\x1e\x29\x4d\x14\x88\xc4\xc9\xa5\x35\xaf\x7e\xe7\x98\x36\xd0\xc2\x69\x11\xbb\x94\x19\xd2\xbb\x5d\x90\x5a\xe5\x89\xe1\x2c\x54\x4c\x7e\x5f\x74\xe6\xd1\x23\xd4\xcb\x71\xb5\x6a\xdf\x0e\xd0\xe6\xe9\xd9\xaa\x9c\xd9\x7f\x35\x1f\x41\x10\x19\x24\x35\xd9\xa0\x08\xf8\xab\xbf\x8e\x98\x1a\xd3\x09\xc8\x38\x0e\x2a\x6c\xc8\x22\xe8\x99\xac\xca\xf2\xb3\xac\x4c\x62\x05\x64\x81\xc0\x53\x36\x81\x8a\x75\xbe\xe8\x58\x01\xc6\x78\xa6\xb4\xf5\xcf\x87\xe5\xd3\x6e\x31\xa8\xe9\xf3\x34\x4a\xa8\x48\x47\x53\x6a\xc8\xfa\x4f\x9e\x2f\x8d\x84\x44\x7b\xeb\x50\xc3\x41\xd6\xe0\x0b\x43\x6f\xab\xfa\xa1\x2a\xd7\x5f\xdc\x64\xf5\x4d\x63\xae\xc3\x72\xea\x3d\x2a\x0f\x71\x0a\xc7\x95\xc0\x94\x6a\xe0\xa6\x39\x3a\x11\x91\x7f\x5d\xf2\xd2\xc7\x0b\x98\x3f\x9d\x44\x04\xb1\x5f\x1b\x68\x11\x72\xb3\xdd\xca\x8f\x69\xde\x30\x34\x24\x29\x96\x52\xf6\x58\x80\x6d\x0e\xf5\x42\x1e\x9e\x40\xea\x97\x7e\x95\x4d\x89\x31\x38\x26\xaf\x6e\x37\x63\xbe\x18\x9e\xd2\xd8\x99\x92\x2e\xc1\x3a\x32\x94\x53\x4a\x22\xe5\xd8\x36\x8e\x0a\x0d\x9b\x6e\x11\xb9\xcf\xcb\x16\x8b\x11\xa7\x4f\x41\x69\x8a\x1c\x0c\xaf\xa0\xb5\x7c\xdd\xf5\x48\xc5\xff\x23\x5e\x35\xa5\x6b\xe2\xc4\x7d\xbf\x7b\xfa\xe7\xcd\xeb\xc9\xd7\xac\xff\x6a\xf6\xa5\x34\x25\xe8\xcf\xec\x65\xfd\x9c\x97\xa3\xdd\x38\x4d\x12\x66\x21\x50\x4e\x7d\xe9\xbd\xcd\x34\x61\x06\xc1\xe7\xc8\x99\xd6\x4e\xa8\x30\x2e\x06\x2d\xd2\x44\x32\xa5\x43\xbc\xad\xf3\x95\xda\xe5\x5e\xe6\xe7\x72\x22\x93\xe7\x4a\x6c\x84\x39\x8b\xbb\xf5\xe2\xdb\xfa\xfb\x76\xf7\xb8\x7c\x5a\xad\x6f\xfa\x67\xb0\x14\x51\x48\xde\xc3\x59\xd6\x72\x04\x80\xe5\x69\x4a\x84\xf4\x20\x25\x24\xe9\x91\x9f\xd2\xe9\x86\x13\x12\xc9\xc4\x48\x0f\xfe\x17\x01\xfb\x34\xe5\xd6\x69\x5d\x17\x55\x03\xc1\x80\xe8\xef\xac\x75\xe2\x23\x40\x5f\xd6\x8f\x9f\x50\xda\x7d\xf6\x10\xe0\xf4\xbd\x3d\xe2\x13\xea\x6e\x69\xbb\xc6\x28\x4c\x6f\x48\x7a\x20\x38\x4f\x59\xe4\x62\xe3\xe8\xf4\x22\x76\xea\xfb\x1c\x92\xc6\x53\x9e\xa6\x99\x07\x83\xd5\x3b\xac\x84\x95\x75\x3b\x19\x9e\x3c\xe5\xb8\xae\xfc\xfe\xe1\x62\xd9\x03\xf1\x07\x4f\xb9\x70\xc4\x1f\x0b\xd9\xbc\x1c\xe4\xe9\xcf\xf0\xbb\x22\x0a\x3b\xa0\x95\xaf\x30\xc8\x2c\xcf\x6e\xad\x28\xc3\x98\xfa\xb1\x09\xa1\x8c\xc5\x24\xdd\x3b\x6b\x9d\x1a\x4c\x84\x3d\x5d\xdd\x2e\x1f\xfa\xaf\xac\x44\x84\xf8\x25\xb9\xcb\x4b\x5d\x3d\x97\xf9\xac\x3a\x85\xa7\x26\xa3\x96\x8d\x30\xcc\xf7\xb0\xbe\xac\x21\x39\xfd\x84\x06\x12\xe9\xc4\xa4\xfd\x3a\xb5\x2a\x87\x32\xd6\xcb\x4f\x08\x34\xc2\x32\xe7\xce\x08\xbe\x85\xbe\x8f\x80\x31\x64\x8b\x58\xbf\x41\x7d\x90\xa7\x29\xc6\x79\xf6\x7d\x81\x4b\xac\x34\xd0\x28\xc6\x70\x19\x98\xc2\x53\x10\x1c\x90\x11\x13\xea\xa6\x2a\x5d\x7d\x80\x8b\x43\x5e\x8e\xda\xfc\xf5\x9f\x70\x61\xe5\x80\x78\xff\xae\x72\xd4\x5e\x44\x31\x3d\x9f\x54\x9e\x3e\x82\x8d\x5c\x40\x65\x93\x7f\xb4\xa1\x06\x38\x1c\x92\x0a\xfd\x31\xf7\x49\x31\xfa\x76\x5e\x7c\xfc\x8b\x92\xf7\x00\xa9\xed\x6f\xc6\x48\xaa\x85\x53\x6e\x6d\xee\x1d\x6d\xf3\x6c\x14\x33\xc2\xd3\xd4\x84\xc0\xc7\x71\x8f\x7e\xa0\x07\x43\xfc\x84\xfc\xfa\xb4\x2e\x07\x8a\x42\x7f\x0a\x15\x2e\x06\x7c\xe8\xdc\x57\x32\x18\x5a\x8c\x5a\x07\xed\xba\xcd\xcb\x16\xf4\xcb\x78\xcb\x61\x09\x91\xd8\x41\x8b\xf5\xea\x61\xb7\x58\x6f\xb6\xbb\xd5\x62\xbd\xdb\xae\x96\x3d\xf1\x34\x67\x09\x75\x42\xf7\x87\xba\x6a\xab\xb1\x63\xc1\xd2\x38\x41\x3f\x1f\x45\x45\xfa\x1f\x53\x85\xdb\xcc\x7a\x9f\x7f\x5c\x30\x57\x19\xcb\x62\x04\xd9\x3e\xc0\xfb\x54\x48\x7a\xfc\xe5\x18\x97\xe0\xea\xd9\x94\x0a\x17\xe6\x00\xc8\x4f\xe6\xf8\xe3\xee\xaa\xe7\x5c\xcf\x2e\x2d\x08\x47\x57\x72\xe7\xf2\xd1\x03\x6f\xc3\x59\xc5\x58\x70\x61\x98\xe0\x24\xe8\x11\x3f\x81\x86\xb2\xbd\xc9\x65\x1d\x02\x12\x4c\x08\x47\xdb\x6b\x00\x35\xe4\x6e\xab\x63\x69\x30\xe6\x75\x03\x6f\x7d\x9b\x2c\xc1\x00\x8f\xdb\x78\x9e\xfa\x15\x99\x09\x93\x61\x5c\x1a\xf9\x27\xf2\x06\x66\x59\x65\x3c\x0e\xe3\xa0\xfd\xbd\xcc\xcb\xff\x3a\x70\xcf\x84\x31\x18\x9f\xc6\x6a\x4c\x3a\x60\x5a\xc3\x6d\x32\xe9\x88\xd2\x37\x77\x8b\x2b\xf3\xd6\x75\x8c\xf9\x4b\x03\x95\x65\x96\x22\xc2\x69\x7f\x2c\x7e\xff\xe3\xd7\x1b\x09\x93\x91\xf3\x0c\xbe\x9e\x54\x9d\x9b\x51\xe1\x33\x67\x32\xa6\xa8\xec\xe6\xca\xd5\x6e\x16\xff\xfb\xcb\x9b\x4a\x96\xe1\x60\xbc\x1d\xaf\x27\xff\x1f\xff\xf6\x1f\x5a\xb1\x08\x57\x76\x9c\x1e\xf1\x28\x5a\xc5\x94\x06\x74\x8e\x4c\x5d\x1d\x3a\x47\xff\xd3\x38\x12\x33\xcc\x0d\xca\xff\x60\xc6\x6d\xe2\x27\x91\x49\x0c\x87\x19\xed\x80\x1c\xdd\x56\x7e\x75\xdf\xd9\x8d\x21\xf3\xca\x8c\x66\x58\x65\xf0\xe5\x66\x71\xa5\x75\x44\xfa\xdf\x8d\x41\xb6\xd0\x63\xe9\x10\x3e\x23\x6f\x88\x41\xca\x59\xda\x13\x25\xd4\xab\x83\x45\xf7\x6b\x1e\x69\x61\x96\x08\xd1\x2d\xa4\x7b\x68\xe5\xf5\xb1\x9e\x4a\xf3\xfd\xfa\x2b\xda\xcc\x65\x72\xdb\x2a\x10\xbc\x39\x73\x3b\xbc\x3c\x8f\x39\x4f\x7b\x8e\x08\x37\xfb\xfc\x11\x42\x47\xf4\x32\x67\xf5\x50\xa1\x91\x31\x3a\x0a\xb0\x35\x54\xba\xaa\xea\x8b\x16\x33\xa7\x11\x41\xde\xee\xbd\xfc\x58\xb6\x2f\x4f\x32\x1f\x80\x36\x9c\x26\x22\x4d\x03\x42\xdf\x5e\xae\x5e\xe1\x9c\xf2\x18\xbf\xd3\x97\xaa\x32\x37\xf2\x34\x5e\xcd\x79\xa2\x1d\x54\x17\x43\x87\x33\xf1\xd7\xe9\x73\xa4\x46\x91\xa0\x23\xb1\x7d\xa9\xab\xf7\xa6\xb3\x14\x9c\xeb\xb3\x2a\x75\x55\xd7\xa0\xdb\xc0\xfe\x11\x2e\xcf\xa2\x14\x09\x76\x3d\x91\x41\x13\x42\x53\xe1\xb0\x27\xac\xf2\xde\xc0\xa8\xdc\x8a\x73\x4e\xb8\xd7\x04\x82\x73\x02\x6c\xce\x39\xd7\x58\xce\xe2\x50\x6a\x0e\xf9\xd7\x4d\xf9\x30\xb0\xb8\x48\x12\x34\x0c\xf2\x06\xf1\x08\x0e\xd8\x8e\x24\x81\x63\x1e\xfa\xae\x5d\x86\x91\x42\xc7\xfc\x2d\x5f\x41\xc9\xcf\x16\x17\x2e\xb8\xa5\xbe\x20\xdb\x73\xb2\xfc\x92\xe5\x92\x73\x91\x49\x54\x74\x38\x96\x0d\x4a\x2d\x57\x75\x03\x97\xa8\xe3\x42\x73\x9d\xc5\xbd\xee\x4c\xd8\x71\x78\x16\x69\xfc\xf5\x5d\xe6\x48\x6f\x33\xfa\x7c\x19\xcb\x9c\x72\xca\x0b\xe8\xd7\x10\x4b\xc4\x70\xee\xed\xef\xb3\x0e\xcb\xb4\x24\x03\x71\x89\x27\x91\xdb\x56\x0e\x94\x18\xb6\x2b\x2e\x69\x86\x51\x42\xe4\xfe\x45\xa7\x6b\x8a\x91\xfc\x54\x13\x98\x73\x29\x22\x14\xa9\x2d\x64\xd3\xde\x1e\x47\x31\x57\x2e\x05\x93\x51\xaf\x8c\x3b\x79\xf7\x60\xcd\x72\xa9\x29\xf1\x2a\x9c\x08\x35\xd9\xcc\xe4\x9d\x38\x57\x9e\xf7\xef\x15\x4e\x5e\xc8\xe0\xab\x6c\x1e\xe6\x22\x7c\x9c\x2b\x13\x23\xdc\x39\x94\x57\x5e\x16\xc4\x1b\x2f\xb5\x5c\x59\x67\xda\x2d\xd6\x0f\xb7\xab\x2f\xbb\xc7\xa7\xd5\x62\x19\x1e\x5e\x07\x5d\x9d\x6e\x3b\x5a\xac\xb7\x2f\x79\x6d\x7e\x02\xbc\x2e\x4b\x33\x5a\x93\xb8\x89\xa2\xc0\xec\xd1\xb9\xe7\x13\xa2\x0e\xce\x0d\xb5\xe8\xe4\x7f\xab\xe4\xa6\x95\xa5\x91\xf5\xe5\x5d\xe7\x3c\xd6\xc1\x8d\x4c\xec\x58\xf5\x66\x5b\xa1\x98\xe2\xf4\x9d\x81\x58\xe7\x56\x3b\x7f\x1f\xe3\x0c\xb7\x55\xbd\xa8\xab\xe3\x21\x1f\x3e\x04\x88\x4c\xb8\x39\xb1\xfc\xc8\x9b\xb6\xf9\x6f\xa0\xba\x1c\x74\x82\xd1\x23\xf8\x00\x7d\x6c\xfb\xc8\xf5\x28\x5f\x37\x7b\x28\xab\xd3\xc8\x86\xc1\xf9\x4f\xa8\xab\x41\x68\x6d\xd4\xc8\x66\x48\x28\x0a\x6f\x50\x22\x40\xf5\x49\x96\xcf\xd0\xab\x6e\x71\x11\x45\x16\x39\xfa\xc2\x42\xfa\xe4\x0d\xfd\x11\xc2\xe0\xe2\xf3\x8a\x38\x55\xf8\xbc\xc8\x2c\xe5\xb3\x14\xdd\x68\xcf\xcb\xe7\x38\x98\x34\x22\x66\x36\x19\xcb\x18\x16\x48\xec\xd1\x1f\x55\xe0\xf8\xa3\x4a\x73\x23\x5b\x68\x87\xef\x2d\x62\x13\xe1\x67\xf9\x43\x56\x7f\x69\x3f\x88\xd8\x52\x6c\x7c\x5b\x55\xed\x46\x57\xc7\x76\x46\x8b\xd3\xb5\x50\x76\xc8\x7c\x2d\x9f\x16\x84\xd0\x5f\xb2\x9a\x70\x41\x68\xaa\x3d\x18\x0e\x53\xa7\xcf\x9e\xd8\x0f\x3f\xfe\x05\xe8\x92\x20\x9c\xe9\xb1\x92\x6e\x77\x97\x68\xde\x46\xeb\x34\xe9\xcb\x4a\x9d\x1a\x05\xbc\xc1\x99\xf7\x1c\x9a\x1b\xa7\x03\xe4\x22\x77\x33\x0e\x03\xdf\x86\x72\xc7\x4f\x1c\x6e\xfb\x50\x95\xdb\x99\x8a\x0c\x17\x54\x4a\x7c\x99\x55\x2b\x8b\xc9\x0e\x25\xa8\x4a\xa9\xcf\xfc\x6e\x8e\x07\x57\xea\x37\xdd\x22\x45\xc2\x22\x87\xa2\x3f\x2d\xdb\x20\x03\xb9\xb6\x0f\xd5\xe0\xa5\x89\xc4\x24\x24\x50\xd7\xed\x0f\x05\x2e\xc2\x93\x02\x2d\xdf\x2e\x8d\x98\xc6\xa0\x52\x75\x92\x45\x7b\x6a\xd6\xef\xa3\xe8\x68\x68\xa3\x5d\xa9\xf5\x7b\x55\x17\x66\x71\x3c\x38\xb1\x7a\x17\x88\x0d\x4d\x20\xc5\x77\xde\xef\xf2\x66\x91\xd7\x18\xd8\x1b\x92\x7e\x82\x93\xc4\xb0\xc1\x80\x09\x9b\xc8\xc4\x3f\xee\x9b\x72\x1c\xa0\x5f\x8e\xfb\x49\xb7\x08\x99\xe1\xef\xbb\xbc\xb9\xab\xca\xe7\xbc\x3d\x1a\xf8\x6d\xd2\xa5\x19\x51\xbe\xe2\x1b\x0b\xf4\x40\x6a\x78\x82\x42\x22\xac\x68\x76\x93\x2c\xe1\x68\xf6\x6b\x28\xda\x5c\xef\x74\x5d\xf5\x68\x09\x91\x65\x2c\x90\xee\x7e\x6f\xf3\x22\xff\x13\xbb\xed\xaa\x34\x57\x65\x79\x94\xc5\x75\x55\xd7\xd5\xfb\x93\xfc\x44\xdb\x8e\x8b\x4c\x25\x48\x97\xdc\xfd\x7a\x2f\x3f\x66\xdf\x5d\xc5\x8e\xd9\x1e\xf6\x79\x7b\x71\xf4\xe8\x38\x35\x99\x2f\xbd\xad\xf6\xd5\x90\x2c\x16\x9a\x44\x88\x33\x7d\xab\xda\x8b\x7a\x91\x5c\x68\x15\x2b\x9f\x19\xfb\xfd\xb9\xcf\xe9\xcf\xde\xdd\xb0\x38\x52\xbd\xcb\x93\x1f\xf2\x81\x21\x81\x0b\xa3\x58\x12\xcc\x23\x2c\x53\x9f\x76\x31\xc4\x4a\xf5\x14\x63\x55\xbb\x0b\xa7\x81\x49\xa3\xa0\xd7\x3e\x28\x90\x6c\x9c\xa9\x92\x6b\xb8\x20\x41\xc2\x05\x58\x97\x68\xc3\xc7\xd3\xf5\xf1\x33\x98\x71\x16\xc5\x04\x5d\x2c\x0c\x3f\x39\xd3\xc7\xf3\xf4\xff\xd6\xb7\x70\x54\xf4\x5f\xa0\xbd\x91\x87\x43\x5e\xda\x6a\xcc\xc0\xc0\xb3\xc8\x38\xf9\x3b\x28\xcd\xda\x76\x76\xdc\xed\xb1\x28\x06\x32\xaa\x70\x9d\x58\xa4\x58\xfa\x80\x4f\xfe\xe5\x08\x4d\xb3\x7b\xef\xc9\x1c\x26\x4b\x5c\x16\x1b\x60\xb4\x47\xb8\xfc\x36\xf3\x37\xb2\x18\x0c\x56\x2a\x5f\xcb\xea\xfa\x6f\xac\x98\x19\x51\x4e\xac\xad\xeb\x59\x6c\x3d\xf2\xe4\xa6\xbd\x41\x2d\xc7\x34\xf3\x01\x3b\x42\x62\x04\x17\xd7\x2d\x47\xa5\x9e\x43\xbd\x2a\xc3\x6e\x3c\x3d\x33\x21\x11\x9a\xf0\x1b\x68\x8f\x07\x4f\xf8\xf4\x49\x97\xa7\x24\x06\xff\x41\x1f\xab\x57\xd8\x57\x3d\x2d\xdc\xac\x5d\xea\x40\x14\x1b\x59\xb6\x43\x37\xa6\x99\xc6\xc5\x3d\x3f\xd8\x30\xb2\x32\x46\x2d\x82\xf4\xdc\xec\x74\xc2\xde\xd3\x91\x99\x09\x22\x91\x29\xc2\x75\xa9\xdf\xab\xc3\xb1\x44\xe3\xe0\x5f\xc8\xc3\x01\x69\x81\x3a\xff\xe6\x4c\xc9\x38\x34\xe6\xa9\xe3\x58\x84\x73\x99\xd6\xd0\x44\xe8\xcc\x59\x39\xaf\x80\x55\xb3\x7f\xab\xce\x5f\x84\xb3\x33\xa7\xb6\x2f\xc7\x1e\x75\xe3\x12\x1e\xe1\x89\xb3\x24\x0e\xeb\x08\x42\x34\x1d\x5e\x73\x21\x8b\xa2\x33\xb8\xbf\xf4\x05\x01\x59\xc6\x12\xed\x2e\x66\x6e\xe0\x50\xc3\xf4\xab\x7f\xea\xe1\x1e\x2f\x81\x8b\x32\x95\x2a\xdc\xf3\x6e\x3c\x1d\xcf\x06\xca\xf6\xfa\xd8\x3e\x54\xed\x3d\xb2\x8f\x7d\x12\xa9\xcb\x94\x49\xb2\x6c\x24\x23\x3e\xa9\x06\xe3\x99\x8e\x2d\xef\x71\x92\x4f\x8e\x9c\xdb\x53\x34\x6d\xde\xe5\xa1\xf9\x6d\x96\x35\xec\xe7\x81\x56\x0c\x23\x80\xea\x78\xda\x68\xb9\xef\x5f\xda\xa4\x1a\xe7\xc7\x62\x7d\xff\x78\xf5\xf0\xc7\x6e\xbb\xfe\xb6\x7c\x40\x6e\xba\xc5\xb2\xcf\xb2\x64\xa8\x8c\x19\x90\x6f\xf5\x98\x16\x97\x67\x46\x00\xf3\x45\x5a\x9f\x95\x37\xfa\x96\x10\x03\x56\x62\x34\xc7\xfd\xb2\x18\x15\xbb\xf7\x52\xab\x3c\x03\xca\xd1\x9e\x6c\x9d\x84\x6e\xb5\x0f\x80\xd6\x0c\x52\x57\xea\xf6\x15\x8a\x7c\xba\x25\x65\xd0\x6d\x24\x2e\xa6\x6a\x5b\xa8\x07\x00\x71\x66\x53\x57\x44\x78\x23\xff\xfc\x33\x1f\x71\xaf\x70\x19\x89\x04\x9c\x7c\x18\x86\x5f\xef\xf2\xa6\x3d\xc7\x77\xc9\x48\xb0\x24\x0e\x96\xe4\x42\x96\xc1\x8d\x1c\xd3\x84\x4d\x3f\xa0\x8c\x23\x89\xc4\x15\x81\x25\x80\xfc\x36\x3b\x1e\xbb\x30\xe0\x66\x7b\xf5\x65\x49\x77\xdb\xd5\xfd\x72\x37\x04\x9e\x65\x9c\xc8\xa8\xef\x80\xc0\x67\xbe\x94\x75\x71\x0a\x76\x68\xd3\x37\x4d\xb3\x34\xa8\x97\xc0\xa5\xf2\xda\xd1\x4d\xb9\xe3\x90\xcb\x75\x45\xd0\x93\xef\xaf\xe1\x79\xd7\xa5\x31\xb7\x75\x7e\x56\xed\x24\x09\xb5\x41\xbb\x03\xbd\xd7\xbc\xbd\x84\xf9\x97\x09\x51\xbe\x26\x67\x89\x82\x19\xf3\xc3\x32\xc2\x6d\xde\x40\x0b\xba\xfd\x1f\x59\x1e\xa5\x87\x4a\xfb\x89\x2c\x53\xc1\x10\x45\xe6\x56\xa5\xaf\xd5\xb1\x01\x30\x13\xed\x47\x2e\x53\x69\xd1\x54\x73\x26\x75\x50\xae\x7e\xc9\x0f\x13\x0a\x52\x2e\x53\x4b\x1c\x9a\xae\x90\xcd\xcb\xaa\xc4\xcc\x60\x67\xed\x94\x3d\xcb\xc8\xac\x77\x52\x6b\x50\x0c\xf9\xe6\xcb\xa3\x13\xcc\x2a\x66\x4c\xad\x5c\x32\x06\xca\x25\x7e\xa5\xf1\xf8\xfa\x70\x88\xc7\x82\x89\x1e\x38\x73\x44\xe5\xe7\xb9\x09\x2c\xbb\x1d\x5d\xf4\x55\x63\xb3\x83\x22\x65\x91\xa3\xf1\x76\x25\x10\x9b\x56\xea\x09\x74\x44\x4a\x66\x9c\xe4\xfe\x4b\xde\x22\x09\xfa\x58\x77\x82\x4b\x29\x48\xc8\xe1\x8f\xbc\xa2\x73\xd4\x99\x94\x10\x79\xfe\x42\x74\xa5\x7a\x79\xfd\x8b\x6b\x98\x54\x84\xf3\x28\x44\x46\xbf\xe4\x6f\xa3\xdc\xc6\x64\x62\x4b\xcd\x33\x87\xa9\x41\x25\x80\xaf\x90\xcf\xec\x3c\x69\x88\xc0\x72\xbf\x2f\x1b\xdc\x1c\x2f\xef\x05\xd2\x24\x19\x06\xb0\xd4\xf1\xf4\x50\xbd\x4f\x31\x6f\x12\x28\x45\x68\xd8\x6d\xd5\xad\xcc\x4d\x8b\xf1\xf3\xf1\x32\x20\x81\x33\xa4\x66\xb9\x59\x3d\x7c\x09\xbf\x59\xc2\x02\x32\xca\x25\xb6\x9a\x5e\xa4\xc6\xb5\x50\x11\x8d\xbc\xb6\x77\xe3\x16\xb7\xe1\x88\xa4\x38\x26\x9b\x97\xfc\xf9\x39\x37\x13\xef\x40\x45\x5a\x62\x28\xb0\x90\x4d\x9b\x46\x87\xe2\xd8\xa8\xa2\x7a\x7d\x91\x7d\xd0\x55\x45\xc0\x32\x9f\xf2\xdf\x95\xf0\xbe\xc3\x1c\xe4\xb4\x5f\x54\x1c\xc7\x08\x09\x3a\xbc\x07\x16\xd2\x49\x70\x42\xc5\x24\x71\x85\x7d\xb8\xfe\x5c\x44\xdd\xab\x98\x58\x57\xf4\xfe\xb4\x5a\x2c\x77\xb8\xac\xec\xb6\x3f\xd7\x63\x12\x66\xae\xe2\x54\x0a\x31\x16\xcb\x44\x28\xf0\x9d\x6c\xda\x8d\x77\xdd\xfb\x96\x2a\x43\xf2\x17\xdb\x07\xd9\x2f\x97\xc8\xa8\xd8\x2b\xbf\x6a\x69\x24\xd6\xb7\xff\xf6\x4b\xfc\xca\x24\x30\xab\x88\x94\xc0\x06\x70\x5d\xc0\xd6\x8d\x4d\x31\x45\x2c\x65\x81\xee\xaf\xc4\xd8\x0c\xd4\x13\x52\x5c\xae\x28\xb1\xa9\xaf\x31\x7d\x9c\x4b\x93\x73\x45\xa9\xc5\x12\x51\x97\xa9\xf0\xb6\xd8\xb6\xda\xca\x57\xb8\x6a\x36\x30\x93\x7b\xc5\xf6\xb8\x8f\x3c\x3e\x2d\x31\xff\xe2\x22\xc6\xe1\x6a\x49\x14\x63\x91\x9d\x74\xd0\x81\xeb\x13\xa2\x97\xe6\xb1\x5f\x95\xf0\x34\xf2\xe5\xb7\x3e\x18\x35\x3b\x2e\x39\x86\x07\x91\x84\x76\x5d\x9e\x57\x0f\x85\x76\x9e\x25\xd7\xa1\xc5\xbe\xe5\x6d\x1b\x28\x68\x67\xa8\x1b\x95\xd2\x08\x61\xe5\x68\x96\xa3\xde\x65\x79\x7a\xef\xd1\x9c\x2a\x4d\x23\xdc\x75\x55\x67\xcc\xe9\x6e\xd6\x68\xc7\x5a\x35\x7c\x4a\x1e\xc5\x38\x73\x36\xb2\x96\x23\xf2\xb8\xee\x00\xc1\x5c\x8f\xaf\xb0\xee\x29\x04\x7c\xc4\x78\x26\x1e\xca\x15\xcf\x62\xf4\x99\xed\xac\x54\x5b\xf1\x8c\xc5\xbe\x57\x1e\x65\x5e\x4f\x02\xe2\xd3\xf7\x16\x89\xc5\xe5\x74\x5f\xbd\x21\xed\xcb\xac\x2c\x7e\x5b\xfd\xec\xbc\xdf\xf0\x80\x42\x1b\x0c\x70\xdc\x9f\x27\xe8\x1c\x01\xec\xfc\xf3\x08\x03\x51\x14\x56\xeb\x8f\x45\x55\x14\xa0\x5b\x24\x9f\x99\xb6\xcb\x62\x85\x09\xe0\x9e\xd6\x72\xb0\x2a\x54\xc6\x0c\x22\x71\x30\x66\x53\xf7\xbf\x72\xa3\x3c\x80\x72\xcc\x9b\x3f\x26\xc8\xf3\x2d\x25\x8d\x54\xa0\x1d\xb8\xf2\xa2\x12\xe1\x50\x42\xac\x67\x69\x74\xec\x02\x9e\xff\x61\x36\x38\x64\x96\x62\xf1\x1c\x86\x98\x48\x7f\xb2\x8c\xd0\x5a\x71\xb5\xd3\x77\x83\xd2\x35\x57\x2a\x8b\x31\x27\x2e\xdd\xe5\xbc\x9d\xdc\xf3\xdc\x4f\xaf\xae\x32\xb7\x9c\xeb\xd0\x9b\xfd\x8c\x52\x1a\x88\x27\xff\x5a\xd7\x0b\xa9\x5f\xe0\x06\x9a\xfc\xb9\xec\xd6\x85\x27\x38\x54\xf5\x54\x21\xd4\x9f\xa5\x09\x75\x08\x6f\x78\x1f\x69\x3f\xff\xc2\xbc\x1f\x4e\x35\xcc\x49\xd9\x4a\x63\x02\xc2\xd9\xf7\xc8\x59\x2e\x31\x9c\x21\x32\x34\x75\x30\x5d\xe0\x83\x6b\xa3\xe5\xcd\x48\x89\xb4\x04\x3f\xef\xee\x27\x95\x0c\xca\x68\x1a\x64\x01\x7f\x54\xc5\x71\x0f\x37\x3e\x20\xfc\xdb\x05\xc7\x43\x41\x1a\x61\x7f\xee\xda\xea\x15\x26\xfe\x86\x02\x1e\xb9\x72\xf8\xea\x88\xf5\x6c\x7f\xa7\x74\x7f\xf6\x0e\x20\x34\xfa\x4d\x07\xa8\x6d\x55\xef\x6f\xbb\xfd\xb7\xbf\xbc\x4c\x99\x0c\x06\xe2\xf2\x43\x43\xd3\x8c\x6e\x6e\xb5\xc0\x8a\xb9\x6b\xa9\x4e\x37\xb5\x7c\xee\xf3\x8f\x3a\x8a\x35\xf5\x30\xae\x6e\x01\x7c\x9c\xf1\x03\x72\x1d\xd1\x08\x15\x92\xcb\xe3\x7e\x6d\x17\x79\x9b\xff\x09\x65\xf3\xf3\xa5\x0a\xe2\xb6\xdd\x30\x6d\xfa\xab\xb1\x04\x49\x20\xae\xea\x99\x31\xae\x23\x96\x05\xf2\xa6\xc0\xbe\xdf\x1f\x32\x09\x9a\xbe\x3d\x61\xe6\xdf\x8d\x45\xeb\xc8\x72\xe2\x63\x25\xdb\xbc\x3d\x16\x32\xaf\x61\xe7\xcb\x14\xd2\x70\x79\x42\x53\x44\x4c\xbf\xb8\x1a\x0b\x2c\xcb\xc7\x4d\x7f\x36\xbe\xb1\xa1\x87\xdc\x6c\xf2\xe7\xb9\xcb\xf4\x8f\x73\xda\x0f\xae\x09\x93\x88\xa4\xed\x0b\xff\x5c\xfe\xac\xb2\x63\xfa\x57\xae\x89\x14\x38\xf8\xee\xaf\x1e\xae\xbe\x2c\xef\x97\x0f\xdb\xdd\xed\x72\xb9\x7b\xba\xda\x86\xb0\xbe\xa6\x29\x43\x3a\xe1\x65\xfb\xd2\xfc\xa7\xfe\x32\x04\x4f\x34\xcd\x34\xba\x8c\xf8\x65\x37\x50\x14\x79\xf9\xbc\x1a\x08\x15\x74\x22\x08\xc2\x33\x6e\xc0\xd6\xd5\xa8\x94\x66\x80\x64\xeb\x44\x80\xaf\xa2\x87\x06\x46\xe5\x0f\x3a\x01\x47\x0a\xf1\x55\xd6\xdd\xcf\x79\xb7\x54\xf6\xcb\xbc\x4e\x6c\x86\x39\xcf\x0d\x4e\xe5\x63\x0d\x2e\x75\x71\x5e\xa3\x33\x8c\x96\x54\xb9\x88\xfe\x5d\xf5\x3c\x5e\x74\xa7\xd8\xc0\xd9\x39\x2c\x06\x8e\xc5\x42\x18\xb4\xc5\x9d\xea\xed\x79\x0a\x3e\xf8\xd5\x5f\x96\x4c\xa7\x89\xe6\x71\x9a\xf9\x35\xba\xdb\x98\xbe\xfd\xb1\x40\x9e\xb0\x31\x97\xd6\x45\x10\xad\xe6\x09\xe1\x0e\x92\x7e\x28\xaa\xd3\xe2\x25\x2f\x4c\x3d\xaf\xc3\xd2\x22\x8e\x71\xb4\xf6\x7b\x5e\x51\xb8\xfa\xa9\xe9\x4b\x89\x58\xb9\x54\xa8\xdc\x43\x10\xbd\xe9\x7e\xb5\x28\xc0\x76\xbf\x59\x2c\xfe\xcb\xc4\x8b\x16\x22\xa1\x7e\xb0\x2f\x9f\x9f\x9b\x4d\xb7\x61\x77\x96\x9a\x13\xbc\x9d\x3d\x24\x64\x68\x6d\x60\x2c\x72\x0f\xa5\xd9\x9f\x85\x9b\xb4\xb0\x19\xd6\x80\xb9\x6e\x3f\xd3\x3c\x3d\x9e\x69\xdd\x85\xc8\xa0\xce\x12\xc0\xa0\x41\x0b\x72\x3f\xc4\xb4\x75\xc6\x9d\x78\x08\xd4\x9a\x93\x78\xe6\x2a\xe9\x4c\x3a\xbd\xc8\x67\x68\xef\x4f\xf7\x55\x09\xc1\x12\xd1\x32\x8a\xd5\x48\xc2\xe2\xb2\xaf\xaa\x25\x95\xc8\xcb\xb0\x80\x02\x54\x9d\xb7\xa7\x7b\xa4\xd4\x9a\xbd\xb8\xe4\xae\x34\xd8\x57\x7e\x57\xfa\x75\xd0\x62\x9b\x5d\x2f\xcb\x92\xac\x9f\x56\x43\x34\xd6\x1f\x56\x69\x8a\x69\x9e\xab\xc9\x2a\xa6\xa4\x46\x37\xdc\x55\x3c\x77\xc6\x20\x1a\xd6\xf1\xae\xb3\x0d\x37\x57\x77\xcb\xb8\x6f\xe9\x6b\x3e\x9d\xee\x31\x3a\x10\xd3\xb2\x3f\xad\x13\xea\xe8\xdb\x36\xe0\x42\xb1\xb3\x07\xd4\x82\x32\x87\xf3\xbc\x93\xdd\xae\x75\x2f\xff\x5d\xd5\xdb\x1a\x60\xbe\x32\x85\xf6\x9a\x68\x7a\x86\x9b\x0d\x77\x33\x4c\x3b\x09\x8d\x63\x5d\x76\xe3\x75\x66\x40\xcc\x3a\xdb\x70\x82\x65\x56\x25\xbc\x7f\xa9\xab\xe3\xe1\x8c\xc5\x74\x16\x4f\xd5\x40\x29\x46\xad\x6f\x40\x87\xd0\x8c\x06\x29\x90\xc9\x6f\x5f\x95\xed\xcb\xa6\x9d\x59\xbc\x1a\x80\x22\x34\x18\x25\xa3\x67\x7d\x63\x63\x83\x6a\x23\x5f\x6f\xb6\xbb\xc9\x07\xb0\x2c\xc6\x08\xb0\x6c\x1a\xa8\xbd\x9e\xcf\xf5\xe9\xba\x1a\x2a\x40\xfe\x0e\x5c\x5e\x5b\xae\x30\x1a\x13\xea\x89\x36\xd2\x7e\x12\x6a\xd5\xd6\xba\x15\xad\x39\xaa\x7d\xde\x5e\x95\xcd\x3b\x72\xb4\x04\xa0\xe9\x5f\x70\xac\xb9\x8b\x98\x48\x3a\xfe\xde\x1d\xfa\xcc\x6e\xc6\x19\x47\xc8\x71\x5b\xd5\xf7\xd0\x3d\xc5\xdc\x9a\x33\x31\x71\x5c\xc7\xad\x6c\x5e\x91\x0b\x61\x1a\xf4\x33\x71\x1a\xe1\x04\xb6\xc7\x12\x37\xd4\x51\x95\x8b\x89\x95\xa3\xfe\xeb\x36\xa4\x9f\x79\xf9\xdc\x60\xae\x33\x9e\x45\x9d\x4c\xac\x8c\xf2\xf8\xaa\xef\x65\x53\x15\x66\x5c\x5b\x6b\x08\x8d\xd3\x9e\xb8\x72\x57\xe4\xe5\x6b\x2f\x58\xc2\x0d\xc9\x28\xa6\xfa\x1d\x57\xde\xb1\x29\xce\x94\xe9\xc7\x0a\x68\xbf\xb6\xe7\x0c\x8d\x33\x64\x0b\x58\xfc\x5c\xd4\x58\x6c\xeb\xaa\xe6\xc3\x51\x9d\x20\xb6\xf6\xf0\x76\x70\x41\x16\x03\xb5\x57\x2a\x9b\xbd\x4f\x12\xa5\x4e\x78\x48\xd6\xe6\x5d\xd6\xd3\xaa\x54\x93\x50\x85\x86\xf0\x7d\x05\x46\x8e\x87\x95\x49\xb2\x14\xc9\xae\x07\x31\x7a\x99\x85\x63\xa9\xf0\x9c\xfa\x58\x64\xb0\xf1\x64\x8d\x97\xcd\x4c\xc3\x93\x84\x0c\x0a\xb4\xdb\x97\x1a\x1a\x54\xfa\x9b\x3e\x26\x57\x80\xd2\x71\xbd\xd9\xe0\x20\x4b\xe3\x7a\x8f\xff\x8b\xfd\xd4\x32\x42\x44\x28\xdc\x00\xa5\x71\x54\x2b\xbd\x69\x60\x84\x36\x81\xfa\xf0\xac\x38\xd1\x64\x91\x45\xc7\x63\x51\x80\xac\x17\x98\x35\xed\x37\xf2\x70\x81\x8c\xc9\x98\xf8\x84\xca\xa4\x43\x32\x0b\x8e\xc5\xc5\xbf\x6e\x67\x35\x5d\x42\xb9\xcd\xbe\xa3\x04\xe1\xd8\xe4\x11\xd2\xb2\x7b\xbf\xa4\x0d\xc0\x8d\x52\x22\x54\x8f\x94\xa4\xb3\x55\x1d\x23\xcd\x64\x8a\x1a\x65\x14\x78\x6c\xcb\x8f\x5c\x43\x67\xba\xe4\x06\xca\x16\x6e\xe0\x1e\x1a\x79\xc6\xb1\x33\x3d\x5b\x33\x82\xd4\x4e\x7d\x15\xc3\xaa\x6c\xa1\x86\x4f\x78\x27\xb9\xd1\x52\xa2\x79\x7a\x7d\x9c\x74\x83\xd6\x4e\x8a\x71\xd9\xbe\x6c\xc6\xfa\xd9\x73\x34\x92\x31\x44\xe2\xd3\xfe\xf0\xf5\x06\x8b\xbc\xed\xe1\x81\x2b\x2f\xc3\xf7\xc9\xad\x8d\x60\xc8\x8f\xe9\x2a\xe8\xe7\x99\x78\x63\x20\xc6\xd2\x31\xdc\x22\x8e\x87\xc9\xe3\x41\xca\xd1\x34\xd4\x2f\xdd\x38\x2f\x9f\x11\x04\x71\x7b\xec\xbe\x30\xd6\x01\x9b\xd3\xd9\xf7\x3a\xab\x9f\x1a\xd7\x54\x85\xcb\x66\x9a\x41\x70\xe7\xa4\x2e\x00\x67\xa3\xd7\x5c\x1a\xdb\x24\xc6\x72\xc0\x4c\x92\xe7\xd6\xf9\x59\x9d\x17\xa8\x18\x2b\x23\xac\xd4\x28\x46\xa0\x34\x88\xb8\xc1\x08\x8d\xe9\xdc\x31\xdc\x78\xbd\xbc\x50\xdf\x40\x31\xec\xd0\x80\xa3\x9e\x80\xe0\x27\xdf\x1a\x22\x23\x7a\x59\xbd\xfa\x6d\x66\xd5\x43\x04\x9c\xb3\x09\xef\xd9\xda\xae\xca\xa6\x1d\xad\xa4\x10\xc7\x80\x81\xe8\x2b\x63\x9c\x90\xdb\x18\xf9\x05\x24\xd5\xd4\xa1\x54\xce\xaa\x2c\x80\x58\x17\x26\x3c\xd4\x20\xfb\x8c\x60\x33\x53\x20\xe2\x40\x23\x81\xeb\xcb\x56\x96\xaf\x73\x89\xa4\xd0\x24\x36\x98\x6e\xc5\x52\x20\x44\xa7\x9f\x2b\x5c\x73\xa0\x52\x62\x8c\xe0\x07\x56\x54\xcc\xc4\xad\x3e\x5d\x6d\xfd\xc9\x09\xc4\xd6\xdf\x62\x23\xf3\x90\xee\xf5\xb6\xdd\xc8\x5f\x80\x54\xbb\xd8\x90\x7f\x25\xf8\x44\x0b\x62\xfa\x02\x2c\xd1\x51\xd4\xeb\xfc\x57\x63\xe2\x4f\xde\x39\xbf\x42\x4e\x90\x6a\x48\xfd\x3f\xeb\x03\x9e\x3a\x4a\x62\xc4\x94\xf5\xc4\x26\xd3\x97\x10\xbe\x54\xf0\xf6\xa8\x5f\xff\xa6\xe9\x0c\x22\xb1\x68\x6a\xa1\xfc\x46\xbf\xbf\x81\x48\x53\x2a\x07\xa9\x5a\x3f\x77\xab\xf9\x97\xc9\xc0\x4d\x07\xbf\xe5\x5c\x17\x52\xbf\x8e\x29\x6c\x7d\x33\x49\x33\xed\x90\xff\x16\xea\x5a\x16\x37\x55\xd9\x0f\x30\x99\x71\x74\x71\x7e\xc4\x67\xf1\xe9\xee\x18\xf8\x80\xf0\xf5\xf6\xeb\x00\x62\xbe\x54\xc5\x05\xd2\xc4\x8e\xb7\x31\x7f\x7e\x69\x79\x32\xeb\x1b\x09\x8e\x89\xa2\xeb\xe5\x12\xf9\xfb\x96\x5e\x69\x6e\x78\x12\x70\xf4\x66\x77\x5f\x26\x04\x46\xa0\x6c\xea\x64\x99\x90\x57\x09\x97\xef\x85\x6c\xda\x7e\x1d\x02\x1d\x5b\x39\xe1\xe4\x71\xd5\x19\x55\x61\xaa\x63\xff\x99\xb5\x4a\x71\xd6\xde\xaf\x1e\x56\xbb\x2f\x57\xf7\xcb\xdd\xf5\x72\xfb\x73\xb9\x7c\xc0\x84\xd6\xd0\xca\x49\xff\x94\xc7\xfd\xb5\xac\xeb\x1c\xea\xe6\x11\xea\xeb\x6a\x60\x97\x00\xad\x63\x07\xa7\x44\x7a\xcf\x4f\xe4\x7e\x39\x18\x6a\x83\x66\x18\x92\xdf\xe7\x3a\x3f\xc8\xb2\xdd\xb5\xd5\xa1\xd8\xc9\x4b\xf8\x55\x30\x3c\x49\x69\x5f\xab\xf7\xd3\xeb\xd1\xcd\x3a\xd2\x18\xa3\xc8\x08\x23\x74\x65\xf6\x79\x89\x74\xad\x6d\x55\x3b\xe7\x65\x76\x82\x15\xc2\x49\x50\x1d\x0a\x28\xf3\xe6\x65\x08\xbe\x80\x8d\x1d\x76\x40\x41\xd3\xee\xa4\xf9\xf7\xb1\xf1\xa6\xe3\x30\xe1\x6c\x22\x91\xa1\xce\x59\x86\x8b\x1a\x4c\xb5\xd2\x9f\xbd\xb4\x55\x16\xad\x07\xc4\x88\xe5\x23\x30\xb9\x8d\x04\x80\x71\x19\xfa\xbc\x69\x37\x47\x75\xc6\xa0\xcf\x6d\x64\x04\xd6\x3f\xcb\xb6\x95\xfa\xf5\x7b\xf9\x19\xac\xc3\x46\xc6\xa2\x07\x73\x0d\xad\x96\xcd\xcb\x5f\x4f\x33\x1b\xd9\x08\xb1\xec\xf6\xd8\xeb\xcd\x8e\xfe\xeb\x1b\xd1\x18\x90\xca\xcd\x56\xf5\xa5\xcc\xe4\x88\x8c\x98\x5b\xaa\x5d\xa6\xe9\x1e\x9a\x7e\x8c\xd9\x84\x00\x04\x64\xe3\xf5\x5d\xae\x02\xe9\xb3\x3f\x9c\xb2\x40\x7d\x32\x4b\x04\x4e\x5d\x0c\x9b\x66\xd6\x20\x60\xfa\x19\xbc\xbe\x78\x83\x96\x1f\x72\x3c\x0d\xca\x7c\xdc\x32\x2b\xfa\x18\xb5\x63\x21\xac\xaf\xa5\x79\x9e\x05\xe6\x2d\x4f\x1c\x52\xab\xcd\xd1\xe7\xbc\xae\xf6\xa1\x34\xc2\xf2\x54\x20\xf5\x19\xba\x9a\x0b\x79\xc8\x5b\x19\x70\x4b\x7d\x13\x4b\x11\xdf\xbd\x97\x75\xbf\x41\x5c\x66\x03\xf5\x27\x08\x19\xe1\x30\xc6\x46\x4f\x73\xe1\x5c\x6e\x33\xc3\xd0\x76\xbf\xc9\xdf\x06\xee\x11\x2b\xe3\x28\xf2\x3b\x00\xc6\xda\x2f\x7a\x47\x56\x26\x4e\x3d\x03\x61\x04\xd7\xb9\xb9\xa0\x97\xdc\xb9\xfa\x16\xe5\xd1\xc0\xe1\x4e\x03\xd6\xc8\xaa\x14\x6c\x1a\xd4\x20\xc7\xec\xbc\xdc\x2a\x9e\xa0\x66\x55\x00\x37\x3e\xc0\xfb\xa7\x6a\xd9\xdc\x2a\xe1\x20\xe9\x7b\x57\x0d\x8d\x54\xd1\xb2\xa9\xc6\x3a\xd8\xdc\xea\x58\x65\x6a\x64\x26\xcc\x82\x53\xc3\x14\xb3\x9a\x50\x74\xe8\x9d\xa5\xf2\x00\xef\x98\xa7\xf9\x55\x30\xcb\xea\x4c\xa0\x47\xdd\x04\xc1\xd8\x55\x89\xfa\x0e\x47\x59\x8c\x26\xaf\x35\x91\x23\xb5\xdf\x2e\xaf\xee\xbd\x7c\xdf\xc3\xf6\x29\x30\xa1\x59\xd3\x59\x20\x03\x57\xf2\x08\xa4\x6b\x81\x70\x2c\x4b\x46\xb4\xfb\x21\x60\x9b\x37\x53\xd8\x7b\x6f\xa7\x85\x93\x94\x56\x41\x52\xa6\xb3\x8a\xae\xf3\xf6\xb6\x90\x67\x25\xd3\xbe\xb5\x4d\x1c\xd0\xe9\xe7\xfa\x66\xb9\x58\x6e\xbe\xae\xae\x57\x7f\x63\x26\x5b\xa5\xa4\x0c\xd4\x5c\xb6\xaa\xbd\x7c\xf0\xa8\x8d\x88\x62\xaa\x13\x5f\xda\xfb\x50\xb5\xb3\xa8\x04\x89\x2e\xc0\xa8\x44\x14\x33\x97\xc7\x40\x23\x47\x57\xfb\x7d\xe7\xd4\xb8\x2a\xda\xbe\x43\x45\x14\x0b\x9d\x90\x00\x81\x43\x64\xc5\x84\x37\x39\xb4\x92\x52\x38\x70\x81\xdb\x29\x6f\xeb\x6a\x8f\x56\xe2\xe4\x8e\x24\x92\xb1\xe8\x09\xd8\x5d\x30\x68\x40\x42\x8b\x88\x12\x86\x70\xad\x1f\x50\xb6\xb2\x1c\x7b\x85\x22\xa2\x2c\xc1\x84\xc7\x5d\xf5\x1c\x50\xbe\xbf\x5d\xc0\x6b\x8b\x28\xe1\x12\xa7\xd5\x53\xa5\xaa\x76\x54\xc1\x25\xa2\x94\x08\x04\x7f\x37\xad\x0c\x28\x3e\x11\xa5\xa9\x40\xaf\xeb\xad\x6a\xa1\xb9\x01\x5d\xf4\x0a\x1e\x22\x4a\x05\xc7\x63\xdf\xcb\x5c\x57\x75\xe9\x08\x4f\x7d\x64\x7c\xd6\x01\x8c\x02\xe6\x2c\x10\x98\x54\xc0\xf3\x58\xd3\x65\x56\x99\x77\x69\x6c\x88\x88\x47\x3a\x41\x6a\x02\x5d\x8d\xa0\x3b\x22\xe2\x92\x61\x56\xf8\xfd\x30\xe2\x4f\x98\x9e\x2a\x52\x47\x3f\xbd\xcf\x43\xd6\xe8\xb6\xaa\x1d\x49\xf6\x68\xf1\xec\xda\x59\x8c\xa9\x63\x08\x61\x21\x4b\xe4\x27\x58\x8c\xd7\xfd\x79\x45\x10\xfd\xd7\xd9\xad\x2c\xf4\x93\xe4\xbe\x33\x67\x66\x68\x3e\x11\x09\xc6\x90\x94\x34\x6f\xd0\x86\xfb\xe7\x18\xc8\x28\xa2\x2c\xd2\xca\x86\x54\xbe\x07\x47\x85\xe7\xcb\x0c\x41\x40\x25\x96\x6d\x3c\xc0\x87\x43\xfb\xf8\x83\x32\xd5\x18\x71\xbd\x3f\x4d\x62\xd9\xe1\xa8\x89\xc1\xc7\x4e\x36\x87\xaa\x6c\x2a\xdc\x6b\x10\x3b\x51\x77\xed\x02\x4e\xe7\x97\x2e\xb3\x88\x24\x48\x1a\xfb\x48\x8d\x0f\x0c\xe1\x3e\xb4\x2e\x9f\xe0\x0d\x64\xd1\x4c\xa5\xc2\xcf\xa2\xfb\x22\x52\xb1\x2b\x15\xf6\xe4\x19\xa5\x59\x96\xa6\x7a\x5f\xc4\x9f\x7c\x3a\x45\xa2\x94\x4d\xe8\xc6\x46\x64\x6b\x22\xd2\x9a\x26\x0e\xf8\xd0\xca\xbc\x9c\x84\x9c\x44\x64\x68\x44\xd2\xa9\xf2\xbf\xd7\x6b\x1c\xbc\xc9\xe9\x7a\x25\x22\x93\xe9\x74\x38\xc7\x8d\x91\x66\x55\xba\x4a\xb4\xe9\xa3\x81\x20\xb1\xb3\xa2\xe0\x4d\x16\xc7\xce\x6d\x5f\xac\xcf\xda\x70\x74\x33\xfa\xe2\xf7\xe1\x7b\x59\xab\x30\x6a\x88\xa8\xee\x91\x30\x8d\x88\xa3\x04\xd0\xbd\xff\x02\xed\xfd\xc9\xcb\xe9\xf5\xc7\xac\x2b\xbc\xd7\xd5\x7e\x60\x90\xeb\x0c\x34\xff\xf9\x7c\xb3\x38\x8e\xb1\x42\xf7\x3a\x64\x7e\xfb\x03\x24\xf5\xba\xd2\xa5\x59\x95\xdd\xda\xd2\x57\xf3\x88\x38\x56\x71\xe4\xc1\x0a\x5f\x47\x71\xce\x75\x39\x6a\xc1\x31\x67\xdb\xf6\xbb\x3e\x6a\x88\x5f\x1f\x3b\x3f\xf4\x22\xb6\x43\xc4\xb1\x8d\xb0\x46\x1a\x67\x55\x37\xea\x82\xc9\x80\x24\x3a\xc1\x3b\xed\xda\x39\x59\x16\x3b\x82\x05\x89\x98\xd0\x48\x8b\x90\x25\x96\x7a\xfc\xb8\xc4\x64\x2c\x68\x18\x4b\x17\x50\x9c\xf4\x7e\x4c\x6c\xcf\x7e\xe4\xd6\x1c\x53\xdd\xc0\xb2\xd1\x47\x28\xce\x43\x32\xd3\x53\x29\xf1\x9a\xcb\xcf\x4e\xce\xc1\x65\x01\x07\x10\x72\x78\x06\x9a\x48\x42\xfb\xd2\x83\x6e\x01\x3c\x04\x28\xff\xac\x1b\xa8\x4a\x94\x97\xa4\xb8\xaa\xdb\x95\xb9\x24\x53\x2e\xe2\x24\x8d\x30\x8e\xde\xfc\xe7\x98\xd7\x35\x14\x7b\x54\x06\x7a\x82\xff\x84\x1b\x26\x22\x46\x3c\xc8\x38\x3d\x7f\x9f\x7f\x12\x1b\x17\x71\x92\xb9\x5d\x41\x75\x7e\x60\x67\x67\x77\x8e\xc6\xa9\x99\x2f\x4a\x71\x92\x59\xc4\x34\x9b\xfc\x0d\xe2\xd9\x93\x27\xa0\x70\xed\xd8\xd6\x47\xef\x0e\x0f\x58\xd9\x69\xcb\x94\x68\xa4\x2a\xf0\xe4\xc5\x6e\x3a\x86\xc8\x52\x78\x03\x16\x3b\xda\xfc\xc7\x1a\x56\xba\x1a\x07\x3d\x45\xcc\x88\x41\x59\x32\x57\x49\xf2\xbd\x6c\xf3\x62\x54\x04\x2a\x62\x9e\xc4\x88\x3a\xbe\xbf\xfa\x7d\xf7\xf8\xb4\xdc\x5c\xdd\x2d\x37\xbb\xe5\xef\xdb\xe5\xc3\x66\xb5\x7e\xe8\x5b\xa5\x31\xd6\xee\x3a\x96\x5f\xd9\x74\x4b\xb8\xa3\x21\xba\x18\x08\x15\xb1\x48\x32\xe5\x93\xa9\xb9\x5b\x0d\x07\x4b\x35\x34\x01\xe5\x38\x73\x8f\xa5\xa9\x65\xde\x5c\x28\xdc\xfe\x55\xd4\xb8\xbb\x80\x06\xe8\xa1\x15\xdd\xe4\x9d\x97\xa4\xfb\x86\x32\x73\xaa\x5f\xc1\x4d\x3c\x91\xf0\x0c\x52\x45\x3a\xf6\x18\xbb\xd7\xcf\x69\x6a\x07\xa7\x44\xc4\xd2\xb8\xae\x58\xdd\x3f\x5e\x2d\xb6\xbb\xa7\xe5\x97\xd5\x66\xfb\xf4\xc7\xee\xea\xe6\xe6\x69\xb9\xd9\x84\x2b\xab\x38\x22\x7e\xa6\xdc\x56\xb5\x3e\xab\xcc\xf3\xcd\x34\x21\x18\x19\xca\x75\x85\x0b\x3d\x41\xe1\x8b\x6e\x61\xed\x61\xe2\xc3\x76\x1a\x6b\xc6\x31\x82\xed\xe7\x86\xbb\x12\x96\xcd\x77\x67\x14\xf3\xa0\x84\x88\x8d\x1f\xfc\x35\x14\xf2\x74\x7d\x3c\xe1\x26\xac\xa1\xf8\xab\x1a\xab\x7f\x8c\x63\x43\x44\xfc\x22\x99\x22\x62\x23\x6c\x20\xb7\xda\xc8\x42\xd6\x7e\x7d\xc4\x94\xc5\x84\x12\x3b\xb4\x37\xd9\x58\x34\xf4\x8c\x33\x54\xc4\xc6\x02\x72\x26\xdd\xad\x17\xdf\x96\x37\xa3\xd8\x81\x88\x41\x24\x81\x97\xf2\x93\x91\x07\xd6\xc9\x94\xc1\xb1\xae\x16\x50\xb6\xcd\xaa\x5c\x97\x30\xde\xe3\x62\x9b\x52\x4c\x60\xe2\x8f\xab\x7e\xb9\xb4\x22\x51\x9e\xeb\x10\x8b\x52\xa6\x0f\x65\x33\x81\x0f\xe5\x72\x7f\x3f\x57\x0f\x37\xeb\x9f\x3b\xb2\x5b\x3e\x4c\x1e\x90\x44\x9c\xe2\xf0\xb8\x3f\xfd\xcc\x9b\x97\xcf\x49\x29\x27\x17\x27\x91\x54\x59\xda\xcb\x54\xa3\x09\x35\x09\x88\x0a\x12\xc7\x0a\x21\x2f\xd7\xcb\x87\x7f\x0e\x49\x7a\x41\x62\x95\x39\x30\xbf\x23\xd3\x1c\xea\x12\x66\xf6\x32\x21\xdc\x69\xef\xb8\x95\xc4\xf1\x13\x7c\x5a\xfb\x29\x08\x05\x57\x26\xd5\x79\x35\x0e\xfe\xbd\x5b\x5c\x3d\x86\xbb\xa6\x2a\x45\x49\xfa\xce\xf6\xcc\x1b\xf9\x3c\x4a\x4b\x86\x16\xa0\xf4\x24\x02\xdf\x2d\xa9\x23\xde\x75\xdf\x8c\xa5\x51\xea\x94\x6d\x96\xed\xcb\x43\xb5\x2c\xf5\xc4\x78\x23\x8c\x5b\x44\x37\x14\xd0\xae\xda\xa7\x11\x77\xd6\xb9\xa5\x41\x98\x48\x3d\xc5\x51\x51\x7c\x83\xd3\x79\xc0\x72\xbc\x28\x10\x66\x5d\x35\x36\x9a\x85\xbf\xf5\x3f\x1a\xdb\x23\xbb\x1d\x77\x06\x96\x26\x76\x93\xe6\xfa\x34\xca\x8e\x09\xc2\x23\x83\x0e\x3f\xf6\x67\x40\x74\x85\x63\x49\x8a\x5b\x6c\x88\x1f\x05\x9d\xd7\xd9\x27\x11\x89\xe3\x2c\x7c\x86\xf6\xa1\xba\x40\x7d\xe7\x9b\x75\xab\x17\xf2\xdb\x7c\x5d\xde\x6d\x16\xeb\x20\xd3\x20\x48\x96\x80\x81\x81\x87\xa2\x7b\x82\x3e\x18\x27\x48\xc6\x13\x1b\x20\x73\x2e\xbb\x17\x26\xe6\x10\x64\xec\xdb\x5a\x57\x93\x8d\x94\xda\x3f\xf3\xf6\x05\x8d\x90\x4f\xa5\x48\x66\x63\x45\x32\x93\xba\x08\xf9\xfa\xfa\x29\x5c\x52\xd1\x2c\x19\xe8\xe7\xcf\x48\xb1\x04\x51\xa0\x32\xf0\x86\x13\xd4\x3b\x18\x44\x3f\x04\xd1\xcc\x01\xf8\xf2\x12\x0d\x94\x61\xd7\x20\x1a\x44\xea\x27\xe9\xe3\xca\x29\x28\x12\x16\x0e\x02\xcd\x18\x39\x27\xaf\x9a\x75\x3b\x18\x8e\x38\xaa\x63\xf9\x1e\x02\xf5\x7e\x29\x0d\x54\xb9\xd3\xf6\x96\x49\x44\x75\xed\xe5\xc7\x4f\xc8\x47\x33\x27\x1c\xcf\x12\x24\x81\x73\x61\xe4\x6e\x9c\xcf\xa2\xfb\x82\x58\x49\x71\x5c\x99\xca\x9d\x3e\x3d\x4c\x63\x19\xa7\x83\x9b\xd4\x1e\xa7\xe0\x09\x41\x63\xc5\xe3\x71\xd1\xed\x0d\xbc\x16\x72\xae\xbf\x31\xda\xa4\x28\x31\xce\xc6\xcb\x9b\xd1\xb7\x9e\xde\x93\xa6\x59\x64\x7b\x00\x04\x06\x6a\x1e\x6b\x68\xdb\x53\xb8\x29\xd5\x1c\xf3\x1e\x6d\x9d\x1f\x0a\x78\xaa\xaa\xfd\xbd\xfc\xe8\x0f\x1a\x05\xd9\xc0\x21\x38\xda\xd7\x69\x02\x0c\x8d\xed\xfd\x20\x39\x18\xa6\x28\x4d\xac\x2b\x5c\x72\x00\xdf\xa1\x48\xf4\x17\x71\x18\x41\x53\xaa\x78\x3a\xa8\x53\xde\xc8\x16\x7a\xdd\x68\x41\x59\xcc\x30\x56\xdb\xb3\x05\xdd\x55\x7a\x48\xb2\xfc\x72\xe0\x52\x46\x28\xe6\xa6\xd0\xfd\x1b\xdb\x7f\xfd\xc5\xb9\xc0\xa8\x77\xdb\xd9\x68\xe3\xe0\x00\x65\xdc\xe0\x56\x8c\xa7\xae\x4a\x5d\x21\x34\xf0\xfc\x02\xca\xc1\x85\x9e\x07\x92\x73\xbc\xcc\x68\x6f\xbf\xb8\xfe\x52\x66\x23\x04\xf4\x79\x46\xbc\x6f\x7f\x2c\x3a\xcf\xe4\x93\x02\xa1\xae\x39\xcf\x92\x7e\xed\x53\x52\x35\xfd\x13\x58\x05\xa3\x1a\x0a\x64\x52\x6f\xb4\x3c\xa0\xde\xe0\x7c\xa0\xd2\x6e\xf3\x8d\x06\x36\x61\x97\x02\xb8\x10\x30\xea\x21\xe9\xbf\xfa\x13\xae\x99\x39\x69\xa1\x97\x51\xc8\xd1\x1f\xca\x88\xa3\x8a\xed\x96\x9c\xd1\xae\x46\x25\x21\x74\x28\x16\xc5\x31\x0c\xb5\x33\x6c\x2f\xd1\x52\x08\x2a\xb9\x0d\x3c\xc5\x33\x05\xf8\x59\x3b\x61\xe2\xd8\xe3\x40\x5d\x9d\xc3\xe0\x0a\x52\x29\x55\xa8\x67\xfa\x29\x9f\x61\x9c\xc2\x12\x54\x33\x81\xde\xc6\x63\xde\xad\x91\xdd\xf2\x08\x03\x27\xc0\xa5\x68\x17\xd5\x8a\x89\x38\xb0\x24\x7e\x40\x3d\x77\x90\x7c\x33\x43\x24\x06\xc5\x0a\xb0\x6d\xf5\x06\xf5\x4f\xc8\xa7\x91\x03\xdf\x0e\x8c\xe1\x51\x9f\x28\x1e\x71\xa1\xf8\xe3\x96\x24\x92\x7c\x12\x28\x99\xef\x95\xd4\x6a\x8b\x6b\xd6\xf6\x3e\xec\x26\x49\x4c\x04\x56\x89\x7e\x95\x7f\xfe\xe9\x02\x61\x98\xb9\xb6\xb2\xf7\xcd\x12\x12\xc5\x3e\x91\x76\x4a\x87\xdf\x80\x7a\x91\x09\x8c\xbe\xb8\x4f\xb9\xc7\x6f\x80\x66\xc8\x59\x68\xc0\x9f\x48\x19\x63\x74\xb0\x03\x57\xd7\xdb\xc5\x45\xa6\xac\xd0\x3c\x8b\xb1\xb4\xe2\xe8\x1c\xa6\xc7\xaa\x3c\xb9\x4a\xe7\x51\xaa\x61\xd4\xda\x68\xd4\xab\x5a\xde\xdd\x86\x07\xa5\x90\x44\x9e\xc0\x0f\xd9\x9a\x1f\x82\x60\x5a\x77\x88\x13\xcf\xf9\xfd\x06\x75\xbb\xad\xae\xb6\xdf\xa6\xbb\x55\x92\xc8\x08\x81\xc0\xdb\x1c\xea\xbc\x2a\xbd\xea\xf8\x78\x49\x48\x52\x99\x28\x3a\x44\x7a\x67\x17\x60\x11\x60\x8a\xe8\x1e\xca\x63\x94\x85\x73\x58\xc2\x13\x9f\x9e\x5e\x9e\xa0\x39\xa7\x24\x10\x09\x87\x04\x0d\x95\xeb\x22\xf7\xd4\xf0\x43\x35\x83\x48\x44\xea\xf4\x04\x6f\x3b\xc3\x20\x4e\xe3\xec\xaf\x8a\x59\x45\x22\xb2\x18\xc3\x65\xcb\xfb\x98\x90\xfe\x3a\x99\xc4\xc1\x7a\x2f\x3f\xfc\x3a\xe6\xf0\xe2\x6e\x67\xd8\xf5\xcd\x8c\x57\xe3\xc2\x79\x86\xd5\x90\x63\x19\x48\x91\x64\x34\x13\x5d\x27\x7c\xa9\xbb\xb1\x7c\x7d\xec\x25\x36\x45\x92\x01\xa0\xe7\xfc\x5c\xb5\xfe\xcb\xf9\x03\x52\x5b\xe2\x8b\x6d\xda\xaa\x86\xab\xa2\xd8\xc2\xfe\x70\xa1\xfe\x5a\x24\xca\x70\xda\xdd\xff\x43\xeb\x70\xb6\x56\x0c\x45\x6a\x97\xdb\xaf\xbb\x6e\x1f\xda\xdd\x4a\xdd\x33\x6f\x89\xc4\x10\x89\x9c\x00\xcd\xa1\x06\xe9\x52\xe6\x87\xa2\x27\xa1\x10\x89\xc9\xd2\x00\x6b\xb7\x79\xbd\xbf\x0f\xb1\xf8\xa1\x62\xea\xcc\x90\x0c\x67\x2a\x83\x26\xee\x1b\xd4\xb9\x3d\xf5\x8c\x5f\x93\x59\x99\xd8\x8c\x3a\xa8\x59\x9d\x6b\x58\xdb\xb5\xb5\xb9\x96\x08\x08\x1c\x54\x21\x45\x62\x8d\xba\x10\x4c\x3c\x03\xb3\x8f\xc2\x7e\x69\x44\x1c\x8a\x06\xd9\x10\x31\x0e\xd1\x86\x82\x01\x91\x46\x5c\x0a\x13\xe8\x8a\xfe\x0c\x18\x4d\x91\xc6\xa0\xd0\xe2\x54\x58\xf8\xa4\x3f\xdb\x4e\x52\x42\x2d\x6a\x00\xc9\xe6\xf5\xb6\xaa\xb1\x36\xf5\xb7\x59\x0b\xc6\x30\xad\x71\x8f\x75\xf4\x4d\x0b\x75\xd8\x73\x6b\x38\x8b\xee\x86\x73\xbc\x20\xad\x2b\xe3\xac\xaa\xc2\x69\x51\x85\x01\x92\x12\xe1\x34\x58\xa5\x0b\x63\x61\x0d\xd2\xbc\x0e\x59\xa4\x34\x71\xfe\xa3\x2e\x72\x6b\x6f\x82\x01\xe1\x0f\x26\xc4\x60\xf5\x63\xb0\x76\x27\x59\x3f\x91\xa6\x51\x8c\xe1\xf5\xc3\xb1\xdd\xa0\x9c\x6a\x38\xfe\xab\x40\x79\x9a\x6a\x87\xb4\x6b\xa0\x5d\x7e\xb4\xb5\x74\xa6\xcb\xdf\x42\x27\x0f\x17\x61\x94\x82\x0b\x6e\x62\x4a\x63\x1d\x62\x77\xe1\xd1\x18\x27\xb1\xd7\x05\xa8\x9f\xbb\x39\x30\xeb\x70\xa6\x15\xa6\x12\x56\x8b\xf5\x7d\x5e\x6e\x3d\xb2\x2c\xe0\x51\x2e\xb9\x38\x29\x4f\x20\x66\xa1\x84\xbf\x69\x6e\xc2\xad\x78\xca\x7c\xee\x4e\xaa\x02\xe6\x75\xf6\x22\xe5\xc2\xc4\x8e\xaa\xa4\x7a\xf7\xc4\x8f\xd2\xc2\x98\x3b\x7c\xf6\x6e\x1c\x54\x50\x75\xdc\xca\xe7\x19\x57\xac\x48\x3b\x13\xc0\xf3\x42\xb9\xb8\xec\xda\xfa\x4d\xba\xff\x30\x82\xbb\x58\x9e\x92\xe6\xb9\x57\xe2\x0b\xc7\x32\x07\x05\xeb\x0c\x84\xdb\x22\x3f\x1c\xfa\xc9\x9b\x0a\xe5\x1c\xad\xaa\xee\x5c\x88\x4f\x0b\xca\x45\x2a\x40\xd9\x81\xd3\xf7\x47\xde\x48\xa4\x0a\x1c\x0b\x81\x7d\x06\xe5\xbc\x84\x30\x13\x9d\xf1\x8c\x35\xe6\xba\x00\x59\xf7\x0a\xa2\x97\x10\x4a\x22\xcd\x88\x71\x9c\xba\x45\xd5\xc0\xcf\xaa\xde\xbf\xf4\x92\x06\x22\x95\x9d\x83\xe1\x08\xfc\x74\xf7\x91\x56\x3f\xfa\xef\xa4\x22\x8e\x5e\x59\xd3\x56\x87\x95\xae\x7c\x59\x7d\x7f\x94\x10\x11\x78\xb7\x5d\xe6\x00\x43\x29\x9f\x64\x40\x45\xaa\xd2\x14\xc9\x9f\xd0\x62\xdd\x40\x01\x7a\x3c\x71\x94\xe4\x99\x08\xc2\x6e\x6d\x0e\x41\xe8\x2b\x1c\x36\x29\x12\x96\xd4\xc7\x72\x14\x3c\x4f\xb5\xc8\x30\x76\xea\x44\xb3\x66\xc8\xa6\xd9\x27\x30\xd4\x60\xfa\x77\x9f\x97\xed\x24\x49\x97\x1a\x96\x32\x2f\x77\xb5\xb9\x7f\xf4\x85\x85\x38\x04\x1e\xd1\x1c\x9a\x0d\x27\xc3\x9c\xe9\x6d\xf3\x32\x6f\x5e\x3c\xc8\x3b\x3c\x11\xa4\x89\x70\xdd\x89\x6e\x63\xcf\xb4\x28\x52\x10\x02\xd1\x31\x79\x0b\x67\x20\x73\xa7\x01\x33\x7e\x61\x30\x4e\xd1\x7f\xbf\x0b\x80\xa6\xd9\x56\x94\xda\x24\xc1\xc8\x69\xe9\x87\xf4\xcf\xbc\x5f\xc9\x58\xa4\xc1\x74\x8f\xb8\x5d\x2d\x9f\xe2\xbe\x8e\x5b\xb0\x98\x50\x18\xe8\xf4\x4f\xf3\xa0\x31\x8b\x53\x40\x56\xc2\x5e\x92\xb2\x34\x8f\xf2\x13\x14\x9f\x3f\x85\x44\x44\xab\x81\xbc\xc5\x93\x7b\x78\x4a\xaa\xcb\x26\x27\x23\x3c\xc5\x0c\x6b\x5e\xb6\xb9\x9c\x64\xe9\x05\x23\x8a\xa1\x85\x0c\xdd\x4a\x87\x71\x70\x7f\x80\x12\x8a\x69\x41\x59\x14\xdd\xa2\x30\x36\x8e\x19\xf5\xf8\xc7\x26\x7f\x0e\xc5\x1e\x17\x83\x85\x8c\x5a\x8e\xf3\xf0\x26\x7f\xce\x1f\xa1\xa9\xc2\x05\x92\x2c\xb6\xda\x0f\xe6\x27\x00\x74\x7f\xfb\x47\x4a\x34\x75\x35\xa5\xe3\x4a\xaf\x8d\xe3\xf6\x9f\x6e\x0e\x2c\x01\x9e\x04\x62\xf3\xbc\x6d\xfb\x9d\x8f\xa5\x91\xf5\x78\xff\x57\x28\xbf\x40\x09\x6e\xdf\xb8\x1b\x42\xe1\x2c\x15\x19\x52\x0d\xee\x9e\x1d\x3c\xe2\x1b\x9c\xf5\x7c\x68\x29\x29\x77\xe1\x09\x27\x08\xbd\x8b\xfb\x6b\x48\x40\x40\xc2\x8b\x6c\x9e\xaa\xe2\x6c\x41\x98\xf5\x46\x6a\x74\xd2\x03\xde\x50\x26\x7a\xd2\xab\x3c\x49\xb1\xce\xb7\x1d\x73\xea\xb7\xd5\xb7\x3f\x16\x9f\x3c\x17\x57\x4e\x4b\xe0\x19\xda\xf5\xc3\x97\xa9\xaf\xc5\x84\x17\xe8\x76\x08\xeb\x6d\xbe\x1f\x69\x6c\x08\x26\x32\x22\x03\x38\x10\x6b\x84\xbe\x1c\x65\x2d\xcb\x76\xa6\x6a\x2f\x98\xd0\x3c\x1e\xcb\xd6\xdf\x0e\x8a\x84\x82\x65\x91\x26\xae\x68\xe1\xea\x4d\xe6\x28\xdf\xdf\xf5\xf0\xa6\xa8\x3e\x89\x33\xb2\x8c\xd8\x98\xfb\x90\xcd\x3d\xd4\xaf\x05\xdc\x80\x95\x9d\x71\x78\x4e\xf5\x7f\x71\x25\x66\x99\x76\x6e\x56\xde\x34\x47\x9f\x28\x9a\xa6\x2d\x59\x66\x04\xf3\xd6\x95\x5b\x56\x9a\xdb\xaa\x76\x85\xa0\x5e\x50\xf1\x93\x30\xb8\x3f\x5f\x5a\x85\xce\xc4\x73\xfe\x06\xab\x0b\xab\x87\x6f\xa6\x48\x86\xcc\xdc\x6e\x41\x68\x26\x9f\x52\x51\x1e\xa8\x94\xd5\x28\xfd\xc2\x94\xe0\x34\xeb\xe1\x68\x30\xa9\x42\x11\x4c\xe9\x18\xd3\x6d\x8e\x31\xf5\xfa\x84\x38\xb4\x79\x50\x85\x69\x1a\x83\xab\x4a\xf9\x7d\x33\xf5\xa0\xc2\xdf\xc9\x63\xea\x54\xa1\xfd\x84\x08\x9d\x9f\x2f\x00\xc5\x6d\x5e\x62\x5a\x69\xb2\x0e\x18\x4b\xe9\x10\xd5\xfa\xac\xbc\xf2\x1f\xf3\x15\x0c\x62\x27\xa3\x78\x75\x34\x79\x3b\xad\xaa\x17\x0c\x38\x0b\xd1\x90\xed\xc0\x64\x31\x26\x91\xec\xda\x64\x2e\x70\x8c\x5b\xda\x6d\xfe\x01\xc6\x15\xf0\xfc\x38\x58\x67\xd9\x9f\x2e\x29\x23\x8c\xc7\xc7\xdc\xe1\xbc\x6c\x91\x31\x50\x54\xf1\x41\xc2\xca\xf7\xfd\xd4\x62\x64\xa0\x49\xea\xa1\x30\x0f\x55\x2b\xeb\xd3\xa3\xac\x35\xcc\x8c\x33\x66\x09\x43\xd1\x93\xeb\xfc\x19\x5d\x9e\xb1\x5f\xc8\xac\xd0\x3a\x0c\x3f\xd7\x8d\x38\x27\xda\x11\x60\x23\xb4\x54\x22\x1b\x48\x74\xd1\x4b\x6d\xc6\x00\x9c\xc9\x4d\x79\x0c\x19\x72\xcb\x3a\xe1\xfb\x42\xe6\xfb\x9f\x32\x6f\x87\x82\x27\xdf\x8c\x46\x60\x3d\x9c\x06\x6b\x9b\xbd\xe2\xc3\x64\xa4\x71\xca\x4d\x50\x42\x5c\xb6\x2f\x9f\xc2\x02\x05\xa7\x36\x32\x2c\xdc\xb4\x73\x44\x7b\x6e\x3c\xc1\x93\x48\x60\x1d\xb0\x3d\x96\x26\xec\x60\xfd\x31\x6a\xd1\x4b\x7b\x87\xfc\x3e\x2f\x2f\x00\x2a\x78\x4a\x08\x1a\xb8\x28\x5a\x36\x04\xf8\x78\x9a\x70\xb4\x62\x7b\xe4\xd6\x56\x96\xaf\x5f\x8f\x81\x17\x5e\xf0\xce\xce\x45\xb7\xc1\x15\x4d\x0f\xcc\x57\x82\x33\x92\x04\xfd\xbb\x2f\x75\xbe\x7f\x02\x79\x80\xba\xb9\x7a\x96\xdd\xca\x3d\xce\x09\x71\x96\x11\x24\xf6\x6a\x87\x54\xfa\x55\x69\x90\x7e\xfe\x42\x80\x95\x33\x9d\x39\x19\xb2\xe5\x62\xfd\x70\xb3\xbb\xfa\xbe\xd8\xae\xd6\x0f\x9b\xdd\xea\x61\xb5\x5d\x5d\xdd\x05\xa6\x9c\xab\x2f\x21\x31\xc4\x39\x71\xc2\x0a\xcf\xd0\xee\xda\xc1\xb9\xdc\xe9\xd1\x32\xc1\x79\x62\x3c\xcf\x4f\x37\xc4\xf5\x08\x24\x2a\xb8\xa0\x2a\x4a\x7a\x46\x87\xfb\xef\x77\xdb\xd5\xe3\xdd\x6a\xf9\xb4\x5b\x2d\xd6\x21\x02\xce\x05\xb7\x98\x12\x28\xe1\xa3\x9d\x45\x91\xb9\x10\xc0\x44\x98\x7d\x01\xb3\x23\x8b\x91\x8d\xc4\x33\x2a\x30\xcb\xd4\xba\x54\x82\x57\x2f\x1b\x7b\x58\x3c\xcb\xe2\x24\x68\x62\xe6\xa6\xb9\x83\xf2\x39\x60\x5d\x05\xcf\xc0\x31\x86\xfe\xcf\xfa\xe9\xe6\x2a\x44\x96\xb8\x24\x8e\x33\x2f\xa0\xf4\x1e\xe4\x1e\x7e\x2f\x3d\xe3\xf7\x8d\x3c\x9c\xd7\x97\x8d\x5e\x5b\x1a\x29\xa3\xd1\xc9\x8f\x47\x35\xde\x98\xc7\x1f\x45\xa5\x8e\x84\x15\xbd\x68\xf9\x5e\x0e\x9c\x34\x53\xa2\x09\xc1\x95\x4e\x70\x4a\xfe\x5c\x7e\x59\xfc\xd6\xff\xe6\xc2\xfc\x3f\xf2\x6e\x91\xc9\x61\x52\xc1\x2c\xb8\x02\x82\xe8\xd6\x51\x8d\x50\xd2\x59\x09\x3b\x3f\x3f\x42\x3b\x4d\x8d\x03\x40\x76\x8b\xe9\x20\x43\x35\xdc\x5b\xa7\x06\x0d\x7e\x89\xfa\x94\x5e\xd8\xed\xb2\x0a\xf2\xfc\x44\xeb\x7d\x24\x5f\xc7\x80\x09\xdd\xe9\x12\xc2\x75\x96\xf0\xc0\xf5\xd6\xca\x67\xb8\x7a\x83\xce\x4c\x9a\xeb\x61\x09\xae\x21\xc2\x48\x4a\xdd\xad\x32\xf1\x68\x0c\x18\x22\xd1\xa6\x5f\x6e\xbf\xee\x16\x4f\x3f\x6f\x30\xf9\x37\x1c\x54\x18\x58\xb8\x3e\x9e\xee\xd7\x7f\x4c\xd7\x10\x93\xb9\x13\xbb\x11\xee\x19\x05\x76\xfe\x59\x77\x30\x0f\x57\x72\x63\x34\xe6\x23\x83\xfb\xb9\x7c\x83\x99\x5f\xc0\x21\x65\xa1\x6a\xe0\xeb\xcf\x85\x77\x19\x2f\x6f\xbe\xdc\x0a\x83\x0a\x0b\x6e\xab\xf4\xe8\x92\xdf\x2e\x18\xcc\x22\x22\x02\xe1\xad\x8d\x5b\x26\x97\x8e\x4c\xf3\xb7\x70\x94\xc5\x08\x4e\x97\x87\x03\x94\xe6\x1b\x9c\x5c\x48\x6e\x1a\x1f\x08\x6d\x45\x84\x51\x1b\x64\xae\x0c\xf5\xbc\x97\x43\x6f\xd3\xa7\x15\x91\x72\x98\xd1\xbb\xea\xd9\xd9\x21\x8f\x8b\x0b\x78\x7f\x21\xe2\x0c\x22\x87\x0b\xfe\xd8\xd6\x32\x2f\xa1\x76\xf4\x97\xfe\x30\x21\x1c\x5d\xaa\x85\xac\x6f\xa0\x1e\x98\x48\xa7\x37\x23\xd2\xe0\x0b\xff\x90\xae\xc6\x7b\xd0\xe0\x11\x82\x02\xc7\xe4\xfd\xa3\x3c\xa1\xff\x32\xbd\x7d\x92\x90\x24\x1e\xed\xd7\x0b\xd9\xc2\x73\x35\xa8\x19\x0a\x91\x48\x67\x9a\x2b\xdc\x5c\x26\x7e\xbb\x60\x46\x4a\xd2\x57\xce\x39\x28\xe3\xfc\x23\x4e\xef\xc7\x33\x63\xc4\x00\xe4\x9b\x94\x1c\x5d\xee\x48\x9e\xb9\x8a\x6a\x67\xa5\x5c\xe7\x41\x88\x2d\x1c\x96\x9a\xa2\x5e\x7d\xcf\x8f\xdc\xb4\x93\xf0\xa0\x10\x1c\xd0\xf1\x08\xa9\xb5\x5b\x2c\xb2\xfd\x30\xf0\xd6\xbc\xf4\xf1\x34\x91\x45\x29\x46\x7f\x1b\xe9\xa0\x41\x17\xc2\xaa\x22\x4b\x9c\x96\xac\xad\xe5\xd8\xb3\x16\x92\x4a\xcf\xa5\x7a\x11\x43\x3a\x97\xe2\x98\xf9\xef\x33\xea\xb4\x69\x7f\x49\x20\xe9\x40\xdb\xfd\x6f\xd0\x6d\x13\x16\xfd\x8b\xe9\x0f\xa1\x22\x81\x55\x9b\xc1\x67\x5d\xd4\xa7\x4d\x55\xac\x15\x9e\x1a\x1e\x58\x11\x83\xdf\x6d\x17\x9e\xf8\xc9\x97\xb4\x5c\x9e\x05\x4a\x30\xee\xa3\x4c\xdb\xfa\xd8\xb4\x30\x2f\x2e\x0e\xed\x32\x8e\x50\x97\xeb\xef\xbf\x8f\x92\xd8\x42\x59\x25\x7b\xfa\x07\xa9\xdb\x1b\x27\xbc\x3f\xa6\xaa\x17\x42\x13\x8e\x85\x78\xf9\x50\x5b\x05\x13\x61\x94\xd0\x2e\x25\xb8\xa8\xfd\x80\xf2\xd8\x8c\x12\x4a\x42\x1b\xa7\x65\xdc\x39\xde\x33\x8f\x46\x18\x1d\x7b\x22\xda\xb2\x84\x7a\x27\xcb\xb2\x3a\x96\x9f\xc6\x46\x05\x78\x4f\x69\xbd\x87\x67\xf9\x58\x57\x6d\xa5\xab\x30\x23\xb3\x28\x03\x3e\xce\xd4\xde\x9f\xc2\x88\x9f\x5c\x24\x8b\x23\xc5\xa3\x11\x37\x17\x8a\xc6\x56\x1f\xa7\x4b\xbb\x55\x16\xd3\x54\x9b\x10\x37\xbd\x76\x5a\xb4\xe1\x50\x6a\x31\xb7\x76\xb3\x40\x3c\xfb\xb5\xd4\xaf\x50\x9a\x8b\xc0\x7e\x91\xc5\x4c\xe1\x06\x82\x21\xe3\x6d\x75\x16\x59\xc9\x68\xc6\xb1\x9e\x46\xb5\xba\xb9\x3e\x9e\x7a\x02\xd2\x69\x2f\x67\x54\x65\x98\xcd\x1e\x30\x05\x81\xd0\xc4\x37\x48\x20\xa3\xc1\x99\xac\xf6\x30\x5e\x42\x43\x0b\x2b\x98\xcb\xb8\x38\x76\xee\x30\xf8\xb2\x34\xa5\x81\x28\xc9\x43\x3c\x17\xb2\x34\x58\x54\x79\x5b\xd5\x8f\x75\xfe\x67\x7f\x97\x34\x4b\xe3\x5e\xa8\xbe\x2c\xa1\x9b\xd6\xb3\xa4\xb8\x6f\xc9\x98\x34\x81\x09\xad\xda\xab\x80\xe4\x98\x35\x32\x86\x79\xae\x61\x8f\x49\x1f\x5b\xc0\x7e\xdb\xcc\x38\x75\x04\x4c\x8e\x7e\x00\x65\x1b\x67\xd7\xe1\x82\x06\xa5\xad\xcd\xa0\x12\x35\x58\x34\x99\x80\x18\x3f\xc3\xce\x0b\x8e\x8e\xed\xd0\x2c\x23\x59\xe6\x29\xe5\x8a\x00\x02\x9f\x78\x24\x59\x66\x28\xbe\xf6\x16\x9a\x36\xdf\x57\xe5\xa9\x3f\x00\x2e\xb8\xdd\xca\xfa\x19\x5a\x1a\x7e\x96\x8a\xe1\xcb\xff\x51\x1d\x3d\xb1\x51\x37\x31\xfa\xcb\xa9\x84\xa5\x3a\xd4\x80\xe7\xed\x15\xd6\x05\xad\xbc\xae\xe1\xb9\xbf\x37\x1d\x30\x4a\x44\xa9\xff\xd0\xeb\x46\xcb\x79\x97\xaa\x2c\x42\x6b\x01\xe1\x34\xdd\x67\xce\xcb\xe7\xc1\xd2\xc8\x94\x96\x58\x66\x70\x7d\xb5\x9d\xb0\x73\x8a\x4c\x7b\x1d\x3f\x67\x23\xdd\xc9\xf7\xd3\x0c\xd8\x9f\x99\x24\x41\x6b\x78\x77\x90\xa7\x73\x1d\x33\x91\x19\x1d\xe1\xb2\xe2\xbe\xd3\xfa\x30\x47\x56\x66\x20\x23\x9b\x7a\x28\xc2\x38\x86\x8b\xb9\xcb\xf2\x7c\xd0\x83\x01\x6d\xfb\xf0\x89\x0f\x4f\x16\xc7\xa6\xaf\x2c\x9e\xde\x1f\x6c\x14\x8f\x04\x9c\x86\x75\xeb\x6a\x1e\xf4\xcb\x6c\xc6\x03\x37\x0e\x72\x02\x20\xf6\xe6\xaa\x7e\x3e\xee\x07\xee\x5f\x91\x59\xe5\x18\x74\xe0\x90\x37\x95\x81\x5e\xc8\x61\x8e\x59\x9c\x3e\x86\x35\x12\x8b\xc5\x6e\xf3\xa6\xef\x5c\x0b\x1a\xd1\x26\x52\x55\xc7\x30\xc9\x1e\x7b\x8a\x3a\x21\x23\xe9\x88\x5e\x91\x5d\xd6\x65\x71\x31\xf6\x3f\xe9\x0f\x19\xc7\x19\x8e\x62\x0c\xfd\x6e\xa0\xfd\x91\x37\xb9\x2a\xe0\xd2\xd6\x28\xe3\x24\x72\x92\x8f\x30\x0c\x57\x19\x03\x47\xdb\xe6\x3d\x37\xed\x0b\x82\x5a\xde\xc2\x21\x22\x12\x11\x4a\x7a\x1d\x8f\x85\xa7\x9b\x9d\x3e\x02\x4d\x5d\x35\xe4\x0e\xb3\xfe\x18\x35\x7a\x94\x75\x9b\x5f\x80\xbf\x49\xea\xdd\x08\xe7\x45\x2e\xcb\xf6\x5c\x95\x3f\x7c\x10\x49\x6d\xa4\x7c\x3c\xda\x47\x1c\xc6\x08\x65\x99\x88\x0c\x5d\x45\x74\x54\xb7\xd5\x11\x29\x24\x7b\xb3\x47\xa6\x11\x43\xad\xf6\xf6\x25\xaf\x1d\x94\x2f\x70\x46\x3d\xba\x1c\xa0\xcf\xad\x77\xcb\x6f\x38\x85\xc4\x68\xb4\x87\x3d\xd0\x49\xad\xd6\xfd\xe1\x84\x0e\x2a\xc5\x4f\xb0\x97\xf9\x28\x06\x2f\x53\xad\x91\xb3\xfa\xd6\x2b\xd9\x7c\xb2\x6f\x49\x16\x39\x74\x7d\x8f\x34\xef\x66\xf8\x71\xa6\x3a\x2d\x24\x27\x6e\xf9\x92\xc6\x5c\x57\xd5\xeb\xc5\xef\xc9\x13\xcd\xf5\x05\x45\xe3\xcd\x71\xbf\x97\xdd\x12\x7d\x46\x32\xd9\x9d\x63\xd1\x09\x44\xb1\x8e\x65\x5d\xf7\x26\x98\xe4\x99\x41\x7a\xa4\xf7\xaa\xb0\x74\x1a\xba\x93\x82\xa5\x36\xe4\xc7\x3d\x2c\x7f\x36\xd3\xa4\x80\x08\x01\x08\xfb\x11\xe3\xf6\xd4\x44\x91\x19\xb8\x8a\x36\x57\xc3\x67\x8e\xba\xf7\x8d\xcf\x6d\x08\x29\x33\x2b\x7a\xae\xd5\xdb\xaa\x5e\x1f\x5b\x5d\xed\xc7\xa4\xa3\x42\x2a\x41\x78\xd2\x7b\x59\xbd\xbe\x92\x90\x2a\x23\x91\x18\x52\x6e\xd7\x27\x17\x86\x9f\x3e\xb1\x92\xce\xe0\x38\xc8\xba\xbd\x85\xe1\x64\x1d\x2b\x45\xc7\xec\x72\xbd\xe1\x75\x09\xd6\x2c\x35\x61\x18\x83\xb8\xad\xea\xd7\xa6\xdb\x0d\x66\x0e\xbf\xd4\x44\x60\xc6\x07\x89\xa1\x7c\x41\x71\xd2\xcf\x3f\x9d\x2a\x2c\xe0\x6a\x03\x3b\x32\xa2\x65\x77\xcf\x2d\xa4\xaf\xdf\x9b\x60\x61\x48\x13\xeb\xb0\x3f\x2c\xe4\x61\x62\xe1\x4b\x60\x31\x46\x2f\x7f\xca\x37\x68\x1e\x65\x7f\x69\x00\xe7\x03\x23\xaf\x69\x5e\x3e\xf7\x95\xf7\xb3\xae\xb6\x9a\x58\x08\x88\xdb\x7d\x5e\xfe\x90\x75\xde\x19\x7f\x7d\x8f\x58\x43\xbd\x5e\xdc\x5b\xde\x54\xf5\x69\x12\xa2\x54\x51\xe2\xbe\xfc\x75\xde\xbe\xc0\xbe\x6a\x2f\x93\x07\x0a\x15\x29\xc7\x9e\x8c\x93\xb0\xee\x4f\x8f\x63\x83\xe1\xf5\x2b\x63\x56\x2d\xec\x31\xb5\x1b\xec\xaf\x11\xfe\x79\x0e\x87\x66\xff\xb8\x64\x06\xab\x98\x38\x28\xf9\x73\x67\x61\x36\x2f\x8f\x55\x5e\xb6\xd7\x27\xac\xa1\xb8\x90\x9b\x55\x31\xa3\x58\x7f\x8a\x42\x13\x8d\x0b\xec\xfa\x43\x24\xa3\x28\x8d\xe2\x88\xb6\x7d\x8f\x8f\x8b\xf5\x7c\x3b\x4a\x63\x24\x51\x38\x20\x50\x63\x60\xdb\x98\x0c\x36\x45\xa5\x13\x3b\xca\x9b\xb5\x31\x67\xc7\x0c\x0f\x68\x0e\xd9\x62\x99\xdd\x5d\xae\xa6\x1f\x49\x51\xc3\x82\x20\xe7\x0f\x28\x4d\x55\x5f\x1d\x0e\x45\xee\x40\xc6\x1b\x5d\x75\x8f\xb5\xad\xbb\xed\xe3\x92\x83\xa6\x28\x24\x18\xdf\xff\xbe\xb9\x21\xd1\x36\xd0\x3d\x84\x57\x4d\x20\x15\x11\x06\x3c\x8b\x4a\x9a\x3e\x5c\xfc\x29\x6e\x49\xa5\x91\x64\x74\xcc\x84\x78\xf9\xae\xa9\xb6\x48\x9a\xa2\xa0\x04\x9b\xeb\x5c\xd6\xa7\xdd\xbe\x32\xb9\x9d\xad\x76\x8a\x31\xe9\x13\x72\xa5\xf9\x5c\x5a\xc6\x37\xe6\x59\x8a\x57\xbd\xfd\xf8\x98\x20\x7f\x3a\x0f\x28\xc8\x06\xe3\x0e\x7e\xae\x9c\x20\x54\xc6\x12\xe4\x36\x0d\xa4\x99\xf3\xc3\x22\x46\x7b\x61\xf1\x74\x77\x08\xca\xac\xfd\x21\x8b\x25\x42\x81\x14\x72\x76\xa2\x24\xd2\x43\xb1\x3f\x53\xff\x99\x75\x4e\x26\x39\x22\x02\x17\x77\x8b\x5f\xe1\x84\x94\x64\x4e\x9f\x6f\x24\x14\x14\x26\xa6\x92\x42\x07\x7a\x96\x07\xf8\x68\xc3\x0e\xb7\xdd\xde\xbb\xdd\xcd\xb0\xdf\xc6\x18\x40\x25\x65\x16\xf9\xcc\xd4\x55\x0d\x72\xe9\xea\xbb\x46\xa8\xd4\x8b\xac\x12\x42\x49\x93\x22\x43\xd1\xb1\x81\xfa\xae\x92\x9f\xd4\x43\x0b\xa5\x24\x44\x74\xea\x4f\x39\xdd\xa1\x39\x20\x47\x99\x84\x3b\xcf\xc3\x21\x1c\xd1\xfc\xd1\xa7\x0b\x41\x86\x19\xa4\x4c\x01\x11\x68\x93\x1e\xcb\xcd\xb1\x39\xcc\x49\xb1\x85\x02\x1a\x59\x3d\x24\x62\x83\x8a\xf3\xac\x91\x14\x99\xdf\x1f\xdc\xe2\x0e\xa6\x07\x0e\x5d\x5c\x56\x6c\x94\x62\xd0\xb6\x80\x37\x28\x62\x17\xc6\xeb\x0f\x01\x02\xbc\x5d\x1e\xbc\xf3\x0b\x07\xab\x40\xd9\x98\xf3\x09\xfe\xfe\xb1\xaa\x5e\xae\x8f\x27\x5f\xb5\x33\x7d\x35\xcb\x5c\x26\x64\xb3\xbd\x7a\xda\xee\xae\xef\xd6\x8b\x6f\xbb\x87\xef\xf7\xd7\xcb\x80\xe6\xd6\x11\x71\x2c\x8a\x5f\x10\x34\x7a\xda\xdd\x1f\xff\xc8\x77\x0f\x55\x80\x8f\xe9\x58\x53\x4d\xa6\x10\x8f\xed\x6c\xdb\xd3\xb1\x95\x98\x14\x47\x32\xd0\x55\xd8\x44\x34\x49\x1d\xff\x5b\xde\x3c\x54\xed\x48\x4e\x67\xd2\x0f\x9a\xe8\x38\x2c\xaf\xba\x02\x6b\x75\xfe\x69\xed\x82\x26\x5a\xa0\x39\xf5\x58\xc0\x07\x06\x01\x2e\x00\x58\x27\x15\xcf\x42\xd3\x88\x87\x42\xbd\xde\xed\x0c\x7e\x8a\xa6\x49\x8c\x61\xb6\xbc\xf9\x56\x56\xef\xe5\x40\xa3\x34\xbd\x44\xda\xd3\x6d\x7f\x3d\xee\x65\x39\x29\x41\xd4\x94\x83\x36\x93\x7a\x08\x74\x4c\x1e\xf3\x0f\x28\x26\xd8\x91\xff\x8b\xd9\x0c\x29\xa9\xa9\x76\xa5\xa6\x4e\xab\xf0\x4f\x58\x8d\x24\x74\x2f\x66\x69\x74\x42\x00\x13\xfc\xa6\x3a\xaa\x02\xce\xa9\xc7\x85\x4e\x58\x4f\xbd\xfb\xb0\x0a\xf8\x04\x9d\x68\x8a\x36\xc1\x37\x59\xcb\xf5\x24\xfe\xad\x13\x6d\x1c\x4d\xbf\x7c\x83\x4d\x7b\x34\x23\x46\xc1\x59\xcc\xea\xe2\x26\xac\x53\x2e\x32\x12\x10\xba\x3a\x6f\xe6\x94\x4f\x42\xa7\xda\xb1\x72\x9b\xbc\xf1\x8b\x64\x4f\x9d\xe4\x5b\xb0\xd4\xa1\x3a\x77\xcd\x08\x2e\x99\xcc\xde\x8c\x29\xc3\x7a\x9d\xa7\xfb\xbc\x9c\xbf\x79\x16\x71\x46\x26\xf1\xaa\x55\xd3\x1c\x3f\xa9\xed\xd6\x19\xc9\xa4\x98\x0c\x0c\x4c\xcb\x79\x89\xdb\xf0\x60\x19\xa5\x98\x8a\xdb\xc2\x47\x1b\x18\x86\x43\x0c\xe6\xc2\xd2\xaa\xb3\x44\x23\x73\xd7\xae\x7b\x88\xcf\x41\xaf\x3a\xe3\x23\xae\x0f\x0b\xf5\x6d\x5d\xed\x7f\x9c\x39\x9b\xff\x7f\xce\xbe\x6c\xbb\x71\x1c\x49\xfb\x75\xea\x62\x2e\xb8\x83\xb8\x94\x25\xd9\xe9\x29\x2f\x6a\x4b\xce\xac\x9a\x3e\xff\xd1\x09\x00\x01\x9b\x6d\x8a\x54\x93\x94\x9d\xea\xa7\xff\x0f\x03\x00\x37\x51\x59\x35\x73\xd1\x55\xd5\x26\x48\x71\xc1\x12\x88\xf8\x16\x09\xcc\x0f\x9d\xd5\x3f\xfd\xcc\x23\x0e\xfb\x1e\x58\x97\x6b\xe5\x00\xea\x78\xff\x8f\x9d\x2d\x94\x5f\x20\xfb\xa4\x08\x14\x15\x78\xb6\xbb\xe7\x41\x06\x4d\x8a\x08\x08\x31\x2c\x68\x0a\x1a\x7f\x5b\x11\x07\x2e\xbf\x72\x5b\x21\xbe\x80\x10\x59\x33\x0c\xa5\xba\x2c\xca\x3c\x10\x42\x0a\xf0\xc4\x90\x05\x3b\x97\x0c\x97\x02\x18\xe5\x25\xc9\x24\x32\x1c\x8c\x4f\x21\x31\x1e\xcd\x75\xab\xec\x33\x53\x58\xa8\xfa\x62\xfa\x97\x52\x79\xb4\x3b\x6b\x43\xd3\xc9\x83\x2b\x90\x54\xfc\xfa\xca\x0a\x55\x7e\x79\x44\x4d\x1d\xb0\x7a\x24\x4a\x49\x2a\x3e\x8f\x0a\x15\x81\x38\xdf\x21\x2b\x86\xaf\x48\x73\x3f\x75\xbb\x02\x42\x17\x2e\x2d\x37\xa8\x53\xc9\x4c\xa5\x56\x46\xbf\xe8\xa1\x7c\xbb\x99\xf4\x7f\xad\x4d\xa1\xf3\xe9\x66\xb1\xf3\x3d\xff\x5a\xa9\x7d\x7e\x7c\x29\x8f\x25\x94\x73\x3b\x96\x16\x04\xe7\xae\xab\xbc\xd4\xa7\x6d\x40\x7b\xab\xdf\xb3\x3c\x07\x7b\x2f\xca\x57\x31\x51\x72\xbf\x9c\xd7\x85\x0b\x20\x26\xdf\x57\xf9\xa8\xc9\x15\xad\xea\xe5\x18\x0c\x91\xdb\x5d\x29\x8c\x24\x95\x11\x8c\xd5\xc1\xaf\x81\x60\x2a\x14\x3e\xa9\x21\x12\x38\xca\x5d\x21\xf2\x0c\x99\xf3\x0d\x0e\x38\x9a\x39\x55\x14\x2b\xdf\x86\x1a\xdb\xf7\xec\x78\x9c\xa8\x90\xa5\x2a\x02\x46\xbb\xbb\xc5\xeb\x6a\xff\x7c\x28\x32\x55\xe6\x39\xf4\xa7\xa3\xf4\x02\x37\x1d\x58\x36\xc5\xe4\xf1\x62\x16\x51\xce\xf1\x8f\xc7\x87\x3f\x87\x73\x9e\x8a\x21\xb0\x7e\x91\xe7\x9b\x36\xbc\x39\x8f\x37\xe6\x8a\x85\x09\x65\x5f\xf7\x07\xf8\x40\x9b\xe8\xbd\x2d\x2b\x5b\x7f\xff\x25\x1f\x5a\x31\xc6\xa8\x2c\xbf\x37\x4a\x3c\xc3\xd1\x92\x8e\xf8\x13\x2a\xc5\x80\x5a\x36\x58\x37\xfb\x20\xdc\x1b\xf1\xcb\x3b\xa8\x5f\xdb\x00\x23\xf0\x3c\x92\x4e\x72\x73\x91\xe2\x7e\x4c\x20\x82\x63\xe5\xc9\x32\x9b\x64\x0f\x15\x84\x42\x8e\x17\xba\x4d\xd9\x6c\xfb\xac\xaa\x02\xe6\x11\xdc\xfc\x58\x61\x26\xcb\x3d\x16\x4a\xf5\xe5\x31\x25\xe2\x34\xd4\xfd\x48\xa7\x78\xbd\xda\x7e\x64\x79\x3e\xaf\xbc\x9d\x2a\x21\x22\x62\xef\xfc\xf7\xf6\xf9\xe9\x08\xcd\xfb\xbe\x9e\xa9\xea\x74\x6d\x8d\xfa\x05\x61\x33\x0d\x53\x75\x9f\xb9\x35\xc0\xce\x1f\x5d\x1e\x55\x09\x8c\x24\xef\xdd\x02\x86\x89\x93\xf1\x2d\xa8\x40\x50\xe9\x9d\x5c\xbd\xdc\x4c\x8a\x44\x5a\x7a\x25\xa4\xc5\x64\x5f\xa4\x30\x06\x43\xee\x39\x76\x7d\xb9\x9d\x79\xff\x77\xfc\x64\xa5\xa3\x88\x68\xa6\x07\xf8\xd9\xb1\x7a\xdd\x7b\xd4\xb1\x92\xbe\xa5\x65\x8f\xf6\xd4\x4a\x73\x00\xe5\xf6\x64\xe7\x1f\x1d\x83\x70\x6a\xaf\x92\xa2\xc7\x15\x58\x35\x15\xb3\x90\xcd\x88\x3f\x53\xae\x99\xa6\x56\xfc\x79\xcc\xcb\x0a\x83\x5f\x48\x49\x60\xe0\x21\x29\x15\x89\x2a\x93\x1f\xc3\x9c\x17\x06\x41\x68\x83\xb4\xfa\x84\x8f\xa8\x26\xf6\xea\x29\x06\xe8\x76\xea\x87\xac\x68\xd7\xe7\x7d\x56\xbf\xe0\xbf\x4f\x59\x85\x46\x7e\xb9\xff\x95\xd0\x33\x18\x3d\x02\xec\xaf\x97\xeb\xfb\xef\xeb\xd5\x80\x5c\x8a\xa1\xf4\x09\xd4\x2b\x4e\xe7\x0d\x19\xd5\x0d\x78\x36\x7f\x63\x31\xc1\x50\x86\xa6\x8f\x56\x99\xda\x95\xa3\x04\xcc\xf8\x0b\x61\xc4\x12\x63\xbb\x6e\xd9\xd7\x5d\xa2\xae\x63\x67\xb9\x00\x17\x23\x30\xfc\xdb\xac\xa6\xba\xcf\x24\xd5\x82\x91\x36\x39\x41\x32\x08\xfb\x72\xb0\x46\x8c\x01\x89\xc5\x45\xfb\x39\x38\x64\xaa\x3b\x20\xbd\x68\x88\xa2\x1b\x01\x4d\xe6\x6f\x36\x96\x8c\x68\xa0\xb2\x2c\x24\x4c\x95\x8b\x66\x46\x13\xc6\x98\x44\x2e\xbb\xe2\x60\x4d\xcf\xd5\xff\x60\x55\x8e\x17\x1e\x4c\xbc\x84\x16\x9e\xe7\xdb\xa7\xe7\x3b\x77\x87\x89\x08\x08\x30\xa9\xb3\x42\x6d\xca\x9a\x92\xbb\x56\x67\xa6\xac\xea\x69\x2a\x07\x99\x2f\xa8\xd2\x9a\xc9\x32\xac\xac\x36\x3c\xd5\x8c\xdd\xf5\x58\x84\xca\xca\x01\xb7\x01\xfe\xb6\xa9\x86\xc8\x11\x4c\x93\xd4\x39\x3d\x52\xc7\xbb\x64\xef\xce\xbf\x95\x94\xc5\x01\x38\x1a\xef\x6b\xdd\xfe\xa8\x82\xf3\x50\x7e\xcc\x35\x14\x3e\xe5\x3a\x32\x9b\xaf\xbf\x78\x02\x9e\x78\xa4\x92\xde\x64\xed\xdc\x33\x61\xab\x22\x4f\x42\xca\xcd\x39\x17\x90\x09\xef\x1b\x39\x03\xe2\xc0\x82\xc1\x5b\x90\x62\x51\x03\x07\x17\xa3\xa0\x08\x81\x0f\x29\xc1\x16\xa1\x30\x4e\x77\xa2\x48\x40\xf7\xea\x74\xeb\x59\x12\xae\x6b\xaa\x91\x02\x09\x7a\x1e\x50\xea\x40\xb2\x74\xbf\xee\x42\x32\x8e\x69\x23\x71\xc0\xee\xbd\xcb\x84\x53\xb4\xbc\x77\x7a\x79\xfe\xde\xa1\xa7\x50\x09\x83\x5b\xff\x9f\xa1\x56\x60\x8a\x18\x68\xc2\xf0\xee\xc5\xe9\x92\x64\xed\xda\x30\x73\x59\x6d\xa8\x7b\x9d\x4d\xcc\x20\x9e\x42\x04\xb3\xa7\x34\x82\x20\xf7\xed\x8a\xd7\x1d\x12\xca\x14\x00\x8e\x58\x34\x93\x77\x84\x3a\x48\x8d\xe8\xbe\xd5\x4f\x9e\xbf\x05\xed\xf9\x01\x65\x59\x29\x41\x9b\x63\x5d\x4f\xd0\x83\x33\x43\x46\x7b\x89\x20\x31\x56\x42\xea\x93\x6d\xd8\xa0\xde\x3c\xee\x2f\xda\xb3\x96\x38\xc6\xe3\x6f\x57\xde\xf4\xb9\xa6\xdf\x5c\x13\x69\xbc\x82\x28\x20\x6c\x4e\xc7\xde\xe7\x62\x08\x0e\xd5\x7e\x12\x82\x70\x19\x67\x93\x85\xea\xb8\xa4\x5d\xa9\x57\x07\x51\x2a\xec\xc5\x6e\xcb\xea\x6d\x12\xbd\xea\x40\x2a\x5a\x3b\xcb\x42\xe2\x16\x1b\x6b\xe1\xe7\x0e\x6a\x8f\x9b\x3d\x51\x56\xb8\xf0\x4f\x87\x9e\x31\xbb\xac\xb1\xe9\xd0\xba\x97\x7e\x7d\xa9\x0e\xa3\xc0\xd1\x22\x6f\x76\xcb\xf5\xee\xdb\xf4\x38\x33\x4c\x62\xec\xdc\x4e\x27\x6f\x2a\x0a\x4c\x02\x6b\xfb\x1f\x9c\xc5\xa7\xba\x66\xb1\x26\x80\xfe\xc3\xfd\x72\xd8\xdf\x74\xac\x3c\x1a\x3a\x16\xd2\xff\x3a\xb2\x74\xb4\x6d\x12\x15\xf3\xa4\x13\xa1\x98\xbe\x9b\x44\x49\x07\x81\xdc\x41\xfd\x41\xd5\xac\xd1\x14\xa8\x99\x9f\x92\xe2\xf9\xe3\xe2\x8f\xfd\xf2\xf9\xf1\xf1\x7e\xa0\x7e\xa2\x79\x12\x13\xa8\xdb\x8d\xdd\xe2\x22\x53\x38\xbe\x19\xae\xfc\x68\x62\xa6\x38\x9b\xdc\xd1\x1c\x63\xc2\x94\xad\x3f\xca\x1b\xc4\x6a\xb0\x97\xd0\xe0\x73\x5f\x74\xd0\x0e\x92\x1d\x34\x46\x3f\xb7\x19\xe6\xbd\xdd\x80\x25\x2e\x0c\x8c\xe7\xdc\xf9\xa8\xa5\x99\xbe\x7f\x8e\x78\xc9\x33\x99\x2d\x2d\x84\x0e\x7b\x59\x11\xb7\xb4\xb5\x11\x4f\xe7\x82\x37\x3f\x09\x69\x81\x9c\x4f\xf7\xa7\x53\xd8\xe4\x95\x33\xb5\xe6\xbd\x3c\xc0\xaa\x2a\x0b\x42\x03\x7e\x87\x9e\x17\xa8\x25\x7a\x64\x33\x77\xcc\x0a\xf9\x4e\x3b\x97\x41\x2e\x67\x7c\x39\xa9\x15\xc9\x5a\x5a\x06\xe7\x0b\xb6\x03\x29\x88\x93\xdf\x8c\x80\x89\x6d\xa5\x7c\xa4\x55\x9a\x7e\xb4\x74\xe6\x78\xee\x60\x60\x84\xb6\xdb\x2e\xf4\x71\xca\xf3\xf3\x90\xf0\xe4\xda\x30\xcb\x73\x38\x09\x83\xb2\xb1\x82\x4b\xbf\x7e\x56\xf4\x63\x9a\x06\x6e\xa0\xc6\xfb\xe5\xf3\xce\xc9\xdb\xce\xa0\x03\x35\xc6\xbe\x4f\x94\x80\xac\x79\xef\xea\x20\x1a\x55\xc8\xbb\x5a\xcd\xb6\xd4\x8d\x74\xbb\x5f\xee\x79\x41\x4c\x69\xb5\xd5\xfd\xf7\xfb\x55\xbb\x2c\xdd\xbe\xb6\xff\x78\x59\x2c\xf7\xbb\xe7\x4d\xd7\x0a\x12\x42\xd7\xbe\xbf\x35\x3d\xf1\x90\x7b\x7e\xe4\x39\x0b\x15\xa3\x6a\x3f\xf2\x60\x1a\xde\x1a\xf7\x7c\x1e\x87\xde\x80\xdf\x3a\x6c\x65\x07\x12\xf7\x7c\xc1\x53\x47\xe4\xd8\xfb\xfb\xb7\x8e\x69\xb1\x20\x1b\x5f\xa3\xb1\xb9\xcf\x2c\xbe\xc0\xfc\xdf\x9b\xb3\xef\x79\xee\x8e\x02\x90\x64\x38\x93\x15\xed\x2e\x67\xaf\xda\xe0\xd1\x1e\x0a\x59\x14\xd9\x09\x6b\xdd\xbc\xdf\x9e\x0a\x35\x81\x93\x75\xed\xe2\x20\xe8\xfa\xf3\xf7\xf2\x8a\x70\x1f\xf7\x42\x19\xc3\x50\x40\x63\xb5\x1e\x02\x93\x07\x25\x5a\xee\x45\x1e\x8f\x3a\xcd\x2d\xb3\x35\x59\x54\x87\xf3\x10\x06\x32\x7e\x5b\x31\xb3\x5a\x9b\xc6\x25\xba\xee\xc9\xd4\x23\xe8\x6a\x64\x9b\x27\x4c\x53\xa2\x3b\x2b\xb2\x76\x37\xf3\x76\x01\xde\xe2\x1e\x4b\xac\x28\x2e\x6d\xbd\xa9\xf3\x8c\xd4\x0c\xb9\xc7\xd0\x98\xf5\xec\x2d\x61\x00\x9b\xc9\x4d\xa5\x81\x11\xc8\xb0\x95\x64\xdd\x2e\xce\x5d\x5f\x48\xb9\x20\xf0\xee\xde\x51\xd1\x5c\x16\x65\x72\x11\xce\x0d\xd7\x1e\x0b\x65\xec\x7e\xa9\xc8\x1d\xba\xcb\x40\x1a\x04\xd1\x38\x15\xbc\x3d\x11\xf8\x4f\x9f\xf2\x15\x82\xf3\x69\x6b\x5b\xa6\x0e\x18\x6f\xdd\x13\x5f\xf0\x98\x67\x97\xb1\x9f\x6d\x2f\xbc\x80\xf0\x22\x39\xea\x26\xf5\x26\x77\x25\x22\x1e\x3b\x1d\xb7\x1c\xc9\xc5\xf0\x5f\x28\x9b\xd1\x3c\xcf\x3d\xe9\x33\xa2\x72\x2a\x38\x0f\x22\x07\x77\x30\x30\xa0\xa4\x45\x2e\xb0\x6a\xde\x31\xfb\x57\xe1\x6e\x55\x2a\x63\x6e\x42\x55\xd0\xe2\x13\xea\xae\xc2\xdd\x5d\x5a\xc5\xc2\xde\xc0\xf1\x5c\x0d\x59\x25\xee\x78\xca\x3c\xe1\x76\x48\x5b\x6c\xe6\x5c\x80\xb9\xef\x25\x01\xa1\x90\x88\x57\xb8\x38\x35\xef\xc3\x5c\x07\xf7\x3d\x99\x52\x1d\x85\xe4\xba\x9e\x7f\xac\x5f\x6e\x16\x0f\x0f\xa3\x5c\x3d\xf7\xfd\x28\x72\x80\x3c\x62\x61\xfc\x52\x2b\x9f\xfb\x81\xd5\x40\x74\x73\x78\xd3\x53\x53\x47\x0f\xe0\x07\x28\x44\xd0\x15\x8c\x29\x69\xaa\xee\x9d\xdf\x07\xf7\xc3\x48\x46\x46\x05\xe6\x2e\x2f\x05\xe4\xcb\x36\xd0\xaf\x20\x2b\x86\x49\xfd\xc9\xde\x73\xa6\xe6\xc3\xfd\x30\x8e\x88\x5a\xb9\x50\x9b\xb2\x81\xa6\xff\x01\x85\x94\xff\x7b\xad\x55\xbb\x75\xdf\x4e\x7b\xb7\x1f\x45\x11\x3d\x89\x93\x08\x70\x3e\x96\xd7\x12\x68\xd3\xb3\x4d\xf2\xc1\x60\x23\x89\x4f\x31\x08\x43\xb8\x1f\x49\x15\x59\xe7\xf7\x4d\x39\x51\xe3\xe4\x7e\x1c\x27\x81\x29\xb3\xf6\x3e\x56\xee\xcc\x98\xeb\xc4\xc0\x34\x21\x47\x75\x73\xee\xfe\x2e\x95\x1d\xf3\x9f\x58\x37\xd3\xea\xa7\x6d\x94\xb4\xcb\xce\xc8\xab\x92\x62\xc7\x9b\x4b\xe1\x2c\xee\x27\x28\x43\x1b\xe7\xac\x0f\x59\x5d\x67\x65\xe1\x82\x07\x37\xe8\x7c\x96\x26\x0e\xdf\xe1\xbc\xd3\x76\x58\x37\xbf\xf4\x4f\x6b\xcf\xe2\xf4\x4d\x0e\xf0\xd3\x64\xb7\xc6\xc4\x6b\xee\x33\x85\x94\x20\x20\x67\x63\x74\x7f\xe5\x81\xa9\x5c\x80\x72\xc5\xdd\xc9\x1d\xf3\x48\x59\x6d\xe4\xb7\x37\x4b\xba\xd7\x58\x91\xf3\x5e\x97\x31\x68\x5b\x69\x69\x83\xa1\xe5\xfa\x79\x06\xfb\xcf\x7d\x40\xf4\x82\x01\x54\xb9\x7d\x3b\xf5\xc6\x69\x82\x37\xfd\xc7\x90\x3c\xa5\x5c\x35\xd1\x60\xb3\xe2\x6d\x80\x33\xe5\xbe\x04\x9f\x5e\xce\xfa\xdf\xa7\xac\x28\x7f\xf6\x01\x19\xf7\x49\x7e\xcd\x1a\x7b\xcb\x72\x5d\xa8\x45\xd3\x1d\x92\x9c\x76\x0d\x4d\x76\x20\xba\xdb\xfc\xfa\xe9\xa3\x2f\xa9\x76\xdd\xd8\xfb\xeb\x81\x0e\xdc\xc7\x20\xa2\xfa\x59\xbb\xa5\xbc\x5e\x10\xe0\xbe\x0e\x35\xb1\xb2\x6e\xca\xf2\x83\x60\xe7\xeb\xe6\xfd\xbb\xbf\x42\xe9\x2e\xa4\x93\xd4\xe8\x1c\x9b\xe4\x9e\xad\x42\x0e\x33\xaa\x3c\xf0\x83\x84\x2a\x95\x4f\xf8\x45\xf0\x93\x5f\xed\xb0\x79\xe0\x47\x29\x8d\xaa\xe5\xf3\xd3\xed\xfd\xdd\xeb\xcb\x7a\x16\x5d\xda\x7e\x69\xc1\x0c\x78\xdb\x2c\x2c\xee\xd7\x02\x80\xd0\x50\x32\xab\x5f\xa3\xd5\x78\x10\x08\x93\x8f\xa9\xdb\x05\x65\xef\xef\xcd\x4c\xb3\xaf\x25\xf4\xa3\x29\x70\x1b\x9d\xfb\xa2\x6e\x67\xd9\xa9\xa2\x3e\x0f\x02\x65\x48\xe1\x3b\xfb\x39\x50\x75\x43\x72\x9c\x19\xe4\x41\xa0\x13\x2a\x1b\x6f\x4e\xd5\xb1\x74\xfe\xc7\x3c\x08\xc1\x13\x16\xc2\xf9\x50\x9e\x21\x6f\xce\x33\x05\x09\x1e\x84\xd2\x60\x35\x8d\x57\x7f\x59\xa9\x9b\xf3\x4b\x39\xc6\x5f\xf0\x20\x8a\x04\x61\xdf\x0e\xf0\xb3\x8d\x31\xbe\x95\x2a\x9f\x8c\x9d\x20\x4a\x04\x76\xb6\x29\x33\xaa\xa7\x3c\x88\x38\x32\xa4\xfb\x3c\x1e\x33\xac\x97\x65\xd5\xdd\x6b\x24\x13\x33\xb9\xbc\x67\xba\xd9\x9b\x85\xe7\x34\x34\xef\xb2\xed\x12\x2e\x69\x05\x83\x66\x7f\xc4\xea\x90\xe5\x93\x5d\x12\x0f\x58\x1a\x98\x7c\xe2\xe9\xe0\x16\xf5\xd8\xfd\x0a\x13\x31\xa8\x4e\xf0\xad\x0b\x91\x86\x4c\x33\x1e\xa4\x10\x12\x7c\x7f\xdf\x86\xd0\xf2\xdd\x78\xd5\x51\xb9\x6c\x88\xdb\xe1\x41\x8a\x21\x85\x29\xd4\x81\x6f\xa0\xce\xe4\x5f\x96\xdf\x79\xc0\x13\x8c\x3a\x58\xd6\x0f\xcc\x6e\x87\xb1\x4b\x20\x23\x4d\x88\xb4\x45\x56\x59\xe7\xd8\xbf\x67\x0e\xc1\x03\x09\xb1\xe8\x48\xb6\xf5\x0e\xe1\xe0\xae\xa9\x62\x03\xc7\x5a\xac\xb6\xa3\xfe\xa5\x98\x51\xd0\x2d\x49\xbd\x22\xf0\x8a\x4e\x33\x98\x07\x0a\x18\x85\x9e\x36\x84\x22\x10\x35\x45\xcb\xb7\x19\x34\x13\xac\xca\xb5\x34\x72\x77\xa9\x94\xca\xa1\x82\x2a\x0f\xe6\x0d\x4e\xc0\x7f\x3c\x50\x32\x24\xc6\xef\x63\x56\x34\x8b\x42\x8d\xb4\xe3\xe7\x69\xe3\x5d\x87\x40\x81\x51\xcf\xab\x5b\x2d\x9e\xaf\x25\x8f\xae\x50\x13\xfa\xe4\x1a\x0f\x50\x32\x5f\x38\x2d\xea\x81\x73\xf4\x3c\xc5\x61\x5c\x19\x75\x97\x50\x91\xf5\x59\xb2\x9c\x21\x23\x81\xeb\x66\xc8\x40\x8b\x18\xad\x27\x19\xad\xcd\xdd\x74\x16\x7a\x9e\x91\x8b\xa4\x0a\xcf\xbd\x5e\xe4\xf9\xe2\x61\x79\x91\x40\xe1\xa1\x17\x0b\x02\xee\x3f\x3c\xdf\xed\x29\xc6\x99\x83\xe6\xf3\xd0\x03\x4e\x71\x5a\xbb\x83\xb9\x85\x2c\x7f\x2c\x3b\xbf\xfd\xd5\x09\x77\xe5\x7d\x51\x9f\xb4\xce\x08\x80\x30\x80\xae\xf3\xd0\xf7\x03\xec\xe6\x77\x32\x67\x1f\x68\x61\xf3\x30\x48\x42\x2a\xd0\x6d\x32\x28\xdb\xff\x0d\xfb\x54\x18\x08\x13\x84\x19\xf7\xe0\xed\x4b\xf7\x77\x54\x94\x56\x7f\x84\xaa\xca\xe0\x0d\x97\xc6\xa4\x57\xf6\x98\x43\x1e\x86\x22\xa6\xec\xc6\xf6\x61\x71\x33\xea\xa9\x61\x28\x7d\xdd\x3e\xca\x1f\x7f\x1a\x23\x9f\x41\x09\x82\x87\xa1\x02\xd9\xde\xcf\x67\x86\x5f\x4e\x42\x8f\x87\x31\x8f\x7c\x03\x6e\x3d\x97\xa7\x86\x46\xe8\x28\x02\x0d\x63\x01\xc4\xcf\x6d\x5f\x8f\xdf\xee\xad\xba\x33\x65\x6a\x07\x52\xfb\xf8\xcd\xfb\x16\xfa\xf5\x2d\x8c\xd1\xa3\x77\x7f\x73\xb3\xbc\x00\x1d\x5d\x0e\xca\x30\x89\x23\x9a\xef\xbe\xae\x64\xdf\x78\x98\xa4\x02\x82\x1e\x6d\xf3\x7c\x6c\x46\x84\xda\x71\xf8\x12\xb2\xc4\xbc\x08\x17\xe3\x6e\x7f\x7f\x74\x77\xc6\x50\x51\xb2\xe6\xad\x82\xa2\x31\xbe\x3a\xeb\xd5\xfa\x8f\x71\x82\x9f\x87\x69\x62\x88\x52\xed\x2a\xd6\x4e\x12\xa6\xc2\xde\xa5\xfa\xdb\x06\xd2\x24\x34\x4a\x9b\xf3\xfc\xfe\xba\x59\x51\xb9\x71\x38\xd7\x87\x9c\x05\x4c\x75\x4e\xc3\xf4\xb5\xcc\xe2\xdc\xbd\x2a\x2e\x39\x4d\xe8\x9a\x60\x06\x8e\x81\x61\x0f\x82\x07\x29\x76\xa3\xa0\x36\x4e\xa6\xf3\x32\x77\x63\xf7\xc6\x5f\xff\xcb\x5d\x3d\x31\x12\x62\x86\x7f\xbc\x42\x51\x65\xf5\x15\xff\xee\xf1\xfb\x15\x51\x44\xb2\x3b\xed\x86\xa5\xac\xb2\x1a\xaf\x09\xcc\xda\xf6\x2a\x01\x42\x3f\x66\xf5\xef\x78\xfe\x46\xce\xfd\x93\xef\xab\x80\x91\x16\xd0\xcb\xf3\xeb\xd3\x6a\x1f\x3b\x6d\xe2\xa1\x7f\x39\x0f\x95\x40\x32\x0c\xea\x0a\xff\x86\x1d\x47\xbf\x6d\x6f\x35\x76\x4d\x51\x10\xe2\xc2\x71\x9a\x56\x70\x3c\xce\x71\xa4\x78\x88\x31\xa0\x70\x68\xd1\x7d\x81\x3f\x9b\xa9\x95\xcc\x78\xa2\x0e\x91\xc5\x04\xfc\x51\x59\x5d\x7e\x8d\x41\x2d\x3c\x44\x14\x04\x9f\xad\x41\x77\xe1\xed\x23\x14\xe7\x5f\xd5\x13\x9d\x27\x97\xbb\x84\x4e\x09\xe7\xb9\x79\x2f\x9b\xb2\xeb\x26\x1a\x84\x73\x26\x36\x82\x0d\xe3\xc7\x88\x3c\x16\x52\xf2\x6c\x63\xad\xca\x79\xe4\xa5\x31\x31\x2e\x6f\xb3\x42\x3d\x9e\x6f\xb3\xfa\x7d\xbf\x2e\x1a\xac\x6e\xa0\x92\xa5\x1a\x0b\xb8\xf2\xc8\xe3\x82\x6a\xdb\x3f\x6e\x97\xcb\xee\x0a\x32\xa4\x22\xbd\x5d\xdd\x36\x70\x6e\xa3\xaa\xf9\xd7\x12\xf9\x41\x28\x9c\xf0\x60\x81\xf9\x1e\x8e\x2e\x99\x12\xf9\x2c\x75\x68\xb1\xcf\x29\x37\xa8\x3d\x2a\xa8\x68\x66\xd7\x81\x1f\x65\xdd\xee\xb7\x76\xe5\x8f\xd2\xa9\xcd\x77\x0d\x15\x29\x5a\x7c\x65\x1f\x99\x71\x67\xa2\xf1\x34\x7a\xb5\x93\x7b\x92\x11\x98\xda\x38\x1e\xa1\x9a\x3e\x72\x90\xa6\x0a\x3b\xe4\x37\x12\xc6\xcb\xbd\xef\x28\x4c\x39\x6d\xd6\xf6\x7b\xf9\xee\x5c\xed\x7d\x77\x8c\xc7\xe8\xfc\x03\xad\x47\xf2\x06\x5c\xb1\x8f\x47\xa1\x4c\x49\x4b\xa6\xcc\x95\xe9\xeb\x93\x2e\x17\x45\xbe\x26\xc1\xa5\x23\x8d\xe6\xc7\x7a\x62\x48\xc4\xa3\x28\x0e\x2d\xe9\x9a\xd2\x69\x97\x71\xf4\xe8\x05\x46\x92\x51\xe9\x6e\xb1\xfa\x7e\xbf\x7d\x7e\xd9\xdf\x3e\xbf\xba\x05\x25\x8a\x19\xe7\xba\xcb\x8d\xb5\xe1\x71\xbb\x86\x4d\xee\x27\x4e\x0d\xea\x92\x40\x58\x8b\x42\xd1\x82\x6b\x1d\x74\x07\xff\xb4\xad\x93\xd4\x54\xf8\x75\x46\x13\x16\x16\xcd\xd4\x6d\xcf\x35\x04\x4d\xd0\x02\xb2\x0c\x51\x9d\xe9\xe7\x69\x2e\x0b\x10\xb1\x08\xa8\x5e\x68\x50\xd0\xa8\xdc\x46\x76\x72\x4d\xc6\x13\x5a\x20\xa5\x9d\xaf\xf7\x83\x68\x2c\x62\x32\xa5\xd4\x68\x37\xed\x7f\xe0\xc0\x2c\x77\xd2\x37\x18\x06\xc6\x95\x51\x6b\xa3\x7e\xa2\x32\x28\xbe\x63\x31\x2f\x7a\xc5\xa3\x54\x45\x84\xcc\x74\x4e\x46\xc3\x57\xc2\x03\xae\xed\x06\xa2\x53\xec\x33\x72\x0e\x9d\x7a\x47\xdc\xe3\x8b\xff\x77\xff\x69\x7f\x02\x3c\x60\x16\x14\xa8\x9e\xf0\x67\xf3\x05\x19\x99\xe8\xdf\x60\x73\xbf\xba\x92\x41\x8b\x80\xc5\x24\x27\xff\xb8\x7e\x78\x7e\xda\x2f\x9f\x9f\x76\x2f\x8b\x65\x37\x41\x80\x94\xc4\xc8\xe9\x71\x62\xdf\xb7\x4f\x97\x78\x68\xdb\x5a\xf0\x34\x32\xe1\xce\x90\x73\xea\xae\x25\x99\xe1\xe2\x5b\x27\xcc\xf2\x63\x83\x55\xdb\xdb\x2e\xbc\x8a\x78\x24\xc1\xb0\x83\x2c\xe8\x6f\x53\x65\x87\xb2\x7d\xf9\xa6\x14\x36\x2d\x27\x8c\x82\x48\x7b\x05\xe5\x85\x54\xc0\x6e\x37\xe0\x8e\xba\xf6\x5b\x77\x8c\xa5\xd6\x59\x3b\x3f\x37\x43\x11\x57\x1e\x69\xe5\x05\x89\xe3\xea\x13\x14\xd3\x80\xf7\xfe\xae\xb4\xdb\x3f\xdd\xc7\xd0\x68\x0c\xfe\x32\x35\x29\x2b\xf3\xd8\x0b\x3d\x29\xac\x31\x54\x0f\x4e\xbe\xf2\x81\x62\x2f\x91\xf1\x40\xa4\xab\x69\x72\x1c\x3a\x57\xff\x33\xe8\xed\x1a\x47\xff\xe9\x4e\x07\xa4\x24\x45\x7d\xcc\xb3\x66\xd6\xdc\x8c\xc7\x9e\x8c\xc2\x4e\x27\xf4\xb6\x42\xfc\x0f\x49\xc0\xf5\x15\xeb\x6b\x00\xf8\xf6\x54\x19\x0e\x20\xce\x1d\x04\x8f\xc7\xbe\x17\x10\xb1\xd8\x95\xc8\xea\xee\x40\x1c\x84\x83\x51\xb2\xd7\x17\x66\xd9\x3c\xf6\x55\xc8\x61\x92\x58\xbc\x2d\x2b\x8a\x56\x5f\x28\x41\xf5\x5e\x39\x04\x1d\x8f\x7d\x0c\x89\x73\x48\x40\xc4\xdb\xf2\x54\x35\xef\x3f\x10\x5d\x0a\x27\x0e\x3c\x49\x17\x83\xdc\xf4\x1f\x8a\xf4\x9f\x8d\xd1\x44\xd7\x86\x69\x8a\x46\xc5\xe9\xbc\x7d\x87\x7e\x92\x8f\x43\x16\x91\xa8\xf7\x11\x89\xab\xf8\xdf\x20\x3f\x8e\x65\x73\x5b\x56\xe4\xde\xe1\x5a\x45\x5e\x40\x22\x98\x2f\x54\xa5\xef\xff\x6a\xc2\xf0\x76\xba\xa2\x5f\x5e\xc1\xf9\xaa\x82\xb6\x3b\x27\x88\x89\x14\xb0\xfb\xe3\x8b\x64\x53\xa7\xab\x70\x1c\x85\xbe\x34\xee\x99\xe5\xc7\xe9\x68\xd7\x24\xb5\x3d\x56\x59\x83\xd3\xd7\x18\xa5\x06\x06\x99\xd5\xeb\x9f\xc7\x6c\xaa\x03\xc0\xe3\x08\x8c\xe5\x35\x69\x77\x0e\xd2\xa2\xc3\xea\xe1\xb5\xfb\x04\xed\x19\x0e\xfb\x27\x42\x7e\x93\x5d\x82\xdb\xfe\x22\xc7\x3a\xbd\x9e\x30\x18\xd3\xfb\xe5\xf3\x7e\x77\xbf\x7e\xd9\x3f\x2c\xb6\xbb\xee\x45\x4a\xe3\xce\x6c\x0a\xeb\x06\x1e\xdf\xed\xe2\xe2\xd8\x8f\x08\x90\xfb\x82\x6f\x6d\xc8\xe7\x68\x64\x3c\x8e\x51\xfa\x96\xcc\xf2\x98\x15\xd9\xe9\x70\x5f\x1c\x4f\xcd\x25\x37\x94\xc7\x49\x62\xd2\x3b\xed\x74\xf1\x54\x7e\xfd\xd6\xfd\x39\x34\x8a\xe5\x5d\xea\xb7\x5e\xb4\x2b\xda\x20\x99\x15\xb3\x50\xfa\xd4\x55\xe1\xe7\x7a\x60\x3a\x3d\x1e\xf2\x2c\x46\x19\x4f\xf5\x4e\xee\x57\xd3\xed\x7f\xf7\xde\xed\x2e\x3a\x4e\xbd\x94\x62\xde\x5e\x62\x44\xbb\xaa\x4a\x9c\x86\x11\xa1\x7f\x80\x0c\x51\x6e\x4f\xb9\xce\xf2\x7c\x68\xeb\x3e\x79\xc3\x3c\x30\xac\xfc\x23\xc8\x8f\xdf\x71\x08\x88\x71\xe5\x50\x1e\x73\xe6\xd1\xb4\x49\x33\x41\x8d\x0d\x99\xc6\x1e\xee\xa0\x1e\x01\xc6\x87\x3e\xce\xee\xc4\x34\xa4\x3d\xe0\xca\x48\xf7\xfe\xb2\xfc\xd9\xb6\x36\x32\x1e\x14\x56\xed\x8b\x72\x5f\xea\xfd\x72\xb7\x72\x4f\xc6\xa5\x50\xed\xb8\xd1\x8f\xa7\x79\xf5\x46\x1e\x73\x0c\x68\x8f\x96\xa3\x6e\x82\x78\xf2\x35\xc1\x03\x88\x9d\x0d\x48\x85\xb2\xfd\xfa\xcd\x43\x76\x98\x6e\xec\x63\x08\x14\x81\xe2\x73\x2c\xd4\x5d\xf9\x89\x55\xd1\xbe\xbf\xc7\x21\x6e\xc6\xb5\x4c\x03\x42\x34\x3c\x94\x6f\xd6\xa0\x86\x72\x72\xee\xa8\x60\x4e\xc5\xca\xec\x02\xe7\x92\x83\x31\x48\xec\x61\xe8\xc6\xa9\xfc\xca\x56\x6a\x3c\xe2\x45\x12\x32\x23\x67\xf6\x7c\x44\x32\x9c\x1c\x80\x98\x27\x1d\x4d\x26\x1e\x77\xfe\xcd\x8d\xa1\x73\xe2\xdf\xcc\x7b\xc5\xa8\x85\x15\x7c\x2c\xb0\xce\xea\xd9\xbd\x50\xac\xb5\x24\x3a\xe3\xe1\xbc\xee\xc1\x1d\xe6\x58\xe2\x25\x86\x77\xfa\xe3\xfe\x69\xfd\x0b\x1e\x11\x4f\x3c\x16\x12\x73\xba\xfe\xea\x51\x55\xe3\x0f\xdc\x3e\x46\xd4\xbe\x52\xd5\xc6\x10\xeb\x0b\x1c\xc9\xb4\x35\x2a\x4b\xda\x22\x0c\xd5\x25\xbd\x81\x27\x7e\x6c\xdc\xf0\xf1\x27\xca\x53\x83\x2f\xa7\x7c\x28\xf5\x39\x69\xab\x90\x7a\x97\x2a\x0f\x04\xe8\xb6\x52\x02\xe3\x99\x38\x09\x38\x92\xe5\x99\x84\x3a\x2b\x4a\x2a\x2f\x4c\x7e\x33\x80\x84\x80\x49\x1d\x7d\xf3\xe6\xfc\xba\x5d\x5d\x79\x86\x40\xc6\x3e\x76\x48\xaf\x9b\x73\x1b\x18\xc8\x77\x9c\xaf\xd5\xb9\x73\x94\x51\x87\x22\xc0\xeb\xe1\xd8\xe0\x3e\x0a\x47\x5b\xa7\x24\x64\x29\x05\x34\xed\x6e\x73\x5f\x9f\xc4\x95\x27\x8e\x74\x40\x23\xd2\x04\x58\xd9\x48\xcc\x7a\xb6\xa7\x25\x71\x20\x45\x27\x77\xdf\x85\x0a\xcf\xda\x55\xa1\xfb\x2c\x70\x12\x23\x38\x2a\x8d\x19\x1e\x43\x89\x28\x9e\x24\xa1\x4e\xa0\xe3\x1a\x6d\x5e\xd6\x66\x0d\x78\x5c\x6f\x77\x8b\xc7\x4d\xd7\x4a\x6a\xd9\xe5\xd2\x7a\xf4\x58\xb9\x30\x44\x50\xb7\x60\x27\x4c\x33\xeb\x9e\x5d\x34\x8f\x20\xdf\xb3\xe2\xa2\xd3\xcc\x2f\x41\x49\x1a\x73\x8a\xb4\xac\xd6\x4c\x57\x2c\x9c\xb4\x52\x20\x8c\x21\x48\x76\xbc\x60\xb1\x4e\xde\x11\x4f\x3c\x82\x30\x56\x08\xea\xbe\xd0\xe5\x1c\x6e\x66\x72\x13\xdc\x92\xfa\x69\x95\x3a\xe6\x50\x38\x2b\x12\x9e\x70\x04\xda\xbf\x53\x1a\xe2\x58\x95\x93\x1b\x03\x8f\x47\x56\xd9\x6c\x7a\x24\x08\x44\xda\xd1\x18\x8c\x49\x5b\x83\x47\xdf\x5d\x18\xd2\x84\x02\xe2\x3f\xac\xd4\x6a\xf7\x77\x44\x0a\x0f\x9c\x02\xb6\xa9\xdf\x9e\xda\xa1\xb0\xc3\xba\xbb\x2f\x21\x95\xf1\x4d\x81\x42\x95\x87\x1d\x69\x4d\x2c\x48\xa6\xa1\x6b\xa1\x85\xd5\x41\x37\x90\xcc\x6a\x7e\x99\x4c\xa4\xc7\x79\xfb\x6e\xff\x7d\xca\x08\x6c\xb4\xc8\x2a\x55\x95\xc7\xee\xdb\xca\x20\x31\xf8\xee\x93\x70\xc0\x6d\xab\xac\x33\xbb\x17\xb8\xdc\x99\x26\x32\xf4\x20\x72\x73\x30\x41\x0f\xe7\x07\xa3\x8c\x63\xda\xf8\xec\x8f\x95\xb3\x81\xee\x05\x16\xe6\xbe\x60\xea\x4e\x14\x46\xe5\x21\x93\x65\x1f\x0c\x27\x52\x1a\xb2\x63\x53\xde\x84\xc1\xc5\x5e\xc2\xdc\xe6\xf8\x55\x28\x66\x4a\xdb\x9b\x97\xf5\x7e\xfd\xc7\x7a\xf9\xba\xbb\x7f\x7e\xda\xdf\x2d\x5c\xa6\x2b\x51\x22\xa0\x12\x11\x21\xe3\x77\xe5\x0b\x42\x7e\x01\x8a\x76\x4d\xd1\xc4\xb0\xc4\x29\x5e\x55\x30\x24\xdb\xf3\x04\x7d\x4d\x71\x41\x26\x4b\xab\x4c\xe2\x0e\xc4\x31\xe9\xeb\x37\x58\x37\xc4\xd1\xaf\x5f\x90\x76\x75\xc4\xca\xa3\xff\xa2\xb2\xac\x6b\xae\x62\x7a\xc6\x43\x56\x74\x01\x83\x39\xc4\xbc\x30\xa1\xec\xce\xe2\xe5\xd1\x1f\xf6\x30\xe6\x85\x06\xb0\x4e\xf5\xb2\xba\x7c\xc4\xe6\xbd\x9b\x36\x98\x17\x71\x61\x45\xe2\x26\x13\x2b\xf3\x78\x4c\xa8\xd8\x3e\x46\x64\x9e\xf4\x8d\xf1\x2b\x64\x35\x92\x9e\xc9\x16\x51\x4d\xb4\x0f\xae\x70\x2f\x38\xf3\xbd\x80\x4a\x95\xbb\xaf\xf2\x76\x22\xd7\xc8\x99\xcf\x91\xca\x3b\xcb\x97\xe7\x1f\x2b\xca\x39\x6e\xbf\x2d\x5e\xd6\xdd\x61\x05\x04\x79\x23\x41\xf7\xd7\xed\x4a\xae\x77\xdf\xdc\xb1\x40\x48\x27\x14\xde\xce\x6a\xb3\x9e\x5f\x9c\x05\x98\x82\xea\xb9\xaa\xed\xac\x3f\xbe\xbd\x00\x81\xaa\xd0\xaa\x82\xb7\x2e\x73\xcc\x22\x2f\x24\x65\xfd\xed\xe2\xc7\x7f\xe3\x17\xa5\xfc\xce\x03\xb3\x51\xce\x22\x5f\x28\xe3\x50\x51\x3c\x8e\xaa\x0b\x2c\x66\x09\x31\x97\xf0\x21\x6b\xb0\x97\xff\xe2\x2c\xd6\x86\xf8\x69\xb6\x6d\x93\xdb\x60\x1e\x4b\x6c\x79\x93\xb8\xf1\x37\x7d\x35\x86\x31\xae\x29\x84\xb6\x65\x66\x93\xe4\x18\x16\xf9\x18\x83\x98\x8f\x85\x7c\xda\xad\xff\xcd\xa8\x26\xc2\xd2\x28\x70\x76\x5e\x46\xe1\x63\x51\xa8\xde\x99\xf8\x2f\xfd\xc9\xdc\x55\x62\x93\x7d\x6e\xe3\xf9\xaa\x33\xa9\xe1\x2c\x05\x4f\x59\xe6\x90\x91\x38\xcd\x20\x27\x01\xfe\x69\x16\x89\xf1\x58\x93\x74\xdd\xa9\xc6\xaa\x7e\xea\x62\x53\xc6\xdb\x77\x60\xa9\x53\x37\x55\x39\x7e\x42\x8e\xdc\xb3\x98\xd3\x3f\x9e\x7e\x77\xf3\x45\xd7\xa1\xb9\x8e\x9d\x89\xee\x5c\x86\x9b\x01\x97\x56\xfa\xb5\xee\xf0\x4f\x53\x1d\xfa\x59\x90\xff\x7c\x9f\x16\x1e\xd0\xd7\xfa\x51\x56\x1f\xc3\x4f\x2c\xfc\x48\x7b\x96\xe1\x6e\x57\xcf\x79\x59\x63\xce\x64\x2c\x48\x48\x36\x2f\x6b\xdc\x94\x65\xde\xd7\x19\x99\x44\x49\x9c\x0a\x97\x49\xa3\x45\x62\x0b\x4e\xdb\xe9\x4a\x8e\x88\x49\xed\x51\x6a\xb0\x2c\x72\x62\x50\x49\xac\xd6\x26\x22\xfb\x15\xe1\x61\x38\x87\x33\x15\x69\x5a\xe1\x6f\x9f\x5f\x9f\x56\xeb\x97\xed\x9e\xd8\xc9\xab\xc5\x6e\xbd\x9d\xf4\x57\x85\xd2\x9f\x48\x78\x5e\x65\xec\x5c\xfb\xe5\xf1\x27\xc2\x30\x55\xf6\x0b\x2f\x2c\x6d\x9f\x34\x17\x6f\xcb\xca\xd0\x4a\xe6\xdf\xa3\x96\x9c\x72\x5f\x06\x51\xb9\x2d\x73\xaa\x95\x7f\x9b\xda\xdf\xf0\xd4\x0b\xa5\xb0\x54\xd4\xd9\x7e\x99\x06\x21\xe7\xc9\x20\xad\x42\x4f\xec\xc7\xc1\xfc\x4e\x2b\x0d\xa2\x24\x19\x61\x85\x16\x5f\x40\xa8\x84\x42\x3d\x95\xf3\xab\x70\x1a\x70\x4e\xfa\x01\x2f\xa8\x6e\xda\x4f\xd9\xfd\xd9\x18\x4f\xd2\x5c\xdd\x5e\x65\x41\x68\xbf\x23\x54\x9d\x61\x40\xd7\x14\x52\x82\x46\xca\xac\x01\x85\xf9\x88\x70\xc6\xd3\x28\x42\xaa\x50\xbf\xe3\x4f\x77\x64\xfc\x12\xe2\x40\x92\x05\x73\x21\xac\x8b\xa3\x3b\x33\xd6\x3e\xd5\xd2\x5f\x30\x87\xf3\xae\x2c\xf3\x7a\x10\x87\xa4\x2c\x96\x3c\x74\x58\x91\x7e\x17\x9f\xa6\x36\x9b\xb8\xa1\x02\x66\x81\x3f\x9b\x6a\xb8\x83\x4f\xb9\x36\x69\x9a\xa3\x11\x82\xb1\x38\xf9\xf9\xf7\x09\x9c\x51\x8e\xb5\xfd\xdd\x1f\x65\x95\x2b\xe7\xbc\x79\x3f\x24\xa5\x0d\xda\x63\xea\x0f\xf3\xcd\x2b\xcb\x44\xf1\xa7\x2f\x5d\x78\x3c\x92\x56\xa6\x9c\xd4\x78\x4d\x08\x5d\x8f\x70\x3a\xa9\x08\xb4\xd3\x21\x7a\xfe\xc4\xea\x33\xc3\x2f\x03\xfe\x9a\x66\x34\x52\x11\x85\x9a\x75\x59\x7d\x53\xec\x9d\x7c\x07\xc1\x8d\x3c\x21\x61\x55\x6f\xb2\x79\x95\x20\x9e\x0a\x89\x54\xa5\x16\xd0\x48\xd2\x14\xa0\x8a\xf4\xc0\xc5\xc7\xb5\xd3\x31\xf5\x71\xda\x68\xef\x9c\x52\x22\x4f\xa5\x97\xd2\xcf\x2c\xab\xf3\xb1\x81\x93\xab\xb1\x97\xd5\x79\xf8\xf1\xa4\x1f\x3b\x8c\xe8\xa6\xac\x1a\x5d\xe6\x9d\x72\xe3\xa4\xb4\x98\x2a\xcf\xf7\x55\x87\xbc\x34\x4a\x70\xbf\xe3\xf9\xb2\x1a\x31\x9c\x35\x52\x85\x29\x18\xbe\xda\xb2\x3a\xab\xea\x7b\x86\x5f\x03\x14\xe2\x70\xcf\x94\xa2\x1f\x51\xb1\x63\xbb\x5b\xec\xf6\xcb\xe7\xd7\x27\x17\x64\xa4\x18\x70\x93\x73\x51\xea\x91\x50\x17\xbf\x40\x66\xa5\x3a\x62\xda\x6c\xe8\x64\x86\x9f\x68\x96\xb3\x5f\x32\x61\xdb\x73\x4c\xd8\x37\x40\xdc\xb0\x76\xcb\xe8\x0e\x27\x1e\x29\xee\x93\x62\xf8\xaa\x1d\x05\xf6\x08\xf7\x7c\x89\x24\xa3\x0f\xc7\xe3\x25\x65\x83\x73\x5f\xc6\x14\xa4\x1f\x3a\x77\x16\x77\x66\x10\x02\xe5\x7c\x2c\xde\x6f\xdf\xae\x99\x66\xa8\x8c\xa7\x1e\x1e\x00\xb0\x5e\x30\xcb\xd0\x5f\x27\x19\x2c\xd7\x19\x78\x20\x54\x2c\x3a\xf5\xfe\xfa\x94\xb7\x41\x23\x11\xcd\x6c\x83\x30\x02\x42\x85\xbf\x97\xb9\xb2\xfd\x32\xea\x8e\x25\x9c\x92\xca\x0f\xcf\xbb\xdd\x9f\x83\x95\x8b\x47\x09\x33\x23\xfc\x1d\x2a\x34\x4b\x68\xb7\x05\x5b\x34\xd7\xc3\x79\x1e\x25\x40\xbc\xa5\xcd\xfa\x65\xfb\xfc\xb4\x78\xe8\xc9\x85\x9c\x47\x29\x68\x36\x7e\xe5\x7e\xff\xca\x79\x12\x29\x1e\xf4\x21\xea\xa9\x92\xd8\xd9\x20\xbb\x78\x83\x27\xdc\x23\x9c\x30\xad\x08\xb3\x16\x0b\x9c\x33\x1f\xb9\xd9\x98\x12\x0a\xf9\x64\x7c\xd1\x86\x1d\x8f\xb3\xc0\x38\x72\x9a\x41\x3b\x55\xe8\x6d\x8f\x0b\x6e\x00\xb5\xb6\xac\xfe\x9f\x41\x7c\x3b\x04\x8f\x73\x16\x73\xca\x3c\x7c\x2b\x97\xef\xd9\x63\x56\xb8\xcd\x36\x67\xdc\x50\x21\x25\x14\x37\x15\x22\x99\x73\xd1\x6f\x44\xde\x7f\x99\x7f\xb9\x86\xe0\x53\xee\xd8\xcd\x5c\x24\x0c\x70\xaf\xf0\x70\x2c\x9b\x81\xd0\xc6\xb0\x26\xd0\x13\x47\x39\x67\x52\xd2\x96\xef\x08\xe7\x47\x37\x7f\xf3\x94\x49\x63\x8b\x6f\x0c\x07\xca\x91\xe8\xe2\xe4\x75\xa5\xca\x53\xc6\x25\xfc\x54\x7c\x3c\x75\xbd\x95\x07\x5c\x09\x47\x61\x6c\xa3\x6a\xb5\x3b\x1f\x71\x8b\xff\x3e\x61\x21\x71\x42\xcf\xe0\xed\x97\x51\xed\xe3\xae\x5e\x9f\xd6\xfb\x9b\xd7\xbb\xbb\x3f\xbb\x0b\xb1\x88\xd2\x2d\x84\xf2\xe8\x3d\x11\x87\x51\x32\xe7\xc2\x27\xd0\x49\x1f\xf8\x6f\xbe\x2d\xb6\xeb\x7d\xb8\xa7\x5c\x45\xd7\x4c\xfb\x54\x3f\x31\xf0\xaf\x15\xd6\xb2\xca\x8e\x17\xf2\xec\x9c\x43\x6a\xec\xa1\xcc\xf6\x75\x34\xe7\x70\xe0\x8a\x1c\xaf\xf6\x35\x0e\x19\xc9\x9b\xaa\x3c\x4e\xae\x22\x04\x1f\xce\xec\x63\xd7\x20\xce\x65\x22\x29\x40\xb5\x2e\x25\x93\x31\xac\xd2\xd0\x20\x92\x7e\xd6\x1b\xac\xbe\x95\xa7\xc9\xba\xc1\x95\x50\x26\x8c\xb7\x86\xee\xa5\x95\xa5\x9f\x0d\x31\xb9\x52\xa1\x1f\x59\x88\x3d\x14\x67\x87\xaf\x74\xf7\xa2\x53\x41\xf0\xbf\xef\x50\x15\xd9\xcf\xd1\xab\xd5\x18\x10\x7b\x56\xe1\x4f\x02\x1b\x9b\x60\xea\xd7\x79\x63\xf0\x44\x40\xe9\x2e\x85\x0e\x18\xb9\xec\xbd\xfb\x39\xf8\xa9\x4e\xd4\x98\x35\x67\x05\xcd\x57\xa7\xf6\x55\xdf\x2f\x9f\xfd\xae\x2d\x07\xd6\xc6\xe2\x8f\x8f\xcf\x03\x39\x6b\x92\x4e\xa2\x3d\xd5\x0e\xe1\x60\xb2\xb8\x8e\x10\x3e\x9b\xe2\x81\x40\x6b\x23\xee\x6d\xa5\xe6\x47\xf4\x0b\x08\x79\x4a\x10\xb6\x87\xf2\x6d\x53\xe6\xb9\x0b\x19\xc7\xf1\x0e\x84\xd2\xe7\xdc\x4e\x96\xed\xdd\x0e\x5f\x14\x44\xb1\x59\x45\xb0\x50\x54\x2f\x1e\x7f\x50\x88\x40\xd1\x40\xaf\xdf\xcb\x53\xae\xbe\x75\x92\x59\xd3\x66\x52\x12\x4a\x78\xef\x14\x63\x88\x13\xd7\x8f\x57\x88\x3d\x9f\xfa\xdf\x16\x8a\x6c\x00\x72\x86\x38\x00\x11\x76\x1c\xc3\x8f\xc7\xec\xcd\x20\x55\x7b\x42\x34\x4d\x53\xab\x8c\xf6\x11\xdd\x59\x09\xa7\xb7\x42\xc9\x89\x36\xf0\x1c\x0d\xf2\x21\x0d\x97\x43\xcc\xc2\xd4\x86\x5f\x47\xac\x9a\xf3\xbd\xda\x95\x56\xdc\x71\xfc\xf5\x63\x61\x10\x63\xed\x6b\xfa\x96\xbd\xbd\x63\x6d\x77\xcb\x4f\x65\xb3\xfe\xd9\x23\xb3\x20\x91\x09\xcd\x11\xb7\x20\x1b\x01\xd5\x0a\xbb\x2d\x18\x24\x52\xa7\xc3\x78\x0c\x44\x8e\x64\x81\xde\x35\xc0\x80\x10\x1f\xdf\xb7\xbb\xbf\x86\xa0\x02\x8b\x8d\x4f\x51\xd6\xc6\xfe\xbb\xf7\x0a\xa1\x03\xff\x41\x6a\xbd\xcd\xda\x50\xd3\xe9\x1f\xbb\x43\x18\x10\x60\xf9\xee\xf9\x61\xf5\x0f\xf7\x47\x9e\x18\xe7\xcb\x07\x7c\xb3\xbd\xb7\x3f\xa2\x29\xb5\x51\x43\x8e\x56\xcf\x60\x1c\xca\x01\xf8\xa9\x79\x2c\xaa\x32\x9a\x1a\x4c\xff\xd0\x10\x1b\x95\xb2\x02\xbf\x56\xa5\xbc\x48\x28\x0f\xe7\x21\x10\xbe\x71\x79\xae\x0f\x90\xe7\xcb\xe1\x4d\x0b\xe0\x72\x2c\x99\x38\xe9\x63\x02\x95\x81\xfb\xc1\x07\xee\x35\x62\xbd\xc7\xe6\x7d\xaf\x9c\x88\x27\x07\xe9\x85\xce\x14\xcc\x49\x2a\xf5\xe0\xc5\xeb\x7e\xc7\x1c\x24\x87\xd4\x12\x5d\x2d\x4b\x7a\x40\x24\xe7\x80\xc0\x3c\x43\x24\x57\x99\x3e\x2f\xb1\x9c\xdc\x98\x0e\x13\x4a\x2b\x1a\x5b\xbe\xc1\x6f\xce\x2f\x3d\xa0\x21\xa4\x31\x75\x84\x73\xcf\x78\x9a\x6d\x2a\xbc\x40\xd1\xfa\x52\x63\x63\x2c\x84\xf2\x4b\xd9\x0e\x5b\x64\x9b\x6a\x06\x0e\xfe\x15\x06\xff\x8c\xfe\xdf\xe4\xbf\x52\xf7\x0b\x71\x2a\x2c\x3c\x90\xa2\xf8\xec\x3f\x78\x07\xf5\xf1\xb2\xc2\x21\xfc\x38\xa5\xcc\x34\xd9\xb8\x38\x0d\xb1\x7a\x68\xfe\xcf\x45\x10\xa6\xa4\xdb\x42\x64\x3c\x4b\xa8\xd3\x99\x71\x78\xfe\x96\x15\x6d\x94\xb6\xcb\xde\xde\x9b\x1b\x9a\x6a\x46\x97\x0f\x62\x08\x4c\x9a\xab\xfc\x79\xbe\x71\x15\x8d\xf1\xab\x16\x61\x62\x28\x93\xbb\xff\xbe\xed\x8d\x1e\xb9\x88\x40\xd0\x7c\x70\xe8\xc9\x71\x7b\xd9\x41\xf0\xf7\x9f\x81\x6b\x18\xfb\x61\x24\x07\xa4\x0d\x47\x48\x99\x4c\x7b\x22\x4e\x7c\x1a\x5c\x24\xa3\x51\x95\x1f\x5d\x38\x2b\x62\x9e\x48\x36\x00\x46\xbd\x40\xb7\xd3\x13\xb1\x88\xa5\x55\xbe\x20\x41\xdf\x0c\xae\xd4\x17\x45\x2c\x23\xda\x2d\x14\xa5\x42\xeb\x79\xe1\x42\x6d\x91\x04\x8c\x3c\x82\x0d\xe7\x8f\xf8\x3b\xc6\x77\x61\x34\xab\x8b\x04\xd0\xb0\xc1\xf3\xbc\x77\x88\xee\xde\x48\x22\x7c\x6e\x26\xb3\xc3\xd1\x95\x30\x06\x50\x73\xc1\x94\x4f\xa5\x03\x02\xa2\xdc\x96\xd5\x0e\xea\x8f\xc9\xf7\x66\x2a\x22\x88\xb5\xf5\xc5\x29\xcb\x46\x18\x03\x5f\x7b\x1c\xc2\xc0\xc9\xcf\x75\x9c\x75\x9b\xe1\x1d\xbf\x4c\x48\x91\x92\xe2\xd6\x3e\x0d\x6a\xa3\x68\xe5\xae\x23\x62\x46\x10\x12\x13\x70\xdc\xc1\x01\x8d\xa8\x4f\x7e\x51\xe6\x75\x27\x24\x3e\x31\x6f\xbe\x21\xe4\xcd\xfb\x12\xea\xf7\xc7\x3e\x28\x10\x92\xa7\x4e\x15\xcd\x10\xe7\x36\x90\x15\x0d\x2a\x42\xdb\xd4\x43\x87\x0e\x77\x82\x4c\x62\xe1\x8c\xa8\xf0\x42\xd3\xb0\x6b\xa5\x5d\x66\xe6\x07\x54\x6d\x50\x77\x1e\x3b\xf0\xfd\xb2\xf8\x23\x94\xc7\x8c\x22\x68\x8e\x60\xe5\x7a\xba\x6f\xa5\x82\x68\x64\x93\x32\x9f\x37\x11\x4a\xfa\x4e\xa8\xdc\xe4\x5a\xbe\x41\x7d\x67\x54\x71\xae\xbc\x28\xa5\x12\x42\x6c\x5a\xe5\xc1\xd5\xe6\x01\x8d\x58\x84\x5a\xe4\xf9\x0a\x1c\x3a\x52\x20\x67\xa4\xbf\x7c\x07\x59\x71\xc0\xaa\x36\x11\xcb\x2f\x33\x55\x42\x87\x7e\xea\x84\xb8\xad\x5e\xed\xb0\x5c\x31\x5f\x6b\x16\x3a\x35\xe0\x9c\x1a\x9b\x1f\x59\x81\x83\xc4\x60\x1f\x2b\x08\x0d\x8c\xb2\xd1\xa4\xb7\xb0\x3e\x96\x72\x5e\x66\x95\x4b\xcf\x37\xe6\x2f\xed\xa6\xf3\x5e\xb5\x03\xce\xba\x0c\xfd\xe6\x1a\x70\x0f\xbc\x81\xbd\x51\x6e\xf6\x56\xa3\x2d\x8d\xbb\x37\xe9\x43\x48\x55\x59\x8b\x02\xa5\xf9\x61\x0a\xae\x92\x3e\x48\x4a\x2e\x0d\x52\x7e\x04\x59\xff\xc5\x46\x5d\x06\x11\x10\xbc\x64\xef\x90\x85\x56\x7f\x67\xd2\x2a\x09\x89\x7d\x71\xb4\x69\xdd\x76\xca\x1c\x22\x3e\xae\x7c\x8e\x61\x12\x42\xb6\xfb\x3b\x6b\x3a\xb0\xc1\x09\x9b\x52\x86\x3e\x0f\xed\x4c\xbf\x3d\x82\xc4\x36\xaa\xef\x2b\xd9\xfe\xa4\xc7\xca\x90\x33\x23\x84\x7c\x20\xd2\xc1\x6f\xdd\x9f\x8d\xb4\x42\x7b\x95\x2c\xff\xc4\xea\x57\xfe\x0f\x5c\x86\x2a\xa4\xf5\x9e\x0a\x62\x66\x5f\xe6\xae\x14\xa5\xcc\xc3\xb1\x64\xea\x38\xec\x90\x71\x60\x6a\x50\x0a\xb2\xde\xef\xbd\xfd\xb3\xf1\x75\x7c\xc3\x5e\x06\xd4\x94\x35\xd6\x16\x3b\x99\xba\x96\xb1\x44\x63\xdc\xe8\xcc\x9b\xb8\x8c\x99\xa0\x4d\x70\x76\x38\x96\x55\xe3\x16\x80\xa1\x86\xc3\xfc\xee\x40\x26\xcc\x08\xc0\x53\x99\xb9\xfa\x20\x87\xfa\x66\x08\xc2\x94\x49\x6a\x8c\x1a\x44\x59\x55\xe5\x17\x56\xe6\x79\x6f\x33\x68\x8c\xd8\xfc\xf0\x21\x12\x1e\x18\x0d\x31\x13\xba\xdd\xd7\x4f\x65\x73\x4b\xb2\xc9\xb7\xa5\x3d\x71\xf2\x2a\x13\x6b\xec\x8b\x07\xac\xde\xb0\x90\xe7\xc1\x56\x48\x32\xcf\x4c\xd6\xe5\x57\x21\x46\xa8\x09\xc9\x12\x65\x8d\x0f\xca\xfc\x5b\x9f\x21\x91\x8c\x99\x78\x6b\x2f\x4e\xe7\x4d\xb8\x9a\xf4\x46\xa6\x14\x4d\x1d\x7b\x33\x74\x6e\x4e\x55\x31\xbc\xfb\x34\xf6\xb4\x7d\x17\xf7\x0d\x1e\x7e\xcf\x8a\xa1\x91\x20\x97\x69\x8a\xb4\x71\x23\xf2\x7a\x97\xbe\x9d\x7f\xaf\x9c\x25\x34\x35\xee\xf7\x12\xf2\x5c\x80\xfc\x98\x2a\x19\x8e\xdb\x83\x27\xd8\xb0\x32\xf0\x52\x9e\x9a\xac\x78\x1b\x62\xd9\x26\xf3\x04\x40\xa8\x82\x7e\x63\x3c\x1e\xf6\x00\x40\xe6\xd4\x87\xac\xd8\x54\x78\xe9\x13\xc6\x25\xa0\xe1\xff\x7d\x4d\x9f\x63\xfe\x79\x04\xf8\x04\x53\x79\x3c\xe5\xbb\x0a\x46\xf3\x91\xd4\x09\xf9\xd2\xd6\x4d\x05\xe3\x99\x4a\x25\x1e\x71\xa3\xda\xc0\x87\x70\x9b\xdb\x7e\x57\x21\x29\x7f\x3b\xb8\x81\x15\x7e\x12\x8d\x72\xfc\x94\x18\x98\xa2\x54\x8d\xcd\x03\x82\xbe\xa8\x03\xbb\x66\x10\x3b\xf1\xff\x15\x42\x3e\xa0\x95\xff\xd7\xe9\x9a\xa5\x3e\x97\x5a\xfa\xa9\x4d\x53\xd9\xbd\x11\x4d\x1d\x8b\xe9\x2c\xa6\x35\x27\x61\xc8\x1c\xea\x66\x5f\x19\xd3\xed\xd9\xc9\x5b\x79\xc2\xa3\xa8\x79\xa1\xd4\x23\x54\xe4\xa8\x3a\x35\xc4\x9d\xbb\x7f\xe5\x47\x8a\xf2\xc5\xc5\xe9\xf0\xac\x6d\x96\x34\x3b\x74\x88\x4a\xe5\x4b\xa4\x2a\xd8\x50\x99\xba\xc3\xad\xfe\x3f\xd7\x48\x45\xa2\x57\xa1\x38\x36\xb8\x0f\xd2\xee\x02\xe8\x51\x51\xca\xe6\x21\x89\xad\x3b\x5b\x2f\x1a\xdc\xe9\xec\x6a\xa7\x7c\x1d\x2b\xde\x45\x36\x1b\x03\xf1\x5c\x1b\x59\xb4\xf9\xaf\xa3\x02\xdf\xeb\x38\x0c\x6f\xf8\x0d\xf3\xe3\x20\x83\xd5\xaf\x91\x2a\x50\x1e\x71\xff\xb7\xc7\x3c\x6b\xfa\x6c\xab\x0a\x23\x33\xe3\x65\x75\xbb\x9d\xce\x8a\x37\xa3\x17\x71\x6b\xb7\xe5\xaa\x6b\x27\x25\x33\x0b\x71\x95\x61\x6d\x65\xc3\xed\xb1\x98\xa5\x38\xc8\x39\x90\x90\xd0\x95\x32\xb7\x3d\x23\xf1\x8c\x8a\x91\x91\xe7\xc7\x4b\xa7\x41\xae\x12\x3f\x89\x9d\x53\xe8\x57\x81\x6a\x2e\xbc\x57\x89\x0f\x7e\xdb\xd1\xef\x0c\x8c\x63\x0b\x1a\x9d\xdf\xdb\xb8\x21\x0b\x53\x8a\x3e\x56\x19\x38\x79\x21\xae\x18\xf3\x8c\x58\x6b\x53\x65\x6f\x6f\x58\x6d\xbe\xaf\x0d\x08\x77\x7c\xb3\x69\x14\x87\xbe\xcb\xb8\x5a\x76\xe3\xef\x59\xf1\xa6\xca\x43\xd7\x89\x52\x11\x10\xef\x44\x5a\x3d\xcd\x3e\xc2\xee\x4b\x94\x8a\xc7\x29\x5a\x39\xbc\xd7\x76\xd1\xb9\xd0\x00\xe3\x0a\x3c\x9f\x10\x80\x46\x1e\xc3\xa6\x1d\xa8\x93\x04\x9e\x6b\x12\xb0\xb0\xff\xe2\x54\x95\xcb\xc0\xd5\xb4\xee\xf5\x13\x4a\xac\x6b\x98\xb8\x26\x70\x05\x51\x9a\x80\x95\xef\xc8\x20\x5f\xcb\x32\x2f\xdf\xce\x2e\x11\x30\xba\x07\x96\x50\xca\x61\x05\x59\x7e\xee\xfd\x75\xb9\x02\x30\x08\x4f\xe7\xdc\x66\xa1\x35\x33\xc1\x89\x02\x40\xe3\x17\xb1\xfc\xb6\xdf\x22\xb4\x2b\xa7\xb3\xa0\xe5\x0a\x24\x0f\x64\x87\x14\x6d\x97\xe4\xec\x98\xe3\x90\xc8\xe0\x1a\x2a\x63\xf6\x47\xab\xc2\xb3\xbe\x32\x04\x84\xaf\x8d\x78\xac\xb3\xfb\xbf\xae\x9f\xc5\x95\xe0\x8a\x58\x72\x6f\xa4\x00\x61\xca\xe5\x24\xa3\xd5\x27\x90\x1e\xca\xb7\xcc\xb1\xd5\x95\x50\x26\x1b\x74\xfb\xba\xfb\xc3\xfd\x4d\x32\x4d\x90\xe7\xf5\x77\xc7\xd1\x53\x0a\xb4\x30\x68\x3e\x2b\x58\xf0\xcb\xb2\x8a\x42\x1f\x09\xda\xf8\xed\x74\x3a\x1d\xa0\x70\xce\x6c\x7f\x13\x19\xa9\x50\xa7\x1c\x1c\x3a\x3c\x6b\x96\x79\x59\xf4\xf3\x99\x0e\x8c\xb6\x34\xd5\xb7\x4a\x6b\xa8\x53\x56\x13\xba\x20\x7a\xca\x20\x41\xde\xb0\x79\x28\xe5\x48\xe9\xdc\xb6\xf0\x39\x70\xa7\xbe\x65\xba\x89\x29\xa5\x0f\xa2\x3f\x97\x50\x18\xcc\xfc\x18\x46\x1e\xf5\xcf\xe7\xd5\x50\x24\x8b\x63\xc8\x31\x9e\x18\x4a\x19\xbd\xa8\xc9\xa0\xc6\x48\x43\x62\x23\xc6\xd7\x5a\x6d\xb0\xfa\x7d\x06\x22\x8d\xb1\xe7\xa7\x36\x74\xfd\x41\x8e\x9d\xd3\xe3\xb1\x66\x56\x71\xd8\x6a\x20\xed\xca\xc7\x01\xf8\xce\x35\x83\xd8\xb3\x13\xfb\xb6\x80\x0f\x3c\x80\xf1\x13\xfb\xb7\xbb\xed\x24\x15\x1d\xb2\xd7\xf7\x26\x9a\x2e\xc8\x42\x8f\x1b\x76\x33\x55\x34\x47\x0f\xcc\xb8\x64\xbd\xe0\xa4\xb2\x99\x9b\xe9\x05\x64\x2a\xfb\x2d\xd7\xcb\x40\xa5\x67\x7e\x63\x88\x0c\x91\x64\xb1\x0b\xfc\xda\xbf\x0d\x04\x36\x26\xcd\xd2\x34\xa2\xba\xca\x11\xce\x2f\x17\x1a\x2e\xc8\x23\x46\x78\xa5\x8f\x4c\x7e\x3c\x9f\x2c\x0a\x72\xf2\x66\x78\x0c\x4e\x08\xfe\xba\x40\x11\x82\x2f\x22\x2a\xa1\x80\xd6\x39\xee\x6f\x69\xcb\xde\x2d\x1b\x08\x21\x23\xd1\x91\xc3\x59\x67\x72\x00\x05\x42\xe0\x62\xb0\xd5\xbc\x69\xa4\x9d\xc0\xbe\x0d\xa4\x30\x27\xef\x61\xf4\x04\x20\x0d\x57\xf9\x11\xdf\xe0\x07\x34\xcd\xb4\x7b\x83\x0a\xe8\x87\xad\xcd\xe3\x6d\x59\x2d\xf3\xb2\x9e\xa4\xa8\x50\xc4\x91\x81\x1d\xfd\xa4\x93\x97\x0f\x4f\xba\x2a\x0f\x66\x09\x7c\x84\x8f\x6b\xe3\x17\x45\xcc\xe9\xa9\x75\x0e\x4d\x27\x9d\xcc\x51\x7a\x31\x81\x91\x3b\x84\x9a\xeb\xe8\x4f\x65\xb3\x2e\xc8\x34\xae\x6b\x1a\x1a\x5c\x9e\x09\x31\xb7\x47\x2c\xd4\x0c\x22\x1c\x25\x46\x94\x3d\x32\xb3\xca\xa3\x51\x68\x18\xc6\x9c\xc6\x72\xec\x13\x1a\xdc\x0c\xcd\x96\xec\xe9\x18\x1a\x67\x8c\x2e\x10\xcc\xb4\xc6\x0e\x0e\x35\x13\x27\xa0\xf6\x91\x0a\x32\x26\x17\x37\xe7\x5d\xc1\x51\xc7\xa6\x74\xdd\xbc\x1b\x54\xb6\x7d\x26\xed\x79\x1e\x61\xa5\xb6\x37\x77\xc3\x81\xa0\x3d\xdf\xcc\x48\x92\x5c\xd3\xf3\x47\x12\x84\xec\x0e\x06\x01\x2d\xe1\xed\xca\x2b\xa0\xb6\xaa\xf3\x64\xc3\x75\x38\x42\x0f\xda\xd4\x5e\x18\x13\x02\x5b\x9c\xb2\x5c\x3d\x66\x39\xd6\x4d\x59\xfc\xc5\x68\x69\x4f\xa2\xe0\x4e\x42\xa5\x08\xed\x3a\x39\x2c\x35\x6d\xd1\x4c\x2f\xb4\xb9\xdc\x1f\xef\x58\x6c\xe0\x54\x5f\x57\x4d\xfb\x75\xee\x46\xfb\x49\x4c\x96\x8f\x66\x2b\xe4\x44\x1d\x47\xa3\x4b\xfb\xe0\x13\xa6\x64\x43\xd6\x28\x37\x90\x0f\x0d\xc8\x67\x16\x2e\x1d\x80\x24\x44\xb4\x42\xd9\xbd\xbb\xd0\xf3\xa4\xa9\xe8\xb7\x5f\x95\x34\x87\x86\x04\x7a\x1d\xa6\xc6\x10\xdf\xca\xdc\xb6\xe1\x88\xd3\x7e\x9f\x04\xa6\xee\x04\xd0\xda\xf2\x1f\xa7\xbe\x13\x83\x08\x41\x47\x0c\x23\xdf\x15\xb6\x56\xf8\x89\x79\x79\x3c\x58\xb1\x81\x31\x06\x5f\x47\x68\x04\xf1\xdb\xf8\x7e\x53\x95\x3a\x6b\xba\x23\x3a\x26\x38\xd8\x1e\x9b\xf7\x11\x85\x45\xc7\x29\xa7\x7e\x34\xaf\xd2\x54\x41\xf7\xfc\x09\xc7\x08\x7b\x0b\xb3\x1f\xef\xe5\xcd\xe9\x2a\xd7\xe3\xff\xfa\x6f\xfb\x5b\x2c\x8e\x48\x5d\xfe\xa1\x7c\xdb\x62\xe3\xb6\xa8\x66\xcc\xce\x4e\x12\x9a\x61\x90\xc6\x9d\x1f\xdb\xfa\xa7\xc4\x91\x25\xc1\xb8\x3f\x30\x04\xa9\x07\x49\xcd\xec\x8a\x91\x08\xd7\xa9\x27\x93\xb8\x63\x11\x51\xa0\x79\xb8\x98\xe1\x75\xea\x0b\xaa\x1b\x36\xd9\x81\x32\x43\xe5\xc9\x16\x0e\xdd\xbb\x4b\x13\x5f\xf8\x53\x9d\xec\xfb\xe2\xb3\xcc\x06\x0a\x4f\xa3\xaf\x9e\xa6\x11\x81\x7d\x6e\xee\x9f\x9f\xee\x97\xbd\x43\x26\xd7\x29\x18\xb6\x4d\xfb\x91\x07\x28\xe8\x17\xab\xb2\x3b\x94\xa9\xd3\x29\x44\x18\x58\x46\xfc\x72\x80\xcd\x1c\x02\x74\x35\xf8\x26\x7c\xdc\x90\x53\xe9\x06\xaa\x1c\xff\xb3\xac\xca\x2f\xd5\x7b\x38\x72\x0d\xa9\x8c\x8d\x0b\x91\x91\xdb\x18\xfb\x14\xb8\x46\x3c\x24\xd5\xdf\xf7\xf2\x54\xe3\xef\x88\xc7\x3e\x1e\xd7\x20\x05\x1a\x8e\xff\xb3\x20\x83\xf5\x6a\x7a\xb2\x94\x64\xfe\xf3\x88\x55\x3b\x01\x37\x13\x13\xe4\x19\xc5\x4c\xae\x45\xc2\x13\x8b\xfa\x22\x05\x30\xa3\xef\xe3\x7e\x52\xb0\x88\xa4\xe2\x89\x82\x97\x1d\xf0\x01\x75\x37\x20\x64\x24\x28\xf1\x32\x24\xe2\xcf\x92\xf0\xe7\xfb\x85\x4c\x0d\x55\xf4\x0d\x1b\xe3\x40\xbd\xa8\xaa\x6b\x0a\xef\x6e\x5f\xab\x25\xb0\x84\x77\xf9\xd5\xa9\xe5\x24\xd7\x52\x84\xbe\xb6\x30\xb0\xbd\xe5\xc9\xbb\xfb\x55\xca\x8f\x0d\x82\xe9\x01\xdf\xb0\x0d\x60\xcf\x9b\xc1\xee\x69\x72\x7b\xe8\xf9\xb4\x60\xef\x5d\x1a\x66\x2f\xce\xc6\x50\xf4\xda\x78\x1d\x64\xca\x34\xfa\x5e\x64\xe2\x2c\x05\x75\x97\xc4\x1b\x2e\x32\x98\x18\xdb\x84\xd5\xee\xdb\x50\xfc\xec\xe2\xaa\xd7\xf7\x06\x1a\x45\x4a\xd3\x69\x1b\x28\x0c\x84\x33\x34\x22\x12\x3b\x5e\x67\x79\xfe\x78\x26\xff\xa4\xc9\x68\x43\x2d\xb8\xad\x21\xac\xa0\x81\x7d\x18\xfd\xd6\x1f\xd1\x36\x8a\x22\x95\xf1\x2b\x89\x81\xae\xb5\xa2\xc4\xba\x51\xd4\xa1\xe7\x6b\x7b\xc9\x40\x00\x4c\xeb\x08\x94\xd1\x1e\xaf\x66\x75\x04\x46\xaf\x4d\xa7\xc8\x6d\x0a\xd7\xf4\xdd\xe7\x53\x13\x4c\x3e\xb1\x4e\x35\x95\x65\x6e\xb0\x59\x14\x37\xdd\xcf\xf0\x48\xd8\x74\x7d\x3b\xed\x96\x45\x87\x1e\x5e\xcc\x7f\x61\xf0\xbc\x38\x25\x85\xd3\x6e\xa8\xfd\xe6\x0e\x80\xaf\x23\x57\x94\x34\xf5\x87\x2e\xe2\x00\x2f\x08\x62\xaa\x8e\x0b\xcc\xcb\xe2\xad\xde\x95\xb3\xf3\x1e\x78\x41\xc8\xc1\x96\x7d\xcc\x1e\x7c\x88\x75\x06\x2f\x88\x3d\xca\x66\x69\x37\x99\x59\xe1\x91\xe1\xc3\x82\x17\x88\x44\xda\xfe\x7c\x3c\x35\x38\xee\xf3\x57\x53\xe6\xbf\x5a\x19\xc0\x0b\xb4\x01\xff\x9b\xe5\xfe\xbe\xfe\x8e\x55\xa6\xb3\x21\x12\xaa\x7f\xd8\x30\x30\x6c\x59\x7b\xc8\xed\xda\xc0\x0b\x99\x56\x26\xeb\x5a\xe8\xac\x3a\x6c\xb0\xd2\x28\x9b\x76\x06\x3d\xf6\xa9\x45\xf0\x22\x4f\x7a\xc6\x51\x8d\xbe\x46\x56\xbc\x39\x81\x57\xd7\xc0\xe7\x04\x11\xea\x14\xbc\xc6\xf7\x1a\xe9\x34\x10\xfd\x8a\x39\xe7\x46\x00\x5e\x1c\x30\xba\xc6\xfd\xe1\x08\xb2\xe9\xca\x8d\x93\x46\x3a\xa6\x89\xd5\x2c\xdd\x34\x39\xd7\x90\xcf\x46\x3b\xe0\x25\x81\xa2\x8a\xd5\xfa\xa7\xd9\x13\xfa\xbe\xbb\xdf\x44\x71\xea\xf1\x56\x49\x6d\x57\xd2\x5e\x0f\x7b\x41\x7d\xdb\x8e\x45\xa9\xf3\x33\xec\x92\x30\xeb\xe6\xbd\x93\x85\x76\xd7\x63\x2c\x82\x0e\x8c\x99\xe7\xb7\x88\x5b\x09\x39\xcc\x4b\x70\x83\x97\xfa\x01\x05\x80\x79\xd6\x18\x83\xbf\xee\x83\xa4\x32\x86\xd0\x79\x17\x58\xcf\x17\x57\xb5\x9c\x3c\x1d\xf7\xfd\xd4\x86\x21\xf4\x74\x77\x15\x5c\x3a\x3f\x99\xfa\x7a\x30\x29\xbe\xbb\x2b\x48\x16\x18\x93\xf0\xcf\x3e\xa0\x06\x0f\x62\x23\xdf\xb6\xfe\x17\x54\xd9\xcb\x29\xef\xbb\x0b\xc4\x9a\x96\xae\xde\xaf\xee\xba\x07\x39\x78\xc2\x4b\x52\xe3\x81\xfe\x96\x15\x77\x5d\xe6\xae\x3d\x20\xc3\xa4\x53\x42\x5d\x61\x4d\xc6\x51\xa8\x5e\xf0\x58\x56\xcd\x53\xb9\x7d\x2f\xbf\xba\xdf\x14\x02\x68\xb3\x64\x13\x4f\xb6\xf8\xbf\x6c\x3b\xec\xdb\x28\x47\x4e\x4d\xb9\x83\xf4\x1b\x47\xe4\x39\x78\xde\x20\x61\x0c\x9e\x62\xc6\x5b\x49\xf4\x5e\x19\xab\xe7\x1f\x4f\xee\xc7\xd1\x37\xc9\x6a\x35\xd0\x76\xa3\xc2\xc7\x9c\x54\xc1\xe4\xf1\x51\x1b\xda\xa3\x53\xc5\x5f\x2d\x76\x6b\x77\x5d\xed\x85\xdc\xb8\xf0\xfe\xa4\x02\xde\x78\x52\xd1\x61\xca\x8c\x65\x4d\xdd\x18\x21\x82\x15\x7e\x2e\x17\xbb\x0b\xd9\x24\xf0\x74\xcc\x94\xd7\x0f\xe0\x1f\x73\x5e\x87\xe0\x69\x30\x6b\x3c\x65\x89\xc7\x7b\x56\xf0\x3d\xe6\x51\x65\xa1\xc0\xaf\xb1\x9b\xec\x7f\xcd\x15\x20\xc1\xf7\x35\x23\xce\xbb\x80\xe2\xc3\x0d\x28\x3f\x08\x8c\xcc\xe4\x6d\x56\xbf\xb7\x07\xae\x45\x0f\xae\x79\x1a\x53\x6d\xcc\xe1\xb0\x4c\x90\x68\x12\xb2\xae\x09\x72\xd4\x8e\x8b\x39\x26\x8a\x8c\x5f\xb4\x1f\x26\xa6\xe2\x5c\x11\x1e\x7f\x6a\x63\x03\x7e\x14\x99\xd9\xef\xf7\x93\x2a\xeb\x9b\xf6\xe6\xc6\xe7\x47\x4c\x11\x70\xb1\xa9\x40\x21\x59\x36\xba\x7d\x22\xf8\x91\x64\x81\x1d\x8f\x86\x05\x6e\x30\x0e\xf3\x37\x12\x61\x28\x82\x61\xd5\xb5\x50\xe6\xf3\x8d\xb3\xc8\x93\xb3\x92\xc0\xd4\xc4\x36\x39\x34\xe5\xd1\x61\x99\xc1\x67\x69\x48\x44\xcc\x5b\xac\x0e\x63\x48\x66\x7b\x4c\x52\xa9\xe5\xd8\xee\xdf\xdc\xdf\x64\x40\xd7\xa1\x8f\x4c\x59\x0f\xa2\x70\xaf\x8b\xb7\x81\xd7\xd7\x4c\x04\x02\x7e\x2a\x24\xea\xce\x70\x60\x02\x69\x07\x9f\xfb\x9c\xb2\x8c\x87\x8c\x32\x1a\x57\x1e\x03\xfc\x90\xc2\x18\x9d\x35\xf5\x08\x75\x38\xf5\x8c\x00\x1f\x00\x28\x09\xb8\x9f\x96\xaa\xec\x71\x11\x28\x1a\x1d\xb2\x3c\xac\x06\xc8\xcf\x5f\x2f\x88\xbe\x88\xc2\x98\x77\x9e\x99\x26\x25\xe4\xde\x8d\x48\x02\x97\x6f\x33\xe9\xe3\xdf\x46\x2f\x40\xf0\x98\x16\xf9\xa1\xd8\xdf\xa4\xf3\x4f\x05\xbe\xae\x74\x6c\xa1\x52\xb0\x28\x8d\xd3\x71\x6c\xfb\xef\x66\x34\x5f\x31\xe6\xf7\x4e\x8b\xdf\xb2\xcf\xae\xcf\xa3\x88\x4d\x1e\x1e\xb3\xdc\xff\xed\x32\x01\x05\x3e\x2a\x61\x90\x09\xef\x50\xe1\x43\xbb\xf1\xc1\x79\xe9\x77\xf0\xd1\x3a\x8c\x3e\x96\x9f\x68\xf8\x70\x7f\x95\xe2\x05\x5f\xfb\x11\x91\xd3\xb6\xeb\xe5\xeb\xcb\xcb\xb3\xbb\x2f\x9d\x44\x84\x9b\x5c\x34\xe5\xe1\xf5\x8f\xee\xaf\xc8\x0c\x36\x99\xe6\xe2\x53\x85\x2b\x22\x8a\x4f\xe5\x1c\xc6\x77\xa5\x75\x4c\xe1\xbb\xcc\x33\xad\x77\x08\x07\xe7\xe8\x9b\xf7\xe2\x34\x10\x04\x7e\xe2\x7a\xa4\x9b\xae\xc8\x33\xcc\x18\x65\x5c\xf8\x14\x40\x10\x44\x86\xdc\x6b\x53\x2a\xb2\xc9\x3e\xb3\xe6\x3c\xf7\xc4\x17\xb7\x14\x04\xa9\xe6\x93\xf0\xb7\xb6\xbf\xd6\xdd\x0f\x1a\xc8\x76\xdd\x90\xaf\xab\xfb\x73\x18\xfa\x81\x33\xc1\x73\xa1\xc8\x64\x7a\x0d\x42\x69\xac\xe0\x51\x65\xcd\x42\x5d\x51\x80\x1c\xff\xcb\x78\x17\x0c\xfb\xdd\x48\x1a\x21\x72\x57\x56\x3e\x2d\x30\x26\x02\x7c\x26\x31\x25\xbb\x90\x8c\x1f\x30\x0a\x22\xb0\xaa\x4b\x9b\xfb\x7d\x7b\x23\xfb\x20\x18\x8d\x80\x20\x12\x1e\x21\xc9\x86\xa9\xef\x89\x07\xd4\xe4\xad\xc5\xcc\xe8\xa6\x9a\x84\xc0\x0b\x7e\x62\x71\xc2\xc9\x0f\xc7\xd2\xa3\x99\x77\xf7\x9e\xd5\xeb\x9f\x86\x1a\xb4\xa8\x6b\x3c\x88\x6e\xb1\x0b\x62\x85\xa1\x1c\x06\xd8\xa3\x54\x0e\x04\x49\xa0\xe3\x74\x20\x19\x45\x95\xe0\x99\x59\x2c\x48\xc2\x98\x52\x55\xa7\xc2\xe9\x8b\x18\x5b\xde\xee\x42\x49\xe2\xcc\x00\x7b\x3c\x49\xd7\x81\x12\x19\x50\x72\xc9\x89\x2d\xc1\xa9\x46\x2b\x7a\xd4\x07\xd2\x41\xa2\x3c\x32\x77\x27\x09\x71\x39\x8c\x74\x47\x51\x7b\x17\x70\x05\xe9\x4c\x99\x1a\x82\x04\x85\xd3\x79\xdb\xc0\x19\x71\x00\x4a\x80\x20\xd1\x06\xd1\xb2\xbc\xbf\x7d\x71\x7f\x63\x51\xe4\xa0\x9f\x8f\x65\xd3\x75\x4b\x06\xc2\x1f\xb8\x8e\x75\x55\x99\xee\xb8\x14\x56\xaf\xa3\x69\xb0\x9a\xd2\x54\x26\x1f\x34\xf5\x34\xc6\x8e\x77\xf9\x0d\xea\xc5\xa9\x29\x7b\x1d\x4b\x08\xd2\x48\x11\x22\x05\x7f\x1e\x33\x13\xe5\xf7\xa6\x35\x10\xa4\x32\x25\x01\x18\xd3\x19\x7f\xff\x73\x39\x8c\x58\xdd\x52\x12\xf0\xd0\xa7\xc8\x8f\x5c\xb9\x47\x23\xc6\xa8\x10\x5f\xd9\x02\xd9\xb3\x81\x33\xda\x84\xde\x75\xc8\xd9\x91\x44\x24\x04\x00\x09\xa9\x2d\x81\x52\x2f\x44\xc3\xbf\xcd\xde\xde\x9b\x60\x85\xd0\xcc\xab\x9b\x41\x20\x82\x98\x2a\x73\x77\x58\xac\x7f\x36\x3f\xb0\x3d\xa1\x4b\xd9\xa6\xae\x11\x8b\x8c\x8e\x16\xd6\xcd\x4d\xd6\xd4\xed\xc2\x0e\x59\x4e\x5c\xc7\xe7\xe7\x1b\xf7\xf3\x42\x68\xc9\x06\x5d\xf5\xf5\xe5\xfe\xa6\x9d\xd4\x46\xdd\x54\x7a\x11\xc9\x58\xbe\xc1\x01\xef\x32\xdd\x3c\x17\x12\x87\x4e\x67\x10\x28\x26\x88\x61\x74\xaa\xb1\xda\x9e\x44\xc7\xa3\x98\xab\x31\x43\xa0\x52\x16\x58\x2f\x3e\x2b\xcb\x14\x74\x17\x4a\x65\x9a\xf6\xb8\x32\x6c\xef\x43\x36\xa8\xb6\x4d\x29\x3f\xb6\x58\xa8\xab\x5c\x21\x08\x94\x44\xbb\xef\x35\x24\x95\x0f\x2c\x88\xdb\x3a\xfd\xa4\xa1\x17\x18\x45\x8a\xbc\x7d\x73\xb4\x09\x7f\xc8\xc4\x6f\xee\x60\xc2\x09\x2f\x42\x6a\x52\xab\xc5\x6e\x31\x7a\x17\xa1\xa7\x22\x2a\x47\x98\xba\xf3\x2a\x73\x44\x38\x08\x7d\x3f\x76\x1d\x7e\xe8\x54\xeb\x8e\x4a\x1d\xc0\xa0\x24\x4c\xd3\xd5\x0b\x64\x1d\xcb\x18\xc2\x20\x94\xdc\x79\x4e\x1a\x75\xbb\xf1\x25\x82\x34\xa4\x18\x9b\x8a\xbc\x5b\xba\xce\x07\x2e\xcb\xc3\x01\xa7\x62\xec\x10\x86\xa1\x04\xa3\x19\x74\x7e\x3e\x35\xd3\x83\x2c\x4a\x2c\x62\x60\x83\xc5\xdb\x29\x2b\xea\x9b\xf3\x88\xd2\x63\x1b\x46\xc2\x54\xbf\xba\x54\xd4\xe4\x42\x31\x4b\xdc\x43\xb9\x59\xda\x4f\xdc\xe3\xc4\x5c\x49\x3b\x0b\xde\xb4\x6b\xc0\x00\xd0\x05\x61\xac\x62\xc2\xbd\xaf\xa0\xfc\x76\x12\x23\x94\x3d\x84\x09\x4b\xd5\x10\x87\x64\xfc\x4d\xcf\xdd\x32\x35\x97\x18\x86\x30\x51\x01\x05\x0f\x6d\x2c\x79\x3a\xee\xca\x79\xed\x76\x08\x13\xad\x48\x28\xfc\xf6\x44\xa8\x91\x05\xd5\xd6\xf1\x82\x44\x39\x39\x8b\x45\x7e\xdc\xd7\x97\x36\xe5\xf1\x94\x97\x13\x3c\x2e\x84\x29\x58\xb9\x0c\x1a\xc9\x77\x93\x1c\x2b\x84\xa9\x02\x61\xdf\xd7\x03\xea\x66\x59\x96\x6d\xf0\xdf\xee\x20\x06\x1a\x94\x10\xa6\xda\x38\x43\xec\xa0\x1e\x9a\x93\xb7\x07\x90\x00\x16\xcb\xb2\xa8\xb1\xb0\x1a\x49\xa5\x03\x38\x43\xc8\x03\xed\x19\xe7\x32\xbb\xd9\xef\xc8\xb4\x10\x72\xc6\x29\xc9\xbe\xbc\x79\x1e\x5d\x93\xa7\x09\xda\x5e\xb7\x5b\x3c\xdf\xab\x79\x39\x3b\x08\x45\x62\x5c\xe1\xa8\x94\xf1\x0d\xea\x01\xe6\x0e\x42\x19\x7a\x84\x3f\xb0\x1a\x02\x5d\xa5\x0f\x42\x29\x74\xe7\xe6\xf4\x9e\x1d\x49\xe9\x76\xb4\x8c\x85\x52\x25\x94\xb0\xb8\xc3\x66\x45\x41\xdf\xea\x79\x37\x24\x58\x0f\x52\xeb\xd0\xc6\x0f\x68\xfc\xa0\x4f\xf5\x6b\xde\x54\xe0\x7e\x47\x05\x21\x98\x49\xb1\x59\x17\xdd\x90\x52\x4c\x31\x53\x2c\xe8\x22\xbe\x2b\x8f\x87\x9e\x49\x2b\xf5\x4c\x85\xba\x33\x0d\xea\xe0\x4d\x10\x62\x18\x1a\x1e\xa9\x59\x73\x67\x75\x76\x26\x57\xd6\xa9\xa4\xf8\x77\x71\xc0\xe6\xfd\xdc\xb3\x22\x21\xd4\x22\x21\x42\x58\x1b\x45\x90\xac\x24\x34\xb8\x71\x53\x61\xe4\x31\x26\x78\x07\xee\xfe\xe6\xd8\x52\x10\x05\xbe\x22\x4c\xfe\x11\xde\xf0\x36\xcb\xaf\x78\xac\x40\x14\x20\x3a\x35\x2d\x23\x6f\x37\x23\x6e\x05\x51\xe4\x01\x91\x72\xbf\x20\xcf\xdb\x9b\x1b\x76\x8e\x28\x4a\x8c\x13\xcb\x80\x98\xd5\x89\xa3\x40\x14\xf1\x90\x96\x7d\xcb\xe9\x1a\x2f\xaf\x51\xa4\x02\x12\x0c\xf8\xcc\xf0\xcb\xa4\x0f\xeb\xee\x10\x7a\xa4\xcf\x69\x85\xf4\xbb\xbd\xd7\x6d\x59\x39\x75\x21\x88\x12\xcf\xd8\x0f\xd5\x16\x97\x00\x33\x34\x93\xc9\x13\x27\xb1\xa2\x5a\x7e\xbb\x44\x1b\x35\x40\x4a\x7b\x75\x57\x04\x16\xda\x2b\xde\xc1\x01\x9d\x28\xd7\xe4\x85\x24\x18\xa5\x36\xf4\xbc\x7b\x58\x8c\xfa\x6a\x94\x60\x22\x47\x26\x59\x88\xf7\x05\x75\xfa\x31\x5c\xa1\x6d\xa9\x9c\x23\x1b\xed\x6e\x57\x65\xb3\xca\xb4\xce\xe4\x29\x6f\xce\xd3\xb6\x1a\xc9\xca\x07\x6d\x46\x6f\x57\xda\xdd\xf7\xfc\x77\x65\xb1\x2f\xbd\x2e\x8c\xb5\x45\x6d\xda\xb6\x1a\x32\xdf\xcd\x69\xfa\x03\xcc\x8a\xf4\x2a\xcc\xe1\xfc\xad\x3c\xf5\x5f\x82\xf1\xd0\x19\x8f\x3e\xc2\xcf\x2d\xca\x53\x95\x35\x67\x92\x4c\x35\x2c\xe5\xc9\x85\x54\x1a\x27\xbd\x2d\x72\x1b\x92\x8e\x36\x35\x51\xea\x4b\x4a\xb7\xad\x90\xcc\xf1\xba\x80\xe9\x2f\xc1\xd6\xff\x97\x5a\x23\x44\x29\xef\x68\xdd\x44\x2a\x9d\x45\x44\x42\xc4\x13\x9f\x3e\x7c\xbb\x72\x2a\x7d\x2a\xe4\x20\x1f\x15\xf1\xd4\x23\xab\x67\x97\x94\x9c\x51\xf8\x80\x88\x73\x4d\x7c\xb1\xad\xb1\x80\x5a\x28\xf5\x3c\x1f\x47\xf7\xf7\xc6\xa5\x12\xb1\xc3\x0d\xd9\xe4\xe3\x64\xc1\x88\x20\x08\xa8\x00\xfe\xf8\xc7\xd3\x85\xdf\x31\x44\xc0\x12\xfa\xd0\x02\x65\x79\x20\xfe\xc6\xf6\x58\x16\x1d\x5b\xaf\x6d\xc0\xa8\x68\x9f\xd5\x2f\xd0\x64\x3a\xbb\xb8\x6d\x48\x91\x46\xe8\x16\x9b\x26\x2b\xde\xea\x2d\xfe\x5a\xc6\x0a\x22\x11\x63\xc0\xad\x08\x2f\xf4\x59\xde\x48\x79\x8c\xbe\xfc\x27\xbe\x67\x32\xc7\xf5\xcf\xa1\x22\xd6\x30\x42\x8a\x54\x60\x22\xda\xbb\xf2\x20\xfa\x5c\x4f\xa4\x83\x94\xc0\xc8\x59\xfd\x5a\x63\x75\x5f\xdc\x55\xe5\xe9\x38\x0b\x2b\x86\xd8\x0f\x13\xe1\xc8\x0c\x2e\x95\x3c\x41\xc1\x4f\xcf\x88\x3c\xaa\xcd\x74\x8a\x9d\xed\x74\x32\x3d\x65\xf6\x89\x63\x9f\x27\x68\xe1\x56\x07\x3c\x54\xf8\x6f\x65\xc1\x56\x57\x9a\x0b\x23\xcd\x93\x9f\xe4\xc7\xd9\x22\x4f\x8d\x82\x88\x6b\xa0\xfd\xc4\x86\xfc\x2b\x38\x0f\x8d\xe9\x20\x0e\x12\xee\x88\x74\x6d\xc4\xfe\xac\xed\x4a\xee\x5e\x73\x1c\x46\x3e\xa4\x9d\x39\x2f\xfc\x7c\x2a\x07\xa9\xf6\x38\x8c\x12\xca\x7e\x5b\x68\xe2\x20\x5d\xfc\xb7\xc7\xd1\x2f\x27\xd0\x38\x8c\x19\xcd\xf7\xed\x6b\x7c\x3d\xfe\x2d\x06\x0e\xc4\x11\x53\xd2\xda\x4c\xdf\xcb\xf2\x1b\x54\xaa\xb3\xb4\x83\x38\x4a\x4d\x7f\x22\xde\xdb\xba\xdb\x87\xd1\x9c\x38\x94\xc8\x80\x38\x0e\xcc\xce\xfb\x1b\x56\xe5\x53\xa9\x86\x10\x31\x88\x19\x0b\x13\xed\x24\x42\x06\x1a\xb2\x10\xf3\xd8\x08\x83\x51\x59\xe4\xa6\x3c\x39\xd3\x94\xcb\xfb\x04\x1e\x26\xbd\x04\x0c\x6d\x73\x46\x93\x57\x0c\x42\xc7\xca\x04\xcd\x07\x2c\x9a\xbd\xd9\x48\x4c\xa7\xf6\x58\xf8\x9a\x74\xe0\xc5\xe9\x1c\x7b\xee\x36\xa4\x07\xcc\x99\xe5\xad\x8c\x7a\xbc\x3b\xc2\x90\x26\xdf\x1f\x4f\x4e\x9e\x19\xe2\x36\x9e\xe2\xa3\x0f\xd9\x69\x4b\x93\x80\xef\x08\xde\xf8\x37\x3f\xa5\xbb\xb4\x60\x64\x3f\xa1\xb3\xaa\x6e\xc6\x39\xaa\x18\xa3\x28\xed\x74\x8a\xda\x0e\x38\x31\x60\x87\x18\xb9\xa4\xa5\xa8\x73\x6b\x58\xc1\xb9\x5d\x18\xda\xad\xc6\x70\x7f\x19\x23\x18\xa3\x75\x5b\x1f\x34\xbc\x8d\x6b\xf6\x64\x2e\x7c\x8a\x75\x08\xe4\x95\x7d\xb7\x78\x5c\xef\xd7\x4f\x2b\x77\x63\x3a\x0d\x89\x6e\xfd\x85\xed\x54\x36\xd8\x14\x25\x5e\xc0\x52\x63\x0a\x2c\x31\xfb\xa4\x02\xd6\xe8\x79\x13\x4f\x31\x8a\x08\x6f\x9e\x17\x2f\xab\xbd\x8b\x9e\x92\x00\x82\x28\xe9\x32\xec\xf5\x85\xaa\x15\x24\x91\x97\x24\xa9\x23\xd0\x3c\xb5\xf1\x80\x94\xa7\x63\x36\x21\x79\x43\x12\x45\xa1\xf3\xcb\xb1\x13\xca\xae\xbc\x28\x70\x8d\x3f\x42\x12\x71\x99\x74\xce\x54\xed\x57\x1d\x61\xce\xc6\xfd\x32\x89\x03\x41\xfa\x7f\xf5\xe9\x70\xb8\xc9\x72\x51\x56\x6d\x2f\x76\xb7\x19\xa7\x71\x67\x8c\xb0\xad\xe4\x3f\x06\x29\xc2\x5f\x0e\xcb\x24\x4e\x35\x69\xee\x88\xac\x6a\xde\x37\x58\x7d\x3b\x15\xaa\xea\x5f\x6c\x22\x45\x88\x9d\x05\x21\xf1\x06\x9d\xa1\x65\x6d\xc0\x3a\xb6\x21\x03\x49\x19\xde\xc7\xfb\xcd\x72\x12\x1f\x26\x69\x60\x0c\x16\xca\xe2\xef\xe8\x00\x40\x92\x86\xa9\xb6\xd9\x9f\x7b\x3d\x40\x60\xb5\x47\xcc\x1b\x1b\xd5\xe8\xc6\x1f\x22\x55\x11\x49\xf8\xe4\x99\xc4\xa2\xc6\xa7\x5b\x37\x9c\x12\xae\x8d\xcd\x38\x54\x15\x18\x71\x9a\xc9\x96\x3f\x01\x10\xce\x06\x6a\xdf\xc6\x23\x17\x3e\x10\xc3\x51\x90\x88\xd0\x17\x8e\xd7\x4f\x92\x7b\xbd\x19\xcf\xd3\x29\xcf\xad\x86\x47\xd3\x75\x25\x01\xc2\x51\xb7\x9e\xf0\x67\x33\x52\x31\x9d\xbc\x01\x19\x1b\x79\xf1\xe5\xcb\xf3\x76\x71\xff\xb2\x27\xf7\xbf\x97\xfb\xa5\xab\xb3\x25\x2a\x95\x34\x9f\xd9\x04\xd8\x0b\xca\x77\xa8\x9c\xcc\x1a\x24\x4a\x23\x38\xb8\xc1\x80\x0b\x30\x54\xf6\x9d\x14\x0e\x27\x0a\x1f\x90\xa0\xef\xd3\xbe\xc0\xee\x61\x6c\x21\x7a\xca\xce\x1c\x9d\xa1\x85\xe7\x1b\x1d\x4a\x67\x3e\xae\xdd\x0d\x69\x96\x50\x98\x63\x32\x36\xeb\x63\x56\x97\x0a\xe7\xe0\x90\xc0\x3c\x25\x68\x87\xfe\x2d\xab\xf0\x6e\x28\x6b\x07\xcc\xf7\xa2\x20\x18\x30\x35\x4d\x7a\xe9\xb6\xac\x7e\x60\x36\x9e\x7e\x99\x1f\x9b\x84\xe6\x3f\xbe\xb2\xa1\x6e\xd7\xdf\x5c\x08\xed\x45\x02\x3f\x21\xc8\x31\x0d\xfe\xdb\xbc\x84\xa6\xc7\x49\x5c\xe0\x44\xa6\x96\xbc\xc0\x02\xe9\x63\xea\x10\xcb\x17\x10\xf6\xd9\xbe\xcf\xc2\xc4\x53\xba\x5f\x5d\x3a\xdd\xa9\xc9\x9c\x39\x11\x5e\x6b\xcf\x0b\x3d\x57\x34\x47\x38\xcc\xf6\x58\x16\x6a\x23\x95\x65\x4c\x73\xeb\xac\x2c\xf6\x55\xbf\x3f\x67\x51\x2a\x7c\x93\x71\x3b\xd5\xa8\x06\xba\x09\xc0\x22\x19\xd3\x46\x45\x66\x4d\x86\x75\x6f\x28\xdb\x1e\x41\xaa\x78\xd2\xca\xba\x84\x23\x6d\xd0\x4e\x55\xf3\xfe\xd8\xee\x57\x7b\xed\x3f\x60\x71\x14\x53\x49\xb7\xc9\x9a\x7c\x94\x19\x66\x71\x62\x8c\x9a\x6e\xd6\x8b\x5d\xf7\x37\xc1\xa9\x37\x29\x3c\xe6\xe5\x79\xdb\xe0\xb1\x83\x10\x01\x4b\x54\x4c\x51\x80\xab\xb3\xcd\x79\x0d\x02\x4b\x63\x83\x39\xa8\x90\x14\xbe\x1f\x4a\x09\x79\x1b\x33\xf4\x89\x07\x96\x2a\x43\x8b\xa1\x6c\x99\xff\xfc\xbb\xfb\x3b\xf7\x7d\xb4\x1b\x7d\x02\x28\xb5\xcb\xa0\xc9\x52\x9a\x81\xd0\xb5\x03\xae\xed\xce\x68\xf7\x73\x51\x6f\x8f\x58\x34\x17\x3c\xaa\xf1\x5d\x09\x15\xa2\x65\x0a\x7c\xa7\xba\xf7\xdb\x56\xbe\xa3\x3a\xe5\xb8\x2e\x9a\x2b\x52\x7d\xc0\xa4\x67\xd4\x61\xa9\x16\x62\xdb\x5f\xa9\x60\x30\x99\x40\x14\x74\x72\xe4\x26\x94\x1a\x8b\xb0\x01\x93\x52\xa2\x9b\xbc\xf6\x65\x61\x54\x50\xd7\xff\xbe\x2f\x1a\x57\xfa\x66\xca\xf3\x08\xe6\x90\xd5\xbd\xa6\xc2\x50\x8c\x75\x7c\x41\x15\x44\xe4\x33\xf2\x5a\xb8\xcd\xac\x2d\x93\xfe\x92\xc8\x0c\x4c\xc5\x8c\xfa\x24\x2d\x82\x2f\x50\xa1\x81\xbe\x5f\x79\x34\xc5\x52\xc7\x3d\x1d\x65\x90\xe7\xfb\xbb\x4a\x13\xb2\xd2\xac\x4b\xdd\xac\x30\xc7\x66\x12\xcb\x31\xf4\x7c\x42\x84\x2c\xf2\x06\x9d\x8f\xdc\x55\x8a\x32\x30\x4c\xb4\xea\x4a\xf7\x54\xc1\x9d\x99\x4e\x5d\x5b\x50\xaa\x73\xc7\x5a\x68\x9d\xe5\x19\x34\xb8\x5a\x75\x1d\x5c\xcb\x20\xb2\xda\x12\x37\x20\x3f\x70\xa2\xfd\xd2\x36\x60\xd2\x64\x70\xce\xe5\x89\x78\x72\xed\x13\x74\x03\x4f\x2b\x5f\x9b\x1d\xc9\xe1\x70\x7e\x3c\xd5\x99\x1c\x45\x2e\x4c\x6b\xa1\xa2\x89\x52\x42\x79\xd8\x1e\x31\x37\xaa\x08\xe9\x3f\xfd\x4e\x95\xc2\x9c\x92\x7a\xbe\xa6\x94\xbb\x9d\xf3\xaf\x39\x71\x5c\xab\x24\xff\x72\x32\x4d\x7d\xe1\xf1\x0e\xba\x4c\x0c\xfc\x6d\x03\xd5\xaa\x9f\x7f\xd2\x20\x61\x04\x96\x7f\x87\xda\x25\x2d\x17\xe4\x23\x3c\x7e\x31\x69\x00\x1e\x25\x19\xeb\x2f\xc4\x23\x69\x2e\x92\xf3\xa9\xbb\x4c\xe8\x79\x44\x37\x75\xd4\xac\x02\x0f\xe7\x65\x79\x10\x63\x84\x49\x1a\x06\x01\x21\x28\xb7\x8f\x8b\x87\x87\xf5\x76\xb7\x1f\x08\x05\x41\x1a\x46\x20\xa3\xae\x92\x55\x9e\x9a\xa7\xd3\xc1\x26\x82\xc6\x8f\x15\xb6\x71\x9c\x55\xbc\x24\xc8\xd3\xa0\xac\x96\xc6\x5e\x42\x93\xd8\xe3\xef\x7f\x0e\xd9\x3b\x90\xc6\x09\x23\x32\xf1\x22\x57\xd9\xb9\xec\x15\x79\x20\x8d\x99\x0e\x4c\xd9\x50\x9d\x24\x55\xc2\x7f\x20\x7e\x98\xd0\x7a\x76\x6a\x48\xe3\x34\x49\x0d\x40\x41\x37\xef\x8e\x50\x3d\xc8\xbb\xa6\x69\x88\x89\x75\x8e\xba\x6f\xf0\x30\xd0\xf6\x1b\x2c\x27\xe3\x57\x9c\x42\x4a\x39\x64\x4b\x3f\x86\xda\x42\x3d\x0c\x91\x7a\x9a\xe2\x4f\x39\x37\x56\xc7\xef\x50\x17\x0d\x91\xfe\xba\x7e\x9a\x82\x67\x02\x09\x52\xd9\xda\xff\x58\xaf\x7f\x0f\x86\xa6\x5e\x90\x42\x64\xb6\xd6\x6d\xa4\xdc\xee\xfa\x5f\x50\x42\xdd\xd4\x23\x34\xe6\xc5\x96\xa1\x7f\xc7\xa0\x12\x91\x74\xa9\xe9\x49\x57\x91\x41\x40\x03\xbc\x57\x23\x99\x76\x26\x15\x68\xea\x4c\x4b\x83\xc6\x35\xd3\xc4\xbc\x1c\x14\xa4\x18\xa4\xdc\xd6\xa4\x9e\xb2\xf7\x2c\x3f\xb9\x74\x6b\x8a\x51\x44\x25\x3c\x57\xa2\x5d\x96\x79\x59\xcd\x06\x38\x29\x22\x23\xaa\xd5\xd0\x43\x7f\x5a\xb5\xb0\x4d\x75\xe4\x93\x4e\xb5\x53\x96\x1a\xf5\x21\x1d\x9b\x9f\x6c\xa7\xf0\x76\xfa\xbe\xd2\x3d\x34\x37\xe5\x4f\xc3\x0e\x43\x65\x2c\xfe\xe6\xcb\xf5\x83\xbd\x5b\xaa\x05\xa3\x35\x76\xb1\xdd\xfe\x3d\x22\x5d\x7b\x8a\x29\x5f\x51\x00\xf1\x98\x0d\xd8\x9a\xc0\x3d\x2e\x3c\x0b\x8d\x76\x7d\x74\x92\x87\xe2\x7e\x10\x93\x3a\xcc\xd7\x7b\xb9\x38\xdc\xbb\x13\xfd\xd4\x08\x58\x1b\x1d\xcb\x8e\x0e\x3c\xc1\xfc\xf1\x20\x65\x94\x9a\x37\x2c\xc8\x6f\x67\x51\x65\x2a\xfb\xcf\x08\xb4\x39\x7e\x31\x3c\x0c\x03\x61\xc1\x9b\x36\x27\xfa\xfa\xf2\x30\x57\x81\xe7\xa1\xf2\x94\x4d\xd3\x0e\x70\xf5\xed\xdf\x35\xe5\x34\xde\xb2\xcf\x8b\x25\x63\xdc\x73\x78\xa8\x39\xe5\xf7\x0f\xf0\x73\x71\x3c\xf6\xa6\xe8\xc0\x23\x2b\xc1\x45\xc9\x1c\x33\xca\x1c\xa4\x60\xfe\x8b\xf2\x08\x19\xd5\x51\xff\xbc\xf9\x3e\xec\x10\x3c\x0e\x23\x42\x2e\x6c\x9b\x2e\xcf\xc4\x63\x6e\xdc\x88\x40\x29\xc3\x8d\xa1\xec\xc1\x4c\x8a\x9f\xc7\x28\xac\xf0\x1c\xf9\x97\x3a\xc4\xdd\xd5\xbb\x48\x84\xa0\xfe\x71\xa4\xcb\xae\x3f\x1d\xf3\xa0\x7b\x30\xc6\x0c\x73\xf1\xb3\xcc\x4f\x07\x9a\x43\x54\xaf\x79\xd8\x5f\x87\x71\x41\xbb\xfa\xed\x11\x65\x06\xf9\xcb\x8c\xa9\xe3\xfc\x8a\xc2\xd3\x24\x8e\xd1\xc1\x2d\xf3\xb1\x0e\x2d\xf0\x94\x87\xa4\xe3\xe3\x64\x1d\xe7\xe9\x40\xe3\x0f\x0d\xc2\x68\xa2\x9b\xfe\x79\x3f\x12\x0e\x05\x0e\xca\xe3\x51\x5f\xdd\x83\x0a\x28\x7d\x3d\xa4\xef\xbb\xa5\x94\x8b\x50\x3a\xff\xf8\x3b\x38\x90\xfe\xea\xfc\x43\x08\xee\xd1\x42\x43\xab\xcf\xfe\xf6\xfe\x65\xbb\xdb\xaf\xee\xb7\xa4\x4b\xba\x7f\x7c\x7d\xd8\xdd\x6f\x1e\xee\x9d\xd7\x3b\x70\x21\x21\xf0\x0d\xfd\x9e\xc0\x40\x68\xc8\x86\xdd\x53\x0b\x25\x28\x20\x5d\xfe\x3e\x58\x54\xb8\xd0\x66\x64\x65\xb2\xa4\x1c\x83\x83\xfc\xf7\x2c\xdd\xc8\x35\x95\x01\x23\x99\x12\x53\xba\xb6\x0c\x96\xc9\x27\x6b\x03\xcc\xc4\xa1\x87\x8f\xf9\x79\x79\x41\x59\x06\x2e\x53\x66\x18\x89\xf6\x65\x9d\x2f\x8c\xc0\x80\x2b\x4f\x13\xc4\xdd\x85\xf1\x06\x89\x38\x5f\xb9\xe5\x2a\x4e\x94\x0d\xfd\x6e\x32\x75\xaf\xba\x47\x56\xdc\x78\x9c\xc9\xf2\x70\x28\x8b\x5f\xaa\x5d\x00\x57\x10\x33\x03\x65\x3c\x5b\xfb\x81\xee\x32\x2a\x15\xc6\x1f\xc2\x76\xa4\x29\xf0\xdc\xb6\x43\x3f\x84\x0e\x6e\x63\x2c\xea\x8c\xf3\xe9\xa4\x19\x18\xed\xfb\x0a\x67\x28\x4d\x03\x56\x01\x70\x44\x93\x1e\xd9\x60\x53\x95\x23\x6b\x0e\xdb\x40\x47\x9e\x4b\x74\x53\xfd\xe2\x36\xcb\xf1\x21\x2b\x3e\xc6\xbd\x53\x47\xa9\x71\xe5\x1b\x22\x33\xdd\xb1\x84\x13\x1e\xc1\xa8\x78\x67\x6f\xe3\x09\xa0\x8f\x03\x26\x2f\x4b\xb3\x98\x38\xc6\x76\x4a\x30\x11\x64\x77\xcd\x34\xb2\x40\x8a\x76\x61\xed\xb9\xcc\xdd\xe9\xe0\x81\xa0\x3d\xe9\x01\xfe\x45\x89\x90\xdb\xb2\xea\x35\xb0\x00\x3c\xcd\x68\xc7\xf0\xb0\xbe\x5b\x3c\xec\xd7\x7f\x6c\xd6\x4f\xdb\xf5\x76\xbf\x58\xad\x5e\x1c\xb9\x1d\xc0\xb7\xd4\x5a\x63\x9b\xf2\x80\x9f\x8b\x42\xdd\xa2\x91\x95\xef\xe1\xac\xe0\x33\x4f\x1a\x27\x3b\x57\x3d\x1b\xa3\xad\xc0\x67\x3a\xe2\x63\x89\xb2\xf1\x7c\x01\xbe\x62\x6a\x50\x6e\xec\x87\xc6\xb3\x5e\xc1\xb9\x1e\x05\xd7\x10\xf8\x48\x8f\x66\x81\x33\xdb\x76\x3b\x62\x42\x55\xd7\x20\x34\xde\xda\x7b\x61\x4c\xcd\x9a\xac\xec\x9e\x29\x48\x43\x4a\x44\x4d\x15\x57\x46\x73\x11\x84\xe0\x27\x66\x5d\x78\x3d\xbe\x55\xa0\x70\x80\xcb\x87\x28\x32\x3c\x98\x37\x6c\xee\x8b\x6d\x53\x21\x1c\x26\x5a\x49\x00\x51\x1c\x10\x7a\x62\x4f\x35\xab\xf9\xf1\x00\x91\xd4\x1d\x1e\xc5\x94\xe5\x69\xcf\x3e\xac\x55\x40\xec\xa1\x29\xd7\x6d\x77\xd4\x81\xea\xec\xad\x3b\xa4\x23\x82\xea\xe9\xac\x50\x62\x42\xb7\x05\x48\xb8\xa4\xe8\xeb\x23\xcb\x73\x2b\xb5\xd7\xcc\x47\x3a\x90\x68\x03\xea\x7c\x2f\xbf\x1e\x4f\xf2\xdd\xba\x71\x39\x84\xc2\x6d\x59\xb9\xa0\xa1\x8d\x96\x08\xe7\xe3\x6e\x81\x85\x8c\xb0\x60\x65\x71\x0b\x59\x7e\xaa\xba\x77\x94\x26\x81\x9f\x8c\x28\xeb\xee\xb7\xeb\x61\xf6\x01\x52\xae\x51\xbb\x05\xf8\x09\xbf\xbe\x61\xae\xc8\x61\xe2\xca\x2b\xe3\x91\xb1\x88\xd1\x24\x17\x64\x51\x29\x96\x8c\x39\xfe\x02\x3c\xf1\x0c\xc7\xf6\xbc\x29\x8b\xff\x64\x93\xa3\x10\x7b\x72\x28\x5f\xdf\xce\x5c\x66\x06\x7c\xc1\x1a\xab\xcf\xac\x78\x7b\xfa\xab\x4a\x1c\x40\x22\x62\xe5\xca\xf7\x94\xc6\x57\xbf\xac\x81\x01\x28\x65\xd8\x15\xd5\xbc\xc9\x14\x80\x48\x53\xe8\x7d\xc2\xc7\x30\x6b\xdb\x44\xfa\x3a\x31\xce\x37\xff\xd6\x5d\x32\x05\x64\xec\x53\x16\xde\xb8\x9a\x9a\x0c\xdd\x78\x8c\x49\x61\xf6\xbc\xe4\x5a\x1f\x05\x93\xab\x92\x40\x36\x6d\xd7\x65\x26\xba\xd4\x32\x20\xf3\x99\xcd\xb1\xdc\x17\xc4\xfb\x3f\x11\xeb\xf9\x02\x7f\x0d\xc8\x8c\x0e\x44\xef\x97\x34\x36\xb3\x06\xd0\xa1\x22\x27\x7a\x68\x1a\x98\xd1\x95\x19\xbf\x08\x8d\x9e\x83\x46\x5c\x02\x2b\x85\x17\x87\x03\xfe\xc6\xfe\x38\x79\x1a\xe1\x71\xce\x79\x07\x34\x7b\x3c\x5f\xba\x5c\xd9\x86\x7e\x60\x34\x49\xd5\x7d\x91\x5d\x94\x0a\x06\x3b\x1d\xe1\x07\x82\x16\x8a\xed\x01\xaa\x66\xfb\xd5\x53\xc2\x44\x10\x1a\x37\xfc\x4b\x0d\x27\xdb\x20\xf4\x12\xea\xb3\x9f\x65\x1b\x93\xf7\x09\x30\x11\x7a\x92\xc0\x8f\xa0\xd4\xd0\xda\xe9\x74\x21\x45\xd4\x4b\xcb\x8d\xfe\x9f\xbd\x4c\xe4\x73\xda\x45\xed\xca\xb2\x39\x57\xc3\xd5\x4b\x44\x21\x92\x6c\xef\xa6\x22\xf8\x41\xb8\x5a\x6c\x36\x93\x37\x10\x25\x71\x1c\x4e\xd4\xec\xbb\xd3\x65\x12\x77\x1e\xbd\xab\xf2\x6b\x90\x7b\x14\x91\x14\x24\x43\xf3\xd6\xf9\x52\xb8\x03\xca\xa7\x0a\x12\x89\x0e\x5e\x88\xac\xf9\x57\x8a\xf1\x22\x96\xa6\x08\x57\x5b\x03\x94\x6e\xcf\x2b\xa7\x8c\x60\x10\xb1\x0e\x23\x8b\xaf\xe8\x85\xc8\xba\xf7\x1d\x6b\x45\x51\xdd\xea\xf9\xc7\xd3\x9e\x6e\xbd\x37\x53\x01\x91\xa4\x9e\xb2\x52\x82\x86\x94\x4d\xd8\x5f\x7b\x90\xa5\x29\x25\x61\x68\x9f\xf6\x82\xb5\x3c\x5d\xd9\xf8\x8b\xd4\x33\x66\x1b\x5b\xa2\x19\xb5\x33\xdf\x6c\x88\xdb\xb5\x56\x89\x25\xa3\x3b\x80\xc0\xf8\x2b\xa4\x81\xc1\x11\x7f\x61\xb6\xc1\xf1\x37\x4c\x43\xc1\x4d\xe9\x22\xcf\x0d\xb3\xcc\xeb\x0e\xa5\xc6\xb6\xf7\xfb\x7d\xd2\xfd\x09\x0c\x7e\xbb\x36\x11\xfd\x35\xf1\x96\xe9\xd3\x48\x8f\x80\xb6\xff\x53\x56\x55\xe9\xf9\xe3\xdf\x47\x1d\x5a\xda\xe7\x4b\x59\x1e\xea\xd9\x8d\xb5\x48\x35\x30\xcb\x69\xd9\x80\xfc\x80\xb7\x51\x85\x21\x89\xfe\x19\xda\xe4\x9c\xe0\x3e\x52\xc7\xc9\xb3\xe2\x63\x57\x1a\xc1\xfc\xb9\x4d\x91\xe0\x21\x10\x13\x75\x53\xe6\x50\x65\xf5\x6a\xfd\xc7\xff\xad\x94\x20\x78\xec\x13\xa8\x8f\x8a\x4f\xb7\xa7\x42\x5a\x16\xc4\x3f\x7d\xaf\xbb\x29\x1e\x3a\x48\xd1\xbd\x2c\x6f\xf0\x2d\x2b\x56\x17\x31\xb3\xe0\xa0\xa9\xf2\xb3\xc3\xba\xf1\x83\xf1\xfc\x2a\xda\x49\xc9\xa6\xad\x97\xef\xd0\x2e\x75\xd3\x54\x8d\x10\xa1\x09\x73\x1e\xe0\xa3\x7e\x3f\x64\xbf\xe2\xcf\x08\x91\x04\x91\x31\x5d\x6a\x70\xbf\xde\x7d\xeb\x74\xf3\xdb\x43\x21\xa1\x7d\x8f\x5d\x98\xb4\x2f\xf5\xbe\x19\xd4\xdc\x85\x48\x18\xb1\xce\x3f\x4d\x96\xbb\x97\xdc\xee\x1a\x08\xe5\x09\xc7\xf9\xa8\x09\xd5\x37\xfa\xea\x42\x05\xa4\x8d\x6b\xf5\xbb\x68\x55\xa1\xe5\xdf\x90\xcb\x27\xcf\xa5\x12\xda\x14\x37\x08\x87\x60\x74\x19\xe9\x49\x4a\xf4\x65\xf5\x06\xea\xda\x20\x58\x67\x37\xe9\x42\x32\x2f\xe9\x35\x90\xc9\x1e\x6e\x59\x76\xd8\x5d\xa1\x02\xe6\x3b\x3f\x55\xbb\x81\x9a\xdc\x84\x0a\x50\x04\xfd\xa6\xa7\x1a\x40\x9f\x26\xfd\x41\xc5\x2a\x89\x1d\x91\xf9\x5c\x4f\xaf\x23\x7d\xf2\x2c\x31\x40\x7d\xb3\xd1\x5b\x91\xa8\xd6\xa4\x7f\xa2\x54\xb4\x79\xde\x17\xf8\x35\x70\x69\xb5\x47\x35\x33\xe0\x5a\x93\xc1\x74\x62\xc7\x6b\xa8\x7a\x26\xc5\x70\x7d\xd1\xcc\x48\xda\xbe\x1b\xd9\xb3\xf1\x2d\xe9\xd4\x94\xca\x69\xa3\xef\x38\x02\xff\x4b\x5c\x96\xb9\x94\xf4\xbc\x88\x66\xb8\x03\xfc\xfc\x06\xf9\x27\x59\x16\xbb\x43\x31\x28\x07\x90\xd8\xfb\x7b\x2c\xea\x53\x85\xdf\xcb\x06\x7f\x94\xd5\x47\xbd\xcf\xac\xd7\x33\xa5\x81\xea\x9b\xb3\xef\xb9\x79\x48\xfa\x7e\x4a\x2b\x7b\x9d\xbd\x15\x37\x37\xcf\xab\x52\x9e\x0e\x5d\x31\x66\xb8\xdf\x92\x3e\x8b\x42\xe7\xba\xda\x5e\x7a\x00\x47\x94\x3e\x8f\xb4\x13\x69\x3a\x35\xa5\xd1\x1d\xeb\x0e\x62\x4c\x99\xb4\xbd\x85\x33\x6c\xbe\x6f\x2c\x70\x67\xfe\x39\xc3\x40\x10\xda\xd4\x08\x57\x6f\xca\x3c\x93\xe7\x49\x20\x3e\x94\x2b\x03\x19\x46\x06\xe4\x6a\x2b\xc4\x84\xe5\xb2\x98\xac\xbf\xc4\x79\xfc\xbd\x57\x1f\xb6\x13\xf6\x30\xdc\x97\x67\x42\xd1\x4e\x5a\xe9\x84\x32\xe8\xff\x3e\x61\x75\xbe\x3d\xd5\x59\x59\x10\x0f\x1f\x7f\x4e\x3a\xbc\x8c\x18\x90\x79\xe9\x16\x9b\xbb\x4c\x1b\x8f\x8e\x49\x0b\x2d\x9d\xa3\xc3\x13\xda\x1d\xfe\x58\xb9\x77\xd4\xa3\x65\x1c\x29\xda\x5e\x3f\x6f\x1e\x76\x83\x77\x1f\x8b\x94\xa8\x3e\x1d\x02\xe6\xef\xc1\x8e\x64\x12\x19\x67\xfb\x37\x6c\x6e\x5e\xef\xe7\x07\xa3\x4c\x22\x4e\xe3\xe4\x69\xfd\x63\xe9\x7e\x30\x01\x4d\x71\xc7\xf6\xc7\xfd\xed\xee\xdb\xf4\x66\xa7\x09\x73\xc9\x78\xe2\x14\x0d\x9d\x36\xf7\xd4\xd3\x74\x72\x82\x4c\x09\x44\x65\xf2\x3e\xbb\x97\xc5\xd3\xf6\x76\xfd\xb2\xdf\xbc\x3c\xff\xf1\x27\xed\x81\xdd\x8d\xa4\x11\x12\xf4\xfa\x40\x48\x62\x2b\x02\xf2\x17\x65\x64\x99\x2a\x4d\x3a\xb9\xab\xf5\xf7\xf5\xc3\xf3\x66\xfd\xb2\x5f\xbe\xba\xca\x93\xe4\x5e\x44\x10\xa7\x3d\x92\x51\xe0\x68\xce\x90\x3c\x8e\x69\x43\x01\xd6\x83\x73\x5f\x0f\xa4\x74\x5c\x9b\x34\xa5\x3c\x6f\xa9\x35\xcd\xda\x66\x15\x42\x63\xac\x39\xdc\x5b\x49\x88\x0d\xd2\x93\x76\xc1\xe3\x70\xca\xb5\x40\x41\x0c\xb4\x63\x8e\xca\x72\x92\x26\xcf\x22\x53\xf4\xed\xa2\xb6\xbb\xb4\x7e\x05\xa9\xbc\x84\x52\x5e\xbf\x97\xc5\xdb\x3f\x06\xee\x06\x20\x55\x14\x51\xb2\x67\x93\xfd\x2c\x17\x15\x16\x40\x46\x20\xe3\xd8\x46\x2a\x61\xc4\x26\xcc\x2a\x63\xb7\x73\x5b\x84\x4a\x4e\x18\x29\x12\xa3\x38\xb6\xa8\x8a\xd7\xc2\x49\x8e\x4c\x6e\x06\x75\xec\x5b\x71\xf9\xac\x18\xf2\x15\xa4\xf6\x53\xc9\x3a\xe1\xcf\xe6\x7d\x78\xa3\x9a\x47\xa9\x15\xbc\x78\xbd\xb7\xc2\x70\x4b\x2a\xd2\x37\x17\x2e\xc2\xe3\xdf\xd3\xe0\x51\x54\x77\x20\xcd\xee\x55\xe7\xd2\x05\xca\xf3\x83\x54\x59\x48\xd0\x29\x87\x06\x17\xea\x5f\x44\xdb\xbc\x25\x84\x7b\x7d\xdb\xf6\x50\xf2\x9b\x77\x7d\x3a\xec\xe1\x21\x2e\x52\x52\x5e\x68\x08\xb9\x56\x75\xa7\x77\x96\x04\xe5\x87\x69\x60\xa3\xe5\xc7\xb2\xa0\xa2\x47\x0e\x75\xbd\xcd\x48\xa8\x65\x7e\x4e\x54\x41\xc0\x52\x23\x3b\xfa\xd9\x0e\x0e\xb5\x30\x95\xe5\xac\x8d\x81\x1b\xcc\xf3\xec\x0d\x0b\x89\x5b\xd0\xd8\x9c\x57\xa8\xb1\xe8\x70\x69\x2a\x88\x62\x62\xb2\x6d\x2a\xac\xc7\x36\x1a\xa0\x02\xc6\x08\x9f\xde\xce\xfe\x34\x44\x8e\xcd\x44\xf7\xcc\x36\x0c\x3d\xa9\xbb\x05\xa6\xd3\x4e\x69\x4a\xa3\x57\x0f\xb2\x21\xee\xee\x5e\xbb\x6d\x94\x3b\x2d\x0d\x28\xf5\xbb\x29\xbf\x0c\xfc\x17\xea\x77\x54\x37\x3d\x6a\x4e\x85\xdc\x27\x46\x3d\x79\x6b\x5f\xc1\x39\x5d\x96\x89\x55\x1c\x18\x55\xbb\x7d\xd6\xe0\xc1\x48\xce\x1b\xc9\xae\x49\x48\xa0\x62\x6e\xea\x54\x64\x80\xa9\xa8\x08\xe7\x56\x4d\x15\xcb\x80\x0a\xa7\x9f\xed\xf8\x5b\xd4\x4d\x55\x0e\x07\xa1\x8a\x65\x88\xd6\xf4\x25\x2b\xce\xdb\xf7\xb2\x6a\x28\x7d\x38\x0e\xfd\x5c\x63\xad\x08\x34\x41\x26\xec\xdd\xb7\x4e\x44\x44\x58\x80\x53\x4d\xba\xe7\x9b\xb2\xce\x9a\x4f\x9c\xdd\xcf\x2a\x16\x84\x04\x5e\x22\xd0\xc5\x6b\x51\xf7\x1b\x36\xc5\x40\x51\x42\x08\xb2\x9f\xdd\x9f\xa4\x91\xfc\x1b\x66\x41\xae\x23\xf9\x67\x67\x3b\xc5\x30\xa2\xf5\x6a\x01\x8e\xe9\xa1\xd2\x44\x44\xb1\x0d\x07\xdb\xc8\x95\xc6\x6b\xe8\x8e\x72\xcf\x54\x90\xbf\xba\x22\xc7\x8b\x49\x71\xd6\x7d\x0b\xdf\x18\xe5\x40\x9e\x8f\xfd\xef\x40\x71\xab\xbe\xec\x26\x7a\x92\xe9\x71\xc7\x52\x23\xc5\x6a\x47\xc4\x4d\xd6\x8c\xfa\x29\xe7\x3e\x85\x90\x4a\xe9\xfe\x4f\x9c\xe0\x96\xe2\x54\x15\xa3\xb4\x93\x3b\x0e\x91\x63\xea\xaf\x4e\x58\xdf\x4f\x38\x63\x0a\xd2\x58\xda\xe3\x36\xa3\x6d\x41\xe7\xa9\x6b\xa0\x52\x6d\xa1\x41\x4f\xf8\xb5\x6d\x2a\x44\x03\x72\x18\x7d\x77\x11\x18\x8f\x7c\x13\x72\xd2\x4d\x0f\x91\x10\xb6\x95\x4c\x39\x0a\x97\x12\xc1\x7b\x59\xb6\x3b\x94\x2b\x20\x68\x25\x85\x61\x04\x8a\xd3\xe1\xb8\x29\x07\x32\x75\xa0\x24\x1a\x49\x65\xda\x69\x3b\xb8\xaf\xcd\x3a\xd8\x26\x8a\x23\x6d\x87\xdc\x37\xda\xd7\xe5\x01\xf7\x60\x18\x85\xf3\xfd\x40\x69\x4d\x74\x6e\xea\x79\x03\xf6\xa5\x3d\x8c\x2a\x75\xc2\x22\x8f\x58\xd7\xf0\x86\xf6\xab\xcf\x8c\xd3\xe1\xbb\x41\x8f\x05\x84\xe6\x6e\x03\xb2\x1f\x97\x61\xaf\x6d\xe5\x0b\x45\x14\x81\x85\x52\xcb\xf7\x6c\x2a\xd9\xeb\x1a\x29\xa5\x3a\x48\xd9\xfe\x68\xb2\x2d\xb3\x11\x02\xfa\xda\x77\x92\x9b\xdb\xf7\xf2\x68\x36\x2e\xa3\xfb\x0a\xfc\x28\x36\x18\x13\x27\xf3\x62\x7c\xe7\xed\xd3\x8d\x1b\x87\x0c\x4c\x99\x84\x26\x99\xb6\xcf\x66\x32\x3b\x0e\x21\x11\x18\x32\x6d\x78\x1e\x47\x2c\xd4\x54\x0b\x06\x43\x6e\x44\x79\xeb\x52\x37\x96\x16\x77\x57\x3a\x9b\x16\xc0\x50\x33\x52\x22\xbb\xab\x20\x87\x9f\x59\xd9\xa1\x36\x31\xe6\x26\x6e\xee\x59\x53\x46\x17\x78\xfe\xb1\x13\xdf\xa7\x5d\x08\xa1\xcb\x69\xd8\x3e\x42\x23\xdf\xef\x36\xed\x82\x65\xa2\xe1\x99\xcd\x0b\x26\xda\x4b\x6d\xe4\xbe\x95\x15\x1c\x1f\xb3\xc2\x5a\xf9\x5f\x44\x0c\xc8\xfa\xe5\xf6\x11\x0f\x75\xf6\x9f\xee\x19\x19\x7a\x14\xfd\x98\xb4\xfd\x22\xcf\x27\x67\xa6\x69\x42\xa8\xee\xf5\xee\xdb\xfa\x65\x04\xe9\xc0\x94\x6b\xc3\xf9\x74\x7c\x3d\x42\xaf\x90\xb8\x3c\x25\xd3\x27\x17\x02\xcd\x6c\x34\x70\x8b\xf8\x83\xac\xbb\x27\xf6\x66\x80\x5c\x86\x46\x41\xa3\x2a\x4b\x6d\x97\x3d\xf7\x73\x1c\x43\x66\x61\x64\x17\x3a\x81\x80\xed\xa4\x30\x40\x6f\x8e\x47\x31\x82\x30\x7e\xd5\x94\xf1\xb6\xcb\xe5\x95\x6c\x37\x0a\x5f\x72\xc7\xa5\x1b\x3d\xaf\x48\x13\x62\xf3\x59\x24\xa1\xcd\x44\x60\x3d\x85\xbf\xd9\xe6\x32\x8a\x69\x05\xb1\x3d\x60\x5d\x4c\xcd\x9b\xfb\x9f\x94\xcc\x28\x40\x89\xd3\xf9\x8f\x4e\x49\x63\x36\x72\x47\x99\x1a\xa1\x82\x43\xe6\xaa\xcf\x06\x7f\xd8\x46\x79\x5d\xff\x93\x92\xfb\x96\xbb\xb1\xfc\xdd\x0c\xa3\xf1\x55\x54\xc2\x48\xeb\x6d\xbd\xfb\x66\x05\x7e\x3b\xf8\x0a\x62\xa4\x54\x62\x4d\xde\x97\xed\xa0\xbd\x72\xd3\xed\x07\x21\x2f\x5d\xfc\xc4\x3c\x18\xa2\x96\x11\x95\x31\x46\xaa\xa0\x41\x52\x02\xa7\x12\x8b\x03\xa1\xa3\xf6\x8c\x73\x60\xdd\x94\x47\x5b\x83\xb9\x83\x69\x60\x89\x3a\x52\x4e\xf9\x6c\x09\xd5\xd4\x37\xf8\x97\x9b\x20\xd4\x71\xc2\x8d\x8f\xd5\x20\xcb\xf2\xd0\xc6\xdb\x6e\x6e\xd4\x9e\xcf\x1c\x33\xf2\xa5\x94\x1f\x38\x32\x69\x01\xed\xc5\x5c\xf6\x35\x81\xbb\x13\x5a\x7e\xa6\xcd\xa8\x8e\x53\xc5\x0e\x93\xa1\xfd\x10\x22\x66\x99\x04\xd5\x27\x79\xc7\x9d\x5c\xce\x5a\xfb\x89\x8f\x0e\xcc\xfb\x9e\x55\xca\x80\xa7\xdc\x41\xd0\xb4\x4e\xda\xf7\xb1\x1f\x99\x2a\x80\xf6\x95\x01\x93\xb4\x1f\xe5\xdc\x7e\xf1\xa1\x28\x8a\x0e\x02\x4d\x65\x17\xaa\x37\x65\xfa\x3c\xde\xe1\xe8\x30\x08\x99\xe7\x94\xfd\x8c\x0a\x9b\x4b\xa3\x8d\x5e\x9b\x8e\x98\x00\x23\xde\x2a\xef\xb0\x78\x00\x71\x0b\xd3\xa9\x44\x47\xa9\x71\x65\xa2\xfa\x8b\xc6\xaa\xea\xa4\xaf\xa7\x0d\xb9\x51\x5c\xba\xb9\x7f\x1a\xca\xb9\x82\x8e\x74\x42\x49\xa7\xcc\x00\xea\x47\xc2\xb6\xa0\x93\x08\x20\xee\x95\xf2\xa1\x38\xaf\xc6\xc4\x23\xd7\x8e\x7b\xb4\x8b\xb9\x79\x78\x5e\xfe\xbe\xfc\xb6\xb8\x7f\xda\xaf\xd6\x9b\xe7\xed\xfd\x6e\x7f\xb3\xde\x2d\xf6\xfe\x63\x77\x45\x09\x94\xfe\x98\xd1\xf4\xd0\x09\xc6\xb4\xcb\x5e\x21\x1e\x6f\x2a\xe8\xbf\x07\x4b\x3c\xe5\x0d\x14\xf9\x92\xee\x80\xf6\x89\x27\x6d\xf7\x92\xe3\x9b\x4a\x75\x64\x44\x5d\x08\xdb\x49\x15\xdc\x1e\x11\xa4\x79\xea\x07\xba\xc7\x98\x65\x45\xfb\xd6\xb2\x4f\x5c\x57\x15\x4c\xc1\x90\x9a\x83\xd1\x47\x73\x37\x10\xb8\xc4\x8f\x06\x5f\x05\xca\xc6\x4f\xa3\x15\x4f\x43\x6c\x41\xcb\x6d\xa7\x3d\x55\xa6\xa8\xe9\x6c\x29\xc7\x77\x0a\x18\x79\x1d\xcd\x63\xf7\x5e\x61\xfd\xde\x86\xad\xe3\x46\x02\xcc\x0d\xb7\x1b\x9e\xc5\xdd\xaf\x8c\x57\x40\xcb\x38\xa1\x0b\x0e\xcc\x1e\x5f\xa0\x31\xf2\x5e\xd5\x61\x00\xdd\x9d\x9d\x4d\xb4\x4c\x22\x5a\x04\xd7\x2f\xcb\x20\x08\x1f\xb3\x82\xbc\xf8\xa9\xdf\xcc\x4a\xc2\x69\x15\x9b\x6a\xfc\xfa\x27\xac\x5f\x5d\xee\x40\x2b\x66\x4a\x8c\x2f\xeb\xed\xfa\xe5\xfb\x7a\xb5\x7f\xdd\xdd\x3f\xdc\xef\xfe\xdc\xdf\xbd\x3c\xbf\x6e\x5c\x2b\x84\xc0\x88\xc0\x1c\xe0\x67\x10\x27\x73\xfa\x3c\x5a\x7b\xa6\x7f\xb9\x7e\x8e\x73\xd1\xf9\x70\x9c\x09\xcf\x4b\x80\xc5\x5d\xe9\x7e\xf4\x2e\x85\xe7\x31\x23\x6a\xd2\x06\x37\x77\x4f\x46\x86\xc1\xaa\xe7\xb9\x16\x22\x25\x8a\x52\x1b\x24\xe9\xb2\x3a\x90\x01\x5b\x66\xfd\xed\x46\x31\x83\xf0\x3c\x65\xe4\x7f\xf7\xc7\xca\x20\x99\xdb\x57\x6d\xfc\xbb\x06\x01\x8e\xf0\x82\xd8\x47\xc7\x5b\x24\xd9\x33\x7c\xac\xdf\x06\x95\x23\xe1\x85\xb1\x41\x4a\x18\xd8\xf9\x6d\x59\x61\xf6\x56\xdc\x54\x99\x7a\x1b\x2f\xa2\xc2\x8b\x7c\x4e\x19\x5c\x4d\x86\x6a\xd8\x80\x0d\xf9\xdd\x95\xa2\x30\xa1\x62\xd2\xcb\xeb\xd3\x7a\x30\xe0\x85\x17\xb5\x93\xb9\xf5\xf2\x20\x16\xa9\xd3\xbf\xb0\xc7\x63\x3f\x89\xed\xab\xa6\xb0\xee\x16\x71\x6e\x4a\x11\x5e\x1c\xf9\x86\x20\x6d\xf4\xab\x8c\xca\x5c\x56\xbc\x75\xb1\xdd\xe5\x19\x5c\xe9\xde\x53\x6c\x5b\x5f\x92\xf7\x06\x03\x48\x78\xb1\x94\x0e\xdd\x3e\xb2\x7d\xff\xe5\x72\x23\xbc\xc4\x43\xaa\xe4\x74\xbd\x8e\x72\x5c\xdb\xfd\xed\xf3\xcb\xfe\xf6\xfe\x69\xf1\xb4\xbc\x5f\x3c\xec\xef\x9f\xb6\xbb\xfb\xdd\xeb\xee\xfe\xf9\xc9\x3d\x79\x92\x1a\x54\xc5\x00\x23\x78\x81\x1a\x12\x5e\xa2\x3d\xc3\x53\x2e\x6d\x48\xe4\x90\x86\xbf\xaa\x2f\x09\x8f\xa5\xda\xa8\x89\x97\x6f\x6f\x39\x39\x4a\x5f\x94\x58\x85\x97\x06\x8c\x3a\x08\xd4\xef\x12\xea\xf7\xd1\x77\x4b\xc3\x88\xd0\x7e\xd6\x44\xca\xe4\xc7\x06\x9d\x2b\x8d\x22\x62\x68\x35\xe5\x6b\x56\x34\xbf\xcd\xbd\xd0\x94\x81\x8a\x47\x68\x0b\x0a\x4f\x37\x58\x75\x92\xbe\xc2\x4b\xa5\x24\x5f\x0b\x2c\xfe\x95\x15\x3b\x84\xc3\xa8\xc8\x23\x3c\xf0\x52\xe6\x4c\xf4\xce\x47\xec\xad\x43\x84\x07\x60\xd8\x6a\x37\x59\xd3\x7c\x41\xd3\x74\x7f\x57\x81\x91\xbf\x2a\x65\x06\xf9\x23\xaa\x0c\x4c\x96\xe1\xd2\x4b\x5a\x78\xd2\x8f\xe9\x39\xde\xb3\x49\x11\x69\xec\x6a\x98\xba\xe6\x1c\x48\x21\xcf\x20\x6b\xb6\x38\x89\x99\x85\xa7\x62\x9f\xc5\x63\xa7\x82\xc9\x50\x52\x4c\xd2\x06\xc1\xb1\x99\x4a\x92\xc0\xc4\x91\x2f\xeb\xe8\x3d\x2a\xe1\x91\xbf\x91\x73\x01\x20\x1e\x2f\xed\x0c\x17\x56\xfc\x65\xbe\x0f\x28\xc5\x7c\xbb\x03\x5c\x88\x2c\xcf\x7a\x87\xeb\x2e\xef\x98\x5e\xfc\xf3\xf2\x32\xe8\x07\xb4\x33\x2b\x8f\x58\xac\xca\xb2\x1b\xf2\xe8\x27\x54\x3d\xe8\x2c\xa2\xa8\x86\xbb\xa2\x85\x74\x6e\x9e\x17\x1e\x4a\x4e\x1f\xac\x99\xab\x91\xfa\x2e\x4d\x24\x3c\x54\x8a\x3a\xaf\x91\x22\xfe\x06\xf5\xfb\x42\x29\x97\x1a\x0c\xbc\xd1\x07\xd1\xc2\xa7\xe9\xdc\xac\xab\x5b\xd0\xb8\xc5\x62\x4a\x56\x6f\xdb\x84\x94\xba\x5f\x21\x09\xc9\xaf\xff\x6f\x24\x29\xe1\xfb\x5e\x64\xb5\x98\xde\x5e\xf0\xcd\x64\x08\xe7\x3e\x9a\xef\x07\x9c\xb6\x3c\x9b\xaa\xfc\x17\xca\x66\xdf\x59\x1f\x0d\xae\x85\x40\x40\xdb\xb6\x2f\x5d\x5a\x41\x09\x3f\x08\x98\x72\xae\x2b\x6d\x8c\x6c\x43\xae\xf1\x46\x22\xed\x1a\x1b\xca\x8c\x2c\x0f\x87\xac\x69\x10\xff\xbb\xcc\x8a\xef\x65\x33\x81\xea\x09\x3f\x08\x85\xa9\x3c\xbf\xfc\xb1\x5f\x6c\xb7\xeb\xdd\x9e\x14\x7d\xdc\xd1\x24\x24\x0c\xb6\x3e\x15\x0a\xaa\x0c\x3a\x69\x0b\xe1\x07\x9c\x13\xa5\x01\x4c\xde\x65\xa2\x86\xd8\x27\x13\xfa\x09\xc6\x0f\x93\x84\x50\x86\xe2\x74\xbe\x84\xea\xb7\x87\x85\x8f\xbd\xdc\xdb\x48\xad\x60\xfc\xaa\xe2\xd8\x38\x2c\xef\x36\xbb\xee\x4d\x95\x6e\xcf\x23\xfc\x58\xb0\xc0\xd6\x3d\x56\xf4\xa2\x47\x6b\xb3\x9f\xc4\xc0\xfa\x78\xfe\x61\x10\x6f\x4d\x7e\x26\x51\x1e\x25\x8f\x8c\xf9\xb5\x21\xf4\xcf\xf7\x03\xe6\x07\x94\xa6\x77\xc2\x4a\xb6\xd3\x75\x47\x19\xa5\x2a\x28\xad\xa8\xc6\x33\x9a\x9f\x7a\x82\x64\x74\xdb\xd8\x75\xf1\xf8\xfc\xfa\xb4\x0b\xba\x43\x92\x53\x7e\xf4\x98\xc3\x39\xba\x72\x8f\xa9\xe6\x44\x47\xb6\x1d\xfe\x98\x67\x0d\x14\xaa\xfd\x7d\x77\x15\x1e\x30\xd2\x09\x5d\xb6\x73\x77\x27\x45\x29\x7c\x60\x3e\xc5\xbb\x6d\x20\xf7\xd1\x46\x58\xfb\x3c\xfb\xb8\xe8\x1f\xc2\x6e\x9f\x8e\x15\x7e\x66\xe5\xa9\x1e\x3f\x99\x50\xca\x37\x5a\x70\x26\x3e\xbb\x73\x07\x64\x14\x6b\xde\xe1\xcf\xda\xee\xda\x3d\xb0\x8c\x43\x34\xd4\x2a\x37\x23\x22\x09\x08\x4f\x7e\x58\x79\x9a\x96\x0b\xc8\x8f\xef\xe0\xce\x55\x49\x2a\x8c\x3a\xe1\xa9\x68\xaa\xb3\x11\x4d\xb9\x5f\xb9\xc3\x88\x82\xf6\x19\x8f\x24\x26\x9b\x75\x43\x47\x27\x09\xa5\x19\x81\x68\xa9\x6d\x97\xc1\xa2\xb9\x39\x5f\xe6\x26\x44\xe0\xf9\x09\x45\x5e\x8b\xe3\x31\x93\x75\xef\x3e\x28\x02\x5f\x4b\x6e\x97\x9e\x26\x3b\x60\x9f\x21\x17\x41\xe0\x85\x81\x11\xd1\x29\x1a\xc8\xdb\x39\xb8\x13\x16\x76\x4d\x42\x8f\x11\x53\xc3\x76\x7b\x94\x9f\xeb\xe6\xdd\x5a\x96\xf6\x43\x24\x08\xad\x9b\xd5\x67\x86\x5f\x5b\x59\x56\x93\xc0\x2b\x08\x39\xa7\x27\x94\xa2\xcf\x39\x4c\x5a\xc8\x98\x30\x29\x99\x2c\x5f\x4e\x79\xbb\xbb\xfb\x5b\x6c\x68\x82\x51\x99\x44\x3a\xfe\x87\xa8\x28\x8b\xaa\x82\xb3\xb1\xb6\xbc\xd0\xcd\x10\x41\x94\x68\x05\xa3\x2c\x72\xfb\xd8\x13\x1c\xa6\x08\xa2\xd4\x38\xad\x41\x4d\xb5\x69\xca\x0c\xcc\x76\xe4\x20\x16\x91\xc7\x2c\x13\xc6\x14\xfd\xdd\xab\x8b\x65\x48\x79\x8e\x7f\x11\xb7\xda\xe1\x8e\x67\x91\xd2\x22\x88\x31\x31\xcc\xa6\xa6\x1a\xf6\x66\xb7\x98\x04\x49\x04\x24\x56\x57\xfb\xde\x50\x52\x4a\x04\x4c\xa4\x4a\xf5\x88\x8d\x71\x40\x1e\x70\x1e\x51\x9e\xe2\xfe\xee\x76\xf9\x97\x64\x10\x11\x70\xad\xcc\xbe\xd6\xd6\xec\x57\x99\x91\x69\x5b\x96\x1f\x57\x96\xe7\x80\x6b\xf4\x03\x0b\x51\x7a\x87\x0a\xdf\x2f\x45\x56\x44\x00\x9e\x24\x29\xf5\x6f\x17\x56\x4f\x6e\x67\xe4\x1a\xca\x94\xf8\x31\x3f\xee\x9f\x28\x00\x5d\xac\x56\x2f\xeb\xed\xd6\x1d\x16\x68\x2a\x5b\x6f\x4e\xcc\xfd\x16\xb1\x43\x52\xb9\x91\x1a\xc8\x08\x03\x2b\xd9\x7a\xcc\xf1\xe7\x56\x42\x8e\xcf\xa2\xde\x4d\xbd\xf7\x45\xa0\x7c\x83\x16\xdc\x54\xe8\x28\xf2\x9b\x13\x99\xf7\xcc\x7f\x6c\x15\xa7\x54\xce\x12\xd0\xc8\x77\x27\xc1\x30\xfd\x54\x18\xf8\x94\xb4\xed\x22\x8a\x71\x2d\x42\x04\xed\xde\x0d\x87\xa4\xf6\x89\x98\xdd\xd5\xd2\x53\x7b\x6a\x4c\xc2\x31\x84\x19\x5c\xbf\x2c\xfd\x24\xb6\xc2\x35\x35\xd1\x8e\x35\xc8\x09\xab\x25\xb2\x67\x6a\x5f\x19\x17\x7d\xc8\x3f\x8c\x2f\x96\xbd\x9d\xd0\xf7\x39\x95\xc1\x0f\xd4\x75\x46\x55\xa6\xd1\xd3\x87\x7e\x9a\x1a\xc7\x7a\x94\x7f\x63\x78\xce\x0f\xd7\xd0\x57\xca\x67\x7d\xe9\xd6\xdc\xea\x6d\x55\x1e\x2e\x95\x17\x86\x5d\x33\xf4\xb5\xf0\xac\xbd\x18\xd6\xf5\x7a\x22\x3d\x28\xc2\x20\x31\x3d\x87\x40\x03\xe3\x95\x33\x0c\x84\xc1\x98\x56\x24\xd4\x7e\xbf\x7c\x76\x8f\x1e\x7a\x8c\x77\x0a\x41\xdf\xdb\x2f\x01\x7f\xa9\x8d\x32\x79\x9e\x30\xe6\xda\x00\x63\x3e\xf0\xa9\x2c\x6e\x4f\xc5\x5b\x26\x2e\x8d\x51\x6d\xeb\xd8\x0f\x89\x29\xe8\xba\x84\x21\xe6\xcd\x76\xb6\x30\x8e\x42\x6d\xa1\xac\x94\x1d\xbd\x34\x28\x13\x61\x0c\x5e\xe8\x2a\xff\x5f\xa8\xc8\x44\xa9\xcb\xa2\x8a\x76\x37\x8b\xc6\x17\x8e\xfc\xe7\x9f\x7f\x05\x92\x16\x21\x93\x48\x9b\x98\x03\xfc\x5c\x37\xef\x33\xb1\x5c\xc8\x30\xa2\x05\x83\x0a\xa6\x54\x4f\x2a\x4b\xdd\x6e\x68\x06\xf4\xc4\xc9\x70\x08\xd3\x50\x10\x2e\xea\xf1\xfc\x84\x5f\xc3\xcd\x59\x98\x0a\x23\x2d\xde\x60\xdd\xbc\xd4\x6d\x08\xe0\x8e\xf0\xd8\x40\x7e\x85\x85\xb7\xb6\xd1\xae\x91\x0c\x98\xb1\xda\x13\x21\x07\xa3\x1d\xe7\x34\x06\xdc\x02\x7d\x5f\xd4\x37\xe7\x2b\xd0\xea\xc9\xb3\x73\x89\x54\x46\x79\x74\x24\x84\x60\xb6\xd4\x21\x42\xc1\x42\x87\x8d\xd9\xe4\xd0\xe8\xb2\x3a\x0c\x76\x73\xa1\xf4\x05\xf5\xa8\x75\x73\xd8\x60\x75\xd3\x48\x77\x40\xa5\x51\xe0\x0f\x6c\xd4\x17\xc5\x1b\xe6\x4b\xa8\xd4\x96\xec\x24\x5d\x33\x64\x9a\xd0\xd6\xba\xac\xde\x7e\x25\xd5\x2d\x42\xad\x0c\xc3\xe4\x54\xa3\x32\xe0\x73\x1c\xf2\x1d\x44\xe4\x85\x8c\x32\xb9\x36\xd5\xf0\x27\xc2\x95\x9e\x16\x79\x98\x92\x94\x5f\xdd\x94\x47\x17\xe1\x76\x57\x41\x45\x1e\xf3\x3f\xf0\xae\xcc\x87\x64\x46\x11\xf9\x81\x0e\x8d\x02\x10\xa1\x84\x57\x98\x67\x9f\x78\x85\x0d\x2f\xa2\xc0\xd3\x68\x52\x24\xd5\x27\x56\xe3\x68\x32\x0a\x02\x34\xb0\x42\x2c\xac\xcd\xe5\xa2\x50\xd6\x12\x69\xf4\xfe\xa3\x88\x49\x67\x29\xec\x32\xc1\x26\xbb\xfa\x4b\x60\xb8\x88\xe2\x88\x51\xdc\x2f\xf3\xd2\x88\xe9\x16\x98\x5f\x24\xf4\xae\xa8\xdc\x0c\xa0\x68\x22\x8a\x13\x53\x05\x22\xc3\x34\x07\xed\x99\x0d\xca\xa2\x18\x42\xcf\x6e\x1c\x36\x39\x14\x38\xe9\xb7\x11\x8b\x3d\x32\xd6\xdb\x7e\xbb\xdf\xf5\xf2\x81\x22\x62\xa9\xd9\x39\x52\x5d\x62\xf7\x55\x0e\x2a\x13\x22\x62\x82\x4b\x23\xb7\xd5\x49\xdf\x94\xd5\x35\xfa\xab\x88\x52\x8f\xd1\xfb\xfa\xb6\xdc\x8d\x3e\x5e\x1a\x45\xba\x4b\x0e\x52\x45\xf5\x96\xa8\xa6\x93\x5b\xe4\xbe\x22\x0e\xce\x70\x36\x18\x2a\x5f\x51\x0b\x4a\xbf\x28\x38\xd7\xbb\xf2\xb5\x30\x5c\xa6\x2b\x77\xc3\x7d\x4c\xed\x02\xfe\x54\x36\x57\x62\x8a\x08\x14\xe7\xc6\xa2\xa4\xa8\x9b\xea\x24\x29\xae\x73\x6e\xe5\x53\xc0\xb4\xa9\x79\x4c\x55\xab\x67\xe4\x1c\xec\x1e\x33\x12\x22\x25\x28\x95\xc8\x9a\xfa\x23\x1b\xbd\x14\xa1\xcc\x20\xed\xf7\x16\x15\xca\xb2\xba\x12\x0e\x44\x32\x0e\x08\x34\xed\xc2\x25\x82\x58\x64\x65\xf1\x5c\xdc\xe0\x3b\xe4\xba\x0f\x2b\x67\x75\x25\x44\x24\xc1\xa4\x8d\x9e\x69\x19\x70\x7f\x44\x96\x18\x1b\x9f\x97\xf5\xcf\x23\x16\x75\xf6\xe9\xd8\x9f\x93\xb3\x75\x8a\x8e\x2c\x63\xaa\x96\x73\x35\x11\x11\x29\x3f\xa0\xe1\x6d\x7d\x19\xa8\x68\xb3\x9b\xf6\x55\xb4\xda\x93\x35\x36\x37\xbb\xdd\xf6\xd2\x48\x4a\x44\x28\x05\x21\xf4\x97\xcf\x4f\xbb\x97\xc5\x72\xb7\x1f\x47\x67\xb1\x9f\x2a\x31\x34\x7d\xbe\xa6\xcf\x2f\x62\x5f\x25\xb4\x79\x7c\x3e\xe2\x40\x59\x52\xc4\x01\xfa\xb6\xce\xf1\x89\x5b\xfa\x92\xc3\xea\x80\x88\x43\x2f\x20\xf8\x52\x81\x3f\x9b\xb5\xcd\x1a\xb9\x43\x89\x0a\xb4\x83\x6a\x69\x38\xe5\xcd\x20\x5d\xe8\xda\x30\x8f\x60\x17\xeb\xf5\x82\x86\xdb\xf8\x68\x14\x6a\x65\x68\x15\x9f\x59\x4d\x86\x09\x37\x24\xc2\xee\x7e\x21\xf6\x99\xc1\x3f\x14\x70\xac\xdf\xcb\x2b\xd5\x57\x11\xc7\x11\xa7\x48\xc4\x88\xdb\x0e\x4c\xc9\xff\xeb\xa2\x04\x2e\xe2\x58\x98\x4a\x88\xd9\xe2\x65\x35\x3e\xe1\x4f\xda\x47\x74\x8b\x6e\x9c\x30\x2f\x10\x4e\xf7\xeb\x07\xe2\xc7\xe4\xc9\x13\x19\x90\x43\xc1\x4d\x96\xe7\x99\x71\x8a\xeb\xb7\xba\x71\xa2\x02\x72\x97\x31\x18\x91\x5b\x23\x69\x31\x79\x72\x26\x23\x23\x0d\x48\x99\x85\x4d\x55\x1e\xca\x76\xeb\x7b\xdf\xe0\x54\x94\x66\x3e\x08\x8a\xd3\xc4\xc7\xf6\x16\x5e\xad\xac\xe6\x3c\x38\x5d\xc4\x29\xe7\x1e\x73\x64\x9f\xba\x99\x07\xa1\xb4\xcd\x8c\xa6\x13\x01\x33\x0d\xad\x7a\x55\xc1\xd7\x10\x53\x6b\x5b\x72\x9f\x53\x46\x65\xe9\x4f\x0e\x40\x60\x80\xec\xa4\xe3\xb3\x50\x06\xe1\xd8\xa9\x8e\xbb\x46\x2a\x72\xb7\x43\xce\x54\x7f\x21\x8a\x61\x66\x11\x17\xd8\xc4\x22\xf2\x29\xa2\x2e\x89\xfb\xf2\x7c\x6a\x64\x79\x70\xa5\xf4\xf1\xb4\x17\x8b\x98\x71\x8b\x42\x5f\xe6\x19\x16\xcd\xbc\x20\x91\x6b\xcd\x12\x4b\xcc\xa1\x0a\x8b\xac\x4a\x28\xea\xf3\xa6\xfc\xea\xbf\xaa\xe4\x11\xc9\xc5\xec\x5e\xee\x17\x0f\xdd\x1f\x35\x57\xf6\xb5\x6d\x8f\x20\xb1\x7e\xcf\x8e\x9b\xaa\x54\x27\xd9\x10\xca\xef\xe6\xfc\x58\x2a\xbb\xea\xf9\xee\xc7\x54\x1a\xc7\xc2\xf1\x82\x09\x55\x70\x7f\xd5\xf4\xd1\x9d\xa2\x23\x5b\x22\x56\x78\xa0\x1c\x13\x65\xc4\x97\x0e\xb4\x38\xf9\x14\x88\x3a\xb1\x18\x40\x95\x51\xcf\x36\x79\x6c\x77\xdb\x3a\xd0\x44\x80\x90\x90\xcb\x99\xfc\x5a\xac\x63\x45\xb9\xf3\x36\xd0\x59\x6c\xac\xc6\x80\x48\xbc\x84\xd3\x69\xc7\x32\x2b\x88\xce\xf3\x54\xaa\x49\xc7\x4e\xfc\x54\x9a\x8a\x1e\xd6\xcd\xe2\xa4\xb2\x4e\x05\x48\x24\x41\x28\x28\x4f\x43\xc9\xcf\xad\xf5\x19\x1f\x80\x86\x47\xcf\x90\x04\x91\x31\xcf\xfe\xd1\x9d\xae\x34\xed\xe1\xf2\xec\xc3\xd8\xb4\x4c\x67\x7a\xdb\x2e\x4c\x3d\x9a\xe1\x07\x52\x4b\x8f\x90\x15\xfd\x1e\x24\x09\x53\x8c\x7d\x27\xdd\x67\xb4\x34\xf4\xaf\x60\xc8\x22\x09\xd1\xa7\x35\x79\x7d\x38\xe6\xe5\x19\xdd\xe2\x30\xec\xda\x49\xe4\x03\x71\xd9\xdb\x71\xec\x2a\xf1\xfb\xac\xd8\x0f\x41\x88\x22\x89\x02\x41\x3e\x29\x77\xa5\x52\x24\x7f\xd7\xaf\x85\x49\x12\xa5\xd2\xb8\xf9\xe4\xed\x47\xad\x20\xcf\xea\x99\x2d\x48\x92\xa0\x76\x2e\xca\x46\xad\xe0\x77\x3c\xbb\xea\x50\xc2\x02\x46\x4b\xc6\xe1\x7c\x93\x0d\x76\x31\x3d\x51\xd7\x35\x4c\x3d\x0c\x95\x83\xf7\x34\x6d\xe8\xae\xcb\xb6\xbf\x16\x8d\x01\xba\xa7\x93\x0f\x92\xfa\x48\x19\x3c\xc2\xdb\xcb\xb2\x1a\x40\x6e\x47\xa5\xd0\xcb\xd3\x62\x47\xf1\x37\x1a\x3b\xc6\x44\x89\x34\x73\xc6\x5f\x2e\xf5\x91\x6b\x1b\x92\xda\x48\x74\x7c\x2d\xce\x19\xd8\xe1\xb6\x24\x89\xad\xa1\xbb\x9d\x9b\x25\x12\x08\x93\xd8\xe6\x47\x8c\x6d\xde\x7c\x07\x03\x34\x50\x51\x83\x95\x7b\xd6\x3f\xca\xea\x83\x7a\xf6\x3f\x4e\xd8\x55\x3a\x13\x21\x02\x4a\x08\xfe\xcf\xf9\xad\x3c\x40\xff\x57\xc3\x60\x01\xf1\xd3\x78\x88\x75\x07\x30\xa6\x62\x23\x16\x6a\xdf\xd4\xfd\x5f\x53\xe6\x04\xb1\xe9\xd7\x6e\xce\xcb\xf2\x74\x2c\x8b\xc9\x0b\x10\xa8\x02\x7b\xe7\xb6\x68\x67\x3a\x5a\x7d\xc9\x41\xef\x9e\x56\xfa\x46\x83\x86\x36\x6e\xdb\x73\xdd\xae\x20\x74\xd5\x78\xf2\xbc\x92\x79\xbc\x37\x88\x1d\x0e\xfb\x2b\x8b\x42\x22\x99\x6f\x40\x3d\xf5\xf1\x42\xd1\x6e\xda\x32\x20\xb1\x16\x83\xf5\xba\xbb\x71\x0f\x2e\xb9\x71\x4e\x58\xbc\x95\x96\x27\xe8\x8e\x68\x1f\x9d\xb5\x1a\xa5\x74\x4f\x3d\x8e\x46\x24\x9a\xc5\xa1\x85\x7d\x6d\x9e\x9f\x1f\x3a\xcf\x12\x77\x98\x2b\x82\x57\x1a\x3d\xca\x4b\x94\x80\x6b\x26\x35\xc9\x0a\x65\xf5\xde\xee\xc6\xa7\xb1\x36\xf3\x62\x46\x95\xde\xaa\x78\xbb\x77\xe1\x35\xf3\x23\xd4\xb6\x97\x19\x06\xcd\xfc\xeb\x61\xbe\x64\x2c\xe9\xe5\x03\xef\x65\x69\x92\x5a\x93\xdf\xf0\x55\x4a\xf9\xdc\xdb\xf5\x7a\xbf\x5d\x3f\xac\x97\xbb\xfd\xc3\xcb\xd2\xfd\x58\x10\x22\xb1\xf1\x8e\x58\xd5\x65\x41\x8c\xdd\x4e\xf1\x55\xb0\x20\xe2\x89\xee\xd0\x88\x43\x2d\xaf\x2b\xf7\x14\x32\xc9\x86\xfb\xf2\x4b\x0c\xa0\x60\xa1\xd0\x34\x05\xbd\xb5\x01\x47\x47\xa9\x14\x2c\xf2\x4c\x6a\xce\x56\x55\x8e\xc7\xfb\xa2\x6e\x68\x52\x9c\xd9\x94\xb1\x88\xe9\xc0\x42\x7a\x9e\x2b\xb8\x83\xfa\xd2\x49\x5a\xb0\x28\x35\x32\x93\x9d\x81\x5a\x3b\x73\x37\xbd\x9d\xc0\x65\x7f\x66\x91\x34\x55\x43\x01\xf2\xe3\x05\xd5\x26\xcb\x8d\x58\xba\xc1\xa3\xd8\x46\xb1\x52\x64\x8e\xb5\xf8\xc7\xcd\xb0\x57\xb1\x84\x71\xcf\x62\x4f\x16\x6d\x4c\x59\xce\xf1\x15\x05\x4b\x90\x3b\x06\xab\x11\x06\x79\x68\xb7\x7d\x93\x46\xcc\x0b\x29\x4e\x7c\x59\xec\xd6\xfb\xed\xe2\x61\xbd\xdd\x2d\xee\xd6\x91\xfb\xa9\x76\x27\x49\xca\x7b\xa5\x15\xcc\x9a\xdd\x6f\x30\x16\x47\xbe\x85\xf0\xee\xce\x47\x54\xd6\xa4\x63\xde\x03\xb2\x3b\x87\x51\x09\xfd\x13\xf2\x13\x0e\x25\x5c\x45\xbb\x4d\x95\xb6\x6f\x5a\x18\xf3\xa2\xd9\xda\xe8\x78\x72\xff\xa9\x8e\x89\xb0\xef\xf6\x06\x6e\x8b\x34\x97\x94\xee\x69\xcb\x73\xb0\x44\xc1\x38\x24\xb1\x1e\xae\x98\x94\x3a\x7c\xc8\xea\x66\xe8\x5d\x22\x18\xc7\x84\x85\x5d\x11\x5b\xe1\xb3\xd6\xa4\x54\x95\x1d\xdb\x10\x6c\x24\xab\x65\xcf\x00\x2f\x25\x69\xc1\xc7\xff\x19\x7d\x48\x08\x34\x45\x5b\x47\x53\x05\x5d\xbc\x61\xff\x23\x10\x25\x5e\x3c\x4c\x49\xd7\xdd\x91\xd4\xd3\xe9\xc0\x37\xca\xee\x9e\x5f\xb7\xab\xc9\xbb\x11\x29\xd3\xda\x56\x48\xe7\x55\x47\x7e\x11\x93\x1a\x7f\xa6\xf6\x1f\x93\x8b\x4a\x8f\x85\x5d\xce\xf3\xc7\x3b\x16\x4f\x65\x43\x06\xf0\x93\x8c\x0a\x93\x10\x12\xac\xe7\x0f\x38\x55\x07\xf2\xa3\x1d\x43\xcc\x04\x53\x41\x42\xb0\x99\xdb\x53\xa1\xae\x32\x83\xc7\x17\x55\xdc\x33\x5c\x49\x2a\xa0\xa0\x32\x5f\x66\x57\x2e\xcb\x92\xc4\xf9\xb3\x4f\xdc\x40\xd5\x0c\x46\x11\x2a\x8e\x03\xc5\xf7\xba\x2e\xab\x5d\x39\xf4\xb1\x75\xed\x74\x4c\x95\xc3\x7d\xb0\x1f\x8a\xc3\xb5\x07\x98\x34\x42\xe6\x55\xa6\xcf\xc6\x3e\xd0\xba\x2e\xcd\xdf\xa3\xf6\x31\xe9\xf8\x5f\xbf\xd0\x9d\x13\x4c\x23\x10\xe1\xe1\xc7\xe2\xe1\x61\xbd\xdb\xef\xd2\xf5\x1f\x7b\x87\x94\xb1\x6d\x52\x2f\x04\x5a\x75\x8e\x65\xdd\x4c\xa0\x9e\x6e\x3a\x49\xbd\xd4\x0f\xed\x8c\x30\x5e\x6c\x53\x0f\x18\x05\x98\x78\xc8\x9a\x65\x79\xaa\x1a\x67\x78\x35\xba\xe5\xd4\xd3\x42\x1a\xbf\x43\x8a\xe8\x9e\xf5\x10\x9f\x29\xd2\x80\x27\x14\x2a\x9b\x49\xf3\xb5\xce\x8a\xb7\xb1\xc1\xf0\x60\xce\x4c\x03\x9e\x1a\x0f\x18\xd9\xc9\xf1\x59\x3f\x3a\xdb\x20\x0c\x31\x74\x0c\x72\x63\xba\x30\x4f\x6b\x1a\x4f\x18\x69\x98\xf0\xc8\x16\x1c\xb7\x90\x0f\x27\xf5\x34\x64\x11\xc1\xd1\xc5\xe9\x6c\x14\x03\x6e\x1d\x97\x6d\x56\xf3\x5a\xa4\xa1\xf2\x68\x57\xff\xfd\x65\xfd\x4c\xd3\xde\x7e\xf9\xf0\xbc\xbd\x7f\xba\xdb\xef\xee\x1f\xd7\xee\xb2\x51\x10\x07\x7d\x90\xdd\x3e\x7b\x17\xe7\xa7\x71\x80\xd4\xad\x8e\x19\x4a\x24\x21\x82\x5f\x6e\x6e\xd2\x38\x61\x14\xce\x2a\x3c\x96\x75\xd6\x3c\xdb\x9c\x67\x3d\x93\xcc\x98\xdc\x6b\x9c\x68\xaa\xf7\xed\x4d\x4c\xb3\x84\x6b\x79\xa3\x34\x16\x8a\x0d\x85\xe7\x68\x76\x72\xc8\xf3\xc9\x17\x4f\x54\x4a\x7a\x3e\x0e\x6d\x72\x57\xce\xcb\xc2\x88\x94\x49\x41\xb2\x10\x77\xd8\x6c\xb0\xb2\x5f\xb4\x7e\xb8\xa6\x65\x2d\xd2\xd4\x67\x89\x4d\x99\xfc\xe3\x84\xf5\x85\x57\xae\x48\xd3\xd8\xa3\x52\xd6\x9e\x4a\x59\xf3\xab\x7c\x9a\x26\x9a\xc8\x2e\x66\x57\xd7\xd7\x8e\x53\x2e\x4d\x7a\xb3\xc2\xe3\xa9\xa1\xf1\x34\xad\xb3\xa6\x1c\x4d\xca\xe8\x26\x6b\x56\x90\xe5\xe7\x9b\xb2\xeb\x7d\x90\xf8\x04\x05\x59\x6c\x36\xfb\x9b\xc5\x76\xbd\xdd\x3f\x2d\x1e\xd7\xdb\xcd\x62\xd9\x7d\x77\x91\x48\xe9\xe4\x11\x4e\xa2\x9d\x9a\x1f\xa1\x69\xc6\x8c\x0b\x91\x0a\xa6\x1d\x60\xa0\xa8\x75\x59\x1d\x26\xf7\x20\xa4\xa1\x50\x3f\x2e\xfe\xa0\x5e\xb5\x7f\x59\x3c\xdd\xad\xf7\xa4\xe6\xe5\x7e\x49\x22\x12\xb3\x74\x3f\x56\xe6\x5c\x15\x30\x79\x63\x52\x43\xdc\x8e\x99\x6f\x8b\xef\x4d\xd9\x4e\xf5\xe3\xc3\x2a\x8e\xff\x3f\x65\x6f\xd2\xdd\x38\x8e\x65\x8f\x7f\x97\xdf\x2a\x17\xbd\x20\x40\x82\xc3\x7f\x27\xcb\xb2\x43\x95\xb6\xe5\xb2\xe4\x88\xac\xee\xd3\x47\x07\xc3\x83\xcd\x32\x45\xaa\x48\xca\x0e\xe5\xa7\xff\x1f\x3e\x0c\x1c\x44\x45\x66\x6f\x32\xf2\x98\x20\xc5\x01\x78\x78\xc3\x7d\xf7\x6a\xe2\x5b\x08\xdc\x56\x91\xaa\x44\x62\x26\x5d\xe5\x0d\x17\x85\x57\xc7\xea\x2d\x50\x0a\x59\x10\x85\xa6\x69\x77\x73\x6a\x2f\x11\x76\x29\x48\x1d\x46\x83\x39\xd5\x2b\xda\xff\x36\x9f\x1a\xbd\xb2\xa1\xf8\x3e\x9a\x91\x00\xe0\xec\xee\xdc\x9f\x31\x3d\xd7\xdd\x93\x4a\x91\x23\xd8\xb7\x03\xf1\xfd\x94\x70\x48\xa4\x00\x31\x96\xa8\xf7\x28\x24\xd0\x05\x30\xe5\xbe\x0f\x8f\x53\x1d\x84\x81\x8b\x56\x56\xed\xfb\x95\x39\xa8\xa9\x46\xbc\x1a\x82\x13\xaa\x9a\xbf\xc1\x45\x8c\x70\x09\xf1\x99\xbe\x81\x6b\xbc\x8a\x22\xd5\x8c\x63\x74\xa6\x01\x1a\x9f\x17\x34\x39\x9c\x29\x62\x22\xd5\x89\x46\xac\xc7\xb1\x9e\xa1\x6c\xb3\x83\xb2\x20\x49\x31\x3c\xc7\xee\x84\x7b\x28\xb1\xf9\x68\x18\x75\x64\x41\x16\xe0\xbb\x53\xf0\x89\x06\x68\x56\x4d\x57\x64\x24\xc8\x70\x62\x3e\x7c\xff\x63\xe8\xb2\x64\x24\x49\x22\xe9\xa5\x64\x2e\x99\xbe\x44\x46\x59\x84\x0e\xf6\x5e\x9c\x2e\x99\xb1\xc7\x43\x43\x42\x9c\x44\xa0\x89\x41\x76\xd5\x13\xfc\x6c\x11\xf3\xe7\x7e\x30\xd4\x21\x7e\x01\xc4\x8d\xe3\xad\x8c\x60\x5b\x33\xaf\x7b\x62\x45\xdd\x26\x99\x45\x31\x47\x50\xd2\x73\xc1\xcf\x5b\x63\x37\x8c\x64\xa8\x3d\xce\x52\xd3\xb4\x73\x57\x55\x23\x3d\xb6\xb9\x8c\x63\xc6\xb2\x10\x7d\xfe\xaa\x8b\xbd\xdd\x9c\xa8\x6a\x47\x15\x31\x79\x27\x71\xa2\xd0\x99\x83\x52\x6d\x34\xb2\xee\x85\xee\x57\x13\x49\xb1\x41\xe1\xf4\xe7\x9f\xa3\x9a\x41\x96\x72\xe1\x29\x3d\x77\xef\x75\xf5\x65\x40\xcc\x5b\x28\x0a\x0c\xf8\x77\x5f\x9e\x7d\x52\x64\xa9\x4a\x9c\x03\xf0\x82\x95\x85\x39\x24\xba\xc8\xb2\x34\x40\x0d\x06\x0d\xad\x7c\xb7\xa8\x4a\xbc\x58\xb7\x0d\x3d\x42\xdd\x45\xcb\x93\x8d\x22\xe3\x94\x60\x19\xdf\x0c\x7f\xf9\xef\xc7\xf9\x6d\x22\xe3\xc2\x70\x0c\xf3\xba\x9e\x6d\xfb\x11\x99\x88\x93\x84\xd9\x27\x7a\xcc\xcb\x76\xf7\x9e\x37\xbf\x8d\xae\x21\xa5\x89\x23\x86\x90\xb7\x19\x7a\x97\x6e\x60\x86\xb9\x69\xdb\x41\x64\xf1\xdd\x57\x58\xb0\x45\x26\x55\xaa\x3a\x2b\xd7\x72\xe1\xde\x98\xa2\x29\xe6\xe9\xca\xd3\xe1\x36\x7f\xcb\x27\x3d\xb6\x22\x53\x4c\x85\xa6\x39\xf9\x90\x97\x2f\x08\x2a\xb8\x52\x0a\xcb\x94\x36\x42\x67\x25\x7c\xed\x80\x1f\x36\xe5\xca\xe6\x74\x66\x3b\x62\x6c\x53\xa3\xc8\x34\x89\x51\xb9\xa5\xe5\x1f\x5d\x08\x81\x59\xf1\x91\x21\x34\xe3\x78\x40\x24\x46\xea\x7d\x78\xf9\xbc\x7a\xda\x5d\x5f\x00\xee\xb4\xc4\x90\x0a\xec\x0d\x22\xe2\xae\xae\x0e\x0f\x23\xb9\xca\xf1\x53\xf0\x00\x0c\x5c\x03\x35\xa5\xda\xaa\x85\xdb\x2e\x5c\xac\x8e\x07\x28\xdb\x21\x57\x8b\xe0\x84\x1b\x30\x9b\xa3\x05\xe8\xdc\xf7\xa6\x3f\x28\x5d\xc2\x6d\x55\xea\xaa\x96\xf0\x02\x9f\x79\xd3\xd3\x8e\xd3\xc0\x8e\xa4\x84\xa1\x63\x8b\xc5\xfe\x8d\xde\xd5\xf0\x59\x95\xff\x18\x40\xe3\x38\x25\x31\x36\xd9\xf3\xe6\xe3\xae\x9a\x21\x1b\x16\x9c\x52\x03\xdc\x71\x5e\x8c\x2d\x87\xfe\x2d\xb4\x2a\xa7\xa1\x69\x95\x7e\xde\x3c\x0f\x57\x1e\xa7\x9c\x61\x53\xd0\xbe\x3d\x95\x57\x9c\x13\x94\xa4\x64\xa6\x9e\x2e\xc1\xe5\xf1\xec\xb1\x90\x64\xc4\x24\xab\xaa\x8f\xed\x91\x7f\xcf\x9b\xe9\xe6\xc4\xc3\x50\x22\xea\xc4\x37\xaf\x37\xcb\x5e\xd4\x47\xf0\x10\x4c\x71\xd5\x58\xd9\xfc\x70\x3a\x8c\x50\x13\xe3\x6b\x45\x32\x65\xd6\x3f\xfb\x31\xe1\xc0\x1f\x7f\x61\x16\x4b\xac\xec\x8b\x93\x15\x00\x1e\xb1\x0d\xcf\xae\x6a\xce\x20\x43\x58\xcd\x16\x0a\x7d\x0b\xa6\x6a\xea\xee\x32\xd6\x09\x96\x53\x4c\x60\x64\xec\xc3\x36\xbf\x8a\xbd\x9f\xab\x7a\xf3\x84\xf2\x08\x8c\x80\xfc\xd3\xfa\x9f\xc6\x15\xdf\x3c\xaf\x9e\x26\xae\x38\xef\xa2\x30\x2c\x46\x55\xd5\x47\x7e\x25\x81\xcd\xd3\x98\x1b\x50\x21\xf6\xfc\xf2\x5a\x89\xca\x31\xb2\xb8\x55\xc7\x53\x01\xb1\x69\x80\xcf\xe5\x07\x98\xf6\xb7\x5b\x28\xe0\x6d\xe0\xdc\xf3\x2c\xcd\x90\x42\xd2\xb4\x7e\xee\xf2\x83\xeb\xd0\x13\x3c\xe3\x29\xb7\x59\x95\x5d\xbd\x3c\x4d\x3f\x6c\xa6\x38\x6a\x63\x1f\x73\xf9\x71\x93\xbf\xd9\x0c\x88\x3d\xc8\x39\x45\x4c\xdd\xe3\xfa\x69\x8f\xc5\xce\xf5\x0d\xf6\x3c\xec\x9f\x5f\x56\xdd\x93\xfb\x71\x22\x04\xe2\x34\xd6\xac\xf3\x6b\x5a\xe2\xc6\xcf\xcb\x15\x01\xaf\x58\x70\x9b\xfb\x04\x0a\x17\x54\xa3\xca\x99\x71\xaf\x07\xe0\xe3\x49\xf9\x7a\x94\xd2\x76\xe7\x26\x1a\x1b\x4d\x8d\xe8\x96\xae\x26\x41\x3b\x97\xd4\xd0\x3c\x3e\xf2\xb2\xe4\x03\x54\x29\x97\x91\x44\x38\xf3\x7d\xaf\x67\x8d\x62\xf7\xbb\x2e\x68\x28\xbb\xad\x66\x0b\xf2\xd6\x11\xd5\x09\x2e\x93\x14\xb5\x27\x0f\x79\x01\x4d\xeb\x15\x7d\x05\x97\xd2\xb0\xb1\x1b\xc8\xdf\x46\x4f\x5e\xb1\xa2\x84\xa3\xd8\x67\xf7\x01\xdb\x86\x7c\x1c\x7b\x1e\x66\xc1\x81\xc7\x08\x68\x7c\xfd\x3e\x5e\xd4\x20\x03\xe4\xff\xb7\xb5\x48\xf4\xe7\xfb\x74\xd6\xa4\x85\x72\xb8\xd5\x73\x1d\x50\xb4\x68\x0f\xd5\xdb\x40\x2b\x58\x70\x4d\x49\xc4\x66\x49\x92\xdd\x00\x26\xa1\x57\x00\xc5\x1c\x74\x9f\xae\x9c\x14\x1e\xb8\x4e\x68\x64\xb3\xc1\xe8\x55\xcd\x22\x3f\xb8\x56\x81\xa6\x03\xb4\xcf\x16\xb5\x78\xbc\xdd\xd0\x4a\x88\xd8\xe9\x08\xa0\x09\x30\xf9\xca\xd9\xb5\x2d\x82\x2c\xc2\xdc\x59\xaf\xb9\x77\x25\x10\x1d\x2f\x33\x41\x92\x50\x79\xbd\x08\xab\x85\x0c\xe7\xbd\x02\x83\x56\x78\xaa\xbe\xf5\x3d\x2f\xee\x94\x34\x74\xb9\x48\xab\x85\xf3\x27\xa8\x87\xea\x2d\x97\xbf\x6a\x9d\x13\x82\x46\x0c\xeb\x2a\xe6\x57\xb0\x1c\x78\x0b\x65\x75\x30\x3d\xd5\xe3\x97\x23\x42\x09\x98\x78\x50\x66\xe3\x82\xda\xde\xdc\xbe\x9b\x81\xcd\xbe\xd2\xfb\xc6\x4a\x10\x0e\xbf\xaf\x88\x12\x85\xc0\x1b\xb4\x1a\x86\x59\xac\x5b\xb6\x3d\x15\x95\x10\x2c\xe1\x48\x7e\xe6\xb6\x99\x4d\x39\xcf\xc3\x27\x44\x4c\xa8\xe3\xf6\xbe\x94\x43\x14\x22\xa6\x9a\x46\x7d\x65\xf8\xd1\x78\xf8\xe3\x67\x8e\xc3\x10\x63\x39\x5c\xd5\xfd\xac\xea\xd5\x11\x84\x48\xa8\x8e\x13\x74\x5e\x8a\x22\xd7\x13\x38\x82\x48\x03\xc0\xb4\x22\xb7\x49\xe5\x71\x4f\x99\x48\xa9\xa9\xca\xef\x6b\x5e\xaa\x9b\xf3\x0b\xa2\xb2\x66\x77\x39\x91\x86\xa1\x32\x19\xc4\x4f\x3b\xc3\xab\x53\xeb\x6b\x08\x22\xe5\xa1\xcb\x51\xde\x58\x1e\x89\xf1\xf9\x59\x2a\xb9\xa9\x66\x1e\xf2\x36\x71\xa7\x65\x0a\x10\x2b\xfd\x86\xde\xbe\xfb\x2b\x17\xca\x15\x24\xca\xd3\xa4\x45\x50\x08\x42\x32\x4b\x4d\x69\x18\xfa\x6c\x50\x33\xaf\x2d\x7f\x9a\xed\xdd\x19\xfe\xd7\x7a\x66\x63\xa6\x6e\x21\x04\x35\x0c\x3a\xc3\xd0\xe5\x2f\xfe\x75\x67\xc2\x58\x81\xf8\xe6\x7c\x75\x55\xd9\x33\x64\xac\x31\xad\x92\x37\xcf\xfc\xdc\x45\xe7\xa3\x6e\x5f\x21\x64\xca\x42\xe1\x92\x4f\xaf\x2f\xeb\xed\x49\x6b\x47\x95\x22\x84\x0a\x0d\xd9\x16\x57\x6a\xd9\xcd\xdb\x0b\x40\xd0\xf8\x8d\xcc\xdf\x82\x8a\xd2\xd8\xf4\xfe\x23\x0f\xdc\x4d\x5e\xab\x66\x20\xd3\x23\x84\x4a\x52\xc5\x47\x48\xa0\xa7\x5c\x7e\x94\x53\x2e\x90\x6e\x60\x86\x59\x02\x9d\x97\x6a\x08\xef\x98\x7a\x99\x42\x65\x1c\x3d\x9b\xc5\xc3\xc3\x66\x69\xb5\xac\x56\xfe\xe7\xb8\x4a\xe5\x50\xa6\xc4\x20\xa1\xcd\x24\xde\xca\x77\x38\x70\x64\x28\xbb\x92\x69\x1b\x87\x1b\x42\x71\x40\xbc\x93\x6d\x05\x01\xa4\xff\x98\xdc\x8d\x0e\xd2\x70\x90\xdc\x98\x4f\xe8\x0a\xa0\x5a\x3b\x98\x45\x5e\x23\x18\x21\xaf\x4a\x9b\xba\x1c\xd9\x12\x1d\x10\xe1\xec\x9c\xc2\x36\x8e\x4b\x80\xe8\xe5\x5c\xed\xbf\x88\x96\xca\xf5\xf3\x2d\x37\xb6\x75\x57\xc8\x80\xa6\x58\x85\xfa\x63\xf7\xdd\x72\x82\x4f\xad\xa6\x1b\x28\x83\xd4\x31\xdd\x8c\xe9\x99\x85\x24\x61\x86\xde\xda\x43\xf5\xf6\x98\xbf\xd5\x7c\x8e\xb4\xcf\x0d\xd5\x14\x39\x10\x9a\x53\x2e\xf3\x29\xf8\x41\xd2\xc4\x80\x4e\x8e\x06\xdc\xf0\x04\x5f\xc3\x80\x5d\xd2\x24\xc5\xed\xf2\xb6\x7a\xaa\xda\x5b\x6c\x9d\xed\x02\xbd\x7b\x68\x77\xef\xf0\x92\xbf\xbd\xb7\x9b\x12\x96\x55\xf3\xcc\xeb\xbc\x3d\x3f\x9f\xda\xa6\x3b\xbc\x29\x77\x8e\x7e\x5d\x48\xaa\x02\x34\x60\xb2\x2a\x9b\xd3\x61\x0a\xea\x94\x14\x0c\x7f\xb7\x01\xfb\xbd\x36\x56\x0b\x63\xef\x8e\x87\x69\x86\x74\xac\xf0\x13\xe4\xa9\x85\xdd\xcf\x89\xc7\x2c\x23\x46\x31\xa3\x5a\xc2\x97\x0f\xd8\x67\xe7\xd2\xd0\x55\x95\x51\x9a\x62\xa3\xce\x6a\x5b\x54\x6d\x73\xb1\xbc\xed\x28\x16\xca\x20\xb1\x74\x04\xe3\x4e\x49\x37\x20\xa6\x99\xdf\x6e\x2e\x96\xed\x38\x11\x3e\x1b\x47\x4b\x96\x64\xae\xd0\xbe\x96\x95\x6d\x9a\x71\xc7\x54\x10\x50\x8b\x2e\xf8\xe7\x09\x3c\x32\x69\x3e\x04\x92\x31\xd3\xa9\x4d\x2a\xdd\x9c\xce\xb8\xbf\x3a\x4f\x57\xc6\x19\x33\xa0\xc5\xaa\x9d\xc1\x6c\xcb\x34\x34\x92\x44\x39\xf2\x32\xd6\xfe\xcf\x29\x41\x47\xfd\x7e\xf3\x70\xbb\x7a\x7a\x59\xec\xd6\x2e\xe5\x26\x33\x12\x1a\xbc\x20\x46\xeb\x06\xb5\x80\xaf\x86\xa6\x7e\x04\x18\x71\x8d\x93\xb8\x0c\xfd\x27\xb7\x9e\x85\x21\xe6\x90\x8f\x7b\x97\x06\xbc\x85\xcf\x6f\x55\xa1\x06\x1b\xb7\xcc\xc0\x54\xd8\x6c\x10\xec\xb8\x2a\xbb\x2b\x45\x36\x0e\x95\x9c\x98\x96\xf7\x37\x68\x1f\x78\xd3\x6e\xc1\xdb\x60\x29\xb8\x91\xd6\xcb\x2d\xbb\x13\xd6\x1c\xc6\xdf\x5b\x88\x30\xf6\xf1\x00\x2f\x9b\x23\xd4\x2f\xa7\xe9\x84\x93\x51\xcc\x6c\xc9\x0e\x09\x9b\xdd\xf2\xbd\x39\x3b\x68\xe7\xf4\x84\x58\x72\xed\xb5\x16\xf7\xb5\x6d\x09\x99\x0c\x12\x19\x2e\x53\x9b\xc8\x19\x4b\x8b\x8f\x87\x2a\xca\x90\x00\x4e\x60\x9a\xed\x19\xea\x6f\xd5\xc9\x7f\x32\x20\xda\xaa\x7d\x68\xa8\x6b\x23\xbb\xb1\x2e\x3f\xf3\xbe\x81\x5d\x82\x08\x70\xa7\x37\x68\xfa\xf1\xb5\xb5\x25\x9a\x75\x0f\x75\x77\x2a\x0a\x9d\x63\x36\xc6\xdd\xcc\x78\x3c\xc9\xb0\xa7\xf8\xde\xd0\x23\x96\x46\x4b\xf0\xa2\x42\xa1\x02\xa2\x30\x0a\x92\xc5\x69\xd0\x4b\xaf\x02\x96\xa0\xef\xf3\x72\xb3\xf0\x7f\x02\x22\xbc\xc8\x74\xcf\xf2\x24\x14\x89\x13\xc4\x5f\xac\xef\x1f\x79\xfb\xde\x4c\x42\x19\x45\xb2\x18\x99\x45\xea\xce\x7e\xed\x81\xd7\xe5\x25\x14\x50\x11\x01\x8e\x9d\xe7\xb6\xae\x26\xf4\xe7\x42\x11\xa5\x33\xf7\xfd\xf3\xf6\x54\xf0\xbc\x86\xbd\x65\x1c\x9f\x80\x07\x15\xa5\x19\x16\x64\x91\x04\xda\xa4\x79\x47\x90\x35\x45\xb9\x44\x96\xac\x3e\xd5\xb3\x74\xe4\x73\xb3\x8b\x40\x85\x24\x08\x1c\x8a\xe3\x94\xe3\xdc\x77\xd7\x0a\x43\x82\x72\x9d\xcf\xf9\x9f\x7f\xf2\xe7\xaa\x28\xfc\x01\x19\x62\x1b\x65\xc3\x35\xe0\x26\x21\x79\x73\xd1\x8d\x7d\x4d\x14\xb2\xb7\x87\x2a\x94\x2a\x1e\xc2\x72\x9f\x8d\x4c\xe1\xe4\x99\x43\x15\xa0\x15\xe9\x3c\x83\xce\xdd\x33\x11\xcb\x6f\x23\x33\x6b\x0d\x9b\x8a\xa8\xe2\x86\xd7\xae\xfc\xf0\x8b\x50\x45\xdc\x28\x3d\x36\xe7\xb2\x7d\x87\x36\xff\x89\x51\x65\x7f\x34\x05\xee\x42\x9e\x66\xec\x6c\xc5\xd1\x00\x11\xa2\x58\x24\xdc\x4a\x35\x3e\x64\x17\x89\x4c\xe6\x1c\x63\x1a\x05\x78\x16\xcb\x01\x17\x81\x62\x59\x84\xa9\x31\x04\x9a\xf9\x36\xcd\x2b\x55\x38\xc5\x40\xc7\x96\x86\xff\x0e\x0c\xcb\xc7\xdb\xdf\xeb\x39\x54\x71\xc4\x0d\x27\x45\x51\x35\x86\x21\xdd\xdd\x42\xac\x78\x6a\xbc\xc5\xd7\x5c\x6d\x27\xa8\x3c\x15\x6b\x86\x70\x38\xee\x89\x08\xc6\x5b\xa6\x4a\x62\xa3\x89\x81\x16\x1e\xd5\x90\x6f\x4d\x49\xc8\x0f\xd0\x8a\xb8\x84\xd4\x63\x5e\xb8\x56\x4e\x95\x46\x31\xcb\xbc\x9a\xae\x71\xc5\x6e\xce\x06\x6c\xea\x0a\x8b\x13\x33\x3d\x7e\xa3\x69\x94\x62\x92\x6d\xbd\xdc\xec\x0d\xd1\x93\x3b\x90\x19\xea\x02\x47\xb6\xd8\x53\x5b\xf4\x0e\xa8\x4a\x25\x45\x48\xc6\x0d\x6f\x72\x89\x3f\xbe\x3e\x1c\xfd\x4c\xce\x48\x82\x6b\x0f\xdb\x86\x50\xaa\xdd\x1f\xe1\x91\xb2\x71\x96\x27\x10\xf4\x2f\x43\xa4\x02\x95\xc9\xa1\x6a\xee\x17\x5b\xff\xd7\xcc\x70\x74\x18\x77\x51\xed\x8f\xc8\xd1\xbb\x3f\xf2\x73\x51\x71\x7f\x61\x49\x13\xd6\xa7\x11\x1c\x04\x4c\x29\xc6\x11\x32\xcf\x65\xeb\x11\x28\xc6\x83\x38\xfd\x35\xf0\x44\x29\xa6\x0c\xd7\xef\x17\x3f\x0e\x0b\xc2\xee\xb0\x54\xc2\x09\x1d\x4a\x44\xd4\xd9\xe0\x7e\x12\x2d\x2b\x20\x59\x9a\x4e\xd4\xc4\x6c\xd0\x66\x7b\x2b\x7e\x59\xa3\x56\xa0\x03\x66\xdf\x1a\x72\x53\xe5\x7f\xc2\x10\x93\xa2\x74\x62\x30\x55\x08\x90\x41\x93\xdd\x9b\x5a\x9d\x32\x0c\x7c\xf7\x70\xc8\xdb\x1f\x55\xfd\xe1\xa4\xdf\xe6\x67\xba\xd6\x54\x5a\x1f\xc6\x94\x3c\x87\xd2\xde\x02\x02\x92\x64\x81\xef\x97\xfe\x76\x14\x4f\x95\xf2\x1f\x10\x48\xc0\x42\x65\x9d\x1c\x94\x52\x90\x1f\xbb\xca\x38\xdb\x76\x04\x0d\x88\x23\x58\x5d\x14\xc5\x4d\xae\xb0\x61\x0b\xe9\x6b\x47\xf7\x01\x54\x48\x24\xea\xdb\x37\x27\x64\xba\xb3\xf6\x78\xf4\x5e\x81\xca\x94\x09\xaf\xfd\x9a\x37\x92\x17\x28\x08\x34\x66\x93\x12\x40\xc1\x34\x44\x1c\x4f\xcd\xfb\xae\x7a\xf6\x35\x67\x08\x03\x82\x75\x97\x1f\xeb\xa7\xa7\xd5\xcb\x7e\xfb\x6d\xe1\x83\x1e\x08\x83\x04\x19\x07\x7e\xcf\x5b\xf9\xee\xf3\x55\x10\x12\xc3\xf8\xd7\xe6\x50\xd3\x5d\x7e\x80\xa6\xe5\x87\xa3\x3f\xca\x02\xe7\xb3\x58\x9f\x66\x1c\xe4\x43\x08\x19\x35\x7d\xea\xd5\x27\x94\x06\xd3\x31\x79\x2a\x16\x31\x97\x8b\xd8\x2f\x7f\x2c\xf7\xb3\x19\x18\x60\x0c\x98\x95\x5c\xc3\xa6\xb4\xb1\x61\x01\x96\x26\xa8\xad\xbb\xe4\xcd\xfb\x73\xf5\x01\xf5\x73\xed\x00\x82\x6e\x84\xe0\xc2\x26\x09\x36\x47\x28\x4d\xb9\xc9\x1f\x94\x1c\x11\x0b\xcf\x9b\xc5\xb3\xff\x9b\x86\x4c\x39\x3b\xfd\x73\x59\xe5\xe5\x36\x57\x16\xbe\x69\x1d\x45\x88\xa5\xc1\x6f\xe4\x86\xc3\x7d\x53\x6f\x8e\x56\x91\x71\x36\x3c\x87\x24\x60\xb8\x4b\xfc\xb2\xf0\x75\x73\x9e\x49\xb2\x42\x96\x51\xde\x53\x53\x19\x5d\xd6\x69\x7e\x6c\x3c\xa7\x32\x00\xa1\x1d\x75\x7c\x2e\x01\xf9\x2e\x27\xdf\x87\x33\xaa\x8c\x6e\x3e\xd2\x9c\x0c\xa4\xe4\x04\x70\x41\x93\x1e\xa2\xf8\x52\x9d\xda\xbc\x7c\x5b\x56\x0a\x26\xd3\x8d\x0b\xe5\x5a\xff\x9e\x8f\x05\x4a\x55\x8d\x6a\xbd\x20\xed\x4e\xbf\xfa\xc9\x0f\xc7\x62\xe2\xb9\x80\xd4\x02\x79\xa1\x3f\xaa\xf6\x7d\xff\x49\x5c\x65\x0c\x14\x01\xc7\x0b\x3e\xa0\x36\x1e\xbf\x14\x15\x1a\xe2\xb0\x7b\x7e\x80\xe7\xaa\x2a\x26\xb3\x42\xe9\x0c\x79\xaa\x77\x37\x01\x71\x7f\x83\x40\x81\xd1\x65\x37\x41\x7d\x7e\x40\x12\x38\x7f\x98\xa7\xe8\x8b\x61\xba\xe3\xbe\xe6\x65\x0b\x30\x71\xc5\x40\x07\xc6\x2a\x18\x5a\x09\x43\x27\x3b\xee\x65\x74\x03\x21\x41\x3c\xf3\xd3\xeb\xe3\x7e\x73\xb7\x7f\xfe\xb6\xd8\xba\xf5\xa6\x49\x44\x11\x73\x85\xf1\xd7\x36\x2f\x9c\x7c\xc0\xb4\x4a\xf7\x8b\xd2\x9d\x26\x91\x52\x86\xa7\xf5\xac\x8b\x8a\x7f\x34\x8b\x37\x9e\x97\x8d\xe1\x68\xf2\x3f\x24\x82\x40\xb8\x1f\xba\x81\xe1\x01\x6d\xd0\x4a\xdd\x76\xdd\x7a\x01\x16\xa1\x09\x28\xdc\x2b\xf7\x5d\x28\x52\xbd\xe1\xa3\xcd\x6a\x24\x09\x4d\x74\x82\x0d\x6f\xfb\x77\xde\xe0\x9c\xbc\xab\xea\xce\xeb\x84\x36\xbf\x1e\xd8\x6b\xa2\x01\xd9\x1c\x3c\x0f\x74\x5f\x07\x1a\xc8\x66\x4f\x4e\xa2\x09\x04\x3d\xa4\x7a\x59\x95\x4d\x9b\xb7\x18\x0a\xa2\x57\x39\x7a\xf3\x9a\xca\xcc\xb0\xb2\x18\x02\xf0\x5e\xf8\x7c\x32\x4c\x87\xae\xf2\xbf\xaf\x47\x5b\x93\x1d\x10\x52\xa3\xd8\x77\xbb\xba\x1d\xa6\xf1\x75\xc8\x0c\x61\x3f\xee\xf6\xb8\xf6\x9b\xf7\xfc\xe8\x5c\x32\xaf\x56\x2f\x74\x14\x31\x1c\x98\x37\x88\xe2\x9c\xb7\x0b\x3a\x62\x1c\x69\xfd\x70\x17\x29\x3f\xfc\xc9\xd2\x68\xe4\x61\x3f\xfe\x8c\x6b\x7c\xe1\x24\xdb\xf3\x58\x40\xa5\x63\x97\x84\xb2\x45\x89\xd4\xdd\x37\x77\x55\x46\x12\x2c\x1d\xed\x65\x55\x96\x20\xdb\xc7\x4a\x9d\xbc\x07\xa6\x59\xc8\xd1\x95\x1f\xd1\x18\x3c\x56\x57\x48\x26\x85\x66\x8c\x22\x39\xfe\xc3\xe6\x7e\xef\xd8\x87\xbb\x99\x30\x6a\xf0\x98\xff\xa2\x4c\x64\xc4\x32\xf7\x6e\xb9\x86\x7b\x3e\x59\x68\x9a\x81\x20\xd2\xf9\xa1\x17\x34\xfb\x76\x50\x1c\x1a\xd5\x1b\xee\xc8\x61\xb7\x9d\x83\x3e\x60\x9b\x16\x3a\x4e\x98\x81\x15\x22\x83\xaa\x39\x7b\xea\xb5\xe8\x84\x46\x32\xf1\xd8\x05\x6c\x7b\xa5\xd3\x21\xb1\x29\x97\x0a\x04\xc8\x6c\xb4\x2e\xf2\x12\x46\x45\x69\x9d\x64\x0a\x25\x28\x4d\x3a\x64\x59\xcd\x8b\xfe\xa1\x0c\x46\x20\x5d\x7d\xba\xcd\xdb\x33\x16\xc5\xad\x61\xb5\x1f\xd4\xf7\x62\xe9\x94\x48\xc4\x7e\x6a\x4b\x23\x6a\x7b\x88\x47\xd6\x4e\xa7\x8a\x6a\xee\x9a\x8c\xf3\xa3\xff\x7b\x96\xea\x98\x8f\xc3\xbd\x9b\x41\xb5\x46\x73\x96\xc6\x86\xf7\xa0\x54\x83\xec\xbe\xe6\xb1\x49\xbf\xe5\x8e\x79\xc1\x41\xd4\xa7\x9f\x89\x67\x29\x5a\x98\x6d\x51\xbd\xf1\x11\xe1\xa1\xd0\x5c\xc4\xe8\xb3\x2c\x3e\x79\x51\x95\xa3\x35\x24\x88\x11\xc2\x45\x90\x50\x73\x3a\xdc\xf2\x96\x8b\x2e\x76\xba\xaa\x86\xd9\x9d\x93\x62\x2d\xeb\xbe\x12\x45\x5e\x4e\xf5\x59\x84\x96\x49\x84\xda\xa2\x9b\x97\xc5\xf2\x61\xfd\xdf\xab\xfb\xc5\xf6\xf9\x65\xed\x21\x75\x5a\x4a\x85\x3d\x12\x88\x2e\x68\x8e\xae\x32\x62\xf7\x73\xad\x44\xec\x68\x81\xd7\xb2\xb2\x6f\x79\xd4\x92\x3f\x1f\x5e\xe8\xce\x67\x25\xd8\x89\x25\xdf\xcb\x6a\xe5\xc3\x5f\x0d\x89\x99\xe3\xd2\xb3\x2c\x8e\x36\x4f\x0d\x82\x24\xda\xdc\xd0\xbe\xef\x45\xd0\x20\x53\xf4\xb5\x97\xdf\x56\x7f\xcc\x26\x54\x26\xd3\x09\x74\xe2\xf8\x64\x6d\x7b\xe8\x0b\xfc\xe7\x94\xd7\xa0\xba\x55\x65\x07\xe9\x88\xa4\x26\xf2\x84\x19\xa2\x84\x3e\x59\x3f\xbc\xb4\x0c\x02\xae\xc0\x16\x23\x90\x94\x69\x5c\xb4\xfd\x9f\xff\xed\xff\x67\xf8\x4a\x64\x10\x88\x18\x53\x80\xab\xa2\xc8\x8f\x0d\x18\x8f\xf6\x11\x15\x12\x7f\x55\xc3\x90\x41\x00\x11\x56\x1c\x6e\x78\xc9\x4b\x7e\xc3\x1b\x9f\x99\x90\x01\xa1\x31\xce\x49\xb3\x67\x4d\x7c\x49\x19\x10\x96\x1a\xc6\xfb\x4b\xb4\x02\xc2\x9d\x22\x7f\x1d\xa1\x02\x39\x52\x22\xc0\xaf\x7c\x57\xd5\xb7\x8b\xf5\x6f\xe3\x17\x40\x49\x4c\xad\x84\x5b\x4f\x3c\x24\x03\xca\x88\x23\x6e\x43\x3c\x6a\xdb\x0e\xd4\xfc\x26\xac\x29\x9d\x9b\x18\xa1\xff\xaa\x40\x56\x0a\xbc\x2d\xef\x13\x19\x32\x88\x68\xe4\xca\x58\x4f\x08\x3f\x99\x2f\x5e\xc8\x20\x4a\xa5\x1e\x66\x3c\x26\x08\x31\x3b\x8a\xd1\x04\xdb\x25\x9f\x6e\x57\x7f\xb8\x7b\x8e\xa9\xa1\x8d\x6a\xde\xab\xaf\x1f\xef\x1c\x79\x88\x6a\x7f\x50\xa4\x18\x63\x97\xa7\xc3\xe0\x63\x35\xfe\xb0\x4a\x11\xef\x5f\x94\xc8\x34\x33\x37\x0f\x65\x10\x83\xe1\xd4\xda\x77\x56\xb4\x39\x8e\x04\xf7\xc6\x0f\x91\x04\x06\x54\x63\xaa\xd2\x37\x50\x02\x6a\x2e\x4c\x58\x44\x65\x90\x72\x63\x5c\x1a\xae\x61\x57\x2d\x94\x9a\xe1\x02\x95\x41\x2a\x62\xc4\xba\xac\xfe\x58\x2c\xdd\x0d\xa7\x40\xa5\x7d\x9f\xdf\xd7\xcf\x97\x14\xab\xdd\x08\xa6\xad\x87\x8c\xfa\x8d\x83\x4d\x43\x06\x59\x64\x3a\x8b\xef\x8d\x5c\x6e\x8f\xf3\x96\x41\x96\x65\x78\x08\x10\x84\xef\xed\xd6\x9c\xa5\x97\x41\xa6\x52\xa3\xf8\xff\x5e\x7d\xb9\x0d\xb2\x59\x56\x23\x85\x78\x19\x88\x90\xa1\x7c\xa1\x11\x2a\xf4\x2f\x5d\x44\x29\xc6\xa7\x08\x3b\x7c\x3e\x09\x84\x52\xfb\x83\xdc\xd4\x0f\x2c\xa3\xc5\x28\xd0\xf7\x13\x4f\xa8\x00\xdf\x8c\x34\x2c\xd2\xb7\xb6\x83\xa6\xff\x05\x65\x24\xbe\xf8\xb1\x8b\x3b\x6f\x41\xd6\xe7\x63\x0b\xaa\x8b\x55\x7f\x9b\x4b\xbd\x9d\xa6\xcb\xbd\xff\xbf\xd9\x51\x97\xf7\x93\x60\x2a\x65\x28\xf6\x38\x3f\x97\x24\xe1\xd4\x54\x97\xbb\x90\x7c\xa3\x1f\xf9\xbf\xab\x1a\xb5\x9e\xfc\xcd\xcb\x24\x09\x4d\xe5\xd0\x4a\xf9\x19\x27\xa1\xb7\x17\x2a\x54\xf8\x85\xb5\xa5\xdf\x1e\xff\x82\x8a\x24\x26\x6c\x0f\x50\xcb\x53\xd1\xe3\x45\xdc\xd9\x20\x08\xba\x65\xb6\xb5\x77\xf7\x0e\x77\xa7\xf6\x54\xc3\xf2\xbd\xdb\xf3\x3d\x8b\x88\x0c\x34\xd3\xda\xee\xe6\x7b\xc9\x4b\x85\x6c\xaf\xfb\x63\x2e\x07\xbb\x8b\x24\x84\x47\x59\x4f\x36\x36\x0a\xf2\xfa\x04\xa1\x24\x44\x84\x69\xec\x78\x85\xf3\xe2\x6c\xbb\x16\x66\x5f\x12\x21\x02\x4c\xf4\x7c\xe0\x45\xb1\xf5\xb4\xf1\x92\xd0\xd8\x96\x1d\x31\x76\xfa\x8e\x1c\x77\x33\x41\x8a\x24\x34\xc9\x54\xcf\x38\x82\x00\xbd\x7b\xe8\xf3\xcb\xff\x43\xff\xd7\x0d\xcc\x52\xc4\xa3\x3d\x54\x4e\x71\x57\x12\xca\x53\xb4\x59\xa8\x9e\xc9\x92\xf1\xfb\x25\x94\x0b\xe1\xd5\x2a\xb1\xc5\xf2\xba\x36\x83\x24\x21\x15\x8e\xe6\xc6\x58\xe3\x4a\x23\xb8\x64\xc0\x1d\xeb\x3e\x3c\x09\x43\x86\x72\x3f\x3b\xe0\x87\x21\x2d\x8c\x24\xa1\x4e\x99\x5d\xd3\x8f\xfc\x27\x06\xb4\x5b\xcf\x51\x2f\x49\xc4\x8d\x6c\x1f\x2a\x77\xca\x7a\x00\xb9\xb6\x03\x58\x64\xfc\xd9\x16\x1a\xf4\x4a\x3b\x8b\xe3\x0f\x19\x22\x5e\x27\xb6\xb5\xab\x4e\x75\xc9\x0f\x56\x41\x16\xa9\x89\xa6\x48\x2c\x24\x2e\x25\x36\x46\x5b\x94\x6a\x0b\xed\x6d\xfe\x39\x48\x30\xce\x85\xf0\x23\xd6\x32\x49\x98\x8c\x1d\xcf\xb4\x82\x63\x9b\x0f\x38\x2a\xc7\x1b\x03\x89\x99\x69\xc6\x35\xfe\xa9\xf9\xda\xdf\x3b\x67\xc0\x3d\x41\x92\x05\x10\xf6\x97\xaa\xe1\x3f\x6a\x4c\xdd\x3d\xb9\x60\x22\x0d\x00\xcd\x75\x38\x1a\x23\x3a\x19\x03\x69\x60\x3f\xdb\x33\xcf\x4d\x3a\x63\x0e\x35\x24\x49\x1a\xaa\xd8\x66\x7a\x0c\x7d\xb1\xe5\x45\xae\xea\x66\x7d\x38\x16\xd0\xbd\xc9\xcb\x16\x6c\x49\xd2\x08\x92\xa0\xe7\x6c\x77\xf9\x5e\x7b\x34\x0b\x02\xa7\x50\xd6\xed\x11\x87\x4a\xc1\xe4\x77\x33\x1a\x23\x9c\x02\x67\xd3\xbe\xd2\xfb\xe7\x91\x91\x25\x59\x16\x86\xcc\xe5\xd5\x06\xd4\x7a\xa3\xaf\xc0\x85\x40\xc0\xde\xe3\xe2\x8f\xfd\xe2\xf5\x76\xbd\x1b\xe0\x02\x25\x11\x59\x88\x7e\xe7\x72\xf3\xb2\xfa\xa3\x47\xa3\x49\x22\x04\x27\x36\x43\xb6\xfb\x69\xa6\xf5\xe3\xf2\xc7\xc8\x09\x94\x44\x80\x00\x4b\x7d\xa9\xf2\x76\x65\xea\xc5\x0a\xf1\xac\x0f\xd0\x34\x77\x2e\x05\x41\xe8\x7c\x53\x92\x24\x92\x84\x86\x4a\x51\x4a\x38\xb6\xd8\x09\xd8\x45\xe2\x5d\xc4\x3b\x3c\x81\x5c\x9c\x27\x22\x54\x8c\x45\xec\xda\xee\xe1\x99\xba\xfb\x56\xb1\x21\xeb\x3c\x98\x06\xed\xf1\x59\xca\x12\x8d\x1c\xcd\xa2\x46\xfe\x9e\x3e\x89\x22\x89\x4a\x43\x2c\x5f\x18\x43\xb7\x83\x02\x8e\xef\x55\x09\x93\xcf\xaa\x74\xa8\xd1\xfa\x9e\x67\xed\x12\x70\x81\xa0\x88\xc6\x06\xa2\xc3\x55\xac\x05\x33\xdd\xb3\xd5\xe1\x70\x2a\xf3\xd6\xaf\x7e\x2d\x79\x82\x20\x65\xa4\x99\x2d\xc0\x65\x7f\xdd\x61\xa5\x75\xe0\xf8\x57\x71\xff\xdd\x9e\x9c\x2d\xa3\x01\x49\xd1\x34\xfc\xf3\x94\xcb\x8f\x41\x26\x4c\xd2\x20\x06\xb4\x29\x48\x85\x91\xff\x09\x7b\x54\xa1\x9b\x07\xe6\xbb\x8d\x8e\x06\x2a\x86\x9e\xf3\x76\x94\x5d\x1e\xbd\x4d\x1a\xe8\xcc\xc2\x8b\x8d\x51\xaa\x0e\xe3\x0c\x9b\xa4\x44\x84\xe8\xca\x1d\x51\xdf\xc6\xd0\x25\xcd\xce\x03\x4a\xb9\xc4\x17\x73\x8f\x82\x27\x9d\x07\xec\xa7\x22\xa5\x52\xc4\x26\x3e\x44\x46\xae\xc9\x89\x20\xac\x74\xfa\x04\x82\xf2\x77\x2a\x46\x92\x46\x34\x72\xb4\xdc\xae\x94\x7c\xa9\x72\xd2\x0d\x83\xd0\x26\x7e\x76\x7d\x34\x3a\x19\x94\x12\x82\x21\xf4\xef\xb7\x9b\xd7\xdf\xfc\xdf\x62\x8c\x87\x16\x28\x18\x34\x68\x27\xb9\x04\x56\xb9\x33\x94\x95\xb2\x46\xc6\xb4\x6a\x96\x2c\xdc\x0e\xcd\xd2\x18\xe3\x22\x93\xe8\x5c\xf2\x16\xde\xaa\x31\x97\x8a\xa4\x19\x4f\x31\x58\x95\x55\x29\x79\x7b\xd3\x7d\x9e\xa1\x8e\xe3\xaf\xff\xeb\xae\xa1\x38\xa5\x0e\x30\xa2\x60\x88\x21\x72\x23\xc0\xe8\x82\xe2\x4d\x5b\xd6\xb3\x6b\x37\xad\x89\x32\x22\xc4\xc7\xd7\xa3\x7b\x4d\x3c\x0c\x58\xec\x50\x00\xf9\xb1\x80\x97\xaa\x3a\x3c\xf2\x89\x21\xa6\x3c\x0e\x70\xe5\xe5\xcd\x0b\x70\xb5\x29\xfd\xee\x49\xb9\x0e\x1d\xc7\xca\x72\xb5\x19\x25\x18\x24\x15\x21\x75\x84\x4c\x3f\x20\x37\xbe\xec\xa4\x85\x53\x52\xc1\x43\x66\x90\xda\xed\xe9\xf8\xcf\xdb\xc5\x6f\xb3\x38\xa3\x6b\x5d\x32\xb3\xa9\x6c\x49\x65\x46\x8d\x8c\x37\x3f\x35\x56\x75\xb5\x0f\xb5\xe6\x67\xa4\xd4\x86\x5e\xb0\xcd\x0f\xb0\x2a\xf8\xd1\xf7\x75\x4b\xaa\xa2\xd8\x75\x2e\xf7\x94\x7b\xee\x98\xce\x98\xdd\x6c\xf7\xb6\x1f\x7a\xdf\xed\xb8\xf5\x81\x5f\xe0\x23\x24\x85\x28\x41\x95\xc6\x86\x7f\x42\x34\x06\xd1\x8c\xf6\x70\x0a\x89\x30\x32\x50\xfc\x82\xc8\xcd\x8d\x10\x12\x71\x24\x5f\x8e\x27\xf2\x91\xe7\x98\xee\xb2\x1f\xe1\x91\x97\xe7\x21\x84\xda\xfb\x8b\x54\xb3\x58\x0e\x31\x7f\x8b\xb7\x1a\xa0\x17\x1a\x9d\x48\xca\x4a\xaa\x93\x34\x4e\x7c\x61\xc3\xd6\x03\xc6\x37\xa3\xd3\x04\x5b\x1b\xd1\x91\xb8\x34\x16\x3a\xe5\xce\x89\x7a\x81\xa6\xf3\x2f\xc6\xe5\xc5\x7e\x19\x86\x41\x9c\x32\xc3\x7f\xd0\x44\x83\x4c\x8d\x0c\x83\xd4\x40\x88\x9b\x23\x94\xed\x55\x75\x35\x37\x18\x28\xea\x0f\xa8\xca\x15\x04\x71\x37\x98\x7d\x93\x61\xa0\x33\x47\xd9\x8a\xbf\x98\xff\x69\x3e\xdd\xb5\xfe\x37\x19\x92\x30\x72\x54\x27\xeb\xa6\xe0\xa5\x32\x2a\x84\xdb\x96\x4f\xfa\x71\x64\x48\xb8\x02\xe8\xcb\x07\x1e\x17\x6f\xb7\x30\x37\x0a\x02\x0c\x10\x9f\x56\xbf\x6f\x96\x9b\xf5\x53\xff\xf7\x08\xbb\xd6\xab\xe3\xb8\x80\x25\x43\x4a\x53\x03\x98\x42\x1d\x9e\x01\x23\x9e\x0c\xa9\x4c\x68\x0f\xc2\xb1\x56\x61\x5c\xb7\x90\x61\x94\xc5\xc8\x2f\xcc\x8b\xa2\xb3\x2b\xbb\xf3\x71\xfa\xd5\x42\x46\x4d\x77\xb6\x0d\x17\x2f\x82\x36\x37\x8c\xc7\x28\x4f\xfa\xb0\xf9\x81\xe2\x9f\xeb\xe5\x0a\x9b\xc1\x77\xfb\xe7\xd5\xcb\x72\xf5\xb4\x5b\xdc\x3b\xb7\x27\x64\x3c\x0b\xfa\x46\x29\x74\x3b\xae\x6d\x1c\xee\x0c\xe0\x98\x80\xc3\x54\xec\xda\x64\x65\x88\xbb\x5c\x62\xe9\x6b\x14\x14\xd0\x1a\x15\x81\xd1\x46\x18\x26\x71\x88\x95\xf6\xd5\x6e\x39\xd8\xd9\xc2\x24\x89\xd0\xdf\xf0\x29\xe0\xd9\xc2\xb4\x0c\x53\x6a\x5a\x03\x9a\xd3\x61\x81\x8e\x92\xcd\xd8\xe4\xc2\x5d\x29\x23\x24\x31\x69\x9a\xce\xc8\x28\x8b\x25\xf1\x9f\x22\x63\x21\x56\x43\x17\xdf\x17\xeb\x87\xc5\xcd\xc3\x6a\x7f\xb3\x79\x7a\xdd\xd2\xfd\xf6\xf5\xf9\xf9\xe1\x5f\x7e\x98\x0a\x10\x7a\xe1\x57\x64\x69\x68\xf7\xaf\x43\xa3\x64\x98\x01\xd3\xd0\x0b\xce\x1f\x2d\x79\x8f\x67\x1f\xf5\xef\x80\x13\xc9\x6d\x5d\x72\xed\x9e\x93\xce\x85\xea\x6e\x7c\x6a\xaa\x6f\xd2\x8b\xcf\x19\x29\xc8\x4b\xb0\xa1\x3b\x21\x8b\xd0\x56\x19\x51\x09\xf4\x42\x47\x02\xa9\xa8\xd8\x1b\xc7\xce\x61\x5e\x39\xbc\xd2\xf8\x5d\x73\x09\x8e\xe4\x6c\x71\x3c\x4e\x0e\xca\x30\xc3\x20\x6b\xb7\xbc\x75\xe9\x9a\x50\x4a\xad\x86\x2f\xcd\x70\xfd\x34\x7b\x5d\x57\x07\x2f\x85\x79\xe5\x96\x15\xe1\x18\x0e\x1a\x3d\xc1\x09\x71\xd4\xbc\x49\x51\x54\x60\xbb\xd2\x63\x5e\xe6\x8f\xb0\xae\xeb\xef\xd0\xdc\xe6\x9f\xe3\x4f\x34\x4d\x50\xcc\x50\x4b\x0f\x2c\x71\xa8\x22\x8a\xf5\x01\xdf\xdc\x91\x0f\xad\xf0\x5f\x52\x5d\xcc\x70\x9a\xc8\x50\xc5\x06\xdc\xbe\x1f\xa2\x29\x16\x45\xb1\xa8\xdf\xae\x92\xbe\x4e\x1f\x95\xc7\x08\xe7\x59\xcb\xca\x5a\x9d\xed\x04\x5b\x20\x43\x90\x42\x98\xa5\x27\x4e\x6f\xfb\x2f\x27\xfd\x21\x43\xd0\x71\x6a\x7b\x83\x9f\xeb\xea\x90\x17\xde\x0b\x0f\x75\xcc\x54\xff\xb8\xea\xe6\xfc\xd8\x1f\x4a\x18\xb6\xbf\x2c\x14\x3f\x0c\xcd\x7e\x14\x70\x4d\xd0\x95\x2e\xd1\x84\xed\x4c\xf3\xcc\xf8\x66\x22\x12\x45\x46\x67\x07\x4d\xf8\x28\xfe\x9f\x0c\x64\x69\xe0\x91\x22\x4d\xb7\xb9\xfe\xc5\x4b\x76\xe7\x65\x5a\xa5\x13\x08\xe8\x85\xcc\xaf\x8c\x08\x18\x11\xb6\x75\xa9\xaa\x7f\x80\xb3\xb5\x11\x0d\xb4\x9a\x20\xce\xaa\x53\xdb\x7d\x97\x9b\x09\x89\xa5\x8c\x68\x14\x3a\xf5\xee\x2d\x2f\x78\x7d\x9e\x9f\x60\xb3\xd3\x3a\x8a\xac\x42\x01\x57\x6a\x2c\x1e\x7e\x01\xac\x9f\x7f\xcc\x48\xd8\xfa\x19\x7e\x20\x43\x19\xd2\xdd\xe6\xd5\x79\x33\x3e\x9d\x45\x12\xc1\x58\xab\xdb\x97\xcd\xb3\x7b\x78\x26\x32\x64\xcd\x90\x03\x85\x87\x25\x32\x91\xb7\x30\xcc\x9f\x46\x4c\x18\x0c\x9b\x38\x9d\x9f\x07\xc8\x41\x77\x54\x05\xa9\x35\x0f\x58\xad\x9e\x6b\x15\x94\x11\x03\x9a\xd8\x64\x0e\x6e\x89\x76\xd4\xcd\x79\x48\xca\x3c\x5e\x40\xc4\x9e\x1a\x07\x19\x5a\x31\xc3\xd0\xf2\x52\x15\x70\x01\x72\x1e\xff\x56\xcc\x93\xd8\x76\x8c\xae\x15\xf0\x66\x9b\x97\x12\x1e\x78\x63\xc1\xe3\x93\x3b\x8b\x65\x8a\xef\x66\xf7\x55\xad\x7e\xbe\x9c\x9c\xd2\x9b\x8c\x62\x95\x21\x92\xa7\x3c\x1d\x50\x5f\xc1\xf4\x04\x7b\xe7\x33\x4a\x44\x88\x19\x5d\x97\xd5\x34\x68\x32\x57\x8d\x93\x51\x02\x0c\x23\x1d\x2b\x93\xb8\x28\x15\x92\xb7\xfd\xc5\x84\xf9\xb5\x51\x19\x46\x21\x51\x9a\xc9\x4c\x8c\xc4\x59\x8f\xd3\x9c\x4e\x94\x85\x06\xe1\xc0\x0d\xaf\xd3\x79\x58\xe3\x94\x11\x0f\x83\x01\x0d\xcb\xb2\x3a\x1c\xaa\x72\x08\x69\x9e\x96\x22\x22\x11\x12\x82\xbe\xf8\x7b\x5e\x2b\x83\xfd\xf3\x04\x9f\x32\x12\x1c\xd0\xf0\xe3\x6e\x62\x01\x4d\xe3\xdb\x11\x32\x88\xa1\xe7\x2f\xf3\x11\xda\x78\x94\x8c\x0c\x38\xd8\x74\x49\x0f\xb5\x2b\x26\x5f\x5a\x51\x89\x01\xe6\x84\xbf\x60\xcc\xe1\x75\x59\x7d\x94\x11\x48\xc0\x8c\x34\x6e\xfa\xfb\x70\x7f\xbb\xf8\xd7\xd6\x3d\x05\x80\xf1\xae\xaa\x4f\xa8\x79\x51\xec\xf8\x07\x94\x03\x1c\x86\x8c\x74\x1c\x4a\x53\x72\x3a\xee\x0f\xdc\x76\xd0\x48\x16\x50\x93\x14\x83\xf6\x7d\x57\xdd\x58\x49\x02\x71\xea\x93\x16\x2c\xe0\x1a\xad\x10\x37\xe0\x0e\xf7\x67\xa2\x05\xf6\x6d\x6f\xb1\x96\xe9\xfc\x62\x7f\x16\x8d\x0d\x9b\x59\xeb\x58\x94\x8b\xb3\xe1\x48\xed\x47\x48\x86\x8a\x45\x88\x2e\x30\x60\x24\x4f\x43\x6a\x87\x84\x61\x88\xb8\xf5\xba\x73\x3d\x25\x92\xab\x1a\xe1\x7d\xe8\x73\xec\x2c\xcc\x02\xac\xd7\xe9\xce\x53\xb0\xa5\xf3\x31\xf7\x9b\x64\x51\x90\xa1\x34\xe8\xf3\xe6\x6e\xf3\xb8\x71\x67\x46\xc4\x28\x15\x7e\xe6\xf0\x15\xd2\xfe\xaf\x20\x5c\xaf\x6f\xe7\xae\x9c\x07\x99\x1f\x16\x51\x9e\x18\x7a\xe8\x47\xfe\x33\x3f\x9c\x0e\xf7\x15\x2f\x5e\x80\xcb\xf7\xfe\xc1\x22\x2a\x91\x98\x6c\xf1\xb0\x1e\xee\x3d\x2c\x4a\x0c\xd7\x46\xe3\xa5\xae\xe6\xf2\x0f\x2c\x52\x19\x66\x6c\x8b\xaa\x7c\xb3\x4e\xc8\x64\x04\x63\x01\x2e\x0f\x93\xda\x19\xcc\x65\xc6\x58\x12\xf7\x22\x36\x9e\xd4\x62\xd6\xbc\xb3\x38\x36\xa4\x48\x6d\x75\x54\xd5\x57\x89\x4b\xbd\x79\xaf\x4e\x57\xbc\x1c\x96\x04\xdc\x79\x7e\x3d\x03\xce\x6f\x93\x7e\x9e\xde\x1d\x61\x49\x42\x6d\xde\xf3\x03\xca\x9e\x0f\x72\xd4\xe0\x25\x59\x22\x89\x69\xbf\xac\x8e\x67\x4c\xe3\xff\xe5\x3a\x60\x89\x0c\x91\x12\xa7\x84\x9f\xed\xba\x3c\x9e\xda\xe7\xba\xd2\xb9\x9f\x10\x89\x62\x18\xad\xc1\xb1\x92\xef\x9d\x05\x75\x07\xd2\x30\x0d\x0c\x8d\xdb\x49\x14\x70\xae\x4e\x35\xf3\x87\x58\x42\x2c\x02\x06\xea\xce\xe7\x7c\x84\x75\xd3\x9c\x5c\x57\x7a\x5d\x7d\x29\x6d\x04\x7e\x67\xe1\x01\x7f\x3b\xaf\xf0\xf7\xce\x1a\xbf\xf7\x2c\x8c\x75\x60\x9b\xdc\x2c\xcf\xee\x00\x2f\x2e\x59\x16\x87\xe8\x85\x3c\xe5\x25\x3c\xec\x6e\x2d\xa3\x89\x7b\xb2\x2c\x11\xae\xa3\x76\x51\xe6\x07\x5e\x0c\x21\x84\x92\x71\x4a\xb0\x8d\x69\xbd\xdc\xec\x0d\xff\x96\x3b\x91\xf3\x08\x13\xdb\x05\x6f\x0c\x2f\xc9\x5e\xd3\x2e\xb6\xdb\xdb\xbb\xf3\xe3\xa4\x70\x20\xd5\x4d\x8d\x14\x1d\xa3\xd4\x15\x13\x41\x84\x10\x84\x4f\x93\x6d\xcf\xab\xf2\x99\x37\x53\x9e\xb4\x6e\x58\x1c\x53\x47\x17\xa6\xe0\xe7\xcd\x79\xeb\xd2\x6c\xfd\xab\x10\xa9\x61\xcb\xc3\x64\x3f\xf2\x9b\x0d\x44\xe7\x26\x43\x65\x84\xbc\xb8\x2f\x5c\x8d\xde\x87\x90\x1c\x69\x20\x5f\xcb\x5c\x56\x75\x79\xc9\xc4\x2d\x99\xd0\x59\x4c\x1c\x62\xc5\xf6\x8e\x62\x30\xe2\xae\x21\x43\x08\xe2\xbe\x24\x8f\x02\xf4\xd8\x62\x7c\x25\x1b\xc4\x64\x16\x27\x7d\xb5\xd9\x74\x67\x98\x9e\x2b\x50\x97\xec\x31\x92\x29\x92\x46\x96\xc8\x64\x7d\x3b\x3d\x96\x09\x8c\xd4\x0e\xae\x7d\x6d\xdb\xc2\xf4\x3d\x29\x1d\x62\xd1\x77\xf5\xf3\x08\x75\x8e\x85\x8d\xc2\xe2\x51\xff\xee\xce\x3d\xeb\xcb\x33\xa5\x35\x3a\xd6\x0f\x55\xdb\x56\xce\xef\xfa\x75\x21\x95\x69\x09\x2a\x72\xaf\xf3\x85\x7f\x78\x6b\xa5\x21\xa0\x96\x3d\x62\x04\xcb\x1e\x55\x92\xfd\xd8\x30\xca\x86\x89\x8f\xf2\xbc\x6d\xf9\x07\x0c\xab\xc4\xbf\x40\xa6\xb9\x70\x34\x0e\xa8\xc2\xbc\x0f\x1a\x56\x7c\xf5\xd8\xfc\x71\x2c\x72\xbf\x55\xc6\x41\x98\x28\x6b\xa8\x05\xc7\xb4\xc7\xdf\xe8\x5d\x18\xdf\x6f\x1c\x44\x0c\x9d\x94\x23\x92\xf6\xa2\x2d\x99\x37\xab\x71\xc0\x18\xfa\x1f\x37\x9b\xd7\xa7\xdd\xbf\xc6\x8b\x30\x26\x24\x8e\x1c\x71\xef\x79\x7b\x84\xfa\xe0\x8f\x44\x2c\x36\x8d\x03\x5d\x54\xb5\xac\xc7\x1d\x59\x32\xa6\xd4\xf0\x95\x35\xb6\x76\xd6\x0c\x56\xca\x95\x78\x6d\xe6\x75\x51\xc5\x71\x29\xa0\x73\xd4\x39\x94\x0f\xf9\x65\xd2\x35\x0e\x79\x4c\x6d\xfd\xf9\x2e\x2f\x70\xcc\x37\x70\xdd\x02\x32\x0e\x75\xe0\x62\xf1\x2d\x6f\x37\x5f\x17\xe7\x47\x71\x88\x29\x41\x28\x4d\x99\xa5\xdf\x44\xe2\x28\x61\x56\x6d\x08\xf1\x03\x8d\xad\xbe\xdd\x3a\x99\xc3\xc9\x95\x98\xa5\x40\x3f\x35\x60\x71\x85\xe3\xe3\x31\xe1\x18\xf9\x1f\x0c\x4b\xf4\xdd\x2c\xe9\xbb\x8c\xe3\x38\x55\xc2\xca\xce\xec\x79\x59\x95\xe7\x43\x75\x6a\xf6\x53\xc4\x8b\x1b\x9d\x28\x07\xa6\x33\x06\x3a\x87\x66\x18\x8b\xc4\x71\xa6\x70\x05\xac\x4a\x55\xd5\x43\x6b\x14\xa7\x99\x0a\xed\xa9\x37\xa8\xb5\x61\xbb\xfa\x7b\x68\x46\x9c\x85\x92\x27\x6e\xf9\xf8\x84\x71\xf7\x9e\x88\x1f\xc2\x29\x92\xf7\xb6\xc0\xeb\xdb\xea\x6b\x62\x0a\xe3\x8c\x73\xdc\x2f\xb7\x27\xc5\xcb\xfb\xca\xc8\xd4\xf4\x9d\x9b\x7f\x6b\xe5\xc7\x82\x48\x61\x77\xff\x39\xdf\xf6\xca\x32\x10\x89\xc6\xb8\xde\xd8\x4f\xfb\xf1\xbc\x9a\xf0\x6b\xa3\x1c\x11\xe3\x95\xd3\x33\x81\x4d\xfa\x65\xd5\xc2\x08\x3a\x2e\x63\x21\x8c\xa2\x02\xbe\x96\x21\xd2\x6a\x5d\x7a\xe5\x50\x19\x0b\x8b\xfd\x36\x20\x62\xb4\xbe\xf5\x4d\x4f\x1b\x34\x7d\x46\x6d\x00\x03\x9d\x63\x71\x83\x10\xaf\xb5\x9f\xc4\x32\x90\xb8\x4c\xb1\xdf\xd9\xff\x31\x04\x88\x7c\x2e\x7b\x67\x59\xc8\x27\xaf\x5f\x29\xc2\xa8\xc7\xd6\xbc\x54\x45\x71\x7b\x51\x9a\x8a\xbb\x50\x9f\x7a\x42\x51\x04\x68\x71\x0c\x69\x6e\xce\x28\x4e\xda\x56\xf5\x1d\x5c\x9c\x94\x49\xec\xc8\xde\x3f\xae\x9f\xd6\x8f\xaf\x8f\xfb\xdd\xe2\xe5\xbe\x37\x1e\x3a\xcc\x10\x3f\xb2\xab\xf3\xb7\x37\xa8\x97\x55\x55\x74\x8e\x9e\x3f\xac\x0d\xf4\xe6\x71\xb1\x7e\xc2\x1e\xf4\xa5\xeb\x3e\x90\x49\x10\x65\x98\xaa\xe4\x65\x79\xe2\x85\x91\x3d\xeb\xb6\x11\x0f\xd3\x96\x49\x10\x73\x8c\xc4\xbf\xe7\xb2\x1d\x09\xe1\xcb\x24\xe0\x22\x70\xdd\x80\xdd\xe7\x71\x25\xe5\x67\xa8\x6f\xf9\x79\xfe\x5b\x27\x24\x4d\x32\xd2\xf3\x84\x9c\x8a\x4b\xa4\xc6\xaf\x6d\x6e\x42\x94\x40\x16\xbf\xaf\xaa\x2e\xd4\xf2\x74\x34\xc5\x81\xce\x51\x70\xce\x7d\x42\x03\x86\x98\xa5\xc5\x5b\x9d\x23\x7c\xd3\x32\xf8\xf7\xeb\xad\xfb\x0e\x06\x53\xc2\xdb\x9e\x92\xd3\x1e\x0b\x03\x89\x74\x91\xb9\x21\x34\xdd\xe6\xe5\x5b\x01\xb3\xdc\x71\x32\x09\x21\x42\xb2\x86\xe6\x8b\x1f\x47\x6f\x27\x62\x11\xce\x24\x43\x46\x6e\xbb\xfb\x95\x3f\x1a\xc7\x0c\xdc\xbc\x7e\x00\xae\xa0\x46\xfe\x1e\x17\x14\x25\x4c\x53\x63\x9b\xfa\x76\xaf\x79\x20\xb6\x4c\xe2\x00\x90\x8e\xe1\x9d\xd7\x6a\xc9\x8f\xb8\xe4\x07\xd1\x4c\x12\x2b\x89\xfd\xb0\xbc\x0b\x43\xee\xaa\x7a\x09\x75\x9b\xeb\x5c\xce\x15\x2c\xe6\xc0\x99\x49\xac\xb9\x70\x64\xa4\xc7\xaa\x1d\x56\xad\x93\x04\x98\xa5\xef\x41\xb6\x11\xb3\x09\x0d\x05\x3b\xec\xb8\x34\x11\x82\x0f\xac\xe7\x0e\x0e\x47\xab\x02\xed\x2e\x95\x65\x1a\x7b\x31\x3a\x13\xd9\xdd\x63\x85\x9f\x6e\x02\x97\x4a\x32\x61\x92\xe7\x36\x4c\xbf\xaf\xab\xd3\x24\xf1\x9b\x64\x92\x82\xa5\xb4\x44\x23\x36\xcd\x8d\x5e\xf9\xd7\x9d\xad\x82\x38\x1b\xf4\x41\x8f\x90\x3f\x09\x17\x80\x09\xa7\xcd\xf3\xea\x69\xbb\x79\x7d\x59\xae\xac\xca\xb3\x1f\x20\x09\x3e\x68\x01\xa5\x1a\xc2\x62\x12\x91\x9a\x64\x94\xe4\x45\xf1\x90\x8b\xed\x34\x8b\x97\x08\xa1\xd0\x8a\xbd\xf3\x06\xbb\x16\x3b\x8f\x6f\x2c\x7b\x27\x13\x29\x34\xf7\x50\x8a\x51\x57\x9a\x4c\x94\xce\x7a\x12\xbd\x91\x16\xf3\x20\x33\x93\x00\x4b\x8c\x07\x8e\x84\x24\xcf\x50\xe7\x95\x9f\x95\x90\x1a\x0d\x30\x47\xa0\x7f\x53\x55\x1f\xd3\x6d\x3c\xd1\x32\x45\x21\x38\xc1\xcb\x0f\xa8\x0f\xd8\x5d\xfa\x02\xff\xb1\xd7\x48\x83\x20\x64\xae\x23\xb4\x1a\xeb\xdc\xca\x34\x20\x0a\xb1\x70\x8f\xe7\x7f\x3d\x2c\x67\x43\xc0\xd3\x05\x34\x29\x0d\x38\x07\x23\xce\x5f\xb4\x43\xca\x79\x99\x12\xa0\x48\xf2\x75\xcb\x6b\x28\xbf\x9d\xdc\x7e\x90\xd2\x38\xf3\xcc\x12\x76\xfa\x0c\xc4\xce\x65\x1a\x32\xb3\xab\x6c\xa1\x6c\xfa\x3f\xc6\x19\x36\xfc\x1d\xac\xcb\xb9\x29\x5d\x1c\x36\x7e\x86\x88\x51\x4c\xec\xd4\x16\xfb\xfc\x9b\xff\xbb\xa1\x05\x31\xa2\x66\x67\xa8\x6f\xa6\x85\x4b\x37\x30\x56\xd8\x94\xb3\xf1\x46\x3a\x8d\x20\xc1\xc2\x3f\xc6\x18\xca\xc2\x0c\x5f\xb7\xb7\xee\x38\x23\xc6\xd4\xe6\xad\xc4\x1a\x8f\xff\x3b\x8b\x89\x97\xb5\x79\xa9\xaa\xc3\xc2\x15\xa7\x26\x8d\xaa\xce\xd5\x4b\x99\xc8\x10\x1e\xf8\x95\x97\xaa\xfa\x22\x63\x8f\x28\x8d\xc1\x04\xa1\x9d\x43\xfc\x5a\xe6\x63\x82\x65\xd9\x85\x65\xb8\x5f\x38\xb2\x89\x7e\xff\x1a\xf7\x38\xdb\xe1\x29\x63\x98\xc9\x12\xd8\xc0\x74\xc8\xcb\x1e\x1d\x38\x7e\x23\x29\x18\x50\x4c\x17\x5c\x2e\x5e\xdc\xcd\xf0\x40\xc7\xcc\x6f\x15\xfb\x37\x7e\x80\xbd\x9a\x30\x1a\xc9\x54\x04\xb6\x1c\x52\x00\xf7\x45\xa7\xc5\x0c\xc7\xf6\xac\x5f\x9e\x0a\x99\xa0\xf8\x8d\x1e\x96\x7c\x47\x13\x3e\x45\x54\xb2\x31\x27\xb6\xe8\xd3\x6d\xd2\x4a\xf0\xcb\x76\x95\x69\x06\x60\x10\x83\xa7\x8a\x04\xf8\xd9\x9b\xbc\x8b\xa7\xb6\x27\x31\x25\xd7\x97\xa9\xa2\x71\x66\x9a\x21\x44\xf5\x13\x71\x96\xe3\x3b\x51\x34\xe6\xca\xbf\x91\xf5\x72\xd3\x23\x1d\xaf\x60\xb6\x52\x80\xc8\x08\x2b\x57\x85\x32\x09\x56\xe7\x4f\xa6\x9a\x72\xb0\x19\x87\xd5\xcf\x63\x91\xcb\xbc\x1d\x31\x34\x18\xf8\x7d\x1c\x79\x70\x66\xaa\x85\x88\x4c\xfd\x86\xb7\xef\xb7\xbc\xe5\x7b\x4d\xdc\xa6\x9b\x05\xa1\xc9\xa8\x71\xa5\x96\xef\xa7\xf2\x83\xed\x2a\xcf\x29\xef\xc7\x44\x80\xb6\xf5\x8b\x7f\xc2\x92\x1f\x43\xff\x77\xab\x89\x58\x5b\xd2\x5e\x50\x08\x95\x9e\x42\xef\x33\x92\xc6\xa9\xb6\x52\x02\xbb\x6a\x7a\x50\xc4\xb8\x00\x4d\xb9\xc7\xb9\x90\x19\x01\x8e\x52\xe3\xcf\xdd\x9a\x34\x82\x58\xce\x1d\x1d\x4e\xa4\x8c\x0a\xa3\xdc\x88\x5e\x5e\x79\xbe\x90\xd2\x74\x4b\x28\x0b\x75\x82\xa0\x1f\x0d\xf0\x8c\xf5\xdb\xce\xfe\x8d\x50\x34\x76\x60\x24\x22\x64\xd4\x50\xd5\x33\x3f\x5f\x2b\x1a\xb9\xb1\x10\x39\xb3\x69\xb2\xb3\xed\xc4\x76\x66\x8c\x98\x9c\xfe\x3f\x4e\x4d\x9b\xeb\x33\x32\x21\x75\xdb\xc3\x8f\xbc\x2d\x9d\x5e\x59\xea\xc7\x1a\x19\x2e\x74\x2f\x36\x9f\x50\xb7\xef\x75\xf5\xe5\x76\xda\x8c\xc5\x11\xf2\x81\x8a\xd3\x05\xbe\xec\x5a\x09\x60\xfc\x64\x2c\x0b\xd0\x4e\xec\xb7\xbb\xc5\xcb\x6e\xec\x90\x66\x31\x8b\x30\x7b\x7a\x57\x79\x3e\xbd\x61\x75\xc1\x8e\x4a\x78\xe4\x54\xa2\xd1\x7b\x7c\x2d\xf1\x65\xfa\x90\x6f\x84\x98\xc9\x12\x95\xf5\x79\xa3\x89\x59\xca\x12\x08\xe3\xd8\xc1\x1a\x0c\x26\xd4\x1e\x49\x63\x82\x5e\x94\xc9\xa1\x3e\xc2\x2d\x9f\x4e\x9a\x34\x15\xa6\xb1\xab\x28\xaa\xaf\x1f\x55\xfd\x01\xf5\xae\xf2\x81\xc6\x05\x54\x64\xf2\x1e\x32\xca\x79\x60\x5a\x41\x7a\x6b\x9d\x65\x69\x86\x19\xc8\x2d\xff\x04\xd4\xb3\xb1\x7f\xe7\x84\x39\x20\x39\xe6\x0b\xfa\xbf\x67\xd8\x0d\x97\x63\xf4\xfe\x05\xca\x00\xf0\xc7\x3f\xc5\x89\x42\xc2\xb7\x2d\xd7\xe0\x0a\xd5\xcd\xee\x65\x35\xa4\x2c\x96\x19\x97\x19\x4a\x67\xe6\xb2\x2a\xf3\xff\x74\xc6\x6c\x53\xbe\x55\x9e\x29\x43\x66\x1c\x0c\x65\x4d\x67\x93\x27\xac\xf1\xe3\xe9\x26\x62\x15\x3b\xdd\x91\xfc\x00\xbe\x50\x85\xd8\xf8\xc9\xbd\x09\x91\xe0\x6b\x2e\xab\xdf\x07\x3f\x25\x63\xc0\x82\xcc\xfe\x70\x76\x9e\xf4\xd0\x95\xca\x54\x4c\x99\x70\x0b\x2e\x2f\x5b\x9e\x97\x46\x9b\xc4\xe7\x05\x32\x05\x80\xb1\x8d\x71\x48\x9c\x56\xa5\xea\xa6\xfd\x2d\x48\x93\xe7\xec\x87\x6a\xdd\xc3\xc0\xa1\x28\x66\xb0\x81\x19\x24\x1c\xb3\xe1\xbd\xfc\xb8\xd9\x4f\x7f\xb9\x49\x64\x90\x09\xee\x27\x09\xa2\x3d\xdd\xaf\x82\xc8\x70\xf7\xd9\x89\xaa\x54\xa4\xff\xab\x21\x99\x71\x73\xdb\xa1\xd8\x86\xa5\x9a\x4c\x07\x31\x02\xf5\x5c\xc9\xfd\x91\x77\x41\xd8\xc5\x8e\x32\xb4\x51\x3c\xb0\x98\x88\xdd\x57\xf5\x8c\xf2\x32\x57\x19\xba\x47\x2b\x84\xd3\x44\x61\xb8\xd1\x40\xfb\x7d\xff\x12\x8d\x5f\x0a\x8f\x22\x11\x66\x3e\xe5\xbf\x29\xe1\x92\x7d\x56\x72\xa6\x09\x7a\xe7\xb6\xb8\xdf\xb9\x86\xf6\x49\x78\x1c\x04\x68\x78\xf3\xe6\x91\x1f\x8f\x13\xbb\xca\xe3\x80\xa5\xa6\x24\x55\x6e\xc1\x73\xaf\xf4\x7c\x1c\x92\xc7\x09\xa0\xed\xdb\xdb\x26\x70\x68\x3a\x13\xd0\xfe\x36\x53\x15\xe0\xb1\x0e\xb1\x89\xde\x25\x69\xfa\xa6\x5e\x94\xb9\xe8\xee\x39\x73\xb7\x9c\x04\xa1\x32\xbd\x04\x6f\xdb\x9e\x9e\xbf\x0b\x6e\x67\x3f\x33\x4f\x42\xaf\x65\xf1\x78\xde\xb6\x95\x97\xc3\x96\x3c\x11\xd2\x25\xb7\x7e\x54\x7d\x98\xc6\xd3\x40\x60\xcf\x24\xbe\x31\x38\x54\xe5\x0b\x2f\x3f\x0c\xb0\xeb\xd7\xa6\x83\x67\x14\x84\xa1\x2f\xb3\x8c\xa1\x0f\xf9\x7f\x4e\x36\x75\xee\xae\x9e\xb1\x88\x58\x42\x92\xea\x13\xea\x6d\xfe\x56\x0e\xc2\x99\xd1\x7b\xc9\xb4\xc2\xc5\x04\x2a\x6f\x2d\x4b\xd6\x8c\x67\x3d\x8c\xaa\xfb\xed\x82\x73\x16\xd3\x60\xc0\x5b\xf3\x03\xe0\x43\x0d\x42\xf8\x81\x53\xc7\xb9\x00\x35\x60\x90\xba\x05\x50\xbd\x3e\xf0\xe8\x96\x84\xce\x42\xed\x93\x1d\x4d\x4f\x64\x23\xb9\x8c\x19\xb5\xf3\x11\xd1\xfe\x26\xdd\x32\xff\x55\x64\x9c\x21\x0e\x3c\x2f\xdf\xa1\xce\x5b\x50\xcf\xa7\xfa\x0a\x2a\x8f\x4b\x48\x02\xbb\x4d\x18\xda\x96\xee\x16\x9f\x79\xae\x5e\xa6\x82\x8d\x92\x4b\x4d\x32\x3e\xf0\xfc\x50\x2c\x17\x5b\xa0\x26\x03\x81\x4a\x61\x1d\x7b\xcb\x95\xf9\x5c\x77\xbe\xd9\xf8\xa7\x01\x82\xd8\x56\x0b\x30\x7e\xb8\xcd\x1b\x71\xaa\x1b\xcc\xa7\xcc\x36\xa7\x71\x00\x4e\x6c\xe3\x0a\x2a\x2c\xba\x97\xa3\xc3\x8c\xf8\xdc\xc0\x22\xaf\x6f\xeb\x6a\x94\x5a\xe0\x9a\x47\xc8\x76\xb4\xe5\x3f\xab\xc9\x01\x70\xcc\xa3\xcb\xaa\x0b\x02\x4d\xc1\xf5\x7e\x4a\x56\x29\xb9\x06\xc0\xf4\xc7\x47\x5e\x14\x0e\x15\x61\x0e\x89\x80\x18\xf1\x8e\x86\x17\x70\xa1\x11\x2e\x45\x10\x52\x69\x3b\x12\x9f\x2a\x05\x26\xfe\x1e\x7e\x77\x11\x44\x0c\x6d\x62\x17\x87\x2e\x11\xc9\x6c\xe5\x04\xc2\xd0\x40\x9a\xed\x38\x42\x8d\x50\x6c\xde\x6c\x2b\xdd\x4a\x7e\xdc\x94\xfe\x90\x0c\x10\x5d\xb9\x7c\xaf\xbe\x06\xa9\x0c\x41\x93\x14\xe1\xfa\x9d\x3f\xb1\x10\x63\xc9\xde\x91\xc5\x13\x21\x11\x08\xb7\xce\x1b\x4b\x4a\xe4\xfe\xce\x54\x10\x7b\x3d\x23\x17\xbe\x98\xb8\xc1\x42\x4b\x46\x6f\x4a\x84\x71\x10\x1b\xfc\x91\xcd\xa4\x3e\xe6\x83\xa0\x5b\x84\x5a\x23\xdb\x99\xf1\x30\x9c\xf7\xe2\x5e\xe9\xb5\x02\xe1\xf8\x27\xa2\x18\x1c\xd2\xf5\x47\x55\x37\xed\x92\x37\xc8\xa0\x6b\x74\xfd\x27\xf7\x13\x25\x89\xcd\x1c\x7d\x40\x39\x92\xff\x91\x22\x4a\x8d\x18\xc9\x48\x17\xbe\x4f\x6f\x39\x0f\x56\xb0\x2c\x0c\xb8\x49\x7e\x21\xdb\xc6\x0c\xbf\xa2\x14\x31\xd7\x9e\x3f\x61\xf1\x09\xdd\x07\x5c\x2f\x37\x88\xa5\xfc\x1d\xce\x33\x9b\xab\x48\xc0\x30\x4c\xb6\x60\xf1\x58\x8d\x95\x04\x72\x97\x4c\x74\xea\xc4\x52\xdc\x4a\x42\x54\x93\xc7\x23\xe4\x55\xf9\x8d\x37\xef\x9d\x39\xbf\xab\x6a\xb7\xc1\x88\x94\x18\xf2\x5e\xdb\x0a\xe2\x5d\x73\x87\xad\x70\xe3\x32\x66\xe0\xea\xc7\x53\xf3\x7e\xa5\x76\x20\x32\x46\x1d\x26\xe8\x26\x57\x2a\x2f\xdf\x2e\x88\xee\xa4\xc8\x54\xc4\xfa\xb6\x0a\x63\x4a\x36\xba\x97\x3e\x30\xa9\xd2\xfa\x4a\x21\x50\xf0\x20\x44\x62\x88\xc7\xf5\xd3\x6a\xe1\x6e\x8e\xcb\x18\xeb\x07\x5f\x79\x89\xf6\x63\x12\x04\x0b\xae\xb2\xc4\xba\x43\xab\x52\xad\x65\xe5\x34\x2e\xc7\xc3\x24\xa1\xb8\x0f\x1f\xf6\xdb\x47\x17\x2a\x0b\x49\x24\x2e\xe7\x5b\x23\xb8\xf3\xf7\xd2\xf6\x42\xa6\x11\x37\x6d\xe3\x79\xd9\x60\xf1\x4a\x3d\x7e\xf8\x97\xa9\x78\xe0\xd4\x2f\x7c\x15\x61\xed\xba\xf4\x27\xef\x0b\x12\xa9\x2d\x43\xeb\xba\x6c\x4e\xc8\xcb\x60\x73\xae\x57\xb3\xbb\xb3\x8a\x2a\xf6\x7a\x9a\xc4\x58\x4a\x79\xaa\xea\x83\x05\xb3\xa7\xee\x10\x8f\x5c\x98\xb9\xed\xac\xd7\xe5\xec\xd6\x10\x2a\xe6\x32\x02\x56\x97\x7b\x92\xe2\x95\x81\x94\xe8\x4d\x5f\x04\x04\x32\x00\xe3\x96\xf9\x8a\xda\x5d\x55\xf7\x29\xd5\xd1\x0b\x94\x44\x2b\xdc\x6e\xba\x68\xbc\xe8\x8e\xbb\x64\x90\xa4\x61\x12\x06\x43\x14\x88\x9c\xa4\x91\x24\x4d\x32\x69\x17\xfd\x37\x5e\x74\x86\xac\xf7\x7b\x65\x18\x1a\x29\x77\x33\xff\x3c\x4e\x97\x17\xb3\x3b\x89\x8c\x28\x18\x5d\x76\x5e\xab\x66\x2f\x8a\x13\xec\x71\xf3\x70\x77\x13\x85\x99\xec\x69\x7d\x6c\x63\xda\x7d\x55\xa1\xdb\x64\x9d\xea\xf9\xdd\x57\x32\x1a\xe2\xac\xbc\x2b\x38\x26\x7e\x3b\xff\x7e\x32\x22\xf4\xc4\xc8\x8f\x03\x09\x79\x7b\x34\x0e\x08\x75\x8d\x7b\xa6\xd3\xc1\x19\x18\x19\x93\xd0\x00\x07\xdf\x41\x7e\x4c\x2c\xe6\xb4\x1d\x5d\xc6\xb1\x40\x56\x6a\xae\xd4\x0b\x18\x4e\xda\xe6\x3d\x3f\xde\xe4\x08\xd7\xf8\x91\x97\x50\x9f\xfd\x7b\xba\x88\xb5\xc7\x74\x02\xfe\x92\xd2\xf1\xb2\x58\x52\xfc\xe9\xf7\x8d\x13\x53\xf1\xfc\xf2\xc4\xd4\xc6\xa0\x79\x47\x46\xc6\x90\x70\xe5\x7d\x9c\x8b\x46\x4f\x99\x10\x53\x15\xb7\xda\x85\xcd\xa2\x54\x77\x96\x5e\xe3\xca\x0b\x4f\x62\x8e\xe8\xf3\xce\x91\xec\x83\x29\x99\xe8\x18\xc5\x1f\x3a\x47\x73\x92\x5b\x97\x29\x31\x53\xc9\x76\x8c\x2e\xcb\xb6\x36\xd1\x33\x8a\x97\xbd\x96\x47\x8e\xb0\x86\xe1\x02\x24\x43\xff\x4f\xa6\x2c\xc3\xe7\xfc\x7d\xb3\x7c\xdc\x2c\x87\x2e\x85\x4c\x39\xc3\xc6\xcb\xa3\xd9\x69\xfa\xb6\x30\x77\x6e\xc6\x8d\x7b\x8f\xbb\x7d\xef\x6e\x5c\xd7\x3f\x1a\xa7\xc8\xec\x55\x44\x20\x53\x4f\xb3\x4e\xf6\x4d\x75\x00\x24\x00\x70\x87\xc3\x04\xed\x8b\x8d\x23\x0d\x33\xdf\xc8\x6d\x91\x82\x19\xc4\x07\x72\xb2\x75\x11\xeb\x42\xa9\x6b\x15\x47\x29\x12\x23\x0c\x84\xb6\xb6\x0b\x45\x16\x45\xe1\x22\x93\x66\xb8\x10\x45\x66\x48\xa1\xb7\x47\x5e\x7f\x8c\x5e\x8c\x10\x04\x27\xe4\x91\x9f\xd1\x2a\xa2\x91\x71\xc7\xb4\x41\x8a\x1f\xf2\xd2\x85\x7e\x4b\x47\xbb\x21\xa5\x8c\x65\x66\xf8\xa3\x6b\x40\x31\x41\xc7\xcb\x3b\x0a\xad\x27\x77\x2c\x45\x44\xd4\x80\x7a\x55\xf7\x4c\xc1\xe3\xf7\x6a\xc7\xab\x28\x24\x5e\x4a\x28\x2f\xdf\x16\xfe\x5d\x2a\x99\x66\xa1\xb9\xd2\x13\x7c\xf5\x29\xba\xf1\xf9\xc0\x39\x4f\x2d\xcf\xcb\xf6\x3d\x47\x65\x94\xdd\xbc\x6a\x9a\x94\x00\x0c\x99\xa0\xbb\xcd\x47\x14\xde\x0b\x6a\xa6\xf9\x3b\xa9\x93\x44\xc2\x08\x1c\x87\x98\x23\x77\x6b\x5a\x18\xd6\xca\xca\x65\xac\x2c\x04\x2a\x34\xc7\x55\xa0\x79\x66\xf7\xee\x3d\xaf\x45\xde\x36\xfb\x43\x5e\xee\xe5\x90\xb1\x77\xf4\x83\x8a\x40\x8c\x5d\xbd\x68\x63\xc6\x24\x2b\x76\x44\x48\x03\x8c\xed\x45\x75\x2a\xe5\x79\x59\x8d\xb8\x5e\xa4\x0a\x25\x45\xb2\x96\x7f\x3e\x2c\x1e\xdc\x56\xae\xa2\x20\x0b\x84\xa3\x74\xe8\x1c\xdb\x61\x4e\x40\x45\x20\x48\xe4\xfb\x04\x4c\x36\xf2\xb7\xa9\x25\xba\xb6\x2b\xce\x05\x77\x8a\xa5\x80\xe9\xd1\xbb\xd7\xdd\xeb\xcb\x6a\xff\xb8\xda\x2f\x6e\x6f\x5f\x56\x5b\x57\x74\x52\x2e\xe5\x56\x9e\x0e\xa6\xa2\xd3\xf4\x47\x62\x9c\x37\xd2\x62\x11\x79\x61\x04\xfc\xec\xe1\x44\x29\x17\x88\xfd\xfe\xaf\xe5\x48\x34\x75\x98\xbc\x56\x69\x40\x11\xc1\x60\x56\x5e\xb7\xbf\x8f\x55\xc4\xdc\xb8\x2c\x8c\x33\x23\xc4\xdd\xd6\x39\x7c\xc2\xa6\xbc\xeb\xf6\x04\x77\x54\x1a\xe9\xe5\xce\xf7\x5a\x2c\xe6\x3b\xc7\x14\x0f\x64\xaa\x7b\xa9\x89\xdb\xfc\x58\x54\x07\x7e\x73\x7e\x9a\x78\xc2\x8a\xd3\x10\x9b\x06\xdc\x7a\xd8\x42\x51\x20\x85\xa3\x55\x2f\xbc\x62\x61\x15\xb7\x3a\x0b\x8a\xff\x39\x0a\x9f\x14\x8f\x04\x3a\x05\x87\x81\x32\xad\x54\x9c\x87\x18\x59\x1f\xf2\xd2\x52\x06\xb8\x94\xb7\x12\x31\xa5\x28\x0f\x02\x4d\xc3\xdf\x60\x7b\x95\xc6\x79\xf2\x88\x42\x00\x76\x60\x22\xe1\x9c\xeb\xb8\xb8\xd4\x46\xb4\xa3\x65\xc0\x50\x0e\x4f\x55\x37\x97\x2a\x63\x6e\x4c\x42\x2d\x88\xbf\x5b\x10\x0d\xb4\xfb\xe6\xbd\x3a\x62\x0e\x63\xc6\x53\x57\x32\x51\xca\xe6\x2d\xaf\xa8\xa5\x0e\x63\x7e\xa5\x62\xe5\xea\x33\xa6\x66\x7b\x11\x5a\xb8\x81\x19\x47\xdc\xd5\xed\xea\x8f\xff\x2b\x98\xdc\x5d\x81\x9b\x16\xb3\x2e\x86\x78\x2d\x75\x0d\xe0\xd9\x26\x14\x04\x01\x71\x0a\x7f\x26\x60\xf3\x47\xd2\x10\x83\xa2\x27\xf8\x9a\xeb\xd9\x9b\xff\x2d\x08\x44\x84\xb8\x0e\x4c\x3b\xd9\xcc\x90\x3d\x44\x88\x51\x62\x03\xa4\xdc\xa9\xfd\x9f\x55\x88\xe9\x1e\xd7\xf5\xf7\x6c\x68\xe1\x87\xb3\x08\x68\x08\x59\x32\x60\x44\x34\x95\xc7\xd1\x7b\x02\x9a\x85\xb8\xff\x1c\xf2\x72\xae\x35\x12\xa8\x88\x1c\x63\xe8\x23\xaf\x3f\x4e\xc7\xe9\x71\x6d\xc4\x75\xbe\x57\x27\xc4\x24\xcf\xc6\xc0\x10\xa6\x46\xa7\xfa\xc8\xcf\x80\x4a\xb1\xcd\xae\xea\x16\x89\xbb\xd3\x88\x47\x08\x1a\xe5\x13\xe3\x0f\x11\x07\xcc\x92\xde\xe6\x6f\xf9\x4f\x13\x3f\x9f\xea\x61\x66\x0a\x22\x11\xa2\x94\x51\x83\x65\xac\x45\xd9\x7c\x41\x7d\x73\x5e\x74\x36\x79\x4c\x4d\x39\xad\xb5\x4f\x7e\x48\x9b\x1e\x4f\xcf\x83\xe5\xae\xcf\x92\xc4\x75\xc8\xe2\x0e\x31\x42\x05\x01\x4b\x32\x84\xee\xc1\xcf\x16\x30\x54\x9a\xbc\x1e\x96\x85\x48\x47\xa3\x72\x43\x9b\xb7\x2a\x55\x0f\x84\xf2\x63\x64\x60\xab\x5f\xcf\xdd\xfb\x99\xbc\x02\x26\x19\x37\x98\xa4\xba\x81\x6e\xa7\x1e\xa2\x1e\x80\xc9\xc4\xf0\x0a\x55\x95\x7f\x9b\x4c\x53\x44\x7f\x3a\xdc\x80\x67\x4e\x1b\xdf\x5b\x1c\x99\x04\xfc\x2d\x88\xbc\xed\xb7\x9b\xab\x7d\xa3\x90\x50\xf3\xad\xdf\xa0\xfd\x47\x25\x6c\xcc\x33\xbe\x66\x92\xa8\xd4\x66\xa8\xec\xb6\x7a\x99\xef\x82\x94\x51\x6c\x8a\xc4\xbe\x85\x21\x9d\xa4\x3d\x9e\xa5\x49\x6a\x00\xc6\xf0\x75\xdf\x6f\x11\x90\xe9\x58\x1a\x5c\xd9\x11\x1b\xa2\xbb\xa0\x6e\x34\xe1\x79\xc0\xb1\xb9\x60\x71\xfb\x87\xff\x53\x42\x88\x6d\xcb\xd9\x9c\x46\x80\x11\xe0\xa9\xd1\x24\x07\x2b\x57\xbf\x5e\x6d\xfc\x21\x29\xb2\xb0\xcf\x03\x3f\xc1\xd7\x0d\x57\x97\x4d\xa4\x6e\xb4\x36\xea\x8c\xe7\xea\xb4\xa8\xa7\x0f\x2b\x42\x48\x94\x47\x00\xe8\xdc\x76\x56\x37\xf3\x7b\x0e\x08\x41\x30\xe8\x33\x13\xca\x9b\x10\xff\x5b\x92\x81\x74\x4c\x5e\x83\xde\xbf\xe7\xaa\x2a\x36\x47\x73\xe1\xf1\xcd\xc9\x84\x22\x5a\x1b\xf3\xc2\x4f\xe0\x48\x9d\x40\x51\x8d\x04\xb8\x76\x3b\x5e\xbe\xf3\xda\x83\xcf\x40\x71\x9a\x58\xb7\xe2\x05\xde\x4e\x05\xaf\x97\xbc\x9e\xeb\x1e\x00\x05\x54\xba\x14\xdb\xba\xd9\xf2\x03\x6c\xf3\x37\xff\x41\x14\x00\x28\x47\xc6\xb9\xd6\x4f\x00\x0a\xd4\xee\x1d\xca\x6d\x0b\x97\xad\xe1\x13\x56\x98\xbf\x68\x24\xb4\x3f\x01\xc0\xc1\xf4\x85\x20\xec\x67\xe9\xdb\x3e\xaf\x9a\xfd\xf1\x0b\xd7\x29\xc1\xda\x7e\xb7\x00\x6e\xf2\x5a\xf5\xf4\x61\xa0\xb9\x21\x57\xf6\xca\x6d\xbf\x2e\xce\x80\x96\x02\x13\x3a\xf0\xd3\x97\x1a\xb1\xe8\x36\xd8\xc0\x74\x10\x08\xd7\xdb\xb3\x90\x86\x00\xc5\x30\x87\xcb\x36\xff\x84\x59\x09\x47\xa9\x09\x4b\x10\xda\x85\x0d\x45\x18\xf8\x8c\x3b\x54\x35\xe1\x19\xa6\xa5\x7a\xa2\x8f\x71\x4c\xa2\x89\xd2\x46\x49\xe0\xbd\xfa\x1a\x73\x43\x8c\xde\x86\xa6\x24\xd3\x36\xe7\xf0\x50\x55\xad\xa8\x7e\x5e\xa0\x00\x75\x18\x71\xf4\xac\xb6\x56\x8a\xe4\xb5\x14\xa6\x77\x76\xa6\x20\xa7\x43\x2d\xa8\xe1\x9f\xfd\xac\x3e\xae\xfd\x2a\x0b\x13\x6c\x8c\x39\x18\x68\xf4\x39\xf9\x6d\xf4\x83\x71\xc8\x0c\x52\xaf\x3a\xd5\x1e\x25\xa3\x63\xce\x32\x93\x57\xbd\xc7\x45\x5a\xef\xde\x79\x39\x1f\x65\xe9\x84\x4a\xe4\x0b\xc4\x2f\x39\xb9\xc3\x24\x4c\x59\x3c\x90\xbf\xc1\x3c\xb2\xb3\x45\x3a\x11\xa6\x6f\xd6\x72\xbb\x18\x6e\xaa\xc9\x05\x64\x80\x2e\x0c\xce\x11\x23\xfe\x7c\x15\x8d\x71\xd5\xd9\x76\xba\xef\xfe\x9a\xd4\x88\x3d\xa2\x18\xe7\x69\xd4\x80\x3b\x98\x4d\x69\x10\x99\x14\x6c\x0e\xb5\x4b\x71\x0e\xba\xa2\x74\x4a\x8c\x1a\x81\xe4\x87\x23\xcf\xdf\x4a\xa4\x82\xdf\x9e\xa4\x84\xa6\xd1\xa7\xc2\x57\x40\x75\x1a\x33\xdc\x67\x7d\xdb\xed\xb8\x99\xd8\x8d\xd2\x24\xe4\x23\xeb\xbe\x6e\xe1\x30\xe3\xd6\xe9\x2c\x48\xd0\x80\xae\x65\x35\x6a\xa6\xd3\x19\x01\xdc\xcd\x1e\x2b\xdd\xf2\x51\x1c\xab\xb3\x28\x76\x59\x90\x45\x51\x3c\x73\xbc\xbe\x9a\x38\x76\x3a\x4b\xa2\xd0\x54\xa2\x3e\x81\x17\x7f\x5c\xf9\xe0\x59\x9a\x22\x42\xf9\x1e\xd5\x00\x26\x29\x1d\x37\x46\x08\x84\x59\xbc\xf3\x06\xdb\xf0\x72\x50\x8b\xd6\x56\xdb\x4d\xed\x7e\x76\x99\xeb\x0c\xd2\x30\x76\xf5\xdd\xaa\x0b\x30\x6b\xdb\x8c\xf1\xcb\x24\xa7\xe6\x31\x47\x65\x6a\x71\x3a\x2f\xdf\xf9\xe1\x38\x4f\x42\xa5\x79\x46\x47\xd5\xd8\x05\x7e\xad\x41\xc4\x3b\x1d\x2e\x91\xfc\xb6\x33\xc0\x46\xee\x9f\x7b\xbf\x4a\x73\x69\x90\x3e\xcb\xe7\x3f\xe6\x3b\x9c\x26\x17\x93\xa1\x88\x6c\x4d\x62\xa1\xd6\xea\xe6\x3c\x82\x5e\x8f\x1f\x47\x46\x86\x13\xf8\xad\xae\xaa\xc3\x80\x58\x51\x77\xf1\x90\xf0\x4b\xc6\xb4\xe1\x4e\x26\x92\xe2\x49\xe2\xb4\x4c\xbf\xbc\x43\x34\x9b\x52\xd4\x10\x87\x38\x63\x74\x5e\xe6\xcd\xfb\x73\x9d\x7f\x5a\xb2\xa3\xdf\xfc\x80\x08\xfb\xbd\xb7\xdf\x16\x7d\x9b\x90\x86\x14\xb0\x56\xb6\x85\x76\xfd\xfc\xf2\xdb\xbc\x30\xd7\x7c\x7b\xd4\x4c\xb5\x57\x6b\xaa\x93\xbe\xd3\x6d\x51\xaa\x7f\x54\x79\xb9\xbc\x75\x00\x66\xad\x19\x4b\x89\xf1\xfb\xef\xe0\xca\x93\x68\x4d\x12\xdb\xe7\x61\xd2\x7c\xaa\xba\x05\x8f\xb1\x19\x4e\x73\x15\x04\xc4\x84\x51\x25\x3f\xc0\xae\xb2\x5d\xb3\xc3\xea\x56\x37\x24\xc5\xf7\xac\xaa\x37\x18\x55\x4c\x54\x10\x44\x92\xa7\x96\xe3\x76\xa5\x5c\xab\x9a\x0a\x82\xcc\x54\x52\x6a\x90\xa7\xba\xc9\x3f\x61\x09\xf9\xe5\x36\x3c\xfc\xce\x2a\x08\x78\xa6\x3c\x2b\xf1\x7c\x13\xb2\x1b\x29\x62\xdc\x64\x4a\xcc\x95\x23\xcf\xad\xfb\x61\x42\x7d\x85\x71\x3d\xce\x7b\xa8\x80\xe8\x04\x5f\xdd\x5b\xb5\xab\x7e\x54\xf5\xc7\xc5\x61\xc3\x6a\xfe\x50\xbd\x19\xff\x61\x6e\x35\xab\x80\xd2\x84\xda\x60\xe7\x9e\x1f\xa6\x42\x8e\xbd\x6d\x55\x01\xcd\x18\xca\xbd\x2c\xab\x1a\x1e\xf8\xd9\xc5\x54\x2a\xa0\x10\x22\x02\xcf\xb2\x68\xef\x7e\x5a\x3e\x8c\xbb\xaa\xfe\xfd\xc7\xfb\xe4\x03\x85\x51\x84\xbd\xda\xb7\x39\x3f\x54\xa6\x95\xd1\x5d\x87\x51\x86\xd1\xa1\x4b\xd6\x76\xd6\x6c\x48\xc1\xa6\x02\xa6\x04\x56\x7c\x2d\x9a\x04\x6a\x8b\xca\x76\xc7\xe3\xd8\x93\x14\xfe\x77\x5f\x0a\x1c\x32\x3e\xa9\x20\x09\x4c\x13\x86\x63\x1d\xe3\x88\x3b\xb8\xab\xea\xbb\xba\xfa\xd3\x4a\xac\x8e\x67\xa0\x0a\xd2\x50\xd3\xc0\xc6\xb4\xcf\x3e\x51\xa4\x82\x34\x0e\x70\xbe\xac\x9b\x4b\xca\x3b\x15\xa4\xc2\xf0\x49\x7b\x3d\x7b\x05\x87\x63\x1f\x83\xa9\x20\x0b\xb2\xd4\x4e\xec\xa1\x1c\xe1\x34\x95\xe4\x46\x2b\xc0\x56\xf5\xde\xf1\xdf\x94\x5d\xe4\xe4\x0e\x03\x09\x3d\x62\xec\x05\xf9\xb9\x4c\xc4\x87\x8e\xcf\x10\x8c\xa5\x02\x4e\x4c\x1c\x9e\x37\x16\xf7\x66\xdb\x3e\xdd\x0e\xa8\x02\x2e\x53\xde\x5d\xed\x5b\x55\xa8\xbf\x6e\x41\xf9\x95\x43\xfa\x77\x9b\xd6\x54\x20\x08\xd7\x76\xb2\x3f\x9e\xdb\x77\xf8\x79\x95\x17\x56\x05\x82\xa6\x58\x62\xbf\x2c\xf7\xab\x40\x24\x5a\xdb\x94\xd8\xcd\xe9\xfc\x54\x7d\x5d\xee\xb4\x2a\x90\x24\xcd\x7a\x9e\x78\x6c\x30\x5a\xfd\xf4\xd2\xa7\xd3\xc1\x11\xe5\x7d\x35\xc7\x71\x26\xaf\x4c\x0b\x91\xe1\xdc\xf3\x43\x35\x61\x4e\xed\xa3\xe7\x01\xee\xfe\x9e\x18\x8d\x97\xb6\x3a\xde\x9f\x5c\x54\xd9\xb9\xac\xfd\x0a\x53\x49\x84\x08\x28\xac\xe4\x21\xc3\xfb\xf8\xc1\x80\x86\xc8\x0b\xf4\x59\xb5\xc3\x0c\xce\xf8\x5e\x21\xcc\x5c\x53\x07\x02\x3c\xe3\xb1\xf5\x83\x24\x0d\x87\xdb\xe4\x8f\xbc\x7d\x37\x0d\x37\x57\x6b\xdd\xd7\xbe\xe6\x3c\x81\x99\x0a\x74\xe0\xa8\x1e\x4b\xe3\xda\xba\xbf\x33\x8e\xab\xd7\x16\x81\x9f\xf3\x55\xff\x7a\x34\x8f\x23\x62\x6a\xab\x65\x5e\xbe\xed\x05\xb4\xcd\xb0\x04\xa6\x48\x10\x80\xe6\x9e\x74\x7b\x20\xce\xa3\x48\xa0\xb2\x04\x86\xc0\xed\x1f\x3c\x6f\x7d\xe9\x45\x11\x42\xa3\xc4\xe3\x31\x1c\x97\x88\x3b\x16\x49\x74\x1b\xb0\x01\x70\xa0\xd6\x78\x65\x2a\xdb\xb3\x3a\x7f\x5f\x61\xbe\xfc\x0b\xea\xed\x57\xde\xca\xf7\xbe\xe8\xa0\x08\x15\x8c\xb8\xfe\x57\xdf\x82\x3d\x34\xec\x24\x4c\x04\x4e\x93\xb6\xba\xe1\x0d\xb0\x74\x26\x17\xab\x48\x08\x14\xab\xfc\xba\xaa\xdf\xe0\x07\xf0\x63\x55\xbe\xa0\x0e\xe1\xdf\x4a\x8f\x29\x12\x6a\x85\x84\x84\x7b\xc3\xf7\xb8\x9c\xc9\xb2\xff\xd7\xdc\xef\x46\x5c\xa0\x9b\xd1\x37\xae\x1b\x39\x97\x39\xea\x19\x45\x18\x51\xc4\xd5\xec\xed\xa4\x5c\xd4\xf5\x00\x2f\x3b\x9a\xc4\x84\x31\x1d\x5e\x40\x1c\xa6\x73\xcf\x96\x82\x15\x61\x22\xc6\xf6\xc9\xc7\xf3\x8f\x7c\xc0\x6f\x31\xdb\xf3\xf2\x2b\x37\x52\x11\xa6\xb3\xcc\xe8\xed\x62\x85\xfd\x75\x7b\x3b\xeb\xa0\x29\x12\x2b\x63\x95\xf3\x66\x69\xdd\x7f\xdc\xd6\xc6\xfb\x18\x89\x35\x04\x36\x13\xde\xed\x61\x37\x5c\x7e\x6c\xc4\xbf\x61\x22\x7d\xa1\x48\x02\x84\x11\x6b\x0f\xb8\xa8\x2f\x8e\x72\x0f\x59\x36\x41\x9c\x51\x5e\x9e\x50\xfc\xf7\xf8\x7f\x45\x52\x41\x59\xe0\x08\x48\xcc\x8b\x9e\x2e\xd4\x4b\x47\x4c\x91\x8c\x2a\xe4\x99\xe4\x5a\x23\x41\x03\x8c\x75\x01\x14\xc9\x42\x48\x84\x27\x2a\xc7\x2c\xe3\x69\xc4\x05\x3a\xb0\x54\x24\x63\xa6\x98\xb9\x2e\x3b\xf7\xf2\x33\x1f\x04\x24\x8a\x70\x6a\xb8\x5f\xc4\xc9\xf6\x6d\x37\x23\x36\x99\xf9\xcf\xc3\x59\x8c\x09\xd5\x1f\x50\x14\x25\x3a\xee\xc3\x2b\x32\x8d\x1e\xc6\xfe\xad\xe6\xa5\x7a\xfe\xfe\xfc\x50\x35\xdd\xe6\xff\xe5\x04\xd3\x07\xd7\x89\x0d\x15\x76\x0d\xc7\xaa\x6e\x87\x8f\x40\xc6\x93\x9c\x73\x86\x9d\xca\xcf\x8b\x97\xdd\xd3\xea\x65\x3b\xea\xe8\x55\x44\x90\xcc\x95\xbd\x91\xbb\x60\x3b\x05\x8c\x29\x22\x62\x82\x45\x80\x6e\xe2\xcf\xc6\x53\x8a\x88\x84\x23\xc7\x44\x59\x95\x77\xa7\xf2\x2d\x17\x05\x8c\xdb\xa1\x14\x11\x69\x66\x44\x1b\x30\x53\xbe\xfa\x99\x37\x13\x36\x39\x45\x44\x26\x51\x83\xf0\x79\xb3\x79\xd8\xdf\xad\x56\xfe\x54\x11\x2a\xe2\x54\x03\x1a\xc9\x5b\x98\xe3\xc7\xe9\xc6\xc5\xb8\xb1\x1a\x77\x78\xb9\xb9\x5f\xf8\xc7\x94\x21\xc3\xce\xb0\x1a\xe4\x59\x16\xd3\x27\x94\x4a\x63\x46\xf1\x03\xce\x82\x37\xf0\x7c\x12\xaf\x2f\x0f\xa3\xfd\x84\x28\x06\xb1\x11\x9d\x94\xf7\x50\x3e\x70\x71\x97\xbf\xbd\x4f\x17\x81\x12\xd2\xb0\x01\xf1\x42\xbe\x96\x8f\xbc\xf9\x00\xb5\x9a\x13\x30\x54\x44\xc9\x00\xeb\xf1\x16\xf6\xd1\x07\x2c\x8a\x28\xad\x9d\xb2\x18\xd2\x8d\x2d\x4d\xaf\x71\xbf\x0f\x00\x8d\x19\xe9\x3b\xcb\x7e\x87\xf3\xe4\xe2\x10\x01\xa6\x95\xf7\x5e\xc8\x6b\x3a\x00\x42\x2c\x5e\x7c\xbd\x0f\xe2\x2a\x7f\x0c\xb0\x77\xc2\x88\x9a\x79\x9d\x91\x3e\x84\x53\x44\x67\x31\xc2\x38\x9e\x5f\x5f\x96\xdf\x16\xdb\xd5\x7e\xf1\xb8\x79\x7d\xda\xed\x5f\x16\xbb\xd5\xfe\x65\x75\xb7\x7a\x59\x3d\x2d\xfd\xe7\xd3\x32\x36\x72\x9f\xb6\x16\xa2\xee\x2e\x15\xa1\xc6\xf3\x89\x06\x9c\x99\xc4\x04\x86\x53\x3d\xb3\xf4\xf8\x31\x28\x61\x91\xd3\x79\x30\x9a\xfe\xcd\x25\xd1\xb2\xa2\x24\x91\x40\x5c\xd4\xaa\x4e\xbd\x22\x99\xa2\x24\xd5\xda\x92\x23\x3e\x23\x9b\xac\x03\x99\xac\x87\xb4\xd2\x93\xcb\xe9\x10\x83\xe6\x76\x1f\xd6\x6a\x8f\x65\xd5\x7e\x83\xa7\x94\x44\x69\x2f\xce\x0d\x6a\x7b\x3a\x6c\x4a\x73\x6d\x3f\x24\x4d\x1d\xf1\xca\xc2\x59\xa9\xa1\x33\x36\xf9\xbd\x30\x52\xa8\xc4\xf2\x9c\xff\x84\xe2\xa6\x3a\x0d\xa6\xdd\x45\xee\x73\x2e\x07\xa0\x68\x98\x64\xb8\x3f\x8a\x4a\x3c\xf2\x0f\xc4\x4a\x3a\xfc\xd5\x64\xef\xb2\xca\x8f\x01\x5e\xd0\x0a\x2b\x29\x1a\xa6\x71\x60\xc8\xd3\x1b\x68\x2f\xda\x4d\xec\xa0\x28\x48\x54\x68\x37\x80\x4d\x59\x9c\x91\xcf\x75\xb4\x97\xd0\x88\x6a\x6e\x7c\x43\xae\xf5\x3e\x72\xef\x83\x85\x52\x05\x63\xc4\xc0\xa3\x51\xac\x70\xc9\xc5\xd4\x8d\xcc\x22\xde\x73\x36\x1a\xb7\xd9\xcc\xa9\xc9\xf2\xa2\x09\x68\x2c\x96\xef\x8f\x5c\x7e\x3c\x7f\x7f\xee\xbb\x1b\x14\x4d\xb4\xa1\x0c\x5c\xb5\x50\x97\xbc\x40\xea\xc4\xeb\xb1\xbd\xa2\x69\x20\x13\x3e\xa8\xf3\x42\xcb\xe5\x7b\x37\x1b\x37\xe5\x33\x3f\x4d\x04\x60\x15\x4d\x53\x92\x18\x76\x4e\xac\x6a\xfe\x3a\xda\xa1\x69\xe7\x45\xfd\xbf\xff\xef\xff\xfd\xf7\xfa\x61\xfd\x74\x7f\xbf\x19\x76\x1e\xe0\x51\xcf\xb7\x00\x07\x81\x13\xdc\x00\x59\xc7\xbf\x99\x45\x04\x97\x58\xde\xcb\x40\x8d\x29\x31\x15\xe5\x41\x82\x6f\xe4\x61\xb9\xf5\x7f\x92\xd4\x76\xa8\x96\xbb\xea\xe1\x74\x45\xcf\x54\x51\xae\x4c\x95\xaa\x91\xef\xa0\x4e\x05\xca\x9f\xfe\x76\xc9\x8a\xa1\xa8\x90\xa6\x51\xeb\x16\x3e\x73\x09\xeb\xe6\x16\xb8\x6c\x31\x21\xa3\x26\xb3\x45\x46\x0a\xc5\x02\x17\xaa\xc2\x50\xd1\x9a\x41\x43\x0f\x56\x38\x5d\x18\xe6\x46\xa7\x69\x6a\xb5\xb9\xba\x01\xdf\xf2\xa6\x1d\x10\x5e\x4d\x6e\x42\x51\x8e\x90\x5c\xab\x7a\x72\xe5\x99\x54\x04\xf8\x3a\x0c\xa3\xd1\x23\x77\xa8\x66\x45\x21\xe0\x98\x31\x33\x52\x01\xa3\xde\x4f\x3b\x42\x47\x20\xec\x57\x79\xb2\xbc\x65\x48\x6e\x66\xaf\x10\x06\x81\x74\xdc\x69\x5b\x68\x11\xb9\x8a\x13\x76\x58\xe0\xb9\x44\xf0\xaa\x30\x20\x01\x16\xeb\xca\x6a\xa3\x77\x79\x6f\xa6\xc2\x20\xa4\xb8\x7b\xa1\xa4\xf7\xf2\x9b\x69\x9f\xf6\x07\x63\xe3\x84\xbb\x57\x7d\x35\x27\xa7\x42\x42\x33\xcc\x95\xf5\x3a\x2f\x45\x71\x73\x3a\x77\x4e\x9d\x67\xfe\x56\x21\xd1\x11\x82\x5b\x10\x96\x78\x0b\xc2\x6d\xe1\x21\x25\x01\x32\xfe\x17\xf0\x09\xc5\xba\x85\xc3\xb2\xe0\x7e\xdf\x08\x69\xa4\xc1\xd8\x29\x90\x30\xd2\xcb\xfa\xcb\xd6\x59\x15\xd2\x38\xd0\x1e\x62\xb7\x39\x02\x4e\xdf\xda\x5f\x3a\x65\xf8\xfd\x5d\xc6\xc4\x18\x7b\x77\x34\xe2\x02\x2d\x8f\x0b\xf5\x6e\xf3\x1a\x64\x5b\xd5\x8b\xf1\x9c\x0b\x23\x69\xf8\x07\x24\x3f\xde\x15\xae\xf5\x4a\x85\x91\xe2\xd8\x9b\x8b\x21\x76\xf7\xb3\x1b\xdd\xed\x77\x0f\x55\x1b\xf9\x21\x40\x90\xf7\xc1\x90\xb5\x79\xb8\x57\x77\x20\xc1\x6e\x0b\xd3\x3f\xfd\x4b\xcf\x2f\x8c\x99\x48\x11\x87\xe5\xba\x69\x55\x18\x0b\x96\x49\x1f\xd0\x95\xb6\xc7\x60\x32\x2b\x62\x20\x78\x9e\x73\xa8\x86\xd2\xe2\x2a\x4c\x04\x98\xd9\x5e\x29\x17\x69\x9f\x7a\x7e\x54\x15\xa6\x51\x80\xa5\x9f\xe7\x97\xf5\xf7\xc5\x6e\xf5\xfc\xb0\x58\xae\x1e\x57\x4f\xce\x31\x0a\xd3\x98\x62\xbe\xfc\x80\x4d\x3d\xc5\x79\x8b\x73\xda\xb8\x9c\x8d\x6f\xd2\xbd\xab\xea\xe5\x7b\x5e\xa8\x49\x92\x62\xf2\x84\x59\x02\x41\xe8\x89\xd9\x6d\x31\xc4\x1e\x13\x01\x89\xa4\xeb\xc6\x68\xa1\x69\xbf\x43\xdd\x0c\x10\x90\x6e\x98\x0a\x9c\x7c\xc2\x0b\x70\x75\xee\x7b\x7e\x55\x28\xa3\x00\x53\x6a\xfb\x06\xda\xc4\xff\x51\x9a\x8a\xf2\xd1\x54\xbc\xee\xaa\xfa\x1b\x14\xc7\x9e\x0e\x57\x85\x2a\x10\xd8\x95\x6d\x36\x8d\xe2\x48\xd2\xc9\xbc\x00\xa6\x11\x5d\xb0\x6f\xde\x79\x0d\x26\xb9\x37\x6f\x35\x42\xd0\x31\x8f\x47\x7d\xa5\x9f\xae\xaf\x54\x85\x9a\x1a\xbc\xda\xfe\x58\x57\xd2\xb9\xf6\xcd\x2f\x61\xab\x2a\xd4\x69\x8c\x0f\x7c\x57\x54\x1c\x33\x93\x66\xc5\xcc\xc6\x94\xa1\xce\x18\x72\xdf\xed\x7b\xf6\x5a\xff\xe3\x9c\x98\xaa\xc3\x7b\x3e\xea\x72\x50\xa1\xd6\x91\x8e\x5d\xa6\x06\x60\x57\xfd\x82\x08\x56\x45\x24\x54\x68\x17\xbf\x43\xa9\xf2\xf1\x4c\x8c\x48\x96\xea\xc8\x4b\xde\xda\xad\x2d\x1d\x6f\x68\x11\x91\x92\xda\x9c\x80\x6b\x64\x1a\x90\xcf\xa8\x88\x80\x11\x81\xad\x41\x01\x1c\x66\x23\xa6\xe1\xed\x47\x34\xd0\xa8\x5b\xc4\x4f\x2a\x6f\x51\x4e\xf1\xd0\xe7\x5a\x22\xca\x42\x6c\x60\x7b\x84\xaa\x39\x0d\x01\x71\x2a\xa2\xd2\xe8\x01\x19\xe6\x0a\xcf\xde\xeb\x0f\x6b\x8e\x67\x9a\xfe\xf2\x10\x4f\x5d\xd9\x52\xff\x8b\x07\xce\xaa\x28\x24\x11\x42\x06\x4f\x65\xfe\x9f\x13\xec\x47\x8a\x44\x2a\x8a\x42\x99\x08\x4f\x9d\x6a\xf8\xaf\x27\xbe\x48\x14\x65\x1c\xbb\x0d\xb0\x9a\xe1\xbf\x58\x14\x71\x82\xa5\x43\x2b\x0f\x0d\x3d\x88\xbb\xe7\x12\x1d\xcf\xd4\x88\x05\x0a\xc1\x2c\x43\xf2\xdb\x1b\x5e\x7e\xec\x2a\xa7\x02\x32\x9b\xba\x88\x58\x22\x13\xdd\xef\x9f\x8d\xa7\x2b\x54\x11\x03\xea\xf8\xd8\xba\x8d\xe3\x21\x6f\xda\x5e\x37\x47\x45\x31\x05\xe4\x3b\xf2\xb9\x6a\xcc\xaf\x76\xbe\xdd\x00\x5f\x3d\xf9\xb5\x38\x09\x30\x54\x42\xc0\xe4\xf8\x50\x12\x2a\xf4\x76\xdc\xe5\xf6\xbe\x18\xa5\xa2\x44\x83\xad\x01\x94\x6a\x57\x8d\x4b\xa9\x7f\x95\xab\xb3\x97\x48\x83\x74\xf8\x9c\x7d\x23\xc4\xe4\x3d\xa6\xb1\xc4\xfe\xd6\xaa\x33\xb7\x3f\x78\xd9\x3e\x9e\x07\x1d\x8f\x2a\x4a\x33\x13\x02\x35\xd0\x6e\xcf\x4d\x0b\x87\xad\x05\xa7\xe2\x06\xf0\x98\x4f\x1c\x82\x28\x55\x19\xf1\x0c\x6d\x5b\x28\x8a\xa1\x9e\xae\x8a\xb2\x84\x61\x51\xdf\xa6\x64\x66\x98\x05\x54\x94\x69\x82\xd0\xe8\x9b\xaa\x7a\x1c\x4d\x63\x1e\x30\x44\xf5\x89\xd3\xd9\xc3\x3d\xd2\xc9\xa2\xe5\x69\x18\xdb\x88\xc2\xbb\xe7\x2e\x6b\xeb\x33\x4d\x83\xbc\x46\xc4\x53\x1d\x93\x81\xcc\xb7\x6f\x14\xf1\xbf\xca\x25\x3a\xb1\xdb\xd5\xc3\xc3\xea\x65\xbf\xdd\xad\x9e\xf7\x74\x7f\xbf\xda\xed\x9f\x17\x0e\xcd\xa9\x22\x0e\xc2\x48\x7d\xe3\xc9\x8f\x79\x89\xd9\xc8\xc1\xef\x08\x49\x30\xd4\xf9\x82\x2e\x5a\x9e\xa0\x6c\x55\x24\x54\x24\x92\x11\xe6\xfe\x31\x2f\xa0\x69\xab\xd2\x48\x95\xfc\xc0\xb5\x39\xde\x22\x22\x99\x19\x47\xd6\x46\x93\x4f\xd5\xa4\x03\x59\x45\x4a\x1b\x74\xee\x07\x32\x43\xd8\x3f\x42\x6c\xf2\x62\x05\x40\x7d\xcf\xfb\x3f\xa7\x29\x92\x51\x1d\xab\xbc\xb3\x11\x27\xe7\x56\x45\x9a\x68\x03\x8d\xb6\xf9\xaa\x6f\xd5\xa1\x92\xb9\xf2\x2b\x43\x33\x8d\x29\x0f\x37\x95\x6f\x6e\x36\xfe\x50\xaa\x91\xaa\xb0\xee\xdc\xb5\xad\x73\x2b\xec\x51\x16\xc4\x26\xa3\x66\x4d\x4d\xd5\xdb\x24\x16\x80\xa9\xeb\xa0\xe7\xb5\x3d\x1d\x0e\x55\xf9\xe4\xfd\x32\x46\x02\xff\x95\x4d\x9c\x54\xd5\x07\xb3\x4c\xf6\xc7\xaa\x9a\xe7\x2f\xef\xce\x4a\x95\xed\x78\xa9\x71\x53\xc2\x46\x5f\x27\x7c\x66\xeb\x25\xa3\xf7\xc7\x48\x00\x48\x9c\x52\xc2\x57\xf7\x4e\x5e\x8f\xb3\xb5\x09\x46\x98\x54\x5e\x80\xfb\x7b\xd5\x7d\xfb\xbb\xaa\xc6\xe7\xb5\x95\x31\x7f\xe7\x9a\x73\x9b\xab\x9f\xca\x9a\x2a\x46\x43\x86\x6d\x7c\x0a\x3e\x4f\x50\xf8\x54\xe9\x6b\x73\xe2\x75\x3e\xa9\x7b\x32\x1a\x45\x58\xb6\x45\xea\x98\xfa\xec\x2b\xda\x3f\xf2\xf6\x7d\xc0\x9c\xa2\x58\x28\x0d\xbb\xe9\x21\x2f\xdb\xab\xbd\xc7\xe3\x1b\x89\xa8\x11\xa7\x6c\x1d\x6f\x96\xfb\x3b\x8f\xa9\xb6\x8b\xa5\xef\xf6\x75\x07\xa5\x51\x2e\xe5\xea\xf3\xa6\x1d\x31\x03\x2b\xc6\x82\x8c\x39\xb6\x90\xce\xd2\xcc\xe1\xec\x14\x63\x9a\xe0\xcf\x1a\x9a\xff\x65\xde\xe6\x7f\x4e\x23\x0e\xc6\xb4\xe9\xeb\x36\xf9\x90\x2d\x4a\x1f\x3c\xd7\xd5\xa1\xb2\xb9\xa1\x5c\x14\xf3\xe2\x59\x17\xd5\x27\x16\x87\x86\xc5\xfb\xbe\xca\xcb\xb7\x7b\x38\xcc\x8b\x5d\x29\x96\x28\x26\x99\x9b\x6d\xa7\x69\xb8\xcf\x52\x66\xd2\xa8\x25\x7c\xe5\x28\xd2\x53\x54\x6f\xbf\xcd\x6d\xe0\x2c\xcd\x08\x12\x11\xfd\xbb\xca\x2f\xe8\x59\xc7\x03\x35\x53\xa6\x5a\xb7\x96\xd5\x1d\x96\xf3\xdd\x9b\xcc\x28\x37\xd5\x9c\xea\xf8\x7a\x1c\xd5\xf8\x58\xc6\x42\xdc\xe6\x4f\x65\xeb\x16\xc5\xa8\x52\xc5\x32\x99\x61\xa9\xbc\x9b\x09\x37\x1c\x2b\x18\x7f\x8f\x66\x69\xf2\x42\x78\x04\x58\x0b\xe9\x9c\xb4\x17\xec\xa2\xb9\xec\xda\x98\xcc\x28\x9e\xe8\x28\x18\xd3\xfb\x2c\x2d\x84\x77\xf7\xf3\x9e\x37\xc7\x1e\x6f\xa8\x18\x97\x86\xe6\xfd\x88\x9d\x86\x2f\x80\xca\xc9\xce\x20\x33\x41\x43\x35\x94\x35\xb9\xa9\x4a\x75\x65\xc5\x0b\x9a\x09\xc3\xd0\x77\x13\xd2\x99\xd6\x68\xc5\x24\x8d\xb1\x37\xfd\x77\x7e\x3c\x9e\x7f\xef\x7d\x65\x26\x79\x9c\xd8\x96\x8b\xce\x9a\xbb\xe4\x24\x7e\xa5\xc7\x9e\x49\xee\xbf\xae\x67\x4b\x98\x14\x1c\x51\x0c\xcb\x6f\x7f\xf4\x1a\xc5\xf6\x98\x92\x0a\xa9\xe7\x74\x5e\x2a\x83\x68\x7b\x19\x8a\x6f\xb8\x51\x8a\x31\xa3\xc8\x3c\xe0\xa3\x9f\x0e\x49\x0d\x6d\x66\x7e\x80\xfb\x7e\xa5\x2a\xa5\x21\xbd\x4a\x09\x3c\xc8\x24\x31\xa5\x4d\xe4\x55\x56\x86\x96\xfa\x1a\x60\x5d\x31\x88\x02\xac\x37\x77\x73\x72\x60\xaa\x21\x35\xa9\xc7\x7f\x73\xf9\x71\xac\xda\x47\x50\x79\x6f\xa9\x81\x27\x46\x79\xee\x54\x23\x8f\x71\x55\x7e\x42\xdd\xee\xaa\x7f\xbe\x2e\x26\x0b\x5b\xc7\x86\x19\xb5\xcc\x25\xbc\x9d\xce\xa1\xbb\x82\xce\x8c\x38\xd2\x76\xb7\xdd\xad\xb6\x3b\x4b\x0c\xac\xe2\x20\xd2\xa8\xac\xb6\x7a\x3b\x1f\xdb\x9c\x97\xcf\x83\xed\x23\x0e\x44\x88\xfd\x3a\x6f\xf9\x27\xdc\x61\x9a\xfd\xf2\x2d\x8c\xfc\x80\x38\xb0\x14\x59\xc7\x81\xa8\xc0\xd0\x5b\x8f\x09\x01\xa4\x64\xdb\x42\xdb\x4e\x23\xd3\x98\xc4\x3c\xea\x4c\xc4\x7f\x43\x5d\xf5\xf6\x32\xa6\x82\x98\x4c\x13\x2f\x86\x2c\x58\x2a\xa6\xa0\x30\xab\xcb\x7f\xa9\x6f\xa3\x62\xaa\x63\x1d\x3a\x5a\xdd\xb9\xb6\x5b\x77\xc1\x90\x84\x98\x6f\xaf\x4a\x1f\x65\xcd\x14\x42\xe6\xcd\x7d\x1c\xea\x04\xd3\x8e\xfa\x54\x4a\x93\x82\x6a\x4f\x98\xaa\xbf\xc4\xc1\xab\x38\x8a\x34\x52\x9e\x09\xde\xe4\xcd\x73\x95\x97\x6d\x33\x08\x12\xe2\x98\x10\x6c\x5e\x79\xeb\x6c\x43\xf7\x49\xfa\x8c\x70\x9c\xf0\x10\xf1\x24\x38\x8f\x1f\x72\x0d\x4b\xac\x40\xd8\xa3\x29\x01\xcc\xe5\x83\xac\x1a\x74\x35\x51\x65\xdf\xe1\x15\x46\xfb\x49\x9c\x5a\x29\xcc\x41\x3f\xb8\x33\x44\x0b\xdd\x42\xbd\xfa\x79\xcc\xeb\x79\x3e\x43\x15\x67\x59\x8c\xd9\x8f\x87\xcd\x83\x9b\x65\x31\x57\x09\x7a\xea\x23\x22\xd1\x89\x73\x19\x73\xad\xb4\x11\xa6\xae\x4e\xc3\x6c\x6c\x2c\xa8\x96\x46\x37\xeb\x86\xd7\xcb\x4a\x41\x8f\x66\xf5\xef\x4d\x64\x19\xa6\xc2\xa0\xf4\x84\x39\xcf\x1e\x8a\xae\x62\x49\xcc\x8c\xbd\xe7\x7f\xc2\x88\x05\xb4\xcf\x32\xdb\x91\x10\xc7\xca\xe7\xeb\x2c\x1f\x1f\x7a\x32\x63\xcb\x10\x43\x0a\x28\xeb\xb6\x3f\xf0\xfa\xa3\x87\xa2\xdc\x9d\x0a\x9d\xf7\x89\x45\x7f\x7f\xa0\x18\xd6\xea\xf3\x32\x6f\xb7\x27\x81\x00\xfb\x0b\xec\xf5\x40\xd5\xd9\x9e\xa6\x03\x8d\xc0\x92\xc5\xf1\x58\x58\x7e\xc2\x75\xb3\x2e\x6f\xe1\x13\x8a\xea\x38\x70\x7d\x12\x92\x29\xec\x58\xe4\x86\x1e\xe1\x5a\x40\x73\x59\x00\x4d\x28\x25\x34\x71\x9d\x32\x86\xc5\x7f\xb2\x7d\xf6\x03\xd1\xea\x3d\x54\x6f\x26\x1f\xdd\x2f\xf0\x84\x26\x60\x84\xec\x4e\xe5\x3f\x8c\xa5\x72\x37\x46\x33\x23\xc5\xcf\x95\xda\x37\xef\x39\x14\x6a\xb4\x6d\x26\x94\x03\xc6\x9a\x5e\x45\x68\xbd\xdc\xec\xbf\x88\x3b\x3d\x54\xc4\x41\xc0\x5d\x48\x3e\xbb\x98\x13\x46\x42\x12\x58\x0c\x8e\x11\xd3\x03\x65\x58\x85\x2e\xea\x56\x09\x83\xc4\x29\x10\xaf\x9e\xaa\xaf\xdf\xfc\x9f\xa5\xb4\xb8\x87\xef\xd0\x60\x93\xe0\xc8\x6d\x1d\xcf\xf4\x24\xf6\xca\xef\x17\x95\xe3\xd9\x34\xff\xb4\x18\x9f\xa4\x49\x9a\x58\xd7\xe7\x74\x9c\x6d\xd3\x19\x3f\x62\x46\x24\x30\x37\x37\x6f\x41\xba\xfb\xce\x62\x11\x98\x46\x0b\x05\x3f\x37\x7a\xc9\xeb\x69\x02\xcd\x0d\x94\xd2\x6a\x11\xca\x1a\xbb\xfd\x87\x36\x38\xc9\x20\x44\xb3\xd9\x1c\x8b\xbc\xed\x05\x39\x47\x24\x26\x2a\xe1\x24\xc1\x1d\x83\x9b\x4c\xc0\x90\x21\x5c\x25\x9c\x0b\x8c\x2e\x3d\x7e\xf7\x1b\x14\xc7\x6b\x69\xe2\x44\xd8\xc6\x20\x71\xea\x8c\x6f\x63\x19\xf2\xef\xea\xea\xd0\x63\x24\xfc\x50\xa3\xc6\x60\x57\xcc\xae\x1a\x68\x01\x4e\x70\xea\x2a\x11\x5a\xa7\xd4\x43\x22\x96\x4e\x19\xd8\xc5\xc9\x89\x22\x71\xca\xbd\x0a\xca\xcd\x09\x6d\xdf\xe8\x21\x55\x2c\x84\x75\xa8\x1e\x8e\x8b\x66\xa8\x4b\xa9\x12\x25\x8c\x22\x2f\x57\xaa\xdb\xfd\xbe\xe7\x25\x9c\x07\x3c\xde\x6e\x94\x02\x6c\x78\x38\xf0\x9f\x28\x97\xdb\x27\x3b\x12\x20\x04\xb3\xb9\xd8\x26\x5b\xda\x46\x76\x1b\xca\x0c\x37\xb2\x04\x04\xc7\x8a\xd0\x77\x5e\x74\x5f\xa3\x04\x8b\x43\x73\x75\x9b\x44\x53\x8a\x54\xe2\x8f\xf9\x92\xd7\xcd\x7a\xb9\xf1\x07\xd2\x14\x9c\x22\xe7\xbe\xe9\x9b\x31\x55\x1a\x68\x8a\x2b\xf5\x7b\x2e\x6a\x5e\x4a\xcf\xff\xad\x52\x92\x64\x48\xec\x31\x60\xbe\x0f\x2e\x99\xef\x55\x4a\xb2\x84\x3a\x98\xdd\xdd\x4e\x9c\x1d\x2a\x74\x32\xe9\x7b\xeb\x90\x86\xa9\x41\x30\x41\xa9\x1e\x1d\x7d\xfb\x90\x68\x53\xa5\x21\x0f\x0d\x69\xa1\xc9\x6f\x55\x75\xfb\x36\xd0\xe9\x75\x83\x64\x8a\x4f\x2b\xb8\xfc\x00\xdf\x4e\xe4\xbf\x6b\x1a\x85\x54\x83\x4b\xea\x1e\x78\x5e\x7a\x85\xb8\x2e\x5e\xec\xfd\xc3\x34\x4a\x94\x1b\xe8\x35\xae\xf6\x87\xaa\x84\xb3\x1f\xc1\x25\xe7\x7d\x34\x0b\x8e\x88\x6c\xfc\x91\x53\x96\x25\x98\xd5\xde\x42\x3b\xd4\x52\x9f\x85\xd3\xfc\x9f\xff\x99\x33\xc2\x29\x13\x44\xd9\xb6\x67\xdb\x6a\xe2\xc0\xdf\xd3\x5b\x13\x29\x36\xb2\x76\x6e\x27\x2f\xae\x54\x53\xd3\x98\x24\x92\xdb\x8e\x38\xcc\x4c\xcd\xae\xd4\x34\xa6\x04\x91\x53\x07\x50\xbc\xd8\x9e\x0f\xc2\x6f\xad\x69\x1c\x19\x06\x1a\x2b\xaf\x6d\xf9\x26\x97\xd5\x25\x7d\xd1\xf4\x9a\x3a\xc1\xbd\x6d\xb9\x79\x7c\x7c\x7d\x5a\xef\xfe\xb5\xb7\x54\xf0\xdf\x36\x0f\xb7\xab\x17\x77\xfd\x44\x66\xc8\xac\x07\x3f\x61\x54\x91\x48\xb3\x24\x41\xf6\x74\x94\xd3\x2c\x7e\x54\x75\xa1\x0c\x5a\xcd\xe6\x87\x9c\xe0\xc6\xc9\x48\xf8\xba\xb3\x52\x8d\x29\x02\x43\x5a\x63\xfa\x41\xab\xaa\x98\x74\xc3\xa9\x34\x53\x9c\xbb\x7e\xbb\x9b\x3b\x5e\x1f\xd6\xb7\xc6\xda\xd8\x62\x75\xca\x03\x89\xfd\x1a\x9f\x5c\x4e\x5b\xcb\x54\xca\x15\xc1\xa4\x8e\xe5\x05\x5d\x1c\x8f\xc6\xeb\x1b\x7b\x05\xa9\x08\x34\xa6\xcc\xeb\x83\x15\x0b\x75\x52\xc3\xfd\xfd\x0a\x95\xa2\x23\xee\x64\xcd\xc6\xbf\x23\x34\x71\x10\x4f\xe3\xbb\xca\x36\xf8\xf9\x04\xed\x57\xe5\x9a\xf3\xc7\xe3\x91\x82\xd4\x4c\xeb\x1f\xbc\x86\xf7\xea\x74\x0d\x4b\xed\xef\x51\x11\x02\xb4\x47\x23\x6f\x4f\xa2\x91\x75\x7e\x6c\x2f\x6a\x2a\xa9\x22\x51\xa6\x7c\x5e\xc3\xbd\xd0\x81\xfb\x9a\x2a\x22\x41\xbb\xfc\xa5\xd1\x14\x32\x88\xb0\xc9\x46\x95\xaa\x48\xfa\x80\xb6\x73\x4d\x7d\x8e\x33\x85\x38\x46\x76\x85\xbb\xd7\xa7\xdb\xfd\xdd\xcb\x62\xb9\xbf\xd9\xec\xfc\x41\x88\x11\xab\x59\x54\x6f\x73\x75\xe3\x14\x74\x1c\xf7\x59\xf4\x4b\x52\x41\x95\xea\x90\x20\xe8\xe2\xdb\xf9\x08\xf5\xf2\x3d\x3f\x8e\x80\x53\xa9\x06\xc0\x4e\xf6\x1a\xbb\xd1\xda\xca\xd9\xce\x2c\x60\x01\x6e\x65\x55\xfd\xc6\xcb\xbc\x41\x0b\x37\x72\xaa\xb3\x40\x46\x41\xe8\x3b\xae\xba\xad\xf3\x0e\xe0\x22\xb4\x1e\xdf\x70\x46\xd2\x00\xf8\x58\x99\xd6\xa4\xd3\x6c\x2e\xdf\xd9\xcf\x8c\xd8\x89\xd0\x56\x6f\x6f\x05\x2c\x4e\xed\x7b\x55\x3b\x05\xce\xa9\x2b\x38\xfa\x6a\x19\x8d\x18\xba\xc6\xca\x4b\x20\x59\x7d\xaa\xdf\xae\xba\x8c\x19\xe5\xa9\x08\x1c\x50\xaa\x3e\x78\x70\x5b\x7f\xe3\x21\x95\x98\x4d\xfe\xac\x5a\x44\xad\x4c\x8e\xa6\x86\x2e\xa0\x0b\xff\xa1\xe5\x17\x30\x93\xf1\x1d\x86\x32\x89\x9c\x9f\x55\x62\xf5\x39\x6f\xcf\x16\xa9\x6e\x77\x91\xf1\xe5\xa3\x38\x40\x64\x37\xea\xea\xa4\x64\x72\x94\xd1\xc0\xf5\xdc\xef\xf8\xcf\x2e\x96\xd8\xe6\x6f\x25\x6f\x4f\x9e\xdd\x4e\x65\x2c\x8a\x05\x19\xf2\x55\x0c\xf4\x28\x55\xc6\x18\xd3\x64\x98\x92\xcd\x15\x96\x53\x2e\x53\x64\xe3\x3c\x86\x3f\x5d\xda\xac\x7f\x51\x0c\xe8\xc4\x26\x9f\x9e\x31\x85\x85\xcc\x9a\x7f\x5d\x30\xf7\x8e\xdf\x0f\x8b\xcd\xd7\x38\x98\xa6\xfb\x21\xa4\xc8\x8e\x88\xa3\x08\xf9\x34\x6f\x6f\x6f\xdd\x33\xc4\x89\xc0\x4f\x60\x78\x5a\x1e\x2a\xee\xe6\x78\x96\x12\xc6\xa9\x6b\x96\x34\x16\x75\x28\x34\xa4\xb2\x94\x0a\x4c\x11\xdd\x71\x09\x37\x55\xf5\x31\x28\x82\x66\x59\xc6\x91\x70\x4a\x16\xc0\xcb\xd7\x23\xc6\xa8\x3d\x72\x38\xe3\x49\x8c\x8e\xf7\x71\x06\x65\x39\xbf\x02\x78\x06\x18\xd7\x2c\x37\x2f\x2f\x33\x42\xf4\x2a\x13\xd2\x80\x91\x4d\x5f\xce\x7c\x70\x90\x09\x9d\x61\xfe\x81\xdb\x85\x01\xdd\xda\xef\xfc\x7b\x73\xad\x49\xaa\x34\x13\x5a\x04\x46\xa3\xeb\xc3\xd4\x77\x6e\x60\xba\xbf\x66\x52\xcb\xc8\x67\x71\x3b\xe7\xa2\xb9\x39\x2f\xb0\x4d\x6e\xfe\x7b\xaa\x38\xc5\xfb\x2c\xf9\x01\xde\x2f\x30\x4b\x59\x17\x76\x3b\x72\xb1\x6d\x5b\x1d\x87\x1e\x67\x06\x61\x8a\x29\xbb\x27\xf8\x32\x21\xe9\xe4\x5e\x20\x0a\xb2\xc8\xea\x76\x3c\xc2\xc1\xa0\x40\xc8\x55\x54\xf3\xe8\xbe\x20\x11\xc4\x68\x7e\xfc\xdc\x1b\xb6\xed\x3d\x1f\x26\x3e\x33\xe0\x34\xcb\x86\xfc\x86\x58\x5c\x72\x4d\xba\x8a\x07\x34\xc6\xd4\x0d\xaa\xb3\xdf\x40\x3b\x28\x86\xf0\x40\x12\x15\xbb\xd8\x72\x71\x30\x44\x70\x45\xd5\x3a\x08\xc1\x2f\x74\x14\x15\x0f\x20\x12\xdc\x7f\xd9\x45\x51\x0c\xc1\x2f\x3c\xd0\x44\x88\xbe\x8c\x97\x77\x2e\xa1\x3b\x46\x42\x43\x42\x7a\x5f\x15\x6a\x40\x5d\xa1\x38\x55\x19\xb5\x79\xc7\x5e\x96\x73\x7e\xce\xf0\x30\x8c\xb0\x86\xf8\x02\x26\xf6\xae\x6a\x43\x3f\xe7\x7c\x44\xde\x1d\xef\x06\x0c\xdd\xaa\x2b\x8f\x12\xa6\x61\x8a\xbd\x3e\x77\xbb\x97\xc5\xad\xbf\x80\xe0\x86\xa1\xf5\xbd\xfa\x2a\x86\x4c\x23\xf6\x78\x14\x09\xd7\x2e\xfa\x02\x32\x3f\xe6\x53\x36\x9c\x8b\xe6\x64\x77\x62\x92\x60\xb6\xef\x0b\x77\xa0\xa9\xf9\x70\x83\x34\x4f\xb5\x97\x93\x1e\x64\x81\xc6\xc3\x58\x60\x28\x9f\x4e\x0d\xd4\x5e\x30\x51\x71\x46\x22\x1a\x79\x1b\x1b\x8c\x17\x10\x67\x4c\x20\x82\xe7\xfe\xa7\x69\x44\x6d\xa6\x17\x55\x0c\xbd\x9a\x86\x57\x0d\xaf\xa8\xbf\xa8\x4a\x70\xaa\x3d\xbf\xb8\x2d\x9d\xc7\x01\x45\x3b\x65\xe0\xbc\x9d\xd7\xf6\x5a\xb6\x8e\x40\x45\xf1\x98\x18\xd2\x02\xd4\x90\xde\x82\x3c\xd5\xb9\xab\x8e\xbc\xc0\xdb\xe4\x57\xe3\x30\x64\x99\xf3\x9d\x8b\x62\xe7\xd9\x98\x07\x99\x0c\x1e\x67\x26\xe1\xca\xd5\x78\x73\xf6\x59\xbe\x41\x6a\x8a\xc7\x5c\x88\xd4\x4f\x42\x9b\x34\x98\x20\x92\x79\x2c\x43\x09\xae\x7e\x65\x69\xfe\x26\xef\x2b\xa1\x14\x0b\x9c\x46\xe2\x70\xb7\x5e\xbd\xec\xe3\xfd\xc3\xfa\x71\xed\xdf\x43\x4a\x24\x56\xad\xf1\x58\xb4\xbf\x79\xfd\x97\xd3\xb7\x56\x3c\xcd\x8c\xf4\x76\x03\xad\x43\x16\xdc\x42\xcb\xf3\xe2\x4a\x80\xcc\xb3\x28\xc4\x65\x79\xe0\x3f\xfb\x12\x3d\xcf\xb2\x10\x73\xd5\x06\x4e\x38\x49\x56\xf0\x4c\x13\xcc\xeb\x7d\xdb\xdc\x3e\x0c\xdb\xa1\xdc\xd9\xdc\x52\xb1\x5b\x02\xec\xf5\xe3\xca\x1f\x89\x24\x5a\xaf\xb7\x9a\x97\xa7\x82\xd7\xcf\x35\x38\x2c\xc2\x5f\x2c\x1b\x9e\x00\xfa\x73\xf7\xd0\x76\x0b\xbc\x8b\xa1\xc3\xc9\x9b\xe3\x5a\xdb\x7e\x3b\xd3\x71\xb5\x05\x39\xbc\x2b\x19\xc7\x58\x94\x41\x15\xb6\xd1\xcc\x51\xd4\x74\x35\x95\xf0\x75\x59\xda\xe5\x2a\x94\x9c\x38\xeb\xfe\xc8\x7f\xf6\x69\x67\x0e\x14\x0c\x38\x66\xdf\xf0\x4f\x20\x34\xfd\x6d\xe2\x1e\x71\xcd\x75\x64\x38\xd0\x70\x0f\x7d\x6a\x3f\x4f\x3d\x81\xb0\x9d\x3a\x82\x50\x8e\xd8\x00\xa3\x85\xc9\xcf\xa6\xfc\xe0\x0e\x46\x44\xd2\x3e\x7e\xf0\xe9\x94\xf1\xc3\x0b\x22\x94\xe1\x39\xc3\x06\xfe\x5f\xbf\x4c\x41\x40\x41\xe6\x9d\x5f\x50\xdd\xd6\x9d\x97\x6f\x5a\x4e\x2e\x4a\x29\x0b\x93\x81\x77\x73\x0b\x5c\xdd\xe4\x7e\xe5\x0b\xca\x14\x16\x5e\xee\x6f\x9e\x8f\x75\xf5\xd3\x99\x43\x11\x12\x89\xbe\xea\x6e\xb5\x78\xb4\x12\x20\xfb\x87\xcd\xf2\xf7\xfd\xf3\xea\x65\xbd\x71\x46\x4f\x44\x69\x86\x39\x8d\xa7\xbc\xad\xab\xce\x75\xf0\x17\x8e\x32\x8d\x9b\xf4\xf6\x98\x4b\x78\xca\xcb\x7f\x3b\x24\xad\x60\x22\xc4\xee\x39\xb3\x6a\x7b\x8e\x0e\x25\x62\x1a\x1a\x57\x0f\xb8\xda\xf1\xe6\x63\x8b\xa4\xba\xc3\x88\x19\x69\x3b\x9d\x22\x58\x7e\xe8\x82\xc8\x41\xcf\xf3\xf8\xd1\x63\x20\xc8\x08\xd2\x79\xad\xa3\x2c\xa5\x48\xa8\x21\x7b\x96\xef\x96\x7f\x16\x5b\xad\x27\x6f\x2e\xc9\xa8\x41\x0c\x20\xe7\x10\x2a\x68\xef\xaa\xfe\xdb\xfd\xb2\x2a\x2c\xd2\x38\xc4\xa4\x10\xe2\x00\x9e\x79\xdd\x9e\xb7\x50\xce\x68\xdc\xfc\xcf\xff\x0e\x4b\x6c\x22\x15\x01\x9a\xcc\xbc\x85\xc3\x13\x3f\xc0\x46\x4f\x6e\x2a\xd5\x46\x35\xf3\xbe\xa8\x04\xef\x39\xdd\x5e\x4b\x43\x96\x30\x30\x7d\x22\x0b\x8d\x64\xe1\x16\xda\x9b\x53\x5e\x74\x0e\x52\xe7\x1e\x9b\xd4\xe6\x64\x92\x8b\x2c\x89\xd1\x5a\xec\x1b\x03\x3d\x6d\x30\x47\xed\x23\x12\xc1\x53\x89\x45\x9b\x4f\x94\x96\xb5\xed\xd7\xd3\xd2\xf1\x68\xd1\x09\x11\x71\x2c\xba\xef\xad\xb5\xc2\x1f\xde\x55\xa6\x2c\x38\x61\xb5\x54\x42\xc8\x90\x99\xef\xca\x6b\xf9\x7e\x73\x7e\xea\x59\xf6\xec\x08\x29\xcc\x2e\x53\xdb\x84\xf0\xa2\xb9\x60\xe1\x19\xdf\x80\x14\x4c\x5b\x9a\x52\xdb\x6a\xe0\x9e\x46\xea\x10\xed\x01\x94\x0d\x5a\x0b\xfb\x67\xa5\x69\x64\xbb\xff\x06\x40\x1c\x01\x89\x8c\x4c\x17\xf6\x27\x72\xed\x74\x9e\xe6\xf1\xe8\x8f\x76\x9f\x64\x10\x1b\xb9\x3f\x67\xd4\x02\xdb\xdb\x9b\xca\x34\x3b\xce\x66\x71\x85\x66\x86\x29\x42\x5a\x1d\xc2\x87\xaa\x6d\xc1\xbb\x25\x42\x33\x43\x17\x86\xdb\xcd\x80\x36\x63\x32\xdf\xb4\x50\x28\x5d\xb2\xda\x7d\x5b\xbd\xfc\xfe\xfa\xe4\x4f\x57\x31\x66\x81\x17\x4a\xdd\x57\x95\x6a\xc6\x68\xcf\x91\x6d\x19\xff\x75\xfc\x4f\x7a\xb9\x5b\xca\x20\xa0\x58\x40\x30\xf5\xda\xaa\xb8\x1a\xfd\x4e\x78\x28\x94\x0c\x94\x61\x90\x33\xf9\x78\x43\x3d\x32\xe6\xde\x74\xd3\x42\x12\x6a\x7a\x71\xf7\xed\x9c\xfc\x97\x92\x34\x0c\xd0\x09\xd8\xca\x77\x38\xb8\x84\x2a\xaf\xfb\xc3\x0a\xf3\x6b\x50\x4b\x12\x33\x4f\xef\xba\x3d\x1d\x8f\xc8\xae\xbc\x7f\xaa\x96\x5c\xbe\x4f\x64\xad\x6d\x52\x48\x86\x61\x84\xcd\x64\x8f\x4f\x0f\xbb\xfb\xd7\x27\xb7\x05\xca\x90\x65\x2c\x18\xd0\x7b\xbb\x97\x3a\xfa\xb0\x32\x84\x10\x03\xc3\x3d\x92\xf5\x9f\xda\x5d\xb5\x9c\x6d\x76\xff\x65\x95\x40\x46\x9c\x4b\x2f\x41\x1c\xdd\x73\x37\x2b\x25\x0b\x25\x7a\x72\x05\x6f\xda\xbb\x1a\x60\xc0\x34\x88\xfa\xbf\xf8\xdc\xb6\x6f\x73\xea\x2d\xca\x38\x34\x42\x6d\xef\xbc\xee\xe2\xe1\xb1\x91\x91\x71\xc4\x74\x8a\xd8\xe1\xa2\xe0\x2d\xd4\xbc\x30\xf9\xae\x89\x22\xb1\x92\x31\x37\xdc\x03\x97\xa5\xd9\xc9\x38\x9d\x86\xe0\x6a\x2b\x53\x30\x8c\x8c\xb5\xc6\xec\x2c\x3a\x7c\xa0\x1e\x40\xbd\xc1\x50\x60\x50\xc9\x34\xe6\x98\x59\xb3\x1c\x38\x37\xe7\xb5\xfa\x6d\x98\x57\x93\xa9\x10\xe8\x18\x60\x9c\xb5\xd1\x24\x08\x02\xc7\xd0\xec\x85\x2b\x94\x4c\x55\x82\xc9\xf2\xbd\x29\x25\x60\xd9\x6b\xfa\x66\xb2\x34\x44\x8c\x80\xe8\x66\xe5\xaa\x54\x0d\x0b\xdc\xe9\x9c\x30\x8c\x86\x87\xa4\x40\xbd\x63\x28\x79\x18\x26\xe6\x70\xdb\xb9\x18\xef\xf0\x9f\x13\x5c\xca\xa2\x76\xe3\x34\x0a\xbc\x69\x47\xc7\xa6\xa4\x20\x3c\x8b\x7a\x95\x31\xd4\x17\x1b\x9f\x24\x74\x92\x59\xd2\xc5\x1e\x44\x7b\x61\x06\xa4\x0a\xe3\x94\x4c\x73\xe6\x75\xce\x8b\x6e\x93\xbb\x12\x1a\x49\x95\x00\xba\x12\xdd\x4c\xfa\x47\xe3\xbd\x2d\xa9\xd2\x24\x0e\xfb\x0e\x96\x9b\xd3\xb9\x73\x22\x56\xbb\x6f\xfd\x80\x14\xab\x79\x2d\x34\xed\x63\xae\x54\x81\x92\x49\xf2\xfd\xa9\x6a\x57\x3f\x07\x6f\x06\xb8\xe6\x03\x9e\x7f\x67\xdb\xa4\xe6\x94\x24\xc6\x69\x7b\xe9\xbe\x7d\x37\x27\x6e\xf2\xa2\x18\x7a\xdd\xa3\x5b\x55\xa4\x33\x3a\x56\xf2\x60\x50\x06\x51\x84\x84\xda\x0a\xc6\x3f\xf2\xba\xce\xf9\x9b\x0f\x2d\x15\x61\x86\x76\x6a\x08\x7f\x9d\x41\xcc\x2b\x22\x62\xd7\x27\x6d\x79\x68\x1e\xab\xd2\x91\xb2\x29\x15\x32\x05\xa9\x6f\xfd\x78\x86\xfa\x66\xb7\x74\xc7\x22\x02\x38\x3f\xa7\xbd\x04\x93\xbb\x67\x01\xd3\x8e\x5e\x6f\xa0\x2d\x75\xcd\x6c\x4e\xc2\xe9\x81\x9f\xa0\x58\x28\xa5\xaf\x35\xae\x97\x1b\x9c\xf7\x7f\xa9\x34\xe8\x4e\x4e\xd2\x84\x4e\x5d\xa8\xe1\x8a\x54\x0c\x88\xf0\x49\xa3\x79\xa4\x97\x62\x10\xa7\xc3\xd7\x8a\x3e\x71\xb3\xab\xe6\x5e\x6d\x1c\x11\xcc\x69\xb5\x39\xd4\x4f\x53\xb6\x7e\xa5\x62\x95\x64\xa6\x55\xca\x4e\xd9\xb1\x2c\x9c\x52\x89\x4c\xb1\xe5\x1a\xef\xe7\x07\x4c\x10\xe6\x2a\x25\xae\x42\x68\x3c\x83\xe7\x81\x23\xab\xd2\x90\xe2\x0e\xb1\x37\x04\x22\x43\x50\xc8\xfc\x22\x52\x19\x0b\x1d\xb9\xda\x6b\xa3\x56\xed\xfb\x0c\xc0\x5b\xf1\x38\x56\x3e\xe9\x59\x77\xc7\xdb\xb9\x80\x5b\x71\x49\xb0\xae\x61\x91\x8e\x98\xfc\xb8\xc2\xdb\xdb\xc5\x1a\x46\x59\xe7\x4b\x8e\xd4\x16\x3b\xff\x2c\x0d\xdd\x4a\xbb\xe3\x79\xb1\xf4\xd2\xe8\x86\xd1\xa8\xb9\xab\x6a\xc8\xdf\xca\xa7\xaa\x5d\x97\xaf\x8d\x13\x55\xed\xfc\xaa\x84\xb9\x3c\xb5\x1a\x81\x74\xba\x19\x8d\x26\x65\x59\x95\x0d\x94\xad\x99\xb3\xf9\xe7\x15\x1b\xae\x54\x68\xe6\xff\x1b\xb4\x18\x7e\xb9\xcb\xe8\x90\x60\xfa\xb4\xb3\x1e\x28\xda\x34\x71\x70\x94\x0e\x8d\x66\x7f\xa5\x35\xd4\x4b\xde\xba\xea\xdd\xfc\x2b\xd0\x82\x1a\xfb\x7b\x3a\xaf\x7c\xbc\xac\xb4\x4e\x23\x13\xcc\x9a\x06\xa1\xff\x3b\xe9\xc6\xdf\xda\x6d\x21\x60\x34\xec\x5b\x05\xbf\xe7\x4d\x8e\x4a\x13\x7f\x5b\xc3\x73\xfc\x30\x10\x30\x8e\x1f\x7f\x97\x97\x7c\x90\x57\x85\x20\x09\xdc\xbb\xc4\x57\x36\x87\xa7\x85\x40\x05\xc8\xff\x7a\xe0\xed\xfb\x34\xe9\x33\x11\xc9\x54\x40\x82\xc4\x48\x63\x74\x8b\x19\xdb\x59\xdb\xaa\xed\x6d\xcc\x24\x25\x0a\x84\x19\x7e\x8f\xdc\x11\x53\x0e\x13\x94\x40\x63\x40\x6a\x16\x83\x1b\x45\x68\xd1\xaf\xa3\x51\xa0\x09\xd0\x6c\x54\x76\x30\x97\xa5\xd7\xcb\x0e\x40\x45\x18\xd2\x71\x03\xa7\x21\x99\x19\x04\x31\x40\xb5\x21\xa0\xb8\x7d\x18\xf2\x76\x2b\x08\x93\x10\x9b\xde\x90\x17\x60\x44\x2f\x73\xf1\x6a\x42\x0e\x71\xaf\x2a\x87\x49\xdd\x19\x3e\x1a\x88\x08\xb7\x5d\x6e\x65\x55\xe6\x7f\x82\x9a\x54\xe7\x21\xa2\x01\x7e\xcc\x23\xcf\x1d\xc3\x8c\x9e\x5e\x23\x94\x98\xe3\x7c\x59\x7d\x5f\x6f\xd7\x9b\x27\x7f\x6a\x96\x19\xca\x08\x0c\xd3\xee\xa6\x1b\x03\x44\x3c\xf1\x84\xcb\x17\xd5\x17\x88\x94\xc4\x3e\xb6\xed\x7b\xf5\xb5\x77\x95\xc3\xf9\xef\x10\xe9\x88\xf0\x81\xc0\x78\xf7\x76\x3a\x2b\x81\xfd\xc6\x83\x37\x34\x49\x07\x01\xe3\x31\x33\xfe\xe2\xa4\xed\x68\x7c\x9f\x71\x0a\xb8\xfd\x5a\x3a\xf8\xdd\xb7\x5d\xb5\x3c\x35\x6d\x75\xb8\x56\x6a\x86\x58\x84\x58\xfa\xf3\xbd\x83\x0f\x15\x2f\xa1\x76\x94\xe2\x93\x27\x8d\x81\x5a\xd6\xbc\x76\xc9\xeb\xa1\xc2\x82\x4b\x76\x41\xac\x23\x24\x26\xe8\x02\x60\x5d\x95\x30\x5c\x56\xb1\x8e\xd2\xa8\x57\xdc\x72\xa5\x85\xf9\xa5\x9e\x70\x8d\xd3\xef\xab\xf3\x17\xaa\xba\xa7\x04\x55\x90\x52\x69\xe5\xba\xf3\xb2\xf1\x7e\x94\x3f\xca\x42\xa6\x87\xdd\xb5\xb6\x90\x3d\xbe\x7c\x2a\x0d\x57\x9c\xed\x90\xf9\x5e\x4d\x3a\xb5\x49\x1c\x0c\x42\x22\x48\x15\xc7\x1d\xf7\x66\xb5\x7a\x59\x6e\x7c\x32\x10\xb2\x30\x33\x75\x23\x74\xc0\x71\xde\x3a\xc7\x06\x78\x6c\x24\xd3\xf2\xe6\xdb\xe9\xc0\xcb\x99\x0a\x31\x70\x30\xb5\x33\xdc\x38\x2f\xe7\x1d\x87\x54\x1a\x21\xf1\xfa\xe3\xb6\x2a\xc7\x59\x12\x10\xcc\xd4\x21\x8e\x1e\x1e\x36\xbc\x63\x11\x87\xc2\xba\x20\x26\x1d\x30\x1b\xde\x82\xa4\x29\x16\xab\x34\xb4\xf2\x1d\x17\x9f\x31\x35\x93\x51\x71\x80\x20\x6e\xbb\x9b\xb9\x27\x94\xd2\x60\xbb\x8d\x9a\x0d\x52\x11\xf7\x2d\x11\xa0\xa2\x4c\x8a\xa1\xc0\xd0\xf8\x9a\x88\xf7\x35\xb2\x73\xdd\xd1\xbb\xaa\x1e\x0a\x05\x4d\x66\x83\xd2\x12\xe3\xcc\xdd\x3b\x3c\xe4\x6f\xef\x23\xe0\x0e\x80\x22\xd8\x81\x7e\x34\xdd\x26\xdd\x06\x0c\x63\xdc\x1b\xe8\xd8\x88\xfd\x70\xf5\x09\x65\x7b\xaa\xa7\xd1\x01\xe8\x34\x0d\xb4\x53\x63\x80\xe3\x65\x59\x0f\x74\xaa\xd1\x86\x7e\xdb\xec\x76\x1b\x7f\x9a\x12\x99\x91\xae\x2a\x8a\x4d\xfd\xfb\x80\xe5\xe5\x7f\x58\x6f\x52\xe3\xff\x1d\xd9\xe5\x2b\x85\x04\x1d\x44\x21\xb6\x24\x20\x82\xe8\xd9\xf0\x0c\xcd\xaf\x5b\x1d\xc4\xa1\xd5\x5c\xb0\x2c\x12\x2b\xef\x09\xeb\x20\x05\xe1\xbb\x6e\x97\xfc\xd8\xf2\x7c\xec\xc4\xf6\x3f\x98\x01\x16\x67\x9f\xa0\x68\x90\xe2\xa7\xdc\xa1\x78\x6f\xff\x6e\x75\x20\x03\x07\xbf\xb2\xf4\x1c\xcd\xf5\x3d\x43\x93\x34\x41\x47\x52\x55\x6f\x86\x49\xc3\xfd\x5d\x00\xb3\xd5\x8f\xf5\x7a\xbd\x7f\x99\x54\x89\x35\x65\x14\xd3\xd9\x7f\x4b\x35\xb5\x1b\x2e\xc1\x04\x2c\xe5\xea\xa7\xbb\xad\xc9\x17\xd5\x34\x31\x8e\xe5\x43\xf5\x36\x92\x9c\xbe\x15\xaf\x65\x0f\x5a\x1c\x4f\x4a\x4d\x33\xe3\x7b\xb7\xc0\x0f\x9f\x83\xce\x13\x4d\x55\x2a\x9d\x40\x26\x34\x58\xc2\xee\xb6\xa0\x63\x55\xb7\x2f\x20\x21\xff\x04\xa3\x64\x3b\xbe\xd1\xd0\x22\x61\xfb\x9e\xf3\x71\x91\xc3\x0d\x0b\x25\x76\x4f\x0e\x92\xb9\xce\x43\xd4\x61\xc4\x1d\x38\x6e\xf1\x56\x03\xa8\xa5\x49\x44\x75\x4f\xd2\xf9\xbb\x38\x85\xc8\x55\x8d\xa7\xc9\x9b\x8b\x88\xd0\xa6\x6d\xe2\xad\xe6\x2d\x38\x09\xec\xc9\x20\x1e\xa0\xe9\x35\x3b\xb2\x6d\x76\x1f\xfb\x58\x71\x74\x99\x77\x1a\x66\x9f\x74\x24\x02\x6c\x9e\xdb\xad\x1f\x57\xfb\xd7\xe7\xdb\xc5\x6e\x35\xae\xc1\x6a\x26\x25\xae\xa7\x85\xe9\x70\xcf\xab\xf2\x87\xd7\x39\xf1\x53\x8c\xf6\x73\x2c\x9d\x38\x0e\x3a\x06\x86\x09\xe0\xfb\xd5\xd3\x3e\x18\xd5\x6f\x74\x02\x84\x27\x2e\x18\xb4\x4c\x8a\xdb\x2f\x7e\x44\x32\x9c\xff\x5b\x86\x47\x67\x2a\x26\xa1\x8b\x3b\xbb\xcd\xf4\xe6\x74\xb6\xe4\x9f\xf3\xdb\xb0\xe6\x21\x8f\x1d\x9e\xa6\x3e\x37\x2d\x2f\x7e\x60\xa7\x9c\xb3\x9b\x9a\xb3\x10\xd9\x0d\xdf\x79\xad\x64\x77\x57\x5d\xcc\xe4\x8e\x69\x9e\xd9\x8d\xc9\x90\x29\xcd\x2f\x01\x91\x0a\x24\x6b\xc1\x30\x7b\xff\x9f\x53\xfe\xe7\xfe\x3f\x7f\xce\x48\x16\x2a\x2d\x59\xa0\xec\xda\xbb\x39\xfb\x09\x63\x4c\xcf\xa4\xcd\x57\xab\x84\x6a\xaf\x0a\xd4\xbc\xdf\x9c\x7f\xd4\x79\x3b\xd0\xfc\x9b\x83\x44\x40\x10\x50\x8e\x79\x9b\xe3\xa9\x79\xbf\xe0\x72\x84\x20\xc8\x4c\x87\xfe\x3b\x78\xce\xef\xe1\xfb\xea\x06\x00\x36\x78\x62\x04\xb2\xab\x96\xef\xbc\x2c\x61\xbe\xf3\x0d\x82\x80\x9b\x5d\xcf\x37\x4b\x5b\xb7\x00\x02\x42\x43\xcc\xb1\x2e\x94\x72\x74\x54\x1e\xb4\x08\x56\x0d\x78\x46\x51\x17\x02\xd2\xed\x82\x5e\x3b\xaf\x05\x83\x9a\xec\x2f\x4c\x23\x86\xd5\xc0\xdb\xd5\xe3\xce\xff\x8d\x43\x76\x1d\x22\xeb\xca\x06\xfe\x15\x51\x4d\x90\x09\xe1\x79\xf5\xb2\x5f\x2c\x97\xc8\xab\xb3\xb8\xbd\x5d\xef\xd6\x9b\xa7\xc5\xc3\x48\xc3\x1d\x82\x28\x4b\x95\x51\x87\x6a\x61\x8f\x1f\xb8\xbf\x17\x96\x05\xcc\xf0\x7f\x6e\x2d\xef\xe2\xf8\x87\x62\x91\x68\x23\xfa\xbb\xe3\x1f\x50\x8f\x5a\xf6\x20\x88\x41\xa3\x77\x86\x0c\x41\x93\x1e\x46\x08\x12\x9e\x62\x27\xc2\xed\xea\xee\x65\xb3\xdd\xed\x1f\x37\x4f\xbb\x6f\xfb\xf5\xd3\xfe\x71\xfd\xf4\xba\x5b\xf9\xfb\x4b\x83\xc8\x08\xcc\x42\xfb\x6e\x74\x08\xae\xb8\xa5\xb3\x46\x08\x82\x34\x33\x8a\xea\xa7\x06\xea\x47\xfe\x33\x3f\x9c\xbc\x0c\x94\x89\xb4\x9e\xde\x26\x33\x24\xe5\x46\x03\xfb\x00\x2d\xbf\xd8\x23\x46\x09\x98\x6b\x3f\x29\xc3\x38\x1a\xf0\xb6\x1d\xba\x40\xbf\x9d\x04\x19\x10\xa4\x56\x65\xb4\x31\x8a\x81\xdb\x16\x8e\xee\xa1\xb3\x40\x20\x1c\xf6\xa1\x92\x1f\xeb\xd2\x36\x65\xd8\x63\x9c\x48\xd6\x87\x30\xdf\x4f\xf0\xcc\xcf\xab\xdd\xb7\x5b\xac\x50\x1b\x08\xd9\x8c\xf3\x05\x01\x4f\xa4\x8c\x07\x6e\xbd\xb2\x6a\x2d\xe3\x51\x82\x98\xb6\xa8\x6e\x07\xe8\x1c\xb4\x45\xeb\xa8\x6a\x26\x0b\x4d\x30\x23\x7f\x61\xea\xda\xcb\xcd\xea\xee\xce\xdd\xa1\xd0\x1a\xe3\x4f\xac\x4b\x19\xa9\xcf\xc6\x1d\x93\x9a\xa5\x06\xa7\x57\x14\x50\x5b\xb0\x5b\x5e\x95\x38\x3f\x06\x69\x6b\x8c\x78\x9d\xbe\xa5\xb1\x68\x8b\x52\x19\x31\xeb\xc9\x2d\x2b\x16\x40\xcf\xab\x15\x58\x5f\x66\x90\xde\x80\x40\x25\x46\xad\x6f\x51\xb4\x50\xef\x1f\x41\xe5\xdd\x92\x9b\xd5\x74\x77\x4e\x2d\x04\x90\x71\x4c\x54\x9f\xca\xaf\x9a\x1f\x27\x8f\xaf\xa9\x88\x2c\xe0\xc0\x6e\xf8\x53\xdf\x7f\x78\x29\x9d\x50\xa6\x7a\xd8\xfa\x95\x66\x52\x37\x18\x32\x6a\x19\xa5\x3a\xbb\xb8\x3b\x1f\x47\xc5\x2f\x08\xb4\x4e\x24\xf3\x20\x77\x57\x5a\xee\xc2\xfe\x0c\xdb\x24\x3f\xa1\x69\x1d\xd4\xde\x1f\xd3\x01\x62\x9a\xa0\xe6\x8d\x69\x78\x1e\x17\xdd\x80\x90\x44\x23\x30\x4e\x9c\xce\x3e\x65\x39\x7a\x66\x42\x52\x8a\xbd\x52\x5d\x78\xd4\x7f\xb9\xd9\xe8\xb3\x1b\x9c\x21\xc6\x26\x6f\x1c\x64\xf1\x8a\x76\x07\x10\x22\x33\x44\x01\x6a\x03\xc2\x19\xfb\x56\x40\x28\x61\x56\xef\x45\x3d\xe4\x1f\x30\xf3\xa9\x08\x15\x8c\x4a\x27\x42\x7c\x1c\x4e\x23\x42\x45\x8a\x38\xee\x7b\x68\x9f\x73\xff\x3a\x42\x01\xd2\xd1\x50\x1f\xf3\xcb\x0a\x23\x90\x28\x8a\x31\x2d\xf3\x99\xc3\x17\x8b\xdc\x79\x91\x10\x48\xf9\x50\x23\x25\xda\x3d\x5c\x7b\xfa\x48\xa6\x88\x92\xb1\x1d\xe6\xce\x32\x4e\x06\xa9\x10\x21\x4b\x16\x6b\xb9\x28\xa6\xdc\xab\x40\x22\x60\x91\xf5\x04\x17\x16\x1e\x39\x33\xbf\x08\x0b\x94\xe1\xc8\x7c\xaf\xab\xaf\x6d\xc1\x0f\x87\xc1\x3e\x3a\xe7\xff\x03\x61\x51\xc8\xe8\x40\x75\xa4\xd9\xe5\x45\xf1\xc8\xdb\x16\xbe\x7e\xf3\x43\x12\xec\x16\x3f\x1d\xdf\x6a\xae\x60\xd4\xdf\x0f\x84\xc5\x0c\x51\x16\x5d\x74\x5d\x62\xf7\x7d\x5b\x49\x07\x1e\x07\x12\xa7\x14\x51\xd6\xcf\xbb\x87\xa5\xfb\x5b\x12\xb0\x24\x70\x3a\xdb\x3e\x78\x05\x92\xc4\x31\x56\x41\xf6\xdc\x4a\xc7\x0d\x29\xac\x80\x24\x19\xc1\x1e\x03\x5e\xa0\xf0\xa0\xf5\x49\xfd\x36\x45\x12\x65\x4a\x0a\xa8\xde\x78\x3e\xb6\xfc\x54\x5f\xc6\xbf\x40\xd2\x94\x20\x05\xb1\xe5\x56\xc9\xcb\x37\x2f\x82\x03\x24\xe5\x3a\xb3\xaf\xc3\x2a\x5e\xd4\xeb\xf2\xb3\xca\xe5\xc4\x29\x4a\xdd\x78\x3b\x81\x06\xbd\x01\x96\x1b\x76\xf2\xa3\x4a\x91\xd4\x66\x49\x1a\x43\x2a\x3e\xf1\x08\x48\x46\x39\x52\x26\x2f\x5e\x96\xef\xfc\x97\x44\x62\x40\x32\xc6\x94\xee\xf1\x27\x37\x67\x1b\x0f\xcc\x03\x48\x81\x70\x49\xb5\x1a\x90\x22\x8d\x04\x6b\xec\x18\x11\x44\xb8\x13\x3b\x54\xc8\x90\x50\xc5\x0d\xa1\x09\x62\x90\xb7\x8b\x87\xd5\x7e\xf1\xf0\xb0\x59\x2e\x76\x3e\xa5\x05\x44\x00\x10\xc7\x13\xfe\x73\xfc\xed\x24\x0d\x13\x1b\xea\xf2\xfa\x6d\x4f\xf7\x39\x7a\xc5\xee\x68\x92\xa2\x90\x9d\xe0\xad\x7c\xdf\x37\xb3\xa8\x08\x3f\x54\xbb\xb9\xb3\x9a\x3a\x75\x44\x66\x09\x22\x4f\x0c\x45\x3d\xf8\xbc\xbe\xff\xbc\x10\xc5\x80\x9b\x5f\xc1\x25\xdc\xc0\xbc\x5b\x9e\xfe\xd7\xe8\x17\x21\x35\x49\xee\xc7\xf5\xd3\xfa\x71\xf1\xb0\x5f\x3f\x7d\x5f\x6d\x77\x3d\xf3\x11\x10\x10\x14\x3b\x0a\xdd\x9b\xfb\xe7\x89\x97\x6d\xb7\x44\xed\x71\x9d\x66\xd4\xb4\x9a\xfc\xfb\xd4\xb4\xfb\xd5\xcb\x92\xd2\xd0\xbb\x14\x83\xf5\xab\x35\x89\x4d\xf6\xc6\x56\x9b\x36\xf5\x33\x6f\x1c\x9a\xfc\x05\x46\x8a\x0f\xa3\x47\xa7\x41\x98\x60\xf4\xe1\xfa\xfa\xcb\xa6\xb7\xdb\xf3\xfe\x09\x0d\x18\x73\x49\xab\xce\x94\x9b\x6d\x0b\xc3\x0d\x95\xf3\xd2\xa0\x3a\x7e\x9b\xfc\x8a\x90\xb8\x3c\x50\xee\xd9\x3e\x1e\x25\xb6\x7f\xe0\xcd\xb5\x04\x02\x25\x49\x4c\x6d\x22\x08\xdd\x87\x66\x3a\xdb\x29\x49\x23\x74\x9c\x3f\xb1\x06\x72\xa5\xad\xce\x8d\x95\x2a\xb1\x0b\x7f\xdd\x0e\x79\x06\xc6\xcf\x43\x94\x44\xa9\x5d\x7d\x2a\x07\x58\x29\x7b\x90\x86\x86\x54\xf0\x0d\xda\xef\x55\x0b\x75\x33\x94\x57\xea\x0e\xeb\x78\xc8\xfc\x85\x75\xe0\xf9\x85\x42\x23\xaa\xd1\xdd\xed\x2b\xdc\xee\x80\x0a\x31\xd5\xfb\x63\x75\xd3\xe7\xeb\x80\x32\x96\x24\x66\xed\xbb\xbd\xd2\x6a\xb0\xd8\xe3\xb1\x10\x46\x4a\xd0\x10\x4f\x0d\xba\xa2\x86\xa6\x86\x26\x04\x90\x12\xcf\x72\xbf\x2c\xca\x37\x28\x7a\xe8\xfa\xaa\x7f\x96\x84\xa6\xa1\x69\x01\x41\x2b\x8a\xdc\xd8\xf3\x81\x0d\x4d\x43\xe2\xdc\x3c\x9f\xd3\x34\x7a\x97\x7e\x80\xc0\x1c\x96\x15\xef\xf1\x50\xa7\xda\x9b\x5d\x9a\x46\x46\xd3\x14\x29\x08\x1e\x78\xd3\x5a\xef\xcc\x1d\x4e\x0c\x24\x93\xcb\xc2\xff\x49\x70\xdc\xc9\x1f\xab\xfa\xf8\x0e\x27\xd3\x80\x71\xb7\xf8\x7d\xe5\x07\x68\x89\x4d\xd0\xb9\xac\xb6\x50\x7a\xd4\x1c\xd0\x2c\x88\xb0\xdc\xbe\xe4\x47\xf3\x2b\xea\x1a\x81\xa5\x3b\x81\x26\xae\x15\xe0\x05\x9a\x53\xe1\x67\x68\x96\x45\xa8\x91\x71\x32\x82\x6b\x36\x8d\x38\xe8\x48\x04\xca\x23\x8e\xdb\xd1\xcb\xc3\xc3\x2c\xf9\xdc\x8c\xb0\x05\x50\x9e\x99\x8f\x6d\xd6\xa1\xa9\x3a\xfe\x45\x84\xf2\x57\x39\x81\xb9\xe2\x6f\x7a\xd1\x83\x07\x54\x50\xa9\xfa\x14\xca\x6d\x55\x5e\xcc\x5c\x11\x45\x8e\x94\xa1\xdb\x82\x2c\xd0\xdb\x77\xbe\x0d\xae\x25\x89\x0a\x4c\xdb\x5b\xa9\x3a\x7b\x15\xec\xaa\xdb\x5e\xa7\xc4\x0f\x02\xac\x46\x21\x35\xe6\x0f\x93\x33\x5f\x56\x87\x03\x66\x89\xf8\x95\x55\x0a\xb1\xa5\x17\x83\x52\xdd\xe7\x7a\xba\x4e\x41\x19\xea\xb3\x76\xc8\x2d\xe3\xa7\xa3\x4e\x29\xd6\xe3\x1b\xfe\x09\xcb\xf7\x2e\x70\x29\x27\x05\x17\x08\x03\xf2\xff\xb3\xf6\x27\xcd\x8d\x23\xc9\xb6\x38\xfe\x5d\xde\xaa\x16\x77\x11\x98\x81\xff\x8e\xa4\xa8\x4c\x76\x69\x60\x93\x54\x56\x75\x5f\xbb\x46\x8b\xc1\x43\xc4\x15\x08\xb0\x30\x48\xc9\xfe\xf4\x7f\x83\x7b\x04\x26\x42\xaa\x7c\xcf\x7e\x9b\x52\x16\x23\x30\xc7\xe0\xc3\xf1\x73\x20\x36\x46\xe0\xee\xb0\xc6\xd1\x8c\x9f\x0f\x99\xf5\x46\x6a\x45\xe0\xb1\xd0\x43\x18\x17\x7d\xad\xc7\x34\x87\xfb\xa2\x1c\x7f\xec\x5f\xc9\xea\x81\xe7\xf8\xb1\xdb\x95\xf1\x7c\xe7\x55\xbf\xf5\xd8\x79\xe2\x39\x31\x21\xc9\x1e\x79\x9e\xda\xdf\xdc\x50\x22\x13\x38\x41\x4f\x6a\xc8\xeb\xee\xcd\x39\xe1\x30\x27\x33\xc4\x06\x16\x45\x36\xfa\x61\xe6\x5f\xf6\xf4\x89\x87\x01\x03\x64\xa7\x22\x0c\x8a\x29\xf4\x18\xdf\xbd\xa7\x62\x74\x75\xb7\x65\xda\x01\x71\xc6\xe3\xda\xf3\x9d\x90\x8c\xc0\x1c\x43\xff\x47\xd7\x3e\x82\x1f\x72\xcc\xe6\x7c\x58\x55\x55\x1c\x2e\x93\x6f\xe2\x0b\x8e\x91\x4c\xc9\x4b\x35\x48\x2b\x82\x17\xf0\x10\xef\x10\x39\x01\xe7\xaf\x1c\x08\x20\xcd\x07\xd4\xdd\xeb\x38\xb1\x6e\x04\x8f\xc7\x8f\x14\x45\xcc\xa1\x4c\xe9\xcf\x4e\x69\xaf\x57\x01\x05\x2f\x92\xc4\xed\xf9\x78\x45\x25\x83\xfd\x99\x97\xf5\xc4\xe3\xf0\x22\x48\x50\xde\xae\x3e\xa5\xd5\xad\xfe\x2e\x78\xb1\x1f\x32\x62\xae\xf9\x89\xf3\x09\x95\x38\xfb\xc6\x04\xd1\x9e\xf8\xee\x8f\xa6\xe2\x8a\x16\xad\x91\x55\x3a\xb5\x70\xbc\x38\xf0\xbd\x78\x98\x1e\x5b\x5b\xe2\x8d\xf9\x27\x8d\x79\x80\xdb\x11\x6d\xd8\xbf\xff\x6b\xf5\xab\xac\x34\xf6\x78\x19\x59\xb1\x98\x7b\xaa\xe5\x99\x11\x8d\x05\x2f\x06\x81\x5e\xdf\xe3\xe2\x4f\xc4\x7e\x3f\xbf\x58\xfb\xc7\x4b\xe2\x04\xcd\x42\x2c\xe4\x53\x8b\xee\x67\x4e\x70\xe1\x57\xa8\x3d\x77\xa6\x5a\x0f\x3c\x1e\x07\xc4\x76\x06\xfc\xfc\x3b\xc0\x25\xcd\x5f\x47\x66\xa3\xc7\x45\xe4\x21\x28\xf3\x9d\x67\x0d\xaf\x01\xc9\x29\xfe\xd9\x40\x79\xa5\xdc\xd3\xf8\x74\x22\x60\xc6\x51\x69\xdf\xf2\xb2\xb9\xa2\xcf\x3c\x5d\x7d\xc7\x87\x84\x01\x3e\xd5\xa6\x32\xe5\x66\x83\x44\x04\x78\x42\x0a\xac\xf9\x6b\xad\x9d\x85\xe5\x97\x83\xd6\x69\xc4\x2d\x4d\xf0\x0a\x8a\xbe\xf8\x04\x3c\xc5\x5c\xcc\xcc\xbc\x7e\xd4\xbf\xc4\x56\x0a\x9e\xe2\x12\xd3\x93\x54\xfc\x30\xc9\x4e\x9a\x3e\xc0\x19\xfa\xc5\xfb\xc5\xb7\xc5\xe8\xf6\xb4\x13\xa3\xe1\x65\x24\x20\x0e\xc0\xcf\x5d\x93\x1b\x82\xc0\x6a\x45\x2e\xb3\xae\xa8\x7c\x3a\xc0\xb5\x50\x18\x14\xe3\x4a\x7d\x4a\x1b\x0d\x3e\x63\xa1\xdb\xa7\xfe\xdb\x29\x6e\xe0\x38\x66\x6f\x9e\x22\x6e\xe7\x42\xda\xe0\x3b\x6e\x20\x4c\x52\x67\x22\x5d\xbe\xce\x55\x51\x56\x70\xee\x41\x80\x63\x94\xe8\x8c\x03\xe4\x3b\x5e\xac\xc6\xc0\x2c\x8c\xa2\xda\x9a\x25\xf0\x1d\x70\x10\xce\xcb\xab\x2a\x7d\xcd\x3f\x41\x03\x4c\x6e\xd1\x55\x12\x31\x0e\x0f\x8d\x7c\x5b\xf1\xea\x74\xcb\xd8\x0b\xbe\xab\x99\xdf\x91\x48\xb6\x26\x43\xd1\xd4\x9b\x9c\x5c\x67\x7b\x6d\x2f\xf6\x31\xc8\xa2\xd3\x9f\xa0\xd6\x3f\x2f\xbf\x8d\xce\xe0\x73\x27\x82\x4e\x8c\xfa\xb1\x50\x18\x34\x1a\x2f\x98\xbe\x2f\x34\x73\x6c\x38\xbf\x7d\xed\x2f\x79\xeb\xde\x55\x40\xd9\x50\xfb\x7f\x03\xa2\x32\xf0\x83\x44\x62\x78\x1e\xb9\xd3\x5b\x17\x6d\x7f\x58\x7c\x5b\x87\xb6\x39\x4c\x18\xce\xf3\x13\xaf\x4e\x4b\xa8\x3b\x9a\x5e\xf0\xa3\x38\xf4\xad\x9e\xf9\x9e\x6b\x58\xa8\x79\x30\x12\xf8\x11\x30\x31\xa2\xaa\xe3\x15\x74\xe0\x3f\xf0\x63\xad\x31\x98\x40\x13\x90\x90\xfa\xe3\x9a\xe7\xf9\x5c\xe4\xc0\x8a\xf1\x13\xdf\x49\xd8\x88\x0e\x64\xa3\x96\xd7\xc5\x67\x77\x94\x08\x85\xb6\xe4\xb2\x93\x4e\x58\xe4\x6a\x0f\x46\xb6\xf8\xbe\x28\x9f\xe0\x03\xbf\x8e\x3c\xf1\x49\x3a\x18\x7c\x61\x20\xaf\x15\xd4\xed\x93\xdc\xaa\xde\xb4\x5d\x38\x71\x70\x83\x6e\xed\x87\x03\xfc\xb4\xb3\xc7\x17\x3e\x33\x4d\xef\x08\xe4\xef\x7e\x26\x88\xb9\x4e\x73\xd4\xc8\xdb\x91\x8f\x6e\x9b\x25\x0b\xa2\x41\x36\x6c\x61\x9d\x08\x94\x7c\x78\x80\x57\x2e\xaf\x3b\xb8\x7c\x8a\xcb\x00\x5f\xaa\x2e\x19\x41\x5c\x50\x77\x20\xd3\x33\xcf\x26\x37\xae\x02\x87\x07\xbd\xad\xd7\x2e\x85\x76\x17\xfa\x6d\x9a\x40\xeb\x10\xdd\x13\x1b\x67\x74\x42\xed\x13\xe3\x26\x5a\x66\xeb\xfa\xf4\x9d\xe7\xaa\xcf\x84\xf8\x3a\xf1\x62\x6f\x8a\xfd\x1b\x91\xb2\xce\xba\x20\x01\x63\xc4\xd4\x52\x7d\x00\x5c\x1e\x2b\x03\xa9\x80\x80\x69\xa2\x7a\xf8\xfd\x2a\x57\x19\x9a\x7b\x37\xdf\x2f\x70\x98\x83\x2c\xee\xb5\x35\xdd\x0f\xc5\xdd\x54\x8b\x08\x02\x47\x07\x76\xc2\xe1\x7c\xd9\xd7\x70\xf1\x26\x7d\x5c\x29\x71\xb7\x7e\xfa\xf6\xa7\xbd\x01\x8f\x09\x2c\xfe\x5b\x3f\x6e\xf6\xfb\xcd\xf3\xd3\xf1\xfe\x79\xd7\x4f\x2b\xbf\xeb\xe6\x47\x08\xe9\x26\xca\x96\x21\x92\x70\xfe\x79\x43\x4f\xc4\x49\x17\x03\xde\xb5\x2b\xa0\x3d\x55\xc8\x5d\x5c\x5b\x40\xa5\xed\x09\x48\x66\x95\x67\xab\x4e\x6b\x73\x72\xd3\x91\x03\xbe\x85\x8c\xd9\x9c\xfc\x90\xd2\x0e\x82\x28\xe0\x18\x3c\x57\x69\xd5\x9e\x62\x57\x4c\xf4\x1b\x20\x88\x42\x89\x4c\x29\xab\xdd\x7a\x71\x58\xdf\x1d\xf7\x87\xc5\x2e\xe8\x0e\x8f\x03\x15\x10\x2c\x79\xc4\xe0\x3c\xc6\x62\xb6\xfd\x38\xce\xd9\xc5\xa5\xa0\x6c\xdb\x64\xa3\x09\x22\x88\x85\xdf\x63\x90\x4c\xad\xc8\xdf\xa4\x91\xcd\xb1\xb1\x07\xe8\xb9\x1f\xd3\x33\x06\x51\x57\x03\x09\x93\x79\xe3\x2f\x88\xc3\x10\x45\x2d\x2b\x27\x31\x17\xb1\x0d\x09\x85\x08\xf1\x26\x1f\x8a\xfc\x75\xfd\x13\x4a\x99\x56\x7d\x4c\x7a\x26\xfb\xdb\x2d\x57\x83\xb6\xe9\x05\x95\x13\x0c\x44\xfb\xb0\x48\x78\x8e\xf1\xc3\x74\x4f\x12\x86\x18\x9b\xcd\xd3\x61\xb7\xde\x6e\xee\x8e\x3f\x9e\x5f\x56\xdf\xd7\xbb\x61\x42\x19\x82\x84\x53\x71\x0b\x06\x3b\xdb\x25\x6c\xd1\xc8\xd9\x72\xff\x2f\x33\x5f\x01\x97\x31\x61\xdd\x08\x1f\x8a\xb1\xdb\x91\x05\x18\x88\xc8\xc1\x68\x76\x8f\xd4\x33\x42\x31\x5f\x9f\x58\x24\x49\x6c\x09\x7f\xf3\xb4\xbe\x03\x0d\xb9\xc1\x97\x5d\xb2\xf4\x6f\x00\x15\xed\xe1\xe0\xb7\x93\x77\x99\xd6\x8f\xeb\x3b\x34\xc0\x87\xd6\x4d\x20\x04\x55\xa9\xe7\x6b\x95\xda\x34\x36\x04\x32\x49\x50\x88\xf4\x5f\xee\x91\xca\x9b\x0e\x44\x9c\x40\xc6\x5b\x9f\xe9\x08\xa4\x88\x50\x11\xf8\xae\xa9\xe5\xc9\xbc\xb9\x6d\x71\xd7\x35\x6b\xc3\x56\x9c\xbe\xc3\xd7\x9a\xbb\xe3\x4f\xa7\x12\x32\x18\xb3\xe2\x75\x9f\xe6\xaf\x99\x11\xf0\x1c\x2a\x7b\x8d\x1f\x53\x71\x86\xc5\x1a\xad\x93\xd0\xfa\xbb\x9d\x89\x12\x28\x19\xca\x78\xc0\x12\x7a\x81\xbe\x09\x38\x22\xc5\x4a\x50\x8d\x84\x4d\xfe\x0e\x79\x5d\x74\xd2\x69\x9f\xb9\xa3\x8e\xbd\x26\xb8\x8e\xb2\xeb\x62\x39\x00\xc5\x43\x00\x11\x49\x83\xbe\x42\xfd\xdc\xd4\xb2\x38\x4f\x02\xd5\x01\x70\xa2\x98\x56\xad\xeb\x3d\xe1\xe5\x1e\x3b\x0e\x01\x00\x29\x0c\x5f\x4a\xd8\xac\x9e\x47\xda\x2f\x10\x68\x8f\x02\xe3\xa2\xb9\x3a\x6c\xe8\xf2\x05\x3a\x08\x10\xe1\x9f\x71\x35\x19\x87\x3a\xa2\x28\xb5\xe6\x8d\x84\xee\x96\x75\x12\x87\xa1\x4d\xea\xb4\x1f\xea\x01\xb4\x6d\x0c\x99\x55\xa9\xfe\x1c\x36\xd2\xd7\x32\xd9\x63\x78\x88\x58\xee\x33\x16\x7d\x76\x72\x2a\x10\xba\x2c\x44\x15\x0b\xac\xce\x19\x30\x6a\x42\xe8\xba\x0a\x73\x8b\xf5\x2b\x8c\x73\xe3\xa1\xeb\x39\x88\x9a\xdd\xfc\xf3\x70\x5c\x3d\x3f\x1d\x76\x8b\x15\x66\xd9\x77\x6b\x4b\x6e\x0c\xa1\x1b\x28\x47\xf7\x42\x83\x84\xdc\xe9\xe0\x17\x10\xba\x31\x78\x1d\xd1\x40\xb5\x32\x7e\xdf\xe7\xf1\xdb\xf1\x08\x0b\xdd\xc4\xf5\x4c\x1e\x70\x0c\x3a\x2a\x64\xd3\xda\x4f\x8b\xfa\x73\x91\x59\x08\xbd\x88\xf0\xe5\x97\xe2\x52\xff\x9c\x47\x7e\x40\xe8\x29\xa2\xb9\xae\xa0\xde\xf2\xb2\xce\x69\x67\xdf\xd2\x87\xb7\xca\x33\x03\x9b\xe5\x33\x31\x2e\x08\x7d\x06\x08\xaa\xeb\x23\x97\xe3\x0d\x29\xf4\x5d\x11\xa0\xf2\x91\x50\xf2\xab\x1c\x48\xe8\x1b\xed\x0c\xdd\xfa\xef\xc8\x31\x5a\x34\xb9\x62\x03\x44\xe3\x4d\x6c\x24\xee\x6f\x23\x16\xb8\x76\xb5\xd6\xd1\xef\x0f\x76\xbb\x9a\xcd\x98\x87\x41\x28\xd0\x70\x5e\x42\x3b\x5f\xf6\x39\x4f\xb3\x33\xc7\x44\xbe\xed\x10\x13\x94\xf7\x48\x76\xef\xaa\x38\x5f\x78\x7e\x9d\xad\xcc\x86\x30\x48\x02\x8c\xf6\x76\xd0\x10\x50\x37\xa1\xcc\xce\x1a\x0e\x03\x45\x49\x21\x9b\xad\x47\xb8\xa2\x69\x0b\x1d\x2a\x95\xc9\x40\xd7\x51\x30\x79\x8d\x61\x04\x11\xeb\x24\x1d\xfb\xea\x8b\xb1\xcb\x13\x86\x22\xc0\xa5\xbf\xc9\x53\x4b\x07\x87\x5a\xf0\x04\x35\xb2\x9d\x40\x31\x65\xf9\x54\x4a\x0c\xa5\x62\xa9\x5c\xf9\x8d\x57\x04\x85\x37\x1d\x23\x3f\x44\x9b\x53\xb7\x5f\x62\xca\x09\x00\x61\x14\x12\xdd\xc3\xfe\x83\xe7\x65\xd1\xf9\xd3\x61\xa4\x15\xca\xb9\x12\x6f\x31\x29\xa5\x8e\x9f\x26\xf6\x78\xd4\x83\x1d\x6e\xf6\xa5\xf1\x65\x62\xe9\x7b\x24\x21\x76\x0f\x9f\xc2\x43\x4c\x5f\xee\x08\x87\xea\x9c\x72\x75\xe6\xe5\xdb\xb6\x28\xb2\x43\x2f\xa2\x08\x21\x4f\x14\xae\x87\xa8\x45\x48\x21\x64\x0a\x73\xcc\x0a\x2b\x40\xc8\x05\x95\xd8\x6f\x9e\x36\x87\xcd\xe2\x61\xff\xb2\xdd\x3e\xfc\xcb\x9e\x4c\xc4\xdc\x35\x5e\x2b\x71\x78\x52\x0e\x62\x7c\x06\x91\x44\xc8\xb6\xb1\x7d\x5e\xb8\xec\xb7\x5b\xe1\xe0\xd8\xf6\xe3\x52\x8a\x89\x2e\x25\xca\xf4\x7c\xb9\x6b\x87\x42\x51\x9d\x41\x09\xfd\x76\xbf\xae\x4f\xf7\xc5\xad\x3e\xe6\xd4\xf5\x08\xa5\xaf\x7d\x2a\xb7\xad\x7e\x81\x51\xff\x93\xbf\xf6\x5c\xdc\x43\xd6\xaf\x63\x45\x8e\x5e\x7a\x03\xca\x9e\x4c\x1c\xa9\x94\x7d\x79\xb6\xf8\x06\x11\xb3\xe3\x5e\x20\x7c\x32\xe4\x97\x8b\xe7\xa7\x87\x8d\x2d\xd0\x84\x10\x54\x84\xea\xc2\xdf\x8a\x4c\x91\x5c\x68\x53\xe6\xed\x00\x19\x2d\x2a\xa0\x19\x12\x2d\x12\x41\xca\xc1\xd6\x75\xf5\xd9\x95\x50\xbb\x7e\xc7\x4a\xf2\x48\x7c\x3c\xdd\x9b\x18\x9e\x2a\x62\x71\x88\x95\x5d\x07\x38\x5f\xb2\x2e\xea\x67\x1b\x85\x87\x2a\x8d\x3b\x54\xab\xff\x91\xc2\x07\x69\x02\xbc\x43\x06\xd3\xe4\x71\xe4\xc4\xe0\x69\x43\x2d\x9a\x22\xb0\x6f\xc7\xd3\x31\x80\x12\x22\x47\xfa\x54\x8a\xd0\x7e\x9c\xbc\x36\xd2\x8a\x03\xbb\xc4\xbe\xa2\xc8\x51\x41\x68\x2b\x0b\xa8\x76\xa6\xfd\x00\x97\x22\xff\xac\x86\x00\x22\x97\x33\x4c\xc8\x2c\x5e\xed\xa2\x10\xb9\x22\xf6\x94\xdd\xd4\x96\xed\xdb\xba\x8e\x7c\x8f\xc8\x95\x04\x22\x25\x72\x17\xaa\xe8\x1d\x30\x02\x42\xe4\x79\x1e\x46\xd7\x48\x9b\xbb\xf5\x91\x3b\x44\x7d\xdb\x18\x61\xfc\x86\x3e\xf4\x7d\x56\x4c\x61\x28\x91\x17\x7b\x98\x0f\x3b\xa1\x1f\x4a\x9f\xca\x6e\xae\xf6\x2c\xbe\x41\xed\xbf\x02\xd6\xc3\x2e\xb2\xb4\xff\x04\x7e\x1c\x23\xdf\x7a\xfb\x71\x74\x51\x9e\x5f\x28\x13\x04\x5d\x3b\x04\x91\x25\x7f\xb9\x91\xdd\x83\x28\x60\x3a\x34\xd9\xd3\xa7\x34\x87\x69\x6b\xec\x23\x61\xfb\x66\x7b\xbf\x1f\x25\x81\xfe\xfb\x13\x17\x22\x0a\xa4\x17\x42\xcf\x47\xf8\x88\x3b\xcc\x53\xa1\x6c\xd1\x22\x44\xa1\xc7\x2d\x65\x1a\x39\xd7\xd0\xfa\x62\x68\x5b\x6d\xf2\x15\xcf\x95\x0d\x9b\x46\x91\xeb\x26\xba\xa3\xc0\xa3\x0a\x81\x53\x7a\x39\x0c\x92\x77\xb3\x93\x32\x8a\x22\x1f\x3f\x6a\x0e\xa0\x2a\x31\xe0\x3b\x1c\xdf\x6b\x1c\xf9\x58\x65\x70\xc9\xae\xe5\x71\xda\x26\x48\x7c\xa3\xc8\xf7\x85\xae\x57\xfc\xb2\x03\x2e\x4f\x93\x32\x61\x88\x62\x88\xe2\x2e\x61\xf2\xc0\x9b\x1c\xfb\x74\x8d\x0a\x13\x4b\x5c\xd6\x0d\xcf\x8e\x62\x46\xa3\x11\xa2\x24\x00\xaa\x67\x2e\x8b\x77\x6e\x8f\x4c\x34\xe9\x48\xbc\xfc\x7e\xa0\xa4\x0f\xa5\x97\x27\x49\xc2\xf9\xcc\x8a\x39\x05\x0f\x12\x5b\x70\x42\xea\x50\x83\xb8\x6a\xc4\xc1\x43\x43\xc8\x7a\xc0\x96\x8a\xb8\x42\x72\xee\xe6\x52\xe4\x03\x01\x7d\x73\x8c\x70\x38\xa6\x11\x6c\x40\xa8\x23\x33\x1f\x23\x69\x22\xe1\xfa\x48\x35\xb3\x59\x3d\x0f\xca\x09\x6e\xab\x3f\x6d\xf7\x38\x41\xfb\xe7\x1b\x55\x93\xac\x7f\xd6\x25\xbf\xe3\x35\x77\xa6\x97\x07\x1e\x19\x93\xff\x70\x2a\xa1\x3a\x15\x86\xa0\xd7\x6c\x24\x91\x74\x01\xf3\x86\x88\x04\xff\xb1\xde\x1f\x36\x4f\xdf\x8e\x77\x2f\xbb\x21\xb6\x23\x92\x49\x22\xbd\xde\x83\x37\xea\xf8\x7d\x76\xed\x73\x84\x3e\x44\x52\x78\xc8\xe0\xb2\x2d\x8b\x42\xdb\x13\x2a\x5f\x5b\x4f\xa4\x35\x6a\x48\xfe\xac\x6b\x54\x01\x5a\xe2\xc8\x58\x69\x46\x38\x12\x94\x6f\x01\xab\x01\x4c\x37\x0d\x1e\x18\x0f\x74\x53\xc3\xf9\xa6\x80\x02\x62\xe6\x39\x49\xdc\x27\x37\xa0\x1c\xf8\x99\xa3\xd7\x14\x33\xcf\x27\x88\x55\x6b\xdf\xef\x6f\xb2\xf0\x9f\x9a\xdf\x31\x13\x0c\x8d\x9e\x4b\x59\x9c\xad\x2b\x11\x3b\x6e\x44\x45\x36\xe8\x74\x2f\xb9\xf8\x35\x05\x62\x88\x1d\x8f\x28\x7a\x31\x66\xf8\x1d\x32\x35\xce\x39\xc5\x4e\x00\x98\xe3\xb8\x2f\x9a\x72\x51\xfe\x3f\x6f\xc2\xbf\xb6\x49\xc7\x0e\xe7\x58\x86\x7f\x22\xa1\xb8\xae\x6e\x1e\x62\xd7\x21\x72\x1b\x63\xf3\x1a\x39\xf4\xb4\xc8\xf7\xc0\xab\x22\xbf\xcf\xf8\xeb\x1c\x8a\x21\x76\x7d\x82\xfa\xdc\xaf\xd7\xc7\xed\x7a\xf7\xb8\x79\x78\x58\x77\xe7\xf4\x35\xe6\x7e\x51\x70\xb0\x77\xf2\x62\x57\x10\xfa\x8d\x78\x6d\x3a\x62\xa7\xaa\x39\x4f\xe3\xe6\xb1\x0b\x5a\x10\x71\xfd\xb9\x33\x94\x63\xcf\x01\x1c\x26\xb4\x97\x3c\xa6\xf9\x61\x8e\x6c\x07\x62\x9f\x69\x4c\x47\x3d\xf1\xaa\xe2\xcd\x70\xbf\x8e\x03\x26\xd1\x07\x50\xf0\x57\x03\x0d\x20\x80\xb4\x75\x90\xbb\x54\x55\x1c\xb8\x5c\x53\x1d\x5c\xbb\xa3\x2f\xa4\x84\xaa\xba\x83\x4b\x56\x4c\x30\x34\x71\xe0\xb3\x10\x11\x71\x45\x59\xeb\x22\x4b\x8b\x69\x3b\xf7\x31\x46\x85\x2b\x23\x5a\x2a\xea\xf1\xad\x7b\x17\x61\xa8\x2c\x3c\x73\x12\x64\x8b\x43\xc1\x11\x52\x7e\xe4\x4a\xe1\xca\xaf\xd0\x92\xcd\xae\xcb\xeb\xb2\x4c\xd5\xad\x5e\xb9\x39\x2e\xf2\x13\x8c\x82\xaf\x9f\xf7\xc7\x7d\x9a\xbd\x77\xd3\x30\x8e\x99\x03\x41\xaf\x3f\x3e\x8c\x24\xc4\x71\x24\x04\xb7\xf5\x89\x48\x36\x3d\x05\x11\xc7\x71\xa2\x90\x13\x83\x4a\x03\x67\x4a\xa1\x21\x8e\xb9\x87\x49\xf1\x0b\xbf\x76\x4b\xa9\xbd\x42\xe2\x2b\x0c\xb5\x1c\xfb\x12\x7a\xdb\xe3\x4b\xa3\x3e\xe6\x8e\x44\x4b\xf1\xf9\x71\x33\xfa\x88\x3c\x24\x66\x58\xc1\xab\xd6\xe4\x5d\xf1\xcb\xb6\x97\x52\x31\x7d\x84\xa3\x90\x73\x86\x26\x2e\x15\x5f\xd8\xb2\xa8\xcf\x66\xf0\xff\x2b\xbe\xe3\xeb\x95\x40\x18\xa9\x4a\xb2\x4a\xf0\x41\x3a\x6e\x9f\xee\x6e\x79\xa8\xac\x20\x6d\xae\xee\x20\x1b\x5b\xc3\xb1\x10\x21\xc6\xd8\x0e\xeb\xfb\x55\x77\x8c\xf6\x44\x88\xee\x11\x3a\xcc\x8f\x69\x9e\x0e\xbc\xca\x58\xc6\x01\x66\x6d\x0b\x9b\x9e\x1b\xbd\x42\x1d\x30\x34\xcb\x0c\x3a\x6c\x5e\xd0\xbe\xed\x16\x60\x60\x5e\xf1\x34\xbb\x8e\x82\xe2\xb6\x03\xf7\x3d\x73\xe3\x3d\x6f\x36\x24\xcc\x71\x98\xa9\xd6\x7c\x78\xf8\x71\x04\x95\xd6\x47\x27\x18\x99\xe8\x89\xe3\xba\x46\x6e\xed\x02\x8b\xda\x78\x30\x96\xc2\xfc\xbf\x26\x70\xe6\xc4\x89\x12\xc4\xe3\xec\xb9\x06\x4b\x04\x5d\x1d\x76\xeb\x3f\x7b\x09\x0e\x48\x1c\xae\xa3\x2e\xb5\x81\x64\xc1\x96\x0c\x0c\x12\x47\x10\x45\xdf\x8a\x97\xea\xb1\x5d\x3f\xec\xec\x48\x5c\x4e\xde\xd0\x43\x91\xbf\x1a\x35\xdd\x99\x20\xb2\x37\xc9\xef\x27\x9e\x13\x92\x28\x26\x37\x54\x57\xf6\x7c\x9e\xef\x23\x37\x95\x31\x77\xcc\x16\x3b\x9e\x30\x89\xe7\x2b\x44\x69\x2e\x9f\x0f\xc7\xf5\x03\x0a\x30\x1e\x9d\xee\x0c\xa1\xaf\xfd\x01\x25\x40\xeb\xe2\x7c\x6b\xae\xad\xb1\x52\x34\x46\x7c\xc7\x74\xf5\x19\x55\x42\x95\x90\x17\x4d\x2e\xa1\x33\x12\xef\x8b\x12\xde\x47\x4c\x66\x90\xf8\x2e\x84\x06\x26\xd6\x7d\x96\xb0\x3b\x93\x1f\xb8\xc6\x2c\x6d\xaf\x47\x4e\x80\x65\x89\x9e\xb7\x33\x13\x3f\x0a\xd1\x76\xe3\x4a\x3d\xc1\x87\x4d\x4b\xcd\x73\x45\xce\x4f\xf2\xc4\x17\x31\xf2\x02\x0a\x3e\x57\xe6\xd6\xf7\x0b\x22\xa9\xcd\x90\x5a\x9d\x9a\xfc\xed\x46\x96\x1c\x92\x30\x70\x85\x19\x8c\xb2\x48\xf3\x7d\x81\x0a\x6d\xd9\x10\x20\x98\x84\x01\x91\x7b\x9a\x62\x8e\xb3\x68\xf7\x08\x35\x45\x58\x25\x21\x90\x08\x58\xbb\x54\xb6\xcb\x4c\x4f\x4a\x30\xee\x17\x3b\xda\x11\x63\x3d\x9f\xd1\x1b\x8f\x85\xc4\x89\xfb\x50\xbc\x1a\xb2\xeb\x7d\x5d\x0c\x22\xc4\x49\xc2\x84\xe2\xd6\x42\x32\x05\x2d\x5d\x5b\x40\x05\xa2\x28\xa0\xdc\x7d\xd7\xbf\x4d\xc5\x25\x49\xac\x10\xc7\x7a\xec\x24\xef\xb7\x65\xf1\x5a\xf2\xf3\xa6\x1a\x21\x16\x13\xee\x08\x24\xba\x78\x24\x66\xf8\xb9\x20\xc5\xe4\xd4\xc2\xf3\x74\x62\x8d\x6a\x32\x9d\x9f\x8a\xd6\xac\x19\xad\x57\x89\x48\xa8\x64\xe6\xcc\x7f\x1e\xd3\x2e\x42\x78\x84\xfe\x3b\x28\x66\x30\x67\xa8\xcc\x43\x70\x95\x5c\x9e\x8a\xf9\x62\x73\x48\x14\xd7\x89\x41\xb7\x58\x1c\xcd\x2d\xb1\x1b\x24\x4a\x04\xca\xeb\xcb\x79\xf7\x27\x5e\x76\x4f\x0b\x5c\x41\x07\x49\xdb\x90\x0f\x3e\x61\xa6\x87\x04\xc0\x21\xbb\xcd\xa2\x76\x6c\x91\x91\x81\xfc\xcf\xcf\x03\xed\xc6\x60\x8c\xe0\x7f\x14\x02\xb7\xeb\xfd\x5b\x9a\x65\x13\x67\x33\xd1\xbe\x8b\x99\x3e\x0a\xd2\xd5\x69\x7f\x5d\x1d\x10\x24\xfb\xa1\x78\x5d\x96\xc5\xdb\xd4\x20\xe2\xcc\x21\xda\x68\x93\x92\x27\x32\xa1\xf9\xbb\xe1\xcc\x11\x5e\x3f\xc6\x9f\x73\xa0\x8d\x7d\xfc\x8d\x38\x0b\xa9\x5e\xc9\x0a\x16\x63\x76\x7d\x91\x95\xc0\xd5\xf5\x31\xcd\xbb\x21\xca\x59\x02\xe8\x25\xd6\xfc\x0d\xe6\x22\x71\x5f\xc6\xa9\x38\xe3\x31\x92\x14\xee\x29\xe4\x6c\x34\x85\x5e\x76\x0f\x37\xe7\x19\xee\x0e\x9c\x49\x81\x7a\xf4\xef\x29\x7c\x3c\xf2\x9f\xdf\xf8\x90\xc6\x02\xda\x81\x1b\x26\x5d\x2e\x38\x55\x69\x3d\xf1\x6d\xb9\xeb\x84\x9c\xf2\x35\x28\xba\x8e\x02\x69\xd3\x2e\x5e\x10\x4a\x4b\x57\xdd\x0e\xd2\xa2\xfc\xc6\x27\x52\x8e\xc0\xbd\x48\x63\xfc\xe3\xbe\x28\xfb\xeb\x7b\x12\x5c\x13\x77\x5e\x67\xe9\x6b\x4a\xf9\xd4\x1d\xa4\x67\xd1\x94\x43\xc1\x15\xe0\xbe\x1b\xe2\xa6\xc4\x55\xeb\x59\xb6\x8d\x7f\xaf\x28\x60\x0e\x0d\x7c\x16\x1b\x12\xe6\x76\xf0\xb5\x4b\xde\xd2\xde\x41\xd0\xba\x2c\x6d\xdb\x89\x57\x70\xf4\x8f\x83\x9c\x19\x0f\x39\xc8\x68\x18\xe8\x1d\xa1\xb1\x78\x24\xa2\x30\xee\x90\x78\xc4\xf3\xfb\x54\x6c\xdf\x26\x03\x24\x4e\x18\x3a\xd0\xad\xa3\xf9\xc8\x7f\xda\xa3\x63\x15\xa2\xdd\x51\x93\x3a\x77\x5e\xd4\xed\xa7\x25\xd3\xca\x20\x37\x74\x0d\xc8\x03\x83\x86\xa6\x1d\xe2\x3c\x61\x44\x77\x86\x35\x19\x50\xbe\x42\x2e\xaf\xd6\x12\xda\xa7\xaf\xed\xfa\xb6\xba\xe1\x4a\x01\x9e\x04\xda\xd6\x95\xa2\xa1\xf3\xd4\x4c\x72\xdf\x3c\x89\x58\x64\xf2\xe7\x66\x29\x19\x94\x82\x55\xad\x9f\x01\xe5\x74\xa2\xf3\x44\xf8\xb8\x44\x19\x18\x76\xcf\x87\x36\xab\x98\x0a\x3c\x91\x91\x2b\x86\x72\xc5\xdb\x12\x6c\xba\xb2\x04\x18\x1d\x35\xfd\x63\x4f\x01\x12\xb3\x81\x77\xc0\xf3\x39\x8d\xf9\xe6\x06\x57\xc6\x39\x53\x28\xe7\xf0\xd1\x95\x37\x5b\x23\x81\xf3\x20\xb1\xb5\xb9\x73\x26\x39\x17\x01\xc7\xb7\x72\x58\x7f\x3b\xd8\xc8\x35\x97\x7e\x88\x90\xb7\x34\x1f\xc9\xe0\xd8\x56\x4e\xaa\xda\x15\xd4\x75\xf6\x9e\xc1\x79\x4a\x63\x3c\xdc\xc6\xe7\x06\xac\x4a\x62\x8c\x95\x5e\x78\x59\x1f\xeb\xe2\xf8\x0e\xa7\x54\x0e\x2c\xee\xb1\x65\xd0\x1d\x44\xee\x22\x25\xa5\xf8\x6d\x5d\xc0\xbc\x53\xcb\x95\xf4\x30\x12\x2c\x2d\x70\x0c\x88\x1d\x67\x79\xbd\xeb\x71\xeb\x1c\x02\xe5\x53\x28\x0c\xb5\x16\xb6\x19\x97\x70\x22\x6a\x6e\xd3\x43\x07\x3c\x18\x6a\xe8\xda\x7c\xdb\x7c\x66\x40\xb0\x50\xa2\x3b\xf3\xca\xcf\x60\xb6\xd3\xd1\xf3\x08\x16\x45\x22\x19\xc0\x49\xbb\x4c\xb1\x60\x31\xe5\x73\x91\x03\x39\xe3\xbd\x8f\x24\x18\xb0\x44\x74\x65\x0d\x69\xfe\x7a\xd7\x0c\x49\x7b\x41\xb8\x2c\xd1\x24\xad\x65\x55\x44\x46\xaa\xd4\xb6\x97\xef\xe1\x20\xfd\x0f\xc8\xfe\xaa\x2e\x30\xbc\x9f\x47\x50\x4f\x5d\x3a\x56\x78\x21\x78\xae\x8d\x93\x18\x3e\x64\xdb\xe6\x3b\x3a\x36\x65\x6a\x87\xe6\x32\xe3\x31\x8d\x16\x0a\xe1\x7b\x31\x46\xa6\xbe\x43\x99\xd6\x7c\xc0\xaa\x6f\xda\x03\x37\x42\x24\x2c\x05\xce\x2a\x40\xa4\xee\x16\x8b\x7e\x6d\x0f\x8f\xf8\x44\x07\xe5\x57\x54\x9a\x32\x39\x91\x0a\xb1\x12\x35\xcd\xdf\xd3\x1a\xca\x1d\x74\x77\x1c\xb2\x10\xd7\xe3\xc7\xd3\x40\xe9\x1b\x44\x98\x78\x18\x1b\x26\x99\xf6\x01\xf3\x38\x88\xc8\xd4\x90\x56\x35\x7f\x05\x97\x02\xdf\x7d\x5b\xd0\x53\x00\x7c\x0d\xdb\x15\x31\x73\x08\xfb\x6a\x46\xcf\x91\x7f\x4a\x2d\xdf\x76\x56\x98\x03\x37\xdf\x10\xbd\x03\xe8\xc5\x4c\x40\xc4\x9e\xa0\x3c\xb8\xb5\x37\xd7\xb9\x7a\x28\xe4\xdb\x60\x75\x17\x89\xe7\x70\x77\x20\x22\x3a\x5e\xb6\x45\xe2\x09\x92\x07\xb6\x92\xc7\xcf\xdd\xeb\x48\xa2\x04\xd9\x79\xcf\x6f\x84\xa0\x6a\xc6\x09\x4b\xd3\x8b\x07\x90\x18\xe9\x91\x4e\x91\xe9\x06\x1c\x3a\x9c\xf6\x82\x2b\x17\x67\xd0\x01\xaa\x8c\xf7\x6a\xf8\xd8\x60\xcb\xc5\x0c\xe3\x4f\x35\xbd\x58\x3b\xf6\x2d\x27\xe3\x03\xbc\x43\xe6\x6c\xa9\x7e\xa6\x43\x54\x9a\x9e\x42\x12\x14\x56\xd4\x72\x07\x19\xef\x3e\x96\x8c\x48\xcd\x5c\x34\xd7\x1d\xaf\xe1\xdf\x50\x16\x5d\xe1\xd6\xf8\x5a\x32\xf1\x11\xa2\xb6\x6c\xe4\x9b\x1c\x8c\x12\x29\x14\x6e\x4c\x97\x12\xba\x5d\x6b\x50\xfa\x22\x94\xe3\xba\x66\x59\x7c\x99\x14\x0e\x0b\x70\xa4\x35\x44\x0c\xea\x37\xcd\x5f\x3f\x59\xc6\x26\x47\x26\xb4\x0b\x9f\x53\x9b\xa0\x22\x85\x2e\xcb\x3f\xd0\x1d\x3e\x4d\xe2\x7d\x5e\x28\x20\x74\x20\x30\x61\x60\x8d\x82\xb2\x7f\x0a\xc9\xdc\x00\x73\xaf\x46\x55\xb6\x23\x54\x1f\x0e\x1e\xc9\x7c\xa2\x86\x68\x37\xb8\x4e\x6f\x0d\xa4\xc3\x88\x92\xcb\x2c\xb5\x98\xa4\x20\x2b\x77\x68\x58\x48\x27\x16\x3e\xd5\x84\xb4\xd6\xd6\xb1\xdf\xb4\xc6\x2f\x4d\xba\x2e\xc9\xa0\xe9\xd6\xa4\x5a\x13\x73\xf6\x0e\x4b\x70\x09\x13\x6e\xbb\xf9\x0e\x16\x5b\x22\xfd\x1c\xcf\xb2\x61\x21\xb0\x74\x43\x85\x02\x39\x0f\xa9\x86\x3d\xd4\x47\xc6\x3c\xdb\xe4\xb9\x1c\x53\xa3\x46\xf0\xca\x2e\xb2\xd2\x17\x3e\x95\xac\x34\x02\xeb\xe0\xdf\xe6\xa7\xb4\x0c\x22\x40\x64\xe6\x3f\x0f\x2f\x8f\xf6\xd8\x40\x6a\x24\xdb\x5b\xff\x4c\xbb\xd9\x2a\x43\x21\xd1\x29\xc1\x34\x4e\xce\x9b\xba\xda\xd2\x10\xea\x3a\x48\x17\x0b\x32\xcc\x44\xeb\xab\x49\x3e\x29\xe4\x92\x91\xcf\x91\x9d\x06\x9a\xb2\x5b\xc0\x65\x14\xf8\x6e\xcf\x5c\x37\xa3\x63\x3a\x9d\x9c\xbd\xf5\x29\x23\x00\xfa\x72\x84\x32\x75\xb7\x19\xaf\xd3\x7c\x6a\x42\xc9\x48\x73\xc7\xc8\xa8\xb4\xde\x0e\xbe\xb7\x51\x1a\x50\xc6\x3a\x70\x07\x92\x7b\x13\xf6\x1b\x90\x49\x48\xf2\xbf\xc8\x3c\x59\x37\x19\x4f\x4b\x38\xae\x8a\xf3\xa5\x86\xe3\x04\xa5\x29\x13\xc1\x11\x6b\x69\xa2\xea\xdd\xa6\x84\x34\xac\x86\x4e\x40\xe2\x50\x58\x15\xd5\x27\xb9\x4c\xc9\x43\x88\x3a\xc5\x8a\xca\xf8\x73\x58\x96\x6e\x3b\x28\x5a\x4b\xcf\x3c\xcd\xab\xba\x04\xa8\xd1\x8b\xd7\x7d\xc0\x48\x0a\x8f\x00\x8f\x1f\xe9\xe4\x69\x85\x1f\x33\x0a\x61\x5f\x06\x2b\x85\x14\xca\x09\x7b\x08\xfd\xd6\x14\x9e\x8e\x6d\x36\xa9\xe2\x28\x36\xeb\xa7\x01\xd9\xcc\xe2\x51\xa4\x8a\x39\x49\xc2\x6d\x9e\x36\xc7\x6f\x8b\xc7\xf5\x71\xbb\xdb\xfc\x7b\x7d\x5c\xed\xfe\xb5\x3f\x2c\x1e\xec\x35\x15\x44\x92\x51\x7e\x68\x05\xe5\x88\x32\x0d\xa4\xd2\x1a\xb3\xd8\x47\x38\xa7\xad\xeb\xb9\x6b\xbf\xee\xeb\xb7\xf4\x1d\x6e\x47\xc7\x4c\x18\x5f\x82\x9b\x60\xf6\x73\xb7\x3e\x1c\xef\x36\x3f\x7e\xeb\x7e\x06\x4c\x42\x9b\x2c\xd1\x7d\x93\x2b\x63\x47\x77\x3d\x3c\x2f\x20\x3d\xbb\x1c\xb6\xc5\xfe\x93\xe1\xdc\xae\xda\x66\xd0\xe0\x39\x26\x6f\x40\x3b\x10\xfa\xfd\xa8\xdb\x66\xa0\x5e\x61\xfc\x21\x34\x30\x45\x66\x7a\x55\x97\xc5\xd5\x4a\x85\x51\xab\x62\xbe\xc6\xe9\x32\xe6\xce\x7c\x82\x8f\x1d\xbc\xa7\xed\x14\x79\x2a\xea\x81\xac\x08\x28\x16\x28\x4c\xf2\x18\xdc\xc1\x8d\xb2\x88\xe9\xe6\x04\x31\xd6\x9e\xe1\xb1\x36\xd0\xf1\x35\xbc\xd0\x1e\x29\x49\xbb\x1b\xcd\xaa\xfb\xd6\xe0\xc1\x1c\x94\xb5\xda\x95\xa3\x98\x88\x87\x95\x6a\xe9\x98\xb7\x63\x7a\x3a\x30\x45\x44\x08\x5b\x41\x90\xf1\xec\x6c\x68\x3b\x62\x21\xc5\x5d\x5a\x5d\x10\xf8\x59\x15\xd9\xfb\xa8\x56\x62\xf2\x84\x10\x61\x30\x04\x33\xa3\xdf\xda\xc9\xd1\xdd\xa1\x0e\xd0\xb1\x7c\xc9\x2d\xe7\xea\x0c\x45\x81\x72\x7d\xe6\x98\xec\xea\xdd\x35\xe7\xe7\x54\xa2\x43\xb1\x36\x4e\xc3\xf8\xe6\x5c\xc5\xa8\xd2\xf6\x83\x97\xea\x8b\x20\x9f\xf2\x98\x67\x75\x36\x41\xd6\xb7\xd9\x3d\xe5\x39\x11\x37\x9b\xe6\x28\x8f\xa5\xbc\x28\xf2\xa9\x4e\xec\x2a\x60\x91\x17\xed\x8a\x7c\x43\xaa\x05\xca\x4f\xe2\x91\x46\xff\x40\x33\x6a\x28\x0b\x38\xeb\x70\xa8\xc0\xe7\xa4\x4f\x50\xa7\xb5\x3c\xdd\x1a\xc5\xfd\xdb\x09\x84\x0c\x4d\xed\xe2\x52\x5d\x36\x67\xe4\x83\x41\x5a\x98\xee\x83\x38\xe1\xff\x74\x9d\x95\x63\x22\x9b\x8b\xcb\x4d\xf4\x74\x7c\x0b\x51\xac\x08\xad\x31\x54\x44\xfb\xb4\xd0\x74\xee\xf7\xdb\xa2\x8d\xf1\x1b\x8a\xfd\xc0\x1f\xe8\x29\x5a\x72\xa2\xf1\x6d\xc4\x3a\x42\x2c\xf2\xb1\x2a\xca\x4f\xd6\x67\x95\xf8\xa4\x93\x54\x9d\x8a\x8f\xd1\x1c\x4c\x04\x8b\x0c\xce\x71\x91\x65\xa6\x78\x15\x86\x04\xb6\xa0\x38\x23\xf4\xe0\xb9\x90\x6f\xfb\xae\xe6\x77\xb8\xcc\x2a\xee\x32\x1c\xf1\xaa\xb0\x04\x40\x53\x12\xc4\xb6\x8f\x26\xa1\x3b\x62\x98\xdf\xd7\xc0\xb3\x47\x9e\x37\x3c\xcb\xae\xa3\x85\x54\x89\x08\x70\x31\x3e\xa6\x7a\xfd\x0e\xf9\xe1\x04\xf9\xb3\x52\x87\xa2\xb8\xcf\xf8\x14\x33\xa2\xa4\xef\x5b\xc2\xbf\x75\x25\x1b\xc8\x3e\x29\x92\x55\x8a\x0b\xc7\x1d\xb9\xef\x33\xb5\x48\x0a\x1c\x17\x39\x08\x71\xcd\xf8\x03\xe0\xed\x39\xb7\x16\x44\xeb\xa8\x49\x62\xfd\xd4\x50\x96\x3c\x6b\x4d\xdc\x0d\xba\x3f\x5d\x17\xed\xf8\x8e\x31\x4f\xef\x90\xf5\x6b\xfe\x5e\xb4\x08\x70\x4d\x47\xd9\x8a\xfb\x51\x9d\xda\x8d\x69\x49\x87\x00\x73\x3d\x70\x07\xbe\xcd\x22\xcb\x16\xe5\x6b\xf5\x54\x2c\x3e\xd3\xeb\x9e\x9c\xc0\x11\x1a\x51\x5c\x18\x72\x7d\xa0\xd8\xcc\x7d\xca\xeb\xd1\x1a\x0f\x8e\xd4\xc4\xe6\x28\x8b\x8e\x57\x0a\xcb\x40\x28\x7d\x6f\x7b\x69\x17\x03\x7a\x5c\xcd\x2f\x21\x93\x4b\xbb\x41\x42\x0a\x82\xb8\xd2\xf7\x00\x87\xd9\x05\x1f\x5c\xc1\x02\x13\x64\x5a\xf1\x0b\x97\x03\xe7\x61\x72\x5e\x8f\xbb\x28\x2a\x63\x51\x20\xfb\xda\x82\x05\xc0\x03\x2d\x2c\xc5\x51\x51\xbe\x41\xb9\x2d\x8a\x6c\x79\x25\xd4\xee\xf8\x2c\xbe\x70\x7d\xe3\xb4\x98\x6d\xa5\xe9\x99\xf1\xbe\xe6\x7a\x04\x08\x5c\x87\x20\x46\xad\xed\xbd\x6b\x5d\x8e\x33\x8c\xa9\x94\x46\x9f\xc3\x9c\x35\xf4\xed\xe1\xbe\x40\xc7\x83\xa2\x46\xe6\x7d\x58\xec\xea\xec\xca\x07\x41\x10\x60\xbd\x98\x4a\x2b\xa2\xb0\x68\x47\x61\x07\xb8\x86\x80\x27\x98\x98\xdf\xee\x36\xab\xf5\x11\xeb\x6a\x8e\x87\xef\xbb\xf5\xfa\x88\x74\x52\xb6\x5b\x08\x01\xf7\x3b\xe9\xc3\xdf\xff\xb5\x9a\xd9\x58\x20\xf2\x14\x5a\x34\x0b\x29\xe1\x52\x43\x9f\xf8\x98\x7c\xb1\x28\x70\x48\xab\x09\x37\xd2\xef\x45\xf6\xd5\xc6\x02\x11\x04\x09\xe5\xf8\x5e\x3f\xd9\xce\xc7\xfd\x63\x87\x23\x71\xdf\x43\x21\x3b\x0c\x29\xc4\x7e\x28\xfb\x18\xfc\x3f\x8a\x34\x87\x9e\xad\x7a\x3a\xa2\xe2\x20\x0a\xcc\x16\xf0\xd4\x9c\x97\xe9\xd4\xf3\x85\x38\x54\x5a\x18\x82\x56\xd4\x4e\xb0\xfa\x0f\x00\xb1\x50\x28\x01\x6f\xe2\x8b\x9d\x5a\x30\x40\xa2\x03\x82\x10\xaa\x89\x7c\x0c\x80\x88\x1c\xd4\xf9\x7a\xbc\x1b\x55\x97\x82\x00\x8e\xd5\x90\x76\x12\xcf\x80\x66\x40\xfa\xd2\xed\x54\x3c\x4b\x55\xdd\x22\x70\x40\x0a\x07\x91\xd6\xbf\x5f\x05\x94\x46\xb8\x74\x84\x88\x33\xfd\x94\x29\x66\x45\xb1\xd7\xd6\x4b\xbc\x37\x13\xc5\xde\x8f\x72\x05\x98\x6b\xdd\xf1\x34\xbb\x92\x70\x61\xf7\xec\xca\x17\x31\xa9\x83\x63\x98\xc8\x06\x3f\x3a\xf9\x15\x00\x48\xb8\xa5\x67\xdf\x3e\x3f\x3f\x98\xec\x32\x1b\xed\x0e\xa0\x43\x89\x6a\x3b\xff\x4e\x5f\x5f\x9b\x92\xd7\xb3\xcc\x0f\xb7\xc6\xbb\x66\x3e\x71\x1a\x1d\x4e\x40\x8c\xd5\x77\xc0\xd5\xfe\x94\xd6\x83\xb0\x92\x66\x0a\x34\x1f\x44\x60\xbe\xa7\x15\x31\x5d\x35\x79\xfd\xac\xc7\x2e\xb5\x76\x62\x87\x0d\xa8\x37\x96\x96\x5e\x1d\xb4\xc3\x5d\xcc\xfd\xbd\x4b\x8f\xe6\xa2\xbf\xed\x50\x20\xda\xf5\x63\x1c\xb1\xc6\x71\x1b\xbf\x65\xed\x8a\xae\x64\x6c\xb9\x58\x2c\x5e\x6e\x58\x16\x67\xe7\xb1\xf6\x05\xc7\xa0\x5f\x53\x97\x13\xb6\x56\xd0\x81\xa3\x30\xb8\xb6\xda\xac\xba\x9f\x92\x20\x22\xa3\xaa\xdd\x32\xaf\x0b\xa5\x76\x66\x1b\x9a\x9f\x36\x3a\x48\x80\x1b\xd7\x87\xf8\x93\xbf\xde\x1f\x74\x20\x04\x66\x2a\xab\xba\x5c\x15\xb9\xe4\x75\xf5\xcb\xc9\x11\x1d\x81\xf0\x4d\x8e\x91\xa8\x9a\x7a\xfa\x27\x1d\xfb\x1e\xca\xd7\xd2\xe2\xf0\xac\x17\xf5\x09\x83\x1e\xbc\x9c\x92\x13\x7c\x0d\xde\xd0\x71\x28\x71\x35\x3a\x17\x2a\xd5\xd7\x19\x1a\xc8\x29\xb6\x5a\xc7\x91\x83\x97\x36\xea\x53\xe3\x59\xa4\x13\x27\x0a\xa5\xa9\x94\x77\xc6\x90\x30\x9d\xb8\x14\x4a\x7a\x5c\xfc\x79\x5c\x2e\x1e\x16\x4f\xab\x75\xd7\x14\xf3\x88\x54\x10\x8c\xb8\x20\xa2\x04\xfb\x1a\x33\x9d\xc8\x08\x67\xdd\x11\xb0\x24\x0f\x83\xa7\x38\x34\x4d\xde\x72\xcd\xcb\x7c\xc8\xcf\xf3\x09\xe9\xc2\x7f\xdd\x2e\xc8\x9a\x27\x2e\x09\x94\x93\xa1\x36\x85\xf7\x68\xce\x03\xe4\x9e\x39\x8e\x2a\x46\xa1\x0f\x31\x7c\xf2\x6a\xb9\xe6\x5e\x64\x55\x0d\x5b\xa7\xbc\x9d\xe6\x18\xe1\x19\xf7\x13\x49\x80\xa5\xf5\xdb\xdd\xf3\xe3\xf3\x11\xeb\x1b\x37\xcf\x4f\xa3\x12\x3b\x2d\x24\x95\xf0\x7e\x40\xda\xc9\x65\x99\x26\x19\x47\xe1\x20\xe1\x4f\xcf\x77\x5f\x16\x67\x92\x2b\x9e\xcc\x2b\x19\x53\xfc\x65\xd9\x5c\x9f\xf5\x17\x64\xc2\x7f\x33\x6c\x24\x10\xe7\x64\x6b\x3c\xce\x1a\x1c\x1a\x5c\x12\xe3\xae\xfb\x28\x9a\x55\x25\x1d\x2f\x1f\xe0\x4a\x2c\x70\x3b\x92\x0b\x08\x12\x8b\xa9\xd5\x0c\x6f\x82\x06\x4d\xbc\xa2\x17\x7e\x45\x20\x78\xfb\x4e\xa1\x1c\x7f\x87\x21\xd3\x2e\x68\xed\x31\x19\x1a\x81\xdb\x39\x7a\x55\xad\x3d\xfa\x48\xb6\x6e\x65\x07\x08\x47\x9f\x74\xf2\x1d\x89\xc1\xa3\xe3\x90\x45\x41\xeb\x20\x0a\xa2\x51\xb1\x91\x25\x67\x98\x7c\x61\x1d\x39\x46\x9b\xb1\x75\x08\xda\x77\xb6\xe5\x69\x59\xe1\x23\xfe\xb7\xfb\x3f\xdd\xd4\xd2\x91\xc6\x38\x18\xee\xb9\x86\xe3\xa2\x1b\x86\x5a\x70\xcb\x81\xd0\x99\x0c\xab\x13\xdc\x0a\x7e\x62\x7f\xcd\x18\xd3\x08\x3f\xe2\x68\x67\x6c\x79\x99\xd6\xd7\xde\xd6\x30\x9d\x1c\x4f\x73\x61\x99\x9b\x33\x78\xe5\xaa\xb8\x03\x6b\xf2\x7f\xe2\x47\x4d\xae\xe3\xc4\x4a\xa8\x9e\xa6\xee\xd3\xec\xf9\xed\x12\xa7\x99\xeb\x4a\x64\xe3\x3e\x41\x96\x15\x8e\xbd\x29\xcf\x0f\x10\x3a\xd4\x8e\xf3\xdb\x84\x69\xdb\x2e\x71\x51\x25\x33\xa5\xec\x0f\x53\xf8\x96\xf9\x6a\xb1\x5f\xf4\x41\x7a\xcd\xbc\xc8\x47\x7e\xa4\x9a\x58\x10\xfe\xb4\xbf\xfb\xbe\x83\xf1\x33\x1a\x79\x34\xaf\x26\x97\x0a\xfc\x28\xa1\x4f\x4c\x7a\x9e\x8b\x46\xa5\xdd\x79\x83\xd8\x47\x83\x7d\x95\xa5\x67\x2c\xa7\x4a\xf3\x11\x48\x4f\xb3\x30\x50\x26\x45\xb9\x3f\x1c\xb7\x0f\x8b\x7f\x59\x31\x79\xcd\x42\xe9\xe0\x0c\xba\x64\x45\x5d\xb5\xdf\xe5\xa6\x8a\xd5\x76\xd4\x09\x0b\x49\x1e\x68\x09\x75\x77\xea\x28\x09\xb8\x91\xa2\xfe\xfd\x2a\x67\x95\xf7\x35\x8b\xa5\xc1\x43\x0d\xa4\x51\x6e\xa2\xea\x9a\xb5\x8b\x36\x99\xa4\x75\x83\xa6\xcc\x88\x60\xe0\xcb\xa5\x40\xb3\x24\x4c\x28\x4b\x99\x01\x2f\xad\x48\x73\x6b\x0e\x8d\x6f\x25\x49\x5c\x87\x6a\x43\xaa\x3a\xad\x9b\x81\x74\x78\x97\x04\xd4\x8c\xbb\x04\x16\x22\x20\xe6\xe6\x35\x2f\x4a\x20\xc5\xc7\xf1\x35\x79\x1c\x60\x6d\xba\x02\x9e\x0d\x5d\x2d\xcd\xb8\xf2\xd0\x69\x36\x1c\x90\x5c\xa4\x59\xfb\xd9\x90\x62\xdf\x74\x11\x0e\x69\x9b\xed\xe5\xe9\x0c\xf2\x2d\xeb\x71\xee\x5d\x8f\xc0\xc5\x82\xd7\x37\xb8\x4e\x3e\xa8\x90\xba\xe3\xb7\x7c\xe7\x35\x2f\x27\x37\x26\x7d\x37\x96\x7d\x5c\x71\x61\xf8\x21\x0f\xc0\xcf\xc3\x50\xbd\x66\x32\xe2\x18\x5e\xcc\xe1\x67\xdd\xbf\x6d\xa7\x3b\x8f\xf2\x30\xd8\x4c\x5b\xcd\xb9\xf8\xdf\xb4\x3b\x52\x31\xd2\x15\x58\x9f\x2f\x45\x99\x16\x58\x62\xf4\xda\xdd\xba\x72\x08\x2a\xf0\x5e\x64\xcd\x19\xc9\x14\xba\x69\xa5\xb8\x8b\x99\x28\x62\xc0\xfd\x63\xf3\x74\xf7\xfc\xc7\xd1\x39\xae\x9f\xee\x06\x1a\xa9\x9a\x81\x16\x08\xc4\x29\x79\x0d\x13\xb9\x1b\xd3\x43\xb3\x04\xcb\x40\xed\x9a\x39\xac\x96\xd1\x4c\xbb\xa1\x45\x50\x99\xfd\xbf\x7d\x87\xd3\x53\x78\x2e\xa6\x33\x6d\x16\x18\x71\xca\x93\x44\x5d\xdb\x8b\x84\x0d\x0c\xf4\x1e\xd7\x82\x5e\x40\xaf\x6d\x07\x64\x74\x4b\xab\x7b\x9e\x59\x99\x87\xe1\x02\xe3\xb0\x04\xa0\x5d\xb9\x4d\x5d\xf5\xa8\x90\x41\x3b\x4c\xa9\xb0\x93\xc3\xdd\x37\xc2\x50\x07\xe0\x90\x19\xed\x52\xda\x71\x22\xda\xa5\x0c\x3c\xa9\xb9\xe0\x28\x7f\x4f\x33\x78\x85\xf9\x6c\x98\x3d\x50\xb9\xe8\x78\x7f\xa4\x75\xde\x0e\xa4\xbf\xe3\x3c\xfa\xdc\x2f\xd6\x8e\x2b\x12\x1f\x28\x3d\x0c\xd5\x98\x22\x4c\x3b\x9e\x27\xf1\xbd\x9f\xd3\x1c\xaa\x5b\x86\x10\xed\x78\x3e\x43\x4a\xf8\x7f\x1e\x76\xc7\x81\x61\xac\x1d\x2f\x08\x31\x88\x74\xbf\x58\x1d\x9e\x77\x16\x30\xa9\x1d\x2f\xa1\xcb\x49\x9e\x65\x82\xcb\xb7\xc9\x2b\xf1\x3d\x2d\xda\x57\xf2\x9d\xcb\x37\x20\x0d\x92\xd1\x94\x77\xfc\x58\x76\x7e\x4c\x91\xff\x27\x9d\x33\x14\xb4\x13\x04\xbe\xa1\x95\xe6\x65\x3d\x4e\x05\x6b\x27\x90\x9e\xd5\x35\xa3\x1a\x97\xaa\x6b\xd1\x84\x73\xbc\x4f\x79\xbd\x43\xb1\xf0\xa9\x87\x3f\x7e\xfa\xd0\xf1\xa5\x41\x93\x3c\x40\xae\x06\x6a\x94\xb6\x43\xe4\xa1\x65\xb4\xfa\xbe\x79\x5a\xef\xd7\xc7\xf5\x9f\xab\xef\x8b\xa7\x6f\xeb\xa3\x6f\x2f\x19\x05\x90\x10\x8d\xd6\xc7\x8a\x9f\x2f\x3c\x7d\xfd\x3a\x46\xa3\xdb\x41\x23\x1c\x93\x92\x7c\xe5\x35\x58\x34\xd0\x22\x57\xad\x75\xf6\x29\x0e\x64\x04\x43\xf8\x72\x48\xc4\x4e\x8c\xf8\xe4\xaa\xe6\x5a\x5b\x80\xad\x76\x62\x2f\x1c\x44\xd5\xf0\x82\x64\x2d\x53\xea\xb9\xeb\x06\xae\xd3\x3b\xfc\xb4\x0e\x0e\x25\x97\x4d\xb7\x84\x31\xeb\x8c\x2d\xd4\xdc\xd0\x4a\x44\x84\x13\x51\xa5\xaf\x69\x7d\x28\x4c\x8d\x4c\x6f\x88\x69\x27\x51\x1a\x19\x7f\xd1\x80\xea\x18\x95\xaa\x99\xc2\x52\xed\xf0\x80\x73\x5b\xbd\x59\xbe\x1b\xe6\x84\x0a\x0b\xef\x06\x01\x33\xed\x70\xa1\x63\x2a\xf5\x21\x7e\x99\xb6\xd7\xf2\x3a\x08\xbb\x98\x7e\x22\xee\x88\x8c\x9a\xcb\xaa\xa9\x53\xba\x7d\x9f\xfd\xd7\x70\xcd\x75\xa4\x1f\x60\x40\xa3\xc9\xad\x26\xb4\x5d\xd3\x1c\xa9\x5c\xd4\x8b\xa1\x55\x15\x63\x6d\x50\xcd\xd8\x93\xda\x91\xda\x45\xac\x0f\x57\xca\xb2\x60\x34\xb7\x72\xa5\xb7\x23\x45\xf9\x81\x15\x04\xbf\x7f\x7e\x79\xba\x23\x1f\x00\xdd\xff\xc5\xdd\xdd\x6e\x72\x15\x25\x04\x86\x3c\x10\xfe\x39\x9a\xcb\x4a\xc5\x6e\xd8\xc5\xcf\xc7\xd7\x00\x2f\x44\x63\x98\x94\x9c\x4c\x5c\x7a\x8e\xcb\x4e\x3b\xc0\x55\x6c\xf8\x58\x68\xb1\xb1\xe7\x07\xe9\x21\xea\x7e\x09\x55\xaa\x80\x28\xf4\x26\x41\x87\xd1\x02\xac\x7d\x1e\x82\xa5\x50\x3e\x03\xb5\x4d\xee\x4b\xcb\x08\x89\xf3\x7e\x4f\xe5\x5b\x2a\x8b\x1b\x28\xf2\xff\x27\x35\x42\xda\x65\x0e\xa7\xe4\x7d\x7a\xbe\x74\x7b\xbd\xcb\x3c\x32\x93\x8d\xf7\x67\x2a\xc5\xbb\x56\xe1\x38\x49\x8f\x35\x59\xd7\x27\xbc\xbb\xdf\x26\x67\x96\xcc\x08\xe8\xa8\x27\xf8\x30\x12\x0d\x8b\x5c\xed\x78\xfe\x56\xe8\xa1\x50\xa7\x7d\x47\xc3\xe7\x77\x99\x22\xf8\xd0\xb2\x78\x7b\xbb\x6e\x8b\x62\xc9\x4f\x15\x6e\xfc\xe4\x36\x72\x91\x01\x59\x54\xa6\xbf\xeb\xb8\xae\xc1\x93\xfd\x01\xe9\x48\xe0\x6f\xf4\x62\x5d\xd7\x4c\x10\xc9\xf3\x97\x6a\xca\x1e\x32\xee\xea\x39\x6e\xac\x3b\xea\x5f\x92\xc2\x9c\x9e\xce\xf3\x63\x5c\x2d\x88\xfe\xa1\xe3\xd9\x59\x20\x39\x36\xaa\x62\xe5\x06\x09\x11\xcf\x8f\x72\xd7\xf7\x42\x41\xbc\xc1\xeb\x9f\x69\x55\x2f\xaf\x23\x61\x08\xdb\x29\x22\xc1\x80\x15\x2f\x01\xca\x3f\x6d\x61\xc7\x2f\x59\xa3\x6e\xe0\xb9\x5d\x21\x6d\x93\xab\x8e\x6e\xda\x36\x83\x44\xac\xe5\xdd\xfe\xd0\x01\x44\x66\x86\xad\x1b\x00\xb8\x86\x85\x17\xa3\xdb\x9b\x09\x17\xbc\xed\xa6\xa9\x36\xfc\x9c\xe6\x5b\x28\x0f\x3f\xed\x65\x42\xc9\x91\x01\x1c\xce\x69\xbd\x2e\xcb\x49\x49\xb0\x76\x63\x0e\x7a\x28\x6c\x4e\xa2\x03\xbc\x86\x6d\x51\x64\xd3\xbe\x2a\xc4\x58\xdc\x1d\xfc\x74\x27\xe3\x2e\xf1\x83\xd8\xac\xcb\xc7\x6f\x3c\xbd\xcd\xdd\x76\xfd\x24\x2a\x08\xd9\x75\xed\xa9\x38\xa7\xb9\x4d\xd5\xcc\x8f\x87\x24\x60\x18\xa5\x34\xc2\x73\xa2\xc2\x77\x35\xc9\xf1\xd9\xbe\x22\xc1\xc5\x02\x2c\xe8\xd5\x46\xa0\x47\x0c\x9b\xd3\x0b\xa8\xae\xac\xf2\x88\x5b\xff\xb1\xee\xf7\x7d\x97\xbb\xcc\x31\xa6\xc3\xfe\x5a\xd5\x70\x7e\x2e\xf9\x37\x5e\xdd\x22\xe2\xdb\xae\xa4\x12\xf9\x70\xf7\x6d\xb8\x12\xba\xdc\x4d\x14\xb7\xa2\x55\x39\x3e\xf1\xa4\x4a\x48\xbb\x3c\x24\x6a\x9f\xb7\x4a\x2e\x79\x2d\x4f\x7b\xc8\xb2\xe5\xf5\xb9\x9d\x7b\x18\x0e\x9d\xbc\xce\x39\x68\xd2\xe0\x97\xd1\x08\x12\x0e\x8d\xb4\xda\xe4\x17\xe7\x87\xab\x68\x8d\xba\xae\x38\xbd\xbd\x85\x49\x78\x55\xbb\x92\x05\x58\x66\xf7\x22\xa0\x3c\x43\x5e\xc9\xd3\x96\xdc\xa3\xdb\x38\xb7\x76\x65\xa4\xe5\xc0\xde\xed\x24\x3b\x7f\x25\xba\x33\x48\xce\x4c\x4e\xaa\x04\x28\x53\xca\xb0\x4c\x15\xd1\xe5\x8d\xec\x55\xd3\x51\x79\x1e\xd2\x70\xa5\xd5\xb2\x04\xfe\x96\xe6\xaf\xab\x89\x10\x85\x76\x95\x4f\x4e\xf3\xba\x3e\xfd\x2d\xaf\x55\xf4\x8b\xbc\x56\xda\x6d\x07\x14\xb2\x83\xad\x9f\x8f\x7b\x14\xa0\x6a\xca\x6e\x30\x29\x2d\x5c\xd2\xf1\xcb\x37\xcb\xe6\x6a\x7f\x86\x40\xb2\x01\xea\xa8\x35\x6b\xb6\x50\xbe\xe4\xa9\x2c\x26\x12\xc6\xda\xd5\x8c\xfb\xdd\x60\x92\x88\xbc\x40\xb0\xd6\xc0\xd2\xb9\xbd\x29\x2d\x38\x92\xb8\xe3\xc7\x5d\xbc\xf3\x2c\x6d\x97\xcb\x21\xa2\x4c\x7b\x8c\x11\xa2\x0c\x8b\x9e\x6f\xb5\xe5\xb5\xc7\x82\x90\x26\x22\xba\xd7\x65\x71\x29\x2a\x9e\x11\x90\x6e\xfc\xed\x3d\x06\x41\x42\x89\x09\x44\xce\xe2\xfa\x96\x8a\xa6\x2e\xca\xcd\xc4\xb1\xf2\x9c\x20\x0c\x2d\xe0\x6f\x73\xc3\x66\x69\x3b\x85\x3e\x9a\x0b\x36\xa6\x65\x7f\x16\xe4\x7b\x23\xa0\x11\xeb\xfa\xfb\xfc\x8d\xf6\x5c\x26\x4c\xb9\x56\x3b\x44\x97\x93\x68\x9f\xf6\xdc\x28\xc0\x5a\xb4\xe2\xa3\x2b\xc0\xd0\x9e\xab\x24\x5a\x5e\x76\x39\xb4\xc1\xdc\xf1\xfd\x78\x4e\x80\x08\x08\x6b\x16\x76\x56\x24\xcf\xd6\x3f\x2f\x90\x77\xd8\x77\xed\x79\x3e\x23\x2b\x0c\x63\x5f\x69\xfe\x6a\x19\xa4\x6d\x87\xd0\x73\xb0\xaa\x1f\xcc\xe6\x39\xa8\x18\xd5\x5e\x1c\xfa\x38\x8c\x6b\x04\xae\x10\x1b\xef\xf8\x56\x12\xa6\x90\x85\x1d\x72\x59\x28\xe8\xa9\x90\xdd\xc9\xc6\x47\x33\xca\x67\xf6\xb0\x80\xf8\x67\xb1\x1e\xc3\xc2\xb9\x66\x28\x32\xb5\xc7\x7d\x8d\xe5\x8b\x67\xfe\x73\xdf\x08\x95\x12\xd8\xa7\xbb\x7d\x1e\x7a\x01\xef\x62\xbe\x77\xf0\x99\xd7\xe3\xf1\x90\x8a\x02\x51\xe5\x1a\x13\x16\x0b\xa5\x40\xad\xdf\x7b\x27\xc0\xe3\x9c\xe4\x97\xee\x0f\x7f\xce\x2c\x29\x9e\x88\x02\x6d\x4f\xd1\xae\xd4\xa4\x61\x6b\xfc\x1f\x2a\x1c\x46\xf2\xa6\x5c\xbd\xf4\x83\x44\x40\x18\x1a\xed\x0a\xd5\xc8\x1a\xd7\xed\xc9\x3e\xef\x09\x48\x10\xc5\xb8\xde\xad\xee\xff\xb0\x07\x4a\x97\xe0\x45\x5d\x79\x12\x61\xf1\x06\x39\xe4\x5f\x2d\x4c\xd5\x9e\xf4\xb8\x67\x76\xe7\xfa\x61\x10\x33\xd7\x9e\x0c\x38\x56\xf3\x56\x38\x17\x37\xab\xe7\x59\xc9\x6e\xed\xc9\x38\xc4\x95\x23\x6f\xce\x47\x79\xe2\x59\x06\xf9\x6b\x3f\xca\xa4\xf4\x4c\xf9\x5a\xfd\x52\xa9\x5b\xfb\xcb\x03\xc6\x1d\xd2\xe2\x24\x05\x10\x43\x27\x38\xee\xa4\x83\x24\x22\xca\x41\xae\xb6\x8d\xc8\x52\xb9\x03\x59\x94\x6a\x96\x96\x49\x7b\x5a\x04\x09\xe2\xa0\xf6\x5b\xcb\x96\xbb\x03\x94\x89\x98\xcf\x6d\x6b\x9f\x05\xcc\x93\x43\xee\xfc\x76\x6b\xb3\x0f\xe1\x33\xce\x62\xe3\x78\xdc\x95\x7c\x2a\x84\x39\x39\x95\x13\x85\x88\x83\x96\x69\x89\x5f\x27\xcd\x5f\xe9\xcb\xdc\x97\xc5\x79\x10\x41\xf3\x9d\x58\x0b\xdd\x49\x7f\xe2\x0e\xe8\xfc\x36\xb0\x9c\x7c\x47\x11\x15\x55\x2a\x8b\xa3\xfa\x3b\x32\x4a\xed\xbb\x21\xa9\x6a\x19\xc2\x26\xbc\x28\x05\x6c\x11\x66\xef\xda\xeb\x5a\x86\x32\x53\x15\x7d\x4a\x33\x65\xe7\xd7\x6f\xfd\x46\xdd\x25\x7f\xb4\xef\x1a\x2d\x16\x43\x59\xb3\xd8\xfd\x49\xeb\xf3\x40\x76\x4e\xfb\x2e\x90\x0e\x28\xa5\x2f\xcc\x8f\x9e\x08\x93\xa4\x2b\xae\x2a\x52\x09\x2b\x2c\xfb\xcf\x6e\x3f\xc4\xe4\x61\x3c\x11\xe3\xb8\xe4\xa2\x2a\xb2\xa6\x5e\x2d\xef\xec\x39\x7d\x5f\xe9\x9e\xe6\x9d\x86\xcb\xf2\x6a\x80\x89\xf3\x27\x0b\x5d\x66\x89\x23\x9e\xe0\x67\x4d\xb4\xf6\x87\xc3\x23\xbe\xa2\x8d\x8a\x7e\x1b\x40\x23\xb4\x1f\x1a\x8e\x4a\xd1\x5c\x6d\x89\xdd\x2d\x82\x42\xfb\x11\x4f\x30\xd5\x7e\x97\xf2\xa1\xbd\xe4\xc7\x2e\x57\x54\x67\x8f\x25\xbf\xad\x85\x3d\xda\xce\xfc\xd8\x0b\xad\x16\xd4\x43\x51\xd7\x50\x5e\x07\x35\x71\x9f\x3c\x41\x1c\x51\x59\xff\x7d\x2a\x90\x60\x10\x9f\xdd\x30\x7f\x7c\xf2\x06\x63\xee\x0a\x66\x53\x6b\x7d\xfd\xe5\x6c\x80\xc9\x4f\x62\xa2\xa5\x3e\xd7\xef\xf6\x36\x13\xa5\x11\x1c\x68\xe2\x1e\x26\x2a\xf3\x48\x28\x4d\x1b\x1a\x32\x56\x8d\xcf\x5d\xa2\xee\x3b\xf1\xea\xa9\x63\xd5\xd5\x3e\xe7\x1a\x4b\xc0\x57\xcf\x9b\xa7\x23\xd1\x67\x1d\x37\xab\xe7\xe3\x61\xb3\xde\x1d\xbb\x01\xc9\x95\x48\xc6\x3c\x86\x73\x78\x19\xed\x0b\x37\xb1\x72\x31\x3b\x2e\x44\x5a\x3f\x22\xc2\x6f\x88\xe1\xd2\xbe\xf0\x3c\x84\x4d\x18\x61\x53\xf4\x11\x97\x7c\x9a\xb4\xf0\x85\xd4\x01\x89\xc7\x92\x58\x5f\x5a\xe4\x03\xc6\x77\xed\x0b\xe5\xd8\xea\x17\xb4\x7a\xd0\x53\xfd\x84\x55\x5b\xfb\x02\xb4\x91\xba\xe6\xa5\x3c\x6d\xf2\x87\x41\x7a\xd8\x74\x91\xae\x63\x61\xae\x58\x1e\x33\x0e\x9a\xfb\x32\x89\x31\x7a\x42\xa3\x7a\xd7\x7e\xa8\x46\xce\x49\x71\x7d\xbd\x9e\xfb\x52\x08\x4c\xff\x49\x64\xe1\xb2\xb6\xd0\x6f\x33\x15\x1b\xda\x57\x0e\xb1\x68\xb5\xf3\x7a\x66\x57\xf3\x95\xe6\x58\xb8\xb1\xdd\xad\xe9\xab\xa1\xc8\xe0\x71\xf1\xf8\xfc\x62\xf5\x72\xb4\x0f\x51\x82\xae\xd7\x8f\xf5\xfe\xb0\xbe\x1b\x09\x11\x6a\x1f\x84\xc2\xa8\xa9\x68\xae\x7f\x98\x72\xb7\xf1\x25\x40\xba\x24\xb9\x86\x34\xbe\xe6\x47\xcd\x18\xb9\x6c\x0d\x2f\xd5\x8f\x34\xcb\x86\x0a\x4a\xe3\xc7\xd5\xcc\xc1\xa0\x5a\x96\xca\xd6\xb8\xd9\x4c\xb3\x20\xbe\x0e\x6c\xd2\x5c\x37\xbd\xf8\x88\xf6\xb5\xf4\x30\x59\xbc\x87\x7a\xb3\xdd\xfd\x36\xab\x02\xf2\x5f\xb7\xa5\xd0\x37\x86\xbf\xaf\xa5\xc6\x72\xb9\x1c\x3e\xee\x01\xb6\x9d\xec\xcb\xa6\xda\xc3\xc4\x0d\x0b\x58\x10\x40\x87\x56\xff\xd1\xdd\x4c\xc0\x42\xaa\x02\xb9\xf0\x2b\xf2\x13\x8d\xae\x10\xb0\x30\x26\x52\x47\x2a\x2b\x38\x9c\x52\xe4\x6f\xe9\x0e\xe6\xb1\xec\x89\xf2\xdb\xe5\xa6\xe4\x69\x35\x07\xd8\x6d\xfb\x6a\xee\x77\x49\xd6\xe2\xa3\xe7\xa0\x18\x74\x72\x94\x1f\x1a\xbf\x92\xb6\x8f\x35\x2f\x91\x02\x76\xfc\x30\x2e\x03\xdd\x49\xc5\x6c\xcd\x7e\x33\xdc\x12\x02\x57\x7b\x18\xf2\x59\xa5\x79\x21\xd3\xb9\x62\xc7\xe1\x70\x0c\xbc\x90\xb4\xf9\x8f\x14\x7b\x1b\x33\xa2\xe8\xc0\x8f\x3d\x6e\x66\x24\x62\x69\xff\x48\x55\x3d\xc6\xdf\xda\x28\x65\xe0\x4b\x2a\x70\x1c\x70\x64\xdd\x1b\x16\xc3\xaf\x02\x3c\x41\x20\x48\x5d\x9d\x32\xd8\xa3\x9b\x0b\x74\x80\x36\xfb\xcb\xd3\xc3\xf3\xea\xf7\xe3\x61\xfd\x74\xdc\xae\x77\xab\xf5\xd3\xa1\xfd\xbb\x79\xb6\xdb\x53\x10\x06\x12\x0b\xb3\xca\x76\x1a\xb7\xeb\xca\xea\xc7\xbe\xa7\x6a\x32\x9d\x22\x07\x90\x51\xe8\x52\x54\xf5\xbe\xd0\x08\xa5\xeb\xda\x12\x5a\x8a\xbf\x15\x85\xd2\x29\x64\x0a\x91\xec\x35\x4f\xb3\x2f\xdf\x5e\xc4\x43\xc0\x44\xed\x2b\xb1\xf7\x98\x5a\x9a\xbb\x9c\x8f\x1f\x24\x12\x91\xdf\xa9\x04\xd1\xa6\x3f\x32\x9e\x82\xd8\x8f\x48\xaf\x27\x6f\xd7\x22\xc2\xfd\xa7\xf9\xeb\xb7\x62\x52\xc1\xa3\x83\x58\xb9\x58\x4a\xf3\x47\x7a\x01\x35\x81\x91\x4e\xde\x6c\xc2\x14\x5a\x50\xbf\xe7\xc5\xc7\xf7\xe2\x83\xf8\xbf\x6d\x9b\x03\x31\x49\x4e\xdd\x17\x25\x52\x15\xdb\x06\x29\xb0\xd8\x0b\x33\xbf\x2f\xa3\x64\x25\x81\xce\x4c\x3f\xee\xf8\xc8\x9d\x49\xc9\xe3\x3f\xac\x58\x93\x0e\x84\x41\xf0\xa3\xc9\x58\x9d\x4c\x76\x64\x2f\x8b\x12\xf0\x93\x8c\xf2\x89\x28\x27\x6c\x98\x23\xfc\x19\x85\x0b\x1d\x48\x1d\xb9\x5e\x9f\xa9\xe8\x73\xb2\x81\xf2\x48\x07\xbb\x6a\x44\xeb\x3c\x4f\xf3\x55\xe3\xf9\xac\x3c\x2a\xcc\x36\x64\xee\x6b\x53\x92\xde\x7d\x00\xa5\x1c\x8b\x9f\x7a\x46\xc5\x87\xc9\x7a\xa0\x54\x12\x93\xdd\xa8\xef\xa1\x75\x89\xec\x5d\x80\x17\x20\x76\xe8\xc4\xab\xe5\xcd\xda\xa3\x59\xc8\x28\x11\x50\x97\x29\xbc\xc3\xba\x9f\x3c\xb6\x47\xe0\x91\x61\x75\x02\xf9\x76\x2b\xa5\x3c\x5b\xea\x3f\x0f\x24\xff\x24\x11\x13\x32\x2f\x0a\xc9\xf1\x95\x45\x2e\xd3\xec\x86\xc4\xe8\xbf\xff\xe7\xbf\x46\xb1\xa3\x78\x44\x3f\x3b\x71\xfb\x43\x47\x07\xe8\x07\xd1\x9c\x26\x76\xa5\xbf\x8b\xe2\x98\x43\xbd\x28\x06\x93\x35\x35\xfb\xac\xdd\x8f\x27\xfd\x54\x82\x41\xca\xd6\xb1\xfb\xd7\xb2\xb0\x52\x88\x3a\xf4\x80\x96\x18\x2a\xa4\x5b\x64\x99\xa1\x8f\xb4\x1b\x7a\xe8\xbb\xd2\x2e\x57\x5d\xfd\xd2\xd8\xf3\xed\x5e\x4b\xa0\x08\x2d\xf6\x0a\xf5\x43\x23\xdf\x96\x05\x66\xd4\xd1\x86\x30\x3d\x42\x2d\x4d\x75\x80\x09\x69\xb5\xdb\x84\x49\x9c\x8f\x47\x47\x18\x39\xb1\x8d\xc2\xec\xe0\xaf\x26\x2d\xa1\x63\x1d\x1b\x3f\x5a\xe4\x29\x24\xfd\xda\x6f\xf6\x8b\x63\x3d\xb0\x60\xc3\x88\x83\x67\xc8\xe8\xf6\x75\xa3\xf5\xad\x35\x13\x46\x2a\xc6\x10\xf2\x39\xcd\x3b\xc9\x08\x1d\xc6\x3c\xc0\x7a\x90\x77\x0c\xe2\x1c\x2f\xa8\x40\xf4\x65\x34\xcd\x1e\x28\xa9\x9a\x55\xf2\x9e\xce\xcb\x36\x69\x85\x2e\xc4\xa5\xb8\x98\xba\x92\x76\x68\x6e\x8b\xe9\x97\xe2\x8c\x21\xaf\x6d\xc5\x35\x74\x45\x87\xd3\x3e\x21\x43\x06\x7d\x5d\x34\x65\x7d\x7a\x2c\xf2\xfa\xd4\x41\x4a\xdb\x56\xe1\x19\x32\x55\x80\xf3\x67\xe1\x82\x90\x0b\x0a\xe0\x9d\x79\x55\xcd\xab\x1b\x76\x03\x94\x0b\xe5\xf9\xe4\xc0\x7d\x27\xa5\xee\xee\x5a\x4a\xa2\xc4\xd4\x3f\xb8\x7c\xbb\x14\x26\x6f\xdb\x35\xea\xc8\x12\x41\xbd\xe4\xc8\x1d\x07\x0a\x79\x7f\x47\xe5\x53\x5f\x32\xed\xb7\x27\x01\x45\x73\x0d\x1d\xdf\x45\x89\x60\xdd\xd1\x8a\x17\x0a\x07\x10\xd8\xc8\x73\x9e\x5d\xff\x03\xab\x22\x27\xb1\x82\xa1\x69\x1f\x4a\xc7\x93\x26\xcc\xff\x98\xe6\x66\x37\xb0\xb7\x2a\x0d\x21\x8f\x09\x81\x57\x15\x9c\x45\x36\x46\xcd\x87\xbe\x79\x33\xed\x3f\xec\x61\x3a\xc1\x95\x74\xf3\xe7\x61\x24\x30\xad\x43\xe5\x71\x6d\x20\x3b\x28\x8a\x47\x02\xf3\x93\xd1\xa7\xfc\xd8\xb7\xb7\xc4\x7f\x0e\xe8\x8d\x75\xa8\x38\x21\x2b\x70\x40\xb7\x4e\x21\x06\x9e\xc6\x87\x83\xe3\x61\x3e\xb8\x1d\x21\xc8\x96\x35\xde\x57\x6d\xaf\x88\x07\x26\x19\x8e\x53\xee\xae\x5f\xf5\x67\x1d\xff\x10\x80\x30\x90\x19\x22\xf3\x86\x0b\xe0\x7c\xce\xba\x3b\x2c\x44\x88\x00\x57\xea\x97\x98\x0a\x3f\x59\xd1\x34\x73\x3d\x92\x23\x7e\x28\xb8\x5a\x15\xe5\x2f\x62\x93\x22\xc6\x58\x64\x6c\x42\xb4\x4b\xe7\x9f\x2e\x62\xa1\x46\xe2\xcb\x7f\x1c\x4a\xb0\x39\x9c\x88\xc5\xa4\x6c\x53\xb5\x1f\x22\xcd\xbf\x14\x41\xd6\x11\xe3\xc4\xbd\x6d\x2d\x8b\x6d\x51\x91\x36\x46\xbe\x84\x13\xcf\xf4\xb3\xde\x81\x44\x72\x94\xe9\xd0\x9e\xab\x52\xd2\x11\xd3\x1e\xfa\x4c\xff\x68\xce\x3c\xff\x5f\x6b\x76\x46\x8e\xc7\x85\x49\x6f\x61\xbe\xc4\x68\x0b\x1c\x2d\x63\xd8\xb1\xba\x41\x5e\x45\xbe\x1f\xa9\x5e\x57\xc1\x90\x04\x8c\xaf\xe6\x07\xb1\x34\x34\x57\x3b\x68\xdd\xf9\xb1\x4f\x35\xef\x1e\x44\x7e\xa0\xdc\xb8\x07\x3b\x61\xfa\xe2\xb7\x31\x5c\x58\x47\x81\x1b\x38\x04\xfa\x7d\xfa\xbe\x38\x1c\x16\x4f\xdb\xdd\xf3\x9f\xff\x72\xf6\x87\xbd\x75\xb3\xa2\x20\x88\x70\x59\x17\xcd\x75\x53\xc3\xd9\xeb\x7f\xe7\x09\x05\x11\xc7\xb0\x85\x28\xd0\x9e\xb6\xc0\x12\x72\x1c\xee\x9a\xf2\x76\x1b\x88\x42\x47\x63\x3d\xfc\x00\x40\x60\x63\x9f\xbf\xb4\x95\x46\xa1\xf1\x94\x77\xa6\x50\x70\xb3\x9d\xf5\x36\xa3\x28\xe0\xc4\xf0\xf1\x96\x5e\x36\x79\x5a\x2f\x41\xf2\xa6\x82\xcd\xe2\xfc\x54\xd4\xcf\xaf\xff\xb7\x20\x5b\x1a\x13\xf1\xe4\x66\xa2\x30\x44\x43\x6c\xc9\xab\x54\x6e\x6a\x23\xf9\x69\x1b\x39\x29\x7a\x3d\x2b\xa4\x78\x6d\x1f\xb2\xea\xda\x80\x66\xc1\x37\xe4\x3e\xec\x4a\x1f\xe2\x4f\x3e\x6b\x04\xc2\x19\xd2\x85\x7c\x2f\xce\xf0\x23\xe5\xc4\x49\x30\xbb\x20\x47\xb1\x74\x88\xe2\x96\x5f\x37\x93\xd4\x49\x94\xa8\x18\x57\x3d\x13\x61\xb3\x44\x44\x43\x09\x31\xb3\x1c\xe3\xde\x1c\xa3\xe1\x21\x9a\xd7\xde\xf8\x8b\x44\x3b\xbd\xfe\xcf\xff\xef\xff\x7c\x94\x69\x0d\x55\x9f\x32\x9a\xb5\x41\x23\x01\x3e\xa6\x54\x8e\x14\x1d\x7f\xba\xff\x22\xcf\x19\x09\x1d\x31\x02\xd9\xd7\xf2\x34\x54\xde\xd4\x91\x0c\x34\x62\x68\xd0\x66\x24\x8c\x5b\x2a\xbb\x46\x19\xe1\x96\x0c\xf5\xe9\x25\x47\x11\xd6\xae\x05\xa4\x1b\x77\x24\xa0\xcb\x74\x2c\x1e\xa1\x23\x25\x14\x46\x7a\x2e\xe5\x08\x11\x18\x29\x0d\x06\x88\x80\x56\xd7\x28\x40\x62\xba\x80\x06\x7c\x3f\x7f\x40\x9a\xe6\x1d\xd5\xb7\x8e\x99\xe3\x60\x5d\xd6\xf7\xe7\x3f\x1e\xba\xdf\xe2\x04\xcc\x12\x6f\x15\xfd\x6f\x35\x62\x75\xec\x38\x0a\x49\x13\x72\x43\x92\x65\x8a\x55\x36\xb9\x51\x2b\x43\x46\x22\x7b\x4e\x27\x74\x99\x49\x56\x91\x42\x48\x85\x82\xce\x84\xd8\x9f\x9e\x38\x82\xc0\xef\xde\x5e\x09\x1b\xac\x7d\xab\xad\x62\xab\x8e\x5d\x47\xe2\xf3\x2e\x37\x77\xbd\x08\xad\x8e\x3d\x8f\xa3\x9f\x4a\xab\xd5\x37\x5e\x8f\xeb\x74\x74\xec\xf9\x3e\xf2\x97\xf2\x2c\x1b\x68\x52\x15\xe5\x23\xcf\xaf\x66\x50\x55\xb7\xe5\x0b\x93\x32\x06\x1d\xfb\x31\x33\x12\xcc\xc4\x7a\xbe\x99\x16\x1c\xe9\x38\x70\x34\xf3\x4c\x2e\xe2\x69\x84\xd3\xec\xfb\x44\x8e\x07\x66\xe5\xdc\x16\x13\xbf\x24\x8e\x1d\x17\x8b\xcf\x69\x91\xde\xe4\x03\xfc\x6e\xdb\x26\x87\x5b\xe3\x8c\x96\xa1\x8e\x63\x9f\x61\x08\xe8\xf7\x34\xcb\xf8\xe9\x3a\x8c\xc5\xc6\x71\x10\xa0\x87\x9a\xff\xc4\xb8\x67\xf7\x73\xac\x11\xb4\xb7\x78\xee\x7e\xd1\x81\x45\x9f\x3f\x15\xf5\xaa\xc8\xab\x9a\x77\x6b\x69\x1c\x6b\xaa\x32\xb1\x99\xb0\xe5\x75\x3b\x23\x37\x3d\xfe\xb6\x22\x8a\xcc\x66\x47\x49\x2c\x93\xbc\xea\x9e\x4d\x08\xc7\x67\xdd\x14\xe8\xb0\x72\xa3\x79\x10\xab\x30\x04\x23\x93\xbf\x35\xcc\xe6\xd3\x1e\xd2\xc3\x99\xb2\xc3\x84\xdf\xac\x79\xd2\x7d\x4e\x65\x18\x96\xd1\xa4\x9c\x43\x66\xc5\xc0\x3c\xc4\xe2\xe1\xf2\xd9\x17\xba\xd8\xd6\xc8\xa3\x68\x5e\x5a\xff\x67\xf4\x9a\x21\x71\x91\xc7\xf8\xd8\xba\x49\xed\xf6\x64\x1b\xb4\xef\x21\x3d\x43\x3b\x3a\xf6\x87\x7f\xce\x7e\x3f\xed\x03\xda\x3f\x45\x99\xbe\x12\xe2\x62\x42\x29\xa2\x63\x1d\x25\xf8\x2e\x51\xef\x34\x83\x41\x21\xb1\x8e\x75\xcc\x63\xcb\x09\x78\x58\x3d\x14\xf2\x2d\xcd\xb1\xdc\x62\xfc\x68\x09\x63\x21\x3a\x8b\x05\xa2\x98\x47\xcb\x4a\xc2\x64\x82\x5b\x58\x2f\x7b\x4a\x85\x28\x5d\xbb\x8e\x70\x7f\x3e\x67\xf6\x91\x13\x47\xbb\xb8\xdc\xee\x5f\x5f\xfb\xa2\x30\x9d\xb8\xcc\x47\x5e\xb4\x4b\xf1\x81\x62\x3d\xfd\x5c\x4e\x5c\x37\x32\x90\x6a\x7e\xde\x43\xb7\x70\x27\xae\xab\x3d\xde\x99\xd0\x9f\xe8\x83\xe9\xc4\x93\x09\xb7\x72\xe8\x04\xe6\xb3\x27\x08\x22\x81\xcb\xf3\x51\x16\x4d\xa6\xfe\x18\x28\xbe\x8f\x8d\xe7\xf1\xaa\x9e\x04\xed\xe4\x40\x8b\xa2\xcc\xef\x8b\xf2\x1b\xaf\xe1\x63\xb0\x79\x0d\xac\x9a\x49\xe6\x23\x09\xc3\x04\x98\xd5\xe6\xef\x29\x8a\x3a\xb5\x36\x3b\x38\x93\x30\x11\xc8\x5a\xb1\xb8\xfb\xb1\xd9\x3f\xef\x8e\x87\x3f\xec\x84\x4b\x42\xee\xe1\xcc\x5c\xa6\xf5\x1b\x34\xdd\xfb\x8b\x12\xa2\x7c\xc7\x84\x11\x59\x89\x38\x1e\xfe\x20\x55\x4c\xe2\x83\xea\x63\x95\x49\x2c\x38\x12\x87\x9e\x8f\xc5\xe5\xc9\x92\x66\xea\x24\x06\xed\x79\x9d\x52\x74\xd1\x94\x96\x9c\x72\xce\x02\x4f\x12\x26\xb1\xb7\x40\x4d\x98\xe7\x8f\x91\x22\x8c\x4e\x12\xcf\x43\xe2\xe4\x3d\xd4\xdb\x8f\xc9\x4e\x95\x24\xb1\xc6\x38\x00\xc1\xa3\x3b\xc5\x9e\x79\x56\x46\x9d\x24\x3a\xc6\x9c\xdf\xa1\xe4\x6a\x04\x4a\x4c\xb8\xaf\x03\x52\x89\x22\x33\x0a\xab\x28\xa6\x5b\x51\xc2\x05\x47\x7c\x72\x75\xe6\x59\xf6\x92\xe6\xf5\x7d\x93\xcb\xb1\xa5\x62\x7a\x0a\x16\xa1\x41\xb3\xff\xe0\x97\x76\xcf\x3e\x4f\x91\xe3\x89\x70\x13\x74\x83\xee\x17\x4f\xcb\xc5\xde\x62\xdb\x13\xe1\x09\xde\x2e\x8e\xff\xbe\x4c\xca\x44\xe7\xed\xbf\x44\x04\x44\xbf\xb1\x78\xf8\x6e\xad\xd2\x44\x79\x44\x1f\xc1\x69\xaf\x59\x36\xd7\xa1\x93\x96\x80\xe7\x81\xc1\x64\x19\x86\xda\x5d\xd1\x19\x07\x89\xf6\x1c\xaf\x3d\x61\xd1\xd4\xfe\x5d\x91\xf7\xbf\x27\x2e\x5a\xb4\x7b\xc9\x67\x04\x77\xed\x2a\xc7\x99\xe4\x14\x2b\xf9\xe0\x97\x2d\x31\x80\x8e\x1f\x9c\x3b\x9e\x8f\x36\xf3\x43\x3b\xbc\xd4\x72\x58\x6e\xf6\xb5\xb5\xf9\x05\x24\x7d\xf4\x99\xb8\x13\xc4\xa8\xb8\xad\x78\xcd\x05\xd6\x38\x0c\x93\x3d\xdc\x09\x04\x26\x9f\x76\xeb\xfd\x7a\xf7\x63\x7d\x77\x7c\x3e\x7c\x5f\xef\xf6\xc7\xfd\xe6\xce\x7e\x06\xee\xba\x1a\x4c\xea\xa4\x9d\xca\xcf\x37\x21\x69\xee\xfa\x60\x88\xfa\x72\x85\x69\xae\xaf\x3f\x14\xf7\x62\x8d\xb0\xd4\xa7\xc5\xd3\x66\x3c\xac\xb8\x1f\x24\x8e\xec\xb0\x12\x0f\xc5\x6b\x2a\x7f\x40\x79\xbb\x0a\xf1\xc0\x0f\x6c\xaa\xce\xca\x8d\xec\x0a\x31\xdd\xd4\x79\xc0\x5d\x84\x27\xda\xea\x87\x55\xa1\xb5\x2d\xcc\xd4\x3c\x14\x12\x73\x32\x0f\xc5\xeb\x2b\x28\x4c\x4e\x6f\x56\xcf\x9f\x7e\x82\x39\x42\x5a\xac\x62\xe8\xd7\x01\x1e\xb9\x2e\x96\xa8\x61\x1c\x85\xec\xb3\xfb\x2c\x7d\x3d\xd5\x93\x04\xc1\xe4\x95\x44\x31\xd5\x71\x54\xfc\x3d\xed\xfc\x04\x1e\x0b\x40\xcf\xff\xc4\xe5\xdb\x5a\x35\x92\x4f\x89\x8e\x34\x4f\x3c\x15\x1a\x0d\x44\x7e\x9d\x2a\x4e\xd9\x3e\xc2\xf7\x8d\x48\xae\x69\x39\x14\x7f\xd8\x1d\x66\xea\x03\x72\xee\x91\x94\x3a\x32\x1b\x3c\xf6\x90\xb0\xae\x83\x12\x3e\x42\x14\x24\xcf\xd5\xf5\x81\xe7\x28\xed\x34\xb9\x24\x44\x4a\x12\xa3\x37\xe9\xfa\x76\xb2\x54\xdd\xb3\x01\xd7\x48\x00\x71\x38\x95\xc5\xc7\x6d\xe9\xb6\xe6\xda\x0b\x71\x6c\xca\xac\xa8\x60\xa5\x2e\x7f\x33\xa8\x74\xe4\xa1\x5f\x9a\xf1\xaa\xbe\x11\xee\xd3\x5c\x73\x4a\xbf\x51\xe0\xf2\x33\xae\x12\xdb\x59\x78\x98\x79\xf8\xe7\xcb\xe2\xa9\x0b\x2a\x72\x2d\x35\x22\xd3\xd3\xea\x31\xcd\x07\xe6\x8d\x6d\x06\x87\xe9\x9e\x68\x69\x92\x46\xa7\x4e\x82\x39\x12\x43\xe6\xcb\x95\x29\x6b\xd6\x82\x79\x64\x5a\x5f\x9a\x4f\xc2\x15\x82\x85\x24\x5c\x82\x79\xe1\xcf\x42\x1b\x5f\x12\xdf\x6a\xc1\xb4\x40\x47\x67\xf1\xf4\x6d\xfd\x30\x96\x92\xd3\xc2\x49\x1c\x0c\xd9\xd8\x68\xe5\x27\x6a\x67\xb6\x37\xa7\xcd\x74\x28\xec\x38\xc4\xfe\xcf\x6f\xf3\xc2\x91\x0c\x77\x2f\x24\x99\xf8\x7d\x42\x3b\xa2\x85\x1b\x24\x58\x0b\x86\x52\x1a\x24\x98\x35\x04\x12\x8f\xdf\x88\x1b\x87\xa1\xb2\x29\xbf\x7b\x2e\x7b\xdf\x5a\xb8\x49\x62\x44\xe5\x72\xf5\x9d\x57\xa7\xd1\x52\x25\x3c\x46\xf1\xeb\x57\xa8\x69\x72\xee\x2f\x5c\x42\x75\x4a\x2f\x8f\x85\x82\x6c\x79\x9d\xa2\xef\x84\x17\x90\x60\xcf\xf2\x69\x79\x7c\xdc\x3c\x91\x1c\xdf\x66\x69\x2f\xe7\x85\x02\xd5\xda\xdf\x5b\xa3\xdf\x00\x13\x6d\x9b\xef\x40\x24\xfb\xdd\x45\xf2\xaa\x1e\x23\x31\x27\x6f\xc8\xe7\x8e\x0b\x5d\x02\xb5\x63\x3b\xc4\x18\xc0\xf8\xf9\x7d\x0e\x68\xaa\xfd\xf1\xfd\xf9\xb1\xbb\x9a\x70\x11\xfa\xa5\x80\xab\x2c\xcd\xe1\x58\x0d\xad\x3e\x11\x24\x94\xe0\x5e\xd7\xa7\x1d\xe4\x9d\x16\x99\x16\x01\x4f\x90\x60\x11\x37\xc8\x7d\xdd\x94\xf0\x57\xd7\xa4\x7d\x44\x54\xdd\x82\xfc\xbf\x8c\xc4\x88\x30\x26\x8d\xd1\xa5\xad\x89\xd6\x22\x4c\x24\x7a\xbd\xb2\xc8\x8a\xb2\x1a\x06\x12\x44\x1c\x51\x80\x08\x69\x19\xd3\xff\xc0\xf2\x7a\x4b\x4b\xd3\xf6\x12\x60\xcd\xeb\x7c\x06\xbf\x25\x62\xee\xc5\x6a\xa0\xe8\xb8\xe5\xad\x2b\x3b\xf8\x1c\xb1\x24\xbe\x4e\xc1\xeb\x3a\x83\xc9\x5a\xb9\xe2\xf9\x12\x6c\x51\x92\x39\x20\x09\x42\xe4\xeb\x2c\xdb\xf5\xdb\xf5\x27\xd7\x4b\x84\x92\x43\x54\xe2\xaf\xe0\x8f\xcd\xa1\xdc\xa3\x67\xb9\xbc\x5f\x3a\xd0\xef\xa7\x7d\x13\xa2\x80\xa0\x1d\x71\x5f\x73\xad\xc7\x43\x9a\x27\x51\x12\x0f\x26\xef\xe3\xb5\x9e\x79\x7d\xc2\x63\xb8\xaa\xcb\x41\xa4\xa0\x1d\x58\xe5\x79\x98\x3f\x14\xc2\xa7\xe2\x08\xb4\x22\xbf\x95\xa9\x1a\x7d\x29\x11\x31\x22\xef\x48\xcf\xf0\xac\x1f\x78\xd5\xd9\xc6\xf6\x78\xe9\x29\x7c\x32\x24\x83\x31\xa4\x0b\xb6\x49\xc4\x6a\xc8\xfc\xb1\x1a\x6a\xc1\xce\x2f\x7c\x2a\x20\x0e\x82\xf5\xeb\x6b\xb5\xfb\x32\x19\x22\x54\xe8\xa0\x2a\x48\xd5\x88\x41\xd9\xb7\x16\x2a\x49\x10\x5e\x71\xe1\xad\xb7\xfc\x49\x6e\xf8\x93\x61\xac\x80\x88\x57\xef\x01\x55\x98\xec\x29\x81\x05\x46\xe5\x31\xcb\xb6\x45\xa9\x6b\x94\x5b\x99\x3f\x05\x08\x85\xdc\x92\x06\x16\xb2\xfe\x79\x49\x8d\xfe\xc5\x94\x0d\x4c\x0b\x90\x8c\x11\x37\xc0\x5f\x0d\xd2\x61\x5c\x52\x39\xfe\xd4\xa0\x42\xd7\x1b\x2c\x10\x23\xa4\x59\x6f\x84\x08\xd0\xa4\x63\x8f\x21\x17\x5b\x72\x32\xb1\xe0\x85\x0e\x3c\x34\xaf\x3f\x86\x29\x1f\xc9\xdc\x08\xb4\xcd\xd6\x5c\x17\x79\x75\x0b\x98\xb6\x1b\x81\x64\x02\x6c\xc9\xe0\xaa\x98\x16\x30\x49\x87\x01\x8f\x4d\x41\x22\x92\x35\x99\xf2\xe1\x75\xae\x06\xd4\x99\x5a\x3a\x4e\x22\x2c\x64\x75\xa7\xd3\x2e\x80\x25\xdd\x38\x44\xbf\xf0\xa9\x91\x19\x34\xd5\x0f\x44\xd5\x0e\xc0\x84\xd0\xf7\xe4\x0e\x06\x11\x9f\x77\x8b\xd5\xf3\xd3\xfc\xa7\x90\x5e\x18\x02\x65\x50\xf3\xfa\x54\x34\x15\xcf\x55\x7d\xb2\xcb\xa3\xf4\x38\xc9\x0e\xcb\xdc\x40\x6f\xbb\x16\xdf\xd5\xb8\x8a\x3f\x9f\xe1\x95\x4f\xb0\x20\xd2\x37\x89\x46\x55\x90\x36\xc5\xd7\x14\x54\x5a\x86\x5a\xa0\xf3\x6c\xb4\x6f\x96\x96\x15\x77\xfc\x6d\x64\xa8\x35\xa2\xb9\x57\x27\x44\xbc\x0c\x1c\x7b\x19\xf9\x52\x58\x35\x0e\xa4\x8f\xee\x08\x2b\xb5\x8c\x02\x91\x48\xb3\xf7\xfd\x23\x7d\x2d\x9a\x25\x91\x08\xcc\xcf\x19\x19\x85\x81\x92\x36\x7b\x55\xcb\x13\x94\xd5\x51\x5c\x8f\xe9\x2d\xe2\x4d\x46\xb1\x50\x44\x5d\x4c\x38\xae\x03\xcf\xb2\x74\x22\x2e\x3a\x3d\xbb\xf2\x6d\xbd\xcb\x80\x00\xfd\xa6\x94\x53\xc6\xa1\x42\x7f\xf3\xa5\x52\x87\x62\x4d\xd5\x1c\x44\x32\x33\xe9\x97\x84\x08\x6d\xdb\x96\x58\xcd\x96\xd7\xeb\x0c\x88\x53\xdd\x3e\x7e\x2c\xb4\xee\x01\x48\x0f\x53\xf2\x0e\x2d\xb9\x4b\xb4\xa9\x0f\x45\xf1\xb6\xa0\xcd\xa6\x3b\x98\x87\x31\xa2\xb4\x09\xf3\x63\x65\x52\x6c\x63\xac\x15\xed\x5e\x06\xa6\x0f\x18\xc3\x7c\x9b\xaa\x91\x6a\x29\x7c\x87\x68\x26\x5a\x9b\x58\xd7\xb6\x2c\x6c\x54\x75\x2d\x45\xe4\x21\x9e\xcd\x96\xf8\x3c\x22\xe9\xd2\x71\x55\x9c\xcf\x8d\x85\xc0\x75\x37\x26\x44\x84\x9e\x0e\x0a\xad\xa0\xbe\xcc\x97\xc6\xab\x14\xd2\xc5\xfd\x80\x00\xae\xcb\xe6\x8a\xa2\xa0\x37\x94\x3c\x5f\x06\x0d\xa5\xf4\x05\xb2\x3a\xac\x8a\x5c\x66\x8d\x82\x95\xc5\x53\x4f\xde\xa8\x0c\xc8\xbf\x4a\x73\x5d\x1c\xf7\x00\x87\xcd\xd3\xe2\x5c\xd4\x19\x5c\x1f\xa6\xf2\x85\x5a\x4a\x05\x3a\xe8\x11\x91\xa0\xfa\x8c\xbd\x54\x32\xd2\x04\x8f\x7b\xdd\x99\x32\xd8\xc9\x9b\x55\x0a\x02\xab\x85\x31\xa2\x11\x90\xed\x32\xdd\x07\xae\xbe\x95\x3c\xaf\x2b\x9c\xa8\xc5\x0d\xa7\x8a\x96\x10\x25\x14\xb2\x6e\xcf\x00\x25\x2a\x97\xa3\xca\x11\x15\x58\x8e\xef\x18\x62\x8e\x29\x67\x9d\x5e\xaa\x07\x78\xe5\xf2\x6a\x93\x4b\xf4\x3e\x5d\x36\xce\x0c\xda\xc3\x44\x20\x7a\x66\x84\x23\xcf\xd5\x51\xa5\xdd\x60\x02\xad\xc8\x8f\x68\xe7\x99\x89\x63\x0f\x72\xd3\x83\x85\x5c\x31\xd7\x47\x37\xca\x0e\x14\x9b\x8f\xb1\x83\x43\x31\x19\x60\xc9\xc0\x66\xf5\x6c\xd4\xd5\x4d\x83\xe3\xbb\x78\xa4\xdd\xa0\x7b\x18\xcd\x5c\xec\x53\x39\x11\xf1\x86\x63\xc0\xb9\x6c\x64\xfd\xef\x15\xaf\x4e\xab\xac\x99\x80\xb2\x94\x13\x69\xac\x81\x12\xcd\x75\x93\x53\x12\xf1\x93\x4d\x74\x6a\xc9\x28\x47\x40\x10\x0f\xa4\x31\x4d\x06\x7f\x0b\xe5\xfa\x52\x48\x9b\x1f\x51\x2e\x63\xd2\xd4\x5d\xec\x1a\x0c\xb6\x0d\xe2\x6c\xca\x55\x0a\x8c\x4a\x46\x6b\x53\xa7\xaf\x39\xa9\x90\xa1\x07\x39\x5a\xec\xcc\x01\x7e\xe4\x04\x96\x8f\x90\x98\x25\x66\x23\x25\xca\x07\xa6\xc3\x0e\x67\xdb\x4e\xfe\xd6\xad\xfd\xce\xb3\x7a\x78\xf9\x80\xe9\xc0\x2e\x04\x80\xa1\xf9\x09\xfc\x43\x05\xae\xc0\x70\xd7\xf1\x15\x6a\xc3\xe8\x6a\x9f\x2c\x50\x1e\xee\x74\xb2\x04\x95\xd6\x8f\x72\xec\x33\xab\x40\x29\x84\x3b\x96\x3c\x7f\x1b\xf2\x4f\x6a\x15\x02\x51\xbd\xd1\x29\x31\x4e\xf1\x9c\x23\x72\x0c\xee\xf8\x1c\x42\x59\xc5\x2c\x44\x39\xb8\x0f\xeb\x78\x0f\x31\xc5\x2a\xf6\xa5\xe3\x99\x7d\xe2\x5b\x0f\x80\x53\xb1\xa2\xdd\x6c\x53\x1d\x4e\x69\xd5\x15\x89\x9a\xd6\xc4\xd5\x31\x1f\x04\x06\x0d\x87\x7a\xd7\xec\xc7\xe8\x60\x50\x5d\xed\xfe\x42\x66\xc5\xf8\xb6\x12\x70\x90\x3d\x49\x95\x45\x4e\x1a\xf7\x07\xbb\x71\x4e\xfc\x2e\xc5\x95\x44\x9d\x00\x53\x20\x65\x59\x35\x7f\xeb\x9a\x49\x09\x7e\x91\x5d\x4e\x7c\xc5\xcb\x61\x08\x53\x09\x37\xc2\x6a\x42\xc4\x5a\x12\x19\x45\xff\x90\x22\xd0\x08\xd2\x53\xc5\xb2\x29\x3f\xc9\x34\x2a\xe9\xf9\x89\x71\x26\x1e\xa0\x32\x40\xfd\xc7\xe6\x86\x04\xc0\x76\x4f\x12\x8b\xa4\xfb\xfd\x52\x5c\x56\x90\x81\xf8\x44\xfe\x7b\x32\xec\x24\x44\x96\xa8\x7a\x2f\x4b\xd4\x8e\x93\x30\xce\xb4\x2a\xe5\x25\xc8\x6b\x73\xe6\x3f\xd7\x87\xef\x8b\xa6\x2e\xba\x72\xb1\xc1\xf6\xa7\x20\x08\x23\xdd\x73\xfb\x2c\x76\x93\x37\xaa\x05\x25\x47\xb8\x52\xeb\xea\xb5\x38\xfc\xf9\x4b\x85\x86\xdd\xf1\xc0\x34\x43\x87\x67\x28\x0d\xbd\x87\x5c\xfd\x0d\xaf\x9a\x06\xc7\x63\xc8\x54\xfb\xbd\x39\xf3\xdc\x44\xeb\x28\x56\xe0\xb8\xde\x14\x4b\xda\x4c\x59\xf0\x34\x38\x82\x28\x01\x8c\x4c\x22\xed\x67\xb6\x4d\x49\xdd\x21\x99\xf7\x14\x80\xac\xdb\x59\x37\xb1\xd4\xc0\xd1\x86\x34\xbe\xf5\x6c\x30\x30\xf0\xc9\x36\xfa\x37\x6f\xc1\x55\x80\xf5\x20\x02\xb5\xd9\xd0\x8c\x1f\x7d\x51\xf0\x3c\x4f\x50\x1d\xd1\x25\x85\x99\x7a\x34\xf0\xbc\x08\x09\x1a\x8c\x3c\x4d\x69\xa8\xfd\xec\x8d\x7a\x7e\x88\x84\x49\x4f\xa9\x7c\xab\x0e\xbc\xaa\x47\x99\x44\xf0\x78\x80\x0b\xf0\xea\xe5\xf0\x7c\x7f\x7f\xdc\xee\xd6\xfb\xc5\xc3\x7a\x90\xd1\x00\x0f\x22\xc3\x7b\x5f\xf7\x7a\xbf\x93\x9b\xf4\xe3\x20\xa6\x5d\x30\xaf\xea\x66\x10\x3f\x01\x5f\x9a\x51\x42\xd3\x72\x60\xba\xdd\x2c\xf4\xa3\x8f\x14\xb8\x01\x37\xc5\x24\xdf\x51\x3b\xf9\x76\x54\xcc\xa0\x85\x21\x00\x4d\x1a\x54\x55\xd5\x7c\x1a\x5e\x30\x7d\xc3\x24\xc1\xa4\xe0\x1e\xa9\x89\xb3\x54\xf2\xbc\x9e\x67\xe8\x9b\xbb\xc1\x90\x6b\x8c\xa2\xb5\xeb\x36\x06\x1d\x31\x49\x88\xf5\xfa\xfc\x5a\x34\xf5\x8a\x57\xb0\x3f\x15\x4d\xa6\x96\x70\xcf\xd3\xac\xaf\x49\x85\x50\x79\x28\x94\xf1\xca\xcf\x22\xeb\x5d\x03\x88\x1c\x27\xee\xf5\x58\x57\x77\xdb\x07\x78\x87\x92\xbf\x76\x9e\x09\x44\x8e\x8f\x76\x94\x4a\xab\xd6\x9f\x6a\x2a\x28\x15\x42\xa8\x27\x76\x23\xc4\x0e\x47\x2a\x88\x6f\x39\x2f\xb3\x2b\xb2\x2f\xd8\x73\x24\xae\x23\x49\x32\x5a\xdb\x48\x1b\x6a\x99\xf6\x3e\x14\xf0\x10\x30\xb4\x71\x31\x0e\x41\x3b\x35\x89\x97\xf7\xc6\x7b\x1b\xfd\xbd\x45\xcd\x8e\xef\x8a\xc7\x3e\xe9\xd4\xb7\xbb\x51\xd1\x74\x93\x89\x2b\xc0\x6c\xd7\x42\xc2\xfa\xaf\x26\xad\xaf\xb3\x84\x96\x37\xf2\xf2\x1a\x84\x13\x59\x92\xa0\xa7\xa2\xe6\x69\xff\x8e\x85\xa3\x95\xc9\x94\xbd\x54\x50\xfe\x28\x06\x3c\xcf\xb3\x23\x47\x78\x94\xe1\xac\x50\x09\x8c\xa7\xd9\xf3\x7b\x6b\x6d\xb7\x7d\x70\xb8\x3e\xa4\xba\x8f\xe5\x80\xf0\xa4\xdf\x5d\x18\xd5\x7e\x67\xd7\x63\x10\xc2\x47\xe2\x36\x54\xfa\x2a\x28\x94\xfc\xce\xf3\x7a\x95\xf1\xa6\xaf\x59\x05\xe9\x45\x9d\x31\xba\x6a\xca\x6d\x91\xe6\x75\x75\x8f\x40\x99\x49\xc8\x17\x94\xd6\x96\xcd\xf4\xf0\x91\x7e\x82\x4b\x07\x60\xc4\x30\x76\x36\xf0\xf2\xfd\x05\x40\x75\x31\x07\x00\x57\x20\x88\xf7\x42\xb4\x77\xc4\x57\x35\x34\x82\x01\x42\x0f\x27\xd2\xea\xf9\xf1\xf1\xe5\x69\x73\xf8\xd7\x71\xfb\xf0\xb2\x3f\x6e\x77\x9b\xe7\x5d\xfb\x7f\xb8\x4a\xac\x16\xdb\x63\x6f\x74\x83\x0e\x7c\x4e\xba\x02\xa7\xe2\xd7\x28\x49\xdb\x63\x62\xde\xa7\x07\x8d\x2c\xd0\x94\x74\x6e\xfc\x06\x74\xa0\x43\x43\x76\x44\x9a\x83\x86\x55\xb9\xbb\x0d\xae\x3d\x6d\x79\xdb\xe0\x25\xe7\x63\x57\x9a\x7a\x69\xe6\x06\xa8\x26\xa2\x0a\xe2\x06\xd8\x77\x59\x56\xcd\x02\x85\xe8\x84\x8b\xac\xef\x36\x77\x63\x7e\xb6\xf1\x49\x1c\xc7\x57\xaa\x23\x65\x1a\x10\xe6\xe2\xe3\x4f\xfd\x70\xed\xc4\x1a\x98\x51\x03\x4f\x15\x1c\x80\x9b\x54\xf6\x4c\x95\x92\x76\xb8\x70\x82\x1e\x44\x43\x8e\xf2\x30\x30\x32\xb9\x17\x57\x11\x0a\x51\xa4\x39\x2f\x27\xdc\x65\xda\xd3\x1e\x9a\x3f\xc5\x90\xf3\x7f\x5a\xf8\xa0\x3d\x1d\x1b\x6d\x3d\x24\xd8\xdf\xf1\x8f\x01\x38\x74\x16\xab\xa8\x7d\x5f\xb8\x44\x9e\xfc\xde\x4b\xc8\x69\xed\xf3\xc0\x66\x42\xdb\x39\xc4\x9b\xf2\x26\x79\xa1\x03\xcf\xc5\x3c\x6d\x56\xbc\x77\xc7\x05\x5e\x8c\x95\x44\x47\x13\x58\xbc\xb3\x52\x38\x5a\x07\x9a\xa2\xc0\x86\x85\xab\xfd\xea\x24\xb3\x34\xbe\xa1\xd0\x27\x4a\xba\xa7\xd6\x4e\x43\x0f\xee\xd6\xc3\x9d\xad\x7f\xb2\xc7\x47\x81\x74\x6d\xb5\x7f\x96\xbe\x77\x92\x2d\x5a\x47\x49\xc2\x8c\x8c\x21\x7e\xb0\x1d\xc6\x50\x3f\x09\x87\xe8\x84\x91\x54\x51\x45\x8c\x53\xdd\xa7\xe0\x51\x84\x64\x78\x47\xa4\x70\xe1\x97\x22\x47\x00\x4d\x32\x79\x0e\xc1\x84\x05\x4b\x53\x6a\x01\xf1\x02\x96\xa0\x74\xf2\x2a\x85\x20\x57\xb8\xaa\x8b\xcb\xad\x92\xad\xd6\x42\x51\x36\xc4\x92\x84\x7f\x3a\xa0\xa5\x4e\x48\x1c\xca\x18\x65\xed\x7e\xf6\x9d\xbf\xbf\xdf\x40\x6a\xb4\x0a\x48\x7b\xc5\x92\x7c\x8f\x1d\x3b\xad\x42\x16\xf4\x00\xea\xd6\x68\x9e\x2d\xd0\xd4\x2a\x72\x71\xfc\x20\x4f\xc2\x9a\x97\xdd\x2d\xab\x44\x60\x16\x78\xb5\x7e\x3e\xa2\xe8\xfb\xfe\xfb\x62\xb7\xee\x5a\x65\x84\x81\x02\x6d\x2a\x6b\x46\x6e\xf3\x7f\x0d\xc3\x48\xe6\x00\x60\x3c\xf4\xba\x04\x2f\x52\xca\x75\x5f\x04\x38\x49\x8a\x9e\x7b\xdf\x45\x6b\x57\x63\x8d\x32\x6f\xea\xc2\x96\x99\x4e\x29\xf8\xb5\xd6\x92\x34\x46\x0d\x05\xff\xd8\xeb\x00\xc6\x98\xaf\x11\xd0\x2d\x5a\xcf\xf6\x30\xe4\xa8\xde\x7f\x15\xdf\xb7\x47\x03\xc8\xde\x1e\xd8\xa6\x3f\xc1\x4c\x58\x7f\x50\x67\x01\x8c\x39\x31\x51\x87\x56\xa7\xe2\xc3\xa4\xa1\x50\xdf\x1c\x0b\x82\xfa\x9d\xc9\xee\x9b\xed\x11\x8a\x6a\x8d\xeb\x8e\x9b\xd0\x40\xfe\x7e\x33\x1d\x5c\xa6\x31\xac\x41\x74\x3f\x5b\xe4\xbd\xa5\x02\xf5\xae\xd2\xbb\xed\xe5\x73\x2c\xa5\x3d\x9e\x07\xd1\x99\xe1\x88\x6a\xfb\x70\x32\x59\x68\x20\x98\x4a\xa8\xc3\x28\x03\xd5\xf6\xd2\xc4\xc3\x2b\x2f\xb6\x02\x10\x18\xf3\x1c\xe1\x98\x7a\x8d\xbb\xe7\x83\x59\x8a\x40\xed\x50\xbc\xbc\xbc\x65\x21\x69\x0f\x09\x19\xd1\xd6\x65\x45\x35\xb6\xff\x4c\x47\x27\x71\xfb\xd8\x0a\x1e\xa0\xf0\x1a\xa4\x15\x6d\x91\xdb\xbf\x0d\xb2\xea\xf1\x00\x24\x04\x8c\xf9\x8e\x87\x85\xa8\x55\x96\xde\x80\x6f\xc6\x1f\xdf\x17\x11\x22\x00\x7b\x4d\x23\x5a\x30\xd4\xe4\xd9\x7d\x0d\xe8\x8f\xad\x78\x69\xab\xfa\x07\x71\x7a\xea\xd0\x85\xb4\x5b\xcb\xe4\x31\xcd\xeb\x6f\xcd\xf5\x8f\x13\x32\xb6\xa1\xe0\xee\xe8\xc2\x41\xc8\x1c\x53\x9d\xfe\xc0\x73\x35\x80\xd1\xc4\x43\x98\x41\x43\x85\x48\xe6\xa0\xd0\x73\xb1\xec\xfb\xbd\x68\x30\x74\x3b\xb7\xde\xb7\xdd\x62\x16\x10\x39\x18\xd1\x52\xcc\x79\xb0\xd8\x8d\x00\x7e\x25\x46\x91\xb6\x50\x62\x8c\x7e\xa2\x64\xde\xf6\x4b\x12\x8c\x86\xf3\xa6\x3e\x41\x5e\x13\xc4\x68\xa8\x92\x6d\xfa\x45\xc2\xf3\x88\x4b\x1b\xca\x34\x1b\xa8\x23\x77\xf7\x1f\x3b\x02\x6b\xe2\xec\x6e\xff\x85\x10\x48\xdb\xdb\xf5\xb1\x42\xe4\xc2\xaf\x58\x73\x6e\x1c\x96\xb6\x25\x91\x08\x26\x7c\x59\xa1\x06\xe8\x2f\x28\x59\xb6\x07\x49\x85\x2a\xb2\xfb\xe5\xbe\x8b\x0d\x00\x63\x3c\xd2\x18\x68\xb1\xab\xa9\x01\xbc\xcc\x6d\x18\x6d\x6f\x41\x7a\xd3\xa6\xc0\xbe\xdd\x1f\xce\x69\x3e\xa9\x78\x6b\xfb\xc9\x04\xcd\xac\xfa\x94\x96\x3d\x9c\x0f\x18\x13\x92\x59\x15\xe9\x0d\x46\x2c\x79\x9a\x43\x89\xa1\xe5\xf2\x0d\xfa\xc0\x13\x76\x8d\x30\x49\xfa\x5e\xd4\xfc\xd8\xe4\x47\x69\xb2\xc3\xd3\x79\x29\xc0\xe5\xc6\xce\x5d\x97\xd2\x65\xbb\xfe\xfb\x98\x1e\x52\x30\xa4\xf1\x05\x22\x2d\x43\xca\x2d\x35\x8c\x77\x03\x63\x8a\x71\xc4\xfc\x1c\x78\x56\x54\xbd\xfb\xd9\xb6\x44\x80\xec\x2f\xeb\x9f\xfc\x7c\xc9\x60\xdc\xa6\x9c\x70\xc0\x2d\x6f\x24\xc3\x80\x31\x1d\xc7\xae\x1c\xe0\x96\xd7\x3f\xe5\x69\x93\xaf\xab\x9a\xd7\xf0\xc4\xab\x45\x36\x54\x0f\x1e\xbf\x3b\x0d\x2e\x98\xe4\xf0\xc1\xd6\xf3\x03\x73\x58\xc8\x88\xb0\xc9\x7c\xa8\x9e\x2b\xb9\xf9\xbc\x5a\x6f\x6a\x9e\xda\xa1\xe8\x30\x19\xe2\x92\x97\xc3\x47\x57\xa8\x3e\x75\x97\x06\xbb\x25\x30\xc7\x71\xa8\x36\xb5\x6a\x57\xba\xa1\xec\xe1\x78\x31\x75\x9c\xc8\xf7\x1d\xcb\x7d\xd0\x1b\xcc\x37\xe0\xe4\xb6\x2b\x97\x98\x81\xe2\x68\xd6\x3f\x80\xee\x1e\xd6\xf3\x98\xb0\x32\x78\x33\x31\xa8\xf1\x1b\x73\x7c\xee\xa1\x9d\xfc\x01\x29\x51\x6d\x6e\x30\x84\x6f\xb4\x4e\x68\xdb\x90\x57\x6a\xfa\xad\x3b\x26\x46\x0b\xbc\x75\xa5\xe6\xa1\x76\xc3\x21\xe4\x04\x7e\x88\xa9\x3d\x5d\x16\xe7\xfb\xd2\x44\x07\x4c\xc7\xd1\xbd\x04\x61\x84\x3c\x9e\x50\x9f\x96\x69\xf1\xb3\x1d\x8c\x8e\xbd\x66\x20\x43\xac\x3c\xeb\xc8\x63\xbe\xe4\x31\xb6\x07\xa9\x18\xad\x82\x77\x5e\xa6\x7d\xe2\x1a\x98\x13\x86\xcc\xeb\x39\xf6\xad\x6a\xe1\xfe\x54\x7c\x54\xd3\x95\xc7\x89\x12\x08\xbb\x19\x40\x4c\x3e\xe3\xab\xc4\xcc\x21\x4b\xbe\xc9\x64\x53\xf2\x9a\x48\x24\x77\xfd\x04\x71\x62\x97\xc4\xfb\x08\x34\x7d\x4b\x15\xd3\x76\x89\x14\xea\x05\xe2\xac\x3f\x5e\x88\x73\xfc\xc8\x47\xcb\xa9\x13\x4b\x0f\x6f\x45\x34\x57\xd2\x21\xe5\xf2\xad\x5d\x74\x6e\x94\x0d\xfa\xa5\xc0\x49\x5c\x86\x50\xa6\x1d\x54\xb2\xf9\x32\xe1\xd8\x76\x0e\x38\xa6\xbc\xce\xfc\x27\xd5\x61\x4f\x77\xfd\x69\xff\xd0\x57\xfd\xba\x3d\x7d\x31\x09\x27\x7d\x7f\xe2\xb1\x5e\x11\xca\x74\x1c\x72\x07\xe6\x70\x2f\xc6\xd8\x2c\xc8\x12\x64\x6b\x70\x93\x9e\xf2\xa4\x14\x6d\x7c\x66\x2e\x49\x8d\xe5\x35\x7d\x07\x93\xc9\x98\xcb\x58\x19\xb3\xc1\x11\x8e\xb0\x79\x8f\x3b\x7e\xed\x5e\xa7\x10\x09\xbe\xf3\xae\xee\x72\x31\xe0\x6d\x1d\xdf\xa4\x90\x21\xeb\xc8\xdc\x56\x4d\x55\x17\x67\x2c\x6d\xac\x1e\xf9\xe5\x62\x0b\x0b\x81\x39\x32\x54\x86\x57\xb7\x3a\x75\x1b\x85\x23\x93\x08\x29\xcc\xbe\x35\xf9\x68\x0d\x74\xa4\xf2\x28\x17\x85\x03\x63\x0f\x59\x66\x69\x77\x26\x2f\x49\x2a\xcd\xb9\xd5\x9f\xbe\x64\xc5\x15\x10\xe8\x33\x45\x20\xb5\x3d\xb5\x8e\xfd\x41\x22\xb5\x1d\x19\xed\x6c\x2e\xca\x1b\xbe\x75\x60\x8e\x72\x34\x62\xb9\x70\x0a\xec\xd3\xd7\xb1\x1a\xf3\x2d\x15\xde\x78\x66\x2b\x45\xf2\xe0\x8b\xc7\xe5\x62\xbf\x5f\xdc\x3d\xef\x48\x3a\xc7\x3e\x1e\xb0\x10\x5f\xb0\x06\xb8\x4b\xdf\xe7\x6d\x09\x07\x12\x17\xb3\xa5\x5c\x54\xbf\x11\xd1\x96\x6d\xe0\x8c\x49\x2b\xb6\x52\xbe\xe5\x85\x02\x24\x23\xc2\xfc\xcf\x0d\x6e\x6c\x38\xe6\x41\x3b\xb8\xde\x73\xa5\x36\xf9\x3b\xe4\x75\x51\xde\xd4\xbd\xcd\xfe\x99\xbf\x43\xad\x35\x26\x40\x34\x3f\xa7\xd9\x75\x14\x2a\x06\xe6\xb6\x8f\xd9\xae\xc4\x6b\x99\xa5\x97\x0a\xba\x9f\xfd\x20\x36\x59\x98\xa3\x80\x59\xb0\x5e\xdb\x4b\xc4\xb8\xd9\x77\x45\x7e\xaa\x5f\x36\x5c\x27\xa4\xc2\x07\x30\x69\xee\xce\xef\x1b\x47\x1e\xda\x9e\x22\x26\xe7\xb9\x02\xf2\x39\x67\x8c\xc2\xc1\x7f\xff\xdb\x89\xc2\xff\xb1\x87\x2a\xc0\x42\xba\x33\x8c\x0b\x4e\x81\xb9\xae\xef\xa1\xd5\x8e\xd9\x3b\x93\xdd\x99\x5d\x07\x5c\x8f\x25\x7e\xbf\x9e\xde\x95\x45\xaf\xee\xfc\xc9\xab\x9d\x9e\x40\x27\xcc\x70\xc9\xae\xac\x7e\x95\x63\x1b\x7d\x37\x94\xc6\x57\xee\x08\x00\x31\x26\x8f\x9f\xd4\x9f\x9c\xca\x07\x19\x98\xa9\x72\x7f\x3e\x57\x77\xc4\x41\x31\xda\x90\xdd\x20\x8c\x11\xf6\x67\xb8\x5f\xab\x1b\xe6\xd7\xb6\x4f\xec\x23\xe6\x3d\x4b\xdb\x85\x36\x2d\x51\x23\x1f\xe3\xa9\xb7\x75\x9e\x16\xd6\x3b\x18\x84\x6e\xc0\xc3\x30\x1c\xda\xc8\x86\x61\xa5\xf5\xf1\xab\xce\x20\x75\x23\xe6\x21\xed\x7c\x5a\xfd\x91\xd6\xa7\x34\xdf\xac\x9f\x6d\x53\xec\xba\x46\x33\xa2\x7d\xab\x8b\xe5\xbc\xd2\x62\xdb\x51\x6b\xa4\xc6\xca\x88\x97\xe9\x5b\xfa\x0e\xdf\x9b\xbc\x46\xd2\x23\x9e\x19\x22\x43\xd3\x37\x49\x42\xc4\x6c\x7d\x5b\x6e\xbe\x08\xc3\x9a\xce\x22\x26\xca\x3f\x53\x06\x3e\x5c\xbb\x5c\xc1\x19\xda\xec\xf0\x53\x42\x55\x0d\x4a\xf1\xdb\x36\xe9\xe0\x9a\x2e\xd2\x2e\x55\x3e\xfe\x00\x42\x2a\x0f\x6c\xc6\xcc\x90\x03\x0c\x49\xcf\x81\xb9\xd2\x13\x81\xea\xa4\xf6\x5a\x0b\xe7\x01\x5e\xbb\xc6\x08\x30\xca\x52\x1b\xdd\x95\x1e\x30\x34\x4d\xa0\x0d\x5d\x69\x57\xc6\xb4\x6f\x90\x2c\x84\x79\x5d\xbf\x35\x53\xbd\xfb\xb6\x27\x48\xe4\x63\xa2\xa4\xfc\x6f\x13\x1b\xd0\x55\x8e\x64\x60\xb9\x98\x31\x58\x55\x4f\x20\x5a\x6d\x27\x8f\x85\x86\x20\xe1\xe5\xe9\xb0\xff\xe7\xa3\xbd\x7b\xa5\x7d\x04\x51\x3e\x2e\xfe\x3c\xae\x0f\xdf\xd7\xbb\xa3\xeb\x7f\xb7\x8d\x3a\x56\x58\xd6\x71\x23\x48\xd6\x75\x48\x18\x12\xec\xa7\x03\xe7\xc0\xd5\x5c\x60\xfd\x1e\xcf\x1b\x91\x8e\x8c\x70\x8f\x31\xa2\x63\x6d\x3a\x51\xcc\x41\xa4\x63\x1a\xca\xff\x7a\x9e\x7a\xcc\xe3\x56\x49\x17\x2d\x90\xc3\x47\xf1\xdc\xd4\x97\xc6\x32\x00\xda\x6e\x7e\x80\x6c\x2d\x85\xc2\x72\xd5\xdf\x06\x9b\xb1\xc7\x8c\x42\xf1\xab\xac\x2e\xbf\x4d\xce\x2e\x84\xea\x58\x88\x0f\x05\xc6\xc9\x97\xd7\x47\xa8\xf9\x23\xaf\x66\x15\x8f\xdb\x83\x94\xc6\xd8\x67\x47\x51\x3b\xb6\x1c\x1c\xd3\xcd\x89\x12\x44\x42\x3d\x14\xaf\xc3\xa5\xf4\x93\x93\x3a\x2a\xd4\xa4\xe4\xb5\x59\x3d\x77\xa8\x4b\xd3\xe8\xc6\xd2\x96\xd8\xef\xc8\x64\xb9\x0e\x9a\xb0\x82\xe4\xc4\x6f\x21\x88\xb3\x73\xd7\xf3\x9c\xc4\x35\xbb\xdc\x30\x2a\x37\x0e\x7b\xb7\xfd\xbc\x40\xd0\xd0\x1d\x59\xc0\x5b\x28\x07\x91\xa3\xee\xac\x3e\xe3\x18\xcb\x7c\xe4\x57\x7e\xdc\x1a\xaa\xf8\xee\x01\x02\x70\x50\x4b\x1d\x8d\x4d\xb4\x56\xd7\x56\x14\x09\x98\x17\x06\x2e\x29\xd5\x57\x83\x74\xde\x16\x7a\x02\x05\x60\x5e\x14\x02\xe2\x16\x1e\x9e\xbf\x1d\xd7\x53\x6e\x60\x9e\xed\x1b\x29\x01\xd4\x3c\xfe\xb2\x3d\x9c\x13\xa9\x7c\x4f\x92\x7c\x9e\xe4\x3a\xec\x68\x89\xdd\x48\x11\x3b\x81\xae\x23\x36\x79\xca\x38\xe1\x7e\xd4\xeb\x23\x11\x5c\xf3\x31\xcd\xa0\xaa\x8b\x1c\xc6\xeb\xb9\x17\xcb\x08\xf7\x85\x01\xc1\xe1\xb1\xea\xeb\xf5\x80\x79\x89\x23\x70\xbe\xb6\x3b\xf1\x1b\x52\x81\xa8\xb4\xca\xd2\xb7\xb1\x3e\x5e\xdb\x31\x71\xb5\x32\x0a\x1f\xf7\x45\xf9\xf6\x52\x66\xdd\x39\x92\x10\x23\x1e\x67\xa4\x67\xeb\xf8\xe7\xfe\xae\x4c\xdc\x1e\x0d\x3e\x77\x86\xf2\xf8\xcd\x58\xf6\xa8\xed\xa2\x29\x90\x93\x56\xed\x95\xed\x65\x85\xc7\x7c\xcb\x90\x75\xe5\x79\xdd\x6e\xc1\xf5\x5a\x16\x79\x71\x4e\xff\x6a\x3a\x31\xeb\x68\xf2\x02\x45\xbb\x8e\x52\x3d\x35\xad\x0c\x77\xf0\x3e\xf4\xae\x3f\x29\x1b\x32\x47\x4b\x27\xc0\x6a\xf2\x87\xe2\x75\x0f\xf5\xfe\x70\x43\xb5\xf9\x2b\xd5\x06\x78\x1e\xe9\x1b\x54\xc3\x43\x9a\x0f\x86\xfe\x27\xdd\x43\x0f\x71\x8b\x5c\x29\x43\x11\x30\xb6\x5a\x6d\x37\xc9\xad\x9e\x4b\x87\x47\xbb\x2f\xca\x73\x93\xf1\x39\x4a\x50\x60\x9e\x8a\x13\x34\xf2\x8f\x56\xa6\xf3\x50\x2c\xac\xb6\xd4\x3a\x6f\xce\x86\x93\x76\xf2\x0e\x81\x25\xe8\xde\x1e\xc9\xf8\xb1\xfc\x77\x7f\xf3\xe8\x93\x67\x02\xc9\x1c\x0b\x47\xe7\xe5\x2b\xd4\x73\x8f\xe4\x33\x87\x1c\x96\xfd\xe3\x6e\xb8\xc2\xfb\xcc\x55\x98\x0e\x7e\xe7\x59\xaa\xee\x8a\xde\x36\xb2\x9f\xca\x67\x89\xa7\xc2\x2e\xbb\x42\xfc\x4c\xed\x74\xb5\xa4\x77\x6d\x17\x49\x4c\x7f\x86\x4b\x22\x70\xbc\xaf\x4a\x85\xdb\x03\xb4\x47\x83\xe7\x84\x48\x8d\x11\xb6\xc3\x74\x71\x5c\x1e\x98\x61\x49\x4e\x71\xd1\xe4\xca\x1d\xbf\x40\xdf\x4d\x04\x7a\xb5\xfb\x53\x9a\x5f\xf7\x7f\x35\x69\x59\x42\x66\x57\x23\xdf\xe5\x0a\x71\x60\x85\xa5\x04\x36\x6f\xc6\x34\xfb\x1e\x24\xa6\x28\x8b\xcc\xa4\x5f\x9b\x69\xbe\x2f\x5d\x65\xf8\xef\x1e\x0a\x6e\xd2\x1b\xbf\x4c\xe2\xf0\xd9\x39\x7d\x82\xd4\x60\x90\x7e\x57\x64\xd9\x5d\xda\xd9\x33\x7e\xe0\x51\x51\xf1\x89\x57\xf7\x45\x53\xfe\x0b\x78\x97\xa9\xeb\xba\x44\xcc\x27\xd0\x7b\x53\xd5\xa0\x36\xf9\xa5\xa9\xfb\xb6\x18\xfd\x3a\x41\xb5\xa1\x59\xbf\x7b\xdd\xc6\x7e\xcd\x21\xa1\x1b\xf8\x51\x57\x04\x61\xe5\xfd\xc7\xf7\x1c\xba\x8a\x11\xb4\xa3\xc4\x84\x25\xc1\x99\xad\x88\x6f\xdb\x41\xfa\x98\x70\xbb\x43\xee\x82\xee\x57\x4d\xa6\x8d\x02\x5e\x9f\xee\x78\xcd\x8f\xdc\x86\x6a\xfc\x88\x01\xd2\x15\x9d\xd1\x50\xbf\x2b\xf9\xeb\x74\xce\xf8\x91\x0b\x18\x10\x31\xc5\x8e\xa3\x18\x9a\xed\x12\x00\x5a\x39\x27\xcc\xa0\x52\x88\xb3\xe3\xa4\xb5\x97\x8a\x15\x43\x32\xbf\xf7\xa2\x36\x14\xad\xe3\x44\x87\x9f\x04\x3c\xf4\x6d\x22\xbf\x3c\xf3\x8c\xbc\x76\xdb\xcc\x9d\x04\xed\x14\x24\x40\xd6\x45\x53\x22\x7a\x6c\xfd\xd7\x4b\xda\x9f\x82\xbb\x01\xaa\x2b\x3f\x15\xfc\x34\x97\x9f\x6b\xbb\xc4\x12\xe9\xb6\xf6\x96\x2b\xaf\xfd\x4d\x32\x24\xf3\x5d\xb6\x7b\xd2\xd5\xb0\x7c\x8d\x1f\x51\x3a\x9e\x09\x2a\xbc\x41\x7e\x1c\x46\x91\x7f\x85\x2c\x09\x4f\x40\x6c\xb3\x3a\xcd\xd5\x13\xfc\xac\xbf\x17\x4d\x8f\xe0\x20\xc8\xa9\xed\xa9\x18\x6e\x4b\xcb\xe7\x87\xc3\xf7\x99\xdc\xd4\xf8\x79\x54\xe0\xa0\xf5\xd0\x99\x1a\x7b\x40\x2a\xa7\x3d\xc9\x6b\x8c\x6f\x42\x7b\x0e\x16\xd2\x4e\x73\x75\xa3\xfb\x18\x0e\x4b\xcd\x25\xfa\xf5\xfc\x47\xaa\xa0\xe8\x24\x39\x80\x05\xcc\x4f\x30\x4e\x23\x1a\xb4\x25\x6e\x6b\xfd\xdb\x3e\x61\x84\xf0\xb0\xa3\xa2\xf4\x6d\x57\x2c\x88\x0b\xcc\xa4\xb3\xeb\x32\xc7\xb5\xea\x36\xff\x8b\x93\x6a\x5b\xd4\x8b\xea\x3e\xfd\xd9\xfe\x2b\xcd\x6b\x2c\x21\x3f\xc3\x66\x0c\x4e\xb7\x87\x73\xaa\xdd\x48\xab\xa7\xa2\xc6\x6a\x8c\x01\x88\x7d\xf4\x16\x02\x57\x33\x19\x77\x82\x81\xfc\xfc\xb5\x18\xe8\x97\x51\xb5\xc0\x73\x22\x84\x5b\xfd\xb9\xda\x66\xcd\x6b\x17\x46\x0a\xbc\xc4\x75\x89\xa2\x17\x52\x59\xf4\xd5\x4a\xc0\x02\x9f\x05\xc8\xf5\xf1\x50\xbc\x2e\x9b\xeb\xd7\x51\xbb\xc0\x67\x54\x21\xb8\xba\x2b\x81\x9f\xd3\xfc\xd5\x92\xbc\xb7\x6d\x92\xb9\x49\x97\xcf\xfb\xdf\x8b\x3b\x79\xa3\x81\x10\xa4\x83\xdc\x94\x79\x17\xb2\x0f\xc2\x24\xc6\x00\x17\xea\x4e\xda\xba\xa8\xf1\x00\x98\xdd\x43\x82\x50\x3a\x18\xb0\x4f\xab\x6f\x59\x21\x78\xd6\xd3\xad\xb4\x8d\xda\xd5\x36\xce\x5c\xde\x03\xca\xa0\xac\x7d\xdb\x1a\x85\x04\x5a\xe5\x4a\x3d\x40\x3e\xca\x5a\x04\x71\x20\x11\x9f\xb0\x84\x5a\x16\x69\x3e\x78\xbe\x58\x4a\x2b\xc6\xf3\x08\x67\x38\x18\x8a\x90\xf1\xe1\x89\xa3\xa8\xd4\x21\xfd\x0f\x94\x9b\x1a\xce\xd5\x24\xe8\x13\x24\x32\x36\x24\xe8\x94\xcc\xa1\x67\x6e\x47\xd2\x92\x97\x23\x29\x8b\xc9\xbb\xe7\x3e\xd1\x31\xf5\xce\xd8\x0f\xc8\x55\x71\x63\x20\x9a\xee\xc2\x27\x57\xe3\x1b\x0a\x8d\xa2\x11\xbf\x98\x24\x8c\x02\x11\xf8\x01\x95\x7f\x40\x3e\x0e\xc7\x4f\xce\xc5\x25\x12\x56\x52\xca\xc0\xe6\x72\x30\xa2\x66\x8b\xd2\xc6\x27\x96\x01\x8f\x3d\x53\xba\x04\xe5\x98\x43\xa5\x6d\x16\x21\xe6\xa3\x1e\xd3\xba\xe4\xef\xf6\xcd\xa8\x28\xc4\x75\x0f\xba\xe2\xa5\x3d\xc8\xa2\x77\x2f\x02\xf0\x98\x6b\xb0\x23\xb6\x84\xe1\x4a\xe2\x6d\x67\xc8\xa7\xcf\x06\x89\x03\xac\x23\x1b\x7f\xc1\x4c\xad\x81\xc0\xdb\x1e\x9c\xf8\x29\x74\x39\x58\x48\x00\x22\x1c\xa5\xbb\xc5\x61\x5d\xd4\x8d\xfd\x59\x3b\x7e\x62\x15\x8b\x8a\x9a\x67\xbb\xa6\xdb\x4a\x02\x1d\xa9\xd0\x2a\x7e\xae\x8a\x9e\x14\xec\x0b\x40\x6e\x7b\x14\x57\x09\x95\x51\xca\x42\x7d\x99\x2f\x0e\x59\x44\x34\x4e\xb2\xc8\x75\x5a\x9e\x09\xbc\x62\x98\x32\x4d\x17\x27\xf2\xc1\x98\x4b\x75\xa7\x0f\xda\xfe\x9e\xc4\x38\x68\xfb\x4f\x3f\xb6\xc4\xc3\x76\xbc\x9a\x98\xd7\x1e\xf2\xaa\x98\xe4\x61\x43\xd7\xa3\x6a\x98\x97\xa7\xfd\xf3\xc3\xdd\xa8\xa0\xb7\x6d\xe5\x5a\x77\x32\x6d\xad\xe1\x3d\x8a\x18\x85\x1e\x4b\x30\xa1\x84\xb9\x0f\x4a\x9d\x75\x4d\x51\x80\xab\xde\x51\xdf\xa5\xdd\xdb\x0f\x3d\xee\x23\x13\xc2\x51\x16\xe7\x4b\x53\x83\xad\xe2\xe9\x42\xbb\xa1\x1f\xb8\x98\x37\x58\x19\xf6\x7c\xbb\x90\x84\xbe\xa0\x31\x8a\x80\xfd\x21\xf5\x2d\x59\x7d\xfb\x8c\xbf\x4f\xfc\xba\xd0\x97\x0e\x62\xfc\x15\xe4\x57\x7a\xa9\xdd\xed\x05\xcc\xc5\xef\xbd\x2d\xde\xe0\x5c\xe4\xdb\xe2\xa3\x6b\x09\x34\x04\xbd\xc2\x7e\x73\x9d\x54\x1a\xb5\x5d\x12\xc7\x27\x05\xc2\x2d\x94\x55\x91\x93\x34\xc7\xe4\xe2\x01\x78\x58\xb6\xf4\x04\x1f\xcb\xe7\xed\xa4\x31\x02\x52\xa5\x22\xa5\xc7\xdb\x92\xf4\xd9\xd5\x39\x8c\x74\xe8\x11\x03\x4f\x0d\xe5\x3b\xcf\x8c\x3a\xbe\x69\x8d\x43\x92\x28\xb7\xc9\xd1\x65\x67\x0a\x87\x09\x73\x89\x8d\xcb\xa8\xfa\x03\x0b\x39\x4b\x40\x0e\x37\x72\x8c\xe3\x42\x55\x8f\xaa\x00\xbe\x36\x6b\x43\x1e\x32\x5c\x86\x11\x90\x9d\xd6\xd7\x95\x2d\x1c\x69\xdb\xb8\x83\xc2\x1d\x14\xc0\x6b\xca\x19\xad\xd3\xcf\xce\xaa\x5d\xa4\x7f\x59\x42\x9d\x5d\x07\x59\xf5\x50\x04\x31\x72\x22\xa0\x9e\x3b\x72\x21\xbe\xe4\xe9\xad\x4b\x39\x3e\x9b\x88\xc0\x4b\xac\xa8\x53\x5a\x3f\x97\x43\xdb\x39\x14\x71\xc0\xa4\x31\xf3\x36\x79\xbb\x41\x57\x50\x1e\x3e\x8a\x3b\x90\xe9\x99\x5b\xdf\x3d\x94\x8c\xea\xb6\xf6\xbc\x2e\xaa\x53\x3a\x74\xb1\x42\x19\xc4\x68\xe2\x21\xed\x4c\x59\x9c\x67\x78\x57\x81\x85\x2a\x56\x68\x0b\x71\xf9\x57\x93\x12\xd6\xa4\x6a\x47\xcd\x1a\x83\x27\x8b\xee\x86\x80\x31\x8c\x2e\x52\xfc\xa3\xf8\xb0\x28\x4b\x6c\x02\xc4\x14\x15\xef\x50\xf6\xec\x23\x6d\x83\x17\x47\x46\x98\xa4\xbc\x5e\xea\x69\x9e\x32\x84\x90\xa4\x70\x1e\xd2\xb7\xbf\x81\x47\x84\x10\xbb\xc2\x35\xf8\xa0\xa7\xcd\xe3\xfd\x62\xb2\x5c\x40\xa2\x2c\xd5\x3f\xe5\xba\x0c\xaa\xc9\x60\x48\xe7\x3f\x01\x48\xca\x3b\xa7\xd5\x43\x8a\x34\x0e\xf6\x6c\xda\x53\x48\x50\x8a\xe0\xc4\x45\xf7\x2b\x27\x16\x81\xf5\x61\xf5\xd0\xff\x16\xc6\x7d\x49\x3b\x16\xc4\x4d\x5e\xb0\x96\xa1\xf2\x0d\x96\xab\xe2\x19\x90\xea\x45\x7f\xb1\x88\x25\x46\xc2\x26\x4b\xf3\xb7\xa3\xe8\x4a\x47\x81\x45\x4e\xc0\xe3\x5e\x23\x6f\x50\x33\xd3\xb6\x85\xb1\xcd\xd0\x0f\xc9\xc6\x7e\x40\x99\xea\x14\x6e\xe2\xbf\x91\x23\xc7\xd5\x0d\x3f\x78\x93\xd5\x3d\xac\x60\xb4\x0e\x44\x6e\xec\xe1\xf0\xbb\x7f\x79\xba\xdb\x3c\x7d\x3b\xae\x0f\xdf\x8f\xdf\x17\xbb\xbb\xe3\x6a\xb1\xfd\xad\xeb\x43\x6c\xe9\x8b\xa7\x1f\xdd\x4f\x42\x39\x6c\x08\x11\xec\x73\x59\xe3\xf3\x7b\x40\x88\xd9\x4b\x23\x7e\x87\xeb\xa1\x58\xa6\x68\xf5\xd8\x8f\x3a\x35\xc0\x23\xdf\x71\xa8\x7a\x15\x1d\xe6\x65\x09\x80\xa3\xf3\xd7\x88\xfb\xed\x39\xdc\xc8\x0a\x0d\xe0\x63\x4f\xa9\xab\xda\x2e\x82\xe2\xd4\x27\x5e\xad\x7f\x82\x6c\xea\xa9\x03\x14\xf9\x42\x0c\xe2\x77\x3d\x90\x6a\x7a\x22\x80\xc0\xa4\xd2\xa8\x32\xb2\x3a\x14\x5b\x7e\xfd\xac\x48\xd1\x1c\x15\x04\x11\x46\x06\x06\xa7\x9d\x1c\x60\xd1\x1e\x7e\xf7\x59\x83\x40\x60\x5e\xe8\x0f\xd8\x3e\xff\x61\xbf\x43\x28\x19\x96\x3e\xff\xd5\x40\x79\x7d\xea\xf6\x90\x28\x72\x75\x88\xc2\x54\xbb\xe7\x3f\xee\xa8\xac\xe2\xf9\xf7\xf5\xd3\x71\xf3\x74\xfc\x63\xbd\xe9\x7a\x05\x54\xbd\x2f\xe7\xa3\x13\xbf\xf8\xd7\x9e\x2c\x76\x1d\x13\xaf\xcb\x80\x57\x28\xc8\xf0\xc5\x9c\x8c\x22\xc9\x11\x7b\xa6\x7f\xda\xdb\x89\x65\xd0\x21\xdb\xcd\x16\x42\x1b\xec\xa1\x40\x1f\x75\xf2\x85\x92\x20\x11\xe6\x33\xa3\x0a\xdd\x94\x49\xa1\xed\x02\x9e\x67\x5d\x6c\xf8\x68\x57\xf2\x7b\xb0\xdb\x55\x94\x40\x04\x81\xa5\xc2\x6b\xe7\xe2\xd7\xd9\xc0\x61\xa4\x33\xe2\x6e\x88\x88\xe7\xb3\x55\xba\xd8\xdb\x89\x70\x83\x20\xff\xbf\x4a\x62\x44\xdc\x73\x64\xd4\x2b\xcf\xa6\xf9\xeb\x6a\x58\xe4\x38\xed\x1d\x28\xf4\x88\x56\x0f\xbb\xc1\x36\x15\x09\x70\xfd\x7e\x12\xb5\xdb\xd4\xfa\x69\x3f\xa3\xb6\x05\x2c\x92\x31\xb3\x94\x15\xbf\xa7\xb9\x1a\x2f\xb6\x91\x94\x0a\x3a\x68\x81\x11\x9b\xb7\x81\xa1\xfd\x30\x3e\x1d\x49\x95\x60\xd4\x64\x51\xe2\xfc\xc6\x7a\xee\xd3\x98\x2b\x6d\x3c\x5c\x94\xaf\x49\x12\x81\xbf\xc3\x8a\x97\x77\xbc\xe6\xc3\x0a\x9d\xf9\x83\x34\x13\x98\xb7\xdc\x43\xae\x0c\x3b\xf8\x34\x47\x38\x3d\x80\xd2\xe3\xff\x6e\x6d\xa9\x2d\xa4\x5b\x48\xff\x1e\x53\xd7\x1e\x15\x0c\xa9\x48\x47\x9e\xcb\x2d\x5a\x36\xd2\x9e\xc2\x08\xe6\x6b\x31\xcc\x26\x45\x9a\x7b\xd2\x19\x92\xd1\x58\x4e\x4b\x60\x31\x73\x7d\xc7\x54\x7f\x3e\xdd\x1f\xee\xa0\xe6\xf2\x34\x5d\x83\x62\x26\x88\xb6\x83\x5f\xd2\x15\xcf\xb2\x6a\x8e\x15\x09\x18\x52\x3a\x06\x7d\x5c\xdf\x96\xd6\x12\x5d\x5d\xf5\x49\x7a\x3f\x76\x3c\x70\x03\x2b\xfd\x92\xab\xe2\xbc\x99\x7a\x38\x6d\x97\x00\xc6\x3a\xbd\x06\x90\xfb\x9c\x4f\x51\x5f\xb1\x13\x04\x88\x21\xdc\xac\x9e\xad\x8e\xc3\xa2\x93\x31\xc6\x76\x89\x78\x3e\x1b\x10\x7a\x4c\xf3\x66\xa0\xfe\x32\x0c\x09\xc5\x4e\x1c\xe2\xae\x91\x5d\xfa\x87\x14\xc4\xc4\x7f\x97\x4a\x78\xce\xb3\xb4\x8b\x02\xc6\x8e\x56\xc4\xcc\x69\x95\x41\x7b\x2e\x82\xd9\x59\x13\xbb\x11\x05\x9c\x8e\xed\xcf\x87\x62\x7f\x23\x0e\x0b\x2c\xf6\x5c\xaa\xc6\xa3\x79\x38\x03\x4f\x89\x3d\x1f\xd0\x8f\xfb\x83\xd7\xf2\x64\x2e\xb9\xc9\x89\x35\xcc\x76\xe1\x0e\xb2\x29\x1f\xad\xb0\x12\x4a\x18\xda\xc1\xd3\xf3\xf2\xdb\x0f\x34\x1c\x84\xb1\xa7\x7c\xf4\x5f\x94\x89\xeb\xcd\x32\x2c\x00\x8b\x7d\x1e\x23\xe4\xf6\x52\xc2\x85\x97\xd0\x33\xdc\x98\xf6\x80\x79\x63\x3b\x7b\x96\x53\xb4\xed\xe8\xfb\xc8\xe8\x74\xbf\xd9\xed\x0f\xc7\x97\xfd\x7a\x77\x5c\xbd\x1c\xba\xd3\x24\xbe\x6b\xdd\xb8\x46\xfc\x2f\xc8\xfa\x91\xd7\x35\x94\xd5\xde\x4a\xc4\xb6\x9d\x64\x60\x4d\x5d\x83\x06\x97\x13\x59\xe7\xb6\x93\x8e\x5d\xd2\x59\x6e\xcf\xb2\xba\x25\xf8\x33\xfd\x42\xc7\x47\xbb\x67\x51\x55\xe9\xeb\x8c\xf1\x6e\xbb\xb9\x5a\x45\xdd\xae\xb1\xe4\x0a\xe9\x4e\x27\x7d\x20\x80\x91\xd2\x5f\x67\xd3\xc6\x91\x27\x19\x41\x21\xb0\x70\x8f\xb4\xb6\x66\x4d\xd3\x38\x0a\x1d\x2c\x75\x50\x35\x86\x62\x79\x0d\xab\xb4\xbe\xee\x73\x7e\xa9\x4e\xc5\x27\xdb\x5c\x1c\x49\x85\x06\x82\xbd\xf4\x26\x97\x90\xd7\xe9\x7b\xe7\x09\xc6\xb1\xcb\x09\x11\x94\x96\x77\x65\x71\xf9\x7b\x74\x7e\x1c\x87\x1a\xdd\x75\x3e\x9d\xb0\x71\xe4\x23\xe8\xa9\x23\xeb\xff\x0a\xfc\x18\xc7\x3c\xc1\x25\x98\xf8\xf0\xcb\x97\xbc\xea\x1c\xb6\x98\x07\x1a\xdd\x53\xf4\xbb\xb7\xc4\xf1\x71\xd7\xfb\x7a\x31\x97\xcc\xf1\x7b\x92\x09\x34\x7d\x2c\x5b\x24\xb0\x58\x84\xa4\x2c\x83\xc1\x4d\x4a\x58\x61\xb1\x5a\xd7\x2e\x3d\x9c\xb3\x97\xd6\xdd\x69\x17\x9e\x41\x86\x3e\x56\x6e\xac\x0c\xd2\x6f\xd3\x89\x6c\xf5\x71\xb2\x58\xc5\x3e\x5a\x0e\xed\x4a\xf3\xb0\xfe\xb1\x7e\x30\xba\x57\xc0\x62\xf0\x3d\x6f\x68\xfb\x0e\xb2\xd4\x31\xa8\x00\x79\xec\xed\xcb\x59\xa6\x6a\x0c\xf5\x1c\x21\x3e\x13\xe6\x39\xb1\xad\xcf\xe7\xb2\xb6\x9f\x2b\x61\x20\x90\xa6\xf4\xc7\x8b\xbd\xa1\xc4\x31\xd5\x93\x0a\xde\x51\x45\xa2\xa9\x8b\x61\xa4\x73\xf4\x8d\x12\x47\x01\x86\xc4\x1e\xef\x16\xdd\xf1\xda\x0f\x8c\xb2\x72\x17\xc5\x1f\x1f\xe4\x26\x82\xa8\xad\xda\x4f\x75\x5f\x02\x20\xc2\x61\x48\x3c\x64\x3a\x7a\x9c\x58\x3b\xb8\x98\xd5\x7e\x05\x96\xf8\x8e\x27\xb8\xdd\xd3\xbb\x8a\x1d\x50\x8b\xb4\x54\xed\xf0\xb3\xdd\x02\x8e\x68\x81\x0f\x21\x7b\xcb\x22\x09\x98\x52\x06\x36\x32\x40\x87\x8f\x77\x96\x24\xd0\x31\x8e\x0d\xc4\x86\x1d\x8a\x1b\x0e\x2c\x60\x49\xe8\x49\x84\x65\x3f\xa4\xf9\xdb\xfa\x0a\xa3\x52\xea\xbf\xdf\xa0\x93\x30\x8a\xb5\x15\x2e\x92\xc5\x7c\xca\x34\x89\x20\x12\xc9\x50\xe1\xa3\x42\xd1\x32\xd3\x1a\x3b\x44\x5e\x8b\xdb\x5f\x89\x75\xf5\xe3\x6d\x35\x89\x23\x5f\x1a\x4e\xd6\x2d\x51\x12\xea\xf4\xf5\x53\x31\xc8\xee\x20\xf2\x84\x29\xde\xb0\xc8\x32\xf2\x02\x3b\x46\x39\xdb\x4d\x46\x48\xfb\x56\x5c\x10\xc0\x80\x24\x71\x35\xcf\x1e\xb9\x35\x86\x13\xae\x24\xb2\x65\x41\x7d\x32\xaf\x70\x80\xda\x4d\x24\x27\xcb\x80\x0a\x0d\x17\x93\xc2\x83\xf1\x2d\x49\xe0\xc8\x21\x70\xcc\xe1\xe3\x6f\x1c\x29\x7b\x84\xd6\x08\x76\xde\xa7\xf9\x6b\x93\xf1\x32\xad\xaf\x07\xa8\x6a\x27\xb6\x97\x57\x4c\x44\x81\x51\x98\xe4\x25\x3c\x00\xbf\xd9\x6b\x3f\x39\xb5\x12\x24\x97\x45\xa5\x85\xb8\x83\xe4\x28\xca\x8d\xf0\xaa\x51\xe4\x30\x51\x8a\x21\x9c\xe0\xfe\x69\x75\x18\x06\x3c\x12\x05\x0a\x07\x79\x86\x32\xfe\xcf\x9a\x48\x0d\xb6\x25\xe8\xf4\xa7\xe7\x7a\xee\x9c\x86\x25\xb0\x04\x12\x3f\x61\xbd\x70\x80\x81\x8d\x8c\xd4\x51\xda\x5e\x3c\x62\x86\xb0\x19\x1e\x8b\xbc\x28\xa1\x1e\x68\xc3\x7f\xfd\x74\x00\x01\x66\x59\xf5\x50\xb6\x6c\xf0\x51\xc1\x54\x39\x5e\xca\xe2\x5c\xac\x9a\x3a\x05\x23\x3b\x38\x74\xf8\x13\xcd\x98\x6b\x18\xc0\x56\x48\xb0\x41\xbb\xe8\xdc\x1a\x9e\x68\xcf\x61\x66\x5b\x3e\xa6\xb2\xc8\xd3\xbf\x8e\x86\x91\xe9\x58\x5c\xa6\x50\xdd\x44\x87\x9a\xb4\xe1\x1a\x89\xc4\x0a\xf5\x72\x10\x84\xe0\x2c\x91\x8e\x9e\x25\xc9\x1b\x9d\x85\x33\x1d\x30\x33\xfb\x30\xe8\x49\xf1\xcf\x21\xdf\x43\xf7\x46\xb8\xc3\xdd\xc4\x84\x6b\xda\x33\x18\x81\x1d\x3b\x0f\xb8\x23\x20\x18\x28\x22\x22\xbc\x00\xd4\x63\x91\xc3\x75\x07\x64\x12\xdb\x9e\x92\x14\xfd\x3f\x8c\x57\x74\x1a\xe0\xf1\xb8\xa3\x15\xa7\xcc\x45\xb7\x7b\x3b\xe6\xab\x73\xd7\x89\x3c\x93\x55\x59\x66\x5c\xbe\xa1\xe2\xcb\x1c\x84\x81\xbb\x91\x70\x87\x56\x82\x71\xc0\x3e\x59\x48\xb9\x9b\x90\x58\x3b\xc6\x8e\x8e\xba\x04\xf8\x0f\x90\xa6\xb8\xbd\x2d\x4f\x90\xc8\xff\xae\xc8\xb2\xe1\x17\xe6\x1e\x44\x64\x93\x51\x10\xfa\x0e\xb4\x29\x53\xb2\x1d\xfc\x44\x1b\x75\x22\x22\xb4\x32\x22\x8e\xb3\x63\x80\xfb\x9c\x23\xc2\x76\xfd\x93\xb7\x03\xa5\x5b\x0e\x27\xeb\xe8\xe8\x98\xc0\xf3\x92\x81\x8b\x98\xe6\xaf\xd3\xe4\x29\x0f\x02\x4a\x60\x63\x41\xdb\x23\x4f\x91\xe5\xbb\xdf\x86\x79\xc8\x00\xf1\xc1\xcb\xcd\xe1\xf0\x3c\x9c\x9f\x3c\x74\x3d\x6b\x06\xee\x4f\xdc\x0d\xc2\xe3\xcb\xe6\x33\x1f\x96\x87\x61\x2c\xcc\xa3\xfe\x20\x8e\xd5\xaf\xc8\x13\x80\xf1\x88\xc5\x0e\xc1\x1f\xe9\x65\x5b\xfe\xa2\x81\x09\xc1\x23\x8f\x94\x31\x2e\x25\x9c\xd3\xce\x2c\xe1\x51\xe0\x62\x2a\xd2\xd0\xce\x2d\x96\xc5\xcf\x19\x44\x3b\x6f\xc7\x81\x67\x8d\x9f\x9e\x30\xca\xb4\xc6\xcc\xc5\x0d\xb4\x92\x3c\xc7\x50\x6e\xf5\x55\x6e\x85\xc7\x6e\x44\x7a\xd6\x3f\x37\xdd\x19\xdc\x04\x0b\x5b\x5e\x91\x50\xee\x7a\xf8\x28\xfa\x16\xa2\x9a\xab\x50\x19\x68\x89\xb3\xaa\x1d\x3d\x93\x4f\x13\x1b\x0e\x58\x79\xe2\x79\x0e\xd9\xf3\x05\x72\xe3\x3c\xda\xdc\x13\x8f\x75\x48\x14\x55\x08\x3d\x98\x07\x32\x70\x1e\x84\x81\x6f\xf3\x5d\x98\x78\xe3\xea\x4a\x96\xfb\xf2\x7a\x28\xb9\x7c\xdb\xa8\xf1\xa2\xcc\x85\xd2\x61\x68\xa7\x53\x21\xdf\x90\xe0\xa1\xe6\xe7\x09\x5e\x92\x4b\x57\xe0\x2d\x7e\xe7\xdf\x39\x6a\xd3\x8d\x46\x88\x0c\x98\x14\x06\xc7\x07\xbc\x6a\x4a\x58\x16\x3f\x27\x5f\x41\x86\x0e\x06\x6d\x29\x0f\x82\x91\xbc\xfd\x89\x97\x28\x8c\x68\x68\xef\xb0\xc0\xac\xbe\xf1\xde\xb8\xe4\x12\xd7\xe1\x8f\x2e\x56\xd1\x0d\x01\xe5\x3b\xe8\x55\xf0\xd6\xd0\x1f\x21\x43\x39\x44\x81\x63\xb5\x2b\x9a\xfa\x54\x94\xe9\x7f\xa0\x67\x5f\x99\x08\x59\xf6\x31\x4b\x0e\x49\x88\x91\x75\xd5\xd9\x49\xc2\x91\x72\x50\x31\x6e\xd1\xc3\xb3\x1e\x82\x70\x24\x60\xda\x15\x43\x20\x83\x97\x24\x3c\xe6\x44\xed\x60\x78\xfe\x81\x24\xfc\x3d\x8e\xf8\x26\x87\x3e\xbb\x4e\x0b\xcf\x49\x8c\x05\x5b\xbe\x43\xb9\x2d\xba\x85\x09\x29\x24\x64\x27\x54\x7e\x80\xf2\x5c\x2d\x72\xf5\x8f\x22\xcd\xef\xfe\xbc\xef\x3b\xc9\x84\x59\x6a\x5a\xe3\x4c\xdb\x61\x20\x7c\x2f\x36\xec\x8a\x28\x76\xc2\xcf\x60\x19\xfa\x86\xcb\x8c\xf0\x03\x1f\xc3\xb9\xc7\x76\x76\x93\xd3\x54\x4c\x62\xb1\xc2\x4f\x98\x36\x0e\x9c\x89\x6d\x6f\xd4\xb4\x8b\xd4\x8c\x77\xd3\xe2\x91\xff\x5c\xde\x8a\x45\x98\xae\xa1\x54\x18\x86\x78\x78\xf8\x71\xf4\x1c\xe7\xb8\xbe\xdb\x1c\x3a\xff\x40\x44\x31\xc1\x14\xa8\x1c\xf6\x40\x58\xa6\x5f\x4a\xa7\x8a\x38\x94\x01\x19\xf9\xc4\x43\xf6\x30\xc7\x71\x3e\x3e\x24\x49\x12\x0b\x99\xfc\x2a\x14\x2a\x12\x88\xbd\x7e\x59\xfa\x55\x84\xe2\xe4\x62\x5c\x04\xb8\x1d\xe9\xa2\x3c\x12\xae\xdf\xee\xb2\x42\x24\x9e\x67\x6c\xdd\x39\xc8\x93\x90\xa1\xc4\x3c\x35\x7a\x17\x9b\xbc\x32\xaa\x46\xa3\x89\x2f\x64\xa8\xa0\x17\x7f\x3f\x0c\xf0\xc0\x33\xe5\xf5\xc0\x84\xf2\x98\x63\xe2\x4b\x28\x81\x34\x88\xcc\xd8\xfb\x52\x81\x27\xc0\x24\xf1\x8d\xa0\x77\x51\xfe\x1b\xe4\x74\xae\xcd\x7f\x69\x15\x29\xc7\xc4\x6f\x3b\xd4\x74\x31\x4b\x89\x00\x4c\x80\x82\x80\xa2\x4f\x65\x65\x22\xf5\xa3\x00\xa6\xd0\xdc\xd1\x7d\xbc\xff\xa5\x46\x4d\xcc\x5b\xa9\xb4\xb6\x27\x24\x68\x6c\x3c\x2e\xfe\xb4\xfa\xbd\x86\x75\xde\x9c\x4b\x32\x87\xc0\x21\xe7\x42\xa5\xfa\xca\x8d\x63\x35\xfb\x14\xd2\x61\x3e\x9e\xed\xee\xf9\x69\x65\x8f\x77\x85\x44\x61\xb0\xd5\xdd\xba\x17\xe5\xfb\xdc\x1d\x92\xae\x92\x18\x09\xcf\x78\x55\x1f\x3f\xd2\xfc\xf8\x61\x14\x63\x81\x49\x5f\xd2\x8e\xf2\xad\x2c\x3e\x86\xab\x8b\x0c\xb4\xc7\x0d\x97\xba\x1b\x84\x9f\xdc\x5d\xc8\x7c\xc4\x3f\x22\x55\x09\x1c\x8a\x21\xfb\xbf\xd3\x75\x72\x12\xb4\x07\xd1\xa6\x1f\x78\xdc\x32\xf4\x12\x44\xdb\x3d\xbf\x75\xbf\x44\xc4\xeb\xb9\x7b\xfe\x7d\x74\x33\x61\xac\x48\x59\xfb\x54\x0e\x4b\x1e\x62\xdb\xac\x1c\x50\x7d\x84\xf3\xbe\x28\x6d\x90\xd3\x9e\x20\x8a\x3d\xcc\xcc\xfe\xb9\xb1\xb6\xc8\xe8\xa3\xc9\x48\x3a\xc8\x95\xb6\x6b\x1d\x4d\xbb\xdd\xca\xd8\x0d\x31\xd7\xb9\xfb\x63\x74\x37\xc2\x23\x49\x08\x83\xf5\xfa\x02\x33\x23\x85\x50\x40\x8c\x66\x6f\x30\x62\x48\x19\x7d\x20\xa1\x63\xdf\x32\x36\x2d\x94\x7a\xe8\x39\x5f\x81\x49\xe9\x03\x7a\xa2\x0f\xa9\xfe\x5b\x3f\xe3\xd3\xbf\xb3\x6b\x96\x54\x9e\x6f\xa3\x98\xb8\x59\x2f\x9b\x34\x53\x37\x70\x02\xa9\x42\xaa\xb3\x12\x05\x2f\x15\x69\xb9\x99\x96\x76\xc9\x4c\x7a\x26\x36\x22\x77\x18\xed\x04\x12\x22\x17\xb7\xba\xa3\x26\x0f\xb9\x3b\x54\xb8\x48\x42\xa2\x79\x5a\xb6\x8f\xb4\x2d\x8b\x9a\x68\x4e\xbb\x1e\x32\xb1\x64\x01\x77\x3c\xcd\xae\x66\x42\x8e\xef\x0d\x80\x24\x8c\xf7\xe4\xb2\xe8\x26\xcb\xae\x76\xf1\x21\x84\xd0\xaa\x75\x42\xf3\xeb\x4d\x06\x72\x9a\x81\x31\x27\xd4\x8e\x87\xd4\x80\x1d\xa8\xd1\xe4\x6d\xbe\x4c\xe2\x4b\xed\x44\x3c\xb0\x51\x93\x7d\x5d\x94\xa0\xee\xee\x6c\x70\x54\x6a\x07\xfc\x5e\xec\xc1\xd2\xee\xde\xa4\xf4\x6c\xef\xc8\xc1\xea\x21\x8c\x15\x1f\x4a\xe8\xb2\x02\x52\x47\x2e\x26\xe4\xd6\xbb\x95\xcb\xfe\xb6\x04\x4a\x6a\xc9\x02\x39\x24\x02\xab\x76\x80\x3b\xd9\x03\x47\x0e\x62\x20\xa2\x84\xbb\x02\xaa\xbc\xfe\xce\xdf\xdb\x95\x1a\x13\xff\x3c\xb3\x6d\x55\x77\x69\x05\xae\x6b\x0b\x47\x88\x7a\x0a\x7a\xfa\xff\xf6\xa0\x15\xbf\xdc\xe6\x40\xe8\x68\xc5\x02\x2a\x49\x7a\x84\x73\x91\x96\xb0\x22\x59\x51\x73\x6e\xe5\x08\x8e\xcc\x0d\x3b\x5e\xc3\xd1\x0a\x88\x01\x53\x6e\x44\xb5\xe7\x8f\x9b\xa7\xcd\xe3\xcb\xe3\xe6\xe9\xc7\x7a\x7f\x78\x5c\x3f\x1d\x0c\x17\x5c\xd7\x2f\xa1\x2c\xfd\xfe\xb0\xd8\x1d\x36\x4f\xdf\x8e\xdb\xe7\x67\x1b\xc0\x55\x5e\x10\x60\x62\xfe\x1b\xd4\xcb\xa2\xc0\x42\x01\x5e\xf3\xf1\x28\x52\x5e\xc4\xb0\xaa\xa4\x4a\xbb\x18\x8a\xf2\x81\x5b\x30\xc7\x1e\xa6\xb9\x97\xb6\x15\xa9\xfa\xb8\x52\x77\x40\x4c\xa2\x58\xee\x6e\xec\xe8\xe1\x77\x50\x81\xdf\xa9\xe8\x6f\xf2\xae\xaf\x7d\xb5\x2a\xe0\x1a\xab\x8a\x46\x0c\x48\x8b\xcc\x62\x3b\x54\x18\x26\x2a\xb6\x05\x5b\xd5\x2d\x92\x47\x85\x2a\xf0\xac\x3a\x90\xb1\x55\xba\x93\x47\x81\xa3\x78\x87\x42\xeb\xa4\xbe\xda\x96\x48\xeb\xd0\x6a\x17\x43\xbe\x2c\x0a\x9b\xe5\xb6\x73\x41\x45\xe6\xc5\x72\xa5\xa4\x29\x81\x56\xaa\x7d\x7b\x73\xc8\x50\x73\x4c\x1c\xb9\xc2\xbe\xb6\x54\xc1\x1e\xca\xf7\x54\x76\xd1\x6c\x95\x08\x49\x34\x90\x57\x71\x2e\xba\x47\xe4\x2e\xc5\xab\x3e\x52\x75\x2b\x23\xdb\xb6\xfb\x9d\xc0\xe4\x1d\x68\xde\x64\xb5\xc5\xfd\x0d\xa2\x5e\x4a\x84\x11\x0a\x53\x15\x5a\x43\x79\xd7\x9e\x65\x34\xb5\x95\x88\x23\x2c\xab\x38\x17\x39\x5c\x31\xd8\x37\x7e\x8f\x82\x87\x4c\x0f\xde\x63\x31\x4b\x3b\xde\x76\x14\xc0\x69\x32\xf0\x72\xc0\x0b\x3b\xbe\x9a\x8c\xa9\x3a\xea\x5b\xaa\xeb\xef\xf4\x8e\xf7\x83\x41\x2f\xb5\xab\xe2\x7e\xe9\xdc\x90\x68\xd9\x0d\x45\x12\x30\xf5\xff\xe7\xec\xdd\xba\x1b\xc5\xb5\x7d\xf1\xef\x72\x9e\xfa\x61\x3d\x20\x09\x04\xfc\xdf\x1c\xc7\xa9\xf2\xaa\x24\xce\x8e\x9d\xae\xd5\x7b\x8f\x33\x3c\x74\x99\x72\x58\xc1\xe0\x05\x38\xa9\xf4\xa7\xff\x0f\xa6\x24\x6e\xc6\xe9\xde\xe7\xa5\xab\x47\x90\x31\x06\x21\xcd\xcb\xef\xa2\x99\x7d\x84\x0f\xb7\xcb\xed\xdf\xac\x80\x6a\x2d\x22\x94\x0f\xf8\xd6\x4f\x09\xf4\x73\x7b\xaa\xe0\xa1\x7c\x87\x75\x7f\x72\x21\x90\x0d\xd8\x45\x2b\xfb\x9b\x97\x3f\x9c\xef\x1d\x04\x1a\x54\xa0\x82\x01\xc9\xd7\x8a\x08\xb8\x83\x26\x22\x9d\x5c\xc3\xbe\x2c\x00\x23\xf8\x45\xa1\xd7\xc5\xbb\xc5\xa2\x8f\x2b\xa6\xda\x44\x56\xea\xeb\xde\x92\x17\x91\x51\x81\x8c\x19\xd0\xd7\x50\x3f\xe3\x5f\x65\x22\xcb\x72\xf2\x06\xb1\x2f\xcf\xeb\xf1\x9b\x66\x74\x80\x9a\x6d\xdf\xd6\x77\xbb\xce\xbe\x0f\x02\x08\x42\x9e\x38\xa9\xdd\x4d\xae\xe7\x0b\xc2\x10\x24\x44\xdb\xbd\xba\x7a\xb3\x5a\x4c\xe7\xba\x3b\x01\x50\xec\x39\x54\xbd\xb4\x80\x0b\x3e\x80\x90\x00\x67\x55\x93\x0d\x10\xdd\xe3\xf9\x0b\x84\x58\x87\xa4\x02\x3e\x7e\x2f\x3f\xd6\xfa\x2e\x17\x7f\x51\xc6\x00\x12\xa5\xcc\x62\x03\x95\xf8\x44\xdd\x12\x05\x88\xaf\xbf\x32\x9c\x1b\xb4\x52\xdf\xa1\x34\xcc\x84\xcb\x34\x19\x2a\x62\xe3\x45\x7b\xb6\xdf\x17\xcc\xff\x46\xca\x2d\xe0\xe1\x98\x15\xd9\xf1\x7c\xfc\xd9\x05\x89\x40\x53\x81\x9d\xea\xed\xfd\xc3\x7a\xb9\x99\xdc\x36\x46\xa3\xc0\xb2\xba\x6e\xc5\xe7\x36\xfb\xd5\x7c\x2e\xdb\x40\xaf\x0b\x60\x80\x85\xd0\xf9\x33\x22\x52\xda\x6a\x2f\x8b\xac\xb0\x78\x73\x68\x06\xea\xe2\xff\x98\x4b\x5e\x80\x71\x4b\xba\xc3\x10\xf2\x42\xfc\xb8\x1d\x20\x53\x7c\x76\xeb\xe3\xf1\x8c\x52\x97\x58\x0a\xe8\x1e\x1f\x93\xc2\x13\xab\xef\xcb\x1a\x6a\x3c\x3a\x3d\x85\x01\xc4\xca\xd4\x6f\xd9\x71\x71\x9f\x35\x4d\x0e\x1b\x63\x76\xaf\xb0\x2b\x27\xc5\x0b\x08\x03\x86\x75\xd2\x42\x1c\x2f\x08\x67\x7e\x48\x6c\xe5\x9e\x9e\xad\xc7\x81\xed\xe0\xb7\x9b\xde\xc6\xf9\x72\x4e\xce\x18\x33\x54\xb5\xc2\x69\xfd\xad\x6c\x37\xe0\x61\x79\x13\x42\x15\xb2\xc4\x35\x2b\x3c\xa1\x3d\xbf\x0c\x65\xc6\x27\x8d\x92\x00\x3d\xb1\x6e\xca\xf2\x2d\x2b\x0e\x4f\xe5\xf2\xeb\x28\x06\x22\x63\x8c\xd5\xf9\x41\xbe\x8d\xef\xcd\x03\x4f\x53\xe6\x00\xc6\x6e\xf9\x75\xa5\xb8\xc1\xf3\xfb\xab\x08\xb4\x5f\x3e\x81\x6b\xae\xa4\xf3\x7f\xc8\x2a\xbb\x6c\xcc\xa2\x3a\xdd\xf8\x98\xd0\x58\xf8\x32\x94\x9d\xda\x1d\x70\xab\x5f\x5e\x20\xa6\x76\xe7\x69\x97\xb2\xc5\xfd\xfd\xe6\xe7\xea\xd6\x71\x90\xbb\x29\x9e\x10\x5b\x77\x69\xcf\x64\xd9\x36\x5b\xf5\x6a\xa5\x2b\xac\x51\xc8\x6d\x37\x32\x4c\xec\xc2\xd7\xce\xb8\xce\x13\x0d\x0f\x40\x42\x86\xe6\x81\x6d\x70\x69\xeb\xc5\xb3\x89\x2e\x24\x91\x41\x40\x7f\xbb\xa0\xa0\xcb\xef\xe2\xb7\x39\x2c\x0a\x24\x09\x65\xc3\xf2\xf2\xad\xc8\xe6\x1b\x68\x90\x88\x08\x7b\xc6\x3f\x16\xf7\x6c\x98\x98\x40\x2a\x99\x47\x48\x3d\xc3\xa9\xac\x46\x52\x3c\x3d\xb4\x09\x04\xb1\xe0\xe2\x63\x9b\xc5\x8a\xea\x73\x74\x12\xc9\x02\x04\x92\x8d\x6c\xf1\xba\x68\xd5\x03\xcf\x86\xcf\x53\xf2\x00\x31\x99\xce\x78\xd3\x29\x62\x4f\x9a\xec\x20\x39\x47\xac\x8d\xeb\x16\x3f\x95\xe5\x85\x24\xc3\x34\x6e\x04\x99\x86\xf8\x83\x8e\xa2\x81\x05\x2a\x02\x5c\xcc\xb3\x99\x18\x04\xa4\xa6\x91\xad\xb8\xd5\x58\x30\x1a\xee\x5a\x20\xb5\x34\xae\x47\x89\x3f\xcd\xbd\xa1\xe5\x04\xaf\x09\x8a\x5a\x62\x88\x15\x31\xaf\x7d\xc0\xd1\xbd\x92\x3a\x4e\xb4\x57\x3c\x2a\xcf\x39\x34\x0d\x3c\x9f\xf3\x29\xe1\x16\x20\x0e\xa1\x67\xa5\x2c\x54\x73\x16\xf9\x7f\x9d\xe1\x3c\x5d\x7e\x20\xb5\xe3\x9e\xda\xe4\xaf\x19\xc0\xb5\x00\x4c\x80\xdb\xe6\xcd\x66\xf3\x63\xbd\x6a\x83\xdb\xfb\xfd\x72\xf3\xf0\xb0\xde\x6e\xd7\x9b\x6e\x8b\x33\x5a\x60\xfb\xba\x2e\x4d\xb3\x74\x7a\x07\xf5\x40\x39\x15\x02\x13\x84\x29\x96\xb7\x9d\x6c\x95\x55\xfb\x13\x39\x74\x64\x18\x13\x70\x16\x79\x52\xd9\xfa\x0a\x9e\xc8\xd0\x40\x20\x7b\x05\xfb\xb7\xf7\x7d\x57\xc2\x30\x62\x84\xf5\x0d\x6b\x5f\x18\x3b\x03\x07\xf5\x7a\x3f\x8a\x12\xb4\x6d\xa8\xce\xc5\xf6\x03\xe0\x64\x1d\x26\xfd\x41\x9e\x62\xc8\xdf\xbc\x66\xf5\x10\x2b\x63\x42\xca\x11\x21\x5e\x9c\x8f\x0f\x4b\x14\x45\xee\x9e\x84\x09\x63\xeb\x7d\xe8\xdf\x1c\xeb\xe8\x89\x1e\x2a\x73\x92\x0a\xdd\x23\x36\xa1\x20\x18\xc7\xb9\x1d\xef\xe9\x79\xb5\xbb\x5d\x0d\x29\xf6\xeb\xa2\xdf\x05\x4d\x08\x1a\x3b\x7f\x27\x51\x29\xc8\xfb\x3c\xc5\x44\x81\x14\xde\x8d\xe4\x9a\x86\x29\x04\x86\x07\xa9\xb6\x98\x88\x5a\x18\x58\xd7\x2b\x8b\x86\xee\x7f\x07\x57\x2a\xb0\x9c\x2d\xac\x88\x8f\x42\x1b\x13\x87\x0a\x59\x9f\x37\x9b\xc7\x97\xed\x7e\xb7\x7e\x58\x6d\xf7\xbf\x2f\xee\x5f\x56\xdb\xc9\xd7\xc4\x31\x41\xef\xa2\x9b\xac\x79\x3d\x1f\xe5\x57\x19\xa2\x89\x65\x88\xb1\xcb\x53\x05\xbb\x03\xac\x7e\x9d\xa0\x6a\x7c\xc9\xcb\x24\x69\x82\x94\x0e\xcc\x69\x71\xb2\xdc\x97\x75\x3d\x7c\x97\x4c\xa2\xb8\xcf\x6c\x9c\xaa\xd3\x67\xbb\xc7\x8d\xa7\x5d\xa2\x2d\x92\xb3\x3e\x95\x45\xdd\x66\xc6\x48\x77\x1b\xae\x39\x26\xa5\x04\xe9\x84\xa8\x46\x79\x3b\xb0\x5b\x1b\xd2\xf2\xae\xf9\x4c\x41\x60\x84\x09\x84\x23\xe6\x6c\xdc\x94\xee\xa6\xab\x4c\x42\x5c\x0c\x2a\x50\xf0\x0e\x7a\xd5\xbc\x8e\x78\x43\xf3\x33\x43\x41\x8a\xe9\xae\x63\xea\x7d\xbd\xd1\x1a\x1d\xa5\xd2\x4a\xcd\x5a\x5c\xab\x3e\x66\x85\xb3\xd9\xf4\x57\xa1\xb5\xf1\xa6\xb9\xe0\x54\x90\x7e\x1b\xe3\xba\xa6\xe7\x34\xd6\xae\xd5\x64\x98\x8e\x5f\xaa\x61\x43\x60\x20\x20\x26\x74\xd5\xa5\xa7\x76\x99\xea\x04\xca\xc6\xe9\x80\x81\xc0\xaa\x38\x9f\x50\x00\x1c\xdb\x38\xdd\x39\x42\x2a\x2d\xe9\x29\xab\x9b\x1a\xc3\xcc\x4d\x81\x30\xa7\x27\x91\x5d\x41\x67\x1a\x08\x05\x32\x7a\xbd\xe2\x6d\x25\x1a\x38\x7c\x2e\xdb\xff\x76\x7a\x45\x24\x9a\xfc\x22\xe0\xd6\x22\xaa\x4d\x0b\xad\x97\xc5\x74\x7f\xf3\x25\x10\x03\xa9\x42\x84\xc1\x4f\x91\x37\xce\x0a\x09\x8b\x62\xdd\xed\x34\x91\x4c\xdc\x46\xde\x46\x37\x93\x57\xc0\x44\x9a\x1a\xdf\x1e\xfd\xf5\x2c\x14\x0c\x9d\xd8\xda\x01\x22\xd0\xde\x43\x11\x2b\x5f\x7b\x43\x58\x77\x6e\x48\x50\x3b\xb4\x80\x0f\xab\xc0\xff\xa5\xd0\xd2\x2c\x4b\x12\xcf\x44\x82\x20\x8a\x10\xcb\x23\xf2\xbc\xfc\xf0\x55\xa9\xb1\xc9\x33\x90\x80\xc4\x8c\x51\x6f\xb3\xd5\xc6\x86\xda\x1f\xa1\x44\x46\x4e\x1a\xf6\xfe\xac\xde\x3e\x9f\x41\x95\x95\xee\x11\x75\x24\xa0\x49\x2a\x93\xcb\x22\xf7\xb4\xec\x37\xbc\x3d\x24\xa0\x52\x08\x39\x48\xa3\xe6\x2d\x64\xda\x81\x3a\x8d\xdc\xeb\xfd\x28\x8e\x56\xb8\xc8\x1d\x62\xdc\x20\x23\xa1\x11\xbf\xf6\xbd\x3f\x62\x77\xe5\x21\xd1\x78\x78\xbf\x6f\x5e\x2b\x8f\x3b\x27\x01\x37\x02\x37\xb9\xbc\x6c\x9a\xf2\xbe\xfc\x80\xba\x19\x12\xb6\xda\x01\xd2\xea\x29\xe0\x6d\xdc\x95\x37\xed\x4c\xfa\x6d\x74\x53\x13\xca\x98\x2d\xb5\xcd\x4a\x11\x92\x20\x49\x29\xba\x80\x2e\x6b\x5f\xec\x20\x41\xa2\xa9\xe6\x5d\x87\xc8\x7a\xcf\x5b\x58\xcc\x40\x18\x6a\x6e\xae\x93\x20\x0d\x6d\x9d\xe4\xf6\xdb\x7f\xdb\x4d\x15\xa9\xd2\xf3\x77\x36\x8d\xad\xf7\x60\x1b\x09\x61\xbe\xed\xbf\x3f\x05\x43\xc3\xc1\x2d\xdf\xa0\x24\x40\x59\xf9\x6b\xb8\xe8\x2a\x4d\x34\x99\x48\x20\xe2\x00\xa3\xdb\xfb\xf2\x60\xe5\x59\x7e\x5f\xdf\xac\xfe\x16\x61\x89\x04\x42\xa4\x98\xfe\xae\xf2\xcf\x5f\xdd\xad\x96\x3c\x0a\x64\x67\x8b\x36\xe6\xf3\x93\x40\x2a\x85\x78\x4e\xec\x71\xf7\xba\x24\x57\xf4\xcf\xff\x31\x28\x1b\x91\x40\x42\x1c\xc4\xbd\xc2\x72\x59\xea\x9b\x4f\x18\x3f\x44\x15\x4b\x84\xbe\x62\x40\x8c\xf5\x52\xff\xc5\x9a\xa6\xe0\x28\x0b\xe7\xfe\x8f\x21\xc1\xc4\x1f\x0a\xb4\x31\xb0\x16\x29\x43\xc3\x1c\x1c\xa3\x02\xdb\x33\x6e\x37\x80\xe9\x54\x06\x1a\xa3\x6b\xea\xb2\x12\x7f\x7e\xae\x44\xd5\x13\x6f\x48\x00\x91\x56\xed\x57\xee\xe5\x39\xcb\xf5\xa0\xe7\x4b\x02\xe0\x1c\x7a\x8d\xe0\x9f\x90\x3d\x79\xb8\xf7\xf8\x0e\x43\x62\x10\xb0\xa8\x4b\xa4\x45\x0e\xde\x50\x48\x23\xdc\x8e\x8d\x35\x01\x5a\xe1\x2f\xe8\xde\x13\xd0\xd6\xd1\x69\xbd\x59\xde\xa1\x51\x61\x9b\x05\xb9\x63\x86\x58\x5d\xa4\xac\xde\x95\xe7\xaa\xcd\x35\x27\x20\x63\x12\x18\x99\x22\x26\xd7\x0b\x66\xda\x3f\x93\x80\x85\xd4\x7a\x4c\x61\xfc\xf6\x3c\x6c\xf7\x11\x12\xc4\xa1\x6d\xae\x17\x59\xd3\x63\xce\x09\x09\x92\xd8\x42\x5d\x3b\x6f\x3a\x20\x84\x50\x8e\x6a\xfb\x15\x2e\x3d\xc3\x7b\x43\x48\x24\x84\x6b\xb0\xbd\xd4\x50\xf9\x6f\xf9\xaa\x0d\x49\x08\x0b\xe3\x34\xf5\xbd\xc4\x5b\x51\x62\xf4\xe7\x2a\xfb\x93\x91\x69\x02\x9e\xb6\x76\x0f\xa6\x29\xdf\x3b\xf6\x26\x21\x4c\x71\xe3\xd1\xe4\xdb\xf5\xe3\x72\xe5\x0f\x84\x21\xc3\x1f\xf7\xf2\xf3\xf1\x2b\xab\x86\xf1\x57\x45\x94\x85\xac\xdb\x1e\xc7\x8f\x96\x44\x34\xc6\xb0\x2d\xcf\x8a\x37\x18\xbb\xad\xb4\x47\x13\x86\xaf\xa5\x7d\xab\x9f\xb6\x53\x8b\x60\x20\x84\x3b\x57\x97\x03\x34\x3f\xce\xba\xac\xdb\x1f\x73\x57\x56\xbe\x57\x36\xbb\xea\x90\x38\x12\xb1\x4b\xe5\x1e\x3e\x77\x59\x9b\x13\xd4\x73\x79\x23\x21\x31\x70\x0c\xfc\x1f\xe6\xbd\x29\x86\xc5\xc1\x31\x57\xe5\xcb\x1d\xec\xab\x7f\xdc\x17\x27\x44\xc5\x56\x5b\xf0\xac\xa0\xb9\xcf\x8c\xff\xc1\x49\x0c\x5e\x69\x6b\x69\x1d\xd0\x32\x69\x35\x5b\x1e\x60\x52\x7a\x27\x24\x01\x8d\x88\x3f\x03\xa8\xb9\xa1\xb7\xa7\x2a\x6b\xa0\xbe\x47\xec\x5e\x77\x46\x23\x85\x9d\xd0\xed\xca\xe7\x2d\x92\xba\x3b\x9c\x9a\x04\x0b\x91\xae\xff\x67\x15\x37\xd6\x48\x76\x7c\xcc\x64\xde\xbf\xea\x44\x44\x22\x1c\x1a\xd2\x61\xf9\x71\x00\xad\x22\x44\x88\x88\x77\xa5\x66\xd0\x1d\x7e\xe5\xa6\x33\x2e\x98\x09\xd7\x08\x91\x81\x73\xe8\xb7\xe9\xd7\x84\x1d\x4c\xda\x8d\x5c\x98\x41\x0d\xc3\x7b\x1a\x0d\x70\x5f\x84\x68\x69\x35\x67\x8e\x96\xbb\x32\xb9\x09\xda\x24\xd8\x47\xc5\x20\xf9\xf7\xec\x84\xbd\xc7\x41\x37\x60\x14\x1f\xf7\x0b\x23\x01\x22\xb1\xb8\x0e\x28\xde\x3a\xea\xb1\x13\x02\x46\xf8\xe2\xdc\x53\x55\x1e\xaa\x29\x31\x94\x10\x13\xa6\xce\x7a\x01\xda\xa9\x5f\xa8\x4f\xff\x59\xc3\x19\x66\x72\x0f\x8b\x7f\xad\x1f\x5e\x1e\x3c\xad\xa3\x3b\x0c\x96\xc1\xfb\x2a\xea\x75\x03\xf3\x85\x4b\x42\x83\xd8\xf6\x99\xad\x56\xde\xed\xa5\x67\x4c\x3b\x26\x8d\x7d\x4f\x61\x79\xae\xaa\x5e\xe8\x9d\x50\xa2\x48\x60\x6b\x0f\x1d\x6e\x7e\x7c\x7e\x4a\xc2\x20\xf0\x37\x3e\x2b\xd0\x63\x78\x38\x8d\x29\xe5\xc4\xeb\xac\xdc\xa1\x4a\x26\x2a\x93\x8e\x2f\x80\x2a\x4b\xfc\xc7\x54\xe8\xfe\xa6\x8d\x00\xf6\xdf\x56\x8f\xab\xe7\x45\x07\x2e\x27\x94\x1a\x82\x65\x90\x6f\x65\xae\xa1\xf0\xfa\xc3\x83\x3c\x87\x50\x46\x2c\xb7\xc1\xbb\xb4\xcf\x42\x72\x09\x0d\x13\x8d\x69\xf8\xed\x1f\xf7\xcb\xfd\xa0\xd9\xe7\x0f\x03\xc3\x1e\x8a\xd0\x7a\x8f\xa1\x25\xe8\xaf\xb0\x29\x84\x86\x26\xc1\x45\xb7\x29\xb1\xea\xe2\xfe\x1a\x51\x99\x4a\x97\x3d\xec\x45\x51\x16\x9f\xc7\xf2\x5c\xef\x47\x7e\x27\xf3\xcf\x2c\x0a\x8d\x14\xfe\x1d\xb1\x1a\x89\xe3\x2f\x8c\xa2\x80\x98\x4e\x82\x70\xe0\x12\x3e\x7d\x3a\x91\x49\x30\x8e\x17\xa5\xea\x71\xe4\x84\x72\x1e\x84\xae\xdb\xb8\x13\x6f\xd0\xb1\x53\xef\x3a\xe0\xec\xf4\x44\x1c\x24\xd6\x36\x2a\xa7\x27\xbc\x2c\x35\x0c\xc9\xce\xe3\xeb\x8b\x03\x89\x68\x51\x71\x25\x04\x74\xc3\x12\x42\x13\xd7\x58\x73\xe7\x79\x59\x17\x8d\xd7\xcd\x9d\x0d\x01\x69\x12\xa6\xd2\xe9\xb6\x3c\x64\x05\x7c\x83\x02\xea\xcc\xaf\x54\x34\x89\x23\xef\x91\x33\xe4\xa1\x4c\xcf\x61\x02\xcd\xbd\xd8\xc3\x01\xeb\x2c\x3d\xb9\x82\xd0\x94\x46\xc2\x35\xc6\x5f\x8a\xf2\xa3\x00\xfd\x98\xa9\x37\x2c\x46\xcf\xb4\x4d\x08\x4d\x99\x15\xeb\x31\xe8\x1f\xde\x2d\x3f\xdd\xe2\x44\x53\x95\xa2\x09\x5c\x51\x36\xa2\xfa\x6c\x13\xaa\x41\x8e\x41\x53\x13\x23\x7d\xa1\x4d\x01\xbc\x2b\x24\xe8\xd9\xba\x37\xa1\x82\x49\x4c\x27\x33\x55\x5e\x02\xd2\xfc\x98\x24\xc5\xda\xf8\x52\xea\xff\x1d\xb2\x9f\x50\x29\x34\x26\x86\x4f\xce\x5a\x71\xea\xec\xdc\x0e\x51\x9a\xdb\x88\x05\x1b\xf7\xed\x55\xf7\x87\x00\xf9\x8a\x27\xa8\xda\x8f\xad\xfe\x73\xbe\x7c\xf4\x93\xda\x02\xa1\x4a\x4a\xac\xcb\x6e\xd7\xdf\x1e\x17\xf7\xfb\xdb\xd5\xfd\xe2\x8f\xdf\xfa\x63\x29\x0c\xb4\xc9\x34\x54\xd6\x2a\xb2\x5d\x7e\xdd\x99\x3a\x41\x76\x42\x93\x8b\xff\xc3\x83\xa3\xaf\x03\x4d\xf0\xeb\x5c\x91\x6e\xb8\x37\x51\x80\x04\xbb\x1c\xb8\x0c\xd9\x22\xcb\xb3\x78\xeb\x9f\xa3\x61\x82\x93\x09\xa6\x6a\x8c\x2c\xf3\x03\x79\x8c\x9d\xce\x5b\x2c\x90\x56\x7f\x0e\xa5\x9d\x09\x0b\xc2\xd0\xf4\xc8\xca\x55\xf3\xba\x6f\xca\xfd\xb9\x1e\xb7\xc0\x09\x0b\x38\xf5\x7e\x34\xeb\xe2\xbd\xcc\x86\x5e\x53\xdd\x46\xe4\xc6\x12\xa6\x8d\x5b\xb2\x1c\xc2\x00\x17\xe2\xf1\x09\x69\x18\x49\x32\x91\x57\xb9\x69\x17\xb8\xa6\x1e\x87\xcd\x8c\x46\x04\x4b\xa2\x68\xf8\x88\x48\xcd\x51\x6b\xec\x82\x63\xdb\x6d\x86\x8c\x6a\x19\x76\xbe\xdf\x7d\xf3\x98\x30\x46\x85\xa3\x83\xf4\x5d\xa9\xdf\x66\xc2\x1e\xc6\x92\x00\x73\xd8\xd5\x71\x99\x8b\xba\xce\x54\x77\x06\xa1\x31\x5b\x87\x5f\x0d\x14\x1a\xc5\xa1\xc6\xbf\x2f\x8c\x24\xee\x55\xdb\x87\xc5\xf3\xee\x5b\x27\xb8\x45\x58\xa8\x52\x63\x6d\x52\xce\x8d\x2e\x3f\x0a\xe7\x8a\x30\xfb\x86\xb1\x10\x18\xb3\x2b\x1d\x82\x6d\xdc\x5f\x23\xa2\x50\xf7\xea\x24\x3e\xf7\x83\x95\x94\xc5\x01\xc3\x62\x6d\xbb\xc8\xdf\x97\x87\xbb\x2c\xbf\x9a\xef\xfe\x25\xa0\xf0\xcb\x24\x93\xc5\x81\x25\x97\x3d\xaf\xb6\xab\xfb\xfb\xf5\xe3\xb7\xfd\xfd\x66\xf9\x63\xff\xf2\xd4\xc6\x05\xeb\xcd\x6d\x77\x45\x5c\x63\x2c\x67\xdf\x19\x2c\x1b\x2e\x54\xbb\x73\x7f\x43\xd3\xb9\xc9\x3d\x8b\x95\xb6\x66\xea\x5d\x11\x12\x29\x11\x0e\x6f\xe2\x06\x25\x60\xa4\xdb\x2e\xd0\x09\x7c\x6b\x81\xdf\xfd\x53\x4f\xc1\xb2\x43\xad\xf3\xbe\x82\x45\x31\xb0\xa7\x20\x4c\xc4\x31\x62\x7e\x2c\x2a\xa6\x39\x57\xdd\xed\x13\x52\x84\x89\x3b\x72\x33\xf8\xbb\xd4\x81\xeb\xce\xe6\x4b\x51\xbf\x66\x57\x78\xcc\x84\x69\x11\x20\x96\xfb\xfb\xe2\xf9\x9f\xf6\x25\xbb\xba\xb8\x31\xad\x68\xe2\xfb\xe9\xd8\x14\xf3\x25\x23\xbf\x7d\x30\xa0\xa0\xac\x76\xdd\xfb\x1e\xf9\x88\xbd\x5d\xcd\xe4\x69\x80\x22\x58\x2f\xc7\xb6\x96\x77\x9b\x9a\x0c\x31\x32\xee\xba\x45\x06\xda\x68\x05\x2e\xf4\x17\x09\x33\xc2\x68\xd9\xb5\xc5\xdb\x18\xaa\xbb\x1c\x03\x29\xb6\x65\x9f\x57\x8b\x7b\xa4\x74\x5b\x40\xe4\xc3\x20\x28\x9d\x2f\xaa\x84\x41\x28\xbd\x5d\xc4\x23\x7c\x78\x44\xd4\x5f\x4c\x40\xf7\x59\x92\x46\xa8\x4d\x83\x53\x3a\xfb\xcf\x39\xf3\xef\x51\x48\x89\x08\xfd\x64\x5f\x17\x8d\x63\xee\x4e\x72\x9f\xe1\x2d\x0f\x69\xca\x3d\x8c\x07\x57\x4c\x8f\x2e\x9c\xcd\x8c\x06\xc9\x6f\xc8\x62\x89\x61\x65\x47\x9b\x75\xfd\x44\xfb\xea\xa2\xae\xad\x25\xd1\xfa\x6d\x85\x38\xd9\x72\x12\x32\xc9\x44\x2f\xab\xf0\x08\x1f\xce\x55\xe1\xeb\x3b\x16\x86\x31\xb5\x92\x02\xa3\xfe\xf0\xec\xaf\x8a\xa9\x46\x69\x9f\xcc\x79\x22\x4f\x00\xe6\x7e\x54\x6a\xeb\xb1\x47\x38\x94\xe3\x94\x35\x8c\x53\xb0\xbb\x78\xdd\xc9\xab\xc2\x18\xe9\x4f\xc2\x84\x12\xfc\x92\xfa\xb5\xfc\x58\x7a\xa3\xeb\xae\xc9\x48\xc2\x84\x83\x48\xfa\x8c\x07\xdc\x72\xd8\x7f\x3e\x25\x88\x58\x50\xd8\xad\xa9\xfb\x1d\x3c\x4c\xa4\xad\x12\x0a\x64\xf6\x2e\xf3\x0c\x8a\x66\x6d\x1e\xcb\x66\x4a\xf5\xf5\xe3\x0d\xd0\x64\xca\xc7\xaf\xad\xbb\x04\xd6\xcd\xbf\xea\x02\x91\x30\xe5\x1a\xdf\x7e\xf4\xf2\x7a\x5c\x3c\x4c\x3a\x2a\x24\x4c\x8d\xc4\x77\x69\xfb\x2a\x4e\x50\xbf\x66\xa6\xb9\x29\x9b\x6d\x99\x8f\x13\x89\x50\x90\xd0\xcf\x25\xa7\xda\x74\x05\xa8\xec\xc7\x2b\x15\x84\x9d\x5a\xd0\x7d\x29\x8a\x61\xdf\x84\x84\x92\x32\xd4\xd2\x5b\xad\x87\xf4\x36\x12\xca\x38\x42\x71\x89\xba\x11\x07\xd8\xb3\xfd\xa9\x57\xd3\x23\xa1\x4c\x2d\x85\xec\x1e\xde\x21\x1f\x7d\x4c\x85\x1c\x49\x79\x0e\x21\xfb\x20\x06\xe2\x72\x24\x54\x11\x10\xd7\xe2\x57\xd6\x76\xe8\x42\x16\x85\x84\x4a\x10\x04\x0b\x95\xae\xc6\xb5\x14\x79\x2e\x85\x7a\xfb\x26\xea\x81\xde\x0f\x09\xb5\x49\x30\x5f\xab\xcf\xb2\xcd\x0f\x9a\x55\x73\x61\x42\xeb\x46\x02\x91\xe8\xea\xb6\x3f\xb8\xc2\xa8\xbd\x05\x6d\x6a\x8b\x6b\xd2\xa4\xe1\x9b\xf8\x8f\x45\x0a\x8b\x06\x37\x28\x41\xee\xbf\x16\x74\x10\x46\x97\x39\xf6\x84\x12\x4f\x42\xc3\x13\x87\xf3\x2a\x74\x87\xb3\x23\x11\x31\x92\x53\xe4\xfd\xe3\xce\xf4\x00\x8d\xd0\x03\xa8\xe0\xe8\x15\x8b\x58\x64\x97\xbe\x3b\x91\x55\x9f\x77\xa2\x3a\x76\x35\xec\x88\x25\x12\xeb\xf9\x07\x51\x3f\x89\x4f\xd9\x91\x4a\x49\xc4\x52\xcb\x11\xc0\xe2\xd7\xbc\xab\x83\x1f\x29\x63\x0c\x91\x51\x5f\xf3\xce\xdd\xe6\xd1\x3d\x0c\x93\xe1\x7a\x14\x85\x24\x4e\xdd\xe4\xdb\x95\x8e\xb8\x30\x9a\x9e\x51\x48\x6c\x86\xd4\xbe\x89\xb7\x99\x50\x55\xd6\x28\xff\xc2\xb7\x07\x95\xa3\x18\xef\x34\xa0\x9c\xca\xe4\xe1\x47\xa1\x26\xf8\xf9\x57\xc8\xf5\x58\xde\x72\xfc\x4c\xa3\x28\x4d\xbd\x54\xdd\x5d\x05\xb0\xac\xca\xfe\x7b\x22\xc9\x11\x30\xbe\x2c\x8b\xf7\x02\xaa\x66\x57\x6e\x41\x55\x8e\xad\x31\xde\x0e\x23\x4e\x12\x69\xd5\x39\xcf\xa3\xbe\xaa\xcc\x01\xed\x15\x43\x7f\x52\x1e\x5b\xdb\xe8\xb7\x5a\xdd\x8c\xed\xec\xac\x82\xe9\x57\x94\xf9\xe9\x1e\xf3\x3f\xff\x77\x72\x11\x89\x25\x99\x0e\x42\xee\x4d\x8f\xc3\xee\x2a\x51\xed\xc5\x95\x67\x27\xe4\xe9\x3f\x9a\x5a\x09\x93\x1e\x7e\xbb\x45\x33\x58\x07\xc2\x6d\x7f\xc7\x63\xe9\xc4\xb2\xdd\x47\xe2\x90\x63\x95\x68\xf7\xcf\xe5\xcb\xdf\x4c\x89\xa2\x38\x21\x88\x53\xe8\xbb\x30\xcb\xcd\xc3\xfa\xc7\xca\x02\xe0\xae\x64\x35\x51\x12\x0b\xec\xd5\x1f\xc5\xaf\xbb\xac\x28\xe0\xf3\x09\xb0\xae\x72\x0f\x75\xbd\x7b\x15\x7e\xd5\x88\x12\x41\x71\x22\x42\xd3\xdd\xd6\xa6\x5c\x2c\x97\xe3\x25\x32\x4a\x03\x70\xd8\xb9\xcc\x6a\x5c\x78\x8d\x46\x7f\x1e\xc1\xac\xa8\xc6\x5b\x96\xe7\x8b\x42\x3f\x5b\x6f\x02\x77\x50\x49\xeb\x09\xbc\x3f\x5d\x97\x46\x9a\x0f\x06\x22\x1d\x58\x52\x16\xda\x62\xbf\x14\x73\xfb\x43\x04\xa9\x46\xbd\x1b\x6d\x6b\x15\x7f\x09\xbe\x23\x91\x61\xd6\x66\x78\x3b\x28\xb9\xff\x63\x8c\x50\xb3\x23\x79\xc0\x03\x44\xb5\x60\x34\xb6\x84\x6a\x22\x73\xe8\x47\x09\xa2\x6d\xc8\x52\x08\xab\x90\xf2\x9b\x3f\x02\x04\x83\x19\xe7\xac\xec\xaa\xcb\xc3\x48\xd1\x0d\x24\x8a\x49\xd3\x29\x49\x39\xee\xf0\xf8\x29\x70\x4a\xa4\xdf\x51\x6e\x45\x03\x4f\x65\x3d\x15\xae\x22\x9c\xf1\x34\x11\x83\x4e\xd4\x5d\x59\x0d\xec\x13\x27\x63\x93\xc8\xd8\x28\xb7\x6e\xaa\xf2\xd3\xbd\xf5\xb3\x85\x7d\xce\x64\xec\x4c\x45\x9b\x26\x87\x1b\x98\x10\x2f\xfd\xbf\x7e\xfb\xe7\x61\x68\x9d\xb8\x3a\x35\x40\x54\x36\xdb\x95\x18\xbb\x7f\xeb\x93\x76\x1e\x0a\x15\x05\x4e\xf1\xcd\x93\x88\xdd\xa1\x28\x34\x48\x8e\xa9\x10\xbb\x35\x7d\x59\xdc\x20\x4e\xc0\xe3\x7d\x6c\x88\x77\xd1\x69\x1b\x5d\x17\x27\xc6\xa0\x2a\xb7\x68\xa6\x4b\x20\xe7\x54\x20\xbc\xb4\x16\xef\xf0\x50\x1f\x6e\x3e\x5f\xea\xf9\x24\x91\x73\x19\x63\xe7\x17\x31\xdd\x0f\xd0\xbc\x96\x7e\xb2\x73\x2e\x01\xb1\xcc\x37\xeb\xc7\x21\x2d\x96\xf0\x38\x8c\x92\xc4\x57\x7d\x2c\xba\xb5\xbf\xd9\x7d\x32\xc3\xe3\x28\xa4\x3d\x02\xed\xae\xde\xfd\x70\x74\xc4\x66\xd2\x42\xe1\xb1\x96\x28\xf5\x06\x0e\xec\x30\x14\x19\x20\x3c\x11\x16\x73\xe8\x14\xfb\xf5\xa2\x02\x31\x39\x41\x22\x00\x27\xcb\x3e\xab\x9f\xaa\x9e\xdc\x4b\x78\xa2\xac\x6a\xcc\x3b\xba\x57\xbb\x3f\xca\x94\x3a\xd9\xfa\x3c\xbf\x41\xdd\xd4\x99\xab\x97\xc2\x7a\x66\x39\xf9\xd9\x76\xd6\x11\xe7\xd1\xd2\x9d\x47\xb3\x0e\x42\x2e\xa6\x88\x2a\xc2\x55\xac\x11\xcc\x60\xdf\xf5\xc5\xd8\x43\xf9\x6f\x27\xb1\x23\xd5\xf4\xfe\xcc\x69\x32\x06\x1a\x8e\x83\x5e\xae\x92\xc0\x4b\x71\x74\xc2\x00\xb3\x4b\x08\x57\x89\xc6\x4e\x36\xfa\x6b\x7f\x3a\x38\xea\xe0\x3e\xa8\x94\x21\xda\x76\xfb\x21\xaa\xcb\x39\x39\x3e\x97\x96\xd6\xca\xd8\xb9\xbd\x65\xea\x8b\xe2\x2c\xd7\x4e\x6a\xeb\xd0\x11\xa6\xb7\x6d\xa6\x70\xbe\xc2\xd7\x27\x1c\x68\x12\xba\xdf\xe4\xc5\x84\x3c\x07\x28\xf1\x43\x52\x16\x06\x9d\x5e\x4b\xfb\xd9\x45\x55\x89\x4f\xdb\xae\x9c\xad\x61\xb7\x1f\x41\xdb\xaf\xdb\x17\x16\xfc\x45\xe2\xcb\x0d\xb3\xc2\xd8\x07\x68\xbe\x8b\x4a\x96\xd5\xfd\xb0\x70\xe8\xdc\x4e\x89\x3f\xb3\x89\x0c\xa6\x07\xb7\x20\x9a\xd7\x3b\xac\x69\xee\xb3\x77\x3f\x79\x8c\xa4\x26\xed\x1a\x96\xbd\x40\xcc\xd7\x2b\x3e\x37\x60\x31\x64\x4b\x91\xab\x3e\x09\xb6\x07\xe3\x80\x45\xd4\x65\xab\x98\xd4\x3d\x94\x15\xb4\x9b\xe4\xa6\x80\xd5\xee\xfb\xe0\xa9\xc6\x81\xd6\x08\xf3\x79\x70\x0e\xe0\x03\x95\x04\x37\x82\x46\x2a\xb5\xc8\x22\x14\xf0\xc4\xb4\xd9\xbf\x41\x31\xe5\xd6\x2b\xed\x74\xae\x3b\xc1\x76\x87\xa9\xfa\x52\x5a\x82\xc4\x34\x4e\x02\x0b\xb2\xca\xb3\xe6\xa9\x6c\xba\x33\xc6\x06\x5f\x37\x0f\xe0\xbf\x05\x04\x1f\x0d\xcb\x1f\x31\x15\x51\xdc\x57\x31\xbf\x41\xe1\xec\x0a\xb6\x4d\x79\xba\x30\xb3\x48\xfc\x87\xb4\x40\xfd\x29\x68\x5e\x37\x3a\x2b\x06\x8e\x87\x24\x66\x32\xd0\x56\x49\xc3\xa6\x5f\x5d\x8c\x1d\x87\x9c\x29\xda\xad\x5d\xf9\x29\x9a\xdc\x9d\xd0\x10\x6c\x47\x3d\x88\xe2\x2c\xf2\x07\x2f\x9f\x37\x19\x15\xc5\x02\xab\x2f\xbb\xf5\xc3\x6a\xf3\xb2\xbb\xb9\xdf\x2c\x7f\x6c\xfd\x57\x44\x89\x44\x62\x45\x21\x9a\xec\x7d\x54\xd8\x8c\x23\x95\x70\xd1\x55\x2c\xb3\x06\x8d\xe8\xfc\x41\x1e\x05\xb1\x03\xdb\x3c\x89\xe6\x75\xbc\x15\xc6\x3c\xb1\xf6\x9c\x5b\x8c\xdb\x7a\x7d\x2c\x7f\x3b\x62\x1a\x72\xf0\x10\xe9\x5c\x7c\x4e\x3e\x1e\x47\x11\x1a\x19\xfd\x59\xfd\xea\x21\x37\x7d\x1b\x39\x8e\xa3\x98\x39\x35\xa1\xef\x18\xc2\xfa\xdb\xce\xc3\xc9\x83\x8e\x79\x88\x40\x86\x76\xc4\x16\x89\xf5\xfe\x80\x24\x89\x6d\x82\x16\xcb\xb2\xac\x74\x56\x88\xc6\x3b\xe7\x75\x43\x2c\x30\xe3\x77\x91\x6b\xc8\x45\xff\x67\xdb\x08\xf2\xa9\x3e\x12\x15\x87\x2f\x68\x9c\xd2\x04\x1b\x3e\x37\x9b\x9b\x0d\xb2\x44\xfc\x47\x05\xb3\x40\xad\x13\xe2\x96\xbc\x9a\x1b\x89\x45\x94\x20\xa7\xe9\xb3\x2c\xa5\x40\xd1\xa3\x51\x81\x21\x16\xb1\x95\xaf\xc1\x1c\x96\x0d\x65\x31\x48\x2c\x69\x24\x3c\x7a\xcb\xe5\x60\xb3\x5d\x9c\x58\x32\xe7\xe4\x6d\x13\xd6\x4b\x5e\x40\x3b\x24\x02\x6b\x51\xd6\xbe\x91\xd3\x83\x26\x41\xf0\x85\x2d\xfb\x7d\x88\x4a\xdf\xdc\x8c\xd7\xfb\x58\xc9\x38\x8e\x3b\x27\xb4\x67\x68\x3e\x00\xa6\xa7\x01\x42\xd1\x50\x08\xe3\xfc\x2e\xf5\x78\x46\xf9\xb2\x7e\x67\xee\x06\x5b\x25\xd7\x2d\x34\xe7\xd3\xcf\x9f\xcb\xbf\x00\x97\x4d\x71\x36\xb3\xfb\x43\x0c\xb1\xa0\x81\x8f\xe9\x90\x80\x88\x5d\x81\xf1\x20\xa3\x62\x0c\x0e\x95\x28\x1e\xd0\x3d\xe0\x5c\xe8\x99\xee\x4c\x6c\x80\xfb\x86\xac\x33\x20\x76\x30\xcc\xee\xb8\xc2\x60\xfd\xa5\xb8\x56\x1a\x4a\x82\x84\xa4\xee\x65\xb8\x39\x7f\xee\xa6\xf6\x62\x24\x09\xd2\x14\x89\x8c\xe0\x9c\x12\x06\x85\xf8\x24\xd0\x52\xda\x47\xb6\x12\x55\xfe\x79\x93\x55\xb3\x96\xf0\xed\x48\xa0\xc8\x5b\x5f\x14\x05\xfc\x82\xfd\xf2\x69\xbb\xe7\xfe\x2c\x14\x2c\x67\xc0\x88\xda\xbe\x51\x59\x71\x18\xd8\x0e\x90\x84\x1a\x8b\xe6\x6d\x9c\xf4\x53\xf1\xe6\x04\x2c\xfd\x1c\x4d\x42\x95\xca\x4e\x0e\xde\x3f\xc0\x24\x22\x32\x71\xcb\xc4\x83\xf8\x95\x1d\xcf\x47\x54\x8c\x59\x17\xab\x73\x55\x2e\xb1\x33\xe9\x47\xa6\x04\x8b\xce\xca\xf7\x32\x86\x45\x89\xff\x3a\x97\x8d\xe8\x46\x8a\x24\x0d\x86\xf4\x37\x9b\x1e\x4d\xe6\x7b\x12\x49\x8a\xdb\x24\x1c\x4f\x8d\xdb\x7b\xc7\xc0\x49\x92\x70\x26\x91\x33\x8b\x91\x42\xed\x4d\x31\x1f\x66\x51\x02\xe3\x49\x94\xb4\x3b\x67\xec\x3b\x23\x2a\x6b\xb2\x3f\xa1\xd0\xae\x1d\xff\x37\x90\x22\xee\x2c\x71\x92\xa2\x82\x42\x56\xdf\x82\x9f\x1f\xed\x8a\x39\xf9\x29\xb1\x88\x30\xa8\xcf\xcb\xc3\x52\xe4\x17\xa8\x7e\x3f\x0a\x04\x92\xee\x85\xd6\xb8\xe5\x4e\xf7\x22\x1f\x12\x24\x09\x0b\xd1\x78\xae\x13\xf0\x43\xe8\xf8\xb9\x17\x3c\x21\x49\xaa\xa5\x20\x2e\x38\xb5\xf5\x8d\x71\x3a\xe3\x86\x89\x94\x78\x49\xd8\xfb\x52\xbd\x3d\x55\xa5\x3e\xab\x69\xb7\x39\x11\x86\x22\xec\xf2\xe9\xfb\xd3\x9c\x0f\xf7\xe8\x8e\x48\x12\x5b\xbf\xbd\x73\xf1\xb7\x79\xdb\xfe\xa3\xb1\x15\xda\xaa\x6c\x32\xdd\x17\x57\x13\x15\x51\x4c\xdf\x1b\x4f\xf7\x2a\x73\xbf\xf4\x3c\x96\xcd\x50\x7d\xa1\xfb\x44\xa2\x30\x2e\xc2\x6e\xf2\x00\xd7\x4e\x12\xcd\x12\x05\x43\x55\xc6\xc7\x01\xad\xc9\x8f\x51\x81\x71\x51\xbb\x6a\xe3\x1a\x87\xf8\x1d\xaf\xea\x09\xb0\x50\x47\xbe\x87\xf6\x59\x9e\x9b\x29\x97\x9c\x24\xa0\x23\xec\x12\xf5\x5e\x70\x3b\xf1\x6b\x32\xc6\x10\x86\xfc\x96\x1d\xd4\xcd\x75\xaa\xf3\x65\x1c\x99\x18\x99\x78\x59\xa4\xbb\xec\xd7\xa5\x88\x25\x49\x0c\xc4\x48\x89\x5a\x64\x6e\x55\xb3\xeb\xe5\x40\xea\x81\xa4\x01\xe5\x88\x11\x2a\xe0\x63\x29\x8e\x27\x91\x1d\x0a\x27\x3c\x32\x3e\x59\x1a\xa4\x96\x29\x83\x24\xcb\xe3\x09\x1a\x6c\x6d\x3e\x43\x7d\xce\xdd\x8c\x61\x74\x90\xfa\xa4\x81\xb6\x7a\x9f\x9d\x4a\xdf\xb2\x12\xd2\x7f\x2b\x21\x1a\x77\xc4\x87\xd5\x6e\x71\xbb\xd8\x2d\xf6\x2f\xcf\xf7\xdd\x31\xc6\xb1\xdc\x79\xae\x64\xe6\xb0\xab\xa3\x1b\x9f\x92\x28\x44\x49\xeb\x45\x91\x1d\x41\x89\x4a\x2f\x7b\x44\x65\x4a\x55\x88\xd0\xa4\xcc\x69\x22\xec\x47\xc5\x97\x94\x25\x12\x6f\x9a\x2f\xea\x6e\xad\xb4\x70\x57\x94\x4a\x99\x8c\x59\x67\x6d\x58\xdf\xa2\xd4\x43\xf7\xe9\x30\x81\xd0\x89\xf9\xa1\xc7\x49\x67\x9d\xd1\x0d\x00\xe6\x5b\x6f\x77\xe2\x08\x48\xf8\xbc\xf9\xc4\x29\x36\x7c\x76\x69\xe4\xf2\x21\x25\xea\xd7\x01\x08\xef\x2f\x9b\x93\x8e\x8d\xd4\x47\xeb\x69\xa4\x83\x94\xfb\xeb\x75\x1d\x80\xee\x7a\x23\x43\x2d\x28\xa9\xfc\x78\x10\xc5\xe7\x1d\x74\xc1\x77\x9a\x04\x56\x30\xc4\xee\x5a\x4e\x0a\x6f\x36\xf2\x48\x53\x19\x43\xe8\x37\x01\x24\x49\x8d\x1e\x47\xaa\x12\x6c\x7d\x6c\x85\xc9\xaa\xa1\x68\x0f\x49\x45\x2c\xad\xd9\x4e\x53\x9e\xfa\xf0\xd6\x1f\x94\x31\x8f\xc7\xda\x8b\xaa\x19\x4f\x4e\xa1\x04\x42\x79\xdb\x1d\xde\x67\x08\xd3\xab\x93\x32\x45\x44\x13\x36\x06\xd6\xb6\x07\x94\x15\x87\xe7\xf6\xbb\xfc\x79\xa4\x4a\xb0\x6e\x25\xcb\xe2\x5c\xc3\x08\x86\xd6\x1e\xc3\x47\x91\x15\x59\xe3\xfc\xf2\xd7\xaa\xfc\xdf\xad\x5d\xa9\x66\xdc\xf4\x0a\x40\x63\xdd\xd4\xf1\xe5\xb6\x8b\xbc\xd5\xbd\x2f\xd5\x9b\x2d\x07\x4d\x7e\x90\x21\x0a\x17\x04\xab\x90\xeb\x8b\xae\xfa\x6b\x98\x7b\x6a\x64\x8a\x9b\xc2\x03\x14\x8d\xc8\xbf\x83\xc8\x9b\xd7\xfb\xcc\xc0\x0c\x7e\x37\x35\x9a\x29\xd4\x6e\x85\x06\xaa\x63\x56\x74\x5f\xe2\xee\x89\x08\xa2\x20\x71\x35\x89\xf5\xf1\x24\x54\xf3\x52\x1c\xdb\xb0\x02\xb4\x25\xc4\x0c\xe7\xb2\x08\x22\x16\xf6\x7e\x74\x5b\xa1\x75\x0e\x17\x12\x2a\xff\xcf\xff\x8e\xee\x8d\x20\x4a\xe3\xab\xaf\xaa\xf2\x43\xb7\xef\xf5\xaa\xd0\x03\xb0\x90\xa0\xb1\xd0\x96\xcd\x00\xba\xc6\xb5\xa3\x47\x77\xf9\x21\x89\x75\xd8\x3b\xda\xa4\x75\xc4\x41\x10\x34\x15\xcc\x45\xe3\xbf\x7b\x2f\xfa\x2f\xd1\x66\x82\xaa\x10\x4b\x9a\xed\xe3\xf4\x8b\xec\x1b\x14\xed\xeb\x36\x8d\x57\x04\x4b\x28\x32\x58\xfe\x7b\xf7\xfd\x2b\xb8\xee\x20\xd3\x12\x0c\xa2\xc8\x39\xc9\xcf\x02\x62\x45\x18\xc6\xa1\x43\x72\x6c\x4e\x56\x69\x61\xf4\xb0\x45\xc4\xad\xfb\x8f\xf2\xd2\x6d\xa8\x30\x39\xa6\x19\x88\x28\xe6\x84\xf4\xab\x08\x6e\xc0\x55\x3d\x6a\x61\x8a\x28\x11\x18\xf9\x9b\xbc\xfc\x70\x36\xd7\x7d\x4e\x27\x38\x53\xb8\xb0\x62\x33\xf8\xa1\x2b\x6f\x09\x1e\x2b\xed\x6d\x32\xaa\x4c\xdb\xf9\x38\x96\x12\x1a\xcf\x64\xc1\x53\xdb\xcf\xcd\xe1\x1d\xf2\x3d\xd9\x8b\x61\x9f\x50\x70\xad\x95\x0d\x98\x11\x34\x30\xb2\x88\xed\x86\x58\xb9\xde\xbb\xfb\xf5\xb7\xef\xbb\xfd\xe3\xcb\xc3\x4d\xd7\x36\x13\x1c\x38\x86\x6c\xbb\x4a\x68\xdc\xdb\x45\x35\xd9\xe9\x04\x37\x56\xce\x17\x95\x15\xae\xbd\x76\x97\x4b\x73\xb7\xf5\x89\x38\xb6\xc6\x97\x07\x68\x56\xbf\xa0\x52\x59\x0d\x56\x65\xe9\x16\x84\xee\xd5\xba\x89\x48\x84\x49\x44\x2f\x70\x0f\xd5\x53\x95\xfd\x39\xd9\xc5\x45\x4a\x82\xd4\x2b\x4c\x82\xe3\xc6\x4f\x87\x08\x8a\x58\x22\x28\x34\x42\x20\xe6\x23\x4c\x91\x9a\x14\x7b\x4c\x7b\x79\xfe\x6c\x03\xd1\x5d\xb9\xcc\xcb\xfa\xaf\xe3\xb4\xf1\x8c\x13\x24\xc0\xba\xe1\xb7\xb3\xa8\xb4\x70\xa4\xdb\x71\x77\x58\x08\x22\x95\xea\x20\x91\xd3\x9f\x2d\x78\x80\xb6\x5d\x3d\x21\xe9\x9d\x75\xc7\x62\xb0\xe2\xbe\x1e\x2f\x80\x55\xe7\x91\x60\xc2\xe4\x7a\x64\x94\x70\x67\xed\x94\x8b\x0a\x6c\x7d\x1f\x0d\xce\xda\xd7\x3b\x17\x57\x4a\x87\x42\x72\x6b\x65\xbe\x78\x1c\x9a\x74\x12\x21\x63\x85\x74\xa9\x4d\x01\xcd\xef\x8f\xdd\x5f\x9d\xe5\x49\x01\x1f\x9d\xee\xc9\x98\xd2\xe6\x07\x1a\x2b\x41\xfe\xad\x8b\x2c\xa6\x3d\x9e\xd9\x8d\x41\xa8\x30\xc1\xf2\x7e\x2d\x72\x68\x43\xd9\x51\xf9\x5a\x28\xc1\x11\x52\xf6\x9f\x73\xa6\xde\xb6\x65\x35\x2f\xc1\x44\x84\x26\x04\xdb\xba\xcd\xd4\xcf\x76\x66\x9a\xea\x98\xa7\x1d\x08\xec\x33\x2f\xc5\xb8\x87\x2a\x74\x12\x62\x6e\xfc\x0d\x03\xcc\xf9\x99\xa7\xb5\x41\x30\xba\xd3\xc5\xb3\x35\x30\x61\xd7\xa1\xf1\xef\x83\x94\x48\xe6\xe2\xdc\xb1\xfb\xd9\xfc\x2f\x31\x01\xc1\x32\xa4\xa8\xeb\x52\xd9\x95\x78\xda\xdb\x16\x26\xb5\xe2\x41\x8e\x7b\x03\x85\x03\x44\x87\xc1\xf4\x64\x32\x40\xf5\x3f\xab\xd0\xed\x28\x7b\xee\xa0\x0c\x74\xe8\x01\x55\x03\xd7\x85\x7a\x61\xc1\xc6\x83\x82\xa7\xa4\x31\x60\x93\x73\xb9\xf1\xbd\x01\xc9\x0c\x43\xad\x82\x73\xa1\x4b\xef\xbd\x3c\xba\x48\x19\x06\x02\xfd\x44\xb3\x93\xa9\xc7\x91\xac\x0c\x49\x84\x71\xc9\xfd\xfa\xf7\xd5\x70\x0e\xca\xd0\x89\x06\x7c\xdf\xec\x96\xcf\x7f\x3c\xed\xba\xaf\x8b\x28\x47\x6d\x87\xa7\x73\x73\x57\x56\x5f\xf2\x3a\x89\x8c\x58\x80\x9a\x89\x47\xf1\x06\xd5\xc2\x98\x2c\xcf\x44\x33\x48\xac\x64\x14\x52\x8c\xaf\xc0\xee\xa2\x1b\xf3\x7b\x76\xc2\x1a\x6d\x2f\x58\x44\x64\x94\x26\xb8\xfe\xdc\x89\xba\x41\x0b\x56\xff\x77\x05\x08\x2c\x90\x03\x75\xef\x99\x94\x50\xc6\x11\x8b\xcc\x08\x3f\xed\x95\xca\x88\x8c\x85\xc4\x77\xed\xfb\x66\xbb\xdb\x6f\xbf\x2f\x9e\x3d\xb5\x45\x26\xcc\x02\xec\xda\x9c\x0f\x6b\x0e\x8b\xaa\xd3\xd9\xb3\x42\x7b\xa6\x81\x21\x38\x5e\x26\xa1\xc0\xae\xfe\xbe\x0d\xfb\xdb\xc0\xbe\xdd\xde\x3d\x7e\x6e\x74\x87\x92\x09\x31\x66\xce\x73\x80\xc8\x24\x0e\x90\x6e\x84\x95\x36\x0f\x2a\xfb\xb2\x9d\x26\x53\x2a\x71\xce\xde\x97\x87\xcd\x11\x0e\x62\x75\x18\x15\xc5\x27\x8f\x27\xd5\xd6\x8d\xb4\x86\xe6\x02\x5b\x32\xfb\x4e\xc8\x54\x5b\x9b\x85\x6f\x79\x29\x0f\x79\x79\x10\xf2\x20\xf2\x2e\xab\x92\x29\x68\x7c\x52\xed\xfa\x3e\x0f\x5a\x18\x15\x12\xa4\x48\x42\x84\x56\xe3\x3d\x76\x57\xb0\x7b\x85\x36\xe2\xf1\xa7\x14\x82\xe2\x1a\x60\x3d\xa1\x8a\x03\xe4\x17\x4e\xd9\xc3\xc2\x83\x14\x22\xc5\x89\xbb\x7c\xdc\xed\xad\x12\x75\x77\x26\xd0\xd8\x80\x7b\xcd\x2a\xb0\x48\x85\xef\xe7\x62\x6a\x1c\x45\xa4\x0a\x42\x5c\x67\x55\x5e\x16\x50\xef\x9b\xd2\xf9\x45\xec\xcb\x02\xf6\x99\x06\x5f\x46\x92\x8a\x05\x01\x8a\xd4\xc0\x3b\x88\xdc\xa9\xce\x8e\x1e\xa0\x52\x56\xf8\xf4\x4e\xa9\xd1\xcb\x85\x1a\x54\x83\x2e\x81\x8d\x46\x26\xaf\xa6\x56\x0c\x99\x6c\x42\x7b\xba\x81\x43\xc2\x5f\xac\xfe\xe3\xb7\x1d\xe2\x10\xb3\x1a\xd9\xfe\xc4\xac\xcb\xb7\x24\x68\x83\x14\xc3\x45\x2e\xaa\x63\xbb\x06\x4e\xe3\x7e\x69\x98\xd5\x44\xe8\x81\x5d\x3f\x8a\xf2\xa3\xb8\xa6\x6f\xf3\x8f\x4e\xa3\xc2\x7f\x3e\x34\x58\x65\x3a\x9f\x0e\x95\xd0\xf0\x10\xdd\x97\x87\x4c\x4d\xbf\x24\xb2\xf6\xa7\x9d\xe0\xdb\xf2\x55\x1c\x2f\x6c\x16\x26\xd3\xce\x28\x86\xfe\xe1\x56\x21\x75\xe3\x63\x3b\x15\x70\x9e\x3a\xf6\xd0\x3f\x4b\xb9\xb5\x8c\xf7\xfa\x35\x3b\xad\xbf\x36\xd3\x27\x2a\x48\x99\x16\x3d\x6f\x60\xa8\xf7\x4c\x14\x09\x23\x22\xba\x14\xdc\x3a\xf2\x3e\xbc\x35\xdd\xe1\x44\x79\xba\xc4\x4a\x54\x05\xe8\x3d\x4a\x5c\x8d\xe7\x91\x22\x32\x45\xd9\xe5\x77\xa8\x32\xf3\x39\x74\xd3\xb9\xc6\xea\xbc\x16\xe0\xfd\x65\x0e\xae\x18\xb3\x6a\xa3\xbf\x4e\xe2\x0e\xc3\x1d\xcb\x12\xf1\x47\x05\x60\xb4\x63\x1b\x4e\x36\x47\x40\x1b\xb2\x59\x65\x26\xa2\x98\x14\xd8\xc4\xaa\xdb\xac\xf7\x41\xfc\x5a\x74\xc4\x5a\xc5\x8c\x4c\xad\x93\xb7\xa8\x31\x74\xf3\xef\xa9\x0a\x53\xad\xad\x98\x3a\xbc\x67\xa5\x33\xf0\xae\xbb\xa3\x82\x0b\xd7\x25\x5d\xd7\x56\xee\x75\x52\xc5\x56\xa1\x4a\x8d\x25\x3e\x39\xa3\xb6\x51\x1d\x5c\x45\x54\xe3\x45\x2d\xad\x29\xe6\x78\x4d\x1d\x9f\x29\xd2\x09\xee\x88\xf6\xbd\xdd\x54\x07\x31\x06\x77\x28\x4e\x09\xaa\xcd\x38\x65\xd6\xaf\xe0\x55\x8a\x73\x2b\x99\xee\x3c\xc3\x5d\x99\x69\x7c\xc3\x78\x62\xd0\x88\xd1\x64\x85\xbe\xcb\xcb\xb2\xfa\x71\x31\x1b\xb8\x24\xa1\xf4\x80\xb1\x4d\xf3\x0a\x55\x9b\xa2\xcc\x2e\xb2\x2a\x0e\x24\x4d\x7b\xa3\x9a\xa7\xf2\xe3\x2f\x24\x58\xa7\x9f\x67\x29\xbe\xe9\x59\xd1\xcf\x81\xd8\x04\xd8\x8b\x5b\x68\x8d\xcd\x71\xed\x6b\x6c\x57\x8c\xfb\x27\xbf\x30\x09\x58\xea\x5a\xb2\xce\x53\xea\x6b\xfc\xac\x4a\x43\x82\x12\xa2\xc8\x9e\xdb\x42\xa1\x7f\x82\xfc\x96\x99\xe6\x8a\x79\x93\xff\x54\x24\x31\x3f\x70\x02\xf4\xaf\x15\xd4\xaf\x65\xae\x1f\xc1\x8a\xa5\xa2\x44\xc2\xe4\x13\x4a\x09\x0b\x16\x2d\x4f\x62\x84\xc0\x54\xc2\x21\xf0\xee\xb2\xfc\x58\xe6\xff\x3e\x9f\x54\xd6\xeb\xbc\x90\x36\x9e\xe5\x66\x04\xe4\xda\x93\x20\xd8\xdb\x77\xbe\x5d\xf6\x8f\x33\x19\xb4\x12\x89\x8c\xe2\x0e\x49\x6d\x65\xc2\xce\x85\x9a\xad\x5b\x29\x21\x02\xd5\xcb\xba\x2f\x0a\x8d\xc5\xf7\x4b\x78\xb3\x92\x01\x44\x8e\xdb\xf1\xbb\x77\x99\x24\x4a\x46\x11\x56\xc8\x0a\xf8\x58\x54\x4d\xa6\x72\x98\xb7\x8a\x1e\x7f\xa9\x14\x09\x7a\x53\xee\x5e\x6e\x56\xcb\xcd\xfa\x51\x8d\xf3\x64\xa5\x23\x83\x93\xff\xe9\x79\xf3\xcf\xd5\x72\xb7\x79\x5a\x3d\x2f\x76\xeb\xcd\xe3\x7e\xfb\xf2\xf4\x74\xff\x47\x37\x4c\x84\xbc\x7f\x89\x9c\x6a\xcf\x5d\x55\x1e\xad\x46\xc0\xf0\xea\x21\xb5\xde\xae\xf5\xb9\xdd\x6e\x49\xb0\x7d\x43\xb6\x3f\x08\x2b\x5c\x3c\x7e\x60\x26\x90\x4c\x76\x89\xd9\x22\xcf\x6d\x11\xdc\xaf\x14\x3a\x08\xac\xcf\xf3\x31\x2b\x2c\xbb\x00\xcf\x31\x3c\x85\x0e\x98\x26\xc4\x13\xb2\x72\x54\x6f\x9d\xbd\xff\x3a\x88\x83\x08\xf7\x1a\x2b\xfd\xbb\x3d\x41\xa1\x47\xd1\x8d\x1b\x47\x9c\xcd\xf5\x88\xfd\xdb\x1d\xb3\xe5\x32\x25\xf2\xfc\x5c\x43\x25\x66\xbf\x89\x80\x15\xe0\xee\x95\xae\x5e\x6c\x35\xaf\xeb\x80\x69\xaa\x19\x16\x31\xb7\x6d\x32\x91\x3f\x80\xce\x44\x77\xc8\xf0\x30\xed\x35\xf4\xff\x8e\x2d\x08\xd1\x2c\x48\xf1\xc2\x3e\xca\xfc\x6d\x5d\x78\x5a\x8c\x66\x11\xc1\xe2\xdd\x53\x55\x9e\x75\x69\xfe\x28\xcf\xd5\x60\xd6\xeb\x10\x0c\x76\xc6\xff\xf8\xee\x89\xa3\x3a\x4a\x13\x0c\x78\xbc\x7c\xd3\xff\xae\xf2\xa8\x23\x48\xf0\x81\x55\x65\x9e\xdf\x22\x2b\x69\x7a\x5c\x85\xb6\xd7\x0e\x76\xe9\xf1\xdf\xcb\x85\xb2\x76\x76\x5e\xa9\x23\x6b\x5e\xdb\x88\x6d\x0e\x3d\x32\x5c\xbe\x35\x07\xc2\xf9\x18\x37\x74\x65\xf5\xd6\x31\x57\x09\x0c\x24\x77\x6b\xa7\x8b\x7e\x0b\xb5\xfa\x9a\x3a\xaf\x63\x05\x28\x28\xb9\x6a\x5e\xb1\xcf\x38\x31\x2b\xf7\xa3\x8c\xc0\xbd\x55\x67\xf5\x7f\xce\x22\xcf\xcc\xe7\xf7\xf2\x04\xe6\x9c\x4f\xc6\x25\x24\x46\x98\x90\x63\xef\x4f\x8e\xa6\xa1\xee\x35\x49\x6d\xa4\xbf\x6d\xa3\xeb\xf1\xbe\xa5\x53\x4e\x31\x9e\x7c\x86\xd3\xb9\xb1\xac\x9c\x49\x56\xd0\xd1\x29\xfc\x66\xa8\x45\x48\xb0\x9d\x80\xe1\xe0\x67\x1b\x1d\x8c\xe3\x4c\x2d\x42\xe3\xc5\x1a\xb1\x16\x85\x42\x1a\x74\x72\x81\x22\xe2\x5e\x92\xce\x81\x02\x7f\x42\xf6\x4f\xa1\xde\x4e\xe5\xf4\x65\x12\x0a\x88\x95\x40\xfd\xc8\x60\x28\x72\x4d\xb4\xa4\x01\xc2\x91\xf3\xf6\x1d\xdc\x65\x50\x91\xee\x48\x02\x9e\xb4\xef\x3c\x58\x6c\x47\xeb\xf1\x7c\xb4\xca\x1d\x75\x3f\xd2\x02\x06\x8f\x59\x61\x71\xf5\xc3\x45\x7a\x02\x39\x4e\xbc\x7c\x5a\x2f\xa4\xd6\x87\xab\x5a\x2a\x3a\x90\x96\xbb\x11\xc5\xdb\xe4\x97\xa8\xd8\xfa\x82\x6e\x4e\x0d\xe8\xcd\xf9\x8a\x76\x80\x56\xc2\x08\x36\x92\xeb\xeb\x9f\x8f\x8b\x61\x26\xe7\x35\x0c\x43\xa5\x47\xf8\x70\x5a\x81\xb3\x59\x52\x32\x99\xcb\x10\x50\x83\xe9\x25\xfc\x9a\x32\x80\x35\xb0\x98\x19\x47\x86\xe8\x9b\x8a\xa3\xc9\x63\xc2\x08\x29\x07\x3f\xb1\x32\x3f\x35\x81\x20\xda\x44\x16\x32\xdc\x75\x0a\x2d\xfc\x7a\xfa\x3a\x9b\xd8\xf0\xc0\x2b\x95\xd4\x4d\x79\x5a\x2f\x37\x83\x0a\x05\x04\x31\x93\xbc\xf3\x8e\xc7\x6f\xb0\x01\xf4\x6f\x7e\x40\x4a\xd3\x74\xa0\x63\x51\x4e\xd2\x53\x57\x78\x46\x30\x74\x64\xe5\x88\xf7\xb7\xab\xa7\xcd\x76\xed\x57\x2c\x20\x26\x45\x98\x08\xfa\x95\xed\xfa\xb6\x7c\xd8\x23\xcd\x59\x47\xf8\x0c\xdd\xf3\x06\x9a\x46\xb8\x1b\x28\x27\x16\xb0\x13\xf5\xe4\x89\x03\x55\x4a\x7b\x6d\xa0\xdb\xea\xec\x7d\xd5\x09\x30\x93\x12\xcb\xf7\x73\x5c\xc5\xec\xcf\xae\x63\x07\x21\x67\x28\xb7\x7c\x7c\x3f\xdd\x8b\x73\xa1\x5e\xd1\x7a\xbf\x3b\x68\x1c\xa2\xdd\x01\x2f\x68\x77\x24\xb6\x3b\x5d\x3b\xf3\xb0\x0f\x30\x22\xaf\x43\xa8\x63\xff\xca\x59\xe4\x70\x55\x4e\x21\x35\x10\xb5\x79\x8c\x4f\x24\xcb\xbc\x33\xd6\x20\x10\x2b\xe6\x99\xcf\xdf\xc4\x11\x6a\x67\x23\x92\xe9\x2b\x80\x62\x48\x22\x65\xa5\x80\x10\xd1\x56\x95\x66\xba\x4b\x42\xe2\x04\x4b\x0f\xd0\x60\x1f\xef\xcb\xe5\x13\x92\x58\xd1\xa4\xdb\xe7\x77\xe5\xcd\x79\xb0\xcb\x43\x12\x1b\x44\x38\xde\x97\x87\xce\x63\xed\xcb\x6a\x5c\xfb\x09\x9c\x77\xfb\x76\x29\xcf\xfe\x6a\x74\x1a\x50\x04\x35\xf5\xa9\xec\x50\xba\x61\x76\x5b\x81\x94\x71\x44\xec\x88\xa6\x3c\x66\x0a\x8d\x7e\xf6\x3d\x9f\x6c\x30\xb7\xfc\xff\x27\xff\xc3\xff\xef\x30\x19\xbb\xfa\x5f\x3b\x98\xf6\x4b\x50\xe4\xe7\x64\x0a\x56\xc1\x08\x0a\x55\xea\x0b\xe2\xd4\xf8\x8e\x8a\x40\x60\xe8\xb9\xdb\xfc\xf8\xb1\xf0\x37\x52\x44\x10\x74\xdd\xe2\xbd\x99\x52\x57\x66\x53\x47\xf7\x51\x19\x19\xec\xb1\xf9\x38\xd6\x9f\x52\x6a\xc9\x5d\xb9\xbf\x13\xcf\x5a\x5c\xb9\x26\x45\xa8\xb2\x7a\x2c\x27\x3b\xc3\x46\x53\x58\xc7\x46\x39\x90\xfa\x8d\x38\x78\x38\xed\x35\x0c\x2f\x68\xad\xf0\x8b\xf7\x95\x98\x58\xee\x11\x80\x94\x26\x61\x87\x9e\xbe\xb0\xda\x6b\x07\x08\x66\xdb\x32\x4f\x15\xac\x55\x39\x68\xca\x81\x09\x6d\x77\x02\xd1\x07\x7b\x6f\x56\xd0\x4d\x46\xa3\x05\x7e\xaf\xc8\x2a\xb1\x1d\xce\xc4\xd9\x98\xc2\x04\xc2\x3a\x04\x3c\xc2\xaf\x72\xf8\x73\x4d\xa0\x18\xd6\x59\x0f\xe2\x08\xb7\xe7\x51\xd3\xcf\x10\x92\xa0\x46\x90\x12\x55\x71\x3e\x4e\xeb\xc8\x86\x70\x8e\xa4\xb8\xac\x78\x6f\x93\xab\x2d\xea\x45\x0e\x14\x19\x89\xa1\x44\x61\x59\x47\x5c\x01\x60\x8f\xaf\x31\x4c\xd2\xa8\xd3\x70\xf5\xe5\x6e\x7f\x4c\xa4\xd2\x85\xcf\xfb\x53\x05\xfb\xb7\x4f\xb5\xc7\xbe\xf4\x5e\x43\x51\x1e\x2d\x90\x71\x7c\xfb\x4d\x44\x04\x42\xdb\xdb\xb9\x60\x1d\xfc\x3f\x9f\xdb\x0d\xd3\x1f\x8e\x39\x4a\x1e\xbc\x96\x55\x0d\x75\x6f\xb5\x3e\x39\x49\x9c\x58\xf2\x45\x79\xdc\x1b\x00\x5b\x01\x9a\x77\x18\xfe\x9a\x93\x6a\x22\x90\xb8\xdd\xa9\xb2\x78\x47\x5a\xd3\x75\xa6\x44\x3b\x16\x7b\xcd\xfb\x93\x55\x00\x5a\xe8\x36\x9f\x9c\x8f\x17\x0d\x0f\x23\xd4\xd2\x59\x1c\x0e\xd9\xb9\x38\x64\x8f\x70\x28\xff\xcc\x44\x31\xf0\x81\xe9\xf7\x3a\xc3\xd3\x14\xd3\xb6\xf7\xb2\x81\xed\xfb\x29\xa0\x83\x8d\xd0\xc4\x3a\x40\xd0\xdd\xd3\xf3\x6a\x8f\x9e\xdf\xab\x47\x4f\xca\x36\x31\x28\xff\x78\xac\x7b\x81\x3f\x90\x50\x8d\xab\xdc\x09\x7b\x48\x1e\x4d\x31\x7a\x7c\x09\x4f\x7c\x6b\xfc\xa9\xac\x1a\x53\xe6\x59\xb9\x1b\x40\x8f\x4c\x12\xa7\x41\x67\xb3\xfd\xab\xb9\x2d\xcf\x17\x80\x30\x93\xa4\x94\x0e\x3d\x95\x87\x18\xa4\xd1\xaa\xd8\x8e\xc4\x8e\x83\x63\xf3\xac\x9a\x57\x14\x35\x19\xdf\x36\x11\x07\x60\x05\xc3\x34\x56\x85\x06\x55\x71\x23\x62\x6e\x55\xed\x9b\x46\x5c\x7a\xf4\x74\x83\x12\x2c\x3d\x2e\x0e\x55\x86\xa1\xc9\xbd\x90\x90\xaf\xbb\x1e\x80\x11\x09\x45\x8c\xb3\xbf\xe0\x36\x13\xbd\xc3\x3e\xf0\x5f\xbc\x09\x22\xb1\x2a\x00\x7d\x9a\x7f\x65\x9e\x88\x04\x70\x85\xf1\x30\xba\x71\x79\xca\xc8\xc0\xe2\xca\x1e\x9a\x9d\x90\xe5\x68\x9d\x33\x12\x04\xc2\x5e\x97\x2f\xcb\x97\x7f\xf9\x3f\x2a\xa1\xb1\xe2\xb2\x87\xff\x9c\xb3\xd3\xcb\x69\x53\x5c\x29\xc3\x1b\x25\x13\x5c\x7f\xfe\x28\xcf\xbb\xb3\xec\x6e\x9c\x66\xda\x72\xc1\x8e\x50\x1d\xa0\x50\x9f\x5b\x68\x6e\x2d\xea\x76\xb6\x48\x63\x34\x67\xc8\x5b\x58\xdd\xbe\xec\x7f\xfc\xb1\xdc\xa3\x76\x69\x77\x36\x19\xca\xb0\xdb\x8f\x07\x8e\x4d\xee\xb8\x49\x13\x43\x3d\x1d\xa6\x11\xd6\x21\xaf\x5f\x7e\x8c\x06\x25\xbb\x92\xe8\x13\x54\xbb\x36\xb9\x7f\x75\x17\x4b\x83\x20\xb2\xca\x6d\x15\x9c\x72\xa1\x60\x04\x0e\x1e\x5d\x26\x0d\x02\x05\xe0\xba\x0e\x37\x65\x5d\xff\x14\x45\x21\x96\xd5\x27\xea\x6c\x1b\x31\xe1\x4d\xd3\x80\x48\x48\x07\x86\xbc\x83\x1b\x4f\x03\xa2\x43\xcc\x04\x71\x6b\xb9\x0a\x5b\x9b\x07\x38\xf8\x9f\x4e\x03\x4a\x8c\xcf\x27\x17\x76\x92\x5e\x91\xc7\xf7\xe3\xa9\x66\x56\xac\xaf\xac\xe0\x11\x3e\xa6\x46\x79\xf3\x4d\x9d\xe9\x49\xc0\x46\x7f\xbe\x3c\xf3\x24\xaa\x66\x53\x8c\xab\x25\x34\x60\x24\xc4\x99\x85\x66\x14\xbf\x75\x01\x48\xd0\x67\x3a\x83\xb8\x84\xf7\x01\x86\x0b\x7a\x69\xc0\xc2\x04\x01\x96\xb6\xe6\xfa\x8c\x6a\xc7\x77\x65\xd5\xb1\xcf\xdc\xfc\xa6\x01\x33\x56\xe7\x31\x07\x61\x06\xe1\x00\x0d\xc2\x28\x8c\x5c\xb5\xbb\x8d\xd7\x8b\x2b\x2b\x45\x3b\x50\x46\x3e\xd7\x16\xfa\x00\x17\x92\x23\x34\x08\xe3\x28\x71\x54\x73\xa8\x9a\xd5\x7f\xbe\xec\x66\xd1\x20\x54\x40\x86\xbd\xe4\xd5\xaf\xa6\x12\x5f\x46\x7e\x34\x88\xb8\xc2\x4d\x06\xc7\xde\x8c\x4a\x82\x34\x88\x52\xa3\x8d\x23\xd1\x63\x56\x62\x05\xb0\x66\xeb\xc8\x34\xe0\x69\x8c\xf7\xce\xf1\xf1\xba\x6d\x6d\xd8\x18\xa7\x41\x12\x8b\x30\xec\x51\xa3\x5e\x62\x72\x07\xf5\x65\x19\x63\xf4\x3d\xee\xf3\xa9\x34\xd4\x79\x72\x3e\xc0\x11\x66\xf8\x6d\x34\x10\xa1\x54\xda\xb1\x6c\xde\xbb\x4e\x91\xb5\xdb\x29\x51\xdb\x32\x7b\xc7\x86\x63\x0e\xdb\xec\x50\xa0\xb4\xdb\x55\x66\xe7\xf5\x98\x90\x06\x22\x12\x48\x18\xc1\x78\xe0\xae\x3c\x57\xcd\xeb\x4f\x00\xe7\x28\xed\x7f\xb1\x48\xad\x60\xc0\x0e\xea\xb2\x2a\xbb\xbf\x2a\x15\xf7\xca\xdb\xf8\x36\xbf\xfb\x5a\x26\x0d\x64\xac\x59\x67\x29\xd0\xee\x20\xee\x37\xec\x32\xa8\x96\xae\x12\x9e\x4c\x1e\xa5\x94\x16\x6b\xf5\x6c\x7f\x35\xba\x3f\xed\xa0\x10\x7e\x57\xa0\x81\x54\xdc\x4a\x73\x9d\x9b\xd2\x96\x02\x27\x8b\x87\x54\x80\x56\x75\x79\xf9\xb1\xcb\x8e\x80\x84\xe1\x81\xa4\x32\x0d\x14\xd7\xcc\x75\x90\x1e\xac\x0c\x1c\xfa\xd5\xf8\xa3\x0a\xb0\xa3\x7b\x72\x7d\x75\xff\x67\xa3\x90\x14\x72\x12\x9f\xa0\x3b\x58\xe0\xcb\xf6\xd6\x0f\xd0\x2c\x42\x28\xc5\x12\xf2\xdc\x33\x2d\x07\xd3\x50\xab\x00\xc9\x9b\x07\xf4\x67\xf0\xe2\xa4\xdd\x51\xe0\xe0\x5a\x05\x95\xf5\xa6\xba\xeb\x5b\x29\x34\x00\xa2\xf1\x9a\x5c\x73\xa0\x2a\x7f\x7d\x5e\xa9\xa7\xd3\x00\x98\x25\x17\xf8\x36\xfd\x42\x8b\x53\x03\xd5\x8d\xa8\xe7\xd9\x69\x34\x80\x28\x14\xbe\x14\xfa\x7d\x67\x1b\x93\xf5\x50\x34\x96\x06\xc6\x70\x84\x89\x1b\x68\xd4\xab\xd7\xf5\x17\x4d\x59\xbf\x66\xdb\xa6\x8b\xba\x29\x09\x48\x14\x78\xdf\xd1\xb7\x76\xac\xe5\x6d\xcf\xb8\xb8\x51\x42\x82\x80\xe9\xde\x9e\x65\x63\x0c\x46\x01\x1d\x2c\x70\x6e\xe3\xa4\x84\xa4\x2a\x09\x7a\xe3\xd6\x67\x10\xf9\xf2\x4a\x57\x85\x12\x4a\x34\xc6\x63\x1e\xb4\xbe\x28\x3e\xfd\x95\xb2\x40\x63\x7b\xd1\x82\x33\x76\x20\x8e\xa3\x57\x9c\x30\xc2\xd1\x6c\xef\x58\x56\x4d\xdf\x77\xf5\x07\x25\x20\x7d\xb2\xeb\x67\x96\x9d\x7e\xda\x74\x24\x58\x77\x60\xd7\xd7\xc1\xb7\x7d\xb2\x3f\xcd\xff\xce\x88\x51\xec\x2f\x6d\xc5\x6b\x36\x5a\xd0\x48\x14\x59\xd0\x1b\x7a\x97\x8a\x7a\x44\xbb\x99\x9c\x84\x07\x89\xb4\x16\x19\x56\xdc\x7a\x78\x1a\x1e\xc6\x56\x5e\xc5\x3e\x4d\x5b\xb5\xea\x0c\xe4\x29\xe1\xd2\x20\xd5\x74\xeb\xca\xa8\xc3\x1d\xe4\xaf\xf0\x5a\x94\xc4\x34\xc0\xb3\xe7\x60\x1a\xce\xc6\x5b\x02\x89\x53\x69\x2b\xb4\xfe\xbb\x12\x1a\x23\x73\xe0\x5c\x1c\xb3\xa2\x19\x5b\x75\x53\x92\x44\xc4\x23\xdb\x2a\x30\xdd\x5f\x63\x40\x3a\x18\x58\xa1\x21\xfb\xd6\xd8\x0f\xb6\x4f\xb3\x1b\x96\x10\x24\x7e\x2c\x9f\x37\x3f\x6f\xf7\x3f\x17\xbf\xaf\xd8\x48\x2d\x89\x92\x54\x08\x6c\x2d\x7c\x83\xc6\xca\xc4\xac\x76\xdf\x47\x12\x8e\x94\xa4\xd2\x92\x69\x2a\x90\xa2\x81\x4d\x01\x77\x50\x1c\xcf\x7b\x7f\x58\x84\x56\xfd\xcd\x47\xf0\x68\x6e\xdd\x1d\x14\x02\x11\x2b\x7b\xf4\xe2\xcd\x4e\x23\x40\xd3\xe4\x79\x09\x95\xe0\x7d\x58\xbc\x8b\x06\xd4\xeb\xe8\x79\xc9\xc0\x1a\xd0\x3b\x0a\x21\x2e\x23\x0f\x59\x31\xc2\x22\x8e\xcf\x26\x39\xf3\x10\xa3\x47\xf8\xc0\x69\xe2\x8f\xa4\x1a\x41\x20\xc7\xbd\x5d\x23\xfa\x54\x82\x12\x09\x21\x42\x37\x97\x37\x0f\xbb\xd1\x05\xa8\xd0\x8a\xd4\x65\x6d\x28\x78\xcc\x9a\xe6\x8a\x42\x1d\x25\x40\x29\x66\xcb\xc3\x6b\x1b\xfa\x64\x4c\xde\x11\xc3\x62\x64\x47\x38\x4d\x4e\xff\x7d\x26\xb4\x17\xd2\xee\x1c\xae\x40\x3c\xde\x32\x26\x37\xcf\x24\xd6\xd6\xff\x00\xcd\xbe\x4d\xc7\xdb\x7c\xb3\x9b\x43\x46\xa7\xc8\xb3\xdf\x97\x1f\x57\xda\xbe\x94\x06\x54\xe0\x8c\xff\xb7\x05\x4a\xb8\xbf\x12\x12\x61\x45\x78\xf7\x73\xb3\xbf\x5d\xfc\xb1\xed\xfe\x1e\x13\x7c\x0d\x4d\x59\xb5\x6f\x4e\xcf\x87\xe9\x4f\x48\x62\x8d\x38\xda\x76\xcf\xf0\x7a\x04\x94\x92\x34\x46\x16\xe4\x87\xed\x8e\x6e\x0a\x85\x0d\xf7\x01\xe0\x94\x52\xa2\x23\xed\x96\xe4\xdb\xf3\x1b\x3c\x66\xea\x6d\x5a\xdd\xa5\x94\xca\x00\x55\x47\x11\xd5\xdd\x3e\x94\x27\xf1\x39\xda\xb5\x29\xa3\x76\x4f\xf2\xeb\xd4\xcd\x50\x10\x73\xf4\x10\x28\x63\xd6\xa3\xbe\x3e\x8a\xaa\xb9\x2d\x7b\x1b\x4f\x57\x3b\xa7\x94\xc9\x08\x35\x1e\x94\xc8\x15\x42\xf3\x66\x0a\xdd\x94\x32\x25\xb1\x84\xb9\xd0\xfa\x26\xbb\xa4\x1d\x5d\x42\x02\x29\x65\xa0\xbb\xec\x16\x9c\x93\xc8\xe4\xa4\xc6\xfa\x6b\xbf\x6c\x57\xcf\xfb\x6f\x8b\x87\xd5\xfe\xe7\x7a\xf7\xdd\xba\x69\x4d\x86\x7a\x95\x96\x4c\x95\x1b\x87\xfe\xf5\x77\x23\x4c\x2d\xa5\xc0\xe2\xe5\xdb\x48\xaa\x97\x65\xe8\x25\xe3\xa7\x3f\x3b\x52\x11\x26\xc3\x28\x2c\x3c\x7c\x21\x68\x04\x56\x4d\x60\xf7\xb8\x7c\xf4\x7f\xe3\x82\x48\x3e\xa2\x71\x3b\x97\xab\xf1\xdd\xe6\x4a\x83\x72\x45\xe7\x8d\x31\x88\x53\xfd\x2a\xa7\xa5\x94\x83\xc6\x90\x51\xda\x95\x69\x63\x90\xb6\x33\x9b\xd7\x52\x1a\xcb\x08\x8d\x53\x56\xbb\xef\x43\x2d\xca\xf1\xa0\x84\x87\xd8\x59\x2a\xf3\xe6\xd3\xb3\xfa\x28\x4d\x84\x45\x6e\xfb\x2d\xf3\xb7\xcb\xf6\x04\xf1\xd7\x94\x68\x8e\x7c\xb6\x02\x7e\x39\x69\xa1\x61\x9b\x89\xd2\x04\x14\xe6\x9f\x68\x7c\x39\x5a\x51\x69\xca\x12\xa4\x20\x62\x77\xf0\x41\x14\xe2\xd0\xbf\x71\x69\x14\x29\xde\x73\xf1\x3f\xaf\x82\x91\xfe\x4e\xb3\x92\xd2\x34\x89\x10\xc7\xf0\x6b\xfd\x74\xb7\xb5\x4f\xfc\x07\xf8\x38\x80\x0a\x26\x4c\x62\x39\x9b\xa8\x5d\x31\xda\x7a\xa8\xe0\x76\x17\x16\x5a\x2f\x45\xa1\xb3\x91\x3b\xf0\x4c\xd4\x4e\x45\x9a\xc4\x6e\x2e\x7f\xff\xb9\x9c\x6b\x51\x53\x2a\x44\x18\x0b\x77\x5b\x3a\xd3\xdd\xe5\xa5\x36\xdb\xe4\x53\x3a\x22\x89\x6f\xc2\x3c\xc2\xaf\xe6\xc9\x3a\xab\xf7\x75\x17\x4a\x05\x30\xf4\x76\xb9\xab\xc4\x11\xfa\x16\x70\xbb\x52\xd8\x0c\xc9\x02\x93\x66\x5f\xca\xe4\x02\x63\x44\xa9\x64\x46\x86\x63\x03\xf0\xdf\x46\xc7\xd3\x10\xd3\xfa\xbb\xb2\x52\xb0\xac\x3e\x4f\x4d\xd9\xcb\x01\x8c\xbe\x5f\x08\x5c\x9b\x8b\xb2\xf8\x6f\xa8\x26\x29\x22\x95\x5a\x60\x1e\x0a\xef\x50\x34\xbf\x43\xd1\x85\xea\x54\x71\x42\x13\x4f\x27\x47\xff\xfd\xf1\x4d\xd1\x24\xb2\x9e\x1f\x22\x87\x55\xa1\xa9\xff\x1c\x24\x41\xc8\xbd\xad\x43\xa1\xde\x3e\x07\xb2\xef\x94\x82\x4e\x07\x70\xef\x6d\x73\xd6\x50\x34\xf3\x38\x0b\x87\xfd\xb1\xd8\x5d\xf7\x71\x93\x68\x44\xe9\xc9\xf3\xe7\x3e\x2f\xdf\x01\x73\x90\xab\x9f\xee\x7f\xa6\x91\x16\x33\xbe\xfc\xe7\xbf\x46\xeb\x88\x51\x76\x37\x3e\xd7\xb0\x6e\xe0\xd8\xf1\xda\xae\x24\x6f\xf6\x53\x2c\x08\x02\x6f\x91\x7b\x23\xd4\xdb\x30\x7f\x67\x01\xd1\x58\x00\xab\xcf\xf2\xc2\x82\x61\x72\x16\x4e\x51\x6d\xa3\x24\xe3\x77\x97\x05\xda\x48\xd7\x11\x58\xed\xbe\xb7\x79\xce\xe4\x83\x40\x6d\x61\x17\x31\xc1\x7f\xf5\x6a\xba\x0f\x11\x22\x10\x1b\xfc\x24\x3e\x4f\x50\xc9\x1e\x7f\x47\x19\x61\x1a\x55\x86\xf0\x25\xdc\x54\x99\x7a\x15\xb9\xea\xa2\x51\x46\xa4\x31\x41\x27\x4f\xee\x8b\xa7\x94\x51\xea\x14\xd2\x7b\x57\xe9\x9f\x59\xa1\xcb\x8f\xee\x87\x50\x9e\x06\xa9\xf7\xef\x38\x57\xf5\x15\x40\xcd\xe5\x32\xe7\x17\xbb\xe1\x9f\xdc\x39\x19\xb1\x7e\x22\x8b\x36\x39\x18\x3e\x4b\xc6\x28\x71\x3c\x71\x55\x16\xda\xe6\xa7\xbd\x10\x04\x65\x0c\x00\x15\xc6\x6d\xa8\x78\x97\xe5\xb9\x35\x40\xb9\xd0\x53\x1d\x06\x54\x2c\xe2\x80\x5a\xfc\xaf\xa5\x17\x06\xdb\x14\x03\xf3\x0b\xca\xa2\xc4\x2e\x29\x42\xeb\x6d\x79\xae\x14\xdc\x95\x55\xfb\xb5\xb8\xb1\x4c\x9f\x89\x07\x23\x75\x3b\x30\x8b\x94\x70\x06\x3e\xef\x20\x72\x47\x55\x1b\x3f\x3a\xee\xdc\x69\xbb\x9a\x6a\x59\x59\xe6\xb3\xbf\x84\x98\x4b\x20\x4e\xf2\xed\x61\xa6\xba\x7f\xee\x11\xbb\x94\x25\xb1\xc4\x6d\xd2\xc1\x5e\xbe\x97\xe7\x2e\x60\x66\x89\x8a\x41\x0f\xa4\x46\xdb\x6d\x03\x59\x55\x5f\xef\x90\x2c\xd1\x60\x3a\xb1\x4d\x0c\xc1\xf5\x78\xd3\x61\x69\x48\xa4\x77\xeb\x75\x78\xc9\xb1\x29\x47\x3b\x84\xe2\x0a\x7a\x5f\x36\x6d\x40\x07\xe7\x0b\x51\xf5\xcb\x48\x66\xf4\xa8\x52\xa5\x50\xc7\x01\x75\x7f\xfd\x59\x05\x89\x90\x96\x9a\x97\x87\xad\x95\xcf\x1a\x02\xc2\xfc\x7e\xca\x44\x98\x12\xee\x39\x8f\x19\xfa\xf1\x9c\x4f\xdd\x39\xe2\x18\x31\x1b\xae\x19\xb4\x28\xf4\xcd\x00\x03\x7f\x51\xe0\xe9\x1f\xae\x48\x42\xdf\x78\xe8\xb9\xa3\xc3\x39\xa9\xa2\x80\xb3\xae\x16\x6a\x83\x05\x1b\x85\xcd\x86\xf7\x4c\x89\x4e\xd0\xde\xf9\x8c\x3a\x4d\xf9\xc5\x6f\xa3\x07\xa2\xa4\xd0\xde\x7c\xbf\x7a\xbb\xf0\x04\xa6\x4c\x07\x69\xea\x4e\x74\x6b\x55\x88\xd7\xb7\xb3\x5a\x37\xed\x50\x49\x6d\xd0\x0c\x6f\x74\xb4\xd6\x69\x11\x47\x43\xb5\xad\x6e\xc1\x9b\x0d\x8d\x58\xbb\x96\x18\xdb\x51\x5d\x3d\x6e\xf7\x8f\x9b\xdd\xfe\x6e\xf3\xbc\xef\xcd\x8e\x29\x03\x46\x69\x3a\x60\xf3\x0e\xf7\x0e\x06\x42\x60\xd1\x7b\x7b\x2c\x0f\xa3\x37\x1f\x64\x60\x7b\x4e\x1d\x98\xe2\x6e\xb5\xa2\xbd\xd3\x96\x1f\x67\x22\x08\x53\x5f\x15\x43\xcf\xa1\xaf\xab\x9b\xcc\x70\x62\xac\x49\x89\x2b\xbc\x6c\xaa\x27\x51\x37\xb3\xaf\x84\xff\x88\x4a\x71\x47\xd9\x23\xd1\xb6\x2a\xee\x00\x16\x72\x8c\xea\xa0\x21\x49\x14\xe2\x1b\xd0\x3e\xa8\xfe\xf9\x0a\xc5\x23\x34\x1f\x65\xf5\x86\x64\x8c\x57\x2c\xd9\xac\xeb\x1b\xe1\xd7\xda\x90\x28\x82\x42\xc1\x1a\xaa\xec\x1d\x06\x78\xd7\xf9\x0b\x0f\x09\xa4\xf6\x8e\x1c\xa0\x79\x19\xc3\x18\x68\x48\x03\xa9\x3d\xff\xe5\xa3\x4d\x26\xab\x9b\xf2\x62\x8c\x36\xd8\xfd\x7e\xc8\x2a\xa1\x72\xd8\x41\x3e\xc3\x2c\xa5\x21\x35\x52\xba\xe2\xd9\xf7\xf3\x51\x8c\x65\x90\xdc\x98\x30\x88\xb0\x7c\x67\x8b\xea\xd6\xf9\xa7\xeb\xd3\x5f\x5e\x7a\x48\x43\x14\xcf\xfd\xfd\x24\x7e\x8d\x49\x87\x34\x0c\xa3\x14\xd3\xd5\x4a\xbc\x9d\x0f\xa5\xf3\x5a\x1c\xef\x9e\x61\x98\x2a\xd2\x17\xec\xb6\xff\xb9\xce\xe8\x9b\x7c\xaf\x81\x24\xf5\x90\xe1\x4e\xa1\xfb\xcb\x04\x05\x6b\xf5\x74\x1c\xdb\x25\x53\x68\xaf\x1f\x1a\x5b\xb4\xbe\x8d\xe7\xfe\x7b\x7b\x15\x33\x30\xbe\x2a\x4e\x18\x88\xae\xbb\x88\x1b\x16\xf6\x05\xae\x7e\x7c\xfc\x18\x39\x57\xd2\x35\xba\x45\x8e\x21\xf4\xa2\x28\xca\x73\xe1\x18\x3f\x93\xef\x8a\x03\xac\x84\xae\x9a\xd7\x5d\x79\x15\x84\x47\x43\xae\x35\xae\xb3\x99\x2a\xef\xb2\x22\xab\x5f\x07\x2b\x5a\xc8\x4d\x8c\x78\x34\x6b\x06\xaa\xb5\x4f\x30\x66\xdf\x96\x30\x16\x14\x7a\xb9\xec\xdf\xcb\xfc\x3c\x51\x53\xa1\x61\x22\x43\xe6\x00\x73\xcb\xe5\xf7\x3d\xe8\xac\xd9\x93\x68\x94\x8e\x87\x29\xd7\x51\xdf\x2e\xfb\x09\xd9\xb3\xc8\x3a\xb0\x3c\x0d\xd3\x54\xa6\x89\x47\xd8\x23\x85\x14\x8a\x06\x8d\x30\xc6\xcf\x28\x15\x51\xec\xbe\x6a\x07\xd5\xd1\x17\x62\xc7\xd7\x23\x88\xad\x5e\x6a\x10\x56\xfe\xa6\x86\x07\xf1\x36\x2d\xb1\x86\x22\xb2\x26\x0f\x98\xff\x1f\xcf\x97\x77\x51\x86\x61\x60\xf1\x65\xc7\xcc\x6f\x89\x70\x09\xb4\x19\x9f\x55\xc6\x56\x27\xd9\xfd\xf5\x1e\xea\xb7\xcc\x6f\xa0\xa1\x62\x1c\x9b\xb6\x26\x3f\xd7\xaf\xab\x4a\x74\x7f\xd7\xda\x1b\x2e\x2c\x45\xd5\x38\xdf\x95\xf1\x89\x95\xa1\xa8\x7b\xa3\xf2\xb2\x06\x27\xd9\x3c\xbe\x5e\x93\x30\x7c\xaf\x84\xd6\x3d\xe0\x6e\x3e\xb4\x0d\x0d\x10\x12\xa0\x88\x99\x42\x5b\x95\x3c\xfb\xb3\x7f\x1a\x06\x34\xd6\x27\xbb\xae\xd4\x10\xbb\x33\x7c\xac\x51\xc0\xc1\x5b\xb9\xad\x1e\x16\x33\xd5\x89\x28\x00\x85\x2c\x86\x65\x79\x80\x62\x90\xdd\x7c\x5d\x22\x8d\x08\xb0\xc8\xda\x93\xc3\x5a\x95\x5b\xeb\x6a\xe3\xae\x2f\xa2\x41\x8a\xef\x0c\xea\x2e\x6e\x0a\x18\x88\xff\xd2\x88\x29\x1b\xa4\xfc\xf7\xcd\x72\xb8\x05\x45\x4c\x6b\xee\xb1\x37\x65\xe1\xf8\x18\xe1\xe4\x6a\x43\x6a\xf0\x91\xdb\xd9\xee\xab\xed\x4f\x65\x5d\x67\x32\x87\x1e\xcd\x80\x0e\x23\x98\xb4\xd5\x47\x91\xe7\x37\x79\x67\x59\x45\xa3\x88\x06\xc2\x3a\xa5\xa9\x37\x84\x0a\xd9\x1f\xe6\xcc\x19\xc7\x4f\x35\x8a\x92\x00\xf5\x98\xba\x7d\xf1\x5e\x14\xfa\x28\xaa\xb7\x4b\x6a\x27\x8d\x22\x6d\x2b\x56\x47\xf1\xeb\xe6\xfc\xf9\x2c\x1a\x58\x17\x4f\x15\xa8\xac\x57\xaf\xa6\x11\xe7\x11\xd6\xaa\x00\xd5\x8b\x84\x7a\x83\xaa\x1e\xf4\x97\xba\x61\x49\x82\x5c\x3a\x67\x9a\xb3\xf8\xb6\xda\x3f\x3d\xaf\x96\xeb\xde\xd3\x95\x46\x31\xa3\xd8\x07\xf6\xe5\x8e\xe7\x65\x77\x24\x02\xd4\xa5\xdf\x67\xb5\x2b\x44\x4c\xaf\x35\xe6\x29\xbe\xd1\x76\x35\x7d\x68\x77\x0a\x30\x4e\xe2\xe8\xae\xac\x56\x5e\x73\x7b\xfc\xa9\x84\x05\x71\xd0\x17\x72\xd6\xc7\x53\x59\x35\xb5\x77\x33\xf2\xdf\x9e\xc4\x5c\xdb\x78\x27\xdb\x95\x56\x3e\x76\x7a\x1e\x11\x60\x46\x64\xb7\x18\xb4\xff\xf9\x5a\xe1\xea\x7f\x9c\x3c\x7a\xfb\x51\x81\xe9\x61\xd7\x4e\x3a\x96\xcf\x70\x18\xbe\x49\x73\xf9\x6b\x94\x48\x60\xb4\xab\x9f\x59\x0f\x93\x43\x57\x12\x20\xd3\xf9\x9d\x46\x01\xae\x51\xaa\x77\x4d\xac\x47\x29\x43\x94\x46\x94\x39\x7b\xb3\x27\x8f\x13\x71\x59\x17\x9d\x34\x06\xa3\x54\x07\x28\x04\x00\x85\x16\x36\x69\x28\x2f\x2b\xae\x91\xa0\x22\x1d\x90\x49\x66\x70\x67\x93\xd3\x8a\xc8\xd6\xeb\x6a\x2b\x30\x83\xeb\xdf\x60\x65\x19\x55\x01\xfc\x47\x34\x20\xb5\xd4\xb9\x03\x5c\x65\x3c\x8e\xc3\xf0\x48\x46\xca\x56\xbc\x76\x8b\x1f\xab\xfd\xe2\xe9\xd9\xdf\x05\xa9\x62\x14\x1b\xef\xd9\x71\x03\xa4\xdb\x95\xcb\x96\x3a\x0c\xd2\xbe\x01\xfd\xd4\x5e\x77\x56\x16\x17\x5d\xa8\xf1\xfe\x1f\xa9\xc4\xaa\x06\xee\x5d\xd3\x67\xad\x4a\xd4\x79\x7e\xb0\xee\xbc\xfe\x8a\x54\xaa\x18\x1b\x74\xf5\x51\xe9\x7c\x3e\x30\x8f\x74\xa8\xd1\x99\xf7\x98\x15\xd6\xea\x6e\x76\x31\x8e\x4c\x20\xac\x25\xb1\x25\x95\x80\xbe\x2b\xab\x4e\x9c\x65\xd1\xcd\x08\x03\xc4\x6e\x7e\x0d\xf8\xa5\x90\x13\xce\xb0\x3c\xfc\xf0\xf4\xc7\x7c\xdb\x84\x93\x98\x63\x60\xda\x7e\xff\xb3\x45\xd6\x8e\xd7\x20\x4e\x8c\xc2\x14\x07\xd1\xc7\xa2\x98\xb4\x8c\x39\x25\x02\x57\x81\xef\x4f\x37\x23\xb2\x92\x3f\x1c\xa5\xa2\xf7\x62\x7d\xf8\xfc\x5e\xcc\x1a\xc5\x51\x1e\x92\x18\xf9\x03\xba\x12\x59\xb1\xda\x7d\xf7\x3f\x21\xa4\x14\x77\x88\x5b\xf1\x59\xef\xca\x5b\x8b\x2d\xe8\x0e\x72\x91\x3a\x1e\xc9\x7a\xb9\x19\xa6\xf5\x3c\x4c\x15\x42\x5a\xdf\xcb\x06\x76\xe5\x5d\x05\xf0\x27\xf4\x7e\x82\x94\x87\xc2\x6a\x7b\xfc\x58\x3f\xee\x9f\x56\xcf\xfb\xbe\x1d\xcd\x43\x63\x9d\x8e\xf7\xf2\xfc\x79\x97\xe1\x5b\xf7\x05\x08\x80\x47\x24\x42\xe6\x22\x52\xea\x2d\x7f\xb9\x38\x2c\x5f\x45\x51\x80\xef\xe7\xf3\x88\x85\xa8\x8f\xfc\xf1\x2a\x72\xf0\xed\xe5\x5e\x57\x8e\xf2\x28\x65\x34\xec\x5d\xe7\xf7\x70\x14\x59\x3e\xd8\x51\x78\xa4\x22\x18\x02\x8e\xf0\x66\xfb\x14\xbc\xb7\x7f\x1b\xdf\x54\x1e\xd2\xa8\xd3\xda\xb9\xcd\xde\xb3\xba\x9c\x47\x93\x52\xce\xa3\xd4\x33\x3c\x17\x79\xde\xa6\x94\x5d\x55\x99\xf3\x94\x59\x0b\x69\xab\xeb\xd3\x25\x90\x9c\x83\xdd\x72\x1e\x3e\xeb\x26\x53\x1d\x7c\x81\xc7\x31\xc7\x4c\xd1\x37\x25\xbf\xdd\xec\xba\x43\x5a\xa7\x2e\xe3\x58\x1c\xbe\x50\x0e\x9d\x4c\x8f\x84\x84\xa8\x9b\xd9\xbb\x68\x67\xd7\x9a\x51\x3c\x61\x91\x95\x0c\xeb\x14\x36\x27\xe7\x0a\x4d\xe0\xb6\xa7\xa1\x9a\x0c\xe5\x09\x08\x0c\x02\xb6\x9b\xbb\xdd\x7e\xb9\x78\xda\x77\x57\x9d\x06\x11\xf3\x61\xbc\x93\x84\xb6\xce\x3e\xdd\x00\x46\xb0\xb7\x7e\xfb\x7d\xf1\xb8\x40\x6d\x73\x7f\xc0\xa4\x34\xed\xb1\x28\xcf\xf0\x5e\xbe\x0d\x8c\x4c\xc6\xa9\x94\xfb\x8c\xe0\x09\xb6\x17\x6e\x9e\xf6\xeb\x87\x87\xcd\xf3\x6e\x71\xef\x4f\x27\x85\x8d\x08\xda\x69\x20\x2a\x2b\x15\xda\x66\x06\xd6\xd9\xa3\xf6\xcf\xd8\x8f\x56\x01\x4e\xcd\xe2\x7c\xec\xbd\xb1\x1e\x4a\x8d\x4e\xf0\x6e\x8c\xa2\x5a\x58\x78\x4a\x35\x52\x83\xa2\x5c\x45\x11\xee\x42\x58\x70\xab\x5f\x97\x65\x61\xed\x91\x46\x5a\x34\x94\xab\x24\x44\xdc\x0f\x66\xd5\xc8\x89\xb9\xad\xc4\xc7\x25\x6f\x8f\x72\x0d\x80\xa0\xc0\xb5\x2a\x57\xbf\xfc\xc2\xc5\x21\x96\xd1\xd8\xac\xa4\xca\x9a\x07\x51\xd7\x13\xcf\x4e\x3f\x3c\xd1\x08\x3c\x6c\xdf\xcc\x2d\xf8\x22\xe0\x5f\x64\x63\x5f\x17\x57\xb9\x09\x18\x06\xfb\xa8\x1b\xbc\xfb\x3c\x41\xbd\x83\xde\x20\xe9\x7f\x48\xf0\x7f\xfd\x40\x4a\xa4\xd3\x1b\xfa\x5e\xe6\xfa\x8a\xd6\x39\xe5\x46\x2b\x84\x62\x21\x98\xf1\xb6\xfc\x98\x44\x32\x71\x10\x24\x08\x1c\x72\xd8\x86\x67\x51\xc1\x57\x5b\xd7\xfc\x65\xc7\x01\xb3\x6a\xe9\x6d\x06\xf2\xcf\x52\x8e\x15\xd5\xff\x9e\xc6\xf4\x50\x03\x8e\xc6\x81\x54\x89\x6d\xd6\xd7\xe7\x23\x2a\x6a\x8f\xde\x9c\x38\x30\x09\xca\x72\xec\x9d\x7b\xc2\x9f\x70\x21\x9f\x49\x63\xc2\x88\xb5\xfc\xcc\x46\x8d\x8c\x98\x46\x04\xfd\xbf\xba\xe7\xbc\xd1\x7a\x68\x7c\x4d\x63\xca\x01\x79\x5d\xed\x3c\x3a\x1f\xfd\x8a\x1e\xf6\x4b\x73\x4c\x65\x82\x1d\x65\x54\x74\xed\x55\xb0\xfb\x5f\xc0\x42\x95\xb2\xa1\x5c\xe0\x9c\xbb\x0c\x8d\x99\x21\xc8\xee\xd9\x42\xb3\x85\xea\x3d\x53\x6d\x28\xf7\x9e\x69\xa8\xee\xe0\x0a\x7c\x26\x0e\x53\x6b\x0e\xfb\xed\x82\xfb\x44\xe3\x50\x30\x88\xb1\x3a\x7f\x82\xea\xd0\x99\x67\xd1\x38\x34\x02\x51\xa9\x37\x19\xd2\x80\xff\x75\xdf\x1f\xd0\xb8\xe0\x63\xe3\x66\x52\x27\x89\xa3\x58\xe0\x2b\xf1\x04\xa7\xa1\x7b\x07\x8d\x23\x11\x10\xee\x2b\x60\x7b\x34\x00\x19\xbe\x8b\x71\x64\xa8\x55\x97\x1b\xe0\x7e\x31\x04\xbf\x4a\xfa\xea\x7d\xd0\x68\xcc\x63\x82\xaa\x68\xaf\x59\x9e\x3b\xb7\xd9\xee\x08\xf5\xca\x01\xb6\x53\x80\xef\xf9\x34\x27\x8e\xb9\xb2\xb7\xe8\x00\x8d\xaf\xfa\xc5\x71\xa4\x3b\x88\x94\xa8\x9a\x4c\xe4\x03\x53\x09\x1a\xc7\x5c\xa0\x58\xa5\x6d\x81\x3d\xbd\x96\x50\x64\xbf\x26\xaa\xea\x34\x4e\xb8\x46\xa3\x30\x0b\xc7\xdd\x9e\xf2\xac\xf1\xb6\x4c\x7e\x84\x0a\x8c\x2b\x8a\x75\x8c\x85\xa9\xc0\x23\x8d\x13\x4d\xbd\x3e\xea\x7d\x56\xc0\xcb\xc9\x5a\xb7\xed\x4f\x65\x99\x4f\xbf\xd2\x00\x12\x9e\x31\xa3\xb6\x2a\x4d\xee\x48\x1a\x24\xd8\xf8\xd9\xfc\xab\xfb\x0b\xb5\x29\x27\xe6\xd6\xbd\x15\xf1\xac\x7d\x0a\x8d\x45\x62\xd9\x01\x42\x6b\x2c\x4d\xdd\xb7\x0b\xb3\xf6\x57\x3d\x8b\x16\x8d\x45\xaa\x62\x27\x1e\x89\xb7\xef\xf1\x8a\x9f\x22\x8d\x65\xcc\x30\xb9\xc1\x18\xbb\x0d\x10\x56\xbf\x1a\xa8\x0a\x91\x0f\x34\x75\x67\xc3\x19\x1f\xea\xc6\x2a\x92\xf8\x72\x34\x50\x37\xdb\xbc\xdf\xee\x63\x2d\x52\x2b\xd7\x6d\x43\xe0\x7d\x93\xf5\xcf\x11\x98\xc1\xac\x6b\xd9\xbe\x6d\x79\x6f\x91\x40\x63\x50\x06\xb5\xa5\xee\x4b\xab\xde\x75\x2b\x9a\x2b\x20\x9e\xd8\x04\xd4\xd2\x3e\x0f\x59\x71\xb8\xf1\xed\xfa\x2b\xef\xa3\x21\x1c\xd7\x82\x9b\xac\xa9\xcb\x42\x34\x83\xad\x2b\x36\xcc\x3e\xa2\x26\x3b\x82\x5b\xa8\xa6\x30\xb5\xd8\x40\x64\x8d\x76\x06\x24\xe2\xfa\xb7\x31\xed\x91\x26\x81\x8c\xac\x89\x75\x4f\xcd\x6b\x53\xf7\x17\x1f\x63\x27\x81\xe6\x18\x34\xd8\x08\xf7\x67\x59\x3c\x9e\x8f\xf3\xd6\x99\x34\x21\x94\x62\x59\xe0\xa1\x2c\x44\xa5\x3c\xac\x25\x21\xda\xa2\x2b\xec\x3b\xb0\xcd\xcb\xa6\x1e\xdc\xc0\x84\xb2\x10\x57\xdd\x8f\xfd\x9d\x35\x9b\xa9\xbb\x23\xb1\x65\x1b\x54\xbd\x93\x54\x77\x28\x65\x88\x06\x75\xfe\x34\xed\x35\xaf\x86\xbe\x72\xed\x08\xee\x9d\x70\x9e\xa0\xaa\x07\x0c\xea\x7e\x3d\x4d\xa8\xd2\x62\x54\x81\xb8\x39\xab\x37\x68\xfa\xd2\x5b\x77\xa3\x98\x26\xa0\x06\x84\x00\x57\x84\x9a\x79\x01\x92\x90\x6a\xef\xed\xb6\xc8\xf3\x36\xb1\xe8\x7e\x51\xc8\xac\x14\x39\x52\x7b\x57\xbb\xef\x4b\x27\xb8\x39\x7a\x37\x93\x50\x59\xcf\x2b\x7b\x82\x85\x5e\xeb\xfa\xe6\x73\x29\x26\x05\xd1\x84\x13\x65\xd5\x07\x45\xfd\xba\x39\x7b\x9a\x9e\x3f\x18\x49\x84\x2c\x1d\xaa\xf2\x03\xed\x10\xfd\xdf\x13\x85\x31\xf3\x22\xab\x74\x55\x9e\xe8\xf4\x9c\xa9\x9d\x59\xcf\x60\xd6\xb7\xb3\xbf\x8e\xa7\x26\x76\x7a\xd7\x9d\x15\xcf\xa2\xd0\x7f\x01\x7b\x77\x1f\x8e\x63\x40\x36\x4a\xb7\x80\xa3\x83\xc0\xe7\x33\xd4\xd8\x9b\x74\x50\x27\xd7\x5d\x9d\x7d\x2f\x92\x58\x68\xcc\x6c\x84\xd6\xdb\xec\x30\x9f\xce\x26\x49\xaa\x12\xdf\x43\xc8\x8e\x70\x49\xf3\xa7\x49\x1a\x0a\x8c\x2e\x36\x56\x4a\xc8\x96\x9d\x47\xdb\x4d\x92\xf2\x28\xb5\xd2\x7f\x42\x43\xd5\xb9\x51\xfb\x5b\x99\x1a\x5b\xbd\xf6\xa0\x7d\xeb\xa4\xe8\x8f\x8a\x08\x38\xf3\xec\x51\xa7\x38\x47\xba\x83\x92\xe1\x4a\xf0\xb0\xf8\xd7\x7e\xfd\xf8\xfb\x6a\x2c\x37\x45\x13\x19\x68\xf4\x15\x72\x3e\x8d\xde\xbe\x5e\x5b\x61\x9a\xf1\x0f\x91\x54\x3a\x41\xaf\xd2\x3b\xb3\x76\xa7\x89\x23\xa4\xff\x2f\xc5\x29\x6b\xa6\x22\x89\x34\xd1\x31\x89\x87\x9c\xfb\x3e\x2f\x4d\x74\x62\x09\xa0\x28\x97\x8b\x25\xc3\xd1\xea\x92\x68\xb0\xdb\x5e\xfd\x01\x70\x1a\x98\x87\xcd\x2f\x66\x09\x70\x89\x09\xc6\x11\x05\x5b\x31\xc3\x5b\x89\xaa\xe8\x51\xd4\x89\x11\x34\xd6\x5e\x84\xdf\x3a\x92\x8c\x4f\x61\xc0\xc1\x72\xd1\xee\xbe\x56\xe7\xe9\x2e\x9a\x22\xa8\xb7\x9d\xda\xb7\xbf\xaf\xb7\x9b\x67\x0b\x02\xf3\xa8\xbc\x94\x50\xc6\xbd\xdb\x19\xd6\x6a\x9f\x44\xd5\xdc\x7c\x7a\x57\x9b\xd9\x15\x2d\xa5\x2a\x0e\xdd\x64\xbf\x6f\xf3\x11\xbf\x8b\xfd\x84\x6c\x7c\x79\x29\x8b\x00\x9d\x1a\x0f\xd0\xbc\x58\xc5\xa3\x36\xe2\xbd\x1f\xb4\x65\xdc\xc0\x30\x51\xd6\x4b\x10\x53\x9a\xac\x38\x5c\x2c\xdd\x69\xc4\xa8\x22\x9d\x95\x90\xb0\xc8\xfe\xb1\x2d\x00\x4d\xa3\x50\x20\xca\xd0\xdb\x59\x6f\x11\x57\xd0\x9f\x23\x21\xc2\xa7\x74\xa5\x86\xc1\xdf\xd3\xd8\x66\xe2\x42\x77\x75\xa5\xbd\x2a\x0b\x93\x1d\xba\x31\x2a\xf5\x15\x79\x3b\xa7\x6f\xda\x6c\xbf\x5b\xc5\xd2\x98\xc6\x3e\x5d\xc4\x09\xd9\xe6\x7b\x9b\xea\x12\xbe\x93\x26\xd4\x66\x7a\x35\x14\xbd\xa4\xd5\xba\xb6\xb6\x63\xb3\x7a\x43\xed\x67\xec\xfd\x39\x59\xeb\x8d\xe9\x43\x4e\xa2\x08\x43\x40\xb4\xb0\x68\x6f\x71\x7b\x87\x26\x13\x3b\x4d\x74\x12\xa9\x81\x88\xc5\x40\xcf\x89\xa6\x29\x4f\x70\x79\xfe\x7e\x2e\x1f\xb3\x73\xf7\x57\x09\xa8\x07\xb8\xcd\x8e\xa7\x1c\x86\x8d\xdd\x54\x50\xdb\x7a\x73\x89\xa2\x63\x06\xcc\x82\x45\xfc\x27\x12\x8a\xd1\xc2\x4d\x76\xb8\xcb\xea\xd7\xe7\xd2\x9b\x70\xd0\x54\x1a\xc0\x3e\x45\x7d\x96\xc7\x1e\x64\xb0\x9b\x21\x3f\x8e\x6f\xa5\xe2\xc2\xfb\x8e\xff\x01\x62\xc8\x38\xa3\xa9\x12\x80\xc5\x13\x17\xb8\x60\x5a\x61\x67\xd4\xa0\x06\x93\xa2\x09\x6e\xc7\xc5\x7f\x82\xea\x56\x7c\xf6\xc7\x12\x54\x2d\x76\x3d\xcb\xa5\x38\x4d\xb5\x24\xc6\x57\x03\x4c\xa0\x8c\x47\x1b\xf1\xd6\x4d\xbd\xa8\xb0\x3d\x3c\x10\x32\xa6\x29\x84\x8c\xbb\xee\xfb\xcf\xb2\xca\xf5\xf2\x7c\x6a\x67\xfa\x48\x6b\x63\x74\xd3\x40\x26\x8c\x7b\x01\xe6\xce\xd4\xd2\x9f\xce\x44\x04\x57\xf4\x76\x9d\x67\x74\x57\x3a\x7f\xd1\xd1\xb2\x9f\x1a\x4e\x10\x43\x03\x85\x26\xd3\xe5\x3a\x35\x69\x8a\x91\x63\xe3\xf0\x88\xfd\xdf\x6d\x0c\xd0\x2e\x0c\x95\x28\x74\x90\x76\x47\x84\x65\xc9\xb5\x51\x69\x95\x1d\xb2\xc2\x07\xf7\xd3\x1c\x74\x3c\x45\x8d\x83\xc3\xd6\xce\xfa\x07\x75\x7e\xf0\x42\xc3\xd9\x6c\x75\x52\xd0\x16\x01\x0b\xb5\xb6\xf2\x02\x9d\x75\x3b\x5a\xf5\xfe\x36\x19\xa7\x23\x64\x0a\x22\x21\xe4\xe6\x5c\x15\xd3\x84\x45\xd0\x58\x89\xae\xdb\x5f\x56\x1a\x2a\x5c\xf9\x48\x38\x1d\x97\x24\xa8\x02\x84\x6c\xbd\x4e\x54\x7f\xec\xfd\x43\x05\x15\x5a\x59\xa0\xcf\x3b\x36\x5d\x30\x6b\x00\xfd\x72\x85\x63\x21\x18\x4b\x90\x81\x88\x80\x01\x3d\x61\x39\x53\xc1\x62\x8e\x11\x15\xc2\xaf\xba\x46\xc0\xff\xae\x46\x20\x58\x22\x42\xd9\x75\x1e\x26\x35\xf7\xd9\xb9\x2b\xc2\xc4\x16\xbb\x6a\x68\x5e\xb2\x81\xe6\xd5\x78\x54\x44\x24\x06\xc6\xc2\xd9\x0e\x8e\x7c\xf4\xfd\x18\xc5\x52\xd3\x81\xa3\x46\x99\x63\x3f\xfb\x46\x33\x54\xc4\xc4\x60\xe5\x44\x58\xc1\xad\x5b\x18\xb4\x76\x44\x42\x49\x24\x07\x4b\xfa\x95\x16\xc2\xf8\x36\xa6\x52\x04\x2e\x01\xbd\x29\xcb\x76\x7b\xed\xd8\xe6\xe3\x5f\x94\x4a\x89\xa1\x9d\x45\xcc\xdf\x88\xa6\xc9\x71\x8f\xba\xd4\x6e\xf8\xbb\xff\xf6\x81\xb4\x48\x95\x5d\x10\x5c\xa3\x0f\xaf\xbc\x93\x66\x74\x63\x04\xb5\xfe\xf1\x2e\x17\x86\xf2\x94\x43\xef\x10\x4f\x85\xe0\x56\x42\xf1\x80\x5e\xf7\xf5\x39\xbf\x5e\x3d\x45\x98\xc6\xfc\x8c\x10\x5c\xf1\xde\xd4\xef\x49\xd4\xf5\x47\x59\xe9\xa5\x97\x9b\xfe\x6d\xce\x11\x8f\x0a\x91\xa6\xb6\x97\xdb\x3e\xbe\x2e\xae\xfd\x83\x4e\xe6\xac\xe4\x29\xf6\x57\xf3\x39\xfd\x88\xf1\x75\x28\x13\xa3\x18\xac\xeb\x49\xd9\xc4\x71\x32\x1b\x74\xc0\xbd\xfa\xc9\x12\xaa\x26\x33\xde\x5d\x6c\x12\xd5\x0e\x01\xb8\xdd\x87\x21\xb0\x14\x3b\x6b\x9a\x0e\x45\xb3\xbe\x1d\xdd\xaf\xee\xbd\x85\x54\x83\x55\x24\x6e\x27\x1b\x16\x01\xaf\x4f\x7c\x19\x44\x41\x3c\x30\x80\xc3\x74\x76\xa6\x8a\x2b\x03\x25\xc0\xd6\xfc\xbb\x8d\x48\x12\x66\x10\x79\xea\x50\x15\xc8\x06\xc1\x4e\xa7\xad\x0b\x6b\x44\x5d\xcc\x56\x00\x24\x89\x13\xef\x7c\x33\xf1\xed\xa1\x92\x06\x54\x9a\xee\x07\x0c\xaf\xbd\x1b\x20\x62\x6b\x19\xd9\x06\x16\xc3\xbd\x51\xd2\x28\xc6\x82\x7c\x56\x2f\x73\x10\x93\x5a\xb9\xa4\x9c\x21\x78\x0c\x99\x66\xa0\x77\xe5\x23\x7c\xd8\x3e\xcb\xe8\xb7\xb2\x38\x12\x43\x2d\xcc\xae\x9b\x36\x99\x1f\x32\x64\x40\x3b\xf5\x1f\xec\x19\x5e\x21\x32\xcb\x50\xb2\xc0\x95\x9c\xde\xdb\x35\xf9\xdf\x65\x56\xe4\x59\xdd\xec\x4b\x3d\x59\xc5\x65\x68\x42\x87\x11\x44\x22\x13\x88\xe3\xcb\x9d\x2f\xdd\xcb\x38\x0e\x64\xdf\x81\x7a\xd9\xde\x3e\x94\x45\xf3\x9a\x7f\x6e\x45\x2e\xaa\x0c\xae\x36\x20\xbb\x8f\x13\xd4\x4e\x78\xc8\x74\xd7\xce\x91\x09\x67\xf8\xa2\x76\x59\xb1\x95\x5f\xba\x32\x61\x92\xd8\xda\xca\x5a\xd9\xd6\xec\x6b\x2f\x14\x2a\x53\xc2\xc8\x40\x8f\x11\x45\xe2\x17\x85\x7e\x69\x23\xc4\x8f\x2a\x6b\x1c\x06\x6b\x78\xd9\xbe\xe7\xdb\xfe\x3b\x06\x8d\x4e\x2e\x05\xe3\x18\xb4\x1f\x3b\xc2\xbe\xfb\x42\x60\xd4\xb1\x58\x75\xbd\x39\x37\x75\x23\x2e\x75\x91\xa9\x14\x91\x2d\x2c\x7d\xa0\x4a\xf6\x60\x5d\x92\xed\xba\x04\x7e\x6d\xc8\x8a\xc3\xfe\x90\xbd\x83\xf8\xe8\xa2\x27\x29\xb8\x02\x4b\x9a\xfa\xf1\xc7\xd2\x57\x5a\xfd\x41\x29\x09\x82\x39\x9c\x64\xc2\xfc\x5e\x29\x15\x49\x63\xd2\x29\xf4\xc8\x1c\xaa\x6f\xe2\x08\xeb\x89\xbd\x04\x95\x4a\xc4\x28\x8d\xd5\x3f\x9a\x2a\xfb\x73\x98\x37\x5f\xdd\x2a\xa5\x8e\x02\x6f\x12\xba\xcb\x9a\x73\x2e\xb2\x0a\xf6\xcb\xf2\x78\x6a\x60\x3f\x29\x03\x48\x9d\x00\xda\x12\x2e\x4b\xfd\x39\xa2\xb6\xa8\x80\x09\xec\x3e\x65\x0d\x1c\x87\xce\x15\x54\x91\x50\x6a\x4f\x9e\xb5\xda\xb4\xe3\xb7\x54\x11\x13\x50\x67\x1e\xb0\x3d\x9f\xa0\xba\xad\xc4\xa1\x83\x6e\x28\x62\x62\x74\xb1\x45\xbc\xf6\x52\x9c\x56\xf8\x90\x86\x91\xbb\xa2\x81\x8d\x10\xed\x5c\x5f\x14\xfa\x1b\x34\xdf\x4b\x9d\x63\x3e\x39\x24\xf2\x2a\x2a\x00\xa1\x9f\x59\x7d\x73\xfe\xec\xd1\x24\x7e\x49\x54\x54\xdb\x76\x6c\x0d\x4d\xb7\x33\x6c\x55\x06\x85\x82\xf9\xb4\x44\x31\x22\x11\xdd\x99\xa9\xba\x9e\x1a\x0b\x52\xc5\x42\xdb\xbe\x2c\x5d\x98\x38\x49\x48\x14\x4b\x00\xdb\xb5\x26\x2b\xb4\xb3\x35\xc2\x14\x03\x51\x5e\xa3\x5b\xaf\x58\x1a\x22\x42\xed\x76\xf3\x6d\x3f\xba\xf3\xcc\xa4\x18\xcc\x3d\x2f\x76\xab\xfd\xd3\xcb\xcd\xfd\x7a\x39\x04\xa7\xaa\x90\x68\xa9\x06\x4e\xbb\x03\x9a\xb0\x8a\x08\x97\x8e\xfb\xe4\xcd\x81\x3b\x13\xa2\xf6\x68\x82\xf5\xa6\x5c\xd4\xcd\x43\xf9\x0e\x43\xd1\x3d\x3f\x24\x0c\xb1\x9a\xa6\x5e\xdb\x7d\xec\xd1\xe3\x97\x15\x27\xc4\xbb\xfe\x58\xbc\xca\xd5\x06\x83\xe2\x3a\x44\xd7\xee\x36\xf0\x51\x99\x5f\x6c\x54\x4c\x12\x6c\x7d\x56\xd9\xe1\xb5\xe9\x79\x4b\xfe\x28\x97\xa8\x1c\xba\x3d\x81\xeb\x9e\xf5\x2d\x17\x15\x9b\xd8\xf9\x28\xff\xdb\x39\xd0\x39\xab\x4f\x77\x3c\xe1\x01\x96\x50\x33\x53\x96\xba\xc3\x4c\x76\x47\x85\x55\xb8\x1f\xa0\x50\x9e\xca\x32\x7f\xc8\x8a\x66\x60\x10\x46\x55\xa2\xb5\x25\xfe\x7b\x6a\xf7\x08\xaa\xa2\x12\xb0\xf8\x51\x9b\xe3\xae\x6b\x8f\xb8\x98\x87\x14\xaa\xc4\xc4\x28\x8f\xb9\x78\x5e\x8f\xcf\x93\x52\x11\x4d\xa4\x49\xbe\x5c\xba\x55\x2a\x03\xac\x98\xd8\x4c\xed\x26\xcb\xf3\x7b\xeb\x35\x33\x94\x5a\xf8\x22\x66\x53\xa9\x54\xf8\x4c\x51\xa8\x3e\xab\xfd\x62\x3d\x7e\xab\x45\x40\x70\x59\x14\x28\x94\xb3\xa9\x2c\xe6\xd2\xd1\xb6\x2f\x7a\x6d\x73\xd8\x52\x25\xc2\x04\x1f\x7c\xfd\x21\x4e\xf5\x38\xb4\xa1\x81\x1b\x23\x65\x8a\xbc\x69\x78\x77\x84\xce\x79\x4d\xfe\xf9\x99\xa5\x68\x80\x00\x1a\x0d\x22\x87\xea\x7b\x57\x04\x55\x2a\x16\xa8\xc5\x56\x67\x87\x02\xb5\xb2\xc1\x64\x3e\xad\x57\x5a\x87\x28\x8c\xfb\x5e\x5e\xaa\xc0\x0c\x6f\x13\xc4\xc0\x63\x5f\x31\xc9\x08\xdf\x8b\x36\x82\xf2\x67\x31\x89\x0c\x74\xb7\x9d\xdd\x9c\x0b\xdd\x6d\x75\x3a\x88\x05\xa2\x65\xfe\xeb\x8f\x1f\xc3\x37\x59\x07\x3a\x22\xa9\x9b\x32\x97\xc0\x9c\xd1\x6f\xd3\x24\x16\x92\xf8\x96\xd8\xb7\x52\xe4\x7e\x76\x6b\xa2\x05\x32\xd0\xfc\x37\x67\x79\xbb\x60\x6e\x8e\x45\x36\xa4\x09\x25\x57\xff\x7b\xf9\x53\x35\x15\x09\xca\xbc\x8a\x73\x53\x5a\xa3\xaa\x2e\x14\x9e\x49\xd1\xfc\x87\xb4\x52\xa2\x4b\xc1\x6c\xdf\x6a\xa1\xa6\x0b\xa8\xa6\x40\xf1\x47\x77\xaf\xd1\x93\x7b\x5d\xfd\xef\x61\xc4\x16\x76\x0f\xd0\xec\xac\xdd\xb4\xc9\x9a\xc5\xf1\x5c\x76\x93\x51\x87\x91\x19\x15\x2c\x3d\xfc\xae\x4d\xa3\x0e\xa2\xb9\x14\xc4\xff\xca\x6d\x7e\x0e\xed\xa2\x23\x1e\xf0\x21\x06\xaf\xf7\x6a\xa3\x3a\xd2\x84\xc8\x2e\xdd\xbb\xaa\x2d\xa0\x39\x68\xed\x58\xe9\xfb\xaa\xfc\xd8\xab\xf2\x2a\xd9\xd5\x7d\x22\x16\xb1\x72\x65\xc6\x45\xd3\x54\xcb\x73\xdd\x94\x7f\x49\x2f\xf1\x9f\x55\xdc\x66\x5e\xa2\x7a\x2b\x4a\x0d\x3d\x12\x62\x31\x7d\x04\x49\x68\xa3\x53\xdb\x1e\xf4\xdb\xaa\x16\x20\x91\x45\xff\xb8\x5e\x7a\x67\x07\xaa\xa5\x34\xbc\x37\x8b\x5d\xab\xf2\xd6\xd5\xd2\x10\xf2\x75\xa5\x03\xa4\x15\x8b\x60\x24\xcc\x74\x15\xf7\xa5\x95\x6b\x9c\x1a\xc4\x68\x3b\xcf\xde\x51\x1d\x54\xab\x38\xc6\x12\xba\xc1\x16\xd7\xa0\xc7\x3b\x98\xb2\x2a\x15\xc2\x41\x8e\x87\x45\xb4\x01\x3c\x8f\x87\xa3\x4c\x43\x83\x88\x49\x34\x10\x7b\x5f\x4f\xe8\xaf\x1a\x84\x48\xbc\x24\x5a\x05\x06\x2a\x28\x2e\x79\xf9\x93\x5f\x03\x32\xc5\xdb\xd5\xae\x34\x83\x82\xc8\x68\x21\xd4\xa0\x2d\x00\xc0\xd5\x64\xaf\xdc\x43\x13\x84\xf8\xab\x9d\x6d\xb8\x55\x56\x1a\x71\x3a\xfc\x40\x12\x69\x87\x50\xb4\x58\x12\xa7\xc1\x3e\x39\x1d\x0d\xb4\x17\xeb\x7e\x17\x59\x2e\xc6\x58\x5e\x6d\x68\x88\xb9\xd3\xe2\x5c\x75\x38\x3f\x6d\xb8\xe2\xc6\x17\x15\x8a\x73\x3d\xd1\x69\x80\x40\x05\x48\x55\xb1\xbb\xc1\x16\xf2\xdc\xa2\x9d\x46\x17\x08\x24\x32\xd4\x8a\x4c\xf4\xda\xed\x14\x88\xb1\xf2\x11\x88\x21\xcc\xf3\xb2\xa9\x1f\xcf\xc7\xc9\x27\x29\x8f\x91\x94\xbf\xcd\x9c\x6a\xe8\xe4\xfb\x69\x6a\x10\x36\x67\x41\xda\xbb\x57\x31\x44\x49\x00\x85\x08\xf3\x17\x7b\x75\x0f\x59\xe1\x51\x12\xe3\x93\xb0\x34\xc4\xf6\xce\xde\xf2\x23\x26\x5a\x39\x97\xa4\x57\x88\x08\x43\xe0\xef\x7d\x79\xf0\x01\x9e\x97\x1f\x98\x9d\xe3\x10\x85\xd4\xbb\xca\x8f\xf2\x7b\x6c\x0b\xcc\x6e\x96\x10\x49\xed\xed\x04\x6e\xda\x1b\x54\x67\x6a\x72\xd9\x91\x11\x5e\x5b\xbf\x5d\x98\xad\x4b\xbb\x3b\xc6\x09\x47\xc2\xcb\x87\x6f\xbc\x5b\x00\x40\x77\xef\x79\xc2\xf0\x61\xaf\x17\x0f\x08\x0b\x5c\xed\xbe\xef\x3b\x49\xba\x36\xb0\xec\x07\x5a\xb0\x7e\x2d\x0c\x2c\xb4\x66\x74\xb8\xa7\x74\x17\x1b\x3b\xef\xa5\xfd\xdd\x72\xc4\xb8\xbf\x6a\x13\x49\x21\x4e\x43\xc5\xbc\x9d\x37\xd2\x94\x27\x4a\x90\x49\x37\xd0\x42\x91\xd1\x77\x8b\xce\x47\x53\x10\x0b\xe9\x6b\x79\xab\xe6\xd5\x2d\xd9\xef\x65\x76\x2d\x8c\x87\x84\x11\x65\x27\xb6\xed\x34\x0f\xbf\x31\x91\x29\x72\x50\xeb\xec\x4f\xd8\x18\x2c\x33\x0c\x93\x06\x48\x81\x63\x9a\xe7\xc0\x9e\xe2\x17\x8a\x6c\x1c\x4f\x02\xf3\xdb\xab\x65\x34\xf7\x69\xc9\x6c\xcb\x6f\x7f\x82\xca\x94\xd5\xb1\x53\xb3\x99\x7e\xec\xcb\x72\x1f\xc8\x94\x38\x2b\x2b\xb4\xf6\xb3\xc7\xee\xaa\xf2\x68\x03\x89\xc9\xcf\x55\xdc\x4a\x16\xf5\xb6\x21\x50\xef\xca\xab\x8c\x21\x50\x92\x91\x3e\xa6\x70\x3d\xee\x2f\xc3\x50\x50\x60\x59\x03\xb2\xcc\xa1\xf0\x79\x01\x68\xa3\xa8\x15\xe3\xc1\x3a\xfe\x62\x20\xd7\x76\x23\xa6\x2d\x4c\x00\xd7\x61\xc9\x9c\x32\xed\xba\x18\xfb\x86\x8d\x7f\x14\xa4\x29\x52\xb0\x1a\x71\xfa\x6d\x14\x45\x82\x49\x29\x1e\xb9\x13\x1f\xc5\x20\x51\x30\x81\x08\x30\x1d\xb4\xf6\xdf\xf7\xcb\xbf\x9e\xa7\x86\x68\x6a\xa7\xb6\xd0\xfa\x5b\x55\x9e\x4f\xbb\xd2\x86\x36\xf3\x1d\x67\x43\x19\x45\xc0\x53\x56\xdb\x57\xee\xe6\xfc\xd9\x2e\x8b\xfe\x0a\x68\xcc\x30\x44\x75\xa9\xeb\xe5\x6a\x6e\x28\x58\x0b\x60\xeb\x0f\xb7\xdf\xdc\xed\x6f\x36\x9b\xed\x6e\xf5\xec\x3b\x98\x86\x91\x84\xf6\x10\x76\xa7\x1e\x31\xfb\x50\x0c\x8b\x8c\xc3\xb8\x88\xa3\xf3\x76\x18\x53\x20\x0c\xe3\x01\x0b\x87\x85\x84\x67\x78\x87\xe2\x0c\x8b\x66\xa6\xc7\x6c\xc2\x08\x90\x53\xf5\x54\x41\xd3\x7c\x7e\xcb\xaa\x7c\x7a\x0b\x47\x37\x8f\x07\x31\xf2\x40\xeb\x13\xa8\x4c\xe4\x63\x3f\xc7\xf6\xb0\x75\xb1\xb6\x3b\x70\xb3\x38\xeb\xac\xb9\x60\xa3\x8f\xef\x4e\x1c\xa7\x66\x68\x32\xec\xd4\x11\xaa\xf2\x88\xc1\x92\xbe\xa4\x4a\x5e\x3b\x8f\x00\xea\x97\x1f\x74\xe8\x5c\x39\xdd\xd6\xf1\xad\xec\x9e\x6b\x22\x02\x62\xd5\xa5\x3f\xd7\x45\xdd\x88\x3c\xbf\xa4\xa6\x99\x44\xc6\xa9\x67\xdc\xe7\xe7\xf6\xd1\x54\xab\xc3\x61\xb6\x1a\x6b\x12\x23\x3c\x95\xd7\x19\x74\xed\xc4\xaf\x81\xcc\x98\x49\x0c\xa0\x38\x4f\x56\x58\x60\xd3\xbe\xb1\xaa\x33\xa3\x6f\x4c\x03\x8e\x8c\x8b\xa2\x6c\x76\x65\x79\x5f\x16\x87\x6d\x56\x28\xf0\x8c\x38\x37\x4a\x44\x0c\x27\xf1\xc9\xbf\x72\xae\xa5\xe3\x0a\x67\x9e\x74\x6d\x44\x64\x9c\x08\xac\x2a\x0b\xed\x23\xbd\x9e\x74\x64\x04\x37\xa9\xf3\x48\xe9\xfa\x2c\xfd\xa2\x33\xec\x72\x4f\x26\xa2\x48\x01\x03\xc2\xf2\x04\xc5\xf6\xb5\x9c\x34\xf5\x8d\x30\xc1\xc0\xac\xf3\x76\xb1\xf9\x7b\x72\x01\x46\x32\xed\x92\xee\xe6\x19\xd0\x82\x2b\xdf\x1e\x45\x75\xa5\xa7\x6c\x14\xe5\x28\xf4\x71\x3e\xb5\xc9\xde\x53\x59\x4f\x0a\xc8\x46\x39\x72\xb7\xf2\xe9\x0e\xb6\x71\x06\x70\x22\xa3\x22\xed\x72\xb6\x66\x68\x3a\x53\xff\x36\xc4\x99\x0e\x02\x53\xa3\xb8\xc1\x5c\x4a\x42\x01\x26\x53\x99\xa8\x3e\xc7\xa4\x73\xa3\x99\x95\x39\xc5\xba\xa2\x2d\x8d\x77\x47\xac\x15\xd7\xe6\xf8\xfb\xd3\xe3\x30\x75\x34\x5a\x29\x9c\x8e\x60\x97\x66\xff\x57\x93\x20\xa4\xdf\x35\x8e\xa6\x7e\x7d\xd4\x80\xd2\xc6\x4a\x83\x9f\x3e\x7f\x9b\xa5\xb7\x4e\x6e\xb0\x01\x86\x1f\xa8\x9b\xb2\xc2\x6e\x32\x6e\x87\x83\x97\x9c\x05\x41\x68\xcd\x4f\x5c\xbd\x69\x9c\xb0\xf7\x61\x13\x0b\x82\x84\x08\x9f\xdd\xcc\xe0\xf8\x59\xc0\x12\x21\x7c\xbd\x19\xf1\xce\xbb\xf2\xa1\x1e\xd7\x34\xfd\x48\x91\x52\x69\x69\x14\x1f\x8e\x61\x3e\x1d\xa1\x94\xd2\x0e\x76\xf3\xe3\x5c\x4c\x8f\x42\x62\xad\xa3\x6c\x8b\xe1\x4f\xab\x86\x70\xd9\xd1\x75\x1b\x22\x0b\xc2\x90\x49\xe5\x45\xab\x47\x50\xdb\x7f\x8c\xcf\x1c\xa6\xd2\x47\xcc\x77\xd9\xe1\xb5\x99\xf8\x95\xb6\x03\x34\x8a\x17\x2c\xf2\xfc\xd3\xd1\xa9\x07\x4f\x96\x05\x51\x10\x86\xa6\xef\xa0\x39\xdc\xee\x43\xe9\x55\x8a\x58\x10\xa5\x0a\x4c\x8f\xb5\x9f\xe7\xf3\xfe\x63\x7c\x6b\x23\x45\x49\xe0\xf5\x81\x6d\x61\x0a\x6d\x5b\xb0\xfb\x27\x4b\xaf\xd2\xe4\xb5\x2c\xdc\xa7\x38\x8b\x31\xb3\x78\x5e\xdd\xdd\x8d\x60\x34\x2c\xe0\x11\xc1\x7e\xc3\x72\xf3\xf0\xf0\xf2\xb8\xde\xfd\xb1\x5f\x2e\x9e\x9e\x56\xb7\xfb\xdf\x17\xf7\x2f\xab\x6e\x54\x0a\x18\xe3\x7f\xdf\xfd\xab\xfb\x53\xbb\x86\xff\x9f\xff\xef\xff\xac\xd6\x4f\x31\xa1\xfb\xdb\xcd\xc3\x62\xfd\xb8\xff\xbe\xd8\x7e\xf7\x23\x12\xca\xb1\x20\xf3\xf6\xa9\x9e\xda\xc0\xfe\x22\x9b\xf7\xe3\x98\x91\xd1\x48\xad\xe9\xaa\xd4\x19\x0b\x92\x38\x40\x18\x64\xe3\xed\x83\x50\x8e\x0b\x01\x61\x77\x65\xb5\x05\xd0\x03\xf0\x2b\x0b\x12\x45\x49\x47\x70\x3a\x4c\xce\x95\x52\x8a\x59\x49\x86\xf8\x45\xab\x2b\x37\x99\xca\x29\x4b\xb9\x83\x69\x6c\xd5\x2b\x1c\xc5\x0c\x86\x8e\x05\x69\x92\x26\x1d\xd4\x61\x5b\xe6\x7a\xef\xbf\xbf\xcd\x66\x23\x8b\xbf\x3b\x17\x7a\x3b\xe3\x7e\xe2\x07\x3a\x3f\xf3\x26\x83\x6a\xf7\x51\xf6\x40\x0f\x16\xa4\xc6\x76\x58\xea\x13\x54\xc7\xbc\xac\xc6\x1e\x1f\x2c\x10\x5a\x7b\x58\xc3\xfe\x54\x95\x27\xa8\x9a\xcf\x7d\x6e\x5b\x3c\xb3\xbb\xfa\xf8\xe2\x65\x18\x60\x0b\xe2\x24\x3e\x7f\x66\x45\x91\x15\x87\x6f\xb9\xd0\xd9\x50\x27\x7c\x72\xad\x52\x5b\x14\x55\x05\xef\x50\xd5\x30\xb9\x65\x8a\x71\x43\x70\xf3\x94\xed\xbc\x1f\x98\x89\x76\x6f\xa1\x62\x36\x32\x77\xca\x9b\x03\x84\x35\x0b\x54\x2c\x51\x47\x71\x57\x95\xc5\xbf\x9a\x36\xac\x9f\xf7\x9b\x65\x81\x12\xb1\x92\x5d\xe2\x69\xc1\xb7\x7e\xc3\x58\x17\xdb\x3f\x85\x2c\xbb\x93\x1a\x11\x5a\x94\xf1\xea\x17\xa8\x21\x3d\x7a\x72\x4e\xad\x29\xca\xab\xac\x4e\x35\x26\xca\xfe\x04\xda\xc8\xd4\x85\x57\xf9\xa2\xd0\x77\x22\xcb\x7f\x66\xcd\x6b\x79\x6e\x9e\x41\xd4\x65\xf7\xd6\x03\x63\x18\x86\x5d\x40\xec\x58\x60\x42\xa0\x6e\x2a\xf9\x3a\xd7\xdf\x88\xe1\xdb\xcf\x99\x24\x1c\xe0\xaf\x2d\x0d\x76\x72\xd3\x4d\xac\x92\xae\xdf\xed\xb0\xa0\x57\x84\x43\x59\x60\x80\xc5\x6e\xb7\xfd\xaf\x33\x54\xb3\x6c\x2c\x46\x02\x45\x95\xa3\x6b\x60\xcf\xf7\x49\x4c\xd6\x66\x42\xc1\xbe\x8b\x53\xd5\xfa\x51\xb5\x64\x34\xd9\x48\x18\x28\xac\xe0\x3e\x2d\xbf\x2f\x3c\xeb\x88\x91\x90\x58\xf5\xca\x0a\xf3\xb0\xd3\xe4\x6b\x42\x16\x60\x35\xcd\xfa\x03\x4e\x92\x98\xd9\xb7\x89\x84\x3a\x89\x9c\x8f\x0c\x62\xb2\x1e\xe0\x58\x5e\xb1\x59\x73\x9f\x88\x58\x42\x7d\x55\x38\x2b\x0e\x7b\x25\x2a\xbd\x77\x13\x5c\xef\x1d\x56\xd7\xad\xa7\x84\x4b\x8d\xc0\xe8\x57\x51\xbf\x3e\xd4\x87\xbf\xb2\xe0\xbd\xe0\xb0\x8c\x6e\x09\x87\x14\x7f\x1e\xa2\xb5\xff\x96\x7a\x04\x23\x71\xc8\x74\x3c\xf0\x94\x35\xce\xe3\x70\xe8\x27\xcb\x48\x12\x5b\x23\xe4\x63\x7e\xdb\x26\xdd\xed\xca\xe0\x67\x23\x49\x44\x8c\x65\xc6\xe7\xc5\x72\x75\xb7\x79\xee\xa0\xa2\x8c\x24\x32\xc2\x79\x5a\x7f\x88\xd3\xac\xd2\xf7\x78\xf9\x26\x89\x86\x98\x79\xb9\xfb\x6a\x88\x19\x1e\xc6\x64\x8c\xa4\xa9\x8d\x0d\x6b\x68\xb0\xee\x8d\xa9\xe1\xc5\x7b\x78\xd9\xd8\x60\x24\x95\x01\x58\x11\x65\xa4\x8b\xd5\x9d\x2f\x98\x69\xa0\x5a\xe6\x99\x31\xfe\xda\x45\x60\xfd\xfc\x0e\xd0\x8c\x8d\x11\x18\x11\xb1\x0a\x30\xcb\xac\xb2\xc3\xc1\x2a\x9c\x8f\x7c\x46\xe7\xa7\x85\x48\x08\xe9\x53\x9b\x81\x1c\x0d\x23\x22\xd5\xf8\x5d\xb9\xa8\x9b\xf5\xad\xff\xab\x24\x02\x7b\x58\xcb\x5e\x28\x79\xc0\xcd\xfa\xea\x57\x4a\x23\x50\xa8\xa0\x80\x5f\xcd\x3e\xf3\x3b\x18\x51\x3c\x00\x8b\xe0\x46\x3e\xed\xfc\xf6\x41\x54\x4c\x10\x88\x5e\x0b\x03\xbb\x72\x7b\x96\xf3\xeb\x1b\xd1\x2c\xe4\xae\xfd\x73\x9e\xd6\x16\xdb\xa3\x29\xaa\xf9\x3f\xac\x1f\x77\xfb\xf5\xe3\x6e\xf5\xfc\xfb\xe2\x7e\xbf\x5d\x2d\xfd\xc5\x80\x53\x97\x6b\xb7\x1a\x28\xf4\x5e\x5e\xe4\x96\x8c\x00\xd5\x08\x63\x33\xe7\x42\xed\x83\x45\xca\xba\x0f\x87\x91\x6d\xad\xbc\x82\x7a\xbb\x29\xa7\x8a\x92\x8c\x18\xda\xf9\xac\xf9\xc7\xb3\x2e\x4c\x89\x61\xfb\xfc\xcf\x36\x0c\x02\xe5\x97\x3d\x87\xd3\x7d\x2a\xf3\x7c\xb2\x94\x99\x90\x62\x09\xb6\x79\x85\x65\x87\x20\x64\xc4\x18\xae\xa8\x0b\xc0\x2a\xed\x65\x89\x7b\x1d\xc5\x6b\x2f\xa3\xfd\x38\x4a\x88\xa3\xf9\x16\x34\xfb\x87\x85\x0f\x8c\x28\x09\xac\x0a\xd3\xc8\x28\xf8\x16\x4e\x15\xa8\x11\x8c\xeb\x42\x49\xfe\xab\x42\x11\xa3\x84\xa4\x7e\xfb\xf8\x02\x5d\xfa\x8f\xc9\x86\x3f\x88\xdb\x29\x49\x6c\xc7\xe6\xf6\x5c\x1c\xa0\xb4\xfe\x50\x13\x37\x3a\x3f\x52\x68\x04\xcf\xee\x95\xe8\x51\x5f\xf3\x97\x45\x9d\x2d\xf2\x29\x03\x05\x75\xbb\x5e\x4c\x42\x28\xca\x12\x4b\xbc\x7f\xab\xd5\x03\x96\x7f\x2f\xae\x79\xb8\x1c\xd2\x30\x8d\x55\xe8\xb5\xa4\x1a\x30\x42\x35\xf5\xda\x77\xbe\x19\x8d\xa8\xb5\xbb\x2e\x2b\xa1\xf2\xec\x4f\x40\x3b\x99\xf2\x78\xbb\x6d\x43\x9f\xd2\xfc\x8e\xa5\xdf\xfd\xbe\x06\xdc\xb3\x7e\xc0\x27\xfa\xf8\x67\xcd\xe7\x0c\xe8\x89\xd1\x28\xb4\x68\x1b\x0b\x5b\xf9\xab\x35\x61\xfa\x61\x1e\x62\xfd\x66\xb9\x79\x78\x5a\x3c\xfe\xb1\x7f\x5e\x6d\x57\xcf\xbf\xaf\xf6\x77\x9b\xe7\xee\x6a\x8d\x44\x38\x23\x2a\xae\x77\xf9\x37\xa3\x5c\x28\x44\x40\xb5\x27\x44\x4f\xd1\x2f\x8b\x8d\x8c\x72\xe0\xd8\xdb\xbe\x5d\xdd\x2d\x5e\xee\x77\xfb\xa7\xe7\xd5\x76\x71\xbf\xda\xee\x6f\x5f\xac\xbf\xa3\x3f\x71\x1c\x59\x53\xf5\x87\xcf\xbb\x0a\xb0\xb9\x4e\x08\xfd\xcb\xf2\x18\xa3\xb1\x08\x31\xdd\x91\x15\x88\x37\x3d\x65\x80\x32\x9a\x04\x84\x3a\xca\x98\x65\xb0\x4e\xa5\xe5\x18\x4d\x94\x8a\xd4\x10\x65\xbe\xa8\x64\xd6\xf4\x5b\x4e\xfb\x72\x63\xe3\x75\xfd\x78\xbb\x2e\x4c\x8e\x2f\x83\xa7\x99\xb8\x21\x29\xe7\x49\x38\x72\x76\x7a\xca\x60\x72\x29\x29\x24\x08\xad\x71\x72\xd0\xc4\x7f\x56\xd0\x14\x6b\xe5\xf2\x5c\x15\xb6\x73\x82\x33\xbc\x93\xf4\x18\x33\x80\x18\x15\x22\x42\x40\xb3\x0d\x2b\xee\x45\xdd\x3c\x64\x39\xd4\x4d\x59\xc0\xa8\x9a\xc0\xa8\x80\x94\xb9\x40\xf3\xbf\xce\x70\x86\xcd\x09\x8a\xc1\x45\x0b\x13\x62\x4e\xb6\xdc\xba\x86\xcd\xe0\xa6\x48\x16\x22\xf1\xe3\x9f\xcb\x1b\x3f\x5c\x72\x46\x6d\xba\x83\xd2\x75\x77\x65\xb5\x56\x17\xef\x84\x1b\xab\x22\x13\x58\x72\x41\x21\x0e\xf0\x34\x41\x04\x0e\xc6\xf1\x08\xe9\x84\x9d\x81\xc7\x4f\xc8\x48\xe4\xbf\x51\x49\xdb\x7d\xd1\xa0\xb2\xa3\xc8\x51\xf5\xcb\x1f\xd3\x94\x23\xe3\x53\x68\xed\xfc\xed\xbc\x62\xfd\xcd\xa7\x77\x01\x99\x4d\x45\xa9\x8e\x94\x71\x4e\x1f\xbe\xd8\xf7\x35\x54\x97\x51\x1d\x73\x6c\x75\x20\x07\xfc\xa6\x2f\xa4\x4c\x56\x0c\xe0\x09\xd8\xbc\xec\x11\x3e\xb6\xea\x75\x6a\x49\xc3\x28\xa4\xd6\x56\xc1\xe2\xf2\xf2\x12\xa9\x05\x33\x2a\xc5\x8c\x82\xd2\x98\x3c\xdd\xaf\xfe\xb5\xf3\xbf\x19\x0c\x53\x8e\x9e\x09\x15\x80\x03\x48\x8c\xae\x81\x05\x11\xd1\x8e\xbf\xf2\x4d\xd4\xb8\xf1\x5b\xd6\xd1\x64\x18\x17\xf8\xde\x2c\x3b\xa8\x7e\xd3\x25\x0d\x2c\x10\x9d\xc9\x5b\xdf\x77\x6f\xa7\x48\x3b\x6f\xab\xbb\x89\x0f\x13\x63\x54\x1b\x6b\xbd\xd0\x3e\xc5\x20\x0d\xc8\x17\x45\x59\xc6\x42\x16\xe1\xdc\xd8\x9f\x72\xf1\xf9\x0c\x22\xef\x08\xca\xff\x0f\xd8\x5f\x7f\xce\xd4\x3a\x41\x0a\xad\xeb\x41\x75\xef\x8b\xf4\x91\x85\x4a\xfb\x90\x6b\x51\x37\x55\x59\x3b\xc1\x27\x7f\xd8\x30\x0a\x9d\x07\x9a\x0b\x10\x47\x27\x88\x02\x1d\xbb\x92\x0c\xae\xd5\x3f\xfe\xf0\xe1\x06\x8b\x98\x61\x08\x73\x2a\x54\xd5\xbe\x2b\x18\xe3\x5a\x21\x81\x6e\x88\x8c\xf0\x9e\x89\x3c\x2f\x95\x68\x60\x7b\x3e\x9d\xf2\xcf\xee\x28\x10\xe3\x3a\x7c\x88\x9f\x1a\xe7\xf8\x57\x6e\x02\x0f\x62\x2b\x90\x2d\x72\xb0\x42\x05\xfe\x74\x1c\x02\x2c\x2b\xb6\x47\xfe\xeb\x2c\x8a\xa6\x83\x1f\x31\x16\xb3\xd0\xe8\xae\xcd\xeb\x6d\xdc\x6f\xc7\x28\x41\x3f\x56\x4b\x54\xb4\x7f\x5c\x3c\xfe\xb3\x57\x5f\x68\xff\xae\x51\x26\x67\x6b\xf3\x62\xeb\x63\x3f\x0b\xd3\x64\x2c\x06\x85\x34\x87\x9d\xc8\xdf\xc6\x03\xdd\x80\x24\x90\x98\xd7\xff\xbb\xcc\x8a\xa7\x2c\xcf\x45\xb5\x2c\xab\xf9\xbe\x77\xe2\x3f\xc2\xad\x76\x4b\x53\x9d\xeb\x66\xe4\x4c\xc5\x58\x22\x42\x2c\x19\xdf\xae\x7e\x5f\xdd\x6f\x9e\x56\xcf\xfb\xbb\xd5\x6a\x7f\xf7\xbc\x58\xee\x6f\x36\xfe\xd5\x62\x29\xb3\x6e\x6b\xef\x65\x73\xf1\xa0\x53\xae\x91\x3f\xe0\xf4\xa8\xac\x33\xf0\xb2\x9c\x74\x4e\x18\x4b\x93\x04\x01\xa8\x8b\xdb\xdb\x67\x94\xff\xbe\x7d\x5e\xfc\x5c\xdc\x93\xee\x3b\xd2\x08\xa3\xd4\x45\x95\x35\xaf\x03\x98\x20\x63\x22\x15\xb2\xb7\x64\xde\x18\x1f\xb6\x90\xe9\x23\x96\xb1\xc6\xa0\x1a\x0b\x36\x5e\x43\xd4\x9f\x45\x26\x71\xe0\xcc\xd8\x60\x62\x55\xc7\x98\x14\x11\xf2\xad\xda\xd4\xcf\xc2\x93\x07\x1a\x83\xdd\xbd\x97\xd2\x96\xbe\x6e\x9e\x6f\xfb\xbe\x15\x63\xca\x77\x2b\x1c\x93\x64\x18\xc8\x5d\x64\x06\x7d\xe4\xc6\x54\x1a\x47\x51\xbf\xb5\x96\x45\x1b\x10\x75\x05\xea\xc1\x26\xcc\x34\xb5\xdc\x5c\x6f\x83\xb9\xaf\x21\xcf\xf7\xe0\x24\x5c\x26\xbf\x45\xd3\x04\xb3\xc8\x77\xa8\x9b\x0b\xfa\xb2\x1f\x23\x0c\x46\x2a\x80\x3e\x00\x95\xab\x8f\x87\xee\x28\x44\xa9\xee\x54\x9b\xeb\x33\x5a\x42\xf7\xae\xbd\xdd\x20\xe5\xad\x83\x5c\xa5\xe1\x65\x5d\x34\xc9\x6c\xc3\x9c\x31\xc3\x6d\xf1\xf8\x00\xcd\xa6\xb8\x39\x57\x8e\x88\x38\x7c\xce\x61\x10\x53\x0c\x02\x65\x76\x78\x28\xf5\xea\x57\xb7\x50\x79\xe5\x2b\x16\x06\x8a\x1a\x8c\x06\x32\xbd\xda\x7d\x5f\xb7\x0b\xc8\xb1\xab\xc8\xb3\x30\xd0\x81\xb6\x8e\x56\x05\x7c\xdc\xc2\x85\x5d\xb0\x1b\x46\x52\x1a\xd8\x0c\x41\x67\xdd\x0f\x0a\xa9\xa2\xc0\x07\xb2\xa1\x1d\x2d\xde\x0f\x60\x06\x04\x1f\xd9\x3f\x7d\x76\x1f\x0e\x79\x80\x15\xc5\x76\x02\x35\xe2\xb0\x2c\x8f\x5e\x3d\xcc\x0f\x48\x38\xae\x59\x59\x6d\xc3\xa8\xa7\x8e\x6d\xc6\xc2\x50\xc1\x90\xbd\xed\xbf\xb7\x9e\x60\x69\x7c\x8c\x13\x46\x81\x65\xa7\xb5\x39\xaa\x7d\xe1\xfc\x99\x22\x12\x4a\xc7\xf9\xfb\x3d\xab\x9a\xb3\xc8\xe7\xa4\x27\x58\x18\x45\x04\xeb\x04\x16\x18\x61\x79\x20\xe5\x4e\xfc\x9a\x0f\x58\xc2\xc8\x58\x04\x41\xfd\x5a\x7e\xb4\x21\xd5\x4d\xa6\x75\xff\xa5\x9c\xa5\x58\xb1\x5b\xb8\xc5\x5a\x2f\xdb\x77\xac\x07\xa5\x5d\x4d\x8d\xfe\x6a\x17\xbb\x96\x4a\xcd\x5f\x24\x0f\x25\x02\xbf\x6e\xab\xf2\xd4\x5d\x9a\x64\x49\xe0\x57\x84\xa7\x6a\x60\x72\xc7\x42\x6e\xac\xd3\x80\xe5\xf8\x8d\x59\x3c\x6e\x48\x1c\x24\x48\x67\x3b\x8a\xea\x0d\xb9\x5d\x5b\xc4\xd8\x0d\xa5\xde\x58\x18\x0b\xeb\x07\x51\x5b\x54\xeb\xec\xfc\x0f\x93\x54\x84\x4e\xb3\x65\xbd\xde\x3f\x93\xf1\x3b\x1b\xa6\x51\xc4\x53\xc7\x34\xbe\x5d\x6f\x97\x9b\x97\x47\xbf\xf8\x86\x69\xca\x92\x0e\x5b\x68\x1f\xb7\x43\xfa\x8f\x2f\x36\x55\x9d\xb6\xa2\xf7\xf5\xb4\xe9\xf8\xfc\x15\xa5\x2a\xd6\xee\x8a\x9a\x1c\x5e\x0a\xd5\x07\xd3\x17\x23\x25\xe9\x41\x66\xfb\x62\x62\x64\xc1\xc2\xd4\x10\x6c\x84\xfd\xbb\x7c\xeb\xf8\xa3\xfe\xea\x45\x6a\xa5\x06\x7b\xc0\xac\xdb\xd6\xfc\x71\x95\xe0\xdd\x13\xef\xa2\x11\x5d\xfd\x66\x60\x4a\xc4\x42\xa1\x39\x52\xa2\xac\x20\xdf\x44\x4e\x69\x2e\xfb\x19\x85\x32\xa1\x8c\x53\x94\xdb\xd0\x25\x42\x59\x8a\xee\xbc\x8a\x25\x48\x52\x6d\x63\x88\x39\x91\x52\x16\xaa\x44\x4b\x33\xbc\xf8\xac\x2c\x6e\x07\x57\xa6\x45\x6c\x85\xe8\x7b\xe7\x81\xf0\x78\xb3\x5b\x5e\x79\x8d\xb4\xb6\x0b\x7e\xcf\xc8\x1f\xdf\x2b\x20\xd6\xd2\x67\xdb\x88\x2a\xcf\x0e\xaf\xa3\x52\x57\xd8\x86\xfc\x4e\xf2\x32\x3b\x5c\x4a\xc5\xf9\x51\x51\x6c\x9b\x16\x50\x37\xd8\x93\xc6\x36\x55\x23\x0a\x2d\x2a\xbd\x14\xc7\x93\xc8\x0e\x85\x9d\x3f\xbb\x72\x18\xac\xfb\xcf\xc7\x09\x82\x3c\xce\xc8\x73\xb9\x2d\x8f\x22\x2b\xc6\x4f\x1b\x62\xa5\x2d\x4b\xfc\x17\x36\x65\x6e\x21\xf7\x6d\x71\x16\x1a\x2a\xf0\xa5\x32\x96\x0c\xdf\x35\x68\x07\x1c\x4f\x16\x9a\x98\x60\x3c\xea\x41\x36\x8b\x2b\x95\xe6\xf1\x2f\x33\x69\x18\x5b\x43\xb5\x93\xc8\xaa\xa5\xf0\xba\x85\xf1\x17\xa2\xfd\xed\xa7\x34\x22\x71\xbe\x2d\x37\xff\x7a\x5a\x38\xbd\xcd\xcb\x0f\x24\xd3\x8f\x19\x25\x07\xda\x90\x59\x31\xd7\xe8\x8c\x82\x40\x86\x89\x6f\x70\xd7\x65\xfe\xde\x2d\x8a\x51\xc0\x03\xd4\xb4\x73\x05\xbe\x95\x53\x23\x77\x8c\xd9\xf1\x43\x8b\x02\x69\xa3\xb0\x83\x38\xc2\xae\xfc\x89\xdc\x96\xc9\x57\xd1\x50\x33\xaf\xbf\x6a\xb3\x12\x0f\x00\xf0\xdc\x78\x3f\x30\x09\x71\x92\xb5\x09\xf3\x53\x95\x1d\xcb\x4a\x67\x4e\xa9\xed\xae\x2a\x8f\xf3\x53\x33\x62\x01\x20\xba\xb4\x6e\x83\xa3\x4e\xb0\xa7\xce\x0e\x17\xca\xf6\xe3\x2b\x67\xee\xf6\xde\x97\x07\x4f\x59\x58\xed\xbe\x7f\x1d\x8a\x47\x21\x17\x98\xa9\x65\xf5\xb3\x68\x32\xdf\xce\x89\x42\xc1\x30\xdd\xb5\x40\x52\x07\x88\xf9\x6d\x08\x80\x1e\xbd\xd8\x51\x14\x10\xec\x2f\xb4\xa1\xd6\xbb\x68\x60\x2f\xf4\x31\x2b\xf6\x6a\xba\xf7\x46\x11\x4d\x70\x7d\x7a\x2e\x65\x79\x89\x53\x64\x51\xc4\x13\xdf\x72\xea\xc0\x97\xa3\x2e\x4f\x14\x29\x8b\x64\xd8\xbe\x8a\x0a\xad\xf0\xfc\x01\x9e\x86\xca\xe9\x86\xe5\x77\xe7\x62\xde\x18\x77\xd2\x28\x70\x1f\x8d\x63\x88\x89\x67\x06\x62\xaa\xeb\xaa\x8a\xf5\x5c\x37\x32\x8a\x53\x40\x24\xae\xe3\xb7\x4f\xe6\xf0\xfc\x53\x4d\x58\x12\x07\xbd\xc3\xe7\x2d\xa8\xd2\xdd\x9a\x69\x3d\x2f\x4a\x64\x30\xb2\x5a\x7b\xaa\x60\xbd\xdc\xac\xba\x94\x2f\x4a\x74\xec\x65\xe8\xef\x44\x56\x7d\x5a\x91\x88\x67\xf8\x8f\x1f\x90\xa6\x56\x12\xc0\x19\x5c\x79\x6d\x20\x07\x64\xff\x1f\x6f\xee\x3e\x44\xb7\xfb\x4f\x2a\x2b\x00\xfe\x2a\xea\x55\x51\x9e\x0f\xaf\x5f\x36\xf1\x23\xc9\x62\x84\x95\xee\x9e\x17\x8f\xdb\xbb\xd5\xf3\x7e\xb9\xd9\xfa\xdd\x32\x92\x49\x8c\xd0\x8b\x6f\x65\x9e\xfd\xc2\x87\x78\x3b\x58\xbc\xaf\x26\xd2\x5f\x36\x43\x22\x99\x5a\x06\xe8\xa3\x38\xc2\x9b\xff\x26\xe5\x42\xbe\x7f\x66\x87\x43\xfd\xdc\xfd\x35\xe5\x3a\xb4\x4e\xd3\xcd\xa5\xee\x1f\x8b\x94\x60\x56\x23\x19\x99\xa6\xb6\xea\x86\xf7\x22\x18\x04\xfc\x91\x66\x11\x2e\x08\x0b\xad\xb7\xa5\xca\x44\xee\xdf\x86\xaf\x38\x1c\x2c\xd2\x9e\x01\x69\x6d\xd4\x4a\xbf\xea\xec\xd9\x7c\x24\x1c\x01\x0f\xb0\x65\x8b\x1f\x78\x82\xea\xa5\xd6\xb7\x03\x43\xe9\x6e\x94\xab\xc7\x3b\x38\xd6\x98\x77\xee\x1e\xe8\x6c\x3e\x1b\x99\xc0\x8a\x3f\x16\x4e\xb0\xd0\x67\xd0\x23\xf9\x3e\x16\x99\xd0\x96\xa6\xb5\xef\x68\x59\x89\xee\x06\x7e\x35\x7b\xcb\xed\x1e\x8d\xe7\x01\xb5\xf4\x57\x3f\x5b\x2d\x03\x60\x76\xba\xf0\x20\x66\xdc\x25\x2a\xdf\xb3\x36\xb0\xff\x9c\x9c\x4b\x58\xd2\x54\x2e\xda\xed\xd2\x06\x02\xee\x97\x73\x42\x08\xb5\x0c\xb5\x27\xf1\xd9\x17\x07\x39\x21\x91\xbd\x6f\x50\x37\x77\x65\xf9\x23\xeb\x82\x79\x4e\x23\x4b\x32\xdb\x5b\x2e\x08\x14\x50\xb5\xc9\x28\x2a\x6a\x5a\xa9\x8c\x51\x8e\x3e\x7c\x11\x38\x8d\x34\x80\x45\x74\xac\x9e\x9f\x16\x7f\x0c\xf7\x7f\x4e\xa5\xc2\xa2\x23\xaa\x80\xd4\x6d\xa0\xed\xcb\x10\x7e\x00\x18\xcf\x68\x40\xae\xdd\xd3\x40\x3d\x8d\x71\x6a\x08\x22\x9d\xda\xcc\x75\x61\x5b\x6e\xd6\x75\xfd\xef\xd5\xc5\x39\x35\x0a\xa5\x4a\x96\x98\x35\x95\x13\x10\x2b\xe3\x2c\x76\x12\xeb\xe7\xd3\xa9\xac\x1a\x3f\x61\xdd\xd1\x90\x91\xce\x73\x02\xef\xf3\xfc\x84\xe4\xa1\xd4\x58\xfe\xfa\xb1\xda\x78\x30\x0b\x8f\x82\xd8\x23\xfd\xbf\x89\xfa\xae\xac\xbe\x3d\x8f\x17\x70\x1e\x11\x40\x1c\x14\xda\x5b\x3e\xa3\x5e\xf8\x16\xa3\xfa\xa6\x63\xe2\x30\x1e\xa5\x80\x31\xf6\xf2\x71\x7d\x77\x99\x9b\x5c\x5b\x10\xe6\x2f\x33\x32\xda\x49\xa6\x34\x0f\x59\x91\xb5\x3b\xc2\xaa\x9d\xb0\xc9\x78\x6a\x71\x12\x25\xdc\x3f\xb2\xea\x38\xf2\xc9\x62\x9c\xa7\xb6\x44\x66\xf1\xf5\x23\xad\xca\xbe\xa0\xcd\xe3\x98\xf3\x61\xf1\xfc\x29\x03\x35\xef\x87\xcd\x78\x12\x01\xda\x7c\x3e\xa1\x67\xf0\x43\x59\xc0\xe7\x98\xe3\xc8\x78\xc2\x25\x72\x02\x9e\xca\x53\xaf\x21\x71\xa5\x8b\x30\x3d\x7b\xa2\x63\x17\xf8\x3d\x9e\x8f\x0f\xbe\x9e\xc7\x53\x1a\xc6\x0e\x2c\xfe\x80\x95\xb8\xa1\xb8\x9a\x1f\x93\x5a\x92\xc8\xbe\xc7\x38\x4f\xe6\x8f\x08\xac\x1f\xe4\xab\xa8\x7b\x46\xfa\x30\x62\xf1\xe3\x8c\xed\x37\x4a\x68\xea\x1f\xd0\x65\xe0\x5c\x06\xd6\xb8\xae\x6e\xca\xd3\x20\xcd\xe3\x52\x90\x38\x1c\xe2\xc1\x97\xe2\xb4\x6a\x5e\x37\x53\xa6\x01\xe3\x8a\x06\x08\xbb\xb7\xb0\x4a\xf4\x1a\xea\xce\xae\x98\xd5\xd3\xba\x59\x3d\xae\xee\xd6\xbb\xb1\x6f\xf5\xdf\xaa\xc2\x72\x1d\x30\xee\x95\x96\x9d\x82\xcb\x95\xc7\xa8\x59\x82\x3d\xf5\x65\x1b\xb2\xcf\x53\x17\xae\x7d\x07\x4b\x91\x31\x7b\x0b\x79\xf6\x6e\xfb\xac\xf8\x1d\x7c\x5e\xd3\xe4\xa2\x32\xe5\xd6\x6f\x1e\x8e\x37\x16\xae\x99\x40\xa6\xf1\x76\xf5\x78\xbb\x7e\xfc\xb6\xbf\xb9\xdf\x2c\x7f\xf8\x7b\xa3\xa5\x75\xb6\x51\x6e\x65\xe8\xfe\xae\xad\x06\xa7\x5f\xa4\x45\x8e\x33\x12\x91\xe5\x6e\x08\x90\x20\x72\xaf\xb6\x12\x15\xbe\x91\xc7\xb2\xb8\x74\x26\xf1\xc3\x23\x5b\xf6\xaf\x5f\xcb\x8f\x5d\x79\xaa\x47\xc5\x0f\x6e\x18\xc1\x4d\xe1\x28\x7e\xad\xeb\xfa\xdc\xa6\x1f\xc3\xb2\x31\x37\x0c\x62\x35\xaa\x58\xdd\x42\xad\xaa\xec\x74\xe1\x69\xc9\x62\x12\x44\xb8\xe3\x6f\xa1\xf0\x6e\xa6\xc3\x37\x3b\x26\x09\x19\x33\xbc\x87\xea\x5a\xb3\x4f\x35\x26\x2a\x80\xa1\x2c\x66\x3f\xcb\xe7\x35\x84\xdb\x4f\x68\x8c\x25\xf2\xf3\xdb\x85\xeb\xec\xf8\x6a\xb4\x41\x59\xab\x36\x08\x15\xc7\x2c\xbf\xf0\x15\x72\xe3\xa8\xb6\xe6\x1c\x28\x6c\x57\x6f\xcc\xa2\x02\xf1\xb7\x08\x6c\x2c\x66\x9c\xa2\xf4\xc6\xe3\xf3\xcd\xfe\x41\x74\xc5\xcf\x38\xa4\x36\xde\xd9\x36\xe5\xa9\x5f\x55\xfd\x41\x48\xb4\x85\xdb\x3f\x7c\x5a\x1e\xad\x2d\xd5\xef\x5d\xae\xe0\xc7\x45\xda\x20\xea\xb2\x4d\x17\xa5\xa8\xa1\x3f\xd1\x6c\x3c\x16\xc7\x42\x21\xa9\x32\x87\x83\xd7\x7b\x66\x71\x12\x2b\x94\x76\xdd\x41\xdd\x23\x8c\x47\xb7\x29\x31\x01\x6a\x2b\x7d\xa0\xc3\x58\x60\x79\x06\xa8\x95\x5d\x16\x7d\x1b\x37\x16\xb1\x41\x05\xd2\x02\x3e\xdc\x04\x9b\xbf\x25\x42\x70\x9c\x8d\x7d\x69\x63\x58\xce\x8c\x85\xb2\x5a\xf6\x37\x9b\x7f\xad\x07\xed\x80\x58\xb2\x90\x6b\x57\x7d\x1c\x44\xa6\xfe\x68\x4c\x94\x8b\x56\xee\xce\x85\xde\xfd\xeb\xca\xdc\x90\xda\x59\x4a\x63\x82\xba\x9a\x56\xb4\x63\xc5\x6d\x1f\xcf\x1a\xae\xdd\x66\xb5\x78\x2f\x3f\x3a\x67\xde\xf1\xed\x54\x09\xc7\xca\x51\xe7\x4d\xe9\x21\xef\x97\xf1\x6b\xac\x94\x50\x5e\x78\xe4\x7c\x42\x1c\xd5\x34\x97\x88\x95\xb6\xf5\x55\xcf\x4b\x7b\xbe\xd8\x0f\x62\x1d\x72\x64\x5a\x1c\x3f\x6f\xb3\x77\xbf\xca\xc6\x3a\xb4\xf3\xa0\xe7\x0f\x74\x62\x93\x93\x8f\x27\x09\x32\x8a\xac\x0e\xf6\x50\xfb\x80\xc5\x40\x39\xa6\xa4\xa8\x9c\xde\x66\xb2\xb6\xd9\xd3\xad\x73\x03\x51\x1a\xff\x09\x6e\xc9\x77\x8d\x9f\x39\x65\xfe\x0c\x38\x7f\x1e\xcb\x66\x08\x63\x8c\x21\xd6\x48\xfb\xcf\x8a\xec\x02\xb3\x33\xe1\xae\xba\x98\x2e\x09\x22\x9b\x37\x39\x22\xd8\xff\xcf\xd9\x9b\x2d\x37\x8e\x63\xf9\xc3\xaf\x53\x17\x7d\xc1\x05\x00\x89\x4b\x59\x96\x9d\xaa\xb2\x2d\xb7\x25\x67\x56\xcf\xc4\x84\x02\xcb\x81\xc5\x36\x45\xaa\x49\x2a\x6d\xf5\xd3\x7f\xc1\x03\x80\x9b\xe8\xac\xfa\xfe\x1d\xd1\x93\x3d\x26\x44\x51\x24\x01\x9c\xe5\xb7\x60\xc3\xca\x3a\xcb\x0c\x68\xab\x71\x1a\x08\xe0\x0e\x83\xf3\x34\xb1\x4d\xc1\x9e\x0f\xde\xad\xee\x01\xcd\xf2\xae\xdd\xe0\x30\x4e\x45\xe4\xd1\x33\xcf\x63\x91\x22\x3f\x24\x0d\xbc\xa8\xd3\xae\x7c\x16\x17\x80\x69\xc6\xf5\xc5\xa9\x45\x8a\x45\x8d\x6d\x03\x6f\xe5\xa0\x05\x92\x46\x9c\x41\x6f\x34\xe9\x89\xbe\xe3\xd7\x22\x8d\x64\x8a\xb9\xc0\x1e\x33\x5e\x54\x49\x19\xeb\x2f\x45\xc1\xe4\xfb\x22\x15\x03\x1b\x2a\xfe\x0e\xd1\x9b\x69\x64\x00\xa7\xb3\x06\xd1\x1c\x6e\x45\x23\xf6\x3f\x89\x3f\x16\x6b\x11\xa7\xbe\xf0\xbb\x30\x26\xcb\x33\xbf\x48\xd7\xdb\xbe\x5a\x92\x92\xd8\x60\xd4\x71\xbc\x3c\x94\x35\x0c\x98\xce\xed\x16\x2c\x70\x3d\xc9\xea\x1b\x84\x65\x4f\xfc\x55\xe2\x94\xa4\x60\x0d\x83\x0e\x7d\x53\x6c\x6e\x79\x4e\xa9\x24\xb1\xf3\x94\xeb\xe6\x3b\x3a\x80\x96\xdd\x6f\xa1\x26\xd1\x91\xdb\x6f\x06\xaa\x4a\x7e\x23\x0e\x27\x08\xf2\x30\x74\x9f\x4b\x92\x18\x39\x13\xb7\xb7\xbf\xaf\x76\xdf\x86\xf3\x20\x6d\x57\x49\x44\x6c\x55\xe5\x7f\xa1\xb8\x15\x97\x36\x74\x76\x91\x7f\x37\x26\x4d\x84\x18\xb0\x58\x6e\xce\x55\x31\xaf\x67\xe5\x3f\xa0\x63\x9c\x00\xed\x63\x6b\x1c\x8b\xb9\x2b\x1e\xa6\xa9\x92\x12\xb9\x12\x1f\xa7\x3b\xac\x0c\x0e\xf3\x93\x94\x4b\x86\x2a\x36\xcd\x14\x90\x33\x0a\x41\x66\xcb\x78\xa9\x54\x56\xe0\xa0\xc9\x8e\xb0\x3b\x88\xc6\x7a\x46\xdd\x9f\x45\x25\x8a\x06\x40\x0f\x7d\x93\xe3\x54\xc5\x54\x76\x0e\x77\xed\x8b\xf6\x5a\xf7\x22\xdc\xa3\xc8\x26\x55\x84\x62\xf0\xf2\x7b\x99\x15\xcd\x7a\xb9\xf1\x3b\xc7\xb8\x34\x9b\x2a\x9e\x22\xbc\xe3\x28\x3e\xdf\x3a\xd1\x99\x38\x55\xca\xd6\x00\xd0\x91\x30\xfb\xe9\xff\xac\x03\x6b\xbe\x89\x3d\x83\x5d\x85\xd8\xd3\x95\x2a\xeb\x4b\xdd\xc0\xb1\x1b\xc4\x24\x22\x6b\x8e\xe2\x73\x88\x40\x4c\x75\x02\xb8\x6f\xec\xc7\x90\xc1\x54\x8b\x10\x39\xd4\x08\x40\xbb\x2d\xb3\xf9\x6a\x7d\x0a\x91\x32\xd2\x5b\x70\x9c\x7b\x4e\x53\x9c\x1a\x92\xda\x17\xba\xc8\xf0\xb6\xf8\x13\x1b\xa9\x8d\x43\x01\xdd\xa0\x3c\xf3\x14\xba\x91\x1a\x43\x31\xb3\xb4\x31\x74\x27\x12\x6d\x8f\xf2\x80\x45\xa6\xbd\x37\x8f\xb7\xbb\x3f\x26\x20\xe5\xf1\xbe\xcd\x03\x26\x63\xed\x42\xe0\x76\x02\x2c\x3b\xc2\x71\xcc\x03\xb0\x68\x3e\xc7\xac\xe8\xba\x60\x77\x25\xe2\x75\xfd\xb0\x90\xd8\x52\x8c\xf6\xb5\x8d\xdc\x12\x4c\x9e\xa0\xb1\x75\xd3\xc9\xe6\xc6\x43\x61\x91\x67\x15\x8a\x5b\x75\xf4\xe1\xe7\x0a\x9c\x95\xe3\x57\x16\x08\x31\x0f\x65\x6c\x49\xd9\x28\x4e\x36\x8a\x25\x78\x28\x2d\x31\xde\xbf\xcc\xeb\xe3\xe9\x8a\x15\x37\x39\x5d\x44\xed\x6a\xb6\x15\xc7\xd3\xc4\x09\xef\x6b\x0c\x17\x0a\x8e\xd8\xa7\xa6\xe1\xb3\x2f\xbf\xb8\xed\x85\x7b\xce\xdf\x29\x17\x05\x34\x0f\x99\xf9\x35\x07\x3e\xe6\x94\xdb\xad\x53\x62\x1b\xc6\x4e\xf6\x1b\xd1\xa8\xc3\x35\xb0\xdc\xe7\xa0\x9c\x05\x29\x76\x6f\x57\xbb\xd7\xaf\x0a\xe8\xd7\x5f\xc4\x42\x9b\x78\xd9\x62\xd4\x75\x9c\xc5\x19\x91\x28\x29\x8d\x4e\xd8\x7f\x59\x98\x9f\xbc\x4a\x2c\xd1\x88\xf3\x72\x6a\x9a\xed\x4e\x32\xdc\x1c\x38\x4b\x00\x43\x09\xdc\x00\xda\xe9\xef\x7c\xd8\xfc\x61\xa9\x11\x31\xfb\x50\xbe\x59\xe8\xf9\x0f\xc8\x5e\xe0\x3f\xbf\x4d\x7e\x82\x16\x49\xdc\xb5\xde\xaa\xb2\x34\xd3\x49\x37\x45\xe1\xf3\x24\x96\xb8\xdd\x3f\x65\x0d\xd4\x87\xe1\x82\xcc\x13\x6d\x74\x5f\x20\x6d\xe6\x9e\xff\xdc\xda\xc7\x53\x9e\xea\xae\x01\xd8\xa6\xb6\x08\xa8\xf1\x67\xe5\x71\x8c\x6d\x4f\x55\x66\x85\xeb\xc0\xf6\xe1\x24\xe7\x84\x73\xd7\x14\xbc\xc5\x36\xcf\xe8\xdd\xe2\xca\xca\xa2\xb4\x2b\x42\x86\x06\x6b\xb6\x75\xdb\x2e\xde\x55\x1b\xa3\x4c\xba\x10\x9c\x6b\x81\x59\xc0\x7f\xcb\xf2\x58\x09\x63\x72\xb8\x03\xbf\x70\x71\xc1\x2c\xc2\x03\xf1\xb6\xc8\x67\xd0\x16\x81\xe9\x07\xc8\x28\x42\x1c\xe0\xff\xac\x36\x4f\xcf\x15\xd6\xec\xb7\x33\x41\xfe\xaf\x6b\x2f\x5c\x92\x00\xd1\x09\xce\xb6\x02\xd7\x90\xc9\x8b\x38\x3d\x51\xbf\x69\x73\x29\x2d\xe1\xcf\x0a\x9c\xe8\x9b\x2f\x52\x4d\x2e\xb5\x11\xd2\xf7\x5b\x1a\x07\x57\x24\x81\x3b\xaa\x98\x4e\xad\x00\x49\xa3\x0e\x57\x00\xd3\xab\x80\xb0\x9b\x48\x2a\xb1\x6a\x36\x7b\x25\xf2\x73\xbb\x06\x37\xde\xba\xc2\xcf\x67\x25\x21\x0d\x06\x62\xbc\xc7\xac\x58\x14\xba\xbd\x4d\x4f\x65\xbb\xeb\x75\xf9\x0e\xd7\x91\x85\xf5\xb4\xdb\xc4\xb2\x3c\x1e\xcb\x62\xb7\x7b\xc4\x17\x6e\xed\x8d\xb4\xb1\x3b\x83\xab\x87\xcc\x85\xaf\xe4\x73\x90\x1a\xc1\x55\x77\x9b\x87\xf5\xe8\x05\x35\x22\x40\x1b\xe1\xff\x9c\xa1\xba\xbc\x20\x02\x77\x29\xf2\x5c\xb6\x09\xfb\xc4\x4b\x60\x80\x63\xe1\x46\xea\xb4\x2b\x22\xd7\xb7\x59\x7d\x82\xa2\x07\xde\x70\x63\x0c\x96\x55\x06\x81\xbe\x08\x44\x88\x8d\xb3\xb7\xec\x27\x7c\xd1\xc9\x14\x81\x06\xab\xc3\x8f\x34\xec\x59\xd3\xe7\xe1\xcb\x2c\xc2\x88\xa4\xc1\x88\x38\x34\xbc\xb1\x22\x8c\x29\xc6\x26\x7b\x99\x7d\x4d\x4f\x98\x5d\x6b\x44\xc8\xad\xd2\x72\xbb\xcb\xef\x0e\x55\xf9\x61\x8b\x32\x4f\xf0\xf1\x02\x56\x64\xf5\xa9\xb4\x85\xe3\x5e\x42\x2f\x16\x91\x88\x91\x7b\x62\x29\xaf\x59\x73\xf9\x32\xab\x9d\xdf\x2f\x44\x9c\x00\x06\xf2\x05\x7c\x58\xa5\xe3\xd1\x46\x2f\x48\x22\xb1\x5b\xdc\x29\xe5\xb9\xbf\xd3\x38\x14\xae\x1c\xd7\xbe\x36\x0e\x0b\x3e\x8d\x6b\xc6\xbf\x30\x09\x40\x59\x44\xea\xe7\xfe\xad\x14\xb9\x2f\xba\xfb\xc3\xa1\x75\x8e\xd3\xb6\xac\x34\xa4\x41\x4d\x78\x4d\x22\xa1\x04\xe3\xa9\xdd\xe6\xa5\x23\x1a\x8a\x84\x27\x26\xf4\xe6\x91\xce\x86\xdf\xf2\xf4\x87\x2a\x58\xdd\xe0\x14\x59\x5d\x56\x72\x66\x5a\x29\x9b\x8c\x35\x16\x95\x0f\xca\xd1\x2d\x7f\x54\xed\x02\x36\xf6\xe3\x9e\x77\x53\x8d\x45\x1a\x47\xd8\x64\x41\x59\x0d\x31\x8a\xf7\x44\xca\x42\x41\x3c\xc8\xf3\xa2\xab\xef\x19\x7c\xcc\x49\x62\xc6\x22\x4d\x8c\xe5\x68\x21\x2b\xdb\x2d\x6b\x0e\x7c\xd6\x53\x93\x63\x91\xca\x30\xb6\xe5\xfb\x19\xb8\xde\x3c\x76\x7e\xf2\x63\x53\x69\xa5\xa1\xe1\x78\x6a\xa6\x75\x5d\x91\x42\xc4\x95\x0f\xe2\xaa\xaa\xfc\x98\x92\xc9\x44\x0a\x34\x40\x63\xa9\xb3\xec\xab\x5e\x36\xec\x19\x51\x7b\xdc\x70\x4e\x00\x65\x73\x9d\xb9\x5f\xbd\x2b\x3d\x8a\x60\xeb\x9f\x47\x5f\xa5\x16\x3c\x21\x08\x89\x3f\x7a\x29\x98\xfa\xb7\x2f\x7e\x62\xbf\x16\x0b\x9e\xa4\x3c\x1e\xdc\x3a\x7c\xd2\xab\x8e\xe6\x29\x38\xd7\x51\x87\x8b\xba\x2a\x54\xf9\x41\x92\x62\x73\xd7\x0a\x3a\xdc\x0e\x94\x6d\x9f\xab\xf2\xf3\xd2\x9d\x4b\x4b\x4c\x5c\x1c\x0f\xba\x9e\x42\xe2\x84\x08\xc2\x14\x5c\x2f\x7f\xe0\x30\x37\xf9\x36\x11\x2b\x06\xfd\x8e\x89\x33\x21\xcf\xea\x66\x94\x5f\x0b\x11\x1b\xd9\xf1\xf6\xc6\x1e\x14\xc3\x1f\xe1\x98\xfd\xb1\x10\x2c\x92\xce\xf2\xe8\x54\x16\xb5\xf8\xe9\x55\x3e\x63\x21\xc0\xca\x59\x65\x35\x62\x29\x7a\x4b\x8e\x58\xc8\x94\xf0\xa8\xf7\xe4\xbb\xff\xb1\xb0\xe1\xe1\xe8\xf5\x94\x20\x4c\x3c\x70\x63\x07\xbd\xeb\x50\xf8\xbf\xcd\x3c\x13\x15\xa7\x6e\x67\x53\xef\xe7\x93\x11\xd5\x71\xdd\xc0\xb1\xfe\x3a\x38\x14\x8a\x6a\xec\x68\x9e\xaa\xec\xbf\xdd\xb5\xa9\x14\x42\x57\xce\xc0\x4d\x2b\xfb\x6f\x6f\x5b\x3e\xbe\xa3\x4a\x59\x2c\xbd\x12\x56\x6c\x71\x57\xe2\xaf\x58\x7d\x2a\x38\x5d\x93\x58\x84\x36\x04\xbd\x8c\x1d\x13\x6b\xb9\xb9\x2a\x7d\x09\x08\x19\x32\x12\x54\x79\x3c\x0e\x18\xb7\x02\x52\xea\xb5\x43\x87\x5a\x47\xb1\x00\x15\x63\x7f\x53\x62\x23\xc6\xbb\x0a\xf9\x83\xa0\x31\x7f\x40\xd9\x45\x34\x92\x1b\x3f\x6b\x30\x91\xec\xf8\x4f\x9e\xc3\x66\x87\xf4\x7a\x11\xb1\x30\x11\x60\xe9\x64\xf7\x63\xb8\xe5\xca\x20\x35\xd4\x75\x88\x94\x68\xfe\x05\xa2\x42\x65\xd8\x19\xba\xb7\x0c\xb8\xc0\x95\xf5\xdb\xb9\x78\xab\x06\xc5\x17\x19\x06\x04\x95\xcc\xef\x7d\x5f\xc2\xfd\x3d\xa2\x1c\x31\x67\x0e\x8b\xd3\x47\xde\x32\x62\x02\x23\x6f\xdb\x5b\x76\x3c\x77\x7f\x30\x4e\x09\x96\xc9\x6d\x07\x0d\xa3\xde\x8d\xe9\x37\xe9\xd1\x1a\x2a\x63\x1e\x47\x36\x9b\x28\xdf\xff\x00\x38\x75\x11\xb6\x24\xd4\xa2\x76\x1f\xd7\x4f\x96\x9c\xbe\x5f\x3c\x0e\x60\x6d\x92\xb0\x40\x71\xd4\x1d\x2f\xdf\x3d\x39\xa1\x3b\xc6\x05\xaa\xd5\x54\x65\x9e\x6f\x6d\xd2\x3c\x7a\xc4\x92\x52\x0b\x15\xc5\xf8\xe8\xe6\x7c\xb9\x2b\xab\x6d\x79\x84\xb2\xe8\x7a\xd3\xa3\xc9\x2d\xa9\x08\xa9\x47\x4c\xae\x4e\xa5\x3a\x74\x8c\x77\xc9\x02\x82\xba\xb1\x76\xc7\x43\xab\xa1\xa1\xb6\x62\x2c\x59\x18\xc6\x96\x57\x60\x91\xa1\x43\x07\x97\x58\xb2\xc8\x0a\xc7\xe2\x9d\xff\x2e\xce\xf9\x04\xdb\x23\x93\xd0\x2a\x0a\xd4\xd0\x3c\x3a\x33\x72\x57\x02\xba\x82\x81\x4d\x3e\x28\x19\xf3\xb2\xf0\x8f\xe2\xf3\x56\x64\xf9\x05\x5b\xf4\xd3\xa8\x5c\x8a\xd8\x0a\x88\x64\xa8\xed\x39\x57\xe2\x95\xc2\x39\x87\x7a\xd1\x72\x4c\x57\xcf\x23\xad\x91\xf1\x07\x64\x10\xa2\xdd\xe2\xcf\x0c\x3e\xac\x2a\x76\x0e\xd7\x46\x19\xb1\x94\x31\x21\x03\xde\x8b\xeb\xb8\xcc\x2e\xd5\x52\x0a\x89\x6f\x30\x62\xd3\xd0\x95\xf8\x16\x7e\x66\xb8\x30\x60\x33\xa4\xe9\xa7\x9d\x94\x92\x60\xc8\xf0\xb8\xf8\x73\x7f\xbf\xd8\xee\x9f\x5f\xd6\x4b\x1f\x4f\x48\x15\x49\xa4\xd5\x17\xf0\xe1\xa5\xc3\x7f\x9b\xdb\x32\xa5\xe6\x2c\xf6\xd2\x5e\x13\xd1\x91\xf9\xa0\x4b\x82\x88\x10\xf2\xa9\x44\x9e\x17\x65\x83\xb3\xba\xbf\x2a\xa3\xad\x55\xf4\xa9\xcc\xb1\x56\xb6\x2e\x94\x3b\xa4\x02\xa2\xe2\xc8\xcb\xc6\xf5\xbb\x95\x3f\x9a\x0a\x6d\x86\x96\x70\x0f\x0b\x63\x26\x63\xc2\x20\xf1\x2a\xad\x8f\x1d\x61\x71\x32\x26\x02\x62\xa3\x58\x0c\x4c\xb0\x35\x88\xf4\x89\x4d\x81\x90\xe3\xa6\x7e\x1e\xa9\x55\x5d\x2f\xf0\x2a\x6e\xb7\x4c\xdb\x67\x7d\x29\xf3\xf1\x6e\xa1\x62\x50\xd6\xce\x6a\xf3\xf4\xba\xdd\xbf\xac\x7e\x2c\x5e\x3c\x07\x56\xc5\xc6\xba\x4b\x62\xf9\xd6\xdb\x4e\x5b\x71\xb0\xae\xc0\x1f\x46\x6e\xb5\x52\x44\x86\x56\xf5\x75\x64\xa3\x17\x75\x36\x7a\xb1\xa2\x61\x82\x60\x95\xf6\xf2\xef\x72\xf1\xd6\xfd\x3d\x65\x91\x53\x40\x5e\x2e\x36\xff\x7f\xa9\x2f\xfe\x24\xc2\x52\xc5\xe5\xf9\xb2\xcb\xd4\x3b\xf4\xb0\x8b\x6b\x89\x49\xff\x11\x1d\x62\x84\xd0\x2e\x58\x37\xaf\xff\x1a\x2b\x6a\x28\x06\x0c\xbb\x36\xde\xac\x04\xf4\x5a\x95\xb8\x55\x0c\xc4\x8f\x63\x95\xc4\x3a\x76\x14\xf5\xec\x78\x3e\xe2\x56\x36\x5c\x4d\x54\xc2\x05\x4a\x6e\x41\xd1\x40\xb5\x29\x6e\xe0\x20\x72\xb3\x31\x33\x57\x37\x9a\x67\x2a\x8d\x2c\x80\x42\x82\x2a\x8f\x70\x7b\x7e\x87\x39\x94\x98\x12\x61\xa4\x98\x4b\x1f\x9b\xf2\x66\xf2\xf6\x08\x63\x75\x7a\xed\x7a\xbc\x5a\xbc\x3c\xfc\x6b\xfb\xfa\xfc\xbc\x79\xe9\x05\xac\x62\x25\x03\x85\xdb\xe4\x51\x7c\xee\xfa\x56\x65\xbb\x73\x9b\xaa\x8f\x3e\x94\x24\xdc\x38\xa9\x1d\xbc\x03\x16\xed\xf9\x17\x7a\xb8\xb1\x92\x29\xc5\x32\xdf\x29\x17\x97\xe1\x6e\xa5\x24\x24\x84\xcc\xf1\x48\x6e\x2e\x9b\x29\xd6\x59\xa9\x98\x62\x3b\xbe\x0d\x37\x3b\x1b\xe2\x71\xdc\x39\x3b\xbd\x95\x62\x9d\x83\x6d\xe7\xd0\x37\xa2\x36\x29\x95\x5a\x59\x75\xdf\x83\xfa\x71\x80\xc2\x56\x9b\xa7\x7d\x2e\xa5\x64\x8a\x2e\xce\x3f\xcb\x06\x36\x85\x87\x36\x0d\x5a\x04\x4a\xc7\x81\x71\x85\x68\x2f\xfd\x6a\x93\xd2\xff\x0d\x13\xf6\x7f\xd7\x08\x20\xa5\x13\x15\x78\xeb\x48\x31\xdd\x12\x14\x70\xbb\x42\x9c\xda\xc8\xd6\xbb\xd2\xcc\xde\xf0\x2f\x72\x1e\x05\x32\xc0\xd7\xf8\x5f\x50\x3f\x95\x57\x0a\x07\xbf\x02\x13\x2a\x13\x0a\xdd\x77\x1c\x5d\xe9\x1f\x6f\xbc\xe3\xc7\x7d\xf1\x31\xc6\x9c\x40\x40\xa1\xff\x38\x3e\xa3\x95\x85\x3f\x04\x86\xf9\xa2\xfe\x0b\x1c\x45\x36\xe0\x5f\x2a\x63\x18\x6a\x6e\x74\x60\x21\xff\x1b\x74\x10\x85\x9a\x0e\x0d\x38\x70\x82\xbb\xdd\xcc\x87\xa5\x3a\x88\xac\xe0\x81\xb6\xfc\xc7\x9d\x13\x08\xe8\x33\x32\x1d\x24\x1c\x53\xa6\xe7\x87\xc5\xee\x6e\xf3\xf2\x88\xd4\xa7\xe7\xd5\xcb\x3e\x0c\x82\x20\xe8\x46\x49\xc0\x32\x3d\xce\x96\xfd\xfa\xe9\xfb\x1e\x17\x47\x7f\x38\x0c\xac\x46\xf9\x7d\xf6\x13\x84\x39\x77\x2b\x81\x0e\x63\xca\x5d\xf6\xbe\x03\x75\xd8\x5a\x58\x54\x77\x14\x98\x76\x5a\x13\xa3\xba\xa2\x3b\x1c\x09\x9e\x7a\xe5\x73\x5b\xe0\x74\xee\x62\xf7\xa5\x98\xb0\x26\x75\xa4\xac\x1d\xac\x6b\x30\xee\x3c\x59\xf4\xb6\xcc\x73\xe1\x43\x2a\x1d\xc7\x46\x0d\xcd\x11\x86\x8b\x92\x8e\x0d\xc1\x56\x91\xcc\xf4\x7d\x66\xbe\x00\x30\x68\x12\x3a\x47\xe0\xf3\x95\x8e\x9b\x1b\x41\x75\x9a\xba\xa2\xd9\x16\xaa\x9f\x50\xf9\x97\x7e\xe4\x14\x79\xf5\xd6\x6b\x0a\x0c\x4b\x16\x17\x10\x55\x64\x63\x68\x7f\x69\x2c\x09\x90\xcd\x24\xe7\x78\x2c\x9a\xa9\x4e\x7d\xe5\x2e\x13\xcd\x8c\xb6\xec\xe8\xfa\x18\x10\x5f\x1a\xc1\x3e\xac\xc5\xb2\xdd\x64\xf3\x8a\x64\xb1\x4e\x08\xa1\x49\x1f\xdc\xb4\x2f\x8f\xb5\xf8\xf1\xc7\x4d\x88\x05\xb3\xbb\xf5\xcb\x76\xb7\xdf\xad\x57\x2f\x53\xf6\x86\x4e\x19\xe7\xd6\x58\x40\xe5\xa2\x82\x27\xf8\x80\xea\x3b\x54\x03\x78\xb2\xe6\x21\xe0\x03\x44\x3a\xf9\x73\x59\xe6\x57\xc9\xa9\xe6\x90\x62\xd6\xd3\xce\xf7\xc2\x31\xb0\xbf\x78\x06\x82\x58\xc9\xa1\xba\xac\x1a\xa7\xfc\xe3\xba\xe4\x6e\xe5\xa1\x7e\x86\x08\x1a\x63\x2b\x25\x07\xd3\xf0\x60\xf2\x56\x09\x6e\x52\xdf\xac\x53\x07\xb8\xbe\x24\xa1\x38\xfe\xf6\xa3\x78\x87\x9d\x38\xed\x3a\xd2\x8d\x96\x61\x22\x7b\x05\xce\x2f\x6e\xad\x64\x2c\xb1\xda\x3d\xdf\x90\x98\x70\x72\x56\x58\x20\xd4\xa1\x8b\xb7\xb4\x14\x06\xa3\x40\x5b\x5a\xdc\x9e\xfa\xce\xad\x96\x5a\x30\x47\xc3\x5d\x58\x7f\x2b\xd7\xba\xf7\xd1\xf4\x17\xc5\x60\xf7\x71\xa5\x23\x54\x78\x3f\x8a\x4f\x87\xbe\x5e\x17\xd8\x52\xf2\xe7\xd7\xa1\xa5\x50\xd7\xd0\x3c\x81\x55\x32\xb4\xda\xf9\xd3\xc2\x8a\x86\x30\x45\x29\x40\xbf\x63\x3c\x5e\x2c\x63\xdc\xb5\x3f\xfd\x72\xa7\x41\x10\xe9\xae\xf8\x51\x55\x16\x2b\x74\x57\x56\xf7\x62\x82\x6e\xd0\x20\xa5\x04\x8f\xb1\xe8\x8b\x35\x4e\x6c\x6c\x7d\x3b\x5e\x2c\x20\x60\x0a\x43\xf0\x67\x71\x79\x16\x97\x41\x66\x08\x61\x90\xb0\x68\x88\x52\x5a\x6b\x10\x37\xe7\x8b\xb5\x4f\x1b\x7f\x2b\x84\x5a\x49\xb7\xf5\xbc\x94\xe7\x06\x4d\x7f\x6e\x2e\xb6\xf2\x38\x1e\x19\xc5\x24\x72\x4a\x70\x96\x58\x60\x85\xe6\x77\x6d\x62\x53\x88\x7c\x14\x52\x42\x94\x4a\x21\x7b\x93\xc7\x99\x38\xcc\x2f\xd9\x10\xc9\x50\x3a\x4f\xda\xbd\x05\x0c\x4f\xbe\x98\x04\x41\x68\xc5\x00\x70\xf7\x73\x59\xfc\xe8\x69\x00\x89\x24\x26\xf3\xff\x03\xc5\xc2\xc7\x9a\x40\x84\xd5\x43\x93\xe7\xaa\x68\x13\xa8\xb1\x96\xa4\x1f\x24\xb9\xe9\xdc\x14\x7f\x2f\x27\xa1\x37\xd0\x20\xa1\x03\xe7\x06\x2b\xce\x66\x11\x3f\xe3\x2b\xa0\x24\xf6\x5c\x0a\x75\x3b\xb4\x0f\x68\x0f\x09\xd4\x26\x59\x8a\xea\x16\xaa\xc1\x16\x7a\x27\xf2\x29\xfb\x08\xa8\xe2\x58\x94\xed\x5a\xa1\x83\xba\xeb\xca\x65\x4b\xb3\x6b\x00\x24\x31\xe7\x8e\xfe\xef\xc8\x24\xa3\x0a\x1f\x99\x0e\xa7\x21\xef\x80\xc3\x58\x38\xcb\x14\x98\xb2\xba\x15\x27\x3f\xa9\x21\x49\x02\xa4\x95\x78\xe1\x05\x9b\xef\x3a\x9d\x87\xbf\x28\xa3\x4f\xbf\x8e\x07\x71\xcf\x18\xde\x62\x41\x74\x7c\x07\x13\x49\xd0\x32\x5e\xa1\x07\xd5\x8f\xcc\xbd\x66\xdd\xb5\x28\xc6\xa8\x5b\x7a\x10\x52\xd8\x1d\xd0\x04\xc5\xe9\xad\x15\x28\x0a\xe7\xad\xda\x2c\x0a\xa6\x8f\x3a\x4d\x13\x0c\x2e\xb6\xd9\x1b\xe6\xd3\xe3\xaf\xe7\x69\x80\x6d\xb1\xbd\x05\xe9\xa3\xc1\xbb\x41\xd9\x1a\x8b\x92\x70\xe1\xc8\x20\xab\x02\x9e\x2a\x94\xf2\x58\x6e\xb6\xdb\xd1\xb5\x72\xa9\xf0\xc7\xda\xb8\x7d\x7b\x2a\x8b\x1e\x7e\x01\x5c\x49\xa4\x61\xde\x64\x55\x73\xf8\xe2\x59\x0a\x46\x10\x18\x54\xb4\x79\x78\xe5\x6d\x49\xba\x37\x5b\xb0\xc4\xe2\xef\x76\x8b\x97\xdd\xfa\xe9\x7e\xbf\x7b\x7d\xd9\x3d\xac\x7c\x7c\x02\x52\x58\xa9\x7c\xe1\x8a\x7f\xe5\x16\xe9\xcf\xb3\x8b\x22\xa8\x20\xb2\x70\xcc\xb3\xc4\x35\xbb\xdf\xa4\x40\x05\xcc\x1a\x76\xe5\x20\xaa\xdf\x85\x7a\x3f\x95\xcd\xb5\xdb\x5a\x0c\x8a\x06\xa8\x25\x74\xbb\x5a\xae\x1f\x17\x0f\xc3\xbd\x10\x54\x42\xb1\xff\x67\xe1\x9b\xed\x6b\xfc\x5a\x58\xb2\xcf\xed\x15\x5a\x08\x94\xd4\x88\xb0\xcc\xea\x95\x75\xfc\xf7\x22\xd9\xe3\xdb\xa3\x43\xe2\x1d\x3d\x6f\x33\x71\x2c\xa7\xd5\x40\xd0\x24\x15\x64\xf0\x72\x6f\x55\x79\x9a\x2e\x7d\x5a\x5a\xdf\xe8\x37\x68\xec\xb2\x7c\x3b\x9d\xd4\x26\x88\x13\xec\x3a\xde\x21\x31\xef\x16\x72\x71\x19\x98\x21\x4d\xc6\xf2\x28\x10\xae\x25\xfb\x88\x34\x99\xdf\xfc\x11\x99\x20\x04\xe3\x03\x57\x85\xbb\xee\xcf\x5a\x13\x57\xa6\x68\xe7\xd7\x15\xcb\x63\x74\xb5\x26\x0c\xc2\xb4\xdf\x5f\xdb\xd4\x79\x24\x75\x31\x3f\xeb\x4c\xc8\x2c\x9c\xe9\xfe\x05\x95\x42\x0e\xd6\x1b\x64\xf6\x3d\x30\x91\x13\x28\xd9\x6b\x87\xe4\x32\x65\x75\xbd\xd4\x9a\x08\x08\xde\x5a\x51\x74\x45\x56\x13\x87\x01\xe2\x03\x4f\xed\x1a\xe2\xdf\xb6\xf1\x95\xc4\xa9\xc6\xd8\xf7\x1e\x9a\x6d\xf6\x56\xf8\x68\xe8\x57\xc9\x87\x21\x3c\xc6\xd8\xb3\x3c\x37\x9b\x9f\x50\x21\xf1\x70\xed\xc3\x04\x43\x8c\x65\x3e\xdc\xb7\xef\xd2\xd0\x75\x33\x36\x34\x08\xb0\x8d\x81\x3a\x88\xcd\xe1\x31\xcb\x41\xbc\xc1\x73\x99\x4d\xc9\x7c\x86\x06\x29\xc2\x58\x6a\x68\x1e\x40\x98\xf9\x1a\x96\xa1\x91\xc2\xa0\xe9\x43\x54\x55\xd6\xcd\x64\x43\x59\xec\x12\xbd\x02\x2a\x8c\x7a\x8e\xa7\xf6\x1a\x77\x50\x1d\xeb\xe9\x17\x71\x26\x3a\x7b\xe9\x21\xf4\xc7\xb0\x90\xfb\xf7\x00\x4b\x0b\xfd\xe6\xeb\x5b\x05\x86\xa5\x29\xbe\xaa\xbb\x43\x56\xbc\xd5\xea\x20\xb2\x62\x06\xa6\x69\x98\xa4\x98\x75\x1d\x61\x80\x7a\x30\x89\xe9\x25\x5c\xbd\x2f\xd5\xc4\x34\xc1\xa3\x85\x0c\xa7\x04\x83\x10\x79\xbe\xac\x97\x9b\x51\xcd\xdb\x70\x46\x82\x60\xc0\x34\xb1\xee\xcc\x96\xf1\xd1\x0f\x92\x02\x0b\xab\x15\x34\xe7\xaa\xe8\x99\x64\x86\x2b\x8d\x14\x2d\x94\xfd\x40\x5e\x62\x59\xad\xbc\x96\xc1\xf8\x67\x08\x6a\x09\xd8\x4d\xd5\xa7\xbb\xe3\x9b\xa9\x82\x18\xfd\x96\xee\xcf\x83\x0a\x6a\xb7\x01\x8d\xff\x99\x7c\x92\xc4\x18\xb6\x59\x31\xca\x7e\x2d\x37\x4a\x0a\x6f\xec\x6b\x9d\x8a\x1c\xc3\x52\x5c\x5d\x9e\x32\x21\x0a\xd6\xec\x6b\xd5\x5c\x89\x0d\xfc\xba\xa9\x6c\x20\x88\xf1\x2e\xec\x5d\x67\xc6\xe2\x36\xee\x00\xe6\x95\x41\x0c\x90\x14\xe1\x5f\x79\x29\x7a\xc7\xfe\xa1\x42\xc0\x98\x37\x62\x80\x59\x26\x6e\x0d\x87\xca\xe2\x4d\xfd\xfd\x07\x6e\x85\x3e\x33\x55\xee\xbc\xde\xea\x38\xee\x36\x26\x32\x68\x57\xf9\x01\x99\x7f\x32\x83\x4e\x8a\x31\xdc\x86\x31\x8f\x8b\xe5\x08\x73\x68\x8c\xe2\x2e\xc1\x2a\x2c\x40\x6b\x57\x0e\xf1\xb3\xc8\xaa\xc5\x0d\xba\xac\xa1\xda\x7c\x35\xc7\x0c\x18\xd4\xf1\xf8\x1f\xa8\xca\x17\x7c\x7b\x86\x35\x77\x12\x04\x91\x8c\x03\xd7\xe0\xc9\x9a\xd5\xb9\x2a\xbb\x23\x09\x47\x76\x8b\x3c\x5f\x86\x05\x0a\x7f\x38\xe4\x80\x1a\x20\x37\x9b\x1b\xff\xa7\x28\xb0\xf6\x1c\x55\x3b\x5b\x47\xe6\xf4\xed\xb1\x34\xb0\xf0\xf5\x6f\x20\xf2\xe6\x70\xe9\x0e\x90\x90\x93\xee\xd5\x46\xc2\x8b\xe8\x8e\x25\x56\x53\xeb\xb8\x3d\x1f\x5f\xc4\xc7\xf6\x04\xfe\xb6\x92\x80\x84\xd6\x3e\xd1\x29\xb1\x0c\x7b\xf2\xdd\x90\xd8\xd2\x58\x5c\x19\xcc\x6e\xf7\x73\x30\xb1\xff\x07\x39\xa0\x5f\xd6\x4c\x49\x40\x52\x6b\x17\xe2\xac\x8a\xca\x32\x1f\xc9\x66\xbb\x51\x2c\xd2\xb8\x4c\x6e\xdf\x2f\x83\xd5\xc7\x1f\x8c\x43\x12\xf4\x9e\xf8\xaa\xc9\x7e\x66\xcd\x58\x60\x94\x04\x8c\x46\xf8\x78\xf1\x7b\xda\xf0\xab\x53\x9e\x9f\x69\xb0\xb7\xc3\x15\x06\x49\x8b\x3c\x13\x75\xf7\x45\x52\xfa\x7e\xb3\xeb\xb6\x0d\x0a\x1a\x24\x48\x94\x92\x96\x7d\xed\x0c\xaa\x27\x97\x90\x86\x1c\x17\xc2\x5c\xb8\xd6\xad\xa7\xd9\xf8\xe3\xb1\xb6\x0b\x25\xfe\x79\xff\x26\x8e\xb0\xcf\x8a\x9f\x59\x73\x25\x9b\xf5\x8f\xf3\xd0\x71\x63\x50\xdb\xe8\x88\x91\x73\x1b\x1a\x09\x52\x6d\x71\x3e\xed\xf2\x5a\xb4\x6b\xdb\x22\xf7\x5a\x1d\xdd\x55\xf0\x80\x81\xf7\x60\xc1\x9e\x3e\x1a\x8d\x5c\x41\x26\x48\xc0\x53\xe6\x95\x64\x96\x22\xcf\xdb\xff\x82\xf6\x1e\x01\xc3\x64\x91\x04\x1c\xb4\xb1\x60\xb2\xb2\xac\xc1\x66\x07\xde\xf8\xde\x7f\xaf\x48\x22\x8c\x29\xf7\x1e\x16\x3c\x7a\xc6\x22\xa1\x98\x6e\x3a\xd3\x88\x9b\xf3\xa5\x5d\xb4\xe6\x16\x39\x12\x08\x4e\xad\x7a\x5c\x25\x8a\x66\x60\xa1\x3e\x1e\x25\x09\x45\xc7\x23\x4f\xe4\x1e\xb5\xd1\xfe\xe6\xcb\xab\xa2\x18\x35\xc3\xb7\x4d\x59\xc0\xe8\x7a\x75\xcc\x78\x34\x74\x90\x03\xbd\x70\x76\xc1\x93\xeb\xd0\x69\xec\x25\x6d\xbc\x0c\xf7\x1a\xc9\xf0\x4f\xe5\x94\x2d\xd6\x0e\x36\xde\xb4\xc3\x76\xa1\xaf\x58\x6f\x24\xd0\x3a\xa6\xb2\x93\xa2\x76\x32\x07\x7a\xf2\xad\x40\x19\xee\xe8\x15\xbc\x9d\x73\x51\xed\xdb\xa8\xb1\x7b\xcf\x21\xf5\x15\x28\xec\xf1\xa3\x7f\x74\x35\xc6\x7e\x90\x30\xa0\xa0\x5d\xe4\xd2\xa3\x4a\xd3\xf1\xa3\x08\x03\x11\xb8\xce\x40\x73\x1e\xdb\x98\xb9\x2d\x9f\x84\x21\xb5\x6d\xe1\xc5\x49\x55\x5a\xfc\x0f\xc8\x0c\x67\xb8\xff\x9a\x28\x88\xa2\x60\x10\x49\xef\xda\x55\x6c\xfc\x63\xc2\x28\x8d\xd2\x8e\x28\xdf\x7d\x50\xd1\x88\x75\x52\xd6\xb0\x7f\xbf\xa8\x3d\x16\xbb\xda\x2c\xdf\x75\x7e\x67\x67\x49\x48\x0d\x41\x42\xec\x5e\x68\x7d\x2b\xb2\xf9\xb7\x2c\x64\x01\x60\xd8\x64\xf9\xff\xf8\x16\xc1\xbe\x63\x9d\x75\x90\x2c\x12\x32\x0a\xa8\xdb\x8d\x91\xd7\x2d\xf8\xf7\x6d\xf8\xba\x84\x4c\x87\x88\xf9\xb4\x04\xf8\x2f\x91\x3a\xf3\xd7\xcb\x0c\x93\x96\xe2\xd0\x86\x6f\x03\xcd\xf2\xf6\x90\xf0\xd6\xb9\x37\xd0\x3c\x79\x17\x27\x12\x26\x61\x82\x19\x13\xfa\x23\xee\x4f\xa2\x6a\x0a\xa8\xc6\x78\x24\x12\x26\x11\xc7\xca\xc7\xb9\xf0\x21\xf9\xed\x62\x33\x53\xc5\x20\x61\xc2\xa8\x06\x0f\x04\x9a\x85\x7b\x91\x30\x51\x31\x3e\xe8\x71\x01\xe5\xd7\x33\x2c\x4c\x14\xc3\x4a\x37\xd6\xab\x87\x96\x61\xee\x78\x9a\x68\x64\xfd\x1c\x6d\x85\xe0\x72\x6b\x75\x09\x67\xf7\x78\x12\xa6\x86\x3a\xf0\x0a\x32\xc1\xe6\x8d\x04\x7b\x3c\x12\x09\xb9\x09\x51\x98\x04\x4f\xbf\x50\x0a\xea\x7a\x5d\x8f\x94\x8c\xdd\x40\xa1\x25\x42\xf5\x9f\xcb\x32\x77\x0f\xd1\x1d\x91\xa1\x8e\x10\x31\x59\xba\x58\x15\x74\x17\x55\xba\x21\x2a\x88\xb0\x4c\xae\xa1\x81\xaa\xdd\x5c\xb0\xde\x6b\xd9\x05\x9b\x73\xd3\xe6\xf0\x93\xfb\xad\x54\xc0\x5d\xee\xb8\x6e\xe0\xb8\x6d\x4a\xef\x4d\x15\xba\x35\x37\xd4\x01\xc7\x60\xdc\x6a\x52\xde\x96\x45\x17\x4a\x91\x50\x33\xeb\xc5\xe6\x74\xda\xa1\x7a\x14\xc5\x59\xe4\x9e\xb5\x48\x42\x10\x02\xdd\x72\x8c\x78\x87\xa7\xb2\xbb\x50\x00\x82\xf8\xe7\xc7\xc5\x9f\xfb\x7f\xbe\x2e\x9e\x76\xeb\xdd\xbf\xfc\x31\x93\x68\x0c\x60\xa1\x39\x60\x80\x3f\x36\xbb\x25\xa1\x91\x29\xb1\x2b\xa2\xf5\xda\xbc\x86\xb5\x90\x28\x88\x18\x2a\x5e\x8c\xd5\xf5\x49\x14\x08\x8e\x31\x91\xa5\x36\x0c\x26\x4e\x14\x68\x85\xaa\x1e\x58\xab\xbd\xad\x32\xd1\x1d\x09\x53\x12\x32\xc7\x45\x3b\x62\x29\xd3\x52\xd3\x27\xaf\x6e\x14\x69\x26\x7b\xd3\xe1\x17\x51\x59\x70\xef\x2f\x5f\xcb\x28\x02\x89\x68\x56\xdc\x24\xfd\x92\x18\x45\xc6\x5a\x24\x59\x68\xd9\x0f\x80\xf7\x71\x6c\x17\x45\xc6\xf2\x08\x9a\xf2\x66\x35\xb9\x0c\xd4\x00\x76\xb7\x76\xfd\xf4\xfc\xba\xdb\xbf\x6e\x57\x2f\xdb\xfd\xa0\x96\x41\x22\xc2\x84\xb6\xa5\xd5\x0e\x5a\x39\x9b\xc3\xb4\x23\xa5\x37\xd6\x70\x95\xe6\x6e\xfd\x9e\x59\xa7\x23\x1a\xc6\x2c\xf4\xab\xac\x16\x17\xdb\xa6\xec\x55\xce\x48\x44\x1d\x65\xe5\xf1\xee\x69\xf4\x00\x12\x42\x10\xe4\xe2\x5c\x67\x97\x2f\x9b\x1f\xb7\x88\x6d\xdc\x6e\xee\x76\xfb\xe5\xe2\xb9\x1b\x98\x18\x54\x2f\x90\xa2\x4d\xc0\x36\xb9\x1e\xc4\xe8\x24\x4a\x44\xc8\x6d\x06\x0f\x3f\xb3\xf2\x5c\xe3\xdb\x31\xa1\x55\x90\x28\x15\x1a\x17\x7a\x6f\xec\x32\x23\xd3\x49\xa2\xd4\x68\x8a\x4d\x04\xf1\x8e\x02\xf7\x83\x62\x1d\x89\x38\x67\x3a\xec\x18\x8a\xcb\x76\xd7\xdb\x95\x83\x25\xd7\x0f\x93\xda\xf7\x94\x5e\x11\xdb\xe7\x48\xb6\x73\x95\x0b\x12\x71\x05\xc6\x19\x0d\xa2\x61\xd1\xc4\x07\x93\x44\x82\x50\x04\x5c\xfd\x61\xcd\x3e\x9f\xc0\xcf\xa8\x48\xa4\xd2\x4e\xfd\x85\xd6\x8e\x92\x3f\xd5\xbe\x19\x5f\x99\xe0\x21\x9e\x6a\x71\x3a\xe5\x70\xaa\xca\xd1\xc3\x10\x9c\x41\x6f\x01\x33\xd9\xb1\x23\x19\x84\xb8\x68\x20\x12\x26\x2b\x6a\xa8\x9a\xbd\xc9\x0a\x5c\x8e\xbe\x39\x72\xcc\xda\xc9\x63\xea\xdf\x46\xdf\x2a\x25\xc7\x82\xe2\xb6\x11\xd5\x6b\x91\x35\x80\x70\xfb\xbf\x24\x92\x90\x48\x1a\x83\x15\xbc\x63\x56\x34\x37\x42\xbf\xcd\xcb\xab\x90\x48\x05\xb6\x88\xba\xac\x2e\xa7\xa6\x3e\x94\xa7\x53\xff\x6e\xa8\x20\xed\x15\x69\xe7\xc5\x05\x49\xa4\xc2\x38\xee\xbd\xe9\x27\xa4\x83\xf6\xb0\x44\xec\x96\xd5\x01\x5b\xb8\x3d\x78\xde\x46\x8c\x44\x4a\x72\x67\x71\x23\x1a\x18\xce\x02\x4d\x25\x78\xcf\x14\x3b\xad\xae\x2e\x44\xb3\x84\x58\xa6\xad\x39\x17\x7a\xad\xca\xee\xb3\x0c\xd0\x4a\xf9\x5c\x54\xce\x87\xb3\x4d\x43\xa6\x60\x66\x12\xe9\x24\x90\xa2\xf7\xd7\x5b\x1e\xa0\xd7\x45\x9f\xdc\x35\x0d\x06\x81\xf6\x78\xd7\xca\x6f\x9d\x20\x08\x89\x0c\x51\xca\x89\xb3\x3f\x43\x55\x97\x85\xc8\x31\x84\x9f\x34\xdd\xff\xf6\x3f\xf6\xb4\x71\xc0\x63\xcc\x65\x4d\x59\x35\x99\xb9\x2c\x73\x91\xb9\x4a\x53\x38\x44\x91\xf4\x99\x5b\x1c\x48\x49\xdd\x4c\xf2\x32\xd2\x7e\xb9\x8f\xc3\x36\x11\x76\x36\x16\x58\xb1\x54\xa2\xd2\x57\xa5\x71\x12\x87\xc2\x58\x7f\xbc\x76\xe0\xd8\x69\x6d\x74\x3f\xe2\x50\x5b\x93\x37\x14\x05\xb6\x3e\xe0\xde\xf3\x14\x2f\x75\xdc\x91\xf8\x25\x52\x9b\xc4\x51\x44\x50\x03\xe3\x51\x34\xea\x70\x63\x55\x92\xee\x84\x42\x2d\x97\xf1\xf5\x45\x34\xd2\x89\x67\xb6\x5e\xb9\x6f\xf8\x41\x26\x00\xea\x79\x0e\x9b\x4a\xa8\x31\x0c\x8a\xc4\x71\x60\x53\x1c\x7d\xf6\xa2\x65\x24\x8e\xa5\x35\x31\xfc\xb6\xf8\xee\x37\xda\x98\x04\x80\x9b\xb0\x6d\xf2\x50\xff\x67\x6a\x6c\x10\xd1\x2e\x7b\x1d\x70\xb2\x53\xac\x1e\x77\xbd\x48\xcc\x02\xa3\x52\xef\x49\x94\x5b\x3f\xc8\xdc\xbe\xea\x83\xf8\x27\x66\x34\x40\x4e\xa3\xb3\x7a\x7d\xb8\xf3\x6a\x22\x93\x1b\xe9\x87\x8b\xd8\x24\xbe\x9b\x57\x36\xd1\x3e\x64\xe3\x85\x35\x66\xd2\xba\x4d\xdd\x56\xe2\x63\xb2\x13\xa3\x52\x80\xe9\x84\xcd\x9a\x2a\x53\x6d\xd6\x34\xb0\x0b\x9e\x3c\xed\x44\x87\xa8\xf2\x77\x2e\x5e\x70\x35\x9f\x9e\x4e\xa7\xde\xcc\xf5\xb6\xce\x5c\x16\x86\x37\xe4\x4b\x5c\x31\x41\xd6\x21\xed\x7f\xf0\xd3\xc2\xb5\xd2\xc6\xcf\x92\x47\xcc\xc8\x6e\x8e\x3b\x25\x4b\x6b\xcd\xfb\xe5\xbb\xc9\x69\x80\xb9\xe2\xa2\x68\xda\x10\x6f\xb8\x6e\xc7\x3c\xd1\x32\xec\xc2\xf4\x7a\x20\x44\x48\x62\x11\x48\xac\x18\x9e\xce\x28\xf6\xa5\xbb\xd9\x23\xd2\x14\xb7\x4c\x1b\xda\xe9\x1b\x51\xf4\xfb\x69\x2c\x04\x45\x39\x81\x47\xd0\xb2\x8b\x89\x62\xa1\x2c\x68\xf7\x36\xab\x40\xb5\x11\x41\x01\xca\x36\x02\xed\x6b\xed\x87\x01\x23\x8e\x79\x01\x0d\xdc\xae\x6f\x6d\xab\xf5\xc7\xa1\x5b\x7e\xff\x07\xaa\x72\x72\x4f\x64\x12\x49\x32\xc6\xaa\x79\xac\xd3\x74\xa4\xb0\x9e\xdc\x59\xbd\x6d\x2a\xd1\xc0\x9b\x93\x1b\x0e\xa9\x1f\x20\x2d\x80\x29\xcf\x8a\xf7\x5f\x76\xd4\x49\x2c\x55\x88\x81\x98\x71\x32\x68\x4f\xe2\x08\xf1\xb8\xfa\x10\xab\xc4\x76\x0c\x6e\x5e\xca\x8b\xc8\xfb\x56\x35\x89\x95\xe6\x58\x52\x6e\xa3\xf6\xa1\x42\x24\x89\x35\x4b\x95\x35\x40\x6f\x6e\x44\xf1\x3e\x32\x20\x25\xb1\x36\x0e\x3c\x71\xae\x8a\x89\x35\x31\x89\x0d\xe3\xcc\xf5\xf0\x67\x4b\xa6\xfd\xda\x68\x52\x12\xf9\x06\xf1\x7d\x99\xeb\x5f\x90\xa0\x09\x09\x62\x8a\x4b\x6f\x63\xeb\x4e\x76\x6b\x1f\xd9\xc6\x91\x36\xad\xc3\xf7\x68\x51\x65\x85\x70\x74\x9a\xfd\xbf\xcf\xfa\xad\xab\x46\xa5\x93\xb3\x46\xc4\x1a\xbd\x2b\x4f\x2e\x9a\x55\x68\x27\xed\x1a\x67\xd9\xe4\xa2\x11\x77\x55\x79\x74\xaa\x71\xc3\xbb\x42\xe2\x98\x20\x99\x61\xf3\xb4\xb2\x38\x46\x7f\x59\x24\x10\x29\x73\x8a\xa6\xd0\x0c\x9b\xd3\x84\x10\x62\x40\xf6\xa6\xa5\xb6\x61\x38\x49\x20\x27\xd7\x42\x68\x80\xb5\x39\xe4\xa0\xe1\xb2\xde\x1d\xb0\xad\xfc\x2b\x03\x54\x44\x6c\x5f\xaf\xc9\x84\x88\x08\xf5\xe7\xf6\x32\xab\x9a\x83\xdd\x28\x67\xe8\xa0\x8c\x4c\xc4\x91\xdb\x4b\xb0\x26\x29\x59\xe1\x32\x7f\xef\x5d\x3e\xf9\x06\x4a\x7c\x93\xa8\x79\x14\x9f\x08\x47\x5d\x35\x87\xc5\x80\xe8\x44\x08\xe5\x96\x66\x9e\xd5\x4f\x65\x71\x77\x2e\xde\x90\xf3\x3f\x7e\x4e\x69\xa0\xb1\x13\xe8\x0b\x0c\xf9\xf4\x38\x00\x56\x3b\xfe\x5d\x66\xc5\xf2\xd0\xde\xe1\xa9\x46\x33\x21\x3c\x32\x08\xb8\xea\xc0\x5a\x9d\x53\x0f\x21\x9c\xca\x90\xf6\xa2\x51\x5b\x68\xd0\x43\xa8\xea\x8e\x2b\x1a\x89\xce\x99\x67\xb4\x71\x11\xae\x2d\x69\xa7\x8d\xdd\x27\x31\x27\x11\x9c\x60\x9d\xe9\x38\x30\x43\x69\x53\x31\x47\xb0\xf2\xa3\x54\x08\xce\x97\x0a\x39\xe2\x93\x90\x88\x48\x9e\x20\xa9\x00\x05\x05\x6f\x60\xf2\x2a\xff\x0d\x0c\x22\x21\x52\x11\x8c\x60\xeb\x06\x4e\x9b\x62\xd0\x58\x20\x44\xc5\xb1\x7d\xb7\x2b\x10\xc7\x1d\x88\xee\x7d\x52\x9c\xe1\x96\x2a\xb4\x5e\x5b\xea\xcd\xd8\x49\xb7\xbb\x3e\x25\xac\x48\xb3\xc3\x8b\x4d\x3c\xb1\x09\xd1\x71\x90\x7a\x58\xe1\x9d\xc8\xf2\x73\xd5\x7d\xb9\x8e\x2d\xd5\xa6\x41\x3c\x21\x66\xce\xf5\xf4\xd3\xcc\x60\xf6\x2b\x41\x60\x39\x73\x3c\x81\xb4\x94\x09\x1d\xf9\xf8\xb6\x0b\xce\x7a\x40\x5f\x98\x4c\x1f\xdd\x26\xc7\x0e\xa5\x7c\x25\xd0\x39\xbf\xf6\x98\x24\x49\x54\xdf\x55\xdb\x7d\x33\x65\xf5\x5a\xfc\xe7\x2c\xf2\xcc\x64\xa0\x6f\xce\x97\x81\x5a\xca\xf8\xb3\x34\x08\x28\x12\x74\xad\xda\x9f\xa8\x9a\xec\x8a\x60\x43\x68\x10\x6b\xcb\x7c\x43\xf9\x90\x83\xa8\xe1\x51\x7c\x66\xc7\xf3\x51\x0d\xed\xfb\xfc\x60\x62\xfd\xe7\x75\xf9\x86\x32\xf4\xee\xcf\x61\xc8\x51\x29\x6c\x53\xe9\x81\x4c\x08\xa1\x21\x28\x8c\xbb\xeb\x0f\x87\xf7\x42\xf8\xcc\x5d\x59\x2d\x9d\x14\xf7\x17\xbf\x7d\x0a\x50\x1d\xbf\x65\xa3\x7b\x4a\xa3\xd4\xda\x8a\xd7\xd0\x2c\xd6\x2f\xb7\x2f\x9b\xe7\x76\x3b\x99\x96\x6f\x69\xcc\x62\x57\x93\xc0\x05\xea\x65\x31\x5e\x2d\x68\xcc\x6c\xa7\xca\x2d\xeb\x2f\x88\x28\xf1\xbf\x23\x4e\x93\xc4\x96\x25\x6d\x49\x77\xea\xa6\xd3\x0d\x53\xcc\x71\xf2\x10\x2b\xf0\x56\x09\x7d\xc6\x7a\xe3\xaf\x83\xff\x7e\x4a\xfd\xfa\xff\x8e\x8d\xbe\x09\x25\x21\xc5\xb2\x9e\x39\x37\x67\xab\x75\x3d\x25\x84\x13\x4a\x62\x6b\x6b\x52\x43\xd3\xc9\xa7\x0f\xfa\x9b\xe3\x1f\x40\x12\x42\xe2\x31\xfe\x71\xb8\x28\xfc\x63\x3a\xda\x58\xa8\x63\xa9\xce\xed\x69\x57\x9f\x28\x62\x3e\x08\x62\x29\xe1\x16\xd2\xe4\xbb\x5b\x59\x2f\x66\x33\x3e\x17\x65\x26\xd2\x36\xe2\x3f\x57\x59\x73\xb9\x6e\x54\x0f\xcd\x5c\x07\xdb\x01\xa5\x3a\x62\x6a\x24\x94\xfb\x04\xa0\x87\x94\x1e\x42\xa9\x51\x36\x39\xff\xc4\x15\x72\xf3\x13\xaa\x3a\x7b\x3b\x34\x9d\x73\x1f\x36\xde\x87\xb8\x70\x42\x59\x10\x23\xea\xc2\x19\xd4\xf4\x1a\x58\x84\x32\x92\x22\x57\xc6\x0b\xf2\x6f\x72\x3d\x82\x78\xb6\x23\x04\x11\xdd\xac\x75\x5f\x83\x70\x2e\x2f\x31\x47\x28\xe3\x0a\x01\x87\x30\xf8\x8f\x3f\x96\xa4\x56\x0f\x74\x7b\xca\x33\x9f\xee\x3e\x8e\x96\xe7\x69\xf8\x4c\x13\x08\xc1\x85\xcf\xd5\xd5\x83\x4d\x55\x82\x52\x3c\x1f\x3e\x43\xaa\xe7\x6a\x51\x54\x10\x23\x9d\x7e\x97\xcb\x5e\xbe\xe8\xd9\x12\x2a\x78\x6c\x75\x96\xd7\xbe\x44\x46\x85\x60\x41\xcf\x0b\xbf\x2b\x2b\x4c\x55\xbb\xdf\x2b\xa4\x95\xae\xd9\x81\x3a\x14\x65\x5e\xbe\x5d\xe8\xfd\x64\x12\xca\x50\xe3\x8a\x5c\x9e\x60\x68\xfe\xe3\xcf\x20\x13\xfb\x48\x6a\x0b\x92\x94\x50\xd5\xfb\xdd\x66\xff\x6d\xb1\x5b\x7e\xdb\x87\xcb\x4a\x64\x6f\xf7\x95\xe8\x1f\xbb\x4c\xc3\x78\x28\xa5\xd8\x06\x24\xff\x1d\x9c\x4e\x05\x48\x59\xd1\x65\x9e\xab\xc1\xaa\x25\x21\x05\xd7\x6b\x1c\xa0\x35\x08\x95\x26\xc1\xad\xc6\x81\x63\x76\xbe\xbc\x40\x55\x98\x26\xae\x24\xe9\xd8\xd7\xe3\xd7\x4f\x45\x61\xa0\x7a\xff\x12\xa8\xd6\x9d\xfe\x82\x9e\xae\x0c\xe3\xbb\xac\x48\x22\xad\x2c\x5d\x33\x90\x8f\x1b\x39\x3b\x0f\xe7\x66\xea\x3f\x06\x09\xd8\x79\x6c\xb2\x3c\xdf\x7d\xde\x01\x3c\x5a\x82\x4a\x77\x49\x00\x1e\xf3\xf0\x5a\x54\x20\xf4\x23\xd4\xb5\x78\x83\x49\xc2\x40\x75\x40\x69\x30\xd2\xd0\x5b\x54\x95\xb8\xcc\xaf\x67\xfe\x33\xc4\x4a\xf2\xfa\x80\xe9\xa1\x7c\xcb\xd4\x57\xb5\xb5\xab\xf7\x58\x8b\x00\x71\x28\x4e\x15\x7a\xd4\x16\xa1\x5a\x0a\xcc\x5f\xbe\x72\xce\x9f\xec\x1f\xdd\x49\x41\x02\xef\x84\x3d\xbe\x97\x9d\x4f\xbb\x3f\x6c\x08\xa2\xf9\x64\x29\x6d\x5d\xc5\x4d\xb9\xaf\xc4\xb0\xc7\x04\x6a\x67\x74\x4f\xa8\x51\x49\x68\x86\xf2\x55\xcb\x8b\x9a\x86\x93\xed\xb2\x82\x6d\x15\x4b\xde\x73\xdb\xcd\x44\x90\xc5\x0d\x0d\x49\x80\x15\xbc\x47\xc8\xcb\x31\xea\xe7\x97\x92\x19\x84\x85\x8c\x60\x69\xfe\x43\x64\x58\x3a\x29\xab\xa1\x36\x2c\x61\x11\x53\x08\xf6\xce\xb3\xf7\x2f\xaa\x82\x2c\x52\x69\xda\xd7\xe6\x2d\xa7\xf9\xe6\x82\xe1\xc6\x17\x9f\x88\x25\x43\x80\xf8\xaa\x29\xad\xcf\xff\x6e\x28\xfb\xfa\x65\x9d\x92\xc5\x46\xa0\xa6\xd2\xc2\x39\xa3\x5e\x27\x0b\x8c\x68\x85\x25\x93\x73\x0d\xd5\x37\x51\x3f\x9c\xd5\xfb\x05\x1b\xbf\x93\x71\x34\x24\xcc\x05\x64\xab\xe6\xb0\x83\x3c\xff\xf2\x6a\x69\x64\xc5\xc7\xf7\x59\xfd\x04\xd9\xdb\x41\x96\xd5\x20\xb4\x4d\xfd\xa8\x38\xc1\xb4\xe6\xf7\x81\xc1\x0f\x61\x54\xd9\xaf\x19\xde\x3e\x77\x88\x85\x89\x64\xfd\x0e\xfa\xe8\x9a\x57\x16\x28\xd5\x2f\xde\x93\x0f\x45\x1c\xe1\xaf\xcb\x87\x9b\xe1\x7a\xc7\x58\x9c\x82\xd3\x8e\xfe\x5b\x46\x97\x84\x31\x4e\x20\x75\x38\x87\x6d\x23\xde\xed\x96\xfb\xba\x5d\x42\x07\xd4\x22\x2c\xa1\x21\xae\x0e\xf0\x79\x1a\x95\x9a\x59\x62\x12\xf0\x2c\xab\xaf\x77\x1a\x96\x46\x26\x08\x3a\x49\x6b\x44\xfc\x59\x53\xad\xf1\xb5\xa4\xb1\xc0\x55\xd1\x56\x6a\x66\xd5\xab\x08\x4b\x89\xc6\x37\x71\xf1\xe7\xd3\x6a\x37\xfa\xf1\x29\x4b\x53\xf0\x95\xbd\x46\xe4\x63\xa6\xa9\x1f\x94\x84\x56\x68\xa2\xfc\x09\x58\x0f\x78\xe8\x5a\x7b\x2c\x55\x12\x75\x48\xee\x5e\x77\x8f\xdd\xdf\xb4\xc2\x28\xb0\x7d\x35\xdb\x2f\x3b\x8a\xf7\x8e\x82\x44\x18\x0f\x04\x2a\x26\x9c\xca\x93\xf7\xe9\xf4\x47\xc2\x14\x75\x27\x6c\x1c\xf3\x02\x35\x54\x3f\xc1\x8a\xd9\x0f\x5f\x17\x1e\x03\x77\x31\x83\xe3\xef\x0c\x5a\x50\x8c\xa7\x00\x89\x8f\xb4\x29\x86\xda\x51\x10\x05\xfe\xb0\xa0\x56\xba\x05\x2d\x13\x8f\x17\x8b\x37\x9f\x24\x24\x4c\x45\x0a\x93\x5f\x79\x69\x44\x55\x45\xce\x7e\x27\x4a\xbb\x87\xa3\x43\xfb\x2e\x15\xe2\x54\xe6\x50\x16\x7f\x62\x02\x6e\x91\x51\x1e\xbe\x48\x98\x66\x0a\xab\x15\x4a\x14\x4b\x47\xef\x42\x39\x8d\xcb\x84\x4c\xe1\x87\x8b\x10\xb7\xa1\x47\xc8\x7e\xcf\xce\x7f\x4f\xc9\x8a\x30\xad\x6c\x7d\x21\x2b\xb2\x66\x5c\xcb\xfb\x82\x93\x49\x98\x06\x61\xf9\xa8\x79\xa9\xde\xb1\xd1\xf1\x2c\x7c\x61\x88\x99\x28\xe8\xf4\xae\xdd\x74\xf8\x26\xea\x2b\x1c\xf5\xdf\x92\x15\x22\xcc\x70\xc0\xbc\x01\x10\x66\xbc\x2c\x35\xac\x3e\x7b\xc6\x16\x61\x46\x82\x75\x27\x3a\x57\xc5\xb6\x3c\xc2\x80\x2c\x42\x98\x01\x89\x8b\x78\x59\xbd\x5d\x42\x33\xc3\xcc\x24\x49\xc0\x00\x53\x5b\xbc\x5b\x6d\xce\xbb\xbc\x36\x6f\x22\x49\xa0\xb5\xe9\x74\x0b\xff\xc8\x9a\x26\x83\x1a\x41\x1f\x1e\x47\x90\x84\xa1\xd5\x1b\xa8\x7b\x65\x5a\x7f\x44\x58\x85\x9b\xd3\xb9\x59\x17\x4d\xf9\x2c\xd4\xfb\x20\xa4\x9f\x85\x21\x92\x24\xd4\x49\x12\x38\xfd\xd6\xdd\x01\xee\xc4\x3b\xd4\xcf\x55\x79\xf4\xc1\x4c\x12\xb9\xac\xf8\x20\x0a\x9d\xc3\xb7\xdd\xc3\xd2\x4a\xa4\xef\x3e\xaf\x4a\xf8\xa3\xa9\x9c\x44\x71\x8a\xdd\xf6\x76\x6e\x3d\x8a\x2e\x90\x4e\x22\x2a\x11\xc8\x68\xbb\xe1\xe3\x02\x61\x42\x28\x4f\x82\xa1\x46\xe0\x7c\x06\xe8\x47\x27\x36\x0f\x13\xed\x52\xd0\xa6\x91\x50\x35\x99\xc9\x5c\xc6\x33\x4e\xaa\x06\xfe\x11\xd3\x74\x72\x7c\x4e\xc3\xbd\x8d\xf6\x73\x05\x99\x2a\xa7\x15\xb0\xf1\x03\xa3\x91\xa5\x80\xdd\x66\x6f\x59\x73\x1e\x2a\x91\xb6\xc7\xa2\xa8\x33\xa8\x40\x47\x84\xee\x59\xb1\x30\x4e\xa4\x93\xa2\x7d\x3d\x75\x7f\x15\x86\xaa\x4e\xab\x6e\xd1\xb8\x4a\xb9\x13\xaa\x1b\x45\x76\xd3\x9b\x3e\xfe\xd7\x9f\x4f\x49\xac\xf6\xed\x07\xb2\x2c\xf3\x3f\x23\x89\x04\x38\x14\x03\x0a\x0d\x5c\x9b\x27\x92\x24\xe1\x3a\x71\x40\x25\xec\xe3\xec\xcf\x57\xfd\xa1\x24\x4d\xe3\xd4\x4a\x57\xb7\x7b\x81\xf7\xa1\xfd\x3b\x50\xae\x81\x44\xf5\xe4\x94\xd2\x6a\xed\x23\xee\xa4\x34\xcb\xb2\xc0\xf7\xc6\x1d\x15\x21\xc7\x7b\x8c\x75\xf3\x23\x56\xca\xba\xa9\x22\x98\xe0\xce\xbe\x47\x9e\xab\xda\xe7\xba\x9d\x50\x24\x49\xa4\x8a\x91\x3f\xb8\x3d\x88\xe2\xdb\x79\x50\xaa\x48\x54\xa0\x10\xec\x74\x0f\xa8\xdd\x84\x08\xcf\xf1\x75\x29\xca\x11\xef\x02\xea\x27\xda\xd3\xfe\x36\xf7\x04\x94\x20\xb8\xe6\x3d\x94\x6f\x4f\xf0\xb1\x28\xea\x8f\x81\x38\xd1\xf4\xdf\xaf\x6e\x53\x9f\xdd\x26\x4a\x86\xb8\x3f\x22\x80\x7d\x76\xe1\x9d\xcb\x1b\x12\x9d\x06\xa9\x75\x5c\x71\x39\xf1\x75\x6b\x2f\xd1\x3c\xc4\x1c\xd5\x80\x3a\xb4\x21\xf1\xba\x30\xe5\x5d\x59\xb5\xff\xd3\xaf\x73\x89\x16\xd4\xd6\xa8\xcb\xa2\x3e\x1f\x3d\xf3\xf6\x57\x29\x4b\xa2\x85\x02\xea\x57\xb4\x07\x54\x35\x1b\x97\xca\x13\x0d\x22\x74\x0a\x19\x53\x4e\xb3\x1b\x01\xa1\x0a\xbc\x41\x4b\x5d\x43\xd3\x39\x07\x93\x04\x12\xc0\x98\x58\xd4\xef\x93\xa5\x14\x99\x33\xf8\x9b\xd7\xcb\x8d\xb1\x22\x34\xfd\xbb\x61\x02\x8d\x2d\xc5\x36\xba\xdc\x9f\x2c\xcc\xb6\x3b\xa9\x09\x53\x54\xcb\xb0\xcd\xdc\x5d\x59\xa9\xc3\x68\x62\x1b\x23\x99\x53\x6a\xd8\x96\xa6\xd9\x2f\x27\xee\xf6\x24\x0d\xa4\x60\xd6\x38\x02\xa7\xd3\x16\x4d\xb6\xb0\x49\x5d\xdc\x97\x7d\x88\x91\x86\xa9\xa0\xbd\x4c\x61\xe1\xc2\xc4\xf1\xc2\x9e\x86\x29\x90\x81\xc4\xd4\xf0\x0d\x4e\x43\x95\xe2\x84\x5b\x2c\xef\x46\xc5\xc8\x34\x04\x69\x5c\xa6\x86\xfe\xcd\xd6\x76\x6e\x55\x34\xd5\x24\x68\x4a\xa3\x88\x62\x83\x05\xe3\x90\x36\x4a\xcc\x8a\xb7\x45\x33\x1d\x94\xc6\x48\xb7\x94\xe7\x8b\xdd\xf9\xc6\x87\x63\x12\x7a\x1a\xce\xab\xa3\x7d\x0e\xec\x4a\xdc\xa0\x36\xf3\x45\xe8\xc2\x09\x2a\x9f\x79\xa6\x84\xcb\xd8\x9a\xbe\xe6\x93\x4a\x7a\x4a\x23\x89\x52\x15\x7e\x33\x98\x58\x02\xb9\x51\x2c\x88\xe3\xde\xf4\x64\x7a\x30\x4e\x93\x0e\xa6\x02\x85\x82\x5f\xe8\x57\xfa\x8f\xa4\x8c\x3b\xc2\x22\x4a\xad\x6a\xf1\xab\x16\x48\x9a\xb0\x08\x1f\xce\x4a\xb4\xbb\xf4\xfd\xd3\x76\x7e\x85\x4d\x13\x65\xb9\xd1\x3d\x2c\xe7\xf5\xe9\xfb\xea\x65\x7d\xb7\x5e\xdd\x22\xc0\x68\x80\xd0\x49\x13\x48\x71\x7b\xf0\x08\x45\xab\x9f\xd1\x67\xa8\x69\x02\x92\xa6\xfd\xd3\xad\x7e\x1b\x65\x9e\x69\x62\x34\xa6\x1d\xa7\x9e\xa1\x15\x6e\xc1\xef\x01\xc3\x62\x44\x9a\x86\x29\x8a\x7f\x2b\xd1\xfd\x89\x2b\xdb\xb1\x3c\x88\xbc\xe9\x51\x13\x29\xd7\x14\x4b\x87\x8f\x8b\x3f\x9d\xa2\xcf\xf6\xf5\xf9\xf9\xe1\x5f\xdd\x71\xa3\x50\xb0\xe6\x49\xc3\xe7\x50\x79\x9f\xa4\x22\xb4\x6a\x9b\xa2\xae\xa1\x6a\x3a\xbe\xad\x86\xcf\x75\xf1\x72\x1d\x05\xa5\x82\x88\xc8\x72\x8b\x2f\xff\x16\xbd\xb9\x0a\x49\x55\xc0\x0d\x74\xbd\xf2\x06\xc6\xe2\x0d\x24\x55\xb1\x75\xab\x6e\xc3\xc5\x35\x6a\x1e\x77\x47\x0c\x43\x28\x12\x0a\xa7\xe4\xa2\xae\xbf\x67\xf0\x81\xe5\xe7\x68\xf2\xe5\x3a\x0d\x91\x51\x72\x74\x0e\x58\x1f\xa3\x69\xa5\x25\x45\x6c\x34\xee\x46\xed\xda\x38\x79\xe1\x20\xd0\x08\x1e\x43\x88\xe9\x0b\x34\x55\x06\x0e\xdd\x78\x0b\x8d\xc8\xf2\xee\x82\x80\x59\x16\x64\x95\xbd\x1d\x1a\x4a\xc6\x17\xc1\x83\x30\x46\x32\xee\xbf\xb3\xb7\xf2\xdc\x9c\xb3\xc3\x59\xcc\xeb\x7d\x13\x1e\x28\x1a\xba\xad\x7b\x85\xde\xb5\xb6\x67\x3d\x9a\x7a\x3c\x64\x29\x36\xfb\x3f\x0e\x99\x3a\xa0\x02\xd2\xe4\x0b\xc3\xc4\x20\x9e\x0d\xeb\xd9\xbe\x42\xf9\x75\xc3\x94\x87\x3c\x66\xc6\xf3\xee\xea\xd3\xb9\x81\xdd\x9f\x93\x53\x46\x69\xa0\x2c\x9f\xb6\xac\xbf\x28\x2b\xf0\x28\xb5\xf5\x24\x2d\x2e\x39\xe6\x8c\xfe\xef\x5c\x60\x17\xe2\x6e\xb9\x1c\xdf\x60\x1e\x47\x02\xeb\x41\xeb\xa7\xa5\x1f\x1c\x83\xc1\xba\xf7\x3f\xfd\x1f\x48\xc4\x91\x20\xb2\x45\x25\x9d\x87\x72\xb2\x98\x71\x1a\x69\x3d\x5c\x58\xda\xdd\x7d\x5e\x86\x92\x70\x6a\x82\xd4\xdb\x07\x95\xe7\x1a\xb7\xc5\xc9\xcd\xa5\x46\x20\x62\x4a\xda\x82\xee\xb3\xb8\x74\xfb\x0c\x67\xc6\x4e\x9a\xce\xd9\x1e\x41\x27\xd3\x4d\x1b\xcf\xf7\xbf\xf1\xff\x4d\xee\x4e\x1a\x03\x4a\x48\x7e\x5b\x6d\x26\xdd\x3c\x9e\xf2\x28\x72\xf7\x7f\xe0\x94\xea\x0f\x4a\x9e\x76\xf0\x0d\x0d\x70\x74\xe9\xeb\x4c\x5a\xce\x53\x63\xf1\xc2\xb6\x16\x6a\x61\x0d\x5d\x60\x3f\xd5\xca\x27\x9c\x53\xbb\x59\x3f\x57\xa5\xdb\xa5\xfa\xe6\x21\xe7\x89\x76\x16\xdc\xc7\xf2\x27\xdc\xe4\x42\xbd\x5f\x49\x46\x11\xce\x53\x8b\xb0\x96\xed\x2c\xfd\x26\xf2\x9f\x03\x0a\xb1\x1f\x62\xa8\x85\x3d\x74\xd6\x0a\xfb\x6a\x04\x30\x9c\x5c\x95\x24\x8a\x75\x94\xba\xc7\x52\x63\x92\x7b\x2d\x6f\x47\xb8\x64\x01\x76\x07\x90\xe3\xed\xe4\x11\xea\xc9\xe3\x54\x9c\x46\xdc\x61\xad\x1d\xbf\x73\x5a\x9c\x64\xff\x37\x8c\xf2\xb8\x52\x4c\x70\x8f\x51\xec\xe2\x9b\x1a\xad\x52\xbb\xa5\x83\x6b\x05\x16\x20\xe1\x8c\xc9\xfc\x52\xc0\x0d\x03\xac\x84\x83\xb6\x4a\x14\x43\x95\xaa\x61\x6e\xc2\x8d\x16\xc2\xf9\x0d\x62\x5d\x72\xe4\x5d\x3e\x5f\x02\x12\x41\x60\x39\x47\xb6\x3a\xb3\x6a\x0e\xd6\x40\xd9\x1f\xa5\x0a\x4b\x94\xfb\x22\x93\x32\x87\x7a\x57\xee\x2a\xf1\x13\xaa\x1a\xbe\xd4\xc5\x26\x22\x50\x21\x82\x25\xfe\xb9\xdc\x8e\x6a\x34\x22\xd0\x31\xe6\x1b\xd0\x1c\x76\xe5\x0d\xe0\x35\x76\x53\x41\x84\xb1\xf1\x4c\xdc\xf5\x72\x33\xac\x2c\xa4\x7e\x84\x4e\xad\x38\xaf\xa5\xd8\xef\x9b\x2f\x6d\x0e\x88\x88\x12\x0b\xab\x45\xa3\x74\xff\x15\x91\x48\x3b\x9b\xe1\xf6\x55\x58\xe6\x19\x14\xcd\x78\xe5\x15\x91\x50\x2c\xf2\xa2\x60\xc7\x93\x50\xcd\x75\x74\x2f\x22\x65\x05\x5a\xf2\x52\xe8\x11\xfb\x4c\xc4\x41\x18\xb2\x91\x68\xf2\xfc\x4b\x29\xe2\x20\xc2\xba\xd8\xcd\xcb\xf7\xf9\x20\xdd\x8f\xa3\xd6\xb0\xf9\x0d\x33\x4e\x93\x7d\x0e\xe5\x6e\x88\x88\x99\x48\x92\xce\x4d\x43\x77\x42\x39\xed\x1d\x7e\x16\x99\xde\x74\x75\x5c\x41\x42\x95\xf4\x64\xf3\xbb\x2a\x83\x42\xd7\x48\x7b\x85\x6e\x08\xb3\xae\x24\x87\xf2\xe3\x51\x14\x36\x96\xab\xdb\x53\xb5\x9f\x18\xe2\x80\x05\x4b\x23\xc4\x39\x78\xec\xd0\xe8\x49\x33\xb0\x05\xb0\x36\x65\xda\x36\x65\x25\xde\xba\x6f\x48\x22\x69\xdd\x44\xfe\xe7\x73\x56\x4c\x9f\x88\x24\xd1\x11\xf7\x3d\x48\xbc\x89\xdf\x45\x95\xc9\x41\x75\xeb\x4b\x25\x81\xd9\x18\x4c\x24\x26\x46\x51\xa9\x27\xf8\xd8\x5e\x8e\xb2\xcc\x87\x6a\x70\xfe\xe5\x4a\x35\x20\x0a\xff\x3f\x67\xd1\x40\x15\xfa\x8b\xe1\x32\x4a\x9d\x44\x93\x93\x33\xb8\x3d\x3b\xd6\xe0\xfc\x97\x89\x20\x41\x64\xe3\xe2\x08\x55\xa6\x4a\x07\x39\x1b\xdc\x1b\x11\x11\xc4\x48\x6e\xcb\x73\x73\x58\x98\x2a\x53\xa2\x8d\x72\x74\x3d\x1e\x45\x63\x74\xc1\x7f\x43\xe2\xea\x68\x05\x12\x82\xd9\x30\xe6\xf1\xdb\xf2\x66\xd9\x7d\x20\xb5\xdc\xba\x36\xfc\xfa\xb1\x5a\xf7\x7f\xb6\x88\x47\x84\x12\x0b\xad\x17\x85\xbe\x6f\x7f\xca\xb0\xff\x28\x44\xaa\x71\x81\xc2\x7e\x07\x9a\xef\x9c\x9a\x81\xee\xd0\x98\x70\x31\x5c\xda\x84\x14\x56\xfa\xd7\x4a\x93\x5e\xa1\x74\x47\x0a\x73\x83\x85\x56\x48\x13\x20\xfb\xf7\xb5\xb0\x1b\xcb\x2c\x11\x45\xa8\x38\x42\x55\xb3\xce\xc7\xef\x9f\xbb\xf1\x4e\x20\x14\x28\x0c\x5c\xda\x88\x39\xd8\xaf\x9e\x6e\xfd\x4f\xd2\x5c\xa0\xfb\x4e\x23\xde\xe1\x57\xa5\x0d\xa1\x05\x37\xae\xa0\x73\x07\x70\x57\x56\x48\x5d\x58\x54\xcd\x8f\xb2\x7a\xf7\xd5\x4e\x5b\xdd\x9d\x7c\x50\xc5\x48\x24\x79\xbd\xd9\x76\x5f\xaa\x08\x26\x55\xb8\xcf\xf8\xa2\xe3\x0f\xc8\x76\x87\xac\xd2\x2e\xff\x1a\x9f\x04\x22\x70\x6d\x63\x21\x73\x70\x52\x06\xd3\x31\x89\xf6\x33\xbc\xb3\x91\x1d\xad\x10\x26\xe2\x46\xd9\x92\x99\xf3\x26\xeb\xe2\x77\x61\xa8\x89\x5d\x9e\xf7\x98\x15\x8f\xe2\xb3\xdf\x71\x84\x49\x63\xf4\x49\x32\xe7\x42\xed\x83\x68\xe5\x11\xaa\x32\x10\x3c\xf1\xbe\x15\x7b\x5d\x9e\x65\x0e\xdf\xd1\xdb\x7f\xf1\x26\xb2\xa2\xab\x73\xcb\x90\x90\xb8\x1d\xf7\xc7\xfa\x8f\xfd\xe2\xf6\xf6\x65\xb5\xdd\x76\x87\xb8\xad\x6d\x5b\x68\xdb\x0b\x16\xf5\xbb\xb5\x5e\x86\xc0\xf1\x27\x1d\x84\xd6\x5e\x19\xf0\x1f\xe7\x81\x42\x20\x91\xa1\xe1\xb1\x4d\x91\x51\xcf\xbe\x23\x81\xce\x2e\xa6\x32\x34\x40\x89\x4f\x94\xef\x3b\x22\xa8\x8c\x82\x18\x6c\xa8\x83\x0a\x2a\xee\xaf\x31\x89\xd0\x7b\x00\x59\xbd\xa4\x73\x21\xee\x0e\x2b\x8a\x1d\x49\xe5\x15\x38\xdb\x85\x2a\x2b\xce\xdd\x00\x12\x11\xfc\x71\x0b\x53\xdd\x49\x91\x23\x52\xf1\xcf\xe1\xf4\x95\x34\x88\xd1\x42\xa7\xb3\x06\xbe\xb9\xdc\x40\x63\x5f\xa7\x09\x0d\x42\xd2\xc0\x9a\x09\xbf\x41\x33\x83\x75\x90\x34\x00\xf0\x2e\xc2\x22\xab\x07\x7d\x84\xc1\x18\x12\xe2\x34\x70\x76\x07\xb7\xf0\xf3\x0e\xba\x6a\xa2\xa4\x94\xc6\xca\xb6\xcc\xb0\x76\x3b\xd5\x28\x22\x92\x26\x2c\x12\x03\x0b\xcf\x3b\x80\xbf\x56\x41\x9f\x2d\x34\xfa\x13\x6a\x0d\xd2\x03\xb2\xec\x06\xb1\x68\xd6\xb7\xc3\xed\x5c\x52\xa0\x48\x5e\x5c\x3e\xff\x58\x8c\x6e\x1e\x23\x76\x39\x6a\x73\x7e\xb4\x40\x9d\xac\x0b\x92\x09\xcb\xf9\xc5\x88\x3a\xc2\xe7\xd7\x23\xe4\x24\x33\x09\x1f\x1a\xcb\xdd\x8a\xac\x3f\x24\xbd\xbe\x9f\xa3\x5b\x62\x3f\x0a\xaa\x81\x35\x17\x91\x49\x2c\x10\x4d\x66\x9c\xbb\x94\x9d\xb9\x71\x77\x98\x58\xb4\x45\x1b\x7d\x8a\x42\xfd\xda\x51\x83\xc8\x44\x86\xa8\xaa\xf8\x2c\x2e\x55\x99\x5f\xb9\x80\xf8\x51\x46\x26\x5e\x5e\xc9\x6f\xe1\xa3\x2c\x59\xa6\x20\x51\x1f\xea\x54\x7e\x40\x35\x00\x20\x48\x1e\x80\x76\x5c\xb9\x36\xa2\xea\x64\x68\xc6\x5f\x20\x62\x8e\x99\xa7\x33\xe0\x7c\x01\x55\x4e\x09\x39\x52\x26\xa1\x4d\xc4\xf5\xbf\xcf\x75\xb3\x2e\x4c\x8e\x3b\xdd\x00\x82\x27\xa5\x24\xf6\xd7\x6c\xba\xcc\x5e\xaa\xc0\xca\x27\xdd\x95\xe5\x63\x56\x34\x9d\xc2\xb6\x3f\xae\x19\xe3\xb4\x6b\x0e\xcf\xba\x78\xcc\xae\xcd\x52\x73\xb0\xe2\xc9\x22\x57\xeb\xe9\xc5\x6a\x61\x15\x4b\xe4\xf9\xe2\x78\x0d\x93\x5b\x0a\x34\xec\xfd\x0a\x96\x87\x2c\xef\xe6\x3f\x24\x29\xbe\xee\xf6\x82\xb6\xa0\x10\x44\xf4\x57\xde\x25\x57\x57\x39\x5b\x91\x1d\x83\x1d\xfd\xbb\x6e\x28\xf3\x73\xfc\x59\xd4\xa8\xd3\x3d\xae\x4d\x48\xc3\x42\xde\xe3\xd9\xef\xab\xf2\x7c\x1a\x52\xb9\xff\x2e\x59\xff\xd7\x2c\x4d\x69\x0c\x45\xf4\xe8\xfe\x64\x2b\xc4\x7e\x43\x41\xfe\x05\xfe\xcf\xdf\x86\x7b\xfd\x14\x5d\xdc\x3e\x69\xe9\x0a\xd6\x5b\x68\x46\xd1\x94\x1f\x41\x45\xd2\x09\x5e\xaf\x8a\xb7\xac\x00\xa8\xfe\x89\xfb\xe7\xf8\x54\x21\x11\x08\xb7\x19\x74\x8a\xa6\xf7\x73\x74\xe2\x90\x13\xc4\x0b\x59\xe4\xa1\xf5\xa6\x9d\xfd\x91\x2a\x0a\x15\x36\xeb\x91\x90\xb3\x2d\x4d\xd3\x69\x5b\x13\x15\xa5\x31\x9e\x45\x9e\x2f\xcf\x65\xd5\x98\x32\xcf\xca\xaf\x1a\x10\xfe\x23\x5a\x7a\x73\xda\x67\x47\x7a\xbb\xcb\x72\x18\x22\xd7\x14\x49\x13\x5c\x32\x6e\xa0\xa9\x33\x25\x7d\x51\x4c\xd1\xd8\x22\x42\xbd\x1e\x6f\x56\x16\xcb\xf3\x88\xd2\xec\x07\x1a\xe3\x68\xbe\xc5\x59\xe4\x8f\x83\x96\xfa\xe4\x6a\x58\x60\x65\xdd\x5f\x16\x4f\xf7\x2b\x94\x75\xda\xa7\xfe\xdb\xd2\x28\x4d\xc3\xee\x1d\xb2\xf9\xd1\x1c\xf3\x4e\xf1\x28\xc1\x9d\xff\x6e\xe1\xad\xb1\x89\x92\x71\x20\x9c\x9c\xc0\xf2\x20\xda\xb8\xfc\x2b\x34\x84\x52\x61\xc8\x2c\x7d\xd2\x52\x64\xef\x45\x3d\x53\x3b\x50\x2a\x4c\x2d\x36\x07\xf5\x51\xf1\x37\xf9\x23\x3c\x45\x7b\x24\x8f\xc5\x1e\x15\xad\x95\x4e\x34\x6a\x5a\x6d\xfe\xdc\x6f\x5e\xee\xbb\xbf\x1a\x0b\x21\xf3\x6c\xc1\xab\x99\xf1\x37\xa8\x42\x0a\x22\x8a\x58\x3c\xab\xe7\xd1\x1c\xac\x82\x8b\xff\x0a\x60\x0a\x9b\xbc\x1a\x40\xff\x36\xf9\xa0\xb2\xca\xbd\xca\xec\xab\x71\x38\x38\xb9\x37\x26\x49\x70\x86\xdc\x97\xa5\xbe\x29\x2f\xd8\x89\xa9\x7f\x95\xe0\x29\xa3\xa4\x71\xc2\x7f\xd8\xc3\x7e\x82\xcf\xe9\x5c\x31\xc0\x71\x3b\x55\xed\x4e\x54\xf5\xb0\xcd\xf1\x7d\x33\x86\x61\x31\xe9\x54\x95\x0a\xea\x7a\x7f\x84\xea\x0d\xb0\xb9\xb7\x6f\x5f\xda\xf1\x39\x75\x60\x88\xef\xab\x2c\xce\xcd\xa1\xac\x46\xf8\xb2\xeb\xe2\x88\x0e\x63\x86\x01\xef\x49\x9c\x6b\x18\x89\x77\x78\x89\x00\x1d\xca\x08\x9f\x91\xb0\x57\x38\x06\xe4\xe9\xc8\xd8\x1e\x7a\x86\x90\x34\x40\x39\xd7\xd9\xdd\x50\x93\x38\x86\x6e\xae\xdf\x82\xc8\xef\x4a\xab\x6c\x3e\xed\x85\xfd\x75\x4f\x4c\xd3\x98\x60\x9d\xd1\x00\x8c\x6a\xb5\x9a\x0a\x4a\x7b\xa1\x2c\xb4\xd1\x31\x1d\x56\x77\x84\xb5\x9e\x2b\xc7\xb9\x93\xb0\x80\x2b\x07\xe2\x75\x69\xc2\x34\xb8\xd2\x09\x31\xd8\x83\xbc\x59\xde\xa8\x81\xfe\x22\xd1\x09\x55\xdc\x3d\x01\x97\x5b\xce\xa6\x41\x3a\x61\x1a\xc3\xec\xc5\xee\x69\x3c\xc3\x74\x22\x62\x4d\x3a\x41\x15\x5b\xce\xf0\x6f\xb3\x4e\x35\x08\xed\xdf\xab\x76\xf7\x9b\x5b\x56\x35\x0f\xe3\xc4\x36\x58\x9a\x1c\x7e\xc2\x24\x6c\xd0\x5c\x47\x61\x64\x2d\xce\xbf\x3f\xdb\xc7\xd6\xd5\x00\x34\xd7\xc0\x7d\xc9\xc6\xef\x55\xa9\x3f\x06\x61\x6c\x9b\x64\x2e\x88\x1e\xbd\x0a\x22\x4e\x31\xd2\xf8\xb3\x5d\x1b\x9a\x0b\xb6\xed\xfc\x31\x19\x45\xb1\x63\x44\xce\x12\xbc\xc7\x17\x28\x23\x65\x23\xcd\x73\x73\x18\xed\x44\x5a\x12\xcb\x73\xc7\x6d\x60\x95\x67\x6f\x99\xcc\xf2\xf6\x95\xfd\x45\x7f\x5f\x4b\x16\x60\xf5\xe7\x3e\xfb\x09\xcd\xe1\xa6\xca\x86\x4c\xd8\xaf\xde\xb6\xd9\x55\x52\x4b\x1e\xa2\x5e\x88\xca\x1a\xa1\x21\xbf\x39\xcf\xfb\xee\x12\x2d\x55\x8c\xed\x57\xdb\xff\x58\xfd\x27\x8c\xbc\x42\xc0\x3f\x46\x4a\x01\x5a\x9a\x24\xe4\x63\x95\xb9\x07\xd0\x6f\x57\x6f\x9c\x8a\x6c\x79\xbc\x19\x20\xa1\x26\x23\x62\x4b\x9b\x46\x1b\x2f\xb4\x6c\x09\x3b\xed\x75\xa2\x95\xb4\xbe\x85\xe5\xa9\x0b\x88\xdc\x11\x9d\x24\xf8\xc4\x9d\x69\xc4\x73\xbb\x14\xf8\xf5\x47\x83\x0c\x82\xc4\x6b\xa2\x7e\x5a\x7b\xa1\x37\x98\x76\xe4\x34\x28\x6b\x96\xe8\x3d\x47\x86\x74\x13\x54\x7a\x1f\x4c\x5e\xd0\xb6\x64\x75\x8b\x04\xb7\x49\x95\x5b\x9b\x88\xc6\x56\xff\xf5\x34\x6e\x1a\x43\x90\x50\xeb\xf2\xda\x29\xea\xb7\x2f\xe8\xcd\x65\x76\x82\x41\x20\x75\xd8\xb5\xcd\x9f\xdb\xf8\x7a\x30\x4d\x21\x50\x41\x1c\x38\x3d\xc9\x39\xa4\xe7\x35\xd8\x62\x3e\x1e\xec\x7f\x16\x84\x41\xac\x2d\x92\xe3\x63\x42\xa4\x1d\xbf\x43\x10\x0a\x81\x98\xbe\x1e\xe1\xb4\x3d\x94\xa7\xe1\xd5\x85\x52\x23\xad\xdf\x5b\xdb\x78\xf0\xf2\xe4\x27\x86\x26\xc2\xb6\xa5\x27\xfd\x6d\x1b\x38\x75\xa7\x30\x4c\x59\x4a\xd1\xf1\x24\x26\x6a\x9b\xed\xd1\x04\x8b\xa6\x3d\x48\x64\xca\x55\xfd\xc7\xf8\xad\xbe\xc6\x00\x42\xc4\x39\x6e\x71\xff\x85\xaa\xdc\x97\xe7\x49\xa0\x00\x91\x34\xd6\x1f\x56\x14\xce\x0e\x06\xa6\x23\x94\xa0\x83\xec\xa5\x5e\xad\x9f\xa3\x00\x33\x1d\x23\xbc\x69\x27\xf1\x63\x75\x84\x40\x6d\x1b\x05\x6d\xe7\x1c\x95\xdc\xc8\x98\x30\x6c\xc3\x2f\x86\x46\x67\xa4\x0d\xa4\x90\x92\x0d\x8f\xbb\xef\xfe\x6f\x34\x91\x4e\x2f\xcd\xa9\x8d\x5e\xab\xc9\x8d\xcf\xcd\x02\x8e\x8d\x93\x87\xf2\xed\xe6\x7c\xb1\x6c\xea\x5f\xc5\xb7\xc0\x58\xec\xbb\x04\xdb\x46\x34\x0f\x68\x5c\x99\x75\xc1\x09\x30\x0d\x61\xea\x85\x22\x4a\xd7\x08\x98\x7f\x9f\x93\x30\x46\x64\xe6\xed\x6e\xb9\xdc\xaf\x1f\x36\x3f\xf6\xcc\x9f\x25\x61\xca\x3b\xef\x58\xf8\xc2\xb6\x3c\xe7\xb3\x22\xcc\x04\x12\x1e\xc8\x21\x95\x6d\x7f\xbf\x5e\x4e\x9e\x4b\x1a\x28\x44\x51\x6c\x4f\x67\xbd\x2b\x5f\xca\x06\x43\xdb\xc9\x18\xca\xb1\xfc\xea\xc2\xd1\x36\xb9\x7d\xb6\xfc\x13\x7f\x51\x3c\xa5\xc2\x65\x47\x7f\x5c\xd4\x44\x8f\x04\xb8\x54\xca\x15\x27\x56\x53\xc9\x92\xf1\x05\x0b\x6a\xc3\xca\xae\x5e\x88\x9a\x5c\x36\x02\xde\x95\x58\x4a\xf0\x27\x15\x92\x30\xf7\x95\x3f\x44\x55\x89\xc2\x93\x48\x7e\xc1\x25\xba\x7e\xc8\x42\x69\xc4\xa3\xa9\x73\x05\x45\x63\x65\x21\xbc\xee\x24\x01\x01\x40\x9c\x4c\xbb\x95\x4b\x1b\x17\x41\x41\x8a\xc8\x16\xa7\x70\x85\x1e\x36\x38\x41\xc5\x56\x9a\xb9\x2c\xac\x7e\xc3\xf8\x77\x2a\x62\x79\x95\x0b\x1f\x1c\x83\x36\xd6\xd0\xc2\xb7\x2c\x2d\xfb\xfb\x78\xb5\xf8\x02\x04\x09\x56\x11\x5e\x9b\x7c\x1e\x22\xfe\x17\xff\xba\xd3\x98\x48\x81\xf1\xc4\xdf\xb9\x66\x14\x98\x18\xd0\x3b\x78\x0b\xcd\xea\xa7\xc8\xcf\x53\xef\x87\x11\x72\xda\x04\x51\x82\x8d\xde\x3c\xab\x9b\xfb\xbc\x94\x22\x47\x7d\x8e\x5b\xc7\x15\x42\x6e\xe8\x15\xbc\xbe\xbf\x95\x26\x60\x61\x10\x78\x8d\xa7\x2d\xa0\xdb\xee\xe8\x51\x99\x28\x30\xd2\x59\x6f\x34\x9e\xd4\x38\xbb\xe6\x9a\x88\x58\x50\x48\x3b\xc4\xfa\xa5\xf8\x03\x8c\xc5\xd8\xba\xc0\x19\x7a\x8d\x9d\xf4\xcb\x9d\x89\x93\x18\xeb\x8b\xa7\xec\x13\xf2\x7a\xd4\xaf\x31\xb1\x21\x5e\x26\xdf\x81\xad\x76\x97\x13\x6c\x8c\x0d\x81\xc6\x57\x42\x14\xc5\xaa\xa6\x9b\xe5\xb7\xd6\xab\xc0\x5f\x0e\x8b\x12\x44\x3b\xbc\xc3\x65\x84\xd9\x30\x8c\x27\x88\x1d\xb8\x59\x3f\x6f\x36\xdf\xf6\xb7\x8b\xcd\x3e\x8e\xfc\xc1\x44\x04\x89\x5b\x00\x62\x54\xa0\xba\x32\xdd\x22\x26\xd1\x96\xff\x90\xd5\x6b\x55\x2e\xcb\xe3\xa9\xdd\x7c\xfd\x09\x52\x62\xfb\xb3\x1a\xcc\xb0\x6a\x66\x52\x12\x1b\xab\x8d\x74\xaa\xa0\x0d\xfe\x77\xed\xcf\x6b\xb6\x67\xd9\x5c\x4e\x43\xb3\x45\x62\x52\xce\x30\xbc\x6f\x13\x95\x5c\x64\xc7\x45\x9e\xaf\x1d\x3d\xb7\x3b\x9b\xe4\x98\xa7\xef\x4f\x96\x8a\x30\x7a\xfd\x4c\xaa\x2c\xad\xff\x5f\xd0\x34\x02\x23\xcc\xc1\x72\x62\x38\x8d\x22\xef\xef\x2c\xea\xde\xc9\xc3\x1f\x17\x4e\x9b\xed\x20\xea\xc3\xbe\x9c\xc8\x82\x18\x21\x03\x66\x1c\xa7\xfe\xad\xcd\x61\xee\x3e\xf4\x18\xcb\xea\x07\x3a\x7a\xe6\xe2\xe1\x61\xb3\xdc\xaf\x96\x9b\xed\xbf\xb6\xbb\x95\x07\x8f\x1b\xc5\xa4\xb7\x84\x71\x4d\xea\xee\x88\x89\x7d\x83\x6b\xde\x00\x9f\x18\x48\xc1\xeb\x0c\x60\xcb\x38\x7b\xc3\xca\xad\xf5\xb0\x1d\x5f\xaf\x09\x0c\xee\x0b\x55\x89\x46\x36\x87\xec\xe4\xd4\x3a\x6f\x31\xa7\x18\xd2\xfb\x8c\x31\x56\xa5\xc2\xa6\x3c\x8f\xc2\x75\x9a\x77\xe5\x6d\x7f\x91\xc3\x0b\xa1\x41\x10\x58\x4a\xd1\x0e\xf5\xae\x44\x03\xab\xe3\x29\x2f\x2f\x30\x1f\x14\xfb\x88\xc8\x7f\x38\x8a\x89\x0b\x08\xb1\x3e\xf0\x28\x3e\x7b\x97\xcb\x99\x4d\xb0\xfd\x84\xb0\xca\xa2\x9e\xda\x31\xea\x0d\xd2\x20\x4a\xac\xff\x9c\x29\xab\xe6\x32\xd2\x6c\xc2\x63\x82\xb9\x2d\x7a\x91\xe7\xb6\xee\xfe\x2c\x2e\xab\x81\x78\xf6\xaf\x9a\xe1\x34\x88\xe3\x88\x39\x40\xbe\x95\x06\xeb\x1d\xe8\xbb\x11\x80\x91\xca\x51\x7c\xda\xdc\xe0\x1b\xb4\xa1\x78\x77\xd8\x24\x28\x0d\x5e\xc0\xc7\xa2\x6a\xb2\x5e\x39\x64\x26\xd7\xa0\x01\x89\xa2\x24\x74\xf1\x72\xa6\xde\x67\x70\xe1\x34\x20\x31\xc3\xba\xc3\x2a\x07\xd5\x54\x65\x91\x29\x2b\x36\x6a\xeb\xb7\x7f\x0f\x5b\x4f\x03\xd2\xde\x59\x87\x48\x74\xd5\x4e\x5b\xd4\x46\x6d\xd1\xe1\xfb\x44\x03\xe2\x0c\x96\x7c\x36\x12\x07\x6e\xe1\x0d\x5c\x7c\x1b\xb8\x81\x8c\x52\x94\xb7\x75\x6c\xcd\x9e\x70\x36\xbb\xae\xd2\x80\x49\x8e\x5b\xcf\xbf\xcb\x73\xde\x3d\xb4\x24\x94\xa9\x75\x4c\x74\x6c\xd3\xc1\x4a\x46\x83\x84\x1a\xa4\x93\xc3\x7f\x4f\xff\x1d\x84\x68\x34\x48\x34\xd3\xba\x33\xcc\x2a\x2c\x7a\x71\xf8\x32\x24\x90\x60\x0a\x24\x2b\x51\x68\x4f\xa9\x19\x56\x5c\x69\x90\x46\x01\x92\x48\x1b\xeb\xfd\xf2\x90\xc9\x4a\x54\x97\xd5\x4f\xe8\xbf\x9f\xa7\x80\x99\x19\xb4\x9b\x73\x21\xaa\x55\xd1\x64\x5a\xe8\x09\xcf\x82\x06\x5c\x72\x44\x1b\xd8\xa6\x7f\xd3\x33\x7e\xff\xda\x09\x9b\x06\x5c\x09\x0c\xbf\xf7\x36\x60\xc5\xdf\x39\x17\xd7\xd1\x40\xc4\x11\x86\x88\xcf\x55\x56\xb6\xcf\xf0\x9f\x67\x38\x77\xbf\x58\xc4\x12\x97\x8c\x09\x94\x68\x74\x05\x13\x3f\x6a\x1a\x08\x99\x60\x5c\xad\x5c\x04\x78\xed\x24\x4b\x03\x09\x06\x17\xdb\x9f\x96\x08\x57\x35\x93\x1f\xaf\x03\x82\x1b\xc2\xd6\x59\x63\x5e\xd7\xca\xc3\x6e\x68\xa4\x85\x7b\xe3\xb7\xe7\x53\x9b\x94\x39\xaf\xf8\xf1\xef\xd4\xa9\x48\xad\x1b\xa7\xf0\x95\xa9\xc7\xac\x68\xe6\x0b\x2c\x34\xd0\x0a\x70\x1e\x35\x50\x37\xce\xe5\x23\x87\xca\x37\x78\xa0\xa9\x31\xcd\xec\xd3\x43\x1a\x68\x1d\x59\x7b\x70\xf7\xb3\xf1\x9e\x4f\x25\xa4\xff\x31\xf9\x16\x4d\x10\x68\x9e\xd5\x77\x59\xad\xbc\xd1\x32\x0d\x20\x32\x48\xef\x42\x07\xa0\xc5\xed\xe6\xb9\x77\xcb\xa2\x81\x31\x29\x70\xc7\x72\xd8\x62\xe6\xe2\x42\x36\x1a\x06\xc4\x2a\x34\xad\x6b\x9b\xa0\x8e\x7f\x54\x18\x30\x01\xbc\xef\x7f\x3e\x95\x5a\xe4\x08\x89\xfa\xbd\x97\xbe\xf0\x43\x93\x18\x01\x66\x6d\xd8\x7b\x8b\x61\xef\x0f\xc8\xc6\x0f\x29\x0c\x78\xca\x45\xe7\x57\xe2\xbc\x47\xd0\x14\x0e\xe7\xec\x64\x74\x18\x47\xb8\xcc\xbe\x80\xca\x4e\x19\xb4\xe9\x62\xfb\x7d\x16\xbb\xab\xc7\xdf\x4e\x05\xd1\x76\xab\x2a\x82\x87\x3e\x86\xa5\x21\x55\x3a\x4e\x7b\x5b\xe0\xc9\xef\x63\x86\xe0\x0c\x7e\x28\xdf\x2c\x16\x67\x24\x8e\x37\xbe\xf7\x61\x12\x73\x04\x7c\x3d\xbf\xac\xf6\x33\x9a\x75\x34\x4c\x8c\xa6\xa4\x43\xc1\x9c\xbd\x26\xf7\x64\x9e\x86\x29\x07\x6c\xfc\x8c\x6d\xe7\xe2\xae\xf4\x41\x43\x1e\x2b\x32\xcc\x79\xee\x45\xde\x06\x26\x6a\x46\x99\x96\x86\x9c\x58\x4b\x10\xdb\x5c\xc7\x88\x15\x93\x88\xad\x67\xce\xd2\x50\xc4\x12\x61\x19\xc7\x73\x7e\x45\x18\xa4\xa1\x48\xd2\xc8\xb2\x86\x2e\xcb\x39\xe3\xdf\x49\x69\xdb\x7f\x4a\x81\x13\x27\x50\xbd\xb5\xa1\x3b\x26\x8d\x76\xcf\x39\x37\xdf\x2e\xb2\xca\xb4\xf3\x56\x1d\x70\x93\x69\xa8\xe2\x08\x5b\xaf\x59\xdd\xf3\x8d\xbc\xe8\xbb\xf6\x83\x74\xd4\x49\x57\xb6\xd1\x55\x67\xe5\x4e\x43\x4d\x15\x06\xc2\x37\x59\x53\x37\x95\xf8\xcf\x7e\xb8\x36\x87\x5a\x59\xa6\x80\x35\x2a\xbc\xc9\xf4\x6d\x66\x1c\xbc\x7a\x5d\x6c\xff\x2b\x64\x39\x79\x2a\xda\x68\x3e\x60\x08\xfa\xae\xef\x6c\xd2\x4e\x43\x88\x15\x36\x1f\x7c\xaa\xe3\xe8\x75\x77\xe7\xe2\x57\xb2\x3c\x34\x84\x34\xc5\x66\x62\xbb\x92\x64\xc5\x9b\xd3\xc7\x9a\x55\xdd\xa5\xa1\x89\x2c\x58\x79\x2c\xd9\x38\x39\xa3\xe1\xb6\xc8\xd4\xae\xfa\x7b\x35\xb5\xef\xf6\x83\x94\x41\x9b\xee\x87\x87\xef\xfb\x38\x0c\xf7\xab\xdb\xf5\x6e\x4f\xfc\xbd\x32\x26\x44\xe8\x46\xd6\xa0\x2f\xc0\xe6\x27\x54\x56\xba\xdf\x0d\x88\x02\x13\x60\xdd\xa1\x71\x81\x5a\x7b\xf5\x6b\x74\xd4\xe9\x47\x28\x64\x39\x35\x15\x88\xba\xd3\x2b\xa1\x51\x18\xd9\x16\xfc\x5e\x9e\x2f\x6b\x07\x44\x1a\xdf\xf8\x28\x8c\x69\x62\x99\xe6\x4a\xe4\x76\x9d\x19\x84\x8b\x34\x0a\xd3\x14\x9d\x5f\xfa\x10\xf6\xb9\x5d\x8b\xc7\x38\x2c\xf7\x2e\x47\x11\x8d\x6d\xf3\xc9\x0a\x3f\xfb\x73\x44\x8c\xa3\x18\xfc\xa6\xac\x40\x97\xa5\xff\x73\x9c\x50\xbc\xea\xa5\xa8\x0f\xe8\x20\x3f\x7b\x8b\x23\xa2\x19\x06\xb7\xaf\x37\xd0\xf4\x55\x2f\x1a\x51\x12\xc4\xbd\xdc\xd9\x93\x38\x82\x35\x89\x1d\x5c\x3c\x4d\x2d\xbc\x00\x5f\xc3\xb7\xf6\xee\xde\x01\xd4\xb7\x67\xd8\x95\x77\x65\xf5\xde\x57\x19\x69\x44\x85\xc1\x48\x66\xb7\x59\xdc\x74\x1f\x57\x31\xe2\xdb\xf4\xee\x65\x7d\x7f\xbf\x7a\xd9\x3f\xad\xfe\xdc\xfd\x58\xad\xfe\xd8\xef\xd6\x8f\xab\xed\x6e\xf1\xe8\x17\x9f\x88\x05\x1c\x1b\x09\xb7\x60\x2a\x71\x51\x83\xcb\x64\x5c\x4a\x9b\x26\x1f\xb3\xc6\xa5\x6f\x6d\xba\xd7\x1d\xd7\x89\x57\xfd\xdd\x81\x38\xfa\x5d\x7f\x34\xdd\xa3\x24\x0a\x11\x8d\xb3\x91\xff\x6e\xef\xeb\x4c\x94\x18\xa5\x34\x45\xf5\x66\x7c\x4b\xf6\xd2\x9f\x3e\x65\x0a\x97\x71\xfc\x73\x58\x37\xe3\xfa\x29\x8d\x78\x68\x23\x8f\x37\x68\xbe\x3f\x3e\x8b\x4a\x1c\xa1\x19\xe8\xc3\xb8\x51\x92\x09\xca\x86\xf6\x27\x36\x0b\x99\x9d\x9d\x91\x0a\x0c\x82\x3f\x95\x37\x60\x1e\x98\x60\x4e\x46\x86\x09\x16\x7d\x9c\xc8\xa5\x55\xb3\x6c\x43\xb8\x9b\x4b\x1a\xb4\xff\xd9\x37\xd9\x11\xb0\x8d\xec\xaf\x57\x31\xa6\xc2\x81\xb1\xc4\x43\x59\x77\x0a\x19\x34\x52\xdc\x06\x17\x6f\xd9\x4f\x10\x1f\xe2\xca\x85\x6e\xf4\xb6\xea\x80\x04\x4e\xc8\xa8\x1d\xb3\x31\xbd\x99\x46\x77\xe3\x75\x60\x29\xea\x1d\x2a\xa6\xac\x6e\x44\x0d\xcf\x57\x21\x50\x04\xdc\x84\x96\x40\xe5\x95\x7d\xd0\xe7\x79\xbc\x14\x44\x20\xa3\xd4\xf5\x9e\xef\xce\x93\x4e\x4b\x7b\x34\x61\xbd\xc3\xe5\xf7\xf5\xf3\x4d\xd9\x99\x50\xd3\x08\x8c\xec\x3c\xf2\xcb\xe3\xa9\x81\x6e\x0d\x89\x0c\x23\x0a\x06\x24\x72\x51\x5c\x26\xda\x00\x34\x0e\xb4\x0c\x15\x82\x47\xca\x7c\x7f\xea\x05\x5d\xdc\xe1\x50\x70\xac\xf4\x15\xe7\xe3\xc6\xbc\x16\x7e\x69\x45\x4c\xda\xec\xd6\x17\x47\x11\x47\x23\x97\xff\x8a\xfa\xb3\xfd\xef\x7f\x84\x3f\x57\x1c\x4b\xdb\xf6\xc8\xcb\x1a\xf6\x05\x7c\x36\x7b\x79\x46\x22\x98\x1b\x40\x42\x8a\xa4\x26\xe7\x31\xe3\xff\x2a\x62\xe2\x10\x43\xb8\x02\xfe\x25\xf0\x61\x34\x49\x62\xa2\x58\xc2\x3c\x7e\xc6\x64\x79\xde\x46\x00\x77\xe5\x08\x29\x47\x63\x9a\x48\xcc\x83\xac\x6d\xc4\xb2\xd4\xc3\xba\x04\x8d\x29\x68\xf4\x72\xc6\x4b\x6f\x03\x92\x02\xf2\x11\xd0\xb9\x4f\xff\x69\xcc\x22\x0b\x4e\x3c\x68\x57\x6b\x9a\x62\xd8\xda\x21\xd6\x6a\xdc\xbf\xaf\x53\x27\x02\x1a\xb3\x58\xe0\x8d\xf7\x68\xe1\x6b\x26\xc4\x5f\xfe\xfb\x65\xd6\x17\x33\x41\xb0\xad\xf1\xba\xbd\x8d\x82\x3e\xf1\xf6\x47\x55\x82\xb2\xfa\x79\xf9\xe1\xe3\xe6\x91\x7c\x13\x8d\x99\x49\x11\x32\x74\x12\xd9\x5e\x68\x3d\xb7\xf2\xc4\x09\x4b\x70\x57\xd5\x50\x64\xd7\xed\x63\x3f\x48\x58\x6c\x0b\x1a\x3f\x8a\x66\xf1\x53\x34\xa2\x7a\xad\xc6\x84\x2e\x1a\xa7\x71\xe8\xbd\xb0\xb7\xe5\xd1\x99\xa7\x8d\x87\xf0\x00\xb0\x3e\xd0\x1c\xb2\xca\xa1\x06\x36\xa6\xd3\xf0\xa6\x31\x0f\x03\xdc\x6d\xdb\x78\xfb\xa9\x7d\x15\x4e\xe7\xa6\x77\x7f\xed\x46\xc5\x06\x3b\x50\xf7\x96\xa0\xf7\x21\x2a\x18\x3d\x15\x11\x45\xc2\x35\x75\xb7\x67\xf9\x98\xe5\x6d\x92\xd2\x9b\x87\x7f\xa9\x3b\xe7\x3f\x9e\x0a\x24\x13\xdd\xbf\x2c\x9e\x57\xdd\x39\x53\x65\x86\x46\x53\xf5\x03\x98\x66\xfc\x76\x0a\x08\xb0\x15\xfb\xfc\xba\xdc\xac\x9f\x66\x35\xcf\xdd\x48\x19\x27\x88\x0e\xc6\xe5\x52\x14\xb6\x33\xe4\xbf\x49\x11\x8a\x21\xac\x9f\xc5\x23\x15\xf4\xc9\x89\x14\xb7\x97\xaa\xcc\xde\x09\xca\xcd\xaf\xeb\xb1\x12\x0a\xa5\x2d\xf2\xac\x6e\x36\xe7\xc6\x57\x81\xea\xee\x4b\x8d\x35\xb0\x47\xff\x80\xc7\xac\xc8\xee\x3b\x33\x60\x1a\x6b\xc2\x71\xe1\xfb\xf1\xf0\x30\x7a\x0e\x10\x10\x41\x3b\xe1\x99\x0e\xb6\x49\x63\x90\x34\xd6\x1d\x7a\x74\x57\x6e\x01\xf4\x13\x7c\x3a\xc9\xfc\xf9\x2b\x04\x25\x51\x40\xa2\xc3\x1e\x8c\x5a\x82\x94\x04\x29\x60\x5b\x68\xb7\x5a\x3c\xee\x5f\x56\xdb\xd5\xcb\x77\xff\x70\x48\x18\xd2\x88\x0e\x11\x9f\x1d\x26\x74\x58\xfd\x21\x61\x6c\xd1\x23\x76\x89\x1e\x5a\xdf\x4c\xf6\x4c\x12\x41\x82\x4e\x37\x6e\x64\x73\x80\x6a\x59\x4e\x20\xc4\x38\x4a\x39\xa3\xf2\xb5\x76\x6c\x68\x4b\xd2\xf2\xdf\x18\xa7\xc4\xf0\x8e\x32\x83\xf4\x4c\xab\x00\x3f\x9f\xa4\x92\x38\x35\xb8\xf8\xde\x3d\x64\x7f\xfc\x9a\xfa\x3b\xbe\x7b\x84\x70\x86\x05\xf4\x73\x71\x87\x4a\x3a\x57\x0c\x60\x4a\x88\xa4\x91\xea\xdb\xbb\x2f\xe7\x5f\x21\xf2\xc7\x67\xa7\x86\x93\x70\xa0\x14\x76\x65\x49\x45\x09\x8b\x38\x1f\x72\x1a\xd1\xdf\x78\xb4\xc6\x13\x16\x07\xde\x43\xfd\xc7\xc3\xb8\x30\x48\x98\xb4\xbe\x8e\xe2\x94\x4d\x8f\x68\xae\x48\x77\x0b\x51\x35\x70\xfc\xcd\xa9\x33\xfa\xf5\xc4\xf5\xe5\x34\x92\x9f\x56\x0b\xff\x37\xfd\x3f\xff\x51\x65\x42\xd7\x11\xd8\x14\xcb\x32\x3f\x1f\x8b\xdf\x66\x64\xc7\x28\x49\x4d\x80\x34\x82\xd5\xee\xdb\xc6\x2c\xab\xcb\xb6\xcc\x6d\x38\xd7\x5d\x26\x0f\x28\x16\xed\x17\x45\xd9\xbe\x2d\x9e\x35\x31\xbe\x54\x1e\x86\x96\xea\xdb\x6e\xde\x9b\x02\x3a\x60\x5b\x7b\x88\x83\xb3\x0c\x5e\x17\x59\xb3\x14\x95\x8e\xba\x63\x44\xa2\x7a\xe6\x19\xbd\x73\xa3\x7f\x75\x7f\xe7\x80\x1a\xba\x0f\x3f\xee\x86\xf3\x92\x70\x50\xd6\x91\x43\x18\xb8\xad\xfa\xa5\x85\x88\x88\x4b\xe9\x77\x59\x7b\xb7\xe0\x5a\x07\x9a\x12\xc1\x19\xb1\xae\x84\x93\x02\x2e\x11\x02\x3c\x1d\xf1\x11\x45\x46\x77\xe5\xe9\x01\x7e\x42\xde\x8d\x50\x84\x23\x77\x04\x0d\x2f\xb2\xe6\xe2\x00\x6c\xdd\x51\xab\x22\x67\xf7\xf9\x73\xa1\xaf\x2d\x36\x29\xd1\x24\xa0\x61\xef\x1e\xb1\x2e\x1a\x78\xf3\xe0\xa1\xd1\x1b\xea\x0b\x53\x44\xb3\x08\xab\x2d\x75\x76\xec\xf8\x1d\x83\xcd\x9e\xe8\x54\x21\x88\xe8\x51\x9c\x4e\x83\xf4\x8c\x80\x04\xd6\x2b\xd6\xf9\x15\xe7\xaa\x41\x45\x69\x48\x2c\xd6\xe7\x71\xf1\xe7\xfe\xf9\x65\x85\x45\x0c\x6b\x21\xbf\xdf\x6e\x1e\x7c\xf9\x81\x86\x94\x49\xda\xb1\x11\xe6\x17\x6d\x1a\x52\x89\x8f\xcd\x01\x97\xea\x1a\x05\x20\xb0\xfc\x30\x59\x87\x68\x98\x32\xd1\x09\x77\x75\xa5\x19\x1a\x4a\x63\xac\x9c\xee\x3b\x38\xb1\xa7\x41\x2f\x87\xd2\x28\xe4\x98\x4f\x2c\x0f\x55\x79\xcc\xba\x6a\x06\x8d\x22\xe1\x35\xc2\x91\x25\xdb\x66\xa3\x76\xe7\x1c\x06\xce\x34\x8e\x13\xee\x54\x04\x6f\x32\xad\xb3\xe2\x0d\x0d\xef\x8a\x69\x3b\x92\x52\x42\x52\xab\x81\x51\x55\xe2\x32\x2a\xcf\x52\xe2\x84\x91\x31\x18\xbb\xc9\xe6\xcd\x4c\xdb\x61\x06\xd3\xbc\x9b\xc5\xef\xeb\xdb\xcd\xcb\x5f\x17\xc3\x69\xbb\x7d\xc6\xb8\xfb\x17\xcb\x43\x76\x1a\x5f\x3a\x55\xa1\xb3\x28\xcb\xf3\xc7\xcb\x90\x88\x47\x29\x13\x01\x12\x49\xbd\x68\xf9\x78\x87\x1e\x3c\xec\x84\x70\x8b\xae\x81\xa1\x11\xca\xe4\xc2\x13\x0a\x9d\x93\xc3\x01\xec\x6f\xdf\x98\x76\x32\xd9\x15\x78\x72\xa7\x12\x11\xa6\x30\x58\x1f\xbf\xc1\x57\x1a\xfd\x94\x26\x52\xa2\x56\x20\xaa\xb0\x4e\x5f\x89\xd4\xe1\xe1\x2c\x75\x71\x86\xe3\xde\x0e\x51\x98\xf8\xc0\x27\xa8\x73\x03\xbb\xcf\x2f\x35\x3a\xfc\x07\x78\x82\x29\xe2\x2d\xc8\xf3\xdb\xaf\xac\x1a\x29\xe5\xb1\x44\xd5\x7d\xbf\x4d\x63\xde\x5b\xe8\x67\x6b\x6c\x33\xa9\xe0\x8c\x6f\x01\x17\x46\xf3\x2f\xd5\xdb\x27\x2a\x6e\x94\x72\x95\x60\x2a\x8a\x1b\xfe\xf7\xd5\x16\xfd\x4f\x9f\x57\x2f\xeb\x4d\x37\xdd\x44\x60\xf5\xb7\xd0\x7d\xb8\xcd\x7c\x3b\x9b\xbc\xbe\xa7\xfb\xb7\xff\x57\xfb\x02\x74\xff\xf4\x5f\xa0\x3a\x47\x84\xad\xc8\xc1\xea\x14\x76\xdf\xcf\x00\xf5\xb3\x7f\x22\xbb\xc6\xc6\xb3\x13\x3a\x0a\xa5\x22\x11\x58\x65\xbc\x87\x63\x27\x11\x43\xa9\x00\xab\xdd\xd5\x01\x9c\x26\x8f\x59\x12\xe1\x31\x15\x88\x4b\x28\x8b\x36\x00\xe9\x3e\x2e\xa9\x55\x75\xb0\xa0\xe6\x6d\xe7\x0c\xbf\xf8\x29\xb2\xbc\x37\x45\xa2\x54\x32\x2e\xe3\x0e\x76\x5d\xd6\xcd\x00\x77\xed\x87\xa4\xd2\x33\x26\x9f\x61\xfa\x0c\xdd\x18\xc5\x74\x90\x0c\xbc\x2b\x6f\x45\x03\x1b\xb3\x14\xc7\x93\xc8\xde\x8a\xf1\x46\x4f\xb5\xb4\xfa\xd4\x95\xf5\xf1\xdc\xfb\x6b\x01\x4d\x70\xb5\xd8\x9f\x0e\x9f\x33\x31\x04\x35\xdc\xd2\xd8\x1f\xca\xb7\xb0\x4b\xc9\x46\x73\xdf\x08\x48\x5c\x51\xe8\xd5\xb7\xad\xb2\x72\x0c\x8f\xa6\x2c\x20\x44\xd9\xac\x4c\x59\x17\x83\x1b\xa1\x5f\xe0\x34\x3f\xdb\x58\x40\x28\xce\x96\x76\xea\xbe\x9e\xde\x2a\xa1\xaf\x9d\x97\x7f\x1d\x1f\xb1\x40\x5a\x88\x68\x0d\xcd\xc6\xb5\x6f\xee\x45\x7d\x1d\x31\xb2\x30\x92\x08\x05\xb5\x90\xea\xdb\x49\x6b\xb9\x3d\xae\x03\x18\xc4\xfe\xcf\x22\xcb\xf3\xac\x6f\x44\x8d\xee\x17\x0b\x8d\xb5\xe3\x52\x59\x63\x9d\xbc\x77\x65\x57\x0f\x1d\x7f\x6f\xa4\xed\xd4\x2b\x4f\x50\x0c\x7c\xab\x28\x8b\x4c\x00\x2e\x28\xfc\xe3\x5f\xcb\x17\xf8\xcf\x39\xab\xd0\x47\xb8\xd7\x9f\xea\x17\x46\x16\x27\x1c\xd7\x89\xc7\xf5\xd3\x7e\xfd\xd4\xce\xc9\xd5\xed\xbe\xa3\xee\x50\x16\x6b\x8a\x71\xa2\x86\xfc\xae\x5a\x7d\x2a\x38\x0d\x99\x96\x6e\x10\x91\xda\xae\x20\x4a\xdd\xb5\x97\x32\xac\xfa\x31\x62\xac\x0e\x9c\xaf\x97\xa2\xe4\x4f\x7f\x50\x7b\xe4\xe1\x53\xd9\x88\xde\x1e\x62\xb0\x78\xb3\x76\x9d\xe7\xc3\x89\xb5\xbe\x9d\x5c\x00\x65\x86\xf7\x69\xc0\x63\xfd\xb6\xb5\xba\x35\x65\x71\xae\x6f\xab\xf2\x34\x59\x71\x19\x95\x71\xda\xbe\x74\x77\x9b\xd7\xa7\xdb\xc5\x6e\xbd\x79\xda\x3f\x6f\x36\x0f\x48\x99\xc3\x85\xe9\xb7\x6e\x20\x60\xc9\xb6\x2e\x4d\xf3\xd8\xa8\x2b\x15\xbf\xc9\x69\x8d\x95\x3f\xdd\xb6\x53\x6a\x14\x2d\x4e\x1e\x33\x23\x0c\x33\x9f\xed\x11\xa7\x70\xf1\xdf\xec\xb7\xee\x88\xed\x5d\x9d\x2a\x70\xab\xc0\x10\x51\x4e\x19\xa3\x92\x5a\x17\xd2\xd2\x34\xaa\x0b\x36\x19\x93\x80\x1b\xcc\xaa\x39\xbc\x40\x9e\x81\x99\xdc\x21\xa6\x0d\xc6\x0f\x7b\x2b\x0b\x66\x65\x03\xa6\x53\x60\xfe\x57\x25\x09\x65\x4e\x9c\xe0\xb6\x8d\x0b\xcb\xd3\x11\x8a\xc6\xf5\x56\xca\x63\xd9\x3e\xec\x19\xab\x07\xca\x52\x16\x20\xaa\xc3\x41\x53\x51\x89\xd8\x1f\xe2\xc2\xf4\xb0\x07\x7f\xb3\xe6\xa7\x22\x4f\x53\xec\x4b\xe5\x6d\x56\xd7\x86\x2f\x83\xa5\x98\x71\x15\x7a\xbc\x75\x1b\xfa\x0c\x08\xd1\xed\x4b\xc3\xb1\x0d\x6a\xb5\xf3\x97\x90\x77\x21\x2d\x13\x5a\x62\x96\xbd\xae\x71\xd7\x9a\x5c\xb8\x8c\x01\x7b\x0d\x47\xd0\xd9\x14\x09\x42\x99\xe4\xda\xfb\x1b\x60\xf1\x7d\x7a\x58\x5a\xaf\xd1\xce\xb3\xf7\xf1\xd2\xf5\xbe\xdc\x10\x15\x06\x58\x64\xde\x3c\xed\xae\xdd\x5a\xdb\xc3\x09\xf1\x31\xfd\x10\xa4\x35\xff\x78\x54\x1a\x62\xec\xd9\x17\xac\x1e\x9d\x10\xca\x17\x6f\xa9\x4a\x29\x22\xd3\xea\x53\x56\xec\x0e\xf0\xe3\x00\xd3\xca\x27\xd3\xb1\x01\xdb\xee\xc5\xe7\x6d\xed\xed\xbc\xc5\xdd\xde\x94\xd5\xfe\x66\xf2\x09\x20\x09\x56\xfb\xc4\xcf\xb7\xf6\xa5\xad\x77\xe5\xb0\x7e\xc3\xda\xfb\xe2\x45\x83\x96\x7f\xc3\xc2\x6e\x72\xc9\xc0\xac\xab\xc5\x36\x2b\xd0\x73\x31\x6b\x2e\x3b\xa8\x9b\x30\xea\xce\x0f\x31\xd6\xa1\x55\x27\x3d\xed\x0e\x98\x38\x75\x75\xe0\x3f\x8a\xf2\xa3\xd8\x14\x9e\xbe\x47\x93\x20\xd0\xba\x7d\x07\xfe\x2d\xd4\xfb\xfe\x23\xeb\x2d\x40\x68\x12\x44\x09\xfa\x69\x23\x74\x2d\xcf\xdb\xa7\xb0\x2e\x9e\x2b\x50\x59\x4f\xd2\xa6\x49\x40\x63\x34\x05\x10\x59\xa5\xab\xf2\xf4\x23\x2b\x06\x6f\x66\x12\x24\xb6\xcd\xd4\x80\x38\x7a\x91\x08\x7f\x48\x5a\xe0\xe8\xed\xf7\xf5\xf3\x8d\x50\xef\x5f\x19\xbc\xd3\x24\x24\x80\xc1\xaf\xb5\x9c\x5a\x3e\x3c\x35\xa5\x4d\xd2\x1e\xc5\xfb\x57\xcb\x50\x12\x2a\x6b\x8b\xf9\x02\x28\x0c\xe1\x8d\x75\xe7\x9d\x67\x68\x12\x1a\x1d\x39\x4d\xde\xe7\x0a\x6a\x55\x65\xa7\x21\xe7\x79\xb4\x5d\x27\x51\x60\x75\xbe\xdf\x90\x3e\xa5\x1d\x80\x1f\x21\xbd\x1b\x63\x1d\x25\xe6\x90\xf2\x34\x89\x34\xa0\xac\x98\x44\xaf\x90\x5f\xf5\x05\x93\x38\x94\x18\x12\xbc\x16\x27\xa1\xde\x5f\xe0\xa7\x97\x44\x1f\xe4\x7f\x49\x4c\x94\x6f\x26\x21\x24\x30\xf4\x59\xe2\xba\xf8\x56\x9e\xa7\x2d\x93\x84\x04\x21\x32\xf4\x45\xbb\x6c\x0d\x69\x9c\xed\x21\x8a\x14\xd4\xd5\xe3\x7a\xbb\x6d\xb7\x82\xbb\xcd\xcb\xbe\x0d\x51\xfd\x00\xaa\xa8\xea\xf1\x37\xed\x2b\xb4\x9b\x04\x5c\x09\xd5\x26\x89\x7a\x74\x98\xd3\x7e\x9a\xad\x08\x25\x2c\x88\x51\xec\x45\x68\xfd\x04\x1f\x5b\x71\x3c\xe5\x80\x2d\xa8\xb9\xc8\x3f\x61\x01\x45\x5d\x3b\x7b\xdf\x86\x92\x61\x34\x61\x0c\x52\xe2\xa6\xbe\xcd\x19\x77\x83\x40\x31\x61\x5c\x48\xde\xa3\xee\xda\x87\x5b\xf7\xef\x78\x42\xa9\xf7\xf8\x69\x2f\xd9\x9d\x79\xf4\xb0\x13\x1d\xa9\x68\x58\x33\xdb\xd9\xa6\x25\x36\x83\x7f\x7c\xcb\xba\x2c\xf3\x1f\x93\x6a\xbb\x87\x9e\x8d\x7e\x49\x1a\x4a\x04\x85\x6c\x45\x73\x97\x7d\x7a\x56\xe3\xe8\x1f\x3f\x32\x32\xba\xcf\xb9\xb7\x4d\x75\x56\xcd\xf9\xeb\x66\xbc\xff\x14\x37\xd4\x0c\x7b\x51\xed\xe2\x35\x4c\xa2\x13\x1e\x2a\x2c\xd2\x1e\xcf\x75\xf3\xad\xcc\xf5\x5d\xd9\xdd\x0d\xce\x12\xd7\xc1\xb7\xee\x49\x7e\xa7\xef\xee\x35\x07\x69\x09\x5f\x87\x45\x56\xb5\x31\xc5\x5d\x7d\x10\xd5\x64\xf1\x4f\x04\x4b\x35\x62\x6c\x1b\x38\x1d\xa0\xf8\x26\x3e\x7a\x7d\x5a\x9a\x08\x95\x60\x1d\xb8\xb2\xc4\x4e\xa7\xc3\xb4\xb5\x32\xc7\x73\xf1\x60\x22\x79\x84\x94\xb0\xbd\x33\x99\x39\xa3\x83\xd7\xec\x8b\x22\x55\x80\xd5\xd6\xdb\x4a\x7c\xf4\x06\xd5\x34\x51\x01\x97\xca\x21\x6b\xa0\x68\x6e\x2e\xeb\x31\x93\x8e\x26\x2a\x49\x31\x62\xec\xdd\xd5\x26\x70\x5c\x3f\x2e\xb5\xe1\x8d\x3e\x1f\x8f\x17\xcb\x23\x71\x47\x34\x11\xa8\xcf\xe4\xec\x15\xb4\xe3\x88\x8f\xbf\x46\xa7\x69\x20\xac\x88\x3f\xd2\xa1\xbf\x70\x91\xfe\xf5\x56\x90\x40\x1c\x62\xe4\xe0\xbe\x6a\x7b\x96\x1e\x30\x33\xbf\x82\xb6\x13\x1c\x41\x58\xc5\x9f\xfd\xca\x0d\x8c\xf2\xce\xd1\xda\xca\xde\x4c\x80\x61\xbf\x20\x06\xd0\x04\x44\xc8\x3a\x46\x2d\xbe\x61\xdb\x8e\x82\xe2\x25\xc5\xa7\x97\x2d\x15\x1a\x74\xdd\xbd\x3c\x0f\x0b\x7b\x89\x71\xf2\x4c\xb6\x16\x8a\xf6\x40\xcd\x79\x12\xeb\xa7\x41\x98\x62\x55\xba\x8d\xf5\xdb\xdd\x75\x0c\xb3\x4c\x83\x04\xb0\xef\x75\x2e\xac\xe6\xfa\x4d\x79\x7e\x3b\x34\x73\x49\x5f\x1a\xc8\x48\x5a\x42\x22\x3e\xe0\x55\x2f\x01\x41\xd3\xc0\x10\xec\x6a\xe7\xc8\x73\xb8\xac\x07\x07\x98\x90\xdd\xdd\xc2\x36\xc2\xa0\x47\x97\x86\x41\x60\x53\x25\xe7\x48\x25\x85\x7a\x6f\x3c\x1d\x13\x33\xf7\x3e\x87\x1f\x67\xf3\x8c\xf4\x7f\xf2\x27\xa3\xb6\x14\xf4\x7b\x79\x10\xc5\xd3\xe5\xad\xea\x6e\x55\x1a\x26\x91\xd3\x3c\xae\x34\x26\x62\xee\xef\x51\x20\x90\xca\x72\x3a\xd7\x87\xe6\x73\x7e\x4f\x49\x23\x46\x70\x4f\x74\xf8\x9a\xf6\x2e\xbe\x9c\x51\x4d\xaa\x3b\x8d\xb4\xe2\xd9\xb9\xc0\x20\x73\xe8\x33\x44\xd3\x48\x6b\xe4\x35\x59\x81\x41\xff\xd7\x38\x60\x86\x7b\x8c\xfb\x97\x0c\x61\x9a\xc6\xc4\x56\x58\x6a\x68\x90\xde\xea\x80\xd5\x7d\x8a\x93\xc6\x3c\x45\xf4\x44\xe6\x2d\x0e\xc6\x8f\x8d\x1a\x86\xc2\xa8\x16\x1b\xe4\x25\x47\xdc\xc1\xc4\x48\x0f\x5a\xdd\x39\xc4\xc9\x4d\xf9\x39\x93\x48\xa5\xa9\x88\xb0\x58\xec\x1a\xa9\x53\xf1\xce\x39\xe0\x70\xc8\xfd\x93\xe1\xb1\x92\x36\xaa\xb0\x6b\xc4\xdc\x17\x08\x46\x03\x24\x9f\x3c\xee\x4c\x9f\x92\xa6\x02\x08\xb5\x86\x0c\x88\xfa\x78\x3e\x54\xa2\x06\xd4\x70\xfa\x9b\x2d\x55\x77\x1e\x19\x58\x0c\xf6\x8f\xac\x78\x87\x7c\xf5\xb2\xf4\xe2\xdb\x34\x95\x54\xb8\x00\xb3\xb9\xc3\x4c\x1c\xf4\xee\xb3\x3b\xc8\xb8\x89\x46\xad\x7a\xd6\x1d\x12\x1c\xac\x7b\x0e\x08\x8c\x4c\xdb\x9b\xb2\x2d\x55\x26\xf2\xb5\x06\xdb\xf9\x99\xbf\x18\xc5\x52\x5c\x57\x1f\x17\x7f\xee\xef\x57\x4f\xc1\xfe\x7e\xfd\xf2\xe0\x61\x86\xa9\x4a\xad\x22\x10\x2e\x11\xcf\xbd\xaa\xa3\x8b\x0c\xc6\x8f\x57\x89\x00\xa1\x37\x58\x16\x6f\xef\x90\x1e\x18\xaf\xd2\x54\xe9\x58\xc9\x81\x5d\xf8\x52\x9c\xd6\xc5\x6b\x71\x55\x5b\x4e\x75\x18\x32\xd7\xb1\x5f\xda\xde\xe1\x20\x6e\xea\xa6\x98\x26\x09\x26\xe4\xb2\x51\xed\x3e\xf1\x7c\x96\x7f\xc0\xe5\xb5\x50\xe5\xf1\xd4\xd3\x79\xc7\x2d\xfd\x7f\x8c\xbf\x46\x53\xec\x07\x40\xa1\x51\x47\xc7\xa2\x4f\xfc\x41\xd0\x28\x92\x6e\xb9\xee\x8e\x18\xdd\xed\xb3\x29\x68\x81\x7b\xc8\xe2\x65\xf7\x63\xf3\xf2\xc7\x7e\xf1\xba\xc4\xf4\xfb\xf6\xf5\x05\xf3\xf0\x6e\x9c\x49\xb1\x58\xe6\x0b\x9e\x7f\x47\x3e\x9f\xa6\x26\x88\x52\xeb\x04\xfc\x74\x7f\xbf\xf8\x36\x70\x52\xa3\xa9\x89\x58\xe4\xfa\x1c\x96\xc9\x65\x35\x82\xfd\x51\x45\x91\xc0\xe3\x51\x86\x77\x65\x05\xd9\x5b\x31\xbb\x88\x1a\xad\x03\xeb\xb2\x82\xaa\x2c\xa3\x83\x3c\x0c\x7a\x7d\x81\xf2\x5c\x29\x4b\xab\x1a\x5d\x26\x0f\x23\x2b\xff\x62\x95\xf5\x87\x9e\xd7\x94\x87\x2c\x40\x61\xe7\xa2\x3c\x76\x5d\x1e\x1e\x1a\x11\x75\x82\x07\xe5\xbf\x41\xb5\x71\x91\x6e\x17\xda\x1f\x59\xa1\xcb\x8f\xf1\x13\xe6\x51\x20\xa4\x0b\xed\x9e\xca\xef\x65\xd3\xd5\x28\x79\x14\x26\xb8\x56\x23\xc4\xa7\xf9\x28\xd7\x05\x96\xce\x57\xff\xb1\x70\xd2\x6e\x18\xd3\x5e\xa9\xbd\xbd\xfc\x51\x1b\x80\x47\xc6\xb6\x83\xb0\xe1\xf3\x81\x53\xc6\xc9\xf2\xcd\x3e\x14\x1e\x93\xc8\x4a\x20\xbf\xbe\x2c\xbf\x2d\xb6\xab\x29\x6b\xc8\x0d\x23\x5c\x52\xed\x70\x4a\x85\x27\xe9\x0c\x0e\x0b\x8b\x04\x11\xd8\x5c\xe9\xcd\xab\x28\x67\x91\xc5\x32\x20\x16\xf7\xea\x79\x30\x9d\xa2\xb1\xb4\x8b\x17\xd0\xa8\x63\xfa\x36\xb9\xa1\x89\x88\x12\x17\x40\xda\x40\x6b\x63\x10\x26\x55\x0f\x24\xdc\x7e\xf4\x0f\x25\x31\x04\xa1\x2b\x4e\x44\xc5\xa6\x3b\x33\xb2\xde\x94\xa7\xc4\x6a\x0f\x89\x3c\x2f\x3f\x16\xe7\xa6\xb4\x28\xeb\xc9\xd7\x73\xc2\x2d\x92\xc2\x5d\xdd\xd7\x0e\x63\xf3\xf7\x99\x73\xab\x78\xf1\x06\xcd\xdd\xf1\x58\x5b\x11\xbd\xc9\x5d\xe4\x22\x41\xfc\xcb\xfd\xbd\x47\x3d\x73\x11\x71\xc1\xba\x3a\xf0\x3b\x3c\x43\x75\xdb\x19\xac\x53\x2e\x4c\x84\x6b\xb7\x3c\x5f\xf6\xf5\x29\x53\xb0\x3f\x42\x8e\x10\x4c\x37\x40\x06\x10\x7a\x83\xb6\x75\xfd\x74\xce\xf3\x61\x9e\xc6\xa5\x32\xb6\xda\x70\x96\x0f\xa5\x8b\x96\xbe\x78\x51\x14\x31\xb6\xd3\x73\x14\x79\xfe\x9a\x15\xcd\xdd\xb9\x50\xbf\x0d\xa1\x62\xd3\x0f\x50\xc0\xe2\xe5\x5d\x96\xe7\x33\x15\xde\x2f\x6e\xd7\x2f\x7d\x05\x28\x57\x5c\x68\x31\x00\x2e\x4f\xdb\x35\xe8\x58\xdd\xde\x43\xd4\x7e\xd2\x03\x5f\x51\xca\x95\xe1\x38\x4f\xb1\xae\xb8\x7a\xf1\x12\x5c\xb1\x3f\xae\x23\x89\x6f\x98\x8f\xd4\x7a\x4b\x3a\x8b\xc7\xf3\xc3\x08\x0f\xa3\x41\xf1\x19\xfb\xa5\xd5\x4f\x31\x7d\x9a\x3a\x25\xb1\x15\x4b\x3e\xe5\x99\x5d\x66\xaf\x3b\xaa\x57\x09\x28\xd7\x10\x71\x97\x5e\xad\x1b\x38\x3e\x43\xf5\xec\xab\x6f\x61\x77\x6a\x88\xad\x1e\x48\x25\x3e\x66\x0a\xfb\x1c\x42\xe5\xdf\x9a\x9b\x2a\x53\xef\x37\xe7\x2c\xd7\x57\x48\x45\x0e\x00\xb8\xde\x3c\xbf\xac\xf6\xeb\xe5\x66\xff\xb8\x7e\xda\xdf\xae\x9e\x37\x5b\xef\x3a\x45\xb9\x61\x21\x62\xa2\xd6\xc5\xe9\x3c\x23\x78\x4a\xb9\x31\xd6\x97\xc0\xce\xb3\x1e\x88\xdc\xb9\xa9\x5d\xd3\x0f\xa9\x08\x42\x60\x6e\x32\xfc\x00\x71\x2a\x0b\x97\x3a\xf9\xc3\x09\x09\xbd\xa0\xd5\x6d\x2f\x79\xa2\xa0\x68\x56\xdd\x4a\x27\x82\x24\x45\x97\x5c\x0b\x83\xf6\x75\x94\x41\x71\x5b\x84\x49\x8a\x95\x9c\x1e\x28\x3d\x90\xc4\x18\xfd\x0c\x11\x82\x50\x1d\xe3\xe7\xea\x5b\xc5\x1b\xc2\xb9\xcf\x73\xe6\x8c\xee\x04\x51\x0c\x49\xcf\xa2\xbe\xc9\xaa\xe6\xe0\xac\x44\x27\xf0\xdf\x21\xac\x52\x44\xd4\x46\xcd\x27\xac\x9c\xef\xe0\x78\x1a\xb5\xef\x45\x94\x04\xc8\x09\x78\xce\xcf\xcd\x55\xd1\x67\xa6\x59\x2b\xa2\x94\x98\xd4\xb7\x82\xee\xca\x73\x35\x7c\x75\x45\x1c\x2a\xbb\x8a\x8b\x02\xad\xbc\xbe\x43\xdd\xc0\x14\x06\x3e\x7a\x95\x44\x1c\x33\xdc\x0d\xf3\xb3\x7a\xbf\xa0\x7a\xfd\xe4\x2d\x12\x31\x31\xdc\xb5\xaa\xee\xce\x79\x5e\x0d\xda\x1d\x22\x56\x56\x24\x07\xab\x57\xd8\x87\xed\x5b\x67\xf3\xeb\x8c\x88\x55\x82\x01\x33\x7c\x9e\xb2\x0a\xd0\x36\x73\x54\x64\x17\x44\x82\x8e\xbd\x8a\x46\x03\x55\x67\x24\x43\x05\x35\x52\xa5\x43\x5c\xd2\xba\x78\xae\xca\xb7\x01\xa0\x42\xb0\xc8\x20\x82\x7c\x97\x75\xa5\x18\xc1\x64\x88\xe9\x9f\x95\x83\x53\x97\xee\xef\x46\x60\x6d\xfb\x05\xb2\xa2\x0d\xdc\xb7\xf0\x13\x2a\x91\xdf\x82\x68\x0e\xc3\x3e\x8d\x48\x02\xc0\x24\xc7\x00\x38\xb2\x7f\xd6\xbf\xcd\x49\x08\xd8\x34\x5d\x37\x08\x5a\x2f\x2b\x1e\x04\xc1\x6b\xde\x54\xa2\x1b\x41\x38\xf6\x26\x0b\x00\xbd\x3d\x57\x3f\x31\xfd\x18\xc6\x0c\x22\x91\x14\xa7\xe1\x49\x54\x50\x34\xcb\x5f\xa0\xec\x45\x1a\x19\x0c\xf1\x5e\x56\x7f\xae\x9e\xc6\xeb\x82\x48\xa9\xe5\xe4\xb8\xaa\xd2\xee\xcf\x61\x19\x58\xf0\x30\x42\x8c\xea\xa7\x1e\xdc\x52\x1e\x5b\x7f\xd6\xac\x58\x66\x15\x96\xcc\x07\x13\x8c\x6b\x26\x1d\x1e\x7b\x5f\xb9\x09\x38\xd1\xa9\xa7\x42\xc4\x1a\xe1\xde\xbe\x8b\x22\x64\x6a\xbd\xe6\xb3\x7a\x59\xe6\xb9\x90\x25\xde\x95\xcd\xaf\x80\x77\x42\x25\x11\x8a\xfa\xb6\x6f\xf3\x8c\xe3\xd3\x64\x70\x6a\x45\xa6\x6d\x78\xdf\x0b\x73\x5e\x9b\x44\x5c\x7f\x14\x3a\x88\xf7\x8f\xb2\xca\x97\xe7\xd3\xcd\xc5\xe9\xf0\xf5\x83\x20\x49\x90\xc9\x5a\x9f\xe5\xb1\x33\x10\x9c\x7e\xc5\xb5\x0b\xcf\x68\xe6\x9b\x00\x52\xde\x11\x8c\x70\x46\xbc\xbe\xac\x47\x15\x3e\x61\x5c\x65\xa1\x46\x4d\x86\xf1\x5d\x35\x31\x0d\x1c\x8a\xb9\x14\xd6\xda\xeb\xe6\xf2\x24\x26\xdc\xe4\x76\x9c\x88\x2d\x02\xb4\x2a\x3f\xea\x76\xf6\xd9\x2d\x6d\x5d\xa8\xb2\xaa\x40\x35\x5d\x3f\xc2\x7f\x80\xa4\xf6\x81\xd7\x53\xae\xc7\x7c\x64\x23\x4c\xaa\x51\x61\x2b\xcb\xb2\xa2\x1c\xb1\xf1\xfc\x00\x88\xa1\x43\xdb\xcf\x18\xc1\x52\x19\x44\x31\x56\x7c\x84\x46\x62\xf2\x24\xf4\x93\x41\x64\xdd\xbd\x4d\x56\xe8\x5d\x79\x7a\xc2\x30\xa5\x3b\xc7\xf4\x19\xca\x00\x80\xe8\x6e\x29\x76\x52\x41\x73\x8d\x6b\x19\x85\x36\x73\x77\x9b\xc7\x65\x74\xfb\x65\x94\x2a\xec\xc1\x7f\x00\xbc\x23\xa3\x7e\x55\xe8\xe7\xfc\x5c\x3f\x96\x45\xb7\x0b\xc9\x48\xd0\x54\xdb\xe6\x47\x09\x03\xca\x85\x24\x41\x80\xad\xe7\xb7\x76\x4a\x3c\x97\x65\xfe\x52\x4e\x6b\x76\x92\x06\x21\xb2\x8f\xda\x2c\xf5\x75\xfd\xe4\x77\x5d\x49\x79\x8a\xed\xe3\x83\xa8\x97\x07\x71\x3c\x6d\xcb\x23\x34\x87\xac\x78\xdb\x14\x73\x5c\x12\x49\x05\x45\x65\xf3\xb7\xec\x27\x6c\x1b\xc8\x73\x51\x8d\xf6\x11\x49\x0d\x58\xa8\xec\x84\x1a\x4e\x25\x93\xc4\xd8\xae\x28\xf2\x5c\x33\xa8\xf7\xd4\x7f\x8a\x81\x50\xc4\x35\x49\x5e\x2d\x16\xce\x1f\x4a\x62\x40\xbe\xf9\xe9\x9a\x8a\x27\x13\x6a\x4f\xe9\xcc\xeb\x7f\x19\xd0\xc9\x04\x54\xea\x64\x3a\xda\xdd\x65\x39\x11\x3b\xa1\x32\x8d\x24\x22\x69\xb5\x70\xae\xbe\x3d\x8a\x56\xa6\x9a\xe1\x4a\xe2\xf3\x42\x57\x81\x31\x03\xd4\xab\x1b\xc9\x45\x62\xb5\x25\x70\xca\xce\x4b\x1a\x8d\x76\x52\x29\x82\x14\x5b\x22\x7b\x29\x6a\xb8\x05\x79\x25\x60\xf6\xc5\x0f\x12\x81\x4c\x85\x57\xe3\x34\xe6\x9a\x97\xf5\x8f\xd9\x46\x8f\x94\x8c\x26\x5d\xa2\x34\x92\xb8\x19\xdf\x5d\xc9\x0d\xf6\x0d\x6c\x50\xb3\xfb\x1c\x56\xfb\xa4\x4a\xec\xd2\x5a\x01\x62\x99\x1e\x4b\x7d\xce\xe1\x1b\x36\x95\xa7\x4f\x49\xc9\x38\x70\xdb\xe8\x42\x29\xa8\xeb\xb2\x7a\x3e\x57\xa7\x81\xb9\x80\x1b\x68\x42\xeb\xc3\xfc\x06\x0d\xb2\xaa\xb3\xb2\x58\x8f\x59\x74\xd2\xf0\x18\xaf\xc9\xd9\x44\x5f\x5b\x9a\x50\x15\x68\xc0\xea\xfe\x83\x90\x50\x41\xb7\x85\xa8\xc0\x08\x66\xfd\x46\x2a\x75\xf0\x61\x57\xbd\x99\x74\xc8\x55\xc8\x65\xe4\x8a\x74\xbf\x8d\xce\x1b\x45\x01\x96\x0e\xf7\x5d\x47\xd7\x45\x17\xd7\x41\x57\xff\xa1\x38\xd4\x4e\x4f\xa8\xcd\xd6\xa7\x7e\xc3\xd3\xc1\xcc\x0a\x92\x36\x1d\x25\xa1\x5e\x2f\x37\x9e\x4e\xa2\xe2\x94\x2b\x2f\x1b\x56\x16\x26\xfb\x4b\x26\x86\xfb\x1c\x89\x0c\xf2\x40\xdb\x35\xaf\xcd\xec\x1c\xbd\x63\xfc\xb3\x09\xb3\x94\x82\x0a\xcc\xf3\x94\x85\xa2\x08\xe3\x28\xc1\x8d\x2b\xf8\x36\x7b\xfb\xca\x05\xce\x0d\xa7\x5a\xd8\xfa\xe2\x76\xf9\x02\x35\x56\x3f\xd0\xe6\xa9\xf2\xf1\x8e\x62\x41\x80\x9b\xec\x21\x7b\x3b\x40\xdd\xec\x65\xa6\xfb\x43\x1a\x3d\x83\x2c\x0a\xe5\x71\xf5\xb4\xdb\xdf\xbd\x3e\xdd\x76\x98\xcc\x81\x75\x09\x55\x2c\xb2\x6b\xa2\x9f\x96\x63\x4d\xb3\x2f\x02\x3f\x95\x24\x04\x15\x80\x0e\xe5\xb9\x86\x95\x7e\x83\xf6\x6d\xa8\xbb\xe2\x94\x4a\xa4\xf5\x7f\x6e\x2a\x80\x7a\x53\x5c\x57\x6e\x54\x02\xb6\xc0\xd9\x26\xbb\xbb\x76\xbf\xf3\x4f\xd6\x89\x3d\x3d\x95\xcd\x0a\x85\xa3\xbb\x9f\x95\xca\x20\xb6\x05\xfe\x02\x6d\xad\xd1\x1b\xac\xfb\xc6\x14\x24\xba\x42\x1c\xdb\x89\xda\x34\x13\x69\x72\xaa\x78\x18\xe0\xbe\x24\xb4\x7e\x84\x9b\xcb\xcb\x72\xf2\xf4\x78\x14\x60\x77\xd0\xa6\x93\xb3\x12\x79\xf3\xef\x06\x4f\xad\xd3\x18\x42\x87\xb6\x4e\xe7\x84\x91\x7f\x4c\x4e\xaf\x22\xe4\x7f\xec\x07\xda\xf9\xb3\x6b\x86\x82\xd4\x6a\xe7\x0f\xea\x67\x8f\xef\x93\x9d\x40\x99\x28\xc2\x38\xde\x92\x08\x36\x1f\xd3\x62\x8d\x32\x84\xe2\x44\xb8\xab\xce\xd9\x94\x23\xa2\x8c\x0e\xb1\xe0\x6a\x33\x99\x78\xca\x05\xd0\x41\x20\x01\x06\x94\xff\x65\x25\xe4\xb3\x05\xb6\x89\x7e\x8c\xc1\x28\x17\xe3\x36\xc7\xb9\xbe\x96\x42\xa5\x3a\x88\x14\x1a\x4a\x61\x2c\x61\xb9\x49\xa3\x49\xd7\x31\x8a\x74\x90\x84\xb8\x09\x1f\xc5\x27\x6a\xc8\x3e\xc3\x28\x21\xd2\x81\x0a\x91\x8e\xf3\xb0\x18\x5a\x2f\x50\x1d\x26\xa1\xad\xda\xbf\x7b\xde\xba\x8e\x14\x44\x0e\x68\xb3\x14\x0d\xbc\x95\x13\xe7\x27\xaa\x63\xcd\xbd\xf3\xc0\xcd\xf9\x32\x72\xf2\x75\x23\x08\xb3\x89\xc6\x1b\x14\x36\x15\xf8\x35\x64\x49\x53\x95\x72\x1b\x8b\x21\xfd\x3f\x2b\xab\xdf\x66\xba\x35\x6e\x30\x0b\x12\xab\xed\x8e\xf5\xf1\x07\xb0\x0e\x99\x7f\xd3\xd4\x8c\xea\x24\x54\x06\x3a\x8d\x35\x57\x84\x1d\x24\x39\x3a\x49\x13\xac\xd3\x1f\xcb\xca\x4e\xe4\x67\xa8\x70\xa5\xbf\x2b\x7d\x4b\x72\x08\x75\xd3\x69\x10\x7a\xbf\x5e\xaf\xdc\x83\xc1\x21\xbe\x5e\x77\x65\xb5\x29\xe0\xa6\x51\xdd\xe8\x30\x88\xc1\x97\xd1\x1b\x91\xcf\x56\x77\x74\x1a\x11\xe1\x66\xdc\xb0\x43\xe1\x8f\x9a\x50\x89\xde\x85\x7e\xd8\x23\xd2\x3c\xd0\x08\xfc\x79\x38\xab\x77\x75\x80\xe3\x65\xf4\xbc\xb9\xb6\x91\x8e\xa8\xeb\xde\xfe\xf2\x8b\x87\x22\x22\x6b\xc0\x7c\xb3\xb9\x19\x9d\x43\x68\x81\xba\x5d\xfb\xd3\xb9\x3e\xbc\x94\xe5\xf1\x09\xa5\x4e\xa6\x33\x7e\x70\x47\x65\x28\x10\xc9\xe4\x9e\x24\x16\xd4\x46\x41\x81\x96\x11\xc3\x5a\x53\x9f\x3f\xfb\xbe\xec\xd5\xd5\xcd\x2f\x25\x5a\x26\x22\xb2\x6a\x7c\x59\x51\xe0\x56\xdf\xde\x95\xdb\x4c\x4d\x27\x95\xe4\x92\xb8\x9a\xcc\xef\xa5\x5c\x17\x3f\xcb\x61\xa0\x3e\x0c\x37\xb5\x22\x89\x77\x2b\xfa\x9e\x69\x28\xdb\xa9\xe5\x1e\xf1\xc8\x59\xde\x0f\x67\x89\x76\xa8\x61\x1c\x99\x97\x45\x57\x4e\x19\x8c\x52\x69\x34\x10\xc7\x0c\xe7\x97\x32\xad\x03\x8a\xed\xce\x53\x95\x1d\x45\xe5\xf4\x1c\x6d\x1a\x3b\x0c\x49\xb4\xe6\x01\x96\xc8\xbe\x9d\x8f\xa2\xd8\x36\xa2\xd0\xe2\x6f\xeb\xbf\x68\x2d\x43\x64\x1f\xec\xd1\x0a\x13\xa1\x0a\xb6\x8d\x32\x7b\x8b\x21\x90\x98\xca\xad\xee\xef\xb7\x03\xc7\xf4\xbb\xc5\xc3\xb2\x6b\x99\x68\x88\x38\x62\x29\xad\x56\x0e\xa2\xb0\xfc\x21\x13\x6b\x1d\xb8\xba\xe3\xb0\xbd\x38\xf9\x1a\xc3\x6c\xb2\x52\x59\x33\x59\x44\x11\xfc\xb5\x86\x2f\xd5\x26\x91\x61\xe0\x4b\xa6\x83\xde\xb3\x3f\x2c\x21\x49\x07\x92\xcb\x30\xa9\x7d\x8d\x1f\x13\x04\x44\xc4\x56\xbd\x04\x25\xb0\xcf\x79\xb7\x39\xd9\x7f\xdc\xb0\x30\x8a\x8d\xf3\x4a\x80\x4a\xe4\xbf\xcd\xb5\xaa\x20\x14\x91\xf5\x7c\xb4\x1d\xf3\x4d\xe1\x43\x1b\x88\xda\x08\xcd\x6b\xe7\x8e\xae\x17\xa2\xd4\xc6\xe5\xe8\xd8\xda\xce\x54\x31\xef\x8a\x39\x28\x73\x43\x64\x34\x36\xcf\x5d\x7c\xea\x1a\xb1\x3e\xee\x81\x38\x35\x2a\x19\xf4\x5d\x76\xd5\x19\x16\x85\xbe\x13\x79\x0d\x0b\x84\x15\x75\x23\x85\x22\xa6\x5f\x61\xea\xba\x5d\x6b\x1b\xd0\x9d\xe2\x98\xd3\xc0\x9a\x4d\x99\xbf\x14\xbe\x74\x27\x27\xa1\x5d\x40\x4e\x67\x99\x67\xf5\x61\x33\x06\x7a\x4d\xc6\x52\x89\x88\x98\xa2\x6c\x32\x73\xd9\xc1\xf1\x74\x53\x81\x50\x87\xdf\xc6\xa3\xd2\x20\x31\x03\x46\xf6\xae\x1c\x29\x09\x52\xa0\xa1\xf4\x5b\x16\x96\x6e\x1d\xe3\xd6\x2a\x98\xf9\x2e\xfb\x6c\x9d\x1a\x68\x4c\xb8\xf5\x2f\x45\x95\x99\x3f\x32\x1b\x0f\x74\xc6\x5f\xf3\x6d\x9c\x36\x52\x40\x4e\xe0\x22\x6f\x06\xcc\xff\xf6\x3d\x34\x61\x97\xd5\xdc\x20\x9c\x6a\xf2\xe6\xb5\x83\xd0\x0e\xe9\x98\x35\xf7\xed\x06\x9a\xa9\xe7\xaa\x3c\x95\xb5\x18\x49\xaa\x53\x60\x22\x40\x29\xbd\x06\xfd\x34\xfd\x75\x00\xd4\xee\xf7\x8c\x2f\x28\xa1\x06\x03\x13\xd3\x1e\x13\x59\x31\xeb\xb2\x43\x21\xe1\x91\xb6\x58\xfa\xea\x4a\x00\xdd\x0f\x11\x21\xc2\x04\x96\xab\xcd\x7e\xfb\x6d\xf1\xb2\xea\x3e\xdb\x26\xb1\xd6\xc8\x69\x75\xae\x06\x60\x52\x48\x54\x94\x30\x67\x6c\xd9\xc5\x41\x90\x18\x81\x1a\xa5\x9e\x29\xcd\xed\xd3\xe7\xfe\x8b\xd2\xd4\x3a\x2a\x9c\x8b\x36\x69\xd8\x9e\xe5\x15\x2c\xd0\x0d\xe4\xc2\xf2\xcf\x3c\x72\xa8\x4d\x2b\xeb\x29\xd9\x1d\x44\x18\x05\xbd\x0c\xba\x75\x21\xdd\x79\x0d\xba\xc9\x42\xd9\x9f\x5b\x48\x83\x9d\xa5\x36\xe0\x9b\x7a\x28\x7c\xd5\xe2\x98\x9c\x42\x72\x8d\xca\x81\xdb\x2c\xff\x09\xd5\x63\xd9\x65\x85\xa0\x52\x6d\x0d\x3a\x44\xae\xda\xa5\x41\xff\xf3\x5c\x36\xe2\xe6\x82\x62\xb3\x7f\x2f\xc1\x02\x1d\x6a\x2b\x47\xd0\x88\xaa\xb9\xbf\xaa\x8c\x81\x8e\x43\x6c\xdc\x3b\x2e\x9a\x9d\x92\xb3\x46\xea\x14\x34\x21\xd8\x1e\xf8\xa3\x3c\xe5\xc2\x47\x8f\xa0\x93\x54\xba\xd6\xff\xad\x98\x15\x7b\x02\x48\x35\x62\xc9\x71\x4e\xab\x7b\x4c\xa1\xd1\xb8\x74\xb6\x32\x30\xf9\x2c\x70\xc4\x74\xe4\x65\xf1\xf6\xfb\x59\x0f\x20\xd8\xe3\x37\xd8\x04\x12\x3b\x46\x37\x59\xf3\xf2\x32\x0c\x49\x4c\xc0\x28\xb6\xe0\x4c\x96\xe7\xde\x95\xc7\xff\xc0\xb9\x87\x6a\xc2\x24\xc4\x39\x76\xf3\xb0\x59\xfe\xb1\xfc\xb6\xe8\x1b\x42\xfb\x9b\xd5\x6e\xe1\xcf\x1b\xa5\x01\xeb\x0d\x21\x06\x7c\x9a\x38\xfa\xdf\xe4\xff\xe6\x1b\x5b\x26\x66\x31\xb6\x26\xee\x76\xbb\x66\x78\x91\xb1\x8c\xb4\x65\x8f\x63\xba\x67\x21\x40\xf5\x08\x4b\x69\x62\x48\xb0\x67\x8e\x55\x8d\x1b\xf8\xcb\x5a\xcc\x78\x17\x98\x3e\x4e\x13\x1b\x6b\xd0\x2e\xf2\x4c\xd4\xfb\xd3\x00\x92\x6c\x08\xb7\x3f\x0d\xc9\xaf\xed\x95\xac\x97\x9b\xf9\xf9\x6e\x28\x87\xc4\x71\x39\xd6\xf5\xf2\x20\xaa\xb7\x4e\x27\xa7\x7d\xc4\x6d\x88\xd3\x07\x7b\x86\xea\x00\x5b\xb5\x96\x69\x61\xdb\x93\xc3\x78\xd9\xb0\x30\x45\xdc\xda\x51\x7c\x0e\xd5\x05\x7e\x40\xd6\x8d\x20\xb1\x32\x03\x0f\x31\xac\xfa\xa2\x25\xa0\x1f\x40\x15\xa6\x2d\x2e\x21\xb4\x2a\xc8\x83\x28\xd8\x30\x61\x65\x22\xdb\xc5\x6d\x59\x1e\x8f\xe7\x22\x6b\x2e\x57\xb4\x18\xc3\x64\x18\xfb\x6d\xe1\xdc\x2c\xc5\x3c\xa8\xd1\x30\x1d\xe3\xea\xe5\x79\x02\xa2\x39\xd7\xdf\x33\x31\xda\xaf\x0d\x33\x11\x1d\x80\x6f\x9f\xce\xc7\x55\xfb\xe3\xe0\x8b\x32\x80\x61\xc6\x62\x3d\x51\xb2\x00\x89\xfa\x3d\xe1\xc5\x24\x9c\x99\xf6\x1e\x2d\x37\x4f\xbb\x97\xf5\xcd\x2b\xa2\x53\x3a\x1b\xab\xf6\xb8\xcd\x32\xbd\xf0\x95\xff\x7b\xaa\x80\xbb\xf6\x9e\x0b\x6b\xa2\x2f\xbe\x9e\x47\x96\x96\xa0\xca\x42\xe5\x67\xdd\xdd\x12\x4e\xad\x31\x98\x4d\x8f\x1e\x45\x73\xb8\x87\x22\x1b\xa6\x28\xd3\x13\x09\x82\xb9\xde\xee\xe5\xdb\x98\xf8\xf8\x37\xe8\xe5\x86\x83\x42\xc9\xcb\x1c\x4c\x43\xc3\xdf\x26\x07\x9d\x09\xe6\x0d\x34\x8f\x5f\x74\x81\x8c\x0c\xac\x26\x33\xbe\x6d\x43\x1a\xc3\x63\x96\x83\xaf\xe2\x1a\xc9\xa3\x30\x74\x06\xd4\x88\xe3\x7d\x00\x61\xa6\xab\xcc\xe4\xcc\x9a\xc5\x56\x77\xa5\xc7\xa3\xe2\xda\xf6\x07\x4c\x36\x6c\xd3\xe6\x54\x8e\x2d\x53\x43\xd1\x3c\x66\x75\x9d\x15\x6f\xcb\xc3\xb9\x78\x1f\x82\x10\x0c\xc4\x76\x1b\x10\xa7\xaa\xfc\x29\x9e\xc5\x9b\x68\xa7\x4f\x39\x9c\x3c\x40\x4c\x3c\x34\xaf\xf9\x22\xd6\x35\x90\xa4\x28\x30\xfc\xb3\x1c\x73\x35\x3d\xea\xb9\xbf\x38\x13\x41\x2a\xbc\x4c\x37\x88\xe3\xf8\xa5\x35\x09\xb3\x8e\x57\xe0\xed\x53\x06\x52\x20\xc6\x80\x48\x3d\x4e\xa7\xd3\x01\x7b\x02\xd0\xa0\xb1\xa3\xd5\x60\xc8\xdb\x0f\x36\x76\x0d\xfe\x9c\x7a\xdf\x0f\xaf\x9d\x05\x81\x4a\x31\xaf\xb4\xfe\xe7\x58\x01\x1e\x84\x35\x2c\x88\x28\xc5\x1a\xfe\xf6\x20\x74\xf9\x71\x53\x3a\x00\x1d\x0b\x22\x61\x10\x61\xea\x14\x29\x6c\x77\xb0\x37\x60\x75\xa3\x88\x32\xdc\x25\x6d\x7b\x91\xe7\xfb\xfa\x3f\xe7\xde\xcb\x83\x05\x49\xa4\x11\x37\x74\xb3\x79\x7a\xdd\xee\x1f\xd7\xb7\xfb\x7f\xee\xfe\xd5\x1d\x14\x0c\xdb\xd0\x6d\x90\xd2\x2b\x06\xce\x66\x68\x2c\x48\x49\x8c\x35\x97\x0f\xc8\xee\xca\xea\x65\x88\xa2\x9a\x0c\x54\x82\x25\x43\x2e\x0e\x46\x32\x65\xaf\xa8\xfe\x0f\xab\x1f\xd2\x23\x1f\x58\x90\xea\x18\xa3\x7f\xcb\x1a\x6a\x5f\x27\xd1\xfd\x42\x1e\x46\x08\x61\xce\xda\x68\x44\xa1\x5a\xf7\x5e\x95\xc5\x4f\xe8\x77\xe5\x99\x4a\x3f\x0b\x78\x4c\x52\x4b\x77\x42\x32\xe2\xa8\x0d\xe9\x86\x88\x38\xc6\x90\xf2\x5c\x43\xb5\x2a\x74\x17\x4d\x5c\x63\xf1\xa6\xa2\xcb\xa3\x67\xed\xcf\x96\x44\x58\x2b\x43\x1b\x6d\x91\xdb\x1d\xef\xdb\x75\xfd\x97\x05\x82\x5b\xed\x9f\xba\xcd\xdc\x11\x96\x7a\x55\x46\x60\x81\x10\x46\xb8\x30\x64\xad\xca\x31\xbb\xc1\x0d\x91\x81\xc2\x3e\x7c\xa7\xd4\x8a\x42\x7e\xa1\xbf\x73\x32\x24\x98\x7b\xbb\x8b\xdf\x95\xaf\xd9\xa4\x8d\xcb\x02\x19\x29\xec\x55\x21\x15\x3f\x42\x65\x2f\x7c\x57\xba\x73\x24\x06\x7b\xe0\x72\x88\xe1\x9a\xd5\xcc\x9e\x54\xa6\x59\xa0\xc2\x10\x19\x57\xf5\x59\xfa\xe8\x7b\x2a\x0d\x30\xfe\x80\x8e\x15\x6a\xec\x3b\x29\xd5\x36\x28\xbc\x15\x97\x2b\x5d\x60\x16\x68\x29\x30\xfc\xfa\xfd\x7c\xec\x5e\x13\x13\x1a\x2f\x0d\xb5\xfa\x9c\xe0\x59\x58\x60\x64\x80\xbd\x5d\x9f\x84\xf5\x94\x35\x16\x18\x1d\x93\xa8\xa3\xd7\xb4\x2f\x2c\xda\xe1\xdc\x7d\x9e\x06\x44\x06\x16\x06\x89\xc2\xb0\x30\xab\x6f\xce\x55\xd1\x75\x51\xfd\xd1\xd4\x20\x10\xcc\x4b\x78\x3d\x94\xea\xdd\xff\xda\xb9\x15\x97\x85\x61\xc0\x8d\xf6\xe8\xd9\x5a\x89\xfc\x3b\xae\x10\x7f\x4b\xfd\x90\x85\xa1\xb0\x4e\x3c\xcb\xf2\x5c\xd5\x70\x23\x6a\xd8\x14\x6b\xbd\x6d\xce\x1a\x2c\x86\x6b\x72\x07\xc2\x28\x48\xf1\x57\x7e\x88\xaa\xc8\x8a\xb7\xd5\xcb\x62\xbb\x52\x23\x25\x34\x16\x46\x82\x48\x07\x30\xda\x97\x88\xf9\x99\x09\x10\x58\x18\x39\xf8\x47\x03\xe2\x18\xf9\xcf\xc6\x61\x12\xf4\x51\xc3\x30\x85\xff\x6a\xee\x7c\xf5\xff\x4f\x45\xa6\xda\x73\x0b\xdc\x9c\x2c\x59\xf9\x06\x0a\x30\x99\xca\x06\xcc\x55\x3f\xae\x5d\x97\xdb\x6c\xce\x26\xf2\xbd\x98\x59\x7f\xed\x31\xd3\x96\xbe\xa3\xca\x1b\x78\xcb\x8a\xa6\xc3\xf4\xb3\x30\x4e\x2d\x1a\xfd\xbd\x50\xfd\x9f\x24\x86\x4c\xbb\xd5\x76\x77\xf3\x72\xd3\xfd\x59\xc7\xd2\x73\xbd\x11\xbb\x71\xa5\xfe\xc1\x42\x1a\x5b\xe6\x46\xbb\x15\xfd\x36\xf4\xcc\x09\xc7\xcf\x76\xe2\x2e\xc6\x42\x0a\x1a\xfb\x35\x8b\x4a\xbc\xb9\x72\x7c\x07\xaf\x79\x2c\xbf\x10\x09\x64\x21\xee\x05\xa8\x4d\xf4\x9f\x33\x0a\x33\xdc\x94\x55\x55\x5e\x03\xcd\xbf\xf8\xb4\xe2\x89\x13\x83\x72\xc5\xc4\xb5\x83\xc5\x0f\x22\x4d\x16\x26\xd4\x3a\x9f\x3c\x8a\x21\xa5\x82\x85\x89\x89\x3c\x02\xb7\x0b\x5f\xc7\xfe\xd2\xe3\xdf\x98\x1a\xeb\x3a\xb4\x83\xe3\xc9\xee\xd1\x5b\xb8\xd6\x88\x98\x0d\xa3\x58\xc8\x13\x43\xc2\x01\x36\x1b\x75\x39\x1d\x00\xdd\x5f\x90\x88\x15\x06\x7c\xf7\xe7\xdb\xf3\x1d\x14\x6f\xd8\xc3\xff\xab\x12\x21\x0b\x85\x64\x38\x8d\x9d\x89\xe8\xf3\x59\x8e\x4a\x2b\x2c\x94\xcc\xea\x29\x56\x56\x6f\x73\xb8\x90\x84\x32\xb1\x9a\xd1\xb6\xda\xb1\xc8\x7b\x11\xcf\x5f\xdb\x64\xb0\x50\x72\x8a\xfa\x96\x1a\x7e\xee\xcb\x73\xb3\x6d\x2a\x10\x47\x7f\x5a\x45\x6d\xfd\xbb\x29\x4f\xaf\xa7\x7b\x31\xd9\x04\x42\xc5\x62\x2c\x05\xef\x07\x15\x44\xa8\x11\xd9\xb0\xcd\xde\x0a\x81\x2c\xae\xc1\x9c\xea\x96\x10\x25\xd2\xd0\x2e\x59\x96\xf3\xee\xc2\x98\xf1\xd9\x35\xd5\x68\x49\x60\x2d\x72\x36\x37\x2f\xfe\xaa\x8c\xb6\x7e\xdc\x37\x99\xca\x6e\xe1\xe7\x19\x72\x5f\xe9\x60\x51\xc0\x12\x0c\x40\xdb\x67\xba\x6a\x0e\x9b\xa2\x3b\x90\xb0\x30\xf4\x66\x4c\x50\x37\x63\x94\x37\x8b\xc2\x38\x44\xc4\x43\xa7\x9e\x6f\x75\x84\xa6\x83\x68\xa0\x3b\x57\x7d\x7c\x4e\x8b\x42\x0f\xf9\x85\x2c\x0a\x65\x88\x65\xef\xda\xfa\xde\x75\xd2\xb6\xed\x11\xaa\x6d\xad\x4f\x03\x1c\x6d\x4f\xdb\x1d\x8a\xb8\xc2\xda\x87\x23\x7e\xcd\xa8\xad\x5c\x3b\xfa\xce\x78\xdd\x74\x37\x2f\x8a\x84\xc4\xdc\xb8\x4d\xbb\x31\x9f\x19\x1f\x8e\x23\x29\x7a\xd9\x9c\x55\xa1\x6f\xc5\xb5\x8d\xba\x1f\x4b\x22\xb4\x8a\xd2\x5e\xb3\xd8\x07\xa4\x9b\xe2\x06\x0e\x22\x37\x7d\x6f\x7d\xb6\x0e\xc9\xa2\x58\x84\x88\x1e\x7d\x57\xea\x3d\xa2\xac\x6e\x2a\xa1\xf5\x40\xd0\x6e\x76\xa2\x46\xb1\xe0\xb1\x97\xbd\xae\xef\xca\x6a\x51\xd4\x1f\xfd\x1d\x8b\x15\xf1\x12\x71\xed\x67\xd6\xc5\xf6\x43\x9c\xe6\xa7\x7c\x44\x02\x67\x86\xea\x3c\xd3\x86\xeb\x4a\x44\xa2\x40\x73\x6f\xbb\x97\xe5\xf3\x6a\x31\x2c\x22\x84\x40\x0f\xd1\xfa\xfd\xe5\xdb\xd5\x6e\x79\xe5\x8e\x71\x05\xdb\x1a\x37\xd8\x58\x44\x64\x60\x6d\x30\x31\xc0\x46\x4d\xd9\x5f\x4e\xd6\x88\xe8\x90\x5b\x41\x40\x14\x6b\xe9\xc1\x57\x93\xb9\x13\xd1\xc8\xf2\x5f\x7d\x7f\x16\x01\x01\xbf\x5d\x57\xb2\x59\x44\x3d\x87\xe7\xf9\x69\xb8\xac\x46\x34\x0d\xac\xe0\xd2\xbf\xfe\x5e\x8f\x83\x45\x94\x1b\x2c\x32\xb6\xfb\x1a\xf6\x2a\x37\xe6\xff\xe3\xec\xcd\xba\x1b\xc7\xad\x76\xe1\xff\x72\xae\xfa\x22\x17\x1c\x01\xf0\xbb\x93\x65\xb9\x4a\x29\xdb\xf2\x2b\xa9\xba\xd2\x27\x2b\x4b\x0b\xc3\x86\xcc\x98\x22\x15\x92\x72\x95\xf2\xeb\xbf\xc5\x8d\x81\x83\x68\x77\xbf\xe7\x26\xd5\x31\x21\x8a\x22\x09\x60\x0f\xcf\x30\xb9\x2a\x16\x46\x28\x12\x8d\x20\xea\xa7\x1b\x95\x0b\x12\x31\x25\x74\x36\x28\x1c\x9e\xfe\x8a\x0e\xe5\xfc\xad\xca\x62\x40\xfe\x87\xb8\xd4\xa5\x5f\x99\xdc\x8f\xcb\x58\x4c\xe5\xff\x83\xf3\x9c\xfd\x38\x4f\x8c\x3f\x6d\x03\xed\xdd\xf7\xf5\x4d\x94\x31\xba\x0e\xae\x19\x4d\x2d\x36\xd1\x84\x3c\xb8\x70\x5b\x7d\x52\x3b\x48\xd0\x2c\x95\x8e\xc9\xd3\x45\x55\xb3\xae\x05\xe3\x7b\xdf\xf7\xcf\x48\x24\x14\xc3\xf7\xa2\xdb\xf0\xb1\x68\xe8\x02\xf1\x48\x06\x09\x86\x8e\x37\x55\xf4\xba\xef\x29\xfc\xf3\x5f\x13\xe9\x1e\x12\xc9\xc8\x28\x6c\x74\xe1\x98\xf3\x3a\xf4\xa7\xcc\x94\x76\x2f\xa1\xa5\x39\xed\x2b\x5c\xcd\x76\xe7\xa9\xc0\x14\x89\xa4\x34\xeb\xee\x6a\xff\x75\xb5\x3d\x7c\x5d\x6c\xef\x7b\xd9\x70\x12\x49\x95\xe2\x0f\xc7\x46\x49\x55\x82\x25\xa8\x60\xa3\x64\xf5\x1f\x37\x4a\x91\x44\x0f\x6d\xc8\xb9\x28\x60\x24\x2e\x48\x22\xc5\x02\x63\xe5\x77\x11\xca\x63\x7e\x7e\x0e\x0c\x0e\xdd\xb8\x2c\x30\xd4\x3a\x5e\xfb\xa0\x5b\x4d\xc6\x40\x2c\x9d\x54\xce\x20\x98\x34\x04\x8b\xe6\xb7\xe1\xe4\x01\xe0\xc6\x5f\xa3\xbb\xe7\x3b\x68\xdb\xa2\xfb\xc6\xd1\x5e\x17\x87\x22\x8d\x4d\xba\x0e\x85\x9a\xaf\x51\x91\x38\x04\x2b\xf2\x53\x15\xef\xb0\xde\xfc\xf6\x41\xb5\x71\xb6\x48\x41\xe2\x28\xa2\xa2\x87\x85\x18\xfb\x9e\xbd\xb3\x21\x73\x63\x92\x88\x5a\x6f\x4a\x9d\x17\x03\x8a\xda\x78\x0a\xc6\xdd\xa3\x8f\x1d\x38\xc9\xf5\x86\xdd\x8b\x1a\xc7\x12\x30\xcc\xcd\x5b\x38\xa1\xe3\xe0\x47\xa4\x8b\xc1\x5d\x8a\x13\xc2\x30\x2d\xcf\x4f\xfc\x17\xd6\xdf\x86\x0b\x4d\x4c\x32\x2a\x87\x82\xef\x9f\x56\x8b\xba\xe1\x80\x11\xd8\x04\x0f\x42\x62\x22\x64\xec\x8c\x20\xab\xeb\xe3\xe5\x17\xd6\x31\xff\xbc\x36\x46\x62\xca\x14\xf2\x2a\xfe\x5d\xe5\x25\x26\xe2\xe3\x8a\xb6\x1b\xa5\x4d\x3b\xf9\x8b\x93\xa5\xb9\xe7\x2d\x5f\x4c\x5e\xf7\x98\x29\x6a\x6a\xae\x86\xfb\x78\x5f\x9d\x78\x7e\x93\x87\xb8\xb1\x3a\x76\x2a\x02\xf7\xeb\xdf\xef\x0d\xa5\xdf\x35\x49\xed\x98\x2c\x61\xa1\xa5\xa7\x7c\x3f\x9f\xa1\xbe\xab\x2e\xa5\x32\x34\xa5\x3d\x4a\x76\x9e\xba\xdd\xdb\x8f\xb6\x12\xeb\xc8\x7c\xb4\x15\xdf\x0a\x9d\xf7\x1c\x37\x70\x7c\xb5\x9c\x50\xc4\x4a\x9e\x90\xee\xb4\x29\xe1\xa5\xe0\xfe\xab\x45\x10\xe1\x94\x32\x52\x47\x3b\x5e\xbc\x4f\xf5\x10\x49\x2c\x08\x0b\xa1\x0f\x69\x2c\xd5\xdb\x3c\xdf\x39\x03\xe3\xee\x13\x02\xb5\x78\xee\x73\x1b\x7d\xf7\x11\x6e\x2c\x59\x3c\x92\x97\x76\x8c\xd5\x72\x0e\xae\x44\x62\x15\x33\xb0\x06\x3f\x67\xa8\x1b\x8b\x12\xbc\xa9\x09\xb8\x45\x2d\x56\x49\x86\x01\x34\xbe\xda\x48\x3d\xf9\xbe\xbb\xff\xb1\x5a\xbb\xaf\x57\x3c\x35\x05\x87\xaa\x42\x59\xfd\x73\xd4\x1f\x61\x89\x74\x5a\x5e\x6d\x5b\xc0\x96\x97\xaa\x9a\x97\x6a\x25\xb1\xd2\x06\x53\x62\x62\xb9\xbf\x57\x62\xd5\xc8\xda\xb1\xf6\xc2\x8f\x89\x4a\x93\xd4\xec\xd2\xcb\xe2\x91\x18\x94\x46\xbf\xaf\x47\xe0\xb5\x9f\x3a\x5a\x50\xe5\xdc\xd4\xd5\x1e\x7e\x4d\xe6\x72\x12\x04\x02\xfb\x3d\xcd\xa5\x39\x83\x7f\x4b\x92\x20\x49\xb0\x94\x6b\x9c\x9d\xbe\xc1\xb5\x99\x7e\x8e\x90\x98\x8f\x58\xea\x7e\xfb\xb0\x22\xa9\xa6\x91\x71\xff\xc1\x72\x96\x04\xca\xf8\xc9\xbd\x5c\xc4\x42\x4a\x38\xdf\xac\xb1\x49\x48\x74\x02\xb6\xe9\xfe\x50\xdd\x3a\x40\x0f\xd6\x8f\x24\x14\x0a\xc2\xb1\x97\xfd\xe4\x6c\x91\x30\x32\x72\x79\xe3\x55\xe9\x36\x65\x71\xb5\x95\x2b\x3f\x28\x43\xcc\xda\xdd\xe5\xd8\x37\x8a\xf1\xcf\x78\x93\x9e\xf6\x2f\x87\x97\xd5\xf6\xb0\xda\x7f\x3d\x8c\xab\xfd\x24\x89\xc3\x0c\xdb\xfd\xfb\xed\x1f\x87\xcd\xa9\xcc\x55\x17\x03\xd7\xfe\xa8\x32\x8c\x96\x03\x76\xc5\x6d\x03\x79\x12\x2f\x7d\xb4\x90\x7f\xb6\x30\x25\x89\xed\xa3\x36\xd0\x1e\x74\x55\x8d\xaa\xb7\x49\xa2\x18\x42\xfa\x72\x59\xc5\xf8\x46\xbb\xcb\x49\x34\x09\x84\x25\x97\x43\xf3\x3a\xfe\x14\xaa\x95\x77\xbf\xe4\xcb\xea\x1e\x50\x42\xf8\x4f\xbb\x9f\x1f\xf6\x5e\xc7\xcf\x20\x25\x1c\x5d\x3a\xbb\x2d\x7e\xb9\x78\xc1\xfb\xf8\xb8\x7e\x72\xcc\x2f\x92\x90\x3e\x79\x9a\x48\xdd\x3d\x54\xf5\x20\xd1\x4d\x08\x13\xb8\x47\x9f\xba\xcc\x79\x0c\xb0\x23\x09\x0d\x34\x3e\x2e\x13\xba\x59\x49\x7f\xc7\x98\x70\x63\xc2\x34\x35\xb2\xc6\x27\x7b\xea\xe6\x0e\x74\x55\x03\x16\x29\x1f\x79\xe3\x47\xb2\x34\x46\x98\xd6\xb9\xf2\x6a\x51\x24\x61\x12\x68\xea\xa9\x5b\x43\x99\x9b\x11\xd1\x93\x60\x67\x2f\x19\x54\x03\x0c\x6e\xed\x06\x47\x4a\x12\x9e\x00\x26\x97\xee\xa2\x79\xb1\xac\x4a\x85\x98\xc7\x71\xb7\xa7\x27\xb9\x61\xf6\x39\x39\x8b\xd4\x3c\x71\x4c\x5c\x6e\xb4\x4e\xf6\xd5\x18\xae\x68\x87\x42\x1c\x25\xa1\xab\x00\x8d\x2e\xbd\x5f\x15\x6f\xab\x5d\x89\x0e\x53\x14\x31\x52\xe8\xf6\xba\xe7\xcd\xdb\x38\x98\x49\x03\x42\x23\x5b\x19\xfe\x52\x83\x43\xaf\x8e\x5e\x84\x34\x20\x0c\xeb\x1f\xa2\xaa\xde\xf2\xf2\xf8\x04\x2d\x57\xbc\xe5\x0f\x55\xfd\x0d\xae\xd3\xf3\x49\x8e\xee\x2c\x3a\xaf\x9b\xf6\x07\xc0\x1b\xa2\xa2\xd6\x65\xf7\x9f\xf6\x71\xa4\x61\x28\xa1\x27\xde\x2e\x2b\xd5\xdb\xd0\x0e\x5f\xed\x34\x8c\x00\x2f\x5e\x77\x3b\xa4\xc1\x7b\xb8\x23\x89\xc2\x33\xd8\x87\x33\x30\xc9\x21\x69\x98\x19\x3a\xcb\xb1\x37\x88\xef\xc5\x36\x48\x1a\x51\xd3\x91\xdc\x94\xf0\xa3\xaa\x0b\x65\x3c\x3b\x7b\x5a\x06\x49\x23\x96\xb8\xea\x6f\xf7\x54\x8c\xff\xcc\x19\x7c\xcc\x94\x46\x92\xe3\x44\x7d\xac\x7e\x4a\x5e\x8b\x11\xcc\x95\xa4\x91\x4e\xa4\xdd\x5a\x90\xae\x70\x03\x28\x21\x69\x1c\x88\xcc\x62\x14\x17\xb5\xc8\x3f\xb2\x85\x27\x69\xac\x52\x23\xed\x64\x2a\xc4\x2f\x75\xf5\xeb\xfa\x61\x84\x36\xdb\xf5\x1a\x85\x3c\xdd\xf9\x90\x18\x67\x22\x4a\x2b\xdb\x86\xe0\xf0\xb5\xff\x75\x31\x48\x6c\x6f\x5f\xca\xc6\xc0\x46\x04\x6e\x18\x2f\x55\xe5\x16\xa4\x34\x49\xcc\x96\xbf\x5e\x6e\xb6\xdd\x0d\x76\x7f\x4f\x83\x00\x3c\x9e\xc2\x55\xaf\xdd\x9e\xcf\x8b\x7d\x5f\x88\x4a\x49\x20\xb1\xf8\x77\x68\xf8\x3b\x8c\x4c\xf8\x26\xb7\x80\x44\x1a\x06\xfc\xef\x87\xaa\xfe\xc9\x6b\x05\xce\x81\xec\xe6\x6e\x8c\x7e\x2f\xc9\x44\x08\x3e\x7c\x5a\xbb\xc2\x4d\x4a\x59\x80\xcb\x3f\x94\x6a\x2d\xfd\xe5\x33\x15\x61\x61\x1f\x1d\x14\x5f\x8a\xaa\x75\xb6\xbc\xdd\x4f\x18\x82\x49\xff\xf9\xaf\xf9\x3c\x6e\xf4\xdd\x59\xe8\x36\xc4\xf6\x79\xf7\xf0\xc3\x35\x25\x7d\x53\x26\xe5\x41\x88\xdd\x3c\x0c\x00\xc6\x3f\x9a\x47\x80\xa8\x2c\x5d\xd5\x12\x56\xa7\x73\x3b\x9d\x66\x5c\x47\x58\x6f\x7b\x29\x2e\xcd\xf0\xdd\x15\x41\x80\xfb\xe6\x48\x3e\x62\x5a\xcb\x19\x5c\x83\x08\xb5\x0a\xfc\x0d\x6a\x40\x5e\xda\xfc\x1d\x2c\x7d\xd1\x8d\x49\x32\x5c\xe6\x0f\xb5\x57\x0b\xe8\xd3\x90\x54\xd0\x04\x51\xb9\x5d\xcc\xc6\x5b\xf9\xfa\x85\xe7\xe5\xe0\x20\x8b\x26\x00\xdf\x9a\x97\xf2\xd5\xcf\x46\x91\x11\x8c\xac\x9e\xae\xf7\xbc\xe4\xa3\x79\x24\x32\xa3\x98\x7c\x69\x90\x3a\x7d\xe9\x3f\x23\x8c\x3f\xf9\x89\xbf\xc1\x42\x55\x88\x6a\x1a\x41\x57\x52\x3b\x50\x86\x11\xb2\x1f\x0c\x6f\x02\x83\xc9\x49\x91\x30\x95\x3c\xc2\xf4\xe7\xd6\x44\xf1\x2f\xee\x99\xf6\x3c\x2a\x34\xce\x7d\xba\xae\x4e\x53\xab\xb0\xee\x68\x26\x7b\x30\x8c\x33\xe6\x5c\x99\xfd\xe2\x26\x35\xfc\xb3\x5d\x7a\xfa\xf7\xb9\xbe\x4a\xaa\x88\xc7\xea\x0e\x3c\xc9\xdc\xc1\xcc\xe0\x93\xcf\x97\xe6\xf5\x77\x28\x55\x35\x55\xaf\x1a\xbe\x22\x8a\x67\xdc\x38\x85\x6d\x9e\x36\x88\xa6\x58\x2c\x97\x9b\xef\x8e\x8a\x46\x52\x05\xf1\x00\x53\xbd\xcf\xdb\x62\xea\xd6\xe7\x07\x72\xdc\xc5\x9d\xda\xf3\x87\xf7\xfa\x93\x59\x85\x91\x33\xce\x2a\x59\x95\xf8\xc4\x64\x51\x35\x79\x79\x1c\xae\xf1\x40\x63\x30\x5e\xbf\xc0\xdf\xfd\xaa\x05\x99\x89\x61\x8d\xa5\x0f\x1f\x77\xda\xed\x18\x1d\x44\x49\xdf\x79\xc2\xb5\xbb\xbe\x9a\xbe\x6b\xb3\x1c\x41\x1d\xc7\xb7\x5b\x87\x0a\x61\xf8\x22\x3f\x3e\x56\xd5\x79\xf2\xfc\x75\xc4\x91\xf9\x0d\x65\x5d\x15\xfe\x7a\x74\x0a\xb8\xfb\xf7\x5e\x50\x61\xf0\xb4\x9f\x60\xef\x08\x09\x42\x2d\xba\x61\xef\x39\xfc\x34\x62\x05\xa3\x4b\x26\x81\xa4\xd8\x78\xb6\x08\x84\x71\x61\x8c\x04\xca\xd8\xb8\xc9\xea\x74\x1e\x02\xa6\x08\x09\x79\x86\xb2\x1e\x20\xab\xe6\xda\xb4\x70\x1a\x40\xae\x08\x09\x45\xac\x4c\xc4\xd5\x05\x23\x73\x1d\x63\x12\x09\xa3\xfd\xaa\xaa\x59\x20\x27\x21\x11\x64\x5c\x3b\x15\xe3\xba\xa9\xca\x6e\xcb\xe1\x6f\x30\x4f\x24\x27\x24\xd2\x86\x26\x3e\x54\x0a\xdf\xb5\x5d\x66\xec\xae\x2a\x4e\x4c\xad\xc0\x20\xa4\x0c\xbb\x60\xd1\x6e\x01\x45\x25\x07\xba\x91\x84\x24\x91\xb1\x4c\xb3\xfe\x08\x86\x9b\xf8\x31\x51\x75\xfc\x38\x49\x12\xa5\x28\x59\x70\x97\x23\x04\x75\x5d\xaa\xfc\x58\xf9\x53\x53\xab\xa8\x51\x86\x11\x43\x1b\x17\xb7\x2d\x24\xff\xf2\x43\x52\x1c\xe2\x4a\x20\x8b\xb6\xe5\xf2\xcd\xd7\xba\x49\xa2\x18\xd2\xb9\x9b\xd7\xea\xe7\x6b\xd5\x9c\xf3\x76\xa2\x0d\x41\x48\x02\x21\x04\x2e\x15\xc4\x6b\xdd\xff\xac\x26\x37\x38\xa5\x01\x62\xb5\x0c\x20\xb3\x59\x97\xbd\x45\x08\x21\xa9\x12\x3c\xb0\x41\x86\xf3\x7c\x54\x2e\xa1\xff\xe0\x09\x90\x28\xc6\x6e\xec\x6a\x2f\x78\xf9\xf6\xa3\x72\xf4\xd0\xee\x08\x60\x9c\xf8\xbd\x8b\x57\x66\x7b\xf6\x6e\x20\x25\x54\x0c\xc5\x7e\xef\xa0\x7d\xa8\x6a\x07\xfe\x2f\xf8\xd5\x40\xda\xc6\x9f\xa2\x4c\xc7\xbd\xbb\x07\xa2\x1e\x6a\xcb\xf0\xb8\xed\xd9\x13\x16\xa5\x28\x4c\x8b\xb0\xbc\x17\xa8\x7b\x21\x7e\x42\x18\x4f\xb1\x82\x37\x91\x1a\x65\xfd\x71\x63\xbe\x2f\x2e\xd7\xb9\xba\xb0\x1b\x05\xa1\x36\x2a\x3e\x5d\x68\x0a\xcd\x40\x3e\x9c\x90\x2c\xd0\x88\x0d\x2c\xe1\x57\x6b\xd3\xe7\xc9\x05\x66\x61\x34\x58\x7d\xcf\x2d\x38\xc6\x2c\x21\x3c\x05\xd4\x78\xfa\xc9\xdf\x61\xc9\xcf\xa1\xff\x3b\x11\xb8\x83\xe4\x0d\x32\xcc\xfc\x8d\xe7\x9c\x62\x4b\xee\x7c\xa9\x61\x02\x02\xb0\x23\x84\x4e\x10\x0e\x77\xff\xf8\xcd\x7d\x48\x26\x21\x26\x3c\x8f\xbc\x3e\x76\xdf\xe2\x15\xd0\x0d\xf2\x67\x52\xa5\x27\x92\x10\x67\x35\xf3\x54\x95\xc6\xb1\x03\x78\x5b\xd5\x73\xa6\xa9\x84\x48\x0e\xb8\x22\x9d\xf9\xf5\xa1\xaa\xdb\x4b\x39\x7d\x3e\x2a\x14\xcc\x2c\x3a\x97\x12\x85\x1a\x67\x60\xd5\x84\xa8\x84\x60\x08\x78\xbc\x9e\xc6\x36\x6a\xdd\xd5\x30\x04\x57\x6d\x57\xff\xf3\x7d\xb5\xdb\x1f\xb6\xab\xbf\xaf\x96\xfb\xd5\xfd\xe1\xee\x8f\xc3\xd7\x8d\x93\x77\x26\x44\x29\x8e\x31\xd6\x4f\xd4\xbe\xef\xeb\xef\x44\x29\x40\x38\x12\x46\xa2\xe6\x85\xeb\xb7\x34\x02\x41\xa0\x99\x9b\x5b\xa7\xbc\xbc\xe7\xcd\xab\xe8\xbd\xc1\x08\xd1\x69\x88\x78\x8a\xc5\xaf\x1c\x56\xdb\x25\x8d\x42\x97\xf4\xf4\x23\x62\xb4\xde\x95\x97\xba\x97\xc7\x22\x44\x13\x70\x4c\xd8\x75\x63\x66\xbd\x3f\x44\x0d\x4b\xb9\x32\x8a\x30\xed\xff\xa0\x99\xec\xec\x96\x67\x3e\x41\x03\x4d\xa5\x97\x29\xfc\xca\x27\x99\x3f\x0d\x13\x8d\x64\x00\x68\x5f\x0f\x5e\x6b\x8a\xd0\x90\xaa\xd8\x23\xfa\xa1\xc9\x15\x94\x5d\x86\xfa\x04\x0d\xbf\xf5\x7b\x1f\x06\x95\x34\xe4\xd2\x29\x6c\x21\x81\x1d\xf3\xe4\x69\xa1\x87\x86\x16\x5b\x58\x95\x18\x51\x61\xdd\x6c\xf5\x0b\xe4\x8d\x80\xc2\xe8\x9d\xa0\x51\x94\xc6\xa1\xfb\x31\x77\x55\xd5\xbd\x65\xb7\xcc\x3d\x42\x23\x30\x81\xcb\x17\x68\xef\x0c\xcf\xc7\x85\xb1\xe3\xf3\xc5\xda\x18\xa2\x34\xa3\xca\xe8\xcd\xfa\xee\xb3\x6e\xdb\x5f\x19\xaf\x56\x34\x49\x82\xd8\xa8\xda\x56\x05\xf0\x72\x5f\x7d\x5f\xfb\xaa\x03\x4d\x98\xe2\xae\x2b\xd4\xfd\xa6\x71\x0c\x4e\x13\x1e\x60\x6d\xd6\x78\xc0\xcc\x2f\x87\x34\x8d\x12\xd4\x44\x42\x10\xe1\x2c\xb7\x75\xfc\xcc\x53\x46\x12\x43\xe7\x7d\xaf\xde\x60\x40\xfb\x1d\x45\xf4\xe3\x5b\x41\x94\x31\xba\xf9\xb2\x5d\xb8\x0c\x87\xd2\x6e\xff\x70\x5c\xc4\xf3\x9e\x8b\xf9\xc0\x85\x52\x45\xa8\x71\x1b\x93\x95\x82\xb1\xfc\x90\x1d\x92\xc5\xc4\xe9\x87\x3b\x98\xa8\x77\xb8\x0f\x47\x92\x35\xb7\xff\x6b\x4f\xc1\x95\xe9\x13\xf2\xbc\x9e\x22\x65\xa8\x90\x1a\x53\x96\x2e\xbe\xb1\xf9\xfc\x12\x41\x0f\x05\xa8\xc7\xfc\xe6\xfd\x90\x89\xce\x48\xdf\x58\x5f\xb7\x70\xfa\xcc\x1e\x83\x50\xa9\x34\xce\xd4\x2e\x38\xdd\x14\xc6\x5b\x67\x3c\x42\xc5\x29\x66\x1a\xdf\x4f\x5d\xe0\xfa\x0e\xc5\xb3\x8f\x92\xa8\xb2\x2c\x1a\x2c\x00\x0c\x30\x62\x14\x02\xe3\x23\x85\x2b\x8c\xa9\x89\xe6\xe5\xf1\xbe\x1a\xda\xc3\x13\x0a\xb1\x42\x78\x3d\xb4\xaf\x7b\xfe\xab\xe7\x75\x10\x0a\x8c\x73\x63\xc6\x92\x6b\x3d\xee\x11\x50\x00\x95\x38\x67\x33\xdc\xda\x0d\x34\x64\xf6\x01\xea\x58\x22\xeb\x84\x8b\xa9\xa9\x3f\xa1\x5a\x2a\x9c\xaa\xe6\x56\x61\x19\xeb\x73\x8d\xd6\xf1\xb9\x59\x40\x25\xcf\xfc\x9c\x2d\xb8\x7c\x2b\x6e\x1e\x08\x0b\xa3\x68\x54\xcd\x29\x9b\x41\xcf\x70\x6e\x5d\x63\x21\x64\x08\xef\x3a\x28\x43\xba\x36\x1a\x04\x83\x05\x9a\x85\x3a\x33\xd2\x27\xfc\x1d\xba\x95\x17\x93\xef\x9b\x34\x76\x38\x1b\x59\x14\x0a\x8d\xc9\x45\xae\xa0\x9a\x84\xaa\x2c\x4a\x04\xa6\xb0\xdb\xd5\xe2\x65\xb5\x3d\xac\x9f\xf7\xdb\xd5\x8b\x2f\x07\xb0\x48\x66\x60\x82\xc5\x46\xe6\xa5\xfa\xbd\x6a\xc7\x5a\x2a\x84\x45\x10\x65\x36\x1a\xf3\x05\xe9\xb1\x14\xe4\x78\xde\x77\x1f\x40\x54\xd7\x8b\x67\xd8\xda\x03\x31\xd3\xa8\x7f\xbb\x14\xdd\x8f\xfa\xdf\xd1\x0e\x09\x4b\x38\x37\x7d\x65\xdc\x50\x17\x45\x0d\x5c\x5d\x5f\x78\xae\xee\xfa\x9d\x86\x25\x8a\x22\x24\xb4\x4b\x46\x0f\x6b\x27\x2b\x8f\xef\xe5\xa1\xad\x0e\x8f\xb9\x06\x79\x95\xbe\x3c\xcb\x52\x6d\x92\xe0\x5d\x5e\xc8\x3f\x4f\x84\x3f\x8d\x9c\x19\x11\xd6\x15\xbb\xe5\x47\x38\x44\x43\xe6\x04\x61\x2c\xe5\x18\x5e\x5a\xab\x08\xf7\x57\xce\x45\x6f\x70\x6a\x5d\x67\xdf\x27\x51\x0e\x63\x2a\x30\x35\x33\xcc\x9d\xdf\xe0\x3a\x3d\xae\x59\xa6\x9c\x0d\xd6\x04\xa9\xc7\xb2\x20\x44\x69\x3e\xae\x94\x41\x1b\x0f\x31\x85\xa3\xfa\x19\x73\x9f\x08\x33\x64\xcc\x7c\xeb\x42\xa7\x41\x85\x85\x65\xa1\x49\x62\x2f\xa5\x82\x1a\x1d\x7f\x30\xef\x98\x42\x23\x58\xc6\x38\x55\xce\xa1\xd1\x5f\xcf\x3f\xa3\x7f\xb9\xe3\x59\xc4\xcc\x02\xfd\x0e\x65\x7b\x05\x64\x02\xbb\x63\x9c\x13\xd3\xfd\x58\x38\xeb\xbd\xcc\x1d\xe3\x09\x0d\x95\x13\x05\xc7\xc8\x14\x89\xd6\xfc\xaa\xf8\x6d\x69\x70\x7c\x8b\x78\x6a\xa0\xc2\x06\xfa\xd8\x2d\x84\x2f\xab\xc7\xcd\x38\x36\x9b\x3c\x4e\x4e\x4c\x3b\xbf\x5b\xfb\xbb\xdd\xfe\x1e\x8a\x96\xf7\xfa\x2a\x5d\x34\x2d\x63\xe1\x35\x42\x8c\xe8\xd2\xfc\x9b\xc1\x33\x12\x06\x13\xc7\xba\x66\x7f\xd3\x70\xb6\xa3\x65\x1c\x61\xff\x5c\x1e\xf9\x10\xfa\x67\x8f\xaa\x98\xa3\xc8\x26\x98\x3e\xdc\x64\xde\xcc\xff\x14\x20\xc6\xa5\xa9\xaf\x45\x75\x77\xc0\x8a\xe0\x8c\xdd\xe5\x08\xd3\x41\x6a\xa6\x04\xb4\x7e\x46\x8c\x33\x6b\xa6\x03\x86\xf9\xd5\x13\x56\xbd\xa0\x6d\xfb\xb0\x7a\x54\xeb\xff\x60\xa2\x68\x11\x21\x26\xe1\xc4\xdf\xac\x26\xde\x5f\x4a\x4d\xb3\x80\xc5\x31\xf7\x52\xa2\x67\xa8\xdb\xeb\x96\x77\x5b\xcf\xfe\x72\xf6\x53\x3a\x0b\x54\x86\x36\xc9\x5b\x84\xe1\xcb\x8a\xa3\xe2\xaf\x3d\x18\x52\xc0\xf6\x7d\x9b\x43\xbd\x29\x3d\x5f\xdc\x1f\x16\xe0\x2c\x39\x0e\xbc\x4b\xf7\x3e\x58\xe3\xb2\x18\x8c\x4f\x7d\x09\x79\x5d\x95\xf9\xaf\x97\xba\xd2\xf9\x98\x15\x49\xb2\x24\x48\x31\x94\x3e\x40\xa9\xee\x2f\xad\x7c\x9d\x64\x4c\x93\x9f\x97\xc4\x91\xb4\xa1\xf9\xd3\xf5\xb9\x8b\xfd\x8a\x7b\xc4\xae\xf6\x27\x54\xa1\x03\x73\x14\xbc\x69\x3d\x17\xb9\xca\xbd\x43\x07\xc9\x12\x6d\x72\x8b\xbe\xb6\xf2\xb8\x7d\xfe\xc7\x07\xc2\x27\x24\x4b\x03\x82\x35\x14\xf3\x52\x1e\x5e\xa0\x3e\xdc\x63\x47\xf0\x70\x0f\x28\xe4\x3a\x88\xf1\xb3\x34\x55\x88\x35\xfa\xc7\x1f\xcb\xa5\xff\x1b\x4d\x11\xee\x77\x82\xfa\x08\xea\x29\x2f\xa1\xb6\xe6\xdf\xd5\x04\xaa\x94\xa5\x32\x30\xbe\x8a\x48\x1b\x5e\xfd\x27\xca\xcc\x5e\x13\x65\x7f\x1b\xfd\xeb\xf6\x9e\x8c\xa8\x10\x37\xaf\x73\x5d\x49\x68\x9a\x1b\xd9\xf5\xd9\xd7\x3d\x23\x5a\xe0\x42\x7c\x20\x07\x5d\xe7\xe0\x45\x2e\xbb\x23\x8a\xf4\xeb\xed\x21\x97\xd5\xc1\x20\x02\xc6\x2b\x58\x46\x23\x65\xa9\xa1\x5c\xad\xba\x45\xaa\xcb\x97\xbb\x4d\x4b\x74\xdf\x7e\xe9\xb9\xdc\x24\xa3\x99\xc8\xac\x27\x7f\x9b\x2f\x94\xfa\xb8\x67\x9f\x51\x91\x2a\xa3\xa1\x6f\x72\xfc\x0f\xea\xfe\x19\x4b\x23\x57\x99\x46\x52\x18\x3f\xc1\x44\xf2\x87\x64\x8c\x85\x44\x0f\x1a\x90\x6b\xb5\xd1\xcb\xed\x28\x4b\xca\xb2\x38\x02\x9b\x91\x3d\xd4\x00\x3b\x80\xfe\x4e\x64\x54\x23\xb6\xa3\xae\xaa\xf6\xfb\xfe\x1f\x9b\x27\xa8\xdf\x0a\xd8\xd7\x00\x98\x6d\xb9\x51\xc0\x64\xec\xeb\x9b\xb6\x41\x69\xb6\xa9\x69\xdf\x3a\xe3\x91\xc2\xbb\xfe\x08\x1f\xb0\xa2\x49\x26\x12\xe3\x38\x99\x37\xcd\xc5\x29\x2b\x0e\x85\x28\x48\x26\x32\x81\x1e\x42\x60\xa3\xed\x2e\x46\x32\xe3\x10\x88\xdb\x37\x56\x33\x15\x64\x52\xf7\x6b\xaa\x7a\x18\xe8\x85\xb8\x21\x91\x31\x05\x2f\x72\x6d\xc5\x7c\x0e\xef\xfe\x18\x4b\x70\xcf\x54\x5d\xd4\xfa\x01\xb7\x20\x83\x20\xc1\x95\x58\xd9\xce\xec\x60\x43\xcf\x20\x21\xd8\xed\xf3\xfc\x9c\x0f\x48\x19\xd3\x53\x66\x31\x22\xe1\x5f\x56\xdb\xdd\xe6\x79\x31\x8c\x8f\x32\xad\x4c\x89\xef\x1b\x94\x6d\xcd\xc7\x71\xd1\xf8\x2c\x5a\x4b\x2c\xa2\x59\xe6\x1a\x16\x01\x51\x42\xd5\x2f\xe3\x3c\x48\x23\x67\x29\x61\xe9\x0c\xeb\xfb\x21\xde\x8b\x87\x60\xd4\x85\x4b\xf8\xe9\x38\xa3\x36\x02\xe0\x11\x95\x7a\xc0\x4a\x5c\x19\xae\x43\x83\x20\x29\x3b\x24\x8e\x23\xc2\x7c\x31\x7a\x10\xdd\xf3\x98\x6b\x53\xe0\x43\x09\x02\xa3\x25\x30\xe4\x8f\x11\x8e\x20\x83\x91\x41\xae\x81\x17\xfb\xe3\x69\x80\x52\xb4\x1a\x5a\xf9\x8a\x6d\x6e\xa4\x20\xdc\x5d\x77\x25\x3f\x37\xaf\xd5\x8c\x03\x3c\xe1\x69\x60\x18\x09\x7d\xd1\xb0\x7b\x63\x46\xdc\x85\x61\x5e\xc6\x53\x45\x51\x86\xe9\xd0\x2d\xb7\xf8\xf2\x6f\xab\x6a\x46\xa7\xd0\x0e\x27\x81\xc1\x3b\xbf\xd4\xb0\x3f\x82\x11\x4a\x72\xd7\x4b\x54\xe2\x16\xee\x95\xd1\xfc\x1e\x06\x59\xfe\x67\x53\x12\xa3\xe3\x23\x5c\x64\x01\x2a\xe7\xe5\x7d\xde\xb4\x9f\xbd\x32\xe3\x87\xce\x99\x06\x24\x07\xc0\xfb\x57\x5e\x0f\x45\x98\x27\xe3\xb2\x20\xc2\x32\x9b\x41\xf7\x7e\xa6\x02\x31\xc4\x73\xb8\x0f\x93\xc8\xd1\x76\xd1\x26\x63\xca\xca\x1b\x4d\x68\x9e\x89\x48\xf5\xfa\xb6\xfb\xc5\xe6\x53\xac\xe7\x04\x44\x35\xb9\x6c\x1e\x85\x44\xba\xbb\x38\x75\x96\x22\x9c\x67\x04\x25\x4b\x96\xdb\x9d\xff\x13\x07\xd6\x97\xc4\x27\x2f\x11\x97\xa6\xc6\x6f\x64\x4b\xdb\x7b\x7e\xdd\xfb\x0f\x8a\x8c\x80\x29\x5f\x34\x2d\x7f\xc3\x16\x3c\x4c\x29\x5d\x5c\x70\x2e\xb8\x0d\x15\x0e\x92\x9f\x0f\x0e\x41\xc5\x65\x48\x79\xff\xbd\x87\x21\x60\x85\x4b\xc9\x11\x98\x63\xf7\x95\xbb\x89\xb3\x18\xe1\x52\x07\xd2\xb8\xd2\xb5\x50\x9f\xf2\x12\x36\x97\x56\x56\x03\xa0\x1e\xbe\xa4\x76\xf7\x60\xfe\xfd\x53\x51\x80\xe5\xbe\x77\x23\xd8\x38\x55\xf9\x9c\xdc\x4b\x95\x0a\xe9\x54\x67\x91\x7d\xd2\x23\x0c\xc7\x57\xa3\x14\xc4\x91\x63\x69\x7f\xcd\x95\x82\xf2\x09\x9a\x86\x1f\xa1\x19\x2e\x26\x10\x18\xdc\xa7\x65\x0e\x71\xf9\x36\xd5\xbf\x70\x03\x43\x9e\xd1\xc1\xb6\x34\x57\xfd\xe4\xc0\x32\x91\x8c\x4c\xf1\x4a\x5d\xad\xcb\x91\x1f\xb7\x1b\x9a\x45\x4e\x43\x15\xcb\x1d\xf3\xaf\x21\x64\xa6\xf0\x6e\x4a\xe8\x26\xa4\xf4\x71\xe8\x5f\xb2\xf8\x21\x5c\x47\x0a\x33\x84\xfd\x76\xbd\x1c\xae\xca\x5c\xc7\xa9\x1e\x2d\xf4\x0f\xe0\x5e\x4a\x11\x64\x9e\x39\xbd\x98\xb3\xb4\x27\x22\x24\x41\x64\x6b\xee\x9b\x12\xb6\x5c\x88\x29\xa9\x4e\x84\xcc\xc8\x8c\x3f\x56\xe5\x71\x0f\xf5\xc9\xca\xe4\xdb\xed\x71\x14\x41\x89\x50\x26\xb8\x6a\x2d\x4e\xfe\x95\x13\x21\xd0\x50\x5a\x33\xb0\x73\xf5\x41\x9b\x4e\xc4\x29\x73\xe5\xd9\x45\x51\x08\x68\xef\xae\x5f\xda\xeb\x19\x7e\xeb\xd7\x44\x91\xa6\x1a\x4b\xff\xf8\xd5\x2b\xdb\x39\xc5\xf8\xe7\x63\xa1\x26\x22\x88\xce\xb0\x5f\x86\x52\x90\x96\x49\x72\x6b\xd0\x37\xba\x2b\x34\x04\x24\x3f\x9b\x69\xbe\xb6\x70\x89\x8f\x43\x27\xc1\x22\x8a\xac\x0b\x01\xdd\x5c\xd9\x9d\xa1\x3e\x15\x7d\x8b\x46\x64\x69\x80\x17\x7e\x90\xd5\xe9\x7c\x69\x61\x59\x55\x85\xaa\x7e\x96\xbd\xfa\x7d\x3e\x51\xb8\x20\x22\x23\x46\x37\xd5\x1a\x2f\xf2\x5f\xcf\x97\x93\xa5\xad\xfa\x11\x1a\x62\x67\x43\x8f\xe6\xbb\x1f\xac\x60\x1f\xf2\x5a\x66\x40\xe9\xf3\x58\x15\xf7\x8d\x34\xc2\x4a\xce\xc5\x86\x7d\xe3\x89\x23\x78\x9a\xe0\xda\xd1\x9c\x01\x5d\x3e\xba\xfd\x78\xfc\xa3\x04\x49\xec\xd4\x42\x0d\x35\x40\x81\x54\x87\x71\xfc\x13\xfa\x94\x10\x8c\x09\xfb\x7b\x9f\xf2\x72\x35\x4a\x30\xdd\x10\xc8\x94\xf2\x9e\x85\xfb\xd7\x1a\x9a\xd7\xaa\xf0\xcf\x41\x46\x12\xc9\x04\x4f\xbc\x96\x50\xf0\x03\x2a\x7d\x77\xd9\xf9\x9f\x62\x46\x84\x4c\x23\x14\x73\x5c\xd6\xd7\x33\xfc\x1a\xce\x40\x21\xa9\x42\x6a\xc9\x03\xcf\x6b\x2f\xc7\x30\x96\xd8\x23\x42\x0a\x89\x91\xe3\xa9\x6a\xda\x5d\x7e\x2c\x73\x9d\x4b\x5e\xb6\x77\x37\xd3\x4d\x4a\xa3\xe4\xb7\xdb\x2f\xb6\xe8\xe2\x7b\xb7\x78\xfe\xb6\x72\x84\x2c\xa1\x02\xc0\x96\x7e\x09\x3f\x47\x3a\xa3\x73\x50\x03\xa1\xc2\x10\x4b\x5d\xdc\xa1\xff\xee\x2e\xd7\x75\x69\x88\xaf\xee\x84\x3a\xd6\x56\x4e\x13\x01\xa8\xbc\x3e\x4d\xbb\xc5\x42\x13\x89\x38\x03\x2c\x36\x1e\x14\x70\x55\xe4\xa5\x5f\x64\x34\x0d\xb0\xca\xe8\x14\x05\x7e\x1b\xda\x34\x65\x1e\x6b\x37\xa6\xe8\x38\x4e\xb8\x0c\xc2\x04\x61\xd1\x48\xc7\x38\xcd\x69\x31\x8f\x9e\x83\x0c\x92\x14\xc3\xf8\x3a\x3f\xbe\xb6\x34\x1b\xdf\x3c\x19\x00\xc1\xb9\xae\xec\x3c\x1f\xec\xd0\x32\x80\x0c\xe1\x4a\xa6\x2f\x72\xbf\x3b\x34\x80\x0b\x88\x71\x69\x69\x30\xaf\x18\x9f\x2d\x24\x01\xde\x9a\xee\x2c\x3b\x68\xfb\x3c\x5d\x86\xc2\xf6\xd9\x6a\x38\xc3\xb4\x65\x2a\x43\x45\xb5\x0d\x15\xd0\xb9\x7a\x5d\x2a\x94\x63\x1b\x8f\x8a\x42\x19\x19\xaf\x93\x25\xd4\x6d\xae\xf3\x41\x95\x62\x7c\x1d\x51\xc4\x31\x14\x36\x29\xb3\x6c\x83\x5f\xcf\xd0\xfe\xac\xea\xb7\xe1\x1b\x26\xa3\x94\xdb\x6d\xbf\xe5\x05\x1a\xf7\x45\xae\xe6\xdd\xf8\x31\x4c\x8d\xb7\xb6\xdd\x99\x4b\x68\x5e\xf3\xf3\x0c\x18\x4e\x46\x0a\x30\x54\xfe\x3d\xf7\x29\x97\x8c\x74\x62\xcb\x2f\xa5\x3a\x55\x25\x5c\x91\xd1\x39\xbe\xde\x38\x36\x68\xf6\x55\xfb\x3a\x02\x0e\xc9\x38\xe5\xc8\x26\x44\x9a\xb9\x35\x7b\xfb\x78\x55\x95\xb1\x48\x90\x1b\x8f\xe6\xa4\x26\x7d\x59\x5c\x5a\x7f\x29\x89\x75\x1e\x7f\xdc\x2c\xbf\x75\x13\xe5\xfb\x33\x32\xf0\xf6\xeb\xa7\x95\x1f\xc2\x13\x44\xcc\x1d\xb0\xbc\x28\xbb\x25\x79\xba\x46\xce\x4c\x76\x99\x48\x23\xa6\x8e\x05\x2e\x6b\xb7\xa3\xa6\xbf\x32\x0d\x8c\x40\xa8\xe4\x45\xb1\x28\x8a\x2e\x9c\x7f\x82\x1b\x4a\x85\x1b\x1c\x05\x21\x19\xc0\x57\x3f\xa2\x1c\xba\xe1\x49\x18\x67\x06\xe5\x70\xe2\x4d\xf3\x8f\xd1\x5d\x4c\x29\x47\x6c\x41\x9b\x9f\xfc\xde\xf4\x02\xb5\x33\x65\x22\x32\x85\x2c\xb1\x41\x72\x3e\xb1\xb7\x98\xbc\x59\x24\x36\x76\x18\xe8\xcc\xd5\x65\x2d\x07\x1e\xd2\x6e\x26\x1c\xec\x38\x77\x4a\x1a\x85\xc6\xcc\x09\xdd\x7f\x9d\x54\xda\x07\x71\xb7\xa4\xa9\xc4\x10\xbf\xad\xf3\xe3\x11\x6a\xb3\x45\x8f\xee\x30\x95\x09\x76\x5f\xac\xa8\xdb\x46\x4f\xfa\xcc\xb2\x5b\xeb\x43\xe7\x2a\x59\xd5\x53\x28\x96\x1b\x95\x29\xc4\x92\x60\xa9\x4e\x6b\x94\xb3\x5c\xe6\xed\xf5\xa1\xaa\x77\xd5\x09\xaa\x72\xd4\x0b\xbb\xbd\xcf\x4c\xcb\x5e\x4e\xe0\x9c\x1b\x07\x0a\x87\x58\x1b\xdf\xaa\x4c\x13\x54\xa7\x69\x5e\xa1\xd0\x73\x96\x82\xa4\x0b\xad\x51\xe8\xe8\xc0\x45\x55\x77\x61\x0c\x86\x8c\x7e\xf2\xf1\x40\x27\xd6\x57\x13\xb3\x46\x7f\x40\x64\x41\x88\x1b\x1b\xd7\x30\x78\xcf\x26\xcf\x4a\x48\xc1\x1d\xb0\x70\x53\xc2\xc0\xdb\x98\x48\xa1\x8c\x42\xb6\x21\x4a\x77\x3b\xde\x5f\xca\xd9\xa4\x80\x38\xc5\x1d\x9b\x17\xe0\xaa\x7f\xf6\x90\xe2\xa9\xd6\x0e\x29\x70\xcf\xaf\xfe\x6a\x21\x24\x91\x41\xf8\x62\xd1\xeb\x89\xd7\x6f\x68\x94\xf1\x27\x20\x39\xf3\x69\x15\x24\x0a\x25\x9f\x7f\xba\x5e\x0d\xa8\x01\x41\x6a\xd2\x1d\x52\x41\x96\x46\x16\xad\xb1\xdf\xef\x87\x5c\x52\x15\xf0\x98\x1a\x7f\x87\x6e\xdf\x7a\xa9\xaa\xc2\xd8\x97\xff\x36\x07\x37\x55\x81\xd2\x8a\x5b\xb5\x2f\xbb\x37\xdc\xc6\x5c\x2a\x0c\x32\x04\xf5\xbe\x1b\x6b\x0d\xe0\xa7\xe9\x00\x1a\x19\xf0\x82\x89\x70\x46\xb0\x2d\x15\x52\x89\xcb\xfe\xc1\x8a\x23\x7c\x5c\x20\x51\x21\xe3\xa8\x9a\x53\xe6\xaf\x79\x71\x39\xdd\xb9\x59\x30\x5e\x80\x55\x14\x70\x6c\xfb\x77\x37\xf8\x50\xe9\x83\x81\x7c\x75\xff\xa7\x79\xcd\x6b\x5f\x53\x55\x11\x11\xd2\xad\x2e\xd6\x13\x77\xa8\x82\x37\x3b\x49\x55\x24\xc1\x29\x8f\x1c\xce\x55\x55\x1c\xce\xbd\x48\xf5\xa0\x12\xa1\xe2\x40\x60\xb5\xc5\x64\x8c\x4f\x79\xd9\x22\xf1\x6e\x5c\x96\x57\x71\x62\x5c\x6d\x1c\x91\xcf\x5d\xc3\x88\x7c\xa9\x62\xc1\x52\x5b\xe9\xf7\x34\x97\x6e\xca\x16\x55\x39\xa0\x9f\xba\xc1\x9a\xd0\x78\x54\x29\xfe\x62\xc3\x46\x35\x92\x92\xb3\xc3\x93\x50\xe0\x9a\xd9\x7b\x1f\x78\xf5\xc0\x31\x88\xdb\xd5\x46\x55\x92\x84\xf8\x26\x17\xf9\x29\x6f\xc7\x0a\x00\x2a\x51\x51\xe8\x80\xe0\x16\xe4\x55\xf9\xfe\xe2\xfc\x3b\x96\x26\xc6\x10\x59\x41\xb1\x33\xef\x87\xa9\xc8\x8d\x6f\x7b\x9a\x6a\xec\x12\x88\xcb\x35\x0c\xde\x8c\xcc\xa1\x7f\x90\x24\xd4\x34\xb0\xba\x03\xad\x45\xa3\xe6\xed\xb5\x7b\x55\x6b\x3f\xc6\x46\x25\xdf\xef\xf6\x7f\xde\x96\x54\x84\x70\xe9\xcb\x5d\xb3\x5e\x31\x93\x57\x93\x12\x4e\x87\x04\xd0\xdd\xb5\x6c\x5f\xa1\xcd\x27\x8d\x3b\x45\x99\xf1\x57\xf1\x80\xbf\x1f\x90\x3b\x28\x95\xa2\x5a\xc5\x7d\xa6\x86\x6e\x82\xe3\x4f\x33\x9e\xe0\x04\xe8\xcd\xf1\x0f\x77\xdf\x9d\x64\x91\x62\x2a\x41\xec\xc7\xe2\xe9\x6e\xb1\xdb\x2d\xee\x37\xdb\xc3\xe6\xd9\x6d\xea\x2a\x4b\x2c\xe7\xcb\x26\x53\x53\xf1\x5a\x17\x5b\xaa\x2c\x05\x81\xca\x47\xbb\x1e\x66\xe7\x4f\x42\x8d\xce\x64\xed\xdc\x23\x6e\xe0\x29\xc3\x8d\x46\x65\x42\x04\xba\x07\xb7\x7e\x2f\xdb\xbc\xe8\xc9\x80\x8a\x5b\x1d\x79\xae\x94\xb5\xac\x78\xa8\xea\x19\x05\x93\xc9\xbd\xe6\x22\xc3\xa4\x00\x91\x0a\xfb\x9a\xcb\xb7\x79\xfa\xa2\xe2\xca\x10\x22\xbd\x06\x78\x5d\x4d\x97\x26\x11\x33\x69\x90\xc3\xa6\x09\xd1\x0d\x99\x59\xe2\x04\xa7\x18\xd3\xad\xfe\xe1\xae\x5d\xe8\x84\x39\xb8\xce\xe3\x72\xf2\xb6\xca\x98\x60\x4f\xf5\xe0\x90\xc1\xdf\xeb\x91\x60\x27\x51\x92\xa5\x08\xa3\xf9\x09\xf9\x7e\x50\x69\x52\x32\x33\x6b\xa9\xb8\x5c\x77\xa8\x56\xb5\x18\x21\xf2\xd8\xfc\x8e\xac\x14\xa1\x11\x56\x21\xbb\xc0\xe5\x89\xe7\xe5\x70\x52\xaa\x8c\x33\xab\x84\x74\x67\x18\x2f\x7e\xe6\x80\x88\x22\xeb\x42\x62\x22\xdb\x27\x7e\x3e\x77\x6b\xca\x5f\x60\xa5\x2a\x00\x8d\x5b\xab\x95\x5d\x18\x3d\x2d\xff\x36\x69\x1d\x63\xec\xec\x77\xae\x29\x41\x6e\xb0\x1c\x42\x90\xa6\x24\x72\x68\xb3\x82\xa3\x72\xd3\x7b\x5e\x5d\x1a\xb3\xec\x8d\x1f\x0a\x04\x4c\x20\xde\xb8\x3a\x43\x69\x24\x9e\xac\x60\xb4\xfd\x75\x10\xc6\x34\x4b\x6d\x1c\xbb\x2a\xbb\xd7\x75\xf4\x7a\x42\x44\x42\xa7\x54\xf3\x70\x29\xd5\xa2\x70\xde\x12\xfd\x77\x44\x32\xc0\xea\xbd\x55\xcd\x71\xbb\xe0\x74\x14\x84\xf8\x22\x77\x6f\xf1\xc3\xc3\x8c\x1b\x43\x3f\x34\x4e\x93\xc0\x13\xb2\x97\x55\x5e\x3e\x14\xf9\xf9\x23\xaf\x1e\xfb\x99\x24\x35\xbc\xa1\xa7\xeb\xff\x83\xb4\x33\x81\x84\x98\xed\x37\x57\xc3\x50\x00\x52\x91\x60\x99\x6b\x91\xd7\x3f\xf9\xf5\x2e\xf7\x40\x6e\x20\x51\xec\xec\xae\x4d\x68\x74\x3d\x89\xaa\x98\xd7\x70\x03\xc2\x24\xd6\x17\x4e\xfc\x3c\x57\x92\x07\x1a\xc5\x54\x3b\x12\xca\xa1\x8b\xbe\x0f\xef\xb9\xf1\x60\x18\xdf\x19\x96\x18\x41\x90\xdd\xa5\x86\x32\x1e\xc6\xee\xa8\xfe\x6a\x2b\x41\x66\x7f\x1c\xf1\x26\x81\x49\x82\xbf\xc4\x2e\x6d\x5b\x68\xce\x55\xd9\xc0\x43\x5e\x37\xed\x57\x5e\xe8\xd1\x75\xb9\x37\x13\xb2\xd0\x04\x1e\xef\x55\xae\x1e\x78\x5e\x74\x21\x95\x21\xe9\x8d\xaf\x2b\x8b\x45\x68\x39\x74\x02\xda\x7e\xf9\x02\x11\x04\x12\xac\x25\x5d\x5e\x1e\x9f\x2b\x7f\xc0\xd2\xc9\x4d\x44\xe3\x39\x65\xf6\xa8\x94\x99\xf4\x74\x2c\x14\xca\x99\x85\x93\x82\xd4\xa6\x1f\xbf\xdc\x3c\xef\x9d\xf9\x84\xfb\x06\x95\x50\x07\x16\x34\x5c\xa3\xe1\x1d\x57\x69\x28\x7a\x76\xef\xf8\x2d\x99\x0d\x6a\x40\x11\x49\x1d\x6f\x6f\xa6\x98\x09\x40\x0d\x6b\xdb\x72\x96\x4c\xf0\x88\x73\xd2\x45\xfd\x76\xa0\xd6\x02\x09\x53\xe6\xab\xdd\xca\xf5\x51\x61\xed\x83\x42\x9b\x39\x97\x0e\x22\x2b\xb5\x61\x9e\xea\x9c\x3a\x3e\xd1\x41\x12\xe2\xcd\xec\x92\xdd\xc7\x2e\xdc\x78\xe5\xee\xad\xd1\x01\x8b\x90\xf5\x6a\xb8\x82\xcf\xd5\x44\x3c\x9f\xe8\x20\x0b\xb5\x8d\x7d\x66\x39\xc0\x3a\x10\x04\xdb\x91\x79\x89\x92\x0d\x17\x5e\xa0\xd5\xad\xd7\x27\xed\x46\x00\x72\x77\x9a\xca\x2a\xee\x31\x0f\x9a\xd7\x21\x0f\x99\x39\xfd\xf2\xd2\xb4\xd5\x69\xf8\x4a\xeb\x98\x03\x5e\x5c\x09\xf9\xf1\x55\x54\xf5\xdc\xdc\xd1\x09\x49\x10\x62\xb2\xbd\x73\x8d\x79\x9d\x50\x82\x59\x0f\x76\xa6\x77\x17\xf1\xa3\xf7\xb7\xf8\x58\x2d\x43\x27\xd2\x6c\xfe\x0d\xb4\x1b\xd4\xc1\x30\x3e\x7d\x33\xba\x7f\x9a\x04\x11\x66\x30\x02\xca\x7d\x55\x39\x0c\x96\x26\x11\xc1\x9a\x40\x79\x39\x3d\x61\x7a\xdc\xf8\x23\x14\x30\xd2\x3d\xf3\xeb\xa6\x3e\xf2\x32\xff\xaf\x8f\xba\x34\x11\xd4\x59\x7e\xa1\x60\xb2\xe6\x12\xd6\xa7\xb3\x11\x04\x36\xc0\xc2\xb9\x9c\x50\x13\x08\x91\x60\x0b\xb6\x5c\xbd\xeb\x4d\x60\x88\xa6\x42\x33\x8b\xa8\xc5\x1f\x30\xae\xa6\x6b\x0a\x12\x6b\xe2\xe7\xea\x6c\xcc\x71\x72\x40\x01\x6a\x3f\x80\x45\x04\x19\x5e\x7f\x37\xa5\x75\x63\x93\x35\x38\x9a\x61\x43\xcf\x0a\x55\x21\x3a\xeb\xb1\xe2\xe5\xa2\x9d\x91\x4c\xd3\x2c\x92\xdc\xac\x4c\x05\xf0\xfa\xae\xce\xd5\x11\x9c\x67\xd3\x74\x68\x9a\x81\xd1\x6f\xf2\xda\xd5\xd3\xb7\x39\x4b\x28\xe1\x23\x75\x84\xa1\x0f\x20\xd1\x99\x8e\x30\xf2\xe1\x35\x3c\x57\xa5\x84\x06\x31\x19\x03\x90\x2b\x1a\x98\xbb\xff\xb0\x1f\xe2\x1a\xb0\xd5\x31\x54\xd8\x7d\xca\xcb\xfc\x74\x39\x99\xce\xcf\xa4\x44\xa3\x45\x2a\xb1\x3c\xb0\xfc\xfa\x38\x7a\x65\x85\x4e\x0c\x59\x65\x20\x43\xb3\xc3\xca\xc6\x0b\xbf\x36\xdd\x0f\xfe\x34\x46\xd6\x2a\xca\x58\xd4\x4b\xf5\xda\xc5\xcf\x9d\x5d\x25\x11\x56\x0a\x6c\x6b\xef\x2b\x2f\xde\xbd\x01\x70\x77\xd4\x98\x5b\x37\x0e\xf8\x3f\x54\xd6\xd0\x8a\x04\x98\xc8\xcb\x8b\x5b\x89\x34\x08\x99\x21\x2a\xc1\x09\x07\x4f\xc4\x3b\xec\x30\x1d\xb0\x34\x9e\x2a\x31\x8f\x12\x54\xad\x95\x61\x85\x6f\xfe\xf1\x65\xf3\x78\xef\xff\xaa\x13\x54\x25\xda\x43\x37\x9f\xbe\xdc\x59\xc1\x18\x1a\x04\x96\x2b\xd0\x98\xb7\x53\x2d\xe7\xd0\x68\xb7\x1d\x17\x1a\x04\xca\x68\x1a\x3c\x00\x74\x79\xe0\x3b\xd4\xed\x6d\x6d\x73\x74\x4b\x69\x10\x80\x96\x46\x72\xee\x97\xd5\xf8\xfa\xb0\xa5\x43\x83\x30\x33\x40\x9d\xfa\x06\x31\x38\x1c\xc4\x09\x32\x6a\x5f\xd1\x41\xcb\x72\xb0\x8c\xbc\x1e\x2f\xaf\x1f\x96\x1d\x69\x10\xaa\x20\xb5\x52\x00\x4f\xa8\x54\x6a\x66\xdd\x6f\xe3\x0b\x8e\x48\x8a\x09\xef\xc3\x76\x61\x7c\xb6\x51\x75\xc7\xdd\xbb\x38\x4c\x51\x4e\xc0\x36\xbd\x7e\x20\xb9\xbe\x07\x12\xd3\x20\x86\x0c\xa1\x2b\xcb\x57\x90\x6f\x38\x37\x7d\xb8\x47\x83\x24\x89\xf1\x41\x95\xd6\x2b\xd9\xe1\x14\x36\x1a\xf3\x09\x47\x9f\xa7\x41\x42\x98\xe8\x95\xf7\x37\x67\x28\xef\x72\x35\x38\x2a\x70\xbe\x34\xd0\x3e\xfc\x1a\x2d\x8e\x34\x48\x74\x98\x86\x56\xb3\x69\x80\xd2\x9f\x71\xe5\xa6\x41\xca\x00\x13\xdb\x6d\x55\x14\xc2\xa3\x59\x69\x90\xf2\x14\xa9\xae\xa8\x2a\x1a\x4e\x55\x45\x69\x40\xa2\xc8\x00\x29\xba\xdf\xb8\x2a\x55\x55\x37\xb8\x5c\xae\x7e\xe5\x4d\xdb\xcc\xaa\xb5\xd3\x80\x64\x21\x73\x32\x45\xfb\xea\x78\x2c\xe0\x2e\x6f\x77\x17\x74\x39\x73\x27\xa6\x31\xc7\x59\x62\x1e\x0f\xea\x8a\xff\x1e\x4d\x2e\x9a\x5a\x22\x3a\x1a\x06\xa3\x01\xba\xf5\xbb\x72\x27\x61\x89\x30\xa6\xaf\x45\xd5\x20\x6c\xbe\xba\xf8\xa7\x93\x45\x22\x09\x7d\x37\xb2\xfa\x39\x12\xf8\x9c\x8b\x3c\x68\x90\xa5\x80\x7d\x1b\x43\x27\xf8\xa0\x2f\x33\x79\xe9\xb3\x2c\x40\x5d\xea\xe6\x72\x3a\x55\x65\x18\xf8\xaf\xcf\xa8\xb9\x71\x45\x0e\x65\x7b\xf8\x39\x98\xc5\x34\xe0\x4a\xa1\xe5\x35\x76\x40\x18\x9d\xbc\x96\x22\x0c\xad\xf0\xdd\x7b\xf5\x06\x16\xa4\x3a\x55\xa3\xa1\x81\x48\x23\xd4\xd7\x3f\xf1\xf3\xd7\x01\xc0\x95\x06\x82\x66\xa6\x3c\x51\xf0\xf2\x4d\xd4\x00\x2a\x2f\x8f\x6a\xc0\xb0\x1e\xce\x43\x19\xa4\xd8\xf9\x82\xf6\xb5\x4b\x3b\xac\xeb\xd3\x68\x17\xa3\x81\x8c\x8d\x4d\xc2\xd7\x6b\x7e\x36\x38\x44\x7c\xc9\xf6\xc0\x4f\xd3\x91\x2a\x05\x13\xe6\x34\x6d\x5d\x5d\xd7\x2d\x9c\x1a\xcb\x84\x77\x43\x80\x64\x81\xad\xe3\x1d\x8e\x4e\xfe\xfd\x70\x9a\xc0\x8a\xbb\x71\x80\x11\xed\xdd\xe6\xfb\x76\xb7\x1a\xb8\xd5\xd3\x00\x44\x6c\x62\xec\x2e\x8c\xb7\x20\xd3\xb9\xb8\x8d\x06\x3a\x55\xde\xcd\xf9\xf7\xc3\x36\x9e\x7c\x87\x86\x14\xfb\xaf\x5f\xa0\x84\x26\x6f\x66\xeb\xfa\x66\x68\x18\xa4\x36\x7f\xab\xb9\x84\x6e\x9a\x4e\xb6\x2a\x1a\x76\xeb\x1f\x31\xf5\x88\x9d\xeb\x92\x87\xe3\x72\x37\x0d\x43\xc5\x51\xdb\x02\xc1\xcd\xfb\x6a\x7c\x6f\xc2\x88\x24\x88\x5f\xe7\x4a\x39\x57\xd2\x66\xf2\x2d\x11\x05\xac\xa7\x72\x57\xd2\xda\xd7\x3c\x9f\x46\x4e\x34\x8c\x84\xb0\x8a\xc3\x2d\xd4\x8b\x1a\x4a\x3e\x20\x52\x8e\x6f\x52\x18\x27\x44\x27\xbd\xab\x4a\x99\x9f\x78\xb1\x56\xdd\x8e\x6a\x39\xba\xb3\xe9\x23\x0d\x63\xaa\x10\x07\xeb\x4a\x1a\xab\xfd\xd7\x4f\x77\x5d\x1a\xc6\x52\x71\xe6\x89\xaf\xdf\xb1\xad\x38\xec\x88\xd3\x30\xe1\x41\xd4\x7b\x46\xf7\xf2\x06\xa3\xd8\x9e\x86\x69\x68\x6c\xaf\x15\x70\xa3\x1e\x70\x78\x0f\xfd\xb1\xc8\xc0\xf8\x5d\x68\xb0\x6b\xf9\xbc\x04\x04\x0d\xd3\x2c\xc2\x9a\x90\xaa\xee\x2e\xd7\xc9\x1d\xa4\x4a\xe0\x69\x96\xaf\x00\x2d\x7f\xed\x61\xea\xdd\x21\x89\xb6\x75\x2d\xff\x75\xd0\xde\x42\x80\x86\x14\x38\x09\x47\x28\xe8\xf1\xf4\x08\x59\x14\x27\xbe\xe2\xf6\xe8\x75\x5a\x68\xc8\x32\xc3\x46\xe3\x85\xe6\x78\xb0\xf5\x72\x0e\x34\x64\x5c\xe1\x4e\xb4\x05\x23\x9e\x80\x61\xd8\x84\x6c\x38\xf9\x61\x59\xa6\x31\xbc\x71\xf7\x60\x89\x80\xbf\xe2\x8e\x97\x6f\x53\x95\x37\x1a\xf2\x20\xc2\xb6\xea\xfd\xea\x71\xf1\xc7\xe1\x65\xb5\x5d\x6f\xee\xdd\x77\xf3\x24\x40\x8f\xf2\xd3\xa5\x38\xe8\xa2\xe2\xed\xe1\x7c\xe3\x01\x72\x4b\x4a\xa2\x21\x4f\x53\x6a\x61\x3a\xcf\x97\xd3\xcb\xc5\x1b\x60\xf8\x7b\xc1\x29\xb3\xe2\xf7\xc6\xee\xe6\xd6\xb9\xc6\x0e\x14\x49\x86\xaf\xf2\xe2\xfe\x7e\x7b\xd8\x7f\xfb\x72\xd8\x6c\xbf\xf8\x63\x34\xc3\x0c\xc4\xb8\x55\xcf\x52\xa5\x69\x28\x98\xc0\x8c\x5d\x5c\xfd\x44\x13\x42\x27\xcc\x77\x5b\xae\xa5\xca\x25\x6f\xc7\x7e\x8c\x34\x14\xca\xc8\xd7\x72\xa5\x5c\xbb\x6c\x72\x66\x19\x0b\xac\x66\x3c\x56\xc7\x1d\xb4\xdb\xbb\x01\xa3\xae\x9b\xd9\x30\x47\xf1\xa4\xa1\xcc\x08\xee\x33\x7f\xe6\xa6\x61\x87\xab\x98\xe3\x36\xb8\xfc\xe3\xc1\x05\x27\xa1\xa2\x14\x73\xa8\x97\xed\x7a\xb9\x3a\x2c\xbf\x2e\x9e\xbf\xac\xb0\x6d\x7a\xd8\xed\x57\x2f\xfd\x28\x13\x3d\xa0\x50\xbe\xd1\x8d\x77\xb7\x68\xea\xc5\x48\x43\xa5\x09\x7a\x8f\x70\x4c\x3f\x4d\x27\x06\x05\xec\x87\x53\x87\x4d\xae\x0d\xd2\x2c\x12\xbd\xe1\xe9\x4d\x57\xf1\x26\xfd\xa3\x21\x48\x4d\x8c\x08\xda\x3b\x94\x17\xa3\xe1\xbd\x74\xce\xdf\xe3\x1b\x05\x5a\xa1\x81\xfc\xd3\xb5\xf5\x85\x83\xb1\x0a\x14\xfb\xdb\x4c\xca\x46\xa3\x20\x54\xd4\x78\x79\x34\x2d\xd4\x03\xed\x5f\x1a\x05\xc2\x64\x9f\xf7\xab\xd5\x93\xff\x1b\x84\xb6\x6c\x54\x9f\xaa\x49\x0b\x87\x46\x61\x18\xc6\x89\xaf\x23\xdc\x2f\x36\x1f\xa8\x55\xb9\xe1\x11\x8d\x58\x8f\x89\x5e\xbe\xe6\xd2\xe7\x2d\x34\x8a\x52\x43\x1e\x6e\x4d\xb4\xb2\x5b\x2d\xfd\x11\x6e\x54\x2e\x3c\xd5\x0b\x8b\x4b\x66\xb2\xe7\x72\x8f\x70\xd0\x41\x29\x8d\x46\x71\x2c\x81\x3a\x3c\xea\xda\xc7\x8c\x51\x9c\x81\xd3\x39\xeb\x62\x22\xc1\x1b\x50\x3d\xd9\xdb\x0d\xe2\x4c\xdb\x64\xb8\xdb\xf7\x6b\x9e\x37\x37\x0b\x43\x94\xa4\x11\xea\x5a\x1a\xa5\xc4\xa9\x28\x4c\x1f\x45\x44\x69\x0a\xda\x54\x5f\x9b\xbc\x06\xe5\x00\x87\xf6\x68\x37\x4f\x06\xfb\x4b\x3d\x51\x13\xa6\x11\x65\x11\x76\x8a\xef\xa1\x19\x24\x79\x34\xa2\x0a\x52\xbb\x7b\xaf\x8e\xc7\x41\x7b\xc0\x1a\x4c\xd2\x28\xcb\x08\xde\xce\xfb\xba\x3a\x17\x23\x50\x0f\x8d\x32\x61\xa8\xdb\x45\x25\xdf\x30\x5d\x9e\x14\x6c\x68\x94\x81\x00\xfb\xa8\xbc\x02\xf3\x0b\xaf\xdb\xa1\x6c\x25\x8d\x44\x60\xb4\x51\x8d\xfc\xe5\xfe\xfb\xdd\x6a\x7e\x37\x89\x04\x31\xfe\xad\xf0\xab\x85\x12\x9d\xb4\x7b\x62\x3b\x8d\x64\x62\x9a\x3e\xcb\xaa\x86\x2e\x72\xc2\xca\xc5\x5f\xd3\x4c\xa0\x91\x64\x21\x16\x7f\x14\x9c\x06\xd6\x7c\xa3\x8e\xfa\xdf\x46\x2f\x87\x14\x1c\x67\xd9\x7a\xb9\x39\xbc\x7c\x5d\xec\x56\xe1\x61\xf1\xd4\x0b\x8b\xd0\x08\x12\x63\xe5\xb2\x3e\x9d\x0a\xbe\x96\x1f\x6b\x53\xce\x5f\x10\x88\x04\x5b\x75\xf7\xd5\x71\xef\x78\x52\xee\xd4\x3a\xd1\x18\x53\x36\x31\xb3\x2a\x7e\xee\x40\x6a\x48\xd5\x27\xfe\xcb\x4a\x02\xba\x03\x94\xa3\x09\x9e\x69\x50\xda\xbd\xb3\xd7\x5b\xa0\x91\xce\x32\x2e\x47\xfb\x3d\x0f\x99\x3f\xa8\x8c\xd8\xb0\x82\x77\x28\xaa\x33\xd4\x4b\x9f\x06\x44\x1a\x20\xb5\x2b\x41\x83\x77\xbd\x39\xf6\xf4\x03\x1a\x07\x51\x9a\x58\x07\x96\x2e\xc7\xdd\x14\xea\x56\xa3\x8b\xc6\x01\x30\xea\x79\x77\x9b\x12\x86\x12\xd6\x34\x0e\x13\x83\xb7\x6d\xa0\x35\x56\x2c\x08\x63\xc8\xcb\xe3\x9c\x4a\xf4\xf8\x36\xc6\x21\xe1\x26\xaa\x6c\xa0\xf5\xc9\x43\x1c\x8a\x00\x27\xcc\xd7\x2e\xf2\xe1\xdf\x72\xf9\x56\x69\x3d\x78\x97\xe2\x50\x08\x4c\xf8\xe5\x79\x4c\x57\xa6\x71\x14\xe8\xcc\x8a\x32\x75\xf7\xcf\x80\x0e\x31\x03\xbd\x9b\xea\x1e\xd3\x38\x22\x0c\xb9\xa2\x2e\x4a\xd8\x20\x7b\x7e\xf2\xe3\x23\x16\x20\xde\xf8\xd2\x58\x3f\x09\xdb\xea\x6e\xa6\xe3\x32\x30\x9e\xad\xf2\x15\xd4\xa5\x80\x25\x2f\x8a\xa1\x9c\xf9\xec\x0b\x35\xd9\x4f\xe2\x88\x53\x7c\x94\xe7\x7a\x90\xf8\x34\x2f\xc6\x4c\xd5\xfd\xfa\x38\x09\x11\x79\x62\x39\x3b\xcf\xf0\xab\xbd\x1f\xb7\x7d\xec\xc0\x84\x86\x18\x4e\x1f\xba\x8c\xee\x19\x89\x8f\x5d\x18\xd7\xdc\x5d\x57\xb5\xdc\x57\xe6\x2f\xa6\x4e\xe6\xce\x9d\x0a\x67\x46\x62\xb4\xe7\x7a\x6b\xb7\xe1\xf4\x8a\x53\x4d\x08\xed\xf3\x1c\x94\xc2\xae\x61\xfa\x30\x08\xe3\x68\xc1\x9a\x0f\xfd\x92\x2d\x92\xc5\xb6\xb0\x69\x4c\x74\x60\x94\x58\xb1\xba\xe7\xb6\xe3\x98\x52\x89\x8c\x3a\x0b\xc7\xb6\xfb\xf1\xe4\x07\xb2\x58\xe2\x8a\x63\x1c\x45\x46\x35\x9a\xd1\xe5\x32\x46\x84\x95\x2b\x79\x1c\x4b\xb5\x8c\x2f\x98\x71\x8a\x15\x11\xbb\xd5\x5d\xca\x23\xdc\x92\xc9\x3e\x2d\x95\xd3\x98\x49\x81\x30\x4b\x84\x0c\x3d\x56\xc7\x2e\x48\xbd\x91\x62\x9e\xf9\x98\xb2\x9c\xc4\x2e\xc4\xcd\xcb\xa3\xc7\x40\xd3\x38\x63\x9a\xc7\x83\x16\xd0\xf6\x23\x3e\x0d\x8d\xb3\x2c\x75\x6e\xe0\xbb\xbf\xc0\xb3\x75\x9f\xe2\x06\x11\x67\x8b\x81\x3b\xe8\x1f\x03\xcf\x42\x07\xc4\xea\x76\xfe\xf1\xe7\x04\x55\x94\x8e\xe3\x2b\xb3\x49\x3c\xc3\xcf\x2d\xbc\xe7\x4d\x5e\x95\xcf\x55\x8b\x95\xcd\x9e\xce\x41\x63\x91\x19\x2f\x63\x81\xaf\xde\x4c\xc3\x85\xc6\x32\x88\x31\xb0\x7a\xd9\xae\xb0\x36\x83\xf9\xaf\x97\x82\xa6\xb1\x8c\x25\xd6\x0a\xcf\x79\x79\xb4\xd3\x76\x7c\x27\x24\x89\x71\xc0\x0b\xbf\xa2\x2e\xd2\xa7\xfb\x4b\x2c\xb3\xcc\xf0\x2d\x57\xfb\xc5\xfd\xe6\xf1\x71\xb1\xf5\x5f\x24\x78\x3c\xa2\xcb\xdf\x82\xe8\x69\x2c\x65\x04\xc2\x4a\x85\x80\x8d\x59\xa6\x71\x54\x2c\xb5\x59\x48\x56\x4f\xeb\xe1\x76\x11\x2b\x48\xe2\x01\x77\xd5\x85\x19\x97\x1b\x45\x09\x1a\x43\x1a\x10\xfb\x26\x6c\xad\x11\x58\xc9\x8f\x50\x1b\x8d\xc2\xf1\x35\x69\x19\xc8\x78\x40\x14\xb8\xbb\x22\xde\x79\x38\x2f\x92\x40\x02\xf2\x80\xee\x77\xc3\x2b\x4a\x02\x9d\x68\x53\x76\xaf\xd5\x01\xab\xbc\x07\x94\x5c\x74\xc7\x43\xa2\x31\x21\x1b\x62\xee\xd8\x2d\xe6\x8e\x26\x51\xa4\xa2\xcc\x42\x37\x46\x12\xdc\x34\x89\x44\x96\xc4\xb8\x36\x9c\xb9\x7c\xe3\x47\xac\x6d\xee\xa0\xbd\x9c\xfd\x08\x25\x90\xa8\x6c\x8c\xcf\x87\x02\x07\x34\x89\x74\x88\xcb\xd4\x50\x74\xf2\xcf\xe4\xaf\xff\xea\xbf\xf6\x2b\x62\x66\x42\x7b\x43\x03\xee\xb1\x75\xbf\x8d\x87\x25\x41\x8a\xc3\x1e\x78\x21\xab\xd2\x82\x8f\xed\xb1\x94\xa4\x44\xf8\xc0\x6f\x7d\x32\x32\xcf\x37\xa5\xac\x84\xc4\x04\x11\xc4\x4f\xbc\x79\xe5\x75\x2e\xf6\x38\x9f\x7c\xbe\x9d\x50\xaa\x91\x7f\xe0\xca\x01\x6e\xb5\x1f\x3d\xf0\x84\x66\x86\xf4\x81\x53\xe5\xf0\xb4\x7e\xf6\x1f\xd7\x71\x68\x82\x87\x41\x37\x71\x3c\x01\x12\x16\xc4\x0a\x7d\x8d\x2f\xb8\x70\x4c\x00\x84\x93\xc1\x59\x98\x22\x7d\xb2\x87\x35\x7d\x0a\x06\xa5\x49\x96\x19\x9e\xa0\xdb\x68\xbd\x61\xe7\x84\x54\x3d\xff\x7f\xe7\x2f\x82\x87\x19\x6e\x6e\x8b\xbc\x56\x75\x65\xe5\xa1\xc7\x2e\x56\xf3\x75\xce\x84\x27\x4c\x40\x6f\x8d\x32\x05\x15\x4d\xbe\x26\x65\x89\xcd\x32\xbe\x14\x5c\xe5\xbc\xad\x6a\x47\x7e\x98\x3c\x46\xce\x12\x54\x7a\x40\xf2\xe5\x27\xb5\xb4\x84\x8b\x00\x3b\xc6\x4e\xc5\x12\x23\xfb\x43\x14\x1c\xfe\xce\xcb\x8b\x17\x2f\xa0\x09\x97\x19\x36\x7f\xb6\x28\x26\xff\x58\x5d\x79\xd1\x5e\x77\xa8\xa7\x36\x9a\xaf\x22\x63\xa1\xc5\xc1\x3d\x00\x6c\x41\xe6\xe7\x7c\xaa\xad\xdf\x8d\x52\xc6\xd3\x84\x6b\xd8\x57\xbb\x8b\x30\x68\xd5\xf9\xbb\x2b\x38\x15\x4e\xae\xc7\x89\xcb\x18\x49\xb4\xdf\xa6\x03\x01\xa5\xa6\xbf\x1b\xf7\xb2\x31\x30\xc1\x8e\x91\xca\x60\x02\xba\x7d\xa2\x8b\x56\xb6\x97\xd2\xcf\x64\x09\x02\xf7\x90\x89\x7b\xf5\xf2\xeb\x7a\xd9\x57\x3c\x13\x45\x8c\x47\xd1\x11\xda\x47\xe0\x53\xa3\x32\x9a\x00\x21\xca\x88\x75\xdf\xd9\x8a\x5a\x7f\x85\x40\x00\x43\xc2\x2f\x77\x4f\xa3\xbb\xa6\x63\x8d\x14\x64\xdc\x71\x7f\x37\x78\xc9\x01\x8b\x92\x26\x9a\x01\x76\x5f\x71\xed\xbb\xe7\x86\x63\x39\x90\x83\xa5\x89\xd6\x42\xa5\xde\x5e\xa9\x9d\x85\x3e\xd1\x34\x10\xa9\x0c\x3c\xab\xfe\xdf\xd0\xc3\x1a\x87\x8b\x71\x1a\x26\x91\x11\x3e\x6d\x6c\x39\xf6\x33\xf0\x23\x4d\xc3\x8c\xe3\x59\x0f\x2e\x2c\x18\xd2\x59\xe6\x48\x41\x34\x0d\x75\x44\x4d\x82\x86\x1c\xca\xf1\x4a\x96\x46\x71\x2a\x6c\x36\x38\xa1\x9d\xd0\x34\x0e\x0c\x36\xb2\x06\x09\x65\x3b\x52\xe9\xec\x0e\x5a\xd4\x28\x82\xe2\xe3\x43\x2e\x2b\x5c\xcc\x67\xda\x83\x34\x4d\xba\x6c\xd7\x14\xf3\xaa\x77\x98\x38\x63\xd1\x34\xe1\x09\x38\xd3\x46\x5e\x40\x64\xb6\x1f\xd5\x2f\xfd\x69\x1a\x31\x94\xc0\x15\x97\xeb\xdd\x25\x2f\xd4\x8c\xe9\x87\x1b\x19\x9b\x26\xef\x4e\xbe\xd6\x55\x37\xce\xaf\xcc\x69\x4a\x28\x32\x3d\xbf\xbc\x8c\x76\xbe\x34\xe5\x46\x38\xa7\xe5\x6f\x80\xa4\x7f\x57\x73\xb9\xe9\x1c\xa4\x29\x04\xf8\xe2\x3e\x7d\x1b\x9d\x81\x44\xb1\xb2\x7e\xe6\x46\x32\xfb\x84\x65\xd0\x53\xde\x03\x4a\x27\x3f\x99\x06\xa9\xa4\x9e\x4d\xfa\xc0\xdf\xe0\xab\x79\xc5\xdd\xf1\x28\x8a\xfd\xeb\x33\xb5\xb7\xa7\x29\x4d\x42\xac\xb7\x70\x21\x47\x17\x42\x59\x8c\x30\xe5\x3f\xaa\xb6\xe6\xfe\x8f\x99\x61\x6c\x20\xc3\xe2\xee\x72\x85\x7a\x94\xcb\xa5\x54\x86\xd4\xc8\x01\x20\x94\x74\xc0\xc7\x46\xf1\x28\x04\xd0\x77\xcf\xb5\x59\x2f\x37\x7f\x2a\xe2\xf2\xd1\xbf\xe3\xeb\x67\x2a\x49\xd2\xb1\x8c\x6b\x6e\x08\x8b\xb3\x20\x27\x9a\x66\x4a\xe3\x7b\xea\xba\xc9\xcd\x5d\xf7\xda\xed\xf2\xff\xfa\x2b\xe5\x01\x35\x32\x7d\xdd\x63\xf4\xf7\x91\x6b\xcb\x7c\x2f\x15\xca\x6e\xe8\xa9\x52\x20\x4d\x45\x42\xd0\x7b\xee\xa0\xc0\xac\xcc\xb7\xad\xb3\xf1\xc5\x0b\x95\xe0\x0a\x2d\x3d\x82\xf3\xbf\x30\x3d\xa7\xa6\xd8\xfc\x5e\xed\x56\xbf\xaf\x9e\xf7\x7f\xe0\x3f\xbf\xf9\x83\x0c\x19\x18\xf0\xcb\xf1\xd1\xdd\x16\x66\x07\x48\x65\xac\xe3\xfd\x6a\xb0\x2e\x77\xdd\xa6\x55\xcf\x37\x7c\x52\x15\x52\x94\x19\x7e\x87\xf7\x5e\xb6\x9e\xa6\x4a\x8a\x70\x62\x05\x64\xa4\x5d\x86\x0f\x18\x48\x86\x15\xd0\x7d\x7d\x1d\x44\x1f\x29\xf0\x0c\x81\xe7\x67\x84\xf5\x39\xf7\x27\x77\x50\x67\xc2\x16\xda\xe5\xdb\xee\x3c\x65\xd2\xd0\x54\x07\x11\xb6\x98\xbe\xd7\xbc\xcc\x2f\xa7\x97\xe2\xe2\xd7\x0d\x1d\x12\x0c\xad\xcf\xc0\xeb\x62\x37\x25\x21\xd1\x54\x13\x88\x3c\x1d\xe8\x49\xbb\x7b\x42\x82\x4c\x86\xd6\xfd\x6f\x86\xec\x45\x49\xc0\x43\x74\xc1\xe0\x6d\xcb\xe5\xab\x9b\x75\xb7\xa8\xe1\x4f\xa3\x04\x12\xa8\x08\xb1\x03\x77\x9b\xcd\xb7\xf5\x6a\x37\xfe\x59\x24\x50\x1c\x09\x42\xb6\x5a\xf9\xf2\x89\x26\x15\x45\x57\x47\xbc\xe0\xba\x7a\x1f\x2b\xbd\x50\xd2\x45\x31\xa6\xf3\x51\x58\x99\x89\xfe\x10\x00\x36\xd4\x0c\xed\x67\x5a\xdc\x9f\x9f\x4e\x24\x4a\x02\x04\x62\x4a\x5e\xc8\xff\xfb\x63\x69\x92\xab\xbb\xeb\xac\xaa\xe6\xf4\xa3\x24\xd4\xc2\x60\x79\x96\x03\x6c\x5f\xaf\x98\x76\x77\x7d\xe4\xa5\xea\x69\xa1\x94\xc4\x54\x20\x1a\xde\xc0\xba\x86\x74\xc9\xf1\xa4\x25\x31\xf3\xb3\x7c\xcb\xb5\x36\xa5\xc1\x47\xd0\x6e\x2b\x25\x69\x68\x5c\x78\x4b\x94\x65\xb1\xcc\x0c\x7f\x90\x9a\xf6\x7d\x8f\x0c\x20\xa9\x90\x68\x18\x8b\x3e\xcd\x08\x49\xf2\x68\x40\x4a\x52\x49\x90\x62\x27\xa0\xdd\x94\xf7\xd5\x7f\xa7\x95\x09\x92\x4a\x81\x22\x68\xdc\xa0\xe2\x9e\xf2\xd1\x4c\x20\x24\x0e\x68\x37\x5d\xaa\x9f\x25\xd4\x07\xff\x57\x45\xb3\x91\x9e\xf3\xaa\xfc\xbc\x0d\x45\xa8\x48\x29\x9b\x18\x95\x2f\x4a\xb5\x68\x9a\xfc\x38\x04\x11\xff\xb5\xff\x1d\x96\x39\x27\x2f\x2b\xcb\x52\x6c\x45\x3a\x0c\xd6\xa0\xc2\x31\x7e\x0e\x59\x92\x64\x26\xed\x3a\x20\x0a\xf8\x60\x08\x2c\xf3\x25\x55\xf7\x19\xc2\x31\x8b\x33\x35\xa1\x1f\xd0\xc5\x49\x03\x4d\xd9\x5e\x90\x28\x74\xbf\xbb\x5b\xa2\x2d\x72\xda\xfb\x64\xf9\x7a\x06\xc9\x34\xc1\xb2\xd0\xd9\x20\x84\x0f\x5e\xc8\xb6\x4f\xd3\xed\x48\x2e\xa4\xc8\xfa\x68\x00\xab\xf8\xdd\xee\x10\xb9\x53\x09\x16\x1a\x21\x0b\xa3\x31\xf3\xd7\x66\xb6\x94\x01\xc2\x6a\x34\xcf\xb1\xc3\x5a\x5d\xda\x2d\xf0\xc6\x11\x87\x28\x51\x2a\x06\xed\xdb\xb4\xae\x43\xe5\x2a\x56\x04\x62\xc3\xdb\xf9\x5a\x95\x55\x71\x29\x2e\xee\x63\x90\x02\x16\xa9\x0f\x87\xfb\xd5\xdd\xf7\x2f\x87\xbb\xc5\xa3\x3f\x94\x45\x88\x50\xb7\xf0\x6c\x67\xe8\xfc\x69\x51\x82\x00\x17\x18\x0b\x99\x1f\xf7\x52\xc3\x5a\x56\x8b\x52\x61\x5c\xe5\x95\xe5\x29\x01\x09\xce\xf7\xc3\xe0\xb9\x71\xc0\xe4\x85\x07\x15\xe0\x32\xec\x14\x8d\x86\xa1\x02\xd1\x01\x8b\xed\x82\xda\x6d\x64\xcf\x97\xd3\x46\x2f\x79\xdd\x4f\x36\x1d\x1b\x77\xe6\xed\xea\x61\xb5\xdd\xae\xee\x0d\x48\xe6\xf0\xb2\xda\x3e\xad\x1f\x9d\xf1\x09\x25\x9a\x44\xd2\x10\x9a\x30\x05\x1a\x5f\x02\x0d\x62\x23\xf5\x6e\xd6\x0a\x94\xbf\x6f\x87\x78\x58\x3b\x2c\x0c\x8c\x22\xe4\x89\xd7\x75\xce\x8f\xf0\x52\x57\x95\x1e\x36\x24\x68\x18\x71\xe3\xed\x79\xbf\xef\x15\xe5\x46\x8f\x98\x86\x2c\xcd\x7c\x9c\xb3\x40\xe4\x4d\x85\xa6\xef\xee\x38\x84\x59\xec\x96\x3a\xec\xf1\x2f\x2b\x35\xe2\x5e\x50\x1a\x45\x3a\x9b\x6c\xbd\xef\xf9\x14\x97\x4a\x69\x2c\x8d\x0c\xbd\xe8\x5e\xce\x55\xa9\x1a\xf7\x72\xd2\x58\x6b\xcc\x0e\xfe\x73\x81\xfa\x6a\x26\xff\xf7\x72\xf1\x93\xbf\xc1\xee\x2d\x2f\x8a\x6e\xa5\x37\xd1\xe5\x3f\xc3\xd0\x76\x07\x69\x12\x48\x6d\x25\x3a\x81\x17\x2f\xfc\x3c\xd6\x39\xa7\x34\x0d\x01\x3b\xb7\xd5\xc4\x63\xe7\x96\xfd\x4a\xbb\x18\xd0\x65\x4d\x2f\x08\xc0\xac\xf3\x89\xd8\x3f\xed\x36\x68\x9c\x8c\xcb\xc5\xd0\x28\x95\x52\xc2\x53\x64\x02\x9a\x92\x96\x57\x34\x77\x47\x35\xc7\x66\xdd\xa2\x38\xbf\x72\x59\x95\xfd\x73\x70\x24\xe9\xd4\xfd\x22\x4a\x8d\x00\x20\x3e\xeb\x71\x87\x99\x52\x61\x9c\x72\x1e\xab\xe3\xd6\x72\xaf\x41\xad\x87\x84\x4f\x92\x8c\xaa\xc5\x94\xaa\x80\x04\xbe\xa4\xf2\x52\x57\xdd\xeb\x5c\x2f\x6e\x64\xdc\x28\x65\xa1\x8e\x0d\xa1\xf0\x7c\x06\xf5\xdd\x25\x20\x34\xb3\x3e\x12\x67\x93\x8a\x99\xc2\xf2\x78\x53\xa6\x19\x67\x38\x93\x79\x6e\x4a\x6b\x03\xac\x3e\xa5\x9c\x28\xce\xdd\x0f\xf2\xfe\xeb\x93\xb7\x98\x67\x61\x64\xd6\x38\xd0\x79\xd1\xb7\x99\x29\xe7\x80\xdd\x6c\x04\xa6\xb8\x24\xe8\xa9\x72\x4e\xff\x94\x8a\x80\x1a\x8c\x3e\xf7\xc6\xf9\x93\x5f\x26\x98\xc2\x97\x3b\x3f\x57\x3f\x7f\xb3\x82\x1b\xc3\x7b\x24\x78\x24\xbd\xb2\xe6\x5a\x3f\xc1\x91\xff\xdd\x83\xf8\xfa\x56\x30\x95\x24\x31\x0a\x55\x68\xc7\xf5\xdb\xcc\xd2\x4f\xa5\xe6\x58\x3a\xfa\x09\xf9\xb8\x09\x41\x95\x88\x62\x23\x29\xfd\xed\x8f\xa5\x37\x99\x1e\x5f\xa8\x52\xa9\x93\x3b\xd8\xf5\xfe\xa6\xe3\x1b\xa5\xb4\x21\x75\x3c\x5e\xdf\xde\xc0\xf6\x57\x06\xfa\x63\x73\xbd\xee\xd1\x7c\x80\x20\xc2\xc5\xfc\x98\x77\xa1\xd5\x00\x38\xfa\x41\x41\x87\x82\x8e\xf0\x85\xef\x76\x1c\x2c\xe2\xd8\xbf\xeb\xcc\x08\x87\x1e\xf9\x09\x5d\x81\xa7\xf5\x5b\xaa\x75\x84\xbe\x82\xd2\x60\x49\x2c\x21\xab\xf5\x2f\xb3\xd6\x0c\xbb\xf5\x76\x5b\xdb\x99\x00\x61\xd0\xb6\x62\x41\x4c\x11\xaf\x67\x9c\x8f\xf3\xf6\xfa\x52\x55\xc5\x00\xe0\xe6\x86\x25\x89\x09\x4e\xba\xe4\xe3\xc9\x58\xc3\xf9\x63\x9a\x38\x33\xc9\x7b\x68\xda\xda\x4c\xfe\x59\x9c\x05\x0b\x83\x18\x2f\xc8\xec\xdb\x56\xab\xb3\xa7\x28\xf8\x5b\xc2\x42\xc5\xa4\x2b\x63\xb8\x7e\x3c\x8b\x28\x30\xa3\x45\x69\xda\xdf\x73\x68\x2c\x16\x65\x21\x2a\xab\x9c\xeb\xea\x04\xed\xeb\xe4\x02\x22\x11\xd2\x21\x0a\xa7\xdb\x6c\x8d\xdf\x78\x2b\x5f\xe7\xe0\xab\x73\xff\x65\xcf\x15\x0b\xa3\x8b\x6e\x56\x74\xa7\x5c\xb9\xaf\x7a\xdf\x17\xca\x92\x38\x43\x7d\xe3\xdd\x7e\xb1\x5f\x1d\x5e\x16\x7f\x6c\xbe\xef\xfd\x31\x9e\x61\x17\xbb\x7d\xcd\x9b\x9f\xde\x2f\x88\xb2\x34\xd0\x48\xf2\xda\x5d\xca\xf2\xea\xff\x48\x22\x69\x0a\x9c\x66\xb7\xdc\x62\xd9\x03\xf3\xe5\xe6\xc5\x73\x4c\xef\x6d\x92\x68\x16\x35\xff\x59\xc1\x31\x23\xf2\x51\x4d\xb7\x36\x6d\x0d\xd8\xc3\x8f\x51\xa6\xcc\xd0\x40\xfb\xbd\xec\x56\x72\xe5\x84\xf7\xac\x64\xed\x8c\xd1\x3e\x65\x24\x4c\x02\x2b\xbb\x7c\x97\x57\x76\xa5\x1d\x4e\x57\x46\x62\x13\xc1\x9b\x65\x03\x15\x14\xf6\xd5\x7a\xb9\xe9\x7e\xb0\xdb\x96\x18\x61\x04\x4c\x55\x1a\x2b\x5f\x43\x28\xfa\xe4\xf9\xd1\x28\x74\x1e\x0b\xbb\x13\xaf\xdb\xdd\x2b\xef\x66\xde\xdd\x75\x3d\x99\xc5\x8c\xc6\x22\xf5\xf6\x17\xe8\x3b\xef\x57\x3c\x46\x13\x53\xab\xcf\x9b\x1d\x56\x38\xa6\x20\x77\xca\x28\x49\xb1\xc9\x74\xd0\x55\x7d\x39\xad\x95\xf1\x78\x1e\xed\x7b\x8c\x32\x66\x12\x61\x07\x58\xff\xc9\x6b\xf5\x50\x73\x39\x9c\x39\x54\xa4\x06\xaa\xf0\xf8\x6d\xa6\x8f\xcd\x98\x48\xf1\x97\xc3\x29\x6f\x17\x35\xf0\xdd\x00\x7b\x34\xda\x15\x99\xd0\x80\x06\x09\xdc\xbe\x68\xb3\x91\x9a\x13\x3a\xea\x7f\x88\x0c\x43\x0c\xa4\x4c\x17\xec\x71\x79\x3f\xbf\x06\x31\x19\x85\x18\x5a\xb4\xfc\x0d\x06\xc8\xbb\xcf\xdb\x74\x4c\xc6\x09\x32\xf2\x04\xb4\xcd\x46\xeb\xc9\x4d\x94\xc0\x94\x93\x20\xe5\x4e\x51\x6e\x04\x2e\x64\x12\x32\x8c\x42\xbf\x6d\xbe\xfd\xe6\xff\xc4\xb1\x34\x2b\x86\x5d\x60\xa6\x48\x1c\xd8\x80\xd0\x78\x63\xb9\x28\x7e\x3a\xff\x95\x22\xa8\x3e\x70\xb2\x34\xc7\xbd\x03\xf6\xf5\x8f\x1f\x62\x8e\x13\x77\xb5\xdb\xbc\x58\xdc\xe8\xf8\x67\xe9\x34\x41\x05\x87\x2e\x21\xe9\xd2\x75\x74\xb4\x1d\x7f\x8d\x56\x19\xf6\x0f\x4c\x89\xec\x29\xff\x40\x52\x96\x32\xad\x53\x16\xf6\x02\xa6\x55\xd3\xc5\x50\xd7\xa2\xe2\x0a\x51\x0f\xb3\xf5\xd9\x2c\xe0\x1c\xf3\xba\x7f\x57\x79\xf9\xd4\xfd\xdc\xa1\x09\xe7\xe8\x5a\xb3\x50\x10\x94\x50\xfb\x01\x27\x5e\xbb\x35\x24\x8b\x02\x02\x7d\x16\xb2\x2a\x40\xde\x12\x4a\x68\x16\x85\x81\x53\xc0\x37\x35\x9e\xc7\xbc\x7c\x1b\xdf\x8b\x2c\x4a\x18\x70\xd7\xe0\x2b\x70\x57\xf0\x44\xd9\x49\x33\x30\x8b\x03\x15\x19\xd4\x50\x91\xbf\x5b\x6c\x82\xbb\xa2\x38\x26\x81\xbd\x0f\x9b\x77\xa8\x6d\xef\xed\xc7\x6a\xdd\x2b\x0c\x76\x83\x54\x6a\x4b\x95\x6b\x59\xe1\x6a\x31\xbb\x91\x64\x31\x13\x58\xb3\x3d\xe5\x25\x16\xc4\x40\x61\x65\x6d\x5d\xf6\x6b\xa1\x3b\x67\xc2\xa8\xe2\x3e\xf6\x28\xdf\x79\x9d\x73\x1f\x3a\x65\x69\x00\xa8\x27\x5e\x54\xc7\x11\xc6\x28\x4b\xa5\xb1\x41\x7f\xc8\xbd\x21\xe8\xf8\xe6\x91\x20\x03\x0b\xea\xda\xd4\x4b\x2e\x5f\xe1\x1e\x1a\xc4\x2c\x81\xda\xc2\xb9\xaa\x5b\x63\x5a\xed\x86\x27\x46\xe8\x1f\xc5\x3e\xa6\x3d\x8b\x8c\xa4\xd4\x7a\x1e\x2e\x0b\xc0\x25\x0d\xb3\x7f\x2f\xaa\x3a\xf9\xf9\x84\x85\xa8\xa6\xbc\x58\x3d\x0c\x61\xd8\x19\xc9\x52\xfc\xad\x9e\x54\x6f\x28\x3c\x33\x00\xb1\x8c\x70\xb7\xe6\xea\x41\xf7\x78\xbe\x0e\x93\x11\x99\x18\x87\xc8\x21\xed\x69\xc8\x3c\x4e\x82\xc9\xab\x80\x18\x01\x6c\x1d\x60\x5a\xf5\x80\x1b\xf6\x34\x1b\x76\x5b\x69\x46\x93\xcc\xc8\x17\xe6\xc7\x7b\x44\x57\xe0\x7b\x66\x63\xb8\x45\xa9\x10\xb9\xe2\xc6\x52\xea\x92\xcb\xc7\xaa\x6d\xa1\xbe\x6e\x06\x6c\x29\x36\x5e\x0f\x27\x09\x6c\x46\x33\xc0\x16\xdd\xe3\xe6\xcb\xe1\x0e\xda\x1f\x9f\xd0\x0f\x47\xcb\x6f\x46\x41\x86\xc6\x42\x0d\xf7\x43\x2b\xd8\x60\x0f\xb2\x84\xc7\x62\x60\xe7\x82\x1b\x41\x55\xcf\x19\x35\xcc\x75\x41\x32\x46\x12\x62\xf9\x9a\xbb\xcb\xb9\x7b\x75\x60\x8c\x7a\x1a\x3e\x38\xa6\x13\xd3\xd9\x07\x71\xbe\xb8\x35\x2d\xcb\x82\x34\x23\x23\x29\xcc\x45\xdf\xe0\x1e\x3f\x9a\x2c\x62\x58\xf8\x3a\x9b\xf0\x79\x5d\x36\x2d\x2f\x8a\x13\x78\x3d\x61\x9a\x65\x44\x23\x0d\xd9\xe2\x03\x5b\xd7\x53\x1d\xdf\x93\x4c\xc7\xc8\x0b\xed\x5e\xa0\xbc\x3c\x3e\xf1\x5f\x03\xf2\x23\xcd\x78\x68\x5e\x81\x4b\xe9\x55\xac\xdc\x11\x61\x4c\x6b\xc4\xa5\x30\x72\x4b\x86\x27\x36\x07\x51\x9d\x46\x5d\x99\x48\x62\x66\x01\xbe\x77\xb9\xc2\x26\xf8\x74\xf7\xce\x54\xc0\x48\xd0\xd7\x96\x87\xb9\x52\x06\x81\xc9\x13\x8f\x56\xe2\x7b\xba\x26\x42\x24\x54\x6f\xcd\xd3\xed\xc9\xd3\x01\x94\x22\x42\x7d\x85\xe2\xc7\xa5\xbc\xee\xb8\xf6\xb3\x5c\x73\x8e\x0b\xd8\xa5\x3c\xf3\x4b\x33\xc6\x36\x64\x5a\xa4\xb1\x45\xae\x7c\xdf\xdd\xe3\xb7\xcf\xb4\x4f\x32\xad\x8d\x32\xd5\x41\xc1\xfb\x6f\xfd\xdf\x32\xab\xd9\xe2\xb4\x08\xea\xe6\x11\xca\xa3\x53\x6e\xa2\x3c\x08\x23\xac\x48\x22\x85\x65\xd2\x71\xe4\x41\x18\x63\x54\xcc\xd5\xbf\x2f\x4d\xfb\x95\xd7\x6a\xc9\xcf\xd3\x31\x91\x19\xd3\xbd\xdc\xf7\xbc\xce\xab\xf1\x2b\x38\x57\x10\xe2\x4e\x39\x0c\x7d\x37\x5a\x5e\x54\x47\x53\x55\x98\x76\x0a\xdd\xf0\x54\xa3\xca\x92\x25\x76\xf8\xfd\x79\x32\x2c\xa4\x8a\xc5\x36\x2a\xda\xf3\xe6\xcd\xd9\x9c\xcf\x16\xa5\x78\x94\x0a\x6c\xf6\xfd\xfd\xd2\xb4\x46\xc0\x6e\x82\x56\xe0\x11\x18\xf1\x79\x9d\x37\xaf\x82\x97\x6e\x97\xe4\x71\xcc\x22\x23\xe5\xc8\x6f\xe0\x38\x6e\x48\x9a\xa0\x94\xfe\xc9\xc0\x5a\xec\xcf\x32\x08\xbe\x27\x7e\x9e\x5c\x78\x2c\x23\xcc\x6f\x5a\x68\xda\x07\x9e\x17\x08\x73\xc3\x6a\x62\x75\xc1\x8a\xc5\x81\xbb\x1c\xed\xd0\x56\x86\xaf\x8e\x92\xe5\xee\x8a\x92\xd4\xdb\x65\x2f\xf3\x1a\xf3\xf8\xbc\x2a\x47\x1d\x31\x9e\x64\x32\x32\x42\x50\x97\xa6\xed\x05\x59\x3e\x4b\x31\x79\xa2\x32\x7c\xab\x1f\xd7\xff\xf3\x7d\x7d\x3f\x26\x6d\x71\x12\x70\x67\x96\xdf\xab\x78\xcf\xf0\x59\x29\x27\x40\x91\x81\xb1\xda\x7f\x3d\x7c\xdf\xdd\x1f\x06\x79\x20\xa7\x41\x12\x5b\xb9\x8e\x97\x1a\x64\x75\x3a\xe5\xad\xe9\x34\x76\xaf\xdc\x69\x46\x50\xd2\x7e\x90\xc5\x86\x5e\xbe\x70\x99\x11\x67\x3c\x95\x16\x3d\xb0\xcf\x27\x9a\x34\x94\x67\x29\xc7\x72\xc4\x8f\xaf\x9b\x47\x0b\xc5\xfa\xba\x5d\xed\xbe\x7a\xfa\x25\xe5\x3c\xe6\x4e\x2c\xce\xf6\xb7\x87\x92\x00\x94\x73\x06\x58\x07\xf3\x45\xa2\xa7\xa5\xbf\x1b\x5c\x18\xef\x8b\x06\xda\xc3\xb8\x1f\xce\x45\x62\x50\x2f\x5d\xf6\xf1\xca\x6b\x6b\x55\xb3\xa8\x6b\xee\x1f\x8e\x4c\x14\xca\x14\x14\xfc\x52\xca\x57\x53\xfd\xbc\x51\x0d\xa0\x5c\xb2\xd0\x36\x95\x2b\x75\x91\xad\x57\x97\xb2\xc5\xa5\xb1\x40\x1f\xe5\x92\x73\xb4\xb7\xf1\x8e\xdc\x37\x8a\x6b\xf3\xb7\x56\x8a\x08\x01\x38\xff\x37\x6f\xeb\xe9\x6b\x24\x95\x34\x90\x19\xdb\x28\x79\x77\xe8\x9a\xb1\x75\x37\xe5\xa0\x43\x62\x0a\x80\xba\x86\xe6\xf5\x46\xa1\x63\xfe\xab\x41\x1b\x8a\x0c\x96\x0c\x7c\xb0\xee\x18\x0e\xfd\x7e\xc6\x75\x92\xa2\xa8\xf6\xf2\x35\xbf\x56\x97\xe5\xa5\x68\x2f\x35\x56\x48\x5f\xbb\xa0\x77\xbc\x5f\xde\xea\x57\x50\xae\x39\xe0\xb2\xf5\x83\x5f\x97\x60\x5b\x56\xf6\x37\x8a\x40\x13\x0b\xd8\x6a\xbb\xb0\x3b\x77\xdb\xa5\x08\x69\x84\x6a\xc0\x5f\x16\xbb\x83\x61\x6c\x0c\xac\x9e\xa9\x08\x33\x86\x1c\xf0\x63\xfe\x0e\x63\x36\xdb\x3f\x93\x7f\xfd\x6d\x70\x93\xd8\xdf\x06\x9a\xb3\x8e\xdb\x4f\x45\xc8\x29\xc7\xe7\xd5\x4d\x6e\xd9\x1e\x34\x8c\xb7\x02\x11\x2a\x13\x50\xb9\x94\xfc\xf7\xaa\x8b\x27\xb6\xdd\xd2\x3d\xd9\x90\x44\xa8\x88\x72\x00\x4a\xec\xb3\xda\x57\x79\x46\x9c\x92\x8a\x48\x51\x30\x72\x49\xe7\x1a\xba\x34\x71\x51\xaa\x09\x0e\xc6\x8e\x8c\x63\x46\x6f\x7c\x7b\xdd\x31\x6a\xbc\x48\xcd\x92\x72\x63\x26\x38\xfe\xca\x24\x96\x49\xaf\xaf\xff\x72\xf9\xef\x7f\x2d\xf2\xf1\x73\x97\x24\x2a\x12\x66\x4c\x24\xbb\x94\xce\x28\x70\x3d\x71\x0f\x75\x11\x09\xd3\x4e\x74\xe2\xb7\xb9\xdc\x53\x24\x90\x72\x13\x91\xb5\xf5\x8d\xca\x19\x15\x69\x18\x81\x13\xb5\xb6\x7b\xd1\x14\x5d\x77\x1b\x5c\x09\x12\xc6\xa9\xd5\x3a\x5d\x16\xd5\xcf\x49\xcc\x2f\x08\x0b\xb0\xb9\xb8\xa9\xf3\x63\x97\x17\x3c\x5d\xd7\x18\xeb\x37\xf9\xa0\x86\x2c\x08\x33\x2e\xaf\xdf\xcb\x33\x97\x6f\xab\xb2\xf5\x35\x6e\x37\x20\x03\xfc\x6d\xa8\x94\x30\x55\xc5\xa3\x02\x79\xe7\x98\x55\x63\x6f\xee\x6b\x55\xbd\x41\xdd\x78\x9d\x6b\x2a\x68\x60\x48\x4e\xdd\xf2\x66\xa3\x81\x51\xa3\xf3\x26\x94\x9d\xf1\xe7\x70\xa7\xe2\xc0\x7b\x55\xde\xe6\x3c\x61\xfc\x0a\x2a\x23\x4e\x9c\x1e\xee\x9f\xe2\x2b\xa6\x7f\x9f\xa0\xe7\xc6\xa7\x66\x81\xc9\x2c\x7b\x2f\x95\x07\x80\xa7\x4a\xe5\x3a\xbf\xc1\x55\x0b\x16\x53\x84\x9c\xb4\x03\x85\xe9\xf9\x5f\xc4\xb2\x8c\x52\x0f\x3d\xb3\x67\x9e\xfe\x2c\xa6\xcc\x20\xb0\x26\xe6\x1b\xbd\xbf\x9e\x27\x81\x98\xc8\x12\x85\x2c\x4c\x65\x15\x3f\x87\xc4\x7f\x2a\x32\xce\xb1\x25\xf7\xb0\xde\xee\xf6\x87\xdf\x37\x8f\xdf\x9f\x56\x23\xaa\xb6\xc8\x94\x40\x65\x25\x69\xbc\xcc\xec\x4b\x3e\xf9\x12\x1e\x06\x58\x6b\x68\x70\x71\x5e\x4e\x23\x02\xc1\x23\x89\x5a\x63\x77\x50\x54\x6d\x5b\xfd\x3f\x3b\xf7\xfe\xd5\x7f\xdd\xd7\x12\x99\x10\x27\x9a\x66\xb4\x18\xac\xea\xe9\xcc\xac\x11\x91\xe9\xb2\xb9\x00\x62\x59\xf0\xa6\x59\xfb\x1d\x6d\x7c\x66\x91\x46\xf1\xd8\x09\xa0\xed\xa3\x08\x21\x94\x09\x7e\x5f\xa1\xae\x96\x55\xed\xff\xae\x58\x8a\x12\xbd\x2f\x0f\x5f\x96\xd3\x4d\xc1\x91\xbe\xfa\x0b\x82\x94\x84\x4e\xd0\x04\xa1\xd8\x68\xb1\x09\x33\x84\x73\xfb\x01\x9d\x9a\xd8\xd7\x77\x7e\x1d\xab\x69\xf6\xd5\xf6\x6c\x27\xa1\xa9\xc0\xa9\xfa\xa5\xae\x2e\xe7\x61\x98\x3a\x2d\xe9\x08\x4d\xd5\x20\x24\xe9\x36\xfd\x99\xd8\x5f\x68\xa9\xd3\xee\xc2\xbf\xe6\xc7\x21\xbf\x55\x68\x25\x33\x83\xc5\x07\x5e\x3f\xc2\x3b\x78\xb9\x02\x19\x08\x85\x71\xff\x0e\x40\x3d\x56\xc7\x69\x97\x7d\x7c\x19\x32\x50\x5c\xa5\xae\x1a\x62\x12\x6c\x5e\x0c\x5c\xcd\xa9\x0c\x20\xc5\x14\xe6\xae\xaa\x4e\x50\xf3\xf2\xf8\xe8\x7a\x03\xf3\x00\x1f\x19\x46\x2c\xb6\x78\xd4\x97\xcd\xe6\xf1\xd0\xcd\xa9\x43\x94\xb8\xf3\x85\x29\xc3\xcd\xe4\x80\x12\x9d\x35\xe6\x2c\x68\xfd\x1f\xb2\xf1\x8f\x97\x21\xcd\xb0\x38\x2f\x5a\xb9\xaf\xac\x37\xcd\x64\x48\x12\x9a\xca\xad\x84\xba\x5d\xa3\xa3\x88\xfb\x9a\x54\x46\x18\x15\x76\x6f\xd4\xe6\x3c\x4d\x29\x64\xaa\x32\xcc\x68\xef\xea\x6e\x31\x1d\xc4\x1f\x92\x44\x11\xa6\x30\xe7\x11\x53\x68\x84\x79\x92\x24\xa3\x98\x40\x6c\x77\xcb\xee\xa9\xdc\xf4\x78\x27\x77\x84\x52\xc9\x9c\x99\xed\xc9\x48\x7d\xe6\xc5\x55\x5c\x7b\xb5\x71\xb3\x11\xfa\x80\x41\x32\x15\xd2\xd0\x41\xe3\x5b\x5e\xfc\xc8\x95\xad\x11\x85\x23\x5d\xaa\x6e\xa4\xc2\x16\xd9\x17\x38\x8d\xa8\x79\x92\x69\x12\x82\xaf\x50\x2c\x2e\x35\x9f\x5f\x20\x65\x96\x52\x6c\x25\x60\x61\xc6\xe9\x7c\x7c\xf4\xda\xfc\x6d\x06\x3d\x2b\x79\x18\x27\x1e\xf4\x8f\x88\x65\xac\x76\x9c\xce\x03\x0d\x10\x37\x34\x89\x99\xea\x6d\x45\xee\xf3\xe6\x5c\xf0\xe9\x20\x49\x22\xa1\x5c\x98\x76\xb8\x34\x3d\x92\x53\x4a\x46\x30\xd9\xe9\x22\x4e\x78\xad\x2e\x0d\xcc\xe4\x25\x52\x32\x05\x6a\x20\x81\xfe\x58\xc9\xb7\x8b\x05\x60\x5b\x06\x6c\x97\x46\xc9\x57\x38\x71\x2c\xbb\xce\x82\x4b\x5c\xc4\x2b\x55\xc2\x11\x8b\xc9\x95\xc2\x4a\xda\x8d\x2f\x23\x95\xc0\x8d\xd0\xa7\x91\xe6\x94\x6f\x86\xd1\x3a\x3e\x8d\x0e\xcc\x43\x35\x4f\x04\xaf\x66\x69\xb9\x34\xc3\x17\x50\xa7\x61\xa2\xbc\x04\x3b\x3a\x19\xac\xda\xd7\x19\xab\x85\x6e\x68\xc2\x64\x1f\x32\x0d\x83\x36\xa9\x89\x96\x7d\xa7\x05\xab\x0b\xfb\x5f\x33\x34\x0c\xa9\xa9\x40\x90\x1b\x12\x11\xbb\xd8\x37\xf6\xa7\xe0\x5a\x5a\xaa\x1a\xaa\xb8\xa3\x2d\xaa\x3d\xa8\x82\x20\xc5\xdc\xf6\x01\x4b\xca\xe6\xde\x7a\x19\x41\xaa\x82\x28\x31\x59\x29\xbe\xbe\x90\x2f\x4d\xe8\xeb\x27\xa8\x0a\x62\xc8\x9c\xd2\x3c\xff\x95\x5f\x4e\xeb\xf2\x7c\x31\x35\x98\xf1\x05\xaa\x40\xa6\xa9\x2d\xd1\x6c\x0d\xc2\xfc\xc5\x14\x72\x1a\x7f\x2e\x49\x81\x5a\xce\xee\xae\xe5\xa7\xf3\x46\xe3\x9c\xdc\x39\x90\xaf\x1b\x18\x86\xdc\x59\x4b\x3e\x5c\xda\x8b\x25\xa4\xdf\x5d\xd7\x6a\xf2\x0a\xa9\x30\xa6\x18\x2f\x5a\xf1\x64\x57\xc0\x18\xf2\xcd\x46\x6f\x80\x0a\x79\x80\xc0\xd5\x67\xf8\xb9\x29\xff\x04\x38\xa3\xa2\x38\xc1\xa2\xd1\x19\xab\x23\xef\xbc\xec\x96\xd3\xf1\xf9\xa2\x4c\xb1\xa1\x89\xf6\xca\x03\x30\x6f\x06\x1a\xb3\x5f\xae\x94\x59\xa5\xa6\xf1\xed\x64\xb8\x4c\x4d\x3e\xfb\x5a\xfd\x74\x73\x74\x72\x71\x3a\xc6\x1d\x04\x1f\x9d\x49\x12\x07\x74\x71\x3b\x28\xd6\xc6\xc8\xf9\x94\xdf\x46\x5e\x93\x6f\x4c\x28\xc1\x5a\xe9\xa5\x7c\xe5\x45\x7b\x08\x53\xe5\xf3\x63\x95\x50\x19\x99\x8e\x61\xa1\xbb\x30\xe7\x6a\xf9\x42\xa3\xd8\x4a\x25\x8c\x26\x36\x79\xb4\x1e\xa6\x93\xf0\x5e\x25\x5a\x65\xe1\x80\x4b\x64\x03\xa7\x21\x48\xd7\x8e\x4c\x03\xc0\x9a\xc5\x03\xaf\x4f\x98\xb5\xbb\x2f\x49\x63\x33\x61\x06\xdd\xf1\xe9\x47\xb9\x59\x7c\x90\x25\x50\xf9\xab\x63\x81\xa4\x81\xab\xfc\x2b\xef\x1e\x3d\x9e\xfd\x8a\xa5\x89\xeb\xa8\x3a\x96\xcc\xe2\x6e\x3d\x6c\xfa\xb8\x81\x24\x0a\x92\x81\xd6\xff\x1e\xf8\x69\x27\xab\xba\x27\x47\xfb\x87\xc0\xa8\xc4\xfa\x3e\xaf\x85\x51\x81\x35\xa2\x3f\xe3\x5b\xc3\x24\xc5\xb6\xdb\x53\x2e\xeb\x6a\xb8\x45\x28\x1e\xa5\xb8\x47\xbe\xe6\xc7\x57\x68\xda\xbb\x5c\x75\x57\xbf\xf4\x87\x39\x47\x4c\x15\xae\x65\xf6\xb9\xf8\x63\x32\xc3\x92\x9c\xe9\x77\xe1\x32\xf6\x57\x23\x50\x77\x06\xad\xc4\x90\xda\x6a\x24\xe0\x3f\xaf\x22\x28\x41\x28\xde\x6a\xc4\xdc\xff\xa8\xea\xb7\x69\x77\x74\x9a\xcc\xd9\xcf\x29\xc8\x8c\xf0\x5a\x03\x66\xf3\x9d\x59\x08\x15\xa4\x29\xd6\xbd\xb0\x0c\xe7\x60\x68\xb7\x37\x1d\x68\xc4\x7b\xb5\x81\x87\x82\x1f\x7f\x9b\xeb\x2d\x28\x80\x0c\xed\xb1\xbe\xe5\x6d\x7b\x1d\xc4\xae\x4a\x47\x1a\xab\x09\x2a\x6f\xc4\xa5\x36\x2d\x2d\x7b\x0c\x82\x40\xa1\xbf\x25\x47\x00\xe6\x1e\x1a\x97\xad\x0e\xcd\x78\x28\x04\x51\x82\x2b\xf3\xbf\x79\xf9\x33\x9f\x17\xc0\xa6\x10\x48\x4e\x4d\x0f\xb7\xce\xb5\xc6\x7d\xf2\xa1\xaa\xe7\x36\x12\x08\x83\x24\x0b\xbc\xa8\x4b\x2f\x07\x4b\x21\x04\x92\x19\x89\xf2\xd3\x29\xef\x5e\x91\xdf\x66\x2c\x23\x28\x44\x9c\x63\xe7\x5f\x5c\xae\x68\x95\xd4\x9d\xc6\x9d\x22\x0e\x55\x6a\x1d\x72\x9e\xf3\xf2\xdf\xfc\x5b\x5e\x5a\x9d\xb3\x41\xfa\x0f\x71\x08\xd4\x2a\xeb\x20\x4a\x7b\x0a\x9a\x86\x38\x09\xf1\xd6\x68\x90\xaf\xb6\x93\x71\x77\x9d\xd4\x95\xdd\x43\x82\x18\x42\xa4\xff\xd6\xc3\x76\xd7\xe8\x27\x27\x2c\x44\x48\xc9\xdd\xcb\x61\xf7\xb2\xd8\xee\x17\xae\x6b\x06\x69\x14\x63\x81\x0b\x59\x35\xbd\xcc\xc6\xd8\x28\x92\x02\xe1\xa0\x9c\x98\xe4\xa1\xfb\x9f\x6e\x57\x77\x6a\xab\x4b\x7e\x3a\xf3\xfc\x58\x8e\xb0\x0b\xf6\x83\x94\x10\xcc\x5d\x96\xbb\xe5\x96\xd7\x60\x45\xb1\xc7\x13\x0c\x7f\x02\x33\xa5\xd5\xd5\x76\xf5\xb4\x79\x3e\xbc\x6c\x37\xcb\xd5\x6e\xb7\x71\xc4\x4f\x60\x61\x88\x0a\x02\xba\xaa\x25\x8c\xca\xbe\x5e\xa9\xc5\x0d\xcd\x08\x4f\xe2\x9b\x98\xdc\x1f\x85\x30\x30\xc9\xdd\x4f\x5e\x1b\xff\xdf\x4f\xa7\x21\x64\x3a\x46\xe4\x4d\x59\x75\xef\x56\x33\x69\x04\x01\x8f\x15\x22\x56\xba\xc8\xad\xe4\x27\x67\x1d\xee\x62\x56\xe0\x49\x82\xdf\xb7\xcc\xdf\xf3\xff\xb8\x8b\xe0\x2c\x20\x56\x4a\xe2\x99\x9f\x4c\x86\x36\x27\xf7\xd8\x8d\x34\x92\xe2\x79\x83\xa9\xa2\xb3\xf8\xfd\x6f\xdf\x81\x03\xce\x79\xe0\xb7\xb0\x85\x73\x66\x79\xa8\xea\xe1\xab\x2d\x22\x86\xf6\x78\x4d\x0b\x67\x8c\x3b\x30\x0d\xf1\x47\x65\x8c\x30\xc6\xb2\x2a\xad\x74\x5c\x97\xf2\x7b\xb9\x23\xff\xc6\x45\x7d\x4f\x8a\x4d\x9c\x7d\x9c\xdd\x2d\x05\xc9\x42\x23\x66\x88\xc4\x3b\xe0\xa7\x11\x8f\x0b\x14\x17\xd8\x82\xb3\x13\xc7\x8b\xf5\x0f\xdf\x1a\x20\x1c\xb9\x0f\xf5\x0d\x94\x0f\x80\x19\x99\xbc\xff\x5c\x72\xf9\x76\x77\xb9\xbe\xf0\x69\x43\x19\x40\x85\x9a\x8e\x38\x2c\x2f\x7e\x03\x03\x2d\xb5\x8c\xfa\xb2\xe8\xb5\xba\xb4\x43\x4b\x46\xaa\x83\x38\x71\x22\xb4\xdf\xeb\x7c\xbe\xf0\xa7\x03\xce\xf0\x01\xba\x05\xbd\xf5\xfb\xf0\x0d\xa3\x48\x87\x61\x18\x0e\xf8\xdc\xf9\x7f\xa1\x0b\x5d\x6e\xf4\x4d\x74\xc8\x22\xec\x92\xe7\x65\x03\xf5\xb0\xc8\x3e\x1d\x27\x13\x5c\x6b\xbb\xd0\x00\x8b\xe7\x1f\x55\xa0\x66\x57\x4a\x1d\xc5\x52\x38\x59\x28\x5e\x14\xbb\x96\x4f\xbc\x05\xa9\x8e\xd3\x84\xd9\xf0\x6e\xf1\x9f\x0b\xaf\xf3\xcb\x69\x72\x0d\x49\x10\xe3\x02\xa6\xe0\x03\xb7\x7b\xe6\x07\x2a\x54\x5e\x77\x30\xd2\xbb\x6b\x8b\xf6\xf3\xee\x75\xd0\x49\x62\x40\x42\x5b\x90\x90\xbf\x83\x7a\xdc\x2f\x3f\x6d\x18\xeb\x84\x12\x6a\xb5\x6b\xbb\x7d\xcd\xaf\x22\x3a\x25\x21\x96\x4f\x70\x83\x36\x4f\xd6\x2c\xba\xff\xfc\xd7\xc0\x2c\x68\xf2\x5f\xee\xb3\x94\xa1\xd2\x83\x95\x1a\xa8\xe4\xac\x83\x93\x1d\x4c\x40\x61\xca\xf6\x6a\x1e\xe3\x9e\xff\x72\x97\x90\x41\x82\x25\x91\xa6\xad\xa6\xc2\x51\x9a\x27\x09\xee\x84\x17\x2c\x29\x2f\x79\xf3\x7a\x2e\x40\x1d\x27\xeb\x89\xe6\x84\x61\xb0\x61\xf8\x54\x0f\x55\x1d\x25\x98\x8a\x7c\x6e\x66\x45\x35\xa7\x19\x2e\xe4\xde\x6b\x36\xb5\xbe\x49\xa9\xf5\x9a\x4d\xdd\x40\x69\x14\x81\xac\x55\xec\x03\x32\xf1\x50\x8d\xe7\x05\xea\xa7\xbc\xf0\x6b\x86\xe6\x20\x41\x0e\x3a\x7a\xeb\xb2\xb9\xa0\x60\x24\x94\x28\xd3\xd3\xf4\x38\x24\xfb\x09\x91\x9a\x06\x35\xfc\xca\x47\xfe\x2c\x54\x0b\x9a\x48\xd3\xf6\x46\x19\xbe\xc9\x0b\x27\x00\x8c\xce\x9a\xc1\xc8\xa2\x28\xb0\xca\xa1\xc1\xa2\xbf\xba\xbb\xbb\x9f\xee\x79\x5a\x26\x02\x9d\x6d\xeb\x5c\xf2\x5a\xe5\xbc\xfc\xbd\xba\xc8\x41\x3a\xf5\x09\x54\xf5\x6f\x37\xfa\x0f\xee\x65\x95\x0a\xb2\x9e\xb9\x3b\xac\x8a\x7e\x70\xd3\xa5\x4e\x91\x30\x86\xf1\x4b\xb5\x85\x66\x26\x22\xb7\x43\x55\xc6\x43\xab\x27\xbf\x3a\x9d\x8b\xea\x0a\x1f\xb0\xd8\xb4\x92\xc6\x60\x58\x5c\xae\x0f\x75\x75\xfa\x9d\x5f\x8a\x3f\x11\xe5\xd2\x0a\x32\x9c\x8e\xbe\x84\xd7\x47\x74\xe3\x79\xab\x03\x93\x3f\x09\xc4\x91\x79\x73\x31\x9f\xa9\x6a\xcd\xb2\x20\x1c\x81\x44\x4b\x98\x25\xaf\xb0\x20\x60\x81\xea\xe3\xa8\x2e\x27\x9f\xf2\xd4\x07\x6f\x00\x0b\x42\x12\x60\xd5\xa0\x32\x76\x85\xa3\x53\x85\x54\x08\xbb\x62\x7f\xdd\x3f\x2e\x77\x16\x9e\x81\x09\xc3\x4c\x95\x82\x05\x21\x8f\x51\xdb\xae\xcd\x0b\x27\xb5\xd9\x73\x5b\xe7\x32\x33\x16\x44\x91\x42\xac\xee\xcb\xe3\xe2\x58\x03\x18\xcc\xc7\x5c\x0d\x8b\x05\x51\x62\x56\x58\xf4\xdb\xaa\xab\xee\x67\xe5\x35\xa8\x2f\x55\xa1\x1e\x2a\x53\x82\xfc\x3e\x46\x10\x74\x9f\x51\xa8\xfd\x04\xcf\xd5\xa9\xaf\x5e\xb2\x20\x4a\x8d\x2a\x87\x29\x4d\xd8\xfe\xd5\xf8\xa3\x31\x83\x28\xf5\xf2\x6f\x73\xf5\xed\xf1\xe5\xc5\x82\x06\x9e\xd4\xda\xf2\xbc\x98\x6d\x88\x75\xe3\x24\x56\x1f\x77\x96\xaa\xea\x7d\x07\x07\x45\x35\x16\x24\x84\xa6\x46\x2d\x4b\xe6\x27\x5e\x34\x07\xd4\xcf\x3e\x17\xb9\x5b\xba\x58\x90\xa6\x90\x49\xab\xed\xba\xfa\x85\x54\xb0\xf1\x37\x91\x0c\x70\xc3\x78\x87\x3a\xd7\xd7\x71\xb3\x69\xb6\xc8\xce\x02\x22\x49\x80\x56\xcb\x95\xa8\xda\xb6\xe6\xb8\x92\xf6\x09\x1b\x0b\x68\xa8\x63\x43\xc6\x3c\x57\x25\x94\xdd\xd6\x79\x50\x20\xf9\xbc\xfe\x23\x0b\xa8\xc5\xe1\x73\xa5\xfa\xaa\xad\x3d\xc6\x62\x86\x4a\x1d\x3a\x2f\x71\x03\x9e\x18\x93\xbb\x51\xcc\xd8\xd2\x7d\x81\x76\xf5\xce\x8b\x0b\x6f\x27\x2e\xa5\x6e\x1c\x07\x8c\x2f\xf2\x66\x2d\xab\x91\x92\x2c\x0b\x98\x22\x34\x1c\x56\xf8\x8d\x40\x70\xee\xe2\x0b\x16\x64\x41\x82\x8c\x9a\xe7\xcb\x09\x6a\x9e\xd7\xc6\x5e\xb4\x9c\x31\xd2\x9e\xfc\xc0\x2c\x34\xbe\x93\xdd\x8e\xfb\xbd\xcb\x19\x96\xfc\xa6\x2b\x65\x87\xf2\x44\xe1\x15\x3e\x57\xed\xa5\xb1\xde\x6e\xee\xfb\x45\x18\x21\x34\xa9\xad\x2e\x18\xb0\x96\x6d\xd3\x27\x65\x2c\x10\x94\x63\xaa\x8a\xd5\xf6\x41\x7b\x9f\x05\x42\xc5\xd8\x5f\xe5\x4a\x59\x83\x39\x03\x94\xbf\xaf\xe4\xa5\x3b\xcd\xbe\xda\x41\xa1\x27\x33\x5b\x26\x26\x18\xdc\xbd\xd6\x80\x09\xfe\xf0\x11\xab\x08\x34\x1b\x5a\x8d\x36\x17\xd1\xc8\x3a\xef\x92\x10\x28\x8a\xc9\xe3\x51\x09\xc5\x66\xf0\xf7\xdd\xfd\x6e\xbf\x7a\xc2\xf2\x9d\x3f\x13\x09\x90\x85\xbc\xac\xaf\xe7\xb6\x7a\xad\x4e\x7c\xfc\x45\x22\xc5\xb2\x80\xac\x6a\x18\x1b\x83\xb1\x40\x47\x71\x4f\x20\x71\x5d\x81\x2e\xf6\xf5\x22\x6c\x1f\x12\xd9\x3e\xec\x39\x0e\xdf\x7f\xf7\x35\x2a\xc3\x6c\x1e\x45\xb1\xbb\x5b\x55\xaa\x7b\x87\x71\x62\x61\x10\x11\x13\x4f\xf1\x16\x56\xb2\xda\x1a\xf1\x19\xe2\x0f\x53\xe3\xd3\x8f\x60\xd6\x2e\x1c\xfb\x6b\x06\x17\x2c\x0c\x93\x80\xdb\xa5\xc2\xf8\x80\x78\x19\x80\xf1\xcd\x0d\x43\x9d\xa2\x0e\xae\x74\xa5\x4b\xcf\x10\x64\x61\x94\x82\xe8\x19\x87\xee\xfe\x0d\xd5\xb7\xdc\xc8\x24\x08\x5d\xc5\xdb\xf7\x09\x1c\xe0\xca\x0d\x09\x35\x96\x42\x8b\xea\xf8\xbd\x9b\x15\x73\xef\x6f\x98\x24\x32\x89\xa6\xda\xe3\x4d\x2f\x51\xca\xc2\x84\xf2\xa8\xef\xdd\x3e\xe5\xe5\x40\xb9\xd2\x0d\x91\x19\x16\xd2\x2c\x39\xa9\x37\x05\x9b\x04\x13\x2c\x4c\x05\x41\x2e\xdc\x0e\xca\x21\x6b\x9f\x85\x84\x85\xb8\x78\x0f\xa4\x75\x22\x7f\x8c\xa7\xa6\x72\xc8\xdf\xe0\xa1\xe8\x25\x8f\x59\x48\x34\xc5\x19\xbe\x68\x9a\x4a\xe6\xfc\x33\xa3\x07\xfb\x89\x6e\xad\xeb\xbe\xa7\x5b\x75\x60\xa3\xb1\x58\x3f\x7d\x42\x94\x10\x4c\x92\x17\xc7\x3a\x5f\xbe\xf2\xbc\xbc\xe7\x2d\x9f\xbc\xcc\x21\xcd\xb8\xf0\x2e\xe8\xfc\x26\x1a\x1a\xbd\x1b\x59\x48\x51\x18\xcf\x21\xc6\xfc\x2f\xcb\x28\x4f\xc4\xa8\x26\x9a\x83\x5a\xe8\x16\xea\xe1\x13\xe0\x44\xa6\xcc\xa5\x79\x5b\x44\xd2\xae\xf5\x33\x74\x8b\x21\x9f\x38\x98\xb0\x50\xc4\xa6\x20\x78\x50\xa8\xc2\x30\xbd\x6c\x11\x4b\x8c\x1b\x97\xdd\xbb\xd2\x27\x63\x2c\x14\x69\x6c\x62\x0c\xe7\x73\xdb\xdc\x76\x6b\x7c\xa9\x88\x85\x82\x07\xd8\x7c\xf2\x1e\xb7\x53\xa4\x1f\x0b\x9d\x99\x75\xe3\x2c\x12\xda\x71\xab\xc9\xce\xa2\xd1\x66\x15\xca\x48\x1b\x89\x6c\x18\xfa\xb1\xba\x8b\x94\x3c\x8c\x8c\x1d\x47\xd9\x5c\x4e\x60\x84\xa9\x66\x83\x3b\x16\x4a\x1d\x25\xb2\x97\x28\x9d\x5f\xbf\x43\x95\xc6\x86\xf1\x56\xbb\x75\x39\x54\x44\x12\xdd\xcb\xe4\xfc\xe1\x9f\x96\x52\x21\x0b\xad\x6d\xe4\xc8\x13\x9c\x85\x10\x70\x14\xe6\xfb\x91\x8f\x5f\x40\x36\xf9\x3a\x08\xa5\x1c\x22\x72\x9c\xcd\xa7\x3f\x4f\x16\x63\x71\xb4\xb9\x9c\x4e\x2f\x83\x8a\xb1\x3b\x2c\x85\xfd\x4d\x26\x85\x1b\xf2\x73\x59\xa8\x83\x30\x45\x5d\x81\xfc\x6c\xfb\x57\xfe\x40\x24\xc8\xd4\x83\x6a\x36\x58\x08\x75\x9c\x6a\xdb\x26\x7a\xe4\x56\xdf\x71\xad\x26\x4f\x56\x2b\x13\x69\x75\x1b\xcd\x92\x97\xca\x6d\x5c\x51\x10\x9b\xa0\x17\x4e\xb9\x2f\x47\x7f\x6e\x98\xc9\xa2\x80\xc7\xc8\x18\x7c\x87\xb6\x1a\xe4\x92\x37\x8f\x2a\x0a\x24\x24\x0e\x05\x7a\xbb\xae\x46\x51\x6c\x42\xc9\xe6\x95\xc7\xb2\xa8\x4a\x18\x80\x61\x58\x14\x51\x12\x86\xae\x99\xc8\x8b\xbc\xc1\xdb\x7e\x00\xad\x01\x61\xe6\x93\x93\xc5\xcc\x28\x53\xb9\x34\xc3\x59\x83\x59\x1a\xe7\xf8\x17\xc4\x22\x13\x66\x9f\x5f\xe3\x39\x10\xaa\x3b\x39\x9f\xe2\x18\x83\xfd\xfe\xed\x6e\xb8\xec\x45\xb1\xe6\xc6\x89\xb4\x4b\xc7\xee\x6b\x7e\x44\x9b\x91\x41\xe0\x3a\x0c\x87\xa2\x44\x64\x98\xda\x9d\x2a\xdd\xf2\xb7\xd1\x89\x28\x31\xa8\xdf\x1a\x34\xd4\xbc\xb8\x65\xc5\xb2\x88\x8a\x18\x8c\x63\x68\x97\x66\xbe\x54\xcd\xcd\x00\x4d\xd1\xeb\xba\xb6\xc9\xc5\xb8\x24\x3b\x79\x1a\x98\xc0\xfc\x9f\xff\xef\xff\x7c\xbd\xc7\xeb\xc8\xb2\xf9\x64\x20\x62\x99\xb1\x7e\x2e\xaa\xc6\x87\xb9\x11\xe3\x11\x6e\x4d\xdd\x82\x78\x1d\xfd\x8e\x2c\x20\x38\x7c\xbd\xc3\xd0\x7e\x7c\xae\x2c\x36\xc4\x83\x22\x7f\x9b\xde\xe0\x2c\xe1\x28\x27\x81\x6c\xe4\x70\xe5\xbd\x3b\x59\x94\x51\x85\xb1\xa6\x02\xdd\xe5\x77\x8f\xa8\x0a\x7b\x7f\xa9\x87\xf3\x2e\xca\xb2\x24\xb5\xd6\x7e\x2f\x75\x75\x86\xda\xe2\x10\xc2\xe9\x4b\x98\x71\xd3\x6d\x7d\x5a\x3f\x1f\xbe\xac\xf6\x56\x5c\xf5\xf0\xb0\x7e\x7e\x5e\xfd\xe1\xcf\xa6\x98\x25\x98\x1a\x65\xbb\xe3\x30\x03\xb2\x63\x38\x55\xb8\x81\x9b\x56\xc7\xa2\x6c\x7e\xc2\xbc\x5a\x39\x8b\x38\x8f\x91\xb9\x69\xbd\x94\x06\xde\x96\x6e\x5f\x8d\x04\x95\xc2\xf2\x11\x7f\x5d\x77\xd0\x2e\xab\x2e\x51\xee\x9b\x76\xb3\x79\x65\x24\x40\xe3\x72\xda\xed\x28\x23\x26\x30\x8b\x24\x01\xea\x77\x26\x9f\x2e\x0d\x0f\x23\x42\xa2\x8b\x90\xd1\xe2\xea\x73\x1b\x70\x7f\x9d\x52\x26\x54\xf7\x6e\x67\x98\xb6\x4f\x5e\xb3\xd9\x75\x29\x52\x94\x62\x2d\xea\xe1\xeb\x72\xb2\xa5\x45\x4a\x50\xd4\x30\xbc\xe3\xed\x89\xdf\x84\x6a\xc3\x8d\x38\x02\x95\x04\xd2\xb6\x1d\x2e\x65\xde\x5e\x87\x85\xf4\x59\x77\x16\x16\x69\xaa\x30\x22\x44\x57\x8b\xd7\xba\xfa\xd9\x6c\xc1\xf8\x63\xe2\x3c\xfa\x58\xef\x91\xc5\x41\x94\x19\xa5\xad\x6e\x76\x8b\x19\x9a\x04\x8b\x83\x98\x60\x4e\x88\x05\xf9\x83\x17\x7a\x64\x71\x40\x55\x10\xf8\x7e\xbd\xef\x12\x8c\xae\x2d\x0e\x53\x8a\xd1\xdb\x89\xff\x1a\x96\x7e\x59\x1c\x32\x96\xd8\x1e\xbb\xe1\x37\xcd\x44\xa2\x71\x24\x12\x16\xd9\xc8\xae\x84\x62\x59\x95\x3a\x3f\xba\x89\x31\xdc\x59\xe2\x48\x2b\xab\xc4\x89\x40\x53\x3e\x09\x00\xe3\x58\x08\x14\x9d\x7c\x78\xfc\x76\xff\x50\xd5\x5f\xb8\xbf\x90\x58\xca\xd0\x76\xd9\x9f\xf9\x09\x9a\x33\x97\xd3\xcb\x48\x82\x40\x3b\xd2\xdd\x45\x1d\xa1\xdd\x68\xd7\xe7\x18\xa7\x38\x71\x92\x50\x8c\x51\x44\x0d\xfc\x0d\x59\x64\xee\x00\x67\x46\xaa\xbb\xe0\xf9\xc9\x95\x58\x58\x9c\x00\xc3\x6c\xfa\xa1\x80\x5f\x83\x4a\x41\x9c\x06\x1a\x81\xb3\xe7\xba\xc2\x4f\x58\xbb\xce\xa1\x79\x2a\x8b\x53\x16\x60\xdc\x9b\x37\xbe\xe9\xff\x60\x93\x5a\xff\x05\x29\x33\x22\x88\x8f\xd5\xf1\x7f\x2e\x50\x5f\x1f\x00\x76\xb7\xba\xee\x6e\xb0\x52\x91\xb5\x87\xff\xb6\x3a\x74\x0b\xc8\xe2\x8b\x4b\xab\x62\xca\x45\x9a\xf5\x8a\x6a\x36\x7e\xbe\xe9\x44\xd9\xd1\x2c\x30\x7d\xd2\xbb\xe5\x5f\x82\x2f\xb3\x98\x51\x8e\xf9\x1f\x52\x05\x26\x48\xd7\xc9\x65\x66\x69\xea\x5e\x9d\x3b\xde\xe4\x72\xd9\x2d\x5e\x58\xd5\x78\x81\x3a\x0e\x7a\x3f\x61\x16\x67\x40\x50\x6a\x0b\x85\x1e\xa2\x8f\x0b\xb9\x2c\x16\x11\x47\x6f\x93\x97\x6e\xc5\xff\x83\x97\x6f\x80\x8a\xbc\x9f\x4d\xd6\x58\xf0\x10\x05\x14\x50\x7d\xb9\x5b\x2d\xbe\x54\xbc\xd8\x02\x97\xaf\x36\xf0\x71\x4f\x4a\x06\x42\xd8\xc0\xc0\x15\xfc\x70\x36\xdc\x5a\xa8\x4c\x17\x97\x1b\xe6\x0f\x8b\x65\x64\x5c\x2c\x1b\xa3\xa2\x1e\xcd\xaf\xc9\xb1\x4c\x4c\x22\xd3\x8d\xf9\x01\xf0\xb6\x29\xfd\xac\x97\x94\x99\x05\x03\x2d\x70\x7a\x45\x21\xd4\x63\xf0\x83\xc0\xd8\xbe\xf5\x26\xb5\x8b\x22\xe7\x1f\x94\xc9\x62\xa9\x6d\x6c\x83\x7a\xa2\x6d\x5b\xc0\x27\x3c\x0c\x16\xab\x50\xe2\x73\x71\x2b\x94\x7c\xe5\xf5\x71\x20\x4a\xce\x62\x95\xb2\xcc\xe9\x0a\x3e\xfe\x3e\x06\xd3\xb1\x58\x81\x42\x20\x9a\xb7\xf8\xee\x36\x4d\xfc\xf8\xf8\xb2\x94\x06\xdc\x35\x97\x55\x29\x8b\x8b\x82\xe5\x2b\x2f\x0a\x28\x8f\x30\x5b\x97\x8c\x21\x88\x4d\xfd\xcb\x95\x4c\x0d\x12\xfd\x21\xff\x65\x08\x84\x87\x0f\x7e\x0e\xc4\x89\x30\x64\xdb\x5f\x0f\xe0\xf7\xa0\x18\xb2\x88\xcb\x5e\xf3\xb7\x99\xba\x9d\xb1\x58\x13\x16\x19\x39\xa4\x63\x8e\x95\xe2\xbc\xbc\x54\x97\x66\x10\x51\x27\x41\x60\xb4\x66\xb0\xf5\x7f\x67\x1c\xe9\x66\xf8\x09\x2c\x09\x64\x88\xe2\x5b\xbb\x2e\xd1\x2c\x9e\xab\xd6\x9f\x22\x0a\x05\x96\xc3\x5e\x0a\x3e\x8a\x65\x92\x28\x0a\xc1\xc1\x71\xee\xf2\xe3\xa6\xde\x9d\x78\x31\xef\xe7\xce\x92\x28\x4d\xb0\xb5\xfc\x7d\x77\x7f\x6f\xeb\x83\xfe\x3c\x59\x8a\x0e\x7c\xc6\xd3\xad\xaa\x3d\x37\xe2\xb3\x52\x35\x4b\x62\x92\x21\x29\xbb\x0b\x28\x1b\xab\x3a\xef\x0f\x49\x9e\x3a\x94\x54\x5e\xba\xe5\xd6\x86\x9e\x7d\x9a\x97\x24\xb1\x29\x80\xbe\xf0\xeb\x31\x2f\xe1\x2b\x6f\x8c\xb8\xdf\x84\x0c\xc7\x92\x44\x1a\xb9\x60\x97\x62\x98\xf7\x73\x5f\x39\x69\x8a\xdf\xfc\x38\x81\xf8\x2e\xc1\x5b\xde\xf2\x5e\xaa\x8d\x25\x89\x0a\x32\x6b\xdb\xdc\xe5\x14\x68\x59\x3b\xf9\x92\x34\x0c\x52\xe9\x8c\xcd\xeb\x1c\xb0\x4e\xb1\xc2\x02\xf6\xc2\x85\x03\x09\x01\x03\x3c\xec\xae\x62\xe8\x5c\xc7\x12\xa2\x43\x44\x5a\xdb\xca\x8b\xb3\xf5\x1a\x7f\x07\xd1\x59\x46\x1d\x5c\xc3\x45\x06\x03\xd8\x10\x4b\x68\xe2\x75\x09\xbf\x5e\x45\x9d\xab\xfc\xbf\x86\xb0\x7c\x29\x8a\x5b\xb4\x2d\x4b\x28\x15\xce\xc0\xfc\xee\x72\x7d\xe2\x33\x70\x39\x96\x50\x69\xd8\x51\x77\x8b\x7f\xac\xdd\x17\xb1\xd0\xf8\xcd\x15\xdd\xec\xed\xbd\xf8\x46\xcc\x63\x96\xb0\x8c\x44\xc4\x15\x9e\xaa\x5f\x9f\xdb\x21\xb3\x84\x71\xc1\xa3\x09\xea\xd0\x40\x9f\x66\xd6\xc4\xe9\xea\x98\x64\x20\x99\x31\xc7\xe1\xa5\x35\x19\x74\x0b\xdc\xad\x8f\x23\x4b\x78\x62\x84\x78\xb8\x52\xaa\x6a\xe5\x6b\x5b\x55\x5a\xc3\xcd\x8b\x6b\x47\x8b\x34\x16\x96\xdb\xb5\x46\xa9\xd7\xff\x55\xbf\x95\x25\x82\x64\x28\xd4\xd8\xad\x66\xc6\x77\x7b\x26\x05\x4f\x64\xa6\x52\xe9\x8b\x55\x9e\xc3\x7c\x2b\x30\x67\xc7\xab\xc8\x14\x7a\xf2\xd2\x79\x1a\x8f\xdf\x2a\x95\x05\xb2\x4f\xe1\xf2\x06\xa9\x47\x43\x22\x58\x37\x24\xc2\x82\xd2\xa1\xdb\x53\x51\x70\xc0\x48\xd0\xdf\xac\x58\x89\xa6\x41\x9a\x78\xbe\xf4\xd3\x75\x2d\xab\x01\xbb\xcb\x0d\x62\x11\xda\xbb\x74\x59\xf6\x5d\xb7\xb4\xd9\x03\x69\x10\x27\xf8\x6c\x8d\x76\xd1\x7e\xa4\x4b\x3b\xc9\xce\x3e\xac\xac\x1a\x77\xf8\xe1\x2b\x93\x06\x24\x44\x64\x89\x81\x15\x2e\x46\x05\xfd\x61\x7e\x9a\x06\x2c\x43\x90\x33\x96\x3e\x47\xae\xec\x2c\x0d\x38\x33\x8b\x61\xb7\x48\x4e\xeb\x82\x69\x00\x09\x7a\x08\x4e\x25\xf8\x56\xbc\x2e\xae\x7b\xa8\x4f\x39\x32\xde\xa7\x42\x7c\xdd\x07\xb5\xc3\xbf\x6d\xe1\x98\x57\xe5\xde\x1a\x8a\x85\x93\x4b\xd3\x31\x77\xfe\x08\x06\xbe\x9b\x57\xe5\x1a\xf9\xd3\xde\xaf\xc0\xff\xe0\x90\x05\xb8\xff\x2d\xbf\x2e\xb6\xeb\xfd\x1f\xbb\xd5\x62\xb9\x71\xb2\xd2\xdd\xd1\x78\x64\x41\xe9\x61\x31\x5d\x02\xf1\xb5\xfa\x39\xef\x51\xe8\x3f\x2c\x20\xe8\x73\xec\xad\x29\x4e\x8d\xe6\xce\x44\x06\xda\x7f\x50\x49\x07\xd4\xe8\xbe\xc8\xe8\xd9\xd8\x83\x51\x6c\xb4\x9d\x4e\x79\xb9\xda\x7f\xed\x5f\x88\x38\x8d\xc1\x38\x19\x9d\xf2\xf2\xd0\x40\xdb\x33\x0f\x6e\x08\x16\x2c\x8d\x49\xaa\x52\x87\x50\x12\x45\x5f\x81\x4c\xe3\x2c\x42\x80\xeb\xae\x8b\x4e\x51\x57\xde\x6a\x5d\x0c\x3f\x9d\xc5\x28\x45\xec\xd2\x28\xcf\x5c\xf6\x27\x91\x26\x89\xc0\x89\xf2\xad\x94\x8b\x5a\xe4\x6d\xcd\x8f\x70\x63\xd1\xd8\x8d\x05\x6c\x3a\xff\xbb\xca\xcb\x61\xc2\x3b\xb9\x9b\x89\x0a\x11\xf3\x60\x85\x7d\x7f\xe4\x13\x25\xbd\x6e\x84\x46\x6e\x22\x42\x28\x3f\xaf\x0d\xa7\x09\x00\xd6\x1e\xb4\xcc\x27\x5b\x70\x9a\x06\xa1\x62\xde\x9b\x6f\x64\x4a\xc6\xba\x78\x99\x09\xa7\xf1\x28\xe1\x8e\x37\xd8\x7d\x9c\xb4\xee\xd2\x94\x03\x86\x1a\x87\x11\xb8\x75\x7c\xb9\x24\x54\xb8\x67\x4b\xde\xbc\xde\x71\xf9\xf6\x50\x57\x27\xcb\x2d\x9d\x5f\x9e\x52\x92\x46\x26\x13\xbf\x14\x9e\x4d\x72\x19\xb0\x47\x58\xca\x02\x93\xc0\xee\x2e\xf5\x3b\xdc\x6a\xae\x8c\xcd\x8c\xfc\x8c\xe4\x32\x45\xeb\x08\xd4\x5b\xdb\x41\xbb\xb8\xa8\x7c\x2a\x11\xc1\x52\x11\x11\xb3\xf8\x19\x39\x50\x04\x6c\xce\x06\x71\xa9\xe4\x06\xdf\x28\xf2\xb6\xdb\xf5\x4d\xef\xb3\xc9\x8f\x87\x77\xec\xba\xdb\x51\x4a\x6a\x5c\x29\x77\xd6\x4c\x64\x68\x10\xfa\x89\x2a\x3a\x4b\x15\x30\xf0\x75\xfd\x75\xf9\x7d\x77\xef\x4e\x09\x81\x50\x36\xae\x18\xf7\x72\xe6\x4f\x04\xb1\x42\x61\x98\xc7\xaa\x3c\x2e\x8b\xaa\xf9\x80\x91\xc8\x52\xd0\x32\x0d\x06\x30\x90\x9b\xf3\x8e\xd7\x14\x1d\x0b\xd4\x4a\xd9\x6f\x76\xb6\xb0\x6b\xb1\x49\x93\x72\x46\xaa\x63\x2d\x6c\xe2\x6f\xa5\xb6\xfe\x0b\xb3\xd8\x45\x46\xc2\x24\x42\xad\x3a\x6c\xf4\x1b\xab\x91\xd9\x7e\x2b\x09\x65\x82\x72\x35\x2e\xf2\x1e\xe9\x73\x31\x12\x82\xb1\xa7\x3b\xe5\xa5\xd9\x6d\x06\x0a\x0b\x8c\x84\xda\x08\x3e\x7f\xe5\x45\x7b\x13\x21\x92\x28\x35\xc2\x74\x5d\xa6\x71\x9f\x37\xe7\x4b\x0b\x6a\x5d\xbe\xf3\x22\x57\xbb\x6e\x9a\x94\x12\x7e\xd4\x55\x79\xfc\x51\xe7\x2d\x0c\xa0\x70\x8c\xc4\x41\x8a\x3c\x67\x94\x58\x7a\xa8\xea\x11\x9d\x9e\x91\x38\x0c\x8c\x68\xd1\xaf\xf3\xa7\xb8\x41\x46\x62\x1e\x3a\xb1\x85\x3e\x3c\x5a\xfe\xf0\x27\x52\x46\x38\xbb\x86\x33\x32\xa7\x9c\xc3\xfa\x9f\x04\x17\xee\xd3\xda\x88\x66\x72\xf9\x56\x56\x3f\x11\x47\x64\xd6\x92\xf1\xb0\x24\x24\x06\x8d\xda\x1a\x8a\x4a\x0d\xbf\xcd\xe4\xb4\x24\x89\x13\xd0\x2e\xdd\x30\xad\x9c\x89\xe1\xfb\xe4\xeb\x13\x6d\x4a\xf7\x30\x91\xc4\x1b\xcf\x71\x92\x68\x53\x5b\xc0\xb5\xf5\xa6\x15\x43\x48\x4a\x2c\x18\xa5\xbc\x34\xb6\x96\x3d\x8a\x62\x08\x51\x71\x60\xd1\xb4\xbd\x66\xde\xf2\x06\xd3\xcb\x08\x0d\x42\xdc\xc0\x4c\x30\x60\xdb\x71\xc3\x6b\x0f\xfd\xc8\x48\x41\xe6\x03\xad\xad\x11\x82\x9d\xbe\x99\x34\x4b\x5d\x7d\xc8\x60\x9c\xaa\xfa\xe4\x59\xa6\x6e\xf2\x10\x0a\xd2\x85\xd0\x5d\x84\x3d\xe5\x37\x32\xc2\x52\xc1\x43\x6f\x3b\xb8\xd1\x3e\x83\x70\x2b\x38\x61\x99\x71\xf6\x3f\x74\x51\x53\x17\xf0\x6e\x79\x77\x17\xbe\xe4\xef\x7f\x02\x0f\x67\x84\x89\x34\xed\x79\xf1\x5b\x14\x29\xc7\xd7\xb9\xfe\x90\x20\x3f\x9a\xfb\x84\x49\x85\x44\xc1\x27\x5e\x7e\x2f\xf3\x16\xd4\x6e\xe9\x2e\x2b\xcb\x12\x47\x4f\x75\x85\xe7\x65\x55\x54\x96\x89\xe0\xef\x65\xa6\x92\x54\x0f\xd0\xfb\xb6\x6f\x79\xd3\xa0\xeb\xfe\x1d\x53\x21\x19\xe1\xb1\xc0\xed\xe9\xc7\x6e\x6d\x57\x9e\xd5\x7f\x2e\x79\x7b\x1d\xd0\x14\x18\xe1\x99\x40\xe8\xa4\x05\x84\xf1\xf2\x63\x90\xc4\xf4\xf4\x5a\x41\x30\xb6\x14\x1f\x15\x0f\x89\xe0\x11\x19\xf8\xd2\x61\xf6\xf3\x50\xd5\x5d\xe8\x73\xdd\x94\x4e\xae\xca\x5d\x88\xd0\x11\xe6\xc1\x2d\x7f\x83\xa5\x56\x53\x86\xa4\x1d\x25\x49\x82\xce\x71\xb9\x47\xc6\x39\xa0\xf3\x64\x1c\xa3\x46\xf2\xf6\x52\xca\x43\x40\x29\x73\x5f\x23\x75\x80\x9d\xd7\x7d\x5e\x5e\xc7\x69\xd3\xf8\xd9\xab\x28\x91\x7c\x4e\x0a\xee\x86\x62\xc1\x88\x62\x04\xb8\xaf\x99\x3b\x58\x97\x4b\x30\x9e\xf8\xf9\xec\xb1\xc4\x8c\x28\x6e\x2c\x62\xba\xed\xa3\x35\xe8\x8f\xc9\x37\x03\xc7\x76\x97\x06\x30\x00\x16\xaf\xb5\xc7\x08\xc4\xd6\x69\x0d\x3f\xba\x2e\xdb\x87\x70\xd7\xd6\x0f\xd1\x6f\x3e\x71\x1b\xad\x3a\x3a\x32\x6e\xf4\x4e\xad\x6c\x07\xb2\x2a\xd5\x30\x82\x24\x9a\x10\x94\x7e\xc9\x9b\x3e\x23\x52\x53\xca\xcf\x65\x08\x43\x1e\xbf\xe3\x34\xe0\x8c\x59\x91\xbe\xf2\x72\x7a\xf2\x51\xb8\x3b\x2c\x00\xb1\xbe\x45\x75\x3c\xde\x4c\x5f\x1a\x92\x30\xb1\x77\x79\x0b\xcd\xb9\x2a\x1b\xf8\x3e\x0c\x92\xc6\x5f\x85\x4d\x4a\x5b\x29\x30\xaa\x69\xf3\xa1\xc1\x5c\x55\x91\x46\x3c\xc0\xc9\xdc\x3d\xee\xa7\xdc\x57\xed\x68\xac\x02\x44\x97\x4b\x3e\x61\xa7\x33\xda\xed\xb2\xb6\x5a\xb2\xac\x4e\xb8\x58\x8f\x4e\x99\x06\xc6\x57\xc5\x09\xf3\x3b\x9b\x1a\x77\x38\xf5\x95\xfc\x1d\xd4\xef\xb9\x1c\xe6\x7d\xe3\xd7\x8d\xa6\x24\x40\x78\x82\x55\x54\x73\x8b\xbe\x3b\x4a\x15\xaa\xd9\x3b\xaa\x78\xe3\x0f\x08\x2d\x2c\x63\xcf\xba\xea\x23\x6a\xd4\x1d\x26\xb1\x51\x60\x43\x49\xe1\x8d\x5e\xfc\xe4\x35\x94\x7d\xb3\x87\x12\xa1\x40\x0f\xd4\x8a\xb6\x3c\x6f\x7c\xb1\x88\x12\x19\x51\x6c\xd6\xf5\xc4\xad\xdd\x14\x02\x42\xbb\x57\x32\x1c\x9a\x13\xf4\xa8\x16\x4a\xd3\x08\xeb\x2e\xb9\x1c\x72\x49\x19\xa5\x34\x44\x5c\xc3\xb1\xe6\x65\x6b\x8c\x48\xe6\x83\x5c\x4a\xc1\xd8\xf5\x09\x5e\xbe\x5d\xc6\xe7\xd0\x59\x18\xd8\xca\xe8\xbe\x9a\xe2\xc2\xc7\xb1\x98\xfd\x08\xa3\x01\x4a\x81\xac\x0a\x78\x87\xd2\xfc\xef\xe8\x9c\x2c\x53\xcc\x82\x12\x6d\xa0\xb4\xd1\xa8\xb4\x3e\xbf\x46\x50\xa6\x08\xbe\x8f\xff\xb3\xfe\x3e\x3a\x4f\x46\x8d\xe3\xf5\xd7\xaf\xdb\x07\x6e\xfd\xd7\x3f\xcd\x40\x28\x0f\xb8\xe9\x06\xad\xef\xdc\x49\x78\xa6\x10\xf0\x77\x7e\xe5\x0d\x84\x56\x68\xc0\x54\xd7\x9e\x1c\x1c\x9a\x51\xce\x29\x62\x92\x0f\x28\x1a\xd3\xad\x69\x97\x3a\x1f\xf7\x30\xfd\x54\x14\x41\x84\x4d\xa3\xc5\xfd\xef\xeb\xdd\x66\xbb\x3b\x3c\x6e\x96\xdf\x0e\xf7\x8b\xfd\x44\xec\x9f\x51\x21\x14\xf6\xaf\x9a\x33\xff\x79\xa3\x0c\x38\x79\x44\x32\x48\xad\x0b\x76\xd3\x0e\x25\x60\xba\x23\x00\xa4\xb7\x26\x1c\xa2\x4e\xa8\x0c\x13\x84\x0b\x8a\x5c\x59\x30\xc7\xf8\x0a\x14\x37\x85\xef\x6e\xaa\xbf\xe6\x85\x9a\x75\x9e\x67\x54\x69\x1a\x18\xe9\xa5\x77\x68\xf3\x93\xdf\xf5\x29\x50\x6a\x7a\x08\x3f\xf3\x56\xbe\x5a\xcb\x24\x7f\x90\x07\xa9\x67\xa9\x5b\xfe\xc2\x6e\x50\x5a\xa3\xa0\x18\xc6\xd7\xdb\xfd\x9d\x03\x81\x50\x9d\x84\x42\x4c\x04\x6d\xa6\xe6\xfb\xb7\x85\x33\xaa\x75\x90\xda\x9b\xd0\xe5\xb3\x77\xd7\x97\x6e\x89\x70\x7b\xa5\x0d\xe3\x58\x10\xc6\x18\x4c\x37\x95\x35\xa4\x6c\xf0\x6e\xf9\xc6\x39\x0b\x13\x62\x38\x2e\x88\xbe\xf3\xd6\xe5\x9f\x2c\x78\x2c\xd2\x0c\x73\xf7\xfb\xf5\xb3\x73\x77\x63\x2c\x4e\x0c\x1d\xbd\xdf\x3f\xad\xc0\x61\xef\x3f\xcd\x58\x4c\x42\xec\x32\x61\x29\x60\x00\x48\x62\x71\x16\x70\x03\x61\xcb\x51\x54\xed\x3e\xd7\x28\x7c\xd0\x9a\xf8\xfe\x4f\x9b\x2c\x2c\x56\x21\x0a\x10\x54\x97\xb6\x69\x39\x16\x70\x5f\xd0\x5e\xda\x1e\x4f\xb2\x8c\x67\xae\x9f\x67\x41\x21\xf6\x50\x1a\x64\xd4\x64\xe2\xe7\xaa\x6e\x9f\xf2\xa6\xe9\x72\xa8\xd7\x4b\xf9\x36\x55\xb9\xfc\x6c\xbb\x62\x69\x0c\xb1\x0d\x4a\xd0\x56\x34\x62\xfe\x0b\x12\xa9\x95\x13\x0f\x47\xed\x94\xf1\x3b\xc9\xd2\x2c\x44\x96\x2d\x5a\x7f\xcc\x0b\xb1\x33\x96\x0a\x86\x3d\x7b\xdc\x64\x8b\x29\xb3\x9b\x31\x12\x65\xc8\xeb\x55\xc8\xd1\x40\x77\xc6\xa6\xae\x2a\xff\x33\xbb\xf8\x00\x9c\x78\xdd\x07\x0e\x18\x33\x37\x96\xb2\x24\x34\xa2\xe3\x93\x8b\xa6\x4c\x20\xfe\xe5\x27\x7f\x83\xef\x67\x13\xf1\xd8\x43\x2c\x0c\xb4\xee\xcd\x06\x5e\xf2\xfb\xbc\x91\x83\x49\xca\x58\xc2\xa1\x3b\xe9\xe1\xd2\xc0\x43\x5d\x9d\x3e\xa0\x3a\x32\xc6\x58\xaa\x8d\x63\x4a\x2e\x21\xdc\xe8\xe9\x61\x30\x5e\x18\x56\xc3\xad\xda\x5c\xde\x73\x55\xd5\x39\xff\x93\x08\xe3\x6f\xa3\xb3\x70\x6a\x50\xb5\x47\x68\x17\x5d\xec\xb4\x56\x06\x5d\x56\xaa\xcd\x2d\x69\x9f\x31\x2e\x62\xe7\xf4\xea\x64\x12\x31\x03\x9a\x76\x08\xed\x70\x11\x04\x18\x7e\x9e\xf2\xb2\x1d\x54\x5e\x6f\xf9\x0c\x1f\x36\x50\x99\x60\x1c\x57\x42\x2b\xc8\xb2\x28\xd5\xb2\x5b\x60\x86\x70\x24\x26\xb2\x04\xeb\x3c\x4f\x7f\x6c\x0f\x9b\x53\x99\xab\xaa\x28\xb8\x7f\xfd\x85\x8c\xb0\xa1\xf9\x3b\xaf\xf3\xd9\xfe\xa5\x1d\x27\x09\x37\xb5\x9f\xea\x7d\x46\xe1\x8e\x31\x15\x51\xab\xbe\x69\xb2\x06\x0f\x6d\x99\x65\x69\xcc\x2d\x1e\x2a\x4b\x49\x8f\xa9\xb7\x81\xcd\x4d\xd9\x9a\x81\xd6\x81\xed\x41\x60\x6a\x55\x15\x23\x2b\xf0\x9e\x09\x34\x7e\x73\x99\x7f\x6f\x75\xcc\x51\xa1\x97\x2b\x13\x96\xee\x2b\x04\x81\x7e\x5e\xab\x61\x3a\x31\x8d\xb1\xc7\xfc\xe8\xf0\xce\x1f\x01\x88\xe7\x6f\xa0\x4e\x0c\xd4\xef\xd2\x80\x5a\x56\xf5\xc8\xe0\x97\x31\x9d\x51\xec\x47\x98\xf6\xf6\x41\x97\x72\x7e\xa1\x9d\x05\x48\x65\x41\x4c\x52\xd2\xd7\x26\x77\x06\x70\x7d\xbe\xad\xce\x64\x01\xe1\x91\xed\x7b\xec\x10\xb5\x33\x25\x9e\xb2\x2c\x4c\x4d\xaf\x73\xdd\xc2\xc9\xf1\xb7\x7e\x73\xc7\x08\x77\xad\xe4\xc7\x5c\x42\xd9\xc0\x1e\xea\xd3\xad\x10\xd5\x48\x9f\x69\xf8\x7f\xdc\x79\x64\x86\xd0\xed\x77\xa3\xce\x07\x3d\x2b\xf1\x16\x9f\xfd\x51\x37\xe1\x46\x03\xea\x83\xf5\x37\x8b\xa8\x89\x58\x9d\x15\xa0\xfb\x31\x11\xd3\x94\x7b\xfd\x86\x1f\x90\x4f\xee\x55\x1c\x80\xb1\xaf\x76\x71\xe6\xf8\x95\xcf\xe2\x08\xb0\x10\x20\x2e\x75\x69\xca\x77\x06\xc2\xe8\x8c\x17\xc7\x57\x11\x13\x81\x49\x58\x91\xbf\xc3\x2e\xef\xe1\xd5\x59\x12\x04\xa8\x94\xcb\x7d\x05\x6e\xb8\x3f\x65\x49\x10\xe2\xb7\x60\x11\xf3\xf5\x26\x13\xcc\x92\x38\x42\xb9\x64\xae\x94\x9d\x33\x8e\xbd\x3f\xbe\xda\x24\x49\x89\xc3\x16\x1d\x0c\x1b\xf1\xa0\xf3\x52\x61\x27\x21\x2f\xdb\x97\x1a\xde\xb7\x58\x3e\xf1\x4f\x3b\xd1\x21\xd6\x12\xf0\x67\x75\xb1\x29\xce\x93\xb9\x02\x86\x4b\xc0\xb3\x34\x13\x8e\xaf\xd1\xcd\xce\xdf\x46\x37\x94\x26\x0c\x37\xc2\x2e\x0c\x2e\xf6\x3f\xab\x5b\x9d\x7c\x96\xb1\x88\x70\xfb\x73\xbe\x4c\xbc\x54\x59\xc6\x28\x41\x06\xe9\xcb\x66\x37\xd0\x95\xfa\x5f\x75\xee\xb2\x2c\xa2\x98\x80\xbc\x57\x2d\x8a\xbc\xf8\xfe\xef\xe8\x9b\xb2\x48\x25\xd6\xcd\x18\x43\x27\x5e\x0c\x52\x92\xc9\x25\x67\xd4\x30\x07\x0d\xc1\xac\xb9\xbd\x32\x37\x0e\x18\xf2\x71\x1f\x78\xd3\x9e\x78\xfd\x06\x6d\x39\x22\x71\x64\x3c\x31\x02\xcc\xa6\xf4\xf4\xce\x5b\x40\xbf\xc1\xf1\xf3\xe6\x09\x64\x36\x9a\x78\x00\x40\xa1\xa3\x87\xaa\xfe\xfb\x6e\xf2\x65\x5c\xa6\xc8\xab\xd8\xd4\x47\x5e\xe6\xff\x85\x61\x92\x96\x71\xe0\x58\x69\x30\xae\x14\x8f\x7c\x62\x0b\xc6\x32\x11\x40\x68\x33\xd7\x89\x25\xbf\x1b\x10\x99\xb7\x69\xcb\x5b\x48\xdd\x69\x45\x0c\x72\x28\xf8\xf1\xf2\xfd\xce\x1f\x4a\x55\x22\xdc\x1c\xec\xb6\xb9\x6e\x52\x95\x08\x70\x9d\x7f\x4c\x82\x46\x08\xc2\x3b\x5d\xcd\x8d\x6f\xf9\x1b\x0c\x29\xbd\x2c\x13\x99\x46\x2c\x17\xd4\xf5\x38\x72\xcd\x84\x64\x44\x38\x69\xf5\xaa\x00\x5e\x3e\xf1\xb3\xc9\x05\x46\x0f\x59\x76\x97\x85\x39\x2e\x82\xed\x26\x07\x95\xd6\x36\x13\xef\xa2\x68\x7c\x12\x97\x19\xa8\x49\xa6\x02\x53\x71\xb3\xe1\xb6\xf1\xce\xf4\xb7\x5a\x51\x8d\xf9\xf0\x99\x5f\x1d\x7d\xef\x83\x5f\xac\x74\x14\x19\x50\x71\x8e\xd5\x1b\x9b\xc0\xbb\x13\xe9\x40\xe3\x1b\x79\xbf\xdf\xfa\x3f\xc5\x09\x56\xcb\x8f\xb5\xe3\xc9\x77\x7f\x33\x88\x20\xbb\xb5\xf5\x29\x62\xa6\xd3\xd8\x00\xda\x0d\x1b\x16\xc4\x4d\x63\x68\x72\x41\x9a\x12\x54\xaf\xd2\x58\x77\xfd\xcc\xc9\x97\x65\x3a\x63\xd8\x0e\x1e\xb5\xe9\x9d\x71\xd7\xe8\xd5\xe1\x41\xa8\x31\x3c\xbc\xe3\x47\xaf\x12\xfa\xbf\x90\x7b\x73\x67\xe1\xa0\xe2\x1e\xa8\x8a\x3f\x74\x86\x09\xea\x46\x4b\xed\x54\x73\x76\x92\xa3\xb3\xa6\x37\x81\x63\x3c\x50\x71\xe8\xb9\xed\xeb\x12\x3b\x17\x17\x0b\x45\xfd\x00\xf7\xc4\x03\x88\x91\x78\x78\x97\x1f\x45\x35\xc4\xcf\xa3\xb4\x92\x1d\x14\x46\x09\x7a\x9c\x2d\xef\x96\x7b\xff\x37\x19\x60\x4c\x59\xe6\x02\x35\x94\x96\xaf\x7c\x12\xf5\xf3\x28\xa0\x08\x30\xd6\xb5\x45\x97\x35\x5e\x00\xc0\x9d\x25\x0a\x4d\x56\xd3\x40\xfb\x5c\x95\x58\x49\xf9\x68\xdd\xe1\x51\x18\x1b\xec\xa5\x23\x64\xa1\x40\x76\xd9\xe2\x2b\x32\x51\x1e\x9c\x7c\x92\xa7\xc2\x98\xe3\x36\x55\xf1\x3e\x63\x61\x36\xdc\xe2\xed\x67\x92\x38\xc3\xbc\x12\x8a\xfc\x97\xaf\x22\xf2\x84\x32\xfc\x49\x75\x75\x29\x55\x30\x2c\x07\x22\x6e\x43\x59\x28\xc5\x7c\x95\x79\xfa\x6f\x18\x7c\xea\x2b\xcd\x78\x22\x68\x46\x7b\x55\xe6\xa9\x75\xce\xe4\x51\xa6\x11\x8b\x94\xab\xb9\x95\x3a\x3f\x8e\x57\x5c\x9e\xa6\x09\xe2\xb0\x0f\xed\x34\x39\xba\xa0\x50\xbc\x1d\x46\xc2\x38\x75\x4e\xed\x3e\x06\x18\x7f\x13\x09\x8d\xf4\xa1\x81\x5c\xa0\xd7\x89\xbb\x0b\x24\x8a\xe2\xd4\xc9\x82\x59\xdc\xc3\xf8\x61\x10\x45\x95\x34\x98\xce\xed\xfe\xb0\x5d\xec\x1d\xa0\x93\x53\xa7\xb8\x88\x95\x87\xa1\x6e\x94\xaf\x2f\x70\x1a\x45\x58\x99\x7f\xe5\xcd\xaa\xac\x2e\xc7\x57\xd4\x35\xf4\xd1\x96\x0d\xe1\x5c\xa8\x3c\x47\xad\x77\x27\x4a\x4c\xf7\xf3\xa7\xab\xdd\x6e\xca\x59\x4b\x03\xc6\xa9\x00\xbc\x21\x4f\xdb\xdf\x67\x03\x66\x37\x0c\x22\x0c\x5e\xb1\xfb\xbb\xaf\xce\xce\x46\x8a\xf1\x2c\xcd\x12\x6d\x71\x08\x1b\xbd\x3a\x75\x09\x78\x55\xbe\x40\xfd\x07\xf8\x04\x86\x67\x44\x24\x64\x68\xf9\x30\xb9\xe7\x19\x05\x24\xcb\x19\x9b\xc5\x81\x95\x20\x1b\xad\x10\x3c\xd4\x58\xab\x3d\xf1\x37\x03\x91\xb8\xcb\xdb\x13\x3f\xdf\xe5\x93\x9d\x8f\xf3\x98\x52\xaf\xdf\xf6\x95\xd7\x5d\x6c\xb8\x39\x5b\x94\xc7\xcc\x12\x64\x33\xcd\x9e\x8a\x34\xdc\x3c\x38\x4f\x19\xca\xe0\x60\x67\x7a\x5f\x59\xf4\xd7\xfc\x7b\xca\x89\xc0\x0c\xa2\xdb\x65\x90\xd7\x68\x09\x85\x0e\x4b\xc9\xb9\xd0\x08\xec\x32\x77\xd2\x35\x05\x20\x37\x35\x78\x7b\xee\xc9\x39\x15\x47\x94\xfa\xef\x39\xfc\xbc\x83\x9b\xdf\xaa\x64\xac\xb1\x92\x2e\x2d\x88\xc5\x7d\x95\x88\x12\xd4\x8d\xfd\xc1\xeb\x3a\xaf\xea\xc6\xd8\x2d\x76\x11\xb0\xc1\x8c\xea\x1c\x8a\x9b\x0a\xeb\xe4\xf7\xc8\x00\x28\x19\x1a\x89\x4c\x0a\x1b\x5c\x52\x62\x28\x6b\x3f\xab\xa7\xbc\x28\xf2\xaa\x7c\xa8\x2e\xf5\xd7\x4b\xa9\x6a\x50\xfb\xd7\xea\xd2\xf0\xd2\x5f\x91\xe4\x09\xb1\xea\x3b\xa8\xbc\x52\xf3\x62\x7a\x3a\x6e\xf6\xb3\x63\xb7\x66\x2a\x5e\x60\xad\xe9\xfb\xf6\xd1\x9f\x01\x8c\x89\x35\x76\x4a\x47\x88\x22\xae\xc2\x00\x69\x81\x87\xc3\x43\xde\x1d\x44\x94\xc4\x48\x4b\x9b\x71\x65\x45\x77\x50\x82\xa3\x81\x39\xbd\x71\xc6\x15\xc9\x42\x1b\xe2\x7d\xe1\x4d\x17\x7f\x3e\x6e\xbe\xdf\x4f\x07\x51\x21\x0d\xda\xb4\x7b\x6e\x7b\x2f\x45\xc1\xb8\xd2\x29\xcb\x1c\xfc\xa3\x85\x9d\x1c\x5c\x23\x50\xa5\xec\xcf\x5b\x2e\xbf\x5a\x9c\x6d\xe4\x8f\x32\x89\x52\x3b\x03\xf9\xb7\xb5\x8f\xa5\xb8\x8e\x4c\x53\xc4\x1a\x1f\x6c\xe1\xc4\xf3\x32\x2f\x8f\x7e\xdf\x59\x77\x7b\x8c\x1f\x0d\x4a\x65\x7d\x93\xc2\x4c\xcb\x3d\xaf\x8f\xd3\x17\x48\x04\xb6\x1f\xb7\x5e\x6e\xa2\x51\x13\x58\x84\x56\x64\xb9\xbb\xda\x57\x9e\x97\xd7\x9e\xe9\x3f\xbc\xab\x22\x54\x81\x25\x0a\x15\xfc\x8a\xf8\xa9\xd1\x16\x91\x0c\xcb\xed\x22\x8a\x09\x26\x18\xa6\x61\x6c\x7a\xde\x0b\x67\xb4\xc1\x44\xcc\x32\x8c\x6a\x2f\x4d\x3f\x3d\x30\x4b\x19\x5f\x74\x0c\x8a\x58\x4a\xf4\x47\x9a\x21\xa3\x49\x2c\x92\x2e\x76\x33\x31\x5e\x97\x4d\x0d\x0c\xdc\xc7\x4b\x9d\x48\x64\x86\xf8\x90\xcd\xcb\xea\xf9\xf0\xb2\x58\x7e\x5b\x7c\x59\x1d\x86\x94\x67\x91\x06\x0c\x7b\xe3\x2f\x5b\x23\x04\xbf\x7a\xbe\xf7\x87\x20\x0d\xb5\x6f\x7b\xb8\xbf\x92\x30\xc4\x94\x48\xf1\xbc\xb8\x8e\x6a\x0a\x82\x64\x81\xe1\x10\xa2\x32\x2a\x6e\x29\xeb\xc6\xe2\x3c\x1a\x50\x8b\x52\xa1\xb6\x85\x1f\x2e\x04\x42\x1a\x75\x17\x74\x98\x25\x63\x92\x9c\x09\xa2\x39\x32\x31\xb1\x56\xea\xa0\xfd\x73\xff\xd8\xf1\x99\x4a\x0d\x2c\x38\x2f\x8f\xd6\x1a\xf1\xd9\xb2\xdc\xdc\xb7\xf2\x48\x63\x1c\xd5\xe5\x27\x93\xd5\x6f\x7c\xef\x38\x4b\x71\x33\xb0\x0e\xa9\x38\xf4\x03\x0c\xbb\xe0\x4c\xe3\x66\xa7\xf3\x5f\xc6\xbd\x61\x67\x58\xf1\xb3\x01\xbc\x10\x3c\x71\xa4\x10\x9b\x41\x83\x9a\x38\xd3\x31\x21\x03\x9b\x10\x1a\x25\x25\x40\x8f\xfd\x2e\x98\x71\x3f\x44\x4a\x8e\x88\xae\x67\x38\x16\x30\xd3\x16\xba\xcc\xdd\x20\x15\x64\x58\x0f\xfd\x02\xad\xb9\x50\xe3\xc3\x30\x2c\xd4\x0b\x95\x4a\xc4\x2b\x3e\xef\xb7\x7f\xbc\xa0\x92\xa6\x8f\x1a\x04\x44\x80\x9d\xd0\xe7\xff\x9f\xb4\x3f\x6b\x6e\xdc\xd6\xf6\x87\xe1\xaf\x93\x8b\x73\x41\x12\x9c\x70\x29\xc9\xb2\x5b\x27\x9e\x8e\xa5\x4e\x27\x7b\xd7\x2e\xd5\x02\xb0\x20\x33\xa6\x48\x6d\x92\xb2\x5b\xf9\xf4\x6f\x71\x01\xe0\x24\xda\xc9\xf3\x7f\x6f\xd2\x29\x13\xa2\x28\x12\x04\xd6\xf0\x1b\xf0\xa3\xb3\x3e\xb7\xf2\xdc\x6e\x04\x4b\x23\x2b\x52\xf9\xa4\x35\x49\xd0\x4f\x41\x29\x7d\xf0\x26\x30\x61\x14\x63\x2c\xb1\x78\xcb\x36\xab\xa7\xc9\x4d\x40\xd4\x91\xb9\xaf\x15\xae\xdb\xfc\xed\xbe\x3c\xb0\x45\x51\x16\x97\x63\xf7\x7d\x5a\x7a\xb6\xa4\xdd\xcb\x95\x50\xa9\x66\x7c\x2a\x8d\xc6\x09\x3f\x87\x42\xb5\xc9\x30\xa1\x99\xb7\x0d\x9e\xa6\x0d\x68\xa1\x51\x10\x4d\x77\xb3\xdd\x7e\x5f\xef\x1f\xd6\xbb\x6f\x4f\xee\x9d\x90\x5e\x68\x04\xb0\x4e\x55\xa9\xb3\x7c\x9c\xc3\x4b\x8f\x9b\x4b\x21\xfd\x0a\x2b\x6b\x60\x42\x84\x9a\x9a\x07\x53\xb7\x8b\x54\x7a\xe0\x29\xed\xba\xea\x76\x2e\x8c\xc9\xf0\x32\x60\x71\xc8\x1d\xf9\xb1\x82\xfc\x71\x5a\xa4\x90\x41\xca\xa2\x91\xfe\xc1\x4d\x56\x9f\xb0\x70\xe5\xa1\xda\x90\x96\x66\xd0\xdb\x32\x90\x82\x70\xff\xf8\xdf\x33\xe4\x5f\x50\x5c\x24\x0b\x14\xc9\xce\xdc\x94\x20\xa1\xa4\x27\x51\xba\x0b\x64\x60\x3a\x84\x35\xbc\xa3\x3f\x5e\x2c\x27\x27\xb1\x48\xac\xbb\x1e\x0e\x32\xdb\xd6\xe8\xaf\x2f\xe4\x06\xda\xd5\xfe\x32\x6b\xaf\x6b\xe8\x7a\xc3\x65\x47\x86\x8a\x19\xb3\xfc\xac\xba\xa9\xca\x93\x9d\xd1\xee\xa0\x36\x42\xb4\xb2\xcc\x0a\x23\x77\x7c\x87\xc7\xe3\xe5\xe1\x5c\x67\xd2\x8d\x89\xb4\x26\xe7\x9f\x3f\x0d\x38\xe8\xbe\xdd\x58\xdc\xb1\xd8\x97\xc4\x18\x32\x38\xbd\xe5\xe4\x06\xc6\xb1\xa4\xe2\x51\xb7\x8d\x11\xab\xba\xfb\x6c\x12\x38\x4f\xf3\x76\xf3\x34\x5d\x05\x77\x0c\x15\xc9\xf3\x14\x99\xc4\xbb\x73\xf7\x5b\x92\x94\x13\xd5\x40\x19\xac\xb5\x3d\xa1\x63\xc8\xcd\x48\x87\xa7\x32\x51\x3a\x85\x0e\x07\x4b\x71\xda\x1e\xd4\x84\xc3\x20\x53\x2f\xa5\x95\xd4\x02\xa4\x6c\x00\x3d\x49\x98\xc7\xaf\x8c\x6c\x33\x15\x53\xb5\x31\x5b\xc0\x4d\xf6\x5e\x4f\x4f\x2b\x84\x51\xfd\x3e\x18\x8c\x72\xdd\x54\xdd\x6f\xe1\x0c\xa0\xcf\xff\xad\x64\x77\x56\x12\x4c\x28\xe9\x06\xc5\x26\x18\xbf\xc7\xba\x2e\x8b\xfd\x27\x94\x24\xc9\xc1\xa8\x86\xb8\x4a\x4f\x31\xce\x95\xdd\x28\xcd\xa9\xb1\x74\x5f\xca\x89\xe3\xd8\x3c\x6c\xe2\x13\x5a\xe6\xe4\x36\x80\x1f\x13\xff\x9d\x70\x6d\x8f\xf8\x61\x7a\x76\xa3\xe8\x42\x02\x13\x42\xf4\xde\xe3\xf5\x04\xf8\x28\x45\xcc\xa2\x8e\x2d\x69\x21\xb6\x7d\xe5\xd9\xbc\x2c\x7d\x42\x34\xe9\xea\x4b\xe9\x79\x94\xcc\xba\x5f\x6f\x20\xd5\xf6\xa0\xf6\x4c\x6d\xcd\xda\x50\x1b\x4b\xa6\xdb\x69\x39\x56\xea\x28\xa6\xa7\xb1\x0a\xee\xbb\x4f\xa6\x31\x6d\x06\x0f\x97\xb1\xdd\x4f\x2a\x35\x8f\x1c\xe0\x65\xf9\xf1\x40\xa5\x43\x23\x4b\x0f\xd7\xe9\xbe\xd4\x32\xa4\x65\xef\xda\x8e\x69\x98\xf0\x90\x7a\xb1\x6f\xae\x33\x2f\x2f\xcb\x12\x3a\xa0\xbb\xf2\x92\x28\xb0\x5e\xa5\x84\xbd\x26\x6a\xef\x78\xa6\x29\x0f\xb4\xb6\x74\x8b\x31\xa2\xbc\x07\xf5\xbb\x91\xa8\x98\x6f\x61\x13\x57\x56\x2b\xe3\x93\xfa\xbe\xa2\x04\xe6\x06\xde\x33\x35\xb8\x01\xca\x4f\xb9\x2f\x3a\x7c\x9f\x51\xc0\xff\xec\x1c\x9c\xa3\xd9\xc2\x9a\x86\xb2\x38\x39\x3c\x0f\xf2\xd8\x40\x83\xda\x88\x48\x5e\x63\x0e\x15\x0b\x3c\x8c\xed\x02\xb5\x74\x9c\xb4\x19\x11\xbc\x76\x64\x4a\xbd\x59\x85\xb6\xa4\x39\x7e\x0e\x8a\x85\x9a\xaa\x8b\x58\xd4\xe7\x0a\x57\x65\xde\xee\x05\x15\xe4\x6e\x43\x99\x7c\x6f\x12\x11\x7a\xe0\x03\xf1\x6d\x9f\x15\xfb\x36\x39\x71\x25\x12\xc5\x20\xa2\xc9\xf2\x67\x99\x15\x82\x9e\xd4\x70\x25\x57\x4c\x1a\x09\xfc\x3e\x80\x71\x4e\x5a\xe3\x2b\x0a\x13\xe3\xcf\xaa\x17\xea\x93\x22\xa4\x8a\xbc\x90\xc4\x03\xcc\x4a\x74\x43\xa8\xc6\x7f\x54\x57\x57\x11\x37\x44\xd7\xe7\x97\xa7\x87\x27\xe3\xc7\x64\x19\xeb\xee\x57\xc4\x31\x83\xd0\xf2\x11\x20\xcf\xf4\x44\xdb\x40\xc5\x22\xa2\x56\xff\xee\xe9\x65\x35\x8c\x11\x55\xac\x63\x2a\xd0\x9c\xae\xfa\xbc\x2a\xf1\xa2\x98\xbb\x7c\xea\xd8\x15\x22\xce\xd7\x72\x1f\x2a\x65\x8c\x20\x06\x1f\x3d\x4a\xee\xa7\x65\x3a\x8d\x0a\xcb\x2a\x4d\x85\x32\xb5\xed\x6e\xdb\x57\xed\xbe\x9a\xb8\x87\xdd\x66\x77\x56\x52\x68\x91\xe7\x8b\xea\x70\x4d\x46\x1f\x7f\x35\x57\x09\xe5\xa6\x3f\x56\x0f\x8e\xb8\xaf\x64\xea\x79\xb2\x53\x89\x68\xb7\xab\xfa\x6a\xfb\xed\xb7\x15\xd5\x26\xaf\xc6\x5b\xb7\x2a\x3f\xea\x1f\xaf\x86\x24\xbf\xa9\x1f\xcb\x91\x38\x5d\xe7\xb3\x91\x2a\xa9\x7c\x0a\x04\x1e\xf1\x5c\x41\xfe\x5c\x95\x4d\x29\x4b\x97\x0b\x29\x25\x12\x7a\x2b\x8f\x97\xfa\xb5\xfc\xc8\x28\x55\x1d\x5f\xb4\xd2\x3e\x31\x2e\x3b\xf9\xee\xe6\x75\x1c\x0b\x29\x8c\x99\x6b\x3d\x59\x59\x42\x6f\xf2\xc3\xb5\x27\xc1\xef\xd7\x59\xca\xac\xcb\x3c\xbf\xe9\xfc\x31\x52\xa5\x21\xf2\x9c\xcb\x56\x76\xf8\x27\x68\xe9\xf1\xc4\x43\xaf\x7d\x11\xe9\x3a\x0b\x55\x7e\x78\x63\xbc\x39\x7a\x3c\x8a\x0d\x1e\xad\x8f\x57\xe6\xf7\x57\xf4\x54\xe4\x64\x76\x56\x65\xf1\x8e\x55\x4d\x49\xb2\x2e\x47\x6f\x1b\x86\x61\x40\x6d\x1c\x57\x0d\x7c\xc8\x8a\xcf\xe4\x14\x30\x4a\x53\x12\x07\x27\x3c\xe7\xa9\x2c\xf3\xdf\xcc\x59\xbb\xa6\x2b\xb3\x65\x35\x4c\xc2\x80\xf2\x73\x7b\x9d\xe3\x67\x81\x89\x4c\x98\xd5\xa3\x25\xdd\xc8\xfc\xb2\x18\x0a\x94\x61\xea\x6b\xca\xdd\xa8\x59\x91\xe3\xa1\x82\xe3\xf8\xa2\x39\xa2\xe3\x24\x3d\x57\x78\xcc\xce\xc7\xcf\xb9\xd6\x08\x5e\x4c\x18\x4e\xd3\x1e\x42\x65\x3c\xe8\xc6\x55\x51\x14\x41\x40\x60\x31\xa0\x77\x67\xfa\x62\xa2\xd0\x8c\xc4\x89\xb3\xcc\x81\xfb\x51\xa2\x91\xb4\x3d\x60\xb3\x3d\x21\x51\x5b\xcf\x2e\x6f\x40\xe5\x05\xa1\x89\x15\xca\x53\xd5\xa9\xc6\x8d\xef\x82\xf2\xa5\x52\x23\x7f\x9d\xff\x3b\xc3\x30\xdb\x41\x25\x02\xad\xad\x6d\x42\x93\x49\xc8\xf3\xcb\xba\x38\x64\x05\x8e\x2d\xfe\x53\x54\x32\xa5\x58\xb0\xb6\x64\x07\xfb\xe7\x36\x47\x0f\x49\x72\x63\xdb\xff\xc9\x00\x5a\x0d\x08\xab\x6b\x17\x2e\x2f\xdb\x02\x4e\xf5\x6b\x69\x24\xa4\x3e\x79\xfe\x28\x35\x89\xe8\x1c\xe1\xe7\xee\xe7\x90\x91\x80\xa8\x8c\xd5\xe4\x2b\xd4\xaf\xa6\x87\x3e\x13\xe8\xa3\x8e\xfc\xce\x70\xd8\xd5\x74\x7c\xd7\x6f\x43\x2d\x7d\xe8\x85\x91\x94\x39\xff\xf8\x29\x69\x4c\xa9\x3a\x4a\xb5\xae\xda\xd0\xc7\xc6\x4f\x4a\x7b\x1e\xb7\xca\xd9\xb9\x34\x49\xe8\x75\x60\xa9\xbd\xd0\x68\x01\xda\x40\xd8\xfa\x94\xde\x65\xef\xf8\xad\x5f\x39\xb5\xc7\x31\x08\x5d\xf2\x47\x03\xaf\x04\xbc\xb4\x9f\x98\x45\x63\x07\x6f\xed\x5c\x46\xf7\xec\xb4\x2f\x94\xb3\x82\x78\xc4\xec\xf0\x2a\xca\x73\xf5\x5a\x96\x6a\x3a\xb5\xb4\xaf\x24\x01\xca\xf6\x67\xb2\xa3\x7a\x80\xb7\x76\xa3\x82\xc9\x28\x16\x69\x22\xd7\x9b\x9b\xf3\x7d\x8b\xff\x7d\xef\x56\x3f\xcd\xa4\x72\x12\x08\xb7\x67\x52\xdd\x1b\x50\x70\x57\x56\xd9\x61\x34\xf9\x74\x28\x8c\xba\xc4\xa6\xc8\x1a\x6b\x40\xb6\xea\x63\x26\x1d\x85\x8c\x1a\xa2\xff\xfb\xbf\x5f\x21\xe4\x74\x24\xb5\x21\x5d\xd1\xfe\xfa\x63\xb5\x0b\x3e\x6b\xdb\xe8\x38\x48\x62\x5b\x8f\xa9\xaf\x56\x77\x1d\x07\x9a\x1e\x6c\x5d\x1e\xf1\x01\x9b\xd7\x52\x05\x5f\x23\x58\x74\x1c\xc6\xb4\x4e\x3a\xbb\xcd\x41\x4c\x3a\x6b\xad\x93\xea\x58\x18\x6b\x03\x73\xb1\xf6\x95\x33\x5e\x3d\x14\x11\x8e\xaf\x37\x09\x52\x22\x29\x11\x8e\x0d\x24\x89\x32\xfd\xfe\xc7\xbf\xdc\x05\xa7\x69\xca\x0d\x76\xff\x7d\x9f\x15\xdb\xa6\xea\xd1\x7f\x3a\x05\x9f\x4a\x97\xe2\x7c\xa1\xa6\xc8\x48\x60\x44\xf3\xc8\x7a\xde\xd9\x05\xf7\xb9\x42\xc2\xae\x7c\x5a\x5f\x9e\xfd\xf7\x13\x74\x88\x06\x5f\x45\xe4\xcf\x04\x85\xca\x91\x70\x1c\x2b\x23\x52\xf2\xd9\xdd\xb9\xfa\xba\xd9\x77\x5f\x83\x0c\xc9\x43\xea\xaa\x6b\xf4\xc9\xbf\x9f\x49\x44\x6a\xd0\x46\x5a\xc4\xe8\xb6\x3c\x2c\x7e\xdf\xaf\x9e\x1e\x77\x2f\x9b\xe5\xfe\xfb\x76\xe1\x6e\x92\xf0\x02\x65\x0a\xcb\x79\x7e\x8b\x48\xf5\x72\xc7\x3a\x77\x43\x64\x9c\x28\x67\x93\x53\x67\x87\x71\xb9\xed\xd3\xaf\x97\x5e\x42\xf3\x66\x7f\x24\xa7\xf6\xc9\x6b\x26\xc3\x88\xfc\x3d\xb3\x22\xfb\xd4\x45\xe3\x9f\x6d\xe4\x5a\x72\x03\xfe\xb6\x7a\xa3\xee\xc3\xa3\xf7\x47\x72\x49\x30\xac\xef\x45\x26\xcb\xea\x4a\x9c\x7b\x3e\x65\xd4\x52\x81\x51\x27\xaf\xb1\x71\xe0\x4b\x8d\xb1\x88\x63\xb7\xdd\xab\xc9\xc2\xa9\x91\x87\x26\xde\x22\x6d\xfc\xd7\x0a\xd1\x32\xcd\xd6\xff\x1d\x28\x1c\xda\xc1\x3a\x88\x39\x76\x48\xa2\xc5\x3b\x34\x70\x5d\xc9\xe3\x9e\x17\x7b\x54\x71\xa1\xf2\xe9\x44\xe6\x7e\x78\xc1\xdc\xf3\x12\x15\xda\x13\x36\x39\xde\x0d\x4b\x97\x93\xd5\x65\x78\x0b\xb9\xe7\x33\xe9\x44\xd2\x6f\x2b\x44\x8a\xd6\xaa\x4d\xf1\x5e\x66\x12\xeb\xe5\xc5\x52\xea\xe6\x5e\x1b\x77\x8d\x41\x18\x73\xa3\xaf\x28\xcb\xf7\xc1\xbb\x36\x32\x19\x1a\x73\x7f\xbe\x7c\xac\xed\x19\x0d\x90\xe2\x58\xaa\x4c\x5f\x1e\xb0\xae\xe1\x30\x2a\x99\x71\x8f\x45\x01\x81\x07\xbb\x0e\xab\x41\x31\x7e\xd5\x3e\xe2\x1e\x4b\xb9\x83\xdd\xfc\x80\xac\x69\x63\x86\xec\x88\xcb\xf3\x90\xf5\x6f\x87\x86\x11\xd7\x4e\x2b\x6e\x5d\x55\x13\x67\x13\xee\xc5\x32\xa5\xaa\xd4\x5e\x75\xda\xc9\x86\x3b\x3f\x64\x4f\x98\xc4\xd6\x45\xe4\xdc\x8b\x31\x8e\xed\x66\xf7\x33\x78\x2e\xf3\x4c\x5e\x13\x5e\xe7\xef\x48\xc2\x39\xbd\xab\x46\x34\x3c\x74\xbe\xb8\x38\xb9\xea\x94\x01\xc1\x49\x55\x05\x59\xf1\x60\x23\x07\xee\xa5\x61\xc2\xda\xbd\x0b\x65\x59\x94\xc7\xcb\xb2\x2c\xeb\x66\x06\x7c\xcf\xbd\x34\xe2\xd4\x7f\x7d\x59\x3c\xde\xad\x4d\xd7\xd8\xef\x4e\x92\x20\x69\x33\x4b\x28\x1e\xca\x77\x9c\x4c\xbf\x14\x0c\xce\xaa\x33\x26\xc0\x7d\x1b\x19\x7c\x9f\x7b\xc7\xc7\xd7\xcc\x03\x41\xd5\x8f\x0f\xc4\xa7\x02\xd7\xcd\xeb\x0a\x8a\xa5\xab\xa7\xf1\x36\x18\x97\x96\x42\xbf\x3a\x57\x57\x28\x35\xee\x71\x14\x1a\x1c\x9a\x8d\x6c\xae\xe6\x2d\xc9\xb8\xc7\x75\x20\xfb\xfd\x7d\x45\x72\xd5\x37\x59\xdd\x90\x9d\x89\x1d\x03\x4c\x6a\x2b\x40\x41\xe5\x35\xa8\x5f\x3f\xca\x5c\x77\x87\x85\x41\xec\xe7\xe7\xa2\xf3\xfd\xea\x8e\x49\x15\x59\xb6\xc0\x54\xd9\x9a\x7b\x42\x0a\x16\x38\xeb\xfb\x6a\x57\x8e\x58\x5d\x76\x8c\x14\x5c\x70\x27\xc5\x51\x15\x53\x75\xb4\xf1\x60\x15\xf8\x81\xd1\x91\x95\x43\x01\x10\xee\x29\xc0\xb4\x33\x2e\x5d\x7c\xbf\x72\x0a\x3c\x4f\xf5\x97\xb8\xa7\x94\x41\x91\x51\xe9\x71\x60\x45\xc8\x3d\x8c\x42\xfa\x4d\x15\x5c\x83\x90\x26\xcf\x11\xa5\x31\xce\x5a\xbf\x97\xd7\x91\x38\xf7\x74\x1a\x0a\x1b\x89\xaf\x77\xdf\x6e\xab\xd2\xd9\x41\x8c\xce\xe2\x7b\x91\xa4\x82\xf1\xb9\xa0\xf8\x73\xb8\xad\x73\xdf\x4b\x23\x22\x8a\x1e\xb3\xa2\xd9\x66\xb9\x1c\xa7\x66\xe3\x13\x05\x9e\x81\x8f\x1c\xa8\xe0\x75\xb9\x2d\xcf\x95\x3b\x4d\xe0\x27\x54\x6e\x37\x95\x56\xe3\xad\x50\xef\xe1\x8a\xe5\xd6\x8e\x14\x14\xc1\xb9\x45\x66\x51\xa8\x05\x15\xae\x3f\xf9\xce\xd8\xb7\xfa\x18\xcd\xb9\x2a\xee\xcb\x09\x9f\x94\xfb\x01\x60\x68\xf3\xc5\x7b\xa8\x9b\x67\xc8\xd4\x90\x43\x6e\x47\x31\x4f\x51\x6b\xd5\x6c\x24\x1f\x65\xb7\x8d\x2c\x2f\x1d\x65\x94\xfb\xa1\x17\x50\x3a\x50\x37\xf0\x86\xbb\xc5\x53\xbb\xb1\xcd\x30\x75\xcd\xca\x9b\x7e\x5d\x3e\x9d\x47\x8e\xbb\x2f\x8a\x92\xc8\x98\xcc\xaa\x67\xf2\x07\xdc\xc8\xf2\xb6\xac\x76\x58\x77\x84\x41\xee\x87\x1c\x59\xd8\xb5\x1a\x51\x75\x0c\x6d\xee\x87\x2a\xa5\xea\x7e\xbb\xd6\x52\xf8\x3e\xa8\xd4\x70\xbf\x7d\xbd\x6d\x9a\xf9\x70\x6e\x7a\x75\x37\xf7\xe6\xf8\xb1\xf2\x48\x4f\x44\x95\x73\x56\xfe\xed\xf1\x80\x1b\x18\x46\x23\x5f\x97\xe6\xa5\x7b\xae\x50\x67\x3f\x7f\xb9\xd6\x5f\xe6\x7e\xe2\x1b\x76\xc8\x4d\x79\x18\xdb\x18\xfe\x4d\xc4\x31\xb9\x29\x89\x0f\xa6\x5c\x6c\x48\x3b\x2f\x28\xb3\x53\x86\x45\x33\xe0\x0f\x71\x3f\x09\x18\xe9\x1e\xc2\xe1\x90\x9d\x8b\x43\xb6\x97\x36\x17\x1c\xd5\x07\xb8\x9f\x24\x9a\x6a\x95\xdf\x76\xab\xd1\xbd\x49\x84\x17\x24\x9d\x78\xce\x9f\x28\x9b\x39\x1e\x29\xf7\x13\x6d\xe0\x48\x4f\x3f\x2f\x7d\x09\x94\xfb\x69\x10\xa7\xbd\x1b\xde\x4d\x05\x1f\x57\x9f\x4c\x13\xd4\xbd\xa2\x8b\x05\x11\xcd\x85\xf6\xdc\xe7\xa9\x47\xd8\x0b\x9d\xe5\xf9\xf2\x7c\x21\x9a\x39\x89\xc1\xb5\x29\xf3\xd7\x6b\x83\xcf\x25\xf8\x56\x94\xe8\xe1\x32\x26\x70\x70\x1f\x3c\x03\x04\x24\xa2\x1d\xaa\x67\xa8\x6a\x94\xab\xaa\xcd\x5c\xbb\xc9\x0e\x71\xea\x0a\x2d\x8b\x3c\x27\x65\xae\x7b\xec\x26\x9f\x60\x20\xa3\x7e\x0e\xe5\x02\x7b\xc7\x05\xee\x8b\x98\xa7\x56\x62\xe1\x11\x3f\x9e\xc4\x9f\xa3\xb7\xb7\x9b\x67\x42\x98\x72\x8a\x29\x61\xac\x0f\x87\xc9\xad\x92\x0c\x18\x76\x92\xca\xcd\xb9\x1e\x7e\x87\x94\x7e\x32\x54\xce\x35\x29\xe2\xf4\x0c\x52\x91\x1c\x05\xe4\xf9\xad\x69\x37\x3d\x57\xa5\xc4\xba\x63\x33\x72\x5f\x2a\x8f\x53\x06\xf0\x9a\xd5\x56\xdf\x6c\xbd\xfb\xe6\x8e\x2a\x1f\xc1\xbc\x0a\x1f\x45\xd3\x55\xac\xb8\xaf\xa4\xe1\x97\x3f\xdc\xdc\x77\x7f\xd2\x21\x75\xa7\x1e\xcf\xd5\x59\x0e\xe6\x84\xd2\x29\x71\xd5\xad\x12\xc3\xb6\xcc\xd5\xd3\xb9\x99\x2c\x53\xe8\x7b\x24\x5b\x03\x1d\x01\xc5\x18\x1e\xf6\xd7\x89\x3e\x33\xbd\x88\x6f\xdf\x1f\x7f\xdd\x6f\x37\xff\x5a\xbb\x23\x9a\x2b\x6e\x63\xe4\x47\xdd\xd4\xcb\xcb\xb5\xf2\x12\xf7\xb5\x4e\x68\xcf\xdf\xee\x9e\x5e\x16\x77\xeb\xfd\x8f\xc5\xfd\xfd\xda\x56\x7d\x79\xe0\x47\x01\xf5\x2e\xf0\xfd\x8a\x5b\x34\x4d\x13\x66\xd7\xe1\xc0\x17\x21\x05\x6f\x6d\x72\x38\xab\x51\xc8\x83\x20\x08\xe9\x3b\x48\x79\xac\xba\x3d\x17\x72\x7e\x4d\x0f\x82\x28\x24\x40\xa3\xb1\x0c\xa8\xd1\x3e\x39\x77\xad\x01\xa2\x95\x63\xb6\xe2\xe2\xd3\xaa\x3e\x0f\x18\x83\x38\xea\x45\x26\x37\xea\xaa\x3e\xee\x06\x86\x1e\x11\xfa\x36\xab\x27\x63\xa2\xbc\xdf\x6d\x1e\xd6\xce\xb2\x8a\x07\x4c\x32\xe5\x5c\x64\x29\xa3\xb0\x41\xf5\xe4\x2c\x98\x90\xcb\xeb\xab\xd1\x5b\xef\x17\xe2\x20\x62\x3e\x75\xea\xc8\x3b\x6b\xaf\x50\x9d\x8d\x2d\xbb\x7b\xcb\x82\x38\x50\x80\x43\x31\x75\x57\xb3\x1e\xe6\x24\x41\xcc\x34\xcd\xd1\x4c\xb7\x13\x6b\xb8\x60\x05\x71\xac\xe5\x40\x3d\xfe\xa5\x14\xe5\xa7\xe1\xdf\xfc\x52\x11\x24\x5e\x88\x69\x07\x77\xea\x36\x83\x41\x18\x1d\x24\x90\x5a\x4d\xab\xf6\x32\x5d\x42\x77\x9d\xa4\x8c\x1f\x43\x22\x3b\x43\x53\xdb\x42\xfd\x34\xbd\x9e\x4b\x94\x82\x44\x01\x21\xdb\xc4\xf9\xf2\x0c\xf2\xed\x47\xd6\xbc\x92\xcb\xdd\x2f\x93\x61\x08\x44\x11\x11\xed\xcb\x33\xb0\x95\x3f\x5f\xa9\xf6\xf1\x20\xd1\x46\x66\xb1\x0d\x07\x08\x03\x4e\x3d\x35\xaa\x4c\x4d\xae\x5d\x4b\x23\x2d\x67\x78\x1a\x23\x35\x5c\x1e\xa4\xa9\x22\x94\xda\xe9\x5c\xbf\xee\xca\x25\x14\x6f\x93\x8f\xa7\xa0\xc2\xa4\xeb\xe3\xae\x9b\xd7\x65\xa6\x26\x52\x2c\xa3\xa7\xe1\xf2\x81\x80\xa7\x82\xf7\x04\xab\x67\xac\x2c\x72\x6b\xce\xe3\x89\x07\x10\xa9\xa4\x37\x09\x6c\xb7\xfb\x1b\x94\x70\xe9\x4a\xb3\xff\x70\x22\xcc\x5a\xf6\x0c\xbf\x47\xc4\x29\xa9\xf4\xb9\x9a\xc6\xf3\xfa\x65\xf3\x74\xe3\xef\x49\xba\xd4\xdd\x14\x91\x68\x42\x02\x2e\x14\x99\xbb\x55\x23\xe8\x1d\x0f\x04\x30\x02\xcf\xda\xfd\x9b\x9e\x11\xb5\xf7\xfd\xee\x04\x22\xa6\x38\x7a\xbf\x82\x3c\x5f\x88\xb2\x1a\x12\xc0\xc7\xe0\xe2\xee\xc2\x74\x60\x5c\x16\xe0\x7d\x54\x5f\xfc\x9f\xaf\x09\x84\x5f\x51\x97\x79\x20\xbd\x40\x76\xa2\x2c\x4f\x27\x2c\x7e\x50\xd7\xe2\x93\x35\x44\x45\x7e\x92\x5a\x2e\x3a\x56\xa4\xbf\xd6\xf7\x36\x78\xa0\xb4\xa0\x7e\x1e\xfd\xd4\xb9\xb6\x22\x0f\x30\x8c\x8c\x8d\x5c\x1b\x7d\x72\x41\x2e\x7f\x77\x65\xa9\x76\x9d\x67\xe5\x2b\x16\x36\x24\xfd\xa5\xfb\x8c\x8a\x47\x66\xc8\x59\x71\xd8\x36\x78\x9a\x9e\x3a\x92\xcc\xe6\xbf\xf4\x4c\xae\x15\x5c\xda\x31\x9a\xda\x89\x0e\xce\x66\xda\x82\xdb\xef\xcf\xcf\xf7\x7f\xec\xef\x37\x0f\x9b\x6e\x9b\xd0\x01\xa7\x17\x7a\x55\x1e\x4f\x15\x74\x7f\x4d\xc2\xd0\x00\xb9\x6f\xe0\xb2\x7b\xcd\xaa\xee\x22\x75\x2a\xc9\x7d\xfc\x61\xf3\xb8\x5f\x7e\xff\x63\xb9\x58\xfd\xba\xff\x6d\x71\xff\xbd\x9b\x32\x9a\x4b\xdf\xa6\x28\x0e\xa4\xda\xe6\x29\x23\x50\xe6\xe4\x76\x6b\x85\x14\x4d\x62\xf3\xfa\x82\xf2\xeb\x28\x88\x79\xda\x8b\xb5\x93\x6d\xdf\x42\x8e\xe3\x72\x5a\x37\x8a\x41\x6c\x4e\xe9\x96\xb6\x51\x13\x8d\x33\xdf\xe7\x04\xa6\x14\x57\xcd\xe6\xd9\x2d\x8c\xf9\xda\xb7\x0a\xb4\xb2\x2c\x14\x41\xd0\x1e\xe0\xb2\x76\x40\xb4\x76\x00\xb8\xc6\xe2\x43\x59\xd4\x0d\x56\x77\x58\xa0\xd5\x49\x99\x9c\x2c\x60\x9c\x58\x14\xe5\xb9\x39\x9d\x1b\xf3\x0b\xc6\xeb\x11\x0b\xc2\x90\x5a\x22\x27\x83\x88\x1d\x26\x94\x8c\xf9\xa1\xf3\x8c\xde\x76\x7f\x63\x1a\xac\xdd\xd6\x9e\x30\x30\x93\x3b\xc2\xb8\x22\xe8\x48\x9b\x3c\x28\xf8\x7a\x99\x67\x4c\x1a\x81\xaa\x36\x47\xa4\x6a\xfb\x6c\xfc\xce\x18\xc6\xd8\xc1\x39\xa8\xa7\xf5\x69\x26\x60\x3f\x11\x26\x48\xed\xcf\x7d\x8d\x79\xfe\x2b\x5e\xae\xbb\xdc\xa3\x8c\x9f\x85\x69\x44\x19\xff\x5b\x21\x5f\xa0\x41\xea\xf9\xd4\x46\xf5\xd0\x8d\x00\x41\xb7\x7d\x21\x9b\x33\xe4\x84\x8b\x6d\x1a\xc4\x97\xb2\x3c\xba\x21\x11\x93\x22\xf9\x04\x81\xc3\x96\xd8\x40\x37\x30\x15\xe4\xd7\x55\xe0\xc7\xfa\x71\x3b\xb9\x81\xb1\xe7\xf1\xb8\x73\xe8\x6a\xdf\x17\x6c\xb2\x2b\xaa\x27\x67\xb1\xaf\xe8\xfd\xc4\xe6\x95\x04\xa0\xde\xb1\x38\xe3\x0b\x19\x64\xba\xef\x89\x53\x4f\x19\x99\xb8\xcb\x35\xb9\x61\x66\x53\x60\x31\xa6\xb4\x20\x39\xe3\x57\x97\x85\xb3\x24\x31\xa8\x97\x63\x33\xea\xbf\x72\x96\xe8\x38\x75\x6a\x11\xeb\x1c\x87\x0c\xe7\xf1\xe5\x72\x5f\x09\xbb\x7d\x2e\xb1\xc8\x74\x26\x33\x70\xe0\x25\xce\x78\x14\x13\x93\xe6\x4c\xc6\x84\x5b\x3a\xc1\xe4\xf7\x82\xcf\x89\x18\x2c\xce\x97\xd9\x02\x38\x67\x20\x38\xf1\xa5\x44\xa6\xea\x7d\x76\x28\xca\x0a\xd5\xde\x24\x4b\x5d\x30\xcc\x04\x97\x29\xb7\x9e\x9a\xbd\x7c\xd5\xf0\x34\x02\x3c\x12\xb5\xe8\x8b\x85\x34\xe5\x26\xc5\x8f\x76\x58\x6c\xb3\x9c\x4e\xe7\x66\x31\x59\x20\x99\x8c\x38\x95\x99\x8d\x2a\xb1\xf3\x24\x1b\xd0\x32\x26\xc3\x79\xea\x29\x57\xec\xa0\x72\x9c\x3d\xa0\x18\x46\x76\x35\xea\x90\xa9\x53\xee\x34\x67\x18\x18\x90\xc9\x5f\x59\x9e\x63\xef\x38\xe4\x8e\x86\x1e\x35\x1b\x49\x37\xd5\xba\x9d\x67\x03\xd3\xd1\xaf\xd7\x43\x4c\x44\x60\x25\x80\x0f\xc8\x6e\x10\x54\xde\x49\xde\x70\xa6\x03\x53\xac\x6d\xa3\x5d\xca\x33\xa9\xd1\xd6\x75\xb5\xae\xac\xbe\x2d\xdd\x84\x33\xcd\x74\xaa\x3a\x45\xdb\x6b\x38\x53\x7f\x01\x3a\x4a\x68\x02\x49\x38\x0d\xf1\x1c\x3c\xf4\xd2\x84\x22\xed\x3f\xcb\xac\x58\xd4\xcb\xaa\x7c\xeb\xe6\x6d\xe8\x6b\xa0\x09\xdd\xa5\x7a\x4e\x4a\x86\x87\x81\xe7\x69\x47\xef\x5d\xe4\xf9\x93\xa1\xa7\x0c\x2a\x58\x61\xc0\x18\x01\x87\xcb\x0a\x64\x9e\xfd\x85\x77\x50\x93\x97\x8d\x3b\x2c\x22\xdf\x32\xd5\x67\x9a\xbb\x3c\x0c\x64\xe4\x0a\xc8\x53\xf2\x31\x0f\x19\x33\x8e\x5d\x58\xa8\x9b\xb1\x04\x0f\x0f\x99\x94\xb4\x3c\x9c\xca\x0f\xac\x6e\x68\xf1\x1f\xbc\x72\x61\x18\x18\x2f\xcd\xdb\xf2\x5c\x2d\xaa\xee\x72\xc2\x48\x11\x9e\xc3\xac\x3e\xa4\xb1\xf8\xf5\x23\x0d\xc3\xc4\x48\x63\x98\xb4\xca\x91\x83\x47\xab\x51\x18\x42\x4c\x90\x76\xea\x69\xd8\xb6\xfe\x0b\xd6\xe5\xb9\x9a\xc6\x22\x61\xa8\x23\xc7\x3d\x6f\x4f\xb0\x2b\x4d\x05\xec\xcb\x1d\x20\x8c\x22\x4e\x82\xdc\xeb\xdd\x70\xae\x86\x91\x64\xdc\x7a\xac\xb8\x5f\x7f\xee\x79\xc8\x3c\x8c\xd0\xb0\xa2\x57\xab\x6f\xfb\xa7\xfb\x4d\x57\xf8\x0e\x63\xdf\x37\x10\xe6\xfc\x5c\xbf\x8e\x5d\x18\xc7\x5f\x1c\x83\x72\x3a\x51\xb6\xdd\x4b\xed\xf3\x79\x12\x19\x0f\x13\x6e\x9c\xd5\xdb\xb0\xfd\x05\xf5\xa6\x90\xe5\x44\xc3\x9c\x87\x69\x00\x14\x0c\x7c\xaf\xb3\xe2\xb0\x78\x2c\xab\x23\xe4\xdb\xa6\x3a\xcb\xee\x19\xa5\x11\xb7\x54\xbd\x62\xd9\xc1\x4c\xd5\xf2\xb2\xde\x7d\x1b\x6a\x5c\xf1\x90\x6b\x53\x24\x68\x97\x55\x37\xee\x8b\x02\x6a\x08\xa1\x12\x46\xc4\x6c\x7b\xce\xc8\x38\xe2\xee\x3a\x86\x77\x63\xa5\x26\x85\x9b\x5d\x56\x5c\x5e\xca\x73\x33\x4d\xf8\x43\x40\xa3\x05\x91\x43\xdd\x6c\x1b\x84\x9c\xb6\xc3\x21\xd0\x97\x87\x22\x06\xec\x8a\xa3\x97\xf5\xe1\x30\x55\xda\xe3\xa1\x4c\x4d\x05\xe5\xf1\xf7\xdf\xdd\xa7\x54\x02\xba\xeb\xc9\x9d\x8b\x66\x91\xe7\xcb\x73\x96\x1b\x74\xd4\xb0\x11\xe3\xc6\xcb\x28\x4e\x2d\x53\xd2\xc6\x55\xf5\x04\xba\xcf\x43\x0c\x85\xb6\x9a\xee\x24\x27\xd2\x79\x29\xf1\x10\x53\x4f\xf7\x72\xc3\x14\x1b\xee\xca\x8e\x2e\x38\xbe\x2d\x98\x32\xd2\x65\xb5\xfe\x29\xa3\x57\x59\xfb\x46\x31\xb7\x1e\xac\xf5\x1d\x07\xf0\xcb\x78\x2e\xf2\xfc\xc8\xf4\x09\x4e\xf0\x51\xd8\x80\x6d\x7e\x4a\x46\x5e\x2c\x69\xb3\xd8\x9b\xba\xec\xa2\x26\x1e\xe5\x73\x55\x12\xde\x67\xfe\xf4\x3e\x07\xe2\x42\xdf\x66\x15\xfe\x1c\xbe\x42\x91\x2f\x0d\x06\xf6\x11\x3f\x16\xa7\x93\x83\x46\xd9\x83\x01\x93\x3c\xe9\x4a\x74\x8b\x36\x8e\xab\xbb\x63\x3a\xa1\xba\xf7\x30\xdb\x72\xc7\x42\x8f\xf1\xc8\xa9\xab\xb5\xa1\xc6\x4d\x46\xa2\xec\xdd\xf1\x58\x91\xc8\xbb\xd3\x62\xf8\xd5\x1d\x88\xbc\x80\xf0\xa4\x39\x89\xfd\x92\x5e\x60\xf7\x85\x51\x1c\x92\x0a\xfa\x76\xbd\x7a\x7a\xbc\xd9\xb6\x29\xe2\xfe\x61\xf3\xf8\xdd\x31\x20\x79\x14\xf1\xd4\xb3\xee\xe0\xdb\xd7\xec\xb4\xbc\x4c\x7c\xa4\x78\x14\x21\x1a\x67\x4a\x7c\xc7\xaa\x79\x2c\x0b\x59\xc3\x95\x67\x83\x1d\x1b\x7b\x82\x89\x6b\x83\x8c\xb9\x82\x75\x14\x07\x31\x55\x2b\xef\xb3\xbf\xce\xdd\xdd\x4b\xfc\x88\x88\xf0\x16\xc1\xbe\xc5\x2e\x3a\x8f\x92\x04\x7c\xab\x1e\xf9\x2d\xab\x9b\x65\x23\xaf\x24\x89\x79\x94\x06\x8c\xda\x1d\x35\xe8\x71\x5f\x9a\x47\xa9\x45\xf5\x9d\xa0\x6a\x0a\xac\x6c\x3b\xb5\x1e\x99\x30\x4d\xa6\x4d\xaa\x7c\x2a\x04\xed\x2a\x9c\xf8\x24\xf2\x88\x07\x40\xe6\xf8\xae\x82\xd8\xa6\xa5\x9d\xd7\xd7\xff\xd8\x7f\xc6\xa7\xe3\xb1\x22\xa2\x8b\xc0\x66\xe8\xa9\x63\x8f\x42\x1c\xd2\xe4\x30\xa6\xbf\x93\x98\x34\x02\xc9\xa9\x3f\x7d\xbf\xfc\x62\xb1\x8a\x40\x7b\x54\x41\xcf\x14\x16\xcd\x10\x0a\x30\xbe\x10\x11\x08\xa2\x90\xac\x9b\xd7\x0a\xb4\xce\x71\xff\x1e\x08\xf7\xc3\x44\x08\x94\xbd\x17\x70\x9c\xc9\xa9\xdc\x20\xa9\x69\x55\xfc\xfe\xdb\xcd\x66\xf5\xd4\x7d\x54\x45\xd4\x35\x24\x17\x9e\x92\x52\xff\x41\xcf\x21\x12\x88\x84\x1d\xa2\x5f\x78\xdb\x2e\xe2\x23\x59\x01\x1e\x29\xab\xac\xf6\x00\x95\xc8\x71\x0d\x55\x0f\xc4\x9d\x7c\xbf\x4a\x7c\xda\xa5\x6e\xd7\xeb\xfd\x76\x7d\xbf\x5e\xed\xf6\x0f\x8b\x97\xbb\xcd\xe3\x7e\xfb\x7c\xdf\xe5\xc6\x91\x4a\x42\xb4\xaa\x7e\x7b\x23\x68\x6c\x84\xf7\xda\x98\x5d\x4d\x15\x09\xdd\x67\x44\x4c\xd5\x28\x71\xbe\xfc\xea\x30\x56\x3c\xd2\x81\x47\x65\xf1\x36\x6b\xfe\xb1\xde\x8c\x00\xba\xed\x51\x99\xd8\x94\xf9\x01\x7e\xde\x97\x50\x8c\xd9\xe1\x6e\x58\x6c\xaa\xd1\x0a\x2e\xcf\x65\xb3\xfe\x79\xca\x86\x06\x57\x3c\xd2\x49\x80\x64\xfe\xed\x78\x3a\x3c\xd2\x90\x70\x22\xe1\x62\x1b\xed\x75\xcd\x5a\xd2\xaf\x1f\x4f\xa0\xb8\x8d\xba\x82\xde\xd0\xca\x19\xef\x7f\x29\x26\xef\xb6\xc5\xd8\xf3\x83\xc4\xe2\x26\x02\x8a\x81\xaf\xac\x88\x78\xec\x09\x6e\x84\x14\xca\xb3\xc8\x71\x9b\x8d\x56\xc5\xd8\x13\x22\x4c\xa7\x7e\x24\xd3\xa8\x27\xf6\x63\x93\x97\x9a\x52\xda\x6d\x85\xf8\x57\xbb\xa5\x1f\x66\x69\x55\x3c\x0e\x52\x83\xbc\x59\x1a\x16\x6b\x3d\xfa\xc6\x80\x2b\xf2\xa9\x32\xaa\x7b\xfd\xe6\x14\x33\x8f\x13\xd3\xfa\x00\xcd\x2b\x56\x4f\xb9\xba\xc2\xa3\xbb\x81\x5c\xa6\x5e\x7f\xcb\x76\xaf\xf8\x54\x65\x87\x6c\xca\x3f\xe7\x31\xd3\x8c\xca\xb1\x0f\x8b\xdf\xf7\xcb\xef\x7f\x6c\x1e\xf7\x77\x8b\xed\x90\x80\xc8\xe3\x88\x19\xa3\xa6\x57\xa8\x89\x62\xf0\x6c\x99\x55\xe3\x6f\x8c\xe3\x38\x95\x03\x2b\xcf\xae\x61\x1d\xc7\xa9\x1f\xa4\xbd\xda\x9b\xe9\x85\xd6\x56\xf1\xcd\x0d\x4a\x12\x41\x9b\x52\xbb\xbe\xad\x8d\x66\xd1\x97\xa2\xe9\x96\x8b\x31\xfa\x2d\x09\x70\x4a\xa6\x15\x34\xb0\xa5\x70\x73\x65\x85\x0f\xd7\x3f\x9b\x0a\xc6\x09\x7d\x37\x41\x12\x61\x3c\x41\x2a\xc7\x0d\x1d\x40\x10\x79\x9c\x60\x4c\x39\x3c\x09\xe5\x2f\xb3\x11\xcc\x9e\xc7\x29\x08\xda\xdb\xb0\x00\x61\xb7\x4b\x57\x46\x03\x91\xe5\x1d\x0c\x95\xc7\xa9\xf2\xa8\x49\x55\xbf\x56\x59\xf1\xe6\x07\xe9\xe4\x39\xa4\xe8\xa3\x2d\xd1\x3c\xdf\x2f\x76\xd7\x5c\x30\x1e\xf3\x54\xc7\xc1\x00\x3e\x40\x2f\x62\x57\xc1\xff\x32\xa4\x88\xb9\x4c\x49\xb0\xa0\xfe\x80\xd3\xdf\xa8\x05\xf2\x18\x62\xc1\xac\x02\xa5\x51\x84\xba\xcd\xe1\x30\xe5\xab\x10\xc9\x3e\x30\x2a\x7e\x13\xba\xc7\xe8\xe5\x15\x11\x12\x31\x6d\xbb\x7e\x59\x3f\x6e\x76\x7f\xb8\x1b\x22\x52\x13\xf9\x8a\xac\xf9\x28\x2b\x55\xf7\x7a\x4f\xe3\x6a\x53\x2c\xb4\xb1\xb3\x6b\x43\xcb\x6f\x7d\x97\x3f\x96\xca\x33\x02\xde\x65\x05\xa3\xb7\x47\x79\xbe\xb2\xc8\x67\x03\x5e\x7d\x7a\xc7\xaa\xca\x14\x6e\xe6\x29\x0e\x3c\x56\xcc\x28\x0c\x75\xc6\x6c\x4e\x99\xad\xeb\x03\xc5\x2a\x36\x9d\xfd\x13\x75\xc8\xa9\x3c\xe4\x8e\x00\xe7\x68\x9d\x3e\xaf\xe8\x72\x76\x0c\x46\x3c\xb2\xfd\x51\xa2\xe6\x11\x74\xca\x1e\xd3\xe8\x3c\x47\x6b\xa7\x42\xdd\x66\x95\x04\xdd\x75\x5f\x92\x78\x2c\xa1\xfc\xae\x3d\xfd\xae\xec\x9b\x43\xbe\x3b\x9e\x44\xa1\x8d\x4f\x76\x3f\x3f\xe9\x3f\x25\x1e\x9a\x3b\xd9\xee\x62\xd7\xf1\x79\xe2\x47\x4e\x31\xdb\xf0\x18\x4d\x28\x39\x2a\x74\x24\x3e\x37\xc5\x4b\xd3\x0e\x33\xcc\xe1\xf1\xb4\x48\x7c\x19\x44\x9d\x74\xca\xe7\xb3\x2c\x09\x82\xd8\x57\x43\x52\x24\xad\x2b\xf3\x4a\xe4\x3c\x61\xa1\x4f\x3d\x10\x93\xaa\xfe\x80\x03\x81\x35\x9c\xd6\xed\x68\xca\x25\x8c\x2b\xe7\x32\x4f\x13\xe3\x3a\x9c\x4a\x98\x48\xa8\x64\x5a\x94\x0a\xf7\xaf\x38\x94\x11\x77\x23\x74\x20\xc3\x01\xb5\x6e\x2f\xcb\xfc\x6f\x4c\x8f\x78\x12\x06\x2a\xe8\x25\x68\xee\xce\x93\x60\x27\x09\x53\x8c\xcc\x5a\x53\xe0\x07\xe4\xb5\xe9\x82\x2f\xb4\xce\xf2\x0c\x1a\x24\x52\x98\x1b\x2a\x3d\xaf\x33\x76\xd9\xd4\x4f\x45\x6e\x3b\xad\xe3\xdf\x9a\x44\xa6\xb9\xde\xbc\x66\x95\x32\xf1\xb5\xe1\xbd\xad\x0b\xb5\xec\x4d\x34\x78\x92\x70\x4e\xa9\xb6\xd9\xe3\xaa\xfe\xcf\x82\xba\xfe\x96\x9b\xf6\xe4\x94\x3f\xe7\xe3\x30\x0a\x55\xa9\x0f\x0e\xef\x58\x5b\x01\xc4\xee\x54\x1a\xe8\x54\x7b\xea\x3f\x7e\x26\x1b\x39\x39\x61\x9b\xb0\xf9\x24\x29\xda\xde\x31\x7a\x2f\xce\x57\x00\xa6\x84\x73\x4e\x8e\x9d\x3f\x28\xa8\x1b\xf4\xbb\x13\x0e\x9a\xb2\x92\x36\xc9\x36\x3a\xd6\x63\x43\x47\x37\x4c\x80\xb4\x31\x36\x69\x8c\x1f\xb1\x5a\x42\xf1\x66\x54\xd8\x7f\x19\x0f\xd5\xa8\x3a\xf1\x11\x02\xdf\xb8\xef\x82\x30\xa1\x8a\x23\x5a\xd3\x78\x27\x1e\xfe\x4c\x66\xe3\x6a\xa6\xe2\x9a\x88\xc0\xe7\x56\x34\x6c\xff\xe1\xec\xb7\xfc\xee\x68\x12\x3b\xed\x06\x92\xb4\x22\xa4\x73\xf7\xce\x0b\x6e\xb0\x68\x05\x9e\x8f\x50\x75\x0f\x52\xea\x94\x48\x4b\xdd\x7b\xf3\x37\x73\x52\x6a\x10\x43\x6f\xac\x2b\x28\x3f\x4f\x54\x9a\xa8\xa8\x8f\x16\x7a\xef\x70\x77\x5c\xc4\x31\x8e\xe4\xf9\xbb\x23\x52\xd0\x9e\x84\xbd\xd8\x16\x4f\x30\xe4\xc6\xe7\x12\x8a\xf3\x44\xc1\x83\x27\x18\x2b\x2a\x0b\xc3\xe9\x94\x5f\x1c\xb5\xc5\x1d\x53\x9c\x60\xcd\xbb\x73\xd5\xe4\x78\x0b\xd5\xb1\x3f\xa9\x8e\x19\xed\x23\x96\x3e\x6b\x12\xcd\xbd\xa1\x9a\xec\x11\xe4\x6b\x37\x10\x7d\x8a\x45\x29\x12\x7e\x28\x55\xa6\xb3\x81\xa6\xe1\x38\xdc\x4e\x3d\x1e\x53\xcf\xa8\xa0\x95\xf0\x49\x93\x4b\xe4\x2f\xee\xa0\x0c\x28\xc8\xce\xb3\xa6\x01\x9d\x59\x00\x96\xa9\xe3\x4f\x7d\x43\x67\xff\xe9\xe3\xbd\xd4\x67\x46\x88\x85\xf0\xa4\x59\x61\x0d\xab\x3e\xbb\x2c\x5f\xa6\x36\x35\xfd\x13\x65\xf3\x0c\xe7\xda\xea\xd4\xfc\x32\x38\x65\xa0\x0c\x05\xf0\xca\x09\xc8\x1f\xdf\xf2\x94\x45\x48\x3e\x3c\xf7\xe5\x61\x71\xa8\x90\x2a\xee\x8b\x23\x52\x89\x7b\x06\x52\xcd\xd3\xd0\x17\x54\xd7\x90\x64\xff\x7f\xa1\xa6\xc6\xc2\x89\x01\xb7\x69\xe6\x65\x5a\x9c\x75\x1f\x0c\x4d\x73\x7f\xb9\x79\xd8\xec\x6f\x16\x4f\x7b\xe6\xef\x5d\x0b\x23\x0d\x55\xc2\xed\xbe\xfc\x02\x9d\x3e\xf4\xd5\x84\x4d\x43\x65\xda\xcc\xff\xc2\x22\xfb\x39\x24\x92\xf3\x34\x42\x46\x82\xa0\x3d\x6f\xab\x3b\xc0\x0d\xb7\xa8\x76\xa5\x9a\xdb\xb2\x5a\xe4\x57\x61\x91\x1d\x9e\x84\x3e\x35\x06\x4e\x96\xec\x64\xd5\x9f\xdd\x51\xce\xe9\xb9\x3f\xe0\x9f\x50\x77\x97\x9f\x48\x19\xda\x3a\x86\x1e\x38\x58\xdb\xa3\x69\x68\x68\x42\x76\x1d\x5d\xe5\x59\xbf\x6b\xa6\x69\xec\x51\x59\x77\x5f\x63\xa1\x9e\xab\xec\x58\x56\x2a\xb3\xfc\x67\xd2\xdc\xa0\xb2\x08\xbe\xcf\x17\x79\xd2\x94\xf3\xd4\xb0\xbc\x75\x9b\x56\xb8\xd7\x25\xe5\x41\x1a\xd8\x0a\xde\x09\x0b\xd5\x86\xa0\xb7\x55\xf9\x17\x16\x2b\x1c\xfc\xf2\xf1\xcd\xe5\x4c\xd2\x1d\x84\xf6\x2b\x47\x45\xf1\x14\x3c\x85\x16\x8d\x76\x97\x35\xdf\xce\x62\xb4\x2e\xa6\xe0\x87\x04\x32\xa6\x7b\xf6\xa4\x89\x32\x70\xea\x7b\x00\x6e\x5f\x4f\x01\x19\xe3\x5d\x33\xea\x01\xaa\x43\x56\x5c\xb9\x5c\xf1\x54\xf8\xa6\x7d\xd3\x66\xb0\xa7\x0a\xf7\x6f\x17\xb9\x27\x83\x90\xbd\xc2\xa2\x24\xc7\xad\x4f\x48\xc1\x3c\x15\x89\x0e\x6d\x56\x3a\x03\xd1\x48\x85\x66\x84\xfd\x19\xea\x5a\xfe\x85\x55\xd9\x67\xbd\xa9\x64\x71\xd4\x19\x0c\x3f\x64\x87\x0a\x1a\x24\xa0\x94\x3b\x9e\xc4\x54\x94\x3a\x96\x8a\x27\xbe\x37\xcc\xf6\x53\x09\x82\x82\x39\x71\xae\x0a\xaa\x0f\x4e\xeb\x82\xa9\xd4\x06\x91\xd6\x9c\xab\xc2\x18\xe3\xb8\xf3\x2a\xe6\x53\x2a\xfb\xf4\x41\x19\x43\x1b\xf4\xde\x2c\x9e\xba\xa3\xd2\xba\xe3\x99\x39\xbc\x9e\xba\xae\xcc\xdf\x0d\xf4\x19\x2d\xb7\x77\xd8\x74\x5c\xb4\xe7\x2a\x2b\x64\x76\x1a\x23\x7b\x52\x4c\xc1\xb5\x17\x7e\x45\x29\xe1\x6d\xf2\x4c\x50\x28\xda\x07\x8a\xf3\xd1\x19\x21\x74\x8b\xa1\x0e\xbd\xc0\x72\xb1\x56\x39\xd4\x35\xe1\xf1\x4d\x44\x32\x57\x13\x4a\x75\x64\xbc\x1b\x6f\x0e\x13\x26\x43\xaa\x31\x22\x20\xf1\xe2\x50\x65\x24\xf4\xb3\xbb\x9c\xdc\x0d\xe2\x9e\x97\xf8\xa1\xa3\x86\x2f\x1d\x5e\x72\xf6\x87\x73\x1f\x90\x14\xd4\x09\xaa\xb0\xff\xa0\x28\xae\xee\x4d\x28\x3e\xd9\x16\xdd\x44\xe5\x41\xa0\x9d\xf9\xcb\xaa\xcc\x88\xd6\x49\x70\x00\x35\xda\xa4\x79\x00\xc6\x66\x74\xf3\xb8\xfa\x7d\xb8\xe6\xf0\x40\xa5\xb4\x4a\xfe\xfa\xb8\xea\xfe\xa4\x63\x22\xf8\x9c\xca\x99\xfc\xca\x8e\x61\x51\x4a\xee\x97\x53\xcd\x2e\x07\x03\xe3\x2c\xe5\xe4\xb3\xb0\x6e\x57\xdb\x25\x36\x6d\x54\xf8\x02\x7f\x4d\x57\xcb\xee\x77\xb0\x14\x5d\xfd\xd0\x91\x37\x3b\x77\xdb\xd4\x73\x83\x78\x40\x95\xf5\x36\xaf\xc9\x6b\xc3\x47\xb9\xd2\xd4\x1f\xcd\x06\xce\x80\x0f\x60\x58\x7b\x9d\xc3\x61\x7f\xa5\x36\xcb\x39\x93\x46\x5b\x7e\x0b\x79\x59\x64\xa3\x3b\x14\x26\x11\x85\x2a\xa0\x94\x35\xf0\xda\x95\xb4\x6e\x58\x7d\x05\x23\x11\x36\xf2\x1f\x1a\x4d\x15\x1e\x79\x71\xd8\x03\xd6\x9c\xbd\xee\xd8\x21\x83\xf3\xc8\x37\xa2\x70\xb3\x62\x7c\x9f\x08\xed\x70\x1e\x85\xcc\x70\xcb\x2b\x17\x74\x0e\x8e\xa5\xcc\x0f\x5d\xcd\xda\xb8\xad\x0d\xfb\x14\x3c\xe2\xbe\x17\x75\xf6\xd8\xcd\x37\xcc\x4f\x83\xaf\x1d\x9d\x2a\x8e\x8d\x72\x63\xb7\x3b\x77\x81\xf1\x17\x8e\xe3\x9c\xc7\x89\x4f\x1f\x23\xd4\x61\x87\xcb\x9a\xfc\xf0\xc4\x13\x54\x2c\xcc\xea\x7b\xac\xeb\xdd\x2b\x7c\xd2\xbf\xe1\x89\x6f\xa6\xaa\xfd\xf8\xa0\xfa\x39\x7e\x96\x69\xac\x79\x27\x69\x44\x71\xe0\x5d\xbb\x18\x4f\x62\xb8\x76\xe7\x21\x6e\xc2\x7b\x86\x1f\x54\x97\x37\x18\xfb\xfb\xac\x6e\xae\x9a\xf0\x3c\x55\x81\x86\xce\xbc\xee\xb7\x81\xf2\xce\xf4\xac\x4a\x50\x3d\x41\x65\x15\xca\xc6\xb1\x82\xae\xb3\x01\x0e\x09\x0c\x72\xc1\x15\xe6\x28\xa6\x1e\x2c\x93\x19\xf0\xef\xf8\x3f\x83\xff\xed\x4e\x63\x22\xd1\x1c\xea\xc6\x79\xd0\x6e\x5c\x7d\x92\x0b\x0e\x2e\x89\x74\x71\xbe\xc9\x51\xd4\xd3\x67\xeb\x91\x0a\xd2\x38\x76\x56\x2b\x57\xf4\xcd\xf6\xb8\xa2\x48\xfc\x5c\x64\xef\x58\xd5\x4e\x00\xc5\x1d\x4d\x18\x23\x57\xed\x3c\x6b\xfe\x32\x0e\x0b\xee\x10\x0a\x44\x07\x2f\x30\xd6\x75\xa7\x1c\x5d\x0c\xfc\xe9\x42\x83\xca\xe7\x36\xbb\xb0\x25\x95\xfb\xec\xbf\x67\xb3\x3d\x94\x8e\xf8\xca\xc1\x53\x2a\x49\xba\xfd\x7a\x99\xf5\x2e\x17\x53\x60\x26\xf8\x51\x4a\xd9\xbf\x34\x6e\x15\xeb\xdd\x37\x53\xa7\x72\x87\xd1\xa4\x33\xcf\x15\x6e\x56\x4f\xff\x14\x70\x3f\x9e\xf8\x10\x84\x3e\x91\x78\x8c\x3e\x40\x79\x2e\x54\x6d\xca\x14\xbb\xf2\xa5\x6b\xa7\x40\x10\x1a\x5a\xf1\xb9\xc6\x2a\x37\xc2\x16\xf6\x08\x4b\x12\x66\x0b\x69\xcb\xb2\x99\xb2\x01\xdd\x20\x1d\x46\x36\x14\xed\x76\xa1\x2d\x76\x0a\x4b\x76\x54\xe4\x1b\xb5\x28\x09\x79\xee\x8f\x67\x35\x44\xb1\x47\x52\x1e\x3f\x5e\x11\xf3\x27\x7d\x5b\x56\xcd\xb9\xc0\xe9\xa0\x54\x52\x5d\x59\x9f\x3f\x79\x31\x21\xe2\x86\x36\x74\xea\x9b\x4a\xf4\x9b\x6d\x64\xf6\xe5\xc6\x0f\x91\x4c\x28\xe1\xde\x7d\x5b\x13\x8a\xce\xdd\x82\x38\x10\xf4\x98\x1e\xd6\x77\x8b\x87\xc5\xfd\x7d\x6f\x1f\xca\x21\x96\x12\xc3\x6e\x1b\xcf\x8e\xbf\xe2\xa5\x1e\xb6\xeb\x20\xd6\x4a\xb2\x7e\xa9\x58\x34\xbf\x8c\x54\x6f\xec\xa8\x24\x8e\x7a\x78\xd5\x66\xf5\x34\x74\x9c\x6d\x8f\x6a\xc7\x39\xdc\x14\xa7\x73\xf3\x38\xc3\x56\x74\x43\x53\x20\x01\x3e\xeb\x44\xf1\x58\xf6\x38\x38\xe0\x1e\x07\x5b\xf0\x7c\xb2\x78\x8a\x76\x22\x5b\xe9\xd9\x6a\x33\x79\xa8\x5c\xfa\xc2\xfe\xb4\x3d\x25\x29\xfe\x5e\x8c\x80\x75\xc0\x65\xe4\xc9\x8e\x02\x30\x42\x6e\x00\xa4\x9e\x98\x3a\x35\x8c\x2b\x91\x20\xbc\x90\x1a\x48\xaf\xd0\xc8\xd7\xf5\xe1\x30\xa7\x1d\xc7\x41\xf8\xc6\xf1\x71\x57\x9d\xbb\x2f\x16\x49\x82\x51\x6f\x42\xd6\x9d\x51\x32\x9f\xfa\x4a\xc7\xfa\xa0\xa0\x03\x7b\x81\x8c\x38\x95\xa4\x3f\x5e\xa1\xb9\xc9\xd4\xff\x42\x5d\x16\x5b\x70\xc1\x2b\x28\xdf\xd4\x67\x75\x56\x38\x93\xac\xe5\x65\x5d\xa8\x53\x99\xf5\x50\xaa\xd1\x5d\x56\x49\x40\xd7\xb4\x97\x50\x58\xa2\xfe\x6d\x85\x93\x65\x1d\x50\x70\x9a\x8c\xca\xa2\x1b\x76\xa5\x15\x86\x18\xef\xf8\xa0\x21\x21\xa4\x81\xd1\xf7\xb4\x09\xd7\x3f\x66\x5e\x9b\xe9\x34\xfe\x66\x0d\xca\x55\x9c\xa9\x10\xe2\x00\xdc\xe6\xb0\xf0\xbc\x28\xb5\x09\x2c\xd5\x26\x7e\x20\xbe\x8d\x5e\x55\xe1\x85\x18\x5b\x17\x02\x53\xf9\xbf\x2d\xab\xe5\x59\x1d\xf0\x1a\xd0\x72\x95\x9b\x0b\x2f\x11\xe2\xcb\xf8\x61\xa0\xfe\xe4\x3e\x22\xbd\xde\xda\xb6\xf3\x0c\x46\x69\x7c\x8f\x86\xfd\x9e\x29\x49\x54\xf8\xa9\x47\xba\x09\x37\x04\x66\x1b\xed\xc3\x6e\x84\xf6\x29\x40\x36\x3c\xc6\x17\x28\x54\x79\xdc\xce\xc0\x67\x44\x60\xbd\xf5\xcc\x40\x03\x31\x37\x62\x40\xb3\x6b\xab\x08\x38\x70\x8b\x9c\x5a\x3c\x4f\x5e\x1f\x11\x68\x23\x61\x75\x2e\x4c\x96\xf9\x55\x1d\x50\xb0\xc0\x80\xe5\xbf\x3d\x7d\xdf\xae\xf7\xeb\x9b\xbb\xf5\xfe\x66\x43\x86\x4e\xee\x99\x31\xad\x28\x0d\xa4\xe2\xc1\xb2\xfc\xe9\xfe\x1e\xa6\x41\x6a\xda\xfd\x6d\x5e\x36\xe6\xfe\x0e\x6f\x53\x08\x1e\x75\x8d\x4e\x70\x59\x7c\xbd\xd1\x89\x28\x4c\x43\x17\x8e\x4c\x85\x5e\xa7\x43\xd3\x20\x30\x96\xbd\xcd\x0d\xd6\x4d\x55\x5e\x96\xe5\xa4\xf2\x2b\x22\x08\x74\xe2\x8c\x88\x5d\x5b\xc2\x5d\x7e\x1c\x68\x2a\x43\xb5\x41\x03\xd5\x57\xf7\x3a\xec\x8e\xf1\x88\x40\x02\x0d\xc2\xd1\x1f\xee\xed\x22\x8d\x24\xd1\xb0\xb6\xd9\xf1\x94\x93\x98\xb0\xda\x36\x65\x35\x65\x3d\x0b\xce\x8c\x76\x11\x05\x8b\x77\x24\xe7\xef\x4e\xc1\xb9\x6f\x7d\x44\x49\x32\xa7\xeb\xd7\x0b\x08\x62\x6a\x70\xf6\xd8\xc3\x76\x5f\xfe\x65\x82\x9a\x13\x10\x20\x17\x04\xc6\x33\xdf\x3b\xfe\xcd\x90\x24\xda\xa8\x69\x91\xbb\xc7\xe8\xe2\x21\x8d\xa9\x53\xbb\x7b\x45\xdb\xad\x24\x62\x5d\xdf\xc2\x10\x20\x25\x31\xfe\x87\x98\x9b\xc9\xec\x12\x21\x50\x8b\xe5\x07\xe4\x4d\x69\x48\x25\x46\x48\xec\x93\x30\x78\xf2\xdc\x44\x1a\xca\x21\x51\x73\x3d\x68\xa0\x4f\x46\x4a\x9f\xda\x31\xeb\x9f\xd0\xde\x6b\x36\xbe\xc1\xd2\x67\x04\x10\xd8\xdb\xd8\x11\x8a\x77\xa8\xa7\xb0\x1c\x37\x36\x66\x6e\x17\x6b\xc3\xb9\x0e\xad\xd4\x7f\x97\xe4\x11\x4f\x5d\x15\xa1\x19\x34\x37\xdd\x8d\x91\x18\xd2\x8a\x7a\xc1\x66\x51\x94\xcd\x6b\x2f\x32\x7b\x6d\x2f\x6f\x3f\xa2\xc2\x94\xae\xf0\xb7\xfb\x11\xbc\x4d\x28\x6e\xb4\xbe\x3b\xcb\xa8\x6e\xda\x29\x10\x24\x25\xd5\x64\xa7\x7a\x3e\xae\x17\x28\x53\x66\xf1\xfb\x1d\x0c\x9a\xaa\x8a\x83\x7a\xa2\xf4\x3c\x46\x1c\x74\x52\x7e\x7a\xd2\xbf\x5c\x09\x7e\xdb\x71\x3e\x70\xea\x8c\x58\x72\x1b\x49\x11\x4c\x9f\xde\x95\xc1\x0b\x97\x41\xe8\xc7\x03\x47\x1a\x97\x57\x8d\xcf\x1d\xc4\x29\xb7\x17\x4a\xbd\xe6\x9b\xb3\x01\x12\x5c\xa9\xb9\x70\x19\x68\x41\xc5\x8a\x25\x14\x05\x8e\xfb\xb2\x92\xf9\xcc\xef\xbc\xd5\x96\x84\xd9\x71\xf5\xc6\x74\x9a\xed\x4e\x7e\x1d\x63\x01\xa9\x79\x3a\x9f\x9b\xe5\x6e\x35\x29\x92\xfe\xcf\xdc\xb6\x2f\x19\x53\x8e\xe7\xfa\xad\x3c\xd7\xb8\x9e\x68\x05\x8c\x2f\x9e\x45\x46\x82\xbc\x4b\x05\xa8\x42\x36\x3a\x61\x08\x8c\xde\x18\x95\xd5\xa7\x36\xe0\xb0\x8f\x5b\x46\x21\x33\xba\x3b\x25\x76\x22\x86\x9b\x76\xaa\x1b\x0f\x8d\x06\x2b\x0d\x72\x62\xce\x6a\x31\x90\x32\x66\x82\xcb\xde\xff\xfd\x19\xb1\x1a\x73\x0f\x64\x1c\x02\x45\x0a\xf8\xfe\x82\xb2\xac\xae\xf5\xfd\x47\xd7\x18\x4b\x3f\x71\xc6\x49\xb3\x8e\x49\xe3\x7b\x1b\xa3\x32\x36\x60\x76\x51\x7d\x2c\x09\x44\x36\xbe\x35\x89\x1f\x52\x4c\xb4\x07\x29\xf1\xd4\x10\xd0\xcc\x5d\x5d\x92\x98\x78\xe9\xd7\xe5\xa6\x19\xbc\x1c\x32\xf5\x7c\xf4\xbb\xc5\x71\x56\x6a\x9f\x4b\x1e\xc4\xa4\x5d\xb3\x3f\x19\x98\xfd\xfa\x67\x56\x37\xd3\x6f\xe7\x4c\x52\x11\x54\x0a\x92\x01\x1a\x99\x69\x72\xc9\x95\x20\x9e\xd6\x66\xf5\x24\x27\xfa\x3b\x5c\x72\x6d\x30\x39\x7b\x43\x25\xfc\x0b\x6f\x21\xcb\xcf\x15\x3a\x6a\xd8\xe8\xce\x01\x37\xc9\xae\x81\x78\x50\x54\x93\x15\x87\x45\xf7\x4d\x20\x19\xe5\x52\x65\x91\x5f\x06\x9e\xa8\x2b\x28\x6e\xca\xdd\x6b\x56\x77\xe3\x34\xd0\xc2\x68\xb4\xa8\x4c\x07\xcc\x1e\x12\x2c\xa6\xb2\x48\xbb\x55\xed\x7a\x3d\x91\xc9\x33\x11\x2a\x26\xb8\xf3\x9e\xfa\xcf\x76\x36\x10\x44\x6f\xbc\x1c\x4a\xa5\x04\xf5\x6b\xd7\x8b\x97\xfb\x3f\xf6\xcb\xf5\x6e\xbf\x79\x5c\xad\x1f\x77\x9b\xdf\xd6\xfb\xd5\xd3\xc3\xc3\x66\xbb\xdd\x3c\xb9\x3c\x43\x22\xea\x68\x60\xcd\x4e\xeb\xac\x3b\xa6\x83\xd4\xba\x2c\xb5\xb7\xef\xee\x0c\x44\x0c\xc6\x81\x8c\x31\x97\x1a\x12\xaa\xb6\x77\x5d\xae\x47\x63\x8c\x43\x6b\xe2\x9c\x4d\xc5\xdf\xfc\xeb\x4e\x2b\x18\xe5\xc4\xdb\xf2\x7c\x9a\x71\x08\x31\xa3\x94\x1f\x07\x94\x5d\x1e\xe1\x27\x11\x7d\xd5\x40\xa7\x8b\x2b\x5f\x9a\x55\x3f\xab\xd7\x79\x76\xb0\x70\xf8\x49\x8c\xe2\x86\xaa\xc4\xeb\x5d\xda\x6f\xcf\xc5\x50\x07\x40\xf9\x18\x92\x73\xf8\xff\xfe\x6b\xc0\xea\x56\x2c\x96\xd1\x50\xdb\xa8\x42\x9b\x0d\xee\x4a\xbb\x26\x8d\xa7\xac\x0a\x7d\x15\xda\xe0\xd9\x59\xb6\x77\x6b\xa6\x0d\x1b\xed\xc8\x28\x56\x01\xf6\x7d\xbe\x4e\x8d\x99\xf8\xd6\xf5\x6d\x59\xc9\x79\x09\x4d\xae\x22\x15\x3a\xfc\xe3\x8f\xac\x28\xb0\x5a\x5e\x6e\x2a\xf8\x18\xa2\x08\xc6\x1f\x48\x82\x10\xa3\x9e\x59\x58\xe1\x46\x96\xeb\x42\xdd\x5c\xb5\xe2\x55\xa2\x12\xd2\xee\xda\xbe\x3c\xee\xf6\x27\xac\xf6\x3d\x21\x5a\x25\x9a\x79\xdc\x29\xf8\x5b\x01\xfa\x51\xda\xa6\xd2\x38\x20\xd8\xd5\xde\xc4\xc0\x53\x6f\x94\xf1\x57\xa5\x8a\xd1\xe2\x36\x10\x4c\xfa\xbe\xdb\x3c\x3d\xee\x6f\xbe\xbf\x2c\x76\xfd\xec\x55\xa9\x12\xe4\xf3\x95\xd5\xce\x72\x67\xfc\x5c\x79\xc2\x49\x76\x6e\x95\x95\xed\xa3\x5b\xbf\xac\x02\xff\x0b\x2f\xcc\xc9\xcd\x6c\xd7\x76\x6e\x74\xaf\xc6\x3e\x5a\xee\xb8\x8a\x2c\x22\x84\x1e\xd3\x72\xb9\xfb\xe4\xa9\x80\x1f\x10\xb1\x6a\xb1\x7b\x19\xc6\x0a\x4a\x44\x8a\x7a\x2b\xdb\x06\xe1\xad\xff\xa3\x8e\xac\x8e\x8a\x05\xe5\xcf\xf9\x38\x71\x25\x92\x94\xdc\x2c\x4c\x3d\x68\xdb\x80\x9c\xb4\x09\x94\xf4\x62\xaa\x8e\xbe\x97\x0d\x0e\x3b\x23\x4a\x06\x18\xf6\x7a\xc2\x9b\x06\x8f\xff\xe8\xf5\xec\x4f\x1c\x9a\xc6\x8d\xf3\x2e\xcc\xf3\x36\xf0\xea\x9e\xb5\x4a\x4c\xb9\xf3\x80\xcd\xf7\xcd\xcd\xe4\xd9\xb6\x91\x96\xb6\x4d\x9f\x4e\x4c\xdb\x1d\x8b\xa4\x67\x35\x00\xe7\x01\x3a\x0a\x93\x94\x1e\xf8\x0e\x6b\xc3\x6a\x86\xaa\xe7\x8b\xb9\x31\x82\x13\xc2\xcd\x3a\x55\xae\xca\x42\xe6\xe7\x9e\x26\xa4\xb4\x4e\x89\x99\xe8\x76\xb7\x07\x02\x17\x0c\xeb\xc7\xdd\xf7\xa1\x17\xfa\x04\x1c\xbb\x5b\xaf\x7f\xdd\x76\x45\xc7\xf6\xcf\x9a\x0d\xf2\xe0\x1f\xd4\xd3\x40\x35\xd4\xa2\x73\x63\x83\x80\x39\x38\xd8\x8f\xac\x70\x38\x9d\x49\x73\x00\x03\xce\x09\xb9\x2f\xa0\x78\x73\xe2\x12\xee\x90\x4c\xd2\xb8\x53\x33\x19\xd6\x5b\xfb\xeb\x64\x5e\x42\x9a\x72\xee\x37\x2d\xa1\x78\x6b\x77\xbd\xf9\x09\x89\x2c\x10\x5a\xb8\xd4\x89\x64\xe1\x86\xcf\x01\x99\xf0\x65\x87\x04\x6e\xd7\x2a\x2c\x9a\x4c\x66\x9d\x25\xa4\x1d\x16\x32\xec\x88\x02\xf7\xbf\x59\x89\x43\xcf\x9d\x24\x0c\x19\x4d\xb2\x57\xa8\x5f\xbf\x72\x1c\x74\xc3\xd3\x34\xec\xb4\x6f\xf6\x46\x5f\x69\x3f\x10\x57\x68\x07\x10\x54\x72\xf9\xf4\xfd\x71\xf7\xc7\x18\xff\x8a\x51\x24\x09\x37\xe7\xd8\xaa\xf7\xeb\xdf\xd6\xf7\x1d\x75\x04\x63\x0e\x6e\xe9\xb5\x0e\xbe\xcf\x70\xc0\x6d\xd6\xf5\x68\x31\x81\x38\xb6\x49\xc4\xde\x80\x49\xc6\x97\x97\x20\xa7\x36\x19\xad\xa4\x4f\xfa\x3e\xd3\xf8\x77\xa6\xba\x1c\x79\x12\x10\x41\x54\x67\x39\xde\x67\x85\x7b\xc5\x91\xa7\xc6\x3e\xe5\xc7\xf6\xd7\x3f\x06\x5b\x0a\x72\xae\x52\xbf\x73\xd6\x28\x0a\xcc\x6f\xf1\x0b\xeb\xa6\xf1\x33\xe5\x22\x12\xb6\xa0\x4a\x56\xef\x9d\xcf\xfb\xa8\xc4\x84\x10\xc7\xb1\x70\x4d\x57\x03\x0f\xdb\xd7\x59\x71\xc8\xf1\xb1\xec\x28\x91\x08\x10\x53\x16\x5a\x7f\x20\x9e\x76\xe5\x40\x26\x9b\xa3\x40\x30\x11\x74\x85\x38\xc9\x0b\x50\x72\x4c\x4d\x7e\x5a\x94\xe7\x42\xe2\xf2\x5c\x0d\x3e\x29\xa5\x27\xb5\xab\x37\x5a\x67\xc6\x19\xf9\x71\x8e\x52\x31\xa2\xe4\xbc\xc0\x9f\xbb\xce\x31\x83\xa3\x4a\x03\x77\x7f\x6e\xb2\x22\x9b\x7f\x65\x55\x6a\x9e\xa4\xad\x29\x92\x67\xee\xe4\xf4\x8a\x8b\x38\xec\xf4\x5c\x4e\x65\x3d\x11\xc1\x76\xc3\x54\x42\x68\xf0\xd5\x6a\xa2\xaf\x80\x4a\x1b\x81\xc0\x57\xa8\xd4\x07\x54\x38\x52\x7e\x42\x8c\x91\x8a\xae\x9d\x5a\xd1\x90\x4b\x3b\x2e\xf5\xa0\x8e\x18\x95\x10\xf7\x99\x01\xed\xde\x43\xa1\xec\x9a\x99\xba\x21\x4a\x75\x9e\x78\x97\xdb\xaa\xbc\x5a\xac\xcd\x38\xed\x45\x1e\x11\x02\x2c\xf0\x65\x5a\xbe\x1f\x3d\x28\xed\x21\x46\x36\x23\x98\xc1\xb0\x6a\x3f\x30\x1e\x6d\x59\x83\xc7\x7a\x79\x99\x5a\x25\x70\xed\xcb\x90\xca\xcf\xfa\x4a\xbb\xd2\x0e\x08\xfc\x88\x59\x94\x42\x0f\x83\x1c\x90\xec\xbb\xcc\xa3\xbb\xdf\x3a\xe0\x22\x11\x8e\x97\xfd\x86\xc5\xf7\x2a\x7b\xae\x50\x8f\xbf\x38\x50\x66\xe9\x3a\xc2\x1b\x9a\x5f\x3a\xea\x4b\x7e\xc9\xe1\xd7\x4c\x70\xf2\x28\x6e\xaa\xec\x70\xc0\x8a\x18\x50\x43\x45\x88\xfe\xf2\x43\x2f\x74\x2a\x13\x33\x05\x36\xfb\x68\x74\xe4\x09\xf2\x7c\xe9\x28\xb8\x93\x0e\xe3\xec\xea\xab\xa3\x14\x08\x79\x59\x95\x0d\x34\xb8\xcf\x51\x7f\x82\xa6\xd4\x31\xe8\xd0\xae\x4a\xff\xc2\xe6\xd5\x90\x18\xbb\xb5\x7d\x32\x56\x28\x32\x23\x75\x10\xa9\x5e\x16\x98\xeb\xc4\x0b\x74\xdf\x89\xbb\xc9\xe0\x58\x16\x6a\x5a\xd1\xf9\x3b\xb7\x1c\xae\xd3\x50\x12\x1a\x63\x95\x23\x54\xc3\x17\x42\xa7\xa9\x04\x23\x99\xf2\x6d\xb1\x79\x1c\x1f\xe2\x7e\xe0\x3b\xae\x24\xbe\xe5\x17\x07\x4d\x1b\x86\x14\x3a\x95\x2a\xb1\x00\x3c\xfa\xf4\x33\x64\x9f\xde\xc6\xaf\x17\x42\xcd\x3d\x4d\x3a\xf0\x6d\x26\xf6\x5c\xbe\xe1\xb1\x9c\xae\x2f\x9a\x73\xe3\xdd\x65\xa9\x2e\x13\x3f\x4b\x37\x48\xa5\x68\xb4\xfe\x1c\x9b\x65\x40\x29\x9a\x9c\x10\xe2\x80\x9a\x73\x26\xba\x7d\x80\xfa\xed\x9f\x89\xaf\xb7\x9f\x34\xd2\xe9\xe6\x93\x8f\xf8\xd3\xf0\xf2\x3a\xf6\x43\x77\x87\x40\x25\xc4\x49\x6d\x5f\x49\xf3\xca\xfe\xcd\xed\xe9\x3e\x97\xd2\x9c\xc7\x9f\x5d\x7e\xac\x85\x97\x38\x57\x82\xdb\x0a\x71\x48\xb5\x98\x7c\x5a\x42\x60\xdc\xdd\xcf\x97\xe9\x3b\xe6\x46\xc8\x84\x40\x34\xe2\x4c\xa2\x57\xf5\xa2\xe9\x09\x39\x5a\xb1\x90\x98\xec\x2b\x54\xf8\xb3\xfb\x63\x88\xbe\x65\x3c\x13\xbb\x60\x35\x70\x79\xf8\x04\xea\x30\x5c\x26\x54\x12\xaa\x4e\x84\x05\xe7\xac\x23\xaf\x5a\x97\xe3\x99\x6e\xcf\x83\x89\x03\x84\x93\xdb\x06\x14\x8d\xe1\xc9\x4e\x1e\x2d\xa2\x6f\x95\x85\x9c\x27\xd5\xf8\x0e\x69\x15\x93\x55\x06\xe4\x86\x4c\xb9\x2a\xcb\x4a\x65\xc5\x50\x7f\xbf\x1b\xa9\xa9\x54\xbe\xae\x64\xe0\xdd\x74\x66\x93\xe0\x79\x10\x38\x7c\x29\x89\x34\x94\xba\x6b\x55\x18\xba\xbc\x1b\x27\x15\xe9\x98\xdd\x54\xf0\x17\x0e\x77\x24\xf0\x3c\x0d\x04\xa6\x97\xd0\x06\xe3\x43\xd1\xab\x61\x65\x09\x3c\xdf\x37\xbd\xed\xac\x76\xf8\xda\x6f\x50\xff\xfa\xc7\x4a\x57\xe5\xf1\xc7\xfd\xe8\xa7\x83\xe7\x87\x31\x25\xf7\xcf\xbb\x3f\xae\xe4\x0b\x07\x0b\x03\x78\x81\xa7\x69\xe5\xfe\x91\x15\x6a\x74\x59\x81\x9f\x38\xd5\xc8\xdf\x4a\x4b\xc8\xcf\xca\x31\x0e\x0b\xbc\x40\x09\x8a\xfb\x3b\x5c\xff\x73\x59\x8e\xe9\x05\xe0\x31\xee\x53\x54\xbf\xb8\xfb\xfa\x52\x98\xf4\xfd\xa8\xd3\x87\xa6\x3c\xbe\xc7\x2d\x81\x17\x46\xda\x4c\xc8\x97\xa7\xed\x76\xff\xb2\xde\xae\x5f\x7e\x5b\xef\x6f\x77\xbf\x77\x03\x52\x63\xa3\xf2\xfc\xf2\xd4\xf7\x63\xc1\x0b\x39\x27\x44\x38\xc5\x86\xc6\xbc\x6d\x6e\x71\x07\x2f\x8a\x63\x2a\x9a\x1c\xe1\x67\x76\x3c\x1f\x1d\xc3\xf7\xb6\x1a\x6a\x0b\x82\x17\x25\x1e\x15\xa1\x24\xc9\xd5\x37\x96\x51\xcd\x82\xc9\x9d\x89\x38\x97\xf6\xe5\xda\x74\xd3\x25\x92\xca\x33\x4d\x2d\xb5\x82\xca\x8a\x51\xfc\x72\x6d\x5c\xf8\xd5\x3f\xd3\x37\x1d\xbc\xd8\xc7\xa4\xd7\x18\x7a\x44\x68\x26\xb3\x21\x06\x45\x9b\xdd\xa9\xac\x9b\x65\xb7\x2d\xda\x83\x89\x0f\xd2\xeb\x71\x95\x43\x16\x28\x78\x29\x13\x69\xec\x7a\xb6\x20\x9b\xbd\xe1\xe1\xa8\xee\xb8\x10\x69\x97\x8f\x92\xe3\x86\x2b\xf8\xa5\x6e\x04\x4a\x42\xb5\x81\x49\x85\xaf\xe0\xc2\x76\x18\x67\x9e\xa9\x49\x5a\xe4\x43\x0f\x8e\x06\x0f\xa2\x80\x02\x12\x28\x4c\x68\xfa\xcb\x68\xda\x40\x62\x8a\xea\xf4\xab\xee\x1e\x56\xbb\x2f\x27\x19\x70\x46\x5b\xc3\x91\x2a\x1d\xa6\xa1\xd7\x7d\x0f\x22\x65\xdd\xcb\xf3\x65\xdb\x94\xf2\xed\xa5\x94\x6f\x96\x4e\x32\x11\xbc\x73\xff\x8c\x7f\x83\xf2\xac\x61\xa1\xc8\xf2\x7c\x0f\x79\xbe\x1f\x80\x0e\xba\x5b\xaa\x7c\x23\x49\xd8\xd5\xdd\xb6\xe7\xe3\xae\x1c\x77\xc1\xda\x51\x09\x3d\x32\xa3\xcb\x6c\xcc\x00\xdc\x7b\x3f\x0b\xe5\x6a\x3f\x92\x52\xa1\xc6\xe4\x49\xbf\x8f\xde\x66\x15\x29\x69\xf1\x9c\xdf\xeb\x36\x7c\x1a\x6a\x12\xbb\x31\x31\x58\x35\x6b\xa3\xd7\xfb\xf2\x74\xfb\x32\x28\x3e\x80\xa7\x52\x05\xbd\xfb\x80\xd5\x6e\xed\xa6\x82\xe2\x29\x6d\x87\xb6\x1e\x35\xfc\xe5\xe3\xe9\xaa\xa3\x30\xb4\x7d\xcb\x4e\xb7\xf3\x93\xe0\x6f\x7e\xc2\xfb\x5e\x12\x84\x5e\x57\x92\x7d\xc1\xc3\x5c\xff\x02\x7c\x4f\xf8\xe4\xfa\xdb\x97\x0b\xb2\xe2\x26\x7b\xb7\x6a\x6e\xe0\x7b\x2a\x70\x2e\xa6\xfb\xb2\x22\x09\xd3\x1a\xdb\x27\x77\xbc\x2a\xda\x80\xef\x7b\xa8\x60\x0c\x95\xb8\x83\xda\xf8\x59\xcd\x5f\xa5\x1f\x98\x62\x8a\x15\xcb\x75\xc5\x8e\x39\x35\x3d\xf0\xfd\x38\x08\x99\xd5\xea\x70\x50\xa9\xcf\x9c\xc1\xae\x1b\xfe\x53\xab\x37\xf0\xfd\x34\x22\x9c\xd9\x7b\xd9\xe0\xfe\x64\x52\x25\xb5\xb7\x63\x46\x2f\x90\xef\xa3\xe7\x19\x17\x88\xc3\x03\x34\xf2\x35\x2b\x0e\x6b\xfb\x96\x77\x7b\x37\xf8\x2c\x88\x04\x8e\xbd\x9f\xbf\x57\xd9\x2f\xfd\xae\x9d\x3a\xe6\xf2\xb9\xd7\x84\x00\x9f\x45\x26\xa3\x92\xe5\xf1\x74\x6e\x70\xfb\x0a\xac\xab\xa0\xf8\x03\xcc\x58\xfa\x1f\xfb\x81\x30\x8c\xa8\xd9\x8a\xc7\xac\x79\x31\x7a\xd8\x57\x5c\xe4\xc9\x6f\x0d\x39\x90\xea\x9f\x80\xe2\x2d\xf8\x0d\x72\xf7\x7c\x43\x21\xa9\x19\x22\xca\x9f\x54\xff\x8f\xdc\x81\x48\x1b\x87\x4c\x12\x77\x5f\x2f\xee\xdd\xdf\xe3\x30\xd0\xa9\xe3\xe2\x16\x97\x69\xa3\xf5\xdf\xee\x1a\x63\xe9\x87\xa6\x3e\xbd\x91\xe5\x88\x80\xda\x0d\x40\xaa\xcd\x1e\x0d\xee\xb9\xee\xf5\x9b\xc0\x4f\x12\x8f\x04\x05\x0a\xfc\xd9\x3c\x00\x79\x25\xba\x43\x29\x32\xe7\x29\xd4\x06\x77\xdb\x8f\xd2\xc9\x06\x81\xcf\x51\x8b\xc8\x89\x98\x99\x1d\x79\x94\xc1\x83\x0f\x81\x11\x16\xaa\x7b\xbc\x60\x3d\x4c\x6f\xc1\x07\x6e\x32\xbb\xcd\xd3\x72\xbb\x23\xa2\x75\xbf\x44\xf8\x22\x48\x69\x5f\x3b\xc2\xcf\x6d\xcf\xc9\x01\x5f\x08\x64\x91\x4b\xfd\xdb\x58\x70\x34\x79\x84\x66\xa9\x13\xab\x6c\x23\x60\x6a\x38\x2c\x9f\x76\xea\xfa\x75\x94\x1e\xa3\x9a\xa9\xdd\x5f\x17\x9d\x12\xc0\xb3\x95\x41\xb5\xf1\xb9\x1b\xee\xc7\x34\x83\x1b\xe7\x51\x4a\xb4\x70\xbc\x22\x17\x83\x2f\x43\x9f\xa6\xe6\xcb\xcf\xf5\xe2\x7e\x6b\x0a\x87\x03\xc2\x3d\xf8\x52\x87\x54\x0b\xdc\x1c\xe1\x50\x2a\xcc\x46\xbf\x5b\xc5\xa1\x48\xdd\x8d\x7d\x2e\xeb\x66\x23\xcb\xee\x18\xa4\xa4\x13\x61\x5e\x61\xcb\xa5\x79\xc8\x8a\xa9\x74\x0c\xf8\x4a\x1b\xec\x7e\x77\xb5\xb7\x59\xd5\x85\x89\x3e\x86\x92\xa8\x61\x83\x25\x2f\xe8\x8e\x45\x49\xe0\x4c\xbd\xda\x45\x68\x09\x75\x26\x6f\x33\xcc\x07\x2a\x97\x9f\xa5\x51\xe3\x09\x80\x49\x88\x7a\x6c\x1e\x84\xd5\xae\xdc\xe8\xe7\xb2\xae\x33\xf1\x59\xe0\xe3\x23\x20\x29\x27\x88\xf3\x85\x7c\x75\x88\x29\x7a\x67\x4b\xcb\xdd\x9b\x8c\x52\x6b\x87\x1b\x5f\x5e\xda\x5f\x22\x5f\xb1\x1e\xf4\xb0\xa7\x88\xd0\xff\x0c\x20\x37\xe0\xeb\x80\x47\xe1\xa0\xb4\xb2\x2d\xca\x0f\x9d\xc3\x9b\x83\x33\xcc\x31\xea\xc1\xd7\xa1\x47\xcc\xe8\x97\xbb\xdf\x3f\xb3\x9b\x9f\x2e\x88\xa9\xfb\x28\x17\xa4\x36\xfb\x58\xfe\x2c\x8b\x4d\x27\xdb\x04\x81\x17\xa4\xa2\x0f\x97\xda\xf9\xf2\x0d\x2a\x25\x61\xac\xb5\x07\x81\x1f\x08\x02\xce\xb9\xdb\xe9\x8a\x56\x73\x65\x19\x08\xfc\x44\x11\x63\x22\x2f\x0f\x56\xb2\xad\xfa\x64\x63\x08\x7c\x19\xd3\x7c\xd5\x59\xa1\xf6\x50\xa8\x7d\x59\xed\x4d\x2a\x83\xd5\xfe\x5c\x5f\x57\x21\xdc\xe7\x94\x4f\xb3\xc8\x6c\x7b\xdf\x8b\x76\x4d\xcd\xb1\x31\x26\x89\xd7\xbd\x7e\x08\x82\x40\x2b\xdb\x31\x5f\x1c\x45\x86\x45\x73\x9f\x1d\x5e\x1b\x2b\x01\x45\x7b\x57\x3d\xfd\x08\x22\xc5\x30\xf7\x4f\x77\xfb\xf5\x11\xab\x03\x16\xf2\xd2\x33\x87\x7f\x2b\x07\xda\xf0\xfd\xee\x10\x30\x69\x9c\x1b\x6a\xf9\x8a\xea\x9c\xa3\xc5\xb7\x4d\xfb\xfa\x0e\x84\x34\xd3\x21\x80\x20\x4c\x3c\xea\xb5\x10\xfd\xc5\x2a\x00\xd8\x43\x91\x2f\xa9\xf5\x40\x8c\xc1\xfd\xf2\x5c\x15\xdf\xfb\x66\xd4\xed\x80\x2b\x34\x39\x65\x14\x1a\x3b\x2d\x63\x5e\x84\xa7\x06\xd5\x5d\xcf\x3f\x83\x20\xd2\x01\xe9\x0d\x19\x37\xaf\x76\x67\x9b\x13\xf4\x1c\x3f\x85\x58\x44\xe4\x4d\xb4\x6e\x5e\xf7\x56\xb0\xab\xbf\xd0\x84\x99\x6a\x42\x9b\x20\x5f\xa0\x68\x6e\xaa\x32\x6b\xd6\x64\x1a\x90\xfd\xf7\x8c\xfb\x55\x79\x3c\x35\xb8\x4f\x27\x53\x2d\x09\x8d\x60\xcc\xc9\x00\x3e\x96\xe7\x79\x7d\x74\x08\x12\x48\x5d\x1d\xf5\xc1\xe8\x51\xac\x0b\x55\x7e\x1c\xe7\x64\xcb\xe7\x27\x5f\x2a\x00\xd1\x01\xef\x21\xff\x51\x56\xb9\x32\x24\xee\x97\xb2\x9d\x80\xbd\x56\xa3\x1f\xd8\x57\x29\xe0\x11\xca\xc0\x86\xac\x56\xd3\x6e\xbc\xe1\x05\x1c\x02\x92\xa7\xa6\x1b\x39\x15\x87\xfd\xfa\x82\x80\xf9\x44\x10\x7c\x7c\xf8\xf5\x97\xee\x4f\x4c\x4b\xb7\xe5\x90\x1b\xc2\xcb\xfa\x79\xc8\x53\x83\x00\x78\xc4\xb9\xcd\x9a\x77\xaf\x59\xbd\x2b\xcd\x1b\x67\x0f\x0b\x99\xd2\x0e\x5f\x92\xe9\xf6\xc0\x7f\xfb\x93\x57\x52\x06\x4c\x0d\x74\xba\x4c\xae\x32\x09\x5c\x03\x19\x18\x1f\x21\x45\x04\x5f\x6a\x91\x4f\x6e\x83\x0c\x19\xb9\x3f\x14\xf8\x61\x22\x24\x6a\x86\x4c\x3a\x47\x6e\x6c\xcc\x95\x6f\x14\x4b\xb2\x3f\xcf\x50\xa0\xf3\xe5\x82\x40\x62\x1c\x19\xda\x99\x39\x8b\x79\x99\x5c\x9e\x12\xa8\x50\x52\x98\xb2\xdf\xdf\x90\x8f\xa4\x51\x5f\x6e\x46\xaa\xb2\xf3\xd3\x47\x81\x69\xac\x3f\xde\x0f\xb7\xc0\x00\x99\x01\x84\x58\xfd\x08\x5d\x56\x47\x13\xd5\xb8\xe3\x60\xfa\x6e\x6d\x24\xb3\x7a\x6d\x43\x8a\xe2\x80\xb7\x16\x83\xe1\x06\xe9\x20\xa5\xc2\x33\xdd\xba\x1f\x88\x6f\xdd\x5b\xa6\x43\x46\x15\x67\x9b\xda\x6d\xac\x0c\x51\xbf\xaa\xec\x10\x8e\x4b\x52\xfb\xed\x3e\xc2\x51\x98\x0a\x4f\x53\x65\xf8\x4e\x70\xfa\xa9\xb4\x1e\x04\x1a\x7d\x82\x2f\x17\x5d\x08\xc5\x3c\xdf\x58\x1c\x8b\x76\x8d\x28\xce\x9d\x01\x70\x77\x3c\x8c\x7c\x7f\x98\xa5\xc0\x11\x9b\x81\x3f\xd7\x90\x46\x3f\xf7\x7f\xee\x34\x18\x50\xa5\xf2\xf7\x0c\xca\x87\xf3\xc3\x79\x78\x3b\x99\x1f\xdb\x0c\x8f\xb8\xe7\x26\x04\x6b\xb3\xae\xfb\x87\xc7\xa7\xf9\xf7\x9a\xf9\x89\x8e\x2d\x6e\x54\x65\x35\xa1\xaf\x4f\x57\xc5\x7d\x60\xbe\x08\xb8\x6b\x33\x19\x21\x63\xda\x89\xe5\xdb\x44\x7a\x09\x98\x2f\x23\x02\xe9\xef\xcb\x13\x16\xed\x9a\x77\x5f\x96\xa7\xee\x02\xa5\x24\x9d\xbb\x6a\xe0\x36\x3d\x1f\x5b\x33\x5f\x45\xb4\x32\x1d\xb3\xa2\xd9\x55\xe7\xba\xf9\x44\x8c\x0d\x58\x10\x87\xa4\xee\xf9\x88\xe7\x1c\x1c\xcf\x0f\x58\x00\xa9\xb6\xa2\xd1\xb5\x29\x2d\xcc\x2e\xab\x2c\x90\x3c\x22\x54\xe1\xc3\xf3\xee\x8f\xfd\xf3\xf7\xe5\xfd\x66\xb5\xff\x75\xfd\xc7\xde\xf5\x6e\x81\xb1\x38\x01\x83\xc3\x7c\x7f\x80\x76\xad\x5a\x1c\xbb\xaf\x61\x89\x24\x1d\x45\xd1\x66\x30\x86\xc9\xfb\xad\xcc\xd5\x5c\xd1\x8a\x31\xa5\x02\xc3\x24\x7d\xc7\xbc\x3c\x61\xb5\x77\xca\x58\xfb\xd3\x48\x54\x72\xf2\x0b\x43\xdf\x60\x25\x24\x34\xf5\x00\x2c\x61\x38\x56\xee\x42\xc2\x54\x11\x35\xe0\xf6\x2c\xdf\xd6\x2f\xe6\x05\x66\xcc\x1d\x8d\x82\x98\x8a\x58\x72\x68\x79\xf5\xff\xd1\xea\xea\x0a\x2c\x0d\x2c\xe2\x26\x4c\x5a\x17\x2a\xec\xbe\x4a\x69\xaa\x3a\x9b\x86\xec\x40\xa9\x00\x58\x84\xa9\x37\x82\xfe\x18\xc4\x89\x3b\x1c\x87\xc0\x1d\x8e\x81\xfa\x8b\x8e\xf1\xfb\x89\x9f\xca\x30\xec\x62\x31\x28\x9a\xa2\x1d\x8e\xf4\xc5\x92\xfa\xcc\x4a\x4e\x6b\xf0\x3f\x00\xa4\x02\x4b\x99\x41\xbe\x1d\xcb\xa2\x79\x65\x9e\x4d\x17\xba\xad\x96\x71\x3f\x34\xf6\x2d\x85\xda\xc8\x72\x60\x0b\x0f\x4c\x30\x18\xfa\x29\xb9\xcb\x9e\xdc\x67\xe7\x03\x09\x4c\x70\x23\xec\x67\x38\xf6\xf3\xf3\x53\xa8\x48\xe9\x81\x93\xdb\xd7\x51\x02\x93\x41\xea\xc3\x50\xd5\xbe\x99\x6a\xf8\x03\x53\x41\x6a\xcd\x29\xda\x20\xc2\x3e\x83\x61\x76\xc5\x54\xe8\xd3\x8c\x6b\x93\xc8\x4d\xbd\x6d\x20\xb7\xdd\xed\xd0\x0d\x88\xbc\x14\xba\x53\x94\xdd\x23\x54\x09\x3a\x2e\xe9\xa0\x5a\xd1\x1d\x4d\x39\xe9\x99\xbd\x9b\x8d\x9a\x76\x32\xcb\x36\xce\xfa\x69\x80\x02\xb0\xd3\x05\x2c\x74\x76\x58\x96\xe5\x98\x63\x0c\x4c\xfb\x06\xfc\xa0\xf0\xfd\x16\x71\x52\x03\x65\x3a\x96\x94\x52\xfe\x59\x66\xc5\x5d\x55\x9e\x4f\x0b\xe7\x46\xfc\xcb\x5c\x01\x2d\xf4\x62\xcb\x4c\x72\xf3\x72\x57\xde\xb6\x8f\x75\x76\x82\x84\x1e\xe7\x44\xb4\x21\x3f\xca\xf3\xf1\x39\x3b\xd0\x24\x27\xbb\xfd\x5f\xdc\x18\x69\xe4\x9c\x16\x2f\xab\x6f\xeb\xdd\x1f\xcf\x8b\xfb\x51\x5d\x2c\xf4\x43\x11\x58\xad\xfc\x1d\xfc\x9c\x51\x93\x86\xd0\x17\xa6\x41\xa6\x4a\x93\x16\x7f\x16\xd5\xcc\xae\x9f\x61\x10\xfa\xa9\xe8\x4c\xc5\x8e\xa4\x6e\x30\x4a\x4e\xc3\x36\x22\x6b\x97\xfe\xc5\xea\xfe\x8f\x1b\x99\xa9\x01\xd1\x08\x42\x16\x99\x8e\x89\x31\xc7\xb7\x68\x32\x33\x53\xea\x6e\x4c\x9c\x10\x6c\xf0\xa3\x5d\xfa\x46\x6a\x32\x10\x32\x8e\x14\x97\x0d\xa0\xd3\x2f\xf0\xe1\x54\x40\x3f\xb9\xf4\x71\x5d\xa9\x8f\xf2\x43\x26\x3c\x02\xcf\x3f\xbf\x6c\x7e\x5b\xec\xd6\x7b\x2b\x2f\xbe\xeb\x2a\x28\x21\x13\x09\x75\xb2\xcf\xc5\x2b\xe4\xcd\x0d\xf1\x0c\x07\x8a\xcd\x10\x86\x29\x4b\xac\xac\x5a\xbb\x25\xae\x8f\x90\x8d\x50\xb9\x10\x46\xa1\x22\xe0\xee\x8f\xb2\x50\x58\xdd\x94\x87\x59\xb4\xc6\x79\x4a\x5a\x84\x30\xf6\xb9\xb3\x17\xa1\xcc\x77\x84\xbb\x85\x30\x66\x8c\x76\xb2\xed\x2b\x01\x82\xff\xf1\x59\x59\x48\x26\xc4\x86\x66\x9f\x63\x5d\xf7\xb0\xa5\xf1\xa3\x8e\x95\xd1\xc2\xdd\x2d\x56\x4f\x5b\xf7\xad\x89\xa7\x08\x17\xfe\x5e\x36\x04\x62\x34\x3a\x96\xd3\x1b\x3f\xb8\xc7\x09\x8f\x05\xef\x34\x13\x37\xfa\xc5\x38\x21\x59\xf6\xe9\x43\x56\x2c\x0a\x75\x93\x75\xbf\x2a\x91\x82\xf6\x32\xca\x8c\x1c\xdc\xcc\x1e\x4b\x63\x49\x84\xab\x63\x69\xa9\xa3\xee\x00\xf7\x44\x6a\x55\xaa\xb1\xc2\xf3\xf1\xb6\xac\xde\x16\x95\xc8\x3a\x85\x11\x08\x39\x48\xd2\xc7\x80\x3c\xdf\x4a\x38\xd6\x4e\x8f\xd8\x1e\x86\xc0\x10\x82\x4d\x23\x63\x5e\xf5\x09\x42\x88\x81\xa6\xf6\x7d\x79\xe8\x4c\x63\xc7\x77\xdc\x0d\xd4\x5e\x40\x78\x8d\xb2\xd0\x58\x61\x21\x71\x45\xc2\x18\x8e\xc6\xda\x0d\x93\xd6\x1d\x8a\x4a\xcf\xf3\xda\x1e\x10\x8a\xd0\x00\x65\x88\x3a\xb4\xb7\x7d\x8d\x19\x48\x0d\x84\x82\x2b\x89\xbd\x9b\xd4\x12\x9b\xa1\x60\x13\x84\x02\x52\xb4\x00\x8e\xa7\x73\x43\xea\xb2\x83\x6d\x37\x94\x21\x23\xa6\x8d\x85\xe0\x52\xb8\xf7\x59\xcd\xc6\x7d\x44\x06\x14\xe8\x19\xfa\xe9\x33\x5c\x8e\x83\xb7\x55\xca\x84\xbe\x4e\x65\xef\xef\x97\xbf\x3b\x11\x06\xa6\xe0\xd4\xae\x0c\xc3\x47\xa3\xb4\x24\x91\x29\x81\xc5\xb8\x11\x17\x62\xac\xd0\x36\x01\xda\xd9\xf0\xa4\xdb\x94\x8a\x5c\x19\x46\x31\x72\x88\x3a\xf2\x4d\xdf\x94\xb2\x97\x36\xad\xfa\xbb\x3e\xfe\xe8\xd2\x50\x43\x64\x8c\xc3\x0a\xac\x5f\x2b\xf8\x73\xb4\xe4\x6a\x2f\x35\x72\xbb\x39\x42\xf5\x5b\x99\x9f\x8f\xe8\xfc\x8c\xdc\x15\x44\x1e\x0b\x03\xab\x84\xf1\x0e\x0d\x0e\x94\xfe\xed\x00\x9f\xc5\xd0\xb1\xc3\x4c\x2d\x60\x8b\x4d\x43\x92\xb5\xb3\x93\x22\xf2\x23\x49\xa9\xcf\xe9\x50\x9a\xac\x0c\x95\x21\xeb\x66\xcd\x65\x72\x6e\xc9\xc2\xde\x12\xf3\xbe\x84\xe2\x49\x6b\xac\x06\x19\xed\xbf\x79\x9f\x11\x24\xff\xb1\xcd\xa0\x7f\x87\xff\xf9\x9f\x6b\xbb\x2c\x88\x02\xcf\xa8\xdf\x99\x25\xbc\xea\xa2\xf0\x88\xc5\xb1\xf4\x3b\x85\x49\xb3\x29\x04\x30\x1f\x62\xd9\x8f\xc4\x10\x1a\x33\x4b\x0a\x70\x6d\x5e\x68\x62\xe1\xf1\x62\x14\x25\x89\x4f\xe8\xf7\xad\x29\x25\x3f\xfc\xba\x19\xef\xcd\x51\xa2\x8c\x05\xc8\xfa\x98\x0d\x59\xd2\x10\xa5\x7e\xa4\xa3\x8e\x06\x43\x8a\x59\xdf\xeb\xab\xf3\xa7\x21\x62\x3c\x12\x63\xfc\x57\x79\x14\x19\x7e\xf4\x8e\x14\xbe\xfb\xaa\x54\xc6\xa4\xdc\xb2\xfe\xbe\xbd\xe9\xbe\x45\x72\x52\x96\x70\x72\xda\x2f\x7d\x85\x3c\x4a\x25\xd0\xda\x73\xd3\xee\x31\x9e\xbf\xff\xdf\xef\x8f\xfb\xc0\xf3\x53\x77\x9c\x33\x8f\x28\x66\x87\xec\x1d\x7f\x85\xea\x08\x5f\x75\xfc\x22\x1e\xc5\xc9\x08\xe9\x33\x1b\xbe\xba\x88\x26\xe2\x31\x50\x84\xbe\x5e\x3a\x2d\xd0\x36\x67\x96\xd4\x59\xfb\xa8\xa6\x45\xc2\x88\x73\x29\x98\x7b\xba\x8b\x5e\xe7\x1f\x22\x0e\x46\xa9\xe7\xce\x89\xe4\xed\x6f\xab\xf2\x38\xf4\xf0\x1d\xc6\xcd\x11\xf8\x46\x2c\x41\x96\x59\xa1\xaa\xf2\x54\x8f\xde\xc9\x08\x02\xe3\xd6\xd9\xe6\x61\xf0\xd3\xfd\x55\x04\x40\xdd\x4c\x2b\x61\x66\x43\xc8\xf1\x15\x8a\x28\xa6\xb7\xf9\x70\x86\x4a\x65\x50\xf8\x54\xc3\xb3\x07\x65\xe0\x91\xaa\xdd\x03\xca\x6d\x03\x85\x82\x4a\xfd\xc3\x8d\x31\x92\x2c\x20\xf3\x10\x5d\x92\x53\x57\x3d\x94\xba\x81\x88\xb6\x3e\x43\x2e\x74\x7e\x4f\xa3\xcb\x8a\x3d\x34\x36\x16\x7f\x9c\xeb\xb3\x35\x87\x6c\xff\x98\x70\x53\x07\xc3\xcd\xea\xc9\x34\xd7\xec\x21\x3f\x88\xc2\xc8\xb1\xce\xab\xaa\xfc\xe8\x84\x96\x3e\xe1\x9f\xda\xcf\x05\x3a\x20\x37\x70\x93\x06\xed\x10\x8e\x0b\xab\x9f\x69\x83\xf2\xf1\x8d\x8e\x59\x6c\x4c\x15\x6a\x6c\x1e\xb3\xe2\x4f\x98\xe5\xb7\x43\xcc\x24\x52\x0a\x0d\x79\x5e\x7e\x4c\x60\xde\x83\xed\x3c\x0e\x41\x51\xcb\x85\xe6\x47\xfb\x1e\x39\x7a\x5a\x97\xc8\xc4\x21\x98\x66\x51\x9b\xa5\x2f\x33\xe5\x0a\x95\x7f\xbb\xe6\xda\x34\x70\xf0\x5d\xda\x5c\x3a\xd9\x02\x8f\x2b\xae\x7f\x17\xb4\xce\x26\x31\x71\xe4\xb1\x24\x1d\xc8\xfc\x6d\x6e\x5e\xd0\xa4\x8b\xcd\xeb\xee\xe7\x38\x15\x88\x23\xcf\x08\xd9\x12\x0c\x78\x57\x3a\x69\x9d\xed\x07\x9c\x9e\xc8\xe9\xe4\x9f\xca\x15\xd8\xf3\xc5\x2c\xa6\x7a\x42\x79\x32\xf8\xfd\x6a\x9d\xc3\xa9\xee\x6f\x5b\x1c\x19\x9c\x5f\x56\x3b\xd5\x92\xc9\x23\x8a\x39\xd8\xdc\xa8\xd9\x9d\x6b\xf5\x62\xc0\x42\x97\xc9\xa8\x24\x60\xd2\xb8\xfc\xab\x87\xc2\x6d\xfc\x71\xea\x79\x04\x59\x26\x98\xb5\xd5\x69\xae\x0d\xf3\x15\xfb\x41\xbe\x61\x73\x7f\x60\xf6\x83\x8c\xf7\x9e\xba\x89\x9c\x06\x06\x1b\xf6\x5b\x36\x64\x7a\x42\xcc\xa3\x88\x9e\x35\x85\x6b\xae\x00\xf6\xbd\xa8\x4f\x6d\x62\x30\x34\xec\x83\x18\x42\x8e\xf6\xf2\x97\x56\x77\xa6\x9e\x80\xcf\x21\x16\x3e\x4b\x2c\xdf\x82\xf2\x86\xed\xd3\xbd\x5b\x62\x63\x81\x9c\xe0\x4f\x6d\x92\x77\xec\x98\x1b\x93\xd7\x50\xfa\x41\x64\x13\xa0\xdb\xed\xee\xd7\x15\xb6\xb3\x3d\x9f\xdc\x23\xc9\x93\xc8\x1b\xe4\xf4\xbb\xd2\x64\x71\xfd\xad\x90\xe0\xa7\xd6\xf4\x75\x71\xb0\xae\xc0\xed\xce\x41\x32\x18\xb3\x01\x4c\x2c\x65\x8c\x86\xa3\xd1\xae\x8e\x66\xd9\xb1\x49\x7e\x97\xc7\xc6\x0a\x31\xb5\xe0\xc2\x5f\x71\x5e\x93\x1a\x62\xd4\x81\x46\xcb\x0a\x26\xf8\x8a\xfb\xb4\xf6\x12\xda\x28\xda\x17\x62\x55\x1e\x4f\xed\x4a\x75\xe5\x5e\xfd\x65\x75\x3a\xd6\xbe\xa4\x0e\x01\x69\x35\x95\x15\x21\xee\xbb\xd3\xc7\x09\x71\xe2\xb6\x59\x71\x38\xe7\x44\x80\xdc\x61\x1d\xc4\xdd\xf1\x44\x53\x42\xd2\xde\x94\x3c\x27\x90\xf0\xf6\x15\xbe\x41\xfd\xda\x75\x20\x12\xcf\xf3\x54\x3c\x42\xab\x8e\xde\xaa\xc4\x13\x21\x19\x09\x9e\x90\x16\xd1\x81\x90\x44\x7b\x4c\x51\x78\x0d\x4d\x03\xf2\x6d\x97\x11\x4d\x8a\x38\x77\x59\x71\xa0\x3d\xfb\xdc\x3b\x14\xcf\xe4\x73\x49\x10\x83\x14\xae\x17\x60\xe6\xf6\x95\xc7\x3c\x24\x41\x62\x34\xb3\xcc\xfb\x4c\xd4\xbf\x01\x76\xdb\x4d\xc5\x24\x50\x9c\x9a\x4d\xdb\xf5\xa3\x51\x8b\x5f\xef\xbe\xed\x97\x8b\xed\x7a\xff\xb2\x70\xa2\xf1\x90\xb0\x44\x44\x4e\x1d\xc3\xf4\x42\x42\xd7\x09\x4d\x42\x16\x70\xe9\x56\x90\xbe\xc2\xf6\x5c\x19\xf0\x44\x37\x2c\x65\xee\xbd\x1e\x9a\x99\x4c\x9a\xf4\x49\x14\x31\x72\x3d\x7d\x87\x73\xde\x90\x34\x64\x17\xe2\x25\x91\x62\xbe\x29\xb0\x3b\x1f\xce\xc9\x6d\x8f\x3d\xd3\x90\x79\x7b\xdb\xac\x9e\x76\x58\x37\xa9\xf7\x4b\x77\x48\xe9\xb4\x17\x83\xf7\xf7\xef\xe5\x47\xf7\x38\x63\x8e\x03\xbb\x37\xca\x7c\x8d\x79\xd3\xe0\xae\xc7\xc0\xe8\xbd\x7c\x80\xd7\x3f\xcb\xe2\xd0\x6b\x6d\x42\x92\x78\x10\x4a\xd7\x4d\xff\x20\x50\xe6\xa6\xae\xcf\xf8\xb5\x73\x30\x24\x09\x53\x04\x88\x14\x79\xc7\x55\x80\x24\x51\x1e\x95\xa0\xc4\xf9\x62\xcd\xb8\x56\xaf\x53\xd0\x3d\x24\xa9\x27\xa8\xf6\x5f\xbe\x63\x95\x97\xa0\x50\x3d\x60\xf3\x5a\x7e\x49\x4b\x85\x24\x0d\x22\xa3\x9d\x7a\xae\xaa\x7d\x31\xcc\x99\x92\x34\x4a\x29\x7e\x34\xf6\x0e\x7b\x43\x72\x1a\xba\xa9\xbb\x71\x09\x53\xb6\xef\xdd\xce\x04\x28\x5c\x0d\x3f\xe1\xa1\xb1\x54\x95\x65\x51\x93\x53\xc7\x0f\x84\x93\xa5\xb4\x6f\xd4\x6d\x59\x8d\xe3\x9c\xc9\xbd\xe0\xca\x50\xb3\xf0\xbf\x67\xc8\xaf\xc0\xeb\xa3\x5f\xc1\x35\x63\x46\x90\x21\xfb\xef\x19\x0b\xac\x6b\xd3\xfd\xb2\x87\xc1\xf3\xc3\xc0\x79\xb2\x1d\xa1\x7a\xf3\x47\x95\x8a\x04\x12\x9f\xd2\x68\x22\x44\xf5\xcc\x4e\xe1\x3e\x2f\x22\x45\x5c\xa3\x13\xca\x73\x91\x95\x16\x02\x3e\x2c\x4a\x24\x32\x30\x98\xc7\xbc\x2c\xdf\xce\x27\x92\xda\xbb\xc1\x06\xb2\xbc\x9e\xd4\xd2\x12\x09\x42\xa9\x8e\xd9\x63\xad\x71\x06\x5d\x8b\xf1\x3b\x2b\x11\x88\x59\x5f\x37\xe5\xe9\x85\xe0\xaf\xdd\x14\xd5\xa1\xa2\xaa\x63\x95\x1d\x5e\x1b\x9f\x4d\xbe\x46\x47\x8c\x40\x90\x27\x53\x47\x7a\xd2\x77\x65\x07\xa8\x49\x74\x62\x44\xf6\x1d\xfd\xd6\x0a\x9d\x4c\x4f\xc1\x83\xd0\x49\x7b\x41\xf1\xe6\xb9\xb8\x3d\xf5\xfc\x94\x30\x6d\x8b\xf7\x0c\x56\x9e\x5f\x74\x7f\x67\xc6\x2b\x88\x6a\xf7\x06\xea\xb6\x2b\xdb\x48\x6d\x76\xad\x66\x81\x7b\xc5\x53\xdf\x4f\x85\x11\x18\x3b\xd7\x0d\xbd\x47\xa3\xbb\x90\x06\x31\xa7\x89\x64\x09\x25\x5f\xd9\x81\x43\x1a\x68\xa0\x8c\xc9\x76\x2f\xb7\xb6\x93\xbd\x32\x4c\x39\xbc\x52\xfc\xf8\x47\x98\x76\x48\x19\x28\x82\xf7\xde\x94\xbb\x51\x47\xfc\xef\x8a\xfc\xe3\x8b\x0b\x03\x24\x07\x54\xd3\xfa\x6f\xef\xcd\xf8\xa6\xa7\x61\x1c\x53\xa1\xf0\x7e\xf9\x7f\x5f\x65\x43\x69\x08\x46\x3f\xef\x88\xed\x3b\x6b\x76\xcb\xc9\x99\x84\xc6\x5e\x1b\x65\x26\xa6\x4d\x23\x3f\x4d\x23\xb3\xb0\x98\x92\xe8\xf0\x98\x30\xfa\xa1\x16\xe2\xed\x3e\xfd\x55\x8d\x34\x8d\x84\x11\x9f\xb9\x41\x50\xa7\xb2\xcc\x83\x97\x76\x5e\x15\x65\x75\x5b\xa1\x93\xc0\x80\x34\x92\x09\x74\x25\x6d\xa3\xb4\xbf\x3d\xd1\x42\x70\x4d\x83\x81\x34\x66\x48\x0d\xe0\xff\x2d\xab\xc3\x28\x04\x4b\x13\xcf\x73\xf2\x55\x2f\x58\xc0\x91\x76\xd5\x29\x4d\x1d\xd2\xc4\x37\xe0\xc0\xfb\xa7\x1f\x7b\x32\xf3\x1f\x6e\x63\x69\xe2\x47\x81\xe8\x10\xe8\xbd\xc6\xc6\xe4\x1c\x3c\x66\xdd\x66\xd7\xd5\x40\xd3\x04\xbc\x01\x71\x60\xd3\xe0\xb1\x9e\x86\x77\xd3\x86\x63\x9a\x06\x61\xdc\x21\x88\x86\x78\xe4\xb4\xbd\x7d\xed\xd3\xf8\xfe\x78\xb3\x7e\xf9\xb1\xf8\x63\xbf\xdd\x2d\x76\xdf\x5d\x01\x32\xe5\x32\x26\x72\x19\xb5\x09\x57\x83\xda\x78\x0a\x1e\x90\x94\xf6\x73\x5e\x36\x3b\xac\x2a\x70\x95\x94\xcf\x5a\x1b\xf3\xb0\xa3\x14\x7c\xa0\x8d\xd6\xac\xf4\xdd\xd9\x43\x46\x3d\xa6\x7f\x65\x87\x6c\xb0\xc5\xa5\x10\xc7\x84\x8b\x06\x51\x97\xf9\xb9\xc1\x07\x63\xaf\x79\xdf\xb7\xa7\x52\x10\xc6\x6c\xef\xf7\xf5\x6f\xdd\x9f\xa4\xa0\x69\xb5\xef\x43\xd0\xab\xc5\x61\x36\xcc\x4c\x41\xa7\x94\x96\xd4\xe7\xa3\x51\x4d\xf3\xdd\x39\x85\xc7\xa4\x51\xe3\x28\xb0\xba\x3b\xb7\x2b\xc3\x3f\xca\x4c\x52\xc1\x90\x5b\x68\xfc\x6d\x0e\x87\xf9\x67\x2f\xc2\x98\x96\x59\xb3\x0d\xde\x43\xdd\x6c\x65\x59\x19\xfc\xc9\x64\x99\x12\x91\x04\x66\x90\xfd\xf6\x37\x91\xbf\x47\x97\xea\xa4\x22\x61\xd4\x7b\xea\xdc\x67\x57\x0e\x6e\xef\x04\x6e\x1f\xb2\xb1\xc5\x5f\x3a\xcb\xaa\xb0\xa7\x93\xbe\xf1\x48\xcb\xea\xa5\x29\x84\xcd\xd1\x94\x21\x55\xbe\xc7\x86\xa2\x4d\x6d\x1e\xbf\x2b\x3f\x19\x2b\x53\xe5\xd9\x30\xd6\x28\xfd\x9e\xaf\x21\x59\x29\xa6\x21\x55\xed\x1c\xae\xd3\x40\xab\x67\x28\x1e\x90\xa2\x08\x85\x89\x68\x4a\xf9\x96\x15\x07\x27\x53\xe2\x6e\x09\x22\xa6\xc9\x00\x99\x47\x75\xc2\xf5\x4f\x0a\xbb\xae\xd4\xe8\x21\x45\x1d\xf9\x03\xb3\xda\x2d\x1c\x71\x2c\x00\x37\x91\x3c\x6a\x3f\x61\x40\x5a\x07\x6c\x96\x84\x75\x73\xdf\xac\xe3\x98\x9a\x8b\xc7\xac\x68\x88\xe6\xad\x33\xb9\x82\x89\x8e\xc7\xe4\x96\x73\x8f\xc9\x24\xed\xac\xd3\x8c\x5d\xdf\x2f\x93\x21\x11\x23\x9e\xea\xbd\x01\x90\xad\xe0\xf4\x82\xd0\x6e\x42\xd3\x71\xa0\x08\x20\x7b\xbb\xf8\xee\x0a\x54\xdc\x47\x49\x8d\x99\x9d\x8d\x9c\x89\xd5\xfe\x37\x41\x23\xf7\x75\x2a\x8d\x61\x46\xf9\xf1\x70\x99\x89\x4e\x78\xe0\x09\x5a\xe5\x04\x36\xdb\xf3\xf1\xd8\x59\x43\x02\x0f\x94\x32\x3d\xa7\x36\x85\x85\x8f\xc9\x25\x32\x8b\xf5\x73\xc8\xb9\x7d\xf3\xa9\xc6\x2c\x70\x16\x07\x94\x37\x1c\xe1\x67\x3b\x8b\x6d\xf2\xe8\xbe\x88\x01\x0b\xc2\x01\xe2\x01\x69\xcb\x32\x78\x2d\xa3\x96\xed\x46\x86\x7e\x44\x0a\x67\xb4\xcd\x5a\x83\x93\xff\xb7\xdd\x96\x87\x32\xa6\x05\xa8\x17\x7c\xfa\x7a\xb2\xf0\x10\x81\x52\xa4\x55\x0f\x8e\x5e\x5e\x16\x43\xa3\xbd\xb9\x28\x9a\x47\x18\x92\x68\xe8\x92\xe4\xc0\x48\x22\xd7\x11\xb0\x80\xc7\xbe\x32\xb6\x9f\x68\xb0\x09\xe6\xd9\x52\x9b\x76\x70\x1d\x57\xa0\x4b\xf7\x69\x06\x81\x7b\xd5\x8a\x55\x59\x1c\xaa\xb9\xf5\x6d\xf4\x23\x12\x2f\x01\x4b\x8d\x5f\xc1\xa9\x81\xac\xb0\xde\x6c\x43\xfb\x6d\x37\x36\x8c\xe9\x07\xdf\x3e\xee\x3e\x75\x7d\xfd\xdb\x7f\x3f\x7b\x28\xe3\x87\x91\x32\x4d\x56\x3d\x8b\x5c\xc3\x60\x23\xe1\x69\xe4\x11\xd6\x6a\xd9\x5e\x5d\x86\x35\x19\x26\xfe\x6d\x94\xe6\x3e\x9c\x86\x44\x7b\x72\x33\x34\xe8\xce\x9a\x22\x79\x66\x1e\xb3\x02\x7d\xcf\xf3\x26\x33\x3b\x55\x66\xe9\xaf\xce\x85\xeb\xc6\x8e\x7b\x38\x3c\xc5\x88\xb8\x09\xa7\xaa\xfc\x79\x71\xc5\xbe\xdb\xaa\x3c\xee\xca\xcd\x6a\xf1\xfc\x23\x6b\x5e\x29\xd7\xc6\x62\x2a\x21\x34\x40\x80\x8c\x66\x49\xaa\xa5\xe6\x2e\x2d\xbe\x2d\x2b\xfa\xc1\xdd\x9b\xc8\x63\x4f\xa5\x43\x7d\xcb\x06\xaf\x75\xa5\xba\x69\xc1\x63\x49\x29\xb6\xd5\xbf\xb6\xc2\xe8\x46\xc3\x64\x02\x66\xe3\xdc\x8a\x8d\x0e\x6c\x3a\x07\x55\x7a\x0e\x0c\x09\x90\xbe\xb8\xfd\x31\x8c\xaf\x38\x48\x03\x32\xc7\x63\xd6\xb8\x22\xe0\x2d\xa2\x09\x2d\xa6\x8b\x19\x60\x12\x58\x3a\xe3\x73\x59\xcf\x55\xa8\x78\xbb\x11\x44\x34\x93\xa1\x52\xfd\xd7\x88\xd8\x34\x01\xc4\xb9\xa2\x00\xc2\xaa\xf7\xdb\xa3\x32\x48\x0d\x01\xdc\x40\xce\xee\x0c\x14\x48\x0e\xd0\x67\xdd\x48\x26\xa8\x80\x9f\xc9\x32\xd8\x13\x06\x5c\x0d\x7e\xa4\x4c\x31\xb6\x5a\x9d\xdb\x23\x54\xcd\x95\x55\x7e\x77\x67\x25\x1a\x7d\x8b\x81\xf2\xe5\xb0\x57\xc8\xd1\xf7\x28\xb1\x32\x9a\x4b\xb6\x18\x09\x5d\x39\xf8\x8a\x01\x33\xbe\x09\xc8\x92\x60\x08\xed\xde\x1c\x4f\xf3\xca\xfb\xc0\x51\xa4\x91\x2d\x94\xff\xb8\x7f\x98\xf1\x39\x02\xae\x3d\x49\x65\x06\x42\xdd\x43\x1e\x78\xbd\x59\x1e\x70\x1d\xf2\xd8\xb9\xb3\x66\xc5\x88\xe0\xe2\x46\x40\x42\x23\x0a\xfc\xf8\x81\x59\x5f\x83\xf9\xf4\xdd\xeb\xf3\x03\xf0\x30\x89\xa9\xa0\x77\x6e\xca\x23\x34\x99\x74\x45\x50\xc2\xa7\xcd\xbe\xac\xe0\x6b\xae\x0d\x18\xf0\xbf\x14\x6c\xdf\xb7\xff\x2d\x06\xfd\x38\x3b\x2e\x88\xb5\x37\xbc\x49\x90\xef\xa9\xb8\xf8\x8b\x3b\x2e\x02\x32\xba\x7c\xcb\xc6\x4a\x60\x00\x81\x36\x96\xe7\x4b\xcc\xcb\xa6\x21\xc5\x99\xc9\xb9\x59\xc2\x78\xef\xcc\xff\xcb\x00\x82\x65\x29\xae\x73\xff\x71\x9f\x4d\x03\x13\x68\xd6\x76\x83\x73\x32\x21\xe3\xaf\x08\x3d\x43\xd8\x35\xc5\x9f\x2e\x16\x1c\x37\x71\x21\xf4\x92\xc4\x36\xf6\x36\xab\xa7\x67\x82\x22\xfd\xc3\x8c\x74\x72\x5b\xc3\x00\x0c\x5d\xad\xc6\x66\x5b\xc0\xa9\x7e\x2d\x1b\xca\xe7\x26\xba\x4f\x5f\xc6\xd7\x10\x26\x8a\x5a\x50\x2f\x99\x7c\x6b\x03\xd1\xb2\x6a\x2e\xdb\xd7\x2a\x3b\x9e\xba\xad\x19\x22\x2e\x93\xb0\x33\xdb\xd8\xbe\x66\xa7\xd3\xa0\x21\x34\x5a\xed\x20\xf6\x95\xec\xab\x8d\x5f\xc9\x8f\x8c\x24\xf0\xae\xf5\xf0\xda\x53\x21\x45\x6a\x4b\x38\x9c\x40\xbe\x65\xb2\x1c\x2e\x54\x10\x87\x86\x6d\x43\x8d\xaf\xac\x38\x8c\xdd\xd0\xfe\xee\x9e\x8e\x2e\x3a\xc5\x98\x16\xe1\xfb\x4c\xe3\x2d\xc8\xa6\xac\xf6\x59\xe6\x78\x66\xc0\xe3\xd4\xc0\x9a\xf2\xb2\xc6\x65\x57\x85\x04\x2e\x38\x41\x4b\x3a\xce\xc8\x1e\xba\x24\x08\x40\xa5\x68\xd8\x32\xed\x94\x27\x3b\xac\xf1\x74\x11\xca\x8b\x70\xa0\xb9\xb0\xfd\x80\xea\x48\xf6\x3e\xb3\x04\x05\x90\x49\x42\xdf\x46\x10\x47\xfa\xc4\x0f\xcc\xac\x90\x74\x3f\xc4\xb4\x1c\x08\x6a\xbd\x97\xce\x16\x0f\x40\xca\x24\xea\x7b\xe2\xdf\x88\x5c\x34\x01\xf7\xdb\x91\x18\xc6\x46\x96\x2a\x47\xa8\x48\x00\xb9\x1e\x85\x0e\xa0\x83\xd0\x98\x93\xbb\xdc\x79\x35\xd0\x03\x9e\x07\xdf\x81\x4e\x53\xd7\x2a\xdf\x61\x8e\xa7\xb2\x5f\x89\x67\xe9\x74\xa0\xb5\x79\x5d\x2d\xd4\xc1\xcd\x36\x47\x66\x11\x5e\xa2\xa8\xb4\x77\x87\xcd\x0d\x5c\x56\x57\x86\x8b\x20\xfc\xc8\x4b\xed\x32\x4a\x6a\x90\x7c\xb4\x62\x08\x3f\x35\xac\xa1\xff\xbd\x5f\x0d\x27\x95\x08\x02\xc3\x18\x7a\x7e\x59\xef\x37\xab\xa7\xfd\x6e\xb3\x7e\xd9\xdf\x2f\xb6\xbb\x6e\x00\x33\x16\x47\x64\xa9\x00\x0d\x2e\x0a\x75\xd7\xbb\x92\xdd\xe2\x75\xcc\x3a\xfb\xde\x89\x20\x81\x44\x3a\x26\x00\xb1\xcc\x36\xc5\x0b\xdd\x19\xac\x06\x62\x6a\x20\x02\xc5\x5c\xea\x41\x82\x94\x0f\xa5\x1a\x56\x6c\x44\xa8\x0d\x3e\x61\xf7\x6d\xf3\x72\xb3\x7f\x5e\xbc\xec\xfe\xd8\xdf\x3f\xad\x7e\xfd\xfe\xec\xce\x10\x49\x95\xf6\x6b\xdf\xb7\xa7\xc7\xe6\x5a\xf9\x05\x44\x1c\x69\xa2\xb8\xaf\x8f\xa7\xae\x35\x3b\x1d\x93\xa6\x31\x45\xf3\x6d\x52\x67\x4c\x00\xbf\x0c\xd3\x44\xaa\x62\x0a\xd3\xba\x1e\xfa\x62\xfa\x98\x38\x8a\x40\x59\xa5\xbb\xbb\x0a\x4e\x5d\x67\x45\x08\x29\xa8\xb5\x4d\x7b\xfa\x46\x96\xff\x8c\x1f\x21\x64\x2a\x8c\x42\x16\x14\x4b\x5c\x66\x4a\x61\x31\xf9\x4a\xe5\xfb\xd4\x92\x31\xb2\xc1\x8f\xe7\xe3\x1d\x16\x58\x41\x6f\xe1\xea\xc6\x45\x8a\xca\x9a\xf5\xf9\x84\xd5\x11\xba\x29\xa2\x78\x48\x55\xcb\xa6\xba\x18\x24\x4a\x7f\x00\x69\x6f\x5c\xe6\x20\xdf\x1e\x49\x93\xb0\x3b\xa4\x22\x02\x31\x74\x16\x53\x8b\xcd\x7c\x3a\x25\xd0\xe3\xe0\x0c\xbf\x5d\xa9\x43\x68\x5f\x92\x3b\x68\xe7\xb2\xfc\xd9\x2a\x37\x9a\xe3\x3a\x34\x34\x5b\xc2\x1c\x38\xf7\xc5\xf1\x76\x24\xb4\x36\x96\xe9\x93\xaa\xe9\x8b\x7d\xb7\xff\x5f\xcb\xa6\xd2\x63\x09\xcd\xa6\x26\x43\x27\x33\xed\x8e\x84\xb1\x31\x37\xb9\xbd\x5d\x0e\x5f\x3d\xe9\xfb\xb1\xec\xa7\xe9\xaf\x59\x71\x50\xe5\xf1\x33\xac\xf1\x6c\xec\x24\xfd\x40\x12\xc2\xbc\x6e\x13\x74\x7f\x04\x0c\x90\x3e\x46\xc4\x26\x26\xe7\xce\xfd\x72\xb7\x72\x25\x36\x19\x84\xa6\x0f\xdc\x26\xf7\x50\xe5\x97\x67\xa8\x2c\x97\xb1\xd3\x95\x9c\x29\xa3\xca\x20\x32\x7a\xb3\x23\xe0\x05\x05\x76\x6e\x80\x4e\x49\x84\x8a\x72\x3e\xeb\x67\x33\x7e\xa1\x24\x0b\x8d\x9c\xb1\x89\x3a\x67\xeb\xf1\x92\xa5\x9a\x08\x4b\x7b\xa3\x5a\x43\x52\x84\xe3\x76\x97\x64\x98\x10\x9b\xa6\x81\xea\x80\x8d\x9b\x36\x32\x0c\xb9\xe2\x9d\xb1\xc4\xfc\x84\x93\x61\xe2\x03\x95\xff\x2e\x32\xc7\xfb\x81\x53\x40\x7b\x28\x20\xd9\xef\x53\x1b\x62\xdc\xe0\xfb\x84\x08\x33\x3d\x51\x1a\xd0\x42\x45\x54\x83\xf2\xd6\xc2\x4a\xdc\xb9\x22\x4f\x86\x96\x59\x65\x0d\x7f\x3e\xdf\xf9\x65\xc4\x18\x75\x66\x1d\x7e\x0c\xf3\x3c\x18\xcd\x95\x28\x0c\x62\x5b\xc2\x7b\xfa\x28\x76\xaf\x48\xbb\xc0\x1c\xd2\x43\x46\xa9\x79\xf5\x5c\x19\xec\xe6\xdc\x4e\xa8\x4d\xd1\x46\xce\x04\x0c\xfb\xe4\xbe\x44\x90\xf2\xae\x61\x33\x10\x18\xfd\x65\x06\x24\x26\x23\x10\x03\xcc\xd9\x43\xd9\xbe\x43\x73\x73\x26\xf6\x04\x55\x15\x17\x4a\xed\xe0\x30\xbb\x03\xcb\x38\x96\xca\xa2\x36\x0c\x9a\xb1\x4f\x5a\xec\x88\xd4\x33\x8b\xa6\x89\xb1\x7e\x83\x2a\x6b\xa7\xd6\x27\xb4\x07\x99\x06\x01\xf1\x20\x4f\x15\xbe\x67\xe5\xb9\x36\x96\x11\xc3\x4e\xb4\x4c\xb5\x61\xdd\x1c\xb0\x21\xcb\xc2\xc9\x0c\xe4\x8a\x53\xbe\x01\xef\x58\xc1\x01\xef\xb0\xf0\xda\x27\x38\x50\xae\x03\x09\x09\x78\xf6\x89\x2c\xbb\x6a\xc7\x7c\x8a\x23\x85\x17\xd1\x2f\x24\x05\xbf\x76\x9b\x1d\x71\xc3\xa4\x88\xa5\x37\xf0\x62\xd9\x95\xdb\xb3\xa8\x65\x95\xd1\xad\xb8\xaa\x5d\x4a\x01\xa6\x22\x5d\x63\x63\x27\xdd\x35\xde\x4d\x0a\x19\x10\xf7\xab\xcd\x6a\x7b\x85\xe9\x36\xa3\xbf\x56\x66\xfe\x22\x99\x97\x02\xb9\xec\x79\x01\x37\xe8\x5a\x94\x0e\x2c\x27\x65\x10\x11\x62\x7d\x87\x70\xdc\x8f\x80\x89\x52\x46\xa6\xa1\x5b\x8f\xe2\x05\x2b\x59\xfa\x09\x69\x54\xca\xc8\xf8\xaa\xd7\xa0\x91\xd2\xbc\x2f\x77\x5c\x29\x45\x40\xa8\xb5\xce\xf2\xee\x84\xa6\xf0\x5a\x77\xda\xaa\x93\xf3\x4b\x53\xfd\xaf\x9d\xf9\xfc\x27\xaf\x83\x0a\xfc\xd0\x14\xa4\xa0\xce\x0e\x85\x7d\xbe\x33\x75\x28\xa9\x02\xad\x59\x87\x2d\x9e\x2e\xe0\x9f\x6d\x1f\x83\x97\x44\x61\x20\x85\x2b\x98\x6c\xd4\xf2\xd2\x73\x1a\xfb\x6f\xc1\x30\x1d\xd4\xe7\xf7\x47\x78\xc3\xbd\xb0\x33\x37\x75\x63\x54\x24\xec\xcc\xd8\x96\x9d\x6f\xe7\xf8\x3c\x3a\x51\x84\x46\x78\x58\xfc\xbe\x5f\xff\xfe\xbc\x79\x59\xef\x6f\xd6\xf7\x8b\x3f\xdc\x43\xd3\x22\x49\xc1\x69\x9c\x57\xef\x58\x3d\x5e\xb5\xc2\xa5\x96\x1e\x6d\x3b\x4e\x5c\xb6\xab\xfc\x2b\x8f\x05\xce\x1d\xfc\x31\x93\x6f\x8f\x57\xcd\x03\xe5\x85\x18\x86\xfd\x64\xdf\xd4\xdb\x53\x9e\x35\x57\x80\x50\xe5\xe9\x84\xa8\xb0\x12\x4e\x8e\xb9\xd7\x7d\x8b\x9f\x68\x02\x01\x91\x3b\xdc\x8f\xac\x50\xe5\x07\x5b\x5b\x1f\x6f\x37\xa4\xbd\x17\x83\x86\x97\xab\x7a\x7d\x39\x9b\x54\x00\x86\x15\x7f\xc0\xe6\x3b\xf5\xd8\x3b\x33\x8d\xd1\x23\x19\x4f\x59\x15\x08\xed\x84\xd8\xef\xe0\xd8\x2e\x13\x7f\x4d\xee\x98\x0a\xb4\x00\x67\x2f\xf3\x89\x3b\xc6\x97\xe1\xb3\x62\xe0\x53\xd5\xf9\xff\xfe\xf8\xa4\x5f\x3a\xb9\x26\x26\x03\x92\x43\x22\x6f\x20\xea\xb6\x8c\x2f\xfd\xba\x65\xa7\x42\x6e\xec\x1e\x2c\x0b\xe9\x1e\x75\xd3\xfe\x5b\xf7\x09\x97\x0a\xb9\xef\x7a\x9a\x0f\x50\xbd\x99\x54\x63\x79\xb1\x48\x87\xc9\x94\x55\xa1\x64\x81\xd1\x2b\x37\x95\xc7\x95\xa5\xc9\x4c\x4d\x51\x41\x85\x1a\x28\x44\xdd\x36\x50\x1d\x33\xf5\xc9\x2f\x1c\x4c\x75\x15\x79\x8a\x8a\xbf\x9a\x84\xcb\x0b\xe9\x16\x53\x15\x29\x16\x0d\xab\x80\x57\x4f\xbc\x7f\xf1\x54\xe2\x7b\x14\x81\x19\x7d\xc9\xe1\xba\xa7\x52\x1f\xd3\xd8\xa1\x3d\xce\xd5\x0c\x7f\xea\x53\xf5\x3a\x50\x3c\x32\x48\x69\xa3\xd2\x32\x6f\x9b\x31\x79\xbe\x22\x08\xa9\xa7\xec\x16\xca\x7a\x3d\x12\x2e\x52\x22\x46\xca\x69\x28\x3b\x78\xc9\x9a\x73\x87\x72\x50\x22\xd6\x56\x3c\x98\x04\xbf\x2d\x17\x78\x53\x2c\xcf\xf9\xdb\xb4\xec\xa7\x44\xea\xd1\xce\x47\x80\xbe\x27\xbd\x7a\xcd\xf2\x4f\x56\x40\x25\xa3\x98\xf4\x75\x84\x01\xaa\x4f\x1e\x99\x14\x9a\x5e\x95\x87\xdb\x9d\x34\xd4\x4e\x77\x3d\x2a\xd0\x54\xc6\xe8\xba\x11\x59\x59\xec\x3e\xca\xc9\xfb\xad\x78\x48\x92\xc6\xe7\x5a\xbd\x40\xd6\xe3\x24\x95\xe2\x32\x25\xc6\x01\x88\x61\xfb\x57\x29\x25\x98\x9d\x7b\x2f\x65\x79\x1c\xee\xe7\x4a\xe9\x88\x2a\x7c\x5d\xd8\x62\xdf\x5b\x23\xb3\x36\x6f\x7e\xd2\x7e\xca\x10\x60\xac\x16\xc8\xe6\x08\x07\xdc\x74\xd7\xa1\x7d\xf3\x03\x3b\x5f\x0f\xb3\x5d\xf4\x17\xaa\x43\x03\xd4\xa6\x80\x69\x2b\xcb\xd3\xd5\x3b\xed\x06\x72\x53\x43\x9c\x0a\x54\xce\xf5\x61\xd1\xf3\xa2\xd8\xc2\xd9\x7f\x2b\x1b\xac\x5f\xb0\x3e\xe7\xee\x87\xa2\xcf\x15\x21\x44\xac\x4d\xa0\x31\x24\x70\x07\x99\x0a\x93\xff\x6f\x62\xcb\xf6\x83\x61\x18\x11\xd1\xc2\xd4\x6e\x8a\x52\xe1\x95\xb5\x05\x60\x18\x45\xb1\xad\x69\x0c\xa2\xc3\x25\x19\x11\x4c\x66\x19\x86\xd2\xa7\xb6\x83\x32\x7c\x6f\xb5\xe8\x7e\x40\x68\xad\x1e\x0f\xd8\x3c\x63\x55\x97\x05\xe4\x56\x28\x7d\xde\xe0\xca\x7e\x2c\x82\x38\x50\x43\xef\x35\x54\x03\xa5\x58\xc0\x38\x89\x08\xf6\x48\xb0\xe5\x75\xf3\x6a\x55\xfa\xfb\x7b\x93\x78\xca\x55\x9f\x4e\xb4\x3e\xcf\xce\x79\x4c\x02\x83\x75\x73\xe1\xc4\x12\x7a\x0b\x03\x3b\x24\xf5\x25\xb3\x4a\x99\x96\xce\x3e\xd2\x68\xc0\x34\x4e\x22\xd5\x23\x06\xa1\xb8\x8c\x10\xea\x6e\x14\x30\x15\x3b\xbf\x40\x2a\x87\x8c\xdf\x0f\x4c\xa5\x26\xae\xce\xbf\xb2\xa6\xea\xda\xc8\xc8\x3d\x46\x89\xb1\x69\xdc\x3d\xc3\x65\x28\xbd\xec\xc6\x28\x41\x6f\x96\x95\x9c\xbb\xd9\x2f\xbf\x6f\x37\x8f\xeb\xed\x76\x7f\xf7\xf2\xd4\x55\x49\x10\x02\xa3\x29\x4e\x1d\xeb\x36\xe2\xcc\xd4\x24\x13\x43\x91\x32\xea\x9a\xb5\xf1\xe5\xde\x11\x75\x51\x32\x2d\x53\x17\xef\x14\x4d\x59\xcc\xe3\x99\x51\x26\x06\x53\xec\xd0\x57\xcb\xf3\x45\xf4\x05\x43\x94\x5a\x42\x0f\x3d\x6c\x6f\xf4\x20\xda\xb3\x63\x54\x60\x65\x1a\x7a\x3a\xe0\x8a\x50\x1b\xf9\x0c\xde\x7c\x6e\x1f\x44\x8d\xc6\x19\x10\x94\x32\x0a\x87\x6d\x1a\x32\xa7\x0b\x0d\xda\x63\x9a\x1c\x83\xbb\xfe\x51\x55\x1e\x6f\x3b\xfb\x9a\x5f\xdc\x28\x85\x8a\xf7\x9a\xdf\x86\x81\xbd\xcf\x8a\xfd\x07\xba\x02\xaa\xf6\x63\x66\x08\x21\x5f\x8b\x19\x6a\x3f\x95\x8e\x23\xb0\xdb\x3d\x8c\xca\x15\xa3\x5f\xa1\x03\x3f\xc4\x5e\xab\x6c\xf7\xb3\xd8\xc1\x64\xb3\xd5\x41\xe8\xd1\x1b\xb2\x37\xd2\x8e\x55\xd3\x47\x2c\xae\xc2\xa3\x03\x88\x48\x70\x27\x6b\xf0\xf8\xd8\xc9\x37\x68\xc6\xc1\x3a\xac\x5a\x2b\x74\x23\x15\x31\x3e\x7f\xe8\x27\xe4\x94\x96\x39\x63\x91\x9a\xba\xfe\xed\xe4\xb1\x78\x73\xd3\xe6\xe8\xde\x49\x1d\xfa\x86\x52\x5c\x37\xe5\xe9\xb9\xac\x1a\xc8\xef\xce\x64\x6e\x9c\x75\x93\x40\x87\x21\xa3\x22\xc5\xf6\x7c\xc2\x6a\xad\xba\x86\x98\x0e\x43\x4e\x68\x7a\x63\xd7\x4f\x9c\xc2\xcf\x98\xfc\x3a\xe4\x40\x60\xee\xe2\x7c\x5c\x14\xd9\x11\xf2\xfa\xf7\x81\x10\xa3\x0e\x45\x4c\x68\x14\xb0\x8c\x6c\xf6\x5c\x95\x7f\xa2\x1c\xa9\x49\xe9\x28\x35\xca\x2b\x03\x0a\xf6\x5c\xe2\xab\x23\xce\x92\xa8\x93\x48\xff\x5e\xd4\x65\xae\xb6\xa0\xbb\x2f\x8b\x83\x98\xda\x01\x5b\xbc\x56\x18\x9d\xbf\xfa\x58\x05\x9d\xe9\x6c\x47\x22\xc4\x6d\x36\x98\x73\x09\xb2\x20\xea\x32\x64\x02\x60\xb9\x43\x6d\xb2\xcb\x3a\xd2\x73\xb7\xdf\xd6\xb7\x65\x35\x3f\x95\xd2\x80\x53\x99\x51\x9f\x0b\xd5\x35\xf3\xc6\x57\x94\xc6\xca\xb4\x18\xeb\x2d\xe6\x79\x56\x1c\xb6\x03\x3d\x30\x9d\x8a\x24\xb1\xa5\xea\x45\x9e\x0b\x6c\x96\x97\x76\x2e\x11\x88\xa4\x0f\xd0\x34\x4f\x42\xba\x51\x2a\xab\xdb\x40\x66\x71\x6e\xca\x17\xcc\x0c\x99\xda\x0d\x49\x15\x01\xba\x6e\xd7\xeb\xfd\xf3\xfa\x65\xb5\x76\x2a\xeb\xa0\x39\x0f\x85\x95\x3d\x6c\x5e\xf0\x74\x6e\xc6\x4a\x37\xb3\x9b\x84\xe6\xca\xa7\x22\xba\x15\xb8\x85\x23\x2e\x0a\xb5\xbd\x1c\x45\x99\xcf\x98\x7a\x80\x06\x69\x7c\xa9\x37\xab\x27\x2c\x54\xaf\x00\x0f\x5a\x04\xc2\xfa\x91\x34\x0f\x04\x3c\x24\x9b\xd6\xcb\xe9\x93\x6d\x43\x8b\xc4\x23\x7a\xe9\x11\xfe\x2c\x2b\x42\x09\xb5\xd9\x67\x5f\xf1\x99\x5d\x6f\x24\x37\xed\x14\x5d\x61\xf1\xd7\x65\x42\xb3\xd6\x0a\x83\xd4\xf0\x80\x3e\x2a\x38\xad\xbb\x22\x95\xc6\x08\x69\xdd\x26\x92\x3a\x1c\x89\xdc\xe2\xd6\xa8\xf1\x55\xe9\x50\xd0\x4e\x75\x7b\x2e\x54\xed\xfa\x96\x9f\xc0\x5a\xb4\x16\x4c\x9b\xda\x99\x28\x0b\x35\x3d\x93\x32\xfc\x46\xc2\x32\x1e\xa0\xc8\x6a\x18\xb8\x5a\x09\xcf\x63\x1e\xcd\x98\x67\xb8\x90\x90\xda\x2c\x00\x6f\xf4\x85\xc2\xf3\x78\x4c\x2d\x8d\x23\x9c\x3a\x89\xf6\xd1\x5c\x15\x9e\xa7\x03\x62\xeb\x9f\x9b\x2c\xcf\x9a\xcb\x88\x2e\x2c\x3c\x3f\x8e\x69\x25\xb6\x7f\x9e\xe8\x72\xcd\x3a\x33\x7d\xa2\xc3\xe5\x4e\xa8\x52\x67\x69\xb2\xcc\x46\x56\xe8\xc2\xf3\x75\x48\xcb\xeb\xaf\x4f\x9b\xa7\xad\xd1\x8d\xae\x88\xe7\xf9\x8f\x9b\x99\xe3\x9f\x16\x78\x09\x6d\xe4\xaf\xcf\x70\xa1\x7a\xe9\x36\x3b\xb8\xef\x0a\x24\xf3\x9c\x7d\x73\x1b\xc5\x4c\xf3\x25\xe1\x31\x2f\x8d\x2c\x4b\xdf\x5a\xa4\x57\xa3\x58\x50\x78\x8c\xf9\xca\x00\x70\xc9\xd3\x6e\x72\xeb\x58\xc2\x7d\x41\x9d\xc6\xba\xc1\xe1\x42\x28\x3c\xa6\x84\x51\xc6\x3a\x67\x32\x53\x48\x73\x67\xf2\x58\x18\x32\x92\xfb\x71\xd2\x12\x6a\x5f\x4f\x8a\x54\xc2\x63\x5a\x24\xc6\xd8\xa9\x28\xb2\xe2\x30\xe8\xf0\x08\x2f\x8c\x12\xea\xa8\x59\x3d\x91\x2d\x56\x19\x4e\xbf\x23\x94\x8c\xc4\x28\xb5\x21\xe3\x0d\x53\x04\xe1\x85\x4a\xfb\x56\x7d\xe6\xe5\xf1\x6e\x05\x79\xde\x06\x16\x77\x50\x1b\xdd\x87\xd9\xba\xa0\xf0\x22\xa6\xc1\x9a\xb7\x4a\xab\x4a\x71\x55\xfb\x1a\xd5\xc4\x82\xd0\x7d\x92\x9b\x79\xa8\xcf\x85\xdc\x07\xc3\x44\x51\x78\x91\xd0\x46\x8e\xd6\xac\x73\xed\x94\x30\x91\xe9\xf8\xf7\xc4\xbe\x69\x33\x1e\xb2\xe3\x11\x9f\xb3\xbf\xfe\x02\xf7\x63\xe2\x54\xd3\x91\x5b\xcf\xf3\xfc\xd1\xa3\x88\x79\x4a\x25\xc6\x73\x8d\xd5\xa2\xb9\x2e\x0a\x09\x2f\xc6\x38\x42\xc7\xea\x6b\x67\x7f\x1b\xb3\x3c\x57\xe5\xcf\xaf\x25\x28\xdb\x0f\x4a\x6a\x01\x54\x94\xd3\xec\xa0\x7e\x5b\x19\x71\xb6\x99\x55\xd6\x7e\x24\x05\x60\x96\xeb\xb8\x1d\xc8\x82\xba\xa3\x82\x11\xbb\xd2\x44\x28\x0f\x08\x6d\x9c\xde\xa6\xfd\xd3\x1b\x91\x2a\x41\x5a\x59\x78\xcc\x9a\xe5\xe7\xbb\xba\xf0\x38\x28\x02\x34\x93\x36\x42\x01\xe7\xa6\x5e\xff\x3c\xe5\x65\xd5\x4d\x23\x67\x43\x71\xfb\xfd\x71\xf5\x77\x0e\x19\xc2\x83\xc4\xa3\x9c\xfc\x15\xea\xdf\xb0\xaa\x7b\x59\x17\x7b\x5c\x68\x60\xa9\xab\x0b\x1e\xb2\xb2\xe8\x81\x28\xfe\x74\x26\x49\x6e\x0c\xe0\x4d\xf5\x7b\x9b\x1d\x0a\x12\x13\x9e\x5d\x0a\xd2\xd9\xd5\x5f\x78\x4a\xc4\x60\x61\xdd\xab\x57\x3c\x12\xd5\x6f\x6e\xc7\x16\x1e\x72\xd3\xd6\xa2\x3c\x73\xc6\x5a\x49\x78\x88\x40\xa9\x99\xb5\x1b\xcd\xb0\x76\xd1\xba\xf0\x74\xe0\x13\xf3\x85\xfc\x35\xbe\x14\x68\x4c\x87\xf8\xab\x09\x12\x4b\x78\x3a\x8c\xad\xdb\xe4\x7b\xf9\x86\x0b\x29\xb1\x26\x78\xc8\x6c\xc2\xd6\x0e\x17\xa4\x23\x51\x9c\x8f\x9d\xcf\xb9\x51\xf1\xc5\x6e\xce\xe8\xc8\xa7\x1a\xcb\x5e\x61\x83\xd5\x31\x2b\xf0\x06\x35\x4e\xf7\x31\xe1\x69\xe1\x01\x1b\x20\x07\x9c\x4b\xc8\xd5\x4b\xeb\x2a\x3b\xc2\xf7\xb8\xf1\x4c\x3c\x81\x7c\x1b\xd0\x72\x85\xef\x89\x50\x28\x57\xde\xa4\xba\xc6\x0d\x9e\x2a\x94\xd7\x55\x29\xe1\xfb\x4a\x19\x97\x88\xff\x9e\xb3\xaa\xc2\xfc\x05\xff\xeb\x4e\x13\xf8\x48\xf8\xa6\xf3\x2c\x00\xfd\xdf\xbe\xe7\xff\xc7\xdd\x39\x3f\x88\x12\xca\x2b\x2c\x14\xe7\xba\x84\x2c\xfc\x40\xc5\x3e\x3a\x05\xa3\xc3\xd5\xea\xe1\x07\x5a\xa5\x8e\xd9\x03\xcd\x50\xe1\xf5\x13\x40\x65\xfb\x11\x24\x5a\x93\xcb\x28\xee\x4b\xb7\xbf\xf8\xcc\x33\x32\x64\xa0\x9c\x42\xd2\xae\xfc\x5e\x48\x38\x9d\x3a\xc9\xa4\xe9\x7a\xec\x87\x01\x52\x3f\x61\x6f\x85\x50\xa8\x40\x30\xfc\x6e\x2b\xa4\x7b\xb5\x6e\xf8\x21\x8b\xa9\x24\x9c\xc3\xc5\x39\x24\xdb\x84\x44\xf8\xa1\x60\x91\x7d\xb2\x77\x58\x60\x9d\x5d\x7d\xad\x8e\x18\x3a\xaa\xcd\xae\xb7\xfa\xec\xef\xd0\x55\x21\x53\xf8\x91\x0a\x68\x77\xfb\xbf\xa1\x70\xaa\xf0\x63\x16\x39\x39\x09\x8b\x6b\xba\xc6\x9a\x09\x3f\x4d\xc2\xc4\xd6\xbf\xef\xda\xd8\x9e\xe6\x2c\xb1\x21\xc6\x57\x96\xa2\x30\xfa\x4a\x46\x14\xdd\xbd\x6f\x7e\xaa\x05\x26\xce\xf1\xc5\x7a\x9c\x4d\xbe\x82\x47\x31\x29\xd4\x6e\xfe\x6f\xb7\xbf\x59\xaf\x36\x0f\x8b\xfb\xad\xfb\x38\x08\xb3\x33\x2f\x9a\xf2\x98\xc9\xed\x07\x9c\xe6\x83\xa9\x89\x1a\xa5\xf0\x85\x30\xbd\xcf\xd7\x8b\xa8\x32\x65\x0d\xdf\xda\x94\xac\xf7\x1e\x12\xbe\x04\xa4\x88\x77\xfd\xfe\x88\x1f\xa3\x5f\x3f\x39\x9b\xd4\xe0\x26\xdc\x03\xfc\xbc\xa9\xca\x53\x3d\xf9\x11\x8a\xa5\x1e\x5a\x41\x43\x17\xbb\xba\x96\xcb\x72\xba\x92\x4d\x69\xdd\x9f\xc5\x4c\xd4\x1a\x1d\x8b\x6e\xba\xaf\x4b\x42\x2a\x3a\x58\x58\xa6\xf1\xfb\x9b\x81\xf6\x0b\x5f\x21\x43\x63\x10\x72\xb3\x6d\xca\x53\xdf\x14\x10\x3e\x06\x52\xd9\x30\xd6\xc2\x33\xc6\xa1\xe3\xf8\x44\x08\x56\x41\x9a\x3c\x48\x2a\x90\x4e\x21\x50\xf8\x28\x14\x99\x92\x2e\xef\xb7\x46\x4f\x68\xbf\x5a\x3c\x77\x07\x95\xa2\xd5\xb8\x4d\x6b\x16\x37\x37\x2f\xeb\x6d\xf7\x74\x35\x37\xb0\xfa\x6f\x50\xdf\x60\x8e\x07\x68\xd0\xf6\x50\x1c\x40\x56\xf8\x1a\x8c\x8e\xf0\x7f\xcf\x58\x5d\x2c\x4c\xc1\x70\x4b\x3f\x79\x56\x5a\xa7\x61\x6f\xac\xb7\xf9\x1a\x46\x2f\x82\x20\xf0\x48\x58\xe4\xb9\x2a\xef\xb0\xd8\xa1\x63\x0a\x88\x20\xe0\x9a\x56\x21\x23\xd1\x42\x2d\xca\x36\x9e\xe8\x5d\x4b\xec\x38\x66\xdb\xb1\xa2\x14\x06\x30\xe5\x3c\x31\xaf\x1c\x77\x86\x3b\x5f\xe0\xcd\xc7\x22\x01\xe3\x8a\x83\x85\x95\x2d\xd4\x9f\xe7\xba\x79\x44\xb7\x56\x05\x61\x64\xe4\xd9\xe4\xb9\x6e\x4a\x95\x41\xb1\xfb\x44\x15\xc3\x8d\xd7\x5a\x75\xd5\xb7\x73\x9b\x10\x63\x3d\x94\x5a\x77\x8b\x44\x10\x2b\xed\xf5\xa4\xa6\x5e\xd1\xa5\x1b\x37\x5d\x56\x82\x34\xf6\xa3\x5e\x51\x7c\x4c\x69\xf9\x9c\xcb\xe2\x3e\xac\x8c\x89\x2c\xd5\xfb\xea\x9a\x92\xa7\xe1\xf3\xf1\xe3\x6e\xa0\xa2\xc6\xcd\x3e\xab\x77\x8b\xa7\x2e\xb6\xb0\x2f\x14\x91\xb2\xff\x11\xe2\x4a\x04\xdc\x43\x2a\x2c\x3c\x64\x47\xc3\x68\xfa\x22\x3c\x0a\x78\x64\x1a\xf5\xbd\x21\xd8\x66\x5c\x8c\x13\x01\x57\x86\xe0\xef\x6a\xa3\x6d\x46\x39\x5a\x8a\x27\xdf\x0f\x49\xca\x1c\x32\xe9\x7c\x21\x9e\x37\x16\xcd\x75\x31\xb4\x1d\x69\x48\xeb\xba\xc2\x59\x8e\xa6\x08\x04\x33\xb5\xa4\xa6\xbc\x41\x49\x25\x9e\xe9\x80\x18\x49\x32\xfb\xf9\xfb\xe3\xcd\xc6\x4d\x1e\x01\x82\xd4\x06\x9c\x5c\xe2\xb3\x13\xec\x14\x81\x50\x02\x5c\xae\xf7\xfd\xfb\xac\x07\xa0\x08\x04\x6a\x0b\xb3\x6d\xaf\xc9\x96\xb9\xfe\xee\xee\x4f\xce\x21\xbd\x80\x8a\x1c\x67\x23\x7e\x33\x0b\xda\x10\x81\xf4\x7d\xea\xba\xae\x7f\x9a\x1b\xe4\xcc\x3c\xfe\x29\x1a\xc9\x9d\x26\x06\x9f\x3b\x67\x36\x93\x53\x7f\x01\xe9\x11\x81\x4c\x13\x6a\x4b\x5a\x6e\x78\x30\xe0\x86\x8b\x40\x6a\xb3\x50\x1c\xb0\xd9\xb7\x59\xfd\x3e\x6b\xf0\xe8\x0e\x6a\xe6\x31\xa3\x5b\x7a\x29\xcf\x57\x6d\x55\x37\x28\x4c\xfd\xa4\x37\x17\x36\x41\x63\x77\x86\xd4\x90\x56\xf6\xbd\x55\xde\x16\x65\x85\xdd\x23\xd2\x3a\x30\xfe\x0e\xa5\x6e\x56\x70\x72\xf9\xb6\x39\xca\xbc\x34\x11\xd6\x36\xeb\x56\x66\xf3\x17\xc0\x3c\x65\x7c\xbe\x9a\x11\x95\xf5\xab\x20\xf8\x33\xbe\xc7\x55\x18\x3f\x07\x97\x10\xcc\xd3\x51\x62\x3a\x29\x3f\xd7\xcd\xeb\xae\xa4\xbc\xd5\x5d\xb2\xaf\x19\x91\xce\xfe\x55\xe6\x8d\x83\xd7\x09\x16\xf8\x3e\x25\xdc\xb2\x5d\x4a\x07\x4a\xf6\x82\x05\x52\x1b\x6b\x3c\xc8\xd1\x31\x13\xda\xf0\x2f\x70\x03\x58\xaa\x43\x02\x9a\xb7\xdf\xf2\x00\x3f\x1f\xcf\x47\x27\x77\x30\x79\x3f\x58\xc8\x4c\x4d\xa1\x03\xb1\x62\x45\x4e\xf6\x9b\x9b\x71\x99\xf3\xda\x35\x6d\xb8\x0d\xb3\x90\x1b\xcf\x99\x03\x1c\xd1\xc2\x08\x3b\x92\x9b\x60\xa1\x34\x3f\x65\xa4\x42\x42\xc5\xe8\x9b\xae\x80\x28\x58\xa8\x81\xd6\x25\xfb\xd0\x77\xf7\xdb\xc7\xe7\xaa\x2c\xf5\x1c\x3a\x48\xb0\x28\x41\x82\x7a\x9d\x4c\x03\x7f\x60\xd4\x28\x58\x04\x69\xe8\xdc\x8c\x28\x6c\x16\x6e\x8f\x62\x71\x1c\x04\xa6\x99\x0d\xca\x19\xde\x8c\x7f\x4a\xac\x22\xfa\xf0\x8f\xcd\xe3\x4b\xf7\x29\x9d\xa2\xd1\xd6\xa7\x56\x81\x91\x1d\x8c\xc3\x51\xa6\xc8\x92\xc0\x77\x4c\x3b\xd3\x04\x37\x40\xec\xf1\xfd\x4e\x94\x0e\xad\x01\xe1\x5d\xa6\x9b\x7a\x79\xd9\xe1\xf1\x94\x43\x83\x13\xe9\xdb\x76\x65\x33\xc5\xb5\xe3\xa0\x4b\x3f\x7f\xf7\xdb\x1d\xc8\x96\x7d\xee\xb3\x77\xdc\xfd\x1c\xaf\x22\x8c\x0b\xc9\xbd\xde\x6d\x10\xab\xe6\xb2\x2a\x73\x07\x53\xee\xd3\xd8\x7f\x47\xff\x71\x9f\xd0\x21\xe1\xb8\xa8\xad\x6c\xa3\xe2\xe1\xb3\x82\x80\xb9\x0e\x85\x93\x45\xea\x97\x0f\x06\x09\x63\x46\x78\x8d\xe4\x46\xf0\xe9\xd4\x0c\x37\x36\x37\x2a\x35\xa0\xd8\xfb\xf2\xf0\x5b\xd9\xb3\x7d\xae\x5d\x40\xda\xa1\x29\x21\x29\xf2\x52\xbe\x59\x3b\xe6\xab\xc6\xb9\x1d\x2a\x3c\x10\x36\x75\xb8\x45\x27\xbf\x3e\xb8\x36\x61\x4d\x16\xe8\xe1\xdc\x9e\x73\x9d\x51\xd3\x68\x76\xdd\x64\x22\x4e\x8d\x08\xec\x6b\x55\x7e\xd4\x3f\x5e\xb1\x0b\x33\x0c\x95\x33\x2b\x0e\xc3\xb5\x47\xb4\xbb\x61\xfb\xdd\x59\x5e\xba\xbf\xc9\x54\x25\x3d\x46\xed\xc1\x78\x46\x50\xd9\xab\x7d\xcd\xca\x73\x43\x73\xfc\x49\xbb\xc8\x78\x7c\x01\x52\x45\x91\xad\x06\xac\xdf\xb1\xba\x2c\x33\x35\x95\x8f\x16\x4c\x79\x8c\xe6\xf4\xed\xe2\x79\xe0\x44\xee\x32\x0f\xa6\x90\x11\xb2\xe6\xc3\xad\xf8\x6e\x0b\x98\x46\xe1\xa3\xd9\xac\x7d\x41\xd1\xaa\xeb\x8e\x2c\x8a\x03\xe6\x3f\x5e\x11\xf3\xdb\xac\x68\xa3\xe2\xdd\x90\x0b\x79\x1d\x16\x31\x1d\x84\x0e\x98\x94\x15\xcf\xd0\xbd\x81\x1a\x78\x40\x7a\xb8\x86\x3c\xb2\xef\xfe\x8e\xe8\x52\x0b\xab\xa8\xe2\xc7\xa3\x17\x2c\xf4\x80\xcb\xae\x14\x23\xcb\xe3\x91\x5c\xc6\xc8\xc0\xcd\x9e\x24\xf4\xb5\x90\x83\x86\x18\xc1\x40\xe7\xf1\x80\x22\x0c\x84\x47\xf0\xaa\x13\x5c\x96\x58\xa0\xce\x64\x06\x54\x71\xb4\xc7\x43\x16\x51\x79\xe1\x2e\x6b\x5e\xcf\xa2\xff\x2b\x27\xf7\x47\x63\x20\x65\x0d\x4c\xdc\xb1\x18\x08\xcf\xf7\xe3\xdb\x66\xb7\xbe\xdf\x6c\x77\xfb\xed\xf7\xe7\xe7\xfb\xcd\xfa\xa5\x1b\x91\x44\x60\x96\x5b\x75\x96\x58\x9d\x8b\xe3\x1c\x7a\xdc\x0d\x16\xc2\x28\x93\x55\xe5\x5f\x58\x90\x04\x91\x3b\xa2\x14\xf5\x92\x6d\xcd\x2d\xba\xcd\x8a\xac\x7e\xed\x0a\xa1\x61\xa8\x95\x62\xc3\xa5\x68\x3c\x63\xc2\x28\x52\x32\x76\x1e\x18\x99\x91\x9c\x98\x41\x1d\x88\x30\x0e\x19\x51\xac\x8d\x28\xd3\xe2\x7e\xbd\x5f\xde\x2f\x56\xbf\xb6\xbf\xcd\x7d\x57\x0c\xbe\x43\xf3\xb9\x89\xd5\x87\x88\xe3\x85\x2a\x4c\x3c\x14\x76\xf5\x6b\xf3\xaf\x6d\x03\xc7\xb1\x11\xba\x08\x13\xa6\x0d\xaf\x3e\x6f\x97\xe8\x0b\x19\x74\xa3\x1a\x03\x54\xc7\x9f\xe0\x7e\x9c\x76\x9e\xae\x0d\x56\xef\x6d\x14\x38\x1b\xb8\x85\x3c\x06\x92\x61\xc2\x9f\xa7\xbc\xcc\x9a\x07\xbb\xe8\xa4\xee\x30\x37\x3a\x1b\x0d\x51\xbf\xfd\x53\x8f\xeb\x14\x21\x04\xdc\xd9\xc7\x6c\x09\x83\xd9\xcd\x93\x76\x45\x09\x06\x1d\xad\xa3\x80\xba\x06\x55\x56\x0f\x9d\x56\x82\x08\x45\xea\xd1\x4a\x72\x82\x8b\x93\xbd\x75\xaf\x4e\xe0\xf5\x2f\x4f\xe0\xfd\xc7\x7d\x00\x63\xba\xf3\x2b\x28\x96\x30\x24\xfc\x88\x50\x46\x11\x65\x99\xb7\x2f\xeb\xf5\xbf\xd6\xfb\xf5\xe3\x4d\x7f\x04\x44\x8f\xf4\xd8\xbe\xc2\x09\xb7\xaf\x99\x6e\x56\xe4\xf1\xd6\x66\x17\xcf\x65\xdd\xcc\x34\xbd\x44\x28\x39\x50\x7d\x82\xc2\x8d\x81\x2b\x85\x3b\xb5\xf2\xd0\x56\x86\x15\x1e\x69\x3d\xbf\xed\x94\xaa\x45\xa8\x54\x6a\xec\x3d\x8d\xca\xc8\xe4\x99\x2a\xd4\x52\x74\xcd\xd1\x55\x79\x3e\xf5\xe1\xf2\xbf\x83\x2b\x0d\xca\x2e\xa6\xfa\x77\xe0\xee\x86\xd2\xa9\xa3\x4f\x3f\x7d\x14\x9b\x06\x8f\xd7\x08\x58\x11\x62\x1c\x12\x78\x02\xda\x95\xa1\xd7\xd5\x1b\xfd\x4e\x44\x49\x6d\x32\xc8\x1b\xa8\x86\x3f\x41\xfb\x31\xf1\x40\x09\x11\xd0\x46\x5b\xe3\xa9\xa3\xfd\xc4\xd4\x6f\x08\xf0\x5b\x4a\x44\x55\x53\x96\x43\xeb\x8f\x91\xb4\x9e\x7c\x22\x32\xbd\x4a\xd3\xaa\xfe\xbe\xbd\xf9\x5b\x31\x42\x11\x6a\x34\x7a\x44\x79\x79\x28\x7b\x7d\x43\x11\x79\x81\xa2\xfd\xd6\xe5\x58\xf3\xb5\xfc\xb9\x80\xf5\x93\x3a\x73\xe4\xc5\xe6\x89\xe1\x4f\x27\xed\xdf\x7d\x57\x1a\x72\x0b\x89\x59\x41\x61\x64\xfc\xe6\x61\xcc\x83\x94\x21\xf2\x52\x43\x1e\xc8\xa1\x6e\x9e\xa1\x0d\xfe\x27\x7b\x59\xe4\x63\x40\x3a\xd7\xfb\x53\x79\xb2\x32\x63\xdb\x31\x84\x6c\x98\x19\x47\x3e\x1a\x7f\x12\x8b\xc2\x22\xf4\xe4\x60\x0d\x8c\x02\xe6\x91\x45\x3f\x99\x5f\xdd\x7e\x7f\xbc\x79\x58\xef\x6f\xd7\xeb\xee\x70\xca\x28\x26\x2a\xf0\xa7\xf1\x02\x1c\x14\x7c\xa2\x00\x43\x2f\x74\xb2\xab\x46\xcf\xc6\xcd\xc1\xb4\x2b\x9d\xfe\x3b\xb4\xd3\xb1\x9d\xa2\x6e\x46\x86\x76\x46\x46\xcc\xe7\xbc\x57\x15\x6f\xdf\x2e\x98\xcd\x02\xcf\x3d\x67\x4c\x44\x24\xfd\x6f\x20\x79\x8b\xa5\x1d\x31\x9a\x9e\x11\x63\x46\xa2\x0e\x7f\x36\x6d\xec\x42\xd2\x8d\xb3\x05\x81\x88\xf1\x40\xb7\xcb\xde\x3d\x96\x05\x54\xca\x05\x1c\x11\x03\xee\xe8\xef\xd6\x74\x24\xfb\x0b\x1f\xcf\xc7\x5d\x26\xdf\xea\x61\xbf\x2d\x62\x2a\x48\xd8\x08\xd2\xeb\x76\xb9\x28\x12\x01\x9d\xa4\xc2\x53\x0e\x97\x2d\xf5\x08\xae\x6a\xcb\x76\x6c\xec\x7b\x91\xc9\x6d\xda\x9d\x66\x50\x56\x8c\xe2\x20\xa2\xba\x5a\x0d\x1a\x3f\x83\xb7\x8e\xe7\x48\x1c\x31\x95\xf4\x90\xe7\x5d\xd9\x31\x7d\xc6\xe3\x12\x4f\x18\xe5\x7f\x9b\x20\x3a\x14\xfe\x86\x2c\xad\xdc\x20\x65\x7c\x0e\x76\x58\x40\xd1\xec\xa8\x95\x00\x0d\x3e\x64\x75\x85\xa7\xf1\x6d\x4f\x7d\x69\xf0\x26\xf2\xac\xca\xde\x10\x5d\x44\x69\xe2\xd1\x34\xda\x9f\xb0\xd2\x65\x75\xfc\xff\x8f\x09\x3f\xb9\x73\xdc\x0b\x65\x1f\x97\xeb\xac\xb9\x19\x40\x23\xe7\x2b\x02\x11\x47\xe9\xc2\xa4\x7b\xa8\x9b\x51\xab\x65\x7c\x8f\x20\x8c\x88\x01\x76\x2e\x5c\x72\xb7\xbc\xdc\x0f\x12\x7e\x17\xa9\x45\x10\xc7\x01\x76\xc8\x0d\xd3\x30\x9c\x7c\x2b\x24\x1e\x63\x0e\x67\x87\x3a\xfb\x89\x6a\x48\xd1\xb4\xa3\x84\x6f\xde\xb9\x66\x82\xcc\x16\x91\x88\x03\x32\x7d\x5d\x3e\x3d\xef\x3e\xd5\xd0\x10\x91\x00\x46\xc3\x4e\x65\x7e\xb9\x66\x69\xb5\xc7\xa3\xb8\x2b\xb5\x95\xd5\x9e\xe8\x5c\x4d\xbd\x9f\xa9\xf7\x46\x02\x4c\xac\xf1\xb0\xf8\xdd\x84\x61\x7f\xb8\xa2\x7a\x77\x36\x81\x3a\x1d\x92\xd1\xdb\xe8\xa1\x80\x7c\xc4\xc8\x71\x63\x95\x22\x76\x50\x17\x0e\x1b\xf1\xd5\x2f\x30\xbc\x63\x07\x41\x11\x49\xf4\x09\xc9\xbb\x85\xff\x1f\x6b\x5f\xd6\xdc\x38\x6e\x7d\xff\x75\xf2\x90\x07\x70\x03\xc1\x47\x59\x96\xdd\x9a\xf1\xf6\xb3\xe4\xee\xc9\xa4\x52\x2a\x2c\x17\x32\x63\x8a\x54\x48\xaa\x6d\xe5\xd3\xff\x8b\x17\x0b\x17\xd1\xee\x49\xd5\xff\x25\x3d\x31\x21\xae\xc0\xc5\x5d\xce\x3d\xe7\x70\xf4\x21\x43\xa2\x54\x80\xf5\xfe\xe6\xb5\x3a\x15\xea\x89\xf7\xcf\xaa\x94\xa1\x26\xb7\xb2\x8b\x7d\x77\xfa\x04\x3e\x64\x87\xa3\x30\x1d\xf6\x25\xa0\x50\x43\x55\x15\x4b\x5b\x0e\x9b\x9d\x7a\xa0\x14\x5e\x17\x51\x02\xc3\xee\x59\x91\xe8\xd0\xc8\xf2\xac\xcb\x06\xea\xd6\xd3\xa2\x8f\xd5\x5b\xd9\xdf\x07\xa1\xe3\xec\x3f\x7d\x8d\x90\x12\xc2\x42\x2b\x0b\xa5\xf3\xb6\xd9\x40\xa9\xb0\x07\xcc\x1d\x0e\x24\x72\xec\x7e\xaf\xf6\x50\xa8\x93\xe0\x5d\xd4\xa9\xda\x81\xf7\x41\x49\x62\xf8\x2a\x5e\x79\x63\x32\xf4\x3f\xba\xd8\x01\x26\xa9\x48\x4a\x52\xea\xa2\x6b\xdf\x0e\xeb\x0e\xc9\x04\x2d\xcb\x35\x57\xcd\x76\x74\x6a\x08\x5d\xdb\x0c\xfe\xc0\x9c\xbf\x59\x97\xf3\x18\x0b\x1a\xc4\xc6\x41\x35\x94\x43\x3b\xee\xe5\xff\xdc\x09\x83\x24\x45\xce\xba\x85\x28\xaa\x8f\x0f\xff\xd7\x2c\xe4\x36\x27\x71\xbf\x7d\xb9\x9a\x70\x93\x0a\x1a\x72\x82\x80\xad\x59\x4f\xf7\xc2\x9c\x8c\x76\x84\x70\xcc\xd2\x23\x68\xa8\xb4\x89\xdd\x70\xef\x36\x67\xb4\x87\xa2\x4c\x63\xae\xa9\x38\xc9\xb7\x73\x9f\xf7\xa4\x11\x04\x58\x4c\xde\x43\x7b\x75\x3a\xa3\x2d\x5d\xe8\x16\xea\x2d\xff\xe8\x87\x70\x65\xd1\x15\x66\x1b\xf9\x32\xe7\x48\xe3\x38\xea\xf7\xa1\x16\x8a\xe6\xea\x3c\x5f\xfa\xa7\x71\x16\x86\xc2\x46\x23\x5b\xe0\x87\xed\x65\x5b\xae\xa0\xb1\x8a\xc0\x2b\x73\x5d\xd7\x3c\x9f\xdf\x6a\x07\xd7\x57\x1e\x51\xfc\x52\x76\xb3\xae\x05\x5e\xe4\xe5\x7e\xc9\x8f\x5c\xe6\xed\xd7\x2d\xbb\x82\x26\xdc\x4c\x0b\x59\x57\xef\xa5\x4f\x2e\xdb\x83\x34\x92\xe8\x3c\xdd\x3d\x3e\xde\xaf\x17\xbb\xe7\xd5\xfd\x62\xfd\x70\xed\xc3\x3c\x4a\x93\x0c\x11\x67\x3b\xf2\x61\xc3\xab\xd1\x94\x4b\xd3\x4c\x39\xc2\xc5\x5d\x55\xc2\x0d\x2f\x1a\x58\x34\xdd\x72\xf3\x43\x24\x60\xc6\xc9\x11\xaa\x6f\x06\xd8\x64\x3b\x84\x91\x14\xe3\xfa\xce\xc3\x59\xbe\x82\x7c\x3b\x56\x79\x3f\xdf\x59\x92\xe0\x02\xbf\xaa\x9a\xf1\x7c\x67\x09\x43\x0a\x32\x0f\x67\xad\xea\x9b\xea\x54\xff\x03\x78\xdd\x0f\xf1\x3d\x8a\x16\xd2\xf4\x69\x45\x90\x32\x69\x12\xec\x56\xf2\xcd\x35\xcc\xbe\xcc\xc8\xff\x8d\x4d\x10\xe5\x41\x8c\xbb\x05\x7c\xe0\x13\x3e\xf1\xba\x6d\xba\x6d\xf5\x16\xca\x89\x2b\x4d\x45\x90\xf5\xba\x79\x17\x55\x44\x37\x48\x28\xc7\xf2\x8c\x95\xe8\x03\xdf\x4f\xcb\xd5\x54\xc6\x02\x53\x08\x87\xaa\x44\x91\x38\xb5\xad\x06\xe9\xca\xf1\x45\x55\x42\xd0\x0f\xde\x3a\xb2\x51\xe6\x0e\x64\x46\xc2\xd4\xf3\x7a\x76\x76\xd6\x6d\x75\x54\xc9\x14\x9b\x47\xbc\x06\x5e\xfd\xc9\x6e\x47\x41\x1a\x6d\x8a\xb6\xce\xf7\x7b\xdb\x0f\x72\x63\x41\x4b\x6b\xfd\x00\xa0\x3e\x6f\x3b\x76\xa7\x50\x61\xc6\xbd\xaf\x7e\x0b\x2d\x76\xa3\x23\x3a\xbd\xdf\xbc\xa8\x66\x44\x07\xbe\xf6\x8c\x04\xb9\xaa\x73\x99\xb6\x77\xff\x38\x42\xbd\xda\x7e\x1b\x3f\x79\x4a\x48\x14\x59\xa0\x59\xe7\x84\x1a\x5a\x86\x41\x6b\x62\x37\x22\x43\x9f\xaf\x79\xad\xde\xbf\x73\xdf\x88\x20\x52\xc2\x12\xd3\xb3\x06\xfc\x60\x95\x95\x87\xed\xc7\x22\x25\x42\x22\xb8\xc3\xb0\xff\x5c\x26\xe0\x66\x9f\x33\x25\x10\x60\xcd\x68\x77\x2a\x8f\x5c\xbe\x6d\xda\x1a\x1b\x74\x47\x76\xc8\x0f\x8d\xb1\x3c\x51\x09\xbc\xba\x9b\xd4\x69\x10\x72\x14\xbb\x45\xb1\x90\x29\xc2\xf5\xef\x13\x9f\x28\x0d\x44\x0a\xe6\x2b\xc2\x91\x9f\x4d\x6f\xc1\xd4\x66\xa7\x61\x9a\x06\x46\x0b\x14\x8b\x93\xfe\x25\x44\x19\x21\x62\xd8\x76\x32\xf9\x5d\x4c\x42\xc4\x60\x60\x13\x96\xa9\x7e\x7c\xb3\x20\x35\x64\xe8\x9c\xdd\xe1\xd3\x38\x0b\x51\x68\xaf\x45\xc5\x5b\x5f\x8a\x75\x17\x8d\x35\xc7\x8b\x5e\x2d\x17\xcb\xe2\x24\x96\xbf\xa8\xec\xa5\x49\x62\x08\x97\x0e\xbc\x3c\xf1\xc2\x64\x90\x2e\xe8\x6d\x45\x9a\xc8\x38\xb0\x1b\xc3\x68\x6b\x72\x87\x95\x99\xc3\x98\x20\xda\x3d\x3d\xaf\x30\x49\xd4\x57\xbd\x53\x4a\x89\xc9\x7f\x5a\x55\xca\xa5\x23\xe3\x10\x29\xcd\x98\xa1\x5c\xe1\x5a\x17\x60\x0d\xe5\x55\x55\xbd\xcd\xe6\xa2\xd2\x94\x28\xe2\x72\xa1\x65\x5b\x9f\x2f\x12\xa1\x29\x23\x0a\x5b\x81\x36\xf7\xeb\xbb\xc7\xdd\xcd\xe3\xcb\xc3\xf5\x62\xbb\x7e\x7c\xd8\x2d\xee\x1f\x5f\x1c\x88\x58\xa4\x2c\x54\x08\xa1\xed\x7c\x2a\xac\x2e\x5d\xe2\x0c\x53\xc6\x8d\xbe\x89\x28\xb8\x7c\x33\x40\xd9\x61\x90\xdc\x1d\xc7\xce\x34\x04\x5f\x99\x3c\xf7\xc5\x1c\xb6\x43\xb3\x58\xa1\xe7\xc1\x95\x42\x46\x84\xc9\x95\xb2\xc4\xd4\x1b\xba\x20\xe9\xa2\x88\x3d\xca\xf7\xbb\x1f\x64\x01\x56\x2f\xf7\xbc\x71\x9a\x58\xee\xae\x32\x90\x48\xa6\xe1\x6c\x3b\xca\xbf\xfb\xa5\x87\x4a\xe2\x6e\xdb\x89\xe8\x8e\xe3\x8e\x73\xcb\x9b\x97\x86\xef\x21\x24\x84\x5c\x55\xbc\x56\xfd\x78\x1a\xa7\xc1\x6c\x4f\xce\x7c\x26\x2e\xe5\x69\x88\xbd\xb1\x05\x6f\xda\xdd\xa1\xdf\x8c\xd2\xce\x60\x50\x4f\xd0\x7d\x2a\xd5\x10\x26\xe4\xc6\x08\x93\x58\xf5\x3c\x6c\xdf\x78\xad\x3e\x61\x0f\x14\xa9\x50\xa6\xdb\xc6\x3f\xa9\xae\xde\xa7\x3e\x43\x2a\x43\x23\x33\x62\x84\xd0\x93\xb7\x97\x46\xad\xcb\x25\x78\x81\x16\x91\x4a\x9a\x20\x82\xfe\x4f\xf1\xdf\xff\x4d\x37\xa2\xfb\xa9\xc6\x0e\x92\xa6\x85\x23\xf5\xe7\x53\x22\x41\x45\x42\x5e\xbe\x5d\x57\xef\x9f\x40\x33\x52\x25\x0c\x12\x49\x17\xf9\x71\x5a\x80\x4a\x51\xab\xcb\xda\xd6\x2e\xc4\xbb\x2d\x2a\xc1\x8b\xc5\x49\xe5\xed\x20\x87\x91\xea\x28\x23\x89\xab\x61\xa2\x92\x41\xde\x83\x71\xfe\x19\x90\x8b\x3c\x86\xfb\xf3\x34\x95\x91\xea\x58\x12\x35\x7c\xf3\x4f\x55\xdd\x56\x9f\x7c\x63\xcd\x85\x4a\x5d\x6a\xd9\xf5\x91\x38\xb3\xc9\x08\x61\xb1\x6d\x5f\xba\xbb\xfb\xbe\x03\x95\xb7\xbb\x80\x8d\x62\x6d\x46\xd2\xc8\x35\xd3\x3e\xe7\xcd\x54\xf2\x51\x30\x22\x22\xb4\x73\x35\x97\xd0\x05\xc4\x4b\xef\x5a\xb3\x80\x30\x6a\x9b\x84\xff\x17\x1a\x41\xc1\x82\x88\x6a\x53\xcf\x72\xfb\x59\xe3\xcf\x09\x99\x69\x28\xf6\x11\xd6\x68\xcb\x9e\x4d\x24\xb3\xd0\xca\x98\x34\x47\x28\x95\x61\x80\x71\x47\x22\x43\xb3\x60\x02\xfa\xce\xc4\xf0\xbc\x84\x7a\xa1\xf8\xb1\xfd\x95\x4b\xc4\x42\xea\x73\x90\x06\xd0\xb9\xad\xae\xcf\x25\x3f\xe4\x72\x24\x74\xe6\x46\x67\x1c\xdb\x76\xee\x9f\xb6\xe3\xa0\x7a\x6a\x3d\x3e\x9d\xc4\x2c\x82\x50\x98\xb6\x15\x84\x89\x9b\x6c\x0b\x1f\x4b\x1d\x0c\x3a\x55\x06\x66\x88\x45\x9a\x04\x46\x7c\xb1\x69\xa7\x52\xe5\x82\xc5\x89\x0c\xcc\x34\x29\x89\xad\xf8\x8e\xa9\x4f\x05\x4b\xe2\x00\xbd\x8c\x83\x68\xe5\xb6\x7a\x69\xa6\xf3\x20\x49\x03\xe9\x5b\xf8\xbf\xf6\x83\x58\x22\x0d\x50\xf2\xf6\x65\x7d\xbd\x1a\xba\xbb\x2c\x51\x19\xd6\x89\xd7\xdf\x5d\x6a\x90\xd1\x4c\xa0\x96\x9d\x23\x79\xf9\xa4\xfa\xc7\x52\x92\x46\x3d\x9c\xd7\xfa\x93\x73\x91\x18\xbb\x6c\x22\x16\x2c\x05\x89\x95\xf5\x12\xde\x0d\x58\x70\x6c\x9c\x18\x23\x11\xf3\xf0\xdd\x65\x55\x6d\x00\xd4\x90\x61\x4a\x30\x46\x4d\xf7\x6a\xe3\xc0\x3e\xe8\xe5\x43\x7d\x83\x34\x9b\xce\xe1\x64\x4c\xd1\xa1\x7a\x57\x75\x38\xe4\xed\x61\xaa\xd3\x2b\x18\x03\x86\xc6\xf0\x8e\xb7\xf9\xe9\x60\x04\xee\xdd\x29\x32\x12\x62\x06\x08\x4a\x75\xcd\x5b\x08\xdc\xdf\xb9\xcc\x42\xb7\x63\x7c\xf2\x92\x44\x10\x62\x2c\xf3\x74\xb7\xd8\xde\x3c\x3e\xdf\xef\x7e\x2c\xee\xee\x56\x6e\xaf\x65\x82\x53\xc4\xeb\xe7\x98\x4c\x40\xc2\xd8\xbf\x8d\x5f\xd9\xe4\x74\x42\x85\x5e\xaa\xa5\xe5\xc5\x4d\x4f\xf9\x2e\x98\xe4\x26\x0b\xae\xaa\x7b\x5e\xd7\x39\x77\x6d\x61\x82\x49\x91\x21\xe7\xdc\x5d\xb5\x47\x72\xa8\x3e\x9d\xc1\x54\x18\x63\x98\xd4\x19\xb6\x75\xb3\x90\x6d\xfe\xd3\xff\x4c\x45\x11\x3e\x1f\x96\xb9\x77\x56\x0e\xb0\xf3\x60\xdc\x00\x08\x28\x25\x43\x64\xa0\x29\x65\xfb\xc3\x60\xa8\xe7\x10\x19\x77\xcf\x73\x24\x74\x31\x5d\xef\x46\xee\xc0\x8e\xd3\x3c\x46\xa7\x57\x0e\x5a\xb1\xd6\xe5\x92\x9f\x0a\x55\xdb\xb8\x83\x4d\x4c\x81\x16\xa6\x49\xbe\xc1\xcd\x57\x42\xd9\xbd\xba\x6d\xf5\x7b\x5e\x14\xc3\x60\xa4\x1b\x07\xd2\xe7\xa1\x9b\xb6\x8b\x8c\x3f\x6d\x31\x33\xbf\xc9\x48\x9c\x10\x9b\x26\x41\x79\xff\xab\xd3\xb9\x57\x17\x1d\x7d\x8f\x8c\xa4\x11\x7a\xd3\x56\x04\xc7\x40\x6e\xe6\xa7\x42\x46\xb4\xc6\xc4\x11\x76\x8e\x4e\x0c\x42\x16\x44\x0c\xcd\xec\x4b\xc9\x3d\x3b\x84\x05\xfe\x8c\xac\x4b\xec\xc6\x8b\x04\x71\xf0\x8b\xbb\x97\x3f\x7e\x89\xe2\xcf\x02\x15\xa5\x36\xd8\xb7\xf0\x91\x01\x29\x8b\xc8\xc2\xd0\x48\xb2\x9b\x5c\xda\xf3\xc5\xe2\xc8\xc2\x24\xb2\x99\xd8\xcf\x7a\x80\x45\x16\x05\x24\x34\xa0\xa8\xa6\xf9\xfd\x1f\xcb\xf1\x72\xce\xa2\x04\x30\x89\x25\xf2\xbd\xa8\x2b\x84\xbf\xb9\x23\xd2\x70\x36\x8b\xb1\xdc\xfb\xe4\x0e\xe2\x18\xe2\x1e\x47\x8f\x23\x6e\x6b\xfe\x59\x72\x37\x8b\x53\x8d\x88\xae\xd5\x07\xa6\x13\x9f\xa1\x41\xee\xd3\x41\x81\x24\x8b\x01\x30\x14\xb3\x74\xdc\x76\xda\x61\x86\xd7\xcf\xcc\x2c\x09\x29\x5e\xb6\x8b\x65\x2b\xc3\xc1\x60\xfa\xd9\x9b\x91\x02\xa7\xc8\x12\x91\x62\xe3\x90\x65\x6d\x9d\x9f\x58\x89\x8a\x51\x4d\xcd\x75\x00\x8d\x99\x46\x3e\x99\x8d\x89\x26\xae\x28\xbc\x3c\xd5\xc8\xca\xb3\xf6\xf7\x47\x13\x99\x18\xb8\x46\xde\x2d\x01\x5c\x7c\x93\x16\x84\x8c\xa6\x46\xf1\xa0\x36\x02\x11\x88\x3d\xed\x9f\x90\x32\x2e\xfb\x7e\x62\x7f\xe3\xa3\xb7\x49\xb9\xe2\xa9\x85\x2f\xbd\x94\xc7\xce\x82\xb8\x9f\xa7\x49\x94\x11\x9f\xee\x33\x7d\x06\x13\x2f\xfd\x12\xfc\x90\xa5\x34\x42\x4c\xb9\xab\xd7\x89\x4f\x8b\x75\xf6\x07\x2c\xd0\x08\xa2\x1c\x36\x19\xcf\x4d\x13\x96\x9a\xee\xe8\x63\xc1\x25\x72\x30\xce\xef\xf5\x6e\xb4\x64\x8a\xf6\xa0\xf5\x06\xbb\x47\x3b\x9f\xd2\x0a\xfe\x4f\xe6\x70\x46\x24\x72\x64\xe4\xbe\x6e\xf4\xab\x12\xa3\xfb\x21\xcd\x38\xf3\x15\x84\x51\x67\xb4\xc8\x78\x12\xa2\x48\xcd\x75\x55\xe2\xf7\xbb\xe7\x2d\x3a\xf4\x5f\xbf\x10\x0e\x12\x71\xb8\x95\x0d\x71\xd6\x6a\xc4\xbf\x28\x32\xae\x59\x14\xf7\xca\xc4\x55\x91\xcb\xf3\x78\x6b\xb1\x03\x85\xa4\x58\x28\x3b\x72\xc4\x3d\x5d\x54\x0a\x32\x99\xa5\xc8\xb3\xb4\xc1\xcc\xd5\xaf\x8d\x8d\xd2\xa9\x12\xe3\xcc\x3c\x37\x49\xa0\x49\x74\x9c\x01\x31\xd6\x73\x0e\xc2\x35\x1a\xc9\x49\xc0\x62\xa3\x02\xd6\x9c\x06\xb9\x71\x4e\x92\x10\xcb\xce\xcf\xa0\x6b\x68\x5e\x97\xaf\xf9\xf1\x05\x91\x27\x58\xc9\x19\x6c\x04\x9c\x50\x26\x6d\xaf\x88\xcd\xad\x54\xf5\x37\xc3\x2c\x3e\xfb\x86\x79\xc8\x4d\x4b\x01\xf2\xfa\xdd\xe7\x65\x3b\x26\x06\x99\xce\x69\x1e\x51\x25\x6c\xfe\x17\xdb\xa0\xe7\x1f\x24\x4a\x39\xbe\xed\xb2\xbe\x07\xde\x9c\x6a\xcb\x9f\xe8\x8f\x2a\xd7\x66\xb3\x28\x0a\xc7\xf3\xd8\x5c\xe7\xcd\xf1\xd4\xc2\x55\x55\xaa\xa1\xf3\xc6\x23\x16\xa3\xd2\x8a\xc6\xec\x84\xa1\xd9\x9f\x7f\x98\x48\x2a\xe4\xd6\x15\xa7\x52\x5d\x36\x5f\xda\x41\x31\x07\x6c\x55\x7b\x80\xf7\xeb\x53\xb9\x87\xaa\xbc\x29\xaa\xea\x42\x80\x67\x58\xe7\xb8\x48\xae\xf3\x84\x46\xc4\x31\xfa\x05\xe8\xa3\xb8\xbb\xa5\x84\x62\x09\xbc\x5b\xbf\x0f\x1e\x93\xc4\x29\x55\xb2\x5b\x55\xbf\x3d\x6e\x5f\x1e\x46\x39\x1b\x4e\x79\x44\x6c\x30\xf5\x7f\xa7\xaa\x1d\x32\x89\x09\x9e\xc6\x92\x0c\xa7\x99\x82\x1f\x80\x9c\x77\x73\xd9\x11\xce\x32\x86\x05\xaa\x5d\xb7\xbd\x42\xd9\x62\xb7\xf8\xfc\xd0\x8c\xc7\xb8\x5a\xaf\x73\x7e\xa8\x4a\xd5\xbd\x75\x77\x4d\x1e\x85\x26\x4e\x3a\x89\x83\x81\xa3\xef\x90\x43\x70\x87\x7b\xfa\xae\xe9\x73\x0d\x9c\xc7\x46\x19\xd1\x40\x32\x3c\x0c\x7a\xe2\xe6\x22\x19\x2b\x36\x7c\xd6\xb9\xbf\x1f\x7b\x48\xc4\x11\xe6\xd8\xf2\xc6\x62\x78\x07\xe1\x2d\x17\x5a\xe0\xd3\xff\x44\x65\xd5\xed\xf9\x08\x2e\xc8\xe6\x8a\x52\x04\x8a\x1e\x76\xab\xed\x37\x5b\xf6\x1d\x46\xf5\x5c\x29\x40\x23\x69\xb4\x12\x1d\xf3\xcd\xb4\xee\xc9\x95\x56\x91\x67\xb6\xbb\xcd\x7f\x42\xb9\x78\xf7\x38\x35\x0e\x51\x82\x02\xf8\xd7\x8b\x47\x43\xd3\x6f\x13\x58\x4f\x43\x42\xf4\xcf\x40\x49\x1c\x62\x23\xbb\x60\x66\xae\xc3\x48\xba\x83\x69\x1c\x39\xc9\xa8\xd5\x96\x6e\xab\x69\xbc\x35\x34\x74\x1c\x52\xa1\x8d\x46\xac\xfa\x76\x14\x0f\x83\x96\xa3\x0b\xec\xf1\x28\x91\xc0\x35\x01\xec\xc8\x57\xeb\x32\x9f\x83\x79\x73\x9d\xea\x50\x7b\x5c\x8e\xa5\x3d\x1b\xcf\x15\x0d\xda\x68\x2f\xf3\x37\xe8\x4e\x33\x6e\x18\x16\x24\x4e\x74\x67\xa5\x9f\x4e\xa2\xc8\x65\xe7\x85\x14\x3f\xa7\x56\x50\x90\x44\x67\xd6\x95\x5d\xb7\x70\xb0\x25\xfd\x9b\xaa\x5e\x14\x73\xb5\x56\x41\x38\xc3\x24\x4a\x01\xbc\x69\xb1\xd5\xc9\x1d\x00\x23\xa5\xa8\xda\x5b\x68\x97\x79\x7b\xbe\x1e\x34\x95\xdb\x31\x41\x20\x11\x1c\xb5\x13\xa7\x19\x0a\xa3\x61\x04\x2b\x02\x91\xe2\x26\xcd\x8f\xf9\x94\xb1\x4c\x88\x40\x49\x0c\x0d\x56\xcf\xcb\x90\x74\xd1\x77\xaf\x7c\x23\x44\x18\x13\x8c\xbc\xad\xf7\x65\x05\x6c\x3b\xb3\x1c\x46\xb3\xf5\xed\xcf\x50\xe2\xf6\x7c\x51\x10\x23\x77\xad\x85\x90\xa1\xf4\x88\xf3\x1f\xbb\x38\x00\x99\x7f\x6e\xaa\x6a\x21\xf2\xc9\xe3\x46\x51\xe8\x40\xc7\x37\xa7\x72\xd3\xf6\xbf\xd2\x0a\xe9\x92\xde\x0c\x7f\x28\x32\xae\xd9\x43\x71\x1c\x61\x9f\xb5\x38\x15\x6f\x9d\xdd\xff\x0e\x4d\x7b\x99\x81\xbf\xdc\x01\x44\xcc\x25\xe6\x57\x6f\xaa\x1a\x29\x8f\x6a\xc3\x11\x7d\xbe\x98\x8f\xe3\x7b\x8c\x75\x8c\x1c\x55\xcf\x8f\x77\xab\xdd\xe6\xe5\x69\xf5\xfc\xb2\xf1\xb5\x32\x91\x70\x03\xa4\xc1\x06\x42\x75\xd7\x2f\xd8\xed\x6b\xb7\xe3\x55\xc5\x64\x4a\x8a\x44\x07\x81\x74\x20\xbe\x5e\xf6\x69\x06\x94\x24\x28\xcb\x10\x6e\x89\xad\x5a\xdd\x6c\x73\x7f\x17\x11\x76\x29\x48\x43\xac\x01\xca\x6a\xa8\xfa\xe3\x32\x31\xf2\x08\x9d\xbd\x4d\xc3\xc9\x0d\x50\x25\x23\xee\x97\xcd\x6a\xe0\xeb\x8b\x34\x30\x54\x13\x03\xad\x81\xb1\x12\xa2\x10\x69\x1c\x38\xb1\x42\xd7\xe8\x3e\xe5\x85\x13\x22\x4d\x38\x76\x43\x2b\x10\xa7\xfd\x5d\x35\xab\xcd\x23\x04\x4b\x12\xdc\x8a\x6e\x17\xf7\xab\xdd\x66\xbb\x78\xde\xee\xb6\xeb\x7b\x17\xbc\x0a\xc6\x44\x66\x77\x17\x8f\x36\xba\x3a\xe3\x4c\x18\xda\x61\xc1\x64\x88\xa1\xe6\x8f\xfc\x72\xde\x7e\x59\xe3\x15\x59\x4c\xd0\xdf\xbf\x3a\x61\xcd\x69\x12\xf3\x89\x8c\x0b\xcc\xae\x76\x0e\x9a\xe1\x0a\xf9\xe4\x34\x22\xa6\x18\x36\x74\x31\xc3\x2e\xd9\x0d\xf6\x01\x91\x09\x03\xd9\x94\x96\x24\x0e\x8c\x99\xba\x71\x1a\x96\x33\x1e\x9f\xe0\x41\x4c\x88\x83\xa4\xb6\xb0\x77\x4c\xd2\x93\x51\x89\x91\xbd\xfb\x71\xfa\x13\x90\x30\x73\x98\x9d\x12\x9c\x07\xf8\x05\x16\xea\x67\xe7\xcc\x8e\xfc\x12\x21\x52\x2a\x8d\xc6\x4d\xb9\xdf\x42\x7d\x18\x32\xc7\x34\x7e\x10\x98\x2a\x50\x0b\x4d\xfb\x50\x1d\x5f\xca\xba\x2a\x8a\x80\x8e\x1b\x7d\x27\x77\x2e\xe3\x0c\xd7\xba\xad\xdc\xbf\x0f\xe6\xa4\xcc\x12\x84\xe4\xef\x2e\xd3\xf1\x86\x7e\x79\xeb\xe8\xd7\xe7\xb7\x24\x01\x24\x51\xc4\xb5\x9a\x95\x3f\x20\x1f\xf3\xe3\xdb\x51\x3a\xd4\x14\x2d\x7a\xfe\x01\x05\x76\x09\xfc\x6d\x8c\xed\x18\xcd\x90\xd8\xfd\x4a\xd0\xc8\xb8\xa9\x9e\x2f\xf9\x13\x0a\x05\xff\x03\x53\x21\xc7\xcc\x8b\x29\x30\xce\x48\xaf\xb8\xc1\x52\xa3\xb9\x6d\xab\x43\x65\xd1\xed\x63\x60\x90\x24\x31\x8d\x1d\x75\xc4\x1e\xba\x6d\x41\x0c\xba\xa4\xec\xa0\x80\xca\xc4\xa6\x4a\xae\xeb\xd3\xfe\x17\xd1\x90\x0c\x44\x8c\xfb\xee\x4d\x55\xc3\xc7\x00\x13\x26\x43\x12\x1b\x04\x7b\x5e\x2e\xf9\xb1\x07\x9c\xc9\x90\x4a\xac\x85\x6f\xab\x72\xd4\x62\x2c\xa3\x48\x26\x56\x6b\xc9\xc6\xe2\xee\x48\x4c\x35\xc6\x12\x0a\x5a\x2e\x5f\x7b\x94\x4f\x77\xd1\xbe\x78\x29\x13\x2a\x11\x7f\xb5\x7b\xe5\xb5\x7a\x86\xff\x9c\xf2\xda\x90\x9f\x8f\xb7\x7c\x99\x50\x43\x02\xd3\x40\x8b\xc8\x94\xf7\x9d\x0d\x8a\x07\xe5\x60\x99\x30\x8d\x9a\x72\xf7\x9b\x3f\xdc\xec\xf6\xd7\xc9\x74\xe4\x71\xbc\xfb\x27\xab\xac\xe7\x5f\x33\xa5\x82\x1b\xc1\x8d\x73\x0d\x8e\x28\x4a\x48\x9a\xa5\xbe\x32\x69\x1f\xe1\x19\xf0\xcb\x3e\x54\xa3\x49\x2c\x29\xa7\x88\x4c\x81\x52\xad\x97\x8f\x98\x0e\x0c\xfd\x31\x88\xf0\xda\xd6\x91\x34\x54\x66\xbf\x96\x8f\x9e\x9d\x5f\x32\x8d\x8c\xd0\x60\x03\xed\x0f\x9e\x7b\x35\xa6\xd1\xbc\x92\x2c\x8c\xb1\xe1\xfd\x2d\x2f\x8a\x35\xb6\x3d\xdd\xe4\x9e\x47\x42\x32\x91\x45\xb6\xd8\xb0\x33\xec\xaa\x63\x4b\x2e\xb3\x54\x46\x86\x0b\xd2\x0a\x71\x43\x9d\x57\xaa\x79\x18\xc8\x88\x0a\x99\xb1\xc0\x26\xc2\x0d\x2a\x61\xb2\x9b\x49\x01\x80\x38\x6f\x4c\x21\x1a\x3a\x93\x21\x88\x51\x4a\xa2\x20\xb0\xa2\x0b\xae\x35\xfd\x17\xd9\x70\x29\x99\x11\xf5\x5e\x6d\xbf\x2d\x1f\x1f\x90\xcb\xfb\x2a\xaf\x95\x0b\xc0\x27\xf3\x5c\x66\x1c\xbd\xaa\xf5\xf2\xf1\x1d\xe0\x2d\x5c\xf9\x70\x40\x4a\x91\xa0\x61\xfe\xc6\x8b\x2a\xba\x7e\xaa\xda\xa7\xaa\xe5\xed\xa4\x72\x27\x15\x53\x4e\xc8\x76\xd3\xf2\xda\xa2\x4e\x67\x9a\xe8\x25\xa4\x19\x06\x87\xa6\x79\x02\xab\xa1\xc5\x0c\x22\x51\x6a\xc5\x10\x7a\xb1\xb8\x1d\xae\x3b\xad\xb2\x30\xf4\x54\xb7\xc3\x7d\x57\x91\x48\x26\x7d\xaf\xf3\x53\xc1\xdb\xfe\xf2\x53\x6f\x4b\x91\x24\x45\xa7\x15\xd1\x24\xbb\x5e\x65\xe5\x6f\x93\x61\x56\xd0\xcb\x24\x18\x4c\x8c\x33\x07\x3c\x51\x44\x27\x58\x62\xe0\xcd\xdb\x10\xb4\xa6\x22\x95\xe0\x7b\xe9\x5e\xc8\x13\xc8\x53\x91\x9f\x0e\x8b\xb9\x13\xc4\x54\x61\x59\x0b\x4a\x59\x29\x9b\x3f\xfe\xa4\x28\xa1\x62\x45\x0c\xa8\x15\xb3\xe3\x45\xc5\x5b\xc3\xe2\xed\x2e\x9a\x50\x23\x42\x29\xf2\xb6\x81\xfa\x67\x1f\x4f\xaa\x84\x65\x08\xa8\x6e\x4e\x22\xfc\xe4\xe4\x94\x72\xf4\xd4\xef\x17\x7f\xec\x16\x77\x77\x8f\x3f\x56\xd7\xbb\xa7\xe7\xd5\x6e\x90\x12\x57\xa9\x54\xd8\x1b\x2a\x07\xbb\xb4\x62\x91\x57\x58\x37\xa1\x62\xb3\xd3\xd5\xa4\xf7\x4d\x31\x1a\xa1\xf5\xb8\x96\x12\x4b\x3e\x83\x57\xc5\x54\xca\x89\x2f\x10\x5b\xe0\x88\x1a\xed\xa7\x8a\x69\x03\x59\xf4\x9e\x80\x0d\xfd\xac\x0e\xd2\xf8\x5a\x59\x96\x60\x5e\xb3\xdd\xd7\x68\x65\x90\xa9\xf3\x0e\xb4\x7f\x4f\x9c\x52\x4c\xc9\x5b\x3c\x8c\xf1\x26\xa2\x71\xd2\x53\x71\x49\x30\xf9\xa7\xcc\xa6\x83\xde\xdc\xf8\x3a\xa2\x0b\xfa\x6d\xc9\x7b\xdd\x34\xa7\x41\xe2\x4b\x89\x34\xc2\xba\xea\x3b\xe4\x4f\x46\x12\xc3\x1d\x90\x46\x28\xd6\x75\x3a\x76\x8f\x39\x34\x93\x4a\x28\xc3\xdf\x63\x42\xff\x9d\xa5\x7f\xdf\xd5\x55\x75\x18\xdb\x20\x25\x25\xc3\x77\xda\x99\xde\x5a\x8e\x36\xdd\x4f\x90\xff\x4a\x45\x1a\xf1\x03\x16\x76\xe4\x44\x0c\xed\xdc\xb6\xfa\x53\x9f\x3b\xd5\x0a\x88\xc0\x44\x13\xd6\x5e\x11\xe7\xe5\x0e\x50\x82\x7d\xa9\x77\xe7\x37\x9b\xc1\x5e\xd5\x32\x0c\xa3\xab\x61\xc3\xf2\x5c\x43\xfc\x9c\x73\xab\x34\x31\x3d\x4e\x50\xaa\x9c\x97\x06\x63\xdf\x46\xa1\x98\xc8\x38\x09\xa5\x19\xc5\x9e\x2f\xae\xd4\x5c\x67\x8b\xd2\x3c\x46\xdb\xf0\xef\x2a\x2f\x41\xf9\x22\x77\x73\xd7\x4f\x3f\xad\x52\xb4\x2c\xbe\x45\x6e\xc4\x1a\x2d\x94\x86\x04\x29\xa2\x8e\xb9\xac\x8e\xcd\x2e\x6f\x76\x58\x13\xcc\x47\xad\x85\x40\x02\xc3\xa1\xbb\x33\x86\xf0\x0d\xc6\xfa\x32\x6e\x54\x68\xa4\xee\xfb\x14\xcb\x20\x69\x0f\x24\xe3\x59\xd4\x67\x6c\x07\x04\x97\xb3\x21\x00\x04\x71\x80\x59\x98\x95\xda\x43\x01\x63\xa8\x1f\x04\xb6\xd9\xf4\xee\xee\xfb\xee\x67\x14\x78\xf2\x1f\x08\x43\x81\x19\x94\x53\xd9\xf4\xed\x8b\x10\xc6\x0a\xa5\xbf\x0c\x3b\xeb\xb2\xad\xea\x89\x43\x0f\x61\x42\x12\xa3\xb8\xf9\x83\xd7\x45\x55\xab\x4b\x25\x6e\x01\x61\x16\x61\x2d\xae\xcf\x22\x6f\xaa\xc3\x67\xa2\xc5\xe3\x6d\x1b\xa2\xd8\x78\x12\xdd\x72\xea\x3e\xc0\x8f\xde\x38\xbb\x11\x54\x0a\x62\x1b\x78\x2d\xc9\xa6\xc6\x24\x9e\x3d\x1e\x07\x86\xa7\xcc\x2e\xd9\x61\x8a\x14\x62\x49\x54\x30\x20\x9e\x6e\x36\xa7\xc3\x4d\x75\x49\x93\xdf\x8d\x4c\x30\x74\xf2\x3c\x1b\x3f\xab\xb7\xcf\x7d\x11\xfb\xa3\x24\xcb\x06\x7a\xb8\x8b\xe3\x71\xf5\x01\x72\x1e\xcc\x05\x09\x37\xcd\x41\x6d\x75\xe5\x00\x20\x93\x11\x34\xd6\x78\x0b\x28\x3c\x59\xa3\x46\xcb\x4e\xba\x04\x0d\xb3\x9d\x29\xff\x72\x83\x13\x8d\x75\x4a\xb7\x99\x19\xa8\xd6\xd4\x45\x1a\xd9\x01\xa0\x82\x63\xf2\x51\x59\xa2\x23\x23\x89\xaf\xb9\x37\x60\x40\x75\x24\xa5\xd3\x0e\x3a\x1e\xad\x5a\x65\xaf\x57\x34\x79\x69\x69\x9c\x61\xd7\x21\x6e\x82\x77\x36\x22\xf9\x9b\x3f\x28\x30\x9f\xe2\xb6\x93\x5d\x44\x76\xab\xed\x37\x7f\x38\x0d\x14\x1f\x95\x3b\x93\xf9\x24\x2e\xa4\xc0\x92\x70\x1c\x10\x22\x13\xf2\x97\x91\x2a\xb0\x54\xe2\xae\x25\xa0\x7d\x07\x98\xb8\x40\xc0\x32\xf3\xb9\x9d\x98\xd1\x05\x43\xe3\x27\x09\x37\xfb\xf3\x2c\x49\x30\xf9\xdc\xe4\x87\x1b\xcf\x3b\x3e\xc8\x34\x01\x8f\x58\xe0\x45\x98\xce\x93\x3d\x04\x78\xa4\x22\x1b\x98\xdd\xe4\x1f\xa0\x7a\x75\x42\x01\x5c\x12\x03\x58\xc5\xe6\x9a\x25\x3f\x5e\xf5\x0d\x3c\xc0\xa5\x43\x6f\x74\x26\xe2\xe7\x94\x2c\x58\x00\x57\x24\xd1\x8e\x9f\x51\x39\x6f\xde\x48\x93\xf7\x21\x9a\x1d\x2c\x08\x8b\x8c\x50\x67\x71\x53\x57\x07\x04\x2f\xde\x5d\x80\x17\x91\xc3\x8b\xd9\x82\xd8\x25\x0c\x11\x44\x20\x70\xeb\xea\x05\x8e\x91\x99\x0b\x37\x8b\x26\xdf\xcf\xc7\xa6\x20\x52\x2a\x30\x23\xda\x34\xf9\xbe\xbc\x87\x96\xcf\x9b\x3b\x99\x46\x89\xa5\x74\xfd\x9e\x2b\xa8\x9c\x73\x00\x2a\xa1\x81\x69\xcb\xdd\xe7\x25\x3c\x9f\x90\x5d\xd0\x1f\x4c\x39\xc6\x65\x87\xbc\x84\x9a\x17\xa1\x0d\x6a\xc6\xa7\x56\xa0\xb1\x8f\x95\x5b\x0c\x8c\x43\xe2\x7e\x95\x42\x04\x1d\x32\x5c\xf2\x57\xeb\x6b\x23\x97\x30\x4c\xc0\x68\x12\x67\x41\x6a\xdf\x85\x7c\xf5\x61\x94\x26\x09\x85\xa8\xd7\xa3\xb9\x98\x64\x7e\x4b\xd1\x84\x0a\x69\x70\x46\xfc\xbd\xdc\xe4\x9f\x6b\x5a\xbb\xf1\x32\x35\xcc\x1a\x95\x87\xf6\x6b\xa2\x38\x86\x42\x80\x9b\xb1\xff\x2b\x24\x18\xdd\x6e\x90\xb8\x17\x5d\xa9\x1b\x98\xa9\xca\x8d\xcf\x1f\x44\xa6\x01\xe7\x90\x97\xf7\x79\x09\x83\x66\x2f\x1d\xf0\x38\x4b\x2c\x8a\x7f\xd5\xbe\x6e\xdf\x61\xa0\x9e\x3c\x22\x70\x1a\xfc\xf7\xe8\x13\xe8\x28\x08\x13\xd7\xb6\x5c\x95\x70\x2e\xfb\x08\x5f\xc7\x34\x43\x0a\x80\xbc\x69\x4e\x97\x94\x1d\xc3\x0d\x5f\x27\x81\xa1\x48\x3d\xe4\x65\xfb\x52\xae\x97\x8f\x9d\xdf\x37\x8f\x90\x1a\x3f\x5d\x12\x86\x66\x03\x2f\xe1\xfd\xb7\x4a\xbe\xc1\xf9\x33\xab\xf2\x97\xff\x9d\x5c\x20\x02\x43\x8e\x55\x9d\xca\x76\x51\x14\xcb\x22\xbf\xae\x5d\x18\xad\x13\x69\xf6\xdf\x7f\x73\xf9\x76\xac\xda\xdb\xd3\x45\x3a\x5e\xd3\x24\x94\x8e\x08\x61\x8d\x7a\xa1\x0e\xab\xa3\x29\x64\x48\x7e\xf9\x3a\x75\x90\x74\x4a\x08\x42\x78\x8d\x6b\x77\xb1\xae\x87\xf3\x2d\x25\x01\x58\x3f\x7c\xc2\x81\x35\xb2\x15\x3a\xa5\x49\x68\xba\xd0\x0a\x7d\x6d\xa8\x44\xe7\x57\xb6\x66\x81\x31\x6e\xbb\xc1\x56\xfe\x49\x37\x8b\xfb\x05\x53\xd0\x17\x76\xbf\x41\xee\xf6\x76\xcd\x32\xa3\x68\xe0\x76\xb9\xa7\xaa\xfc\x6f\x3e\x79\xd8\x2c\x21\x98\x26\x13\xe6\xbe\x1f\x35\x2a\x39\x8e\x6d\x98\xe6\x91\x44\x6b\x71\xe0\x1f\x46\xfd\x0c\x51\x07\xee\x32\x9c\x4b\x69\x1a\xe7\x0c\xf7\x1d\xc2\x63\x2e\x2d\xa1\x16\x11\xc5\x47\xfb\x09\x75\xc9\x0f\xde\xb1\x1c\xba\x60\x5a\x85\xcc\xc9\xa6\x7c\xb7\x2e\x23\xd2\xf3\x1f\xdb\xa1\xf6\xe6\xd0\xa6\x68\xc5\x8d\x62\xdf\xdd\xe3\xe3\xd6\x9f\x46\x52\x14\x09\xd6\x56\x4d\x6a\x9c\xfe\xd2\x40\x8c\x26\xc1\x81\xbf\xc1\x10\xf8\xed\x0e\xab\x0c\xdb\x55\x0e\x55\xe7\x48\x5a\xce\x82\xf1\x10\x1d\x52\x4c\x25\xff\x98\xca\x63\xfc\x22\xfd\xe2\x7e\x1e\x07\x44\xb9\x76\xb2\xf1\xcc\x99\x04\xbb\x5a\x2b\xc3\x70\x6b\xf8\xc8\xf7\x10\x78\x44\xb8\x24\x84\x08\x91\xb8\x36\xc3\xfc\xbf\xce\x62\x4a\x42\xa2\x94\xc4\xee\x35\x1a\x85\xb6\x96\xd7\xf3\x24\x93\x92\x90\x24\x44\x8f\xbf\x9b\xd8\xdb\xaa\x0b\x8e\xc7\x52\xa6\x92\x10\x15\xf2\x9e\x5a\xa1\x0b\x81\xea\x91\x14\x94\x24\x41\xca\x42\x32\x10\xde\xd8\x56\x57\xdb\x65\xb5\x9a\x75\x4a\x24\x09\x74\x8a\x1b\x6d\xe7\xf3\x1a\xa9\xa1\x49\x6f\x9a\x24\x61\x1a\x83\xf2\x14\xfd\x46\x1f\x61\xc6\x7c\x49\x12\x05\x29\x26\x49\x16\xb9\xea\xb3\x1f\x92\x44\xb1\xc0\xdf\x2b\x9b\xc5\x19\x4d\x01\x49\xa2\x24\xca\x5c\x7a\x18\x4b\xeb\x3f\xf3\x2e\xb6\xc0\xb8\xd7\x64\xa4\x6c\x21\x22\x24\xfe\x17\x1c\x43\x47\xfc\x66\x8f\x3f\xa1\x8e\xbc\x3f\x26\x49\x94\x46\x92\xba\x0e\x69\x2f\x5b\x38\x7a\x43\x71\xc0\x7d\x4f\x7e\x7d\x5f\xa9\x5c\x9f\xad\x0e\xff\xe4\xc9\x63\x16\x63\xfa\xb6\xae\x72\xe3\x7a\x8c\x8c\x89\x24\x71\x16\x22\x96\x69\xd1\x1e\xf8\xb0\x51\xaa\x3b\x12\x61\x2b\x9d\x6d\x19\xb7\xc8\xa9\x21\x6f\xdb\xdf\xad\xea\xd4\xa4\x76\x6f\x7f\x4f\x43\x2e\x89\x07\x2b\x1b\x48\xae\x3b\x37\xa5\x3c\x36\x00\xb3\xbb\x7f\x8c\x2e\x9a\x91\x58\x1b\x76\x2a\x94\x9f\xbf\xa9\xea\xc9\xf3\x64\x54\x33\x2b\x4d\x38\x8c\xcf\x3e\xf7\x13\x24\xe1\x44\x60\x5b\xb7\xe1\xd1\xb0\xfd\xa8\xee\x82\x3c\x08\xd1\x6f\xfe\xed\xf7\xd1\x7d\x88\x48\x79\xf0\xe5\x16\x09\x68\xd6\xfa\xa9\xe0\x12\x5e\x31\xac\x5c\x37\x57\x5c\x0d\xc6\xa2\xcd\x34\x5a\x2f\x4f\xd0\x5e\x76\x2e\x4a\x22\xe2\xe0\x72\x7b\xfd\x62\x59\x77\xbf\x08\x49\x6a\xa7\x35\x7e\xfb\x61\x46\x46\x12\x91\x84\x58\x26\x43\x19\xcc\x1c\xfd\x93\x6d\x7e\xec\xe1\x8a\x7e\x1c\x37\xf0\x7f\x34\x0b\x13\xb2\x4f\x49\x04\x04\x58\x86\xbf\x1b\xf5\x51\x4a\x22\xa9\x91\x68\x30\x3b\xbe\xdb\x33\xc6\xb8\x9c\x4b\x02\x71\x49\xa4\x56\x44\xf4\x9a\x20\x50\xb7\x79\x6f\x48\x14\xcd\xc0\xf4\x5c\x0d\x89\x13\xbd\xf4\x1e\x73\xc3\x38\x91\x6a\x40\x8b\x65\x60\x9f\x4f\x3c\xbf\x6c\xcd\xf8\x2a\x26\xec\x4e\x14\xe1\x1e\xd1\x7d\xc4\x0d\xd7\xb0\x39\x89\xd9\xdc\x9b\x24\x0a\x42\x74\xad\xb4\x2f\x45\x75\xdb\x7b\xaf\xab\x29\x09\x70\x86\xa9\x62\x51\xc3\xa0\x5c\x7b\xa9\x1e\x7c\x99\x04\x91\x44\x07\x46\x66\xbc\xbb\x8f\xab\xbc\x6d\x1e\xeb\xcd\x69\x40\xbb\x26\x89\xa6\x44\x59\xd2\x7b\x39\x14\xb2\x35\x87\x03\x12\xc6\x18\x3a\x4b\x28\x9b\xaa\x06\xb5\x7c\xe5\xed\x3d\x34\x0d\x62\xa2\x47\x0f\x12\x90\x90\x61\xeb\xcc\x53\x95\x97\x6d\x01\x4d\x33\xd7\x8a\x34\xca\xff\x8c\x96\x57\x40\x32\x43\x89\x68\x3a\x45\x90\x52\xc5\x36\x5d\xab\x25\xee\xc7\x97\x4a\xfd\x7f\x71\xb3\xba\xf8\x66\x9f\xfd\x3b\x7e\xa0\x20\x8c\x31\xb8\xde\x79\x4e\x48\x8f\xa6\x74\xaf\x27\xb0\xd2\xd8\x1a\xa1\xd9\x03\x18\x8f\x0c\x02\x45\x90\xb8\xf1\x1a\x8a\x96\xfb\x3d\xd1\x1e\x0c\x75\x60\x94\x37\x6c\x16\xf3\x9e\x7f\x20\xe3\x8d\x97\x29\x6d\xe6\x5e\x5c\x7f\x6b\x51\x68\x04\x51\x4f\xa5\x63\x5e\x99\x1c\x97\x12\x39\xb6\xcc\x7d\x8d\xed\x6e\x10\x29\x4d\x2d\x6d\xd8\xea\x03\xe4\xa9\xcd\x7f\xc2\xa3\xd6\xb9\x9c\xa4\x43\x64\x10\x13\x1e\x74\xb7\x79\xb5\xdd\xfc\x36\xb4\x51\x41\x9c\x29\x54\x77\xc6\x64\x3c\x9c\x0e\xef\xaf\x95\xec\xf7\xac\x20\xd6\x19\x22\x50\xee\x17\x7f\xec\x96\x8b\xe7\x8d\xfb\x7b\x92\x98\x16\x8f\xce\x43\x1f\x8a\x94\x4f\x9e\x2e\xe1\x1a\x6b\x1f\x3a\x2f\x0e\x47\x9e\x2b\xff\x73\x49\x85\xd1\x77\x16\xe6\xad\xfc\x6d\x9e\xbf\x7f\x7e\x4d\x06\x34\xa6\xb8\x16\x76\x86\xc1\xb5\x8b\x61\x91\x37\xd6\xbc\xf0\xf9\xf6\x52\x19\xa4\x54\x01\x98\x6c\xee\xb6\xb2\xbd\x9a\xd2\xcb\x5b\xc9\x20\xe5\x29\x8f\x7a\x01\xbb\xcd\xd2\x63\xd0\x65\x90\x0a\x43\x14\x6f\x2b\x24\x9d\xff\x82\x5b\xe5\xe4\x6b\xb1\x38\x15\x16\xae\xf9\xa3\xaa\xdf\xa0\x36\xdc\xee\xe3\xfb\x60\x99\xe1\x48\xb0\xe6\xcd\x4f\x25\x26\x4d\xee\x1e\x09\x58\xba\xf1\xe0\x6f\x2d\x8b\x18\x02\xbe\x16\x4a\x3d\xc0\xfb\x06\xf6\x23\xc9\xbb\x5f\x2d\x9a\xa1\x1d\x09\xb8\x8a\xd3\xde\x39\xc7\x3c\x81\xe9\x8b\x9b\xff\x82\x22\x32\x6a\x7d\xcd\x91\xd7\xaa\x6a\xa0\xec\x71\x28\x32\x50\x99\xd0\x06\xff\x75\x5b\x15\xca\x94\x8e\xeb\xf3\xe4\x71\x21\x66\xa6\x97\x1d\x33\x03\x3f\x8c\x6c\xc0\xd4\xe4\x00\xe5\x98\xe8\x6c\x81\xd7\xd8\x76\xe5\xfe\x9e\xc6\x46\x4b\x08\x9b\x22\x7a\x40\x89\x39\x1c\x92\x58\xb3\xd4\xfa\x4c\x86\x6e\x62\xac\x18\x3f\xd8\x11\x42\x22\xe2\xc4\x76\xf1\x5d\xf0\xa7\x8d\x6e\x26\x24\x5a\x22\x53\x94\xf5\x59\x10\xea\x6f\x6b\x14\x76\x44\x40\x65\x14\x3b\xe0\x19\x26\xfe\x2f\x49\xfc\x65\x18\xf0\x2c\x88\x7a\x79\xb0\x30\xa1\x7f\x9b\x9b\xce\x61\xa8\x33\x47\x7a\xf0\x8c\xf2\xb9\x9d\xf1\xe8\xc5\x51\xbe\x57\xed\x27\xa4\x11\x32\x8c\x04\xc7\xfa\xde\xef\xfc\x98\xb7\xbc\x80\x0f\x4f\x39\x24\xc3\x98\x73\xe2\x7b\x23\x9e\xac\x00\x2d\x2f\x60\x33\xd8\xd9\xc3\x84\x1b\xdd\x31\xae\x54\x3b\x74\x0d\xc2\x34\x10\x60\xe5\xef\xeb\xbc\x3d\x9b\x49\x32\x76\x59\xc3\x34\x95\x16\xdb\xda\xe4\x45\x0e\xbe\x72\x22\xc3\x54\x18\xfe\x32\xf9\xda\xfd\xae\xdc\x63\x89\xeb\x78\x6a\xfd\x71\x6d\x75\xea\x61\xcf\xe5\xf9\x19\x8e\xe3\x44\xb5\x0c\x19\x11\x1a\x4b\xf4\x55\x0d\xf7\x79\x69\xba\x48\xc6\xaf\x8d\x05\x01\xd2\xa3\x94\xf0\xd1\x3a\x9a\x5f\xa7\xb6\xb4\x56\x81\x3b\x53\x16\x9a\xb6\x44\x95\xff\x44\x47\xd9\xff\x3d\x65\xd8\x71\xa4\xa0\xc8\x7f\x42\x7d\x5e\xfb\x59\x95\x69\xed\x15\xcd\xf9\x47\x7e\x3a\xe0\xad\x0f\xca\x95\x32\xe4\x31\xa1\x96\xc4\xe5\xf1\x08\xe5\x8c\x2d\x08\xb9\x4c\x62\x18\xe4\xb1\x3f\x03\x94\x4d\x7e\xa5\x4d\xc7\xa3\x63\x16\x40\x5e\xe0\xd5\x7f\xae\x7c\x85\x41\x86\x22\x60\x68\x27\x6e\xa1\x7d\x79\xbe\xfb\x64\x0e\x8b\xc4\x60\xf2\x2d\xab\xfb\x5d\x2e\x6a\x3e\x5d\x9a\xa1\x10\x19\xd6\xbe\xaa\x23\x52\x04\xfc\xd7\x7f\x3e\x21\x55\x18\xf6\xa6\x70\xc9\x4b\xdf\x81\x00\x93\x73\xc8\x90\x09\xbf\x14\xae\x4e\xe7\xc9\x5b\x90\x4c\xbb\xee\x96\xd5\x7e\xdf\x3c\x6a\x3d\xfd\x7d\x46\x02\x3a\x64\xba\xf3\x1f\x48\x2a\xc1\xd2\xbe\x0c\x81\xaa\x54\x46\xcb\xc2\xdf\x27\xc8\x94\x39\x0f\xfb\x86\xe7\x45\xf7\x4a\xca\x66\x24\x7c\x22\x43\xd0\x80\xcc\x18\xf7\xc8\x62\x78\xf0\xd5\x41\x19\xea\x28\x13\xc6\x7e\x19\x2c\x43\xed\x75\xe5\x64\xa8\x99\x51\xc4\x34\x4d\x59\xb7\x75\x75\xba\xe8\x9a\xf9\x5f\xff\x35\x67\x8e\x08\xd1\x98\x02\xba\x07\x95\xa3\x10\xe2\x65\x9b\x80\x8c\x48\x66\x68\x78\x25\x2f\x4d\xa0\xec\xfe\xce\x15\x26\xe9\x56\xed\x6b\xf3\x9f\x7a\xe9\x55\x33\x64\x44\x64\xec\xc2\x72\x74\xdc\x9a\x6d\xb5\x39\x82\x4b\x8a\xc8\x28\x48\x99\x76\xfc\x25\x70\x80\xe6\xea\x7c\x09\x78\x97\x51\x18\x72\xec\x45\x43\x63\x50\x40\xe9\xe4\x89\x64\x14\x2a\xc3\xd2\xf7\x51\x63\xe5\xd6\x10\x81\x4c\xd6\x64\x14\x42\x0c\xcc\x45\x9d\xbb\xbc\xc4\xb4\x36\xf4\x25\x7a\x0f\x8c\x97\x51\x14\xc6\x78\xa5\x6e\xf2\xdd\x54\xb5\x01\xa0\x1a\x2a\x2f\x3b\x22\x0e\x39\xe2\x9d\xae\x16\x9b\x95\xff\x5b\xc4\x31\xd1\xff\xcc\x5b\x88\xdd\x1f\x93\x24\x45\xcf\xfb\xd6\xd1\x30\x0d\x9a\xce\x64\x94\xa4\x46\x0f\xaf\xa9\xa4\xf4\x2b\x38\x4a\x52\x49\xed\x2e\xbc\x46\x07\xf7\x19\xf6\x43\x54\x9d\x8c\x68\x90\x51\xc3\x9a\xbe\x39\xd6\xe0\x43\xb5\x28\x8d\x23\x47\xc6\xb0\x05\x7e\xe8\x29\xe8\x64\xc4\x48\x88\x5d\x4c\xf7\x7c\x08\x37\x93\x11\x8b\x79\x04\xee\xad\x6e\x2b\xc7\xf9\xeb\x52\x13\xc6\x34\xfe\x8f\x3e\xaf\x3b\x35\xb0\xc4\xa6\xc6\xdb\x5e\x23\x79\xf2\x59\x38\x89\x11\x30\xfa\xb4\x18\x45\xca\x11\xb7\xb8\x05\x2c\x56\x56\xea\x1a\x24\xe6\x1c\xc6\x6e\x66\xc4\xa9\x4e\xad\xe4\x87\xdd\xe3\xb9\xc7\x6a\xcb\x88\x2b\x6d\xb2\xd3\x2a\x47\x53\x33\x15\xe1\x1b\xff\x1b\x90\x2f\x31\xcf\x32\xe2\x3a\x76\x34\x3b\x16\x94\xf7\xfb\x49\x55\x13\x5f\x2e\x12\xc2\x70\x56\x1e\x0c\x1d\xeb\x50\x45\x48\x46\x9d\x7b\x0a\x0e\xf9\x8b\xcf\x7b\x3f\x30\xcf\x9f\x36\xd3\xca\x2e\x5c\x47\x77\xf5\xed\x2c\x91\xc8\x69\x7c\x4d\x15\x27\xc0\x3c\xfc\xee\xa9\xf3\x02\x8d\xb8\xfe\xf4\x6d\xab\x44\xe3\x8e\xd3\xb4\x79\x51\xd8\x76\xad\x67\xe0\x6a\x38\xfb\x75\x44\x11\x7a\x84\x8c\xca\xc3\x1d\x39\xd2\x89\xc2\xad\xc5\xad\x99\x67\x68\xda\x47\x3d\x6a\xc9\x91\x91\xb6\x42\x49\x9d\x59\xfd\x38\xe6\xb5\xd7\xf7\x40\x3f\x64\x92\xb2\x93\x31\x91\x31\x46\xe8\x9b\x43\xe7\x0a\x74\x7b\xc9\x97\x26\x2a\x26\x4a\xa0\x51\xfe\x06\x6a\xef\xfb\x63\x82\x2f\xdb\xc0\x64\x1c\x84\x80\xa0\x4d\xa3\xdd\xef\x76\x64\x04\x6e\x5a\x88\x98\x8c\x43\xcd\x10\xb0\x6e\x50\xf5\x6b\x59\xb9\x03\x51\xa6\x68\x3a\x48\xac\x77\x33\xa9\xf1\x07\x01\x9c\x5b\x6d\x1f\xf3\x51\x4f\x70\x58\x32\x8e\x23\x86\xde\x16\x36\x5a\x6f\x2b\xe7\xaa\x0c\x92\x38\x71\x9c\x81\xb9\xc8\xa0\xc3\x70\x5d\xea\xea\x51\xcf\x87\xf4\x71\xcc\x0d\x4d\x50\x5b\xf3\x1e\xfe\x2f\x63\x4a\x08\x2a\xea\xaf\x9a\x96\xb7\xf0\x87\xff\x73\x6a\x82\x22\x53\x80\xf2\xa5\xef\xc9\x7d\x52\xa1\xd1\x8e\xc2\x01\xea\x3d\x94\xf2\xec\xad\xe3\x64\x60\x1a\x66\x68\x4c\x76\x4b\x5e\x14\xbd\x3a\xe6\x68\xb9\xc4\x69\x12\x63\x9a\x0f\x4a\x05\x03\xec\x92\x8c\x53\x9e\x66\x49\x4f\x01\x03\x0a\x27\xd9\x74\x62\xa4\x60\x10\xf4\xe8\xdc\x4c\x6f\x78\xf2\x7d\x19\x49\x92\xd4\x16\xee\x31\xe6\x32\x59\xc9\x47\xed\x38\xed\xfd\xf7\x62\x54\x22\x35\xfe\x03\xbc\x5f\x0d\xed\x4d\xcc\xd3\x0c\x43\x69\xd3\xd7\xc1\xe7\xc2\xb4\x98\x4b\xd3\x0c\x28\x78\x29\xab\x7a\x6b\xde\xfc\xc4\x3d\x8c\x45\xcc\xb8\x73\x93\x96\xbc\xbc\x1e\xfb\x58\x6e\x10\xe7\x88\x63\xd8\x74\x7e\xb4\x5c\xb5\xaf\x3e\x32\xf7\xa7\xd1\x0a\x7b\x9f\x7d\x29\xda\x12\x5d\x77\x7e\x46\x55\xc2\x50\x36\x22\xfb\xd7\xb8\xb7\x63\x90\x8c\x8e\xa5\x2d\x7e\x36\x9e\xb1\xf1\x0a\xd9\xf3\x3f\xa7\x5d\x92\xb1\xb4\x59\x85\xbc\xb1\x79\x1c\x7d\x72\x1e\x5e\xac\x18\x43\x8a\x86\x53\x83\x85\x89\x09\x02\x5d\xc6\x90\x18\x5c\xd2\x4e\x81\xac\x94\xc9\x56\x60\x4e\x75\x38\xd9\x41\xc4\x28\xc3\x67\xba\x75\x27\x73\x4b\x0b\x03\xd7\x42\xd0\xa2\x09\x9b\x9f\x8c\xee\xa9\xbb\x07\xad\xcc\x1c\xef\x2c\x4c\x37\x39\xae\xab\x71\xc5\x41\x26\x24\xa2\xd8\x16\xd8\x93\xc2\xb9\xcf\x93\x90\xc4\xe8\xb8\xaf\x1f\xae\x1f\x97\x8b\x8d\x4b\x4a\x27\x41\x14\x23\xd2\xc7\x52\x2b\x6d\x5a\x38\xfa\x43\x71\x84\x19\x8a\x97\xf2\x27\x9f\x41\x03\xd8\x51\x11\x51\xe0\x13\x91\xbd\xa4\x91\x3b\x1a\x26\x32\x70\xec\x71\xf5\x5b\x59\x29\x98\x67\x19\x97\x49\x94\x30\x7c\xbc\x9b\xd7\xf2\x7d\x90\xa4\x4f\x62\x1e\xd1\x1e\x02\xb2\xcd\x0f\x13\x02\x78\x99\xc4\x9a\xe3\xee\x52\xe4\x4d\xbb\x7c\xbc\x59\xbb\x5f\x26\x94\x31\xa3\x1f\x5b\x7d\x9c\xfd\x1f\xb3\x20\xb5\xbd\x11\xab\x5e\xcd\x71\xfe\x96\x28\x61\xa1\xa5\xb6\xe2\xb5\x7c\x3d\xaf\x4a\x65\x3b\x7a\xdc\x00\x1e\x19\x41\x01\xbb\x18\x26\xd3\x22\xa1\x92\x22\xb2\xc6\x1d\x87\x9f\x50\xb6\x83\x6e\x1f\x99\x50\x10\x59\xd4\x4b\x18\xe3\x14\x5f\x5e\x60\xc8\x65\x92\x42\x88\xcc\x5e\xf7\x7c\xff\xdf\x9c\xbb\x5f\xb3\x90\xa3\x81\x5f\xbf\x9d\x6a\xbe\x69\xab\xba\xdf\xb5\x12\x26\x4c\x13\x88\x41\x40\xda\xc4\xe2\xec\x2e\x13\xb8\x76\x14\x99\x30\x1d\x0b\x2b\x38\xbc\xb9\xec\x3b\x92\x49\x16\x88\xd0\xb4\x0e\x74\xc6\x6f\x03\x9d\x19\x74\xf8\x19\x37\x24\xa1\x58\xb7\xb9\xca\x4b\x5e\x9f\xcd\xf2\xfd\x1e\x7e\x59\x26\x96\x49\x96\x06\xa1\xbd\x6e\x3e\x48\x02\x26\x59\x9a\x48\xea\xb8\x0b\xba\x35\x61\x71\x8c\xee\x38\x0f\x13\x2c\xae\x9a\x60\xd8\xc5\x54\xee\xa0\x04\x6c\x51\x37\x01\x83\x91\x0e\x98\x5c\xfe\x9f\x51\xdf\x92\x93\xfc\xeb\xef\xa3\x57\x2e\xd3\x40\xb8\x4f\xf3\x9a\x17\x6a\xad\xbe\x56\x96\x97\x89\xcc\x08\xba\x10\x7d\x36\xf5\xeb\xf1\x2a\x93\x88\x44\xb1\x85\xd5\x69\x9a\x72\xfc\x8a\x54\x06\xb8\x82\xab\x81\x2a\xe8\x20\xf5\x93\x28\xcd\x11\x79\xdd\x05\x67\x06\x25\xd7\x4c\x3a\x4f\xb3\xfe\x3b\x2b\x2d\xb0\x51\x43\x88\xb1\x1b\x93\x68\xcd\xa5\x55\x83\xed\xdc\xb8\x81\x48\x86\xa4\x24\xd5\xc8\x3b\xd5\x85\xf7\x06\x98\xed\x8f\x08\x89\x3d\x8e\xe2\x54\x97\x37\x75\x75\xf8\x12\x4c\x2d\x69\x20\x63\xcc\xe0\xff\xe3\xa4\xf2\x5f\xf5\x06\x4b\x1a\x12\x70\xf2\x03\xd8\x87\x8e\xa1\xfd\x3c\x03\xbd\xa4\x61\xc8\xb2\x01\x73\xb8\xc9\x2b\x0d\x73\x73\xee\x15\xd0\x30\x49\x6c\xc9\xe9\x90\x97\x57\xa7\x7a\x2e\xe8\xa3\xa1\x08\xd1\xed\x7a\x7a\x5e\xed\xd6\xcb\xc7\xdd\xd5\xe3\xc3\xcb\xc6\x29\xe8\x2e\x6e\x5d\x10\x44\xe3\x54\xa1\x69\xff\x6d\xb5\x19\x6e\xaf\x34\xd6\x09\x7a\x57\xa2\xe6\xce\x57\xa1\x09\x49\x55\xea\x1a\x91\x76\xed\x27\x22\x4b\x93\xe7\x4a\x82\x04\xdb\x1d\x9e\xbe\x3f\x7d\xed\x29\xd2\x24\x62\x51\xe4\x36\x12\x0b\xfc\x1f\xe8\x18\x4b\x9a\xd8\x5e\x35\x74\x4e\x4c\x5f\xb3\xaf\x06\xf4\x63\x00\x83\x5d\x2e\x65\xae\xfa\x6d\x84\x26\x76\x97\xba\x59\x3f\x2c\xee\xd6\x7f\xae\xc6\xf6\x8e\xd2\x98\x62\x0b\xca\x6d\x55\xcd\xbd\xcd\x34\x94\x9a\xf6\xed\xce\xd0\x34\x8b\xba\xe6\xe7\x69\x26\xcd\x7f\xa2\x94\x0b\x2c\xc1\xdd\x3f\xde\x0f\x76\x04\x9a\x42\x84\x94\xcf\x26\x7f\xf9\xdc\x19\xd5\xd3\x84\x2d\x47\x52\x16\x64\xa9\xf5\x00\x6e\xb9\xc1\x4a\xce\xc0\x33\x24\x65\x0c\xd0\xf9\x7b\x47\x0b\xf2\x50\x59\xdf\x6c\xbc\xf8\x28\xe3\x29\xba\xeb\x46\xaf\xeb\x08\xb2\xaf\x7f\xd1\x8c\x71\xb4\x5d\x3b\xff\x2d\x31\x87\x3b\xcb\x61\x3c\x0f\xb2\x19\x1b\x43\xca\xe3\x98\x59\xae\x48\x2c\x2a\x4e\xd2\xc1\x93\xc1\xd2\xa8\x3f\xd6\x3e\x3b\xb9\x2c\x80\x4f\x85\x28\xdc\x60\x2d\x31\x8b\xe4\x18\x00\x76\xa8\x7c\x36\xbf\xfa\xfe\x19\xb9\xcf\x20\x02\x83\x06\x3e\xde\xe7\xe5\xba\xbc\x71\x0e\x02\x15\x81\x0a\x6c\x43\xae\x1a\x39\xf7\x7e\x3e\x88\x28\xc3\xd7\xd6\x9c\xc4\x0f\xc8\x6d\x4c\x38\x9e\x13\x02\x08\xb5\x79\xfc\x5e\x32\x62\xbe\x5e\x40\x65\xc0\xb0\x81\xcc\x30\xe3\x39\x3d\xbf\xdd\xfd\xcb\xdd\x76\x3d\xd0\x84\x90\x54\x46\xa1\x54\x9e\xb5\xbe\x0b\x0b\x0b\xe8\xd6\xc0\x3c\x7c\xd3\xfe\x08\xe2\x88\x03\xae\xf5\xf5\x72\xb5\x5b\x7e\x5b\x3c\xdc\xa2\x12\xc0\xfa\xe1\x76\x00\x41\x93\x14\x12\x85\xed\x02\x86\xef\xe7\x5b\xde\x8c\xfa\x35\xbf\xb4\xf8\x14\x52\xe1\xd5\x1a\x30\x28\x43\x00\xda\x5f\x01\x84\x48\x0a\x22\x0e\x4c\xd3\xf2\xbf\x4f\xcd\xac\x90\x9e\xa4\x3a\xe2\x88\xd3\xaa\xea\x7c\x9f\x97\xd6\x91\xb4\x98\x69\x37\xc4\x72\x70\xae\x65\x85\x79\xac\x1e\x51\x2a\xa9\x4e\xd3\xd0\x96\xe1\xbf\xe7\xf5\xe9\x13\x57\x2d\x25\x31\x71\x91\xcc\xfd\x79\x59\x57\xd2\xad\x85\x34\x88\x8d\x12\x49\xe3\x9e\x6f\x14\x74\xb2\xf1\xb7\x4f\x83\xc4\xb4\xc9\x58\x58\xc0\xd0\x72\xa6\x61\x60\xfa\x4c\xf7\x75\xf5\xde\xad\xa4\x9e\xf7\x72\x03\xe5\xbc\x90\xad\x4c\xc3\x94\x10\x87\xb5\xb2\x98\xc3\xeb\x2b\x77\xc6\x88\x0a\xea\x11\xa9\x4f\x50\xcb\xc9\xdd\x44\x69\x92\x9a\x04\x80\x61\xda\xbe\xcf\xcb\xf6\xc5\xc8\x61\x7f\x72\xb9\x88\x99\x02\xaf\x5b\xf7\xf7\xc8\xfb\x58\x9c\xbf\x0e\xcb\xd3\x38\x15\xc4\x25\x54\x4c\xfa\xf3\xea\xfc\x49\x73\x8a\x4c\x63\xc1\xb0\x8f\xb9\x16\x5d\x5c\x5c\x1f\x70\x89\x77\xae\x9e\xfb\x68\x69\x42\x01\x12\x07\x1a\x59\x72\xf9\x6a\x52\xd4\x79\x7b\xbe\xaa\x4a\xf5\x03\x43\x55\x8c\x53\xdd\xf8\x4c\xb0\x21\xcb\x40\x33\x74\xdf\x52\x1a\x05\x21\xb7\x98\x43\x2f\x3e\x82\xa5\x14\x37\x40\x28\xcc\x2e\xf5\x2c\x02\x89\x3b\x94\x26\x91\x29\x8d\xda\x37\x68\x39\x28\xfc\x61\x46\x4c\x0b\x30\x16\xba\x16\x4d\x03\xc8\x50\x6b\x92\x9e\xb3\xd5\x94\x34\xe5\x0c\x7f\x82\xc0\x7d\xc4\x40\x83\xda\xfb\xb9\x9c\x32\x1a\x52\x9b\x53\x7f\x7a\x7c\xbc\xb3\xe4\x78\xc1\x28\x6b\x98\x32\x96\x06\x06\x17\x3e\x32\x52\xc3\x52\x54\xca\x32\x30\x24\x0d\x50\x14\xc7\x9a\xc8\x2a\x2f\x9b\xc5\x9e\xe7\x65\x63\xab\x0c\xe3\x8f\x92\xd1\x8c\xf8\x9c\xac\xdd\xc4\x26\x23\x40\x73\x9b\x2d\x56\x88\x7f\x5e\x6d\xbf\xe1\x13\xfb\xa5\x92\xe9\xcc\x71\x7f\xd8\xf7\xe4\x8b\x69\xc8\x1f\x5c\x4f\xca\x17\x29\x8f\x38\xe6\x5c\xba\xd0\xb8\xf3\x57\xa6\x64\x9d\x32\x15\x21\x43\xa0\xde\xdb\x4f\x79\x7f\xba\xc8\x28\xb9\x41\x4c\xc6\xc4\xe3\x5a\x6e\x10\xad\x35\x2f\x45\x2b\x53\x91\x51\x4c\x65\x36\xc7\xbc\xce\xdb\x13\x2f\x76\xfb\x53\xae\x06\xfe\x62\x2a\x44\xe8\xb4\x95\x6f\xa1\x24\x03\x01\xe0\xee\x98\x44\x55\x39\x4c\x21\x2f\x54\x33\xd8\xc3\x53\xa1\x53\xf4\xbe\x36\x58\x97\x2d\xd4\xa6\xe4\xc7\xe6\xb5\x6a\xe7\x31\x18\xf3\x4f\x22\x89\x21\x84\x50\xd5\x7d\xbe\xaf\x79\x3f\xd1\x64\x08\x7a\xc8\x64\xb9\x83\x8f\x2e\xb8\xdd\x8d\xea\x69\xa9\xa4\x51\x6a\xe3\x69\x6b\x4c\xcd\xdd\x8f\x5f\x81\x52\xa9\x10\x03\xbc\xf7\x35\xb4\x3c\x9f\x68\x22\xca\x54\x41\x00\x06\x2d\x88\xd0\x16\xbd\x84\x6e\x92\x97\xe7\x27\x18\xb0\x54\xc8\x54\x69\x86\x9b\xdd\x2b\x6f\x36\xd7\xcb\xe5\xd7\x3e\x5f\xaa\xb4\x88\x6d\xb3\xd3\x6d\xe5\xda\x35\x64\x0a\x12\x64\x32\x24\x50\x1b\xf5\x81\xdb\x41\x3a\x34\xda\x33\x77\xd5\x7e\x00\xa8\xf2\xd5\x9a\x29\x3e\x7a\x66\x3f\x4c\x75\x96\x19\x88\x11\x66\xc6\x6f\x6a\x80\x45\x89\x94\xdd\xe6\x35\x4d\xae\x07\x1c\x97\xfe\x55\xfe\xc7\x69\xeb\x72\x88\xa9\x06\xc9\x4c\x2b\xae\xce\x4b\x30\x2a\x3d\xfe\x98\xa6\x81\x67\xbd\x6c\xe5\xeb\x5a\x39\x13\xc3\x48\x10\x1a\x42\xe3\xf5\xf6\xdb\xea\xee\x09\xb7\x7b\x77\x2c\x20\x94\xc5\x1e\x46\x54\xfb\x7a\xec\xbc\x89\x66\x41\x48\x64\xe6\x1c\x37\x74\x83\x6f\xaa\xba\x17\x18\x93\x2c\x88\x8d\xb0\x9f\xaa\xae\xe1\x27\x14\xd5\x71\xa6\xb0\xc9\x02\xce\x6d\x4b\xf1\xb1\xa8\xce\xbe\x8b\x6e\x32\x48\xc4\x98\xdc\xf2\x4c\xbd\x92\x05\x60\x48\x00\x0d\xad\x01\x0a\x53\x59\x9d\x85\x99\x26\x7b\xc9\xc2\x58\x62\xa6\xfd\x95\x37\xaf\x03\xf5\x71\xe6\x0e\x0b\x8d\x82\x47\xbb\x23\x3f\x9b\xb9\xbc\xc3\x2a\x3c\x76\x3c\x4d\x6e\x26\x94\xe6\xb1\x3a\xeb\x62\x52\x71\x4f\xc7\xc3\x90\xed\x49\xb2\x38\xd0\x18\x3b\x77\x53\xc4\xe4\x9b\xb0\x03\xd4\xca\xfe\x4e\xce\x17\x27\x4a\xb1\x5e\xb0\x56\x34\xb2\xce\x07\xbc\x7d\x92\xc5\xa9\x06\xc3\xb7\xf1\xf3\x75\xe8\x6f\xb0\x24\xe6\x88\x33\xbd\xb6\x97\xf1\x7f\x57\xa1\x36\xea\x47\xfb\x53\xd1\xbd\x12\x4b\xe9\xe8\x0f\xc7\x34\xf6\xaf\xce\xa0\x08\x8c\x03\xb9\xa9\x6e\xf8\xc4\x20\x33\x4a\x0d\xc7\x61\xde\x58\x2a\x94\xc7\xd2\xf5\x4f\x48\x46\x53\x23\xb8\x9a\x1b\x38\x8a\x03\x0d\x8f\x17\x3a\xa3\x10\x38\x16\xd6\x67\xeb\x8f\x9c\x8f\x30\x1d\xa4\x3d\xd9\x92\xdd\x6b\x4d\x89\xd4\x31\xd9\x2c\xab\xc6\x99\x3f\x96\x26\x86\x92\xc6\x00\x38\x97\x7f\x3e\xdf\x5f\x2a\x4c\xfb\xa1\x3a\xb3\xe9\x8f\x65\x75\xaa\x3b\x43\x3c\x8e\x0c\x5c\x48\xc4\x58\x10\x23\x82\xef\xbb\x69\xab\xa9\xea\xd1\x5e\xc7\x18\x0d\x8c\xa4\xd2\x7b\xde\xca\x57\x27\x7c\xdc\x77\xd4\x49\xc6\xb8\xa1\x6b\xdf\x3c\x7e\xff\x19\x04\xa3\x2f\x92\x91\xcc\x69\xa7\x6c\x5e\xab\x7a\x62\x09\x59\x26\x99\x36\x55\x5b\xf9\x0a\x05\xfc\x32\x70\x67\x3c\x94\x58\x4f\xcc\x7d\x10\xee\xbf\x2e\x97\xb1\xb2\x9a\xa6\x73\xc9\x0e\x26\x42\x86\xb4\x28\xfb\xfc\x17\xfa\x36\x92\x09\xab\xcc\xc9\x95\xba\xcf\x4b\xa8\x07\x6b\x93\xc6\x13\xe6\x15\x4f\xab\x2b\x99\x80\xc4\xe8\x7a\xf1\x12\xb3\x0a\x9f\x91\x2b\x0c\x4d\x22\x93\x1c\xc2\xc8\x9b\x44\xe3\x57\xcf\x64\xeb\x98\x14\x21\x56\xc1\xab\x23\x42\x6b\xbd\xb1\x51\x2c\xd4\xec\x32\xfe\x1a\x22\x2f\x7b\x8e\x18\xfb\x1b\x08\x38\xb6\x56\xe7\xae\x95\x6c\x5d\x36\x6d\xb7\x5b\x0d\x91\xc3\x0c\x94\x4e\x7b\x95\xbe\x31\x36\x64\xfc\x6a\x75\xa4\xb9\xdd\x3e\xfa\xfe\x81\x31\x8c\x84\xe9\x58\xe1\x9a\xad\xca\x5f\x68\x0c\x4d\xee\x55\xb3\x04\x71\xa2\x66\xe3\x85\x77\x7f\x3e\xc1\x10\x93\xe7\x7b\xe9\x0a\xf5\x85\xe2\xa4\x64\x1a\x08\x35\xfc\x8e\x67\x0c\xdb\x86\xa3\x26\x46\x33\x23\x01\xc1\x7d\xe4\x90\x3b\x2c\xad\x61\x6e\x3e\xc0\x15\x6f\x40\x59\x6c\xfb\xff\xc4\xc2\x22\x33\x12\xa6\x29\x32\x88\x5b\x5d\xba\xd1\x2b\xcc\x48\x68\xf4\xa0\x0e\x7e\xbe\xcd\x3f\x47\x46\x78\x9a\x19\x5a\x1b\xf9\x73\xa7\xeb\xea\xb0\x6b\x72\x05\x3b\xf9\x3a\x42\xca\xf6\x13\x2c\x0b\x42\x23\x68\x7e\xe0\xf5\xdb\xb2\xee\xdc\xd9\x4f\xce\x1c\x88\x04\xd1\xcf\x87\xbc\xcc\xcb\x7d\xe7\x39\xba\x49\x96\x85\x22\x43\xd7\xca\x94\x6b\x56\xb5\x0c\xc9\xca\x83\x06\xb2\x28\x4a\x4d\xe1\xb9\xaf\x96\x2e\xf6\xbd\xa4\xdb\xd8\xff\xce\x22\x4e\x70\x22\x7f\x83\xe2\x08\xf5\x06\x78\x2d\x5f\x87\x36\x23\x8b\x44\x84\x33\xfa\x16\x50\xd6\x06\x4d\x66\xff\x95\xd8\xd0\xc9\xce\x22\xa9\x31\xc0\xbe\xe9\x26\x2e\xcf\xcb\x47\xfd\x03\x78\xd1\xdf\x5a\x1c\x18\xf1\xa0\xab\x3f\xfe\x1c\x5d\x23\x96\x10\xf7\xfa\x90\xdd\x2a\x77\xa0\xe9\xde\xae\x65\x69\x18\x71\xeb\x4e\xa3\x74\x95\xc9\x4f\x7e\xfd\x95\xd3\xd0\xb4\x6b\x16\xbc\x69\x31\xab\xb8\xd3\x81\x0b\x66\xb2\x34\xd4\x98\xbb\x6f\xf3\x03\x3c\xea\x3b\xde\xb4\x33\x28\xd5\x2c\x8d\x28\x26\xfe\xcc\xbd\xcd\x24\x98\xb2\x34\x23\xa8\x2e\x65\xdb\x0d\x07\x8b\x36\x4b\xa5\xd6\x16\x00\xb7\x34\xb4\x49\x06\xae\x7d\x5d\xc9\xd3\x08\x4f\x38\xca\xaa\x64\x2c\x91\x99\x55\xb1\xd5\x9d\x4b\xe5\x36\xba\x8c\x51\x83\xbf\xc2\xb8\x9b\x17\x41\xff\x35\xdc\x00\x00\xdd\x43\x68\x46\xcd\xa7\x9f\xcc\xb3\x2c\xd2\x51\xaf\xb5\xea\xa2\xf9\xd1\x49\xb3\x34\x06\x31\xe0\x17\xfe\xb1\x5a\x0f\x91\x59\x59\x26\x34\x64\x5e\x2a\x03\x3f\x0e\xaf\xf9\xe1\x22\x83\xfb\xc9\x47\xca\x24\x25\x72\xe0\x27\xde\xd4\xd5\xc1\x33\x35\xf6\xc3\x38\x05\x97\x34\xbb\x06\xcd\x4f\x05\xc6\x96\xb9\xc1\x5e\x8c\xe9\x4d\x65\x26\x12\x89\xad\xc2\x47\x84\xb8\x74\xb7\xe4\x19\x3a\x64\x26\xc0\xb6\x9e\x82\xe5\xe6\x98\x41\xe5\x64\x92\xa6\xa9\x27\xba\xbb\x86\x01\x98\xe1\x64\xba\x88\x27\xdf\x4c\x45\x09\x9f\x2a\xba\x2f\x7b\xe7\x6d\xfe\xe5\xab\x54\x63\x00\x65\x5a\xc7\x4e\x07\x2c\x88\xaa\x8d\xe1\xa0\xb8\xe9\x57\xbc\xe2\x89\x93\x17\xbc\xe7\xf9\xa8\x9f\xf8\xc2\xfe\x67\x90\x66\xa9\x85\x54\x2c\xd4\xc1\x47\x64\x19\x28\x2d\x2d\xc2\x6c\x73\xe0\x45\xf1\x19\x24\x73\x7c\x8f\x9c\x90\x40\xf9\x17\xe1\xd5\x39\x7e\x41\x32\x33\xcf\xa3\x20\x39\x09\x33\xdc\x3f\x6a\xfe\xbe\x81\x76\xd1\x3a\x80\xdb\x2c\x40\xc5\xfd\x26\x61\x08\xde\x32\xc1\xdd\x4d\x55\xff\x80\x71\x03\x9b\xe4\x44\x00\x8a\xef\x6c\x57\x8b\xfb\xdd\xed\xf3\xe3\xcb\xd3\x88\x52\x5b\x72\x04\xd8\xa3\xab\xd6\xc0\x83\x23\xe1\x91\x3c\x70\x1c\xb6\x2e\xd2\x6a\x66\x36\x7b\x1e\x26\x1a\x4d\xc0\x76\xf1\x7c\xbb\xda\xee\x16\xd7\xd7\xcf\xab\x8d\xc3\x65\xf3\x90\x49\x81\xd2\x55\x05\xf0\x01\xe4\xf3\xd3\xc9\xff\x49\x2f\x84\x3b\x1b\x50\xdc\x98\x0f\xfc\x0d\x7e\x54\xf5\x5b\xcf\xfe\x7d\xf9\x65\x22\x06\xb8\x70\xa0\x7d\x1d\x54\x82\x79\x04\x80\xd4\x64\x16\x72\x61\x79\x14\x2d\x4c\xd7\x8e\x89\xd3\x38\xe4\xc3\x3c\x9a\x47\xb3\x4c\x9e\x3d\xce\x28\xca\x53\x6c\x4f\x75\x89\xdb\x2d\xca\x9d\xf4\xd6\x8f\x27\x51\x84\x55\xdd\x6e\x77\x5e\x7d\xb4\x35\x9f\x0b\x9d\x78\x22\x53\xac\x82\xb6\xd0\xb4\xab\xba\xae\xea\x21\xa5\xf5\x03\x3f\x80\x23\xc1\x72\x37\x48\x21\x0e\xad\xb5\xdf\xd9\x52\xd5\xae\x1d\x8a\x4e\xda\x71\x69\xa4\x31\x8a\xb0\x0f\x7b\x35\x80\x9b\x72\x96\xc4\xd8\x23\x65\xdb\xbb\x7c\x8d\x6f\x3c\x25\x33\xa2\xd1\x64\xde\x55\xfb\x5b\x5b\x78\xff\xaa\x55\x56\xf2\x2c\x31\x64\x14\x7b\x23\x82\x04\xa6\x1b\xf2\x13\x38\xbd\xfd\x0d\x27\x80\x2c\xec\x8f\x7f\xdc\x3e\xde\x5d\x0f\xbb\xbf\x25\xe7\xda\x10\xa3\x95\xf0\xbe\x56\x5b\x5e\xbe\x7d\x3b\x39\xd6\x3d\xc9\x45\xc0\x89\x53\xf6\x5f\x7d\x1c\x51\x54\xa7\xc6\xfd\x69\x74\x7e\xc1\x35\xf6\x95\x3d\xc0\xfb\xb7\x7c\xff\x8a\x0d\x2b\xf3\xda\x2a\x92\xcb\x54\xe3\x6e\xdb\x9c\x0f\xa2\x2a\x46\x1d\x7c\x5c\x0a\xa3\x18\x66\x85\x65\x36\x79\xf9\xca\x0b\x3e\xdc\xac\xb9\x0a\x52\xac\xf8\x7f\x3b\xd5\xa8\x61\x90\xf7\x47\x52\x86\x05\xca\x23\x3f\x2b\x23\x58\xdb\xac\xb6\xdf\xc6\xd6\x89\x03\x37\x25\xa2\xe7\xd5\x66\xf5\xfc\x7d\x75\xbd\xb3\xed\x5d\x37\x8f\xcf\xbb\xe5\x3f\x1e\x1e\xb7\xcf\x2f\x1b\xbf\x6c\x91\x77\xdd\xee\x77\x50\xb4\xfc\xbe\x2a\xdb\xd7\x4f\x56\x83\x4e\xa9\xb0\xbc\xc1\x58\x96\x19\x4d\x78\x41\x82\x80\x72\x87\xde\x42\x56\x1a\x7f\x24\x4c\xa8\x11\xda\x2d\xf8\x79\xfb\x61\x73\x87\xf6\x12\xb6\x72\xfc\xaf\xf1\xff\xff\xfb\x5f\x18\xe3\xce\x9e\x06\x88\x39\x39\x58\xa2\x7b\xcc\xc8\xab\x3e\x62\x10\x44\x30\x6a\x5f\xda\xa4\xc2\x25\x82\x38\x09\xac\x5c\xff\x6c\x27\xb6\x1b\x96\x50\x24\xeb\xbf\xe5\xcd\x4d\x5e\xf8\xb2\x95\x08\x44\x84\x9c\x8f\xdb\xe7\xc7\x87\xf5\xd2\x81\xb3\x45\x48\x14\x46\x90\x2d\x7f\x83\x2b\x1b\x9d\x8d\x4a\xe7\xc3\x92\x79\xff\x9f\x5f\x99\x75\x11\xb1\x0c\xa7\xcd\xe1\x80\xc2\x56\xc8\x73\xe1\x0e\x65\x52\x18\xf9\x56\x4c\xbe\x40\x6d\x72\xb8\x4d\x77\xf9\x5d\x8d\x60\x8b\x5d\xcd\xc7\x34\xb7\x52\x44\xca\x44\x96\x16\xc9\x8d\x73\xd4\x1b\x07\x11\x07\x11\x66\xd9\x1e\xaa\x76\x51\x22\x6f\xbc\xe9\x6a\x76\x87\x43\x83\xc3\xba\x5f\x3c\x2c\xfa\xbf\x65\x28\x3b\xb5\xd9\x2e\x6e\x57\xbb\x60\x77\xbf\xf8\xa3\x4f\xe3\x88\x98\xb2\xc4\x46\xab\xc8\xf9\xed\xfe\x9e\x30\x89\x9d\x1b\xc8\x7a\xe5\x6a\xa8\xf3\x7b\xb9\x48\xb4\xc6\x89\x7d\xbd\xba\xdb\xfa\xcb\xd2\x10\xb0\x2f\x4b\x79\x8f\x85\x1f\xa0\xbd\x00\xf1\x0a\x1a\x91\x20\xf8\x85\xa6\xc8\x74\xf3\x60\xee\xb7\x5c\x87\x56\xb9\x10\x5b\x88\xfd\xb5\x45\x82\xdb\xc3\xf3\xe2\xfb\x7a\xb2\x69\x09\x2a\x63\x53\x61\x2d\x8a\x4d\x5b\xb9\x82\x9f\x48\x09\xcf\xfa\xb4\xf7\xd5\xf9\x9a\x37\xaf\xdb\x8f\xf1\xa7\x49\x89\xc6\xfd\xee\x95\x37\xab\x52\xf9\xaa\x83\x48\x13\x82\x71\x87\xed\xc4\xc7\xee\xf0\x41\x8e\xab\x7f\x56\x16\x32\xa4\x6d\x47\xbe\x1a\xbc\xd0\x50\xf8\x41\x0a\x96\x2a\x14\x83\x93\xff\xde\x02\x3f\x0c\x25\xa4\xa4\xc8\x98\x51\x0f\xb3\xdc\x2e\x8a\x1f\x06\xdb\xa3\x1b\xa3\x28\x06\x6f\x3b\x83\x61\xd9\xbe\x95\x97\x22\x5c\x52\xf0\x80\x61\x2e\x44\x76\x2e\x41\x8f\xe7\xe8\x77\x36\x21\x08\x95\xce\xad\x45\xe7\xc0\xa8\xde\x15\x9d\xd7\xe2\xb2\x0f\xa7\x0b\x91\xcf\x31\x13\xb1\x14\x22\xc9\xd0\xf0\x5c\x83\x84\x6e\x79\xa3\xc4\x2b\x5e\xcf\x11\x1c\x7f\x52\x32\x9e\xb5\x72\x42\x48\xa5\x06\x70\x2e\xcc\x65\xae\xf5\xa2\x74\xbb\x89\x10\x2a\x30\x6a\xfe\x0e\x5f\x77\x6f\xf0\xba\x57\x3e\xc9\x36\x79\x11\x32\x88\x31\x02\xec\x7e\xf0\x7d\xfd\x64\x6a\xb4\x9f\x80\xc1\x84\x8c\x8c\x8e\x56\xf3\x6a\x10\xdf\xe3\xb4\x82\x90\x51\xc8\x7c\x15\xbd\x0b\x17\x2f\x39\x44\xa5\x90\x4c\xf3\xf4\xb3\x32\xe7\xd8\x7a\x4a\x9e\x24\xca\xe9\x8c\x3a\x39\x76\x57\x16\xf1\xaf\x58\x05\x09\x72\x40\xf0\xc2\x51\xd1\x7f\xae\x02\x21\x85\x12\xd4\xc9\xf2\x5e\xf3\x96\x4f\x90\x34\x7e\x90\x40\x5e\x45\x0b\xdc\xe9\x9b\xbc\x85\x02\xc8\x2c\xec\xe0\x07\x72\x94\x6d\x78\x5b\x35\xaf\x13\x8f\x54\x00\x64\xd9\xc8\xb3\xbc\x82\xf6\x42\xc0\x4b\x0a\x1d\xa4\x81\xad\xae\x6c\x72\xc7\xd3\xfa\xcb\xc0\xe9\xaf\xe5\x38\x84\x96\xc4\x7c\xac\x6e\xcf\x31\x39\x30\x73\x44\x12\x2a\x1d\x46\xee\xa6\xaa\xbb\xb0\x63\x7c\x5f\x92\x00\x60\x51\x52\x57\x75\x7b\x2a\x61\xd7\x40\x9b\x1f\xf6\xe5\xe1\x82\xe5\xe7\x9f\x41\x1c\x4f\x42\x21\x19\x44\x86\xeb\x7f\x0f\xad\xf1\x8d\x16\x0a\xb5\xbe\xeb\xf3\x5c\x97\x98\x0c\x58\xc2\x9c\xaa\x3a\xca\xcb\xd9\xd0\xaf\x3f\x9f\x34\x9a\x4d\x96\xc8\x61\x84\xd0\x93\x81\xd4\x7c\x98\x79\x5a\xdc\x2d\xc7\x9f\x42\x86\x01\x73\x54\x41\x06\x23\x7a\x03\x30\xe8\xb7\x9e\x0c\x4e\x98\x52\xbe\x84\xb9\x01\x59\x75\x93\x1c\xb9\x2a\xef\xaa\x89\x0e\x9d\x94\xa1\x8c\xb1\x6d\xa9\x3a\xb5\x1b\x25\x1d\x2d\xd6\xe4\x8c\x90\x98\x40\xb2\xe0\x4d\xf3\x9d\xd7\xf9\x25\x7c\x5d\x46\x01\xc1\xc4\xc9\x5b\xde\xb6\xe7\x85\x1c\xf5\x13\xfc\x7d\x32\x94\x99\xb6\xd2\xe7\xd5\xcd\xea\x79\xf5\xec\xa0\x4a\xee\x75\xc4\x24\xcc\xec\xbb\xdf\x1c\xa1\x6c\xc7\x4b\x7e\xec\x39\xc8\x98\x2a\xa4\xf4\xb8\x5e\x5d\x2d\xb6\xab\xee\x54\xeb\xc7\xeb\xdd\xfd\xfa\xe1\x65\xbb\xda\xf8\x33\x72\x2a\x43\xa7\x78\x3e\x94\x9d\xb4\xc7\x93\x98\x60\xd5\x7d\x5b\x19\xb2\xab\xab\xbe\x69\x4f\x26\x89\x49\xec\x74\xaf\xbe\xaa\x8a\x70\x60\x5e\x65\x92\x9a\x36\xb8\x9d\x86\x56\xbe\xa2\x07\x72\x75\x5e\xab\x2e\x6e\x7e\x42\xe2\xd0\xb9\x7c\x95\x4c\x38\xc7\x30\x1b\xe7\x34\x0a\x79\x8f\xea\x89\xb3\xaf\x2c\x0d\x33\xeb\xe1\xd9\xe5\x7c\xcf\xeb\xbd\x77\x5b\x65\x1a\x0a\xa7\xec\xd3\x85\x51\xa6\x1f\x66\xd6\x76\xc8\x34\x32\x3c\x4e\xd2\x90\xdf\x82\xda\xf8\x58\x52\xa6\x90\x0a\x69\xa5\x4f\x2d\x81\x53\xef\x35\xcb\x2c\x90\x0e\xff\x88\x21\xc6\x55\x5d\x59\xe8\xd6\xe8\x3b\x07\xa1\x5b\x15\x19\xa5\x89\xa5\x5b\xe9\x5e\x49\x75\x6a\x7b\x65\x4c\x37\x84\x49\x44\x4f\xad\x9e\x97\x69\x18\xec\x9e\x57\xcb\xd5\xfa\xfb\xea\xda\x1f\xce\xb8\xb6\x30\x80\x07\xd8\xaf\xfd\xdf\x39\x31\xb0\xdf\x57\xde\x7c\xaf\x2e\x0a\x41\x92\x67\xd2\x29\x9b\x63\x83\xda\xc8\x8f\x96\x9c\x33\xc7\x36\xb2\x39\x42\x51\x2c\x84\xc1\x4f\x8c\x16\xac\x08\x12\x7c\x15\x1b\xde\x7a\x41\xe8\x19\xe7\xb8\x73\x51\xb0\xdb\x88\x2b\x85\xf4\xed\xed\x7c\xc4\x22\x85\x4c\x10\xe9\x7a\xe0\x1f\x8b\xb6\xe5\xf2\x0d\x6f\x6c\xc4\x3b\x29\xa5\xd0\xb1\x94\x03\x24\x29\xfa\x8c\x17\x44\x14\x52\x46\xa6\x2a\x75\xed\xdf\x87\x0a\x8c\x94\xfb\x8d\xb1\x75\x23\x6f\x47\xaa\x80\xe3\x8e\xf6\xb0\xfa\xe1\xd7\x98\x62\x40\x7c\x27\x88\xc9\x9b\x3d\xcf\x10\x75\x4f\xe6\x0e\xa4\x40\x2d\xca\xd1\x76\xe4\x76\xee\xcd\xe4\xe5\xeb\x40\x84\xc8\xc9\x5c\x9f\x9b\x96\x17\xd7\xd5\x49\x78\xc9\x31\x29\x75\x66\x14\x97\xac\xba\xc5\x45\x4b\xff\x97\x37\xa0\x08\x13\x12\x81\x64\x9e\x3b\x46\x11\x49\xf0\x4f\xbb\x61\x1f\x83\x0a\x22\x81\x9e\x9c\xb2\xc9\xc0\xeb\x1c\xed\x9f\x3f\xcc\x59\xc4\x7b\x76\xde\x65\x55\x15\xd8\x3f\x3c\x7a\xcf\x2a\x90\x31\x56\x21\xb8\xc3\xbc\xfe\x79\xe7\x5e\xa0\x0a\xc3\x08\x17\xc3\x3b\xe4\xf8\x10\xde\xf7\x53\x61\x1a\xe0\xa5\x75\x0d\xb0\xad\x5e\x9a\x91\x10\xae\x54\x51\x4a\xb0\x3a\xe7\x8c\xfd\x12\x55\xa2\x47\xe9\xbb\xc9\x43\xc7\x20\xd0\x83\x6f\xa0\x54\x17\x54\xa4\x52\x25\x29\xc8\xc0\x37\x18\xdd\xf3\x0f\x4f\x35\x37\xca\x6c\xab\x24\x53\x68\x56\x1f\xb7\xdf\x56\xcf\xcb\xe7\x97\xb5\x27\xe3\x97\x8a\x46\x29\x36\x69\x1c\xf8\x1b\x38\x44\xff\xd8\x76\x5d\x7c\x98\x99\x62\x9a\x4a\xe3\x54\x39\x55\x82\xbc\x79\xbd\x3a\x3f\x55\xd3\xbb\x4d\x13\xa3\x35\x74\x53\x9d\xea\x1f\xfc\xbc\x39\x16\xf9\x65\x4b\xfa\xff\xf8\xaf\x3b\x75\x46\x28\xfd\xbc\x21\xda\x88\xf9\x4e\xd8\x9c\xa5\x4a\x95\xc6\xec\x84\xa5\x41\x8e\xfb\x24\xab\xca\xc2\x2c\x1d\x7e\xaa\x85\xd6\xc3\xe4\x8c\xca\xe2\x38\xf4\x29\xcd\x8f\x1f\x90\x3b\x91\xad\xf1\x23\x67\x32\x48\x92\x41\x5a\xd5\xa7\xe8\xab\xba\x79\xcd\x8f\x93\x49\xc7\x03\x82\x22\xc1\xa6\x8c\x7f\xe8\xac\x79\x0f\x7e\x53\x3c\x8c\xf1\x23\xbe\xac\x7f\xe4\xcd\xeb\xe6\x0b\xf8\xf6\x2f\xff\x9d\x7f\x89\x3c\x22\x06\x4d\x83\xd2\x78\xeb\xe5\x63\x30\x79\x1a\x9e\x30\x39\x6c\x34\xdb\x45\x0e\xb0\xe1\xdf\x1b\x4f\x34\x82\x80\x8e\x9d\x89\xeb\x5c\xec\x11\x63\x82\xe2\x94\x62\xa3\xbc\xe1\x61\xbe\x5f\x3f\xec\xee\xd6\xf7\x6b\xbf\xb2\x04\x31\xbb\x86\xc8\xdb\x87\xaa\x9d\x7c\x2d\x41\x43\xb4\x5b\x95\xd6\x45\x5e\xc2\x33\xf0\xe2\xb0\x19\x68\x45\xcc\xd7\x5f\x95\x4c\x03\xbc\x64\x17\x19\x03\xc7\x8f\xb8\xb4\xc1\xc5\xa5\x0e\x90\xfd\x8d\xca\x8c\x40\xaf\xe7\x49\x0a\x48\xef\x43\x2b\x95\x19\xd1\x1f\x97\x41\x9b\x45\xee\x7f\x06\xa5\x9d\x5b\x3b\x3a\x0e\xb0\x0c\xa7\xaa\xce\x22\xf4\x3d\x12\x4a\x27\x31\xae\x18\xfe\x8e\x1c\xf0\x1a\xea\xda\x12\x57\x7c\x5d\x74\x56\x9a\x6a\x30\x62\xdd\xbc\x86\x6b\xc7\x7d\xea\x4f\x2b\x4d\x56\xae\x75\x6d\x3c\x03\xc0\x89\xd2\x4a\x22\x1a\x01\xa5\x3b\x16\xd7\xf7\xeb\x87\xf5\x66\xfb\xbc\xd8\x3e\x3a\x8b\x01\x24\x34\x12\x91\x58\x1c\xbe\xe5\x07\x70\x18\xd3\xd1\x3d\x00\x51\x09\xd6\x0a\x97\xbc\x9b\xad\x3f\xa7\x6b\x03\x82\x20\x0b\xac\x67\x76\x05\xed\x28\xd4\x9a\xdf\x02\x20\x50\x14\x91\x84\xc8\xe1\xe6\x73\x50\x10\x28\xc0\x0c\x12\x3f\x1e\xa1\xa7\x9a\xb3\x07\x43\x62\xd4\xee\x1a\x2f\x13\x68\x1c\xf0\x91\x65\x86\x90\x68\xec\x8c\x28\x4f\x45\x91\xeb\xb3\xff\x33\x70\xc4\xa2\xa1\xde\x3e\x3f\x0e\x56\x23\x44\x89\x32\x5c\x09\x80\x15\x92\xb1\xd2\xa9\x84\x38\x16\x18\x96\x96\xa7\xc3\xd2\x79\x5b\xfe\x98\x36\xcc\x69\x77\x2f\x77\x2f\xcb\xc7\xb5\x83\x0e\x41\x22\x79\x42\xfb\xd0\x6e\x17\x45\xee\x08\x0d\x4d\x0d\xb9\xd9\x2e\xcd\xd7\x9f\x7f\x3f\x94\x46\xb1\xe9\xef\x38\x1f\xdb\x6a\xc3\xf7\xfc\x1b\xd4\x93\x98\x0d\x68\x1a\xa6\xc4\x35\x44\xa9\xea\xbd\x5c\x37\x2f\x6e\x47\x85\x54\x46\x18\xf7\x6d\x4e\xf5\x4f\x38\xf7\x22\x0d\xee\xb0\xe6\xc9\x90\x23\x69\x9c\xd7\x9b\xa5\x76\x9e\xdc\x22\x8b\x35\x6a\x0a\x4a\xb7\xfb\x1b\x15\xf2\xfe\xe5\x30\x4a\x11\xf7\x50\xf8\x3f\xf0\x00\x41\xac\x82\x8b\x73\xff\xb7\x30\x53\x43\x3c\xca\xdf\xe6\x56\xd7\x17\x4b\x0e\x32\x0e\xa6\x8f\xaf\x06\x5e\xff\x76\x82\x7d\xd5\x98\x7e\x72\x87\x0d\x03\xae\x34\xf6\x66\x3e\x3e\xac\xfe\xf0\x7f\x83\xcc\x71\x24\x58\x45\x06\xd5\x99\x15\x47\xf6\x61\x6d\xdd\xf8\x89\x45\x98\xc5\x89\x2b\x40\x39\x55\x79\x54\x16\xfa\xac\xa4\x32\xa8\x1e\x81\xc8\x00\x83\xc7\xcd\x3b\x58\xc7\xf0\xae\xda\xe7\xf2\x57\xdb\xe6\x85\x92\x8f\x04\xc1\x59\x4a\x07\xed\x42\x2f\x65\xde\x85\xb5\x13\x86\x20\x90\x3c\x09\x33\x9b\xf1\xed\xec\xf7\x53\x0d\x03\x37\x15\x14\x09\x1d\x38\xf7\xe9\xb5\x0f\x95\x40\x85\x99\x69\x94\x75\x79\x9b\x45\xa9\x5c\x51\xc4\xa8\x11\x74\xf3\x76\xea\xc0\x80\x4a\x12\xc4\x63\x6f\x96\x9e\x6e\x5e\x82\xa2\x12\x3d\x12\xe8\xeb\x31\x4f\x50\xbf\x94\x79\x7f\x17\x5c\x23\x47\xea\x06\xb5\x98\xfe\xb2\x27\x39\x5f\xb4\x02\xa5\x53\x11\x0e\xd8\xab\x9b\x91\x64\xc2\x64\x30\xc4\x20\x82\xe1\x83\x3e\x54\x8f\xda\xdc\xe4\xb6\x42\xe8\xf7\xf8\x09\x41\xc8\xc8\x4e\x19\x74\x11\x6c\x7b\xea\x20\x94\x04\x4d\x20\x41\x04\x5a\xbe\xcf\x3f\x44\xd5\x9a\x4e\xe6\xf1\x65\x35\x0d\x12\x61\x01\xc0\x8e\x04\xa0\xaf\x02\x68\xc2\x62\xec\x12\xe9\x76\x54\xab\xc8\xef\x0e\x05\x21\xa5\xe8\x75\xe5\xa3\x90\x4e\x07\x40\xb4\x5d\x43\xf7\xbc\x3c\x8f\x2e\x7a\x39\x7d\x74\xd0\x6d\x1a\x4e\x7b\x1c\x39\x13\x0a\x58\x77\x6f\xff\xe0\x45\x3a\xfd\x48\x05\x96\xd7\xf9\x38\x61\xa4\xbe\x90\x00\xfe\xff\xf5\xaf\xbd\x74\x18\x03\x46\x18\x43\xf5\xd3\x5f\x6d\xcc\xf6\xa7\x71\x20\x59\x0f\x3d\xb0\x9a\xbf\x93\x6c\x91\x1b\x1a\x02\x32\x1c\xad\xb6\xdf\x9e\xef\xd6\x0f\xbf\xcf\xcf\x14\x1d\xa7\x46\x3e\xd5\x4f\x4f\xc7\x17\x32\x1e\x96\x50\x65\xf2\x47\x5d\x5c\x6d\x69\xa6\x9a\xdd\x78\x16\xe9\x24\x13\x86\x60\x5d\x56\xd1\xbd\x8f\xfd\x35\x4d\x02\x6c\xdf\x3a\x20\x15\xe3\xce\xba\xef\x21\x5e\xe8\xfa\x02\x74\xab\x29\x03\xac\x31\x8d\x24\x4d\x27\x8e\xeb\xe4\x21\x28\x08\xcb\xfa\xda\x2e\x51\x20\x66\x8c\x51\x9f\x0c\xd6\x01\xc2\xce\x45\x3e\x82\x52\x6a\xaa\x0d\xac\xec\x2a\x6f\xf7\x35\x77\x29\x07\x9d\x06\x04\xfb\x62\xf1\xc9\x27\x22\xb3\xe3\x1b\x4f\x05\xc3\x3e\xd6\x1d\x1f\xaa\x1f\x5d\xbc\x4a\x16\xca\xcc\x86\x43\xa8\x65\x34\xf0\xb6\xa7\x23\x23\x43\x27\x66\x42\x51\x87\x58\xfb\x8c\x88\xc2\xfd\x88\x1a\x26\xde\xa6\xad\x8e\x9d\x3d\x3e\x0e\xbb\x0f\x35\x63\x41\x10\x0c\xdf\xd4\x5f\x6b\x9b\xd1\x19\x61\x58\xfb\x6c\xa1\x69\x61\xff\x49\xb3\x93\x1b\xab\x22\xc8\x5c\x41\xd1\x68\x84\x83\x32\x92\x9a\x4f\xfc\x5c\x9d\xda\x6f\xbc\x71\x70\x25\x9d\x01\x47\xc6\x07\xf8\x38\xf2\x41\xa5\x43\xf3\x28\xc4\x16\x44\x2f\xe9\x36\x85\xf1\x4c\xbe\xaa\x88\x0d\x9a\x0c\xb3\xe2\xbd\x70\x81\xd4\x22\x51\x41\x3a\x44\xea\x1f\xfa\x1c\xcf\xe4\x14\x90\x62\x2d\xc7\x05\x0e\x3d\xcf\xc6\x27\x6b\x47\x26\x19\xd6\xc5\xf3\x52\x0e\x09\xc7\xc7\x6f\x4e\xa6\x80\xdf\xc3\x08\xe3\x7a\xae\x38\x2d\x21\x15\x96\xa1\xea\xa9\xae\xd4\x49\xb6\xab\x52\x55\x75\x83\xa6\x6a\x5a\xe8\x1e\xa6\xdf\xe6\x5e\xb9\x22\xc6\x29\xb3\xe5\x29\x57\x87\xd4\x8a\x65\x21\x1b\xea\x7b\x57\x23\xaa\x54\x0d\x3a\x44\xbe\x91\xfb\xea\xdf\x79\xeb\x9c\x0a\xad\xa3\x0c\xd3\xbd\x46\xb9\xed\xc7\x6a\xf5\xfb\xce\x9f\x51\x27\x51\x6a\x13\x79\xb7\x50\x92\xe5\x23\x4e\xa2\x61\x66\x4a\xeb\x84\x29\xed\x7c\x37\x4b\x76\xd2\xf8\xdf\xa7\x09\x76\x2b\x5d\xf1\xf2\x0d\xea\x1b\x5e\x1f\x7c\xea\x45\x6b\x19\x20\x27\xf1\xf3\xa9\x69\x72\x5e\x2e\xfd\x34\x51\x84\xa4\x12\x23\xb6\xc5\x7e\x9f\x9f\xca\x7d\x8e\x20\xd5\xd1\xf7\x53\x84\x88\x14\x37\xb1\x95\xa8\x46\xe5\x74\x45\x02\x4a\xb1\xe1\x7a\x65\xac\xd7\x1b\x94\x81\x3f\x24\x74\x68\x34\x07\xd5\xde\x95\xc0\x14\x09\x79\x6a\x14\x53\x2b\xb3\xe2\xed\x8a\x9e\x5d\xf8\xdd\x68\x85\x22\x63\xa5\x25\x8e\xb8\x3d\x0d\xda\xf7\xf1\x30\x72\xfa\x3a\x5b\xd6\x85\x4f\xcd\xa7\x0d\xbe\xcc\xfd\x4a\x29\x0c\x8e\x8a\xaa\x69\xb6\xd5\xd2\xd0\x95\xcd\xda\x3f\x45\xa2\x90\x23\xc4\xa9\xe0\x4d\xdb\x8d\x7c\xa8\xfe\xec\x5c\xea\xc1\x14\x51\x24\xe2\x09\x36\x00\xcb\xa2\x2a\x61\xd4\x6c\x33\x01\xcb\x2a\x12\x29\xa2\x86\x9a\xcf\x96\x96\x7e\x7c\xcd\x38\xe1\x08\x2e\x56\x95\xe1\xc3\xfc\x32\x2a\x52\x24\x4e\xc1\x6c\xe4\xd8\x6e\x6a\x2b\xca\x98\x54\x0a\xa6\x27\xb6\xa4\xd0\x7b\x2c\x25\x78\x54\xcd\x33\x2f\xf7\xfd\x3b\x4d\x08\x73\xc8\xfc\x61\x43\x84\x22\x49\xc2\x42\x9b\x9b\x47\x33\x33\xff\xc5\x12\x0e\x4e\x16\xc8\x02\xfb\xe7\x3a\x01\x15\xa1\x84\x63\xea\x4a\xf0\x56\xbe\xde\x8f\xb2\xfc\x9f\xbd\x3c\x4a\x99\x16\xae\xad\x6f\x8b\xf8\x0d\x7f\xd7\x94\xd3\x50\x3a\x15\xb3\xfa\x70\x55\x89\xeb\xbc\x06\xd9\x99\xc5\xbf\x4d\xce\xa2\x62\x64\x95\xff\x3d\x7f\xcf\x7d\xb2\xdb\x9f\x46\x0b\xdc\x41\x9e\xba\xe5\xf9\xbc\xfa\xb1\x78\xbe\xc6\x4e\xcb\xe5\xca\x8d\x48\xc1\x10\x36\xf2\x5a\xe4\x3a\x1f\xa5\xef\xed\x08\x16\x44\x38\xef\x7f\x0e\xba\x3e\xac\x1b\xa5\x48\xa6\x4c\xa8\xbf\x87\x36\x9a\xdc\x18\x57\x51\x38\xe8\x36\x54\x8f\x7a\xf2\xca\x04\x31\x60\x8c\xfb\xf5\xc3\xea\x79\xb3\xdb\x6c\x17\xbf\xfb\xdb\x12\x81\xc4\x39\x78\x77\xf7\x7d\x17\x05\xc1\x6e\x75\xbd\xde\xee\xfc\x52\x14\x12\xb0\xee\x6c\x02\xc3\xa2\x6a\xdb\x2a\xb8\xe6\x97\x4d\xa1\x73\xc6\x58\x11\x19\x07\x61\xd4\xa7\x0b\x78\xae\x26\x37\x26\x53\x92\x99\x3b\xef\x66\xa0\x69\xda\x7b\xcd\x8f\xee\xea\x52\x86\x10\xf4\xd5\xc8\xe6\xe5\x58\x54\xdc\x6f\x48\x8a\x48\x65\x04\xf1\xee\xab\xb2\x0b\x17\x5c\x61\x61\x7e\x7e\x41\x4c\x11\x7a\xbd\xf8\xbe\x58\xdf\x2d\xae\x30\x47\xf1\x7d\xbd\x79\x7c\x1e\x31\x2c\x2b\x02\x59\x08\x89\xaf\x84\xf5\x2a\x7b\x53\x3c\xa9\x1d\xae\xc3\x10\x9d\x35\x74\x9d\xac\xec\xb0\x0a\x08\x0d\xd1\x4d\x58\xf2\xa2\x30\x7c\xa9\x03\xe0\xe0\xd0\x39\x50\x01\x81\x08\x17\xed\x09\x65\x50\xdc\x09\x02\x4e\x51\x4d\x0a\xed\x3d\x36\xea\xbe\x3c\x6f\x9d\x6f\xae\x82\x40\x19\xd0\xc1\x4d\x55\xb7\xd0\xb3\xa8\xaa\x20\xcc\x24\xe2\xc7\x8e\x75\x5e\x5a\x96\x3b\x7f\x08\x0c\x56\x7d\x0f\x2d\xa2\x55\x46\x04\x09\x2a\x88\x43\x3a\xd2\xe3\x47\x47\xe8\x6b\x0b\x12\xc4\xcc\x88\x27\x23\xbc\xad\x6c\x6e\x78\x5e\xf8\xd3\x65\x49\x10\x5b\x97\xca\x08\xa6\x5e\xa4\x9e\xdc\x48\x41\x31\x63\xde\xf9\x44\x8f\x5e\xc7\x50\x05\xb1\x0a\x52\xe8\x8b\x4e\xb6\x1d\xde\x1d\x4d\x68\x8c\x99\xb6\x6f\x50\x57\x23\x5a\xd8\x2f\xa7\x64\x90\x30\x8a\x49\x7c\x51\x55\x6f\x3f\x00\xde\xbe\xe7\xcd\xa4\xe5\x4b\x05\x89\x8c\xd0\xff\x31\xbb\x12\xf9\x58\x1c\xfa\xf7\x9b\xc8\x04\xdf\xd2\x0c\xf3\x94\xff\xf8\x89\xe2\x68\x57\xef\x86\x8c\x44\x2a\xa0\x61\x8a\x3e\x18\x22\x2f\xb6\xaf\x79\xb3\x3d\xd5\xfe\x60\xaa\x38\xa2\x4b\xcc\x52\xf1\xfe\x27\xa8\x11\x57\x8e\x0a\x52\xcd\x39\x1b\x82\x33\xae\xf9\x79\xd5\xbe\xae\xcb\xcb\xde\x35\x15\x30\x12\xc7\xb6\xe4\x3f\x66\x05\x75\xc7\x93\xc4\x60\xb0\xcc\x35\xae\x81\xab\x22\x2f\xfd\xb5\x18\x8b\x98\xcd\x80\x2d\x4e\x6d\x75\x75\x3a\xf7\x47\x34\x62\x09\xe4\x66\x70\x6b\xcc\x06\xac\x9b\xa2\x9a\x2c\x92\x80\x81\xc4\x3a\x6f\x23\x79\x39\x5e\x06\x81\x1b\xa1\x09\xce\x24\x51\xf4\x9f\x38\x23\x29\x66\xa5\x90\x0f\x1b\x73\xfe\xee\x40\x18\x21\xbd\xee\x01\x54\x7e\x3a\xf4\x19\x3d\x15\xf0\x4c\xf2\xc0\x37\x57\x35\x8f\x25\xbc\x94\x25\x3f\xc0\x7c\x13\xb2\x0a\x44\x1a\x00\x1f\xe4\xa5\x86\xf2\x4e\x9f\xcc\x20\xc1\x19\x7a\x16\x4f\x50\x22\x2a\xe3\x54\x2a\xdb\x56\x35\x08\x82\x67\xbd\x88\x4f\x10\xc3\xe3\xd3\xab\x98\x99\x2c\x9b\xa9\xaf\x19\x5c\xd4\xbc\x80\xbe\x0a\x14\x8b\x5d\x45\xce\xa8\xb2\x54\x35\xf6\xe2\x4e\xaa\xdf\xe3\x67\x06\x09\x06\x6a\x9b\x97\xb0\xf4\x88\x02\x15\x00\x00\xb5\x1b\xf0\x0d\x8c\xca\x81\x2a\xd0\x01\x4d\xbc\xf2\x24\xef\x21\xdb\xee\xb7\x3a\x0c\x43\x5b\x3a\xb3\x13\xf7\xa6\x32\x91\x59\x0e\xcd\xc2\x43\x09\x1a\x3f\x3e\xcb\xb2\xc0\x75\x8a\xfb\x7e\x0d\x6c\xc7\x9e\xc3\xe3\xaa\x90\xe8\x28\x25\x96\x5b\xa4\x54\x05\x2c\x4a\x35\x4b\x7a\xa6\xc2\x20\x60\xa9\xdd\x28\x1d\xd2\x7b\x88\xf5\x54\x61\x10\xc6\x38\xad\x1d\x93\x97\xfb\x73\xac\xb5\xbe\xb8\xa5\x3b\x5f\x77\x56\x61\xc0\x53\x44\x10\x2e\xf2\xba\xe1\x3f\x87\x66\x37\x0c\x13\x8e\x6e\x32\xfc\xe7\x94\x1f\x0f\xa6\x9a\x8e\x0d\x2c\x37\x00\x28\x67\x74\x2c\x72\x6f\xd9\xc2\x90\xa6\x81\x85\xf7\x7c\x4d\x61\xe8\xc6\x4b\x82\xd1\xfa\xe6\x76\xf5\x54\x83\xe7\x8a\x56\x61\x14\xa5\x4c\x0c\x19\x4d\x97\xa6\x09\xf3\x9e\xe7\x85\xa8\x3e\xfc\xb0\x18\x42\xe2\xb2\x9e\x87\x23\x2f\xcf\x73\x2c\x1a\x2a\x8c\x20\x11\x86\x76\xed\x3f\x27\x68\xda\x47\xd1\x85\x09\xcf\x55\x5f\x50\xf9\x0b\xa0\x48\x15\xc6\xb1\x96\x6a\xa4\x0b\x83\xe6\xd1\x7c\xd1\x60\x88\x81\x51\x61\x0c\x06\x77\x6b\xfc\x8b\xc5\xd5\xc6\xdd\x72\x22\x0c\xdf\x83\x28\xf2\x52\x1a\x99\x48\x7f\x08\x0c\x30\xc3\x84\xa7\x36\xce\xf9\x67\xec\x48\xd3\xfe\x19\x52\xeb\x33\x85\x34\x66\xca\x11\xec\x2c\xbf\xd9\x26\xfa\x78\x34\xb3\x43\x2a\x39\xb8\x70\x8c\xe7\xe5\x27\x9b\x54\xb7\x37\xe2\x4a\xbb\x85\xd6\x52\x36\xcc\x80\xca\x54\x48\xb5\x44\xbc\xfd\xa6\xac\xde\xaf\xb8\x83\x33\xab\x90\xa5\x06\x9a\x39\x24\x52\x59\x94\x6a\x08\xad\xf9\x4b\xea\x29\x2a\x64\xca\x04\x7b\x06\xbf\xea\x8d\x75\xc8\x40\x27\xc1\xa7\x59\x39\x3b\x28\x93\x01\x7a\xe2\xf7\x8e\x4b\x4c\x85\x3c\x34\xbc\x9c\x65\x85\x0a\x38\x93\xe7\x11\x36\xa2\xe8\x1c\xff\xaa\xae\xab\xf7\xe7\x19\x20\xe8\xe4\x0e\x05\x03\xaf\xa9\x50\x55\xc5\x73\x65\xb2\x7c\xd7\x50\x70\xb7\x81\x84\x32\x0b\x45\x30\x20\x54\x40\x65\x65\x7e\x38\xf2\x7c\xef\xd7\x94\x14\xa6\xc8\xba\xb3\xb4\xc9\x5f\x34\xd6\xa9\x50\x05\x0a\x3b\x45\xf6\x55\xa5\x1e\xf2\xfd\x6b\x8b\x79\xef\xa7\x3a\xef\x3d\x9c\x50\xc5\x1c\x61\x3f\x16\x43\xb8\xdb\x7b\x92\x29\xd5\x45\x76\xb8\x43\xc9\x82\xe7\x87\x45\x81\x79\x83\xce\xb7\xaa\x1d\xd1\xfb\x65\xaf\x8c\x0a\x15\x64\x49\xe8\xc8\xf8\xac\xa9\x71\x64\x65\x93\x91\x3a\xa4\x76\x4d\xdc\x22\xea\x7f\x28\x43\x67\xc7\x40\xa4\xd1\xdf\x41\xa2\xde\x2e\x16\xbf\x64\x1a\x52\x21\x24\x86\x94\x16\x59\x62\x27\x87\x84\x21\x49\xf0\xb9\x92\x11\xa4\x7f\xfe\xb5\xe9\x30\xc2\x1c\xaf\x21\xcf\xc5\xb4\x94\xb3\xd1\xa1\x4e\x44\xc0\x5d\x69\xbc\x7b\x36\x18\x4a\x98\xd8\xa6\xe6\xc9\xe9\x84\x46\xc0\x4a\x9b\x1f\xa0\x29\x6d\xf2\x42\x45\x24\x61\x40\x06\xb3\xff\xb9\xfb\x40\x63\x3f\xc0\x8d\x04\x89\xe9\xe8\x1d\x72\x99\x0c\x88\x20\xc6\xf7\x1d\x05\x59\x82\x16\x6d\xe7\x54\xf8\xcc\x67\x42\x27\x68\x72\x53\x51\x94\x26\x58\x1c\x7f\xde\x3c\xdd\x6d\x77\x6e\xe2\x47\x11\xd3\x86\x5b\xd7\x34\x49\xf5\x25\x3a\x15\x45\x19\x41\xaf\x40\xe7\xa5\xba\x1a\x88\x56\x4e\x6e\x22\x02\x82\xc9\xa9\x63\xbf\x5d\x20\xda\xd0\xf4\x37\x36\xfe\x6c\x5a\xa0\x6b\xf3\x94\xb7\xf9\x80\x2a\x42\x45\x71\x10\x60\x40\xe9\x9c\x0f\xa7\xb9\x63\x2e\xe3\x41\xb6\xbe\xc7\xcb\x20\xa5\xdc\xd5\xe3\x28\xc5\xdc\x68\x23\x79\xd1\x6d\x34\x83\x72\x79\x77\xd0\x30\xe5\xe2\x7e\x7d\x5d\x57\x47\xac\x83\x98\xdc\xe7\xd0\x29\x8d\x62\xc9\x11\x8e\xb0\x7d\x45\x25\x64\xf7\xe7\x24\x11\x6e\x0d\x77\x2f\xc0\xb7\x4c\xd9\xc3\x34\x30\x74\x58\x9a\xe7\xc5\x86\x6b\xb8\xaf\x14\xf4\xc7\x24\x26\xf7\xc4\xa9\xee\x36\xc0\x25\x3f\xa2\x2c\x87\xd9\x09\xa6\x16\x29\xa2\x71\xa4\xa8\x2b\x72\x6d\xf2\x7d\x17\x27\x5c\x9d\x91\xfe\xed\x13\xe5\xaf\xc9\x47\xa0\x9c\xa5\x5e\x59\x88\xcb\xc2\x89\x87\xda\x93\x0c\x6d\x7d\x94\x32\x86\xc8\x66\x7d\x6a\x4f\x35\x58\x5a\x84\x6e\xb7\xee\xec\xd4\x08\xd2\xab\xa2\x0c\x38\xc6\xc5\xdf\x6e\xb7\xee\x4f\x3c\x0c\xd0\x54\x1a\xab\x52\x20\x64\x1e\xca\xeb\xaa\x28\xb8\x7f\x33\x9c\x19\x35\xde\x9a\x4b\x70\x34\xef\x2a\xe2\x2a\x8e\x60\xc8\x1f\x63\x65\x34\x87\xa5\x82\x91\xc1\x88\x44\x0c\x92\x7b\x80\x8e\xd9\x6b\x02\xa3\x3c\x36\x7e\x7e\x15\x2b\x4c\x87\x3c\x3d\xfe\xb8\x77\x97\xeb\x36\x55\xd1\x4b\x02\xe3\x9b\x9f\xae\x0a\x88\x29\x1a\xbc\x36\x3f\xf6\xb9\x5f\x15\xe9\x40\x62\xb7\x21\x0a\xc2\x2f\x8c\xea\xcb\xec\x8e\x18\xe9\x38\x8e\xb4\x4b\xaa\x5c\x75\x36\x42\x56\xb5\x1a\x7a\x5a\x91\x56\x04\x99\x07\x56\xdf\xef\x37\x48\xab\xe0\x74\x1b\xcc\x64\x75\xbb\x41\x4c\x82\x34\x51\x03\x6e\xf5\xc7\xb2\xfb\x5f\x50\xcb\x7e\x07\x8d\x09\x23\xc2\x79\x8c\x35\x60\x83\xb2\x6d\x4c\xf8\x34\xe4\x8f\x09\x67\x92\x79\x8d\x0c\xf7\x35\xe2\x20\x4c\x31\x19\xba\x5c\x3c\x7c\x5f\x6c\x76\xdf\x56\xeb\xdb\x6f\xee\x23\xc7\x61\x66\xb0\xa1\x3b\x8e\xef\xdc\x56\x89\xed\xc1\x28\x30\xba\x79\xd7\xbc\xe5\xe6\x79\x37\x6d\x7d\x9a\xd2\x63\xaa\x38\x0e\x4d\xda\x04\x43\xc4\x11\x86\x42\xc5\x49\x1a\xe3\x06\xde\xd9\x88\x25\x14\x17\xbd\x0e\x6e\x98\xcc\x84\x85\x45\x2d\x8a\x62\xfb\xda\x45\x8c\xe5\xbe\x3f\x0b\x24\x2e\x5b\xb6\x68\x5b\x5b\xfc\xb9\x03\xdd\xde\x54\x75\xef\x20\xc6\x14\x04\xee\x50\x26\xd3\x8e\x74\x49\xe3\x32\xb3\x8a\x53\xc9\xb3\xd8\xb3\xf6\xa1\x56\xf1\xd9\x64\x17\xb7\x35\xc0\xc6\x2b\x0f\x5f\xa6\x26\xff\xf9\xaf\xbf\x54\x5d\x53\x71\x16\x18\x20\x2a\x37\x09\x9a\x02\xb8\xa7\xd1\x50\x71\xc6\x0c\xa1\xd0\xa9\x99\x6e\xf1\x6e\x80\x32\x45\xa0\x03\xff\x18\xfa\x10\x31\x07\x8a\x90\xcc\xbc\x41\xce\x08\x2b\x55\x37\xfe\xad\x08\x14\xba\x6d\x8d\x7c\x05\x75\x2a\x60\xa8\xc1\x35\xbe\x47\x19\x48\x04\x40\x7f\xf0\xd3\xb6\x5a\x9d\xfc\xed\xc9\x40\xe1\x86\xdb\x9c\xcb\xa1\x0c\xb9\x8a\x25\x4b\x0d\x41\x90\xd1\xbc\xc0\x94\xfa\x14\xff\x36\xfd\x77\xc0\xcf\x34\xfa\xdf\x3e\x09\x18\x2b\x15\x22\xb7\xe7\x66\xb5\x7c\x7c\xb8\xde\x6d\xd7\xab\xe7\xdd\xf5\x7a\xb3\x7c\x7c\x79\xf0\x73\x14\x68\x82\xf9\xcc\xb2\x42\xbe\xac\x75\xb3\xc0\xed\xdb\x1f\x4e\x23\xa3\x8f\xdb\x99\x53\xb5\x1d\xb8\x9c\xbf\x04\xcd\x7d\xf6\x3d\x2f\x8b\x76\x2a\xd6\x41\x80\x2c\x3e\x7d\x87\x42\xe7\x1c\x8e\x35\xc1\xdd\xd0\xd0\x70\xf9\x35\xd0\x5a\x6d\x03\xf6\xf7\x71\xeb\xb2\x8a\x75\x1c\xa0\xe5\xfc\x56\x15\xfc\xd5\xb5\xe6\xa8\x84\x24\xca\xf2\xd9\xb7\xbc\x30\x76\xf0\x51\xdb\xa4\x88\x67\x83\xb6\x48\xe1\x01\xd0\x4e\x25\x44\xa9\xd8\xb8\x53\xf9\x1c\xe4\xed\xa2\x52\xad\x92\x90\x50\x26\xbd\xd4\xea\xd5\xa9\x2e\x3d\xcf\xc8\xe8\xc9\x93\x90\x52\x62\x28\xdc\xa0\xf3\xc1\x6f\x78\xb9\x7c\x3d\xb9\x89\x91\xc4\x69\x8c\x5d\x5a\x05\x6f\x5a\x97\x92\xb4\x87\x12\x9b\x90\x41\xe2\xde\x71\xdb\x9b\x4a\x68\xa0\x6d\xe2\x11\x63\xfe\x0d\xc8\x53\x9d\xb7\xe7\x39\xc2\x69\x95\xd0\x24\x42\xe7\xec\xc8\x4f\x13\x24\x86\x4a\x28\x35\x65\x2c\xe7\x6e\x3d\xea\xa7\xea\x7d\xea\xbc\x26\x34\x4d\xb5\xf1\xd5\xa0\x46\x9a\x05\x5f\x1e\x56\x09\x55\xc0\x86\x65\xb7\x3f\x9f\xff\x18\x7f\xd1\x84\x25\x04\xd1\x36\xde\x77\x19\x67\x3a\xdc\xc7\x4d\xfe\x35\x9e\x34\x09\xa3\x11\x5e\x95\xef\x79\xde\x94\xed\xee\x67\xd5\x7a\x8f\x33\x61\x82\x2b\xe6\x13\x4e\xb6\x4b\xf6\x1e\xf9\x41\x2e\x09\x08\x54\xc2\x24\x8b\x87\x6e\xe5\xed\x69\xde\x96\x26\x4c\x59\x59\x06\x68\xef\x0c\x6f\xd5\x7c\x32\x37\xc9\xa2\x20\xe2\xbd\x94\x49\x39\xf5\x20\x92\x8c\x09\x4c\x01\x6c\xa1\xe4\x65\x7b\x5f\xfd\x84\x75\x39\x19\x01\x0a\x33\x50\x3b\xae\xd4\xe6\x74\x84\x7a\xda\x6e\x6e\xc7\x09\xc9\x0c\xa5\xdc\xa9\x54\xa0\x9e\x7a\x26\x67\x95\xc8\x84\x59\xce\xb6\x96\x7c\xa0\xcd\x31\x87\xc7\x27\x50\x61\x88\x29\xe0\x02\xb9\x03\x64\x7e\xd1\x82\xa1\x92\x6e\x3b\xc7\x49\x52\xbd\xef\x02\x32\x3d\x48\xb5\x30\x85\x0f\x44\x62\x0e\x66\xa9\xe2\x31\xca\x77\x74\x47\x4e\x2d\x3c\x63\x2e\x6d\x04\x1f\x73\x03\xa5\x89\x7f\x50\xd8\x02\x9d\x93\xc7\x9f\x17\x37\x01\xd4\x88\x81\x60\xda\x73\x51\x96\x27\x6e\x3b\xf0\xdd\xe5\x20\xa5\x98\x0b\x42\xb8\x43\xe7\x1f\xdb\x1c\xc7\x97\x69\xb8\x04\x58\x8c\x69\x38\xc3\x99\x3b\x5e\x00\xc0\x35\x36\xe4\x2e\x8b\xbc\xcc\x25\x2f\xb6\x75\x3e\xe8\x29\xfc\x4b\xb6\x6e\x9c\x81\x49\x40\x66\x81\x29\xcd\xe4\xea\xd3\x3d\x84\x12\x6e\x28\xc3\x45\xae\x1e\xcb\x4d\xde\xcd\x8a\xb9\x66\x87\xfe\x07\x41\xc0\x4c\xc7\x26\xf2\x2b\x1a\xd3\xf9\x52\xbe\x56\x85\xba\x9e\x01\xd6\xbb\x1f\xb1\x48\x18\x3a\x77\x5b\x66\x1b\xec\x24\xdd\x82\x73\xff\x61\x87\x87\x41\x82\xaf\xf7\x77\x5e\xf3\xb6\x0b\x2b\x07\x21\x08\x0d\x03\x8e\x15\x16\xcc\x1e\xfe\x00\x78\xbb\xa9\xfc\xd6\x47\xc3\x40\xe1\x5a\xc5\xda\xa9\x6d\x69\xf4\x87\x00\xab\x51\x5c\x29\x5f\xba\xff\x1a\x08\xd4\xfd\x46\x63\xbf\xc9\x3f\x5e\x1e\xa6\x58\x85\xd3\x54\x20\x43\xd1\x30\x31\x3a\x12\xa2\x6d\x9b\xe1\xbe\x4b\xc3\x8c\xa1\x33\xb1\x43\x7a\xbb\xb6\x2d\x5c\x34\x3d\xae\xcb\x8f\xff\x19\xbf\xc1\x50\xea\xc0\x42\xab\x96\xbc\x44\x2f\x73\x7e\xa7\xee\x8d\x0d\x0d\x75\x42\x0c\x81\xcd\x87\xe5\xbe\x33\xc0\x09\x67\xbc\x68\x44\x42\x74\xd8\x0a\xd0\x6d\xc6\x26\x33\x23\x8a\x93\xc4\x38\x0b\xb5\xb5\x3e\x98\x6b\xba\xc4\x0d\x28\x1a\xc7\x46\x7d\xf1\x8f\x04\x8b\xd2\x5f\xc0\x3a\x14\x8d\x45\x84\xef\xa2\xbb\x66\x90\x4c\xae\x19\x0b\xc0\x1a\xf7\x6f\xfc\x30\xfc\xe4\xb1\x24\x06\xaf\x54\x00\xaf\xaf\x4c\x89\x7d\xb4\xb4\xba\xad\xc5\x32\x94\x61\x5a\xdb\xea\xb0\x8e\x4f\x4e\x29\x64\xa6\x9a\xd9\x36\x46\xa5\x76\xe4\xfa\xd3\x54\x48\xd3\x8c\xea\x42\x1e\x77\x80\xc5\x12\x89\xcf\xdb\x3a\xdf\xef\xa7\xc6\x82\x32\x90\x38\x1f\x4b\x78\x47\x85\xf1\xd1\xd3\x32\xad\x43\x39\x02\x51\x62\xc0\xd8\x53\xf4\x56\x55\x31\xb6\x12\x94\x87\x02\x23\xbe\xbb\xbb\x31\xab\xd7\x6c\xd0\x45\x79\xa8\x10\xf1\x7d\x55\xe4\xe5\x20\xbb\x4b\x39\x33\x98\xfe\x16\xf8\xc1\xb8\xa8\x43\xe6\x59\x45\x45\xa8\x52\xe5\x70\x87\xb2\x9d\x24\xaa\xc6\xd7\x10\x31\x41\xa4\x19\x92\xf1\x3e\x1b\x21\x78\x7f\x9e\x84\x63\x2d\x11\x37\xf5\xcd\xbb\xeb\x57\x51\x54\x48\xc5\x3c\x5c\xc1\x98\x1e\x47\xc0\x38\x79\x92\x2f\x79\xac\x14\x15\x8a\x21\x31\xd0\xb1\x73\x9b\xc2\x09\x4d\xae\x42\xce\x62\xda\x2b\xb1\x6d\x8e\x5c\xc2\x68\xf1\x09\x6d\x0a\xb6\xa6\x3a\xb1\x2a\x7b\x3b\xe5\x8c\x2f\x15\x9a\x63\x8e\xb1\xad\xf6\xfb\x02\x9c\xf7\x32\x58\x49\x32\x02\x43\xd1\xde\x99\x6e\xa3\x38\x75\xea\x35\x5e\x15\x95\x22\x23\x43\xf2\xd9\x39\xb6\x17\x45\xa5\xa2\xb4\x97\x48\x7e\xf9\xfd\x76\xf5\x13\x3e\x2b\x79\x50\x15\x9b\x06\x85\xcd\xd5\xba\xb3\x80\x93\x53\x29\x96\x60\xfd\xfc\xfb\xcb\xdd\xe8\x61\x55\x16\x60\x72\xec\x78\x6a\x5e\x2d\xca\x6c\x72\xda\x8c\x3a\x2b\x68\x85\x12\x67\xa3\xd1\x4f\xbe\x85\x12\x81\xc9\x6f\x7e\x7b\x79\xb8\x7e\x76\xfd\x6b\x8a\x42\x6a\x18\xcf\x6c\x9a\xf2\xfe\xd4\x22\xf7\xee\xa2\xf3\x36\xd5\x6f\x95\xb0\xfa\x2c\xe6\x52\x4e\xd2\xf8\xaf\x6c\x6e\xec\x42\x40\x5c\x51\x60\x89\x34\xca\x67\x4d\xcb\x8b\xe2\xda\x0a\x46\xcf\xfb\x47\x14\x04\x67\xf1\x50\xe9\xa5\xb3\xf9\xf6\x13\x4f\x36\x61\xaa\x49\x8a\x68\x31\xde\xbc\x99\xc4\x8c\x7d\xbe\x94\x28\x43\x81\x87\xcb\x58\x3f\xd5\x15\x42\xfb\x46\x17\x4a\x09\x10\x04\xfb\xec\x2c\xa5\xee\x4f\xde\xf2\x89\x07\x95\x06\x91\xc2\x8f\xfa\x27\xd4\x75\xf5\xc7\xa8\xd6\x9a\x06\x52\x63\xf6\x26\x6f\xae\x1d\x93\xc2\xc8\xd9\x4e\xc3\x38\x20\x66\x80\xf1\x5b\x4a\xb8\x24\xd7\xb2\x43\x23\x92\x60\x36\x70\x55\xd6\xf9\xe9\xf0\xeb\xad\x2b\x8d\x42\x85\xb0\x04\x03\x2f\x83\x4b\xb9\xad\xf1\x68\x41\x39\x35\xbc\x65\x79\xf7\xad\xc1\xa5\x3c\xd2\x38\x4a\xb0\xe8\xf6\x8f\xf5\x66\xf3\x39\x19\x9b\x4a\x63\x05\x99\x72\x30\xa2\xaf\x93\xf3\x69\x12\x10\x44\xe3\x3a\xbf\x7d\xd9\xa3\xd0\x10\xa1\x37\x7f\x85\x24\xa6\x58\x18\xda\x61\x9a\xae\x5b\x69\x6b\xbd\xac\x0e\x87\x2b\x5e\x14\x93\x76\x1b\x95\xd2\x2c\x43\xe4\xa7\x38\x9d\x67\x19\x87\xed\x30\x16\xa6\x48\xf4\xb6\x5e\x3e\x3e\xac\xff\xcf\xd1\xa1\x3c\xac\x56\xd7\xab\xeb\xdd\xd3\xea\x79\xb7\x7e\xf8\xbe\xda\x6c\x57\xd7\xbb\x1f\xab\xb5\xff\x51\x02\x58\x67\xb4\x01\xe0\xd5\xf3\xea\xfe\xe9\x93\x7b\x66\x9d\x89\xb0\xb0\x75\xd3\xbf\xd1\xf9\x37\xf3\x3e\x55\xca\xa4\x8e\x8d\xa7\xdc\x0e\xec\x6e\x9a\x45\x46\xd3\x7a\x27\x4e\x75\xf9\x0c\x07\x53\xd3\x9b\x61\xfa\x51\x29\x0f\x12\x6c\x91\x35\x39\x37\xd3\x40\xbd\xfa\xb8\x68\x92\x74\xa3\x63\xb0\x7c\x82\x9d\x07\x37\x4e\x3d\xa6\x3c\xa3\x86\xeb\x92\x17\xb0\x2e\x71\x81\x0c\x8f\xaa\x10\x81\x65\x06\x6f\xec\xec\xeb\xc8\x79\xb5\x23\x45\x9c\xa2\x86\xf7\xd5\xcb\xdd\x9d\xfb\xb5\xe4\x1c\x99\xd4\x8c\x92\xce\x63\xdd\x79\x31\xfe\x18\xa4\x18\x2e\xfc\xfe\xe3\xd9\xa5\x1a\x52\xa5\x28\x12\x18\xa1\x98\xf8\x03\xbc\xdf\x54\x35\x48\xde\xfc\xa2\x6e\x19\xb8\xb9\x00\x5a\x87\x62\x48\x64\xd0\xce\x5b\x96\x54\x33\x05\xa6\x57\x59\x9b\x36\x9b\xbb\xe0\x09\xea\x80\x10\x7b\x23\x8c\x24\x86\x97\xac\xd2\x1a\xea\xab\x56\x5e\xcc\xf3\xd1\x24\x64\x84\x5a\x35\xf2\x66\x8d\xdd\xc5\x98\x22\x5a\x97\x34\xfe\xdb\xa0\xdb\x58\xb1\x80\x48\xe4\xa0\x84\x43\xde\x76\x01\xff\x17\x9b\x08\x0b\x88\x22\xa1\x87\x68\x6c\xa0\x44\x4e\x32\x77\x7f\x41\xa2\x10\x68\x6d\x88\x2f\x07\x9f\x81\x05\x9c\xe2\x2b\x07\xd5\x4d\x85\xd2\x35\x69\x29\x16\x58\x4e\x8b\xba\xaa\x0c\x57\xf8\xa3\xc6\x06\x8b\xcf\xae\xaf\xa9\x21\xac\x30\xb3\xf9\x9a\x9f\x1f\x35\x4e\x69\x7b\x3c\x8c\x35\x56\x89\xf1\xfe\x56\xdb\x6f\xc3\x06\x66\xc5\x42\xc9\x2d\x5f\x30\xae\xc2\xc9\xf4\x65\x11\x64\xd8\x5f\xfe\x8f\xeb\x6f\x86\x95\x78\xb6\x27\xc7\x0f\x16\xf8\x2d\x6e\xf2\x02\x46\xe2\x3c\x8a\xc5\x81\xc9\xe2\x20\x01\x5d\xf3\x0a\xb5\xd3\xe7\xb1\xc7\x93\x54\x20\x36\xe6\x2a\x6f\x0f\xbc\x69\xbc\x3c\xe1\xc0\x78\x33\x1a\x98\x36\xd9\xe6\x24\x0e\x79\xbb\x69\xb9\xbc\x58\xb6\x9f\x07\x6f\xde\xcf\x60\x34\x00\x54\x69\x3b\xf0\x92\xef\x2d\x9d\xe9\xba\x7f\x21\x54\x65\xb8\xf3\x1d\x0b\x7e\x46\xe1\x0b\x9d\xcb\x6d\x9d\x1f\x0b\x98\xef\x92\x52\x2c\xcd\x64\x9a\xf6\x71\xf1\x03\x7c\xb4\x9b\x73\xd3\xc2\x01\xb7\x8e\x5e\xc7\x5b\x31\x96\x30\xc7\x82\xb1\x35\xe0\xe7\x49\xb1\x8f\x31\x69\x26\x85\xea\x36\x5c\xff\xbb\x2c\x0b\x30\xb1\xe7\xfb\xf5\x8f\xfe\x88\x08\x39\x19\x76\x8f\xfc\xdf\x89\x97\xad\xa1\xc2\xbf\x68\x8f\x51\x2c\x03\x86\x2e\xbc\x81\x3f\x9b\xc0\xf2\x13\x0c\x0c\xe3\x71\x80\x52\x30\xbb\x1a\x3c\x33\xa0\xcf\xc9\x30\x9e\x46\xe8\xc8\x4f\x78\x8c\x5a\xf8\x68\x77\xbe\x17\x6b\xe4\xa7\x33\x9e\x49\x0c\xf4\x30\xc2\xb0\x9a\x81\x37\x35\xc0\x7f\x2f\xf2\xb3\x4c\xd0\xc4\x75\xae\xfd\x66\xf8\x73\xc6\xb3\x56\x64\x24\xb1\x5c\x34\xbd\xb2\x67\xb1\xdb\xf3\xe9\x03\x0b\xcd\x31\x19\xa9\x6a\x9e\x97\x9b\x7b\x87\x23\x60\x32\xe4\xa0\x5c\xf6\xe1\xa9\xf2\xf5\x04\xd6\x99\x08\x0c\x9d\x78\xbd\x87\xa6\xfd\xf6\x78\x7d\xb7\x7a\x1e\x1b\x62\xa6\xb4\x09\x84\x1e\xe0\x7d\x44\x65\xeb\xad\x0c\x50\x43\xeb\x67\x27\xf9\x84\x61\xfa\xef\x73\x20\x0b\x06\x2c\x35\x25\xf5\x9f\x86\x9e\xd4\xfd\x39\x33\xc1\xcd\x5d\xb5\x7f\x29\x5d\xd0\x34\x71\x45\x98\x26\xa1\x22\x6e\x89\x23\xaa\xe2\xc9\xac\xb3\x39\xaf\x64\xf0\xb3\x80\x28\xed\x80\x54\x7d\x85\x9d\xe9\x20\xc0\xd6\xeb\xd5\xcf\x81\x12\xbb\x62\x1a\x22\x2c\x29\x19\xc5\xb6\xe7\xe6\x47\x35\x38\x04\x18\x21\xdd\x6f\x3c\xb0\x35\x23\x32\x15\x3d\x9a\xdf\x02\xe7\xc7\x37\x9e\x05\x2c\xc0\x36\xc9\xa7\xbc\xd0\x50\x5f\x4e\xc5\xbf\x4f\x86\x4b\xc3\xd0\xde\xb4\xd5\xf1\xd6\x95\x91\xb3\x30\x55\x58\xb2\xb2\xdf\x60\x5b\x6d\x8c\xa0\xfb\x57\xcd\x17\x2a\x0b\xb5\xf1\x78\xae\xb6\xcb\x34\x21\xa4\x2a\xe3\xcc\x9d\x30\xe2\xa6\x1e\x78\x05\x2d\xf9\xd8\xf7\xc9\xbe\x4f\x3a\x11\x47\xdf\x31\x8b\x24\x37\x8a\x20\x2e\x88\xba\xf6\x3b\x69\x96\x10\x8a\x2a\x43\xef\x2e\x37\xe2\x05\xcb\xdd\x80\x30\x0d\x59\x2f\xcc\x5e\x35\xbc\x98\x83\x46\x0f\xb7\xf3\x2c\x89\x04\x86\x23\x6f\x70\xb6\x52\x3e\xee\x80\x4e\xcc\x26\x8b\xdc\x20\xbc\x76\x3b\x42\xc6\x02\x85\x6a\xdf\x7d\xcb\x19\x80\xea\x02\xf5\x2e\x7a\x80\x9a\x7f\x0a\xef\x9c\x4d\x9b\x64\x4c\x07\x38\x45\xbb\x0d\x84\xd7\x25\x2f\x9e\xc1\x50\x9f\x5c\xc8\x82\x5d\x22\xe0\xec\x29\x32\x9a\x20\xac\xd5\xc6\x36\x3f\x5e\xa1\xec\x79\xb8\x54\x96\xa5\x4c\x1a\xde\xda\x72\x7f\xea\x77\x8d\x2c\x63\x84\x9b\x2e\xdb\xc3\x13\x3f\x6f\xb9\xe8\x01\xdc\x19\x8f\x2c\x1e\x3c\x1f\x65\x51\x33\x1e\x29\xac\x6c\xe7\xcd\xf2\xd4\xb4\xd5\x01\xea\xbc\xbc\xba\x9b\x8f\xca\x33\x4e\xb9\xad\x97\x23\x8f\x7a\xa9\xaa\xda\x61\xa0\x33\x41\x02\x62\x8d\xf9\xae\x81\x52\x41\x6d\xd0\x4a\xa2\x8b\x24\xc7\x6f\x48\x08\xe6\xa8\xd6\xb7\xef\x00\xd3\xa2\x6b\x26\x40\x90\xc4\x02\x46\x96\x8f\x83\xa0\x38\x93\x54\x25\x4e\x93\xcd\x41\x95\xfc\x3c\x95\xa9\xc4\x0e\x21\x0f\x76\x58\x3c\x6e\xb0\x87\xe7\x54\xc3\xb4\x2d\x65\x6c\x73\xbe\x02\x6a\x65\x92\xc7\x7a\xd8\x61\x08\x6a\x5b\xb9\x92\xca\xe8\xde\x74\xe2\x70\xa0\xc3\x7d\x3a\x53\xa1\x4a\x87\x81\xfa\xd6\xa7\x47\xe6\x3d\x98\xac\x73\x27\xa3\xc1\x0f\x7a\x9e\xd8\x5b\x68\xdb\x69\x85\x22\x53\x3c\xa5\x48\xfb\x51\xe6\xff\x31\xe0\xb1\x90\xb9\x6c\x62\x06\xdd\xfa\x33\xb1\xf7\xe2\xa4\xf2\x29\x27\xec\xe4\xfb\xea\xc0\x74\x00\x98\x72\xba\x69\xbf\x9a\x53\x45\x57\x99\x8e\x49\xe0\x94\x76\x86\x22\x43\x93\x51\x9a\x20\x86\xf2\x68\x89\x4f\x7b\x55\x5d\xc5\x09\x89\x24\xf4\x84\xcd\x3d\x82\x7c\xfc\x78\x9c\x24\x29\x35\xf7\x04\x7f\x56\x07\x91\xc3\x73\x55\x4c\xe2\x04\x4e\x32\x85\x5d\xb3\x9b\xd5\xdd\xdd\xea\x79\xb7\xfc\xb6\x5a\xfe\xbe\xdb\x6c\x57\x4f\xe3\x98\x8b\x07\x41\x18\x9a\xd2\x95\x02\x38\x4c\x0f\xc6\xa1\x11\x4e\xcb\x0f\xdd\x9d\x1e\x8e\x8f\x1a\x57\xec\x88\x1e\x58\xf1\x90\x98\x5c\x99\x2d\x08\x80\xa9\xc1\xfb\xa3\x91\x0e\xed\x7b\xb9\xcb\x9b\x76\x0b\x87\xa3\xa3\x10\x73\x23\x38\xe1\xce\xda\xb8\xdc\x68\x37\x8b\xdc\x27\xe3\x11\x91\x99\x95\xc1\x47\x36\xd5\xf1\xeb\x88\x93\x0c\xeb\xe2\x9a\xbf\xc1\x6e\xda\xdc\x33\x3b\x9f\x78\x0c\x14\x43\xbc\x23\x86\xed\x03\xf1\x72\xc5\x13\x02\xf8\xcc\x5c\xa9\x6b\xe8\x35\x1d\xe6\xb6\x47\x9e\x28\x86\xbb\x38\x0a\xe1\xa3\x11\x1d\x25\xbb\x79\xa2\x20\x95\x7d\x46\xab\xee\xbd\x7e\x9e\x68\x8d\x10\x9e\x12\xde\x7f\x0c\x84\x6d\xbe\xec\x1b\x56\x9c\x42\x88\x09\x02\xec\x6f\xb6\x11\x38\x22\x7d\x8f\x9f\x6a\xf7\xdb\x5f\xa6\xc4\x60\xc4\xc0\x78\x55\xc3\x94\x2b\x4f\x03\x4d\x2d\x62\x60\xd5\xb4\xf9\x81\xb7\xf0\x28\x8a\x7c\x3f\x48\x14\xf9\xf3\x30\x4a\x1d\xb1\xf2\xa2\xad\x0e\xcb\xa9\x4e\x33\x73\xe3\xb2\x30\xb5\x7d\x83\xb6\x92\xb1\x9a\x22\x50\x38\xa7\x86\x2a\x68\x73\x2e\xa0\x47\xdb\x71\x0e\x80\x71\xea\xb5\x8b\x25\xb9\x8c\x4c\xab\xc9\xb1\x3a\xae\x3e\xba\x6f\x36\x1c\x2e\x33\x86\x7d\xca\xc3\x8a\xc2\x14\x2d\xc4\xa5\x56\x98\x1b\xcf\x4b\x67\x0a\xbb\x5d\x13\xa6\x3c\xd8\x8a\xab\x54\x23\xe5\x89\x25\xc9\x9f\x64\x7f\xb8\x62\x09\xf3\xe6\xde\xb0\x30\x3e\xd5\x70\x93\xd7\x4d\xeb\x85\xa2\x15\x57\x20\x70\x87\xcf\xcb\xbc\xed\x4c\xd5\xa9\xcc\x5b\x14\x70\x9b\xcc\x5c\x48\xd3\xd4\x36\x70\xfe\x9e\x97\x7b\x55\x1d\x9c\x6a\xc6\x0d\xc0\x94\xb4\x59\x71\x10\xd2\xad\xa4\x6d\xcd\xf3\x11\xe9\x9b\xe2\x00\x06\x14\x26\x4e\x67\xab\x4a\x73\x53\x57\x87\xcb\xe2\x1e\xd7\x90\x20\x55\xa8\x06\xd8\xbc\xf2\x6e\x5a\x5f\x1d\xdd\x5a\x14\x24\x96\x48\x91\xf1\x78\x84\xf2\x47\x5e\xaa\x3e\x7f\x3f\x3f\x25\x05\x61\x71\x64\x41\xe1\xbe\x92\x72\x31\x15\x9d\x72\x91\xbb\x59\x41\x84\x88\xfa\x6e\xd8\x59\x0d\xe2\xaf\x93\xa0\x82\xe8\x50\x9a\x6e\x47\xf9\x76\xdb\xed\x2f\x7b\x18\x24\x89\x44\x40\x52\xdc\xc4\xc5\xe9\x8c\xe2\x07\x16\x8c\x39\x6f\xe5\x45\x90\x2a\xb4\xdd\xff\xae\xf2\x72\x57\x8f\x5a\xe0\xec\x88\x30\x61\x71\x30\x10\x3d\x9a\xdf\xa8\x44\x98\x5a\x91\x19\x54\x1b\xf9\x91\xff\x97\xd7\x93\xd6\x25\x11\x0a\x86\x59\xea\x12\x3e\x10\xd2\xd9\x0b\xa4\x28\x11\xd1\xd0\x40\xa3\xaa\xc2\xc3\x2f\x3e\xb9\x52\x1c\x28\x2c\x4d\x57\x25\xe6\x21\x7b\x73\x2c\x12\x95\xc5\x46\xb5\xad\x40\x3d\x5a\xbf\x18\x58\x5f\x5a\xa3\xff\xfa\x6a\x83\x17\x34\xce\xd0\xbf\x37\x9f\x07\x69\x60\x1c\x0b\xcc\xf8\x2e\x52\x06\xe8\x9e\x23\xfa\xf5\xd7\x34\x31\x4a\x64\x89\xc1\xd0\xef\x72\xcb\x60\x31\xfa\xf6\x6e\x10\x0d\xb4\x49\x48\x7c\x83\x8f\xb1\xaf\x6e\x47\x70\x48\x25\xed\xb7\x4a\xe4\x4b\x6c\x73\xd3\x6f\x7b\x99\x35\x13\x22\x50\x08\x9f\x68\xf8\xcf\xbc\xdc\x37\xbb\xbd\x17\x8f\x52\x02\xa2\x50\xc6\x7e\x55\x29\x40\xee\xd3\x4b\x01\x29\x25\x80\x1b\x20\x59\x37\xd3\x0d\xc9\xea\xe5\xc3\xfe\x8f\xff\xba\x33\x03\x84\xae\x1c\xde\xc2\x61\x7b\x3e\xc2\x5a\x5d\x9d\xbb\x7f\x17\xa5\x5a\xab\xd9\xdd\x47\xe8\xd8\x08\xd3\x3a\x12\x89\xff\xfe\x52\x93\xe4\xeb\x25\x25\x09\x07\x23\x5c\x8d\x09\x42\xd3\x25\x84\x02\x03\xff\xdb\xd2\x94\x41\xc0\xd1\xeb\xcc\x9b\x67\xe0\xea\xbc\xad\x6e\x10\xb6\x3b\x19\x94\x71\x66\x50\xb4\x1a\xb6\x13\x95\x50\xe4\x1d\xfb\x05\xd2\xc8\x9d\x86\x0b\x64\x8b\xe5\x65\x59\x9d\x4a\x09\xbb\xce\x08\xf4\xe8\xfe\xf1\xbc\x96\x01\x18\x80\x82\x73\x5c\x79\x29\x61\xf3\x0a\xd3\x42\xa6\x74\x04\xf6\x9d\x47\xf2\x0c\xdd\x42\x9a\xfd\x04\x32\x04\x88\xc1\xf5\x80\xee\x7b\x89\x7e\x7b\x38\x0a\x0c\x9a\x0f\xbb\xdc\x4c\x33\x5f\xb7\x20\xd1\x80\x6c\x5e\xab\x53\xcf\xe3\x62\x94\x33\xc7\x8d\x75\x32\x12\xb1\xa3\x05\x5d\xbe\x72\x54\xcb\xae\x1f\x4e\xff\xe6\x93\xab\xc4\x81\x32\xaa\x64\xbc\x5c\x16\x55\x03\xdf\xab\x6e\xc9\xfe\x04\x5e\x18\xbe\x94\x51\x65\xfa\xe2\x95\xc4\x61\x04\xd4\xeb\x57\x9b\x84\xcf\xa8\xec\x22\xe3\x30\x45\xbe\xf7\xe3\xa9\x28\x30\x05\xd8\x7d\x26\xaf\xa8\xa0\x5b\xa8\x0d\xee\xc2\xb0\xd9\xf4\xbf\x12\x61\x2f\x93\x31\x90\x41\x98\xcf\xe3\xca\x98\x65\x68\x60\xc5\xe9\x7c\x75\xee\x5c\x8b\xc9\x53\xd2\x90\xa3\x93\xb8\x1b\xb3\xc8\x3f\xb9\x2a\xe0\xc5\xce\x24\x69\x9c\x60\x66\xa7\x33\x10\x26\xfc\xf8\x22\x35\x29\x69\x22\x99\xc5\xce\x3c\x5a\x2d\xa2\x25\x2f\x0a\xc1\xe5\xdb\xed\x34\x69\x24\xd3\x98\x18\x4d\x65\x68\xa1\x3e\xe4\x25\x3c\x9e\x5a\x59\x1d\x3e\xdf\xc3\xfa\xa0\x48\xa6\x42\x22\xaa\xdc\x54\xc7\x2f\xc4\x46\xa6\x4b\x77\xfc\x4c\xa9\x8a\x8d\x80\xb7\xfd\x4e\xf9\x3e\x2f\x8d\x2d\x5a\xab\x9b\xaa\x5e\xb4\xaf\x28\x66\x37\xff\xe3\x2c\x0c\x79\xe6\x73\x07\x3f\xf3\x81\x0f\x2e\xb3\xc8\x14\x70\x97\xd5\xe1\x88\x20\xce\xc0\x1f\x89\x13\x64\xe7\xda\xee\x61\x18\x26\xcb\x2e\x34\x32\xba\xd8\x46\x69\x70\x78\xe3\x31\xb1\xff\xd8\xb1\x3c\x00\x04\x5c\x89\x22\x7f\xf3\xf3\x8a\x47\xa6\x99\xe9\xea\x74\xde\x80\x8f\x17\x24\xcf\x82\xd8\xfa\x31\x96\xe3\xd2\x1e\x10\x91\x44\xae\x8f\x75\xb3\x2e\xf3\x76\x81\xbd\xe7\xfe\x58\x06\x59\xbf\x61\x99\x20\x62\x32\xc1\x20\x21\x0a\x7a\x86\xf4\x4f\x51\xe2\xf3\x76\x46\x87\x1c\xd9\x9b\x76\x5c\xa9\x3b\xd8\xe7\xed\x4c\x5b\x87\xd4\xb1\xc2\xa4\xa4\x4b\x68\xe5\x12\x0c\xc9\xd8\x78\xc9\x69\x6a\xdc\xc3\x3d\xb4\xdf\x0d\xfe\xf1\xcb\x99\xa9\x15\x49\x4c\x13\xd6\xa8\x15\x4e\x11\x12\x23\xec\xaf\x73\x24\xc6\xf3\x53\x11\x91\x48\xe1\x3b\xf2\x9e\x3b\x97\x72\x7c\xab\x8a\xa8\x0c\xf1\xad\xbb\xdd\x81\x7f\xec\x76\xf3\x19\x5e\x15\x44\x46\xf4\xda\xf4\x4b\x3a\xfe\x6d\x77\x30\x33\xa4\x06\x56\xb1\xf5\xde\x64\xcb\x5d\x2a\x73\x76\xa7\x53\x81\x22\x8e\x2b\xf5\x01\x3e\xba\x9b\xb3\x4e\xa6\x3d\x1e\x12\xf3\xac\x77\x8f\xb7\xbb\xcd\x09\x51\xe4\xfa\x54\x5c\xd7\xfc\x7d\xde\x0d\x52\x61\x60\xa0\x7c\x3e\x53\xf5\x7b\x59\xbd\x17\xa0\xf6\x68\x52\x27\xaf\x25\x4c\x05\xd3\x4e\x11\xa7\x69\xeb\xea\xec\x05\x46\x27\x23\x23\x6a\x3a\x71\x2d\x3c\xd7\x6a\xcb\x7d\xc5\xed\x73\x91\xc0\x72\x67\x62\x19\x45\x6a\xd7\xd7\xea\xfd\xc7\x2b\xf7\x6d\x06\xee\x89\x23\x05\xda\x66\x76\xb6\x87\xe3\x8f\x3a\x6f\x61\x9b\x1f\xa0\xe9\xc2\xed\xf9\x4c\x83\x8a\xb4\xc6\x62\x7a\xde\x6c\x8e\x55\xd9\x54\x35\x17\x05\xfc\x56\x09\x27\x4c\x72\x11\x0a\x4e\xa2\x21\x15\x93\x08\x0d\xc1\xf6\xf1\x29\x20\xbe\x52\xa6\x62\x22\x5d\x7d\xfd\xbe\x3c\x6f\xf3\x29\x27\x94\x52\x49\x0a\xa6\xba\xae\x40\x56\xca\x58\xd5\xf5\xf4\xdd\x25\x60\xc0\x6c\x47\xde\x34\xdb\x6a\x34\xb3\x02\x87\x9e\xbd\x70\x3c\x27\x6f\x8d\x46\x31\xf2\x06\xe9\x53\x51\x0c\x0b\x24\x8a\x46\x29\xba\xfd\x06\xbd\xb1\x7c\xde\x7c\x32\x2f\x68\x94\x62\xc2\x5b\xcc\xf9\xa4\x6e\x4c\x4a\x92\x5e\x21\xee\x2b\x66\x5a\xf7\x03\xa9\x45\xd0\x73\x5d\xb7\x27\xd5\xd3\xbb\xb8\x21\x5a\x60\x4d\x44\x9a\x1e\x00\xa4\x86\xf0\xb6\x4d\xa5\x84\xa7\x13\x8a\x00\x2e\x5b\x4c\xdf\xb8\xf7\x30\x3a\x5b\x9a\x1a\x11\x0e\xac\x9e\x1b\x9c\xfa\x4d\x55\x9b\x4d\x1a\xcd\xe6\xe4\xed\xa4\x42\xa4\x89\x7f\xa2\x01\x82\xc0\x1d\x97\x9c\x6a\xd7\xe2\xda\x42\x0d\xcd\x3c\xd3\xb5\x52\xa9\x96\xe8\x15\xef\xac\x33\xd8\x6d\x73\x63\x61\xa6\x91\x5b\x11\x4f\x7e\xce\x94\x42\x8c\xa9\xe3\xbd\xcc\xab\xd2\x18\x86\xbf\x5c\x8f\x1b\xdf\x78\x16\x6b\x61\x1d\xb7\x2b\xde\xc0\xaa\x7d\x5d\xf2\xe3\xe4\xe1\x32\x08\x70\x07\xd7\x00\xea\xa5\xcc\x65\x55\x4f\x60\x96\x4a\x10\x82\x46\xdc\xe0\x2b\x4e\x67\x13\xc9\xfd\xb5\x3b\x10\x49\x84\x00\x33\x9c\xf3\xbd\x4c\xe0\x27\xd3\x4f\x82\x49\xd1\xb9\xc6\x94\xeb\xbc\xa9\xde\xcb\x87\xaa\x75\xae\x2e\x6a\xa3\xd9\xc1\x9d\x31\x96\x3e\xc7\xd8\x4e\x55\x8c\x95\x52\xa1\x8a\x32\xdf\x50\x57\x9d\x6a\x09\xc8\x67\x34\xec\x78\x0e\xfc\xe0\xcc\xb0\x7b\xb5\x5e\xcb\xcc\xe4\x10\xdd\x61\x11\x25\xc4\x37\xd9\x42\xd3\x54\xf5\x79\x03\x75\x0e\x43\xd1\x6b\xa5\x80\xc6\x06\xc0\xe0\x52\xae\x3b\x71\x1e\x81\x89\xe7\xf7\x49\x05\x2c\x42\x76\x05\xab\x37\x51\x3a\xba\x6f\xa5\x20\x0b\x90\x95\x10\x01\x01\xde\x0d\x76\x7e\xfa\xf8\x2c\x3a\xe2\x88\x89\xb8\x32\x08\xce\xdd\x66\xfb\xe0\x4e\xa3\xa5\xd6\xdc\xb1\xbd\xf0\xa2\xb9\x83\x72\xef\x04\xf3\x14\x90\x50\x60\x46\x45\x14\xc0\x6d\xdc\x12\x84\x06\xe2\xea\x6b\xf7\x40\x12\xc6\x52\xf7\x0a\xda\x7c\xb0\x10\x6d\x27\x52\x29\xf9\x78\x59\x43\x18\x1a\xd9\x81\xeb\x47\xd7\x21\x03\x51\x4c\xc0\x76\xb8\xae\x8a\xaa\xdb\x63\x07\xd2\x14\xa3\xd5\x00\x11\x8b\x43\x5f\x17\xc3\x1c\xb2\x71\xd6\xe6\x27\x0f\x44\x2a\x53\x89\xe7\x22\xb8\x3e\x97\xfc\xe0\xfd\x6a\x88\xc3\x80\x59\xe7\x01\x4f\xb7\x1b\x6a\x23\x29\x88\x99\x11\x1b\xb1\x28\x49\x03\x4b\xb0\xc7\x12\x4e\x9c\xbc\xf3\xe6\x3f\x27\x5e\xc3\xa2\x86\x49\x30\x01\x89\xa6\xce\x42\x98\x5c\xe6\x7d\x5e\x40\xd3\x56\xe5\xb4\x52\x0c\x69\x98\x71\x4b\xf6\x05\x75\x3b\xd4\xcb\x75\xd7\x4b\x53\x86\x89\x3c\xbc\x09\x03\x3e\x1b\xa2\x9a\x9d\x3f\x04\x29\x4b\x90\x6b\x6d\x75\xbd\x0d\xdd\x6f\x19\x97\xca\x97\xa6\xdc\xaf\x46\x6e\x14\x30\xae\x49\xd0\xfb\x12\xb7\xfc\xd0\x37\xce\x01\x93\x1a\xb7\xfa\x67\x9e\x2b\xc7\x2c\xff\xab\xa0\x7c\xfc\x7c\x0c\x08\x56\x2c\x6f\xd6\x7e\xf2\x01\x03\xa1\x23\x67\x8f\xa7\x42\xa0\xd3\x9f\x1b\xba\xcf\x7b\xe8\xde\xe2\x42\xa9\xcb\x7d\xd9\x8e\xcc\x22\x23\xc8\x6c\x7d\x7a\xc7\x65\xd3\x4e\x5c\x36\xc8\x68\xa4\x4c\x58\x6d\xd7\xbd\xad\x90\x8f\x4e\xeb\xdf\x0e\x8f\x00\x5b\xe3\x8c\xfd\xbe\xc9\x4b\x69\x27\xb9\xd1\x0b\xa8\xdb\x7c\x26\xc6\x1e\xbf\x60\x11\xc5\x28\xc6\x88\xe2\x20\x8d\x37\x25\xfe\x1d\x8b\x18\x8c\x38\x73\xf5\x7e\xcf\xcb\x09\xc6\x11\x44\x9a\xa5\xd2\xcf\x24\x43\x6f\x38\x9d\x43\x42\x30\x2b\xdc\x6d\x62\x3a\xac\x8f\x35\xe7\x1e\x72\x3b\xab\x11\xa3\x40\x2a\x20\x30\xe4\xca\x2e\x30\x72\x2d\xa1\x98\x78\x2c\xa0\x12\xdb\xde\x0d\xed\xb2\x2a\x3e\xa1\x5f\x56\xa0\x44\x8a\x2c\x11\x47\x7e\xee\x5c\x52\x73\x56\xbf\x45\x4e\xc6\x82\x69\xe2\xe9\x6c\xfb\x38\x62\x07\x10\x41\x6c\x65\x50\x9f\xfa\x86\x33\xd0\x4c\x28\x07\x03\x36\xad\xd2\x46\x64\xde\x1f\xd7\x09\xee\x96\xfb\xfc\x27\xdc\xc3\xa6\x3a\xc0\xd5\xd5\xcb\xf2\x77\xe7\x23\x6a\x12\x67\x3a\xb5\x9c\xec\x4f\x50\x47\xfe\xef\xc2\x94\xe7\xb1\x61\xde\xc8\x06\x2c\x3f\x55\xaf\x50\x9a\x28\x0b\x8f\x01\xa3\xed\x79\x5d\xb5\xcb\x2a\x2f\xc5\x20\x49\xe0\x46\x76\x56\x68\xf0\x7e\xf1\x83\x8c\x28\x4e\x66\x23\x4c\x1d\x28\x8e\x51\xe4\xed\x07\x1a\xf7\xbb\x29\x2f\x9f\xd2\x01\x00\x6a\x88\x7a\xbd\xdf\x53\x03\x46\xfa\x6c\x64\x70\x75\x48\x0d\x7f\xbc\xfd\xf5\xd4\xfa\xe8\x50\x85\x3c\x74\x9c\x61\xe6\x26\x6f\x39\x12\x67\xbf\x5e\x34\xb8\xeb\x50\xa7\xb8\xf5\x94\x55\x9b\xeb\xf3\x16\x43\xf6\x8b\xfc\x9e\x8e\xa4\x40\xef\x6e\x0b\xfc\x70\x9d\x37\xff\x39\xf1\xe2\x52\x15\x5b\xe9\x98\xc7\x24\x72\x62\x2d\x2d\x4e\x96\x61\xfb\x98\x4e\x22\x86\x06\xda\xfe\x0a\x49\xf9\x27\x81\xa2\x4e\x52\x8a\x4b\xf9\x9e\x9f\x45\xe7\x5b\xe9\xaa\x3e\x60\xee\xc6\x9f\x44\x1a\xb0\xb7\x49\xfd\x74\x13\x7b\xc0\x27\xa2\x69\x6c\x20\xcc\x0f\xf0\x7e\xcf\xcf\xd5\x45\xaf\xbe\x1b\x46\x49\xe0\x74\x42\xf3\x12\xa1\xef\xd0\xb4\xe3\xfe\xfb\xbf\x8f\x5e\x01\xcd\x0c\xea\x2e\x5f\xf2\x7a\x39\x92\xe4\x9d\x69\x22\xd0\x54\x0b\x14\x2b\xc9\x9b\xab\xbc\x3a\x40\x5b\xe7\xb2\x67\x67\x1f\x99\x12\xcd\xa2\x08\x9b\x32\x86\x34\x16\x0f\x55\x69\xc0\x84\x2a\x6f\xc4\xc9\x92\x25\x62\xea\x7d\xd6\x4e\x6a\x96\x72\xcc\x0a\x1b\x8b\x66\x79\x89\x06\x15\x9c\x69\xdf\x88\x66\x99\xd1\x50\xac\xab\x93\xa9\xe5\x28\x04\x46\x8d\xef\x2c\x0b\x35\x9a\xf4\xba\x0b\x61\x2b\x35\xfa\xe2\x93\x1b\xe0\xb1\xa1\x70\xba\x85\xf6\xbe\x73\x86\x9c\x21\xd4\x5c\xc4\x5a\xf6\x0d\x78\xea\x07\xe4\x4b\x8f\xc0\xd2\x22\x0e\x52\xab\x00\xf2\x5c\x15\x85\x69\x3a\x19\x43\xc5\x86\x4d\x9d\x97\xab\x4a\xc4\x81\xe3\xbc\x71\x26\x69\x58\xbf\xd3\x42\x71\xcc\xd0\xec\xb8\x52\x0f\x37\x5f\x00\x7e\xb5\xd0\x86\x4a\xae\x81\xd6\x44\x13\x9e\xb9\x69\x3a\x2e\x43\xde\x37\xc4\xa7\xa3\xb6\xea\x24\x43\xf1\x95\xab\xac\x25\x70\x09\x3e\x0d\xb2\x69\x3b\xcb\xbe\xb7\xd0\xc6\x20\xb1\x83\x54\xa8\x31\xff\x7b\xf4\xc2\x42\xcf\x20\xf3\x63\x0e\x65\xeb\xed\x9b\x4a\x19\x16\x26\xf1\xf4\x4d\x5b\xfb\xbf\x77\x3e\x2e\x06\x59\x55\xa1\x4e\xef\xe5\xcb\xd3\xc8\xa1\xd0\x90\xc4\x18\x09\xac\xff\xef\x66\x88\x3b\xd0\x40\x53\xab\x6b\xd3\x4d\x33\x2b\x60\x8a\x19\xcc\xef\x50\x9f\xef\xaa\x72\x7f\xdb\x33\x7b\x68\xe0\x86\x42\xf4\x88\xe3\x90\x80\xd8\xbf\x72\x1d\xa6\xc4\xe8\x12\x94\xaa\x7a\x37\xc4\xa2\xa3\x00\xd2\x8d\x83\x08\x5c\x63\xa2\xf9\x22\x37\xc1\x4d\xf8\xc9\x7a\xd5\x96\xf0\xf8\x90\xff\x3f\xd6\xde\xad\xbb\x55\x1c\x6b\x17\xfe\x2f\xfb\x6a\x5d\xf4\x85\x00\x01\xe2\xbb\xb3\x1d\x27\xf1\xae\x24\x76\xd9\x4e\xad\x55\xfd\x8e\x1e\x1e\x3a\x4c\x25\xbc\xc1\xe0\x06\x9c\xc4\xfd\xeb\xbf\xc1\x94\xc4\xc9\x24\x55\x3d\xc6\xbe\xe9\xd5\x15\x09\x0c\x42\x87\x79\x78\xe6\xf3\xe4\x03\xb2\x05\x20\x24\x88\x10\xa1\x59\xd5\xe5\xbe\x58\x9f\x9a\xb3\xb2\x18\x4a\x4b\x00\x21\x31\x47\x4e\xe7\x53\x2a\xdf\xac\x8a\x54\x55\xf5\x90\x24\xa3\xba\x59\x20\x84\x2b\xa4\xdb\x59\x2d\xd6\xa8\x4b\xd7\xc5\x5b\x2e\xdf\x01\xcf\x81\x10\xa5\x1c\x3b\x18\x9a\x76\x98\xfe\x1c\xcc\x20\x20\x1e\x0d\x8d\xa5\xc4\x33\xb9\xdc\x2f\xea\x62\xb1\xde\x8e\xbb\xb0\x08\x27\xa3\x38\x5f\x9c\x20\xc0\xd4\xac\x05\xe2\x27\x0a\x5d\x2f\xb0\x03\x8c\x8b\xe0\xdd\x65\x70\x80\x50\x1a\x21\x9b\x36\x77\xc2\xac\xd7\x04\x3b\x40\x68\x14\x22\x84\x64\xde\x18\x02\x66\x93\xfa\xd1\xe6\x25\xbf\xc9\xbc\x8f\x9e\x85\x0a\x6a\xcb\x57\x2b\x79\x06\xe4\x9d\x72\x8f\x11\x25\xc4\x61\x37\x67\x59\x36\x08\x96\x01\x89\x00\x70\x4d\xac\x4f\xe7\x0c\xf2\xba\xa8\x5c\x43\x4c\x18\x22\x7b\x54\x5a\xa1\x96\x77\xfb\x77\x2f\xc4\xe8\x9a\x4b\xc1\xe5\xcb\x4f\x6b\x6c\x54\xa3\x37\x8b\x3d\x8e\x86\xf8\x2b\xaf\x5a\xe2\x7f\x2b\x98\x73\xd5\x95\x1b\xb4\xc7\x23\x7f\x83\x1b\x9e\xfe\x57\x0c\x42\x40\x62\xa1\x31\x4d\xd5\xf7\x38\x80\x30\xe2\x3b\x65\xdc\xa7\xf3\x71\x0b\x2f\xe7\x8c\x3b\xf2\x9b\xe2\xdc\xe7\x6b\x19\x3e\x0b\x0b\x98\x01\x94\xf3\x66\xeb\x1d\x11\x08\x01\x61\x5a\xea\xa0\xe5\x29\x30\xd4\x60\x95\xa3\x29\xab\x7e\x0c\xf7\x7a\x20\x89\x47\x30\x0d\xbd\x92\x85\xe3\xd6\xeb\x24\xcb\x2a\x87\x63\xed\xbf\xe7\xb5\x1e\x3b\x90\x24\x94\x68\x57\x42\xae\xb6\x5c\x6b\xe7\xa2\x03\x49\x38\x20\xcc\x1f\xea\xd7\xe6\xc3\xda\x58\x67\xdb\xaa\x7c\x34\x75\x6d\x3d\xe1\x04\x7a\x13\x08\x67\x46\xb0\xf2\xa5\x31\xa6\x4d\x81\xde\xf4\x0c\x13\x84\x8a\x96\x50\x68\xef\x24\x9c\x47\xa3\x23\x88\x31\xa3\x56\x45\xfd\x33\xd5\x69\xdd\xdf\x2c\x44\xa8\x1c\xb7\x97\xd9\xe2\x56\xb9\x2e\xe6\x97\xa9\x6a\x28\x20\x92\x18\x01\x07\xb3\xb2\xb0\xee\xd8\x68\x17\x8d\xba\x05\x60\x20\xec\x25\x57\x80\x8b\xfe\x9e\xe7\x2a\xfb\xda\x20\xbc\xfa\xef\x71\x16\x6a\xf8\xd2\x52\x18\xcd\x8c\x0f\x5b\x49\x5a\xbf\x76\xbb\x28\x10\x15\x11\x2c\x82\xe4\xe7\xfa\x15\xf2\x3a\x45\x51\xd1\x0e\xe1\x08\x44\x25\x06\x39\x55\xa0\x97\xb1\x32\x09\xd1\xe1\x34\x55\x89\x44\x6d\x10\x67\xd2\xfe\xda\xac\x46\xfb\x91\x92\x14\x99\x31\x10\xec\x0a\xf5\x32\xd7\x45\x29\x61\x0b\xef\x69\x85\xae\x8b\xed\x06\xbe\x87\xbb\xb4\xdd\x65\x86\xf7\x00\x01\x96\xd9\x47\xbe\xf1\x17\xe8\x1d\xd3\x40\xb4\xa7\x22\xd1\xca\x32\xe0\x97\x41\xd6\x9f\x2f\x98\xd0\x81\x68\x46\x12\x8b\x61\xd8\x9f\xb3\x74\x18\x0e\xf6\xdc\x4f\x6a\x29\x63\x1b\x40\xde\xc9\xa2\xfc\x6a\x13\xd5\x4a\x21\xb6\xfa\x84\xc1\xf1\x61\x25\xca\xb0\xab\x47\x38\x45\xd7\x71\xf9\x38\xe0\x90\x04\xcf\xf3\x05\x82\xaa\x67\x50\xc2\x75\x41\x53\x7f\xba\x7b\x1e\x17\x89\x8d\x35\x2c\x96\x0a\x6a\x9e\x66\xc3\x3a\x2f\xf0\x82\x20\xe0\x8e\x3b\xdd\xa6\xa3\x7e\x82\xa8\xd2\x5e\x90\x70\x70\xcb\x20\xa6\xdc\x1f\x94\xf7\xe1\x4c\xf5\xbf\x41\x0e\x82\x17\x00\xc1\x4c\xee\x1f\xe9\xa7\xc7\xba\x6a\x56\xf0\x42\xc1\xd0\x78\xc5\xab\x6f\xcf\x99\x4e\xb3\xec\xd8\xab\xe1\xf8\x1f\xbf\x33\x28\xd9\x28\x68\xdd\x6b\x73\x77\x03\x40\x26\x6c\xc7\x58\x3a\x08\xf2\x83\x17\x45\x42\x58\x7a\x00\x03\x2f\x48\xff\x33\x34\xb9\xc0\x8b\x84\x46\x09\x8a\x5b\xcb\x8c\x84\x91\x29\xcc\xa4\xb4\xb9\x43\xf0\x22\x19\x0b\x4b\x26\xb7\x4f\xe5\x5b\xff\x36\xd3\x7b\xb6\x17\xfb\x21\x6d\xf9\x17\xad\x5a\x66\x8f\x24\xd4\x3d\x60\x4c\x23\x3c\xbb\x6c\x59\x91\x4d\xa6\x77\xcd\x09\x0b\x8d\x02\xa9\xb2\xc0\xa8\x49\xc1\xd0\x2f\x9e\x81\xc5\x09\x68\xab\xf7\x65\x42\x6c\x50\x3a\x75\x3d\xf0\x92\x48\x63\xa8\x5f\x15\xad\x88\xaf\x6b\xb1\x1c\x9b\x2f\x60\xb2\x6d\xd5\xc0\xdb\x06\x2f\xe1\x26\x31\x8d\x61\x51\xac\x38\x46\xb7\x76\xb8\x75\x79\x89\xd0\x86\xed\xc5\xa6\xda\x7f\x16\x65\xa6\x16\x45\xe9\x0a\xe0\xad\x28\x6d\xfb\x8f\xbb\x4c\x46\xca\x52\x2d\xee\x61\x52\xe3\x7c\x22\x72\x09\x5e\xa2\x05\x38\xc6\xfe\x43\x65\x6d\xe7\xe1\x15\x6d\x4f\x53\x08\x7d\x4c\xf3\x1d\x26\x7d\x4e\x3d\x8d\x4d\xdb\x87\x53\x81\x19\x8a\xca\x05\xc6\xc0\xe3\x91\x8f\x95\xff\x98\xd8\x18\xd0\x8f\x81\xc7\x21\x09\x04\x1a\x4a\x88\x35\xd8\x82\xe4\x59\xb6\xe0\xa7\xb4\xfe\x22\x50\x0d\x9e\xa0\xcc\x90\xca\x37\xde\xe7\xbc\x28\xde\xda\x39\x2b\x04\x33\xdc\x91\x50\x3f\x6f\x57\xd3\x4b\x52\x32\xc6\xec\xbc\x5e\xe6\x8d\xf9\x32\x3f\x5f\x66\xb9\xc2\xd4\x5b\x6f\xda\x4a\x68\xc1\x53\xbf\xc1\xa5\xbf\x29\x7a\x8a\x04\x91\x74\xb9\x50\x9c\x59\xae\x3e\xe5\x8b\x07\x56\x3a\xc4\xc4\xe5\xa9\x28\xb2\x4e\x75\xa2\x6d\x4c\xd0\xa6\x78\xd8\xaf\xdd\x9f\x20\xf2\xd0\x38\x1c\x8a\xfb\xef\xfa\xa3\x0c\x92\xe2\x33\x98\x50\xdd\x20\xa2\x0c\x9e\x0e\x79\x6c\x73\x86\x08\x7e\xb0\xf2\xca\xc3\x39\xa6\x39\xb8\x4e\x8f\xfc\x73\xce\x6b\xf9\x6a\xf2\xd3\xb8\xa3\x0c\x5f\x40\x4b\x1f\x4c\x92\xd8\x01\xa0\xd0\xf6\x9d\xd0\x1b\x00\x4f\x83\x8f\xa6\x1d\x82\xeb\x26\xcd\x28\x9f\xc4\xe0\x40\xe6\xcd\x54\xe8\x85\x22\xc0\x27\x2c\x11\xbe\xdb\x61\xa1\x8f\xb3\xef\x00\x09\xe0\x13\xa0\xe8\x26\x2f\xb2\xe2\xac\x7e\xb5\xd7\x42\xcc\xe8\x08\x2a\xf3\x63\xf4\xd3\xda\x1c\xcb\x2e\x7a\xb7\xa9\xe0\xac\x8a\xc6\xf7\x70\x37\xf1\xfc\x18\x79\xb4\xb6\xb3\xfd\x12\x19\x89\xfc\xb6\x25\x4a\x02\x07\x79\x92\x05\x02\x55\xd6\x39\x58\xce\x92\x54\xc2\x2a\xdf\x14\x8d\x8f\x06\x68\xf0\x0e\x46\xc5\xf7\x22\xed\x52\xa6\xf6\xb5\x16\x59\x51\xa5\xf9\x0b\xae\x85\x51\x5f\xce\xb1\x12\xc7\x90\x3e\x5c\xd3\xc2\x83\xef\xd3\x98\xc4\xc3\x58\xa2\x23\x07\x73\x3d\x22\x8f\xf4\x96\xd5\x57\x34\x1e\x4d\xc7\x04\xba\xc0\xfd\xa6\x6e\xf6\xf1\x07\x5e\xb6\x33\xcd\xf7\x99\x01\xed\x99\x10\xc6\xef\x67\x38\x4f\x28\x80\x34\x4e\xc9\xd4\x1f\xdd\x3d\xb8\x42\x56\xab\x43\x09\xb6\x9e\xcc\x52\xe4\x3d\xf0\xaa\x9e\xbd\x43\xc9\x5f\x60\xfa\x4d\x03\x2f\xc2\x98\x7a\xc9\x73\xd5\x7e\x88\x80\x05\x3c\xea\x12\xaa\x8e\x4a\xf3\xdc\x51\xae\x3a\x4b\xc3\x0f\x78\x42\xed\x6a\xc7\xba\x37\x6e\x93\x8f\x5f\x9c\x02\xee\x2a\x88\x31\x78\x59\x9e\xf3\xde\x5e\xe5\xd3\x50\x84\x16\x6f\x73\x9b\x56\xaf\x62\x5c\x5d\x0f\x3e\x15\x21\xaa\xb5\xbe\x1a\xad\xb7\xf9\x58\x18\xbb\xe9\x21\x90\x01\xec\xb5\x2e\xf8\xe8\xe2\x30\x34\x8a\x4e\xb2\x4d\x80\x75\x1a\xfb\xe0\x87\x3a\x64\x46\x91\x2c\xaf\xce\x47\x78\xac\x9c\x9f\xe6\x47\x91\x51\x03\x2f\xd0\xc9\x4e\x8b\x9c\x67\xc8\x20\x3d\xd0\x4e\x05\x3f\x8a\x13\x21\x3b\x62\x32\xa7\xb3\xe3\x5a\xb9\xc0\x30\x68\x47\x6a\xbc\x6c\x3e\xe4\x6d\x51\x2e\xe7\x7f\xee\x97\x23\x74\x32\xf8\x91\xd0\x48\xa0\xfc\x50\xbc\xec\x90\xe8\xea\xfb\x11\x8d\xb9\x30\x6a\x55\xb9\x42\xd7\xfb\x86\x5f\x5a\xe6\xb6\xa6\x55\x26\x36\xe4\x70\xc8\xe1\xe3\xa0\x2c\x8f\xdc\x01\x95\xf9\x46\x23\x18\x83\x99\xfc\xe2\x7c\xe9\xb3\x6b\xd9\x56\x46\xb4\x61\x0a\x2a\xea\x1a\xca\xcb\xfc\xb2\xdc\xdf\x8f\xc6\x99\x89\x98\x5a\xf4\x24\x1a\xb3\x5d\x5e\x13\x7c\x06\x1c\x59\xc2\xb9\x94\x70\xaa\x27\xd8\x40\xc0\x4f\x42\x23\x1b\xbe\x2c\xa5\x93\x67\xb9\x86\xc2\x30\xd7\x99\x29\xe4\xd2\xf9\x30\xce\x6d\xe3\xd4\x55\xb0\x6b\xbf\x49\x22\xc1\x0b\x9d\x02\xe1\x6f\x70\xf9\x31\x05\x2d\x00\x9f\x13\x83\x70\xc6\xdd\xc3\x14\x61\xf4\x50\x19\xa3\xbe\x9e\x51\x3b\xb5\x6c\x02\xc6\x56\x2c\x8b\xe3\x9c\x97\xd3\xfc\x8b\xe0\x73\x2e\x4c\xad\x27\xcf\x51\x9b\x6b\xf4\x10\xd3\xd2\x6b\x83\x51\xe7\x3a\x70\x25\x27\x07\x6d\xf9\x0e\x87\xbf\x21\x62\xc6\x2d\x12\xd5\x95\xdd\xfc\x5e\x3b\x4f\xc7\x97\x54\xe3\x26\xb3\x99\x6d\xf7\x4f\xcb\xed\x61\x37\x7b\x70\xe2\xd4\xe0\x2b\x9f\x62\x1d\x95\x48\x95\xe6\x69\x76\x2e\xdb\xaf\xa5\x84\x32\xc8\x5c\xae\x94\xe1\xd3\x1c\xfd\xaa\x12\x1a\x03\xdb\xaf\xbc\x42\xa1\x09\xfb\x67\x88\x22\x2c\xbd\xb2\x12\x80\x59\x51\x57\x5d\x59\x97\xeb\x23\x78\xd8\xf1\x4a\xa2\x08\x6e\x33\x59\x56\xf9\xfc\x9c\xbd\x7d\xc9\xfc\x03\x3e\x80\x87\xd6\xeb\x19\x19\x48\xcd\xf0\x17\xa5\x0b\xb4\x8d\x9e\x0f\x74\x84\xef\xdd\x98\x99\x2b\x94\xde\xc6\xc9\x38\x9c\x70\xa0\x13\xd4\xf6\x3b\xa6\x8a\x3b\x8a\x87\xa1\xb1\xee\x6b\x42\x70\x57\x31\xea\x43\xf6\x80\xe9\xd9\x2c\xbe\xe6\xda\x4a\xe4\xd6\xed\x9b\xce\x0d\x9d\xd4\xdf\xc1\x12\x80\xaf\x85\x0e\x78\x57\x04\xe4\x6c\x92\xbe\xbf\x1a\x10\x16\x24\x8d\x49\xb1\x7a\x3b\x97\xfc\x31\xfd\xa2\xb8\x1c\x02\x8f\x1a\xdd\xfc\x16\x00\x85\x75\xc3\x77\xfc\x08\xa8\xf9\xec\x6e\xe7\x09\x4d\x08\x56\x99\xa7\xf2\x6d\x48\xb5\x77\xad\xe0\xe7\xae\x01\x41\xec\x7b\xce\xcb\x54\xbe\x4d\xae\x91\xc0\xd3\x89\x6e\x3d\x0c\xf3\x0e\xfb\xe3\xc9\xfd\x6e\xf3\x7c\xe8\x2d\x2b\x95\x7e\xc9\x67\x05\x41\x90\x68\xac\x7f\xdb\x94\x67\x10\x5c\x16\x69\xee\xf9\x41\x7b\x0f\x4e\x10\x65\x5b\xa2\xef\xb0\x52\xa3\x07\x08\x64\x88\xb2\xdd\x07\xab\xf2\x8c\x44\xe5\x69\xbf\xb6\x63\x1c\xfa\x0c\xa8\x8c\x4c\xc8\xec\x22\xca\x54\xa5\xff\xc1\x9d\x7e\xf9\x99\x56\xa3\xc2\x3b\x08\x42\x1a\xa3\x85\x8b\x11\x16\x43\x95\xde\x09\x52\x41\x10\x86\xc2\xd3\x2d\x7a\x76\xa8\xc9\xed\xba\x24\x49\x98\xb4\x41\xe7\xe6\xc3\x60\xc4\xf9\xa1\xc8\x5f\x56\x39\xd2\x27\xa7\xed\xda\x0d\x22\xa2\x75\x9f\x99\xce\xc9\xfc\x39\x32\x50\x17\x78\x1a\x8e\x40\xe4\x2b\xcc\xae\xcc\x16\xb3\x4e\x40\xf3\xaf\x30\xe0\xa3\x5b\x58\x60\xe9\xb7\xd0\x18\xdb\x37\xf6\x3c\x8c\x50\x0d\x2a\xf8\x21\x88\x69\x80\xb7\xc8\xe1\xb3\xee\xdb\xd7\x41\xcc\x22\xac\xae\x18\xe8\xcd\x8d\x46\x29\x06\xdf\x95\xc2\x20\x5e\xf7\x72\x02\x27\x2e\xf7\x63\x1c\xad\xbb\x06\x6d\xda\x9b\x30\x3f\x40\x97\xc5\x4c\x84\xa7\xa2\xe6\xdf\xc5\x28\x02\x16\x09\x68\x43\x00\xd5\x06\xca\xdf\xd0\xc2\x1f\x15\x63\xbb\xce\x89\x40\xb6\xd3\xfd\x40\xa7\x1e\x02\x26\x63\x13\x57\x5e\x3f\x3d\xef\x0e\xab\xc5\xfa\xb0\xdb\xcf\xee\x96\xde\x61\xb3\x5d\xe2\xd6\x1b\x76\x3d\xb9\x23\x95\xff\xf3\xf3\xa9\x57\xc7\x36\x55\xee\x0d\x41\x02\x31\xb7\x29\xc0\xdf\xdc\x2d\x38\x31\x6a\x09\xb6\x0a\x76\xbe\x5f\xf4\x8d\xd1\x8e\x24\xb4\x1f\x78\xb3\xdc\xd0\xee\x0e\x21\xe9\x21\xd0\x50\x00\xc4\xb0\x0c\xda\xec\xe0\xe8\xad\x39\x63\x08\x67\xdb\xbf\xc2\xee\x23\xd5\xf5\xeb\xcd\xec\x1b\x86\xbd\xff\xaa\xec\x01\x02\x19\x08\x5c\x85\x69\x65\xab\x48\xdb\x1a\xd2\xe9\xad\x4e\xca\x08\xa7\xf9\xe3\x6e\x33\x5a\x00\xca\xd7\xc4\x28\x8a\x57\x15\x9e\x2c\x6e\xc0\x20\x00\x9f\x77\x42\x42\x50\xae\x73\xe8\x91\xc9\x40\x00\x8c\x63\x60\x13\xd0\x7d\x6d\xa6\xde\x35\xb0\x17\x02\x90\xe6\x1c\xea\xb4\x46\xfb\xfa\x04\x98\x8f\xc8\x3b\x17\xdb\x5e\xa4\x3d\x81\x07\xa3\x39\xac\xfe\x28\xea\xbe\x92\x4d\xff\x53\x53\xe2\x1b\xa0\x3f\x66\x89\x8e\x69\x3e\x6d\xb9\x50\xc2\x3d\xc4\x67\x72\xa5\x9e\xe0\xc3\x88\xf0\xfd\x18\xde\x48\x18\xb3\x74\x0f\x55\xbd\x2d\xfe\x92\x71\x08\x28\x51\xa6\x8e\x66\xf7\x0e\x59\xdd\xb8\xe6\xd7\x29\xdf\x89\xab\x3c\x16\xa2\x9b\xcd\x95\x1a\x44\x5c\xfe\x16\x98\x0f\xa8\x07\x8a\x5a\xea\x28\x28\xeb\x45\xf3\xc1\x87\x1d\x7c\x5f\x23\x01\x87\x40\xe5\x80\x55\x0d\xc7\x71\x07\x66\x34\x82\x16\x9b\x3d\x26\x43\xdb\xb0\x1e\xf5\x85\xf1\xd5\xda\x9a\x3d\xa0\xbe\xf4\x55\x8b\x9e\xfb\xe0\xa5\x7a\xe4\x75\x99\xba\xb4\x0d\x0d\x42\x62\x84\xab\x21\xcb\xe6\x45\xae\x46\x3b\x13\x0d\x54\x80\x81\x53\x6e\xfc\x42\xd8\x42\x55\x3b\xfd\x55\x77\x0f\x2a\x62\xd5\x03\x86\x9e\xc5\x50\x61\x7f\xf8\x19\xa9\x02\xac\x45\x44\x20\xe3\x67\x35\xa2\x4a\x03\x1a\x7a\x91\x7b\x5e\x9b\xfb\x1f\x28\x9d\xe8\xe2\x8a\x26\x62\x78\xff\x30\xf0\x7c\x9b\xe4\x45\xb3\xba\xee\x27\x84\x5d\x1f\x6a\x48\x44\x91\x64\xc9\xd4\x31\xba\x9f\x8f\x88\x8c\x2c\xba\x18\xa9\xfb\xdd\xdf\x63\x69\xea\xd6\xe6\xcb\x7f\xae\x37\x87\xe5\xaf\xc5\xfd\xec\xe9\x6e\xd9\xb6\x2a\x89\xc6\xd7\x22\x3b\x8b\x3d\xf0\xe3\x43\x21\xdf\x86\xc5\x93\x40\x99\x1f\xbb\x78\xde\x82\x97\x6a\xf0\x2a\xd3\x33\x85\x05\x81\xe3\x75\x3d\x9f\xdc\x71\xf3\x45\x57\x6e\x54\xa8\x2a\x0b\xea\xc3\x23\xbd\x1f\x10\x18\xf5\xe7\xc4\xc3\x64\x96\x7c\x7d\x33\x6b\x6e\x7a\x30\x39\xd3\x48\xb5\xd3\x16\xea\x0c\xc2\x34\x5f\x3c\x36\xe7\x81\x29\x99\x30\xd4\x54\x9b\xe5\xf6\xb0\xdc\xdf\x2f\xb7\x87\x9b\xd9\x9f\x87\xf5\x53\x3b\x68\x1c\x7c\x99\x58\x5c\xcf\x63\x91\xc3\x17\x31\x2f\x2a\xc0\x67\xac\xab\xb2\x43\x42\x39\xdb\x24\x3d\x30\x87\x4a\xcd\xdf\xe0\xee\xe1\xd7\x17\xaf\x21\x79\x12\x83\x1b\x48\x4c\xa1\x5d\x33\xc3\x02\x55\xc4\x18\xc7\xb7\x59\xf1\x79\xe9\xe7\x94\xa8\xf2\x19\x0a\xb2\x89\x73\x99\xdf\x8d\xe1\xf2\x40\x55\x20\x4d\xfc\xeb\x94\x4a\x78\x3e\x4d\x06\x0b\xa9\x4a\x28\xf1\x5b\x31\x99\xe3\x04\x5f\xd2\x34\x27\x94\x8b\x98\x52\x05\xb1\xe3\x7c\xc1\x3d\xbc\xc8\x86\xdc\xfb\x40\x81\x52\x3c\xae\xd2\xea\x91\xa7\x48\x95\xd9\xa5\x60\x29\x70\x21\xbb\x1a\x11\x37\x39\x5d\xa8\x64\xf8\x42\x5a\xf8\xf8\xac\x4f\xb3\xed\x94\x46\x98\xe9\x15\x7a\x61\x1c\x5a\x70\xd9\x73\xee\xb2\xcf\xc8\x66\xba\x2f\x4e\x5e\x48\x7a\x31\xd0\xd0\x13\x0c\x0b\xa2\x25\xa4\x19\x06\x20\x2d\x2a\xc2\x36\xfb\x84\x70\x07\x2a\x5b\xbe\xbc\xac\x1c\xed\x3b\x84\xbe\x95\xc0\x72\x51\xb6\x9f\x69\x6e\x90\x99\xfb\x09\x81\x89\xef\x77\xde\x30\x20\x1e\x22\x4b\x07\xf1\xc4\x2f\x06\xdd\x99\xcd\xee\x52\x5f\x63\x86\xa3\x1e\xd5\xea\xdd\xf0\x9a\x7f\x99\x47\x1e\xdc\x20\x30\x44\x3b\xe8\xc9\xa5\x43\x18\x0e\x84\x81\xf0\xb8\xcd\x17\x2d\x3f\xd3\xfa\x16\xc0\x45\xa8\xc2\x40\xf9\x18\x62\xc0\xca\x6d\x43\xab\x3f\xf2\x41\xc2\x40\x45\x18\x19\xb0\xf9\xef\xc5\x6b\x7a\x1a\x77\xa1\x1e\xd3\xc4\xc1\xb6\x72\x55\x1c\xfb\xe7\xce\xd8\xf1\x6c\xb6\x47\x44\x9e\xcc\x1e\x7e\xf5\xf7\xe6\x90\x26\x81\x88\x6c\x69\xa3\xe1\xc1\x03\x75\x9b\x96\xc7\xc1\x31\x1c\x52\x15\x52\x43\xb4\x6b\x18\x41\x46\x8f\x12\xfa\x41\x62\x1f\xa5\x2d\xcf\x76\x79\x87\x30\x8c\x84\x91\xdd\xe6\xef\xf0\x08\x35\x1f\x8c\xef\xb7\xdc\x69\x43\xac\xa4\x3f\x41\x4c\x3c\x9c\x0c\x21\x68\x00\x17\xfa\xef\xf4\xd8\x20\x8c\x68\x88\x03\x7e\xa8\xb2\xc2\xe2\x76\x9f\xe0\xc3\xb5\xc6\x40\x11\x74\x08\xc7\x53\x7d\x31\xf8\xe9\xe6\x2d\x3a\x7c\x1a\x84\x8c\x86\xd2\x79\xe2\x98\xef\xba\x2d\xca\x85\x53\x3c\xf5\xc6\x93\x92\x31\x43\x4f\xb3\x59\x6f\x9f\x5c\x14\x2b\x4c\x28\x47\x98\xba\xe2\xe5\x5b\x5e\x28\x43\x57\x24\x7f\x83\xd1\x96\x15\x26\x8a\x53\x7f\xac\xf3\xfb\x55\xc9\xfa\xe8\x87\x65\xa0\xb0\xc8\xc7\xe8\xcd\xff\x4c\xc7\x4e\x49\x28\x93\x08\x21\x35\x0e\x76\x22\x8b\x23\x54\x18\x0e\xfc\x4b\x4f\xff\x8b\x05\x08\x5e\x88\x62\x4b\xf3\xd5\x62\xbd\x7a\x72\x2f\x0b\x7e\x82\xfb\x3b\x72\x5d\xc1\xc0\xb4\x08\x81\x19\xe8\x8f\x53\x57\x5c\x7e\x72\x59\xff\x2c\xb2\xb7\xd1\xb3\x6a\xe2\x05\xd6\x26\x33\x58\xdb\x21\x7e\x6f\xc2\xa8\x9b\x9a\x21\x6e\xa0\x46\xcb\x41\x33\xa3\xae\x53\x16\xe7\x41\xc6\x29\x22\x31\x47\xcc\x64\x56\x18\xd5\x20\x4c\x3f\x18\x45\x41\xd7\x43\xf8\x88\x96\x2d\x2c\x6a\x69\x07\xb9\x9a\x5f\x1a\xb7\x45\x0e\xf8\x17\xbe\x0a\x90\xb9\x6d\xa8\xbf\x97\x44\x44\x68\xac\xee\x59\x2c\x1f\x1e\x76\x87\xfd\xfa\xf0\x38\xfb\x6d\x79\xf0\x0e\xbb\xcd\x72\xfb\xe8\x7e\xd9\xb3\x7c\x59\x5d\x14\x16\x9f\xee\xbb\x74\x71\xe4\x93\x04\xe9\x7c\xac\xb0\x61\x2f\x66\x1c\x05\x89\x2f\xed\x66\xdf\x56\xb3\x62\xac\xc5\x75\xa0\xda\x47\xda\x64\xeb\xa3\xb7\xa0\x93\xa1\xb4\x83\xed\x1c\x12\x1f\x2b\x1c\x30\x92\xe6\xbe\x42\x17\xeb\x8c\x42\x00\x2c\xee\xde\x94\x45\x5d\xec\x4b\x9e\x66\xfd\x7d\x28\x8a\xb8\xc7\x6c\x76\xd2\xd6\x07\xa0\x0a\xf0\xd2\x88\xe3\xff\xe8\x83\x09\xdd\x15\x4a\x62\xa5\xfe\xc1\x01\x8a\x4e\x67\x43\x3a\x6b\x40\x03\x93\x27\x6e\x14\x87\x71\xa8\x7b\x9b\xfe\x4f\x10\xc1\xff\x7e\x35\x76\x31\xe7\x98\xac\x3c\xb4\xb1\xba\xef\xcd\xa4\x28\xd6\x12\x6d\x2b\x04\x52\x9f\x2f\x8f\x3c\xbf\x60\xe9\x9b\x7b\x49\x16\x28\x2c\x21\x3e\x20\x1f\xdc\x2c\xcb\x9c\x8f\xea\xda\x29\x0b\x10\xb4\x5d\x64\x19\x22\xd8\x86\x4b\x22\x62\x31\x41\xb4\xd3\xe2\x7e\xbb\x1f\x3e\xcf\x97\xae\x4d\xc4\x12\x8f\xf7\xdf\x78\x7e\xd9\xbf\xa6\xa5\x6a\x2c\xf0\x2b\xc1\xe6\xc1\x6b\x4d\x53\x29\x40\xc4\x40\x71\x53\x25\x29\xcf\xed\x54\x49\xc2\x84\xb4\xf9\xc2\x9e\xfc\xde\x0e\xea\xda\x7c\xc2\x5b\x80\x9b\xd4\x20\x71\x86\x2f\x95\x24\x86\xcc\xd1\xc5\x37\xa7\x4b\x1b\xfe\xd6\x6e\x14\xf1\x10\x42\x17\xe0\x4b\x4b\x3c\xcb\x47\x41\xd5\x88\x0b\x8a\xe9\xa1\x8f\x74\x1a\x53\x0a\x91\xf4\x35\xb5\xee\xca\x2d\xea\xbe\x1c\x8f\xc6\xf0\x36\x25\x8c\x93\x96\x53\x24\x43\xce\x44\x2b\x33\x85\x89\x5f\x9c\x8c\xc3\x0c\x7f\xa4\xfc\x88\x7a\xd6\x40\x6e\x8c\x8d\xe5\x67\x5d\xf2\x3b\x5e\x2d\x3f\xbf\xc4\x1e\xb8\x2b\x19\xb5\x95\x05\xf5\x3c\xe3\x4e\x03\x10\x22\xf0\x0c\x12\x23\xcd\xd3\x7a\x9e\x15\xc5\xf1\x36\xcd\xea\x36\x1c\x10\x81\xf6\x30\xea\xda\x34\x1f\x14\xbc\x1f\x78\xae\x0e\x76\x33\x38\xf0\x6b\xd9\xa0\xe9\xb7\xd3\xa1\x42\x85\x17\x9b\x73\x76\x9a\xd7\x69\xd5\x7a\x53\x31\xd1\x01\x56\x90\x5b\x8e\x49\x43\xfb\xca\x1d\xcf\x1b\xc4\x9e\xaf\x31\x6a\x68\x09\x1d\x57\xd5\x53\x51\xa3\x0e\xf8\x54\x00\x21\xf6\x98\x44\xc2\xab\xc5\x6c\xe1\x6e\xe0\x93\x00\x61\x15\x58\x40\x83\x2c\xfb\x03\x0d\xe4\xa6\x83\x91\x23\x6d\x36\xe4\x23\x3a\x1f\x83\x11\x8c\xfd\x80\xf8\x2d\x5d\x7e\xaa\x56\xaa\x77\xc2\xc7\x7e\xa8\xd0\x44\xa8\x0b\xeb\xa2\xae\x6e\x06\x26\x50\x1c\xc4\x26\xcb\x82\x2e\xd0\xe1\x66\xb9\xfb\xed\x80\x11\x32\x77\x83\x40\x7a\x5e\x4b\x74\x39\x56\xae\xcd\xce\xd5\xbe\x4c\xe5\x5b\x06\x37\xc5\x47\xee\x88\x2a\xed\x95\x34\x32\x52\x84\x1b\x7e\x69\xe6\x1b\x0e\x4f\xf9\x63\xf0\xe8\x34\x31\x05\xd6\xa7\x73\xbd\x2f\x90\xb7\xdb\x36\x84\x92\x63\xc5\xca\xae\xc8\xd4\x53\x31\xba\x71\xc4\x25\x89\x1d\xb9\x7f\x96\x01\x4c\x32\x15\x40\x1c\x49\xdf\xf1\x03\xaf\xf2\x77\xc8\x31\x41\xf3\xed\x42\x8b\xe3\x58\x26\x49\x2f\xe7\x3f\xa8\x31\x1d\xde\x3d\x66\xbe\x76\x72\x55\xbf\x8d\x3e\x49\x2c\x25\x5a\x0f\x07\x89\x42\x71\x93\x05\x19\xe7\x1e\xc6\x24\x8e\x35\x60\xca\xc6\xa9\x18\x0d\x14\x0b\x6c\xe1\xe6\x30\x6a\x38\xd8\xd2\xec\x5d\x58\x20\x9d\x28\x15\x26\x7c\x9f\x77\x37\x72\xb9\xbf\x77\xe3\xc6\xac\x58\x37\x72\xd7\x15\xed\x5f\x23\x86\xa5\xe3\xd7\xec\x24\xff\x43\xff\x75\x75\xc8\x7b\x1d\xa2\x6a\x42\x32\x08\x62\x26\x12\x57\x22\x69\x38\x73\x72\x9d\x5e\x69\xb1\x8c\xae\x49\x88\x12\xbe\xab\x14\xac\x90\xf6\x0e\x94\x89\x9a\xdd\x9c\x7b\x45\xd6\xb6\x3b\x6f\x9c\xa3\xc6\x50\xc9\x8c\x0b\x37\x74\x50\x62\x49\x94\x20\xfd\x09\xdb\xcc\x21\x77\xad\xf4\x62\x16\xd9\x4a\x08\x75\x9b\xe6\xad\x51\x10\x4b\x6d\x04\xf0\xdf\xd2\xfc\x65\xde\x89\x91\x42\xac\x62\x5f\x50\xf7\x46\xd5\xb5\x08\x33\xc4\x2a\xf1\x71\x05\xdf\x41\x0e\x55\x5b\xf4\x75\x45\x0b\x34\xb9\x2b\xc7\xe0\x31\xb4\xd2\x1b\x9b\x78\xa0\xfe\x36\xdc\x38\xc0\x27\x58\x59\x6a\x00\x09\x4f\xf0\xf1\x9d\xec\x08\xc4\x10\x12\x66\x23\x38\x98\x79\x6e\xfc\xf8\x02\xf1\xa9\xae\xce\x13\x62\x48\x28\x02\x77\xb3\xe2\xe5\xa5\xf3\xbe\x63\x1d\x98\x0a\xca\xff\xcb\x15\x34\x2e\x75\xdf\x9c\x89\x75\x22\x31\x22\xf8\x9e\xc2\x07\x65\xed\x5f\x65\x88\x0c\xb2\xc7\x73\xf6\x65\x51\x36\x30\xa2\x62\xe4\x3a\xb0\x9b\xad\x83\x92\xdb\x56\x2f\x34\xf2\x9c\x56\x8a\xba\xd9\x34\xa0\xc7\x51\x08\xcc\xd3\x01\xc8\x16\xb3\x81\x4f\x35\xc4\x8f\xf7\xc0\x7e\xdf\x01\x02\xdb\xdb\x85\xae\xea\xcd\x0a\x0c\x98\x4a\x64\x0b\x6a\x59\xf0\x5c\xb9\x3d\x9e\xf9\xcc\xd4\x38\x3e\xe7\xc6\xf0\xff\xfe\x48\x63\x3e\x97\x2e\xda\x80\x33\x09\x79\x3f\x47\x5d\x80\x1b\x11\x77\x53\x52\xb4\x05\xae\x5c\x16\x8d\x05\xbe\x87\xa6\x6d\xc6\xab\x7a\xa9\x75\x2a\x53\xc8\xcd\x8d\xfa\xa4\x75\x4d\xbf\x18\xbd\xa2\xdf\x4e\xc5\x69\x01\x19\x88\xb6\xc1\xea\xfe\xdc\x9c\x8f\xc7\xcb\x37\x84\x2a\xa3\xc7\x0e\x24\xb0\x76\xa7\xb7\x5c\xbd\xa3\xc7\xa6\x92\x20\xb3\xc7\xbc\x28\xaa\xfa\x98\xba\x1f\x8c\x40\x4a\x3b\x96\x0f\xbc\xaa\x71\x1a\x0f\x03\x3e\x2c\x0e\xa8\xe1\xb5\x3d\x97\xf9\x2d\x3f\x4b\xa8\xd7\x79\xdb\x26\x03\x61\x68\x9c\xcb\x97\xd4\x59\x16\x63\x9c\x39\x63\x84\x39\xa2\xba\x66\x36\x0f\x74\xb7\x80\x31\x9f\x27\xb6\xd5\x1c\xd1\x55\x4b\xe6\x3e\xdc\x1f\x18\x4b\x00\x9f\x04\x72\x35\x9a\x82\x89\x10\x38\x00\x26\x89\x8d\x79\x80\xc7\x73\x95\xca\xd1\x20\x24\x8a\x0b\xea\x8e\x15\xb7\x67\xba\x1d\x86\x71\xc2\xd1\xd6\x6d\xe6\x71\x63\xe9\x4f\x6c\x18\x8c\x53\x00\xbf\x93\x5f\x99\x65\x19\xaf\xd7\x9d\x35\xc5\x44\x60\x32\xb5\xce\x57\x6e\x66\xdd\xd0\xe0\x62\x22\x96\x18\x01\x74\xbc\x6c\x85\x4e\x33\x18\xeb\x61\x02\x13\xca\xc3\x3b\xcd\x94\x32\x39\xcf\x91\xe7\xcc\x84\xf2\xfd\xe6\x65\x0a\x51\xf3\x34\xb7\x21\xcb\xc9\x9d\x8a\x49\xdf\x50\x3d\xb8\x8d\xd5\x7e\xe1\xf6\x5c\x66\x92\x0a\xa1\x9d\x94\xf0\x95\x98\x46\xd3\x2e\x23\x27\x02\xb9\xe1\x97\x3d\xf0\x63\x7b\xa9\x90\x88\x42\xe6\x4a\xe1\x80\x81\x32\xf0\xbd\xc9\x4c\x36\x93\x56\xf8\xad\x82\xfa\x09\x3e\xae\x89\xc9\x80\xa9\x38\xd4\x26\xf6\x61\xc8\x10\x6e\xcf\xb9\xaa\xfa\xc4\xd3\xc0\x20\xf4\x0d\x87\xb5\xe1\x7e\x68\x53\x5a\x93\xa7\x3d\x83\x24\x41\x1f\xd5\x8c\x37\x1a\x24\x0e\x69\x34\xfc\x65\x1d\x78\x32\xe8\x36\xea\x73\x96\xed\x53\x9b\x1a\xf5\xda\x3e\x49\x82\x41\xfd\xf4\xd8\x9c\x71\x4e\xe9\x60\x54\x34\x32\x50\x61\x1c\x3e\x8c\xd6\x46\xd5\xdf\xa0\x18\xfb\x05\x4f\x90\x78\x2c\xc6\x7d\xed\x6c\xd5\xcd\x46\x63\x97\x78\x89\x0a\xdd\xfc\x1c\x3e\x7a\xe3\x50\x71\x5b\x8f\xd0\xcc\xa4\x3e\x5d\xb1\xeb\x21\x18\x0a\xdd\xa2\x7c\x0d\x72\xc9\x76\x4c\x52\x90\xf8\x91\x49\xae\x58\x6a\xcf\xe1\x8c\x4d\x7c\xe5\x0b\x0b\x06\x44\x00\x5c\x06\x6d\x52\xec\x1f\x13\x27\x5e\xe2\x2b\x6a\xc9\x53\xac\xcf\xd5\xde\x08\x74\xd8\x83\x74\x01\x94\x8b\x73\xfb\xfa\xbe\x36\xe2\x6c\x2f\x50\x3f\xa7\xd3\xe4\x36\x90\x04\x9e\x61\x2e\xaa\x1d\xa9\x4c\xef\x3c\xb5\x5d\x68\xcc\x71\x18\x9b\x9d\xe0\x7c\xb2\xaa\x21\xae\x4d\x28\x74\x3d\x0d\x77\xe0\xf3\xe9\xa5\xe4\x0a\x90\xea\xdb\xb2\x36\x77\xa7\x56\x42\x65\xec\x6a\x8d\x1e\xa1\x7c\xcb\x60\x5f\x02\x74\x82\xeb\x2e\xdd\x9b\x50\x15\x05\x56\xdc\x7b\x03\xf5\x4a\x3d\xf2\xd3\xa9\xcf\x53\xd0\x0f\x3d\x26\x54\xc5\xe8\x1b\x49\x5e\x16\xe7\x8a\x67\x86\x37\xc8\x35\x02\x24\x16\xa3\xd6\xe2\x55\x5c\xbd\xd8\xe8\x83\x87\xdc\xb0\x07\x3a\xa9\x90\x27\xf8\x78\x84\x66\x19\x7c\x05\x62\x4d\x42\x0d\xdc\x04\x4c\x0d\x11\xda\x68\x7e\xc4\x5c\x09\x33\x6a\x5c\x21\xf5\x69\xab\xdf\xe8\x9e\x2e\xd6\xb1\x36\x7b\x7d\xd5\x79\x73\x09\x8b\xb5\x96\x6e\x41\x7f\xd6\xae\x30\x68\xbf\xff\x69\x99\x6b\xbc\x41\xec\x35\x61\x96\x00\x0f\x72\xd5\xf2\xdc\xba\x7b\x25\x3e\xb1\x42\x5c\xfc\xed\x8a\x18\xb4\x69\xd6\x8a\xb5\x89\xe6\xb5\x5e\xf0\x53\xed\xe2\x6f\xee\x8c\x48\x12\x6a\x4a\xf4\xd6\xc7\xb4\x7a\x69\x47\x96\x87\x34\x30\xae\x60\xf9\xd6\xb2\x2d\xb4\x35\x6a\xc3\xa1\xe5\x8c\xb2\xa4\x3b\x12\x6f\x4a\xfe\x71\x7d\x84\x27\x5c\x99\x82\xb9\x23\x28\x9e\x7d\xcb\x23\x09\x8d\xa7\x24\xfa\x95\xb9\x9b\xc2\xc8\x26\xba\x66\xea\xa1\x52\xdf\xe3\xea\xe9\x70\xbf\x7e\xb8\x59\x6e\xad\xe0\x8a\xeb\x20\x09\x43\xd1\x21\x91\xd6\x7d\x92\x67\x48\xa4\x1f\x39\x37\xe9\x78\x39\x15\x55\xdd\x18\x1e\x69\x3b\xdb\x65\xac\x69\xd0\x89\xb0\xde\xa5\xaa\xc7\x3f\x02\x89\x14\x14\x7d\x8e\x87\xe2\xc5\x00\x07\xc7\x74\xa8\x90\x48\x20\x18\x46\x37\x5c\x44\xab\x5c\xa5\x25\xc8\xba\x5f\x17\x94\x48\x10\x86\xc7\x32\x4f\xeb\x65\xfd\x8a\x54\x9b\x83\x9b\x70\xe2\x45\x68\xd1\x3a\xee\xe2\xf6\xbb\x76\x8b\x8d\x13\x16\x99\x75\x61\x2c\xcc\xa6\x0b\x7c\x8e\x50\x63\x9c\x28\x0f\x31\x9c\x0a\x4e\x59\x71\x79\x4c\xf3\x7e\xb6\xdf\xcc\x02\xbb\xf5\x0e\xfe\x8f\xbd\xda\xa3\xb1\x8c\x5b\x2b\xe4\xd4\x58\x3a\xed\x93\x0c\x1f\xd8\x8b\x43\x67\x4e\x75\xee\xaf\xeb\x5b\xcd\x2f\xb6\xbc\xfb\xeb\x68\xea\x28\xd5\xc1\xbd\xc4\x63\x36\x52\xf2\xc8\x3f\x6f\xd2\xea\x94\xf1\x4b\x8f\x55\x08\xb8\xef\x49\x4c\x86\x2c\x57\x8b\xbf\x19\x46\xe3\x7e\xa0\x5c\x61\xc0\xa6\x2c\x8e\xc5\xe3\x75\x80\x81\xfb\x3c\xc0\xc3\xd4\xc6\x49\x6f\x01\x7a\x05\x10\xc3\xae\x81\x1f\x83\x21\xf4\xae\xcb\xf3\x88\x53\x00\x38\xf5\xbd\xd0\xeb\x06\xaf\x86\x03\x75\x56\x2f\xa7\x36\xaf\xd4\x3c\x08\xbf\x34\x1b\xc8\x40\xce\x76\xf0\xd0\x54\x6a\x74\x51\xaa\xb3\xb8\x81\x77\x77\x87\x90\x4b\x0c\x60\x63\x6d\x5c\x5a\x94\xf3\xf6\x50\xe4\xa1\xf2\xb0\x5c\xd0\xe2\x08\x8b\x12\x8d\x8c\xef\x44\x33\x80\x47\x71\x18\x88\x16\x14\xfb\xbd\xc9\xcf\x23\x19\xd2\x41\xd2\xca\xae\xf3\xef\x02\x91\xd7\x77\x89\xc3\x18\x1f\xf3\x85\x57\x5b\xa8\xa0\x7c\x6f\xbf\x6c\x0c\x34\x72\xc0\x93\xb4\x9c\xaa\x68\xe3\x8c\x46\x61\x87\xa0\x69\xd9\x8c\xdd\x1d\x98\xa4\xaa\xe3\xd0\x9a\xef\xf6\x56\x60\x6f\x2a\xbd\x6b\x2f\x49\x42\x8e\x8a\x31\xe7\xbc\xe2\x1a\x90\xf1\xec\x39\xcd\xa7\xb5\xf2\x81\xf3\x38\x14\x76\xc7\xdb\xf3\xea\xad\xf9\x7a\x66\x12\x0e\xcc\x6f\xce\xb5\x87\x96\x1e\xc6\xd3\x27\x23\xb1\x5c\xf8\xbe\xa3\x43\x68\x56\xce\x26\xeb\xef\x99\x5c\x84\x31\x5a\x99\xb3\x87\x87\xf5\xe2\xb0\x58\x3f\x3e\x3e\x3f\xad\xf6\x7f\xb6\xcd\x9c\x60\x49\xb9\x35\x8c\x2d\xdb\xc6\xf5\x3a\x9b\x7c\x07\x19\x29\xac\x2c\xbc\xe5\x6f\xf0\xcf\xad\x2b\xb1\xe0\x92\x51\x0c\x82\x2e\x5e\xa1\xaa\x0d\xda\x62\x34\xb3\xc1\xd3\x68\x51\xf0\x2c\x33\x05\x83\xfb\x96\xd4\xa9\x59\xed\xee\x46\x10\x02\xa6\x56\x11\xf9\x5c\xad\xf5\x4e\xbe\xc2\xb8\x12\x82\x83\xf4\x91\x04\xa3\x46\x59\x7e\x74\x30\xfc\x42\xfb\xed\x3d\x20\x40\xb4\xfd\xc3\xea\x71\xb5\x47\xc8\xc2\xf3\x6e\xb9\x75\xad\x1a\x62\xe1\xcc\xbb\xc5\xc3\xb0\x8e\xd6\x74\x11\x84\x46\xe8\x6e\xcd\x53\x35\xc3\xb9\xfd\xd5\x12\x10\x84\x1b\x58\xb9\x11\x4a\x7f\x4c\xb1\x54\xf7\xe6\x5c\xf6\x8b\x2e\x84\xaf\xfc\x48\x74\x34\x1b\x33\xb7\xe8\x44\x20\x13\xcf\x08\x91\x61\x32\x60\x0b\x0a\x8e\xa7\xeb\x62\x8c\xe6\xe0\xc2\xf4\xa6\xe0\xb5\x7c\xed\x2c\xb1\xca\x91\x42\x4d\xc9\x91\x5f\x6f\x8f\x82\x52\x0f\xb3\x3a\xe6\xc3\x3f\x20\xef\x5b\xe1\x84\x9a\xbc\x2b\xc8\x82\xbb\x2a\x8a\x02\xeb\xcc\xdd\x17\x99\x1a\xeb\xd7\x80\x08\x7d\x1f\x17\x41\xaa\x9c\x1d\x20\xc2\xd8\x0b\x7a\x49\xec\x89\x2d\x53\x84\x8c\xe2\xbb\xcf\xee\xa6\x90\x5a\xfd\xcd\x4c\x44\x54\x63\x25\xea\x66\xfd\x34\x6b\x63\xab\x7d\x81\x3e\xd7\x2f\x34\x25\x5c\xca\x0a\xf8\x55\x23\x6d\x47\x10\xb1\xcf\xb0\x9a\x21\x55\x90\xd7\xa9\xbe\xb4\x7f\xe7\x02\x7f\x01\xeb\x59\x57\x47\xfe\x02\xab\xfc\x74\xfe\x12\x92\xf0\x3f\xff\xb2\xa5\x2d\xed\xc1\x2a\x62\x01\xc2\xd0\xa8\x62\x78\xae\xbc\x87\x12\x54\x2f\xc8\x6d\xbb\x31\xce\xb8\x71\x4a\x31\x04\xb0\xba\x19\x8d\x0a\x13\x49\x60\x35\x15\x24\x3c\x9e\xb3\x3a\x3d\x65\xe9\x88\xf6\x1c\x44\xe2\xfb\x08\xe0\xec\xb8\xdb\x10\x87\x7b\x57\xf0\x6c\x0b\x5c\xbe\xb6\xbe\xb6\x48\xa2\x00\x4d\xbd\x63\x9a\xd7\x83\x64\xac\x10\xb1\x06\xc4\x40\xdd\x94\xfc\xa5\x9b\xab\x82\xfb\x08\x4c\xb9\x5f\x3f\x6f\x1f\xfe\x3c\xfc\x31\x7b\x78\x5e\x1e\x6e\x96\x8b\xd9\x9f\x87\xed\x6c\xbf\x6c\xbb\x29\x5f\x0c\x38\xd5\x6e\xcf\xb9\xfc\x3e\x8e\x27\xa4\x4f\x7a\xa2\x6d\x8b\xe2\x74\x29\x91\x4c\x79\xa4\x17\xff\x45\x9a\xf7\x6f\xc4\x67\x84\x0c\x8d\x1c\xcd\x01\x83\x7a\x79\xcf\xb7\x12\x32\xe6\x8e\x77\xce\xaa\x86\x5a\x22\xcc\x96\x85\x14\x84\x54\x34\xb6\x51\xf3\x55\x35\x3f\x5f\xba\x90\x9f\x50\x0a\xb0\x84\xb2\xb7\x44\xbf\x3d\xee\x84\xd2\x1a\x01\xe7\x07\x2c\x6e\x7c\x38\xcb\xf1\xfc\x07\x8f\x49\xed\x92\x1a\x77\xfc\x78\x37\x10\x16\x01\x01\xd4\x43\x3b\xc1\x9c\x46\x9b\x12\x34\x94\x88\x3e\x68\x8e\x8e\x6f\xb9\x8b\x40\x80\x32\xb2\x82\x1f\x37\x29\x3f\x16\x6d\x0d\x9b\xd0\x09\xc3\xe0\xd4\x26\x7d\x79\xb9\xf4\x92\x09\x92\x04\x14\x73\x20\x60\x2b\x1f\x73\x95\x75\x2f\x2f\x89\x52\x88\x68\x77\x5a\x17\x83\x1f\x93\x9e\xa7\x11\x64\x37\x9b\x2f\x06\x5b\xfa\x5f\x25\xf2\xdc\xe5\x81\xd7\xa9\xce\xec\xbb\x94\xa8\xf4\x78\x90\x58\x7f\x6f\xde\xbd\x83\xf4\x59\xe2\xe2\xb6\x5b\x0b\x43\xaf\xa6\x4e\x7b\xe9\x8b\x08\xcb\x41\x05\xe8\xa2\x04\xcb\x59\x3d\x7a\xf6\x20\x64\x78\xd4\xda\x4c\xf2\x0e\xc5\x06\xaf\xa1\x7c\xae\x37\x93\x4e\x42\xfd\x60\xe4\x69\x1b\xa7\xaa\xdb\x04\x64\xd0\x98\xfa\x7d\xd1\x4b\x23\xfd\xf1\xc5\x9b\x07\xe0\x3b\x42\x95\x87\x87\x3f\x8c\xdc\x8d\x9f\x0c\xa2\x53\x32\xd0\xd2\x18\x96\x59\x51\x41\xe7\xc8\x0d\x6f\x44\x99\xe4\x61\x2b\x26\x0a\xa5\x23\xb8\xff\x42\xc4\x0d\x24\x15\x12\x74\x2f\x3a\xd2\x96\x0e\xcd\xcf\xa3\x69\x2a\x43\x45\xe2\xa8\xa7\xe2\xf6\x8c\x18\x6b\x50\xb3\x5c\x3d\xe7\x36\x3a\xa7\x86\x38\x04\x77\xa5\x36\x22\x0e\xfc\xac\x46\xca\xfd\x20\xa3\x50\xa0\x07\xde\xd5\x06\x3c\xf2\x34\xff\x23\xe5\x5b\xc8\xf8\xe5\xaa\xb3\x0c\x59\x4f\xaf\xe0\x91\xbf\x59\xeb\x61\x10\xae\x92\x51\x62\xd4\x27\xe7\xf3\xfd\xa2\xbf\x94\x64\xa4\x42\x2c\x18\x39\x36\xfb\x29\x56\x32\x7d\x91\xf3\xbc\x3e\x33\x65\x4c\x48\xd4\xc1\x45\x5e\x4b\x80\x7e\xea\x43\xc6\x9e\x40\x1c\xe8\x43\x61\x14\x31\x2d\xfe\xf4\x6f\x19\xb3\x32\x66\xa6\xa0\x5d\x9c\x2f\x87\xe5\xa7\x7c\x7d\x39\x88\xa2\x78\x1b\xc7\x34\xfe\x12\xfc\x23\x63\xcd\x0d\xe0\xee\x7a\x4c\x18\x49\x9c\xbc\xd1\x63\x91\xd7\xaf\xee\xc4\x18\x7d\x65\xa6\x0c\x4c\x6a\xb1\x5d\xff\xbc\xd9\xcd\x1e\x96\x87\xfd\x6c\x7b\xb7\xdc\xbb\xdb\x70\xcb\x21\xbc\xd8\xec\x06\x23\xcb\x23\xa5\x7b\x1e\xdc\x1f\x69\xde\xc6\x31\xa4\xf0\x29\xae\x16\x3c\xca\x6e\xfa\xd9\x42\xd7\x81\x1a\xbd\xa9\xbb\xed\x72\x3f\xb8\xab\x88\x09\xf2\xc8\x9c\x2b\x98\x55\xcd\x36\x55\xb6\x9a\x75\x20\x65\xe0\x21\x97\x21\xa2\xf7\x5b\x6a\xaa\xe6\xef\x02\x57\x13\xcf\x32\x43\xf4\x7a\x2e\xbb\x67\x51\x7e\x6c\xaa\xff\x40\xd7\x2c\x1a\xbd\xbc\x62\x2c\x36\x5c\x58\x9f\x58\x30\x3b\x9a\x7e\xe0\x81\x11\x4a\xb7\x89\xc7\xdd\xeb\x59\xeb\xfe\xf6\x08\x3e\xc1\x12\x28\x4b\x7b\xe3\x82\x14\xa8\x55\x7c\x5d\x34\x2d\x41\x45\xf8\x76\x5c\xa9\x4d\x09\x2a\x1d\xf0\x41\x4e\x27\x2f\xaf\xbe\xff\xf0\x09\x75\xcc\x6c\x76\xe0\x0d\xbe\x0a\xd2\x0e\x2c\x2a\xa9\x45\x60\x22\x87\xd2\x64\x8e\x43\xa7\x62\x6d\xda\x15\xf1\x01\x19\x25\xfe\xb7\x48\xf3\xbb\xb2\x38\x0f\xf9\x69\x41\x11\x0a\x46\x15\xba\x6c\xb6\x0c\xf4\xb0\x83\xf6\x5a\xe9\xc5\xcd\x31\x7f\x5b\x14\x6a\xc7\x35\xd4\x17\x03\xdf\x72\xcd\x5a\x5a\xce\x39\x83\x01\xc5\x14\xe3\x54\x1d\x8d\xf2\x3c\x16\xb8\xad\xa7\x04\xd8\x75\x25\x60\x2a\x08\x3c\x9c\x77\x38\xe3\x11\xa0\x6e\x19\x3e\xf9\x67\xdb\x45\xc7\x86\x2d\x91\x1f\x61\x7b\x2d\x83\x02\x8a\x86\x92\x33\x77\xda\x23\x4f\xbc\x75\xc6\xda\xfd\x5c\xd1\xd8\xb3\xe0\xe7\xfd\xec\xe1\xf0\xb8\x7a\xba\x31\x11\xa3\xc3\xee\x79\xb3\x79\x70\x0e\x95\x0a\x09\x0f\x7c\x4b\x12\xf6\x32\x00\x55\xd8\x0e\x51\x68\xb4\xcb\x5c\x89\x6d\xef\x4d\x62\xcf\x37\xa5\x8a\x43\x2d\x00\x4c\x94\xb6\x7d\x7c\xdf\x8b\xfb\x34\x7c\x8f\x69\x9e\x1e\xcf\xc7\x3d\x7c\xd6\x4e\xac\x7a\xf4\x8b\x31\x70\x87\x4f\x9f\x99\x58\xf3\x30\x98\x62\xbb\xb1\x30\xc6\xe8\x5a\x85\xe1\xa0\xbe\x16\xcc\x24\xce\x52\x25\xbe\x11\x67\x9f\xa9\x12\x72\x9e\xa5\xf9\x5f\xd9\xee\x8a\x13\x40\xbe\x58\xe0\x25\xb2\x38\x21\x5b\x1e\x7e\xab\xb5\x5e\x40\x96\x4d\x13\x5a\xa3\x60\x57\x62\x78\x88\x4c\xe0\x75\xf4\xe0\xdc\xf7\xb1\xd8\xa3\x68\xbe\xfd\xa6\x39\x8b\xb7\x20\x11\x89\xdd\x8f\x2d\x2b\x1e\x05\x58\x5e\x2c\xc0\xd0\xcc\x1d\xdc\x90\x0a\x2f\xa6\x41\x57\xe5\xc0\xaf\x02\xb5\x4a\xc4\x26\x02\xbe\x58\x1f\x6e\xd7\xcf\x4f\x37\xcb\xed\x61\xb3\xde\xee\x57\xeb\xa7\xf6\x1e\x49\xd8\x23\x3b\xfd\xe7\x34\x7d\x77\xd3\x0d\x1c\x50\x79\x53\xc2\x31\x6d\xd3\xcb\x4a\xa8\x18\x8b\xb6\xf0\x70\xdf\xf0\xba\xd9\x2b\x06\xbe\x97\x12\x10\x78\x6a\xa0\xdf\xdc\xaf\x46\x53\x32\x89\xa2\x36\xa0\x31\x59\x28\xaf\x64\x62\x84\xa9\x56\xb9\x2a\xca\x6a\x50\x9d\xa1\xa4\x0e\x09\xc7\x7d\x23\xcd\x6f\x66\x0e\xaf\xaa\x94\x67\x14\xea\x54\x01\xd5\xa6\x2c\x0a\x8d\xd5\x84\xd3\x5f\x79\x8c\xba\xb4\xb7\x00\x1a\x7b\xb8\xf8\x8a\x7d\xb1\xcb\x00\xc6\xfb\x87\x0e\x09\x7a\xf9\xf3\x3b\xaf\xff\x44\x40\x48\x0c\x3d\x1d\x98\x5d\x9a\xbf\x64\x2d\x87\x69\xb3\xb8\x07\xb7\x01\x92\xc4\xa1\x5d\xc2\x8f\x97\xc5\xb5\xbf\xe6\xba\x89\x30\x34\xc9\x44\x8b\x87\xa9\xfa\x35\xb0\x40\x54\x82\x3f\x6a\x11\x87\x6e\xd9\x81\x47\x3d\x44\x62\x6f\xb6\xeb\xdd\x7d\xf7\x47\xaa\xf4\x20\xb5\xb9\x03\x50\xb3\xea\x36\xfd\x04\x85\x01\xe7\xdb\xa2\xb4\xfc\xbd\xc3\xa7\xf0\x98\x49\x46\x63\x9e\xa3\x59\x00\x2b\xf5\xb9\xd6\x57\x8c\x9a\x00\x9e\x0c\xd1\x28\x2d\x72\xb8\x2f\xce\x25\xba\x76\x63\x4f\x16\x3c\x88\x91\x9f\xa1\x2d\xe3\x9a\x9f\xcb\xe1\xd9\x0f\x9e\x0e\x75\xd2\x71\xce\xa8\x9f\x69\x6e\x8a\x7f\xc7\x89\x63\xf0\xa9\xef\x19\xa6\xeb\x5e\xd4\xb8\x6d\x0b\x63\xe2\x1c\xa7\x7a\x7c\xa1\x94\x68\xc1\x18\xc4\xc1\xf2\x1d\xca\x4b\xfd\xda\x1d\x8d\x10\x44\xb1\x87\x12\xdf\x5c\x1d\xd3\xbc\x55\xaf\xbd\xbd\xda\x8d\x21\x48\x7c\xd9\xc3\xd8\x7c\x1f\xe9\x87\x40\x52\x53\x6d\xd2\xac\x06\xb4\xca\x3a\x4b\x00\xa8\xcf\x90\x70\xf4\x71\xf6\xeb\x70\xfb\xfc\x74\x73\x98\xed\x76\xcb\xfd\xae\x6d\x0e\x63\xdd\xc6\xa7\xf3\x36\x98\xd0\x6c\x4c\x98\xcf\x1b\xcc\x64\x08\x23\x81\x39\x81\x9a\xbf\x41\x71\x1e\x9d\xe5\x10\x26\x12\x9d\x38\xdc\x86\x5a\x0e\xf2\xc9\x87\x77\x99\x19\x88\x24\x18\x35\xf1\xed\x12\x2d\xad\xe5\xfe\xfe\xb0\x7a\x3a\xfc\x5c\xae\x0e\xb3\xc5\x62\xb9\xd9\x2f\x6f\x9a\xa3\xc6\x3d\x6e\xcc\x42\x24\xc9\x69\xf5\x22\x51\xc8\xf3\x5b\xa8\xa4\xbd\x92\x31\x0f\x2d\xa2\x43\x55\xf3\x7c\x18\xc0\x62\x5d\x21\x71\xcf\xc2\xb8\x56\x32\xe8\xb6\x52\x48\x08\x03\xd5\xf3\x47\x53\x09\x8b\x73\xf9\x0e\x3b\xa8\x6b\xa4\xe7\xfb\xc2\xd6\x9d\xb6\x7d\x21\xf1\x03\x7c\xad\xfe\xc1\x3c\x3c\x02\x20\xa1\x86\x4e\xb0\x85\x29\x5d\xfd\x44\xff\xf1\x42\x1d\xd9\xe0\xb8\xa8\x2f\x72\xa2\x50\x0c\x92\xd8\x47\x71\x21\x55\x9c\xaf\x8a\xe9\x41\x78\x31\x18\x01\x5f\x7e\xae\x5f\x8b\x32\xfd\x0f\x20\x81\xbd\x61\xd3\xba\x5a\xa3\x82\x6a\xb4\x4d\x66\xbb\xbd\x83\x29\x82\x10\x81\x0d\x22\x39\xea\xcc\x9f\xe9\x28\x92\x07\x92\x00\x82\x09\xca\xbe\x9f\x33\x1a\x1a\xe5\xc5\x51\xec\x84\x73\x1f\xd2\xaa\x76\x75\xad\xa3\x67\x50\x9e\x81\x06\xc2\x67\x0d\x79\xe5\x4a\xc4\x5c\x63\x62\xe0\x4d\x1b\xa7\x41\xde\x78\x6b\xae\xcc\x63\x74\x23\x88\xa5\x24\x9d\x9c\xcc\x6d\xca\xbf\x97\x60\x04\xd0\x89\x0a\xc3\x81\x24\xe2\x4a\x21\x96\x63\x48\x43\x65\x7a\x6b\xe2\xc5\x7a\x98\xd4\x70\xa1\x5a\x4d\x42\x1d\x85\x3d\x59\xd5\xd5\x49\x57\x03\x11\xe0\x5e\x0a\x4c\x13\xd0\x78\xaa\x58\xb9\x74\xe0\xc7\x4d\x51\x64\xab\xbc\x99\xdf\xa3\x9d\x49\x13\xad\x44\x5b\x11\xf2\x50\xf0\x7c\x9d\xcf\xe1\x95\x67\x7a\xad\xb7\x20\xcf\x65\x75\x5d\xb2\xfc\xad\xe9\xa3\x3d\xe6\xf9\x76\x82\xe1\x7c\x5f\xc9\xeb\xe2\xc5\x6f\xa7\xbc\xf6\x3d\xa9\xfc\x4e\x31\x83\x5f\x4f\x2b\xed\xfb\x1c\x11\x3c\x18\xf9\x9b\xa5\xe5\x4d\x59\x9c\xfe\x66\x9e\x4a\xfb\x71\x82\x95\xa6\x6e\x03\xbf\x05\xf8\x36\x7d\xa3\x03\x4e\x50\x7e\x60\xb3\xd9\x2c\xfe\xc6\xfd\x03\x99\x60\x1a\xf3\xc6\x58\xb9\x8d\xd7\x3f\x7a\x7a\x4a\x13\x0c\xcb\xef\xce\xaa\xa8\xce\xb2\xe5\xdf\xd2\x34\x01\x08\xba\x09\xd6\x86\x27\x75\x48\x63\x65\x57\x5d\x76\x70\xd4\x7a\xfd\x3c\xb3\x0e\x43\x19\x5b\xe4\xe3\x9c\x67\x59\x51\xaf\xf5\xce\x58\xaa\xae\x03\xa7\x49\x07\xfb\xb3\xca\xdb\x69\x91\x3f\xe7\x69\x1d\x75\x9d\xa4\x30\x52\xf0\xa2\xd5\x41\xb5\x99\xae\x2d\x1e\x5d\x13\x6a\xdc\x93\x76\xa9\x0e\x85\x46\x10\xde\xb3\x0d\x18\xa1\x08\x5f\x2f\x94\xa6\x23\xa6\x10\xc4\xd1\xf8\x1d\xb7\x69\xde\xac\xbd\x2f\x95\xbe\x47\x1f\x24\xd2\x26\x1a\x85\x21\xc3\x1e\x0f\x94\xe7\xee\x1d\x7b\x89\xb0\x0b\xe9\xf7\x33\x2f\x6b\x28\x2d\x4d\xe7\xf0\x3e\xb1\xcf\x11\x89\xd3\xa3\xdd\x1c\xf3\xf4\xe8\x38\x00\x21\x3a\x92\x82\x2b\xa1\xc1\xa6\x87\x46\xf3\xe1\x06\xde\xab\x81\x32\x03\xe8\x58\x29\x34\x1c\xef\xa0\x9e\x43\xbd\xfa\x6a\x82\x31\x22\x84\xcd\x52\xdd\xf0\x9a\x1f\xbc\xf6\x45\x58\x62\x52\x06\x86\x8a\xe2\x4b\x46\x10\xcd\x20\x08\x6d\xf8\x02\x9d\xc8\xcb\xf3\xf6\x61\x10\x20\xd3\x09\x91\xb8\xce\xf1\x4e\x06\x6c\xd3\x83\x3a\xe8\x24\x88\xd0\xf3\xba\x83\xfa\x06\xef\xb0\x85\xf7\xe2\xad\x71\xd3\xfb\x67\xfd\x00\x69\xac\x13\x9a\x60\xcc\x7c\x31\x9b\x17\x9f\x7d\xf3\x54\x27\x94\xa3\x33\x63\xe6\xda\x3e\xf4\x82\x63\x4f\x2c\x60\x3a\x18\xab\x13\x69\x18\x55\x6d\x92\x67\xca\xd5\xd5\x3c\xb4\x70\xa7\x6a\xf0\x7b\x3c\x54\x08\xfa\xd8\xa4\xf9\xcb\x86\xb7\x80\x03\x2d\x92\x30\xb0\x76\x2f\x0e\x6c\xe0\x0f\x07\x45\x06\x26\xc3\x67\x75\x53\xb2\x62\x1c\xb4\xd5\x10\x30\x8f\xb5\x6f\xb2\x3e\x41\x3e\xcb\xd5\x43\xbf\xfe\x7d\xd4\x9f\x19\xe5\xb4\xc7\x4b\x73\x82\xa4\xe7\x63\x63\x00\x34\x86\xde\xf0\x3d\x80\x47\x98\x16\xd0\x00\x26\xbb\x59\xf3\x6c\x51\x54\x8d\x4d\x6c\x69\x06\xbe\x1d\x2c\x4d\x48\x24\xfa\x45\x4b\xa6\xca\x29\x85\x92\xfe\xb0\x1d\x3c\x1a\xf0\xc0\xe9\x07\xa4\x9f\x90\x35\xee\x30\xd6\x9d\x4c\x2a\x4c\x69\xe2\x29\x81\x19\x63\x8e\x24\x76\xab\x1a\x8e\x86\x0e\xd7\x50\xca\x0c\x7f\xdd\xe7\x8a\xf4\xf1\x7b\xab\x5c\x17\xcd\x00\xef\x4b\x2e\xdf\x5a\xb3\x56\x13\x5f\x02\x9a\xbd\x5b\xae\x79\xcd\xcb\xf6\xcf\x2a\x44\x98\x88\xb2\xf9\xbf\x11\xf0\x46\x93\x20\x36\x2e\xc0\xae\x38\xf2\xe6\xfc\xf8\xea\x04\xfa\x6e\x9b\xd0\x84\x06\x12\xd3\xd8\x4f\x50\xbf\x95\x45\xde\xde\x9d\x6a\x25\x2c\x01\x16\x86\x33\xaa\x1e\x8b\x06\xfb\xe2\x5e\xa1\x67\x52\x6b\xf3\x8c\xe7\x6f\x0b\x9e\xbf\xf3\xca\xdd\x2e\x8c\x4d\x92\x75\xb7\x5c\x3c\x6f\x97\xeb\xe7\xed\x6e\x71\xbf\x5e\x3f\xec\xfe\xf2\xa8\xd0\x24\x64\xbe\xb0\xba\x01\xcb\x53\x5a\x15\x0a\xb0\xf4\xf3\xab\x5d\x70\x74\xad\x0e\xed\x86\x7f\x57\x64\x58\x59\x3f\x51\x79\xaa\x49\x28\x34\x7e\xd7\x6d\xe3\x9c\x1f\xfc\x83\x33\xa7\x7b\xa5\x19\x9a\x84\x4a\x62\xc5\xe1\xb1\x50\xbf\x7e\x0c\xdf\x3c\xf2\xa8\x4b\xc6\x37\x93\xa2\xad\x52\xd6\x24\x4a\x38\x04\x1d\x8f\x30\xcf\xc0\xc6\x5b\x46\x77\x88\x39\xf3\xac\x2b\xd8\x46\x61\x86\x3d\x18\x25\xc4\x70\x3e\xbd\x16\x59\x2f\xc0\xa6\x49\x42\x3c\x44\x8a\x1e\x5e\xf8\x69\xad\x17\x67\x01\xbb\x1e\x0b\xed\xf0\x2e\x49\x44\x22\x74\x18\x8a\x2c\x33\x40\xec\xbf\x77\xa0\x68\xc2\x3d\x8a\xfc\x7a\xc6\xe2\x70\xac\xed\x65\x71\x1c\xd0\x04\xb8\xce\x01\xa1\x91\x5d\x59\xeb\x73\xdd\xa3\x16\xd1\x84\x2b\x2f\x72\xea\x9f\xce\xbe\x58\x97\x4f\x45\x79\x1c\x51\x85\x68\xc2\xc1\x1c\x3e\x2f\x50\xa7\x15\x2a\x87\xf4\x4d\x47\x4d\x84\x1f\x20\xb8\xc8\xfe\x75\x5f\xec\xea\x72\xdc\x85\x1a\x0e\x11\x3c\x07\xfd\x65\xde\x7d\x1a\x41\x95\xc3\x41\xbf\xcd\x2a\xab\x68\x37\x7a\x00\x11\x52\x27\x2d\xbd\xfe\x00\xe5\xe8\x86\x46\xbd\x94\x90\xee\xfc\x6b\xf5\x3f\xeb\x7e\x51\xaf\xe7\x62\xaf\x53\x1b\xa2\x26\x4a\xf9\xd4\xf2\x96\x2d\xf8\xa9\x9f\x5a\x6d\xda\x14\x82\xac\x80\x97\xd9\x45\x74\x2c\x96\x9a\x80\x1f\x24\xc2\x61\xb0\x07\x84\xaa\xb6\x83\x0e\x7d\x3c\x32\x5f\x0b\x95\x19\xa1\x9d\xbf\xb0\x31\xcd\x75\x9e\x47\x4c\xe5\xda\xde\x14\xa1\xa1\x65\xe3\x7e\xd5\xf3\xc2\xd0\x48\xc0\x66\xc0\xcb\x11\xf5\x84\x35\x08\xb4\xe7\x81\x87\x08\x8e\xac\x78\x69\x93\xba\xdf\x3a\x98\xcd\x25\x61\x68\x4e\x2d\x44\x32\xf6\xf8\x3a\x9b\x36\x8d\x04\x37\xf7\x67\x91\xa6\x4f\x50\x7f\x14\xe5\xdb\x60\x94\x3c\x3f\x0c\x22\xd2\x4e\xce\x9f\xce\xd9\x19\x79\x27\xda\xf3\xb9\xd9\x10\xb6\x00\xcd\x77\xca\xe5\xe5\xb1\x4d\xc0\x68\x2f\x88\x62\xc7\x6d\xfb\xc0\xf3\x97\x33\x7f\x69\x2b\x71\xdb\x57\xa3\x9e\x4f\xed\x42\x35\x11\x92\x7d\xd1\x53\x70\x63\xae\x17\x27\x08\x04\x5f\xcc\x57\xfd\x74\x44\xd3\xa0\x64\x6c\x59\x55\xd2\xfc\xc5\xb0\xc3\x0e\xbf\x9b\x17\xca\x10\x01\x39\x46\x27\x62\x5b\x14\xc7\xf9\xa5\xf9\xdf\x51\x82\x5f\x7b\x31\x89\x8c\xa0\x44\xc9\x6d\xe1\x48\x3b\x20\x2c\x88\x69\x9f\x23\xb8\x17\xa4\xd2\x1e\x03\x8a\xa1\x2e\x8d\x6a\x3b\x7d\x95\xe1\xbf\x2c\x98\x6c\xbd\xe4\xe6\x2e\x09\x3a\xf1\x06\xb1\x35\x20\xc6\xb2\x3d\x92\xc8\x43\x4b\xb9\xf1\x3c\x4e\x70\xc5\xf9\xe7\x7a\xc5\x09\x72\x11\x65\xa9\x84\xbc\x82\x3d\x94\xc7\x61\x91\x91\xf6\x12\x19\x18\x7d\x45\xc4\x54\x20\x0b\x9f\x9a\xcc\x72\x4c\x57\x9b\x6a\x8f\x2b\x8a\xf3\xe3\x66\xb6\xd9\x20\xa0\x68\xf0\x51\x84\x06\xb4\x4e\x8f\x86\x0b\xb2\x5d\xe6\x03\x48\xb5\xf6\x20\x8c\xa2\x0e\xeb\x34\x06\x90\x8f\xe6\x33\xc4\x80\x92\xe5\xbd\x18\xc0\xfc\x5c\xe6\xd3\x31\x00\xed\x01\x53\xe8\x0a\x64\xbc\x32\xc5\x27\x07\xee\xd9\x2c\x88\xf6\x89\x1f\x62\xd1\xb3\x70\x95\x38\x36\xfe\xee\x9a\x85\xd6\xd6\xd2\xd8\x9d\xf8\x47\xde\xd5\x40\x8c\x0d\x18\xdf\x23\x21\x26\x32\x0c\x2f\xdb\xb2\x1e\x16\xca\x68\xdf\x27\x7e\x60\x6b\xd6\xee\xca\x54\x31\xf7\x13\x3e\x03\xaf\xf9\x46\xcf\x8b\x99\x0b\x5f\x6a\xdf\x4f\xdc\x5c\xae\x77\x35\x9c\xae\x81\x39\xda\xf7\x05\x43\x02\x94\x09\x8a\xd8\x6f\xf7\x20\x3f\x08\x0c\xea\x7c\xbb\x7c\x58\xce\x76\xcb\xc3\xfe\x7e\xbb\xdc\xdd\xaf\x1f\x6e\xdc\x8f\x07\xc2\xd8\x6e\xff\x3e\x17\x35\x1f\x05\x21\xb5\x4f\x45\x1c\xf7\x23\xfe\x4f\xf0\xd1\xe3\x48\xf8\xc7\xb8\xb3\x21\xa0\x5f\xee\x16\xf3\x8e\x27\xee\xef\xa4\x4b\xb5\x1f\xc6\x01\x5a\xd5\x6d\xe8\xf4\xbe\x38\x57\xb0\x38\xd7\x13\x30\x02\xed\x47\xa1\xc2\xc0\x52\xf3\x21\xbf\x65\x2b\xd2\x7e\x04\x14\xa3\xf5\x6d\xe0\xa6\x3d\x40\x7d\x46\x15\xb2\x0e\xdc\xa4\x95\xe4\x65\x5f\x11\x45\xfb\x2c\x51\xcc\x4a\x20\xfd\xd6\x33\xa9\x47\x99\xbb\xef\x8f\x7a\x3f\xe1\x26\x1e\x0c\xc7\xb4\xfe\x59\x94\x6f\x5f\xb9\x9e\xae\xbb\xf2\xdd\xf1\xf7\x04\xe9\xcb\xab\x28\xce\xa5\x61\x94\xfa\x02\xb8\xaa\x7d\x9e\x78\x58\xd8\x66\xcb\x78\xab\xe6\x05\xad\x49\xf1\x38\x12\xb0\xd4\xbe\x20\x14\x0b\x1d\x24\xcf\xb2\x79\x2d\x7f\xa6\xf5\xeb\xae\x96\xd7\x01\xbc\x6f\xb2\x9e\x53\xfd\x06\x31\x4b\xf7\x53\xb1\x32\x2e\x03\x3a\x7f\x77\x50\xf7\x28\xa6\xbe\x78\x7b\x21\x84\xea\xc8\xf5\x5c\xee\x73\xd4\x47\x79\x4e\x6d\xed\x26\xad\xb8\xe5\x73\xbf\xd2\xaf\xd0\xbe\x0c\x19\x9e\xae\x87\xc6\x6b\x78\xcb\x3b\x9e\x05\xed\x4b\x99\x20\xa0\xe8\x71\xf6\xeb\x30\x5b\x6d\x6f\xb6\xeb\xcd\x00\x72\xae\x7d\x45\xa9\x0c\x5a\x07\xf7\x78\xba\x2d\xca\xa9\x99\xec\x7a\x87\xa6\x36\xd3\x78\x6d\x37\x57\xe9\x46\x1b\x76\x1b\x4d\x4b\xc5\x62\x42\x9c\x9d\x2a\xcf\xbd\x1c\x87\xf6\x95\x12\x61\xcf\xdf\x7a\xce\xb5\x29\xdf\x1b\xfd\x2e\x44\xb8\x5b\x15\x1f\x79\xd5\x03\x6f\x0e\x42\x35\xda\x07\x9f\x58\x76\xc8\x0a\x6a\x5b\xe9\x69\xc0\x12\xc3\xbb\x41\xa0\x5d\x58\xa0\xf5\xb2\xee\xa1\x4c\xc7\x11\x4e\xed\x43\x1c\xa0\xbf\xbd\x7a\x5a\xed\x57\xb3\x87\xbb\xd9\xee\x76\xbd\x5d\x6f\x67\x8b\x87\xd5\x3f\x97\x3f\xda\x4e\x12\x61\x1f\xab\xc7\x9b\xe5\x2f\x14\xf5\x68\x6d\x1b\xd6\x96\x05\xfd\x0f\xfd\x97\xeb\x9e\x84\x18\x72\x3a\x0b\x3c\x11\x5c\xf8\x56\xfb\xda\x37\xa0\x29\xeb\xa7\x1f\x4e\xa8\xbc\x7d\x38\x57\xad\xb4\xb8\xf6\x75\x62\x48\xcc\x75\x51\x6a\x48\x6b\xeb\x66\x0d\x5f\x4f\x73\x2f\xb2\xfa\xae\xd6\xc6\xbb\x85\x69\x1a\x40\xed\x6b\x65\x74\xdd\xdf\x53\xf8\xf8\xa3\xa8\x5d\xca\x57\x07\x24\x08\x91\x52\x9a\x1b\x15\xf4\x05\xcf\x91\x0b\x70\x40\xdd\xac\x03\xc2\x18\xae\x32\x1b\x29\xdc\x82\x02\x38\xce\x6e\xf7\xbf\xf9\xae\x87\x27\xb4\x15\x5a\x44\xb8\xdb\x0e\x4b\x87\xcf\x25\xcc\x72\xf5\x08\xf5\x6b\x71\x0d\x85\xe9\x02\xae\x3a\x68\x8e\x0b\xab\x5c\x67\xb5\x25\x3a\x5b\x3c\xf0\x03\xe5\xc0\xf6\x9b\xac\xa8\x7b\x30\x7b\x1d\xf8\x91\xa9\x63\x4b\xab\xf5\x88\xbd\x48\x07\x41\x10\x21\xe5\xf9\xc9\x68\x6d\x57\xf3\xcb\x1c\x72\x30\xec\xc0\xe3\xae\xb1\x51\x48\x56\xf0\x6e\x8a\xdd\x6c\xf5\x90\x6b\x66\x82\x99\x30\x08\xbc\xad\xd5\x17\x5b\x5d\x10\x24\x5a\xd2\xde\x74\x43\xb6\xb0\x41\xc5\x83\x0e\x02\x6d\x18\x95\x04\xd4\x1e\x21\xe4\x40\x88\x07\x8e\x37\x5f\x07\x34\x08\x19\x73\x8a\x31\xd3\x93\xcb\x66\x55\xfc\x8e\x9f\xd5\x4d\xb8\x80\x2a\xc0\xb0\x6f\x56\xd4\x75\xd1\x27\xe4\xd7\x41\x28\x4c\xa6\xef\x30\x10\x27\xac\xf6\x85\x65\xe6\x77\xdd\xa4\x12\xd6\x6b\x68\x81\x62\x01\x69\x5b\x55\x82\xfc\x5e\xa7\x12\x56\xb2\xe8\x79\x4b\x41\xa8\x25\x52\x88\xdd\xaf\xee\xee\x0f\xdb\xd9\xd3\xdd\xb2\x87\xe1\xd4\x41\xe4\x05\xb8\xf7\xf0\x2c\x5b\x76\xcf\x14\x71\x66\x62\x47\x8d\x4d\x37\xc3\xda\x0d\x43\x77\x5b\xcd\x4a\xb0\x66\xdc\x00\x33\x3d\x6d\xbe\x05\x91\x36\x80\x4b\x7d\xe2\x65\xfd\x63\xf0\x45\x62\x12\xfa\x96\x2c\xb3\x74\x71\x21\x64\x85\xb0\x52\x92\xc3\x49\x10\x4b\x03\x54\x7d\xc1\x60\xa3\x49\xdd\xce\x72\x65\xd4\xe8\x5d\x9f\xc6\x9f\x6f\xf6\x80\xcd\x5a\x16\x69\x7e\x5f\xd4\x90\xd9\xc5\x69\x7b\xb0\xd8\x90\x30\x95\xbc\x6e\x86\xa9\xfd\x33\x0f\x88\xc1\x98\xe4\xc3\x31\x67\x8a\x20\x62\xc8\xc6\x79\x21\xcb\xb0\x7c\x6d\xda\x1c\x09\x12\x0a\x9e\x13\xa9\xe7\x55\xed\xd8\xcc\xbc\x3e\x7e\x87\xb9\xbe\x1a\x10\xc0\xd4\x41\x0e\x31\xa7\xff\xc8\xf3\x33\xcf\x46\xb2\x09\x3a\xe0\x11\x09\x3a\x85\xce\x41\x02\x5f\x07\x9c\x6b\x47\x7a\x82\x36\xcc\x54\x2d\xa8\x0e\xb8\xd2\xe8\x34\xff\xda\xcc\xac\xe2\x94\x6d\x10\x31\x11\x4e\xac\xf9\x9c\xd5\xe9\xd6\xc1\xd0\x1b\x03\xac\xe4\x57\xb5\x19\xee\x32\x90\xe8\xda\x01\xaa\xdd\x4f\x6e\x6c\x81\x24\x21\x3e\xb6\x2c\xf2\x1a\xf2\xfa\xbe\xa8\xea\xf9\x65\x35\x94\x52\xd4\x81\x8c\x28\x42\x70\x56\xd2\x30\xe9\xf6\x1c\xbb\x40\x0a\x19\x18\x76\xeb\x1c\xfd\x94\x65\xfd\x6a\xec\xb3\x43\xdb\x43\x09\x4b\x91\x8b\xe5\x85\x8f\xe1\xfe\x2a\xe9\xa7\x03\x15\xf9\x48\xb1\xb1\x5c\xef\xe6\x50\xb7\x60\xb2\xe9\xcf\x08\x8c\xe1\xd6\x8d\x81\x73\x43\x84\x5f\xfe\x18\x9a\x5f\xb6\xa7\x8e\x25\x9e\x9b\xc6\xf6\xec\xb1\x08\x7e\x65\xad\x4d\xfe\x20\x25\x91\x22\xad\x12\xf7\x72\xfe\xfc\x0d\x94\x46\x53\xc2\x08\x96\xb7\x21\xa1\xcb\xa9\x84\x43\x2a\x87\x19\x18\x4d\x89\x0c\x20\x72\x81\xdf\xdd\x07\x3f\x3d\x74\x23\x4a\xbd\x88\x23\x20\x4f\xa7\x65\x65\xd0\x80\x4b\x07\xab\xd5\xd4\x03\x83\x73\x6c\xe6\xd9\xfe\xb5\x2c\x3e\x26\x64\xa3\x9e\x0a\xe3\x98\x76\xd7\x70\x64\x62\xd4\xa6\xdc\xa9\xfd\xb3\x4e\x30\x3e\x99\xc3\xc7\xa6\x2c\x4e\x45\xc5\xb3\xaf\x30\xde\x93\x59\x46\x7b\x1b\x3f\x8e\x11\x96\x97\x5a\x4a\xda\x45\x8b\x74\xc0\x38\xc3\xb7\xe6\x30\xf5\x45\x88\xb5\x3c\x7d\xc4\xc1\x38\x09\xa2\x69\x40\x38\x37\x5c\xb8\x35\xbc\x14\x8e\xb1\x46\xd3\xc0\xa3\xc8\x27\xd3\x78\x76\x37\xfc\xd2\x85\xde\x35\x0d\xb8\x61\xb2\x30\xa9\xb5\xa5\x2d\x9e\xde\x22\x70\x02\x1c\x15\xc1\x70\x0d\x53\x9a\x30\x66\xa1\x89\xc5\x47\xf5\x04\x1f\x77\xbc\xa5\x86\xd2\x34\x4c\x7c\x2d\x5a\x45\xf4\x73\xd6\x2f\xfb\xd3\x34\xa2\x80\xd0\x0c\x37\x0a\x56\x1d\x68\xf4\x0b\x11\x10\x3c\x28\xad\xcf\xf6\x35\xe3\xb5\xa6\x31\x25\x61\xa7\x92\xb6\x3e\x35\x9e\x69\xf3\x6d\x7e\x0c\xe6\x5a\x4c\x13\x5c\x36\xd5\xf9\x78\xbc\x2d\xce\xb9\x82\xd2\x60\xe4\xdc\x53\xc7\x2c\x76\x55\xc4\xab\xca\x16\xa4\xb7\x6d\x5a\x23\x7a\x50\xf4\xf8\x28\xed\xee\x47\x19\x8b\x10\x7a\x5c\x42\x5d\xa6\xf0\x0e\x7f\xf0\x3c\xad\x2f\xb7\xc5\x48\x8c\x66\xb4\x4e\x18\x98\x6a\xd6\x13\xbf\xca\xb6\xd8\x1e\x49\x18\xe1\x5c\x5c\x1e\xe6\xe9\xb4\xe8\xa9\xa6\x89\x2d\xc4\x4c\xab\xbb\x8c\xab\x94\xd7\x45\x89\xf5\x4a\xa3\xc1\xe4\xc4\xc8\xab\xa5\xb2\x38\x20\x3a\x3f\xcd\x5f\x0e\x55\x2f\x01\xa6\xa9\x08\x3c\x2c\x91\x3d\x35\xb6\x84\xd1\xb9\x70\x2d\x11\x0b\x9c\xe3\xe3\x34\x58\x6d\x3c\x6e\xf4\x33\x22\xf1\x30\xeb\xbe\x31\xf7\xe8\xa3\xef\x5c\x0f\x1e\x22\x4a\xba\xd0\x1a\x4a\xb4\xaf\xae\xbc\x7f\x2a\x94\xc6\xf8\xd7\x0e\xea\xc3\xa5\x38\x97\x87\x17\x7e\x84\x43\x8e\x08\xbb\x83\x80\xfa\x03\x20\x3f\x78\x07\x2f\x1c\x7e\x5f\xc9\x22\x34\xde\x1e\x8a\x97\x27\xf8\x98\x10\x02\xd2\x54\x45\x1e\x35\x33\xcf\x22\xbe\x9b\xdd\x77\xd4\x07\xa2\x38\x69\xb9\xaf\x9e\xea\x1e\x91\x8c\xa6\x20\x09\xb5\xa8\x45\x3b\x83\xc6\x17\x6b\x0f\x91\xa0\xc2\x6e\xca\xcb\x4f\x33\xc5\xcd\x91\xfb\x8d\xac\x9b\xa6\x9a\x48\xcc\x0b\x9a\x49\x8c\x54\x5a\xf3\x31\x73\x83\xa6\x3a\x82\xc4\x39\xfa\xcf\xf9\x23\xaf\xde\x40\x2d\x2d\x0e\xf1\xab\x1b\xdb\x0a\xc9\xe6\x12\x8c\xa5\x7e\xff\x18\xda\xb0\x54\xdc\x17\x39\x54\xf5\x0b\x3f\xb6\x8a\x21\x3a\xf4\x7c\x0f\x4f\xdd\xc6\x73\x04\x99\xa2\x9f\x86\x98\x10\x48\x5d\x17\x9f\x70\x61\x03\x7e\x3c\xcb\x0e\xaf\x45\x59\x41\x1f\x9a\xa6\x43\x9f\x2b\x74\x80\x1e\xd3\xbc\x7e\xec\x19\x9f\xd3\xbb\x5e\xe8\x0b\x82\x90\xfb\xed\x39\x1f\x18\x0a\x61\xe0\x73\xf7\x2d\xe6\xfc\x65\x96\xab\xbb\x54\xd7\xd3\xc7\x7b\x18\xb0\x10\xf1\x49\x4f\x70\xaa\xf9\xe0\x2e\x94\x11\x67\xe5\xa0\x66\x1a\xda\xed\xa9\x4c\x79\x99\xb6\xdb\x59\x48\x19\xc7\xfa\xf7\xcd\xc3\xec\xcf\xe5\xf6\xb0\x7f\xde\x3e\x1d\x76\xab\xa7\xbb\x87\xe5\x61\xb3\xdc\xae\xd6\x37\x6d\x47\xae\x31\xe0\xbc\x4f\x61\xe2\xe0\x0e\x43\x4f\x60\x8e\x73\x63\xdc\x84\x91\x69\x63\x19\x9f\x5c\xdf\x88\x20\x97\x7c\x73\x78\xdd\xf2\x2c\x13\x5c\xbe\xad\x2a\x44\x58\xa8\x75\x1b\x2c\x75\x3f\x1c\x27\x01\x86\xe6\x1e\xd6\x77\x07\x3c\xcf\x5a\x50\xfc\xe4\xb6\x11\xc6\xd2\xe8\xa0\xcd\x67\xdb\xc1\x70\xb0\x90\x98\x58\x5a\xcd\xdf\xa0\xac\x6e\x8b\x72\xd3\x98\x16\x03\x13\x27\x64\x49\x94\xd8\xe8\xdc\xee\x71\xd3\xd7\x12\x5d\xe5\xad\xd2\x8d\x0e\x93\x44\xf0\xd0\x41\x64\x5a\x86\x97\x1f\x7d\x5e\xab\xf6\x96\x89\x66\xd2\x66\x7f\x4d\x2a\x73\x3c\x36\xc3\x81\xe4\x01\xc7\xd3\xc7\x89\xe7\x54\x3d\xa5\x57\x1d\xf2\xc8\xc7\x18\xbe\x72\x2a\xe1\x97\xd1\x77\xe0\x8c\x98\xef\x69\x90\x15\x43\xf5\xff\xf1\xbf\xf6\x98\xef\x22\xce\x21\x67\xda\x72\x5a\x64\xd9\x43\x2b\xa7\xa5\x43\xc1\x4d\x24\xda\xd4\xa8\xda\xe0\x88\x6b\x94\x3e\xc1\xda\xc0\x1d\x64\x7a\xc3\x5b\x49\xdd\xbf\x8a\x12\x7d\x6b\x6b\x85\x2a\x0c\x02\xe3\x0a\xdf\xf3\xea\x15\xdd\xe1\xd1\xb7\x52\x5c\xe3\xe2\x3f\xa8\xf3\xf1\xb4\x2f\x8c\xfa\x86\xdb\xf3\x43\x9d\x04\x18\x9f\x5c\x9f\x4e\x45\x59\x5f\x06\x53\x41\x73\x85\x68\xb6\x1b\xfe\x13\xd2\x49\xc0\x4e\x7f\xf7\x0d\xb5\x20\x96\x18\xf7\x72\x0f\x59\x56\xb4\xb7\x11\x86\xe6\xab\xaa\x8b\xd3\x26\xe3\x5d\x01\x9a\x0e\xb5\x0a\xdd\xda\xfb\x0d\x2e\x2e\xf2\xd2\x97\x3c\xd7\x91\x47\xa8\x67\x64\x6f\x0c\x7f\xf3\x2c\xcb\x66\xe5\xcb\x55\xb4\x7b\x38\x2e\x91\x17\x85\xcc\x51\xa2\x39\x62\xd6\xfd\xfd\x93\x83\x29\xeb\x28\x24\x46\x6b\xcb\x30\xb5\x4d\x2f\x92\x28\x22\x26\xea\xe1\x0c\xae\x6d\x5b\xc9\xd5\xb4\x71\x23\x8b\x08\x59\xfa\x0e\xe5\x82\xe7\x2a\x55\x5f\xb1\x60\xe9\x28\xa6\x60\x8a\x34\xab\x7e\x52\xc8\x35\x4a\xce\x89\x0d\x32\x95\xef\xae\xf4\xc8\x99\x28\xae\x17\x0b\x4d\x81\x24\x57\x6a\xc1\x2b\xd9\xec\x9c\xd3\x8f\xcd\x98\xd2\xb6\x18\xa3\x31\x11\x4b\x9e\x8e\xf1\xb8\x3a\x62\x89\xd1\x2a\x50\x65\xb3\xcd\xdf\x20\x29\x42\xf7\x40\x49\x63\x98\x1b\x53\xa0\x46\xbd\xe2\xbf\xc5\x6a\xd6\x5c\x17\x23\x3d\x91\xa5\x58\xdd\x62\x16\x6c\x94\xfb\x8a\x78\x14\x63\x1c\x05\x2d\xc7\x7d\x5f\x48\xe5\x47\xdb\x43\x20\xb1\xd4\x43\xf1\x62\xb7\x81\x05\x3f\x2d\x3f\x25\x80\x9a\xa8\x43\xea\xcf\xc2\xc6\xd1\x47\x46\x89\x99\xa8\x30\xff\xf9\x7b\xd3\x0b\xaa\x0a\x72\xc7\xe2\x3f\xfd\x7d\xb8\x24\x18\x2c\x29\xcf\xc3\xca\x75\x1d\x09\x8f\x7a\x4e\x55\xcd\xca\x88\x75\x5b\x41\x24\x02\x3f\xe1\x0e\x92\x77\x50\xc5\x47\xfb\x12\x92\x0a\xdc\x24\x1d\xb7\xd1\xa4\x1f\x1b\x29\x4f\xe2\xbe\xf7\xfb\x3f\xbf\x54\xd7\x1a\x3d\xa9\x8a\x85\x11\x91\x3c\xa6\x96\xfc\x39\xfb\xba\x38\xcb\x5d\xc3\x69\x20\x5d\x59\xc8\x4f\x48\xdb\x02\xf0\xbe\xc2\xb6\xed\xab\x3d\x83\x02\x75\x38\x1c\x7f\x68\x65\x45\x9a\x01\x32\x63\x62\xd6\x3e\x75\x5c\x05\x3a\xd2\x5c\x1a\x73\xd6\x54\xde\xf5\x61\xc8\xb6\x4b\x4c\x22\xae\x3a\x35\x1e\x64\x9e\x1e\x5a\x37\x31\xe1\x80\x55\xfe\x90\xab\xc6\x3c\xe8\xf6\x8a\xd8\xe3\x1e\x12\xf5\xcd\x17\xdb\xe5\xcf\xd9\xf6\xe6\x0a\xb2\xd1\x7f\xc8\xd8\x4f\x02\x0c\x88\xee\x96\x0f\x0f\xcb\xed\x61\xb7\x5f\x6e\x0e\xd4\x42\x91\x87\xdf\x37\x0e\x12\x23\xbc\x6b\xcc\x2e\xb4\x54\x7a\x7c\x91\x86\xae\xc7\x76\x0d\x89\x91\x4b\x6c\x8e\xe4\x9f\xa8\xc4\x3a\x7a\xfc\x28\xe4\x18\x53\x86\x52\xfa\xc4\xc8\xa5\xc2\xe2\x15\xfa\x38\x9b\x38\x92\x04\x53\x80\xf7\x9b\xdf\x27\x4c\x84\x38\x66\x0a\x89\xc4\x5a\xe8\x5f\x1f\x0d\x30\xaa\x53\x18\xbe\x48\x2c\x22\x43\x84\x71\x3f\xdb\x2e\x6f\x57\x37\xcb\xa7\x85\x0b\x8b\xc5\x31\x28\x04\x14\xa6\x55\x27\xb0\xd9\x02\x37\x62\xc6\x43\xb3\x45\x63\x69\xc2\x73\x05\xe5\x2e\x7d\xc9\x9f\xa7\xc9\x61\x75\xcc\x14\xd5\x96\xc5\xae\xa5\x47\xd2\x71\xc2\x0d\xac\xcd\xe8\x8c\x63\x2d\xcc\x03\x6a\x6e\x0d\x2f\xe6\xd4\xd4\x15\x65\xc5\x4b\xb1\x6a\x2f\xe6\x61\x82\x0e\xdc\x7c\xbb\x7e\xfa\xe7\xf2\x30\x7b\x5c\x3f\x3f\xed\x0f\xbb\xdf\x1e\xba\x0e\xdc\xa9\x98\xaf\xce\x0a\x3e\x91\x15\x79\x36\x66\xcb\x6c\xc7\x82\x4b\x62\x32\x47\x79\xbf\x7a\xad\xb7\x70\x63\x19\xb7\x0c\x4d\x3b\x14\x10\x33\x78\x89\xa1\xe4\xd8\x1f\x50\xa2\xb3\x33\x7a\x07\x99\x00\x2a\xf3\x9b\xe8\xe4\xbe\x13\xd6\x72\x4f\xab\x68\xec\x8a\x57\x1f\xd3\x1c\xf3\x05\xee\x18\x5a\xe5\xeb\x1c\xee\x8a\xd1\xc4\x51\x42\x62\xd0\x2b\x4b\x91\xb4\xf1\x04\x75\xda\x15\x71\xeb\x58\x29\xe3\x80\x99\x12\xad\xc3\xed\x7a\x7b\x98\xdd\xfc\xb1\xda\xad\xb7\xbb\x76\x84\xc0\x03\x0c\xee\x9d\x8a\x0f\xf7\x27\xed\x1b\xed\xc8\xdc\x7e\x0f\x23\x82\x36\x37\x0e\x14\x3e\x71\x67\xe3\xc6\xda\x07\xcf\xaa\xd7\x34\xb6\x44\xd9\xe3\x1a\x1e\xee\x10\xb1\x0e\x98\x21\x4f\x28\x51\xf0\x04\x6b\x1b\x66\x9d\xf4\xf7\xb8\x70\x4b\x33\x42\x7c\xf4\x63\xad\x80\xeb\x21\xcd\x75\x31\xee\xe2\x03\x72\x9b\x19\x1a\x93\x96\xc4\x0f\xa3\x88\x2e\xf0\xcf\x08\x05\xae\x5a\x8a\x0c\x40\xdb\xae\xbe\xcc\x2f\x5d\x8e\x81\x11\x19\x06\x2d\x4c\xc5\xb2\xa9\xcc\xe1\x25\xed\xe1\xc8\x35\x23\xda\x43\xc6\xb3\x87\xb4\x3e\x9e\xc7\x6a\x78\x4d\xb3\xf6\x5a\xae\x28\x27\x66\x37\x0c\xae\x33\x2f\xd2\x2a\xb1\x2a\x2c\xe3\x53\x9f\xb9\x3e\xb1\xc6\x39\x8b\xa8\xa3\x7f\x72\x5e\xde\x5a\xb5\x40\xd7\x0e\x46\x27\xd2\x80\x45\x1e\x78\x85\x33\x71\x9d\x67\x97\xa7\xa2\xee\xf4\xa5\x6d\x6f\x5f\x32\x6e\xb2\xeb\x2e\x00\xd5\xf7\xaa\x98\xaf\x0d\xc0\xb3\x82\xfa\xb6\x2c\x46\xd0\x71\xcd\x02\xdf\xc7\x35\xfb\xef\x33\x94\x97\x6d\x91\x8d\x08\xe2\x34\xa3\xe0\xc7\x76\xf9\xfe\x2c\xca\xb7\x53\x91\xe6\x75\x33\x45\x8a\xd2\x9e\x32\xee\x87\xc2\xc4\xe8\xdf\x57\x96\x6d\x76\x57\xc3\x69\x58\x7d\xaa\x59\xa8\x0d\xa9\xf6\x6a\xbb\x70\xea\x2a\xa8\xb5\xe5\xee\x11\x25\xd4\x90\x4b\xa1\x1b\xde\xb8\x2a\xa6\x02\x04\xca\xd5\xf0\x28\xf3\x7c\x37\x98\x31\x31\x2b\xba\x76\x8a\xfb\x37\xf0\x0e\x59\x71\x3a\x76\xa9\x23\xc6\xc2\x18\x71\xd5\x77\x8b\xc5\x50\x67\x60\xe2\x88\x60\x09\x31\x27\x6f\x5a\xdd\xf5\x51\xcd\xae\x95\x05\xa1\xd1\xe1\x7a\x07\x9e\xdd\xa7\x4a\x41\xee\x58\x65\x7a\x76\x6a\x44\xdb\xf4\x88\xe7\x5e\x3e\x51\x11\x58\xef\x68\x56\x1e\x8b\xd2\x04\xf5\x87\x03\xc4\x7d\x9f\x5b\x0a\x0b\x68\x59\xc2\xdb\xc9\xc5\x13\x1f\xa3\xe9\xb2\x2d\x8f\xeb\x50\x16\x8c\x27\x86\xeb\xdf\xe9\x1d\xa9\x5e\xf5\x9c\x66\x82\x18\x91\x4d\xab\x40\x36\x38\x85\xbf\xb5\x11\x98\xf4\x14\x6b\xab\x0f\x9d\xf7\xb8\xe1\x65\x05\x72\x14\x83\x60\xd2\x37\xc5\xeb\xc5\x09\x72\x8c\x07\x19\xcd\xe8\x9e\xf5\xc3\x24\x4b\xa8\x8d\xe2\x9b\xe4\xea\xa8\x74\x4c\x33\x45\xb9\xe3\x25\xc7\x08\xfe\xea\xe6\xb6\x28\xf7\x97\x13\xec\xe0\xdf\xe7\xc6\x5c\xeb\x60\x46\xa3\x27\x55\x52\xfa\x60\xeb\xd3\x3b\x20\xc7\xc2\x10\x3a\x5e\xc3\x7b\xc6\x57\x2b\x82\xe1\x1d\x83\x6a\x5a\xe2\x69\x3f\x38\x3c\x18\x30\x62\x92\x9d\x47\x9e\x65\xfd\x14\x20\x03\x1e\x20\x89\x28\xca\x7b\x99\x84\xc2\x80\x8d\x77\xb8\xa4\xb4\x67\xd4\xe0\x96\x8f\xab\xdd\x6e\xb5\x7e\xc2\x7d\x1b\xd5\x3e\xf7\xb3\xbb\xa5\x43\xd5\x30\xad\x0c\x35\x5d\x1f\x6a\x96\x10\x9f\x23\x86\x75\xf7\x5a\x7c\xcc\x8b\xa2\x27\xd7\xad\x13\xd2\x4c\x31\x2b\xe4\xd7\x7f\xbc\x84\x70\x8e\x68\xc7\x97\xf4\x1d\x2c\xa9\xe7\x60\x62\x25\x9e\x4f\xb1\x34\x76\x5f\xa6\x79\x3a\x74\xf7\x12\x2f\x20\xa2\x4b\x49\xad\x6a\x38\xf6\xf7\x97\xc4\xf7\x98\x53\xad\x7a\xe4\x9f\x2d\x1b\x50\x3f\x59\x9e\xf8\x7e\x40\x4c\x19\xfb\x62\x31\xb8\xb7\x1f\x53\xfc\x62\xab\xc5\x1a\xa5\x6d\xdc\x9f\x6d\xc5\x76\xc5\xdf\xe1\x0e\xf2\x45\xf1\x95\x4b\x93\x50\x4b\x86\x7e\xe2\x17\xc5\xbf\x24\xfa\x77\x9d\x3d\x85\x81\xe3\xb4\xaa\xce\xe3\x90\x5b\x7f\x0b\x48\x68\x90\xa0\x64\x56\x5b\x4f\x34\xdc\xe4\x13\x2a\xc1\xb3\x9a\x1d\x8f\x90\x9f\x07\x76\x70\x12\xfa\x46\xfd\xfe\xae\x3c\x6b\x9d\xe6\xff\x69\x96\x5a\x5b\x62\xa8\x93\x90\xf3\xd0\x55\x46\xf2\x3c\xd5\x50\x5d\x2b\xfa\x0c\x1f\x3b\xf2\x82\x28\xee\xd1\x32\xde\x16\xa5\x33\x05\xc6\xab\xf7\x8b\xfc\x64\xc2\x7c\x10\xd6\x57\xa9\x8b\x33\x12\x81\xe6\x35\x82\xc2\x27\xbd\x8f\x84\xd1\x04\xa9\xc1\x5b\xca\x0a\xc8\xcf\x85\x95\xe0\x30\x92\xfe\xaf\xe9\x69\x7c\x8d\x02\x1e\x0c\xca\xa4\xac\xb7\x37\x1a\xbc\x44\x26\x18\x14\xbf\x99\x2d\xfe\xe8\xfc\xe6\x44\x10\xdf\x33\xc5\x62\x5c\x1d\xd2\xc0\x3f\x70\x2c\xb1\x72\xad\x61\x88\xee\xd4\xe2\xe1\x57\xfb\x27\x6d\x20\x5f\xa6\x1c\xd3\x95\x8d\xb5\x3f\x23\x83\x10\x89\xec\x35\xcf\x64\x91\x1b\x7e\xc9\x2d\xfc\xbb\x6d\xa6\xd4\x2a\x03\x36\x67\x98\x39\x39\x61\x5f\xb4\xcd\xa1\x0f\xa6\x5a\xf8\xb3\x4b\xa0\x26\x32\x4e\x54\x4b\xa3\x9d\x41\x17\x36\x48\xa4\xa0\x71\xa7\x38\xd3\x1c\x94\x50\x6e\x8a\x22\xdb\x14\x59\x2a\xbf\x64\x99\x1f\x7d\x68\xc5\xbd\x40\xb9\xea\xd3\xc6\x84\xc6\xa1\x36\x30\x80\x29\xb9\x2b\x9d\x40\xac\x13\x1b\x70\xd2\x87\x66\xe4\x2e\x3d\x73\x26\xd1\x11\xc1\xaf\xb8\x79\x9e\x3f\xac\x16\x08\x18\xef\xd7\xf2\xeb\x44\x4b\x4f\x41\xaf\xca\xc9\x95\x50\x4d\x9a\xf7\x89\x96\x21\xb1\x00\x09\x63\xc8\x7f\x11\x29\x4e\x34\x04\x5c\x3a\xb8\x31\x96\xc0\xb1\xc1\x12\xe1\x84\x31\xa3\xcf\x63\x82\x4e\xfd\x5c\x0b\x27\xdc\xc3\xe9\xb1\x83\xba\xe6\xf9\xdb\xea\xd8\x7c\x18\x35\x2e\x87\xd6\x9c\x40\x84\x00\x9c\x65\xfd\xea\xa6\x04\xf7\x64\x40\x0d\x30\xb5\xaa\xcb\xe2\x62\x25\x0e\x86\xf3\x94\xfb\xbe\xc1\x59\x68\x3c\xd9\x6d\xea\xda\xb5\x85\x5e\x12\x39\xea\x79\x1b\x41\x74\x37\x0f\x12\x03\x99\x6d\x29\xd7\x97\xef\xbd\x1a\xf6\xaf\x52\xa1\x13\x16\x06\x0f\x54\xc8\x6c\xc5\xc0\x68\xf5\x0e\x5f\x31\x50\x12\xdd\x09\x23\xb6\xe1\x22\x9a\x1b\x28\x3b\xe1\x44\xcd\x29\x31\x81\x0d\xe4\xc3\xe9\x87\x89\x1e\xd2\xaa\xb6\xa4\x5a\x1d\x85\xff\x5f\x70\xa7\xfd\xc3\x70\xf8\xb4\xb7\x96\x68\xa7\x42\xfe\x92\xe6\x30\x0a\x41\x0c\x07\x95\xea\x04\xb1\x3d\x56\xd9\xfe\x06\xb8\xca\xd2\xb6\x5a\x83\x87\xbe\xc9\xca\xa7\x35\xd2\x3e\xdc\x8d\xc4\x76\x35\x0f\x23\x8e\x3b\xea\xb9\x82\xc3\x7a\xf9\x78\xd8\xf0\xb2\xae\xbe\xe2\x09\xb1\xd7\x44\x5a\x21\xdc\xf5\x04\x65\xef\xb8\xef\x48\x57\x34\x8f\xfd\xc8\x91\x0e\x2d\x5f\x5e\x3a\xd8\xe9\x50\x20\x5f\xf3\x98\x6a\x57\xdc\x80\x63\x37\xbf\xec\x2e\x47\x51\x64\xc3\x59\x1b\x43\x88\x30\xcc\xc6\x2c\xec\x21\x4f\x38\x0b\x03\xb4\xca\x5a\x28\xc1\x61\x5d\x72\x79\xce\x46\xae\x0c\x67\x2a\x49\x8c\x2e\x80\xa9\x37\xd8\x9d\x60\x6c\x8e\xf3\x84\x02\xe6\x2e\x6c\xd1\x55\x9f\x30\x71\x72\x2a\x25\x09\x60\x4d\xf6\xee\x2c\x1e\x0b\x24\x6c\x39\x57\x27\xb8\xd2\xd4\xd1\x9c\x87\x21\x86\x12\x91\xe4\x84\x8f\x48\x06\x35\xe7\x2c\xc2\x62\x3b\x53\x45\x07\xfc\x38\xc1\x72\xa4\xb9\xf0\x20\x24\x9d\x82\x46\xb3\xdf\xde\xd8\x3a\xc6\x51\x47\x2a\x90\xce\xea\x70\xce\x4f\x5c\xbe\xad\xf2\x1a\xb2\x2c\x7d\x69\xac\xb7\x09\xab\x97\x0b\xce\xd1\x45\xad\x8a\xb2\xde\x97\xe7\x5e\x08\x94\x4b\x62\x14\xa3\x36\xc5\x07\x94\x66\xc5\xfd\x45\xe1\xd0\xdf\x8d\x98\x5f\xf1\x1f\x69\x2e\xa9\x12\x74\xb8\x30\x47\xe2\xda\x9a\x4b\x15\x63\x98\xcd\xf0\xee\xc0\xb6\x90\xf7\x67\x13\x90\x9a\x9e\xa5\x2a\x52\xc8\x70\x2c\x2f\x32\x83\x9e\xc2\x96\xe6\x8a\x33\xe2\x72\xe1\xe7\xfc\xa6\x57\x10\xda\xbb\x9a\x27\x54\x38\x1a\x54\x94\x49\x40\xa0\x5e\x9f\x18\xf0\xaa\x8e\x5f\x73\x20\x1a\xc1\x22\xb3\xd5\xf6\xe0\xb9\x9f\xd3\x0c\x50\x38\x33\xad\x4c\xfe\xb5\x13\xc2\x1b\x80\x7d\x5c\xef\x84\xa0\x17\x74\x33\xfb\x73\x77\x08\xdc\x4d\x04\x91\xca\x04\x72\x61\x5f\x14\x7d\x53\x4e\x78\x24\x51\x96\xcc\xef\x1d\x1d\x90\xf3\xf1\xaf\x83\x96\xc2\x8b\x03\x45\x5b\x6d\xc9\x53\xbf\xc0\xb0\x3f\xcf\x85\x97\x10\xa2\x5a\xe3\x7c\xff\x9a\x56\x43\xea\x06\x2d\x7c\xa2\x91\x1e\xe4\x67\x51\x66\x0a\x85\xc8\xdb\x96\x40\xc5\x41\x4f\xfc\xe2\x1e\x3e\xe7\x17\xc7\x36\xea\xb9\x4e\x42\x1b\x3d\x4e\x07\x1a\xc4\xf0\x5c\x9b\x47\x13\x41\x94\x60\xfe\xab\x47\x01\xa8\xaa\xf9\xe5\x6b\xbd\x58\x2d\x42\xc6\x80\x76\x70\xd3\x47\xfe\xd9\x87\x71\x89\xc8\x33\x80\xa4\xb4\x72\xb9\xe0\xf9\xf9\x32\x8e\xc7\x8b\x38\x22\x5e\xab\xaf\xd8\x15\xdb\x8f\x7b\x81\x25\x45\x4a\x31\x3f\x37\xac\xb5\x10\xb1\xe6\xb1\x11\x32\x78\x48\x73\x64\x62\x7d\x44\x73\xe8\x3b\x14\x82\x60\xc2\xec\x08\x5c\xd7\x50\x7a\xc4\xaa\x28\xb8\x5b\x26\xa1\xc4\x8c\x96\xb3\xab\x3e\x78\xa9\xaa\x21\x60\x53\x24\x4c\x48\xed\xb0\x1e\x36\x6e\xd3\x33\x4f\x04\x4f\x84\x2d\x11\x97\xc5\x3b\x94\x0f\xa0\xeb\xe6\xdf\xf6\x37\x44\xa8\xbd\xd8\xa2\x27\x78\x5a\xbb\x3a\x7a\x2d\x9a\xa1\xeb\x13\xaa\xed\x6a\xb1\x2f\xcc\x97\x18\xce\x2e\x21\x0c\x5a\x1a\x59\xb7\x8f\xa2\x18\x37\x83\x87\x11\x57\x2e\xd2\x1b\xe4\xa2\x6e\xf9\x77\x7a\xa0\x14\x21\x89\x51\xde\x76\xbf\x86\x3f\xb4\x7b\x4d\x4f\xfb\xc2\x92\x2b\xf6\x71\x42\x42\x86\x14\x9d\x44\xae\xd4\xdf\xae\x26\x10\x92\x1b\x92\x76\x33\xbd\x4d\x38\x6c\xad\x3b\xd2\xde\x49\x7f\x46\x48\x10\x18\xfa\x58\x8b\x6a\xb0\x14\x15\x15\xc8\x83\x86\x64\x64\xb7\x45\xb9\x05\xf9\x97\x82\xa3\xee\x52\x16\x05\xad\x35\x61\x01\x01\xc6\x95\xec\x07\x5d\x84\x62\x3c\xf1\x7b\xb1\x1e\x13\xc0\x1a\x0d\xaf\x4a\x8c\x14\x9e\x99\xb5\xa8\x42\xd5\x3a\x3a\xad\xd3\x2a\xc0\x93\x18\x5e\x84\x36\x5d\x8a\x3c\x40\x9d\xd6\xf9\x7d\x91\xa9\xb9\xc3\xb0\x9a\x74\xee\xf4\x70\x40\xc0\x12\xa3\xe3\xf7\x06\x1b\x5e\xa7\xbd\xa9\x08\xd4\xc7\x28\xe2\xc1\x09\x3d\x9f\xa0\x9c\x24\x9a\xd0\x02\x42\x46\x0d\x5e\xf3\x66\xa9\x10\xa6\x3d\x59\x15\x24\x20\x32\x84\x86\xef\x86\x59\x13\x7e\x4c\xc0\xba\x04\x30\x83\x48\xee\x1f\xe7\xdf\x51\x7c\xba\xcb\x24\x65\xd6\xab\x9d\x17\xd5\xe8\x4c\x10\x00\x09\x2e\xf6\x03\xae\xf5\xef\x9d\x47\xa1\x63\x85\x08\xd7\xbb\xb2\xf8\xb8\x3b\xa7\xd9\xa0\x1a\x43\x12\x8f\x61\x42\x4d\x16\xe7\x53\x73\x00\x8d\x4e\x01\x49\x62\x0f\x95\xf8\xb8\x0d\x3a\xb6\x50\xa2\x51\x3f\x2f\x48\xd0\x52\xdd\x1d\x79\x59\xcf\x2d\xaf\x9f\x6b\x13\x66\xae\xdc\xf2\x37\x3b\xb3\x1b\xe7\xd1\x1a\x4b\x97\xf1\x8d\x24\xc1\x08\xec\x2e\x3d\x9e\x8c\x80\x49\xdb\xd1\xf6\xf0\xb5\xf2\x3b\x4a\xcc\x34\xcb\x76\x35\xaf\x6f\x8b\x72\x60\xab\xc9\x20\xf0\x0d\x2b\x00\x0e\x7c\xcf\x52\x77\xcc\xbf\x5e\x2b\x50\xe9\x5d\xb3\x07\x6b\x19\x28\x1f\xeb\xf0\xee\xa0\x7e\x38\xcb\xb7\xcb\x03\xcf\x55\x57\x35\x2b\xa9\x14\x08\x44\xba\x4d\x0b\xd9\xd9\xe2\x92\x5a\x16\x48\xa3\x04\x61\xd1\xae\xad\x39\x2a\x43\x66\x78\xca\xaa\x13\xff\xc8\x31\xb6\xf5\xb7\xb8\x13\xb5\x0c\xa5\xc1\x55\x58\xc4\xdb\x0e\x1c\x43\xa0\x96\x51\x20\xf0\xdc\x3a\x94\xfc\xe3\x0e\xea\xbb\xac\x10\x3c\xbb\x2e\x96\x70\xbd\x43\x81\x51\xf0\x45\x9a\xab\x54\x36\x1f\xb2\xaf\x21\xae\x65\xec\xb3\x96\x41\xd7\xea\x90\xfc\x4c\xeb\xd7\xff\x5e\x2c\x5e\xcb\x38\x0a\x7d\xa7\x7a\x34\x7b\xf6\xbf\x0f\xbe\xc9\x38\xd6\x58\x8d\xf6\xb0\xbf\x1f\x4c\xd0\x98\x51\xe2\xf5\x8c\x96\x59\x96\x15\x1f\xe3\xbc\x8b\x64\x1e\x67\xdd\xd7\x76\xd7\x32\x3f\x40\xc5\x45\x3c\xf4\x9b\x83\x67\x84\x8d\x91\x4c\x05\xc8\xab\x66\xf8\xac\x9d\xf7\xb4\x05\x5d\x0d\xce\x4f\x99\xf8\x31\x46\xc0\x76\xaf\xc5\x47\x1f\x04\x39\x5c\x97\x92\xdb\x08\xc6\x7d\x51\x6f\x8a\x7a\xf0\x1a\xdc\x07\xe8\x79\x72\xad\x62\x5e\xdb\x9e\x68\x62\xf1\xbf\xe9\xf1\xdc\x8a\xcf\xf4\xcd\x45\x29\x22\xa9\x3a\x42\x18\x73\xe6\x7c\xa5\x27\x3c\x86\xa8\x4c\x05\x85\xa4\xb4\xe2\xdf\x2f\x98\x8c\x4a\x37\x45\x91\x2d\x11\x6d\xef\x7e\x51\x02\xb7\x0a\xd6\x28\xde\x86\xcc\x73\xed\x23\x2b\xcf\x28\x0e\xb5\x06\x13\xea\xeb\xf6\x4f\x4e\xa9\x7c\xa5\x3a\x16\xa5\xc6\x29\x42\xf8\xce\xe8\xe3\x29\x16\xe2\xa7\xbf\x29\x5e\xe0\x3f\x50\x6e\x4a\x58\x2d\xd6\x5d\xee\xe5\x2b\xf4\xcd\xf0\x26\x40\x22\xc6\xfa\xd9\xd1\x23\xd4\xaf\x3f\xc6\x7d\x0c\x49\xa2\x2a\x7e\x3f\x5f\x01\x21\x25\x78\x0a\x81\x18\xf3\xb4\x5e\x5e\x60\xf9\x39\xbe\x38\x82\xd8\xb0\x09\xe7\x6f\x83\xf8\xa8\x04\xe6\x33\x3c\x32\xdf\xd2\xdc\x56\xac\x77\x81\x21\x09\x60\x50\xd6\x86\xdf\xbe\x28\xb2\x81\x5d\x2b\x41\x0b\x14\x0a\x70\x48\x92\x59\x96\xf5\x8a\xae\xda\xed\x48\x13\x93\xc4\x79\x4f\xe1\xc3\x25\x51\x1f\xe1\x58\xf4\xb0\x68\x52\xfb\x14\xe9\x74\xea\x32\x1d\x59\xde\x6d\x87\x18\x33\xc8\x87\x53\x09\xc7\xaf\x68\x48\xb4\xd4\x54\x53\x27\x64\x98\x7e\x42\x36\x88\x90\x48\x1d\x29\xac\x68\xd7\x69\xce\x73\xbb\x64\x9a\xb5\xd5\xc3\x5e\x2b\x22\x99\xd3\x75\x30\xee\xca\x16\xb8\xba\xf4\xb7\x42\x45\x34\x75\x9c\x4a\x8b\xd7\x41\x1e\x43\x79\x7e\x84\xac\x51\x88\x46\xdd\x14\x55\xdd\x21\xc7\x94\xcf\x0d\x3a\xad\xad\x66\x9c\xe5\xf5\xfc\x7c\x31\xa7\xc5\xf0\x83\x2a\x5f\x0b\x8c\xe7\xdf\x40\x66\xa1\x7d\xce\x23\x50\x34\x02\x34\xaa\x97\x74\x5b\x7c\x18\x99\x92\xb6\x49\x11\x4c\x8d\x6a\x9b\xf7\xc9\x0a\xae\xba\xc3\x4c\x45\x34\xc6\x38\x64\x5b\x7f\xf7\x5c\x35\x96\xc4\x38\x6d\xa9\x22\xca\x1d\x1d\x9d\x51\x2e\x4c\xf3\x97\x9f\x29\xd6\x10\xd8\x1e\xb1\x07\xc8\xcc\x6f\x2a\x23\xfe\xe0\xe7\xac\x9e\x42\xa6\xaa\x38\x30\x41\xc1\x0a\x05\xd6\xab\x5e\x54\xa4\x33\xa2\x54\x1c\x70\x3c\x78\x1e\xd3\x17\x13\x7f\x47\xd2\x39\xd7\x18\x19\xd2\xa0\x83\x85\x57\x94\xea\x0b\xaa\x39\xad\x18\x8b\x6d\x4c\xf5\xbd\x78\x83\x69\xcb\x47\x31\x19\xe0\x44\x3b\x57\x50\xfe\xda\xee\xa7\xa8\x18\xb5\x4a\xe2\x44\x8a\x36\xd3\xdd\x6c\x6a\x18\xf3\xd8\x17\x06\x62\x32\xfa\x56\x89\x32\x3a\x21\xbf\x15\x45\x35\xcb\x04\x94\xf5\xc0\xa2\x55\x92\x9a\xd2\x01\xf8\xac\x4b\xbe\x05\x09\x69\xe3\x28\x0c\xea\x8b\x94\x0c\x05\x7a\x39\x66\xb7\x39\xe4\x85\x42\xa9\xe7\xd1\x73\x49\x11\xda\x1a\x98\xfa\xb1\x7a\xb9\xe3\xd5\x1c\x19\xb3\xdb\x9b\x48\xe2\x4a\x95\x7b\x51\x90\xe1\xc3\x4a\x95\xc4\x36\x85\x75\x0b\xe0\x9e\x66\xf4\x3b\x10\x29\x74\x7e\xb6\xf0\xbf\x08\x94\x72\x3f\x00\x89\x42\x4d\x96\x55\x8e\x82\x23\x59\x06\xbd\x1c\xb2\x5b\xf6\x1e\x99\x50\xda\x24\xff\x72\xb7\xe0\x86\xbb\xa2\x86\xaa\x3e\x04\x87\xaa\x38\x42\x47\x25\xae\x15\x48\x85\xf3\x1e\x4b\xd1\xdb\x62\x2b\xc5\x8b\xb6\x03\x24\x54\xb7\x8a\x37\xe3\xf8\xbc\xd2\x3a\x76\x05\x58\x2d\x59\x84\xe9\x71\x5d\xd4\x02\x84\xf1\xb8\xdb\xe2\xbf\xc5\x66\x02\x01\x9a\x0c\x58\x1c\xff\x40\xa8\xb5\x19\xe3\x91\x40\xca\xdf\xb2\x31\xc0\x0b\x7d\x54\x56\x6c\xb6\xc5\x5b\xc3\x82\xac\x06\x93\x02\x7c\x2f\x40\x09\x82\x43\x47\x2a\xda\x17\xef\xd2\xe0\x4b\xc6\x69\x4b\x8d\x51\x9d\x8f\xdd\x78\x0c\x9f\x3e\x88\x15\xd6\x8c\x2c\x1f\x0c\x61\xc2\xea\x78\x72\x46\x18\x04\xcd\x9e\x89\x23\x5a\x43\x79\x4c\x73\x58\xe5\x35\x94\x9a\x4b\x68\x7a\x21\xd1\xa6\x91\xec\x1e\x6a\xfc\xf4\x61\xbd\x40\x83\x20\x60\xfd\x7b\x4c\x01\x89\x80\x02\xc1\x4a\x04\x1b\x48\xdd\xbf\x96\xc5\xf9\xe5\x75\xf7\xc1\xcb\xe3\xf7\x2e\x26\x84\x9e\xc4\xb0\x77\xd5\x6c\xc3\xce\x95\x86\x48\x68\xcb\x30\x94\x99\x8d\x61\xc4\x6c\x00\x91\x34\xa9\xf3\xc7\xd9\xaf\x83\x41\x39\xef\x30\x73\x8f\xa9\x4a\x77\x97\x38\xf1\xf1\x50\xd8\x6c\x57\x8b\x65\xd3\xf4\x74\x33\xdb\xde\xb4\xad\x3c\x44\x75\x80\xe5\x53\xf7\x27\x19\x63\x7c\x10\xeb\xf4\x76\xfb\xd9\x76\x7f\x08\x5d\x1b\x8b\x14\x7a\x7f\xa8\xff\xb1\x39\xe7\xf2\x75\x7d\xae\x47\xe1\xb8\x88\xba\xa3\x11\x58\xa2\x7a\x3a\x37\x3e\x66\xa9\xc7\xdf\x8e\x49\x33\xe3\x0f\x15\xd7\xb0\x3b\x8b\xe9\x50\x1d\x24\x01\x71\x1c\xcc\x8d\xb7\xda\x6c\x00\xf3\xcb\x26\xe3\x97\xfd\xe5\x34\x3a\x5d\x20\x49\x18\xda\x84\x50\xbf\xba\xc8\x7c\x9f\x90\x54\x43\x22\x08\x16\xba\xab\xb4\xaa\x8a\xec\x7d\xb4\x3f\x42\x02\x0c\x83\xc9\x8f\x97\x4d\x9a\x5b\x98\x63\xb3\x8a\x9d\xf1\x05\x9c\x18\x66\x69\x3c\x06\x57\xb2\xe8\x25\x7a\x81\xb3\x20\xb4\xa5\xa2\x1a\xa0\x2a\xce\x35\xb2\x5e\x76\xe7\x14\x08\xca\x11\xe7\x56\xe4\xc8\x7a\xb0\xeb\x7c\x61\x10\x21\x84\x46\x2a\xa0\x0f\x68\x1f\xbe\x9d\x08\x4d\x40\x9c\x2b\x35\x75\x28\x81\x48\x4c\xf1\xff\x6a\xb1\xc6\xe7\x6b\xef\x2d\x63\xa4\xa3\xa9\x3e\xf8\x69\x99\xab\x5e\xb4\x07\x24\x17\xc8\xd1\xc8\x95\x61\x89\x9a\x3c\x80\x40\x79\x11\x82\xee\xf4\x39\x97\x07\x42\xdb\xc0\x23\xa8\x58\x20\x0b\x9b\x2e\x72\xb5\xc9\x78\xad\x8b\xf2\xd8\xb6\x69\xea\x9b\x90\xcb\x31\xcd\x0f\x47\xf4\x31\x0f\x69\x75\x85\x74\xef\x8d\x20\x48\xe1\x4c\x14\x67\x4f\x0d\x6c\x7e\xd0\x41\x82\x0b\xed\x34\xa2\x18\x77\xcd\x94\x22\xa8\xd9\x05\x85\x6e\x78\xcd\xbf\xe5\x27\xe9\xd9\xc5\x9a\xf8\x20\xc3\x36\x73\x39\x2f\xca\xb2\xf8\x00\x50\x5d\x5d\xaa\xf6\x02\x8a\x1a\x38\x83\x52\x59\x34\xf9\x4d\xa8\xad\xed\x47\x25\x5a\xa5\xd5\x59\x1c\xd3\xda\x84\x17\xf1\x97\x6c\xa0\xa6\xb1\x09\x29\xed\x54\x98\xdc\xd6\x36\x58\xe3\xda\x8f\x78\xd0\x9e\x18\x86\xff\x78\xf0\xb9\x75\x10\xea\xd8\x11\x57\xa6\xf2\x0d\x3f\xeb\x60\x3c\x74\xc0\x74\xe2\x3b\xb2\x3e\xa8\x7a\xe0\x4e\x1d\x48\x8a\x64\xa3\xc5\x09\xf2\xdb\xa2\xec\x6b\x44\x6a\x4d\xbd\xc0\xc9\x7c\xdd\x15\x99\x32\xf6\x4b\x2f\x03\x79\x65\x31\xeb\x50\xfa\x51\xe4\xca\xb4\x1f\xe1\x68\x02\x4b\x83\x2e\x11\xd1\x08\x1a\x7c\xd8\xfe\x5a\xac\x1d\xb9\xac\xd6\x51\xe0\x49\xdd\xc9\x84\x9a\x63\x60\xf8\x1a\x91\x00\xbf\xc3\x7c\xce\x79\x85\xe5\xec\xa3\x3e\xc0\x5c\x96\x16\xa3\x51\x13\xc4\x32\x3a\x06\xe5\x98\x3e\xfb\x51\xdb\x65\xe3\xdd\x3e\xef\xbe\xc0\xaf\x68\x46\x3d\xe5\x0d\x52\x79\x3f\x01\x45\x63\x46\xdd\x22\xc3\x7e\xb1\x28\xcf\xff\x81\xb4\x1c\x84\xe1\x35\x8b\x0d\xa9\xb4\xa9\xe9\x71\xd1\xbb\x55\xde\x55\xe2\x68\xc6\x02\xa3\x1c\xc8\xdf\xa0\xc4\x62\x5f\x0c\x45\x8c\x7e\x04\x62\x6a\x0a\x29\x8c\xf6\xe2\x75\xd0\x59\x27\x9e\x8c\xc1\x45\x57\x11\x7a\xd7\xce\x4b\x4e\x8c\x15\x9d\x56\xab\xdf\xf7\xd7\xfe\xae\x16\x8c\x7a\x76\x7c\x0e\x25\x48\xb4\xe6\xa6\x77\x04\x2d\x84\x99\x59\x06\xb1\x79\x63\x65\x07\xda\xda\x76\x77\x47\x49\x25\xee\x58\xf5\x6b\x59\x7c\xac\xf4\xa0\x76\x5e\x4b\x45\x91\x2d\xf4\x83\x67\x59\x55\x97\x00\xb5\x3b\x00\x1b\x93\x17\x79\xe4\xa0\x7e\xdd\x17\xbd\x41\x52\x9c\xc4\x36\x31\x61\xd1\x79\xfb\x62\xb1\x99\xb6\x6c\x34\x90\x00\xb3\x97\x27\x8e\x42\x33\xdb\x56\xc1\x41\x6b\xed\x69\x61\x8c\x6f\xa3\x0e\x35\x78\xcb\x96\x8c\xf1\x1f\x7d\xb8\x8c\xd6\xb1\x87\x47\xc7\x7c\xb5\x9f\xaf\x7e\xb5\x77\x8a\x59\x2b\x7c\x72\x6e\x25\x64\xff\x9e\xa5\xa4\xb5\x66\x38\xb1\xdf\x9b\x2d\xa2\x9b\x30\x9a\x10\x42\x8d\x7c\xf1\x66\xbb\xfa\x63\xb6\x37\xb4\x72\x48\xdb\xb1\x98\x6d\xda\x3e\x51\xec\x14\xf6\x51\xf6\xad\xd3\x60\x9f\x08\x3a\x36\xfd\x93\x04\x3d\x6d\x5b\xac\xfc\x95\x0f\x6f\x7b\xfb\x34\x8a\xe3\x2e\xb7\x83\x42\xa2\x8f\x85\x1a\x1c\xe2\x9a\x90\xc0\x0f\x11\x06\x63\x53\xcc\xb7\xbc\xec\xcb\xe8\x36\x1d\x18\x33\x5c\xd7\xe9\xfb\xe4\xf1\xd2\x74\xe1\xd4\x4a\x3a\xa3\xa4\xcd\x55\x94\xc1\x76\xa3\x24\xc6\x30\x99\x95\xe3\x9e\xc9\x31\xdd\x5d\xd3\xc7\x37\x20\x87\x5f\xbf\x7e\xb5\x21\xc0\xe6\xcf\x34\x41\xef\x75\x9e\xd6\x77\x70\x44\xe3\x61\x8a\xbd\xda\xf5\x16\x1e\x56\x9e\xe2\x83\xf4\x89\xc2\xa7\xca\x57\x34\x21\x91\x67\x24\xbd\xcc\x50\x2d\x8a\x3e\xb5\xaf\xeb\xe2\x1b\x8d\x85\x97\x33\x2f\x55\xca\xf3\xc0\x3d\x59\x44\x19\x16\xa6\xb8\x33\x65\x51\x94\xd0\xf3\x71\x6c\xaf\xd8\x8f\xd1\x48\x4f\x6b\x38\x56\xdb\x66\xe3\x9a\xda\xac\x9a\x8e\x61\x88\xd1\xa3\xd5\xe6\x97\xc9\x99\x37\x87\x64\xdb\xc6\xfc\xa4\x23\xe2\xd8\x9c\xc5\x6f\x70\xe9\x42\x43\x9a\x10\x16\xf8\x98\x49\x96\x3c\x6f\x4d\xe4\xd6\x68\xbe\x2d\xc6\x36\x78\x3f\x72\xd5\x5c\x1d\xc5\x24\xe8\xf4\x61\x5b\xf1\xd5\x2f\x1e\x95\x09\xc3\x60\x69\x61\x93\xfb\x14\x4a\x27\x29\xdb\x23\x00\xb2\x9d\x93\x80\xa2\x47\xf3\xdb\x59\x15\x95\xd9\x62\x86\x03\x9c\xb0\x04\xf1\xb6\x28\x94\xb0\x7a\xba\x3b\xec\x97\xb3\x47\x77\x35\xe7\x26\xa6\x86\xfc\xd0\xdb\x6d\xfb\x67\xe9\x29\xab\x9c\xd3\x4d\x15\x2e\x8d\x78\xfe\xa9\x84\x13\x2f\x01\x77\x8d\xe9\x17\x90\x51\x8c\x24\x4e\x06\xba\x47\x3e\x7b\x21\x8b\xa6\x35\x8e\x30\xc4\xd4\x51\x73\xbd\xfb\x6d\x5b\x02\xb8\x68\x9a\xed\x19\x79\xc5\xaa\xd6\xe9\xec\xb2\x56\x9a\x10\xe5\x33\x84\x0a\xed\x1d\x47\xed\x10\x40\xd0\xf4\xa0\x22\x54\xa3\xf0\xe3\xf4\xa4\x56\x71\xe0\x47\xbd\x98\xed\x38\xd1\xf2\x8f\x41\x74\xab\xb9\x40\xf8\x91\x51\x09\x55\x50\x7e\x34\x1b\x4c\xfb\x5c\x40\x3d\x03\x95\x3c\x42\xf9\x02\xb9\xbc\xd8\x32\x05\x5b\x19\x6e\x4b\x29\x54\xdb\x3d\x6a\xab\x01\xf6\xbc\x7c\xb1\x0c\x17\xd8\xa0\x09\xef\xd7\x9d\xb7\x1c\x9d\xcc\xf5\x60\x51\xd8\xa5\x6a\x2c\x3b\x44\xeb\x76\xf8\x13\x0e\xb9\xf7\xaf\x6b\xeb\x4e\x13\xa2\x89\xa1\x14\x2b\x4e\x60\x62\x31\x83\xbc\x68\xd3\x21\x16\xc8\x61\x96\x15\x15\xac\x55\xfb\xec\x3a\x11\xb4\x2f\xe8\x7b\x5b\x94\x8f\x46\xb0\x7e\x38\xbc\x5a\x7b\x78\x32\xbd\x43\x99\xea\x4b\x6b\xe4\x4e\xc4\x78\x35\xf1\x48\xa2\x11\x49\x89\xfb\xbe\x65\xce\xf9\xe1\xda\x44\x84\x76\xc4\x47\x7a\x82\x79\xc6\xe5\x9b\x29\x3e\xdb\x97\x67\x68\x6c\x94\xc1\xaf\x7a\x1e\x8f\xb1\x32\x12\x01\x22\x3d\x89\xf1\xa6\x09\xfc\xd8\xc4\x15\x31\xd8\x37\xf4\x5b\xbf\x3b\x97\x34\xf1\xfc\x40\x60\x8e\x50\x99\x1a\x2a\x77\xcb\x20\x06\x2c\x08\x6a\x41\xdd\xde\xb2\x7e\xdd\x04\x6d\x33\x10\xb0\x86\x12\x56\xcd\xf5\xe3\x3c\xe3\x64\x8e\x26\x1e\xf5\x94\x2b\xfa\xbb\x01\x99\x1e\x79\xe6\xb6\x3b\x8f\x52\x8e\x8e\xa8\xe2\x35\x6f\x8c\x91\xa3\x0a\xd1\x0a\xae\x6c\x04\xb7\xe9\x92\xc4\xce\x55\xc0\x8a\x8e\x1f\xc3\x11\xa6\x89\x40\x5a\x9b\x7f\x42\xde\x78\x3d\x96\xfd\xd1\x5d\x1c\x86\x46\x70\x5f\xa5\x5a\xa7\xf2\x9c\xd5\x97\x99\xfa\xdf\x73\x55\x1f\x87\x81\x88\xa6\xa7\x90\x03\xa5\x84\xd9\xcd\xcd\x76\xb9\xdb\xb9\xe6\x28\x88\x0c\x1b\x33\x2e\xbf\x9b\xe2\xc8\xd3\xab\x92\xb5\xe1\x3a\xf4\xa2\x80\x33\x6b\x93\x3f\x15\xa2\x55\x94\x77\x77\x8c\x03\xb3\x89\x6e\xd7\x0f\xcb\x03\xf2\x4c\x2d\xdb\x26\xca\xfd\xd0\x92\x6f\x3c\x42\xcd\x9b\xd1\xb1\x96\x97\xeb\xc2\x74\x4c\x4d\x62\x66\x53\x42\x85\x12\x93\x70\x03\x8f\x50\xf1\xd1\xf8\x24\x42\x61\x8c\xa6\xd5\xfc\x19\xc6\x1f\xbf\xf2\x97\xa6\xb2\xa4\xee\x8e\xd2\x8f\x8c\xbd\x60\x64\xb6\x66\x96\xae\xec\xbb\x1a\x44\xbc\xcc\xb0\x64\xc0\xe7\xa9\xe7\x44\x61\x43\x82\xaf\xb2\x7b\x98\xfd\xe1\xfe\x26\x58\x82\xd1\x1e\x7e\x14\xa9\xdb\x4c\x3d\x29\x0d\xcf\x8b\xd1\x17\xe3\xa5\x7c\xbd\x58\xe4\xc3\xf4\xbe\xed\x29\xa1\x88\x11\xde\x69\x7a\xd9\x33\x0d\xaa\x5d\xbb\x2f\x79\x0a\x98\xb4\xd8\x94\xe6\x24\x9b\xf3\xba\xce\xa0\xf5\xaf\x8c\xa8\x80\x26\x1e\x34\xa7\xf7\xff\xf9\xff\xfe\xcf\x1f\x45\x3d\x51\x90\xec\xfc\xda\xa6\x63\x40\x3d\x8b\xd1\xdc\x14\x55\xbd\xce\xfb\x92\x2b\xa3\xf9\x01\x51\x04\x96\x9a\x6c\xf6\xfe\xd2\x01\xc6\x9b\x26\xa5\x8c\x3a\x70\xb3\xda\x1f\x2f\xb3\x53\xda\xae\x18\x00\xdf\x7a\x51\xb9\xc2\x62\x8a\xfd\x07\xc0\x57\x82\x39\x53\x9f\x4f\xfb\x04\xd7\xb6\x38\x97\xf9\xd5\xf1\xeb\x69\x88\x92\x4e\x37\x73\x0a\x40\xaf\x89\xdf\x98\x59\xda\xd2\xce\x63\x3d\x8c\xbb\xdc\x6f\x36\xaa\x66\xa0\x4c\xa4\xad\x5f\xe5\xd0\xd2\xed\x34\xbd\x28\x41\x7b\xd6\x95\x4a\x5c\x87\x79\x9b\x4e\x11\x47\xc8\xd1\x8d\x33\xe1\xbe\x16\xe5\x64\xff\xe8\xd7\x4b\xfe\xbf\xfa\xd7\x3d\x47\xac\x11\x88\x73\x90\xc5\xd1\x26\x1f\xdb\xf7\x10\x1a\xf7\xc1\x47\xb9\x28\xb1\x44\xaf\x6f\xd9\xfb\x44\x91\xc4\x92\x32\x64\x97\x55\x5e\x9d\xcb\xae\xcc\xde\x2d\x4f\x9f\x68\x1f\x83\xf9\x96\xbe\xe4\x67\x9a\x6f\x8a\x22\xbb\x2d\x4a\x03\xf8\xd9\xf5\xbe\x8d\xef\x05\xa6\xcc\xd1\xa4\x2c\xf6\xa9\x7c\xb3\xf0\x8f\xd1\xc8\x79\xa1\x8f\x49\xfc\xea\x54\xe4\x55\x51\xae\x4f\x69\xde\x2f\x86\xe8\x46\xcc\xf5\x8f\x43\x19\xbb\xf8\xc3\x13\x7c\xa0\x71\x81\xc5\xdc\xdf\x8f\x8c\x17\xcb\xc0\x1f\x70\x57\x9b\x42\xb6\xbf\xbe\x0c\xcf\xbd\x13\x94\xc7\xb4\xfe\x2a\x87\x6a\x3b\xfb\x2c\x92\x46\x6e\xf0\xf4\x7c\x7a\x38\x0f\xf9\xfd\x9a\x76\x1e\x21\xe8\x64\x5f\x7c\x8a\x5a\x0e\xc6\xdf\xe7\x2c\x8a\x5b\x42\xec\xc7\xbc\x3e\x4d\x7b\x25\xbe\xaf\x12\x1d\x0d\xe9\x99\x37\xa6\xc0\x1a\xc5\xf2\xba\x81\x0a\x54\x84\xe4\x86\x2e\x28\x75\xe0\xbd\xd0\xbd\x26\x3e\x8d\x35\x86\x83\x8e\xfc\xf3\xf7\xfa\xb2\xca\x6f\xdd\x59\xef\x47\x09\xc5\x9f\xd8\xd9\x62\xe5\x3f\xa0\xaa\x47\x8c\xf6\x9a\xf8\xb1\x34\x69\x98\x66\xdf\x5f\xa3\x6e\xc4\xa6\x2c\x5e\x4a\xee\xce\x42\x3f\x56\x9e\xb6\x72\xd2\x0b\x7a\xdb\x92\x63\x7f\x6d\x0c\xfa\x2c\x14\x88\xa8\x3e\x60\x60\xb6\x57\x0d\xd9\xb4\x25\x21\x02\xe4\x56\x8b\xf5\xe8\xb8\xf3\x93\x48\x68\xde\xaa\x7c\x4e\x92\x20\xb9\x9e\xe0\x21\x23\xdc\x8e\xe7\xea\x23\x95\xaf\xbb\xd7\xd6\xc2\xf1\x79\x40\x30\xd9\x52\xa7\x47\x28\xce\xf5\x2f\xc3\x66\xac\xda\x66\x4a\x11\x40\xbc\x7b\xbb\xb8\x28\x8d\x6b\x52\x31\xe0\x8b\xa6\x03\x89\x4b\xd7\xa8\x4c\xc6\x1a\x03\x1f\xf9\xc8\x50\xf6\x81\x08\x84\x9e\xe0\x29\xbe\x7a\x3a\x6c\xb6\xeb\xbb\xfe\xab\x69\x4f\x44\x8e\x49\x9d\xa7\xd9\xe5\xa1\xa8\x6b\x28\x2f\x3d\x22\xcf\xf1\x4e\xa4\x03\x03\x8f\x2d\xc0\x12\x00\xb7\xb7\x62\x21\x06\x12\x9b\xf7\x5b\xeb\x07\x67\xff\xb7\xcd\x32\xc6\x8a\x30\x8c\xa4\x6f\xe1\xe5\x9c\xf1\xd2\x61\x20\xda\x18\x60\x27\x8e\xe4\xec\x25\x5f\x6b\x8d\x26\xcd\x6d\xcf\xb1\x0d\x48\x40\x11\x11\xd3\xd1\x2d\x8c\x67\xb3\xbb\x3e\xf0\xa8\xc2\xc1\x43\x08\x1c\xa2\x79\xc7\x32\xb9\xae\x23\xa7\x88\x00\xdc\xf3\xea\xad\xba\xe7\xb9\xca\xae\x33\x93\xdf\xef\x8e\x41\x40\x94\x29\x25\x40\xe0\xf2\x47\xda\x8c\x65\x57\x30\xd5\x74\xa0\x86\xc5\xd2\x68\x6d\xd5\xa0\xe6\x23\x87\x2e\xa0\xbe\x17\x27\x3d\x30\xdb\x73\x9e\x8e\x3f\x41\x40\x13\xe5\xb4\x39\xce\x27\xdc\x14\xdb\x1f\x08\x89\xc4\xf4\x86\xb3\xdb\xcd\x4c\x1f\x17\xc8\x34\x1d\xfd\xc4\xd1\x9f\x1a\xfc\xe5\x2d\xc0\x17\x03\x13\x46\x1c\x33\x11\x76\x57\x5e\xeb\x9e\xce\x8d\x0b\x13\x6b\x12\x44\xd4\x8b\x75\x4f\x50\xc8\xa2\xd6\x87\xe8\x0f\xd7\x37\x92\xa8\x70\x90\x1e\xf9\x0b\xd8\x4c\xf2\xf0\x1d\xa3\x24\x74\xe8\x6e\x7c\x43\xe2\x64\xc6\x9a\x36\x11\xba\xf8\x2e\x8e\xee\x10\xf0\x37\xfa\x26\x11\xa8\xd0\x86\x68\xb7\x50\x15\xe7\xb2\xcf\x42\xdd\x99\xe9\x26\xfd\xd5\xce\x9a\x38\x34\x2c\x73\xbb\xb3\xe2\xf9\x5d\x91\xa9\x45\x61\x49\xc3\xdd\x43\x30\x9e\x44\x9d\xfa\xcd\x4e\xf2\x81\xa3\xf1\xd7\xcc\xc1\xcd\x2d\xc0\xc3\xf4\xef\xe2\xb7\xd9\x7a\x3f\xb8\x79\xe2\x7b\x98\x9f\xd8\x16\xe2\xd2\xcc\xfb\x43\xe3\x32\x7b\x6d\xab\x4a\x54\xe8\x00\x3c\x9b\xd4\xc9\xfd\x68\x12\x70\x4f\x48\xfb\xb2\xf3\x6b\x40\x97\xeb\x14\x46\xcc\x40\x59\x4d\x65\x6b\xcb\xd3\xef\xda\x23\x86\xc9\x1e\x91\xd6\x47\x5e\xbd\x1d\xc6\x95\x21\xbd\x3b\x71\x83\x64\xcc\x8b\xd6\xb8\x71\x45\x4f\x9a\x04\x82\x48\x22\x7a\x24\x87\xbb\xf4\xe5\x3a\x7f\xd3\xf4\x8b\x65\x4c\x5a\xd8\x35\x96\xca\x8e\x48\xeb\xc6\x04\x10\xcd\x45\x4c\x20\x7d\xc8\x73\x31\x9f\x3d\xfe\xf3\x69\x30\x7a\x42\x9a\xb8\x87\x49\x44\xcc\xfa\x2a\xc8\x57\xfa\x6a\x9a\x04\x92\x80\x61\x88\x0e\xfe\xef\x0d\x1c\x8b\xa9\x6f\xc8\x86\xd3\x57\x86\x0c\xd3\x97\x98\xf4\xd6\x00\x8d\x95\x82\x75\x43\x87\xb4\xc2\x3d\x4d\x16\xaa\x0d\x1b\x04\x32\x96\xb8\xf1\x9f\x5a\x2f\x35\x90\x2c\x42\x6d\x3b\x5c\x9d\xd6\x99\xd9\xf0\x0b\x8c\xe2\x67\x81\xa2\x01\x42\xb5\xce\x1d\x31\xd7\x97\x96\x4e\xa0\x62\x85\x61\x55\xb7\xf6\x9d\x22\xf5\x17\x24\xb8\xcd\x15\x32\x50\xd6\xe0\x7f\xae\x40\x6d\xe1\x1d\xca\x01\x4b\x00\xf6\xa1\x40\x3b\xc6\x8c\x83\xc1\x50\x20\x04\x2b\xe3\x97\x6b\xe2\x6e\xbc\x24\xc4\xaa\x29\x83\x4b\x41\xd2\x9c\x81\x1d\x13\x28\x65\x58\x86\x3a\x15\xfd\xe5\xfe\x7e\x7c\x13\x08\x35\x18\x4d\x95\xfb\x87\xcd\xe3\xde\x3d\x0f\x84\x0a\x0d\xa6\xb4\xba\x49\xab\xd3\xb9\x1e\xda\xdc\x01\xc4\x0c\x91\xf7\xee\x64\xc8\xd5\x82\x3b\x6a\xa8\xaf\x60\x5b\x7f\x69\x03\xf7\x22\x2a\x81\x16\xa6\x9c\x01\x21\xf9\xa6\x46\xcd\xa5\x00\x6f\x33\x64\xf8\x9a\x29\x65\xa9\x55\xab\x3e\x18\x67\xda\x13\x0c\x34\x28\xac\x84\xc8\x3f\x8e\xfd\x49\x4c\x89\x4a\xb0\x50\xc0\xb8\x35\x7f\x45\xbb\x32\x1d\xcd\xa6\x5e\xe0\x61\x44\x41\x70\x65\x63\xa7\x6c\x00\xc3\x73\xdd\x98\xaf\x8c\x04\x64\x05\x65\xdd\x52\x47\x8e\x87\x67\x74\xef\xc4\x70\xf3\x96\x70\xca\x2e\xd7\xd4\x02\x9a\x50\x3f\x34\x1e\x41\xf5\xc1\x4f\xa7\x56\xab\xdc\x36\x06\x24\x80\xc0\x91\x35\xf3\x0c\x57\x40\x59\x9c\xa0\xbc\x46\x98\x4f\x5b\xc3\x34\x88\xb9\xcb\x90\x3f\x5e\x9a\x9d\x23\xc5\x48\x06\x96\xa0\x0c\xc6\x98\x06\x09\x10\xdd\x62\xb8\x97\x9f\xa7\xb4\x04\xf5\xc4\x8f\xf0\xa3\xbf\xac\x1b\x03\x0c\x3f\x6d\x56\xa4\x6f\xe9\x9b\x4a\xdd\x8e\x48\x69\x04\x68\xd6\x19\x96\xb3\x34\x7b\x4c\xf3\xfa\xa9\x98\x9d\xeb\xd7\x1f\x83\xdf\x09\xa3\x08\x87\x7b\x53\xc2\x7b\x3f\xa2\x49\xc3\x84\x52\x62\xeb\x49\x37\x8d\xa5\x8f\x9e\xd3\x64\x96\x49\x13\x1a\x05\x86\xc6\xb3\xea\x69\xa6\x8d\x12\x10\x34\xa2\x11\x2e\x8f\xb2\x25\x3e\x73\x0d\x2c\xe2\x36\xba\x8b\xc1\x0d\xa7\x5b\xf3\x6d\xda\x83\x46\x52\x39\xc9\x70\xb7\xca\x91\xd7\x76\xa9\x5e\x46\xdb\x0c\x8d\x69\x80\x27\xf3\xc9\x4e\x93\xeb\xb4\x60\xd3\x29\x09\xf0\x88\x3e\x15\x45\x36\x53\x6a\xdc\xca\x43\xdf\xb0\x1a\x6c\x0b\x13\x42\x5d\x96\x65\x51\x2e\x20\xbd\x0a\x3a\x8f\x86\x26\x56\xc4\xe0\xaa\x10\x3d\x36\x3f\x5f\x9e\x8a\x8f\x2b\x8a\x1e\x4d\x28\x0b\x03\xdf\x16\xdb\xb5\xe2\xa0\x76\xfe\x0f\x5f\x9c\x59\x4a\xba\x63\xa1\x16\xb7\xeb\x09\xb4\x4d\xd3\x47\x24\x78\x9e\x9c\x2b\x28\x1d\x1a\xf6\xe9\x7c\x7c\xe4\x23\xa3\x8a\x26\x91\xe7\x68\x05\x8d\x88\xcf\xf0\xa1\x92\xc4\x38\x2c\x56\x8c\x6f\x38\x77\x38\xf7\xd1\xe2\x68\x25\x60\x66\xef\x3c\xc5\x65\xf1\x17\x9f\x4e\x40\xc8\x5a\x52\x92\x7a\x04\x80\x1b\xf7\xd5\x44\x76\x0c\xc8\x68\x0f\x23\x47\xcd\x2a\x9f\x9f\xb3\xb7\xef\x0b\x33\xed\x2d\xa4\x60\xc4\xb1\x34\xb9\xb2\x3b\x5e\xf3\x59\xae\x10\xbd\xfd\x04\x1f\xc3\x1c\xd3\xf7\xdf\x53\x51\x23\x67\xa9\xc0\xa1\xfa\x1f\xd2\x1c\x56\x35\x38\x2f\x8f\x2a\x1e\x85\x4e\xb8\xc7\xf0\x4a\x0f\x5f\x09\x7c\x81\xa6\xe4\xa1\xb1\xa9\xc7\x6d\xd4\x97\xaa\x17\x5a\x69\x8c\xb8\xea\xeb\xd8\x2c\x85\x98\x22\xf1\xed\x7c\x37\x5f\x74\xde\x06\x05\x26\xd1\x49\x32\x21\x65\x13\x29\xed\x47\x88\x29\xa8\x04\xdd\x91\xfa\x72\x32\x62\xe9\x83\x97\x0c\x1b\x27\x26\xee\xd1\xc6\xfc\xfb\xdc\xec\x3f\xb7\x45\x39\xcb\xb2\x9f\x69\xbb\x25\x86\x5e\xc4\xc0\x6e\x68\x33\xcb\xfb\xbe\x85\x66\x7f\x74\xa8\xe6\xb6\xa7\xcf\xe3\xc8\x69\x08\x9e\x40\xa6\x7c\xc8\x53\xf5\xf7\xdc\x95\xd0\x57\x51\x68\xa7\xeb\xc2\xea\xf6\x8f\x9e\x3c\xa0\x40\x78\x1f\x7a\x63\xbc\x99\x29\x9b\x3e\x0c\x92\x08\x73\x90\x36\xb1\xb5\x76\x19\x07\xf7\xcc\x34\xf1\xd1\x9f\x3f\x20\xd9\xc0\x5b\x0f\x30\x7e\xfe\x8a\x2c\xa0\xb9\x4a\x79\x48\x46\xad\x6c\xac\xdc\xda\xfa\xb6\x35\x54\x01\x26\x38\x3f\xec\xc3\x9d\xf3\xfa\x32\x8c\x12\x84\x11\x01\xac\x35\xb5\x06\x81\xda\x36\x0f\xf5\xf7\x12\x02\x61\xc4\x4d\x2c\x48\x81\xcc\x78\x09\xdb\xdb\xc1\x79\x11\xc6\x21\xc1\xd2\x2f\x9b\xdf\xff\x36\x76\x13\xc6\x11\xc5\xe7\xb0\xc0\xbf\x9a\x57\xce\x35\x0e\x59\x40\x55\xf4\xff\xaa\x6a\xda\xdd\x33\xa4\xb8\x15\xed\x5c\xe1\x54\xfb\x63\x91\x36\xc5\x8b\x05\x92\x4d\xf7\x22\x3a\x21\x83\x08\x21\x1f\xfb\x5f\xeb\x96\x69\x48\x93\x30\xf1\x02\xa7\xcd\xf7\xd8\xae\xcb\x30\xa1\xca\xb0\x84\x22\x71\xc3\x07\x2f\xbf\x91\xcc\x72\x97\x08\x61\x05\x5d\x2c\xe3\xc7\xa6\x84\xfb\xa2\xb8\x2a\xe6\x70\xdd\xa5\x36\x4c\xc8\x27\xc8\xeb\x7d\xa1\xb8\xb3\x49\x43\xee\x5b\x0d\x45\x34\xbf\x2c\xa4\x77\x0e\x13\x32\x32\x4d\xe7\x88\x62\x69\xe3\xa9\xe8\x64\xbc\x9b\x3f\xc7\xcc\xeb\x04\x99\x5c\xa0\xaf\x6d\xe5\x41\x60\x48\x01\xb4\x21\x38\x9c\xb5\x2d\x2a\x31\x25\xb4\xae\x1e\xce\xe4\x61\x6c\xab\x60\x21\x06\x83\x1f\x8a\x97\xdd\xbf\xcf\xbc\x84\x66\x7d\x1b\x5a\xdd\x2f\xa5\xe3\xec\xa5\x52\x2a\xc4\x35\x15\xf9\xcd\x7f\x95\x4b\x08\x95\x17\x69\x0b\x88\xd8\x7f\x8e\x20\x42\x4d\x73\x18\x62\x66\x37\xe7\x47\x50\xc3\x09\xac\x22\x86\xf1\xc4\x43\x0e\x1f\xab\x5c\x16\xc7\x34\x7f\x99\xaa\x13\x9c\xce\x87\xb8\x9b\x30\xa3\xbd\xc8\xeb\x81\x01\x1b\x2a\x15\x29\x4b\x74\x6c\xb3\x70\x5f\x3c\xbe\xe2\x48\x30\xf5\x0b\x86\x1e\x76\xa8\x03\xb0\x50\x0c\xe4\x50\x82\xf2\xf0\x5e\x20\x23\x34\x32\x73\x0d\x9e\x41\xd3\xd0\xd4\x87\x1a\xf5\xa8\x0a\x19\x73\x30\x78\x35\x4a\xef\x86\x9a\x43\xe4\xe4\x9f\xea\xa2\x1c\xe5\xa1\x22\x12\xc5\xb8\x89\xb9\x43\x78\x7e\x79\xf8\x1b\xd5\x46\xee\x62\x29\x91\x71\x15\x2a\x79\x7b\xce\xd5\x6c\x10\x0f\x8d\x88\x8e\x3c\xfb\x99\x16\xe7\xb2\xfa\x2a\x0e\x15\x79\x9e\x44\x94\x5c\x56\xc8\x37\x54\xa0\x77\x1c\x83\xd3\x3f\xea\xb1\x48\xba\xa4\xfa\x16\x90\x6b\xcc\xfd\xa2\x4f\x49\xd2\x86\xb2\x31\x18\xb7\x3c\x9e\xea\x49\x1e\xef\xa6\x37\xf8\x51\x07\xd5\x56\xbc\x7c\x73\x30\x6d\x4d\x22\x4a\x0c\xd3\x54\x73\x2e\x01\x3f\x3a\x49\xd1\x49\x2b\x23\xa2\x91\x11\x22\xbc\x99\x6d\xf7\xed\x0d\x44\x12\x63\xe8\x1a\xb1\x4b\x59\x51\xb5\xac\x81\xb6\x43\x28\x03\xf4\x92\x1f\x8b\xbc\x38\x15\x19\x62\x97\xbe\x73\xc5\x47\xbf\x19\x51\x4e\x5b\x3d\xf8\x75\xde\x7e\xd0\x28\xd2\xb8\x0f\x0a\x94\x1a\x9e\xa7\x35\x86\x11\x27\x67\x62\x14\xc5\x5e\x82\x79\xb6\x52\xec\xfb\x50\xa1\xab\x8d\x96\x5d\xc7\x29\xa3\x88\x51\x8a\xa9\x45\x38\xa6\xf5\xac\x04\xbe\x7c\xe7\xd9\x79\xd2\xf4\x3e\x8f\x6b\xcf\x9b\xcb\xa5\x30\xe2\x1f\x25\xc0\xfc\x9c\x66\x93\xbc\x27\x9a\x44\x2c\x14\x68\x43\xee\x1b\x57\xe4\xdc\x06\x6d\x22\xc6\x0d\x8b\x9e\x45\xa1\x60\xed\xe3\x17\x13\x8c\x29\xc9\x7a\x8b\xe5\x3f\x0e\x5f\x70\x05\x74\xb1\xfd\x93\xc8\x4f\x4c\x6a\x2e\xc7\xf0\x80\xa9\x24\x2c\xeb\x56\x55\x53\x93\x88\x7b\x80\xa0\xb6\xdf\x9f\xd7\xfb\xa5\x91\xfd\x77\x4d\x82\x24\xa6\x6a\x2e\xc7\xe2\x6c\x5d\x42\xf5\xfa\xd0\x05\x86\x23\x11\x06\xa8\x32\x52\xf1\x77\x68\x79\x45\xda\xc6\x44\xe2\x6b\xf1\xf7\x17\x03\xec\x81\xba\xab\x5b\x6f\xda\x85\x01\x83\x2e\x7f\xed\x97\xdb\xa7\xd9\xc3\xe1\xf7\xe7\xe5\xf6\xcf\xc3\xdd\x6c\x77\x78\x58\x3d\xae\xda\x87\x90\x61\x84\x11\x07\x59\xe4\x55\x5d\x1a\x46\xa0\xde\x69\x10\xa9\x20\x30\x89\x61\x5b\xff\xfd\xfd\x04\x57\x61\xc4\x2d\x53\x54\x30\x48\x9c\x47\xc0\x23\x1c\xab\xba\x78\x46\x34\x98\x0d\x3c\x74\x72\xb0\xdd\x17\x07\x21\x9d\x94\xf0\x6f\xef\x5f\xac\x49\xd0\x11\x26\x95\xf4\x39\x57\xe8\xcd\xad\xac\x18\xc1\xf7\x47\x42\xa4\xa5\x47\x9c\x56\xef\x90\x3c\x63\x7a\xeb\x8a\x09\xd5\xe8\xe1\x7e\x00\xbc\x05\xfd\xec\x6b\x4c\x42\x1f\x19\xd0\xac\x68\x4a\x75\x9a\x89\x74\xb0\xf9\xc6\x24\x0a\xb1\x04\x18\xc1\x32\xfb\xe2\x26\xe5\x7d\x6a\xd2\xd6\xbc\x88\xbd\x30\xc4\xec\xd4\x81\x2b\x85\x32\xa8\x63\x61\xe2\xc1\x20\xc7\x9e\x08\x51\x9d\xe1\xa1\x78\x31\x10\xa3\x2d\xfc\x7b\x78\xb4\xc5\x9e\xe4\x58\xd7\xd3\xb8\xab\x8b\x2c\x05\x43\x06\x98\x5d\x07\x10\x46\x97\x29\x81\x76\xaf\x06\xa8\x16\x06\x09\xd9\xe6\x61\x62\x0f\x24\xba\x48\xb3\xdb\xfd\x72\x7b\x78\x9c\xfd\x3a\xdc\xad\x67\x0f\x87\x9b\xe7\xed\x6c\xbf\x5a\x3f\xb9\x6e\xbe\x1f\x2b\xa3\x2d\x6d\x54\x21\xba\xad\xe2\x8b\x44\x44\xec\x87\x21\x06\x3c\x72\xf8\x44\x4b\x55\xf1\xf2\xd2\x43\xe9\x6b\x12\x07\xc2\xc7\x03\x0f\xce\x65\xb1\xe5\x69\x05\x6a\x2b\x5d\x1b\x4d\x8c\xf9\x28\x32\xee\xfe\x14\xc6\x06\x2e\x82\x00\xc9\x83\x29\x77\xd8\xdf\xaf\x9f\x77\xb3\xa7\x9b\xfd\x7d\xdb\x4b\xfb\xa8\x67\xf5\xfb\x76\x9b\xb6\x76\x4a\x1c\xf9\x89\xe1\x80\x7d\x87\xbc\xae\xee\xd3\xaa\xa5\x7c\x6c\x1a\x05\xc7\x49\x0c\x8d\x0f\xdb\x8c\xbc\xd2\xdd\x4e\x13\xc7\xbc\x1f\x4c\xd9\xf1\xe3\x69\x1a\x40\xaf\x49\xcc\xbc\x84\xbb\x24\x03\x54\x7c\xf4\xf5\x98\x1f\x51\xe2\x6a\x7b\x90\x6e\x63\xd1\x1f\x8d\x24\x88\x99\xf5\xcc\x53\x7d\xb9\x2f\xca\x0a\x2e\x37\x39\xff\x31\x0a\x0a\xb9\xde\xd4\x6c\x14\x2f\x50\x6f\x0b\x89\xb6\x1c\x7a\x91\xc3\x9f\xe4\xc4\xc3\x64\x52\x61\xd0\xeb\xb8\xd4\x47\xeb\x63\x38\x09\x05\x0d\x0d\x89\x53\xfa\x6e\x0d\xf1\xb4\x35\x12\x63\x41\x23\xc2\x1c\xc3\xd3\x39\x2d\xcd\x7e\x5b\x17\x6d\x7b\xc2\x31\x19\x23\xa1\xac\x67\xe7\xfa\x15\x1d\xe4\x6a\x01\x25\x32\x90\x5e\xfb\xf5\xa3\xd3\xee\xaf\x6a\xf3\xf1\x17\x34\x96\x38\x3c\xf2\x53\x06\x3d\x97\x35\x96\x44\x20\x42\x67\xf6\x52\xa6\xa8\xbe\xfe\xc0\x05\xb4\x5f\x5f\x52\x2a\xdb\xf4\xd9\xa9\x4c\x47\xe5\xc3\x9a\xc4\x8a\x48\x5c\xf5\x0f\xc5\x04\x8b\xf9\x60\xf5\x83\x12\x58\x6e\x74\xe4\x9f\x8d\x15\x8e\x0b\x7b\x68\x54\x31\x12\x04\x58\xe4\xb1\xdf\x9d\xb8\xec\x3f\x26\x23\x9a\x21\xd8\xee\x71\xf6\xa7\x33\xb0\x99\xa7\x12\x44\x84\xdf\xf3\x92\xff\x96\x96\x69\xfb\x77\x6d\x08\x15\x9b\x25\xb9\x5f\xef\x67\x0f\x8e\x80\xf7\x6e\xb9\x3f\x2c\xdb\x09\xcf\xfc\x28\x74\x69\x87\xe6\x98\xba\xd2\xbf\x1e\xaa\x0c\x8f\x51\xcf\xb6\xa2\xc7\xfe\xe3\x6e\x99\x48\x24\xf6\xfb\x03\x4a\xde\x7f\xfc\xc0\x0b\x23\xa4\x00\xff\x73\x3e\x88\xd0\x5e\xa7\x0c\x58\x00\x0c\x99\xa1\xed\x58\x36\x47\xb7\xd3\xe6\xb0\x3d\x68\x20\xb0\x3a\xec\xdf\xe7\x54\xbe\x2d\x8a\xfc\x1d\xca\x09\x1c\xd9\x70\x02\xb0\x50\xf8\xdc\x73\x02\xc3\xf8\x0c\x7d\x7b\xd5\x76\x8a\x02\x49\x6c\x26\x1e\x99\x8b\x9e\xab\x61\x9d\x5d\xd3\x25\x89\x10\x76\x94\xa3\xb0\xf4\x01\xf5\xd6\x0e\xaa\x3b\xe0\x9b\x0e\xe1\x17\x05\xdf\x6d\x8f\x18\x17\xfb\xef\xe7\xcb\x0d\x3f\xbb\xeb\xe2\x28\x46\xef\xe3\xb7\x42\x16\xfd\xa1\x8b\x95\x8f\x01\xc7\xdd\x7e\xbb\x9c\x3d\xae\x9e\xee\x5c\x03\x53\xc6\x5d\x11\xe7\x51\x6a\x94\x25\x81\xc2\x6a\x82\x23\xff\x6c\xcc\x33\x43\xbc\x5b\xf6\x9d\x3a\x96\x08\xa3\x49\xfc\xca\xab\xd7\x9a\xbf\xb4\x7f\x56\x21\x22\x95\x71\x72\x5e\xe3\x8c\x59\x02\x3e\x38\xae\x3b\x6b\x95\x4e\x2d\x37\x96\x40\x82\x99\x31\x1b\xe2\x78\x82\x5a\x63\x00\xd3\xdd\x87\x87\x9a\xdb\x80\x0a\x1a\x60\x18\x8a\x1e\x4c\x03\xc1\x7c\x17\xe2\xe9\x8b\x9c\xd8\x56\xd9\x3c\x88\x89\x86\xd5\xaf\xc8\x6b\xae\xfd\xb6\x4d\x2a\x3c\xa1\x5d\x2c\xcb\x32\x22\x7c\x73\xba\xb7\xb3\xd8\xe4\xcf\xba\x93\x98\xa9\xb0\x83\xd4\xa5\x3c\x33\xf1\x0b\xb4\xab\xae\xf6\xc1\xff\xf6\x5f\xfb\x0b\x10\x44\x83\x5c\x94\x51\x81\x9a\x3c\xe8\x19\x70\x8a\xbc\x1f\x46\xf2\xa7\x35\x5a\x87\x43\xaf\x79\x60\x08\xa3\x1c\xb5\xe2\xc1\x6a\x1a\x5c\x6e\x46\xc5\x20\x9a\x24\x44\x02\xd2\xa1\x70\xa5\x5a\xbc\xaf\x6d\xf2\x20\xe4\x48\x0c\x5f\xa4\xf9\x23\xb4\xd8\xb7\xc4\x27\x1c\x17\xc0\xc7\x31\xfd\x12\xde\x91\xf8\x9e\x60\x04\xa7\x97\x48\xe5\x6b\x0e\x6d\x4a\x36\x09\x08\xb5\x62\x1b\x06\x39\xfe\xce\xb3\x9d\x7c\x05\x75\xce\xdc\x87\xfa\xde\xfb\x4f\x02\x5f\xa8\xb8\xb3\xdf\x71\x5a\xd9\xea\xd1\x51\xc7\x80\x0b\x03\x67\x5f\xe5\x26\xf5\xd5\x87\x45\x25\x81\x56\x18\xb1\x3b\x88\x54\xf5\x34\x8b\x46\xbf\x46\x7d\x85\x2c\x71\x2f\xfc\x08\xb6\x0e\x74\xb0\x98\x13\x1a\x47\xf8\xa6\x08\x61\xea\x2a\xe2\x35\x49\x42\x50\x86\xcc\x04\x23\xf0\xb3\x5c\x2d\x73\x35\x20\x1f\xb4\xfd\x22\x9a\xb8\x35\x85\xc5\xf6\xbd\x52\xd8\xa6\xd5\xc6\xe7\x7b\xf8\xe2\x69\x1b\x22\x89\x89\x59\xbb\x56\x79\xf5\x2d\xb3\x7c\x9e\xdf\xc7\x9a\x92\xd8\xe6\xd6\x8f\xfc\x73\x7e\xbe\xa4\xf9\x4b\xcf\x5b\x49\x18\x18\x06\xc0\xd5\x62\x3d\xc8\x1e\x26\x4c\x1b\x96\x2c\x9d\xe6\x3c\x33\x25\xf2\xbd\xed\x25\x49\xbc\xd0\x10\x84\x55\x55\xfa\x32\x29\xd2\xd0\x74\x0a\x93\xc8\x6c\xa5\x35\x6f\xbc\xab\xe9\xb2\x94\x24\x91\x06\x0c\xff\x02\x75\x4b\x64\xd3\x2b\x4e\xda\xf2\x5c\x15\x23\xf3\x25\x49\xb4\xc0\xa3\x11\xb5\x7d\x9d\xbc\xf5\x08\x39\x91\x70\x4f\x63\x7a\xbf\xd9\x03\xd1\x67\xd8\x5f\x4e\x36\xf8\xc4\xfe\x6e\xc6\xd3\xdd\x8a\x12\x2f\xb2\xfb\xc4\xb4\x81\x94\xf0\x90\x69\xd6\x53\x49\xdb\x41\x66\x36\xb5\xdb\xb2\x30\xc6\xc0\x75\x36\xaf\xdd\x88\x12\x9e\x18\x78\x12\x57\xea\xae\x68\xad\xd3\x44\x00\x47\xf2\x12\x04\x38\x2c\xd2\x3a\x6d\x23\xdf\x89\xd0\xd2\x60\xb4\xdb\xa1\xba\x4d\x3f\xe1\x0b\x86\x3c\x4d\x12\xe9\x87\x46\xf0\x01\xf9\x9d\x31\x69\xbb\x29\x8b\x77\x2e\xb2\xcb\x2d\x4f\xcb\x6b\xa2\xa4\xe6\x9a\xc0\xc3\x70\xfe\x13\x94\x6a\xf7\x9a\xd6\xbd\x73\x2b\x91\xb6\x9a\xa4\xfa\xe0\xa7\xf1\xc8\x4b\x2e\x13\x93\x11\xc5\x2a\xfc\xab\xf0\x5d\x2f\x37\x9a\xa8\xc0\x78\x68\x65\x71\xe1\x59\x7d\xd9\x97\xdc\xe8\x2f\x0c\x47\x57\xa9\x18\xf1\x1c\x2d\x23\x87\xd6\xe9\xff\xcf\xd9\x9b\x74\x37\x8e\x63\x5f\xe2\xdf\xa5\x57\xb9\xa8\x05\x01\x70\xfc\xef\x64\x59\x76\xe8\x97\x9e\x4a\x92\x23\x32\xab\x4f\x1f\x1d\x0c\x0f\x36\x2b\x24\x52\x45\x52\x76\xb8\x3e\xfd\xff\xf0\x3d\x00\x22\x29\xd9\x99\xdd\x9b\x8a\x2c\x03\xa4\x48\x10\xc3\x1b\xee\xbb\x77\x57\x62\x26\x63\xbf\x2f\x07\xe8\xcb\xc2\x98\x3c\x8e\x03\x15\xb8\xcf\x52\x11\xbc\xf9\x33\xad\xe7\x0b\x8c\x0a\x36\x2a\x40\xc4\x1e\x30\xe5\x0b\x1b\xa6\x94\x7c\x7d\xaf\x34\xb1\x0e\x7e\x3c\xeb\xea\xfd\x8d\x9c\xec\x35\xde\x76\x2a\x40\x72\x34\xcc\xeb\x51\x82\xe2\xcb\xd4\x72\x01\xda\xa2\xb7\xee\xcf\x82\xed\x30\x36\x2b\x23\x21\xd1\xd0\x58\x6e\x16\xe1\x4f\x92\x23\xab\xc4\xf7\xe5\xd3\x0d\xf8\xe5\x2a\x59\x42\xb7\xd9\x2c\x17\x2b\x7e\x12\x60\xb5\x91\xe4\x82\x98\xfe\x28\xa3\x84\x06\xf2\x99\xcc\x45\xdf\x2d\x2b\xd0\xcf\x3f\xf4\x63\xc9\x16\x98\xa9\x9c\x75\xe1\x26\x0a\xa4\xcf\x0a\xe3\xc4\x5a\xd5\x3f\xc7\x96\xaf\xe4\x3a\x16\x84\x61\xbc\x45\xf6\xa8\x01\xf2\xda\x77\x11\x1c\x32\x45\x1b\xd5\x0a\x7a\x3f\x0b\xb7\xf3\x40\x5d\xed\x7b\x25\x29\x2e\x94\x63\x0b\x0d\xea\x11\x4f\x82\x34\x52\x68\x48\xcc\x68\x5d\x5c\x97\x6f\x9f\x9c\x63\x52\x38\x6d\x0c\x92\x9c\x9e\x3d\x2d\x2f\xf0\x1c\x62\x37\x2b\x63\x2f\x1f\x40\x86\xd6\xbc\x6e\x9a\x0b\x04\x6e\xde\xc9\x95\x31\x27\x91\xa0\xad\xab\xb6\xbb\x83\x37\xd8\x7d\x61\x7e\x7f\xfd\x8f\xbf\xa9\xc8\x70\x3b\x78\xf7\xe5\x15\x98\x63\xf3\x8d\x89\xb6\xe4\x8e\x1e\xea\xa6\xdb\xa2\xe9\xf4\xc9\x6b\x67\x0c\x6c\xea\xcd\x3c\x78\x23\x78\xe2\x60\xe1\xcb\x2c\x4f\x28\x24\xe3\x8e\xee\x61\x2c\xfc\xc2\x46\x21\xb3\x22\xf3\x40\xbc\x6b\xf9\xf1\x4f\x52\x7a\x98\x7e\x19\x69\x34\xc2\xd7\x67\xcb\xfb\x01\x84\x51\x4a\x1b\x7b\xc0\x3b\xa1\x5b\xdb\x9b\xba\xb9\xaf\x8d\x1b\x2e\xbf\x7e\xa4\x52\x22\x27\xa6\xcc\x6f\x75\xf7\x39\x49\xa2\x8d\xa4\xd6\x39\x16\x0a\xfe\x73\xbe\x9e\x0f\x03\xe9\x52\x5b\x9a\xa8\x87\xb2\x91\xd5\xab\x6c\xa7\x5a\x20\x36\x92\x86\xc7\x02\xbc\x2f\x7e\x52\xd3\x24\x61\x99\xc9\x30\x1a\x0d\xa8\x4a\xe5\x08\xc0\x7e\x94\x55\x55\x56\x2f\x01\x35\xe2\x7b\x19\x22\xe3\x70\x06\xcd\x77\x68\xfa\xed\xea\x62\x84\x51\x42\x24\x14\x81\x19\x54\x3d\xdc\x6d\x65\xef\x16\xb9\xc2\xd7\x7e\xf6\x3d\x93\x9c\xc6\x0e\xcc\x35\x58\x18\xa6\xb9\xc7\x4f\x68\x93\x48\x17\x4e\xcd\xeb\x00\x54\xe2\xef\x9b\x32\x48\x93\x93\xf9\xf2\xe2\xbe\x6c\x18\x6e\xab\xa8\x46\xa9\x82\xf7\x9b\x63\x77\x6c\xc0\x21\x62\xbf\x36\xdf\xa4\x35\x04\xd9\xd8\xf2\x2d\x98\xa3\x1e\xae\x5d\x15\x31\x42\x20\x7e\x5f\x3e\x2c\xfe\x9c\xad\xae\x27\xf0\x62\x15\x25\xca\x9a\x13\xb3\x55\xfb\x68\x49\x8c\x60\x3c\x48\x2a\xca\x48\x69\x94\x0c\xa1\xd9\xe1\x00\x72\x37\x3e\x80\x54\x94\x67\x3a\x68\xd9\x55\xb6\x7c\x79\x2e\xab\x6e\x38\xc3\x55\xa4\x89\x62\xa3\x01\x69\xd6\xb5\xed\xde\x65\x03\xcb\xca\xf6\x5e\xdf\x57\x19\x1f\x77\x35\x93\x86\xbe\x93\xa3\xa6\x9c\x4a\x3a\xfa\x6e\x8a\x88\xf4\xe9\x49\x03\x8a\xbc\x7e\xff\xed\xef\xc0\x22\x15\x8f\x59\xce\xfc\xe9\x4f\xd3\xb4\xff\x82\xde\x13\x52\x3c\x61\xc8\x58\xdd\xbe\xd6\x87\xdf\xab\xd2\xfa\x6f\xab\x44\x64\x53\x1f\x49\x26\x9f\xe6\x04\x9e\x3a\x77\x6c\xc6\x3f\x2a\xb8\x4e\xbd\x90\xe1\xb6\x7b\x6d\x00\xb0\x5a\x74\xf1\x9f\x2b\x3a\x24\xc3\x6f\x64\x04\xb0\x3d\x56\x21\x7c\x3e\xf9\x4e\x42\x66\x98\x71\x78\x95\x8d\x99\xcb\xc3\x70\x25\x2a\x21\x0d\x40\x08\xa6\xd2\x79\xb0\xfa\x44\xc3\xc6\x46\x2a\x61\x69\x42\xe4\x38\x3b\xf9\xf1\x68\x89\x8d\xcc\xdf\x2b\x11\x1c\xa7\x55\xff\x19\x4f\xe0\x58\x95\x88\x58\x3b\xbc\x84\x2f\x48\x3c\xe9\xdb\xdb\x48\xa5\x3c\x92\xb4\x9f\x38\x7d\xc7\x79\xbd\x3f\xec\xa0\x9b\x02\xcb\x55\x0a\x54\x67\xfd\xb8\xba\x5e\xac\xb6\xf3\xd9\xc3\x7c\x71\xf7\x17\x83\x98\x41\x82\xe1\xea\xc0\x14\x81\x69\xfe\xcb\x7d\xf3\x28\xc2\xf2\x01\x5f\x62\x46\xc4\x2b\xd7\xa7\x43\x5a\xe5\x89\x62\x0e\x0a\x7d\x0d\x56\x1e\x77\x28\x42\xbf\xac\x46\xb2\x0e\xa7\x1b\x16\x90\xe0\xb8\xd7\xd5\x62\x35\xcf\x38\x73\x5c\x48\xe7\xaa\x63\xc3\xf5\x20\x39\xc9\x36\xef\xd1\x7e\x25\x38\xdf\xa0\xb2\x4c\xc9\x22\xc1\x02\x66\xc4\x27\x0d\x4b\x34\x95\x2c\x52\xe2\x35\xa5\xb2\x6c\xe2\x16\x0b\xa3\x2c\x81\xe3\x4a\x34\x35\x06\xfd\x26\x10\x5b\x25\x21\x43\x1b\x7d\xeb\x4c\xc5\xab\xe3\xc7\x4a\x56\x9f\x24\xc2\x95\x92\x24\xa6\xf6\x6d\xfd\x6d\x34\x9b\x14\x44\xa8\xe3\x89\xe6\x09\x51\x59\xe0\x42\xd9\x6e\xea\x53\x97\x1c\x43\xca\x41\x3b\xef\xab\x58\x9e\xd2\xa9\xc6\x90\x7b\xd9\x12\x76\xf4\x6c\x4e\xe8\x42\x3b\xb2\x10\x1a\xdb\xeb\xc5\x86\x78\x43\x3e\x79\x72\x2d\x29\x3d\xf3\xdc\xf6\x1e\xd8\xd5\xe4\x6e\xa6\x90\xe8\x34\x1f\x8e\xed\xeb\x18\x34\x74\x72\x11\x94\x65\xc4\x53\xf9\x24\xcb\x41\xaa\x80\x4c\x57\xdf\x25\x36\x36\x0e\xf4\x5e\x8b\x8a\xd0\xec\x93\xe9\x61\x53\xc6\xc6\x24\x29\xf5\xe4\x71\xac\xc9\x30\xca\xb7\x81\xb6\xeb\xbe\x56\x92\xb4\x91\x8e\x22\x66\x88\xd7\xb6\xae\x6d\xef\x62\x6d\x67\x95\x69\xea\x00\x1a\xd4\x51\x12\x63\x70\x10\x45\xf7\xcc\x30\x4e\xa4\xa3\x54\x22\x7b\x02\x1a\x6b\xc7\x76\x62\x5b\x6b\x66\x98\xce\x06\x25\x38\xae\x68\xec\xa9\xae\x77\x93\x9e\xbc\x48\x2c\x1d\xb2\xf0\xaf\x7a\xaf\x4a\x98\xd7\xbb\x7a\x02\x3b\xd3\x22\xcf\xa9\xa2\x89\x62\x8a\xf7\xb2\xac\x74\x6f\xf1\x9e\xf3\xf2\xd9\x48\xc7\x4c\x60\x04\xed\x0c\xec\xff\x35\x0a\x4d\xc7\x4c\x29\xee\x39\xf4\xe4\xfe\x30\xa5\xa3\xf6\xdd\x92\x38\x0b\x41\xfd\xf2\x63\x51\x19\x57\x43\x3d\xa5\x71\xe9\xfb\xea\x08\x33\xaa\xc8\xb3\xa6\x3b\x0a\x21\x85\x36\x21\x1c\xa5\xdd\x0d\x1a\xb1\xeb\xb2\xd2\xe0\x69\xcb\x7d\x27\x4b\xb3\x75\x7f\x6c\xbb\x4d\xdd\x7b\xa6\x44\x52\x30\xe8\x60\x22\x62\xbd\x9e\x75\xce\x6a\x26\x92\x80\xc9\x93\x24\x32\xc6\xd4\x38\x69\xc9\xf5\xdb\xf0\xe6\x71\x7b\x18\x26\xfe\x74\x22\x33\x34\xe3\x69\x67\xef\x9d\xf3\x7e\x1b\xf1\xb1\x95\x30\x9d\x75\x5a\x40\x6e\x86\xbc\x63\x01\x03\x7d\xda\x75\x74\xc6\x04\xe2\x5b\xfe\x0b\xd5\xe3\x7a\xac\xfc\x65\x23\x9d\x67\x79\x42\x63\xf8\x06\x21\xba\xcd\x78\x7e\xca\x3d\x05\xed\x84\xa9\x7d\xae\x8b\x44\x69\xef\xb6\xf5\xce\xf9\x77\xd9\x94\xfd\x2f\x7f\x5a\xa6\x76\xf9\x8c\xd6\x45\x91\x21\x08\x14\x2a\xb3\x9c\x3f\xa2\xcb\x12\xfb\xe7\x93\x29\xcb\x89\x55\xce\xc0\xbe\x2a\x5b\xdc\xac\xb7\x22\x34\x83\x44\x58\x0f\x46\x48\x57\xf5\x71\x07\x5d\x88\xcc\x68\x69\x21\x02\x0f\x95\xbb\x7d\xf0\x87\x9d\x56\x09\x45\xda\x69\x78\x89\xe1\xc5\xab\xe3\x8f\x81\x57\xfe\x82\x2c\x8e\x48\x5e\xe7\x7f\x6a\x45\x60\xbd\x51\x73\x4e\xd8\x92\xde\x54\x38\xd5\xc2\x4e\x26\xab\x82\x08\x55\x3d\x50\x6b\xdc\xd7\x2a\xdd\x34\xf5\xbe\xff\x66\xb8\x43\xc2\x05\xa8\xe5\x99\x7b\x3d\x5a\x5f\x5a\x73\x24\x35\xd4\xaf\xc7\xea\x67\xb2\x6c\x49\xd5\xd7\x35\x9a\x84\xf8\x5f\x66\xc7\xee\xb5\x7f\xa8\xc9\xf3\x98\x44\xb3\x13\xf8\x75\xf3\x2b\x5c\x96\x47\x88\xa0\x79\x9c\xcd\xe7\xfe\x6f\x90\x72\x2c\x0f\xfe\x63\x39\x7b\xfc\xd7\xb7\x65\xf8\x38\xa0\xa5\x1d\x00\x7d\xf1\xbc\xf8\x26\x1b\xa3\x83\x05\xa1\x2d\x2b\xa8\xf8\xc4\xd1\x53\x23\x08\x59\x9d\x2d\x65\xab\x25\x56\xb7\x6e\xb1\x5c\xf8\x7d\x81\x5c\x6e\x4b\xff\x2e\x26\xe2\x1a\xd3\xfa\xb3\xef\xb7\xdb\xab\xbb\xc7\xf9\xef\xeb\x6d\xc4\x7f\x84\xd6\x2c\x42\x97\x4e\xee\x76\xcb\x0e\xf6\xbd\xef\x33\xb0\xd2\x4d\x64\x8c\x70\x15\x1c\x54\x5d\x4e\x7b\xc9\x85\x0d\xcb\x30\x9d\x6b\xa0\x70\x17\x81\x36\xfc\xdf\x4d\xc4\xdd\x4c\xdf\xf6\x7e\x40\x37\x95\x57\xec\xfb\x00\x29\x66\xd3\xa6\x55\x55\xb0\x9b\xb2\x0a\xda\xc8\x70\x2e\x91\xea\xb6\x3f\x14\x0f\x84\xa5\x1e\x2e\x05\x23\xa2\x2c\xf7\x5e\xa5\xd3\x5e\x9b\xcb\xdd\x0e\x79\x48\xcb\x41\x4d\xa7\xef\x2e\x0b\xe3\x7e\x13\x29\xf6\xdb\x61\xd2\xd3\xc4\x59\x8c\x54\x9d\x98\x19\x32\xf5\xcb\xa4\x31\x41\x27\x8d\x12\xbe\x8f\x37\x37\x8b\xd5\xf2\xe1\x76\x3b\xbb\xbb\x7b\xfc\x31\xf3\x3a\x9a\x7d\x3f\x5d\x70\xe3\x19\xb2\xf6\x30\x2a\x58\xf4\x5d\x0c\xc3\xa8\xcc\xee\x42\xbd\x9f\xeb\x92\x44\x31\x28\xec\x52\xff\x3c\x1e\x7e\x2f\xbb\x13\x72\xc8\xf7\x48\x18\x73\xdb\x67\xe3\x11\x13\xcb\xf6\xa6\xa9\xff\x0b\xd5\xd5\x85\xb8\xbc\x49\x93\x04\x83\x85\xdb\xb0\xfb\xe1\xb1\x4f\x59\xf0\x59\x65\x88\x99\xdf\x40\x73\x75\x34\x2f\x30\x49\x01\x98\x54\x53\x9d\x10\xf4\x87\xc6\x6e\x87\xaf\x35\x88\xce\x9a\xd4\x5a\xac\x4b\xbf\x07\xe8\x1e\x9d\x0c\xfb\x80\x08\xc6\x64\xba\xb0\xd6\x97\xd6\xc1\x5b\x59\x1f\xdb\xf5\xb1\x39\xec\x8e\x5f\x40\x82\x4d\x66\x05\x8e\x82\xa4\xa8\x33\xd2\x0e\xfb\x1b\xe6\x89\xce\x0b\x8f\xdb\xc4\x5c\xf2\x24\x65\x65\x72\xc7\x78\x72\x57\xbf\xac\xc0\x00\xec\xa9\x7a\xe7\x2c\x0c\x36\x9a\xd1\xb9\x89\xa5\x2f\x6a\x0f\x5c\x9a\xfd\xdf\xa1\xf0\xd0\xb5\x3b\xd9\x76\x77\xe0\x99\xe0\x9c\x49\x6a\x8a\xa8\x40\x03\xe6\xd8\x9a\x11\xb0\xc0\x14\x19\xc9\x00\xf8\xd2\xbc\x50\x60\x3a\x7e\xda\x42\x29\xcc\x26\x7f\x40\x3b\xb4\x33\x8d\xcc\xe3\xc0\x43\xea\x56\x11\x9e\x56\xe3\x89\x2d\x25\xc7\x75\x60\xea\xa3\xda\xc1\x1f\x7f\x5e\x0e\xc2\x18\xa9\x24\xc2\x81\xf6\xd0\xf4\x0f\xd1\x2d\x51\xc8\xd3\xff\x94\x8e\x19\xc2\xc4\x1c\x41\xd5\xd8\x75\xbb\xf0\x79\x4c\x46\x02\x66\x0a\x79\xeb\xae\xea\xfa\xe7\xd9\xd8\x8e\xdf\xd1\xc8\x34\x90\x8a\x5f\xce\x9d\xf9\x8e\x3a\xc2\xd0\xeb\xb2\xfa\xf7\xb1\xf9\xd8\xcb\xc3\x20\x2e\x61\x2c\xa7\x4a\x11\x75\xfc\xb8\x87\xb6\x3d\xe5\x5f\x8c\x4d\x0b\x8c\x0f\x3b\x94\xf7\xb7\xe3\x5e\xfa\xab\x20\xe2\x0a\x91\x92\x3f\x16\xcb\xed\xfd\xec\x8f\xe5\xfd\xf3\xfd\x76\x31\x5b\xdd\xfd\xf9\xf4\xbc\x9a\x7f\x9b\xad\xfd\x02\x06\x16\x69\xc4\xe8\x1e\x76\xf2\xa2\xdc\x42\xdf\x45\x10\x30\x81\x50\x18\xfd\xa1\xb4\x78\x79\x79\x9a\x92\x03\xf6\x1d\xd3\x82\x39\x08\x37\xa5\x69\x2e\x65\x36\x81\x29\xc9\xb5\x57\x69\x38\x31\x7d\xf7\x2d\x96\x24\x08\x5a\xe8\xbe\x23\xfc\x92\x68\x88\x8e\x43\x15\xf4\xf1\x18\x03\x17\x4c\x91\x26\x7b\x07\x55\xa0\x06\x02\x9e\xda\xdc\xe1\x3d\x88\x5a\xe2\x82\xca\x8c\x8d\x40\x18\xe6\xe5\xe1\x16\x95\x19\x6c\xd7\x20\xac\xb5\xb9\x0f\x0c\xfc\xa8\x27\xd1\x5a\x88\xa3\x34\xe5\x83\xdc\xea\x25\x34\x30\xc4\x5c\x7a\x75\x25\xef\x94\x0d\xa2\x7c\x77\x60\xc3\x8b\xc7\x3a\xb6\x4e\x7d\xe2\x56\x76\xf0\x2e\x3f\x96\x93\x1f\x4c\x44\x8c\xeb\xbf\xf7\x1d\x5f\x9a\x13\xf0\x12\x12\x00\x44\x91\x96\xba\xe6\xdd\x00\x1e\x0c\x29\xcb\x08\x05\x49\x19\x12\x80\xff\x0e\x62\xfe\x03\xaf\x07\x52\xcd\x11\x5e\x34\x9f\xad\x87\x4b\x11\xb2\xb4\x70\xb0\xa3\xf6\xb8\x87\xf5\x7b\x38\xb5\x21\xd3\x96\x09\xcf\x3b\x89\x21\xe2\x59\xd9\x98\xa6\x3e\x9c\x03\xc8\xdd\x15\x79\x6a\x0b\x97\x05\x43\xc6\x9d\x1d\xc9\xbd\x8f\xdf\xb1\x48\x0a\x3c\x90\xa8\xa4\x57\xee\xa6\x46\x12\xc8\x88\x04\xdf\x5b\x57\xa8\xcb\xc9\xd8\x1a\x8f\xba\x8c\x85\x90\x6e\x4b\xc3\x30\xa9\x2d\xc1\xf4\x87\x4e\x05\xcd\x3c\x30\x49\x7c\x5a\xa8\x08\x32\x56\x68\xb5\xa0\x4a\xbc\x37\x31\x40\xf1\xc2\x2a\x4f\x46\x81\x58\xec\x51\x50\x13\x54\x26\x32\x5f\xdf\x40\x19\x7b\xcf\xb4\x15\x7a\x68\xf0\x15\x10\x8b\x2a\xb0\xec\x80\x8e\x84\x0c\x56\xe8\x0f\x28\xd7\xf5\x2e\xfc\xa8\xce\x62\x24\x1a\xfc\xbe\xd8\xac\x66\xe1\x8f\x45\x8c\x3c\x24\x60\x5e\xe0\x09\x9a\xa0\xc1\xea\x9b\xa5\x21\xbe\xa2\x7a\x7f\x68\x8e\xa0\xe4\x65\x2a\xb1\xbe\x1f\x66\xc2\xdf\xea\x0e\xd6\x6f\x87\x48\x0c\x67\xbf\x89\x78\x41\xfa\x78\xea\x48\x81\xbd\xf1\x18\x19\x16\x63\x7d\x45\x53\xbe\xbc\x76\x45\x32\x6d\x55\x99\xb6\x81\x96\xb4\x37\x8a\x66\xfd\x50\x6d\x11\x04\xbd\x5d\x9a\xed\xcd\xb4\xf8\x14\x20\x33\x96\x07\x31\xcd\x1f\xe5\x24\xe0\x02\x36\x23\x16\xa0\x9b\xb2\x7d\x3d\x21\x6e\x6d\x64\x01\xb3\x2e\xc4\xb1\x40\x47\xe3\x7e\x0f\x95\xc1\x08\x71\x73\x1e\xb9\xb1\x9c\x09\xca\x5d\xf5\x4f\xce\xb3\x69\x6b\x1e\x61\x10\xac\x6c\x1f\x71\x02\x4e\x9a\x85\xe5\x3a\x1f\x63\x37\xc6\x1d\xe2\x98\x08\xbd\xfa\xc3\xaf\x01\xd9\x1e\xa7\xa7\xb4\x8d\x53\x81\xd0\x8a\xf6\xb5\x3e\x7c\x83\xdd\x3e\xa0\x02\x6c\x22\x00\xdc\xe4\x26\x7d\xd3\x69\x89\x47\xf8\x3c\x36\x91\x16\x83\x31\xc1\xb4\x79\x54\x9d\x2c\x2b\x30\xb3\xfb\xe5\x7a\xf2\x48\x99\x32\x68\x9c\xdf\xf5\x66\xf5\x50\xe1\xd4\x46\x36\xcf\x48\x7d\x07\xff\xd8\x3b\x1a\xf5\xd1\xd1\x51\x5d\x28\xff\xf4\xd7\x48\xeb\x09\xde\x9f\x9c\xcc\x0e\xd2\x68\xd2\x0e\x78\x7f\xdc\xcd\xeb\xdd\x4e\x76\x54\xfa\x72\x71\x85\xd9\x5c\x91\x18\xb8\x82\xee\x8f\xc4\x3f\x4b\x91\x66\x88\xa3\xd0\x12\x4d\xda\x73\xae\x9f\x93\x47\x65\x0b\x99\xe1\xc1\x67\x3c\x84\xf7\xd1\xfa\xdb\xc8\x24\x91\xce\xfc\x58\xef\xca\xc3\x41\x4e\x6b\x0a\xad\x8a\x05\x86\x05\xfa\x27\xac\x5e\x70\x4e\x5e\x4e\x72\x58\x95\x83\xf5\x25\x5d\xef\x2e\x2c\xf8\x59\xec\xc8\x2a\x9d\xd3\x3e\x5c\x99\x65\x65\x77\xe8\x88\x3a\xed\x74\xff\x6c\x0a\x38\xc4\x27\x5c\x96\xdb\x33\x43\xab\x35\xb8\x6f\x75\xc8\xdf\xe6\x77\x0f\x44\xca\x84\x41\xd2\x2c\x16\x0e\xca\x60\xc0\x07\x53\x3f\xab\x9d\x3d\xfb\xff\x5f\x22\x55\xad\x4e\x95\x0e\xd4\x47\x93\x20\xa2\xd5\x3a\x45\x6e\xf4\xc3\xb9\x91\x30\x19\x34\xa3\xc8\x5c\xd1\xb2\xc2\xa9\xf4\xe3\x44\x0a\x66\x8d\x4e\xbd\x11\xbb\xac\xde\xf8\x64\x69\x18\x4b\x2a\xea\x13\xec\xa6\x05\x41\xca\x0b\x7b\xe8\xe4\xd5\xb1\xa9\xe6\xb2\x51\x75\x75\xdd\x4f\xb3\x73\xd2\x8c\x11\xfa\x79\xf2\x86\x00\xcc\x3a\x0b\xd9\xf1\xed\x7e\x1d\x63\xb6\x00\x16\x39\x5c\x30\xac\xe6\x45\x35\xcf\x7f\xe1\x93\x7a\xb2\xde\x45\x40\xd0\xe9\xdd\x51\xff\xd4\xaf\xb0\xff\xf8\x84\x76\xd3\xda\x54\xea\x78\x10\xcb\x3e\x25\x5b\x46\x0f\xe6\x64\xa8\x2c\x8b\x22\x66\x73\x3d\x30\x3f\xc6\x52\xa9\xc3\x9b\xb3\x88\xc5\x82\x24\x8e\xb1\xa2\x1f\x93\x54\xcf\x67\x84\x3c\xa3\x17\x67\x11\x4b\x89\x13\x62\xaa\x90\x92\xff\xe6\x3b\xb8\x32\x45\x55\x1f\x5f\x5e\x3b\x2f\xfb\xd1\x37\x28\x4e\x2a\x60\x87\x43\x8b\xdb\xfd\x80\xb7\x85\x45\x42\xc5\xc8\x00\x48\xa1\x95\x7b\xf9\xcb\x1d\xa2\xe3\x5f\x8f\x75\x2e\x5c\x7d\x01\x6e\x2d\xde\x11\xb8\x95\x97\x0d\x68\x16\x25\x5c\xda\xc4\xf9\xcd\x5e\xdc\xef\x62\x45\x02\x8b\x12\x5d\xe4\x8e\xd5\x6e\xab\x29\xe2\xb9\x95\x8d\x2a\xbb\x76\xbb\xf7\x46\x37\x8b\x12\xe0\x18\x06\x7f\xfa\xbe\xd8\xce\x1f\xef\x9f\x16\x0f\xeb\x01\x24\x9b\x45\x69\x1e\x23\xfb\xca\xc1\xc7\x60\x59\x94\x45\x91\x76\x3b\xfb\x71\x67\xfc\xe2\xbc\xf6\x95\x64\x2c\xca\x1c\x79\xe7\x0b\x74\xdf\xa1\x29\x6d\x49\xa9\xbb\x81\xc0\xfb\x00\xc0\xef\xaf\x29\x88\xd6\x4c\x1d\x3f\x36\x43\xc1\xe4\xf1\xeb\x67\x2a\x81\xcc\x4b\x2b\x23\x34\x76\x60\x56\x33\x94\x2a\x18\xa6\x4a\xbe\x72\x09\x59\x54\x24\x2c\xd3\x8e\x6a\xf5\x45\x76\x60\x36\xbf\x7a\xaf\x09\xda\xe7\x16\xc6\xf1\x0a\x16\x15\x69\x8e\x01\x73\xd9\xb6\xd0\x74\x8b\xff\xfc\x16\xd0\x7f\xff\x18\x77\x94\x31\xd1\x50\xfe\x98\xdd\xdd\x2d\x36\xdb\xa7\xd9\x6a\xf3\xb0\x58\xf9\x07\x94\x59\x56\xf8\x0a\xea\xe3\x49\xbe\xe6\x1f\xe3\x2f\x27\x8b\x1c\x7d\x6e\x8f\x88\x74\xf4\xe5\xcf\x94\xfd\x6f\xc3\xcd\x80\x48\xb8\xb6\x5b\x53\xbe\x6c\xbb\x57\xa8\xb6\x87\xe0\x46\x0c\xdf\x7a\x38\xce\x5a\x52\x4e\x15\x57\xfa\x45\x4a\x49\x16\x69\x25\x30\xb9\xfe\xa8\xfe\xed\xdd\xc5\xbf\xe4\xef\xe8\xaf\x4a\xd0\x8a\xa6\xd8\xd2\x54\x68\xf8\xf2\xf2\xd3\x90\xe9\x38\xe4\x3e\x9b\x71\xba\x74\x74\x77\xc3\x8c\x27\x84\x7c\xae\x54\x8d\xe1\xed\x01\xc1\xb7\x4b\x35\xb3\x08\x12\x0d\x2a\xd0\xbe\xfb\x2a\x79\xbf\x9d\x80\xd6\x94\xa8\x7e\x95\x65\xb5\x2b\xab\x9f\x03\x2b\x81\x45\x56\x42\xea\x6c\xb3\xbb\xbb\xef\x5b\xe8\x37\x02\xce\x7e\x1b\x3d\x87\x35\x36\xd1\x03\xed\x0c\xaf\xb0\x4f\xcd\xfd\x3c\x46\x8b\xd0\xc9\xc1\x7d\x1c\x26\x9b\x14\x8b\x94\x32\x4e\xfc\xf8\x78\xf0\x8c\x16\xfe\x6a\xc6\x01\x83\x31\x07\xf9\xf1\x27\xc8\x66\xf7\xf1\x3f\x52\xff\x3c\xd4\x93\x95\xcd\x58\x42\xb4\xdc\x3e\xfa\x76\xbf\x5e\x5e\x5e\x2f\x8c\xf7\x1e\xf7\xff\xfa\xff\xfe\xd7\xed\xff\xdc\x2f\xfd\x8f\x08\x4d\xd2\xcc\xa5\xae\x37\xaf\x0d\xb4\xaf\xf5\xce\x60\xd8\x87\x85\x1e\x36\x8b\x08\xac\xf4\x56\xb6\x75\xf3\xe1\x45\x80\x06\xb0\xda\xbe\x93\x93\x2e\x6e\x8e\x70\x5b\x9b\xf0\xf7\x38\xd6\x68\x31\x7f\x9b\x90\xfb\x30\x16\x27\x19\x77\x20\x64\x3c\x30\xa1\x79\x92\xbe\x62\x89\xb1\x38\x53\x72\x48\x88\xbf\x22\x0c\x97\x6f\x4e\x52\xed\x23\x7c\xce\xed\x20\xc7\x39\xb4\xdb\x88\xc4\x41\x5f\xcb\x0e\x09\xe3\xd7\x70\x2e\x46\x68\x19\x4b\x23\x83\x9b\xd7\x20\x38\x37\xa3\x9c\x73\xf7\xf1\xdb\x85\x22\x38\xc6\x52\x4e\x82\x05\xf3\xe6\xe3\xd0\xd5\xce\xda\xf5\x1b\x3d\x4b\x33\xc0\xa8\x82\x93\xa5\x42\x8c\xc1\xd2\x3e\x00\x98\x89\xd7\xc7\x58\x9a\x03\x63\x27\x5d\xd9\xfb\x5a\xa1\x12\xe5\x84\x96\xe7\xb3\x54\xc1\x70\x16\xb2\x4c\x14\x88\xf4\xa4\x68\xb2\xb9\x69\xea\xfd\x2d\x91\x6f\x5e\x50\xa2\xf4\xd7\xc4\x89\x63\x5c\xed\xe4\xee\x5b\xbd\x0b\x28\x79\xc6\x32\x4d\x94\xd6\xd8\x44\xe0\x5e\x30\x27\x46\x79\xcb\x58\x2e\x00\xdd\x12\xbf\xff\x45\xa3\x1a\xac\xd1\xf6\xc1\x72\x88\x53\x57\xa3\x4a\x3c\x19\xdf\x97\x57\x8b\x3f\x3e\x79\xaa\xdc\x66\xbe\x4c\xfb\x1a\x19\xeb\xf0\x15\xd0\xbd\x6e\x2f\x52\x1b\x31\x56\xc8\x38\x27\xa9\xb5\xe7\xaa\xfc\xd5\xf9\x1c\x57\xa8\x79\xff\xe4\x7f\xc3\xd5\x46\x7a\xf4\x0b\xc8\xfd\x68\x75\xb3\xc2\x6a\x49\x09\x8e\xfb\xb2\xea\xa4\xda\xc1\xc3\xcd\xc6\x8f\x81\xcc\x0b\xfc\x7e\x92\x56\xed\xe6\xd7\x38\xc8\xc2\x98\x2c\x32\xa4\xe8\xb9\x0f\x7a\x1f\xe1\x52\x2b\x90\xb5\x78\x71\x1c\x92\xf9\x5b\xc6\x54\xa1\x90\xb8\xfa\x66\xf5\x84\x01\xe8\xd3\xdf\x2d\x3a\x60\xb0\x2f\xbf\x8a\xa8\x31\xa6\x1c\x9c\x6c\xeb\x98\xb8\xbf\x9d\x88\x43\xfc\x1b\x2b\xc8\xb4\xa7\xb7\x1d\x93\xb5\x85\x45\xab\xb9\x26\xd5\xad\xcf\xa9\x9f\x27\xab\x42\xc7\x71\x3e\x20\x8b\xeb\x67\xe0\x88\x4a\xfb\xa2\xa1\xd9\x5f\x96\x5a\x52\xd0\x7b\xdf\x76\xf5\x16\x01\x02\x52\x77\x28\x62\xb4\xc5\xe4\x95\x1e\xaa\xfe\xf6\x57\xe4\x06\xdd\xa5\x7f\x2d\x1e\xc2\x97\xd0\x56\x13\xf8\xa7\xd4\x3f\xc3\x0e\x61\x92\x08\xb3\x97\x87\x9d\xd4\xb0\x7d\x1d\x4d\x70\x93\x10\x21\x33\xd1\xb4\x4e\x03\x05\x93\x67\x34\x86\x38\x17\xde\x4a\x78\xbf\x2d\xdf\xe0\x77\xd9\xec\x65\x40\x40\x32\x06\x2a\x2a\x28\x83\x05\x4b\x5d\xcf\xa8\x74\x60\x70\x06\x80\x4d\x34\x81\xe7\x70\xdb\x1c\x7d\x0b\x9b\x19\x6e\x4e\x85\x3d\x57\xa5\xf1\x7a\x87\xd4\x81\x47\x11\xc3\x6d\xb0\x37\x82\xa0\x81\xe3\xfe\x57\x68\x89\x8d\x4a\x4f\x97\xfa\xa3\xc1\xb7\xe6\x12\xc3\x78\xfd\xd6\xf9\x03\xe0\xe7\xee\xc3\xd5\x87\xfb\xf6\x22\xc3\xbc\xef\xfc\xdb\xe2\xe1\x7a\xe1\xff\xca\x12\xc3\x93\x01\x79\xca\xa5\xcd\x86\x73\x30\xce\xd7\xaf\xcc\x76\xef\x22\xb3\x97\x0e\x69\x2e\x84\xca\x8a\x01\x7d\xe8\x1e\xae\xa0\x7b\x07\x40\xa0\xe6\x64\xb5\xf0\x38\x2b\xa4\x3b\x49\x4f\x21\xd6\xdc\x37\x4a\x11\x45\x5e\x15\xfb\x83\x02\xe3\x61\x13\xe7\x31\x10\xc6\x61\xb1\xb9\xf6\x6f\x92\x24\x29\x32\x0f\x54\x75\x57\xda\x8f\xa9\x64\xd7\xe7\x62\x2d\xfd\xa5\x79\x62\x93\x01\x2b\xde\xf7\x7a\x77\xdc\x83\xab\x26\x2c\xcf\x9e\x3b\x65\xcc\x52\x12\x70\xcc\xa0\xdd\xb7\x58\xcc\x9a\x11\xed\xe8\x89\x87\xd1\x35\x67\xdc\x62\x7d\x00\x85\x06\xdb\xee\xf4\x71\x32\xc1\x73\xe9\xf7\x5f\x5c\xee\x93\x0a\x4a\xc6\xb3\x9c\x23\x14\x60\xf1\xf4\xc7\x88\xe4\x9b\xf1\x0c\x12\x44\xb1\xde\x1d\x2b\xfd\x8a\x5a\x40\xbe\x25\x8f\x34\x77\x76\xf8\x7c\xfe\x8d\xec\x19\x0f\xba\x62\x3c\xcf\x24\xee\x56\x8b\xee\x75\x5f\xff\xdb\xef\xf4\xbc\xd0\x89\xf1\x10\x7a\xa8\x60\xad\x4b\xa8\x34\x8c\xf0\xb5\x8c\x4b\x96\xe4\x43\x51\xc3\x6b\x78\x1b\x32\x2e\x63\x07\xe4\x0e\x78\x05\x79\x28\xed\xc7\x6f\x3e\x99\xee\x9b\xb5\x46\xbc\x94\x03\xb4\x3e\xd5\xd5\x47\x6f\x7a\x7f\x56\x90\xcf\xb8\x12\x54\x20\xb1\x86\xaa\xbb\x01\xd8\xd4\x41\x21\x68\xd2\x2f\x8d\x30\xbc\xb6\x59\xcc\xee\xb7\x4f\x8f\x8f\x77\xdb\xe5\x83\x2f\x58\x66\x5c\x47\x05\xd2\xde\x9c\xc8\x0f\x68\xfa\x6e\x67\xa3\x63\x80\xeb\x3c\x43\x23\xf2\xb0\x93\x95\xd3\x80\xb9\x20\x3f\x6d\x19\x37\x2c\xd1\xc2\x5b\x62\xef\x93\x8a\x1c\xdf\x47\x90\x34\x95\x43\x76\xd2\x34\x1f\xd6\xba\x0f\xfe\xeb\xab\x69\x6a\x8c\x21\xe6\x8e\x50\x7e\x7c\xf9\x99\x20\x01\x3c\xc3\xfc\xb7\x41\x4b\xe7\x44\x6a\x7e\x79\x63\xe6\x36\x89\x51\x9f\x54\x6a\xdd\x1c\xc1\x17\xf8\xb4\x7f\x03\xe6\xc7\xb8\x4d\x0b\xdc\x45\x1e\xea\x9f\xc7\x9b\x9d\xec\x9e\x76\xf2\x53\xe6\xf2\xf1\x31\x22\x22\x46\x7c\x16\xbe\xd2\xc1\xd7\xf5\x5c\xfc\x21\x11\x15\x64\xce\x7a\xc3\xf7\xeb\x2a\xec\xe9\xc5\x46\x26\xa4\x93\x0c\x50\xfd\x31\x3c\x85\x05\x8b\x18\xa6\xd5\xb7\xde\x15\x1c\x2f\x6c\xc1\x98\x44\xec\xe5\xe1\xa5\xbe\xaf\xab\xee\x75\xf7\xe1\x4b\xc6\x51\xd5\x31\xdc\x26\x13\x89\xf3\x1f\xbe\xcf\xff\xf8\x7a\xd0\x04\xcb\x34\x0e\xf8\xab\xdc\x75\x5b\x4f\xf7\xdb\x86\x5b\x15\x79\xe1\x2b\xaa\x4a\x5b\x56\xfd\x04\x1c\x3e\xb0\xcc\xf0\x94\xc0\x0a\xc5\x7e\x73\xf5\x0d\x3c\x92\x38\xff\xe1\x17\xec\x0f\x13\xc3\x49\x88\x2c\xc1\x4a\x17\x69\x8c\x47\x31\x92\x81\x75\x09\x40\xcc\x84\x28\x32\xd4\x8d\x59\xec\xa1\x91\x5e\x56\xfa\xf3\xc2\x59\x26\x84\xa4\xc2\x8a\x2d\xed\xff\x97\x97\xb2\x10\x5a\x60\x48\x07\xf5\x84\xaa\xee\x49\x36\x2d\x92\x4b\x38\xe2\x7e\xff\x26\x71\xce\x30\x02\x78\x5d\xfb\xfd\xee\xf2\x38\xc6\x05\x19\x90\xb4\xf1\x53\x4c\xb6\x7f\xde\x87\x3a\xec\xc0\x13\xa5\x8b\xfe\x9a\x02\x89\x37\xc0\xc9\xf2\x0f\x4c\xb9\xb1\x2d\x2b\x52\x99\x93\x48\x90\x1b\xaf\xcb\xa8\x16\x26\xb2\x88\xe2\xe9\x8b\xc7\xf9\xb7\xd1\x97\xca\xa2\x4c\x85\x0c\xd2\x2d\x74\x0e\x85\x3c\x7e\x9e\x2c\x07\xe4\x42\xfe\xe7\x51\x56\x7f\x8e\x2f\xd7\x1c\x23\x44\xd7\xeb\x87\x20\x74\xd5\xff\xd9\x30\x19\x22\x2c\xbd\x45\x37\x4e\xcb\x4d\x86\x28\x17\x19\x42\xf4\x67\x77\x4f\xa3\x9b\xe7\xb9\x45\xbc\xc8\xbe\x6b\x7e\x85\xbf\x59\x2d\x13\x67\xbc\x74\xbf\xd7\xbe\xb8\x8c\x89\x22\x21\xfd\xe6\x20\xd8\x70\x0d\x6f\x1d\x78\x4a\x28\x26\x8a\xdc\xe0\x8e\x7f\xaf\xd4\xe8\x47\xa4\xc8\x7d\x0d\xf9\xbc\xae\xda\x4e\x56\x61\xbd\x48\x95\x62\x55\xaa\xa9\x91\xba\xca\x41\x67\x27\x23\x2b\x8d\x50\x36\xb8\x3a\xb3\xdd\xee\x1b\x48\x73\x3a\x55\x85\x4a\x73\xf0\xa9\x0a\xb7\x8a\x7a\x73\xe1\xbe\x36\x30\x19\x65\x95\x93\xfe\x2f\x65\x77\x9f\x08\x62\x3a\x41\xe0\x30\xa1\x64\x2a\x0b\x0f\xa7\x20\xc3\xc4\xb5\x68\xc1\x10\xd8\xb6\x1d\xfa\x7a\x97\x32\xbf\x4c\xe8\xcc\x26\x59\xd0\x7f\x9b\xed\x76\xa3\x12\x96\xde\x05\xb7\x78\xf6\xbe\x43\x49\x7b\xd8\x6a\x90\x83\x63\x42\x17\x0a\xb7\xfa\x17\xa2\xbc\x19\xc0\x0e\x98\xd0\x32\x56\x2e\x84\x84\x74\x78\x93\x56\x9d\x62\x85\x9e\x3a\x7e\x3c\x3c\xae\x27\x03\x60\x18\x63\xd6\x95\x33\x35\x6d\x38\x89\x7c\x2b\xe7\xde\x4d\xb8\xaf\xcd\x71\x07\x57\x1f\x53\x36\x47\x26\x8c\xe6\x58\x2e\xfc\xde\x2f\xb2\xbd\xf4\x11\x6f\x26\xac\xa6\x38\xe2\xcd\xf2\xe1\x0f\xf7\xb7\x38\x4a\x48\xfa\x0d\x21\x71\xbb\xf0\x57\x45\xa1\xb4\xde\xdc\x82\x2a\x2c\xd2\xf1\xb3\xc6\xcc\x44\xc8\x1a\xe7\x29\x22\xb6\xd7\x8b\xf9\x6a\x31\x5b\x2f\x50\x9b\x72\xb1\xf9\x16\x82\x6a\x31\x67\x24\x45\xe6\x0f\xbc\x29\xed\x29\x8b\x45\xa6\x8c\xb3\x26\x87\x12\x7e\xbe\x15\x52\x2c\xbd\xc0\xcd\xd4\xcb\xc2\x4c\x6e\x60\x2d\x1e\x10\x4f\x4d\x6d\x87\xb3\x3b\x8e\xd3\x0c\xb3\xa5\xdf\x4b\x78\xbf\xff\x78\x22\xfc\x17\x92\xb3\x0e\x87\x2d\x8e\x73\x4a\xdf\x35\x74\xf7\x05\x9a\x02\x01\x65\xe7\x3a\x25\xae\x7c\x73\x8e\xc4\x9e\xa7\x10\xfa\xc5\x45\x1d\x27\x59\x8a\x38\x21\x0a\xa5\x18\x3c\x04\x3e\xe9\xa9\x25\x0c\xc8\x46\xba\xba\x99\x6a\xde\xf5\x9d\xac\xf5\xb6\xe2\xa0\x60\x72\x14\xf2\x89\xd3\x82\xaa\x66\x1c\xd0\x5e\x76\xe7\x08\x47\xd7\x33\x33\x80\x39\x57\x75\x6c\xb5\x6c\x66\x6d\x5b\x22\xd7\x9e\x1c\x8f\x4a\x66\xac\x70\xb1\xba\xed\xcf\xde\x0c\x93\x97\xce\xa1\xb8\x48\xa3\xcc\x41\x1c\x5c\x99\x2a\x6a\x2f\xb9\xb8\xdf\xb0\x30\x8e\xc5\x12\x18\x16\xc8\x90\x68\x89\xdc\x81\xdf\x13\x26\xf7\x54\x4c\x23\x60\xc6\x19\xa0\x4e\x00\x6e\x32\x26\xca\xe4\x88\x83\x69\xa0\x2d\x5f\xb0\xf6\xf2\xb6\xa9\x8f\xde\xf0\x8e\x15\x14\x81\x9b\x9b\x94\x71\x27\x3f\xa2\x65\xe6\x4d\x69\xc7\xc6\xef\x6a\xff\x7c\x35\xf3\xe5\x23\x2d\xd6\x32\xcf\x13\xe7\x60\xce\x1f\xf5\x19\x0b\x34\x8b\x0d\x8b\xb3\xb0\x19\xaf\xe5\x0e\x7e\x40\x79\x2f\x7f\x85\x66\xcd\xb2\x41\x50\xc5\x51\xf3\xcc\x8f\x8d\x1c\x88\x34\xb9\xbe\x50\xa4\xd6\x2d\xfb\x2b\x68\xbb\xab\x09\x4e\x97\xc5\xa0\x04\x46\xb8\xfa\x9f\x99\x23\x7f\x96\xab\x15\x76\xed\x36\xc9\xf1\x06\xb4\xad\x9e\x29\x0d\xf6\x3d\xa4\xc5\x1c\x8a\xa9\xab\x29\x29\x06\x8b\xad\x56\x18\xe9\x40\xed\x8b\x31\xae\x8f\xc5\xd6\xb9\xd2\xb8\x57\xc8\xce\xc1\x82\x9e\x9b\x71\x8d\x0e\x4b\xa2\x9c\x45\xfd\x88\x3d\xbe\x56\xe5\x5f\x87\xaa\x13\x96\xa7\x18\x89\x94\x55\xdd\x6f\xa1\x83\x42\x48\x96\x30\x88\x25\xd1\x05\xbc\x1d\x61\xf7\x36\x14\xdc\x60\x09\xe7\x26\xa1\x38\x82\x01\xd8\xf7\xe7\xcc\x5b\xb9\x6b\xcb\x89\x3a\xb8\x65\x89\x10\x05\x9e\xdb\x57\x0f\x9b\x01\xf1\x0f\x4b\x84\xa1\x2d\xf1\xea\xd8\x54\xc7\xc3\xb7\x7a\x87\xd5\x8f\x48\xa6\x8a\x41\x99\xda\x6f\x93\x49\x9c\x52\x68\xfc\x07\xec\x7a\x23\x70\x39\x7f\xfc\x7b\x26\x75\x92\xf2\x0c\xd9\x2b\xf6\x65\xd5\xd1\x42\xf9\x0c\xe9\xc5\x92\xd4\x00\x7a\x95\x7b\x94\xa1\xa2\xd5\xfe\x68\x27\xef\x92\x71\xc8\x8c\x57\xfe\xac\x71\x7b\xf3\x0f\x99\x09\x8e\x87\xd1\x6a\x31\xbb\x0b\x7f\xd3\x49\xac\x82\x3a\x56\xdd\x10\x46\xef\x0a\xb1\xbe\xfa\xf5\x4c\x72\xfc\x92\xaf\x93\x64\x20\x91\x6e\xc4\xd6\xcd\xcf\xb1\xeb\x99\xe4\x71\xe2\x33\x82\x5e\x76\xbc\x32\xf5\x3b\x5a\x0e\x17\x37\xa3\x24\xcf\x69\x7f\x77\x3f\xb8\xa9\x7d\x74\x60\x53\xbb\xe0\xcb\xfa\xd0\x94\x7f\x91\x23\xed\x6f\x43\xe6\xc3\xc0\xd0\x70\x67\xef\x27\xfd\x21\xce\x02\x91\x4d\xfd\x31\x97\xfb\x83\x2c\x5f\xaa\xf1\x0c\x4f\x0a\x50\x58\x1a\xf7\xfb\xf7\xf9\x68\xa6\x15\x56\xe4\x36\xc0\x03\xf5\xcf\xd6\xfb\xed\x89\x64\x0a\x01\xd4\x04\x77\xaa\x9b\xcd\xc9\x08\x4b\x64\x5a\x60\x14\xe4\x8d\x44\xf9\xdc\xd6\xe7\x1b\x0b\x09\x9e\xb1\xe4\xfb\x53\x3f\xdd\x50\xbc\x2d\x8c\xac\x84\x24\x75\x04\x0f\x8b\xaa\x9b\x00\x3a\x58\x22\xad\x44\x74\xba\x3d\xdc\x1f\x77\x4b\x07\xd7\xfd\xc7\xe8\x95\x15\x57\x66\xc0\x13\x7e\x5f\x56\x9d\xa3\xf1\xbc\x3c\x44\x0a\x40\x3b\x0e\xd8\x87\xde\x5e\x1b\xc6\xe3\xc2\x08\x29\x9b\xf9\xaa\x04\xac\x2c\xa6\xc8\x1e\xce\xec\x21\xfd\x01\x4b\xb4\x94\xb2\x08\x84\xdb\xd7\x67\x5b\x4d\xa2\x2d\x60\x14\xf0\xf7\xd5\x8f\xcd\x76\x34\xda\x26\xcb\x06\xd2\x77\xf7\x60\x4a\x59\x95\x53\xd3\x30\x01\x21\xfd\x56\x79\x2f\x3b\xfd\x3a\x23\x46\x89\xa5\x99\x51\x8c\xe0\x93\xf9\xd7\xef\xe8\x88\xdc\x1b\xf3\xb0\xb1\xc4\x72\xa2\x9d\x53\xc8\x22\x88\xa0\xff\xd0\x94\xa4\x32\x73\xc0\x97\xab\xb2\x7a\x71\xb5\x47\x2c\x8d\xf2\x74\x70\x06\x3f\xb7\xd0\x38\xc0\xdf\xdf\x61\x1b\x1e\xfc\x17\x95\x32\xb8\x9b\xb2\x88\x21\x46\xb5\x82\x5f\xdd\xf6\xa5\x7c\x03\xf9\x1e\xb2\xb9\x29\x4f\x12\x11\x8f\xd8\x84\xa9\xec\x66\xf4\x92\x29\xcf\x22\x8c\x84\x7c\x5f\x6e\x02\xaa\xed\xaf\x1c\xf3\xe9\x46\xf6\xbf\x79\xe4\x9f\x88\xeb\x44\x9e\xca\x15\x35\xb1\xe3\xfd\x0c\x16\x72\x2a\xb2\x54\x0c\x03\x50\x57\xfd\xf7\xf8\xed\x2c\x90\xe2\x7a\xc7\xb1\x4a\xdd\x9e\x71\x23\x8f\x1a\x42\xe0\x3b\x4d\x45\x8e\x81\xef\xe7\x16\x76\xd0\xb6\x2e\xd3\x85\x34\x89\xbe\x47\x22\x31\x19\xfb\x00\xef\x03\x35\xfb\x4f\x03\x8b\xe3\x51\x49\x8d\xc6\x83\xa6\x3f\x55\xc7\x11\xd3\x49\xc7\x8c\xa9\xc4\x6d\x2e\x44\xfd\xbd\x3a\x69\xd5\xb0\x34\xcb\x33\xa5\x5d\x81\x69\x6f\x86\xcc\x3f\x55\x24\x63\x69\x56\x44\x45\x32\xc6\x15\xbb\x1d\x74\x28\x14\xe6\x3b\x9b\x14\x3b\xb7\x52\xcb\xe6\xba\x96\xba\x0e\x21\x88\x34\x8f\x39\x02\x9f\x1f\xdf\xab\x21\x61\xb6\x6f\x4d\x39\x22\x46\xbe\xd5\xa6\x6e\x46\x66\x5d\x9a\x67\xd2\xe5\x67\xfa\x79\x80\x05\x42\x1e\x6f\xcd\xd2\x22\x56\xc2\x0c\x8a\x35\x5b\x90\x8d\x7e\xbd\xbc\x3f\xa4\x2a\xa5\x24\xc3\x8b\xdc\x03\x82\xf6\x4d\xfd\x5e\x4d\x1e\x44\x15\x31\x72\xd8\x20\xc9\x60\x63\x6e\x64\xb9\x03\xf3\xb8\x33\x78\xa8\x07\xe7\xe2\x93\xfb\x1b\x85\x9c\x6c\xb8\x5d\xf6\xfb\x05\x95\x66\x47\xd8\xad\x08\x5c\x56\xa7\x69\x75\x3c\x55\xd0\xe3\xd5\xb4\xdf\xb4\xf3\x63\xdb\xd5\x7b\x68\xca\xea\xea\x0e\x4b\x59\xce\x6a\x3a\xdd\x25\x3a\xa1\x42\x25\x14\x1d\x6a\x6e\x8f\xa5\xb7\x2f\x2e\x3f\x9f\x29\x24\x22\x95\x7e\xbe\x4a\x55\x8e\xdc\xea\xd4\x58\x85\x46\x3d\x69\x44\x4e\x98\x15\x5d\x1f\xc8\x62\xe9\x60\xd9\x7e\xef\x39\x77\x19\x53\x5b\x28\xb4\x69\x7a\x1b\x17\x7c\x60\xc8\x4b\x3c\x7c\x19\x3f\xbf\xcc\x7d\x31\x79\x65\x2b\x53\x4c\xcc\xba\x22\x23\x2a\x8d\xc0\x0a\xab\x69\xbf\x22\xa1\x6d\x46\x1d\x5f\xb6\xbd\xc9\xfd\x5f\x58\x01\x46\x04\x6d\xf9\xc9\xd6\x9a\x45\x91\x2d\x62\xaf\xd4\x6d\xeb\x1b\x36\xbe\x69\x16\x09\xc3\xe3\x70\xa4\x95\xdd\xc7\xb4\x5d\xe7\x18\x56\xb6\x72\x0f\xc8\x3e\x3e\x36\x36\xb2\xde\x3c\x76\x02\xae\xc3\x14\xf8\xc5\xaf\x95\xf5\xb6\xac\x26\x3a\x57\x12\x4e\xe8\x00\x36\xf5\xbd\x3c\xcc\x2a\x83\xc7\x15\x41\xc5\xc7\x4f\xc0\x64\x26\x86\x21\x4d\xec\xb3\x3d\x47\x7b\x85\xe4\x47\xc6\x14\xa1\xf3\xdf\xa0\x31\xa5\x76\xbe\xe4\x44\x50\xdd\x75\xe5\xbd\x6d\x3e\xae\xa2\x39\x27\x19\xeb\xbb\xe5\x18\xa1\xfe\x77\x7f\x56\x7f\x10\xbb\xc4\xf8\x29\x05\xa3\x8a\xde\x63\x45\x85\x28\x17\x03\x86\x99\x48\x0d\x16\x2b\xec\xb7\x06\x65\xaf\x06\xd0\x9c\x4c\xe4\x1c\xcd\xea\xf5\xf3\xd3\xd3\xdd\x9f\xdb\x9b\xc7\xd5\x76\xb5\x58\x2f\x56\xdf\x17\xa1\x47\xa1\xe5\x10\xd5\x80\xe9\xc4\xc7\x8b\x4a\x4b\x2c\x8b\x23\x46\xf5\x43\x55\xd9\x6d\xf7\xc7\x5d\x57\xd6\xef\xd5\xa7\x8c\x35\x2c\x8b\x93\x58\x45\xb4\xcf\x37\x54\x1d\xe6\x96\xba\x6f\x4f\x89\xe6\xe1\x3b\x66\x48\xfd\x23\xc5\x4a\xa0\xc1\x40\x6e\xec\x75\xad\x8f\xbd\x99\x59\x3f\xd5\xcd\x72\x72\xfe\x65\x09\x4b\x51\xb8\xa3\x7d\xad\xdf\x57\xc8\x9a\x41\x21\x32\xaf\x28\xc3\x42\x47\x1e\x41\x12\x4c\x8d\x20\x6e\x3a\x62\xf5\xf1\x5d\x05\xc9\x35\xb5\xc7\x43\x7f\xc3\x36\xc8\x27\x4f\xbe\x5f\x02\x14\xb2\xea\xb7\x7c\xd2\xc7\xf2\x2f\x90\x72\x22\x30\x51\x95\x22\x1e\x94\x91\x3e\x1a\xcb\xd2\x44\xe1\xe6\x49\x7c\xdd\xc3\x33\xdb\xdb\x06\x59\xc6\x34\x1a\x29\x57\xcf\xab\x87\xd9\xd5\xdd\x62\xfb\xfc\xb4\xdd\x78\x3b\x25\xcb\x20\x17\xc4\xc2\x9f\xf2\x45\xa5\x6b\x33\x95\x9c\x63\x59\x66\x35\xce\xae\xa7\xba\xa9\xd6\x1a\xaa\x91\x47\x95\xe5\x4c\x23\x48\x95\xbc\x47\xb2\x16\xb1\xfe\xe8\xf2\x1a\x2b\x64\x9e\xc2\x20\xfa\xb5\xa1\x74\xba\x4f\xa2\x0e\xe6\x7e\xa1\x53\x20\x78\x78\x65\xcb\x66\x4f\x06\xc2\xf4\xe5\x0a\x5b\xa0\x45\x77\x90\x4d\x0b\x7a\xde\x80\x29\x4f\x5c\x69\xae\x8f\x64\x16\xd3\x83\x57\xb3\xdb\xed\x66\x35\x7b\x58\xdf\x2c\x56\xdb\x9b\x45\x98\xb7\x52\x68\xf4\x77\x6e\x36\x6b\x9f\x68\xca\x14\x33\xa8\x3b\x77\x25\xf5\x5c\x36\x32\xfc\x39\x51\x38\x0b\x09\x45\x81\x36\x64\x59\xbd\xf8\xd8\xe0\xe5\x2d\x4e\xa5\xa6\x50\xc4\x89\x2a\x3f\xe6\xf7\xf3\xcd\x65\x24\x68\x98\x0c\x4a\x32\x2c\xab\x75\x36\xf8\xd5\xc7\x54\x68\xfb\xf2\xc0\x6a\xe7\xb5\x6d\xa0\xed\xee\x4a\xf5\x5b\xf8\xb3\x41\xc1\x9c\xeb\x87\xfb\xb9\xff\x9b\x61\x39\x5a\x53\x81\x3f\x69\xb7\xc3\xbc\x17\x5a\x26\x93\xc1\x83\x98\xec\x2b\x0c\x7f\x7f\x7d\x1a\x67\x96\x17\xc6\xc5\x79\x6e\xeb\x9d\xe9\xcf\x88\x35\x34\x81\x5f\x95\x65\x56\x68\x8c\x7a\xcf\x9e\xe7\x18\x12\xfc\xf1\x6d\xf1\xb0\x7d\x5a\xac\xe6\x8b\x87\xcd\xec\x76\xb1\xbd\x7b\xbc\x5d\xce\x89\xf3\x60\x1d\xae\x49\x2d\xa6\x56\xa1\xd5\xf2\x00\xfd\x99\x16\x56\x47\x1e\xa5\x92\x3b\x7b\xfe\xb9\xf2\x11\xfe\x7e\x87\x68\x43\x8f\x2c\x26\xa8\xb2\x0f\x7a\x8f\xe8\x25\xfb\x76\x10\xc9\x30\xa4\xec\xe5\x3b\x07\xb9\xec\x9c\xa5\x29\x42\x8e\x36\xab\xd9\xf5\x62\xbb\x5a\xfc\x98\xad\x7c\xda\x3a\x67\x4a\xe4\xb9\x2f\x22\xeb\xe4\xee\xc7\x67\xc8\xc5\xf1\x11\x3b\xf0\x95\x73\x66\x45\x41\x7b\x33\x72\xfa\xd3\xe1\x3e\x49\x42\xe6\xdc\x18\xa1\x4e\xcc\xba\x74\x8e\xc5\xa4\xde\x3d\xe9\x2a\xe2\x84\xeb\x49\xd7\x4b\x75\xe7\x2c\x17\x89\xc1\xca\x5a\xb2\x41\xfe\x86\xf2\x04\xcb\x45\x2e\x59\xe2\x98\xc3\x6f\x48\x1d\xe3\xda\xfb\x15\xa7\x98\x52\x2e\x72\x0b\xee\x5c\x5f\xfc\x3a\x60\x22\x9c\xc2\x8d\x93\x49\x3c\xaa\xce\x9e\x04\x37\xf2\x24\x92\xa1\xc2\x6e\xa0\x9d\xe7\x5a\xd3\x88\xb1\x80\x30\x3f\x3b\x44\xc7\x43\x92\xb2\x0c\x89\x5b\x7b\xff\xc8\xe3\xd5\x37\x9b\x7b\xbc\xeb\xd2\xa4\xe1\x96\x05\x95\x83\x2c\x4d\xbd\x3b\x15\xb6\xb1\x3c\x95\x29\xe6\x47\xfd\xc9\x46\xae\x77\x77\x3a\xdb\xa6\x21\x91\x4b\xe0\x8a\x3c\x55\x04\xae\xe8\x0f\xf3\xf2\x17\xec\x4e\x6a\x65\x63\x6a\xa7\x7e\x75\xa6\x99\x3d\xc9\x9f\x9e\x1b\x06\x79\x6a\xb2\x0c\x4e\x74\xae\x97\x11\xc4\x79\x16\x01\x26\x3c\x3c\x24\xe7\xa6\xac\xe4\xae\xfc\x6f\x38\x3e\xf2\x2c\x4d\x48\x40\x17\xda\x9f\x57\xb0\x0b\xd9\x5b\xdf\x9c\xd1\x21\xfd\x70\xfc\xb7\x24\xb8\xb2\xa7\x43\x66\x79\x1e\x31\xee\x25\x03\x36\xf7\x4f\x63\xd5\xee\xbe\x59\xa1\xe1\x86\xbc\xf9\xe7\x2c\x62\x2c\x2f\x44\x4c\x90\x09\xd8\xe1\x69\x3b\x7f\x95\xfd\x23\xba\xd9\x1c\xe6\x5b\x91\x00\xb2\xb4\x6e\xb7\x68\x72\x7f\x65\xbf\xe5\x45\x6e\x31\x7a\x41\x95\xc0\xf3\xc7\x87\xcd\xea\xf1\xee\x6e\xb1\xda\x2e\x1f\x36\x8b\xd5\xcd\xcc\xd7\x02\xb3\x5c\xaa\x04\x6b\x6b\x0e\x80\x38\xd4\xbb\xb2\x9d\x0e\x9d\x34\xa9\x55\x5e\x8d\xbe\xf7\x4b\xfc\xa5\x2a\x53\x38\x26\xeb\xc3\xae\x0c\xc5\x72\xed\x6c\x5f\x57\x2f\xad\x9b\x11\x93\xf5\xa8\x64\x81\x01\xaf\x57\x54\xcf\xc4\x28\x2c\x41\xae\x5d\x4d\xb4\x92\x13\xc9\x5a\x96\x6b\xe5\xde\xba\x9f\x58\x9b\x7a\x8d\xd3\x68\x6c\x34\xe4\x26\x12\x7a\x28\xca\xf0\x19\xde\x6b\x32\x48\x86\x47\xc8\x56\x84\x1b\x7a\xd8\xad\x7c\x63\x6c\x94\x8b\xb4\xd1\x8a\xbb\x00\x7a\xcf\x4d\x22\xb1\x42\x8e\xbe\xc5\x1a\x3e\x0b\xa0\xe5\xc6\x24\x0c\xa1\x9a\x8b\xd5\xfa\xf1\x61\x76\xb7\xbd\x59\xae\xd6\x9b\xed\xb7\xc7\xe7\xd5\x76\x3e\x7b\x0a\x3f\x6a\xa9\x62\xa3\xac\x9c\xc0\x47\x6f\x0b\xf4\x07\xea\x17\x9e\x55\x0e\x8c\x07\x19\x45\xf9\xcb\x09\xa7\x9c\x18\xea\x27\x9d\x35\xd5\x58\xa2\x1c\xd0\x45\x38\xf4\x70\xa1\x16\x91\xcc\x0a\x27\x66\x72\x90\x15\x15\x22\x39\x20\x63\xe8\xa1\x31\x5b\x4c\xf5\xb2\x67\x39\xe5\xa9\xf5\x5a\x44\x2a\x36\xc4\x72\xfe\xde\x1f\x4f\x04\xb5\x41\xe6\x12\xd7\x81\xc5\x06\x43\x4c\xeb\x4e\x76\xa5\x5e\x74\xaf\x27\x9d\xab\x23\x41\x6f\xc6\x75\x15\x05\xd3\x1c\x55\x63\xe6\x4f\xde\x66\x29\x78\x4e\x8e\x5a\x0b\xbb\xdd\xb8\xa2\xda\x77\x80\x02\x33\x4e\xb6\x6e\x2c\x4c\x43\xf5\x85\x60\x0a\x2b\xe9\xee\x66\x37\x21\x4f\x5d\x08\x29\x6c\x16\x8c\xdd\xab\x21\x1b\xcf\x68\xbd\x14\x31\x8b\x11\x07\x42\x95\x74\x65\x85\x47\x02\x6c\x7d\xdd\xd3\x6f\x93\xde\x9a\x63\x2e\x7a\x7b\x42\x03\xcf\x76\x9d\x6c\x68\xa9\x79\xba\x04\x56\x24\x3c\x46\xeb\x65\xa6\xeb\x46\x96\x46\xde\xd7\x55\xa9\xe5\x0f\x59\x75\xed\xa6\xfe\xbd\xaa\xdf\x37\xaf\xf0\x00\xef\xff\x3c\x42\x8b\xa7\xcf\xe8\x33\x26\x45\x91\x50\x21\x3e\x02\x2b\x07\xf8\xda\xc1\xe1\x5e\x24\x36\xc2\x2a\xb1\x76\x57\x6a\xe0\x17\x6a\x66\x4e\xe3\x97\x66\xa4\xd0\xfc\x24\xbb\xa6\xae\x36\xaf\x0d\x9c\x78\x4a\xc2\x97\xcc\x8a\x1c\x41\xfd\xd5\x71\xbf\xaa\x77\x61\x43\x2c\xb2\x82\x60\x90\xad\xdb\xfd\x67\x0d\xc8\x11\x2f\xcd\x97\x41\xb6\x20\xa9\xc1\x8a\x4c\x29\xe4\xa2\x31\x20\xcd\xae\xac\x20\x14\x19\xb2\xa2\x60\x92\x13\x7f\x87\x13\xa3\x20\x28\x5a\x03\xf8\xda\xab\xc0\xf5\xca\x8a\x82\x13\x87\x96\x87\xed\xb8\xf3\x73\x14\x32\xb8\x18\x1c\xf0\xd7\xdb\x04\xa7\x5f\xd3\x9b\x53\x23\xe4\x58\x21\x93\x9c\x44\x25\xdc\x94\x71\x16\xc8\xb9\x36\x27\x2b\xa4\xe2\xe8\x3b\x5f\x9d\x28\x00\x59\x21\x75\x82\x08\xcb\x0a\xde\x5d\x55\xda\xa9\x16\x76\x72\xbd\x02\x41\x35\x27\x9d\xee\xd7\xe0\xd3\x51\xfd\x0e\x1f\xfd\xe6\xda\x5c\x2e\x8c\x28\x14\x24\x38\x4b\x1d\xf6\x72\x5e\x37\x9f\x32\x10\x4f\xbe\xbd\x8e\x78\x64\x02\x20\x80\xf6\x9b\x81\xc0\xb2\xef\x95\xe5\x88\x6b\x1c\xa6\xfc\x30\x99\xec\xdb\x2d\x58\xc2\x42\x1c\xea\x7e\xc3\xe8\xdf\x89\xf4\xb9\x2e\x6f\x73\x85\xe1\x0a\x41\xfa\x8b\xc7\xf5\x58\x49\x9c\x15\x26\x23\x69\x98\xa7\xa6\x6e\x0f\xc1\xa2\x2d\x8c\xc9\x10\x22\xb7\x6b\x87\x24\x6b\xac\x00\xa1\x0b\xaf\xc1\x54\xc9\x43\xfb\x5a\x77\x5e\x04\x71\xfc\x93\x90\x11\x9d\x2f\x56\xaa\xde\x4f\x2b\x6a\xfb\x76\x02\xa2\xba\x65\x75\x75\xb6\xcd\x80\xca\xb0\x8e\x73\xf3\xbb\x0b\xd2\x23\xdf\xdc\x97\x3b\x2e\x00\x27\xcc\xc6\x8b\x2b\xa4\x0a\x4f\x6d\x75\x2c\xbc\x80\xc1\xb1\x32\x4b\x92\x3b\x1f\x0c\x83\x15\x3c\x26\x50\xc8\xbf\x41\x0f\x4c\x32\xdf\xac\x18\x02\x39\xbc\xaf\x13\x2a\xef\x59\x61\x75\x8a\x2b\xf5\xa5\xae\x96\xcb\xd1\x58\x59\x48\xd1\x65\x0b\x8c\x6d\x54\x90\xf6\xc9\xd6\x67\xc1\x62\x70\xf7\x5b\xdd\xaf\xc7\x97\xaf\xfd\x34\x19\x45\x84\x62\x3b\x56\x9e\x2f\xb0\xb7\x3e\xa0\x9a\xd2\xdc\x32\x19\xc9\x3c\x71\x2a\x0b\x97\x52\xe5\x92\x89\x1c\xa1\xd8\xae\x3a\xb3\x95\xc3\xa8\xa0\xe4\x09\x65\xf6\x10\x0d\x52\xc1\xc7\xd5\xa9\x54\x43\x0a\x03\x08\x5d\xf3\x4f\xb0\xdd\x3b\x31\xa5\xf1\x03\x24\x2c\xc1\xe2\x5d\x34\x77\x43\x50\x45\x26\x59\x84\x77\xf6\xc6\xcf\x0a\xf4\x87\xde\x7d\xae\x73\x76\x79\x45\xc9\xc4\x6a\x44\x61\xe3\x0a\xdd\xd4\xcb\x11\x27\x23\x93\xa9\xc8\x30\x74\x43\x58\x1d\x5a\x24\x5f\x18\x04\x32\x05\x83\xf3\xe0\x71\xb5\xbc\x5d\x3e\x6c\x17\x9b\x6f\xdb\xab\xd5\x66\x8b\xe0\x13\xff\xe4\x85\xb4\x54\xd5\xd9\xef\x8d\xc3\xb4\xae\x2c\x0c\x39\x08\x77\xab\xf9\x1c\x37\xa3\x2f\x66\xab\x94\x20\xd9\x90\x76\x49\x5d\x8c\xa6\x49\x25\x52\xe5\x7c\xa0\xde\xe8\x1b\x12\x4a\xba\x1e\x1a\x18\x26\x49\x90\xe3\x6f\x31\x5f\xde\xcf\xee\xbc\xdf\x2b\x8d\x20\xad\x35\xac\x4d\x0c\x42\x0e\x4c\x1a\x48\xd0\xa6\xff\x0e\x3b\x68\x07\x4e\x8a\x84\x24\x16\xa7\xa3\x7a\x23\x7f\x9e\x83\x44\x24\x64\x1c\xc1\x61\x24\x33\x03\x87\x0e\x4c\x6f\x6b\x8c\x26\x0e\xe4\x24\xf2\x8d\x83\xb4\x92\xd6\xee\xa6\x77\xb1\x9a\xce\x41\xcc\xe6\x51\x21\x8a\xcb\x7d\xef\xce\xcd\xd0\x51\xd2\xea\xef\xe6\x93\x2e\xce\x18\x15\xf1\x08\x51\x9c\x1b\xb9\xfb\xb9\xa9\x7b\xbf\xb2\xe9\x2e\x62\xce\x54\x94\x51\x39\xac\x01\xe5\x39\x1c\x3e\x89\xa2\xb8\x0b\x18\x8f\x89\xf5\x41\xd7\x9f\x52\xbb\xfd\xdf\x3d\x2c\x17\xb1\x74\x0c\x21\x5f\xf0\xd3\x32\xc5\x55\x84\x11\x6c\x1c\xee\x6d\x48\x6c\x29\x6e\x52\x8f\x10\xec\x37\x08\x24\x14\x75\x4d\x02\x24\xc2\x31\x64\xfb\x51\xe9\x6b\x50\xe5\x27\x06\xb8\x12\x36\x70\xe3\xac\xa4\x86\x45\x65\x88\xdd\x37\x34\x1b\x34\x8b\xf7\x75\x3f\x84\x9b\x72\x0f\x8f\xf6\x72\x10\x4b\xc5\xa9\x72\x7c\x02\x68\x44\x01\x11\xb1\xcf\xfb\x63\x7f\xe8\xae\xa9\xd8\x24\x71\x7e\x3a\x1c\x30\xb5\x3d\x71\xeb\x55\x12\x69\xcc\x71\x03\x86\x32\x43\x4c\xc9\xb7\xc6\x8c\x8a\x53\x71\x8d\x06\xfa\xc6\x01\x9d\x3f\x53\x89\x22\xca\x2f\x44\x48\xe0\xe4\x8d\x43\x93\xce\xb2\x6c\x78\x02\xc3\x0f\xd9\x62\xd4\xc8\x84\x2e\x26\x43\x0f\xee\xd0\xc0\x16\x99\x5d\x26\x0e\x9b\x4a\x05\x43\x55\x0f\x34\xa1\x02\x17\xdb\xc0\x68\x54\x69\x96\x4a\x57\x82\x27\x16\x95\x39\xdd\x3b\xd5\x80\xc1\xe1\xf7\xb2\x7a\xaa\xbb\xb3\x57\xcf\x62\x11\xfb\x0c\xfd\xaf\xb2\x2d\xfb\xcf\x3a\x12\x89\x3f\x0b\x8b\x4c\x83\x22\x2a\x4b\x58\xe6\xe7\x05\xbc\x48\x3d\xf1\xce\x54\x2e\x13\x65\x03\x1c\x07\xf1\x8f\xf7\x65\x35\x20\x3b\xed\xcd\x7c\xe0\xb1\x2f\x6e\x97\x03\xaa\x7f\xa6\xa4\x8a\x0a\xa7\x63\xbb\xf8\xd5\x35\xf2\x9c\x25\xab\xef\x13\xa3\x81\xb7\x97\xd5\x91\x84\xcf\x3e\x99\x7e\x4a\x26\x58\x4a\x7b\x5b\xef\x68\xe2\xb5\xe4\x96\x84\x07\x51\x32\xb5\xc5\xa9\x20\x6b\x64\xbe\x2b\xa5\x53\x0c\xc1\x06\x88\x14\xea\xe3\x99\x13\xb7\x15\x53\x5a\x8a\x81\xe8\xd2\xbd\xac\x3e\x30\x0a\x3f\xd5\x37\xec\x3b\x66\xf8\xbd\x4c\x8d\x16\xee\xf8\x31\xb5\x4a\x29\xa0\x3f\x22\xe6\xad\xcf\x1d\x6a\xac\x16\x9e\x64\x81\x47\x8f\x6c\x62\xa2\xc1\x7d\x81\xae\xb7\x30\x9f\x42\x75\x8f\x32\x49\x91\x51\x18\xc3\x5d\x2f\xb6\x5b\xdf\x06\x2c\xf5\x71\xa1\x7b\xd9\xfc\x0c\xc6\x8f\x82\x98\x63\x70\xbb\x3a\xee\x43\x74\x24\x8c\x5d\xef\x38\xa3\xab\xee\x1d\xc5\x7f\x85\xf2\x2a\x65\x55\x81\x56\x23\xb1\x82\x57\x2f\x3b\x98\x9f\x0c\x74\x1d\x25\xb9\x18\xc9\x42\xae\x2f\x09\x71\x5c\xfc\xa4\x9a\x45\x1a\xa7\x4e\x59\xd9\x7a\x1c\x8b\xf1\x1d\x52\x83\x95\x17\x63\x00\xcb\xff\xd3\x16\xaa\x39\x23\x59\xeb\xa7\xd5\xe3\xd5\xec\x6a\x79\xb7\xdc\xfc\xb9\xbd\x5e\x7e\x5f\xae\x1f\x3d\x74\x54\x73\x2e\xa3\xc4\xf3\x69\xbf\x4f\xc2\x6a\xa7\x3b\x89\x08\x34\xc1\x37\x91\x33\x62\x68\x68\x68\x91\x52\xbd\x2b\x46\x34\x51\x9e\xe1\xc2\x61\xae\x85\x31\xc8\x32\x67\x8f\xfa\xe7\x89\x7e\x8c\xe9\x98\xa9\x34\x0f\xac\xa4\x2d\x54\xed\xb1\x5d\x1d\x07\xd4\x91\xff\x3b\xfd\x3f\xbe\x6b\x4a\x04\xa6\x7b\x68\x65\xeb\x6c\xef\xef\x14\x79\xf5\x3d\x4c\x8a\xe9\x85\xeb\xc7\xdb\xed\x84\xe0\x92\xe9\x18\xb4\x72\x92\x52\x73\x79\x38\x95\x76\xea\x44\x48\x8c\x71\x3f\x07\x44\x09\x2e\xdd\x6b\xd9\x49\x36\xad\x94\xf3\x97\x24\x85\x60\xa7\x0a\x37\xaa\x7a\x19\xbf\x70\x62\x22\xa4\xee\xec\x88\xb5\xe1\x0d\x68\x05\xfb\x1f\x4d\x59\x81\xea\x55\xd7\xcb\xdb\xe5\x66\x76\x37\x9f\xad\xbf\x85\x26\x09\x18\x55\x5e\x23\xd7\xf2\xae\xd4\x72\xcc\xaf\x35\xd0\x5c\x18\x19\x59\xfe\x72\x9d\x20\x96\xa5\x39\x22\x83\xba\xa3\x98\x9b\x6c\x42\x3a\x4b\x23\x4c\x36\xda\xf2\x97\x4b\xbf\x4c\x45\x00\x43\xc7\x1c\xc3\x1a\x73\x59\x99\x8f\x81\x0b\xac\x8b\x98\x24\xb2\x77\xb2\xed\xf0\xdd\xb6\x32\xfb\x26\xdb\xd7\xad\xfb\xa1\xd0\x4f\x6b\xac\x1a\xed\xbb\xdc\x07\x73\x4b\xcb\x82\x76\xc1\x17\xa8\x22\xf7\x31\x07\xb4\x84\x4c\x6b\x99\x4b\x47\xd8\x85\x84\xcf\x67\xc6\x98\x06\x91\x99\x7e\xdd\x83\xd4\xaf\xfd\x57\x73\x92\xf1\xbe\xb5\x48\x10\xd9\xb1\x59\xde\x23\x64\x7a\xf9\x78\xbd\x5d\x3e\x6c\xd7\x8b\x79\xe8\x21\x73\x12\x10\x9b\xdf\xad\x2e\x63\x5a\xfe\xe2\x5f\x77\x1f\x9b\x28\x2f\xb9\xf8\x03\xba\x57\xbf\x01\x5e\x5e\x07\x56\xb1\x88\x56\xd2\x5e\x22\xe6\x90\x54\x08\xc7\xb1\x24\x6d\x2d\x09\xff\x74\x08\x48\xed\xda\x87\xba\x5b\x43\xb7\x3e\x22\x4e\xd2\x3d\xbf\x89\xb8\xc4\xb8\xe8\xfd\x09\xbb\x78\x81\xcb\x92\x99\x28\x57\xd6\x8d\xe4\xe3\x01\x11\x73\xb8\x61\x9d\xa2\xe1\x86\x25\x96\x39\x20\xef\x9d\xac\xcc\x68\x07\x18\xef\x29\x86\x65\x69\x7e\xb2\xdd\x5d\xbc\x1b\x15\xa5\xe5\xe1\x30\x70\x81\x06\x27\xf0\xf0\x87\x72\x19\xa3\x71\x22\x2d\x78\xb7\xec\xfc\x37\x78\x64\x90\x1c\xee\xd0\xd4\xbd\x87\x44\xe4\x9a\x5f\x7f\x04\xc3\x1d\xa9\x79\xff\x6a\x43\xf5\x1d\x66\x38\x57\xb8\x3f\x39\x59\x8a\x69\xcc\xc1\x70\x45\x5a\xfd\xe8\xfa\xb2\x70\x95\xa2\x30\x54\x0b\x27\x04\xf5\xf8\x29\x45\x94\x63\x2c\xa4\x3f\x20\x8e\x3b\xd9\x94\x1d\x12\x77\xb0\xcc\xdf\x42\x24\x81\x22\xea\xb6\x7e\x83\xa6\xf2\x5c\xdf\x93\x47\x17\x32\x47\x8f\xf6\x49\xee\x76\xe5\x71\x7f\x8e\x7b\x1f\x77\x4f\xf2\x5c\xbb\x2d\x7b\x55\xef\xfa\x53\x5b\xbe\x4c\x33\x53\x26\x29\x62\xef\xf7\x3f\xaf\x17\x9b\x33\x6d\x06\x66\x52\x96\x27\xd1\x29\x3d\x8c\x7e\x15\xf1\x49\x3c\xbe\x05\x6b\xd2\xa4\x8c\x50\xf1\x5d\xb9\xc7\xdc\xf4\x8c\x18\x11\x26\xbf\x96\x31\x85\x36\x95\x82\xee\x6a\x77\x1c\x68\xf1\x31\x93\x89\x04\x99\x71\xfe\x79\x2c\xff\x7b\x71\x76\xe6\x31\x55\x93\x0e\x5c\xaa\x91\x3f\x65\xf2\x22\xc7\x08\x84\x2b\x4c\xf0\x48\xf5\xcb\xd3\xa0\x60\x45\xcc\xbd\x69\x66\xeb\xe7\xc6\xc3\x67\x46\xbf\x29\x93\x1c\x73\x27\xae\x5c\x61\xf8\xbc\x32\x83\x54\x78\xb7\xbf\xe9\x5e\xe4\x0b\xac\xce\xea\xe1\x8c\x94\x0c\x31\x01\x28\x4e\x7a\x0d\x16\x25\xcf\x06\x9b\xec\xf8\x15\xa5\x24\x0e\xf9\x40\xe2\x45\x2f\x78\x53\x37\x67\x95\x1a\x46\x71\x61\xb4\x3f\x36\x9e\x9a\x5a\x03\x04\xbc\xa4\x51\x4e\xc5\xee\x66\xf9\x80\x42\x85\x77\xdb\xeb\xd9\x9f\xeb\x53\x2b\x55\x13\x39\x1a\xf5\x13\xda\xf2\xf2\x2a\xd3\x9c\x70\xde\x28\xc0\xde\xbe\x3e\xd5\x65\xd5\x5d\x7d\xe0\x56\x5c\x87\xef\xdf\x6f\x1e\xf1\x28\x73\xe7\x43\x89\xd3\x0a\x63\x7f\x41\xca\xbc\xd0\x1e\xd9\x37\x4b\x3d\x81\x86\x1b\xc8\x48\xb2\x94\x04\x53\x6c\xf9\x6b\x48\xc3\xeb\xfa\x58\x6d\xd0\x3a\xeb\x37\xc0\x01\x29\x10\xd2\xde\xfb\x67\xb3\x16\xbc\xb8\xd9\xd2\xd1\x67\x0d\x39\x74\x19\x44\x3c\xe5\xbe\xea\xa5\x6c\xda\xee\x8c\x0d\x9c\x41\x24\x0c\x52\xa9\x92\xed\x3a\xdc\x8b\xd9\xd7\x6c\x5a\x17\x85\x1e\x3f\x49\xfa\x02\x4f\x1c\xfd\x79\x53\xea\x9f\xcb\xf0\x3d\x81\x17\xb9\xa6\xda\x38\x73\x81\xa5\xf0\xb2\x09\x09\x5c\x6a\xcc\x0a\xc1\x9b\xdc\x3d\xc9\x46\xee\x27\xa8\xe1\xb3\xc7\x9e\x14\xf9\x7b\xa3\x1e\x38\x14\x98\xfd\x47\x1d\x24\x6f\xdd\x82\xe0\x39\xfa\x14\x3b\xb0\x5d\x9a\x4f\x86\x2b\x96\xb4\x9a\x8f\x15\xda\x6b\x75\x63\xca\x6a\x30\x5d\x20\x89\x74\x50\x5d\xbe\xf7\x1f\x0a\xd2\x22\x1a\x85\xcb\xae\xdb\x71\x2d\x63\x18\xb6\xff\x9d\xf8\x67\x4b\x95\x62\x0e\xb0\xda\xbb\x5e\x4e\xcb\x66\xf2\x34\xa9\x8d\xd1\x4c\x47\x86\xbf\x38\x9a\xb4\x66\x12\xf0\x50\x23\xa5\xd7\x7b\xd8\x2b\x68\x10\x91\xf5\xb5\x6a\x31\x83\x5c\x6a\x20\x85\x78\x5d\x1b\xb8\x2a\x77\xbb\xb2\x7a\xb9\x87\x4e\x9a\x81\xe8\xa7\xeb\x5b\x24\xb1\xc9\x07\xb9\xb7\x00\xfd\x3d\x63\x45\x80\xa2\x48\x3c\x47\xe8\x8c\xca\x51\x70\x97\x1b\xf0\x28\x85\x73\x12\x0a\x99\x60\x61\xe2\xf7\xd5\xe2\x71\x8b\x42\x16\x4f\xdf\x66\xeb\xc5\x96\x6f\x17\x0f\xd7\xdb\xde\xa4\xf1\x77\x95\xb1\xc0\x87\xdd\xcc\xd7\xf3\xc1\x3e\x06\x32\xd5\x2a\xd0\xb2\x94\x75\x75\x5f\x56\x41\xce\x83\x81\x34\xc2\xa4\xa3\x8a\xa2\xf6\x66\xba\xab\x83\x04\x4e\xa4\xb6\x75\x13\xc8\x46\xfb\xbf\xa6\xb1\xa4\xea\x06\xc4\xb6\xfa\xbf\xab\x08\x0c\x41\x04\xde\x97\x24\x00\x49\xf5\x81\x98\x33\xec\x0d\x83\x8b\x85\xb3\x9f\xcd\xf5\x7f\x0c\xa2\x05\xa0\x20\x4e\xfa\x89\x3a\x7f\xad\xeb\x16\xae\xfc\x2f\x6a\x6b\x31\xc9\x7b\x25\xdb\xae\x1e\xa3\xaa\xc0\x14\x05\x9e\x5b\x65\xbb\x08\x0c\x15\x10\x80\x0a\x00\x40\xaa\xaf\x65\xd5\x1e\x1b\x20\x91\xe7\xd1\xac\xf0\x41\x62\xb0\x45\x8e\x24\x62\xaf\xb2\x7d\x5d\x83\x6e\x82\x77\x09\xb6\x90\xf8\xf3\x87\x06\x4a\x7d\x9e\xc3\xf4\xbd\x54\x96\xba\x62\xbf\x27\xf9\xe1\x25\x34\x98\x8d\x12\x29\xfc\x6c\xe8\xba\x33\x35\x35\xdf\x4b\xf1\xc2\x0b\x26\xd2\xfb\x9d\x26\x49\xbf\x56\xd1\x7b\x87\xee\xf5\xa6\x6e\x7e\x87\x49\x24\xc3\xf2\x88\xf9\xc2\xd0\x59\xd3\xbd\xd7\xcd\xcf\xfe\x48\x9c\x74\x12\x22\x41\xae\x9a\x85\xd7\x4a\xed\xff\x54\x00\x55\x2b\xa1\xfe\x58\xf8\xb3\x04\x41\x0a\x84\x6f\x72\x6a\xe3\xba\x2e\x71\x11\x61\xcc\xd9\x80\x39\xea\xce\x73\x22\x5e\xdc\xc6\x6c\x0c\x1c\x91\x79\x8f\xba\x93\xc3\xa8\x9a\x4d\x39\xe9\xab\x95\x2d\xc5\xfd\x08\x12\xb7\x5d\x9f\x65\x41\x6d\x6a\x0a\xf4\x40\xde\x41\x4d\x1e\x24\x13\x1c\xe5\x6a\xae\x1e\x1f\x9e\xd7\x5b\xc4\x33\xac\x3d\xdc\xf2\x3a\x74\x4a\x89\x62\x11\x21\x16\xc4\x31\x36\xf9\x81\x3c\xb3\xa8\xf8\x74\x55\x76\xf7\xa5\x2f\x2e\xb3\x45\x22\x30\x13\x84\xe4\xe5\x2b\x39\xa5\xe1\xb3\x92\x65\x71\xec\xf2\xc8\x87\x13\xb3\x37\xb3\xb2\x88\x3c\x0a\xdf\x91\x8a\x3e\xc8\xe9\x89\x64\x95\x90\xc8\xa1\xb1\x2f\xab\x45\x28\xed\xb0\x2a\xe1\xac\x18\x71\x9c\x8f\xc8\xb7\x8e\x53\xfa\x1f\x3f\x7f\xad\xb2\x1c\xc3\xa0\x67\x04\xa2\xeb\xab\xcd\xe4\x97\x75\x6c\xf0\xac\x27\xd3\x7e\x7e\xec\x6a\xeb\xc2\x99\xfe\x66\xa6\x48\x59\x1c\xb8\xc5\xae\xcf\xb6\x43\x0b\x31\x25\x4d\x06\xe4\xc7\xbe\x9e\xd4\xfb\x05\xe2\x3c\x34\xc7\xd8\xff\xb9\x94\x24\xb5\x20\x89\x34\xa8\x85\x0e\x99\x2c\x90\xbf\x23\x1b\x19\x0a\x16\x34\xfd\x62\x55\x1b\x18\x66\x24\xac\x15\x26\x0e\xfe\x37\x7d\xdd\xfb\xb2\x3a\x11\x8a\x58\x1b\xcb\x34\x3b\xc1\xbc\x7e\x94\xdd\xeb\x2b\xec\xa6\xc2\xf6\x83\xf5\xd6\xcf\x2a\x07\x99\xb8\x92\xd5\xcf\xb3\xd9\x62\x0d\xe0\x74\xbc\x92\x6d\xa9\xaf\xe4\x6e\x77\xe2\x2d\xbb\x10\xed\xe2\x51\x14\x31\x8c\x56\xdc\x43\x75\x8c\x1c\xdf\x22\x8f\x58\x2a\x11\x2d\xea\x88\x13\x71\x16\x3c\x41\xf3\x50\x77\x81\x47\x70\x34\xe8\x3c\x62\x46\x46\x2e\xe1\xeb\x99\x2b\xff\x6e\xe8\x7d\xf8\x02\x3c\xe2\x11\x47\x5d\x9d\xe3\x09\x01\xc8\x23\xce\x08\x83\xfb\xcf\xfe\x9d\x51\xd3\x30\xb4\xf0\x02\x63\x47\x5d\xbd\x33\x7f\xd6\xc7\x65\xf7\xa3\x3e\xee\xcc\x89\x05\x94\x47\x22\x66\xd2\xc7\xcf\xbd\xbf\xbb\x41\xd2\xd3\xd0\x43\x5a\x9e\x0e\x4c\x83\xe5\xfe\x50\x7b\x51\x0d\x67\x16\xe4\xff\x18\xbf\xae\xd0\xa4\xb6\x8e\x4f\x39\x5a\xf7\x7d\x1b\xf9\x0a\x2f\xd0\xad\x0f\x20\xa7\xdf\x88\x47\xb1\x60\x18\x87\xbf\xff\x40\x97\xe8\xc1\xf3\xe7\xf0\x28\xc9\x18\x46\x11\x29\xfd\xb3\xac\xda\xae\xec\x8e\x27\xc0\xf8\x84\xa4\x6c\x7c\xd7\x34\x21\xbd\xec\xea\x97\x3e\x91\x3a\xf3\x28\xcd\x89\x5f\x5a\x1a\xf3\x5c\x95\xff\x39\xc2\xfa\x40\x94\x44\x93\x33\xf0\xe2\xd9\x37\xfc\x5f\x7f\x3f\x6d\x91\x8b\xe1\x7e\xf9\x40\x2c\xef\x9b\x6f\xdb\xf5\xe3\xcd\xe6\x04\x06\xe2\x51\x0a\x19\x6e\x59\x16\xf4\xeb\x6c\xb7\xeb\x8d\xa7\x15\xb4\xc7\x5d\x77\xf5\xe1\xd3\xd6\xb4\xdb\x8e\x07\x35\x63\x19\xb8\x18\xea\x83\x1a\x28\x5e\xf0\x28\x4b\xd2\x78\xa8\xce\x36\xb9\x30\x8f\x14\xd6\x9e\x3f\xd5\xd5\xcb\x6f\x83\x67\xcd\x05\x47\xdb\x9b\xc2\xe3\xb8\x1f\xf4\xd6\x54\x43\x9e\x68\x27\x7f\x5e\x0e\x7a\xf3\xa8\x60\x51\x8e\x67\x08\xb2\xbe\x7e\x5c\xcb\x21\x87\x1e\x8f\x8a\x8c\xa6\xa3\x3a\xea\x9f\xd0\x2d\x7e\x95\x6d\x37\x56\x19\xee\xbb\x28\xcc\x3e\x9b\x1a\xfc\xfc\x78\x7c\xaf\xfc\xd8\x7f\xf2\xab\x56\xa3\x71\xe6\x79\x48\x9a\x40\xa3\x37\x99\x40\x2a\x16\x18\xaf\xf4\x36\xc5\xbd\x2c\x2f\x96\x7a\xf9\xee\x85\xf0\xb5\xfe\xcb\xea\xad\x2e\xb5\xf3\xfd\x9e\x64\x69\x26\x8f\x6d\x12\x81\x45\xcf\x50\x9d\x4a\xdf\x31\xfd\xc0\x4f\x22\xc3\x7d\xaf\x02\x1d\xfb\xd6\x11\xd0\xb1\xf0\x77\xc0\x99\x7f\x52\xea\xdc\xd4\x4e\x6e\xeb\x9c\x63\xd6\x5f\x63\x60\xa0\x2e\x34\xaf\xdb\x2e\xe4\x49\x79\x64\xa0\x40\x13\xb1\xb7\xf3\x6e\x65\xef\xfd\x7b\xc6\x25\x1e\x41\x42\xa8\xdf\x93\xf9\x78\x89\x74\xbf\xef\x67\xd1\x70\xa3\xb8\x82\x67\xc4\x1c\x4e\x69\x90\x80\xdb\x77\x7d\xec\x0e\xc7\xb0\x2b\x58\x4e\x2a\x96\x78\x7a\x9e\xaa\xe9\xa8\x95\x45\x5c\xa0\x51\xd4\x4f\xfd\xf9\xec\x69\x20\xc1\xca\x59\x94\xd9\x5c\x04\x2a\xab\x9f\x65\xf5\xd2\xdb\x3c\x4f\xf2\x63\x57\x4b\x33\x08\x5b\x73\x16\xe5\x24\x34\x73\x33\x14\xdf\xe7\x8c\xc5\x19\x52\xd8\xbc\x95\xf0\xbe\x06\x5d\x57\xe6\xae\xee\x4e\x7a\x55\x28\x3a\x1d\xfa\x26\x62\xc4\xb6\xba\x86\xae\xdb\x9d\x29\x33\xff\x15\x29\xf3\xd8\x67\xbc\x40\x28\xc8\x19\xd3\xa4\x7a\xed\x8e\x2a\x24\x07\xbc\xfa\xa0\x94\xde\x38\x55\xc3\x19\x4f\x2c\xba\x68\xeb\xc5\xe2\x2e\x0c\x0b\xd7\x9c\xb9\x7a\xf8\xf5\x47\xdb\xc1\xde\x7f\xb6\x4b\xa2\x77\x9c\x09\x96\x14\xfa\xc4\x8a\x76\x8e\xdc\xf8\xc7\xa4\x7f\x21\x95\x57\x9f\x29\x5f\x9e\x9a\x7a\x5f\xe3\x26\x13\xca\xfc\x7d\x3f\x29\x71\xc0\x8c\xfc\xf0\xc0\xaf\x41\xcc\x97\xb3\x98\x91\x0a\xf9\xae\x6e\xdb\x4d\x3d\x7f\xc5\xa0\xda\xe4\xd9\x62\x51\x28\x5a\x26\x6f\xf5\x4f\x08\xc5\x0f\x43\x5f\x8b\xb3\x38\xb3\x38\xb3\x1d\x81\xec\x93\x53\xd8\x0a\xe6\x01\x67\x49\xc4\x31\x69\xf5\xaf\xcd\xb7\xcd\xef\x0f\xb3\xeb\xeb\x55\x68\x11\x16\xe3\x22\x57\x0f\xbf\x0f\x2b\x92\x39\x4b\x94\x76\x6a\xa6\xd5\xa2\xed\x7e\x87\x0f\x7c\xc7\x87\xc9\x8e\xc8\x52\xc1\x91\xa8\xb5\xd4\x35\x56\x68\x04\xc5\x40\xdf\x9e\x4a\xe4\x89\xf9\x75\x90\x95\x91\x5f\x00\x25\x38\x4b\x15\x8f\x02\x52\x74\xfd\x51\x99\xde\x00\xf8\xdb\xd9\xa0\x70\x13\x8b\x0b\xd9\x15\xcc\xf6\xe7\x2b\xfa\x01\xe3\x5f\xb2\x71\x62\x1c\xc0\x1b\xe7\x15\x25\x2e\x5d\x6b\xc6\x98\x15\xa7\xe1\x24\x3e\xf5\xd0\xe8\x12\xed\x6d\xd7\xbf\x4f\x63\xae\x27\xa5\x4f\x9c\x65\x96\x11\x10\xa7\xa6\x40\xff\x6f\xe7\xc6\x1e\x67\x79\xa4\x51\xe0\xfc\x8d\x24\x5d\xe7\x75\x38\x82\x58\xce\x80\x9c\x39\xf2\x2b\xcb\xff\xc2\xad\x6c\x9f\x82\xa6\xc8\xcd\xb1\x32\x28\xe1\x30\xfd\x12\x85\x95\x69\x7a\x9a\xc6\x04\xa3\xfa\x8b\xd5\xe8\x2e\x95\x2c\xf6\x99\xff\xc7\x63\xa7\xeb\xfd\x88\xfc\x95\x33\x29\x01\xeb\xc1\x90\xe9\x72\x68\x15\x31\x09\xd6\x90\x12\x26\x4a\x2a\x84\x3f\xdb\x08\x75\x2f\x8f\x55\xa8\x78\x1a\x9f\x2c\x4c\xc5\x1c\xad\xdd\x13\xb0\x09\xab\x2a\x4d\x29\xcf\x12\x13\xfe\x8a\x94\x20\x12\xce\xd1\x9a\x06\x13\x39\x53\x85\xc8\xbc\x94\x50\x7d\xac\x4c\x00\xc5\x8e\x31\xbc\x93\x8b\x24\xe8\x21\xe2\xeb\x09\x59\x1e\xb1\xee\x23\xbc\xbe\xe6\x19\x56\x67\xcf\x37\xb3\xfb\xd1\x1a\xd1\xc6\x31\x5d\x80\x6d\x42\xd1\x2b\x67\x26\x31\xe0\x29\xd9\xa8\x60\x26\xb4\x18\x9d\x11\x8c\x5d\xee\xaf\xbc\x3a\xe0\x64\x64\x6c\x22\x48\xf4\x97\x98\x5e\x66\xe1\xb6\x36\x8f\x3c\xad\xcd\x2d\x54\xf5\x27\x04\x30\x7d\x3f\x22\x91\x42\x3b\xd4\x7e\x02\x44\xe3\x3c\x8a\x8d\x3f\xd6\xc8\xf5\xc4\x8a\x1e\xac\x1a\xf6\x3d\x34\xe5\x12\x6e\xa1\x5b\xb6\xa8\xda\xe4\x97\x35\x67\x79\xce\x9c\x05\xe5\x8c\x8e\x59\x65\x10\xe1\x83\x33\xf5\xd1\x0e\x94\x06\x39\x67\x52\x81\x75\x34\xe6\x52\xbf\x82\x09\x4c\xc4\xa1\x87\xe2\x89\x83\x92\xaf\x0f\x75\xd5\xd6\x08\xcb\x23\x95\x65\x2a\x65\xfb\x0b\x72\xe9\xfe\x16\x59\xe2\x44\x7a\xe6\x8b\x4d\xec\xbd\xc4\xf3\x54\xe2\xf4\x1f\x7f\xbd\x35\x28\xbb\x8d\x2e\xd4\xaa\xae\xf7\x23\x52\x1f\xce\x79\x92\x60\x2e\xeb\xe6\xdb\xe0\x04\xe5\xdc\x44\xaa\x08\x4e\x22\x12\x77\x5f\x05\xcc\x02\xe7\x22\x26\x01\x4b\xc2\xeb\xbc\xf4\x0e\xf0\xb8\x6e\x66\xf0\x24\xec\xab\xb8\x50\x7f\x2b\x8b\x08\x4e\x97\xc2\xa0\x0a\x42\xdf\x96\xe7\xf8\xee\x13\x62\xcf\xb3\x2a\x19\xce\x13\x26\x10\xa5\xb7\x2b\xbb\x6e\x2e\x0f\xed\x71\x07\xb7\x30\x06\x77\x63\x27\x39\x5c\x14\x77\xb2\x2b\x8f\x63\xee\x45\xce\x93\x98\x79\xdd\x17\x27\x57\x46\x13\xfa\xd3\x12\x34\x77\x5d\x1a\x45\xc2\x67\x48\xa7\x3d\x83\xff\xc9\x79\x2a\x80\x51\xa5\x20\x7d\x7d\xa7\x71\xe9\xdf\x38\x2d\x34\x0a\x24\x3a\x76\xae\x9b\xba\xee\x14\x56\x7b\xad\x3b\xf9\x97\x20\xe9\x70\x0f\x83\x99\x0a\x49\x90\xc8\x79\x5d\xef\x4c\xfd\x5e\x2d\xaa\x30\x2d\xb3\x58\xaa\x50\xd7\x81\xc9\x6f\xb3\x6c\x89\x17\x60\xbc\x6a\x79\xa6\x18\x52\xbd\xd3\x9e\xff\x63\xb1\xb8\x6c\x22\xf3\x42\x2a\x75\x82\x33\x5d\x1d\x9b\x41\x90\x8b\x73\x19\x29\xe1\x4a\xd4\xae\xe5\xc7\xc4\xc0\xe4\x32\x29\xb0\xbe\x97\x9c\x36\x5c\x68\xcf\x81\x7a\x75\x57\x56\x30\xed\x2f\xe9\x5b\xf7\xe6\xe1\xf5\x7c\x3e\xcc\x88\xf5\x8d\x80\xa6\xdf\x76\x0f\x7b\x7d\xf8\x5a\x9b\x9b\x73\x15\xe9\x22\x88\xb8\x54\xc7\xf6\xd1\x5a\x7f\x23\xc5\x13\x2a\xcd\x21\xb2\x61\x02\xa5\x9c\xd5\xfe\x5d\x1e\x0d\x95\xe6\x82\xd8\x77\x76\xbf\x7f\x68\x52\x0f\x00\xe3\xe9\x28\x27\x43\xac\x23\xeb\xc8\x9e\x08\x2d\xf6\xcb\xa1\xf9\x6e\xea\xe6\x7e\xfe\x63\x32\x85\x35\x8b\x7c\xba\x64\x00\x3c\x6c\x3f\x2f\xb4\x3b\x7d\x04\xed\xb4\x37\xcb\x76\xd9\xc1\x7e\x4d\xfa\xe7\xbf\x85\x46\x89\x2a\x02\xeb\xcd\xe2\x42\x82\x8f\x73\x9d\x31\xb4\xb4\xac\x2b\x9e\x1a\x4a\x9f\xb3\xf4\x22\x05\x31\xe7\x3a\xb7\x98\x86\xbb\x59\x3e\xcc\x1e\xe6\x8b\x81\x87\xcb\x4d\xc4\xb9\x72\x78\x13\x84\x1b\x96\xe1\x58\xe6\x46\x59\x3c\x96\x6d\xdd\xdc\x0d\xe9\xd3\x39\xb7\x3c\xf5\x82\x63\xf7\x65\x35\x62\xa3\xe3\xdc\x5a\x83\x88\xba\xcd\xdd\x03\x05\x0b\x27\x68\x52\x2e\xa2\x28\x47\x22\x82\xb9\x6c\xae\xea\x6a\x1e\xb4\xe5\xb8\x88\x8a\x0c\x8d\x93\x16\x3a\xac\xad\xc6\x2a\x4a\x79\x1e\x82\x19\x8e\x89\x60\x29\x09\xd6\x06\x02\xfb\x8f\x91\x79\x21\x78\xc2\x31\x84\xf8\xfd\xf9\x6e\x3e\x7b\xd8\x3e\xad\x1e\xef\x17\x9b\x6f\x8b\xe7\xf5\xf6\x7e\xf6\xc7\x76\x3e\x5b\xdd\x3e\x86\xae\x79\xee\x80\xf5\xb8\x1a\x7f\xc8\x31\x4f\x3d\x17\x5c\x92\xd4\xda\x8b\x57\xee\x99\x75\x1d\xec\x0f\x67\x0b\x56\x70\x10\xe8\xad\x9d\xcc\x2c\x37\x4c\xe1\x56\x22\xe6\x26\x44\x4c\xbf\xc9\xf6\xf5\x92\xff\x2d\x44\x02\x85\x1b\xea\xd9\xdb\xcb\xad\x6c\x7f\x3b\x6d\xec\xae\x44\x8f\x8b\x98\x2b\x25\xbd\x6c\xdb\xcb\x45\xf7\x51\xc4\x5c\x63\x86\x7d\x80\xf0\xfb\x32\x0e\x23\x62\x25\x75\xe2\x21\x6f\xbe\x6c\x63\x2e\x0f\xcf\x23\x3a\x4e\xd7\x39\x51\xc6\x0b\xe4\xaf\xf0\xe7\x5d\x70\x22\xbc\xf4\xf8\xde\x89\xb2\x9e\x36\x7d\x42\x36\x71\x89\xd0\x84\x8b\x14\x38\x16\xc0\x3d\x6f\xe6\x1b\x3f\x7e\x19\xb3\xc8\x85\xf9\xd2\xc8\xaa\xbb\x2d\xdf\x90\xa8\xf1\xf7\xa3\xa9\x2f\x57\xe4\xe1\x05\x86\x51\x68\x6f\xb1\x47\xad\xed\x66\x32\xd8\x79\x9a\x63\x1e\x61\x27\xdb\xee\xf7\xd3\x69\x20\x72\xa3\xd0\xe2\xda\x13\x45\xd4\xf6\xe0\x70\xbe\xae\xb9\x10\x26\x71\xa6\xce\xef\xa0\xa4\x6a\x51\xe9\x18\x6f\xd2\xff\xdf\xc9\xbb\x17\x3a\x31\x94\x4c\x72\x71\x89\x61\x24\x95\x8b\x02\x12\x9e\x3b\x62\xde\xc7\x0a\xd0\xeb\xf9\x56\x7b\x98\x21\x17\x32\x05\x34\xed\x51\x43\x9d\xb1\x24\x39\x13\x51\xff\xd2\x35\xf6\x77\xc9\x59\x32\x64\xca\xa5\x3d\xf1\x6b\x13\x48\xc8\x5c\x7a\xf2\x4d\x8c\xe3\xdd\x95\xa7\x0a\x2c\xd7\x45\x25\x44\x61\x7c\x75\x95\x0f\x4d\x59\xa1\x52\x8b\x14\xcd\xb0\x2f\x3b\xbf\xaa\x47\x04\x16\x97\x77\x70\xa1\xf2\x0c\x73\x4b\xdd\x9b\x0e\xb7\x92\x39\x6e\x4b\xaf\x65\xf3\x49\xa0\x48\x28\x4d\x6a\x98\x44\x44\x80\x49\xb3\xdf\x06\x81\x7c\x2e\x74\xc2\xb4\x09\xb2\xa0\x98\x7a\xff\x0a\x69\xc4\x85\x96\x11\x9a\x0b\x0a\x7a\xf7\xe5\xa1\x6e\x5a\xb0\x65\x13\x3e\x0a\x70\x2e\x29\xfc\xdd\xf6\xf6\xe7\xd1\x21\x89\x29\x68\x7f\xd9\x8e\x16\x96\xa5\xf8\x1e\xf2\x70\x00\x49\xac\x36\x97\xbe\x94\xe5\x5a\x0d\x95\x2c\x7a\x5f\xff\x52\x7e\xfb\xfc\xa4\x89\xa3\x44\x20\x6a\x6b\x8d\xf5\xec\x9b\x6f\xab\xc5\x62\xbb\xd8\x7c\x1b\xb2\x83\xf2\x38\xca\x0d\x56\xf8\x3f\x2d\x1f\x2e\xbb\xcf\x5f\x5b\x39\x71\x54\x98\x34\xf1\x0c\x6a\x3b\x90\x2f\x80\xe0\x87\xcb\xd6\x59\x1c\x99\x08\xe9\x0f\x2c\x40\xeb\xa3\x16\x55\x78\x14\x9b\xe1\xe4\x31\x65\x7b\x38\x86\xc8\x50\xcc\x98\xd0\xe9\x00\x25\x55\xdb\x72\x77\x59\x6c\x86\xc7\x4c\x88\x64\xa4\xdd\x4d\x71\x8a\x21\x79\x5f\xee\xbb\xc6\x94\xd4\xfd\x73\xa4\xdf\xc8\x63\x96\x10\x98\xef\x7b\xfd\x0b\x76\xd7\x44\xb7\xe6\x03\x6d\xe7\x71\xe4\x98\x25\x0c\x83\x64\x9b\xb2\x7b\x3d\x3d\x72\x6a\x53\x2c\x5b\x6a\xa4\xde\xc1\xb2\xf3\x95\xb5\xe3\x08\x7b\xcc\x63\x97\x93\x91\x16\x86\xe2\xd5\xff\x37\x4b\x39\xe6\x05\x65\xf7\xd5\xf1\x83\x44\x45\x0e\x65\x85\xf9\xfd\xf1\xc8\x8b\xc8\xa2\xe5\xf0\xb4\x3b\xee\x7d\xfa\x8d\xc7\x42\xb3\x2c\x1a\x22\x4c\xf8\xf4\x32\x4d\x33\x1b\x4f\x01\x44\x8c\x78\xff\x2d\x8e\x73\x42\xa6\xb7\x28\x93\xfc\x5c\x11\x26\x8c\xc2\x43\x14\xed\x9b\x9c\x41\x71\x12\x09\xcf\xb7\xf1\x54\xd7\xbb\xe9\x23\x26\x4c\xc6\x0e\xc1\x81\xfb\xcb\x43\xdd\x49\x82\x2a\x0c\xcf\xfb\x38\x49\xf2\x28\x0b\x7c\x94\xe5\x4b\x25\x3b\x30\xc4\x92\x32\x4d\x51\xc4\x49\x16\xa1\x8f\xe9\xf9\x18\x08\xf0\x54\x86\x53\x38\x4e\x54\x81\xdc\x00\xd7\xdf\x97\x4f\xd3\x6b\x4d\x8e\xf3\xee\x01\xde\xbf\x41\x53\x4f\x5a\xd3\x88\x65\x8e\x29\x2a\x30\x55\x8e\xbe\xdd\xf8\xd5\xd3\x28\x8f\x9c\xfb\xf8\x06\xaf\xa5\x1e\xa8\x74\x4e\x96\xdb\x17\xff\xf8\x7b\x09\x92\x9a\x5a\xf7\xd3\xc6\x61\xc9\xfc\xfb\x64\x11\x4b\x5d\x9d\x69\xdd\xc1\x63\xf5\x52\x9f\xce\xb1\x38\xcb\x2c\x5e\x88\x62\xdf\x43\xea\x08\x1e\xe7\x2c\xc7\x24\xef\xb1\xea\xfd\xe6\x13\xae\x9d\xc7\x05\x13\x08\x7c\xee\x8d\xa5\xf5\xf2\xe1\xf6\x6e\xb1\x5d\xae\xd7\xcf\x8b\xeb\xed\xcd\xea\xf1\x7e\xfb\xb8\xf9\xb6\x58\x6d\xe7\xcf\xab\xd5\xe2\x61\xbe\x5c\xac\xc3\x65\xda\x7a\x17\x7e\x2b\x77\xbb\xad\x7e\xed\xfd\xa7\xea\xe5\x34\xf4\x32\xb2\x08\x4a\x55\x64\x23\x88\xf0\xf7\x44\x60\x92\xe4\x11\x17\x4f\xf8\x6b\x5a\x20\x79\xd2\x5e\xfe\xba\x95\x2d\x39\xed\xa1\x0d\xd2\x98\xe0\x77\xbd\x45\x36\x92\x41\xe2\xb1\x4a\xb2\xac\x08\xb8\x7c\xa7\x59\xe2\x66\xf2\x25\x7b\x32\x56\x69\x36\x20\xc5\x0b\xe9\x83\xa9\x17\x34\xf9\xc0\x86\x27\x82\x07\xef\x69\x35\x90\xa0\x5a\x77\xb2\x3b\x5e\x72\x42\x63\x88\x89\xbf\xe2\xe9\xd8\xbc\x84\x17\x85\xcc\x9a\xc2\x27\x7b\x64\x07\xbf\x97\xbb\xdd\xfa\xbd\xec\xf4\x6b\xe8\x61\xac\x57\xb9\x09\xf1\xaf\x40\x26\xfe\xd4\x0c\xc2\xd8\xc3\x1f\xb3\x85\xc4\x83\x04\xed\x25\x52\xe6\xfe\x9c\xbf\x80\xc7\xd6\x16\x5c\xff\xb5\xb8\x5e\xb8\x20\x89\x12\x8e\xd0\x64\xbf\xe7\xfd\xf3\x08\x27\x0e\xdc\x2f\xa6\x73\xc2\x04\x60\xba\x8c\x34\xf3\xc9\xc1\x6b\x7f\xbc\x42\xe5\x62\x42\xe3\x9f\x61\x79\x91\x13\x69\x6a\x89\x36\x0b\x1a\x48\xbf\xf9\x46\xa5\x73\x97\x24\x44\x35\xa8\xd3\x40\x0c\xed\xe5\x84\x59\xea\x86\xb1\x98\xf9\x19\x23\x2e\x4f\x38\x8b\x71\x57\x98\xaf\xfe\x7c\xda\x3c\x5e\x3f\xde\x85\x06\x01\x99\x0c\x0e\x4a\xa0\xa1\x38\x0d\x73\xc2\x0b\x40\xcb\xea\xa6\x44\x7d\xf4\xbf\x9b\x3c\x1e\xbf\xa4\x88\xc8\x87\xc2\x02\x81\xde\xae\x1d\x0b\x4b\xf2\x7e\x85\xc4\xa7\xfa\xba\x39\x34\x5d\xef\xda\x4e\x76\xbf\x44\x40\x8a\x47\xd9\xb5\x6c\x4a\x6f\x3f\x25\x71\x04\xc8\x80\xb9\x3d\x56\xb6\xde\xed\xea\xf7\xcb\x47\x75\x92\xa4\x1c\xeb\x13\xa1\x32\xd7\xc7\x4e\xbf\x7a\xa2\xde\xcb\x4f\x9c\x68\x8e\x39\x3f\x32\xb6\x2e\x1b\xf3\x93\x4b\x52\xb7\xdd\xa3\x94\xee\xb1\xd4\xa5\x81\xc9\xf3\xa7\x82\xa0\x7e\x1f\x20\x1b\xf6\x5c\x9d\x80\x2d\x3c\x49\x15\x13\x54\xf7\xd3\x4f\x97\xb2\x7a\xb9\x39\xed\x07\x49\xaa\xe2\x1c\xbc\x3f\xe4\xc2\xa0\xd7\x65\x3b\x89\x43\x25\x99\x0a\x8c\xd1\x41\xb5\x8b\xa8\x37\xc7\x8f\x91\x73\x40\xa3\xa5\x77\x49\xdd\x62\xbe\x2c\xb3\xe5\xfb\xcb\x18\xdd\x85\xd2\x05\x1a\xc2\x8e\x34\xee\x56\x44\x02\x57\xff\x88\x06\xf9\x4b\x73\x38\x91\x59\x8e\x97\xdc\xd7\xfa\xe7\x28\x51\x8a\x98\xb7\xbf\x98\x5b\xd3\x7f\x7d\xd0\x2e\x91\x5a\x61\xa8\x96\xcc\xe5\x6b\xf0\xf2\x1e\x61\xbd\x48\x30\xc8\xa6\xe7\x4a\xa3\x7a\xc3\x8d\xbc\xc0\x13\x47\x51\x58\x3a\x8a\x67\x18\x15\xb2\xd0\xe9\x57\xd4\x8d\x1f\xbf\x82\x12\x96\x2a\x6d\xa9\x82\x63\xdc\xa8\x99\xc0\x53\x92\xa2\x6e\x8f\xd5\x39\x37\x28\x4f\x74\x9e\x61\x9f\xfb\x8f\xc5\x6a\xce\xb9\xb8\x24\xba\x3b\x19\x36\x23\xc9\xf3\x33\x8d\x2c\xab\xd9\xf3\x7c\x72\x47\x10\xb1\x2c\xbc\x27\xfe\x3f\xc7\xe6\xa3\x3f\x3a\x27\x0e\x7d\x02\x99\x0a\x05\xb4\xdd\x80\xdd\xd1\x37\x17\x60\xb8\xaf\x9b\x6a\xcf\x0c\x91\x04\x54\xa2\x4f\xbc\xd6\x2b\xc7\x99\x1f\x1a\x8d\xf4\x3c\xe3\xf5\xaf\x8f\x4b\x28\x74\x9e\x00\x70\x64\x7b\xbc\xff\x20\xe3\x6a\x68\xb4\x26\x60\x35\x96\x0c\x5b\x0c\x95\x12\x73\xc5\x74\x70\x6d\x4c\xac\xa0\x16\x60\x48\x20\xc2\x13\xab\x00\xf3\x0c\xf7\xd0\xc9\xdb\x53\xd4\x3c\x8d\xa4\x21\x4c\x4a\xd9\x8d\x81\x03\x69\xa4\x0c\xc6\xeb\x3c\xd5\xa5\xc3\x25\x21\x82\xb6\xfd\x12\x9d\xc4\x27\xe8\xa4\xf1\x97\x4a\x99\xcc\xf5\x90\x89\x55\x7d\xec\xdd\x60\xb8\x0e\x3c\x8e\x52\x27\x46\xbb\x74\x30\xd1\xb9\x3c\x8c\xdf\x34\xed\x0f\xfd\x7e\xa8\xde\xfd\xe9\x38\x4c\x8c\xa6\xfd\xf6\x8e\x14\x72\x88\x02\x4d\xb6\x4f\xab\xa5\x27\xe3\xe1\x29\x37\xe0\x4f\x90\x6d\xdb\xc9\xb2\xd1\xbe\x58\xc1\xaf\x86\x54\xc4\x71\x9e\x78\xd5\xf9\x3d\x8c\x0a\xac\xbe\xde\xd7\x53\x91\x65\x98\x7b\xfe\x59\x76\xdd\xc7\xed\xc7\xde\xff\x6a\xcc\x4d\x44\x99\x1e\x2d\x3f\xc0\x7c\x46\x6d\x36\xde\xa1\xd3\x44\x14\x98\x92\xa3\xd5\xe2\xd8\xe0\x3f\xd9\xa6\xff\xe2\xc1\x92\x24\xc3\x60\xd4\xcc\x00\xec\xe4\x06\xfa\x21\x0b\xf1\xff\x34\x29\x14\xae\x9f\x5b\xe8\xe6\x65\xf7\x71\x27\x2b\xf3\x70\xdc\xb7\xa1\xd9\x50\xac\xab\x91\x1d\xac\xe1\xc4\x18\xc8\xd3\x54\x48\xca\xb9\x2e\x56\xeb\xc5\x6a\xe6\xf1\x10\x69\x16\x09\x2c\x30\xb9\x7a\x9c\xad\xae\xb7\x2c\xfc\x99\x53\xcc\x7f\x4b\xa0\x3e\xac\x57\xa1\x42\xcb\xc9\x07\xce\x0c\x60\x30\x8b\x72\xb9\x94\xc9\x1a\x2f\x97\x34\xe7\x04\xb8\xc5\x90\xf2\xb1\xea\x3e\x3e\x17\xa7\xe1\x69\x2e\x88\x66\x82\x98\xd9\x02\xbc\x6a\x59\x39\x4e\xf5\x49\x77\x19\x25\xb8\x14\x9f\x39\xfb\xd3\x3f\xbb\x2a\x48\x86\x79\xf1\xf0\x78\x1f\xfe\x26\x49\xb8\x60\xab\xe5\x01\x89\x30\x03\x08\x91\xa7\x4a\x25\xc2\x85\x20\xfa\x31\x45\x95\xa3\x8b\x9b\x7e\xaa\x14\x91\xb5\xfc\xf8\xf6\x78\x7f\x59\x0a\x99\xa7\x9a\x25\x08\xa3\x74\x75\x39\x17\x08\x5c\x79\xaa\x53\x09\x9f\x40\xdb\xc6\x3f\xa8\x15\x14\xd2\x4b\xf9\x93\x60\x74\x7b\x8d\x28\xd4\x49\x96\x8c\xa5\xd1\x3f\xe8\x1f\x77\xa5\xb1\x84\x37\xc2\xf0\xb4\x07\x2c\xdc\xd4\x44\x73\x74\x7b\xda\x3f\x20\x01\x5c\x42\xb7\xd0\x39\x1d\xda\x51\xfc\x63\xfc\x38\x90\xe5\x8e\x5e\xac\x32\xd7\xb0\x0b\x0b\x44\xba\x5a\x3c\xd7\xcd\x0a\x72\x2e\xef\x97\x0f\xcb\x87\xdb\x31\x1f\x28\x4f\x6d\x6c\x31\x6c\xd6\x85\xd4\xe0\x84\x26\xcd\xf7\x4b\x1d\xd3\x01\x74\xf3\x46\xda\xde\xb2\xb8\x3c\x65\xac\xca\xa2\x24\x60\x91\xeb\xa3\x67\xef\x76\x3f\x98\x45\x4a\x1b\x17\x93\xed\xa7\x70\x59\xbd\x10\xc2\x81\xa0\xb1\xa3\x37\xcc\x18\xcb\x19\x11\xe7\xef\x4e\xb8\x8b\x8c\x15\x99\x74\xe6\xc9\xb2\x3d\x51\x30\xb9\x56\x1e\x47\x18\x89\xde\x3a\xd7\xf6\xeb\xbd\x22\xe3\x45\x8c\xee\x53\xe5\xb2\x88\x37\xb2\xd9\x9f\x80\x89\x19\x2f\xcc\x40\xb9\xfa\xd8\x4d\x23\xb6\x19\x97\x69\xe4\xf6\x45\x0c\x31\xe3\x67\xb8\xfc\xc1\x32\x6e\x81\x91\xf4\x88\x23\xa9\xff\x6c\x0f\x1a\xff\x84\x48\x08\xd9\x30\xff\x50\xbd\x59\x31\xd0\x22\xbb\xe4\x36\x64\xc2\x2a\x64\x3a\x39\x90\xf4\xce\xf6\x7d\x44\x1f\xc6\xb3\x38\xe2\xe8\x56\x28\xfd\x3a\x8a\x78\x65\xb1\xcc\x31\xc2\x5a\xea\x1a\x21\x61\x82\xb4\xfb\x7d\xab\x89\xf0\x45\xef\x66\x3f\xe6\x9f\x72\x6f\x4c\x9e\x3c\x29\x00\x86\x19\x08\x12\x2d\xbe\x92\xfa\xe7\xa6\x5e\x03\x12\x51\x8c\x1e\x3d\x8d\x0c\x15\xb6\x0f\x52\x47\xa3\x23\x39\x4b\x59\x8c\x39\x8b\x7b\xd9\xbd\x3e\x77\xe5\x2e\xfc\x3d\x8d\x70\xab\xdd\xc9\xb6\xbb\x29\xab\x32\xa4\x4e\xb2\x14\xa8\xa0\xf7\x2d\x80\x14\x91\xaf\xa0\x7d\x3d\xe7\x01\xf3\x86\x5f\x96\x5a\x91\xba\x19\xd6\x9f\x64\xd7\xb2\x93\x57\x1f\x23\xf2\xf9\xd0\xd1\x20\x4b\x41\x5d\x6d\xe4\xaf\x2f\x89\x37\x79\x96\x45\x0c\x73\x28\x07\x68\xb4\xd3\xd7\x2b\xf7\xd0\xb2\x28\xf2\x8f\x9a\xb1\x64\x80\x8d\x46\x00\xd6\xba\x9c\xec\xb1\x59\x9e\x19\x84\xbf\x5b\xf0\xdb\xd9\xd0\x02\xc9\x72\x65\x22\x4e\x9b\xd9\x55\x5d\xef\x40\x56\x54\xb3\xe4\x9a\x8b\x34\xce\xd5\xa9\x12\xba\xeb\x0d\xbf\xee\xb7\x29\x46\x6c\x54\x28\xc2\xb3\xc2\x52\xc6\xc3\x07\xc5\x3f\x25\xb3\x1b\xbf\xb0\x8c\x59\xee\xe6\x13\x16\x95\x9e\x66\x9a\xcc\x04\x26\xba\xc8\x2a\x9b\xc3\x39\x9f\x95\xef\x98\xcb\xe2\x24\xaa\xe3\xb2\x13\x30\xac\x30\x18\xcf\x7d\xa9\x63\x8c\x11\x18\x20\x13\xe8\xb3\xdb\x42\x86\x29\xcd\xeb\xdb\x6b\x0c\x78\x84\x07\x53\xa9\xc9\xc9\xe2\x23\xfd\xcd\xaf\xdc\x99\x4c\xe5\x11\x8a\x4a\xbc\xe3\x0c\xfd\x01\xea\xc3\xd4\xe1\x46\x85\x88\xbd\x1a\x2c\xc8\x3d\x55\xa9\xb4\x41\xd8\x9e\x67\x9a\xc7\x10\xe0\x26\x78\x96\x0f\xd0\x87\x99\x16\x0a\xc9\x5b\xea\x0a\xfe\x04\xd9\x84\x3f\xe7\x89\xd2\x5e\x23\xa4\xd4\x3f\x11\x04\xf7\x44\xf3\xc9\xf7\x31\x91\xb4\x2e\xb7\x0b\x1d\xcc\x1a\x55\x76\xe7\x82\x34\x3c\x33\xa2\xc0\xe8\xd5\xc3\xe2\xf1\x6a\x07\xc7\x70\xb5\xca\xb5\x8b\x4e\x91\xb2\x29\xed\xe1\xbe\x19\x38\xe0\x73\x55\xf0\xab\xdf\x0f\x81\x52\x15\xbe\x31\x56\x0c\x19\x39\x30\x28\x43\x74\x4c\x83\xf3\xe8\x31\xcc\x51\x80\x0c\x63\x71\xfd\x62\x0d\xf4\x0b\xfd\x9f\x0d\x44\x9e\x49\xb4\x93\xbb\x21\x9d\xff\x78\xe4\x6d\x91\x21\xec\xfe\x5e\x36\x2f\x32\x54\xcb\xf0\x3c\x62\xd6\x0b\xd7\xf7\x3e\xe9\x72\xa0\x18\x33\xde\x99\xf2\x28\x15\x3a\xd4\x25\xee\x43\x9a\xda\xb7\x66\x89\x74\x50\xc3\xed\x01\x3f\x5d\xe0\xf5\x1a\x3d\x48\x1e\x81\xc5\x8e\xae\x75\x53\x5f\xa1\x7f\x38\x1e\xeb\x9c\x45\x05\x9a\x89\xc4\x3d\xd0\x6d\x60\x7f\xd8\xf5\x9e\xd2\xe5\x74\xc2\xe7\x11\xa1\x9c\x69\x81\xd4\xdf\x5b\xb7\x87\x7c\x8d\x1e\xc8\xb9\x4d\x12\xe6\xcf\x6c\x1f\xad\x43\xae\xaf\x5f\xdd\xdb\xf4\x21\x45\xbf\x51\x8e\x59\xd1\xd0\x9f\x1b\x49\xbe\x8c\x9e\x46\xe4\x29\x02\x32\x1f\xe0\x57\x19\x26\x76\x9e\x08\x4e\x9a\x8a\xe7\x22\xc7\xbe\x47\x2a\xb9\x3c\x5b\x1b\x93\x91\x4d\x4c\x81\xa1\x8a\x23\x46\x37\x86\x45\x51\x3c\x4f\x2c\x99\xb0\x68\x95\xfa\x9a\xb9\x73\x97\x3a\x4f\x35\xd3\x44\x77\x68\xba\xda\xb1\x7e\x5e\x9e\x0e\x59\x11\xe1\xde\x7c\x57\xbf\x8c\x4a\x5e\xfe\x9f\xa2\x54\x79\x9e\x91\x09\xdb\x7f\xa2\xf6\x09\x9a\x93\x75\x9b\xe7\x39\x71\x77\x1e\xab\x76\x08\x4f\x77\xad\x05\x23\xd9\x06\xd9\x62\x02\x8e\x42\xa5\xd5\x24\x3c\x93\x4b\x6e\xb1\x82\x62\x2b\x1d\x3c\xfc\x99\x38\x89\x11\x75\x36\x48\xca\xe7\x32\x2b\xd0\x7c\xfa\x4f\xbf\x57\xf0\xf0\x57\x9d\xa7\x81\x6d\xf9\x0b\xa5\x49\x9e\x4b\xa3\xd1\x94\x9a\x75\x5d\xe0\x25\xe3\xb9\xb4\xb4\xcc\x0f\xc7\xf6\x75\x56\xbd\x80\xcb\x91\xf6\xf3\x64\x28\x38\x30\xb9\x97\x12\x54\x89\x45\xd4\x93\x2d\x74\xdb\xf6\xb5\x3e\xa0\x4c\xda\xca\x83\xfe\xc7\x83\xa1\x32\x49\xf8\xe0\xb2\x55\xc7\xa6\xc5\x89\x38\x2c\xda\xe6\xb9\xca\x39\x06\xc4\xef\x67\x9b\xed\xe6\x71\x33\xbb\xdb\x3a\xde\xfb\xbb\xe5\xbd\x97\xa3\xe5\xb9\x8e\x32\x96\x9e\x52\x1d\xa7\x30\x4e\x18\x50\x0d\x3c\xa1\x3a\xbe\x6d\xff\x70\x2f\xb5\xdc\x6d\x1b\x42\xcc\xf9\x9b\x18\x4e\x9f\x14\x85\xdb\x30\xe4\x18\x02\xe9\x39\x24\x85\xdf\x33\xb7\xfd\x12\xdb\xd6\x17\x26\x3d\x00\x99\x4f\xc4\x16\xdc\x81\x71\xac\xd0\xae\xd9\x46\x16\x3f\x8a\x3a\xee\x7e\x12\x96\xe9\x4e\xee\x55\x7d\x31\xb4\xec\x28\xe6\xce\xe6\x5d\xc1\x62\x92\xbd\x72\x75\x5f\xdb\xe1\x12\xbc\x68\x5a\x16\xfd\x73\x11\xe2\xe4\xd0\xc9\xb2\x7a\x6a\xe0\x54\x6d\xc9\x0b\x11\xe7\xc8\xe0\xf4\x4d\xee\xe4\xee\x09\xaa\xea\x23\xb4\x28\x92\x86\x26\xab\xb9\xb6\x15\xbc\xfb\xe1\x28\x62\x29\xb1\xda\x66\x51\x99\x7a\xfd\xed\x94\x4a\x29\x12\x1e\x61\x38\x65\x7b\xac\x5a\x69\x61\x58\x6b\x37\x79\x91\x24\x21\xcf\xe6\xa5\x7c\x83\xe5\xc6\x6b\xc1\xf1\x22\x65\x19\xfa\x0e\xcd\x20\x8b\x30\x29\x00\xf4\x3d\x13\x89\x51\x7a\x52\x00\xbb\x45\x65\x93\x06\xa6\x9d\x34\x43\x19\xd7\x90\xe4\xfb\x34\x79\x3c\xdc\xf7\x8a\xac\xdf\xcf\x51\x8e\x8b\x4a\xfd\xb6\x28\x83\x7c\xf7\x38\xff\x7d\x71\xbd\x5d\x2f\xbd\xee\x37\x2f\xb2\x4c\xa3\x6f\x31\xf5\x44\x86\x76\x96\xeb\x9a\x47\xb9\x70\x76\x99\x87\x2e\x8d\x9f\x35\x8f\x48\x43\xac\x77\xab\x88\xca\xd3\xc9\x32\x8d\xbb\xc9\x8c\x23\x77\xe5\xd6\x93\x03\x6f\x6a\x54\x26\x1e\xed\x66\x17\xd1\x50\x85\xe2\x11\x26\x8b\xe0\x17\x56\x47\x8d\x3a\xe7\x7f\xaf\xbe\xc0\xdd\x49\x33\xa5\x3d\x3f\x42\x3b\x7f\x95\xcd\x8b\xa7\x0e\x09\xc9\x5c\x18\x50\x83\xf0\x42\x67\x79\x16\x79\xd8\x81\x2d\xab\x91\xd7\xeb\xfa\x18\x6e\x79\xe0\x70\xff\x09\x15\x1d\xd9\x93\xd7\xb7\x8c\xe0\x14\x2b\xd0\x25\xbc\x21\x6f\xde\xd7\xd8\x8d\xc2\xc6\x06\x29\x8a\x91\x60\xe6\xf8\x31\x48\xf0\x15\x36\x53\x4c\x85\xd0\xe4\x76\xc8\x38\xe8\x7b\x18\x95\x9f\xc2\xb2\x6b\x90\xed\xb8\x4c\x32\x90\x41\x06\x9e\xbd\xfc\xe4\x6c\xe4\x3e\xf9\xd2\xff\xd7\xa9\xdd\xdf\x1a\x88\x3b\xbc\x83\xb6\xb7\xb4\xba\xdb\xe3\xc7\x90\x77\x80\xcb\xa8\xa0\xb0\x27\xc9\x17\x1a\x5f\x63\xe1\x5b\x65\x91\xf7\x53\xef\x76\xfe\x30\x94\xba\xe5\x92\xa5\x06\x43\x49\xb7\xd0\x3d\xd4\x5e\x0f\xc1\xe5\xec\xa5\xc8\x8d\x74\xb1\xa1\xdf\xff\x9c\x8f\xc4\x32\xc6\x1b\x87\xec\x7d\x45\x04\xeb\x75\xe0\x4f\x7e\x99\xa4\x14\xa4\xa6\xaa\xc4\xe7\x43\xf8\xbb\xce\x0a\x5f\x66\x5f\xc2\x7b\x7f\x48\xf8\xcd\x42\xa6\x09\xcb\x4e\x85\x88\x4e\x94\xfd\x04\x38\x19\x7f\x5e\x99\x16\x31\xcb\x42\x46\x0c\xd1\xe2\xf8\xd6\x63\x7a\x3a\x2e\x53\x48\x31\x06\x01\x6f\x50\x5d\x97\x6d\x47\xb8\x67\xdf\x9a\xf1\x18\x6b\x23\xd6\x55\xfd\x9f\xa3\xdc\xed\x4b\xf8\xdc\xa1\xf5\x97\x24\xc4\x94\x0f\xfb\x43\x40\xfb\xc9\x0c\x52\x3e\x54\x2d\x1e\x79\xaa\xb2\x90\x39\xfa\x9d\xd2\x13\x65\x5f\x46\x66\x48\x25\x00\x09\x5c\xca\x4a\xd7\x7b\x78\xb4\x2c\xf2\x27\xad\x54\x49\x81\xde\x8c\x1e\x98\x24\x54\xd9\xb8\x0d\x5d\x0a\x81\x3e\x48\x7b\xdc\x2f\x76\x78\x44\xb6\x13\x3e\x3b\x2e\x95\x89\x30\x69\xe6\x20\x77\x57\x30\xac\xac\x90\xba\x88\x39\x89\xef\x94\x1a\xda\x4d\x4d\xa2\x3a\xd3\x8a\x1f\x69\x74\x21\x4e\xd9\x62\x27\xdb\x3f\x29\x9b\x91\x36\x02\x6e\x43\xed\x31\x85\x29\xa9\x9a\xc3\x81\x60\xc7\x9f\xd3\x26\x05\x1a\x90\xb6\x3e\x36\xdd\xeb\x80\x3c\x90\x4b\x0b\x05\x06\xc2\xee\x16\x57\xab\x47\x47\x74\xcd\x55\x24\x08\x22\xba\x7d\x81\xee\xa1\x54\x6a\x07\x24\xbd\x38\xd8\x7c\x54\x94\x68\xe6\x95\xb9\xea\x43\xa9\xe7\xe7\x11\x3f\x15\xc9\x24\x71\xa7\xf9\xd3\xae\xee\xce\x6a\x8c\xb9\x62\x59\xa2\xa3\xa1\x0c\x3c\x92\x24\x5e\x3c\xad\x14\x53\x54\x92\xdb\x42\x37\xfb\xcf\x51\x36\xe5\x71\x7f\xbe\x7f\x29\x9e\x26\xe8\xf3\xf6\xfe\xc4\x48\x46\xf6\x73\x7b\x5f\x71\xe7\x8e\xf6\xee\x16\xe6\x73\x3d\xad\x92\x6f\x2f\x8a\x42\x84\xe8\x14\x34\x72\x37\xfd\x51\x1b\x53\x74\xaa\x9f\x84\x17\x29\x86\xfa\x3e\x96\x39\x19\x7e\xd4\xfa\xa7\x82\xbe\x50\x4f\xa5\x84\x31\xd6\x07\xec\x16\x9b\x98\x70\xe6\x93\x01\x8d\x23\x8e\xe4\x1b\xab\xd9\x66\xe1\xf1\x0a\x2a\x8e\x13\x49\xf4\xd3\xef\xcd\x30\x5f\x35\x19\xbe\x38\x91\x98\x01\x22\x4f\xb8\xf7\x53\x86\xaf\x18\x27\x40\xb2\x7e\x75\xf5\xcf\x63\xf9\xab\xee\x86\x14\x0c\x5c\xc5\x99\x49\xb8\xa3\xbc\x5c\xeb\x12\x4e\x78\x5b\x15\x6b\xa6\x8a\x13\x6e\xf9\xda\xfb\x08\xa3\x65\xe8\xfa\x26\x49\x81\x1b\xdf\xa1\x29\x2b\x94\xdf\xa4\xcd\x74\xf4\x9c\x29\xe4\x2a\x75\x50\xbd\xf5\x47\xd5\xbd\x42\x57\xfe\xa2\x74\xdf\x24\xc6\xae\x32\x49\x32\x2f\x06\xda\xce\xb1\x50\x13\xd6\xdd\x3f\x5b\x1e\x33\x4d\xf4\x03\xe4\xfd\x2c\xcd\x67\xc5\x9d\x2a\x4f\x12\xe6\x9c\x98\x07\x78\xc7\x99\x33\xfe\xb1\x22\x8a\x11\x1d\x86\x59\xba\x2b\xe8\xe6\xf5\xee\xb8\xaf\xc6\x24\x50\x17\x29\x63\xb8\x2a\x92\x18\x33\x3e\x8e\x98\xa6\x7b\xed\x17\xff\xb1\x2a\x3d\x89\xef\x05\x6d\xd7\x21\xc6\x4b\x15\x2a\x26\x72\x08\x44\xd5\x0f\xb1\x1d\xfe\x45\x0b\x5b\x60\xa2\x03\x33\x17\xbd\x21\xa2\xcb\x83\xac\x90\x53\xea\x13\x5f\x4c\xe1\xa9\xea\xf4\x98\x76\x97\x29\xb7\xb9\x92\x2c\x87\x11\x9e\x6d\xc0\x9d\xc9\x95\x14\x0c\xcd\xda\x7b\xd9\x94\x55\x98\x10\x32\xce\xf0\xc4\xc4\x95\x34\x97\xed\xeb\x93\x3c\x63\x78\xfa\x5b\xb4\xc8\x5c\xc9\x9c\x45\x48\xeb\xbd\x5a\x10\x73\x8a\x88\xb6\x44\x03\x71\xbf\x0c\xbb\x95\x94\x32\x3a\xd1\xfe\x78\x0a\xee\xa9\xdd\xa5\x54\xa2\xb1\x94\x6f\x2f\x7f\xf5\x07\xfd\x53\x53\xd7\xf6\xd1\x52\xf5\xb2\xef\xa2\x89\x45\x00\x3f\xf1\xf7\x1a\xd3\xfa\x75\x43\xe6\xfd\xd5\xf1\xa3\xb7\xd9\x1d\xe9\x8c\xbf\xc0\x48\x8c\x24\x3e\xf0\xb9\xff\x93\x36\x11\xe7\x23\xdc\xca\x18\x74\xa7\x8c\xb1\x4e\xb8\xdd\xf4\xc7\x5c\x59\x57\xa3\xf8\xc9\x71\x80\x13\x55\x90\x92\xbf\x4c\xe5\x37\x1b\x59\xfd\x6c\x37\x1f\x87\xe9\xce\x02\x92\x61\x69\xfa\xfd\xec\x61\x76\xbb\x58\x39\xef\xcc\xff\x1e\x40\xe4\x13\x3d\xe4\x36\xc9\x4b\xf9\x04\x65\x33\x42\x96\x50\xaa\x64\x36\xff\xea\x9c\x56\xd6\xa6\x68\x46\x97\xba\xde\x76\x43\x5f\x58\x47\x51\x81\x68\xa7\x6d\xbf\x7c\xbd\xbd\xd0\x7c\x81\x0e\x1e\x3d\x85\x8e\xb4\x41\x90\x90\x97\x4a\x68\xc7\x51\x37\x1d\x19\x86\xa5\x7c\x15\xbc\x8f\x42\x1e\x93\xdb\x30\x43\xb4\xec\x37\xb2\x6a\x87\xfb\x98\xe6\x45\xae\x46\x05\xf0\xc3\xd7\xd2\xdc\x58\x74\x54\x3a\xa4\x26\x2b\x77\xeb\xde\x78\xeb\x56\x80\x76\x52\xbf\xf4\x1e\xea\x6e\x20\xaf\xcc\xb5\x88\x23\x4b\xa0\x2b\x3b\x77\x41\x88\xd1\xcf\x09\x48\x4d\xe1\x94\xd2\xcb\x86\xb6\xd4\x9b\x23\xf8\x3d\x5f\xc7\x11\xc7\xbd\xae\xab\x8d\xfc\xf0\x25\x38\xa1\x31\x06\x0c\x1d\xba\x0c\x95\x17\x3b\x1b\xbf\x69\xac\xa9\xd6\x73\x2f\x7f\xc2\x29\x40\xf0\x59\x32\xe6\xd3\x65\x37\xbe\x69\xc2\x2c\x7a\x5e\xd7\x0f\x33\x0f\xdb\xd1\x49\x41\x81\x05\x24\x17\xfd\xe5\x62\x25\xcc\xed\x70\x3a\x55\x12\xe9\x2f\x88\x53\xd6\x25\x99\x5c\x5b\x16\x39\x1d\x5d\x13\x4a\x5f\x96\xf6\xa1\xf6\xf5\xfe\xe3\x9f\xce\x8c\x70\x64\x9c\x97\x79\xcf\x5c\xb7\x3c\x8a\x45\xe2\xb5\x59\x9e\xab\x3d\x41\xd8\x27\x7d\x18\xa1\x8f\xa4\xf1\xd8\xb4\x4d\x7d\xe5\x19\xb0\x27\x3f\x9b\xf3\x24\x73\x71\x4a\x2d\x0f\x95\x0c\xde\x89\xce\x65\x8e\xd5\xc7\xeb\x3f\xe7\xbc\x32\x0b\xd9\xec\x3e\xc6\x52\xc4\x5c\xe7\x2a\x45\x81\xf2\x9b\xd9\x7c\xf3\xb8\xda\xe6\xe1\xef\x86\xc7\x8e\x7e\xf9\x0d\x9a\xae\x1c\xd5\x6a\xfa\x74\xbe\x2e\x20\xc2\x2d\x76\xfd\xb3\x39\xee\x43\x97\xd0\xa8\x4d\x3e\xac\xbf\xf3\x0d\x4a\xa6\x88\x85\x5f\x2d\x9e\x9e\x37\x33\x14\x10\x9b\x94\xb9\x68\x2d\x29\x49\xed\x28\xd7\xbd\xbd\x1f\x88\xaf\xc7\x23\x60\x72\xd2\x2c\xe9\x4e\x4e\x5f\x6f\xa5\x22\x43\xec\xb8\x27\x18\x89\x95\x84\x5e\x0a\xba\x1e\x90\x0c\x5f\x0e\xe1\x6b\x80\x04\xb1\x5c\x9b\xe5\x62\xc5\xbc\xc8\x99\x7f\x4e\x9b\xe6\xb8\xf3\xdc\xcf\xfe\x78\x5a\xac\x7e\x2c\x96\xa1\x01\x78\xea\x80\xb6\x8b\x43\xad\x5f\x83\xfd\xc8\x78\xee\xb2\x49\x69\x3c\xfd\x8f\x81\x45\x6e\xa2\xc4\x72\x67\x72\xf5\x87\x7f\x65\xe0\xd7\xa6\x1e\xc5\x69\x7c\xc7\x94\xa8\xd0\x5a\xe8\xae\xca\xee\x20\x49\x01\x60\xdd\xd5\xcd\xa0\x2a\x7f\xbc\x48\x0c\x4b\x74\xec\x1c\xe5\xbb\x52\xf7\x16\xd1\x06\x53\x6d\x84\xf8\x26\x74\xce\x78\x18\x0c\x67\x02\x09\x4b\xf0\x08\x5b\x5c\x6f\x9f\x9e\x57\xf3\x6f\xb3\xf5\x62\x3d\x8a\xa4\x19\x0e\x0c\x31\xcf\xff\x5c\x7f\x7b\x0e\x7f\xb3\xb2\x60\x64\x39\xbd\xf5\x3e\xb0\xdc\xc1\xbd\xfc\x85\xdf\x74\x14\xac\x33\x22\x4f\x7d\xc5\xe6\xbf\xeb\x63\x53\xc9\x1d\xae\x32\xd7\x1a\x8b\x02\xe7\xd3\x53\xfd\x73\x92\x73\x30\x49\xc4\x12\x16\xf4\xcf\x56\x2d\x3b\x59\x71\x63\x73\xc6\x24\x59\x8e\xb4\x86\xab\x6f\xc3\xb9\x6a\x92\x4c\x1a\x47\x3c\x8a\xd3\x26\x10\x06\x8c\x07\x21\xc9\x53\x54\x4b\x99\x6d\x36\xab\xed\xe2\x8f\xa7\xbb\xc7\xd5\xec\x2a\xb0\x1b\x98\xc4\x24\x98\x13\x3c\x1c\x3f\xcb\x56\x99\x34\x07\x18\x82\x74\xe6\xf5\xae\x37\x4d\x1a\xb9\xbb\x69\xea\x3d\x2a\x09\x7d\x72\xa1\x36\x18\x32\x9b\x2f\x1e\xb7\xc8\x8b\xe2\x97\x93\x49\x21\xc2\x5c\xf7\x76\x7b\x68\x6a\xe4\x65\x3d\x57\x7f\xe5\x26\x8b\xe8\xc3\x04\x51\xe9\xcf\xe2\xd4\x43\x8e\x53\x7f\xad\x30\x88\xe6\xee\x0d\xa8\x7f\x8d\x19\xce\xb8\xc9\x6c\x4a\x72\x05\xbb\xba\x05\x2f\x6e\xfa\x97\xdc\x13\x94\x3f\x3c\x99\xd7\x26\x8f\x48\xd1\xc5\x96\x4d\x4b\x95\xff\x94\x79\x5e\x56\x81\x21\x99\x9b\x22\x4a\xb5\x3e\xe5\x52\x9c\x06\xa0\x57\x64\xe7\xa6\x10\x56\xf9\x20\xd1\xb1\x7d\xdd\x94\x7b\xb8\xd9\xd5\x75\x33\x3f\xd3\x92\xe2\xa6\xb0\x31\x62\x1e\xec\xae\x3c\x3c\xc9\x8f\xb2\x7a\xb9\xae\x8f\x6a\xd7\xb4\x83\xa8\x93\x91\xcc\x62\xbc\xa2\xdc\xcb\x17\xb8\x08\x66\x30\x32\xcd\x4c\x10\xb0\xaa\x4e\xe3\x7a\x29\xf8\xc5\xa3\xb1\xb5\xed\x6f\x91\x53\xae\xd1\xc8\x4e\x3e\xda\xf5\xa7\xb9\x4e\x23\x15\x4d\x02\xd4\x59\x3d\x50\xf9\xd3\xe7\x39\x6a\x23\x8d\x41\xf3\xe9\x06\xb5\x7d\x08\x66\xe6\xd6\x20\x9c\xcb\x7c\xb8\x8b\x54\x42\x0a\x0a\xdf\x6f\xfd\x6e\x6c\x14\x44\x58\x13\x54\x3b\xf6\xc3\x4f\x54\xf2\x5c\x6f\x9d\xe7\xd9\x30\x0a\x87\x2c\x84\x9f\xeb\xf3\x73\x63\x62\x85\x20\x9d\x83\x4b\xba\x3b\xab\xed\x62\x08\xd2\x98\x34\x41\xaf\xff\x45\x36\xb2\xea\x80\x58\x44\x5c\x80\x77\x59\x79\x05\x4c\xff\xe4\x46\x67\x58\x69\xe0\x2a\xb3\x87\x51\x00\x63\x8c\xc1\x12\x9f\xab\xbb\xeb\xd9\x45\x2d\xb1\xa1\x4f\xe3\xae\x01\xc6\xad\xd7\x2f\xff\xf5\xbc\xbe\x76\xef\x75\x29\x35\x62\xac\x64\x58\xec\xbf\xde\xcc\x36\xcf\xeb\xed\xf5\x62\x76\xb7\xfd\x31\x5b\x6e\xb6\xf3\xc7\x87\x9b\xe5\xea\x1e\x4f\x3e\xff\xa0\xd6\x64\x88\x93\xa5\xb0\xd5\x0f\xd9\xf4\x6f\xf7\xf1\xdb\x17\xc8\x09\x88\x84\x44\xd2\x81\xfa\x00\x95\x0f\xa5\x8c\x41\xad\x5f\x26\x0f\xe9\xed\xce\x57\x3b\x44\x05\x31\x21\x78\x10\x3d\xd5\x24\x39\xbf\x64\xf8\x86\x10\x99\x54\x0c\x49\xb3\x1c\x3f\xc0\xb8\xef\x09\x5f\xeb\x37\x61\x60\xac\xc0\xec\xde\x7b\xbd\xfb\x39\x70\xe4\x81\x71\x29\x8a\x13\xa3\xf0\x05\x92\x62\x0e\x4c\x31\xad\x43\xf6\x79\xbd\xab\x27\xeb\x1a\x98\x02\x24\x66\xba\xbd\x7e\x1a\x55\x41\x00\xe7\x12\xb7\xde\x3d\x25\xee\xaf\x6a\xd9\x98\x91\x0d\x0d\x3c\x11\x48\xf7\x73\xf3\xbc\x79\x5e\x2d\xb6\xf7\x0b\xc7\xd8\x17\xee\x90\x29\x71\x12\xe8\xf6\x1e\x02\x9e\x35\xff\x4f\x3e\x22\xf0\x1c\x30\xef\x74\xd5\x94\xb2\x82\x5f\xc3\x7d\x15\x38\x24\x30\x28\xde\x76\x9b\xcf\xb2\xba\x7b\xde\x4c\xde\x58\xc4\x05\x46\x56\x10\x8c\xb9\x9d\x3f\x6f\x1e\x6f\x6e\xfc\x5d\x62\x6b\x45\x74\x8a\x70\x4c\x10\x8e\xae\x53\x92\x90\x9a\x0c\x1d\x9f\xae\x70\x7d\x50\x84\xf7\xd9\x66\xfe\xc9\xff\x0f\x77\xa5\xa0\xcd\x0b\xd6\x1a\x75\x65\x85\x5e\xff\x45\x90\x0c\xa4\x9c\xd6\x29\xa5\xfe\xe4\xc8\xeb\x84\x34\x89\x30\x61\xf1\x04\xcd\x01\xba\xa3\xdc\x4d\x30\x96\x90\x02\x55\x62\xb9\xeb\xa0\x25\xf6\xb6\xbf\xe2\xa5\x80\xd4\x82\x0e\xde\x3e\x3d\x5e\x88\x69\x41\x96\xb0\xd8\xd5\x86\x5d\x7d\x20\x3f\xe2\x68\xae\x64\x85\x44\x72\xfc\xc5\xe6\x1b\xc8\x5d\xc8\xde\x42\x1e\x5b\x8c\xf8\x6e\xd5\x47\x33\x2d\xfb\x87\xa2\xc8\xd1\xcc\xc0\xec\xdf\x0a\xde\x40\xee\x1e\xdf\xa0\x69\x4a\x33\xed\x29\x73\xd2\xf9\x06\xd2\x73\x5b\x81\x3e\x36\x6d\xf9\x76\x66\xd0\x85\x5d\x72\x7c\x35\x64\x41\x5b\x04\x59\x2b\x1d\x80\x73\x7f\x1e\xe8\x04\x09\x80\x68\x20\x79\x38\xec\x3e\x7e\xc8\xc0\x96\x03\x4a\x50\xe1\xb0\x34\xe6\xd1\x5a\xe4\x96\xb9\x98\xf8\xfe\x2a\x11\x06\x4a\x80\x88\x5d\x60\x99\x85\x3b\x27\xc6\x04\x45\x90\xe7\xf5\xf5\x89\xcd\x9f\x83\x32\xc4\x1f\xd6\x35\x1f\x8b\x5f\xa0\x7f\xbb\x70\x5e\x82\x4e\x23\xcc\xdc\xd9\x93\x6e\x5f\x98\x0b\x3a\xe5\x69\x50\x3d\x73\x8b\xe6\x7c\xc9\x68\xa0\xaa\xe4\x86\xb8\xe3\x97\xda\xa3\x72\xc0\x70\x16\x3b\x2f\xfd\x56\x76\xd0\x5b\x4a\xbe\x45\x65\x18\xad\xf7\xd4\x6c\x3f\xea\x33\xcd\x5e\x0e\x90\x2b\x70\x5b\xd8\xfa\xa8\x1c\xc0\xff\xf1\x00\xd3\x25\x07\x92\x30\xed\x2d\x74\xc7\xc3\x4c\x6b\x14\xbc\x0e\xab\xfc\xf2\x41\x09\xa0\x93\x6c\x28\x51\xdf\x04\x8a\xf2\xf1\x27\x05\x4d\xb2\x67\xf3\xcd\xe3\x38\x80\x63\x23\x91\x3b\x55\x1d\x8c\xe0\x1f\xc7\xa8\x2e\xdf\xa9\x48\x33\x9f\x68\x2c\xed\xb9\xe6\x2b\xb7\x2c\x97\x18\x3b\xf0\xa3\xff\xc9\x03\x5b\x9e\xc4\xda\x81\x6d\xee\xa4\x4b\x53\xd5\xcd\xa6\x01\x98\x70\x45\xfb\xfe\x32\x8a\x07\x1c\x06\x03\x92\xef\xb3\xb2\x79\x2b\x44\x1e\xfb\x40\xff\x2d\x54\xd1\xec\x12\xfa\xc6\x0a\xc9\xb0\xb6\x60\xd1\x68\x1e\x5d\x90\x26\xb8\x54\xf3\x60\x85\xa6\xe5\xd3\x3b\xfc\x13\xea\x30\x1b\xe7\x80\x7c\x82\xb4\x4b\x92\xc6\xf5\xf6\x69\xb5\xc0\x10\xdf\x66\x79\xbf\x58\x6f\x66\xf7\x4f\x93\xa7\x88\x41\xa1\xdd\xa6\xeb\x50\xf7\x6c\x93\xd4\x5a\xe7\xb6\xcf\xc7\x5f\x63\x3c\xd6\x29\x97\x38\x86\x9b\xc7\xb5\x33\xde\x96\x95\x86\xaa\x2b\xdf\x60\xac\xf1\xcd\x6d\x9a\x14\x81\xe8\xbf\x91\xda\xd5\x93\x4e\x9e\x25\xcd\x53\x8c\xe5\xff\x28\x2b\x55\x76\x27\x09\x14\x6e\x53\x1d\x60\xb7\xae\xf4\xa7\xf7\x49\x86\x41\x23\x9b\x5a\x4b\x75\x37\x8f\x77\x8f\xab\xed\xd5\xdd\x6c\xfe\xbb\x6f\xca\xa2\x04\xeb\x1a\x4c\xd9\x4a\x45\xa6\xe9\x4d\xdd\xc0\xdb\xe9\xe2\x3c\x49\x11\x68\xad\x8e\x1f\xb3\xea\x1c\xa8\x7f\x61\xa5\xdb\x3c\xb1\x88\xc1\xba\x5d\xcd\x1e\x3c\x48\xc0\x16\x9c\xe1\xde\xd8\x3a\x1e\x49\x24\xfa\xba\xad\x6b\x67\x05\x8e\xe9\x68\x6c\x91\x11\x45\x54\xff\x56\xd0\xb5\x57\x1f\x73\xd9\xc1\x4b\xdd\x7c\x8c\xf6\x73\x2b\x73\x9b\x16\x3e\x86\xf8\x54\xef\x4a\x3d\x49\x45\x59\xed\x14\x71\xde\xa1\x74\x62\xf7\xed\x55\x5d\xd5\x93\xe1\xd5\x05\xe9\x6a\xf4\x1b\xde\x27\x55\xaa\xa3\x29\x37\xc8\xf0\x5b\xc3\x25\x56\xa2\xbc\x20\x5d\xce\x07\x0a\x93\xfa\xd7\x30\xc6\x58\x07\xae\x5e\x54\xba\xf9\x38\x74\x17\xb5\xa2\xb9\x35\x40\xd4\x32\x7e\x93\x38\x29\x29\x4e\xfa\x59\xda\x99\x5d\x62\xfa\x00\xba\x84\xa9\x6e\xc0\x64\x2a\x02\x93\x8c\x42\xba\xeb\xda\x76\xef\xb2\x81\xef\x44\x92\xe6\x8a\x66\x1c\xdc\xc0\xf7\xd6\x05\x23\xf5\xdd\xdd\x0e\x74\x77\xff\xfb\x6a\x32\x54\x36\x22\xec\xd1\x0b\x74\x14\xb4\x99\x75\x17\x6c\x03\x6b\x55\x6c\x89\xa8\xa9\x3e\xdc\x05\x3d\x0d\x11\x45\x11\x09\xbe\x3e\xc0\xfb\x7c\x17\xbc\xd2\xe1\x13\x8b\x28\xd2\x96\x19\xc7\x7c\xda\x42\xb3\xa9\xef\xe1\x13\xf8\x91\x88\x98\xd4\x58\x8d\xff\x2a\xdb\xd7\x0b\xb8\xc2\xbf\xa2\xb3\x9f\xdc\x8d\xf3\x20\x13\xdb\x3f\xe0\x17\x0c\x09\x22\xe2\x49\x92\xa4\x5e\x29\xf5\x0d\x76\xf5\x61\x82\x10\x4e\xe3\xd3\x34\xe9\xbb\x13\x31\x35\xb9\x8b\x57\xc7\x8f\xe9\xed\x14\xc4\x41\x79\x0d\x47\x65\xac\xfe\x77\xd1\x5e\x13\x91\x48\x49\x12\xea\x79\xf3\xb8\x7a\xf0\x83\x2c\x8a\x1c\xf9\xc1\x7e\x94\xed\xeb\x49\xdc\x55\x44\x31\x4b\xb5\x2b\xe6\x44\xff\xee\xe8\x98\xe4\x2f\xbe\xe6\x3f\xc6\xcf\x17\x0b\xa6\x12\x1f\xdc\x24\xb9\x8d\xa1\x7f\x3e\xe9\x9d\x70\xf2\x79\xfb\x7d\xd2\xaf\xdc\xf1\x83\x27\x29\x45\xa2\x09\x20\xe0\x54\xbe\x3f\x4d\x99\x8a\x28\xe3\x11\x6e\xe1\x07\xd9\x74\x15\x34\x5b\xb6\x3d\x05\x4d\x45\x94\xc5\x0a\xd5\x78\x02\x99\xe6\xf5\xc6\x36\xf5\x5e\x8f\xf6\x5a\x11\x65\x45\x8c\xa1\xa0\x57\xd9\x98\xb9\x3c\x04\xfa\x55\xd7\x9c\x0b\x8d\x20\xf4\x5b\xe8\xee\x3f\x16\xb2\xa9\x4e\xba\x7f\x22\xca\xf3\x38\xb5\x03\xbf\x09\x8c\x27\x39\x98\xce\x8c\x22\x49\x98\xab\x1e\x3a\x89\xef\xce\x4f\xc8\x32\x11\x15\x59\x8e\x71\xc2\x3b\x68\x75\xfd\x06\xbf\x30\xf3\xea\xdb\xb4\xc4\x8f\x54\xea\x7a\x51\x19\x4c\x18\xbd\x78\xda\x7a\x11\x15\x20\x08\xfa\x78\x82\x08\x86\x02\x36\x11\xc9\x58\x66\x0e\x69\xbb\xae\x77\xc3\x8a\x39\x11\xc9\x8c\xa5\x21\x0c\xf1\x15\xf9\xc2\x49\x7c\xe7\x2c\x3a\x21\x22\x25\xf3\xe4\x54\x38\x44\x18\x48\x68\xb6\xd5\x71\x0f\xcd\x49\xcb\x41\x44\x4a\xe5\x08\xa0\xbd\xad\xe5\x6e\x35\x84\xdc\x89\x48\x47\xc4\x7e\x88\xba\x88\xd5\xcf\x28\xf1\x0d\x46\x48\x13\x7b\xa2\x98\x53\x00\x62\x58\xcc\x20\x22\x13\x1b\xa4\xac\x19\xbb\x73\xfd\x7b\x10\xdf\xfc\xff\xa5\x4f\xf7\x8f\xf3\xb0\x9b\x88\x8c\x25\xb2\x98\x90\x84\xbc\xaa\x9b\xa6\x7e\xa7\xc7\xf1\x7c\x24\xe3\xe9\x6c\xf3\x24\xca\x3d\xd2\x89\xd2\x2a\x74\xda\x0c\x59\x80\x3f\xd9\x75\xac\xb4\xa4\xe8\xe9\x64\xff\xc6\xb7\x66\x11\x63\x98\xc3\x9e\x3d\x6c\xd6\xdb\xcd\xe3\x76\xfe\x78\x77\xb7\x98\x6f\xb6\x6c\xf6\xb0\xf9\xb6\xbc\x73\xa5\xda\x82\x45\x82\x8a\x80\x1d\x41\xc3\xa7\xdc\x0c\x82\x45\x69\x86\xd2\x93\xd7\x75\x28\xb3\xfe\xca\xe5\x15\x2c\xca\xb4\xb3\xaf\x7b\xaf\x16\xe5\x50\x66\xd5\xc7\xa6\x9e\x55\x1f\x7c\xfa\xb4\x92\x08\xb6\x11\x82\x21\x3f\xa0\xf9\x2e\x8f\xbb\xae\xfd\x06\xbb\x03\x9c\x11\xc9\xb9\x6b\x58\x16\x03\x09\x2a\x60\xf8\xa2\xec\x3e\x5c\x6d\x9f\xb3\x85\x5c\x37\x9e\x48\x66\x07\xac\x7c\xd3\x51\x3d\xaf\xaf\x14\x8c\x17\x31\x11\x2f\x55\x55\x7d\xac\x34\x22\x69\x9e\x57\x4b\x7f\xcb\x7e\x42\x27\x83\xb0\x57\xdb\x2f\x9b\x65\xe5\x94\xa9\x26\xaf\x16\x67\x2a\x0a\x8c\x86\xcb\xf9\xe3\x30\x0e\x2e\x58\xac\x6c\x9c\xfa\x19\x80\x4f\x7f\x3d\x66\x42\x12\x2c\x06\x8e\xe8\x80\xde\x0d\x5e\xfc\x72\x52\xb1\x7f\x2b\x88\xd5\x5f\x5b\x60\xce\xe7\x20\x1b\x0d\xbb\xdb\xff\xa2\x13\x55\x1f\xbb\x01\xd5\xaa\x60\x09\xe4\xee\xac\xa7\x68\x2c\x0b\xdc\x7b\x82\xa5\x11\x99\xf5\x2d\x10\x2e\xc6\xff\x99\x51\xfa\xd8\xe5\x8c\x36\x44\x3b\x3b\x79\xf3\x34\x06\x4a\x1b\xba\xe5\x36\xab\x0c\x71\x14\x7e\x32\xc1\xd2\x34\xf2\x84\xe0\x8f\xcd\x8b\xac\xca\x96\x78\x4d\xd6\xe5\x7f\x21\xfc\x70\x91\x44\x14\x87\x92\x41\xaa\xf0\x92\x2d\x21\x58\x0a\x12\x63\x93\xea\xf8\xf1\xd8\x78\x16\x70\x7f\x9b\x4c\xe5\xc8\x74\x39\x74\x1d\x1d\x61\xbf\x3c\x4c\xc6\x3f\x67\x51\xc4\x08\x97\xd4\x7b\x81\xbd\x3d\x0b\x72\xbf\x86\xd3\x47\xcc\xb9\x49\x1d\x50\xee\x06\x46\xda\x4d\x9f\xac\x8c\x3c\xcf\x20\xf5\xfb\xa1\xdf\x8d\xae\x3e\xc6\x10\xbb\xc9\x25\x3a\xc3\x5a\x50\xf3\x56\x1e\x46\x9e\x5e\xdf\xa4\x63\x57\x48\x5f\x76\x9f\x8a\xa3\xbb\xce\x05\x23\x95\xae\xae\x7e\x79\xe9\x4d\xf7\x97\x11\xfb\x86\xef\x54\x40\x91\x07\xe6\xba\x1f\x50\xde\xd4\xcd\xf5\xb2\x2a\xbb\xc9\x18\x17\x32\xc7\x82\x9c\x07\xb9\x87\x69\x5c\xd2\x75\x91\x51\x8c\xa8\xf1\xde\x25\xdc\xe2\x5a\x1b\x26\x6b\x7c\x27\x96\x4b\xc7\x43\xbe\x9c\x3f\xe2\x24\xcc\xfc\xb3\xa8\x18\xf2\x41\xd1\xcf\xa1\x6c\x6b\x73\x06\x97\x1a\x3f\x96\x92\x84\x54\xa7\xd2\x93\xbb\x5a\x56\xe3\x2c\xfc\xa4\x37\x28\x3c\x74\xae\x8e\x2f\x54\x02\xfb\x58\xc1\x55\x43\x4c\xfe\xae\x8b\xb1\xc2\x52\xdd\xaf\x59\x76\xb0\x1f\x22\x37\xd8\x78\xa0\x59\xf8\x67\xb4\x0e\x41\x00\x02\xf3\x66\xf7\x61\xe3\x85\x4c\x20\x70\x5e\x12\x9c\xfe\x2b\x34\xae\x60\x60\x0a\x9c\x30\xd7\xd0\x6a\xd9\xa0\xf8\xf6\xe9\x90\x66\x16\x0a\xa4\x62\x81\xca\xdc\x36\x67\x5c\x00\x82\x47\x11\x89\x5f\xd3\xde\xb1\x6d\x3f\xf6\xaa\xde\x0d\x7d\x22\xc1\x23\x16\xa3\x45\xd8\x4c\xd0\xf7\x17\x03\xff\x82\x47\xc2\xe0\x9e\x84\x55\x69\x6d\xf9\xd2\x7a\xa2\xf5\x4f\xba\x27\xba\x20\x48\x7d\x6f\x9a\x5f\xc9\x2a\x88\x3f\x09\x1e\x99\x02\x69\x17\x65\xdb\x42\xd3\x2d\xfe\x73\x81\xd0\x51\x70\x16\xa5\x28\x7e\xe6\x8b\x65\xfe\xe6\xfe\xc7\x19\x13\xc6\xed\xd4\x57\x2f\xbf\x3e\xaf\x6d\x16\x9c\xc5\x29\x42\xc7\x1e\xbe\x0d\x79\xae\x04\x67\x69\x22\xa4\x2f\x91\x73\x70\x28\x82\xb4\xba\x25\x73\xb2\xd6\x39\xcb\x44\xec\x53\xd9\xaf\xf5\xfb\x06\x7e\x75\xe1\x36\x39\xcd\x70\xcf\xc7\x72\xce\x73\x23\x38\x67\x1a\xd1\xaf\xaf\xb2\x1d\x05\x9a\x87\x21\x1b\xc1\x79\x96\x51\xe5\x65\xfd\x12\x68\x6d\x66\xe6\x53\x1f\x26\x5c\x65\x74\x1c\x92\x0e\x58\xf5\x30\x1a\x28\x2e\x99\xc6\x45\xb0\x3b\x02\xc6\xff\x46\x83\xc0\x75\x86\xa6\x8d\x91\xf5\xfd\x90\x68\x40\x70\x11\xa5\x86\x0f\xe6\x4d\xbf\x13\xfc\xb1\xbc\xbe\x94\x26\x11\x5c\xa4\x31\x06\x2d\x30\x7f\xe8\x11\xc1\x82\x0b\x19\xa5\xc4\x45\xdb\x75\xf5\x3f\x8f\xe0\xeb\x13\x05\x4f\x0b\x2a\xd6\xf8\x08\x55\x6f\x82\xa7\x0a\x10\xcd\xdb\x9b\xc6\xf2\xd8\x84\xbe\x59\xce\x30\xf5\x7c\x75\xfc\xb8\x59\x6f\x3e\x0d\x59\x8e\x9f\x28\xcb\x49\xce\xeb\x05\xc3\x28\x5d\xd9\x1d\xcd\x80\x0b\x7a\xda\x59\x65\x96\x48\xa3\x1e\xea\xee\x5f\x03\xae\xab\xf1\x9c\xcb\x85\x55\x6e\xc6\xf8\xe5\x31\x99\x6b\x32\x89\x33\x97\xd8\xe8\x5d\xba\xf1\xaf\xc8\x8c\x63\xec\x41\x96\xcd\x75\x53\x1f\x48\x44\x6c\x3a\x5b\x65\x61\x33\x12\x28\x44\xfc\x09\x9d\xbe\x97\x9f\x5a\xe5\x09\x7a\xa7\x5d\xb9\x87\xb5\x3e\xf9\x2d\xdc\xa4\x0c\x94\x27\x08\x7b\xdb\x78\xd3\x7c\x58\x49\xe6\x7a\x42\x1e\x79\xb5\x51\xd7\xc1\x93\x4a\x7c\x7d\xd8\x70\xd0\x92\x11\x4c\xe6\xad\xfe\x09\x33\x94\x12\xbd\x54\xa1\x21\x38\x58\x83\x92\xea\x0d\xf4\xae\x4d\x83\x04\xd8\x5f\x19\xe3\x97\x65\xef\x04\xb7\xa9\x44\x6a\xd4\x7a\xf7\xb1\x3f\x84\x03\x8d\x5b\x9d\xa3\xdb\xfd\x43\x56\xfa\xc4\x9c\x2e\xb8\x85\x02\x13\x83\x3b\xb0\x5d\x91\x8e\x5f\x5b\x44\x5c\xe2\x31\x42\x7b\x9b\x3f\xa6\xcf\x96\xbd\x88\x12\x09\xae\xc0\xe1\x61\xc8\x2d\x3d\x7a\x43\xc1\x22\x8e\xeb\xf6\x76\x76\xbf\x78\x9a\x3d\xaf\xbd\x28\x54\xdf\x92\x62\x2d\x83\xf7\xce\x9c\x88\xe1\x25\x6d\x5c\x21\x58\x9c\xe2\x69\x85\xe7\x69\xf7\x5e\x6f\x9a\x23\xb2\xaa\x35\xc1\x4f\xec\x4d\x1f\x4a\x30\xf6\xa7\xd9\xba\x9f\xd2\x55\xe7\x25\x91\x7c\x97\xdc\x22\x9a\x67\xf3\xda\xd4\xef\xed\xb2\xa2\xea\xdf\x23\x4a\x68\x0f\xde\x8c\x15\x3c\x26\x71\x2d\x5d\xee\xe5\xee\xa6\xf9\x82\xaa\x51\x08\x66\x20\x76\x29\x7b\x64\xfb\xfd\x7b\x6b\x50\xf0\x84\x79\x91\xba\xcd\x2f\x5d\x4f\xf2\x23\x42\xf0\x94\x3c\x99\xb6\x37\x0b\x06\x14\x25\x42\xf0\x3c\xc2\x2a\x18\xe8\xa7\xff\x80\xfe\x5f\x08\x2e\x39\xee\xc4\xc7\x4a\x79\x4e\x96\xf1\x30\x0a\x6e\x1c\x1d\x60\x43\xed\xed\xe2\xd7\xe1\x93\xf7\x12\x02\x32\xeb\x7f\xc6\xeb\x63\xfa\x48\x86\xef\x93\xa5\xfa\x44\x32\x82\xd0\xb3\x4b\x9b\x83\x10\x16\x22\x87\x94\x72\x74\x54\x3a\xb0\xe4\xf8\x49\x2c\x92\x5c\xea\x93\xe6\xd5\x64\x38\xd2\x2c\x22\x91\xe2\x7e\x88\xc7\x62\x44\x42\xa4\x4a\x23\x40\x6c\x2f\x7f\x5d\xbb\xa2\xe7\xa7\x10\xc8\x10\x29\x10\xbb\x1e\xe2\x17\x7e\x95\xfb\xe3\x9e\xd0\xa3\x3f\xca\xca\xd4\xef\x93\xdf\xc9\x78\x8e\x36\xa0\xe9\x50\x9a\x67\xf8\x2d\xf3\x71\x5c\x73\xe4\xfa\x7b\x59\xc5\xff\xe3\x6f\x93\x12\xd3\xde\xd3\x62\xb3\x58\xf9\x07\xc9\x64\xe4\x19\xbd\xef\xee\xbe\x93\xc8\x56\x1c\x1a\x35\x89\x59\x04\x3f\xfa\xc1\xe3\xdd\xa9\x76\x7d\xfc\x98\x79\xc4\x20\xf2\xe7\xb3\xd4\xaf\x9f\x0b\x09\x0b\x91\xf3\x14\xe3\xd6\x65\x3b\x97\x7b\x7f\xfc\x88\x3c\x87\x2c\x71\x1b\xe4\xae\xd6\x3f\x31\xb2\x55\x23\x1d\x81\xef\xa1\x8b\x3c\x1e\x94\x4c\xa0\x95\x38\xf2\xe3\x44\xc1\x0a\x1c\x2d\x7f\x76\x8f\x7f\xb8\xe0\x05\x56\x42\xec\x03\x62\xeb\xc4\x66\x2d\x44\x91\x92\xa8\xd5\x0e\xf3\x77\x0f\xf5\xfb\x65\x51\x02\x21\x0a\x9d\xa0\x56\x7d\xdf\xd1\xd3\x49\x8f\x7f\x48\xca\xc2\xc3\x1f\x97\xad\xdf\xb1\x3c\x24\x73\xb0\xb0\x25\x64\x48\x44\xec\x94\xba\x1f\xed\xe4\x3e\x8a\x81\x33\x57\xde\x65\x83\xf1\xd4\x33\xd2\xee\xf3\x30\x8f\x30\x91\x15\xf2\x84\x23\x35\x57\x10\xc6\xc7\x14\xd2\x21\xf3\xbb\xad\x91\x9d\xdc\x2a\xa8\xc0\x96\xc3\xc4\xed\x68\x9d\x18\xcd\xb0\xcc\xc0\x39\x5d\x0e\x36\xef\x45\x15\xfd\x5d\x6d\x4e\x52\x5e\x2d\x74\x87\xa3\x3a\x34\xbd\xa3\x38\x7e\x11\x5b\x24\x9c\x3b\x7f\x71\x3e\x2d\xd9\x12\xc2\x5a\x4d\xd5\xa0\xc6\x60\x58\xbc\xff\xb8\xd5\xb1\x9d\xd7\x95\x71\xea\xba\x5f\x3a\x72\x71\x94\x47\xc8\xae\x7c\xbf\x7c\xd8\x2e\x1f\xbe\x2f\xd6\x9b\xfb\xc5\xc3\x66\xbb\x9c\x3f\x3a\xf5\xcc\xcd\x8f\xc7\xed\xd3\xe3\xf3\xc3\xb5\x43\x16\xf4\x97\x30\x36\xcc\xec\x4d\x99\x6a\x2f\x9e\xe2\x71\x64\x25\x3a\xa1\xe6\xd2\xe9\x19\x33\x4e\x12\xc4\x8e\x79\x0c\x49\x74\xda\x41\x78\x30\x66\x79\x8a\x90\x3e\xa8\xcc\xa2\x7b\xbd\x0d\xdf\x25\x66\x5a\xfa\xd8\xf5\x62\x0f\xcd\x0b\x54\xfa\xc3\x6f\x6d\x17\x4f\xd8\x98\x99\xff\x9f\xb2\x2f\x69\x6e\x1c\xc7\xb6\xfe\x3b\xb5\xe8\x05\x49\x0c\x24\x97\xb2\x2c\xa7\xd5\xe9\x41\x6d\xc9\x99\xdd\x5f\xc7\x0b\x05\x86\x0b\x9b\x2f\x29\x52\x45\x52\x1e\xea\xd7\x7f\xc1\x0b\x80\x93\x28\x67\xbd\x4d\x65\x85\x01\x71\x00\x31\xdc\xe1\xdc\x73\x88\xb4\x7c\x94\x85\x7e\xcf\x74\xf3\x6a\xc9\x42\xfd\x05\xdb\x31\x8d\xec\xea\xc5\x30\x67\x5f\x42\x47\x28\xe1\x49\x4c\x7c\x28\x64\xf1\x91\x41\x6d\x6b\x17\xbb\x0f\x4a\x09\x57\x08\xf9\xd9\x7d\xff\xf7\xd0\x00\xa5\x44\x59\x16\xda\x65\xf5\x59\x37\x22\xdf\xfe\x3a\xf9\xba\x54\x42\x29\x8d\x03\x47\x58\xbd\x13\xc5\x2f\x44\x9e\xfb\x26\x43\x71\x16\xdd\x2e\x9e\xae\x97\x8b\xcd\x66\x75\x3d\x42\x9d\x13\xca\x74\xe0\xa9\x3d\x76\x59\x0e\xb7\xc7\x3f\x06\x4e\x5c\xe2\x3a\x71\x12\x21\x62\xa1\xce\x5e\x8a\xd3\xf1\x06\xba\xcb\x73\x16\x26\x16\xed\x88\x28\xab\xa9\x26\x10\xa1\x9c\x4b\x1a\xfb\x40\x11\x92\x28\x62\x7e\x64\x82\x01\x26\x94\x1b\x8d\x2a\x6b\xbb\x4a\x28\x18\x48\xbb\x10\x9a\x10\x47\x16\xc0\x02\xff\xa7\x34\x4a\x43\xd6\x03\x9d\xb6\x47\x28\xb4\x3d\xfc\xc6\x17\x4d\xb9\xfd\xa9\xa3\xe3\x76\xb9\xb2\xe5\xed\x4d\x77\x21\x20\x28\x8a\x5c\xbe\x4f\x4e\x47\x2a\x1c\xf1\xd0\x3d\x54\xea\x54\x7d\x8e\x3e\x85\x4c\x99\x24\xe7\xd8\xf4\x69\xae\xc4\xf5\x56\x71\x10\x06\x5d\x16\x7a\x0b\xea\x84\xfa\x4a\x5f\xaf\x2a\x1d\x45\x3a\x98\x12\x5b\x74\x74\x53\x57\x96\x12\xcf\xf7\x35\x29\xe6\x86\x5d\x7a\xea\x02\x59\xfb\xc0\xcd\xa2\x10\xf1\x34\x75\x34\x72\x18\xb0\xbb\x71\x2a\x01\xdd\x2c\x04\x62\xf9\xf5\x9d\xf6\xd5\xc8\x53\xa2\x40\x95\x75\x62\x4e\x55\xf5\x70\x3a\x3c\x9a\x2b\xd1\x34\x39\x2c\x45\xa5\xbb\x87\x02\x4d\xd1\x5d\x7f\x12\xc5\xf5\xe2\x71\x93\x9f\x26\xf6\x3b\x35\x94\x98\x4e\x1d\xe6\x68\x15\xa5\x46\x27\x39\x35\xcc\xa0\x05\xb3\x6a\x27\x4c\xff\x62\xb6\x95\x85\x91\xb2\x00\xa7\xd6\xc1\xb8\x2b\x87\x1c\x9e\xbe\x87\xb6\x81\xfb\xbd\x57\x22\xb2\x3a\xd3\xa3\x81\x66\x51\xc4\x59\xf7\x18\xff\x0b\xea\x5c\xf1\x98\x30\x12\x06\x8e\xa9\x50\xbd\xf6\xd2\x7e\x37\x65\xb5\x14\x85\x46\x5a\xbb\x79\xc7\x83\x11\x01\x18\xfe\x7d\x29\x4b\x9d\x9f\x3c\x63\x00\x61\x34\xb0\x55\x68\xdb\x63\xbb\x29\x0f\xe7\x16\xa3\x61\x8a\x4b\xd9\x41\x61\xc6\x1e\xf0\xfc\x64\x61\x34\x51\x9a\x74\xac\xfe\x43\xfb\x90\x51\x88\x94\x2f\x37\x72\xe5\xb8\xae\x85\xc9\x34\xd2\xd6\x59\x1c\xd7\x7a\xbb\x76\xae\xb9\x87\x9e\x6d\xd6\xd6\x3e\x09\x13\xff\x63\x0e\x09\xd2\xfc\x1c\x73\xa1\xe0\x01\xde\xb7\xa7\xea\x0d\x3e\xcf\xa0\x53\xa7\xf3\xf2\x1e\xc2\x62\x2a\x30\x21\x35\xe2\x43\x99\xa9\x3b\x99\xe2\x2e\x67\xbd\x7a\x16\x73\xab\x78\xe8\x13\x58\xb9\x9f\x3e\x2c\x89\x88\x87\x05\x0d\x67\x17\x8c\x12\xb7\x84\x25\xdc\x20\x0c\x7b\x9f\xd5\x8e\xdb\xf3\xaf\x73\x28\x95\xef\x9b\x26\xd2\xf2\x09\xc0\x5b\x56\x9e\xea\x21\x2e\x9b\xb0\x44\x12\x1c\x94\xa7\xd5\xf7\x9d\xe7\x2a\x1a\x96\xc0\x12\x96\xf2\x38\x54\x13\x8a\x76\xac\x2e\xc4\x32\xbd\xe9\x8b\x8e\xa6\x7b\x2a\x03\xef\x1d\x8a\x5c\xe1\x11\x0d\xdd\xab\xa6\xda\x22\xb5\x75\x65\x09\xea\x07\x13\x40\x24\x71\xca\xbb\x32\xd5\xdb\xf2\x54\x23\xb7\xcb\x64\x86\x4b\x22\x99\x8d\x1c\xe4\x79\x56\x16\x83\xdc\x27\x93\x3c\xe0\xf6\x78\x6c\x97\xe1\xcf\xac\x68\x37\xa0\x61\x89\x03\x61\x52\x30\x9c\x7f\x96\x16\x74\x09\x65\x9f\x85\x77\x3d\x54\x68\xd9\xf9\x71\x16\xaa\xb2\xd0\xb7\xf0\x71\xf5\xe9\xad\xfe\xd0\xf5\xd2\xdc\x2a\xf5\xae\x76\x37\x23\x87\x65\x68\x67\x4d\xbe\x88\x16\x9a\xf6\x62\x49\xa0\x01\x0e\xdd\x26\xc6\x80\x58\xa5\xe2\xed\xd3\xed\x6f\x0a\x9a\x09\x03\x2a\x3c\xe3\x38\xb2\x7c\x9d\xcb\x75\x12\x1e\x44\x84\x5a\x46\x98\xc3\xb1\x75\xee\x66\x57\x23\x0f\x28\x58\x0e\x54\xfd\x96\xd5\x65\x55\x7f\x07\x07\xaa\x22\x3c\x48\x52\x50\x1e\x05\x53\x38\xcd\xb5\x1e\x0f\xd6\x76\x90\x88\x07\x6b\x97\xeb\xaa\x79\xdd\x95\xcf\xb5\x1e\x99\xf3\xbe\x9f\xb2\x5c\xf2\xf5\xb0\x68\x7d\xd0\x0c\x11\x1a\xdb\x0a\x72\x90\xed\x69\x33\x9c\x12\x3c\x0c\xe3\x30\xed\x4f\xcf\x9b\x2a\x83\x42\xe3\xd7\x1a\x8e\x08\x0f\xb9\x48\x7b\xec\xcf\xed\xe3\xdd\xf5\x85\x2a\x2e\xc2\x23\x99\xa2\x47\x8e\x23\xf7\x00\xef\x58\x7b\xeb\x6f\x17\xe9\x38\xf1\xee\xfa\x55\xd6\x3c\x94\xcd\xea\xcf\x93\xc8\x91\x01\xab\xdb\xec\x39\xa1\x56\xc4\x1a\xf3\x01\x7b\xb9\x17\x43\xdf\x82\x13\x4a\xbd\x83\x8c\x64\x20\x65\x75\x5d\x36\x23\x39\x19\xec\x93\x9a\x4e\x92\xc5\x86\xf4\x07\x4a\x43\x84\x13\x26\x10\xfb\xf7\xa6\x22\xbb\x2c\x69\xef\x18\x72\x12\x6b\x4f\x0d\xb4\x11\x9f\x78\x9e\xf4\x07\x26\xa7\x31\x4b\xe3\x0e\x6b\x54\x34\x56\x7a\x69\x75\xbd\xfa\xf7\x2c\x2e\x85\x70\x0a\x31\x02\x58\xf6\x36\xd6\xb9\xa8\xb1\x1e\x49\x66\xd5\x85\xad\x85\x73\x12\x42\x5f\x1b\x89\x34\xf2\xa7\x91\x16\x97\xef\x17\xb3\x30\xee\x2a\x9c\x9b\x7e\x98\x79\x0a\x48\xba\xf2\x5a\x1e\xc1\x9c\x26\xaa\x2e\xad\xcb\xcc\x91\xb6\x7d\xbb\x7a\xd8\x8e\x16\xd7\x97\x92\x7c\x84\xc7\xee\x6c\xb1\xb9\x07\x0f\x8d\x74\x27\xc6\xb8\xab\x08\x2d\x1f\x39\xd2\xf0\xbc\x5f\x9d\x3e\xaf\xb3\x0a\xfa\x11\x16\x54\xe2\x95\x6c\xc0\xae\xb5\xc3\xdc\xd0\xd9\x62\x3b\x67\x2c\xdf\x88\x2c\xbf\x5c\x84\xe8\x2e\x25\x43\x2b\xde\x60\x31\xc0\xab\x7f\x6f\x1e\x1f\xba\x32\x25\xc2\x55\x90\xa0\xc1\xf5\xb4\x78\xb8\x7e\xbc\xdf\x5f\xfd\x67\xb7\xda\xee\x97\x8f\xcf\x83\x1e\x09\x31\xce\xba\xda\x9c\x8e\xc7\x49\xfc\x91\xeb\x50\x62\x42\x78\x9b\xbd\x14\xad\xa3\x3a\xe6\xd4\x6e\xdb\x81\x82\xcf\x58\xbe\x8b\x01\x81\xee\x85\x41\xd4\x51\x0a\x16\xe6\x99\xbd\xbc\x40\xb5\x73\x4e\xe9\x6f\x65\x4d\x08\xd7\x32\xc5\xd4\xe9\x8b\x38\x80\xa5\x2f\xad\xfc\xd3\xb8\x38\x64\xc7\x11\x40\x38\x44\x81\x96\xc3\x2c\xe6\x80\xaf\x90\xe0\x91\x8d\xd5\x5b\xa0\x33\x25\xf2\xa5\x28\x0a\x21\xb3\x6e\x01\x9a\x88\x78\x0a\x80\x3b\xd0\x7d\x7c\x9b\x1b\x1d\x62\xbc\xa6\x35\x01\x76\x59\x93\x4f\x33\x4f\xb6\x5b\x1c\x04\x36\x99\x73\x05\xcd\x63\xb1\x98\x63\x07\x18\xbf\x5a\x1c\x84\x5a\x58\xb2\x99\x2c\x1f\x17\x4b\x92\x38\x88\x64\x12\x0d\x64\xbe\x36\xa2\x69\xa0\x2a\xfe\x38\x3b\x06\xbc\xb1\x17\x07\x44\x20\xa2\xed\xae\x7c\xc1\x15\x6a\x39\x83\xf4\xac\xc2\x3f\x89\x03\x2e\x11\xcf\xfc\x2b\xcb\xf3\x39\xec\xb7\xff\x77\xe6\xa4\x88\x03\x63\xe5\x75\xef\x4a\x4b\xe1\xd2\x15\x19\xfe\xad\x05\x15\x87\xd4\xca\x03\x7a\xbd\xa7\x6f\xe3\x5d\x2a\x0e\xc1\x12\x34\xa3\x0a\xaf\xf6\xf8\x95\x98\xc4\xc6\xb8\xb0\xc6\x75\x56\x8f\x20\x44\x33\xa3\x41\x79\x4a\x7d\xfd\xd3\x55\x56\x35\xaf\xd3\x09\xfa\xdf\x9e\x5e\xf9\xbf\x51\xff\x2b\x63\xe2\xfe\xe4\x72\x78\x0c\xff\x04\x4c\x2a\x8c\xba\x19\x5c\xa1\x48\xd5\xd8\x88\xc3\xd1\x0b\x78\xb8\x5e\x9c\x10\xc4\xa9\xd9\xd8\x6d\x67\xfa\xc4\x5c\x5b\xe1\xdf\xfb\xfb\x7f\x7f\x75\x0e\xc7\x71\xeb\x32\xba\x3c\xa8\x2a\x91\x2a\xf5\x5e\x14\x27\x91\xf7\x23\x14\x1b\x26\xdd\x66\xec\x58\x04\xac\xbc\xb5\x1d\xc6\xf1\x68\x27\x21\xc7\x8d\xfb\xf6\x24\xb3\xec\x8c\x13\xf7\xc2\x27\x4a\xa8\x86\xa1\x99\x36\xde\x93\x7c\x27\x63\x10\x57\x50\x89\x42\x97\xa3\x7c\xa8\xf7\xfc\xe2\x34\xa4\x98\xa2\x78\xbc\xbb\xb6\xb5\x15\xfe\x0d\x52\x9a\xa2\xa2\xff\x21\x2b\x1c\x09\xc0\x29\x17\x55\xfb\x7f\xb6\x0a\xe4\xbf\xf4\x7f\xc6\xdb\x7e\x2c\x62\x8d\x81\x78\x59\x96\xad\xc7\xd9\x0d\xb7\x48\x15\x5a\x94\x8b\xbb\xbb\xc7\x9f\xfb\xab\xd5\x6e\xe1\x5b\x64\x60\x69\x4c\x50\xea\xa5\x3a\xd5\x43\x56\x4c\x12\x4b\x4a\x2c\xea\xd9\xa9\x10\x2d\xc5\xa0\x0c\x6b\xd6\xd7\x98\x00\x39\xc7\x23\x26\x63\x8a\xd8\x2b\xe1\x2d\x68\x27\x89\x37\xad\x6e\xfa\x7b\x4b\x44\xa6\x61\x4f\xc8\x66\x17\xf2\x73\xa3\xda\x19\xb7\x2e\xb6\xa0\xba\x77\xd0\x02\xa3\xe2\x3e\x8c\xb4\xcd\x5e\x2e\x15\x6f\xf8\x5f\x98\x50\x82\xa7\xe2\x75\xdc\x0b\x0d\x3c\x0c\xc8\x47\x5c\x47\xa5\xec\x97\x6b\x6d\xed\x47\x2b\x92\x3d\xff\xa8\x3a\xb4\x05\x3a\x4a\x14\x7f\x47\x97\xc7\xfd\x0a\x98\xf5\xbd\x3a\xc6\xb7\xf5\x74\x76\x41\x4c\x2d\xa7\x9c\x65\x2e\xfb\x09\xd9\xcb\xeb\x24\xba\x11\x9b\xa4\xcb\xb5\x3a\xdc\x63\x73\xce\x21\xd1\x6d\x09\x46\x8b\x50\xf6\x68\xf3\x73\x77\xab\xb3\x76\xda\xae\x86\x8d\xb5\x91\x4a\x93\x35\xb3\x99\xb1\xd8\x98\x20\x9c\x06\xb2\x43\x47\x79\x42\x92\x20\x8e\xd2\x4e\x9f\xe2\x2a\xf2\x7f\x0e\x49\x88\x19\xef\x63\x55\x7e\x7c\xee\xc4\x2f\x9b\xbe\xbb\x12\x93\x62\x67\x92\x84\xb1\x8c\x88\x2f\x80\xfa\xeb\xaf\x8d\x28\xb4\x40\x63\x76\x1a\xaf\x4d\x42\x41\x30\x05\x75\x73\x82\x1c\xd9\xb5\xae\xa7\x28\x7a\x92\x84\xc6\x96\xfe\xb8\x78\xd0\x52\x78\x07\x25\x21\x11\xc1\x70\xbc\xc4\xc0\xb6\x17\xe8\x5e\x17\xa3\x48\x4b\x42\x54\x2c\xc9\x84\x3f\xd2\x9e\xb1\xe3\xfb\x10\x6d\x4b\x7b\xd1\x0f\xfa\x61\xa9\xef\xcb\x6a\x7d\x38\xfa\x88\x5d\x42\x39\xc1\xa2\x0e\x2f\x02\x5f\xb4\xd6\x31\x1e\x9a\xa7\x33\x65\x58\x5f\x42\xdd\xa7\x14\x12\x1a\x73\xf4\x44\x50\x42\x25\xfb\x0b\xf6\x7f\xa2\x86\xca\x70\xb5\x75\xdb\x7a\xc2\x02\xe3\x48\xe2\x30\x53\x3a\xb6\xdd\xc6\x33\x33\x61\x3a\x41\xa3\x5f\x15\xcd\x7e\x48\x2a\xd7\x0d\x01\x4f\x18\xe6\xc1\xcb\x4a\x23\x86\x71\x1a\xa1\x4f\xb8\x4c\xf0\xa0\xda\x79\xaa\x97\xee\xa3\xc7\xc4\x0a\xdf\x23\xdd\xb0\xb2\x31\xa3\xae\x2d\x09\xc0\x92\x71\x58\x8e\xd5\xcc\x1b\x5b\x49\x22\x03\x84\x87\x39\x15\xec\x9d\xa8\x7f\x75\x4d\x60\x10\x8e\x67\x07\xf1\xdf\x9b\x3b\x0f\xab\x9c\x7c\x8e\x34\x60\x98\xbd\xda\xd7\xd0\xdc\x97\xa7\xe6\x15\xb3\x28\x6c\xda\x2b\x11\xe9\x80\x04\xe0\xdc\xf9\x9c\x0c\x95\xe0\x76\x0e\xaf\x0b\x85\x78\xd8\x99\xe3\x27\x11\x49\xc4\x23\x2f\xa5\xd3\x6b\x60\xcc\xe3\x1a\x12\x61\xa4\x71\x07\xdb\x7d\xd9\xee\xca\x36\x6d\x31\x8b\x24\x48\x64\x60\x4b\x43\xfd\x21\xb5\xb0\x87\xf6\xa0\x20\xb4\xed\xc3\xd1\x7a\x34\x59\x65\x99\x69\xef\xca\x97\x6e\x69\xca\x08\xd0\x08\xc6\x99\xf7\x0a\x08\x4e\xbc\xb7\xa5\xb6\x59\x67\xfd\x25\x9a\x29\x1b\x1e\x79\x81\xe6\xcb\xda\xbf\xf1\x2c\xd0\x92\x68\x0f\xeb\x3c\x15\x96\x22\xdf\x25\x73\xfb\x8d\x26\x01\xa6\x84\x4b\x89\x5c\xe5\xa5\xc4\xad\xb0\xdd\x3e\x6f\x4e\x79\xde\xfe\x61\xad\xc7\x69\xc1\xc4\x48\xce\x2c\x03\x5d\xfb\x89\xf0\xd0\xb2\x2d\x69\xc0\xac\xc5\x98\x49\xd1\x41\x0e\x7c\x93\x12\xc8\x55\xb6\xb8\xbe\x7e\xda\xef\xbe\x7f\xdb\xef\x56\xcb\xdb\xfd\xcd\xb3\xaf\xb1\x20\x69\x00\xd4\x4b\x76\x3c\x41\x8d\x64\x96\xa3\x08\x47\x1a\x12\x40\xeb\x72\x84\x56\x9b\xdd\xe8\x67\x37\xfc\x34\x34\x41\x3c\xd0\x45\x59\xeb\x9b\xb2\xfa\x12\x36\x9e\x46\x91\xd2\x8e\x13\x63\xf5\xa1\xe0\x38\x8f\xd9\x49\x23\x96\x62\x9c\x78\x2f\x45\xa3\x5e\xa3\x7d\xa6\xca\x6e\x53\xea\x4c\x34\xff\x16\x44\x12\x2c\x18\xdf\x5f\x8b\x46\x3c\x75\x70\xec\xf1\x18\xa7\xc4\x58\x60\x63\xa6\x4a\xbc\xcc\xc6\xe3\x8c\x53\x1a\xc5\xcc\xc9\xae\xed\x3e\x76\x25\x0a\xa5\x1f\xa0\xea\xc4\x8d\xfe\x56\xad\x40\x4a\x99\x12\xae\x7e\x71\x55\xe8\xd2\x11\x99\xce\xa7\x5a\x52\xca\x03\xe5\x59\xf6\x5f\x41\xfd\xba\x9f\x94\xe5\xf5\x93\x29\x65\x5c\xc4\x28\xa4\x5a\xdf\xaf\x6e\xfd\x23\xf3\x28\xb1\x27\x2d\x26\x2e\x50\xd8\xf7\xf3\xc2\xad\xb8\xd2\x68\x79\xbe\x43\x66\x13\x9b\x36\x83\xef\x5b\x21\xc1\x63\x6e\xbb\xb8\x5b\x6d\xf7\xd7\xcf\x4f\x83\x82\x66\x92\xc6\x49\x82\xfc\x56\x47\xac\xae\x7b\x3c\x42\x3b\xe3\x07\x79\x9f\x34\x21\x40\xfb\xfa\x13\x7b\xfd\x76\xfe\xec\x0e\x30\x9c\x0b\x13\xb3\x65\x32\x27\x12\xad\x2c\x4a\x02\x65\x31\xab\xe7\xfa\x24\xaa\xac\x9c\x0f\x28\xa4\x89\x11\x42\x0c\xd0\xe2\xa9\x7f\x94\x94\x68\x44\xa4\xe0\x8c\xf9\x3b\x46\x8b\x3f\x75\xd2\x34\x09\x31\x2d\x2d\x4f\x55\xb1\x3d\x63\xeb\x6d\xdb\xd3\x30\xf1\x6c\x77\xc8\x7c\x61\x03\xaf\x87\x33\x42\x02\x92\xa6\x69\x84\x8b\x12\x79\x5e\xde\xcb\x0e\xac\x9c\xa6\xca\x02\x43\xb1\x9e\x63\xc8\xee\x35\x79\x3f\x61\x04\x26\xe1\xbe\x2d\x7f\xf8\x9f\xca\x10\x70\x95\x2d\xff\x75\xff\x03\xb7\xf8\x65\x56\x59\x03\x06\x45\xf7\xea\xae\x1f\x93\x58\x31\x08\xcd\xab\xab\x6d\xda\xbe\x8b\xe3\xba\xb8\x68\xe6\xa5\x32\x36\x32\xec\x73\xb7\xd9\x1e\xad\xc7\x32\x2f\x87\x48\x4e\xfb\xdf\x30\xf0\xbf\x31\xd2\xe6\x7b\x33\x4b\x0f\xd8\x5c\xe0\x54\x75\xdd\x55\x14\x8e\x74\x17\x36\xb6\x5e\xa3\x7b\x68\xa5\x00\x13\x03\xee\x78\xba\x2b\x9b\xb5\xae\xcf\x34\xce\x5d\x67\x4d\x18\xbe\x61\xeb\x64\x5e\xc3\xa1\x54\xa3\xd0\x5e\xaa\x53\x2b\xb9\xb7\xdc\xae\xb6\xa1\xbf\x01\x70\x40\x93\xf3\xd1\x01\x82\x47\x14\xa9\xbe\x4f\x6a\x84\xcb\x36\x5b\x4d\xa5\x85\x2b\x9b\x1f\xa6\xd6\x53\x50\x21\x9e\x63\x79\x59\xfe\x3a\x1d\x27\xdb\x8b\xa1\x11\xde\xe6\x66\x7d\xf5\x7d\xe1\x77\x60\x11\x50\x81\xf1\xb2\xcd\xf3\xd5\xdd\x7a\x39\xaa\x44\x27\x22\x24\x44\xa4\x83\xd8\xec\x62\x32\x99\x44\xc8\x15\xca\x77\x4f\x15\x88\x7f\x66\xcd\xeb\xe3\x18\xea\x2d\x42\x49\x65\x34\x67\xc3\x89\x42\x7b\xbb\x6f\x7e\x16\x88\x50\x47\x96\xbe\xd6\x51\xc9\x7e\x59\xf1\x36\x1c\x70\x11\x1a\xab\x24\x81\x87\xf0\x13\x7a\x8c\x36\xc8\xe2\x40\x49\x97\x8b\xb7\xdd\xd5\x46\x9f\x41\x44\x34\xc6\x60\xde\xff\x2b\xcb\x11\x0c\xd4\x37\xc7\x16\x4f\x7a\x2a\x30\x88\x70\x9f\xf5\x15\x34\x82\x08\xa9\xa6\x92\x80\x97\x8b\x13\xbb\x6f\x2a\x88\x04\x63\x01\x20\x05\x54\x5b\x55\x76\x19\x66\x41\x34\x20\x34\x6e\x75\xbf\x58\xf6\x1e\xf6\x85\x80\xd8\xe4\x45\x28\x35\xb8\xa3\x74\x9e\x76\x59\xfd\x2c\xab\x5f\xad\x5f\xe4\x2f\x4f\x53\x93\x7a\xe2\xc9\x41\x75\x26\x11\x2c\xa0\x98\x66\xb7\xb2\xfc\xdd\x5f\x89\xe5\x61\x5a\x2f\x1f\x7f\xae\xff\xdf\xe2\xe9\xfa\xb7\x15\xb0\x44\x30\x1e\x71\x57\xfb\xed\x83\x39\x17\x02\x47\x82\x71\x8b\xe5\xee\x34\x99\x57\xed\xcd\x07\x3b\xbd\x60\x29\x0b\x3c\x4f\xed\x6d\xf6\xf2\x0a\x76\x7c\xbd\x28\x23\x11\xcc\x58\x9b\xb0\x46\xa6\x7d\x09\xd5\x2e\xbb\x84\x5c\x14\x3c\x50\x56\x00\xa3\xb8\x2b\xad\x28\xec\x39\x7f\x3c\x11\x3c\x0e\x10\xc2\xd9\xe5\x3f\xbe\x74\xaf\x05\x8f\x05\x02\x56\xeb\x93\x74\x38\x07\x1f\x49\x9f\x7f\x88\x24\xb0\xc1\xf7\xdf\x86\x4f\xbe\x46\xb9\x89\x24\xa6\x48\x84\xbf\x28\x9a\xec\x46\xfc\x82\x3b\x21\x21\x1f\x2f\xa4\xc9\x0f\x5c\xc4\x69\x9f\x97\x2f\xed\x49\xf0\x2d\x33\xcd\x90\x82\xcf\x75\x4b\xa5\x09\x48\x47\xe8\xb0\x3e\x0c\x99\xa0\x46\xab\x50\x50\x8a\xb9\xc2\x7d\x6b\x8e\xeb\x1d\x92\x2e\xb5\xb6\xc7\x55\x59\x36\x97\x29\x82\xc6\xcf\x84\xa3\x37\xa4\xc8\xb6\xb4\x1b\x1b\xf1\xb9\xbe\xf4\x1a\x32\x06\xb7\x7d\x41\x0f\xa8\x17\x2a\x8a\xc9\x80\xac\x65\x0a\x88\x10\x8a\x68\x74\xc2\x11\xd2\xd3\x6b\x16\x12\xa1\x52\xc0\x93\xf3\x28\xaa\x1a\x5a\x53\x63\xd7\xc9\x10\xfe\x37\x0c\xfb\xb0\x5e\x18\x74\x6e\x23\xfd\x9f\x29\x05\x11\x11\x4a\x59\xdc\x47\x05\x4d\x25\x5a\x9f\xbd\xbb\xbe\x8b\x7d\xe0\x2e\xd7\x88\x7c\x80\x3b\x73\x3d\x74\xa0\x71\x8d\x8d\x2a\xe2\x2e\x66\xec\xfc\x8f\x94\xa2\x7c\x40\xcd\xda\x3a\x13\x4f\xad\xef\x6b\xfd\xba\x5b\x91\xbf\x75\x75\xcc\x44\x40\x44\x11\xe1\x91\xd5\x73\x1a\x77\x44\x00\x13\x38\xe5\xef\x44\x6d\x6b\xbf\x54\x33\x5c\x84\x00\xa9\xe9\xec\xf5\xda\x0a\x42\x8e\x6a\xa2\x84\x81\x30\xb2\xe9\x92\x53\xb5\x29\x9b\xd5\xc7\x31\x1b\x12\x75\x12\x61\x8c\x45\xb6\xb8\x82\xde\x2b\xf1\x62\xcb\x76\x6f\xce\x8a\x0b\x64\x10\x4b\xe9\x08\x2b\x57\xcd\xeb\x06\xaa\x61\x48\xd9\xf5\x09\x99\x8d\xdf\x22\x68\x35\x2b\x6a\xa8\x9a\xbd\x2a\x8b\x46\x64\x45\xed\xb5\xa0\x88\x0c\x79\x84\x55\xb9\x65\x71\xdd\x09\x14\x11\x49\x02\x82\x2f\xbb\xd0\x6f\xed\x32\x1d\x06\xf2\x24\x61\xb6\x02\xfb\xad\x6c\xce\xd0\x72\x92\x88\x14\xc1\x3f\x07\xf1\x31\x0e\xe6\x4a\x1a\xd9\xaa\x00\x5f\x45\x9a\x97\x42\xcf\xd9\x69\x92\x46\x8a\x5a\x4a\x95\x47\xcb\x6d\x54\x7c\x92\xaf\xb3\x1d\x92\xc6\x04\xe5\x9e\x73\xcb\xdb\xde\xe5\xdd\xa7\x57\x06\x85\x87\xd8\xd2\xeb\xfd\x0e\x26\xb9\x64\x81\x0a\xa8\xd3\x49\xcf\x06\x7f\x66\x01\x32\x88\xee\xae\x3f\x7e\x5f\xfa\x20\x19\xb7\x99\xc7\x15\x2a\x0f\xdf\x2f\xfe\xbd\x5f\x3e\x3e\xec\x9e\xd6\x57\xdd\xe5\x12\x86\xd1\xbb\x62\xdb\xc0\xb1\xee\xfe\x2a\xac\xd8\x89\x6c\xcd\x86\x9b\xb2\x5a\xbd\x41\xf5\x59\x16\xdd\xd8\xf1\x20\xc0\xf0\xf0\x7e\x8c\x56\xfe\x7a\xd7\x95\x5c\xc4\x88\x05\x71\x87\x32\x1a\xdc\xe3\x1e\x31\x03\x20\xbd\xd8\xac\xab\xb4\x68\x47\x65\x28\xfc\x4f\x64\x1c\x5b\x96\x1b\xac\x21\x38\x2f\x25\x92\x09\x4d\x51\xf5\xb7\x7b\x3e\x4f\x60\xfc\x95\xfd\x29\x13\x19\xe1\x2e\xf5\x0e\xd9\xd5\xe9\xb3\xbe\x2d\xdf\xef\x45\xf1\x39\x27\xcf\x4d\x64\x1a\x27\xc8\xe7\x81\xf4\xab\xc8\xcf\xfa\x47\x07\x7a\x9d\xc2\x5f\xa5\x08\x09\x66\xd3\xda\x55\x8f\xb0\xbc\xc9\xc5\x84\x08\x52\x4b\x51\x6f\x05\x2f\xd1\x20\x9a\xcd\x8d\xb9\x1f\xc8\x34\xa6\x61\x07\xa8\x6a\x37\xf0\x33\xfd\xb0\x91\xc9\x29\xa5\x4a\x30\x5a\xd6\x64\x50\x75\x8a\x43\x44\xea\x28\x16\xd6\xb7\x6c\xdf\x11\x33\x66\xf7\x16\x9d\xda\xf5\x10\x2c\x10\x1e\xb6\xd0\x3c\xc0\xfb\xae\x1d\xc7\xac\x98\x45\xd8\x4e\x6e\xaa\x55\x84\x26\x9f\x23\x5f\x44\x3f\xc7\x06\x67\xc6\x6f\xa3\x41\xe0\x4c\x6f\x9d\xaa\xf5\x72\xb1\x7c\xec\xe5\xf5\x5d\x0f\x08\x62\x90\x9e\x5a\xc8\x88\x53\xee\x0c\x0a\x98\x5e\x0a\x42\x40\xae\xcd\x1f\xeb\x1f\x8b\x19\xbb\x50\x82\x92\x0c\xcd\xfe\xc9\xef\x0c\x97\xb1\x8b\xc6\x1e\xcb\x5a\xe4\xe8\x69\xff\xce\x8c\x90\x26\x4e\xc0\x45\xab\xae\x16\x8b\xc5\xf3\x25\xa2\xb4\xf9\x90\x88\x34\x29\xc1\x30\x80\x29\x2b\xd5\x49\x52\x62\xf5\xdf\x78\x1c\x8d\xd6\xd2\x33\x5a\x7c\xae\x47\x1c\x56\x44\x1a\x88\x99\x4d\x3a\x0a\x1b\x6c\x5c\xab\x72\x8a\x65\x53\x01\x18\xe8\x83\x37\xe5\x48\x77\x61\x3e\xb8\x7f\xc9\x6a\x1d\x4f\x44\x15\x32\x6e\xc8\x80\x23\xe7\x3a\x7b\xc9\x1a\x91\x2f\xaa\x66\x0b\x79\x9e\x15\x2f\x5d\xa5\x5c\xf7\xda\x2a\x64\x86\xba\x0a\xcf\xbb\x4c\xc8\x2c\xcf\x3c\x7f\x3e\x51\x21\xb7\xc8\x91\x27\xa8\xcb\xfc\x6d\x02\x89\x57\xa1\x8a\xb1\xe0\x0c\x25\x79\xb2\xa2\x5e\x1d\xb2\x19\xbf\xc1\x75\x8e\x02\x2b\x1d\xd5\xf4\xc1\xde\xb0\x6b\x8b\x29\x3a\x71\x59\xbd\xe9\xc0\x4b\x8a\xc4\x12\x0f\x04\x0c\x91\xcc\x18\xa4\x43\x38\xa8\x62\x01\x53\xbd\xf0\xf9\xba\x68\x17\xab\x15\xcb\xff\x6a\x20\xbb\x07\x60\x81\x85\xee\x2d\x4b\x09\x16\x7d\xb2\xec\xa8\x62\x88\x62\xa1\x42\xa8\xf9\x7e\x55\xbc\x95\x59\xfd\x55\xb8\x5a\x31\x12\x2b\xcb\xa3\x58\x34\xc9\x1f\x83\x27\xe4\x34\x41\x5e\xb4\xd6\xbe\xd3\x30\x66\x83\xc5\x52\xd9\xe9\x71\xa4\xb8\x88\x30\xd3\x70\x95\x99\xaa\xac\x9b\x70\x78\xca\xaa\x98\x52\x44\x51\xe5\xe5\x4b\xeb\x9f\xc0\x40\x09\x6a\x38\x1f\x55\x9c\x04\x58\x81\xb5\x40\x24\x54\x56\xbc\xb8\x52\x9f\xae\x38\xb0\xf7\xa8\x54\xac\xa3\xd8\x1a\x78\x50\x9c\x8e\xb3\x14\x0e\xf3\x5a\x82\x93\x59\x18\x03\xf3\xa5\x49\xfb\xda\x82\x6a\xcc\x29\xdf\xbf\x4d\x3e\xa4\xeb\x9d\x30\xc0\xb0\x89\x2a\x0f\xc7\x39\x0e\xfa\xc9\x00\x27\x86\x20\x23\x06\x46\x63\xee\xb2\x7a\xb0\x3b\xaa\xc4\x58\x59\x7e\x28\xf4\x06\x35\x37\x06\x82\x05\x44\xa5\x2c\x46\xf7\xec\x55\xe4\x8e\xf2\xc7\x19\x60\xd3\x28\xe1\x78\x96\xa7\xcc\x62\x4b\x1d\x85\xdb\x30\x55\xe5\x7b\x08\x7b\x68\x77\xee\xc8\xa0\x5a\xe1\xc2\x7a\x9d\xdc\x43\x44\x29\xda\x6b\x58\xfa\x8c\x7c\x3a\x3f\x7b\xed\xfa\xae\x8f\xb4\x7c\x0d\xae\xc8\x08\x9f\x66\xf5\xe7\x16\xbf\x44\xd7\x89\x71\xe4\xd0\x46\xcb\x65\x12\x0c\xb8\xe4\x23\xfd\x26\x7e\x3e\x47\x26\xe1\xef\x16\xd3\x88\x59\x68\x68\xa5\xb2\x1a\xf0\x14\x9a\xe6\xc1\x94\x48\x22\xaa\x06\xc1\x92\x5e\x4a\x6f\xd2\x4f\xe8\xc0\x16\xa4\x2e\xb3\x26\xfb\x6b\x5a\x1e\xa4\x64\x98\x60\x49\x86\xcc\xf4\x63\x71\x55\x01\xe8\xac\x78\x19\x32\xea\xd1\xe0\x1f\xf6\x1f\xff\x83\x44\x21\x21\xb4\xd0\xda\xeb\x12\x4e\x2f\xa9\xac\xa0\x8e\x65\x6d\x1f\xc7\x62\xbf\x9e\x86\x12\x62\x69\x5f\xdd\x16\xf0\x0a\x4f\xbf\x5c\xb7\x76\xd4\xb6\xe9\xf4\xde\x89\x52\x11\x45\x9a\xc6\x83\xf8\xd8\x94\x65\x3e\xac\x79\x57\x8a\x27\x9e\x32\x6a\xa4\x7c\x30\x7b\x82\x2b\x25\xa8\x55\xb7\x45\x26\x6c\xc7\x18\x32\x87\x95\x55\x4a\x58\x9d\xca\x8e\x80\x63\x5b\xe6\x7a\x54\x1d\xa3\x94\x48\x98\x33\x25\x30\xd0\x38\xc6\x3a\x2b\x25\x84\xd5\x3f\x38\x0c\x96\x90\x92\x14\x43\x7e\xd7\x59\x6d\x23\xde\xe0\xf0\x0e\x2e\x4d\x03\xe7\xee\x96\xff\xa5\x8a\x9c\x90\x53\xad\x44\x75\x5d\xaa\x53\xbb\x57\x95\x9b\xb2\xfa\xd7\xfd\x78\xc7\xd2\xa1\xea\x54\x84\xdc\x99\x88\x45\x26\xef\xe3\xcd\x4a\x33\x6a\xd9\x43\xa0\xd0\x57\xe5\xe9\xe5\xb5\xf9\xca\x98\x54\x10\xd9\x28\xd3\xde\x9e\x10\xe8\x38\xbc\xbd\xdc\x66\xed\x40\x9e\x79\xda\xfe\x37\x34\xf0\xc5\x98\x5b\xf5\x6a\x0f\x50\xc4\x7f\xcc\x65\xd6\x14\xc4\x56\x6f\xe7\xae\x2c\x5e\xec\x03\x75\x83\x31\x80\xb6\xb0\xe9\xc0\x80\x73\xfb\x5e\xc0\xf2\xc3\x6f\x5b\xa7\xc8\xfb\xe4\x0a\x80\x53\x2f\xb5\x7c\x98\x78\x79\x3a\x32\x61\xec\xcd\x30\xd1\x88\x7d\xe4\x13\x9b\x3a\x32\x49\xe4\x92\x14\xff\xfe\xd7\xf3\x68\x7c\x35\x09\x98\x4f\x2d\x5d\x21\x76\x43\x6f\x9c\x95\x55\x9f\x0b\xb1\x10\x4d\x68\x80\x64\xa1\x76\x9a\xdb\xb0\xf1\x50\x8d\xe5\x1f\xe3\x8b\x27\xc2\x73\xd7\x5d\xed\xae\xfc\x94\x1a\x77\xd1\xd4\x93\x5f\xf7\xfb\xe4\x6c\xd0\x58\x13\xa3\xbc\x41\xd7\xe4\x70\x07\x85\x1e\x45\xb7\xa7\x1b\xda\x59\xe4\x7b\xe8\x84\xb4\x77\xd5\x91\xaf\xc0\xac\x3e\x87\x0a\xa5\xbe\x47\xac\xc3\x21\x75\xd7\x22\xcf\xe7\xa8\x57\xfc\xf6\xa7\x69\x6a\xd1\x6d\x4d\x47\x16\xd1\x0b\x79\x5d\xc2\x8a\x8f\x9e\x48\xda\x0a\x21\xf0\x45\x3e\x37\x28\x81\xed\x3f\x22\xa3\x14\x1f\xf8\xe6\x69\x37\x5b\x5a\x3f\x1a\x55\x2e\x99\x47\x00\xba\x25\xb9\x19\x56\x5e\x8d\x27\x9d\xe6\x4a\x46\x2e\x7e\xdd\x41\x24\x08\x1d\x7f\xa7\x38\xb5\x0a\x1d\xf5\x49\x5a\x3d\x06\x7d\x51\xa8\x79\xf4\x56\x71\x1a\x61\x62\xc9\x2a\xc7\x5a\xa0\xc6\xf5\xa0\x22\xc1\x77\x93\x96\x1a\xcc\xb3\x92\xb7\x27\x75\x4f\xdc\xe2\xc7\x20\x56\xdc\xc4\x1e\xad\xe1\xf8\xf7\xc6\xeb\xfc\x3c\xb0\xa3\x63\xa0\xc8\x41\xb9\x5a\x3c\xdd\xfd\xc7\x7b\xd8\xcf\xbb\xc7\xa7\xfd\x8f\xd5\x76\xb7\x7e\xf8\xb6\xdf\xac\x9e\xd6\x8f\x3e\xd4\xaf\x13\x92\x08\x6b\xfd\x1d\x3f\x2b\x84\xb5\xf8\x86\xd4\x22\xdf\xda\x41\x3d\x35\xa5\x8f\xe3\x9f\x71\x06\xe9\x34\x8c\x11\x91\x98\xd5\xab\x3c\x7b\xc9\x64\x0e\x37\x65\xe5\xc4\x17\x26\xef\x9d\xc6\x22\xea\x99\x86\xc7\xc3\xfa\x9b\x28\xa6\xbf\x82\xb4\x44\x69\x6e\xe7\xfb\x4d\x1a\x47\xa7\x00\x18\x1c\x58\x96\xa7\xaa\x06\x6f\xf6\xcd\x5f\x5a\x06\x29\x0a\xbb\x64\xad\xa1\xab\xce\xaa\xa6\xff\x96\xc8\x66\xa7\xa8\xe6\xaf\x49\x2d\x93\x7e\x05\x4d\x95\xc1\x1b\x6c\x32\xb0\xcc\x86\x73\xd5\x2f\x5a\x0a\x83\xb2\x25\xb6\x3a\xe0\x07\x12\xd7\xbe\x8c\x38\x58\x5c\x47\x4d\xac\xec\x77\x01\xef\x36\x60\xa7\xa6\x74\xcd\x03\xff\x40\x6b\x99\x62\xac\x4f\x42\x53\xef\x9b\xc1\x09\xac\x81\x71\x4c\x6b\xfb\x22\xe1\xf7\x6d\xa9\x32\x68\x3e\xc7\x8b\xc1\x04\x12\x71\x5a\xb5\xc3\x93\x5b\xb6\x89\x3f\xc6\x72\xcc\xe3\x30\x83\x36\x51\x8a\x54\x3b\x47\xb4\x32\xd7\xbb\xc7\x3d\x14\xc3\xc0\x3c\x84\x4a\x62\x56\xa4\xaa\xad\xe9\x61\x61\x28\x53\x1b\x60\x78\x7a\xfc\xe6\xff\xfc\x75\xc1\xa0\x68\xd7\x9b\xc5\xf9\x64\x65\xb1\xb7\x34\x34\x13\xc3\x15\x22\x62\xb7\xc4\x6d\x53\x95\xc5\xcb\x77\xf0\x26\x0b\x44\x42\x24\xc4\x15\x8d\x42\xdd\x3c\x01\xae\x3f\x8b\x64\x71\x5d\x88\xe2\xb8\x85\x20\x88\xde\xd7\xc6\xa2\x7d\x57\x2f\x2c\x11\x83\xeb\x48\x43\x2b\x10\x2d\xb4\xc6\xc3\xb3\xfb\x7b\x12\xc7\x4e\x3c\xf4\x8c\xd4\x76\x6a\x3e\x00\x55\xb6\xfa\x7a\xff\x32\x64\x62\xf3\x97\x62\x2a\x44\xa7\xbb\x56\x15\x40\x51\x37\x7d\xfd\x02\xf0\x88\xa3\x85\xe7\xa3\xe3\x5f\x93\xf0\x01\xe7\x54\xf9\xc4\x9e\x10\xf5\xe2\x98\xd9\x0d\x6c\xf6\x7c\x02\x9e\x58\xb2\xdb\x17\x68\xb6\xd9\x4b\x01\xd5\xa3\x71\x43\x31\x02\xa6\x9c\xc6\x84\x93\xfd\x5e\x09\x71\x18\x63\xad\x17\xda\x9f\xbb\x4c\xfd\xea\x73\xc2\x90\x50\x85\x66\xb3\xaf\x11\x6c\xad\x66\x3d\x68\x44\x47\xbf\x9b\xb5\x4f\xf0\x96\xd5\x67\x80\x61\xd7\x3b\xa5\x0c\x9d\xc5\xbb\xf2\xa5\x93\x0e\xfb\x32\x16\x02\x22\x8c\x68\xd8\x57\xdb\x21\x14\xc7\xdf\x5b\x50\xc5\x3b\xf7\xee\x9c\xb6\x06\x84\x0a\x2c\x13\xa9\x0d\x0d\x39\x0b\x7d\xf4\xc1\x64\x44\x6d\x1d\x4c\x76\x38\x7a\xd9\x92\x79\xb6\xf4\xf1\x80\x2b\x62\x90\x55\xe9\xdd\x27\x0a\x5d\x56\xdf\x7d\x1e\x14\x00\xe8\xa7\x50\x6f\x2d\x82\xd2\x22\x6a\xdf\x67\xbd\xdb\xde\xfb\x87\x50\x90\x1a\x5b\x16\x63\x55\x4d\xee\xa6\xda\x2e\x04\x74\xc0\xf1\x7e\x18\x78\x0d\x06\x1c\x5c\xa0\x4d\x18\x46\x9d\x59\xe4\x38\xd1\xc6\x3f\x06\x4e\x02\xd6\x6d\x65\x3d\xb3\x40\x56\x16\xde\xfe\x9d\x87\x5d\x01\x48\x0b\xde\x40\xc5\xcb\xf6\xd1\xf6\x26\x6d\x67\xd4\xde\x8d\x8a\x7f\x08\x30\x29\x66\x04\xf6\x99\xa7\x81\x9a\xb8\x40\x26\x0c\x34\xb2\xaf\xfa\x7c\xda\x57\xa3\x6b\xc2\x30\x40\xcb\x0c\x9a\x57\x37\xa0\x76\x47\xfa\x3e\x28\xa4\x1b\xfb\x25\x43\xda\x6b\x62\x42\x2e\x30\x45\xf2\x56\x0e\xc3\x40\xfd\x57\x30\x61\xc2\xc3\x9e\xe8\x7c\x67\x99\xd5\x9d\xca\xee\x85\x75\xe9\x16\xcf\xac\x6b\x6e\x42\xc9\xf0\xed\x96\x65\xf1\xd2\xfe\xa8\x35\xa0\xfd\x17\x32\xa1\xb6\xb4\xec\x15\xe6\x20\x47\xe5\x56\x73\x8f\x06\xd4\xd5\x22\x14\x2f\xb9\x98\x61\xa7\x40\x22\x74\x97\xa7\x5e\x34\xce\xfb\xc1\x55\xaf\x27\x0b\xfd\x02\x64\x7f\x86\xd3\xce\x44\x26\x40\xb5\x78\x5b\x78\xaf\x32\x51\x7d\x7a\x1b\xde\x90\x30\x61\xc4\x43\x83\x3f\x77\x88\xbb\x1b\x06\xad\x0c\x25\x31\xfa\xcb\x47\xc0\x0d\xa2\x8f\x18\x4c\xb6\x29\x43\x59\x82\x4c\x59\xea\x53\xe5\x96\xac\x63\xef\x6f\x42\x93\xc0\xea\x57\xfa\x94\xc7\x28\x27\x65\xa8\x00\x43\x06\x6a\xed\xd7\x8b\x42\xaf\xed\x51\x32\x21\xd5\x34\x2c\x4a\xb8\xc3\xfe\x6e\xa0\xaa\xcb\x42\xe4\x88\xc8\xb1\x4e\xe7\x05\x50\x99\xe1\x26\xd0\xb1\x9b\xe9\x96\x30\xce\x35\xc4\x01\x47\xe4\x0c\xe2\x49\x61\xaf\x44\x3e\x89\xd2\x9b\x98\x33\xb4\x14\x0c\x34\xea\x15\xd9\xe4\xea\x9b\xb2\xba\x87\xaa\x5d\x92\x93\x85\x6c\xe2\x54\xf8\x72\xa9\x6b\x90\x9e\x2a\x27\x2b\x5e\x5c\xa1\xfc\xf8\xd2\x69\x44\x03\x0b\x56\xb1\xa5\x52\x93\x8b\xa5\x3c\x15\x9d\x16\xae\xc7\xac\xb9\x52\xcd\x5e\x34\x62\x66\x92\xa5\x2a\x70\x39\x24\x63\x44\x8e\x6a\x33\xae\x45\x84\x16\x89\x2a\x4f\xf9\xaf\x85\x15\x2b\xed\x9c\xdf\x3f\x26\xe7\xbb\x11\x91\x22\x5e\x43\xdf\x96\xc2\x0d\xd8\x2d\xbe\x36\x1e\x8d\x50\x14\xf7\xad\x76\x44\xd5\xca\xd9\x23\xe3\x2e\x32\xb5\x55\x69\x35\x34\x43\x27\x69\x72\x21\x29\xa4\x64\x7e\x44\x35\x32\xa6\xb4\x8e\xe4\xc7\x84\x0d\xd7\x48\x63\xc3\x67\xdb\x9b\xdd\x76\xe5\x81\x51\x46\x31\xc2\x75\x47\x42\xb4\xb4\x19\x67\x31\xf4\x9c\x7c\xc7\xd8\x20\x38\xe6\xb1\xd2\x59\xcf\xee\x67\x14\x10\x7f\xf7\x25\xbd\xf1\x75\x5b\x9d\xa2\x69\xd9\x1e\x2b\x17\x36\x21\x9d\x44\xc8\xfe\xda\x0c\x80\x66\x13\x03\xfa\x3c\xf2\x35\xfd\x04\x1a\x22\xa4\xc7\x72\xc2\xb6\xd9\xcc\x93\x43\x18\xa1\x29\x81\xa6\xd3\xe8\x84\x34\xc0\xac\xfa\x32\x1a\xa2\x3f\xb3\x46\x57\xe5\x3b\x8c\xaa\xae\x0d\x18\x22\xc8\x00\x87\x32\x6f\xdc\x1b\x13\x06\x68\xea\x3d\xd7\xf0\xaf\x93\x28\x9a\x76\xfe\xf5\x05\x1f\x34\x08\x52\x9d\xa6\xdd\x31\x85\xa8\x60\x0f\xc4\x1c\x7d\x75\x1a\x04\x82\xe0\x4a\x34\x59\x91\xd5\xaf\xd7\x9d\x09\x45\x83\x40\xdb\xca\x8c\x4f\xa8\x7f\x94\x0d\x6c\x7d\xbe\x8a\x06\x81\xd1\x98\xf8\xb7\xa5\x91\xa1\xff\x73\x18\x68\xab\xe8\x06\xed\x47\xd8\x65\xe3\x8d\x8b\x06\x21\x17\x8a\xf8\x09\x86\x35\x47\x18\xbc\x1e\x4d\x9c\xb6\x97\xc4\xba\x42\x9f\xae\xda\xac\xb6\x8f\x97\xb1\x19\x34\x88\x18\xe3\x49\xaf\xf5\x3b\x64\xf2\x99\x74\x4c\x21\x75\x18\xdf\xfb\xb2\x68\x57\xef\x13\x34\x27\x57\xcb\xe5\xdc\x16\x1a\x90\x90\x9a\x8e\x1e\xd7\x4b\xe4\xf6\xe1\x64\x1a\x50\x6a\x0b\x79\x3e\xac\x88\x81\x9d\x79\x75\xd7\xaa\x43\x84\x8f\x0f\x78\x36\x47\x15\x2d\xe3\x98\xc5\x60\x76\xb4\x3f\x35\x9d\x84\xee\xea\xe3\x88\xdc\x14\x23\xfe\xca\xf9\xf7\x67\x24\xc4\xe8\xc5\xfd\xff\xc1\xa3\xfc\x3f\xe1\x65\x68\xc0\x84\x4d\x10\x60\x2e\xf4\x9f\x65\x56\x80\x76\xa0\xf9\xf9\x47\xe2\x94\x22\x00\xd6\x49\xbe\xb4\xc6\x1a\x1e\x98\xed\x7e\x95\x15\xae\x36\xe6\xf7\xc2\xe5\xe7\x09\x1f\x1a\xc4\x61\x8a\x51\xc2\x43\x56\x34\x8b\x93\xce\x1a\xbb\x6b\xfe\xc6\xb0\xa5\x41\xac\x2c\xaf\x2a\x7e\xd6\x87\x72\x1e\xae\x48\x83\x04\xac\x8e\x84\x86\xb7\x7d\x05\xb5\xaf\x1a\xa3\x41\x2a\x38\x5a\x15\x99\x03\x8f\xdf\x67\x45\x73\x9e\xd9\x6c\xfb\x49\xce\x7d\x8a\x14\x33\x2e\xa0\x07\x35\xcf\x34\x48\x81\x63\x79\xf1\x16\x9a\xd5\xc3\xb7\x6b\x78\xfb\x0a\x7d\x4d\x03\x11\x50\x2c\x5b\x69\x2a\x0c\xb3\x8e\x6f\x26\x52\x6b\x8c\xbe\xbf\x8a\x1c\x3c\x0d\xdc\x80\x7b\x8b\x06\x2a\x48\xac\xb2\xc3\x49\xd6\xaa\xca\xe4\x94\x3b\x6a\xb8\x75\xd1\x40\xc7\xa1\x19\x58\xff\x5f\x84\x17\x68\xa0\x13\x2b\x80\x6c\xe3\xaa\x8b\x4e\x4a\xdb\x35\x43\x20\xb1\x8a\x5d\x95\x59\x51\xef\x4a\x14\xd7\xf2\x4d\x51\x62\x59\x69\xd0\x87\x41\x0d\x89\xd3\x2c\x95\xd9\x97\x90\x3d\x1a\x40\xa2\x13\x1f\x60\xf8\xfc\x89\x70\xc0\xc9\xf8\x80\x60\x4a\x8e\x28\x9d\x5b\x6f\xa4\x9d\x81\x93\x7e\xd2\x7a\x55\x35\xf4\x2e\x2d\xe2\x8c\x6e\xca\x79\x3c\x1c\x0d\xc0\xc4\xa8\x99\x64\x71\xd6\xab\x42\xd7\x0b\x3f\xe8\x61\x10\x5a\x6e\x42\xe3\xf2\xbf\xf6\x6e\xd4\xb7\x8a\xc8\xc1\x9d\xb0\x08\x66\xc6\x5b\xec\x62\x09\x6d\x67\x2b\xcd\xb4\xcf\xea\xfa\x04\x5f\x05\x1a\xbf\x08\x8a\xba\x6b\x85\x9c\x24\xae\xb0\xfc\x26\xab\x95\xc8\x47\x07\x17\x0d\x43\x23\xd1\x57\x32\x18\x8d\xfc\x79\xe1\x00\xea\x8f\x54\x1a\x46\x29\xf1\x3a\x23\x68\xc4\xdd\x94\xd5\x0e\xc4\x61\xad\x67\x8a\x10\x69\x18\x09\x93\x3a\xe8\xf2\xe3\xe9\x2d\xd3\x65\x95\x89\x55\xa1\x8f\x65\x36\x31\xdb\x68\x48\xe2\xd8\xd3\xdc\xf7\x52\xf2\xb3\x2b\x36\xa4\xd4\x5a\xb2\x75\x57\x90\x3f\xbf\x92\x42\xaa\x2c\xca\xc7\x73\x6b\x03\xfc\xd5\xda\xd6\x3d\x28\x68\x9c\xe5\xa2\x21\xe3\x31\x52\x20\xb4\xaf\xd4\xda\x6c\xa3\x44\x09\x0d\x19\x68\x2c\x9d\xac\xf3\x41\x02\xc7\xb5\xf1\x88\x21\x30\xa6\x28\x35\x74\x1c\x45\x34\xe4\x84\x38\x08\x93\x2b\xe4\xf4\x7f\xd7\x11\x3e\x1a\x0a\xe0\xda\x58\x68\xd6\xaf\xa5\x30\xe6\x21\x7a\xa3\x2e\xae\x03\x8b\x42\xdb\x93\x6b\x54\x80\xe0\x3a\x27\x32\x64\x36\x84\x83\x94\x28\xf7\xa2\xfa\x05\x0d\x96\xa1\x0d\xa3\x20\xa3\x6c\x78\x94\xf8\xdf\x2a\x43\xc1\x11\x3f\x56\xce\x41\x5b\x9b\x07\x50\xed\x3e\x5e\x7d\xfa\x5b\xa4\xa9\x74\xd1\x42\x5b\x38\xfc\x17\x74\x00\xde\xb3\x41\x4c\x15\xc7\xfd\x6b\x6f\x57\xfb\xa6\x2c\x7e\x8b\x6f\x9c\x7c\x37\x11\x46\x48\x97\xb5\x6f\xbd\x8a\x33\x55\x8d\xf1\xb2\x0c\x25\x23\x1c\x7c\xfd\x8c\xca\x8e\x19\x9e\xde\x7d\xa6\x94\x86\xd2\x88\x14\xdc\x01\xf2\xc7\xe4\xc6\xc3\xe3\x38\x54\xa1\xe5\xc9\x6d\xfd\xbe\xa2\x7e\x87\x6a\x1a\xfe\xa5\xa1\xe2\x24\x05\x17\x91\xbd\xaf\xbb\x5b\xe8\x40\x06\xca\x2f\x0b\x93\x9f\xa0\x50\x63\xd9\x60\x1a\xea\x50\x60\x91\x90\xd3\x42\x18\x4a\x21\xd0\x50\xa7\xb1\x57\xbb\x73\x99\x55\x8b\x28\x29\xee\x44\xed\xc3\x2a\x93\x55\xa0\x25\x89\x5c\xb0\x6d\x36\x33\xea\x3f\xf4\x30\x4a\x40\x43\xad\x22\xe4\xb1\xb6\xf6\x28\x64\x77\x65\xdd\x3d\x04\x10\x8a\xd1\x9c\x57\xe1\x27\xeb\xf8\xdd\x81\x07\x8a\x75\x02\xe3\xbd\xd3\x32\xd8\x1e\x20\x31\xf8\xe5\x6c\x20\x74\x98\x85\xa4\xa1\xa1\x12\xa9\x11\x7c\x74\x18\xf9\x60\x76\x9d\xb0\x36\x0d\x8d\x48\xd1\x82\xdd\xf5\x52\x39\x34\x0a\x42\x45\x2c\xeb\xeb\x8f\xf5\x66\x3c\x04\x51\xc0\x63\x64\x23\xf7\x96\x33\x46\x2d\xc7\xd8\x0a\x1a\x05\xa9\x95\x7c\x2c\x4a\x37\xa8\x0b\xc7\x62\x77\x53\x56\x5b\x80\x61\xa4\x92\x46\x81\x62\xbe\xd6\x02\x95\x4e\x2c\x57\x87\xbd\x64\xe2\xfb\xe8\x54\x7b\xbe\xd1\xd3\xc1\x91\x30\x2c\xde\x44\x96\x0b\x9b\x0d\xf8\xf2\x78\x8f\xc2\x98\xfb\xa4\xd8\xc5\x35\x14\x85\x10\x60\x24\xbd\x81\xba\x59\x8a\xa2\xf1\xb8\xa2\x76\x8b\x5e\x17\xaa\xac\x2a\x50\x4d\x57\x42\x4a\xa3\x28\xe0\x48\x36\x86\x63\xba\xd2\x2f\x60\xbd\xc5\xc9\x50\x44\x49\x9c\x88\x5e\xbd\x6d\x5d\xa3\xdb\x7e\x9d\x29\xf8\x26\x0e\x30\xcb\x26\x42\x23\xc2\x98\xb0\xac\x8d\x5b\x34\x39\xfc\x06\xd0\x8d\x19\x49\x6d\xd6\x41\x18\x93\xe5\x59\xbb\xe2\x87\x6a\xdc\x34\xa2\x5c\x02\xf5\x98\xde\xab\x53\xa1\x73\x98\xad\x82\xa2\x11\x0b\x0c\x1a\x9d\x8b\x97\x2a\x43\xaa\x8f\x4d\x05\x6f\x3d\xef\x3d\x8d\x18\xb5\x35\xd4\xc7\xaa\x3c\x94\xbb\xb2\x2c\xea\x21\x3a\x91\x46\x2c\x4d\x3c\xb7\xc6\xbe\x5d\xed\x18\x49\x71\x6d\x3c\x01\x8b\x01\x0e\xe3\xa6\x77\xbf\x68\xc4\x15\xa0\x8e\x81\x68\xbf\xe3\x45\x01\xbe\x4e\x5a\xb1\x1f\x4d\xae\x13\xe1\x2b\xf5\xb3\xe2\xb6\x3c\xc0\x39\x0d\x1c\x8d\xb8\x09\x3c\x81\xf5\x0d\xc6\xd8\x0b\xf5\x39\xe9\x12\x47\x61\xa8\x3c\x0b\xde\x01\xa2\xc9\x07\x88\x53\x1d\xf6\x66\xd7\xaa\x79\x7d\xde\x5e\x0f\xf5\x16\x69\x24\x22\x45\xa3\xee\x9c\xc3\x7a\x23\x0f\x97\x19\xdf\x49\x88\x28\x89\x27\x35\x8f\x23\x8d\x6e\x1a\x09\x15\x6a\xb7\x59\xfe\xeb\x54\x56\x13\xfe\x53\x1a\xc9\xd0\x6a\x3b\x9e\x8a\x8d\x38\xd5\x38\x71\xfc\x63\xc8\xd4\xae\xdf\x4c\x95\xf7\x59\x61\x55\xbc\x7d\x9b\x0a\x18\x56\xde\xb8\x14\xa3\x45\xc3\xad\x1a\x1b\xcd\xf9\x79\xeb\x75\x2f\xfd\x7e\xe5\xff\x1d\xc7\x1d\xdb\xcb\x18\x0c\x58\xdc\x2f\x9e\xbe\xaf\x30\xbf\xb7\xbd\x5d\x3c\xad\xba\xbb\x30\x8e\xde\xb6\x92\xd5\xf4\x3b\x28\x11\x81\x7b\x80\x3d\x89\xe6\xac\x95\x48\x87\xda\x62\x5b\x51\x22\xae\xac\x7c\x3c\x6b\x7c\x21\x90\xb1\x8f\x7e\x2d\x5e\x2a\x18\x15\x10\xfa\x2e\xc6\x52\x2d\xb5\x87\x7b\xbb\x62\x31\x54\xf7\x5b\x70\x29\x8d\x4c\xa0\x70\xab\xca\x91\x24\xec\xd1\x2c\xcb\xc3\xa1\x6c\x17\x81\xc9\x3e\x48\x34\x13\xef\xa7\x24\x60\x61\xd8\x73\xca\xf6\x96\xcd\xe0\xbd\x48\x90\x5a\x59\x17\xf4\x6e\x70\xe8\x27\x1c\x59\x94\x44\x81\x09\x3c\x29\x8d\xad\xfa\x7f\x2e\x4e\xb5\x97\x43\xe9\x7a\x31\x8a\x7e\xfa\xe2\x78\x9c\x22\x8e\xe6\xce\x53\x12\x31\x8d\xd2\xdc\x96\x15\x69\x88\x1d\xa7\x84\x84\x04\x53\x66\x9e\x77\x9e\x84\xee\xfd\xc2\x7f\x8c\xff\xf5\x6f\x41\x22\x1e\xf5\xcb\xe0\xa6\x2a\x0f\x5d\xed\xa7\xef\x91\x58\xa9\x82\xf6\xcb\xe4\x79\x6b\xc3\x2d\xcb\x4e\xd5\x9a\x12\x02\x61\x64\xc9\x79\x87\xf6\xd1\x90\x24\x8d\x12\x1a\x5b\x31\xf1\x17\x68\xfe\xfd\xc7\x70\x9c\x29\x04\xe8\x84\x5a\xb0\x19\x46\xbf\xae\x4e\x9f\x17\xa0\x8a\x67\xee\x34\x61\x61\x8a\x59\x63\xb7\x7d\x62\xed\x01\xc6\x69\x66\x43\x6e\x6d\x7f\x08\xbd\x70\x93\x85\x60\x5b\x5d\x96\xda\xaf\x12\x97\xf3\x38\x2f\x10\x9f\x5e\x88\x44\xa2\xd7\x1e\xf8\x29\xde\xe0\x47\xd9\x9c\x6d\xf5\xe3\xcf\xc6\x74\x10\xba\x03\xee\xb9\xc8\x9a\x7f\x0a\x0d\xdb\x06\x04\x82\x4a\x9d\xc7\x79\x51\xca\x7d\xc6\x67\x20\xcc\xd8\xd8\xfd\x99\x9e\x3c\x25\x5c\x43\xe8\xd0\x2b\x9d\x3f\x79\x4e\x33\x4c\x49\x2c\x15\xb3\x15\x13\xdd\x96\x42\x62\xcd\x31\xa2\x5e\xca\x76\xbe\x6e\x5f\x33\xf0\x60\x02\x4a\x92\xd0\x2a\x02\x5f\x83\x15\x6f\x74\x54\x93\xff\x77\xce\x1c\x4a\x12\xd6\x69\xa7\xd9\x6f\xb0\x9e\xd8\x45\x24\x61\x80\xeb\xeb\xfb\x66\xbd\x1d\xcd\xf1\x24\xd6\x09\xce\xf1\x4a\x66\x4d\xd5\x9a\xf1\x36\x60\x75\x9f\xe5\x50\x37\x65\x31\x7d\xcb\x94\x69\x9b\x23\xc8\x9a\x43\xeb\x45\x8f\x2e\x96\xa6\x06\xab\x89\xef\xaf\xd7\xa3\xbf\x8b\x38\xf2\x4a\xdc\x28\xc4\x03\x03\x7b\x8c\x08\xa9\x7d\x54\xbf\x83\x2c\xa2\xde\x63\x67\x3a\x10\xa1\x6c\xa9\x28\x26\x26\xef\x6c\xd9\xc4\xe4\xb9\x64\xc8\xa3\xa0\xd7\x76\x5b\x9c\x9a\xd2\xff\x5a\xd2\x04\x27\xf6\x5b\x06\xef\x1b\x51\xd7\xef\x65\x35\x1d\x1e\x19\x0b\x24\xab\xc1\xd4\x3e\x38\xaa\x80\xf1\xc6\x22\x85\x42\x0f\xe6\x58\x96\xf9\x0d\xc0\xba\x40\xc2\x85\xe9\x85\x80\xd8\xea\xc9\x53\x61\xd1\x33\x8b\x3c\x9f\x4c\x27\x20\xb6\x08\xf8\x7e\x75\xe7\xeb\xa3\x29\x81\x34\x51\x76\x17\x32\x43\xbd\x42\x4a\x0c\x8b\xf0\x68\x3e\x94\xf3\x20\x09\x4a\x8c\x8e\xf1\xb0\xdb\xbf\x8a\xd6\x6c\xd9\x55\x96\x02\xb5\xb5\x8e\x4f\xe7\x1c\x7c\xe3\x1f\xd3\x30\x4a\x30\x69\xe3\xc9\x23\x90\x75\xd7\xaa\x0a\xfc\xe1\xbb\xa4\xa1\xb7\x57\x2c\x3b\x7f\x59\x7d\x7a\xd9\xde\x59\x6f\x87\x86\x32\x44\x03\xdb\x5d\x74\x64\x61\xd3\x88\x2a\xa1\x3a\xe2\x72\xac\xe4\xbd\x2b\x5f\x56\xad\xc7\xe8\xf9\x1a\x29\x25\x34\xd5\xc8\x3d\x5d\xbc\xb8\x0a\xb8\x21\x07\x14\xa5\x24\xe6\xc8\x8b\x70\xac\xe0\x26\xfb\xb8\x00\xf2\xa6\x94\x80\xc5\x0d\xdc\x67\x85\xbe\x15\xaa\x2b\x2e\xa3\x94\x2a\xbb\xf6\xac\xfb\x77\xfd\x2b\x9f\xc6\x7a\x86\x17\x0c\xa7\xa3\x46\x41\xe0\x21\x6c\x79\xdc\x84\xc7\x56\x52\xca\x42\x4b\xd3\x2f\x4f\x9f\xb7\xdb\xed\x6b\x79\x1c\xcf\x0e\xca\x28\x45\x7e\x94\xf6\x23\x6f\xca\xee\x75\x79\xa4\x31\x11\x63\x3d\x92\x4c\x75\x90\x77\x4a\x39\x89\xa5\x33\x87\xaf\x4e\xd5\xb4\xb4\xb1\x6d\x37\x88\xfe\xef\x40\x5b\x5b\xc8\xcd\x35\x58\xa6\xfe\xee\x22\x2a\x44\x12\x84\x85\xff\x43\xca\xc3\x14\xfa\xda\xad\xcd\x19\x2b\x36\xa5\x69\xca\x12\x6d\xa3\xe6\xd9\x1b\x54\xb6\xca\xec\x00\x45\x33\x03\xf0\xa4\x34\x55\x04\x43\x05\xfb\xa3\xdd\xc4\xc6\x9f\x2b\x35\x06\xdc\x0e\xea\x36\xb9\x33\x05\x57\x4a\x45\x60\x39\x61\x2c\xb1\x55\x6b\xc7\xa3\xd7\xe3\xc3\xf8\x54\x70\x25\x9c\x2f\xb9\xa9\x4a\x7d\x9a\x3a\x01\x54\x52\xab\xc0\xe3\x22\xee\xe3\x6a\xad\xf9\xf8\x2b\x95\xcc\xf2\x32\x99\x53\x81\xdf\xff\x41\x1c\x20\x1c\x5b\x4a\x54\xc6\xa9\x1c\xe6\x3e\x44\xbe\xe8\xa2\x86\x54\xea\x04\xc9\x02\x76\x4f\xcb\xd5\xd3\x32\x0a\xbe\x40\xc5\x51\xaa\x15\xc3\xca\xd6\xbd\xd0\xfa\x3b\x9c\x51\x1c\xbb\x5e\x10\x12\xcf\xb4\xe8\xa4\x8c\xe6\x4a\xfc\x28\x35\xa1\xa5\x10\xb1\xd6\x49\xe4\x9f\xc8\x74\x9a\xc3\x85\x7e\x80\x97\x27\xf8\xf3\x62\x64\x63\xf4\x70\xc6\xc4\x78\x86\xc8\xf6\x08\xbc\x85\x1e\x78\x46\x59\x10\xa4\xbc\x37\x6b\x1e\x1d\xa7\xce\x37\x31\x5f\x75\xd0\xf6\x07\x4c\x87\x61\x5d\xd9\xf2\x06\xe0\xbe\xd4\x88\xb5\xaf\xbb\x2b\x26\x01\x06\x1a\xf6\xc7\x2a\x53\xb0\x1f\x3a\x3b\x2c\x48\x0d\x1a\xc8\x77\x8f\xcb\xef\xab\xeb\x7d\xf8\x9f\xfd\xf5\x62\xb7\xea\x5a\x25\xc3\x4c\xec\xfe\x90\x7d\x74\xeb\x99\x05\xca\xa0\xe5\xec\xe4\x66\x37\x55\xf6\x96\xe5\xf0\xd2\x79\x5d\x2c\xd0\x56\xa3\x47\xe4\xb9\xf5\x53\xeb\x41\x1b\x30\x9c\x38\xb6\xa8\x7e\xbf\x7d\xbc\xbb\xde\xdf\xad\xef\xd7\x3b\xdf\x21\x0c\x28\x72\xfa\x6c\x77\xff\xb2\xb6\x55\xd4\x7a\xff\x63\x94\xc5\x04\x8d\x4e\x59\x48\x15\x56\x91\xc8\xd3\xe7\xb6\x3c\x5c\x2e\xf8\x9e\x1f\xc2\x30\x0d\xb0\x54\x49\x42\xf3\xa8\xbb\x27\x8d\x24\x4f\x55\xaf\x12\x8c\x45\xba\x83\x33\x8a\x45\x86\x44\xda\xd7\x02\xed\xe6\x73\xa5\x94\x11\xca\xb5\xfa\x42\xee\x6e\x34\xcd\x18\x49\xad\xf0\xb7\xe5\xa1\x2e\xab\x5e\x0d\xe2\xea\xd3\x86\xf1\x26\x79\xdb\x81\x59\xc5\x88\x4a\x22\x67\xab\x3a\xbb\xff\xa6\x35\x81\x88\x7f\x60\x4a\x23\x66\x41\x29\x33\xe5\xf5\xbe\x8f\xb2\x54\x50\x0d\x88\xc3\xd3\xc0\x4a\xaf\x7b\xd8\x77\x37\x40\xac\xdd\xd9\x2c\x0c\x0f\xfd\x87\x1d\x78\x76\x17\xca\x78\x40\xf1\xac\xeb\xd1\x60\x94\xf1\x30\xe0\x96\xb0\xb8\xd4\xcb\xa1\xc9\xc2\xe2\x88\x23\x98\xca\xa5\x2a\x2d\x21\x56\x27\x27\x77\x5e\x09\x4a\x59\x4c\x38\xba\x39\x47\x91\x69\x47\x5d\xdb\x5d\x8c\xd1\x18\x3d\x20\xe4\xb3\x1e\xc7\x1e\x58\xcc\x13\xdc\x69\x95\x28\xf6\xd9\xfe\x7f\x4f\xfd\x13\xc7\x71\x84\x8a\x11\x43\x3e\x7e\xca\x62\x00\x44\xca\xeb\xd2\x8a\xd4\x8f\xb7\x05\x96\x84\x21\x72\x30\xff\x28\x3f\x7b\x15\x26\xca\x12\xae\xbc\xe4\x90\x83\x31\x3e\x61\xb2\xfb\xfa\xb7\xa9\x3c\x96\x86\x96\x9c\xc7\xe6\x62\x2d\xe0\xc2\x5f\x36\x25\x14\x5d\x24\x25\x2a\x5d\xef\x5f\xca\x5c\x0f\xf1\x8c\x94\xa5\x09\xb5\x6c\x57\xed\xda\xda\x3f\x3f\xac\x77\x7b\x64\x86\xe9\xda\x41\x72\x1b\xcc\x2a\xa0\xb5\x3e\xbf\x83\x52\xe2\x57\xc4\xf8\xd0\xb3\x61\xa9\xb1\xa4\xae\xda\x51\x7b\xd6\xe7\x81\x6f\x26\xe2\xc8\xaf\x8d\x0b\x4a\x20\x94\xc9\x30\xe0\x96\x5b\xd2\xba\x08\xf7\x65\xd1\xbc\xe6\x9f\x83\x72\xe4\x1f\x65\x7e\x3a\x40\x47\xc1\x3a\xfd\x3d\xed\x74\x9b\x3c\xaa\xc4\x72\x67\x5c\x42\x22\x4f\x7e\x9e\x72\x5b\xd2\x97\x15\xad\x13\x61\xc1\x2d\xf5\x30\x0f\xc7\x54\xc2\x80\xf5\xb6\x13\x4e\xe2\x1b\x98\x84\xab\x98\x82\x44\x7b\x86\x47\x7b\xa7\xef\xff\x59\x9e\xa3\x0b\x28\xd3\x02\x30\xf0\x8c\xb5\xf0\xa8\x72\x67\x0c\x54\x96\x08\xcf\x3d\xdb\x7f\xe3\x41\x19\xbc\xfb\x19\x44\x29\xb2\xbd\xbd\x8a\xfa\x75\xd9\x71\x5d\x53\x06\x89\x95\x08\x93\xa7\xcf\x9f\xa2\xca\xcb\x4a\x2f\x5f\xa1\x9e\x2e\x04\x90\x16\xd2\xbf\xf7\x1f\xd5\x12\x7a\xb4\x17\x73\xac\x51\xc3\x83\x87\x81\xb1\xcc\xc6\x05\x7c\x34\x4f\xa0\x4f\x6a\x6c\x3d\x30\x30\x90\x24\x5e\xdc\x27\xb4\x10\x63\xdf\x66\x62\x8a\x5b\xf7\x0f\xa8\xb2\x66\x28\x42\x40\x79\x40\x63\xe4\x3c\x31\x59\x9e\x2f\xaa\xca\x2b\xf7\x53\x1e\xb0\x14\xe1\x34\xae\xf4\x02\x91\x92\x33\x63\xc7\x03\xc5\xd0\x6a\xc9\xb3\xba\x19\x16\x2a\xce\x25\x80\x79\x00\x4c\x7b\x10\x8e\x38\x40\x31\x1f\xa8\xe4\x61\x62\x65\xbd\xae\x45\xf3\x2d\xab\xfc\x2a\x69\xad\x31\xcc\x4c\x3f\x94\xbf\x4e\x96\x35\x0a\x8d\x89\x2d\x54\x6f\x99\x82\xe9\x35\xb4\x74\x04\x1a\xe2\xd0\xc9\x9d\xf4\x40\x5e\xca\x23\x02\x81\xa3\xeb\x98\x12\x57\x7c\xe9\x46\xf2\x88\xc7\x18\x00\xb3\x4c\xef\xd7\xf6\x2c\xbd\xe0\x77\x70\x42\x22\xf0\xf4\x68\x7b\x44\x95\x20\x1f\xd4\x1e\x0e\xc7\xe6\xf3\x06\x6c\x3a\xe8\x5d\x54\xba\x5d\xab\x7e\x95\x72\xc2\x2c\x90\xca\x95\x3d\xd8\x20\xcf\xa3\xe9\x9a\xe3\x00\xf7\x68\x8f\x53\x58\xbe\x66\xb9\xae\x26\xe0\x37\xca\x89\x04\xe2\xe6\xbf\x2d\xc0\x76\xab\x60\xf2\xba\xbe\x37\x68\x0c\x3c\x3b\x63\xdf\x83\x1d\xc7\xaf\x43\x81\x53\x1b\xb6\x85\x43\x76\x3a\x6c\x50\x7e\x79\xda\x25\xd6\x36\x6f\x9b\x7f\x41\xcb\x41\x39\xe3\x11\x1e\x42\x96\x7d\xf9\x69\xb1\x5b\xed\x6f\x1e\x9f\x9f\x76\xb7\xfe\x2d\x79\x60\x8c\x97\x13\x42\x15\xdb\xae\x21\x32\xb1\xd5\x35\x2a\x9e\x8b\xfa\x15\x72\xf3\xc7\x8c\xf4\x3a\xe5\xdc\x84\x81\xd3\xa4\x39\x63\xac\xbf\xf0\x6d\x63\x2a\x31\xf0\xe4\xad\xd8\x0b\x52\xa2\x93\x1b\x25\x5c\x62\xd4\xf6\xdb\x07\xf6\x7e\x3c\x82\xa7\x3b\x9c\xf4\x03\x6b\x23\x67\xc5\x7a\xe9\xf7\x76\x9e\xc6\x01\xd2\x0a\x62\x50\xfd\x5b\x99\xeb\x33\x48\x2b\xe5\x92\x91\x68\xa4\xe4\x84\x3b\xfb\xcc\xf1\xca\x65\x9a\x70\xd1\x55\xa3\xaf\x3e\x1a\x2c\x5c\xc5\xed\xb7\x75\x16\xea\x55\xc7\xeb\x47\xb9\x94\x0a\x61\x11\xcd\x6b\x56\xe9\xbe\x96\xa3\x67\x92\xa7\x5c\x05\x26\x4a\x5d\x9d\x27\x14\xf5\x99\x3f\xc2\x15\x0b\xac\x95\x54\xb6\xae\x74\xf7\xb3\x84\xf9\xf4\x84\x8b\x12\x4c\x5e\x48\x87\xa9\x67\x66\x3e\x5d\x48\x07\x72\x9d\x86\x08\xe6\xc1\x87\xba\x3a\x55\x13\xb4\x06\xd7\x22\x48\x7a\x32\x34\xa4\x5f\xfd\xaa\xec\x75\xe4\xae\x70\x0d\x14\xd3\xb2\x78\x08\x9e\x0e\x03\x2d\x3b\xca\x41\x29\xe5\x79\x75\xa7\x8a\x81\x94\x9b\xd0\x46\xa6\x6d\xe0\xda\xff\xc6\xb4\xbe\x01\x8e\x43\x9e\x8b\xca\xc9\xf8\x3e\xb5\xb3\xc0\xf5\x88\x83\x40\xe3\x4e\x9b\x1f\xef\xc5\x87\x3d\x40\xbb\x26\x62\xe5\xda\x2d\x69\x97\x3d\xea\xee\xc5\x47\xd7\x1c\x13\x43\x07\xe2\x37\xeb\x42\x95\x07\x18\x9c\x77\xa3\x71\x89\x03\xa3\x6d\x35\xfb\xdd\xb3\xbf\x42\x18\x31\x5c\x4a\x5b\xcc\xa3\xf4\x93\x2f\x0e\x81\xe3\x9d\x5b\x8f\xc0\x3a\x84\x57\x9f\xcb\xb9\x2a\x31\x1a\x47\xb1\x4d\x96\x29\x71\xec\x14\x64\xfc\x65\xa2\x24\x45\x02\xa6\x3d\xa8\xeb\xf2\x24\x2f\x13\x37\xf9\xfe\xda\x62\x8a\x6d\xfe\x71\xad\xba\x41\x8a\xc0\x46\x1c\x8c\x17\xc8\xb3\xb5\x29\x03\x8c\x57\x4c\x68\x82\x91\xa1\xfd\x80\x32\xf9\x6f\x7b\x0c\x31\xe1\x34\xea\xb1\x75\xcf\x45\xa6\xca\xaa\x78\x12\x85\x7a\x9d\x45\x28\xc4\x44\x51\x9c\x64\x57\xa2\x51\xaf\xd7\xd0\x08\xf5\xea\x58\xe0\xbc\x61\x10\x06\xce\x1e\x88\x69\xca\xb1\x80\x4f\x67\x75\xb3\x6f\xcf\xc3\x7d\x0d\x33\x04\xa0\xff\xed\xfa\x4b\x8e\x51\x30\x21\xcb\x53\x63\x0b\xc2\x27\x77\x67\x51\x82\x3b\x98\x63\x6b\x8b\x36\x50\x16\x9f\x33\xc8\xa5\x98\xc5\x02\x8b\x9e\x1c\x55\xd4\x55\xa6\x7d\x7c\xf7\x42\xd4\x27\x66\x69\x8a\xdb\xf4\xcf\xbb\xfb\xdd\x15\x6a\x73\xfb\x6f\x10\xbb\xd9\xb8\x58\x6d\xdb\x63\x5f\x34\x7d\xe6\x68\xce\x5f\x8f\x63\x1e\x60\xac\x0a\x29\x18\xbe\x89\x73\x27\xce\xf7\x4b\x19\x46\x30\x6d\x2e\xc4\x3a\x27\x43\x1a\xa8\x59\xbf\x26\x8e\x05\x97\x71\xef\x86\xb9\xc4\xb0\x6f\x54\x91\xf4\xf8\x91\x32\xd7\x97\x65\x69\x69\x9c\x50\x89\x87\x21\x02\x2b\x96\x27\xf9\x7f\x74\x35\xe3\x44\x01\xc2\xab\x72\x10\x1a\xaa\xbd\x0f\x24\xc4\x82\x5b\x41\xe2\x97\x4e\x77\x5c\x77\x4d\x22\xc4\xf9\xb0\x38\x35\xe5\xf6\x98\x67\xcd\xf2\x54\x0d\x31\x2e\xae\x9b\x8c\x63\x0b\x2c\x29\x4c\xe9\xf1\xb4\xae\x49\x25\x14\xf3\xf4\xf7\x8b\x7f\x8f\xc8\xec\x68\xac\x74\x88\xe6\xe0\xe2\xfe\x6a\xb1\xdd\x2e\xae\x1f\x9f\xf0\xf4\xec\x9a\x81\x84\x2e\x1c\xf9\x54\x96\x07\x0f\x85\x84\xe9\x5e\x01\x46\x2a\x57\x4f\x6c\x59\xc4\xee\xb2\xe2\xd7\x74\xe8\x0c\x4b\xa3\x70\x50\x31\xfe\x78\x1c\x95\xfd\x90\x7e\x66\x13\x37\xb5\x93\x20\xb6\x8a\x9f\xba\x7c\x2f\x76\x99\xfa\xb5\x83\x73\x19\x7e\xd7\x35\x8c\x40\x76\xbc\x1a\x6b\xbd\x2b\xcf\x95\x4a\x68\x12\x52\x8a\xf5\x89\xfb\xee\x60\x1e\xaa\x76\xd0\x24\xd4\x56\xe8\xea\x4a\xd4\x70\x23\x2a\x58\xba\x83\xd2\xcb\xa9\xd1\x84\x10\xc2\xdd\x88\x20\xcc\xa9\x30\xe5\xd5\xe7\xfa\x7a\x72\x1f\x42\x52\xb4\x66\x1d\x83\xcb\xaa\xe7\x84\xa3\x09\x61\x02\xab\x0d\x8e\x65\xdd\xdc\x8a\x4a\x0f\xce\xc9\x84\x24\x14\x43\xef\x79\x59\xc3\xcf\x61\x14\x6a\x36\x9b\x32\x19\x01\x0a\xd6\xfd\x47\x30\xd2\xf6\x20\xf2\xfc\xb9\x06\x24\x15\x1b\xba\x77\x09\x0b\x09\xb8\xb2\xe2\x9b\x53\xa1\x1f\x7b\xeb\xb9\x37\xc7\x13\x9e\xc6\x91\x8b\xa7\xfc\xcc\x9a\x57\x0b\xdd\x1c\xf2\x82\xfa\x7c\xec\x7c\x79\x06\x4d\x62\x1a\xe0\x41\x56\xe6\x43\x9e\x3c\x9a\xc4\xca\xc6\x05\xae\x45\x23\x6c\xb6\x79\xb8\x09\x24\x31\x58\x0f\x77\x0b\x85\x46\xab\x7c\x57\xe2\x3e\x39\x9e\x4a\x49\x12\xc8\x68\x88\xb0\x1d\xaa\xa5\xd3\x24\x35\xc2\x78\x20\x8c\xfd\xd9\xae\x44\xd3\x25\x3f\x33\x89\x12\x41\x6c\x85\xe2\x26\x17\x7f\x89\xdf\x95\xda\xd2\x44\x88\x00\x27\xd0\xc9\xd6\x77\xae\x9a\xd7\x65\x39\x75\xc9\x12\x49\x09\x82\xdc\xb6\x57\xb3\xda\x26\xbe\x17\x44\x91\x1c\x20\xa8\x6a\xe8\xf5\xea\xba\x57\x51\x21\x8b\x75\x8f\x93\x1c\x18\x27\xe3\x8a\x43\x9a\xa8\x48\x20\xbb\xd6\xe6\xc7\x0c\xef\xe1\xfc\x13\x28\x12\x20\xab\x04\xf2\x9e\x7b\x8e\xfc\x49\x17\x6a\x91\xaa\x2e\xd4\xf7\x84\x19\x93\xee\xe9\x74\x18\xba\x3c\xb2\x85\xd3\x95\x87\x1f\xeb\xcd\xdd\x0c\x7c\x25\xd1\xc4\x6a\x4d\xd9\xf7\x38\xdb\x33\xbf\x7c\x4c\xcd\x03\xdc\x5c\x5e\x45\x6d\xa7\xd2\x78\xb4\x21\x0a\x4c\x34\x50\xe3\x69\x2d\x1a\x1b\x32\x7b\x2e\xb2\x37\xa8\x6a\x18\xd0\xc5\xd1\x04\x98\xc1\x55\xd2\x6e\x93\x1e\xdf\x18\x76\x8d\xa9\xc2\xd7\x5d\xed\x36\x65\x23\x9a\xd2\x05\xd0\xbf\xe4\x1e\xa2\x09\x68\x83\x58\x2f\x07\xe4\xba\xf0\xbd\x0d\x51\xb8\xee\x6e\x6f\xd0\xc9\x9f\x99\x5d\x69\x40\x2c\x19\x71\x01\xef\xdd\xa2\x1c\xbb\x24\xff\xfd\x9f\x89\x1d\x3a\x7e\x94\x34\xa4\x69\x98\xfa\x98\x0b\x92\x51\x95\xed\x0e\x74\xca\x9a\x4f\x17\x0d\x18\x02\x1c\xd2\x90\x19\x04\x7f\x5d\xdd\xba\xca\x38\x9a\x86\xdc\x60\xe5\x1a\xc2\xfd\xdf\x8e\x41\x10\x7d\xfd\xf6\x69\xc4\x52\x3c\x59\x5d\xc9\x73\x47\x86\x31\x9e\x49\x69\x94\x72\x01\xa8\xf8\x5c\xdf\x82\xe7\xd7\x69\xff\xac\xf0\x68\x6a\x57\xc1\x46\x64\xd5\xf4\x57\x22\xc6\x1c\x7f\x9d\xbd\x14\xcf\xc7\x39\x23\x68\x3c\x82\x44\x25\x88\xa5\xf2\x1b\x83\xe3\xa6\xf8\xbc\x6c\x3e\xa5\x2c\x08\x2d\xf0\xb7\xdd\xaa\x3a\xb4\x7f\xa7\xcb\x4d\x53\x46\x49\x12\x7b\x9e\x8e\x7c\xb8\x4d\xa6\x3c\x8a\x11\x7e\xb4\x03\xf5\x5a\x94\x79\xf9\xf2\x49\xbf\xf9\x9f\xc5\x81\x0d\x33\x38\x83\x78\x40\xea\x32\x7b\x80\xa5\x71\x14\x4b\x17\x4e\xde\xfe\xca\xf2\x7c\xf5\x26\xf2\xd3\x28\xe6\xf8\xf7\xc0\x92\x69\x4c\xb9\x07\x18\xfd\x10\x55\xd6\x7e\x90\xaf\xa9\x90\xfa\x67\x48\x82\x04\x9c\xc3\xb5\x6a\x5e\x6f\xca\xca\xef\x0a\xae\x3d\x25\x12\x9f\xd1\xe9\x01\x76\x0a\xa5\x53\xc6\x1a\x9a\xa6\x82\xa0\x25\xf9\x00\xef\x16\xae\x72\x59\x07\x98\xa6\x82\x31\x9f\x92\x3b\x64\x4d\x03\xda\x42\x85\xca\xa9\xd3\x94\x0a\x27\x5e\xec\x20\x1f\x00\x56\xf3\xee\x4b\x7c\x5d\x2a\x38\xc7\xa8\xe8\xfe\x78\xaa\x5f\xef\x44\xa1\xd7\x17\xa2\x2c\xa9\x8c\xa3\x04\x3a\xf0\xc1\x13\xd4\xe5\xa9\x52\x80\xe7\xd0\x19\x44\xd8\xff\x24\x01\xb4\x90\xae\x20\x87\xbf\xc4\x03\x34\xef\x65\xe5\x33\x94\xa9\x94\x0c\x65\x66\xac\x43\xb6\x69\x3d\xee\xd5\xc7\x60\x7b\x1c\xcf\x5d\x29\x3b\x75\x09\xcc\xc8\xe7\x19\x14\xcd\x0c\x2f\x07\x4d\xa5\x31\x9e\xfc\x63\x14\xa1\x4b\x75\xa8\x71\xf9\xbf\x65\xf0\xbe\x85\x3c\xc7\x00\x64\xbd\x68\x56\x1f\xbe\x08\x48\x55\xa5\x28\xea\xcf\x99\x10\x5c\xaa\x41\xc5\xae\x5c\x7a\x03\x47\x58\x78\xf4\x9e\x9e\x1e\x23\xae\x3f\x24\x21\x19\x09\x73\x38\x0f\xfb\xd3\x56\xf6\x8e\xb7\xe9\x14\x00\x10\x32\x80\x39\x28\x5b\x79\x77\xe5\x1f\xdb\x04\x69\xdc\x1d\x44\x78\x7e\xd8\x06\x11\x84\x16\xde\x37\xd4\xe6\xb5\x59\x89\xd6\x6b\x9c\x5d\x47\x22\x60\x06\x8b\x12\xf6\x5d\xf9\x0d\x1a\x10\xd3\xa3\xb0\x7f\x71\x11\xb2\x84\xb9\x12\x81\x07\xf8\x68\x96\x9f\x3d\x92\x4e\x44\x51\x04\x0e\xc2\xf6\x24\xb2\x1a\xf4\xaa\x8b\x2c\x09\x12\x01\xc6\x43\xb1\x42\x78\xca\x5f\x41\x05\x25\x96\xec\xe4\x05\x9a\x15\xd6\xa5\x6f\xcf\x12\xbf\x82\xc6\xb6\x3a\xa1\xd9\xaf\x0f\x07\x57\x7b\xea\x6a\x46\xca\x0e\xc7\x24\xa8\xb4\x80\x05\xfc\x9c\xcf\xc5\x28\x00\xe5\x30\xfe\xad\x39\x38\xfa\x3c\x82\xc7\x04\xa5\xf4\xeb\xd7\xf2\xbd\x9f\xbd\xbe\x11\x0c\x22\xf3\xf2\xf2\xe5\xaa\xbd\xc0\x38\x0b\x2b\x92\x50\x7b\x55\xf4\xef\x27\x5d\xd6\xdf\xb2\xb7\xe9\x86\x2e\x12\x1e\x22\x21\xd1\xb1\x82\x71\xe8\x25\xf1\x1d\x84\xd5\x75\x45\xe0\x25\x5a\xdc\xfb\x53\x95\x9d\x6d\x66\xc3\x35\x20\x12\x25\x55\xcf\x14\xb7\x2b\x7f\x42\x36\xbf\x56\x45\x1a\x05\x38\x9f\x2a\xf1\xee\x40\x34\xb3\x05\xd5\x54\xa4\x71\x84\xf8\xc5\xba\x34\xa8\x62\x38\xa5\x97\x9e\x5c\x56\xd9\x03\x14\xc9\x1e\x76\xaf\x59\xf1\xab\x8f\x4f\x88\x54\x1b\x4c\x29\x8b\xa2\x38\x4d\x90\x26\xad\x93\x96\x8e\xc8\xa3\x5b\x43\xc9\x71\xa4\x7e\x4d\x5e\x48\x85\x48\x19\x6e\x6b\xb6\x90\x64\x5d\x3b\x91\x0a\x7f\x5b\xa1\x02\xe2\xb2\x63\x55\xd6\x7c\x76\xaa\xff\xae\x59\x46\xb6\x1c\x2a\xab\xbb\x5a\x48\x54\xeb\xea\xdb\x65\x98\xf6\x15\x3d\x8b\x3c\x7f\xcc\xf5\x99\xa4\xb9\x3f\x0f\x85\xa4\x1a\xab\xa4\xf6\x58\xcd\xdb\x2c\x4e\x95\x98\x4c\x5a\x99\x0a\xed\x42\x8d\xad\x95\x30\x39\xb3\x85\xe2\x0c\x5d\x24\xa4\xf4\xff\x91\x1d\x7f\x36\xd9\xeb\x58\x12\x77\x70\x7a\x0f\x96\xa1\x52\x91\x77\x4c\xfc\x8b\x8c\xa3\xa6\xa3\xbe\x5a\x74\xc2\x2f\x67\x87\xdb\xe4\x79\x20\x14\x96\xda\xae\x54\x50\xd7\xa3\x82\x89\xf9\x49\xa0\xa3\x08\xb3\xf3\x18\x25\x80\xd3\xa1\x3d\xe7\x44\xbf\xb0\x75\x62\x03\xe2\xb9\x85\xd4\xd6\xa3\xe2\x41\x01\x81\x8e\x8c\xf7\x10\xd5\x2b\x3a\x1e\xe1\x64\x04\x21\x0a\x2d\x4b\xcd\xf5\x30\x8b\x22\x80\xc7\xc2\x81\x11\x76\xa2\x7a\xe9\xc5\xd5\xd0\x82\x4d\x27\x17\x31\x69\x48\xb9\xaf\xc2\x1d\x32\x71\xfe\x31\xf1\x0d\x84\x91\xda\x0a\x62\x61\xc8\x69\x0f\x1f\xc7\xbc\xac\xa0\x42\xca\xdf\xa1\xb2\x3e\x95\x81\x02\x74\xcf\x1e\xe0\x7d\x5d\xd7\xa7\x73\xcb\x77\xe0\x49\xca\x30\x20\x9a\x76\x4c\x0e\xad\x37\x27\x5e\x26\x1b\x9c\x0c\x13\x2e\x62\x8f\x46\x29\x4d\xd6\x9c\x53\x86\x53\x19\xc5\x11\x06\x91\xf2\x4c\x41\x51\x43\x57\x62\x3f\xc9\x09\xc8\x28\x89\x51\x48\x6e\x29\x8e\x8d\x18\xa3\xe1\x64\xa4\x8d\x2d\xe2\x6f\x67\x5d\x56\xbc\xec\x6f\xb2\xa2\x80\xcf\xba\x6b\x37\x4c\x3a\x26\xb6\x01\xc6\x69\xbd\x7c\xf4\xc6\xbf\xa4\x24\xc2\x22\xd2\xe3\x6b\x25\xba\x1a\x88\xf6\xaf\x58\xe8\xf2\xd6\x11\x00\x0e\x37\x2c\x49\x13\x2b\xa6\xe8\x1c\x42\x3d\x79\x33\xaa\xe3\x18\xb1\x3f\xa7\xa9\x46\x14\x95\x4c\xc9\x4e\x4d\xc4\x53\xb5\x4d\x7e\x1e\x53\x81\xa7\x8f\xb5\x77\xae\xa0\x6e\xbc\x65\x34\x3f\x73\x65\x9c\x92\x38\xed\x32\xbc\xf9\x20\xb6\x20\x13\xae\x68\xe2\x48\xac\xab\x5f\xd0\x60\x04\xcb\x37\xa6\x8c\x23\x24\x6f\x5d\x3f\x81\xd0\x9f\xdd\x9f\x39\x43\x93\xe0\xa5\x02\x68\xf6\xe5\x41\x4c\x9c\x2f\x99\xc6\x96\xa8\xc4\x72\x48\x3f\x94\xfa\x0c\xc9\x3f\xde\x8d\x65\x6a\x04\x22\xfa\xb5\xc8\xfc\x4d\x44\x62\xe9\xb1\x01\x39\x81\xf6\x06\x60\x5f\x9c\xda\x15\xd7\x87\x5d\xa4\xd4\x4c\x53\x5f\x52\x29\xf2\xab\xa1\x37\xd3\x3f\x8d\x34\xda\x66\x2d\x86\x3a\x72\x67\x45\x70\x52\x07\x52\x19\xbf\x61\x5a\x65\x89\xfb\x2e\xe3\x2f\x75\x00\xd2\xf9\x93\x18\x6d\xfb\x7b\xa6\xb3\xd4\xdc\x62\x5a\x1d\xc9\xdc\xe6\x55\xd4\x80\x9a\x37\xdd\x75\x53\x1b\x32\x3e\x15\xa2\x6e\xdd\x99\xd1\x42\x18\x6f\x59\x12\x84\xb6\x99\xe4\x4e\x55\x73\x57\xee\xca\x06\xee\xb2\x3f\x4f\x56\xbe\x6b\x84\x52\x96\x20\x85\xea\x05\xab\xf6\x32\xeb\x7c\x74\x69\x8c\x40\xfe\x65\xcf\x1f\x7d\x2f\x86\x69\x23\x15\x70\x95\x40\x4f\x54\x62\x8b\xf1\x87\xf1\x22\x15\xd2\xc0\x4b\x54\x2c\xaa\x26\xab\x9b\x1b\x98\x2e\x4c\x15\x25\x80\x15\xeb\x79\xf9\x0e\x15\x16\x3d\xdc\x94\xd5\xae\xd4\x5d\x1e\x58\x45\x20\x75\x1f\xc8\x68\xad\xf0\x45\xa1\x27\x75\x4c\x97\x12\xfa\xe3\x91\x56\x24\x11\xb8\x4b\xb6\x2e\xe3\x9d\xe5\xbf\xf8\xfa\x7c\x55\xc4\x10\x64\x12\x43\xba\x88\x45\x9e\x5f\x8b\x46\xdc\x94\x95\x97\x0c\x1a\x2f\x3a\xc5\x22\x4e\xe9\x90\x00\xc9\x9c\x0a\x7d\x5d\x16\x83\xf9\xa8\x98\x90\x98\x5a\xf6\xe5\x78\xed\x4c\xbb\x08\xd1\x52\x3c\xb6\x41\xf2\x6f\x99\x2e\xce\x42\x50\x8a\x1b\x1a\x0d\x08\x97\x7e\x8a\xaa\x12\xc5\x39\x97\xc4\xfc\xa5\x63\x93\x22\x5e\xa7\x80\xf7\xa7\x93\x84\xfa\xb9\x68\xb2\x7c\xa8\x04\x4e\x55\x42\xad\x53\x60\x27\xe6\x5c\xe0\x41\xa5\x61\x12\xc4\x43\x53\xde\xb9\xc1\xe8\xb4\xed\xbb\x83\x3b\xee\x4f\x6e\xf7\xbf\xc9\xe8\xbf\xf3\xf4\x7b\x54\xa5\x71\x98\xf6\x4f\xd0\xda\xd8\xdf\xc4\x01\x36\xe5\x78\x81\xf9\xce\x69\x18\x7b\x26\x67\xd4\xbb\xdb\x40\xeb\x86\x3a\x72\x92\x49\x5f\x19\x1a\x8b\xe6\xb1\x94\xdb\xdb\x9e\xfe\x89\x2a\x01\x16\xca\x90\xd5\xbd\xbc\xe2\x60\xae\xb8\x5e\x32\x48\x95\x71\xd3\xfb\x20\x45\x5d\x0b\x3d\xf0\x3b\x07\x36\x87\x92\x54\x00\x99\xea\xba\xdc\x8b\x0f\x47\x4d\x37\x08\x19\xa8\x76\x67\x37\x5e\x28\xf0\x8c\x9a\x65\xbc\xd8\x15\x70\x8e\xb9\x7d\xb0\xca\x01\xcf\x99\x2f\x1f\xb9\xf0\xc9\x21\xb6\x2a\x9b\x9e\xe8\xb9\xbd\xc3\xb9\xd0\x5c\xdb\x4f\x63\x6e\x72\xf9\x2a\x8a\x02\xf2\xde\xa6\xc2\x9b\x7b\x32\xb8\x0b\xcf\x24\x35\x6e\x28\xb7\x50\x95\x3d\x1d\x32\x55\xe0\xb8\x37\xfe\x57\xd4\x4e\x25\x70\x70\x06\xeb\x40\x5a\x45\x43\xbb\x64\x3a\x27\xde\x11\xa6\x8d\xee\xa0\x03\xc9\x31\x5f\xbd\x85\x19\x46\x0a\x1d\xc6\x1c\xac\x88\xc1\xf1\x5e\xd4\x9d\xb0\x34\xd5\x51\xc8\x30\xe5\x67\xcb\x86\xfe\x75\x3a\xc3\xa6\xeb\x28\x4c\xf0\x38\xe9\x08\x94\x96\xb9\xc8\x3a\x1d\x76\xaa\xa3\x48\x06\xc3\xd8\xf1\x7d\x59\x41\xeb\xd4\xcd\x1e\xa8\x3a\xa2\xd6\xac\xa8\xa1\x87\xa5\x0c\x27\xfd\xa0\x27\x37\xa0\x3a\x4b\x60\x50\x68\xa6\xa3\x44\xc8\x5e\xbb\x7c\xbf\xdd\x2d\x9e\x76\xfb\xcd\xd3\x6a\xbd\x7c\xdc\xef\xd6\xf7\xab\xed\x6e\x71\xbf\x99\xbe\x85\xea\x78\x32\xba\xac\xfb\xa4\x0b\x81\x14\x27\xd9\x3b\x64\xd6\x35\x5d\x17\x3e\x5e\xe9\x7a\x50\x2a\x63\xaf\x68\x57\x8a\x6a\x8c\x7e\xd2\x34\x51\x48\xa2\xa3\xec\xfc\xe8\x16\x89\xcb\x04\x8f\xb9\xfc\xa8\x66\x5c\x30\xab\x68\xb6\xd6\xc8\x3f\xec\xea\xc4\xfc\xe3\x30\xcd\x95\x0d\x9e\x54\x19\xd4\x57\x23\x58\x91\xe6\x34\x46\xd2\xaf\xdb\x17\x35\x9a\x31\x31\x97\xe8\x2b\x1c\xcb\xba\x71\xd2\x94\x70\x56\x8e\x31\x7e\xed\x58\xc6\x48\xa2\xf8\x4d\xd4\x03\x5e\x31\xaa\x93\xd8\x20\x58\xe0\xe7\x4f\x32\xba\x45\x1a\x25\x58\x73\x81\xd0\x99\xfa\xf5\xd4\x5c\x97\xef\xc5\x8f\x11\x64\x50\xa7\xd4\xba\xaa\xab\x42\x97\xef\x07\x28\x9a\x27\x57\x92\xda\xcd\xbb\x94\xc5\x38\xb5\xf1\x2a\xb8\xeb\x63\xc9\x4f\xeb\xe5\x75\x1e\xa5\xeb\x2a\xb8\xc0\xb0\xfa\xe2\x79\x77\xfb\xf8\xb4\x5d\x7f\xbb\x5d\x6c\x6f\xbb\xc6\xc4\xa9\xf6\x23\x05\xa4\x3b\x00\x77\xe5\xd5\x69\x3a\x8d\x85\x48\x13\x85\x0c\xe0\x8d\x2a\xb3\xe2\xe6\xd4\x9c\xba\x65\xa8\x85\x56\x08\xe4\xb3\x7a\xa0\x93\x1f\x42\x84\xec\x13\x88\x0c\xdc\xbf\x43\xb6\x7f\x41\xef\xdd\x37\x1b\x1b\x96\xb4\x7b\xf1\xfe\xf5\xac\x70\x5d\xb7\xee\x5d\xd8\xa9\x8f\x3e\x16\x79\x56\xc0\x08\xf9\xaa\xa5\x08\x11\x76\x81\xaa\x6b\x93\x4d\xca\x3b\x1d\x5a\x82\x4c\x75\x17\x97\xd7\x4f\xa2\xf8\x55\x5f\x7d\xa2\xb8\xe8\x90\x13\x6a\xfa\x33\x15\x69\xcc\x12\x5e\xc3\xb4\xdc\x43\xeb\xc0\xf8\x58\x4c\xd8\xe3\x1a\xb4\x56\x02\x0b\x82\xeb\xd7\xb2\x6a\xa0\xb0\x12\xdd\xe8\x49\x4f\x7f\x6f\x0c\x6e\x9c\xfb\x06\xc4\x61\x7d\xed\x7f\x0f\x89\x36\x30\x40\x45\x3e\xf7\xe9\xbc\x59\x9b\xaf\x1b\x28\x30\x94\xf6\x0a\xe7\x66\x62\xdf\x6b\x13\x5a\xfa\xa2\xe6\x15\x0e\xa0\xb7\x47\xb4\xcd\xa6\x5f\xcb\x24\x81\xaf\x42\x6c\x9d\x8b\xaf\xe8\x36\x20\x30\x96\xbf\x09\x3e\x40\x5d\xe8\x12\x12\x8b\x98\xf1\x9b\xdb\xde\x42\x23\xfc\xe6\x07\x91\xe6\xc8\x97\x91\x37\x6a\x9c\xfa\x04\x42\x6d\xfa\xfd\x09\xf4\x4d\x59\x76\x7f\xe5\x02\x0f\x58\x93\x15\x7a\xf7\x5a\x95\x05\x5c\x7d\x3e\x88\xc3\x88\x75\xca\x77\x95\xe0\xe1\xd0\xdb\xa3\x78\x2f\x2c\x21\xd4\x70\xc0\x80\x46\x09\x75\x92\x02\x3d\xc1\xf3\xf0\xcc\x06\x16\xd8\x84\x6f\x7b\x91\xd3\xf1\xd8\x7e\x50\x8b\xba\xf6\x45\x30\xe3\x7b\xf2\x48\x61\x64\xe4\xb1\xca\x5e\xca\xe1\xaa\x07\x9e\xd0\xc4\xe9\x27\xae\x97\x8f\x0e\x51\xdc\x35\x8a\x18\x77\x3e\x2c\xa6\xcb\x0e\x22\xdf\x7d\x1e\x61\x9c\xd6\xf4\x3d\xb5\x15\x10\xef\x0c\xa3\xbb\x52\xfd\x82\xa1\xda\xfd\xb0\x77\x4c\x08\x6e\xda\x79\x66\x60\x80\x11\x84\x98\xc9\xb8\x53\xe0\xad\x5f\xb3\xa3\x7f\x77\xcb\xbe\x7c\xe9\x14\x86\x98\x0b\xaf\x52\x84\x5f\x4b\x9c\xd3\xb2\xba\x9e\x09\x61\x48\x54\xf0\xa3\xcc\x4f\x45\x03\x50\x35\xed\x91\x87\x20\xa2\xa6\x7d\xe2\x6e\x5c\x52\x1e\xa4\x56\x27\xb6\xc9\x0e\xad\xd5\xf2\x5a\x1e\x8f\xbf\x15\x48\xfb\x9d\x8a\xc6\x68\xcc\x52\x95\xe2\x57\xde\x3c\xad\xf6\xed\x11\x67\xcf\xbb\xf6\xa0\xf3\x0f\x21\xe2\x08\xc9\x4f\x77\xe2\x17\xec\x6b\x04\x32\xb6\x4b\x72\xbf\x58\x6d\xfb\x2e\xb1\x25\xb9\x2c\xb3\xa2\x27\x4b\xa3\x20\x52\x86\x69\x7e\x6f\x78\x3b\xb0\x84\xdf\xcf\xed\x74\xeb\x00\x04\x20\xa3\x00\xd5\x86\xb7\x0f\x4b\x7f\x05\xc9\x93\xc4\xd2\xfb\xd4\xaa\xca\x10\x83\x10\x76\x6d\xa0\xe3\x41\x31\x95\x85\x54\x8e\xc2\x3b\xa0\xc2\x04\x41\xec\xf7\x65\x59\x0c\xd0\xba\xa0\x58\x4a\xb4\x95\x7a\xbb\xac\x3b\x37\xff\x99\x75\x60\xf0\x33\x83\xf5\x45\x31\x4c\xec\x9b\x22\x9b\xf0\xb0\xee\x99\x0f\xe3\x3b\x35\x46\x1b\x23\x9a\xc5\xa9\x80\xe6\x3c\x30\xee\xbc\x5a\x9b\x55\x5e\xf7\x97\x14\x31\x77\x5b\x44\xd6\xac\xf5\xc7\xae\x3c\x93\x1c\xa7\xa0\x65\x88\x21\xf1\x42\x54\xaa\xac\xaf\x3e\x67\xa2\x36\x00\x89\x2d\xa0\xb6\x68\xf3\xed\x6a\xf9\xf8\x70\xbd\xbf\x5e\x6f\x97\x8f\xcf\x0f\xbb\xfd\xfd\xf3\xdd\x6e\xbd\xb9\x5b\xaf\x3c\x98\x04\x20\x05\x03\x03\x9d\xf9\x47\xb3\x9a\x2a\x10\xcf\x1a\xbc\x00\x26\x45\x71\x32\x0d\xc7\x06\x8b\x12\x85\xe7\x7b\x1a\x3a\x31\x60\x84\xd5\x1a\xc0\x7a\x8d\xa2\x86\xa2\x3e\xd5\xd7\xd0\x88\x6c\x42\x8a\x48\x4d\x20\x39\xb0\x8e\xe3\xaf\xac\xce\x28\xaa\xa9\x09\xb4\xdd\xf8\x76\xc1\xbf\x87\xfb\x8a\x09\x8c\xc2\xe3\xa9\x6a\x2d\xae\xa5\x38\xce\x7b\x7c\x26\x8a\xb8\x97\xd5\xbb\x8c\x5d\x4f\x7c\xe7\x38\x40\xdc\x67\x79\x3c\x07\x0b\x4c\xae\x4b\xc2\x28\xea\xb8\x88\xb7\x33\x53\xcc\xf7\x93\x69\xdc\x27\xca\xb6\x27\xac\x88\xbd\x17\x4d\x33\x88\x96\x0e\x07\x0f\x25\x82\x42\xfb\x71\x4e\x17\xdc\x58\x43\x54\x22\xa8\x93\x3a\xea\x93\x82\x86\x46\x11\xe5\xa3\x60\xc5\xf2\xd4\x37\xea\x88\x0c\x05\x73\xc6\x57\x64\x71\x84\x49\xe1\xe5\xfd\xe3\xde\x81\xc4\x3a\x23\xc7\xb0\x34\x45\xae\xb6\xc3\x5e\x14\x22\xff\x6c\x32\x55\x77\x4d\x92\xe0\xec\x3e\x15\x59\xb3\x83\xba\xf9\x06\x4d\xc7\xb7\x31\x58\xb4\xe7\xaf\xc0\x20\xc4\xd7\x44\x92\x80\xfd\x55\x3b\x53\xff\xe3\x2f\xca\x43\xc6\x3b\x6a\xba\xb7\xac\x01\x18\xe5\xde\x26\x57\xe2\x9a\xe3\x6c\x7e\x87\xec\x3e\x2b\x06\xce\x9f\x89\x23\x5b\x77\xf8\x02\x8d\x93\x9e\xa8\xfe\x59\xca\xfa\xea\xd3\xa1\x54\xe6\xbe\xb0\x9f\x0a\xb1\xb2\xa8\x50\x9d\xd5\xe2\xa5\x82\x9e\x81\x69\x7c\xf3\x84\x53\x2c\x13\x6d\xb7\xd6\xab\xf5\x6e\x26\xdf\x6e\x92\x38\xf6\xdc\x05\xad\x9d\xd7\x9c\xa3\xfd\x4c\x4a\x05\x22\xc6\x4a\xab\x3d\xe0\xa4\x40\xbf\x39\x33\xe8\x1e\x9a\xd7\xa9\xc3\x6d\x52\xae\x2d\x79\xfc\x41\x54\xcd\x28\x06\x65\xd2\x44\xa0\x66\x8f\x15\xc2\x9a\xfe\x2e\xe5\xd8\xf8\x53\x14\xba\x41\x26\x8f\x29\xcc\xe6\x34\x55\x4c\xa3\x46\x70\x85\x99\x08\x2c\x92\x7b\x1d\x16\xc9\x19\x91\x70\x8c\x53\x1b\x21\xab\xcc\xba\x14\x5b\x61\xba\x4f\x20\xa4\x95\x37\x83\x42\x47\x13\xe1\x69\x6a\x24\x8f\xf1\x00\x68\x7e\x15\xe6\x5d\x8f\x56\xb7\x8c\x35\xe2\xd2\x0f\xfb\xa2\x2c\xd0\xa7\x5e\x4e\x43\xe4\x46\x8a\x10\x6b\xb2\x5d\x0e\x7c\x2a\x38\x36\x7e\x6f\x45\x6c\x00\xd5\xe1\x67\x06\x57\x1b\x7f\x2d\xc5\x74\x48\xd0\x32\x7a\x03\x91\x5f\xc1\x48\xc9\x87\x1a\x4d\x22\x3c\x06\xb6\xa7\x23\x54\x4b\x51\x49\x7b\xf6\x8c\x9e\x5d\x83\xe5\x4f\x40\x22\xa2\xb2\x80\xcf\x21\xee\xca\x80\x52\x58\x64\x72\x57\xbe\xb4\x76\xe6\x73\x31\x50\xdc\x1e\x3f\x8a\x61\xdc\x8a\xdf\x7a\xfd\xad\xbc\x2c\xce\xeb\x12\x26\xe9\xbb\x71\x94\xd7\x98\x38\x41\x6a\x4a\x9f\x75\xae\xcf\xb2\x44\xc6\x88\x58\xa4\x9e\x89\xf1\xe4\x2a\x5d\xd7\xfa\x4c\x75\x1a\xbb\xb3\x20\x60\x96\x50\xbd\x02\x55\x16\x2a\xcb\xe1\xda\x55\x27\xfd\x31\xe9\x27\x02\x8c\x44\x62\x8d\x8a\xa8\x07\x23\xc4\x82\x30\xd2\x54\x7a\xf1\xd6\xf6\xe3\x7e\x61\x6d\xb3\x20\x64\x41\x10\x74\x44\x1a\xcb\x57\x51\x09\xd5\x74\x84\x0b\x5d\xaf\x44\xa3\x4f\xb1\xae\xca\xe2\x56\x14\xba\x8e\xba\xbb\x09\x83\x9f\xfe\xf1\x08\xc5\x5d\x59\xbc\xc0\x5b\xd6\x7c\x8e\x1c\x74\x16\x84\x3a\x91\xc9\x84\x8f\x74\xbd\x7c\xbc\xf0\x44\x11\xd1\xe8\xff\x98\xf2\x54\x68\xa8\xa2\xe1\xfa\x63\x41\x44\x53\x64\x8c\x42\xbf\xcf\x7a\xdf\x9d\x93\xc4\x82\x48\x69\x15\x0c\x19\xd7\xe1\x61\x7d\x7f\x9e\x91\x9b\xdc\x91\xc4\x32\x1a\xf0\x03\xdd\x21\x0d\xc9\xac\xb1\xca\x02\x22\x52\x24\x8b\xca\x41\xbc\xc1\x0e\xc4\x19\xa4\xda\xf5\xa3\x51\x12\xb8\x24\xd7\xa2\xb6\x91\xa2\xdf\x24\x48\x59\x40\x65\x80\x4b\xf6\x80\xe0\xd2\xef\xf0\x39\x76\xa3\x58\x40\xc1\xda\x79\x79\x29\xf4\x3e\xef\x74\xfd\xc2\xbe\xdd\x60\x74\xfe\x58\x1e\x6f\x45\xe3\xe5\x6f\x59\xc0\xa2\xc8\x93\xcc\x3d\x94\x03\x60\xda\x84\xbf\x79\xb0\x18\x59\xc0\x52\x9b\xdf\x3c\x88\x5f\xe0\xb8\x51\xa6\xdc\xda\xe3\x87\x63\x22\x4a\xbd\xca\x5a\xa7\xb8\xd1\xcd\x13\x26\xd2\x48\xf7\x9c\x28\x97\xe8\x06\x59\xc0\xc0\xd2\x29\xfe\x2c\xf3\x5f\xd7\x96\x18\xf5\x02\x2c\x9b\x05\xcc\x30\x8c\x78\xff\x79\xca\xd4\xaf\xba\x44\x79\xcf\x9e\x9f\xe0\xe2\xf7\xe6\x3a\x06\xd6\x95\xbc\x1e\x1b\xd8\x93\xd0\x3f\x27\x37\x0a\xc3\x1a\x02\xd5\xc4\x7e\x88\x1c\x8a\x26\x2b\xbc\x44\xe2\x64\x19\xc6\xd4\x20\x87\xbc\x23\x70\x5d\x14\xc8\x24\x37\xe9\x94\x24\xee\x88\x2a\x8f\x17\x09\xe1\x5c\xd7\x34\xb0\xe2\x99\x59\x7d\x53\x56\x13\xfa\x00\xdf\x85\x08\x2c\x84\xb3\x51\x36\xeb\x55\x0e\xa2\x75\xbe\x97\xe4\x08\xff\x73\x42\xb7\xe3\xe1\x8b\xa8\x73\xf0\x27\x53\x3b\x55\x0c\x5f\x7d\xb3\xde\x6c\x97\xb7\x8b\xf5\x83\x1f\x13\xe1\x52\x05\x4a\x14\x9e\x77\x78\x2e\xbd\xec\x7b\x3b\x52\x8b\xca\x6d\xbd\x73\x94\x39\xc9\x78\xae\x09\x19\x61\xc6\x73\xdb\x94\xc7\x9e\x59\xa9\xfd\x7b\x8c\x21\x45\x6b\xdf\x2d\xcb\xd3\x31\x07\xd4\x1a\x5e\x6f\x6e\xb6\x7d\x4c\xc7\xf7\x56\x06\x71\x85\x4d\xa7\x8e\xbb\x11\xd5\x0c\xeb\xd0\x39\xca\x78\x70\x11\x49\xad\xe3\xe3\x55\x18\xd6\xba\x3e\x77\xc9\x59\x20\x19\x41\xe8\x88\xad\xc7\xea\xbd\x80\x7d\x9f\x6a\x65\x81\x8c\x39\x52\x22\xe4\xa2\x6e\x56\xd6\xeb\x99\xa4\x47\x59\x20\x85\x44\x91\xa7\x7e\xc7\x5a\x3e\xed\x7e\xbf\x65\x29\x41\xb9\x43\x8b\xae\x97\x8f\x37\x58\x45\xeb\xe3\x1f\x2c\xd0\x24\x0d\xa9\x67\x3e\xea\x69\x25\x9b\x1e\x74\xc4\x02\x90\x36\x02\xf5\x78\xfb\xed\xee\x24\x8a\x97\x4d\x25\xa4\xf0\x68\x0c\x16\x80\x32\x58\xf0\x27\x45\x9d\x29\x5b\x43\x33\xa0\x5b\x65\x81\x09\x25\x1e\x6c\x7b\x84\xf2\x5b\x65\x86\xde\x06\x99\x83\x6d\xb2\xc0\xa8\x00\xcd\x7a\x93\x67\xc7\xfa\xae\xa3\xb4\x61\x61\x40\x62\x2c\x73\xb6\x74\xca\x5d\x45\xd8\x28\x62\xc7\xc2\x40\x59\xe6\xbf\x95\x15\xeb\xf1\xe5\xb5\x13\xe7\xe7\x22\x7c\x70\xae\xce\xa9\xbb\xb2\xd2\x58\x6c\x31\x0c\x57\xfa\x87\x0b\x43\x9b\xd6\x42\x9f\x0c\x89\x78\x7d\x82\x8c\x85\x61\x44\x50\xc5\xb3\xf5\x3f\x6f\xf2\x52\x34\x83\xaa\xd0\xb6\xd5\x20\xa4\xf2\x1d\xf2\x76\xfc\x06\x92\xf8\x2c\x8c\x5c\xd9\x70\xfb\x4b\x4b\xdb\xf8\x1d\x3e\x07\x10\x5e\x16\x46\x51\x84\xfe\xe0\x5d\xf9\x62\x49\x52\xa6\xc8\x9f\xb1\x36\x11\xed\x93\x38\x2c\x24\x82\x63\xf8\xb3\x2e\x73\xbd\x6e\xe0\xd0\xdd\x96\x12\x89\x07\xf9\xed\x43\x07\xbd\xf5\x2d\x60\x53\x6c\xbb\xc5\xd3\xb7\xd5\x6e\x7f\xfd\x8c\x35\xd5\x0f\xfb\xab\xd5\x0e\x09\xc7\xae\xee\x1e\x97\xdf\xbb\xce\x26\xc0\x80\xd1\x76\xb7\xf8\xb6\xda\xef\x6e\x9f\x56\x2b\x0c\x7d\xec\x57\x0f\xd7\xbe\x0f\xe3\xb6\xb0\x79\xb9\x5a\xfe\x0e\x71\xce\x42\xce\x01\x44\x7f\x3c\x38\x0e\x82\x2e\x0c\xd5\x11\xf6\xb3\x90\x83\x23\x19\x6b\x5e\xaf\x21\x6f\x84\xc3\x91\x8d\x2a\xb7\x59\x18\x93\x10\x71\x53\xd6\x6b\xbf\x59\xdf\xec\x6e\xf7\x7d\xed\xa4\xef\x95\x00\xc7\xc5\xbe\x17\x5a\x23\x27\xe0\x2b\xca\x4d\x8f\x37\xb4\x30\xa5\x02\x89\xae\xef\xc7\x60\x0c\x16\xa6\x4c\xa2\xfb\xab\xf6\x1a\x71\x81\xdd\xdf\x79\x10\xf8\x84\xc4\xe3\x66\x90\x8d\x68\x9b\xc2\xc4\x81\x8a\xbc\xa0\xdc\x2e\x83\x2a\xb2\xf5\x24\x53\x66\x56\x16\xca\x38\x25\xae\xe4\x64\x2f\x8e\xc7\x93\x5b\x18\x83\xbd\x3e\x54\x51\x8a\x59\x4d\xcf\x43\xb8\x7b\xad\xa0\x6e\x5f\xc4\x9f\xbd\xa1\x8a\x19\xeb\x58\x15\xcb\x42\x89\xe6\x1e\x0e\x65\xf5\x49\x88\x45\xc5\xf9\x6e\x52\x61\x1e\xc5\x0a\x06\xbb\x3f\xea\x40\x21\x4f\xc7\x1e\x79\x02\x6f\xca\xea\x09\xac\x63\xdc\x8e\xd3\xb0\x3c\x63\xbc\xd6\x43\x1d\x92\xd4\x69\x53\x9c\x14\xfc\xa6\x66\xd8\xff\x86\x06\xa1\xe9\x22\xcd\x2f\xd0\x13\xb9\x4f\xba\xa9\x8e\xac\xd2\x46\xb0\x7e\x3c\x6f\x7a\x0c\x08\x0b\x35\x0f\x4d\x7b\x9d\xdd\xab\x28\x44\x53\x76\x2f\xa8\x63\xcd\x3c\x66\x29\x6b\x26\x30\x14\x16\x6a\x25\xd0\x7a\x5a\xfc\xf8\xf6\xf8\xd0\xcd\x11\x08\x13\xcb\x34\xa7\x7a\x8b\x36\x34\x34\x26\x9d\xc2\x9b\x67\xe2\x1f\xac\x3f\xc3\x00\x23\x6c\x42\x6b\x4b\x9e\x35\x8f\x17\xf1\x6f\xd4\x3a\x9c\x88\x09\x13\x39\x0c\xb2\x3d\x2c\x34\x92\x0b\x5b\x47\x65\x9a\x75\xd1\xce\x14\xd7\x12\x05\xb1\x55\x7e\x94\xa7\x3a\x2b\xa0\xae\x37\xb9\x28\x0a\xbf\x56\xae\x4f\x43\x5d\x75\x16\x85\x09\xa0\xbf\xed\x39\x0a\x9e\xe0\x38\x24\xee\x44\x31\xf7\xab\xb2\xd0\x36\xa3\x3e\xb1\x3a\xa3\x08\x14\x16\x87\xef\x2d\x93\xd4\x0c\x59\x0f\x8b\x08\xb5\x55\x97\xed\xd6\xbe\x42\x97\x31\x2b\x8b\xed\x7b\xd6\xa8\xd7\x5d\x39\x18\x99\x88\x30\x1b\xec\xed\x00\x84\xd6\xca\xaf\x5b\x53\x7a\x51\xf8\x02\x58\xff\xc9\x22\x92\x30\x8b\xfe\x6a\xca\xe3\x90\x59\xb1\x6d\xe1\x3c\xf0\x8e\x40\xc7\xfd\x3b\x55\xee\x66\x11\xe5\x21\x1e\xb0\x96\xeb\x79\xf6\x94\x70\x2b\x29\x62\x61\xc4\x53\xcb\x31\xe3\xfd\xae\xee\x41\x18\x15\x26\xf1\x21\x29\xfc\x46\x37\x65\x75\x7b\xb7\xb9\xdf\x75\x3d\x12\x81\x81\xc2\x41\x06\xfa\x92\xe1\x1a\x31\x25\x2d\x08\xab\x2c\xf3\xe1\xfe\x10\x31\xad\x8c\x73\x1b\xda\xcd\x6f\x24\x72\x3a\xbe\x44\x1c\x70\xaf\xe3\x74\x9f\x15\x4f\xe8\x70\x4d\x02\xf6\x83\xce\x2a\x41\x65\x17\x47\x47\xb3\x59\x3d\xed\xbf\x23\x93\x8e\xbf\x6f\xac\x35\xba\xde\x7b\x38\x64\x16\x98\x3f\x28\x7f\x9b\x37\x98\xfc\xb9\x1c\xa5\x91\x0d\x43\xec\xeb\x76\x0b\x75\xa9\xaf\xb3\xc3\x6a\xf6\x1a\xc9\xfc\xee\x11\xa5\x89\x40\x87\x45\x9e\xaa\xaf\xc3\xa6\x2c\x4a\x9d\xd8\xa2\x53\x6f\x9c\x6c\x34\xe3\xbe\x82\xda\x22\x88\x43\x56\x34\x8f\x3f\xef\x2e\xf5\xd2\x3c\xb5\xc8\x4e\xfd\x02\xcf\xc5\x50\xb2\x90\x45\x02\x22\xda\x29\x22\x1e\x4e\xcd\xa5\x5b\xc9\xc4\xb2\x97\x62\x44\xca\x51\xcc\xe8\xd0\x1d\x56\xfe\x62\x52\x2a\x74\x8a\xce\x24\x30\x2e\xd9\x32\xe3\x45\x27\x75\xac\x1c\x29\xc3\xf6\x5d\x38\xab\x8b\xfd\x63\xf8\xcf\x74\xc7\x09\xcf\x10\x6b\xff\x18\xf2\xa0\xb2\x48\x51\x66\xf7\x7b\x1b\x51\x5b\xe6\xe5\xfb\xff\x8d\xad\x9e\x45\x26\x62\x58\x55\x37\xa9\x80\x1c\x8f\x8f\x89\x63\xd9\x53\xe3\xaf\xac\xae\xc7\xac\xcb\x1d\x19\x91\xa4\xc8\x19\xfe\x56\xe6\x6f\xe0\x02\x77\xfe\x8a\x61\x77\x41\x13\xda\x1c\xc8\xf5\x6e\xbc\x37\x91\x20\x62\xa9\xa5\xa0\x40\x41\xf8\x3c\xab\x1b\xef\x58\x56\xd3\xae\x89\x65\x22\xb5\x89\x08\x9f\xbf\xba\xeb\xa4\x6e\x19\x09\x13\x92\xb8\x65\xb7\x42\x20\xcd\xe7\xb2\xa9\xf2\xc9\x65\x42\x61\xb0\x58\x6b\x77\xbb\x7e\xf8\xbe\xdf\x2d\x1e\xbe\xef\x6f\x9e\x1f\xae\x47\x55\xa9\x8c\x84\x4a\x61\x24\xf6\xae\x7c\xb1\x25\x5d\xab\x1f\x0f\xf3\xb3\x89\x84\x5a\x62\xa4\xc9\x25\x21\x7e\x2e\x36\xbd\x81\x76\xfb\xf8\xfc\xd4\x5d\x33\x22\x1a\x83\xd7\xc7\x57\x51\xc3\x9e\xed\xe5\xc0\xe6\x24\x11\x24\x49\xd2\xe9\xa2\xfe\xba\x29\x2b\x44\x7a\x8e\x6f\x45\x78\x8c\xa1\xec\xab\x9b\x9d\xea\x12\x3f\x8c\xd0\x50\x62\xcc\x10\xd3\xb7\xd9\xf1\x08\xe7\xa2\xd2\xd3\xa8\x42\xbf\xeb\x13\x4a\x62\x16\x0d\xb4\x84\x57\xc3\x7c\x2d\x23\x54\x06\x51\xe4\x96\x7b\x7b\xd4\x0d\xad\x2c\x42\x75\x68\xc9\x7b\xb3\x2a\xbf\x6a\xbd\x91\x51\x2b\x57\x7c\xe0\x3a\x2c\xf2\xbc\xa3\xf7\x70\x1d\xe2\x20\xc1\x92\xe3\x1e\xa1\xf4\xa3\x6c\x40\x5b\x3e\xda\x69\xc6\x6a\x76\x8b\x21\x31\x07\xac\xf2\xd9\x59\x92\xa3\xf3\x92\x72\x46\xe2\x98\x68\x35\xa4\xc2\x40\xd1\x90\x73\xbe\x20\x46\x12\x62\xbc\x45\xd7\x7b\x66\xe3\x98\xb9\xef\xc9\x08\xa2\x49\x6c\x28\xa2\xcb\xaa\x62\x79\x84\x7f\xbb\x34\x65\xc6\xf8\x68\xbe\xca\x4f\x1a\x9c\xf7\x32\xa0\x27\x67\x44\xa4\x96\xc6\xee\xfe\xd3\x11\x6a\x63\x94\xb6\xcb\xdf\x8d\x6f\x2b\x03\x89\x0f\xb8\xaf\xe0\xe5\x94\x8b\xea\xda\x71\x42\xd5\x03\x59\x67\x46\x24\x49\x51\xdb\x61\xa0\x6f\xb7\x1c\x4c\x17\x99\x68\x44\xb9\x63\x16\xcc\x2a\xd8\x5d\x16\x35\x9d\xa0\x23\x18\x91\x2a\x21\xac\x0b\x4a\x4e\x51\x23\x8c\x48\x0d\x08\x8e\x41\x1e\x94\xcd\xd3\xfa\x47\x6f\xd3\x13\xc5\x94\xaf\x63\xdb\x65\x79\x4f\xf9\x7a\xea\x59\x17\x43\xaf\xb9\x36\x7e\x71\x1d\x08\x04\x89\x0a\x7d\x68\xfd\xe9\x66\x00\xcd\x65\x44\xa7\x9a\x25\xc8\xe6\xa9\x2d\x3c\xb5\xdd\xaf\xc6\x4f\xa5\x45\xea\x50\xd0\x5d\x71\x1d\xe2\x63\xfd\x25\x0c\x25\x5e\xbf\x41\x89\x63\xd1\x57\xb9\xfa\x76\x19\xe0\x76\x9e\xd5\x4b\xcb\xa1\x98\x95\x85\x93\x85\x5e\x34\x5e\x49\x66\x7c\x6c\x76\xbf\x14\xc6\x07\xc5\xf7\xab\xdd\xed\xde\x54\xe5\xc1\xe2\xde\xa7\x7c\x41\x8c\x18\x1d\x61\x64\x72\x7f\x28\x75\x66\x3e\x37\xd9\x07\xe4\xcb\x32\xf7\x12\x61\xf3\xc1\x21\x1a\x84\x21\x92\x62\x60\x96\x62\xf5\x61\xa5\x61\xc6\x98\x20\x46\x83\xd4\xa2\x83\xeb\x46\x14\x5a\x54\xfe\x9c\xa3\x21\x0d\x10\xfb\x89\x94\x3e\x2e\x73\x35\xb2\x21\x68\x98\x86\x1d\x9f\x2a\xe5\xfe\x77\x44\x13\x94\xb4\x46\xb1\x71\x93\x15\x7d\x18\xe6\x72\x30\x89\x52\x65\x2c\xb9\x08\x28\xf1\x09\xda\xe9\x0a\x2c\xc5\x84\xa0\x95\x51\x16\x86\x88\x12\xa9\x4f\xb2\x23\x01\xeb\x2b\x45\x7c\xa7\x98\x69\x3e\x4b\xce\xf2\x8f\xc9\xd5\x92\x40\x29\xc7\x5a\xb6\x97\xf9\x09\xf6\x87\xac\x10\x03\x9e\x52\x46\x59\xaa\x71\xcd\xac\x1f\x7e\xac\xb6\xbb\xc7\x27\x1f\x28\xa2\x3c\x0a\xb1\x1a\x35\xab\x6f\x30\x4e\xdc\x47\xb4\x29\x8f\x2c\xfd\x5e\xeb\x66\x9c\x1a\xb8\xff\x5c\xbd\xbc\x4c\x36\x0a\xca\x99\x4d\x21\xa2\x29\x6c\x71\x24\x33\xa4\x45\x8c\xc6\x81\xc6\x82\xba\xac\x81\x03\x62\x41\xdc\xdf\x13\x27\xd1\x5e\xc0\x87\xe5\xed\xec\x51\x1d\x8c\x26\x82\xa1\x2b\x63\x8f\xc4\xab\x53\x55\x9c\x6c\x8c\x6e\x7c\xed\x54\x6b\x74\x12\x7e\x64\x8d\x38\x74\xfb\x00\x15\x91\xd6\xca\xeb\xd2\xb4\xde\x03\x22\x06\xe7\x47\x50\x92\x84\x0e\xad\xa1\xab\x53\x96\x6b\xbf\xdf\x4e\xdf\x59\x29\xcb\x61\x70\xf0\xea\x44\x35\xea\x1a\x20\xb9\x95\x3f\xf0\x10\x93\xd8\x3e\xd4\xe3\x66\x7b\xc6\xee\xc6\xa8\xa6\xa1\xee\x49\xbb\x5a\xef\xa2\x68\x4a\xa4\x8c\x3d\x4d\xc1\x5e\xff\x18\x9a\x1a\x54\x8b\xc4\x52\xe7\x6b\xfd\x53\xd4\x0d\xe0\x58\x8e\xe6\xa0\x96\x06\x93\xf4\x97\x52\xff\xbe\x9b\x0e\xb1\x9a\xea\x26\x17\x2f\xdd\x53\x69\x5b\x25\x68\x95\x7c\xce\x4a\x33\xfd\x3e\x36\x1e\x0d\x20\x29\xa2\x89\xaf\x76\xf7\x77\xfe\x42\x10\xbb\xbc\xa7\x31\x88\x6d\xeb\x23\x66\xf3\x4f\xc3\x02\x25\xf1\xbc\xa9\x44\xf1\xeb\x42\x97\x30\xb5\xe0\x83\x06\xea\xe6\x98\xe9\x17\xe8\x7c\x4c\x16\xa6\x80\x94\x83\x3f\x45\x81\x99\xcf\xe1\x29\xcd\xa2\x80\x23\xae\xf0\xed\x02\xf8\xd1\x77\x0b\xa5\xa5\x0d\x29\x45\x31\xf1\x61\x5b\x43\x1f\xfd\xb8\xd5\xd6\x93\x68\x32\x16\xc9\x08\x43\x4c\xcd\x6b\x05\x42\x4f\xfc\x56\x16\xe9\xd4\x8a\x9d\x5b\xd6\x7d\x4b\xbe\xef\x76\xac\x75\x71\x3c\xfd\xb6\xe6\x61\x16\xc8\xc2\x18\x89\x41\xc3\x28\xce\x3c\x43\x7f\x30\x19\x38\x92\xd2\xa0\xd3\x0f\xb2\x70\x8c\x75\x61\xac\x66\xc6\xc8\x8e\x65\x94\x59\xc4\x30\x16\x56\x9d\xe5\x50\x19\xa3\x90\xe0\x3e\x53\x1a\x94\xd3\xcc\x6f\xbb\x5a\xcc\xb6\x2d\x45\xa0\x98\x35\x13\x97\x8f\xf7\x9b\xc5\xc3\x7f\xf6\x8f\x3f\x1f\x56\x3e\x2a\xc7\x58\x44\xc0\x8a\xe0\x89\xa6\x3f\x21\xba\x46\x4b\xcd\xf5\x5e\x36\xd7\x62\x72\xbc\x31\xc6\x2d\x6a\xe8\x07\xbc\x88\xba\xfb\x85\x4c\x42\x3b\x67\x1a\xf0\xf1\x26\xc6\xa3\xd8\xeb\x7a\x22\x2a\xd9\x72\x6f\xdd\x94\x15\x02\x95\x27\x97\x4d\xa2\x04\x13\x88\xcb\xd5\xc3\xce\x9b\xb1\x2c\xa5\x61\x3c\xd4\x95\x92\x42\xfd\x3a\x1d\xfb\x56\x9e\xa8\x9e\x53\x22\xff\xb4\x71\x42\x47\xf1\x35\x1e\xae\x94\x73\x64\x50\xbf\x2d\xf3\xb2\xd7\x1d\xf1\x8d\x31\x60\x0c\xdc\xf2\xff\x1e\xa1\x6a\xe6\x14\xb6\x3b\x88\xf0\x10\x29\xcc\x98\x90\x29\x1a\x1a\x47\xb0\xcf\xb8\x2e\x2c\x0f\xf9\x3f\x4f\xd5\xf9\x21\x31\x35\x71\x98\x8c\x88\x72\x70\x78\x3c\x4a\xef\x40\xbc\xf9\x3d\x97\x49\x92\x62\x7a\x77\x03\x4d\x0f\x4b\x6f\xc7\xda\x78\x97\x1f\x81\x39\x7a\x86\xd4\x8c\x31\xa9\x35\x4e\x90\x87\x9b\x9d\xb3\x05\xaf\x7a\x23\x84\x49\x30\x0e\xce\xf4\xfc\xf4\xb0\xb8\x5f\x3d\xec\xf6\x7d\x50\xa0\xfd\x06\xbe\xa3\x4a\x0d\xb7\x12\x87\x6f\x90\xb7\x63\xe3\x9c\x58\xdf\x0e\xca\x04\xae\x2e\xcf\x03\xb6\x9e\x66\x48\x2f\x5c\x6f\x43\x43\x0c\x18\x7b\x04\xdb\xa4\xea\xe3\x37\xff\xda\x8b\xf0\x20\x4e\x88\xcb\xcd\xdc\x89\xda\x55\xda\xfd\xe1\x1b\x85\x60\xde\xee\xeb\xe4\xb3\xeb\xf3\x5c\xa0\xff\x02\x3c\xd0\x34\x64\x03\x79\xfe\x49\xec\x8d\x87\x01\xe7\x1e\x25\xf7\x70\x3a\x58\x13\xa2\xee\x5a\x69\x84\xf0\x97\xd6\x65\x71\xa5\x11\x5f\x27\xf7\x78\x08\x91\x49\x3b\x3e\xf6\xc1\x76\x3c\x55\x5b\x62\x3c\x0a\xc0\x1b\x1d\xeb\xf6\xac\x2e\xff\x66\x72\xc3\xff\x5c\x4b\x2c\x73\x7b\x57\x5e\xb1\x92\x71\x12\x86\xda\x6d\x40\xf7\x45\x73\xbc\xcf\x5e\x06\x4e\x74\x7f\x67\x12\xd9\xf4\xa2\x93\x6c\xd3\xab\xe6\xb5\xbb\x02\x8d\xd0\x03\xc4\xf2\xa2\xab\x2c\x17\x0d\x0c\x55\xb6\x47\xf6\x1c\xa7\x52\x26\x9e\x92\xbd\xd4\xb0\xd6\x1f\xa3\x03\x92\x53\x6d\x99\xb7\x6b\x68\x9e\xab\xbc\x9e\x29\xd7\x61\x9c\x82\x88\x9d\xc2\xd5\x5e\x8a\xe2\xd7\x5e\x8b\x46\x8c\x97\x37\x67\x44\x20\xe6\x14\x49\xc2\xc1\x95\x90\x4e\xde\x89\x25\x6c\xb4\x5f\xcf\x80\x22\xba\x9e\x29\xe2\x77\x36\xa7\xe3\xf0\xf8\xe2\x3c\x24\x96\xb6\xb3\x54\xbf\xae\x9c\x66\xac\x6f\x22\x09\x96\x1d\x1d\xb2\x91\x46\x59\x57\x3f\xcf\x38\x57\x21\x16\x93\xec\x8b\xb2\x3a\xe0\x4e\x71\x0d\x2a\x3b\x88\x7c\x1e\x80\xc6\x78\x1c\x19\xab\xde\x29\x2a\x29\x5e\xc0\x39\x03\xfe\x72\xb1\x88\x11\xac\xd0\xee\x63\x3e\x85\x60\x53\x3c\x33\x53\x7d\x3e\x42\xc3\x93\x20\xe0\x66\x80\x05\xff\xad\xa4\xbb\xff\x5d\x68\x10\xec\xde\xe9\x3d\xfe\x2e\x60\xe5\x7f\xc7\x02\x04\xf2\xbb\xe0\x29\xac\x97\x8f\x45\xf9\xee\xdf\x28\x49\x13\x87\x4c\xf7\xe9\x78\x1a\xf4\x6d\x22\xe9\xf3\x38\xcb\xa7\xd5\x62\xb7\xba\xde\xdf\x77\xb9\x69\x9e\x86\x12\x0f\xd6\xbd\xcc\xf4\xf5\xaf\xfc\xc2\x90\xa6\x3c\xe2\x36\xc0\x5e\xec\x76\xbb\x65\x9f\x7a\xe4\xa9\x88\xcc\xd0\x71\x0f\x27\x53\x42\xb0\x30\xe6\x1e\xc0\x53\x37\x4f\xa0\xa0\xf0\xca\x64\x98\x9f\xf0\x17\x92\x89\x0d\x6c\xef\x56\x8b\xfb\xfd\xd5\xe3\xc3\xf3\x74\x47\xe5\x8a\x73\xcc\x5b\x20\x71\xee\x1a\x51\xd8\xe3\x45\xa1\x63\x81\x3c\x10\x1b\xa1\x60\xe0\x4c\x73\x08\xac\x22\xe7\xcf\xb2\xca\xf5\xf2\x74\xfc\xb2\xf8\x94\x71\x70\xf9\x11\x74\xd5\x86\x25\x0d\x8c\x43\x42\x2d\x35\xa6\x73\x51\xff\x3c\x65\x55\x05\xf9\x00\x43\xc5\x38\x48\xab\x71\xbe\xfd\xb6\x1a\x2e\x82\x38\x0c\x2c\x87\x4d\xaf\x69\xeb\xbd\x8c\xd1\x58\xc7\x21\x4f\xd1\x53\x76\xa0\xcc\x63\x9e\x35\x7f\x8f\x98\x85\xc5\xa1\x16\x68\xfb\x38\xd8\xc2\xa2\xae\x51\x1b\xc2\x3f\x41\x14\xc4\xdc\x6d\x1a\xd7\x95\x78\x9f\x9a\x46\x71\xe4\xd8\xeb\xeb\x93\xac\x85\xb9\x70\x14\xc5\x51\x1c\x2a\x6d\xc3\x6e\x96\xb1\xac\x0f\x94\xc4\x51\x6c\x98\x93\x8d\xc9\x8a\x3b\xd0\x1d\xd9\x35\x42\x38\x31\x79\xdd\x94\x2f\x2f\x39\xac\x8b\x4d\x2e\x3e\xff\x59\x0e\x88\x1d\x59\x4c\x12\x8e\x9e\xe7\xa6\x12\x85\x86\x0f\x4b\x5a\x32\x1a\x43\x92\x48\xa5\xfd\x18\x5a\x41\x05\x8c\xd5\x0c\xa7\x41\x4c\x89\xaf\x36\x76\xec\x46\x0f\xe5\x99\x2f\x17\x53\xc5\xd1\x75\xf8\x3e\x41\xc8\xb1\x98\x85\x0c\x89\xf4\x4e\x85\xc9\x3e\xfa\xa3\x70\x5d\xfc\x84\xac\xeb\xa3\x92\x30\xe8\xe8\xb7\x07\xa5\x7d\x8b\x42\x6f\xdd\x22\xdd\x7e\x41\x09\x35\x19\x52\x9e\x24\x96\xb1\xbb\x3c\x1c\x4e\x45\xd6\x7c\x3a\x3a\x70\xfa\x1f\x10\x5d\x2e\x27\xe6\x26\x8e\xa2\x51\xde\x6e\x97\x41\x35\xd8\x4c\xe3\x38\x4d\xb1\x62\xe1\x28\xea\xba\x7c\x83\xca\xb3\xc0\xfb\x66\x61\x09\x91\x8f\xa8\xd9\x3f\x9a\xd9\x71\x62\x34\x5a\x8c\xe2\x78\xcc\x3f\x6f\x9c\xd0\xca\xa0\x31\x61\x03\xd1\xa5\xe0\xac\x5c\x9a\xc5\x22\x54\x68\x36\x19\x7a\x61\xde\x08\x15\x21\x1f\x04\xae\x42\x6f\xeb\xc6\x42\xb3\x80\x78\xa8\xc5\x53\x39\x8d\xa6\xc5\x42\x73\x10\x3d\x23\xe3\x0c\x42\x95\xc5\x02\x62\x44\xfb\xcb\xd6\xe1\x5d\xeb\xe8\x6c\x57\x9d\x7e\x85\xe1\x73\x4b\x48\x98\xf6\xf0\xd6\x45\x6b\x81\x7a\x8e\x1a\xff\x88\x3a\xa6\xb8\x2c\x64\x2e\xba\x3c\x46\xac\x63\x0b\x55\x7d\x82\x76\xee\xa9\x06\x34\x52\x2d\xd7\x33\xf6\xef\xf9\x50\x68\x69\xeb\x16\xeb\xec\xa5\xb8\x2b\xc5\x04\x01\x14\x43\x44\x78\xc7\x18\xd3\x25\x1a\xfd\x9d\x81\x13\x4c\xa7\x43\xeb\x6f\x0f\x38\x03\x59\x0c\x10\x7b\xc2\x1f\xd4\xe9\x58\x77\x2d\x46\x45\x88\x96\xc8\x95\xfa\xd8\x81\x70\x6a\xe6\x6e\x96\xb9\x4e\x49\x40\x15\xe9\x8a\xd7\xea\xf2\x00\xbd\x9e\x22\x4b\xc2\x90\x22\xc4\xc8\xe6\x1b\xc6\x10\x8f\x24\x8c\x78\x12\x8f\x40\x38\x78\x03\x24\x37\xf9\xda\xb1\x4b\x42\x12\x24\xcc\xe3\x85\x7c\xf8\xa5\x9e\x17\x5d\x66\x49\x98\x68\x44\x0f\x22\xe8\xd6\x2b\x58\x6c\xda\xdd\x02\xba\x67\x01\x85\x84\x36\x37\xeb\xa7\xed\x6e\xff\xe3\xf1\xee\xf9\x7e\xb5\x5f\xfd\x7b\xf7\xb4\xb0\xa7\x4a\xd7\xcf\x84\xe0\x22\xbf\x9b\x4c\x95\xc7\xda\xc9\x81\x4f\x77\xc5\x24\x22\x12\x91\x3c\x78\xec\xa0\xee\x9c\x9b\xfd\xb3\x46\x76\x12\xe9\x28\xb5\x86\xed\xe7\x38\x4a\x9f\x44\x06\xd0\x53\xdb\x9c\x0a\x9d\x0d\xeb\x05\x58\x42\x48\x8a\x80\xf3\x8e\x9e\xfd\xdb\x49\x54\x3a\x13\xc5\x1c\x78\xff\xeb\xcd\x24\x21\x3c\x46\x63\xe1\xfa\xdb\xd5\xdd\x7f\xfc\x0d\x28\xb1\x25\xd0\xcb\xac\xc9\xfe\x9a\xa0\xc0\x59\x42\xa5\xc1\x03\x72\x5b\x9a\x46\x79\x89\x27\x96\xb0\x24\xf5\xc1\xf1\x45\x56\xe9\xaa\x3c\xab\x63\xf8\xcd\xa3\xb0\x34\x40\x28\xaa\xd3\xa0\x7d\x15\x07\x68\xfe\xfa\x3a\x1f\x99\x70\x1e\x70\xe7\x17\x59\x5c\x8f\x35\x49\xc7\x50\x4b\xdf\x37\xb1\x89\x85\x45\x17\x71\x96\xd3\x0d\x24\xe1\x8a\x6b\x07\xab\x3c\x8f\x61\x25\x5c\x1b\x54\xe5\x43\x70\x92\x03\x91\xbc\x66\xe7\x16\x82\x73\x60\x07\x1b\x47\x12\xc7\x12\xc3\x5f\x07\x91\x15\xcd\x90\xa1\x98\x25\x71\xa2\xa9\xc5\x7e\x7e\x6c\x87\xe9\xe9\x24\x56\x0c\x83\x30\xfd\x77\x06\xa7\xe6\x35\x76\x92\xcf\x87\x25\x65\xa1\x1e\xf0\xc4\xed\x2b\xf8\x5f\x50\xcd\xde\xa6\x6d\x2e\x29\xd9\xb3\x24\x55\x52\xba\x50\xdb\x26\x9b\xc6\x0e\x12\x11\x0a\xc7\x9e\xde\x9c\x2e\x7f\xdb\x2f\x61\x7f\x17\x56\x81\x60\x04\xa1\x22\x98\x47\xdb\xe0\x79\xd3\x4e\xe5\x68\x7f\x53\x95\x07\x3f\x1a\x42\x1b\xc4\x91\x2e\x2d\x63\x91\x73\x90\xeb\x61\x4d\x30\x4b\x24\xb5\xa8\xca\x53\x8d\x05\xfe\x1d\x63\x01\x4b\xa4\x0c\x94\x2d\xd1\x12\xb9\xb3\xa8\x86\x2e\x66\xa2\x22\x16\xda\xd8\x29\x42\x50\x7d\xea\x25\xd1\xc4\xf2\x9b\xb7\x57\xac\x97\xa2\xe8\x52\xd4\xbd\x21\x93\x40\x44\x10\x00\x6a\xba\x14\x13\xae\xd7\x5b\x8b\x6f\xf2\x9d\xb4\xe5\xb3\x5d\x6f\xaf\x2c\x52\xb2\x1e\x58\x9d\x89\x51\x11\x26\x31\xef\xb2\xc3\xf8\x38\x4d\x0c\x58\xf9\x7e\x97\x45\x75\x7f\x4e\x03\x21\x94\xe3\x77\xba\x3a\x75\x7f\x8d\x88\x40\x3c\xef\x40\xac\xf6\xeb\x2d\x35\x25\xc4\xe0\x0a\xb2\x41\x85\x9b\x5c\xbc\x20\xaa\xee\x8c\x57\x8c\xa5\x24\x91\xc2\x78\x3a\x61\xc7\xb2\x6d\xd9\x14\xfc\xdd\x09\xd8\x72\x75\x59\x65\x7f\x0e\xd2\x99\x29\x95\x02\x8f\x1a\x4b\x52\xd2\x2b\x51\x8d\x17\x5f\x4a\x8d\x05\x8f\xbc\x95\x56\x38\x77\xd2\xcc\x4c\x68\xdf\xd8\xf2\x73\x20\x65\xc8\xfc\x3b\x71\x22\x84\x8d\xf0\xff\xb3\xee\xc2\x1f\xbe\x8d\x69\x14\xac\x79\x47\x3a\xcf\x29\x42\x34\xe5\xb1\x40\xa6\xa5\xd7\x32\x1f\x43\xe1\x52\xae\xc3\x40\xf8\x9d\xbd\x2f\x2c\x1a\x2c\xf2\x34\x16\x14\x61\x58\xcf\x35\x54\xd7\xa2\x11\x52\xd4\xd3\x41\x8c\x75\x90\xda\xa4\x4d\x05\xe2\xe0\x6a\x41\x84\x42\x5d\xcd\x61\xfa\x22\x8d\x4d\x8a\xc9\x71\x4f\x37\x2e\xf2\xab\xd6\xb4\x1f\x5d\x2c\x89\x08\xf2\x4c\x2c\xcb\xe2\xa5\x0b\x57\x9f\x73\xa0\xfa\xde\x60\x53\x51\xd6\x0c\xed\x6a\x1d\x5c\x6b\x1a\x8a\x80\x39\x6d\x84\x76\x62\x76\x1f\x55\x40\x12\xa9\x01\x46\x77\x3e\x9a\x9c\x6a\x11\x21\x48\xeb\xfe\xea\xfa\x2b\x04\xe2\x10\x02\x94\x6a\xc9\xd1\x4c\x38\x56\x60\x2b\x7c\xda\x49\xb1\xd0\xff\x7b\xaa\x7b\x48\x51\xaa\x8d\x46\xf9\x22\x33\x2d\xde\x66\x29\x04\x49\x4a\x5d\x26\xce\xca\x48\x5c\x98\x10\x40\x12\xe4\x13\x95\x9e\xa1\xec\x32\x89\x2e\x4b\x21\x66\xd4\x65\x51\x9c\xe5\x72\x16\x33\x4a\x41\x27\x88\x26\x18\x84\xb3\xae\x7b\x4c\x5c\x6a\x18\xd8\x83\x02\xed\x9f\x9f\xaf\x00\xf9\x15\x34\xc3\x02\xe7\xf9\x8d\x3b\x35\x69\x8a\x01\x43\x27\x1c\x00\x1f\xcd\x00\x81\xe1\xfb\x08\x83\x08\x8b\x6f\xd5\x24\xf0\x2f\x02\x10\xbc\x67\xc4\x45\xd6\xaa\x79\xf3\x5a\x84\x2a\x45\x17\xbd\x80\x0f\xe4\xde\xd9\x40\x75\x9f\xe5\x79\x7f\x17\x11\x1a\xab\x01\x83\x04\x86\xef\xe7\xb5\x9a\x4c\x44\x24\x48\x88\x8f\x8d\x3c\x7a\xc7\x5b\x44\x44\x60\x1d\xd9\xe1\x13\xf3\x9c\xeb\xba\x6b\xd0\x56\xd5\xff\xba\x6c\x37\x8f\x33\x66\x2a\x26\x48\xa0\xf0\xe5\xb3\x02\x33\x84\x27\x91\xdf\x8b\x8f\x4e\x44\x92\x09\x42\x22\x4c\xbc\x42\xa1\xd7\xcb\xc7\xf1\x17\x11\x34\xe1\x88\x36\xca\xea\xfa\x04\x4f\x50\x97\xf9\x1b\xe8\x59\x43\x40\x30\x4a\x12\xf0\x64\xf8\xc2\xd9\x2a\xb3\x13\x47\x70\x1a\x0b\xe1\x66\xd8\xce\xf1\x07\x6e\x5b\x5b\xfa\x8c\xbb\xf3\xef\x46\x57\xe7\xb7\x61\x11\xa7\xb1\xd7\x84\x9d\x8b\xac\x8b\xd8\x18\x90\x56\x33\xaa\xd9\x88\x22\x53\x7e\x50\x12\x10\x81\xa7\xe7\x74\xac\x24\xbb\xd7\xac\xee\xeb\x9b\x99\x48\x83\x4e\xb0\xda\x4a\x3a\xdb\xc8\xeb\x68\x4c\xd2\x10\x4c\xec\x0b\x0c\x45\xe6\x2d\x1f\xfb\xdd\xc7\x3d\x19\xb7\x7e\xff\x7b\x5f\xa9\x7a\x09\x39\x2f\xd2\x84\x31\x9b\xcf\xb4\x8e\x4f\x56\x16\x4f\x98\xda\xd4\xdd\xc3\x41\x84\xd0\x2d\x25\x8a\x67\x57\x78\x70\x38\x8a\xe2\x73\x83\x8a\x62\x50\xa8\xde\x4b\x1a\x8f\x88\x08\xa2\xc0\x97\xcc\xe0\x8b\xfb\x2b\x8a\xd0\x92\x07\x57\x80\x19\xf0\xe7\x42\x0d\xc9\x5a\x98\x10\xd2\xaa\xbb\xb8\xb0\xcc\x5a\x95\x03\x38\xab\x90\x21\x57\xb6\x3a\xfa\x5d\x54\xb3\xf0\x4b\x21\xa9\xe2\x5e\x64\xdf\x51\x00\x95\x85\xf3\x9e\x07\x55\x81\x4c\x48\x9e\xa2\x8e\x26\xaa\x98\x6c\x72\xa1\x60\x53\x36\x5d\x63\xc2\x51\x05\xcc\xd2\x52\x7a\x93\xd9\x35\xaa\x40\x62\xf2\xfa\x4a\xd4\xbf\xa0\xb1\xd4\xa6\x67\x88\xad\xc9\x58\x2b\x9a\x84\x7a\xb6\x58\xea\x4b\x1b\x5a\x28\x4e\x70\x3c\xf6\x36\xcd\xd1\x3d\x42\xbb\x3d\xdb\x40\xae\x65\x60\xf6\x0d\x3a\xb5\xd4\x91\x5d\x8a\x4f\xbd\xe2\x8c\x1a\xa8\x6d\xf9\xb0\xbf\xd0\x42\x63\x9e\xe0\x4a\x1f\xfb\x3a\x45\xa7\xbb\x67\xc1\x15\xae\x23\xa8\xc4\x87\xb0\x3b\xce\x8a\xd9\xbc\xba\x30\x24\x46\x4c\xe0\x9c\x89\x73\x31\xff\x20\x0c\x0d\x08\x1b\x4a\xff\xd4\x37\x65\x35\xf3\x53\xdf\x9d\x47\x08\x3c\x5b\x2d\xd6\x7b\xec\xfe\x3b\x6d\xc8\xf6\x27\x3c\x0a\x3d\x35\xab\x12\xc7\xae\x8a\xe9\xd4\xd3\x55\xb4\xbd\x34\xa0\x8a\x48\x56\xd5\x16\x77\xbd\xea\xce\x60\x61\x8c\xc2\x2c\x10\x4e\xd8\xdb\x29\x8b\x0a\x93\x41\x68\x30\xad\xb0\xab\x4e\x3d\xbb\xdf\x6f\xd2\xa8\xf3\x1f\x5d\x06\x26\x46\xa4\x03\xfa\xc6\x45\x5f\x05\x24\xc3\x88\x51\x57\x06\xbc\x5b\xed\x1f\x1e\x77\x96\x6b\xa1\xcb\x69\x4a\x42\x34\xda\x41\xf7\x99\xaa\xca\x6b\xf8\xe8\xfe\x2e\x01\xd3\xc3\x8f\x6f\x50\x2d\xf2\x7c\x03\xd5\x16\xbc\xcc\x26\x93\x34\x14\x6e\x23\x6d\xf6\x99\x2a\x8b\xec\x4f\x1b\x9c\xd9\x8b\xc3\xc5\x82\x68\x26\x29\x8b\xb1\xb4\xc6\x2d\xd5\xef\xbd\xd7\x24\x69\x1a\x60\x48\xa5\x6a\x6d\xee\xbb\x52\xfd\x1a\x99\x4f\x92\x1a\x82\x3e\xf2\xcf\x9b\xe5\x4c\x90\x65\x12\x6a\x97\x8c\x40\xd8\x25\x8c\xdb\xbf\xff\xd1\x35\x18\xbc\x8c\xf5\xf8\xca\xa2\x6e\xa0\x5a\x34\x8d\x70\xce\x51\x87\x6d\x1a\x58\x35\x92\x71\x85\xf0\xdf\x57\x2f\x78\x82\xe6\xea\x55\xa6\xbb\x8b\xc6\x02\x93\xf7\x5d\x85\x26\xc0\x35\x14\x9e\x4a\x84\x49\x26\x4c\x88\x26\x79\x5e\xd6\x60\x11\xed\xdf\x3a\xc5\x85\x6e\x32\x30\x69\x30\x8e\xd5\x7a\x78\x99\xee\x6b\x57\xc7\x6f\xc6\xc3\x08\xeb\xe1\x00\xa7\xe4\xad\x95\x8a\xa9\x9b\xac\x18\x9a\x14\x32\x61\x02\xf7\x74\x0c\x04\x0d\x4d\x0a\x99\x52\x8a\xe7\xce\xd3\xe3\xdd\x6a\x7f\xbf\x78\x58\x7c\xeb\x60\xcc\x32\xe5\x14\x0d\x25\x4f\xca\x31\x28\xf6\x90\x42\x5a\x50\xa6\x93\x87\xc1\xd2\x87\x5d\x79\x65\xdf\x60\x68\x34\x4b\xa1\x81\x77\x94\xa3\x16\xb0\x3b\x7e\x05\x01\x1c\x37\x22\xf8\xf3\x24\xf2\x3f\x46\x96\xed\x68\x05\x4a\x19\x44\x88\x72\x5d\x2f\x1f\xdd\x95\x26\x65\x37\x52\x32\x81\x84\x34\xb6\xb8\xbb\x19\x94\x2f\x8e\x0f\x17\x29\x95\x0d\xd8\x65\xf5\xa2\x92\xd9\xb4\xd2\x98\x49\x4d\x13\xe4\xd9\x44\x10\xd0\x5d\xd9\x5c\x8a\x41\x49\x4d\x53\xac\x1c\xe8\xbe\x35\xd2\x19\x5e\x98\xee\x3a\xb1\xd4\xf9\xfb\xac\xde\x55\x27\x98\x5e\x0a\x14\x96\x27\x6c\xa1\xf9\x26\x6a\x5b\x1f\x36\xfe\x3d\x90\x30\x25\xfe\xa9\x90\x6b\xb5\x9b\x73\x20\x62\xa4\x57\x6a\xdd\x58\x0f\xce\xdc\x58\x47\x6a\x90\x1c\xad\xbb\xee\x40\x71\x9b\x42\x66\x6d\xbb\xd1\x97\x03\x77\x55\x1a\xae\xf9\xf8\x4e\xd5\xc8\x11\x97\x26\xa6\x21\xf1\x73\xf8\xeb\x83\x4b\x9a\x18\x88\x1e\xd4\x30\x5e\xaf\x1f\x2e\x78\x76\x2a\x64\x96\xfa\x21\xab\x37\xb9\x68\x4c\x59\x1d\xe6\xa4\x75\x99\x8a\xc2\xd8\xd6\xee\x8a\x1a\xa1\x81\xd3\xa3\x59\x45\x84\x98\xe1\x77\x59\xd8\x4d\xe4\xef\x85\xe0\x55\xc4\xb8\xf2\x66\xe1\xa6\x82\xa3\xc8\x9c\xb2\xc8\x3b\x0c\x80\xfc\xb3\xc1\x5d\x77\x05\x62\x22\x9f\xd0\x77\x54\xd3\xd5\x34\x1a\x3c\xa9\x4e\x52\xd4\x49\x1d\xbb\xfa\xe0\xeb\x9e\x6b\xc6\x1a\x4e\x7a\x5a\xfb\x39\xda\x2f\x14\x8d\xb9\x49\xfb\x29\xab\x7e\xc1\x48\x7b\x96\x29\xaa\xc0\x62\xba\x11\x64\xba\x2c\x5d\xca\xa4\xac\x6c\x99\x9d\x3f\x51\xcf\x35\x75\x98\x62\x31\xc1\xd9\xd5\x1e\x24\x53\x50\x9f\x6a\xf7\x16\x62\x21\x82\x5e\x3f\xe2\x54\x74\xf4\x7b\x4c\xf1\x80\xa0\x05\xfb\x9f\xd3\x19\x94\x49\x71\x25\x82\x64\x64\x7f\x8f\xa7\xbc\xe2\xca\x9e\x46\xdf\xf2\x52\xc2\xc7\x56\x65\x1d\x0f\x69\xdb\x66\x65\x27\x6c\x68\xc3\x06\x99\xcb\xea\x8c\xf5\x8e\xa9\x98\xd9\xd5\xfc\x02\xcd\xf7\x4f\xe5\xbe\xc7\x64\x27\x55\x09\xd7\x36\x15\x8c\x89\xaa\x33\xca\xef\xf9\xf9\x9a\xc4\x3a\x0a\xbc\xce\xe7\x21\x2b\x5c\x4c\x6a\x70\x5c\xa8\x24\x35\x38\x3c\x98\x09\xba\xb7\x51\x95\xcf\xb5\x1e\x0f\xba\x1f\xe8\x44\xc7\x88\xb2\x42\x41\xab\xfb\x21\x41\xf9\xfc\xfd\xd3\xc0\xa2\xee\x3a\x48\xbd\x4a\x43\xc3\x84\x83\xf3\xfc\x16\xe8\x30\x3f\xfb\xd3\x38\x12\xce\x41\x6e\x6d\x35\xcc\x29\x7d\x69\x6d\xa8\x34\x11\x18\x1b\xfe\x56\x01\x34\x50\x5d\x0d\x0f\x00\x95\x6a\x86\x4b\xd1\x42\x35\x36\xa2\x9a\xf8\x3e\x4a\x70\xa5\x7b\xa0\xd5\x76\x71\xb7\xda\x2f\xee\xee\x1e\x97\x88\xc8\xf7\xef\x25\x94\x12\x08\x57\x11\x96\x62\x23\xf7\x90\x09\xd7\x2e\x03\x8d\x06\xc8\x9f\x27\xa8\x3e\x7f\x8a\x0c\xb1\xe5\xd9\x01\xae\x4e\x03\x84\xb7\x92\x44\x1b\x33\x96\x3b\xae\xca\xc3\xb5\x68\xc4\xe8\x91\x65\x1a\xa2\xa9\x6d\x91\xac\xb3\xcc\xc1\x4c\x49\x63\x3d\x09\x65\x57\x52\x53\x4e\x3b\x28\x1a\xa0\xa1\x70\xb5\x75\x9a\x4e\xfe\x29\x14\x30\xc4\x66\x1e\x6d\x5e\xb0\xdd\x78\x7b\x37\x58\x41\xa0\xb1\xc0\xd0\xb9\x52\x1d\x65\xd1\x64\xcc\x0d\x8f\x89\x0b\xd7\x5a\xbf\x70\x9e\x18\x98\xe9\x20\x50\x18\x45\x7a\x80\xf7\x8d\xc0\x6a\xa2\xd1\xc6\xa1\x03\x66\x10\x19\xd2\x47\x37\x7f\x40\xdd\x80\x1e\xe9\x78\x30\x1d\xa4\x09\xeb\x73\x3e\xd7\xa7\x02\xf1\x8a\x7f\x73\x66\x4d\x1f\x29\x35\xc6\xc6\x6b\x0a\x55\x56\xab\xdd\xed\x70\x53\xd0\x61\x6c\xbc\x82\xd8\xbe\x81\xea\xb0\xf7\xe9\x3e\x28\x34\x16\x87\x76\x1d\xb5\x25\x49\xb0\x44\xe1\xed\xa7\xaa\x6c\x29\xe2\xf8\x05\x23\x1a\x62\x41\xb2\x23\xb3\xc5\xc5\x19\x8c\x16\x94\x8b\xe9\x8f\xff\xe9\x86\x5a\x13\x6e\xd1\x50\x7f\x9e\xca\xea\x74\x18\xf1\x40\x32\x4d\x54\x9c\x0a\x0f\x31\xb5\xec\x50\x83\xd8\xb1\x66\x81\x41\x52\x39\x17\x9a\x5a\xd4\x9e\xa3\xce\xcf\x49\xcd\xc0\x6a\xf6\x6a\x38\xe6\xe5\xa7\x97\x94\x9d\xe3\x6c\x63\x9a\x07\x96\x50\x53\x60\x0d\xf3\xa6\xcc\x33\xe5\x8f\xe4\xb6\x4d\x75\x26\xff\x4e\xfc\x82\x85\x69\xa0\x1a\x67\x71\x34\x8f\x05\x6e\x58\xce\xe2\xee\xcb\x16\x7c\xbb\x11\x68\x91\xbf\xbf\x66\xea\xf5\x5c\x0e\x8d\xe9\x38\x12\x51\xe2\xf9\xe6\x7f\x39\xe6\xa4\x7a\x86\x69\x97\xe9\x98\x44\x7c\x7c\x06\x7f\x7e\xc5\x9e\xa2\xe3\x84\x47\x2e\xfb\xe7\x09\xb0\x86\x7b\x8f\xeb\x95\x44\xd6\x75\x16\xfa\x42\x34\x50\xa7\x84\x61\x90\xbc\x80\xf7\xef\x95\xf0\x29\xfb\x5d\xa6\x7e\x4d\x62\x1d\x3a\x8d\x2d\xad\x8f\x2b\x77\xcb\x0a\x51\xcd\xdb\x79\x3a\xd5\xc4\x92\x1a\xa2\x4e\x1e\xe0\x3c\x14\xfb\x93\x57\x08\x66\x5a\x84\xdc\x66\xb7\x56\xcb\xf1\x6c\x16\x51\x18\x78\x8a\x31\x94\x67\xb9\x3e\x03\x5e\x69\x21\x15\x1b\x72\xba\xf4\xc2\xe9\x9b\x8f\x33\xed\x1f\x2b\xdc\x31\x7a\x0f\x49\xe2\xc0\xe5\xe6\xb6\xa2\xc8\x9a\x4f\x2b\x20\x3d\x53\x1d\xe2\x7f\x90\x48\x35\x90\x36\xb4\x12\x25\xe3\x67\x92\x69\x12\x05\xde\x93\xb5\xb4\x71\xfe\x95\x74\xcc\x59\x80\x65\x6d\x16\x47\xbf\x2b\x4f\xe8\x63\x16\xcd\x15\x14\x80\x48\xda\xea\xf3\x2c\xa8\xaa\xb5\x71\x50\x2c\x14\xaa\x3f\x35\xa2\xb7\x6d\x10\x3e\xd2\x4c\x78\x79\x99\x36\xa1\xf6\x3b\x81\xaf\xe2\x90\x39\x22\xc4\x2f\x94\x26\xfe\x63\xfa\x7b\x13\x5a\xf5\x78\x5b\xd1\x59\x96\x67\x98\xa6\xe9\x0e\xd5\x0d\x91\xe1\x1c\xc5\x3e\x0b\x78\x1f\x50\xf8\xcf\x85\x06\x20\x8c\x43\xd4\x57\x6d\xef\xb1\xaf\x7b\x6e\x4a\x06\x51\x6c\x2d\x7e\x38\x1c\xa1\xea\xb0\x37\x40\x48\xea\xb9\x9e\x9d\x0e\xe8\x37\x28\x5a\xe7\xe9\xec\xe9\x6c\x3d\x61\xf7\x33\x91\xf6\x84\xe8\x9b\x72\xc4\xf8\xc4\x80\x30\x8a\xea\x70\x79\x59\xf6\xf8\x5e\x20\xb1\x0d\xd1\xec\x75\xb9\xab\x84\x86\xf9\xb8\xc8\xbc\x7d\x01\x34\x36\x29\xf7\x45\xde\xea\x17\x5c\x74\x84\x80\xa6\x44\x08\x4f\xdd\xea\x36\x95\x5d\x06\xd5\x50\xda\x6d\x6c\xb1\x02\x73\x3a\x7a\x1d\xb7\x09\x36\xc7\xae\x35\x26\x1c\x8b\x9e\x1a\xa1\xca\xf6\xc3\x0d\x0b\xa6\x20\x96\x09\x38\xde\xb5\xad\x2a\xdb\x31\xe8\x0a\xf5\xc7\x53\x08\x62\x05\xa9\x65\xe3\x2c\x36\x50\xb5\xcb\xf7\xcc\xa4\xb2\x8c\x0f\xbe\x3f\x98\xd8\xbf\x47\x6b\xc7\x2e\xb3\x26\xeb\x6a\x20\x20\x89\x6c\xfe\xd1\x11\x79\xdd\x64\x79\x3e\xbd\xdc\x7f\x59\xbf\xdc\x92\x71\xdc\x74\x5e\xf8\x90\x41\x02\x09\xe2\x37\x1f\x16\xdb\xa7\xe1\xde\x01\x69\x9a\xe0\x39\x79\x73\x52\xbf\x06\xee\x19\x88\x90\x69\x32\x96\x3d\xe9\x57\x7b\xc8\xff\xc7\x77\x8b\x98\x09\x06\x28\xde\x05\xd6\xbe\xb5\xeb\xe6\x49\x5c\xaa\xb5\x05\xa1\x40\xf5\x29\x0a\x0f\xcd\x01\x19\x11\x74\xf8\x9e\xab\xfc\x36\xeb\xac\x02\x90\x34\xc2\x4c\xf4\xea\x03\xd4\x5d\xf9\xf2\xfb\x32\xc6\x39\x2e\x13\x90\x49\xe2\x8a\x84\x71\x55\xe3\x7a\x1b\x4f\x2f\x15\x01\xce\x06\x65\xa3\xc7\x0f\x7d\x44\x0b\x54\xc2\x11\x34\x82\x51\x35\x3c\xf3\x28\xd3\xe2\xb3\xfb\x66\x0a\x02\x74\x21\x54\xf5\x79\x6c\xca\xe5\xab\xc8\x73\x28\x5e\xba\x9f\x6b\x95\x5a\xb9\xb8\x93\x7c\x2f\x4b\x03\xd5\xb3\xd7\x60\x74\x1d\x80\x10\xea\x4e\xbc\xbb\xec\x6d\x98\x18\x06\x10\x56\xc3\xa0\x3c\x42\xe1\x28\xd3\xbf\xaa\x89\x07\xd0\x29\x46\x86\x10\x73\x55\xa3\x1d\xdb\xc7\xb4\xc0\xa4\x89\xe7\x0d\xbf\x06\xd1\xbc\xce\x00\xfc\xc1\x48\x1d\x39\x1a\xda\xfb\x52\x9f\xf2\x89\x82\xd1\xfc\x3e\x68\x02\x6e\x93\xc9\x22\xab\xae\xab\xf2\x38\xf2\x0b\x4d\x60\x42\x4b\x11\xd6\x6e\xf4\x57\xa7\xcf\x21\x6e\xdb\x44\x44\x62\xad\xe9\x41\xfc\x82\x9d\xe7\x28\x1f\xbc\x92\x89\x38\x4f\x6d\x9d\x9d\xdb\x17\x1e\xca\x66\x75\x38\xf6\xf5\xc7\xbe\x9f\xe4\x38\xcc\x05\x7c\x0c\x94\xf2\x98\x89\x34\x60\xb4\x19\x9a\xd7\x27\x07\x93\xf6\x4d\x04\x18\xd2\x7b\x38\x33\xd9\xa3\xaf\x0d\x0d\x23\x32\xa8\xaa\x5e\xbc\x89\x46\xcc\x12\x23\xf5\x03\xc0\xa4\xf0\xac\xe6\x7e\xc1\xfc\x7f\xce\xfe\xa4\xbb\x71\x1c\x4b\x1f\x87\xbf\xcb\x6f\x95\x8b\x5e\x70\x00\x01\xf0\xdd\x49\xb2\xec\x50\xa5\x6d\xa9\x25\x39\xa2\xb2\xfa\xd4\xd1\xc1\x70\x61\xb3\x4d\x91\x2a\x92\xb2\x43\xf9\xe9\xdf\xc3\x0b\x80\x93\xe4\xc8\xec\xff\xa6\xa2\xd2\x80\x38\x80\x18\xee\xf0\xdc\xe7\x19\x4c\x21\x93\x48\x89\xb6\xf4\x9b\xa8\xdf\xe6\xd9\x35\xb3\xd8\x74\x56\x7f\x51\x86\xef\xaf\xa6\x68\xe4\x88\x3c\xef\x96\x95\x8a\x82\xdb\xc6\x9c\x49\x4c\x68\x0b\xf9\x1c\xe3\xdd\xcf\xec\x78\x3e\x0e\x71\xcf\xf7\x65\x65\xd1\x12\xb6\xf2\x71\x7c\x17\x0a\x02\x0b\xc3\x97\xcd\xdb\xba\xe8\xde\x84\xc7\x62\x64\x73\x3d\x89\xe2\xf2\x28\x5a\xe7\xda\xea\x89\xfd\xd6\x45\xd0\xa7\xa1\x74\x77\x01\x19\x32\x0c\xec\x95\xad\xdb\xb4\xc9\x00\xa9\x19\xda\xe1\xbf\xda\xf8\xaf\x7e\x28\xb1\xd4\x4a\x9e\x2f\x57\xd5\x98\x46\x3a\xce\x34\x5c\xa3\x4f\xa5\x6c\xb7\xfb\xfb\x5e\x16\x34\x31\x32\x0d\x31\xf0\xa3\xcb\x42\x34\xed\x21\x0a\xfe\x00\x33\x2a\x0a\xb0\x6e\x51\x89\xe2\xe5\x6a\x14\x54\x1c\x29\x57\x85\x3d\x43\xc5\x80\xe1\xa7\xe1\x5d\x27\x4d\x6c\xd1\xb3\xaf\x86\xfe\xa5\x57\x6d\x54\x32\x8a\xfe\xd5\x4d\xf7\x98\x3a\x0c\x31\xb5\xa8\xca\xb2\xd2\x19\xca\x7b\xec\xa0\x99\xbd\x56\x80\xe7\xaa\x2f\x50\x1b\x5f\x4e\x87\x69\x6c\x01\x9d\xe7\xa2\xf9\xd7\xfe\xf7\xc5\x1b\xf4\xa0\x0a\xa3\x23\x5b\xac\x09\xcd\xdb\xbe\x9c\x43\x6f\xfa\xe9\x5d\x67\x71\x19\x9d\xc6\xc4\x72\x3d\x7a\xc1\xf2\xc4\x68\x91\x68\x4f\x7a\x74\x88\x93\x83\xc5\x63\x3e\x88\xfa\xa5\x16\xaf\x10\x92\x20\xb0\x04\xfe\x7d\x7f\x8e\xfe\x41\xdb\xdf\x4e\x2b\xdf\x62\x62\xad\x5c\xb5\x07\x26\x10\xb3\x3f\xe1\x07\x32\x8f\xb7\x0e\xf4\xda\x18\xaf\x85\xe7\xc7\xd3\x24\x0a\x61\xdc\xe2\xb5\xf7\x0f\x8d\xe1\xb6\x6a\xae\x82\xf6\xf3\xcf\x2a\xab\x6a\x78\xbe\x0e\xe4\xd2\x20\x0a\x6c\x25\xaa\x5d\xbf\xc3\xb2\xf9\x21\xec\xc9\xd5\x06\xd1\x20\x22\x14\x1d\xd4\x76\xc2\x7c\x2d\x89\xd9\x57\xc8\xd3\x20\x52\xb1\x65\x3d\x6f\x57\x9f\x8d\x03\xfb\x16\x88\xd1\xc7\x70\xd4\x48\xb3\x01\xfe\x8b\x06\x71\x20\x30\x18\x7e\xcc\xae\x33\x16\x43\xac\x05\x0d\x62\x1e\x5a\xd5\xad\xa6\x12\x91\x92\xa5\x37\x0f\x9d\xf5\x48\x83\xd8\x08\x57\x45\xfa\xfa\x9a\x03\xa6\x14\xde\x40\x2f\x0b\x53\xda\x18\xd9\x6f\x83\xa7\x25\x31\x55\xba\x63\xf7\xe9\x31\xba\x34\x20\x24\xe5\x62\xe8\x3b\xb8\x20\xec\xaf\xac\x5e\x1a\x10\x1a\x05\x62\x64\xb4\xcd\x9a\xd9\xb5\xcd\x46\x03\x02\x54\x0c\xe9\x63\xfe\xf9\xfc\xfb\xa4\x47\x42\x02\x44\x3e\xad\xee\x1f\xf7\xbb\x4c\x03\x42\xb9\xfd\xd3\xb5\x27\x96\xa5\x5c\x28\x5e\xe7\xe5\xf9\xf5\xad\xd7\xf0\x8d\x7a\x1b\x28\xf9\xf7\xd8\xf6\x19\x04\x18\xdd\x75\xa8\xa4\x23\x01\x56\x97\xbf\xab\xca\xe3\xee\x04\x2a\x13\xf9\x17\x5a\x9d\x93\xcb\x30\x42\x30\xa6\xff\x01\x55\x66\x2e\x13\x04\xcf\x0d\xce\x94\xaf\x2d\x32\x1a\x30\xe0\x38\xf0\x36\x89\xd5\x41\x62\x5c\x6b\x9a\x30\x2c\x37\xfb\x56\x7e\xb6\xef\xbe\xaa\xef\xb2\xba\xf5\x83\x76\x4d\x96\xe7\x5e\x88\x6f\xfc\x70\xa9\xb0\x13\x06\x05\x5b\x9e\xb2\xc2\x71\x9b\x8d\x9d\x0e\x1a\xa4\xd2\x2a\x2f\x15\xf0\x79\x27\xca\xed\x39\x87\xda\x73\xaa\xfe\xed\x50\xcb\x50\xd7\x71\x32\x44\xa9\x34\xc4\xeb\x54\x21\x9e\xa6\x6e\x67\x9b\x0d\x16\xff\x36\x30\x83\x69\x20\xa8\x05\x90\x1c\xb1\xb4\x09\xd7\xe8\xc0\xc2\x0c\xfc\xf3\xca\xc0\x26\xf0\x96\xa8\xc3\xb5\x98\xd4\xc8\xff\x32\x47\x49\x03\x99\x12\x8c\x91\x7f\x58\xe4\x31\x06\x48\x5f\x8a\xec\xe7\x24\x98\x4f\x03\x29\x62\x4f\x10\xb5\x3e\x41\x71\xa5\xfd\x42\x03\x29\x99\x55\x76\xb4\x26\x04\x62\xc7\x5c\x93\x12\xd4\xc2\xe0\x1d\xed\x66\xff\x67\xcc\x3a\xe9\xac\xee\x65\x33\x69\xa0\xb4\x32\x9d\x12\x86\xcd\xcd\x75\x57\xd2\x42\x20\x0f\x9c\x3e\x37\xea\xad\x93\xe1\x58\x54\xc2\x74\x57\x85\xc8\x1a\xec\x98\x4f\x6c\x07\x6d\x56\xe8\x55\x91\x35\x2b\xf3\x0c\x0a\xea\x5a\x5c\x67\xf9\xfd\x2f\xb5\xc4\x92\xef\x93\xa3\xf7\x9f\x92\x08\xd3\xc0\x84\x0a\x19\x0d\xce\x35\x7c\xc1\x06\xe9\x3b\x92\x14\x79\x7b\x37\x62\x58\x2f\x41\xc3\x20\x89\xd0\x79\x59\xa0\x21\xbc\x13\xaf\x62\xd6\x6e\xd6\xdf\xa1\x0a\xff\xcf\x28\x97\x71\x9c\x6c\xfa\x9f\xfd\xe6\x16\x06\x90\x58\x3a\x58\xf4\x3d\x2c\x49\xf6\x20\xd6\x4a\xc3\x48\xd0\x4e\x03\x42\xf4\x14\x13\xab\xda\xb2\x6b\xd4\x13\xb2\x61\x1a\xc6\x86\x09\x5f\xac\xfe\x52\xb7\x13\xa7\x5b\xea\x7f\x63\x69\x87\x24\x4a\xd1\xd7\x10\x79\x73\x55\x79\xe5\xbb\x18\x8d\xd6\xa2\xaf\x70\x88\x88\x7d\xe2\xc8\x61\x7e\x23\xb7\x4a\xc2\x24\xd0\x98\x57\x3e\x89\x4b\x57\x3f\xea\x9b\x42\x63\xe8\x74\x53\xf3\xac\x76\x34\x4c\x62\x65\x0f\xe3\x76\x9e\x8d\x88\x8c\x68\x98\x40\xec\x2a\x73\x72\xcc\x03\xe5\xd9\x07\x54\x93\xf0\x73\xdb\x4b\xe3\xd7\xac\xcf\xd2\xad\xe5\x9b\x58\x30\x1a\x52\xc9\x1c\x5e\xe6\x54\x56\xa3\x90\x01\x0d\xa9\x82\xd8\x49\xcb\x78\x05\x3f\x1a\x52\x13\xa5\x66\xf0\xe8\xcb\xe6\xed\x1e\x60\x56\x68\x4b\x3a\xf0\x57\x11\x14\x77\x15\x46\x64\x3a\x24\x10\x5d\xbc\x21\x5e\xe2\xef\xed\x0d\x21\xa3\x36\x96\xf1\x0a\x0d\x52\xf3\xe6\x93\x3a\x0f\x1a\x32\x61\xe1\xe4\xf3\x72\x67\xd9\x52\x0e\x7b\xa8\xaf\x92\x73\xe7\x29\xa5\x05\x0d\x39\x0b\x02\x6b\x7d\x38\x88\xc5\x44\x3c\x95\x86\x5c\xc5\x38\x00\x28\x6f\x24\x72\x2c\x81\x79\x45\xcf\xe4\x97\x27\x50\x98\xc6\x01\x11\x7e\x7b\xcd\x73\x2c\x0f\xb0\x34\x49\x96\x52\xcd\x5f\x5f\xc4\x60\x03\x1f\xe5\xc0\xa2\x99\xbc\x9e\x60\x06\xab\x0a\x4d\xf6\xd3\x2e\x0b\x4f\x8c\xe7\xdb\x55\x6c\x89\xf5\xdb\x9d\xc6\x32\x09\xa2\xf3\x34\xf4\xed\x68\x28\xb4\x41\x2e\xbc\x97\xa2\x9d\xe6\x46\x14\xf5\x35\xef\x3b\x6d\x0d\x77\x4c\x51\x3d\x25\x8f\xe5\xab\x37\x0b\x69\x28\x53\x01\x7a\xc2\x34\xfd\xe5\xe7\x1b\xb2\x17\xba\xdf\xab\x88\x52\xf7\x0d\x97\x3f\x4f\x59\xb7\xc9\x86\x8a\x2a\x62\x89\xc5\xad\x23\x20\xaa\x63\xd7\x24\x98\xe5\x00\x1d\xa8\x37\x6f\xce\xd5\xa9\xbc\xd6\x76\xfa\xaf\xe1\x2e\xa2\x04\x67\xa2\xcf\x59\x0d\xca\x04\xa2\xe0\x8b\x29\xa6\x34\xc3\x4a\x56\x25\xda\x5d\xd6\x06\x48\x70\x09\xcf\x9a\x6b\xcf\x9b\x86\x3a\x15\x58\xdb\xb8\xac\xaa\x8e\x52\x8f\x86\xad\x47\xdf\x1a\x1d\xbf\x67\x79\x3e\xf9\x81\x09\x42\x8c\xd6\x3d\x64\xcd\x3c\x6b\x46\x3b\xb1\x89\x13\xfc\x2c\xf7\xeb\x87\xee\x4f\x09\x41\x56\xc1\x1d\x14\xda\x46\xf0\xcb\xfb\xf3\x04\xee\x41\x43\x63\x62\x34\xb2\x67\x0a\x9d\x89\xfb\x2c\xcf\x01\x67\xd0\xb5\x52\xc4\xd4\x66\x8d\x82\xc4\x4a\x46\xb4\xe7\x9d\x45\xd4\xed\xa0\x9b\x4f\x51\x24\x2c\x6b\x8a\x4b\xef\xcc\x4e\x63\xde\x59\xbf\x7d\x46\x91\x52\xdc\x0a\x6b\xa8\x5c\x54\xe8\x27\x64\xc5\xeb\xfa\xdc\xa8\xf2\x38\x8c\x0c\xd0\x28\x8e\x12\x4c\x7f\xed\x40\x9d\xab\xac\xb9\x1c\x1e\xa0\xb1\x89\xb4\xb5\x99\x35\x0d\x1c\x4f\x4d\xbd\x2f\x17\x65\x51\x80\x6a\xe6\xa2\x78\x77\x2f\xb5\x2f\x67\x1e\x91\x3a\xaa\xcf\xa0\x51\x1c\x07\x08\x9c\xb9\x2b\x8f\x50\x0c\xb5\x7b\x68\x14\x6b\x26\x1c\x74\xaa\x6e\x72\xa8\xeb\x21\xea\xe1\xf0\x58\x4e\xec\xb1\x28\x01\x88\x3a\x06\x42\x4b\x36\xbf\x28\x4f\x17\x8c\xc7\xe8\xf2\x73\xb2\x42\xa2\xc4\x10\x3c\x11\xb0\x46\xb8\xfc\x2c\x06\xe7\xb3\xbe\x0e\xb3\x8f\x77\xc2\x88\x86\x22\x70\xb0\x0f\xd4\x2b\xf3\x2b\x1e\x21\x1e\x5f\x56\x73\xba\x1f\x33\xa7\x25\x9b\x21\x6f\xf2\x34\xd6\xf8\x6f\xdf\xcb\x80\xd3\x7c\x69\xce\x55\xb1\x2b\x8f\xd0\xbc\xf5\x1b\x5a\xc4\x43\x91\x4a\xef\x11\x40\xd5\x53\x37\x8c\xef\xc5\x09\x43\xde\xc9\x3d\x54\x55\x56\x62\xc5\x56\x77\x05\x4e\xa2\xc8\x2b\x35\xa0\x93\x7b\xa8\x2f\x75\x03\xc7\xae\x03\x70\xe8\x06\xb4\x63\xb9\xf2\xad\x22\x8d\x8c\xf7\x55\xb7\xf0\x01\x55\xb3\xff\xe9\xdb\xa4\x8a\x90\xd5\x66\xb5\xd8\xcf\xfc\xdf\x94\xb2\x51\xa1\x83\xca\x41\x20\x4b\x6a\xa5\xbf\x65\x50\x89\x4a\xbd\x5d\xa6\x8c\xeb\xff\xf3\xef\xf1\x11\x1f\x29\x50\x11\xf3\x55\x43\x5d\x91\xf4\xe4\x65\x35\x04\x28\xbc\xf4\x09\xd9\x06\xaa\x97\xdd\x9d\xbf\x37\x04\x31\x16\x3f\x7a\xae\xde\xc5\xe3\x7a\xe7\x45\x86\x68\x04\x1a\xb4\x2d\x2f\xbc\xb4\xd7\xbe\x7d\xe6\x46\x00\x21\xd6\x52\xc8\x73\x55\x8c\xb6\xcd\xd1\x5a\x02\x50\x81\x25\x31\x68\x2d\xd3\x47\x51\xfb\xc3\x1e\xa3\x6c\xe3\x77\x32\x84\x89\xf6\x13\xbe\xdc\xdd\x1f\x36\xeb\x6d\x9f\x1a\xa7\x91\x49\xb5\xec\xa8\x59\xb6\xed\xc0\x8f\x51\x14\x34\x0e\x12\xcb\xe1\x7a\xff\x4f\xcc\xb1\xdf\x8c\xe0\xd0\x38\x10\x84\x3a\x33\x7b\xd6\x94\xc7\x55\xbd\x1d\xb2\xba\x9d\xad\xd4\x95\xef\x0b\x81\xe9\x35\x15\x7f\x41\x87\x73\x2d\xf0\x39\xb9\x6b\x18\xf0\x70\xb8\xe3\xdf\x95\xea\x0a\xd8\x3a\x5a\x4f\x71\x18\x13\xaf\xbd\x9f\x8b\xea\xd5\x52\x41\xef\x9a\xf2\x74\xed\x18\xc4\x11\x35\x32\xee\x13\x5d\x1d\x93\x00\x8d\x63\x61\xd5\x6b\x30\x1b\xe5\xcc\xe9\x1b\xc1\x8a\x98\x04\x12\xe9\x0a\x9c\x46\x6f\x55\x5a\x7a\xee\xdf\x7e\x61\x09\xf7\xb7\x27\xd2\x69\x9f\x80\x3a\xb4\x3f\xf0\x37\x4f\x82\x24\xb2\xb5\xd9\x79\x59\x0d\x02\xae\x34\x4e\x74\x48\x5d\xcc\x7e\xb3\x5e\x3f\x5a\xe6\xff\x28\x18\x99\x6d\x71\x62\x12\xcc\x29\x1e\xb3\xc2\x9d\xf8\x3d\xbb\xaf\xeb\x42\x03\x1d\xb3\x5e\x21\xf6\x2e\x3b\xe5\xe5\x51\x4c\x46\x87\x52\x89\x86\x0e\x6e\xb6\xd6\x72\x98\xe5\x79\xa9\x10\x6d\x34\xe9\xca\xcd\x48\x25\xee\x8b\xef\x3c\x7a\x4c\x9a\xc6\x21\x96\xe0\x67\x05\x88\xd3\x29\x87\x4d\x99\x15\x3e\x98\x46\x63\x16\x47\x98\x5c\xc2\x2a\xe3\x1d\x34\xbd\x30\xfa\x5f\x61\x54\x68\xcc\xa4\x05\x80\x29\x9b\x16\x04\xdd\xd5\x63\xd3\x98\xe9\x34\x71\x59\xc3\x59\x5d\x3b\x86\x89\xf1\xcf\x39\x09\xf1\xa3\x1a\x40\xc7\x61\xf4\x05\x38\x51\xd2\x63\x92\xb6\x60\xa0\x12\x79\xde\x6e\x85\xbf\x62\x43\xa5\x31\x4f\x02\x2c\xa7\x7e\x10\x85\x70\x75\x34\xbe\xce\xed\x2f\x2b\x90\xc7\x57\x4a\x63\x9a\xf8\x38\xdd\x0e\x9a\x87\xce\x6e\x8c\x05\xb1\x34\x37\xf6\x4b\xf9\xa8\xc4\x38\x5c\x1d\xfe\x75\x80\x60\x7c\x3b\x91\xe8\x28\xea\xb0\x2e\x8e\x4d\x03\x81\xa2\x9b\x0a\x54\x56\xdf\xae\xfc\xa7\xb1\x0c\x0d\x6e\x93\x0f\x65\xae\xa1\x78\xcc\x5e\xdf\x1a\x4c\x51\xfd\xa5\x01\x1e\xab\xc8\xb2\x08\xe1\xa8\x2f\x9c\x4a\xde\x04\x3d\x43\x63\x95\xc4\xe8\x9a\xf4\xfc\x12\xed\xdf\x92\x38\x1a\x16\xf3\xef\x1a\x71\x45\x3c\xe5\xfb\x4a\x2e\xbc\x44\x72\x56\xf9\x1a\xe4\x3e\x41\xe3\xcf\xce\x58\x8b\x08\xb7\x13\xac\x8b\xe8\xdc\xed\x58\x9b\x08\xfd\x0b\x6b\x10\xed\x2c\x09\x9f\x1e\x87\x8f\xc7\x77\x04\xc3\x88\x2f\x57\x72\x55\x8c\xed\x7e\x33\x30\x53\x63\x13\x00\x96\x16\xb4\xa7\xf4\xda\x98\x85\x2f\x8a\xf0\xfa\xc6\xab\x22\x6b\x44\xfe\x94\x15\x73\x68\x7a\x4d\x37\x4a\x02\xc9\x71\x25\x61\xac\xb7\x2c\x60\x55\x20\xf9\xd7\xf2\x3f\x0e\x71\xfb\x04\x75\x2d\x5e\xfb\xee\x3a\x09\xae\x22\x6a\x5f\x65\x35\xdc\x6f\xc2\x18\xbc\x70\xe0\xbd\x38\x2b\x5f\xa7\x32\x60\xd1\xa7\x24\xe4\xb6\xfa\x59\x9e\x31\xa9\xe0\x52\xc9\xbe\x51\x5b\xa2\x2a\x47\x4a\x9a\x5b\xb6\x85\x81\x4e\xdc\x68\x16\x90\x28\x00\x64\xc6\x68\xbc\xbf\x81\xaa\xf9\xaa\xcf\x8e\x3d\x8a\xcf\x0b\x54\xf5\xaa\x68\x8d\xc5\x42\xe3\xda\x1b\x5d\x21\xa6\xc2\x1e\xd4\xc8\x0f\xb2\x5a\xac\x0f\x9b\xe5\x76\xb5\xbe\x3b\xec\x7f\xac\xbb\x6b\x2a\x83\xd8\xd3\xe7\xe5\xed\x31\xb8\x39\x77\x08\x09\x22\x2f\xb3\xff\x3d\x53\x70\xaa\xa0\xce\x34\x14\x0d\xdc\xc1\x13\xd4\x62\x7c\x34\x13\x42\x24\x66\xd7\xb2\xfa\x0e\x21\x3c\xbd\xe1\x45\x08\xa5\x16\x4e\x93\x35\x6f\x77\x95\xf8\xdc\x63\x2a\xdb\x56\xdd\x4c\x6e\xc9\xe3\x34\xec\x12\x19\xa3\x72\x04\xdf\x43\xa5\x98\xf0\xd9\x89\xea\x28\x2e\xf0\x26\xc4\xd0\x02\x26\x09\xa1\x18\x02\x13\x5a\x1f\x54\x57\x02\x3c\x20\xc4\x18\x0f\x7f\x42\x52\x04\xc9\xb4\x7e\xad\xf8\x14\x08\xd7\xf0\x4d\x3c\xc6\x05\x21\x7b\x30\xc7\x55\x39\x54\xd7\x55\x59\xe1\x85\xf2\x5f\xe1\x0d\x04\xa9\xeb\x45\x83\x94\x62\x3e\x05\xc4\xf1\x77\x80\x53\x56\xbc\x6e\xa0\x5a\x9e\x4a\xd5\x4d\x1e\x1a\x59\xbc\xae\x97\xad\x54\x30\x04\x11\xb6\xed\xdc\xfb\x92\x36\x2a\xb7\x7b\xcb\x4e\x38\x8e\x9d\x44\x9c\xcf\x17\x10\x9a\xc6\xe8\xe8\x1c\xda\x33\x54\xa8\x77\xd0\xe8\xcf\x39\x10\xdf\xad\x0c\x34\x25\x3c\xb2\x1a\x0c\x42\x6b\x3f\xdd\xc6\xa1\x12\xc2\xa9\x05\x20\xb6\x26\x9d\x2b\x4e\x1e\x96\xa8\xfa\x5e\x0c\x08\x74\x26\xdd\xc2\x69\x8c\xdf\x8c\xd3\x11\x6e\x22\x5c\x4d\xe2\x15\x0a\x75\x19\x2a\x33\x51\x22\x64\x14\xba\x50\xc2\xba\xc0\x78\xf1\x60\x35\x8e\x9e\x5c\x26\x2a\xf4\x81\xcc\x3b\x2f\x97\x41\x89\x34\x42\xba\x0b\xcc\xcf\x83\x28\x26\x51\x01\x47\x42\x9b\xb2\xb0\xe2\xac\xdd\xdf\x95\xc2\x64\xc0\xc9\x47\x0d\xff\xd6\x69\x45\x94\x8e\xec\x87\x51\xc7\xdb\xc2\x86\x94\x40\x48\x3d\xf5\xd4\x1e\x7e\x36\x83\x9c\x37\x25\x60\x84\xa5\x69\x55\xe5\x37\x51\xe9\x85\x38\x0d\xa8\x55\x28\x31\x4a\x44\x30\x64\xbe\x1a\x4d\x0a\x03\x56\x7d\x4f\xd4\x97\x42\x0d\xc5\x82\xbe\x78\x56\x63\x34\x38\x1c\xb0\xf3\x35\x1d\x44\xde\x0e\xeb\xe8\x4b\x26\x41\xec\xe4\x18\x85\x01\x07\x19\xfe\xf5\xe5\x93\x80\x24\xda\xf8\x98\xde\x22\x2f\x6b\xd0\x73\x2f\x19\x4c\x93\x80\x4b\xa0\x5d\x3d\xd8\x06\xaa\xf6\x35\xc7\x17\x08\xa5\xc1\x03\xe4\x58\x7e\xc0\xa1\x29\x87\x54\x86\x34\x89\x02\x86\x03\x7d\xf0\x85\xba\xf5\x98\xb0\x6e\xf2\x30\x91\xb4\xd5\xfc\x32\x6b\x76\xbb\xd9\x70\xa7\x48\xe2\x88\xa5\xaa\xe7\xaf\xbf\x5f\xbf\x3c\xdf\x2d\x3d\xeb\x35\x4d\x62\x1d\x59\xf1\x6b\x4c\x5d\x39\x9d\xbc\x1c\xd6\x45\x4f\x8e\x48\x13\xcc\x4d\x21\xef\x88\xc8\xcf\xd6\x2e\xc6\x2c\xc5\x13\x34\x55\xa6\x96\xd3\xc0\x45\x42\xa3\x04\xc9\x43\xed\xe1\x60\xb3\x8b\xc8\x8e\x8a\xb2\x73\xf7\x65\xb5\x15\x7f\x7e\xf1\x26\x8c\x31\x4c\x2c\xa3\x99\xdf\x61\x8b\x56\xc7\xd3\x5f\x62\xb9\xdc\x05\x78\x12\xe2\x0a\xc1\xa9\x73\x7f\x2e\xd4\x70\x12\x25\x5c\x86\x56\x83\xd0\xcb\xf5\x8e\xd4\x98\xc6\x8f\x92\x0a\x82\x70\x2e\x57\x54\xfa\x0b\x34\x23\x4d\x24\x68\xcc\x3b\x64\x45\xd6\x3c\xc3\xe7\x83\x3f\x08\x79\x07\xd0\xa1\x89\x34\x46\xc5\x3e\x88\x77\x53\x9d\x8e\x26\x8a\x68\xdc\xcd\x3a\xad\xf5\x09\xad\x03\x4d\x74\x48\x38\xf7\x04\xcf\x4e\xba\xc1\xd2\xf9\xdd\x82\x6a\xd1\xd6\xde\xa3\x66\xc0\xb2\x32\xef\x6a\x52\x6f\x46\xcc\x13\x4d\x35\xa2\xd5\x9e\x66\xff\x3c\x3c\xad\x9e\xf7\x87\xe7\x97\xa7\xb9\x2f\x13\xa2\x09\x44\x96\x62\xc4\x4a\x41\xda\x5d\xf6\xe1\xdc\x9e\x16\xfa\x66\xf5\x0d\x4d\x80\x6b\x8b\x7f\x2e\x1b\x2f\xd5\xe2\x5a\x4c\x02\x60\xe5\x81\xca\xb2\xee\x53\x77\x7d\x3e\x81\x86\x5c\x0a\xd9\xed\x6b\xae\x06\xcf\xab\xcc\xf9\x3e\xb2\x97\x6f\x5f\x88\x62\x4c\xac\x4c\x69\x08\xb6\x16\xf7\x23\xcb\x73\x91\x15\xa8\x48\xb5\x2f\x6f\x96\x05\x50\x1a\x85\x61\xe4\x34\x24\x76\xb9\x38\x1e\x6d\x52\x7c\x3c\xa2\x34\x8a\x93\xc4\xe5\xd5\xec\x36\x8e\x73\x75\x7a\x38\xd0\x88\x5a\xe1\x88\xc7\xfd\xde\x3f\x4b\x24\x42\x4c\x8f\x94\x2e\xef\x7e\xa8\x70\x14\xef\x76\x87\x53\x55\x96\xe6\x3b\xe6\x32\x0f\x07\x1b\xd7\x59\x94\x7a\xca\x7d\x32\x0c\x82\xd2\x48\x72\x1e\x76\x72\x9a\xad\xf9\x35\x29\xd6\xa0\x34\x32\x91\x37\x33\x56\xc3\x0a\x81\x71\xaf\x38\x88\x44\x84\xa7\x18\x2a\x25\x3f\x4d\x66\x1c\x8d\x43\x85\x07\xfa\x66\x33\x5f\x1c\x30\x5a\x79\x18\x94\xe8\xd2\xd6\x56\xc1\x22\x04\x2c\x2d\x5c\x3d\x3f\x1c\xee\x67\xab\xed\x1f\x5d\x2b\xd7\x64\x60\xe7\x3d\x65\x3f\xa1\x42\xd6\xdf\xd1\xb4\xa3\x49\xca\x30\x22\x9a\x67\x75\xb3\xaf\xca\xd3\xdb\x97\x82\x6f\xe3\x95\x47\x13\x91\x90\xd0\xe9\x40\xd7\x23\xe1\x10\xd7\x01\x21\x05\xad\xf7\x77\x2e\x34\x06\xe9\x57\x85\xe5\x0d\xbd\xbd\x94\x29\x8d\x23\xc4\x77\xbe\xbc\xac\xee\x3c\xd0\xdc\xbf\x4c\x1a\xd8\xfc\xd6\x51\xfc\xf4\x05\xe4\x4f\x1d\x3e\x8e\x52\xc1\x52\x61\xdd\x79\x55\xb6\x0e\xc4\xf8\x98\xa7\xc2\x28\x61\x4d\xc7\xfd\x1b\xcc\xd6\x5f\x79\x8a\xae\xb7\x24\x5c\xbb\x33\xfd\x5b\x59\xd5\x80\x48\xe2\xf1\xa3\x4a\x13\x45\x8e\x41\x71\x7e\xbe\x8c\x52\x52\x54\xc5\xc2\xdb\x58\x33\x6d\x3d\x19\x37\xe9\xbb\x0c\x5a\xdd\xf5\xa5\x96\x11\x0d\x05\xf2\x7d\x92\xb8\x6b\x64\x09\x24\x5d\x45\x47\x17\x66\x1f\x3f\xac\x52\x10\x58\xb2\x99\xff\x3d\xd7\xcd\xef\x9b\xd5\x17\xf9\x29\xaa\x83\xc0\x93\x02\xfa\xf0\xf0\x62\xe9\x6f\xa5\x43\x4b\xc9\xe3\x66\xe2\xbe\x5c\x8a\x2a\xbf\x78\xd6\xdf\x2f\xf6\x5e\xaa\x23\x86\x30\x9d\xd9\x6b\x95\x61\xd1\xd1\xa0\x98\x6a\xd5\x0f\x08\x70\x2a\x87\xa5\xc6\x0f\xa2\xde\x88\x8b\x14\xfd\x9b\x9a\x40\x62\xb4\xef\x29\x2b\x5e\xff\x38\x8b\xe2\x26\xf3\xc5\xb5\x8b\x4b\x4d\x64\x8f\xc7\xfd\xb7\xd9\xf3\xef\xbb\xfd\x72\xb7\x27\xdd\x25\x29\x71\x89\x5e\x78\x2d\x44\xd1\xfc\xab\xd4\x99\x50\xdd\xc0\x1b\x1e\x63\xde\xb0\x3d\x89\x5a\xff\xbf\xca\xa0\xf6\xda\x12\xb6\x0b\x0b\x22\x2e\xc1\x57\x6e\x5f\x23\x86\xcb\x32\x1f\x6c\x98\x2c\xe4\x0c\xa7\x98\x43\x05\x0f\x1f\x93\x85\x4a\x80\xf3\x73\x56\xaa\xdc\xbf\x65\x95\xfe\x01\xf0\xbe\xbd\x3a\x63\x58\x68\x12\x17\x47\xcb\xc1\x2a\x8c\x54\xf0\x90\x97\x26\xf3\x48\x3e\xca\x22\x22\x90\x79\x05\xcd\x1f\x3b\xf3\xec\x77\xea\x92\x0c\x2c\x4a\xa5\xad\x1a\x45\x5a\xeb\xe2\xd5\x43\x0f\x7c\xb3\x0a\x85\xf0\x57\xb0\x84\x7f\x43\x63\x91\x45\x60\xb9\xd7\xac\x11\x81\x05\x57\x57\x50\x51\xca\xe2\x50\x53\x1b\x24\x68\x16\x22\xcf\x7f\x64\xcd\x9b\x05\x5b\x0c\x93\xc3\xff\x43\xfe\xed\xbb\x33\x82\x7b\x15\xe8\xd2\x1a\x65\x07\x7f\x3b\xa2\x2c\x23\x91\xa3\x0d\xa3\x41\xd7\xa0\x99\x93\xe3\x6a\x2d\xb5\x27\x51\x5c\xee\xab\xf2\xd8\x47\xd5\x27\x11\x06\x96\x04\xa1\x43\x05\xa0\x12\xfb\x2f\xb4\x80\xc6\x83\x9e\x30\xe5\xab\x95\x9c\x2a\x34\x5c\xc7\xb2\x18\x0d\x43\xac\x09\xf9\x31\xd1\xbd\xf1\xcd\x3a\x89\x1d\xe5\xd5\x41\x8b\x26\x3b\xe4\x65\xd3\x94\x43\x13\x88\x31\x62\xd5\x9f\x3a\x13\xe8\xf9\x7c\xbc\x5b\xdd\xed\x4b\xac\xfc\xbc\xbd\x6c\x19\x53\xc6\xda\x37\xf5\x00\xb2\xe6\x47\x88\x87\x04\x77\x45\x68\xde\x1e\x45\x81\x59\xd6\xf5\xa9\xb3\x40\x19\x8f\x13\xc4\xd6\xff\xfe\xc7\x62\x68\x99\x32\x4e\x2c\x48\xb4\x81\xea\x58\xcf\x0a\xbd\x28\x0b\xab\xf4\x58\x77\x3d\x12\x8d\x8c\xdb\x05\x7c\x6e\xc4\x65\x7d\x6e\x7a\x95\xa6\x55\x3d\x50\x59\xf2\xdd\x95\x09\x22\x5f\x9c\x93\x0f\xe4\xde\xc6\x9b\x15\x4b\x43\x6e\x0b\x30\x86\x3a\x69\xbe\x8d\xa5\x58\x44\x70\x42\xbf\x73\x5b\xe6\xd7\x76\xe7\xf8\x62\x22\xb4\xa1\x57\xf4\x3a\x71\xfb\x99\x80\x8e\x29\x13\xcc\x96\xeb\x9e\xb0\x6e\xa6\xc3\x6f\x52\x26\x78\x88\x18\xe0\x79\xf6\x2a\x45\xf7\x47\xa9\x91\x51\x0f\x8a\xa6\xba\x78\x85\xc6\xf1\x8b\xca\x38\x20\x2e\xe5\xb1\x6a\xe0\x88\xd4\x85\xd7\x81\x47\x6f\x33\xf4\xbb\x83\x4e\x6c\xad\x7a\x0d\x85\xee\x64\xba\xda\x99\xb4\x05\x73\x3b\xa7\x38\xbe\x2f\xc4\xd6\xca\x7d\x2b\x3f\xdb\x75\xd0\x7a\xe5\xdd\xb7\x02\xae\xa5\xb3\x8a\x96\xcd\x9b\xe3\x8c\xc7\xf3\xb6\x97\xce\xa4\xcc\xf0\x58\xf4\x0c\xa7\xf7\x59\x0e\x5f\x21\x19\x98\x31\x01\x66\x55\x0e\x79\x27\x96\x71\x33\x27\x7d\xf3\x50\xe0\x41\x90\xca\x74\x40\x88\xd8\x9b\xbd\xbf\x5c\x85\x3c\x08\x29\xe2\x27\x5e\x7d\x51\xb6\xff\x7b\x4c\x11\x5d\x6f\xa3\x65\xbe\x4e\xd9\x37\xd2\x80\x91\xa1\xfc\xc2\x10\xa0\xe1\xfb\xc8\x10\x81\x08\xed\x76\xdb\xc7\xd1\x78\x48\x42\x4b\x2e\x24\xea\x66\x5f\xae\x26\x94\xe4\x94\x87\x86\xe2\x12\x50\xe2\x94\x35\x22\xdf\x0e\x58\x3d\x28\x8f\x52\x86\x34\x39\x70\x84\xea\xf5\x72\x98\x6a\x61\xb9\x5e\x71\xa4\x10\xa8\x70\xe7\xe3\x64\x3c\x76\xa2\xb1\xe5\x09\x8a\x1d\xa8\x0a\xae\x9c\x81\xd1\x01\xc7\x09\xb1\x19\xec\xe3\xc5\x03\x76\x22\x7f\xa9\x04\x6c\xe1\xcc\x41\x55\xe5\x67\xcf\xa7\x36\x7e\x89\xc4\xa4\xe8\xd5\xfc\xeb\xb9\xaf\x6b\xc0\xbf\x62\x8c\xe5\xa9\x14\x3e\x2a\xc8\x69\x90\xe2\xb1\x02\xc7\xac\x99\xc9\xb2\xea\x77\x19\x4e\x29\x09\xa4\xaf\x39\x11\xb2\x5e\x9b\x6b\x1e\x23\xca\xa9\x09\xc2\x74\xc4\x88\x9c\x76\x17\x30\x02\xeb\x8b\x2c\x64\x70\x3e\x5f\xdf\x95\xea\x7c\xec\x4a\x24\x87\xc6\x35\x67\x29\x45\xb4\xb6\xd0\xda\x1e\x4d\x4e\x7a\x65\xfc\x5e\x5c\xca\x48\x76\x2c\x89\x77\x7f\x83\x25\xd1\xfd\x30\x65\x09\xd6\x80\xa0\x47\x76\xd8\x89\x8f\xde\x2b\xe2\x42\x4a\x04\xad\x3a\xba\xbf\x7d\x79\x8f\xba\xf6\xb7\x2f\xa4\x82\x08\x4b\x88\xd1\x2c\xff\x27\x78\xda\x09\xca\x55\x22\x31\x56\x87\x3c\x0b\x2e\x6e\xec\x28\x1b\xc6\xdf\xda\xf7\x07\x3b\xba\xcd\xb9\x6a\x72\x38\x62\x8e\x7c\x0b\xff\xf1\x97\xd3\xc2\x5a\xb6\xb3\xe6\x0d\x0a\xf1\x28\x64\x3d\xc8\xb1\x76\xe8\x4f\x76\x95\x14\xef\x72\xd7\xae\xba\x9c\x72\xad\x34\x8e\xd9\xd3\xb7\xbd\xa5\xd4\x9b\x2e\x14\xa0\x31\x56\xfb\x74\xfa\xc0\xfe\x19\x4c\x28\x02\xe5\x14\xde\x3f\xa0\x5a\xee\xbf\x1d\x76\x50\x68\x79\x79\xca\x50\x3e\xaf\xeb\xc7\x01\x67\x9b\x16\x8d\xd8\xa1\x0a\xc8\x03\x34\x0f\x55\x79\x3e\x6d\xa1\x3e\xe7\x93\x15\x96\x06\xb1\x4a\x2d\xf7\x5e\xa9\xa0\xae\x97\x85\x5e\x9b\x3f\x40\x4c\x42\xb6\x69\x28\xe3\x40\x3a\x22\xf3\xad\xb5\x4f\xef\x44\x03\xf4\xa9\x2c\xba\xd5\x9c\x86\x10\xa3\x35\x82\x9f\xe3\x6e\xfd\xb0\xec\x0a\xd8\x69\x1a\xb1\x30\x71\xa5\x81\x0f\xe2\x08\x83\x67\xf1\xb1\xcc\x34\xe2\x01\xd2\x84\x16\xce\x32\x6e\xfb\xf9\x79\x91\xc6\xb1\x15\x58\xcb\xda\xa1\x77\x5b\xbe\x6b\x22\x51\x18\x2a\xa7\x74\x53\xde\xf0\xc4\xa7\xf0\x5c\xf7\x7f\x6f\x44\x8a\x53\x42\x53\x64\x8c\xf9\x5f\xa1\xde\x0f\x27\x4f\x70\x44\x53\x22\xad\xdf\xef\xab\xd1\xca\x7c\x2a\x44\xf0\x37\x13\x51\xe3\x09\x9c\x12\x45\xd0\xbc\x7d\xde\x0d\x29\xb3\x69\x9a\x04\x56\x70\xf4\x71\x75\xbf\xfc\xb1\xde\x3e\xde\x75\x0d\x61\x80\xf0\x50\x74\xf7\x2d\x23\x5b\xd6\xbc\x39\x12\xc6\xfb\xb2\x82\xec\xb5\x08\x7d\x67\xaa\x08\x82\x9a\x4c\xbb\x84\x66\xaf\xce\x1e\xf8\x35\xe1\x26\x4d\x59\x6c\x13\x4f\x58\xe7\xaf\x71\x97\xb9\x25\x62\x4e\x53\xe6\x8a\x91\xbe\x89\xfa\xad\x28\x35\xb2\xe6\x22\x38\xad\x80\x4f\xff\x08\x4c\x04\xf8\x08\xa7\x93\xbc\xbd\x86\x53\xa6\xed\xc9\x89\x25\x39\x63\x10\x4c\xca\x99\x2d\xd7\x69\xdf\x71\x44\xe2\xf0\x8a\x3b\x57\x3d\x45\x47\xf8\x9f\x71\xc9\xdc\x2e\x78\x37\x11\xa1\x40\x66\x8c\x6b\xc3\x32\xe5\x52\x81\xdb\x5e\x5b\x97\xb6\xe7\x88\xa2\x29\xd7\x02\x77\x24\x6d\xb9\xde\xe0\x24\x06\xfa\x5e\x34\xe5\x40\x31\x55\xf1\xa3\x12\xa7\x2d\x08\xeb\x6b\xa2\xb7\xea\x3a\xa4\x42\x3b\x66\xbf\xe6\x7c\xba\x3f\x63\x10\x76\xf8\x04\x93\xf1\x10\xb1\x62\xf2\xa6\x5d\x38\xab\xd0\x79\x75\x13\xfc\x0b\xcc\x67\x2a\x68\xca\x9d\x25\xf2\x3d\xab\x9a\x33\x8a\x6d\x69\xa8\x77\xe7\xe3\x71\xc0\x22\x37\xb9\xa9\x56\x60\x03\xeb\x63\xac\x51\x2a\x53\x6d\x19\xd2\x84\x81\xbe\x1e\xe1\x06\x7d\x05\x4d\xa5\x08\x90\x5c\xb1\x29\xe7\x71\x74\xdb\x59\x4d\xa5\xb4\x74\x40\xbe\x98\xcf\x85\x1e\xaf\x2d\xaf\xde\x6c\x4b\xa5\x09\x62\xe9\xd9\xf0\x36\xa2\x6a\xba\xfc\xfd\xe4\x01\x54\x7b\xb0\x0f\x6a\x2c\xd1\x7d\x76\xb7\xb9\x9d\xc2\xef\x06\x4d\xb7\xdb\x20\x0a\xb8\x2e\x6c\xd0\xc2\xae\xad\x49\x30\x25\xd5\x89\x41\x7f\x36\x53\x25\x96\x29\x4d\x9f\x40\x8b\x98\x59\xaa\x77\x4c\xa6\xfb\x41\x84\xd6\x9d\xc3\x58\xb7\xce\x0c\x3e\x11\xb2\x64\x16\xe7\x01\xd2\xfd\x56\xd6\x24\x05\x16\x23\x3d\xe2\x47\xd9\xc0\x7d\x59\x2d\x44\xa1\x33\x3d\x14\x0c\xb9\x19\x3b\x49\x81\xc7\xa8\x5c\xa8\xa0\xb4\x0c\x75\x8b\xb2\x9c\xbc\x09\xa4\x1c\xe9\xb7\x64\xf6\x85\xf2\x0a\x4d\x4d\x68\xeb\x21\x36\xdb\x25\xf2\x54\xfc\x58\xae\x0e\x0f\xeb\x99\x3f\x90\x52\x13\x72\x4c\xa2\x34\xd9\x11\xea\x55\xbd\xfe\x98\x5a\x23\xa9\x09\x53\x5f\x0e\xfe\xa3\xac\xde\xa1\xba\xa1\x56\x48\x53\x43\x89\xf1\xe6\xfc\xf5\xc2\x34\x4c\x61\x0c\xd4\xee\xbc\xf8\xdd\xbf\x0b\x7f\x74\x74\xdf\xcf\x70\x91\xa8\xde\x6a\xd0\x98\x06\xba\x2f\xab\x6b\x05\x7e\x2a\x82\x30\xea\x39\xdf\x76\x4d\x59\x0d\x54\x6f\xc7\x03\x29\x82\x18\xa4\x19\x80\xab\xa6\x57\xe2\x0a\x37\x37\xcb\x44\x38\xcf\x1a\xab\x34\xe7\x5b\x25\x60\xa8\xfa\x79\xb1\x1d\xd8\x7d\x22\x00\x8e\x60\xd6\xbb\xfd\x62\x71\x58\x3d\xae\x7f\x1c\x98\x6f\x0a\x83\xc8\x46\x52\x9c\xc1\x6f\x55\x54\x6e\xae\x24\x11\x46\x12\x0b\x49\x90\x19\xf3\x28\xde\xa1\xda\x54\xf0\x31\xd2\xb3\xff\x5b\xf9\x5f\x11\x12\xe9\xd9\x12\x7d\x48\xaa\x23\x95\xdb\xbf\x59\xf2\x3d\xdf\x95\x51\x4c\x6c\x98\xd3\xd3\xf9\xb6\x60\x06\x15\x51\x12\xe2\xac\xb1\x5c\xea\xd0\x1c\x72\x21\x3d\x03\x31\x15\x51\x2a\x31\x6a\xbb\x2c\x9a\xaa\x3c\x5d\xf6\x3f\xa7\x1a\xfc\x37\x2a\x1a\xa9\x88\x03\xc0\x98\xe4\x31\x2b\x6c\x91\x8f\xbf\x5c\x1c\xb2\xd0\x72\xd1\x7f\x94\x36\x01\xfc\xc5\x68\xc5\xa1\x44\x2b\x67\x50\x2a\xd8\x7a\x30\x63\x4e\x2d\x2a\xe2\x38\x1a\xa4\xf5\x11\x5e\x36\xf9\xe4\xb1\x0c\x75\x87\x65\xff\x26\x2a\xdd\xf1\x4d\x50\x11\x6b\xab\x73\x03\x3f\xb3\xba\x99\xcc\x72\x11\x03\xc7\xe2\xbd\xdc\x9f\x3f\xc3\x07\xf5\x26\x90\x20\x54\xe1\x4e\x51\x43\xd3\xe4\x30\x6f\xad\x2c\x8b\x92\xeb\xea\xb2\xa9\x20\x0c\x90\x84\xe3\xa9\x2c\x5e\xcb\x3c\x13\xcf\xc2\x72\xea\x0e\xf7\x6d\x91\x24\x84\x7a\x10\xe2\x3c\xcb\x33\x99\x55\x5a\x8c\x7b\x50\x89\x54\x29\xfb\x4c\x14\x8f\x99\x28\x46\x80\x96\xf1\x4b\x27\x8e\xf9\xd2\x7b\x58\x1d\x65\xf2\xb6\x03\x34\x88\x44\x5a\x5e\x80\xe3\x61\x90\x4a\xef\x1a\x8d\x40\xe6\xb6\xfa\x2c\x9d\x58\xc0\xf8\x06\x34\xd0\xdc\x06\x99\xea\xf3\x11\x26\x44\x1d\x54\x30\x02\x9a\x75\x31\xa8\x41\xb5\xc8\x78\x88\x39\x09\xc2\x8e\xc8\xeb\x69\x39\xdb\x97\xc5\x88\x52\x9b\x0a\x2e\x40\x30\xa7\x0e\x56\xa8\x4c\xe4\xbb\xa6\x12\x0d\xbc\x76\x1d\xd2\x48\xa3\xc1\x71\xbc\xa8\xae\xd6\xfc\x7c\xad\x6a\x49\x45\x4a\x00\x73\xb9\x45\xd9\x64\xe6\xb2\x36\x48\xad\x66\xb9\x6d\xbd\xb1\x34\x29\x84\x9d\x8c\xa9\x24\x11\x71\x6c\xf9\x0b\x51\x37\x5f\x93\xdd\xbb\xfe\x2a\x21\x38\xf1\x30\x7d\xb6\x85\x57\xc7\x42\x32\x3a\xc6\x84\xa2\x94\x13\xaf\x83\xdf\x2e\xa4\x7f\x41\xf5\x85\x9d\x21\x34\xa5\x68\xd1\x9b\xf8\xab\x0e\x22\x14\xba\x63\x0f\xbd\x13\x97\xfa\x11\xba\xea\x1f\xa1\x85\x44\x8b\x58\x43\x2e\x2e\x6b\xb3\x5a\xac\xbd\xd9\x29\x4c\xc8\x11\x2f\x79\x2c\x8b\x26\xbf\x1c\x4e\x5d\xa2\x5e\x98\x88\xa1\xbb\xfc\xdf\x67\x51\x34\xa2\x6e\x3a\xfc\xbd\x30\xc2\x95\xad\x42\x73\x93\x6d\x9a\x0a\x03\x1c\x41\xdb\x9b\xed\xd2\xf2\x26\x3d\x3c\x6d\x37\x07\x27\xef\x33\xdb\xb8\x0b\xc9\x20\x0d\x53\x2b\xce\x05\x99\x2a\xf7\x3e\x01\xdd\xc7\x1c\x64\x90\x72\xc3\x5d\x75\xb6\xe5\x3f\x9c\x16\x61\xc9\x30\xe0\xb6\xde\x64\x60\xf5\xcc\x3c\x01\x24\x95\x61\x64\x10\x50\xfd\x2a\x8e\x30\x50\xc0\xa1\x32\x4c\x0c\xb8\xf0\xbe\xd3\x18\xbb\x39\xb4\x32\x4c\x15\x46\x4c\x74\x25\xb2\x49\xde\x55\x46\x32\x8e\x2d\x06\xf3\xb5\xb5\xdb\xae\x25\xbc\x7c\x3f\x15\x63\x51\xd7\x77\x28\xb4\x65\x02\x1a\xb7\xc7\xa9\x74\x98\x32\x3b\x91\xd1\xd9\x7e\xca\x8a\x2e\xa4\x20\x63\x08\x50\x22\x09\x4b\x33\xd6\x05\xf4\xd4\xb1\x54\x12\xa2\x51\x9d\x04\xa1\x57\x96\xb3\xb5\xdf\x82\xa4\xd7\x90\x41\xf6\x1a\x34\x68\x17\xed\x3a\xea\x82\xf7\xa3\xb5\x22\x89\x36\x48\xbf\xac\x7a\x7d\xfb\x81\x91\x2f\x13\x42\x11\x32\xee\x77\x97\x7d\x25\xd4\xfb\xda\x8c\xa2\xf7\x32\x49\x04\xd6\x5f\xbe\x95\x2e\xeb\x38\xb9\x08\x4d\x29\x72\x91\x67\xc7\x53\x89\x20\xe8\x8f\xac\x3c\xd7\x36\xf7\x3e\x14\xb8\xba\xc2\xaf\xfb\xc0\xb5\xa4\xda\x66\x8c\x6a\xc7\x59\x34\xe1\x68\x9b\x8c\x3e\x0b\x58\x60\x39\xee\x11\x0b\x78\x3c\xe5\xf0\x73\xc4\x7b\x4b\x25\x73\x75\xb3\xf3\x32\x6f\x3c\x85\x12\x95\x9c\x25\x48\xf5\x9b\xb9\x34\xdc\x42\xe4\x6a\x4c\x04\xe9\x3a\xa6\x61\x28\xd5\x54\xc9\xfe\xf6\x54\x48\xc3\x14\xb1\x14\x9f\x38\x32\x8f\x59\x57\xc4\x4d\x65\x1a\x11\x9c\xec\xa8\x5a\xed\xc5\x4b\x7e\x0d\xe7\xbd\xbd\x01\xc9\x94\x28\xfc\x8a\x05\xbc\x96\x4d\xe6\x8d\x50\xbf\xf5\xc8\x34\x61\x08\xe2\xb1\x7b\xf4\xa1\xbc\x0e\x4e\xc9\x94\x85\xb1\x25\x47\xd3\x70\xc4\xfc\xd4\xe2\x8a\x1d\x9a\xca\x54\x07\x08\x09\x95\x18\x78\x72\x10\xdd\xac\x1f\xc0\xd4\x68\x74\xee\xba\x7c\xeb\xf7\xd5\x73\x07\x59\x97\x22\x8c\x91\x2e\x3f\x17\x75\x33\x40\x42\xad\x0a\x0c\x83\x76\xbd\x62\x89\x25\x04\x42\xeb\x3d\xd6\x0e\x8c\x09\x6f\x6e\x45\x01\xa5\x8c\x95\xa3\xae\xca\xa1\x01\xbb\xbd\x8e\xb7\x5f\xa9\x13\x9e\xc6\x3e\xc6\x31\x39\xe3\x24\x10\x86\xa9\xbf\x85\x28\x0a\x21\xb3\x3f\x87\x87\xb1\x04\x66\x45\x2e\x6a\x68\x3a\xf9\xd2\xc9\xcf\x85\x0d\x42\x3e\xae\x17\xbf\x2f\xef\xb2\xe7\xee\x97\x3a\x48\x6c\x12\xf4\x67\xbf\x0f\x99\x00\x74\xaf\x46\xaf\x44\xd1\x94\x85\xcf\xaa\x4c\x86\xdb\x18\x63\x78\x4f\x30\xb1\x2f\x8f\xb2\xdd\xf1\x86\xc4\x4d\xa3\x71\x50\x41\x62\x99\xab\x5c\x81\xc7\x80\x2e\x8e\xfb\x1e\x2c\xa6\x43\xae\x1b\x27\x5d\x74\xfb\x6a\x9a\x22\x72\xf5\xf0\x0a\xcd\xc2\x6a\x67\x21\xba\x61\xf4\xf2\x2a\x14\x4a\x5b\x76\x8c\xb2\x34\xf7\xe5\x88\xd9\x8a\xaa\x50\x4b\xcc\xb1\x3f\xb4\x97\x68\x0f\xdf\xd6\xbe\x9a\x5f\x86\x14\xf5\xae\x67\xc4\x23\xcc\x96\xcf\xcf\x97\xfb\xb2\xba\xaf\xb2\x21\x8e\xea\x6f\x99\xcb\x2a\x36\xbe\x80\x5d\xe8\x76\xaf\xf3\xc8\xe4\x59\xb3\x1a\x55\xad\x8c\x7f\x45\x22\x16\x0e\xf0\xa2\x3f\x4f\x59\x05\xfa\x9a\xf6\x94\xaa\x24\xd0\x28\x2d\x6d\x17\x50\x3d\xaa\x70\x53\x49\x4c\x5d\x82\xbd\xd0\x98\xb0\x78\x12\xc5\xe5\x4b\xe6\x2b\xaa\x12\xc5\x31\x61\xa1\x72\x10\xc5\x8b\xdf\x98\x14\x95\x2c\xb6\xc4\x6a\x4d\xf6\x01\xf7\x59\x55\x37\xc3\xd5\xa1\x18\x89\xd1\xcb\xfd\xc7\x6c\x33\x5b\x7c\x5b\x3e\xae\x3d\xfc\x45\x71\x43\xd1\x3c\xf5\x0e\xca\x5c\x7c\x4d\x33\xea\x7e\x92\x32\xaa\x23\xef\x0f\x84\x13\xe2\x86\x64\x44\xdb\x40\x55\xca\x35\x1a\x7a\x3f\xb2\xf7\x6c\xb8\x3e\x54\x9a\x6a\xb4\x45\x76\xcb\xfd\xcb\xa6\xfb\x23\xa4\x68\x55\x3a\xa7\x6f\x07\x85\xbe\x41\x62\x39\x2c\xd6\x9b\x3c\x9b\x60\x09\x06\x37\x66\xef\xe5\x40\x83\x9e\x2a\x21\x05\x8e\x73\xbb\xf5\xb6\xe7\x40\x2f\x87\x40\x95\xe4\x14\xb1\x66\x9f\x3e\x03\xea\xc7\x62\x53\x65\xc7\xb2\xd2\x99\x33\xc4\x7f\x55\x40\xe8\x2f\xa5\x84\xf4\xc5\xbd\x1b\x51\x75\x8a\x18\x1e\xdb\x3e\x5a\xa8\xaa\xdd\x01\x02\x5f\x93\x67\x75\x85\xb2\xe2\xf5\x4b\x07\x51\x29\xa6\x7d\x71\xc5\x4b\x91\x35\x77\x60\xa0\xa8\x61\x55\xb4\xeb\xfc\x16\xd7\xff\x74\xda\xf7\x11\x18\xa5\x4d\xc4\xc3\xae\xe2\x6a\xd3\xec\x84\x81\x27\xd0\x59\x17\x6f\x57\x00\x76\x73\xb4\x40\x0b\xed\x35\x2d\x6f\xd4\xc7\x7f\x41\xaf\x4f\x95\x89\x05\xd3\x9e\x11\xc8\x05\xed\x16\xe7\xe9\xfa\x30\x24\xc1\x18\xb1\xe5\x60\x18\xd5\x2e\x7e\x85\x8c\xbb\x62\xb2\xb9\x19\x37\x53\x26\x21\x61\x27\x35\xd9\x5a\x84\x9b\x0a\x56\x9e\x81\x84\xea\x40\x1a\x4c\xd7\x3e\xf4\xac\x3a\xbe\x48\xc2\xf5\x88\x40\x62\x2e\xeb\xe0\xb5\xaa\xff\xfb\x2c\xf2\xac\xb9\x2c\xca\xa2\x86\xa2\x3e\xd7\xb7\x21\x67\x3a\x32\x56\x1b\xb3\x86\xe6\xbe\x02\xc0\x6b\x7e\x31\x8d\x6f\x68\xab\xf1\x7e\xd5\x0f\xfe\xdf\x70\x7f\xd4\x71\x9c\x7a\xe4\x83\xb7\x9a\x26\xc0\xaa\xd1\x4c\xd3\x31\xb5\xe2\x34\xcb\xe7\xfd\xf6\x8f\xc3\xfd\xd2\x03\x54\x74\xac\x13\x2c\x5f\x47\xc6\x3d\x0b\x6a\xd0\xb7\x8c\x89\xee\xd5\x62\x27\x32\x85\x9b\x19\x46\x50\x7a\x50\xe3\xf8\xc3\x6a\x22\x22\xec\x2a\xb4\x7e\x14\xea\xdd\xcb\x95\x5b\xf2\x1e\x4a\x3a\x25\xf5\x8e\xcd\xa7\xfb\xfb\xe4\x3f\x71\x50\xfc\x16\xa8\x93\x90\xc6\xdc\x27\x42\xd5\x4a\xbb\xcc\xec\x6a\x92\xcb\xd2\x49\x9a\xf8\xaa\xc1\x99\x97\xe8\x6c\xce\x93\x33\x5c\x53\x6e\x90\xda\xc7\x71\x77\xfd\xc8\x8a\x4d\x59\xe6\x18\x28\xc9\x2a\x8d\x14\xf8\x7e\xac\xa8\x4e\x44\xc7\x02\x24\x64\x3e\x54\xd6\xa3\x9a\x45\xc2\xcb\x39\x7e\x2f\x9b\x01\x27\xcc\xcd\xb5\xac\x39\x0d\x86\x1a\x58\xed\xb9\xf3\xfb\x1f\x8b\x59\xa1\x77\xa8\x8e\x0f\x55\xf5\x05\x23\x2a\xd5\x3c\x75\xb8\x61\x0f\xe3\x6c\x44\xee\x44\x14\xfd\xc3\xa4\x09\xd5\xb6\x80\xef\xf2\xdb\x68\x4a\x4d\x9e\x42\x84\xca\x73\xad\x60\x39\xcb\xee\x69\xb3\x1f\x02\x7c\x7d\x37\x19\x27\xce\x09\x7a\xd8\xec\x46\x4a\x8c\x54\xcb\x48\x22\x42\xe7\x71\xfd\x70\x98\x43\xf3\x58\xd6\xb7\xf9\xf2\xa9\x96\x14\x70\xbf\x3b\x95\xc5\x9f\xd9\xbe\x1c\x20\x88\xa7\x1d\x55\x84\x80\xc4\xa7\xf5\x76\x94\x44\xd1\x4a\xc6\x91\xea\x8a\x9b\x06\x12\x18\xae\x5d\x07\x21\x77\x3e\xe7\xee\x2c\x91\x30\x63\x7c\x65\x2d\xac\x9b\x76\x76\xbc\x8d\xce\x10\xbd\x91\x38\xd2\x5a\x01\xe2\x67\x3a\x7d\xb3\x43\x3d\xd5\xf8\xa1\xda\x04\x3a\x09\xfc\x4a\x2f\xff\x44\x92\x3a\x84\x0e\x2d\xd6\x03\x8e\x1c\x6d\x22\x7b\x64\xbe\x67\xea\x7d\x7d\x6e\xbd\x0b\xab\x8d\xf9\xc5\x40\x19\x61\xc0\x39\x63\x18\x5c\x71\x52\x5d\x93\x4e\xca\xf8\x28\xdf\xa2\x2c\x73\x5d\x7e\x7a\x95\x0f\xec\x48\x02\xdb\x0f\xc2\x84\x7b\xe0\xc0\x26\x43\x6d\xf4\xba\x86\xa6\x9e\x15\x1a\x29\x2a\xb0\x8a\xba\x2f\x45\xbd\xda\x7a\xc6\x8f\x06\x51\x18\x21\xc2\x43\x68\xbd\xa8\x2e\x75\xf3\x15\xea\x10\x08\x25\xa8\x9c\x72\x72\xd6\xd4\x54\x31\x8b\x02\x11\xb1\xd6\x1e\x08\xe6\x76\xde\xeb\xb4\xc1\x57\xff\x7d\xfb\xae\x89\xa2\xa2\xe3\xbe\xfa\x01\x19\x96\xf2\x76\xfe\x31\x24\x10\x86\x91\x3f\x11\xec\x59\xeb\xab\xed\xbb\x1e\x51\xca\x3d\x35\x63\x06\x05\x16\xa2\x0c\x91\x8a\xa3\x49\x02\x94\x2a\xa4\xd0\xb0\xa8\xb1\xcf\x81\xe5\x03\x94\x87\x98\x12\x5f\xbd\x9f\x2b\x61\x91\x8a\xe2\x8a\x6e\x71\xf2\xf8\x2c\x4a\xf1\x58\x6e\xed\x87\xd6\x12\x1c\x84\x0a\xc6\x07\xc5\xb5\x69\x08\x4c\x32\xcc\xdd\x35\xda\x82\x80\xfa\xb7\x66\x86\xa6\xbe\x24\xef\x90\x15\xad\xb9\x76\x30\x99\xe5\x6e\xf8\xd6\x5a\x2a\x15\x7c\x78\xdd\x9b\xd1\xe3\x70\x66\xf0\x71\x76\xef\x59\x9e\x4f\xe9\xcf\x29\xf0\x94\x4b\x57\xa9\xb8\x52\xa0\xfb\x2a\x1b\xd7\x9e\x4a\x8e\x21\x7c\x5d\xee\xa0\x59\x88\xc2\x66\x60\x1e\x2a\x51\xf4\xb1\xd4\x81\x51\x02\x22\x14\xc8\x8c\xe7\x18\x5e\x4e\xd9\xa4\x8e\x1d\x04\x75\xfb\xc2\xea\x79\xb9\x3d\x2c\x9f\xef\x0e\x98\x53\xf7\xf7\x93\x61\x8c\xc8\x25\x2b\xcf\x32\xa2\x74\xfa\x7b\x1e\x71\x7b\x05\xc4\x09\x7e\xcf\xa0\x29\x9c\xb4\xe8\x5f\xe3\x25\x41\x26\x5c\x0f\x8d\x68\x17\x8b\xde\xc2\x47\xf9\x3e\xcd\x38\x81\x04\x12\x5a\x15\x58\x23\xce\x79\xf3\xb2\x5d\x0d\xb4\xa3\x29\xa8\xd4\x02\xfa\x3b\xad\x7d\xb7\xa3\x74\xed\xd2\x6a\x70\xbd\x42\x73\xaa\xb2\x3f\xe1\x58\x16\x70\x99\xdc\x42\x69\x86\x69\xb3\x9b\x2c\xea\xbf\x22\x94\xba\x89\xc4\xfc\xaf\xc9\xc5\xc1\xa2\x20\x1f\x41\xbc\x9e\xa1\x97\xab\xec\x13\xa8\xa0\x89\x64\x5d\x39\x54\xfd\xde\x9a\x7f\xa3\x9c\x80\xef\x96\xd8\x4a\x27\xbb\x19\x5b\x12\xa6\x61\x3e\xbb\xff\x2e\x9a\x1b\x04\x0d\xbd\xe2\xdc\x79\x29\xf2\x1e\xce\x0b\x10\x69\xc4\x80\x75\x03\xe6\x5c\xac\x11\x54\x19\x80\x58\x52\x14\xef\xc1\xe2\x26\xd8\xee\xc3\xed\xa9\x39\xfe\xc0\xb7\x12\x16\x00\x9c\x61\x59\xed\x21\xf8\xb9\xec\x34\xe3\xbb\x8b\x73\x85\x1e\x3b\x3a\x5e\x16\x77\xe6\x5b\x24\x4f\x5d\x58\x62\x9e\xe9\x2f\x04\x75\xc7\xa3\x02\xc6\x60\xb1\xe4\xe9\x5c\xbc\x3f\x97\x8f\x65\xf1\x8a\x79\xaf\x2b\x61\x00\x0a\x26\x65\x66\xc2\x74\xb3\x2f\xdd\x6b\x4f\x7a\x2a\xe9\xf9\x45\x7e\x87\x4b\x4f\x18\xff\x95\xe9\x6c\x02\xe3\x44\x60\x40\x1c\x1d\x38\xc4\x6f\x27\x26\x0c\x2c\x75\x63\x53\x9e\x5e\x4e\xed\x1e\x82\x03\x32\xf3\x12\x08\xf7\x65\xe5\x71\x30\x37\x37\x39\x13\x26\x80\x99\xd9\x47\x51\x49\x51\x9e\xb3\xee\xba\x4c\x62\xcd\x57\xaf\xbc\xbb\xa9\x60\x57\xe6\x5e\x8d\xd8\x77\x4b\x53\x2b\x72\x5c\xe4\x17\x0c\xd5\xee\xa0\xb1\x90\x26\xf7\xea\xa3\xe1\x34\x71\x48\xb0\x5a\xe3\x01\x61\x7c\xb7\x44\x9b\xa8\x89\x23\xeb\xeb\x2c\x56\x0e\xd0\x79\xc3\x1e\x30\x31\xa5\xc4\x05\x74\xbe\x1f\xb6\xc9\x78\x84\x4d\x9c\x32\xdc\xbb\xcc\xb9\xd0\xbd\x8f\x61\x48\x4a\x54\xea\x8b\xc7\xaa\x63\xdd\xf9\x50\xe3\xe1\x4e\x82\x04\x1f\x60\x2b\x8c\xc9\x61\x8c\xea\xf9\xf2\x24\xfc\xbb\xff\x5e\xf9\x1d\xe3\x5b\x13\x1e\xb7\x5b\xde\xb7\xec\xf5\xad\xb5\x1f\x5a\x5f\xf2\x5c\xc1\x62\x40\x95\x67\x92\x44\x20\x72\xdf\x02\x21\x06\x78\xd9\xdb\x1f\x38\x01\x89\xcb\xc1\xcf\xcb\xd6\x56\x9e\xe2\x52\x4d\x62\x12\x2c\x63\xd9\x3d\x6d\x66\x0a\x6b\x9c\xff\xa2\xfe\xcd\xd0\xc4\xe0\xc6\x39\xdb\xed\xb7\xcf\x36\x4d\xe0\x2f\x46\x41\xa3\x06\x03\x02\x0a\x2a\x57\x05\xde\xcd\x18\x6a\xac\xd1\xf7\x86\xd3\xb2\xd7\x8c\xf6\xed\x2c\x0e\x42\xb7\xa5\x62\x39\xe6\x90\x2a\xc2\xf0\xc8\xa6\x85\x8e\xa2\x76\x0e\x92\xe5\x5b\xb0\x21\x3d\xeb\x53\xb4\xcb\x33\xcb\x3f\x1c\x35\xc9\xe3\x08\x44\x3d\x38\xe0\x0c\x27\xc4\xbb\x6d\xeb\xd3\x64\x0a\x70\x25\x02\xe6\x22\x14\x9b\x7f\x3e\x7e\x31\xb4\x69\xc8\xf0\x88\x7b\x9a\xfd\xf3\x70\xbf\x5d\x2e\x0f\xdb\xe5\xfd\x72\xbb\x9d\x3d\x1e\x36\xb3\xc5\xef\x3e\x66\x6a\x52\x22\xd0\x16\xd8\x29\x91\x83\x8d\xf5\xf7\x4d\x12\xd3\x32\x56\xcb\xc3\x29\x7e\xfc\x7a\xe0\x53\xaa\x31\x37\xd0\x1a\xc1\x6b\x83\xab\xbd\xbb\x1a\xb7\x4c\x27\x4a\xe4\x6a\xeb\x8b\x1c\x7e\x51\xa9\xec\x7e\x26\x23\x85\x84\x34\xf2\x7c\xf1\xea\xd0\xbf\x4e\x96\x19\x49\x14\xa6\x48\x5d\x50\xf3\x3e\xcb\x8f\x5f\xe0\xb5\xfc\x0f\x28\x28\xe3\x85\xd4\xbf\x95\xe7\x8e\xff\xd0\x48\x15\x50\xe7\xf4\xfc\x80\xac\x03\xf9\xdf\x74\xb6\x8c\xe2\x96\xd0\x42\x68\xbd\xbb\x32\xff\x8d\x4a\x29\x06\xb1\x8e\x22\x2b\x06\xe9\x4d\xa3\x24\x78\x03\x1e\xc1\xfb\x2f\x59\x31\x5d\xf2\x4a\x85\x98\x5a\x16\xaf\x7b\x50\x6f\xa3\xc3\xca\x40\x2c\x02\xf7\xf3\x17\x7b\xbf\xa7\xac\x18\x99\x66\x06\x80\xc5\xd1\xa8\x18\xf4\xb9\x6c\xc6\xfb\x1a\x0b\x02\x1e\xa2\xdf\x76\x78\x13\x1f\xb0\xfc\x80\xea\x52\x16\xd0\xd3\xc6\xf9\x5e\x42\x62\x9a\xa4\x3d\xa3\xce\xfa\xf5\x1a\xdf\xef\xfb\x81\xc0\x6a\x92\x2e\xab\xd3\x7e\x68\xa4\x14\xfa\x32\x60\xc9\x82\x48\x6b\x24\xde\x78\x7b\xb7\xe4\x9b\xe7\x5b\x67\xad\xeb\x1b\x53\xbb\x0e\x6b\x61\xe0\x20\xf4\x15\x55\x9b\xef\x06\x96\x64\xcb\x46\x5e\x1f\x33\x03\xcb\x9f\x27\x50\x8d\x28\xd4\x98\x81\x9f\x05\x84\x48\x01\x57\x8e\xd4\xa0\x2a\x83\x05\x84\x87\x34\xec\xb3\xb0\xed\xfe\x3d\x66\xe4\xe3\x63\x71\x68\xff\x33\x99\x30\x8b\x74\x6f\x94\xe5\x80\xea\x2e\xa8\x24\x7a\x10\x42\x6b\xe4\x0b\x1c\x83\x18\xbe\x72\x67\x46\x03\x91\xc4\x91\x81\x31\xdf\x73\xdd\xd7\xc2\x4d\x86\x23\x31\x92\x3b\x99\xda\xd5\x62\xdd\x69\xe6\xb2\x80\x52\x5b\xfb\x97\x8b\xba\xf9\x87\x50\xef\xa7\x72\x18\x14\x66\x01\x95\x84\x39\xe4\xd6\xe1\x24\xce\x35\xbc\x2c\xf7\xbd\xd3\xda\xb6\x73\xac\xfe\xdf\xcc\xb6\xbb\xe5\xe2\xb0\xd8\x2e\xef\x56\xfb\xc3\xdd\x72\xb1\x7a\x9a\x3d\xee\xfc\x55\x58\x4c\x2c\xf9\xf9\xf9\xf2\x98\x15\xef\xdd\x9f\x49\x1a\x5a\xea\x18\x28\xbe\x41\x05\xb3\xae\x21\x25\xd0\x33\x2a\x7e\x83\xfc\x34\xf9\x66\x4c\xc4\x96\xfd\x21\x83\x6a\xff\x59\x3e\xf9\x63\x88\x05\x9c\x6a\x8c\x99\xec\x8e\xd9\x2b\xd4\x03\x0b\x8c\x05\x69\x40\xac\x1e\xac\xc8\x21\xb4\x44\xf1\x1d\x8f\x01\x0b\xd2\x44\xa3\x03\x64\x0d\xcd\x3d\x14\xed\x47\xf9\xf0\xec\x5f\x8b\xb7\x2c\xd7\x2f\x45\xf6\x01\x55\x3d\xae\xe2\x63\x41\xaa\x75\xe2\x56\x22\x62\xee\x8e\xa2\xea\x5e\x51\xe8\x04\xf3\xd2\xad\x8d\x74\x70\x15\x5e\x07\xe8\x69\x01\x58\x20\x03\xbb\xa7\xd7\xed\xaf\x51\x36\xf8\x51\x34\x80\xb5\xd5\xd5\xb5\x03\xc4\x02\x19\xc6\x2a\x71\x94\xa2\xa3\x6c\xa5\x43\x93\xb0\x40\x4a\x99\x76\x01\x1b\x5b\xb3\xbc\xfc\x69\xd3\x8e\x76\x3c\x6e\x71\x75\xb7\x3f\xd3\x58\x7a\x60\x37\xcf\x1b\x66\x68\x1c\x8d\x35\xeb\xa6\xbf\xd7\x12\x51\x16\x33\x9d\x69\x31\x50\x06\x67\x81\x4a\x23\x74\x7d\x1e\xd6\xbb\x6f\x2f\xab\xe7\xee\xcf\x4a\x21\x3f\xc3\x93\x38\x35\x5e\x7d\xd3\x35\x69\x46\xb1\xc6\xef\x60\x61\xeb\x68\xc2\xd5\x6f\xd9\xc9\x83\x94\x7e\x19\x38\x63\x81\x96\x92\x39\x8d\x35\x27\x8b\x31\xd0\xc1\x66\x81\xd6\x21\x2e\x9d\xac\xa7\x02\xa2\xbe\x0d\x84\x44\x7b\x59\x68\xdd\x1a\x01\xb3\x42\xcf\xf4\x47\x56\x97\x55\x3d\xc8\x49\xde\xbe\xab\x09\x39\xae\xa5\x4f\x80\x77\xe4\xf6\x5d\xf6\xeb\xc8\x88\x28\x1a\x14\xa5\x66\x22\xcf\xfe\x84\x85\xa8\xdf\x06\x81\x05\x16\x86\x24\xc6\x40\x63\x56\xb7\x96\xfc\x63\x07\x76\x66\x61\xa4\x9d\x19\x0f\x75\x73\x2f\xb2\xbc\x47\xc3\x0c\xcb\x44\x5a\x43\xbb\x3c\x37\x5d\x20\xc1\xff\xd8\xc4\x48\x5c\x86\xaa\x68\x88\xa0\x5d\x6e\x17\x21\x4d\xb0\x26\xd4\x08\x35\x61\xd8\x77\xf3\x28\x8c\x39\x0c\x26\x84\xa3\xbb\xf6\xc9\xe4\x5b\xd3\xc3\xfd\x8e\x90\x10\x93\xb1\x47\xf1\xf3\xa1\xec\x9f\x82\xd0\x08\x39\x3f\xdb\x57\x78\x80\xc6\xd6\x52\xdf\x55\xe2\x75\x92\xf4\x64\x21\x49\x23\xe4\xf9\xd8\x3e\x3f\x74\x3f\x16\x96\xcb\xe3\x78\x71\xe2\xba\x5d\x83\xb4\xec\x27\xe5\x07\x54\x26\x2f\x3f\x07\xc0\x0c\x16\x12\x0d\xe8\x59\xe1\x01\x34\x43\x41\x21\xdf\x44\x03\x46\xe9\xa8\x64\x22\x8c\xbb\xb6\x90\x85\xbd\x08\xf5\xbe\xab\x41\x0c\x7f\x2d\x4d\x1a\xd2\xf1\x38\x50\x12\xe0\x24\x76\x90\x8e\x4d\x05\x26\xfb\xb9\xf1\x68\x5e\xf4\x03\x87\x87\x87\xff\x95\x22\x41\x30\x51\x19\x79\x29\xb2\xff\x9c\x61\x48\x72\xc1\x42\x6a\x00\x91\x44\x75\xcc\x7e\x1b\x48\xa8\xb0\x90\x11\x5b\x98\x76\x72\x68\x08\x0c\xda\x4e\x54\xe2\x59\xc8\x54\x8c\x75\x21\x06\x4b\x57\xfc\x24\xaa\x77\x59\xa1\x6e\xb2\xd9\xb0\x90\x53\x5b\x9a\x8b\xb6\x1d\x9c\x8f\xae\x38\xc7\x3f\x4f\x1a\x59\xc5\x2f\xd5\xfa\x4e\xf9\xa4\x1a\xea\xb7\xd1\xc0\xa4\x10\x62\xce\xe5\x5c\x83\x27\x63\xef\xae\x02\x4e\x2a\xbd\x1d\x9d\x8d\xad\x9e\xf6\x6d\x42\x13\x0f\xc3\x1d\x93\x68\xb0\x50\x06\x24\x54\x5d\xb9\x2e\x82\x51\x46\x2c\xf9\x37\x0d\x46\x16\xca\xd8\x0a\xc3\x6f\x56\xcb\x7f\xee\xb7\xcb\xd9\x53\x77\x3d\xe0\x68\x42\xd7\x03\x66\x13\xd7\xa4\x68\x20\xdb\xf7\x9c\x3d\xcd\x67\xbb\xdd\xec\x6e\xbd\x3d\xdc\xaf\xbe\x2f\xfd\x2f\x95\xb2\x48\x04\xc7\xd2\x39\x86\xbe\x4e\x6e\xaf\x65\xcc\x9d\xc6\xc9\x00\x48\xb6\x98\xe0\x65\xc6\xb7\xd7\x4a\xe2\x77\x73\x48\xe5\xa7\xfd\xe6\x8b\x8b\x1b\x66\xf1\xeb\xf5\x75\x9d\x93\xef\x91\x2a\x4c\x92\x58\xb0\x9c\x4f\xec\x8c\xae\x12\x05\xc4\xee\x3b\x07\x28\x5a\x0f\xcd\xda\x3e\x93\x67\x8a\x02\x4e\x2c\x96\xbf\x93\x57\x43\x43\xea\x37\xdf\x2c\x48\x12\xbb\x80\x3c\x8e\xc8\x7b\xdf\xa4\x6d\x9a\x02\x0a\xed\x34\x69\x7f\x95\xbf\xfd\xab\x7f\xbd\x41\x19\x05\x60\x02\x3e\x54\x85\xc9\x9e\x01\x77\xaf\x6b\x6a\x58\x16\x05\x26\xb6\xa9\x6a\x57\xdb\x6e\x7d\x97\x9b\x13\x26\x0a\x0c\x0f\x2c\x28\xdd\x12\x6a\x4e\x2e\x15\xc6\x56\x70\xba\x6c\xe7\xfc\x7d\x96\xe7\xf5\xd8\x54\x88\x48\xc2\x70\x4b\x5d\x58\xf6\x22\xa8\xee\xa4\x1f\x8a\x24\x0e\x58\x38\x84\xb0\x1c\x4c\xd0\xb5\x71\x1b\x98\x3a\xb6\xfb\x98\x93\xd3\xbf\x2a\x7d\xf4\x1c\x91\xee\x37\x34\xd0\x31\xf4\x7c\xe1\x7e\x4f\x8c\xa8\xe3\x48\x75\x32\xd5\x35\xd6\x33\xae\x7c\x48\x9a\x45\x54\x18\xac\x85\x79\xca\x72\xa8\x9b\xb2\x00\x5b\x41\x38\xac\xc1\x63\x11\x35\x16\x81\xdb\x87\x61\xac\xd4\xc5\x78\xb4\x58\x92\xe0\x82\xd5\xd0\x40\x75\xcc\x0a\x18\x72\xa8\x8e\xba\x79\x4b\xd6\x83\x28\x27\xed\x1c\x5c\x12\x63\x5e\x09\xf5\x6e\xb1\x82\x4f\x99\xd6\x39\xe2\x94\x57\xee\xc6\xdc\xf5\xe7\x34\xc0\x53\xd4\xe1\xee\xcf\x75\x53\x1e\xa7\xea\x56\x5d\x57\xce\x5d\x9e\x10\x91\xfd\x0e\xd6\xe2\x5a\xd3\x90\x83\xb3\x05\x30\x5d\xf7\xfd\xca\x7b\x8a\x52\xca\xb1\x0c\xff\xf0\x26\xea\xfb\x5c\x5c\x93\xfb\xf9\x7e\x32\xc2\x0a\x88\x63\xe9\x78\xda\x2c\x38\xd1\x46\xed\x00\xf4\xd0\xe8\x8e\x52\x57\x77\xfc\x0a\xcd\x3f\x4a\x39\x99\x42\x22\xb2\xb1\xaa\x37\x51\xe8\x1c\x5a\xa3\xe4\x73\xc0\x1b\x36\xb9\xad\x00\x16\xd9\x7d\xd1\x41\x77\x47\x12\xa2\xae\x93\x64\x02\x93\x3f\x3b\x99\x97\x4a\x89\x76\xff\x29\x27\xaf\xa9\x48\x8c\x7c\x2a\x59\xfd\xed\x7c\x14\xd3\x15\xa4\x58\x22\x12\x87\x91\x7a\x15\x0d\x7c\xb7\x6c\xf7\x7e\x23\xbb\xae\x58\x64\x91\x8e\x14\x52\xf2\x59\x62\xb3\x6f\x2b\xff\x2c\x3a\x96\x38\xb1\x1e\xc5\x51\x96\xce\x78\xfb\x5b\x1c\x38\x2c\xd2\x49\x20\x7c\x0e\xab\xa3\x95\x24\xdd\x85\x93\xd8\x93\x45\x3d\x9f\x8f\x08\x9f\x87\x6e\xce\x6b\x99\x08\x87\xe0\x7a\x7c\xfc\x6e\x7f\xc9\x7d\x23\x10\xea\xf3\x9f\xf3\x97\x97\x97\xaf\xc4\x16\x7c\x6f\x9a\x7a\xe6\xce\x4d\x59\xe6\x53\x28\x03\x8b\x4c\x1c\xa0\xdb\xef\x06\x69\x32\x2e\x26\x26\xda\x25\xa4\xef\xac\xc8\xac\x9e\x8b\x3a\x53\x73\x91\xe7\x65\x53\x3f\x4f\x26\x83\xa1\x1c\xc3\xac\x76\xf3\x9e\x72\x12\xb1\xc8\xa8\x04\xcb\xf8\x0f\xc8\xbe\x51\xc1\xac\x58\x17\x0f\x65\x3b\x0f\xc4\xa9\x53\x5d\xb0\x7d\xe3\x20\x89\xd0\x4a\xc4\x34\xd5\xae\xcc\xf5\xd0\x05\x8e\x03\x96\x62\xd9\xc7\xec\xdc\x4c\xf3\x4d\xbe\x07\xb7\xc5\xc7\xed\x27\x8b\x76\x4d\x79\x3a\x75\xfb\x45\x1c\xa4\x26\xf2\xb6\xdf\x23\xaa\xcf\xbe\xb4\x67\xc1\x88\x8a\x82\xc5\xa1\x8a\xf1\x68\xcd\xcb\xa6\xb1\xd8\xf7\xa1\xd9\x10\x87\xda\xd2\x25\xce\x4e\x7f\x0e\xbc\x8b\x38\xa2\x96\xcc\xe9\x15\x9a\xd9\x76\x55\x7c\x58\xb2\x9b\xbe\x94\x8b\xc5\x51\x4a\x2c\xc1\xb0\xc5\xae\x89\xa6\xac\x66\x79\x05\x42\x5f\xda\x15\x7d\x3b\xaa\xc3\xe2\x08\xa4\xb7\x10\x6d\x04\xec\x0e\x8a\xf2\x68\x15\x71\xfc\x95\x49\xa4\x50\xa5\x6c\xf7\x70\xef\xff\x44\xa3\x30\xf1\xc8\xa7\xfd\x5b\x55\x7e\x1e\xda\xff\xd7\x3e\xce\xb0\xf4\x69\x21\x6a\x17\x91\x68\xad\xf9\x73\x77\x58\xc6\x8c\x05\x60\x5d\x97\x83\x07\xce\x5a\xc7\xbb\x1b\x4b\x66\x22\x46\x3a\x7a\xa0\x3b\x38\x8a\xe9\x67\x8f\x79\xc2\x10\xca\xa1\x41\x9c\x9b\xb7\xb2\xca\xfe\x84\x9b\xd6\x44\xcc\x21\xc1\xad\x12\x91\x1a\x7b\xf1\x0e\x0e\xbf\xec\x9a\x53\x91\x60\x8c\xa9\x2e\xc4\x69\xf7\x56\x36\x37\xeb\x65\x58\x9c\x4a\x81\x20\x99\x53\xa6\xca\x53\xdd\x55\x64\x1f\xe0\xe7\xc0\xe2\x8e\x53\x65\xb5\x32\x73\x78\x05\xe4\x89\xe9\x1a\xc0\x92\xe5\x64\xfa\x60\xca\xea\x70\xae\xa1\x6a\xfd\xbe\xa1\xcc\xd0\x78\x91\xc5\x22\xb1\x15\x46\xfd\xf1\xa3\x0f\x4d\x57\xb1\xc2\x62\x99\x58\x7a\x1c\x79\xce\xdf\xbf\xe2\xac\x60\xb1\x14\x06\xeb\x56\x4f\x55\xf9\xf3\x72\xc8\xbc\x5b\x36\x80\x9d\xb2\x58\xc5\x01\xb8\x9d\x61\xb9\x5b\x6f\xba\x3f\x73\x8d\x5a\x99\xa7\x8f\xd3\x7f\x9f\xe1\x0c\x3d\x91\x25\x8b\x95\x4a\x91\xb3\x71\xa6\xf5\xdd\x7a\x3f\x60\xa1\x60\xb1\x0e\x12\xbf\xba\x77\x6f\xc2\xff\x40\x27\x29\xbe\x3f\x32\x22\xce\x3b\x11\x16\x16\x43\x60\xc1\x9f\x5b\x68\xaa\x0c\x3e\x60\xd1\x31\x53\x77\x83\x6a\x08\xc8\x41\x1d\x6f\xcf\x17\xf5\x57\x85\xaa\x7d\x44\x81\x04\x31\xd1\xc3\x2c\xfc\x03\x14\xc1\x28\xab\xe9\xfb\xb1\x90\xb9\xc3\xf2\x20\x45\x71\x9d\x24\x61\x24\x30\x52\xf9\x75\x6e\x01\x51\x1b\xa8\x1c\xda\x9f\x91\x30\xe8\x06\x73\x9e\x35\xf5\x70\x68\x48\x28\x69\x60\x49\xd7\x8b\x8e\xfb\x66\x72\xf1\x28\x20\x08\x92\x7c\xce\x3f\x6e\x26\x5d\x87\xbb\x11\x89\xa8\xc4\x8f\x7b\xb6\x79\xc0\x91\x05\x3c\x48\x90\x7f\x49\xdd\x3c\x6e\xf3\x17\x65\x29\x26\xb3\x71\x8b\x5c\x8a\xaa\x57\x54\x60\x24\x26\x80\xc7\x8f\x18\x5a\xf2\xbe\x1e\xc4\xf7\xd1\x16\xe4\x3f\x47\x51\xe0\xf9\xd9\x2f\x01\x42\x92\xd8\x72\x54\x20\xd7\xf4\x22\x07\x51\x21\xc3\x59\x36\xf5\xcd\x27\x25\x9c\x8c\x10\x2e\x46\xea\xfc\x96\x56\xf3\xa6\x4b\x40\x12\x1a\x23\xe4\x7e\xa0\x12\x3c\xf5\xf2\x08\x85\x08\x9f\x04\x63\x9c\xea\x6d\x20\x27\xea\x3b\x98\x18\x11\x5b\x99\x2a\xf1\x90\xf0\x85\x50\x6d\x8b\xc2\xd9\x7d\xb2\xc7\xf6\x53\xeb\x36\xdf\xb2\x4a\x08\x0b\x13\x4c\x97\x38\x6a\xa6\xd1\x23\xfb\x2e\x44\xa3\x17\x7c\x12\x97\x41\x2e\x81\x91\xd6\x16\x34\x2e\xfc\xbb\x83\x42\x2f\x06\xfc\x04\xff\x35\xb9\x04\x23\x71\xd2\x51\x09\xff\x28\xab\xf6\x44\xeb\x8e\x0d\xc2\x44\x82\xa5\xbf\xc2\x06\x34\xe6\xd9\xb8\xaa\x86\x11\x26\x2d\xd7\xad\x15\x3c\xc6\xf0\xca\x75\xda\x94\x91\x34\xb0\x15\x50\xda\x52\xe8\x56\xcd\xb8\xba\x8c\x91\x34\xb6\x04\xa2\x2f\x8e\x5d\x1b\x8e\xd9\xf9\x38\x02\x01\x4f\x86\x27\x95\x96\xb6\x7b\xfe\xf2\xc7\x72\x7b\x58\x7c\x5b\x2e\x7e\x3f\xec\xf6\xcb\xcd\xe4\xf9\x52\x9d\x62\x1d\xc7\xa3\xa8\x9b\xa5\x15\xeb\xf4\x67\x04\x11\x04\x68\x3c\x62\xc7\x45\xc6\xae\xf1\x7d\x24\xa3\x54\x74\x61\x8e\xf9\x2f\x38\x7b\xa6\x72\xbc\x8c\x28\xca\x64\x3c\x52\x19\xff\xfd\x8f\xc5\xae\x11\x53\x03\x99\x28\x96\x60\xce\x53\x97\x45\x63\xe1\xab\xfe\x19\x35\x8b\x41\xf9\x7c\xdc\xae\xa3\x73\xbd\xf2\x6b\x7c\x77\x10\xb8\x79\x60\x2c\x67\x97\xbd\x8e\x13\xb9\xb7\x30\x92\x57\x73\x1b\x38\x4d\x9c\x4b\xdc\x9d\x0a\x33\x14\x78\xbb\x8e\xb3\x12\x48\x25\x06\x2d\x4f\x9f\x5f\x38\x83\xc4\x10\x5b\x0c\xe2\xca\x06\x2d\x09\xb3\x7e\x12\xff\xdb\x13\x3d\x3b\x80\xc4\x60\x0b\x30\xd2\xa6\xd6\x70\xac\xbc\xcf\x3d\xb8\x6d\x6b\xb1\x71\x47\x09\x67\x73\xda\x93\xbc\xfe\xf8\x21\x92\x40\x88\x91\xc0\x19\x66\x70\xac\x32\xc2\x68\xfc\x92\x90\x26\xa8\x48\x57\x65\xaf\x6f\x4d\x14\x8d\xe7\x42\x12\xb2\x84\x7b\x9e\x11\x0b\x13\xb4\x5e\x4a\xcf\x1a\xce\x92\x50\x46\x38\x5f\xce\x05\xa2\x1b\x5b\xa7\xe5\x22\xf2\xe6\xd2\xb5\xab\x08\x0b\xc0\x9e\x66\x8b\xfe\x4f\x1a\xf5\x2d\xfb\x02\x19\x96\x44\x94\xe0\x71\x27\x20\x37\x1d\xc8\x0d\xbf\x6a\x9d\xbd\x76\x9d\x8c\xb6\xd2\x05\x96\xb3\xfb\x8b\x97\x8f\x43\x8a\x11\xfd\x45\x29\xb3\xe2\xad\x2c\xf5\x30\xde\x9f\x10\x63\x43\x7c\xb5\x23\x2b\x1c\xa0\x1c\x47\xff\xeb\xba\x27\x71\x80\x23\xef\xaa\xae\xbd\xaf\x7a\xf3\xc6\x89\x60\xb4\x57\x90\x45\x34\xfb\x78\x75\x26\x89\x48\xb9\xd7\xae\xf7\x61\xbc\x65\xa1\xaf\x65\x57\x58\x42\x49\x80\x6b\x49\xf9\x7e\x0b\x0c\xa1\x75\xab\x39\xa1\x54\x12\xe7\xd9\xcc\x27\xd8\x05\x96\x50\x99\x78\x73\xf0\xae\x2a\x4f\x43\x3e\x3c\x96\xb0\x48\x21\x57\x4e\x01\x9f\x57\x44\xbd\xe3\x87\x40\x5b\xd6\xd3\x48\x7d\x8a\x4a\xff\x10\xf5\x0e\x8a\xe9\xdd\xb8\x31\x98\xb6\x6f\x9b\x3a\xbc\xf6\x40\x07\x7b\x72\xd5\xd4\x21\xe5\x06\x55\xc6\x38\x02\xf5\x06\xaa\xdf\xb3\xce\xf2\x4f\x44\xc4\x12\xd9\x6b\x16\xea\xc7\xcd\xde\x37\x49\xae\x63\x35\x90\xd8\x01\xfd\x75\xd1\x19\x4b\x24\x08\xcc\xe8\x7e\x3b\x8b\xfd\xb9\xf4\xd7\x50\x4a\x22\x8f\x11\xe6\xef\x9c\xba\xcd\xf8\x73\x29\xc3\x10\x51\xd5\x3a\x0f\xaa\xcc\x0a\x0b\x16\xf1\xbf\xd7\x31\x41\x16\xbd\xd5\x62\x3d\xc1\x3f\xbb\x0e\x90\x68\x6e\x77\x96\xdc\xdc\x81\x25\xac\xf8\x05\x5d\x03\x4b\x40\x46\x24\xe8\x6b\x5b\x45\x9e\xef\x4e\x18\x1e\xbb\x32\x57\xfd\x0f\x54\x12\xb9\x91\xdc\x9d\x84\xba\x66\x49\x63\x89\x11\x09\x7a\x96\x3f\xcb\x6a\x8b\x3a\x8b\xd7\x90\x4d\xdf\x53\x72\xb4\xe4\x6c\x3a\xf0\xb3\x8b\xa3\x26\x46\x2b\x0b\x5f\xc6\x19\xd8\x85\x80\xc6\x37\xa2\x81\xb6\xdc\x99\x87\x8e\xa4\x1e\x3f\x6a\xbb\xa5\xb9\x71\x75\xa1\x70\xb7\xb4\x68\xc8\xac\x5c\x63\x56\x2f\xff\x73\xce\x4e\x5f\x80\x42\x18\x0d\xb9\xc0\x51\x79\x5c\x3d\xad\xf6\x87\xcd\x76\xfd\xe4\x88\x64\x18\x8d\x02\x7b\x9a\x67\x05\x6e\xb3\x87\xfc\xba\x60\x88\xd1\x88\x69\xd1\x41\x37\x5f\x8a\xbc\x3d\x64\x41\x5f\xa1\xa2\x18\x8d\x78\x8a\x2b\x6a\x1e\xcd\x9e\xef\x54\x6f\x15\xd0\x08\x42\xdc\x9e\x85\xb6\x10\xd8\xab\x23\x71\xb0\x97\xd3\x98\x49\x3c\xc1\x5c\x72\x7d\x0b\x42\x43\xe5\x41\x92\x37\x4f\x31\x4a\x92\x18\x99\xd6\xda\x65\x8e\xd6\x82\x57\x62\xf2\xed\xcc\xa0\x90\xaa\xcd\x7c\x76\xaa\x8c\x37\x57\x17\x25\xc0\x85\x35\x92\xaa\x66\x53\xd6\xdd\x35\x40\x3a\xd1\xca\x57\x97\xc7\xbf\x2f\xab\x8e\x7a\xf7\xf6\xa5\x92\x80\xe3\x46\x6d\x8d\x14\xab\xc4\x79\xd3\x65\xa4\x09\x09\x6d\x46\xf8\x94\x77\x8e\x22\x4d\x48\x8c\x05\xd4\x6f\xa2\x5e\x9f\x60\x60\x16\xd3\x84\x03\xda\x9c\xb2\xdd\x81\xef\xc0\x96\xa1\x74\x24\xde\x8c\x26\x92\x4a\x97\x18\xc3\x62\x45\x9c\xd7\xa3\xb5\x42\x13\xa0\x40\xba\x3a\x14\xeb\x0d\x77\x3f\x07\x85\x81\xa9\x3e\x6a\x2a\xc2\xf0\x9b\xa8\xdf\x0e\xee\xfd\x7c\x47\x4a\x13\x6b\xd7\xa2\xe4\xde\x9f\xae\xcc\xa3\x2f\xf1\x61\x94\xa6\x11\x9e\xa4\xba\x41\x46\x9b\xac\xb9\xec\x0a\x71\xaa\x5b\xb7\xf7\xf6\x6c\xa5\x4a\x7b\x7e\x02\xef\xb1\xf4\xd6\x30\xa5\xa0\x30\x1d\x6a\x59\x91\x20\x6f\x1c\xbe\xf7\x36\xf6\xc5\xfd\x88\x05\x12\x1d\x5b\x6b\xa1\xcf\xce\x83\x32\x9f\x6b\x13\x85\x32\x6e\xb4\x43\xec\x3d\xc3\x67\x27\xf1\xf2\x35\x44\x91\x51\x66\x34\xee\x8f\xbf\x6f\xff\xe8\xb6\x58\xca\x0c\x60\x15\x6d\x47\xad\x3c\xeb\x74\x5c\x18\xe5\x91\xc0\xe0\xde\xe2\x65\xfb\x7d\x79\x58\xbc\xec\xd7\xf7\xf7\x87\xbb\x97\xed\xac\xd7\xe7\x61\x94\xc7\x12\xf3\x25\xcb\xfd\xde\x43\x6d\x19\xe5\x24\x88\x1c\x0c\x7c\x53\x95\xfa\xac\xae\xac\xb5\x89\xd1\x36\x34\xd6\x28\x4f\xa3\x18\xf7\x8c\xd7\x22\xeb\x3f\x92\x88\x08\x96\x5a\x67\xf5\xde\xc5\xcf\xce\x3d\x83\x38\xa3\x42\x40\xe4\x23\xb6\x50\x65\x26\xeb\x10\xc7\x93\x59\x2c\xb9\x4a\x6c\x68\xba\xbd\x0a\x7a\x6b\xd3\x14\x19\x95\x9a\x21\x94\x40\x67\xb5\x90\x39\xac\xea\xfa\xdc\x17\xfe\x30\x2a\x4d\x84\xfa\xb7\xbb\xa6\xac\x8e\x37\x12\x0b\x54\xb6\xc7\xea\x00\x4e\xba\x11\xaf\x6e\x4b\xe6\xbf\x28\x39\x65\x54\x05\x06\x51\x3f\x8e\x2e\x30\xcf\x2c\x0b\xb7\x3d\x96\xc7\x7c\x7e\xfe\x17\x21\xf8\xa4\x13\x8a\xe4\x9d\x9a\xc7\x4c\xc8\x7c\x58\x3c\x30\x7e\x34\xc5\x89\x95\x01\x46\x36\x1a\x7b\xa6\x59\x4e\xaf\xc9\x85\xd3\x00\x6b\x3a\x8f\xce\x28\xf4\x2b\x62\xe5\x6d\x13\xaa\xc0\x2a\x7c\xa3\x13\xb7\x87\xe3\x29\x1f\x2c\x29\x65\x08\x12\xa9\xcc\xb3\x7d\x59\xf9\xd3\x98\xea\x88\x61\x5a\xe0\xe0\xd3\x33\x0e\x51\x74\x7b\x49\xe8\x38\xc1\xb4\xb1\x38\xeb\xac\x29\xdb\x95\x84\x31\x66\x7f\x31\xe0\x56\x7e\xc8\x69\x98\xb4\x9b\x12\x6a\x55\x1f\x87\x66\xfd\xed\x41\x80\x34\xe4\x16\xc8\xdd\x88\x7c\xf7\xde\x1f\x02\x86\x6b\x3c\x1e\x77\x7f\x3c\xcd\xd7\x8f\xdd\x5f\x53\x9b\xcd\xc0\xc7\xab\x9b\x6a\x32\x54\xc6\x80\x85\xcf\xa2\xdc\x5a\x56\xb4\x93\xb3\xe7\x83\x62\x2c\x08\x89\x5f\xac\x0f\xdf\x97\x9e\x5e\xe2\xff\xe3\x3f\xdd\x35\xad\x33\xa1\xcb\xcf\x22\x2f\x85\x46\x73\x7d\x98\x18\x65\x41\xa8\x30\xa8\x2b\x45\xa3\xde\x7a\x54\xe6\x35\x18\xcb\xf7\x17\x1c\xbd\xfb\x7b\x51\x09\x6d\x31\xf6\xbd\x45\xcd\x02\x95\xe2\x6e\xbb\xbf\x5b\x0e\x19\x36\x18\x0b\xa5\xa2\x4e\x56\x1a\x2a\x2b\xe6\xd8\x5b\xa1\x2c\x4a\x08\x72\x5b\xb9\x9b\xee\xcb\xdd\x59\x76\x64\xc5\x5f\x24\x47\x59\x44\x19\x08\x97\x35\xf4\xb4\xd3\x96\x4e\x68\x64\xc8\xfb\xde\x3c\x12\x72\xb0\xbd\x7b\x98\x82\x6b\x8e\x45\x6c\xec\x7c\xff\x39\xab\x6b\xcc\xbf\x7b\x5e\xf5\xbe\x8b\x44\x77\x3a\xab\x37\xdf\x37\x63\x0a\x6c\xc6\x62\xc5\xb0\xfe\x70\xff\xb4\xfb\xe3\xa6\x74\x84\xeb\x47\x02\x02\x1d\x41\x70\xeb\xdc\x94\x85\x27\x92\x18\x0f\x18\x49\x0c\x26\x9e\xe6\xe7\x61\x50\x82\x11\x0a\x56\x47\x5d\x4c\x18\x02\x19\x23\x29\x20\x98\xaf\x2a\xd5\x3b\x20\x4a\xf6\xa5\x68\xb2\xfc\xa9\x9c\xc2\x27\x58\x12\x48\xb4\x65\x71\x26\x2e\x9b\xb7\x07\x18\x4a\x33\x32\x96\xa4\x0a\xe9\x42\x3c\x9f\xb7\x7d\x32\xa7\x20\xe7\xfa\x50\x9e\xe0\x68\xe0\x99\xec\xd1\x01\x33\xf5\x25\x4c\x6d\x24\x47\xcf\x18\x0b\x52\xe4\xfd\x94\xe7\xcb\x01\x0a\xe4\xe9\x54\x65\x05\xb7\xab\x06\xf1\x1f\x07\xe7\xef\xfe\xcb\x5d\x88\x9b\x38\x72\x53\x67\x96\xbf\x4e\x2c\x5e\x96\x86\x41\x38\x28\x05\xfe\x51\x65\x37\x8a\xea\x7c\x5f\x41\xd1\x00\x38\x38\x9d\xb4\x2f\xd1\x76\x03\x0b\x8f\xa5\xc2\xb2\x24\xdd\x89\xf2\xc5\xa2\x38\x26\x96\x3f\x13\x41\x8a\xfb\x1f\x62\xfc\xb2\x62\x63\xe3\xb0\xd3\xd8\x25\x13\x24\x0d\x5c\xe5\xdf\x53\xd6\xa9\x6d\xdb\xa5\x3a\x7e\x27\x21\x02\xa1\x07\x51\x05\x0b\x43\xba\x75\x88\x31\x21\xb5\x77\xfd\x30\xa1\x65\xb5\xc7\x90\xf4\x71\x9c\x87\x0c\x53\xbf\x63\xc8\x90\xfb\x2a\x3d\x4f\x90\x3e\xdc\xa4\x24\x35\xd4\x59\x63\x8b\xed\x9b\xa8\xdf\xd6\x66\xb1\xf5\xa5\x93\xb7\xd7\xa9\x0a\x35\xc6\x15\xce\xc5\x7b\x51\x7e\x16\x3d\x6f\xf9\xa4\x1b\x61\x69\xe8\xd9\x40\x06\xa2\xcf\x6d\x8b\x41\x5d\x9a\x83\xe9\x4a\xd2\x2d\xf9\xa7\x6f\x17\x11\x26\xf3\x8f\xb6\x60\x66\x55\x6f\x86\xe9\x10\xa6\x69\x64\x3a\x3a\x13\xeb\x64\x1e\xba\x36\x41\xad\xf0\x45\x2e\xb2\xe3\xea\x78\x04\x9d\x79\x36\xb1\xe9\x58\x6a\xe5\xb8\x5f\xa0\xf9\x56\x96\xef\x5d\xe9\xe6\xed\x91\xd7\xc6\xe0\xfc\xfe\xdf\xf6\x93\x67\x79\x2e\x50\xc5\xd5\x45\x84\xc7\x63\xcf\x27\xe3\x05\xc4\x96\xfa\x63\x88\xfc\x0f\x71\x59\xd5\xcf\x65\xb3\xfe\x80\x6a\x97\xfd\x6c\x2e\x8e\xeb\xd9\xbf\x00\x70\xc9\x1d\x23\xab\xd5\x04\x1a\x52\x20\x30\x66\xa2\xd4\x1b\xcf\xf7\x00\x3f\xb2\x42\x97\x9f\xbf\x75\x6d\xc6\x73\x4a\x59\xcb\x61\x02\x45\xe9\xed\x48\x1e\x04\x80\x47\xac\x39\x17\xda\xb2\xac\xf9\x86\x28\x49\xa1\x93\x0a\xaf\x06\x52\xe1\x8c\x07\x9a\x53\xe6\xc5\x98\xda\x2d\x6c\x6c\xd3\x0d\x27\x8b\xdb\x15\x78\x98\x18\x8f\xb4\x5d\x15\xcd\x7d\x06\xb9\x8e\xfc\xe5\x22\x69\x6b\x06\x0f\xaa\x2c\x4c\x56\x1d\xc7\x03\xce\x89\x12\xb8\xb1\xde\x43\xd3\x23\x82\x38\xd1\xda\xea\x72\x80\xb0\xb0\xf2\xae\x76\x80\xf1\x24\x4a\x44\x38\x14\xfb\x9a\x5f\x50\xa9\x6b\x38\x80\x3c\x01\xc3\x9c\xd4\x2b\x56\x03\x1c\xba\x5f\x9b\x20\xee\xd6\xeb\x6b\x25\xd0\xd4\x1c\x0c\x19\x0d\xa4\x74\x78\xe8\x7d\x39\x0a\x16\x70\x1a\x01\x8a\x3a\x18\xff\x45\xe6\x43\x2a\x97\xd1\x64\x40\xf8\x01\x41\x95\x5c\x2b\x50\x73\xd8\x2e\x7f\xcc\xb6\x77\xdd\xa5\xa4\x4d\x62\x7c\xcb\xfe\x4e\x8d\x59\xdb\x1f\xb0\xbe\xf8\x69\xf6\x8f\xf5\xf6\xf0\x7d\xb9\xdd\xf5\x36\x3a\xa7\x4a\xf2\xbe\x92\xea\x11\x8e\x65\x61\x21\x2f\xdb\x1e\x1c\x70\xd7\xc7\xe9\x38\x0b\x14\xc6\x64\x5c\x25\xd5\xaf\xc0\xfa\x8c\x73\x2e\xd0\x15\x76\x25\xd2\x03\x20\xf2\xf8\x3b\xa6\x11\xb7\x40\xe4\x76\xfb\x3b\x84\x87\xe1\x17\x4b\x53\x8d\xb3\xed\x20\xcf\x17\x7b\x76\xee\xf7\x4f\x5f\x56\xb8\x8c\xaf\x2b\x98\xc5\xeb\xc3\xcf\xa6\x12\x4b\x97\x25\x1b\x6f\x41\x5c\x30\xcb\xde\xef\x82\x76\x28\x72\x35\x22\x38\xbd\xe9\x88\x70\x45\x25\xee\x0c\xba\x53\x7c\xbd\x99\x89\xe1\x4a\xa5\xaa\xd3\x9c\x79\x87\xe2\x19\x7e\xda\x82\xe9\xc9\x63\xe8\xd0\xe6\x03\xec\x7e\xb6\x59\xdd\x4d\xdb\x13\x82\xc4\xa1\xee\x50\x7b\x86\xcf\xd6\x9a\xf4\x8f\xea\x3b\xe9\x00\x73\x04\x4f\xe5\x47\x06\x5f\x72\xb8\x31\x0e\x24\xc2\x13\xd2\xab\xea\x7d\xb7\x9a\x7a\x23\x1a\x25\xc6\x41\xc7\x91\x15\x43\x79\x6d\xd7\xc8\x0f\x8b\xd8\x98\xac\xe4\xf1\x80\x1b\x11\x62\x8a\x15\xfd\xec\x7d\xb9\xdb\xdc\xed\xa6\x26\x31\x37\xc2\x1e\x0d\xdf\xfe\xe9\x03\xc2\xdc\x80\x95\x34\xaf\x1b\x9f\xb5\xe6\xbd\xb6\xed\x7f\x9d\x07\x45\xfc\x2c\x0d\x62\xce\xec\xea\xfe\x18\xd6\xe2\xb0\x34\xe0\x26\xe8\x39\xad\x87\xca\xac\xbe\x43\xca\x8d\x3b\x18\x97\x96\x45\x75\x2c\x44\xec\xba\xc5\x49\x8a\xba\x08\xfb\xb7\x0a\x60\xe6\xdd\xe1\xf6\xcf\xd4\xb3\xa8\x8b\xe2\x6a\xe6\xfb\x5e\x46\xa2\x40\xcc\x87\xc8\x3b\xbd\x0d\x96\x12\x1e\x20\xaf\xce\x00\xc5\x15\xa6\x37\xe2\x11\x29\x01\x86\x15\x92\x42\x6b\xe4\xe8\x50\x60\xb9\x40\xc6\x43\x40\x40\x26\x2e\xea\x87\x21\xec\x9e\xab\x8b\xa5\x34\x06\xee\xb9\xfe\x9e\xe1\xd3\xa2\x45\x6c\xa1\xf2\xaa\xfe\x13\x3a\x7f\x2b\xa5\x14\x30\x67\xe6\x2d\x8a\xd3\x79\x52\x6f\x30\x70\x29\x52\x9a\xda\x00\x98\xb2\x0e\xdf\x1c\xb9\x50\xba\x2b\x41\x80\xf6\x7f\xa7\xa2\x80\x8a\xf9\xd6\xbb\xf5\x7a\x40\xe3\x51\x62\x61\x80\x89\x72\x5c\x97\x13\x31\xa9\xdb\xe3\xca\x84\x72\xa2\x2a\x7a\x07\x79\x9e\x15\xaf\xab\x06\x8e\xbf\xac\xfc\x61\x29\x93\x34\xb4\x85\x51\x5d\xf2\x78\x23\xa6\x81\xf6\x94\x19\x86\xf0\x3c\x24\xd1\x5e\x3d\x3c\x1f\xf6\x7f\x6c\x96\x77\x87\xbb\xd9\x7e\x76\x98\x6d\x1f\xbe\xcd\x76\xdf\xfc\x9b\xf2\x50\x6a\x2b\x6d\xa5\x7b\x09\x71\x96\xf2\xc8\xd2\xf7\x09\xad\xb7\xa0\xb2\x53\x36\xf4\x32\xc7\x37\xe3\x4c\x20\x95\x9a\x97\x7e\x7d\x12\x3f\xf1\x8c\xf6\x64\xba\xdd\x25\x85\x54\xe0\x2a\x04\x1e\x4b\xf5\x3e\x88\xbd\xa4\x69\x98\x60\xdb\xfb\xfb\x1e\xea\x66\xb5\x58\xa7\x61\xd7\x14\xd9\x88\x33\x74\xc6\x5b\x9a\xd2\x10\x93\x7e\xad\x51\x82\x38\xde\x69\x44\x23\x15\x91\xe4\xce\xc8\x41\xf8\xf1\x53\x76\x2d\xdd\xea\xbb\xc6\x0a\xe1\xa3\x2e\x1b\x72\x67\x63\x20\xfe\x56\x22\x65\xc6\xe6\xee\x76\xa7\xd6\x41\xf8\xb9\x11\x97\xd6\xe3\xbe\x2f\xab\xa7\xc5\x8f\x71\xfc\x2e\x15\x4a\xe8\xb8\xdf\xd0\x3a\x0b\x71\x55\xcc\xcf\xf9\xfb\x14\x96\x91\xca\x28\x02\x2c\x16\x81\x66\x5d\xcc\x90\x88\x74\xfc\x16\xca\x08\xb0\xd2\x4b\x8f\x37\x2a\x31\x6f\x19\x5d\xa9\x0e\x04\x1a\x5d\x4a\xe4\xf9\xae\x3c\xc2\xfd\xb9\xc0\x0d\xe3\x7b\x26\x56\x45\x01\x55\x37\xac\x9a\x52\xde\x73\x4e\xe2\xe5\xaf\x24\x97\x59\xaa\x95\x41\x5f\x02\x44\x95\x67\xed\xce\xda\xfa\x39\x4d\x7f\x94\xa5\x10\x49\xa7\xe2\xfa\x98\xd5\xcd\xec\xcb\xc2\x9c\x14\x44\x8a\x68\xbe\xef\xa5\x8b\xf2\x74\x57\x90\x9a\x19\x8f\x4a\xc5\x63\x04\xe1\x47\x5d\xb3\x4e\xc9\x20\x61\x32\xde\xcf\x53\x93\x44\xbc\xa7\xb5\x76\xbe\xf0\xb0\xd2\x20\x35\x8a\x05\xbe\xdc\x7f\x2e\x6a\xd8\x35\x1e\x98\xf8\x52\x67\xc5\xab\x55\xf9\x74\x12\xf0\x7d\x2e\x5b\x04\xa1\x0d\x2d\x63\xf6\xf2\x49\xa8\xb7\xcc\xeb\x7a\x30\x11\x50\xe1\x35\xda\xda\x85\x0b\xd5\xc3\x59\x54\xa2\x68\x00\x7e\x1b\x82\x79\x7d\x6f\x16\x22\xd5\xf9\x5d\x59\x0c\x39\x52\x98\x08\x38\x41\x05\xe0\xd9\x6a\x7b\xb7\x5d\x6f\x0e\x48\xf8\x76\xe8\x76\x67\x11\xc8\x08\xe3\x28\x4e\xac\x1a\xf2\x72\xf9\xb3\x81\xa2\x1e\x42\xa7\xc7\xc6\xa3\x08\x00\x10\x1d\x7e\x14\x3f\x9b\xe1\x41\x22\x02\x23\x3c\xb4\x0f\x73\xad\x5d\x80\xa4\xdd\x1d\x07\x7e\xa0\x88\x28\xc7\xda\x5b\x8b\x96\xf7\xd5\xf6\x23\xac\x72\x6f\x1c\x8a\x38\xb6\x39\x5c\x74\x49\x3a\x16\x42\x27\xc7\xc3\x44\x4c\x12\xe6\x61\xdf\xa3\x62\x8a\xf1\x08\x91\x00\x10\xbb\x77\xb4\x10\x09\x16\x85\x7f\x67\xff\x14\x44\x11\x24\x54\xe8\xf6\xe8\x9d\xc8\xc1\x65\xde\x6f\x6d\xa2\x93\xa5\x22\xa8\x08\x50\x39\x4c\x0a\xf5\xbe\xae\x00\x19\xb2\x86\x45\x15\x82\x91\x00\x27\xd7\xfc\x7c\x79\x84\x0f\x4f\xf2\xcb\x04\x03\x85\xbc\x19\xad\x17\x71\x40\xd5\xef\xff\x13\xc7\x1a\x13\x3c\x60\xb8\x3b\x0d\xe2\xc5\xc3\x25\xed\x7b\xc9\x98\x38\xad\x9a\x02\xc6\xe2\xbb\xb7\x2f\x9b\x86\xa9\xec\x73\xb5\xed\x71\xd5\x1f\x7d\xff\x13\xd2\x7f\xff\xdd\x9a\x69\x7f\x39\x61\xf1\x7d\x38\x05\x10\xac\xd6\x4d\x27\x41\xac\x1e\xd8\x53\xd6\xbc\x55\x59\x3e\xab\xaa\xf2\xb3\x6f\xd4\x29\xb2\x46\x8b\x23\x74\x42\xdb\xf5\x74\xf3\x13\x92\x82\x72\xfe\xf9\xda\x18\x68\xdf\x7e\x7e\xe9\x90\x9a\x37\x9c\x2a\x21\x85\x74\x3e\x5a\xbb\x57\x21\x76\x73\x18\x69\x12\x2a\xa1\x58\x6c\x71\x3a\xd7\x6f\xce\x05\xfc\x02\x2b\x31\xb8\xa8\x4a\x2d\x21\xb1\xdb\xb2\xbb\xa2\x95\xd6\x92\x19\x40\x0b\xfe\xe6\x87\xd5\xcc\xa2\x00\xac\xf0\x6f\xf9\x09\x2e\x8a\x3d\xbf\xf4\x34\xd3\x4c\xe8\xd4\x19\x17\x9e\xb9\x74\x2a\xc3\x7e\x7b\xbe\x6b\x45\xb8\xaf\x8c\x8a\xc7\xfb\xb4\x80\x88\xa0\xc3\x79\x7f\xb6\x44\x26\xee\xe4\xbd\x7d\x21\x48\x49\xd4\x15\x79\xfa\x43\xea\x16\x17\x00\x13\x00\x22\x24\xdd\x29\xf1\x90\x97\x52\xe4\x56\xa8\x40\x64\x83\x7d\xe1\x56\x1c\x4a\x98\x28\x44\x88\x9c\x4d\xb1\x4e\x48\x8f\x99\x30\xd4\x2a\x6e\x3c\x40\x33\xcf\x7c\xe4\xd3\x6d\x38\x18\x8c\xbb\x09\xbe\x95\x41\xaa\xb1\x42\xff\x35\xfb\x00\x2f\xdd\x7b\xbe\x56\x8b\x75\xbd\x43\x12\x78\x64\xc4\xf9\x2f\xd5\x5b\x6e\xef\x16\xbf\xfe\xe4\x32\xe4\x1c\x33\x12\xe7\x62\x33\x48\xd7\xc9\x28\x32\x22\x1a\xc1\x4c\xe6\x3d\x6d\x74\x9f\x3c\x93\x11\x0f\x70\x8b\x3c\x96\x39\xb4\xbb\x58\xd5\x80\x7a\x2b\xca\xbc\xf4\x9c\xcd\x4c\x46\x82\x49\xe8\x78\x8a\x47\xb0\x07\x49\x22\xed\xeb\x3f\x0e\xa7\xf6\xec\x3c\x88\x42\x1f\x6a\xb8\xd6\xb5\xf2\x3f\x88\x05\x26\x2a\x3c\xe9\x3d\x2a\x6d\xaf\xb7\x83\x14\x97\x24\xad\x47\xec\x80\xdd\xa8\x7b\xef\xd7\xa7\x23\x5e\x1a\x7d\x65\x49\x64\x60\xfd\x5c\xcf\x6c\xd4\x9a\x5b\x37\xe4\x0b\x98\x24\x06\xd0\x73\xb6\x41\x8a\x51\xc5\xaa\x4c\x62\x82\xe0\x3e\x03\x50\xef\xc5\xb0\x81\x04\x18\xa6\xc7\x48\x4a\x3b\x53\x5b\xe3\xcb\x8d\xe8\xb5\xd2\x2f\x93\x09\xe3\x48\x08\xf3\x98\x7d\xc0\x20\xde\x2c\x69\x1c\x44\x30\xbc\x4e\x59\x8d\x95\xf7\xbf\x98\x40\x2c\x89\x46\xd4\xe0\x79\xbd\xc4\xfa\x20\x6f\x28\x4b\xc6\x04\x2e\x26\x5b\x26\x53\x94\x1a\xbc\x9f\xf0\x55\xf2\x5f\xf2\x28\xd2\x0e\x31\x73\xb7\xc4\x5c\xcf\x15\x97\x76\x7f\xc6\x4a\x9e\x8a\x18\x06\x0a\xaf\x8b\xb2\x8f\xe5\x4b\x2e\xa8\x47\x0f\xce\x72\xab\xd9\x3f\x45\xed\x0f\x4e\x77\xc9\x01\xa4\x2b\x30\xf9\xf1\x76\x05\x16\x90\x69\x64\x10\xb5\x69\x75\x18\x46\x1f\x28\x4d\x74\xec\x13\x6f\xcf\x0f\x0b\x91\xe7\xed\xb1\x39\x65\x81\x65\x52\x70\x9e\x22\xf8\x0a\x8b\x1e\xbf\x8a\x69\xf8\xce\x5a\x60\xbd\x94\xed\xbc\x78\x2b\x33\x05\xf7\x55\x79\x6c\x90\x04\x1f\x55\x68\x5c\x4f\xa9\x43\x15\x76\x51\x65\x5b\xd2\x3c\x2a\x5f\x72\xfd\x54\x14\xa0\x2f\xe2\x0a\x90\xbd\xd6\xf3\xb8\x44\xee\x26\x50\x45\xaa\x38\xc5\x95\x51\x7e\x4e\x43\xa6\x52\x47\x31\x46\xdf\x1e\xcb\xf2\x7d\x36\xa6\x45\x64\x2a\x08\x78\x22\x07\x9c\xfa\xed\xab\xac\xab\xd7\xd9\x66\xf5\x3b\x5c\x46\x41\x38\x15\x04\x36\x69\xeb\x70\xa3\x3f\x20\x1b\x15\x1b\xa9\x80\x11\x5f\xb1\x64\x59\xef\x44\x7e\x75\x70\xaa\xc0\x10\x45\x87\x66\x0f\xb2\x15\x76\x97\x30\x82\x58\x9a\x62\x44\x8f\x2c\xca\xaa\x02\xe5\x73\xa5\xe3\xc1\x52\x91\x8c\xb9\xea\xf4\x4c\xeb\x43\xde\xd1\x9f\x33\x15\xd3\x00\x7d\x13\x03\x70\xb0\x20\xb8\xaa\x6b\xe2\x81\xb5\x0b\x5c\x74\xe9\x62\x0b\x1f\x6f\x9d\x90\x7c\xc0\x48\x9d\xfc\x7b\x40\x88\x40\xff\x7d\xc5\xae\x36\x08\x8f\x0c\xff\x9f\xbf\xa9\xb4\xe1\x9d\xe5\xf3\xe2\xf7\xbf\x47\x44\xc5\x54\x0c\x36\x51\x99\x1d\x8f\x65\xd5\x20\x57\xa5\x7f\x07\x12\x09\x54\x2b\x28\x0b\xa4\x76\x59\x69\x28\x9a\xac\xc9\x26\x2a\xbf\x4c\x11\x2a\x58\x47\xb9\xff\x56\xd6\xc3\x42\x50\x95\x70\x1b\xb4\xfc\x84\xcc\x17\x39\x75\x4d\x86\xc8\x8e\x28\x1d\x56\x8b\xf5\x80\x07\x89\x29\x1a\x72\x15\x76\x3b\xfa\x70\x9d\x29\xca\x8d\xb1\x75\x77\x9e\x68\x68\x3d\x98\x6b\x3c\x22\x48\x4e\xb1\x28\x8f\x32\x2b\xa0\xc3\x04\xfb\x49\xac\xb8\x08\x30\xf9\x60\xca\xca\xd7\x14\x75\x2d\x06\xf5\x34\x34\xd4\x4d\x55\x5e\x86\xa1\x06\xdf\x43\x53\x5c\xfd\x8d\x98\x54\x62\xa9\xd4\x9d\x40\xc8\x73\x01\x55\x83\x67\xd8\x84\x7b\xbc\xeb\x6a\xcf\xbd\x8e\x8f\xe8\x01\x9a\x99\xfe\x18\x32\x7a\x30\x95\x9a\xd0\x67\x88\x37\x65\xf1\x67\x86\x5e\x5f\x76\x9d\x22\x52\xa9\x61\x38\x9b\x1d\x4d\x9b\x1a\xaa\x79\xdf\xdc\x5b\x95\x90\xdc\xf3\xec\x6f\xcf\xf9\x84\xc0\x40\xc9\x84\x05\x29\x8e\x5f\x56\x58\x01\xc0\x97\x42\xe4\x8d\x25\xe5\x59\x15\x0d\xbc\xf6\x9f\x50\x32\x8e\xe4\x02\xe8\xdb\x74\xa4\xd5\xbe\x91\x03\xf5\xaa\xd4\xab\xee\xbd\xa4\x92\x7c\xc8\xf4\xde\xd9\x3c\xeb\xfa\x0d\x2a\xbc\xa9\xef\xaa\xb8\x42\xc2\xe4\xa7\x52\xee\xfe\x73\x16\xba\x8e\xfa\x16\x5b\x96\x58\xc8\xb9\x50\xef\x80\xf9\x96\xa7\xb2\x82\x75\xb5\xfc\xcf\x59\xe4\xfb\x7e\xae\x68\x43\xb0\xfe\x62\xb9\xff\xb6\xdc\x2e\x5f\x7c\x4d\xaf\x82\x28\x91\x36\x06\x50\xe9\x59\xa1\x17\xad\x99\x97\x67\x75\xb3\xd2\xf5\x7d\x59\xdd\x28\x52\x53\x40\x08\x4b\xbd\x6c\x91\x03\xaa\xde\xcc\x07\x29\x13\x08\x4c\x36\x58\xa7\xf4\x29\x2b\xe6\x53\x9c\xb8\x32\xa9\xb0\x72\x65\x96\x5e\x61\xba\x2f\xdc\xb2\xea\x94\xd1\x69\x10\x79\x3b\x53\xe4\xf3\x5c\xa8\xf7\xc7\x2b\x6c\xa0\x0e\x38\xa0\x99\xdb\x97\xc3\x38\x13\xd0\x79\x02\x37\x8f\x19\x1d\x40\x40\xa4\x4f\x10\x4d\x63\x82\xae\x0f\x51\xac\xab\xd8\xe8\x4b\x2f\x91\x13\xd2\x7f\x33\x9d\x84\x5c\x26\x36\x26\x50\x75\x32\xf0\xe3\x90\xcc\xf0\xa5\x74\x02\x04\x23\x57\x43\x85\xf9\xaf\xf0\x08\x9a\x6a\x89\x79\x9f\x17\x5f\x43\x6f\x3d\xa1\xee\xe6\x8c\x30\x84\x16\xd4\xe7\xa3\x35\x01\x07\xac\xff\xae\x0b\x27\x21\x32\x0c\x3f\xfd\xb1\x5d\xde\xfd\xf5\xfe\xa8\x39\x0b\xb1\x1c\xe6\xf9\xac\x72\x38\xd7\xdf\xb3\x3a\x2b\x0b\xa7\x74\x68\x8d\xa3\xa7\xac\xf8\x8a\xd8\x8a\x69\xae\x38\xa6\xec\x64\x05\x80\x4e\x07\x56\xcc\xdd\x34\x3b\x75\x1a\x58\x11\xe7\xa3\x8d\xa1\x9f\x40\x65\x22\x1f\xda\xed\xbe\x5f\xa8\x90\xba\x4a\x38\xba\x0a\xf7\x79\x1d\x15\xc2\x28\x38\xae\x53\x96\x30\xc7\x27\x32\xca\x3e\x4c\x6f\xcd\xb8\xe8\xc1\xeb\xcb\xa2\xa9\x2e\x03\x18\xaf\xef\x24\x12\x9c\x58\xf3\x46\x0d\xb7\x63\x2d\xb4\xf1\xa4\xcd\xf3\x73\x55\xdc\x97\xd5\xf1\x9c\x8b\xc9\x43\x0b\x97\x5b\x43\xdb\x52\xc3\xcf\xb9\x68\xd4\xdb\xfc\xf2\x52\x43\x55\xb4\x53\xc4\x69\x6a\x77\xdf\x49\xb2\x98\x38\x50\xaa\x73\x3b\x7f\x49\xcc\xe8\x31\x5f\x5a\x8a\x50\x2b\xd4\x0f\xcc\xf3\xcc\x5c\x7c\xe8\x60\xb4\xc5\x69\x15\x10\xab\xdc\xec\x9c\x4a\x47\xc2\xf1\x57\x9c\x1e\x5a\xa5\x41\xda\xeb\x50\x3d\xc3\xa7\xf5\xc1\x26\x44\xca\x37\x71\x6c\xe3\x59\xa5\x23\x40\xfc\xee\x7c\xf6\x70\xd8\x6f\x67\xcf\xbb\xfb\xe5\xf6\xf0\xb4\x7a\x5e\x3d\xbd\x3c\x1d\x66\x4f\xeb\x97\xe7\xfd\x61\x7d\x7f\x98\xbf\xfc\xe1\x59\x73\xb4\x36\x12\x17\xe8\x11\xf2\x61\x39\xad\x6f\x06\x65\x10\x9e\x26\xdb\x5d\x01\xcb\x05\x3e\xb3\xa6\xe3\x95\xd1\x60\x00\xcd\x98\x53\xa6\xde\xf7\x6f\x60\xcf\x25\xdf\x68\xb8\x41\xf7\xe4\xc3\x82\xe8\xee\xdb\xcd\x1c\xaa\x71\x14\x11\x02\xa9\x10\xe0\xb6\x58\x3f\xae\xb7\x87\xc5\xcb\x6e\xbf\x7e\xea\xda\x80\x91\xb8\xf3\x80\xef\xad\x88\x1f\xf2\xa4\x3c\x0e\x92\x85\xae\x73\x14\x53\x66\xe5\x5c\x9b\x59\xe3\x76\xa8\x2f\x0a\xa5\x21\x8a\x19\x62\xaf\xdc\x39\x7d\x55\xd2\x0a\x11\x37\x18\x7e\xfa\xf4\x66\xe2\xcc\x34\x50\xdd\x65\xb5\xc5\xe0\x96\x58\x87\xee\xfb\x82\xc6\xf3\xe8\xb8\x2e\xfe\x5e\x34\x01\x22\x63\x53\x4b\xe7\xda\x1e\x31\x36\x62\x30\x21\xa6\x63\x10\xab\x80\xfa\xa7\x6c\xb2\x57\xf0\x2c\xfb\x0c\x62\x13\x60\x0c\x68\xf3\x32\x7f\x5c\x2d\x50\xb2\x66\x77\x88\x0e\xdb\xd9\xde\xe3\x22\x81\x44\x14\x0f\x63\xc7\x34\x54\x9d\x6b\x9b\x67\x1a\x3f\x09\x49\x39\xaa\xa4\xdb\x24\xd7\xa6\x2a\x4b\x33\xa9\x62\x1b\xd5\xab\x4d\x4d\x43\x20\x82\x08\x0b\xc9\xad\xf4\x42\x9c\x36\x15\x0c\x6a\xbe\x21\x09\x22\x2c\xc1\xfa\x36\x7b\x1c\xae\x6c\x48\xd2\x04\xe9\xb5\x0e\x96\xac\xed\x28\x32\x87\x3b\xf4\x1d\xa8\x30\x08\x0c\x3a\xbc\x42\x33\x0c\x0b\x02\x23\x80\x2e\xa9\x23\xea\xf4\xb2\x13\xd3\xa5\x3b\x5c\x14\xc0\x18\x10\xd2\xfb\x25\x4f\x97\xef\x43\x52\x23\xdf\x89\x03\xce\x08\x3b\x10\x77\x20\xf2\x1b\x5a\xae\x0c\xda\xb3\x02\x75\xd7\xca\x5a\x75\x41\x25\xe0\x41\x82\x49\x6f\x4b\x5f\xd1\x6e\xc5\x5b\xb0\x05\x5d\x93\xe1\xe6\xb1\x40\x0f\xd9\xde\xe5\x4a\x1c\x97\x41\x9a\xc4\xb4\x67\x85\x7e\x38\x3f\x89\xfa\xfd\x6a\x12\x4f\x66\x53\xca\x35\x56\xb3\xff\xb1\x7c\x7c\x5c\xff\x78\x9c\x3d\xcd\x3d\xc0\x0a\x04\x13\x1e\x60\x30\x0c\xda\x8d\x7f\x2f\x74\x90\x46\x1d\x53\x71\x56\x8c\xa2\x1c\x20\x40\x11\xd3\xad\xc1\x71\x21\xd3\xf8\x3a\x92\x04\xa1\x13\xc0\xf2\x78\xd8\xf9\x65\x59\xe8\x53\x99\x4d\x99\x4d\xfd\x2f\x54\x9c\x5a\xc4\x7e\x07\xfe\xb2\x91\xbb\xbf\x58\x3f\x2a\x8a\x70\xfe\x74\x75\xc7\x7a\x5f\xde\x55\xc2\xa3\x52\x40\x45\xc6\xc2\xf8\xeb\xc9\x76\x06\x8a\xc9\xa4\xd7\x5a\x3d\x14\xf0\x79\xd0\xe0\x94\x12\x27\xd5\xf6\x7e\x57\x07\xa5\x08\x6e\xaa\xed\xf9\x89\xb2\x7f\xe3\xba\xd1\xc9\xb3\x69\x1a\xc4\xe1\x40\x1d\xdb\x43\xe2\x87\x64\x25\xa0\x59\xa8\x03\xac\x52\x36\x0d\x09\x26\xdf\x43\x4b\x89\xe8\xe3\x02\x7e\x36\x8f\xe2\xd4\xa1\x60\x01\x92\x00\xa3\x11\xa0\xb3\xc6\x6a\xd5\xdd\xc8\xfc\x83\xd1\x21\x12\x81\xab\xb1\x09\xf8\x17\x25\x6c\xff\xd7\x7f\xc7\x7b\xaf\xd1\x24\xf0\x55\x4d\xf5\xaa\x99\x86\x06\x4c\x10\x27\x48\x4c\xb1\x14\xf5\xc5\x45\x77\x07\x01\x22\x13\x26\x71\xd0\xce\xfa\xd9\x76\x71\x77\xb8\x7f\x79\xbe\xeb\x1a\x52\xab\x09\x62\xf5\x5b\x6d\x86\xa9\x76\xa7\xea\xc4\x2d\x30\x51\x14\x22\xaa\xbd\x3c\x41\x6b\x18\x5b\xc5\x14\xdf\xc6\x2c\x73\xcf\xec\x7e\x3f\xbc\x6f\x1c\xa5\xf8\x58\xaa\x3c\x9e\xce\x0e\xb2\xd5\xee\xc7\x7d\x21\x57\xff\x0a\x71\xac\x10\xa0\xb1\xa8\xb2\x53\xeb\xcf\x0a\xbb\x63\xd5\xdd\xb5\xb8\xd5\x20\x46\x46\x4d\xa8\x6e\xd8\xb9\x26\x16\x1a\x6f\x77\x9f\xfd\x9c\x43\x93\x84\xdd\x4f\xb5\x40\x11\x52\xab\x71\xeb\xe8\x2c\xba\x94\x97\x21\x32\xd5\x9e\x51\x6e\x59\xe8\xee\x67\x49\x60\x6c\x19\xcd\xdb\xb9\x78\xaf\x3d\xd7\x80\xa5\x90\xf4\x5d\x38\xc7\x0a\xb2\xae\xec\x1c\x76\xe4\x7e\x39\x79\xac\x24\x25\x2e\x76\x6f\xa3\x71\xcb\x9f\x59\xdd\xc0\x14\xfe\x6d\x92\x54\x62\x8d\xc5\x63\xf9\xea\xd9\x4e\x3c\xfa\xfd\xe6\x72\x75\x51\x7e\x43\xb5\x85\x24\x3f\x54\x00\xc5\x52\x54\xcd\xdb\x52\x95\x45\x79\xbc\xdc\xf7\x64\x24\x86\x11\x89\x88\x41\x95\x97\x35\x7c\x2f\xab\xbe\xb6\xc3\xb0\x34\x4c\xb4\xaf\x3f\xf8\xe9\xa0\x7b\x30\x52\x88\x62\x86\xc7\x56\xc7\xf5\x64\xed\xb2\xd0\x86\x61\x7d\x23\xb3\x21\x24\x57\xa7\xb2\xa9\xca\x9f\x5f\x40\xd6\x0d\x17\x02\x91\x23\xbb\xb3\x2e\x7d\xb0\xb1\x8f\x07\x9a\x54\x49\x9c\x47\x9f\x95\x38\x9d\xae\x12\x97\x46\xe8\x14\x13\xd6\xb6\xbe\xc5\x16\xaa\x8e\x07\x51\x06\xcc\x13\x95\xbb\x40\xea\x00\x6c\x61\x24\xe1\xc8\x84\xd0\x63\x14\x7f\x3c\xf5\xf4\x6e\x46\x85\x52\x53\x8c\x1f\xaf\x9f\x5a\xbf\xf3\x65\x77\xd8\x7d\x5b\x6d\x86\xd4\xe3\xcc\x28\xc6\xd0\x33\xd8\x89\xd6\x91\xf4\x8c\x77\xe3\xb7\x54\x5c\x60\xa4\xe2\x4d\x7c\xc0\xee\x0d\xf2\x91\x1e\x1a\x33\x4a\x10\xe3\x13\xf8\x00\x37\xed\x6e\xa3\x04\xd7\xb1\x63\x62\xb5\x91\xea\xc1\xc1\x6f\x14\xd8\x6f\x5e\x21\x8b\xf0\x41\xf4\x68\x03\xa3\x23\x40\x3a\xc6\xd1\x42\xd4\xb1\x0e\xc2\xfe\x88\x5e\x88\x4a\x96\xc5\x5d\x99\xe7\x62\xba\x93\x40\x64\x01\xca\x05\x20\xe2\xad\xfd\x42\xeb\x13\x14\x0e\x19\xf0\xa5\x2d\x7f\xc3\x58\x36\x10\x13\x34\x18\xad\x6c\xd0\xf2\x3f\xbf\x4d\x32\xac\x06\xa8\x89\x11\xb1\x98\x49\x0f\x73\x31\x00\xd2\xea\x1b\x1d\xa1\xd0\xe8\xd0\xfc\x36\xb1\x8d\x6e\xff\x1b\xba\xf6\x70\xfc\x9f\xd3\x48\xa8\x31\x49\x00\x91\x77\x21\x2c\xde\xe8\x30\x60\x5d\x67\xc6\x08\x81\x21\xcf\x25\xc2\xaa\x67\xdd\x9f\xa5\x45\x6a\x08\xcb\xa3\xe4\xc1\x76\x5d\xb3\x8a\xd1\x46\x05\x5b\xc2\xbd\x3d\xe7\x59\xf1\x3a\x1f\x8d\x2d\x0f\x42\x46\x85\xec\x08\xaa\x91\x7e\xed\xe6\x21\xc7\x83\x90\x0b\x8c\x59\x9c\x2a\x38\xdd\x90\xb9\xf2\xbd\x8c\x5d\x4c\x07\x63\x6b\x4d\xef\x32\x0f\x2d\xe3\x41\x14\xb0\xc4\xf4\xb1\x52\xbd\x2c\x74\xf9\x79\xec\x40\xa9\x3c\x88\x88\x0e\xdd\x4a\x79\x82\xa3\x84\xca\x8b\x60\x8d\x9f\x24\x8e\x6d\xf2\x6d\x58\x13\xd9\x1d\x0a\x3c\x88\x25\x20\x6e\xd7\x94\x95\x02\xbb\x2c\x7d\xec\x6c\x1c\xdb\xe5\x41\x6c\x52\xab\xaf\xec\x4d\x91\x97\xfd\xda\x26\xf2\x93\xab\xbe\x09\x97\xe8\xbd\x1f\x16\xdb\xf5\x8f\x3b\x4c\xe6\x6c\x66\x2f\xbb\xe5\x9d\xbf\x6f\x22\x63\xb4\xf0\xb1\x89\xfc\x58\x2e\x7f\x3f\x20\x09\x91\x6f\xa7\x09\x68\xea\xc5\x7f\xcb\x13\x02\xab\xe7\xd0\xf4\x54\xa1\x3c\xe0\xb1\xc4\xaf\x51\x67\x47\x0c\x35\xdf\xca\x2d\x8e\xc7\x9b\x27\x0a\xf3\x25\x67\xbf\xfd\xbc\x43\xd5\xda\xfc\xd3\x0d\x80\x07\x29\x4b\x35\xf5\xd4\x95\xbb\x9e\xba\x72\x3c\xb6\xa9\xb2\xbc\x3f\x0e\x13\xbd\x2f\xef\xaf\x68\xd9\x78\x20\x4c\x8a\xcc\xa2\x18\xaa\xb3\x18\xb7\x81\xfd\xc8\x03\x19\x27\xb4\xaf\xab\x9b\x6a\x04\x8d\x92\x02\xff\x13\xfd\xbb\xfb\x91\x32\xc2\x67\x49\x51\xca\xe5\xf3\x2d\x7b\x7d\x1b\x10\x70\xf1\x40\xca\x08\x4b\xdf\x50\x69\xac\x7d\xdf\xb3\xdc\x0e\xa1\x10\x5d\x37\x40\xc7\x1d\x3a\xae\xc0\x9b\x3e\x21\x0f\x34\x05\xa4\x8f\x7d\xd8\x7c\x1b\x38\x2b\x3c\xd0\x29\xe0\xa8\x6e\xbe\x2f\x0f\xf3\xd9\x7e\xff\xb8\xec\x5a\x24\x47\xf4\xd2\xcc\x98\x2c\xcf\x44\x83\x49\xaf\x09\x73\x80\xef\x6a\xb4\x72\x61\x8a\xfd\xf1\x84\x25\x04\xbd\x30\xe8\x70\x07\xe0\x01\x30\xa6\x07\x5a\x04\xfb\x6f\xcf\xff\xba\x9b\xbc\x13\x88\x24\xf4\x82\xa6\x20\x72\xa8\xb0\x9e\x71\xb0\xb9\xf1\x00\xa4\x60\xaa\xa3\x8b\x3d\x65\xe3\x92\x4c\x3f\x86\x86\x10\xac\xdc\xc6\x72\xfd\x94\x4d\x6e\x63\x08\x08\x6f\xf8\xa2\xba\xc2\xdf\xd2\x0e\xe1\x81\x49\x34\x46\x8e\x97\xed\x55\x1b\x80\x62\x34\x9e\x26\xd1\xda\x89\x31\xdd\x2e\x43\xe6\x81\x49\x29\x7a\xa5\x76\xce\x3c\x88\x42\xcc\xc1\x94\xce\xb7\x9c\x74\x95\x4c\x38\x20\xdf\x62\xb9\x27\x13\x45\xd3\x71\x29\x13\x0f\xc3\x88\xe2\x9c\x39\xe1\x74\x5f\x2d\xd6\x28\xab\xe4\x28\x39\x79\x18\x26\x96\x67\x78\xbf\xfe\x7d\xf8\xc8\xed\xdf\xbd\x24\xe9\x4e\xb8\x04\xeb\xfa\x73\x52\xa5\xc1\xc3\x28\x09\x52\x07\xb9\x39\x68\xf8\x50\x65\x71\x38\xfa\x6c\x33\x0f\xa3\x54\xe1\x77\xad\x6f\x6c\x98\x57\x74\xd5\x3c\x8c\x0c\x89\x2c\x08\xf0\xa3\xdd\x3c\x87\x82\x3a\xdd\x48\x87\x71\x64\xd9\xa3\xf2\x52\xbd\x2f\x2e\xca\x1f\xc0\x3c\x8c\x8d\xd5\x57\xaf\x2c\xa0\x77\xec\xed\xb6\xcd\x7e\x7d\x89\xe2\x15\xee\xcb\x72\x55\x58\x7a\xf0\xbb\x4b\x21\x8e\x99\x42\xa6\xa1\xf1\xad\x48\x20\x70\x7b\x44\x4c\xad\xa8\xd0\x04\xf3\x4d\x89\x45\x13\x1c\x7c\xe4\x70\xb9\xff\xe6\xeb\xd2\xfd\x69\xca\xc3\x24\x08\x11\xb4\x5a\x1f\x07\xf4\x25\xb6\x96\xac\xde\x4d\x02\xd9\x3c\x4c\xc0\x9e\x45\xef\xba\x69\x77\x1d\x67\xba\xf9\x3b\x52\x13\xa0\xe9\xfb\x2a\x8e\x8e\xc7\x20\x9f\x90\x4a\xf2\x90\x27\x22\xf4\x51\x65\x47\xc4\x36\xfe\x5c\x5c\xb3\x68\x48\x5f\xb2\x29\x3f\x27\xc1\x79\x1e\xa6\x71\x82\x51\x94\xee\x50\x28\xb4\x63\x41\xf9\x02\xce\x3d\x34\x31\x78\x28\x42\x8e\x9c\xed\xef\x59\x9e\xaf\x8b\x97\xa2\xd3\x7f\xbd\x2f\x3d\x7b\x33\x0f\x45\x9a\xe8\x2e\x44\x6e\xf5\xb6\xa6\x41\x52\x1e\xca\x30\x45\xb4\x57\x7b\x5a\x78\x67\x19\x09\xeb\xa7\x67\x53\x28\x8d\xd5\xae\x69\xef\xb9\x7f\x9b\xba\xc0\x3c\xd4\x81\xad\x28\xad\xa1\xd9\x88\xea\xba\x02\x7b\x7c\xa8\x84\x3a\xe0\x18\x85\x6d\x8f\x7a\x51\xc1\x23\xb2\xa6\x5d\xba\x8b\x45\x29\x1e\x84\x0f\xe2\x28\xc5\xd0\xa9\xe3\xa1\x56\x01\x3e\xc7\x7f\x9f\xb3\x3f\x3f\x47\x7a\x3d\x3c\xd4\x10\x79\x9e\x81\x21\x92\xb6\x9e\x7d\x88\x2c\xef\x21\xa0\x6d\x47\x08\xfc\x92\x7a\x2f\xc1\x4c\x46\x05\x38\x63\x89\x05\x28\x96\xf9\xc7\x4d\xfa\x31\x1e\x82\xb6\xca\xf2\xdd\xb1\x58\x4d\x27\x9b\xe1\x21\x9a\x9f\xbd\x9b\x34\xd0\x15\x6b\x9b\xa5\xa1\x4e\x10\x61\x90\xc4\x98\x26\x55\x46\xdb\x78\x68\x8c\xe5\x93\x74\x66\xfe\x02\xcb\xb6\x3a\x9e\x13\x1e\x05\xa1\xb0\x95\x76\x76\x85\x3e\x96\x4e\x78\x20\x8c\xf8\x15\xff\xef\x2d\xab\x96\x92\x41\xe0\x88\x47\xa1\x08\xfd\x7e\xff\xbd\x6c\xcd\x08\xc7\x45\xea\xf5\x6e\x7c\x37\x65\x77\x95\x76\x13\x72\x92\xc2\xf5\x75\x5a\xc4\xcf\xa5\x28\x8a\x19\xfa\xdf\x8f\x42\x26\x61\xeb\x9e\x0e\xbf\x62\x14\x25\x02\x55\xb3\xb1\xc4\xd6\x13\x44\x03\xcc\xe4\xd8\x77\xe6\x51\x44\x35\xa6\xf7\xf7\x8b\x5f\xb0\x69\xf1\x28\xe2\x04\xc3\x3a\x9b\xaa\x3c\x41\xd5\x5c\x76\x83\x72\xdd\x5b\xd6\x72\xfb\x0b\x83\x1b\xb6\xc0\x72\xcb\xdd\x49\x54\x8d\x28\xea\x7d\x39\x17\xcd\x54\xb4\x9a\x47\x51\x0a\xd2\x55\x8a\xcf\xce\xcd\xdb\xfc\xb2\x28\xf5\x2f\x72\x48\x3c\x22\xa1\x66\xfd\xc4\xe9\x45\xa5\xfa\x4c\xf9\x64\xed\x45\x24\x52\xb1\xc3\xdb\x2f\xde\x5a\x03\xa0\x78\x9d\x1c\x58\x11\x89\x39\x11\x1d\x29\x3f\x4e\xfd\x59\x33\x29\xcf\xe0\x11\x61\x51\xea\xaa\x03\x56\x67\x0d\x3f\x77\xaa\xac\x60\x96\x7f\x61\xf9\x45\x89\x23\xd8\x3f\xa1\x27\xb6\xb5\xab\xa1\xf2\xdf\x89\x12\xe6\x73\x24\xf6\x18\xe8\xa6\x03\x4f\x02\x04\xe8\x3a\xce\xc2\x27\xa8\x6b\xf1\x0a\x4e\x26\x77\x34\x16\x5c\xc5\x78\x62\xd4\xea\x0d\xf4\x39\x47\x32\x91\xf1\xc7\x21\x37\xb9\xc3\x78\x94\xea\x10\xf9\x23\xac\x80\x34\xd6\x4e\xbb\xfa\xb3\x4e\xd1\x90\x47\x82\x30\xc7\x4f\x8f\x70\x88\x39\x34\x9f\x00\xc5\x53\x56\x34\xdd\xb3\x0a\x46\x10\xdd\xf2\x9a\x7d\xc0\x13\x2c\xee\x36\x93\x21\x13\x32\x42\x88\xd3\x66\xbb\xfa\x3e\xdb\x3b\x1d\xf7\x81\x6b\xcc\x23\x19\xa9\xd8\x55\x07\x9a\xac\x3a\xce\x2f\xd3\xe9\xe8\xfb\x19\x23\x9c\xeb\x71\x38\x42\xf5\x9e\xc3\x01\xc5\x81\x27\x37\x54\x41\x8a\x7c\x9e\x9b\x0a\x6a\xa4\x32\x5a\x2c\xd7\xfe\x56\x2a\x8a\x9d\x43\xdb\x4e\xcc\xfb\xaa\x3c\xf6\x4a\x7b\xbe\x4b\x12\x20\x9e\x20\x2f\x5f\x27\x17\xd6\xc0\xbc\x76\x2b\x58\x22\x9b\x49\x07\x20\x02\x63\xb2\xed\xa6\xd2\x9c\xaf\xa5\x60\xff\x0e\x60\x92\x47\xa0\x62\x8c\x33\x3e\x97\xd5\xd1\x3f\x14\x68\x15\x4a\x44\xd4\xed\x86\x2c\x3e\xe3\xd9\x66\x62\x5b\xa0\x5d\xbf\x89\x1b\x7c\xb7\x3c\x32\x4c\xd8\x9c\x6f\xbb\xd5\xba\x93\x7b\xf9\x33\xbb\x22\x76\x9c\x3c\x8f\x91\x31\x56\x16\x64\xaa\xec\x89\xe7\x27\xab\xc7\x80\xc5\xc5\x6e\x1e\x67\x7f\x2c\xb7\x87\xa7\xe5\x7e\x76\x37\xdb\x3b\x2f\x98\xc7\x01\x25\x6a\x78\x5c\xe3\x04\x7a\xcb\x4e\xe3\xab\xc4\x81\x8a\xa3\x3e\x8b\xf0\x95\xd0\x12\x8f\x03\x4d\x78\x8a\xb8\x8d\xeb\x77\xb8\x91\x25\x71\xbf\x0a\x39\x45\x86\xaa\x6f\x65\x75\x29\xcf\xc3\x1d\x33\x0e\x05\xe0\x90\xb7\x2e\x99\x2e\x8f\x98\xa5\xcf\xca\xe2\x1e\x60\x55\xdc\xb7\x7e\xe9\xa5\xeb\x09\x29\x8d\xbc\x34\x8c\xb4\xa4\x37\x5d\x93\x75\x0c\x1d\xa9\xfa\x18\xae\x7d\xf3\x53\xc7\xa1\xb1\x51\x13\xb7\x93\x9d\x4e\x5f\x11\x37\xf6\xf6\x5a\x1c\x07\x14\xa7\xc2\x76\xb9\x5b\x3e\x3e\xae\x9e\x1f\x0e\x8f\xeb\xc5\xef\x2f\x9b\xc3\x66\xb9\x5d\xad\xbd\xa7\x1b\xc7\xb1\x85\x23\xcf\x2a\x71\xf4\x6a\x53\x3c\x8e\xd3\x20\x48\xbc\xc5\xac\xf5\x74\x2f\x8e\x63\x93\x22\x0a\x7b\xbd\x5b\x8e\x06\x88\x84\x56\x04\x75\x0e\x7f\x0a\xc7\x0e\x36\xda\x87\x62\xc2\x22\x84\x69\x49\x68\xea\x67\xaf\x11\xcc\x63\xa2\x25\xf1\x3a\x6f\x3d\xd6\xd3\xaa\xdf\x75\x7d\x20\x0a\x9d\xe1\xf3\x20\x8e\xb0\xa9\x06\x46\xee\x64\xbc\x92\xd0\xaa\x54\x7c\x3a\x5d\x8e\x2e\x35\xc5\xe3\x84\x08\x1e\xb9\xe8\xfc\xac\x82\x42\x0c\x2c\x85\x38\x11\x94\x7b\xb7\xde\xe5\x15\x7d\x0b\x48\x1c\xcd\x67\xf8\xfc\x0a\x19\x7d\x6b\x06\xd2\x28\x45\x28\xd8\x72\xfe\xe8\x27\xcb\xaf\x8e\xd0\x98\xd1\x10\x1c\x54\x70\x3e\x7b\x89\xae\xb0\x8d\xb7\x5f\x97\x01\x43\x4c\x94\xc4\x63\x73\xa6\x27\xa6\x74\xcc\xa5\xad\xa7\x6b\x37\x44\xe1\xb9\xa0\x0f\x80\x44\x59\x5f\xd8\x8d\x31\x07\x11\x0a\x2f\xb9\x8c\xfa\x82\x4f\xe2\xe7\x3f\xce\x47\xef\x0f\xc5\xdc\x50\x2c\x7e\xb2\x54\x09\x98\xe1\x87\x6b\xd5\x4d\xd7\x39\x8d\xe2\xa0\x57\xda\xb1\xc9\x8f\x27\x31\xd9\x38\xe3\x94\x04\xcc\x5b\xd2\xa2\x01\x0c\x07\x5c\x69\x25\xb5\xdd\x08\x2e\xa0\xc7\xf2\x75\xf9\xfa\x8a\x9a\x5f\x75\xf6\x65\x7a\x9e\xc7\x29\xe5\x14\x05\xc2\xf7\xbb\xfd\x72\xb7\x67\xfe\x0d\x52\xad\x2c\xb5\xab\x38\xd7\xf0\xa3\xb5\xe8\x27\xbf\x03\x89\x43\xe0\xf1\x84\x57\xfb\xdf\xed\x91\x13\x44\xf1\x4e\xdd\xd7\x43\x7c\x86\x44\x14\x3c\x16\xcc\xd2\x0c\x08\xad\xef\x32\x05\xdb\xf2\x0b\xcc\x31\x8f\x65\xa2\xb1\xb8\x0b\x94\x7f\x6a\x45\xcc\x20\x59\xb9\xc8\x2a\x44\x32\xf6\x31\xb3\x58\x51\x83\x11\x9b\xa7\xd5\x6c\x20\x6d\xc6\x63\x05\x41\xa2\xc7\x7c\xbf\x83\xf2\xd6\xe9\x56\x1d\xeb\x80\xa3\xb9\xd5\x13\x4f\xf1\x58\x87\x96\x58\x47\x9e\x2f\xbb\x77\x68\xd4\xdb\x64\xc4\x34\x4d\xd1\x15\xca\x8a\x66\xa2\x33\xc5\x63\x9d\x52\x9c\xa4\xab\xa2\x3e\x57\xed\x04\xb4\xb9\x48\xd7\x0a\xb1\xc1\x2a\xcb\x1d\xca\xd1\xfc\x2f\xa8\x66\x5a\x87\xcd\x63\x48\x18\xfa\xe7\x4a\xbc\x42\xb7\x30\x21\x15\x28\x03\x82\x65\x94\xa7\x81\x82\x0b\x8f\xa1\x1d\x3c\x1f\x3c\xd4\x56\x95\x60\xf2\x92\x46\x69\x10\xbf\xc0\xc1\x8c\x3f\x2d\x09\x62\xee\x4b\xe9\x9f\xb2\x22\x3b\x9e\x8f\x43\xba\xe6\xdf\x7c\x2f\x66\xc1\x80\x18\xfd\xba\xb7\xa0\x89\x49\x31\xd0\xe4\xb2\xdc\x6a\x24\xb6\x7d\xb3\xe2\xf5\xb0\xb3\x91\xc4\x83\x12\xf5\x9b\x14\xea\x1d\xab\xc6\x0e\x75\x2f\xee\xc9\x49\x9c\xd8\x02\x1e\xab\xd3\x7f\x38\x89\xcb\xc0\xed\x22\xb1\x0c\x11\x42\x59\x67\xc5\x6b\xde\x95\x13\x76\xad\x9a\x80\x4b\x75\xf9\x38\xb1\xc7\xe5\x5e\x9f\x23\x24\xd6\x02\x63\x8d\x58\x8c\xbd\xff\x2c\xfb\x4d\x91\xc4\x20\x48\xaf\x86\x84\xdc\xf8\x36\x43\x3d\xeb\x8a\x57\xc6\x13\x84\x10\x91\x1a\xd2\x7b\x4d\x03\x41\x8b\x2b\xec\xf5\xed\xa1\x4a\x82\x10\x37\xd4\x53\x55\xd6\x27\x70\xd5\xa2\x23\x48\x0a\x27\x09\x25\xe8\xef\x6d\x1f\x86\xf3\x9f\x24\x9c\x22\x82\xb8\x80\xcf\xa1\xf6\x87\x6b\xa5\x29\xc5\x8a\xa6\x3a\x1f\xd0\xe9\x7e\x21\x5e\xcc\x09\x93\x21\x6e\x29\xab\xe7\xd9\xf0\xfc\x23\x3c\x48\xc3\x6e\xed\x8f\x59\x76\x6f\xee\x4d\x84\x47\x0a\x4b\x20\x36\xe2\xd2\x1a\x4c\xdd\x75\xb4\xe5\xa6\xf6\x68\x48\xcb\x04\xeb\x1a\xd3\x80\x69\xd6\x69\x51\x1c\xda\x19\x32\x8d\x65\x91\x54\x28\x64\x33\x2f\x3f\xa0\xaa\x32\x0d\x08\xb8\x19\x7c\x55\x11\x00\xb2\x82\xcc\x77\x3f\x16\x58\x0b\xe0\x37\x12\xb0\xa2\xce\xfe\x5e\x82\x26\x98\xee\xf1\x71\xfe\xbb\xf2\xb3\x4b\xd6\xf8\x2e\x3a\x40\xd8\xad\xa3\xc3\x69\x37\xd2\x31\xaa\xf9\xaf\xfe\x3d\x0f\x64\x12\x39\x11\x86\x61\x4c\x33\xab\xf1\x49\x56\x1a\x01\x24\xeb\xca\xe1\xd1\x6f\x23\xea\x38\x91\x91\x49\x1c\x0f\xd7\x7f\xce\x22\xb7\x79\x4d\xdf\x46\x23\xe2\x1c\xd3\x76\x67\x19\x44\x39\x88\x4c\x6d\x4e\x7e\x40\x12\xde\x35\x29\x19\x86\x83\x65\xb2\x75\x1a\x19\x57\x27\xa6\x77\x1f\x89\x82\x90\xba\xd3\x7b\x59\x58\xc9\xf7\x70\xb2\x00\xb4\x92\xe8\x23\x2f\xee\x47\xf3\x46\x6b\x83\x21\xb8\x5c\x38\x1f\x7d\xd5\x3d\x86\x89\x03\xac\x2a\x3c\x64\xb5\x43\xa4\xcf\xcf\x97\xac\x98\x5c\xd7\x90\x28\x90\x5d\x39\xba\x2e\x8f\x4e\xa4\xe2\xf6\x60\x19\x05\x89\xcd\x1f\xf4\xb0\x0b\x9e\x04\x22\x8c\x1d\xf0\xfa\x90\x97\x35\x1c\x54\x09\xa6\xee\x5b\x19\x0a\x62\x1f\x84\xd6\x43\x4e\xcd\xf1\x02\x4d\x02\xc9\x30\x4c\x88\x93\xff\x8f\xdd\x10\x38\xc4\x93\x30\x08\x11\x30\x62\x05\x1d\x92\xe0\x10\x06\x41\xd7\x96\x28\xa3\x7a\x90\xb5\xd5\x9a\xbc\xf4\xad\x80\x86\x25\xe6\xe6\x65\x0e\xd3\xb0\x59\x12\x52\x45\x31\x80\x52\x95\xe7\xd3\xa6\xcc\x33\x75\x59\x15\x75\xd3\x57\x1b\xf0\x24\x14\x84\x58\x05\xc6\x63\x37\x01\x92\x88\x44\xf8\xd2\x77\x90\x43\x03\xab\x63\x6b\x70\x8e\x06\x2b\x89\x64\x8a\x5c\x86\x87\xf3\x20\x2d\xec\xda\xe2\x98\xc4\xee\x20\xc7\x7c\xcd\xec\xee\x26\x8e\x96\x27\x31\x95\xc8\xd7\x70\x12\x55\x93\xa9\xec\x84\x5a\xe2\x5f\x74\xe5\x14\xcd\x92\xd6\xac\x3a\x9f\x6e\xca\xf2\xf0\x24\x06\x40\x6e\xca\x4a\x34\xf0\xb2\xf3\xd6\x7c\x42\x22\x93\x74\x7a\x7f\x27\xb1\x28\xab\x71\xd5\x2f\x4f\x08\x97\x78\xe2\xfd\xe7\x2c\xaa\x06\x2a\x2b\x30\xd5\xb5\x59\x62\x29\xef\x7e\xfd\xda\xe1\x4b\x88\x66\xc8\xd1\xdb\x41\xb6\xbd\x8b\x7c\xdb\xa7\x71\xbf\xa2\x9a\x06\x49\xb7\x7b\x8d\xc1\xff\x3c\x61\x81\x44\xc7\xfb\x50\xc0\xe7\x12\x15\xf0\xc6\xbf\x66\x2c\x94\x1d\xd8\x19\x9c\x3c\xf6\x17\x53\x91\xa5\x02\xa7\x22\xd2\x5a\x9c\xa0\x52\x96\xfa\xc8\xdf\x8a\xf3\x24\xb5\x1b\xcd\xee\x7c\x82\x6a\x5a\x16\x3c\xb9\x58\x1a\x24\x42\xb9\x8b\x21\x98\x3c\x6b\xac\x18\xe7\xe8\xf1\x44\x64\x89\xac\x6b\x68\xf6\xcb\x9f\xe3\x3d\x39\x11\xb1\x35\x36\xac\xc4\x3b\x66\xd9\xd6\x66\x29\xaa\xfc\xe2\x0b\xa9\xea\x1e\xbd\xe2\x7f\x03\x46\x7a\xfe\x86\x79\xd6\xd4\x3b\x40\x2d\x08\x4c\xa5\xae\xd7\x73\xdf\x4d\x46\x56\x5c\xb4\x02\xd5\xee\xf8\x6d\x17\xd0\x8f\xbd\xe5\x96\x28\x2a\x11\x60\x71\xa8\x85\x81\x07\x51\x5f\xc7\x7f\x7c\x47\x19\xf4\x40\xed\xa8\xfb\xb9\x8e\x71\x9b\x6c\x0d\x91\xd6\xd2\x1a\xa5\x23\x12\x9d\x2a\xc5\x7c\x04\xfc\x23\xfb\x80\xab\xf8\x77\xa2\x85\x40\x19\x29\x67\x7a\x36\x97\xa9\x80\x95\xeb\x07\xc4\x32\x2c\xe1\xec\x58\xd5\xf5\x19\xf4\xa6\x82\x1d\x86\x95\x3a\x35\x64\x9e\x80\x21\xf8\x3a\x56\xbd\xc7\x2e\xf7\x0e\x35\x3a\x30\xb8\x27\x09\xb3\xc4\x04\x29\x86\xd2\xee\xcb\x9f\x99\x2a\x37\x03\xe2\xfa\xdb\x16\x5f\x62\x62\x89\x15\xf6\x4e\x63\x7d\xa5\xca\x3b\x10\x3a\xef\x2a\xda\x79\x62\xb8\x88\xad\x7e\xe7\x3e\x13\xa3\x30\x39\x0d\x92\x28\x76\x81\xa8\x67\xf8\xdc\x83\x38\x6e\x4a\xeb\xa9\xf8\xd2\x02\x47\x4c\x39\xa8\x9a\x74\xa4\x66\x9c\x06\xc2\x42\x15\xbb\xea\xb9\x51\xed\x14\xa7\x01\x50\x0c\x44\xfa\x88\xfe\x2f\x83\x45\x34\x4c\x74\xe4\xf5\x40\xb2\x72\x12\x96\xf5\x7d\x74\x84\x61\xde\xa7\xd5\x76\xe1\xef\x12\x71\x5b\x48\xaf\xcb\x01\x17\x79\xdd\xb5\x6a\xc6\x03\x1f\x0c\x1d\xcf\x76\x1a\x19\x6a\xac\xa0\xef\xe9\x50\x9c\xab\xb3\xff\x4d\x1c\x25\x58\xe2\x3c\x9f\xed\xc6\xf1\x3d\x1a\x27\x80\xbe\x4e\x79\x82\x62\x07\x96\x9c\xc7\x35\x91\x90\xa3\x5f\x7c\x38\x55\x36\x59\x2c\x72\x18\x6a\x1a\x8e\x0a\x33\x26\xaf\x4e\xa4\xc2\x53\x79\xc0\xfe\x9a\x5c\x93\xad\x70\x4a\x94\xad\xd7\xed\x55\x69\x6f\x50\xf9\x73\x4a\x80\x45\xce\x99\xee\xd2\x1d\x5e\x30\xe9\x8a\x6b\x9a\xd3\x24\xd4\x78\xd4\x6e\x2a\x18\xec\x73\x94\x07\x34\x74\xc4\x5b\xab\xc5\x7a\xf9\xd3\x57\xc0\x4d\x10\x47\x9c\x72\xae\xb5\x87\x80\x8a\xca\x72\x78\xd9\x6c\x7f\x07\xa0\x1b\xff\x20\x95\x21\x9a\xa0\x1a\x54\x2e\x2a\xf8\x9e\xa1\x66\xf3\xed\x59\x91\xca\x18\x85\xdb\xbc\x7a\x65\x0f\xe9\xe2\x54\xc4\x89\x55\xe3\x41\xe0\x69\x6b\xcb\xd4\x7d\x13\x20\x31\xe8\xd3\xe5\x41\x94\xaf\x67\x51\xf4\x2d\xd4\x6a\x57\xd4\xd0\x78\x2a\x71\xdc\x48\xee\x44\x03\xa8\x88\x7d\x33\xc6\x4c\x85\x34\x28\x08\x7c\x14\x59\x81\x4c\x04\xad\x3b\x41\xba\x8b\x02\xc7\x3d\xdf\xf2\x10\x22\x27\xb2\x27\xa0\xe2\x54\x06\x14\x79\x78\xe4\xb9\x2a\xa0\x1a\x40\x95\x38\x95\x89\x95\x3d\xb9\x9b\x3d\xef\x76\x65\xde\xbd\x99\x6a\xbd\xa7\xff\xf7\xff\xfb\x7f\x0f\xe5\x87\xda\x83\x7a\x2b\x32\x25\xf2\x87\x76\xfb\xed\x7a\x70\x40\x74\x94\xc4\xe8\x2d\x52\x28\x3e\xc3\xe7\xa6\x6c\xa0\x68\x32\x04\xd9\x16\xfd\xa7\x54\x4a\x93\xb0\x83\xee\x4c\x44\x91\x39\x6d\xb7\xce\xf6\x03\x16\x25\x0a\xfd\xdc\x08\xbc\xbb\x8e\x5a\x50\xd0\xde\x6d\x44\xb8\xef\xbc\x37\xc4\xa9\x96\x21\xd6\x6e\x9b\xb2\x42\xe2\xf5\xac\x79\xdb\xc2\x07\x54\xd7\x98\xa9\xc1\x6e\x4e\x81\xa7\x88\xef\x7f\x13\xf5\x53\x56\x38\x39\xc0\xf5\xaf\x45\xb5\x39\x0b\x22\x83\x1c\xe1\x4a\xe4\x0a\x83\x3a\x93\x90\xd5\xa4\x37\x27\xa9\xd3\xc5\x9f\x8b\xe2\x1d\xaa\x4d\x95\x15\xad\x89\x93\x0f\xf1\x1e\x2c\x54\x0a\xa1\xe6\x07\xd5\x6d\x7c\x5d\x13\x58\xb5\xab\xbb\x73\xa3\xde\x3c\x29\xe7\x2f\x83\x2c\x2c\x0a\x05\x9a\xf4\x16\x81\xde\x9c\x2b\xc7\x5c\x72\xfb\x85\xa2\xd0\xe0\x6a\x2b\x66\xb9\xa8\x8e\x7e\x4c\x59\x94\x10\xb4\x00\x1e\x16\xb3\xb0\xfb\x9b\x04\x64\x16\xa9\x8b\xee\x2f\x2a\xd5\x96\x7d\x65\x90\x35\xbe\x39\x12\x71\x64\xb9\x9e\x5f\xcb\x52\x3f\x9e\xaf\xe9\xd0\x7c\x37\x26\xf1\x16\x05\xfc\x6c\x2c\x6f\xda\x20\x06\xc9\xe2\x94\xa0\xbf\x7d\x57\x16\xa2\x81\xa1\x71\xc4\x62\xcd\x2c\xaf\x71\x97\xe7\xdc\x57\x67\x34\xff\xc6\x37\x20\x91\xdd\xc9\xde\xb2\x8f\x76\xaf\xe8\xed\x43\x46\x78\x64\xbf\xac\x25\xf3\x45\xd2\xba\x49\x86\x8b\x25\xca\x52\x1c\x78\xa1\x36\x0c\x7f\x39\x55\xe0\xb1\x51\xc7\xfd\x07\xa4\x61\x10\x2a\x5f\x03\x87\x56\x77\x53\xdf\xa4\x59\xe1\x8c\x46\x49\xd0\x4b\xac\x2d\xf2\xb2\x80\x7a\x55\xfc\xc8\xf2\x49\x94\x8f\x51\x03\xb8\x8f\x09\xbf\xc9\x7e\x13\x1f\x1f\x53\x4a\x46\xce\x58\x9a\x44\x8e\x0f\x64\x52\x56\x36\x98\x60\x9c\x51\x95\x8c\xd2\x39\x88\xd8\x9a\xdc\x91\xf3\x98\xdb\x78\xe0\x65\x07\xd5\xc7\x34\x1c\xd4\x57\xf2\x9c\x7b\x2a\xd2\x5f\xff\xe3\x2f\x9c\xda\x57\x71\x92\xf3\x2f\x45\x86\x72\xd5\x5f\xb0\x90\x72\xc6\x8d\x42\xb4\xd1\xd1\x92\x0a\x96\x85\x87\xd5\xbb\x76\x21\x38\x46\x32\x0e\x58\x5a\x75\xb9\x46\x91\xb7\x5d\xec\x54\xdc\x21\x9b\xc6\xc4\xfb\x67\x42\x0a\x34\x4c\x4e\xb9\x50\x7f\xa9\xe9\xe2\x7e\xa3\x18\x53\xce\x98\xf9\x9e\x55\x8d\x63\x84\x2e\x20\x1f\x07\x52\x98\x66\xd6\xa1\x12\x5a\x2f\xc4\xe9\xbe\x82\xdb\x69\x7d\x06\x8c\x60\xc0\xe5\x5b\x79\x6e\xba\x83\x9e\x81\x50\x6c\x4c\xd5\xfe\x11\x26\xbe\xd1\xc4\x21\xea\x7d\x1c\x6d\x7c\x31\x5b\x2d\xd6\xbf\x72\x35\x98\x21\x44\xba\xd2\xcc\x1f\x20\xdb\x5d\x79\x14\x50\x64\xc6\x48\x4b\x8d\x2a\x8e\xb0\xd2\x8b\xa2\xf1\x2b\x8d\x07\x41\xa8\x6d\x9c\x0a\x8d\x91\x0e\x1a\xcb\x79\x10\x52\x5f\x1f\x80\x7b\xb4\x5d\xa6\x3f\x96\x2b\xc4\x70\xf9\x4e\x34\x21\xbd\xb5\xf5\x28\x8a\xd7\x33\x9e\x9f\xa3\x11\xe0\x81\x49\x31\x74\xd9\xee\x61\x4f\xe2\xa7\xff\x71\x18\xaa\x98\x0e\x18\xc1\x9f\xe1\x73\x12\x3e\x74\x1d\xa3\x90\x63\x2c\x0c\x83\x4d\x9b\x37\x28\x8b\xec\xe7\xb4\x4b\x1c\x23\x4b\xc0\x21\xab\x1f\xb3\xfa\x2b\x19\x3b\xce\xe3\x38\xb5\xfc\xed\xf3\xf5\xe6\x9a\xa5\xbc\x6d\x07\x2b\x65\x56\x95\x52\xc8\x2c\xb7\xf5\xde\xa3\xd1\xc6\xac\x8b\x33\x8c\x7c\xd1\x44\x7d\x8b\x19\x85\xf3\x98\x85\x8e\x6f\xda\x12\xdc\xb4\xd3\x13\x74\xf8\x87\x1f\x81\x58\x1b\x99\x8c\xf6\xb9\x01\x87\x10\xe7\x24\xb0\x92\xb4\xfb\xf2\x84\xa1\xdd\x11\xb3\xe1\x57\x25\x9b\x9c\x13\x6e\xc5\x09\xf1\xa3\xe8\x95\xae\xe7\x97\x5b\xaf\x4a\x20\x41\xbb\xfa\x35\xfb\x80\x85\x70\x55\x7c\xc9\x64\xbc\x12\x16\x63\x0d\x3c\xc2\xea\xb2\xba\x19\x96\x32\x70\x9e\x80\x30\x51\x8f\x99\xb4\x8b\x77\xb0\xc7\x73\x1a\x30\x14\x2b\x40\x06\x91\xd6\x04\x8e\xba\x16\x92\x7a\x42\xd2\x47\x51\x37\x23\x4b\x83\x53\x6e\xcb\xde\xec\xee\x3d\xa9\x61\xe5\x9c\x2a\x69\x51\xdb\x20\x74\x37\x15\x29\xa4\x92\x76\x0e\xf3\x16\xf2\xeb\xca\x06\xce\x39\xb3\x0a\x85\xfb\x4e\x09\xea\x06\x7b\xf5\x57\xe9\x69\x77\x8d\x34\x51\x38\x24\xb5\x7a\x83\xa3\xf0\xb7\x4f\x29\xe0\xa0\xa3\x8a\x78\x76\xec\xfe\xcc\x52\x92\xd8\x95\xdc\xfd\x49\xd8\x02\x8d\x7f\x6c\x0e\x75\x97\x18\xe4\x22\xa0\xcc\x0c\x16\xc3\xb7\xb2\x81\x7c\xb4\x8a\xb9\x60\x24\x92\x5d\xa1\x3b\x5a\xaa\x37\x3c\xc0\x2b\xa3\x80\xcb\x80\x61\xfe\xbf\x35\x0d\x87\x6e\x1b\x97\xa1\x89\x87\xd3\x93\x4e\x26\xba\x34\x61\x22\xba\x21\x7d\xcc\xfe\x73\xce\x74\xd6\xfc\xff\x39\xfb\x97\xe6\xc6\x71\x2c\x7f\x18\xfe\x2e\xff\x55\x2d\x7a\xc1\x3b\x81\x77\x27\xc9\x72\xa6\xba\x6c\x4b\x2d\x29\x33\xab\xba\xa3\x43\x71\x00\x1c\xd8\x2c\x4b\xa4\x86\xa4\xd2\xd6\x7c\xfa\x37\x78\x00\xf0\x26\xda\x59\xf3\x44\x4c\x74\x4e\x99\x10\x45\x91\x20\x70\x2e\xbf\xcb\x87\x19\xd8\xf8\x6b\x35\x86\x6d\x89\xe6\x92\xd7\x83\xd0\x9a\x49\xc9\x52\x69\xa3\xf7\x26\xc9\x9c\xac\xfe\x30\xa9\x59\x60\x01\xa4\xdf\x31\x57\x45\x69\xf9\xac\x1f\xf6\x91\x3f\xfc\xb7\x5b\xe0\x99\x0a\x3c\x23\xea\x48\x80\xbc\xce\x91\x7b\x3c\x2c\x49\xa9\x17\xad\x6e\x36\x1d\x86\x9e\xf0\x78\x0b\x5a\xa5\x99\x44\x51\x59\x4f\x54\x8e\x31\xe4\x9a\xb2\xcc\x4f\x3c\x9b\x18\x43\x65\xde\xa0\xd3\x24\x1c\x97\x7b\x5e\x4c\xe0\x2c\xdb\xd8\x37\xc1\xb0\xc6\x12\x3b\x8f\xdb\x76\xa4\x49\x9f\x9e\x0b\x35\xac\x34\x70\x2f\x4c\x29\x1e\xdd\x5f\x4a\xdc\x97\x08\xd5\xa5\x44\x12\xb4\x68\x07\xa4\x11\xa1\x46\xb3\x6a\x51\x1c\x8f\x28\xfb\x1b\xb1\x35\x68\x30\xff\xb8\xf1\x68\x2c\x46\x8b\x12\xe4\xb1\x27\x6e\x6b\x0f\xfb\x9e\x4f\x95\x74\x1b\xdf\x52\x5a\x84\xd3\x4e\x2b\xcd\xe0\xc0\x08\xa7\x3a\xcc\x8f\x29\x17\xdd\x93\x1f\xe0\xe4\x73\xe1\x01\x22\xd5\xd5\xaa\x8b\xb8\xc3\x9f\xfb\x37\xb7\x02\xf0\x48\xf1\xd8\xd9\x94\xa3\xb2\x65\x74\x53\x7d\xf8\x9b\x80\x93\x7f\x8c\xda\xd0\xf6\xc4\x71\x14\x26\xb6\x79\x66\x8b\x10\x1b\x28\xe1\x84\x75\x4f\xda\xe2\x6f\x4c\x3c\x1e\x27\x90\xa4\x3d\xfd\xd2\xcf\x5b\x26\x3c\x89\xbd\x10\xdc\x0b\x94\xeb\xec\x79\x04\x4a\x77\xc3\x12\xe6\xb9\x82\x9d\xa5\x9c\x51\x30\x6d\xb7\xa4\xdd\x4b\x71\x39\xaa\x39\xfe\xbb\xd5\x40\x65\x3c\x8d\x25\xed\x60\xff\x86\xbc\xee\x29\x20\x31\x9e\x26\x21\xb1\x33\xb6\xc5\x6b\x7f\xa5\xe0\x29\x18\xfa\x74\x7e\x39\x2d\x4f\xe7\xfa\x4a\x65\xb9\xf6\x65\xe6\xa9\x34\xa0\xcf\x26\x98\xa1\x8a\x45\xb7\x05\xf0\x14\x85\x90\xae\xbf\x6e\x02\x6d\x45\x95\x8c\x96\x7c\x66\x07\x32\x3f\x65\x9d\xbe\xc4\xf9\x98\xdd\x6e\xa8\x9c\x45\x86\x3b\x7d\x68\x85\x6d\x6c\x7b\xf2\xdc\x83\x2c\x72\x86\xc6\x04\x2c\xcb\x65\x93\xc7\xfe\x1c\x28\x19\x76\x26\x37\x8c\x33\xcd\xa8\xc1\xbe\xac\x24\x9c\xfb\xd5\xf6\xd1\x04\xe0\x31\x67\xcd\x2c\x9d\xcd\x67\x8e\x19\xc1\xb9\x48\x08\x09\x76\xff\xae\xfa\x77\x90\x23\xa7\xae\x0e\xe4\x79\xf6\x92\x91\xe2\x20\xf9\xd6\x4d\x47\x6e\x1c\xbc\x38\x14\x4e\xfd\x90\x62\x9f\x7b\xc4\xc7\x42\x91\x1d\xfa\x2f\xd0\x32\x1c\x62\x9f\xc8\x1b\xdb\x2f\x1b\xf7\xf5\x90\xa6\xc2\x6f\x97\xec\xd6\xe0\x77\x20\xce\x68\x87\x0a\x34\x65\xe1\xaa\xd0\xb5\x6c\xe1\xdf\x5c\x82\x67\x11\x61\x3f\x11\x8e\x8f\x63\x65\xa4\xde\x5b\x62\x3f\x80\x91\xa2\x5f\x4c\x2e\x97\xd9\xf1\xf5\x83\x37\x1d\x93\x98\x50\x2d\x8b\xc7\xbb\x91\xcc\x1b\xe3\x08\xc6\x20\xe1\x50\x52\xef\x7a\x69\x9c\x72\xa7\xef\x18\x02\x12\xa7\xa0\x99\xee\xbd\xfa\x08\xd7\x01\x24\x16\xae\xef\xaa\x4c\xa3\x12\x15\xd7\x21\x0b\x6d\xb4\x6a\x6f\xf6\xe2\x85\x90\x5f\x04\x3d\x9d\x5f\x97\x79\x9d\xd5\xd7\x95\x1a\x7f\x2c\x35\xbe\x2d\x8f\xb3\xfd\xe2\xeb\x72\x77\xd8\x2c\xb7\x87\xed\xba\x65\x7f\x36\x03\x24\x59\xd6\x99\xbe\xc9\x5d\x09\x6f\x53\x34\x15\xae\x15\xd0\x9b\x60\x74\x54\xed\xbe\xf1\x79\x35\x1e\x3c\x2e\x95\xd5\x59\xab\x8f\x64\xe3\xe2\x80\xb2\xfd\xc4\x0b\x3c\xa9\xd0\xb2\x0b\xbe\x55\x58\x1a\xca\xa7\xf1\x69\xfe\xe0\x3e\x82\x9f\x1a\x49\xd5\x07\x84\xe7\xcb\xb4\xb2\x19\x83\xc0\x26\x01\x1b\x53\x8d\x6c\x26\x7a\x5f\x4f\x91\x41\x18\xf8\x78\x23\x13\xb8\x98\x90\xe0\x71\xe3\x23\x41\x54\x1d\xab\x6e\xf5\xc1\xd7\x86\xb1\x20\x5e\xf4\x09\xde\x9b\x97\xbb\x6f\x90\xd2\x7e\x31\x87\x04\x5d\xcf\xa3\x7e\x2b\xf6\xe5\x85\x3a\xba\x65\xfd\x54\x58\x78\x68\x3b\x54\x22\x0b\xac\x3a\x6c\x3d\xac\xb7\x42\xe4\x09\x42\x8d\xdb\x3e\xfd\x0e\xeb\x8e\xbd\x64\x7a\xd1\xd3\xf0\x79\xf7\xf1\x24\x26\xe5\x83\xaf\x50\xbd\xe4\x05\x29\xb2\xf4\x16\x03\x88\xd2\x80\xa0\xfd\xdf\xf3\xec\xdd\xe2\x9c\xdb\x43\x52\x52\x99\xcb\x15\x61\x37\xc5\x88\xef\xce\x20\xc2\xc4\x6b\xa9\xfe\x19\xaa\xdf\xff\x5c\x74\xd8\xde\xe1\x6d\x8d\x43\xce\xa1\x9d\x26\xcb\x56\x5e\x7a\x3c\x2c\x31\xd9\x4d\xab\x4b\xbf\x85\xb7\x9b\x53\x01\x53\xaa\x8b\x6d\xe4\x0b\x56\x16\x67\x6b\x07\x24\xbe\xc1\x5a\x97\xa6\x4d\x3c\x69\xe0\xf5\x8f\x89\x8e\x0b\x24\x32\xe6\xb1\x81\xb5\x1a\xfe\xdb\xc8\x17\x84\x41\xa2\x25\x11\x79\x2c\xf0\x75\x75\x3a\x63\xa9\xad\x34\xd9\xf9\xb6\x04\x0c\x69\x9a\x12\x82\x91\xfc\x7c\x4c\xd1\x8f\xe2\xef\x1c\x8e\xcd\x5b\x48\xee\x13\x76\x28\xd3\x2a\x71\x12\xbf\xee\x6f\x9c\xa7\x81\xb9\x6b\x4d\xd4\x63\x52\x90\xc0\x6b\x8f\x4a\x03\xc7\x7f\x2e\x8e\x99\xcb\x59\x01\x3c\x20\xc7\x47\xf3\xaa\x8b\x41\xa7\x02\x80\x85\xe4\xfb\xb3\xff\xba\x5d\xee\xbe\xae\x1f\xee\x82\xf6\x88\x10\xb6\xee\xfb\x8a\xfb\x7f\x8e\x6f\xb9\xf0\x02\x23\xaf\x5d\x6d\x51\x77\xd4\x82\xd1\xa0\x34\xa2\x8e\x27\xf9\x48\xef\x47\x8d\x4b\x37\x46\x70\x2a\xc1\xbe\x40\x45\x5e\xee\xeb\xdc\x29\x05\x39\xe0\x15\x1b\xad\x2f\xc2\x0a\xaf\xd3\x6a\x0a\xb9\x7a\xcb\xe4\xcb\x30\x22\x1e\x8e\x97\x49\x9c\x7a\x6d\x53\x73\x5e\x5c\x9e\x5f\xea\x55\x4e\xbd\x3d\x91\xb5\xe0\x43\x50\x09\xa7\x07\xf9\x95\x7a\x01\xfd\x50\x02\x94\x30\xd0\x43\x6c\x3e\x63\xd4\xab\xcc\x92\x32\xe2\x82\x32\x50\xd2\x38\x28\xab\x62\x03\x65\x9d\x63\x69\x77\xd2\xe1\x6f\x46\x65\xa2\x24\x51\xcb\x6a\x53\x94\xcd\x2c\xa1\x7a\x85\x3b\x8b\x0e\x62\xaa\x11\xae\xaa\x55\x5b\xb3\xcb\xf2\xe2\xdc\xee\x3e\xa0\xe3\x84\x04\x0f\x0f\xba\x49\x71\xdb\x79\xae\x39\x26\xb6\xc5\x39\x53\x3f\x3f\x43\x33\x0a\x8f\x27\x42\x38\x05\x51\xab\xa9\xfb\x41\x3c\xf8\x9f\xff\xfe\xa3\xd5\x7f\x66\xff\xf1\x03\xf6\x5f\x77\x0e\xe9\x39\x35\x38\xf7\x74\x77\x35\xb8\xb9\x2a\x7c\x2f\x4a\x22\x87\xe1\x3b\x58\xec\xf8\x6e\xd6\x92\xfc\x84\xef\xb3\xd8\xd2\x88\xbe\x60\x6e\x63\x2b\x6b\xaa\x38\xbc\x65\xc2\x8f\x62\x8a\x1b\x9c\x33\x44\xeb\xef\xf4\x7f\xc4\x67\xff\x63\x74\x5a\x65\x94\xcd\x9c\x35\xc4\xbc\x78\xc7\x51\xb0\x2a\x02\x26\x03\xfb\x2b\x77\x28\x4b\xac\xe7\xa4\xb3\x30\x1e\x25\x45\xa4\x1d\x25\x6a\xa2\xb0\x22\x02\x0c\xe8\x35\x3c\x16\x6f\x0b\x38\xb7\x0e\x5f\x4c\x84\x61\x40\x7e\x41\x45\x7e\x06\x83\x8b\x38\x1e\x4f\x3d\x8d\x80\xe9\x50\x5b\x84\x89\x01\x96\x4a\xa8\xf1\xb9\x30\xe2\xab\xa3\x11\x2a\xb4\x81\x15\xad\x7a\x36\xd0\xbe\xef\xf4\x75\x98\x88\x62\x41\x51\x0c\x35\x92\xaa\xce\x48\x88\x89\x08\x44\x0a\x3d\x1c\xf7\x8d\xc2\xc9\xe8\x72\x22\xa9\xa5\xa3\xcb\x0d\x53\x7c\x37\x00\x3d\xe6\xf5\xf4\x24\x6b\x5c\xeb\x5b\x93\x7a\x26\xe2\x28\xa0\x5a\xc5\xc1\x7b\x6f\x42\x92\x17\x3c\x66\xd0\x7f\x1b\x45\xe2\x31\x68\x9d\x5b\x2e\x24\x45\x95\x13\xe9\x8d\xec\x57\xc7\xcb\xba\xab\xc0\x88\xd4\x97\x96\x2c\x6b\xc4\x09\xa7\xf7\x71\x91\x46\x06\x3a\x3b\x57\x67\xa2\xa0\x13\x2e\xa1\x45\xb4\xf8\xc9\x7f\x07\x89\xa5\x60\x5c\x69\xe1\xc8\xc6\x78\xee\xb7\x4e\x04\xe7\xa6\x94\x66\x24\x07\x4c\x7c\x43\x41\x56\x6b\x23\x6c\x07\x42\x1a\xfa\xa6\x47\x0f\xc7\x47\x32\xf4\x7b\x74\xd5\xe5\x76\x08\xc3\x04\x7a\x0a\xcc\x04\xd2\x3c\xdd\x16\x1e\x85\x08\xba\x72\x7f\x59\x5c\xce\xd9\x38\xa4\x14\x82\x1b\x3c\xc2\x7e\xf5\x65\xb9\x75\xe7\x17\x12\x8c\x56\x79\x93\xd3\x37\x21\xd1\xfc\x72\xfd\x3c\x94\x17\xd2\x8b\x29\xa9\x3d\xa2\xae\xd3\x51\x1d\x46\x48\x16\x47\x96\x85\xb6\x59\xaf\x1f\x0e\xa8\xb2\xfa\x10\xba\x4e\x8e\x50\x51\x44\xd9\x97\xd5\xcd\x9a\xcf\x76\xcb\xfd\x72\xf6\xd8\x1e\x8e\x83\x04\x5d\x5e\x95\xe5\xf0\x8c\xd3\x1d\x0b\xa1\x52\x9f\xd0\x0d\x97\xbc\xea\xe2\x6a\xa1\x84\xa0\x5f\xe8\xd4\x07\x7c\xcf\x9a\xda\x7a\x56\x21\xc0\x73\x03\x6d\xfb\xe8\x19\xeb\x43\x65\x56\x6a\x7b\x44\xa7\x86\xfb\x6a\xf8\xd9\xad\x1a\x45\x35\xbd\xc7\x08\x2d\xc2\x48\xba\x34\xb9\xd9\x8b\x06\x1d\x2f\x33\x48\xfa\xd2\x67\x06\xd9\xd5\x2b\x5a\xcb\xc0\x4b\x84\xe3\x31\x1a\x09\xe1\x8f\x74\x65\x06\x5f\x29\x83\x58\x46\x5d\xc1\x91\x22\x89\x4e\xed\x7a\xf8\xc5\x01\x93\xe8\x75\x12\x10\xe3\x34\x56\x86\x81\x34\x76\xfe\x9b\x2f\xed\x9f\x22\x2f\x36\x58\x4e\x32\x24\x34\xae\xaf\xed\x41\x08\x28\x0d\x9b\xdd\x7d\x5f\xed\xd6\xdb\xdd\x61\xf6\x74\x77\xd8\xcc\xb6\xfb\xa7\xe5\xd6\xe4\x1a\x8b\xe5\xd3\xde\x8d\x8e\x42\xae\xac\x9c\xe3\x61\xf9\x6d\xdb\xfe\x39\x41\xea\x6f\xdf\x1b\xc3\xbf\xb6\x55\xff\x4b\x33\x08\x26\x23\xc6\xa9\xc7\xd2\xb2\x4b\xa7\x54\x47\x26\x57\xfe\x1b\x91\xdc\xc1\xa6\x28\x23\x10\x3c\x68\x41\x21\x8b\x0b\xa9\x03\x64\x3f\xb1\x7d\xe5\xdc\xc5\xc7\x81\x4f\x2c\x17\x85\x65\xf6\x13\x8d\xed\xaa\x7d\x04\xf7\x2d\x4b\x7f\x78\xd1\x31\x4b\x09\xa4\x74\x86\x73\x5b\x35\x96\x31\x06\x8e\x6d\xbe\xc3\xe3\x71\xdb\x3c\x16\x77\x2c\x89\x18\x6d\x79\x55\xf6\x9c\x77\x25\x23\x99\xc4\xc2\x48\xfa\x3d\xcb\xcf\x36\x78\x99\xc6\x21\x81\x2e\xdd\x4d\xfa\x9e\xc1\xf4\x7d\x9a\x5c\x07\x25\xf3\x94\xcd\x7a\x4c\x1a\xe5\x18\x12\xee\x70\xc0\xa8\xb0\xeb\xce\x7e\x68\x92\x28\x78\xc6\x43\xf1\x96\x63\x79\xcb\x0b\x92\x2c\x4d\xe2\xa1\x5c\xce\xaf\x6a\xd8\xee\x83\x0a\x49\xac\xc2\xfc\xb8\x7d\xf1\xad\x79\x8c\x83\x42\xa2\xe4\xb1\x59\xd1\x28\xc2\x73\x11\x42\xfc\x61\x80\xff\xff\xf1\xbf\xed\x97\x41\x88\x64\xb5\x64\x84\x7a\xba\xba\xc0\xaf\x8a\x6a\xd3\xbf\x0e\x78\x2b\x8d\x6c\xdf\xdd\x43\x96\x1f\x7a\x9e\x9d\x4c\x0a\x65\x9c\x1c\x0d\x27\x69\x42\xa8\x43\x4a\xdf\x1b\x68\x23\x2e\xe0\x78\x1c\x3e\x84\xd1\x6f\x90\xc2\x50\xd8\xa9\x45\xe2\x42\xb7\xf2\xa3\x0e\x94\x94\x42\x51\xd1\x9d\xe2\x78\x87\x87\xbb\x2f\x4a\xb3\x57\xb9\xeb\xc4\xd0\xa7\x0d\x16\xa4\xbc\x58\x59\x8d\x8e\xc8\x2e\x31\x66\xbc\x53\x5f\x23\x82\x10\x41\xbc\x86\xdf\xa4\x3d\x63\xf4\x71\xa1\xd6\x3b\x39\xe9\x0c\x06\x28\x8f\x9b\x0a\xd0\xef\xd9\x6b\x26\x27\x7a\x4b\xfd\x79\xa1\x7c\x1d\x6b\xa7\xf8\xee\xe2\xc5\x89\x8c\x42\x05\x3c\xf0\x9d\x7d\x5e\x96\x3f\xef\x8c\xf9\x78\xf6\xde\xc9\x48\xb4\x03\x35\xd1\x47\x5e\xa0\xda\x94\x85\xce\x8e\xb8\xc9\x64\x7d\x29\x3f\x28\xc2\xa9\x30\x48\x6d\xaa\x4e\x22\x8b\x65\x71\xba\x91\x65\x18\x7f\x02\x02\xda\xe7\xff\x75\x81\x0a\x9a\xbd\xaf\x2b\x0c\xb5\x23\x34\x61\x7d\x73\x6b\xc7\xdf\x73\xcf\xaa\xda\x31\x18\x10\xb0\xc9\x70\x56\x1f\x0a\xf9\xda\x31\x03\x54\x14\x78\xe0\xb7\xbd\x84\x2f\xce\x7f\xc3\x45\xb2\x2a\xf6\xe2\x28\x70\xf1\xd5\xcd\xf5\xde\x32\x99\x55\xec\x25\x54\x50\xd9\x2f\x9e\xfe\xec\x95\x12\x54\x9c\x32\x63\xec\x68\xfb\x43\x83\x1a\xcb\x07\xec\x29\xf7\x51\xce\x09\xc5\x04\xe7\x33\xe6\x6a\xaa\x38\x33\xfa\x40\xe2\x71\xc2\x21\x99\x2d\xff\x80\xef\xbd\x96\xba\x4a\xd2\x98\xa2\xdc\xdd\x4b\x71\x9e\xde\xc0\x55\x22\x52\xcf\x56\x23\x66\x57\xc8\xeb\xbb\xb2\xc8\x6a\x23\xa6\x95\xfd\xcf\x05\x0f\x8b\xe2\x74\xae\xf1\x10\x0f\xdf\x3c\x95\xea\x94\x84\x4d\x16\xeb\xc7\xc7\x6f\x4f\xab\xbd\x6b\x93\x2a\x96\xb4\x25\xe4\x27\x7c\x5b\xe6\x8a\xcc\x85\x7e\x91\x9c\xd8\xcf\xf2\xd0\x60\xbd\x77\xf0\xf3\xc6\x8c\xb2\x37\x2a\x8e\xa9\x43\xdd\x02\x55\x9e\xb2\xfc\x2f\x18\x0c\xf6\xdb\xb1\xa9\x49\xd4\x0c\x7c\xc9\x7a\x3c\x6f\x0d\x6d\xa0\x89\x9e\xab\x71\x2f\xab\x97\xf0\xb9\x53\x30\xa6\x4c\xa6\xe0\x66\xe4\xe8\xcd\x04\xf0\xb0\xaf\xf1\x43\x2e\xa6\x06\x76\x8c\x1f\xdc\x74\x50\x21\x65\xcb\x8f\xb3\x3f\x56\x8f\xdf\x1e\x57\x4f\xdf\x97\xbb\xfd\xe3\xf2\x69\xbf\x9b\x3d\x3c\xac\x7f\xb4\x92\x3f\x4a\xf8\x8c\x24\x43\x1f\x71\xe0\x84\xcb\x94\x88\x95\x97\xb6\xeb\xc5\xef\x57\x39\xba\x28\x91\xfa\xc2\x71\x25\xc9\x3a\x65\x3a\x8e\x54\xd2\xf7\x25\x3d\x2e\xd7\x6f\x5c\xe5\x46\x79\xab\x57\xf2\x55\x32\x56\x8a\xb7\x6f\xf3\x10\xd6\x38\x3d\x2b\xa5\x50\x6a\x9c\x1d\xf4\x8e\xca\x10\x2d\x6a\xe3\x21\xcb\x5f\xad\xb7\xcb\x64\x3f\x47\x49\xc9\xa9\x23\x76\x2e\x6a\xa8\x5d\x2c\xa0\x94\x9f\xd2\x92\xbb\x38\x22\xfc\xcd\xc6\xf0\xf0\xb4\x4a\x05\xc6\xf2\x29\xf4\x6d\x88\x6c\x0f\x60\xa0\xb4\xea\x10\xff\x46\xe3\x7b\xfa\x47\x22\xf8\x54\x95\x25\x0e\x94\x51\x25\x73\xd7\xa7\x3d\x46\x24\xa4\x7f\xb7\x61\x9f\xd2\x00\xbe\x29\xc5\xd5\x87\xec\x34\x62\x19\xa2\x27\xa5\x6f\xe3\xe8\xcd\xca\x26\x0d\xae\x22\x85\xbe\x00\x17\xad\xb7\xdb\x6e\x5f\xf7\x01\x7d\x94\x44\x22\x58\xec\xd7\xb2\x5b\x87\x9a\x10\x4b\x46\x2d\xf8\x61\x32\x3b\xc7\x80\x33\x66\x27\xca\xe1\x19\x4e\x78\x18\xd6\xc9\x30\x50\x1e\x35\xfd\x4e\xf0\x6e\xd8\x1b\x46\x38\xab\xea\x8e\x1b\x4f\xc8\xb2\x79\x33\xd6\x9a\xd0\x81\x93\xef\x2d\x86\xdc\xa7\x7e\x50\x96\xd7\x25\x9e\x33\xb5\x7b\xc9\xce\x56\x8f\xda\x8d\x00\xe0\x4e\xcd\xe6\xe9\xf2\xfc\x91\xb3\x3a\xc3\x28\x34\xa0\xa8\x4c\x16\xdb\x0b\xb1\x69\xed\x1c\x72\xc7\x63\xcf\xe1\xb9\xf6\x1d\x66\x7b\xf4\xcb\x23\x16\xd1\x14\x30\x80\x88\x3b\xfc\x89\xc7\xe2\x8c\x65\xb5\xb8\x8c\x22\x58\x8c\x50\x91\xae\x18\x56\xb2\x2c\xde\xee\x50\x66\xd5\x54\xd5\x68\x78\xfa\x38\x0e\x7c\x7b\x0d\x94\xf3\x7e\x85\xea\x65\xad\xd4\xba\x5c\xfe\x1c\xa7\xfe\x18\x33\x8f\xf0\x62\xe4\x3d\xd5\xfe\x8a\x24\x0e\xb8\x71\xc3\x2e\x4a\x5c\xd5\x83\xd0\x0f\x13\x60\xe4\xd9\x79\x86\xeb\x72\xff\x75\xf4\xd3\x12\x11\x52\x2b\xe0\xaf\x5e\x05\x15\xd3\xd8\xec\xc9\xf7\xab\x79\x7f\x29\xc1\x34\x91\x84\xa1\x3a\xe0\x7b\x56\x8d\x9c\x26\x19\x32\x5b\xa6\x24\x39\x0e\x83\xeb\x1b\x7e\x17\x43\x8f\xea\xff\x8b\xf5\xee\xeb\x6c\xf1\xf4\xe7\x44\x2d\x1b\x21\x76\xd4\x67\x57\xaf\x1f\x98\xae\x30\x04\xe9\x53\xcc\x4e\x9d\xf5\x0f\x6b\x2d\x08\x2a\x75\x46\xa5\xdf\x2a\x2c\x67\x3f\xb1\x09\xbd\x1d\xb0\x67\x7b\x03\x1b\x44\x11\x6b\xd9\x52\xc6\xdd\x4b\x33\x3c\xa7\x00\x41\xce\xb3\x87\x26\x58\xca\xde\xf1\x48\x4f\x6b\x9a\x78\x39\xfa\xa4\x0e\x58\x27\x44\xfe\x75\xd7\xec\xb2\x1f\x0b\x97\x33\x94\x91\xd0\x96\x2b\x4e\x79\xd5\x20\x80\xe9\x76\x6d\x94\x91\x24\x31\x2b\x77\xb7\xe6\x99\xba\x2f\x4a\xd7\xef\x17\xb7\x21\xb7\xfb\x5c\xc2\x89\x1b\x26\x2e\x57\x01\x6d\x91\x05\x65\x8a\x24\xde\x48\xdd\x17\x13\x85\xfe\x8e\xd7\xc3\xff\x62\x59\x3c\xe1\xdb\xef\xad\x3c\x00\x4a\x11\x3b\xcb\xce\xfb\xac\x7a\x99\x4f\x3a\x06\x30\x44\x8c\x55\x27\xa4\xb5\x81\x4c\xcd\x41\xbe\xce\xdb\xfa\x57\x77\x41\xda\x0f\x09\x6d\xbf\xac\x5f\xc4\x70\xff\x42\xcd\x8d\x88\x70\xb3\xde\x19\xe6\xde\xc3\x58\xb2\x02\x35\x68\x4a\xb5\xce\xa6\xa2\x7c\x08\x0e\xa4\xbe\xee\x8e\xea\x84\x40\x29\x35\xbc\x5a\x63\x46\x7b\x44\x7b\x29\x17\x7d\x87\xc1\x4e\x29\xdd\x0e\xf0\x83\x80\xf8\x2b\xf9\xe5\x44\xdd\x6b\xac\xc7\xa6\xfa\x4c\xfb\x3c\x24\x00\xb1\xf3\x55\x22\xd6\xe6\x61\x31\xdb\xb4\x03\x14\xa7\x54\x82\x0a\x47\x44\x2c\x6b\x81\x4a\xd9\xf3\x4b\x7d\xbc\x6e\x06\x14\xc8\x91\xca\x35\xd3\xbe\x36\x53\xbe\x26\x05\x9c\x01\x5c\xc0\x8e\x08\x54\x4c\x80\xac\x73\x89\x2b\x69\x64\xe6\xaa\x45\x4f\x06\x4f\x87\x81\xc2\xa4\x6d\xff\x9a\x8e\x9a\x5b\x98\xfc\xe0\x63\xc3\xab\xfe\x42\xa2\xa3\x44\xc4\x7a\xa0\x1e\xfa\x98\xe5\x23\x45\x75\xa6\xe3\x50\x12\xb8\x25\x27\xe1\x2f\x43\x7d\x99\xe5\xd7\x7d\x31\xcb\x47\xad\x30\x1d\x4b\xd3\xb8\x32\x53\xed\x09\xdf\xad\xd6\xe2\x2f\xe4\x34\xed\xa7\x93\x30\x24\xf5\xa5\x3f\xff\x18\xb0\xf4\x74\x92\xa6\xa1\xe8\xbb\xe4\xb8\x74\xec\x56\x57\x97\xe9\x84\x31\x2b\x31\xf4\x13\x06\x20\x1d\x9d\xd8\x62\xec\xb7\xdc\x98\xe0\xb4\x52\xca\xe3\x2e\xcd\xe8\xb2\xd2\xd0\x0f\x9a\x1f\x65\xb8\x26\xf3\x4b\x99\xcf\x49\xaf\xdd\x88\xea\x7f\xf4\x19\x46\x3d\xc1\xa1\x68\xf2\xc8\x28\x82\x69\x06\x9c\x9a\xed\x5f\x70\xe8\x44\xc4\x34\x0f\x52\x0a\x0a\x9c\xfd\xed\x73\x0b\xea\x33\xdb\xdd\x7d\x51\xee\xb2\xe3\x4f\x2c\x29\x59\xe9\xdb\x6b\xf4\xb0\x03\x9a\x47\x71\x62\xec\x3b\x6c\xe8\xe0\x58\x8c\x83\xd7\x5a\xf3\xc4\x78\x4c\xf7\x40\xae\xc9\x04\x23\x45\x73\x61\xf8\x78\x5d\x97\xbb\x7f\x61\x83\x56\xb7\x16\xbe\xf2\xb4\x73\x1c\xfc\xd6\x19\x0e\x36\x47\xb4\xd1\xe6\x39\x17\x79\x55\x94\xd5\xc8\xf0\x95\x69\x11\x1a\x71\xd1\xaa\x2e\x86\x0a\xf0\x4c\x8b\x88\xfb\xba\x13\xc4\x98\x5c\xa5\x34\xd5\xf1\xff\xdf\xff\xef\xff\x3d\xcd\x67\x7b\xcf\xf3\xff\x6f\xe1\xa1\xa6\x4a\xaa\x7d\x29\x5e\x5e\x0d\x14\xf4\x33\x54\xaf\x96\x7e\x42\x4e\xc5\x27\x72\xbd\xd9\x17\xc6\xd1\xca\x5d\xb1\x4c\x34\xed\x31\xff\x7a\x9a\xcf\x56\xed\x1f\x79\x04\x06\xb1\xd7\xa4\xdf\xbd\xcd\x80\x6c\x01\x96\xef\xe7\xec\xd6\xd8\x82\x69\x95\x06\x20\x1d\xd0\x88\x52\xb3\xc8\x71\x52\xb4\x42\x41\x88\xc9\x37\xcc\x1e\xe1\xbd\x35\xa5\x63\x1a\x03\x4d\x8b\xd9\xef\x57\x81\xe5\x17\xcc\xb1\xca\xaa\x89\x7d\x5a\x63\x12\x3a\x25\x61\xe3\xdb\xb9\xfa\x80\x0f\xaa\x75\xe2\xd3\x1b\xf6\xa3\xe5\x25\x0d\xcd\xe4\x46\xb7\x47\x63\x14\x58\x25\x85\x45\x81\x7a\x8b\x6f\x83\x9f\xc5\x3d\x2f\xe6\x34\x60\x5f\x3c\x3f\x77\x2c\xaa\xae\xfc\xd8\xce\x67\xee\x79\xc2\xec\x3f\x36\x08\xa0\x0e\x4d\xb3\x0b\x4d\x16\x16\xb8\xe7\x7b\x8a\x6a\x1c\x7f\x15\x59\x6e\xde\x56\x77\x00\x7c\xd6\x9b\x46\x93\x2f\x31\xf7\x02\x0f\x43\x87\x98\xe9\x07\x99\xdc\x0b\xb9\x0e\x3b\x24\xc9\xc1\xda\x4e\x1f\xca\x1e\x5d\xaa\xbf\xd2\x72\x2f\x12\x9c\x0a\xbf\x5f\xfe\xb8\xfb\xba\xdd\xf4\x56\x37\xee\xc5\x9c\x19\xd7\xdd\xca\x4a\xbc\xb8\xd0\x88\x7b\x89\x25\x08\x1b\x59\xbb\x22\x1b\x82\x09\xb9\x97\xf2\x84\x02\xf8\xdd\xa6\x2b\x41\x70\x8f\xf9\x82\x4c\x52\x2a\xd0\x38\x14\xeb\xe3\x1e\x0b\x83\xc4\xec\xab\x57\xd3\x9c\xb9\x2f\xca\xcf\xf4\xfa\xb8\xc7\x22\x43\x2f\x3b\xff\xac\x0f\xe7\xe3\xa9\x36\x75\xba\xc3\xb3\xe9\x5d\x76\xd7\xca\x23\xa3\xa8\x62\x9a\xb3\x46\x33\xae\x3d\x96\x44\x04\x7d\xb3\xdd\x38\x63\x0c\xdc\xf7\x66\xe6\x1e\x57\x89\xa7\x06\x4a\x16\x5f\xa0\xea\xa9\x0c\x70\x0f\x02\x1d\x5a\x93\x0b\xf5\x54\xf4\xb2\x99\xd1\x53\x13\x81\xd0\x96\x41\x4f\xb2\x65\xbf\x8d\x0f\x1b\xa1\x81\x0a\x1d\x0a\xaf\x43\xc1\x71\x4f\x86\x9a\x76\xf6\xfb\x6f\x4f\x77\xab\xa7\x2f\x03\x6d\x22\xee\x49\x34\x0d\x9e\xdd\xa9\x13\xa2\x6a\x8f\x69\x8f\x4a\x54\x0f\x30\x12\xf5\xe0\x9e\x52\x68\x34\x98\x9b\x3b\x47\xde\xe4\x65\x35\x1a\x82\x01\x0f\xa4\xc9\x27\x9f\x31\xdc\x75\xca\x1a\xdc\xd3\xbe\x4f\xab\x99\x0b\x09\x9f\xbe\xef\x75\x59\x9c\xbe\x4c\x78\xc8\xba\x4f\x84\x41\xca\x1c\x90\xa6\x75\xae\x19\xcc\x1c\x1d\xc5\xc9\x80\x70\xd1\xfe\xdd\x10\x31\x1e\xa1\xae\x5f\xf0\xad\xfd\x33\xc4\x96\xf4\xe7\xcc\x3d\x9b\xb0\xc5\x70\xf4\x6e\xac\x53\xb8\xef\x69\xa4\xe5\xad\x99\x81\xed\xe6\x6a\x8f\x05\x18\x5b\xa3\xba\x7a\x53\x62\xbb\x31\x4d\xad\xe4\xcd\x60\xe5\x39\x31\x95\x47\xf7\x90\xfc\x10\x58\xca\x5b\xe0\x3c\xc9\x36\x0d\x3f\x16\x0a\xee\x5b\x88\x22\x69\x36\x18\xb4\xfe\xa5\xa3\xb6\xb6\xf7\xca\x8f\x12\xe1\x44\x38\xb6\xa8\x37\x70\xdd\x4d\x58\x4a\x71\x3f\x0e\xb5\xe8\xb6\xe3\xaf\xc5\xa5\xc2\xf1\x88\x28\x32\xac\xfc\x43\x89\x0a\xf1\x34\xd1\xa8\xe4\x7e\x2c\x35\x95\x19\x9d\x85\xce\x7c\xb9\x3f\x7c\x9f\x3d\x7c\x5b\xba\x9f\x96\x84\x48\xc5\x8d\xe6\x07\x7f\x3b\x9b\x73\xec\xea\xb2\xe7\xc4\x3d\x3c\x61\x1a\x04\xce\x13\x75\x7d\x54\x3b\xc4\xe3\xed\xda\xce\xfd\x34\x8a\x8d\x4b\x45\x51\x98\x36\xd8\x4f\xdc\xd1\x16\xfe\x61\xff\xe8\xa3\xbf\x8f\xd5\xc9\x9a\xbc\x1e\xa8\x93\x6f\x60\x3d\xf7\xf3\x87\xe9\xd7\xd2\xe7\x9e\x36\xd5\xa6\xe6\xdd\xd9\x99\xad\x7f\x74\x99\xdc\x17\x3e\x6b\x63\xda\xef\x45\xdd\x83\x63\x8e\x6b\x75\x13\x95\xd9\x51\x8d\x96\xfb\x3c\x36\x93\x59\x15\x56\xc8\x66\xec\x80\xf4\xc1\xaf\xb6\x1f\x87\x38\x8a\xad\x84\xc5\x43\x51\x55\x3d\xd8\xb3\x7b\x5a\x90\x72\xda\x09\x15\xca\xf2\x7a\xae\xbf\x36\xaf\xfe\xe7\x7e\x18\xf6\x83\x82\x19\x38\xe9\xc5\xc0\x7e\xee\xcb\xe2\x14\xec\x8b\xd0\x9d\x57\x48\x95\x26\xed\x62\x58\xdf\x17\xe5\x16\xcf\x45\xd9\x2c\xa9\x1b\xa7\xd7\x90\xd7\xe6\x5a\x7a\x58\x76\xee\x4b\x2f\x08\x44\x2b\x7b\x48\x57\xdc\x86\x02\xdc\x97\x41\x42\xa4\x1a\xf5\x50\x3c\x3f\xb5\x7f\x0c\x43\x8e\xfd\xe0\x7a\xff\x4e\x48\x8f\xd1\x0c\x98\xb8\xbd\x52\x84\x46\x88\xc7\xda\x9b\xcd\x7e\x42\x0d\x43\x19\x1b\xee\xab\x48\xd1\xea\xe5\xc0\x94\xf2\x75\x84\x86\xe2\x3e\x32\x23\xd2\x74\x82\xf7\xc7\x22\x27\x52\x45\xbb\xac\xfa\x3a\x61\x14\xf0\xd5\x86\x6b\x5c\x16\xa7\x79\x66\x0b\x15\xed\x77\x68\x66\xc1\x51\xcd\x77\x0c\x30\xc4\x03\x4b\x0f\x1e\xf8\x71\x42\xf7\xf5\x6c\xd2\x91\x6a\x7e\x75\xce\x13\x2e\x6f\x72\x03\x39\xa7\xe8\xbb\xee\xf3\x4f\x48\x0c\x61\xad\x75\xb3\xaa\xe4\xca\xec\x4d\x93\x8f\x37\x08\x62\x8f\xea\x3f\x8b\xed\x9f\x9b\xfd\x7a\xfe\xed\xe1\xc1\x5d\x41\x90\x98\x6a\xc8\x43\xf1\xfc\xb1\xb5\xf3\xf8\x6c\xca\x28\x25\x53\x6f\xc2\xac\xbd\x8e\xcb\x3c\x49\x5f\xe6\x41\xa0\x03\x32\x06\x51\x66\x8f\x35\xba\x3f\xf6\x58\xe8\x99\xf5\xf7\x19\x9b\xad\xbc\x86\xe3\xa1\xea\x21\x45\x79\x10\x0a\x06\xb6\x29\x30\x5f\xfc\x39\x7c\x54\x41\x14\x01\x17\xed\x3e\x40\x15\xbc\x72\x3c\xc4\xd2\x29\x4c\xcf\xb3\xc6\x3d\xc2\xe9\xbb\x31\xec\x1a\xbe\xee\x41\x24\x03\x7a\x1a\x1a\xe5\x0b\x91\x4e\x8c\xe1\xda\x75\x97\xc3\xb9\x7a\x29\xea\xdb\xb2\x02\x0f\xe2\xc4\x27\x10\xf3\x11\x4e\xa2\xa8\xe6\x97\xec\xa8\x7a\x69\x31\x0f\x12\x5f\x39\xbd\x0b\xd7\xfd\x72\x40\xdc\x11\xb0\x60\xaa\xe3\x3e\xbc\xbe\x84\xf9\xce\x3b\x79\xa9\x9e\x71\x83\xa5\x53\x4b\x18\x5d\x54\x02\x32\xf0\x1c\xa0\x68\x95\xb7\x30\xa7\x26\x87\xd3\xaa\x93\x99\x6b\x56\xa1\xc9\x7d\x2e\x60\x49\x1c\xf7\x3b\xcb\xb3\x60\x3e\xbd\xe0\x07\x8c\x85\x10\x58\xca\xe1\xdf\x25\xd7\xd8\x8f\xf2\x14\x5c\x34\x69\x4a\x55\x66\x31\x1f\x8c\x81\xd0\xa4\xda\x67\xb8\xde\x17\xe5\xfa\xfc\x19\xf3\x79\x74\x7a\x48\x38\xa9\x78\x99\x94\xd7\x48\x60\x4c\x5e\xe1\xb4\x69\x2f\x0f\x20\x0d\x49\x46\x6a\xb5\x58\x3f\xad\xfe\x65\xf4\x56\x17\x0f\xeb\x5d\x13\x87\xed\x57\x8f\x6e\x8f\x0c\x20\x35\xf8\x54\xfd\x7e\x7e\xbc\x1c\x9d\x11\xd4\xe0\x9f\x76\xa4\x89\xba\x9b\x9c\x86\x54\xb6\x9d\x3b\xb3\x3b\xce\x15\x1a\x44\x03\x15\x80\x9b\x35\xa1\x87\x14\xe3\x01\x08\xa4\xe6\xc7\x17\xac\x97\x3f\xe1\x78\x71\xe1\xbd\x33\x1a\x70\xc3\x94\x69\xa5\x4e\xb4\xf9\xff\xde\x93\x11\x61\xcc\xad\x35\x6a\x5d\x5e\x9a\xcb\x78\x84\x3c\xd3\x6d\x5d\x8b\x07\x82\x2b\xc2\xfc\xec\xbf\xef\x5f\x4a\xac\x5e\x5a\xf5\x00\x1e\x08\xc1\x24\xef\xd3\x4f\x48\x05\x66\x78\x6b\x65\x18\xea\xe6\xe3\x94\x04\x3d\x5c\xe4\xeb\xd5\x14\xf4\xb7\xb4\xd3\xde\x6a\x58\x4d\xef\x88\x81\x8c\x62\x91\x76\xd5\xb5\x81\x7f\x39\x0f\x64\xd2\x26\xce\x5f\x2e\x58\x55\x36\x65\x9a\xfe\xc9\x92\x0b\x22\x77\x51\x6d\x6d\x77\xb8\xff\xb6\xff\xb6\x6d\x9f\xb0\x04\x4d\x58\xd1\x6f\xe7\x63\x01\x6a\xf5\xf8\xa5\x3d\xa0\x02\xd3\xf1\xec\xb9\x70\x56\xa4\xc6\xfe\x61\xab\x96\x07\x28\x39\xf1\xa6\xce\x25\xf6\x75\xb3\xda\x1b\xa8\xb5\xf6\x7b\xca\xd9\x4b\x03\x85\xfd\xb6\xbb\xfb\xad\x6d\x08\xde\x5c\x7f\xe8\xa5\x2c\xb4\x12\x33\x8f\xf0\x2e\x47\x38\x44\x1e\x7a\x10\x92\x3a\xbf\x05\xd0\x3f\x7e\xf2\xba\xda\x4f\xf8\x1c\xa8\x27\xb1\x5b\x2e\xd6\x4f\x77\x87\xfd\x6a\xb9\xed\x19\xf0\xf1\xd0\x47\xa0\x32\xc3\x25\xa7\x7d\x2e\xfb\x5f\x74\xba\xd6\x83\xd0\x3e\xf4\x51\x09\xd3\x1f\xa3\x22\xd7\xa8\x74\x31\xf9\xee\x86\x41\xe8\x53\x55\xf4\x4b\x13\x30\xbf\x12\xe4\xe4\x15\xf3\xc7\x4b\x9d\x9d\x8f\x59\x1b\xbb\x87\x41\xc8\x48\x9b\x75\x5b\x5c\x9b\xbc\x3b\xef\x93\x6e\x27\xc0\x08\xcd\x07\x8c\x28\x39\xd9\x27\x75\x09\x61\x18\x44\x92\x0a\x8f\x04\x48\x9e\x67\x65\xcf\x14\x89\x87\x41\x2a\xb8\x75\xd6\x6e\x32\xe2\xa1\xbe\x0d\x0f\x43\xc1\x22\xa7\xfb\xb5\x2f\x46\x5b\xcb\xa7\xc2\xa4\x3c\x8c\x63\x45\xaa\x5d\xfa\x92\x53\xb9\xe5\xbe\xb8\xb4\x3f\x2e\x66\x5c\x9a\xbc\x51\xfd\x70\xd6\xeb\xee\x10\x20\x13\xbd\x19\xd2\x57\x47\x99\xfa\xd9\xb1\x56\x84\xfb\xf8\x81\xd9\x8d\x83\xe3\xf0\x82\x52\x48\x50\x38\xca\x9a\x7c\xbd\x9c\x0f\x99\x25\x67\x7c\x4e\x2a\xe2\x21\xf3\x52\x12\x5c\x7c\xc3\x6c\x5f\x6c\x8d\xcc\x92\xb1\xa7\x1e\xee\x2d\x21\xf7\x8d\xd2\xce\xec\x78\xdc\xc0\x75\xd6\xf7\xb3\xe1\x21\x8f\x38\x37\x4c\x83\xe6\xcb\x35\x94\xa7\x1d\x49\x34\xfe\x62\xbe\xf0\x48\x3a\x33\x9d\x05\x94\x65\x51\x2f\x4a\x54\x99\xab\xa0\xf3\x10\x02\x9f\x88\x97\xb3\xbb\x7d\xfb\x27\xa6\x48\x6e\xbb\x79\xbd\xb0\x84\x5b\x0c\xd1\xf0\xaa\x41\x0a\x6b\x9c\x25\x9c\x88\x47\xa1\xb3\x7a\x02\x65\xcb\x43\xd0\x61\xdc\x59\x53\xee\xb2\xe7\x7e\x82\xfd\x8f\xde\xcc\x12\x51\x44\xd9\xd2\xc3\x45\x5d\x4e\x7f\xab\x75\x6c\x3f\x28\xc1\xf0\x47\x66\xb2\xbe\xc0\xf1\x5f\x17\x6c\x43\xee\x50\x79\x81\xa5\x74\xe4\x6a\xb5\x58\xcf\xaf\x1f\x4b\xff\xf0\x50\x61\x20\xc3\xbe\xe3\x72\x76\xba\x9c\xfe\x75\x29\x6a\x18\x2d\x1f\x18\x28\x63\x0b\xa5\x4e\x59\xbe\x54\x59\xbd\x70\x84\x5e\x7f\xac\x7a\x32\xba\x54\x4c\x52\x72\x6f\xd4\x25\x22\x09\xc5\x74\x44\x3a\x1e\x22\x06\x04\xd9\x04\xa5\xa8\xd2\x6f\x17\x07\xbb\xa7\x0d\x97\xd0\xb6\x5f\xc1\x43\xed\x87\xce\xaf\x64\x53\xbc\xe2\xa9\xc8\xe7\x48\xce\xa2\xd5\xe8\xb2\xb5\x2f\xc8\xfa\x39\xcb\xe5\xfc\xda\xe2\xf7\x78\xa8\x53\x20\x48\x42\x65\xb5\x74\x48\xe5\xed\x0e\xae\xed\x71\x0e\x14\x0a\xb6\xc8\x1b\x63\xad\xa4\xa6\x1e\xa2\x96\x9c\x44\x79\x47\x3d\xad\xcc\xe2\x35\x9f\x8a\xaf\x23\x15\x34\x1e\x79\x68\xe8\x92\xae\x84\x32\x1d\x5b\x45\x3e\xf7\x98\xf3\xa7\x79\x2a\xf2\xfb\x4b\xfe\x3c\x68\xb9\xb5\xf7\xc7\x8d\x97\x9e\x6b\xf3\xd2\x43\xef\x97\xf5\xa2\x40\x18\x54\x17\xe6\xea\x0e\xae\xeb\xbc\x47\xb6\xe4\x51\x18\x18\xc3\x1d\x17\xef\xf5\x0b\x5d\x51\xc4\x53\xed\x28\x53\x26\xab\x6e\x52\x05\xe3\xad\x51\xdd\x17\x25\x66\xcf\xb9\xd7\x0e\xd6\x46\xa1\xdc\xe0\x33\x48\xef\xc9\x1e\x89\x23\x1d\xf6\x99\xea\x9f\xaf\x27\x51\x1c\x1b\x85\xf9\x0a\xeb\xaf\xc5\xf1\xd6\x1c\x86\x47\xb1\x08\xa8\x72\xf6\x17\xc8\xd7\x73\x61\x7a\x7a\xcb\xfa\xa5\x33\x9c\x6b\x86\x00\xb5\x4a\x80\x52\xc1\x16\x09\xc7\xa3\xd8\x4a\x26\xf5\x7c\xea\xfa\xde\x4a\xa3\x6b\x49\xc2\x94\xaa\x61\x36\x38\xa0\x48\xf0\xeb\x6c\x7b\xd7\xf5\xe0\x78\x94\xa8\x84\xee\xef\xb1\x78\xee\x3c\x34\x6c\x7e\xd4\x81\xfb\x08\x15\xe8\x76\xfa\x28\x65\x9c\x72\x93\xdf\x2f\xf9\xb3\xbe\x0c\x1e\x17\x53\x26\x19\x31\x2b\xbb\x31\xd7\x9c\x7c\x87\x23\x86\x31\x3d\xf5\xec\x74\x36\x3d\x10\xfa\xe6\xc0\x9d\x88\xfb\x56\x89\x75\x71\xd7\xa5\xde\x11\x84\x81\xf1\xc9\xb8\x88\x53\x56\x2f\xca\x62\x92\x48\xdf\x8c\x33\x65\x50\x8b\x0e\xa2\x02\xd1\x6e\xf5\xef\x65\x7b\x1e\x60\xf4\x0b\xe6\xc7\x6c\x7e\xcc\x26\x39\x5d\x76\xa4\xe0\x29\x85\x85\xab\xbc\x2e\xcc\x82\x35\x3d\xe9\xa5\x6f\x3c\x75\x0d\x32\x6e\x83\x54\x28\x31\xad\x2e\xf7\xa5\x92\x19\x99\x93\x6d\x21\x8a\x7a\x5f\x82\x72\x01\xc2\x6f\xa3\x53\x71\x74\x0e\x39\x56\x8a\x85\x34\x48\xa6\xbf\x57\x05\x8a\xb6\x71\x5d\x94\x27\xa8\xad\x3a\x28\xfd\x84\x68\xf4\x4b\x54\x6a\x0c\x1f\x2e\xb9\x9b\xca\x6b\x41\xf1\xe7\xa8\x7e\x14\xa9\x14\x7c\xcf\xe1\x15\x3a\x2d\xb6\x4f\x3a\x64\x3c\x52\x3a\x26\x0a\x4b\x76\x22\x23\x9d\xb2\x6a\x76\x9b\xea\x01\xeb\xe6\x6b\xb4\xd9\xd6\x7e\x6b\xc7\x26\xa9\x6d\x92\xcf\x5a\xa7\xd8\x66\x71\x26\xe5\xe8\xaa\x1b\xc6\x0d\x63\xb3\xf8\x4c\x07\xef\x53\xc4\x2d\x8f\xd0\x63\x44\x28\xfd\x9f\x0b\x96\xd7\x1f\x90\x35\x41\x4e\x7f\x05\xc1\x28\x56\xa4\xa7\x23\xe1\x58\x67\x79\xa1\xdd\x01\xed\x45\x18\xd9\xfd\xc8\xda\x51\x7f\xd2\xbd\xe2\x91\xf6\x91\xf6\xaf\x87\x4c\xe3\x06\xaa\xea\xad\x28\x95\x6b\x54\xf1\x48\x27\x9c\x6e\xe9\x66\xbd\x7a\xda\xef\x0e\xfb\xf5\xe1\x61\xf9\x7d\xe9\xca\x19\xb1\xe7\x99\x46\x38\xd6\x2f\x07\x23\x37\x76\xf8\xeb\xa2\x9e\x5b\x26\x0f\x73\xe3\x94\x08\x8c\x0d\x84\x01\xf4\x5a\xba\x9b\x3b\x8d\x1f\xf9\x9e\x73\x66\x97\xc5\xe5\x5c\xf4\x68\xb7\x23\xcf\xe3\x66\x30\xd2\xc4\x76\xfa\xbb\xf3\x61\x37\x93\xc7\x7e\xac\x49\x1a\x1f\x94\x22\x3c\xde\xf8\xb0\x66\xb1\x4d\x53\x0c\x33\x85\xba\x48\x6d\x52\x30\xfc\xb2\x20\x48\x6d\x75\x8c\x34\x28\xb4\x1e\xe9\x34\xf3\x38\x68\x62\xb1\xb6\xfe\x49\xff\x7b\x29\x3f\x88\x6a\xe2\x90\x07\xa9\x53\x14\xdc\x16\xc5\xe9\x53\x1c\x11\x8f\xa3\xc8\x13\x56\x3a\x2f\x3b\xc1\xd1\xca\x85\x0e\xbf\x3f\x8a\x3d\x2a\x90\x11\x4e\x79\x5b\x5c\x8e\xcd\xd4\x9d\x63\x4d\xbc\xa6\x81\xd9\xb6\xfd\x40\x1c\xa5\xda\xee\x5a\x5f\xe0\x84\x7d\x3d\x35\x3b\x22\x89\x81\x32\xf9\x27\x7c\xa3\xa9\xf3\xa5\x84\x5b\xa9\xf0\xe9\x6d\x24\x4e\x92\x90\x70\x5c\x3f\x30\x7b\x7e\xa9\x51\xed\x9a\x05\xaf\x47\xe5\xe5\x71\x02\x06\x9e\xe8\xa4\xbe\x37\x59\xde\x17\x31\xe0\x71\x22\xfd\xd0\x26\xb4\xa4\x8a\x75\x8b\xfe\xe6\x71\x82\x52\x19\x64\xfd\x4f\xc3\x9d\x6f\x31\x01\xe3\x81\x5a\xc6\x81\x8b\xea\x9d\x2c\xec\xf1\x08\x35\x96\x3d\x4b\xee\xc9\x57\x23\x4e\x23\xdf\x14\xde\xac\x23\xe0\xe0\x2a\x53\xa5\xe8\xd9\xb8\x98\x62\x76\x3c\x36\x8b\xcd\x68\xb2\xb1\x38\xa4\x2e\xb8\x68\xde\x8d\xeb\xa4\x9c\xcd\x6d\xc6\x1a\xb3\x04\x5d\x0d\x6e\x67\xde\x87\x0e\xc8\x62\x3a\xf8\xa3\x5f\xc9\x52\x53\x81\xd8\x35\x73\xba\x09\xc9\x55\xf3\xf8\x17\x45\x5e\x8f\x61\x9f\x3c\x66\x1c\x89\x05\x5f\xe4\x12\xd7\x97\xba\xee\x16\x95\x98\xfb\x0c\x8d\x72\x8d\xc2\xf7\xb5\x6e\xa2\x09\x5a\xc1\x87\x5f\xc6\x43\xcf\x1b\xc0\x31\x76\x58\x5f\xce\x56\x89\x84\x42\xce\xf1\x07\x34\x46\xc2\x05\xb3\x07\x72\xb3\xb3\xc8\x8b\x89\x15\x39\x86\x38\x26\xf3\x66\x71\xb9\x42\xae\x10\xca\x51\xb9\x2d\x86\x34\xa5\xaa\xcd\xe3\xec\x61\x4a\x69\xa9\x9f\x89\xc5\x90\x32\x02\xa4\x9c\xb2\x63\x93\x55\x59\x54\xae\x05\x29\xf0\x18\x74\x42\xf1\xb0\x5b\x95\x5a\xfb\x96\xb1\x3e\x7e\xff\xfa\x34\xb3\xa2\xda\x47\xed\xa6\xd4\x00\xbc\xd1\x0c\xc1\xc0\x21\x3a\x8b\xf2\xb6\x62\x18\x8b\x28\x74\xc2\x34\x07\xc3\x6a\x46\x75\x38\x1f\xe1\xda\x86\x6f\xb1\x88\x21\x6e\x2d\xcd\xa8\xae\x34\xcb\xab\xb7\x71\xb9\x35\x16\x31\x7a\xca\xc6\xac\x5d\x95\xda\x4a\xe4\x7d\x9e\xc5\xc5\x42\x48\xde\x69\xf6\x53\x23\xa1\xa7\xf5\xcb\x63\xe9\x43\x4a\x1a\x19\xdd\xe4\x2b\xca\xe5\x6e\x31\x17\xd7\x5d\x67\xb6\xc4\x63\xf4\x20\xee\x68\x0e\x9f\x3e\x0f\x4c\x42\xcf\xf6\x0c\x24\x56\x15\xb1\xc0\x7f\x3a\x3a\x05\x8f\xb5\xd0\x49\xda\x8b\x59\xe7\x50\xca\x42\xe1\xb8\x6f\xf3\xeb\x7f\xdc\xf9\x30\x40\xc3\xf9\x50\x4f\xf8\xd6\x59\x68\xfd\x6a\x4f\xee\x1e\x77\xe2\x71\x4d\x48\x1e\x2b\xed\x33\x1d\xcd\x24\x7e\x04\xd2\x72\xe6\xc9\xea\x7a\xba\xc1\xe4\x06\x27\x82\x56\xe0\x59\xa6\x96\x3f\xa1\xd7\xba\x4f\x7c\x66\xec\xfa\xef\xbe\xdc\x89\xc3\x2f\x84\x27\x3f\x3a\x39\xf7\xa9\xb0\xb6\xca\x05\x56\x75\xbf\x1b\x32\xbd\x27\x25\x21\x57\xac\xcd\xe5\x73\x03\x5e\x99\x6a\x5e\x26\x21\x00\xb1\x5d\x17\xeb\xa7\xfb\xd5\x97\xc3\xe3\xec\x8f\x83\xb1\x4d\xda\xb9\xcb\x8f\xfd\x40\xf6\x4a\xc0\x58\x76\x29\x5e\x12\x47\x61\xca\x5c\x23\xa8\x99\xa3\x24\x7a\x92\xd5\x57\xab\xc1\xf1\x09\x03\xee\x33\x4e\x20\x4f\x62\x0c\xa9\x09\x67\x22\xf7\x5b\x0e\x22\x4f\x12\x2f\xa4\x5b\xa2\xb1\x96\x2f\xb3\xe3\xd1\x7a\x60\xb9\xa3\x81\x64\xba\xc5\x34\xd2\x8c\xc4\x71\xd0\x91\xa4\x41\x14\xd9\xd0\xf6\xd1\xea\x8f\xd8\x84\xec\x66\x20\xa3\x5e\x40\xa7\xdf\x3f\xdb\xee\xe9\x37\xcf\x6f\x14\x1e\x79\x92\x26\xa6\x56\xe7\xac\xd2\x9b\xfb\x72\x07\xd9\xdf\x8e\x19\x7b\x45\xaa\x24\x4d\x53\x65\x98\xe7\xd7\x7f\xba\x0c\xcd\xca\xb5\x4d\xcf\x94\x34\x35\xa4\x2e\xeb\x56\x6f\x78\xde\x37\x04\xec\xe1\xcd\x66\x5e\xa8\xec\x7d\xf8\x67\x21\x2c\x28\xa5\x9a\x5f\x6d\xad\x77\xb2\xdc\xef\x3e\x1a\xb2\xc0\x88\x46\x64\x39\x61\x54\x87\x57\xc3\x40\x09\x43\x3e\x7d\xdf\x60\xb9\x7f\x77\x8f\x87\x69\xa3\x89\x6a\xd8\x0e\x7d\x9d\x6f\x9e\x80\xcf\xfc\x56\xba\x6c\x62\xaf\x4b\x40\x68\x4f\x5a\xe9\xd0\xba\x03\x1b\x4c\x12\x22\x78\x22\x92\x90\x52\xb7\x2f\xab\x87\x87\xd5\xfa\xa9\x67\xd6\xc1\x13\xe9\x27\x84\xa4\xcb\xaa\x55\x6e\xc3\x6a\xf2\x17\x69\x8f\xa3\x94\x7e\x27\xb1\x37\x78\x7f\x86\xdd\x73\x17\xb9\x25\xca\x97\x54\x25\x24\x8f\xfa\xfe\x82\x9a\x28\xa5\x53\x1b\xa2\x99\x6a\xd6\xb4\xbf\xf1\xe8\x7c\x28\x3c\x2f\x6c\x55\x3a\xd1\x12\xd5\x86\x3f\x51\xfb\x11\x89\xbd\x6d\x97\x0f\xcb\xd9\x6e\x79\xf8\x32\xdb\x1d\xee\x97\xcb\xf6\x0d\xd6\x81\x26\x9e\x14\x25\xc0\x43\x5f\x83\xe1\xec\x49\xbd\xc4\x94\x61\x4b\x94\xc5\xe9\x84\xb9\xba\xbf\xe4\x6a\x5f\x6c\xcc\x26\xf6\x69\x72\x93\x7a\x42\x90\xb5\x82\x29\x5a\xdc\x65\x95\xb4\x38\x87\x8b\x1c\xbd\x78\xa9\xef\x7b\x10\x3a\x6b\xe2\xf3\xb1\xb8\xa2\x9a\x1f\x0b\xa7\x17\xc2\x53\x3f\x8e\x62\x5b\xb3\x99\xd9\x30\xad\x2f\x9e\xc7\x53\x9f\x69\xd9\x41\xfd\x07\xf3\x27\xf5\x85\x47\x1b\xd7\xae\x2e\xde\x09\xd3\x33\xf8\x64\x80\x46\x7e\x9c\x82\x02\x1b\xb9\xf5\x20\x4b\x69\x04\x3e\xb5\xe2\x36\xdf\xb6\x8b\xaf\xcd\xcd\xb4\xc4\xee\x6f\x4f\xab\x7d\x37\x06\x43\xd9\x09\xf3\x10\xc2\xeb\x23\x6d\x6d\x9e\xc6\x60\xb8\x00\x4d\x7a\x40\x10\x27\xe7\xba\xc1\xd3\x58\x9b\xbe\xdf\xea\x69\xb5\x5f\xcd\x1e\x2c\x26\x79\xf7\x6d\xb3\x79\xf8\xd3\x8d\x49\x7c\x2f\x32\x2b\xd9\xcf\xe2\x15\x9d\x8a\xd7\xcd\xfe\x31\x45\xb6\xe1\x69\x22\xc3\xb4\x79\xf2\xff\x7e\xf8\x3a\xb8\x0b\x29\x53\x14\x60\xe8\xec\xdd\x3c\x5b\xea\xb7\x96\xd7\xd5\x07\xc5\x9b\x94\xf9\x08\xad\xe2\x8f\xbc\x94\x50\xb7\xbc\x06\x9e\xb2\xc0\xa7\x4a\xa2\xce\xb4\x53\xaa\xe1\x29\x43\x46\xa8\x98\x03\x28\x45\xec\xcc\xe1\xa4\x4d\x79\x14\x11\x67\x68\xb1\x5d\xce\xf6\xee\x36\xff\xd6\x1e\x4c\x08\xc9\xa4\xc9\xee\x6e\x5f\xfc\xc0\x6c\x74\x57\x79\x0c\xdc\x6a\x3b\xee\x8e\xd9\xf9\x0c\xcf\x16\x06\xbb\xca\xe7\xe7\xf6\xca\x78\x9a\x10\x6d\x87\x24\xb6\xef\x0a\x57\x91\xb0\x47\xc1\x0b\xb4\xe9\xd0\xd1\x2c\x6b\xe7\x00\x70\xc3\x12\x15\x4d\xdc\x74\xab\x7f\xc4\x53\x11\x1a\x70\x63\x57\xbc\x58\x9e\x68\x1a\x8f\xf0\x43\xa9\x48\x62\x05\xed\x6a\xf0\x52\x94\x75\xdb\x6d\x76\x23\xd2\x90\x7b\x83\x1a\x9a\x7b\x73\xac\x00\x90\x49\x94\xdc\x68\xcd\xb1\x5d\x5d\x3e\xec\xef\xf5\x36\x90\x54\xa6\x01\x49\x67\x1c\x8a\x7c\x0e\xad\x0e\xcd\x07\xff\xfb\x9f\xf0\xbf\xf4\x7f\xfe\x7f\xdd\xa7\x51\x18\x19\x7d\x3c\x1e\x61\x67\x4d\x9d\x87\xfe\xe8\x1f\x49\xa1\xf2\x54\x79\xb1\x69\xd1\x41\x59\xf5\x8c\xcc\x87\xcf\x51\x31\x20\xb2\x1d\xb9\x9d\xcf\x8b\xfc\x06\x9f\x3a\x9a\xd1\xe8\xa7\xd4\xbd\x3d\xc3\xb5\x57\xa3\x4c\x11\x12\x2d\x5d\x60\xad\x9a\xed\xab\xd9\x75\xa9\x5b\xd6\xf2\xf1\x09\x5e\x8d\x44\x28\xfe\x7b\xdd\xef\x54\x33\x2b\x77\x06\xaf\x38\xe9\x36\xf4\x9f\xb8\xcb\xf3\xd8\x7f\xff\xf1\x37\x16\xf4\x54\x83\x2f\x88\xb5\x53\x16\xff\x6b\x4d\xcf\x0d\x8a\x75\xf2\x12\x98\x17\x32\xba\x3f\x2f\xc5\xdb\x23\xe4\xd7\xbb\xac\x0b\x72\x98\x07\x1e\xf5\x38\x07\x82\xf6\x7e\x7b\x14\x63\x2a\xdb\xca\x23\x9c\xdc\xdf\xfc\x90\x0b\xb7\xb7\x62\x5e\x5d\x4a\x54\xf3\xeb\xa2\xe5\xf8\xfb\xee\x5b\xfd\x38\x15\x56\x6d\x7d\xd4\xa9\x63\x3e\x67\xcc\x78\x67\x3c\x3f\x53\x1f\xaf\x7e\x59\x18\xc5\x28\xa3\x3b\x73\x35\xdc\x7c\x37\x1a\x40\x5a\x23\xdb\x3b\xec\x99\xdb\xdd\x06\x86\xbd\xbf\x0e\x6e\x18\xf3\xb5\x67\xe8\x4c\xcf\x78\xe3\x42\x3d\x1c\x19\x78\x66\xbb\x7e\x2a\xea\x97\xae\x2f\xc9\x42\xe9\xd1\x6b\x5e\x5e\xf2\xf6\xe6\x44\x71\x62\xfc\xf3\x73\xe3\x70\xe7\xb6\x82\xf6\xde\xc6\x91\xd9\xcd\xa4\xe9\x81\xcd\x9d\x68\xd7\xf0\x05\x67\x71\x9a\x52\xb6\x55\xd9\x94\xb5\xbd\x83\xb1\x8e\xe9\xf3\xad\x0b\x9e\xb2\xba\xdc\x64\x13\xf9\x51\xe8\x37\x3c\x79\xc2\x8d\xd3\xd3\xf2\x61\xb5\xd9\xf5\xd7\x6f\x96\x7a\xa9\x73\xce\xb4\x76\x53\xa3\xeb\x4a\x93\x98\x4a\xf3\xf3\xa2\xde\xd2\x7e\x3c\x82\xaf\x32\x16\x98\x0b\xcf\xaa\x99\xe5\x37\x31\x77\x84\x25\x8c\xd2\x35\xc8\x2a\xc4\xfa\x05\xfa\x78\x00\xc6\xb8\x4e\x99\x53\xfd\x6a\x0b\xb2\xd9\x7b\x8b\x1b\xf8\x10\x62\xe6\x4e\xa0\x20\x32\xc0\xf0\x73\xf5\x37\x57\x12\xc6\x03\x49\x51\xe6\xa6\x2c\x0a\xbd\xd6\xbb\x9a\x4c\x09\xbb\x14\x8b\x41\x64\x8c\x9b\xd0\xd8\xae\x93\x88\xfe\xf0\x6b\x85\x6f\x3c\xe1\x88\x48\x5e\xbd\x74\x71\xbb\xef\x18\xc6\xa3\x39\xd9\x33\x2d\xe1\x4c\x04\x09\x91\x56\x4d\xa5\x7f\x63\xb1\x71\x9f\x37\x5f\x98\x10\x92\x36\xb1\x26\x94\xca\x3e\x30\xa9\xfe\x3b\x4b\x06\x93\x11\x93\xb6\x8b\x73\x07\x35\x1c\xfc\x81\x6a\x04\x67\x52\x68\xd3\xe6\x68\x76\x85\xe5\x1f\xeb\xed\x8a\xea\xde\xed\x5c\x56\x01\x23\xfe\xd4\xb9\xcc\xc8\x15\xa7\xcf\xa0\xe1\x4c\xa5\x92\x08\x3a\xd4\x90\xd9\xed\x67\xbf\xbb\xbe\x04\x43\xcf\x68\x59\x1f\xb3\xaa\xde\x62\x55\x5c\x4a\x89\xed\x49\xd1\x4f\xa1\x99\x26\x1b\xa4\x45\x75\xfd\xd3\xe1\xed\xda\x8a\x17\x43\x96\x0a\x2b\x32\xf0\x82\xaa\x27\xdb\xea\x8e\x03\xd0\x1c\xa4\x65\xfa\xef\x40\x1a\x98\x8e\x85\xb3\xa5\x6f\xbb\x8a\xe3\x8e\x01\xf7\x42\x9f\xae\x2c\xab\x6e\x9a\x04\x6e\x44\x6a\x9a\x5e\x70\x3c\xde\x5a\xfb\x71\xee\x71\x4e\xdd\x56\x71\x39\xbe\xee\xea\xa2\xc4\xaf\x08\xca\xc5\xeb\xff\xe8\x6f\xb2\x03\x64\x12\xf7\x84\xc1\x59\x61\xde\xbc\xec\x03\x99\x4d\xce\x7d\x88\xa8\x73\x67\x69\x05\x7b\x50\xe7\xe2\x68\xb9\xd7\x76\x48\xc0\x9d\x77\x66\x13\x4c\x7c\xae\xd4\xc3\x79\x98\xca\x40\xb8\xb5\xbc\xac\x33\x9d\x49\xd3\x35\x6d\x7f\x47\xc8\x7c\x6e\x30\x30\x98\xab\x4b\xd7\x45\xe4\xa1\x40\x02\xdc\x9d\x8b\x6a\xbc\xbe\xf3\x50\x71\xa2\x0d\xcd\xf7\x8b\xc3\xee\xdb\x6a\xb7\x5b\x1a\xd4\x8a\xc3\xb1\xf2\x28\x34\x1e\x21\x8f\x78\xac\xb3\xfc\x79\x44\x46\xe0\x51\xec\x09\x5b\x05\x5b\xae\x77\xab\xf5\xe1\xdb\x6e\xb9\x7d\x9a\x3d\x2e\x87\x2f\x24\xf5\xed\xa0\x05\x9a\xa2\x21\x2e\x54\xb7\xf8\x49\x37\x5c\x68\x0d\x4e\xf0\xbf\x9c\xae\x2c\x4c\x14\x8b\xa8\xb3\x40\x4e\xbc\xc5\x2a\x3f\x5f\x6a\xe3\xe2\xe1\xae\x35\x0e\x90\xe8\xa7\x26\x76\x9f\x17\x30\x9e\x28\x71\x68\xb0\x64\xa0\xd4\xba\x7c\xfe\x6d\x78\xe6\x24\x20\xc9\x5c\x47\x28\x5c\x6f\x96\x4f\x23\x54\x1b\x4f\x42\x46\xe0\x5c\xb1\xef\x60\x5f\x3c\x89\x8d\xd1\xfd\x73\xf6\x13\xe7\x54\x42\xfe\x28\x1f\xe3\x89\x4c\x78\xda\x17\x35\x74\x1b\x18\x4f\x23\x45\x18\x8f\xb6\x5e\xfb\x23\xcb\xb1\x79\x11\x77\xd4\xc2\x1c\xdd\xec\x34\x0d\x89\xef\xb1\xd8\xae\x7f\xdc\xd1\xd5\x0e\xe2\xed\x26\xac\x32\x1c\x30\xd0\xe4\xec\x3b\x81\xbb\xe3\xa9\xf6\x68\x15\x3a\x9c\xb2\x9c\xb0\xf2\x4b\xd5\x26\xb7\x3c\xd5\x29\x15\x99\x8b\xbf\xb2\x23\xf6\x44\x5f\x38\x67\x21\xa7\x64\x69\x25\x8b\x9e\xb7\x68\xf3\x77\x70\x2c\xb9\xc7\xab\xe1\x7b\x9e\x30\x1f\x32\xe6\x38\xe7\xbe\xe1\xe4\xcc\x94\x72\x1b\xdd\xf4\xdb\xc0\x41\x51\x81\xd9\x74\x6c\x36\x8b\xc5\x74\x3c\xc5\x39\x22\x21\xdb\x49\x27\x0f\xf7\xc5\x5d\xf6\xb3\x7d\x5f\x44\xaa\x9d\xbd\xe1\xec\x78\xa4\x36\xc5\xb8\x8d\xc2\x25\xf8\x14\x8f\x9d\x8d\x16\x7a\x56\xe4\xe3\x98\x80\x4b\x30\x34\xc1\xba\x75\x6e\xc8\x8a\xbc\x33\x5d\x6b\x97\x50\x2e\x25\x37\x32\xaa\x84\xcb\x82\xf7\xbe\xba\x2b\xe7\xca\xd6\xed\xbf\xaf\xbe\x6d\x97\xf7\x05\x39\xbc\x56\xad\x3b\xd1\xe7\x4d\x26\xae\x78\x44\xf5\xaf\x67\x38\x21\x31\xcf\x4c\x27\xbd\x6b\x0b\x70\x8c\x53\xaa\xdf\xcf\x17\xcb\xdf\x3f\xab\xee\x72\x14\x22\x75\xbc\xd6\x7b\xc8\x8e\xa6\xa0\xfe\x00\xcd\x7f\x6f\xf1\x27\x51\xe7\x97\x39\x79\x24\xb8\xff\x6c\x7f\x21\xca\x90\x6a\xe6\x47\xa8\xea\x7b\x2a\xc7\xef\xf0\x7f\xfa\xd1\x06\x47\x64\x64\xd0\xf1\xfb\x72\x36\xa8\xfb\x0f\xef\xba\xf6\x03\xc2\x37\x9f\xe0\x15\x0f\x16\x91\x79\x70\xc5\xdb\xd1\x50\x9e\x12\x8d\xd8\x34\x67\x36\x58\x4a\xcc\xeb\xb5\xee\xc9\x52\x72\xae\xa5\x47\x5f\xaa\x5c\xbb\xea\x68\x94\xc5\x9f\xda\x5d\x91\x6b\xa5\x28\xe1\xcd\x2a\x2a\x69\x0e\xbc\x28\x47\x5f\xa8\x7d\xe6\x59\x43\x84\x47\xe8\xfa\x24\x56\xa1\xad\x1b\x16\x29\xc3\xef\x7f\xfe\x40\x90\x9d\x83\xe7\x23\x15\x8f\x4e\x59\x6e\x65\xf6\xfe\x2e\xe6\x74\x7c\xa2\xd4\x98\x12\x5b\x9d\xb4\xe5\xfe\xeb\x6f\xa3\x01\xda\x98\xe9\x6d\x7b\xf0\x48\xec\x28\x37\xc3\xd9\x04\x3e\xf7\xa9\xdc\xf2\x4c\x72\xde\x25\x12\xdd\xd4\xec\x9c\x2d\xa1\xef\xd3\xe2\x10\x04\xdc\x4f\x74\xbf\xf1\xd1\x91\xcc\x20\x90\x82\xe8\xf1\xab\xa7\xfd\x76\xb9\x59\xdd\x1d\x76\x5f\x57\x9b\xc3\xc3\xea\xb1\xad\xb8\x40\x18\x04\xf4\xc0\x0e\x75\x0f\x02\xb0\x2f\x56\x8b\xd9\x66\x28\xcb\x3f\x0e\xb2\x46\x13\x7b\xf8\xb3\xc2\xc0\xc4\x37\x75\xf1\x1d\x2e\xc7\xba\xfd\x32\xe6\xa3\xd1\xc5\x32\x3b\x75\x6f\x35\x83\x10\xbd\xd4\x32\xda\xd6\xe2\xaf\x55\xae\x0b\x7a\xaf\xcf\x83\x0e\x14\x44\x81\x20\x68\xa1\x33\xf3\x3c\x83\xc4\xea\x25\x3b\xdf\xca\x15\x70\x88\x13\x4d\x0e\x7c\x5f\xe0\x84\x65\xd5\xbc\x03\x6e\x8d\x87\x38\x05\xca\xf6\xf3\xa2\x2b\xf9\x8f\xf0\xb9\x10\x73\xa3\xf2\xd8\x76\x4c\xcb\xe2\xb9\x84\x53\xbb\x6c\xb9\x60\x0c\x12\x05\x54\x35\x3d\xb7\xf9\x23\xa4\x3c\xa2\xb5\x90\x9e\xfe\x43\xf1\xb3\x0b\xcd\x20\x85\x80\x70\xa9\x39\x9c\x9c\x11\x81\x3b\x22\x8d\x5c\x78\x65\x75\xf4\xe9\xf6\x34\x99\x27\xf1\xb1\xf6\x6f\xa3\xc6\x22\xb0\xc4\x74\xe6\x4f\xf0\xfe\x03\xb3\xdd\xe3\xee\xbb\x55\x54\x76\x5f\xc5\x52\x45\x05\x2e\x71\xb9\xce\x8e\xd6\xb1\x72\x7e\xb9\x2e\xeb\x1b\xba\xca\xe7\xe8\x0a\x60\xc2\x34\xd6\x8f\x94\x9a\x34\xef\xfb\xbd\xcc\xc6\x57\x23\x12\x92\x54\x20\x5c\x55\x5e\x15\xc7\x51\x5e\x04\x4c\xc6\x14\xbe\xd4\x08\xa7\x9d\x73\x08\xe1\xc0\x90\x91\xcc\x63\x75\x84\xea\x65\x6b\x91\xd2\x2d\x0b\x6f\x10\xca\xb7\x77\x9c\xe9\x94\x5b\x34\xb1\x59\x2d\xa7\x2b\xd4\xc0\x23\x15\x59\x92\x25\x1c\xb3\x0a\x07\xec\xe8\xe6\x30\x12\xd7\xb8\xd9\xdc\x0d\xe1\xa6\xd8\xc2\x5f\xee\xa8\x08\xcc\x64\xb5\xdd\x5d\x8b\xfa\x6b\xd1\x7e\xbd\xa6\x17\xc8\xd4\xa7\xb8\x83\xcc\xf9\x9f\x8a\xb2\x7e\xd9\x14\x06\xc4\xdc\x25\xcb\xa0\x94\x4f\xbf\xbf\xb8\x94\x63\x6b\x18\x0e\x98\xa6\x04\xbd\xaf\x2e\xe7\x26\xc1\x78\xc2\xb7\xcd\xa5\x7c\xfe\x05\xae\x14\x50\xa7\xc6\x18\xf9\x52\xe2\x97\x0e\xe3\x2e\xbc\x48\xa7\x26\x3c\x35\xf0\x58\x57\x3a\x18\xdc\x1d\xe1\xa5\x82\xd8\x29\x7b\xcc\x5e\x5f\x8a\xca\x06\x4c\xf6\xa0\x9f\x44\x44\x06\xfb\x5a\xe4\x58\xd5\x59\x65\x75\xbe\x97\xfb\xaf\x67\x83\x9a\x75\xe3\x18\xd2\x57\x6d\x31\xa7\xdc\xb1\x15\x51\x9b\xd8\xf0\x44\xe0\xa5\xe4\xec\xbd\x47\x3c\xb7\x60\x37\x11\x70\xa3\x3c\xb5\xb9\x23\x5e\x6e\x3f\xc6\x11\x81\x30\x8e\xc3\x4d\x28\xde\x6e\x7e\x22\x50\x26\x54\x10\x97\xeb\x7d\x51\xde\x97\x19\x8e\x49\xa4\x22\x40\xc9\x9a\x21\x8f\x19\xa9\x05\x53\xad\xaf\xd3\xa0\xb6\x83\xc2\x58\x52\xb5\xbc\x42\x54\xcd\x02\xa8\x9a\x7f\xfa\x5f\x1f\x62\x4a\xf2\x64\x4d\x9e\x65\x7b\xdc\x2b\x35\x08\x56\x45\xe4\xb7\xf0\x8b\x79\xf1\x7e\x5b\xf1\x11\x51\x10\xd3\xc2\x96\xe3\xdb\x1f\x12\xea\x1b\x10\xc5\x74\xa5\x66\x72\xf7\x11\x91\x4a\x08\xe9\x4f\x0a\x8a\x6b\x3d\x8a\x8f\x44\x2c\x13\x8a\xe9\x56\x8b\xf5\xd3\xe2\x08\x55\x95\xc9\xfe\x1a\x2b\x12\x61\xbc\xa8\x87\x32\x0b\x7f\x6f\xe7\x13\xa9\x8f\xd4\xde\xae\x21\x7f\x6d\xd2\xe0\x0a\x55\xeb\x7a\xd5\x04\x78\x82\x16\x23\xa3\x73\x29\x0a\x28\x55\x93\x1e\x66\xf9\xf3\xdc\x6a\xac\x4c\x4e\x61\xc1\xc2\x30\x08\x5b\x3f\x39\x52\xab\x23\x6f\x93\xf6\x59\xb3\x24\xe6\xc6\xc1\xb5\x06\x5b\x58\x08\x83\x7f\x0c\xcf\x91\xaa\xc8\x02\xd9\x28\x49\x73\x2f\xe8\x88\x03\x79\xe9\x91\xe0\x04\x53\x49\x8b\x9a\x21\xcd\x8d\x81\x75\x89\x1d\xc4\x21\x71\xb2\xce\xb4\xea\xb9\x1c\xaa\xbd\x38\xf0\x43\xaa\x82\x57\x17\x61\xdc\x70\xa7\x1b\x59\xc3\x9f\x0c\x90\x60\x8b\xa2\xc8\xf2\x67\x82\xc3\x8d\xbe\x19\xac\xc8\x15\x45\xba\xc3\xe0\x56\x88\x24\x26\x52\x3a\x25\xc2\x3b\x4b\xb6\x6f\xe7\xb4\x60\x11\x89\xc7\x43\x89\x3f\x10\x5f\x15\x5c\xab\xf5\xb9\xab\x05\x4d\x31\x40\x47\xd7\x27\xa4\x4c\x2c\xbc\xec\x31\xcb\xbf\x17\x35\x1a\x74\xd2\xef\xc3\x15\x5f\x48\x11\x51\x01\xbc\xba\x9e\x44\x71\x34\xca\x0f\xee\x2a\x14\x0f\xa9\xd0\x5f\xe4\xa6\x1a\xfb\x31\x40\x44\xa0\x17\x98\x07\x6c\xd8\x77\x6d\xf5\x61\x92\xfa\x25\x30\x0a\x53\xc3\x75\xe9\xc0\x27\xd3\x03\xb5\xa2\x7d\x96\x5e\x95\x1d\xd6\x2d\x3f\x7e\xf8\x23\x74\xb3\x76\x1b\x6d\x9a\x6f\x2b\x47\x0f\x9d\xa4\x09\x0a\xad\x25\x81\x93\xce\x2f\xab\xbb\x83\xfd\xa1\xd2\xf7\x43\xc2\x83\x6e\x11\xd4\x62\x80\x66\x70\x03\x02\x65\x1a\x15\x46\x94\x68\x76\xec\xdb\x6a\x72\xe9\x47\x61\xea\xda\x3f\xf1\xa1\x42\x28\xe5\xcb\x4c\x96\x45\x55\x3d\x15\xaa\x7d\xe6\xd2\x07\xdf\xa4\xab\x36\x4a\x5b\xd6\x2f\x46\x09\x67\xfa\xb5\x92\x01\x47\x82\xee\x37\x0b\x17\xd5\xd7\x0f\x6d\x26\x9c\x76\x33\xc0\xfe\xbf\xc3\x7e\x45\x6f\xcb\xed\xf7\x3b\x64\xc8\x90\x36\xb9\xd9\xa6\x49\xb9\x5d\x28\x25\x43\x6e\x0c\xe3\x9b\x79\xb2\xca\xd7\xe5\x33\xe4\xd9\xff\x1a\xe5\x15\xf9\x82\x6d\x56\x24\x43\x48\x98\xd5\x6b\x3e\x19\x20\xff\x84\x04\x2e\x97\x51\x64\x6c\x9d\x1c\x3e\xed\x33\x2d\x11\x2e\x63\xc6\xe9\x05\x3d\xe0\x29\xab\xff\x59\x08\x42\x1c\x6e\x8a\x6a\xc2\x9d\xfd\xf3\xd5\x4d\xc6\xe8\x41\xa7\x65\xde\x79\x51\x4f\xd6\x0d\x65\xe2\x45\xce\x3a\xe9\xbe\x28\xc9\xf7\x74\x32\x75\x1c\x7e\x47\x12\x32\x32\x10\x7f\x3e\x16\x02\x8e\x8f\x6d\x91\x55\xa6\xbe\x26\x86\x7e\x56\x2d\xff\xe7\x92\x9d\x51\xcd\xf2\x6b\xf8\xab\xe5\xd9\x7d\x96\x79\x34\x33\x5a\xd9\xa8\xc1\x6b\x20\x99\xc7\xb5\x63\xc3\xf6\xb4\x5e\x27\x67\xb8\x64\xbe\xaf\x4d\x57\xfe\xf9\xc7\x07\xc4\x74\xc9\x14\x12\xba\xf9\xf7\x3f\x17\x87\xed\xda\x09\xf5\x73\xc9\x83\x84\x8a\x18\x2f\xf0\x81\x34\x86\xe4\x61\x2c\xed\x8b\x2e\x5b\x2a\x76\xdc\x7e\x5e\x70\x82\x28\x2e\xdf\xcf\x58\x66\x04\x14\x3f\xf6\x37\x2f\x29\x7c\xe1\xe4\xc2\xf7\x86\x39\xea\x2a\x1b\xed\x88\x44\xa5\xd0\xe3\xdb\x99\xa9\x33\x2b\xb1\x17\xe3\xb7\x63\x25\x3a\xdd\x57\xeb\xe0\x36\x88\xef\xd8\x0d\xab\x43\x0a\x94\x14\x4c\xb6\x24\x04\xc8\xd5\xbe\x58\x56\xb4\xf8\x0e\xca\x3a\xa3\x3b\x26\xbd\xc4\xb5\x14\xc6\x11\x88\x94\x01\x3a\x41\x82\xcd\x11\x6a\x5d\x94\x27\x63\x10\xed\x7b\x9e\xe7\x8d\xde\x0d\x99\x68\xa2\x5c\x35\xef\xdf\x6a\xbd\x9f\xf5\xea\xf4\x52\x85\xd2\x94\x89\xc8\xbd\xac\xa3\x12\x48\x25\x24\xc5\x88\x67\xb8\x52\xcf\xbe\x0d\x95\x47\x53\xa0\xfd\x9d\x98\xa4\x94\xf7\xc8\xe2\x74\x86\x12\xf7\xc5\xea\x39\x2f\x4a\x5c\x40\x35\xc9\xde\x92\x98\x86\x54\x9b\xdd\xb4\x6e\xc7\xcd\xdf\x98\xdf\xbf\x57\xbf\xca\x37\xdc\xc7\x30\x25\xac\xab\xf1\xac\x96\x70\x3a\xa1\xfa\xd7\x05\x08\x3f\x64\x4f\xad\x3c\xee\xd3\x2b\xef\x4c\x07\xce\x99\x24\xd1\x0a\x8a\x77\xac\x40\x65\x6c\x2b\x04\xb1\xfb\x8c\x46\x15\xb9\xf8\xbc\xc9\xa9\xdb\x28\xd5\x0e\xf0\x43\x41\xb3\xc1\xe5\x7a\xed\x62\x19\xfd\x77\x7c\xc9\xff\xf1\x83\x0f\x36\x4e\xe5\xa7\x89\x88\x1c\xc9\x31\xbf\x74\xf1\x42\x8f\xae\xa7\x02\x2f\xe6\x43\xc4\xd3\x7d\x96\x43\x2e\x33\x38\xce\xa8\x2e\x61\x2e\x3d\x18\x54\xc3\x7d\xbb\xf0\xa8\x90\x31\x62\x56\x61\xdb\x08\x54\xa1\x88\x88\xfa\x55\x88\xc2\x95\x61\x54\x14\x70\x0a\x90\x9f\xd6\x87\xf9\x6c\xbf\x7f\x58\x1e\x1e\xd6\x5f\xda\x83\xdc\x64\x4f\x6f\x6e\xa7\x7d\xa4\x04\x72\xb8\x70\xa8\x38\x04\xaa\x4c\x80\x52\x1b\x92\x23\x1f\x1d\xe6\xc6\x41\xb3\xc2\xfa\x69\xf6\x7d\x00\x43\xf8\xc7\x68\xa4\x88\xa8\x47\xf2\x50\x3c\x7f\x26\xd2\x3b\x04\x41\xf5\xa1\x50\x2a\x46\x8f\xb5\x80\xd8\x6f\x55\xd9\xa7\xb0\xab\x24\x34\x52\xc5\xfb\x6f\xab\xc3\xec\xe1\x61\xbd\x98\xed\x57\xeb\xa7\xf6\xa8\x42\x5a\x34\x7e\xcc\x1e\x1e\x96\xfb\xc3\xc3\xfc\x30\x92\xe1\xe5\x2a\xf5\x02\x12\x4d\x11\x97\xeb\xa2\xbc\x56\x75\xaf\x97\x3a\x7c\xbc\x69\xac\x49\xd0\x1d\x55\x56\xdf\x41\x76\xbc\x4e\xc4\x13\x2a\xd5\x1e\x75\x27\x17\xbb\xe5\xce\x91\x5c\x14\xf3\x94\x54\xae\x46\x53\xd5\xcd\x0c\x5c\x0d\xe8\x30\x43\x90\xba\x62\x41\xe4\x9b\x22\x53\x4e\xfa\x56\x24\x36\x39\xbc\xab\x02\x63\x7a\xea\xae\x10\xd2\xda\x66\xde\x5e\xb7\xf4\x52\xee\x78\x26\x56\xbf\x61\x0e\xf9\xeb\xd3\x58\xe5\x46\xc9\x58\x39\xd4\x9e\x61\x3f\xf6\x2d\x46\xdc\x18\xe0\x54\x9b\x17\x28\x8b\xd3\xa0\xc9\xa2\x24\x1a\x31\x20\x99\xd5\xd7\x4d\x51\x1c\x17\x97\xda\x16\x09\x3b\xac\x96\xd2\x49\x4c\xeb\x54\x7e\x39\x1e\xfb\xc5\x0a\xa5\x13\xe3\x1c\xd5\x09\x6b\x98\xd5\x7b\x10\x24\xf4\xe2\x46\xa5\x99\x4f\x7b\xb0\x69\x31\xb4\x61\xa3\x83\x0e\x11\xc2\xae\x53\x44\xb1\x06\x35\xee\xb3\x10\xd9\xc4\xaf\x99\xfc\x4d\x30\x62\x69\xcc\x56\x8c\x6c\xf8\x9b\xb5\x08\x13\xbf\x63\xd8\x92\xdc\x50\xcf\x9c\x83\x2b\x2d\x8d\x58\x4b\xfd\x0b\xf7\xb3\xd1\x9b\xa1\x95\x47\x3d\x8c\x21\x2f\xe9\x57\xde\x06\x5c\x69\x34\x00\xe2\x12\x9b\x8b\x30\xa4\x8d\xf1\x08\x49\xb5\x06\x93\xab\xf7\x68\x8b\x37\xb3\x03\x3d\xcf\xa8\x96\x92\x38\xe3\x8f\x11\xe3\xcf\x6d\x0a\xe8\xc5\x86\xda\x5f\xbd\xc0\x50\xfb\x03\xfd\x50\x51\x29\x4d\x15\x9d\x21\xc9\xf4\x37\xf9\x5c\x43\xdc\x1a\x96\xf5\x72\x16\xf4\x25\x2a\x18\x28\xdc\xdb\x89\xd3\x03\xa2\x60\x10\x29\x72\xd5\x6e\x5d\xbe\x88\x92\xd9\x96\x9e\x31\x48\x7d\xcf\xb8\xab\xbb\xb8\x80\xcc\x59\x88\x12\x63\x87\x84\x69\x4a\x73\xac\x33\xf2\x96\x45\x39\x8a\x98\x30\x94\x3e\x72\x27\xcb\xfd\x5e\xdf\x08\xcc\x73\x8c\x3c\x20\x87\x75\x38\x1e\x7f\xb4\x78\x23\x8c\xb4\x20\x1b\xbe\x56\xa2\x4e\x63\xb9\xba\x85\x23\x0f\xef\x49\xec\x0b\x5f\xf5\xa9\x96\xf6\xe6\xf6\x1f\xbf\x5b\x16\x30\x8e\x8c\x8a\xaa\x2a\x8b\xf3\xb0\x42\xd6\x0e\x49\x18\x27\xfe\x86\xf9\x81\x77\x65\xd1\xb6\x1f\x31\x0d\x8d\x10\xb4\x15\x03\x30\x0a\x0f\x37\x15\xa6\x71\xa3\x0c\x59\x14\x12\x1c\xec\x92\xe3\x3b\x9e\xce\xa3\x44\x15\x59\x6c\xec\xc4\x8a\xa3\x5a\x46\x5b\x94\x57\x79\xc4\x79\x1b\x96\x20\x03\x95\x1a\x30\xc4\x86\xa4\x39\xfb\xb8\x4d\xe4\x2a\x8c\xa0\x93\xa7\xdb\xa2\x1e\x09\x2f\x0f\xdf\x17\x84\x10\x7c\x1b\x01\x7e\xdd\x3f\x2c\x76\x67\xc3\xbe\x23\xea\xce\x65\x18\x81\x0d\xef\x0a\x30\x46\xc9\xfe\xec\x78\x7e\x01\xeb\xc4\x31\xd0\xcd\xef\x7e\xfc\xe8\x1b\x85\xc7\xad\x3e\xca\xe2\x25\x93\xaf\x98\x7f\xbd\x01\x7a\xa3\x88\x8c\x5e\xd9\x6c\xb3\xd9\xae\xbf\xcf\x1e\x3e\xb8\x7a\x01\x3c\x34\xea\x19\x22\xab\x47\xba\x47\x6e\x88\x92\xb4\xd1\x65\x95\x05\xfe\xb8\x0a\x71\xaf\x5c\x34\x3c\xa9\x0c\xd0\xa8\x87\x37\x6b\xd2\x13\xbe\xcd\x8b\xb6\xd9\x8e\x28\x13\x22\xa3\xe5\xf8\x5e\xff\xf6\x7f\xa4\x02\x20\x22\x77\xfc\x56\x03\x22\x70\x32\x1a\xc3\x2b\xd6\x5e\x44\xb0\x27\x5d\xe2\x87\x2d\x02\x37\x34\x90\x54\x07\xfb\xba\x5f\xb8\x2b\xd4\x61\x48\x55\xcf\x37\x82\x4d\xac\x97\x8f\xed\x81\x24\xd1\x36\x64\x26\xe2\xeb\x8f\x8c\xa4\xab\x3f\x48\x03\xb5\x17\xc6\x54\x7c\x32\xca\x3d\x9f\xb4\xdc\xb4\x17\x7b\x44\x36\xac\xb3\x13\x9a\x8a\x45\x5f\x3c\x4e\xfb\x91\xa6\x3d\xe5\x98\x89\x12\xca\xab\x1f\x39\xe5\x83\x76\x40\x82\xa4\x9d\xd4\x3a\x2b\xf4\x01\xb2\x3a\xf0\x62\x57\x88\x32\xd9\x09\x1d\x9e\x08\x13\x74\x10\xa8\xa4\x83\xfe\x37\x5b\x71\x75\x86\x56\xaf\x70\xf8\x90\x75\xc0\x12\x6d\x57\x24\x52\x7d\xae\xb2\xe7\x47\x18\xc3\x3e\x75\x20\xfd\xc4\x3e\xb1\x2f\x85\xba\x39\x68\x7a\xc5\x15\xe4\x35\x2c\x8e\x70\xe9\xae\x19\xa5\x93\x21\x59\xbe\xd7\x68\x24\x77\x46\x9f\x0e\xb9\x81\x93\x74\x8a\x2d\x07\x01\x79\x7e\x63\xe7\xc7\x75\xe4\xfb\xd4\x73\xb9\x54\x2d\x5b\x7e\xfa\x91\x45\x91\x69\x6b\x13\x8d\xe2\x78\x6c\xde\xe1\x1b\xc7\x34\xae\xe3\x50\x18\x28\x2b\xbd\xa7\x26\x16\x98\x68\xf5\xe8\x18\x99\xec\x8c\x8e\xf6\xc6\xad\xf2\xd3\x95\x57\xa7\x7e\x44\x85\x47\x47\x84\x37\x68\xdd\xea\x4b\x51\x6c\xda\x06\xf4\xe8\x5b\xd2\xd0\x0f\x9d\x00\xfc\x0b\x8e\x35\x4c\x74\xaa\x4c\x06\xbb\x5f\xef\x67\x0f\x87\xcd\x72\xbb\xd8\x2e\x9f\xf6\x0e\x2b\xae\x99\xa5\x07\x75\x9e\xb8\x8b\xa2\x28\x55\x35\x88\xc1\x34\x4b\x04\x29\x5e\xd9\x55\x7a\x8a\xf5\xd6\x8f\x8d\x35\x13\x31\x19\x46\xfd\xf3\xb1\x9f\x2c\x93\xc1\x55\xda\x61\x62\x7a\xfb\xa8\x66\x9a\x19\xad\xf4\xb7\xac\x96\x2f\xeb\xf6\x23\xdc\x03\x02\x55\x29\xab\x02\xb6\xca\x07\xc4\x0f\xcd\x03\x41\x1b\xbd\x38\x82\x7c\x3d\xde\x40\x7f\x34\x8f\x04\xf1\x5d\x44\x56\x18\xb3\x89\xbf\x83\xc2\xd7\x80\x91\x6e\x85\x6d\x0e\x04\x59\x5e\xad\x7b\xea\xd1\x5c\x83\x16\x64\x8a\xf7\x50\x3c\xcf\x33\x45\x56\x50\x7f\xaf\x34\xa2\x85\x6f\x5c\xf3\x9a\x7c\xf9\x8f\x6d\x5f\xf4\x53\x8b\x50\xf2\xbe\x1d\xce\xd0\xb8\x7a\x74\x9a\x28\x0e\x74\x07\x4c\x58\xdd\xb5\x27\x51\x31\xc5\x61\x24\x1d\x3f\x78\x8a\xd2\x33\x9e\x13\x96\xb7\x65\x21\x38\xee\x73\x32\x62\xa4\x37\xd6\x72\x21\x69\x5e\xdf\xb4\x92\xb5\x8a\xcc\xcb\x54\x61\xbd\xc5\x9f\xc5\xf1\xd6\x79\x96\x6b\x15\x07\x64\xc2\x75\xb7\xfe\x71\x78\x6c\xf3\x1e\x8d\x3a\x14\xce\x87\xf5\x71\x64\xd9\xcb\xb5\xf6\x0d\xb9\xa8\x2a\x8e\x99\xcc\x6a\xb8\xa3\xb3\x4b\x70\x02\x14\x5a\x83\x20\xd4\xdf\x13\xbe\x7d\x9c\xda\x81\xe7\x85\x82\xb8\x44\xbb\xc5\x62\xb6\x9a\x14\x08\x71\x03\x13\xc5\x8c\x26\xf6\x5b\xf3\x9e\xed\x70\x84\x9a\x04\xcf\xe3\x46\x2b\xf9\xfd\xfd\x3d\xed\x1e\x14\x78\x3e\x37\x8a\x2f\xeb\xea\xa5\x89\xab\xb3\xdc\x24\xc9\xfd\xdf\x03\x9e\xaf\xa4\x97\xb4\x48\xfe\xf1\xa9\x7d\xa5\x68\xed\x9b\x5b\x66\x91\x3b\x75\xc0\xe3\xb8\xaf\xf8\xf0\x88\xeb\x9c\xd2\x80\xfe\xb3\x04\x2f\x90\x11\xbd\x4a\x60\x08\xd4\x9f\x2a\xd4\x80\x17\x28\x83\x94\xdd\x43\xfe\xfa\xa3\xe3\xba\xba\xef\x0c\x3d\xa4\x0a\x9b\x00\x01\xed\xdf\xa2\x28\x91\xad\xf9\xe8\x7d\x59\x98\x64\xa4\x3d\x9c\x84\xa4\xab\x36\x73\x48\x02\xfb\xf7\x28\x14\x46\x31\xfa\x05\xe5\xeb\x2e\x7b\xbe\xf1\x67\x99\x7c\xed\x46\x0f\x26\x8a\x58\xe2\xc4\x9c\xb2\x12\xd7\xaf\x7d\x8b\x0f\xf0\x22\x66\x22\x2e\x50\xea\xeb\x59\x3c\x15\xea\x76\x93\xef\xbf\xce\xe0\xc5\x5e\x12\xa1\xeb\x61\x5f\xf2\xfa\xda\x67\xd4\x4d\x76\x69\xc1\x8b\x59\x4a\xef\xe2\xb1\x78\x9e\x8d\xb6\x1e\xf0\x12\x5f\x51\x02\x9f\x55\x5b\x04\x75\xdd\x17\xbb\x6b\x5e\xbf\x60\x95\xfd\x2f\x8e\x26\x41\x92\x68\x42\x56\xdb\xc5\xd5\xd5\xfb\xb7\x08\xf2\xc5\xa5\x99\xe0\xf1\xd4\x23\xc0\xeb\x41\x5c\xca\xbc\xf5\x66\xed\x6f\xe3\xe0\x71\x29\xa8\xf7\xb9\x81\xba\x3f\x15\x39\x26\xf4\xe7\x1e\x85\x79\x74\xb1\x90\x48\x2a\xb6\xce\xee\x97\xf3\xc1\x54\x03\xa6\xa9\x68\xd5\x26\xb7\x4d\x66\x71\x6b\x80\xc0\xec\x70\x11\x63\x1c\xf7\x66\xe6\x87\x18\x19\xf0\x44\x12\xf8\xb6\xec\x4a\x91\x52\x4f\x10\x19\x3c\x01\x2a\x30\x5d\x98\x26\x74\x1b\x00\xc0\xc0\x13\x92\x91\x25\x93\xed\x25\xee\x0a\x99\xc1\x71\xa5\xd0\x54\xdb\xa6\x56\x54\xf0\x64\xe8\x51\x8e\xf3\x05\xf3\x62\xe3\xc8\x8a\xe0\xc9\x88\x33\x6c\xf5\xb9\xff\x59\x08\x2b\x58\x5a\xbd\x64\xe7\xe9\xbc\x13\x3c\x99\x26\x86\x02\x0a\x47\xd9\xfc\xbe\xbb\xec\x67\x35\x6d\x12\x0c\x9e\x54\x92\xf9\x8e\xe2\x6e\x94\xde\xe6\xd7\x95\xfa\x6d\x38\xf7\x54\x2c\x28\xf7\x99\x63\x59\x5e\x1f\xe0\x15\xfb\x0f\x4f\x31\x53\x97\xc9\x64\x71\x87\x79\x71\xca\x72\xa8\x8b\xb2\x67\x0d\x03\xbe\x17\x24\xad\x77\x0c\x01\x8b\x4f\xe3\xbe\x1c\xf8\x5e\x0a\xe4\xf1\xb2\x80\xbf\x2e\x35\x7e\x84\xba\xff\x05\x07\x62\x78\x27\x7c\x3f\x34\xee\x2a\x4d\xa8\xfd\xb8\xbf\x2f\xca\x2f\x30\xc4\xc6\x35\x43\x52\x8a\x1d\xe6\xcd\xde\xbb\xc3\x1e\x09\x16\x7c\x3f\x0e\x08\x72\xfa\x58\x94\xf8\x0c\x59\xfe\x0b\x92\x37\xf8\xbe\x8c\x08\x76\xd6\xcc\x09\x83\xc1\x7a\xc8\x24\xe6\x23\x89\x5e\xf0\x03\x95\x52\xba\x59\x9c\x31\xff\xd2\xda\x49\x80\x1f\x7a\x22\x61\x9d\x0c\x20\x96\xc6\x84\xa7\xc6\xf7\xfa\x40\x5e\x90\x83\xf5\xd3\x0f\x43\x6d\xf5\x4a\xab\x6a\xc0\xe8\xaf\x3e\x00\x67\x82\x1f\x82\xe6\x86\x94\xbb\xc3\xf2\x67\x26\xfb\x52\x02\xe0\x47\x1e\x52\xc5\xe2\x31\xab\x87\x7f\x8f\x0d\x94\xdc\xed\xe9\xbf\x6f\xd7\x6e\xc5\x59\x8f\x1d\x07\x87\x77\x24\x4a\x31\x36\xf3\x77\xb0\x1e\xcc\x72\xd5\x55\x0f\xc0\x8f\x94\x4e\x44\xa7\xd7\xf2\x8c\x5b\x94\xd9\x39\xc3\xbc\x6e\xcb\xed\xe0\x27\x1c\xa5\xcb\x51\xa1\x7a\xb9\xcb\x9e\x47\xc1\x01\xf8\x09\x08\x5a\xef\x5d\xc1\xbf\xfd\xa8\x34\x2a\xb7\x77\x59\x25\x4b\xa8\x5e\xfa\x6a\x2a\xe0\xa7\xe0\x13\x2c\x95\xe0\x80\x44\x18\x72\x47\x18\x4b\x88\x5a\xd8\xd6\x73\xe3\x1b\x3f\xf5\xff\xc4\xff\x6d\x07\x2b\x1d\xb4\x92\x56\xf5\x6d\x69\xde\x8d\xe3\x89\xb6\x86\x48\xeb\x1c\xad\xdf\x55\x2b\xd5\x09\x3e\x53\x2a\x30\xa9\x2a\xc9\x19\x3c\x16\xaa\xbd\x05\x3c\x34\x1e\xf6\xdf\x8b\xba\xdd\xc5\x7c\xce\x12\x4a\xd1\xca\xc2\x68\x0b\xdb\x02\xcf\xa7\x1d\x33\xf0\x21\xd6\x14\xfb\x55\xc5\x71\x80\xce\x02\x1f\xa4\x20\x3d\xb7\x03\x65\xbe\x1d\xfc\x12\x7c\x50\x1e\x69\x90\xf4\xeb\x30\xeb\xcb\x87\x82\x1c\xf6\x53\x22\x44\xc1\x2c\xac\xb3\x1a\x01\x4f\xc1\x17\xe0\xa3\xf1\x8b\xe9\xe4\x15\xfe\xf1\xa1\xdc\x21\xf8\x42\x21\xe3\x8e\xd4\x57\x61\x7d\x68\x52\x86\x75\x09\xb2\xc9\x9d\x9a\x7c\xa7\x73\x9d\x01\x5f\xc6\x3c\xc2\xae\x01\x6e\x3d\x22\xae\xa6\xc3\xdd\xb5\x0e\xc0\x97\x60\x7a\xc5\x2d\x56\x6f\x81\xc5\xe8\x42\x25\x62\xdc\x0b\x56\x7e\x7f\x5a\x34\xa1\xff\x16\x7a\x2c\x7e\x3b\x52\x71\xa9\xed\x44\xfd\x77\x91\xe3\x9e\xe8\x5b\x66\x45\x0d\x06\x00\x4b\xf0\x95\xf0\x49\x16\x60\x87\xb9\xda\x62\x75\x39\xd6\x16\x94\x37\x1d\x04\xf8\x18\x69\xea\x89\x37\x0b\x4c\xf1\x13\xcb\xe1\xc6\xe3\xa3\x25\x79\xe6\xf8\xb6\x93\x2f\x46\xe9\xd0\xc8\x5b\xf5\x7e\xab\xe6\xbe\x53\x35\x3c\x60\xae\x54\x9b\xc0\x40\xe0\xa5\x21\xd8\x75\xda\x68\x3c\x50\x3f\xa0\x6a\x0f\x33\x49\x1b\xcb\xef\x99\x7c\xdd\xbf\xf4\x37\x81\xc0\x43\xe3\xeb\xd4\x3c\xc6\x7a\xb0\xe7\x07\x01\x37\x1d\x93\x66\xa6\xf5\xd1\xc2\x10\x84\x5e\x40\xaf\x65\x93\xd2\xec\xe0\x88\xed\x47\xc2\x30\x21\xee\x7a\x93\xe5\xcd\x1e\x0c\xfd\xf9\x93\x75\x37\x88\x30\x25\x61\xa6\xf7\xeb\x5f\xf5\x14\x3d\x67\x30\x38\x8e\x7d\x27\xda\x4e\x78\x18\x73\xdf\x1f\xb1\xaa\xda\x02\x1a\x04\xb1\x56\x71\xda\x1a\x8c\x0c\x0d\xee\x07\x4f\x3b\x48\x94\x48\xb1\xc5\x74\x58\xf1\x11\x83\xb6\xeb\x5e\x46\x18\x4f\x92\x20\xd1\x48\x82\x94\x0a\x8f\xd9\x4f\x2c\x07\xd2\x99\x10\xa4\xe8\xa5\x5e\xcb\x4b\x26\x88\x19\x11\x01\xf3\x09\x3e\x9f\xfd\x08\x83\xa4\xe7\x32\x58\x9a\xd5\x76\x18\x08\x75\x93\x20\x60\x02\xbc\x3e\x04\x73\x6b\x40\xb7\x0f\x85\x7c\xd5\xd9\x11\xbf\x6d\x57\xc3\x0b\xe2\x7e\x64\xc0\x1c\x59\xbe\x43\x87\x78\x74\x37\x8b\x07\x92\x96\xc9\x79\x56\xcb\x22\xcb\x37\xc5\x5b\xbb\x3a\x05\x90\x30\x22\xad\xfd\xab\xbf\xa1\x04\xc0\x38\x4f\x6d\xec\x49\x5f\xac\xda\x23\x5c\x90\x9d\x50\x2b\xde\x7b\xec\x69\x07\xf9\x1f\xac\x66\x01\x48\x93\x05\x7d\xb1\xaf\x0f\x59\x85\xff\x02\x7c\xf5\x0f\xfb\xa6\x5d\x3a\x14\x2c\x04\xa0\x39\xd5\xcb\xcf\x76\x07\xe9\xd3\x8e\x20\x10\x71\x4a\x3b\x05\xd4\x87\xb3\x79\xb0\xd9\x71\xfc\x60\x45\x9a\x74\x1e\x0b\x0e\x75\x19\xb8\x33\xc8\x54\x73\x27\xe5\x6e\x9e\xe6\xf0\xd3\x12\x0c\x6b\xac\xc4\xbf\x50\xd6\xcb\xfa\xa5\x67\xc9\x62\x71\xcf\xed\xa9\xa4\x3f\xd4\x4b\xb7\x21\xc2\xf4\x1d\x52\x29\x1a\xa9\x0f\x75\x84\x6a\xf0\x2c\x14\x8b\x68\xe2\x80\x52\x73\x57\x80\xf8\xcc\x89\x03\x02\x85\x8a\x60\x56\xbb\x99\x51\xe2\x32\xea\x78\xee\x7c\xc8\x15\xad\xf7\xd5\x25\xaf\xb0\x76\x99\xda\x5d\x6f\x99\xd1\x01\x37\x53\xf5\x08\xd9\x69\xb9\xde\x49\x03\xa8\xbb\x1f\xe9\xf0\x43\xa0\x43\x23\x09\x96\x5f\x4e\x36\xf7\xa8\x48\x06\xc8\x1d\x4e\xc1\x0a\x66\xe4\xc5\x25\x97\x23\x8f\x11\x08\xbd\xd4\xac\x96\x15\xe6\xca\x9a\xba\xa1\x7d\xcf\xfb\x11\xd2\x24\xaf\xd3\x9d\x82\xc7\x14\xd1\x29\xcb\x61\xff\x82\xf5\x27\xc5\x37\x08\x3d\x11\xc4\xd6\xfe\x6c\x9f\xc9\x57\x1c\x06\x28\xa1\x1f\xc9\xc4\x66\xeb\xb3\xba\x38\x75\xd1\x4d\xe8\x8b\xb0\xfd\xa2\x1a\x8d\xfd\xe5\xef\x78\x9d\x34\xa4\x84\xd0\xc7\x84\x45\x1d\x56\xde\x5c\xd2\x8e\x04\x25\xba\xf7\x32\x0c\xd2\x44\x98\x16\xc1\x63\xa1\xa8\x25\xb8\xca\xcd\x76\x30\xb5\x63\xbb\x77\x20\x0c\x03\x9f\xa2\xfd\xe7\x4c\xd7\xcd\x92\xd3\x63\x73\x43\x18\x0a\x49\x31\x71\x56\xad\xf2\x1b\x96\x1a\x84\x91\x08\xa3\xb8\xad\x3b\x57\x2d\xf5\xbf\x3b\x4c\x92\x99\xc4\x52\xdf\x94\xf8\x33\x2b\x2e\x95\x69\x75\x7e\x1a\xae\x84\x91\x82\xd8\x92\x80\xf7\x24\xc0\x3f\xcc\xc9\xdd\xa5\xc7\x81\x99\x99\xb5\x95\xa7\x77\x1c\x81\xc3\xf4\x5b\x11\xc6\x31\xa7\x1a\x19\xd4\xc6\x01\xad\x9d\x41\x83\x48\x64\xf0\x08\xe3\x58\x51\x07\xf9\xd0\x83\x19\x1c\x0b\xa8\xcd\x4a\x31\x60\x87\xba\x4f\x30\x19\x44\x6d\x0e\xb7\x81\x4b\xb7\xdc\x85\x31\x84\xd4\x49\x68\xfb\xf7\x1f\x4b\x60\xb7\x9f\x00\xe2\x5b\x28\x84\xfa\x85\xa8\x95\xda\xf7\xdc\xe9\x92\xd0\x77\xd6\xfd\xf7\x19\xd4\x1b\x82\xb3\xdd\xe8\x3b\x40\x98\x30\x24\x20\x62\x56\xfd\x78\xec\x70\xdb\x10\x26\x16\xdc\x36\x60\xca\xfe\x36\x04\x89\x43\x98\xc6\x91\x84\x49\xfe\xff\xb6\xf7\xac\xd3\x24\xa1\xb7\xd3\x52\x88\xc7\xe0\x18\x13\x0f\x79\xed\xbf\x9f\x3f\x7f\xee\x4b\x6a\xb1\x65\x55\x6b\x96\xe7\xbe\x07\x3c\xed\xc4\x10\x0d\x91\xca\xb5\xa1\xf2\xba\x2c\x28\xf4\x72\x03\x43\x63\x5f\x70\x87\xa7\xc2\xe1\xd5\xc7\xdf\xfa\x37\xf3\xcb\xd1\xd5\x09\xa6\x89\x32\x34\x53\x3f\xb1\xac\xb3\x8a\xe0\x07\x1b\xb8\x16\x23\x17\x4f\x08\x65\x12\x52\x64\x43\x09\x02\x79\x75\x14\x87\xd2\x68\x26\xbb\xcb\x94\xcc\x2c\x21\x4d\xe4\x7d\x87\x12\xae\x2e\x6b\x5a\xe6\x3f\xb3\xb2\xc8\x6f\xa0\x03\x10\x4a\x6e\xfc\x8e\x9b\xd4\xa8\xa8\xea\x6d\x51\x9c\x1e\xfa\xc8\x86\xd1\xea\x81\x5c\x44\xb1\x4d\x8b\x4b\x83\xb9\x18\x45\xbb\x21\x2a\x2f\xb2\x91\xe0\xdd\xac\x14\x59\x5d\x42\x79\xed\x94\xfc\xdc\xf3\xb3\xa3\xb5\x8f\xdc\x05\xe5\xf3\x63\x21\x88\x80\xba\xb5\x25\x96\xee\x49\xe9\x18\xa4\x76\xeb\x71\xf5\x3c\x81\x79\x82\x50\x73\xce\x0c\x40\x43\x21\x9e\x26\xf9\x52\x10\x36\x59\x4f\xd2\x47\x05\x18\xf3\xff\xe1\x6f\x88\xbc\x08\xc3\xa8\xad\x5d\x6e\x8a\xe2\xb8\x2d\xc6\x05\x90\xc8\x4b\x25\x09\xd6\x3d\x6d\x17\xfd\x5d\x31\xf2\xa4\xf9\x30\x28\x65\x63\xba\x8e\xdb\x3a\x6c\xe1\x43\xe4\x07\xb1\x59\x45\xac\xee\xcb\x13\xbe\x0f\x55\x65\xdd\x38\xad\x28\xe6\x3b\x42\x45\xad\x19\x6b\x2b\xd7\x62\xfe\x21\x6a\x76\x3c\x52\x08\x81\xf3\xc1\x7e\xcb\x60\x03\x89\x22\x66\x04\x79\x0e\x2f\x90\xab\x23\xce\xb4\xce\x8e\xd9\xdf\x40\x9c\xdb\x8f\xc7\x2c\x66\x9d\x44\x55\x13\xc9\x6d\xd6\x9b\x8f\xed\x42\x21\x8a\x01\x3c\xaf\x23\xa9\xf7\xa8\xae\x76\x40\x62\xc9\x8e\x15\x1a\xd4\xe1\xae\xc6\x73\x30\xfa\xdd\x49\x80\x4e\xf7\x84\x9c\x98\xfb\xb5\xa1\x28\x11\x8c\xa0\x5d\xcd\xc5\x34\xcb\x87\x29\x00\x4c\xb3\xcd\x20\x4a\x03\x41\x19\xca\xee\x35\x3b\x1e\x9b\x04\xa4\x23\xa9\x42\x94\xca\x38\x31\x0e\xb6\xd4\xe2\x35\x3d\xcb\x41\x02\x15\x31\x11\x09\x6b\x91\x67\x08\x64\xf3\xd2\x85\x13\x11\x53\xc6\x20\xaf\x93\x40\xff\x2b\x43\x95\xc1\xed\x66\x3f\xba\x28\xce\x22\x82\x1a\x50\xbd\xcf\x54\xf5\xdd\x11\xf0\x89\x55\xf0\xfd\x72\x7c\x76\x8d\x41\x88\x20\x30\x15\xf9\xdd\xcb\x35\xc7\x11\x84\x64\xe2\x9d\x88\x80\x79\x54\xda\x7e\x84\xba\xcc\x8a\xea\x15\xda\x13\x49\x3f\xee\x63\x1c\x66\x5a\x1b\x56\xd8\xf0\x6c\x76\xb4\x10\xbe\xd5\x0b\x34\xb3\xb3\x2f\x75\xdb\xfe\x16\x19\x05\xa9\x01\xaa\x52\x73\x7a\x75\xbf\x1b\xbd\x30\x32\x56\x24\x6d\x01\x4a\xb9\x9c\xe9\x06\x50\xd3\x07\x99\x41\xa4\x3c\x19\x4a\x9b\xe6\x0d\x99\xdb\x10\xa9\xd0\xf3\x8c\x48\xf1\x7a\x77\x3e\xb6\x35\x99\x48\x85\x09\xb7\x95\x3b\x53\x61\xba\x79\xe9\x14\x7a\xb4\x0f\xfe\xbe\x59\x6f\x0e\xb3\xed\xf2\x69\x76\x58\xac\x9f\xf6\xdb\xd9\x62\x7f\x98\xdd\xdd\x6d\x97\x3b\x17\x91\x46\x18\x63\x0c\x86\x93\x96\xe9\xab\x95\x93\x99\xba\xd1\x3a\x8c\x28\x8f\xfc\x42\x75\x28\x23\xd1\xb7\xcf\x4e\x7d\x1f\x78\x37\x32\x8e\x7d\x63\xe3\x6f\xfc\x6f\xbe\x95\xed\x1b\xa1\x79\x42\x54\x90\x56\x05\xca\x48\xa5\x50\x24\xd1\x65\x60\x91\x16\x61\xc2\x2d\x0a\xd0\x6c\x46\x9f\x05\x96\x91\x46\x41\x0f\x2f\x73\x26\xac\xf6\xeb\x62\x2f\x90\x66\xf1\x51\x6a\x9e\xa9\x7d\xb1\xab\xbb\x02\x48\xec\x25\x06\x44\x30\xd2\x80\xf8\x2c\x23\x62\x2e\x2f\xea\xdf\x99\xd8\x63\xa1\x46\x57\x27\x26\x58\xd7\x1c\xfb\xbb\x7d\xec\x31\x45\x7a\x5e\x2a\xcf\xfb\xeb\x68\xec\x71\x03\x40\xca\xf1\xbd\x2e\x72\xac\x8b\x67\xac\xcf\x90\xa9\xee\xb8\xa6\xcb\xb7\x20\x7e\x54\x07\x74\x7a\x4c\x10\x7b\x22\xa4\xb6\xf0\x6a\x67\xf8\xfc\xed\x03\x7e\x9c\x7d\x59\x2d\x0e\x4f\xdf\x1e\xe7\xcb\xad\x1b\xec\x33\xa3\xa1\x65\xec\x18\x5a\xd4\xda\x70\xfa\xc6\x3e\x18\x2d\xad\x0a\x6b\x53\x8c\x20\xd7\xb8\xee\xb9\xc4\x3e\x20\xb5\x7d\xb7\xb3\xfd\xf2\xb0\x58\x6f\x9f\x96\xdb\xdd\x7e\xfd\xb4\x74\x5f\x13\x78\xa6\x60\xf5\x70\xb1\x22\x70\x9f\xbd\xba\x71\x10\x07\xc6\x3e\x57\xf4\x59\x69\x10\x07\x42\x0a\xc3\x27\xda\xed\x17\x65\xf1\xd6\x0b\xc2\xe2\x40\xa6\xd4\x9c\xb4\xb9\x79\x31\xf2\xe8\x6b\x06\x00\x91\xbd\xbe\x2e\xfb\xdd\x78\x7b\x30\x14\xc2\xb7\x46\x0e\x60\x7a\xed\x05\xf5\xbc\x06\xd3\x29\x8e\x22\x03\x69\x70\x8a\xf1\xa3\x93\xc4\x5e\x42\xd5\x41\x53\xec\x82\xe3\x7d\x51\x76\xad\xb6\x38\x0e\x14\xed\x22\x6e\xd9\x69\x2e\xde\x6f\x0f\x26\x9c\xf6\xe6\x26\x7c\x59\x50\xb3\xfa\x73\x23\xb2\xe1\x3c\x8f\x49\xb2\xd4\xf6\xf2\xe7\xab\xaf\x50\xbd\xdc\x17\xe5\x63\xa1\xa6\xe2\x8e\x38\xd6\x11\xa1\x8f\x4f\x4d\x7a\x73\x5d\x1e\xb3\xe7\x4c\x64\xc7\x5e\x93\xc5\x8e\x4b\x12\xa5\x0c\x81\xbe\xe3\xfe\x4e\x86\x46\x71\x92\x32\xe7\xfe\xb8\xb9\x94\x15\xf6\x71\xb5\x1f\xf4\x5b\xe2\x14\x03\xb0\x56\xcf\xc5\xf1\x27\xaa\xc9\x76\x61\x6f\xb8\xd6\xa6\xf8\x6f\xe9\x33\xff\xec\xa9\xd8\xff\xbd\x6d\x3c\x66\x3a\x76\xae\x17\xf7\x88\x8f\xf0\x3a\x8a\xef\x63\xee\x73\x68\xa6\xd0\xdd\x6c\xbd\x43\x79\x29\xb3\x4e\xaf\xe1\x46\x7d\x6d\xea\xab\x1c\x08\x11\x62\xae\x7c\x0a\xed\x4c\x25\x8a\x80\x24\x83\x09\x0e\xbe\x12\x46\x85\xe1\xe7\xe7\x24\x0d\x88\x45\x18\x51\x35\xb6\x49\xf6\x9f\xf3\xdd\x45\x18\x7a\xd8\xf4\x82\x17\x0b\xf0\x0c\x34\x67\x14\x30\xc4\x42\x48\x15\x38\x92\x16\x89\x28\x9a\xe8\x6f\xfc\x96\x08\x69\xf4\xd8\x0a\xad\xb1\x6c\x12\x94\x26\xfd\xff\x8e\x1f\x68\xfd\x43\x2c\x90\x69\xd6\x23\x09\xff\xea\xd7\x68\x49\x92\x8f\xd6\xc2\xd9\x00\x11\xbe\x16\xc5\xeb\x47\x62\x60\xa3\xcf\x4b\x4f\xa6\x5e\xe7\x0a\x3f\x28\x31\xba\x21\xca\x54\x2a\xff\x2a\xb2\xbc\x0d\x07\xc7\x43\x8c\xa0\xca\xfa\xa1\x09\x84\x76\xd7\x1c\x6a\xc7\x1c\x84\x58\x41\x44\x2d\x35\x02\xe2\x34\x69\x03\x9a\x5c\x7e\xad\xc7\x08\x65\x88\x31\x60\x14\x77\xcf\xe6\xf3\x85\xfb\x3c\xaa\x90\xd0\x98\x87\x73\x41\xa2\xbe\x5b\x33\xc1\xcb\x19\x15\xab\xc9\xd2\x74\xb2\x3c\x11\xa3\x0e\x9c\x6d\xe0\xf7\xa2\x46\xd2\x80\xbe\x99\xda\xc3\x8f\x68\x8f\x93\x8e\x05\x31\x29\x56\x0a\xc1\xa4\x3c\xbf\x80\x9d\x41\xac\x03\x23\x1a\x3b\x5b\x7f\xf9\x50\x20\xed\x17\xff\x9a\x33\x25\x5e\x1a\x91\xf8\x5f\x9d\x9d\x70\x9d\xe3\x0e\x7b\x62\xe1\x90\x78\x8c\xf1\x7e\x8b\xba\x6d\x70\x3b\x04\xca\xe0\xb9\x24\x1e\xb8\x44\x9c\xba\x6c\xb6\x9e\xd6\x73\xcf\x1c\x0d\xd7\xc2\xa9\x78\xec\xdf\xb7\x45\x31\x4a\x78\x12\x3f\xf2\x68\x01\x7b\x43\x7c\xdd\x14\xf5\x83\xd1\xf6\x71\x07\x53\xdf\x08\xed\x5f\xce\x58\x4e\xf9\x3b\xd9\x71\x01\xf8\xba\x53\x65\xa4\x38\x75\xa8\x96\x6a\xc7\x45\x5e\x14\xd8\xda\xf7\x06\x4b\x2b\x9a\x5e\xb5\xc4\x8e\xd1\x60\xa5\x9d\x88\xfb\x1d\x56\xf5\xbf\x26\x16\x9a\xc9\xf7\x27\x89\x55\x18\x5a\x1e\xdd\x7d\x89\xb8\x39\x42\x2b\xd4\x04\x49\x92\x70\xd1\x19\xe9\xd8\xda\xdf\x00\x8d\x6a\xcb\xc1\x53\x8b\x98\x3f\x04\xa9\x42\x92\xa4\x9c\x30\x43\x26\xeb\xa1\xfd\x8e\x64\x45\x37\x58\xee\x5f\x8a\x4b\x05\xb9\xba\x2f\xca\xf9\xa5\xc9\xb4\x47\x37\x3e\x11\x48\x6b\x96\x34\x5a\x93\x0f\x98\x3f\xd7\x2f\x6b\xdd\x5e\x27\xfa\x84\xeb\x47\x2b\xa5\xb8\xcb\x9e\xa9\xec\xb4\x5b\x6f\xdc\x90\xd4\xc7\x58\x0f\xea\x35\x3f\x7d\xde\x1d\x34\x8d\x4f\xda\xea\x1d\x31\x6f\x25\x8b\xd1\x55\xa4\x9c\xeb\xa0\x7d\x72\x63\xa7\xa9\xd1\x58\x30\xc1\x6e\xb3\x8c\x99\x88\xfb\x08\xd7\xf1\xf9\x04\x38\x65\x0b\xe3\xa2\x5f\xed\x5b\xd4\xe6\xfc\xba\x7f\x1f\x0d\x67\x29\x03\x3b\x21\xe6\xb3\xf9\x0d\x6e\xb6\xb7\x23\x27\x8c\x19\x13\xa2\x6f\xf9\xef\x5d\x77\x28\x61\x22\x22\x7a\xd5\xb1\x28\x5e\x2f\xe7\xd5\x6e\x1d\xfa\x7e\x72\xf0\x0f\x70\x3c\xbf\xc0\x21\xfc\xad\x7f\x06\xee\x43\x90\x38\xa6\x12\xe5\x29\xd5\x06\xaa\xae\x64\x96\xf0\x58\x91\x3b\x9f\xa9\x2b\xad\x6a\x3c\x7d\x14\x61\xb4\x21\xf7\x64\x6d\x37\xe1\x89\xa2\x1c\x63\xb6\xdd\x1f\xee\xd7\xdf\x9e\xee\x0c\x40\x6e\x98\x3c\x24\x1c\x55\x07\x5a\x7f\x6b\x42\xde\x6a\x3e\x56\xf7\x87\x04\xbc\xd4\x0f\x7a\xf9\x4a\x97\x53\xb7\x5b\x69\x02\x22\x09\xdd\x4b\x4e\x92\x38\x2d\xe2\x28\x01\x69\x60\x1e\xd4\xd5\xf4\x0e\x54\x47\x81\x2a\x93\xfb\xf7\x36\x66\x77\x23\x95\x47\x42\xf1\x9b\xed\x62\x7f\x98\xaf\xbf\x3d\x39\xba\x0d\x24\xc2\x0f\xa8\x3b\x41\xc5\xcf\x2f\xc6\x16\x3b\x2b\x86\x4a\x8d\x6e\x68\x1c\x5a\xd5\x2e\x92\x23\xb6\x92\xc5\x93\x8b\x79\x22\x94\xa0\x7d\xf1\xf0\x4b\xca\x59\xff\x31\xaa\x30\xa5\xa4\xcf\x2c\x55\x14\x37\xb8\x23\x4c\x93\x4f\x84\x84\xe3\x91\x76\x92\x66\xfd\x3c\xf8\x13\xea\x58\xdd\xed\x45\xcf\x28\xdc\xce\xb6\xfb\x41\x99\x26\xc1\x38\x4d\xcd\x2a\xf2\x13\x09\x64\x4b\x6b\x76\x7f\x87\x48\x50\xc6\x51\x5f\xca\x1d\xc7\xd6\x97\xbd\xac\x2c\xd1\x61\x4c\x52\xd4\xcb\xfa\x25\x3b\x35\x71\x2f\x49\x18\x2d\x9f\x9f\xdb\xa5\x49\x87\x9c\xd6\x2d\x2a\xaa\x63\x79\x5b\x77\x4a\xb4\xf4\x42\x03\x51\x44\x43\xf3\x9b\x97\xd8\x2b\x68\x0c\x9a\xdb\xfd\xff\x68\x3f\x2e\x09\x77\x68\xfa\xef\x73\xec\x13\x62\x20\xf5\xa2\x24\x71\x89\x98\xf1\xa8\xad\xfa\xa2\x08\x90\x7a\x3a\xa1\x84\x6b\xb7\xdf\xce\x06\xa8\xbc\xd4\x0f\x34\xa5\xf6\x59\x35\x87\xba\x3e\xa2\x95\x12\xb0\x71\x5b\x7b\x02\x3f\xf4\x08\xbe\xbb\x5a\xae\x6e\xbd\xd1\x26\xd7\xf2\x34\x88\x91\x48\x3f\x16\xeb\x46\xc8\x97\x29\xee\x38\xa4\x01\x37\x05\x77\x97\x77\x7c\xcf\xca\x4b\x65\x56\xd5\x9b\x91\x82\x9c\x48\x17\x4f\x7f\x1e\xd6\xa7\x3c\x53\xc5\xf1\x08\x6e\xcf\x4b\x03\x19\x87\x56\xd2\x8a\x76\x25\x43\xed\x5c\xb6\xa9\x63\x1a\x82\xd1\xc5\xfa\xb2\x9d\x3d\xed\x0f\xf3\xd9\x7e\xf1\xb5\xe7\x5f\x04\x69\x28\x85\x79\x48\xf5\xfb\xe0\x26\x85\xda\x23\x99\xbd\x4b\x45\x9b\xb6\xfb\x73\x22\x82\xd8\x11\xb8\xcc\x65\x36\x29\x91\xa5\xde\xf7\xa7\x5b\x9a\x72\xa1\xda\x3e\xac\xed\xcf\xef\xb3\xf1\xbe\x99\xa6\xd2\x7c\x4f\xf5\x02\xfb\x97\x12\x87\xd1\x58\xca\xe2\x20\x09\xdd\x49\x8c\x18\x26\xdd\xae\x59\xf9\xfc\x8b\xb8\x34\x65\x31\x37\x30\x3c\x63\x5e\x3d\xcf\x6e\x89\x0e\xe3\x00\xf5\x83\x7c\x65\x7c\xe2\xc4\xa3\x89\x85\x4d\x3a\xf9\x15\x4a\xd5\xba\x4a\x41\xca\x84\x9f\x1a\xfe\x0c\xbc\x99\x1d\x05\xca\xab\xc9\x78\xdd\x8b\x93\xf2\xc4\x0f\x6c\x97\xf8\xe1\x72\xc2\xbc\xea\x66\xd7\x64\x40\x96\xf2\xc4\x48\x80\x2f\xa8\x4c\xfe\xef\xe2\xc6\xc0\x69\x34\x1e\x12\x49\x92\xf0\x1d\x7a\xca\xdc\xd3\x83\x91\x51\x18\xde\x61\x40\x03\x31\xa0\x1a\x3c\x5c\x4a\xdb\xa9\xbd\xbf\xb4\xe8\x9f\x14\x74\xa2\xb1\xa5\x3d\x91\x1e\x7f\x7e\x6b\x65\x61\x07\xcb\xd0\x27\x74\xf9\x5b\xeb\xed\x72\x3a\x5d\xf2\x9b\x54\x34\x95\x10\xf1\xa0\xe5\x8f\x35\xf1\x57\x7b\x83\x54\xc2\xb4\xcd\xc9\x9d\x22\x4a\xcf\xf3\x64\xf4\x34\x30\x32\xce\x2c\xf3\xe5\xc3\x6a\xbe\x7c\x98\xb9\x93\x20\xd3\x44\x0b\x5a\x92\xe8\x8a\x69\x85\x54\x3d\xa4\x46\xaa\x13\x61\x6a\xe7\x54\x45\xb2\xda\x12\x93\xa1\x04\xf3\xb8\x4f\xa4\x19\xab\xcb\xff\x54\x28\x74\xd0\xc0\xfe\x5a\xcf\x7c\x61\x78\x9e\x27\xa8\x8c\x59\x15\x36\xd9\x62\xee\x70\x1e\x2c\x88\x7d\x16\xb7\xf0\xae\xf2\xb9\x9b\x14\x2c\x40\x4e\xe0\xc1\xc2\xa8\x1b\x60\xe9\xea\x08\x2c\x94\x9e\xab\x63\xec\xea\xe2\xbc\xc3\x5c\xfd\x40\xf1\x25\xd3\x75\xaf\x5a\xc3\x22\xa6\x85\xe7\x58\x3a\x63\x7b\x3b\x60\x11\x0f\x0c\xb3\x9c\x7a\x86\x77\x7d\x7a\x7c\xfb\x45\x4d\x20\x6a\x54\xd3\x5a\xd3\x63\x53\xf0\x77\x03\x52\x86\xd4\xc8\x32\x40\x7a\xaa\x0b\xf9\x1e\xb1\x10\x96\xcd\xd2\xb2\x7e\xfa\xe6\x82\x05\xc6\x62\xa3\x59\x58\x61\xbd\x07\x71\xc4\xdd\x0d\x98\x96\xb1\xd8\xf0\x8c\x4d\xdd\xef\x94\xe5\x9f\x6c\xa8\xa3\x4f\x32\x49\x4b\x46\xb3\x71\xae\x46\x19\x02\xe3\x91\xb1\x00\x34\x4d\xc6\xe1\x62\xc3\x78\x24\x3d\xd6\x11\xfc\x7e\x14\xd5\xa6\x28\x8e\x84\x28\x69\xde\xd5\x1e\x75\x0c\x18\x84\x46\x1f\xa5\x84\x1a\x17\xed\x1f\x79\x1a\xb7\x10\xb9\x16\xfb\xd5\x83\xe9\x0e\xdf\x06\x06\x2a\x21\x96\x24\x41\x00\x56\xd5\x16\xf3\x7a\x7e\x9d\xd5\x9d\xcf\x94\x1d\x27\xd2\x40\xeb\x3e\xa8\xd9\x3a\xc7\x18\xd4\xc5\xf0\x9c\x4a\x86\x21\x74\x6b\xa2\x2c\x4a\x65\xf9\xbb\xfd\xb9\x88\xd2\x23\x11\xe1\x5f\x47\x2b\x53\x81\x06\x43\x05\x62\xbc\x7a\xff\xcd\xc7\xa3\xa5\xc7\x48\x7f\xfa\xfd\xb6\x2a\xc7\xb4\x0a\x88\x7f\xdf\xbc\x6f\x16\xc7\xd1\x89\x15\x00\xf7\x12\x1e\x1a\xcc\x1f\x6d\xf6\x5b\x6a\x7e\x8d\x3c\xc0\x80\xfb\x41\x6a\x44\xb7\x10\xab\x5d\xdd\x3c\xa0\x67\xf7\x8e\xf1\xc0\xca\x1d\x9c\x33\xf9\x0a\xef\xed\x89\x83\x50\x51\xa5\xe8\xfe\x52\x5f\xca\x3e\x62\x8b\x07\x5a\x50\x20\xb1\xaa\xaa\x0b\x6e\x09\x6e\x72\xf3\x85\xa1\xe7\x73\xdb\x57\xb4\x8c\x95\x9b\xea\x3e\x0f\x7d\x16\x6b\xfb\xcb\x9a\x4c\xff\x3a\xd2\x6e\x9e\xbe\x5b\x3c\xd4\x8c\x39\x1f\x93\x2c\xbf\x8c\x3b\xd4\x3c\x49\x23\xd2\xb3\xcd\xf1\xbd\xb6\x26\x6d\x8f\xb4\xbc\xb8\xeb\x4f\x18\x92\xe4\xc7\x29\xcb\xe7\x58\x0f\x00\x49\x3c\x81\x88\x63\xab\x76\x40\x65\x5e\x7b\x0e\xf7\x52\xf3\x34\x69\xcd\xaa\xd7\x79\x93\x34\x9b\x33\x18\x95\x1a\x37\x86\x71\xea\x57\xd6\x25\x64\xf9\xef\x59\x3d\x5e\xcc\x39\x8b\x14\x95\xd9\x76\x97\xbf\xb2\x7e\x14\xc1\x59\x0c\x86\xd8\x62\x49\xe4\x87\xd3\x13\xbe\x6d\x8e\x45\x7d\x87\x3f\x47\xf8\x4c\xfb\x09\xee\xa5\xd4\xd8\x3a\xc3\x35\xf6\x3c\xb7\x75\x8e\xc6\xa8\x94\x18\xa1\xc4\x5d\xbf\xbb\xe4\xcf\xd8\x11\xa9\xfe\x13\xfd\xb7\x4f\x69\x05\x0e\x91\x74\x94\xaa\xcd\x7a\xfd\x60\x90\xc4\x81\x5b\xf5\x38\x48\xe1\x59\x95\xd8\x92\xfc\x8f\x66\x65\x09\x37\xb9\xbb\x1b\x8c\x52\x9b\xe9\xf9\x2d\x2f\xde\xf2\x9b\x79\x02\xda\x98\x8b\x3d\x63\xfd\xa5\x38\xaa\x3f\xe4\xcb\x73\xaf\x37\xc0\x45\x64\x78\x1e\xd6\xd3\x71\xb9\xff\x7a\xd3\xce\xe1\x02\x4c\x1b\xf0\xfe\x92\xdf\xc3\x10\x96\xcc\x25\xa6\x84\x92\x6c\xe6\xd5\xbe\xa5\x72\xec\x6a\xb2\x61\x71\x54\xd3\xd1\x25\xa9\x20\x24\x10\xcb\x0b\x54\x5b\x13\x95\x2a\x22\x46\x9b\xf6\xa2\xdb\x7f\xb8\xd2\x86\xab\xd6\xec\x32\x2f\x43\x83\x3e\xe0\x98\x68\x6a\xf2\x2c\xdf\x41\x67\x65\xfb\x73\x90\x05\x34\x2d\x2e\x64\x0a\x4e\x2c\x47\x6a\x34\xb8\x27\xe1\x7e\x92\xf6\xfd\x54\x77\x74\x67\xca\x65\x1f\xe1\xfd\xae\xc8\x8b\x9b\x47\xab\x83\x88\x40\xb7\x0b\x38\x9f\x51\x4d\xa0\x48\xb8\x56\xc6\xb8\xb4\x2d\xe6\x7d\xa0\xa6\x00\xe0\x25\x86\xb3\xf3\x05\xc9\xac\x97\x6a\x7d\x83\x1f\x06\x1e\x04\x49\x64\xd1\x9a\xfd\x3b\x0d\xbe\xa7\xa3\x5e\x20\xdf\xdb\x69\xc1\x07\xe6\x2c\xec\x9b\x50\x54\xcd\x8b\x0f\xea\x4c\x10\x72\x46\x5b\x51\xf3\xe1\x47\x3c\x15\xe5\xd5\xcc\xad\xde\xc9\xa2\x98\xe9\xa8\xed\x4b\xd5\xa8\x9a\x04\x11\xab\xb1\x72\xca\xe8\xc4\xb1\x1f\x51\x1c\x61\xf5\x4d\xf7\xcd\x0b\x5d\x4e\xe6\x19\x10\x87\x09\x57\x4e\x3b\xae\x2c\x8b\xb7\x2c\x7f\xa6\x52\xc1\xe8\x8c\xb6\x63\xdc\x5a\xd3\x7e\x1a\x5b\x43\x2c\x81\xf4\x1e\xb0\x94\x81\x37\xbf\x5c\x6f\xd6\xb8\x89\x0a\x25\xc4\xca\x43\xab\x7f\x64\x85\x22\x8b\xfc\x52\x2d\x89\xe3\xd9\x07\xe6\x42\x8c\xbe\xc3\x09\x39\x78\xe1\x6f\xed\xa1\xd4\x0a\xd0\xbf\x62\xbe\xe9\x79\x34\x7d\xb9\x40\x09\x79\x8d\x7f\x73\x93\x82\x24\x50\xa1\x6e\x6b\x7b\x16\x9a\xba\x2f\xa8\x09\x36\x1a\x99\x1a\x8b\xda\x7d\x39\x7a\x1d\x21\xd5\x32\x31\x18\xb7\xaa\xde\x76\xf6\xac\x00\x10\xa9\x20\x18\x08\xb0\x6c\x16\x7f\xde\x52\x11\x46\x97\x04\x31\xa3\xbc\xc2\xec\x1b\x04\x8f\x1a\x25\x4b\x00\x8a\xbb\xf5\xc5\xec\x43\x64\xee\xd7\xc1\x2c\xba\x61\xbe\xd1\xd7\xc9\x7f\x62\x59\xef\x8b\x4d\x99\x9d\x8a\x52\x65\x70\x1c\xfd\x38\xc1\x3c\x2a\x80\xe1\x09\xcb\x67\xcc\xe5\x95\x42\x4c\x18\xa3\x43\x40\x70\x15\x72\xc7\x13\x24\xf0\x38\x8c\xaf\x4d\x48\xdf\xb0\xf8\x69\xa1\xbf\x01\x90\x4d\xbf\x22\x92\x7b\x06\x41\x59\x17\x65\xeb\x02\xe3\xf6\x72\x90\xda\xd3\xa6\x90\xd3\x84\xcb\x03\xde\x18\xa8\x08\x22\x7b\x45\x77\xd6\xbb\xf0\x83\xbe\x14\xa8\x04\x45\x77\x65\x03\x2d\xbc\x5e\xc9\x03\x94\xf0\x23\x18\x8a\x98\xec\xdf\xad\x44\xc9\xef\x3f\x5e\xc6\xb4\x34\xfb\x29\x8c\x24\xd9\x8c\x5c\xac\x5a\x42\x65\x44\xd3\x0c\x37\x62\x34\x54\x28\x0a\x8a\xef\xb3\xe7\x97\xfa\x60\xe0\xd6\x37\x02\xf1\x83\x1b\xe5\x07\x6c\xf0\xef\x68\x45\x18\xfd\xa7\x8d\x44\x40\x7b\x41\x2a\x06\x39\x7a\xab\x3c\xbd\xba\x81\x3c\xba\xcf\xf8\x9c\x5a\x1c\xe6\x1e\x91\xf6\xdb\x02\xf3\xba\x22\x24\xca\x55\x5a\x49\x92\x36\x6c\x00\x9d\xfa\xd8\xc6\x87\xbb\x42\xd7\x0b\x38\xaf\x5f\xdb\xa3\xe0\x51\xa6\xb0\x80\x7a\x6c\x7f\x0f\xc2\x8b\x13\xea\xb0\x7c\x59\xdd\xef\xff\x9e\x89\x04\x08\x3f\x12\x56\xe3\xfc\x88\x43\xac\xbf\xf0\x99\x47\x16\x08\xf9\xe5\xf4\x50\xb4\x49\xa4\x08\x64\x94\xd8\xb8\x66\x77\x1c\xfc\xdd\x9c\xc9\x84\x44\x2f\x50\x62\x45\x91\x9f\x6a\x07\x60\x44\x1a\x3c\x5f\x66\x8f\xcb\x1d\xd9\xe9\xdd\xb5\x87\x34\x4b\x8c\x14\x42\x71\xfe\x5e\x74\xca\xab\x20\xc2\xd4\x8f\xa3\x16\xfc\x3e\x29\x2c\x08\x22\x14\x06\xc5\xfb\x63\x39\x2c\xde\x89\x10\x05\xc9\x1c\x3e\x7d\x7b\x78\x38\x2c\x9f\x16\xdb\x3f\x37\xa6\x02\xfb\xf0\x65\xbd\x5d\xed\xbf\x3e\x1e\xee\x96\xbb\xc5\x76\x65\xfe\xfa\x6d\xbb\x3a\xec\x96\xfb\xc3\xaa\xbd\xae\xc8\x63\x04\x86\x22\xb3\x9e\x7e\x16\x20\xa2\x20\xa6\x88\x01\xdf\x4d\xd2\x7e\xa8\x8b\x43\x66\x13\xf8\x03\x19\x2b\x1d\xf2\x09\xf4\x8b\x88\x42\x29\x5a\x7f\xf9\xfc\x79\xe0\xb1\x00\x22\xe2\x09\x31\x27\x8c\xbb\xc8\x16\xb2\x0a\x55\xcf\x7b\x0d\x44\x24\x85\x93\xbe\xfc\x01\x65\xb3\x30\x5f\x37\x3d\xda\xd6\xe7\x5d\x5d\x11\xc7\xe6\xd5\x6e\xee\xde\x41\x17\x65\xbb\xb0\x8a\x38\x35\xb2\x28\x75\x79\x41\x91\xd5\xa3\xcb\x8a\xa5\xb9\x68\xb3\x99\xce\x07\x04\xf1\xfe\x4d\x49\x52\x21\x6c\xc7\xe5\xa9\xa8\xfb\x74\x46\xc1\x82\x58\x5a\xb1\xb4\x05\xe4\x3f\xa1\xa2\xa0\xc1\xbe\x6b\x83\x19\xc9\x98\x59\x11\x77\xfb\xdd\xdf\x98\xbf\x4c\x1a\x66\x7b\x75\x3e\x5a\x4a\x59\x35\x47\x5d\xf4\x74\xe3\xc6\x5a\x00\x20\x78\xc8\x28\x32\x15\x70\x3c\x16\xf5\x43\xd1\xd2\x6f\xff\x13\xfc\xd7\x0d\x11\x26\xad\xcf\x2a\x13\xd6\xf7\x89\x8d\xff\x98\xe2\xa1\x09\x2e\x81\xca\x33\xff\xbc\xe4\xcf\x47\xdc\xc9\x92\xbc\x54\x86\xf3\x94\x6b\xa3\xe1\x7a\x97\x3d\x67\x3f\xb2\xe3\x71\x30\x57\xc1\xd7\xc4\x2c\x3f\x38\x62\xc2\xdb\x07\xd6\x9a\xbf\x78\xc8\xcd\xe2\xde\xac\xed\x7f\x62\xfd\xfe\xaa\xfc\xc4\xf3\xdb\x6f\xc0\x84\x77\xf2\x6b\xfa\xfd\x1e\x47\x31\xad\x10\x41\x4c\xbd\xb6\xf7\x83\x2c\xf2\x8a\x4c\xea\xc6\xc5\x67\x21\x52\x23\x53\xd3\x6c\xf0\x60\x64\x92\xdb\x67\x39\x46\x84\x09\xa1\xa4\xa9\xb1\xae\x57\x4f\x87\xc5\x7a\xb7\x3f\xac\x16\x6b\x03\xb5\x71\x8c\x05\x21\x7d\x49\xd8\xd2\x4b\x7e\x6e\xb6\xe6\xd1\x25\x49\xc9\xa8\xfd\x3a\x72\x5c\xb5\x91\x70\xa7\xe7\xd6\xfc\xbf\xfd\x2e\xc1\x44\x35\x72\xf4\xef\x7f\x42\xf7\xb4\x15\x32\x52\x01\x97\x45\x96\x8f\x52\x72\x3b\x02\xfd\xc8\x37\x24\xe0\xbc\xf3\x65\x71\x3f\x00\x65\x14\x0d\xd1\xca\xdf\xb1\xec\xb5\x76\x05\x62\x42\xa6\x53\x35\xbc\xef\x47\x38\x58\xa1\x3d\x8f\x34\x19\x9f\xf0\xed\x53\xf3\x69\x37\x3c\x46\x30\xf8\xcd\x77\x23\x53\x82\xca\x68\x94\xb8\xe3\x49\x4c\x2b\x96\x25\x91\x4d\xaf\x97\x5a\x20\x65\x5b\x47\xa8\x2c\x88\xb8\x8f\xc0\x97\x1e\x63\x54\x06\x9a\x93\x5a\x68\x2f\xa5\x97\x81\x07\x82\x75\x86\xda\x16\x71\x34\xb8\x42\x19\xc4\x11\xd5\xf4\xcc\x03\x9b\x46\x60\xdc\xa2\xde\x65\xc0\x42\x17\x76\xac\xf2\x9f\xd9\xc7\x80\x53\x37\x5e\xc4\x0e\x4c\xb1\x3c\x1f\x61\x28\x90\x0d\x32\x0c\x43\x20\x66\xc2\xb8\x71\x2e\xc3\x48\x13\xb6\xa9\x7e\x29\x8b\xb7\xfb\xc2\x81\x33\x65\x08\x11\x71\x5d\xad\x26\x99\xc3\xa1\x8a\x23\x3e\x61\xad\xb7\x38\x3e\x8d\xf4\xb5\xdd\x98\x88\x1c\x88\xfd\x2c\x68\xf8\xd3\x22\x3f\x21\xf8\x0e\xad\xd4\x54\x8b\x37\xb1\xb9\xfb\xe6\xd8\xc3\xc8\xc4\x6a\xcf\xfb\xb7\x42\x98\xe0\xdd\x49\x4e\x80\x8c\x83\x90\xde\xa1\x1a\xc1\xfa\x01\x59\x8b\xec\x76\x75\x95\x71\x20\x8c\xf7\xf3\xf5\x90\x77\x6c\x5f\x19\xa7\x9a\x4a\x10\x2f\x50\xb5\xd5\x89\xe1\x6d\x8a\x85\xb1\x0e\x22\xcb\x2c\xc7\xd1\x1a\x46\x57\x32\xd6\x82\x5c\x11\x5c\xe4\x79\x67\xb8\x8e\xa3\x14\x5d\x26\x51\x6a\x84\xd4\xb0\xaa\x1f\x8a\xfc\x19\xcb\x7f\x56\xed\x2b\x20\x93\x38\x20\x0e\xe9\x1b\xfc\xc4\x6a\x80\x2f\x94\x49\xa2\x3d\xbf\xb5\x36\x55\xd9\x27\x48\x28\x99\xa4\x52\x77\x4b\xd8\xf7\xd5\x66\x0b\xf9\xeb\xe8\x37\x25\xc0\xa8\x95\xe7\x0a\xe5\x2e\x7f\x1f\x90\x92\x64\xa2\x91\xde\xf9\x23\xfe\xc4\xe3\x21\x19\xe5\x43\x32\x65\x8a\xaa\x47\x75\x86\xa5\xe1\xb6\xd0\x13\x1b\x5e\x4d\x0a\x02\x43\xa3\xad\x8f\x55\x6d\x4d\x8c\xad\xd3\xde\x74\x38\x28\x53\x11\x78\x60\xde\xdf\x05\x9c\xad\x72\x7d\x6b\xc2\x01\x92\x01\xa3\x4a\x77\x56\x59\x56\xe7\xf0\xe3\x3c\x0e\xa4\xad\xb9\x18\x21\x7a\x2b\x3d\xe6\x0e\xa7\x7e\x30\x81\xfc\x9a\x5c\x05\x24\x57\x01\x3d\x57\xda\xcf\x5f\x8b\x3c\xc7\x96\xd8\x24\x21\x95\xda\xf8\x10\xe1\xcf\x61\x58\x28\x01\x18\xc9\x43\xaf\xaa\x65\x25\xcb\xe2\xad\xef\x12\x09\x52\x04\x26\x59\xa1\xd7\xb8\xbe\xf7\x7f\x1b\xdc\x30\xa1\x4d\x15\xd2\x48\x63\xf7\x24\x6a\x40\xca\x94\x7b\x46\xab\xac\x49\x15\x7b\x25\x76\x29\x31\x26\x11\xca\x26\xc3\xb6\xc6\x0a\x7d\x4d\x16\x90\xca\xe3\x84\xa4\xa7\x42\xf9\x21\x88\xbd\x43\xec\x79\xed\xc1\x34\xb2\x85\xcf\xef\x0e\xed\x38\xba\x0f\xe8\x85\x06\x18\x74\xce\xf2\xfd\x0b\xfe\x78\x41\x3c\x8e\x87\xb0\x34\xd4\xad\xba\xa2\xf9\xc5\x7d\x3e\xa9\x44\x8e\xd4\x5e\x7f\x81\xea\xe5\x50\xbd\x40\x10\x27\x53\x32\x61\x20\x51\x87\x64\x92\xb9\xfa\xb2\x72\x9f\xd5\x71\x8c\x89\x33\x5c\x5e\x1c\x8b\xbc\x3d\xad\xf2\x38\x10\x88\x93\x3c\xcc\xa6\xf1\x31\xca\x8f\x13\xd2\x17\xf8\x76\x7a\x35\x90\xa6\xcf\xfc\xa5\xdd\x67\x18\xa6\xa2\x57\x95\x68\xd6\xae\x3f\x9a\xd3\xde\x97\xc5\xe9\x0e\xce\xb7\x62\xc3\xfd\xb4\xae\x9f\x13\xa9\x20\xe4\xb4\xd0\x6e\xb0\x34\xab\x53\x0f\x2f\xaf\xc2\x38\xa1\x45\x9a\xb8\x4f\x3d\x93\x92\x1d\x1e\x75\x37\x86\x91\x4e\x89\x84\xa3\x34\x2b\x7f\x39\xc7\x1c\xf5\x98\x93\xa1\x42\xcd\xa8\xb3\x7b\x82\xf7\x81\x19\x04\xa8\x48\x70\xde\x09\x40\x2f\x5e\x20\xcf\xf1\xf8\x68\x94\xaa\xa7\x4b\x48\x2a\x42\x5f\xdb\x85\x6f\x75\xf7\x08\xe7\x73\x0f\x99\x33\x1a\x1a\x43\x40\x91\x5d\x56\x2d\x9a\xc7\xa0\x66\xb9\xa2\xa9\xe4\xbe\x3d\xf1\x22\x62\x5c\x0e\x6c\x58\x3e\x4f\xcf\x55\xe2\x25\x54\x7c\x26\x4a\xfd\xa6\x2c\x74\x56\xcf\xaf\x1f\x6a\x82\x83\x4a\xd3\x88\x28\xce\x66\x8a\x3f\x2c\xbf\x2f\x1f\xda\x00\x4a\xa5\xa8\x28\xef\x3b\xcc\x8c\x03\x82\xa1\xe9\x0d\x49\x4c\x8a\x05\x9e\x87\xad\xba\xd7\xd3\xe5\xb4\xc0\x23\x8a\xd1\x9a\xa0\x18\x13\x94\xd6\x7c\x5f\xaf\x76\xcb\xf6\xa3\xc2\xcc\x59\x03\x0e\x5a\x9f\xa7\x30\x09\x8a\xfb\x1e\xad\xa7\xf7\xeb\xc7\x75\xf7\xad\x9c\x07\x08\x0e\xc3\xb8\x7a\xda\x76\x15\x05\x37\x00\x04\x35\xf6\xd5\xa5\x9b\x35\x5c\x68\x2a\xae\x57\x75\x51\x22\xad\x12\xcd\x3a\x77\x8f\x48\x60\x0e\xab\xdb\x30\xf4\x9d\xeb\x47\x7e\xc3\xbf\xd9\x73\x42\x20\x69\x96\xf5\x44\xa3\x46\x1b\x98\x82\x48\x10\xd2\xe3\x7f\x2e\x50\x63\x19\xba\xab\x81\x58\x51\x93\xd8\xe2\xc7\x3b\x04\x80\x92\x5e\x4a\x6b\xb5\xf3\xee\x79\x84\xd7\xee\xd5\x95\xb1\x2f\xcd\xac\x21\xe5\xc2\x41\x8d\x45\xc9\x38\x8e\xba\x18\xe9\xa9\xc8\x9b\x99\x95\xe5\xcf\x4e\x41\xb3\x2c\x0a\xfd\x61\xfd\x62\x5c\xc2\x9c\xb0\x4e\x74\x5f\xa3\x18\xd5\xd1\xa4\x63\xad\x95\x59\x8f\x4d\xf1\xa1\x82\x20\x28\xa9\x7d\x23\x39\x47\x00\x91\x9e\xb9\x08\x28\x15\x06\xa6\xea\x0f\x27\x5c\xe6\xaa\x0f\x1d\x51\x0a\x02\x8f\xf5\x8d\x19\x66\xa6\x5e\x33\xba\xd1\x28\x62\xd7\xf4\xb1\x3e\x13\x77\xf3\xdf\xfa\x6b\x8a\x8e\xa4\x08\x1c\x49\x70\x46\x60\xde\x8f\x54\x47\xac\x36\xac\x2b\x89\x2b\x1d\x69\x5a\xee\xbf\x2c\x17\x93\x78\x67\x37\x2c\xf1\xed\x02\xf8\x13\xe1\xf8\xdb\x40\xb8\xd3\x0d\x61\xa9\x70\x0e\x5f\x5f\xb0\x9e\x67\x75\xb5\xbb\x48\xd9\xa5\xc5\x4d\x4e\x40\xc1\x93\x09\x2f\x0c\x40\x64\x92\x8b\x8f\x7e\x8a\x41\xf7\x20\xe6\xd9\x87\x7e\xbe\x9f\x17\x57\x31\xf0\xb5\x07\x56\xcc\x6f\xde\x44\x3e\xee\xef\x51\x64\x55\x65\x4f\xc5\x4f\x6c\xd6\x9f\x47\xc8\xe1\x99\xaa\xf8\x1f\xf0\x14\x30\x88\xa3\x28\x1a\xba\x77\x90\x04\x7f\xfb\xf3\x02\x8e\x68\x23\xec\x1f\x28\x08\x29\x30\x31\x57\x30\x50\x8a\xe6\xf2\xc9\xf4\x01\xec\x5f\xa3\x80\xd3\xa2\xf9\x94\xe5\x7f\x91\xe4\xcd\xd3\xa2\x3d\x04\x01\x09\x8c\x8b\xcb\xb5\x79\xaf\x6d\x70\x32\x23\x5b\x75\x39\x90\x97\xee\x33\x6f\x31\x0e\x83\xc0\xaa\x9f\x18\xbd\x3f\x03\x40\x1b\x0a\xca\xb5\x56\x21\xfd\x3d\x0a\x63\x9e\xc6\x7d\x49\xf3\x56\x52\xc6\xf1\x8b\x86\x77\x26\x41\x25\x9d\x2d\x97\x5b\x64\x31\x0d\x42\xb2\x9c\xa7\xd0\xe5\x07\x66\xa6\x38\x73\x77\x69\xee\x04\x95\x68\xc2\x76\x64\x18\x53\x26\x33\xbf\x94\x79\x7d\xe8\x07\x9d\xc8\x62\x03\x5e\x3c\xc1\xfb\xb9\x87\x38\x47\x96\x78\x94\x7b\xd4\xad\xc6\x8e\x85\x4a\x8e\xfa\xc3\xbf\xa8\x00\x7c\x30\x6b\x98\x0c\xb8\xe5\xec\x6e\xca\xe2\x54\x50\x05\xbc\xfd\x6a\xcd\x21\x70\x01\x1b\x49\x44\x6e\xa0\x49\x61\x47\xb2\xf8\x9f\xfc\x63\x4f\xc4\x83\xc4\x01\x14\x0d\x28\x64\x32\xea\x44\x1e\x43\x6a\xfd\xaf\xeb\x4c\x66\x67\x42\x10\x6e\x4a\xac\xe0\x88\x5f\xb3\x8a\xaa\xd4\xa3\x4f\xc8\x84\x82\xa0\x9e\x20\x72\x8b\x8d\x76\xbf\x82\x2b\x2f\x19\x18\x3f\xee\xfb\xd5\x8d\x61\x0c\x8e\xe0\x33\xe2\xf3\xca\xa2\x30\x2d\x81\x45\x39\xca\xca\x11\x92\x80\x52\xb2\xef\x4e\x08\xf4\x43\x86\xde\x54\x4a\x3b\xba\xff\xc0\x7d\x2a\x4f\xef\xae\x4d\x6a\xd0\xb5\x2d\x51\x79\x0c\x0c\xf5\xe1\xa1\x00\xf5\x47\xde\x2b\xa3\xb8\x11\x3e\xa7\x49\x7f\x76\x1d\x99\x97\x66\x6f\x87\x52\xb5\xa7\x48\x53\x30\xc1\xf1\xb9\xd9\x1e\xef\x3f\xd1\x72\x1d\x5d\x95\x62\x26\x2b\xad\xea\x72\x51\xe4\x12\xea\xea\xd7\x1b\x03\x2a\x4c\x68\x33\xfc\x33\x38\x1c\x69\x86\x1a\x17\x97\x7e\x6f\x1c\xd1\x0f\x85\xcd\xe4\x7f\xeb\xbd\x84\x18\x45\x5e\xd0\xf3\x98\xa4\x9f\x32\xfa\xb9\x18\x81\xef\x75\x62\xa5\xcd\x12\x57\x16\x2d\x2d\x08\x75\x00\x2a\x70\xc2\xa3\x35\x3e\x17\xe5\x95\x70\x9f\xc3\x67\xa7\x75\x42\xf0\xc6\x73\x73\xc3\x7c\xd3\xd0\x6a\x5e\xb6\x55\xde\xed\xdd\xda\xe3\x71\x20\x5c\x64\xfa\x52\x16\x6f\x5b\x34\x3a\xbc\x45\xdd\x13\x46\x07\x1d\xf8\x3e\x69\xd8\x7d\x87\x63\x51\xe2\xa9\x63\xd2\xea\x20\x4c\x28\x7d\xc2\x93\x2b\x3c\xf6\xe4\x25\x3e\x7f\x23\x75\x90\x1a\x8d\xc6\xe7\x12\xb1\x1e\x89\x16\xea\x50\xf9\x06\x20\x68\x52\x76\x23\x72\x3b\xf8\x89\x3a\x0a\xfc\xc0\x66\x59\xf4\xd5\xdf\xb6\xab\x99\xd6\xd9\x3b\x56\x53\x4b\xb4\x8e\x7d\x3f\x76\x20\x98\x5e\xbe\x3c\x7c\x2d\x34\xf3\x05\x95\x96\xe0\x7c\x3e\x5e\x27\x09\x2a\x6e\x60\x2a\x98\xa9\x8a\x5f\x8b\x4b\xbd\xbc\x77\x77\x84\x31\xcf\x50\x67\x0b\x5d\x4b\x38\x3b\xf5\xbe\xc9\x1d\x58\xf3\x20\x92\x56\x99\xb3\x70\xb9\x80\xe6\xb1\x91\x07\xdb\x80\x51\xa3\x21\x6a\xc3\x72\xff\xf5\x63\x2f\x78\xd0\x9c\x99\x68\xe2\x69\xf5\xed\xd7\xf5\x62\x32\xda\x72\xf4\xdc\x1d\xe6\x6a\x50\x8a\xd0\x5c\x87\x24\x13\x08\x52\x96\x17\xdc\xb7\x05\x97\xcf\x8b\x72\x1a\x22\x69\xc4\xbd\x51\xc3\xe5\xd8\x66\x3a\x5f\xa0\x3d\x31\x30\xb4\xe0\xa9\x66\xbd\xb9\x83\x21\xa4\x93\x3a\x72\xd6\x13\xfa\x63\xf5\xe8\xe1\x77\x8a\xc0\x5c\x2a\x95\x61\xfb\x3a\x00\xe3\x71\xa1\xa4\x82\xe0\x73\xa6\xeb\x05\x4c\x57\xe2\xdc\xd0\xb4\x15\xd1\x5b\x6b\x4d\x1b\x42\x57\x15\xd4\x82\x87\x86\xec\x5e\x1c\x8f\x87\xbc\x28\x4f\x9f\x68\xb9\x8e\xf1\x9e\xb7\xae\xde\xbd\x0b\x14\x49\x20\x3a\x63\xb3\x4f\x92\xd7\xb1\xed\xda\xf4\x34\x16\x82\x83\x73\x25\xc3\x77\x7b\x73\x7a\xf5\x04\x2d\xa4\xc1\xaa\xad\xe6\x4f\xff\xbe\x6b\x32\xa9\xf5\x66\xb9\xdd\x11\x11\xe8\xb0\x18\x1a\x54\x83\x96\x71\xa2\xb8\x03\x09\xe2\x79\xff\x56\xdc\x8a\x5d\x68\xa9\x24\xdd\x1a\x75\x13\x65\x69\x15\x98\x52\xab\x84\xea\xa5\xb8\xd4\x53\x7d\x04\x37\x32\x12\x64\xd4\xb8\x5d\xee\x96\xdb\xef\xcb\x3b\x2b\x7a\x73\xb8\x5f\x6f\x0f\xd4\xb8\x5a\x1f\x96\x7f\x2c\xbe\xce\x9e\xbe\x2c\x1d\x1a\x50\xab\x44\xc8\x91\xe8\xf8\xdc\x2a\xba\x8c\xcf\x2e\x42\x8a\xc7\x4c\xe8\xe4\xe2\x8a\xe1\xed\x1d\xfe\x28\xe7\xed\xf5\x8c\xf5\x0f\x0a\x7a\x68\x5a\x2f\x2c\xae\x88\xb5\xa3\xb8\xe7\xa4\x5c\x0e\xa6\x34\xbe\x7a\x9a\x9d\x8a\xfa\x88\xd7\x87\x2c\x1f\xdf\x29\x64\x1e\xa9\xac\xcc\x1f\xd6\x8b\xdf\x0f\x9b\xe5\xf6\xb0\xf9\x3a\x6b\x33\x4d\x8d\x8c\x91\x6e\x44\x0f\x48\xa3\xa6\x54\x36\xb5\x8e\x3d\xc2\x45\x95\x45\x51\x3f\x75\xfa\x75\x5a\x27\x89\x87\x56\xb3\x9e\xb8\xd1\xe6\x80\xf0\xbc\xd4\x27\x86\xce\x02\x08\x8b\xd5\xa1\x22\x84\xe7\x49\x23\x99\x63\x0c\xbc\x0e\x6f\x54\xd4\x3e\x88\x4c\x0d\x18\x71\xcc\x8d\xd6\x28\x6d\xb5\xc6\x70\x9b\xee\x8b\x72\x5b\x14\xf5\x8d\x02\xb6\xf0\x7c\xcf\x97\x51\xa7\x91\x4f\x86\xa7\xab\x51\x3d\x5a\x78\xbe\x80\xce\xb3\x27\xbf\x9a\xce\xa9\xbb\x6c\x5f\x1b\x9f\xb6\x16\x71\xbc\x29\xb3\xff\x35\xc4\x79\x37\x24\xf0\x39\xc1\x29\x41\xa9\x2d\x9e\x8b\x76\xd9\xe8\x2d\x30\xc2\x0b\xd3\x30\x36\x2c\x23\x53\xc3\xed\x95\xd1\xdc\x79\x42\x04\x74\x3c\xab\xac\x3a\x5f\x6a\x2a\x55\x93\x70\xfc\x7d\x51\xde\x17\xe5\xab\x1b\x19\xb1\x94\x4a\x75\x59\x8d\xa7\xb5\x1e\xfd\x9c\x48\x07\xa4\x54\x52\x11\xf0\xd3\x56\x94\xef\x5a\x2f\x03\xe1\xc5\x51\x44\xfd\x3d\x09\xf9\x1c\xa1\x6c\x52\x80\xc9\xa5\x4b\x78\x71\xcc\xc9\x03\x75\xb7\x9f\x6d\xf7\xab\xa7\x2f\x87\xdd\xd7\xed\xea\x71\xe3\x4e\x94\x04\x40\x12\x45\x44\xbf\x5c\x9f\xa9\x6c\xbc\x2f\x96\x96\x28\xb5\xce\x8f\xd7\xe5\x7b\x5d\xc2\x27\xf9\x41\xfb\xa4\x12\x4b\x56\x06\xf5\x33\xab\x8a\xd2\x15\xd8\xdb\x16\x8e\xf0\x92\xc4\xa3\x8c\xd8\x10\x81\xa7\xa9\xb4\x9f\x09\xf4\xf7\xe6\x5b\xea\x29\x6a\xd0\x2d\xa0\xbe\x87\xf2\xe4\x62\x0d\xe1\xa5\x81\xa7\xac\xce\x29\x6d\xfa\x1b\xbf\x3b\xa2\x4c\x05\x06\x72\xd5\xab\x2d\xf5\xe7\x65\x0a\x92\x19\x1d\x65\x38\x52\xb8\x63\xba\x12\xee\x0c\x2c\xd4\x4a\x3a\x57\xdb\x3b\x3c\xd6\xd0\x1e\x61\x71\xcc\xdc\xd4\x20\x4c\x4d\xf3\x48\x8a\x4b\xed\x58\x60\x6e\x1c\x0f\xd3\x56\xf9\xe8\x46\x49\xf9\xb3\x0d\x52\x78\x4c\x87\x14\x36\xb6\x32\x97\x0e\x31\xd7\x9e\x5c\x2b\x30\xfb\xe3\xf9\x08\x3d\x9d\xad\xfe\x22\x26\x3c\xce\x25\x3d\xf1\x1c\xdf\x4c\xf3\xab\x68\xef\x1d\x17\x3e\xb8\xee\xc3\xdc\xb9\x8c\x6c\x51\x1f\x51\xd6\xad\x74\x69\x3b\x58\xf2\xc4\xbe\x98\x7f\xfc\xeb\x5b\xfb\x57\x25\x7c\xdf\x89\xbc\xd7\xd9\xcf\xce\x97\xc6\x8d\x20\xbd\x67\x9a\x04\xf2\x75\x7e\xb9\xb6\x7f\x0e\x8c\x28\xa2\xb8\x5c\x9b\x7b\x2b\xb3\x13\x1c\xdb\x37\x18\x42\x96\x74\x44\xc3\xc5\x31\xc3\x7c\xd8\x5e\x17\x1e\x30\x99\xd8\xcc\xd6\x92\xaa\xba\xdf\x25\xbc\x80\x58\x04\xc5\xa5\x6e\xd2\xfa\x4d\x51\x1c\x47\x2f\x9c\xf0\x02\x69\x98\x56\x55\x5d\x16\xd7\xf9\x85\x44\xc1\x86\x2b\x91\x48\x44\xa2\x3a\xdd\x92\x9e\xe4\xdb\xfc\xfa\x88\x2a\xa3\x6f\x1c\x9e\x56\x7a\x46\x41\x56\x5c\xae\xc1\xf8\x90\xaf\xe9\x61\x3d\x20\x94\xf9\x1f\xee\x4a\xa5\x36\x99\xc8\xb3\x75\x65\xeb\x08\x6a\x6e\x8a\xaa\x14\x4d\x53\xdd\x46\xf7\x14\x62\xda\x63\x3a\xd1\xc4\x8d\xad\xfc\x7e\xa5\x4c\x78\x9a\x87\x89\xa3\xc5\x98\xfe\x4a\x35\x9a\x14\x9a\xa7\x60\x24\x6d\x49\xc8\x67\x52\xca\x7c\x34\x1d\xb5\x34\x05\xd3\xba\xcc\x9e\x9f\xb1\xdc\x56\x78\xd4\x74\xfb\x2e\xb2\xde\x1a\x78\xbb\x19\xe9\x7b\x7e\xcc\xfc\x41\x62\xbe\x78\x81\x3e\xd9\xdd\x8d\x13\x1e\x31\x43\xac\x66\xbf\x55\xb0\xd8\xc1\x11\xc7\x36\x4a\xc2\xf7\x23\x4d\xca\x8f\x85\xd5\x14\x3d\xfc\xcf\x05\xcb\xeb\x34\x07\xf9\x3f\xe1\x50\x5f\x57\xf8\x7e\xe2\x87\xd8\xb5\x60\xab\xf9\xf5\x6e\xc4\xbe\xa4\x31\x46\xa9\x9c\x2a\x77\x2d\x8b\x46\xf8\x01\xf7\xa5\xbd\x9b\x9b\xec\x1d\x8f\x43\x20\x95\xf0\x03\x44\xc2\x3f\x1a\xfc\xc9\x5a\xaf\xcf\x98\x6f\xef\xff\xe5\x9e\x92\x1f\x42\xda\xe3\xb9\xda\x05\xa2\x7d\x4d\x46\xad\x09\xe1\x87\x42\x83\xbd\x56\xe3\x73\x4f\x45\xa4\xe1\x98\x28\x65\x24\x48\x64\x05\x83\xe0\xd8\x55\x15\x87\x3f\x2a\x92\x26\x67\x22\x60\xd4\x0d\x8e\x73\x7a\x91\x1f\xea\x8a\x09\x3f\xd2\x5e\x6c\xa9\x11\xf6\xe2\x07\x12\xf9\x76\x54\x8c\x29\x31\xb7\x9a\x35\x7b\x5f\xcc\xcd\x39\x46\xf2\x2a\xc2\x4f\x22\x5f\x25\xad\x90\xe2\x97\x7e\xf7\x77\x78\xe1\x49\xc2\xa5\xe3\xcb\xf6\xe2\xae\xde\x00\x16\x91\x10\x41\xf3\xa3\xf7\xf8\x5e\xff\x8e\xd7\xa9\xe6\x91\xf0\xd3\xd0\x70\x40\x77\x56\x19\xe5\xef\x14\x0d\x85\x9f\x26\x82\x00\x5b\x67\x38\xe2\x15\x4b\xbf\x7a\x29\xde\xfa\x30\xfb\xdb\xff\x75\x1f\xe4\x1e\xa5\x8d\x77\x78\x2a\x8e\x59\xf5\x32\xbf\x1a\x31\xaf\xe9\xbc\x50\xf8\x8c\x1b\x98\x43\x13\x2b\x17\xba\x7e\x23\x6a\x62\x93\x3e\x4d\x01\xd2\x9b\xf5\xda\x08\x60\xe5\x45\x0d\x4d\x54\xd3\xc3\x57\x09\x1f\x30\x75\xe8\x7d\x83\x32\x68\x92\xb1\xd1\x09\x64\x18\xd1\xae\x7d\x68\xab\x3e\x1f\x28\x13\xbb\xf1\x68\xb4\x92\xf6\x58\xd5\xcb\xf5\xae\x03\x36\x34\x87\x4c\x9f\xe2\x89\x04\x7c\x1e\x3f\x7a\x94\x8a\x05\x9e\x89\x13\x94\x89\xc1\x2e\x7d\x00\x53\xbb\xd7\xf7\x7e\x87\xe2\x86\x44\xd0\xf6\x86\x2e\xb9\xaa\xfe\x46\x52\x29\xfc\x66\x37\xd2\x1d\x70\x10\xca\xe3\x75\xe3\x6a\x66\x13\x55\xdd\x8f\xce\x82\xdc\xf4\x63\x8b\xe3\x4f\xdc\x43\xf5\xfa\xa1\x34\xcf\xe4\x7f\xda\xb3\x60\xc8\x3c\xc2\xce\x7f\x7b\x78\x30\x79\xc9\x61\xf6\xb8\xfe\xf6\xb4\x77\xf7\x0f\x13\xdf\x09\xf6\x39\x11\xd1\xe1\xca\xa2\x23\x9f\xe6\x78\x96\xeb\xe2\x40\x15\x96\x4f\xf2\x04\xe1\x6b\x50\xff\x7f\xca\xbe\xad\xb9\x71\xdc\xda\xfa\xef\xcc\x43\x1e\x40\x80\x24\xc8\x47\x59\x96\xbb\x95\xb6\x2d\x47\x92\xa7\x27\x27\x95\x52\xe1\xb2\x21\x33\xa6\x48\x85\xa4\xec\x76\x7e\xfd\x57\xdc\x00\x78\x13\xed\x99\xaf\x4e\x25\x9d\x63\x82\x14\x2f\xc0\xc6\xbe\xac\xbd\x56\x64\xc5\xbb\xf3\xe9\xb4\x31\x5a\xa1\x70\x45\x8e\x3d\x9d\x8f\x65\xb3\xfa\xef\xa5\x0f\x45\x07\x20\xe0\xa1\x03\x4c\x49\xeb\x98\xb6\x81\xc7\x72\x63\xa5\x72\x3c\x06\x7e\x12\x53\x7e\x21\xe1\x2d\x29\x91\x9c\xe8\x01\x81\xc7\xad\x68\x60\xb2\x39\x52\xa2\x89\xa3\xb7\xb2\xa5\x55\x67\x67\x76\xea\x05\xf4\x65\x06\x44\xf6\xff\x93\xca\x6d\xaf\x9e\x26\xa6\x6b\xab\x5e\xe9\x6c\x5a\x88\x6b\x87\xa8\xc4\x27\x06\xda\x2d\xf8\xae\xac\x7e\x87\x2a\x33\x99\x12\x57\x58\x38\x49\x03\x97\xac\x76\x9e\xc1\xe2\x7c\xce\xfd\xc0\xf1\x65\x03\x16\x63\x9a\x5f\x38\xec\x09\x7d\xaa\xca\xd6\xf0\x0d\xf2\xdb\x92\x06\xa1\xc1\xb4\xe9\x19\x75\xe2\xbe\x7d\x9c\x90\x26\xb8\x73\xbc\x68\x90\x18\x9b\x88\x6a\xca\x0a\x90\x6d\x61\xf4\x91\x02\x00\x84\xb1\x98\xf7\x31\xa1\xc7\x60\x41\x51\x4a\xad\xa8\x04\xfc\x42\x0f\x11\xd9\xc8\xe6\xd7\x93\x3b\x81\xc5\x36\xae\x3e\xd8\x77\x86\x35\x8e\xc9\x4b\x60\x1c\x6c\xe7\x43\xdd\xc6\x69\xfd\x7e\xa6\x27\xef\x80\x49\x0b\x27\xb5\x55\xd8\x9f\xeb\xc7\xdb\xcd\xcf\x03\x3b\xac\x1e\x6f\x0f\xfb\xf5\xc3\xca\x3f\x65\x18\x84\xd8\x1e\xb1\x05\xfd\xd4\xbf\x9b\x48\xc6\x18\x18\xb5\xb3\x7d\xf4\xd2\xe2\x90\x21\xdf\xd9\x6d\x25\x8e\x65\xf1\x63\x48\xbc\x30\x9c\x24\xd7\x76\x3a\xf0\x82\x42\x81\x6f\x09\x91\x34\x56\x84\x58\x50\x3d\x88\xfa\x32\xc9\xa5\xb7\x87\x19\x16\xe4\x9d\x8c\xb3\xcb\xbb\xff\x84\xec\xd6\xd1\x20\xfa\x71\x40\x91\x21\xaa\x39\x56\x53\xc9\x44\x49\x79\x18\x47\x5d\xe0\xb5\xb4\x65\xd1\x4c\xe6\xed\x4c\xb3\x2c\x63\x8b\x41\xdc\xfc\x85\x89\x19\xdf\x1a\xe7\x82\x7a\x45\x9e\x36\x44\x5f\x17\xc8\x59\xf1\xdb\xe8\x4b\xf1\x34\xc6\x60\xb7\xb6\xc0\xe8\x61\xe2\xb9\x3d\x08\xc6\x62\x76\xce\x5f\x96\xdf\x25\x4d\xa8\x40\x6c\x79\xdf\x47\xd0\x11\xbb\x4f\x4e\xec\x5e\x6c\x42\x0d\x16\xfb\xd0\x90\x7e\x1b\x02\x1e\x27\x97\x66\x81\x8f\x22\xb6\x97\x62\x87\x42\x4d\x83\x6c\x03\x4d\x62\xcb\x91\xf2\xb0\x7e\xdc\x0f\x27\x4d\x92\x26\x16\xc8\xda\xbe\xee\xf6\x35\xb6\x5f\x64\x32\x4f\x13\x09\xdc\xed\xff\x97\xf3\x3f\x9e\xfe\x39\xcf\x68\x70\xf5\xef\x97\x3b\x04\x4d\x99\xc0\x6d\xb8\x7d\xfa\xf6\xb9\x6c\x86\xa8\xdd\x1c\x07\x89\x70\x49\x53\x21\x52\xde\x95\x0b\xef\xcb\x37\x24\xc6\xf0\x9e\x21\x55\x69\x84\xd0\xdf\xf6\xec\x3f\x58\xf7\x57\xc9\x90\xdc\xc4\xef\x7e\x43\x6a\x5a\x49\xb5\x11\xa1\x03\x33\xfd\xc8\x9a\x26\xeb\xd2\x1e\x14\x08\xc1\x0a\xcd\x7b\xc7\x06\x89\xfb\xe6\xf0\x3d\x02\xa3\x5e\xaf\xed\x16\x6f\xb4\x0d\x8f\xec\xa6\x3c\xc7\x32\x21\xa9\x57\xc5\x43\xa1\xca\xa6\x19\x08\x2d\x4b\x0a\xc6\x60\x94\xf5\xf4\x52\x42\x91\xfd\xea\x7b\xb4\x25\x35\x4c\x60\xb2\xfb\x61\xf1\x87\x63\xc3\x38\xec\x9e\x9f\x9e\xee\xff\xd9\x0d\x88\x88\x0f\x26\x5d\xfb\xd9\xd8\x1c\xf9\x61\xd2\x84\xe9\x60\x5f\x58\x6d\x76\x7e\x99\x0c\x6d\x20\x23\x51\x84\xde\xda\xb3\xcc\xfe\x3b\xc4\xcf\x4b\xd6\xee\x2c\xa4\xe3\x09\x59\x1c\x61\xb4\x34\x58\x20\x62\xc4\xdf\x39\x22\x4d\x6b\xe7\x46\xf7\xc0\x02\x49\x31\xd0\xfc\xfd\x02\x4f\xe2\xa3\xeb\x5d\xf0\x3f\x10\x18\xc3\xdc\x27\xbe\xbb\xe4\xb9\xed\x80\x1d\xef\xe3\x8c\x52\xe2\x35\xc9\x1f\x4b\x2d\x72\x84\xba\x5f\x59\x72\x46\x85\x06\xd6\xd3\x47\xdf\xf7\xb5\xa2\x7a\x4a\xc2\xdd\x0e\xb6\x42\x88\x6f\x65\x03\x37\xfe\x66\xa8\x09\x51\x46\x70\xb1\xfd\x71\xb8\xbb\x5f\x7c\xfb\xb6\xda\x1e\x82\x83\xc7\x75\x49\x16\x46\x89\x0e\xfa\x7d\x60\x65\x15\x79\xb1\x6f\xaf\x0d\xa2\xc7\x2b\x87\x85\x31\x88\x0e\x78\xb6\x3b\x77\x40\x3f\xc9\x42\x6d\xbb\x1c\x94\x45\x0d\x21\xc4\x67\x9f\x9d\xc0\x67\xd4\x1d\x69\xb5\x64\xa1\x51\xd8\xd1\xf3\x53\x34\xea\xe5\x11\x7e\x35\xae\x91\x76\x90\x43\x63\x11\x89\x30\x1b\xda\x39\xa4\x03\xce\xe6\xba\x1b\xc4\x38\x19\x16\x7b\x6f\x45\x95\x7d\xed\xc5\xb1\x28\x0a\x7c\x6b\xdc\xa8\xcb\xc6\x1f\xe6\x06\x2b\x46\xab\x9b\xfb\xfb\xcf\x51\x0f\x92\x45\x22\xc4\xad\xf0\xc7\x8f\xbf\xd6\x1e\x22\x59\x24\x43\xb4\x4a\xf8\xde\x6e\xe1\x9c\x97\xd8\xb5\xd3\x3f\x8b\x8e\x42\x8b\xda\x73\xf3\x00\x42\x7f\x28\x8e\x08\x6a\xbe\x1e\x2b\x21\xe7\x70\x1b\x7e\x98\xeb\x7d\x47\xa6\x20\xac\xf7\x3c\x4e\xa5\x51\x25\x8b\x41\x8a\x1e\x3f\x81\xf5\xcf\x51\x37\x8f\xa7\x65\xf2\xc3\x8d\x00\x87\xcd\xfd\xfb\xf9\x43\x39\xf6\x99\xb9\x7a\xb4\x64\x5c\x8a\x71\x6a\xaa\x75\x01\xee\xca\xca\xe7\x8c\xa6\xe3\x93\x98\x06\x3e\xff\x0b\xa2\x99\x6c\x75\x7e\x10\x28\xa4\x0e\x35\x96\xdd\xc5\xdb\x43\x96\x06\x09\x32\x0b\x99\xac\x5d\x5e\xc8\x07\xd1\x1d\xe2\xa9\x21\x53\x42\xaa\xe5\x8b\xa8\x9a\xc5\x51\x64\x45\xdd\x60\x2b\x7a\x56\x1c\x57\x56\xe4\xe9\xaf\x14\x1a\x25\x13\x81\x91\xd4\xfb\xe5\x36\x15\x2b\xfd\x2f\x0a\x66\x70\xbb\xfc\xbe\xb9\xbd\x5f\x6d\xe7\xdf\x8e\x90\x01\x75\x1c\x09\xab\x42\xef\xa6\x15\x5b\xc9\x64\x60\x59\x29\x96\x3f\x97\xc3\xd6\x1b\xc9\xa4\x48\xb1\x6a\x7f\x5f\x1e\x1f\xe1\xbd\xe3\xfd\xbf\xe6\xc6\x19\xff\xa0\x54\xa1\x65\x7a\xf8\xb0\xa8\xb8\x7a\x0b\x0a\xb2\xb7\xde\x0a\x2a\xa2\xd1\x0a\x0e\xc1\x76\xf3\x39\x9f\xf9\x35\xa0\x13\xdb\x95\xbe\xcb\xda\x69\x8e\xfc\x91\x2e\xb1\xf4\xd7\xc2\x69\xa6\x15\xb1\x0f\x66\x29\xd2\x26\xb5\xa8\xf1\xbc\x05\x11\x21\x34\x50\xa0\x34\xf5\x4d\x6b\x39\x7a\xa7\x72\x28\x6b\x2d\x19\xe8\x08\xcb\xc9\x4e\x3c\x72\xa8\x63\x22\x99\x09\x0c\xe6\x1a\x8a\xd6\xda\xb5\x73\x0a\xcd\x6e\x2d\xb1\xd3\xa5\x80\xf7\xb3\xe8\x87\x86\xb6\x17\x0e\xd3\xb4\x0b\xdb\x05\xf0\x27\xd6\xc5\xf0\xc0\xcb\xc5\x5f\xa9\x5f\xcf\x05\x53\xcc\x68\x8b\x02\x38\x1d\xe4\x1a\x09\x3e\xdc\x8f\x87\x84\x2a\xa4\xd6\xba\xb9\x78\x9e\x85\xac\x79\xf9\x3a\xda\x1d\xdf\x4b\x48\x58\x48\xb4\x37\x38\x8f\x58\x65\xdc\x0f\xd8\xa6\xba\x79\x10\x12\x45\xa9\xe8\x20\xb9\x4b\x51\x77\xde\x43\x18\x90\x40\x59\x6d\x93\xf7\xa1\xa5\x18\x7d\x9a\x90\x49\x8a\xb8\x17\xd7\x28\x81\x0c\x4a\x53\xce\xb3\x90\xb8\xc1\x61\x4c\x7c\x65\x14\x95\x91\x76\x0d\x42\xfd\x66\x5f\x67\x18\x69\x82\x01\xd8\x39\x83\x2e\x13\x3d\x5e\x56\x61\x9c\xb0\x90\x78\xa2\xae\x46\xe4\xae\x4b\xc2\x1f\xd5\x21\x82\xbc\x9b\x77\x18\xcb\x3b\xc8\x30\x36\x96\xdc\x05\x1c\x69\xde\x83\xf8\x04\x13\xe7\x13\x5f\x53\x7b\x1b\x72\x22\xf0\x0a\x77\xf9\xc5\xaa\xac\x75\xaf\x8d\x07\x0a\x33\x71\xab\xed\x92\x52\xe6\xed\xdf\x01\x5c\x1f\xb1\x1f\x25\x08\xe6\xb3\x0f\x68\x52\xde\xb2\xf6\x2e\x70\x27\x74\x64\xcf\x13\xb6\x7d\x77\x56\x12\x2b\xee\xec\xc8\xb7\xec\x0d\x8a\xcf\x3a\x86\x64\x98\x28\x81\x2d\xb6\x8f\xf0\xbe\xbb\x1c\x8f\x6d\xf4\x5c\x5e\x45\xe9\x93\x8b\x2b\x43\x60\xf0\x75\x46\x9e\x79\xf7\xc1\x53\x12\x63\x26\xe4\x58\x65\x60\x7a\x6d\x30\x19\xa6\xdc\xa2\x4a\xea\x46\x1c\xe1\x10\x1c\x9c\xd6\x45\x99\x77\xcf\x9c\x6a\x85\x0d\x3e\x8b\xd5\xdd\x9d\xd5\x0a\x72\x07\x44\x90\x78\xf0\x14\x56\x8e\xad\xfc\x02\x56\xe3\xe7\xe7\x86\x88\x15\xea\xcc\xb6\x41\x95\x14\xb5\x4b\xeb\x38\x70\x4f\x77\xd5\xc4\xaa\x6a\xd8\x2c\xec\xbe\xbc\x01\x0b\x36\x1b\x6f\x8a\xa1\x10\x04\x57\x61\xfb\xa3\xce\x4a\x76\x53\x48\xf2\x38\x65\x8e\x08\x7f\x07\x88\x59\x9e\x32\xab\xca\x50\xe9\x04\x9c\x20\xf2\x4d\xa6\x75\x07\xfd\x93\xa1\x02\x22\x5c\xa3\xe0\xa2\xae\xa1\xa9\xaf\x29\x7c\x65\xa8\x45\x84\xa4\x0b\xe7\x01\xab\xc3\xe8\xfa\x46\x2a\xed\x75\x13\xac\x0e\xb5\x40\xf9\xb0\xaa\x54\x00\xba\xfe\x29\xb2\x41\x5d\x5e\x86\x46\xa7\x4e\x72\x04\x13\x48\x4f\x7d\x4e\xf0\x4b\x1d\x5a\x19\x11\x01\xbe\x29\xe2\x77\x28\x74\x59\x0d\xb2\x18\x8e\x7f\x72\x78\x5f\x51\x20\x02\xb0\xc5\x26\xa1\x0f\x68\x68\x0e\x1e\x5f\xd5\xfe\xff\x7a\xd2\x4c\x24\x23\x4a\x6c\xa7\x7a\x53\x65\xea\x35\x87\xe7\xf3\xf4\x78\xa8\x90\x76\xff\xdb\x90\xbb\xda\x3d\x56\x14\x92\x90\xab\x61\xf7\x33\x56\x25\x47\x4a\x07\x13\xd8\x84\x3b\x31\xe2\x0a\xab\x14\x4f\x55\xa6\x47\x19\x83\x28\x4a\x52\xa4\xb2\x38\xc1\x69\x59\x9e\xaf\x04\x1f\xc7\x73\x2e\x8a\x34\x41\xa6\x02\x2c\xfd\x61\xcd\xa0\xbb\x0e\xd8\xb2\x62\x07\x8a\xce\x4b\xb5\x2f\x9f\xa7\xed\xf1\x32\x4a\x62\x8e\x62\x0d\x8f\xe7\xb2\x0b\x17\xa2\x34\x31\x09\x1f\x08\x29\xd5\x9f\xe4\x5d\x23\xc1\xac\xf6\x7d\x05\x75\x73\x97\x15\xd9\x04\xb1\x25\x23\x99\x50\xed\x22\x1b\x97\x4e\x98\xc6\x08\x91\xd4\x8c\xca\x41\x44\x78\x0b\xe3\xbe\x14\x19\xe9\x88\xd3\xb4\xef\xac\x7d\x73\x80\x05\x5b\xe6\xf2\x0d\x36\xed\xb0\x34\x4d\x3d\x9d\x28\xe6\x3c\x44\xf5\x71\xf0\x5a\xe1\x07\x65\x45\x3d\xba\xd1\x9c\x21\x26\xbc\x6e\xe0\xec\x3d\xdb\xc8\xb0\x14\x77\x83\xd2\x98\x3c\x2b\x50\xe4\x60\x7e\xb9\x47\x26\x11\x01\xeb\x8a\x1b\xce\xf3\xf9\x51\x64\xc7\x97\x89\x0b\x1f\x19\xb0\xf5\xaf\x3e\x23\xb1\xb8\x1f\x39\x54\x31\xa1\x01\x16\x53\xd6\xcb\xcd\x9f\x76\x78\xc8\x98\xa4\xac\x73\xab\x2f\xa7\x85\xab\xe7\x38\x00\xb3\xb9\xe4\xb7\xd0\xd7\x28\xe3\x80\xa5\xd2\xc1\xc9\x5a\x1f\x1c\xc9\xee\x66\x2b\x10\x71\x10\x27\x58\x66\xbd\x79\xfe\xe7\xa1\xcb\x5d\xc4\x34\x30\x41\xd8\xb1\x7d\x22\x19\xb4\xc5\x05\xce\x04\xb8\x31\x4d\xb8\x76\x36\xd3\x46\x47\x57\x8a\x87\xb3\xc0\x1e\x19\x53\x20\x58\x12\x10\x5a\x63\x8a\xee\x7e\x26\x45\x17\x33\x0a\x66\x28\x24\x59\xb5\x9b\xd7\x27\xdb\x70\xcc\x54\x88\xdc\x60\x0f\xab\xdd\x6e\xf1\x6d\x75\x78\xda\xae\x97\xdd\x43\x31\xb0\xd0\x8b\xe5\xea\xff\x16\x5f\x10\x04\xcb\x38\x24\x21\xa2\x8b\x0f\x7e\x37\xbf\x39\xa9\x5b\xf1\x51\xbb\xe4\xd4\xec\x9a\x88\xc3\x50\xe0\x2b\xbb\x2b\xab\x49\xb3\xa9\x8c\x43\x20\xdc\xae\x97\x36\x00\xff\xb4\xd4\xfe\xc9\x85\x21\xc6\xdb\xce\x54\xd9\xd3\x0b\xca\x38\x8a\xed\xb6\x7d\x84\x02\xea\xac\x5e\xb6\x6f\xbe\x1a\xd7\xa1\xe3\x28\x55\x58\x1f\x69\xad\x7e\xd5\x64\x2a\x87\x21\xa1\xc9\x30\x0b\x1b\x47\x22\x40\x90\x55\x03\xe2\x84\x53\x76\x7e\x01\xc4\x91\x60\x4a\x0e\x02\x37\xab\x65\xf0\x59\xf5\xce\x9f\xe4\xdf\xfc\x80\x1a\xdd\xdf\x23\x0f\x15\xb6\x5d\x7a\x07\x68\x35\xf2\x4e\x62\x9e\x26\x58\x8a\x37\x17\xf5\x8a\xee\xbd\xc8\x4e\xc1\x15\xa1\x9c\x8c\x13\x3e\x54\x4c\x7a\x80\xe6\xa5\xd4\x8b\x9b\xb5\xbf\x4c\x22\x44\xe2\x1a\x27\xd7\x45\xd6\xb4\x01\xa7\xc7\x62\xc4\x29\xd1\x98\x67\xb1\x38\xd6\xe9\xfc\x13\x11\xc3\xd9\x7d\xba\xe4\x4d\x76\x33\x90\x9c\xf4\x0e\x58\x2c\x40\xe2\x4a\x7f\xda\xae\x0e\x4f\xcf\x37\xf7\xeb\xe5\xe1\x7e\xb3\xfc\xf1\xfc\x74\x78\x5a\x6d\xd7\x9b\x5b\xff\x3b\x32\x48\xd0\x8b\xc5\x0d\x6a\x91\x55\xb7\x55\x79\xee\x8e\x85\xc2\x38\x7f\xf4\x27\x88\x73\x59\x3c\x94\x1a\x26\xc0\x80\x58\x4a\x89\x9c\xb8\x13\x4c\x9b\x8c\x15\x95\xb1\xcb\xc2\x9f\x2d\x54\xfb\xb7\xa1\xa7\x14\x2b\x61\x9b\xd9\x1e\xa1\x79\xcd\xda\x79\xf2\x85\x0a\xc1\xe4\x7b\x6b\x62\xa3\xf9\xf3\x25\x77\x1c\x10\x93\xf7\x03\x81\x15\xee\x16\x5e\x2e\xf8\xf7\x32\xbf\x5c\x97\x4e\xff\xb4\x3c\x32\xce\x8c\xcf\xfa\x05\x31\xc4\x16\xd9\xf2\x52\xe6\x1a\x2a\xe7\x9f\x8e\x6f\xc7\xc4\x09\x66\x7f\x6c\x6d\xe0\x7b\xd9\x4c\x5a\xff\x64\x6c\xb8\x9d\xe9\xb5\xa5\x16\xbc\x2a\xfd\xc7\x26\x65\xc2\x25\x1b\x56\xcd\xcb\x73\xad\xaf\x00\x82\xed\x98\x08\x79\xd6\xd7\x45\xbb\x10\x3a\x4f\x8f\x13\x0a\x98\xc4\xc2\xd9\xd2\x31\x16\xc0\x74\xce\x70\x12\x32\xf4\x58\xb2\xda\xc2\x13\x9e\xca\xba\xce\xba\x0e\x62\xc9\x49\xaa\xa9\x53\xdd\xa9\x32\x4c\xa4\x8e\x7e\x9f\x13\xc3\x51\xdb\x03\xf3\x11\xe8\x17\x39\x7e\xe0\x41\x90\xc9\x89\x31\x48\x0f\x90\xb9\x9b\x7c\xca\x40\x39\xb9\xb7\xf1\xd5\x82\x84\x78\xda\x29\xf4\x15\x66\xaa\x9f\x9f\xb0\xfe\xdb\xe0\x64\xc6\x88\xf2\x20\x0d\x02\x36\x11\x1d\xe3\xfe\xce\x68\x98\xa0\x15\x39\xdb\xbe\x8f\xcb\x30\x7d\x30\xc8\xfb\x70\xaa\xa9\x55\x30\x7f\xc9\x4c\x73\xa8\x70\x9b\xbd\xf4\x1a\x8c\xfd\x13\x50\xa3\x0d\x78\xfc\x74\xbb\xbc\x1c\x1f\xe3\xac\x11\xe3\x4c\x44\xe8\x4c\x5b\xec\xd7\x22\xcf\xef\xe1\x0d\xf2\xa5\xe8\xf5\xb1\x27\x2a\xc8\x92\x87\x41\x84\x05\xd3\x75\xa1\xb3\xb7\x4c\x5f\x44\x3b\xfc\x53\xb2\x5b\x7f\x52\x44\xa4\x17\x60\x6f\xd4\x28\xa9\xe1\x47\x68\xe1\xa5\x40\xf7\x50\x34\x02\x51\x4a\x59\x81\x42\x9c\x18\x76\x0c\x59\x2f\xae\x11\x89\x3c\x84\x18\x5b\x28\x17\xb7\xbf\xaf\x77\x9b\xed\x61\xb7\x5f\xfc\x58\x1d\xee\x36\xcf\x5b\xff\xaa\xa3\xd8\xca\x37\xe3\xaf\x97\xa7\x4c\xfd\xea\x8e\x48\xdb\x2e\x6c\xa3\xea\xa1\x6c\xa5\xe4\x9c\xc6\xd8\x61\x72\x86\x2a\x2b\xf5\x7a\xbf\x39\xd8\xff\xd5\x1d\x67\x1c\x93\xe8\xbb\xe5\xc6\xf3\x96\x4b\xce\x23\x19\x62\x26\x6d\x10\xb8\x70\x0e\x02\xa8\x2f\x83\xb4\xd1\xc1\x4e\xe4\x08\x48\x1b\xa2\x85\x78\x02\x12\xb7\xdc\x4d\xa1\xca\xbc\x3c\x76\x53\x38\x31\x09\x92\x9c\x9d\x8e\xd5\x40\xa7\x50\xf2\x34\xb0\xec\xf7\xde\x7b\xbc\xd6\x42\x90\x3c\x0d\xa9\x15\x2a\x17\xf5\x41\x9c\x46\x67\x03\xc7\x9a\x1a\xd2\xdf\x3f\x96\x6f\x62\xbc\x6e\x04\x55\x58\xa8\x17\x5a\xff\xe3\xe2\xe2\xd5\x4f\x2a\x32\xa3\x29\x2f\x22\x13\x3a\x17\x6d\xdc\x48\x27\xb9\x48\x48\xea\x10\x65\x88\xa5\x6a\x17\x84\x4b\xc7\xff\xc5\x7a\xf1\x64\x6a\x09\x60\x01\x8c\x28\x2a\x90\xd7\xea\x1e\x4c\xf7\x94\x52\x18\xee\x7b\x2f\x2c\x15\xd5\x03\x52\x98\xcc\xd7\x1e\xfb\x4b\x2b\x22\xb0\x37\x5a\x97\x37\x97\x09\x10\x89\x2b\x99\x44\xc4\xf7\x04\xfd\x7a\x80\xea\x38\x42\x84\x71\x65\xe2\xd4\xd2\xc4\x7d\xb8\x16\x8d\x4e\xa6\x5a\x72\x88\x42\xc0\xb2\x40\x3f\x07\x81\x87\xc8\x22\x00\x85\xde\x98\xfb\x52\xbd\xce\x14\xa1\xb9\xa1\x01\x58\xd1\xdf\xa3\x23\x77\x90\x09\xd1\x31\x6e\x79\xbb\x7f\x6c\x1d\x7e\xe1\xe1\xf9\x7e\xbf\x7e\xba\x5f\x7b\x79\x1f\x99\x10\x03\xa9\xa7\x48\x9f\xed\x1c\x92\x49\x40\xd3\xd4\xa5\x31\x16\x79\xee\xb8\x6f\xef\xb2\x42\xe4\xd9\xff\x86\x54\x6b\x32\x09\xa2\x08\xdb\xc5\xfc\x8c\xfb\xd9\x61\x4d\x92\x20\xb2\x2c\xed\x16\x0f\x7c\x3a\x5f\xf2\x1a\xac\x0c\x85\x1b\x10\x6a\x2b\x54\x6f\x9d\xa6\xdd\x2b\xb4\x9f\x61\xc6\x68\x26\x11\x31\x58\xd5\x28\xe0\xbd\x73\xad\x2e\x23\xfa\x2a\x37\x30\xa6\x81\xb6\xdb\x72\x6f\x12\x66\xd0\x2a\x49\xcc\x28\xf2\x7b\x74\xbb\xf3\xca\xb9\x59\xfe\xd6\x62\x6e\x15\xbe\x50\x53\xe4\x0d\x86\x55\x7a\x3f\x42\x84\x68\xf9\x5e\x86\xfc\xcd\x32\xe1\xd2\x60\x02\xe8\xfe\xfe\x8f\xee\x4f\x3a\xc2\x4d\x6d\x46\x80\xd6\xa7\xb4\xc2\x7f\x4f\x1d\x81\x7f\x05\xc1\xbf\xff\x36\xe3\x91\x26\x1c\xec\x12\x47\x22\xb5\x76\x8f\xac\x1d\x31\xc1\xe0\xa3\x24\xc0\x55\xcf\xc5\x75\x83\x49\x86\xf2\x54\x5e\x9a\x4f\x34\x62\x64\x92\x12\x5b\x28\xfe\xe7\xf3\xd3\xd7\x49\xe6\xd9\x90\x25\x49\x8d\x44\xaa\xec\x8f\x0c\x72\xcd\x6f\xbb\x2c\x6d\x22\x22\x4b\x79\xff\x9d\x6e\x96\xfd\xdf\x0c\xd6\xb6\xed\x67\x1f\xbc\x95\xeb\x9e\x8d\x49\x67\xc8\xf8\x47\x25\x09\xd0\x84\x63\xcf\xb5\x4d\x0c\xb5\x9f\x72\xca\x88\x29\x13\xa9\xa8\x2f\xe9\x7a\x38\xed\x93\x68\xd7\x54\xd7\x99\x28\x13\xc5\x43\xea\x04\xcb\xb6\x08\x3e\x76\x6e\x94\x3b\xac\x35\x93\xbd\x7f\xef\x74\xc8\xc6\xce\xd8\xbf\xae\xbe\xe1\xd7\xb6\x2a\x81\xd0\x60\xaf\x8c\xed\x3b\x9e\x74\x01\xf8\x31\x3c\x41\x63\x25\x2f\x1f\x3f\x40\x0a\xe9\x77\x86\x04\x12\x6a\x53\x23\xd9\x68\x29\xf8\x1d\x30\x25\x9c\x81\x9c\xb4\xdc\xcd\xf5\xa5\xc8\x34\x60\x3a\x08\x5d\x0a\xed\xe6\xa3\xfd\x1c\xea\xe5\x4a\x8e\x66\x6e\x2a\xa6\x94\x08\x6d\x21\x40\xf8\x09\x16\x85\xc6\x40\x60\x76\x86\xa5\x34\x4c\x90\x2e\xc7\x3e\xe7\x48\x29\xd1\x8f\x88\x08\x2a\x9f\x6b\xf1\xd1\x64\xa7\xab\xa3\x10\x62\x83\xc9\x21\xab\xbf\x95\xe5\x2c\x29\xbe\x4c\x19\x0d\xb0\xe5\xa5\xcf\x2e\x7c\x72\x37\x11\x89\x22\x97\x1d\xf1\xca\x8f\x57\x50\xa0\x34\x22\x82\xbb\x0d\x0f\x29\x8b\xda\xd9\x35\x40\xcc\x5f\xbd\x9a\x6e\x01\xa6\x91\xd0\xe0\xbb\xee\xee\x44\x66\x29\x40\x5e\x44\xfd\xb2\x2e\xea\x8b\x31\x19\xa8\x0c\x8a\xa6\x2f\xcc\xa7\x91\x4e\x81\x77\xa5\x09\x93\x1d\x57\x45\x53\x59\xa2\x84\xd9\x2a\x7f\x1a\x07\x56\x4e\xd9\x52\x9f\x3b\xe0\xca\xec\x1c\x4a\xe3\x54\x12\xc7\x22\xda\xd4\x4d\xd5\xd9\xaa\x94\x33\x9b\x16\x70\x98\xa8\x4e\x20\x63\x52\x48\x98\xbc\x3a\x9e\x4a\xcc\x05\x6f\x37\xcf\x8f\xb7\x87\xe0\xf0\xb4\x5d\xed\x16\xf7\xab\x21\x7d\xb7\x4c\xb9\x8c\xd1\x57\xc8\xcf\x8b\xfa\xd5\x85\x3e\xee\x50\x22\x42\x82\x9d\x46\xaf\x59\x31\xd6\x99\x96\x69\x4a\x68\x82\x94\xfb\x88\x7c\x6f\xa0\x82\xeb\x64\xdb\xff\x9f\x47\x90\x0a\xaa\x80\xfa\x9c\x4d\x9e\x3f\x95\x35\x12\xef\x7c\xb2\x18\x44\x18\x61\xf2\xfc\x5b\xd6\x7c\xbf\xc8\x21\x23\x80\x4c\x85\x0c\xd0\xf2\xae\xce\x43\x86\x1d\x99\xca\xd0\x92\x45\x59\xdb\x30\x49\x36\xa4\x52\x10\xd6\x09\x10\x38\xff\xbb\x17\x3e\x78\xb0\xc4\x62\xf3\x45\xc2\x54\x0a\x2e\x55\xd7\x4d\xb7\x50\x0a\x61\xa9\xa0\xbb\xa6\x80\xc9\x70\x09\x58\xa3\xdc\x8a\x6c\xd7\xa5\x0a\x52\xc5\x6d\x43\xb7\x72\x4c\x19\xf6\xe4\x53\x0f\x0d\x48\x95\x08\x90\x95\xf0\x41\x54\x99\x28\xc4\x0f\xb8\x02\x69\x5f\x57\xcc\x53\x25\xad\x62\x66\x71\x39\x2d\x5f\xb2\x73\xdd\x3e\x49\xff\xa3\x5a\x27\x51\xd0\xa3\xb7\xd7\x85\x29\x6f\x3e\x6c\x9b\xdd\xf8\x85\x6b\xd0\x61\xfc\x49\xbb\xf9\x7a\xb9\xf1\x15\xe5\x14\x02\xea\xbc\x36\x7f\xf7\x6b\x7d\x2f\xea\x66\xd1\x34\x70\x3a\x37\xa0\xf7\xe5\x0e\x9a\xa6\x0b\x15\x53\x50\xb6\x73\xca\x6a\xa4\x3d\x41\x55\x67\xa2\xa8\xf7\xa5\xc5\xc4\x4c\xee\x02\x8c\x32\x3e\x31\x7b\xa9\x9b\x52\x67\xa2\xb8\x2b\x2b\x68\x1d\x8d\xd1\x3b\x16\x24\x4e\x10\xde\x62\xb2\x73\x8d\xda\xe2\x35\x46\x71\x28\x8a\xee\x6b\x42\xbe\x2e\xe5\x4f\xe1\x3c\xc5\xfa\x45\x26\x9a\x41\x3d\x46\x10\x21\x2c\xdf\xd5\xaf\x3b\x80\x5d\xfb\x44\x03\xaf\x50\x10\x05\x91\x0b\x81\xee\xb3\xe2\xb5\xfd\xe8\xa3\xfc\xa2\x08\xa8\xe5\x0d\x45\xe2\xfb\xd6\x47\x1c\x4f\x3c\x11\x30\x89\xc9\x66\xd7\x2f\xf0\x49\x6e\x50\x04\x8e\x3b\xeb\x2e\xff\xf0\xef\x4e\xd0\x30\xd6\x56\xdf\x19\x4f\x5d\xed\xbf\x77\x47\x62\x4a\x9c\x80\xd1\x33\x06\x9c\xbf\x5d\x49\xff\x4b\x41\x05\xf5\x99\xcf\x27\x1b\x1e\x0d\x51\x0b\x82\x4a\x2b\x86\x70\x38\x42\x63\x23\xdd\xfa\x52\x9d\xf3\x2e\xea\x11\xd4\xc8\xd8\x56\x81\xdf\x9f\xca\x3c\x53\x1f\x9f\xe9\x00\x8e\xfe\x4d\xc6\x59\x11\xc1\x62\xc9\x6c\x03\x3e\xd2\x2f\x6c\x61\xfa\xe4\x61\x6b\xff\x86\xfc\x59\x4e\xe2\x7c\x3c\x37\x44\x28\x24\x42\x0b\x6c\x17\xb0\x7b\x8d\x4b\x04\xe7\xcf\xee\x2d\x22\xa2\xc6\xab\x4f\xf8\x85\xba\xb4\xd2\x76\x73\x80\x29\x11\x69\xb0\xee\x50\x7b\xdd\x1c\x65\xf1\x8f\xa8\x0c\xe2\x5f\x47\x04\x40\x7d\xd6\x39\x2b\xda\x9d\x0d\x0e\x60\x0c\xa8\x26\x33\xdd\x18\x13\x20\x5f\xd8\x7b\x9f\x25\x9b\xe4\x46\x44\x1c\x47\x81\xaf\xcf\x78\x49\x8d\xbd\xf8\x35\xcd\xa1\x88\x98\x87\x89\xea\x04\x4a\x5d\x7b\x61\x1b\x9d\xf6\x9d\x40\x22\x86\x28\xf0\x9f\x10\xc3\x82\x09\x3c\xa4\xf7\x85\xa6\x19\x03\xc1\x09\x4b\x5c\x0b\x1a\x14\xcd\xa5\x82\x9b\x4f\xba\xcc\xe6\xfe\x9d\xce\x34\x1e\x18\x94\x94\x72\xf1\x38\xee\x85\x47\x88\xfd\x6d\xf2\x30\x44\xa9\xb9\xa7\xb2\x86\x4c\x97\xc5\x3f\x2e\xa2\xeb\xee\x13\x9c\xa7\xf8\xca\x44\x75\xfa\xf8\x0e\x79\xa6\xca\x73\x03\x55\x3d\x93\x08\x12\x3c\xe5\x9c\xbb\xed\x3c\x50\x9d\x02\x93\x14\x5c\x05\x18\x98\x08\xad\x51\x3b\xf2\x6b\x22\xcb\xee\x24\xc5\x9d\xef\xb1\xae\x87\xac\x62\x52\x24\xa1\xc4\x42\xd5\xfd\x7f\xde\x77\x8d\x28\xb4\xa8\xf4\x70\xab\x11\x29\x89\x1d\xe8\xa1\xa3\xe3\x1f\x7c\xa0\xc1\x28\xac\x13\x7e\xcf\xaa\xf2\xe3\xf2\x9a\x0d\x1a\x00\x44\xca\x52\xab\x41\x75\x2c\xbb\x5a\x91\x48\x15\x60\x99\xde\x53\x16\xdc\xc2\xdb\xe0\x10\x56\x48\xeb\xf2\x04\x0b\x75\xed\x24\x89\x54\x4b\xeb\x19\xbf\x14\xe2\x08\xbb\x33\xa8\x4c\xe4\x77\x00\xfb\x81\x96\xe6\x9f\xbc\x90\x14\x94\x50\x7d\xfb\xcc\x8d\x28\x5e\xfb\xd9\x2f\x08\x60\x76\xf7\x1d\xe0\xd5\x77\x25\xfb\x43\x49\xaa\x1d\xf4\xe6\x26\xd3\x9f\xa8\x25\xb8\xb1\x52\x59\x16\x98\x27\x10\xed\xea\x15\x59\xf1\x67\x92\xb3\x52\x48\x2d\x11\xdf\xac\xb3\x5a\x4c\x00\x26\xe3\x8b\x2b\x96\x46\x41\x2f\x3a\x31\x4d\x96\x0b\xc5\x75\xa0\x3d\x29\xec\x27\xa5\x81\xcf\xfe\xc5\x76\x9c\xc9\xe5\x12\x3b\x73\x2d\x18\x6d\x10\xf8\x09\xa5\x42\xcf\xdf\x76\x33\x40\x8a\x08\x9d\xa4\x89\x2f\x93\x7f\xf4\x5c\x61\xee\x28\x44\x80\x8e\xb7\xb7\x56\x53\x8b\x00\xed\x2f\x5a\x7b\x6c\xb5\x93\x9e\x7c\x01\x41\x18\x92\x86\x62\xa0\x1e\x35\xb9\xb2\x09\x28\xea\xdd\x1d\xac\x07\x33\x40\x47\x5d\x17\x5f\x25\x01\x89\xfb\xc2\xc9\x91\xad\x96\x7d\xd1\x53\x06\x81\xe9\xe4\x60\x10\x26\x23\xb3\xc9\xd9\x81\x8a\xb0\x09\xf9\x8f\x9b\xe5\xe6\xe1\xe1\xf9\x71\xed\xe5\xdc\xa4\xa4\xb1\x26\xa4\x07\x69\xa2\x1e\x9c\x57\x9c\x72\x43\x58\x6a\x10\x2d\x85\x50\x6f\xa4\xc3\x9f\xcf\x5d\xca\x50\x5b\xcb\xb7\x79\x83\xaa\x06\x51\x6f\xa1\xb9\x54\x05\x40\xfd\x5c\xf4\xe9\x03\x19\x6a\x65\x79\x9e\xb1\x39\xf8\xa1\x2c\x9a\x97\x55\x07\xb5\x95\xa1\x21\x08\x1a\x7d\xbc\x0c\x17\xb7\x8c\x12\x85\x49\xbd\xae\x0d\xf8\x6e\x71\xbf\xdc\x3c\x76\x87\x75\xe4\xba\x8e\xac\x5e\x7b\xbd\x2f\xd7\xcb\xcd\xf8\x53\xc9\xc8\xc4\x58\x82\xfe\xf1\xfc\xb8\x5f\x8d\x4d\xc8\x9f\xba\x74\x32\xa6\x9c\x76\xb2\x77\xf5\xa8\x56\x22\xe3\x88\x63\x64\x65\x2a\x00\xfd\x33\x2b\x3e\x93\xbd\x91\x92\x27\x3c\x40\x9b\x6c\x0d\xd3\xa1\x86\xe6\x24\x7e\xdd\xc0\xc4\xa8\xca\x24\x65\x1e\xd8\xb4\x03\xd1\x78\x8a\xa2\xf1\x20\xc9\x23\x0f\x79\x70\x7b\xa8\x13\x31\x77\xc7\x15\x0b\x43\x07\xbd\xf8\x69\x6b\x5c\xbd\x93\x99\xf8\x31\x32\x44\x6f\xe6\x5b\x99\x15\x4d\xf9\x90\x1d\xab\x99\x60\x4f\xea\xd8\x22\x3c\xcf\x97\xfa\xe5\xfb\x90\xd3\xf8\x6f\x83\xf0\x7a\x02\xc0\x94\x5a\x5a\x26\xf2\x97\x4c\x6b\x18\xe1\xc8\xa5\x96\x06\x19\x6d\xda\xe7\xdf\x67\x3d\x18\x41\x02\xb5\x98\x13\xe9\x91\x58\xf3\x13\x0d\x78\x82\xa8\x83\x47\x78\xbf\xd9\x3c\x7d\x59\x14\x4d\x66\xf3\xae\x12\xb4\xc1\xf9\x84\x39\xb7\xbf\xc6\x98\x28\xa5\x09\x02\xcc\xfc\xdd\xec\x97\xcb\xc1\xbe\x21\x4d\xca\x04\xf1\x70\x82\x46\x64\x5d\x51\x5d\x1a\x11\xa2\xa3\xaa\xe1\x9a\xd4\x48\x4a\x03\x09\x23\x5d\x01\x12\xef\xe2\x3b\x96\xa9\xdc\xe9\x8a\x10\x89\x16\xe4\xdb\x62\xb9\xec\xfe\xc6\xac\x0e\xf4\xb7\xe5\x9d\x2a\xb3\xe2\xee\x2b\x2b\xad\x48\x2a\x11\x8b\x77\xb2\x10\x97\xd6\x1b\x47\x7c\x45\xbf\xba\x15\x0b\xb5\xa5\x0e\xa8\x9a\xac\x6e\xea\x45\xd5\xbc\x97\xd5\xab\x1d\x32\xba\x5d\xc5\x34\x01\x83\xd3\xbc\xfc\x1f\x14\x0e\xba\xba\x07\x71\x1a\xd5\x01\x54\x48\x28\x46\xce\x36\xc1\x76\x2b\xaa\xd7\xa2\xd4\x80\x5c\x7b\xb3\x3b\x44\xbb\xf9\x44\x8e\x63\xac\xd3\x7c\xba\x34\x2f\x65\x95\xfd\x4f\xcc\x34\xfb\xaa\x30\x4c\xd1\x70\xde\x65\x55\xdd\x4c\xa2\x64\x15\x72\x88\x3a\xe1\xb1\xfb\x6c\x66\x80\x49\xd1\xc7\xf2\x98\xd2\x9b\xfd\xf2\x4b\xa0\xa3\x8a\x98\xc2\x4a\xe8\xa2\x12\xb5\x12\xed\x3b\xff\xf2\x95\x47\x5a\x62\x94\xdc\x06\xb3\x75\xb3\xa8\x07\x34\xa6\x52\xc5\x8a\x60\x2c\x65\xf0\xd6\x5f\xb2\xf3\xb0\xa2\xa1\x62\x4d\x10\xe1\x7d\xdd\xa1\xdd\x3a\xe9\xbb\xec\x58\x88\xd6\x29\x1c\x0b\x98\x24\x43\xa4\x9f\xbb\x10\x17\x56\x26\xdf\x20\xd0\x06\xf4\x7d\x89\xa0\x2b\xff\x3b\x09\x89\x00\x3a\x44\x8a\x43\x2b\x0d\x0b\xed\x56\x88\x1d\x19\xcd\x26\xfb\x9d\x4a\x88\x55\x85\xbf\x13\xaf\xf0\x08\xef\xa3\x68\x5f\xa5\xa1\xd4\x0e\x77\x60\x31\x3e\x9d\x9c\xdd\xf8\x22\x69\x68\xd0\x6b\xb7\x37\xd0\xb3\x33\x4d\x87\xa5\x04\xa3\x34\xb7\x43\x8e\x69\xa4\xfd\x18\x15\x93\xa0\x07\x8c\x2d\x2c\x39\xdf\xa0\x30\x78\x95\xc0\x57\x22\x96\x02\x17\x85\x68\xc3\xf2\xe2\xba\x19\x57\x49\x45\x26\x1a\x79\x93\x5f\x55\x8c\x73\xab\x11\xf3\xf0\x61\x67\xbf\xed\x6e\x38\xec\xa0\xdb\xca\x94\x52\x54\x06\xbe\x53\xb0\xcc\xef\x82\x36\x2a\xbc\x0b\x76\x4d\x75\x47\xd7\x45\x63\xd8\x6f\x23\x91\x4e\x37\x99\x46\x37\x02\x52\x5b\xbe\x2c\xc8\xe1\x28\x1a\xd0\xdb\x6b\xe1\x35\xa9\x40\xd9\x8e\xed\x76\xff\x99\x27\x2a\xf3\x03\x8d\x05\x49\xfe\x14\xc5\xb1\xfd\xcf\x72\x66\x32\x5f\xef\x7d\xca\x04\x11\x56\x68\x9e\x1f\x91\xb1\x65\xbf\x5a\x3c\x78\xe2\x51\xa9\x8c\x20\x03\xa1\x5c\x84\xe5\x4f\x0a\x5f\x53\xf3\xdc\xfb\x64\x9a\xc4\xca\xea\xba\x87\x74\xd4\xf2\xaf\x89\x8a\xf0\xaa\x48\x63\xfa\x17\xf0\xd9\xfe\x34\xe0\x58\xe3\xd8\x42\x76\x92\x97\xaa\x2b\xb2\xeb\x20\x0a\x90\x42\xc0\x36\x8c\xba\xfd\xb4\xee\x8e\x6a\x83\xcd\x6c\x58\x07\x1e\x5a\x47\x1d\x80\xc4\x92\x85\xc6\xb6\x07\xec\xbb\x18\x59\x3b\x4d\x69\x88\x41\xbf\xe5\x41\xde\x8a\xff\x74\x07\xb8\xe5\x26\xb7\x74\x1d\xdf\x26\x41\x5c\xe2\x47\x69\x69\x05\xb9\x2a\x78\xcb\xca\x4b\x7d\xeb\x3e\xf4\x64\xd9\x69\x96\xda\xab\x21\x3b\xfe\xb5\x70\x93\xd4\x4c\x45\x98\x30\xcf\xc1\x34\x09\x9b\x1e\x74\x8e\x19\x96\xe0\xea\xe6\x4a\xce\x68\xbc\x40\x74\x48\x2d\x8d\xab\x14\x35\x58\x36\xd9\x43\x56\x1f\x6a\x80\x4e\xcb\xa1\x1d\x03\xc4\xcc\x37\xf7\x74\x43\xc0\x1a\x3b\xf5\xf2\x8a\xfd\x5b\x7a\xe2\x5b\xeb\x28\x14\xb1\xf7\xbc\x1d\x50\xea\x93\xc8\x58\x47\xa9\xd5\x0d\x59\xed\xef\x87\x16\x47\xc7\xb1\x65\xcf\xab\x5d\x40\x5e\x4e\x29\x83\xa5\x8e\x35\xe7\xe0\xd3\xc7\x65\xa5\xb3\xe2\x8a\xb9\x56\xea\xd8\x68\xf4\x83\x6c\x49\x60\x59\x56\x9f\xf8\xb8\x9a\x13\x8e\xc2\x8a\x87\xc3\xc1\x52\x29\xfe\xfa\x98\xc1\xc5\x6a\x2e\x93\x88\x0d\x7c\x72\x1b\x8f\x5a\x96\xfe\xc9\x05\x55\x84\xb6\x06\xb9\x20\xf7\x3e\xa7\xa7\xb9\x26\xb8\x4d\xd9\x42\xe5\xf7\xcd\xed\xfd\x81\x3d\xf8\x83\x49\x60\x05\xa5\xf2\xf2\x78\x1c\x33\xc7\x49\x9d\x12\x8a\x4d\xce\x87\x3e\xcf\xef\x18\xc6\x3d\xc4\xf8\x53\x14\x99\xbf\x42\x24\x9c\x1c\x51\xeb\x94\x7c\x32\x55\xa6\xe7\xa8\x98\x46\x53\x90\xe3\x93\xc8\xdb\x7d\x67\xf2\x6a\x52\x65\xd9\xa2\xde\xa0\xd0\x3e\xa3\xa7\x45\xdc\xc1\x90\x91\x85\x74\xba\x42\x85\x11\x26\x1d\xe7\x8d\x16\xcd\x4c\xce\x54\x4b\x4e\xb0\x14\xf2\x63\xfb\xd3\x37\xa6\xb7\x4b\x0c\x01\x61\xb9\x68\xdd\x01\xc7\x89\xdc\xfb\xba\x6e\x94\x22\x0c\xf1\x20\x05\x34\x6d\x88\xe5\xfd\x86\xda\x72\x32\x7f\xbe\x5a\x54\x14\x53\xd1\xa9\x9a\xd8\x32\xc3\x20\xee\xd4\x9a\xa5\x89\x65\x35\xe1\x63\x1b\xa7\x79\x82\x22\x1a\x1d\x13\xa9\xbf\x13\x9d\x44\x18\x4f\xe0\x9e\xb8\xc0\xb6\x11\xb8\x2a\xfa\xfb\xb1\x22\x88\x2c\x2a\x68\x5f\x5d\xda\xe0\xd1\xdf\xf7\x6c\x11\x48\x43\xc8\xed\xf6\xbd\x5a\x1d\xb6\x8b\xc7\x6f\x1e\xe9\xa8\x21\x92\xb6\x83\x51\x9c\xc0\x29\x25\xfb\x23\x89\xd0\xed\x91\xf3\x55\x13\xb0\x86\x44\x73\x2b\x44\x51\x5c\x44\xee\x89\xe8\xf7\x7d\x88\xd4\xdf\x27\x80\x42\xb7\xb5\x9d\x53\xd9\x09\x9e\x2a\x14\xa0\x77\x07\x0d\x61\x3c\xe9\xfb\x38\x5e\xb2\x5c\x57\x50\x8c\x71\x2b\xda\x84\x11\x76\xa8\xfc\x5f\x59\xa2\xd4\xec\xd0\x0e\x00\x21\x16\xae\x56\x59\xaf\x0e\xd3\x95\xd8\x06\x28\x4e\x30\xce\xfd\x02\x09\x6d\x4e\xb1\xfd\x44\x77\x97\x42\xf5\xa4\x1e\x83\x9d\x09\x48\x44\x2c\x3d\x4c\x79\x3c\xe6\x70\x55\x46\x06\x92\x32\xe4\x52\xb2\x9a\xaf\x96\xf7\x37\x2b\xf5\xed\xc5\x4e\x2a\x27\x78\xef\x7f\x93\x82\xe5\x6a\x14\x5a\x0f\x82\xbd\x49\x80\x32\xb8\x3a\x63\xa1\x49\xba\x46\xdb\xbb\x4b\x6e\xb2\x3c\xb7\x4d\x77\xa3\xd7\x0a\x2c\xb4\x0d\xe5\xa7\xac\xb8\xb9\x7c\x6c\x45\x03\xeb\xe2\xa9\x02\x95\x0d\x0a\xf6\xc0\xa2\x30\x75\xec\x60\x3f\x01\x01\x51\xfe\x40\x62\x1c\x31\x5d\xb1\xaa\x95\x38\xc3\xbe\xf4\x05\xd3\xc1\x1d\xfa\x2f\x00\x4c\x4a\x4c\x85\xed\x77\x7b\x24\x96\xfa\x5f\x9f\xec\x00\x06\x56\x3b\xfd\x80\xcb\xe0\x3c\xdb\xd7\x01\x61\xc0\xb0\x27\xcf\x71\x51\x8f\x65\x41\x86\x4d\x23\x3e\x89\x09\x61\x24\x31\x86\xbd\x14\x59\xf3\x74\xbf\xd8\x2f\x07\x08\x73\x37\x24\x52\x40\x7a\x5a\xc5\x91\x31\x1e\xaf\x54\x88\x74\xc2\x61\xd0\x71\xe3\x70\xe6\xdd\xa6\x06\x71\x64\xe9\xee\x4c\x56\xe8\x4d\xae\x3b\x12\x7b\x09\xb1\x48\xa5\xd5\x93\x40\xc9\xcc\xc3\x30\x41\x02\x3c\x0d\x30\xb3\x64\x97\xea\xc1\xa9\x9a\xf9\xa3\x49\x9a\x22\x5c\xe2\x5b\x1b\xda\x15\x57\x33\x37\xd1\x42\x7a\xc8\x3a\x6e\x5f\x77\x65\x35\x60\xf3\x19\x2f\x77\x48\xa5\x25\x71\x3a\x38\x29\x03\x57\x85\x40\x9f\xa5\xfa\x93\x26\x00\x10\x22\x41\x5f\xc5\x3a\x91\xbb\x21\x49\xca\xac\x55\x07\x21\x00\x8b\x15\x4e\xca\x06\xf4\xe2\x58\x01\xf6\xd8\x2e\x2d\x44\xde\x67\x49\x41\xa8\x54\x75\x12\x76\xc6\x46\x35\x9f\x5c\x13\x24\x72\xe7\x9d\x2e\x55\x1f\xe9\x82\x4c\x2c\x9c\xbe\x29\x2f\x28\xf4\x56\x4c\xe3\x36\x90\xca\x92\x49\x7b\xda\x22\x1b\x22\xce\xd5\xf7\x41\x85\x1c\xdb\xa7\x11\xbb\x74\x2e\xcb\x1c\x09\x7e\x50\x57\xaf\x67\xd5\x02\x15\x05\xae\x80\x88\x91\xc3\x16\x34\x9c\xce\xd7\xc9\x0f\x50\xb1\x41\xde\xee\x63\xdf\x0c\x04\x2a\x0d\xf0\x6f\x27\xf1\x6b\x3b\xa2\x63\xf3\xc7\x21\xb5\x1a\x5e\xb2\xac\x1a\xaf\x7d\x7f\xfd\x41\x80\x4b\x8c\x7c\x8f\x99\x69\xd6\xd8\xb6\xec\x7f\x00\x94\x0c\xb1\x96\x24\x0c\xf8\xa0\xf8\xe6\xe3\xaa\x33\x6f\xfe\x15\x03\x70\x5c\x66\x59\x6d\x8d\x92\x95\x2c\x98\xdc\xa2\x21\x56\xa4\x03\x89\x73\x2c\x19\xdc\x5f\x2a\x1a\x83\x49\x23\x6e\xf3\xfa\x9e\x3e\xce\x90\x08\xf0\x85\x7f\x13\xf5\x7d\x79\xfc\x04\xf8\xe6\xc7\x0a\x0d\x2e\x2a\xb2\x2d\xfb\x13\x01\x2a\x69\x88\xe1\x28\xd5\x28\x2f\x59\xae\x37\x97\x09\x53\x9a\x09\x92\xd0\x93\x2f\xda\x6c\xb8\x15\x04\xdf\xc2\x7f\xbb\x11\x22\x44\x9a\x92\x97\x32\xff\xb0\x65\xea\xbb\x4b\xa1\xc7\xec\x16\x26\x30\x16\x8e\x78\x29\x26\xf9\x6b\x77\x9c\x52\xed\xe0\xb6\xf5\x05\x1c\x9b\xed\x5f\xe0\x15\x33\x94\xc5\xe8\x3c\x67\xb5\xf3\x61\xc6\xe8\x74\x43\xb5\x8e\xc5\x84\xaa\x6c\x28\xf3\xff\x19\xa8\x68\xfc\x2b\x2c\x22\xe8\x2f\xe1\xe9\x37\x37\x98\xb6\xf5\xbf\xc0\x54\x92\x68\x5f\x13\x3b\x16\xa0\xb1\x16\xab\x56\x85\xfa\x01\x93\x14\x94\x09\x49\x24\x6d\x9f\x62\x21\x5e\xfb\x2d\xc3\x84\xd4\xb6\x1f\x2c\x45\xfd\xf2\x54\x66\x45\x53\x07\xdd\xa1\x50\xf8\x60\x62\xe3\xd8\xcb\xbe\x89\xc9\xbe\x64\xa2\x88\x62\x3b\xff\x4b\xd6\x19\x42\x13\xc5\x81\x81\x91\x72\xbe\xd0\x1d\xbf\xe6\xc1\x94\xd5\x61\x31\xb9\xbb\x28\x91\x6c\x48\x1d\x31\xa9\x21\xb9\x51\x71\xca\xb0\xad\xe1\xee\x92\x03\xfc\x1a\x1a\x57\xc3\x93\x44\xc7\x8e\x79\x75\xb6\x88\xf6\x09\x6c\xdc\xf0\x34\x21\xa6\x43\x7c\x67\x45\x7d\xdd\xa0\x32\x7a\x5e\x2e\x05\x1a\x79\x04\xfb\xac\x7e\x9d\xf3\xb2\x82\x2b\x25\x58\x69\x38\xa4\x18\xa9\xaf\x7e\x89\xe7\x9d\x47\xf9\x9b\x84\x70\xce\x3a\xea\x99\x6d\x59\x4e\xd2\x0d\x26\xa1\x1a\xcb\xb5\x3f\xcb\x2a\xd7\x3f\x33\x3d\x90\xd8\x96\x26\x0d\x12\xdf\xf9\x88\x45\xff\x8b\x76\x2d\x75\xe3\x6b\xa4\xa1\xc2\x75\xf7\x2d\x17\x99\x9e\xbc\xa6\x54\x0b\xe9\x40\x60\x37\xd0\x34\x7d\x0e\xd9\xa4\x5a\x21\xdb\x58\xbb\x79\xf5\x62\x03\xd2\x88\x30\x45\x04\x41\xa6\xca\xb1\xfe\x50\x7b\x48\x72\xd3\xdb\xd5\x7a\x18\x4f\x1b\xc1\x39\x52\x2f\xbf\x89\x4b\xde\xfd\x51\xf2\x18\xcb\x13\xdf\x9e\x17\xab\x3f\xbe\x4a\xae\x19\xc9\xb9\x76\x25\xf6\x45\xf5\xdf\x4b\xf6\x56\x0e\x09\xc3\x10\x1c\x8a\x8d\xe3\x08\xca\x3c\xf8\x3b\x73\x9c\x34\x93\x6f\x21\x13\x69\x79\x1a\xac\x33\x92\x15\x1d\x6b\x95\x1f\x20\x63\x04\xd4\xdf\x2c\x76\xab\xc3\xf2\xfe\xe6\xb0\xdf\x1c\x56\xfb\xef\xa8\xcd\xef\xc7\xa8\x20\xc6\x38\xef\x8f\x9b\x51\x5c\x6a\x74\xa0\x85\xab\x4b\xff\x00\xa5\xc4\x2b\x8d\xe2\xe7\xec\xb3\x4e\x20\xa3\xc3\x08\x89\x2e\x9e\xb6\xab\x03\x02\x86\xb0\xce\xd1\x25\x59\x8c\x4e\x09\x82\xdf\x6d\x42\xef\xe6\x52\x15\x59\x71\x44\x2a\xb6\xc1\x8e\x66\x0c\xa7\xd8\x78\xf1\xbd\xd4\xb2\x9c\x76\x7c\x18\xa4\x90\xf0\xec\x98\x59\x53\x23\x65\xd6\x9d\xc8\x72\x0c\xa3\x36\x1b\xc7\xba\xa1\x08\xa1\x96\xb0\xc5\x52\x90\xfa\xe2\x85\x22\xc4\xb1\x1e\x3c\x6c\x6e\xd7\xcb\xcd\xfa\xd1\xff\x3d\x08\x22\x6c\x6e\xb4\x49\xcd\xf6\x67\x1d\x83\xdf\x6d\x57\x8f\x54\x24\xe0\x21\x6e\x37\x1d\x35\xab\xe5\x6a\x5d\xfd\x82\x4a\x61\x5f\xeb\x9c\xbd\x6b\x97\xa5\x77\x8a\x15\x09\x12\x45\x6c\xb4\xf1\x0a\xd6\xa4\x75\x17\x4f\x13\xdf\x59\x8c\x60\x8f\x99\x9c\x9d\x22\x81\x90\x16\x59\x8f\x13\xaa\xe7\xf4\xbb\x9e\x67\x8a\x04\x0a\x12\x36\x68\x83\xc0\xfa\x4a\xfd\x27\x4a\xfd\xfe\x5c\x6d\xa4\x2f\xd5\x3d\x9f\x9b\x72\xd6\x0f\x52\x84\xc6\x14\xda\xb9\xba\x3c\xe3\xa3\x7c\xeb\xbc\x0b\x45\xa8\xb2\x48\x5d\x51\xd7\x50\x35\xab\x5f\x67\x50\x8d\xcb\x84\xbb\x11\x2c\x0c\x6d\xd2\x3e\xcf\xc7\x5c\xa3\xed\x21\xe9\x1b\x6e\x9f\xca\x32\x1f\x96\x84\x14\x61\xb1\xc6\x4f\xb5\x5b\x2d\x9f\xb7\x5d\x15\x50\x11\xc6\x39\xb6\x38\xba\x5f\xfc\x2f\x73\xfd\x52\x2c\x70\x76\x31\xf0\x03\x15\x07\xd5\xbf\x69\x28\x74\xf0\xdb\xf8\xb9\x98\xb1\x0c\xaa\x0f\x42\xdd\x94\xe5\xeb\x90\x81\x56\x91\x90\xd9\x8a\x07\xf2\x72\x63\xa1\xa1\xc3\xf9\xb5\x07\x95\x70\x95\xe0\xa7\x4b\x9e\xb7\x6e\x74\xc7\xea\xac\x48\xc8\x39\x26\xb8\xb6\xfb\xee\x2f\x82\xe2\xbd\x1c\x8e\xed\x4e\x94\x1d\x33\xdf\x6b\x38\xd4\x03\x98\x13\xea\x54\x24\x54\x56\x84\xf3\x2c\xaa\xa6\x80\x8e\xe7\x63\xdc\xe6\xf6\x09\xed\x7a\x7b\xb6\x35\x0c\x58\x10\x5d\xd4\x3b\xa1\x90\x5a\x0d\x35\x57\x90\x8b\x6c\x32\xf3\x22\x11\x1b\xe5\xd9\x81\xca\x73\x0e\x56\x9d\xf4\x61\x9e\x05\x5c\x91\x98\x58\x8e\x42\x5b\x41\x41\xbb\xd2\x61\xb0\xff\x8a\x8f\xa6\x48\x1c\xc5\xca\xf1\x2b\xeb\x71\x1b\xa6\x1f\x20\x12\xde\x67\x6d\x17\xe7\xf3\xd4\x69\x1b\xbd\xae\x58\x53\xcc\x98\xd7\x97\xa2\xca\xea\xee\x93\xf0\x44\x62\x66\xe0\xdb\xed\x72\xa1\x14\x89\xfc\xdf\x13\x62\xe9\x3c\x25\x34\x87\x87\xde\x4e\xa4\x81\x44\x58\xe6\x43\x36\xd0\x93\x54\x24\x35\x4e\xe9\x09\x85\x65\xe7\x20\xcf\x33\x95\xb9\x11\xbd\xc1\xb8\xfc\xa1\x88\x60\x29\x6e\x67\x59\xed\xb4\xef\x66\x01\x8d\x8a\x28\x16\xc6\xb8\x04\xab\x8f\x73\x53\xb6\x3e\xde\x6f\xdd\x91\x04\x4b\x4c\xb7\x75\xa9\x32\x8f\x05\x51\x44\x45\x96\xf8\x08\xb5\x27\xf2\xfc\xa9\xa9\xfa\x23\x21\x7a\x75\x4d\xbf\x09\x28\xa2\x49\x60\x51\x68\xe8\xa0\x0e\xf3\xc6\x8a\x68\x05\x48\xd7\xb3\xd8\xdf\x4f\x66\x0b\x30\x9d\x92\x8e\x43\xf7\xb5\x7b\xdb\x10\x5a\xe2\xa6\xc3\xe1\xb0\xc8\xf3\x51\xe3\xb3\x22\x10\xdb\x3a\x6e\xaf\xe0\xf2\x4d\xb4\x5e\xa5\xf7\xd0\x26\x8b\x14\x78\x88\x85\x9a\xfa\xe5\xd2\xe8\xf2\xbd\xbb\x63\x10\x36\x6d\x79\xae\x4a\x05\x35\x32\x77\xac\xf7\xdf\x3e\xb1\x60\x86\xa5\x58\x12\x6f\xbf\x96\x85\xd9\x18\x78\xe8\x57\x6c\x40\x88\x63\xd4\x2b\x86\xde\x86\x0a\x48\x1c\x61\x51\x54\xa8\xe6\x22\xf2\x83\xc1\x52\x6f\x77\x30\xb1\xb2\xfe\xcb\x3f\x06\x73\x24\x20\x89\xed\x4b\xf9\x26\x4e\x32\x87\xea\x69\x5e\x90\x5f\x05\x44\x87\xda\x95\xc4\xef\x00\x3a\x9d\xb0\x9b\x8f\xf5\x38\xfc\x51\x41\x60\x78\xa0\xfc\x0b\x9b\xaa\xdc\xce\x23\xbb\x83\xee\x5f\x77\x0d\x4a\x93\x94\x76\x8d\x83\x9b\x33\x14\x0e\x05\x34\x81\x3a\x0d\xd7\x52\x40\x95\x8b\x6e\xf2\x52\xbd\xda\x74\x67\x3d\x21\x50\x57\x01\xd5\x06\xfb\xac\xde\x21\xbb\x85\x3c\x7b\x83\x8e\x26\x5b\x05\x2c\x0c\x31\xc0\xf8\x0e\x22\x6f\x5e\x5c\x3f\xe2\x5f\x83\x31\xa8\x80\xc5\x29\xb6\x95\xac\xbc\x24\x7d\xa7\x71\x9a\x5b\x88\xf3\xe0\x77\x04\xb7\x53\xda\xe1\xb4\x17\x5a\x3b\xd8\x27\x26\xe8\x1e\xcb\x66\x5d\x3c\x77\xc6\x20\x08\x29\x43\x8f\xf9\x1d\x32\x0a\x97\xca\x0a\x9c\x4f\x1e\x2b\x64\x86\xda\x6a\x8a\xa9\xca\x7a\x28\xb2\xa2\x82\x50\x58\x8a\x84\xe5\xfe\x66\x34\x5b\x42\xd0\xbc\xef\xd7\x98\x73\xe5\x54\x10\x71\x19\x38\xa2\xd8\x4d\x75\x14\x45\x27\x22\x35\x19\xa6\x15\x58\xcf\xb4\x1e\x92\x06\xaa\x80\x07\x56\x08\x10\x55\xae\xba\x8e\xc1\xfe\xc4\xd6\x3f\x55\x5e\xf3\xdd\x3a\xb4\x37\x1f\x57\x28\x1d\x15\x70\x2e\x1d\x1d\x30\x3a\xa8\x95\xef\xf5\x50\x01\x4f\x0c\x26\x89\x1f\x4a\xd7\x76\x69\x9b\x7d\x3e\xf7\x75\x55\xc0\x15\x60\xed\xfe\x49\x14\xcd\x0b\x54\x6a\xb0\x1c\xb8\xa6\xc2\x4d\x5e\xff\xa8\xab\xf6\xb6\xaf\x8b\xa8\x2a\x48\x42\x63\x1c\x50\xff\xe9\x05\x8a\xf2\x04\x45\x39\x05\x3b\x0c\xe7\x8b\x3b\x2d\x25\x34\xee\x80\x9a\x0d\x54\x6f\x22\x6f\xed\xc9\xcf\xac\xd0\x8e\x39\xf8\x2b\x60\xd6\xe8\x0e\x52\xa2\x63\x9b\x58\x7f\x7f\xb6\x02\xce\x53\x3e\x7c\x15\xa4\xd4\x48\xd2\x49\xbc\x67\xa7\xcb\xa9\x9f\x98\x93\x07\x4a\x63\x65\xbc\xb6\x47\x39\xa6\x80\x57\x81\x08\x02\x14\x0f\x72\x1c\xdc\xf7\xd9\x7f\x2f\x99\x5e\x17\xb7\xd0\x19\xf1\x40\x04\xa1\x35\x5b\x1a\x5f\xd7\xf7\xf2\xd2\x9f\xcd\xac\xb4\x9a\x06\xeb\xf6\xe1\x97\x42\x6e\xa3\x59\x0b\x18\x08\x6d\xd0\x51\xb3\xc0\xeb\xbf\x44\xc7\xa5\x02\x99\xd8\xfe\xcd\x2a\x53\x2f\x50\x37\x96\x6a\xd1\xdf\x81\x4c\xa9\x63\xf0\x7f\x17\x95\xc6\xb4\x73\xd6\x7c\x74\xf8\x28\x15\x28\x12\xc8\x21\xdb\x4c\xeb\xe1\x3f\x89\x4a\x9c\xae\x99\x36\xc7\x3f\xab\x68\xe0\x29\x61\xbf\x97\x63\xd6\x85\xc9\x2c\x56\x8c\xa2\x10\x8d\xb9\x14\x5a\x54\x99\xc0\x6c\xde\xdd\xa5\xd0\x63\x1f\x22\x50\x11\x45\x39\x45\x0b\x2e\x6c\xcd\x5f\xdf\x52\xe9\x02\x69\x15\xa8\x34\xa6\x03\xa4\xf5\xa6\xea\xc2\xc5\xf1\x8f\x6a\x61\x37\xd0\xb3\xa8\x50\x10\x0c\xba\xa7\x5b\xe4\xdd\xa7\x6b\x5f\x77\xc7\xf7\x77\x2b\x1a\x11\xb4\x2e\xd7\x94\xd4\x46\x05\x10\x08\xe4\x62\x79\x84\xc6\x8c\x37\xca\x00\xa8\x82\xb4\x07\xdf\x5b\x3b\x30\xb5\x53\x20\xed\xf6\xe8\xd1\xcf\x4f\x65\xde\xad\x64\xd0\x21\x12\x24\x3a\x02\xfb\xb1\x21\x31\x54\xe0\x3e\xb5\xd0\xfa\xcb\xb5\x6d\xa8\x45\xf6\xdb\x1e\xc2\xf2\xdd\x3b\xa0\x3d\xa3\xf3\x60\x6d\x98\x48\x61\xfa\xfe\x0c\x55\x5d\x16\x22\xdf\xc1\xf1\x04\x45\x33\x78\xec\x69\x53\x58\x77\x22\x44\xcc\x9b\xa3\x7d\x76\xc2\x2a\xed\xef\x22\xbf\xc0\xe4\xe5\x1b\x1e\x63\x25\xea\x90\xd5\x37\xa5\xa8\xf4\x0c\xd2\x42\x51\x42\x04\xc6\x8f\x6d\x5c\x83\x94\x5e\xee\x82\x9f\x4d\x7b\x7f\x5a\x10\x74\x58\xaf\xeb\x4a\xa9\xa2\x24\xb4\x92\x42\x58\x04\x7e\x47\x44\xde\xbd\xa8\x9b\x8d\x17\x0b\x51\x94\x70\x65\xf9\x04\x30\x99\xb9\x98\x18\x67\x1a\x18\xe1\x79\xb4\xec\xc7\xb8\xf9\xb0\xed\xad\xea\x63\x32\x92\xb2\x30\xb0\x50\xde\x41\x11\x66\x44\x99\x75\xf5\xbf\xfc\x99\x51\x18\xa9\x4e\x22\x7b\xbd\xdc\xdc\x21\xa7\xdf\x30\xb7\xa1\x28\x15\x16\x3e\xec\x66\xc6\xba\xae\x2f\x83\x99\x47\xa9\x26\x60\xdf\xdf\xb1\x12\x7f\x22\x6d\xae\x28\x0b\xe3\x58\xf7\x82\x34\x5a\x78\xb1\x0e\x45\x59\x64\xb0\xa7\xa6\xc9\x4e\xf0\x53\x64\xcd\xe2\x7c\xce\x3f\xc2\x2d\x68\x80\xd3\xe4\xe5\xb2\x38\x48\x1c\xb4\x0a\xfb\xe9\xf9\x68\x9d\x50\x66\x22\xe9\x71\x2e\xf6\xbc\x9b\x8f\xf5\xed\xe4\xad\x85\x89\xe5\x9d\xdb\x7a\x9d\xe0\xd6\xc5\x1b\x4d\x34\x1a\x42\x84\x20\x58\x29\xf4\x11\xf6\x3d\xfe\xda\xdf\x71\x44\x23\x2f\x0b\x31\xc7\x12\xd5\x0e\x90\x88\x30\x69\x43\xb9\x1b\xd7\x07\xdc\x9d\xcc\xa5\x70\x04\x45\x1a\xaa\x7e\x5b\x40\x3c\x54\x3e\x5f\x95\x55\x34\x4a\x42\xac\x47\x99\x2c\xcf\x37\x95\x63\xb8\x18\x0f\x89\x49\x82\x35\xc3\x1f\x87\xf5\xe3\x7a\xbf\x5e\xdc\x8f\x48\x5d\x15\x8d\x83\xc8\x3b\x93\x56\x6b\xb0\x47\x72\x29\x1a\xb3\x10\x63\x0c\x25\xf2\xfc\x79\x7b\x3f\xbb\xa1\xfa\xa1\x3a\xc2\x15\xd0\x64\x67\x0b\xc3\xeb\xae\x61\x80\xb8\x54\xb8\xb0\xdc\x1e\x56\xb1\xb3\xba\xc6\x09\x28\xca\x41\x24\xac\xd7\x17\x1b\xd9\x1d\x9a\x04\x34\xe8\x3a\xf6\xd7\x85\x29\xab\xd3\x35\x8e\x53\xd1\x24\xd4\x58\x00\x02\x51\xe5\x1f\x37\x42\xbd\xc2\x04\xcf\xac\x68\x22\xed\x62\xab\x1b\x61\xcc\xb8\x06\xa3\xa8\x4c\x2c\x1a\xa6\x9d\xe1\x43\xf2\x88\xf1\x25\x64\xa2\x50\x60\xe2\xbf\x97\xac\x3f\x53\x73\x01\x6e\x95\x37\x25\x76\x04\xd9\x2d\x68\x96\xba\xce\x9d\xa4\x02\xad\x5d\x5a\x67\xdd\xc0\x69\xe1\x1b\x92\x7f\xbb\xaa\x98\x2a\xaa\x18\x78\xd9\xd9\x75\x03\xc3\xca\xbe\xa2\x9a\x5a\xf1\x83\xdd\x09\x95\x6c\x3d\xf9\x7e\x77\x38\x0e\x81\x75\x15\x38\x84\x6a\x5f\xf5\x34\x2b\xaa\x8d\xa5\x06\xf0\x7b\xc2\x7a\xb9\xe9\xa4\x04\x15\x85\x48\xa2\x07\x89\x8c\xbb\x1b\x84\x71\x8e\xee\x72\x32\x3b\x41\x24\x56\x66\xcf\x12\x3d\x8e\x3f\xa6\x89\x20\xe6\x8e\xfa\xe7\x0d\xaa\x0f\x4f\x4c\x61\x0f\x33\x42\xec\x74\x72\x41\xe8\x1d\x4c\x56\x23\x23\x0c\x4c\x30\x10\x83\x29\xfb\xd6\x2f\xc5\x48\xc2\xcd\x90\x55\x79\x91\xe7\xd4\x1f\x0b\xb8\xc2\x0c\x59\x3b\xd7\x91\x7d\xba\xcf\xdf\x31\x4a\x35\x77\x2c\x56\x79\x0e\xc5\xb1\x9d\x39\xe3\x9f\xa5\x61\x1c\xda\xf8\xd4\x26\x15\x1e\xe1\x7d\x96\x5d\xff\x2f\x65\x30\x18\x8d\xc0\xb3\xdb\xb4\xdf\x7e\xae\x41\x4e\x31\x9a\x38\x7a\x59\x68\x6e\xe1\x58\x01\xcc\x61\x42\x5a\x77\xc6\x32\x29\x3c\x58\x61\xad\xe1\xc7\x67\x2c\x00\x39\x24\xe2\x85\x4a\x51\xf2\x75\x86\x8f\xb1\x10\x12\xd5\x0b\x07\xcf\x55\x10\x14\x63\x91\x44\x3e\xad\x4d\x75\x82\x65\xd7\x16\xa3\x18\xe3\x26\x12\x7d\x43\xc7\x52\xf8\xef\xce\x42\x9a\x86\xf6\xbb\x17\xf0\x7e\x07\x88\xf5\x9c\x84\xad\x2c\x94\x29\x4e\xf3\xfd\x66\xbf\xb8\xb7\x6d\xa5\xce\x6a\x1d\xba\x4e\x34\xc5\xe2\x58\x50\x2b\x23\xb7\xff\xbf\x55\xf7\x47\xa5\x52\xdf\x68\x51\x96\xf9\x77\xa8\xca\x91\xab\xc6\x62\x08\x22\x4f\xc1\x3c\xda\x27\x18\x77\xf9\x55\x69\x21\x06\xfe\x8a\x09\xd1\x48\x16\x23\xb4\x46\x1f\x71\x0c\xfc\x98\xbc\xb4\x24\x94\x7c\x40\x4d\xbd\x6b\x84\x7a\xb5\xa4\x3c\xc3\x94\xcf\xe4\x9c\x48\x63\xef\x88\x45\x15\x39\xf2\xda\x78\xb2\xc9\xb1\x24\x21\x68\x5b\x10\x41\x35\xa1\x09\x51\x2c\x51\x80\x90\x7b\x24\x92\xf7\x10\xa8\x19\x88\x8a\x62\x89\x0e\xc5\x40\x73\x73\x71\xcc\xf2\xac\x99\x2f\xc4\x2b\x96\x46\x2a\x75\x9e\xde\x4d\x96\xe7\x0f\xa5\x9e\x51\x44\x57\x4c\x72\x86\xfd\x4c\xb9\xa8\x2d\x74\xe6\x20\x82\xc4\xdf\x9a\xa2\x89\xb0\x42\x0e\x6f\x5e\xb4\xc4\x1f\x49\xa2\xd8\xeb\x4e\x5f\x53\x02\x4d\xfa\xc7\x12\x6f\x30\x99\x4e\x0d\x96\x9d\x95\xc8\xd5\x73\xf1\x20\xea\x57\xd0\x3f\xe0\x63\x25\xb0\x5e\xf0\xd9\x97\xd1\xc2\xa0\x65\x3b\x2c\x45\xae\x6e\xb3\x37\x7f\x13\x26\xb0\xa2\x8c\x97\xc2\xf3\x95\x63\x6d\xe9\xea\x19\x8d\x0a\x10\x12\x77\xbb\xfe\x7d\x7d\xbb\x7a\xbc\xed\xce\x57\x21\xe8\x91\x6c\x13\x4a\xff\x8c\x7e\x3c\x0c\x82\x18\xd7\xdf\xf9\x60\x03\xfc\xc3\x69\x8b\x72\x04\x4f\x79\xd9\xec\xc5\xaf\x39\xd5\x18\x15\x06\x71\x10\x59\xc1\x8a\x0a\x56\x5b\x07\x8d\x57\x21\x95\x91\xe7\xbb\xf3\x0e\xf5\x1d\xcc\xf7\x25\xa9\x90\x31\x86\x92\x59\x2a\x07\xe1\xad\x41\xc8\xc2\x04\xdb\x51\x2f\x45\xe7\x89\x5f\x15\xfe\xfc\xdb\x0e\x99\x94\xc6\x6d\x4f\xd3\xd1\x9f\xfc\x66\x48\xc1\x4b\x2f\xdd\xe5\xe2\xad\x0b\x5b\xc3\x10\x42\xac\xa9\x6e\x17\x8f\xb7\x9b\x87\xbb\xc5\x72\x3f\x34\x52\x61\x68\x34\xb5\xe8\xcf\x0f\x17\xce\xec\x4b\xdb\x5c\x33\x4a\x2a\x86\x11\x11\x80\x15\x9a\xcb\xe9\xf4\xe1\xaa\x20\xe3\xf2\x9c\x0a\x23\x95\xf8\xed\xa3\x17\xe2\x9f\xf5\xa1\x42\x4e\x02\x2c\xb8\xec\xa1\x6e\xd4\x18\xb7\xa2\x42\x2e\x53\xc4\x86\xc8\xea\x92\x43\x75\xfb\xd9\x6b\xe6\x46\x61\x65\xcb\x52\x6c\x6a\xb0\xbf\xe8\x2f\x92\x48\x5b\x3e\x13\x0e\xef\x0f\x7f\xca\x74\xe7\x4e\x4c\x53\x1a\x1b\xdf\xb0\x79\x29\x30\x89\xe9\x97\x7c\x28\x48\x82\xf6\xbe\x80\xf7\x27\xa8\x7c\xe6\x7c\x92\xd3\xf7\x79\xe3\xb0\xfb\x9e\x22\x14\x81\xe7\x65\x1d\x90\x92\xaa\x50\x92\xc0\xa7\x50\xf6\x99\x7a\x85\xa6\xde\x97\xb7\xed\x2b\xbd\xc6\x71\x25\xfe\x14\x1a\xe2\x76\xb9\xb8\x5f\x1e\x96\x9b\xc7\xfd\x76\xb1\xdc\x1f\x16\xb7\xb7\xdb\xd5\x6e\xd7\x5d\x56\xa7\x58\xcc\x6c\x5e\xaa\xf2\x7d\x6d\x76\x18\x5b\xd4\x28\x9e\xd1\x5a\xa7\x85\x69\x00\x93\x5d\x78\x3f\xdd\xc3\x29\x62\x55\xf2\x0e\xe2\xd8\x1b\x8c\x50\x53\x62\x1c\xc0\xec\xa1\x2c\xda\xb5\xba\x91\xff\xf1\xe0\x98\x39\x97\x3b\xd4\x9c\xa0\xb5\x5f\x6e\xee\x37\xdb\xc3\xb7\xcd\xfd\x6d\x77\x2d\x19\x63\xfd\x6f\x77\x05\xcb\x9d\xff\x18\x11\x09\xe3\x28\xf2\x0e\xd4\x98\xc1\x47\x45\x01\x95\x98\x24\x3d\x97\x75\x9f\xb1\xe8\x26\xe5\xf8\x42\x41\xa4\x91\x64\xcb\x21\x32\x7c\xc2\x61\x97\xfd\x0f\xba\xcb\xc9\x14\x9b\x9e\x6c\x47\xb0\x4d\x38\xf8\x2f\xda\xeb\xa4\xfd\x2b\xfa\xf7\x8c\x3e\xb9\x8a\x02\x2d\xc0\x5c\x53\x20\x59\x75\x29\xff\x13\x94\x19\xee\x00\x9d\xcd\xb5\xd1\xf5\x83\x22\x85\xd0\xc7\xc5\xe9\x24\xa7\xec\x67\x83\x89\x10\x51\x69\xd1\x69\x58\x9d\x6f\xbc\x92\xf8\x0c\x53\xc6\xe4\xf2\x4a\x61\x57\x64\x56\xa8\xa7\xea\x73\x76\x51\x15\x51\x43\x91\x4d\xe3\xb6\x3c\x6e\x85\xf2\xc2\x13\xfe\x51\x18\x4f\xa4\x0b\xbc\x7c\xe1\xd5\xd1\x0d\x8c\x7b\x08\x54\xc4\x52\x11\x0a\x9f\xef\xab\x9b\xf6\xed\x4e\x1c\xbc\x88\xa9\x84\xba\x68\xd1\x26\x08\xea\x21\x50\x54\x45\xcc\xa4\x88\x66\x5a\xdc\x3e\xac\x1f\x0f\x8b\xfb\xfb\xcd\xcf\xc5\xa3\xe7\xd2\x6c\x0f\x03\x6e\xe6\x87\x6e\xb1\x7b\xa0\xdc\xf0\xc9\x02\xea\xdf\x5c\x98\x18\x74\x75\x1c\xa4\xb8\x92\x59\x33\xb3\xc3\x46\x91\xb2\x10\x0f\x79\xf9\x40\x5c\xd8\xb4\x86\xe7\x87\x81\x40\xef\xc7\xa2\x04\x2d\x09\xef\x18\x3a\xad\xa2\x98\x12\x44\x52\xfc\x7d\x79\xf7\x16\x7c\x41\x75\xe8\xef\x30\x66\x71\xd4\xa3\x34\xe5\x84\x4d\x4c\x45\x3c\x61\xb4\x0f\x2c\x90\x3f\xc4\x27\xd9\x6f\xae\xfa\xf6\xfd\x39\x46\x60\x4a\x71\x6d\xf1\x7d\xb3\x19\xba\x28\x09\x23\x4b\xf5\x27\x6a\x64\xbb\x1e\xd5\xb7\x7c\x79\x22\x4a\xc0\x22\x98\xee\x3a\xc2\x3f\xcf\xad\x81\x3a\x7c\x03\x0b\x17\x25\xad\x49\x1d\xb0\xf9\xcd\x17\x4f\x27\x53\x2f\x0d\x02\x97\xa2\xb0\x93\x7a\xff\x71\x76\x7d\x0b\x5d\x2b\xe0\xf8\x86\x04\x09\x22\xcb\x6f\xfb\x46\xa3\x78\xde\x1b\x89\x84\x0c\x10\xde\x75\xb0\x1d\xbc\x1b\xec\xf6\x1f\x3f\xbe\x8c\xb8\x88\xbb\x6f\x39\xf0\x24\xa7\xe3\xe2\xc8\x76\x8c\x97\xc7\x47\xb8\x9c\x44\xf5\x5a\xdf\x5c\xaa\xe2\xba\x0f\x7a\x72\x0b\x12\x12\xb0\x08\xe1\xe2\x52\x2b\x91\x67\x6a\xe2\xb5\x44\x8a\x58\x0a\x6f\x91\xe7\xed\x6b\xbc\xcd\x6a\x75\xd5\x1a\xaf\x22\x9d\xd2\xb0\x13\xce\x18\x7a\xc8\xee\x38\x50\xa5\x60\xa0\x14\x32\xc0\xab\x0c\xb8\x21\xe6\xb5\x99\x55\x04\x32\xc1\x1c\xa2\x4b\x75\x7f\xbf\x14\x4d\x47\x70\xe9\x86\x18\x21\x10\x7a\xfe\x54\x95\x03\x11\x92\xee\xa8\x62\x5e\x7a\xc7\x26\xa1\xd7\xba\xee\x8f\x25\xce\xa7\x86\x36\xd0\xed\xa0\xcc\x2a\x26\x81\x85\xef\x1f\xb2\xda\xea\x26\xfa\xbf\x27\x10\xf0\x0e\xc3\x8d\xf2\x60\xb6\x1f\x64\x39\xb7\x83\xf8\x93\xa4\x64\x71\xdf\xe1\xf5\xad\x2a\x2f\xe7\xbb\xaa\x3c\xcd\x41\x83\xfd\x12\x89\x09\x24\x54\x0d\x05\x56\x2c\x4b\xf8\x5f\x8a\x2b\xe3\x80\x8a\x44\xfb\x60\xc1\x96\x23\xfc\xeb\x8a\x29\x03\x8c\x8d\x5f\x44\xfd\xb2\x2f\x77\x83\x4e\x74\x37\x80\xd1\x18\x23\xb4\x87\xc7\xbf\x58\x6f\x8b\x59\xca\xb9\x18\x65\xd8\xda\xc7\x6b\xd7\x58\x31\x55\x38\x51\x31\xd3\x96\xc6\xa9\xc4\x5d\xad\x6b\x0e\xf3\xeb\xda\x5b\xc6\x98\x69\xa1\xe3\x1e\xf1\x75\x73\xf9\x80\x6a\xdc\x13\xe8\x06\x46\x41\x9c\x62\x52\xbd\x8d\x79\x42\x8f\x4d\xf7\x8f\x1b\x49\x26\x1c\x88\xe4\xd0\x80\x38\x1d\x84\xf5\x18\xbb\x4f\x1d\x01\x38\xc0\x4d\x75\xcc\x8a\xa5\xc8\xf3\x4d\x71\x03\x2f\x22\x37\x1b\xb3\x05\x85\xfd\x55\x57\xcd\x5d\x73\x95\xf6\x38\x32\x09\xc2\xc8\x0e\x6e\xb2\xce\x14\xaa\xe2\xb8\x0d\x6e\x3d\x01\x75\x9e\xcf\x0d\xe1\x4c\x21\x2b\x49\x79\xb6\xc1\xd6\x1c\xa5\xd6\xdf\xa6\x44\xbf\x2a\xe6\xb1\x4d\x6f\xaf\x4e\x52\xd4\xf5\xc7\x27\x73\x91\x0b\x83\x75\x21\x9f\x19\xe9\x88\x40\xc6\x15\x84\x38\x89\x28\x56\xa8\xc7\x94\x29\x2a\x4e\x38\x43\xe0\x8b\x84\x66\x53\xfc\x36\xf8\x0a\x49\x02\xd8\xad\x9c\x97\xc7\x29\xc8\x73\xfc\x78\x82\x28\xb4\x6b\xae\x2d\x12\xc4\x69\xe7\x27\xb6\xbf\x96\x60\x06\xc9\x3b\x1b\xeb\x87\x6e\xde\x8b\x76\x2f\xb9\x2e\x45\xc6\x92\x53\xec\xac\x93\xa8\x70\x22\x26\xa6\x29\x56\x21\x61\xce\x31\x78\xf8\x40\x89\x5a\x7c\xdd\xe3\xf9\xa8\x89\xd6\x2e\xb3\x7e\x9f\x1d\x5f\x50\xe7\x75\x52\xbd\xb9\xfa\xee\x73\xd4\x0d\xfd\x05\x03\x5b\x30\xb7\xd5\x51\x6c\x87\xcc\x20\xef\x21\x44\xde\x15\x8f\x35\x98\xc0\x52\xf2\xaa\x4c\xf7\x0b\x14\x18\xc3\xc6\xd5\x87\xc5\x1f\x16\x26\x77\xfb\xbc\x5d\xec\xd7\x9e\x07\x40\xc5\x60\x22\x11\xf5\x6a\xeb\xbe\x7e\x27\xf2\x09\x74\xcb\x0d\x37\x61\x8c\x8d\xdb\xad\x63\x0f\xc3\x8d\x66\x2e\x57\x35\x96\x53\x57\xb1\x49\xc3\xd8\x2a\xa6\x9c\xb2\x09\xbc\x26\x36\x42\xe3\x0e\x72\x5f\x1e\x8f\xa0\x9d\x3e\xd4\x17\xd6\x62\xd2\x7e\xa2\x38\x21\x1a\x89\x9f\x6d\x2a\xcd\xea\x39\xdf\x43\xa1\xe1\x8a\xf3\x6c\x16\x28\xcc\xe8\xbf\xf8\x90\x66\x66\x12\xba\x72\x22\x43\xc4\x92\xbc\x65\xf0\xbe\x85\xf3\xa5\x99\xc9\x16\x73\x4a\x25\xb5\xa9\x31\x6c\x2c\xf2\x9d\xdc\xb6\x0e\x50\xf9\xe4\x3e\xa7\x2a\x40\x9f\x1a\x2b\xda\x37\xa2\x9e\x2c\x5a\xce\x22\x40\xb2\xfd\x37\xa8\x32\xd3\x9d\xc5\xe2\xc4\xd8\xae\x8d\xf2\x0c\xc5\x94\x01\x41\x71\xa6\x92\x18\x86\x0d\x5f\xb6\xfb\x65\x7c\x87\x0c\x14\x21\xdd\x82\xf1\xe1\xec\xe4\x4a\x61\xa0\x30\xf1\x74\x12\xaf\x36\x1f\xe0\xff\x9e\x5a\xef\xec\x71\xbf\xec\xfe\xa4\xad\x0c\xbf\x6f\xb7\xc5\xf6\xbe\xf1\x2e\xe4\x47\x9a\x08\x0b\x42\x6b\xf8\x05\xea\xfb\x45\xda\xbe\xe3\xa9\x73\xca\x23\xa6\x2c\x9b\xc5\xe2\x61\x75\x58\x6c\x7f\xf8\x1f\x8a\x62\x85\x19\x69\xfb\x79\xb1\xf7\x6b\x36\xcc\xe0\x51\x1a\x23\xce\x16\xf1\xb7\xe5\x08\x47\xc3\xe3\x88\x04\xc2\xed\xd1\xaa\x0c\x90\x1d\xac\x3b\x16\x27\xf8\xd0\xff\xc9\x8a\x63\x0e\xf5\xa6\xb8\x46\x4d\x70\x4e\x62\xa2\xa7\x1c\x4f\xdf\xcb\x13\xac\x7e\xb9\xae\x6d\x3f\x90\xaa\x44\xf6\x5c\x86\x93\x67\xe4\x2c\x40\x46\xaa\x6f\x03\xc0\x0e\x4f\x64\xc8\xc8\xe0\x4d\xa2\x97\xfa\x65\x14\xc9\x53\x6a\xb9\x31\x5e\x44\x7d\x03\x50\x38\x4a\x0b\x7f\xc1\x34\x0c\x12\xe6\x8a\x5e\xb5\xb9\xa8\xd7\x6e\x26\xa5\x2a\xc1\x08\x68\x7f\x33\xbc\x01\x01\x29\x06\xc4\x67\x1b\x52\x3f\x88\x5f\x23\x26\xf9\xf1\x23\x48\x9e\xc8\x60\x2a\x69\x7d\x2d\xb2\xa6\xb8\x4c\x15\x96\xbc\x9d\x14\x9a\xf4\xf1\x37\x97\x22\xc6\xba\xbd\x70\x84\x89\x50\x2f\x2f\xcd\xe6\xd2\x94\x26\xf0\x72\x75\x8a\xab\xc0\xaa\xb2\xb6\x0e\x97\x68\xb7\xc1\x9b\xc9\x17\x51\xa1\x15\xd2\xd2\xe5\x6d\x56\xf7\xb0\x2c\xae\x24\x45\x53\xf3\x54\xee\x46\x33\x40\x13\x8e\x0e\xa4\x77\xb8\xee\xac\xd4\xd8\xc8\xcb\xe4\x9a\x4a\x44\x13\xe2\xe7\xdd\xa8\xaa\x4f\xbf\x70\x1d\x47\x81\x0b\x60\xee\x4b\xf5\xba\xd3\x1e\x51\xcb\x81\x58\x8e\x42\x55\x16\x6f\x50\x8d\x13\x13\x9f\xe2\x1c\x86\xe6\x91\x43\x68\x1b\x65\xf1\xed\x67\x85\x23\x82\x77\x07\x4d\x20\x92\x64\x80\xaf\x6d\x37\x72\xab\x53\x25\x3e\x09\x74\xb9\xe1\x69\xe4\x0b\x6e\x0f\xf0\x20\x3e\x64\x37\xd9\x8d\x12\x30\x90\x01\x44\xe5\xc6\xd1\xc9\x09\x21\xda\x38\x38\x36\x7a\x4b\xf2\x43\x4c\x12\x75\xa3\xef\x9c\x04\x49\x9c\x58\x4e\xe2\xaa\x40\x4d\x49\x5f\x08\x1b\x5f\x96\xb2\x10\x61\xd9\x87\x4b\x81\x8d\xd9\xbf\xf9\xbf\x6b\x82\xbb\xb4\xf3\x76\xba\x82\xd4\xb0\x0b\xd8\x0d\x65\x71\x84\x3d\xd0\x3b\x28\x46\xed\xd3\x2a\x09\xa3\x04\x0b\xe3\x7d\xdf\x98\x3f\x12\x13\xc0\xbc\xbb\xd7\x3f\x18\x44\x72\x49\x4c\x09\x75\x08\xf9\x47\x71\x82\xfd\x62\x73\x5f\x96\xaf\x97\xf3\x6c\x20\x99\xc4\x82\xfb\xfd\xd2\xd6\xf3\xca\x5c\xcf\x38\x5e\x09\xe7\x29\xf1\x19\x30\x04\xfc\x97\x97\x66\x90\x5a\xf5\xa3\x52\xab\xb9\x65\x97\xd1\xe1\x1c\x4c\xaf\xd2\xda\x25\x7b\x95\xf6\xac\xa5\x38\x4f\x2e\x90\x10\x89\x98\xe8\x9d\xa5\x61\xb3\x4f\x67\x01\x0b\xe3\x2b\x25\x54\x63\x46\xae\x7c\x2f\xa0\xfa\x2e\xea\x97\xce\x50\x24\x09\x00\x22\x5b\x4b\x04\x98\x7b\x7c\xf9\x84\xda\x4f\x25\x69\x20\x91\xf7\xf6\xa1\xac\x61\x54\x0e\x4c\x52\xaa\x3c\x2f\xfc\xe5\x7c\x68\x46\x87\x84\x31\x71\x07\x55\xb5\x8a\xca\x96\xae\xe9\x2a\x3b\x9c\xa4\x86\x61\x48\xbd\xd9\xfe\xdf\xe8\xf2\x42\x08\xee\x89\xb3\x64\x6b\x98\x8a\x8b\xc8\x57\x93\x24\xa5\x1f\xab\x19\x5a\x71\xfb\x42\x11\xe6\x03\xcd\xa0\x66\x3b\x1f\xe3\x24\x32\x14\x29\xf1\xb4\x9a\xb7\x17\xab\x83\x04\xd8\x0d\xb7\xfe\x93\xd8\x37\x91\xae\xc1\xd0\xcd\x97\xa6\x5c\xd4\x2a\xcb\x76\xb8\xb2\x27\xaf\x50\x51\x83\xfb\xc7\x22\x3f\xbf\x08\x5b\x61\x6f\x7d\x56\xdb\x71\xe5\x12\xd3\x57\x2e\x88\x3f\x57\x6b\xac\x97\x2e\xb6\xcb\xc5\xed\x7a\xe1\x5f\x8e\x0e\x3b\x3a\x74\x34\x18\x96\x0e\xa7\xbe\xae\x1b\x24\x5a\x00\xae\xd0\x45\x9e\x2f\x4e\x50\x65\x4a\x8c\x96\x88\x61\xa2\x03\x14\xa0\xcc\x69\x77\x20\x0e\xd0\xaf\xf8\xe3\x8f\x3f\xba\x3f\x29\x4b\x88\xff\x23\x6b\x9a\x8f\x81\x1a\x9a\x4a\x49\xcc\xa9\xc3\x4c\x59\xa9\x40\x04\xc4\x8e\x5b\xb1\xfd\xc7\x4a\x49\x9c\xe0\x8c\xb2\x64\xed\x5d\xd1\x66\x12\xc4\xfb\xc1\xa9\x05\x78\x5a\x3d\xa6\x4a\x74\x36\x39\x0d\xa8\x13\xb4\xc7\x3a\x9d\xed\xb2\x9c\x99\x5f\x69\x10\xa6\x38\xbf\x30\x4d\xe4\xed\xd3\x94\xe7\x6d\xd6\x94\xa6\x81\xa0\x3c\x1c\x23\x66\xec\x14\x9d\xb0\x82\x8f\x3e\x59\x1a\x00\x61\x9d\x84\x14\x36\x0c\xce\x67\x71\xd3\x50\x6b\xdc\x55\xac\xc3\xf7\xfd\x72\x12\xc5\x98\x6d\x6b\x7c\xdd\x28\xd5\xa9\x0b\x91\x1f\x3a\xc2\xe6\xee\x31\xe3\x20\x8e\x9d\xb2\xc6\xd3\xfa\x00\x3a\x6b\x26\x20\x96\x34\x8e\xb5\x95\x1f\xcd\x8a\x66\x5f\xee\x9a\x49\x16\x2e\xe5\x24\xc1\x62\xd1\x93\x50\x37\xa2\xc3\x92\xa5\x3c\x4e\xd0\x50\xda\x4a\xea\xb5\x9e\xbd\x4a\x39\x0f\x91\x29\x5c\x3b\xbf\x72\x46\xcb\x44\xa5\x89\xe1\xc1\xa8\xa9\xad\x97\x42\x54\x69\xca\x42\x9b\xa7\x43\x37\xef\x80\x24\xc9\xfd\x31\x8e\x70\x20\x0c\xf6\xeb\x43\x0d\x6d\x14\x3e\x40\x87\xa4\x69\x1c\xe1\x86\x77\x2c\x73\x3d\x01\x62\xa4\x69\x62\x49\x8c\x90\x97\x1a\xd7\xdb\x24\xc0\xb9\x46\x53\xa4\xd2\x08\x8c\x2e\xc1\x79\x77\x08\x1e\xc8\xc5\xd1\x5f\x53\x85\x1c\xbf\x6f\xde\x6e\x4f\x4f\xad\x27\xd8\x53\x51\xa9\x54\x25\x9a\xa5\x6e\xfb\xed\xff\xaa\x85\x8c\x9c\x20\xb6\xee\x59\x16\x55\xaa\x55\x4c\x1c\xee\x08\x13\xec\xfb\xec\x13\xad\x6c\x95\x42\xc4\xb4\xf1\x8a\xc6\xbf\x9c\xea\x40\x25\x26\x9e\x74\x0a\x1a\xe2\xa8\xcf\xa5\x42\xd5\x7c\xdc\x80\x2a\x4f\xbe\x13\x68\x98\x68\x4c\x4d\xa2\x30\x7b\x75\xc8\x6a\xa7\x7e\xa9\x9f\x44\xff\x59\x8c\x01\xe2\x4a\x60\x8e\xbc\x27\xf3\x5d\x5f\x4a\x90\x98\x22\x71\x22\xe2\xb3\x6d\xa3\x86\xe3\x74\x70\x03\x02\x62\x69\xe4\x7a\x62\x97\x2f\xad\xb1\x08\x68\x8a\xe2\x31\xc6\x49\x04\xdc\x42\xad\xaa\xec\x3c\xc8\xc4\x88\x20\x56\x3e\x1a\xef\xd0\x4f\x5f\x5f\x94\x86\x11\x95\xfd\x56\x2b\xc7\x6f\x4b\x50\x6d\xbd\xdf\x1a\x8a\xa6\x81\xfe\xe1\x28\x18\x84\x34\xdd\x96\xaa\x28\x1b\xe1\xdc\xba\x79\x27\x48\xb0\x30\x46\x6f\x14\x95\xc6\xbb\xbe\x2e\x7f\x29\x16\x87\x58\x30\xb0\xab\x7c\xc8\x50\x97\x4c\xe1\x88\xff\x0a\xff\xed\x4f\x92\x91\x10\x1d\xcc\xb7\x99\x66\x2d\x44\x98\x46\x86\xf4\x34\x0e\x9d\x28\xe2\xf8\xe1\x23\x4d\x22\xde\x23\xe9\xac\xdb\xf4\x7b\x30\xef\x38\x8a\x48\x53\x74\x65\xcf\xb9\xf8\xd8\xe5\x65\xf7\x2e\x22\x88\xed\xca\xad\x2e\xc7\x09\x14\x40\xc4\xa1\x85\x62\xb4\xf7\x09\x8d\xb8\x0a\x4f\x45\x9c\x0a\x0c\x5f\x97\xff\x5c\xde\xaf\x0e\xcb\xc5\x93\xbf\x6a\xac\x43\x6c\xcc\xbd\xc7\x64\xcf\x95\xc7\x25\x78\x6c\xd5\x51\xdb\xd9\xf5\x20\x7e\x8d\x70\x72\x82\x2b\xdb\xa2\xf7\xf0\xbc\xdb\xcf\x62\x67\xbe\xe8\xac\x6e\xcf\xd6\xa8\xec\x7c\x3e\x96\xc8\xaa\x98\x7f\xb8\xef\xfb\x7b\xdf\x6c\xa9\x44\x12\x47\x18\xe3\x8a\x9d\xab\x4a\x54\x1d\xf0\xc2\xaf\x1f\x91\x26\x96\x31\xb7\xdd\xf7\x1a\x38\x7b\x8c\xb9\xdf\x17\x45\x2a\x25\x0a\x38\xdd\x2d\x96\xfb\xcd\xf6\x10\xf8\xbf\x0b\x1e\x7b\x19\xf4\x61\xe7\xa0\x10\x69\x8c\x6f\xeb\xbd\x4f\x70\xef\x5f\x2a\x80\xf6\xe2\x7e\x8c\x0a\x14\xfa\x6d\xb7\x95\x38\x96\xc5\x8f\x19\xe2\xef\xd9\x4c\xc7\xb5\x2a\x49\xe0\xe1\x9b\x41\x67\xfb\x84\x66\xb6\x1f\x7f\xff\x02\x77\x39\x66\x77\xbf\xe6\x37\x55\x42\x27\x16\x65\xbe\x85\xa2\xd9\x18\xd3\xe3\x11\x05\x90\x04\xbc\xe4\xe6\xc8\x63\x17\x10\x86\xe8\x93\x5c\x8a\xfa\x22\xdb\x45\x2e\xfb\x93\x12\x85\x74\xa9\x8d\x78\x85\x87\xb2\x00\xff\xc9\x25\x61\x2c\x75\xcd\x96\x0f\x59\xd1\x89\x65\xb4\x07\x2c\x7d\xa2\x97\xd1\x1d\x4f\x40\x49\x04\x17\xba\xdb\x35\x11\x98\x61\xed\xc6\x68\xba\x49\x02\x36\x4f\x71\x40\xf8\xcb\x37\x28\x26\xcc\x52\x4a\x06\x31\xb3\x9e\x88\x93\x8c\x3f\x8f\x28\xf7\xfe\x36\x97\xb4\xf2\x67\x26\x24\x74\xb7\xb0\x15\x0d\x2c\xac\x99\xb7\x50\xc9\x19\xee\xc6\xf9\x59\x2b\x03\x19\x5b\x38\x7e\x25\xb3\x06\x2a\xcb\xa1\x31\xc4\xd5\xca\x40\x49\xe1\xe4\x27\xfe\x71\x29\x3b\x1c\xac\xa4\x29\x43\xd0\x44\xbb\xe3\x5e\xce\x9f\x72\x23\x8c\x5f\x08\x15\x0a\x2d\xe0\xe1\x5c\x01\xba\x4e\xa2\xe9\xcd\xcc\xac\x01\x91\x54\x09\x6c\xdf\xb3\x96\x6e\x36\x90\x92\x8c\x10\x44\x5e\x1c\x7c\x33\x94\xbf\x49\x16\x5b\x8a\x7d\x79\xf9\x58\x8a\x5c\x2d\x3e\xd3\x86\xfd\xf4\xdf\x3e\x29\x28\x99\x60\x9d\x0c\x99\xaf\xa4\xcf\x99\x51\x19\x49\x65\x19\x61\x1b\x51\x35\x48\xe3\xe7\x31\x7e\x32\x52\x80\xdb\x5b\x2d\xde\x60\x5f\x2e\x7f\x76\x7f\xd7\x21\x7e\x4c\x5d\xae\x7e\xd9\x4d\x65\x32\x4f\x62\x46\x6d\x53\x62\x31\x4a\x02\xf9\x25\x26\x79\x60\xc9\x90\xa5\xe7\x52\xff\x3e\x53\x92\x93\x3c\x22\xd8\xff\xbd\x5d\xdd\x3d\x3f\xde\x1e\x6e\xd7\xbf\xaf\x77\xeb\xcd\xe3\xa0\xa7\x5a\xc9\x84\xc4\x58\x97\x70\x0c\x93\x0e\x13\xdb\x1f\xd5\x5e\x7b\xdd\x95\xf0\xef\x8e\x6a\xb0\x6e\x92\xd4\xa2\x2a\xee\x57\xdf\x16\xf7\x87\xd5\x1f\x4f\xab\xc7\xdd\x6a\x87\xd8\x8b\x6e\x88\x0c\x70\x05\x3f\xc2\xfb\x77\xa7\x50\x33\x7e\xd6\x94\x72\xe1\x44\x10\x1d\x8f\x7d\xcf\x3d\x60\xcb\x0b\x93\xc9\x35\x82\x8e\x4f\x12\xb1\xfe\x05\xa5\x61\xe0\x29\x52\xbe\x61\x1f\xce\x27\x4c\x4d\x93\x09\x9b\x86\xda\x02\x14\x6d\xc3\xf2\x27\xa3\x54\x20\xb1\xa1\xd5\x3b\xda\x94\xa1\xd1\x78\xf8\xb4\x77\x45\x2a\x13\x62\xe9\x4d\xe5\x20\xaa\xdd\xe5\xe4\xad\x98\xd4\x24\xb6\x7b\xf4\xe5\xdc\x6e\x0e\x50\xd5\x0f\xd3\x40\x5d\x6a\xca\x91\x90\xc0\xa3\x26\xf7\xa5\x4d\x95\x8e\x7f\x02\x88\xc1\x6d\xe2\x66\xeb\xb1\x25\x12\xda\xf0\xd7\x2e\x87\x7d\xe6\x32\x92\xe3\x6a\xb1\xb7\x2e\x86\x05\x2c\x18\x53\xe5\xde\x88\xe2\x75\x7e\xf9\x19\x37\x39\x77\x2a\x03\x44\x47\xf5\x01\xb7\x22\x81\xad\xb2\x1e\xc1\xb5\x52\x83\x47\xb5\x8c\x82\x6d\x15\x90\x40\x8a\x09\x07\xfc\xd0\x57\x1b\x3d\x9b\x0a\x02\x1a\x5a\xaa\x76\x3d\x12\x12\xfb\xd3\xf5\x3c\x78\x46\x15\x44\x96\x5a\xb4\x0d\xaf\x5f\x47\x2f\x63\xcc\xa9\xdb\x8d\x57\x2a\x95\x5d\xe1\xbb\xb5\x7b\x88\xa4\x3e\xe7\x30\x5d\x8e\x8a\x06\x96\x07\xf5\xbd\x23\xe5\x6a\x63\x73\xff\x4e\x68\x2a\x20\xe9\x68\xf3\xba\xcc\x68\x39\x89\x9d\x14\x15\xb1\x65\xbc\x15\xc5\xeb\xc5\x75\x6c\xfb\x6b\xb0\x10\x10\xf4\xef\xbc\xb0\x9e\x6f\x60\xf4\x69\x14\x8b\x2d\xb4\xa0\x02\x73\xa9\xaf\x04\x36\x94\x0a\x79\x42\x58\x5f\xcc\xb7\x1c\xe9\x08\xa3\x9e\x5c\x28\x14\x91\x6f\xc2\xbb\x05\xd0\x7d\xb1\x5a\x85\x1a\x94\xfb\x89\xf2\x2a\xf7\xa7\xa2\x88\x20\xa0\x60\x69\x09\x2a\x97\x0f\xf3\x0b\x42\x45\x32\x12\xba\x6b\xe6\xea\xe8\xdf\x26\x57\x8b\x89\x8c\x2d\x2d\xcc\xba\xc8\x3a\xea\x28\xa5\xe2\x30\x31\xf1\x34\x99\xbe\x2f\x9d\x0d\xb3\xec\x90\xdd\x58\x69\x1b\x0b\x4c\x96\xe7\xfb\x17\xc8\xaa\x11\x8c\xc9\x0d\xe2\x2c\xc6\x3e\x23\x0b\x8b\xf4\x46\x79\xa8\x2b\x39\xb9\xff\x84\x5a\x3f\xf7\x08\x8d\xa9\xca\x53\x7d\xf9\x54\x36\xc0\x9f\xc0\xac\xd4\x20\xd6\x00\xb7\x99\x7a\x5d\x14\xfa\xa1\xac\xbc\xa8\x8b\x52\x49\xca\xb1\x5f\xe6\xbe\xb4\xa8\xa2\xd6\xfd\x77\xdd\xc5\x28\x75\xf6\x49\x96\xe1\x93\x9f\x4b\xa5\xd5\x4e\xc8\xea\xb5\x2a\xef\x44\x96\xf7\x2f\x4f\x84\x24\x24\xbe\x7b\x7a\x29\xce\x5b\x10\xea\x65\x70\x38\xb1\xa9\x8e\x73\x6b\x04\x6e\x3b\xb0\xec\xa1\xdd\x46\xe7\x7f\x4b\xd1\x04\x1b\x42\x6f\x9e\xb7\x8f\x13\xd8\x9d\x52\x2a\x46\x94\xe8\x7d\xf9\x06\x37\x59\xb7\x53\x2b\x20\x56\x56\x1f\x51\x0d\x1e\x86\x58\x79\x52\xed\x97\xec\x3c\x6f\x7a\x15\xd0\x18\x01\x95\x1d\x32\x7e\x51\xd4\xef\x53\x2e\x01\x3f\x16\x04\x7a\xff\xca\x1b\x98\x91\xff\xaf\x4c\x24\x30\x67\x6e\x1b\x15\xb2\xa2\x27\xed\x55\xca\xc4\xb6\x2b\xa0\x00\xab\x5c\x58\x4f\x1d\x1e\x3f\x2e\xa1\x88\x62\x06\xcb\xbf\xb1\x31\x4f\xd5\x40\x00\x41\x69\x22\x38\x86\x36\xdb\xf5\x18\x64\xaa\x03\xc2\x3b\x09\x63\xdf\x07\x31\xee\xef\x98\xff\xb0\x3a\x60\x0c\x03\xe2\x4d\xbb\x4d\x2e\xcb\xac\x70\x61\xc7\x62\x58\xf5\xec\xc6\xea\x38\xf2\x20\x74\x9f\xb3\x72\xf5\xc4\xd1\x73\xe8\x20\xb4\x32\x7f\x0d\x88\x93\xab\xc8\x3c\x0d\xf4\x24\x95\xa6\x61\x88\xc5\xbf\x1c\xf3\xdb\x5e\x3b\xe0\x49\x54\x0d\x9d\xfc\x28\x23\xdc\xb2\x3d\xd8\xae\xf6\x2d\xa0\x26\x74\xfe\x75\x96\x4c\xb3\x88\x31\xe5\x6a\x00\xf3\xd5\x39\x1d\x06\x11\xa1\x8e\xea\x26\xab\x40\x3f\x88\xff\x94\x55\xd6\x7c\x8c\xd1\xdc\x3a\x0c\xac\x38\x64\xd9\xc6\x11\x59\x2f\x08\xe2\x0f\x47\x96\x96\x2d\xb3\x79\x68\xdf\x67\x05\xfa\xe6\x63\xf7\x71\x92\x65\x3e\xca\x77\xe9\x90\x83\x97\xc8\x28\xca\x77\x25\x2a\x3d\x20\xa3\x53\x3a\x0a\x04\xa2\x37\x0f\xb5\xed\xdc\xcd\xf3\xec\xd8\xee\x89\x98\x46\x0f\xe2\xc9\xab\x89\x12\x16\xb3\x8e\x82\x7c\x89\xa0\xca\x1c\xf4\x37\xe1\xf2\x35\x1d\xb5\x9a\xdf\x58\x74\x0c\x0c\x13\x41\xc7\xec\x0d\x10\xd1\xee\xaa\xdb\xdd\x61\x85\x28\x88\xef\xab\xfb\xfb\x8d\xff\x23\x67\x36\xe6\xf4\xee\x82\xfb\x9e\x7f\xad\x61\x56\x73\x9e\xe8\x8e\x60\xb3\xd2\xf5\x97\xfe\x92\xe6\x29\xc5\x52\x4f\x01\xbf\x9a\xae\x63\x68\xda\xfe\xaf\x13\x66\x09\x40\xda\x6b\x2e\xbf\xdb\xbc\x22\x4d\xc6\x2f\x3a\x51\xa9\xb6\x39\xe4\x32\xd7\xd7\x5d\x6d\x3a\xa5\x69\xea\x24\xed\x3f\x0a\xd5\xfd\x95\x59\xed\xed\x5d\x76\x3a\xf7\xab\x2e\xd5\x22\xf4\x69\xcc\x3f\x4d\xe3\x4f\x9e\x3f\x35\xa1\x55\xf9\xf0\xe9\xd6\x49\x9a\x76\x74\xd3\x22\xd4\x08\xba\xaf\x5f\xca\x77\xf4\x97\x86\xad\x45\x5a\x52\x45\x42\x6f\xf2\xbd\xf8\x94\x3f\xa8\x35\xc1\x15\x77\x16\x1f\xeb\xce\x2a\x00\xb5\xcd\xc0\x87\xd6\x24\xf7\x40\xab\x09\xc2\x23\xf9\xdb\xe5\x5a\x72\xb2\x3d\xd9\xd6\x4b\x8e\x7d\xf2\x96\xb2\xee\xca\x71\xc2\x02\x5f\x53\x1a\xd6\x15\x47\xdc\x1e\xbd\x5b\x3d\xb9\x74\x0c\xb2\x4f\xad\xb6\x06\xae\xde\x67\xad\xf9\x29\x4c\x76\x7c\xe8\xc2\x01\x0d\xdc\xf6\x7e\xe1\x4f\xdc\x6d\xf7\x13\x2b\x03\x69\x4a\x6d\x99\xd8\xe2\x33\x6d\x87\xea\xf8\xa7\x0c\x8b\xac\xb6\xd9\xb7\x6f\xbb\xc3\x7e\x73\xf8\xbe\xd8\x2f\xbf\x1f\x82\xbb\xc5\x7a\xeb\x7b\x05\xb5\x49\x79\xd4\xe3\x35\x6e\xb3\xfa\x7c\xe9\x76\x16\x08\x42\x82\xf7\xe0\xd8\x66\x10\x09\x38\x36\x11\x10\x28\xc5\x22\x4f\x47\xd1\xfc\xe6\x5e\x2d\xbe\x59\xeb\x06\x0e\x59\x39\xfb\x73\x94\xb0\xfd\x3a\xfd\x3e\x01\x01\x30\x48\xfd\x4c\x6b\xac\x92\x5e\xaf\x3d\x94\xba\x65\x0c\x94\x04\xa9\xe3\x56\x37\x03\x9f\xe9\xeb\xa9\x08\x94\x7a\x22\x84\x02\x5a\xa7\xef\xa9\x86\x8b\x2e\xb7\xa2\xd0\x63\x67\x1a\x68\x1c\x63\x65\x54\x58\x39\x81\xfa\x4e\xa8\x2b\x01\x04\x05\x8c\x19\x32\xec\xa9\xb3\x95\xd1\xc9\x18\x99\x62\x9a\x6e\xad\xcb\x1c\x3f\xa2\xcf\x36\x01\x93\xb6\xc3\xca\x01\xc6\xda\x77\xd0\x07\xcb\x10\x86\x31\xb3\x24\x88\x18\xe6\x7f\x17\xf5\xcb\xfe\xe3\x3c\x42\x53\x41\x98\x58\x71\x70\x65\xe9\x33\xa7\x34\x1c\x10\xaa\x80\x26\xbe\x90\xd6\xbb\xae\x5b\x67\xee\xbd\xc3\x3e\xfc\x55\x93\x84\xc6\x09\x91\xec\xcb\x65\x59\xd4\x97\xd3\xb5\xb0\xe8\xe4\xad\x46\xa9\x46\x46\x8f\x07\x51\x1c\xcb\x2d\x9c\xfd\x8a\x84\x58\x47\x88\x2a\xb8\x2f\xad\x8a\xfd\xbc\xe7\x0a\x3c\xb1\x72\x68\xfb\x4b\xd5\xe4\xf0\xa7\xb9\x2d\x48\xc2\x18\x12\x1f\x11\x35\x95\x18\xf6\x4b\x41\xc2\x2d\x13\x03\xfa\x62\xcf\x55\xf6\x54\x81\xc9\x7e\x75\x47\x53\x5b\xb5\x38\x8b\x8f\x9b\xec\xba\x96\x38\xf0\x75\x20\x25\x09\xfa\xd3\xef\xbe\x37\x66\xff\x6b\xde\x64\x43\x4a\xb9\x61\x9e\x6a\xd1\x79\xcc\x7a\xae\x45\x0b\x52\x23\xb1\xee\x7b\xca\x8a\x9f\x90\x3d\xe1\x7a\xef\x42\x97\x6e\x8c\xd6\xc8\xfe\xf9\xf4\x4f\x74\xf9\x67\xe4\x28\xdd\x48\x99\x5a\x02\xe6\x76\xe3\xdd\x18\x83\x44\x7f\x9f\xb6\xfb\x80\x8a\x03\x84\x72\xaa\xb2\x30\x79\xa6\x9a\x55\xa1\xef\xb2\xae\x4b\x1d\x54\x6a\x49\xa1\x10\x0e\x76\x05\x93\x9b\xff\xf0\x4a\x84\x98\xd9\xfa\x7d\xbd\xdc\xfc\x31\xfe\x6e\xe3\x37\xa4\xa4\xf4\x6c\x1c\xa8\x5b\x71\x9e\x04\xaf\xa0\x43\x91\xc4\x1d\x95\xd1\xf7\x4b\xd1\xac\x7b\xd0\xf2\xdf\x26\x17\x9d\x5c\x5c\x47\x56\x80\xf9\x6e\xf3\xfc\x78\xbb\xda\x06\x56\x11\xdc\x3f\x97\x8e\x05\xf6\xf9\xfc\x58\x6c\x1f\x16\xc3\x6a\x38\x40\x18\x79\x50\xc5\x94\xc4\x53\x81\x21\x29\x62\x54\x6f\xf2\xec\xbc\x2c\x4f\x67\x68\xb2\x6b\xe0\x0d\x98\x28\x16\x3d\x21\xf0\x8d\xf0\x1f\xd1\x10\x6e\x45\x82\xcc\x14\xbb\xde\x0d\x30\x11\xb6\xaf\xc0\x1b\x14\x96\x87\x72\xa2\x8b\xd1\xdd\x8a\xa1\x4c\xa4\x2e\x25\x8f\xe6\xdd\x2b\x81\xce\xbe\x0d\x43\x99\x8e\x99\x97\x78\x6b\xd4\x4b\xbb\x43\xde\x67\x75\x43\xfc\xc6\x65\xa8\x49\x22\x33\xf0\xfa\x6e\xe1\x6d\xa0\xcd\xe1\x06\x31\x6a\x39\x68\x67\xa7\xc3\xbf\xc2\x51\xa7\xca\xe5\x53\x22\x4a\x65\x58\xc8\x12\x47\xf5\xb2\x3b\xd5\x4b\xa8\x9a\xcc\x64\xd3\x60\xd1\xb0\x38\xc5\x92\xab\x2e\x97\x22\xcf\xc7\x73\xc3\x84\x24\x40\x52\x0a\xec\x74\xf3\x5d\xd7\xfe\x18\x63\x03\xaa\xb1\xd6\x48\x0e\xb9\x09\xba\x41\x36\x87\x59\x43\x83\xb6\xb4\x53\x69\x99\xcb\xc5\x98\x50\x46\xdc\x6d\xfa\x58\x78\x98\x2b\x83\x98\x28\xb0\x49\xa6\xdf\x2f\x80\xe5\xf9\x7e\x5a\x99\x28\xb4\x0b\x69\x77\x39\x43\xf5\x9c\x37\x95\xc0\xff\x1a\x54\xf7\x4d\x14\x47\x9c\x7b\xb6\x61\xe4\x6c\x74\x75\xd7\xde\x12\x1b\x0e\xb6\x9c\x89\x94\xdb\x05\xa0\xe7\xdd\x6f\x40\x7f\x29\xed\x3a\xb2\x9a\x26\x09\x53\xc4\x4c\xda\x7d\x60\xa1\xb5\x55\x3a\x9e\x35\x2d\x26\x89\x62\x84\x19\x5c\x8a\xba\xcc\xf5\xb2\x7d\xf3\xcf\xde\x27\x31\x69\x10\xa0\xa0\xad\x06\x1f\x0a\x58\x8c\xcb\xf8\xb3\xa5\xca\x66\x64\xdb\x0b\x3c\xaf\xf6\xf3\xb6\xb6\x1b\x2d\xa8\x44\xd4\xca\x6e\x71\xbf\xda\x59\xfa\x48\xff\x73\x22\x66\xbe\xbf\x7d\x0b\x75\x79\xa9\x54\x47\x89\x3e\x7a\x40\xa9\xec\x03\x3e\x17\x35\x34\x93\x96\xa6\xf1\xd7\x53\x81\x7d\xff\x96\xd8\xec\xae\x98\x74\x0a\x19\x45\x49\x02\x2e\x57\xdc\x8b\x6f\x3a\xe1\xd2\xfd\xe6\x93\x95\xa7\x99\x40\xe7\xc2\x32\x6c\x4c\x26\x8c\x16\xc2\x56\x9a\x2f\x38\x9d\xcc\x25\x1f\xa0\x9e\x8c\x96\x0a\xb1\x9c\x67\xa8\x4c\x59\x9d\x0e\xef\xb3\x24\x33\x46\x2b\x93\x0c\xa8\xc2\xcf\x50\x3c\x88\x57\x18\x65\x5f\xa6\xf7\x04\x52\xf4\x4d\x48\xad\xc7\x6c\xe9\x7c\xc7\xd6\xce\x68\xc3\x95\xc3\x2b\x2f\x26\x6a\x78\xf3\xf3\x03\x28\xf5\x05\xc6\x21\x2e\xf1\x76\x28\xfd\x31\x3d\x25\x16\x66\x98\x73\xbd\x9a\x10\x5f\xa5\x63\x3e\x33\x2f\x26\xb0\xb2\xb8\x1e\x88\xf7\x4d\xd4\xbb\xf3\x50\xc0\xfb\x32\xec\x3c\x30\x26\x02\xcb\xa7\x6b\x73\x69\x2f\xa2\x28\x20\xf7\x9a\x25\xb3\x8f\x1c\xa4\xdd\x4f\xc9\x20\x04\xcf\xdb\x54\x9d\x44\xee\x0a\x21\xe3\xa7\x34\x26\x88\x1d\xc4\xdf\x2d\x77\x4d\x48\x68\x91\xf9\xeb\xed\xe6\x71\xb0\x03\x69\x12\x50\x4b\x6c\x6f\x6f\xe7\x1b\x14\xc4\xcb\xc4\xcc\xbd\x42\x4d\x02\x1d\x8a\xc0\xc3\xc6\x6e\xb3\xb7\xbe\x99\x5d\x13\x46\x63\x2b\x1a\x7e\x68\x23\xc7\x3e\x63\xa2\x09\x8b\x09\x4e\xbd\x53\xa9\x9f\x44\x7d\x1d\xb5\x7d\x4a\xfd\xa1\x09\xe3\x52\xf5\xb2\x18\xeb\xfa\x49\x7c\xa0\xa2\xfe\x90\x12\x5a\x13\xd6\x3a\x64\xbe\xae\xd3\x46\x49\x37\x65\xa1\x67\xd3\x3b\x9a\x30\x45\xb0\x90\x28\x8e\x15\xc0\xa0\x4c\xa6\x09\xd3\x3c\x76\xe1\xe8\xe5\x04\x3f\xcb\xea\xf5\xb7\xf1\xd3\x33\xe0\xd4\x4a\x25\xd9\xfc\x07\xbe\x4a\x35\x42\x96\x68\x12\xa6\x0c\x51\xb8\xbd\x7a\x48\x70\xb3\xef\x57\xa3\xf3\x86\x34\x09\x85\x6d\x03\x42\xc8\x0a\x62\xe7\xeb\xc6\xf5\xf1\xf7\x0f\x16\x69\x8d\x95\xb3\xe5\x72\xb9\xed\xed\xb7\x46\x88\x05\xb2\x43\x8b\x42\xe7\x30\x0c\x50\x66\x5d\x14\x4d\x62\x15\x63\x71\x09\x3d\x44\xfc\x08\x23\x50\xf6\xa8\xed\x45\x13\x4e\x62\x4c\x95\xf5\x64\xf2\x5b\xa8\x2f\x79\xe3\xb1\x45\xec\xdf\xff\x0a\x82\x7f\xff\x8b\x51\xff\x30\x3c\x54\xe8\xe7\x5b\xbb\xf0\x13\x75\x62\x6d\xa0\xf0\xaf\x80\xc7\xff\x1e\x96\x98\xbb\x33\xac\xde\x84\x8d\x0c\xcc\x83\x85\xef\x75\xe2\x22\xfe\x41\x13\x12\x20\x84\x48\x9c\xcf\x50\xe8\xc7\xcb\x09\x01\x4a\x6d\xa4\x32\xd3\x51\xd7\x0e\x4f\xb1\xff\xd5\xe2\x0b\xaf\x94\x7d\x87\x4b\x57\x93\x84\x71\x94\x46\xc8\xea\x6f\xa2\x76\xf7\xeb\x74\x13\x34\x49\x42\x89\x55\x32\xfc\x32\x4f\xa2\x72\xde\xd7\xe4\xe7\x22\x89\x35\x8c\x93\xa5\xfb\x18\xa6\x0a\x34\x49\x52\x1a\x38\x4c\xca\x3f\xc1\x3b\x66\x9a\xa4\x04\xd0\x70\xdd\xae\x9e\x36\xbb\xf5\xfe\xf0\xb4\xda\xae\x37\xb7\xdd\xd1\x34\xc1\xbe\x38\xcc\x96\xc8\x61\xdf\x8c\x26\xa9\x8c\x11\xdb\xf1\xf7\xc7\xdb\xfd\x70\x11\xa7\x9a\x60\xae\x76\xb9\xdd\xfc\xbc\xc5\xae\x8e\xc5\xfd\xfd\x66\x39\xe8\xeb\xd0\x44\x70\x83\x44\xe0\xc7\x4a\x14\xcd\x8c\xde\x7c\xdd\x0d\x04\x89\x51\xdf\x4a\xdb\x54\xa4\xff\xbb\x4c\xb5\xa2\x5d\x0d\xd7\xfb\x63\x8e\x8e\xee\x4f\x14\x94\xfd\x25\x24\x8f\x1c\x6a\x08\x03\x26\x2f\x20\xe7\x7f\x42\x05\x80\x6c\x35\x87\xda\x39\x3e\x93\x95\xab\xa8\x05\x7e\xf6\x85\x92\xcf\x7c\x8f\xf9\x35\xa0\x78\xa2\x68\xa7\x9b\x29\xaa\x8f\x8d\xeb\x82\xea\x6e\x40\x2b\xbc\x01\xbf\xf9\xf5\x95\xf8\xc9\x85\x8c\x40\x92\x03\x29\xea\x76\xed\xdd\x66\x6f\x59\xdd\x5f\x45\x07\x0c\xd3\xd9\x3f\x57\x7b\x2f\x3a\xa8\x89\xd6\x21\x76\x02\xc9\xa6\x18\xe6\xc0\x34\x81\x30\xf6\x2a\x02\x85\x82\xbc\xbc\xaa\xdb\x68\x02\xda\x93\x22\x5a\xd5\x09\xc4\x8f\x7d\xb5\x3b\x6a\x62\x68\xec\x54\xb7\x44\x83\x12\xe2\x87\x37\xe2\x7f\xd1\x44\x22\xe9\xf9\x20\x7f\xae\xd6\x6e\xda\x8e\xae\x10\x10\x1e\x69\x32\xe8\x4d\xb5\x49\xca\x61\xf5\xc4\x0f\x4c\x43\xb4\x2c\x7f\x17\xd9\xf7\x72\x38\x2f\x03\xaa\x02\x4c\x61\x40\xf3\x72\x57\xbc\xb6\xa7\x52\x7f\x88\x85\x0c\xb7\xe2\xd5\x6e\xf3\xb4\x68\x4d\xf5\xe9\x2c\x8a\x8f\x1d\xcc\xb7\x39\xea\x80\x25\x94\xba\x1a\x97\xfd\x22\x16\xb3\x37\x7a\x95\x01\x13\x16\xcc\x9f\xd5\x1e\x8f\xd0\x4e\x53\x8b\x09\x99\x9d\x91\x41\x18\xa6\xd8\xdf\x7a\x9b\x15\x65\x57\xa0\xf1\x97\x0b\xc1\xc2\x98\xbb\x7a\xfc\xee\x69\xe7\x8f\x45\x40\xd2\xbe\xdf\xc1\x26\x99\x1f\xc5\x69\xc4\xfa\xa2\x03\x6e\x28\x16\xf8\x1a\x10\xa7\x21\xdb\x93\x3b\x9c\xc4\x1a\x21\x0f\xbb\xa6\x9c\xd5\x45\xf0\xc3\xa4\x05\xc5\xfc\x9e\x35\x62\xf4\x7e\x53\x16\x27\xb6\x92\xb6\xd2\x68\x9d\xc6\xfc\x4e\xce\xd2\x06\xc2\xd1\xce\xfd\x7d\xfd\xf8\xad\xfd\x8f\x3f\x5d\x08\xc1\x69\xa7\x52\x85\x81\xdd\x94\x9f\x7b\xfc\xb6\xa4\x4e\xe5\x88\x27\xee\x1e\x3c\xe1\xaf\x0e\x54\x44\x80\xb8\xbc\xcd\x84\x44\x68\x72\x19\x15\xc7\xda\x97\x89\x6d\x34\xa6\x44\x03\xeb\x76\x63\xd2\xdd\xd5\x94\xc0\x84\xc6\xf7\x4c\x43\x25\x7c\xdd\xf4\xf3\x94\x8c\x0e\xb4\x0a\x98\xf3\x07\x9b\xd1\xcb\xec\x22\x1a\x1d\x40\x94\xa0\x1b\x84\xde\xcb\x67\x5e\x60\x37\x16\x7c\xdf\xe9\xa6\x5a\x0a\xf5\x02\xb7\x50\x63\x90\x0a\x7a\x0b\xe7\xb2\x6a\x1e\xcb\xdd\x4b\xf9\x8e\xb2\x9c\xee\x1c\x13\x4a\xe1\xf2\x69\x8b\x23\x14\x5a\x8c\xa7\x83\x91\x36\x13\xdc\x06\x88\x37\xdd\x39\xca\x66\x30\x1c\x7f\xd9\x35\xfc\xd4\x8e\xa3\x84\xa5\xc4\xa3\x36\x44\xb5\x6b\xc4\x98\x62\x48\x53\x92\x28\x04\x06\x40\xa1\x5d\xc5\x7f\xad\xca\x3e\x9e\xd3\x34\x08\x01\x6b\x08\xca\x8a\xf6\xb8\xed\x6e\xae\xc7\x6d\x3c\x01\x29\x0d\x88\xc5\x2a\xf8\xa4\x70\xfb\xa7\x24\x49\x7d\x13\xb0\x4d\x4d\x2e\xba\x63\x94\x23\x9c\xf8\x04\x79\x59\xb4\x2f\xaa\x3b\x10\x29\x64\xa4\x5a\x96\xed\xff\x75\x5b\x0b\xa5\x89\xc2\xf4\x70\x56\x3f\x64\x45\x73\xdd\x35\xa4\x29\x15\xb1\xf2\x3e\x6d\x1b\x42\x8c\xb3\x5a\x9a\x32\x42\x71\x1d\x6f\xaa\x52\x0d\x2e\xcc\xa8\x8c\x5c\xa1\xc7\xd6\x8f\x1d\x5f\xc2\xf4\xf4\x30\x00\x2a\x07\xc4\x8c\xf7\x23\x99\xed\xf9\xdd\x8c\x86\x91\x55\x52\xb0\xf0\x8f\xa6\xac\xc4\xb1\xdb\x08\xbd\x93\x47\x23\x66\x4b\xa2\x39\xa0\x7e\xe8\xf7\x6c\x08\xcc\xd2\x34\x8a\xe2\x84\x8d\x9a\x9b\x6d\x1c\x3b\xfa\xb0\x31\xd1\x9e\xfc\xbc\x5f\x2f\x6d\xa8\x23\xdb\x59\x70\xa9\x27\xef\x2a\x66\x2c\x75\x86\x1b\xf5\x26\xae\xd7\x01\x8d\x95\xa5\xed\xae\xa1\x39\x1c\x7b\xab\x35\x5a\x50\x94\x47\x1a\x6b\xec\x36\xef\x8f\x84\x07\xd5\xf6\x92\xc3\xf4\xf7\x38\x67\xa9\xf5\x2c\x77\x50\xbd\x4d\x7b\x60\x35\xe5\x32\x0a\x7c\x91\x1c\x5b\x1c\x7a\x32\x12\x4d\xb9\x82\x94\x79\x2f\xd0\xd1\x53\xcd\x2f\x48\xca\x75\xa0\xdd\xbb\xc2\xaa\xd9\x75\x97\x8d\xa6\x09\x15\xce\x64\x37\xea\x65\x87\x9d\x7b\x5f\xca\x22\x6a\x9a\x30\xbb\x03\x38\x43\xfe\x0e\x70\x9e\x13\x3f\xd0\x34\x49\x39\x36\x27\xb4\xfb\xf4\xee\xa3\x68\x5e\xa0\xce\xfe\x87\x1b\xcc\xef\x99\xf8\x32\x68\xa2\x89\x01\xc9\xba\x20\xcb\xd5\xff\xd7\x0d\x78\xc4\x90\xa6\x69\x1a\xda\xa6\xe4\xd6\xeb\xb3\x6a\x31\x4f\xae\x0b\xcd\x0f\x91\xa1\xc1\x1d\x70\xff\x02\x7b\xb0\x2a\x7c\xa2\xf8\xe8\x8e\xc6\x32\xb0\xed\x90\xbd\x78\x44\x67\x4d\xa9\x4c\x62\x66\x5b\xf6\x4b\x7d\x51\xf0\x5c\x64\xcd\x48\x5e\x4d\x53\xc5\x84\xc5\x48\xa1\x18\x9b\x67\x63\xc0\xc9\x98\x74\x63\x1c\x4b\x98\xf5\x1b\x3c\xa7\x71\x77\x14\x82\x04\x7c\x6b\xde\x47\x5e\x0a\x8d\x6a\x4c\xe3\x97\xa8\x00\x50\xa6\xee\x5c\xe6\xb9\xbd\xc3\xf1\x5c\x51\xc6\x36\xfb\x5b\x4a\x9d\x9b\xfb\xe7\x95\xbf\xbc\x66\x96\xb5\x06\x39\x70\xb3\xb2\x98\xb4\x23\x69\xaa\x25\xc3\x5c\x2a\xde\x38\x7a\xcf\x9d\xe0\xfc\xba\x98\x48\x79\xa0\x68\x28\x35\xc8\x2a\x56\x39\x48\x88\x3b\x00\xa9\xc2\x70\xfe\x09\x10\x3b\xd0\x51\xc2\x69\x0a\x4a\xa1\x46\x59\xeb\x9d\xde\x8b\xba\xb9\xbd\x72\x85\x28\x68\x8d\x0e\xaa\xed\x88\xb8\xdf\x2c\x7f\x78\x87\x81\x91\xd8\x5a\x67\xbf\xeb\x58\xa5\xb2\x7d\xf9\xbd\xec\xba\xde\x34\x23\x29\xc5\x46\x0e\xd7\xd9\x34\x0d\x19\x19\x8d\x43\xcb\x4e\x96\x83\x28\xee\xcb\xa3\x3f\x8f\x11\x2b\x52\x8d\x8f\x7d\x70\x14\xef\x75\x77\x34\xe1\x78\xd4\x7e\x37\x4b\x54\x61\xbd\xb9\xf9\x0a\xb0\x66\x2c\xb5\xfd\x27\x0d\xd4\x8d\x13\x92\x6e\x3e\xf6\xd5\x47\xfb\xbf\x9f\x8b\x9e\x6a\xca\xff\x42\x18\x19\xd5\x85\xb2\x8f\xe5\x29\x2b\x00\xba\x9f\x0f\x81\xba\xb4\xbe\xae\xf6\xe5\x5d\x59\x5d\x4e\x13\xee\x1c\xcd\x22\x65\x89\x50\xec\x0a\xb9\xcf\x64\x25\x7e\x9b\xa8\x13\x04\xf1\x55\x47\x86\x66\x11\xf0\xc0\x6a\x22\x36\xd5\x87\xcd\x86\xdc\x4e\x5a\xdd\x34\x8b\xb9\xe1\xba\x13\x22\xec\x68\x01\xfd\x51\xc5\x50\x17\xd3\x37\x2a\x5a\x4a\x8e\xf1\x15\xb8\x09\xbc\x2f\xbc\x2e\xde\x82\xc9\xcd\x27\xc2\x74\xb2\x30\xb7\x20\x2f\xc7\x65\xaf\xf0\xa8\x59\x2a\x43\xdc\xdc\xda\x6d\x6b\xa7\xca\xaa\x9f\xf3\x33\xfc\x4a\xed\x70\x81\x5b\x96\xb5\x04\x98\xc7\x1b\x39\x8d\x4c\x70\x8e\x31\x8a\x40\x98\xaf\x83\x76\xf6\xda\x97\x9a\x09\x49\x11\x4c\xf2\xdf\xee\x0f\x4a\x7a\xea\x5d\x6c\x25\xd9\x98\x5d\xf6\xab\x01\x14\x20\xf7\x31\x7d\x7f\x03\x92\x85\xe8\x94\x2e\xb4\x5e\x15\x4d\xd6\x7c\x0c\xf4\x81\x34\x93\xd2\x7a\x38\x25\x72\x55\xa3\x2c\x1a\xba\xcc\xfd\xe6\xc2\x54\xc0\xd0\x35\x36\xf9\xa5\x7e\xc1\x8e\x9f\x47\xf8\xe5\x77\x3c\xa6\x02\x15\xb6\x66\xec\xbd\xcc\x5f\x47\x05\x09\xcd\x54\x48\x31\x27\x7a\x23\x9a\x26\x87\xdb\xaa\x3c\x61\x16\xb3\x3b\xaa\x64\x3b\xf7\x65\xa6\xc7\xcc\xef\xe3\xdb\x57\x49\x22\x35\x12\xb8\xe5\x4d\x36\x0a\x22\xa7\x03\xd3\x00\xf1\x04\x99\xb3\x63\x7d\x32\x54\x33\x25\x24\xb6\x61\x1e\x9a\x2a\x3b\x1e\xa1\x7a\xfa\x7d\x65\xd5\xb8\x27\xef\x4a\xc9\x08\x59\xae\x75\xd9\xe1\x1d\x5b\x0f\x66\x0e\x98\x31\x3a\x4f\x13\x8d\xcf\x92\x95\xbf\xb2\xee\xf1\x75\xa2\xb4\xe5\xc4\x74\x2c\xc1\xe2\x04\x7f\xac\x6f\xaf\xa8\xde\x35\x03\xaa\xb1\x54\xb5\x3a\x8b\x79\xd9\x82\x2b\xa8\xb9\x66\x10\x11\xe1\x32\xe6\xd9\x9b\xc7\x02\x6b\x06\xb1\x20\x62\x60\x96\xbe\x56\xa9\xd5\x0c\x94\xe5\xc7\xb3\xdb\xe5\xea\x57\x03\xad\x15\x1f\x36\x27\xf9\x81\x60\x3c\x4b\x78\x17\x95\xb8\xad\x78\xe8\x65\x30\x13\x08\x12\x8e\x44\xe4\xc6\xd7\x31\xd4\xc4\xfd\x0f\x3e\x59\xc7\x76\xd4\x88\x3e\x1a\x1f\x92\x84\x63\xe6\xca\x64\x15\x60\x79\xe1\xbe\x3c\x86\xbf\xf9\x83\x22\x80\xd4\x71\xbc\xa1\x2b\x82\x02\x63\x13\x69\x8a\xde\xdc\xb8\xb3\x02\x16\x75\x24\x9d\x97\xfc\x75\x6a\x95\xc3\x20\xe4\x28\xd7\x85\x0a\xd4\x79\x76\x04\xfd\x29\xe1\x7d\x3b\x58\x20\xb0\xdc\xb6\xcb\x6d\x17\xfb\xd5\x81\x92\xc3\xd3\x6a\xbb\x5c\x3d\xee\x2d\x1d\xa9\xbf\x5b\xea\x1c\xb0\xac\x68\xbd\xc6\xf3\xb9\xfb\x6a\x21\x8d\x23\xdc\x26\x3d\x19\xcc\x40\x06\xa2\x3d\x08\x21\x19\x86\xca\xae\xbb\x67\xfd\xe4\xa7\x5a\x18\x86\x31\x46\x57\xad\x71\x59\xdc\xaf\x0e\x7f\xdf\xac\x1f\xf7\x78\x47\xdd\x8f\xc7\x84\x11\xea\x97\x47\x81\xa6\x08\x1b\x61\xfe\x1a\xee\x68\xde\x65\x0e\xe3\x30\x45\x0f\xc2\x66\x8d\x9e\x6b\xa8\x9e\x56\xf7\x9b\xcf\xb5\x2e\x75\x18\x47\xb6\x47\xca\x0a\x84\x2c\xf2\xfc\x26\x2b\xb1\x78\x96\x8f\xb2\x56\x61\xcc\x2d\x5b\x20\xb6\x1c\xdf\x5d\x70\xef\xfe\x14\xe9\xa9\xc3\x38\x11\xbe\x8b\xca\x42\xe2\xea\x61\xc4\x1c\x72\x66\xcb\xda\x7b\x91\x2d\x5f\xb2\x41\xa8\x12\xf2\x28\x41\xd2\xba\x02\xde\x5b\xf7\xa2\xaa\xaf\x25\x4f\xba\x91\x46\xd0\x81\xac\xbe\xd6\x76\x67\xf1\xa3\x87\xab\x20\xe4\x89\x12\x69\xc7\x83\x86\xd9\x46\x95\x9d\x45\xc7\x24\xa4\xc3\x44\xa9\x30\x1a\x62\x24\xa7\xa5\xda\xf1\x05\x53\x16\x08\xe7\x2c\x3f\x67\x45\xd3\xd1\x25\xcd\xdf\xab\x60\x21\xfa\x87\xd8\xfe\xff\x90\x4d\x73\x41\xa1\xd0\x91\xcb\xbe\x28\x28\x9a\xfc\x03\x5d\xb7\x99\x38\x2c\x94\xa9\xb6\x15\xb7\x93\xc8\x4b\x59\xfe\xf2\x77\x2f\x75\xc0\xe5\x90\x70\xea\x67\x56\xc0\xcd\xe5\xc3\x41\xbc\xc6\x17\x51\x91\x42\x2f\xe7\x61\xfd\x78\xb8\x5f\x2d\x6e\x57\xdb\xc3\xdd\x76\xb1\x3c\xdc\x6c\xf6\xfe\x7a\x2a\x51\x48\x8e\xd1\x3a\x33\x7f\x50\x9f\xd9\x0a\x75\x4c\x10\x70\xf8\xb4\x3b\x3c\x6d\xd7\x9e\x38\x4f\x87\x5a\x48\x24\x58\xa9\xcb\xfc\x6d\xa0\x03\x3d\x09\xd6\x42\x2d\x6d\x4b\xf5\x9e\x12\xf5\x57\x74\xfd\x75\x08\x41\x8c\xb8\x91\x2d\x46\xc1\xd5\xa9\x5f\x85\x10\x5a\x61\x67\xf7\xa2\x17\xdd\xdf\x41\x22\x76\x36\xab\x37\x0f\xeb\xce\x2d\x1d\x77\xa7\xea\xd0\x84\x56\xed\x18\xbd\x00\xcb\x2a\x62\x39\x3d\x26\x29\xd3\xd0\x08\xb0\x1a\x68\x2f\x22\xf3\xb8\x1e\x1d\x1a\x63\x15\x16\x84\xd6\x1d\xaf\xea\xd8\x74\x4d\x3d\xa9\x88\xd0\x34\x75\x0d\x1b\x77\x00\x5a\x8a\x19\x59\x82\xf1\xd4\x1d\x6e\x2f\x11\xe1\x86\x0f\xe8\xb8\x3f\x01\xd5\xeb\x88\x48\x82\x84\x58\xf2\xf2\x71\x57\xf6\x62\x0d\xdd\x03\x45\x54\x5a\x52\xd9\x32\xbf\x9c\x72\xd1\xff\xd5\xc5\xa2\xef\x00\x16\x16\xde\x47\x46\x11\x23\x0a\x79\xd3\xbc\x3c\xe9\x50\x06\xb9\x9b\x55\x11\x0b\x6c\xa4\x39\xce\x3a\x8d\x5d\xb9\x88\x45\x94\xf4\x60\x4e\x7c\xf1\xbf\x4d\x2e\x03\x1c\x8b\x5c\x88\x4a\xb0\xbd\x4a\x30\x5f\x2c\xd5\x51\x68\x04\xca\x0c\x74\xb3\x7e\xc0\x60\x37\xce\xb9\x4e\xee\x35\x0a\x29\xf5\x12\x1b\x99\xde\x98\x2d\x2a\x14\xfd\x76\x55\x44\x89\x22\x1e\xf8\x06\x32\xab\xc7\xec\x30\xbc\xf5\xcd\x87\x17\x34\x1e\xce\xd7\x28\xe2\xb6\x07\xf9\xbf\x17\xa8\x3e\x50\x09\xda\x1d\x88\x59\x80\x3e\xf2\xe2\xf1\xe1\xcd\x99\x78\x7f\xa4\x5d\x6d\xbe\xa9\x03\x9b\xe9\xd7\x85\x29\xbb\xe8\x74\x7c\xe3\x1c\x52\x74\xa6\xad\xb9\x5e\xe5\xd0\xf7\x29\xb4\x07\x01\x9d\xfc\x26\x3b\x41\xfe\x67\xb2\x17\x3a\x4a\x20\x66\xce\x46\xe3\x7b\x73\x73\x2a\xbb\xfa\x24\x22\x26\x41\xea\xfc\xef\x2b\x1e\x2f\x3c\x8c\xbd\x4a\xaf\x59\x9e\xdb\xd6\xc8\xc9\xf9\x8a\xc4\x88\x57\xe9\x0b\x76\x1d\x45\x70\x17\x42\xfa\x67\x50\x21\x41\x46\xc8\xd5\xfd\xfa\x8f\x31\x2c\x5e\x47\x2a\xb6\x28\xa0\xae\x96\x5a\xc0\xff\xb2\xda\xa3\x3d\xfd\x20\xc9\x90\x7a\x0f\x29\xd9\xcb\xcb\xf1\xe5\x2f\xf7\xb1\xb9\x0b\xe8\x80\x63\xe5\xef\x61\xf1\xc7\xe1\xf1\xf9\xe1\xb0\xf9\xbf\xfd\x61\xb4\x75\x47\x9a\x59\x51\x84\x63\x8f\x10\xb7\xe2\x7e\x7e\x00\x68\x6d\x98\xeb\x4f\xca\x3f\x66\x60\x62\x3a\x32\x01\x10\xd6\x11\xed\xf8\xdd\xc8\xe6\xc5\x3e\x61\xb4\x1d\x45\xf2\x91\xe1\x34\x8a\xfd\x3a\xd9\x42\x53\x65\xf0\xd6\x99\x39\x8b\x31\xf5\xc5\x80\xc8\xb8\xce\xf4\x53\x56\x74\x22\x2b\xa0\xbf\xa6\xca\xb1\xa7\xc6\x84\x04\x88\xfc\xb6\x3c\xee\xfb\xf5\x6a\xeb\xaf\x1a\x13\x12\x62\x07\x7d\x73\x86\xee\x4f\x3c\xc2\x2f\xd4\x2e\xdd\xf3\x50\x63\x5c\xc7\x24\x95\x18\xb5\xdc\x42\xfe\x7b\xe9\x95\xd5\x97\xa2\xd0\xd8\xdf\xf8\xdb\xe4\x57\x21\x10\x89\xc7\x83\xd8\x52\xf0\x72\xc0\xfb\xa7\xe3\x80\x31\x11\x8f\xf5\x07\xeb\x3e\x39\xef\x07\x25\x56\x92\x14\xd3\xd5\x1d\x93\xf4\x34\xb1\x11\x07\xa9\xc6\xaa\x46\x9d\xb9\xa2\xc7\x53\x55\x1e\x2b\x71\x1a\x47\x4f\x71\x20\x38\x8d\xba\x76\xd6\xec\x74\x39\xd9\x2c\x75\x56\x1c\xaf\x4a\x54\x31\x8d\x2d\xd8\xad\x86\x3c\xff\xf1\xf3\xfb\xe2\x28\xb2\xa2\x6e\x66\xec\x5d\x4c\xb9\xed\x98\xc4\x98\xeb\xc7\x8f\xa1\xe1\x8d\x59\x94\x28\x57\x75\x7f\xaa\x32\x95\x15\xc7\x5d\x53\x89\x06\x8e\x9f\xf6\x3b\x7c\x3d\xb7\x63\x16\xa7\x7e\xd3\x74\x2a\x62\xb3\x5e\x61\xcc\xb8\x41\xe7\x74\xbf\x5a\x3c\x74\xdf\x9b\x99\xd8\xab\xd8\xdc\xdf\xff\x6e\xb1\xd2\x91\x3f\x18\x46\x41\xca\x3a\x09\x16\xcb\x25\x34\xf2\x3b\xfd\x38\x50\xca\xa6\xa2\xef\xca\xea\x5d\xf4\x02\xeb\x3a\x8e\x02\x8d\x2b\xb7\x17\x13\xff\x3a\x56\x8a\xa3\x88\xa0\x4f\xea\xea\x47\x56\xfc\x6b\x6e\xa3\x88\x63\xce\x4c\x34\xa4\xc1\xdd\x18\x9b\xa6\xe9\xbe\x6e\x9c\x26\x56\x95\xab\x8d\xb8\x67\x7f\x37\x99\xfc\x3a\xd7\x32\xf1\x56\xe0\xa5\xdf\x3f\xfa\x01\x49\x1c\x10\xd7\xed\x84\x1f\xfe\xa6\xe3\x77\xd0\x71\x92\x70\xcc\x82\xfd\xf7\x02\x80\xcd\x28\x4d\x76\xec\xe6\x6d\x22\x42\x6a\x3d\xdb\xe6\x52\x15\xa7\xb2\x80\x0f\xe5\x64\x74\xfb\x1b\xf1\x88\x17\x1d\x27\x10\xa2\x79\xbd\x83\xac\x01\x99\x8d\x03\xd6\xa1\x4f\x35\x72\xad\xe2\xc4\x30\xcc\x06\x40\xf3\xf2\xd1\x3e\xb5\xff\xf5\xd4\x30\xaf\x58\x61\x63\xb8\x61\x42\x3d\x16\x42\x53\x1b\x33\x69\xf8\x75\xb5\x94\x24\xb7\xf4\xa4\xb5\x30\x30\x50\x47\xf3\x47\x45\x18\xa5\xce\x0c\x2d\x45\x35\xce\xff\x27\xff\x0a\x1c\x07\x83\x8e\xa5\x0c\x63\xe5\xa7\xa9\x1c\xed\xb0\xb1\xd6\xb6\x30\x62\x05\x94\x2d\x7d\x2b\xee\x07\xde\xc3\x89\x21\x90\x91\x8d\xcf\xda\xe5\x79\x03\x45\x76\x2c\x26\xf7\x09\x4c\x7a\x02\xa5\xc7\xbb\xfd\x57\xdd\x1a\x3a\x06\x65\x15\x65\x7a\x60\xeb\x2d\x34\x22\xcb\xeb\x61\xde\x26\x06\x03\x48\x9c\x76\x9b\xd5\x6a\x10\xcf\xc4\x26\xb4\x55\x33\x2c\x40\xbc\x95\xd7\x2e\x51\x6c\x22\x8a\xd8\xc7\x65\x79\x39\x97\x85\xf7\xb1\xbc\x5f\x47\x7b\x4f\x92\x4f\x60\x98\x83\x63\xdd\xa5\x2c\xa5\x9d\x83\x6c\x41\x97\x0b\x18\xef\x1d\x9c\x24\x01\x73\xb2\x00\x7b\xa8\x4e\x35\x16\x88\x0b\x5b\xe2\x1c\x21\xee\x34\x27\x32\x44\x06\xa5\xef\x1d\x25\xc1\xe8\xee\x39\x31\x21\x56\xcd\x54\xd6\x64\x30\x14\x9b\xd2\x3c\x90\x11\x76\x01\x61\x13\x28\xa8\x17\x51\x64\xf5\x3c\x3e\x5c\x73\x4a\x08\xd6\x54\xaa\xd6\x28\x25\xe3\x16\x20\xcd\x29\x23\x03\x4c\xd7\x4c\xdb\x9a\xe6\x54\x04\xc8\x34\xb8\x2f\xab\x4b\xbd\x1c\x06\x17\xe3\xfb\xa5\x60\x0b\x59\x96\x9f\xb5\x7d\xde\xa1\x3e\x81\xe6\x2c\x8a\xd1\xf2\x39\x0d\x90\xc7\xee\xef\x69\x88\x91\xf5\xba\x40\xae\x9d\x8b\xc8\x3b\x49\x4b\x37\xc2\x2b\x47\x2e\x4b\x2f\x88\xaa\x79\xc8\x6d\xe1\xad\xaa\xc5\xef\x96\x5b\x72\x40\xfd\x3a\x03\x49\xd7\x3c\x14\x01\x52\x90\xaf\xf6\xdf\x0f\xb6\xff\xdc\xa2\x58\xfc\x15\xa3\x98\x28\x31\xf2\xa5\xbc\x74\xc6\x8d\xa8\x41\x6f\x0a\x4c\x81\xce\x4f\x65\x1e\xc9\x04\xdb\x85\x3a\x7f\x19\x71\x2a\xcb\x2b\xc6\x44\xcd\xe3\x20\xb0\xea\x9e\x1d\xd3\xac\x75\x2c\xc6\x3e\x83\x1f\x1c\x02\xf6\x04\x36\x53\x8d\xe2\xc9\x5d\x5c\xf5\xca\x7c\xa5\x91\xab\x39\x4f\x49\xa4\xfc\x6c\xce\xcb\xea\x01\x1a\x81\x22\x63\x73\x01\x39\x4f\x88\x55\xa4\x6e\xcd\x71\x66\xc9\x42\x87\xdc\xef\x9a\x27\x54\x63\x5f\x80\x6d\x03\x77\x7f\x4c\x09\x13\x6e\x4f\xdb\x83\x38\xdd\x55\xe5\xe9\x1e\x84\x86\x4a\x96\xbe\x33\x70\xd4\xe0\xdc\x9e\x91\x62\xa8\xfe\x0a\x1f\xeb\x93\x38\xc2\x73\x0d\xda\x81\x74\xfc\xc3\x79\xd0\x16\x4f\x5d\x5d\xf7\xd8\x46\xf2\xc8\xf9\xe7\x0f\x30\x85\x75\x0c\xd9\x1c\xbb\x3f\x29\x8a\x19\x0a\xff\xa6\x11\xec\xe0\x8e\x89\x40\x62\x1f\xa1\x29\x2b\x99\xe9\x5b\x38\xe7\xe5\xc7\xe4\x1b\x08\x19\x60\x2b\x83\x7a\xc9\x2e\x3a\x3b\xbc\x95\x8d\xf8\x5f\x56\x16\x59\x77\x09\x65\x03\xaf\xbd\xe7\xf7\xef\x0e\x18\x96\x58\xd2\xc2\xae\xa3\xf4\x06\x9a\x77\x80\xc2\x92\xc6\xb9\x61\x8a\x70\xec\x1a\xf1\x3a\x37\x6d\x94\x9c\x15\xc7\x39\x7c\xb5\xe6\x2a\xb4\xb4\x9d\x2a\x93\x50\xdd\x97\x4d\x03\x55\xf7\xc6\x95\x30\x18\x51\xe5\xe5\x87\xc8\x9b\x8f\x8e\x16\x41\x73\xcd\xd3\x30\xe9\xb5\x51\x4c\x59\x9d\x40\xbb\xb6\x38\x8f\x1a\xe3\x10\x48\xe4\xd7\x35\x13\x82\x78\xcd\x4d\x1c\x04\x7d\xbb\x95\x2f\xdf\x8d\xe6\x88\x51\x16\x42\xe1\xc4\x30\x87\x71\x03\x37\x10\x20\x9f\x2f\xe2\xb7\xc6\x80\xf0\x41\x6a\x98\x1b\x90\xac\x17\x77\xf8\x59\x16\x1a\xae\xe5\x5e\x35\x37\x46\xcb\xc4\x09\x64\x55\x7a\xf7\x51\x37\x70\xb2\x0c\xa7\x33\x51\x5d\x42\xa2\x08\x1b\x18\xac\x37\x7b\xb3\xd9\xdf\x64\xd8\x2c\x34\x24\x95\xfb\xdb\xac\x62\xef\x1c\xed\xbd\x4e\x48\xca\x7d\x59\xfe\x9f\x20\xaa\xb5\xf6\x79\xa2\x24\x20\xb6\x52\x9a\x77\xdc\x3f\xe3\x4e\x3d\x3f\x2c\xb0\x1d\x5a\x58\x35\x3e\x57\xf0\x56\x5e\xc9\x22\xea\x24\xa0\xc0\x7b\x8d\x29\xd4\x7a\x9c\x7a\x9f\x56\xbe\xc4\x8f\x0f\x35\x56\x0e\xbe\x89\x13\xfc\x31\x9c\x83\x09\x8d\x6c\x4d\x41\x89\x02\x51\x2a\x9f\xd2\xea\x8c\x1f\x93\xa6\x04\xd1\x26\x0f\x50\xbe\x0f\xf6\xdc\x84\x8a\x28\xb5\x54\x90\xe8\x93\xbb\x84\xc0\x80\x62\x48\x27\x2c\x0d\x22\xe8\xa6\x73\xdf\x3f\x3d\x61\x2e\xf6\xa3\xb5\x20\x5e\x22\xa9\x53\x1d\x1b\xdf\x0b\x33\x16\xc1\xfe\x8f\x0b\x5c\x30\xf1\xfa\x20\x3e\x6e\xc0\x29\x23\x7f\xdc\x56\x65\x01\xcb\xb2\x29\xaa\xd2\x7b\x43\x49\x48\x6d\x0a\xaa\xca\x94\xa8\x74\x26\x8a\xdf\xcb\x8b\x7a\xe9\xdc\xe1\x24\x0a\x03\x5c\x0e\x56\x53\xb2\x63\x46\x1f\xff\x6c\x24\x03\xc1\x5d\xb9\xc8\x61\x9d\x27\x23\xe2\x98\x69\xd7\x19\x71\x73\x41\x45\x3d\x34\x44\xe3\x07\x8c\x21\x4c\xb5\x8f\x94\x0e\x59\xed\xf2\x2e\x93\x51\x9c\x86\xd8\x8b\xf6\xf4\x63\xec\xb9\x8d\xbd\x8b\x84\x87\xc2\x4a\x71\xe5\x36\xcc\xcc\x4e\x70\x57\x56\x36\xb4\x1a\xb2\x11\xe9\x84\x1b\x8a\xc1\xc0\xe2\xf6\x8f\xa1\x55\x4e\x12\x6a\xf9\x72\x2b\xf1\xbe\x73\x82\x2d\xb3\x8d\x33\x3a\x49\x45\x8a\x0d\x76\x80\x70\xe5\xf5\xe9\x2c\xb2\xaa\x23\xf5\x9f\xb0\xed\xf4\xab\x38\x49\x75\x80\x15\x85\xfd\xf7\xf5\xf6\x76\xa4\xa9\xa8\x13\xa1\x12\xac\x45\x2a\x71\xbe\x15\x1f\xb4\xff\xb3\x0a\x1d\x4b\xce\x04\x8c\xe0\x07\x00\x0d\x9d\x9f\x88\x31\x36\x98\x66\x5d\xfc\xc3\xa7\x0c\x13\x49\x52\x74\xab\x57\x8f\x37\xa3\xb9\x2f\x65\x8c\x61\xc4\x40\xf0\x10\xb9\xde\xc6\x17\x97\xca\xc4\xba\x4f\x76\xdb\x2e\x68\x9c\x10\x03\x13\x98\x48\xa0\xe8\x6c\x76\x69\x4f\xfb\x4b\x5f\x99\x0a\x15\x1b\x08\x31\x6e\xfb\x35\xdb\xdd\x35\x59\x09\x3a\xb4\xdd\x6d\x0f\xe5\xc7\xe6\xdc\x06\xd5\x75\x5f\x27\xb2\x43\xda\x35\x19\x78\xa8\xf8\xa5\x29\x8d\x99\xa4\x3e\x52\x12\x52\x4c\x29\x6c\x9e\xf6\xcb\xe1\xab\x48\x49\xac\x30\x60\x72\x16\x3c\x2f\x0b\xf8\x6d\xde\xdc\x4d\x6c\xe1\xe4\xfa\xb1\xe5\xda\x38\xfb\xbc\x8a\xc7\xcf\x06\xff\x8a\x7d\x88\x91\x92\xd4\x66\x2a\x32\x55\x7e\x2b\xbb\x10\x25\x25\x22\xb6\x8c\xe9\x79\x5e\xbe\x5b\xe2\xd3\x1c\x4b\x8e\xa3\x89\x9b\x06\x41\x9a\x72\x47\xd8\xfd\xd9\x1b\xfb\x92\x6f\xbe\xbf\xdb\x80\x31\xcc\x15\xdd\x6f\x96\x36\xf8\x5f\x6e\xd6\x8f\xdd\xef\xc4\x89\x48\x7d\x17\x91\x99\xbc\xc7\x80\x73\x9c\xfb\xf7\xe5\xf1\xa1\x7c\x83\x07\xa1\x61\x12\xf6\x5d\xfd\xb7\x3b\x93\x52\x11\x5a\x9b\x50\xf5\xa5\xca\x94\x32\x91\xfa\x0f\x07\x45\x53\xcf\x11\x7a\xf8\xa1\x11\x47\x4c\xed\xf9\xad\x39\x9c\xf3\x53\x73\xe8\x6a\x61\x87\xac\x38\x74\xd2\x4a\x3a\x65\x24\xc4\x6c\xf3\x29\x2b\xfa\xe6\x54\x0b\xc1\xf2\x23\x28\xc3\x36\x3a\x29\x8a\x57\xa8\x56\x8e\x88\xd1\x1f\x4c\x19\xaa\x91\x65\x45\x2f\x36\x3a\x17\xcc\xa6\x4c\x6a\x39\x94\xe1\x6b\x0f\x22\xcc\x7f\x34\x7d\xd3\x50\x25\xe8\x8f\x9f\xab\x0c\x43\xf2\x49\xb6\x3f\x8d\x12\x8b\x15\xce\x6a\x64\x8c\x7d\xbc\x20\x6f\xab\x9b\x3d\x6e\x0c\x17\x04\xd3\x5e\xe2\xd2\x94\x5d\x52\xe9\x6e\xc2\xab\xae\x53\xae\xe2\xc0\xc1\x1b\x5b\xf7\x6f\x42\x82\xa0\x53\xae\x19\xe2\xee\x8f\xd9\x1b\xd8\x96\x48\x7f\x24\xa5\x0c\xb3\x3e\xa2\x3e\xfd\x25\xa9\x31\x9d\xa6\x61\x84\xf8\x74\x17\xb4\x20\x93\xf9\xa4\xfe\x90\xa6\x82\xa3\x16\x4b\xd3\x4b\x19\x8e\xc2\xb5\x34\x55\x04\x05\x30\x9e\x77\xb7\xfb\xe7\x9b\xd5\x08\x14\x91\xa6\x2a\x1e\x0a\x0f\x2e\x45\x35\xec\xb1\xf7\xf3\x4a\x84\x10\x8f\x39\x97\xae\x33\x9f\xa9\x0c\xad\x54\xd9\x80\x1d\x2b\x83\x5c\xbb\x94\xf0\xa2\xd0\x7b\x84\x48\xf9\x5f\x96\x09\xc7\xec\xc6\x20\x3b\xed\x8f\x80\x55\x19\xed\x28\xfb\x3e\x11\xd2\xd3\xa9\x34\x04\xef\xfe\x60\xcb\x91\x8e\xc9\xf8\x2a\xe0\xef\xde\x95\x34\x0c\xab\x97\xa7\x6c\x90\x86\x1d\x5d\x11\x68\x40\x89\x9b\x98\x4f\xa2\x12\x7f\x9a\x8f\xfb\x32\xcb\x9a\x42\x64\xa4\x63\x18\x6d\xa7\xff\xae\x11\xaf\x83\x32\xda\x78\x62\x41\x62\xf5\x35\x76\x2f\x1d\xa7\x85\x4e\x4d\x40\x11\x39\x9c\xd5\xff\x84\xd6\x74\x75\x7f\x8f\x13\xcc\x12\xb7\x9e\x8b\x4b\x2d\x74\x49\xca\xd4\xb4\x2f\xd7\x96\xca\xce\x57\x9d\xaf\x5a\x10\xc2\xb1\x92\xb6\xf8\xd1\x06\x0d\xb8\x5e\x82\x3f\xf3\xcc\xe6\x9f\x4f\x10\x16\x62\xbc\x93\x5f\xd4\xeb\xc7\x0e\xde\x50\x4e\xc1\x5b\x53\x41\x12\xab\xca\x65\x01\x8e\x53\x3f\x53\x10\x15\x07\xda\x97\x9e\x7b\xf9\xf1\xf1\x20\xca\xac\x68\xec\x11\x0a\xa8\xb3\x21\x5d\xb6\x16\x34\x66\xe0\xd5\xa8\x3b\x9d\x7a\x2d\x28\x17\x58\x8d\x44\xb2\xb8\x5d\xd6\x0c\x5c\xf3\x49\xae\x4f\x84\x29\x60\x51\xaa\xa9\x40\xd4\x97\xaa\x9b\x83\x22\x4e\x8d\xe8\x34\x20\xc6\xc8\x0b\xc1\x63\xc0\xa2\xa8\x83\x82\x7d\xcb\xcc\x28\xf2\x12\x3c\x89\x10\xd7\x09\xaa\xb4\x01\xc2\x28\x13\x21\xb8\xe3\x7d\x50\xe5\xe9\x9c\x67\xb8\x36\x46\x09\x69\x91\x90\xd0\x86\x22\x87\x87\xa1\x75\xed\x0e\xc7\xca\xda\x32\x07\x30\xd8\xc2\x5b\xf9\x0a\x4b\xa8\x26\x5d\x3b\xfd\x3e\xe5\xd5\x7c\xfa\xe7\x4e\xa9\xc6\xa6\x96\x55\x55\x95\xd5\x43\x7d\x1c\x3f\x60\xea\x78\x68\xb1\x88\xfa\xcd\xbe\xf8\x2d\xa8\xec\x9c\x41\x9f\xaa\x17\xa9\xb0\x90\xd1\x9f\x1f\xff\x2b\x0b\xdb\x3c\xe6\x0f\xb5\x5f\x06\x4d\xce\x39\x2f\x85\x7e\xde\xde\xcf\x86\xf6\x42\xa4\xa1\x86\x1e\xa3\xa0\xf5\x44\x76\xc9\x0f\x53\x26\x18\xea\xe4\xa2\x57\x6f\x99\x2c\xc7\x73\x45\x06\x5d\x46\xcf\x59\x20\xe7\xd1\x8d\xe8\x29\xe7\x6d\xad\x90\x51\x8c\xa4\xcc\x07\x07\xa7\x19\xd6\x3a\xbb\xb0\xa7\xf3\x34\x85\x22\xc4\x7e\xc5\xcb\x79\xdc\x82\xaa\x85\x62\xc2\x53\x77\x1f\xa0\x99\x40\x9f\x84\x4a\xed\x32\xaf\xa1\x59\x34\x2e\xd5\x33\x12\xc6\x9f\xd5\x31\xd2\x42\x49\x50\xae\x62\x09\xcd\xcb\x24\x32\x17\x4a\xdb\xce\x67\xcc\xa9\xf8\x4e\xb0\xf1\x05\x34\x0f\xfc\x72\xbb\xcb\x0a\xdf\x03\x39\xf4\xf4\x30\xd4\x1b\x3f\x8b\x06\x8a\x21\x57\x1b\x62\x94\x65\xdd\xf4\x2b\x04\x98\xc4\xf4\xe6\xb9\x2a\x4b\xb3\x31\xbb\x0e\x93\x2b\x20\xb1\xcd\xb4\x99\xa7\xcb\x59\x17\x37\xb9\x50\xaf\xe8\xfe\xce\x34\xf5\x6a\x01\x9a\xb1\x60\xac\x9e\x6a\xb9\xed\x27\x8f\x00\x9a\x73\x0f\xaf\x5c\x96\x85\x12\x8d\x83\x8f\x33\x6a\x19\x0a\xdd\x38\x13\x44\xc8\x6a\x21\xa4\x3a\xb4\x96\x7c\x44\x1f\xa7\x85\xa1\x14\xed\xc6\x29\x2b\x2e\x4d\x97\x20\x97\x24\x24\x98\x01\xc2\x52\xc1\xef\x59\xd5\x5c\x44\xee\x63\xaf\xd9\x3e\x38\xc9\x02\x8d\xc5\x05\x27\x3b\x3d\xf2\xca\x71\x64\x34\xef\xdf\xfe\x05\x6f\x57\xb2\x88\x7b\x8a\xb4\xdf\x91\x65\xe5\xae\xac\x96\xd7\xf0\x6a\xc9\x52\x85\xd5\x9b\x4b\x6d\x91\x6f\x98\xd0\x15\x03\x4a\x75\x37\x2e\x24\x96\x16\xa5\xbc\x34\x75\x23\x10\xe7\x33\x97\xf4\x93\x21\x67\xd2\xea\xd0\xd6\xd0\x3c\x7c\x0c\xd2\x55\x32\xd4\x56\x23\xc1\x82\x2b\x8e\x3e\xc5\x25\x23\x41\xd0\x9a\x54\xe0\x12\x30\xee\xef\x5c\x92\x38\xea\x52\xfa\xb7\xa2\x11\x96\x2d\xa1\x3b\xae\xad\xa1\xdb\xaf\x96\x5f\x39\x81\x32\x61\x1c\xbf\xd7\x37\x5f\xac\xcf\x33\xf5\xda\x7d\xb6\x24\x65\x88\xc9\x7f\x12\xd5\xeb\x72\x06\x7d\x32\xba\x54\x1a\x58\x8e\x64\x25\xce\x23\x72\x32\x2d\xd3\x24\x56\xed\x9c\x79\xcc\x4a\x99\x5d\x4e\x43\x8b\x2e\x85\x8c\xb0\xcc\xf4\xf4\x7c\x73\xbf\x5e\x22\xf2\x6b\xf5\x78\xbb\x5f\x3f\xac\x76\xfb\xc5\xc3\x53\x37\xcc\x70\x4c\x8c\x7b\xcb\xec\xf9\x73\x3f\xa9\x40\x48\x19\xc4\xc6\xad\xc8\x55\xf3\x32\xa7\x37\xac\xa5\x8c\x04\xe6\xc5\xdc\x44\x7c\x84\xf7\x69\xab\xd1\x97\x1e\x88\x94\xa9\x41\xd4\xeb\xf3\xe3\xdf\x9f\x77\xfb\xf9\x90\xf1\x6f\xd7\xf6\x4d\x2a\xd7\x22\x75\x80\xa2\xdd\x18\x1f\xe1\x1d\xd7\xa3\x3f\x1a\x92\xbe\xa7\xc6\x95\x7a\x7b\x26\x73\x2d\x55\x1c\x61\xc1\xc2\x26\xbe\xaa\xf1\x06\x27\x55\xca\x50\x08\xef\x26\x87\xba\xce\x8a\xa3\x65\x3f\xc9\xed\x66\xe8\x07\x61\x0b\x48\x07\xd7\x6d\x3f\xec\xf0\x6b\xe9\x44\xeb\xa4\xcb\xf8\xad\xdd\x0b\x9f\x77\x13\xa5\x4e\x23\x0c\xb2\xcb\x76\xf6\x65\xff\x83\x03\xa2\x38\xa6\xf3\x04\x97\xcb\xb4\xcd\x41\xb6\xfb\x1c\xb7\x41\x27\x14\x8d\xa3\x63\x1f\x7f\x46\xad\x02\x74\xb0\x25\x06\xf9\xf5\xb5\x0c\xbc\x96\x86\x70\x5c\x09\x2f\x9d\x85\x75\x30\x9b\xb4\xe3\xdc\x1c\xf3\x4e\x05\xdd\x99\x01\xb7\x59\x8b\xf2\x74\xbe\x34\x80\x96\x1b\xdd\xc8\xf1\x2f\x28\xc2\x83\x4e\x55\x6d\x48\xca\x3c\x0c\x05\x54\x90\x32\xf4\x97\x5b\xfb\xc9\xee\xb0\xd6\xe5\x8e\x50\x42\xb1\xad\xd0\x8a\x0c\xcf\xb6\x08\x2b\x1a\x12\x74\x3c\x6c\xf9\xf2\x01\x09\x18\x1e\x4b\x0d\x9f\x40\x10\x15\xe5\xd4\xc0\x40\xe1\xe5\xf7\x32\xbf\x9c\x40\x8a\x1a\xac\x66\xfb\x16\x65\x83\x2a\x24\x09\x66\x93\xc7\xa1\x29\x45\xb8\x48\xf3\x79\x7b\x9f\x62\x91\x7d\xef\xf7\xe5\xf1\xe6\xf2\x29\xbd\x86\x1f\xcc\x55\x62\x3b\xcc\xd4\xa5\xca\x9a\x8f\xe5\x0b\xa8\xd7\xe7\xed\xda\xbf\x00\xa6\xff\x1f\x6b\x6f\xd6\xdb\x38\xae\xed\x8f\x7e\x97\xfb\x54\x17\xd8\x0f\x9a\x28\x8a\x8f\x9e\x92\xf2\xe9\x0c\xee\xd8\xa9\xea\x7d\x36\x0e\x0c\x0e\x8b\x8e\x76\x64\xc9\x5b\x92\x93\x72\x03\xf7\xbb\x5f\x68\x91\xd4\x64\xb9\xaa\xce\x1f\xff\x97\xee\x42\x44\xcb\x96\x44\x91\x6b\xf8\x0d\x89\xa2\x56\xbb\x6d\xc7\xab\xf7\xb5\x0b\x27\x65\xe4\x45\x08\xa4\x3d\xf2\x1f\x38\xcf\xa0\xc2\x58\x7e\xdf\x1e\xa7\xc6\x40\x9b\x2b\xf5\x02\x72\x57\x60\xa5\xf0\xc6\x2d\x89\x12\x8a\xb3\xe9\x0e\x9d\x7f\x4d\x7a\xf3\x73\x31\x40\x25\x23\x11\x86\x49\xdf\xa8\x1a\xc1\xc3\x55\x9f\x35\x33\x56\x0c\x51\x32\x92\xa1\xa9\xb4\x59\x49\xa3\xa1\x15\xb7\x92\x44\xe8\xc0\xd4\x78\x91\x39\xb4\x2b\x8c\x93\xa3\x3d\x1a\xfb\x0a\xe1\xd9\xb2\x18\xd9\xcb\x29\x19\x87\x12\x9b\x37\xfc\x54\x16\x82\x97\x8f\x90\x57\xfc\xdf\xe3\xfa\xc4\xe0\xa7\xc4\x44\x1a\x19\x99\x9a\xbf\x23\xff\x74\x64\x46\xaa\x64\xcc\x02\x66\xec\x79\xd5\xbf\xcf\x55\x6d\x33\xd4\xe9\xbb\x91\x30\x4d\x4d\x6c\xba\x29\x3e\xa1\x7c\xd6\xa8\xe6\xfe\x95\x67\x1f\x63\x4c\xa5\x64\xb1\x11\x8c\xfa\xf7\x92\x67\xd9\xa5\x57\x48\x96\x2c\x31\xcc\xab\x2e\x50\xc4\xcb\x7f\x41\x76\x0e\x26\x92\x19\x6a\xfa\xb4\xcb\xa1\x64\xcc\x8b\xa3\x81\x21\xfd\x53\x51\xf3\x91\xaa\x98\x92\x4c\x79\xc8\xa5\xd9\x41\x06\x87\xd2\x89\xde\x2a\xc9\x80\x62\x45\x7b\x5f\x7c\xe6\xd7\x30\x51\x29\x62\xcf\x54\xa7\xb0\x74\x3f\x50\x9d\x56\x52\x50\x62\xec\x2f\x8a\xbc\x2e\xcf\x18\x2f\x36\x5b\x69\xbf\x4b\x2d\x85\xf2\xd0\xf4\x6f\x6f\x42\xe9\xc7\x34\x77\xd3\xc3\x65\xf2\xff\xe8\x77\x5b\xa4\x23\xa4\xde\xf3\x1a\x3e\xf9\xc5\xd0\xe1\x4c\xb7\x4b\xf5\x2f\x5b\xc6\x02\x42\x97\x4a\x81\x9a\x90\x47\x51\x52\xea\xc8\x94\xdc\xcd\x0a\xb5\xe8\xd9\x6c\xae\x8f\xa7\xac\xdf\x6b\x6b\xbf\x5f\x79\xdc\x37\x99\xe1\x0b\x02\x06\xab\xa1\x2c\x85\x54\x71\x84\x25\xab\x55\xfd\x36\xcb\x5b\x8e\x91\x54\x49\xcc\x85\x13\xd6\xa9\x47\x71\xb7\x04\xaa\xf1\x87\xfc\x97\x35\x9e\x3b\x41\xfe\x0b\x3f\x1a\x25\x21\x31\x7e\x1c\xd8\x10\x69\x42\xa7\x2b\x2b\x87\xdf\xcb\x84\x25\x30\x12\x1b\x19\x96\xba\x99\x3f\x39\x58\x63\xef\xae\xc9\xff\xaf\x7e\xc7\xdf\x95\x24\x24\xf0\x10\x4b\x76\x3a\xfd\x61\x90\x2b\x8f\xa9\x52\x19\xe4\xbc\xe7\x5a\x32\x78\x9d\x9a\x18\xb8\x99\x0e\x7f\x14\x7f\xff\xbd\x29\x8b\x7f\x83\x1c\x64\x9f\x52\xfb\x46\xab\x78\xfb\xbc\xec\x55\x1c\xa5\x8e\xb5\xd3\x2e\xdf\x15\x27\xdb\x45\x1b\xd1\x8d\xcd\x50\xe5\x05\x0c\x09\x69\x4e\x4b\x55\xa9\x5f\x51\x3a\x95\x97\x98\x42\x8c\x93\xa0\xdf\xf6\xa1\xb9\x83\xe9\xa2\xfc\x40\xe2\x53\xba\x01\xff\x56\x3e\x8f\xb0\x45\xd5\x7a\xc5\x34\x4f\xa6\x6f\x88\x3b\x94\x41\xb7\x9f\x0a\x22\x02\xd0\x13\x18\x79\x48\xf3\x77\x8b\xe6\xfa\xe2\x86\x68\x53\x4a\x69\xc2\xb6\xfd\xe3\xeb\xc3\x6e\xbd\x79\x58\xaf\x5e\xdc\xe1\x90\x27\xd4\x20\x3c\xd3\x16\xce\xa3\x42\xae\xb1\x54\x82\x72\xc9\x25\x57\x57\xeb\xfa\xaf\x66\xc7\xb0\x91\x32\x4c\x1f\x54\x28\x7d\xee\x0f\x7a\xfe\x3b\x8b\xf0\xfc\x3d\x10\x9f\x0a\x21\xc4\x92\x9b\xf5\x30\x9e\xec\x5f\xa8\x10\x8c\x1f\x95\x51\xf6\xd8\x00\x94\x2f\xf0\x91\x82\xdb\x0a\x54\x14\x40\xd0\xca\x54\x3e\xef\xe6\x57\xb1\xf8\xf5\x9a\xae\x22\xad\x8c\xac\x24\xe4\x3c\xab\x2f\xcb\xb4\x12\xe7\xb2\x1a\xc9\xcb\x2a\x45\x92\x00\x6f\xdf\x91\x57\xd5\x86\x5f\x6e\x71\x49\x55\xcc\x9d\x10\x37\x57\xd8\x91\x6c\xcf\x10\x2b\x8d\x9b\xc7\xf1\x9c\x05\x56\xfb\x70\x74\x79\x54\x25\x56\xb0\x41\x66\x69\x7e\x03\x21\xa1\x92\x38\x71\x28\x82\x5d\xc9\x9b\xec\x61\xfa\x8e\x26\x9c\x86\xa1\xbb\x19\xcd\x96\xe1\x8a\xe5\x6e\x39\x56\x09\x28\x5c\x31\xe6\x68\x5d\x2d\xe1\x5a\xbf\x72\x72\xa5\x51\x2c\xe6\xe0\x02\xb9\x66\xd3\xec\x91\x71\x8a\x6b\x3d\x56\xfb\x21\x1e\xaa\xc4\x42\x79\xbf\xa5\x12\x4e\x25\x54\xa9\x82\xbc\x86\x25\x3c\x42\xc5\xaf\xa8\x0c\x37\xce\xa2\x4d\x2c\x8f\x1d\xac\xd3\x09\x4a\x9b\x6a\xf0\xc3\x0d\x9a\x87\x12\x91\xa1\x57\x1b\xc2\xd8\x4f\xfa\x4c\x4a\x50\x40\x69\x95\x23\x37\x01\x3a\x6e\xef\xe3\xad\x58\x09\x29\xb9\xd1\x6e\x3c\x57\xb0\x77\xb4\x22\x25\x23\x63\x5d\x79\x00\x64\xe2\xa8\x59\x55\x41\x3d\xb0\xf6\x57\x4a\x12\x82\xfc\x8d\x79\x5a\x7f\xe5\xe7\x76\x62\x34\x5b\x9e\x63\x1f\xce\x2f\x0b\x0b\xa3\x9b\xbe\xf5\x52\x9a\x8e\x6b\x5a\x0f\x54\x4b\x94\x12\x21\x16\xf9\x66\xf5\x1b\xe4\x0e\x32\xaf\xb4\xa7\x91\xc3\x06\xf5\x1b\xfa\x9a\xaa\xf6\x80\x1f\x8b\x26\x78\x5b\x3f\xed\x56\x2f\x77\xb3\xc5\x6a\xbf\x5d\xdf\x3f\xcd\x76\xaf\x2f\xab\xfd\xea\x65\x41\x03\xbf\x1d\x19\x01\x06\xe3\xfb\x13\x97\xef\x8b\xe2\x28\xd2\x1c\x14\x8a\xef\x56\x3d\x7d\xd5\x5b\xff\x73\x27\x01\x49\xdb\x96\xd5\xad\x86\x81\x19\x0b\x5e\x44\xd0\xc0\xfa\xeb\xf3\xf2\x81\x0f\xde\x41\xf0\x68\xe0\xdb\xf9\xda\x43\xa7\x83\x47\x0d\x3a\x5d\x18\x02\xbd\x69\x19\xec\xdb\xa3\x3c\x8e\x54\x0b\xd6\x4f\x73\x0b\xd7\x3f\x19\x0d\x29\x37\xca\x0f\x68\xdc\x69\x9a\xb5\x4e\xf4\xc3\x9f\xe6\x53\xf3\x46\x29\x38\xa6\x15\x2c\x56\xcf\xe3\xe3\x00\x91\xe1\x05\xa8\x19\x1a\x46\x99\x76\x78\xdf\x9c\x78\xf8\x81\xc0\x13\x08\x22\xac\xd3\x53\x37\x8f\xad\xf0\x80\x1d\x12\x46\x0a\x25\x96\x9d\xef\xd5\x34\x7e\xc1\xad\xc3\x10\x4a\x23\x13\xf3\x74\x96\x19\x9c\xab\x6f\xa9\x11\x54\x2a\xfb\x66\x0e\x0a\xa2\xc8\x13\xc2\xa9\xdb\x5e\x8a\x73\x8d\x5d\xa4\x66\x3e\x55\x03\x9f\x48\xb7\xb5\x43\x44\xc2\xc8\xc4\x8c\x68\x63\x3c\xbd\x1f\x42\x14\x0b\x5c\xfb\xf6\x15\xd4\x7e\xfb\x5d\x22\xc4\xbe\xbd\xc9\x9f\xd1\xd0\xa8\x7d\xa0\x91\x62\xae\xa7\x30\x3b\xd7\x85\xa9\x6d\xda\x63\x44\x72\xaa\x2c\x10\x6c\x09\x1f\x43\xf7\x67\x37\x06\xfc\x00\x93\xc0\xfd\x2c\x57\x25\xb4\x9d\x70\x88\x43\xe3\xed\x69\x60\x97\xd6\x0e\xc1\x04\x25\x43\x8b\xf7\x21\x6c\x76\xbc\xee\xb9\xb3\x71\xd3\xb9\x3b\x35\x8b\x64\xcf\xc5\xea\xe7\x6b\x15\x50\x69\xac\x47\x9d\x2a\xdc\x5e\x20\xbe\x60\x74\xd3\x92\x90\xe3\x28\x4c\x0f\xab\xbb\xa2\xec\x1c\x26\x14\x30\xcf\xcc\xb8\x26\xb8\xc4\xae\x7a\x9a\x1f\x56\x95\xe4\x27\xd8\x15\xfd\x98\xb8\x7d\xfe\x2c\x4e\x90\xc5\xb5\x5e\x3c\xef\x97\xb3\x7f\x6e\xdb\x13\x31\xd3\x34\xb6\x9a\x7d\x65\xcf\x02\xdb\x8d\x10\x3c\x1a\x08\xe3\x0d\x2d\x5a\x86\x97\xc6\xa4\xd1\xc7\xfe\x7c\x4b\xe5\xdb\xe4\x5e\x0d\x0c\x88\x41\x5d\x36\xcf\xcf\xf5\x20\xb7\xe7\x11\x8a\x0f\x78\x02\xb6\xdd\x09\x3d\x6e\x3e\x88\xc8\x44\xf5\xbc\x13\xa7\x1a\xac\xa5\xa0\x12\x3f\x94\xad\xb3\x75\x91\x4a\x47\xd8\x18\x5d\x16\x84\xa6\x3d\xbd\xda\x7d\xdd\xef\x1e\x96\xfb\xa7\xe7\xa5\xa3\x84\x01\x44\x5a\xdb\xd6\xb5\xf3\x34\x79\xc1\x82\xc0\xe8\x52\x80\x50\x14\xc8\x7b\x5c\x3f\xe9\x26\x14\xbe\xb4\x27\x20\x12\xdb\x7b\xbb\xaf\xb3\xef\xeb\xa7\xfb\x91\x91\xba\x02\x88\x3d\x30\xb1\x45\x56\x98\x54\xb7\x87\x42\x00\x88\x99\xb6\x50\x47\xcb\xc2\xb6\x07\x34\xf3\xf1\xd6\xbd\xf1\xaa\x6b\x05\xde\xe2\x5a\xf4\xfb\x0b\xda\x8b\x7d\xed\x8d\xf5\x52\x07\xce\xfb\x4a\x7b\x2a\x01\x8b\x27\xdc\x73\x23\x73\xb1\xb7\xf0\xf4\x7d\x7d\x0d\x9f\xd5\x3e\x8f\xc2\xa8\x7d\x81\x07\x7d\x9c\xbb\xa2\xec\x09\xe4\xb6\xe3\x8d\xd1\x14\xe6\x21\xfe\xf4\xae\xac\x43\x5f\x84\xcc\xbd\x1b\xcd\xa9\x76\xbc\x7a\xaf\xba\x7a\xff\xf0\x27\x84\x34\x40\xe4\x60\x9e\x4a\x38\x9c\xdb\xd7\x5c\x87\x82\x21\x46\xa6\x05\x8b\x7e\x83\xaa\x1e\x8b\x1e\xff\xfc\x2d\xd5\xa1\xe6\xc4\xb0\x02\x9a\x37\x63\xc1\x6b\x38\x14\xe5\x08\x27\xaf\x49\x24\x19\x5a\x4a\x14\xcd\x42\xf2\x54\xa8\xf6\x6e\x12\x62\x68\x91\xf9\xf9\xf8\x02\xda\xf4\x8e\xa6\x50\x79\x9a\xc4\x0a\xed\xf6\x3e\x0a\x24\x45\x4d\xbc\x32\x9a\x24\x89\x1f\x8d\xd8\x0b\xa1\xfb\xa2\x38\xd0\xc8\x9a\x33\xf5\xf9\x55\x7e\x68\x22\xc4\x89\xf0\xf6\xd7\x57\x1c\x87\x2c\x94\xed\x5a\xb0\xfa\x91\xe2\xb2\x32\xbd\xe7\x69\x1a\x07\xb8\x55\xec\x56\xb3\xc7\xfd\xec\x69\xb9\x9f\x3d\xdd\xaf\x1e\x86\x78\x24\x4d\x13\x8d\x0d\x94\x73\xde\x44\xfc\x53\x8a\x34\x9a\xb2\xc4\x30\xb9\xb8\x06\x17\x01\x2c\xde\xd2\xec\xb6\xff\x49\x7f\x5e\x27\xe0\xfb\xb2\xc7\x71\x9b\xe5\x07\x68\x2b\x7e\x9a\x51\x29\x82\xd6\x62\xbf\x7d\x34\x9c\x50\x27\x3a\xb3\x2c\xf9\xa7\xfd\x59\xfd\xe5\x52\x73\x99\x60\x5d\x65\xfe\xe8\x44\xda\xb4\x14\x11\x76\xc3\x5a\x0b\xb2\x5f\xa5\x45\xb8\xaf\xf7\x1e\xb4\x22\x22\x0a\xaf\xd3\xe7\x2d\x5a\x20\xb9\x6f\x01\x29\x3c\xd3\x58\x5a\xc9\xc2\x19\x8f\x2b\xbf\x9d\xd9\x3a\xf4\x41\x39\xee\x55\x5a\x6e\x21\xcb\x1e\x0c\x1a\xb5\x09\x14\xa6\x43\x27\xad\x63\x81\xa5\xea\x1a\xeb\xc8\xa8\x30\x63\xdf\xfd\xd7\x2a\xcd\x0f\x4f\xf0\x39\xe2\x98\x6a\x9d\x10\x6c\x1a\x2f\x9e\x9f\xee\xd6\xf7\xfb\x97\xd5\xee\xf5\xe5\xa9\x3d\xc8\x04\x46\x4e\x47\xab\x2f\x31\x78\xa2\xe0\x79\xa1\x87\x0a\xe1\xeb\x97\x4d\x2f\xb8\x68\xfe\x6e\xe8\xda\x76\x5b\xb8\xea\xe1\x4d\x6e\xb2\xe0\x79\x71\x82\x2b\xc2\xfa\x69\xbd\x5b\xcf\xec\x0c\x73\x53\x0c\x3c\x8f\x52\x06\xed\xa4\x35\x48\xbd\x5b\x2a\xe3\xcd\x68\xc0\x9a\x21\x5a\xc0\xbc\x14\xe7\x0c\x6a\xdb\xd3\x72\x5b\x51\x7b\x5e\x61\xb8\x4d\xef\x45\xc5\x25\xd7\x83\x2b\xf1\x23\x86\x2b\xd9\x7f\xff\xb9\x18\xfe\x1d\x6c\x74\x91\x01\x2f\x27\x98\xf0\x6e\x98\x36\x28\x12\xfc\xec\x0e\xba\x8e\x63\x73\x48\xc7\x9d\x90\xe2\xee\x47\x0f\x97\xfd\x8f\xc9\x7f\xde\x3c\xf0\xbf\xf9\xa7\xfd\xf2\x80\x86\xac\x57\x30\xfd\x2f\x2e\xdf\x4f\xce\xd0\x13\xbc\x80\xf9\x08\xc7\xa8\x3e\xf9\x95\x57\xcf\xe4\x82\x02\x5e\x98\x78\xac\xd3\x36\x6a\xe2\x97\xca\x9d\x2d\xe2\x44\x48\xab\x2f\x07\xe5\xa3\x23\x09\x80\x17\x49\xe1\x5a\xb8\xe6\xc5\xbc\x96\x72\x02\x8f\x04\x02\x4d\xa7\x8e\xa6\xfc\xd1\x6d\x3c\xeb\xbc\x05\x70\x81\x47\x20\xc1\xf0\x8c\x57\x15\x94\xf5\x5d\xcf\x60\xbe\x9f\xe9\x83\x47\x34\x45\x78\xa3\x82\xaa\x2e\x8b\x8b\x2e\xca\x71\x4b\x1b\xbc\x98\x33\xbf\x25\x5d\x3f\xee\x36\xed\xab\xe9\xbe\x2c\x09\x38\xca\xbf\x6e\xef\xfa\x6e\x54\xe0\x25\x84\x52\xd2\xab\x34\xb5\x71\xcb\x4f\xeb\x1e\xe0\x25\x40\x1c\xcd\xe7\x1e\x4d\x81\x2f\xbb\xcf\x62\xea\x5e\x30\xcf\x68\xb2\x34\x2b\x4a\xb9\x4c\xb5\x4e\xe5\x39\x73\x2e\x53\xe0\xb1\x88\x22\xe4\xeb\xf1\xb7\x9f\x1a\x4b\x42\xea\x9b\xcc\x42\xdd\x95\xc5\xdf\x90\x2f\x20\x1b\xf6\x9d\xfc\x60\x48\xe4\x02\x8f\x07\x86\x74\x6f\x1a\x27\xb3\xb2\xe4\x17\x6c\x57\xfb\x3d\xed\x04\xf0\x38\xe1\x18\xbd\xcd\x51\xfe\x68\x3f\x7f\x5d\xfc\xb1\xda\xed\xb7\xeb\xff\x5e\xb9\x9f\x2b\x78\x88\x32\xc6\x18\x52\x37\xab\x9b\x8d\x6f\x6f\x6d\xda\xf6\x63\x32\xf2\xb0\xf5\x61\xf9\xc9\x46\x3e\x6a\xb8\x8e\x28\x66\xfc\xa6\x2d\xd0\x6c\x74\x17\x15\x57\xd8\x1b\x41\x35\xc6\xcf\x02\x37\x93\x01\xcd\x0e\x3c\x1d\x68\xac\xcc\x9a\x06\x19\x32\x4f\x7e\xc6\xbe\x02\xdf\x53\x49\x18\xf7\x54\x32\xab\x5d\x31\x37\x9f\x6b\xa7\x8d\xef\x7b\xbe\x1f\x0f\xad\xfe\x0a\x87\xb3\x06\x3f\xe0\x80\x35\x6f\x34\x60\x41\xed\xbb\xd9\xe9\x54\xa4\x79\x7d\x43\x5f\x1f\xfc\x90\xf9\xd6\xb8\xd4\x58\x88\xdc\xa5\x3f\x7a\xc2\xf9\xe0\x87\x3c\x31\x00\x00\x53\xc9\x7e\x81\xea\x54\xe4\x15\xdc\xa5\x65\x55\x7f\xe5\x99\xfe\xd2\xeb\xcc\x81\x1f\x0a\xdf\x37\x19\xf4\x21\xcd\x97\xe7\xfa\x2a\xa6\x1f\x3e\x06\x3f\x14\x1c\x81\x1f\x7b\xc8\x65\xa1\xcc\xc2\xba\x56\x5f\xae\x53\x7f\xf0\xa3\x90\x09\x67\x11\xb4\x1b\x26\xcc\xe0\x47\xc2\x3c\xce\x4f\x44\x15\xbd\x56\x50\xf6\x7a\x7c\xe0\xc7\xcd\xea\x61\x3e\xdb\x62\xaa\x76\x6f\x25\x54\x6f\x45\x0b\xc6\x1b\x3e\x5f\x3f\x4e\x0c\xa0\x69\x9f\x56\x4f\xc5\x13\x80\x5a\xe7\x96\x04\x8f\xae\x28\x8b\x81\x27\xe7\xaf\xe2\xa5\xe9\x49\xe8\xc7\x90\xc4\xc1\x08\xa6\xf8\x9c\xdf\x15\xd6\xeb\xdb\x32\x6d\x26\xf7\x04\x9f\x36\x21\x2b\xd2\x6d\xaa\x5e\xb6\x0b\x3e\x65\x09\x76\xd3\x8c\x1d\xf6\xac\xae\x5b\x22\x26\xf8\x49\xc0\x84\xb3\x1c\xcf\x8d\x95\xa6\x44\x88\xbf\x8d\xd8\x56\xf9\xb5\xf8\x0e\xf8\x49\x4c\xa4\xea\x60\x34\x35\xec\x83\xb8\x8f\x8d\x02\x3f\x49\x7c\xd4\x14\xcd\x78\x55\xdb\x12\xbf\x3b\xa2\x62\xa3\xf0\x53\xe4\x1f\x50\xd6\xbb\x62\x35\x5e\x28\xfd\x44\x27\x01\xef\x51\x0e\x3f\x40\xdd\x9d\x73\x35\x0a\x12\x7c\x16\x68\x8c\xc1\x4e\xbc\xac\x60\x9d\x1b\xf1\xa9\xa9\x9e\x2c\xf8\x8c\x18\xd5\x9e\x1e\x6d\x6c\x33\x7b\x18\x6f\xed\x3e\xd3\x11\xb6\x6e\xbf\xad\xb6\xbb\x26\xe7\x5a\x3c\xac\xef\xee\x46\x99\x17\xf8\xc2\xe3\x8e\x98\xe5\xcc\x49\x87\x3f\x4c\x90\x04\xeb\xb9\xfd\xc2\x68\xfb\xe1\xd8\x73\xd7\xb6\xf9\xb6\x59\x5c\xd0\x15\xe3\xdc\x37\xf0\x6a\xc6\x98\x72\xfa\x01\xea\x6f\x90\xab\x02\x01\x2b\xe3\xef\xe0\x80\xa5\x47\xc9\xb3\x4c\x17\xe5\x1b\x64\xa7\xd1\x5d\x94\x84\xa3\x49\xeb\x76\x40\xb1\x7f\x7d\x59\x5f\xad\xe1\x83\x27\x27\x99\x8f\x22\xa2\x56\xa8\xdf\x25\x7a\x56\xb4\xb0\xef\x1a\x3c\xfc\x41\x52\x09\xa4\xfc\x3c\x16\xea\x9c\x8d\x7f\xad\x04\x62\xb4\x2c\x9b\xbc\xed\xb9\x4f\xa6\x19\x9d\x45\x05\x01\x3e\x81\x39\xcf\xdf\x7b\x0c\xda\xe9\x09\xaf\x22\xea\xa9\x7e\x8a\xb6\x4c\x25\x18\xe1\xbb\x1b\x8b\x8b\xe2\x04\x65\xc4\x4d\x41\x64\x7e\x59\x9d\xcb\xdd\x8f\xe1\xcc\x55\x52\xe0\x8e\x3f\x73\x7d\xe4\x56\xc4\xf9\x2a\x49\x76\x71\x39\xf8\xe0\x99\x08\xd2\x10\xac\x67\x79\x7a\xe4\x59\xf5\x97\x2d\x0a\x0d\xaf\x10\x84\x40\x41\x2a\x7e\x3e\x1c\x53\xd4\x3d\x87\xf2\xa3\x5b\x5c\xb5\x17\x63\x47\x7f\xfd\xe7\x7a\xf6\xf4\xcb\x16\x03\xf8\xda\xf7\xb5\xc5\x84\x3d\x89\xb4\xee\xb3\x72\xc1\xd7\x31\xc7\x02\x88\x55\x8c\x68\x66\xd1\x14\xc3\x07\x7c\xad\x42\x14\x24\x42\x0f\xea\xd5\x31\xad\xe7\x67\xad\xed\x4f\x0a\x7c\x3f\xa0\x4e\xff\x62\x53\xa6\x46\xd9\xbb\x1f\xb4\x06\x7e\x48\x2d\x76\x7a\xf5\xb2\xbf\x5f\xed\xf6\x9b\x97\x6e\x3f\x0e\x9a\x25\x06\xfb\xd6\x55\xa1\x9d\x33\xd3\x17\x93\xd9\xf4\xca\x29\xcd\x38\x4d\x8d\xab\xb0\x1c\x9c\x3d\xd0\xd2\x80\x58\xaa\xea\xdc\x2c\xcb\x0f\xbc\xaa\x1f\x0b\x95\xea\x74\xbc\x41\x07\xa1\x17\x53\x0b\x20\x79\x41\xea\xd9\xf8\x38\x31\x25\x2c\x0d\xf2\xed\x5b\x81\x7b\xd7\x39\xab\xef\x8a\x9e\x12\xc3\xe8\x03\x22\xc0\xf5\x58\xba\x76\x2d\xac\x17\xcf\x03\xd9\xf4\x66\x0c\x07\xee\xd6\x83\xea\x6d\x7e\xf9\x5e\xa6\x3d\xc7\xe7\x7f\x8c\x6e\xf9\xe8\xaa\x43\x19\x23\x88\x60\x0e\xf5\xf7\x1b\x3e\x48\x10\x44\xc4\x93\x7e\x5f\x9d\xc9\x82\x6a\x07\x1e\x65\x10\x10\xcf\xc0\xd4\xc5\xf9\x72\x57\x16\xc7\x39\xcf\x7e\x5a\xd2\x85\x80\x44\x04\x35\xe1\x4e\x56\xcf\xba\xf9\x94\x21\x8a\x0d\xbf\x9f\x80\x87\x32\x6e\xd6\x02\xdc\x7d\x5f\xec\xc5\x61\xd7\x2e\x52\x30\xcb\x55\xcb\x83\xf3\xa7\x39\x34\x10\xc4\xbe\x09\xe0\x9a\x19\xb0\x2b\x5e\xd7\x79\xfd\x65\x98\xe6\xa2\x5d\x27\xf6\x41\x66\x87\x32\x45\xd4\xd3\xb2\x90\xe7\x63\x87\xaa\x85\x20\x8e\x22\xd9\x52\xa2\x8b\x72\xaf\xa1\x7d\x1c\xb1\x54\x98\x9f\xcd\x3a\xcb\xb3\xd1\x55\xc7\x8a\x7b\xe6\xaa\x9b\xed\xee\xde\x64\x09\xdd\xe7\xad\xbf\x85\xc3\xd5\xcf\xe6\x6b\xbc\x28\x7b\x98\x92\x00\x99\xee\xdb\x34\xfb\xe8\xee\x04\xa5\x5c\x18\x99\xd7\x26\x3a\xff\x9c\x19\x99\xa2\x2f\xbd\x6b\x4a\x3c\xc3\x8f\x2e\x9b\x5d\xaa\x65\x36\x0e\x6b\xac\x10\x24\xa1\x87\x98\xe2\x0d\x3f\xa3\x44\x67\x4b\x65\x5a\x1f\x4f\x59\xf3\xc7\x89\x5c\x77\x72\x3d\x0e\x12\xe5\xe3\x5b\x83\xa2\xfd\xfb\xef\xb3\x6f\xab\xa0\x2f\xff\x06\x01\xd3\x12\x5f\x5a\x57\x96\x5a\xf0\xd3\xf6\xba\xfe\x6c\x07\xf3\x08\xf0\x3d\x40\xb3\x98\x5c\x2d\xbb\x56\xec\x4f\x1b\xb0\xa3\xb3\x88\x38\x88\x3a\xd9\x92\x47\xfe\xe3\x31\xc5\x1c\x9e\x97\xcd\xb5\xfe\x5e\x55\x0d\x02\x19\xfb\x58\x30\x43\x6d\xe8\xc1\xe2\x1d\x48\x4e\x48\xe8\xb4\x89\x8d\x2a\xc6\x8d\x0b\x92\x12\xf0\x29\x6f\xf8\x25\x83\xaa\x7a\x4c\xf3\xb4\x3a\x65\x69\xfb\x2a\x49\x90\x81\x71\x20\x2f\x44\x5a\x0f\xd6\x23\x95\x30\x2c\x9c\x9f\x4a\x58\xcb\x9e\x84\xcf\xf0\xfe\x2b\xce\xa8\x2d\x85\x36\xc1\xe7\xfc\xd2\x6a\xa4\x0d\x27\xa3\xe2\xd2\xb7\x34\xa6\x27\xf8\xfc\x13\x0b\xf1\x45\x3e\x5e\xa7\xff\x31\xda\x09\xa6\x0e\xb7\x73\xe9\xc6\x7d\x53\x32\x46\x86\x9e\x6b\xf7\x6c\xac\xa3\x62\xb7\x10\x56\x37\x5e\x18\x08\x3d\x24\x29\x9d\x9a\x0d\x2d\x98\xa7\x2e\xf5\x08\x80\x28\x8c\xc0\xb7\x9f\xfc\x74\x69\x43\x9d\xe9\xf7\x1e\x94\xf4\x4d\x95\xc5\x88\xf5\x18\xc5\xcb\x36\x8d\x09\xb4\xd2\x9e\xe8\xd7\xb6\xae\xf3\xdc\x2b\x5d\x31\x08\xb4\x8e\x64\x5b\x08\xd9\x16\xd9\x15\x04\xc3\x8c\x0b\x7d\xc5\xb1\xd7\xa8\xd2\xca\x22\xd7\xe7\x97\xf9\x64\x2e\x1f\x06\x3c\x36\x58\xc6\x73\xf5\xb6\x5e\x3c\x0f\x97\xc2\x30\x90\x11\x76\x49\xf1\x0b\x27\x1c\xf4\x21\x0c\x03\xb3\xbc\x08\x2e\xdf\x97\xb3\x97\x3b\x0c\x36\x7a\x12\x8a\x10\x86\x5c\x59\xb3\x14\xac\x90\xde\x35\x4b\xc2\xd5\x69\x48\xc8\x49\x6b\x60\xe2\x62\x21\x6c\xa1\xdd\x15\x0e\x2a\x7a\xf7\xd7\x8d\xcb\x25\xa1\xc2\x40\x67\x6f\x93\xb4\x27\xf8\x51\xdf\x43\xee\x4d\x64\xff\x21\x21\xa1\x67\xe3\xd9\x66\x8e\x76\x61\xd7\x94\x50\x35\x84\x24\xf1\xa2\x8e\x68\xee\xe8\xed\x93\x53\x2e\xa4\x3a\xf0\x3b\xf5\xeb\xec\xe4\xd3\xd1\xc9\x12\x06\x1e\x6b\x4b\x6f\xc3\x12\x22\x84\x09\x28\xc4\x14\x1a\x21\x96\x01\xe0\x0b\x42\x16\x4b\x6a\xbd\x51\xea\x15\x2f\x33\x34\x6b\x30\x76\xf8\xd3\x8b\x92\xfb\x1c\xf3\x7b\x26\x3b\x50\x3a\x01\x89\xbd\x3b\xb1\x08\x22\x43\xa6\x33\x96\x77\xf3\x67\xb7\xfb\x4c\x92\x70\x21\x94\x61\xe8\x30\xa5\x33\x6c\x00\xff\xd7\x59\x1d\x9a\xf1\xf3\x4b\x13\x78\x5f\x46\x97\x2c\x23\x92\x58\xbd\xe2\xf6\x7a\x7f\x1a\x22\x84\x92\xb4\xda\x0e\x3b\xe0\xc7\xb5\x1a\x2c\x7a\xa1\x24\x0a\x77\x24\x01\xb2\x38\xc2\x36\xe7\x69\x66\x6c\xbf\xdc\x05\xc9\x98\x2b\xdb\x3b\x96\x59\xcf\x25\xfb\xa6\x2d\x12\x84\x92\x89\xd8\xa6\xc7\x6b\x59\x4c\x66\x81\xa1\x04\x43\x5f\x31\xf6\xce\xe6\x1a\xa2\x5e\x69\x1d\x42\xe5\x79\xb8\xe7\xb9\x4a\x17\x96\xd6\xa7\xb1\xde\xa3\x7b\xaa\x3c\x8a\xbc\x5c\x05\xb6\x87\xd3\x2c\xb3\x79\x5d\xdc\x9c\x69\x2a\x08\xb0\x50\x62\xa0\xf3\x7b\x93\x8c\xf7\xed\xa8\x21\x04\x0f\x10\x47\x8e\x74\xae\x97\x45\xe0\xfd\x8a\x1e\x0c\x21\x70\x45\x5b\x95\xd2\x12\xd4\x59\xc2\xb1\xcf\xa8\x19\x0e\x8f\x7c\xe2\x63\x9d\x79\x53\x16\xbd\x5c\xfa\x8b\x3b\x4a\x3d\x5b\xaf\x74\x5c\xb4\xa1\x23\x5e\x33\x42\x63\xdc\x83\x38\xc2\x9f\x4d\xe2\xc8\x17\x81\x73\x5c\xb6\xd5\x78\xf4\xfd\xe3\xfd\x8d\xc8\xad\x91\x51\xe0\x13\x2c\xa9\x94\xc0\xd5\xbe\x04\xc9\xab\x7a\x2f\x51\x22\xcd\xfd\xb4\x80\x30\x30\xbd\xe0\xc7\xbc\x3e\x3d\xa6\x87\x92\x8f\x3b\x65\x10\x05\x52\x04\xaa\x57\x8b\x72\x7d\xcd\x09\xe2\xe1\x74\x4c\x12\x05\x8a\xfb\xa4\x65\x32\xa9\x69\x07\xbb\xd1\x95\x86\x44\xc7\x62\xdc\xb8\x0a\xdd\x0f\x0f\x05\x60\x04\x5a\xd5\xbc\xac\x97\x50\xd5\xa5\x2d\x2e\xd9\xe3\x51\x10\x21\x3a\xa4\x02\x2c\x44\x1e\xaf\x58\xf1\xd3\x5f\x1a\xf1\x38\x8e\x7a\x25\xb0\x6e\x4d\xc4\x50\x70\xd4\x12\xbb\x71\x0e\x15\xa1\x4c\xde\x63\x91\xcb\xb4\xc8\xfb\x21\x44\x44\x02\x0f\x4b\x6c\x7b\x0b\xe9\x29\x27\x38\x26\x10\x11\xc9\x98\xf1\xe5\x41\xf5\x9c\x74\x53\xf4\x8a\x98\xa3\x98\x39\x8a\xbd\xc0\xa9\xf2\x4d\x88\x1a\xb9\x41\x31\x75\xaa\xc9\x8f\xfc\xc7\x43\x51\x55\x33\x5d\x43\x39\x8d\xd9\x3b\xdf\x44\xdd\x40\x44\xb9\xe9\x9a\x1e\xcf\x59\x9d\xda\xfa\x2a\xa2\xe9\xc7\xf7\xe6\x3c\xfa\x98\x29\x45\x61\x09\xdc\xca\xe8\xba\xdf\x46\x65\x82\x9d\x69\xeb\x01\xef\x8e\xfe\xb4\xd0\x1c\x51\x15\xa2\x2e\xcb\xeb\xf6\x67\xdc\x18\x88\x18\x67\x48\x13\x82\xfa\xed\x3e\xfd\x18\xf5\xa1\x21\x62\x82\xbb\x1e\xe0\x2b\xf6\x19\xd7\x0a\x72\xeb\xe3\x39\x7e\xca\xa3\x4f\x2a\x85\x56\xa3\x6f\x3c\xfb\x80\x15\xca\xc4\xf7\x6a\x6f\x11\x03\x16\xb1\x9e\x70\x81\x71\x99\xcb\xab\x73\xd9\x04\xa7\xad\xaf\x5a\x62\x68\x0e\x93\xff\x6b\xe1\x91\xe3\xbf\xda\xaf\xe0\x21\x97\x2d\xd2\x00\xe4\xc4\x0e\x1f\xf1\x10\xb0\x62\x85\xb3\xac\x99\xcf\xaf\xa7\xab\x34\xc2\x0e\x15\x49\xa4\xb4\x65\xf6\xa6\x03\x54\x90\x1d\x20\x43\xe6\x9a\x0a\x8f\xfc\xc7\xac\x84\x9c\x3f\xe7\xb0\xe4\x97\xf1\xb8\x58\x60\xd3\x60\x6f\x15\xc1\xff\x37\x89\x42\x24\x39\x8f\x8d\x35\xf4\x4c\x34\x5b\xba\x5b\xc3\x23\x09\x80\x11\x41\xee\x64\xec\x9c\x71\x5a\x3b\xc5\x55\xc0\x11\x78\xb8\x47\xbe\x6c\x1f\x13\x04\x91\x8a\x03\xcd\x3a\x0d\xc3\xfc\xf0\x47\x6f\xfe\x29\x95\x28\xd6\xe3\x61\x18\x9b\x48\x9e\x8d\xae\x0b\x22\x8e\x95\x4d\xf8\xe1\x2c\x03\x5f\x2c\xd4\xfd\x6a\xc1\x84\x58\x68\xab\x86\x7a\x86\xc7\xf4\xda\x8a\x74\x74\xd5\x00\xc1\xb0\x90\x9f\x9e\xae\x6f\xd8\xd4\x29\xa6\x91\xb3\x10\x69\x0a\x68\xf5\xff\x47\xf3\x43\x07\x2b\x10\xf1\x7c\x89\xf9\x8f\x25\x4c\x6d\xa1\xae\xb3\x11\x17\x12\x88\x27\x25\xb5\x5a\x78\xf7\x25\x40\x07\x8c\x6b\x0e\x41\xec\xb5\x6e\x29\x85\xca\xd2\x1c\xab\x07\x1b\x24\x00\xdd\x48\x24\x88\x4f\x8d\x43\xb3\x6d\x0f\x62\x42\xeb\xce\xe8\x4b\x92\x74\x46\x9e\xd6\x8e\x7c\xa0\x69\x6d\x07\x06\x00\xd4\x6b\xdb\x7b\xa8\x40\x39\xa5\x79\x6b\x47\x87\x9e\x17\xd0\xae\x81\xdf\x32\x3c\x46\xa3\xac\x59\x3d\x4a\x4d\x9a\xc0\x10\x6d\x4e\xf0\x0b\x66\xb9\x1a\x45\x40\xff\x18\x7d\x9a\xf2\x24\xe8\xe4\x01\xfa\x0c\x7e\x20\x11\x4b\x70\xd3\x3b\x41\xc7\x26\x1c\xc0\x66\x80\x44\x82\xa0\x03\xcf\xfb\x45\xa0\x12\xb3\x2b\x36\x10\x12\x06\xa4\xc5\xdc\x38\x68\xc3\xf7\xa2\xbc\xd1\xa2\x20\x24\x96\x88\xd1\x59\xa4\x25\x56\x44\xd3\x62\x60\x09\x06\x84\xb0\x30\xb0\x71\xc3\xd3\x0d\xec\x3c\x90\x38\x00\xd3\x0e\x6c\xb2\xa4\x66\x35\x1c\x12\x6f\xcf\xd3\xe2\x1a\xa3\x7b\x12\x53\x82\x44\xc1\xba\xe8\xec\x19\x80\xc4\x10\x84\x81\x5b\x3d\x9a\x70\xfe\x68\xfc\xef\x47\xd7\x11\x6b\xc2\xed\x23\x6e\xd6\x54\xbb\x56\x8e\x06\x51\x2b\x29\x73\x80\x7a\x9b\x15\xb5\x55\xf4\x9c\x7e\x42\xcd\xd8\xce\x00\x64\xc3\xd3\x41\x29\xdb\x0d\x22\xdc\x0a\x02\x20\x11\xd7\x0a\x47\x0f\x27\x5f\xe2\x13\x6e\xf1\x53\xa3\x04\x96\x24\xca\xb4\xfb\xeb\xf4\x08\xd8\x11\xb2\x46\xb4\xf6\x30\x63\x04\x55\xa9\x4c\xf1\x63\x55\xbf\xed\x8a\xd7\x4a\xdd\x54\x19\x01\xc2\x23\x08\x94\x63\xb4\xe0\xeb\x60\x0d\x8c\x4c\x33\xc4\xd9\x09\xfc\x56\x47\x96\x70\xde\x22\xb3\x9a\x24\x0f\x09\x0d\xcf\xf9\x6d\x5b\x38\x20\x82\x87\x16\x6d\x6e\x2a\xd4\x1b\x28\x5f\xf3\x61\x29\x84\x28\x92\x20\xf4\xef\xaf\xff\x9e\xff\xd5\xfe\x8d\x1b\x0b\x87\xfd\x7f\xce\x30\xf9\x46\x82\x9f\x90\x96\x37\x3f\xef\x5e\x14\xa0\x80\xfc\x58\xc8\xd5\x7a\xf1\xec\x47\xee\xef\xda\x37\x30\xd5\xcd\xcb\x6a\x3b\x7b\x58\x6d\x1e\x5e\xb7\x9d\x13\xe5\xea\xdb\xaa\x1d\x17\x40\x92\xb4\xe2\xda\x83\x1c\x89\x68\xed\x93\xc8\x08\x92\x95\xe7\xb4\xfe\x0a\x65\x71\xd7\x96\x0c\x63\x2f\x90\xb1\xd1\x3d\xd9\x9f\x6c\x51\x64\x5f\xd9\x6c\x52\xb5\x83\x94\x6f\xb9\x60\x86\x2b\xd6\xfe\x1d\x54\xd2\x69\xaf\x34\x37\xf7\xbe\x2c\xce\xa7\xe9\xc0\x3d\xf6\x03\xa6\x88\x5b\x68\x8a\x63\x71\xdb\x9c\x00\x62\x3f\xf4\xc2\x5e\xf9\xfe\x6c\x74\xb2\xb6\x3f\x33\xa6\xfc\xe9\xb6\x1a\x07\x7e\x84\x77\xf2\x61\xb9\x1b\x39\x16\x41\x1c\x70\x8f\xf7\x37\x1f\x5c\xcc\x4b\xa8\x0f\xe6\x6e\x4e\xff\xc2\x30\x34\x75\x61\xc7\xf6\x5a\x59\x36\xca\x3c\xcd\xb2\x9b\xc2\x40\x3f\xff\x8d\x21\x05\x62\x5b\x29\xa8\xe5\x68\xdb\xaa\x13\x41\x68\x1c\x2a\xea\xf9\x6d\xf1\x00\x09\x85\x4e\x12\x7c\x78\xce\x88\x86\x2c\x72\x82\x9f\xfc\x68\x5a\x44\x53\xda\x7d\x10\x47\x2a\xd6\x9d\xd0\xdf\xf4\x18\xe2\xc5\xce\x0d\xf8\xb5\x52\x8f\x79\x39\xfa\x3a\x22\x44\x6c\x44\xf2\xaa\xb7\xaf\x69\x85\x59\xab\x3d\x14\x33\x19\x58\xaf\x0f\x24\x74\xfe\x5e\xc9\x33\xa6\xc4\xd4\xb4\x6f\x95\xd8\x6e\x8a\x2f\x4d\xe6\x61\x31\x25\xda\x0f\x3b\xc7\xa2\x14\x32\x35\x33\x90\xb4\x0e\x53\xee\x86\x72\x1f\xf5\x66\x5d\xd1\xb0\xa7\x4f\xd4\x1c\x24\x91\xb1\x47\x52\xb3\x41\xde\x15\x27\x54\x60\xe6\x5f\x03\x3f\xca\xf6\x8f\xc2\x74\xdf\x0e\x4d\xa4\x6a\xa3\x27\xd4\x39\xe4\x57\xf2\x2b\x10\x27\x10\x24\xa4\xdd\x3f\x30\x8e\x6b\xcf\xa3\xa9\x2b\xb8\x98\xad\x76\x7e\x56\x87\x5b\xa5\xeb\x98\x49\x86\xb7\xbc\xc8\x0d\x12\x65\xb8\xe6\xdd\xf8\x8c\xe2\xb8\x5d\x60\x3f\x6c\x59\xf2\xcf\x9b\x81\xab\x4b\xb2\x63\xee\x49\x65\x37\x06\xfc\xc1\x00\xd8\x0b\x99\xbb\x1f\xcd\x55\x8c\x1d\x8b\xb4\x42\x4a\x24\xda\x5b\x0d\x82\xa3\x58\x48\x6e\x04\x67\xb2\x6c\x07\x55\x4d\xdd\x27\xa5\xcf\xb0\xab\xf3\x15\xb2\xf4\x87\xd3\x29\x73\xc7\x34\x43\x42\xd7\x1f\xe5\xe5\x54\xa7\xb2\xf7\x04\x54\x14\x22\xa6\x73\xf6\xb0\xd8\x2f\x57\x8b\xf5\xe3\xec\x61\xdb\x1e\x93\x4a\x18\xda\xf0\xc9\xfd\x09\xbc\xc8\x39\x0d\xa7\x47\x9e\x7d\x87\x74\xf7\xb0\xf1\xdd\x51\xed\x29\x0c\x70\xac\xa2\x84\x49\xb3\x8b\xd2\xf8\xeb\xbb\x31\xbe\xf0\x4c\x9c\x83\x3d\x29\x03\x86\x2b\xdb\xa3\x01\x8f\x0d\x01\xa6\x96\x6f\x70\x23\x3e\x8c\x35\xe8\x28\xea\x95\x18\xfe\x3c\x17\x9d\xe0\xa9\x19\x43\x3d\x8f\x69\xb7\xed\x37\xb1\x4d\x3a\xae\x9c\x52\x2f\x92\x3e\x2a\xcf\x7c\xff\xf3\x5a\x6e\x12\xa8\xc7\x7d\xc4\xaf\xfc\x91\x66\xd9\x98\x41\xe6\x86\xe8\xc8\xb7\xb2\xc5\x4f\xf0\x79\x57\x94\xef\x2f\x70\x3a\x1b\xce\x45\xa7\x97\x06\xd4\xe7\x80\xae\x71\x0f\x69\x13\x3e\x2f\xb8\xac\x1d\xf5\x06\xa8\x2f\x00\x57\x89\x63\x91\xf3\x52\xbe\xf5\x1f\x1b\x0d\x02\x4a\x0d\x71\x04\x27\xc9\xee\x72\x1a\xb5\x05\x68\x40\x19\x16\x21\xdd\x9d\x70\xc1\xdf\x1d\x58\xf5\xd1\x09\x55\xac\xc9\x7d\x9c\x06\x5c\x22\x90\x39\x87\xcf\x89\xdc\x90\x06\x40\x7d\x93\x92\x2f\x53\xe8\x77\x8f\x69\xa0\x43\x61\x0b\x95\x46\xae\xfe\xcb\xa4\x2e\xc7\x64\xda\xfd\x8f\xa9\xc0\x92\x86\x42\x63\xe9\x55\xc1\x07\x64\xc5\x09\x4a\x53\xce\xa9\xe1\x47\xbd\x77\x2b\x42\xb5\xcf\xd2\xfc\x7d\x20\xc3\x0c\x34\x84\x10\x41\x4c\xa7\x12\xb2\xf4\x98\xe6\xbc\xbc\xdc\xf3\x23\xf4\x0c\xc6\x2c\x67\x16\x68\xa8\x29\x12\x3b\x5d\xfb\xce\xda\x4b\x16\xc7\xdd\xec\x65\x7a\x17\xa3\x51\x20\x63\xa3\x77\x95\x65\x69\x91\xaf\xf3\x45\xaf\xd5\x48\x23\xed\x21\x52\xc8\x40\x00\x57\xff\x99\xda\x8a\x28\xa1\x1a\xc5\xe8\x32\x5e\x19\x41\xe1\x7e\x15\x80\x92\x84\x63\xeb\x63\x8f\xd6\x14\x08\x16\xea\x40\x0d\x6e\x8c\xd2\xba\x59\x1f\xee\x65\x91\xe6\x9b\xb2\x70\x82\x68\x40\x89\xd6\x26\x76\x39\xe7\xa3\x6a\xbb\x1d\x10\x6b\x43\x3f\x36\x09\xd1\x01\x9e\x4f\x80\xbe\x4c\x2e\x61\x49\x06\x3d\x46\x4a\xa9\xc0\xc5\x0d\x9d\x4e\xee\x8a\xb2\x57\xa3\xa4\x94\x2b\x65\x13\xb4\x82\x2b\x23\x73\x70\xb3\x2f\xe7\x3e\xa3\x09\x10\xe7\x07\x51\xd5\x3b\x5c\xb0\x1f\x9a\x47\x3c\xfa\x9d\x89\x47\xf0\xcd\x45\x2d\xb3\x6d\x7a\xe8\x0b\x3e\x01\x4d\x62\x49\xac\xcd\x55\x93\x2a\xbd\xe6\x0a\xca\x0a\xd5\x9c\x07\x53\x81\x09\x8d\x4a\x0f\x87\x54\xd7\x8b\x42\xc1\x94\x54\x0e\x50\xc1\x35\x16\xd9\x5f\x2c\xe3\xd3\x7a\x0c\x4e\xee\xe7\x54\x68\x8f\xc0\xd0\xcc\x3a\x76\xbf\x4a\x4a\x81\xe0\x87\xc5\xe2\xa9\xfd\x93\x62\x8c\xf5\x82\x9e\xbb\xa2\x5c\xf7\xfd\xf7\x4d\x3a\x64\x07\x2b\x9f\x38\x7d\xe1\x05\xcf\xae\x45\x0c\x26\x37\x6e\x37\x97\x55\x42\x9d\xe5\xc0\x5d\x09\x80\x19\x5f\xe9\x4a\x98\x57\x5b\xd2\x75\x77\x8c\x82\x9f\x50\x23\x05\xab\xf6\xef\x17\x79\xb5\x52\x82\xe0\xad\x40\x09\x22\x1c\xe4\xc5\x52\x61\x86\x4f\x4e\x7b\x0a\xd9\x03\xcb\xed\x6e\x3f\x7f\x7e\x7d\xda\x39\xec\x74\xe2\x79\x51\xd2\xfa\x09\x36\xf9\x41\xd5\x99\x36\x43\xe2\x05\x8a\x1a\x37\xa2\xc7\xaf\xbb\xa9\x66\x59\xe2\x33\x0f\xd5\xfe\x9a\x9d\x65\xff\xe1\x36\x9c\x24\x20\x01\xca\x42\xba\xb7\x38\x1b\x30\xdf\x21\x09\xbd\xd0\xf2\x9f\x5c\x46\x32\x61\x4d\x77\x0d\xfb\x6f\xcb\xa5\x49\xe8\xfb\x4a\xd8\xc2\x30\x26\x6b\x0e\x5e\xb9\xe1\x65\x9d\x8f\x24\x95\x9a\xe1\x01\x02\x30\x3e\x4c\x95\x1d\xec\xd4\xed\x43\x81\x06\x4b\x5d\x12\xc6\x0c\xb5\x9a\x8c\x50\x73\xdf\xb8\x1f\x92\x90\x1a\x8a\xdc\x53\x9a\xff\x9b\x77\x82\x0b\x90\x44\x42\x3b\x9f\x06\xb7\xde\x0f\x38\x73\x6e\x98\x24\xb8\x1a\xea\xf4\x07\xa8\xd5\x8f\xd3\x6b\x5e\x71\x3d\x12\x97\xb0\x43\x49\x18\x13\x3b\x83\x5e\x10\xfe\xd7\x6c\x37\x30\xe0\x3b\x41\x42\x62\x8a\x54\x23\x04\x0e\xca\xf6\xaf\x2c\xc2\xe2\xcf\xa6\x99\x6c\xe9\x86\x97\x19\xfc\xdd\xdf\xc4\x92\x38\x0c\x91\x74\x6c\xb4\xa0\x91\xf7\x85\xe2\x36\x43\x89\x96\x38\x72\xb3\x31\x89\x15\x98\xb0\x13\xaa\xfa\xff\x8c\x26\x3e\x2c\x41\xdc\x52\x18\xbd\x06\x68\x25\xd4\x23\x98\x76\xd5\x6f\x65\xf1\xf9\x9c\xaf\x73\x59\x1c\x4f\xbc\x4e\xc5\xd8\x1b\x0b\x12\x0a\x80\x51\x2a\xe4\xea\x65\xe1\xfe\x98\x78\xb1\x26\x6d\xaa\xe1\x00\xc5\x93\x1b\x6e\x92\x04\x1a\x6c\x80\x82\x4f\x6f\x96\xab\x79\xf1\x63\x34\xef\x13\x2d\x51\xd3\xdc\x60\x89\xaa\xc9\x77\x83\x05\x21\x96\xae\x96\x8f\x0f\x7b\x63\xf9\xda\xa7\xc6\x34\xc7\x89\x6e\x2d\x26\xa1\xaa\xef\x00\x86\x80\xa0\x84\xf1\x18\xa7\xed\xe3\xec\xaf\xfd\xec\xe1\xe1\xf9\xfb\x6a\xb9\xdf\xee\x66\xf7\xab\x7d\xfb\xa6\x71\x6a\x54\x8d\xf7\x69\xf5\x50\x7c\x42\x29\x79\x05\x0f\xd0\x6c\x33\x7d\xdd\x4f\x48\x44\x40\x3d\x63\xf0\x88\xad\x2b\x30\xee\x55\xf7\x90\xa3\x44\xe8\x70\xf9\x1a\xdd\x10\x11\xc7\x56\x6f\xb5\x5e\x35\xf1\xbe\x84\x17\xf8\x48\x8d\x06\xe5\x20\xea\x49\x04\x08\xea\x3b\xe4\x63\xd9\x8c\x18\x2b\x8b\x42\x22\x05\x20\xa0\xf8\xa1\x38\xcc\xd3\x56\xb1\xe5\x17\x11\x7d\xa2\xe2\xc8\x35\xb9\x53\x5d\x14\xaa\x35\xd4\x9c\xdc\x12\x12\x95\x48\x6a\xe5\xe7\xb6\x6f\xc5\x39\x53\xf7\x2e\x03\xef\xf5\xeb\x12\x88\x39\x8a\x73\xfe\xe7\xcc\xcb\xf2\xb2\x40\x0f\x88\xd1\xbb\x0a\x8c\xa1\x11\xf0\x39\x3f\x71\xf9\xde\x83\x34\x0c\x2f\x5c\x47\x46\xe6\xf3\xe5\xf9\x9f\xf3\xe7\xb5\x01\x3d\x0f\x5e\x36\x1d\x09\xe1\x84\xdf\xd5\xf7\x34\xdf\x20\x7a\xea\x7b\x9a\x1b\xed\xc4\x76\x98\x30\x0e\xbe\xd6\x43\xf8\x91\xff\xe8\x88\x0d\xa3\x9f\xc6\xbc\x44\x60\x31\xf6\xc4\x2f\x57\x0d\xe8\x5b\x2f\x62\x2f\x3e\x64\x9e\x0e\xb1\x55\xf0\x7d\x33\xfb\x67\x6f\x15\x63\xbe\x0a\xa9\xf9\x0d\x47\x9e\xd7\xa9\xb4\x4f\xb2\x87\x0c\xfb\x57\x68\x97\x04\x16\x78\x46\x79\xdb\xa8\x2e\xcc\xf2\xea\x13\xca\xf9\x65\x56\x8a\xb4\x36\xa0\xcb\xf1\x3b\x3e\x78\x4c\x2c\x20\xc6\x76\xc4\x61\x11\xf8\x35\x95\xf1\x06\x80\xe6\xff\xa8\x80\xc2\x42\xaa\x79\xe4\x66\xb2\x7a\x4c\xf3\x6b\x97\x66\x60\x11\xf3\x09\xb3\x5b\xcb\x23\x54\x15\x3f\xc0\xae\x70\x0a\x79\x13\xcd\x29\x16\x01\xf1\xa2\x9e\xd3\x83\x0d\xda\x06\x63\x88\x6f\xaa\x4f\x9a\x5f\xea\x37\x17\xae\x31\xc2\x09\xee\x9e\x6f\xbc\x6e\xff\x24\x85\xb2\xec\x2e\x44\xfb\x57\xcd\x1b\xe2\x9c\xd3\x87\x3f\x94\x80\x44\xb2\xce\xa9\x38\xc9\x26\x3e\xec\xf3\xd7\x80\xc5\x09\x47\xd9\xc9\xd3\xb9\xde\xd6\xb2\x39\xcb\xbc\x2e\x6e\xe1\x09\x7f\x79\x1f\xa7\xd6\x6a\xbb\x49\x31\x1a\x78\xa4\x33\x36\x9b\xdc\xc9\x7f\x73\x83\x68\x4f\xa8\xb1\xef\xb1\xaf\x8b\xc7\x5e\x25\xca\x1d\x15\x12\x97\x4d\xb3\x21\x1a\x43\xa4\x7b\xdb\xe8\x55\x53\xbb\x28\xa3\x10\x61\x89\xef\xc8\x7f\x2c\xf8\x69\xff\xb8\x6e\x57\x58\x46\xc1\x14\x1d\xdf\x78\xb5\x79\xeb\x29\x76\xdb\xc3\x89\x9f\x20\xcf\xcd\x74\x1f\xd4\x6b\xde\x24\x6e\x15\xfc\x96\xb0\x31\xb0\x84\x48\x61\xd4\x1b\x2e\xe3\x2e\x08\x4b\xb4\x8f\xb8\xd1\xda\xe8\xa1\x1b\xb1\xca\xf4\x6f\x58\xeb\xa7\xa2\xc6\x08\xbb\x6a\xfb\xfb\x8c\x79\x11\xe3\xa3\xe2\xde\xef\x51\x79\x18\x0b\x0c\x3d\xd5\x82\x5e\x9f\xf5\x2c\x1b\xa5\x2e\x8c\xc5\x0c\x69\x5d\x9b\xc7\xd5\xee\x67\x5d\x58\xc6\x43\xd3\x56\xb7\xb5\xd5\x87\xb1\x8e\x2d\x30\x41\x75\x60\xa4\x50\x7e\x98\x98\xa9\x35\x48\x07\x26\x3a\xcc\xc3\x62\xbb\xb0\x0d\x22\xab\x28\x31\x3a\x8b\x8e\xbc\x6e\x42\x39\xdc\xd0\xe4\x6e\xcd\x64\x28\x71\xbb\x77\x10\xd8\xaf\x3c\xeb\x8a\xbe\x4c\x4a\x8a\x73\xe5\x1b\x88\xd5\x5f\xdd\x1f\x0d\x92\xed\xc8\x7f\xcc\xa1\xee\xd8\x62\x4c\x05\x89\x2b\x70\x6d\xd6\x26\xb7\xf5\xfd\xf6\x20\x35\xb8\x23\xab\xc5\x69\xcc\xd0\x6e\xac\x56\x5d\x28\x7f\xd3\x72\xb9\x39\x61\x84\x73\x4b\x9c\x2f\xf3\x73\xf6\xfe\x02\x87\x73\xc6\xcb\x05\xbf\xd2\xf7\xf8\xd7\xff\x8c\xae\x59\x31\x53\xda\x17\x3d\x3e\xfa\x60\x69\x07\xdf\x48\xd1\x0b\x27\xcd\xb8\x9f\xb4\xba\x36\x9f\x71\xbf\x47\x73\x03\x9c\xc5\xf0\xae\x89\xb3\x56\x86\x26\xb5\x85\xcc\x44\x87\xbb\xcf\x2e\x27\x66\x9a\x1b\x06\xa8\x35\x77\x83\x61\xc6\xcf\xb4\x10\x89\x51\x74\x9e\x75\x76\xf0\x83\xab\xe0\x7e\x68\x8a\x28\xaf\xdb\xe5\xfe\xeb\xec\x65\xb9\x5f\xcc\xac\xc6\x24\xf0\x20\xe0\x88\x1f\xca\xe1\xd3\xea\x1b\x4d\x88\x71\x03\x0f\x28\x55\xfd\x62\xc1\x70\x36\x5d\xad\x3a\xc3\xef\x0f\x58\xe0\x75\x40\xb8\x27\xf8\x5c\xb6\xca\x71\xc0\x23\x12\x07\x5d\x57\x60\x57\xd4\xcd\x9c\x1f\x7d\x3b\x51\x14\x6b\x3c\xc7\xc3\xb1\x46\xe3\x8f\x9e\x49\xc4\x74\xa9\x82\x13\xc5\xb0\x8d\x93\x61\x00\xbf\xfa\xcf\xb9\xeb\x4f\x5f\xcd\x19\xfb\x11\xea\x25\x58\x58\x30\x8e\xef\xd6\x8d\xd8\x1d\x4b\x94\xb6\x80\xf1\xfb\x22\x9b\x86\x16\xdf\x68\x2e\xf3\x66\x19\xb5\x2a\x63\xd8\x81\x1f\x77\xca\x79\xc2\x01\xf9\x48\x8f\xfc\xdd\xa1\x0a\xe1\xb3\x07\xbc\x9a\xbe\x42\x26\x08\xa6\x1d\xd6\x7f\x72\xee\xa4\xa7\x80\xf3\x80\x59\x31\xcb\x0a\xca\xda\x14\xf1\xbf\x42\x09\xed\xf1\x48\x62\xce\x68\x1a\x6c\x6b\x34\x00\xeb\xf3\xcc\x6e\xc3\xdd\x38\xe7\x46\xa0\x7b\x7e\x2e\x87\xf5\x61\x97\xbb\x70\x19\xc6\xc8\x60\x31\x5f\x3e\x5d\xbe\xe4\x12\xb8\x35\x6f\x55\x1b\x6b\xff\x38\x6d\x5b\x33\xb9\xd4\x72\xe5\x79\x8c\xba\x9a\x1f\xa6\xd3\x1f\xa8\x39\x30\xcb\xd5\x6b\x6e\x5b\xe6\x37\x14\xaf\xdc\x19\x24\x30\x69\x9d\x0d\x52\x39\xe8\xaf\x73\xa5\x8d\xff\x8c\x35\xe8\x30\xfd\x9d\xf4\xef\xf6\x38\x70\x92\xc4\xd6\xb3\xc7\xe1\x35\xa6\xd7\x4c\x0e\x8a\x24\xac\x6b\xe3\x5b\xb3\xf3\x4e\x2a\xd7\x0e\xd3\x5e\xe2\xe0\x03\x83\x1a\x66\x9f\x88\xc7\xb5\xaf\xc1\xef\x55\x53\x76\x45\xdb\x7c\x1d\xbd\xef\x3a\x26\xa1\xb2\x71\xd5\xaa\x7e\xbb\x21\x93\x05\x5c\x0b\xca\x10\xe7\x5c\x9c\x73\x85\xc1\x36\x6a\x66\x9b\xa3\xc2\x0b\xcd\xf7\xed\xdf\x78\xae\x32\xd8\x94\x85\x32\xad\x8b\xb5\x95\x52\x99\xbe\xb5\xc2\x4b\x12\xa4\x6e\x16\x5d\x71\xcd\xbc\x4c\xbb\x4f\x57\xa9\x13\x41\x64\xba\xeb\x58\x31\x55\x69\x9f\x35\xe4\x46\xd0\xc0\xac\x4b\xc5\xf2\x7c\xca\x50\x36\x7b\x40\xd9\x11\x01\x35\x68\x9e\x4d\x59\x14\x7a\x5f\xe8\xfd\x8e\x4b\xa7\xbd\x0c\x22\xe0\x81\x51\x6c\x3e\xa5\xc6\xbf\x68\x99\x56\xfd\xba\x88\x08\x7d\x86\x08\x44\x6e\x58\x7e\xbf\x68\x5a\x88\x90\xfa\x58\x0a\xfc\xf6\xba\x31\x26\xaf\x36\xc3\xec\x3b\x9d\x82\x88\xb8\x4a\xac\xad\x3d\x02\x6d\x37\x76\xab\x6c\x7f\x56\x24\x0d\x41\x38\x87\x1f\xb5\x41\x4e\xd5\x17\x07\x1e\xb6\x43\x88\x67\xbc\xf9\x0e\x50\x3f\xc0\x07\x3a\x94\xe5\x87\x3f\xd2\xba\x86\x2e\x09\xfc\x47\xbf\x90\x2b\x88\xf2\x5d\x6d\x6a\xbe\xe9\x4f\x19\x41\x83\xd8\x6a\x99\x59\x15\x47\x64\x24\x8d\xee\x34\x55\x01\x2e\x4f\x7f\x14\x79\x5a\x54\x43\x73\x97\x89\x25\x40\x24\x1e\xe0\x93\xa9\x6a\xfe\x8e\x2f\xc7\xb4\x8b\xce\x70\x52\x30\x16\x32\x83\xcf\xb0\x66\x69\x63\x52\xb3\xe0\x8c\xe0\xcf\x68\x19\x36\x36\xbc\x6f\x46\x0e\x7f\xb0\xf0\x34\x05\x0c\xb4\xda\xb9\x2a\xfc\xd0\x98\x72\xf1\x0a\x6b\x54\x7d\x6a\xba\x10\x24\xc2\x84\xdc\x52\x93\x1e\xd2\xff\x9c\x53\x95\x8e\xe1\xc6\x42\xfa\x06\xcd\x8c\xbc\x13\xbc\x8d\x6d\x53\x46\xc8\x80\x99\xf4\xa9\x67\x9b\x9e\x83\x55\xb9\x1a\xae\xe6\x42\x26\x12\x67\x96\x06\x98\x69\x9d\x66\x69\x47\x99\x11\x92\x29\x30\xda\xa5\xcd\x0d\xc5\x5d\xa9\x9a\xca\x74\x84\x12\xcc\xfa\x82\x7d\xf2\x52\x0d\x88\xa1\x02\x22\x86\x50\x70\x0b\xcf\x9f\xa6\x19\x0a\x48\xfc\x80\x39\xa2\xbd\x3c\xb7\x73\x02\xa4\x87\x49\xd7\x7d\xab\x55\xba\xbb\x9c\xac\xc0\xe2\xf5\xc5\x80\x56\x48\x49\x43\xd8\xa8\x6d\x5d\x56\xb3\x5c\xcd\x53\xf5\xe5\xca\x91\xcf\x7c\x46\x7a\x56\x09\xa4\xbd\x59\x3b\x9e\xdd\xd0\x5f\x05\xe9\x49\xe9\xb3\x16\x3f\x8d\xad\xde\x68\xba\x3f\x29\x7d\xce\x91\x87\x23\x0b\x05\x48\x15\x40\x6c\xc6\xae\x30\xf8\xb3\x31\x26\x4b\xfa\x32\xc2\xe6\xd6\x4c\xa9\x27\xf8\x74\x6a\xf3\xe7\x41\x53\xe2\x7f\x97\xd5\xca\x00\x02\x7c\x9f\x8c\x86\x74\x87\xcb\x19\x44\x64\x32\x0c\x8c\x68\x6b\x13\xb5\x6f\x78\x5a\x56\x77\x45\x69\xd9\x8b\x37\x93\xee\xae\x56\x22\x43\xe2\x63\x0b\xb1\x03\x1e\xfc\xaa\xd8\xf7\xd3\xe8\x4b\x86\xc0\xb0\x61\xd9\xbc\xfe\xb3\x5c\xb9\xbd\x65\x3d\x5b\x4c\x47\xa9\xed\x73\x0c\xb5\xc0\xf2\x9c\x3e\xe7\xf8\xdc\x9b\xf5\xfb\xf7\xee\x13\x89\x6c\xc1\x13\xbb\x1c\x0b\xde\x84\xb5\x46\x2a\xbb\xff\x62\x4a\x12\x1b\x9b\xc9\x5d\xc7\xe1\x1e\x0a\x95\xb8\x55\xa2\xff\x4d\x83\x5b\x4d\xa4\x01\x6c\xdf\xad\x9f\xfe\x0a\xfa\x65\x20\x49\x54\x68\xd4\x0f\x76\x8b\x97\xee\x05\x94\x31\x33\xc8\xa5\xe7\x1c\xb6\x35\xcf\x15\x2f\xd5\xe4\x8a\x77\x5d\x58\x90\xb1\x34\x60\x06\x7e\x3a\x65\xc8\x1a\xec\x3b\x3a\xfc\xac\xe1\x67\x3f\x4f\x23\x85\x85\x6e\x28\x32\xc4\x8a\x99\x7c\xda\xfd\x30\x2a\x3d\xde\xdc\xec\xbb\x97\xcd\xcb\xeb\x66\xb5\xda\xb6\x07\xb4\xc4\x06\x4d\x5a\x6d\xd3\x43\xee\x7a\xe1\xfe\xe8\x75\x97\x49\x64\x48\xcc\x0f\xc5\xe1\xb5\x42\x85\xf4\x26\x02\x42\xc6\xfe\x75\xf6\x28\x13\x25\x90\x14\xbd\x08\xf7\x3d\x67\xdc\x9f\x2d\xfb\x92\xc5\x31\x16\xb1\x70\xb3\x42\x49\x97\xed\x1b\x0a\xaf\x8c\xca\xc2\x92\x51\x89\x39\x93\x46\xd4\xd7\xdd\x39\x57\x25\x4f\xc7\xde\x0b\x20\x99\x54\x58\x38\x44\x39\x42\x63\xf2\xde\x04\x95\xd3\x81\x94\x64\xca\x74\xaa\x4d\xc8\xfa\x04\x9f\x3f\x89\xba\x24\x17\x11\x2a\xda\x7d\x94\x50\x34\x0b\xdb\x73\x7e\x28\x3a\x44\xa6\xe4\x8a\x23\xbd\xe1\x74\xae\xde\x66\x75\x71\xb4\x6d\xd1\x1b\x40\xbd\x76\xb7\xed\xff\xaf\xb7\x7d\x0d\x5a\x86\x52\x86\x31\x8a\x3d\xea\x73\xfe\x65\x70\xb9\x92\x13\xc3\x58\x78\x03\xf9\xfe\x78\x59\x16\x39\xef\xc1\x40\xa4\x0a\x23\xa7\x5c\xb9\x3b\x67\xe9\x28\x01\x92\x2a\xf1\x69\xd7\x41\x98\x9f\x1d\x4c\x46\x02\x21\xa8\x73\x74\x2c\xe4\xbb\x55\x6d\xbd\x71\x53\x34\x63\xb8\xee\x0f\xda\xbd\xd5\x15\xf6\x68\xf0\xbd\xca\x0b\x8d\x26\x45\xf3\xb3\x96\x2b\x4b\x66\xb8\x85\xc3\x53\x5e\x12\xe0\xc6\xfc\x52\x54\xd0\xab\x73\x2a\x8f\x89\xc0\x34\xb7\xee\xe0\xc8\xb3\x9e\x4d\x02\x28\x4f\x24\x74\x28\x38\x60\x29\xa1\x58\x99\xb9\xcd\x67\x53\x9e\x0a\xb8\x6f\x9d\xd3\xc7\x9e\x4f\xa0\x7c\xc9\xf0\xb4\xe8\x2d\xe8\x96\xbc\x6e\x0e\x28\x5f\x02\x42\x22\xb9\xb2\x9b\xeb\x28\xe1\x55\x81\x17\xa3\x3e\xd7\xd1\x94\x2e\xf9\xb6\x2e\x81\x5f\xb9\x12\xdf\xea\xac\xb8\x93\x84\x41\x10\xda\xdf\x88\xaa\x1f\xe3\x2f\x89\x29\xc6\xfd\x7f\x1b\x94\x5d\x67\x68\x5e\x4c\x31\xff\x47\x27\x0f\x19\xc3\x0d\xfe\x64\x02\x73\xc3\x9b\xeb\xbf\xb2\x2a\xe4\xa1\xd7\x99\x25\xb3\xd1\x97\x87\xc2\xc7\x7d\xa1\x79\x52\xa2\x87\xb0\x72\x87\xb5\x9f\x4c\x48\x76\x7e\x4e\x19\xa7\x83\x8a\x62\xdf\x50\x26\xcf\x39\x94\xdc\xfa\x9b\x0c\x3a\xff\x2a\x52\x40\x2d\xa2\xab\xad\x54\xbc\x14\xd9\xf4\xda\x69\x3f\x43\xbc\x50\xaa\x5e\x39\xae\xf9\xad\xeb\xdc\x62\xd5\x7f\xab\x2c\xa7\x68\x28\x88\xd5\x73\x33\x32\x03\x6b\xf5\xac\x07\x32\xd5\xe3\x0f\x08\xe1\x59\x48\xcb\x16\x40\x99\xea\xda\x5d\x51\xde\xf3\x23\xac\x47\x41\x86\x4a\x02\xd0\x0e\x51\xc0\xf3\xb4\xbe\xcc\x0b\xc4\x9c\x8e\x46\x71\x62\xf0\x89\x3c\xcb\x04\x97\xef\x6b\xcc\x8d\x6d\xdc\x32\x60\x09\x8f\xdf\xc7\x89\x89\x9f\x88\x10\xa1\x84\x92\xe7\x06\x8c\x6e\x84\x24\xa7\x2f\x26\xd1\x91\x67\x58\x0a\xae\x21\xfb\xc8\xd3\x51\xfd\x41\x31\x96\x38\x27\xc6\x25\x1c\x0b\x89\x58\xf2\xd5\x11\xca\x03\xe4\xf2\xaa\xe5\xe1\x3e\xa4\x22\x24\x94\xcc\x5e\xe6\xeb\xdd\xcb\xec\xe5\x9f\xfb\x6f\xb3\x87\x57\xd4\xff\xd8\xaf\x9f\xf6\x5d\x39\x52\x71\xdf\x43\xc5\xdd\x2a\xe3\x1f\x30\x80\x32\x28\x1e\x26\x8e\xe9\xd5\x86\x3b\xcf\x27\xc8\x7b\xbd\x23\xc5\x05\x47\xe2\xaa\x34\x68\x11\x38\xf1\xf4\x36\xb5\x7b\x6a\xe7\x55\x22\x56\x86\xcf\x36\x5b\xec\xd6\x8b\xd9\xc3\xe2\xe5\x75\xbd\x5d\xbd\xec\xef\x76\x0f\xfb\xed\x66\xb5\x5a\xba\x9f\x23\x24\x08\xde\x36\x81\xdf\x1f\xb8\x6d\x79\x8f\xee\x97\x0c\xb8\xe1\x8c\xf6\xa3\xf3\xea\xcb\x54\x47\xbd\x7d\x6a\x12\x8c\x3c\xd7\xee\x0d\x29\xa6\x18\x01\xb8\xaf\x55\xdc\xc0\xf4\xbe\x2e\x92\xf5\xe2\xb9\xfb\x6b\x82\x25\x0a\xbc\xee\x6f\x46\x6b\xa9\x3d\x26\x22\xa4\xe1\x9c\x40\x9e\xb3\xe7\xcc\x65\xb5\x0a\xbc\x48\x1a\x28\xf2\xbf\x41\x3a\xe3\xe2\xe1\x6b\x08\x44\x5a\x78\x5d\x75\x86\x5b\x46\x27\xbd\x78\x54\x01\x97\xc8\x22\x30\x65\x80\x3f\xcf\xa9\x7c\x5f\x64\xcd\x0a\x6f\x1b\x35\x63\x24\xe5\x6f\xb6\xaa\xed\xd9\xb5\x0f\x2a\x71\x98\x18\xa3\x90\xe3\x0a\xc1\x4a\x2b\x82\x7e\x3e\x8b\x3e\x05\x4f\x69\x30\xa6\xff\x1f\xc5\xaf\x75\x01\xdd\x47\x9a\x44\xa3\xcb\x00\x5f\xac\xa8\xfb\xb0\x07\x0c\x9e\xef\x53\xda\x4a\xda\xa7\xb2\x6a\x0f\x10\x16\xf7\xfc\x46\x6d\xbc\x33\xe1\x1c\x0d\xe0\x87\x46\xf2\x69\xf1\xc6\xcb\x03\xec\xac\x0d\xdc\x97\xf6\x28\x8b\x45\xaf\x84\xf3\x04\x9f\x56\x7d\x63\x10\x79\x83\x1f\x7b\xd8\xc3\x5c\xf0\xf2\x8e\x5b\x85\x72\x6b\x79\xe0\xe4\xa2\xc0\x8f\x13\x5c\xbe\xab\xb7\xe2\xd3\xb2\x24\x87\x6b\x32\x04\x7e\xe4\x7a\xc4\x4b\x7e\xc1\x25\x6f\x3f\x9c\xc9\x10\x44\x11\x89\x6c\xa5\xe8\xa9\xf8\x7c\xe0\x55\xdd\x2f\x20\x40\x20\x0d\x54\xb1\x2d\x71\x40\x68\xed\x00\xaa\x0e\x79\x71\x65\xb5\x37\x91\xd5\x40\x48\xb4\x36\x95\x8f\xcf\x75\xe7\xaa\x7d\x33\xf2\x80\x48\x9b\x7e\x90\xb1\xbc\x3c\x9d\xfb\x4e\x7d\x00\x31\x0b\x90\x41\x70\x30\x9a\xc5\x47\x8e\xaa\xb1\xa7\xa2\xac\x97\x69\x75\x3a\xd7\xb0\x3c\xa3\xf6\x7d\x55\xf3\xe3\xa9\xfd\x90\x0a\x30\x2b\xe1\x4a\x6d\x73\x7e\xaa\xde\x8a\x61\xe2\x06\x14\x42\xd2\xba\x1b\xbf\xbe\xac\xb7\x3d\xb0\x88\x1d\x92\x50\x8a\x18\xb7\x4d\x8f\x71\xd7\x1e\x32\x22\xdd\xf6\xaf\x75\x61\x2c\xc4\x86\x83\x18\x4b\x98\x9d\xee\x7d\x36\xe8\x78\x10\xe0\x5a\xf1\x75\x33\xfb\xcd\xe4\x04\x18\xe7\xd1\xc0\xb1\xdf\xe8\x9e\x74\x04\xf8\x5b\x5f\x25\xb9\x1f\x5a\xea\x44\x9a\x9f\xfb\xa1\x19\x70\xcf\xc7\xa6\x9a\xed\x36\xba\xbc\xc3\x86\xc1\xbd\x5a\x1c\x70\xca\x98\x68\x97\x9d\x5e\x3a\x37\xd5\x33\x01\x19\x6b\xc4\x5a\xec\xe0\x20\xdf\xf8\x4f\x0d\xb6\x00\x24\x25\xf8\xb6\x9b\xc0\xbf\x75\x0d\x1c\xdd\x56\x49\x63\x53\x9f\x31\x94\x28\x80\x6a\x12\xad\x00\x8a\x90\xd8\x77\xab\x4d\xa7\x96\x3f\x98\xf3\x8a\x24\x5a\x3b\x69\x0c\xf9\x7e\xb0\xf5\xa0\xac\x28\x5d\xfd\xcd\x2d\xea\xcd\xfe\x85\x6a\x59\x5c\xd9\xca\xee\xce\x55\x38\x01\x12\xc3\x70\x76\xad\xea\x4e\xbb\xca\x3c\xbe\xf6\x1c\xcd\xab\x6c\xc4\x26\xca\xaa\xee\x07\xd7\x03\x4e\xb6\xf6\xc2\x04\x3d\xcb\x4e\xe9\xe1\x70\x99\xf3\xfc\x7d\x78\x65\xda\xf7\x84\x71\xda\x2d\x8a\xcc\xca\x74\xbb\x23\x4a\x52\x53\x0d\x86\x77\x07\x93\xb2\x87\x82\x44\x62\xd2\xf8\xcf\xb3\x7a\xe3\xb2\x8b\xd8\x75\x20\x25\xb3\x4b\xe1\xa6\x84\xae\xb1\x64\xe1\x59\x93\x73\x49\x47\x14\x42\x23\xa4\xb2\x9a\xed\x56\xfb\xa7\xd9\xe3\x6a\xff\xf2\xfc\xe0\x68\x27\x3a\x12\x2c\x66\x2d\xed\xa4\xc9\xa0\xb7\xf0\x81\xd1\xe2\x55\xd0\x63\x3f\x41\x38\x60\x76\x03\xcd\x36\x65\xab\x55\x46\xbc\xcc\x0d\x10\x3e\x62\xdf\xcd\xec\x68\x12\xdf\x95\x3a\xcb\x81\xe2\xfb\xc4\xbb\xe3\xd6\x50\x4d\xb4\x0f\xb4\x07\x56\xb3\x70\x25\xab\xac\xef\x7e\x4d\xf4\x3f\xe3\x35\xea\x5f\x7e\x27\xe9\x69\xed\x43\x06\xcb\x84\x8e\xc3\x98\x27\xa6\x6c\x76\x80\x00\xb9\x71\xee\x27\xc7\x11\x84\xc6\x00\xcc\xd8\x72\xe0\xc1\x6b\xd1\x00\x4d\x15\xc1\x53\xe8\x34\x57\xab\xe3\xa9\xbe\xcc\x21\x07\x8d\xbd\x5c\x13\xbd\xda\x71\x49\x98\x20\x19\xe8\xc0\x8f\xf0\x7c\x3a\x15\x79\xb7\xa3\xe9\x24\x21\x48\xf1\x7c\x2b\x8e\xc7\xb4\x7d\xea\x4c\x10\xde\x79\xda\x1f\xd3\xdc\xc8\xfb\x54\x3d\xba\x8c\x1b\x29\x4d\x0b\xa0\x82\x7a\xf6\xc1\xd3\x8c\x8b\x0c\x90\x07\x6d\xae\x68\x38\x98\xc7\x46\xa8\x55\xf0\x5a\xbe\x2d\x3a\xa8\x9b\xdb\x46\x35\xa7\xca\x37\x72\xbb\x0f\x85\x7c\x3f\x8f\xc4\xe0\x34\xa7\x10\xf9\xae\xc0\xb0\x2c\xcf\x87\xee\x83\xcc\x28\x8d\xa1\x23\x96\xd1\xa2\x18\x7f\x96\x07\xac\x47\xc1\xb2\xbd\x9f\x4e\xc4\xbd\x19\x11\x23\xb9\xa1\xb9\x4d\x8e\x8f\xd6\x63\x68\x68\x2e\x01\x2f\xd5\xb5\x23\x90\x71\x6c\x8f\x09\x3f\xc4\xfe\x65\x55\x8a\xd1\x35\x8b\x44\x61\xbc\x85\x77\xb0\x7a\x43\xde\xf9\xc4\x2a\xa6\x05\x8b\x30\xfb\xdf\xdc\xcd\xfa\xfb\x98\x16\x3c\x56\xfd\xfc\x66\x96\x5f\x56\x2f\x8b\x20\x08\x7f\xd2\xf8\xd3\x32\x4c\x8c\xcd\x1f\xd6\x64\xad\x42\x72\xfb\x4a\x48\xea\x61\x0f\x62\xf6\x6d\xb6\x7e\x98\xcd\x1f\x56\xfb\x97\xd5\x76\xf5\xf2\x6d\x35\xc4\xc4\x69\x99\x88\xc8\xc1\x22\xf6\xa6\x59\xb7\x6f\xe6\xda\xf7\xb4\x7e\xfb\x9a\xe6\xf5\x53\x51\xef\x9a\xbc\x71\xde\x7f\xdf\x54\x18\xc6\xd2\xe5\x46\xe8\xff\x80\xeb\x49\x7b\xa7\x54\x64\xb6\x8c\x16\x03\xf1\x92\xca\xf1\x4a\xa5\x88\x2f\x6c\xb3\x6b\x5e\x36\x87\x87\x57\xa7\x62\x40\x04\x86\x15\x9d\x07\xd3\xba\xbd\xd1\xc2\xd2\xda\x33\x02\xf7\x5c\xa9\x07\x23\xa1\x7d\xc3\x92\x70\xf8\x1b\xb4\x8a\xf0\xc5\xd0\x50\x1b\x7d\xb3\x47\xde\x24\x96\xda\x2e\xdf\xda\xf3\x24\x61\x16\x89\xf7\x74\x3e\x5a\x11\xb1\xf6\x1d\xe8\x6d\xab\x53\xe7\xd7\x9e\xaf\x7d\x94\x73\x41\x32\xd0\x6b\x7e\x32\x7a\x54\xed\x41\xed\x25\x4e\x6d\xf6\x08\xdf\xf8\xb5\x5d\xcb\x4f\xe3\x59\x3c\x03\xef\x08\x7c\x6d\xe6\xd4\xdb\xd2\xdc\x77\x05\x61\x10\x1b\x1f\xfe\x22\x5f\x9e\xab\xba\x35\x01\x68\x07\x90\x04\xeb\xef\x8e\x27\x6e\x84\x59\x9c\xe2\xd1\x10\x76\xa8\xbd\x20\xf6\x49\xe2\xd2\xdd\x6c\xba\xf5\xa0\xbd\x28\xe2\x38\xab\x8b\x4c\x2d\x4a\x5e\x43\x85\x72\x43\xf6\x20\x89\x0d\xd1\x1f\x05\x4b\x78\x05\x63\xfb\xc9\xe1\x95\x12\xce\xb4\x03\xb1\x6f\xb2\xe2\x5a\x9a\x76\xf8\xcd\x04\x9c\x8d\xa3\x6e\x82\x20\x4b\xe9\x1d\x9e\x32\x66\x22\xb2\x73\x78\x03\xb5\xb8\xec\xd2\xcc\xe5\xf5\x7e\x1f\xcd\xa4\xbd\x58\x08\x42\x5b\x3f\x4d\xc7\x76\x18\x9e\x8d\x7a\x31\x6e\xdf\x0f\xaf\x0b\x77\x85\x89\x32\xc6\x50\x1b\x7e\x79\x4c\x3b\xf3\x21\xed\x31\x2f\x46\xde\xd2\xf6\xf1\x65\xd7\xd5\xc7\xb4\xc7\x42\x62\x4d\xe9\x41\xbe\xdf\x01\x6c\xe5\x1b\x5c\x69\x43\x36\xc3\x8c\x26\x44\x5a\xf5\xda\xd5\xda\x63\x34\x26\xcc\xbd\x93\xe5\x07\x94\xad\x66\x5a\xf7\x2b\x99\xd6\x88\xc4\x77\xcd\xb5\x45\x5a\x8f\x6f\x0b\x0f\x02\xc4\x79\xef\xab\x37\x5e\xde\x10\x87\x1c\xdd\x6d\x11\x6a\xd9\x3a\x47\x7f\xf0\xac\x0f\x96\xd6\x9e\x60\x92\x75\x90\x43\xb4\xdd\x42\x39\xdd\xf6\xb8\x96\xcc\x60\xc5\x2e\x0e\x54\xd6\xb5\x9f\xb5\x27\x09\xc7\x8a\x52\x3b\xa9\xd3\x22\x6f\x6d\xf8\x7f\x13\x85\xe9\x4e\xa5\x0c\xf9\x76\xdb\x5c\xd9\xaa\xaa\x5b\x6b\x5d\x7b\x1c\x64\x10\xda\xfa\xc7\xca\x40\x34\x5a\xca\xf7\x20\xcc\xd6\x5e\xb3\x3c\xc9\x16\x85\xb9\x4c\xab\xba\xcf\x2d\xb7\x71\x8b\xf6\x74\x40\x95\x3d\xe1\x7a\x89\xba\x7c\x93\x21\x53\x33\xd0\xc0\x32\x8d\x1c\xa6\xd9\x2e\xe7\x97\x0d\xbf\x40\xfb\x78\x75\xa0\xa9\xe3\x37\xed\x16\x53\x61\xad\xf6\xbd\x20\x61\xb1\x4b\x5c\x5e\x40\xc1\x71\xe0\xd3\x3e\xb8\x06\xdf\x53\x12\x95\x21\xd0\x98\x6c\x88\x2e\x9f\x7c\x07\x7d\x1f\x0c\x03\x40\x16\x59\x06\xd2\x18\xbc\xdb\x5f\xe7\x07\x7e\x60\x0c\xa5\x6a\x38\x7d\x19\xd7\x0e\xb4\x1f\x10\x99\xf4\xe1\x74\xa8\xf9\xf7\x0b\x13\x3d\xed\x87\xd2\x30\x00\x8d\x97\xdf\x43\xc1\xd5\xa8\xb9\xa7\xfd\xc8\xf3\x91\x34\xff\xac\x52\xb4\xd5\x1a\xdd\x90\x38\xe4\x12\xe5\xef\xe5\x7f\xce\x69\x6e\x5b\xd4\xa3\x31\x34\x4e\x30\x65\xda\xbd\xf1\xbc\xa8\xfe\xea\xcf\x08\x9f\x26\xc6\xff\xb0\x84\x4a\x9e\x61\x04\x74\x19\x55\xe4\x9a\xd1\xc6\x63\xa6\xd9\x4a\x6d\x51\xef\x7b\x9a\x65\x28\xbd\x79\x99\xb9\xfe\x46\x7b\x6e\x61\x71\x82\xe7\x32\xef\x4b\xda\xd8\xc3\x49\x24\x30\x09\x35\x0e\xbe\x83\x5f\x95\x90\x90\x89\x81\x2e\xd2\xc8\xa7\xca\x8d\x8b\x45\x60\x35\x5c\x7a\xec\x2a\xed\x33\xcf\xc3\xec\xa7\x43\x28\xe2\x62\x3f\x75\x73\x58\x20\xa4\x91\x12\xbd\x43\x5e\xc6\xf8\x30\x15\x32\xec\x0c\x63\x3a\x4d\x39\x7b\x9c\x2b\x9a\x18\xfe\x1a\x57\x22\x55\xe3\xf9\xca\x15\x45\xe9\x5c\x2c\x6d\x99\xcd\x75\x7e\x6d\xb8\x3a\x98\xb5\xc2\xf3\x91\x75\x2d\xa0\xf6\x3d\xcf\x1b\x4d\x07\x11\x85\x18\xcc\x00\xaf\x2e\x66\xef\xba\x59\x1a\x72\x9f\x88\x43\xf4\xf0\x35\xba\x19\xf6\x8f\x92\x04\xb8\x7d\x18\xcb\xd5\x71\x6d\xbf\xaf\xc4\x3a\x7c\x8f\x7d\x49\x08\xb3\xae\xca\xc7\x53\x5a\xe4\xf7\xbd\x28\xf3\x56\xa1\x63\xf4\x83\x24\xf7\xb0\xd4\x62\x21\x9f\x8b\xe2\x68\x63\xf9\xde\xc6\xd4\x8d\x56\x81\x27\x88\x5b\xf4\x65\x91\x2b\xac\x89\xf7\x8b\xab\xcd\x18\x23\x36\xfb\x61\x60\xe5\xbd\xac\x41\xfb\x2a\x31\x56\x65\x0e\x71\x74\x5f\xf2\xbc\x86\x21\xdf\x45\xfb\x8a\xf9\x08\xd3\x92\xb2\xcb\x52\xda\x43\x4a\x75\x86\x34\x9b\xa2\xc8\x26\xfd\xa8\xb4\x0f\x41\xc2\x3b\x88\xe9\x16\x0b\x32\xd3\xaf\xbd\xa6\x5e\x14\x5b\x09\xa0\xb4\x84\xca\x31\xa5\x07\xf3\x40\x2b\x46\x5d\x39\x9f\x5f\xa6\xf3\xd1\xe1\x79\x03\x8f\x86\x88\x48\x6b\x16\x93\x17\xd3\x8a\x74\x47\x12\x23\x23\x76\x33\x06\x86\x1f\xf5\xac\xde\x34\x6f\x5a\xf3\x43\x06\x67\xf5\xc3\x08\x5f\xe3\xbb\xac\xf8\x4c\xf3\xc3\x57\x9e\xb6\xa7\xf5\x59\x82\xe6\x1b\xcd\x69\xb1\xeb\x7e\xae\xdf\x46\x1f\xd6\x81\xa5\x7b\x55\x6e\x79\xf9\xad\xc8\x2f\x08\xbc\x20\x11\xdd\x3d\xc2\xf5\xc3\x08\x31\xb5\xc9\xf9\xe8\x03\x24\x91\x46\xce\x51\xeb\x7f\xc2\x44\xa8\xe9\xc6\xc5\x21\x9a\xd1\x61\x19\x02\x73\xec\xf6\x91\xf7\x8a\x68\x3a\x08\x7d\x1f\x1f\xe7\x7d\x73\xff\xeb\xb4\x4d\x36\x75\x10\x26\xc6\x3b\xc4\x14\x24\x33\x38\xf0\x1a\x1e\xab\xc3\x16\xae\x24\x1b\x75\x10\x4a\x8a\x04\x47\x33\x29\x66\x65\x8d\x99\xed\x54\x9d\xeb\xf6\xad\x08\xc1\x37\xf6\x22\x6f\x4d\xaa\xd0\x5f\x28\x83\x88\x09\xe1\xf5\x66\xf7\x86\xcb\xf7\x2e\x7a\x77\xa3\x08\xd7\x68\x5c\x76\x34\x2a\x6e\x0e\x87\x75\x8b\x2c\x35\x19\x03\x05\x04\xfc\xd8\x82\x05\x1f\x8a\xc3\xaa\x2c\x8b\x72\x56\x1e\xfa\x1a\xbc\x3a\x20\x3a\xc1\x08\xed\x8f\xf5\xd3\xfe\xee\xf9\xf5\x69\x69\xba\x24\xb3\xe5\xf2\x65\xb5\xdd\xba\x51\x71\x00\xa6\x43\xec\x68\xe3\xa3\x27\x19\xc7\x2a\x30\xaf\x47\x71\x1a\xaf\xd7\x01\x0d\x8c\x72\xe1\x7e\x5f\x17\x4b\x90\x28\xab\x3d\xfa\x3c\x4d\x22\xdc\x8b\xef\x8b\x4c\x4d\x2c\xf9\x01\x95\x06\xda\x59\xbd\xa5\xba\x9e\xa7\x75\xf5\x82\x32\x31\xd7\xe5\x8d\x66\xa8\x50\x7c\x08\xdf\x8e\xdc\x65\x24\x42\xca\xa0\x67\xb8\xd6\x2f\x46\xe9\x20\x91\x8a\x23\x15\x66\xb1\x1b\x7d\x7d\xa2\xe2\x80\x74\x50\x49\x2b\x36\x79\xbd\x08\xf7\x17\xe3\xc9\xa0\x2a\x60\xc4\xc3\x82\x97\x36\xc2\x68\xdb\xba\x38\xf5\xda\x2d\x3a\x60\xcc\x90\x91\xe6\xbb\xc5\xeb\xef\xd5\x57\x75\xc0\x84\xc4\xf2\x1a\xaf\xaa\xf4\x90\xdf\xc8\x59\x46\x77\x89\x49\xdf\x8b\x7a\x7e\x49\x0f\xc0\x15\x94\xa2\x68\x52\x49\xf7\x5b\x78\x48\xf1\xa6\xe3\x4e\x38\xcb\xb2\xd7\xbc\xea\xb6\xd1\x40\x78\x04\x63\x3f\x55\x34\xbb\x70\xe7\xd3\x3d\x48\xca\x02\x11\x44\x8e\xbb\xfa\x04\x9f\xd6\x71\x7d\xdc\xa0\xfe\xf9\xbb\x24\x42\x82\x02\xf1\x06\xd8\x74\x9f\xea\x7a\x82\xed\xaf\x03\x15\x19\xd6\x19\x57\x6a\x59\xc8\xda\x22\xf4\xc2\x60\x12\x31\x7c\x03\x4f\xd1\xff\xaf\xdd\xd6\x86\xda\xce\x3a\x00\xad\x51\x85\x64\xe1\x9c\x5d\x9a\x18\x98\x87\x76\xbf\x5b\xc2\x48\x10\x42\x87\x9e\x36\x86\x13\xc6\xc2\x02\xeb\xcf\x59\x0b\xfa\xd1\xa1\x0f\x0c\x21\x95\xa7\x32\xfd\x1b\xb7\xaa\x81\xad\xac\x0e\x7d\xcd\x20\x6e\x37\x53\xb4\x73\xb7\xf1\x95\x51\x2c\x73\xaa\x24\x3a\x0c\x03\x2e\x68\x6f\x61\x59\x42\xdd\xb9\xde\xeb\x30\x02\x8d\x33\x6f\x53\xa6\x47\xde\x5f\x91\x42\xc2\x24\xe2\xf9\x5e\x66\xbb\xd5\x7e\x3b\x7b\x58\x21\xb9\x30\x70\x87\x63\xa9\x49\xeb\xc9\x6d\x6c\x17\x76\x5f\x87\x37\x3f\xa4\x94\x7a\xa4\xcd\x15\x56\xcd\xc0\xdb\x4d\x70\xf7\x99\xc4\x44\x8c\xcd\xef\xfd\x31\x5a\x50\x42\xaa\x42\x74\xff\x01\xf4\xd0\xc1\xdb\x7a\xee\x70\xa5\x3a\x64\x91\x6f\xe4\x87\x6c\xf0\x8e\x81\x7f\xb5\x2b\x5c\x0d\xc1\xd1\x45\x86\x67\x65\x1c\x08\x31\xf1\x2b\x94\x70\x3e\xae\x7e\xd4\x25\xb4\x71\x43\xc8\x09\xa0\x06\x7c\x5a\xad\x65\xd1\xfe\x91\xf9\x4e\x51\x0e\x77\xb4\x4d\x2a\xeb\x73\x09\xa3\xa7\xcc\x95\x44\xd0\xd2\x3d\xff\x1b\xe1\x25\x23\x65\x1e\x1d\x72\xcd\xa8\xab\xdc\xb7\xae\xf0\xbf\x44\xcf\xfd\x4e\x0b\x51\x87\x42\xfb\x08\xea\xab\xd2\xda\x71\x47\xf7\xee\x7b\xa5\xcf\x9d\x0d\xc5\x2e\xad\xbb\xdf\x23\x2d\x31\x98\x2b\x75\xae\xae\x54\x21\x86\x4f\x57\xf9\x02\xf9\x0a\x55\x5d\x9c\x36\xa8\x97\xbd\x6f\x72\x2a\xdf\x9d\x4b\x85\x0c\x9b\x57\x2d\xd1\x64\x7e\x99\xf5\xda\x4b\x93\x41\x73\x08\xc4\xc7\x28\xfe\xbf\x5f\x1f\xd6\x0b\x57\x9f\x08\x21\x11\xdc\x90\xbe\xec\x83\x5d\xa6\x25\xc8\xdb\x86\x9a\xc3\xa7\x00\x3a\x42\x7d\x92\x7d\x73\x49\xcf\x9f\xf9\xf4\x5d\xb6\x83\x75\x14\x18\xdc\x92\xe1\x17\x15\xa2\xaa\x0d\xc3\xa1\x8f\x56\xf9\x25\x99\x79\x70\x4d\x5a\xd0\xd8\xc5\x6c\xc6\xe5\x65\xc1\xdb\x62\x48\xe4\x25\x1e\x6d\x25\x86\xe5\xf9\x78\xce\x3a\x83\x5e\x1d\x79\x5a\x22\xc3\x43\x9c\x2f\xf3\xf9\x62\xf8\x7e\x45\xbe\x36\x3a\x6c\x5f\x5f\x77\x61\xb4\x7f\x59\xed\x66\xce\xed\x5c\x47\x41\x18\x62\x25\xa8\x95\xba\x1f\x84\x5a\xc3\x47\x19\x05\x4c\xcb\xb6\xa5\x5d\x64\xaa\xf8\xcc\xbf\xf4\xda\x0e\x3a\x0a\xb4\x8a\xfc\xfe\xc6\xd0\x0b\xdf\x46\x4b\x6e\x14\x06\xcc\x1a\x91\x63\xe9\x63\xc1\xab\x37\xc1\x47\x35\x55\x1d\x45\x5e\x82\xa3\x9a\xd9\x83\xaf\x45\x8b\x15\xd0\x51\xac\x03\xdf\x10\x84\x5e\x73\x8d\xc2\x3e\x53\x72\xd5\x3a\xa2\x1e\x41\xdc\x0b\x12\x98\x04\xcf\xdf\xbf\x15\x2d\x53\xc1\x9d\x2b\xd1\x8a\x39\x54\xd4\x7d\x09\xb7\x9e\x7b\xc4\x44\x10\x77\x8c\x1f\xa3\x7e\x33\xf5\x74\x5b\x88\xdd\xd4\x14\x48\xda\x93\x25\xb8\xba\xff\x71\x11\xb6\xd9\x7c\x85\x68\xd4\x11\x8f\x63\x6c\x3e\xe9\xc2\xda\x1b\xab\x2b\xf7\xd4\x5b\xec\xf7\xe1\x4f\xe7\x94\xe3\x94\x9d\x67\x6d\x5e\x18\x71\x11\x58\xb6\x48\x6d\xfa\x7c\xad\x1e\x69\xf7\x39\x11\x6b\x5c\xd8\xf6\x18\x3f\xa1\xb6\xc3\x14\x28\x4c\x47\x42\xf9\xd4\x58\x13\xf2\x6c\x7e\xbe\xb4\x69\xd3\xf4\xac\xff\xe9\xcb\x10\x09\xed\x23\x36\x63\x07\xf2\x2d\xed\x61\xee\x74\x24\x99\x49\x6d\x5a\xc1\x0a\x43\x1e\xbb\x2b\xca\x6b\xa5\x1f\x1d\x49\x6d\x24\xd4\x8b\x7c\x9b\x1e\xf2\xd7\xd3\x94\x39\x90\x8e\x14\x8d\x2c\xfd\xd6\x52\x45\x93\x9f\x45\xea\x6e\xc5\x88\x94\x32\xb2\x74\xc6\x4b\x06\x11\xc0\xbd\x5a\x41\x04\x3c\xc0\xdc\xd9\x86\xe1\xc3\xc0\xc3\xd5\x58\x22\xed\x85\x9c\xf5\x14\x71\xdc\xde\x41\x3c\x0a\x58\x4b\x58\x14\x79\x75\xce\xea\x9e\x9b\xdc\xf0\xd7\x13\x2f\x51\xd4\xc4\xcf\x4d\x42\xf2\x1d\x44\x7b\x06\x2e\x94\x74\xbc\xaf\xa5\x63\xed\xb7\x47\xb5\x44\xe3\xa7\x73\x05\x6a\x2d\x8b\xbe\x4a\xa4\x26\xbe\xc7\xad\xe3\xca\x73\x6e\x4a\x69\xc3\xef\xf4\x95\x9f\xd8\x5a\xf3\x5d\xd6\x84\xd3\x8b\x22\xcf\x8d\xed\x68\x35\x58\x13\x48\x10\x1a\xd0\x7c\x61\x81\xd2\x7f\x9e\xa1\xbc\xdc\xf3\xd1\x2c\x23\xa1\x24\x3c\x6c\x2b\xff\xce\x52\x61\xf8\x2e\x10\x12\x44\x88\x20\xbf\x87\x3c\x2f\x3e\x06\x81\x08\x21\x31\x48\xd1\x85\xd9\xaf\x79\x2a\x8b\x91\xd7\xae\x26\x44\x19\x95\x5f\xa3\xe4\xf3\x9c\x67\x17\x74\x6f\xd6\x29\xa8\x05\xfa\xe3\x8d\x41\x3f\xee\x73\x10\x80\xad\x7b\x2e\x78\x95\xe6\xc5\x64\xb9\x92\xc4\x21\xc3\x09\x51\x9c\xea\x35\x2a\x0e\x2d\xb2\x26\xae\x96\xee\x37\xc6\x82\x30\xee\x1a\x5c\x31\x72\x02\x02\x2f\x20\xdd\xe1\x98\x38\xfb\xf9\x1f\x96\x3e\xf6\xc7\xf7\xb7\x61\xb4\x40\x68\x68\xac\x51\x3a\x16\x02\xd6\x39\x7e\x62\x1c\x7d\xe5\xb4\xa3\x09\x8d\x02\x84\x47\xfc\x13\xe0\xfd\xae\x28\x9b\xed\xc4\xfd\x8a\x24\x22\x8e\x83\xd6\x53\x58\x72\xaf\xbc\x3d\xe5\xe0\xae\x26\x44\x72\xdd\x43\x01\x8e\x6e\x3a\x0b\xfc\x80\xb8\x9a\x80\x7a\x3a\x1f\xdd\x37\xb1\xd8\x8b\x59\x67\x23\x67\xef\xa9\xd1\x43\x1c\xcc\x21\x46\x29\xb3\x69\xef\xb6\x47\x52\x74\x47\x13\x23\x61\x23\xec\xae\x73\xcf\x2b\x34\x06\xd9\xb7\xdf\xa3\x43\x23\x44\xfa\x06\x8b\x66\xa9\xbd\xe7\x35\xbc\x03\x9c\xda\x7a\x09\xe1\x11\x4d\xfa\xc6\x18\x3b\x27\x35\xa7\x89\x60\x89\x48\x5c\xab\xf8\x60\xb0\x38\x69\x7e\xb8\xe7\x13\x9e\x92\x9a\x08\x69\x5a\x19\x07\xd3\x47\x72\x6b\xa0\x79\xf7\x0d\xe4\x6e\x38\x65\x24\x84\x28\x4f\xbe\xe7\xca\x24\xaf\xbb\x62\x7a\xeb\x21\x2a\x30\xf4\x9b\xba\x88\x83\x55\x2e\x0b\xd5\x77\xe2\x1a\x0d\x85\x28\xb2\xc1\xc2\xb6\x2e\xe4\xfb\x38\xad\x9b\xfe\x02\x20\xbe\x68\xe6\xc4\xb7\xdd\xf3\xf6\x57\x6c\x29\x4d\x80\x2a\xc4\x31\x99\x12\x0d\x0a\x92\x9a\x82\x9d\x4b\x1a\x88\xf6\x43\x2c\x7b\xe9\x02\x1d\x66\xdb\x3f\x27\x02\x7f\x5c\xcd\xdf\x4d\x99\xa7\x7a\xeb\x60\xe1\xc3\x88\x83\x68\xa9\x51\xdf\xb1\xd3\xa2\x7e\x82\xcf\x49\xf9\xcb\xc9\x8c\x99\x68\x10\xa1\xad\x06\x7e\x2b\x6a\x28\x9b\xff\x58\x50\xcc\x68\xa0\x4e\x10\x86\xff\x80\x6e\x75\x59\x5b\xf3\x73\xf4\x8e\xf1\xad\xeb\xd0\x2e\xc3\x9b\x18\x7b\x9e\x97\xf8\x3d\xe9\x97\x0d\x94\x8f\xa9\x2c\x8b\x3f\x9c\xaf\xb7\x8e\x3d\xae\x13\x2b\xf6\xf0\x84\xe4\x64\xb7\x34\x7f\x19\x9d\x4a\x2a\x6d\xb3\x37\xdf\x14\xa2\x21\xcb\xfa\x75\xef\xd8\x27\x02\x49\x1f\xdb\xd5\xe2\xf9\x69\xb9\xdf\x7c\x9d\x6d\x57\xfb\xcd\xcb\x7a\xb1\xda\xdf\xcd\x16\xbb\xe7\x97\x76\x20\x57\x9e\xcd\x43\x5e\x0a\xb4\x85\xba\x92\x0e\xd6\x71\xa0\x02\xc4\xa3\x1a\xf0\xe7\x4c\xfd\xfb\x6c\x54\x43\xfa\x78\x1d\x1d\x87\x1e\x8d\x5c\xa7\xb4\x86\x13\xce\xe9\x1b\xb5\xb7\x66\x2c\x62\xe3\xd0\xfa\xe3\xae\x25\x63\x62\xbb\x6a\x09\x79\x71\x4c\xf3\x5e\x14\x1b\x87\x09\xe5\x96\x10\x6e\xcc\x09\xce\x25\x8e\x37\xa5\xae\xeb\xb7\x2d\x0e\x19\xc1\x9a\x9d\x29\x5e\x80\xda\x63\x49\xde\x1d\xe4\x12\x61\x6b\x7b\x4b\x77\x75\x7f\x8f\x7c\x8a\x28\xad\x13\x4f\xd5\xa8\xd9\xed\x46\x50\x2a\x5a\x01\x52\x7e\x1c\x1f\x55\x11\xae\x5a\x9f\xd0\xde\x5e\x12\x04\xb1\x65\x31\xb4\x14\x06\x1d\x13\x12\x06\x5e\x2f\xb6\x36\x40\x79\x77\x10\x8c\x8f\xb1\x6b\x5c\xce\xcb\x22\xff\xbb\xfd\x8d\x71\x22\xf1\x17\xa8\x22\xe7\x68\x1d\x00\x19\xd4\x8e\x54\xa1\xe3\x98\x1b\x65\x47\xcc\x07\xcf\x79\x7d\x19\x09\x1c\xd8\x61\x94\x50\x94\x77\xb1\x76\x9f\xfb\x96\x91\x3a\xbc\x20\x2a\x99\xd3\x9c\xb2\xde\x6c\x68\x99\x9e\x8e\x1c\x07\x75\x9c\xc4\x54\x7a\x2d\x3e\x23\x57\x5b\x5c\x5e\x4e\x57\x18\x1f\x1d\x33\x2e\xd1\x8b\xc3\xe2\x52\x8d\x9a\x7a\x4f\x01\x4b\xc7\x0c\x02\x04\x48\xf7\x63\xb8\xf6\x98\x0e\x31\x68\x33\x10\xc9\xd5\xb1\xf8\x77\xda\x3e\x55\x1e\x2b\x24\x46\x21\x33\xa2\x75\xbc\x70\x47\x65\x18\x62\xc1\xc3\x30\x59\x9f\xbf\x3f\xad\xda\x67\x24\x13\xf3\xae\x3c\x6e\xee\xdb\x1e\xa8\x3d\xa4\xac\xdd\xcb\x16\xd4\xe6\xf9\x7b\x3f\xaa\x88\x55\xac\x4d\x49\x6d\xb1\xfb\xe5\x92\x18\x6b\x4f\x21\xe8\x74\x97\x9e\x90\x47\xe4\x4e\xa2\x03\x86\xda\x69\xda\xb8\xfc\x54\x0e\x75\xd1\xe7\xc7\x6a\xea\x51\x0f\xcb\xbe\x7b\x6b\x7f\x80\x0a\x55\x69\x7e\x18\xca\x44\x0c\xee\x33\xf5\x84\x49\x5b\x36\x69\x13\x61\x76\x6a\x62\x13\xf5\xbe\xe9\xf4\x9f\x7a\x32\x52\x76\xbd\x9a\x9f\x2f\x30\x80\x7f\x0c\x91\xb9\x9a\x7a\x60\xf4\xf1\xb7\xbb\xd9\x1f\xab\xfd\xe3\xeb\xc3\x6e\xbd\x79\x58\xb7\xb7\x98\x7a\x9a\x47\xcc\xb5\xf1\xac\xbe\xe3\x70\x0a\x51\x5f\xc6\x58\xc0\xfe\x3e\x7b\x78\x58\xed\xf6\xbb\x64\xf5\xd7\x7e\xf1\xfc\xf8\xf8\xfa\xb4\x76\x8a\x72\x9a\x06\x81\x31\x0e\x68\xde\xbf\xf7\x34\xcb\x76\x97\x13\x2c\xba\x1b\x15\xc8\x04\x61\xf7\x82\xb7\x7f\x0a\x19\xa0\x4c\xde\x31\xcd\x57\x79\x8d\x1a\x99\xed\x21\x15\x38\x1c\xf6\xba\x7a\x81\x0f\xc8\xcf\xb0\xe1\xe9\xb4\x9e\xb1\xa6\x11\x33\x4c\xc8\xaa\x2e\x17\x45\x2e\xf9\x14\xec\x49\xd3\x48\x7a\x26\x28\x38\x0b\x0c\x39\xd6\xf9\x47\x91\x4a\xb8\x3a\xe9\xf8\xe4\x60\xfc\x9f\xad\x57\xfa\x88\x60\xa9\x29\x21\x86\xd6\x7c\xea\xdc\x3a\x83\x2d\xe4\xa6\x33\xbd\xe8\x4f\x16\x42\x15\xd6\xd5\xde\x91\x3f\x3d\x64\xaa\x69\x4a\x63\x4d\x48\x0b\xc7\x1e\x3d\x02\x9a\x30\x2c\x97\x3b\x60\xcc\xa2\x15\x17\x77\x2f\x19\x4d\x42\x82\x3c\x33\x9c\xc5\x58\x91\x6a\x15\xe9\x35\x4d\xa2\xd8\xa0\xdd\xf2\xb4\xee\x5b\xe0\x69\x9a\xc4\x1a\xe5\xca\x1f\x8a\x03\xe6\x0c\xd8\x34\xf8\x15\x9b\x65\x38\xc5\x92\x84\x20\x1a\x74\xcc\xc6\x99\xde\xdf\x69\xa2\x08\x1a\xd9\x1f\x55\xdd\xb9\xc8\xb5\x3f\x07\xa2\xc4\x39\x18\x55\xc6\x95\xe0\x59\x77\x04\x0c\x4d\x99\x8a\x91\x46\x34\x9f\xed\x66\xf7\xed\x66\x49\x05\xa1\x8e\xa8\xbe\x5d\xdc\xb9\xbf\x4a\x16\x06\x76\x72\x3f\x1a\xed\xf8\x8e\xd2\xd9\x0e\xa1\xb6\x5e\x7d\x4c\xf3\xbd\x72\x5e\xf0\x13\x21\x33\x05\x9f\x1a\xd7\x5d\xe3\x2a\xd0\x29\xed\x6a\x0a\x84\xa3\x4a\x83\x75\xa1\x5e\x57\xdd\xf7\x4c\x4f\x59\x4d\x34\x6a\x0e\xe0\x2c\x49\xff\xc6\x2d\xf3\xb5\x4e\xb3\xca\x55\x61\x13\x2f\x48\x30\xb2\x3b\xc2\x81\x2f\x78\xae\x2e\xfd\x35\x2e\xf1\x44\xcc\x8c\xf8\x69\xee\xfc\xc5\xfb\x4b\x75\xe2\x4b\x62\xc4\x99\x8a\x34\x7f\x34\xb6\xd1\xee\x88\x16\x88\x74\x39\xe7\x6f\x69\x5e\x7f\x99\x2a\xab\x25\x81\xf0\x5d\x5f\x13\x5d\xf0\xd2\xc3\x84\xea\xf9\xe0\xa9\x26\xa1\x04\xdf\xc8\x86\xe0\xae\xb6\x1d\xc9\x2c\xba\x51\x9a\xa0\x21\xa1\x29\xed\x77\x91\x64\xff\x8d\x4a\x22\xcf\xd8\x01\x22\xd6\x39\x6d\x7f\x78\x94\x30\xe4\x7c\x9a\xcc\xfd\xae\x28\x9d\x76\x52\x37\x00\xb8\x95\xcc\x5d\xc2\x84\x89\xe6\xe4\xfb\x9d\x44\x8c\xa1\x38\xc3\xe3\xcb\x72\xdb\xbc\x36\x83\xdb\x1c\xa9\x56\x98\xed\x31\xcd\xd3\x4d\x51\x64\x2b\xb4\x32\x1a\xfd\x62\x50\xb8\x75\x3a\x15\x85\x1b\xf7\x88\x10\x2e\xc3\x2b\xd6\xa3\x3f\xdc\x87\x13\x22\x14\xe6\x0c\x77\x65\xbb\x20\x26\x44\x0b\x24\xe4\xa2\x0c\x5f\x0f\xc1\xab\x93\x38\x30\x8d\xce\x23\xe2\x3b\xb8\x75\xb0\x1c\x9e\x31\xa1\x81\xb4\x77\x1d\xc5\x99\xea\xb7\x61\xab\xda\x0e\x63\x84\xc7\xc6\x0d\xdf\xe1\x38\xdd\x97\x30\x6a\x44\x48\xac\x03\x64\x9a\x4f\x75\x77\x13\xc6\x29\xc6\x4e\xab\xc5\xe2\x97\xfb\x6e\x22\xb4\xd6\xb2\x93\x05\xd9\x7d\x02\x8c\x5c\x92\x9c\x67\x62\xef\xdf\x53\x27\x92\xda\x00\xf8\x8d\xff\xfc\xbc\x28\xcb\xe2\x13\xca\x66\xb7\x78\x18\x93\x42\x75\x02\xca\x33\x91\x08\xbf\xd1\xf7\x4f\x00\x4c\xe1\x11\x5f\xcc\x9c\x67\x0f\xc5\x07\x98\x75\xc8\xdd\x8c\x66\xc9\xf7\x0d\xcd\xdb\xf1\xa3\x74\xa2\x99\xc0\x89\xf2\xf0\xfc\xe0\x7b\xdd\x1f\x15\x22\xba\xe7\xe7\xcb\xcb\x6e\x51\xf7\x91\x35\x89\xe6\xde\x00\x6c\x7b\x57\x16\xe8\xda\xbc\xe4\x35\xbf\xb9\xfc\x0e\xdf\x52\xe4\x63\xf7\x1d\x6c\x37\x65\x61\xd4\xbb\xa7\x74\x6e\x34\xf3\x89\x8f\x5f\x59\x42\x5d\xf2\x5e\x97\x94\xf9\xc2\xa0\x20\xf3\x22\xb7\xfe\x67\xfd\xba\x12\xf3\x85\x88\xac\x30\x3e\x66\x64\xd3\x77\x8e\x05\x20\x02\x69\x0b\x72\x30\xd2\xa2\xd5\x2c\x4c\x74\x64\x45\x56\x16\x59\x0a\x06\x87\x80\xea\xbe\xc3\x59\xc8\x42\x4e\xfc\xe0\x37\xaa\xb5\xbf\xa1\x3d\xe0\xea\x75\x2c\xa2\xc4\x56\x33\xb6\x6f\xe7\x7a\x59\x7c\xba\x17\x1c\x45\xfc\x2c\xfe\x77\xad\xe6\x97\x01\x15\xd3\x0e\x21\x1e\xb0\x16\x4a\xbe\x3d\xf1\xcf\x7c\x56\x55\xdd\xf2\xd6\x87\x60\x5d\xff\xcb\x9d\x83\x27\x0a\xbf\xa6\xe4\xb9\x33\x8e\xdc\x01\x3f\xf6\x17\x1b\x16\x8b\x28\xb6\x45\x1c\x83\x49\xdf\xcb\x1e\x2d\xe4\xe7\x61\x0a\xa3\x01\xc5\xb6\xcf\xbe\xf5\x31\x19\x5d\x46\xe2\x7b\x8c\x75\x69\x75\x35\x3e\x4c\x02\x0c\x1f\x1c\x1c\xeb\x73\x24\xdc\xa5\x59\xc2\x38\xb6\x65\x2b\xae\x61\xe9\x0c\xfe\xa6\x93\x48\xc6\xfc\x10\x43\x02\xe4\xd3\x8f\xce\xc3\x02\xc0\xd4\x85\xab\xb6\x64\xd8\x2f\xa1\x8f\xcf\x14\x06\xd8\xb6\x12\xcd\xde\xe3\x7b\xe0\xe0\xdf\xcd\x11\x8e\x74\x70\x63\x35\xd1\xbc\x63\x57\xef\x3b\xe3\x31\xc5\xf2\xf6\xd2\x09\xf0\xdf\x08\x4d\x7e\xbe\x47\x30\x11\x1a\xd6\xe7\x5b\xd1\x41\x5d\x99\xf4\x25\xb1\xea\xe6\xeb\xc5\x73\xf3\xde\xae\xdb\x8a\x47\xfb\x23\x65\x12\x85\xb4\xab\x70\x6e\x6b\xfe\x7e\x05\x54\x9e\x2e\xed\x30\xf0\x05\x36\x11\xb8\x32\xaa\xda\x87\x92\xab\xb3\xbb\xc4\xff\xdb\x6d\x6e\x06\x21\xc3\x12\xc1\xa9\x49\x6c\xf7\xe1\xbe\x84\x23\x47\xb3\xad\xfd\x60\xdd\x62\x40\x0d\x0b\xe3\x91\xff\xd8\x34\x0b\x6d\xaf\xcc\xcf\xb4\x67\x0c\xcb\xcc\x36\x31\x98\xdb\x3a\xf4\x08\xe9\x59\xf3\x2d\x73\x3e\x06\xaa\x32\x1d\x87\xe8\x0a\x68\x01\x44\xe6\xa6\x5c\x77\x15\xcd\x68\xee\x91\xd8\x91\xd7\xf6\x58\xc0\x74\x7f\x4f\xa4\x68\x4d\xeb\x37\xc6\xbd\xa9\xe7\x49\xef\x46\xb1\x08\x05\x7e\xde\xd2\xc3\x1b\x54\xf5\x3c\x55\xeb\xaa\x6d\x4a\x72\x9f\x2b\x8c\x7f\xbe\xad\x5e\xb6\xeb\x67\xd7\x78\xe3\x41\xe8\x61\x22\x84\xb5\xf9\xc5\x1b\x6f\x56\xaf\x6d\xb7\x33\xf0\x80\x18\x50\xcb\x43\xaa\x61\x0b\xf5\xde\xf3\x92\xf6\x90\x26\x32\xb0\xf1\x58\xb3\x43\x57\xdb\x9a\xb7\xae\x03\x9a\x87\x1e\x43\x19\x23\x9b\x7b\xdf\xa5\x95\xe4\xd9\x3f\xc1\x69\x0a\x69\x1e\x06\x86\xae\xb2\xdc\xee\xf6\xb3\xe5\xb7\xf5\x76\xf5\xb2\x6d\x8f\x45\xc6\x81\xdd\xc2\x23\xc7\x64\x40\xcd\x43\xa6\x50\x91\x78\x95\x81\xac\xcb\x54\xf6\x9e\x59\x73\x0c\x6f\xfa\x7e\x4a\xb2\xaf\xaf\x6b\xae\x79\xe4\xf1\xc8\x4e\xf8\x43\xce\xf3\x7a\xc3\x73\xc5\xdb\x4b\x88\x98\x91\xe3\x87\x1f\xa7\xb4\xbc\xac\x4e\x85\x74\xd9\x07\x8f\x7d\x8d\xd5\x17\x44\x9f\x6e\xcf\x28\x81\x35\x1d\x22\xf1\x38\xf2\x30\xf3\xab\x9b\x5c\x64\x94\x22\xf1\x98\xf8\x18\x80\xa3\x8e\xeb\x21\xcd\x01\x4a\xe4\x0c\x6b\x2e\x47\x65\x0f\x1e\x53\x6d\xaa\x3b\xae\x2d\x6f\x79\x0f\xed\xa9\x2c\x3e\xac\x49\x88\x96\x5d\xa4\xc3\x63\x16\xa3\x93\x37\xfc\x48\xeb\x11\xdf\x80\xc7\x1c\xac\xb8\xe1\x5a\xf5\xdc\xe3\x2c\x15\xd1\x0e\xa2\x56\x70\x19\xeb\x2d\xf3\xf3\x65\xec\x57\xa5\x79\x12\x68\x6a\xde\xeb\x8f\xb4\x2a\xac\xed\xed\x20\x7a\xe7\xcd\x52\xeb\x19\x53\x8e\x63\x5a\x55\x58\x4e\x5b\x4c\x5b\xc8\x8c\xce\xcd\x25\x62\xbd\xb7\x75\x59\xe4\x87\xaf\x5d\x63\x8b\x27\xd2\xd4\xae\x1e\xd7\x4f\x88\xf8\x68\x55\x17\x35\x67\x9e\xa6\xa6\x86\xa8\x00\x8e\x03\x91\xd1\x41\xe0\xd1\xe3\x4d\x6a\xce\xa8\x01\x35\x37\x1b\xa7\x49\xa4\xa7\xdb\x30\x9c\x87\x31\x16\x06\x3e\x8a\x1a\x65\xb4\xdc\x9f\x63\xaa\x8c\x55\xec\x29\x2b\x2e\x8e\x51\x3e\xc4\x88\x8f\x9a\x21\xed\x7f\x86\x8f\x9a\x33\x19\x58\x76\xcc\x2c\xcb\xa6\x58\x16\x9c\xab\x98\x93\x4e\x05\xfb\x56\xb9\x9e\x0b\xcf\xc8\x92\x34\xeb\x09\xd6\x7c\x9a\x1b\xd2\x2e\xe6\x5c\x84\x01\xce\xe3\x55\xfd\x66\xd0\xe0\xb7\xd2\x3b\x2e\xa8\x92\x4e\x26\x13\x75\x1e\x0c\xa9\x20\x5b\xd6\x7d\x7d\x97\xf6\x1e\x09\x66\xf8\xc5\xc6\x9b\x7c\x7e\xee\xbb\x51\x6a\x2e\xb9\x02\x5b\x7b\xbe\x4b\xb3\xfa\xda\xdc\xd2\x8d\x83\xc8\xb4\xe3\x8a\xcf\x3f\xcf\x9d\xe1\xbf\xe6\x52\x1b\xe9\x0d\x55\xb4\x28\x15\x9b\x0e\x5f\x3d\xe8\xc1\x55\xa8\xc8\x84\xd6\x18\xf9\xa0\xeb\xed\x34\xf3\x49\x73\x45\x09\x88\x56\x66\x67\xbd\x78\xee\xa5\xec\x1c\x7c\x82\x42\x06\xed\x05\x41\x20\x89\x68\x09\xd3\x36\x0a\x1c\x9e\x10\x42\x86\x7d\xd8\x0a\x65\xbc\x5f\xe0\x03\xe5\x1b\x7b\xe7\xd4\x01\xb1\x2e\x27\xcd\xce\xfb\x02\xd5\xa9\xc8\xab\xeb\xd7\xa3\x9f\x2a\x70\x4d\x13\x5c\x84\xf7\xd6\x4f\x2e\x2d\x79\xfe\xc6\x7f\x06\xfc\x48\xa6\x30\x00\xbc\xc9\xba\xb4\x23\xa4\xa2\xde\xc9\x77\x48\x11\xcc\x3b\x8a\x99\x84\xe7\x29\xed\xbb\xda\xe6\x76\xff\xf0\xbc\xf8\x63\xb5\xdc\x07\xff\x34\xc2\xf0\x5f\xdc\x28\x62\x5c\x1d\x8f\x69\x6e\x8b\xb9\x0a\x31\x82\x88\xfc\xee\x95\xc1\x85\x97\x24\x08\xc7\xc7\x34\xf0\x4a\x8d\x78\x70\x07\x85\x4f\x7d\xdc\xe1\x3e\xa0\x4c\xf5\xc5\x76\x0f\x50\x9f\x70\xfa\xed\x76\x1f\xe3\x5e\xac\x9c\x4d\xff\xba\xd9\xa6\xda\xe2\x8c\xf0\x79\x2c\xed\x73\xfb\x9e\x8e\xf1\x78\x22\x88\xa2\x28\x6e\x2d\x46\x87\xc8\x3f\x37\x44\x46\x94\x75\x66\xb1\xe3\xa3\xca\x30\xde\x31\x68\x34\x2f\x98\xfb\xe6\xd0\x33\xa8\x8b\xcf\x32\xad\xa1\x35\xf6\x3e\xf7\xc5\x8f\xae\x20\x42\xff\xfa\x9f\x9f\xa4\x8d\x22\xf4\x25\x26\xbb\x73\x14\xcd\x1f\xf8\x60\x69\x11\x46\x1e\x82\xd1\xb6\xe9\xf1\x94\x81\x3b\x38\xf9\xd6\x89\x30\x01\xec\x0c\xed\x6d\x91\xa9\xdf\x8f\x6e\xe7\xab\x08\x99\x8f\xfe\xab\x5f\x1f\x47\x17\x1d\x79\x3e\x09\x7a\x76\x81\x7b\x7c\x5e\x69\xbb\xe8\x88\x48\x26\x88\xf6\x31\xde\xcf\xe5\x71\x96\x2b\xa4\x2f\x0d\x37\x27\x11\x81\x91\x15\x6e\xc2\xa1\x5e\x29\x72\x7a\x9b\x15\x24\xe2\x98\x0c\x34\xdb\x6c\x9a\x1f\x50\xe5\xc4\x1d\x4a\x82\x08\x83\x85\xf7\x1a\x49\xd8\x93\x11\xb1\x20\x5a\x06\x9d\x45\xfc\x12\x96\xf0\x04\xf5\x67\x51\x8e\xb0\x40\x82\x46\x14\x29\x73\x26\x24\x9c\x5b\x1b\xa9\x9f\x6e\x62\x82\x0a\x8d\xeb\xc5\x67\x33\xda\x91\xff\x46\xb7\x2d\xa1\x06\xb7\x72\x4a\x7f\xc0\xa0\xbf\x26\x58\x10\xe3\xf6\x2a\x8b\xe3\x11\x33\xad\x1e\x8f\x4b\xf0\x90\x1a\x02\x7f\x6e\x1c\x3e\x06\x6c\x17\xc1\xa5\x87\x24\x9c\x3f\x52\xf9\xbe\x28\x8e\xc7\xb4\xae\x01\x45\x25\x1f\xf9\x69\x96\xab\x59\x59\xf2\x8b\x49\x48\x87\x17\xc9\xb5\xc2\x87\x6b\x2e\xb2\x89\xec\xa6\x6c\x3d\xb4\x10\xb1\x11\x8a\x70\xf5\x9f\x26\x0e\x6b\xbf\x5c\x05\xb1\x04\xc7\x2b\x4e\x8d\xe1\x82\xba\x52\xb3\x70\xc1\xb2\x50\x91\xe7\x09\xcc\x8b\x8a\x6c\x57\xbc\xae\xf3\xfe\xf2\x28\x54\xa4\x54\x2b\xf0\x75\x2d\x0d\xe7\x46\xc5\x1a\x73\xab\xea\x94\xb9\x3e\x5d\xaf\x39\x3a\x7a\x2a\x8a\x86\xe8\xe0\xf3\xbc\x7d\xcd\xd3\xd5\xf2\x75\x50\x23\x10\x2a\x91\x98\xe7\x88\xf3\x65\xfe\xf4\x34\xbc\xad\x5a\xf9\xb8\x96\x73\x29\x5f\x2b\x28\x07\x18\x6c\xa1\x55\x88\x05\xdf\xbb\xa2\xd8\xd6\xaa\x9f\x33\x48\xcf\x8b\x91\xe9\xfc\x67\x9a\x1f\xee\x20\x3f\x2c\xb8\xf8\xb8\x92\x85\x3b\x5f\xc1\xa3\xa5\x17\x25\xa8\x38\xbb\x28\x4a\x18\x82\x6b\xa5\xa7\x3c\x44\xee\xbe\x1d\xea\x16\x98\x6e\x0f\xf9\xc2\xc3\x74\x4b\x38\x1d\xdb\x69\x3c\x8b\x0c\xfd\xc0\x27\x6d\x9f\x7e\xe8\x73\xa4\x65\xc8\x69\xcc\x7a\x65\x9d\xdb\x44\x2d\x19\x6a\x1f\x69\x07\x5f\x2f\xa7\x21\xb5\x4a\x46\x01\x43\x68\x93\x81\x77\x8d\xa2\x60\x19\x25\xd2\x10\xa7\x7a\xad\x9f\x76\x2f\x18\xed\x65\xc3\x9f\x1e\x09\x81\x25\x65\x6c\x6a\xa2\xd5\xd3\xa2\x68\xbb\x9b\x92\x04\xdc\xd7\x3d\x3d\x98\xf9\xe5\x61\x30\xf1\xae\x2e\x80\x44\xc0\xfb\xb6\x6f\x86\xc0\x35\x28\xe2\xd9\x91\xb1\xd6\xa8\xe9\x24\xb3\xa2\x82\xed\x59\xd8\xa0\xd6\x7d\x33\x65\xd4\x05\x38\x68\x66\x32\x2f\x72\x35\x68\x1d\x0f\xa7\xa2\x4c\x88\x42\xaa\xa7\x43\x7e\xd8\x5e\x7c\xfb\x28\x13\x21\x15\x75\xcd\x51\xbd\x2b\xe6\x97\xf5\x2f\x58\x7e\x32\x91\x11\x6e\x6d\x26\xb5\x2b\xf2\xea\xdc\xee\xba\x92\xf9\x24\x30\xa2\x87\xe3\xa8\xcf\x0d\x08\x42\x43\x56\x38\x8b\xd5\xb1\x09\x67\x9b\xe7\x39\xd5\x61\x9a\xfe\x6e\x96\x30\xe7\x95\xdf\xbc\x1f\xfd\x0a\xa0\x1d\xc1\x03\x86\x9c\x51\x67\xd4\x89\x1e\xc7\x6f\x3c\xb4\xb8\xb7\x5b\x62\x47\xc3\xaf\xe1\x22\x74\x2e\xf2\xd8\x83\x5d\xda\x4e\xfd\x36\x3d\xe4\xbc\x3e\x97\xd0\xde\x3f\xae\xa2\x08\x9c\x81\x74\x71\x3e\xdd\xa5\x4e\x8f\x75\x30\xd7\x85\x0f\xca\xfe\x6e\x87\xc2\x36\x90\x87\xfe\xca\x20\x45\x68\xfc\x7e\xeb\x14\x4a\x6f\x74\x5d\x42\x10\x65\xcc\xc3\xd2\xbc\x6e\xd6\xcd\xf6\x27\x48\x2a\x84\xee\xee\xc9\xac\x9e\xa8\xcc\x49\x99\x44\x49\x64\x05\x8c\xb1\x59\xb0\x7a\x59\x60\xe2\x68\xe4\xe1\xda\x73\x41\x68\x20\x4b\xc6\xbb\x72\x73\xb7\x45\x53\x93\xc1\xb5\xa8\x38\x42\x37\xb4\x3d\x02\x9e\xe6\x97\xe6\x85\x92\x6f\xf0\x4b\x6e\xef\x55\x62\x24\x95\x14\x58\x1e\x9e\xbd\x15\x45\x06\x60\x71\x10\xf0\x3b\x00\x98\xdf\xad\x6f\xda\x6f\x02\xa9\x11\x20\xb2\x79\x31\x28\xfe\xfd\x76\x37\x7b\xd9\xed\x43\x77\xdd\xda\x37\x56\x20\x59\x81\xed\x9b\xb4\x02\x23\x84\x31\xe6\xaf\x4a\x1d\xf8\x08\x67\x84\x66\x6f\x43\xf4\x8c\x93\xb7\x1e\x7e\xa3\xf2\x3d\xc0\xe4\x16\x25\x50\x36\x45\x31\xb4\x94\xc0\x75\x3e\x31\x95\x88\x59\x56\x02\x57\x97\x8d\x09\xf4\xc6\xdf\xa8\x22\x4f\xa0\xf7\x84\xd5\x55\x28\xca\x11\xda\xc9\x0d\xf3\x13\x2c\x28\xfd\x79\xe6\x79\x7d\x3e\xfe\xd5\x0a\x92\x69\x15\x11\x8d\xae\xeb\x43\x44\xdd\x40\x35\x78\xf4\xe3\x23\xca\x84\x70\x52\x3a\x15\xf4\x89\xe9\x5d\x6e\xe9\xc6\x26\x82\x1a\xab\x85\xcb\x4d\x55\xb2\xd1\xd9\x13\x1d\x79\xae\x8f\x9e\xc1\x81\xab\x62\x09\x46\x4a\xaf\x2e\xbe\x61\x0c\x3e\x8c\xd8\x54\x04\x1e\x04\x3d\xe0\xf5\x5a\x16\x83\x7d\x53\x45\x40\x31\x48\xfb\xba\xfb\xaf\xfe\xf6\xa0\x22\x1d\x21\x3a\x73\xd8\x46\x42\xe8\xe2\x08\xbe\x6b\x3f\x40\xa8\x8f\xb9\x3a\x5a\x07\x56\x2d\x87\xbd\x8d\x31\x55\x9c\x44\x18\x0c\x37\xcf\x0c\x83\xcb\xa9\x82\xec\xe8\x82\x63\xee\x61\xe0\xba\xb0\x96\xbb\xc7\x34\x37\x8c\xcf\x9f\x8a\x51\x28\xea\x1b\x37\xb1\xac\xe0\xaa\xbf\x41\x8f\x46\x45\x9e\xd2\xad\x71\xd7\x53\x31\xc6\xb2\x2a\x2a\x08\x82\x46\x52\xdc\xa4\xbf\xa7\xf5\xdb\xe2\x5c\xd5\xc5\x11\xca\xde\x52\xdf\x7f\xc3\x55\x42\x44\x9c\x38\x0d\xa4\xbc\x2e\x8b\x2c\x83\xd2\x51\x03\x47\x5f\x9f\xc4\x11\x56\x81\xe4\x5b\x0a\xda\xdd\x24\x26\x39\x3e\x61\xb7\x3f\x9a\xc7\x19\x78\xff\x38\x8f\x35\xa8\xb4\xe2\xdc\x47\xac\x01\x3e\x9a\xef\xe3\xbe\xf8\xf8\xf5\x1f\x5e\x1a\x17\x46\x51\xdb\x5c\xfb\x2a\xaf\x47\xce\x91\x5a\x09\x0f\x84\x15\x1c\xfb\x0b\xc5\x99\x6c\xdf\x67\xc0\x97\x55\xcd\xea\x40\x7a\xa1\x48\xf3\x33\x9e\x78\xd9\x2c\xfa\x1f\xd7\x6c\xb1\xc1\xbd\x52\xbe\x97\x58\xf5\xb0\x61\x03\x66\x38\x8a\x48\xed\xbb\x12\x90\x2e\x46\xf7\x10\x3c\xe9\x7a\xc8\xf7\xfc\x38\x8c\x8a\xdd\x90\x04\x90\xf7\xab\xd2\xaa\x89\x08\xe6\xe7\x3c\x1f\x83\x4f\xc0\xe3\xc6\x37\xd6\xe5\x47\xdb\xcb\x51\x14\x99\xe1\x5a\x7c\xe9\xb5\x08\xdd\x70\xcd\x51\x4f\x60\xc1\xcb\x11\x5d\x0a\xfc\x84\x81\x75\xaa\xfc\x30\x1b\xa7\x67\x8f\x04\x89\xe7\x90\xc2\xd3\x76\xf4\xfd\x67\x0b\x81\xa2\xd4\xfc\xea\x12\x64\x5d\x94\x0f\x1d\x9b\x0f\x42\x2f\x50\xbe\xab\xfb\xfc\x3d\xd8\x62\x20\x8c\x4c\x63\xcb\x50\xa6\xac\x60\xe1\x68\xe2\x43\xc8\xa5\xa4\xed\x5e\x65\xab\x46\xb8\xdd\xd7\xbc\xbc\xb6\xad\xd2\x10\xca\x18\xf5\x77\xfe\xfe\x23\x6d\xe1\x9a\x10\x11\xe1\xdb\x7b\xff\x75\xf7\xb0\x58\x3b\xbd\xcd\xb4\xc8\x77\xe9\x11\x8a\x73\xdd\xd1\xf7\x86\x95\x9f\x49\xd7\x10\x0d\x51\x22\xa9\x53\xf5\x5f\x2c\x77\xcd\xa4\xbb\x2b\x26\x44\xb0\x34\x44\xcc\xc7\x3a\xe3\x9b\x81\x52\x4c\xaf\xc5\x10\xb1\x58\x07\x2d\x87\xe1\x90\xe6\xdb\x13\xe4\xa3\x4d\x02\x22\x0d\x58\x6f\xc6\xad\xfd\x6e\x0c\x81\x03\x42\x8c\x1d\x8e\xcb\xe5\x16\x25\xa8\xd4\xb8\x8f\x4f\xce\x57\x20\xd4\x28\x9b\x2c\xf9\x8f\x9e\x6a\x04\x10\x2a\x71\x27\x11\x97\x73\x71\xae\x67\xfd\xd0\x01\x62\xdf\x60\x0e\xc4\xf9\xb2\x69\x32\xcd\x5e\x5f\x3b\x1a\xae\x8b\x91\xfb\x44\x64\x64\xc4\x6d\xc3\x67\x96\x65\xcf\xb9\x84\x7e\xf1\xcc\x0d\x14\x02\x2b\xdd\xc7\x8b\x65\x97\xba\x75\x1f\x12\x00\x4c\x52\xb6\x18\x57\x5d\x23\xf5\x80\x79\x02\xe5\x07\x0a\xad\x2b\xa8\xfb\x54\x7a\x60\x11\xc7\x7c\x5b\x9c\xcb\x7c\xc3\xab\x6a\x52\x2f\x55\x03\x63\xd2\x41\x9e\x8d\xff\xdd\x16\x6f\x54\x35\xee\xc9\x00\x8f\x43\x74\x04\xef\xc0\xbc\x93\xc1\x6c\x32\x3a\xbf\xa0\x8a\x5a\xb0\xe3\xeb\xe9\xd0\x84\x64\x8f\xbc\xaa\xaf\x5e\x6e\x19\x46\x68\x81\x8b\xb7\xf5\x31\xcd\xeb\x4d\xb1\x1c\x70\xd3\x41\x6a\xe2\x5b\x49\xa5\x79\x31\xca\xbb\x41\xc5\xa0\x6c\xd2\x39\x53\x5f\x7a\x8d\x2e\x77\x5c\xa9\xc8\x3a\x60\x6c\x8a\x2c\xed\xa9\xc7\x0e\x3a\x60\x93\x6b\x20\x00\x6d\x55\xe7\xe6\x45\xf1\x3e\x58\x5b\x01\x78\x40\xfb\x99\xbc\xd9\xf9\x82\xee\xb0\x4c\x0c\xed\x58\x17\x7b\x94\x6f\x71\x07\xa4\xe6\xdc\xa0\xad\xfc\x71\xbd\x7c\xcc\xb5\x19\xd7\xc0\x3b\x5b\x47\x0d\x3a\x10\x58\xd1\xdd\x5a\x71\x06\xa8\x51\x14\x00\x27\xbf\x13\xf7\x73\x43\x13\x9d\xb4\x7a\x33\xa3\x89\xa4\x99\x40\x5d\xe9\xbd\x11\x02\xe7\x3f\x0c\xd7\x7e\xa2\x84\xae\xbd\xc8\x68\xd5\x5b\x75\x02\x5c\x50\x6c\xd0\xf6\x54\xd4\xff\x0d\xa5\xe3\xc0\x68\x8f\x06\x48\x28\x3b\x61\xe1\x7b\xf5\xe3\x0a\xcd\xa6\x7d\x8f\x3b\x65\x5b\xdc\x5e\xaa\x81\xdd\xbe\xd6\x41\xe2\xdb\xa6\x29\x32\x91\xfb\xc1\x8f\x0e\x7d\x1f\x5f\x62\x14\xa5\xde\x42\xfd\x6f\x2e\xdf\x4f\x45\x3d\xad\xf7\xa0\x43\x12\x23\x25\x29\x95\xc5\x03\x3f\xe7\xf2\x6d\x2c\x21\xa0\x43\xee\xa1\x64\xd2\x38\x61\x9f\x12\xef\x45\xda\x67\xe8\xa4\x3e\x2d\xf6\xbf\x49\xd7\x76\x25\x97\xef\x1d\xcb\x4d\x87\x32\x22\xd4\xc6\x53\xd6\x4b\x70\x54\xec\xd4\x51\x28\x30\xc7\xda\x37\xe1\x68\xf3\xb2\x36\xd1\xf4\x70\x08\xa1\x62\x50\x2e\x32\x02\xcb\xb7\x48\xe8\xed\x87\x4c\x7f\x16\xef\x1c\x17\x19\x3c\x2f\x5c\x72\x36\x5d\x0b\xd4\x31\x27\x18\xd7\x3c\x14\xf9\x61\xbe\x28\xae\x25\x30\xaf\x4b\x2c\x3a\xd6\x46\xc7\x7a\xb7\x7b\xfe\xea\x2e\x9a\x26\x1a\x71\xad\xaa\x40\x1b\xb1\xf6\xcf\x9c\x51\x5b\xd7\x1a\xd9\xef\x0e\x7f\x46\x12\x02\x2e\xb5\x16\x70\xeb\x08\x88\xc3\x5b\x92\x90\xf6\x8d\x5e\xbc\x9d\xf3\x77\xbf\xef\x2a\xe0\xc6\xa8\x08\x97\x2c\xec\x64\x1b\xb9\xc3\x34\x3f\xcc\xda\xe3\x2c\x04\x19\x3a\xb3\x4d\x6c\x0f\x6f\xf8\x61\x58\xc6\xd1\x8c\x48\x08\x1d\x00\x75\x53\x14\xed\x74\x61\x71\x60\x48\xd5\x2f\x2b\x4c\xb9\xbe\xcd\x5e\x1f\x76\x26\xf1\x6a\x87\x28\x22\x2c\x7d\x5a\xa7\xe5\x11\x4b\xee\xcf\xfa\x7b\x51\x8e\x38\x36\x9a\x33\xb3\xb6\x9a\xe7\x5b\x7c\xee\x46\x21\x94\xe6\x4c\x39\xf7\xd3\xfb\xa2\x50\x63\x0a\xdf\x68\x6e\x0a\xe2\x23\x23\xb9\xb7\x54\xff\x34\xd0\xd4\x52\x01\xf6\x8d\x57\xcf\xdb\xf5\x53\xfb\xf3\x25\x24\x28\xa5\x2d\x10\xa4\x3e\x14\xdc\xe9\x45\x5a\x5a\x91\x40\xc6\x76\x8e\xf7\xa6\xbe\xe2\x09\xbe\x71\x19\xaf\xea\xaf\x45\x59\xc1\xb6\xdd\x9c\xb4\x12\x60\xdc\x30\x91\xf8\x69\xd2\x96\x41\xb1\x40\x83\x97\x24\x06\x63\x92\x8d\x4a\x77\x1a\x84\x4d\x62\x6c\x0d\x04\xf3\x94\x6d\x7a\xc8\xe7\xcd\x9b\x33\x78\x19\x46\x33\x4b\xc7\x02\xcb\x69\x16\x9c\x39\x2d\x68\xd6\x5c\x38\xd6\xbd\xa1\xa7\x7a\x6a\x72\xe1\x2f\xff\xef\xff\xf3\xff\xfd\xff\x01\x00\x00\xff\xff\x41\xc7\x6f\x7d\x39\x03\x54\x00") + +func _4byteJsonBytes() ([]byte, error) { + return bindataRead( + __4byteJson, + "4byte.json", + ) +} + +func _4byteJson() (*asset, error) { + bytes, err := _4byteJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "4byte.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x56, 0x18, 0x15, 0x8, 0x49, 0xac, 0xa1, 0xbf, 0xc2, 0xcb, 0x21, 0x40, 0xee, 0xff, 0xc2, 0xba, 0x46, 0xc0, 0xe1, 0x85, 0xa1, 0x44, 0xe7, 0xca, 0xd6, 0xfd, 0x44, 0xf9, 0x4d, 0xf, 0x34, 0x4d}} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "4byte.json": _4byteJson, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + canonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(canonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "4byte.json": {_4byteJson, map[string]*bintree{}}, +}} + +// RestoreAsset restores an asset under the given directory. +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) +} + +// RestoreAssets restores an asset under the given directory recursively. +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + canonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.json b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.json new file mode 100644 index 00000000..d23b441b --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/4byte.json @@ -0,0 +1 @@ +{"00000001":"account_info_rotate_tine(uint256)","00000002":"razor_balance(bool)","0000000c":"gumXZCZ()","00000033":"matchTokenOrderByAdmin_k44j(uint256[])","00000039":"XXX_unrecognized_adapter(string)","0000003a":"good_mirror(uint256,uint32)","00000063":"math_rotate(uint256,uint256,uint64,uint64)","0000006e":"display_allow(uint256,uint256,uint256,uint32)","00000080":"conduct_auto(uint256,uint256,uint256)","00000082":"artefact_keep(bytes1)","000000a0":"tree_stream(bytes,bytes)","000000a1":"pistol_valve(uint256,uint32)","000000b6":"matchByAdmin_TwH36(uint256[])","000000c4":"festival_happy(uint256,uint256)","000000c7":"lend_during(uint256,uint256,uint64,uint32)","000000da":"muscle_teach(uint256,uint64,uint8)","000000db":"viable_print(uint256,uint256,uint64)","000000de":"pledge_future(uint256,uint32,uint8)","000000ed":"access_coconut_alarm(uint256)","000000f5":"cherry_tomorrow(uint256,uint64,bool)","000000f8":"required_strconv(string,string)","00008962":"token(string,uint8,string)","0000aeb3":"migrateByAdmin_DQV(uint256[])","00012f8b":"LatiumX()","00014502":"totalInfected()","000150a0":"DEV_TEAM_STAKE()","00020a28":"HaltTokenAllOperation()","000267a4":"getUint()","00026e13":"checkAtkBossQuest(address)","00027737":"aicontract()","0002aa37":"richtestkk(uint256,string,uint8,string)","0002c1dc":"Johnsonville()","00046c1f":"totalDragons()","000525fd":"robCoin()","0005a533":"CoalichainToken()","0005bfb7":"gemmyMusicLockTime()","000713fe":"Initiate(address,uint256,uint256,uint256,bool)","000751b8":"LogExtendSale(uint256)","00076943":"unlocker()","00076de7":"disableSellerCancel(uint16,address,address)","00085d25":"round3()","0008f8df":"changeIcoFinish(uint256)","00094161":"TERMS_AND_CONDITIONS()","00096469":"AuctionCreated(uint256,address,uint256,uint256,uint256,uint256)","0009803b":"makeProject(address,string,uint256,uint256)","00099cdf":"withdrawTokens3(uint256)","000a4a7a":"backAtIndex(uint256,uint256,uint256)","000ac1ff":"addparts(bytes32,uint256,uint256,uint256)","000adc67":"buy_the_tokens(string)","000b66d3":"setIcoStartTime(uint256)","000b9726":"MintingContract()","000be356":"expiredBlock()","000c12af":"TOTAL_TOKENs_SUPPLY()","000c65c3":"withdrawVNET(address,uint256)","000ca58e":"refundRequestTimelock()","000dae5c":"claimantConvicted(uint256)","000e02d0":"fiveHundredThousand()","000e28d3":"setLandsLimitPerBid(uint256)","000e2f3a":"totalLBSold_GENERAL_1()","000e60f8":"pendingBetsBalance()","000e7fa8":"presalePrice()","000f0ded":"doAirdrop(address,uint256)","000f71f8":"recieveNegReq(uint256,uint256,uint256,uint256,string)","00100a18":"NewPoll(string,string,uint256,uint256)","0010ed99":"getBraggerAtIndex(uint256)","00113e08":"getBalances()","00115cba":"UpdateSellAgentBounty(address)","001246eb":"availableFlg()","0012d90a":"BNB_HARD_CAP()","001339b0":"prizePoolTotal(bytes4)","00137d6e":"peculAdress()","0013da50":"delList(string,uint256,uint256)","0013eb4b":"isExist(address)","0014f956":"getResourcesInfo(address)","00152924":"setSelfContractAddress(address)","0015be71":"executiveOfficerAddress()","001667bb":"getPI_edit_34()","00173d65":"getShouldGenerateDna()","001773e6":"convertMetToEth(uint256,uint256)","0017cd8b":"PRIME()","0017e1cf":"getTeamNameForAddress(address)","0018b1d3":"pps()","0018b665":"killTokenContract()","00190f64":"getStatusLogs()","00199b79":"_updateList(address[],address,address[])","0019a46b":"gen0CutieCreatedCount()","0019c97d":"redeemPop(uint256)","001a4f5e":"createNewRevision(bytes32,bytes32)","001aa026":"withdrawMarginPreSigned(bytes,address,uint256,uint256,uint256,uint256)","001ab1cd":"setAsBurner(address,bool)","001ab993":"VTestDistribution(address,uint256,uint256)","001b1441":"Ethernext()","001b1cf0":"DualMintableToken(address,address)","001b3fe6":"card_blue_first()","001ba7ea":"signWitness()","001baa89":"createdBy(uint256)","001bc69a":"getGratitudesOf(address)","001cf577":"wcOnCrowdsaleFailure()","001d7bf6":"getInvestmentArray()","001db74d":"FreeLove()","001dbe8a":"getSoftwareExecRecordLength()","001ed012":"previousBurners()","001ee6b2":"participateGame(uint32,uint32,uint32,uint32)","001f0479":"getResultMask(uint256,uint256)","001f4701":"Examples()","001f8d11":"removePackage(bytes32,string)","001f91ce":"curatorAddress()","001f9bc0":"set_arbits_presale_open(address,bool)","00201e33":"BONUS_6_DAYS()","00203116":"endGame(address,uint8)","00203385":"getTotalBorrowingItem()","00212667":"m_Creator()","0021d364":"getNOVotesByEntity(uint256)","00226eb5":"getDepositNum()","0022771f":"numAdviserDeposits()","002338ef":"TLSC()","0023de29":"tokensReceived(address,address,address,uint256,bytes,bytes)","00245220":"HAJDToken(string,uint8,string)","0024eb4b":"getCompanyAllocation(uint256)","00277883":"TeamTokensHolder(address,address,address)","0028b91f":"Distributor(address,address)","0029514f":"PROCESSBY()","00297671":"cancelOneSell()","002a2133":"createCitizen(uint16,uint16,uint8,bytes32,bytes32,bytes32)","002a228c":"initSeed(uint256)","002a4b14":"Nine()","002a5cc9":"getTicketHolders(uint256)","002beece":"unfroze(uint256,address)","002c1a9e":"percent(uint256,uint256,uint256)","002c8456":"toOpenVote()","002ce636":"settrusteeVaultAddr(address)","002d7c9d":"concludeFirstAuction()","002dc7f1":"ChangePeriod()","002e0ae7":"transferTokenOut(address,uint256)","002e1316":"maxInvestment()","002e1d7e":"LCOpenTimeout(bytes32)","002f15ca":"isExistInvestor(address)","002f9569":"allocatedTokens()","002fd07c":"_approve(address,uint256,uint256)","003074ff":"getFrontend()","003078b0":"unlockTo(address,string)","00310e16":"sellWolk(uint256)","00319aad":"_transferadvanced(address,address,uint256)","0031a48e":"myICO()","00322bb6":"sendPlatformMaintenance()","003259ea":"voteResult()","003271d5":"checkStateProof(bytes32,bytes,uint256[],bytes,bytes)","00333375":"minimumMainSaleRaise()","003338a0":"DrawOp()","0034451c":"_buildInternalSalt(uint128,address,address,uint256,uint64)","00346b57":"setHodlerStake(address,uint256)","003495a4":"getHighestBidder()","0034b5fd":"withrawFundTeacher(uint256)","0034f529":"_requestExists(address,uint32)","003538c5":"TestRegistrar(address,bytes32)","00354975":"VRYCoin()","00359e08":"presaleFinishedAt()","0035a45c":"isAllowedToPurchase()","0035ceb1":"BrinkzToken()","0036059c":"TESTER(uint256,string,string)","00360b66":"MyMonsterIds(address,uint256)","0036242d":"Power2X()","00362509":"LogWin(address,uint256,uint256,uint256)","00362a95":"donate(address)","00364ceb":"bountyManagementWalletAddress()","0036624a":"AmountReceived(address,uint256)","003705bc":"getTotalUSDInTokens()","0037dd47":"addUniqueSaleTokens(address,uint256)","00383d0a":"maxSignup()","00387733":"setGameResult(uint256,uint8)","0039522c":"emergencyWithdrawal(uint256)","003958e2":"LogOperatorAdd(address)","00397647":"addToFreelancerTotalEarned(address,address,uint256)","0039ad6d":"ROUNDS_KEPT()","003a3d80":"GetSale()","003a5b06":"getRoundEndBlock(uint32)","003a661d":"renounceOwnedOwnership(address)","003ab1ff":"timereum()","003b0a3f":"getFreeDino()","003b9d88":"setLowerFeePercentage(uint8)","003ba1ed":"setRoot(address)","003bcb34":"Received(address,bytes,uint256)","003cdf26":"Lima()","003cee5a":"HLCToken(address,string,string,uint256,uint8)","003db783":"Purchase(uint256,uint256,uint256,uint256)","003de230":"participantClawbackEther(uint256)","003e9d5b":"FillOrder(uint256,uint256)","003ead5f":"setPVEBattleFee(uint256)","003f07fa":"isValidAddress(address)","003fd35a":"CONTINUE_MINTING()","00404930":"CryptoRiyal()","00405351":"getWarriorChestAvailable()","004056c7":"validateNameInternalET(string)","004079b6":"CheckExec(string)","0040ff6c":"changeFee()","0041edee":"preSaleTokensLimit()","004240e3":"startTransaction(address,address,uint256)","004264c3":"overflow()","0042a3be":"isPublish(bytes32)","00432cf3":"getCurrentMarginAmount(address,address,address,uint256,uint256,uint256)","0043cce7":"technologyShare()","00442a07":"getLoanConfig(uint256)","00452636":"GxManagedWallet(address)","0045626f":"returnETHByOwner()","0045a4d4":"isPointerExpired(uint8)","0047850a":"getOfferCountByToken(address)","00478f87":"TIC()","0048236b":"setOrganName(string)","0048d680":"testTransferVotes()","00498257":"maxWeiTier2()","0049f068":"onContribute(uint256,address,uint256)","004b1e75":"actionAuthorisedBy()","004bd9a5":"setRate5(uint256)","004c942e":"Request_Dividends()","004d39b1":"HavvenGold()","004d4ed9":"setRegion(uint256,uint256)","004db370":"DawnCoin()","004dcd1c":"changeBrick(uint256,string,string,string,bytes32[],uint256)","004ebaa8":"silo_timer()","004ef6c6":"book(uint256,uint256)","004f3e86":"forceCancel()","004f4042":"takeAllPossible(address[3][],uint256[3][],uint256[],uint8[],bytes32[],bytes32[],bytes4)","004f4803":"raise(uint256)","004fba00":"addAdminAddress(address)","00501553":"subHours(uint256,uint256)","005016a3":"checkReturnValue(bool)","0050945d":"referrerLevel2Ether()","0050a315":"getCreationTs(uint256)","0050b3df":"newAlex(address)","0052992e":"buyForInvestor(address,uint256,string)","00530933":"BuyAsset(uint256)","00541756":"jackPotB()","0054438d":"validateResale(address,uint256,uint256)","0055bc9c":"withdrawAtOnce(uint256)","0056c4c2":"getTokensForWei(uint256,uint256,uint256,uint32)","0056ce89":"getCryptoPicture(uint256)","005733e6":"EMISSION_FOR_SALESTAGELAST()","00573858":"setrateIco(uint256)","0057e18f":"setPlatformMaintenance(address)","0057e8d4":"restoreToColdWallet(uint256)","00599e65":"getTokenOrder(address,address)","005a7d9a":"forFund()","005ab803":"LogRegister(address,address)","005b42cb":"MainSalePrice()","005b4487":"totalPayments()","005b7ce8":"SIGMA_EXTRACTION_BASE()","005b9b48":"sellAnimal(uint32)","005bb714":"BlocksToken()","005c0541":"_totalActiveBets()","005c33e1":"receiveFunds()","005d204d":"dataIdentifiers()","005e885e":"getSigners(uint256,uint16)","005ef4ec":"setReservedTokensList(address,uint256,uint256,uint256)","005f41cc":"create(address,uint256,uint256,uint256,bool)","00601801":"setCCH_edit_4(string)","00601d6c":"board(uint256,uint8,uint8)","00603126":"computeNodeId(bytes32,bytes32)","00604854":"FreePPCoin()","0060c778":"removeCompany(bytes32)","00613e27":"register(address,uint8,uint16,address)","0061c78e":"PayoutIncreased(uint256,uint256)","0061ebed":"TransactionFeeChanged(uint256)","0062c8cb":"canCallWithNoOne()","00634064":"Lescoin(address,address)","00639319":"Milestone_BankLicenseSuccessful(string)","006409c4":"Signed(address,uint256,uint8,bytes16,bytes)","0064575f":"shiva()","0064b1f8":"gameNum()","0064d618":"add_referral(address,string,uint256)","0065318b":"dividendsOf(address)","0065d700":"getTileFromBattleboard(uint16,uint8)","0066753e":"removeCertifier(address)","0067a9fb":"BrokerImp(address,address,uint256,address,uint256)","0067ba69":"FT_TOKEN_SALE_CAP()","00686741":"registerProxyFor(address)","00691967":"SUPER_HERO_MULTIPLIER()","006932bb":"whitelistAllAddresses()","0069a132":"AshenVoid()","006a003e":"planetCordinates(uint256)","006a6ef6":"create(address,address,address,address,address,address,address,uint256)","006ac4bf":"findNextMonth(uint256,bytes2)","006ae9d5":"HopeToken()","006b1fd1":"purchasedCount()","006bcb71":"witness(bytes32,address)","006c10e8":"trackPurchase(uint256,uint256)","006c2abc":"privateSaleEndDate()","006c81d3":"isAllocated()","006cfea8":"_delegateAssetOwnerAdded(bytes32,address)","006d96e0":"hasVaultAccess(address,address)","006ddae3":"changevotePrice(uint256)","006e3a1d":"exitOverPlayer()","006f91d2":"RiskPrice(uint128,uint128,uint128,uint128)","006fbd88":"changeSellGenesPrice(uint256,uint256)","00703d48":"crearCelda(uint256,uint256,uint256,uint256,uint256,uint8)","0070c3b3":"Proxy(address)","0070c537":"increaseBid(uint256)","007188d3":"FAOC()","0072615c":"claimedBoards(uint256)","00728f76":"vestingAmount()","0072d7b5":"addressAdded(address)","00732113":"setHolderInformation(address)","00739f2a":"changeStartDate(uint256)","0073c769":"disableTime()","0074477d":"listMultipleItems(uint256[],uint256,address,bytes32)","0075a317":"mintTo(address,string)","00761731":"createContract(bytes32,uint256,uint256,uint256)","00774360":"deploy(bytes)","00797f77":"has_donated(address)","0079efb0":"withdraw1()","007aa091":"san_whitelist(address)","007aaac9":"sisterCheckPrice(uint256)","007b2a03":"GoldTokenERC20()","007bd509":"generalTerms()","007c197d":"ISE()","007cb3fb":"updateOraclizeGasPrice(uint256)","007cc224":"RESERVED_TOKENS_FOR_PLATFORM_OPERATIONS()","007d8051":"issueAndFreeze(address,uint256,uint256)","007e5d08":"updateAvailable()","007e9355":"GetAllChallengesByAUser(address)","008000d6":"configSale(uint256,uint256,uint256,uint256)","008066b6":"doftManaged()","0081d6e5":"updateGravatarImage(string)","008201e7":"TokenSold(uint256,uint256,uint256,address,address,string)","00821b81":"bonusCalculation(uint256)","00821de3":"parentAddress()","00822599":"deleteMasternode(uint256)","008250e5":"fortune_new()","00837b15":"balanceEth(address)","00849f88":"changeFundCollection(address)","0084dbf5":"ProofOfEtherDelta()","0084fe51":"Exercise(uint256,uint256)","00851303":"tokensForSiteReg()","008557d2":"Buy(uint32,bool,bool,address)","0085c647":"setPreICOEndDate(uint256)","00862c3c":"areTokensUnlocked()","00865f92":"parseJsonArrayAndGetFirstElementAsNumber(string)","0086969f":"dissalowFreezing(address)","0086bb3e":"teamUnlockedAfterCliff()","0086ce4d":"LogUpdatedLimitPerDay(uint8,uint256)","00873367":"comparisonchr(string)","00873c97":"CLPContractToken()","00882097":"EtherDeltaDeposit(uint256)","00886980":"LogClaimReward(address,uint256)","0088fca8":"start_go_quiz(string,string)","0088fed7":"addIndex(address,address)","008a3ca1":"reverseSplit(uint8,bytes6,uint8,uint32)","008a5c23":"getCurEarlyIncomeByAddressRound(address,uint256)","008a706b":"Primal()","008a745d":"claimDividendShare(uint256)","008ad306":"changeLockCostPerHour(uint256)","008bdd13":"isWithinSaleTimeLimit()","008bed3e":"getAgreementCount()","008c1b28":"POSTSALE_START()","008c3215":"addReplies(address,address[],string,string)","008c8920":"currentType()","008ca816":"isSalePaused()","008cbc8c":"oraclize_query(uint256,string,bytes[4])","008df454":"ratio(uint256)","008e0f1b":"getTeam(uint256)","008e6865":"buyTicket(uint256,uint256,address)","008e8135":"setProviderRateHistory(uint256,uint256,uint8,bool)","008f7cc2":"requestLoan(bytes8,uint128,address,address,address,uint256,uint64,bytes)","008f8b35":"currentRoundInfo()","008fcc94":"stageEndDate(uint8)","00903c69":"Kether()","0090e9c2":"transferBonuses(address)","00918c7b":"icoPeriodTime()","0091d862":"Minaxis()","00922db6":"secondWeekBonusInWeek()","00923f9e":"tokenExists(uint256)","0093703c":"bankConfirm(address,uint256)","0094151b":"setPurchasable(uint256)","0095716b":"crownBalanceOf(address)","00961320":"stringToUint()","0097130e":"_realBalanceOnEther()","00971a30":"court()","00975ba6":"_sendP3D(address,uint256)","0097b607":"validRareId(uint256)","00983401":"setAuthor(string,string,address,uint256)","00987265":"migrateThroughAllForks()","0098728f":"buyXaddrForContract(address,uint256)","009888ce":"calcNextPrize()","00988a16":"EthMinContributionUpdated(uint256,uint256)","0098fe2b":"refundWhite(uint256,uint256,uint256,uint256)","00991d8e":"setMakeFee(uint256)","0099d386":"enableTrade()","009a1faf":"getSumOfGamblingPartiesBonusPool(uint256)","009af857":"setnextRoundId(uint256)","009b38fa":"canBeFinalizedNow(uint256)","009b9369":"getVoteNumber(uint256)","009ca5e8":"maxTokenWinValue()","009e2297":"SetFreeDCT(uint256)","009f9262":"setEthPrice(uint256)","00a0190e":"BIDDING_DURATION()","00a051ca":"FiCoinFundDeposit()","00a09a7a":"devTokensToken()","00a0d28f":"batchExecute(uint256[])","00a13901":"burnRemains()","00a16cab":"checkCutoffsBatch(address[],bytes20[],uint256[])","00a18b30":"setTeamAddress(address,address,address,address,address)","00a219f4":"payForDemocracy(bytes32)","00a22ee4":"EXOToken(address,address,address,address,address)","00a3216c":"getNextDepositBlockIndex()","00a32af6":"AIRDROP_WALLET()","00a35aa2":"deleteBoolValue(bytes32)","00a470d0":"doInvite(uint256,uint256,uint256)","00a4b146":"SDCToken()","00a53598":"emergencyToggle()","00a58a2a":"Coffee()","00a5e715":"TripCoinTeamSupply()","00a626f6":"getACLRole7123909213907581092()","00a676f9":"getExists(bytes32)","00a6dec6":"setPayerPercent(uint256,uint256)","00a70e03":"priceOfTicket()","00a7d6b3":"checkTransferFromToICAP(address,bytes32,uint256)","00a7fdfc":"bids_count()","00a81ef6":"emitRoleRemoved(address,uint8)","00a8efc7":"subBalance(uint256)","00a8f276":"last_transfer_state()","00a94b6e":"oraclize_query(uint256,string,string[5],uint256)","00aa21e6":"transferFromVault(bytes32,address,address,uint256)","00aa25b2":"_isValidAddress(address)","00aac98b":"Griefing(uint256)","00ac4663":"getWarrantyQuote(string,address,uint256,uint256,uint256)","00ac77a0":"ownerSetCanBurn(bool)","00ad3a23":"RELEASE_PERIODS()","00ad800c":"name(uint256)","00ad8035":"SwingerTokenSPICO()","00ad861f":"README()","00ad8b69":"releaseVestingAllocation()","00adc382":"addressHash(address)","00aea59b":"reviewAudit(uint256)","00aec05d":"BEECASHBACKHOME()","00aeef8a":"deposit(uint256,uint256,uint256)","00af4274":"getTokensForEther(uint256,uint8)","00af9811":"checkRedemptionFulfilled(bytes32)","00afd295":"getAllCellInfoFrom_To(uint256,uint256)","00afdcef":"ELink()","00b08526":"GXCH()","00b172d7":"buyTokensForProposal(uint256,address)","00b23740":"VersusArenaToken()","00b2516d":"vetoMotion(uint256)","00b34747":"contractInitialized()","00b37044":"totalDonated()","00b3c619":"VoteSvp001(address,uint256,uint256)","00b44750":"acceptMembership(address,uint8,uint256,address,uint256)","00b5152b":"VibeXChainToken()","00b526e4":"_sendTokensManually(address,uint256,uint256)","00b5277a":"checkSell(uint256)","00b55554":"emergencyDropEth()","00b56aa7":"emitSynthRemoved(bytes4,address)","00b5988e":"lockTournament(uint256,bool)","00b5b223":"computeResponse(uint256,uint16)","00b6849f":"airDrop(address[])","00b6b707":"accept(uint256,address,uint256)","00b76307":"ChangePrivilege(address,bool,bool)","00b767fa":"EventAddAdmin(address,address)","00b79dd9":"taxlvlEconomy(string,string,string,string,string)","00b7f20a":"isDebtor()","00b8a73c":"IntegrativeWalletToken()","00b9189d":"setPreIcoContract(address)","00b9840a":"DBDHToken()","00b99f8c":"view28()","00b9eb8b":"Coinchangex(address,address,uint256)","00ba092c":"is_current()","00ba3e50":"setProductAttributes(string,uint256,uint256,string)","00badc85":"getcvotesid(string)","00baea15":"pastOneDay()","00bbec1c":"payServiceProvider()","00bc83a9":"xToken(address,string,string,uint8,uint256)","00bca785":"state_of(address)","00bcb883":"ProposalAdded(uint256,address,string,uint256)","00bd35b8":"EventAddToBattle(address,uint64)","00bd6f4c":"transferToAddress(address,uint256,bytes,bool)","00bde030":"getDurationS()","00bdfbcd":"installed()","00c023da":"revokeAttribute(address,bytes32,bytes)","00c17ee4":"setConfig(uint256,uint256,string,string,uint256,uint256)","00c1e956":"addressFundBounty()","00c2943c":"declareWinner(uint256)","00c2b78e":"voteFor(uint256,uint256)","00c33731":"prepair(address)","00c42173":"winnerDeterminedDate()","00c43503":"totalReturns()","00c4cefa":"toKeyValue(int256,string)","00c56675":"setNegativeGrowth(int256)","00c5f509":"preICOSupply()","00c721ab":"setHand(uint256)","00c822fb":"oraclize_query(string,bytes[2],uint256)","00c8bb45":"addMeleeParts(uint8[])","00c90ac8":"AutoCoinICO(uint256,uint256,uint256,address)","00c988e8":"crowdsaleConcluded()","00c99206":"setIdentifier(bytes32)","00c9c8e7":"_emitFeeSet(uint256,address)","00cab8b1":"lockAddressValue(address,uint256)","00cae5df":"solve(uint256,bytes32)","00cb1ae4":"methodThatThrows(bool)","00cb41e3":"getWithdrawableDates()","00cb527f":"miningFive()","00cc15b0":"lengthEncode(uint256)","00cc48a6":"updateNameIP(string,string)","00ccbc68":"firstRedemptionRequest()","00ccfdab":"removeForgivedChar(uint256,string)","00cdbc1f":"changeHash(bytes32)","00cde2bb":"releaseAccount(address,address)","00ce2057":"triggerPayment()","00ce4462":"register_with_node()","00ce8e3e":"getUsers()","00ce9f8a":"getPeggedTokenValue(address,address,address)","00d11245":"Mallory(address)","00d17799":"defaultCreatedCount()","00d2c31d":"getHashSignatures(uint256)","00d30eb9":"firstWeekPreICOBonusRate()","00d32a75":"TransferDFN(address,address,uint256)","00d357d1":"CustomcoinCrowdsale(address)","00d3f51a":"VirtualRealityChain()","00d4b768":"currentMideTokenTime()","00d4b959":"ico1total()","00d52342":"loseGame()","00d56d71":"StageTwoEnable()","00d5da02":"setTokenDescription(string)","00d7b3a9":"Exoso()","00d7e9cf":"landPricePrevious()","00d7f5d8":"Human1StandardToken(uint256,string,uint8,string)","00d80e07":"getGuardianSale(uint256)","00d84fd8":"remove(uint32)","00d9694c":"setBonusRound3(uint256)","00d9f24e":"UpdateNumPlayers(uint256)","00db90d1":"setCanWithdrawBeforeEnd(bool)","00dba80c":"mineableTokenStorageContract()","00dba864":"TOKENOPSPLATFORM_JOINTTOKENS()","00dbeb31":"getPromoCodeForEther(bytes16)","00de1eb4":"cofoundersSupplyRemaining()","00de8393":"SetLimit(uint256,uint256)","00dee43f":"initMinting()","00df415e":"preSaleZxcCap()","00dfafa4":"addMarket(address,uint256,uint256,uint256,uint256)","00dfd21a":"getUserDocId(address,uint32)","00dff399":"Fibonzi()","00dff60a":"partnerPreICOBonus(address)","00e063bc":"AddressQuery(address)","00e0c53f":"hold()","00e11919":"setClamTax(uint8)","00e1986d":"grantVestedTokens(address,uint256,uint64,uint64,uint64)","00e29488":"selfRegisterDINWithResolver(address)","00e31614":"modifyGuess(uint32,uint64,uint64)","00e37634":"batchRefundzFixed(address[],uint256)","00e38410":"getVotingMetadata(uint256)","00e43ee9":"setMigrationStatus(uint256,address)","00e46700":"setMinimumPassPercentage(uint8)","00e4768b":"setPrice(address,uint256)","00e4778a":"addAccessoryIdMapping(address,uint64)","00e4fc14":"withdrawNetfRevenue(uint256)","00e520d0":"_emitSkillEvaluated(address,address,uint8,uint256,uint256,uint256)","00e5fc5f":"rawVotes(address)","00e610fc":"passwordMint(address,uint256,bytes32)","00e62620":"zoDailyLimit()","00e64f6d":"regularDonations()","00e6abbe":"EggFactory(address)","00e6b9f8":"MetalToken()","00e756cc":"roleAddressAliaser()","00e7d289":"registerListening(address)","00e8516a":"buySamples(uint256,address)","00e85279":"ownerLock()","00e893ce":"crowdsaleTokenPriceDenominator()","00e97827":"percentRake()","00e9c006":"deleteTransaction(uint256)","00ea11ec":"calcCakAmount(uint256)","00ea3146":"postGood(bytes32,uint256)","00ea81c0":"mint(address,uint256,string,string,bytes32[],bytes32[])","00ea8737":"myTickets()","00ead724":"Ticket(uint256,address,bytes3)","00eaedc8":"retrieveVanityForWallet(address)","00eb52f2":"setIsActivated(bool)","00ebc96e":"setCrowdsaleEndTime(uint256)","00ed015b":"setETH(address,uint256)","00ed2592":"sendEvents(address,uint256,uint256)","00f052f6":"getBidByBidder(address,uint256,address)","00f12159":"SpectrumNetworkNetwork()","00f17754":"accountAt(int256)","00f1c7ec":"setAllocationFee(bytes32,uint256)","00f29d55":"isOrdered(address,bytes32)","00f2c41b":"calculateTotalPayoutAmountAndCommission()","00f31e76":"isPresent(bytes32)","00f380f4":"communityFund()","00f3e717":"mrate()","00f40839":"LogTowncrierCallback(uint64,uint64,bytes32)","00f43f6d":"Simple_Claimable_Temporized_Stake()","00f45438":"createTokenToMarket2019()","00f49203":"Hard_Cap()","00f545c6":"addressBelongsToAccount(address,address)","00f54f0a":"Wallet2()","00f5544f":"openGame(uint256)","00f55d9d":"destroy(address)","00f62717":"setMockedBlockTime(uint32)","00f64e66":"StakePoolICO()","00f666d4":"QueueManager()","00f6ca59":"runCredits()","00f714ce":"withdraw(uint256,address)","00f733e9":"pieceForSale()","00f784a4":"OrderAdded(address,address,uint256,uint256,uint256)","00f7c5be":"unregisterAddress(address)","00f821a7":"addMintContract(address)","00f9ac78":"setVoteFactory(address)","00fa081a":"multiplicator()","00fa7be5":"EnterToken()","00fac74a":"salesdeadline()","00faf4dd":"getTokenDivisor()","00fca46f":"initialAuctionEndTime()","00fdc73f":"currentMinPurchase()","00fdd58e":"balanceOf(address,uint256)","00fe03e3":"icoSoftCapInWei()","00fe4789":"batchFillOrKillOrders(uint256[],bytes[])","00fe9590":"getMaxInt64()","00fec4ba":"afterForkBlockNumber()","00fece08":"giveDown(address,address)","00ff2fb1":"log_2(uint256)","00ff6262":"DefensorWallet(uint256,string,string,uint8)","010066ad":"joinWhiteList(address)","01008275":"addPersonalCap(address,uint256)","0102305b":"logGameData(bytes32[],bytes32[],int256[],uint8,bytes32,bytes32)","01024700":"OnePhaseAuction()","0102fcfc":"distributeOwnership()","010342f4":"averageSalePrice()","0103c92b":"userBalance(address)","01044632":"setDevelopersTokens(uint256)","0104855f":"mctTotalSupply()","01056361":"setupFunding(uint256,uint256,address)","0106172a":"invalidEarlyPurchaseIndexes()","01061ae1":"removeArtworksByString(string,uint32)","010648ca":"setDocument(bytes32,string,bytes32)","01067543":"getParentCount(address)","01068767":"ABL(address,address)","0106bc8f":"PVE()","010731c0":"sendCryptedHand(bytes32)","0107a4eb":"XRRfrozen()","0107a8df":"withdraw_bonus()","01080c6f":"activateTokensForArbitration(uint256)","0109057e":"WIZISHOPPINGCOIN()","01090c4e":"_removeProxyManager(address)","01090c9e":"PowerOfPutin()","01095962":"oraclize_setCustomGasPrice(uint256)","0109f22e":"CrowdSale()","010a38f5":"getTokenId()","010a7d65":"tryTransfer(address,uint256)","010abbd0":"getCardOwner(uint256)","010ae545":"creditTokens()","010afc20":"claimWrappedContractAdmin()","010b66de":"mainSale_Cap()","010b8701":"hasSubstring(string,string)","010ba4e2":"balanc()","010bd255":"DPNToken(address,address)","010cc97c":"transferMarketIncentivesFund(address,uint256)","010d214e":"WithdrawProfit(address,uint256)","010d2446":"getProblem(uint256)","010d3bf6":"buyUsingRefBonus(address,address)","010dbfec":"sell(uint256,bool)","010e3964":"mintTokenForPreCrowdsale(address,uint256)","010e3c1c":"setInflationChange(uint256)","010e8209":"admin(address,uint8)","010f7735":"burnToken(uint256,string)","0110ea76":"TanterX(uint256,string,uint8,string)","01114d74":"getCCH_edit_33()","0111ae8a":"maximumValueAfterGuaranteedPeriod()","01122ddb":"BonusEnrolled(address,uint256,uint256)","011285da":"multiplication()","0112e2c4":"CotteToken()","01132b70":"setXTVNetworkEndorser(address,bool)","0113b261":"getNumberOfShareHolders(uint256)","01146844":"loadFund()","0114af17":"investment_address()","01169399":"createEthTknDelegation(address,address,address)","0116bc53":"CostChip(uint32)","0116bfc0":"BuyUpgrade(uint256)","01172005":"affiliateContract()","011721ad":"getValidation(address,uint256)","01173a74":"mintToken(address)","0117b324":"addTestimonial()","0118251c":"getHighWinPercent(uint256)","011847a2":"inviteReward()","011857d0":"bntConverter()","011879db":"createAuction(uint256,uint128,uint128,uint128)","0118895c":"reservations(address,uint256)","0118e662":"SiekechuCoin()","0118e686":"isCrowdsaleActive()","0118fa49":"create(uint256,string)","0119ada7":"eliminate(address)","011a44bf":"isAllFrozen()","011a8eb7":"DrawPrepareEvent(uint256)","011aab02":"Oculta(uint256,string,string)","011afdd7":"hello2()","011b1a7b":"setCrowdsalePrice(uint256,string)","011b29e3":"changeCourse(uint256)","011bc2e1":"calculateWinners()","011c3d06":"getCurrentStats(uint256)","011ce353":"OwnerRecall(address,uint256)","011d07c0":"getMyIdeas()","011d0b58":"buyListing(bytes5)","011d79ca":"CrowdsaleEnabled()","011db570":"calculateObtained(uint256)","011de7aa":"intervalAtTime(uint256)","011e0162":"Flercoin()","011e6492":"checkSuccess()","011eb18c":"removeAddressFromOperators(address)","01201c0b":"getTheTokens()","01209d09":"updateVaults(address,address)","0121683f":"createAuction(uint256,uint256)","01216f05":"calcEthReceived(uint256)","0121b93f":"vote(uint256)","0121be14":"_createCard(address,uint16)","01233474":"saleInProgressB()","012397ff":"firstroundprice()","01239adf":"maxPos()","0123aff4":"BurnCoinToken()","0124188d":"CAIRToken()","01250e4d":"CraigGrantEatDick()","01253fbf":"threshold1()","0125ae62":"setMeterPoint(int256,address,int256)","0125d7c8":"IPAYTOKEN()","0126b8b6":"batchAllocateTokensBeforeOffering(address[],uint256[])","01272c2c":"canExecute(uint32)","0127eb0d":"angelAdminAddress()","01281641":"OfferCanceled(uint256,bytes,address)","01281867":"keccak256calc(address)","01284ad4":"removeAddressFromPrivateWhiteList(address)","012874a3":"EthsMePresale(address,address)","01289e3a":"AvenceToken()","01293b5c":"defaultURIEnd()","012a08f8":"_vote(uint256,bool,address)","012aa25e":"releaseTokens(string,address,uint256)","012aa809":"InvalidCoinUsage(string)","012b1f73":"announceEndOfGame()","012bac23":"addCoinAllowance(address,address,uint256)","012beac9":"vendorRegistry()","012cd104":"LoveCrowdsale()","012d61e1":"buyRedirect()","012defec":"harvests(bytes32)","012ea37c":"arrangeFreePoints(uint256,uint256,uint256,uint256)","012f52ee":"escrows(uint256)","012fd089":"EscrowAccountCrowdsale()","012fec73":"KakushinToken()","0130371a":"MAX_SUPPLY_NBTOKEN()","01303778":"refreshMonarchyGamesReward()","013054c2":"redeemToken(uint256)","01307338":"dispatchRewardToken()","013130c0":"maximalInvestmentTimeTreshold()","01326c34":"clearAddresses()","0132cc82":"tokenFounderLockTime()","0133311b":"deleteLockTime(address)","01339c21":"launch()","0133db3a":"nameOf(uint256,address)","0133e1fa":"RunchuToken(uint256,string,uint8,string)","01340592":"MAX_CONTRIBUTION_USD()","01345514":"BJLToken()","013459ca":"getTokensForGraphenePower()","013512e3":"CABtoken()","0136356d":"unregisterAddresses(address[])","01365406":"deathData_f19()","01367751":"PryzeSale(address)","01372911":"throwsWhenActivatingBeforeDeployingANT()","0138aac1":"getUserBalanceOnToken(address,address)","0138e31b":"_jAdd(uint256,uint256,uint256,uint256)","013953a6":"amountForRefundIfSoftCapNotReached()","01395d33":"tokenPriceInWeiForDay(uint256)","0139caad":"payout(address,uint256,uint256,bool,uint256)","013a0e9b":"pairwiseOr(uint64)","013a83f1":"beat(uint256,bool,uint8)","013a9c50":"updateWallet(uint256,uint256)","013b490c":"updateDaoAddress(address)","013cf08b":"proposals(uint256)","013d48bd":"getGuessStatus(uint256)","013d64bd":"setCanCall(address,address,string,bool)","013dbf17":"crowdsaleProgress()","013e5415":"getGoldDataInitialized()","013e7c35":"getUrlCountOf(address,address)","013ed428":"author1()","013eebd7":"getmaxcardcount()","013efd8b":"tokenToEthSwapOutput(uint256,uint256,uint256)","013f83c9":"createTeam(address,uint32[])","013f84fa":"getAllNumberOfBets()","013fc2a3":"SmillesCoin()","0140e359":"stand(uint256,uint8[],bytes32,uint8,uint8,bytes32,bytes32)","0140ea82":"setNormalRoomMin(uint256)","0141e90a":"ICOaddress(address)","01429244":"getVendorApplicationsCount(string)","0142b8d1":"makeMerkle(bytes,uint256,uint256)","0142c8de":"currentPeriodRate()","0142c9ae":"isSoleout()","0142d43e":"notHungry(uint256)","0142d7b4":"authorizedBurnTokens(address,uint256)","0142f904":"CalculatePriceofRigs(uint256,uint256,uint256)","0143279c":"whitelistTicket(address)","014345c8":"SENDER_BALANCE()","01447eba":"disableCrowdsale()","0145e333":"init(address,address,address,uint256,uint256)","014647f4":"approve(address,bytes)","0146705b":"approvedRatio(string)","0146d0ca":"sendVote(string)","01491f09":"baseRateInCents()","01492a0b":"matchingEnabled()","0149eea0":"view_get_Treasure()","014a7453":"getPI_edit_22()","014a897d":"Token_2()","014b0732":"validateTrade(address,address,address)","014bed81":"setAmountToKoikeToken(uint256)","014c3dbc":"current_external_block()","014c8ac0":"CBToken()","014d0f68":"hardCapHighUsd()","014d36f4":"Afroin()","014e5fde":"ARKController_1_00()","014e6996":"ZTF()","014e95ba":"rateBase()","014f7f22":"joinCount()","014fc169":"setLockToAccount(address,address)","015008b1":"reLoadXaddr(address,uint256)","01500a97":"getTokenForCommunity(address,uint256)","01501347":"disableRefund()","01502460":"freezeTransfers()","0150b530":"addressesLength()","015129a1":"sellPriceEth()","01512db1":"removeIntervalCoefficient(bytes2,uint256)","01515a7b":"weiToReceive()","01518d76":"sendQuery(uint256)","0151cf1d":"setVotingWinner(address)","01538868":"_setTokenURI(uint256,string)","015493b4":"setFoundationWallet(address)","0154d3ea":"notexistdept(string)","01567739":"beneficiaries(address)","015689c6":"testControlCreateWithParentsParentSameItemId()","0156b323":"destroyTokensFrom(uint256,address)","015773b6":"set_private_sale_total(uint256)","015854f8":"quoteBid()","0159a91d":"concatenate(string,string,string,string)","015a18ed":"start(bytes32)","015a4ead":"unfollow(address)","015aeda7":"setAttribute(address,bytes32,uint256,bytes32)","015afa55":"winnerIsB()","015bf264":"depositTokens(uint256,address,uint256)","015c1c7a":"toTokenAmount(address,uint256)","015cb3ff":"pauseTime()","015cb8cf":"baxianchain()","015ccd07":"DockToken(address)","015d200f":"lockBalanceAll(address)","015def53":"priceFactorC()","015e4f3a":"getConfigUint(int256,bytes)","015e52c6":"getPool(uint32,int256)","015f32f9":"cappedSaleStartTime()","015fa6c1":"setWeiCap(uint256)","015ff39f":"GNOSIS()","0160751c":"setDepositary_function(uint256)","01608f5f":"amountOf(address)","0160e2f6":"cancelOptionOrder(address[3],uint256[3],bool)","01612def":"additionalInternal(bytes32,uint256[])","0161d5f0":"createCampaign(address,uint256,bytes32,bytes32,bytes32,bytes32)","016211b5":"bonusAllocation()","01621527":"destEthDevs()","01623ee4":"basicRate()","0162827c":"bonus02End()","0162f799":"getPrivatePresaleFundersCount()","01637ff4":"getAccessory(uint256)","0163d8ff":"MostValuableCoin()","01644ea7":"getSimple()","016474ce":"withdrawalRound(address,uint256)","01655e31":"CollectibleBidEntered(uint256,uint256,uint256,address)","01659863":"_0xBitcoincashToken()","01665393":"BLOCKRADIO()","016774e9":"donatetokens(uint256)","0167eb85":"stone()","01681a62":"sweep(address)","016899de":"depot()","0168e2e3":"JonsCoin()","0168f063":"tokenAmountOf()","016a8cf6":"topUp(address,uint32,uint192)","016aba15":"setDividendTransactionNumber(uint256)","016b0882":"Cst()","016c6601":"_receiveDeposit()","016d60b3":"buyStoreCore(uint256,uint256,uint256)","016d7c83":"pauseLottery(uint8)","016deccc":"createContractSpecial(string)","016e03b1":"getItemIdToTokenId(uint256)","016e128b":"ProfitWithdrawn(address,uint256)","016ea771":"isNotCommittee(address)","016eb8a8":"percentage(uint256,uint256)","016f34ad":"callgSoftCap()","016fa018":"getPartnerBalance(address)","01725a0b":"demo()","01738ecd":"setCurrent(uint256)","0173e3f4":"addCoins(uint256)","0174e12b":"myx()","01750152":"isNode(address)","01769b37":"sendTokensToSeven(address,address,address,address,address,address,address,uint256)","0176b596":"DreamBit()","01770e0c":"NKTToken()","01775f23":"_closeBooks()","01778b6d":"Ynfiniti()","0178090c":"toSHA256(string)","01788d1d":"Decabes()","01788d56":"balanceOfTranche(bytes32,address)","0178b8bf":"resolver(bytes32)","0178fe3f":"getData(uint256)","017945ba":"changeDollarPrice(uint256)","017972af":"getNumbersFromHash(bytes32)","017b0d00":"highestBidForEdition(uint256)","017b39a7":"getMiniPoolEdit_1()","017bef67":"addExplorationByShip(uint256,uint256,uint256)","017e322c":"getCurrentGameSteps()","017e6f5f":"reOrganizeAuthorities()","017f27fc":"saleIsClosed()","017fa10b":"returnUint128(uint128)","017fa51d":"shouldRevertPure(bool)","017fe809":"getPower(uint256)","01828e61":"Quecoin()","01836037":"foundationBoard()","01838f01":"addAnimal(uint8,address)","0183f310":"potMembers(uint256)","0184e952":"award(uint256)","0184fc35":"crowdSaleAddress()","0185f409":"getInvestorAddress(uint256)","01863f79":"thisContactsTokens()","0186aa16":"OxBioToken()","0186c36e":"getCurrentExchageETH()","0187699c":"VerixChain()","0187a677":"bbodServiceRegistry()","0187e973":"PricingStrategy(uint256,uint256,uint256,uint256)","0188c09f":"altList(uint256)","0188fdef":"setMaximumBuy(uint256)","01890840":"MilestonePricing(uint256[])","0189bd41":"getProofOfPerfBlockStateState(bytes32)","018a25e8":"getBuyPrice()","018aba3f":"createPledge(address,uint256,uint256)","018b06ff":"isWinner(address,bool)","018b64b6":"AuctionCancelled(address,uint256)","018d3490":"assignOracles(uint256,address[])","018d6f7a":"showethconf(address)","018de5c5":"distributeCBC(address[],uint256,uint256)","018dfaa0":"calcCount(uint256)","018e13d0":"numOfCurrentEpoch()","018f5472":"isAUser(address)","018fa360":"getDeposits(address,address)","018fbf9f":"hashAt(uint16)","01909317":"_storeSettingDataState(uint256,address,uint8,string,address,address,string)","0190b805":"editEarlyParicipantWhitelist(address,bool)","0190e84f":"Bitscorone()","0191903e":"setBlogregistry(address)","0191d35c":"summFounders2()","0191dc92":"numOfAdmins()","01930b6e":"darknodeDeregisteredAt(address)","01933c43":"TOWN_START_PRICE()","0194abaf":"prolong()","0194ac16":"BlockchainFUN(uint256,string,string)","0194db8e":"sum(uint256[])","01968a56":"mintAllocation(address,uint256)","01970353":"setStepOneTime(uint256,uint256)","01970c6b":"team_funds()","0197d972":"VESTING_PERIOD()","01984892":"name(address)","0198632a":"getPurchasedProducts()","0198aa74":"firstsaleOpen()","01991313":"scheduleCall(address,bytes4,uint256)","01996951":"ethPerTransactionLimit()","01998ad4":"GlobalAdminChanged(address)","0199c7b2":"numberOfHolders()","019b1576":"backupAddress()","019b32ad":"transferToSalesPartner(address)","019c3f52":"newCollectible(uint256,string,uint256,uint256,uint256,int256,string,uint256,string)","019c5675":"BatchComplete(uint256)","019d2729":"approve(bytes)","019e56fd":"findCurrentFor(address)","019f5c5b":"narcoCore()","019f64cc":"payBack()","019f80b6":"toSecond(uint256,uint256)","019f8e26":"AddedManager(address)","019fef03":"resetFine(uint16)","01a00216":"addMod(address)","01a01551":"getApprovers(string,string)","01a048c3":"mintLockTeamTokens(address)","01a08a8b":"getWorkerPool(address,uint256)","01a0dee1":"investorsSupply()","01a12fd3":"removeAlerter(address)","01a15ee9":"mintTokensLocked(uint256,int256,address,uint256,uint256)","01a1b778":"battleId()","01a2789e":"transferPreSignedBulk(address[],address[],uint256[],uint256[],uint256[],uint8[],bytes32[],bytes32[])","01a2f48a":"changeAssetPackPrice(uint256,uint256)","01a2f75c":"createContract(address,uint256,uint256,uint256)","01a340a5":"totalBoughtColor()","01a413b9":"bankrollAvailable()","01a50001":"rewardEvery100000Draw7(uint256)","01a521d6":"getSellerBalancesOfCurrentAuctions(address[],address[],address)","01a53d3b":"maximumBuyBackPriceInCents()","01a5e3fe":"isWhitelisted(bytes32)","01a682c1":"createTeam(string,string)","01a68a94":"donkeyCoin()","01a6ab93":"PassedGateway(address,uint256)","01a77625":"_subEth(uint256,address)","01a7a8c0":"batFundDeposit()","01a80669":"createInvestorWallet(uint256,address,uint256)","01a88f7d":"buySeeds()","01a8d07f":"addBidder(uint256,address,uint256,uint256)","01a93f1c":"giveAwayOwnership(address)","01a96b94":"set_stage_Discount(uint256)","01ab2a66":"getPlayer1()","01ab2f14":"Manus()","01ab9806":"BUY()","01ab9f19":"_safeCall(address,bytes)","01ad35e3":"mintTokensForCommand(address,uint256)","01ad3936":"assignedAmountToDevelopmentTeam()","01ad62a3":"getBackendWallet()","01ae19d6":"LogLOTTransfer(address,uint256,uint256,uint256,uint256)","01aef755":"setBestProbability(uint8)","01afd5f3":"allBalancesForManyAccounts(address[],address[])","01afebac":"ICOopen()","01b057b1":"isAdminSet()","01b07f75":"adjustValue()","01b0c649":"collect(address,address,uint256,uint256)","01b11792":"toggleLocked()","01b125e6":"resetTimer(string)","01b14149":"getFcontracts(address)","01b2320e":"getStartBlock(uint256)","01b2a413":"baseVerifierFee()","01b490ed":"CAIDToken()","01b54744":"setLLV_edit_24(string)","01b5990c":"getCreatedOn(address,uint256)","01b5ffcf":"addVesting(address,address,uint256,uint256,uint256,uint256,bool)","01b6b523":"viewMyContribution(bool)","01b74d73":"TEAM_SHARE_PERCENTAGE()","01b78b12":"BitcoinMoon()","01b852c9":"MetadollarCrw()","01b869f1":"release(uint32,uint32,uint32,bytes)","01b8a0b9":"createTestingEnvironment()","01b96aaf":"waveCap2()","01b98853":"assetFreeze()","01b9a397":"setDescriptor(address)","01b9fe59":"testMint(int256)","01ba2bd5":"Request_Airdrop()","01ba6805":"loseEth(address,uint256)","01baa2e7":"validateCap()","01bb4edf":"RAIOCO(uint256,string,string)","01bb67a8":"InvestCancelEvent(address,uint256)","01bb7e5a":"getLockerDetails(address,uint256)","01bb85a4":"__startBlock(string)","01bbb8fa":"verifyTimelock(bytes32,uint256,address,address,uint256,uint256,bytes32,bytes,bytes)","01bbc3f5":"stopWhitelistReservetion()","01bc237d":"researchers(address)","01bc43a0":"sha(uint128,bytes32)","01bc45c9":"_admin()","01bc757a":"getstudentInfo(uint256)","01bc9533":"totalTokensGenerated()","01bd4051":"disown(string)","01bea2bd":"Mountain()","01beb7cf":"setBadgeLevel(bytes32,uint256,string,string,bytes)","01bebf36":"updateAirdropStageState(string,bool)","01bf6648":"removeFromWhiteList(address)","01c0c6bc":"_processRefund(bytes32)","01c11d96":"MAX_PRICE()","01c1c877":"setChampion(uint256)","01c1de96":"fechVoteInfoForVoterByStage(address,uint256)","01c24a90":"minimum_balance()","01c28786":"date_end()","01c2b6f5":"commitDeadline(bytes32)","01c355df":"appSelectors(bytes4)","01c432ce":"wrongClaimerOrUnsetInManager()","01c4a07e":"convertDeposit100to70(address)","01c516b1":"crowdsale_end()","01c543c2":"claimOreOnlyFromAssetId(uint256)","01c5b2f0":"compressBoard(uint256[81])","01c64ce8":"maxTxGas()","01c69452":"brandAccounts(uint256)","01c6adc3":"transferFrom(address,uint256)","01c6f167":"auctionsRunByUser(address,address)","01c7cb58":"migrateMileageLeader(uint8,address,uint256)","01c835e5":"returnRemainRewardToken()","01c8c9d4":"getCurrentBonus(bool)","01c96df6":"ZeusShieldCoin()","01ca1d72":"getTransformRate()","01cb0261":"getWeightedVote(bytes20,uint256)","01cb3b20":"checkGoalReached()","01cb63e8":"arrayIndexOutOfBoundsDynamic(uint256)","01cceb38":"setExpiry(uint256)","01cdc371":"getCBATransactionMessageLength(address)","01ce5e75":"fundsCombinedValue()","01ce616f":"setMaxweiAmount(uint256)","01cff174":"getNumberOfAvailableStartTickets()","01cffa17":"getTokenWithBonus(uint256)","01d09a3c":"setCallbackGas(uint256)","01d0ac0b":"requestAccess(address,address)","01d1c7fd":"BTCS_ETHER_CAP()","01d223c1":"set_modified_weth_address(address)","01d2db89":"isValidKyc(address)","01d4277c":"thisisalsofind(uint256)","01d42a9c":"closeChannel(address,uint256)","01d490fd":"registerVestingSchedule(address,address,uint256,uint256,uint256,uint256)","01d4fb7c":"fundsKeeper()","01d511f1":"request(string,string)","01d5c488":"gemCriticalRateConversion()","01d6e35b":"unfreezeTeamTokens(address)","01d78a8b":"alterTotalSupply(uint256)","01d81121":"allocateCreationInvestmentingToken(address[],uint256[])","01d81a50":"slice(bytes,uint8,uint8)","01d8715f":"replaceManager(address,address)","01d8ce92":"KpopArena()","01d90bbc":"getCurrentUserMaxPurchase()","01d92dc8":"unsoldAllocatonScheduled()","01d97f08":"setMapping(bytes32,bytes32)","01d98d44":"changesDenied()","01da31ad":"_setPermission(address,address,bytes4,address,bool)","01da73ff":"isValidChannel(bytes)","01da7b31":"getBankName(address)","01db61e0":"HARD_CAP_EUR()","01dbdf44":"priceAt(uint256,uint256)","01dd91c0":"force_received()","01dda205":"updateSoftCap(uint256)","01ddc95e":"getTargetBlockLength()","01ddfa9d":"referalFundBalance()","01de7a1c":"updateVendorName(uint256,string)","01dee025":"getTombDetail(uint256)","01df6885":"getTokenDetails(uint64)","01df7f30":"validateProposedThroneConfig(uint256,uint256,uint256,uint256)","01e0ba3a":"bonusAccountIndex(uint256)","01e11c29":"SellToken()","01e1bcf7":"rateIcoPreICO()","01e1c861":"minWeiValue()","01e1d114":"totalAssets()","01e1ecb4":"releaseTokensAndEtherForEmergencyFund()","01e30a7f":"bigContributionBound()","01e33667":"withdrawToken(address,address,uint256)","01e343db":"setOffset(uint256)","01e3d346":"create(bytes1,bytes32,uint256)","01e3d718":"transto(address,uint256)","01e40f5b":"getFeeWindowBurnTargetValue()","01e4741c":"Ebets()","01e4abc1":"setWhiteList(address,address,uint32)","01e5691c":"createTransaction(uint256,address,uint256,uint256,address)","01e56c77":"stopPayouts()","01e57a37":"dth()","01e5aa3e":"getIssuerArray(bytes32)","01e68cbb":"timestamp_msg()","01e6a70e":"EthlanceInvoice(address)","01e73b73":"bulkVote(uint256[])","01e7fefe":"addParticipant(address,uint256)","01e88208":"permissions(address)","01e8b608":"TOKEN_SECOND_EXCHANGE_RATE()","01e91872":"DECToken(uint256,string,string)","01ea6270":"setTeamTokenAddress(address,address)","01eb6fdd":"max(uint32,uint32)","01ebc88e":"pingReading(uint256)","01ebccb9":"activeNameOf(address)","01ebd36b":"enable_sale()","01ebebf2":"myTulips()","01ec0793":"profitsOf(address)","01ec16ef":"RulesChangedEvent(uint256,uint256,uint256,uint256)","01eca37c":"medalDataContract()","01ecaca5":"changeOVCPerEther(uint256)","01ed7f8b":"distribute(address,address,address)","01edb1ea":"dayIdx()","01ef6cad":"addJobContractFeedback(uint256,string,uint8)","01ef74f1":"tokens_rewards_available()","01efb6c8":"getOrderInfo()","01f2a2c5":"buyForBtc(address,uint256,uint256,uint256,uint256)","01f40a85":"issuePurchase(address,uint256)","01f59d16":"maxFee()","01f5af30":"addJobSponsorship(uint256,string,string)","01f6dad0":"remaining_for_sale()","01f6e6d5":"asignarDni(uint256)","01f78f43":"getFreeCHICKEN()","01f7e49a":"removeFromPresaleWhitelist(address)","01f81649":"claimBrokerFee()","01f865c3":"setWinPercent(uint256)","01f89de0":"purchaseSharesOfArtwork(uint256)","01f99ad7":"left9(uint256)","01f9a0aa":"setOraclizeQueryMaxTime(uint256)","01fa3e53":"addSocial(address[],uint256[])","01fabd75":"addArbitrator(address)","01fae3b6":"setTokenState(uint8)","01fbaf99":"totalLareSold()","01fc59e1":"checkId(bytes32)","01fce27e":"getQueue()","01fd1b1d":"finalizationFailHook()","01fd89a4":"getFlags(bytes20)","01fe34e3":"EWCertificationCenter(string,string,string)","01feeef4":"getTitleDeeds(bytes32)","01ff62ab":"isConcerned(uint256,address)","01ff8961":"getPortfolio(uint256,address)","01ffc9a7":"supportsInterface(bytes4)","0200b10d":"collectedEthers()","0201b5d5":"transferOverBalanceFunds(address,address,uint256)","0201e253":"WhoHoldsPatentFor(bytes32)","0202f3ea":"allowTransfersTo(address)","020331dd":"getFact(bytes16)","0203596d":"purchaseKingdom(string,string,bool)","0204c163":"maxFadeoutPromille()","0204d0f8":"unlockOwnerDate()","02055186":"Alexa()","02063d93":"calcMaxDeposit()","0206432d":"FlexionCoin()","02064b42":"consul_price()","02065fb8":"isLoanFunded()","02067e6a":"add(uint8)","0206deb5":"unitsLimitForCurrentSaleStage()","0206e79d":"decodeParamId(uint256)","02072579":"controllerSet()","02078166":"unburnedTypeTokens()","0207eda6":"NOVA(uint256,string,uint8,string)","02083e27":"REET()","02093ee2":"finalize2()","02096a8e":"amountsByCurrency(uint256)","02099186":"totalRise()","0209f982":"reminder()","020a0ff5":"setClaimLimit(uint256)","020acb6a":"round1Bonus()","020bdf54":"getFreeStrippers()","020d308d":"removeDelegate(address,address)","020d4786":"OmmerToken()","020de876":"setTakerFeeRate(uint256)","020df04b":"createBarCode(bytes32)","020df957":"setAirdropReceiver(address)","020e2d48":"getArrayHashLibry(bytes32)","020eb6e1":"createWorkOrder(address,uint128)","020f899a":"hybridizationPrice(uint256)","0210d751":"getMyGames()","02114111":"allowTimelock()","0211c4bb":"MessageToken()","0212d0b9":"payByTokens(uint256)","0212fd1f":"InternationalRapidAsset()","0213443c":"changeZombieCreator(address)","02135534":"getNinja(uint256)","02138563":"buyOre()","02140adf":"CryptoHuntersToken()","0214e9cf":"preIcoFinishTimestamp()","0216f544":"transferExecutor(address)","02171e7c":"largeConstant()","02172276":"triggerEvent(string,string)","02175beb":"setOzr(address)","0218a1c3":"setString(bytes32,bytes32,string,bool)","02190a52":"allowRecurringBillingInternal(address,uint256,uint256,uint256,uint256)","021979c3":"wlcontract()","021991e7":"getBetsLocked()","021a11d0":"setContractICO(address,address)","021ba8f8":"CLAWBACK_PERIOD()","021bb947":"burnAfterIco()","021bc974":"checkPoolBalance()","021c309a":"solveBet(address,uint8,bool,uint8)","021c43b4":"NBY()","021c7bd7":"setInspectorId(address)","021da58e":"initCrowdsale(uint256,uint256,uint256,address,address)","021dc2fc":"tokenExchangeRateInWei()","021dd82c":"checkNotLocked(address,uint256)","021e7f85":"CONTRACT_ALLOWANCE()","021ea45e":"claimTilesForExistingUser(uint16[],uint256,bool)","021efe49":"getPawnOwner(uint256)","021f0376":"_addAssetTo(address,uint256)","021f36a4":"changeResource(bytes32)","021fe51f":"VUPRefundedForWei(address,uint256)","0220611a":"timeOfLastPublish()","022079d9":"ecmulVerify(uint256,uint256,uint256,uint256,uint256)","0220a5b4":"terminate(string)","0220f662":"addPolicyAttribute(uint8,uint256,uint8)","0221038a":"payOut(address,uint256)","02218ad6":"desBan(address)","0221f2fb":"Beneficial()","0222f96e":"Poppy()","02238cbd":"_activateDevice(bytes32)","02238e43":"launchnewround()","0224dc18":"TOKEN_SALE1_PRE()","0224e9a7":"devFees()","02258730":"nodeRegistration()","02259b07":"setPBTTForGas(uint256)","02262ced":"setBackendOperator(address)","0226401d":"ownerTestValue()","02264b63":"private_withdraw(uint256,address)","0226a5c9":"petOnLeaderboard(uint64)","0226ed48":"changeGlobalAdmin(address)","02285548":"FarmHopeProjectToken()","0228e05a":"walletFromData(bytes)","022914a7":"owners(address)","02299496":"updateICOStatus()","0229ae31":"CosmoCoin()","0229b23e":"pauseSALE()","0229c4eb":"TransferMinimumFeeProposalAdded(uint256,address,uint8)","0229e448":"founderMulSigAddress()","022b7433":"add(bytes32,uint8,uint8)","022b8a7f":"getIdProject()","022b9735":"GetMyBalance()","022bc71f":"getNextCallSibling(bytes32)","022bd24c":"hypes(uint256)","022c254a":"pendingChanges(address)","022cabac":"CoinViewToken()","022e1e59":"USBEEF()","022ec936":"updatePeriod(uint256,uint256)","022edd35":"getActiveContracts()","022fc88b":"approveToken(address,uint256)","02300cbb":"DepositReleased()","0230a07c":"releaseDeed(bytes32)","0230d870":"tierThreeRate()","02329a29":"pause(bool)","02337657":"documentIPFSHash()","0233d94d":"getEscrowsByTaker(address)","02340ad6":"deleteVisaOffering(uint256,uint256)","023569aa":"MoniCoin()","02356ec0":"returnCoupon(address,bytes32)","02358773":"XFL(uint256,string,string)","02359fdd":"OfferingCloses(uint256,uint256)","02361dbc":"totalAllStage()","0236bb5a":"isAdminAddress(address)","0237ef12":"contributionInWei()","0238777f":"preCrowdsaleContractAddress()","0238b5aa":"testToAddress()","0238b770":"endDateICO()","02394872":"getLastBlockHeight()","02395e9b":"lpc()","023a624a":"right11(uint256)","023bb74d":"DATE_PRESALE_START()","023c19ce":"MyWishChain()","023c23db":"getSize(uint256)","023c6042":"tokencap()","023c61ca":"price_agent()","023c8be2":"setWithdrawalAddress(address,address)","023d6c03":"REPO_APP_NAME()","023e1c34":"communityContributionPercentage()","023e36d8":"nVotesCast()","023eff9f":"airdrop(uint8,bytes32,bytes32)","023f4147":"totalContributed()","023f4a66":"issueToReserve(uint256)","023fadda":"getRedeemedList()","02400845":"publish(bytes12)","02404bee":"crowdsaleCount()","02404fcb":"buyBanana()","0240ab3f":"finishRetrieving()","0240db33":"summFounders4()","02410cf6":"isFundReleased()","0241747f":"ReceivedBTC(address,uint256)","024187a5":"window0TotalSupply()","0241fb82":"returnChildForParentNew(address)","02421ca7":"SaddleFS(uint256)","0242622b":"changeMultisigAddress(address)","0242a5fc":"testRecovery(bytes32,uint8,bytes32,bytes32)","0242ba2a":"FOToken()","0242c430":"CreateTokenToTeam(address,uint256)","0242deb8":"registerIntermediary(address)","0242f1ef":"TonCoin()","0242f351":"getVote()","0242fc62":"voteNo(string)","02431422":"addSuperPlayer(address,bytes32)","02433d0f":"num_holders()","02437982":"adjustRate(uint256,uint256,uint256)","0243aa1b":"getCurrentNbVote()","02443111":"oneTrancheAmount()","0244ba4a":"Hubble()","0244eb3f":"testFundsAreLockedDuringSale()","0245c5c8":"importSequence()","02460d1e":"_emitHolderRegistered(bytes32,uint256,uint256)","02474718":"paydayFrequencyInDays()","02474c59":"myPledgeTo(address)","0247e02a":"subFromAddressBalancesInfo(address,uint256)","024800ff":"presaleWeiSold()","024858b1":"createTrade(bytes32,uint256,uint256,address,address)","02491bd5":"CryptoLottoCoin()","0249e64a":"CodeMailStamp()","024a56a4":"testIsData(bytes)","024adb25":"LogStateSwitch(uint8)","024c4199":"addListener(address,address)","024c6def":"BONUS_ICO_WEEK_TWO()","024c764f":"setChallengeCooldownTime(uint256)","024cc06d":"updateRecipientInfo(bytes32,string,string,address)","024ddebe":"Error(bool)","024edd75":"buyHero(uint256)","024fcc6c":"enableService()","024fd650":"tokenData()","024fd912":"GoToken()","02500824":"buyDentacoinsAgainstEther()","025026d5":"updateEmployee(uint256,uint256)","02502787":"FDT(uint256,string,uint8,string)","0250bd2d":"unregisterName(string)","02521b16":"saveTxt(string)","0252607e":"bitcoinPublicKey(uint256)","0252b995":"gameStartTime()","025313a2":"proxyOwner()","0253a95a":"getMaxMerge()","0253e935":"setOrderListLengthFactor(uint256)","0253fbd1":"momFab()","025404d4":"amountRaisedUSD()","02543238":"setDiscountValueOff()","02548866":"TOTAL_CAP()","0254aa41":"CommonEth()","0254e687":"GodlyCoin()","0254ef0f":"enterMedium()","02550e4d":"profit(address)","02556de3":"updateMajorTree(bytes32)","02565633":"buriedSupply()","0256c7f5":"Afin()","0256e827":"enablePurchasing(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","02571be3":"owner(bytes32)","0257210f":"ForgeCDN()","02573fc2":"resetStellarInvestor()","0257a0c0":"onLotteryCompleted(uint32)","0257c48c":"meta(bytes32,bytes32)","02581ab3":"offerIndexedPieceForSaleByAddress(address,uint256,uint256)","02581cde":"refundExpiredBet(bytes32)","025830ac":"changedBrokerDealer(uint256,address)","025845ae":"thinkTankFundAddress()","02587586":"companyAddr()","025932fd":"bitikzikToken()","0259371c":"TTTTokenSell()","02593c2b":"_Split()","025a6f02":"OsmiumCrowdsale()","025abd58":"getTokenBalance(string)","025b22bc":"updateImplementation(address)","025b97bd":"getProviderAdmin(uint256)","025bbbe5":"newSale(bytes16,uint256,uint256)","025cce45":"AMULETS()","025cf89f":"setMigrationManager(address)","025dd017":"OnReceive(uint64)","025e029b":"buyStar(uint256,uint8,uint256)","025e56d3":"NeuroDAO()","025e7c27":"owners(uint256)","025e8095":"transferCell(address,uint256)","025ec81a":"getBytes32Value(bytes32)","025f9bc1":"updateTokenInformation(string,string)","025ff12f":"airdrop(address,address[],uint256[])","026164ad":"sunset()","026189ec":"BitRecord()","02618eb2":"AltCurrency(uint256,string,string)","0261a403":"issueDID(address,uint256)","0261edec":"getContractByID(string)","0262dc13":"claimOne(address)","0263379b":"bringBackTokens()","026345b6":"ledgerContract()","0264ba24":"sendValueToJackpot()","0265190c":"b66ReserveTokens()","026654bf":"PoolManager(address)","02667e9b":"killPay()","0266ba02":"list(address[])","0266f044":"reservePool()","02682ab3":"setNewWallets(address,address,address)","026858ea":"getRateModifierInPermilles()","0268ec43":"MyEtherTeller()","02690ef0":"setICOElePrice(uint256)","026993e0":"Midas(address,address)","026a308a":"_checkWhitelistContract(address)","026a9cdd":"getPotato(uint256)","026b1d5f":"getPool()","026c0d8f":"RHP()","026d0e1c":"grantUserLicense(address,string)","026d19d5":"WeTestToken(address,string,string,uint256,uint256)","026d6a67":"setStartStopBlocks(uint256,uint256)","026e402b":"delegate(address,uint256)","026eca12":"createTapPoll(uint8)","026f9d56":"SOT()","026fcf83":"setSaleFinish()","026ff05e":"deleteUser()","02704a4d":"COIN_SUPPLY_ICO_PHASE_3()","027116f7":"approveNewOwnersCount()","027391bf":"sendMoneyBeforeEnd(uint256)","02742425":"preFundingtokens()","027471b0":"roundActive()","0274d5ff":"soulIsOwnedBy(address)","0274ea81":"jadd(uint256,uint256,uint256,uint256,uint256,uint256)","0276650b":"individualCap()","027681ab":"setJackPotInfo(uint256,uint256)","02780677":"LN2()","0278199e":"StandardToken(uint256)","0278bde1":"ask(address,uint256,uint256,uint256)","0278fa20":"TeambrellaWallet()","027903ef":"setReservedTokens(uint256)","02795b3a":"tokenMarket(address)","027a4425":"EthereumDiamond()","027a5e3f":"getLastVersion(bytes)","027a7ccc":"calculateFirstCut(uint256)","027aa9f5":"getUnits()","027b1fb3":"SimpleStorage()","027bb838":"FLTToken()","027bd9a8":"changeColorGreen()","027bfab4":"discountedIcoTokensSold()","027c3e08":"ControllerChanged(address)","027cb7c6":"clearing()","027e7a0f":"getTotalGamePot()","027ec848":"setDurationOfLock(uint256)","027efe2b":"makeOperation(uint32,string)","0280052d":"setKing()","028118a1":"PREBUY_PORTION_MAX()","02814b86":"maxETH()","0281b752":"admin_set_ExchangeRateInWei(uint256)","02825adc":"gvOptionToken30()","02836f24":"upgrading()","0283f4b4":"addPropertyForUser(bytes32,address)","02846858":"removeBurner(address)","0285d554":"transferWithEvent(address,address,uint256)","028780e4":"ownerWithdrawZth(address)","02879f9c":"addProduct(string,uint256,string,string,string)","02884909":"authorizedLogicContractAddress()","02889f26":"getCustodianChangeReq(bytes32)","0288a39c":"withdrawDelay()","0288ab5d":"TCC()","0288c0a0":"TransferDomain(string,address)","0289e966":"newVersionReleased()","028a582e":"findEndpointByAddress(address)","028a95a0":"lockRemainingTokens()","028ab3b1":"__get(address,uint256)","028ae3b7":"setAffiliateList(address)","028af743":"getServerCurrentMatch(uint256)","028b7854":"throwsSaleWalletIncorrectBlock()","028e10ac":"BidaCoin(uint256)","028e3731":"getUsersByDocHash(bytes)","028e6c67":"intOrRevert(uint256,uint256)","028ebc44":"setRegistryContract(address)","028fb6b8":"deleteRef(bytes32)","029043a4":"removeBlacklistSpender(address)","02911cfe":"distribute(address,uint256,uint8,uint256)","02917f4a":"issuePatrons(address,uint256)","0291b9b1":"judgeIsReachDailyLimit(uint256,int256,uint256)","02927d20":"setupEventsHistory(address)","0292f88a":"setBaseDenominationAddress(address)","02931e59":"getUserPower(address)","02932f56":"totalCampaigns()","0293a772":"get_sale_owner(address,address)","0293fafc":"ADBToken()","02940dbb":"Decenturuon()","02942724":"preservedTokens()","02949bff":"CampaignToken()","0295d71b":"currentDepositLimit()","02965297":"update_height(uint256)","0296b3a8":"STARLIGHT()","02978be8":"gameHostAddress()","0297abe5":"getLimitMaxGame()","02981cfe":"transferedToPool()","02987db8":"priceInWeiPerSatoshi()","02989d9f":"SellOrder(uint256,uint256,address)","0298d557":"isValidSignatureAndData(address,address,bytes)","029a258a":"claimDonations(address[2],uint256[8],uint8,bytes32[2])","029a8bf7":"multiAsset()","029ad03e":"get_nb(address)","029bca78":"isPremium(uint256)","029c19aa":"getCreditBondAddress()","029d1ecd":"ownerApprove(address,uint256)","029d4b2d":"isTimestampInsideRange(uint256,uint256,uint256)","029da1c4":"walletFounder2()","029dc6d2":"piggyToWallet()","029deeb0":"updateUportInfoFromOracle(string,address,address)","029eabcb":"contributions()","029f1d0e":"userName(uint256)","02a10d87":"getPreSaleEndDate()","02a182d1":"setInvestmentCapIcoPhaseTwoPounds(uint32)","02a1a7a8":"isReachCapped()","02a251a3":"votingPeriod()","02a2680c":"getUserWalletByID(uint256)","02a2c88f":"kycLevelOf(address)","02a2cf02":"NOK_Omnidollar()","02a2e105":"RYANTOKEN()","02a2f06e":"GetMyBet()","02a3036d":"init1_block_height()","02a4e488":"decreaseAllowanceProxy(address,address,uint256)","02a4e849":"getMiniPoolEdit_9()","02a566bd":"Woyager()","02a59ea3":"isEntitledForCluster(address)","02a5c0be":"CryptoSagaArenaRecord(address,address,uint8,uint8)","02a63c28":"consumeMarketOrderAsk(uint256,address,address)","02a6f266":"Presale(address,address,address,address)","02a72a4c":"tokenGrantsCount(address)","02a86781":"authorAddress()","02a8a406":"setBurnPolicy(bool,bool)","02aa26f6":"buySeatForEvent(uint256)","02aa274b":"setForward(bytes4,address)","02aa6318":"getDistributions()","02aa9be2":"unvote(address,uint256)","02ab4781":"reservedCoins(address)","02abb4c5":"Miner()","02ac8168":"Launch()","02acbaa3":"CrowdsaleMinter()","02acc6b6":"GNTTokenERC20(uint256,string,string)","02acdb44":"setAnyoneCanCall(address,bytes4,bool)","02ae832f":"trashTokens(address,uint256)","02ae8cdc":"tokenProduct(uint256)","02aec20d":"PrintableToken(string,uint256,string,uint256,int256)","02af2095":"massTransfer(address[],uint256[])","02b04384":"AIRDROP_ADDRESS()","02b09ac5":"charityVault()","02b32af5":"greenToken()","02b33929":"SMTToken(uint256,uint256)","02b3b3da":"Divium()","02b4b52c":"isLogoInitied()","02b518fd":"callback(address,address,uint256,uint256,uint256)","02b5ecc8":"rateAngelsDayEnd()","02b68bbf":"getPlayersItemTickets(address)","02b6ef74":"CRofMakerByIndex(address,uint256)","02b6f286":"TokenContract(address,string,string,uint8)","02b70b41":"addConfirmation(bytes32,address)","02b7144f":"updateCheckpoint(address,address)","02b74a7e":"setupStates(uint256,uint256,uint256[])","02b857f3":"unlockMintDate1()","02b985d3":"arr(uint256,uint256,uint256,uint256)","02ba302b":"nextPrice1Of(uint256)","02ba6f8d":"getHistoryEntry(uint256,uint256)","02ba742b":"extendMembership(address,uint256)","02ba8742":"sendCoins(address,uint256)","02baaf40":"lastInitTimestamp()","02bb2929":"etherToDustPrice()","02bb5d6e":"setEOMarketToken(address)","02bb8465":"setContent(uint8,string,string)","02bc54bf":"companySite()","02be8e4e":"changeOwnerShip(address)","02beee07":"_getElement(uint8[],uint8)","02bf3165":"auctionUnpause()","02bf7fe7":"JumpCoin()","02bf9e7f":"verifySignature(address,bytes32,uint8,bytes32,bytes32)","02bfeeb8":"totalPicoUSD()","02c06bcd":"prevTokenAddress()","02c1d7cf":"iSportNews()","02c1ecbf":"returnStateChange()","02c28410":"getPublicAllocation()","02c29349":"fixWithdrawalAddress(address)","02c2a74d":"episodeManager()","02c3d7f6":"end_ICO()","02c4897b":"getAutorPicture(bytes32)","02c4960e":"InsufficientFee(address,uint256)","02c4980c":"BOC()","02c63852":"TokenVesting(address,address,uint256,uint256,uint256)","02c6d827":"getgamecardpos2(address,address)","02c6f427":"PRESALE_LEVEL_4()","02c71d92":"newClonedRepo()","02c76d45":"mintCoolDown()","02c7e7af":"sold()","02c85991":"distributeMinting(address[],uint256[])","02c90584":"userAddressExists(address)","02c95d2d":"setHaltIco(bool)","02c9972c":"TICK_TIME()","02c9e537":"cresusAddress()","02ca5994":"registerToken(address,uint256)","02ccee02":"getNoteLine(uint256)","02cd0f96":"Deadline(uint256)","02cdc1ee":"setSendGodz(uint256)","02ce5813":"whitelistActive()","02ce5fc4":"generateMintEvents(address,uint256)","02ce728f":"updateExchangeRate()","02ce8ac9":"withdrawSale(uint256)","02d0181c":"HamidToken()","02d05531":"getUriCount()","02d05d3f":"creator()","02d06d05":"bytesToUint(bytes)","02d19fe5":"testApproveWillNotModifyAllowance()","02d1c1e6":"sendOwnerBalance(address,address,uint256)","02d1d5fe":"getDesign()","02d23cef":"sendWithFreeze(address,uint256,uint256)","02d2f349":"lastPeriodChange()","02d3b339":"drawColors(uint256[],uint256[],address)","02d3bd16":"circulatingSupply_()","02d3fdc9":"burnMin()","02d44e57":"_getBetTimestamp(bytes32)","02d49d0b":"_createHiveInternal(address)","02d52fa4":"createProposal(uint256,string)","02d596d8":"getUserFromAddr(address)","02d66fc2":"hasSchema(bytes32)","02d6e7f4":"tokenXchangeRate()","02d6f730":"getFreezing(address,uint256)","02d77954":"getVoteOf(uint256)","02d7ccef":"UP_winRate()","02d800ec":"deactivateKey(string)","02d8146e":"tokensWallet()","02d947ef":"vote(uint256,address)","02d99637":"BlockClaimedEvent(address,address,uint256,uint256)","02da6d06":"lastDao()","02db2d8a":"myRefund(address)","02dbf3c8":"CGE()","02dc2e1d":"queuePayment(bytes)","02dcfc8e":"setAssetFees(address,uint256,uint256)","02dd6731":"disableApiAccess(bool)","02dd92c4":"crowdsaleOn()","02de2cf3":"isLatestPreReleaseTree(bytes32,bytes32)","02df0b61":"deprecateById(bytes32)","02df45a8":"closeActive(uint256)","02e0a2ff":"getAvailableBlance()","02e0b293":"LogVote(address,uint256,uint256,uint256,uint256)","02e0c14a":"get(bytes12)","02e0d5a5":"AquaToken()","02e1033a":"monsterFleeTime()","02e132f6":"recalcInvestorsFee(address,uint256)","02e26c38":"richest()","02e2c3b7":"setRefererPercent(uint256)","02e2f0b6":"Erc20TokenMarket()","02e32144":"precentDecimal()","02e33d25":"HydroToken()","02e49bd9":"publicityAddress()","02e4ef66":"transferWhiteList(address)","02e4f63b":"doExchange(address,address,address,uint256)","02e635e6":"AID()","02e650b6":"DigitalMoney(uint256,string,string)","02e6a5dc":"LIC(uint256,string,string,uint8)","02e6a951":"PayableContract()","02e7491e":"ERC165ID()","02e8243e":"WeiCoin(address,uint256,uint256,uint256)","02e8d8c0":"scheduleTransaction(address,uint256,uint256)","02e97770":"InfinitiEstate()","02e98e0d":"diffMinutes(uint256,uint256)","02e99e16":"SplitAmount(address,address,uint256)","02e9ad65":"dispatchTo(address,uint256)","02e9d5e4":"acceptBid(uint256,uint256)","02eb4759":"RightAndRoles(address[])","02eba8a7":"auditContract(bytes32,bool)","02ec77d2":"joinPot(string)","02ed26d1":"startTokensSale(uint256,uint256,uint256)","02ed4d2d":"Purox(uint256,string,uint8,string)","02ee3275":"setSatoShi()","02ee3a52":"getAllProducts()","02ee50e0":"EliteToken()","02ee6a6b":"RegisterEvent(address,address)","02eef456":"UK()","02eef7c3":"MassivelyMultiplayerOnlineGame()","02ef3844":"getBountiesByCreator(address)","02ef43c3":"recordPurchase(address,uint256,uint256,string,uint256)","02ef521e":"registerEtherToken(address,bool)","02ef6c86":"calculateWithdraw(address)","02efbde5":"batchApproveWhitelist(address[])","02f050e4":"getWinningDetails(uint256)","02f08568":"lockController()","02f0c937":"buyItem(uint256,address,string,string)","02f1bfad":"setupTimeWindow(uint256)","02f1ed99":"putOnInitialSale(uint256)","02f2008d":"hintURL(bytes32,string)","02f20b9c":"getReport(string,uint256)","02f41314":"continueDistribution(uint256)","02f58015":"claim_bounty()","02f65096":"executeBid(uint256,uint256,uint256)","02f652a3":"setTransferAgent(address,bool)","02f83a56":"withdrawBonusToken()","02f9fd84":"HHGTTG()","02faabb3":"fetchOrderByIdWithMerchant(string,address)","02fac967":"ownerHasCard(address,address)","02faf1e2":"revokeAccessFromAddress(address,address)","02fb0c5e":"active()","02fbe0d5":"getKittyGetOrNot(address)","02fc1f85":"ownedNumbers(address)","02fc28c4":"TAP_POLL_DURATION()","02fc2a8a":"_buy(address,uint256)","02fc3127":"tokenSaleBalanceOf(address)","02fd9dd8":"market_DeclareForSaleToAddress(uint256,uint256,address)","02ff1fac":"changeDevevoperAccont(address)","02ffc0b0":"getApprovedAddressesOfList(address[])","03015ea3":"registerArbiter(uint256,uint256)","03021c87":"setMaxInterval(uint256)","0302263a":"getPendingManager()","0302c688":"prod()","03031960":"VestingVault(address,address,uint256)","030326ad":"pushAddr(address)","0303f694":"_getBonusPercent()","030481d5":"changePreseller(address)","03048590":"ratePresale()","03048a42":"createRequest(address,uint256,string,bytes,bytes)","0304de3b":"setFeeRecieverValue(uint256,address)","03058aad":"getLatestManifest(address)","0305bdfe":"Trongold()","03060b68":"getCoreSupply()","03062183":"getVisaLeft(address,uint256,uint256)","03068d57":"setMinimumTextDonation(uint256)","0307024f":"getCreatedStatus(uint256)","03070ae7":"MANHATTANPROXYRIVDR()","03071302":"getCCH_edit_23()","030745ec":"_calculatePaymentToOwner(uint256,bool)","03075018":"getCosts()","03075ded":"emitIssuanceRatioUpdated(uint256)","03078416":"requestOfAmount(address,uint256)","0307acae":"copy(uint256[],uint256)","0307f82a":"SoldToken(address,uint256,string)","03083883":"compose(uint256[],uint256)","03090958":"_transferAct(address,address,uint256)","03096e92":"proposedMilestones()","0309922f":"icoMaxAmount()","0309c7f8":"payLastSixteenWinner(uint256)","030a78aa":"MAX_SITE_TOKEN_ID()","030b1776":"ROPE()","030ba25d":"withdraw(uint256,bytes)","030bccb0":"QLANCE2()","030c3631":"dungeonPlayerCount(uint256)","030cc118":"depositSuccessful_()","030cecc7":"decode(string,bytes32)","030d406b":"entryPayout(uint256)","030d945c":"PMHToken(uint256,string,uint8,string)","030e30df":"super_transferFrom(address,address,uint256)","030e6b98":"testFinalizingBeforeCapChangesHardCap()","030e9080":"returnAllCoke()","030eafa0":"endThisContact()","030f5702":"returnAmount(uint256)","03101f46":"setDistributionMinimum(address,uint256)","03110f23":"returnKitty(uint256)","031122ef":"exhaustChibis(uint256,uint256)","031126e1":"_approx(uint256)","0311904c":"investAmount()","0311a8f0":"getUploadNames(uint256)","03122043":"setCompte_40(string)","031324fa":"_transferDivis(address,uint256)","03137d43":"test_insert_findWithHintPrevRemovedUpdateHead(int256)","03138b31":"phase_5_remaining_tokens()","0313953d":"indexBalance()","03141fcd":"listPairForReserve(address,address,address,bool)","03145ac2":"WildFurToken()","03149252":"everyoneDisabled()","0314bcfb":"FUND_SUPPLY()","031578af":"bytes32Storage(bytes32)","0315a513":"getDigitalAsset()","0316bdb0":"CofounditToken(address)","03178d05":"getB3()","0317c06e":"isAllowedBalance(address,uint256)","0317fb71":"asmApprove(address,address,uint256)","031a36f1":"EBBToken(address,uint256)","031a8161":"convertDecimalBack(uint256)","031adff0":"whitelistingAddress()","031b3677":"funders(address)","031bd4c4":"TOKEN_LIMIT()","031d5d01":"readMessage()","031d7421":"createRegistry(address,address)","031d973e":"closeMarket(bytes32)","031e1b65":"sendFounderAndTeamToken(address,uint256)","031ee1c8":"contribute(address,bytes32,bytes32,uint8,bytes32,bytes32)","031f22e7":"PRICE_STAGE_TWO()","031f273c":"getMixerCountByType(bytes32)","031f3b1a":"remainderAmount()","031f74d4":"bugDiscovered()","031f9d7b":"buyCore(address,uint256,uint256)","031fce17":"listBackers(uint256)","0320fead":"getUsedBySoftware(uint256)","03216695":"monthlyWithdrawLimitInWei()","0321f836":"namiMultiSigWallet()","03228d0f":"changeSendingBanPeriod(uint256)","0323aa55":"isValidDeletion(uint8,bytes32,bytes32,string,address,address)","0323cc33":"getKnowledgeSinceLastUse(address)","0323e576":"INITIAL_CARD_PRICE()","0323f64a":"removeSubDivision(uint256)","03240775":"getActiveEntryById(bytes32)","0324149a":"marketGolds()","0324d0d9":"calculatVotePrice()","03251a08":"setMin(uint256,uint256)","0325be06":"biathlon_transfer(address,address,uint256)","03261030":"Time_call()","03267c60":"CITY_START_PRICE()","0326be45":"Permission()","0326c06b":"utfStringLength(string)","0327194a":"startPublicsale(uint256,uint256,uint256)","03282473":"AcceptedApplication(address,uint256,string)","03291893":"issueAndActivateTokenBounty(address,uint256,string,uint256,address,bool,address,uint256,address)","03294614":"buyPickaxes(address)","032a0af7":"adIds()","032a8838":"withdrawOnBehalfOf(address)","032aabf0":"has_presale_time_ended()","032b0824":"updateLatestRevision(bytes32,bytes32)","032b13da":"fourthChainETC()","032b3400":"end_Time()","032b642d":"changeStartAndEndDate(uint256,uint256)","032bc66b":"Locked(uint256)","032be08b":"ticketCountMax()","032c05aa":"maximalParticipationAmount()","032cbc5f":"chainStartBlock()","032ccf33":"dayPot()","032cfa5c":"comelBabyCoin()","032dbae5":"setTiers(uint256,uint256)","032e0868":"getAllStaff()","032eb997":"CCXTokenERC20(uint256,string,string)","032fa796":"SVCoin()","032fc13b":"whatRound()","03314efa":"shares()","0332c6d4":"advertisementPayment()","03335d04":"ethGoal()","03339af5":"getRobotCountForUser(address)","0333d499":"getOwnedPoints(address)","0333d4a2":"ZilleriumPresaleToken()","03347d75":"findOrderIndexForAddress(uint256,address)","0334e725":"FALCON(uint256,uint256)","0335d533":"USER_GET_CROWDSALE_TOKEN()","0335e18f":"timeComplete()","03379e7f":"Initialize(string,string,uint256,uint256)","0337aa74":"systemAuctionDuration()","0337e379":"releaseTokenOwnership()","0338e3a5":"getArrIntField2()","03395ba5":"AUCTION_TOKENS()","033988a1":"Pollen()","0339f300":"revise(uint256,bytes32)","033a010b":"adminClaimAirdropMultiple2(address[],uint256)","033a38b0":"vehreqexist(uint256,address)","033a6cab":"admin_redeem(address)","033b8675":"ICOCREED()","033ba5d1":"getWillData()","033c44c3":"m_totalInvested()","033c6ee6":"countHolders()","033c8477":"mined()","033da70b":"setLogicContractAddress(address)","033df9cb":"stepOneStartTime()","033e7ef4":"registerVoteToken(bytes32,bytes32)","033e86d4":"PurchaseLocked()","033f7bc9":"testEmergencyStop()","0340249e":"HotelloadTokenERC20(uint256,string,string)","03402a9a":"ClubTransferContract()","03406e76":"getOptionSellOrders(uint256,uint256)","034187fd":"setEthToCents(uint256)","03427656":"getDefaultSoftResolutionBlocks()","0343d550":"getApprovalCount()","0343dfa0":"checkInvariants()","03440022":"setAsSeller(address,bool)","0344a36f":"draw(address,bytes32,uint256)","03460f6c":"airdropAllowed()","0346a4ad":"MAXIMAL_PARTICIPATION()","034741a8":"patformWithdraw(uint256)","03487513":"SIGToken(uint256)","034889ff":"unFollow(address)","0348946d":"mintedTokensCap()","034a7bce":"saosao4()","034ac7a3":"ROLE_GRADE_PROVIDER()","034cb28e":"addressOf(address,bytes)","034cd0b0":"buyTokensGrowthLife()","034cf8bc":"transferClub(address,uint256)","034d0834":"NoBsCrypto()","034d3b0d":"withdrawTipForDeveloper()","034de540":"_getEthAmount(uint256)","034f55d2":"calculateSum(uint256[])","034f9774":"setWhitelistWallet(address)","034fcf55":"updCouponConsumed(string,bool)","0350bcd9":"toSendLeft()","0350d085":"Sign(string,string)","035186d6":"increasePrizePool(bytes4)","0351947f":"claimFine()","0352017b":"getInvestmentRecord(uint256)","03520535":"getPI_edit_10()","03526ff0":"LFDNetwork()","035340f1":"Bitether()","03547e53":"ownedBalance(address)","0354d6c5":"accountslength()","035502f2":"addCategory(string,uint256)","03553835":"calculateTokenAmount(uint256,uint256)","0355b70a":"getSpaceshipTotalSold()","03562dbb":"changeEmissionContractAddress(address)","0356948e":"previousstagedata()","0356fe3a":"genesisBlockNumber()","0357088b":"trancheByIndex(address,uint256)","0357371d":"release(address,uint256)","03580712":"executeDueToInactivity(bool)","03582fc5":"setReferralBonusPercent(uint256)","0358395d":"DominionCoin()","0358c295":"testInitialBalanceWithNewRGXBonus()","0358d965":"addPayout(uint256)","035ac814":"lastTimeUpdate()","035cf142":"getMinimumDeposit()","035d0880":"_requireQuePayment(uint256)","035d37a8":"setMinContribAmount(uint256)","035e898a":"getStellarInvestor()","035e902d":"Set_EmergencyCode(uint256,uint256)","035f057d":"multiIncreaseApproval(address[],uint256[])","03602e9e":"getPrivAddress()","03606b30":"setStopFunding(bool)","03611ec7":"Finside()","03612cb5":"settle(bytes32[],uint256[],uint256[])","03627e70":"countStudent()","0362d1f6":"getGamblerBet(address,uint256)","03635100":"bizcoin()","0363b1e1":"trade(address,uint256,address,address,bool)","036478c1":"GlobalAmountCapSoft()","03652c4e":"ICOStartTime()","03656d07":"exchangeMethodIsAllowed(address,bytes4)","036648b7":"TokenRateUpdated(uint256)","036723a2":"Payout_intern(uint256)","0367f96d":"setHardCapValue(uint256)","036896ab":"getERC20TokenBalance(address,address)","036a131d":"setPI_edit_28(string)","036a66eb":"GetProductionPerSecond(address)","036ae645":"deleteMessage(uint16)","036b3a81":"partnerSupply()","036bd387":"totalEthInWeiForFirstIco()","036c36eb":"relaySellerRequestCancel(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32)","036dd086":"createGame(string,string,uint256,uint256,string,string,string,string,bool)","036e05b0":"CreatePHX(address,uint256)","036e4220":"changeMinAcceptQuorumPct(uint256)","036ee850":"votingDeadline()","036f60ec":"setSupplyAdjuster(address)","037051eb":"startRound(address)","0370c0d9":"_repayLoan(uint256,uint256)","0370ca41":"contractStage()","0370e65c":"preSaleEndedAt()","037101c4":"remainingPresaleCap()","03710668":"callContract(address,bytes)","03714af7":"burnApproveReset(address,address)","0373e649":"Withdrawal(address,address,uint256,uint256,uint256)","03741040":"get_presale_arbits_total()","0374fc6f":"getBestOffer(address,address)","03750d94":"serverSeed(address,bytes32)","03771327":"HardcapGoalReached(uint256,uint256,uint256,uint256)","03771f2f":"numOfInflatableTokens()","0377ebe8":"itemKindCount()","0378f83f":"destroyFashion(uint256,uint16)","03792d52":"lastSubTokenBuyerOf(uint256)","037933dd":"calcSTQAmount(uint256,uint256)","0379565f":"EIP165Implementer()","037a417c":"testFunc()","037a9d30":"isDataSource()","037ae882":"reLoadKey(uint256,uint256)","037b5fdc":"burn_balance(address)","037c68b2":"disagreeCount()","037c983a":"resumeCrowdSale()","037c99b0":"setBonus(uint256,uint256)","037ca5fc":"HubCrowdsale(uint256,address,address)","037ca6c4":"allAgingTimesAdded()","037cf465":"has_token_sale_time_ended()","037d4ff8":"get_pre_kyc_bonus_denominator()","037e2e91":"Insureum()","037ed3e2":"executeClaim(address,address,uint256)","037ef916":"CaterToken(address,address)","037f9cf0":"rewardDistributionStarted()","0380e2f3":"getHashOfTheSignedDocument()","0380fd03":"newExchange()","0381c260":"getYearlyUSDSalary(address,address)","0381cb3b":"setRowcol(uint256,uint256[2])","03824f76":"hasSoldOut()","03828729":"coordinatesToAddresses(uint32)","0382c254":"CheckHash(uint8,uint8,uint8,uint8,bytes32)","038339ab":"publicGetDeposit(uint256)","03833bae":"ValidContributionCheck(uint256,bool)","0383966b":"testCanFinalizeOnCap()","0383a6f0":"CheckLimTransferDay(address)","038424c3":"maxEarningsClaimsRounds()","038461ea":"getCertifiedStudentsCount()","0384899b":"OwnershipChanged(address,address)","03850848":"saleAuctionContract()","03856d15":"BalanceOnlyOwner()","0386a016":"closeProposal(uint256)","03872547":"setarg_1_input(uint256)","0387b0a2":"saleCounter()","03880bab":"deal(uint256[2],bytes32,bytes32,uint8)","03894922":"allocateTokens()","038b117b":"onlyAdminAndNotFinal()","038ccee8":"createNew(uint256,address,address,address,uint256,uint256,uint256,uint256)","038d71ee":"switchOff()","038e666f":"ethereumSaleRate()","038e7577":"setConfigUint(bytes32,uint256)","038f1845":"returnFunding()","038f21a6":"mapToRange(uint16)","038f5ed6":"drawDown(uint256)","038f8b64":"batchFillOrdersNoThrow(uint256[],bytes[])","038fa9cb":"getRomms()","03901913":"DLBToken(uint256,string,uint8,string)","03905f10":"scoreKnockouts(bytes32,bytes32,bytes12)","03906217":"SaddleNotForSale(uint256)","0390d190":"YouDealToken()","0392d2b4":"isManagerAllowed(address,string)","039314b1":"VotingEnded(address,bool)","03941cc5":"onwerName()","0394b9ce":"getWeaponList()","03959bb7":"setDataContract(address)","03960631":"raindropAddress()","03969758":"SetDurationOfLock(address)","0396dcb0":"purchaseByEMONT(uint16,uint256,address)","0396ece5":"SetupReserve(address)","0396f60a":"Invested(address,uint256,uint256,uint128)","03975d1f":"_validateBetOrRefund(uint8)","03976b0e":"setBattleProviderAddress(address,address)","03980ac4":"prophetize(string,string,string,bytes32,bytes)","03985426":"getMode(bytes32)","03991aea":"getReleasableFunds()","0399247a":"isVotingProxy(uint32,int256,address)","0399321e":"set(bytes)","03995b2d":"holdingsOf(address)","03999795":"rouletteOwner()","0399c357":"assignFreeReadings(address,uint8)","0399f881":"ART_DECIMALSFACTOR()","039a21b8":"tryExecute(address,bytes,uint256)","039af9eb":"tiers(uint256)","039b267d":"mdtFoundationAddress()","039b6c34":"assign(uint16,address,uint256)","039ba6be":"getPriceETH()","039bd55a":"constrctor()","039c84c1":"Add(uint32)","039c9a21":"refundTransactionInternal(uint256)","039c9d84":"getOpenNum(bytes32)","039d0bfa":"setSelfOn()","039d8751":"GOX()","039de01d":"unregisterScheme(address,address)","039e4e2a":"situation_challenge()","039e9e00":"acceptOwnershipAPI()","039efdeb":"startMilestone()","039f0156":"withdrawNxc(address,uint256)","039f0e9c":"_createPuppy(uint256,uint256,uint256,uint256,address,uint16,uint16,uint16,uint16)","039f6b28":"QuadrantAssets()","039fb41c":"get_description_hash()","03a0d68f":"expiry_date()","03a168e0":"jackpotLastWinner()","03a19a4f":"maxDropsPerTx()","03a1b87d":"manageInvestors(address,uint256)","03a1bdc3":"walletLockBoth(address,uint256)","03a250f9":"startWork(uint256)","03a3053b":"reserveFundManager()","03a47b58":"tyms(uint256)","03a503a4":"addHorseIndex(bytes32)","03a5c8e7":"tdeActive()","03a68d1d":"REBToken()","03a6981b":"StateUpdate(uint128,int128,int256,uint256,address,uint128)","03a76fed":"createToken(uint256[],address)","03a77c7a":"setRegulator(address,address,bool)","03a7b41f":"queryPlotExists(uint8,int256[],int256[])","03a7bdd7":"testCloseContract(bytes32,bytes32,uint256,uint256,uint64,uint64,bytes32,bytes32,bytes32,uint64)","03ab614d":"testTranferOneToken()","03ac58d7":"deathData_f8()","03ac7215":"setTotalSupply(uint256,bool)","03aca792":"pendingList(uint256)","03ad4be3":"updatetoken(uint256,string)","03adaee6":"applyForCertification(string,string,string,string,address,uint128)","03adcbd2":"walkBook(uint16)","03addce2":"payout(address[],uint256,address)","03ade532":"ctrtMarketPrice()","03ae0357":"DevidendsSnapshot(address,uint256)","03ae3ded":"aproveLoan(uint256)","03ae4c1f":"buyCoke()","03aeeba6":"_setClientSupply(address,uint256)","03af2cda":"createMultiple(uint256[],uint256[],uint256[],uint256[],uint8[],uint256[],address[])","03af73d3":"sendCollectedEther(address)","03b05c73":"maxIssuedTokensPerIco()","03b0a55c":"icoPvtEnded()","03b0e428":"_unpackRarityBonusValue(uint256)","03b103ea":"Vote(uint256,string,bytes32[])","03b25050":"CGCToken()","03b4e20c":"removeAddressFromAccountFor(address,address)","03b5af0f":"incomingRandomNumber(address,uint8)","03b5d494":"takeBet()","03b62e10":"lowestDiff()","03b6eb88":"note(address,uint256)","03b718ee":"getCityBuildings(uint256,bool)","03b753dd":"tokenPurchase(address,uint256)","03b8a24e":"ritual(uint256)","03b918dc":"allow_contributions()","03b98c0e":"pauseable()","03b9b4f9":"releaseTokens(bytes32,uint256)","03b9f0b2":"referrerBonusRate()","03ba27f6":"withdrawToWallet()","03ba3a88":"notifyContract(address,address,uint256,bytes)","03bad56e":"transferERC223(address,uint256,bytes)","03bb5d8a":"openGameResultAndNewGame(uint256,string,bytes32)","03bbba93":"incentiveDistributionStarted()","03bc1e19":"changeOneBet(uint256)","03bc6d0d":"amendFee(uint256)","03bcebea":"initOneChance(address)","03bcf11d":"abortSale()","03bcf514":"finishedCrowdsourcingDisputeBond()","03bda14e":"raiseMaxNumBets(uint256)","03bdecf5":"right69(uint256)","03bec188":"ChangeMinAmount(uint256,uint256)","03bf4fb7":"setTradersContract(address)","03bf8e70":"birthKitty()","03bfee9e":"_getBidId()","03c0bfb5":"getOwnUserState()","03c13148":"setReceiver1(address)","03c175ff":"isRestrictedAddress(address)","03c1d1df":"collectERC20(address,uint256)","03c2d5b6":"nextGameDeveloperMiningPower()","03c327f0":"changingMilestones()","03c401e3":"ADDR_TKG_VC()","03c41c04":"NewUpgradedAmount(uint256,uint256,address)","03c45305":"foundersSupply()","03c49580":"priceOfElement(uint256)","03c4d93a":"payWithGold(uint256)","03c5b1dc":"setPeriod(uint256,uint256)","03c5f26a":"PublicCheckGameStart()","03c5faf4":"s12(bytes1)","03c63869":"resumePlayer(address)","03c6c8f9":"TheExcelToken()","03c7bce1":"_addMinter(address)","03c7da39":"mintMarketingTokens()","03c83302":"distributeDividends()","03c94ca6":"tokenSoftCapReached()","03ca0a95":"performSetTokenControlInfo()","03ca0eed":"requireCustomerId()","03ca0f6c":"advisors(address)","03ca30e0":"changePreMine(address)","03ca558a":"read_i8()","03ca71d6":"setSecurityCheck(string)","03ca7bcc":"debug_last_approved()","03cba01e":"bonusEndTime250()","03cbcf57":"getBetAmountAtLayer(uint16)","03cc1e32":"addFundingRound(uint256,uint256,uint256,address[])","03cc5597":"wrestle()","03cc5e4d":"setTechnicalAdmin(address)","03cc7b85":"num_tokens_auctioned()","03cc8efb":"BethingWorldCup()","03cd3e47":"transferRecovery(address,address,uint256)","03cddb2c":"capitalAllocated()","03ce6c55":"roundUp(uint256,uint256)","03ce9c00":"AcceptsTokens(address)","03cf0678":"bigBang()","03cf4fd6":"expire(uint256,uint256,uint8,bytes32,bytes32,bytes32)","03cf678b":"vitToken()","03d08f3b":"nextLotteryTTWTokenId4()","03d0b7d2":"minimumFeePlusDividends()","03d0cecd":"getLx()","03d2107f":"getSender(bytes32)","03d22885":"scheduleCall(address,uint256,bytes4,uint256,uint256,uint8,uint256)","03d231b5":"signerFlag(address)","03d258c4":"set_prices(uint256)","03d285fd":"nameok(string)","03d2e963":"zint_now()","03d37d78":"showPoolNumber(address)","03d38296":"indexSuperInvestor(uint256)","03d3a6b7":"shutForETH(uint256)","03d41eb6":"reserveSupply()","03d499ef":"totalEthereumICOReceived()","03d4e98a":"getProposalVote(uint256,uint256,uint256)","03d50703":"challengeExit(bytes32[],bytes32[],uint256,uint256)","03d51a0c":"transfer_ether_to_owner(uint256)","03d5aa0c":"PigChain()","03d5f483":"founderTokenVesting()","03d699da":"YggdrashCrowd(address,address,address,uint256,uint256,uint256,uint256)","03d6b6b4":"EpigenCareCrowdsale(uint256,uint256,uint256,address,address,address)","03d6d7b6":"getCallMaxCost(bytes32)","03d7244f":"dice_game(uint256)","03d756cb":"ethealToken()","03d75937":"setUIntValue(string,uint256)","03d76547":"addressFin()","03d83c4d":"stopTge()","03d9d253":"unlock(uint256,address,address,bytes)","03da04d7":"BRN()","03da8902":"transfearDBOwner(address)","03dc0532":"getLableRecords(bytes32)","03dc6340":"AdminTokenSent(address,uint256)","03dcead2":"directDebitOf(address,address)","03dcf6bc":"truToken()","03dd5a18":"testSimpleArray()","03dd88f8":"getAssTotal()","03ddc104":"ownerClaimOverride(uint256)","03ddcae9":"checkTradeSignature(bytes32,uint256[],bytes32[])","03dec463":"getRentOwed(address)","03df1550":"ECR20HoneycombToken()","03df6106":"setNewReleasePeriod(address,uint256,uint256,uint256)","03e07b2f":"getMinRefEthPurchase()","03e1b3c6":"sellAllAmountBuyEth(address,address,uint256,address,uint256)","03e20503":"localManualEntry(bytes32,bytes32,uint256,uint256,address)","03e28366":"playerNum()","03e2b9f5":"syncDate()","03e337d1":"SEPCToken()","03e39113":"BeggarToken()","03e3b1ed":"applicationApproved(address,address)","03e3f677":"setICOStart(uint256)","03e3fa51":"editScores(uint256[],uint256[])","03e4d9f5":"getDayIndex(uint256)","03e55f1c":"lockEscrow(bytes32,address,uint256)","03e5affd":"add(string,int256,int256)","03e6c117":"getIcoAddrListByIcoRuleId(uint256,uint256)","03e7b4e9":"getEmission(uint256)","03e83b6a":"MyToken(uint256,string,string)","03e864fa":"TestableMarketContractOraclize(string,address,address,uint256[5],string,string)","03e8837c":"getUserCount(address)","03e9287a":"Tacoin(uint256,string,string)","03e93b2e":"changeStarbitWallet(address)","03e9598c":"updateClientVersion(bytes32)","03e96fe3":"getAllTickets()","03e9e609":"getRecord(uint256)","03ec1bbe":"tokenIssuedTotal()","03ed9d21":"setMaxContribution(uint256)","03edae57":"withdrawFounderFunds(uint256)","03edf914":"placeBet(uint256,uint8)","03ee8f08":"getCoeff(uint16)","03eea024":"issueTreasury(address,address)","03eeb40e":"AngelsvsRedSox419()","03ef03b4":"buyBulkMidGradeCar(address,uint256[],address)","03ef2a2c":"tryExecuteProposal(uint256,bytes)","03efb5c4":"book(address,uint256)","03f0cc64":"affiliateCodes(address)","03f10bff":"IDMONEY()","03f11878":"casino(uint256,uint256)","03f14be9":"updateEmployeeWallet(address,address,address)","03f14e96":"currentAirdrop()","03f166de":"calculateTransferValue(uint256,uint256)","03f17336":"BOPs(uint256)","03f187ea":"registerFee()","03f21bda":"privateOfferingTokens()","03f3b07f":"setUserScore(address,uint32)","03f3cea1":"requiresHardCap()","03f3e275":"getRatioList()","03f3e7c8":"setICOWeek4Bonus(uint256)","03f4864d":"XXXXXXXX05()","03f499b8":"refundState()","03f6477d":"setBonusSetter(address,address)","03f67e1b":"changelp2(address)","03f73f08":"start_ICO2(uint256)","03f744b0":"JessieEducationToken()","03f7d4ff":"BitpaintingStorage(uint8)","03f8008c":"getUserDAOsCount(address)","03f979c8":"saleEndTokenCreationRate()","03f9b456":"LockupTokensWithdrawn()","03f9c793":"invest(address)","03fad66e":"settokenCap(uint256)","03fb3f63":"currentMigrationSource()","03fba444":"_receiveBuyNextRank(address)","03fce7ef":"approveEscrow(uint256)","03fd8c65":"withdrawBalanceHashing(address,address,uint256)","03ff20a1":"crowdfundEndTime()","03ff5e73":"stopTime()","03ff90f6":"minApproval()","03ffae3b":"FlightDelayDatabase(address)","040177b7":"previousDungeonId()","0401d897":"setVestingCliffDateTime(uint256)","04021ba8":"_increaseBalance(address,uint256)","04029f23":"_setBugFixVersion(string,uint32,bytes32,uint32)","040425d1":"protectedSupply()","040502e4":"EmmiumCoin()","04053d21":"checkCourse(uint256)","0405440c":"secureMode()","040622a9":"UNITPaymentGatewayList()","040677f1":"sentFirst()","0406870c":"SupplyManagementChainSolutions()","04072322":"GetEventData()","0407dc78":"medalBalanceOf(address)","04089c7d":"ALTnextCoin()","040a772e":"getUserDividends(address)","040c014b":"_changeName(string)","040c3a53":"maxRacers()","040cf020":"withdraw(bytes32,uint256)","040d54ce":"addFile(bytes32,string,uint256,string,string)","040d5e82":"partialFlip(bytes32)","040da8f4":"jackpotBalance()","040e33f0":"SHRToken()","040e55f5":"getTransferCount()","040ea2f4":"ownerSetPriviledgedAddress(address)","040f9a5e":"transferRemainingTokens(address)","040fa051":"isPendingRegistration(address)","04106c8b":"startGeneration()","0410ec85":"randomReward(uint256[])","0410fac7":"adminRemoveTrustedCurrencyContract(address)","04115187":"initTime()","0411bca8":"getChallengeAnswerResult(uint256)","041257ef":"setWhitelistControllerAddress(address)","04126ce5":"getHashSubmissionEnd()","04143865":"dec_multiple()","04148f7e":"createGame(uint256,uint256,string,address)","04150694":"airdropBSupply()","04153ac9":"inflateActiveSupply(uint256)","04155727":"dcntrpls(uint256,uint256,uint256,uint256,uint256,bool)","04157752":"withdrawRed_(uint256,uint256)","0415bd13":"create(uint256,uint256,int256,address)","04165443":"gatherAllOldBalanceOf(address[])","0416c10c":"_getBytes(address,bytes32)","04186c57":"getPermissionsProvider()","0418945a":"addStablecoin(address)","0418ac09":"unFreezeTransfer()","04194636":"bulkTokenSend(address[],uint256[])","04198675":"setHitPrice(uint256)","0419c814":"isExistedOwner(address)","0419eca5":"createChild(uint256)","041abd9f":"timestampEnd()","041ae880":"funder()","041b1406":"checkPoDs(address[])","041b8c3e":"group(address,uint256)","041c3ade":"punkIndexToAddress()","041d0c0b":"MyTokenLoad(uint256,string,uint8,string,address)","041d15c9":"getPurchaseTimestamp(uint32)","041d40c1":"buyOrders(bytes32)","041dad49":"incrementpostId()","041dd0f9":"ValueToken()","041dd3f6":"testControlCreateWithParentsParentNotInUse()","041e3929":"getInvitationCreatedOn(address,uint256)","041e6b8b":"rejectUpgrades()","041f173f":"blacklist(address[])","041fa8aa":"times9()","041fe13d":"onEtherandomSeed(bytes32,bytes32)","04213a59":"setServiceDuration(uint256)","0421a94c":"sendSpecialTasterPackage(address,uint256)","042228db":"adminUpdateArrayInvite(uint256,uint256,address,address)","0422ddf3":"isGamePaused()","04239743":"lastGrantedIndex()","0424b6fe":"ContentChanged(bytes32,bytes32)","0424d979":"removeDepositCreator(address)","0425b5e9":"initialLockAddress(address)","0425c357":"submitVote(uint256,bytes32,bytes)","0425c4bf":"updateProduct(address,string,string,uint256,string,bool)","0425ccba":"DoubleETH()","0425e6ff":"SEXNTestToken()","04267892":"koth()","04269bc2":"ICO_SUPPLY()","0426c697":"changePayoutAddress(address)","0426dcef":"unlockBalance(address,uint256)","04275375":"MCToken()","0428c6aa":"earlyBirds(uint256)","0428ca27":"WalletAddressUpdated(address)","04293236":"m_owner80()","0429b880":"confirmationPeriod()","0429b9ca":"totalEthAmount()","042abdf8":"PRE_ICO_MIN_CAP()","042ae62b":"killAborted()","042b5fed":"placeBet(bytes32)","042c71f5":"DevsmartCoinFour()","042cb150":"batchSend(uint256,address[])","042d65ab":"getTokenAwarded()","042e58c8":"receiveResults(string,uint256)","042e9a43":"propose(bytes32,string)","042f3b34":"DesafioStone()","04304b55":"getUSDEth()","04306d69":"MOOSToken()","0430e405":"gameStopped()","043106c0":"deleteAddressValue(bytes32)","043122bb":"minimumParticipation()","04318794":"giveTimeToDemoc(bytes32,uint256,bytes32)","0431dd86":"TokenNedCoin(uint256,string,uint8,string)","0432ff56":"START_WEEK_4()","043331ee":"addOnCount()","04336615":"hashLoop(uint256,bytes32)","04338def":"maxAmountPreICO()","04339140":"setCloneFeePercentage(uint256)","04339582":"buyAndTransfer(uint256,address,address,bytes,uint8)","04343722":"addUsers(address)","0434a44d":"codeSize()","0434e5a6":"changeWalletForETH(address)","0434fe0b":"heal()","043531b1":"setFeeDivisor(uint256)","0435a745":"stat()","04362c2d":"getEsgoTXCount()","043753ba":"makeDecision(uint256,bool)","0438ebce":"getPlayerBetForPlayRound(address,uint256)","043996c2":"setUseAmountBasedBonus(bool)","0439f7d4":"getProviderSupply(uint256,uint256,uint256)","043aea8b":"CrypthubtTokenTest()","043b743f":"investor_getShortInfo(address)","043bb5e7":"getIdentities(address[])","043c8816":"INM()","043cf01a":"addCourse(string,uint256,uint256,uint256,string)","043cf343":"CreditIDENTITY(address)","043d0258":"changePriceLimits(uint256,uint256)","043d5f1a":"ENCSToken(uint256,string,uint8,string)","043da739":"getNextBid()","043eabd0":"RUVI()","0440187e":"hostingProfitAddress()","04403b30":"TokenSaleSucceed()","0440c8e4":"_unpackRarityValue(uint256)","044166ec":"PollManagedFund(address,address,address,address,address,address,address,address,address[])","044215c6":"token(uint256)","044337ca":"setPortfolio(address)","04433bbc":"getContractAddress(string)","044431f0":"setRefundEnabled(bool)","0444c5db":"SSPRegistryReplaced(address,address)","0445154c":"PRIVATESALE_USD_PER_MSENC()","044553ae":"configureBoard(address)","04455e95":"testIsList(bytes)","04461f4d":"XaurumAmountMelted()","0446e187":"buyDonation(address,uint8)","04474181":"JixoCoin(uint256,string,uint8,string)","0448e936":"setSite(string)","0448f79f":"addOptionChain(uint256,string,uint256,uint256,bytes,address,int256[])","0449aa40":"allowedToBeSold()","044a3038":"_changeResolverAllowances(string,address[],uint256[])","044a5f97":"mgmtDistribute()","044aed7c":"removeEmployee(address,uint256)","044b1b02":"addProblem(string,string,string,string,string)","044bf6c2":"getSpinnerData(address,uint256)","044c1d4d":"clientVersion()","044c9366":"privateCrowdsale(address,uint256)","044c96e4":"startGame(string,string)","044ce308":"refundBuyer(uint256,uint256)","044d0b06":"oraclize_query(string,string[2])","044ec699":"get_mail(uint256)","044f19bd":"InfiniteCorridor()","044f53ee":"OPC(string,string,address)","044f9ac8":"findThroneCalled(bytes)","04509918":"scheduleCall(address)","04514185":"ShortBlog(string)","04517225":"transferlock()","04520116":"centsPerEther()","045236b4":"getChainyData(string)","0452396c":"subtrInvestorBalance(address,uint256)","04532035":"settleEth(address,uint32,uint32)","0453a7d2":"computeBonus()","0453e3b1":"ITIX()","04549d6f":"presaleStarted()","04550e70":"MyTestToken2()","04554443":"lockDuration()","045585a4":"priceList(uint256)","0456860a":"acceptAtCommunity(address,uint256)","04571211":"setTokenReward(address,address,uint256)","04578f90":"JTC(uint256,string,string)","0457d76b":"Mesa(bytes32[],uint256,address)","045820b3":"Player()","045894ab":"getCreate()","0458996a":"CBTSToken()","04590a28":"EtherWithdrawn(uint256)","04599012":"balanceToken(address)","045a1796":"upgraderSet()","045aceb9":"useResolver(string)","045b1a0c":"isBreakingInvestorCap(address,uint256)","045b7dca":"mintSupply()","045b9c72":"START_TIME_PRESALE()","045c123a":"sponsorDAI(uint256,uint256)","045c6ce0":"voteForProposal(uint256)","045cc8ec":"_createZodiacWithTime(uint256,uint256,uint256,uint256,address,uint256,uint256,uint256)","045ccf7b":"byte64ToString(bytes1[64])","045d0389":"exchange(address,uint256)","045d2ad9":"upgrades()","045d4503":"TeamDeleted(uint256,uint256[])","045d465f":"setDataFactory(address)","045d46c2":"getBalances(address,address)","045e240f":"getAvailableTokensToWithdraw()","045e7dd7":"ContractEdited(string,address)","045ea88a":"fishySalmonToken()","045eb3b5":"expLimited(int128,int256,int256)","045ec563":"rndInc_()","045eea7d":"changeSelfName(string)","045f2593":"getRoot2(uint256)","045f7850":"airDrop(address,uint256)","045f8aad":"CONUNToken(uint256,string,uint8,string)","045f91ea":"getCurrentWallet()","045f955b":"buyPets(uint256,uint256)","045ff49a":"TIER2END()","0460b206":"Bxcoin()","046111e9":"addVip(bytes32,string)","04612d20":"minionAdd(address)","0461ac58":"dteamVaultAddr3()","04638e1a":"getBalanceOf(address,address,address)","0463cd73":"getSuperManager()","0463e4af":"releaseDividendsRights_(address,uint256)","0464f4b2":"InitialPriceEnable()","0464f8d0":"getCatsCount()","04651a1e":"firstRoundICOEnd()","0465832e":"modifyTransFee(uint256)","04658ad8":"NonIssueDeposits()","04659819":"capUsd()","0465a76d":"airdrop_cnt()","0466450e":"getUserByAddress(address,address)","046672cc":"batchTransfer(bytes32[],uint64)","0466c7ab":"executeComputation()","04670c9d":"nextStage(uint256,uint256)","04673368":"getCurrentPrice(uint256,uint256)","04676af4":"getCompte_7()","0467c3ff":"ThirdBonus()","04684ba3":"convertTokens(address,address,uint256,uint256)","0469756a":"MintAuthority(int256,address)","04699a72":"tipbot()","0469d644":"storeSecretVote(bytes32,uint256)","046ae3c2":"YourPyramid()","046c472f":"IOU()","046c82e4":"GraceFund()","046ce030":"isFactoryApproved(address)","046d30c7":"_random(uint256)","046d5c53":"setMintAmountApproval(address,address,uint256)","046dc166":"setSignerAddress(address)","046e85f9":"getLastPendingTransaction()","046f7da2":"resume()","04706fdf":"giveContributionsBackProfitBugged()","047087cc":"getTotalTokenSupply()","04719030":"manualSendTokens(address,uint256)","04729a8d":"tokensToEthereumAtSupply_(uint256,uint256)","0472a3bf":"doCrowdsaleMinting(address,uint256,uint256)","0472f549":"ran()","0472f72c":"_allocation(address,uint256)","0473e09c":"setConfigUint(bytes,uint256)","047408aa":"getAngelByIndex(address,uint256)","0474b484":"AllyICO()","0474d4a4":"isInitialAllocated()","04751333":"getRevForecast()","047564b7":"revokeValidator(address)","0477d647":"setSalary(uint256,uint256,uint256,uint256)","04780570":"ERC223Token_STB()","04787d83":"winBidDekla(address,address,uint256,uint256)","047956cf":"assign(address,uint256,bool)","0479fcd0":"setPopNameOriginal(uint256,string)","047a7ef1":"transferrable()","047a8dcb":"JetwingToken(address)","047ba641":"LowerStartingPrice(uint256)","047c738e":"wdivfloor(uint128,uint128)","047cfed9":"hasOwnership(uint256)","047d6649":"getUpdateByID(uint256)","047da93f":"testInvariantOverflow()","047de1f3":"drawerFee()","047e2b27":"setDataStorage(address)","047f9651":"make(uint256,uint256[4])","047f993d":"_vote(bytes32,uint8)","047fc9aa":"supply()","047fe8b3":"getUnsoldTokensBack()","047febbe":"admin_renewLockedAddress(address,address,uint256)","04803c2a":"addSales(uint16,uint128,uint16,uint16,uint64,uint64,uint16,uint8)","04804ee8":"sell(string,uint256,uint256)","0480c975":"setUnicornContract(address)","0480e58b":"maximumSupply()","04812aaf":"moveAccountData(address[],bytes32[],uint256[])","0481559b":"getLockDataFromMerkleTree(bytes,uint256)","04819507":"ICO_START4()","0481cb1b":"tokensAlreadyClaimed(bytes32,address)","048259e6":"UTCToken()","04830ddd":"getVotersAt(uint256,uint256,uint256)","0483a7f6":"lockedBalances(address)","0484c7cf":"AppSupply(address,uint256)","0485066e":"addReading(uint8,uint256,uint256)","04858fef":"StartQuiz(string,string)","048641be":"updateUserInvestBalance()","0486529b":"boardMemberApply(uint256)","04865327":"PlayerBet(address,uint256,uint256)","04869083":"auctionCreated(uint256,address,uint128,uint128,uint64)","0487b7e9":"Unity3d()","0487eed2":"restrictionsAllow(uint64,uint8)","0488781a":"teamOwnerOfPlayer(uint256)","0488dbfb":"getConfirmRefund(address,address,uint256)","048911a6":"createRandomZombie_ZOB_smallpack()","048926ac":"updateMaxPhase1(uint256)","04892c9f":"BASE_MIN_CONTRIBUTION()","048957d8":"sideBetPayToken(bytes32)","048986ae":"activityCore()","0489882e":"totalAdminsMapping()","0489fa70":"removePermittedContracts(address[])","048a5fed":"getSelfBalance()","048ae1bb":"addAssetPartOwner(bytes32,address)","048b0bcc":"addCustomerNReqACC(address,address,address)","048b3918":"messageNumber()","048bbc72":"CIR_SUPPLY()","048c35ca":"debug_is_recipient()","048ca698":"trackTotalVolume(address,uint256,uint256)","048cb8e0":"CarlosMatos()","048cc4a2":"BurnToken(address,address,uint256)","048cf8ed":"serviceDecreaseBalance(address,uint256)","048de56d":"setName(bytes2)","048dec38":"changeMarketingAddress(address)","048e2e94":"getAccountSize(address,uint256)","048e8c3a":"FidgetSpinner(uint256,uint256)","048e927b":"Checked(string,bool,uint256,bool,uint256)","048eb854":"_sortTopQuestions()","048f06f2":"setRoot(uint256,bytes32)","04903592":"withdrawAirdropTokens()","04904105":"setMiniPoolEdit_9(string)","0490540b":"Parameterizer(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","0490c71c":"unclaimedDividends(address)","0491eda0":"isCertainProduct(uint256,address,uint256,uint256,uint256,bool)","0492600e":"Issue(address,address,uint256,string)","04937cf9":"DoremiXToken()","0494630f":"oraclize_query(uint256,string,string[4],uint256)","04950f45":"KWHForGas()","049540c5":"structurePreIco(uint256)","0495cad9":"motionPasses(uint256)","0496e9ae":"triggerRequireError()","0496ee77":"checkPosition(address,uint256)","049766a8":"CleariumToken()","049878f3":"join(uint256)","04990162":"newChain(address[])","04994883":"ustAddress()","049948b0":"getMyGrapes()","0499ed13":"TOKEN_PRICE_WEI()","049a2dd1":"claimPartnerTokens()","049abf89":"queryUserContractCount(address)","049ae734":"scheduleCall(address,bytes4,uint256,uint256,uint8)","049b7852":"getElevations()","049c9bf2":"addExchangeAccount(address)","049cac16":"tokensUnvested()","049cc8b1":"soldForSecond()","049e63ee":"defaultClaimPercentage()","049eb289":"submitBuyOrder(bytes32,uint256,uint256)","049efcc7":"startReleasing()","049fb520":"countTickets()","04a077a4":"MyPasswordHint()","04a0c67e":"EagorNetwork()","04a1c63c":"token_a_amount()","04a1eb6b":"lastBlock_f16Hash_uint256()","04a23be0":"isAddressInWhiteList(string,address)","04a2b2c2":"testOwnerCanBreach()","04a2eaa5":"getTimeBonusPercent(uint256)","04a3693c":"applyFee(address,uint256,uint256)","04a373cc":"s20(bytes1)","04a3c21f":"maybeNewRound()","04a3ddd2":"_addToValueHeld(address,uint256)","04a48c27":"setActivityCoreAddress(address,address)","04a4a0d4":"getPriceMoney()","04a4a0ec":"TOTAL_XB_TOKEN_FOR_PRE_SALE()","04a4b776":"updateOpeningTime(uint256)","04a5288a":"stepcode()","04a6021d":"getByTypeNameVersion(string,string,string)","04a7137e":"controlledMint(address,uint256)","04a782ee":"addRecordByAdmin(bytes32,address,address,string,string)","04a79e9a":"spendDeposit(address,address,uint256)","04a7ca0e":"BonusUpdated(uint256)","04a7ff18":"totalNum()","04a82adf":"privateReservedUFT()","04a84938":"avaliableSupply()","04ac3b80":"addReceivedTrade(address,bytes32)","04ac75b0":"withdrawMulti(uint256,address[])","04aca4bc":"getClout(address)","04af7a20":"setDividendAndPayOut(uint32,uint32,uint32)","04afd2ce":"Multisended(uint256,address)","04b02ed6":"times_()","04b07a5e":"removeUpdater(address)","04b1142c":"getGuessCount(address)","04b1af75":"buy20()","04b1c6f0":"ICO_CAP()","04b2bf99":"stateControl()","04b370ab":"icoOver4()","04b43c5a":"withdrawZOB(uint256)","04b47e21":"isSignedWithEnc(uint16)","04b4e7e5":"awardsReservations()","04b5723d":"disableNewStakes()","04b5b5b6":"pointToToken(uint256,address,uint256)","04b64260":"tmpShuffleSeed(uint256,uint256)","04b65e74":"checkSTAGE()","04b69fa0":"jockeyNotForSale(uint256)","04b6ae61":"failedVotingCount()","04b6d39e":"_transferCroupier(address)","04b70576":"resetAgent(address)","04b7dcde":"hashData(string)","04b8ca98":"MAYTotalSupply()","04b92b7d":"overdraftAllocation()","04b94ec5":"MyToken30(uint256,string,string)","04bb1e3d":"updateActive(uint256,bool)","04bb754c":"TradeFinancing()","04bb89d5":"saveNick(string)","04bbc255":"isPricingStrategy()","04bd05d5":"getPeriodicalPnL()","04bd85f0":"getCapTab(uint256)","04be2f50":"isInvalid()","04bf1ee2":"JtoA(uint256[3])","04bf2a7f":"getScriptExecutor(bytes)","04c07569":"getBlock(uint256)","04c08fbd":"borrowFunds(uint256)","04c181f5":"beneficiars(address)","04c2a0ae":"DonateToLosers()","04c2a4a0":"computeKeyConstant(uint256)","04c313f4":"setAirdropGameInterface(address)","04c49f2c":"setFeePeriodDuration(uint256)","04c64e25":"revealMyVote(address,bytes32,bytes32,uint256,uint256)","04c6a9c5":"startIcoForOptionsHolders()","04c6ff7c":"devTeamTokenAddress()","04c76899":"sellerApprove(uint256,bytes)","04c76af0":"withdrawAdmin()","04c80c3c":"TOKEN_HODL_6M()","04c8384d":"trivialThreshold()","04c97ada":"setThirdRoundPricing(uint256)","04c98a2a":"validatePurchase()","04c98b2b":"startPresale()","04ca2775":"saleActive(uint256)","04caa6dd":"pauseReason()","04cb17ad":"returnPeriodExpired()","04cbc791":"getSellerOption()","04cc734b":"VoxelTransferred(address,uint8,uint8,uint8)","04ccf60e":"WrapperLockEth(string,string,uint256,address)","04cd1819":"disableVoting()","04cd5294":"getRefundAmount(uint256)","04ce1a61":"tokensWithdrawal(address,uint256)","04cf447d":"estimatesellvalue(uint256)","04d092c7":"claimPoints()","04d0a647":"getWallet(address)","04d0ac48":"tokensPending()","04d0c98a":"distribute10MTI(address[])","04d0fefe":"HoneyPot()","04d10f1c":"isValidChainyJson(string)","04d16482":"strConcat4(string,string,string,string)","04d1809c":"validateJoinSplit()","04d1b108":"_computeOwnerCut(uint128)","04d2cdbf":"setAcceptable(address)","04d2dec6":"getWalletAddress()","04d332a2":"setRefereeRewards(uint256[])","04d41474":"totalNormalContributorIdsAllocated()","04d58b3f":"MrwToken()","04d5c2c5":"toEGR(uint256)","04d6878f":"closeMicroWallet(uint256)","04d69a11":"SoldToken(address,uint256,bytes32)","04d6db05":"startSale(address,uint256,uint256,uint256,uint256)","04d742dc":"startSale(uint256,uint256,uint256)","04d84108":"SWAP()","04d88bce":"DDJETH()","04d91c6a":"testFail()","04dbd2d3":"LogInvestorProfit(address,uint256)","04dcad85":"testDifferentTokenPrice()","04dcc44a":"getTip(address,bytes32)","04dd2dea":"getCardDivShare(uint256)","04dd69fa":"getGenerationIdForCall(address)","04de40ea":"AnnoToken()","04de76cf":"VisualChain()","04deaeb5":"retrieveEth(uint256,address)","04dee65f":"contractBatchTransfer(address[],uint256[])","04def102":"getRemainReleaseTimeOfStage(address,uint256)","04df0a1d":"kudosByMember()","04df48ef":"ICO_LEVEL_4()","04dfe14e":"LandmarkCoinTestF()","04e15de5":"issues(uint256)","04e1805a":"setFreezeForAngel(uint256,address,uint256)","04e1826c":"getNumTransactions(address,address,uint256)","04e262b8":"wlStartBlock()","04e5a069":"registerUBetCheck(address,string,string,string,string,string,uint256,string,string,int256,uint256)","04e639b6":"fetchSlot(uint256,uint256)","04e6a9a1":"teamLock(address,uint256)","04e6adf8":"serHoldTime(address,address,uint256)","04e75fda":"Contribution(uint256,address)","04e78a30":"stakingMintAmount()","04e7dfcf":"getAssetRaised(address)","04e80e90":"getMasterCopy()","04e86e15":"calctime(uint256)","04e88f2d":"SayaToken(uint256)","04e98568":"withdrawBalanceCut(uint256)","04ea23bf":"FLUXBlockToken()","04ea4a57":"getDisputedPayoutDistributionHash()","04eab1e1":"gvpe_per_Keos()","04eb7d83":"setFirstPeriodEndDate(uint256)","04ebb1d9":"commonWithdraw(address,address,uint256,uint256)","04ebfc52":"userCount_()","04ec70a7":"determineAttackingOrDefendingOutcomeForAttributes(uint256,uint256,uint256,uint256,uint256)","04ecdaac":"rateSecondRound()","04ed02f6":"getCards(uint256)","04ed3f6a":"canStartSale2()","04ed6fbc":"minCDTToParticipate()","04edad4d":"YouLose(address,uint256)","04ee54d2":"revokeInitiator(address)","04ee9748":"storeWinnerShare()","04ef1353":"setTokenWithoutFee(address,bool)","04ef161b":"findSeed(address)","04efa227":"feeMakeExporter()","04f016c9":"transferMulti(address[],uint256)","04f03b6a":"getSomeVar()","04f041b5":"BtcEthRateChange(uint256)","04f05f91":"joltToken()","04f08b55":"getPolicy(uint8)","04f08eec":"PayEth(address,uint256)","04f0aa4e":"setServiceAgent(address)","04f13e40":"HashLand()","04f14090":"setBlacklist(address,bool,string)","04f17b11":"PriceChanged(uint256,address)","04f182f4":"icoPhase1End()","04f1e4e2":"tradeEtherDelta(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,bool)","04f24897":"PlanetagroExchange(address)","04f30b37":"getFutureTransIdxByAddress(address)","04f31a47":"confirmICOSpec()","04f342f6":"_addToAging(address,address,uint256,uint256)","04f3bcec":"resolver()","04f49a3a":"addressStorage(bytes32)","04f4d425":"toEthFunction()","04f4f7ab":"KYRO()","04f5222c":"setEthMinContribution(uint256)","04f53231":"SendEth()","04f65288":"AK47Coin()","04f65590":"preSaleWeiRaised()","04f68d49":"dataSourceGetFinals()","04f6aa30":"forwardETHtoSTCcontract(uint256)","04f74b59":"make(address[],uint256[],address,bool)","04f7a69d":"baseSummonPrice()","04f7e87c":"issueBounty(address,uint256)","04f80977":"setBattleContract(address,address)","04f88d71":"testFailHardLimit()","04f8aa9b":"IoTeXNetwork(uint256)","04f92405":"icoTokensLeft()","04f9d030":"test_interface_call()","04fad28d":"instanceId()","04fb82cc":"_deliverTokens(address,uint256,uint256,uint256,address)","04fb9e81":"closeRequested()","04fc11d5":"getActual()","04fc7c6d":"updateJoinedCrowdsalesMultiple(address[])","04fcadf1":"totalZTHWagered()","04fd295c":"WOLF2()","04fd9f78":"variationsOfOwner(address)","04fda0d8":"_trade(address,uint256,address,uint256,address,uint256,bytes32)","04fe947c":"mapToNewRange(uint256,uint256,uint256)","04ffb5b9":"registerToken(address,string,string,uint256)","05009f0a":"_createBid(address,uint256,address,bytes32,bytes32,uint256,uint256)","0500de3e":"interestResolution(uint8,uint8,uint8,bool)","0500fe3e":"getRegionCurrentPixelPrice(uint256)","05010105":"stakeRequired()","05015e79":"coldAdmin()","05018d91":"objectPants()","0501b79f":"getBlocktime()","0501d556":"setEmergency(bool)","05021ce9":"_trade(address,uint256,address,uint256,address,uint256)","050225ea":"giveaway(address,uint256)","05026317":"bitcoinSaleRate()","0502ca6b":"addTime(uint256)","050394ec":"minGasPriceForDrawing()","0503a3bb":"transferCharity(address)","050414bb":"addWhitelist(address[],uint256[])","0505140c":"totalSupplyWithDecimals()","05062247":"blocknumber()","050642f2":"exchangeTokenRate()","0506689a":"omegaPerEther()","050895ff":"backEndOperator()","0508ed90":"contribute(uint256,address,address,uint256)","050906ea":"_computeDamage(uint256,uint256,uint8)","050a2eb4":"diceRollAddress()","050a3250":"ArithLib()","050b8c66":"drainStrayTokens(address,uint256)","050c09ee":"founderWithdraw(uint256)","050c0fd6":"AmmbrToken()","050c8803":"getAmountFida(uint256)","050c931d":"paymentNumber()","050d6a15":"setSellPrice()","050df9f7":"PoolJoined(uint8,address,uint256,uint256)","050e25a0":"getHash(address,uint256,address,uint256,uint256,uint256)","050eb8c0":"BuyableCourt(address[],uint256[])","050f2f3e":"updateBools(bytes32[],bool[])","051064c6":"lighthouseFee()","051097ef":"addProposal(uint256,string)","0510e186":"getSncTokenAddress()","05111c1e":"getItemHolder(uint256)","05117619":"endVesting(address,address,address,address)","05117e0d":"validateTokenPurchase(address,int256[],int256[])","0511a431":"addOns(uint16)","05120ba6":"getTokensReleased()","05128716":"sale(string)","0513fc8b":"onBurn(uint256)","0514be3b":"ownedTemplates()","0514c275":"REALPlaceHolder(address,address,address)","05160860":"initialDayWithdrawCount(uint256)","0516af06":"getMonsterId(uint256)","0516c9f0":"frozenToken(address,uint256)","0517431e":"_teamSupply()","05175786":"announceWinnerManually(uint256)","051847d5":"childTokenByIndex(address,uint256,uint256)","0518afdc":"tokenToReward(uint256)","0519b873":"heroLottery()","0519bb83":"getVoteStatus(uint256)","0519ce79":"cfoAddress()","051a2664":"nameOf(uint256)","051a65dd":"deal_cancel_rate()","051a86cc":"mintApprove(uint256,int256)","051b044f":"_sell(uint256,address)","051b4e6c":"getSurveyInfo(bytes32)","051ba270":"getLogCancelArguments()","051c4ab6":"AddPlayer(uint8,address)","051cb630":"mintRandomCards(address,uint8,uint8)","051d9955":"confirmCustodianChangeProxy(bytes32)","051e5c45":"fiatPerEth()","051f4f6f":"transferAll()","05204231":"setPermission(address,address,uint8)","0520ed4a":"LYT(uint256,string,string)","05215b2f":"createStandardToken(uint256)","0522345a":"blackListFreezeTime()","052369a6":"submitLocation(uint256,uint8)","052534e7":"VerificationEvent(address,address,uint32)","0525ca77":"packParams(address,uint16,uint32)","0526179e":"getSoilTempControlLimits(bytes32)","05261aea":"finalize(uint256)","0527da64":"_openGamePlayNos(uint256[])","0528bb57":"isSubscriptionProduct(uint256)","05297781":"MintToken(uint256)","05298d37":"setWhiteListERC20(address)","0529be17":"circulateTokensForSale(uint256)","0529de04":"getCertificateExpires()","052a076f":"disablePresale(bool)","052a6849":"tokenStartPrice()","052a829c":"notSoldTokens()","052ab49c":"bytesToUint1(bytes)","052b2aa7":"getRegistrants()","052b81c7":"releaseBadges()","052ca699":"end_()","052d5707":"JYToken()","052d9e7e":"setWhitelistEnabled(bool)","052deec5":"investorsIter(uint256)","052f1a7a":"BGXToken()","052f7d11":"freezeAccountSend(address,bool)","053011b7":"authenticate(uint256,uint256,uint256)","0530abf0":"SwingTradeToken()","0533073c":"publishingOwner()","0533f57b":"RAISED_AMOUNT()","0534ab04":"setCapsMerkleRoot(bytes32)","0535020d":"payTokens(uint256)","05354bed":"etherPricesAreClose(uint256,uint256)","0535ec77":"initialDistributionDone()","05365bb0":"presale1()","0537665d":"setOutcome()","053902f6":"DTCC_ILOW_4()","0539272a":"startDay()","05398302":"destroyFrom(address)","05398d45":"setNewMiner(address)","0539c6d6":"num_squares()","0539eba9":"setAllowBuying(bool)","053abd3c":"createShareToken(uint8)","053ae2ca":"getHairColorValue(uint256)","053b8d2f":"deleteBackgroundImage(uint256)","053c351b":"oraclize_getPrice(string)","053c5d59":"e_Purchase(address,uint256)","053db3a9":"testSetPresaleTokens()","053e3169":"openSaleStartTime()","053e3253":"window3EndTime()","053e71a6":"getTotalNumberOfTokensForWinningOption(uint256)","053f14da":"lastPrice()","053f598a":"policyActiveNum()","053f7492":"minimumPriceInDailyAuction()","05401284":"debundle(uint256,address,address)","0541b0f8":"acceptPayment(bytes8)","0542b61b":"snt_claimed()","05433a26":"GetNumbersFromHash(bytes)","054348d6":"icoIsOver()","0544587f":"getCRYPTON_CUT()","054550f3":"assertEq8(bytes8,bytes8,bytes32)","05459f42":"WeeklyLotteryB(address)","0545a03b":"getGroupManagement(uint256)","0545f8ba":"changeExchangeAdmin(address)","05468c26":"addToBond(address,uint256)","0546a746":"restrictedTokensOf(address)","054726cb":"MNTOKEN()","0547bf4d":"DEFROST_MONTHLY_PERCENT_OWNER()","054909aa":"_addNewOwnerHoldingsToToken(address,uint256,uint256)","0549f150":"getAdministrator(address)","054a8c02":"getGirl(uint256)","054a9f11":"shopGloves()","054ba658":"delete_key(uint256,uint256)","054baaf2":"jan()","054be0b7":"setIssuanceRatio(uint256)","054c3c71":"getBetsOnTimestamp(uint256)","054d2a7e":"ChuCunLingAIGO(uint256,string,uint8,string)","054dcbb5":"AdvisorsTokensHolder(address,address,address)","054ded2b":"registrazione_candidato(string)","054e9507":"lastEventId()","054f268e":"getDCategoriesN(bytes32)","054f381b":"entrepreneur()","054f7d9c":"frozen()","054fce82":"ZipperWithdrawalRight(address)","05502a62":"BONUS_PRESALE()","0550f92f":"setMintAddress(int256,address)","05514a3e":"winBonusArray(uint256)","05529d94":"addMultipleParticipants(address[])","0552ce3e":"MonthToken()","05533ce1":"setSettings(address,uint256)","0553b805":"transferStorage(address)","0553e156":"finalize(address,uint256)","0553fd5b":"incSupply(uint256)","05540534":"setMultisigAddress(address)","0554bb48":"depositToLock(bytes32)","0556369e":"tokenToReserve()","055680f0":"purchaseCounter()","0556a66f":"deliverPresale(address,uint256)","0556fcd0":"setIcoFinish(uint256)","0557b2b0":"getApprovedTransfer(uint256)","0557df99":"FundingRulesSet(address,uint256,uint256,uint256,uint256)","0558171d":"maxCharId()","05597d88":"setOwnerCut(uint8)","0559c114":"removeSellOrder(uint256)","055a7341":"USEAddr()","055ad42e":"currentPhase()","055bb725":"_approveForSale(address,address,uint256)","055c7c96":"sliceBytes32Arr(bytes32[],bytes32,uint256,uint256)","055cbb3d":"CalculatePayout(bytes32,uint256,uint256,uint8)","055cdee1":"UpdateBetOnTeams(string,address,uint256)","055cff88":"AlarmxToken()","055e0e07":"Bela()","055e6d8b":"playGameCheckBid(uint256)","055ee253":"claim_reward()","0560ff44":"tokenMetadata(uint256,string)","056129a6":"TravelShare()","0561d562":"GoldiamToken()","0561eff6":"addStoneToBoard(uint256,uint8,uint8)","0561fc18":"ICOResumed(uint256,uint256,uint256,uint256)","056265d1":"storeData(bytes32[],bytes32[],bytes32[],bytes32[])","05626694":"LABEEToken(uint256,string,string)","05626f09":"timeFundingStart(uint256)","0562b9f7":"withdrawAmount(uint256)","0563324c":"executeOrder(bytes32,uint256,address)","0563451a":"icoEnd()","056362e8":"Crowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address)","0563bbf6":"USDEtherPrice()","0563d55e":"MomaSpace()","0564a9a7":"getPollResults()","0564df4a":"_addBattleSequence(uint8,uint8,uint256)","0565ac43":"get_bonus(uint256)","0565c3f4":"pushAngelInvestmentData(address,address,uint256)","05664cea":"getRevisionTimestamp(bytes32,uint256)","0566bc12":"getDebrisPrice(bytes32,uint8)","0566c02a":"discountedSaleDuration()","0566c979":"iCashToken()","05674427":"numToString(uint256)","0567e83e":"kill(address,address)","05681031":"_sendBack()","056841b0":"InsertManifesto(string,string)","056a6421":"activateInvoiced(address)","056ab62a":"TestPool(address[3])","056b01ce":"mint(string,uint256)","056b2300":"TxUserWallet()","056b8197":"tokensInVault()","056ba056":"trade(address)","056bef9e":"addRequester(address,string)","056cf6bf":"Witness()","056e1059":"oraclize_query(uint256,string,string,uint256)","056e25e3":"returnIcoInvestments(uint256)","056e4d88":"TotalInvested()","056e81a6":"TokenBooksAirdrop()","056ed205":"EstateTransactions(string,string,string,address,int256)","057101b1":"Token(uint256,string,string,string,uint8)","0571d85f":"Forwarded(address,address,uint256)","05733989":"setAttribute(address,string,bytes,uint256)","057466ea":"buyToken(uint256,uint256)","05748be2":"dropAmount()","05763ff7":"pauseProposer()","0576cb6f":"verifyTargetWallet()","05777d9b":"ReturnToken(uint256)","0577f15c":"exchangesStatus()","0577f62f":"PRE_MAX_CAP()","05785e4c":"minimumBuy()","05788701":"Ribble()","0578e3e5":"isAtMost(uint256,uint256)","0578f356":"addManagedInvestmentProposal(uint32,bytes24,uint256,uint152)","0579d25d":"price(uint256[],uint256[])","057af1c4":"exist(string)","057b0416":"getAccDetails(address,address)","057b17c0":"timeMode()","057b7105":"calculateTokenAmountICO(uint256)","057bd53f":"sameVar()","057bfcc7":"amount2()","057c3cf5":"get_flag()","057d2c17":"Jack()","057dd42d":"purchaseCompanyCard(uint256)","058026d0":"checkTransferToICAPWithReference(bytes32,uint256,string)","058029a2":"icoCoinCap()","0580d5c7":"massBurnTokens(address[],uint256[])","0581345e":"issueClaimOwnership(address)","058206d9":"ICBCCoin()","05831c62":"donateFor(address)","05839b29":"sortTopTen()","0583ae52":"IRCToken()","05860b6f":"getBidIndex(address,bytes32)","058618f8":"setAuthorizeMintToken(uint256,int256)","05862435":"testFloatKeyValue()","05862611":"CrowdsaleLimit(uint256,uint256)","0587c1ba":"requestTokensFromOtherContract(address,address,address,uint256)","05888fcd":"tradeBalances(address,uint256,address,uint256,address,uint256)","058a628f":"setAuthorizer(address)","058aace1":"divest()","058ab8c9":"EthVerifyCore()","058af982":"nameIsAdvocate(address,address)","058b316c":"MANAGEMENT_KEY()","058c5103":"safeKill()","058d4dd0":"setAssetCooldown(uint256,uint256,uint64)","058d7433":"setAlliesContract(address)","058fa067":"setGasRefundForClaimLootWithConsolationPrize(uint256)","058fcde9":"testFailTransferFrom()","058fe7d9":"setMiningRate(address,uint256)","05910b91":"canBreed(uint40)","05915147":"authType()","05917369":"populateFromOldContract(uint256[])","05917e8d":"updateWhitelistAddresses(address[],uint8)","0591eb24":"promoCreated()","059275ab":"howManyTokensForEther(uint256)","0593d244":"setSaleContract(address)","05940728":"setGGCFee(uint8)","059417da":"_getAllParentIds(bytes32)","05943a15":"TEAM_SHARE()","0595ba4c":"getRoundMinAmountByBet(uint256)","0596334f":"rewardOne()","0596bd84":"_ChallengeFailed(uint256)","05976587":"test_expiry_increaseTimeBy30000()","05978450":"tokensReleasedAdvisorsTeam()","0597f3aa":"setGasRefundForClaimConsolationPrizeLoot(uint256)","05989e9d":"getAward(uint256)","05991e56":"Freewatch(uint256,string,uint8,string)","0599c284":"setAddress(string)","059a500c":"makeDeposit(uint256)","059a7d93":"cardEmojified(uint8)","059b8140":"upgradeAllowance(address,address,uint256)","059b8c77":"computeGainsRate(address)","059c00be":"STL(uint256,string,string)","059c5c4f":"policyFeeCollector()","059caad3":"creatorSupply()","059ce95d":"getVerifier(address)","059d45da":"removeAllPVPContenders()","059d92dc":"FeefersToken()","059eb515":"crowdsaleSold()","059efd9e":"_getShipColor(uint256)","059f8b16":"MULTIPLIER()","05a0c707":"setMintAgent(address,int256)","05a10028":"burn(uint256,uint256,uint256)","05a10e6d":"withdrawStakeTokens(uint256,address)","05a17fc6":"getAccountFeed(address,uint256,uint256,uint256)","05a308fa":"setReferralSignupTokens(uint256)","05a30a7a":"lastDepositDate()","05a3823b":"colorplat()","05a3e81a":"ratePerWeiSecondPhase()","05a44292":"Train(uint64,uint64,uint64)","05a506b0":"seEnableTransfer(bool)","05a5b8c6":"verifyTx(bytes,int256,int256[],int256,bytes,int256,int256[],int256)","05a5f830":"signedApproveAndCallHash(address,address,uint256,bytes,uint256,uint256)","05a873dc":"setMetadataSize(uint256)","05a8bf98":"SEXYKITTEN(uint256,string,string)","05a955af":"holderList(address)","05a95f04":"triggerPayout()","05a9cec2":"BetOnMe()","05a9f274":"totalLockedAmount()","05aaee1f":"unlockTimeStamp()","05ab421d":"sendTokens(address,uint256)","05ac7908":"TakeBackToken(uint256)","05ace573":"commitPhaseMinSeconds()","05ae6bcc":"userPublicFundingEthCountMap(address)","05aeb1e1":"RDMGameToken()","05aebead":"plantationSize()","05aecc80":"IAmVeryPoorToken()","05af0194":"getUserQuickPromoBonus(address)","05af2a81":"AddrDevelopFunds()","05af636b":"PunkTransfer(address,address,uint256)","05afff5b":"isHandleValid(bytes32)","05b0876d":"mgrAddress(uint256)","05b09e07":"getGameNumber(address,uint256)","05b1137b":"transferEther(address,uint256)","05b2b03a":"CertificationCentre(address)","05b34410":"creationDate()","05b35924":"totalLuxCents()","05b3dcb9":"roomFree()","05b4655a":"withdrawlWinnings()","05b496bb":"penalizeSolutionSubmitter(uint256,uint256)","05b4fe5f":"DepositFrozen(address,uint256)","05b542d9":"startPortalGun()","05b5711d":"level_3_amount()","05b575a5":"addWhitelister(address,address)","05b5b0dc":"submitSolution(uint8[])","05b5da23":"setPlayerTokenAddress(address)","05b64993":"setRequestCancellationMinimumTime(uint32)","05b67c8e":"BitGuildCrowdsale(uint256,uint256,address,address,address)","05b6d298":"assertEq0(string,string)","05b6d9e2":"distributeeBitcoinCashLarge(address[])","05b74d87":"inPrivatePreSalePeriod()","05b765ea":"getCertifierStatus(address)","05b8b29e":"profitOwner()","05b95822":"enableFundingWallets(address)","05b961e6":"PayWinner(address)","05b9cb3c":"totalDelegations()","05ba2ded":"voteForCashBackInPercentOfWeight(uint256)","05bbf5db":"startDocumentPoll(uint8,bytes32)","05bc99f8":"eth_sent(address)","05bccd09":"EGGCOIN()","05bdd57b":"AVMTestSuite()","05be478b":"calulateXticket(uint256,uint256,uint256)","05bf3bf0":"FtechizTestToken()","05bf4ecc":"batchPopularitySetting(uint256[],uint8[])","05bf779f":"setFoundation(address,address)","05bf9ece":"ICOSuspended()","05c06367":"RequestDetachment(uint256)","05c06db9":"majorPartnerAddress()","05c080be":"getTotalF6()","05c091f6":"_setCEO(address)","05c0dd91":"DEPOSIT_WINDOW()","05c0e497":"CDcurrency()","05c1f502":"post()","05c1f5ff":"getWhiteListStatus(address,address)","05c24481":"reserveSlash(bytes32)","05c270e2":"getPreviousBlockNumber(uint256,uint256)","05c31491":"test_oneTrueAssertNoMessage()","05c35eb6":"MICE(uint256,string,string)","05c3cb8d":"changegp(address)","05c4af9d":"getProto(uint16)","05c4b3dc":"Snydertoken()","05c54cd6":"MUNIRAHAMID()","05c7603d":"updateGenGuVault(uint256)","05c78929":"thirdWeekTokenPrice()","05c7cd4b":"confirmAndForwardWithRevert(address,uint256,bytes,bytes32,uint256,uint8,bytes32,bytes32)","05c7f589":"BACS()","05c85c42":"icoTimeStart()","05c8a4e2":"FeuzingToken()","05ca11cf":"TIM5(uint256,string,uint8,string)","05ca3557":"makeAdoptionOffer(bytes5,uint256)","05ca3841":"getOraclizeAddr()","05caca6c":"transferOwnershipServer(address)","05cb177a":"referralPay(uint256)","05cb71d4":"firstLoos()","05cc49dd":"distributeFee(uint256)","05cc72e3":"FilmscoinToken()","05ccfddd":"invalidateCombat(uint256)","05cd4794":"ExEquity()","05ce55fc":"channelDisputeResolver(uint64)","05cf5fcd":"mediationExpiry()","05d0f15b":"tokenPriceWei()","05d1127f":"changeChanceToWinModule(uint256)","05d1afec":"ausGroup()","05d1fc5d":"AIRDROP_MAX()","05d2035b":"mintingFinished()","05d258dd":"getMixingResult(uint256,uint256)","05d26bc6":"feedme(uint256)","05d2f3e2":"ErrorReport(address,uint256,uint256)","05d2f92a":"check_depth(address,uint256)","05d35816":"ConstitutionalDNA()","05d430db":"isNameValid(string)","05d4665f":"CROWDSALE_TOKENS()","05d473da":"assinaPresenca()","05d52eeb":"OMPxContract()","05d53802":"setPreSaleTokens(uint256)","05d55093":"oraclizeRequests(bytes32)","05d56a4e":"GetDChainNumRevokableHashes(bytes32)","05d57a59":"destroy_time()","05d6671c":"m_txs()","05d67464":"getTether(address,uint256)","05d74066":"SendPreReserved5()","05d7649f":"sendPortion(uint256,address)","05d78739":"cratesMigrated(address)","05d85eda":"count(address)","05d861fa":"CommunityAdVoucher()","05d866cd":"MemberChanged(address,address)","05d87fe2":"issueLetterOfCredit(uint256,uint256,uint256)","05d8bb97":"additionalDebt()","05d8c792":"_buyHicsTokens(address,uint256)","05d9a5fb":"sgn2sga(uint256,uint256)","05dabbcd":"lockedHasEnd()","05dad1c0":"test_userSetup()","05dae1f9":"ChargeStation(address,uint256)","05db3b82":"minwei()","05dc2708":"getCardNumber()","05dd071c":"_initialTransfers(address,address[],uint256[])","05dd23f7":"_stringGas(string)","05dd686f":"MIN_TOTAL_AMOUNT_TO_RECEIVE_ETH()","05dd7303":"EthereumStack()","05ddd49f":"Rotharium()","05de4f07":"getContentParent(uint256)","05de6288":"WithdrawalDone(address,uint256,uint256)","05df5e86":"XPAToken()","05df75db":"foobar()","05dfedac":"incrementDate()","05e1bd8c":"calculateInterest(uint256,uint256,uint256)","05e1c942":"reclaimTokens(address[])","05e206f0":"_registerBid(uint32,uint256)","05e24a93":"DISTRIBUTED_STATUS()","05e2b66a":"update_eth_ratio(uint256)","05e2eee0":"getArrayString(bytes32)","05e33b6e":"calculateMask(uint256,uint256)","05e33dd0":"allParticipants(uint256)","05e43263":"AzwieToken(address)","05e437b5":"setAllSteps(uint256,uint256,uint256)","05e4438a":"applyHotFix(address)","05e4545d":"nextActionIsAuthorised()","05e45546":"promoCreatedCount()","05e49d1d":"findWinner(uint256)","05e4a75c":"setupairdrop(address,address)","05e52ea0":"numberOfBasesSold(uint256)","05e53535":"operationTokenCreated()","05e57cb1":"CommitGoodToken()","05e633e2":"bonusEnds3()","05e6b4a4":"_emitHolderAddressRemoved(bytes32,address,uint256)","05e6ee11":"btcInvestment(address,uint256,uint256,string,uint256)","05e7781e":"changeReserveWallet(address)","05e87e2a":"tracetoMultiSigContract()","05e88b69":"production()","05e992ff":"BitcoinDeuce(string,string,uint8,uint256)","05eb1877":"projectBuget(address)","05ecc085":"snapshotAt(uint256)","05ed2cd3":"settleBBDBatch(address[],int256[],uint256)","05ed76c4":"resolveTime()","05ee27a6":"RavneetToken()","05ee72b5":"playerEndGameConflictImpl(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address)","05ee8d89":"investorMinimalBalance()","05eed946":"waracoin_per_ether()","05ef6848":"getTokenPods(address)","05f04e46":"writePublicRecord(bytes32,bytes32,string,uint8,bytes32,bytes32)","05f0f662":"ComputeMyEggs()","05f203d9":"revoke(address[])","05f29b89":"smartSpeedEarning()","05f36283":"Nitrogen()","05f3a852":"tkn()","05f43bba":"calculatePreTokenAmount(uint256)","05f53b29":"getSkillCount()","05f5c0f3":"FrozenFunds(address,uint256,uint256,uint256,uint256,uint256)","05f6237f":"canClaimRefund()","05f671d9":"UUSD()","05f6d329":"limitTokenForSale()","05f766a4":"Spc(uint256,string,string)","05f8002a":"setts01(uint256,address)","05f8b0cf":"setERCContract(address)","05f8b6f5":"_rewireIdentities(bytes32[],uint256,uint256,uint32)","05f8d55d":"addOwnerBalance()","05f908e6":"ICOPERIOD()","05f9bb6b":"transfersEnabledFlag()","05f9bf10":"AuctionCreated(uint256,address,uint256,uint256,uint256)","05fa0d5f":"_createTileAt(int32,int32)","05fc0586":"buyOptions(address,uint256,string)","05fcd234":"batchTransfer(address[],uint256,uint256[])","05fd22d0":"isPopulous(address)","05fe035f":"right100(uint256)","05feb950":"SOVREN()","05fec4be":"transferAdvisorToken(address,uint256)","05fefda7":"setPrices(uint256,uint256)","05ff088c":"getVendingInfo(uint256)","05ff711b":"blackList(uint32)","05ff792e":"cancelEscape(uint32,int256)","06005754":"nameRegAddress()","0600a865":"totalWithdrawable()","0600b814":"tokenBonusPct(uint256)","06011b14":"getUnitInfo(uint256,uint256,uint256)","06021e7e":"finalizeWork(address,string,string,string)","06024287":"attemptSomeMethod(address,uint256)","06026d87":"addAddressesToBonuslist(address[])","06027876":"sendBountyProgramBalance(address,uint256)","06040618":"currentPeriod()","0604c594":"getFreeBalances(address)","0605062f":"ownerOf()","0605d0cd":"emitSkillSet(uint256,uint256,uint256,bytes32)","0607dd94":"submitChoose(uint256)","06087e5b":"setColdWallet(address)","0608a48a":"reactivate_trading()","06090738":"setAdultTime(uint256)","06096931":"bountySupplied()","0609b433":"amendRetention(uint8)","060a02b7":"_hasIcoContributorType(address)","060a1051":"isExistInWhiteList(address)","060a56dc":"publisherCut()","060b2128":"getEndPointOfCampaign(bytes32)","060ba7e9":"hackAdept(address)","060c265f":"checkMaxCap(address,uint256)","060c7f33":"AVAILABLE_FOR_EARLY_INVESTORS()","060cf4e8":"_cap()","060d15f9":"getBonusFactor(uint256,uint256,uint256)","060d206e":"modifyWhitelist(address,bool)","060d4f0d":"canDownload(address,address,bytes32)","060dac88":"setTokenBalance(address,address,uint256)","060eb520":"snt()","060f3102":"UbexToken()","060f400b":"removeFromOwnership(address)","060f58c3":"getUserFee(address)","060f919b":"getHash(address,bytes32)","060f99c4":"ZillaGDToken()","060ffb99":"getPromiseCount(address,bool)","0610e037":"isEnabled(bytes32)","0611037c":"QiiToken()","06114d36":"testChangeBet()","0611ae4a":"allocateBid(bytes32,uint256)","06122ea8":"createTokensAnySale()","061268d7":"requestFoundationTransfer(address,bytes32)","061303a7":"refundIsAvailable()","061307b0":"fixPlayerPrename(uint256,string)","06130ca6":"getTopicAtIndex(uint256)","06132b38":"_create(address,uint16,uint16,uint8)","06137c9d":"add_luck(bytes32)","0613c265":"getLockBalance(address,uint8)","0613d936":"setAttackAddress(address,address)","0614117a":"recoverETH()","06155e95":"EmployeeSignedToESOP(address)","0615b520":"isBurner(address,address)","0615f7c3":"setGasForPBTT(uint256)","0616558c":"CampaignRules(address)","06169f63":"setAirdropAgent(address,bool)","0616ae05":"GenerateChips(address,uint256,uint256,uint32[])","0616cca0":"currentMood()","06171a5d":"OpsAddressUpdated(address)","061777ed":"incrementOpenInterestFromMarket(uint256)","06177ba8":"getdepositValue()","06184a25":"monthlySubscriptionCost()","0618c0b0":"INACTIVITY()","0619978d":"raiseApprovalEvent(address,address,uint256)","061a85c7":"forwardedOracle()","061ab664":"receiverTwo()","061b3245":"withdrawToExchange(address,uint256)","061c8800":"setInt(bytes32,bytes32,int256)","061c9040":"getLockInfo(address,address)","061d5102":"LivingstonCoin()","061d8169":"_addResolvers(string,address[],uint256[])","061e494f":"getBet(uint256)","061e5844":"withdrawFor(address,uint256,uint256,uint8,bytes32,bytes32)","061e7845":"buyTokens(string,string,address,uint256)","061ea8cc":"countByOwner(address)","061f7650":"supportsToken(address)","06201ad9":"getPLATPrice()","0620b2af":"PenaQuantumLeapToken()","0621472c":"approveAll(address)","0621afe4":"Virgingold()","0621b4f6":"sellAllAmount(address,uint256,address,uint256)","06222be3":"buyIcoTokens(uint256)","06223dac":"getDRCTotal(uint256)","06228e95":"freeTransferItem(uint64,address)","0622e74b":"crowdsaleTokenPriceNumerator()","06232bb0":"openAgreement(bytes,uint8,bytes32,bytes32)","06237111":"_getFilteredBoxes(bool)","06237526":"serviceCount()","06240d7d":"getWeiInCents(uint256)","0624ac2c":"getOutcomeTokens(bytes32,uint8)","0625d365":"getRightCoordinate(bytes1)","06262f1b":"trust(address,bool)","0627586a":"splitterNames(address)","06279d72":"priceUnits()","06287693":"directDebitAllowance(address)","062907d5":"initiateVotingContractUpdateVote(string,address)","062af37d":"isVersionContract(address,bytes32)","062b01ce":"isPricingSane()","062bbe59":"setEditedTrue(address)","062d0f09":"timestep()","062d4a34":"addressAdvisoryBountyTeam()","062db578":"createtoken(string,string,string,string,string,string,address)","062e43a1":"withdrawalToken(address)","062e53f3":"intFunc(int256,int256,int256)","062fe08e":"TOKENS_AVAILABLE()","06301ce8":"delUnpausedWallet(address)","06309aa0":"SistanToken()","0630da28":"TokenDeskProxy(address,uint256)","0631a171":"DocumentAdded(uint256,string,uint256,string)","0632a2f3":"getBlockAddress(uint256,uint256)","0632f718":"RedditRegistry(bytes32,uint8,uint16)","0633cd32":"requestAddressChange(address)","06347def":"getCooldownEndTimeFromIndex(uint16)","063575de":"withinPeriod()","0635fe90":"playerLockedFunds(address)","0636d7ac":"getOrdersForSeller(address)","063925c8":"scheduleCall(bytes,uint256,uint256)","06394c9b":"changeOperator(address)","063a7400":"registerUserOnToken(address,address,uint256,uint256,string)","063b1566":"partyTo(address)","063b3b29":"getPlayerStatus(uint256,uint256)","063bac1f":"giveRightToVoteByBatch(address[])","063bde24":"MAX_VALUE()","063c67c2":"getMatchInfo()","063ca521":"setPossibleMobs(uint32[])","063cea26":"prenupAgreement()","063cfaf0":"getVestingReleaseRate(address,uint256)","063d93d8":"register(address,string,string,string)","063db820":"payFee(uint256,uint256,address,bool)","063dda8b":"preSaleBonus(uint256)","063e1b78":"setTradingTime(uint256[])","063e7451":"initialSupplyAddress()","063ec2f0":"MEDIA_SUPPORT_PERCENT()","063f4540":"LogBet(address,uint256,uint256,uint256)","06407746":"Grant(address,bool)","0640f885":"PAYCLECOIN()","0641d812":"accruedDiv(address)","064292a8":"updateDates(uint256,uint256,uint256,uint256,uint256,uint256)","06437e4f":"_getCards(uint8,address)","0643be3e":"transferFrom(uint256,uint256)","06444e91":"register(address,uint32)","06459119":"testThrowsTransferNotTransferable()","0645b5d5":"getMyShareholderID()","06463556":"validateFunction(bytes4)","064701c6":"buyChest(uint16)","06474d12":"tokenIdOf(uint256)","06477332":"getMemberAtIndex(address,uint256)","0647b106":"Store(address,uint256,uint256,bytes32)","0647f697":"Uint256Oracle(uint256)","06490f47":"lockup()","064aa0e3":"ATMToken(uint256)","064af4ee":"setCoreContractAddress(address,address)","064c4ebc":"backDevvoteOwner()","064cc7a7":"delegatesByDelegator(address)","064cd77f":"changeFreezeDate(uint256)","064cfc16":"checkIsOpen()","064d4d7c":"_minAmount()","064da5e7":"getBAAU(bytes32,address,address)","064da642":"TransferSellAgentMulti(address[],uint256)","064dcb17":"sellTokens(uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","064ddd04":"getItemsForSale()","064f4fa7":"rateAge()","064f5dcd":"decentralizedEconomy()","064f67e7":"LockRemoved(address)","064fe208":"IxiniumFundingCoin()","06502ac0":"setMemberShip(address,uint256)","06504c31":"getNeedCloseBets()","0650b590":"bulkAdd(address[])","0651844e":"activateBalance(address)","06525841":"canCashBack()","0652d7f5":"fxFee()","065361a6":"buyBkgAtExchg(address,uint256,uint256,uint256)","0654cb16":"canInvest(address,uint256)","0654fbc4":"giveEther(address,uint256)","06552ff3":"init(address,address,address,address)","0655c58b":"getIcoTokensAmount(uint256,uint256)","06562575":"isTermOver()","0656dd02":"existingContract(address)","06575c89":"currentWeek()","0657a9c5":"registerTopPlayers(uint256,uint256[],uint256[])","0657f3a1":"finishIco(address,address)","0658a429":"BlockHashStorage()","0658b574":"storeImageString(string)","0659928c":"weiPerMinToken()","065b1061":"ln(uint256,uint256,uint8)","065b3133":"getDataColla_AA_02(string)","065c6b90":"setLevelRewards(uint256,uint256)","065de1f6":"minionRemove(address)","065de950":"dropNectar(address[])","065df077":"createBondFundToken(string,string,uint256,int256,uint256,uint256,address,string,uint256)","065e5360":"currentTick()","065ec2e6":"_restriction()","065ece90":"StageTwoDisable()","065f7a98":"totalNonSaleSupply()","065fcdff":"distributionThree(address)","065fe24f":"heldTimeline(address)","0660b8b2":"updateethFee(uint256)","0661b2f4":"setOtherPCK(address)","0661f204":"generateOtherNums(uint8[4])","066208de":"setInitialDuration(uint256)","06621ff6":"AZEEMCOIN(uint256,string,string)","0662572f":"activateSale(address)","06637876":"customers()","06637cd9":"getNewPeriod()","06638e92":"GetNumbersFromHash(bytes32)","066406ad":"LootEtherCom()","0665a06f":"createVesting(address,uint256,uint256,uint256)","0665c82b":"doPurchase(address)","06661abd":"count()","066636da":"getTotalEtherOfCurrentRound()","0666a6da":"setUnlceRateAndFees(uint256)","0666c071":"getEmployeeInfoByName(string)","06673ac7":"OmnesToken(address,address)","0668f649":"lambosTuneCount()","066aa53b":"updatCokeTotal(uint256,uint16)","066aff83":"calc1RealTokenRateFromRealTokens(int128)","066b0380":"assertEq30(bytes30,bytes30,bytes32)","066b3136":"paymentSuccessful(bytes32)","066bdc1b":"Legend_Royale(uint256,string,uint8,string)","066bf18c":"checkGoal(address)","066c94ba":"minTxSize()","066cd2c6":"createOfferAssets(uint256[],string,uint256,uint256)","066cf539":"vaultSecondaryUnlocked()","066d4701":"callFirstTarget()","066d76fe":"update_ratio(uint256,uint256)","066e4748":"calculateIdeaBuy(uint256,uint256)","066e4ce3":"CancelSell(address,uint256,uint256)","066f8a7d":"_disconnectModule()","066fd899":"availableReward(address)","067002ce":"removeSellingItem(uint256)","06713c3e":"proxy(address)","0672859b":"getMonsterCP(uint64)","0672cce3":"changeMinBet(uint8[157])","0673c8be":"isZero(address)","0674763c":"assert(bool)","06748fb1":"_random()","067497e2":"LogIcoTokenSupplyUpdated(uint256)","0674fde4":"aventus()","0675cb0b":"mintBool()","0675e962":"delegateIsCurrent()","0676aade":"GetOtherCustomerInfo(bytes18)","0676bde3":"BitGuildToken()","06771000":"ownerClawbackCredits()","06772bbd":"LogStateTransition(uint8,uint8)","06780cf5":"preIcoWallet()","06784b81":"MAXWIN_inTHOUSANDTHPERCENTS()","06787b98":"setHalfLifeRate(uint256)","0678c282":"extendRound(uint16,uint256)","067903f9":"withdraw4()","067906b1":"profiterole()","0679195a":"BerryLakeToken()","06791fc8":"enterPool(address,uint256)","067969a3":"sale2Accepting()","067a1e16":"getLockedValue(address)","067a2f3e":"Goochain(uint256,string,uint8,string)","067a6b05":"myRole()","067a8eb4":"registeredFundToRegistrants(address)","067ad784":"defaultBonussRate()","067ade9f":"claimSeedOwnership()","067c2d78":"thirdStartTime()","067cf182":"generateReport(int8[],uint32[])","067e06ee":"getServerStatus(string)","067ec02e":"Xkcd()","067eeeac":"tempTokensBalanceOf(address)","067fc6dd":"isTokenHolder(address,address)","06802613":"mintForCreatorsPool(uint256)","068045c7":"crowdsaleSetup(uint256,uint256)","0680d58a":"replaceService(address)","0681ae70":"FARTCOIN()","0681ca55":"milestoneCount()","068365ec":"buyWithCustomerId(uint256)","0683751e":"_removeByValue(address)","0683d56a":"minimumParticipationAmount()","0683dc58":"checkTransferIn(address,address,uint256)","0683dfdb":"getIdentifiersCount(address)","068417d9":"_registerInterface(bytes4)","06845b9f":"setTransferAbility(bool)","06845c4a":"LogFreezerRemoval(address,uint256)","0684c12b":"distributePresaleTokens(address,uint256)","0685224c":"GraspSmartBlockchainLock()","0685b410":"submitChooseByFactory(address,uint256)","0685b42c":"maascash()","06867f7d":"accountA()","0686dc8d":"setNEW(address,uint256,uint256,uint256,uint256)","06873418":"getcoolduwn(uint32)","0687bb4a":"purchaseCarCard(uint256)","06881fd1":"setBaseTokenGetRate(uint256)","068841c6":"getNeedLockFunds()","06884fc8":"airdrop2()","06886a53":"curOpenBNumber()","06886fd0":"logRoyalty(address,uint256)","0688b135":"recipient2()","0688ec24":"preicoAndAdvisorsAmounts(uint256)","06894f59":"TakeBack()","0689d0ff":"timeToChallenge()","068aafb8":"NepExToken()","068ae02b":"DATE_LIMIT()","068aebbc":"transfer(uint8[],uint8[],uint32[])","068b7310":"maxWei()","068bcd8d":"getPool(uint256)","068c017b":"calcUnlock(address,address)","068c8e61":"GetLandData()","068c966b":"DrawDetails(uint256)","068d5363":"withdraw_bix()","068ea2aa":"getLawyerAtIndex(uint256)","06900a40":"coAdmin()","06900c41":"ZeroPonzi()","06903e3e":"offeringProposals(address,uint256)","06903ecc":"GVE()","06907e17":"block(address)","06909f69":"cancel(string,uint256)","0691d0bf":"move(address,int64)","069215c9":"icoPhaseAmount4()","06921a9c":"PRESALES()","06934753":"getLanguageCountry()","0693b1ab":"minCount()","0693e603":"tokensAmountForPurchase()","0693ee6e":"firstStartTime()","069489a2":"init2()","0694d1be":"refundsOpen()","0694f9d6":"getQtyValidators()","06961560":"DAO(address,uint256,uint256,uint256,address)","0696647a":"test_insert_findWithHintNextAtPosition()","0696ba24":"revokeTickets(address,bool)","0696eab6":"RICHCrowdsale(address,address,uint256,uint256)","0698ac9b":"decreaseWeiRaised(uint256)","06991539":"_addTokenToOwnersList(address,uint256)","06993c97":"writerAccountSupplyRemaining()","069984c9":"SmartVows(string,address,address,string,address,address,string,string,string,string,string,string,string)","0699d07d":"updateMaxVal()","0699f10a":"LightAirdrop()","069a2e73":"registerModuleHandler(address)","069a6947":"biddedico()","069b559c":"migrateThroughOneFork()","069b9232":"ChenXiangToken(uint256,string,string)","069bd974":"validateTransfer(uint256)","069c97df":"angels_lock_days()","069cff34":"getMymorties()","069d6d1c":"closeOrder(uint256)","069d92e3":"showInvestEther(address,uint256)","069e5e53":"createEscrow(address,address,uint256,uint256,uint256,uint256)","069e9dba":"activateHandbreak()","069f5f72":"getMineableTokens()","069f74c7":"zcc()","069f7e85":"getGreeksBattlePoints()","06a0ab2b":"earningsPerShare()","06a24640":"setNextPot()","06a248c6":"depositTo()","06a33300":"BITOX(address,address,address,address,uint256,uint256,uint256)","06a36aee":"getUserRoles(address)","06a46703":"pubsaleDeadline()","06a493fa":"redeemCards(address,uint8)","06a49fce":"getCandidates()","06a5312b":"GetNumber()","06a585e6":"addInvestor(bytes32[3][],address,uint256,uint256)","06a5cb3a":"ecosystemAddress()","06a5f087":"signSeller(uint256)","06a628d4":"packSize()","06a6c28f":"commitDividend(address)","06a74947":"getBigWinPot()","06a81591":"_price_token_PRE()","06a85497":"getGameBonusAdded()","06a86539":"PBTTForGas()","06a8f8a2":"admin2()","06a95b53":"blablabla()","06a98f0a":"Mine_Block()","06a9ce79":"updateTimer(uint256,uint256)","06a9d1a9":"fundraisingDeadline()","06aa4083":"icoWeek1Bonus()","06aacb14":"Broker(bool,address,address)","06ab5923":"setSubnodeOwner(bytes32,bytes32,address)","06aba0e1":"getTotalWeight()","06ac1527":"capWalletAddress()","06ac2303":"EthereumButton()","06ac5879":"perReserveListedPairs(address,bytes32)","06adb71d":"increaseEmployeeExtraOptions(address,uint32)","06ae9483":"contractExists()","06aef16a":"getAuthorizationDate(address,address)","06aef6fb":"_withdrawToken(address,uint256)","06af0650":"initializeCurve(bytes32,bytes32,int256[])","06af3c75":"get_next_user_recast_from_item(bytes32,bytes32)","06af7414":"ContestAnnouncement(address)","06b05238":"safeWithdrawAmount()","06b091f9":"withdrawTokens(address,uint256)","06b0c76d":"setReferenceHash(bytes32,bytes32)","06b16a6c":"petPresell(uint16)","06b1b479":"indCommunity()","06b1efe5":"pushData(string)","06b28cec":"createDividendWithCheckpoint(uint256,uint256,address,uint256,uint256,int256)","06b2be05":"payStyle()","06b2e607":"GetGamestatus()","06b2fe22":"remainingTokensCount()","06b2ff47":"canReverse(address)","06b3bcd1":"getIpfsAddress(bytes32)","06b4c3e9":"ABCToken(string,string,uint256)","06b5338a":"JCoinz()","06b5760d":"getCreateShareTokenOutcomeValue()","06b5ad18":"recovery(string,address)","06b5b21e":"proposeTransfer(address)","06b5f02d":"calcWinnings(uint256,uint256)","06b6689b":"nextLotteryTTMTokenId5()","06b70f62":"MULTISIG_OWNER()","06b726d6":"smartBlockAddress(address)","06b77972":"getDescriptionInfo(bytes32)","06b82a7d":"deregisterSettlement(uint64)","06b89153":"BBB()","06b8ef4a":"rewardCheckpoint()","06b96bb4":"HoloSale(uint256,uint256,uint256,uint256,uint256,address)","06ba089a":"updateWebsite(address,address,string)","06ba2987":"addSellTokensRequest(address,string,string)","06bb18c0":"NewCratePreSale()","06bbbeff":"getUserBetOf(uint256,address,address)","06bc7ef3":"deleteInvestContract()","06bced7c":"set_presale_arbits_total(uint256)","06bcf02f":"updateStartTime(uint256)","06bd7aac":"setSubdivisionEnabled(bool)","06be8e04":"_payToInviter(address,uint256)","06bee2be":"CartycoinToken(uint256,string,string)","06c01551":"setAtomDna(uint256,uint64)","06c0e841":"withdrawPayout()","06c1032c":"Created(address,address,uint256,uint256,string)","06c15206":"GTL()","06c17cd7":"sliceLengthThrow()","06c18600":"takeOwnership(uint256,uint256)","06c18ae0":"CyberVeinToken(address,address,address,uint256)","06c1b0ba":"adPriceDay()","06c1df7b":"checkBetColumn(uint8)","06c265b6":"VICCOToken()","06c270be":"HmcDistributor()","06c2b53c":"becomeTo()","06c2f050":"setSendToSafeWalletPercentage(uint256)","06c30e84":"CoVEXTokenERC223()","06c3f137":"getLastNReadingsByDeviceId(uint8,uint8)","06c45c2a":"addToTradeList(uint256[],uint256[],uint256[],uint256[])","06c4811e":"TokenOWLProxy(address)","06c5b9d0":"XiaoMuBiaoERC20()","06c6c546":"massApprove(address[],uint256[])","06c7e165":"SevenStandardToken(uint256,string,uint8,string)","06c80102":"releaseAbstractToken_(address,uint256)","06c89667":"change(string,string,uint256,uint256,bool)","06c8ffed":"removeMultipleAddressesFromWhitelist(address[])","06c91ce3":"gx()","06ca218f":"doPayout(uint256)","06ca66f0":"Indosat(address)","06ca9bba":"Start_NewRound(uint256)","06caf3e6":"extraDiscount(uint256)","06cb0ea4":"updateAd(uint256)","06cb4bcd":"sendDeposit()","06cc01bc":"setBuyCommissionBps(uint256)","06cc2035":"revokeFeeExemption(address)","06cc2cd2":"recordSoldPrice(uint256)","06cc6373":"UpdateUserExtraData3(address,bytes32)","06ccd230":"addToNumber(uint256)","06cd4728":"RublixToken(uint256,address)","06cf2280":"transferWithFee(address,address,uint256,uint256,uint256,address)","06d00b10":"doesOwn(bytes32,address)","06d0407e":"getBeneficiaryFinance()","06d0db26":"roundMoneyUpToWholeFinneyET(uint256)","06d145c9":"getFundingInfoForUser(address)","06d1772d":"TWOIoT()","06d177c1":"divPoolAmt()","06d19d68":"getHashRevealEnd()","06d19eb3":"updateSeller(address,uint256,address,uint256)","06d37817":"loanToken()","06d44278":"_emitError(uint256)","06d586bb":"maxPerUser()","06d58f2a":"claimAndWithdraw(address,address,address,uint256,uint256)","06d65af3":"preSaleStartTime()","06d6b095":"ProposalAdded(uint256,address,uint256,bytes)","06d6e513":"checkIsKYC(address,address)","06d83296":"setData_17(string)","06d832a3":"ownerStartContract()","06d8619b":"transferKing(address)","06d91eea":"getExoplanet(uint256)","06d978b2":"setMinDepartureLim(uint256)","06da3309":"Deposited(uint256,uint256)","06dafac6":"setGreyToken(address)","06db33e4":"getVotesByCandidate(uint16)","06db8af7":"toAddrString(uint256)","06dc5d7f":"total_user_eth()","06dc8949":"calculateTokenSellPrice(uint256)","06dcd5d0":"CATTOKEN()","06dd497f":"cancel(address,uint256,address,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","06df6cf0":"icoTokenExchangeRate()","06e102a0":"Presale(address,uint256,uint256,uint256,uint256,uint256,address,address)","06e16a36":"currentTierId()","06e1976c":"lockAccount()","06e232c4":"getLuckyblockIds()","06e25081":"getFreeToken(uint256,address,uint256,bytes32,bytes32,uint8)","06e2f5c1":"getRoundRate(uint256)","06e31056":"FANCrowdsale(uint256,uint256,address,address)","06e34150":"filters(uint256)","06e3a700":"setStartingSeeds(uint256)","06e3d732":"getMyChest()","06e42962":"_winnerJackpot(uint256)","06e430f6":"getAcceptedOracles()","06e48538":"defaultOperators()","06e4d36f":"getSoftCapReached()","06e53e5c":"getCountHolder()","06e53f47":"whichChainIsThis()","06e5fe85":"promoPurchase(uint32,uint8,uint8,uint8,string)","06e63ff8":"insert(string,string)","06e64907":"End()","06e795e8":"sendToAddress(address,uint256,uint256)","06e7b5ad":"isDisputing(address)","06e8337f":"getTotalTickets()","06e83e2f":"send(address,address,address,uint256)","06e840ea":"incrementStatistics(uint256,uint256)","06e91d2e":"ROY()","06e99fef":"sendEth()","06ea1c02":"setArbitrationFeePerJuror(uint256)","06ea29c2":"notEqual(int256[],int256[],string)","06eb0c2f":"TokenERC20_test(uint256,string,string)","06eb6ac1":"TokenPaymentGateway()","06eb815f":"handleETH(address)","06ebe49f":"incMemberGoodRep(address,uint256)","06ec16f8":"collect(address)","06ec6272":"payCustom(address,uint256)","06ec8ca6":"setCurrency(bytes32)","06ec967b":"deleteHpbNodeBatch(address[])","06ec9b9e":"ETH_PRICE_USD()","06eca511":"unhaltICO()","06eccccb":"_getPersonalAirdrop(address,address)","06ed6908":"buyTokensFromContract()","06ed69b9":"dDeprecateCategory(bytes32,uint256)","06edcd24":"hasOpenedOldCrates(address)","06ee3b69":"startCloseSalePhase()","06ee4917":"ChainMaster()","06eeaba0":"tokensForParnter()","06ef53e0":"latestWinner()","06ef856b":"ethRelief()","06efdecd":"OwnerTransfered(address,address)","06f1117d":"REFERRAL_BONUS_LEVEL2()","06f13056":"batchCount()","06f2bf62":"getExchange(address)","06f33115":"ClaimedAmount()","06f33ae2":"setUnownedLifeRate(uint256,uint8)","06f36cc9":"helpBlue()","06f3fc8a":"Mapoc(address)","06f470e9":"purchaseEstate(uint256)","06f4b12e":"changeTenant(address)","06f4f7de":"cancelDigitalArtSellingItem(uint256)","06f57add":"getWeekNumber()","06f639fe":"tier3(address)","06f660ef":"getInitialPrice()","06f68f12":"updateFirstBuyNum(bytes32,bytes32)","06f69881":"crossForkFundDeposit()","06f70295":"answer(uint256)","06f74bcf":"pauseInternal()","06f7ec97":"preICOBonus()","06f7f3fe":"getERC20Pawn(uint256)","06f84701":"canRedeemUTXO(bytes32,bytes20,uint8,uint256,bytes)","06f8ac40":"miniumInvestment()","06fa01b1":"MasonCoin()","06fa9df9":"hashPositions(uint32,int64[],bytes16)","06faebbe":"setPromoToPartner(string)","06fbf606":"setBurnFeeProp(uint256)","06fd06f8":"Exchanger()","06fd537b":"burnMoney()","06fdde03":"name()","06fdde58":"structure_variant_confirmation(int8)","06fde169":"REQUIRED_SHARES_TO_BE_BOARD_MEMBER()","06fdf75d":"getRedeemValue(uint256,address)","06fe0c29":"finishMilestone(string)","06fe1fd7":"getPackageName(bytes32)","06fe2212":"changeWaitTime(uint256)","06ff8908":"JoyToken()","06ffce53":"getTokenValue()","07002f02":"canIssue(uint256)","07006a55":"createPromoEggs()","07016f60":"getPOOL_edit_25()","0701da46":"limitAccount(address,uint256)","07023a38":"SellerHistory(address,uint256,uint256)","07031305":"setExpiration(uint256,uint256)","0703ffd1":"getLimitedReporterMarkets()","070485a9":"setGlobalPause(address)","070494ce":"blockFundsInEscrow(address,uint256,address)","070545d8":"Extend(bytes32)","07058808":"WinTokenLock()","07062cf2":"vision()","070669e6":"Requested(address,bytes32)","07073756":"_getTokenAmountForReferral(uint256,bool)","0707873c":"getInvestorInfo(address)","0707a106":"setRateEthToToken(uint256,uint256)","070816f1":"transferTeam1Tokens(address,uint256)","07085842":"smartcontracts(uint256)","0709544e":"getColor(bytes1,bytes1,bytes1)","0709d116":"setBlackListERC223(address)","0709df45":"vaultOf(address)","070a888f":"updateRewardDuration(uint256)","070ae23b":"createContractTokenWithPrice(string,uint256)","070b91d1":"voting(uint256,uint256,bool,uint256)","070bc415":"_computeUniqueness(uint256,uint256)","070bc508":"SupremIOTToken(address)","070be532":"BSE()","070c04b1":"setFromContractAddr(address)","070c3c23":"previousPayoutBlock()","070c87f9":"enableERC20()","070caf36":"exchangeTokenToEther(address,uint256)","070cf0cb":"isAgreementFullySigned(bytes32)","070f0e96":"countTokenHolders()","070f52f4":"canExchange()","070f5c09":"pausePresale()","070f723d":"_initializeGame()","070f7926":"_sendByDefaultTranches(address,address,address,uint256,bytes,bytes)","070fdb96":"getTakerBet(uint256,address,uint256,address)","07113965":"setPOOL_edit_3(string)","07120872":"createFightAuction(uint256,uint256,uint256,uint256)","07121a7a":"_requireBidderBalance(address,uint256)","07129e67":"SimpleEthBank()","07133caf":"HCToken()","07134b8b":"tokensNeededToGetPayment()","071357bd":"concludeCampaign(uint256)","07142877":"PRE_SALE_MAX_CAP()","07144458":"forwardTokens(address[])","07146786":"userRankAddress()","0714c622":"anotherFunction()","07153d3b":"setStates(bytes32[])","07156854":"flipSwitchTo(bool)","0715b09f":"nouvelleProduction(uint256)","0715ec34":"EnchantedShop(address,string,string,uint256,uint32,uint256)","071696e0":"transferFAIDS(address[],uint256[])","0717f39e":"_isValidPerkToAdd(uint8[32],uint8)","0719d365":"TOKENS_CAP_ICO()","071a56df":"addOracle(address,string)","071a7541":"BETA()","071b7e73":"FinishIco(address,address,address,address)","071bafb5":"sin()","071bd079":"demo(uint256)","071bdfbd":"PlayCoin()","071c0306":"AvailableTokenPool()","071c802b":"saiVox()","071da02f":"totalBelaStaked()","071e1ddc":"processFunding(address,address,uint256)","071e9a76":"distributeFunds(address,uint256)","071eeeb3":"setStarNameMessage(uint256,string,string)","071fac61":"getAllMediators()","071fe9b0":"isBurnInClose()","07202460":"getMonsterObj(uint64)","07209e2b":"AllowanceCrowdsale(address)","0720fc78":"removeOWhitelist(address)","07216bda":"getBurnRequestStringMap(uint256,string)","072180ff":"buyCoinsAtExchg(address,uint256,uint256)","0721c6dd":"setCompte_29(string)","07220134":"getBetInfoByReveal(uint256)","0722559c":"endRentFlatDaily()","072419f4":"changeTeamFee(uint256)","072448f7":"midTimeBonusValue()","07256175":"SecondLevelCost()","07259d06":"limitGasPrice()","0725e898":"getTokensForOwner(address)","07260a43":"serveTx(address,uint256,bytes,bool,bytes)","07266117":"networkDevelopmentSupply()","0727adb3":"last_balance()","0728d5e3":"getDiscountedItemsForSale(uint256,uint256)","072933e9":"OWN_kill()","07293b9d":"maxStage2AllocationPerInvestor()","07298203":"GetStats()","072b3f49":"createContract(address,address,address,uint256,uint256,uint256)","072b8277":"VAPEbits()","072b9c83":"AxieERC721BaseEnumerable()","072b9cf2":"schema(bytes32)","072bdbb8":"getScripts(uint256,uint16)","072de7f3":"calculateTokenPrice(uint256)","072e28c2":"setCRManager(address)","072e4308":"detailsOf(string,string)","072ea61c":"entryFee()","073005f1":"canTransferFrom(address,address)","07304435":"getKilled()","0730a322":"FoundationTransfer(address,uint256,uint256)","073171d8":"LeaseBill(uint256,uint256,string)","0732717d":"buy_the_tokens(bytes32)","07336e35":"producedCaps()","0733b888":"getRoundsActive(address)","07342e9f":"MultiSigWalletWithDailyLimit()","073455f1":"BitDex(address,address,address,uint256,uint256,uint256)","073767fc":"changeRateFee(uint256)","073933ed":"isNotZero(int256,string)","07394d39":"TeamTokenLock(address,address)","0739cd26":"tsSucceeded()","073b3bf9":"addressToNumVillages(address)","073b423d":"mintTransfer(address,uint256,uint256,uint256)","073cc554":"newProposal(address,string,address,uint256,address,uint256,bytes)","073d5fd8":"DeadlineExtended(uint256,uint256)","073d9a28":"transferactive()","073e1fa3":"givecandyfrom()","073ede30":"addTeam1(uint64,uint64,uint64,uint16)","073f323d":"MamatToken(uint256,string,uint8,string)","07414002":"secureApprove(address,uint256)","07415ce8":"addressOfTokenUsedAsReward4()","0741dc1e":"withdrawToken(bytes8,address,uint256)","07420a41":"sendReward(address,uint256)","07433ca4":"createVesting(address,uint256,uint256,uint256,uint256,bool)","0744c56b":"getFreeHipster()","0745c160":"startProICO()","07461622":"setMinMax(uint256,string)","0746bfd9":"buySharesForProposal(uint256)","07471b18":"distributeInvest(uint256,uint256,uint256)","0747ab2a":"Winner(uint256,address,uint256,uint256)","0747e4eb":"wpr()","07489aa6":"totalFinalStage()","07489f92":"getUnsoldTokensVal(uint256)","074a1594":"addToAging(address,address,uint256,uint256)","074a1600":"percent2()","074b1e61":"referralsVault_()","074b5270":"leadingBid()","074bc101":"btcToken()","074c0836":"POMoooon()","074c09eb":"catalog()","074c32c4":"updateRatePlan(uint256,uint256,string,bytes32)","074c71e5":"SaleWallet(address,address)","074c9647":"updateEtherAmount(uint256)","074cac6c":"getFreeMinerForMiniGame(address)","074e06ee":"_addLuck(address,uint256)","074e0f36":"setMaxRefundableGasPrice(uint256)","074e6254":"blendWithYourself()","074e8940":"companyWalletAddress()","074f0a22":"DataContacts(address,address)","074fcfd5":"_blockKey(bytes32,bytes32,uint256)","07501073":"migrationGetPlayer(bytes32,uint8)","0751076d":"setBetMax(uint256)","07518c8e":"blockhashOf(uint256)","0752881a":"buyTokens(address,uint256)","075360bb":"moveRoundsToHolder(address)","07537ad4":"closeCrowdSale()","07539074":"LogInvestorRefunded(address,uint256)","0753afdf":"registration(string,string,string)","0753c30c":"deprecate(address)","0754236d":"minContributeETH()","07542576":"BayernvsRealMadrid()","07546172":"minter()","07549893":"SimpleChildToken(address,string,string,uint256,uint8)","0754e744":"icofunding()","07550f0a":"areAllBalanceNull(bytes32)","07560f13":"transferWithMessage(address,uint256,bytes)","0756f58f":"getDifficultyAsFixedPointForGameId(uint256)","0757114e":"getenddate()","075840d0":"bounty_funds()","075865c4":"getMiningWarDealine()","07587fa3":"KissMe(uint256,string,string)","075881d6":"purchasePlayer(uint256)","0758a980":"specialBonus(address)","0759a351":"getCCH_edit_30()","075a3b57":"releasedTo(address,address)","075acda7":"gasAmt()","075b1a09":"schemaId()","075bbcc7":"RESERVED_TOKENS_TIQPIT_SOLUTIONS()","075bf772":"teamTotal()","075c04ab":"dividendRewards(address,address)","075c18f7":"contributeByBitcoin(uint256,uint256,address,uint256)","075d4782":"publish()","075d7bb3":"setDontIndex(bool)","075deb95":"buyGana(address)","075e0a7c":"window3TotalSupply()","075f8ec2":"CommunityCoin()","075fe66a":"EDD()","075fe877":"scheduleCall(address,bytes,uint256,uint256)","0761923c":"TargetWalletUpdated(address)","0761a004":"step(uint256,bytes)","0761c57a":"rocketBlocksUntilAllowedToLaunch()","07621038":"getSponsorshipUser(address,uint256)","07626adb":"getApiId(string)","0762c317":"createNewPop(uint256,string)","07630eac":"sendTokensToBatch(uint256[],address[])","07632269":"_deliverPack(address,uint8)","07634cbe":"getCoupon()","0763b78b":"getPVEDuration(uint256)","0763f34e":"referrerReward()","0764a7fa":"FinderHyper()","0764ebd9":"updateExcludedAddress(address,bool)","0764f5e0":"serviceDeployCount(address)","076600ec":"ClaimDivs()","07660978":"PrepareForSale()","076736a2":"maxPurchaseSize()","07675951":"UpgradePurged(address)","0767d178":"weightOf(uint256)","076804b8":"checkAddressVerified()","0768e8fa":"payAffiliateToAddress(address)","07695379":"ControlStructure(uint256)","0769aefa":"createAnimecard(string,string,string,string,uint256)","076a1852":"zTransferLosingBets()","076a39a0":"HOUSEEDGE_inTHOUSANDTHPERCENTS()","076a6440":"setMain(address,address)","076ae31d":"BountyEscrow()","076b5fe1":"FangToken()","076c4870":"owner(address,address)","076c52b2":"betA()","076ccbe4":"testLedgerZeroCollateral()","076e18a0":"getCurrentTokenPriceWei()","076fdf3c":"getLockingTimestampTo()","076ffa3a":"___isActive()","0770a074":"adjustSupply(uint256,uint256,uint256)","077135a8":"totalNoOfTokenAlocated()","07715fd4":"BCOToken(address,string,string,uint256,uint256)","07716dd2":"hasEmployee(address)","07718a3b":"BankOwner_WithdrawDonations()","07730eb9":"BurnAllTokens()","077340c5":"transferAndFrozen(address,uint256,bytes,uint256,uint256)","0773aa85":"changeFoundersWallet(address)","0773e6ba":"addPermissions(address,address[])","0774774f":"lineageToken()","07751070":"getProperty()","07762e74":"viewMult()","0776e4fa":"set_balance(address,uint256)","077757fc":"transferWithoutChangeBest(address,uint256)","07776028":"creatorOwnership(address,address)","07777949":"transferEthBackToUser(address)","07779627":"isDelegate(address)","0777fa95":"TokenTKC()","0778425a":"getProposalsBySeller(address)","07786d0c":"sendAward()","0779afe6":"send(address,address,uint256)","0779d0f5":"refundApToken(address)","077a05dd":"sellSpecialTokensForPreSale(address,uint256)","077a8eaf":"abandonedIcoBalances()","077b109b":"_checkLedger(string)","077b124b":"addSuperInvestor(address)","077cd4bf":"petHpThreshold()","077d256a":"icoInvestorsAddresses(uint256)","077d3f8c":"Engrema()","077dadb2":"coinBalanceMultisig(address)","077e43b4":"getLastBallot()","077e6334":"endLock()","077f1008":"tovote(string,uint256,uint256)","077f224a":"initialize(string,string,address)","07801b5c":"nextroundGOTCHatcontract()","07805363":"joinGames(address,uint256)","07806b19":"cardDetailsStructs(uint8)","0780a196":"createDetail(address,uint256)","0781c111":"TokenSeller(address,uint256,uint256,bool)","0781f4d2":"emitting()","07822f7d":"viewauctionlist(uint256,uint256)","0782709a":"setKrsUsdRate(uint256)","0782fc35":"releaseValue4()","0783c2ef":"getAuditState(uint256)","0783d820":"getSysRestEth(uint256,uint256,uint256)","0784a07f":"distributedTokensAmount()","0785001c":"amountGoal()","07855f4f":"startPlacingPhase(uint256)","07858f0e":"setBallotOwner(uint256,address)","0785ca29":"BalanceCheck(uint256)","0785cb94":"DateOfBirth()","0786f01e":"setCookUpFee(uint256)","0786f72b":"etherAddress()","0787006d":"setCosignerCallGas()","0787bc27":"providers(address)","07883703":"Mint(uint256)","07885cd1":"PaymentChannel(address,address,address,address,uint256,bytes)","078895ea":"GbeeStandardToken(uint256,string,uint8,string)","0788f69c":"setCityPicture(uint256,string)","07894b1e":"initMartial()","0789fc01":"burningPercentage()","078aa5af":"testStorage(uint256[],uint256[])","078b247e":"shouldBeTerminated()","078b55e6":"createLibrary(string,string)","078bd227":"outputa(address)","078c0452":"setJobCompleted(bytes)","078c3fa4":"_transferToICAPWithReference(bytes32,uint256,string)","078c42e6":"AirdropCheck()","078cc1cb":"setStartersProxyAddress(address)","078cfee6":"initializePrivateSale(uint256,uint256,uint256,uint256,uint256)","078d1258":"addFrostTokens(address,uint256,uint256)","078d88ff":"Validated(string,uint256)","078db9c9":"Mepoupe()","078dfbe7":"transferOwnership(address,bool,bool)","078e096d":"endPublicIco()","078f8d3b":"ConversionAborted(uint256,string)","078f9378":"updateParameters(address,address,uint256,uint256,uint256)","078fd9ea":"saleCap()","079095ae":"VULCAN_POD()","0790e880":"setBlockappsAddr(address)","07910a78":"get10Tokens()","079172da":"proofSet()","07927187":"addEmployee(uint256,string,address)","07930644":"getExchangeAdapter(bytes32)","07932772":"judge(uint8)","07939a17":"BUYER_STEP_3(bytes32,uint256)","07957360":"verifyOwnership(address,address)","0796c325":"Loading()","0796f97b":"FIRST_DAY_END()","07973ccf":"userCount()","0797595a":"donateDnaFromContract(address,uint256,uint8)","0797adb0":"loadEngineerOldData()","07986518":"GoogleChainSale(address,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","0798d7ef":"removePreIcoMembers(address[])","07993f04":"getPaper(uint256)","0799ad8d":"takeBackNTRY(address,address,uint256)","0799f1b2":"registerZTKCheck(address,string,string,string,string,string,uint256,string,string,int256,uint256)","079a193b":"changeAllowance(address,uint256)","079aab88":"newPresserFee()","079b365e":"reportProfit(int256,bool,address)","079c002f":"TOKEN_WITHDRAWAL_START_DATE()","079c345d":"major(uint256)","079c9fbb":"airDropSame(address[],uint256)","079caa14":"grantAdvisorsTokens(address)","079ce327":"reLoadXname(bytes32,uint256,uint256)","079cf76e":"getRoot(address)","079d229f":"freeFromUpTo(address,uint256)","079d2b96":"IsCampaignAvailable(uint256)","079d7d7f":"winningPot()","079e0e0e":"batchBuild(uint256[],int256[],int256[],uint8[])","079eaf34":"addUser(string,string)","079ee6b3":"addParticipant(address[],uint256[])","07a1ca5f":"endGame(address,bytes)","07a2aac2":"reverseBytes()","07a2c4d5":"DanatCoin()","07a3082d":"ConstructByCredits(uint256,uint256)","07a43efd":"export()","07a67fb3":"get_pool(uint256)","07a6e434":"getDocs(uint256)","07a72184":"stringToBytes32(bytes)","07a7465f":"getDescendantsOfThing(uint256)","07a77473":"_isOnAuction(uint256)","07a8275d":"getInviteEarnings(address)","07a878f6":"CLPToken()","07a8af6f":"expiryLimit()","07a8df44":"capInitialized()","07a94ed2":"powerDayRemainingLimitOf(address)","07a9574a":"changeLeaderMessage(string)","07a95e83":"refundUnclaimedEthers(uint256)","07a993e5":"setOtherCurrenciesChecker(address)","07a9d7a8":"hasConfirmedApplicant(address,address)","07aba33d":"getNext(uint256)","07ac15e2":"getInitBlock()","07ac8087":"getQuickBuyEtherTokenAddress()","07ad3282":"lastSettlementStartedTimestamp()","07ad9ecb":"safeSend(address,uint256)","07ae279c":"stage_Days()","07ae3095":"setNotMoreThan(uint256)","07aef7a6":"BGGToken()","07afbe74":"addAssetToOwnedAssets(address)","07b1470c":"debugVal3()","07b15667":"addPresaleAllocation(address,address,uint256)","07b1be24":"addTokenPairSecondPart(address,address,uint256,uint256)","07b261bc":"addOwner2(address)","07b26217":"removeAvailability(uint256[],uint256)","07b2779f":"BasicRegulator(address,uint256,uint256)","07b3776c":"currentRecord()","07b39962":"delAllowContractList(address)","07b578a0":"getGuestName()","07b5fc54":"updateDividendsFor()","07b657ce":"lastBlock_v17()","07b6b762":"reserveFullMintAllowance(int256)","07b6f631":"testTestHarnessAuth()","07b86b41":"transactionsOnNowVal(address)","07b88cb3":"registerOffering(bytes32,bytes32,address,uint256)","07b8ef24":"votesSupport()","07b99366":"initExit(bytes32)","07b9ac2c":"editTrustee(address)","07ba216c":"coinsaleactive()","07ba217c":"pay1(address)","07baa3db":"ARXCrowdsale()","07bbb378":"BoughtTokens(address,uint256,uint256,uint256,uint256)","07bc6fad":"withdraw(address,uint256,bytes32,uint256)","07bc8829":"showText()","07bcf03a":"CFXToken()","07be02fe":"getPublisher(bytes32)","07be6ef8":"getTopCompanyStartPrice()","07be74b9":"refundWhite(uint256,uint256,uint256)","07bec66f":"buyout(uint256)","07bee472":"totalMainSaleTokenLimit()","07bf5863":"unprocessedQueryList(uint256)","07bf9b9f":"BONUS_SCALE()","07bfaa03":"toB32(uint256,uint256,bytes)","07bfce37":"long()","07c037af":"NipToken()","07c24086":"preSaledeadline()","07c299c2":"eT(address,uint256,uint256)","07c2e16c":"getOrdersLength()","07c34e73":"releaseState1()","07c38522":"RMBToken()","07c3d98b":"balanceOfTotalUnclaimedMilk()","07c430bd":"Robincoin(uint256,string,string)","07c4d580":"transferForAdmin(address,address,uint256)","07c4e9e4":"ToggleFreezeToken(uint256)","07c533a5":"MTSCoin()","07c599df":"Stakefasttoken()","07c6b2fa":"_addDataStream(address,string,bytes32)","07c7accb":"getIdentityProvider(address)","07c7bae8":"LogContributions(address,uint256,bool)","07c8e56f":"Filter(address[],uint256[])","07c8fb5a":"HelperSearch()","07c9cd45":"cancelSell(uint256)","07ca140d":"numberOfCampaigns()","07ca3bc1":"ping(bool)","07ca6931":"StrategyAddress()","07cadb0f":"createCryptoAvatar(uint256,uint256,uint256,uint256,address)","07caf9e1":"advisorFirstLockTime()","07cb33d5":"ReleasableToken()","07cb4419":"OWN_contractlocked(bool)","07cbe8ab":"raisedFromToken(address)","07cc36da":"BNBNSRegistry()","07cc6051":"airAmount()","07ccad95":"TEAM_POOL_TOKENS()","07cd401c":"dividendDistributionPool()","07cd5c29":"batchRefund(address[],uint256[])","07cdee49":"coo()","07ce55a0":"ExtraFinalizeAgent(uint256,address,uint256)","07cfa11f":"WELFARE_HANDOUT()","07cff6f2":"getERC20(address,uint256,address,uint256)","07d03f8c":"sendTokensToSale()","07d0da7e":"NormalToken(string,string,uint256,uint8)","07d15ffd":"SteriliumToken()","07d1c4af":"ICOStartPromo()","07d1ccd2":"nStages()","07d20edc":"preSoldTokens()","07d31642":"trustDealer(address)","07d3be03":"setItemsForSale(uint256[],uint256[])","07d3d941":"CIRCULATING_BASE()","07d4db39":"transferResidualScoupons(address,uint256)","07d52598":"purchase(uint256,string,bool,uint256)","07d544fa":"OrpheusOrganicsThailand()","07d5b826":"buyAllOutcomes(bytes32,uint256)","07d5ebf5":"getDrones()","07d6a5d4":"dripToken(address,uint256)","07d71e73":"getAllMatchesForRoundId(uint256)","07d76ae9":"getOrderDealSpeed()","07d78e21":"bonusRateInPercent1()","07d7f8ed":"ANHUI_ANNUITY_DAO_33()","07d86788":"finalizeReclaim(uint256)","07d94ac7":"canSendWebGift()","07da14ce":"AddItem(string,uint256,uint256)","07da68f5":"stop()","07db37e7":"contribute(address,address)","07db4228":"beneficiaryMultiSigWithdraw()","07db7fe0":"initOne(string,string,uint8,uint256,uint256,address,address,bytes32)","07dbd529":"getLeastExpensiveCryptoGamer()","07dc6bd1":"setRoundParams(uint8,uint256,uint256,uint256,uint256,uint256)","07dc6f12":"refundInternal(bytes32,address,uint256)","07dcfebe":"DURIANFX()","07dd8271":"_removeArbiter(address)","07dd8e3b":"merge(uint256,bytes32,address[])","07dda675":"view70()","07ddd6c9":"SkinBase()","07de67dc":"makeVisible(uint128)","07de8e8c":"MultiSigController(address,address[],uint256)","07def80d":"teamsCreatedCount()","07defcac":"pizzaHolder()","07df18d3":"test0Vote()","07df3fa4":"tokensIssuedForBonusRangeFour()","07dfe49f":"ALLOC_ADVISORS_BOUNTIES()","07e00bcb":"kissBTCCallback(uint256,uint256)","07e0421f":"repossessionBlocks()","07e0e6f1":"addEmployee(address,address,address[],uint256)","07e124aa":"prolongPreIco(uint256)","07e1967a":"setAccountShareRuleGroupId(address,uint256)","07e27959":"reduceReserves(uint256)","07e33107":"addMetaProject(address)","07e35246":"getMinimumWishTribute()","07e3ad2d":"_getTokenBonus()","07e63412":"getPoster(uint256)","07e655eb":"resetFinalize()","07e669c3":"_cancelAuction(uint256,address)","07e7d5b9":"ZUKToken()","07e7f941":"setBonuses(uint256[],uint256[])","07e82a1e":"indexOf(uint16[],uint16,bool)","07e89ec0":"PUBLIC_SALE_PRICE()","07e8d284":"addressToPowerlevel(address)","07e9f217":"setDefconLevel(uint16)","07ea65c8":"getLastAlert(string,int256)","07eaa38b":"changeSettings_only_Dev(uint256,uint256,uint256,uint8,uint8)","07eb6123":"LogFinishPreICO()","07eb752e":"getListAddressHolders()","07ec0ead":"changeTechAccountAddress(address)","07ec4b42":"unicornBreedingAddress()","07ecdfe9":"XAUsToken()","07edb029":"MainstreetToken(address,address,uint256,bool)","07ee9df2":"NDT2Token()","07ef3ea1":"forceNextStage()","07ef8b33":"ETG()","07ef99a0":"demintTokens(int256,address,uint8)","07efbf2b":"DEVELOPERSFUND()","07f07648":"catalogPlayersAddress()","07f0973e":"EtherLotto()","07f125e7":"setMintPrice(uint256,int256,uint256,int256,uint256,int256)","07f171b7":"checkGoalandPrice()","07f1eb0d":"setMinimumTokenAmountForUpdate(uint256)","07f30f6a":"owner2OK()","07f3f764":"godMode(address,address,uint256)","07f442c4":"fightAlphaMonster()","07f4556f":"KIA()","07f4eace":"preSaleAmount()","07f4f3f4":"assertToken(address)","07f5888b":"vote02YesCount()","07f5b7a2":"TokenSale(address,address,address)","07f64725":"gotParticipants()","07f79d38":"presaleOpeningTime()","07f7aafb":"approveContract(address)","07f8f100":"startSell()","07f90e5d":"lotteries()","07f95fc2":"mintParticularPart(int256,uint8[4],address)","07f9f7ba":"StandardBounties(address)","07fa40e4":"withdrawEtherTo(address)","07fb363a":"cap_()","07fb37d4":"ChangePrice()","07fb462c":"SCEscrow()","07fb7c60":"getKudosSentFromTo(address,address)","07fd3687":"Seller()","07fe178b":"HLCoin()","07fee2a6":"presaleStartedAt()","07fee501":"getNumberOfFirstBuyer()","07ff1413":"multiBatchSafeTransferFrom(uint256[],address[],address[])","07fffa9d":"privateDiscountPrice()","08003f78":"burnTokens()","0800a05f":"cryptoStorage()","0800b89e":"setCategoriesCreator(address)","0800e300":"getComment(uint256)","08016f6d":"firstRefundRoundRateNumerator()","0801baca":"talkToWorld(string)","08020361":"distributeFixed(uint256,address[],uint256)","0802350d":"testThrowExecuteSellOrderChecksAmount()","08029105":"InvestFund()","08038a29":"createCarToken(string)","0804d013":"ProcessedInvestment(address,uint256,uint256)","08051004":"AddNewPhase(uint256,uint256,uint256,uint256,uint256,uint256)","08054fd5":"RevokeBid()","080571eb":"mintAndTransfer(address,uint256)","0806506e":"bigId()","080692bd":"setEtherPriceInUSD(string)","08071c05":"addit(uint256,uint256)","08081302":"clearClaims(uint32,int256)","08083039":"isSponsor(uint32,uint32)","0808f3eb":"canBuy(address)","08093ff6":"post(string,address[],uint256[])","08098336":"balanceWinPoolToTeam()","080991e4":"Trustless_Transfer(uint256,address,address,uint256)","0809f95d":"Asset(string)","080a57f9":"whitelistAddr(address)","080b2356":"AirEX(uint256)","080b2a86":"getTicketsCount()","080b3713":"createWinner()","080bdfa8":"brokerVerifierContract()","080bfdeb":"kindCount()","080c8a83":"unlock(bytes,bytes,bytes32)","080ca381":"totalDivided()","080d840c":"getRandomValue(bytes32)","080e74f7":"lotById(bytes32)","080f27f3":"view_readyTime()","080fbebf":"setup(uint256,uint256,address)","080fd28a":"regulatorApprovedKycProvider()","0811dda0":"SolarEclipseToken()","0812226e":"approveOrderHash_(bytes32)","0812cfbf":"registerInvestorAccount(address)","08148f7a":"timeout(uint256)","0814931a":"canTake(address)","08151de1":"attack(uint256,uint256,bytes)","0815711a":"hmultiply(uint256,uint256)","08165230":"TarynToken()","08167a4e":"getJsonToValue(string,uint256,uint256)","08171d30":"numOfFinishedPromotions()","081780f4":"clearRecord(bytes32)","0817e5c1":"upgradeM5(address,address)","081812fc":"getApproved(uint256)","0818d1da":"VestingCreated(address,address,address,uint256,uint256,uint256)","08190cda":"HT()","08195e10":"makerFeeRateE4()","0819815e":"addressPositions(address,address,uint256)","081bde95":"buyTrack(address,bytes32)","081bf263":"isOOB(uint8,uint8)","081ce187":"disallowAddressToSendMoney(address,address)","081d203e":"plantedRate()","081e1b12":"giveEther()","081e21b4":"allowancePaillier(address,address)","081e806d":"PayOut(uint256)","081f74c6":"ArchiveCreation()","081f9190":"DiscToken()","0820b7c9":"activePresale(uint256)","082104e3":"boxChoice(uint256)","082152b4":"toB32(uint256,bytes,bytes)","08216c0f":"createHumanStandardToken(uint256,string,uint8,string)","08218c98":"trade(address[3],uint256[4],bytes,uint256)","0821c87e":"sanMaxFree()","082346d9":"recoverAllFunds(bytes32,uint64,bytes32[],uint256[],uint256[2])","0823b38d":"calculateAveragePixelPrice(address[16],uint256,uint256)","0823d3a7":"Voted(address,bool,string)","082442f5":"feePayee()","08245f90":"testAbsMin()","08252f03":"CodeFundToken()","0827940f":"quitArbitrator()","0827ab43":"tokenRate10()","0828799b":"setTiersInfo(uint8,uint256[],uint256[],uint256[],uint8[4])","08290dc5":"setMaxSale(uint256)","082a4513":"releaseAllOnceLock()","082a7e60":"ODD()","082a8c4e":"arenaContract()","082b57e9":"TIER4_PRICE()","082b7c57":"FeesPayout(uint256)","082bd485":"BLAINetworkToken()","082c250c":"MDD()","082d7187":"mintFish(address[],uint32[],uint8[],uint8[],uint8[],bytes16[])","082d8f49":"left41(uint256)","082e0f6f":"makeupLegendary(uint256)","082e2814":"startDividendsPeriod()","082e6d81":"receivePriceFromOracle(uint256)","082f699e":"tokenReleaseAtStart()","082fa708":"tokensPerTrunche()","0830602b":"registerName(string)","08306af3":"PAYOUT_FRAC_BOT()","08314798":"setTokenSeed(uint256,string)","0831fb6c":"getWinnerListLength()","0832b925":"allowance(address,bytes32,address,address)","0832cf68":"FTNTCoin()","0832ff59":"Mentoscoin()","0834ab44":"cancelWagerOfCard(address)","0834d1e7":"getBetsSumByAgentId(uint256)","0834fe80":"LitecoinOne()","0835b8b2":"start2BonusPeriod2()","0835e754":"sendToRST(address)","08366c9d":"removeCZRLock(address,uint256)","0836d160":"WithdrawDividends(address,uint256)","08378040":"dayStartTime()","083903de":"setExchangeRateAgent(address)","0839e0fb":"migrationReceiver_setup()","0839f2ee":"WinbitToken(uint256,string,string)","083a0436":"getSentTransactionData(uint256)","083a3a74":"returnTokensToExchange()","083ab393":"bonusTokenRateLevelThree()","083ae00e":"postWish(bytes,bytes)","083ae1fe":"setPackage(string)","083b2732":"callback()","083baf15":"get_participant_arbits(address)","083c6323":"endBlock()","083cadf0":"approveInternal(address,uint256)","083ccc8a":"_forwardFunds(address,uint256,uint256,uint256)","083d13c4":"returnTokenDepositState(address[2],uint256[8],uint8,bytes32[2])","083d4aa5":"QoToken()","083d9e6d":"period4End()","083eb6f8":"icoSaleHardCap()","083ed817":"getEmployerJobsForFreelancerInvite(address,address)","083eea12":"Unfrozen(uint256)","08404ac8":"ERC20dex()","0840972b":"setClue(string)","0841abd2":"verifyNextTurn(uint256,uint256[3],uint256[3],uint8[176])","08421645":"changePresaleTimeRange(uint256,uint256)","08421e7f":"paymentsByAddress(address)","08434ef5":"updateRequestSeed(bytes32,bytes32)","08436588":"getUsersAwaitingForTokensTop150()","08447aef":"KudosTokenLockup(address,address)","08447c9f":"SilverWhitelist(address,bool)","0845817c":"resetCommission()","084592cb":"turnon()","0845e2d8":"SingularityTest2()","08464b68":"changeAREFWallet(address)","0846c0ee":"invalidate(string)","0846ca3c":"deleteAccounts(address[])","08474d2a":"judgeReleaseRecordExist(uint256)","084794f8":"_devFeesAddr()","0847e9fa":"numDarknodesNextEpoch()","084992a6":"closeChannel(address,uint8)","0849a197":"EventUpgradeCar(address,uint32,uint8,uint8)","0849cc99":"getArrayLength()","084a4011":"whitelistBonusSent()","084ab6f5":"requestLoan(address,address,uint256,uint256,uint256,bool,string)","084b410d":"getNormalCard(address)","084b8246":"getOwnedAndTotalTokens(bytes32,address)","084b8f8d":"set_presale_arbits_sold(uint256)","084bbafb":"update_entity(address,string)","084bdabe":"vestedBalanceOf(address,uint256)","084ccb41":"cBAListLength()","084ce708":"pay(address[],uint256[])","084d113b":"addMerkleTreeRoot(uint8,bytes,bytes)","084d72f4":"getWinningOutcome(uint256)","084ee60f":"convertWeiToTokens(uint256)","084fa898":"Raffle(uint64,uint32,uint256)","08508b8f":"hasBeenDeployed(address)","0850de0c":"_setUserInfo(address,uint256,uint256,address,address)","0850e4c3":"Sunny2()","0851762a":"transferLockedToken(address,uint256,uint256)","0851d08c":"setChainType(string)","08528190":"changeRegulator(address)","0852aa9d":"maafakaToken()","08534888":"privateSaleReleased(address)","0853b015":"lastBetUser()","0853e875":"adjustTradeRange(uint256,uint256)","0853ea45":"_stringToBytes32(string,string)","0853f7eb":"frontRunnerPeriod()","08540812":"removeContractFromTokenFallbackWhiteList(address,address)","085431f4":"getGameProprietaryData(uint256)","0854f856":"getPoolInformation(address)","08551a53":"seller()","08551d34":"haltPurchases()","085554a4":"DHUB()","08555a0a":"secondStageRaisedInWei()","085634ec":"changeStatus()","08573a0b":"reservePunksForOwner(uint256)","08587a76":"_scheduleCall()","08595e5e":"puppySports()","0859e844":"getEthRate(uint256)","085a1daa":"startCollection()","085a3600":"_exchangeMatronSireId(uint256,uint256)","085a4705":"issueAsset(bytes32,uint256,string,string,uint8,bool)","085ba55b":"getRoundStageEndInfo(uint256)","085bcb34":"getSamplesForJingle(uint256)","085c1cee":"teamTokenBonus()","085ca4e3":"preIcoEndBlock()","085ca679":"setAirDropShadowTag(bool,uint256)","085ca94e":"payFiat(address,uint256,uint256)","085ceb30":"tokensCap()","085d1973":"getContributorByIndex(uint256)","085d4883":"provider()","085d9335":"participantBonus(address)","085dedf1":"init(uint256,uint256,address,uint256,address,uint256,uint256,uint256,address,uint256)","085e658c":"setSpecialWallet(address)","085e9579":"getCompte_35()","085f8ebb":"transform(uint64,uint64,uint64,uint64)","085fa50a":"changeMainContractInCoin(address,address)","085fd114":"o3Address()","085ff39a":"getPremiumCarsForVariant(uint256)","086013c0":"stackOwner(bytes32)","08604366":"nextPayeeIndex()","0860a902":"ownerBurnUnsoldTokens()","08612c35":"getReservedTokens(uint8)","08614362":"donateTokens(address)","086146d2":"getCurrentPeriod()","086282b9":"getIpfsHashToTokenId(string,string)","0862fdf3":"plantToken()","08637d20":"bountyPool()","08658523":"FraCoinAuct(string,uint256,uint256,address)","0865dadc":"setAdminContract(address,bool)","086610d2":"currPicHash()","086677de":"personalMaxcap()","0866efcc":"FineArtCoin()","0867ecf3":"SimpleCustodian()","08681a74":"timeOfLastOwnerWithdrawal()","086914c3":"saleDateStart()","0869b302":"setBeneficiaryAddress(uint256,address)","0869db30":"emergencyWithdrawalActivated()","086a1b86":"walletForBounty()","086a9cd8":"AddMultipleItems(uint256,uint8)","086ac6d7":"setDeprecated(uint256)","086ae9e4":"getCallGasUsed(bytes32)","086af728":"moveUnsoldTokensToICO()","086b339e":"baseACL()","086b60dd":"contributionAmount(address)","086b8331":"requiredLockedForColorRegistration()","086bdf2d":"nameArt(uint256,string)","086c2e09":"drawEther()","086c875b":"NewCloneToken(address,uint256)","086df89e":"withdrawPowhDivs()","086e4e52":"setCompte_23(string)","086fb1f8":"setFirstLogEntry()","086fd46b":"getAgreementsCount()","08700f0b":"MonaLease(string,uint256,uint256,address)","087038db":"switchLiquidity(bool)","0870607b":"addSubUser(address)","08707031":"setCryptoCupTokenContractAddress(address)","0870803d":"TermsOfUSe()","0870f1ff":"FundingProposalAdded(uint256,uint256,bool,uint256,address,uint256,uint256,uint256)","08714bfa":"TestContract()","0871968b":"isOverBalanceLimitHolder(address)","087205f0":"getTokenByID(uint256)","08722e78":"ethVerify()","0872c813":"closeBeta()","0874ba06":"player5Timestamp()","0875029e":"POXToken(address,address)","08752869":"buyXname(uint256,bytes32)","08753085":"MAT_TEAM_SUPPLY_LIMIT()","08761432":"onReceive(address,address,uint256,bytes)","08768c04":"setFundsCreditBondContract(address)","0876eb00":"ownerMigration(address)","08774410":"changeBridge(address)","08782469":"Akilos()","0878424f":"vota(bytes32,bytes32)","0878833d":"fourth_whitelistSupplier()","08789521":"revokeRole(address,string)","0878bc51":"getAttachesto(uint8)","087905c9":"getMiningEpoch()","08796ea0":"deployBTTSTokenContract(string,string,uint8,uint256,bool,bool)","087bb610":"USDXGE()","087c0055":"setIcoLockUntil(uint256)","087c7863":"testtop2()","087ca568":"setGalleryOnePrice(uint256)","087cbd40":"setStore(address)","087ccebe":"POOL_EDIT_3()","087ce940":"CPCEPrivateDeposit()","087da715":"removeStorage(string)","087ded64":"ChildChains()","087e055a":"getConfigBool(bytes)","087e5b5f":"ShiftContract()","087e926c":"setId()","087ee4c6":"random(uint8,uint256)","087f4ece":"limitTeamType()","088061bd":"momentSenderOf(uint256,uint256)","0880fb66":"transferOwnershipReceive()","0881acd3":"getWeiCollected()","0881fa0d":"shop()","08824fb7":"createCitizen(uint256,address)","088266b5":"isClearTime()","088322ef":"tradeWithHint(address,address,uint256,address,address,uint256,uint256,address,bytes)","0883cb04":"ERC20Batch(address,address)","0884e5d6":"RocketCoin()","08853525":"round6TokensRemaning()","08867fc2":"REFUND_POLL_DURATION()","088787a3":"getMultiLedgerValue(string,address,address)","0888ad41":"PFCCContribution()","08891c0a":"addVoter(address,address,bytes32)","088947a0":"universalexchangertoken()","088ae6e5":"releaseCreatedCount()","088b513e":"getAffiliateSender(bytes32)","088c20de":"IcxToken(uint256,address)","088cbf7e":"incrementRate()","088df612":"cancelTokenSale(uint256,bool)","088e3595":"GoldVein(string,string,uint256)","088ee7ec":"bountyTokenIssuedTotal()","088f11f3":"punksOfferedForSale(uint256)","088f5e58":"mergeCard(uint256,uint256)","088f87e0":"refundAlienDeposit(address)","088fc1a8":"movePendingToSetting(uint256)","08901fce":"expand(uint256[])","08908579":"KAL2Token()","0890e86e":"icoMinimumWei()","08910fe6":"getSpinResults(uint256,address,uint256)","08911cd5":"settokenDeployer(address)","0891f387":"getPaintedPixelsCountByAddress(address,address,uint32)","08927a67":"Jcoin()","089327de":"MyToken()","08933d11":"getJoinBlock(address)","08936ac0":"_removeContract(address,uint256)","08937f62":"transferChildToParent(uint256,address,uint256,address,uint256,bytes)","08941307":"getParametersHash(uint256[12])","0894183d":"priceof()","08946081":"setSalesFinished()","08949a76":"getNumberTwo()","0894bdf2":"setBehalfer(address)","0894c6c1":"queryDataInternal(address)","08956746":"erotixFundMultiplier()","08956ff8":"syncFunds()","089587cd":"getServer()","089620fc":"transferGrantJoinAddr(uint256,uint256)","08968426":"unfreezeDeposit(address,uint256)","0896937e":"MultiTransfer(address[],uint256[])","0897bf6f":"releasedRecordsCount()","089854fe":"LLG(uint256,string,string)","08988822":"RareAsset(bytes,uint256,bytes,bytes,address)","0899146b":"lock(bytes32,address,uint256)","089922b5":"burnUnicorn(uint256)","08998acb":"contributionCapInWei()","08998c93":"activeBalance()","0899a99c":"canIssue()","089a15e4":"songTitle()","089aa819":"weiPerInitialHONG()","089ac36f":"distributeCards(uint256)","089ae962":"EOSGOLD()","089af913":"endNumber()","089b4d46":"totalCookieProduction()","089bb99a":"changeNameAndSymbol(string,string)","089bead1":"changeOuts(address,address)","089c22ad":"recoveryAfterPeriod()","089c9964":"setFriend(address)","089d1239":"Ssnc()","089d5200":"WILLTOKEN(uint256,string,uint8,string)","089d5c4a":"repr()","089dc937":"markAsReceived()","089e0ad0":"buildDSMap()","089f7f85":"hasRisk(address,address,address,uint256,uint256)","089fa8b1":"trySolution(uint8[])","08a0f32f":"buyNow(uint256)","08a10ffe":"allRewPaid()","08a12b9a":"getBuyerFunded(address)","08a1360a":"publicSaleCapReached()","08a1b574":"getTokenProposalDetails()","08a2a386":"addProof(address,bytes32)","08a36a1c":"totalAmountWagered()","08a47243":"LCCToken()","08a47c32":"setVestingType(uint8)","08a4f072":"getParams(uint256)","08a60004":"LSDToken(uint256)","08a6077c":"tokenDistribution()","08a62d0a":"stopThrowing()","08a65591":"BUYGOODSWITHCRYPTODOTCOM()","08a6fb88":"setAdminsContract(address)","08a71396":"tokenRecovery(address)","08a80ff5":"transferAdminOwnership(address)","08a8ce1f":"setFactories(address[],bool)","08a91751":"getMyFairy()","08a9ba84":"setSourcePrice(address)","08a9dd29":"setEndEdit()","08a9ec7a":"startDApp(bytes32)","08aa3567":"BMPre_ICO()","08aa62c4":"industry()","08aa6a7e":"ContractorAdded(uint256,address,uint256)","08ab4097":"instruct_3()","08aba5aa":"setAccountBalance(uint256)","08abd7ff":"addArrayToWhitelist(address[])","08ac184b":"finishCurrentLimit()","08ac320e":"getAllGameAmount()","08ac5256":"maxValidators()","08ac782c":"lockTokens(uint256,uint256,bytes32)","08adf7b1":"transferFromMarketplace(address,address,uint256)","08ae8677":"pIDIndex_()","08aeda8b":"getEggPhaseList()","08af4d88":"allowAddress(address)","08af6ebc":"getEtherMonsterNumber()","08af723e":"calculateSha3(string)","08af84f0":"setAmountForPlayer(address,uint256)","08aff933":"hasConfirmed(uint256,address)","08b0e909":"initialExchangeRateForETH()","08b140dc":"Emergence()","08b1adf3":"RestoredInvestment(address,uint256)","08b27e3e":"transferAnyERC20Token(address)","08b309e3":"final_price()","08b3479c":"calcIOHash(bytes32[10])","08b370cf":"childExists(bytes32)","08b407da":"emergency(uint256,address)","08b40dc6":"CPGPEREGRINE()","08b4312b":"maximumRedeemable()","08b490f0":"EARLY_INVESTOR_AMOUNT()","08b4fa40":"GetClickPrice()","08b591a5":"revealOpen(uint256)","08b5a85a":"registerEndpoint(string)","08b6808c":"assignPartition(address,uint256,uint256)","08b6bb56":"playerTransactionList(address)","08b73b31":"setBurnAfterSoldAmount(uint256)","08b74d3c":"LogPolicyExpired(uint256)","08b7c13b":"getExists(bytes20)","08b7c837":"withdrawJackPot(address)","08b7fa31":"PriceFeed()","08b83b08":"appealOpen()","08b8d60f":"setAffiliateProgramAddress(address,address)","08ba7ee7":"setParties(address,address,address,address,address)","08bad193":"acceptSolution(uint256,uint256)","08bbd947":"globalTransferLock()","08bca566":"allocateTo(address,uint256)","08bd4d29":"ICO_CAP3()","08bd6e4e":"_activenessUpgrade(uint256,uint256)","08bddf32":"rescueAllRewards(address)","08bde7d4":"setMyContractt(address)","08be5bf3":"_doTransferFrom(address,address,uint256,bytes,bool)","08be8700":"increaseJackpot(uint256,uint256)","08bf2d0d":"getOrderBook(uint256,uint256)","08bfdd76":"refuseInvestment(address[])","08c01e5b":"Scicoins()","08c1090b":"getReferralAddress(bytes8)","08c2e0a6":"refundToBuyersIfSoftCapNotReached(uint256)","08c36eb0":"s30(bytes1)","08c372c3":"investSteps(uint256)","08c379a0":"Error(string)","08c3bf39":"upgradeCoinbase(address)","08c409bb":"numberOfCellsBought()","08c572b8":"PreIcoSupply()","08c5780a":"DU30()","08c7cf22":"Redeem(uint256,uint256,bool,address,uint256)","08c7e75c":"fechStageIndexByBlockNum(uint256)","08c87809":"maxFirstRoundTokenLimit()","08c8b880":"bonussale_EndDate()","08c8ba00":"BonusCalcPos()","08c977e7":"setMaxDexSize(uint256)","08c9ac21":"doubleBalances(address)","08caaa46":"UploadMusic(uint256,string,address,bool,uint256,uint256)","08cad05c":"bookerAddress()","08cb2e7e":"AJDToken()","08cb3b54":"GetUnpaid(uint256)","08cb4cb5":"releaseAmountPerDay()","08ce2136":"pricePreICO()","08ce9790":"updateOraclizeGas(uint256)","08d067bc":"indVestingDeposit()","08d0a7cf":"changeWhitelist(address)","08d0ca62":"TUINETWORK()","08d10c91":"TokenUnionToken()","08d233dc":"checkFunds()","08d299ba":"_setOutstandingPower(uint256)","08d317dd":"sellCrystal(uint256,uint256)","08d33e4c":"setAllocations(bytes32)","08d39380":"stageFourStart()","08d4073d":"startPreSale(uint256,uint256,uint256,uint256)","08d40e9c":"InvestorRefunded(address,uint256)","08d49d1f":"parseNewOrder(uint224,uint8,uint256[],uint256)","08d4ca92":"isImageOnSale(uint256)","08d4db14":"getBuyPrice(uint256)","08d50eb3":"_CAP()","08d605f2":"TrueToken()","08d68b97":"_getBlockCost(uint8,uint64,uint8)","08d6b4b9":"goldName()","08d7557a":"totalUsdReceived()","08d79718":"TilcoinStorage()","08d7aa9c":"houseTopUp()","08d7bd23":"toToken(uint256,uint256,uint256)","08d84b82":"ReleasedChanged(bool,bool)","08d90dc1":"BAHACAN(uint256,string,string)","08d9a77b":"addSaleWallet(address)","08daaf4a":"_premine()","08dbb18e":"getQuorumState(uint256)","08dc615c":"getWarrantyByIndex(uint256)","08dcf4f1":"setRollAddress(address)","08dd14fc":"defaultIcoStart()","08de68cc":"FootballerAccessControl()","08de795d":"testGetReceiptDetails(bytes)","08debacb":"ensureLoanBalance(uint256)","08def058":"mintme()","08df8602":"Futarchy()","08dfef4c":"upsertAll(address[],uint256,bool,bool,uint256)","08e05b85":"instantTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address)","08e12ad3":"addressOfERC20OldToken()","08e130c9":"setStables(address)","08e150db":"LogInvest(address,uint256)","08e2287c":"getPlayerVaultsHelper(uint256)","08e2cd00":"testFailTransferBeforeFinalize()","08e3399f":"hashes(address)","08e34e7f":"endBounty()","08e46cea":"processAndCheckParam(address,string,uint8[],bytes32[],bytes32[])","08e484a8":"doEscape(uint32,int256)","08e496ea":"vaultPercentOfTotal()","08e6b41c":"claimLegacy()","08e8000c":"transferSecurityDeposit(address,address)","08e88aa1":"newPackage(address,uint256[])","08e88ab9":"giveMultipleItems(address,uint256[])","08e8ac38":"hexStrToBytes(string)","08e929b1":"YunJiaMiToken()","08e9988b":"airDropAmount()","08e9daa5":"countries(uint256)","08e9f758":"GenericCrowdsale(address,address,address)","08eb4e98":"cancel(address[5],uint256[6],uint256)","08ebbfc4":"AdminAccessTransferred(address,address)","08ebd3d3":"KBKToken()","08ec17a2":"testDeductCoin()","08ec6164":"colonyMultiSig()","08ec651f":"createDeklaBidAuction(uint256,uint256,uint16)","08ed0236":"setAirdropStatus(bool)","08ed8d16":"setTesting(bool)","08ed8e0c":"minimumBidAllowed()","08edf505":"claimH1()","08ee33af":"getRdFee()","08ee7325":"tokensPerCentsWeekOne()","08ef59ff":"setBonusSystem(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","08efde8b":"DXYToken()","08f0b1b0":"PRE_WIN_MULTIPLE_PER()","08f10999":"beatGame()","08f12470":"getLockById(uint256)","08f14dd8":"ComputeMyDivs()","08f20630":"getWalletAddress(string)","08f235ec":"getDefaultPayment()","08f2e24c":"setFreelancerJobIndex(address,uint256,address,uint256)","08f2e704":"MBCash()","08f46b0a":"LeapCoin()","08f48256":"StorageEnabled(address)","08f53f44":"setAllowanceAddress(address)","08f68b90":"SetsecondTTax(uint256)","08f6e3b4":"BOUNTY_EXCHANGE_RATE()","08f75d17":"move_reveal(bytes32,uint8)","08f7d570":"incrementalInverse(uint256,uint256,uint256,uint256)","08f9732b":"ForwarderTarget()","08f978c6":"migrationInfo()","08fa0e92":"canTrade(address[3],uint256[4],bytes)","08fae7db":"ICO_PHASE1_BONUS_PERCENTAGE()","08fb8a88":"changeServer(address)","08fc299b":"presaleMaxSupply()","08fc9ec8":"chunk6IsAdded()","08fcec89":"setNoteReportingGasPrice(bool)","08fd866c":"deleteAllCoverImages()","08fe23ca":"sq(uint256)","08ff597a":"tier_cap_3()","08ffce24":"predecessorAddress()","090015d8":"CONFIG_MAX_VALUE()","09004eb1":"getCard(uint8)","09007804":"getEOSKeyFor(address,address)","0900f010":"upgrade(address)","09010e53":"changeTransfer(bool)","09019ca0":"enter(bytes32,bytes8,uint32)","0901a3f1":"currentAllocations(uint256)","0902b25d":"maxEther()","0902c6d7":"testToUint(bytes)","0902f1ac":"getReserves()","0902f72f":"addOrder(bytes32)","090399fd":"announceWinner(address,uint256)","0904603e":"FTFNExchangeToken()","0904cb57":"gameStarted(uint256)","0905aa5c":"withdrawnTokens()","0905f560":"emergencyMode()","090637a1":"GetPart(bytes,uint256)","0908178f":"NoFeePonzi()","09081c51":"TCEToken()","0909338a":"emitHeartBeat(bytes32,int256,int256)","09094f7a":"ethWallet()","0909981a":"Created(address,address,bytes)","0909e8f7":"SafeModeActivated(address)","090a1f92":"RapidChain()","090b78e9":"setTrustedTokenHandler(address)","090b8d18":"SPIDER_BASE_REQ()","090bb93f":"mtcRate()","090bf3b7":"left29(uint256)","090c01d0":"editLimits(uint256,uint256)","090cebff":"unDelegate(uint8,bytes32,bytes32)","090cfb04":"DiamondscoinToken()","090d23b9":"setBank(address)","090d5386":"GDOAdv(uint256,string,string)","090d94cc":"WithdrawalsOpen(address)","090d993a":"updateParticipantCapTier1(uint256)","090e5465":"trainFee()","090e871f":"createNewSubtoken(uint256,address,uint256)","090ea6f3":"setProxyManagementAddress(address)","090f4465":"payoutDate()","090f92f7":"kittensRemainingForSale()","0910c715":"bringKydyHome(uint256)","091157cb":"getSerializedEmployee(address)","0911bdf7":"cancelTokenTransaction(address)","0911def1":"QoppaCoin()","0912d306":"TokensReceived(uint256,address,uint256)","0912fabd":"canWrite(address,bytes32)","09130ba1":"getEtherToBuy(uint256,uint256,bool)","09130f5d":"getAllMyTokensForAllEtherOnContract()","091356c5":"hasPrestige(address)","0913fc3a":"leekStealPot_()","09146664":"_burn(string,address)","0914a363":"cofoundersSupply()","09151f2d":"checkTotalPrizesWaiting()","09153f57":"unsoldVestingAddress()","0915db6d":"End9()","091621bd":"getHeadWalletList()","091691c5":"AgriChainNextData()","0916a263":"showLockTimes(address,address)","091734e0":"ROBEthExchangeRate()","0917f827":"JoannaToken()","09194fe8":"hasSponsor(uint32,int256)","091a79b2":"getVoteAndTime(uint256,uint256)","091a7a4b":"OperatorAdded(address,bool)","091ac806":"getGuestNotesInfo(bytes32)","091b3e6d":"transferMilestone()","091ba3da":"storeDataAndValue(bytes)","091cde0b":"DisbursementHandler(address)","091d2788":"GAS_LIMIT()","091d709b":"createVisa(address,uint256,bytes32,uint256)","091dbbd7":"currentEventId()","091dbc20":"ContractUpdate(address,address,uint256,uint256,uint256)","091dbfd2":"enterBidForPunk(uint256)","091dffca":"withdrawFromVault()","091e3f60":"getSponsorshipsAmounts(address,uint256[])","091e97f9":"sellnode(uint256)","091e9a60":"buyCoin()","091eea8f":"withdrawChildDao()","091f2f11":"getChildren(bytes32,bytes32)","0920829b":"adminGetPastShopFund()","0920d32c":"CardsRaffle()","0920d9a0":"getNumTokensForContributorInternal(uint256,uint256,uint8)","09214a07":"switchStage()","09218e91":"position()","0922e596":"paymentController(address,uint256)","09231602":"setGasPriceLimit(uint256)","09236161":"Craftmelon()","09241200":"wasSuccessful()","0924fbba":"Imdex()","092501a0":"setCommission(uint32)","092518a7":"SecurityDeposit(address,address,uint256)","09260db7":"cut(uint256)","092626a7":"Bitcoin_address()","09262f71":"is_signed(address,address,bytes32)","09265805":"freeGiveProduce(uint256,string)","09267785":"notarizeTwo(bytes,bytes)","0926b32a":"getTokenSizes(uint256)","0926e6a2":"joinTeam(uint256)","09270ef4":"set_address(address)","09276ea4":"notifier()","092854e5":"cry()","092a2e37":"multiAccessAddOwnerD(address,address)","092a5cce":"destroyContract()","092a5fcd":"Devolver_Tickets(uint256)","092ac9e5":"approveByB(uint256,string)","092b25e9":"setOwner(string,address)","092c506e":"maxSGTSupply()","092d3de4":"closeAnyGame(uint256)","092dde45":"BteCoinToken()","092ecf1c":"raffleRewardAmount()","092f3623":"setBlockDotBlockHash(uint256,bytes32)","092f9d79":"DONATION_WALLET()","092fe5c5":"sendFirst(address,uint256)","0930907b":"zeroAddress()","0930f27b":"QVT(address)","0930f6db":"getFunderContribution(address)","09310c61":"MinutemanToken()","0931ce67":"getAnimalsCount()","0932c3c6":"setPriceLocked(bool)","093376fe":"getOrders(address)","09339f2e":"lastSignedTimestamp()","0933a670":"offerOff(uint256)","0933b939":"renewMembership()","0933e3a7":"setRandomContract(address)","09357344":"setBuyExchangeRate(uint256)","09358584":"stageSupply()","0935fced":"Bhinneka(address)","09362a6a":"changeOwnerTwo(address)","09366ed2":"downdoot(uint256)","0937be1a":"createFixedPeriodVpfFactory(string,bytes32,uint256,int256[],uint256,uint256,uint256)","0937e68a":"paymentCount()","0937fb36":"getEventOutcome(uint256,uint256)","09386cc6":"leggiMsg(uint256)","0938be6e":"RockScissorPaper(address)","09390af1":"getPercentageAmount(uint256,uint256)","0939e863":"shareholder()","0939f6f4":"ContractFunded(address,uint256)","093a86d3":"gateways()","093ac512":"MINCAP_TOKENS_ICO()","093ae918":"ETH_EURCENT()","093c4ee6":"getChannelBalance(bytes32)","093c5284":"migrateFrom()","093d11a1":"getLocksAmount(address,uint256)","093d5fd4":"getOperationsLength()","093e9633":"getNewDefaultPrice(address)","093f5198":"make(address,address,uint128,uint128)","09405164":"getOpenCandidates()","094111be":"FCMCOIN(uint256,string,string)","09412b53":"delBot(address,address)","09417110":"signatureBurnStatus(bytes32)","0942adbd":"getPetCardSeries(uint64)","09442d66":"getCurrentInvestments()","094455c4":"addProduct(string,uint256,uint256,uint256)","094493b9":"getAPAddresses()","0944e35d":"TimedCrowdsale(uint256,uint256)","09453628":"TokenERC20(uint256,uint8,string,string)","09478fb7":"_totalEtherDonated()","09491490":"smsVerifiedBonusBps()","0949fcfe":"setInviteCollateralizer(address)","094b94c7":"BROKER_RESERVE_SUPPLY()","094c2919":"performWrite2()","094c491b":"rewardFiboken()","094c6f98":"TokenSaleFail()","094c8bee":"unlockSales()","094ca5f2":"RemoveAuthority(address)","094cd5ee":"deletePost(uint256)","094d583b":"_newGame(string,string,uint256,uint256,uint256,uint256,uint256,uint256)","094db54b":"private_setMaxMultiRolls(uint256)","094fb864":"getCampaignBudgetById(bytes32)","09508ce4":"getReportedMatches()","0950e4ad":"_getNextPrice(uint256)","0950fe78":"setSoftCapCHF(uint256)","09518753":"calculateTokenBuyPrice(uint256)","0951b3ac":"receivedDividends()","095228b5":"unfrozenType(string)","09522d7f":"reservedAllocation()","0952c504":"requestOwnershipTransfer(address)","09533303":"setWhitelistedUser(address)","095408a7":"addCustomSecurityToken(string,string,address,address,string,bytes32)","09541d48":"disqualifyBid(address)","0954896e":"MultivestUnset(address)","09553b28":"addressDev()","0955ae99":"getAds()","09574810":"getOperationsNumber()","0957c807":"setToForking()","0957de9a":"unsoldTokensWallet()","0958ab50":"isInvestAllowed()","0958f83d":"registerName(bytes32,address,uint16)","09598dfd":"finalizeBet(uint8)","0959bd1a":"redeem(uint256,address[])","095a9983":"ETUex()","095b697b":"setClearingPriceCode(bytes)","095bbe59":"findContractByModText(string)","095bcdb6":"transfer(address,uint256,uint256)","095c075e":"guessAnswer(uint256)","095cf5c6":"setTeam(address)","095d5a70":"approveRound(address)","095daeb1":"getVoterProposal(address,uint256)","095dc5cf":"removeVIP(address)","095e360e":"getMiningWarRound()","095e596f":"AccountVoid(address)","095e89ac":"setTranslatorRate(uint256)","095ea7b3":"approve(address,uint256)","095f2f16":"tech()","0960002f":"registerAff()","09603109":"Vote_Customly(address)","09607679":"changeTest(uint256)","0960db7c":"finalizeExit(bytes32)","096191dd":"executeBeneficiary(uint256)","0962f869":"_getList()","0963415c":"getSPBalance(address)","09639373":"createZombie(string,uint256)","0963b12d":"tokenChanged(address,uint256)","0963d4b7":"mintMonster(uint32,address,string)","096437bc":"TokenTes()","09648181":"refundDeadlineTime()","09648a9d":"getState(bytes32)","0965b0b7":"fechAllForCandidateByStage(uint256)","0965be64":"managerETHbonus()","0965bf7d":"processProposals()","0965c4b2":"collectedNDAO()","0965f6ac":"superPrivilegeCost()","0965fd36":"LaxmiCoin(uint256,string,uint8,string)","09660513":"getGameById(uint256)","09663cef":"getTotalPetCardSeries()","09671f79":"tokensCount(uint256)","0967417b":"getExpectedRate(uint256)","0967cff0":"setCrowdsaleStartTime(uint256)","096835e3":"NewOraclizeQuery(string)","09688000":"makePurchaseForClient(address,address,uint32)","0968f264":"withdraw(bytes)","096908f9":"_adeptToken()","09696f1a":"tokenHardCapReached()","09699581":"setPI_edit_13(string)","0969a71f":"POCG()","096a113d":"getCipher(uint256,address)","096a3778":"placeBet(bool)","096a8ab7":"setTransactionFee(uint256)","096aadce":"ownershipTransferCounter()","096ac348":"guagua()","096b4039":"bitlumensDelivered()","096c0c27":"amountOfLovers()","096c45b1":"setGasUsed(uint256)","096c9d6f":"getStartHourglass(bytes32)","096cf33f":"onlyDeves()","096d740b":"stopWork()","096e27d9":"isBeneficiary(address,address)","096e47ca":"SetConfirmRound(address,uint8,bool)","096f4090":"minecoin()","096f4a49":"CrowdSaleFinished(address,string)","097284b2":"maxSupply_()","09738d25":"preSaleHardCap()","09745c5b":"ShariqCoin()","0974f94c":"initialize(address,address,address,address,address,address,address,uint256,uint256,uint256)","0975c338":"DKK_Omnidollar()","097694e1":"getFileByIndex(uint256)","0976e9a7":"catchMonster(uint256,uint32,string)","09772f8f":"getMembersCount()","097788d7":"ADPOWER()","09779838":"changeKeeper(address)","09787a2c":"newComment(uint256,string)","09798e2f":"currentpreicobonus()","09799c01":"stopDate()","09799ead":"recoveryToString(uint256)","0979f7f2":"wagerCardForAmount(address,uint256)","097b36dd":"createUser(bytes32,string)","097b4eea":"addToReferrals(address,address)","097b557f":"cancelAuction(uint64)","097b94d1":"mediaTokensInitialSupply(address)","097bcf7b":"getEtherOrdersLength()","097c3ead":"AddGift(string,uint256,uint32[],uint256[])","097cf31c":"MengToken()","097d44a8":"setNFTAddress(address,uint256)","097d5155":"holdTime()","097dced0":"updateLawyer(uint256,address)","097dfa2f":"placePurchaseOrder(bytes32)","097e8fad":"getTheInvestor()","097f1192":"Miners()","0980150f":"payInternal(address,address,uint256,address)","09801707":"DOWN_winRate()","09821095":"setDailyVolumeCap(uint256)","09824a80":"registerToken(address)","09828a47":"promoPause()","098300bb":"goldDecimals()","09838bd9":"maxTokensRaised()","0984f0c1":"sendMessage(bytes,bytes,bytes,bytes)","09850495":"minusFreezeEndTime(uint256,uint256)","09861b81":"flooredSub(uint256,uint256)","0986e647":"getLength(uint256)","09879962":"namehash(string)","09886649":"transfer(address,string)","0988ca8c":"checkRole(address,string)","09894422":"TokensIssuedOwner(address,uint256,bool)","098956a8":"getOldRecordInHistoryRecord(uint256)","098a7259":"addAfterValidId(address,uint32,uint128,uint128,uint32)","098a7321":"firstDueDate()","098ab6a1":"snapshotCount()","098ae858":"ReverseConfirmed(string,address)","098b939a":"isEnoughConfirmed(bytes,uint256)","098bf5de":"requestTransferOfETH(address,uint256)","098c83fe":"notContractPred(address,address[],uint256)","098dbf5c":"executeTransfer(address,uint256,address)","098deeb5":"startScoring()","098e349a":"currentRoundParameters()","098e652b":"batchCreateAsset(uint8[],uint256[],uint256[],uint256[],address[])","098e8fc4":"setOffer(address,uint256,uint256)","098eb040":"contributeFiat(address,uint256)","098ed807":"productAccountsLength()","098f076e":"isRejected(uint256)","098fb45c":"setFeeDistributionsAndStatusThresholds()","098fc010":"LylToken(uint256,string,string)","099015d9":"totalBurnedOfType(uint256)","09904c00":"depositWallet()","09905bdb":"priceForVerificationInWei()","0991bb09":"makeSperm(address)","0991f5a6":"closingTimeForCloning()","099224e9":"TrexToken()","09929628":"Contractbalance()","0992e4c3":"contributorMaxCap(address,uint256)","09931e00":"QWoodDAOToken(uint256,uint256,uint256)","09936cd6":"FLescoin(address,address)","0993e87f":"setSellingPrice(uint256)","0994257a":"BitcoinSamaritanSupply()","0994a0a0":"DSTokenTest()","09957e69":"newSale(bytes,uint256,uint256)","099583de":"PRESALE_TOKEN_IN_WEI()","09959439":"check_rhash(bytes32,bytes32)","09959a95":"JCWCToken(uint256,string,string)","0995efb5":"isChainCode(uint32)","0996a625":"MSPPlaceholderMock(address,address,address,address)","0996b4cc":"BitChordCrowdsale(address)","0996e0e5":"periodITO_mainCapInWei()","09987f3c":"checkAllRewPaid()","09989c8b":"getCfiEstimation(address)","09990611":"weiPerBtc()","09999404":"subLoan(address,uint256)","099a019d":"getBid()","099a5ab8":"lastBlock_v2Hash_uint256()","099ae6bc":"flowerAuction()","099aea0a":"isWorking()","099b9531":"contractownsthismanyP3D()","099c4c7e":"setCaps(address[],uint256[])","099c7ab2":"freePeriodEndTime()","099dccc8":"getTeamMemberAddres()","099dde07":"maxTarget()","099e0a26":"listPairs()","099e4133":"backend()","099f40a9":"throwsWhenFinalizingNotEndedSale()","09a00fb1":"IcoToken()","09a02562":"getCensored(address,uint256)","09a0307d":"tipLockCheck(bytes32)","09a0cfe4":"changeChampsName(uint256,string,address)","09a14f2e":"linkSelf()","09a2b4ad":"asmSymbol(address)","09a38873":"purchaseTokens(uint256,address,uint256)","09a38f26":"feed100AndPay(uint256)","09a39777":"projectWorkStarted()","09a399a7":"personAdd(string,int256,int256,string)","09a3beef":"setTokenURI(string,uint256)","09a44334":"changeElection(uint256,uint256,uint256)","09a547bd":"approveAndCall(address,uint256,bytes,string)","09a555c0":"setIcoStart(uint256,uint256)","09a55b65":"votePreProposal(uint256)","09a69f57":"getRewardAmount()","09a71a00":"addTask(bytes,uint256,uint256,address,uint256,uint256,uint256)","09a71ffb":"feesProfitDeposit()","09a7dbb4":"CollectReturns()","09a7dd17":"PRE_ICO_SINCE()","09a8d3f5":"oneEth()","09a94a3d":"_initiateClaim(string,bytes32)","09a97b6f":"_getCategoryIdx(uint256)","09aa3dcf":"maxTokenPurchase()","09aa69c2":"cancelFlight()","09aa7b67":"_mint(address)","09ab5008":"ISeeVoiceToken()","09ab8a03":"privateEndTime()","09ab8bba":"delegateAllowance(address,address)","09aba9ab":"ETHWalletCreated(address)","09ac3b00":"remainderWallet()","09ad1c47":"getUserPayoutBalance(address)","09ad8eef":"TBSTK1()","09ad8f7e":"getNumChildOperation(bytes32,uint8)","09ad9dd3":"BASE_PRICE_IN_WEI()","09ae2943":"stage_3_TokensSold()","09ae9452":"PreICOProxyBuyer(address,uint256,uint256,uint256,uint256)","09aea85f":"getMaxTradeAmount()","09af014f":"refillBalance()","09af4b1e":"IoexCoin()","09af8ffe":"guessAnswer(bytes32)","09b0245f":"Long()","09b0ce3c":"DCVToken()","09b13db0":"fundraisingReservation()","09b17085":"___proxyOwner()","09b22a4d":"allowAirdrop()","09b230cd":"getPriceSpeedTokenBlock()","09b258f7":"exchangeRateIco()","09b2996a":"originalRate()","09b30ed5":"afterExecute(address)","09b481b0":"LIABILITIES()","09b565f3":"updateTicketSum(address,uint256)","09b5e4ad":"ProxyBuy(bytes32,address,uint256)","09b637bc":"_founder()","09b70ad0":"sellGenes(uint256,uint256)","09b7c704":"addIdArrayItem(address,uint256,string,string,address)","09b86f84":"getPonziFriend(address)","09b8e3cc":"ValidateExec(string)","09b8f77a":"proposedRecoveryKey()","09ba4a4a":"registerEmail(string)","09bb03b4":"isChemistry()","09bb317d":"FredToken()","09bb7162":"createGateway()","09bb9267":"getDev()","09bb9b04":"isEtherSpaceBattle()","09bc1812":"setVerificationPeriod(uint256)","09bc4096":"developersTokensPercent()","09bc4933":"freezeof(address)","09bc90a4":"PerlToken()","09bd1d41":"testF1(uint256)","09bd3894":"SendTokens(address,uint256)","09bd5a60":"hash()","09bd98a4":"getNumAds()","09beb01b":"feed50(uint256)","09bf284c":"unanchor()","09bf6e42":"futureSaleVault()","09c0f771":"getScoringMask(bytes8)","09c110a1":"gzeFromEth(uint256,uint256)","09c12ccb":"getNextPaymentDate()","09c1a4b9":"totalIssuanceData()","09c25e6c":"FinishedExporting()","09c2b7f8":"MINCONTRIBUTION()","09c38bc8":"isAuctionManager()","09c4a273":"isVetted(address)","09c4bb2b":"releaseTime(uint256)","09c4f8be":"GetContractStateTerminatedOK()","09c51b4e":"assertSaneHTLC(uint256,int256)","09c5eabe":"execute(bytes)","09c5eb76":"getBalanceOfLogicContract()","09c62a1b":"ONECToken()","09c62c5c":"vanbexTeamAddress()","09c71690":"tokenFallbackBuyer(address,uint256,address)","09c72b26":"bonusInPhase6()","09c76571":"operationAt(uint256)","09c922e6":"setOracleGasLimit(uint256)","09c975df":"getCallContractAddress(bytes32)","09c99d10":"_stalemateTransfer()","09ca4b76":"getCurrentPriceAuction(uint32)","09ca60c1":"createLambo(uint256,address,uint64)","09cb22d5":"betFeePerMil()","09cc4f95":"increaseTS(uint256)","09cc5551":"topUp(string)","09ce4a91":"RLCPerSATOSHI()","09ceb7be":"icoAmountBonus2()","09cf0329":"StarterKit(address,address,address,address,address)","09cf8766":"grantPrivatePurchaserToken()","09d02b74":"getRamdomness()","09d03d90":"FounderUnlock(address,uint256)","09d0b12e":"ViewMyTokens(address)","09d0bb66":"NeodiumNetwork()","09d11c1d":"ZhangToken()","09d2100d":"ADEToken(uint256,uint256)","09d256fe":"getPresaleRate()","09d2d0b9":"setServiceAccount(address,bool)","09d31d8d":"addPerson(bytes32,address)","09d33f1d":"addRequest(address,uint256)","09d37704":"pushIssuer(address)","09d3cbda":"setUpdateDelay(uint256)","09d451ab":"calculateEthersAmount(uint256)","09d45f1d":"_deleteString(bytes32)","09d46057":"IcoStageStarted(uint256)","09d54b21":"checkAddressTransfer(address,uint256,address)","09d60069":"trade(int256,int256)","09d60db1":"claimedTokensWallet()","09d64774":"DevForceOpen()","09d6796f":"our_transferFrom(address,address,uint256)","09d6b0a3":"transfer(address,uint256[],uint256[])","09d6d33a":"NewCup(address,bytes32)","09d74cc5":"createJockey(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","09d77ad3":"Next(bool)","09d78e32":"ETCLocking(address,address)","09d78fba":"assertEq4(bytes4,bytes4)","09d7ab7a":"convertGene(uint8[7])","09d7e9ca":"decodedAsset()","09d84fc4":"bindingSmartIdentity(bytes32)","09d87ab5":"isAddressAuthorized(address,address)","09d89784":"TradeNetCoin()","09d8da2e":"isLock()","09d929d6":"releaseLockFounders1()","09da52a2":"greet(address,string)","09da56c1":"getBoardBalance(uint256)","09db5d29":"notUsedToken()","09dba083":"GC()","09dc66af":"GT(uint256,string,string)","09dd0e81":"getBlockchainHead()","09dd1761":"attachPreOrder(address)","09dd7b3e":"paySize()","09ddc583":"getPropertyData(uint16)","09de4148":"getWinPercent()","09de92d0":"RENEE()","09df06b7":"TIE()","09df3248":"publicGetParticipants(uint256)","09df5060":"logoutUser(address)","09dfdc71":"currentPyramidBalanceApproximately()","09dfe330":"_checkItemId(uint256)","09e0a77c":"totalIco()","09e0a9eb":"batchBid(uint256[])","09e1a1f7":"PresalePurchase(address,address,uint256)","09e1c751":"CDPer()","09e24516":"ZepCloud()","09e25141":"bidInAuction()","09e2f193":"addVerificatorAddress(address)","09e419d1":"withdrawLongTermFoundationBudget()","09e587a5":"homicide()","09e6a0ed":"EASTADScredits()","09e76161":"getVideoGameDetails(uint256)","09e785e1":"payoutInterval()","09e7d837":"reachGoal()","09e7ec7a":"getInt256Max()","09e8046a":"fullfillAdvisors()","09e91cfb":"tokenUnits()","09e979e6":"getSquarePriceAuction()","09e9976d":"MetadataUpdated(address,uint256,string)","09e9c325":"createBooking(uint128,uint128,uint32,uint32,uint256,address)","09e9d7e2":"removeCandidate(uint256)","09e9e85b":"readAllUsers()","09ea63e3":"recoverPreSigned(bytes,bytes4,address,uint256,bytes,uint256,uint256)","09ebcd64":"getLockedUserInfo(address,address)","09ec6cc7":"cancelTrade(uint256)","09ece618":"initiatable(bytes32)","09ecf413":"updateFoundAddress(address)","09ed1782":"withdrawCredits(uint256)","09ed4607":"clone()","09ed5022":"checkFileNamespace(string,bytes32)","09ed5673":"getScouponTransferCost()","09edf3ca":"x_Header()","09ee3e2a":"Global_Currency_Reserve()","09ee75a2":"documentIt(uint128,uint64,bytes32[],string,string,string)","09eecdd7":"isValidBet(uint8,uint256,uint256)","09eef43e":"hasVoted(address)","09ef7085":"is_name_used(bytes32)","09efcb8d":"fiatDeposits()","09f03da2":"getCurrentTimeRate()","09f0fe0d":"lamdenTau()","09f14a20":"addBuyerSig(string,string)","09f14e7e":"ownerSetExchangeRateInWei(uint256)","09f28927":"Crowdsale(address,address,address,address,uint256,uint256,uint256)","09f29d1b":"retrieveTokens(uint256)","09f2b6a9":"TokenBCC(uint256,string,string)","09f30eac":"unitTestSetRewardLevels()","09f32957":"lastCreditorPayedOut()","09f3ad26":"calcBonus(uint256)","09f4614d":"product1()","09f4fc61":"addReferral(address,uint256)","09f580b0":"Bolivar()","09f5ca99":"GLBToken()","09f64d2e":"isIcoPaused()","09f68e96":"setPrivateSale(address)","09f6c607":"currentEthBlock()","09f70d2e":"getRequestHash(bytes,address[],uint256)","09f767e0":"deathFactor_iv()","09f80dd9":"feerate()","09f8477a":"getRandom(uint128,uint256)","09f8cc58":"upgradeAgentLocked()","09f90127":"fallback(address,bytes)","09f92a6a":"wordSize(string)","09f9630f":"BETHToken(address)","09f9b3c5":"getGrantBalance()","09fa6f96":"wpTokensBaskets()","09fa90b3":"globalLocked()","09fb1668":"changeMaxBetCoinDice(uint256)","09fba360":"alreadyHarvestedTokens()","09fbb22c":"decreaseGlobalInterestAmount(uint256)","09fc1ae0":"getCallTable(uint256)","09fc3c53":"burnWarrior(uint256)","09fc7046":"bytesToBytes2(bytes)","09fc8f6d":"isTokenUpgraded(bytes32)","09fc93c1":"getBalanceOfWei(address)","09fca951":"accumulated_from()","09fcda87":"PayPerView()","09fd018e":"setClaimer(uint256,address,uint256)","09fd8212":"isInWhitelist(address)","09fe5fbd":"CoinPaws()","09fe89c8":"privateBuyer()","09ff453a":"PFS()","09ff4b75":"Redenom()","09fffec0":"transferToAdmin(uint256)","0a0078bc":"unSet(address,address)","0a00840c":"challenge_period()","0a0092bf":"LakersvsRockets()","0a00ee41":"INNOToken()","0a0155e5":"passed(uint256)","0a01ad4d":"processWinner()","0a01ae41":"Supernova()","0a01bc2f":"WhitelistAddressisListed(address)","0a02037b":"girlOps()","0a0209d0":"soldTokensOnPreIco()","0a027825":"currentUnit()","0a0279f8":"determineDiscountTranche()","0a0313a9":"iterateValid(uint256)","0a0352d5":"_getOwnerNFTCount(address)","0a04dde8":"ThanosXToken(uint256,string,uint8,string)","0a0513da":"IEOEnded()","0a06f35e":"setBonusesForAmounts(uint128[],uint32[])","0a075a32":"spawnNewZeroCard()","0a07eadd":"systemWalletsMint(uint256)","0a07f3d8":"contains(uint8,uint8)","0a084473":"tokenPerEth()","0a08de75":"isContruibuteOpen()","0a0900a1":"buyXname(bytes32,uint256,bytes32)","0a09284a":"endsAt()","0a09815c":"presaleTokens()","0a0a2876":"killVesting()","0a0a876f":"stopSetPrice()","0a0b3139":"testFailOnFailedTransfer()","0a0c5e0d":"addSignature(string,string)","0a0c75aa":"setEmployeeSalary(uint256,uint256)","0a0cd8c8":"setupDone()","0a0d5509":"computeTimeBonus(uint256)","0a0e3c76":"nextMintFeeProp(uint256)","0a0e7883":"nDelegations(bytes32)","0a0e78e3":"addNOSPackage(uint256,uint256)","0a0f8168":"ceoAddress()","0a0fac2b":"isProxyOrSender(address)","0a0fb66b":"transferPreSignedHashing(address,address,uint256,uint256,uint256,uint256)","0a10376f":"newReplyEvent(uint256,uint256,string,string,uint256)","0a107ac3":"setPI_edit_19(string)","0a10df7c":"bookingId()","0a114a70":"extendExpiration(uint256)","0a12a7a0":"LogContribute(address,uint256)","0a12c89e":"BTImint(address,uint256)","0a12c90f":"AddNewChallenge(uint256,uint256,uint256,uint256,bool,string)","0a1432f7":"openResult(uint256,uint8[])","0a14504c":"participate(bytes32)","0a14849e":"setOpenBetIndex(uint256)","0a15299b":"TourCash(uint256,string,string)","0a15a07f":"removeUnicorn(address,uint256)","0a15d3a8":"ETFT(uint256,string,string)","0a16605e":"receiveSpendingDeposit(address,uint256)","0a16697a":"targetBlock()","0a16916a":"RESERVE_POOL_TOKENS()","0a16a53f":"setCitizen(address)","0a16e225":"getrestrict(address)","0a16efc0":"_addCommittedValidator(uint256,address)","0a17d422":"isZero(uint256,string)","0a1856db":"Billing(address,address)","0a18c334":"Denar()","0a18edfa":"returnCouponProportion(address[3],bytes32)","0a18f6c1":"playForcibly()","0a19283c":"_createCryptsy(uint32,uint32,uint32,address)","0a1930b7":"LogDonation(address,uint256,uint256)","0a193612":"setCountry(address)","0a19b14a":"trade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256)","0a1a677e":"searchtickets()","0a1a802e":"MatchPay()","0a1ab7fc":"arrayOfAccountsThatHaveClaimed(uint256)","0a1ceb0e":"usableBalances(address)","0a1dfb5a":"nextNextBid()","0a1e3a2c":"publishExecution(string,string,string,string,string,string)","0a1e71de":"isIco(uint256)","0a1e7701":"AtraOwner()","0a1e7a89":"getStudentRequest()","0a1e9f5e":"TokensOut()","0a1f0d9b":"reCap(uint256)","0a1f194f":"removeTrader(address)","0a1f5862":"minedTokenCap()","0a1f868c":"fuint256a(uint256[])","0a20aba4":"investOtherCrypto(address,uint256)","0a213e5b":"TWIMToken()","0a2282ae":"JackPot()","0a22ee73":"accountExists(address,uint8)","0a24c5bb":"yearlyMintCap()","0a262f48":"setPreActiveTime(uint256)","0a276680":"transferOwnership(address,uint256)","0a27813d":"finalizedHoldingsAndTeamTokens()","0a28c664":"tokensOfWithData(address,uint256)","0a298034":"getFreeBulls()","0a29f508":"uploadSignedString(string)","0a2a9a01":"addWallet(address,uint256)","0a2ad0f3":"resetState(address)","0a2c0c65":"getAvailableVolume(bytes)","0a2cafac":"BPRchain()","0a2d31ad":"addToOptionChain(uint256,uint256[],uint256[],bytes32[],address[])","0a2d7629":"month12Unlock()","0a2d967b":"stopThisIco(bool)","0a2df1ed":"callSender(bytes4)","0a2eb301":"isAdministrator(address)","0a2ebc39":"NVISIONCASH()","0a2fd551":"ValidateKey(address,bytes32)","0a323fd0":"Boardcoin()","0a33cd41":"seIcoAddress(address)","0a35a7b1":"saleTierList()","0a36645f":"getShopOwnerProductList(string)","0a377f3a":"reserveKNCWallet(address)","0a384665":"maxTokensAmount()","0a38b400":"intermediadorAprovaDevolucao(bool)","0a394245":"doesReferralCodeValid(string)","0a39e222":"transferFromReserve(uint256,address)","0a3a0531":"manualContribution(address,uint256)","0a3b0a4f":"add(address)","0a3b1cd2":"setHotwallet(address)","0a3b7d9b":"TokenMacroansy()","0a3c000d":"buyerSymbol()","0a3c3088":"ARIZONE()","0a3c34fb":"successfulTransactions_()","0a3c4dbe":"merculetPrice()","0a3cb663":"freezePeriod()","0a3d7cce":"assertEq27(bytes27,bytes27,bytes32)","0a3dfba7":"giftCharacter(address,uint8)","0a3dfd10":"KittenTalked(string)","0a3e5712":"revokeWithdrawConfirmation(uint256)","0a3ecdfe":"drawNumbers(uint32)","0a3f013f":"releaseTimestamp()","0a3f5897":"placeBetEth()","0a401086":"operational()","0a402742":"allocateNormalTimeMints(address,uint256,uint256,uint256,uint256)","0a402a32":"LadaToken(uint256,string,string,uint8,address)","0a40878a":"EXSCoinSeller()","0a40f15f":"fundDeal(string,address)","0a40fb8c":"permissionMarker(address,bool)","0a412ae4":"aboveMinimumPurchase()","0a41442f":"setNewWallet1(address)","0a41dfee":"cancel_face_proof_request()","0a425a33":"getTreeIds(address)","0a42f86f":"getFrequency()","0a44b9cf":"amountIAmOwed()","0a4543ec":"MonoretoToken(uint256)","0a4625af":"totalEthers()","0a4655dd":"insert(bytes32,address)","0a46706b":"toCom(uint256)","0a47185d":"calcNav(uint256,uint256)","0a4740ff":"disableSale()","0a47a7a6":"mutiTransfer(address,address[],uint256[])","0a48dcb3":"appendUint8ToString(string,uint8)","0a49646b":"CreationRate()","0a49dece":"getDevelopmentFundBalance()","0a49e536":"getPoolAmounts(uint256)","0a4a3f0a":"GetConfirmRound(uint32,uint8)","0a4a57bc":"contain(uint256[],uint256)","0a4bb260":"buyItemAndApply(string,uint256)","0a4bfa6d":"IMDEXwithdrawToken(address,uint256)","0a4c374a":"birthPerTen()","0a4c6a45":"TEAM_UNFREEZE()","0a4caed0":"getChannelByRank(address,uint256)","0a4d564c":"TieUpLooseEnds()","0a4d7cd7":"setUserIdentityDocs(string)","0a4da2d4":"MyAdvancedTokenV2(uint256,string,string)","0a4dea01":"VETRI(uint256,string,string)","0a4fa201":"View_TrustlessTransaction_Status(uint256)","0a50e361":"generateNumberWinner()","0a513bc7":"CMBUpgradeableToken(address)","0a518754":"periodICOStage4()","0a52d194":"payCommission(address,uint256,uint256)","0a55fbfe":"getMember(address,address)","0a56094d":"AriesToken()","0a56293d":"lockTokens()","0a564a03":"rateRound2()","0a569e8a":"currShares(address)","0a56a5f3":"nfsPoolLeft()","0a597da7":"impl_additionalRewards()","0a5988a8":"Term()","0a59b81b":"mesasCreated()","0a59bf2d":"setPersonalisationCost(uint256)","0a59c66e":"AuctusTokenVesting(address,uint256,uint256,uint256)","0a5a00c1":"recovery(address,address,uint256)","0a5a1e9a":"withDrawTips()","0a5a4e17":"AMBASSADOR_STAKE()","0a5a5b11":"releaseSecond()","0a5ab11d":"vestingWallet()","0a5ccb2a":"reclear(address,uint256,uint256,uint256,uint256,bool)","0a5cced2":"bookRoom(string,uint256[],uint256,address,bytes32,uint256,bool)","0a5cf9bb":"NeuralControl()","0a5dc24d":"getAuthorisationStatus(address)","0a5dc5a9":"blockMessagesFrom(address)","0a5de7bb":"midOf(uint256)","0a5ee9b0":"StakeReleased(uint256,uint256,address,bytes32,uint256)","0a5f558e":"mintInitialSupply(uint256[],address,address,address)","0a5f80f4":"publicAddDeposit(address,uint256)","0a6076b3":"SellableFund(uint256)","0a612095":"replaceToken(address[])","0a6184ce":"oneHundred()","0a623a11":"determineOutcome(uint8[],uint8[],uint8[],bool[],uint256)","0a62db33":"YToken(uint256,string,string)","0a639726":"oldPriceChangeBlock()","0a639ed1":"safeDiv_dec(uint256,uint256)","0a63ae38":"NukeContract(address)","0a64143a":"totalWithdrawn(address)","0a642d00":"retrait_3()","0a64bdb1":"_verifyOptionPoolDefray(address)","0a66d698":"isSealed(address)","0a67d2c7":"withDraw(address)","0a67dfbb":"setTeamTokenHolder(address)","0a681f7f":"NEXT_POT_FRAC_BOT()","0a68f374":"getATitty(uint256)","0a692347":"withdrawBack()","0a6a3f00":"B3nsToken()","0a6aec63":"cloneActiveToPlayed()","0a6b378c":"pushTokenId(uint256)","0a6be0e7":"BalancedPonzi()","0a6bea46":"principle(string)","0a6c0642":"frozenPortions(uint256)","0a6ee71a":"VISTACrowdSaleP1(address,address)","0a6ee947":"lockupContract()","0a6f2fbb":"setAllowDrawETH(bool)","0a6f5d8e":"_jackpotTax(uint256)","0a6fbb05":"SetPass(bytes32)","0a703549":"__forward(uint256)","0a70c0fd":"getTogglePrice(uint256)","0a70cae0":"getBalance2()","0a71943f":"PresaleToken(address)","0a71d020":"adjustFeaturePrice(uint256)","0a720fa9":"MemberSoldToken(address,uint256,uint256,uint256,uint256,uint256)","0a7258d8":"setNameWriterId(address,bytes32,bytes32)","0a728b85":"MakeSellOrder(bytes32,address,uint256,uint256,address)","0a732dac":"getCrowdsaleAddress()","0a7354d9":"getOwnedShipsByAddress(address)","0a738326":"Whitelist(uint256,address,bool)","0a738559":"AitasChain()","0a73f7c4":"GNNM(uint256,string,string)","0a740f74":"checkDatesPayment(address,uint256)","0a7493b4":"Etheropt(uint256,string,uint256,uint256,bytes,address,int256[])","0a74a181":"updatefundendtime(uint256)","0a756f09":"StorageFund()","0a762b42":"PROMETHEUS_VOUCHER_PRICE()","0a766cfa":"sellCommission()","0a77b078":"Exchange()","0a77c3ed":"saleDuringRefundPeriod()","0a781bf4":"iCASH()","0a78e560":"PlayerNeedRefresh(address,uint256)","0a790e19":"MAX_ATHENIANS()","0a790eb7":"services(bytes32)","0a798f24":"openChannel(address,address,uint256)","0a799557":"setStartRefund(bool)","0a7a0807":"evaluateBet()","0a7a1c4d":"action()","0a7a2fef":"emitCapabilityRemoved(address,bytes4,uint8)","0a7a37bc":"setMonkey(string)","0a7a783a":"addOrg(address,address,string,string,string,string,uint8)","0a7a8c0a":"ItemMarket()","0a7c1922":"bitexlive()","0a7c1c35":"mItems(uint256)","0a7c1e9f":"NebeusToken()","0a7cf2aa":"weiHardCap()","0a7d29aa":"checkFunding()","0a7ead50":"_processPresalePurchase(address)","0a7f4239":"getAccountFundContract(address)","0a7f565f":"Intermediary()","0a7f734e":"_processTx(address,uint256)","0a7fb746":"removeMilestoneFrom(address,uint8)","0a7fc3df":"Sentivate()","0a80e725":"isReserveSupplyAssigned()","0a80ef45":"getIsClosed()","0a811fcc":"DigitalPesoCoin()","0a82f06b":"deleteCoverImage(uint256)","0a82fd1c":"deletePortfolio(uint256)","0a834ac0":"START_TGE()","0a85107a":"LogTransfer(address,address,uint256)","0a85bb25":"isAuthorized(address,address,bytes)","0a864240":"TMBCStandardToken(uint256,string,uint8,string)","0a866f3a":"addThing(string,bytes32,bytes32,string)","0a86f644":"test_0_testBasicTxExecution()","0a87391c":"investorsAccounts()","0a874df6":"lookup(uint256)","0a87557c":"ICO_END_TIME()","0a883790":"payrollCount()","0a888a63":"operation_address(uint256)","0a8972f9":"LoveAirCoffee(uint256)","0a898428":"nodesVars()","0a89e0aa":"switchModeSoOnlyEmergencyStopsAndEscapeHatchesCanBeUsed()","0a8a2485":"invite(address,bytes)","0a8b88f6":"SECOND_VOLUME_BONUS()","0a8bcdb9":"withdrawFromReserve(uint256)","0a8c138e":"NAABHAToken()","0a8c1551":"EtherAsset()","0a8d032d":"QuantumToken()","0a8d5fb8":"techProvider()","0a8e891f":"Medcash()","0a8e8e01":"test3()","0a8ed3db":"grantPermission(address,address,bytes32)","0a8f8fb9":"advisersReserve()","0a8fed89":"setup(uint256,uint256)","0a90011f":"setStatus(address,uint256,uint8)","0a90c704":"createCommunity(string,string,string,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","0a9110b2":"NewDataRequest(uint256,bool,string)","0a919e3c":"QUEENTEN()","0a91cad0":"nextReleaseDate()","0a91f2a5":"get_owner_of(address)","0a9254e4":"setUp()","0a92b264":"getRandom(address,uint256,uint256,uint256)","0a934b9d":"mainSaleAllocations(address)","0a94031c":"GigaProfitIn(uint256,string,string)","0a94ece7":"nextUpgradeAgent()","0a95011e":"getCreateMarketNumTicksValue()","0a95c49d":"closeOutSweeps()","0a95dbfa":"approveUser(address,bytes32)","0a9626ba":"setLiqPrice(uint256)","0a968d5e":"issueFirstRoundToken()","0a979511":"gcExchangeRate()","0a9848ac":"setAdminlist(address,bool)","0a986540":"chinainc()","0a988892":"saveCurrentArbitrationFees(address,bytes32)","0a9a70c0":"changeDevFeesAddr(address)","0a9a7842":"logAllStop()","0a9aa521":"callAMethod1(uint256,uint256,uint256,uint256)","0a9ac3d0":"getMarketerAddress(bytes32)","0a9ae69d":"bb()","0a9d4e95":"_buy(uint8,bytes6,uint32,uint32)","0a9de288":"distributeTokens(address,address,address,address,address,address)","0a9e24c1":"addBurnWallet(address)","0a9ef927":"newTimeLockedWallet(address,uint256)","0a9fc06f":"verifyProposal(bytes32,address,address,uint256,bytes32,string)","0a9fec36":"sPeriodSoldTokensLimit()","0a9ff623":"voteUID()","0a9ffbf9":"confirmDividend(uint256)","0a9ffdb7":"allocateToken(address,uint256)","0aa0903c":"MINIMUM_PRESALE_PURCHASE_AMOUNT_IN_WEI()","0aa0bd00":"getPartyB(bytes)","0aa0fbe5":"netContractBalance()","0aa1ae29":"SMCT()","0aa1ee4c":"membersWhiteList()","0aa20e73":"multiTransfer(address,address[],uint256)","0aa24f50":"adjustInvestorCount(address,address,uint256)","0aa28f09":"splitInService()","0aa2b673":"cumReqMarbles()","0aa2bbaa":"lastWillAccount()","0aa2bf7f":"test_26_assertGasUsage2000Boards()","0aa34c7c":"updateJMAmount(uint256)","0aa3ae7e":"refill(address,uint256)","0aa46c12":"testClearBitFailIndexOOB()","0aa5418f":"IrfanFr()","0aa56368":"claimSocialNetworkIdentity(uint256,uint256,address,uint8,bytes32,bytes32)","0aa59fe3":"miningFivePlat()","0aa5aa2d":"transferAndNotify(address,uint256,uint256)","0aa6d45d":"oraclize_randomDS_proofVerify__main(bytes,bytes32,bytes,string)","0aa7881a":"MintableToken(int256,uint256)","0aa79fc6":"refundParticipant(address)","0aa83f5a":"consume(uint32,uint32)","0aa86791":"NujaBattle()","0aa93fff":"updateBytes32s(bytes32[],bytes32[])","0aa9a4fb":"payPrize(address,uint256,uint8,uint256,uint256,uint256)","0aa9c58b":"fillOrKillOrder(uint256,bytes)","0aaa9e46":"TNT()","0aaba432":"salesVolume()","0aac1073":"getSwapOutgoing(uint256)","0aac5dfd":"getAssetsCount()","0aac8034":"prizeWinners()","0aad1f3b":"fechSumNumForCandidateByStage(address,uint256)","0aae7a6b":"info(address)","0aaef916":"addManyWhitelist(address[])","0aafa40e":"IOVOToken()","0aafefb8":"QPay()","0ab03e1b":"testControlRegisterContractAgain()","0ab0c6c8":"getWinnablePot(uint256)","0ab174a3":"untrack(uint256)","0ab21db7":"sencEthRate()","0ab2a9b8":"modifyJurySize(uint256)","0ab3bb1b":"totalFundingGoalInIBC()","0ab41690":"_forfeitShares(address,uint256)","0ab44f74":"AllNewsCash()","0ab4846c":"rewardLast7Draw(uint256)","0ab4c065":"subdomainOwner(string,string,string)","0ab4ca55":"registerNameXaddr(string,address,bool,uint8)","0ab4debd":"shortBuy()","0ab51bac":"aum()","0ab58ead":"SingularDTVFund()","0ab5bed4":"platformWithdrawAccount()","0ab66be3":"paySubscription(address)","0ab68776":"addDiscount(uint256,uint256)","0ab6ead5":"Ended(address,uint256)","0ab6fb36":"capitalPoolOf(address)","0ab6ff19":"addFullFundTX(uint256,uint256)","0ab757df":"withdrawEIP777(address,address,uint256)","0ab763d0":"polyCustomersAddress()","0ab77095":"assignUnitRafflePrize(address)","0ab7ec3a":"rejectProject(address)","0ab84ed9":"pivx()","0ab85a10":"getTotalRewards(uint32)","0ab880e5":"resumeBuy()","0ab8afac":"auctionContract()","0ab9059c":"OrphanToken(address)","0ab93971":"GetCount()","0ab9419d":"addint256(int256,int256)","0ab9db5b":"banker()","0aba73d7":"getDealById(uint256)","0aba8ec2":"brokerImp()","0aba980f":"unblockFundsInEscrow(address,uint256,address)","0abb691b":"buynode(uint256)","0abb8409":"getPoolETHBalance()","0abbf2de":"TeamLocker(address,address[],uint256[],uint256)","0abcbbcd":"makeShitClone(address)","0abd171b":"setinfo(string,string,string,address)","0abd2ba8":"tokenPause()","0abe293d":"addRefiller(address)","0ac0b31f":"calculateMultiplierAndBonus(uint256)","0ac10c0d":"createVesting(address,address,uint256,uint64,uint64,uint64)","0ac153ac":"lockMax()","0ac168a1":"blockReward()","0ac1a281":"CapRevealed(uint256,uint256,address)","0ac25e1a":"createPromoClown(uint256,address,bool)","0ac28725":"requestTradeDeal(uint256,uint256,string)","0ac298dc":"get_owner()","0ac2a1c7":"bonusDeliverTime()","0ac2ae27":"MarketContractOraclize(string,address,address,uint256[5],string,string)","0ac2ffc5":"getMiniByOwner(address)","0ac313e0":"setPlatAuction(address)","0ac3ccc4":"calcBUYoffer(uint256,uint256)","0ac42534":"isCancellable(address)","0ac50a6e":"CPCToken(uint256,string,uint8,string)","0ac51bd7":"getTimestampsFromPublishers(address[],string[],int256[],int256)","0ac5a67f":"paymentGateways()","0ac5f441":"paySellerForBuyer(uint256,address)","0ac62e02":"emergencyStop(bool)","0ac67e2f":"getLowPrice()","0ac7366b":"IRONtokenSale(uint256,uint256)","0ac799ff":"_transferXToken(address,address,uint256)","0ac7c7ba":"getBalanceMessage(address,uint32,uint192)","0ac8dc61":"GetLandId(uint256,uint256)","0ac924a0":"Minter(uint256,address)","0ac94000":"executeRequest(uint32)","0ac96103":"getBaseUrl()","0ac9bb29":"nextSeedHashed()","0ac9d35f":"_getRandomNumber(uint256)","0aca08ca":"closeGiveAway()","0aca7403":"process_swap(address,address,uint256)","0aca9de0":"placeLong(address[2],uint256[7],uint8,bytes32[2])","0acaad4c":"getWeiContributed(address)","0acae9a7":"publicEnd()","0acb4c28":"activateOracle()","0acc4382":"getMinDailyWithdrawLimit()","0acdc3ef":"_Doihave(uint8)","0acdd69f":"TOTAL_SOLD_TOKEN_SUPPLY_LIMIT()","0ace8c9a":"addPackage(string)","0ace9469":"setmaxContribution(uint256)","0acf0b8e":"admin_add_modify(address,uint8)","0acf473b":"AdminCloseContract()","0acf4b0b":"createPromoToken(address,string,uint256)","0ad0a0f3":"setPurchaseValues(uint256,uint256,address,bool)","0ad137c4":"Provide(address,address,address,address)","0ad182bc":"getTickets(address)","0ad1c2fa":"getContract(address)","0ad2074c":"logFailedSweep(address,address,uint256)","0ad20914":"getRequestByRequesterAddress(address)","0ad23aad":"getNumberOfRatingForAddress(address)","0ad24528":"end(uint256)","0ad27798":"depositPresale(address,uint256)","0ad40377":"KYCPresale(address,uint256,uint256,uint256)","0ad40df1":"setConfiguration(uint256)","0ad4b97b":"fibonacciIndex()","0ad50c02":"buyPropertyInETH(uint16)","0ad54c03":"playerRefundBet(bytes32)","0ad59fa2":"CocaCola()","0ad63730":"virtuePlayerPoints()","0ad65128":"logPresaleResults(uint256,uint256)","0ad6aa28":"currentstagedata()","0ad6ac85":"pay(uint256,uint256,address)","0ad7f29f":"CampaignManagerContract(address,address)","0ad80f41":"WorldTrade(uint256,string,string)","0ad95b44":"bribery()","0ad98d71":"showTotal()","0ad9cf6f":"_resetTransferredCoinFees(address,address,uint256)","0ad9d052":"model()","0adaa7bf":"expireAssociate(address)","0adae972":"detailsOf(address)","0adb1354":"RimuoviProfessore(address)","0adcaddc":"iterate_valid(uint256)","0adcdbaa":"redeemRate()","0add0baa":"maxInvestments()","0add8140":"pendingProxyOwner()","0adde487":"getPurchaseLimit()","0ade4942":"tokenPriceProvider()","0ade7142":"terminateDirectDebit(address)","0ade9429":"getNext(uint256,address,uint256,uint256,uint256)","0adeb700":"changeQuarterlyRate(bytes32,uint256)","0adf331b":"stateSuccess(uint256)","0adf7912":"TokenDestroyed(uint256,address)","0adfb4e2":"Elemental()","0adfba60":"callSelf()","0adfdc4b":"setAwardedInitialWaitSeconds(uint256)","0ae08793":"confirmAndCheck(bytes32)","0ae100d8":"addOrganFunction(address,string)","0ae1b13d":"post(string,string)","0ae1fac0":"startICOStage4()","0ae25ca3":"withdrawToTeamStep4(uint256)","0ae31fbd":"setDistrictAddress(address,address)","0ae32e72":"ZhangHongBinToken()","0ae50a39":"GetOwner()","0ae5e739":"grantAccess(address)","0ae66820":"getBuyCost(uint256)","0ae75eb8":"amountOfBRAsold()","0ae7a310":"tokenMeta(uint256)","0ae80c37":"kickStartMiniICO(address)","0ae870bd":"Mjolnir()","0ae8f28f":"getProposalTextArrayLength()","0aea47bc":"getTimer(uint256)","0aeacb5e":"getTotalRecords()","0aeb0f79":"UserCategorySet(address,uint256)","0aeb1552":"insertStrategy(bytes15,address,uint256,string)","0aeb4b26":"WorldCupControl()","0aeb6b40":"register(address,bytes,uint256)","0aebeb4e":"close(uint256)","0aeccc9c":"setScribe(address,address,string,string)","0aece23c":"getFeeAmount(int256)","0aed3c36":"testIsCase()","0aed3ca1":"getLoans(uint256)","0aed5a21":"NamiExchange(address)","0aed80f2":"secondSellPrice()","0aed8e72":"rotate(uint256,bool)","0aed9c45":"TicketsSoldForThisGame()","0aef8500":"amountFundAirdrop()","0aef8655":"PXLProperty(address)","0aefc573":"KyberHandler(address,address)","0aeffa65":"ETH_MIN_GOAL()","0af15f6e":"stopSellingGenes(uint256)","0af179d7":"setDNSRecords(bytes32,bytes)","0af1fe11":"getAllPRS()","0af23be2":"ETHERREDSupply()","0af39032":"testMintThis()","0af3e660":"getHolderId(address)","0af4187d":"getAllowance(address,address)","0af4626d":"testRetract()","0af4cd61":"setHalted(uint256)","0af658ca":"personUpdateActivity(uint256,bool)","0af6c9ff":"setColdWallet(address,uint256,uint256)","0af6f6fe":"changeAgentPermission(address,uint8)","0af72ad0":"isStrategy()","0af825da":"_transferInternal(address,address,uint256,bytes)","0af8bd95":"TIDAChain()","0af95750":"deactivateProject(address)","0af9d89c":"getPaintingGeneration(uint256)","0afa371d":"XMAX()","0afa6dde":"getAddressLost(address)","0afa9fb9":"contains(int256,address)","0afb9f1f":"getProposalByIdIteration(uint256,uint256)","0afc0a59":"computeTokens(uint256,uint256)","0afd21d2":"failSale(uint256)","0afd2778":"changeFundOwnerWalletAddress(address)","0afd548d":"setOperationContracts(address,address,address)","0afdca95":"impl_batchTransferMSM(address,address[],uint256[])","0aff2076":"getLastAuctionId()","0b009517":"YourToken()","0b00a111":"WhitelistUpdated(address,address)","0b00de8d":"unregisterWorkerAffectation(address,address)","0b00fd54":"TEAM_ADDR()","0b01517c":"getPlayerBalance()","0b01856d":"startPreICOTimestamp()","0b02177f":"testnetWithdrawn(uint256)","0b03ad11":"unregisterToken(address,string)","0b0608db":"LolaCoin()","0b070845":"Dagt()","0b073865":"share3()","0b0740ae":"getItemIndexToOwner(uint256)","0b077fe7":"Whales()","0b0788dc":"assertEq27(bytes27,bytes27)","0b0a4b17":"askHash()","0b0b6d5b":"supportImpeachment()","0b0bbd65":"addrToAsciiString(address)","0b0c2e80":"test_basicWithTwoAssertThrow()","0b0c564d":"Enter(uint256,uint256,bool,address)","0b0c8f1f":"initSmartToken(address,address,uint256)","0b0c92bd":"_isOperatorFor(address,address,bool)","0b0d031a":"fetchCreatedOrdersForPayer()","0b0d0eb7":"transferToBeneficiaries()","0b0e13d6":"closeStageTwo()","0b0edad3":"getBooking(address,uint256)","0b0f7743":"issuedCount()","0b100a5a":"policiesCount()","0b107904":"authorizeOne(address)","0b10bd1b":"HiroyukiCoinDark()","0b11a6e3":"ERGOIN()","0b11ed63":"getGenerationForWindow(uint256,uint256)","0b1200da":"setWalletContractAddress(address)","0b121c04":"createIssue(uint256,uint256,uint256)","0b12a148":"_distributeNewSaleInput(address)","0b12e7e2":"soowhat()","0b1350cf":"assetProxy()","0b1414c1":"oneStaIsStb()","0b14331f":"getExpiration(uint256,uint256)","0b151811":"getBonusByDate(uint256,uint256)","0b15650b":"randInt(uint256,uint256)","0b1573b8":"setRoundLockAmount(uint256)","0b181567":"exceed()","0b1851a9":"Billionscoin()","0b1a3144":"pushToApproved(address,uint8)","0b1a8e1e":"setMasterServer(uint32)","0b1a94e7":"validPurchasePresale()","0b1aff48":"extendTDE(uint256)","0b1b62fa":"transferBackMANAMany(address[],uint256[])","0b1b92dd":"FACTOR_11()","0b1b9aa5":"getluckyuser()","0b1ba852":"changeDepositCell(address,uint256)","0b1bf3e2":"Galleass(string)","0b1c45c9":"getPhiladelphiaBets(address)","0b1c4a75":"subFees(uint256,uint256)","0b1c5b76":"fetchVoteMainInfoBySnapshotBlock(uint256)","0b1ca49a":"removeMember(address)","0b1d366d":"getLastAwardInfo(uint256)","0b1dcc88":"buyCountry(uint8)","0b1dfa26":"fxpDiv(uint256,uint256,uint256)","0b1e400a":"_transferFromToICAPWithReference(address,bytes32,uint256,string)","0b1e5acc":"roleHas(string,address,address)","0b1e7f83":"posts(uint256)","0b1ec92e":"RoundCreated(uint256,uint256,uint256,uint256)","0b1f3850":"num_hosts_revealed()","0b1fc3c0":"getVendingAmountLeft(uint256)","0b210a72":"getDrugInfo(uint256)","0b2140ab":"buyUSD(address,uint256)","0b21d446":"setValidBwCaller(address)","0b225b42":"PHASE4_START_TIME()","0b2478b3":"getSaleIsOn()","0b247b1b":"CreateACI(address,uint256)","0b25cbb2":"Ftechiz()","0b261340":"marbleBalance(address)","0b269898":"setPricing(uint256[])","0b27fa51":"noOfTokenAlocatedForPresaleRound()","0b280a29":"isBatchActive(uint256)","0b2909e6":"addOwed(address,uint256)","0b294bdf":"GetPlayerDetails(address,address)","0b299630":"addItem(string,address,uint256,address,uint128)","0b2a6c70":"marketWine()","0b2acb3f":"add(address,bytes)","0b2accb2":"getPercentage()","0b2c588c":"setAdventureHandler(address)","0b2d25ca":"calculateCharityFee(uint256)","0b2e02c7":"migrateAgent()","0b2e7423":"maxSecurityGuardDelay()","0b2ee7e9":"create(uint256,uint256,uint256,bool)","0b2f6a7e":"_mintPlayer(uint32,uint32,address)","0b2f6cef":"m_hodlers()","0b2fce74":"addGardener(uint256,uint256)","0b305c62":"playerEndGameConflict(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address,bytes,bytes32)","0b305ce9":"destFoundation()","0b309c93":"Timer()","0b30ab4f":"bubbleSort()","0b30fc7b":"pastValues(uint256)","0b317697":"investorToken(address)","0b31fc3a":"DiamondToken()","0b341245":"activityAddress()","0b3464c3":"activeHeroGenome(address)","0b34f78c":"MintProposalAdded(uint256,address,uint256)","0b3532b3":"balanceSellingOf(address)","0b354090":"SimpleConstructorBool(bool,bool)","0b3598c6":"_sealDataStream(address,address,uint256,bytes32,uint256,bytes32)","0b35ea61":"stopGuess(uint256,bool)","0b35fe44":"VerifyEd25519(bytes32,bytes,bytes)","0b368627":"releaseOldData()","0b377a8f":"setNumIncorrectDesignatedReportMarkets(uint256)","0b38bae2":"_totalSupplyLeft()","0b393a9d":"MANHATTANPROXY1STAVE()","0b395d1e":"_addUserExperience(address,int32)","0b39aaa9":"privateEquityClaimed()","0b39c3e1":"requestLoan(address,address,bytes16,uint256,uint128,uint128,uint16,uint64,uint64,string)","0b39f18e":"setCardTokenAddress(address)","0b3a2ffd":"setRoyaltyInformationContract(address)","0b3af901":"proposePlatformWithdrawal(address)","0b3b2222":"TokenDistribution(address,address)","0b3bb024":"getTenant()","0b3bc259":"funderCount()","0b3cd070":"multiBet(uint256[],uint256[],uint256[])","0b3d7174":"prev_week_ID()","0b3e9c7b":"userEndGameConflictImpl(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,uint256,address)","0b3ed536":"claimDonations(uint256)","0b3f191a":"disableChanging(bool)","0b3fe32d":"setHalfTimeAtkBoss(uint256)","0b407022":"migrateV1Upgrades(address[],uint256[],uint256[])","0b40ab43":"setBankAddress(address,address)","0b4130f2":"GenomaToken()","0b424b66":"HHDCToken(uint256,string,string)","0b42d1de":"BejonesStandardToken(uint256,string,uint8,string)","0b43c6e6":"CryptonCoin()","0b440f33":"initCrowdsale(uint256,uint256,uint256,address)","0b4438e5":"spinAll()","0b45e8db":"SALE_CAP()","0b464bf6":"blocksSinceLastBid()","0b4650a0":"FiatContract()","0b467b9b":"revoke(bytes)","0b47459b":"LAARToken()","0b480095":"teamAddressThreeTokens()","0b483f6e":"toAllow()","0b48af0b":"interestOf(address,address)","0b4964a8":"addDungeonNewFloor(uint256,uint256,uint256)","0b4a1ece":"VisibilityDerived()","0b4aca45":"__formatDecimals(uint256)","0b4b5d5e":"GamityToken()","0b4bb61f":"burnPercentage1000m()","0b4c72a9":"rejectProvider(address)","0b4ca1cd":"doResult(uint256,bytes32,bytes32,uint256)","0b4cf825":"getRandomColorType()","0b4da628":"IsPlayer()","0b4db63a":"Tratok()","0b4dfc77":"contractMint(address,string,bytes32,bytes32,uint256)","0b4e0513":"reserveTokenFund()","0b4efd9a":"RobotBTC(uint256,string,string)","0b4f12f6":"updateUser(string)","0b4f3f3d":"cancel(string)","0b4f79a1":"RejekiKita()","0b509e1d":"getCountOfCell()","0b513828":"parseChannel(bytes)","0b513ce9":"PonziBet()","0b51989a":"setData(address,string)","0b520ad5":"freePeriodDuration()","0b522abf":"closeCrowdsale(address)","0b549884":"matingPrice(uint256)","0b54cbfb":"setType(uint8)","0b5608f2":"PackageCoinPresaleOne(uint256,uint256)","0b566f33":"unlockedCollateral(address)","0b56d4c6":"airdropNum()","0b56f01c":"createAmountFromEXORForAddress(uint256,address)","0b573638":"ethToTokenTransferOutput(uint256,uint256,address)","0b57adc0":"Transwave()","0b57c487":"COVERCOINToken(string,string,uint8,uint256)","0b583982":"getUserProductCount(bytes32)","0b586f1a":"_emitWorkResumed(uint256,uint256)","0b58dc38":"SetNewBlockchainEnabled()","0b590c6b":"SingularDTVToken()","0b591195":"largestPenis()","0b5945ec":"setTokenURL(address,string)","0b597135":"onHardCapReached(uint256)","0b5982f0":"payOutDividend()","0b59a5c4":"purchasedCoins()","0b59df68":"withdrawEscrow(uint64)","0b5a006b":"currentYear()","0b5ab3d5":"destroyDeed()","0b5ad1c1":"UpdateSellAgentCreators(address)","0b5adfff":"getNumTickets()","0b5ba082":"stagesManager()","0b5c2307":"globChanceOwner(uint256)","0b5c3f87":"addReferral(address,address)","0b5ca8db":"issuedBounty()","0b5d1c3d":"testLessThanOrEqual()","0b5d69ab":"UpdateMaxBalance(uint256)","0b5d94f6":"getOrderPrice(address,address,uint256,uint256)","0b5e19b0":"getInvestSum()","0b5e2232":"HunxuHappyToken()","0b5e89f4":"icoStarted()","0b5ee006":"setContractName(string)","0b5f2efd":"setCurrentRate(uint256)","0b5f5ef1":"setAvatar(uint256,bytes)","0b5faf97":"claimWin(bytes32)","0b5fcf81":"enableAutoDividends(uint256)","0b605fcd":"tokensTo0xbtc_(uint256)","0b60ca88":"raisedSale2USD()","0b611241":"ieoStorageVault()","0b6142fc":"breach()","0b620b81":"withdraw(address,address,address,uint256)","0b6386d4":"KyberNetworkCrystal(uint256,uint256,uint256,address)","0b63b114":"freeTokens(address)","0b63fe95":"processPayment(address,uint256)","0b642d72":"recoverLostEth(address,uint256)","0b65108b":"merge()","0b654e7d":"finishedRaceCount()","0b663e63":"promoCount()","0b66c247":"scoreTeams(uint32,uint32[],int32[],uint32[],uint32,uint32)","0b66f3f5":"multisendToken(address,address[],uint256[])","0b6700d6":"getLogo()","0b6780aa":"extendSaleEndDate(uint256)","0b679d2c":"REQUEST_CANCELED_BY_CREATOR()","0b6826ca":"payDividend()","0b682cb8":"Quhabitat()","0b684de6":"CitizenOneCoin(uint256)","0b695449":"MiningUpgrade(address,uint256,uint256)","0b697362":"withdrawFromSubRound(uint256)","0b6b80b2":"sampleRegistry()","0b6bf29f":"partner1_will()","0b6c754b":"isSuccess()","0b6c9ac7":"airdroppedAmount()","0b6d3017":"overflow_upper()","0b6d715b":"createGame(string,uint256,uint256)","0b6d8d52":"createDAO(address,uint256,uint256)","0b6e01db":"total_bet_available()","0b6e46fe":"enableController(address)","0b6e6511":"convertToELIX(uint256,address)","0b6ebf86":"KWHTokenAddress()","0b6f0530":"test_twoInvalidEqBytes32Message()","0b6f2fad":"HashCoin(uint256,string,string)","0b6f46ed":"isPresaled(address)","0b6f5b3d":"ShrimpFarmer()","0b6f6e0d":"CanYaCoinToken()","0b6fc163":"claimSignerAddress()","0b6fcdb0":"getEnforceRevisions(bytes32)","0b70ce55":"Betfunding()","0b714b17":"AddHash()","0b71ff6a":"MTDCERC20()","0b72396c":"validateContractWithCode(address,string)","0b730fae":"ICOadvisor2()","0b731652":"Ethbet(address,address,address,uint256,uint256)","0b7373d6":"giveAllBack()","0b73aad0":"msgsWaitingDone(uint256)","0b74074b":"startPayouts()","0b743021":"TOKENS_TOTAL()","0b745a01":"setLockup(address)","0b747d91":"randomSeed()","0b74b620":"getChannelsParticipants()","0b74edc6":"testFinalHash()","0b74f633":"getTradeParameters(uint256,address,address,uint256,uint256,uint256,uint256)","0b7507ae":"getTaskAtIndex(uint256)","0b7623ba":"abs(int8)","0b779363":"checkVotingForChangeAdminAddress()","0b77fa28":"generateThemedSpinners(uint256,uint256,uint256)","0b781385":"nextCampaignBalance()","0b78f9c0":"setFees(uint256,uint256)","0b7abf77":"TOTAL_TOKENS()","0b7ad54c":"getContent(uint256)","0b7d1de1":"proofOfSMS()","0b7d6320":"crowdsaleAgent()","0b7d796e":"loop(uint256)","0b7ddd25":"setRaisedAmount(uint256)","0b7e4e7f":"substractNumber(uint256)","0b7e9c44":"payout(address)","0b7ef89b":"contributeToCampaign(uint256)","0b8021c4":"getPublishedTokens(address)","0b803b6b":"transferApprovedBalance(address)","0b80b4f9":"QuantaloopToken()","0b80f8d3":"invmod(uint256,uint256)","0b811cb6":"executeProposal(uint256,bytes32)","0b816045":"getRequestInfo(uint256)","0b81e216":"setAllowTransfer(bool)","0b82a541":"setIcoEndTime()","0b82d33d":"withdrawBalanceDifference()","0b83284e":"MinterFunction(address,uint256)","0b834864":"publicTransfers(address,address,uint256)","0b83de20":"ABI(bytes32)","0b841433":"agentApproval(address,uint256)","0b8440ec":"bonusTokenRateLevelTwo()","0b84cc4a":"Committees(uint256)","0b851937":"year4Unlock()","0b85877f":"isICAP(address,address)","0b85881c":"ceilLog2(uint256,uint256)","0b869824":"CeoAddress()","0b87572b":"communityDevelopmentSupply()","0b8762d1":"Block18Token()","0b87cf10":"crowdsaleActive()","0b88e06b":"testTokenBalance()","0b892e3f":"celebs(uint256)","0b8a7bf8":"coinbaseWallet()","0b8b709d":"_createDroneInternal(address)","0b8ba87d":"UnilotBonusTailEther(address)","0b8bbd5b":"webGiftEtherAmount()","0b8d0a28":"wallet2()","0b8d9d94":"createSportsBet(string,uint256)","0b8e845a":"burnFeeFlat()","0b8eebde":"gameEnd()","0b8f0b61":"sendCoinsToBeneficiary()","0b8f0e0a":"LIWUC()","0b901c82":"totalRepaidQuantity()","0b910f86":"PRESALE_MIN_INVEST()","0b91eaf9":"isValidated(address)","0b926ecd":"validStoreVal()","0b927666":"order(address,uint256,address,uint256,uint256,uint256)","0b93381b":"success()","0b936a77":"DuanZiToken(address)","0b93bf0d":"setRecruitHeroFee(uint256)","0b948684":"delegatedTransfer(bytes,address,uint256,uint256,uint256)","0b95c8ae":"aggiungiMsg(string)","0b962e8f":"AlphaChainConstructor()","0b96406a":"vestingMappingSize(address)","0b96740c":"changeMinimumContributionForAllPhases(uint256)","0b967584":"voteForCandidate(uint256,address)","0b967fd2":"remove_master(address)","0b967fe7":"assertEq18(bytes18,bytes18)","0b96e72e":"setBAS(bytes32,address,string)","0b972ff6":"weiPreCollected()","0b97bc86":"startDate()","0b97fc8d":"WeiPerTicket()","0b98107c":"dateFrom()","0b9830ba":"tokensIndexOf(address,bool)","0b9849ab":"WEChainCommunity()","0b98f975":"setBonus(uint256)","0b9902d0":"WithdrawPerformed(uint256)","0b99ccee":"ico2Ended()","0b9aa067":"isVerified(address,address)","0b9ac851":"getCurveUnset(address,bytes32,int256)","0b9adc57":"deleteBytes32(bytes32)","0b9b0e7d":"highRate()","0b9b8130":"registerMintedToken(address,string)","0b9b9602":"SalesWalletUpdated(address,address)","0b9bfa6c":"inCommunity(address,address)","0b9cae77":"KinetiQ()","0b9d5847":"getExchange(uint256)","0b9d98e9":"getTotalVolume()","0b9e9817":"CanaryV7FastTestnet()","0b9ea6c8":"getCurrentSold()","0b9ea95d":"configureSaleClockAuction(address,uint256)","0b9f1e76":"wphcToken()","0b9f2816":"nowwww()","0b9f2ca6":"getCountBuildings(uint256,uint256,bool)","0b9f6108":"divsm(uint256,uint256)","0b9fc8fb":"checkerSign(bool)","0ba0a3a1":"TakerSoldAsset(address,uint256,uint256,uint256)","0ba12c83":"commitUpgrade()","0ba1772d":"callDistributed()","0ba1f7ad":"getImpactCount(string)","0ba234d6":"cancelRecovery()","0ba24e4c":"customers(address,address)","0ba27775":"fondToken()","0ba2e8a8":"allowFunding()","0ba46624":"setBountyAgent(address,bool)","0ba4d242":"s43(bytes1)","0ba5890a":"noteBallotDeployed(bytes32)","0ba6d271":"updateFunds(address,uint256)","0ba7ebe2":"changeAll(address)","0ba8916f":"updateMeterKey(address)","0ba8d735":"purch(address,uint256)","0ba8ebec":"lockance(address)","0ba92878":"delOrganizationCertificate(string)","0ba95909":"getMaxAmount()","0baaaed9":"setConfigBytes(bytes,bytes)","0bab4d84":"setClearingPriceSubmissionDeposit(uint256)","0bab718f":"updateCurs(uint256)","0bab7ff6":"messiCommunity()","0bac0312":"TryUnLockBalance(address)","0bac15ae":"PUBLICSALE()","0bac2850":"setFunctionFourPrice(uint256)","0bac3c01":"isDeferred(address)","0bac9fe7":"getUsernameByIndex(uint256)","0bad342a":"EscrowContract(address,address,address,address,uint256,uint256,uint256,uint256)","0bad4481":"setupRegion(address[16],uint256,uint256,uint256[],bool,uint8[128])","0bae2129":"affiliateTree()","0bae3288":"getSale()","0bae461c":"KomicaToken()","0baf0bcc":"lockDateTimeOf(address)","0bb0482f":"concatBytes(bytes,bytes)","0bb0e827":"add_addys(address[],uint256[])","0bb15acc":"GoldeaToken(uint256)","0bb18da2":"saveRefundJoinId(uint256,uint256)","0bb24375":"ITX_Token()","0bb25901":"freezeSupply(uint256)","0bb2cd6b":"mintAndFreeze(address,uint256,uint64)","0bb3a066":"unsetAdministrator(address[])","0bb4bbaf":"testInitialNumberOfVoters()","0bb4e6f4":"getTotalWei()","0bb536a2":"fightMix(uint256,uint256)","0bb563d6":"logString(string)","0bb5e62b":"EGC()","0bb700dc":"getStats(bytes32)","0bb7a81a":"ZhuhuaToken()","0bb8b9c3":"zint_convert(string)","0bb954c9":"WithdrawAndTransferToBankroll()","0bb9ee71":"createRepository(bytes32,bytes)","0bb9f21e":"SCAMERC20()","0bba3065":"AuthorityFilter()","0bba662d":"oneCoin()","0bbaa27a":"seedSourceB()","0bbad618":"setupReclaim()","0bbd4e38":"defrostReserveAndTeamTokens()","0bbd501e":"NewEtherPrice(uint256)","0bbdb469":"getLuckyblockSpend(bytes32)","0bbe0ee3":"transferAllFrom(address,address,uint256[])","0bbed2b7":"secondsaleopeningTime()","0bbf2768":"infrastruct(uint256)","0bbf709a":"validHolder(address)","0bbf8f38":"setMinBid()","0bbfdbec":"setUsdAmount(uint256)","0bc09cfe":"buy(uint256[6][])","0bc0c61f":"destroyOwner(address,uint256)","0bc1236e":"getTokenAmount(uint256,uint256)","0bc16f1b":"presell()","0bc1734c":"addPermissions(address[])","0bc217d9":"setCastleSale(uint256,uint256)","0bc23901":"WalletAddressesSet(address,address,address)","0bc2a3b7":"Showercoin()","0bc30aa0":"getTicketWinnings(uint256,uint256)","0bc311ea":"addFound(address)","0bc32ab6":"tokenToPointBySkcContract(uint256,address,uint256)","0bc33b22":"addressJenkins()","0bc3a268":"KelvinToken()","0bc4ec45":"FirstDropToken()","0bc59a8e":"date15Nov2018()","0bc5b2c5":"stage_2_tokens_scaled()","0bc5e51e":"endTimeSale3()","0bc5f216":"kgtToken()","0bc69912":"createICO(bytes,bytes)","0bc6b708":"placeBetTESTONLY(uint256)","0bc6b89c":"dailySpent()","0bc6c96e":"failSafe()","0bc7760c":"crowdsaleSet()","0bc785df":"ACTToken()","0bc7fd93":"toTuis(uint256)","0bc8982f":"getBQL()","0bc8b4c2":"getMintRequestUintMap(uint256,int256,string)","0bc954dc":"addEgg(uint64,uint32,address,uint256)","0bc9c89c":"removeMessage()","0bca1704":"setHardcupTrue()","0bca441b":"BETHERTokenSale(uint256,address)","0bca5903":"claimMedals(uint16)","0bcab28a":"verifyReceiverAddress(address,address,address,uint8,bytes32,bytes32)","0bcb8a23":"getBondDivShare(uint256)","0bcbad90":"WLMTPrice()","0bcbbd21":"r2()","0bcbe35b":"lastBlock_f19()","0bcbfe1c":"withdraw_Eth(uint256)","0bcd0694":"getUserCities(address)","0bcd3b33":"getBytes()","0bcd87ed":"dashboardAddress()","0bce62ea":"isPreICOPublicOpened()","0bce8cdf":"getContributorInfo(address)","0bcef54c":"Eticket4Sale(address,address,uint256,uint256,uint256)","0bcf963b":"getDocumentsCount()","0bd089ab":"MyAdvancedToken(uint256,string,uint8,string,address)","0bd11894":"addBuilder(uint256,address)","0bd12120":"MMCC()","0bd18d7a":"investment(address)","0bd263ff":"registerPID(address)","0bd2ae1c":"ERW()","0bd38767":"testCanClone()","0bd3ae61":"EARLY_BIRD_SUPPLY()","0bd3cf7e":"Timebomb()","0bd58493":"sellMyApple(uint256)","0bd5b493":"payPostDrawRef(address,address,uint256)","0bd601df":"setLockEndTime(uint256)","0bd61e79":"_finalRoundLosersFight()","0bd62ad5":"FantasySportsCoin()","0bd64dbf":"BsToken(string,string,uint256,address)","0bd6a40f":"setWorkerAdress(address)","0bd6c769":"Load(address,uint256,uint256)","0bd7b6b8":"computed_fundraise()","0bd85158":"setUInt8Value(bytes32,uint8)","0bd8599e":"countUp()","0bd8a1d0":"auctionFinalized()","0bd8a3eb":"SaleEnded()","0bd934c3":"UPEXCoin()","0bd93738":"updateShareTimeGap(uint256)","0bd9c534":"right43(uint256)","0bda4dbf":"refundCount()","0bdab855":"distributeHNC(address[],uint256,uint256)","0bdc0031":"STARTBLOCKTM()","0bdc7953":"multiBuy(address[],bytes32[])","0bdc9c35":"CalculateReward(uint256,uint256,uint256)","0bddb83b":"bonusPresale()","0bdddb73":"stampOut(address,uint256,uint256)","0bdde107":"balanceOfme()","0bde1d36":"changeAllowanceToMint(address,address,int256)","0bdf3dae":"CryptoRoboticsToken()","0bdf5300":"TOKEN_ADDRESS()","0be0453b":"StringDemo()","0be0713d":"gcSupply()","0be0f677":"log(bytes32,string)","0be21ea9":"MAX_TIME_EXPLORE()","0be23ace":"RealMoney()","0be2858e":"multipleTransfer(address[],uint256[])","0be48491":"personalMax()","0be5430f":"DroneTokenSale(address,address)","0be560be":"NarniaUSDT()","0be5ca05":"privatePresaleTokenReservation(address,uint256,uint256)","0be5efa6":"year2LockAddress()","0be6ba2b":"addRestricedAccount(address,uint256)","0be702bf":"_v4()","0be72b6d":"allOfferingQuota()","0be76f80":"memberData(uint256)","0be77485":"Unlock(address)","0be77f56":"log(bytes)","0be80f39":"setComission(uint256)","0be80fa9":"changeVisitLengths(uint256,uint256,uint256,uint256,uint256,uint256)","0be8287e":"getJackpotInfo()","0be9189d":"showInvestorVault(address,uint256)","0be924ef":"tier_rate_4()","0be96fbd":"MAX_TOKENS_SALE()","0be9f930":"REL(uint256,string,uint8,string)","0beb90d3":"icoLimit()","0bebd0f9":"addAddressToGeneration(address,uint256)","0bec3231":"GalaxyChain()","0bece492":"setPhaseBonusAddress(address,address)","0bed63c7":"_isActive(uint256)","0bee1c3e":"availableICO_w2()","0beeb0af":"getValue(address,bytes32,address)","0beedbd4":"AdoptionRequested(bytes5,uint256,address)","0befe82b":"AddBankerPrincipal(uint8,uint256)","0befeeb0":"lastCreatedGame()","0bf05c99":"DraftPlayer(address,uint256)","0bf09985":"openRound(uint256,uint256)","0bf0e4e4":"myProfit(address)","0bf1c747":"destructed()","0bf2c50d":"setCFO(address,bytes)","0bf2ee8d":"addPerson(string)","0bf318a3":"finalizeCrowdsale()","0bf34d54":"CVToken()","0bf36806":"Bivacoin()","0bf474a9":"claimDonations(address[2],uint256[7],uint8,bytes32[2])","0bf5035d":"secondYearEnd()","0bf51f36":"updateTime(uint64)","0bf53613":"getBonusNow(address,uint256)","0bf53668":"consumers(address)","0bf61fd4":"t_Slava()","0bf63c60":"setBasicCentsPricePer30Days(uint256)","0bf6898e":"DPSToken(uint256,string,string)","0bf6dbfd":"VanityToken(address)","0bf75567":"voteSuperQuorum(uint256,bool)","0bf757e5":"HopiumToken()","0bf77989":"debug_coinbaseTxSha(bytes,uint256)","0bf7fb57":"getUserMilestone(address)","0bf82810":"removePartnerAddress(address)","0bf84797":"RATE_FOR_WEEK1()","0bf867c2":"Zemana()","0bf9236a":"KillContracts()","0bf9c50f":"calcNextNBonuses(uint256)","0bf9fd52":"wasPaid(bytes32)","0bfa1191":"setPriceStorageInternal(address,uint256)","0bfd1271":"confirmErc20TransactionRequest()","0bfd7b62":"getBonusesAmountAvailable(bytes32,uint256)","0bfefed4":"createUser(address,string,bool,bool,bool)","0bff2ac2":"NewBatch()","0bffa8b4":"changeMigrationInfoSetter(address)","0c0075a3":"getBallotOptions()","0c0078e8":"RESERVED_TOKENS_ANGLE()","0c012834":"ARS()","0c01b2ae":"setConfiguration(string,string,uint256,address[],uint256)","0c02159f":"HavEtherToken(uint256,string,uint8,string)","0c022933":"highTimeBonusValue()","0c031f45":"TokenBuy(address,uint256)","0c03348d":"getIntel(uint256)","0c0399a4":"iteration()","0c03f24a":"parseDate(string)","0c03fbd7":"getNumPassingTokens(address,uint256)","0c0615a7":"evaluate(address,string,string)","0c0662a8":"getLastWithdrawal()","0c06c3ee":"viewHouseFee()","0c06fda1":"AVINCOIN()","0c07fa56":"ICO_END()","0c087782":"PXLProperty()","0c087bc5":"stage1Start()","0c08bf88":"terminate()","0c08ec49":"importTokensToSidechain(address,address,uint256,bytes32)","0c099133":"ERC20TokenFactory()","0c0a5c55":"cancelAuth(address,address)","0c0a7a68":"Stars()","0c0ad299":"removeProject(address)","0c0b86ca":"currentAuctionId()","0c0bea5c":"FinalTokenToken()","0c0c13c8":"query2_fnc()","0c0cde7c":"ZIBToken(uint256,string,string)","0c0e5f0d":"calculateGrapeBuy(uint256,uint256)","0c0e6dea":"publicAllocationEnabled()","0c0ef2b0":"isGameActive()","0c103837":"votedHarvest(address)","0c112598":"fun(bytes32)","0c119354":"rateMain()","0c11dedd":"pay(address)","0c11f32e":"milestoneShares(uint256)","0c131629":"RDFToken()","0c14080b":"bonusSale()","0c15b963":"againAttack(address,uint256)","0c15f601":"meltTokens(address,uint256)","0c16683e":"SCLToken()","0c1688f7":"IstriumToken(address,address)","0c17d023":"dungeonTokenContract()","0c17d42c":"setAlpha(uint256)","0c1838e9":"importAmountForAddresses(uint256[],address[])","0c18e1c9":"balanceInSpecificTranche(uint256)","0c1925f3":"stock(string,string,uint256,string)","0c192fe5":"RBCToken()","0c195d99":"totalAllocatedTokens()","0c196a74":"getInterestRate(uint256)","0c19f80e":"checkReferral(address)","0c1a8b05":"toSPool(uint256)","0c1a972e":"newAccount(string,bytes)","0c1b33d2":"setRemainingSupply(uint256)","0c1be377":"removeSupport(address,address)","0c1c0974":"littPoolIDExists(uint256)","0c1c3c14":"registerNameXID(string)","0c1c972a":"startPublicSale()","0c1ca1ba":"withdrawOwnerEth()","0c1cd8cd":"endPvtSale()","0c1d4af7":"LogTokenAssigned(address,address)","0c1db532":"getPI_edit_28()","0c1e3fd4":"submitWithdrawTransaction(address,uint256,bytes)","0c1e3fea":"previousState()","0c1e517f":"bytes16ToStr(bytes16,bytes16,uint8,uint8)","0c1f679f":"WithdrawalTokensAfterDeadLine()","0c1fad51":"setSeedSourceA(address)","0c1fe4b1":"showTransaction()","0c204dbc":"getF()","0c2073e4":"LemonSelfDrop2()","0c21a2f1":"nextGameMinBlock()","0c21e754":"setLLV_edit_9(string)","0c237dde":"servusTokensAllocated()","0c23cf4b":"buyCardXid(uint256,uint256)","0c250dcd":"logUnsigned(bytes32)","0c255c94":"max256(uint256,uint256)","0c25c6c1":"getBonusUsersCount()","0c26a816":"pvpMaxIncentiveCut()","0c26ac30":"closeEarlyAdopters()","0c26e42e":"getReleaseHashForNameHash(bytes32,uint256)","0c270f44":"recleared(address)","0c2737d2":"incrementCounters(uint256,uint256)","0c27677a":"getCRaddress()","0c28e291":"Prout()","0c294f51":"getAllCounts()","0c29e589":"createMyEntity(uint256,bytes32,bool,uint256,uint256)","0c2a48e2":"realitycheck()","0c2ab324":"SAN()","0c2ad9e3":"battle(uint64,uint64)","0c2b14fe":"buyCostume(uint256,uint256)","0c2b3eda":"TeacherCoin()","0c2b4b85":"addGames(bytes32[],bytes32[])","0c2b663c":"SDR22(uint256,string,string)","0c2bc34d":"indexOf(uint256[],uint256,bool)","0c2c5add":"contribute(address,uint256,uint8,bytes32,bytes32)","0c2c81ed":"platformFundingSupply()","0c2cb820":"setDebug(bool)","0c2d71b1":"docStore()","0c2e4bf4":"icoStartAt()","0c2ec050":"isCurrentRoundFinishing()","0c2edc1c":"setExchangeAddresss(address,address)","0c2f6f48":"crowdSalePeriodInit()","0c31309e":"getPrivatePurchaserStatus(address)","0c316d6a":"DTOToken(address)","0c319d80":"BidiumToken(address,address,address,address)","0c3257d0":"changeUserClass(address,uint256)","0c326330":"_isICO()","0c3304d1":"mintMAN()","0c333556":"Vault(address[],address,address[],address[])","0c340a24":"governor()","0c345385":"RenaS()","0c34644c":"getInstructor(address,address)","0c3499ca":"_setSkills(address,uint256,uint256,uint256)","0c34f8a5":"addAddressesToWhitelist(bool,address[])","0c367f63":"DAEXToken(address)","0c36add8":"issue(uint256,uint256,address,address,uint256,address)","0c37348d":"buyPreSaleTokens(address,uint256,uint256,string)","0c376ee6":"setPvtTokens(uint256)","0c38708b":"get_all_project_information(uint256)","0c3890b7":"addThing(string,string,string,bytes32)","0c3980ef":"NextRewardHalving()","0c3a9658":"MTUV1()","0c3b3b70":"Unihorns(uint256,string,string)","0c3b7b96":"minTokensToCreate()","0c3c450e":"icoHashedPass()","0c3c92a3":"finishHardcap()","0c3cebfa":"issueTo(bytes32,uint256)","0c3d5157":"contractStartTime()","0c3dbf43":"removeMarket()","0c3dfa0e":"SLoader()","0c3e2d2d":"getTotalFundsRaised()","0c3e3c58":"getAdministerList()","0c3e4004":"GraceCoin()","0c3e564a":"airDeliverMulti(address[],uint256)","0c3f08c6":"newGame(uint8,string,string,bytes32,uint256)","0c3f0cac":"getLastPlayer(string)","0c3f1f14":"updateSupply()","0c3f64bf":"isDev(address)","0c3f6acf":"currentState()","0c402ed8":"confirmMinting(uint256)","0c424284":"setWhitelistStatus(address,bool)","0c4326a0":"getMajorMinorPatch(bytes32)","0c432c8d":"calcJadeReceived(uint256,uint256)","0c432f1f":"handleLastRef(address)","0c433edf":"receiptUsed(address,address,uint256)","0c437aa7":"setMandateInBlocks(uint256)","0c44ba40":"getMyTicketAddresses(address)","0c45361f":"creators_count()","0c45453c":"_feed(uint256,bytes32)","0c45e8d7":"roomsAvailable(string,uint256[])","0c4641d3":"BJCToken()","0c46fc92":"deliverLastMilestone(bytes32)","0c486a96":"requestPayment(uint256,uint256)","0c486c00":"CNRToken()","0c48ae9e":"createAdSlot(string,uint256,uint256,uint256[])","0c48c6bd":"getBonusMultiplierAt(uint256)","0c48e582":"updateVendor(address,address)","0c497094":"createAngel(uint8)","0c49c0a2":"MIN_CONTRIBUTION_AMOUNT()","0c49c36c":"sayHi()","0c4a3338":"CheckTime(uint256)","0c4a5153":"commitStageActive(uint256)","0c4a8d94":"STAGE_3_FINISH()","0c4a9869":"unregisterContract(bytes32)","0c4ada17":"cards_gold(uint256)","0c4ae1ca":"cancelBooking(address,address)","0c4bfa94":"left13(uint256)","0c4c4285":"setHash(bytes32)","0c4d6bdf":"EarlyBirdsFinalized(uint256)","0c4dd1d9":"totalUsdAmount()","0c4ecab4":"confirmations(bytes32,address)","0c4f65bd":"getOwnerAddress()","0c4f8f6f":"regularTransfer(bytes32,bytes32)","0c50b116":"BTHPoint()","0c51015d":"adjustTap(uint256)","0c51171d":"getTokensSold(address,bytes32)","0c516283":"freezeHybridizationsCount(uint256)","0c5241fa":"LOL6()","0c525571":"arraySum(uint16[])","0c52780d":"unCertifyDelegate(address)","0c52bb4c":"auditorsList(uint256)","0c547097":"goldenTicketOwner()","0c549dd9":"getCET6ByAddr(address)","0c54ce44":"ProofOfRipple()","0c5532bf":"singleValueAirdrop(address,address,address[],uint256)","0c55699c":"x()","0c5589b8":"DecreaseWithdrawalAmount(uint256)","0c559757":"setHouseEdge(uint8)","0c55d925":"deleteBytesValue(bytes32)","0c55d9a4":"confirmStaking()","0c55f818":"CTU_ADDRESS()","0c560c64":"USD(uint256)","0c58062b":"teamLockPeriodInSec()","0c584803":"SGTMock(address)","0c58bcb8":"EthLendToken(address,address,address)","0c58e23c":"ZClassicGold()","0c59b556":"viewCoinsKarmaBySymbol(string)","0c59c570":"CashTron()","0c5a534e":"allowBuying()","0c5a97a6":"getProviderName(uint256)","0c5c2ca3":"getIndexName(bytes)","0c5ce593":"open(address,bytes32,uint256,uint256)","0c5d919d":"totalsuplly()","0c5e3f11":"nestedFirstManyToSome(uint256,uint256)","0c5ebb1a":"userForceGameEnd(uint8,uint256,uint256,int256,uint256,uint256)","0c5ed9d5":"REB()","0c5f9a60":"allocationFee(bytes32)","0c5fd414":"preOrder(address,address,address,address,bytes32,uint256,uint256,uint256)","0c5fd4b2":"minttoken(address,uint256)","0c60223e":"withdrawAuctionBalance(address)","0c61257e":"WartegToken()","0c620494":"changeAllowTransferWallet(address)","0c62b816":"minableSupply()","0c62bfbb":"_calcNextRate()","0c636091":"adoptAxies(uint256,uint256,uint256,address)","0c646fbd":"get_entity_count()","0c64a739":"price_exponent()","0c64a7f2":"remainingTime(uint256)","0c657eb0":"bankroll()","0c65829b":"_setSkills(address,uint256,uint256[],uint256[])","0c65e229":"startICOPhaseThree()","0c662943":"_lockup(address,uint256,uint256)","0c66adf8":"getCurrentRoundInfo(uint256)","0c68194f":"getCourseIdOfStudent(address)","0c68a104":"fundingMaxInEth()","0c68ba21":"isGuardian(address)","0c68f917":"cancelOfferingProposal(address,uint256)","0c693110":"getVoted(address,uint256)","0c6940ea":"addMeToAllGames()","0c69b189":"claimCrystal()","0c6a3161":"RESERVE_ADDRESS()","0c6a5be4":"Arexium(uint256,string,uint8,string)","0c6a62dd":"updateCurator(address)","0c6b1324":"Etherboard()","0c6bfdd0":"openTheRabbitHole()","0c6cbf92":"lastPayOut()","0c6cd73a":"issueCard(uint256,uint256,uint256)","0c6d1efb":"releaseEachTokens()","0c6ddc0d":"getUserAllowance(address)","0c6de527":"addToBonusSeed()","0c6df351":"doBondBonusTransfer(address,address)","0c6e29e3":"subscribeToPool()","0c6fc9b2":"processTakerOrder(uint256,uint256,uint256,uint256,bool,address,address,bytes32)","0c6fe674":"getPresaleTotal(uint256)","0c700183":"listGlobalAuditDocuments(uint256,bool)","0c7013c1":"send(address,address[],address,uint256[])","0c70f055":"getRandomRarity(uint32,uint256)","0c71614c":"divsforall()","0c717036":"colourID(uint8,uint8,uint8)","0c71b48c":"BTCTransactions(bytes16)","0c72bf39":"ArtToujourToken()","0c72fe56":"_payBidAllocationFee(bytes32)","0c736e04":"refundForValidPartners(uint256)","0c73a392":"getLogSize()","0c740736":"addPicture(string,uint32,uint32,uint32,uint32,string,string,string)","0c7452b8":"viewPetitionSignerWithAddress(address,uint256)","0c74be3d":"TIME_TO_MAKE_TOMATOES()","0c7516fd":"numPurse()","0c754b9f":"BuyOptions(address,uint256,string,uint8)","0c75941a":"setContractMessage(string)","0c76316d":"withdrawPot()","0c763fef":"showContractMsgSender(address)","0c77a697":"claimFounders()","0c77b44e":"setLedger(address,address)","0c790369":"maxMessageChars()","0c798c81":"SCCToken(address,address)","0c79af3d":"witrhdraw(uint256)","0c79e3e6":"setCrydrStorage(address)","0c7ac7b6":"arbitratorExtraData()","0c7b5616":"Time_Start_Crowdsale()","0c7befb2":"_tokenLayersExist(uint256)","0c7ca61e":"ArrAccountIsFrozenByDate(uint256)","0c7caded":"destroyMe()","0c7d8c20":"_register(bytes32,address)","0c7de59d":"edit(address,bytes,bool)","0c7e30b7":"getUsdCentsFromWei(uint256)","0c7eca6e":"setCurs(uint8)","0c7ef39b":"HUBTToken()","0c7f076e":"advisoryReserveTokensDistributed()","0c7f27ba":"COE()","0c8004b5":"buyTokens_Address(address,uint256,bytes8)","0c80d6dd":"view_last_result(address,address)","0c8114d3":"_forwardFunds(address,uint256)","0c8135a7":"getTeamOwner(uint256)","0c8209b6":"manualWithdrawEtherAll()","0c823abe":"importedTokens()","0c82b942":"whitelistRemove(address[])","0c832ef0":"restoreOwner()","0c8367fb":"HALAL()","0c83700a":"divCutPool()","0c8496cc":"getReturnByPath(address[],uint256)","0c857b25":"getLoveLock(uint64)","0c85b18c":"SetBuildingData(address,uint256,uint256,uint256,uint256,uint256)","0c85feea":"matchOrders(uint64,uint64)","0c861d4b":"Aeron()","0c87355e":"BANCOR_CONVERTER_UPGRADER()","0c875c8d":"Withdrawn(uint256,uint256)","0c89a0df":"transferTokens(address)","0c89b766":"randomSource()","0c89ef35":"hasEnoughAllowance(address,address,uint256)","0c89ef67":"PXMCCoin(uint256,string,uint8,string)","0c8a611f":"getInvestorsETH(address)","0c8ac6f7":"transferAnyTokens(address,address,uint256)","0c8b29ae":"hodlTillBlock()","0c8b494d":"RadarSpeedChain()","0c8bae5c":"sellTokensForBtc(string,address,uint256,uint256)","0c8bd2c5":"Issue(address,address,address,address)","0c8bdcfa":"GetPolicy(address,string,string)","0c8c0392":"listAsset(uint256,uint256,uint256,uint256)","0c8c085f":"getNumContents()","0c8dfeda":"maxLinkedWalletCount()","0c8e3166":"assignAtheniansToBattle(uint256)","0c8e9977":"whitelist_pool(address,address,uint256)","0c8f167e":"TOKENS_SOLD()","0c8f78fb":"setGasAmount(uint256)","0c9066dd":"getZodiac(uint256)","0c90da51":"End2()","0c915c74":"releaseWithStage(address,address)","0c91af81":"IGTUSD()","0c91e624":"Winner(string,address)","0c91f2d0":"rewardForWork(address,address,uint256,bool)","0c92b17b":"checkBurnTokens()","0c932e77":"ritualFee()","0c938c3f":"changeSubscriptionFee(uint256)","0c939ae1":"KYROInv()","0c93c981":"playBatch(uint256[],uint256[])","0c96526b":"getRateUsd()","0c96c4ea":"triggerRelease()","0c97200a":"getLoansCount()","0c975447":"lowBonusRate()","0c97bb77":"curConfig()","0c98048d":"transferFromAdmin(address,uint256)","0c981d58":"closeGame(address)","0c987501":"EtheraffleFreeLOT(address,uint256)","0c990004":"createToken(uint256,address,bytes32,uint256,uint256,bytes32)","0c99d807":"_isValidBlock(uint8)","0c9a6c24":"getUserCoinMarketValue(uint16,uint256)","0c9b016c":"expItemClass()","0c9b5777":"Erc20()","0c9bb7d2":"denyByPassword(bytes8,bytes)","0c9bc2c0":"calculateNonVestedTokens(uint256,uint256,uint256,uint256,uint256)","0c9be46d":"setCharityAddress(address)","0c9c1c58":"setAltFundAddress(address)","0c9cbfee":"moveProduct(address,address,uint256)","0c9daf45":"vcxWallet()","0c9dc2b8":"checkEthFundDepositAddress()","0c9dd381":"RewardTransfered(uint256,address,uint256,uint256,uint256)","0c9f6ed8":"ZEXCoin()","0c9f88c0":"Zignal()","0c9f980f":"isCSO(address)","0c9fcec9":"setApproval(address,address,uint256)","0c9fd581":"assertTrue(bool)","0c9fe5eb":"PIXEL_COUNT()","0c9ff620":"listINF()","0ca09e1e":"XoudCoin()","0ca1988b":"getnum(address)","0ca1c5c9":"getTotalMinted()","0ca2bda2":"isAllowedTransferDuringICO()","0ca2f2fd":"MultiBonusCrowdsaleMock()","0ca35682":"recover(uint256)","0ca35c22":"setScouponTransferCost(uint256)","0ca36263":"exit(bytes32)","0ca40865":"capRound2()","0ca413a4":"getDateRanges()","0ca435a6":"grabBooty()","0ca4f838":"BetCommunity()","0ca5bdb4":"novaBurn()","0ca5f72f":"rewardPercentageDecimals()","0ca621a8":"updateSplitandEmit()","0ca6afa7":"EtfToken()","0ca6d310":"setNamePiture(uint256,string)","0ca72e82":"testGetLawyerCount()","0ca7395f":"returnFund(address,uint256)","0ca78923":"updateConnector(address,uint32,bool,uint256)","0ca8fe1e":"burnCoins()","0ca9183c":"icoFundingRatePredictionBonusInPercentage()","0ca97903":"emergency(address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","0ca9897c":"citePaper(address)","0ca99ca8":"hardCapInWei()","0ca9c14e":"PryvCn()","0caa1d84":"isUserGranted(address,string)","0caa5d91":"UserDestroy(address,address)","0caa8605":"getStage3End()","0caaa284":"PresaleClosed(uint256,uint256)","0caab83a":"poolBounty()","0cab068c":"isVestingRevoked()","0cac54ed":"claimTransfer(address,address)","0cacbf21":"getSponsorshipsSortedByAmount(address,uint256)","0cadc5b3":"deliverBonus()","0cae3cbb":"checkStageCondition()","0caeb350":"upgradeValue(uint256)","0caee2ca":"calculatePayout(uint256,uint256,uint256)","0caf10b2":"GreenEnergy()","0caf9d39":"testFailTooManyMembers()","0cafabd8":"getTPrice()","0cafef9c":"Clen(uint256,string,uint8,string)","0cb08716":"airdropDynamic(address[],uint256[])","0cb08e3b":"_finalizeICO()","0cb09309":"ArysumToken()","0cb0a44b":"enableInvestment()","0cb0c7f0":"forceOwnerChange(address)","0cb1982b":"updateNAV(uint256)","0cb1d243":"ICT(uint256,string,string)","0cb1d6b4":"fourthWeek()","0cb296ae":"Gemstones()","0cb335c4":"setMissedVerificationSlashAmount(uint256)","0cb5f653":"newUser(address)","0cb60443":"minRate()","0cb61d7a":"setCurrentBonusPercent(uint256)","0cb6aaf1":"keys(uint256)","0cb6b577":"TOKEN_DECIMAL()","0cb743a5":"buyOld(uint256)","0cb749b6":"FutureBlockCall(address,uint256,uint8,address,bytes,bytes,uint256,uint256,uint16,uint256,uint256)","0cb795e8":"getDividendInfo(uint256)","0cb7eb4c":"getReleaseTime(address)","0cb812d3":"openWithoutCounterparty(address[4],uint256[3],uint32[4])","0cb9208a":"JorgeCoin()","0cb97f57":"advisorsTotal()","0cb9da1b":"RedemptionContract(address,uint256)","0cb9ec43":"TemperatureMeasurementB(address,uint32,uint64)","0cb9ee4b":"getAllPlayerObjectLen()","0cba5853":"angelCollection(uint64)","0cba6d27":"getSocialAccountsLength()","0cbb0f83":"entryCount()","0cbc9ce7":"sendToToteLiquidatorWallet()","0cbe1eb8":"USDDOWNLOADPRICE()","0cbf0601":"numMessagesSigned(bytes32)","0cbf54c8":"auctionDuration()","0cbf711a":"LogClosed()","0cbf7ec0":"startPrivateIco()","0cbfe979":"updatePrivateSaleWithMonthlyLockupByIndex(address,uint256,uint256,uint256)","0cc00bc9":"MarketPlace(address,uint256)","0cc03e7a":"claimShare(uint256)","0cc04b55":"adminUnregister(string)","0cc06221":"getUserAccountInfo(address)","0cc10550":"BIToken()","0cc2001c":"TastToken()","0cc20a0c":"getHoldEarningsInRound(address,uint256)","0cc3ad77":"verdictExecuted(address,bool,uint256)","0cc3db97":"_createToken(uint256,uint256,uint256,uint256,address)","0cc4330c":"visit()","0cc4fb87":"changeGeneralSaleEndDate(uint256)","0cc6373f":"tokenExchangeRateMile3()","0cc69a27":"Marketplace(address,address)","0cc69b5b":"NOKIA()","0cc7086b":"canBurnUtility(address,uint256)","0cc73b6a":"BLOCKS_PER_ROUND()","0cc79a85":"getEnded()","0cc8299b":"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww()","0cc87b1c":"soldPreSaleTokens()","0cc88021":"hasPlayer(address)","0cc8c9af":"getOrCreateNextFeeWindow()","0cc91bb9":"setEarlyParicipantWhitelist(address,bool,uint256,uint256)","0cc966fa":"buy(address,address,uint256,uint256,uint256,bool)","0ccc642e":"emergencyFlagAndHiddenCap()","0ccc68bb":"_create_mineral(bytes32,address,uint256,uint256)","0ccc88b1":"BurnupGameBase()","0cccfc58":"auctionPeriod()","0ccde0b1":"initialSupplyPerAddress()","0ccec396":"getNumReleases()","0ccf30f1":"setRentTime(uint256)","0ccf5af4":"_prizeAmount()","0ccfdd8b":"potentiallyCirculatingPop()","0cd0563b":"broadcast(string)","0cd0c3d7":"resetRental()","0cd1812f":"sendFundsTo(address,uint256)","0cd205bb":"CrowdsaleContract(uint256,uint256,address,uint256,uint256)","0cd28e9d":"getRoundPlayerList(uint256)","0cd2b327":"approveSponsorableJob(address,uint256,address)","0cd30783":"getcompany(uint256)","0cd3c7f7":"ransom()","0cd3fad2":"_base64decode(bytes)","0cd4700a":"NT()","0cd522da":"returnStartBlock(uint256)","0cd55abf":"nextNonce(address)","0cd5ea83":"earlyBirdDuration()","0cd641b2":"tokenForComunity()","0cd64ad0":"changeEthDailyLimit(uint256)","0cd6ceb3":"Boldman()","0cd74cd9":"etherWallet()","0cd7d0f2":"DestlerDoubloons()","0cd865ec":"recover(address)","0cd8dd0b":"setXPTokenAddress(address)","0cd9aec6":"testFailTrustWhenStopped()","0cd9f271":"buy10()","0cda88ce":"mul256By256(uint256,uint256)","0cdbf3dd":"setReferralsMap(address[],address[])","0cdc92ea":"canBeCanceled(uint256)","0cdd4234":"mainAddress()","0cddb437":"CNDTPrivate()","0cde0e7d":"solve(int256,int256,int256,int256)","0cde6009":"KinTokenSale(address,uint256)","0cded5f0":"migratePool()","0ce08a49":"refundAmount(uint256)","0ce10cbd":"changeOwnerToZero()","0ce11049":"setBCoinContractAddress(address,address)","0ce11a77":"registrarAddress()","0ce11ded":"updateMthEthRate(uint256)","0ce18afc":"TabToken()","0ce1f4b7":"toB32(bytes,uint256,bytes)","0ce3151c":"personUpdateRelation(uint256,string)","0ce38276":"setColorYellow()","0ce3d998":"fetchCancelledOrdersForMerchant()","0ce46c43":"scheduleCall(address,bytes4,bytes,uint16,uint8,uint256[5])","0ce4c990":"minRevenueToDeliver()","0ce4e104":"bnbTokenWallet()","0ce52e25":"time_on_trademarket()","0ce5a098":"getWordCount()","0ce64868":"setPendingValue(uint256,string)","0ce6bd26":"EtherCarbon()","0ce71356":"canPropose(address,uint256)","0ce84479":"Wallet10()","0ce8544a":"Ethlyte()","0ce90ec2":"levelUp(uint256)","0ce96e71":"removeAddressFromQueue(uint256)","0cea64a0":"callSomeFunctionViaOuter()","0cea7534":"withdrawMargin(uint256)","0ceaeb5a":"ecosystemSupplyRemaining()","0cec1ecd":"getPixelDistributor()","0cecf728":"ListingCancelled(bytes5,uint256)","0ced5b02":"buyTokens(uint128)","0cedd0bd":"_getDestinationPartition(bytes32,bytes)","0cee1725":"withdrawFund(uint256)","0cee22e9":"testSetBalanceSetsSupply()","0cef7d5a":"WBW(uint256,string,uint8,string)","0cef9a27":"add2MarketPlace(uint256,uint256,uint256)","0cefa4de":"minPersonalCap()","0ceff204":"withdrawRevenue(uint256)","0cf01051":"startFunding()","0cf039e3":"setBuyRequestLimitInterval(uint256)","0cf044ee":"enable_exploration()","0cf1d050":"withdrawAllToExchange(address,uint256)","0cf1dafc":"refreshRate(uint256)","0cf1dd6e":"BattleOfThermopylae(uint256,uint256,uint8,address,address,address,address)","0cf20cc9":"withdrawBalance(address,uint256)","0cf3da77":"ELCToken()","0cf45ba5":"updateFirstDuel2(uint256)","0cf56f3f":"addBetWithReferrer(uint256,address,address)","0cf59cc6":"changeScientistForElement(uint256,uint256)","0cf6d879":"getARInvTable()","0cf79e0a":"transfer(uint256,uint256)","0cf7f3b5":"changePrice(uint256,uint64)","0cf820e0":"lengthOfRecord(uint256)","0cf838e1":"Test2(address)","0cf85c4c":"stateMask()","0cf868bf":"_airdropLimit()","0cf8bcab":"setItemTransferable(uint256,bool)","0cf935c0":"getDegreeCount()","0cf93a60":"ICOweek1End()","0cf94990":"checkMD(address)","0cf94cda":"calcInvitationAmount(uint256)","0cfa0318":"approveBurn(address,uint256)","0cfa1d12":"rndExtra_()","0cfa8af4":"deleteCandidateByStage(address,uint256)","0cfb37a7":"revealProofOfPerfBlock(uint32,bytes32,bytes32,bytes16,bytes32,bytes16,bytes32,bytes32)","0cfbf6c6":"lockConfiguration()","0cfccc83":"SUPPLY_CAP()","0cfd0a0d":"INDI()","0cfd2c6a":"RecreationCultureMassMediaCoin()","0cfed2a2":"pauseSale(bool)","0cff4058":"AacharyaToken()","0d009297":"initOwner(address)","0d011088":"convert2(string,string,address)","0d015e4b":"get_depositLock()","0d02369b":"takeSellOrder(address,uint256,uint256,address)","0d024f83":"DownStats(uint256,uint256,uint256,uint256)","0d02e05c":"setBuyStatus(bool)","0d032623":"getRemainingCompanyTokensAllocation()","0d043a60":"getRewardsWithdrawn(uint32,address,address)","0d047c5b":"NewFounderAddress(address,address)","0d047d49":"getFashionsAttrs(uint256[])","0d051c52":"clearCrowdsaleCloseTimer()","0d052f39":"getBurnAdminApproval(address,address)","0d055d1e":"sendBill(uint256)","0d0567ae":"latestAddress()","0d058fe3":"create(uint256,string,address)","0d062959":"FXTOKEN(address,uint256,uint256)","0d06a2ee":"setBenefeciar(address)","0d0a1901":"secondReserveAllocation()","0d0a6bf2":"investor_clearRefBonus(address)","0d0abf52":"matureBalanceOf(address)","0d0b0c74":"loadN(uint8[],uint256,uint256)","0d0b86c6":"CryptaurDepository()","0d0b8825":"weiPerRtc()","0d0bfb2f":"ba2cbor(bytes[])","0d0c0c51":"LogParticipation(address,uint256,uint256)","0d0c2008":"TwoAndAHalfPonzi()","0d0c2c62":"MOTDiscount()","0d0c529a":"getacttslen()","0d0cd4f4":"allWalletBalances(address)","0d0d0554":"ARMYToken()","0d0d7dc9":"raiseEvent2()","0d1017d6":"EnterRentCrowdsale()","0d10e842":"weiAmount()","0d1118ce":"burnTokens(address,uint256)","0d117d16":"chunk1IsAdded()","0d11dd70":"currentRefundInvestorsBallot()","0d121337":"transferOperatorRole(address)","0d1352cf":"marketAnts()","0d13bec6":"SellAcorns(uint256)","0d13d85e":"transferMintTokens(address,uint256)","0d13ea7d":"BONUS_2_DAYS()","0d145d16":"RegisteredPlayer(address,uint256)","0d14ed4f":"midgradeOpen()","0d157352":"ForkiToken()","0d15fd77":"totalVotes()","0d16b6ca":"setBTCRate(uint256)","0d16cba5":"addMessage(address,address,address,string)","0d172a01":"transferTokenTo(address,address,uint256)","0d174c24":"setWithdrawer(address)","0d17ace0":"currentDiscountPercentage()","0d17bc2e":"_disallow()","0d17c576":"_deliverBonusTokens(address)","0d18952b":"UpdateReleasePrice(uint32,uint256)","0d1946df":"MasterToken()","0d1a0c62":"setPackSize(uint256)","0d1a0d5e":"TokensPurchased(address,uint256,uint256,uint256)","0d1a94de":"SeriesCreated(uint256)","0d1cf200":"muscFund()","0d1d38aa":"info(uint256,bytes32)","0d1d8d6d":"listTeams()","0d1dcd74":"foundersRewardsMinted()","0d1edad1":"Start8()","0d1ee029":"add(string,int256)","0d1efd7d":"getDistrictCode()","0d1f3471":"deleteRecord(address)","0d1f9bb6":"isBetLocked()","0d1fce42":"getBankroll()","0d20a889":"getRegistrantId(address)","0d213d31":"migrateTo(address,uint256)","0d2218d6":"millRaised()","0d229be7":"priceTokenWei()","0d24317d":"_getTotalHp(int256,int256,int256,int256)","0d244d68":"setNotRetractable(bytes32)","0d25320c":"distributedAmount()","0d2560ee":"addMe()","0d25b6f2":"getMonsterName(uint64)","0d260b60":"_sendTranche(bytes32,address,address,uint256,bytes,bytes)","0d26c879":"getTotalFundationTokens()","0d271720":"transferFromAdmin(address,address,uint256)","0d274929":"getChannelName(uint256)","0d27864f":"TokenSwapOver()","0d278a8b":"Technology3GCrowdsale(uint256,address,address)","0d2806ad":"TOKEN_PRICE_D()","0d285d8c":"ETH_TO_QST_TOKEN_RATE()","0d28f8d1":"importIsland(bytes32,address[3],uint256[7],uint256[8])","0d290220":"getAllCardsType()","0d290deb":"SumToken()","0d294629":"splitProfits()","0d298318":"heapSort(uint128[])","0d2a1fa7":"mintAfterIcoPeriod()","0d2a246e":"tokenDividend()","0d2a25bb":"tentimes()","0d2bd1ac":"changeFact(string)","0d2be064":"buyToken(address,uint256,uint256,bool)","0d2cbe13":"settleBet(uint256,uint256)","0d2cc54a":"rebirthAxie(uint256,uint256)","0d2ce376":"submitVote(bytes32,bytes32)","0d2e017b":"getGamers()","0d2e677a":"getHotels()","0d2f2971":"authorized_recordFailedOldOwnerTransfer(address)","0d2f99d0":"removeChild(address,bytes32,bytes32)","0d2fc226":"createTokenUri(uint8,uint8,uint64,uint64,uint64)","0d3016bf":"_getIPFSHash(address,bytes32)","0d301c75":"removeFromGoldList(address)","0d30afb0":"CONFIG_DICE_SIDES()","0d310998":"DataContacts(address,address,address,address)","0d3167da":"BarmatzTestToken()","0d325b29":"setTokenApproval(uint256,address,bool)","0d329d14":"ICOtotalSupply()","0d334130":"m_callbackGas()","0d33cfa0":"meltAddress(address)","0d342cab":"autoTransfer()","0d3471f9":"sumHardCapICOStage5()","0d349aea":"updatePaid(address,address,uint256)","0d35f64c":"teamReservedBalanceOf(address)","0d3665b5":"IloveYou()","0d368fee":"deverify(address)","0d36c02c":"BACKUP_TWO()","0d3737b0":"mintAgent()","0d37ac7f":"toggleFunding(bool)","0d381a28":"tokensByOwner(address)","0d381cad":"addJobContract(uint256,string,bool)","0d38a077":"affRegister()","0d38ea48":"ethreceived()","0d38ffcd":"donationRate()","0d392cd9":"updateWhitelist(address,bool)","0d39820c":"preInvestStart()","0d39968c":"funderSmartToken()","0d3a557e":"_allowance(uint256,uint256,bytes32)","0d3ade73":"adjustNextTranche(uint8,uint8)","0d3b7901":"withdrawBonus(address[])","0d3c1b45":"addLayer(address,uint256,string,string)","0d3c7519":"distribute_NRT()","0d3cb409":"getAdjudicatorAddress()","0d3e4044":"binary_search(uint256,bytes32)","0d3f5cb5":"findCliPendTAndSetPrfm(address,address)","0d3fbdf8":"getPI_edit_8()","0d40022a":"_buildShip(uint16,uint16,uint8,bytes32)","0d40e8d6":"supportHarvestQuorum()","0d41117f":"calculateFee(uint256,uint256,uint256,bytes32,bool,bool)","0d42240a":"isWhiteListedAddress(address)","0d425559":"ownerSetMiningProfit(uint256)","0d441f8c":"totalNacInPool()","0d465263":"assessFees()","0d469483":"fiatToWei(uint256)","0d46f410":"getProposalParent(bytes32,bytes32)","0d46f877":"irucoin()","0d46f91a":"kycCertifier()","0d472f5f":"airdrop_byadmin(address,uint256)","0d4766a3":"STARTING_SHITCLONE()","0d480993":"getFoundersTokens(uint256)","0d483442":"NO()","0d4891ad":"signalDoneDistributing(uint256)","0d48a771":"claim(address,uint256,uint256,uint8,bytes32,bytes32)","0d48e8d0":"doBalance()","0d494a05":"isICOUp()","0d498b1e":"setTokenSPUsdCentPrice(uint256)","0d49a0f0":"addProofOfPerfBlock(uint32,bytes32,bytes32,bytes32,bytes32)","0d4a464f":"_newHorseShoe(uint256,uint256,uint256,bool,bool,address)","0d4a690a":"KopiToken()","0d4a8b3b":"wadmin_freezeAccount(address,bool)","0d4b8208":"convertCarbonDollar(address,uint256)","0d4c8f62":"setPayouts(uint256,uint256,uint256)","0d4d1513":"mint(address,uint256,address)","0d4d389f":"POOL_EDIT_4()","0d4e03e1":"changeTargetWallet(address)","0d4ea316":"buyLandWithTokens(bytes32,int256[],int256[])","0d4faa05":"acheter()","0d50266c":"TEAM_PERCENT_GZE()","0d505d54":"GDX()","0d5260e7":"setGasReserve(uint256)","0d5269ab":"distributeInviteReward(uint256,uint256,uint256,uint256,uint256)","0d5302c4":"DEVCLASS_EXTRACTION_BASE()","0d533e99":"UnlockEvent(address)","0d53b406":"recordEscrowOnBid(uint64,uint64)","0d543862":"sigBountyProgramEDUSupply()","0d54c49e":"processEndGame(uint256)","0d550b75":"allowance(uint256,address,address)","0d55af64":"AFRIHUBcredits()","0d5624b3":"preSaleStart()","0d567f38":"setStartRound(uint256)","0d571742":"setGenesisAddress(address,uint256)","0d57a47f":"setTokenCountFromPreIco(uint256)","0d582f13":"addOwnerWithThreshold(address,uint256)","0d5866e2":"setDeprecated(address)","0d59b564":"submitTransaction(address,uint256,bytes,uint256)","0d59c736":"Gavsino()","0d5a13f4":"BitdealCoin(address)","0d5a5c32":"CROWDSALE_OPENING_TIME()","0d5a621b":"childContractByIndex(uint256,uint256)","0d5be2df":"ballotLog(address,uint256)","0d5d6f7a":"BitEyeExchange(address)","0d5defa4":"escrowAddress()","0d5dfdd8":"debugVal4()","0d5e1e82":"redeemReputation(bytes32,address)","0d5e4c8d":"initialPrizeWeiValue()","0d5e87f4":"calcTokenAmountByZWC(address,address,uint256)","0d5f8f17":"setXWinContractAddress(address)","0d5fced3":"CHAJING()","0d605c4a":"NUM_RESERVED_AXIE()","0d60889c":"Thanks(address,address,uint8,uint8)","0d609939":"setParameters(uint256,uint256,uint256,uint256,address,address)","0d60e231":"migrationRewardTotal()","0d6103a1":"unsoldTokensBack()","0d616d20":"withdrawContribution()","0d61a4ff":"HUT34_VEST_ADDR()","0d61b519":"executeProposal(uint256)","0d61cd5d":"mintICD(address,uint256)","0d623e10":"oracleType()","0d63e87d":"setIntervalTime(uint256)","0d63fdbe":"parseOutputScript(bytes,uint256,uint256)","0d6495ef":"View_MediatedTransaction_Status(uint256)","0d649f90":"getVisaIdentifier(address,uint256,uint256)","0d65d50b":"TIER3()","0d65e3e7":"IS_SIGNATORY(address)","0d66343c":"getPaintingOwner(uint256)","0d668087":"lockTime()","0d668818":"dataContract()","0d66a3ec":"ApisCrowdSale(uint256,uint256,uint256,address,address,address,address)","0d679531":"soldedSupply()","0d6798e2":"userFinalize()","0d67d01b":"GradeBook()","0d68ddeb":"setBUUU(bytes32,uint256,uint256,uint256)","0d694114":"addressPremineBounty()","0d6c66a1":"safesub(uint256,uint256)","0d6d1437":"changeMemberName(address,string)","0d6d1e64":"EricToken(uint256,string,uint8,string)","0d6dcab3":"getProofOfStakeReward(address)","0d6e548e":"getAgentsNum()","0d6ec16f":"isMyDrone(uint256)","0d6f6f0b":"summTeam()","0d6f72aa":"DLXV()","0d6f7ca3":"maxgas()","0d6f849b":"minAmountPresale()","0d6f8563":"withdrawWei(uint256)","0d6fef5f":"MoonBook()","0d70e29c":"isAuthorizedToTransfer(address,address)","0d70e7e3":"getRate(uint256,uint256)","0d71212f":"robotLiabilityLib()","0d7128d8":"setGoalETH(uint256)","0d7172f4":"canMakeUnrefusableOffer()","0d71aba5":"getRace(uint256)","0d729abc":"setStopDay(uint256)","0d72d57f":"backendAddress()","0d730a1a":"updateMerchant(string,string)","0d73a44a":"_collectFee(address,uint256)","0d73c10e":"totalWeiRaisedDuringICO2()","0d7519a9":"initialTokenSupply(address,uint256,bool)","0d7548f7":"seeEthPrice()","0d75d68e":"_canDownload(bytes32,uint8,bytes32,bytes32)","0d75f659":"TemperatureMeasurementA2(address,int8,int8,uint16,string)","0d7714e2":"PiedPiperCoin(uint256,string,uint8,string)","0d78573e":"releaseManager()","0d78bc17":"importCustomer(address,address,uint256)","0d7982ad":"lockMinting()","0d799734":"setMinSet(uint256)","0d7a90c8":"maxSeedStage()","0d7af726":"addGame(address,string,string)","0d7b4ac4":"setLLV_edit_27(string)","0d7b69e2":"fiatCurrency()","0d7bca61":"withdrawSuccessful(bytes32)","0d7bf53c":"getBlockHash(uint256,uint256)","0d7c064f":"setMinStandingBalance(uint256)","0d7cffb0":"PrizePool()","0d7dc36a":"setManagement(address,address,bool)","0d7eaa8b":"FudgeCucks()","0d7f7eff":"TokenDestructible()","0d8053ca":"getBetLength()","0d806df7":"setXaurCoined(uint256)","0d80b84b":"crowdSaleTime()","0d80bf64":"whitelist(string)","0d80fcdb":"distributeBonuses(uint256)","0d81057e":"multiplierOnWin()","0d81a570":"migrationDone()","0d826264":"phaseThreeLimit()","0d82cb3a":"setHeir(address,uint8,uint256)","0d830190":"getCharacterInfo(uint256)","0d831d09":"forwardUpdateFeesTo()","0d83304c":"getSales()","0d83a371":"unprocessedQueryBytes32s(uint256)","0d83dd8a":"recordNewAddress(address)","0d854646":"magic()","0d85ef17":"ZombiewCreator()","0d8693bd":"sBitcoin()","0d869ada":"immortals()","0d873644":"addToken(uint256,uint256,uint256,uint256,bytes)","0d87a7c0":"WLBDrawsDB()","0d8814ae":"cardOwnerOf(uint256)","0d882848":"BTNSold()","0d88fb04":"removePatternUserIndex(address,bytes32)","0d895ee1":"setBurner(address,bool)","0d8b2708":"functionFour(uint256,uint256,uint256,uint256)","0d8b5fa2":"testControllerValidTransferFrom()","0d8b70bf":"grantAccessMint(address,address)","0d8c1a62":"toogleActive()","0d8c1c17":"read_supply()","0d8c2f67":"_logSendWebGiftAndSendEther(address,uint256)","0d8c3c2f":"calculator(address,uint256,uint256)","0d8cba74":"PublicMiningSupply()","0d8e6e2c":"getVersion()","0d8f9cee":"disableToken(address,address)","0d8fbe23":"getDigitFromUint(uint256,uint256,uint8)","0d8fd836":"ExeniumToken()","0d9019e1":"RECIPIENT()","0d9029ea":"Cryptodraw()","0d9049f2":"createOffer(uint256,uint256,string,uint256[])","0d927924":"XPCoin()","0d92b691":"transferDefaultPercentsOfInvested(uint256)","0d92d381":"ElectricQueue()","0d92ddac":"LockEvent(address,uint256,uint256)","0d92e3e8":"claimedTokens()","0d93afef":"revokePermissionBatch(address[],string)","0d9543c5":"donateAs(address)","0d955209":"ARTWORK_STARTING_PRICE()","0d95ccc9":"setPreSale(bool)","0d963235":"setGrowthBump(uint256)","0d973d2e":"getTimestampProposal(bytes32)","0d97f395":"redeem(string,bytes32)","0d98dcb1":"getTransferPreSignedHash(address,address,uint256,uint256,uint256)","0d997dc3":"setdivsforall(bool)","0d99bbec":"calculateUSDWithBonus(uint256)","0d99edbf":"presaleWeiLimit()","0d99f40a":"setInvestors(address)","0d9b2730":"FireXToken()","0d9b71cc":"setParter(address,uint256)","0d9d19b9":"joinMatch(uint256,uint256,string)","0d9db3f1":"VertesCoin()","0d9e16d1":"Alphonic()","0d9e8cab":"winnerLast(uint256,uint256)","0d9ec228":"_price_token_ICO3()","0d9f2817":"getJobSkillsCategory(uint256)","0d9f5aed":"mixGenes(uint256,uint256,uint256)","0d9f5faa":"oasisDirect()","0d9fcb03":"juegoSillaConsensys01(address)","0da03197":"_build(uint256,int256,int256,uint8)","0da04fa6":"Smrtoken()","0da072a8":"newMediaTokenCreated(string,address,string)","0da108ff":"JointICOBonusAmount()","0da1eb03":"deleteHiddenPosition(uint32,int64,bytes16)","0da24421":"bytesMemoryArray(bytes)","0da2c5f0":"setBuyLimits(uint256,uint256)","0da2e088":"upgradedContractAddress()","0da2ee2f":"init_register_contract(bytes32,address,address)","0da30317":"ExchangerPoint(address,address)","0da304b0":"AssetToken()","0da3bec6":"addToCategorie1(address,address)","0da3e613":"EthFactory()","0da4f991":"createContinuousSaleContract()","0da4fc46":"unMutex()","0da590d4":"withdrawDevFees()","0da5f845":"unBlacklistAccount(address)","0da719ec":"onERC998Removed(address,address,uint256,bytes)","0da76f1c":"externalDecline(uint256,bytes32)","0da84bc1":"newIntegrityFeeProposal(uint256,string)","0da86f7f":"JUSTed()","0da8ba5d":"checkRecentInvestments(address)","0da95761":"upgrade(string)","0da97716":"isSignedByAlex()","0da9e3d7":"tokenIcoAllocated()","0daa431a":"currentstageplayer1()","0daa5703":"set(bytes32,bool)","0dab6e08":"getallowedContracts(uint256)","0dac3d99":"deadlineTwo()","0dae2a63":"DTXToken()","0daf233b":"agingTimeByStage(uint256)","0daf37e6":"Sales(address,uint256,string,uint8,string,uint256,uint256,uint256,uint256,uint256)","0daf7a8c":"setBlacklistInternal(address,bool)","0daf96f9":"ThaiBahtDigital()","0daf999a":"heroContract()","0dafc58f":"Compound_now_Accrued_interest()","0db02622":"ownerCount()","0db03955":"fundingProcessed()","0db0624a":"z_Determinations()","0db1b335":"getNextMaximumPlayers()","0db293cb":"depositDekla(uint256,uint256,bytes,uint256)","0db38253":"DEFAULT_CLIFF()","0db38f66":"BetChampion(uint256)","0db3be6a":"decrementOpenInterestFromMarket(uint256)","0db49c84":"TokensSold(address,uint256,uint256,uint256,uint256,uint256)","0db4bad0":"claimDate()","0db5db26":"weiToOwner(address,uint256)","0db6a786":"SALES_DEADLINE()","0db6ba9b":"debugGetNumPendingSubmissions()","0db71d53":"createCrowdsale(uint256,uint256,uint256,uint256)","0db73c72":"noevent()","0db74aaa":"getInvestorBalance(uint256)","0db75ab9":"UsingAVirtualStruct()","0db79003":"addWineryOperationByRegulator(string,string,string,string,uint256,uint16,string)","0db81580":"purchaseAd(uint256,string,string)","0db9d891":"icoEndOfStageA()","0dba2400":"addToMidnightPrize()","0dbb78ce":"showPoolMembers(uint256)","0dbbc14c":"endOfROSCARetrieveSurplus()","0dbce4dd":"registerCandidate(string,string)","0dbd5270":"numberOfBackers()","0dbd5e81":"Send_Data(uint16)","0dbda70b":"angelOnLeaderboards(uint64)","0dbe671f":"a()","0dbea6d0":"robotRefund(address)","0dbedee7":"getNFTbyTokenId(uint256)","0dbf19cb":"PRICE_RATE_LAST()","0dbf23f4":"vehicleregistration(address,string,string,string)","0dbf2a3f":"isNewWeek()","0dbf527e":"MintedToken(address,uint256)","0dc03ec7":"INFLIV(uint256,string,uint8,string)","0dc06e50":"postTX(address,uint256,uint256)","0dc081c5":"tokenTransferOwnership(address)","0dc10a60":"advisorsAddress()","0dc115c8":"coinanxtemp()","0dc16a56":"getDepotEth(address)","0dc174bd":"track(address)","0dc1819f":"purchase_tokens()","0dc193f5":"getEtherReceived()","0dc1d357":"isAfterEnd()","0dc224ec":"partnersMintLockEnd()","0dc26492":"bankPercent()","0dc2e439":"setBZxAddresses(address,address,address,address)","0dc30397":"counterAppeal(uint256)","0dc3279d":"maxnumber()","0dc32b72":"EtherStopLoss()","0dc36f2a":"migrationAgentCandidate()","0dc5bffb":"crowdsaleTokenAmount()","0dc6bae5":"allowFreezeBypass(address)","0dc6c392":"Puttu()","0dc7bd07":"testBurnAuth()","0dc8b5a8":"shortenPreIco(uint256)","0dc8f435":"Party(address,uint256)","0dc96015":"getVotes()","0dc9c838":"changeSaleTimes(uint256,uint256)","0dc9ebfe":"FoundationAddr_()","0dca59c1":"debt()","0dca7ed8":"winningOption(uint256)","0dcad340":"getCitizenLocation(address)","0dcaf3e2":"test_setupSucceeded()","0dcb4627":"_addPendingRequestId(uint32)","0dcc59e6":"DEFROST_INITIAL_PERCENT_OWNER()","0dccca72":"showFPLocktime()","0dccfde4":"WithdrawProfitFunds(uint256,address)","0dcd772c":"AmountSent(address,uint256)","0dcd7a6c":"sendMultiSigToken(address,uint256,address,uint256,uint256,bytes)","0dcd9759":"PPToken(uint256,string,string)","0dcdefa8":"playThreeDiceTotal(uint256,uint256)","0dce06c1":"goalOfState(uint256)","0dcec63d":"updateEtherPrice(uint256)","0dcf298b":"pollExists(bytes32)","0dcf38a9":"FirstPaySend(uint256,address)","0dcf4b8f":"totalContribution()","0dd0a042":"lock(bool)","0dd0cf9e":"founderAdress()","0dd12d38":"moderatorTransferFrom(address,address,uint256)","0dd1d147":"ActionCompose(address)","0dd27120":"exchangeState()","0dd2d96c":"doFinalize()","0dd2d9c0":"Rookcont()","0dd30c81":"toB32(uint256,bytes,uint256)","0dd327fe":"FundsKeeper(address)","0dd32910":"welcomeMsg()","0dd3e1b1":"CNT_Crowdsale()","0dd3fd03":"buySpins(uint256)","0dd5db48":"startPreSale1()","0dd5e582":"masterTransferFrom(address,address,uint256)","0dd5ee1b":"verify(address,bytes32)","0dd636ef":"setBuyDividendPercentageFee(uint8)","0dd63ba3":"setIntArrayIndex(bytes32,uint256,int256)","0dd6a4ad":"addOversight(address)","0dd6eae1":"setCourse(uint256)","0dd84392":"setAllowance(address,address,uint256,uint256)","0dd8cdbb":"initRegistryData(address,address,address)","0dd93b56":"restartAuction()","0dda20d1":"sellCrystalDemand(uint256,uint256,string,string)","0dda350f":"dumpdivs()","0dda507e":"manualFinish()","0ddc4a94":"WHOLESALE_TOKENS()","0ddcc528":"Testable(bool)","0ddcfe8e":"checkAddress(address)","0ddd0824":"checkHash(bytes32,bytes32,uint256)","0ddeb632":"buy(bytes32,uint256)","0ddeeb4f":"tokenSaleUpperLimit()","0ddef58d":"isUnfrozen(address)","0ddf0bfd":"Cryptogs()","0ddf0c41":"updateCandidate(address,string,string)","0ddf78c2":"divForEthertoteDevelopmentWallet()","0de0271e":"paymentReceived(address,uint256)","0de04691":"testCreateWithParentForeign()","0de0b1bc":"giveBirthByUser()","0de1f4c1":"CreateCodeToken(uint256,string,string)","0de2b2d8":"openPosition(address[11],uint256[10],uint32[4],bool,bytes,bytes)","0de3513a":"test_validRuleChange()","0de39733":"activateFlat(address,uint256)","0de3b100":"VoteForProposal(uint256)","0de41aa4":"checkIfAddressIsWhitelisted(address,address)","0de41e45":"lockBegunAtBlock()","0de54c08":"setUpgradeController(address)","0de607c3":"makeSubscriptionID(address,uint256)","0de6aa7f":"getOneTimeCostsPaid()","0de94e4a":"HodlEth(address,uint256)","0de96dff":"giveBack()","0de9b825":"sellShip(uint256,bytes32)","0de9cacd":"reCalc()","0dea35bf":"playerBet(uint256)","0dea38b6":"VESTING_TIME()","0dec1c23":"requestDetachment(uint256)","0dec5d85":"initializeCrowdsale()","0ded195e":"freezeTokensOfOneUser(address)","0ded7f62":"secondBonusEnds()","0dedffb8":"feedAndMultiply(uint256,uint256)","0dee302e":"transferToRef(address,uint256)","0dee34ed":"tokensaleStageAt(uint256)","0dee3863":"nameEntriesCount(bytes32,uint16,bytes32)","0dee4af0":"doThrow(uint256)","0def3866":"updateChamp(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool)","0df04802":"_7_russkayaRuletka()","0df07980":"secondLevelPrice()","0df0de11":"ownerChangeBuyerfee(uint256)","0df104d7":"EtheeraToken(address)","0df12532":"setpricefactor(uint256)","0df18942":"hsub(uint128,uint128)","0df19d35":"lockup(address)","0df22268":"CryptoSanguoToken()","0df23e5b":"saleCounterThisPhase()","0df2dcd2":"OdinToken()","0df3a342":"_coldStorage()","0df4135a":"CMCT()","0df428f0":"GoldenFleeceToken(uint256)","0df62a33":"Lilbank()","0df63210":"DOMAIN_SEPERATOR()","0df71602":"setWinner(uint256)","0df76370":"createInvoicingAddress(string,string)","0df8cbfe":"isCluster()","0df8e481":"setassetPrice(uint256)","0df9178f":"LimeEyes()","0df9d568":"CentraWhiteList()","0dfa1140":"_RaffleDraw()","0dfa71ae":"salesAgent()","0dfad849":"TokenSale(address,address,address,address)","0dfb0297":"changePriceSelectFight2Death(uint256)","0dfb6615":"user(bytes32)","0dfbdcc5":"lethalBonusAtHits()","0dfc2bcd":"originalFunds()","0dfce266":"setCovman(address)","0dfd085a":"ICOBeginsAt()","0dfd45f9":"removeHelper(address)","0dfd799c":"SponsoredLink(string)","0dfdcb76":"setAuctionWinnerMessageHash(bytes32)","0dff5cb9":"bop()","0e001ec0":"balanceOfContractFeeToken()","0e011262":"mockWhiteList()","0e014cf8":"viewBalance(address,address)","0e0280d0":"bookRoom(string,uint256[],uint256,address,bytes32)","0e0290a4":"_3_orientation()","0e037cc0":"bulkRemove(address[])","0e03f276":"setLLV_edit_7(string)","0e04a7d8":"isGameOver()","0e05a512":"superVoteAgree(address)","0e0643ae":"EvTokenAdd(uint256,uint256)","0e06e7ef":"NFOCoin(uint256,string,string)","0e0701be":"test_oneValidEqStringUint(int256)","0e07419c":"ConversionStarted(uint256)","0e07658b":"eliminate(uint256)","0e07ef81":"registerNameXname(string,bytes32)","0e0a0d74":"getAmount(bytes32)","0e0a6f0c":"getHours()","0e0ac84c":"QBASE()","0e0afb86":"getKYCVerificationContractAddress()","0e0b3519":"rateTierHigher()","0e0bc104":"computeNextGen0Price()","0e0c3f58":"super_transfer(address,uint256)","0e0c8241":"MAXIMUM_LOOP_BOUND()","0e0d3567":"highestAddressReserving()","0e0d946b":"CyberPayToken()","0e0dbd72":"updateToSendFromStorage(address)","0e0e26da":"getRemainShareAmount()","0e0e4acc":"LIANG(uint256,string,string)","0e0e73a8":"next_round_players()","0e0f05a5":"executeRaiseCapital(uint256)","0e0f1f00":"allocationAddressPreICO()","0e0f55d0":"RewardOrder(uint256,uint256)","0e0fec9f":"Arbitrage()","0e1087c3":"getMarketMakerFunds()","0e10e99d":"Vault(bytes32)","0e10f1ae":"X2()","0e114c89":"setBonusAffiliate(uint256,uint256)","0e11624b":"crowdsaleBalances(address)","0e136b19":"deprecated()","0e137368":"getBorrowInfo(uint256)","0e13af5d":"lockedTokensWallet()","0e13b9af":"getValue(uint8,uint8)","0e1456c0":"maxPreSale2Token()","0e149b52":"RBRToken()","0e14a376":"deleteAddress(bytes32)","0e14f955":"readyTobreed(uint256,bool,uint256,bool)","0e153d48":"MarketStake(address,address,address,address)","0e15561a":"totalRewards()","0e1565c2":"getClaims(string)","0e15dc89":"sizeOf()","0e169119":"grantAccess(bytes32,address,string)","0e18d11e":"changeFunder(address,address)","0e18ea3c":"fuoco()","0e19bac1":"MOBILINK()","0e19f74f":"makeDeposit(uint256,address,address,address)","0e1a0217":"boolOrRevert(bool,uint256)","0e1a0399":"calculateWithdrawalAmount(uint256)","0e1a9e3f":"getJobSkillsArea(uint256)","0e1ac81f":"natecoin(uint256,string,string)","0e1ae0e4":"RateUpdated(uint32)","0e1af57b":"getScore(uint256)","0e1b39fb":"Wallet()","0e1c0188":"errorTickerQueryError(string,bytes32)","0e1c2d46":"deliveryVSpayment(bytes32,uint8,bytes32,bytes32)","0e1c6491":"getTotalBettersForFighter(address,address)","0e1ca8a5":"Oraclize()","0e1cdd2d":"getStandardComponent(uint256)","0e1cfd97":"tokensub(address,uint256)","0e1d2ec8":"isUpdatable()","0e1d88fc":"addTender(uint256,uint256,address,uint256)","0e1da6c3":"claimTimeout()","0e1e1d0f":"removeAuthorized(address,address)","0e1e3914":"coreSupply()","0e1e56f7":"Tix()","0e1f6d3b":"DIGC(address[],uint256[])","0e1fa28f":"containMinValueFromOther(uint256,address)","0e1fd315":"changeWhitelistStatus(address[],uint256[])","0e20ebe2":"right96(uint256)","0e213129":"ZestCoin()","0e216954":"ReturnEthToEtherhero()","0e21750f":"setFund(address)","0e219339":"getContractHash(string)","0e21a6a6":"ADD_TIERS(bytes32)","0e21c886":"OWNERS_TOKENS_AMOUNT()","0e21f784":"getCoverImage(address,uint256)","0e21fce3":"Suggest(string)","0e2286d3":"rdiv(uint256,uint256)","0e22dc5b":"getAllCommentIdsByAd(uint256)","0e2318cb":"BonumFinancialTokenPreSale(uint256,uint256,address,address,uint256)","0e234cd4":"countBonus(uint256)","0e2350ba":"TopCoinSaleClosed()","0e239679":"SputnikToken(address)","0e2451c7":"Lilith()","0e24c52c":"register(string,string,string,string)","0e24c810":"calcAmountWithBonus(uint256,uint8)","0e2562d9":"getAccountAddress()","0e25b620":"addFreeze(address)","0e263906":"transferToBranch(address,uint256)","0e26fb41":"SeniumSupply()","0e27324d":"approveKYC(address)","0e274eab":"pullTokens()","0e275b49":"artworkSaleCount()","0e27e3df":"removeConsumer(address)","0e2833eb":"random(uint8,uint8)","0e288064":"setManyBonusExtra(address[],uint256)","0e28bc4a":"CanceledAuctionEvent(address,address,uint256,uint256)","0e2916e1":"requestClosingChannel(uint256)","0e2984d1":"Cancel(uint64,address,address,uint256,int256)","0e29df22":"sendEther()","0e2a05c8":"delayOfICO2()","0e2a273f":"getCandidateIndexArrayLength()","0e2a9237":"r15Backers()","0e2b75cc":"setWhitelistedMemberTypes(uint256[])","0e2cfe93":"getPercent(uint8,uint256)","0e2d1a2a":"vestedBalanceOf(address)","0e2d27cd":"claimUnsoldCoins()","0e2dc949":"TIER_3_BUYIN()","0e2dce69":"Play()","0e2df9aa":"Withdraw(address,uint256,int256)","0e2e4037":"removeOwnersConfirmations(address)","0e2e4ce8":"maximumLockYears()","0e2ebe6c":"GetPoolInformation(address)","0e2f0a0f":"weiReceive()","0e2f5fb3":"getThree()","0e2f8058":"setBCFContractAddress(address,address)","0e2f94a6":"RegionsToken()","0e30643f":"MemberChanged(address,uint256)","0e30cda7":"getTotalCoinsAvailable()","0e316ab7":"removeSigner(address)","0e32a720":"sendMarketByOwner(address,uint256)","0e336f00":"getSeedsSinceLastHatch(address)","0e33e181":"get_modulo_value(bytes32,uint32,uint32)","0e3484c1":"DelGift(string)","0e34df82":"openTicket()","0e351605":"transfer_token(address[],uint256)","0e3589d9":"DAILY_FUNDS_RELEASE()","0e366cbf":"ourLastJackpotWinner()","0e3802e9":"addRewardToken(address,uint256)","0e388774":"setContractorImpl(address)","0e38901a":"unvault(uint256)","0e39b210":"founders_1()","0e3a04a7":"digitalcashToken()","0e3a23db":"mineMany(address[],uint8[],bytes32[],bytes32[])","0e3a997e":"countPartnerPlayers()","0e3ab61d":"startSale(uint256)","0e3b70fd":"month48Allocated()","0e3bc6ca":"BLOCKLAND()","0e3be37d":"ToggleTransferAllowanceFor(address,bool)","0e3c8068":"BotpyToken(uint256,string,string)","0e3c9563":"privateIssue(address,uint256)","0e3d2202":"feeFixed()","0e3db9f2":"startNow()","0e3e9a67":"FundsMigrated(address)","0e3f732a":"TheGame()","0e3fd8c2":"getSolid(uint256)","0e407bdd":"soldTokensMainSale()","0e414500":"setClaimingStart(uint256)","0e417055":"address5()","0e41c63b":"addHistory(uint256,address,uint8)","0e420f42":"setEventResult(string,uint64,uint8)","0e429ecc":"providerValue()","0e4355d4":"validFactories(address)","0e43806a":"Rental(address)","0e438ee5":"withdrawTeamToken()","0e43d7c3":"getUserRoleBitmask(address)","0e449cf9":"foundersTokens()","0e4649fd":"LogProcessedInterval(uint64,uint64)","0e46695e":"sumHardCapICO2()","0e468245":"pledgeEth(uint256)","0e473722":"volumeType4()","0e4739b1":"_refulshFrozenInfo(address)","0e476e27":"getten(string)","0e479dc7":"getShop(address)","0e47c259":"evolveByAtom(uint256)","0e47c76f":"rotate(uint64,uint256)","0e496d25":"VICETOKEN_ICO_IS_FAKE()","0e4983ff":"setSecondsAfter(uint256)","0e4a4e8c":"fechVoteNumForCandidateByStage(address,uint256)","0e4aed3f":"yearlyRewardPercentage()","0e4b0ba8":"account2Address()","0e4b10b6":"totalETHLimit()","0e4b8389":"getEstKeyBlockNr(uint256)","0e4c3aa6":"OrangeCirculateChain()","0e4d5919":"PHASE1_START_TIME()","0e4debbc":"SHIT()","0e4e0054":"isIcoFinshed()","0e4e47cb":"claimAfter90days()","0e4e5d93":"_bidERC20(address,address,uint256,uint256)","0e5004e6":"_calcPhasesPassed()","0e501834":"emergencyTransfer(address)","0e51574f":"endGameRound()","0e51c00d":"getPawnStatus(uint256)","0e5229b0":"addOwner(address,uint8)","0e5263fa":"discountedTokensPerDollar()","0e5356ec":"testEvents()","0e536ff4":"ratifyMint(uint256,address,uint256)","0e5376d6":"vars()","0e53aae9":"connectors(address)","0e53bf67":"producedDiamondCaps()","0e541185":"pauseBet(uint256)","0e542f82":"refundOptions(address)","0e54316f":"setSantaClaus(address)","0e54a883":"setPublicSaleDate(uint256)","0e54b872":"registerUser(string,address)","0e54d1fc":"pruneShareholders(address,uint256)","0e554bd8":"scheduleCall(bytes,uint256,uint256,uint8)","0e5689bc":"getBidsNum(address,uint256)","0e56f529":"guardarDocumento(string,bytes32,bytes32)","0e58369f":"registrator(address)","0e583df0":"GEN0_STARTING_PRICE()","0e587aee":"set_presale_arbits_per_ether(address,uint256)","0e58d08c":"setInvestmentGateway(address)","0e597ed9":"PreCrowdsale(address,address)","0e5a6c70":"peep()","0e5aaace":"initIcoRule()","0e5aaffc":"getSellingItemByObjId(uint64)","0e5c011e":"harvest(address)","0e5c6a3d":"_withdrawTo(address)","0e5ceb47":"register(bytes32,bytes32,string)","0e5d095d":"codepointsOf(uint256)","0e5d4b99":"fechVoteMainInfoForVoter(address)","0e5e36fb":"TCH(uint256,string,uint8,string)","0e5e4d72":"createAndExecuteTransaction(address[],uint256[],uint256)","0e5fc721":"addUserBalance(uint32,uint64)","0e5fdad4":"releaseTeamTokenTransfer()","0e5ffb3c":"hashVersion(uint32,uint32,uint32,string,string)","0e60de7a":"rinkeby3()","0e620d70":"MultiSend()","0e62fde6":"getAttributeTypeID(uint256)","0e6436d2":"TokenChange(address)","0e64780d":"distribute(address,uint256,uint256,uint256,uint256,uint256,uint256)","0e64ff0e":"tradeWalletTokens(address,uint256)","0e655432":"adventureItemContract()","0e65e5d9":"ETBSToken(address)","0e662cf0":"buyTokens(uint16)","0e662ff9":"oddEven(uint8,address)","0e666e49":"userExists(address)","0e67cf6c":"GetWageredWei(bytes32)","0e67f4bb":"ReferrerRegistered(address,address)","0e6848cc":"massNotify(address[])","0e686170":"changeTotalAirdrop(uint256)","0e687501":"OpticalNetwork(address)","0e68c2f0":"finishPurse(uint256)","0e69782b":"BCTT()","0e698493":"transferFounderTokens(address,uint256)","0e69890f":"withdrawATN()","0e69d16b":"testToSliceB32()","0e6ae3fb":"bid(string,string,uint256)","0e6b0afc":"adminContractSettings(uint32,address,uint256)","0e6b5823":"changeMaxBet(uint8[157])","0e6bc36c":"OkeToken()","0e6c04db":"icoThreshold1()","0e6c5f93":"changeAddr(address)","0e6ce30d":"createNew(uint256)","0e6d1de9":"getLatestVersion()","0e6d3a89":"mintingState()","0e6dfcd5":"redeem(address,address,uint256)","0e6e1b3e":"addSubject(bytes32)","0e6e4f3e":"lockPlayerFunds(address)","0e6f21f2":"sendBatches(address[],uint256)","0e6f2cf8":"game_withdraw()","0e708203":"rewardAccount()","0e70ab11":"addEthBonusToBuy(address,uint256,uint256)","0e70f147":"immediateRefund()","0e713a50":"_preValidatePreICOPurchase(address,uint256)","0e714202":"returnContributionsToTheSponsors()","0e7238f1":"setNormalRoomMax(uint256)","0e741a36":"generateVoteSecret(string,uint256)","0e7470cb":"getFullProfit(uint256,uint256,uint256)","0e757191":"finalizeRound(bytes32,uint8,bytes4)","0e757a2e":"testSetAndGet()","0e78501f":"ChangeStart(uint256)","0e787cce":"predict(bytes32)","0e792536":"removeGlobalConstraint(int256,address,int256,address)","0e7938ec":"tokenCreateFunction()","0e79964c":"getBoolField3()","0e7a2d4e":"isInAssetList(address)","0e7a967a":"_distributeBountyToken(uint256)","0e7b592a":"Halo()","0e7b8e07":"Sleipnir()","0e7b9f10":"hasBuyerLotteryBonusWon(address)","0e7bda18":"addAddressListItem(bool,address,address,uint256,address)","0e7c0f80":"masterCopyCountdown()","0e7c1cb5":"originalToken()","0e7c5d2b":"test_validEmptyEqEmpty256()","0e7ce976":"owner_bonusSend()","0e7d490d":"numberOfVotes()","0e7ebce4":"min_bid()","0e7f2be7":"DecreaseAllowance(address,uint256)","0e7f756a":"totalAssetUnits()","0e801d7a":"ticket(address,bool,uint256)","0e80d8b9":"PRICE_SALE()","0e816f66":"payForYourGladiator(uint256)","0e830e49":"setEngine(address)","0e8354b9":"CreateOOG(address,uint256)","0e83afbb":"approveTokens(bytes32,address,uint256)","0e83d92b":"playerPull()","0e840284":"LMDA()","0e848c1d":"NeoBitToken()","0e850239":"scheduleCall(bytes4,bytes)","0e856588":"getScheduledTimelockCount(address)","0e858b64":"setBridgeValidatorsOwner(address)","0e8670e0":"highestPrice()","0e86b63e":"calcLevel2Bonus(uint256)","0e86ec01":"doConfirmDeath()","0e870871":"rateOfZLT()","0e87457b":"ZincElement()","0e887cda":"getUserMoney(address)","0e88aace":"contractErc20Token()","0e88c4a4":"RegisterMine(string,uint256,address)","0e89341c":"uri(uint256)","0e89439b":"stake(uint256,bytes)","0e8a4ac7":"getPositionPrincipal(bytes32)","0e8b3971":"mintTap()","0e8bf00e":"ReleaseOfAccount(address,uint256)","0e8c0cdd":"_mineableSupply()","0e8ca718":"transferCurationRights(address)","0e8da019":"getInitRound(uint256)","0e8de473":"getDividendBalance(address,address)","0e8ef0c1":"systemOnSaleCount()","0e8f0a95":"commonDiscount()","0e91f4b3":"removeBadToken(address)","0e923d3b":"submitEther(address)","0e9279a0":"BountyManager()","0e929611":"AdminRemoval(address)","0e92eb6d":"sellMyTokens(uint256)","0e934447":"createPromoPlayer(address,string,uint256,uint256)","0e940fd8":"CELL_ADD_SPACE()","0e94869e":"ArJoust(uint256,uint256)","0e94a0ee":"proofToken()","0e95e127":"readpriceXname(string)","0e96127a":"transferEther(address,address,uint256)","0e96938c":"matchExistingBids(bool,bytes32)","0e972421":"isSpawningAllowed(uint256,address)","0e975f73":"FirstPeriodEndDateUpdated(uint256,uint256)","0e978e81":"AgriChainDocumentContract()","0e97cfdf":"placeOrder(uint256,uint256,uint256)","0e97e3d3":"validateAuthentication(address,uint256,uint256)","0e97fa7a":"setEarlyParticipantsWhitelist(address[],bool[],uint256[],uint256[])","0e98f811":"reservedTotalSupply()","0e995ff5":"cd()","0e997ce3":"IPMCoin()","0e99b380":"getCoinAddress(bytes4)","0e99f5e6":"claimBonus(address)","0e9a9dbb":"signature(string,address,bytes32)","0e9aa208":"getAddressAdmixture()","0e9b6281":"setSubsidy(uint256)","0e9cbbad":"PurchaseFailed(address,uint8)","0e9ccb94":"Boboho()","0e9d02cc":"setTokensPerKEther(uint256)","0e9d56a2":"getTotalEth()","0e9e543a":"collectableTokenOf(address)","0e9ecedd":"mEtherInvalid()","0e9ef902":"join_voter()","0e9f0816":"getContractHash(uint256)","0e9f9f86":"isMinimalReached()","0e9fb0ed":"getOptionAddress(address,uint256,address,uint256,uint256,bool)","0e9fd199":"licenseAffiliate(uint256)","0ea008c8":"bonuscalpre()","0ea04562":"requestRandom(uint256)","0ea12558":"girlIdToOwner(uint256)","0ea126f9":"registerUser(address,string)","0ea17a76":"safe_mul(uint256,uint256)","0ea1f459":"DVCToken()","0ea227e7":"StarTravelLane()","0ea317a9":"SUNCOIN()","0ea37c64":"repost(uint256)","0ea412ab":"_setPrice(uint256)","0ea49bc1":"changeRental(address)","0ea51122":"decreaseMarketCreatorSettlementFeeInAttoethPerEth(uint256)","0ea5edea":"payTodayReward(address,uint256)","0ea662ea":"hourPot()","0ea733bf":"setmyPrice(uint256,uint256)","0ea7a110":"getEmployee(address,uint256)","0ea7c8cd":"airDeliver(address,uint256)","0ea7ee82":"testRegisterAndVerified()","0ea81cf9":"initialPokemonInfo()","0ea8e5ac":"tokenPriceIncremental_()","0ea9e4f1":"doInitialReport(uint256[],bool)","0eaac106":"TokensAdded(address,uint256)","0eaadd04":"_addBurner(address)","0eaaf4c8":"withdrawBid(uint256)","0eaaf5ac":"auction_start_time()","0eab31b1":"initAuctions(uint256,uint256,uint256,uint256)","0eaba26a":"getCurrentValidatorsLength()","0eabdab6":"removeOracles(bytes4[],address[])","0eabeffe":"sendMessage(string,string,string)","0eac6ae7":"getClientAtIndex(uint256)","0eac7a0e":"transferToAnotherAddr(address,address,uint256,string)","0eacecd2":"getEquipTokens(address)","0eacf634":"BKCToken()","0ead3ec8":"payeePricePerPart()","0eada49f":"standingOrdersByPayee(address,uint256)","0eae2f86":"initAccount(address,uint256)","0eae73dd":"stringToAddr(string)","0eaee52c":"setGrantsUnlock(uint256,bool)","0eaf94c3":"secondDueDate()","0eafb6da":"getCapInWei()","0eafe473":"balanceOfCoin(address)","0eb05d49":"viewGoldList(address)","0eb0afa6":"createDebt(address,address,uint256)","0eb14edb":"Mondo()","0eb15f0f":"claimRewardWithBlockData(uint256,bytes)","0eb1947f":"changeGatewayAddr(address)","0eb288f1":"executeTransaction()","0eb34740":"lockedTokens()","0eb3f5a0":"sweepCommission(uint256)","0eb3f993":"getAreaQualityByDay(uint32,uint32)","0eb40426":"IncPreSupply(uint256)","0eb40916":"EthernautsStorage()","0eb43fe3":"SaleClockAuctionERC20(address,uint256)","0eb495c2":"pushCity()","0eb4c7d6":"checkTeamUnlockedTokens(address)","0eb4d170":"setLockup_dakehus(address,uint256,uint256)","0eb51018":"getProductOperation(string,address,uint256,uint256)","0eb523ac":"PRIVATE_STAGE_FINISH()","0eb524d4":"block1()","0eb5a167":"XCloudRoc()","0eb6f543":"hodlerTotalValue6M()","0eb82c13":"updateHpbNode(address,bytes32,bytes32,bytes32)","0eb8d153":"AICoreCoin()","0eb8ed07":"transferEnable(bytes32)","0eb8fe7a":"getChannelCount()","0eb944d5":"PiperToken()","0eba6b06":"getChannelInfo(address,address,uint32)","0eba7f2d":"SomeCoin(string,string,uint8,uint256)","0ebb0d30":"getSummaryReferralProfit(address)","0ebb172a":"WITHDRAWAL_DELAY()","0ebbe5d6":"firstPrivateLockTime()","0ebbf213":"AddPauser(address)","0ebc1568":"viewTokenName(uint8)","0ebdc43a":"IsSaleEnabled()","0ebe0f32":"HacToken()","0ebe31c8":"getCountTrack()","0ebe4acb":"EtherModifierMonstro()","0ebf0bcb":"FAID(uint256,string,uint8,string)","0ebf3886":"CryptoLandmarks()","0ebf5f27":"Reservation2(address,uint256)","0ec0692a":"prizeEth()","0ec0786d":"tb()","0ec08b29":"getLoopLimit(uint256,uint256)","0ec0fce5":"setPercentage(uint256,uint256,uint256,uint256)","0ec1268c":"_freezeFunds(address,address,uint256,uint256)","0ec12782":"internet()","0ec173d0":"changeTreshold(uint16)","0ec1b057":"verify(bytes32,string,string)","0ec1ce16":"_getCurrentRate()","0ec1e7ac":"claimBalanceByOwner(address)","0ec2c379":"_getJYPCBonus(uint256)","0ec2c5d7":"loik()","0ec3b247":"testControlSetEnforceRevisionsNotOwner()","0ec3f62e":"NITRONEUMERC20(uint256,string,string)","0ec48a42":"quater4()","0ec4fb0a":"WHITELIST_PERIOD()","0ec52541":"unshelf(string)","0ec59606":"addPlayerTxHistory(address,uint256,uint256,uint256,uint256)","0ec5c49a":"changeEthToTokenRation(uint8)","0ec6688d":"intrepidSoldCount()","0ec66924":"getStudentRequestsLength()","0ec6b08d":"validIdentifier(uint256)","0ec78d9e":"setup(address[],uint256,address,bytes)","0ec843d1":"setMinAmount3Round(uint256)","0ec852f2":"QuranToken()","0ec89f2b":"requiredProgressOfPreviousDungeon()","0ec8c387":"getContractRates(bytes32)","0ec8e2b4":"Moneyplant()","0eca4c92":"CryptoPunksMarket()","0ecae7d3":"wager(bool,uint256,uint256,uint8,bytes32,bytes32)","0ecaea73":"create(address,uint256)","0ecb93c0":"addBlackList(address)","0ecba3f8":"BusinessAutomationUnion()","0ecd0424":"decompressPoint(uint256,uint8)","0ecda113":"freezeEndTime(uint256)","0ecdbfd4":"DesingCoin()","0ecdd94f":"goldFeeDataUpdatedAtBlock()","0ecea92c":"allowInvestor(address)","0ecf19e5":"balanceWithoutFreezedBonus(address)","0ed0b19f":"resetBonusPool(uint256,uint8)","0ed15d23":"dInit(address)","0ed21029":"getIssueAssignee(uint256,bytes32)","0ed2fc95":"exchange(address,address,uint256,uint256)","0ed387c1":"getSpinsContainer(bytes32)","0ed3909c":"startBonusCompaign(uint256)","0ed3d5b9":"passed(address[])","0ed40dff":"resetAppendDecryptedBids(uint256)","0ed469b8":"houseFee()","0ed5410a":"endOfRewards(bool)","0ed59a60":"releaseProof(bytes32,string)","0ed5a933":"isCanceled()","0ed61407":"makePick(uint8,uint256)","0ed659b4":"getLLV_edit_18()","0ed68aa5":"getPlanetOwners(uint256,uint256)","0ed6b171":"LogStartICO()","0ed74c08":"func_0C2C()","0ed7a0f2":"Predatex()","0ed7c905":"FantomToken()","0ed86f04":"withdrawDivis()","0ed9b97b":"buy_fromContract()","0edaf441":"lockAddressRegistration(address)","0edc1923":"changeMaximumHodlDuration(uint256)","0edc4737":"SEED()","0edc54a8":"holdTokens(address)","0edd2ffc":"penalty()","0edddd3e":"lstFunc(uint256[])","0ede050b":"ico3Max()","0edf2134":"deathData_a17()","0edfb0f7":"withdrawCollectedInterest()","0edfe7ec":"setBackendWallet(address)","0ee02d9d":"getHash(address,address,uint256,bytes,address,uint256)","0ee07836":"adjustDifficulty(uint256)","0ee21ddc":"setEtherPriceUSDWEI(uint256)","0ee2b0e6":"commissionToWithdraw()","0ee2cb10":"getCreator()","0ee2ce58":"VKNToEth()","0ee33128":"RequestRefund()","0ee33c70":"claimed_blocks()","0ee36dbc":"setParamsStopSale(bool)","0ee3c31d":"getUserIndexOnEther(address)","0ee4229c":"grantReservedToken(address,uint256)","0ee454dc":"getBUB(bytes32,uint256)","0ee526e0":"enableMintToken()","0ee5ca1f":"secondsLeftPublic()","0ee62c77":"getStageVolumeBonuses(uint256)","0ee75f6b":"TOKEN_THIRD_PRICE_RATE()","0ee7968e":"REWARD_NUM()","0ee79fb3":"closeReferendums()","0ee7c858":"beatMartialOwner()","0ee7f045":"TransferSellAgent(address,uint256)","0ee85800":"getCFOHashing(address,uint256)","0ee8e338":"testFailCreateWithParentsForeignNotInUse0()","0ee95ecf":"getNextPrice(bytes32)","0eea10b1":"sysPer()","0eeb63b9":"getUserAccountTokenBalance(address,address)","0eebd59b":"log_recast(address,uint256)","0eebdb04":"AprilAirdrop(address,address)","0eecae21":"draw()","0eecc2a3":"updateRequiredTimeBetweenDraws(uint256)","0eeccb84":"removeAdvisor(address)","0eedc7b5":"voteDescription(uint256)","0eedc9d9":"payAffiliate1Address(address)","0eefdbad":"tokenTransferProxy()","0ef12aa9":"getUserID(address)","0ef14b98":"viewFirstLotOfClauses()","0ef25f8b":"TicTacToeRules(address,address,address,address,uint256)","0ef26743":"height()","0ef270d5":"CreateNewAccount()","0ef2d7af":"bonusDeadline()","0ef43cbd":"confirmerNouveauProprio()","0ef486d1":"revisions(uint256)","0ef504ae":"preSaleHalted()","0ef524ff":"setDefaultMint(uint256)","0ef5a7e0":"allocateToCrowdsalePurchaser(address,uint256)","0ef60e48":"setRubusOrangeAddress(address,address)","0ef67887":"Balance()","0ef6eb9c":"getCompte_33()","0ef71d79":"privatized(bytes32,bytes32)","0ef72880":"DADXChainERC20()","0ef76243":"withdraw_Arina(uint256)","0ef7cc8e":"metadataOf(uint256)","0ef845df":"propose(address,string,string,string,string,string,uint256,uint256,uint256,uint256)","0ef96356":"stakeFor(address,uint256,bytes)","0efafc03":"SaleClockAuction(address,uint256)","0efafd01":"getPlayerGainLossOnLastFlip()","0efc9d03":"minEthToRaise()","0efcf295":"deleteAnyProposal(bytes32)","0efd0973":"club()","0efd2cca":"postICO()","0efd3d5b":"getPrice(string,string,uint256)","0efd4989":"numAdmins()","0efe5fb7":"addToCart(uint256,string)","0efe6a8b":"deposit(address,uint256,uint256)","0efe7f62":"objectShoes()","0f00dfdb":"NonOperationalWithdrawManager(address)","0f027c67":"membersLength()","0f0308fb":"upgradeGems()","0f03be37":"mimax(uint64,uint64)","0f03e4c3":"numberOfAccounts()","0f041cef":"KitFutureToken()","0f0433c4":"_getDroneAbility(uint256)","0f050dce":"getBitcoinAddress(bytes32,int256,bytes32,int256)","0f052173":"invest2017()","0f059913":"vested(address,uint256)","0f06670a":"didWin(bytes32)","0f092c44":"MIDGRADE_TYPE3()","0f096163":"Chainy()","0f0ba766":"removeChild(uint256,address,uint256)","0f0c27ad":"HashRegistered(bytes32,address,uint256,uint256)","0f0ed39e":"EthealPromoToken(address)","0f0f3f24":"addOwnerAddress(address)","0f106e0a":"encodePacketCommit(uint256,uint256)","0f120fc3":"toggleTrading()","0f122a6c":"_setSealableProperty(uint256,bytes32,bytes32)","0f12354d":"updateStateBasedOnContributions()","0f12b32a":"Garcut()","0f12d8f8":"RoundWinner(uint256,uint256,address,uint256)","0f12ffac":"weiToFNU(uint256)","0f134bee":"payPreviousOwner(address,uint256)","0f1354f3":"burnFrom(bytes32,uint256)","0f136527":"getShareIndex(address)","0f13af83":"setCurrentCoin(address)","0f13dbde":"inRankList(address)","0f14212b":"transferFromOwner(address,uint256,uint256)","0f145dca":"Ethbet(address,address)","0f149d0a":"changeBurnPaused(uint256)","0f14a7e4":"ModeratorRemoved(address,address,bool)","0f14b900":"setTimeStampStatus(uint256,uint256,string)","0f15573b":"setLLV_edit_2(string)","0f15f4c0":"activate()","0f166ad4":"local()","0f183119":"vote_for_candidate_D_for_Free()","0f188e1d":"studioLevel(address)","0f18a530":"chemistry()","0f18ac07":"transferFromOwner(address,uint256)","0f191524":"fillOrder(uint256,bytes)","0f19f92a":"isIcoOver()","0f1a6444":"cliffTime()","0f1bf454":"getGameStatus(uint256)","0f1df574":"WithdrawETH()","0f1e3b5b":"getHousePayout()","0f1e8c24":"commitTeam(address,uint256,uint256[])","0f1ed0c6":"setOwner(address,bytes32,address)","0f1fd654":"ELearningCoinERC()","0f2004a1":"Bob(address)","0f201ca6":"reportConvertTokens(uint256,address)","0f20b9df":"crowdsaleContracts(address)","0f215afb":"paySeller(uint256,uint256)","0f21a046":"WithdrawMonethaBuyerUtility()","0f226a31":"getServiceUpdateAddress(address,uint32)","0f228087":"transferTokens(address[],address)","0f2284cc":"SbuyToken(address,address)","0f22a95d":"deleteCountry(uint256)","0f23a104":"burnAssetOperator(uint256)","0f23b047":"getPlayNumber()","0f23cbaa":"recycle()","0f246780":"ZJF()","0f24f5c8":"doTransfer(address,uint256)","0f250780":"AKCToken()","0f2636bd":"getStockSellOrderPrices(uint256)","0f264e1a":"farmerRequestCertificate(address,uint256,string,string,string,uint256)","0f2905f7":"verifyStage()","0f29eb73":"revokeStaking(address)","0f2bc56d":"fixTokenCalcBug()","0f2c9329":"split(address,address)","0f2da195":"LimitSet(uint256,uint256,uint256,uint256,uint256)","0f2dabca":"punchIn(address,uint64)","0f2e5b6c":"Locked()","0f2f9bb7":"getNextWhitelistedNode(address)","0f2fa473":"test_already_paid()","0f3092fb":"EasyHomes()","0f30c971":"TheGambler()","0f3554ad":"addBoolListItem(bool,address,address,uint256,bool)","0f36f691":"getLockStatus(address)","0f37e79a":"transferClockmaker(address)","0f37fd4a":"HexelErc20Token(string,string)","0f391236":"ethRateMax()","0f39c6ab":"removeVotersVote(address)","0f3a00d5":"CreateCOR(address,uint256)","0f3a0533":"extraReceiverAmount(address)","0f3a1412":"getArrlist(uint256,uint256)","0f3a31d6":"SymbolChange(string)","0f3a9f65":"setPeriod(uint256)","0f3ae419":"PreferentialRateChange(address,uint256)","0f3afeec":"Nodelist()","0f3b305e":"getPawnPackageId(uint256)","0f3bd3fd":"teamJust()","0f3c92f3":"calculateFLCCore(address,uint256)","0f3cb8bc":"setCardUpgradeLevels(uint256,uint256,uint256)","0f3d7c3e":"release(string,uint32[3],string,string,string)","0f3d8803":"getMinPurchase()","0f3de489":"newAuction(uint256,uint64)","0f3e7027":"clearTransferValueby(address)","0f3e9438":"frontRunner()","0f3eb785":"add(string,uint256,uint256,uint256)","0f3f0e42":"allowTotalMintAmount()","0f3f53c1":"dappsBonusCalc(address,uint256)","0f3fb52a":"LogSetState(uint256,uint8,uint256,bytes32)","0f3fc29e":"setChestProduct(uint16,uint256,uint16,bool,uint32,uint24,uint24,uint8,uint8)","0f40593e":"ViewMyBet()","0f40988e":"contributorsShare()","0f40d645":"demander(uint256)","0f4170f2":"BaseICO(address,address,uint256,uint256,uint256,uint256)","0f41ba4b":"bid(address,uint256,uint256)","0f420113":"_calculateCurrentRate()","0f42fdfb":"recoveryModeTriggerTime()","0f4391f5":"setPauseMaster(address)","0f43a677":"validatorCount()","0f43c196":"setTournamentAddress(address,address)","0f45368c":"checkTransferHash(address,uint256,address,address,uint256,uint256,bytes)","0f45c3e1":"transferFromAny(address,address,uint256)","0f45f528":"getTknOfferor(uint256)","0f4665aa":"getOrderHash(address,uint256,address,uint256,address,uint256,uint256,address,address,uint256)","0f47165e":"managePlayer(address)","0f473d72":"_calculateDiscount(uint8,address)","0f47435b":"pvt_inv_Pool()","0f481bf7":"postTransfer(address,address,address,uint256)","0f482da1":"unblockSpending(address)","0f482e64":"LikeCoin(uint256,address,address)","0f4acfcd":"charToByte(bytes1)","0f4b1cfc":"setGovernment(address)","0f4bbdf2":"registerBuyer(string,string,string,string,address,string)","0f4cf692":"numMessages()","0f4d14e9":"depositEth(uint256)","0f4df754":"Gladiethers()","0f4dfc17":"ICOTokenDelivery(address,uint256)","0f4ef8a6":"rewardManager()","0f4f8184":"bancorRegistry()","0f4fd9cc":"log_event(string)","0f4ff474":"_openGameResult(uint256,uint256,uint256,string)","0f501d07":"saveInfoAboutInvestors(address,address,uint256,uint256,bool)","0f505a01":"sealDataStream(address,uint256,bytes32,uint256,bytes32)","0f5137f9":"sellOrderBalances(bytes32)","0f522614":"Shufflix()","0f527200":"SimpleCoin()","0f529ba2":"D()","0f52fb0a":"searchFreelancers(address,uint256,uint256[],uint256[],uint8,uint256,uint256[],uint256[],uint256[],uint256)","0f5381f1":"testUserCanIncreaseVersionNumber()","0f53a470":"getProfile(address)","0f53b7ee":"communityTokensAddress()","0f53ba51":"appWasMade(string)","0f53e2a8":"NewToken(address)","0f555b46":"MicroCoins()","0f560cd7":"list()","0f56e460":"Shitcoin()","0f574ba7":"subscribe(uint256)","0f577d97":"getCompte_16()","0f57b9d9":"removeFromPrivileged(address)","0f57eb79":"minboc()","0f581aed":"MinimumBitcoinInvestmentUpdated(uint256,uint256)","0f58d28f":"weightOf(string)","0f590c36":"emergencyFixGameResult(uint64,uint256)","0f59a638":"totalWeiCommitted()","0f59eb95":"ownerUpdateOthers(uint256,bool,uint256,uint256,bool)","0f59f83a":"go()","0f5a5466":"claimWithResolver(address,address)","0f5a8d9c":"raiseDollarsFunded(address,uint160,int160)","0f5aa9f3":"setAuthorization(address,address)","0f5ad969":"node_index(address)","0f5b807d":"cuddleData()","0f5bab7c":"countManagers()","0f5c8c0a":"balancesDB()","0f5e7348":"getCommunityBallotCentsPrice()","0f5ea100":"price(address,uint256,uint8)","0f5eacf6":"EndStage()","0f5ed9e9":"escrowAllowed(address)","0f5ee138":"userSignupCount()","0f5f0151":"GxTradersProxy(address)","0f5f1dbc":"operationsAccount()","0f5f4c53":"unpause2()","0f5f8593":"MetaBall(uint256,string,string)","0f601679":"balanceOwner(address)","0f60e3d9":"resetAddTokenData()","0f610c06":"getValidatedLiability()","0f61280e":"nutzAddr()","0f62562f":"pregnantNinjas()","0f632fd3":"onMint(address,uint256)","0f63d864":"addOwners(address[],uint256[],uint256[])","0f6413b7":"batchAssignStopped()","0f64864d":"transferTokensAndDividends(address,address)","0f6521e2":"FROZEN_TOKENS()","0f66791c":"setHTML(string)","0f66acd1":"EcosystemEthereum()","0f670da6":"destroyLogicContract()","0f6798a5":"Mint(address,uint256)","0f67f3f7":"distributeToDev(address,uint256)","0f683fd1":"Token(string,string,address)","0f69cdbe":"approvespender(address,uint256)","0f6a1734":"Crowdsale(address,uint256)","0f6b6756":"tokenSaleIsPaused()","0f6bb3c3":"doSpawn(uint32,int256,address,bool,address)","0f6c2a33":"setMaxStage2AllocationPerInvestor(uint256)","0f6d37d6":"supportAddress()","0f6d6236":"setIssueDividendReward(uint256)","0f6d9f00":"ERA_PERIOD()","0f6e40c3":"startRound(bytes32,bytes32)","0f6ea4fc":"MISCELLANEOUS_TOKENS_SUPPLY()","0f6f5f98":"setAndFixTokenPriceInWei(uint256)","0f6f72a8":"getClosingTimeValue()","0f710616":"TRSToken()","0f710e32":"CryptoFinexToken()","0f71590c":"setPOLYUSD(uint256)","0f732bdc":"getEncryptionAlgorithmCount()","0f73b4f4":"setStartingPrice(uint256)","0f73d212":"addLog(string,string,bytes32)","0f74a5cc":"cancelCenturionSale(uint256)","0f74e527":"RenmiCoin()","0f74e689":"registerNewPubKeyForHash(bytes28,string)","0f7503c9":"baseStartTime()","0f75806f":"GraphenePowerCrowdsale()","0f75c82e":"getObjClassExp(uint64)","0f75e81f":"issue(bytes32)","0f762cfe":"emission(address,address,uint256,uint256,uint256)","0f76496a":"returnTokens3(address,uint256,uint256)","0f76b651":"unlockDate5()","0f76c114":"getCurrentValue()","0f76de0d":"left45(uint256)","0f76f489":"getPoolName(uint256)","0f774287":"Burnt(address,uint256,uint256)","0f774931":"administrativePayouts(address,uint256)","0f776fb2":"PutDiv(address)","0f77c1d3":"addUsersWhitelistB(address[])","0f784943":"mintable(uint256)","0f78628e":"allowedToBurn()","0f7875c6":"startblock()","0f78d408":"JuvToken()","0f78ee7c":"payoutLockedToken()","0f79cfa2":"addReferrer(bytes32)","0f79e120":"nrFailures()","0f79e1c7":"createRandomDeveloper(string,uint256)","0f7a4590":"goalAchieved()","0f7a8971":"buildBoolMapping()","0f7bd1dd":"enterRaffle(uint256[],uint256)","0f7bff76":"getHeroDBZHeroAddress(uint256)","0f7c9085":"addToAdmin(address,bool)","0f7c932a":"getReservedTokensListValInPercentageDecimals(address)","0f7d6673":"Channel()","0f7e1653":"OpenGame()","0f7f97c8":"calcNewSkinAppearance(uint128,uint128,uint128)","0f7fa72f":"addOperator(address,uint256)","0f809adb":"changeTokenOwner(address)","0f80fc58":"exponent(uint256)","0f8143f6":"discardRejectedProposal()","0f819fe8":"disableTuneOption(uint256)","0f81d248":"endPeriodC()","0f822b78":"admin_transfer(address,uint256)","0f825673":"deleteCoupon(string)","0f82b42f":"userAccountTokenBalances(address)","0f832bc6":"testIsLawyer()","0f83f112":"CanTransferChecked(bool,address,bool,bool)","0f8410e3":"getPresellToKenAmount()","0f85751e":"change_p5(uint256)","0f861127":"argl(uint256,uint256)","0f861ca3":"ownerUnpause()","0f86abc1":"modifyStakerLimit(uint256)","0f86e3eb":"denaToken()","0f86f702":"compatible223()","0f87a044":"withdraw1(uint256)","0f88aa81":"emitRecord(bytes32,uint256,uint256,uint256)","0f88f1a5":"collectBounty(address,uint256,uint256)","0f89fa28":"OrganizationRegister()","0f8a771e":"skr()","0f8a8887":"rocketSetResourcePrice(uint256,uint256,uint256)","0f8b70c9":"getBotContract()","0f8bca8c":"getStage0Start()","0f8c04e2":"create(address[],uint256[],uint256[],address,address,bytes)","0f8d4030":"totalShareholders()","0f8d598a":"decayedPriceOfSocialIdentity(uint256,uint256)","0f8dc272":"ComputeAcornPrice()","0f8ea4f3":"addSomeOfManyLine(uint256,string,uint256,string)","0f8eaa74":"addToPreSaleRefunds(address,uint256)","0f8ef9f8":"getBoosterRaiseValue(uint256)","0f8f8b83":"spendableBalanceOf(address)","0f8fcb74":"_setInt(bytes32,int256)","0f8fd363":"getRepPriceInAttoEth()","0f900587":"addBonusPerShare()","0f902bc2":"delayedTransferFrom(address,address,uint256)","0f907ba3":"failCar(string)","0f90b83a":"deployTokenContract(uint256)","0f917e31":"transferAndDonateTo(address,uint256,address)","0f917f9e":"totalSupplyTeamTokens()","0f91c8a5":"setCap(string,uint256)","0f91cce1":"releaseVanbexTeamTokens()","0f92f38f":"changeMartial(uint256)","0f9302c8":"LogEvent(string)","0f95378f":"MerchantWallet(address,string)","0f953b97":"getCmcAddress()","0f960644":"addClaim(address,bytes32,string,string,uint256)","0f96dd39":"maxTokenCap()","0f973874":"MiniMeTokenSimple(address,address,uint256,string,uint8,string,bool)","0f974ef2":"PasserBy(address)","0f977561":"getUserEvents()","0f97f2f1":"managePlayer(uint256,uint256)","0f98a9cc":"lockTokens(address,uint256,address,uint256)","0f98c91a":"TOKENS_PER_ETHER_EARLYSALE()","0f99da4a":"getBoosterAmount(uint256)","0f99fab2":"allowWrite(uint256,uint256)","0f9aea56":"last_release_date()","0f9b481a":"TokenFinalized()","0f9b5129":"maxSellRateInPrecision()","0f9b87be":"transferToDestination(bytes32)","0f9bac2d":"ADVISORS_ADDRESS()","0f9bb8b3":"getCurrentUserQuickPromoBonus()","0f9c95da":"GDCAcc04()","0f9ce471":"Ether2Gen()","0f9e144d":"changeMaxMin(uint256,uint256)","0f9e39bf":"minBidMultiplier()","0f9e42da":"drawToken()","0f9e5bbd":"createShares(address,uint256)","0f9fb983":"lastBetTimeSEC()","0fa01949":"yearOfProduction()","0fa2b5d4":"Interestv3(address,address)","0fa2d864":"block4()","0fa48688":"calculateItemId(bytes32)","0fa53db8":"divideDecimalRound(uint256,uint256)","0fa6002e":"sellCharacter(uint32)","0fa6e84d":"SouYingToken()","0fa7a798":"getOpenRequestPublicKey(uint256,uint256)","0fa7b7b3":"totalRefunded(uint256)","0fa803e8":"SetCategoryName(string)","0fa85ab0":"claimTokensForUser(address)","0fa87b15":"closeMyGame(uint256)","0fa8beb3":"claimBonus(address,uint256)","0fa8f516":"getPosition(address,bytes32)","0fa95aee":"etherToTokens(uint256,uint256)","0fa9ced4":"emergencyFuneral()","0fa9e486":"registerCoin(string,string,address)","0faa2aae":"amountOfBSTRequired(address)","0faaa357":"nCanOpenRewardMinEth()","0fab0f6a":"minimumWitcoins()","0fab14e8":"agencyOwner()","0fab459c":"transferSoldTokens(address,uint256)","0fab7539":"getIssuanceCount(bool,bool,bool,bool)","0fac20e1":"dev1Wallet2Pct()","0fac8dc5":"update(string,string,bool,string,address,uint256,uint256)","0fac960e":"sellTokensForWaves(string,address,uint256,uint256)","0fadb5c7":"getWHaddress()","0fae42cd":"pricePreSale()","0faf2775":"newGame(string,string,uint256,uint256,uint256,uint256,uint256,uint256)","0fb0a8d3":"manageOperable(address,bool)","0fb0cf2d":"changeLockupDuration(uint64)","0fb125ac":"transferTokens(uint256,address[])","0fb26f0b":"switchTransfers()","0fb2e692":"buyMCTTokenProxy(address,uint256,uint256)","0fb35574":"SCC()","0fb3844c":"_status()","0fb411e8":"evc()","0fb4b070":"tokensMintedForSale()","0fb4ecdf":"complained(address,address)","0fb524ce":"castVote()","0fb54f3a":"AuthenticationManager()","0fb553ba":"FLC()","0fb59f95":"buy(uint256,string,uint256,uint16)","0fb5a6b4":"duration()","0fb65f10":"authorizeMintRequester(address)","0fb66557":"trustedTransfer(address,address,uint256)","0fb66da3":"getMessageOfVisit(address)","0fb7657f":"isAllocationLocked(address)","0fb792d0":"ONE_HUNDRED_PERCRENTS()","0fb7a5e6":"getCensuredBy(uint16)","0fb7cb1d":"addToKycTeam(address)","0fb7e602":"startEmergency()","0fb9398f":"getProductBuyers(uint256)","0fb9d85e":"buyIndex(uint256,address,bool)","0fb9dcd5":"getTokensAtCurrentRate(uint256)","0fba34a4":"has(bytes12)","0fba4ca1":"accept(string)","0fba80de":"pickValues(bytes32)","0fbad611":"setTimeFrame(uint256)","0fbb3b6b":"shittyRandom()","0fbbeceb":"PostCompleted(address,address)","0fbc0cd1":"bounty_solve(address,bytes32)","0fbc0f82":"LotterySymbol()","0fbe333a":"getLastBidder()","0fbe3e40":"returnLast()","0fbed9fe":"EFAFCOIN()","0fbf7151":"startsWith()","0fc03687":"Booko()","0fc0e9a8":"_addWithdrawal(address,address,uint256)","0fc10026":"CALLER_EXCHANGE_RATE()","0fc12b1a":"isGetWhiteList()","0fc1b08b":"setValue(string,string,string)","0fc1c83d":"minimumTokenCommission()","0fc24c03":"ZarFundsToken()","0fc33bb7":"lrcBalance()","0fc3866f":"isSoftCapGoalReached()","0fc38daa":"CSToken()","0fc4af53":"cloneTokens(uint256,uint256)","0fc4f262":"updateSubdivsFor(address)","0fc55d1e":"ENTS()","0fc55fd1":"bid(uint256,string)","0fc63d10":"tokenA()","0fc66f45":"PO24()","0fc69407":"BidPlaced(uint256,uint256)","0fc6ed30":"Satum()","0fc709e5":"setDistribution(uint256,uint256,uint256,uint256)","0fc72f4e":"purchaseCallback(string)","0fc783d1":"SacToken(address)","0fc7c15e":"getUnapprovedUsersTop150()","0fc81bdc":"editEventResult(string,uint64,uint8)","0fc85c7f":"INAYCOIN()","0fc8a393":"transferUpdater(address)","0fc8afbd":"getFreeSnake()","0fc958dd":"tMemberSolId(uint256,address)","0fcac452":"addToRakePool()","0fcaed94":"restartLottery()","0fcb5984":"getprice()","0fcb83f2":"SancojTokenContract()","0fcbb5b9":"getSubscriberType()","0fcbbc8e":"_lookupOwnerIdentityCount(address)","0fcc0c28":"deprecate()","0fccf22e":"ban_user(address)","0fcd1cab":"killInstance(address,address)","0fcda174":"getAccountTokenBalance(address,address)","0fcddd06":"CreateCRC(address,uint256)","0fce00ed":"calculatedPaymentInterval()","0fce349e":"popularitySetting(uint256,uint8)","0fce887b":"transferLockedFrom(address,address,uint256[],uint256[])","0fd02fc1":"isValidUnbondingLock(address,uint256)","0fd0aa67":"Parties()","0fd0ae10":"insert(address,uint256)","0fd0e440":"uniq(uint8[])","0fd1ed1f":"setMarginForVictoryPercent(uint8)","0fd1ed78":"LOG_EmergencyWithdrawalFailed(address)","0fd1f94e":"firstClaimBlock()","0fd2ce17":"funcArrayInArguments(address[])","0fd3d758":"WWAMPricingStrategy(uint256,uint256,uint256)","0fd3ee83":"__redeemTokens(address,uint256)","0fd4d286":"BlueSkyDragon()","0fd5084a":"validOrigins(uint256)","0fd548ef":"myShareToken()","0fd56202":"addressToNumCities(address)","0fd57f3e":"seatPrice()","0fd58d07":"expectedWinnersCount()","0fd62f57":"adminCharge_p2()","0fd68e3f":"newRaffle()","0fd6fc49":"IntelliShareEco()","0fd7410c":"in_finalization_phase()","0fd7b03d":"HackDivs()","0fd8a8fb":"setAnonymousCap(uint256)","0fd9d5bf":"Matrexcoin(uint256,string,uint8,string)","0fda890e":"changeGenRNGcontractAddress(address)","0fdb1c10":"withDraw()","0fdb468f":"fee(uint64)","0fdc3609":"changeDeposit(address)","0fdc7956":"unlockAllTokens(bool)","0fde0f8e":"ROLE_VENDOR()","0fde5686":"setBUB(bytes32,uint256,bytes)","0fdfa5ee":"preBuy3()","0fe1dfa8":"lastRoundLengthUpdateRound()","0fe1f548":"getTokenSCADARequiresHardCap()","0fe234ed":"testSetController()","0fe2abcf":"exchange(uint256,address)","0fe2c5d1":"BTSMToken()","0fe3152e":"airdropEnd()","0fe3c10d":"MANHATTANPROXY4THST()","0fe41fd5":"acquisitionsTokens()","0fe433db":"reallocate(uint256)","0fe43e1f":"foundersAdvisorsPartnersTokensVault()","0fe4ea72":"killDragonDeathContract(address,uint256,uint256)","0fe793aa":"studioHandler(address,uint256)","0fe7c250":"DaoRulesProposals()","0fe7db9c":"MedSupplyToken()","0fe83bb8":"preSaleTokens()","0fe8c788":"addCertificate(string,address)","0fe961da":"_getCurrentRoundTeamCos()","0fea657f":"totalExch()","0fea81fe":"setComisionInETH()","0fea9be6":"ChinhCoin(uint256,string,uint8,string)","0feacc42":"CommonToken(address,address)","0feb10ff":"Register(uint256,string,string)","0feb172f":"buyTeam(uint256)","0feb376b":"AMOUNT_ICO()","0febb8b7":"setSaleInfo(uint8,uint256,uint256,uint256,uint256)","0feca6d5":"releaseAdvisorsTokensForPercentage(uint256)","0fecef48":"getProductsByOwner(address)","0fed240b":"dAdd(bytes32,address,bool)","0fed5dc8":"setSendAllow(bool)","0fee32bb":"setAuctionIndex(address,address)","0fee5a40":"getProviderCurve(address,bytes32,int256)","0ff0a4df":"reFund()","0ff188c7":"transferPixel(uint16,uint16,address)","0ff244b2":"transferByAddress(address,uint256,address)","0ff2e4b2":"assignCEO(address)","0ff3687b":"remainingGenesisCats()","0ff39daa":"generateDepositAddress()","0ff3d57e":"addMasterWallet(address)","0ff3d5ea":"getCastleSale(uint256)","0ff4009c":"getLotteryInfo(address)","0ff42eab":"setProofAddr(string)","0ff43cfd":"IFCNBToken()","0ff4c916":"getValue(uint256)","0ff4d239":"HashRushICO()","0ff4f160":"oraclize_query(uint256,string,string[1])","0ff58f40":"month24Allocated()","0ff7bb07":"refundClient(address,uint32)","0ff88a8d":"getChar(uint256)","0ff88baa":"RoyalTransfer()","0ff89c2b":"divide(int256,int256,uint256)","0ff8cf9b":"dividend()","0ff92e7b":"burnDead(address,uint256)","0ff9aafe":"updateMinimumBond(uint256)","0ffb1d8b":"whitelistToken(address,bool)","0ffbe43b":"initializeOfferChannel(uint128,address,address,uint256)","0ffdbd42":"feePoolShare(uint256,bool)","0fff6e06":"totalAvailableGames()","0fffbb54":"changeRankingSize(uint256)","10001fdd":"setPublicSaleParams(uint256,uint256,uint256,bool)","10002f39":"WorthlessEthereumTokens()","100153b6":"blocksByDay()","1001c39c":"tokensReleasedToIco()","100278d8":"startPreSale2()","100349fa":"Good_Bye_World()","10038099":"isPuppySports()","1003ac0c":"customFallback(address,uint256,bytes)","1003e2d2":"add(uint256)","10042e10":"remainingPublicSupply()","100565f4":"setTurnover(uint256)","10059be0":"do_redemption()","1006a41f":"auctionStarts(address,address)","10072af7":"SetupRaffle(string,uint256)","1007f753":"erase(uint256)","10082bff":"getActorBillXdetail(address,uint256,bool)","1008737d":"test_oneValidEqBytes32()","1008a2a5":"getTotalLendingItem(address)","10096c84":"exchangeBalanceOf(address,address)","10098ad5":"available(address)","100a0ed1":"receiveCreateAuction(address,address,uint256,uint256,uint256)","100a1099":"getTransactionIdsOf(address,address)","100a5ec5":"mintedCrowdsale()","100ac510":"addRx(address,address,uint256,uint256,bool)","100aca47":"totalFund()","100acefc":"_storeProof(string)","100af203":"reserveETH()","100b815d":"loadData()","100bce92":"toHex(string)","100be094":"setRefundRate(uint256)","100c6cfd":"ipoPlatformPercentage()","100c8ada":"setCAmodulus(bytes)","100c98fe":"SaleFailed()","100cdd91":"burnAll(uint256[])","100d7e30":"FuckFacebookCoin()","100e187a":"transferHolds(address,address,uint256)","100e4b94":"every_day_im_shufflin()","100ed0fc":"preallocateFirstStage(address,uint256,uint256)","100f23fd":"cancelWhitelistAddition(bytes32)","100f2e78":"determineSalaryTokens(address)","100f759f":"EDU_PER_ETH_SALE()","100f7a79":"registerBounty(address,uint256)","100fd02f":"isAbove(int256,int256,string)","101005bd":"releaseReserve(uint256)","10103122":"totalDurationInDays()","101175e8":"BONUS_DATES(uint256)","10119521":"TokenBurnt(address,uint256)","1011a635":"changeCommissionFeeRate(uint256)","1013ad53":"KairosToken()","10142785":"assign(bytes,uint256,bytes1)","1014a29e":"firstRefundRoundRateDenominator()","1015295c":"ClaimMyBet()","1016774e":"period3End()","1016ad94":"Baliv()","1016eadb":"Epilepsy()","10174967":"God()","1017a357":"HeirOwnershipClaimed(address,address)","101817ba":"getLastEmissionNum()","1018f294":"getRandom16(uint16,uint16)","1019635d":"assignReserved(address,uint8,uint256)","10196bf7":"pendingRefs(uint256)","1019dc59":"setSale(address,bool)","101a3fec":"setIsTokenTransactionOpen(bool)","101a889b":"LogBeneficiaryPaid(address)","101a917e":"makeTradeDetail(address,address,uint256,uint256,address,uint256)","101af16b":"countriesTokens()","101b6106":"RevokeEntity(bytes32,bytes)","101b7e7c":"vbtToken()","101b94f1":"setRightOfGroup(string,string,bool)","101ca1b9":"YoobaBatchTransfer()","101d52d2":"checkStoredFileName(string)","101d990c":"hmul(uint128,uint128)","101e1f2c":"initLottery(uint256,uint256,uint256,uint256,int256)","101e359b":"reviveFee()","101e5a32":"setSoftcap(uint256)","101e652e":"presaleUnlimitedStartTime()","101e8952":"forward(address)","101f13e2":"verifyProof(bytes,bytes32,bytes32)","102046db":"townPrice()","1021688f":"changeAdminAddress(address)","1022b30b":"proposalResult(uint256)","1023d597":"priceDecraseTime2Action()","102455a5":"sanity_check()","10253fec":"election(string,string,string,string)","10258bfd":"Payment(address,address,uint256,uint256)","10271334":"receiveICOcoins(uint256,uint256)","1027853f":"withdrawShare(address)","10278bc8":"setBytes32Value(string,bytes32)","1027e242":"getBoosterStrength(uint256)","10282b61":"payoutcount()","10286952":"parseKeys(bytes32[])","10288c4b":"startIco(uint256,uint256,uint256)","1028e4a8":"theCyberMemberUtilities()","10290e51":"computeProfit(uint256,uint256,uint256)","102accc1":"fireEventLog2()","102b61f7":"setMinimumWeiAmount(uint256)","102c920a":"allRefunded()","102ce658":"setRule(address,string)","102deb9c":"changeMonethaVault(address)","102e58d0":"timeoutAt()","102e8b94":"sellnow()","102ff0b3":"amountToken()","10309781":"createdTimestamp()","1030adea":"change_king_name(string)","1030c539":"setCreditbit(address)","1030e227":"TroyToken(address,address)","1030f288":"releaseState2()","10314b07":"GOX(uint256,string,string)","10316eec":"getActionParametersCountByIndex(uint256)","10319417":"returnHost(uint256)","1031e34e":"raisedFromToken()","1031e36e":"pauseTrading()","10328e89":"CoinhiToken()","103359ce":"sendToIco()","10340069":"tokenDistributionPool()","10342d02":"endSaleCarProduct(uint32)","10347a2c":"lockSymbol()","10348938":"setRankDynamic(uint256)","10361bf2":"transferLog(address,address)","10369540":"icoPhaseAmount2()","1036bbe2":"MAX_PERCENT()","1036cde8":"allocateCustomer(address,uint256)","103728a3":"FundingFueled(uint256,uint256)","10375a67":"getRemainingTokens(address)","1037706d":"uploadSignedString(string,int256,bytes20,int256,string)","1037a5f4":"getPrev(uint256)","10388809":"setTransferPrice(uint256)","1039cf3c":"isIcoStopped()","103aeda7":"isContractAuthorized(address)","103b0506":"preter(uint256)","103b5dad":"computeIndexId(address,bytes32)","103bf0bd":"tSLDToken(address,address,address,address)","103cbb7f":"ethpyramid()","103cfacf":"CryptovationX(address)","103d26ac":"getRareItemsPrice(uint256)","103e8154":"sellComissionUnits()","103ed140":"_getSkill(uint16)","103ef9e1":"authorizeOperatorByPartition(bytes32,address)","103f3a83":"getAuraColor(uint64)","103f9251":"transferFrom(address,address)","10400446":"setMaxAppeals(uint256)","10402040":"createSaiCollectorsEdition(uint256,address)","1040233f":"LevelUp(address,uint256,uint32)","1040762d":"setExchangeRates(uint256)","1040dc27":"getSTODetails()","1040e5a5":"showBal()","10422c24":"releaseAngelVested()","1042604f":"isTrue(bool,string)","1042876d":"getDisplayName(address)","1042ca73":"getWeekIdx()","1043dcdf":"LastIsMe(uint256,uint256)","10442a1b":"GetMainAddress()","10443ab3":"setLotteryTokensWallet(address)","10445a16":"_joinGame(address,uint256)","1044bbe6":"unLockTokens()","1045290e":"Boocoin()","10458684":"GBCCoin()","1045a889":"buildContract(string,string)","1045de72":"isEndOffer()","1046bc68":"deleteContact(address)","1046d078":"transferItemFrom(uint256,address,uint256,uint256)","1046e2ab":"Flood_Standard_Ethereum_Coin(uint256,string,string,uint256)","1047456e":"userTransfer(address,address,uint256)","1047d79e":"freezTime()","10482f57":"getWhitelistedResolvers()","1048a25c":"view_random(address,address)","1049334f":"tokenBalance(address,address)","1049f742":"terminateEscrow(address)","104a5963":"targetDiscountValue9()","104a5e75":"getRareItemsPLATPrice(uint256)","104ace02":"register(string,string,string,string,string,string)","104b6704":"currentManager()","104b78bd":"amountRaised(bytes32)","104bb708":"GetStatusCount(string)","104bc708":"LamboCrowdsale(uint256,uint256,address,address,address[])","104bf512":"createBATokenContract(address,address,uint256,uint256)","104bff92":"HasBooster(address,uint256)","104c9cff":"releaseDividendsRights(uint256)","104ce199":"Launcher()","104d5fdd":"getPriceProxy()","104d7bbb":"LuzCoin()","104de5a1":"setPromoted(bool)","104e81ff":"_approve(address,address,uint256)","104e9929":"tokenPool()","104f2d8f":"_approve(uint256,uint256,bytes32,uint256)","104fea4c":"activeCrowdsalePhase2(uint256)","10510ec1":"payToken(address,uint256)","10518aeb":"removeOldFirst(address)","10519ff4":"WestCoin()","1051db34":"implementsERC721()","10523af3":"getPokemonCD(uint256)","1052506f":"isSignedBy(bytes32,string,address)","10525660":"setConsumeToken(address)","10549874":"tokenRate1()","1054d657":"divestETH()","105541ae":"returnPtSafeSmall()","105689a0":"doLockdown()","10570116":"newGroup(string,uint32,uint256,uint32,uint32,uint32,uint32,uint32,uint8)","1057ce8c":"create3DoggiesTokens()","10594e19":"JPGProject()","1059c492":"CROWDSALE_WALLET()","105a6356":"minimalSuccessUSD()","105ae3bf":"getRoundIsEnded(uint32)","105b2645":"CheToken()","105b6f00":"Fructus()","105c287b":"lockPeriod1()","105d3e0f":"cryptogs()","105d9e37":"disputeLength()","105e029f":"JSONpath_string(string,string,string)","105e68f0":"allBankers()","105ea540":"minimumToRaise()","105edd83":"toTheTop()","105ee9a7":"endFight(uint256,uint256,bool)","105fc4e8":"REQUEST_FOUNDATION_AMOUNT()","105ff033":"redeemReward(address,uint256)","10609902":"sendFundsToBorrower()","1060c965":"ZILLION()","106109c9":"RandiveBhToken()","10618776":"setETHUSDdemon(address)","10619300":"lockAccount(bytes32)","106233e8":"addAltOracle(address)","106259c8":"getNonEtherController()","10639ea0":"cancelMigration()","106524a5":"multisendEth(address[],uint256[])","106639ba":"getOwnAssets()","1066cd3c":"voteFor(uint16,address,bytes32,bytes)","1067f077":"setCompte_41(string)","1067f361":"totalTokenToSale()","10680b84":"getShareTokenAddress()","106812c9":"setPI_edit_18(string)","106858cb":"getRemainingPreSalesAmount()","1068d056":"getaddress0()","106a182b":"getLambosCount()","106b291f":"ethUsdRateInCent()","106bd2da":"initiateEscrow(uint64,uint256,address,address,address,address)","106be310":"getNameByNumber(uint256)","106c0a45":"collectOriginalBetERC20(address)","106c5511":"create(address,string,string,uint8,uint256)","106c6441":"removeReinforcedWhitelist(address[])","106d2813":"setCreditGameAddress(address)","106e6290":"withdraw(address,uint256,bytes32)","106f6a3d":"TOKEN_FIRST_EXCHANGE_RATE()","106f6f33":"bountyTokensCount()","106f77a7":"multiMint(uint256,uint256[],uint256)","106f923f":"RewardClaimed(address,uint256)","106fcb7a":"changeAsset(bytes32,string,string,uint8)","106fd2d5":"setSaleAddress(address,address)","106ffbd3":"withdrawBatchTokenToInvestor()","107046bd":"projects(uint256)","1070eb4f":"calculateInterestDue()","1070f410":"convertToBytes(uint8[],bytes1)","10711911":"BONUS_TIER_5_LIMIT()","107169c5":"allLinesWrong()","10717a2e":"switchCompatible223(bool)","10718655":"contributeFor(address)","1072cbea":"transferToken(address,uint256)","10731a65":"claimTokenOwnership()","10735089":"readteamXaddr(address)","1073c4a9":"exploreBuilding(uint8,uint8[176])","1073d1f8":"releaseTprFund()","10745f7e":"getMinAmountToWager(uint256)","1074c619":"flushEthers()","1075153f":"multiPartySend(address[],uint256[])","1075f186":"fundingPoCEndTime()","10764268":"salvageOtherTokensFromContract(address,address,address,uint256)","10768bdd":"myUsingOracalize()","10769e01":"POOL_EDIT_2()","1076c2d7":"StreamXOnline()","1077135a":"oraclizeSetWinner(uint256)","1077666e":"unmined()","1077f06c":"makeClaim(uint256)","10780cce":"grantsStartTimestamp()","107853a9":"Spacoin()","10787d58":"checkfriend(address)","1078ad80":"makeContractPermanent(string)","107925bb":"viewCustomer(string)","10793b50":"m_contributionHistory()","10796a47":"staticCall(address,bytes,bytes)","10797bab":"runtoeth(uint256)","1079b859":"finalRewardPeriodPercent()","1079ed67":"getChildByAddress(address)","107a2c5e":"betEvents(uint256)","107a69e8":"WithdrawResult(uint256,bytes32,uint256)","107a77d0":"finalizeVestingAllocation(uint256)","107a83e2":"prizesAwarded()","107b1f8c":"debug_verifyShare(bytes,uint256[],uint256[],bytes,uint256,uint256)","107bf304":"withdrawEthToOwner(uint256)","107d1d55":"startPeriod(uint256,uint256)","107d4b23":"Bitcan()","107d8a90":"COBA()","107e1a29":"setEndTimeIco(uint256)","107e7b1f":"setBroker(address,uint256)","107e8b24":"setTimeSale(uint256,uint256)","107f3f6a":"setExeStatus(uint64,uint64)","107f587c":"deactivateEmergencyProtectedMode()","107f76c5":"cancelOrder(bytes32,uint64)","10802749":"maxPlayerNum()","1080b7b1":"token4DivsOwing(address)","1080f251":"ownerOfLand(int256,int256)","10814c37":"bot()","10816757":"crowdsaleClosingTime()","1081dc8a":"contractIndex(uint256)","10828bcc":"noOpenGameResult()","1082a128":"SaveRickAndMorty()","1082cda1":"Register(bytes32,address)","1082d51e":"COINESIA()","1083d2fe":"technicalAmount()","1083f761":"assetToken()","108456b4":"FIRST_AUCTIONS_MINIMUM_RAISE()","10848ddf":"getDaysInMonth(uint256)","1084a1fb":"transferToAccount(bytes32,uint256)","1084bc90":"farmSingle(address,address,uint256)","1084cc51":"canDoubleDown()","10855269":"setProxyStorage(address)","10861f40":"wasDelegate(address,address,uint256)","108623f2":"checkProofOfWork(uint256,uint256,uint256)","10867877":"eatUnicornWithoutCorn()","1086a9aa":"approve(address,uint64)","1087452c":"signatureOwner()","10875ac0":"getMembershipExpiryDate(address)","10878ea1":"REGISTRY_INTERFACE_REQUIREMENT()","10888f2f":"admin_exFeeRate(uint256)","1088996b":"_newOutgoingTransaction(address,address,uint256,string)","1088f03f":"crowdsaleCompleted()","10895087":"DDJXRP()","1089843c":"OAKTokenCrowdsale(uint256,uint256,uint256,address)","10898a3e":"currentStateStartTime()","1089b16e":"setPod(address,uint8)","108a101b":"hasEmptyEditionSlots(uint256)","108a936b":"_initGame(uint256,bytes32,bytes32,bytes32,uint256)","108afb9f":"getBonusAmount(address,uint256,uint256,uint32)","108b77ad":"tokenPresaleSold()","108c3708":"paoContactAddress()","108c8ae4":"completeTask(uint256,uint256)","108caf79":"whitelistTokens()","108d0c84":"enableDefinedGame(uint256,bool,bool)","108d40f8":"PutGift(address)","108d6f94":"ProjectOwner()","108d995b":"getContinuityNumber(uint32)","108e161b":"isBallotSealed(uint32)","108e4bdb":"isKycTeam(address)","108eaa4e":"resolver(uint256)","108f69f8":"verifyTetherLoss(address,uint256,uint256)","108fa161":"newEnglandBets()","108fe10c":"advisers(uint256)","109050bc":"jackpotLastQualified()","1090a638":"presaleGoalReached()","10922cc1":"testTransferCost()","1092735d":"Created(address,uint256,uint8,uint256,string)","10937b5a":"adminAddMoney()","1094252e":"reconciliationDate()","109447e1":"createHash(uint8[5],bytes32)","10947164":"changeCEO(address)","1094d009":"LowGasAmount()","10950708":"setInvoicePaid(address,address,uint256,uint256)","109538ca":"transferAdeptTokenOwnership(address)","10953c22":"ChangeChallengeAdditionFee(uint256)","1095b6d7":"withdrawFee(address,address,uint256)","1095f211":"PushInvestorList(address)","10961935":"Bionic()","10970fbb":"convertTransferredTokensToMny(uint256,address,address,uint256)","10971bee":"bonusDayPercent()","10972704":"getCurrentAward()","10978594":"depositSoul(uint256)","1097b9ee":"sellingPrice(bool)","1097c929":"episodePurchase(address,uint256)","1097d54a":"addMaster(address)","1097e579":"Enter()","1099107b":"apSaleIssue(address,uint256)","1099d3ec":"scheduleTransaction(uint256,uint256,uint256,bytes)","1099f6fa":"disablePOSReward(address,bool)","109a9dbc":"bulletAddress(address)","109ac462":"safebalance(uint256)","109b678a":"immortals(address,uint256)","109c2032":"LotteryToken()","109d42d3":"addTokenSale(uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","109df68e":"rotateBitsRight(bytes,uint256)","109e591a":"SchmecklelToken()","109e8b21":"addOldMayors(uint256[],uint256[],address[])","109e94cf":"client()","109e9de6":"getMaxBuy(uint256)","109ef276":"newDutchPriceRate(uint256,uint256)","10a03b22":"PHASE1_SUPPLY()","10a0d2f1":"startOfCrowdsale()","10a101df":"getKeyData(bytes32,bytes32)","10a20b4c":"testMintGuy()","10a2f7cb":"createOption(uint256,string)","10a31091":"createRadar(uint256)","10a37c26":"getWinnerAddress()","10a3ec4f":"test_fiveAssertTrue()","10a4fd08":"Platinum()","10a5bbdb":"changeCharPrice(uint256,uint256)","10a64976":"ARLCToken(uint256,string,string)","10a6fdc2":"updateEtherPrice(uint256,uint256)","10a73f5e":"jackpotrate()","10a78f4a":"playerTwoReveal(bytes32,bytes32)","10a7a5f5":"secondStageWallet()","10a80397":"addBudget(uint256,uint256,uint256)","10a82579":"lockTokensAddress()","10a86088":"getIntField3()","10a942b4":"withdrawCoindropsToken()","10a9de60":"getOracle(uint256)","10aa3d8c":"VirsymCoin(string,string,uint256,address)","10ab96e1":"LYNDO()","10abda2b":"leaderAddress()","10abdb0a":"Dealer_HitOrStand(uint256,bool)","10acec5d":"_save(address,uint256,uint256,uint256,string,string,address,uint256,uint256)","10adb0ea":"sanMaxLength()","10adda0e":"feesAvailable(address,bytes4)","10ae4a73":"presaleAllocation(address,uint256,uint8)","10ae4ce2":"setReleaseValidator(address)","10af92ba":"eachCandy()","10b0a4cb":"updateServiceMaxCreditsPerProvision(address,uint32,uint256)","10b0b5d5":"add(uint256[])","10b1bf2c":"LongPlace(address[2],uint256[8],uint256,uint256)","10b23ceb":"isAdjacent(uint8,uint8,uint8,uint8)","10b3d502":"ICO_BONUS2_RATE()","10b44094":"LogUserRegistered(address,address)","10b60e65":"SimpleTrade(address,address,uint256,uint256)","10b787d1":"evaluate_model(uint256)","10b798d9":"countRef(address)","10b7d9ae":"view_get_maintenanceMode()","10b8b441":"PrediksiToken()","10b9e583":"shutDown()","10bc044f":"setUserLanguages(address,address,uint256[])","10bc3c75":"getCurrentMiner()","10bd0d9e":"LegendsToken(address,address,uint256,bool)","10bd6d2b":"__address2__()","10bdc6cc":"joingames(uint256)","10be3808":"receivedWei(address,uint256)","10beb070":"getRaffleStats()","10bebe64":"OneExchangeToken()","10c067d2":"setPriceForProtectedCrypton(uint256,uint256)","10c0afaa":"balanceForReward()","10c1181d":"memberId()","10c12917":"calculateWinnings(uint256,uint256)","10c193b9":"total_tokenwei()","10c19421":"born()","10c1952f":"setLocked()","10c1b414":"moveTokens(address,uint256)","10c1de19":"GeneratedNumber(uint256)","10c1ff21":"crowdsaleSuccess()","10c2a365":"PreICO()","10c2c1c1":"setArbiter(uint256,address)","10c36365":"SetExchanger(address,bool)","10c3b15f":"calculateAmountToRelease()","10c452ef":"deactivate_trading()","10c4610b":"exporterBanker()","10c49b78":"CarlosCoin()","10c4b19a":"minMakerBetFund()","10c4e8b0":"all()","10c5b269":"orderMatchSell(uint256,uint256,uint256,uint256,uint256)","10c5b328":"mintTokens(uint256,address)","10c70801":"setMaxAddresses(uint256)","10c74fc6":"setGlobal(uint256,uint256)","10c7868f":"sessionNumber()","10c9135e":"getTime3(address)","10c9ab39":"makeTrans(address,uint256)","10c9c76d":"updatePokecoinAndPokemarketAddresses(address,address)","10cad61f":"combinedGoalReached()","10cad69c":"getBrickIds(uint256,uint256,bytes32[],uint256,uint256,uint256)","10cb4302":"DstTokensIssued(uint256,uint256,uint256,uint256)","10cb4d64":"rejectCurrentPlayerDraw(bytes32)","10cb5628":"isPartOf(uint256)","10cb954c":"members_push(address,address)","10cbe445":"applyMC()","10cc6e21":"Dappster()","10cc969b":"sumbitForElection()","10ccbbdb":"_checkVotes(address)","10ccbe66":"setAltCapitalization(uint256)","10ce0516":"canSwap()","10ce2f3f":"buy3(address[],address[],uint256[],bytes,bytes,bytes)","10ce6452":"set_deposit_fee(uint256)","10cf5d47":"awaitingPayout()","10cfcc19":"left17(uint256)","10d0059c":"removeLock(uint256)","10d07e27":"_lotteryCard(uint256,address)","10d08ef4":"_check_winner()","10d0ffdd":"calculateTokensReceived(uint256)","10d26354":"greaterThan(bytes32,bytes32)","10d2f2e5":"set_whitelist_enabled(bool)","10d3bd2a":"transferMoneyMoney(address,uint256)","10d426f2":"_remove(address)","10d48cd3":"verificationAddressOn(address)","10d5105d":"offlineTransfer(address,address[],uint256[],uint8[],bytes32[],bytes32[])","10d58506":"transFeeCut()","10d5e276":"maxAttempt()","10d6a13a":"tokenSaleClosingTime()","10d72742":"removeFailedGame()","10d7b903":"DIALSSPUN()","10d89d37":"isExchangeUser()","10d8d74d":"setPrice(bytes32,uint256)","10d92060":"requiredGasPrice()","10d979f6":"tokenDivsOwing(address)","10da9f75":"StayBitContractFactory()","10dc0e3c":"decimalOfPrice()","10ddaa87":"_setCurve(uint256[],uint256[])","10ddd6fc":"_onPromo(address,uint256)","10debdf8":"isAuditFinished(uint256)","10e04dcb":"BONUS_500()","10e0ebb3":"callStoWithBtc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","10e1c5e5":"getKrsFromApproved(address,uint256)","10e1d6db":"payoutEscrow(uint256)","10e22d41":"receivedWei()","10e2b914":"setTargetDiscountValue6(uint256)","10e56973":"keyPrice()","10e5bff8":"setSuccessor(address)","10e6913e":"upDate()","10e6a223":"allocateSurvivorWinnings(address)","10e6be35":"getRewarder(int256)","10e6d3c9":"teamReservation()","10e6d746":"_mint(address,string)","10e6e06c":"vote(bool,uint256)","10e776ed":"lockBalanceOf(address)","10e7a9ce":"countMonths()","10e7e89f":"getLockingTimestampfrom()","10e80ded":"accumulate_to()","10e82384":"airdropAdmins(address)","10e89b22":"remove_deal(uint32)","10e96b3c":"createMorePaymentChannels(uint256)","10ea13df":"totalInvestment()","10ea6b34":"setReadOnly(bool)","10eae945":"wdToken(address,address,uint256)","10eaf707":"getWarehouseByAddress(address)","10eb3a32":"getContinuityNumber(uint32,int256)","10eb5a8c":"transferAndCallFST(address,uint256,bytes)","10ebb38d":"ASFBToken()","10ebf103":"getPokemonBet(uint256)","10ec5d2c":"funeralAndBirth(bytes32,int256,bytes32)","10eca945":"SetupMultipliers(uint256,uint256,uint256,uint256,uint256)","10ece9c6":"correctedHeroContract()","10ed5dfe":"_emitActiveChanged(bool)","10ee1910":"submitGameResultAndTriggerPayout(uint256)","10ee51ca":"GXVCSentByEther(uint256,address,uint256)","10eeb69a":"arbitrate(uint256,bool)","10ef0ac7":"endTimeICO()","10ef1976":"getEpmBalance(address)","10f01eba":"pIDxAddr_(address)","10f0c4da":"maximalInvestment()","10f13a8c":"setText(bytes32,string,string)","10f169e8":"disputeStatus(uint256)","10f1726d":"isDayTokenActivated()","10f1a274":"setMinWei(uint256)","10f226df":"addAction(bytes32,int256,int256,bytes32[],bytes32[],bool)","10f2bf3e":"closeSale2()","10f2e11c":"PrometheusX(address,address)","10f32982":"GetQueueLength()","10f3ac24":"EmergencyWithdrawNoAccountedTokens()","10f40804":"alottMainSaleToken(address[])","10f41715":"updateMintingData(uint256,uint256)","10f444ac":"ChinaInvestmentToken(uint256,string,uint8,string)","10f5f1b3":"get_participant_arbits_kyc_whitelist(address)","10f5f6b6":"free_vote_for_candidate_A()","10f66c54":"AirdropOne(address,uint256)","10f6e2a6":"setCountWinnerByPlace(uint256,uint256,uint256)","10f6fd02":"GetAllChallengeIDs()","10f74467":"kycRegisteredContributors(address)","10f7cf32":"statuses(bytes32)","10f85f44":"EAACoin()","10f88546":"declareCheater(address)","10f91e39":"walesaDawajMojeStoMilionow()","10f945c7":"withdrawToPoolOwner(uint256)","10fa01e6":"isBattleCreator(string,address)","10fa85c6":"HybridToken(string,string,uint8)","10fab6c7":"addReceivedMessage(address,address,uint256)","10fae6f4":"futureFundingWalletAddress()","10fb3c85":"addDelayedBonus(address,uint256,uint256)","10fb52bf":"createSaiFoundersEdition(uint256,address)","10fc0a6e":"RigCraftPresalePackageManager()","10fc0d39":"transferToMultisig()","10fc31ce":"balancesForPreICO(address)","10fccbf0":"presaleBurnPaused()","10fcda55":"DDFToken(uint256,string,uint8,string)","10fcdecc":"fechVoteInfoForVoter(address,uint256)","10fe42b8":"getBdpControllerHelper(address[16])","10fe5a2a":"rateEarlyStage3()","10fe7c48":"placeBet(uint256)","10fe9ae8":"getTokenAddress()","10feb0e5":"setPowerToken(address)","10ff4a1b":"lockedTokenBalance()","1100482d":"attach()","1100a9d8":"endGame(uint256,uint256,address)","1101a0fd":"claimWinnings(bytes32,bytes32[],address[],uint256[],bytes32[])","1101eaaf":"purchaserCount()","1101fa06":"WhaleChain(uint256,string,uint8,string)","1102610e":"setMarketplaceContract(address)","110466ed":"setOperatingStatus(bool)","110496e5":"allow(address,bool)","1104e09e":"SaddleShopSaleFee()","110506f0":"createCard(uint256,uint256)","11056874":"finishDApp(bytes32)","1105efe2":"_setExtraReceiverAmount(uint256,address)","11063eb1":"updateUnlockDate(uint256)","11071cb3":"CratesPurchased(address,uint8)","1107c3f7":"orderConfirmer(bytes32)","1107e77c":"removeRequester(address)","1107fa00":"thirdStageMintingDate()","1109a0a8":"blocksProducers(uint256)","1109ef92":"transferFromCrowdsale(address,uint256)","110ae711":"checkReferral(bytes8)","110b5f76":"ApprovalDenied(address,address)","110b8a6d":"changePlatformFlag()","110c478b":"uintRound(uint256,uint256,uint256)","110cee6b":"FlightDelayPayout(address)","110d35b8":"buyAsset(uint256)","110d9e68":"insert(bytes32,uint256,uint256,address,address)","110dc7a6":"doInvest(address[3])","110df916":"getChannelID(uint256)","110f8874":"withdrawRefund()","110fd65f":"toBeRaised()","111002aa":"createTask(string)","11102d4d":"devRatio()","11103599":"Token_Offer(address,address,uint16)","1110b13a":"getWinningPosition(uint32)","11115e38":"controlTime()","1111cd24":"getBuyReturn(uint256)","11125497":"setCodename(string)","1112b124":"setBuyPrice(address,uint256)","11136747":"_init(uint256)","1113ed0d":"KERNEL_APP_ID()","1113f2e6":"_addEth(uint256,address)","1114811a":"FACTOR_9()","111485ef":"individual_cap()","11149ada":"getProof(uint256)","1114fce5":"clearAdmins()","1116cba9":"WWNCoin()","1116f631":"setFunctionSevenPrice(uint256)","111723ed":"getShipDetails(uint256,uint256)","1118069c":"enforceKyc(bool,address)","111839d5":"rushTimeFloorCount()","11184392":"registrationDeadline()","111878f6":"addBonus(uint256)","11191186":"setReservingPercentage(uint256)","11196117":"setGameStateFCF(bool)","11196cc2":"tournamentFinished(uint256[])","11199872":"setSignatureChecker(address)","1119e8a6":"increaseNumber(uint256)","111a1fe9":"dividendsBuffer()","111a7427":"setNewAttributes(string,string)","111b30a7":"setFundariaTokenBuyAddress(address)","111b63ab":"CoinparkToken()","111b72c3":"accountCreated(address,bytes32,int256)","111bc51a":"VibeCoin()","111cf909":"setIntegerVaule(uint256)","111d7241":"tournaments()","111d8171":"getNews()","111da3a7":"popFirstFromArray(address[])","111e73ff":"SetAlias(uint256,bytes32)","111eaba0":"updateOwners(address,address[],uint256,uint8[],bytes32[],bytes32[])","111fba02":"NETM()","1120ba47":"ApolloSeptemCrowdsaleExtended(address,address)","112227ae":"TIER3_BONUS()","11223a2f":"phasePublicSale1_From()","1123adb1":"currentDividendPeriodNo()","1123cdd9":"decideSplit(uint256,uint256,string)","1123e608":"LogMigrate(address,uint256)","1123efd5":"getNumGamesStarted()","1123fcce":"getEmployeeCount(address)","11247233":"changeArrangerFeeRecipient(address)","1124c05a":"getLogs(uint256)","1124e9ea":"setfocuscardid(address,address,uint256)","11262105":"getLog(address,uint256,uint256)","11269de6":"setFreezeForCoreTeam(uint256,address,uint256)","1127be97":"recomputeLastAverageBalance()","1128798f":"isCrowdSale()","1128b59e":"bonusStage2FirstDay()","1128bbfd":"getProposalAddress(uint256)","112940f9":"addConsumer(address)","1129f644":"STAKE_START_TIME()","112a19af":"Enlisted(address)","112b3c52":"MuxeToken()","112b4495":"_appendTagged(string,string,string)","112b466e":"btcraised()","112c7075":"ManualDeposit()","112cc015":"ROLE_CRO()","112d6b34":"getRefBalSended()","112d761c":"addAnimal(uint8,address,uint32)","112dd4fd":"foundation_coins()","112e39a8":"scheduleCall(uint256)","112e40b5":"setBalanceOfETH(address,uint256)","112ea262":"authorizeProvider(address)","112ed3f5":"resetWeiBalance(address)","112f5eb8":"airdropCall(address,address,uint256)","112fb7c9":"finishGenerating(bool)","112fbe9b":"transferMinimumFee(address)","11302818":"addRefBonus(address,uint256)","11308d66":"freeLandsOf(address)","1132fae4":"_utoa(uint8)","113353a8":"changeMember(uint256,address,address)","1133f89d":"sendToGrowthContract()","11340c21":"getEGTTotalSupply()","1134269a":"convertForPrioritized(address[],uint256,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","11349a6d":"dispute_end()","1134b7da":"emptyBody(uint256)","11355585":"setBlockLimit(uint256)","1135b3ac":"allocateInternalWallets()","113642e5":"getConfirmationCount(bytes32)","11367b26":"destroyer()","1136aa64":"rocketTravelTime(uint256)","1138001c":"lenghtenFrozenState(uint256,uint256)","113990b8":"PRICE_MULTIPLIER()","1139a355":"releaseForTransfer()","113a8ed5":"Film()","113b2eff":"_userRefund(address)","113b5cf2":"checkBonus(address)","113bb8db":"EventTransfer(address,address,uint32)","113c589f":"SmartBillions()","113ca356":"ticket(address,bool)","113ce458":"winnerBidValue()","113d1975":"totalTokensForSaleDuringICO4()","113d32d0":"TournamentCreated(uint256)","113d8938":"addBytesSetting(string,bytes32,address,address,string)","113e2088":"votingData()","113e5b93":"dayToDate()","113e6b66":"fipsAddToLedger(bytes20,address)","113e9d4f":"DigitalKeyCoin()","113ee583":"aliceClaimsPayment(bytes32,uint256,bytes32,address,address)","11400d8e":"priv_fastGetBlockHash__(int256,int256)","1141d7de":"URI()","11420f90":"MYINITIALSUPPLY()","11424eac":"implementInterface(string)","11428ce8":"DTXToken(address)","1142d47f":"spentFunds()","114385a0":"AddReward(uint256,string,string,string,uint256)","1143c026":"disableICOSwapLock()","11448a56":"scuttle()","11456b47":"addName(string)","1145a20f":"scheduleCall(address,bytes4,bytes32,uint256,uint8)","1145a49c":"test_oneTrueAssert()","1146015e":"setData_6(uint256)","11461614":"pushRatePlan(uint256,string,bytes32,bool)","114630e1":"ADVISORS_TOKENS_SUPPLY()","11463a01":"getChampion()","11466110":"Pretorian(string,string,string)","11467d7c":"deactivateUser(address,uint256)","114719c5":"getLongGap()","11471e17":"tokensPerEther2()","1147b142":"MercatusDeals()","1148d93e":"initializedRatify()","1148da2f":"proposeWrittenContract(string)","11497c69":"PlayChapToken()","1149b5f5":"PendingManager(address)","1149f736":"unpackPrice(uint16)","114b4f1c":"howManyGuaranteed()","114beab3":"availableTokensforPreICO()","114d081d":"markHours(bytes32,bytes32,int256)","114d38a0":"notExceedingSaleCap(uint256)","114d69b2":"setCRLaddr(address)","114d8be1":"addNewOwner(address)","114da3e3":"mintWithEvent(address,uint256)","114de05e":"addMultipleRecords(uint256[])","114e4802":"congratulationsText()","114e6b37":"setDependencies(address,address,address,address,address,address)","114f0e49":"player4()","114f9511":"pay(bytes32,uint256,address,bytes)","11506970":"freezeTokensAmount()","11506d4b":"forgiveThis(address)","11513ba5":"setTTWTokenAddress(address)","11552212":"Hodl(address,uint256)","1155d042":"accumulateFee()","1155f60f":"RoundBetStarted(uint256,uint256)","11563b04":"ETokenAirdrop()","11566dd7":"fundingMax()","11567f95":"readnameXaddress(address)","115793d4":"newClockmaker()","1158183a":"isPreIcoActive()","11589260":"_createProxy(address,address)","1158f696":"createMarriage(bytes32,bytes32,uint256,bytes32,bytes32)","115976c4":"admin1()","1159f39b":"transferFromCroupier(address,uint256)","1159fd53":"isAContract(address)","115a43e9":"getWarriorOwners(uint256[])","115b7fa8":"setOverBalanceLimitHolder(address,bool)","115bd3f8":"rejectInvestmentWithdrawal()","115bdfe7":"currencyMap(address)","115ce332":"isAddressMember(address)","115e397e":"getTotalchannels()","115e9375":"getUint256Min()","115ecc58":"fundStorageVault()","115ece4c":"getTokenAmount(address,uint256)","115f2be2":"customBuyerLimit(address)","115f2f2f":"tokensPerUSD()","115f6795":"cratesSold()","115fd072":"PowerStandardToken(uint256,string,uint8,string)","1160a807":"addWinTickets(uint256,uint256)","1160b93b":"calculatePayrollRunwayInMonths()","11610c25":"bet()","116134ee":"mask()","11613fc9":"godBank()","116191b6":"gateway()","1161a5c8":"registMyHns(string,address)","1161d226":"_participateIsAllowed(uint256)","1162247e":"lastTwoAmbassadorsAdded()","11642134":"produceEmeralds(address,uint256)","1164e11e":"getPurchaserAddressCount()","1165214d":"NotToRent(uint256,uint256,address)","1165dce2":"getTeamList()","11667335":"adminRetrieveContractConfig3()","1167ecb2":"finishPreICO()","116877cc":"changeAuthority(address)","116a6f6c":"BONUS_TIER_7_LIMIT()","116a8221":"airFropTracker_()","116b556b":"founder1()","116b7aa9":"setGameGiftOnceAmount(uint256)","116c347a":"_withdrawTokensTo(address)","116c6eab":"getProfitShare(address)","116c92b7":"addAccount(address,uint8,bool,address)","116d816b":"assetManagement(address)","116e8726":"crowdsaleDasTokensChangeBeneficiary()","116ea900":"createETHCardCollectible(uint8,uint8,uint256,address,uint256,uint256,uint256)","116fb2a8":"setTokensPerETH(uint256)","116fe01b":"ClipperCoin(uint256,string,uint8,string)","11704f52":"tradingLive()","1170a759":"withdrawalCoolingPeriod()","11715316":"CorpCoin(address,uint256)","11715c94":"getBonusRateForAmountBased(uint256)","11717501":"IEFBR14Contract()","11719d7e":"getCrowdsalesForUser(address)","11728ecf":"toKey(address,uint256)","117328b9":"LogBidReturned(address,uint256,uint256)","11737d7b":"getFreeTime()","11738735":"bnbWithdrawEnabled()","1173ca7d":"CashBackToken()","11746e5e":"getSpaceshipProductCount()","1174ca26":"totalLossValue()","117546c5":"lastParentBlock()","1176205e":"setMaxRequestQuota(uint256)","1177275e":"ZferToken(address,uint256,uint256)","117735f0":"NewQuest(string,bytes32)","1177645b":"set_devContract(address)","11776737":"CrowdServe(address,uint256,uint256)","11777af7":"refundVault()","1177892f":"getBalanceByAdress(address)","1177dc34":"nullFace(address)","117803e3":"OWNER()","11780a01":"erc20tk()","11789bec":"njbToken()","1178f51a":"ubiatarPlayVault()","11791368":"removeCurrentIcoRound()","1179778b":"setBasePremium(uint256)","1179cf71":"lowEtherBonusValue()","117a0a22":"CosmoToken()","117a4425":"setII_S(uint256)","117a5b90":"games(uint256)","117b198e":"soldTokensLimit()","117b4705":"retract(bytes32)","117b652b":"rewardinterval()","117cae9a":"editStartlist(uint256[],uint256[])","117d4128":"getOrder(uint128)","117d82d6":"playCount1()","117d94f5":"sendFundsToWallet()","117ddaf9":"weiRaisedInPreICO()","117de2fd":"payout(address,uint256)","117df088":"withdrawDeposit()","117e62fd":"getLastAuctionsWinningBid()","117f8684":"changeBZxVault(address)","1180788e":"searchString()","1180d67e":"angelFoundationShareNumerator()","1180f83b":"changeFMPcontractAddress(address)","1181324b":"updater(address)","11815312":"grantTeamAdvisorSupply()","1181a459":"freezeAdministrationContract()","11822cb7":"UTPL()","11823d43":"OCMarket()","11823e04":"advisorAllocation()","1182c796":"debug_is_dry()","11831234":"testFailPullWhenStopped()","1183429a":"removeAddressesFromWhitelist(uint256,address[])","11844aae":"period2End()","11851b5e":"BOARD_3()","11857ed7":"spendAdvertising(uint256,uint256)","1185a6b9":"getBBFarm(uint8)","118644f6":"OxBtcDex(address,address,address,uint256,uint256,uint256)","118654f1":"XinXianToken(address,uint256)","1186560e":"increaseEthRaised(uint256)","11873ee7":"SetGuestName(string)","1187497e":"updateContractState(uint256,uint8)","1187648b":"testInstant(uint256[3])","11878333":"InitialToken(string,address,uint256)","1187d66e":"votedNo()","1188189e":"storeSomething()","1188324b":"soldCWC(address,uint256,bytes32)","11883c6d":"make_hash(uint256,uint256,address,address,uint256,uint256)","11886bd4":"view36()","118934cc":"ownerCommission()","118a0aae":"addHero(string,address,address,uint256,uint256)","118a9db3":"revenueShare(uint256)","118aa5a1":"convertToRate(bytes32)","118b0f04":"santToken()","118b53ec":"LogTeamTokensTransferred(address,uint256)","118cbccb":"etherWeiRate()","118ceab6":"lastAdjust()","118da6fb":"getGameCompleted(uint256)","118dd8fc":"bonusesAfterClose(uint256)","118e1f2e":"globalOrderSerial()","118e31b7":"getBorrowBalance(address,address)","1190516d":"GetByte(uint256,uint256)","1190647c":"buyerHistory(address,address,uint256,uint256)","11916ce7":"moveIcoTokens(address,address,uint256)","11933e4b":"Transmuted(address,address,address,uint256,uint256)","11937ccd":"adminUpdateStartEndTime(uint256,uint256)","1193e38e":"setPercent3(address,uint256)","1194ed46":"payerString()","11952369":"onRemove()","1196004f":"newCycle()","1196245b":"registerDIN()","1196493c":"getJobContracts(uint256,uint8)","119669cb":"GiveChipGitf()","1196deda":"sendTeamTokens(address,uint256)","1196fb60":"contributeToPrizePool(string,string,string)","119739ff":"privatesaleEnds()","11997dc6":"BASE_DURATION()","119aa5c8":"checkForward(bytes)","119b22b3":"roundNum()","119c1c23":"tokenAllowance(address,address)","119cb2ff":"tokenPriceDivides(uint256)","119cbed6":"rtm_contract()","119cc328":"setFoundersWallet(address)","119ce91b":"voteInfo(bytes32,address)","119d0cb5":"DumbCoin()","119d97ee":"team4Address()","119d9bfe":"KudosTokenFactory()","119dd1b0":"presaleLimitReached()","119e045b":"checkMaintenanceTime()","119e5cdf":"creationUnit()","119ebe89":"getExternalCurrencyProcessor()","119ecb35":"tokensaleStageNow()","119ee4ab":"batchCancelAuctions(uint256[])","119eeb9c":"darx()","119f118d":"ethToCash()","119f1edb":"claimPlatinum(uint64)","119f2546":"distributeEBTC(address[])","119f2c9f":"transferCard(address,uint256,uint256)","119f32dd":"adminIsDead()","119f8747":"support()","119fdee2":"sha256ofString(string,string)","11a00327":"deleteOrder(uint256)","11a09ae7":"airDropTracker_()","11a0c16c":"dsquare(uint256,uint256)","11a10508":"switchToNextSale(address)","11a10698":"ERC223Token(uint256,string,uint8,string)","11a153df":"getBlockNumSinceInit()","11a1b31e":"commandGetBonusTime()","11a4c710":"buyRecipient(address)","11a5a793":"percentageToKill()","11a5b9bc":"migrateBlock(string,uint256,uint256,uint256,address)","11a76729":"transferFromInBatch(address,address,uint256[])","11a800bc":"addressOf(uint256)","11a881e8":"setFee(uint256,uint16,uint256)","11a88e05":"preSale2()","11a8f413":"latestRoundId()","11a98193":"ETHfund()","11a9c3c2":"sellDOTCH(uint256)","11a9f10a":"noToken()","11aa7e26":"setKevin(uint256)","11aaf884":"HCPToken()","11ab19f8":"addTokenToTotalSupply(uint256)","11ab27d2":"HydroCoinPresale()","11ab31ed":"rejectProposal(bytes32)","11ac20c0":"cancelLottery(uint32)","11adbaad":"getListOfAddresses()","11ae40b2":"Presale(uint256,uint256,uint256,uint256)","11ae6aee":"_mint(int256,uint256,uint256,uint256)","11aee380":"memberCount()","11af07e2":"create_event(string)","11af3c68":"divest(address)","11af6564":"getCurrentGasPrice()","11affa5c":"setEggTable(uint16,uint32[])","11b059c6":"mintableProperties(uint256,bytes32)","11b2b22a":"FRKT()","11b35c48":"AGSCoin()","11b4bbdb":"mintTokens2(int256,address,uint256,uint256)","11b546f6":"firstWeekTokenPrice()","11b639d9":"currentTokenCount()","11b63a17":"CROWDSALE_TOKENS_NUMS()","11b70018":"bookingList(address,uint256)","11b7702a":"ImportTestA()","11b7d483":"addressGains(address,address)","11b8f957":"dayAfterDeadline()","11b97324":"participateCrowdsaleSelected(address[])","11b98e12":"isMainSaleTokenRaised(uint256)","11b9fee8":"ForkChecker(uint256,bytes32)","11ba65e5":"_setUpgradeabilityOwner(address)","11baae84":"Contribution(address,address,uint256,uint256)","11bab044":"getCreditFundAddress()","11bb20da":"withdrawBattleValue(address,uint256)","11bbb155":"goLong()","11bbdf53":"maxOpenAttacks()","11bc0a34":"BuyOrder(uint256,address,uint256,uint256,uint256,uint256)","11bc5315":"drawer()","11bcd573":"SetTest(address)","11bcd830":"MinDeposit()","11bd85ad":"Owned2()","11bdfe19":"revertBet(uint256)","11be40e0":"transfer(address,address,address[],uint256[])","11bec062":"EVT()","11bed352":"eip20Approve(address,address,uint256)","11bf68cf":"_issue(bytes32,address,address,uint256,bytes,bytes)","11bfe017":"playerWinItems(address)","11c07649":"getMainAccount(uint256)","11c09100":"calculateNumWeiToIssue(uint256,uint256)","11c0b024":"_setDamgeValue22(uint256)","11c0f931":"bindSmartIdentity(string,string)","11c12715":"LCToken()","11c134e1":"sumPreICO()","11c15dcc":"purchaseBalances(address)","11c19d3c":"SpiderFarm()","11c1dc82":"monakojima001()","11c1ddd9":"addMedalBurned(uint16)","11c28e1a":"initial_tokens()","11c33625":"royaltyInformationContract()","11c3a62f":"GetLuckyResults()","11c3fec5":"CreateLand(uint256,address)","11c4d4f4":"communityAddr()","11c4dbf4":"auctionReputationReward()","11c4e123":"rootHashOf(bytes32)","11c52ec0":"setMaxWagerWei(uint256)","11c57757":"tixPromoDeposit()","11c5a234":"logResult(int8,string)","11c60418":"remAdmin(address)","11c7d6bd":"issueNewSeries()","11c8efac":"lifeA(uint256)","11c911d9":"unreserve(address,uint256)","11c91914":"isUnderLimit(uint256)","11c93d03":"crowdsale_eth_refund()","11c94362":"COMMUNITY_RESERVE()","11c98718":"getMsgDataBefore()","11c99f3b":"FundsWallet()","11c9ccf6":"deleteCustomer(address)","11ca3c63":"satoshiRaised()","11cb0bcf":"getParticipantOriginWithIndex(uint256)","11ccf822":"beneficial()","11cd98ed":"convertToAllTable(uint256,string)","11cda415":"peer()","11cdf27a":"addVersion(address)","11ce0267":"storageContract()","11ce3d24":"postMonForMon(uint64,uint64)","11ce3d2c":"GQHToken(uint256,string,uint8,string)","11ce4556":"TOKEN_TO_CREATOR()","11ceb21c":"ZigZagSupply()","11cec8f0":"getTradeByIndex(uint256)","11cfb19d":"freezedTokenOf(address)","11d12402":"testEasyPropose()","11d15e17":"freeReadings(address)","11d17e78":"Blocker_destroy()","11d295bf":"_getShipName(uint256)","11d36bf5":"reservedSaleEther()","11d36c4f":"setBoolF1F2F3(bool,bool,bool)","11d40001":"EthernautsVendingMachine()","11d414af":"changeIcoStatus(uint8)","11d4f314":"setBounties(address[],uint256[])","11d62de9":"ownerShip(address,address)","11d634ac":"HamsterMarketplaceToken()","11d7b2fe":"unlockAccount()","11d817f2":"getUsers(address,bytes32)","11d8657a":"finalizeAndPayoutForHopeful(uint256,uint256,uint256,uint256)","11d87c4e":"initGame(uint256,bytes32,bytes32,bytes32)","11d89f3a":"setResearchAndDevelopment(address)","11da60b4":"settle()","11da9598":"add2MarketPlace(address,uint256,uint256,uint256)","11daa2d0":"jpPercentage()","11daa7a0":"gamessage(address,address)","11daca81":"joinPot()","11daea9c":"removeExchangeTestAccounts(address,address)","11daf56a":"MainFabric()","11db0176":"unLockFreeze(uint256)","11db3be7":"invokeVerification(uint256,uint256,uint256,string,bytes32[2])","11db6e0e":"ownsSouls(address)","11db8d1b":"burner(uint256)","11dbb12e":"removePolicyRule(bytes4,address,bytes32)","11dc273d":"currentBalances(address)","11dc45c9":"withdrawPrize(address)","11dc4703":"removeUser(uint256)","11dc6816":"getAllowanceOwnerValue()","11dcee2f":"priceCallback(bytes32,uint256,bool)","11dd2837":"_updateCurrentStage()","11dd39b4":"cancelApprove(bytes32)","11dd576d":"userCheck(bytes32)","11dd8845":"getRecord(string)","11ddf693":"debug_changeOwner(address)","11df19f7":"_medalTotalSupply()","11df9995":"coin()","11e0de8b":"tickets10kprice()","11e13c32":"BONUS_ICO_STAGE1_PRE_SALE4()","11e14b2e":"employees()","11e21245":"weiSoftCap()","11e3655f":"updateInstantToken(address)","11e38468":"MarketboardListingComplete(address,uint256,uint256,uint256,uint256)","11e3d606":"min_investment_eth()","11e48cdf":"tokensAllocatedTotal()","11e5b955":"Order_sell(address,uint256,uint256)","11e5ea57":"teamsWallet()","11e67c57":"totalBuyOrders()","11e6a0fd":"getProviderDetails(uint256)","11e847b6":"HATCHBACK()","11e84c71":"claim(bytes32,string)","11e956c8":"isMasterNode()","11e96ab6":"LockCredits(address,uint256,uint256)","11e99c22":"arrival()","11eb6d4b":"GxAuth()","11ebbf24":"createWallet()","11ec76cb":"LogClaimHalvingSubsidy(address,uint256,uint256,uint256)","11ec7b4a":"balancePrivateSale()","11ed1bf6":"artworkIndex()","11ed7b42":"thirdItemWrong()","11ee0ec5":"getZone(uint256)","11ef8d4b":"delegateBonusTokens(address,uint88)","11efbf61":"getFeePercentage()","11efec9b":"shareHolderByNumber(uint256)","11efff1f":"unlockRecordAdd(uint256,bytes32,string,string,uint256)","11f02c87":"createHybridization(uint256,uint256)","11f03b83":"GiftCrowdsale(uint256,uint256,uint256,uint256)","11f0b806":"getDutchAuctionToCraftAddress()","11f1507e":"getAssetToken(uint256)","11f15380":"clientKeysCount(uint256)","11f1fc99":"withdrawTreasury(uint256)","11f217c7":"getNodeAddress(address)","11f29729":"setsymbol(string)","11f2a395":"finalWithdraw()","11f2eed1":"convertEthToMet(uint256,int256)","11f37ceb":"get_price()","11f3eecd":"sellTokens(uint8)","11f43157":"openCrates()","11f45f23":"buyVIBET()","11f48166":"IntroToken()","11f4a9ce":"KernelProxy(address)","11f4ba60":"importBalanceOf(address)","11f54545":"SmatrOCrowdsale(uint256,uint256,uint256,address)","11f58e99":"maxTokensSold()","11f598cd":"editPersonalNote(string,uint256)","11f6649b":"authorizers(uint256)","11f6ad2b":"lastWinnerId()","11f72496":"testT()","11f82a2b":"_getPolishingPrice(uint256)","11fa3d14":"LeekCoinCrowdsale(uint256,uint256,address,address)","11fa3f4f":"weiUsdExchangeRate()","11fa7da2":"getInvestmentsInfo(address)","11facae2":"setValidatorCount(uint256)","11fb57e2":"TokenManager(address[],uint256)","11fb584a":"BloccaConto(address)","11fbad62":"_rejectTransfer(uint256,uint256)","11fdff0c":"advisorPool()","11fe12b3":"isRecovery(address,address)","11fe773d":"memcpy(uint256,uint256,uint256)","11ffb1d4":"deleteMember(address)","11ffe7c9":"getUserDocCount(address)","12005e53":"alexToken()","1200617f":"auction(uint256)","12007984":"addBalanceToGame(uint256)","120149a1":"readCube(bytes32)","120184fa":"gvCF()","1202be01":"eth2mnt()","12032e52":"getSecondaryRecord(string)","12035ca6":"setData_3(uint256)","12038a01":"totalDevelopmentFundEarned()","12039fed":"mintMedal(uint256)","12045d3f":"VKTToken(uint256,address)","1204bab4":"popcount(uint64)","1204ce91":"Debug(bytes32,uint256)","1204d27c":"coinIssuedBurn()","12055758":"checkOwner(address,uint32[11])","12058764":"lockBalanceGroup(address,uint256)","12059f68":"LoversAdded(string,string)","12065fe0":"getBalance()","1206dc5f":"transferMarketplaceOwnership(address)","12074a46":"getUserBets()","1207bb8e":"crowdsalePrice()","1207f0c1":"issueTo(address,uint256)","1208a256":"getLock(address,uint256)","1209073c":"updateBalances(uint256)","120960de":"depositInPot()","1209b1f6":"ticketPrice()","1209f7ed":"withdrawPledge()","120bd501":"approves(address,uint256)","120bd8f5":"setMinimumBetValue(uint256)","120c5194":"getCollectReporterAddress()","120c52ef":"calculateDemurrage(uint256,uint256)","120c7efd":"certifier()","120cc993":"isEmptyOwner()","120dae83":"setMinimalContribution(uint256)","120e6c16":"_finneyToWei(uint32)","120e8f05":"calculateMintAmount()","120fe731":"Tropycoin()","120fe89b":"getPolls()","121114e1":"SuperTicketCoin(uint256,string,string)","1211540c":"withdrawPartial(uint256)","121166ef":"clearTrade(bytes,address,bytes32,address,uint256,int256,string)","1212c12f":"RecordManager()","12136918":"setMaxTranferLimit(uint256,uint256,uint256)","12136e57":"ERC777ERC20BaseToken(string,string,uint256,address[])","12146222":"highSupport(address)","1214ab82":"Lightning()","121557a3":"Avatarium()","121563ae":"Axioms()","12156c66":"snowflakeCall(address,string,string,uint256,bytes,bytes)","1215f8ef":"releaseValue3()","1216e771":"expiration(uint64)","12179a2d":"pendingReferals(address)","1217b6ff":"TransactionConfirmedByMediator(uint256,uint256)","121839f6":"addConfirmationNode(string)","1218d6bf":"decree()","12192649":"countOfParticipants()","12192b00":"getInitialHP(uint64,uint64,uint64)","1219bcfc":"MolToken()","1219d5c8":"APM_APP_NAME()","121a47ac":"nonceForPublicKeyX(uint256)","121a496b":"Lupecoin(address,address)","121ab65b":"LogChangeSponseeAddress(address)","121af083":"DFSCrowdsale(uint256,uint256,uint256)","121b5a25":"calculateCompensation()","121b68c1":"ERC223Received(address,uint256)","121c2b35":"burnPXLRewardPXLx2(address,uint256,address,uint256,address,uint256)","121c5e91":"putOnSale(uint256,uint256,uint256)","121d6426":"senderWeiBalance()","121dbc31":"changeMax(uint256)","121e0d4e":"godPause()","121e6832":"frozenDaysForPartner()","121e8122":"unQuarantineAddress(address)","121eb9e2":"createMintRequest(address,uint256,string)","121ef243":"createUser(string,uint256)","121f0a10":"resolve(uint256,uint256,string,bool)","121f2081":"testCreateWithForeignParent()","1220c6ed":"registerOwner(address)","12217378":"oldTokenTotalSupply()","1221a071":"cmctcybermovie()","1222c25a":"redeem(string)","1222e789":"isPublicSaleWithBonus()","122366fd":"PACCOIN(uint256,string,string)","1223716a":"masterHas()","1223f208":"withdrawadm(address,uint256,uint256)","12243b67":"deletePlayer(address)","12247a57":"IncentCoffeeToken()","12253a6c":"stopContract()","12263017":"setBool82(bool,bool)","122636b1":"getRemainingDaysToThirdPhase()","12267abc":"PRICE_6()","1226afde":"numtickets()","1226be3e":"NotifyMe(address,address)","1226cd98":"allocate(uint128,uint256)","1226f5f8":"wei_per_token()","12278825":"Git(uint256)","1227d0f4":"gameListOf()","122809dc":"deposits_refunded()","12285576":"Donated()","12286715":"SimpleSavingsWallet(uint256)","12287629":"consultantsKey()","1229987d":"collectProfitERC20(address)","1229af09":"FreshROI(uint256,uint256)","122a1949":"Group_1()","122a7723":"GetPriceMultiple()","122b0e85":"getVerificationLevel()","122bdc32":"ThemKhoaHoc(string,uint256,string,string,string,string)","122d34d9":"returnToken(string,uint256)","122d9a8d":"piEndTime()","122e04a8":"WITHDRAW_ADDRESS()","122e74f4":"getWeiLeft()","122fe685":"presaleAddress()","122ff73a":"_getStrengthDexterityVitality(uint256,uint256,uint256)","12302932":"reinvestAffiliate()","123119cd":"payer()","12317402":"betMinAmount()","123180a2":"testInitialBalanceWithNew()","12333b32":"StartGame(uint256)","123398aa":"johnnycoin()","1233f543":"distribute55M(address[])","12342248":"CreditleetToken()","12360151":"dayPotLeader()","123702e2":"profitAddress()","123731c4":"addressPositions(address,uint256)","1237b2a6":"TotalPot()","123802e1":"forceRefundState()","123807b2":"markParticipantIdentifiend(address)","123841cf":"MintedGreen(address,uint256)","12386471":"sumExpOffset(int256,int256[],uint256,uint8)","1239ec8c":"batchTransfer(address,address[],uint256[])","123b06d5":"currentPendingParticipants()","123b1dae":"accountOfP(address)","123b5e98":"setAttributeSigned(address,uint8,bytes32,bytes32,bytes32,bytes,uint256)","123ba3e2":"changePrizeSplits(uint256,uint256,uint256,uint256,uint256)","123c3a4f":"maxTokenSupplyICO2()","123c3ada":"getMedalInfo(uint256)","123cc082":"setJoinedCrowdsales(address)","123d997a":"removeAllowCnsContract(address,bytes32,address,bytes32)","123e4112":"arrayToCrabPartData(uint256[])","123f513c":"testDeadChickenCnt()","12407f98":"toSaleWallet()","1240adc8":"stoppCrowdsale(uint256)","1240b381":"PermarektToken()","1240de76":"testUnexpiredBalance()","124135c9":"exit(bytes,bytes,uint256,bytes,bytes,uint256,bytes)","1241d7a7":"setEnableRecord(bool)","1241ee7d":"profit(uint256)","1242031a":"ZhaoGuCoin()","12424e3f":"approve()","124279a7":"activeSignersCount()","1242e96d":"updateMarketPhase()","12432fee":"canSendWebGifAmount()","124442be":"approveIncrease(address,uint256)","1244861e":"addTokenData(uint256,string,string)","1245c653":"currentDrop()","1245e347":"teamWalletAddress()","1245f45e":"getRunningAuctions()","12460fdd":"confirmCeilingRaise(bytes32)","12468cc5":"getWifiPwd(string)","12474435":"unfreezeAwardedTokens(address)","1247caf4":"ChangeFounderMulSigAddress(address,uint256)","1248b101":"claimDay(uint256)","12491ad9":"ReverseRemoved(string,address)","1249209e":"returnExcess(address)","12494160":"isHolder()","12495a5d":"ContributionWallet(address,uint256,address)","1249c58b":"mint()","1249d3b8":"isEcoAllocated3()","124abb0a":"_checkAndCallSafeTransfer(address,address,uint256,uint256,bytes)","124b0939":"afterCallBack()","124c27a9":"addPrize(uint16,address,uint256,uint256,uint256)","124c2dde":"executeBet(address,address,uint256)","124c32a1":"enter(bytes32,bytes8)","124cf830":"isSecondaryOperator(address)","124cfc8c":"beneficiaryOf(uint256)","124d3396":"releaseICO()","124eaee6":"Identity()","124f0b31":"rewardDecimalPercentByTime(uint256)","124f2418":"deleteBytes32Value(bytes32)","124fc7e0":"increaseSupply(uint256,address)","124ff29b":"getAyantDroitEconomique_Compte_5()","12504109":"getLast24hSendingValue(address)","12508ea4":"play(uint256,bool)","1250ca3d":"getUserPaybackRate()","12511c14":"transferEnable(bytes20)","12514bba":"transfer(uint256)","12529d22":"getRank10()","1252aadb":"EightBitToken()","1252cc33":"processTickets()","125385f2":"COLOR_GREEN()","1253b82f":"travelPrice()","1254e64d":"transferEthers(address,uint256)","1254f0dc":"startRate()","12555df2":"zasxzasxqaqq()","12568c24":"blanceOf(address)","125716d6":"getContractStatus(address)","12571a33":"migrateInternal(address)","12582c1a":"setAdminMode(bool)","12592381":"incomeAllocation()","12599d3f":"GlobalEnergyDigitalChain()","1259c00d":"stampIndextodissolved(uint256)","125b8f06":"isInNextGeneration()","125bfb66":"claimToken(address,address,uint256)","125d5d71":"startEpochTimestamp()","125e527e":"Ether()","125f67e7":"SunriseCoin()","126004b8":"deleteRole()","12600aa3":"concatStrings(string,string)","1260c19a":"showInterval()","12610b5b":"pendingEditionsOf(address)","1261795d":"withdrawGas()","126262a3":"init(address,address,address,address,address,address,address,address,address,address,address,address,address,address)","1262d6be":"fortnightsFromLast()","1262eb73":"queryPlayer(uint32)","12630012":"LEOToken()","1264299a":"endPresaleTime()","126596e7":"ownerSetCallbackGasPrice(uint256)","12660306":"getLogos()","1266cae2":"setCrowdsale()","1266d5f9":"getWitnessesCount()","126702a0":"DOW_TUE()","12671fb4":"balanceAirDropToken(address,address)","12675713":"getTestekTokenIssuance(uint256,uint256)","1267961b":"ERC777BaseToken(string,string,uint256,address[])","12686aae":"transferLocked()","1268cb71":"XBPToken()","1269359a":"enableWallet(address)","126a710e":"dnsrr(bytes32)","126af4af":"tokensContractBalance()","126b12e7":"initICO()","126b6e17":"downX(uint256)","126b85e7":"addLevelQuest(address,uint256)","126c13c8":"toldYouSo(bytes32)","126c27b5":"setETHAssets(address)","126d20f1":"getBestPromouter()","126d5b83":"getPoolAmounts()","126d9882":"updateLogoFee(uint256)","126eac43":"getContribution(address,address)","126f992c":"forceOff()","126fbb3a":"removeFunds(uint256,uint256,uint256,uint256)","127043c3":"feesRate()","12706ccd":"NIGIZ()","12709b90":"SuddenDecayingTokenFunction()","1270a4d3":"setMinSale(uint256)","12711ae3":"wtech2()","127157c3":"activateDevice(address)","1271bd53":"upgradeContract(string,address)","1271f09a":"approve(address,uint256,address)","12724689":"addToTokenTransferDisallowedList(address)","1273f6e7":"BIGSELL()","12746e9f":"changeParam(uint256,uint256,uint256)","1274c3f3":"announcementHash()","127616f9":"releaseMultiWithStage(address[],address)","127714c7":"getBudget()","12778e8d":"addDistributionContract(address)","1277b0c9":"createBid(bytes32,uint256)","1277b4f1":"createCandy(string,uint256)","1277e24f":"payOneTimeFee()","127810bc":"getCompany()","12783f2f":"VESTING_TIMES()","12788f97":"B0xPresale(address,address,address)","1278cec4":"WinnerPaidEvent(address,string)","12795d7f":"putSaveData(string)","127a0dd9":"setJypcBonus(uint256)","127afec6":"MakerTransferredAsset(address,uint256)","127b0901":"delayAutorelease()","127b4da5":"getAmountForCharger(uint256)","127c3d45":"getUserLibrary()","127cc6bf":"medalTotalSupply()","127cf0b9":"multiInvokeWith3Args(address,string,address[],address[],uint256[])","127dd730":"donationNum()","127e499c":"firstBonus()","127eca3f":"totalDividendPayments()","127ecfa9":"getMinReward(string)","127effb2":"operatorAddress()","127f0b3f":"roundCount()","127f1068":"pieceprice()","127f2d2c":"shutForDai(uint256)","127f3374":"calculateselfOdd()","127f902f":"addressFundReserve()","12800751":"determineWinner(uint256,uint256)","12806653":"setMaxContributionPhase2(uint256)","1280db73":"donate(address,string,string)","12810fd8":"Lesson_6(address,uint256)","1281311d":"buy(uint256,uint256,uint256,uint256)","1281619b":"SeeleTokenLock(address,address,address)","12818f0c":"withdrawNac(uint256)","12819817":"setXauForGasCurrator(address)","1281d056":"test_threeValidEqBool()","12821b5e":"sellingPrice()","1282467d":"checkTip(uint8)","12826f30":"isEthereumBased(address)","1282cc2a":"getNumContributionsDID(address,address)","1283c377":"FixedCapSampleCoin()","1283e328":"bonusOf(address)","128424a7":"sort(address[])","1284c8f5":"transferSafety()","1286d9e8":"setRowColors(uint16,uint8,uint256,uint256)","1286e393":"removePartOwner(address)","12874688":"setMinBid(uint256)","12883df0":"lcSold()","12889639":"settleFeePub(address,address,uint256,address,uint256)","1288c42a":"Prism()","12892b7f":"setblnpereth(uint256)","128952e4":"addElements(bytes32[])","128a0b2c":"approveFund(address,bytes)","128a1c74":"createUpdateRisk(bytes32,bytes32,uint256)","128a3765":"clearTransferInsToken(address)","128b265f":"addBridgeTokenFeeReceivers(uint256)","128b3bc0":"_withdrawFunds(address,uint256)","128bad8d":"MFL()","128bfcae":"startStake(uint256,uint256)","128c785f":"ICACOIN()","128cf7c5":"SEC_PER_ETHER()","128d7215":"addRequest(string)","128d9281":"checkTransferFunction(address,address,uint256)","128e0423":"getSenders()","128e1329":"offerHelpUsingBalance(address,address,uint256)","128e1af0":"withdrawFromPot(uint256)","128e3761":"firstTeamContributorId()","128e87e0":"tokensAfterCrowdsale()","128eb401":"expiredCrates(address)","128ef181":"ticketMag()","128f04e7":"importPresaleBalances(address[],uint256[])","128f8e04":"admin_active_payable()","12901f26":"purchaseTokens(uint256,address,address,address,address,address)","12907e08":"lastBlock_f6Hash_uint256()","1290a2b4":"rightSharePriceRateOfIncrease()","1290aed9":"AcornPotSplit(uint256)","12919d90":"setMoneyManager(address)","1291ebdd":"getAllowedTokenAt(uint256)","1292de0b":"sendTokensTo(uint256,address)","129441cf":"_cMoney(uint256,uint256,uint256,uint256)","129484b6":"changeFeeRecipient(int256,int256,int256,int256,int256,int256)","1294d4db":"assignReferral(address,address)","12950877":"setOrCacheValidityBond(uint256)","12958f1c":"getUserName()","1296830d":"transferPreSigned(bytes,address,uint256,uint256,uint256)","1296aef3":"timeInvestInMinute()","1296d47d":"signedApproveHash(address,address,uint256,uint256,uint256)","1296ee62":"transferAndCall(address,uint256)","12973afd":"isNotDuplicateTreasure(bytes32)","12974218":"tokensRemainingForSale()","12975687":"mediaTokensDecimalUnits(address)","12987c98":"large()","129893dc":"ParameterizedToken(string,string,uint256,uint256)","129932d5":"_spto(uint256,uint256,uint256,uint256,address)","1299c8fe":"GetAccountIsFrozenByDateCount()","1299f11e":"updateNextWindowAdjustmentRatio(int256,bool)","129a1a37":"Dissolved(address,uint256)","129a5b99":"getPropertyStatus(bytes32,address)","129a8d25":"LogKYCConfirmation(address)","129a9e99":"enterEvent(uint256[12])","129b873b":"addVote(uint256,address)","129bc044":"unlockAccount(bytes32)","129caa18":"haltICO()","129cf7cb":"ForeignBridge(uint256,address[],uint256)","129ed395":"accountLock(address)","129f80fb":"rewardAirdropMany(address[],uint256[])","12a00b21":"calculate_base_mining_reward(uint256)","12a0421c":"safeWithdrawal2(address)","12a06c35":"NFF()","12a0b32c":"transferRestrictedStock(address,uint256,uint256)","12a0b3ba":"VOLOP(uint256,string,string)","12a12106":"setPayoutAmount()","12a15b91":"BlocktorialTestToken()","12a187f3":"toggleTransfer(bool)","12a1c2f2":"Mether()","12a203c3":"getFinalAnswerIfMatches(bytes32,bytes32,address,uint32,uint256)","12a2716d":"affirmations()","12a3234c":"unlockAdvertisement(uint256)","12a3bbaf":"_addHorse(bytes32)","12a3cda2":"TokenOMG(uint256)","12a3ff95":"endPrivatesale()","12a49007":"p_setInvestorFundPercent(uint256,uint256)","12a4b899":"claimPresaleTokens()","12a63964":"Releaseable(address,uint256)","12a71ee0":"setBiddingAuctionAddress(address,address)","12a77dbd":"getLockedToken(address,uint256)","12a7b914":"getBool()","12a837b4":"transfer(address,address,uint256,bytes)","12a8c1ed":"testAllocatesTokensInSale()","12a916f9":"getPlayerWallet()","12aa2c0d":"getMinBal()","12aa5360":"addAlpha(string,string,bytes32)","12aaac70":"getKey(bytes32)","12aaafa7":"amount_milestone()","12ab7242":"setupStackDepthLib(address)","12abbaaf":"WhosItGonnaBe()","12ac18ff":"About()","12ac4a2e":"bonuscal()","12ac5bad":"GetContractStateCancelledByTenant()","12ac9b46":"_escrow(address,uint256)","12ad8bfc":"registerSecret(bytes32)","12ad8d20":"CryptoElections()","12addb94":"saleEnd4()","12ade015":"oneTokenInFiatWei()","12aef8c3":"tokensForSale()","12afbc78":"getOwnedPointCount(address)","12afef2e":"Reservation(address,address,address,uint256,uint256,uint256,uint256)","12b0b3ca":"transferFromToICAPCallGas()","12b0b627":"splitStr(string,string)","12b0d309":"restrictTokenTransfer(address)","12b1cc95":"createHash(uint256)","12b1f8a9":"removeLand(address,uint256)","12b27e3e":"miningActive()","12b2ecc6":"init_bounty_program(address)","12b392ee":"admin_profit()","12b3a445":"getERC721Nfts(uint256,address)","12b48d3c":"CountryCoin()","12b495a8":"delta()","12b4ba71":"emitTokenStateUpdated(address)","12b58349":"getTotalBalance()","12b62a07":"playerWinHeroes(address)","12b68263":"creditDragon(address,uint256)","12b68286":"whitelistMinTok(uint256,address)","12b6ef5c":"Decision(uint256,address,address[],uint256[])","12b706a7":"buyPreSale(uint256)","12b8ca5e":"_isDiamondOutside(string)","12b93ec6":"ChallengeContract(uint256,string,uint256,address,address)","12b97812":"addOffering(address,bytes32,address,uint256)","12bae48d":"StartDate()","12bb05ff":"claim1Ply(uint64,uint64,uint64,uint64,uint64)","12bb65ca":"MANHATTANPROXY7THAVE()","12bb6df7":"LogRewardPicked(uint256,address,uint256,uint256)","12bb9d3e":"RefundableCrowdsaleWithCommission(uint256,address)","12bc74e2":"withdrawBondReward(address)","12bcc858":"claimTokensInBulk(address[],uint256[])","12bd2cea":"setImageDataCloud(uint256,uint256,string)","12bdc81b":"freedWinPoolForThirdStage()","12bddc9c":"changeRules(bool,bool,bool,bool,bool)","12be78d1":"freeze_pool(bool)","12bea6eb":"kickStartICO(address,uint256,int256)","12bff72f":"doTransferOwnership(address)","12c0af96":"getVoterOnElection(address,address,uint256,address,address)","12c0d1ea":"changeLuck(uint32)","12c1083d":"distributing()","12c2302e":"DocumentRegistered(uint256,string)","12c24128":"FootStarCrowdsale()","12c27c64":"contrp3d()","12c3ee37":"setStorageControllerContractAddress(address,address)","12c3f754":"modificationFee()","12c3f757":"soldiersinfo(address)","12c45f64":"maximumTokenSupply()","12c55a9b":"openDeposit()","12c59488":"setAddress(address,address,address,address,address)","12c61a20":"initambassadorsbags()","12c6651c":"MoralityAI()","12c6ac16":"Reconcile(address,uint256,uint256)","12c723e1":"createDeposit(uint256,uint256,bytes)","12c77207":"getLLV_edit_1()","12c7df73":"rewardValue()","12c8052f":"won()","12c82894":"compute(string,string,uint256,uint256)","12c82bcc":"sendRobust(address,uint256)","12c85095":"getRestrictedTokens(uint8)","12c89869":"getHeroCurrentPrice(uint256)","12c96f5f":"ZAYAToken()","12c99005":"startPREICO()","12cacbb5":"inPresaleMode()","12cc08f2":"getPackageReleaseHashes(string,uint256,uint256)","12cc1abc":"set_exchange_rate_in_eth(uint256)","12cc9dd3":"usdId()","12ccb421":"payPlatformIncomingTransactionCommission(address)","12cd2101":"transfered(address,uint256,bytes32[])","12cd24be":"funder(address)","12cd57c9":"inputauction(uint256,address,uint256,string)","12cdc37a":"OrderTake(uint256)","12ce73dc":"callFor(address,uint256,bytes)","12cef27a":"secondWallet()","12cf0ec8":"balanceOfAt(address,uint256,int256)","12cf85c8":"s26(bytes1)","12cf8a10":"getType(uint32)","12d00c2e":"soloWithdraw(uint256)","12d0e65a":"changeBeneficiaryAddress(address)","12d1456f":"requiredExpIncreaseFactor()","12d1612a":"closeContest(string)","12d1b19a":"poissonData()","12d2c9a5":"isWhitelistedInvestor(address)","12d43a51":"gov()","12d60f86":"fillUpAllowance()","12d6468d":"mathTransfer(address[],uint256[])","12d67c5f":"getLastDataLength()","12d69389":"maxUint32()","12d6c704":"getTMul(uint256)","12d72e99":"deregisterProduct(uint256)","12d96887":"getRollUnder()","12da6e2b":"fourthTime()","12dc006a":"racer_index()","12dc34a0":"disableSetTransferable()","12dc5ca0":"CrowdsaleToken(address,string,string,uint8,uint256,bool)","12dc6449":"test_remove_head()","12dc8c4b":"InitialTokensAllocated(uint256)","12dc9a5b":"assert(bool,bytes)","12dcb676":"remainPackage()","12dd4763":"_transItem(address,address,uint256)","12dd8700":"CevacFund()","12dd9b94":"addBet(address,address)","12de10fd":"setMinimumFundingLimit(uint256)","12de8a12":"addReferenceParentWineryOperationByRegulator(string,string,uint256,string,string,int256)","12df172d":"setScale(uint256,uint256)","12df2f49":"serviceStation()","12df9b63":"AddContact(bytes32,address)","12e135a0":"setBuyCommission(uint256)","12e228fd":"investorAddress()","12e26673":"maxMSC()","12e36530":"addMerkleTreeRoot(bytes32,bytes)","12e43d92":"AVAILABLE_PRESALE_SUPPLY()","12e43da5":"kycConfirmer()","12e530aa":"Hacksig(uint256)","12e56faf":"activeTransfer()","12e57fdc":"MONEYTREETOKEN()","12e5b7fa":"GetOwnertName()","12e6414e":"getCampaignStartDateById(bytes32)","12e753e1":"modifyContact(address,string)","12e7b2ba":"vanilAddress()","12e8e2c3":"setPlatformFee(uint256)","12e8ebdf":"unpauseWithdrawal(address,address)","12e905b0":"selfAddress()","12e9db2d":"get_deposit_balance(address,uint256)","12ea0b0e":"INV()","12ea7d20":"BoSToken()","12ea965d":"icoStartBlock()","12eabe7e":"approuver(address,uint256)","12eacf4b":"fundInsurance()","12eba773":"isAdvisorsTokensFirstReleased()","12ebca9c":"get_admin_list()","12ecaa62":"freezeAccountOf(address)","12ef900b":"getMaxLoanAmountAllowedByLtd()","12ef934b":"nCryptClubShare(address,address,address,address)","12efe5ad":"minDonationInWei()","12effc32":"rejectTransfer(uint256)","12f05418":"campaignCanceled()","12f0f9df":"createBountyContract(address)","12f11ed3":"getDenyPremium(bytes32)","12f20e2a":"withdrawFundsToOwner(uint256)","12f26140":"setWhitelistContract(address)","12f2b838":"updateReservedWei()","12f31b5f":"firstTeamWithdrawal()","12f3d1e0":"discoverResources(uint256)","12f4cbd9":"Vote(uint8)","12f53950":"refunded()","12f58b43":"RATE_CHANGE_THRESHOLD()","12f62bd6":"updateProperties(uint256,bytes)","12f63d96":"lockedByUser(address,address)","12f6e641":"okamiMaxPurchase_()","12f7cf74":"approve(address,uint8,uint8)","12f7fb6f":"RocketCoins()","12f8ae31":"getRedeemEst(address,uint256)","12f8b3db":"createCrowdsale(uint256,uint256,uint256,uint256,address,address,address,address)","12f95b16":"GIC()","12fa6feb":"ended()","12fa769f":"paidAmount()","12fb5b67":"purchaseTokensInICO(uint256,address)","12fc41a1":"MyScheme()","12fc848e":"_randomLucyAddr()","12fca967":"contract6function2()","12fd67ba":"getValidations()","12fdf767":"FuseaNetwork()","12ff2ad9":"Consent(address,address)","12ff658f":"DmitryCoin()","12ffb59b":"checkIcoStatus()","12ffe4df":"_decreaseApprovalAllArgs(address,uint256,address)","130067ca":"updateCostContract(address)","1300a6d1":"timeLeft()","1300cc41":"freezeTransferToken()","13012a3b":"doMap(address,string)","13019a5e":"EtherTool()","1301b876":"EmbiggenToken(uint256,uint256,string,string,uint8)","1301c4aa":"CryptoniumCoin()","1301ee02":"transferringETC(address)","1302188c":"getLastDataHash()","13028f44":"addUserRewardPayouts(address,address,uint256)","1302d03a":"setWhitelist(address,uint256)","130346d2":"icostart()","13037d22":"xioniCoin()","1303a484":"commitment()","13040bc1":"tokensFinalized()","13045155":"MONTHLY_INTERNAL_VAULT_CAP()","130497ac":"getCountryList()","1305413e":"BetMade()","1305d2de":"changeAllCosigners2(uint256,address[],bytes,bytes,bytes,bytes)","13063180":"doEscape(uint32)","13065fed":"MoneroClassic()","130766c5":"enterLarge()","1307d2d7":"EARLY_CONTRIBUTOR_STAKE()","1308c324":"setAddrForPrivilege(address)","1308e82d":"L19_PALToken()","1308e9e0":"startSweepStake()","130985f4":"GetcrowdsaleContract()","1309a563":"IsPaused()","1309d3bd":"RAVI_ALLOCATION()","130a39b1":"removePersonalTokenLock(address)","130bcaa2":"removePersonalLockMultiple(address[])","130c0e88":"advisoryVUPDestination()","130d04d0":"companyHolding2y()","130d7906":"register(uint32)","130d993d":"lifeFactor_iii()","130e54a1":"prizeshow(address)","130fbba4":"setPixelToken(uint24,uint256,uint24)","13110199":"twentyEndTime()","13110874":"preSaleFirstEtherCap()","1311457c":"transferToken(address[],address,address,uint256)","13114a9d":"totalFees()","1311b45e":"setGasForCMT(uint256)","1311c860":"KCoin()","131284c8":"FUNDING_START_TIMESTAMP()","13137731":"testThrowsUpdateLatestRevisionNotUpdatable()","1313c739":"getBidForAuctionByIdx(uint256,uint256)","1313f631":"Register(bytes4,bytes32,bytes32[8])","1314e272":"addAddressesToOperators(address[])","13151981":"to()","13155455":"legacyToken()","13163d53":"CTO_Signature()","13169ab7":"rewardManual(address,uint256)","131719e1":"testtop()","13174093":"bountyAccount()","13175b40":"_emitUserCreated(address,address,address,address,uint8[],uint256,uint256[],uint256[])","13178704":"ContributeToPool()","1317b559":"buyshares()","1318b88c":"GetPlayer_FromID(uint32,uint8)","1318cd2d":"NameInt()","13193936":"GEMERAToken(address[50])","13194658":"MossCoin(uint256)","131a0680":"store(string)","131ad146":"getWorksStatus(bytes32)","131b0563":"EITARD()","131b81ad":"transferExecutorOwnership(address)","131b9c04":"getEarnings(address)","131bb0d6":"ethCostTotal()","131be36c":"preICOregulations()","131c4305":"SoundcoinsAddress()","131d2873":"isContractFrozen()","131de517":"getKeyBlockNr(uint256)","131e03ba":"withdrawOtherEDEX(address)","131e1816":"setRetiro(address)","131fa183":"createBoard(address)","132002fc":"votingDuration()","1320f614":"callServer(string,uint256)","1320f838":"modify_ICOStartDate(uint256)","1321d291":"enact_liquidation_greater_equal(address,uint256,uint256)","1321ea19":"mulTransfer(uint256,address[])","13220305":"doTransferOther(address,address,address,uint256)","13222d0a":"payoutsETH(address)","1322311b":"LoanBit()","13224fc5":"missingTokensFallback()","1322e9d0":"checkPayoutReadyState()","13233cd9":"appointAgent(address)","13242733":"getRoundOfSixteenTeams(uint256)","1325c502":"debugSetNow(uint256)","13270bb8":"authorizedCount()","1327290d":"isAddressActivated(address)","1327487f":"activation(uint256,address)","1327d383":"hybridizations(uint256)","1327d3d8":"setValidator(address)","1327fbe5":"getPanda(uint256)","1328ec9b":"getAvatar(uint256)","1328fd8f":"getDetails(string)","13299604":"getWallet()","132ac1dd":"itemsForSaleCount()","132ae5e9":"numInvestors()","132c3bea":"setContractPrice(uint256)","132c8641":"given()","132d05e5":"_distributeJackpot()","132df661":"isPrePreSale()","132e4f3c":"fail(uint256)","132e63ba":"PRICE_8()","132e8bee":"batchWithdraw(uint16[])","132ff514":"SQUAD_SIZE()","133086a5":"SphereTokenFactory()","1330a21f":"calulateRate()","1332143c":"getGoldTransactionsCount(string)","133252a6":"grantToken(uint256,address)","13326f43":"transferTokenToSender(address,uint256)","1332dd07":"_isFreezeList()","13331391":"buyPreIco()","133323c8":"setLevToken(address)","13332c6c":"myVoteFactory()","133369c6":"GetRigData(uint256)","1334a5e2":"eventCallback(uint8,address,address,uint256)","13352334":"payOwners()","1335461c":"joinGameWithBalance(uint256,address)","13357914":"from(uint256)","1335b56b":"GasSell()","1335b598":"get_ptc_count(address)","1335ff36":"createEventAndMarketMaker(uint256,uint256,uint8,uint32,address,uint256,uint8,uint16,uint256)","1336a756":"previousPeriodRate()","1336cff6":"isAccountFreeze(address)","13373786":"powerBalanceOf(address)","1337d6ed":"sendFlower(address,bytes32,string,bytes16,uint256)","13381fbf":"registrantsPaid(address)","1338c9e9":"SspStandardToken(uint256,string,uint8,string)","1338f493":"isClose()","13390cf2":"VASTToken(uint256,string,string)","133922ad":"setCompanyURI(string)","13392662":"totalTokensOfThisContract()","1339305f":"createRandomZombie_FreeZombie()","1339870e":"GetOrderBookScreen(address,uint256)","13399d10":"INCRYPT(uint256,string,string)","1339cba2":"getRemainingDaysToSecondPhase()","133a473e":"sleep()","133ae30b":"transferFunds(uint256)","133af8b3":"getIcoTokenHoldersAddressesCount()","133b5ba9":"honestisFort()","133c5ff5":"getAdminAccounts()","133cbe3a":"setLatestToNow(address)","133d10e6":"HPCToken()","133d27e1":"partner1_address()","133d2afe":"myfast(address,uint256)","133d5d4e":"setMultisignWallet(address)","133d8555":"withdrawTokenFromElc(address,uint256)","133e3f71":"getOld_BalanceOfr(address)","133f44dc":"removeVerifiedInvestor(address)","133f50f5":"checkUserExists(address)","133f6ac0":"earlyExchangeRate()","133f8a2f":"getStockReleaseTime(address,uint256)","133fe629":"calculateCuts(uint256,uint256)","134000c0":"getGrid()","134087a2":"gameLogic()","1340d09a":"isPoint(uint256,uint256)","13413858":"isFreelancerAvailable(address,address)","13414a4e":"doDisputeMemoryWrite(uint256,bytes32,uint256)","13419be3":"LifeFactor_v()","1341b33c":"releasableViewOrSend(address,bool)","13424bf0":"unpause_4()","13426d87":"addEmitter(bytes4,address)","13429e31":"newPrice(uint256,uint256)","1342c0e8":"VZT_WALLET()","1343a35f":"sendLoan(address,uint256)","1343ed05":"isStoreSet(string)","134538f3":"testRemoveGains()","134562a6":"SimpleToken(uint256)","13463751":"ThroneClaimedEvent(uint256)","13468929":"signedApproveCheck(address,address,address,uint256,uint256,uint256,bytes,address)","1346c20e":"canBuy(address,uint256)","134741f7":"SimpleERC20Token(uint256)","1347b972":"setICOWeek2Bonus(uint256)","1347b9ae":"CommonToken(address)","1348ab3a":"setRequiredTotal(uint256)","1348fdcc":"changeStarttime(uint256)","1349c273":"ClearExpiredFreezingEvent(address)","1349f5ec":"_provideChars(address,address,uint32)","134a04ea":"breedingDB()","134a5330":"updateTokenPrice(int128)","134abf66":"sendVesting(uint256)","134b684f":"SafeGiftTokens(uint256,string,string)","134c021b":"divForTransfer()","134c1a28":"L2Cash(address,address)","134c91be":"setFile(string,string,uint256,string,string)","134ccdfb":"IBIZACASH()","134dc5ad":"setManagerAddress(address,address)","134e3917":"setM2(address)","134f1893":"goWiner()","134fd7d0":"_convertToWei(uint256)","134ff97e":"startGame(uint32,bytes32)","1350a997":"AccessGrant(address)","1350acbd":"PRESALE_MAX_ETH()","135128c2":"CounterPartyDeposit()","13517fea":"maxCost()","1351cf51":"setAuthorizedAddress(address,bool)","135217e7":"requires_depth()","1352faec":"setReleaseDate(uint256)","1353e7b3":"purchaseMetal(uint256,uint256)","1356c5dd":"raceBet(uint8)","13574cd2":"calculateKnowledgeBuy(uint256,uint256)","1357b862":"contractSolidStamp()","1357e1dc":"totalPaidOut()","13582b6e":"HIDDEN_CAP()","135859c0":"distributeICOTokens(address,uint256)","135892bf":"FundUpdated(address)","1358937f":"TEAM_HOLDER()","13590153":"ManualChangeEndDate(uint256,uint256)","1359844a":"winNetworkFeeBasisPoints()","13598b71":"LightningEthereum()","1359cb2c":"getCommissionWithdrawn(uint32)","1359fc91":"setPublicKey(bytes32,bytes32,bytes32,bytes32)","135a2474":"joysoWallet()","135bada6":"setDungeonStatus(uint256,uint256)","135bf431":"gamerun()","135c0701":"purgeAccount(address)","135da3c2":"getBal(bytes32,address)","135da767":"LennartCoin()","135e9ad6":"fulFillTX(uint256)","135ec4bd":"AddAppraise(address,string)","135ed7bd":"priceRound1()","135f01df":"addDocument(bytes16,bytes32,uint8,bytes32,bytes32)","135fae64":"getOwnerProprietaryData(uint256)","135fc676":"loseHandler(address,uint8)","13601234":"checkRejectionRatio()","136047ab":"ticketTransferers(address,uint256)","13612119":"distribToken(address)","136125a7":"GoldFiatFee(string)","13618756":"readnationnameXteam()","1362180e":"setItemName(uint256,bytes32)","13622274":"prealocateCoins()","1362dd32":"testinx()","1364326c":"countVotes(uint256,uint256)","13643605":"crowdsaleTarget()","136439dd":"pause(uint256)","13651124":"WithdrawAmountFromBankAccount(uint256)","136512c9":"_checkPixelRight(uint256)","13653b24":"RECFToken(uint256)","1365e6a3":"REBELCOINSupply()","1366b970":"test_transfer_token_to_contract()","1367641e":"releaseAdvisorTokens()","1367944b":"getIdByName(string)","13683532":"getAccountCap(uint256)","1369f6fd":"getCurrentOwnerBallence()","136aa762":"Remmittance(uint256,uint256)","136ac4bf":"WillTestament()","136af582":"next(bytes,bytes,bytes,bytes,bytes,bytes,bytes)","136b4fea":"getActiveFish(uint256,uint256)","136bcbab":"Windlord()","136c545c":"transferToProjectWallet()","136c8744":"WBSToken()","136cf5c1":"deleteVestingFromStorage(address)","136d1057":"accountBalanceCount()","136d5a59":"giveKudos(bytes32,uint256)","136d6a39":"getBalanceByAddress(address)","136dbbab":"revenueFraction()","136e1949":"buyFunderSmartToken(string,string)","136e1c45":"suspendGame()","136ede68":"verifyCopieExecutoire(bytes32)","136ef18a":"allowTransfers(address[])","136f1016":"hasBet(address)","136f5b5a":"ordersCanMatch_(address[14],uint256[14],uint8[6],bytes,bytes,bytes,bytes,bytes,bytes)","136fa2d7":"rateSeedStage()","1370128e":"free()","13711a31":"presale_allocation()","13714545":"GATEL()","137157c0":"changeBlock(bool)","1371dab9":"whitelisters(address)","13730838":"getCanvasPainters(uint32)","13734a9f":"setClaimDividendPercentage(uint256)","13737db2":"TiValueToken()","13740cf3":"isTrigger()","13748a40":"Withdraw_2()","1374b22d":"proposalExists(uint256)","1374eb6f":"getLockByIndex(address,uint256)","1375111e":"returnrandom()","13754f9a":"notUpgradableInStore()","13765838":"deposit(uint64)","13767204":"AirDropRedeemAFTK()","1376f2ce":"setCrowdsaleStartDate(uint32)","137759df":"ammendReceivedLand(uint256,uint256)","13776ba1":"buyPLATCards(address,uint256,uint256,uint256)","1377900b":"PreICODayOneCents()","1377ae65":"_getEarnings(address,address,uint256,uint256,uint256)","13788651":"test_oneValidEqBytesNoLog()","137935d5":"totalGuaranteedCollected()","1379c6e0":"getICOEndDate()","137a1464":"ifEmergencyStop()","137a3fa7":"transferPayment(uint256,address)","137b3bcd":"getBounsByAmount(uint256,uint256)","137b763d":"SetReferrer(address,address)","137b8721":"getTierWhitelist(address,bytes32,uint256)","137baa2a":"BigToken()","137c1feb":"buyCommonTTMByETH(uint256,address)","137c638b":"getExtraGas()","137ce088":"TokenReserveMinted(uint256)","137ce8e3":"HARD_CAP_USD()","137d7026":"abiEncode(bytes,bytes,address[])","137db23c":"updateWhitelist(address,address,bool)","137e37d9":"accountGet(address)","13801995":"getHopefulId(address)","13819313":"OTTToken()","1381e400":"cancel(uint32)","13823365":"setOneTokenInWei(uint256)","13827950":"getShareholderDB()","1382a652":"isTrustedShop(address)","1382e75e":"addUser(uint256,string,string,uint256)","13831693":"getLevitatingUnicorns(bytes32,uint64)","13844e60":"totalOVCSold()","13845d2f":"creation()","138495de":"SimpleToken(string,string,uint256,uint256)","1384dc12":"endTx(uint256,uint256,uint256)","1385053e":"FlyCareTokenSale(address,uint256,uint256,uint256,uint256,uint256,uint256,address,uint64[5])","1385625d":"MintTimelocked(address,uint256)","13857c1a":"foundersFundMultiplier()","13859f46":"_metadata(uint256)","1385d24c":"toggleContractActive()","138665ff":"testJoin()","13869333":"RealityCheck()","1386a244":"getSettingAddress(string)","1386dc2d":"orgName()","138716e8":"root_domain()","13872f8d":"test_againstFor()","13877deb":"FBLFund()","1387c80b":"test_invalidRuleChange()","1388483d":"BLING()","13887592":"multilocked()","13888565":"surplus()","138a7084":"_4_owner()","138a886e":"testGetTransactionDetails(bytes)","138acb80":"View_MediatedTransaction_Info(uint256)","138b3ab1":"numPlots()","138b806c":"addMultipleAddresseseToWhitelist(address[])","138bdf1b":"simpleTest(address)","138cc941":"testErrorTransferToRejectAuthority()","138e2317":"IcoTokenMock(address)","138e8da1":"getIncreaseAllowancePreSignedHash(address,address,uint256,uint256,uint256)","138efd00":"_createTot(string,address,uint256)","139020d1":"deedByIndex(uint256)","13902e9f":"initBonusPeriod(uint256,uint256,uint256,uint256)","13905905":"addWhiteListedAddressesInBatch(address[])","13907d22":"abrirDoacoes()","1390b247":"getNbSellOrder()","1390df6c":"oldXPAAssets()","1391697d":"weiRound1()","13916c2e":"bidOnCraftAuction(uint256,uint256)","1391c5f8":"EnddateICO()","1391ff43":"fetchVoteInfoForVoter(address)","1392c495":"updateItemPrice(bytes32,uint256)","13930cf6":"setCurrentVersion(string)","13932337":"highTimeBonusLimit()","13943033":"RBOC()","1394f216":"addProjectManager(address)","139654e0":"window2StartTime()","13966db5":"mintFee()","1397d7ae":"setPI_edit_24(string)","1397fdbd":"getShares(address,bytes,int256[])","139818a1":"setFrozen(address,uint256)","1398bbf7":"getRanking()","1398e076":"lotteries(uint256)","139949fa":"sAssert(bool)","1399cc5b":"UWC()","139a667a":"_calcNextPrice(uint256)","139b3752":"_batch1_rate()","139c7048":"generateTokenAmount(uint256)","139ccd1e":"stopCollectSignatures()","139cd9d3":"drawnTokens(address,uint256,uint256)","139ddefe":"ProposeProposal(bytes32,bytes32,uint256,uint256,uint256)","139df200":"getAllMarketsInfo()","139e23b5":"getDividendInfo()","139f1838":"NoBonustimer()","13a070b7":"add_admin(address)","13a0c990":"BearTrap()","13a110b4":"getMin(uint64[])","13a19e1b":"initialCoach(uint256,uint256,uint8,uint256)","13a1da40":"tgrSettingsMinimalContribution()","13a22af9":"latest_buy_time()","13a24744":"BurnupGameAccessControl()","13a2852d":"setICOEndTime(uint256)","13a30010":"refund2(address)","13a396d8":"getRequiredDeposit(bytes)","13a3d9a1":"registerDocument(string,string,string)","13a460b7":"tourisToken()","13a46425":"getNumberOfDisputedStepsProDoctor()","13a46827":"fund(address,address,uint256,uint256,uint256)","13a4b3bc":"OwnershipRequested(address,address)","13a4fd37":"soldTokensIco()","13a517bf":"eighthTeamWithdrawal()","13a5aac7":"paymentRegularTokensPriority(uint256,uint256)","13a5d9e4":"remaingNTRY()","13a666a6":"hasReachedSoftCap()","13a7070f":"withdrawDeveloperCut()","13a8a080":"TokenDemo(uint256,address,address,address,address)","13a91cc8":"getVlsTokenAddress()","13a927c7":"toggleMatchStartEnd(uint256,uint256)","13a92f02":"frozenAccountForLogic(address)","13a931dc":"gasForOraclizedQuery()","13a9589c":"getSalt()","13a9cd8d":"lastDETCWC()","13aa48bf":"minePepe(uint256,address)","13aa7b6f":"viewUnclaimedDepositDividends()","13abdd75":"ecosystemSupply()","13ac2bdb":"addNetworkMember(address,bool,bool,bool,bytes32)","13ac58bb":"increaseCredits(string,uint256,uint8,address)","13acb45b":"calcDoubleBindedBlindHash3(string,address,address)","13ad41d8":"getSkill(uint32)","13ad9ce1":"getRepMarketCapInAttoeth()","13adc129":"MIGG()","13ae4522":"token3MstepCAP()","13ae457d":"mainCapInUSD()","13af4035":"setOwner(address)","13afa97a":"readMarketplaceConfigs()","13b15b24":"setRoundGap(uint256)","13b18640":"participate(uint256,address)","13b222ba":"getMyPoohs()","13b2663b":"cash_received(string)","13b2807e":"setCampaignEndPointById(bytes32,string,int256)","13b2e657":"unfreezeAccount(uint256)","13b37a83":"getRandomUuid()","13b39b9c":"approveMint(address,uint256)","13b3cd91":"collectForREQBurning(uint256)","13b3cdf6":"ownersLUT(uint256)","13b3fffc":"updateChannelManagerContract(address,string)","13b4312f":"transferCollectedFees(string,address,uint256,bytes)","13b499ce":"PRE_ICO_TIER_FIRST()","13b53153":"isFunding()","13b57686":"self_last_result()","13b5a19e":"GBPsToken()","13b5d420":"returnWebsiteData()","13b63f60":"updateBuildingPrivacy(uint256,bool)","13b6c8a8":"setListingFeeInWei(uint256)","13b6f213":"ContributionReceived(address,uint256,uint256,uint256)","13b7423a":"setFundraiserCallData(string)","13b796f4":"getMilestoneTimeAndRate(uint256)","13b84004":"gameTokenAmount(address)","13b96a9e":"numOfSamples()","13ba350a":"Whales_group()","13bac8f2":"updateStorage(string,string)","13baf1e6":"removeToken(address,uint256)","13bb7b0d":"PreICO(address,uint256,address)","13bbae9b":"addProxyManager(address)","13bc33ca":"CryptonHotels()","13bc4bda":"operatorSendTo(address,address,uint256,bytes,bytes)","13bd05e4":"silo_addr()","13bd4e2c":"_prepareAndSendReward()","13bd53e6":"applySettings(uint8,uint256,uint256,uint256,uint256)","13bd9e3c":"fundFoundation()","13bdbb19":"getCustomer(address,address)","13bdfacd":"print()","13be31ae":"preSaleDeposit()","13bfabf0":"isCurrentOrPastAccountReader(address)","13bfcd2c":"growthContract()","13c03159":"payPlayers(uint256,uint256)","13c04769":"submitBallot(bytes32,bytes32)","13c10e44":"attackerExpAdjustment()","13c13d6b":"updateMarketContract(address)","13c1629c":"_getBlockIndexAtYear(uint256,uint256,uint256)","13c1e906":"RentaCoin()","13c25ba6":"subtr(uint256,uint256)","13c2beff":"processWithdrawalForAccount(address)","13c32148":"_computeFee(uint256)","13c3922f":"Aborted(address)","13c42ca1":"getPrice(bytes1)","13c4f953":"getTime(address,address)","13c52111":"amountOfTokens()","13c58cbb":"countNoClients()","13c667d1":"calculateAmountBoughtICO(uint256,uint256)","13c68344":"Verto()","13c709d4":"transferToGame(address,address)","13c7db1a":"limitOfBranch()","13c82b0b":"setIsForkingMarketFinalized(bool)","13c89a8f":"getAllowedTime(bytes32)","13c8a376":"recovered(uint256)","13c8e60d":"getCurrentDebt(uint256)","13c9134b":"setcoinfee(uint256)","13ca1464":"getDHandRank(uint32)","13ca18ac":"WatermelonBlockToken(address,address,address)","13ca43a0":"teamWallet1()","13cc22ea":"createController(address)","13ccca96":"limitbreak_RELEASE()","13cceb21":"getHolderWithdrawIndex()","13cd528a":"miadd(uint64,uint64)","13ce15a9":"left67(uint256)","13ce401b":"getPlayerRecommond(address)","13ceb89b":"getCopaMarketAddress()","13cfed7f":"deposits_until_jackpot()","13d033c0":"cliff()","13d073d0":"Sign(uint256,address,uint256,uint8,uint256,string)","13d19950":"stringsEqual(string,string)","13d1aa2e":"f(uint256,uint256)","13d1bdfb":"priceForMateAdvertisement()","13d40e71":"RefundableCrowdsaleImpl(uint256,uint256,uint256,address,uint256)","13d4bc24":"buyTokenProxy(address)","13d4c63a":"_purchaseWhaleCard()","13d53ca9":"check(bytes32,uint256,uint256,uint256)","13d5469d":"periodICOStage7()","13d557bc":"operatorRedeemByPartition(bytes32,address,uint256,bytes,bytes)","13d567ca":"isApprovedTAAddress(address)","13d59ca9":"upgradeAddr()","13d5d4fe":"test_insert_findWithHintNextRemoved()","13d5ee74":"accPartner()","13d5f1fe":"durationOfStatusSell()","13d65cd9":"test_34_assertGasUsage700Boards()","13d73a08":"AMOUNTWAGERED()","13d769de":"auctionCreated(uint256,uint256,uint256)","13d8867c":"mint(string,uint256,string,uint8,string)","13d8c840":"tail()","13d9028b":"Remain_burn(uint256)","13dc01bb":"BKBK()","13dce04f":"updateRoutingPreference(string,string)","13dcfa08":"AmountClaimed(address,uint256)","13ddb69a":"CROWDSALE_START()","13ddd3ae":"getTokePerWei()","13ddecd5":"withdrawICOReserve()","13de214e":"minimalSuccessUSDWEI()","13debf7c":"_getPersonalAirdropAmount(address,address)","13defbd9":"getMyCrabs()","13df20fd":"createTimeBasedVesting(address,uint256)","13df35d1":"publicTGEStartBlockTimeStamp()","13df7091":"mintAll(int256)","13e003dd":"ASStoken(string,string,uint8,uint256,uint256)","13e0e70d":"ownerRegistry(address)","13e1d1d2":"multiCancelVoteForCandidate(address[],uint256[])","13e1f2b0":"DATToken(address)","13e26d58":"minRequired()","13e2cae1":"revealBid(bytes32,address,uint256,address,bytes32,bytes32,uint256,uint256)","13e2dfc1":"depositDividend(uint256)","13e3151b":"MyEPPToken()","13e33fb6":"calculateBonus(uint96)","13e41971":"setup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","13e468b3":"getVotingToChangeProxy()","13e4b51f":"putHash()","13e50ca4":"totalFiatValue()","13e5a3b1":"SetUp(uint256,address)","13e5d8b6":"icoStartsAt()","13e5e26e":"recirculateLateFees(uint256)","13e60074":"OwnerRetireHodl(uint256)","13e7323e":"fundingEnd()","13e75206":"getParentOf(uint256)","13e7a234":"getAccessor(bytes32,uint256)","13e7d076":"STERNIUMHUGEELLIGENCECOIN()","13e81119":"purchaseTicketsWithReferral(uint256[],uint256)","13e8360d":"commissionerAuctionComplete(uint32,uint128)","13e8e5d2":"address2a()","13e8e74b":"IexecHub()","13e8fdea":"TxExecuted(uint32)","13ecfbfa":"lastBuyer()","13ed0846":"calculateReward(uint256,uint256)","13ed5f31":"getTransactionConfirmerInfo(uint256,address,address)","13ee4bc5":"pay(bytes32,address[],uint256[])","13f06abc":"balanceFrozenTokens(address)","13f0790c":"tokensSoldWithBonus()","13f07f6f":"Object()","13f0ec1f":"withdrawDekla(uint256,bytes)","13f20d76":"fundDigitalMarket()","13f233c2":"ethReceiveMainSale()","13f25eb6":"NinjaToken(address,address)","13f29768":"addUnsoldAllocationOrder(bytes32)","13f4318e":"SetSubscriptionTo(address,int256)","13f44d10":"isAddressWhitelisted(address)","13f46d3e":"SponBToken(address,uint256)","13f47f24":"lockedDelegatingTokens(address)","13f4b42c":"pixelsPerCell()","13f4c7a5":"INVESTOR_LOCK_DURATION()","13f4e977":"minimumFundingGoal()","13f52533":"capitalLedger()","13f56f73":"changeMinInvestment(uint256)","13f5ef00":"Main(string,bytes)","13f652fe":"getText(string)","13f6ee53":"cliffAdvisorsTokens()","13f73570":"manualyAddReferralPayer(address,address,uint256)","13f94a43":"getSiteTokenIds(uint256)","13f9cf76":"disableBundlingMultitoken(uint256)","13fa095f":"setDestinationWallet(address)","13fac256":"xem()","13faede6":"cost()","13fb2324":"EndEvent()","13fc5ace":"depositForMySelf(uint256)","13fc6ac2":"getEventData(bytes32)","13fcaf54":"getDepositCount(address)","13fdcbec":"developer_Coin_Character(string)","13fdd2b4":"TilexSupply()","13ff962a":"privatesaleSupply()","13ffdbfc":"gameCountOf(address)","13fff718":"doBet()","14001f4c":"setSiringAuctionAddress(address)","14004ef3":"multimint(address[],uint256[])","14007c6d":"nextState()","1400d1e4":"checkName(string)","14012549":"isMainSaleTime()","14025dcd":"cancelFee()","14029756":"setaddress(address)","1402c310":"NEWSOKUCOIN()","1402f031":"triggerAttackManually(uint32)","1402f80d":"selectTemplate(uint8)","1403041b":"PegasusToken()","14036f62":"Vboom()","1403835f":"_isExpired(uint256)","140420a9":"isRateValid(uint256)","140575af":"LogTokenPriceChange(uint256,string)","140604cc":"getInitialState(uint256)","14061862":"setIcoMin(uint256)","14069b12":"MXMPDMToken()","1406b921":"vent()","1406d3be":"lowestGameWithoutQuorum()","14074135":"dividendsRightsOf(address)","140758a9":"disableServiceProvider(address,bytes)","1408073e":"GangnamToken()","14081570":"addEpisode(string,uint256)","14081e39":"setEscrowFee(uint256)","14082cd2":"findProductById(uint256)","1409b88f":"getManualByAddress(address)","140a681a":"_getVersion()","140a7ac6":"getFinalScore(int256[])","140ad293":"spitnetwork()","140aee46":"_0xDogecoinToken()","140b1706":"maxHLPMTMarkup()","140b2cdd":"calculateMyRewardDecreased(uint256,uint256)","140b4465":"executeSpendingRequests()","140cc562":"isCollectSignatureCorrect(address,address,uint256,bytes32,bytes32,uint8)","140cd7af":"issueToken(address,address,uint256,uint256,uint256)","140d3e95":"changeFiatFeeContract(address)","140da6b7":"getAddressField1()","140dcec4":"right23(uint256)","140f64b4":"GoyanToken()","140f7f8d":"Staged()","14102159":"presaleLimit(address)","14106b49":"JustifyClaim(address)","14107f3c":"buy(uint8)","14111a43":"isValidService(bytes32)","1411539d":"multiSend(address[],uint256[],address[])","14116c3c":"SetPeriodPreITO_startTime(uint256)","14117228":"getNoteKeyByIndex(uint256)","1411d713":"licenseIssuedTime(uint256)","1412409a":"whitelistSetterAddress()","14127f13":"setOrderFill_(bytes32,uint256)","141283f1":"setNewWallets(address,address)","14131611":"setChibiForFusion(uint256,uint256)","14133a7c":"setSaleAgent(address)","14139904":"directorB()","14143c91":"TotalSpecialFeeTakes()","1414a506":"falangiToken()","1414ef78":"createInvoice(uint256)","14162e8d":"IouRootsReservationToken(string,string,uint8)","14163a83":"setCrowdsaleContractAddress(address)","14167bf0":"oraclize_query(string,string[])","14174f33":"withDraw(uint256)","14177dbf":"setLockTokensAddress(address)","14179865":"logos(uint256)","1417b946":"adminOwner()","1417c845":"Mortal()","14189a7e":"outstandingValue()","141926fa":"updateAccount(string)","14193456":"MainSaleEnd(uint256)","141961bc":"campaigns(uint256)","1419c3f3":"grand_factory()","141a8dd8":"approver()","141bd92a":"getBallotInfo(uint256)","141c4306":"AbroToken()","141c4e60":"challenge(uint256,address)","141c9422":"listingDate()","141ca2c7":"reservedIcoCrowdsale()","141d717b":"OC()","141dbe66":"distributeBTCB(uint256,address[])","141e26a5":"setEditionMaxSales(uint8,uint256)","141edaa1":"manufacture(address,address,address)","141f211c":"snapshotStakeAmount(uint256,address,address)","141f6800":"fundingMinimumTargetInUsd()","141fd3cf":"channelResultTimeout(uint64)","14204ca9":"QZG001TOKEN()","1420765a":"isBuyLocked(address)","14211803":"hasBuyTotal()","14219ff9":"sq(uint64)","1421c1a4":"vote_for_candidate_C_for_free()","14225b9b":"token_ratio1()","1423113a":"fluxFeed(uint256,bool,bool)","142359f4":"fillOrder(bytes32[],bytes32[])","1423649b":"cofounderApproveSwitchRequest(address,bytes32)","1423c40e":"setBudgetOfCampaign(bytes32,uint256)","1424c182":"recordDeposit(uint256)","14253887":"certify(address)","1425d2fa":"getBalanceToken()","14263f0c":"Dadice()","1427407f":"NINECOINTOKEN()","142769aa":"requestNumber(address,uint256,uint8)","14279086":"getIndividualCount(uint32)","1427f168":"log2Bounds(uint256)","14280bb8":"getBodyColorValue(uint256)","14287a07":"playerPrizeClaim()","1429a36b":"getOrCreateFeeWindowByMarketEndTime(uint256)","1429e26c":"User()","142b353d":"MultiTransferETH(address[],uint256[])","142bc2ae":"latestData()","142d239a":"canPurchaseAmount(address,uint256)","142dc95d":"testAmount(uint256)","142e0bdf":"LogAllocate(address,uint256,uint256)","142e133f":"totalBalanceDown()","142e8e25":"setAdmin(uint256,address)","142e9ab8":"setTrade(bool)","142e9bc9":"weaponToOwner(uint256)","142f328e":"fundDao()","142f53c2":"sendInitialTokens(address)","143085c3":"updateRankBoard(uint256,uint256)","1430990a":"bidTransfer(uint256,address,uint256)","1431b23a":"getData(bytes)","143211ec":"newDaoRulesProposal(uint256,uint256,uint256,uint256,uint256,bool,uint256)","14325458":"calculateTokensFrom(uint256,uint256)","1432621a":"getPeakSupply()","14332c93":"SetConfirmRound(uint32,uint8,bool)","14350c24":"changeMinimumMakerProtocolFee(uint256)","143551e4":"timeExtension()","143580d0":"PGDA()","14359466":"NBTV()","1435e397":"setAllocation(address,uint256,uint8)","14361fd1":"singleWithdrawMin()","14363e65":"setPeriod(uint256[])","14367652":"revealStageActive(uint256)","1436fb39":"_isVotingAddress(address)","14371c33":"someMethod5(uint256,uint256,uint256)","14373817":"rateSoft()","1437f9a3":"Set_your_game_number(uint16)","143a1a2f":"pilfer(uint256)","143bb3e6":"StartRollDice(uint32)","143c56cf":"disprove()","143c6d4f":"TokenTransferTo(address,uint256)","143c7a3f":"OPAY()","143e55e0":"era()","143e6209":"setImagePartsCount(uint256,uint16)","143f68c9":"getRedemptionBalance()","143f9d1f":"week4Price()","143fb46d":"setRemainingTokensWallet(address)","143fcbbe":"cancelBooking(string,uint256[],uint256,bytes32,bool)","14404eb2":"roundOver()","144052b6":"C4coin()","1440f2bf":"PRE_SALE_PERCENT()","144136a1":"restartCrowdsale()","144138c8":"removeGlobalConstraintPre(address,int256,address)","1441a5a9":"referral()","1441c288":"showUnpaidInterest(address)","14423381":"GameConfig()","144267e0":"refundSecurity(address,uint256,uint256)","1442b548":"ZTST()","14432f6e":"Received(address,address,uint256,uint256)","144344b9":"setEth(uint256)","14442f54":"VERSION_NAME()","14447e11":"checkGamesReadyForSpinning()","14449c92":"finishRoundB()","14459309":"price_constant2()","1445c6da":"increasePosition(bytes32,address[7],uint256[8],uint32[2],bool,bytes,bytes)","1445f713":"hexstrToBytes(string)","14462b93":"findWhichCTD(address)","14468d32":"nextBidExpireBlockLength()","1447431e":"setCCH_edit_24(string)","1448b3ca":"tokenSaleAddress()","1449757d":"annulCertificate(address,address)","1449c321":"view_get_gameStates()","1449c6dd":"Staked(address,uint256,uint256)","144a2752":"getBuyAmount(address,address,uint256)","144a3260":"createWithDeposit(address,address,uint256)","144a3472":"inMaintenance()","144a88a0":"updatePlayerPoint(uint32,uint32,uint32,uint32,int256)","144b2a82":"transferICO(address,uint256)","144be7eb":"totalNumberOfCards()","144c7e40":"CRYPTOKEN(uint256,string,uint8,string)","144cbdfd":"NobeToken()","144f2f94":"_burn()","144fa6d7":"setToken(address)","145000ab":"PRICE_2()","14525b6b":"auctionFee()","14525bce":"INITIAL_BALANCE()","14526f8c":"Buy(string,address,uint256,uint256)","14534ad0":"LogCertifierAdded(address)","14534ba7":"ballotEncryptionPubkey()","1453671d":"changeWithdrawAddress(address)","1453bfb3":"visitingUnicorns()","1453d756":"bytes64ToString(bytes32,bytes32)","145538ea":"phase1StartBlock()","145671aa":"getValidations(address,bytes32)","14567b8b":"setSelfAsContributor(string)","1456974f":"setNameReaderId(address,bytes32,bytes32)","1456979f":"setNewValidator(address)","14572dff":"incrementUniquenessIndex()","14576a49":"NewSophonToken(address)","14577c55":"accountLevels(address)","14584a9d":"getAuctionIndex(address,address)","1458ffb3":"VREO_SALE_PHASE_1_END_TIME()","1459457a":"initialize(address,address,address,address,address)","1459cef4":"balanceOfMine()","1459ecc4":"lastrecordindex()","145a0adc":"setDataLink(uint256,string)","145a7f92":"social(address)","145af145":"getAllCardsLowestPrice()","145b2ab2":"CocoToken()","145ba84c":"_payAwardOwner(uint256)","145c03f2":"TransferFromCompanyInventory(address,uint256,bytes32)","145ca0b3":"UnLockTokens(address,uint256,string)","145cb459":"showCertificate()","145cf0c2":"decrementTokenIdsLength()","145d82d6":"setKingdomFactoryRP()","145e1944":"buy(bytes,int256)","145e6701":"SteemitFund()","145e818f":"BALVINDER()","145e8f5e":"HVB()","145eb4ee":"HuaTuoToken()","145ee04c":"pendingFeesWithdrawals()","145f3143":"releaseTime1()","145f8ba2":"getPainting(uint256)","145fa890":"setWhiteListDuration(uint256)","145fd87a":"getTotalHashRateOf(address)","145ff9cb":"terminateShortPosition()","146008e3":"grid(uint256,uint256)","14606109":"cap1(address)","14607fc2":"dispute(bool,address)","146091f1":"removeFromAllocationList(address)","1460b505":"setWeights(uint256[])","1460e603":"numDarknodes()","146124f9":"totalDistributedr()","146155bf":"createUserByEmailVerify(bytes32,bytes32,uint256)","14619c7f":"setContractAdmin(address,bool,uint256)","14627834":"GOVERNANCE()","14633039":"VanityToken_v3()","146483f9":"setCreateUnicornPrice(uint256,uint256)","1464bc45":"walletFacebook()","1464f516":"votosTotales()","14653f87":"SHIP(uint256,uint256,uint256)","14656957":"PeculiumToken()","1465aa97":"testingContract()","1466724a":"subUserBattleValue(address,uint256,bool)","14670850":"test_33_assertGasUsage200Boards()","14673d31":"setReserveAddress(address)","146740ee":"bulkAddMake(address[],uint256[],uint256[])","14679957":"GenesMarket()","14686ac2":"puntAmount()","1468d9cb":"Latium()","1468fc26":"changeSharedExpenseAllocation(uint256)","146901db":"setFailed()","14690be7":"TransactionSucceededICAP(bytes32,uint256,string,address)","14697cc8":"claimHalvingsSubsidies(uint256)","14698895":"Certification()","146b4955":"RICHERC20(uint256,string,string)","146b58df":"getInvestment(address)","146bea7b":"nextYear()","146c8710":"addressOf(address,uint256)","146ca531":"round()","146d2148":"setReaderId(address,bytes32,bytes32)","146dd227":"BLTToken()","146dd8e0":"BestEther()","146e3cb5":"getDroidsIds()","146e7eea":"soulsForSale()","146e91b5":"signContract(bytes32,string,bool)","146e9329":"summJenkins()","146ee571":"requestFreeDistribution()","146ef27d":"balancePreSale2()","147035ba":"processPublicPurchase(uint256,address)","14704d91":"getCCH_edit_26()","14709544":"BetCoin()","1470dfa8":"closeWindow(uint8)","1470fc6f":"approveRejectOrg(string,string,string,string,string)","14712e2f":"proxyApprove(address,uint256,bytes32,address)","147180ab":"feesA()","147288fb":"test_insert_findWithHint(int256)","1472d56a":"assertEq1(bytes1,bytes1)","1473248d":"SampleContract()","14743e7e":"activateRound(uint256)","1474b789":"burnXPTokens(address,uint256)","1475e751":"game_token()","1476e40f":"multiCall(address[],uint256[])","1478b6af":"abortUpdate()","1479290e":"removeBouncer(address)","14793058":"createPhoenixes()","14794702":"withdrawWinnings(uint256)","147a5640":"_getAllRevisionIpfsHashes(bytes20)","147aaa8d":"giveTokensTo(address,uint256)","147bfd66":"GuardedBeercoinICO()","147c9f6d":"updateWallets(address,address,address)","147d57b0":"send_bounty_token(address,uint256)","147d959a":"setUSDPrice(uint256)","147da3c9":"newSpaceshipProduct(uint16,bytes2,bytes2,bytes2,bytes2,uint256)","147e14a4":"retrieveTokens(address,address,address)","147e51f4":"freezeTheMoment()","14807045":"flipCapSwitchTo(bool)","148105ab":"addBankroll()","148174cd":"ownerSetCasino(address)","1481c04a":"getTXSValue(uint256)","1481d439":"deleteUserClaimInBulk(address[])","148222cf":"donateSkin(uint128,address)","1482bd40":"bountyBalanceMap(address)","14838617":"DEV_PORTION()","1483fc8c":"addBlockData(uint256,bytes)","14841164":"extraBalanceWallet()","1484abf4":"whitelistApplication(uint256)","1484cd32":"getWinners(uint16,uint8)","1484e9ad":"startICOStage2()","14852606":"setAccompliceBContract(address)","1485ffc4":"finalizeTDE()","14870a57":"setMonthClose(uint256,bool)","14870d2c":"withdrawAllToken()","14887c58":"isEntity(address)","1488f983":"LogFinalized(address)","148ab04e":"balance_in()","148ab078":"MEW_RESERVE_FUND()","148bea6b":"gamblerlist(uint256)","148cd939":"transferBecauseOf(address,uint256,address,uint32,uint256)","148ce4a4":"test_claimShare_isTranscoder()","148d3e7b":"FQCoin()","148da7f6":"disableInvestment()","148dd101":"thirdChangeBlock()","148f2e5e":"sendWei(address)","148fa780":"just10Send()","14900396":"changeRaceOwnership(address,address)","149148e0":"getCityPlanAddres()","1491858e":"calculateSetupAllowedUntil(address[16],uint256)","14918f5e":"performInitialWithdrawal()","14930d7e":"transferResidualBcoupons(address,uint256)","14941e80":"getFreeAmount()","14946a97":"CoreToken(uint256,string,string,uint8)","1494ecfc":"SentosaX()","14950f64":"RevokeAddressChanged(address)","14959741":"UserMessage(address,string)","149607d3":"EtherollToken()","149679b9":"GOE()","1496fc4c":"Telcoin()","14975cc7":"hardCapPrice()","14986f5b":"setCooldowns(uint32[100])","1498970a":"getDeployedblockbytesMarriages()","149947fd":"finding(address,bytes8,uint8[])","1499c592":"setParent(address)","149acf9a":"daoCreator()","149b8690":"supplyInCirculation()","149c5066":"ChanceOfWinning(uint256)","149cc1f6":"_finalizeBet(bytes32,address,uint256,uint256)","149cd0be":"alterCreatePetitionFee(uint256)","149dffc8":"numCancelledRequests()","149e6788":"heroClasses(uint32)","149e685a":"getFundById(uint256)","149eead5":"master_contract()","149f2fdb":"sellExchangeRate()","14a0069a":"getVoter(string)","14a03e7c":"concludedGameIndex()","14a06710":"TokenRelease(address,uint256)","14a091a9":"createLockTokenHistory(address,uint256)","14a1231f":"guardian2Vote()","14a26806":"setPreUri1(string)","14a2d99f":"Grant(address)","14a34ebd":"getMilestones(uint256,uint256)","14a3557b":"intrepidVoucherSoldCount()","14a3b19a":"transferIndexedByAddress(address,uint256,address)","14a47046":"add_blockedAddress(address,address)","14a4a273":"penalizationOpen()","14a528f2":"HasGift(string)","14a54912":"token_a()","14a57db7":"LogPreparePreContribution(address,uint256,uint256,uint256)","14a59e9d":"getStakeholderConfirmationCount(uint256)","14a5cd29":"getAssetEmitter(uint256)","14a6a1a5":"REQUESTED_STATUS()","14a7945a":"redeemAllOwnedAssets(uint256)","14a7c57d":"getData_26()","14a89904":"rollDie(address,uint256)","14a8bd0d":"EXCHANGE_RATE()","14a8ca20":"fromPercentage(uint256,uint256)","14aa0eaa":"claimBountyToken()","14ab260e":"retrieveCompletedProof(bytes32)","14ab9038":"setTTL(bytes32,uint64)","14aba0db":"MineAD(address,uint256)","14ac1102":"get_total_items_in_state(bytes32)","14ad47eb":"SwapToken()","14ae1229":"setRightForInterest(uint256,uint256,bool)","14aedbee":"TokenFactoryAirdrop()","14af0908":"XdacTokenCrowdsale(address,uint256[],uint256[],uint256,uint256)","14af1e92":"MinterGaveCWC(address,address,uint256)","14af35c3":"MyToken(string,string,uint256)","14afd79e":"ownerOf(address)","14b0519d":"AltExtraHolderContract(address)","14b08b4d":"getAllDepositors(uint256)","14b0e266":"addBid(uint256)","14b11606":"BONUS_ICO_STAGE2()","14b11651":"setPoolAndAmount(address,uint256)","14b11875":"verifyProposal(address,address,uint256,string)","14b1e1f8":"setRefer50x50(address)","14b24209":"multiGuess(int256[])","14b2cd55":"LightPool()","14b2d6dc":"isValidDate(uint256,uint256,uint256)","14b419c9":"getAllUsers(address)","14b49c36":"Police_5()","14b5202c":"stage_Discount()","14b546b4":"FreePublicity()","14b577ab":"addIdArrayItem(address,address,string,string,uint256)","14b72000":"txFeeCapInWei()","14b77798":"unsetMany(address[])","14b78abb":"cloneProposal(uint256,string,bytes32,uint256,uint256,uint256,uint256)","14b79e21":"_depositTransferCredits(uint256,uint256)","14b7c684":"DGD()","14b80402":"isStateDestructed()","14b85c1b":"removeSalesAgent()","14b87862":"getParticipant()","14b8e9a4":"checkpointLevel()","14b92721":"loveMessage()","14b933e1":"getWeiPerSatoshi()","14ba5c09":"getDay()","14bafeab":"getMessage2()","14bb4dd9":"WavesTransfer(address,string,uint256)","14bba4b8":"setDiscount(uint256,uint256,uint256,uint256,uint256)","14bba8a2":"updateRequestExpired()","14bbe21c":"transferBeneficiary(address)","14bc3efc":"endBorrowAgreement(string,string,uint256,uint256)","14bd0c21":"getServiceAddress(bytes)","14bd3d87":"acceptOffer(string)","14bd8acd":"massApproval(bool,uint256,uint256)","14be5169":"releaseLockAgencyLock2()","14be7793":"isPrivateSale()","14beb3a3":"latestParams()","14befc70":"parkingOff(address)","14bfd6d0":"admins(uint256)","14c01fb4":"_checkPixelAbove(uint256)","14c0a37a":"stateBorrowerDefaulted(uint256)","14c0bc27":"EtherBalanceOf(address)","14c0ffdc":"formula(uint256)","14c15569":"getAccountOutputSdcslength()","14c16f41":"updateStageWithInvested()","14c239a9":"_cappedReward(uint256)","14c259eb":"white_duration()","14c292ca":"finishITO()","14c2d2e0":"handleRef(address,uint256,uint256,uint256)","14c33c24":"setSystemEndingPrice(uint256)","14c3512d":"adminSetFeeUsdDialNumber(uint256)","14c3e29f":"NONEC()","14c411c7":"releaseTeamTokens()","14c44e09":"registrationFee()","14c485c9":"getMartialListInfo()","14c588de":"setPromoGen0(uint256)","14c5f158":"callModifiedTransfer(address,uint256)","14c65687":"_getWeightUntil(uint256,uint256)","14c72e9e":"_getFirstIndex(uint256,uint256[])","14c74834":"setHeir(address,uint256)","14c7763b":"MINTING_LIMIT()","14c78333":"batchResolveAquarium(uint256[])","14c7bddf":"manualRefund()","14c888da":"setFeeParams(uint16,uint256,uint256)","14c8e5f4":"requestHangingDividends()","14c9035e":"quickConvertPrioritized(address[],uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","14c9b8a5":"closeEarly(uint256)","14c9eed0":"onlyadmin()","14ca5200":"MiningRewardTransfer(address,address,uint256)","14ca5398":"submitFullBlock(bytes,uint256[],uint256[],bytes,bytes,bytes,bytes,bytes,bytes,uint256)","14ca6e01":"setBleachPrice(uint256)","14ca8e01":"validPlayer2(uint256,address)","14cabddb":"joinProof(uint256)","14cba002":"_forwardTransferFromWithReference(address,address,uint256,string,address)","14cbb90d":"yea()","14cbd993":"getRegisteredTokens()","14cbdb54":"EspCoin()","14cc3cf9":"FOUNDERS_LOCK_PERIOD()","14cd70bc":"FakeOwner(address)","14cddf9e":"whiteListMinAmount()","14ce2f61":"MappingDone(address,uint256)","14ce4059":"owner_fee()","14cf12d5":"softCapTime()","14cf19fe":"TIER1_PRICE()","14cf588f":"LBA()","14cf6983":"getBalanceCell(address)","14cfb977":"minFinneyPerSaleMoreThan()","14cffda2":"synertreeToken()","14d03ea6":"TrivialToken(string,string,uint256,uint256,address,address,uint256,uint256,uint256)","14d04e06":"FooozCrowdsale(address,address)","14d066d5":"addCertificator(address)","14d07a3e":"left28(uint256)","14d0f1ba":"moderators(address)","14d10920":"BetstreakToken()","14d140b0":"communityPool()","14d20606":"devTeamPrecent()","14d23c8b":"MaliciousSeller()","14d296f4":"getPremiums()","14d2d59d":"_approve(uint40,address)","14d30335":"assignInitialDays(address,uint256,uint256)","14d33a30":"addCandidateBatch(address[])","14d36f53":"checkVerifyAccess()","14d3df67":"getSMPTokensAmountPerEthInternal(uint256)","14d47bc9":"registerBeneficiaries(address[])","14d4ecd9":"defineCurrentPeriod(uint256,uint256)","14d5d892":"changeMemberAddress(uint256,address)","14d67848":"setClass(uint256,uint256)","14d6c2b1":"_maint_updateOwner(address)","14d72106":"nextNumberOfWagersToFinalTimeout()","14d75e9d":"createProduct()","14d8c981":"getItem(address)","14d9d2e5":"getCostForUprade(uint256,uint256,uint256)","14dacf5b":"disableWhiteUserList()","14db6d58":"hasUserPermission(address,bytes4)","14db8c7d":"getGladiatorPower(address)","14dba3ba":"PPToken(uint256,uint256)","14dbb508":"Project(string)","14dcd58f":"derpcoin()","14dcfd55":"vendorWallet()","14de9cc2":"tokenGenerated()","14dea8e7":"onCancel(bytes32,uint256,address)","14deb0ac":"addressAt(address,bytes,uint256)","14df96ee":"isRoundingError(uint256,uint256,uint256)","14dfad27":"_emergencyLoop()","14e0246a":"setMintSigner(address,int256)","14e2bc2a":"finishMinting(uint256)","14e3fad3":"extra_bonus_amount()","14e4a723":"SafePromo()","14e580ab":"LogIdentityCreated(address,address,address,address)","14e604b6":"EXPLOSION_DENOMINATOR()","14e6a86d":"doCheckBounds(bytes32)","14e8093f":"clientWithdrawAll()","14e887e8":"transactionCounter()","14e904e8":"LogBidCompleted(uint256,bytes32,bytes32)","14eaa43b":"withdrawToken(address,uint256,string)","14eb75bb":"assignRoles()","14eb76ac":"updateTeamAddress(address)","14eba026":"removeTeamMember(address)","14eba5d8":"affiliateList()","14eda32c":"COZE()","14eea0dc":"IND()","14efaf86":"ChangedPaymentDestination(address,address)","14f0ff32":"FUNK()","14f1586a":"objective()","14f1dcac":"setFreeCoins(uint256)","14f2979f":"getTickets(uint256)","14f36e17":"getTokenIssued()","14f3f491":"preICOContract()","14f52c07":"Blogcoin()","14f60881":"getJobClient(uint256)","14f64d6c":"PRESALE_START_WEEK1()","14f685a8":"Etherumble()","14f6c3be":"getETH()","14f72e50":"EightStandardToken(uint256,string,uint8,string)","14f7731b":"getAllowedAmount(uint256)","14f7789d":"GRAChain(uint256,string,string,string)","14f796ca":"changeStageAndReleaseETH()","14f80083":"setMultisigVault(address)","14f8917a":"initialSupplyPreSale()","14f8b424":"roundID()","14f8f160":"hasIssue(address,bytes32)","14f99533":"changeAuthorisedContract(address)","14f9e35b":"groom()","14fa0b45":"NenasChain()","14fa274c":"MigrationInfoSet(string)","14fbc22b":"createHero(uint256,address)","14fc2812":"setAuthorized(address)","14fc7b9d":"AscToken(address)","14fcb95c":"ubiatarPlayWallet()","14fd0c14":"deadlineVoting()","14fd24f0":"updateIndividualCap(uint256)","14fddb71":"devTeamBalance()","14fdecca":"getPromotion(uint256)","14fefca1":"set_hp(uint256)","14ff5ea3":"getTokenId(uint256)","14ff5f99":"punterAddress()","14ff89cd":"getContactByIndex(uint256)","14ffbafc":"startEthGet()","1500214e":"calcPercent(uint256,uint256)","15003368":"withdrawEMONT()","1500c257":"startTimePre()","1501bf03":"transferFunds(address,address,uint256)","15020cb0":"commandTookAway()","1502906d":"timeStep()","15036fa2":"update_dividend(address,uint256,uint256,uint256)","1504460f":"poke(bytes32)","150455a4":"HOTCASH()","15045c3e":"GenieToken()","1504ce95":"payout(string)","1504d8f0":"createSnapshot()","1504e40b":"RoundEnded(address,uint256)","150627bb":"minimumInWei()","15067c4e":"p_setRoundDuration(uint256)","15070401":"getSymbol()","150727ff":"getSecondAddressBalance()","15087f7d":"cancelBet(uint256,bool,uint256)","15093e03":"minimumAllowedWei()","1509c42a":"pr()","150a5655":"giveVote(string,uint8)","150a6480":"allowMinter(address)","150aaf74":"BHB(uint256,string,string,uint8)","150ad2a8":"owner_transfer_ownership(address)","150b52db":"removeAddressFromPartnerWhiteList(address)","150b6885":"genaroDevMultisig()","150b7a02":"onERC721Received(address,address,uint256,bytes)","150bc419":"unitMythGrowth()","150c3e8b":"getIdxArray(uint256)","150d6277":"setMinBetPerSpin(uint256)","150d7163":"UnfreezeTokensOfOneUser(address)","150eb4d9":"releaseTeam(uint32)","150f16ac":"stoppedPresale()","1510ca79":"MAX_CROWDSALE_TIME()","151110b0":"releaseLockedBalance(uint256)","1512cfc1":"_preValidateInvest(address,uint256)","15136fb5":"ChiTrader()","15139f09":"ExaGBP()","15142ed4":"shutDownVersion(uint256)","15143d6a":"buyOx()","1514617e":"vestingDuration()","15148649":"getAllowedTokensCount()","1514b9cb":"RKCToken()","1514bc48":"tokensForPurchase(address,uint256)","1514ea54":"getLossesShare(address)","15154aff":"ITO()","15158a10":"numberOfTokensToAvail25percentDiscount()","1515bc2b":"hasClosed()","151682a5":"HASH_RATE_MULTIPLIER()","1516bbc4":"setTeamVault(address)","1516db09":"allOwners(uint256)","1516def7":"multiSigAddress()","1517d107":"totalNormalCollected()","15183e2f":"twitterBotAddress()","15191c98":"hibernate(uint256)","15194a9f":"init(uint256,string,string,uint8)","151b0bed":"getSponsorshipsBalance(address,uint256)","151b2342":"getOraclizeCallbackFee()","151bc167":"Control()","151bcc06":"massAdvertiseTransfer(address[],uint256)","151c0d40":"crowdsaleEther()","151c3b12":"store(address,bytes)","151c61b6":"setUSDExchangeRate(uint256)","151d7d32":"flushDividends()","151e2a0a":"check_ptc_num(address)","151eeb55":"transferAllowed(address)","151fa6be":"delegateIsDeleted()","15226b54":"getReserveBalance(address)","1522f110":"preregvills(address)","15248362":"buy_bounty()","152583de":"getAttributes()","152592b0":"WALLET_ALLOCATION()","1525b4f5":"mintLockedTokens(address,uint256,uint256)","1525d680":"MainToken(address)","1525ff7d":"setTeamWallet(address)","15263ef7":"VHW()","15270ace":"distribute(address,address[],uint256[])","152713b3":"sumAcceptedVirtualContrib()","152744ea":"BondInfoById(uint32)","1527d657":"returnHowMuchMoreETHNeeded(uint256)","152826e9":"cashoutable()","15285aa3":"EventBid(uint256,address)","1528f43c":"getPOOL_edit_10()","152993a8":"addContract(string,bytes)","1529a639":"getCollateralBalance()","152a3f28":"getSponsorships(address,uint256)","152af8f9":"acceptFoundationTransfer()","152afab4":"adicionarAssinatura(string,string)","152b6f9a":"hasDNN(address)","152cf9db":"getDataPoint(int256,uint256,uint256)","152e84a7":"tokensDistributed()","152fb125":"SimpleMixer()","152fb5fd":"period_count()","15303771":"updateUnsold(string,uint256,uint256)","1531076c":"getAgonArray(uint64,uint64)","15312b50":"SimpleTokenVesting(address,uint256)","153154fd":"getRecommender(address)","1531c267":"fipsRegisterMulti(uint256,address,bytes)","1531dfdb":"ethtosend()","15328109":"parentAddr()","153345ce":"changePrice(uint256,uint256,uint256,uint256)","15334b77":"setGameStarterDividendPercentage(uint256)","15334fa7":"SOCToken(uint256)","15336f80":"setProof(string)","15338724":"mediaTokens(address)","1533ba50":"EMBCToken()","1534180f":"_transfer(address,uint256,bytes,string)","15347380":"priceInWeiToken(uint256)","1534b1fc":"getPlayerDepositData(address)","1534b392":"getNumLockers(address)","1534e8d2":"multiVesting(address[],uint256[],uint256[],uint256[])","1535884e":"notarizeHash(bytes32)","153677b7":"deployOtherVesting(address,uint256,uint256)","1536a614":"EphesusToken()","1536cabf":"addCertAdmin(address)","1536fec6":"get_end_time()","15370598":"getCurrentMode()","153737f5":"OWN_DistributeTokenAdmin_Multi(address[],uint256,bool)","15373e3d":"castVote(uint256,bool)","1537671c":"qtdePokemonsMapping(address)","15382559":"LogDepositReceived(address)","153913e3":"ICO_Live()","15398afe":"compareNumericStrings(string,string)","153a1f3e":"bulkTransfer(address[],uint256[])","153a6bd3":"test_sendFundsToContract()","153a79c9":"buySaleTokens(address)","153aa771":"totalSupplyBonus()","153b0d1e":"setBlacklist(address,bool)","153b31fd":"sign(string,uint256,uint256)","153cc53d":"hasCrowdsaleStarted()","153d3572":"deletePawn(uint256)","153debee":"FOUNDERS()","153e66e6":"buy(address,address,uint256)","153e6d70":"setPercentFrozenWhenAwarded(uint256)","153faf2c":"FOUNDER_WALLET()","153fbb81":"setCAPAddress(address)","153fe583":"getAddressFromSig(bytes32,uint8,bytes32,bytes32)","153fe6aa":"STATUS_INITIAL()","15408734":"addMake(string,address,uint256,uint256,bool)","15409c1d":"TradingAccount()","1540fe22":"weiMinimumLimit()","1541eb12":"JournetToken()","15420b71":"transferPreSignedHashing(address,address,uint256,uint256,uint256)","1542b365":"phase_4_remaining_tokens()","1543136c":"getDeployedLength(address)","1543d99f":"bonus_calculation()","1544fc67":"delegatorStatus(address)","15454cd2":"registerNameCore(uint256,bytes32)","15480c63":"createDefaultCobeFriend(uint256,uint256,uint256,address,uint256,uint256)","15490ebb":"transferReward(address,uint256)","154920b0":"firstEmptyId()","15497d2c":"lockStatus(address)","1549be43":"getOutstanding(address)","1549c1e2":"usePlayerToken()","154a7d71":"DATE_31_DEC_2019()","154ad3f7":"ChangeMemberName(address,string,string)","154af6b1":"sendShares(uint256,uint8,uint256,address)","154b3f4c":"executeSigned(address,uint256,uint256,address,bytes)","154d56db":"callHotel(address,bytes)","154d6e12":"buyPack(uint8,uint128)","154d7944":"newCarID()","154e3f61":"enroll(address,address,uint256)","154e45a4":"privateSold()","154e8152":"withdrawnBalance()","154e95f1":"changeNamespaceOwner(string,address)","154e9bd5":"PumaPayToken()","154f78dc":"FREETOKENTEST(uint256,uint256)","154faf5d":"getTodayIndex()","15502d73":"changeTokenFreezeDate(uint256)","15506bf1":"RemoveParticipant(address,address)","15519af1":"RANGESTART_PRESALE()","1551e636":"tokensReceived(bytes32,address,address,address,uint256,bytes,bytes)","15525991":"getMaxAmount(address)","15527006":"icoPhaseDiscountPercentage3()","1552cb04":"addBaseWhitelist(address[])","15544fc2":"Teaeum(uint256,string,string)","1554611f":"escapeHatch()","1554c243":"_setApp(address)","1555e337":"ConferenceCertificate()","1555fe7e":"RecordableRefundableCrowdsale(uint256)","1556195c":"LowRiskBag()","15574634":"requestTransferFundToSupplier()","1558687a":"DepositContract()","155897cc":"changeDeDeAddress(address)","1558ab7e":"sendEthBack(uint256)","1558ae4d":"Etheroll()","155949ca":"buyStores()","15598339":"GetPurchaseInfo(address)","155ac95f":"switchname(bytes32)","155bdaa0":"SEGFAULTCOIN()","155ce432":"Restitution_Historique_Transactions(address)","155dcb47":"ZJFTokenDeposit()","155dd5ee":"withdrawFunds(uint256)","155f0ebc":"dividends(bool)","155f1861":"claimBonusCard()","156014e8":"addAddressToPartnerWhiteList(address,uint256)","15613495":"earlyBackersWallet()","15613d9f":"chainIdValue()","15616d2b":"getCurrentResult()","1564d706":"lockIn()","15659dde":"getBidCount(bytes32)","1565b0b6":"PRICE_ICO4()","1565c3c8":"takeEther()","1565f12f":"createVote(bytes32,address,address,uint256,bool,string,string,uint256)","156773ca":"setAllStopper(address)","1567d7a7":"transferPromotionalShares(uint256,address,uint256)","1568a1a1":"vinciSold()","15691522":"AltSocialAccountPw(bytes32,bytes32,bytes32,bytes32)","15698812":"redeemExcluded(bytes32)","156a0528":"getBalancesPayer(uint256)","156a2f36":"bid(address,uint128)","156bf4c1":"getKtcAddress()","156c0ed4":"Scanetchain()","156c2e82":"withdrawGxTokens(address)","156c6baf":"isAllowCnsContract(address,bytes32,bytes32)","156cacc3":"Etheroneum()","156e29f6":"mint(address,uint256,uint256)","156e5039":"safeadd(uint256,uint256)","156e9507":"mineTotalBalance()","156f985c":"getFundsStatus()","157003d9":"tierCaps(uint256)","157024b3":"producerStatement(string)","15728a73":"GoBlockSupply()","1574126a":"preSaleEndBlock()","15748250":"freeze(address,address)","15752ac5":"bonusTokensAllocated()","15764334":"Hybrid()","15770d99":"disapprove(address)","15781c80":"checkPurchaseValid(address,uint256,uint256)","15786590":"lotteryTotalEarning()","1578a123":"Send_MediatedTransaction(address,uint256)","1579e5c5":"getAllCardAddressesOfOwner(address)","157a18b4":"ADMOToken()","157a68df":"createIssue(uint256,address,uint256[],address[],string)","157ad5a1":"canWithdrawBond(address,uint256)","157bbbf5":"winJackPot(address,string,uint256)","157cb62c":"getPlayerDnas(address)","157d5956":"isGetFreeZombiew(address)","157daf2e":"returnChange(uint256)","157db359":"airdroper()","157ddf8f":"bonusTotalSupply()","157e2063":"ASTBToken()","157f33f5":"coinIssuedTotal()","157f5610":"showGameEnd()","157f67e8":"withdraw_my_tokens()","157f8f51":"feePaid(int256,int256,int256,int256)","157fbd8d":"emitAccessBlocked(address,bytes32)","1580391c":"set(bool,string)","158048a0":"settlePut(uint256,uint256,address)","158059e2":"changeVotingRules(uint256,uint256)","1580beb7":"HOPEtoken()","158163c8":"setMerculetPrice(uint256)","15817881":"saleStageStartDates(uint256)","1581b600":"withdrawAddress()","15830662":"assignTokens(address[],uint256[])","1583deb2":"businessAddress()","15843245":"PeoplesToken()","158495df":"tokenIds(uint8)","15862aff":"lookupIndex(uint256,uint256)","158641f5":"getArtistId(bytes32)","158686b5":"change_admin(address)","15875f54":"getVestingEndTime(address)","158859f7":"disableTokenTrade(address)","1588ce09":"closeManualyMining()","158952da":"tipUser(bytes32)","15899670":"todaysBidTotal()","158a1184":"operation_amount(uint256)","158a4988":"distributeTokens(address,uint256)","158b8e54":"LastTokenId()","158be5a2":"WTF()","158d1fd4":"crowdsaleEndedSuccessfully()","158dec25":"maxSubmissions()","158e7986":"addBallotAndVoterWithPk(bytes32,bytes32)","158e7e53":"maxPreIcoAmount()","158ee887":"emergencySetOwner(address)","158ef412":"forceUpdateName(string)","158ef93e":"initialized()","158f7f5c":"reservedFounder()","15902a09":"removeOpenOrderFromBook(uint128)","159090bd":"take()","15910e5c":"logPurchaseViaToken(address,address,uint256,uint256,bytes32)","15915ddd":"directMintTokens(address,uint256)","15917977":"changeUniqueOwnership(string,uint256,address,address)","15919eed":"Arena()","1591bf51":"getPubKeyArr50(bytes32,uint256,uint256[])","1591dc6a":"BuyLoan(address,uint256,uint256)","159218d2":"setStagesManager(address)","1592aa2e":"registHns(string,address)","1592c087":"transferTusdProxyOwnership(address)","1593796e":"didReveal(bytes32,address)","1593a8c7":"endLottery()","1593ecb8":"LOG_IncreaseInvestment(uint256)","1594060a":"HalvingInfo()","15945790":"_supply()","15949ed7":"getPermissionParamsLength(address,address,bytes32)","1594afd1":"setExchangeRateShift(uint256)","1595f207":"TKT(address)","15969c4e":"minimumStageDuration()","1596b2bf":"getServiceFeeNumerator()","1596facb":"saleTime()","15977d45":"ledger(bytes32)","1597ee44":"encode(uint8[])","15980795":"freezeOf(uint8,uint8)","15981650":"setTicketPrice(uint256)","15983796":"getNextSnapshotBlock()","1598653d":"firstThousandUsers()","159887d1":"calculateFactor(uint256,uint256)","1598b2e0":"getSeatClaim(uint256)","15992cda":"uniq(uint16[])","1599a096":"mixStringAddressFunc(string,address)","159a3c33":"AWAXToken()","159a6475":"getFingerprint(uint256)","159ad680":"updateuser()","159b4e91":"sendTempTokens(address,uint256,uint256)","159bd2f3":"earnedFunds()","159c18bc":"removeWhitelistOperator(address)","159c2d9f":"BuyKeys(uint256,uint256)","159c60e8":"ZDMCoin()","159ce057":"getReturn()","159d3c24":"sellZone(uint256,uint256)","159d526f":"calcStateHash(bytes32[10],uint256[4])","159d8562":"ediv(uint256,uint256)","159da82d":"getInvitationValidPeriod()","159dbef7":"_0xDiaryToken()","159de07a":"FundariaBonusFund()","159e1e14":"EthereumPrivate()","159f82fc":"getEventResult(uint64)","159fb416":"transferCreditBotAddress()","15a03930":"TossMyCoin()","15a090c0":"getMiningWarRoundNumber()","15a0df43":"testThrowCreateNewRevisionNotOwner()","15a0ea6a":"claimFees(address)","15a269f7":"withdrawBalance(address,address)","15a29035":"getTask(bytes32)","15a2bd76":"allowOrRestrictMethod(bytes4,bool)","15a38bda":"isOldVersion()","15a3c611":"project_registry(uint256)","15a4806c":"EtherButton()","15a4d313":"NovaChain()","15a50aff":"getInvalidKeys()","15a51595":"TeamMembersAddress()","15a52302":"getService(address)","15a529b6":"getAllSalesByAddress(address)","15a55347":"reservedTokens()","15a5d9d8":"contractAddr()","15a60b76":"_calFrozenAccountCoin(address)","15a653a0":"numberOfSupportedTokens()","15a686f3":"PixelOperationsContract()","15a6a11c":"mintLeftOverZCOToWallet()","15a6a38d":"RedeemMTU(bool)","15a6f5c1":"setLatestTokenPayday(address,address,address,uint256)","15a75f9f":"playFor(address,bytes32)","15a9a145":"numRewardsAvailable(address)","15aaa09b":"PRECOE()","15aaefd5":"_transferPrimordialToken(address,address,uint256)","15ab250d":"setCresus(address)","15ab8302":"RoundASold()","15abc160":"createValidatedRequest(address[3],address,uint256[11],uint256,bytes)","15ac4c90":"setDayEthInLimit(uint256)","15ac534d":"closeBetting()","15aca0c4":"LogError(uint256)","15acce5e":"arpDeposited()","15ad1be3":"unrestrict(address)","15ae0629":"getHash(bytes,uint256)","15ae1972":"stageRate()","15aec1fb":"airdropadd()","15aec7ee":"BlockChainCourse()","15aee408":"FinaliseSale(address,address,uint256)","15af64e7":"JACToken()","15afa98e":"totalEth_()","15b02a4c":"totalICOable()","15b03fde":"getaddresstotal(uint256)","15b07f69":"nextCourse()","15b0821f":"mintDRSCoin(address,uint256)","15b21082":"requestCustodianChange(address)","15b23e47":"OncoToken()","15b2b1ae":"SaleStatus(string,uint256)","15b3433b":"dexjartoken()","15b37899":"setKyberNetworkAddress(address)","15b40ec0":"deployed(uint256)","15b4bc22":"getMinerHalving()","15b53beb":"TournamentOver()","15b556df":"getSellPriceAfterTax()","15b56b44":"checkReward(uint256[])","15b66fef":"calculateClaimableRewardTillRound(address,address,uint64)","15b73a1d":"ICOSupply()","15b7ab02":"setAgriChainProduction(address)","15b8003b":"buyChance(uint32,uint32,bytes32,uint256)","15b88b35":"PeaceToken(uint256,string,string)","15b9a8b8":"controllerCount()","15ba9ea2":"register(address,bytes32[5],address)","15bbc15d":"approveMP(address,int256,uint8)","15bc9441":"convertToDEF(uint256)","15bd73f1":"offerchangeprice(uint256,uint256)","15bd8bb2":"getTimestampByHash(string)","15bddfbe":"__setParameters(uint32,uint256,address)","15be2e7c":"totalSaleLimit()","15bef9cd":"changeMembers(address[],bool)","15bf2b51":"last10()","15bf430d":"Project()","15bf7cd7":"deployedPresaleContract()","15bf7ed2":"publicFundingPersonalEthLimit()","15c0251c":"getCoinWallet(bytes4)","15c12d4d":"totalWeiWon()","15c1c5b8":"EternaCoinContract()","15c2eed8":"RedlineFinancialLabCoin()","15c30006":"_payoutReferr(address,address)","15c32297":"setCanTrade(address,bool)","15c3cd94":"canTransferUST(bool,bool)","15c43aaf":"contractInfo()","15c560c7":"addTotalInvoiced(address,uint256,uint256)","15c5c950":"isProcessedTx(bytes32)","15c6b117":"CRPA()","15c6b40a":"cloneFeePercentage()","15c73afd":"resolveEmergency()","15c7ff34":"isPaidUntil(address)","15c8276d":"_supportsInterface(bytes4)","15c83cac":"getNewItemId(address,bytes32)","15c8d628":"normalBuyLimit()","15c91115":"pbkdf2(bytes,bytes,uint256)","15c98193":"getCampaignCreator()","15ca41c3":"notarizeHash(uint256,bytes32)","15ca65f0":"purchase(uint256,uint256,uint256,address,bytes)","15cab9c0":"pre_active_time()","15cb75e3":"replaceChiphash(uint256,bytes32)","15cbfdc1":"SpendingBlockedEvent(address)","15cce224":"setFeeToken(address)","15cd8e0b":"SECOND_PHASE_MAX_SPAN()","15ce09ad":"winningTimestamp()","15cec355":"_escrow(address,uint40)","15cf4a5f":"createElection(string)","15cf59b6":"getCreatefeeWindowIdValue()","15cf7a35":"fechVoteResultForCandidateBySnapshotBlock(address,uint256)","15cff546":"isOperationBlocked()","15d10f38":"decreaseICOcap(uint256)","15d28e11":"totalLendingAmount()","15d2fc8a":"setPreIcoEndsAt(uint256)","15d3b5d8":"getTotalAllocation()","15d3cfe2":"EtherCashPay()","15d3e0a3":"transferToSafe()","15d3f614":"Bet4Land()","15d42327":"testMulMod(uint256,uint256,uint256,uint256)","15d44202":"resultsValidationStep()","15d494c4":"test_chain2_1_increaseTimeBy5000()","15d4c5d5":"proposeMint(address,uint256)","15d4f2df":"_internalTransfer(address,address,uint256,uint256)","15d51761":"partner2_will()","15d5219f":"calLoanAmount()","15d53d7d":"_existPublicKey(address)","15d655c9":"claimPrice()","15d6af8f":"winnerList()","15d707af":"KD0Token()","15d7085f":"calcRankFundsFee(uint256)","15d7811e":"findYforX(uint256)","15d7b2c4":"setVestingManager(address)","15d7bf44":"register(bytes32,bytes32,address)","15d85401":"QbaseTalk()","15d87dc4":"vendorVerify(address)","15d887a7":"confirmedTotalToken(bytes32,uint256)","15d99a77":"CleanSweap()","15d9a9ee":"registerBarcode(bytes32,bytes32,string,bytes32,string,bytes32,bytes32)","15d9ad50":"illiquidBalance()","15d9aefd":"TeaToken()","15da0b02":"setCommunity(address)","15da42dc":"airdropSEEDSinWei(address[],uint256)","15da63a0":"thirdStagePriceOfTokenInWei()","15da65a5":"currentQuestionId()","15dacbea":"transferFrom(address,address,address,uint256)","15dae03e":"getType()","15dbfe28":"fromReal(int128)","15dc806e":"getStageBonus()","15ddf344":"getWhitelistStatus(address,bytes32,uint256,address)","15de4607":"getOwnFashions(address)","15de8027":"getAquaTokenAudCentsPrice()","15deaa3f":"INTARO()","15df1a09":"_fromToken(uint256,uint256,uint256)","15dff3b3":"RoleLookup()","15e04206":"Strings(string,string,uint8,uint256)","15e1146b":"deadlinePreIcoTwo()","15e1c65c":"added_to_the_bank()","15e28700":"addTokenPairWhitelist(address,address)","15e3187d":"amIBeneficiary(address)","15e33901":"digest(bytes,uint256)","15e3ab3a":"nccToken()","15e3d37d":"getAllCardsForClaim()","15e5ae1e":"Killer()","15e5c69e":"_purchase(address,uint256)","15e70102":"myTarif()","15e812ad":"getBaseFee()","15e82e87":"Free_vote_for_candidate_B()","15e839c1":"setHeroGenes(uint256,uint256)","15e9c2d4":"PainPoints()","15e9fc28":"setBets(uint256,bytes32[])","15ea426d":"hasUserWon(uint8,uint256,bytes32,bytes32)","15eaef6b":"tokenTransfer(address,address,uint256)","15eaf224":"getlastJadeProductionUpdate(address)","15ed6d06":"totalBondSupply()","15ed97c5":"_preValidateAssign(address,uint256)","15ee1255":"overrideCharPrice(uint256,uint256)","15ee3726":"createMesa(uint256,address)","15eec1b6":"setPayerString(string,string)","15ef29c3":"configureTokenParams(string,string,uint256)","15efc893":"confirmAdminTx()","15eff89b":"DiamondToken(string,string,uint8,uint256)","15f063f7":"totalStores()","15f06ede":"placeBuyOrders(uint256[],uint256[])","15f0c220":"marketingAllocation()","15f17902":"updateCeleb(uint256,string,uint256[6],uint256[6])","15f2226e":"removeAccessor(address,address,address,string,uint32,string,string,bytes32,bytes32,uint8)","15f28c5f":"walletB()","15f2e1bf":"getFunderCount(bytes32,string)","15f2e2f7":"LOCK_START_TIME()","15f2eb87":"getNumEndableGames()","15f2fe4f":"setDelegadoDeDistrito(bytes32,bytes32,uint8)","15f3161f":"issue(address,uint256,uint32,uint32)","15f3223c":"assertHash(bytes32,bytes32)","15f570dc":"burn(address,uint256,string)","15f59033":"setPropertyLastUpdaterLastUpdate(uint16,address,uint256)","15f5ea17":"stop_auction()","15f647fc":"setLoanProductActiveState(uint32,bool)","15f667ca":"phase2TokenSold()","15f73331":"invalidateName(string)","15f78c0c":"GetBank()","15f84d25":"isActiveContributor(address)","15f903a3":"setNameValue(uint256)","15f92e3b":"getBeat(uint256)","15fa168a":"setVerificationRate(uint64)","15fb1a65":"slashPower(address,uint256,bytes32)","15fb2185":"adminSetAdmin(address)","15fbba7a":"delPokemonFromMaster(address,uint256)","15fdf660":"mPerSellData()","15fe3b6c":"testTransferAfterFinalize()","15ff8f3c":"RESERVE_PORTION()","16002f4a":"totalAuctions()","16011bf1":"addReader(string,address)","1602a124":"allowMinting()","1602c424":"purchaseRect(uint256,uint256,uint256,uint256,uint256[])","160344e2":"startLottery()","16035ba0":"getTotalVolumeEth()","16038be8":"mintVestedTokens(address,uint256,uint64,uint64,uint64,bool,bool,address)","1603c521":"opensourceFundManager()","1604901b":"getGameByID(uint32)","1604c449":"numTilesClaimed()","1604f9ea":"requestPrice()","1604fa4d":"checkIfProjectExists(bytes32)","1605750d":"addToWhiteList(address,address)","1605782b":"sha1(bytes)","16059170":"onSubCanceled(uint256,address)","1605a889":"DecenterHackathon()","1605bc07":"SVDelegationV0101(address)","1605dd61":"getAddressBySymbol(string)","1606a1c9":"getAuditReportIPFS(address,bytes32)","1607dd9d":"distributeSpecial(address,uint256)","160849a7":"participateICONow(address,uint256)","1608e93f":"dice(uint256,uint16)","1608f18f":"disableTransfers(bool)","16090250":"getPolicyDetails(bytes4,address)","1609a397":"unhaltsTrades()","1609b182":"ReputationToken()","1609bbbf":"BarimCoin()","1609bdf2":"EEMWallet()","1609be1d":"sweepTokens(address,address)","1609e43b":"levelStartupTimestamp()","160a453e":"queryTokens()","160a7925":"getPermissions(address)","160abc9d":"tier1Rate()","160b01a1":"childTokenByIndex(uint256,address,uint256)","160b313d":"addAssociatedAddress(uint256,address,address)","160c5239":"read_total_global_purchased_today()","160d5240":"_toNanoNIL(uint256)","160d66ae":"voteToken()","160dc0ac":"buyItem(uint256,address,string,string,string)","160e3f3d":"grant(uint256)","160e915f":"canAcceptPayment()","160fc374":"cancelOrder(address[3],uint256[3],uint8,bytes32,bytes32)","160fe0e2":"getWtotalEth(uint8)","1610b59b":"infoFields(bytes32)","1610c734":"bonusLimit5()","16114acd":"recoverTokens(address)","161181ea":"getUserLengthOnToken(address)","1612ec4f":"applyToken(address)","1613520f":"priceTLP1()","1613ec9d":"getInitFunction()","161448df":"BossContract()","16145311":"ISAO()","161593a3":"landmarkToApproved(uint256)","1615d035":"airdropWallet5Pct()","1615e11d":"DARK()","16164467":"findRequiredSubscriberIndex(address)","16164b33":"icoTarget()","16164e15":"setInvestorData(address,uint256,uint256,uint256)","161666eb":"calculateAddress(uint8)","1616f54a":"FOURTH_TIER_SALE_START_TIME()","16173f39":"sin(int256)","1617adf7":"periodITO_softCapInUSD()","16180e8e":"reallocation(uint256)","16181a48":"insert(address,string)","16181bb7":"shortSellShares(bytes32,uint8,uint256,uint256)","16188c79":"isBadToken(address)","161895eb":"startBuy()","16192d2a":"accountInformation(address)","161965d9":"getRN()","1619fc14":"initOraclize()","161b5e46":"transferOwner(address,address,uint256)","161b75b2":"returnRemainingTokens()","161b9f5e":"ControllerManager()","161c389a":"NewImage(uint256)","161c8594":"setKpopArenaContractAddress(address,address)","161d2a59":"approveCertificate(bytes32,bytes32,bytes32,bool)","161dc300":"mintForSampleRegitry(address,uint32)","161fc5b3":"StartNewMiner(address)","161ff662":"proxyTransferFromWithReference(address,address,uint256,bytes32,string,address)","16201c24":"updateLastActive(address)","16205a7c":"RateDelivered(uint256,uint256,uint256)","162094c4":"setTokenURI(uint256,string)","16210e25":"verificationHoldersVerifierAddressMap(address)","16212265":"closeAirdrop()","16216f39":"return13()","16220188":"AddToWhiteList(address)","16222950":"golemFactory()","162255e1":"m_frozen()","1622dbe4":"buy(address,uint256,uint256,uint256)","16233f3f":"withdrawMortgageTokens(address)","1624288d":"balanceOfTokens()","16243356":"end_time()","16244907":"changeAnimal(uint256,uint256,bytes32,uint8)","1624f6c6":"initialize(string,string,uint8)","16260713":"isFrozenByAddress(address)","1626315c":"purchaseNew(uint256,string,string,uint256)","16265694":"validRateDurationInBlocks()","16265b4e":"isDatasetRegistred(address)","1626ba7e":"isValidSignature(bytes32,bytes)","16270f7d":"ownerIndexBit(address)","1627540c":"nominateNewOwner(address)","16277952":"userLoveLocks(address)","16279055":"isContract(address)","1627c3c1":"divForTeamEthContract()","1627d3f2":"createToken(string,string,address,address,uint8)","16281405":"buyXaddr(address,uint256,bytes32)","162856f5":"_emitOracleRemoved(bytes4,address)","162897c0":"sendUnsoldTokenToRewardSupply()","16291032":"setQualifiedPartner(address,uint256,uint256)","162927b6":"approve(uint256,address,uint256,uint256,address)","162a8e5f":"distributeTokensAfterIcoByOwner()","162bb373":"disableERC721()","162bc80c":"WithdrawTokens(uint256)","162bf1ee":"getBurnRequestAddressMap(uint256,string)","162cbefe":"AVAILABLE_AIRDROP_SUPPLY()","162d563d":"withdrawGNO()","162d7daf":"buyQST()","162dd6da":"takeEtherProfits()","162e2f6c":"reservationFromEthereum(address,uint256,uint256)","162e4fd0":"getFinalOutcomeByEntity(uint256)","16317946":"notifyTestimonial(address)","16317e7e":"setLiquidationThresholdPercent(uint256)","1631eb07":"unlockReward(address,uint256)","1632070c":"setRewardDivisor(uint256)","1632612a":"TrustEURO()","16328378":"precrowdsale(address)","16330c55":"setRafEnd(uint256)","163317c6":"fundAdvisor()","16339604":"_FIVETHOUSAND()","1635717c":"getInstruments()","1635e13c":"initBuilding(uint256,uint256,uint256,uint256,uint256,uint256)","16367c63":"earlyParticipantWhitelist()","163687ab":"defaultOperatorsByTranche(bytes32)","1636ed74":"gatewayOpened()","163740d1":"HieToken()","16381382":"getBetUint(int8,int8)","1638e70d":"DIETSweets()","1638f628":"calculatePayout(uint256,int256)","163935a8":"BlokTokenSale(address,uint256)","163aa00d":"lastRewardEthBlockNumber()","163aa631":"isIssued(bytes32)","163aba3c":"getQueryFee()","163c0351":"reserveTeam(uint256)","163c17b1":"goldFreeze(address,uint256,uint256)","163c4e3c":"CryptoGripInitiative(uint256,uint256,uint256,address)","163db71b":"totalDistributions()","163dba92":"setBlocks(uint256)","163ebd3a":"MainExchangeNM()","163ef5cb":"tgrSettingsPartProject()","163f6691":"getAttribute(address,bytes32)","163f7522":"isUserRegistered(address)","163f9b4f":"withdrawalOwner()","163fa64a":"setSkillPointCost(uint256)","163fa8af":"addInvestmentPackage(string,uint256)","164116f8":"_getPrice(uint256)","16413515":"tokenIdToData(uint256)","16419aa7":"slice16(bytes,uint256)","1641bced":"jackPotGameLockedToken(address,uint256)","1642fcca":"SZ(uint256,string,string,uint8)","16431c5b":"CreateANM(address,uint256)","16443801":"Zigilua()","16448c99":"allocateTokens(address,address,uint256)","1644b20b":"Bhinnekamint(address,uint256,uint256)","1644ed01":"isVolumeReached()","16450092":"totalCap()","16458d74":"show_Candidate_Victorious_in_Election()","1645f0cb":"_mintIdentityToken(address,address)","16468fe2":"mintEndYear()","164745c5":"presaleendTime()","1648371d":"bboBalance()","1648be60":"lockSupplierAndLockPosition(address,address)","1648f38e":"createExchange(address)","16496a15":"onceAddTime()","1649b76d":"maxDexSize()","1649cdcd":"testGetItemStore()","1649d72b":"proposeNewNotary(address)","164a009e":"WHITELISTING_DURATION()","164ba24b":"Payments()","164c9bf0":"Trust()","164ce703":"useless(uint256)","164ceb70":"getTradeByReferenceCode(bytes32)","164d3f3a":"Redeem(string,string,address)","164e68de":"withdrawFees(address)","164f81c3":"confirmAddress(address)","164fa4ef":"withdraw_token(uint256)","1650533f":"distroyIssuerToken(uint256)","16511a67":"removeHodler(address)","16512624":"setAgonValues(uint256[5])","16514052":"setPropertyDAppContract(address,bool)","1651f29a":"redeemForAllFeeWindows()","16521a2b":"getGameJackpot(uint256)","1652a9d3":"StartPeriod(uint256,uint256,uint256)","1652b365":"Xenith()","1652e7b7":"getAssetData(address)","16534bfc":"SKRToken()","16537a85":"makeschoolToken()","1654474b":"submitSellOrderWithPosition(bytes32,uint256,uint256,uint64,bool)","16552393":"creatorAddr()","1655a451":"PotPayout()","1656df0a":"_5_avto(uint256)","1658d496":"TamasCoin()","16597742":"announceWinner(uint8)","1659aecc":"timeoutYEnabled()","165a0e03":"channelsLimit()","165b22c1":"claimNxc()","165b2644":"getDepositN(address,address,uint256)","165b9ad0":"MOMO_FOUNDATION_WALLET()","165c4a16":"multiply(uint256,uint256)","165c86df":"rewardsWithdrawalRecipient()","165ca484":"USDDigital()","165cfea3":"TheImmortals()","165db404":"AdvisorsAndPartnersMinted(address,address,uint256,uint256)","165e2eea":"setFund(address,string)","165f7d38":"buyIntoSyndicate()","165ffd10":"restart(bytes32,bytes32)","16603758":"setUserCategory(address,uint256)","16618e61":"ICOweek3End()","16628014":"setBitcoinRate(uint256)","1662da6a":"setWhitelisterAddress(address)","1663f4ee":"SplitEqual(uint256)","166428c0":"PoolSubmitted(address,uint256)","16643430":"setRateEarlyStage4(uint256)","1664b9cf":"create(uint8,uint8,uint64,uint64,uint64)","16654268":"getName(address,address)","1665e6b3":"approveOrder_(address[7],uint256[7],uint8,uint8,uint8,bytes,bytes,bytes,bool)","1666b514":"RipeXToken()","16670bcd":"resolveDispute(uint256,uint256,uint256,uint256)","16671990":"minCapMain()","166728cb":"feesend()","1667504e":"updateTitleTransfer(string,string,string)","1667590d":"GenesisRewardPerBlock(address,address)","1667d763":"changeRegulatorStatus(uint8)","16685890":"huntingPrice()","1668603f":"PFXTestCoin()","16687369":"chargeProtocolFee(address,address,uint256)","16691869":"addClient(address,address)","16694dd9":"isReportingActive()","166a3952":"createVoter(address)","166bf1b0":"createC1(uint256)","166c4b85":"len(bytes32)","166d3bbf":"payOutJob(address,bytes32)","166d561a":"FatPeople()","166d91fd":"FOUNDATION_RESERVE()","166dc43e":"setManagementProxy(uint32,int256,address)","166e55d9":"computeStablecoinFee(uint256,address)","166eb4cb":"Put(bytes32,uint256)","166ee1de":"newIdentityL1(address,bytes32,bytes32,bytes32,bytes32,uint256)","16706514":"MyDice75()","16708bc6":"metadataSize()","1670cb6f":"oracleA()","1671055d":"etherollBeneficiaryAmount()","16713b37":"receivedTotal()","1671719d":"MINIMUM_LOCK_AMOUNT()","16730131":"addHpbNodeWithString(address,string,string)","16735925":"setAllowErc20OwnerClaim(bool)","1673f758":"FundTransfer(address,uint256,bool,uint256)","1674bade":"setMinDuration(uint256)","16754c55":"createArea()","1675f455":"tokenUri(uint256)","1676503e":"updateParameters(address,uint256,uint256,uint256,uint256,uint256)","16772492":"HngCoinSale(uint256,string,string)","16772b6a":"SentPrizeToWinner(address,uint256,uint256,uint256,uint256,uint256)","1677496d":"withdrawART(uint256)","16783ba7":"assertEq18(bytes18,bytes18,bytes32)","16786ae2":"createMineral(bytes32,uint256)","1679657a":"isTrustedBy(uint256,address)","167aee44":"rewardPoolShare(uint256,bool)","167d219e":"ROLEX()","167d3e9c":"SetOwner(address)","167ddf6e":"getArtwork(uint256)","167e7921":"setTotumAllocation(address)","167f66c0":"startOfDay(uint256)","167ff46f":"openSale()","16801d17":"getBattle(string)","1680a070":"setPlotDataMultiple(uint256[],string,string,string,string)","1680f70d":"transferlottery(address,uint256,bytes)","168110f3":"Tokens_For_Sale()","16812d5b":"retreiveFinalResult()","16815137":"Poge(uint256,string,string)","168179e2":"ESCBCoin(address)","16821349":"ETH_RECEIVED_MIN()","16829de5":"changeEthPrice(uint256)","1682fa59":"GetMaximumBet_Ether()","16831877":"BMICOAffiliateProgramm()","16842582":"createLottery(string)","1684844b":"registerNameXaddr(string,bool)","1684c715":"TaskCompletedEvent(uint256)","168656e1":"OwnerWithdrewERC20Token(address,uint256)","16868752":"buyTicketWithRef(address)","16870257":"getTileDescription(uint8,uint8)","16876976":"addrTeam()","16878b07":"activeVerifiers()","16879344":"commitPeriodActive(bytes32)","1687f112":"left54(uint256)","168936a0":"Remain()","1689eb38":"batchSendTokens(address[],uint256[])","168a80d3":"deleteAllTopics()","168b3c69":"CertificationDeleted(string,address,uint256)","168b4a53":"changeColorBlack()","168b6231":"getCoinIds()","168b912d":"numOfDeclaredPublicOfferingPlans()","168bb279":"insertAllowedTokenInternal(address)","168c8120":"COMMISSION_DIV()","168cd7ae":"tokenQuota()","168d71e5":"mediaTokensSymbol(address)","168e41e8":"getHash(bytes32,uint256)","168ecec5":"revokeOperatorByPartition(bytes32,address)","168f3260":"calculateMinPriceForNextRound(uint256,uint256)","168f788e":"reRollMove(uint256,uint256,uint256)","168fb79d":"RANGESTART_7()","16907c12":"updatePlanetLiason(uint256,uint256,uint256,string)","1691473c":"getProducts(address)","16915743":"proofLink()","16925ee2":"changeTradingEnabled(bool)","1692823d":"getViewDatasCount()","16928a44":"updateProjectDescription(string,bytes32)","16937d56":"addressMoneyBalance()","1693b85d":"allowDelegate()","16948e9b":"changeSettings(uint256,uint256,uint256,uint256,uint256)","169509b6":"getOraclizedIndices()","1695533d":"signLease(string,string)","16958c79":"registerBid(int256,int256,int256)","1695d97c":"removeRange(uint256)","16962849":"changeBalanceReplenishmentStorage(address)","16962bc1":"setAllocationClosed(uint256)","16962d7f":"_createKittyToken(address,uint256,uint32)","16963872":"tokenPriceInitial()","16967407":"getAdministrator()","1697283a":"getRequesterLock()","169742f6":"ebyteBalance()","16985349":"standardGrowthRate()","1698755f":"claimToken(address,uint256)","1698933d":"myStrongHand()","1698c7ff":"removeOrc(address)","16993811":"ptxHead()","16996713":"WXGToken()","169a7c3a":"eventWebsite()","169b15fa":"TechZU()","169b9890":"signByGroom()","169bd52d":"MyTestToken(uint256,string,uint8,string)","169bf233":"reportDoubleSpend(bytes32[],bytes32[])","169c13ed":"pendingTransaction(address)","169d16f4":"authorizerTwo()","169dc72c":"MBEToken(address,address,address)","169e18d9":"currentHitTotal()","169e2633":"tokenOwnerAdd(address)","169ea2f8":"dropCoins(address[],uint256)","169f66df":"monetarySupervisor()","169fab66":"TIXToken(address)","169ff375":"RANGEEND_2()","16a0390b":"BountyAmount()","16a0ea3c":"totalLockedSupply()","16a11ae5":"testFailPullWithoutTrust()","16a124e8":"setKeys(uint32,int256,bytes32,bytes32,uint32)","16a25cbd":"ttl(bytes32)","16a27019":"allowedAddr()","16a2a0cc":"setBountyFactory(address)","16a3feca":"_canOperate(address)","16a50228":"minLimitPublicFirstSale()","16a5290c":"purchaseWeapons(uint256,uint256,uint256,uint256)","16a54085":"setSideBetPercentage(uint256)","16a5410c":"Joined(address,uint256,uint256)","16a558d0":"_generateRandomhashNumber(uint256)","16a69a9a":"getDiscountStage()","16a7859b":"listService(uint32,string,uint256,uint256,address,address)","16a8e046":"setLuckThreshold(uint256)","16a92f39":"getDocByIndex(string,uint256)","16aa8508":"_leftSupply()","16aab1bf":"fundingEndTimestamp()","16aabcbd":"onlyAdvisorsCanDoThis()","16ab2b03":"getBid(address,uint256)","16ab4b17":"checkPoolsEnd()","16abdf7d":"setB(uint8)","16ad42ad":"holderList(uint256)","16ada547":"time()","16ae10f5":"USD_SOFT_CAP()","16ae4ec4":"FT_OPERATIONAL_FUND()","16ae5607":"KakToken(address,uint256)","16ae7944":"UpdateRateAgent(address,address)","16aee925":"saleDuringRestrictedPeriod()","16af001c":"calcBonusAt(uint256)","16af87a9":"getSavedReferral(address)","16afdf8e":"release(address,address,uint256,uint256)","16afe218":"setarg_1(uint256)","16b07323":"winsReported()","16b08755":"minorEditsAddr()","16b0c11e":"upgradePrefixPreSignedSecond(uint8,bytes)","16b0cc2d":"Extend(uint256,uint256)","16b0dc06":"getCitizenLevel(address,address)","16b0fc55":"removeAdmin(address,string)","16b14e19":"SingularityTest34()","16b15135":"getEscrowCount()","16b1f6b3":"CROWDSALE_PHASE_1_START()","16b208eb":"_clearApprovalAndTransfer(address,address,uint256)","16b21dfb":"getLockAccount(address)","16b2cd34":"airdroptotal()","16b3299d":"printListOfBooks()","16b33e74":"shuffleNDecks(uint256)","16b3d4ae":"_approved(address,uint256)","16b40451":"changeRandao(address)","16b4e79c":"setCampaignPriceById(bytes32,uint256)","16b57509":"killBounty(uint256)","16b60f2c":"mintMAYToken(address,uint256)","16b64898":"GEN0_TOTAL_COUNT()","16b65fac":"BITXOXO()","16b66016":"tier1Timestamp()","16b6824c":"CryptoWarriorCore()","16b6c75b":"changePeriods(uint256,uint256,uint256,uint256,uint256)","16b6c7bd":"withdrawUnallocatedRestrictedToken(uint256,bytes32)","16b78191":"decrementValue()","16b7d8f2":"VIP_MINIMUM()","16b86ed8":"amountOfMeatInUnicorn()","16b87739":"setCrowdsaleActive(bool)","16b8aa6b":"secondStageDatetime()","16b96f05":"addTotalDividendPoints(uint256)","16ba7197":"WITHDRAW()","16baa937":"AddMinter(address)","16bac350":"overthrow(string)","16bac7e5":"lockBet()","16bb1f6a":"isOriginalRoundContributor()","16bb6c13":"setBaseToken(address)","16bdb7b6":"stage3_price()","16bf3537":"SocialMediaIncomeCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address)","16bf4657":"getNumPayments()","16bfe25c":"emergencyRefund()","16c05aa2":"depositMoney()","16c0acde":"CryptoStars()","16c12746":"getAllOwners()","16c19739":"getPosition(address)","16c1df06":"WorkerPool(address,string,uint256,uint256,uint256,address)","16c24739":"uintInArray(uint256,int256,uint256[],uint256)","16c27c4a":"UNITSimplePaymentGateway(address)","16c3002e":"allowanceForContract(address)","16c38b3c":"setPaused(bool)","16c393a6":"oraclizeBytes()","16c45c7a":"areStringsEqual(bytes32,bytes32)","16c4fcbb":"gotransfer(uint256)","16c519ee":"hasRecentPrices(address[])","16c5792d":"transferCurator(address)","16c6ec92":"ChangeTarget(bytes32,address)","16c6f470":"addNewRaz(uint256,uint256,uint256,uint256)","16c72721":"forked()","16c72861":"nextFrontWindowAdjustmentRatio()","16c7f79f":"testTransferTokenAllowanceAndReturnFunds()","16c85710":"buyMasternode()","16c9b08d":"WenWanCoin()","16ca3b63":"increaseApproval(address,uint256,bytes)","16cac8c7":"Why(string)","16cb9100":"ETHER_MIN_CONTRIB()","16cb9a01":"assertFalse(bool,bytes)","16cba9d3":"checkEtherBalance()","16cbf987":"changeMemberGroup(uint256,string)","16cc7699":"getHistoryRecord(uint256)","16cc9022":"_newWallet(address)","16cd84c1":"AltCrowdsalePhaseOne(address,address,address,address)","16cdf170":"CoinTransfer(address,address,uint256)","16ce8a69":"setBuilding(uint256,uint256)","16ce8c98":"changeBiteCost(uint256)","16ceaa95":"getStageCount()","16cf1651":"setArbiters(address,address[])","16cf8f77":"createDroid(uint256)","16cff09c":"ETHER_MAX_CONTRIB_PRIVATE()","16cff511":"setFunctionFivePrice(uint256)","16d05042":"finalLoser()","16d061a5":"gettime()","16d0ba10":"putOwner(bytes32,uint256,address,bool,string)","16d190e3":"maxWin()","16d2bc5c":"getPlayerRoundInfoByID(uint256,uint256)","16d390bf":"addOwner(address,address)","16d3aa92":"removeTransferRate(address[])","16d41a5a":"setNFTContractInfo(string,string,string)","16d45615":"test_0_ensureDefaultRulesSetToFalse()","16d4c77c":"removeBlockeddUser(address)","16d4db19":"teamCompanyLock()","16d544f1":"resetActive()","16d63f17":"simFirstObligation(bytes)","16d64127":"_setReserveHolders()","16d6be4c":"buyOfferedStakes(address,address)","16d873cf":"TransferOddEther(address,uint256)","16d8b5a2":"ferromContract(uint256,string)","16d8f16c":"updateTentativeWinningPayoutDistributionHash(bytes32)","16d9356f":"oraclize_query(string,string[4])","16d93f3d":"getAddressAnswerKeccak256(uint256)","16d960b5":"createThing(bytes32[],bytes32[],uint88)","16d99cb0":"NewContribution(address,uint256,uint256)","16da1d50":"transferdissolvedFrom(address,address,uint256)","16da7d91":"reorganize(uint256,address)","16dabbf6":"getWalletSetting()","16db5172":"getStaker(bytes32,address)","16dc9704":"numberOfVestedContracts()","16dd68b1":"getFirstAuctionsEndDate()","16ddcef5":"WillCoin()","16de035a":"EtherBB()","16dfae3c":"setGenaroDevMultisig(address)","16e02e2a":"inventoryLocked()","16e10d6a":"ICOInvestorsAmount()","16e1286d":"BEXToken()","16e17852":"TAO()","16e1aed4":"setPartitionControllers(bytes32,address[])","16e242ca":"burnTotalSupply(uint256)","16e27349":"getFeeRecipient(int256,int256)","16e32d82":"_burnPlayerTokensFrom(address,uint256)","16e33aa2":"getData_27()","16e3cad0":"HAYATO_MAX_CARGO()","16e3cfc7":"testStoresUser()","16e457f0":"sellAll()","16e4822b":"calculateEarning(address,bytes32,uint256,uint256,uint256,uint256,address,address,bool)","16e4f677":"UpdateICOAddress(address)","16e55626":"getDogName(address)","16e58a1b":"detach(uint32,uint32)","16e7371f":"LiquidDemocracyController(address,address,address,uint256,uint256,uint256,uint256,uint256)","16e74f09":"getWinner(uint256[])","16e7c80d":"getTierStartAndEndDates(address,bytes32,uint256)","16e807c4":"addBid(address,uint256,uint256)","16e82dcf":"MMaker()","16e85b2e":"scapeHatch()","16e8f2c4":"Rectangle(address,address)","16e93702":"addTeam(bytes32,bytes32,address,bytes32)","16e9fe81":"resetValue()","16ea0728":"totalBuriedValue()","16eb6603":"right50(uint256)","16ebd6d5":"devResWithdrawal()","16ebf77d":"revealConsensus(address,bytes32)","16ecc686":"setup(address,address,uint256,uint256)","16ece9db":"GetContributionInfo(uint16,uint16)","16ed2ae4":"ONE_TOKENS()","16ed36fb":"EscapeHatch()","16ee94bf":"giveArraywords(string)","16eea70f":"RaffleResult(uint256,uint256,address)","16eebd1e":"launcher()","16ef376b":"getPhase(uint256)","16eff85d":"sendRefund(address,uint256,uint256,uint256)","16f0115b":"pool()","16f0e221":"configTimeMax()","16f25d16":"LindaCrowdsale(uint256,uint256,uint256,uint256,uint256,address,address,address,address,uint64,uint64)","16f33fc2":"getLockupCell(address)","16f36d74":"withdrawEtherHomeLocal(address)","16f38b63":"heroAsset()","16f3cb5e":"__kill()","16f4acf8":"changeHolder(uint256,address)","16f4d022":"tier()","16f573e6":"addtoblacklist(address)","16f60f5f":"SPIKE()","16f898fe":"LogCompanyTokensTransferred(address,uint256)","16f8e09b":"privateSaleEtherCap()","16f9ce49":"_slotCommitNew(address)","16fa2f7f":"getUsernameByAddress(address,address)","16fa99be":"totalSuplay()","16fc1a0b":"FaFengToken()","16fc1e64":"resetCreateShareToken()","16fc68cb":"PrivateSaleBuy(address)","16fcdb84":"minBuyPrice()","16fd381a":"settleBet(uint256)","16fd48a1":"ThreesigWallet()","16fd9869":"DepositProjectProfit()","16fed3e2":"receiverAddress()","16fef995":"sundown()","16ff1c76":"appreciateTokenPrice()","16ff5b87":"getNumProjects()","17011011":"BookERC20EthV1()","17019fb4":"givePoint(uint32,int256,address,bool)","1701feaa":"GobizToken()","1702ef0c":"getProposalOrganization(bytes32)","17031f9c":"advisersPeriodLength()","170381fe":"setIcoContractAddress(address)","17038cb2":"partialForwardFunds(uint256)","1703a018":"quorum()","1703b7fd":"eth4DivsOwing(address)","1703c11a":"setFundManagementContract(address)","17040713":"WithdrawRequest(address,uint256)","1704c271":"getShipCount()","170594c6":"totalTeamSupply()","1705a3bd":"migration()","17075992":"lastThreads(uint256)","1707e05a":"loanRequested(bytes32[8],bytes,bool,uint256)","17089563":"rand(uint256,int256,int256)","1708a723":"setRootAddress(address,address)","1708d725":"unregisterFromPool(address)","1708f617":"gasPriceForOraclize()","170ab405":"setSize(uint256)","170ad53c":"totalUnclaimedTokens()","170b0782":"setSystemAddress(address,address)","170b99d9":"trivial()","170bdb36":"inPermissions(address)","170c28a2":"burnlvlToken(address,uint256)","170e1dcb":"bountyVault()","170e2070":"unfreezeAccounts(address[])","170e6d4c":"getLuckynumber()","170eb245":"secondTeamWithdrawal()","170eeb0f":"investmentRefunded(address)","170ff3e1":"addExtension(address)","171060ec":"setLocker(address)","17111edb":"DevvotePrefundClosed()","1712193f":"_requireERC721(address)","17124ed9":"LogCratePurchase(address,uint256,uint32)","1712649b":"rlc_reserve()","17126586":"getOwnerPercentage(address)","1712a72f":"ProofPresaleToken()","1712c489":"setDates(uint256,uint256,uint256)","17135b7b":"transferTokents(address,uint256)","17140bcf":"isSecond(bytes32,uint8)","17154004":"checkIfRefundAvailable(bytes32)","17155659":"createBadge(string,string,string)","17158228":"signupUserWhitelist(address[],uint256)","1716b7f0":"longTermBudgetAllocation()","1716f47e":"getCurrAmount()","171755b1":"getQuote()","1717bb12":"VoxelPlaced(address,uint8,uint8,uint8,uint8)","17183ca3":"maxCallFrequency()","17186ca3":"GetLastBetUser(address)","17191704":"refundToken(uint256)","17193854":"SetAngelCardDataContact(address)","1719b727":"_getTokenAmount(uint256,uint256)","1719d726":"stopBallot()","171c0077":"compare(uint8,uint256)","171d833c":"test_twoValidEqAddress()","171d9243":"TokenOfEightSilver()","171da314":"showPendingAdmin()","171dde3f":"devsTokens()","171dfb4f":"target_hit()","171ef0b2":"exchange_rate()","171efc3f":"refreshWaitPairBetIDsByCancelBet(uint256)","171fc143":"controllerLocked()","171fcb5a":"revealNumber(address)","17203e1d":"makeProfit()","1720684a":"whitelistBonusClosingTime()","1720ce1f":"addTxToRegistry(bytes32,uint256,uint256,uint256)","1721117b":"UpgradeabilityProxy()","17214a8a":"GenesisInitialSupply(address)","17216484":"genericSender()","17219f03":"Ehfirst()","1721ebba":"mokenNameExists(string)","1722a8b0":"rateAngelDayEnd()","172325c7":"refundDuration()","17235779":"Tutorial()","1723934d":"setAvailableSupply(uint256)","17241962":"Zerk()","172419a8":"getCapByStage(uint256)","1724cf8a":"isCARegistered(address)","17255086":"blackjack(uint256,uint256)","1725b847":"voteAgree()","1725d8aa":"getOwnedShipAtIndex(address,uint256)","1726cbc8":"releasableAmount(address)","1726d2c5":"getRefPercents(uint256)","172727c0":"lastCheckBlockNo()","17274abd":"setBtcTokenBoughtAddress(address,address)","172775ef":"generateOrderWithPayeeByAdmin(address,address,address,uint256,string,string,string)","172820de":"KaliToken()","1728ac68":"SPTOKEN()","1728dd43":"GameFinished(address)","1728fb46":"ROLE_LOCKUP()","172960d4":"LogWhitelistAdd(address)","17299c04":"setDisputeFee(uint256)","172a735c":"updateDocumentPoll(bytes32)","172a9438":"ArsenalvsManCity()","172ab60c":"getPositionFromHolding(uint256)","172ac1ea":"isInvoice(bytes32)","172b319d":"GOOLA_UNIT()","172b95e1":"get_transaction_by_row(uint256)","172c61e6":"totalAdoptedAxies(uint8,bool)","172c9a0e":"inspire(address,uint256)","172cf717":"left55(uint256)","172d8a30":"setDirectorLock(uint256,uint256)","172e0456":"set_property_contact(uint256,string,string,string)","172e1e52":"priceView()","173029d7":"derivePayoutDistributionHash(uint256[])","173067a3":"priceStart()","1730e216":"setStartLockPeriod(uint256)","17324249":"playNumber(uint256[])","17324543":"nationalitiesOf(address)","1733043f":"getAllChildIds(bytes32)","1733cbb5":"ConfirmationNeeded(bytes32,address,uint256,address,bytes)","1733fea0":"SKYST()","17342859":"batchSetApprovalForAll(address[],bool)","17342d36":"init(address,address[],uint256[],address,string)","17349ad5":"TokenDecimals(uint256)","17356c22":"getVirusLength()","17367bc8":"VDN(uint256,string,uint8,string)","173817b6":"checkSellerOffer(address)","173825d9":"removeOwner(address)","1738c3ff":"removeVendorById(uint256)","17393f04":"PURCHASE_DIVIDER()","173975aa":"SetENGCommunityAddress(address,address)","173a0615":"Dealer()","173a21f8":"changeWethContract(address)","173a2b5c":"proposalAmount()","173a48a4":"distributeFUDD(address[],uint256,uint256)","173a4b70":"newProposal(address,uint256,bytes32,string)","173a705f":"transmitStatus()","173c9d27":"batchTransferForDifferentValues(address[],uint256[])","173cb7de":"getNumReleasesForNameHash(bytes32)","173d2795":"train1(uint256)","173d6ca2":"tier1Reached()","173dbd4e":"GoCryptobotCoinCore()","173dc741":"addBonusToUser(address,uint256,uint256,uint256)","173e49b7":"BoomstarterToken(address[],uint256)","173ea238":"changeBtcOracle(address)","173ea341":"isPrivilegeAddress(address)","173f22f0":"rmin(uint128,uint128)","173fc012":"preSignedCheck(bytes8,address,address,uint256,uint256,uint256,uint8,bytes)","173febeb":"Send69Wei()","1740b479":"gameManagerSecondary()","1741526f":"getContractPayout()","17415d50":"_deleteRequest(address,address)","17421c8c":"withdrawAmountToken(address,uint256)","17431634":"LevelUp(uint256,uint32)","17436b1e":"RoundOpen(uint256,uint256,uint256)","1744215a":"EIP20()","1744cfe4":"GetLoansLenght(bool)","1744d5a5":"StageBonusUpdated(uint256,uint256)","17453358":"date01Oct2018()","1745422c":"addTx(address,uint256,string)","174609f8":"UNC()","17462891":"proofOfShit()","1746bd1b":"getGameInfo()","17473975":"breakDurationBetweenPresaleAndICO()","1747af0d":"AdminOwnershipTransferred(address,address)","1747b48b":"Reveal(uint256)","1747dfd4":"ContractPlay()","17484b0c":"RSOC()","17490da8":"modifyTrialDeadline(uint256)","1749bdf1":"getClassRank(uint32)","1749c16f":"isEnded(uint16)","1749e462":"getOwnersTokenList(address)","174a6277":"getTxDataBlockNumber(address,bytes32)","174a84d8":"BetComplete(bool,uint256,uint256,uint256,address)","174b0093":"createDefaultGen0Zodiac(uint256,address,uint256,uint256,uint256)","174b9fa4":"getCurrentDayDepositLimit()","174c2002":"burnAndDist()","174cd9b3":"lastBlock_a19()","174dcea8":"getBalanceAndHolderByIndex(uint256,address)","174e7d55":"isReadyToAction(uint256)","174efd12":"minBidValue()","174f51eb":"winOdd()","174fa48e":"distributeBTCG(uint256,address[])","1750f564":"newProposal(bytes32,address,uint256,uint8,uint256,bytes)","1751dc90":"createMultiplePhoenixes(uint256[],uint256[],uint256[])","175207b7":"_readBlockBeneficiary(uint256,bytes)","17528c7f":"ReceiverAddressSet(address)","175323a8":"contributeETH()","1753a655":"singBy(address)","1753d61c":"AirdropToken()","175466ee":"proofVerifyFailed()","17548962":"SPTI()","17549ff0":"lovelock_price_LOV()","1754bd8e":"minerState(uint256)","1754de57":"sendleftmoney(address,uint256)","1755ff21":"poolAddress()","1756ffd9":"addMonsterClassBasic(uint32,uint8,uint256,uint256,uint8,uint8,uint8,uint8,uint8,uint8)","1758078b":"trader()","175892b4":"previligedSubApproval(address,address,uint256)","17597b0f":"getLockedAmount_contributors(address)","175a0061":"install()","175a8bf4":"MigrationAgent(address)","175b0284":"closeChannel(uint256)","175b859d":"Bitwincoins(uint256,string,string)","175baaf1":"accrual(uint256,address)","175beead":"advisoryTokens()","175c6709":"TransferStatus(address,bool)","175c8640":"ZEEX()","175c9885":"POSSCOIN()","175d27e0":"MONTH_IN_SEC()","175ebfc7":"AdoptionOffered(bytes5,uint256,address)","175f6d9c":"JustAnIndex1()","17602ddf":"isFlowerAuction()","1760705f":"setAssetContract(address)","1761af6d":"upgrade(address,address,address,address,address)","1761eab4":"buyLong(address[2],uint256[5],uint8,bytes32[3])","17623c41":"isAllowedToParticipateNow()","17623e5b":"unauthorizeManager(address)","17634514":"creationBlock()","17634ec8":"freezeAccounts(address,bool)","176416ed":"getVotesBetween(uint256,uint256,uint256)","1764250a":"verifyWithdrawSignatures(uint256,address,address,uint256,bytes,bytes)","17645315":"migrate_participant(address)","1764dc3d":"GiveTokenPerm(address,address,bytes32)","17653b6e":"setChainRoot(address)","17655f6c":"transferOtherERC20Assets(address,uint256)","17659a1d":"Undelegate(address,uint256)","1766f424":"unsoldAllocationDelay()","17671962":"calcTotalWinnerKeys(uint256)","17674544":"deleteEntry(string)","17676e4c":"valueSet(string,bytes)","1767da08":"addBalanceForOraclize()","176854f6":"setLastJadeSaveTime(address)","176898c9":"setRefundStatus(bool)","1768b436":"ETCSurvey()","1768fd6f":"getMaxLockAmountAllowedByLtd()","1769511c":"fidaTokenAddress()","1769af29":"removeFromOwnerlist(address)","1769f049":"fee_balance()","176b0eac":"gcStartTime()","176b63f4":"seedSourceA()","176b6742":"EtherFlip()","176b866f":"alterBankBalance(address,uint256,bool)","176cd40a":"PUBLIC_OFFER_SUPPLY()","176d0780":"createMicroWallet(uint256,uint256)","176e5f32":"withDrawMoney()","17700f01":"disableTrading()","17701ee6":"mission()","1770616c":"tier3LOT()","17711a46":"setTokenTimelockFactory(address)","1771b7dc":"bids_burned_count()","1771d4d4":"setAliasPrice(uint256)","1771ece6":"updateHouseFee(uint8)","17727a00":"withdrawCapital()","1773234b":"kscBatchBurnWhenUseInSidechain(address[],uint256[],string)","17733eac":"yank(address[],address[])","177378f0":"testRegularBuy()","17738cef":"placeEMONTBid(address,uint8,uint256)","177413da":"bet(bytes32)","1774218e":"CRAToken(address)","17743338":"MakeClaim(address)","17749a16":"adminRefund(address,address)","1774df3e":"distributeMAGGIE(address[],uint256,uint256)","1774e646":"setUint8(uint8)","1774f6c6":"confirmPurchase(uint256,address,address)","17753c44":"DIGTREX()","17759493":"TotalPoSRequests()","1776683e":"payDev(address)","1776b437":"countInvestorsRefundedInCrowdsale()","177766e6":"getOptionChain(uint256)","17776b86":"ExhibitToken()","1778f1df":"ICOStartDate()","177a9e9d":"refundFor(uint256)","177b3010":"registerProject(string,string)","177b979e":"initiatecontract()","177bd86e":"syncSubscriptions(address[],string[],uint256[])","177c75ae":"offerIndexedPieceForSale(uint256,uint256)","177cf218":"UNIX_DAY()","177cfaa2":"teamTwoShares()","177d8ee4":"emitSkillsSet(address,uint256,uint256,uint256)","177dc9e5":"getCompte_15()","177dcde9":"_transferTokens(address,uint256)","177e0f71":"setLockedWalletReleased(address,bool)","177e6ae4":"ETHERFLEXCrowdsale(address,address)","177ea52d":"buyTokensSigned(address,bytes,uint256,uint8,bytes32,bytes32)","178003e1":"BCTopCraftCannabis()","178021e3":"saleFee()","1780eb18":"charityFundations(uint256)","17813d37":"BitGCoin(uint256,string,uint8,string)","17834d36":"isReachedHardCap(uint256)","178394bd":"LockedUnsoldTokens(uint256,address)","178407ca":"Board(address)","178450bd":"EbocoinToken()","1785478c":"_preValidatePurchase(address)","1785f53c":"removeAdmin(address)","1785f8dd":"PreTgeDisable()","1786351b":"AllbesticoContract()","1786e362":"orderTokensOf(address)","1787119c":"spendlarge(uint256,uint256,uint256)","17880b67":"getTotalBorrowingMonsters()","17888efc":"projectTokens()","1788de80":"enableTokenTransfers()","17897fcd":"RedRabbitToken()","178a8c8d":"accountsHolding(uint256)","178a8f34":"lotIdsByAddress(address)","178a9e2e":"tixGenerationContract()","178a9ffb":"HarborCrowdsale(uint256,uint256,address,uint256,uint256)","178ab6bb":"startICOStage8()","178af534":"createTokensWithoutReffer()","178afb39":"setSalesState(bool)","178b6de6":"getAllTokens(address)","178b8baf":"printCoins(uint256)","178b9d1a":"closeTicket()","178c02e9":"prometheusSoldCount()","178c17f0":"_createRandomNumber(bytes32,uint256)","178c4e40":"proof_of_public_key1()","178cec5c":"setBAU(bytes32,address,uint256)","178e6079":"APP_ADDR_NAMESPACE()","178ef307":"numberOfTokenHolders()","17904743":"bitpaintingStorage()","17905b2a":"Taur()","1790bd17":"contributorIndexes(uint256)","179101a6":"DECoin()","17916537":"clearDistributionDetail()","179194e1":"Bitnova()","1791cf01":"arr(uint256,uint256,uint256,uint256,uint256)","1791db21":"tokenMult()","1792b0bc":"transferTokens()","1792cc61":"tokenDecimalPlaces()","1793140a":"setO1(address)","179381d8":"setICOController(address)","1793b0f2":"addRecord(bytes32,string)","1793c314":"lastChance(address,address)","1794164b":"killcontract()","1794a463":"changeDevFees(address)","1794bb3c":"initialize(address,address,uint256)","17958e75":"omegaToken()","17961d0f":"ord()","17968fc9":"doPurchase(address,uint256)","1796b2ca":"unspent_supply()","17974399":"changeWithRef(address,address,uint256,uint256,address)","1797552b":"approveansCall(address,uint256,bytes)","1797814e":"IADOWR()","1797ec8a":"totalCrabTraded()","17986d83":"setRefferalFee(uint256)","17993e2f":"IREC()","17997878":"totalOwned()","179a5480":"masterresellercontract()","179ac197":"setOraclizeContract(address,address)","179b1b70":"LogFinalize(uint256)","179b51b1":"lotteries(int256)","179b73da":"killBoardProposal(uint256,address)","179c537e":"setSaleContractDepositAddressVerified(address)","179d375c":"addToken(uint256)","179dd216":"calculateMarketPixelPrice(uint256)","179dfbf3":"getBettingStatus()","179e91f1":"tokensLockedAtTime(address,bytes32,uint256)","179ef331":"nameRegistered(bytes32,address,uint256)","179fc99f":"etherBalanceOf(address)","179ffe76":"getMovie(uint256)","17a081bf":"queryTimestamp(uint40)","17a23ec6":"TOKEN_scaleDown(uint256,uint256)","17a2aaa4":"WithdrawalPremature(address,uint256)","17a2c026":"setCampaignEndDateById(bytes32,uint256)","17a3a329":"GLBX()","17a40e92":"updateAsset(address,bytes32,bytes8,uint256,string,string,address[2],uint256[],bytes4[])","17a432f5":"getActualPriceOfCardOnCraftAuction(uint256)","17a523c1":"useInsurance(uint256)","17a5d4df":"minTransactionAmount()","17a5f8cc":"createRatePlan(string,bytes32)","17a601b5":"MAX_STACK_DEPTH_REQUIREMENT()","17a650cc":"enter_square(uint256)","17a66006":"stageBaseRate()","17a689f3":"SuperSkyNet()","17a7cd10":"weeksFromCreation()","17a7eb4c":"vote02NoCount()","17a7f4cc":"feedOnKitty(uint256,uint256)","17a7f53e":"PriceHKGChange(uint256,uint256,uint256)","17a7f9b2":"countOfAddresses()","17a87b80":"changeInitialPrice(uint256,uint256)","17a950ac":"actualBalanceOf(address)","17a96982":"pullBounty(uint256)","17aa2899":"toB32(address,bytes)","17aaaea7":"BaseAltCrowdsale(address,address,address,address,bool,uint256,uint256,uint256,uint256,uint256)","17aad447":"FOUNDERS_LOCK_START_TIME()","17ab6cbb":"getRedCards()","17ac195a":"devTokensWallet()","17ac410f":"mintedtokens()","17ac896c":"GlobalBusinessSystemToken()","17adeb7c":"setClientProviderUID(address,uint256)","17adfa08":"confirmOneBuy()","17ae1f6c":"commission1()","17ae1fc5":"getIsActive(address)","17ae5d88":"unPreIco()","17af4d8a":"removeRoleAll(string)","17afa8a3":"set_refererPercent(uint256)","17afd19a":"decrementDID(address,address,uint256)","17b2e350":"deletePermissions(address,address[])","17b3a34b":"_addIdentities(uint256,bytes32[])","17b4c4d3":"META()","17b591e5":"closeContract(bytes32,bytes8,uint256,uint32,string,uint32,uint32,uint64,uint64,bytes32)","17b5f729":"_getAuctionIdArray(uint64,uint64)","17b65ae6":"hasEmployerMinRating(address,address,uint256)","17b75be6":"setBigICOStopped(bool)","17b7c328":"OpenPollCoin()","17b83aa6":"getSaleContractDepositEtherMax(address)","17b88dd7":"NEC(address,address)","17b98723":"isAuraSet(uint256,uint256)","17b9a28e":"calcWinner(uint256,uint256,uint256,uint256)","17b9e89c":"sumHardCapPreICO3()","17ba169a":"HybridEXToken(address,uint256)","17ba86af":"OpenContentIndex()","17bb0532":"AdminAddressChanged(address)","17bbcb6f":"newInvest(address,uint256)","17bd1251":"txsThreshold(uint256)","17bd927c":"testNewCounterValueAfterADecrease()","17be3fa5":"lockToken(address,uint256)","17be85c3":"getEntries()","17be89f0":"createTradeContract(address,uint256,uint256,bool)","17bf2671":"PDOne()","17bf8f50":"sendTokenFromDex(address,uint256)","17c0b0f9":"Escrow(address,uint256,address)","17c163e9":"ROLE_STATE_LOCK_PROVIDER()","17c201a1":"getRemainingMineSupply()","17c208a0":"EtherGirls()","17c24891":"completeInternal()","17c2d98b":"minSizeInvest()","17c2f390":"getNumberOfSuccessfulSteps()","17c3119b":"TeamAndAdvisors()","17c32a58":"latestPhaseNumber()","17c35e88":"deedName(uint256)","17c3925f":"encodeBillingMetadata(uint256,uint256,uint256,uint256)","17c39286":"getCars()","17c4c7bb":"getShipPriceById(uint256)","17c4f0a0":"autoReleaseTokenSaleJM()","17c4fcbf":"getExpectedGameSize()","17c51080":"getMyLockedFundsReleaseTime()","17c520f9":"CerttifyToken(uint256)","17c5838a":"stopMinting(string)","17c5fed8":"emergencyWithdrawalRatio()","17c63141":"getCountSenderCities(address)","17c65aa7":"getMaxLossAfterTrade(address,uint256,int256,int256)","17c6ee4f":"PaidOut(address,address)","17c70de4":"initiationTime()","17c73612":"ItlyCoin()","17c73ff0":"COMMISSION_WALLET()","17c83ed4":"getBindAddressAccount(address)","17ca1a6d":"getCrystalsSummary(address)","17ca2e41":"addBlacklist(address,bool)","17ca7f63":"getMintMarketMakerApproval(address,address)","17cacc1e":"_beingVIP(address)","17cb6426":"totalPaidOut(address)","17cbe981":"ChangeShipSellMaster(address)","17cc4138":"lastUETCWC()","17cc67b9":"firstRoundICOStart()","17ccf6a0":"rate5()","17cd4d5a":"setEtherPriceInEuroCent(uint256)","17cd802d":"repayment()","17cdb812":"TEAM_VESTING_AMOUNT()","17ce42bd":"addEntry(string)","17ce9aae":"getIsSecondPhaseByTime()","17ce9d68":"getMeshPointByName(string)","17cfd0d6":"house_edge()","17cfde55":"onSubUnHold(uint256,address,bool)","17d01716":"unregisterPair(address,address)","17d077af":"NamiPool(address,address,address)","17d0aa13":"TXOtoken(address)","17d18cd6":"_capOwO()","17d28620":"toggleTransferFor(address)","17d2e4e4":"realDevRewardWeight()","17d35f47":"setLocked(uint256)","17d3953f":"tmed()","17d48fc7":"getMigrationAccount(address)","17d4e24c":"EXT_COMPANY_STAKE_THREE()","17d51877":"cancelLine(uint256)","17d55d13":"timeLeftToBid(address)","17d5e4be":"testDrip(address,address,uint256)","17d60394":"Briant2Token()","17d6de15":"setSnapshotBalanceBatch(address[],uint256[])","17d70f7c":"tokenId()","17d7a154":"getShipTotalEarned(uint32)","17d7a47d":"sendOtherTokens(uint8,address,uint256)","17d7de7c":"getName()","17d8405a":"setUserAccount(bytes32,address)","17d86154":"setStartPrice(uint256)","17d8fd7a":"acceptedBookingfc(uint256)","17d928a7":"ClaimNFT(uint256,uint256,uint256)","17d94ad3":"isMinterAllowed(address)","17d9adb7":"stage_3_tokens_scaled()","17d9b4ab":"checkPromo(string)","17d9bfcb":"withdrawAndTransfer(uint256,address)","17d9c090":"isCharged()","17da485f":"getMiningDifficulty()","17db59a4":"dEthereumlotteryNet(address,address,address)","17dba48c":"GRAC2Coin()","17dbaf9b":"unlockFirst()","17dbe4f1":"burnPassportToken(address,uint256)","17dc86c5":"minWeiContribution()","17dc92f5":"cash(uint256)","17dd0873":"Winner(address,uint256,uint256,int256,string)","17dd4cc1":"getPreviousPrice(bytes32)","17de15ad":"GreHackCoin()","17de2f1f":"defaultOwner()","17dec7af":"distributionFixed()","17df1773":"StopIco()","17df5696":"finishPreSale4()","17df74f9":"availablePercent(uint256)","17df9a73":"findBid(address,uint256,bytes32)","17e01c95":"isClientBlocked(address)","17e04e55":"PoSatoshi()","17e0aeb8":"setPropertyEarnUntil(uint16,uint256)","17e0dfb2":"backAtIndex(uint256,uint256)","17e139a7":"lockedTokenHolder()","17e1b09b":"minimumDeposit(uint256)","17e1bfb7":"addInstitution(address,string)","17e22621":"joinGameWithInviterID(uint256)","17e2912f":"Amount_of_AOC_for_One_ETH()","17e30f6b":"TimeChainToken(uint256,string,string,address)","17e398a5":"seizedTokensWallet()","17e3f5fa":"callModifiedContractBalance()","17e49dc9":"ETH033()","17e50791":"FundsReceived(address,uint256,uint256,uint256,uint256)","17e51f21":"CrowdsaleController(address,uint256)","17e5259e":"ETH_MAX_LIMIT()","17e63b79":"centsPerMonth()","17e63bff":"setupICOPeriod(uint256,uint256)","17e6a087":"markFunding(address,uint256)","17e72721":"VLToken()","17e760bb":"votingAllowed()","17e7dd22":"getBooleanValue(bytes32)","17e875e3":"Transparancy()","17e95fbc":"releaseAdvisorsAccount()","17e9884d":"OG()","17ea4a79":"Took(address,uint256,uint256,uint256)","17eb85e3":"contractBoost(uint256)","17eba34d":"MIN_PRICE_IN_CENTS()","17ed31f4":"TIACOIN()","17edfb06":"trade(uint256,uint256,string)","17eef4cd":"setTotalTokensForPublicSale(uint256)","17ef67c6":"setContract1(address)","17efa370":"SmartTokenController()","17f143e1":"supplyExponent()","17f19efb":"ZoarToken()","17f1d65b":"hasIcoPhaseOneEnded(uint256)","17f1ee05":"paySecurityPool()","17f46c15":"getVoucher()","17f5de95":"MAX_TOKENS_SOLD()","17f5f53a":"XYTTEST()","17f6252f":"PRESALE_PERCENTAGE_4()","17f6c712":"ObjectPurchase(address,address,uint256,uint256)","17f708fb":"removeWhitelist()","17f7a530":"_computeNextMinerPrice()","17f80c13":"releaseJoyToken()","17f8252e":"tokenOwnerNumber()","17f95eac":"approveCloser(address,bool)","17f992ab":"SECOND_VOLUME_EXTRA_BONUS()","17fa664f":"callerDel(address)","17faa66f":"transferOwnershipWithBalance(address)","17fab0a0":"info(string)","17face84":"withdrawCommission(uint256)","17fad7fc":"batchTransferFrom(address,address,uint256[],uint256[])","17fb44c1":"returnAmountPaidBackSoFar(uint256)","17fb4d66":"Destroy(address,uint256,address)","17fb6c6e":"approveRequest(uint256,bool,string)","17fc01bf":"LegendsCrowdfund(address,uint256,uint256)","17fc3f55":"angelGoal()","17fc91f8":"holdAmount()","17fccb47":"erc20TokensContractAddress()","17fe375f":"getComments(address)","17fe5b79":"apolloSpecialTransfer(address,uint256)","17fe6185":"log(address,address,uint256)","17fe72bb":"setEnabled(address,bool)","17ff0caa":"WeatherBet(uint256,address,address,address)","17ffa830":"tixFounders()","17ffc320":"reclaimToken(address)","17ffd225":"KittyTrained(uint256,uint256,uint256,uint256[5])","17ffe171":"lock(address,address)","18004bba":"transferArrayBalanceForPreSale(address[],uint256[])","18005d93":"JinuToken()","1800c0fe":"extraTime()","1800e68e":"calculateTokens()","1800ed8e":"manager_address()","18015191":"transactions()","1801db43":"ExaCHF()","1801f00f":"newProposal(uint256,uint256)","1801f38e":"restart(uint256)","1801fbe5":"mint(uint256,bytes32)","1801ff10":"getAllContact(bytes32)","18024acc":"voteStartTime()","1802f969":"PokeCentral(address,address)","18037b78":"issuerJurisdiction()","18039230":"getPlayerGoodList(address)","180489ed":"Withdrawal(address,uint256,bytes)","18051c4a":"targetWei()","18054275":"executeSpins(bytes32,bytes)","180603eb":"registrationFee_()","1806874a":"amountLockedInVestings()","1806be68":"CompanyReserve(address,address)","1806cb4e":"getGiftSoldFromType(uint256)","180773de":"MAXIMUM_CONTRIBUTION_WHITELIST_PERIOD_USD()","1808c6b6":"setDividendsDistributor(address)","1808eeb8":"pending(bytes32)","180941f0":"setPredictions(int16,string)","1809549f":"updateAllComponents()","1809ced7":"sendEther(string)","180a3277":"sendDiary(address,bytes)","180a351b":"getByteFromByte8(bytes8,uint8)","180a42a3":"LifeSet_006()","180aadb7":"underLimit(uint256)","180afbf6":"DaxtherCrowdsale()","180b0d7e":"feeDenominator()","180b2607":"lastRelease()","180c0da6":"GlobalAssentToken()","180c0dfe":"maxBuyTokenAmount()","180c9309":"hasOracle(address)","180ca180":"CooperativeToken()","180cb47f":"GOV()","180da450":"addTierRateAndTokens(uint256,uint256,uint256)","180db1b4":"getErrno()","180dc318":"owners(uint32)","180ee30d":"forgivedChars(uint256)","180eebba":"accumulatedGasFees()","180f4c2c":"submitTotalBuyOrder(bytes32,uint256,uint256)","180f8f4f":"nextPrice2Of(uint256)","18117abb":"changeOwnerWallet(address)","18126325":"getOrganBlog()","18128ec7":"buyMorty()","1812982c":"fechAllForCandidate(uint256)","1812d2aa":"setBonusToken(address,uint256,uint256)","1812d996":"signature(bytes32,uint256)","1813b684":"preIcoEnded()","18158e6b":"BdpController(bytes8)","18159bf3":"_addSGCUsers(address)","1815ce7d":"setBackendAddress(address)","18160ddd":"totalSupply()","181670e6":"isApprovedOnceFor(address,address)","18167416":"officialGameUrl()","1816e794":"getMainsale()","18178358":"poke()","1817c5a7":"revokeGrant(address)","181a916b":"getKeys(address,uint256,uint256)","181aa1fd":"takeFee()","181b3bb3":"functionOne()","181b591a":"phase_4_bonus()","181be00d":"getValue(uint8)","181c8ef9":"enter(bytes8,address)","181d85eb":"internalRedeem(address,uint256)","181da773":"EosPizzaSliceDonationraiser(address)","181dcbcd":"setMaxConfig(uint256,uint256)","181e0124":"getRemainingTime(uint256)","181f1437":"permissibleWithdrawal(uint256)","181f1965":"fillSellOrderPartially(uint256,uint256,uint256)","181f4456":"setAuctionStart(uint256)","181f4477":"getLockedStructStartTime(address,address,uint256)","181fd85b":"cancelSale(address,bytes32)","181ffc5f":"GetGift(bytes)","182092a8":"ChangeSymbol(string)","1820b575":"Team(uint256,address,uint256)","1821cd93":"jackPotFunds()","1821e7c6":"acceptOffer(address,address,uint256)","1822b886":"createTradeOffer(bytes32,bytes32)","1822cbc5":"mintingIsAllowed()","1822f8db":"finishSafe(address)","18237476":"getAccountTotal(address)","18237e0c":"enableBuyback(uint256)","182439de":"claim_PreICOTokens(address)","1824461d":"administror()","18248f2a":"sendToken(address,uint256,address)","182493f2":"plantedOf(address)","182499fe":"ico_address()","1824a46b":"onUpgrade()","18253234":"ticketsAvailable()","182575f1":"authorizeFloor(uint32,address)","1825d0e8":"_mintCUSD(address,uint256)","18264f33":"startMigration()","1826fb35":"_calculateShards(int256,uint256)","1827caf4":"getInfoB(uint256)","1827edbc":"Reaper11()","18285e6b":"secondPlay(bytes32,uint8,bytes32,bytes32,uint256)","18287ef2":"executeOption(address,uint256)","18289482":"currentIcoPeriodStartDate()","1828983a":"authorizedUsers(address)","1828b254":"nextTicketPrice()","1828db82":"ownerPayout(address)","182930ce":"AddedToWhiteList(address,uint256,uint8,uint8)","1829b73f":"buyoutAmount()","182a7506":"setMinimumFee(uint256)","182ae5f2":"getVotesForItem(uint256)","182af96b":"regularEndGame(address,uint32,int256,uint256,address)","182b0b00":"checkChangeToReceive()","182b144c":"incrementBatch(address[])","182b434b":"newRequest(address,uint256,bytes32)","182d326e":"getTeamAddress()","182d709a":"scaleWeights(uint256)","182db370":"getWhatHappened()","182e0c49":"totalUnrestrictedAssignments()","182e7533":"getBetResult(bytes32,bytes32,bytes32,uint256)","182e8a67":"changeGroupActiveStatus(bytes32,bool)","182e9a1e":"getOwnerVehicleDetails(address)","182ee07f":"setDistributionMinimum(uint256)","182ef78e":"getTMul()","182f67a3":"reservedWei()","18300c1a":"CappedMintableToken(uint256)","1830d69d":"IsGot(uint256[],uint256[])","1830f493":"getPermission(bytes4)","1832425f":"registerAddress()","1833198f":"makeMemChange2(uint256,uint256,uint256,int256)","1833b7c6":"changeMyAddress(address)","1833fa4c":"update(uint256,string,uint256,uint256,uint256,uint256)","18342c9c":"BettingCore()","1834906c":"thisContractAddress()","1834ef4e":"addMoneyToContract()","1835e57d":"VESTING_DURATION_4Y()","183651d9":"tokenApprovalWithSignature(bool,address,address,address,uint256,uint256,uint256,bytes32,bytes)","18369a2a":"initialBalance()","183718d1":"getCheckoutTime()","18384df2":"getMetadataOf(uint256)","1838daab":"getRealmSale(uint256)","1839a417":"_cancelEthOffer(address)","1839babf":"zGetGameBalance()","183a7947":"pregnantKitties()","183abe66":"testRewardSB(string)","183b3159":"getAssetBalance()","183bfb4f":"AddBankerProfit(uint8,uint256)","183c5901":"DigitalGold()","183d255e":"SetWhat(uint256)","183d4cf7":"CNT_address()","183df5ef":"test_invalidSuicide()","183f9bcf":"isQuorum(address[3])","183ff085":"checkIn()","184018c6":"awardHighScore()","1840f0ca":"countVotes(uint256)","184188f2":"setStopTransfer(address,bool)","18423074":"ShowerToken()","18433bb7":"DrawPrepare()","18456048":"auctusTokenAddress()","18469491":"lastPlayerPaid()","18469dfe":"canStartDispute(bytes32)","1846d125":"isGroupExists(bytes32)","18476db4":"newRandomValue(uint256,address,uint256,uint256)","18477799":"Touch()","1847c06b":"ids(address)","18489f50":"thingExist(bytes32[])","18494108":"doPayout()","1849bd6a":"ExecuteTrade(address,address,address,uint256,uint256)","1849cb5a":"get(uint80)","184a9ce1":"Log2_fnc(address,bytes32,uint256,string,string,string,uint256,bytes1,uint256,uint256)","184ad5ff":"VjuCoin()","184b1912":"minimum_goal()","184b9559":"init(address,address,address)","184bd394":"changeSaleAddress(address)","184c703d":"LogVoteInitiate(uint256,uint256,uint256,uint256,uint256,uint256)","184d009b":"teamNameIndex(string)","184d1a77":"acceptBid(int256,int256,int256,int256)","184d69ab":"isWhitelistEnabled()","184db3bf":"initErc20Deal(bytes32,uint256,address,bytes20,bytes20,address)","184e8549":"getPI_edit_31()","184fb2bd":"signOwnerCount(uint256)","184fd65e":"addMomRelation(address)","184ffd9d":"RATE_CROWDSALE_S2()","18501714":"clearJackpotParticipantsAfterDistribution()","185061da":"undoIt()","18507210":"templatesOfOwner(address)","185190f6":"addCustomerwithETH(address,uint256,uint256)","1851e59e":"Omnidollar()","18520be5":"EventBid(uint32)","18520de3":"sendFrom(address,address,address,uint256,uint256)","1852e8d9":"calculateReward(address,uint256)","1853d033":"GetAskingTokenBought()","1854229a":"REFERRAL_BONUS_LEVEL1()","1855e405":"managerOff(address)","1856a6df":"coupleImageIPFShash()","1856bc0f":"BuyGenesis(address)","1856c1dc":"main_sale()","1856e01b":"setVotingController(address)","18573bf9":"calculeReward(uint256,uint256)","18577f8d":"calVote(address)","18579ece":"clearances(address)","18584a5d":"hasAlreadyPlayed(address)","185870f9":"developerWallet()","1858cb5b":"verifyProof(bytes,bytes32)","185917c5":"distributeToFound(address,uint256)","1859b2d7":"getDStructData(address,uint256)","1859c8e2":"getUserTicket(uint256)","185a5671":"setTransferAddress(address)","185a6284":"discountedMiningTarget(address)","185a7daf":"FundingRules(uint256)","185b9067":"QuadCoin()","185c4279":"hardCapCHF()","185cc751":"loan(address,uint256)","185d1af6":"setUncirculatedSupplyCount(uint256)","185d9e79":"AOL(uint256,string,uint8,string)","185e00fd":"getDisputeStateText(uint256)","185e4a00":"getCurrCanRefund()","185e9969":"getContractDetails(bytes32)","185f23c4":"_arbitrationPercent()","1861355b":"transferMintOwnership(address)","1861cb28":"getNowVestingType()","1861e523":"testOwnerToken()","1862c10b":"withdrawBalancesToLogic()","1862caec":"firstStageMinting()","186415c0":"releasesollidaTeamTokens()","18643d37":"raffleLimit()","1864db71":"getCompetitionInfo(uint256)","18656a1e":"founderAmount()","18659adb":"starbitWallet()","1865c57d":"getState()","186601ca":"activated()","1866191a":"editDiscount(uint256,uint256,uint256)","186690b0":"broadcastMessage(string)","1866ae7d":"PayRollHistory(address)","1866f761":"ConstantaToken()","18671d23":"Auditor(address,address,address)","1867b937":"_bytesToBytes32(bytes)","1868291f":"getIp(string)","1868516d":"KMEToken()","1868c2a1":"computeSeed(uint64,address)","18695c4d":"DSToken(bytes32,uint256)","1869a084":"releaseLockedBalance(address,uint256)","186b6f05":"updateFallbackDeposit()","186b79c9":"isProviderInitiated(address)","186ba9de":"lastUnlockMineBalanceTime()","186bbb05":"getAppCode(bytes32)","186bcaf0":"ontology()","186c9b11":"issueTokens(uint256,address,uint256,uint8[],bytes32[],bytes32[])","186cd7d2":"card_black_first()","186d9ce8":"allowAvatarCreation()","186d9d88":"unblockAddress(address)","186db237":"ecosystemBuildingTokens()","186e378a":"CCH_EDIT_4()","186e4297":"charityCut()","186e7047":"forceAdvance()","186eb86b":"cnt_per_eos()","186f0354":"safe()","1870082d":"inviteCollateralizer()","187047b5":"LogUserAdded(address)","1870a73a":"totalNTD()","1870ad14":"setAddress(string,address,bool)","1870c10f":"donateAndCreateGiver(address,uint64,address,uint256)","18714bc8":"purchaseWithFiat(uint256)","18718656":"XENCToken()","1873355e":"Emoji()","18737e07":"Redeemed(uint256,address,address,uint256)","18758480":"worldContract()","1875aa22":"transferWhiteList()","1875ccf3":"setGlobalCompositionFee(uint256)","18760eb3":"RequiringAuthorization()","18764471":"ANTDToken()","1876d0a9":"astutelandToken()","1877fc8a":"quickSort(address[21],int256,int256)","1878265a":"Rent()","1878d1f1":"ETH_TOKEN_ADDRESS()","187958ac":"VOCToken()","18797499":"ENTERED_MASK()","18797c35":"emitAccountFrozen(address,uint256)","1879c2da":"NewSale(address,uint256)","1879dcf3":"MIN_TOKEN_PRICE()","187a62d5":"voteEmergencyWithdrawal(bool)","187ac4cb":"migrationManager()","187adf2e":"failsafe_subtract(uint256,uint256)","187b1f2a":"VOZToken()","187cba25":"issueNomins(uint256)","187cbdd2":"subWallets()","187d2371":"LOG_MaxInvestorsChanged(uint256)","187d3954":"getClaimableBalanceFor(address)","187d8803":"updateKoCommissionAccount(address)","187ecd37":"Open(bytes)","187ed86e":"ROE()","187f707b":"AdvertisementFinance(address)","187fac20":"setStartStage1(uint256)","187fd079":"MINI_GAME_TIME_DEFAULT()","18804b0d":"setDescriptionHash(bytes32)","1880692f":"getPublicKeyCount()","1881656b":"canSpend(address,uint256)","1881b0f0":"kycVerify(address)","1881f980":"read_i64()","18821400":"TOKEN_NAME()","1882d267":"liquidityFundAddress()","18836994":"get_allowance(address,address)","1883d2a4":"IUPToken()","1884c517":"registerWorkerAffectation(address,address)","18856694":"deny(bytes8)","1887af2b":"LogicBase(address,address)","18886657":"purchaseLimit()","1889500c":"marketplaceManager()","18896972":"isBuyFull()","18898452":"saleMinimum()","18899745":"AffiliateMarketing(address,uint256)","1889fc0a":"_preValidateReserve(address,uint256,address)","188a1d68":"getOuverture_des_droits()","188b5372":"generateToken(address,uint256)","188b81b4":"getGameEnd(uint256)","188c668c":"recordDealRefundReason(uint256,address,uint32,uint32,uint256,string)","188cad26":"referralTokensAllocated()","188d0aae":"buyAndCreateGame(uint256,uint256,address)","188dbc1a":"setAccountIsFrozen(address,bool)","188ec356":"getTimestamp()","188f1fee":"notifyObservers(address,address,int256)","188fdbdc":"commission_rate()","189048fc":"getAccountLevel(address)","189052ac":"_setFreezingPeriod(address,bool,uint256)","18911bbe":"ProdFToken()","1891381d":"setROI(uint256)","1891c701":"AssignOwnerToProject(int256,address)","18921de4":"addSignature(string,uint256[],uint256[],uint256[],bool[],uint256[])","1892c15a":"fwdPayment(address)","18940084":"_getDestinationTranche(bytes)","18942a33":"new_record(address,address,uint256)","18946e8f":"voteOnParameter(bytes32,int256)","18954b3e":"collectEstimation(int256)","18955b1e":"willThrow()","1895687d":"issueLoan(address,uint256)","18958959":"individualClaim()","1895e858":"resetWallet()","1896367e":"setBlockSze(uint256)","18968a03":"finalize(uint256,address,address)","1896f70a":"setResolver(bytes32,address)","18976fa2":"closeVault()","1897bcf3":"sellToken(uint256,uint256)","1898a1c7":"addVendor(address,string)","189959de":"EXPC()","1899f1ad":"setChargerAddress(uint256,address)","189a5a17":"nodes(address)","189ae13c":"numArbiters()","189af42f":"powsm(uint256,uint256)","189aff3a":"authorizedSupply()","189b11fc":"AddSeed(address[])","189b600c":"setNameHashByWriter(bytes32,address,bytes32)","189c94ae":"testFallbackStaticSig()","189ca316":"setVoteWeight(uint256)","189d165e":"setBurnRate(uint256)","189e688a":"ClaimDividend(address,address,uint256,uint256,uint256)","189eeebe":"isMembershipAllowed(address)","189f0197":"getPlayersPick(string)","189f4d34":"setMinUCCoinSellingValue(uint256)","189f9041":"mintCoreToken(address[])","18a08d2d":"TheTokenH()","18a0e773":"UnlockGrant(address,uint256)","18a17df1":"DataDump()","18a24b5b":"unlockToken()","18a30d16":"getResponse()","18a39c54":"payForward()","18a3aad2":"ReserveCoin()","18a4155e":"calculatePrice(uint256,uint256,uint256,address,uint256)","18a45c41":"_receiveFundsUpTo(uint256)","18a51621":"getReadableSupply()","18a54ecd":"mintTokenForPrivateInvestors(address,uint256)","18a6217d":"comments1()","18a66563":"AQI()","18a689aa":"getNamePicture(bytes32)","18a6bc32":"tokenDistributor()","18a6d58b":"addTokenTeller(address,uint256)","18a6d765":"BANKROLL_LOCK_PERIOD()","18a6dec5":"getCountTokensByGame(uint32)","18a7bad6":"setFreezeAdmin(address)","18a8fac9":"icoInvestment(address,uint256,uint256)","18a94030":"putStoWithBtc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","18a991f7":"setEmeraldPrice(uint256)","18a9cc1b":"isUser(uint256)","18a9f29f":"setMetadata(uint128,string)","18aaaa51":"registerTickets(uint256)","18ab8888":"paymentSortId()","18ab8c37":"timeToCalm()","18abb75c":"createLibraryBounty(string,string,address,uint256)","18abfdfc":"totalSupplyFromCrowdsale()","18ad052b":"safeTransferByContract(uint256,address)","18ad28af":"icoWasSuccessful()","18ae15e4":"DBC(uint256,string,uint8,string)","18ae19c2":"get(bytes32,uint256)","18ae21e8":"NuoYiLian(uint256,string,uint8,string)","18af26fe":"setRestrictedWallet(address)","18af4099":"PARALLELNETWORK()","18af5e74":"addressesDeposited(address)","18af7021":"force_refund(address)","18b03ceb":"remainderPurchaser()","18b0bdf7":"getMensaje(uint256)","18b0efb6":"isEmptyName(string)","18b123d5":"hasBeenApproved(address,uint256)","18b15e2a":"Ongo()","18b20071":"setCurrentPrice(uint256)","18b2739d":"giveEthJackpotAddress()","18b31f94":"registerLengthFunction(string,string,address)","18b322a4":"update_instant()","18b38777":"fuzexAccount()","18b3a119":"getCrowdsaleMaxRaise()","18b3b58b":"Hamza__Coin()","18b3c724":"forceRecoverCollateralOnBehalfOfRecurse(address,address,bytes32,address)","18b3cd45":"qwecoin()","18b40adf":"maximumCirculation()","18b437aa":"COMMERCIALPOINTCHAINSYSTEM()","18b49ba4":"AMPIToken()","18b4a702":"EPACOIN()","18b4a924":"week_max()","18b64d5b":"unmint(int256,uint256)","18b749c4":"payEther(uint256)","18b7bb11":"EthRoi()","18b7fed8":"deliverPresaleTokens(address[],uint256[])","18b8275a":"addUser(string)","18b919e9":"ROLE_WHITELISTED()","18ba4218":"countAssetEvents(bytes32)","18ba5cdc":"ownerAddToWhitelist(address,uint256)","18ba6973":"setTrainingFormulaContract(address)","18bb2edb":"maxRegistrants()","18bb7c08":"_setNameToAddress(address,string)","18bbedf4":"Bulletin()","18bcd3d0":"transferOwnership(address[])","18bd21f9":"_purchase(uint256,uint256)","18bd387a":"level_referrals_count_by_address(address,uint256)","18bd5108":"stopCrowdsaleTime()","18bd710b":"NewGirl(address,uint256,uint256,uint256,uint256)","18bd8dcb":"ufoodoToken()","18bdb1b0":"StartdateICO()","18bdc79a":"payOwnerOnly()","18bdffbb":"verifierAddress()","18bee97e":"Creator()","18bf0225":"etherFundsOf(address,address)","18bffce9":"voteToResult(uint256)","18c0e04f":"purchaseStake()","18c10ad0":"disabled(uint256,uint256)","18c1d9b2":"bonusWallet()","18c1fc68":"buyOne(address,address,uint256,bytes)","18c20f44":"entrarAJuego(uint256)","18c26389":"multivestMint(address,address,uint256,uint8,bytes32,bytes32)","18c2d4c9":"initialSingleWithdrawMin(uint256)","18c306bd":"checkSignatures2(bytes32,bytes,bytes,bytes)","18c3cf34":"EthPriceProvider()","18c41a80":"mint(bool)","18c48e96":"bitRegisters(address)","18c53aca":"tokenIsComponent(address)","18c5bddc":"PRESALE_THIRD_DAY_START()","18c5e3af":"addInvestmentProposal(uint32,bytes24,uint256)","18c5e502":"GetTime()","18c8bda5":"Procare()","18c93884":"_setCrowdsaleStage(uint8)","18c9ef97":"mintETHRewards(address,uint256)","18caa857":"emitJobBinded(uint256,uint256,bool)","18cc4c65":"startEngines()","18cd55f3":"canCreateGrants(address)","18cda1e7":"lockInternalAccount(address,bool)","18ce1a23":"BailOutToken()","18cee8a4":"setPlatformCommissionRate(uint256)","18cf1c25":"lookupDonation(uint256,uint256)","18cf85d1":"adminSetCityData(address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","18cfa483":"invalidate(address,uint256)","18d0073e":"startNextMilestone()","18d0122a":"upgradeAgentStatus()","18d0376c":"getFastGap()","18d0a7cc":"incentFundAddress()","18d0c322":"EtherLambosCore()","18d0eb93":"finalizeAndDistributeToken()","18d30bfa":"setLastMoveTime(uint16)","18d32128":"CLVRCrowdsale()","18d43f0d":"userTokensValues(address,address)","18d4b4b3":"COCCToken()","18d4e834":"getPrivilegeState()","18d62bc6":"PHXFlip()","18d6676c":"entityStructs(uint256)","18d69faa":"StopDistrib()","18d74c37":"deleteShare(address)","18d760be":"LogFinalize(bytes32,bytes32)","18d76b78":"CCIToken()","18d78358":"ICOCENTRAL()","18d80168":"startUnitRaffle(uint256,uint256)","18d80d4a":"check_prize()","18d84553":"calculatePayout(bytes32)","18d8ec5b":"validateWinnersCount(uint32,uint32,uint32)","18d8f9c9":"erc677token()","18d92a5d":"getRegistryDataCustodian()","18d95092":"domainOwner(string)","18d97731":"setPriceStep7(uint256)","18da0011":"treasuryContract()","18da650d":"WithdrawalInterCrypto(uint256)","18da754a":"setBuyMinLimit(uint256)","18dad1cd":"multiTransferFromValues(address[],address[],uint256[])","18db02e1":"etherToLEONRate()","18db0750":"contributionReward()","18db62fb":"checkValue(uint256)","18dcdfbe":"isRetirementAllowed(uint256,bool)","18dd97f0":"secondStageTokensForSale()","18de0afd":"getEnabled()","18deb066":"init(uint8,uint256,uint256,uint256,address[2],address[],uint256)","18debd27":"addWalletAddressAndTokens(uint256,address,uint256)","18def2a1":"DistributedCreditChain()","18df02dc":"Migrate(address,address,uint256)","18df11ee":"SpendingApproved(address,address,uint256)","18df6090":"mintBountytokens(address)","18dfcf7b":"_investorCount()","18e01199":"burn(uint256,bytes,bytes)","18e02bd9":"setTokenOwner(address)","18e0d683":"getBAI(bytes32,address)","18e124e4":"upgradePackageCountOf(address)","18e146f9":"InvestmentPolicyChanged(bool)","18e2d679":"describeTile(int32,int32)","18e2e4be":"getInvestor(address,address)","18e37cdd":"ITGToken()","18e3b44c":"setMemory(uint256,uint256)","18e3d998":"crowdSaleEndTime()","18e45427":"whitelistedContract()","18e4ac35":"isConfirmed(address)","18e4c3f3":"GMOON()","18e4d2db":"_AIExchangeSupply()","18e536bc":"comissionList()","18e6ab9c":"funding(address,uint256,uint256)","18e75a1c":"PresaleEDUSupply()","18e7eb4b":"PRE_SALE_1WEEK_BONUS()","18e857ab":"queried(uint256)","18e9e7ab":"listSimpleService(uint32,string,uint256,address[],address)","18eacb96":"GetDivs(address)","18ebcc8c":"takeOrder(uint256,uint256[5],uint256[3],bytes32[3])","18ecc6f4":"getTotalDividendsRounds()","18ece632":"superApprove(address,address,uint256)","18edf434":"_revokeConfirmation(uint256,address)","18ee00b6":"_changeRate(uint256)","18ee1b9f":"WithdrawEther()","18ee9d5e":"EtherIncognito()","18eeef80":"Wallet1()","18ef7adb":"transferAdvisorTokens(address,uint256)","18f0db29":"remainingBettingFor(uint256)","18f11de2":"BSSCoin()","18f2217a":"EPXtokenSupply()","18f2a0bb":"ownersConfirmedTransactions(address)","18f303a1":"SetInternalValues(uint8,uint256)","18f3a50d":"cooAddress2()","18f3fae1":"setOversight(address)","18f61c0d":"configRunTime()","18f729da":"founderLockance(address)","18f76a2c":"getCCH_edit_3()","18f7d5ad":"lastBlock_f13Hash_uint256()","18f80bb9":"createContract(string)","18f839bd":"Expensive()","18f873df":"chAllowTransfer(bool)","18f889c2":"setOracleGasPrice(uint256)","18f9266c":"talks(bytes32)","18f95486":"openPendingPartCrates()","18f96441":"getShipDetails(uint256)","18f96857":"Lazadex()","18f9b023":"addPayee(address,uint256)","18f9bdee":"allocationOpen(uint256)","18fa11ab":"revokeRequestorAddress(address)","18fa223a":"GGCT()","18fb75f4":"callDeposit()","18fc6513":"companyCurrentPeriod()","18fd3474":"HumaniqICO(address,address)","18fd8903":"refund(address,uint256,uint256)","18fdcaba":"getSumAmountOfDisputedDealsProDoctor()","18fe1a8d":"banToken(address)","18fed50a":"getLast4Bytes(bytes32)","18ff1361":"manualyMintTokens(uint256,address,uint256,int256)","18ff318d":"thorToken()","190038dc":"supplyAdjuster()","190042b8":"CARA()","19006185":"getNumRefundTransactions()","1900aabf":"CollectChips(uint256)","190108b5":"getAyantDroitEconomique_Compte_3()","190151c6":"_createNumber(uint256,uint256)","19018557":"COCToken()","19022f20":"TTT()","1902e902":"adjustEntitlement(address,address,uint256)","190377a5":"getCategory(string)","1903bbe0":"_getQueryStr(uint256,uint256)","1903c10e":"setPI_edit_3(string)","190406b3":"customExchangeSecure(address,address,uint256)","19045a25":"recover(bytes32,bytes)","19055df2":"preSaleTokenExchangeRate()","19058903":"NewPassProject(address,address,string,string,bytes32)","1905fbf6":"setNewWallet(address)","19062b8f":"settleTransaction(uint256)","190663e4":"setGreeter(string)","1906ff98":"getVotePrice()","19077dca":"resetOwnership()","1908c425":"m_leeway()","1909773f":"get_milestone_information(uint256)","1909787f":"NextMint(uint256)","1909d314":"GCPrightToken()","190a2688":"changePrices(uint256[3],uint8)","190a597b":"restartCrowdsale(address,uint256,uint256,uint256,uint256,string)","190a6aa9":"burn(address,uint256,bytes,bytes)","190a8613":"getNodeLeftChild(bytes32)","190a867e":"testThrowNoPartialTokens()","190bc9d4":"w_Advisers()","190bfa4d":"singleDVIPQty()","190bfcd0":"initialTokenValue()","190bfea8":"sellWei()","190c23c4":"adminSetTxFeePaidGame(uint256)","190c69a2":"unWhitelistUser(address)","190d9253":"testInitialContract()","190e4c77":"numOfProperties()","190e8266":"makeProduct(string,string,uint256,uint256)","190eaaba":"getDenominator()","190ef61d":"readAnalyticsMap()","190f4cfc":"doCalculate(uint256,uint256,uint256,bytes32)","190fe712":"payoutETH(uint256)","19110d05":"DTCC_ILOW_8()","19113b4a":"changeStatement(string)","19123c1f":"magnitude()","1912f84f":"BONUS2_LIMIT()","191313ae":"EndOfPayments(address,uint256)","191347df":"setStr(string)","1913742f":"appendSchellingSupplyChanges(uint256,uint256,bool)","191384d1":"viewMessage()","19141100":"bankRollDivest(uint256)","1914427f":"MultiSigWalletWithDailyLimit(address[],uint256,uint256)","19154616":"FART()","1916037d":"withReferrer(address)","19162a30":"getYumWithETH(uint256)","19165587":"release(address)","1916fcb7":"Galaxy100()","191723ed":"lockBalance(uint256,uint256)","191797df":"isStoped()","1917ab5c":"activate(string)","1917e6d1":"addDoctor(uint32,string,uint16,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","19190495":"SimulateCurrentDate(uint256,string)","1919cf62":"allEthShares()","1919fed7":"setSalePrice(uint256)","191ad190":"open_free()","191af4bc":"thirdroundprice()","191b548e":"VIVACrowdsaleRound(bool,uint256,uint256,bool)","191b8260":"_createScene(string,uint256[],address,uint256)","191be7b7":"getQueryResults(bytes32)","191d7a7a":"TVToken()","191d8cd7":"passToken(address)","191e39b3":"setOwnerCut(uint256,uint256)","191e521f":"moken(uint256)","191e8daa":"_getRand(uint256)","191f06e7":"setEscrowFactoryContractAddress(address)","192014f4":"buyKeyWithReff(string)","1920b2a6":"BitOnBayToken(uint256,string,string,uint256)","1920ed48":"isOwner(uint32,address,address)","19213471":"addFRA(address)","192159a6":"ListingCreated(uint256,uint256,uint256,uint256,address)","19216c4d":"getPreIcoInvestorsCount()","19216e8d":"freezeForOwner(uint256,uint256)","19218eda":"secondTokenExchangeRate()","192193b9":"transferFrom(address,address,int256)","1921c454":"priceChangeBlock()","19220c69":"TAKLIMAKAN()","1922936d":"RegisterTransferBeneficiaryContract(address)","1922e9b4":"getJobApprovals(uint256)","1922ff39":"payOut(address)","1923350f":"ADVISORS_TOKENS()","19236b4e":"getSanTimeAlive(uint256)","192399d1":"vestingBalance(address)","1923a4a3":"issuePercentToReserve(address,uint256)","1923e5d4":"noActiveBallotExists()","19240661":"setTrusted(address)","19245155":"StartedSafeUnlock(uint256)","1924f74a":"PVP_INTERVAL()","1925259b":"ShroomFarmer()","19254e2e":"getInsuranceStatus(address)","19261e6f":"setERC20ApproveChecking(bool)","1926b63d":"savePost(bytes32)","1926de89":"readInt256(bytes32)","1927a754":"drainEther()","1927a8ea":"listFiles(uint256,uint256)","19287f3a":"withdrawBalanceAll()","1928b3cb":"getPosition(bytes32)","19291c74":"getGoldStatusLastauditid(address)","192a4422":"safeWithdrawalAmount(uint256)","192b3092":"mintPreAllocatedTokens()","192b3608":"Bond(uint256,string,string,string,uint128,uint128,uint128,uint128,uint16,string,string,address)","192b663d":"vestSupply()","192b7700":"CitrusCrowdsale(address,address)","192d65c9":"getRoundByRId(uint256)","192e571d":"getPlayerByName(string)","192e7a7b":"releaseFunds(address)","192ecd68":"getDistrito(uint256)","192f1076":"crowdsaleEndDate()","193080cb":"getLockedContract(address)","1930fc01":"FastmarketNetwork()","193115b4":"changeHiddenOwner(address)","193118fa":"CPCCrowdsale()","193237f5":"_isValidSignature(address,address,bytes)","1932bb33":"lastBlock_a12()","19337d6c":"setLink(string)","193402bb":"PRE_SALE_PRICE()","1934d55a":"isPermanentlyApproved(address,address)","19350aea":"nameFor(address)","19354750":"setRegistryLogic(address)","1935f8d2":"Instacocoa(uint256,string,string,address)","19362921":"CONTRIBUTORS_SHARE()","1936a8cd":"getSeedByWinner(uint256)","1936dd8f":"writeMessage(string,string,string,string,string)","1936e4be":"advisor()","19375602":"challengeOwner()","1937714b":"confirmDeployment(uint256,address,bytes32)","1937b7fa":"Burnfrom(address,uint256)","1938a238":"softcapInTokens()","19397ed0":"Transfer(address,address,address,address,uint256,bool)","1939805f":"TPPC2018Token(uint256,string,string,uint256)","1939c1ff":"transfer(address[],uint256)","193a4249":"minFunding()","193a824e":"_escrow(uint256)","193a8a83":"getCCH_edit_28()","193c114b":"transferTokensOut(address,address,uint256)","193c8da4":"AkikToken()","193c9be1":"getCreateShareToken(uint256)","193ccc20":"depositTokenToUser(address,address,uint256)","193d5b77":"getGiffBlock(uint32)","193df7ea":"addBlacklist(address,address)","193e06c4":"CalcPeriod(address,uint256)","193e6679":"MarginBanc()","193f69a1":"getPhaseBonus()","193fc711":"_getBeginIndexKey(uint256)","19404c2f":"replayAnserWithReferrer(uint256,uint256[],string)","1940a936":"isPregnant(uint256)","19424222":"approveAndCall(address,uint256,bytes32)","1942c3ce":"_transfer(uint256,address)","194307bf":"terminated()","19447eb6":"userStructs(address)","19449cb2":"changeAuthorizedCaller(address)","1944bc3d":"priceThresholds(uint256)","1946283a":"CarRegistrationFailed(uint256)","19465953":"changeInfo(string)","1946fdf4":"logicVersion()","19476244":"icoNumeratorPrice()","1947bd2f":"getMap(address)","194809a6":"finalistTeamFIFAIdsSet()","19483cd1":"checkHash()","19498426":"BOUNTY_REWARD_SHARE()","194a7adc":"CONNECT(uint256,string,string)","194b546b":"_addRec(uint256)","194b81d0":"TGxToken()","194c78d0":"setApp(string,uint256)","194c8e15":"Update_START_ICO_TIMESTAMP(uint256)","194d0de2":"createOrder(address,uint256,uint256,address,uint256)","194d297f":"canSend(bytes32,address,uint256,bytes)","194dee32":"setTokenForSale(uint256,address)","194e10ce":"run(bytes,uint256)","194e4acd":"reqvehreg(address,string,string,string,string)","194eb01c":"CimbomCoin()","194f4795":"getItemsLength()","194f8806":"setMigrationHost(address,address)","194f97ba":"setColorGreen()","194fe9a4":"transferWithBonuses(address,uint256,uint256)","195055f1":"isTransferable(address)","19507d2c":"allowedToTransfer()","19509649":"ImpactRegistry(address,uint256)","1950c218":"checkWhitelist(address)","195199f6":"setDeadline(uint256)","1951f9ba":"isRequestPending(address)","19530f76":"multiTransferFixed(address[],uint256)","19547404":"sendTokens(uint256,uint256,address)","1954f39e":"EndDate()","195629de":"initMETToken(address,address,uint256,uint256)","195743fc":"claimSMRforAll(uint256)","19583b05":"modifyCollectorAddress(address)","1958623f":"BitcoinPluse()","1958ccb1":"setParams(address[],uint256)","195977a6":"emit(uint256)","1959a002":"userInfo(address)","195aa377":"SportsChainToken()","195ad926":"authenticate(uint256)","195b616c":"_unmountSameSocketItem(address,uint256,address,uint256)","195d06ff":"addBigPromoBonus()","195de8a1":"CapReached(address,uint256)","195e38b2":"EnergyModulationProject()","195e8688":"Osiris()","195ec9ee":"getAllParticipants()","195f4807":"getTotalPayouts()","195fa903":"ownersNum()","195fd221":"issueAmount()","19608123":"Vetricoin()","1960d761":"AccommodationCoin()","19617fe4":"coinBurnIco()","19618a9b":"testDivideFractional()","196198fa":"getDepositWithdrawCount(address)","1962d041":"SayadyToken()","1962df71":"_performTransferWithReference(address,uint256,string,address)","19638ca5":"CryptolifeToken()","1963a0d1":"OWN_freezeAddress(address,bool)","1963a693":"IncreaseAllowance(address,uint256)","1963df66":"dtGetWorldData()","1964569b":"Aktium()","1964dcbf":"SCCCOIN()","19656b46":"teansferFrom(address,address,uint256)","1965e183":"MIN_TOKENS()","19663f7f":"TransferAmountFromBankAccountToAddress(uint256,address)","196667e4":"start_amount()","1966cdbe":"pickWinner(bytes32,uint256)","19677635":"TEAM_SALE_MULTIPLIER()","19679680":"emptyInactiveToken(uint256)","19682b09":"DonationDeposited4Doubling(address,uint256)","19689e76":"paySemiFinalWinner(uint256)","1968bf4f":"getPersonalStakeUnlockedTimestamps(address,address)","1968c160":"addPaymentDetail(address,bytes32,uint256)","1969c21a":"removePixelsFromMarket(bytes32)","196be409":"DLTESTToken(uint256,string,uint8,string)","196c16cb":"tokenPriceInEth()","196c9909":"_bounty()","196cd388":"isRangeInsideRange(uint256,uint256,uint256,uint256)","196e5c46":"sellSeeds()","196ecd25":"getOwnedCount(address,uint256)","196ee9c7":"remainingCats()","196f5851":"transferAgents()","196f9aa5":"getLedger(uint8)","196fa707":"GAMEMAGICERC20(uint256,string,string)","19711d67":"campaignDurationDays()","1972172b":"satLimit()","19726b4e":"TheGoDigital()","1972b464":"emitJobOfferPosted(uint256,address,uint256,uint256,uint256)","1972c8dc":"Eggfrenzy()","19739117":"checkSignatures(bytes32,uint256[3],bytes,bytes,bytes)","1973c5de":"icoPreEnded()","1973cae7":"nextPriceDate()","1973e795":"setWorkpointSupportCancel(uint256)","197425c4":"testSupplyOf()","1974a003":"_startAuction()","1974a540":"RoundIndex()","1975a9e7":"o_deus(bytes32,bytes32)","1976804a":"TTCoin(address)","19774b86":"bulkWhitelistInvestor(address[])","19774d43":"orderFills(address,bytes32)","19775795":"aquariumCost()","1977bd68":"pepePremine(uint256)","1977f5c6":"Anubis()","197828b1":"bucketHolding(bytes32,address)","1978658b":"setCaps(uint32[],uint256[])","1978a87b":"TokenERC20()","197a1976":"setInvested(address)","197a2820":"depositarLucro()","197a9187":"NodeAction()","197b9454":"paintingsCount()","197bc336":"holderAt(uint256)","197c0f3d":"createPool(address,address,uint256,uint256,uint256,uint256,uint256,uint256)","197c3555":"getPlace(uint256)","197c418f":"MyAdvancedToken7(uint256,string,uint8,string)","197cb5bc":"balanceLockedUp(address)","197d24ad":"changeModuleOwner(string,string,address)","197ea97e":"mintAsideTokens()","197f3c29":"notLike(address)","197f8a82":"claimReveralTokens(address,uint256)","197f9508":"_getExchgAddr()","19806d8e":"s11(bytes1)","19810f3c":"withdrawShares(uint256)","19811fc9":"TPOMZ()","1981d521":"participate(uint8)","19825187":"changeMinToken(uint256)","1982640c":"walletOf(address)","1982c626":"withdrawOverpay()","1982ed58":"ChangeReuseCashInHarware(bool,uint16,uint16)","1983111d":"getTotalCompositionPrice(uint256[])","1983f4c2":"getDivsBalance()","1984a063":"StarbaseEarlyPurchaseAmendment()","1984a906":"preallocatedTokenAmount()","1984d419":"getProvisionBalance(uint256)","1985a440":"ContractRegistry()","1985acf0":"checkLimit(address)","1985f54a":"getScribe(address,address)","19863bb7":"ReDraw()","19869555":"evacuateToVault()","1986bc55":"stopBatchAssign()","1986f704":"setTrigger(address,bool)","1986fd4d":"getAccountWhitelist(uint256)","1987b887":"setTokenPorter(address)","1987da04":"secondPreSaleDate()","1987e50c":"getSellerAddressPayment(address,uint256)","1988f6fd":"didWithdrawProfit(bytes32,address,uint256,uint256)","1989a5ba":"canDoLoop(uint256,uint256,uint256)","1989d175":"YEAR_THREE_SUPPLY()","198a2085":"isATrustedContract(address)","198a5423":"presaleFundingGoalReached()","198ae785":"payTrnsTax(address,uint256)","198b5d0d":"MinimumPoStokens()","198c1f97":"getKeysfromETH(uint256,uint256,uint256)","198c548b":"supplyTokensSaved()","198df3b9":"LoginCheck(bytes32)","198e2b8a":"create(string,string)","198fa9a3":"isSigned(address,address,bytes32,uint8,bytes32,bytes32)","19901f1d":"TokenSale(uint256,uint256)","19901f20":"removeMultipleAllowedAddresses(address[])","19902b40":"changeCardAttr(uint256,uint16[5],uint16[5],uint16)","199099dc":"updateAccountState(address,uint256,bool)","1990ad6b":"private_delPermittedRoll(uint256)","1990f521":"fundings()","199156e4":"generatePresaleHouse()","1991d34a":"getDataColla_AB_02(string)","1991d6ac":"moveTokensFromSaleToExchange(uint256)","19921ad2":"AuthStart()","199317cf":"mining_uncle(bytes,bytes,uint256)","199326cb":"lastBlock_a2Hash_uint256()","1993584b":"countSecondWinners()","1994ad1e":"founderEggSupply()","19950c5b":"withdrawUnprotectedFunds(address,address,uint256,bool)","1995333b":"burnFunds(uint256)","1995b86d":"changeServerState(uint256)","199676c7":"TOKEN_RATE_40_PERCENT_BONUS()","19973261":"assigner()","19978a49":"rejectRequestUnpause()","1998524c":"updatePriceBottomInteger(uint256)","1998a5c4":"RHC()","1998aeef":"bid()","1998fb75":"addCar(uint80)","19996d50":"DinosaurFarmer()","1999cf37":"CHINESE_EXCHANGE_BUYIN()","1999eca8":"attack(uint8)","199a620a":"acceptNegotiationOwner(address)","199ba9e8":"basicFunctionReturn()","199c8b74":"SecvaultTest()","199cbc54":"totalVested()","199d70f4":"forceWithdrawRejected(address)","199d743a":"bountyTransfers()","199ed01b":"weightOf(uint256,uint256)","199f0791":"withdrawCntr(uint256)","199f4045":"NewRisk()","19a04a33":"SetDraftOrder()","19a08058":"setDelay(uint256,uint8,uint256)","19a0e572":"unverifyAddresses(address[])","19a17468":"ENS(address)","19a1b54f":"WEI_PER_ETHER()","19a1c691":"_removeChild(uint256,address,uint256)","19a1f592":"BONUS_AMOUNTS(uint256)","19a231eb":"getMilestoneDisputes(bytes32)","19a278b9":"getBAddress()","19a2bfd8":"unreadMessageCount(address)","19a32f66":"setHashByProvider(address,bytes32,bytes32)","19a3d0bb":"getMyStrippers()","19a3e3c0":"getAllRevenue()","19a50f49":"numUsers()","19a51554":"scheduleNextAuction(address,address)","19a523b0":"Violated(string,address)","19a5ce51":"oraclizeGasExtraArtwork()","19a64104":"Lockup6m(address)","19a6b356":"updateStrategyLabel(bytes15,string)","19a72fef":"DroneEmployeeROS(address,int256,address,address)","19a7e59d":"assertEq4(bytes4,bytes4,bytes32)","19a876c2":"stopPubTrade()","19a9119f":"prolongedDuration()","19a96e72":"setCarrotsMultiplier(uint8)","19a9c2f1":"generateId(string)","19aaff86":"claimAllDividends(address)","19ab453c":"init(address)","19ac2756":"TIER1_RATE()","19ac74bd":"userCampaigns(address,uint256)","19ac8c0f":"payComission()","19adda2c":"fairsaleProtectionOFF()","19ae8994":"test1(uint256)","19aec48a":"endTimeNumber()","19aec6a9":"newThreadEvent(uint256,string,string,uint256)","19af1bd9":"WeiRaised()","19af6f48":"crowdsaleTokenSold()","19afa824":"setFactoryInterface(address)","19afdfe1":"showMigrationAmount(address)","19b0297d":"info_BalanceOf(address)","19b05f49":"accept(uint256)","19b09f9b":"payWinner(address)","19b1f94b":"getLastAuditPass(address)","19b24684":"updateEntity(uint256,address,uint256)","19b35f3d":"organisationIndex(address)","19b36162":"updateParams(uint256,uint256,uint256,uint256,uint256,uint256)","19b3fa4b":"removeEmitter(address)","19b500ef":"deposit_internal(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256,uint256)","19b5176e":"memberGroupNameHash(address)","19b587ad":"putCompanyOnsale(bytes32,uint256)","19b61c09":"createSaddle1(uint256,uint256,uint256,address)","19b64015":"connectorTokens(uint256)","19b667da":"setFinalizeAgent(address)","19b6eabe":"setBounty(bytes32)","19b7b0b4":"acceptBid(uint256,uint256,bytes32)","19b7d7bd":"getBudget(address)","19b97530":"setFundariaPoolAddress(address)","19b985b3":"fixamt()","19ba0b63":"getNumberOfProjects()","19ba567c":"cancelAddOwnerRequest()","19bad1b2":"Stage1MEI()","19bb3c3d":"Reddit(uint256,uint256,bytes,bytes)","19bba58b":"_updateInventories(uint256,uint256,uint16)","19bdfc7f":"returnTokensFromHoldProjectAddress(uint256)","19be28ec":"CurrencySwap()","19be65f0":"GetBalance(address,address)","19bece1b":"buytoken(uint256)","19bee474":"totalFundsDistributed()","19bf01c0":"firstLockTime()","19c02b27":"allowTransfer(address,uint256)","19c039bc":"airDropJoin(bytes32)","19c0737f":"WineChainToken()","19c2a5b5":"auctionClose()","19c2b4c3":"getLastRequestId()","19c2f201":"GEN0_AUCTION_DURATION()","19c32e0b":"hmacsha256(bytes,bytes)","19c38c66":"inPermission(address,bytes4)","19c46f51":"kscBatchBurnWhenMoveToMainnet(address[],uint256[],string)","19c47214":"getBlockVersion(bytes)","19c4e40f":"envelopeTypes(uint256)","19c54359":"createData(uint256,uint256)","19c55a31":"SearchByGit(bytes)","19c55cea":"cancelBid(bytes32,uint256,uint256,uint256,uint256,uint8,bytes32,bytes32,uint8)","19c5ab4b":"addAccountReader(address,address)","19c5b887":"bonusSize()","19c5b89c":"DToken()","19c5ef1b":"oneStepRate()","19c61b6f":"dealEndOffer(bool)","19c6c6cd":"THRD()","19c6eeb8":"getIPFS(address,string)","19c76700":"withdrawBankroll(uint256)","19c85a4d":"RakugoCrowdsale(uint256,uint256,address,address,address[])","19c87f1f":"toAddress()","19c8b591":"ChangeCurrencyAdditionFee(uint256)","19c97154":"getLastTicketTime()","19c9a4f3":"platformTokensAddress()","19ca6feb":"_appendSchellingSupplyChanges(uint256,uint256,bool)","19ca964c":"_isOperatorForTranche(bytes32,address,address)","19cae462":"difficulty()","19cb355d":"requiredStake()","19cbe072":"contractFallback(address,uint256,uint256,uint256,uint256,uint256,bytes32)","19cc02aa":"airdropped()","19cc1ec4":"maxContributionAmount()","19cddd4b":"hackoin(string,string)","19ce4432":"DMPhuongToken()","19ceb660":"Ticket_Price()","19d0f54d":"allowRecovery()","19d152fa":"vestingToken()","19d1997a":"supplyLimit()","19d1b6c6":"getRegistrationRight(address)","19d1d967":"MOAC()","19d2993e":"phase1DurationInHours()","19d2fe85":"_iD()","19d3237c":"setDataColla_001_002(string,string)","19d375f1":"isLeagueRosterContract()","19d3be48":"_getPartId(string,uint8,uint8,uint8)","19d40b08":"approved()","19d41c69":"ticket_price()","19d45925":"isJobHasFreelancer(bytes)","19d45a08":"launchContract()","19d46f71":"makeWeeklyInvest(uint256)","19d4c380":"setBestGuessSecondPlaceTentativeWinningPayoutDistributionHash(bytes32)","19d56f84":"BuyChestSuccess(uint256)","19d70e0b":"createSaleAuction(uint256,uint256)","19d7943a":"reLoadXid(uint256)","19d8ac61":"lastTimestamp()","19d9217c":"midTermHolding()","19d9c8df":"ScaleObs(address,bytes32)","19da8c99":"getICOStatus()","19dacbf8":"Deposit(address,bytes32,uint256)","19dad16d":"setOwnerCutPerMillion(uint256)","19dba3d2":"getBountyToken(uint256)","19dc2525":"closeChannelEcrecover(bytes32,uint8,bytes32,bytes32,uint256)","19dc831a":"withdrawHavvens(uint256)","19dd9455":"getContractTimestamp()","19ddd5a3":"_buyXname(bytes32,uint256,bytes32)","19de029a":"setBountyDuration(uint256)","19dec62a":"approveAgreement()","19e044f8":"MockToken(uint256)","19e06f20":"mintIssuerToken(address,uint256)","19e072ef":"updateStatus(bool)","19e0a0cf":"sendTokensWithLock(address,uint256,bool)","19e0eb0e":"currentBlockHash()","19e13c93":"winningTeamName()","19e1568c":"pause_1()","19e1d8d4":"Luckblocks()","19e1fca4":"allowed()","19e3897a":"UpdateUserExtraData2(address,bytes32)","19e3a1d8":"BoomstarterICO(address[],address,uint256,bool)","19e4540b":"getBankAccount()","19e5221a":"getBonusFee(uint256)","19e5bf3a":"Register()","19e5d0cb":"mintInPeriodCount(uint256)","19e66508":"ztToken()","19e6ab23":"icoDiscountLevel1()","19e6e158":"totalVotes(uint256)","19e740c0":"getNextVestingIndex(address)","19e77c34":"startSlotAt()","19e7998c":"votingInfo()","19e7fbc2":"totalEthPos()","19e82d86":"cfi_whitelist(address)","19e82e6f":"BrokerBank(address,uint256,address,address)","19e858e5":"processCollateral(address,address,uint256,uint256,uint256,uint256,bool)","19e860c1":"secondPrivateLockedAmount()","19e9e5de":"getGooProduction(address)","19ea61db":"testFailTransferDisabled()","19ea809b":"intercrypto_convert(uint256,string,string,address)","19ea8a98":"setPackSaleAddress(address,address)","19eae36b":"setMaxBlockPurchaseInOneGo(uint256)","19eaeccb":"getInfoCellLockup()","19eb4a90":"getValues()","19eb5dc6":"transferToken(address[])","19eb691a":"curUserId()","19eb8d48":"canVote(address,uint256)","19ecb310":"allocateTicket(address,address)","19eced6d":"mCURRENT_STATE()","19edc0aa":"minimalInvestment()","19ede85a":"Hydron(uint256,string,string)","19ee1f1c":"getPrizeFund()","19ee5bca":"BountyManagerEntity()","19f02ceb":"set(address,address,uint256)","19f1cded":"getStakedTeller(address)","19f1d7b0":"Kentkoin()","19f2b931":"removerAssinatura(string)","19f30aaa":"hire(uint64,address[])","19f353bb":"protectionPrice()","19f37361":"isToken(address)","19f3edec":"_released(uint256,uint256)","19f4ff2f":"setFeeRatio(uint256)","19f577b3":"placeBuyOrder(uint256)","19f8dee9":"isEthWithEnc(uint16)","19f97a46":"createContractPlace(string,string)","19fa55bd":"MinasAlbarit()","19fa8f50":"InterfaceId_ERC165()","19fa9f72":"DNNToken()","19fac8fd":"setCommissionRate(uint256)","19fb361f":"transferTo(address,address,uint256,bytes)","19fb52db":"mainPoolCutPercentage()","19fc36ed":"MIN_TRANSFER_TIMESPAN()","19fc3b9d":"getMyHolding()","19fc5b88":"minEthAmount()","19fc5dfa":"LogBeneficiarySet(address,address)","19fc9e54":"cashInvestment(address,uint256)","19fce740":"capCommitment()","19fd93f1":"unregisterSsp(address)","19feda7e":"addEmployee(address,address,uint256,uint256)","19ff1d21":"hello()","19ff7096":"cost_of_transfers()","1a000513":"getLotteryResultTotal(address)","1a0058f5":"getBatchInfo(uint256)","1a006503":"hasAlreadyClaimed()","1a009265":"setArrBoolField1(bool[])","1a013939":"gameStarted(string,uint256,uint256,uint256)","1a017f3f":"transferPrivileged(address,uint256)","1a026c96":"wallet1()","1a02af40":"tokensInAuctionsOfOwner(address)","1a038873":"FREEZE_TIME()","1a041463":"retryOraclizeSetProof(uint256)","1a04d5c5":"startingFeeBalance()","1a053713":"unblockTokenFunds(address,uint256)","1a05619b":"infoTier()","1a05ba8d":"setPI_edit_12(string)","1a06008a":"dividendFund()","1a069c72":"contribute(uint256,uint256,uint8,bytes32,bytes32)","1a0725ce":"wagerIndex()","1a0726df":"getHatValue(uint256)","1a080a7a":"placeBet(uint8,int8,uint256,uint256)","1a081330":"isSaleOpen()","1a08a7bf":"ConfigAction()","1a08b189":"setFounderAddress(address)","1a0919dc":"unregister(bytes32)","1a092541":"getDescription()","1a09510a":"index(address[],address)","1a0a8fae":"creditJackpotTokens(address,uint256,uint256)","1a0a9ac7":"KNOXV()","1a0abd34":"getMyDepositAmount()","1a0b1b86":"crowdPrice()","1a0b4656":"LiveStarsToken()","1a0bc596":"pandora()","1a0be73f":"DispatchHub()","1a0c3479":"decreaseApproval(address,uint256,bytes,string)","1a0c83f8":"buyerLastPaidAt(uint256,address)","1a0d77b9":"ClaimAmount()","1a0ddce9":"setRewards(address[],uint256[],uint256[])","1a0e722b":"LogDeliverEVN(address,uint256)","1a0f0bf1":"unrestrictedMintToPool(uint128,uint256,uint128)","1a0f2f5f":"BroToken()","1a0f518d":"updatePlayerBalance(address,int128,int128,uint256)","1a0faecf":"addNewMeme(uint32,string,string,string,string)","1a0fb847":"disperseRewards(address,uint256)","1a10cfc3":"delete_entry(uint256,uint256,uint256)","1a11415e":"PRIVATESALE_BASE_PRICE_IN_WEI()","1a120481":"enlist()","1a12e7a9":"setCreationFee(uint64)","1a144940":"codetokenIndexToOwner(uint256)","1a145c34":"getNumEthTweets()","1a148644":"newDocument(string,string)","1a14e94a":"buyAnimal(uint256)","1a14f128":"EventCreateAccessory(address,uint256)","1a14ff7a":"getD()","1a1542e6":"checkGameResult()","1a15b206":"holdTokens(address,uint256)","1a160fe9":"checkPermission(address,address)","1a170aa1":"buyTickets(bytes32)","1a1773f4":"otherchainstotalset()","1a182801":"createNewCertifier()","1a18e707":"setBlockReward(uint256)","1a197588":"availableAmount(address[3],uint256[4])","1a19b0da":"confirmEngineerQuest(address)","1a1a0d65":"distributeSRNT(address[],uint256)","1a1a0d76":"updateTopicDescription(bytes15,string)","1a1a4ed7":"HALVING_DELAY()","1a1a7993":"random(uint64)","1a1a8da8":"WebPay()","1a1aab46":"unlock_times(uint256)","1a1abe3d":"sizes(uint8)","1a1b8d08":"CompleteInit()","1a1c59e2":"setBidSubmissionProofsAdd(address)","1a1ceb11":"cloneProposal(uint256,string,bytes32,uint256,uint256,uint256,bool)","1a1dca07":"setLockFunds(address[],uint256)","1a1df394":"Play(bool)","1a1e01d5":"pushAllRemainToken(address)","1a1eea7d":"ProposalRequestSubmitted(bytes32,uint256,uint256,string,address)","1a1feae1":"txGasPriceLimit()","1a2084f1":"updateCreator(address)","1a209776":"isVerified(address,uint256)","1a21bb22":"PREVIPdeadline()","1a21c229":"gracePeriodMaxTarget()","1a2309f0":"CONTRIBUTION_MAX()","1a23bee3":"endOfROSCARetrieveFees()","1a24b91a":"setPriceFee()","1a24befc":"clearSaleSharesSold(uint256)","1a254884":"Coffeecoin(uint256,string,uint8,string)","1a256090":"sawan()","1a25e513":"upgradeProvider(address,address)","1a261fda":"scoreUp(address)","1a26ed1c":"validateReservedWindowSize(uint256,uint256)","1a2a4ab5":"withdrawDeadFund(address)","1a2a627c":"nextroundtotalsupplyGOTCH()","1a2ad007":"GetCurRoundInfo()","1a2b3431":"completeBooking(uint256)","1a2b3adf":"signedTransferFromHash(address,address,address,uint256,uint256,uint256)","1a2b4cd8":"airDropPool_()","1a2b6250":"canPerform(address,address,bytes32)","1a2c4334":"FortuneGodToken(address)","1a2c752a":"testLimiting()","1a2d3be8":"masterNodable()","1a2d72fb":"_api_PlaceBet(bool)","1a2d8629":"getinfo()","1a2e2b2c":"getHolderIndex()","1a2eaaeb":"Unicoin()","1a2f1640":"amountSecond()","1a300a98":"_setCooldownEndTime(uint256,uint256)","1a3057f3":"performAddToken()","1a30ec13":"ETHWallet()","1a311968":"roundICO()","1a3142bd":"depositAndWithdraw(uint256)","1a314552":"isUsernameExists(string)","1a31752a":"masternodes(uint256)","1a31e733":"WinningsClaimed(address,uint256)","1a327d97":"bitmask_rm(address,uint256)","1a3480b5":"rateDecimals()","1a34b59d":"OjtToken()","1a34fe81":"max_amount()","1a3538f3":"closeFailedInstallationAndWithdraw()","1a360f5f":"EWM()","1a363bf1":"giveMeTokens()","1a365f2b":"stampIndexToOwner(uint256)","1a3722b2":"grantPermission(uint8,address)","1a372eaa":"allPiranhasInfo(uint256)","1a3739ec":"getInitialReporter()","1a389eb9":"exploreFastenEMONTFee()","1a38fa06":"distributeBounty(address[],uint256[])","1a399698":"genDailySecondPrizeKey(uint8[4])","1a39d8ef":"totalAmount()","1a39e1cf":"addAffiliate()","1a3a67d8":"zGetGameID()","1a3ae67a":"getPlatBalance()","1a3b8bad":"CABoxCrowdsale()","1a3cb4f5":"getBalanceA(bytes)","1a3cd59a":"getInfo(uint256)","1a3d069b":"totalEuroUlps()","1a3d96ff":"IdentityManager(bytes32)","1a3dc39c":"getRewardPotSetting()","1a3de5c3":"_pay()","1a3e42d0":"setSignUpOnOff(bool)","1a3e5457":"validDestination(address)","1a3e91b9":"getTitle(bytes32)","1a421103":"getProperty(address,bytes32)","1a426550":"claimBounty(uint256,string)","1a429a0e":"SCND_CRWDSALE_RATIO()","1a433daf":"withdrawProposedAction()","1a437780":"orderOnFightAuction(uint256,uint256,uint256)","1a43c338":"compute()","1a44731c":"statePhase()","1a454ea6":"COMMISSION_RATE()","1a45fac7":"removeOwner(address,address,address)","1a463a7d":"amountReceived(uint256)","1a464fa1":"claimProductOwnership(bytes32)","1a470b6a":"SweepBalances()","1a476260":"indiFundAndSocialVaultDeposit()","1a4813d7":"setBaseRate(address[],uint256[],uint256[],bytes14[],bytes14[],uint256,uint256[])","1a488a60":"zpzToken(uint256,string,uint8,string)","1a48fb3a":"testDeleteLawyer()","1a49803b":"investWithSignedAddress(address,uint128,uint8,bytes32,bytes32)","1a4a1a6c":"benefactorsBalance()","1a4b746f":"CharacterRegistry()","1a4bcc4a":"validTokenBalance(address)","1a4be5d8":"HITSCoin()","1a4be6ff":"ConstantConfig(uint256,bool,bool)","1a4c24f9":"purchaseInternal(address,uint256,address)","1a4e0afd":"countBit(uint8)","1a4e1e78":"tips()","1a4e9a6c":"getWithdrawConfirmations(uint256)","1a4f5b67":"isFrontRunnerPeriodOver()","1a4fb653":"getGDemoc(uint256)","1a4fbee1":"committeesArrayIndexCounter()","1a514d97":"reActivate()","1a51a28c":"contributorsAllocation()","1a52691b":"refundForAll(uint256,uint256)","1a534fd1":"calcCanAcceptAmount(address,bool,uint256)","1a5375e1":"passTurn(uint256)","1a53cd90":"presaleBalancesLocked()","1a555b0c":"NewClonedToken(address)","1a55ad28":"_verifyProof(string,bytes,bytes,uint256)","1a55b8f7":"BACKUP_ONE()","1a582962":"isMintingFinished()","1a58349a":"fetchCreatedOrdersForPayerByAdmin(address)","1a5834aa":"start_game(string,string)","1a592bc1":"saasPayUser()","1a5ab391":"Wallet7()","1a5b189d":"NCASHTOKEN()","1a5b72c3":"endStage3()","1a5b8f96":"MAX_SITE_ID()","1a5bd7fc":"getTournament(uint256)","1a5d3b75":"getAssetIdOwner(uint256)","1a5d60bd":"removeBoard(address,address)","1a5dbe98":"iflea()","1a5e2110":"tokensPerEthPrice()","1a5e6f7d":"getOneBet()","1a5e7852":"kaliSupply()","1a5eba21":"invest(uint256,string)","1a5f9613":"DevMiningRewardPerETHBlock()","1a5f9bed":"exploreUsingETH(uint256,uint256)","1a620a3e":"AgriChainMasterContract()","1a6253ed":"ownerTransferPHX(address,uint256)","1a629b00":"AddTokensToMember(address,uint256)","1a62c928":"approveAllocation(address,address)","1a62f6f7":"escrowReturn(address,uint256,uint256)","1a63aa4d":"prolong(uint256)","1a64937b":"cleanupAbandonedGame(address)","1a64adae":"vestedTokens(address,uint256)","1a65569b":"placeBid(uint256,uint256,uint256,uint256,bytes32)","1a65d3c2":"SnakeFarmer()","1a65e283":"buyCountry(uint256)","1a668c42":"finishAirdrop()","1a67456e":"getNumberOfItemsByTypeAndOwner(string,address)","1a67d6e5":"MainSaleClosed()","1a68b1a1":"setRetirementManager(address)","1a690752":"UDCC()","1a695230":"transfer(address)","1a699085":"view64()","1a6a3c03":"GetEscrowOwner()","1a6af7b7":"currTime()","1a6b0e73":"addArts(address)","1a6b13e2":"changeMinimumTakerProtocolFee(uint256)","1a6becd6":"getAllDividends()","1a6c0983":"getShipSell(uint32)","1a6c6e38":"MagicStore(address)","1a6c9c0d":"withdrawStart(uint256[],uint256,uint256,uint256)","1a6d7561":"getFundingInfoOfPhase(uint8)","1a6dafa6":"getJackpotRoundEndTime()","1a6e2445":"changeRelease(uint256)","1a6ea411":"MANHATTANPROXY5THAVE()","1a6f1974":"disableNodeRegistration()","1a6f56a0":"balancesLocked2Y(address)","1a6fb342":"getTransferStatus()","1a700013":"inWhiteList(address,address)","1a700a95":"QWHappy()","1a701609":"HEAD()","1a70388f":"shareToWei(uint256)","1a70d015":"exchangesTokens()","1a715bcf":"lauToken(address,address)","1a71733c":"determineAllocation(address,address[],uint256[])","1a71d3db":"freezingBalanceNumberOf(address)","1a7303de":"eddToken()","1a73293d":"updateWhitelist(address,uint256)","1a750945":"vote03YesCount()","1a751b2c":"makeMonthlyInvest(uint256)","1a7626e7":"minimumFee()","1a76e30c":"BONUS_DAY2_DURATION()","1a776b3c":"reclaimSurplusEth(address)","1a787915":"startConditions(bytes32)","1a790a2c":"_setPowerPool(uint256)","1a79464e":"setFeeBurner(address)","1a799617":"revokeRound(uint256)","1a79bbef":"addAddressToMaster(address)","1a79c5de":"setTimeWindow(uint256,uint256)","1a7a98e2":"getDomain(uint256)","1a7ae0ba":"updateCostUSD(uint256)","1a7aed0e":"_checkMyAging(address)","1a7b11f5":"epoch_fund()","1a7b9fe7":"setCouponRatio(uint32)","1a7c6eb0":"getHalvingBlocks()","1a7c7105":"__load128(bytes)","1a7cecb2":"recoverAddressFromCooperativeSettleSignature(uint256,address,uint256,address,uint256,bytes)","1a7cf619":"round0StartTime()","1a7e0c50":"totalBaseLareSoldInPreSale()","1a7f8588":"IRE()","1a7facff":"rcn()","1a7fae47":"pubkeys2(uint256)","1a8012e4":"is_active()","1a809b02":"unpauseRefund()","1a81284b":"CCH_FGRE_1()","1a81a01f":"configContract(uint256,address[],uint256[],uint256[],uint256[],uint256[])","1a81c3a2":"getUserContract(address,uint256)","1a81e7b4":"getExtender()","1a82844c":"getERC721AmountPawn(uint256,address)","1a82eeb4":"ocpTokenContract()","1a833d3f":"trancheNumerator()","1a83690d":"Work()","1a841b1b":"configureFromStorage()","1a8432ea":"isUnLockedAccount(address)","1a844205":"SaintCoinWorld()","1a859db8":"rewardsAccounts(uint256)","1a85bd57":"_find(uint256)","1a85c6cb":"RandomNumber(uint8)","1a85f4fb":"UrlHint(int256)","1a85f7d2":"applySettings(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","1a860d91":"AddUser(string,address,uint256)","1a861d26":"maxLimit()","1a86430e":"calcTotalShareRewardFee(uint256)","1a86535a":"GetWhoSignedAVersion(string)","1a86ac4f":"initialAddressSet()","1a86d5b6":"sendToOtherBlockchain1(string,string)","1a871a2c":"playerCharacter(uint256,uint8)","1a88bc66":"slot()","1a88cc31":"getCommissions(uint256)","1a88f306":"transferFromContract(address,uint256)","1a8932d9":"allocated2Year()","1a8943dd":"overflowResistantFraction(uint256,uint256,uint256)","1a895266":"unBlacklist(address)","1a8a5de1":"citizensAmounts()","1a8a85f3":"checksum(address)","1a8af7a8":"restartMint()","1a8b1874":"endprivate()","1a8c7243":"presale_finish()","1a8dc392":"checkAddressTeamTwo(address)","1a8f8f3e":"MJCCToken()","1a8fc985":"INITIAL_TOKENS_PER_ETHER()","1a9069cf":"signDate(bytes32)","1a90f0c4":"numTurnsToRevolve()","1a918bdd":"addTraps(uint256,bytes,uint256[])","1a92e6da":"Veegotoken(uint256,uint256)","1a9360dd":"checkDate()","1a93d1c3":"getGasLimit()","1a93fa4b":"reorganizeSubUsers()","1a9425c1":"verified(uint256)","1a94d49b":"BASE_BET_ETHER()","1a955061":"numToWei(uint256,uint256)","1a95bc99":"GreatHarmon()","1a95f15f":"TICKET_PRICE()","1a968069":"multiSig(bytes32)","1a974bb5":"KOCMOC()","1a97d1fa":"CLASSYToken()","1a98d0de":"whitelistedParticipantsLength()","1a991f0d":"approveSpenderDecimalAmount(address,uint256)","1a9938aa":"activateAddress(address,bool)","1a994fd2":"addVideoGame(string,address,uint256)","1a99bed2":"VestingSent(address,address,uint256,uint256,uint256)","1a9a01fb":"removeGame()","1a9a0426":"setDecimal(uint8)","1a9aa710":"ownerAuctionCount(address)","1a9aea0a":"lockTransfer()","1a9b0b7c":"isWinner()","1a9b26a2":"decode(bytes,uint256,uint256,uint256)","1a9b70f2":"destroyBlockFunds(address)","1a9be331":"getFastExtra()","1a9bf9cf":"bountyTokens()","1a9c4571":"listEggsIds()","1a9caab9":"createGen0(uint256)","1a9d64c8":"publicsale_address()","1a9df17b":"OrderPaid(uint256,address,uint256,uint256)","1a9e3e18":"ownerBuyCut()","1a9f170d":"buyIcoToken1()","1a9f66c4":"StrimTeam()","1a9faa80":"setUpdateAddress(address)","1aa022bf":"UacToken()","1aa02d59":"set_fee(uint256)","1aa05ab6":"testSellTwoTokens()","1aa19567":"interruptLastRound()","1aa260c0":"withdrawAsSupporter(uint256)","1aa359ff":"newTokenContractAddress()","1aa37733":"AudCoinToken()","1aa3a008":"register()","1aa43078":"minTime()","1aa44efd":"createNamedDistrict(uint256,string,bool)","1aa49291":"Getter()","1aa57ec5":"TokenLab(address,uint256,uint256)","1aa58bd3":"isAetherClockAuction()","1aa5b55c":"stageTwoStart()","1aa5c70e":"getDAI(uint256)","1aa6e29f":"hasOneYearWithdraw()","1aa7655c":"START_TOKENS()","1aa7e54c":"dungeonDifficulty()","1aa859d0":"remTokenPairWhitelist(address,address)","1aa86370":"updateXIPFSPublicKey(string)","1aab7bb5":"setParamsPreSale(bool)","1aab9a9f":"holderCount()","1aabaffe":"WhaleToken()","1aac38c8":"addPhase(uint256)","1aacd03c":"checkNewPlayer(address)","1aad5bc2":"_getRarity(uint256)","1aad8b82":"calculatemortiesell(uint256)","1aadadaa":"getRegistrantFund(address)","1aadcc34":"convertGreyGreen(uint8,uint8)","1aadddea":"investorGiven()","1aae3460":"investedAmountOf(address)","1aaf39ff":"check_dividend(address)","1ab06ee5":"set(uint256,uint256)","1ab08c61":"albosAddress()","1ab1025c":"tokensOutInMarket()","1ab12b10":"CurrentDevFee()","1ab268d6":"getCompleteSetCostInAttotokens()","1ab27060":"Unapproved(address,address)","1ab2935c":"VestingScheduleRegistered(address,address,uint256,uint256,uint256,uint256,uint256)","1ab30817":"gasLimitForOraclize()","1ab3a6c8":"getParentsForTokenId(uint256)","1ab3c515":"balanceOfLocked1Y(address)","1ab3d055":"removeAdminWhitelist(address[])","1ab46d4e":"referralBonusCalculate(uint256,uint256)","1ab51aec":"buyEPU()","1ab59612":"setAllowPriceLower(bool)","1ab5c5b8":"adduser(address,uint256,uint256)","1ab5d260":"transferTo()","1ab681e8":"withdrawEth(uint256,address,bytes32)","1ab733a3":"getTotalProfits(address)","1ab7df5f":"addUserTokens(address,uint256)","1ab86572":"calculateRoom(uint256,uint256,bool,uint256)","1ab8bc44":"_setMilestoneTo(address,uint256,uint8)","1ab8ff3b":"_finalization()","1ab961a1":"BSDB()","1ab971ab":"setFee(uint32)","1abb0ba9":"getTotalCurrentSaled()","1abb10e8":"chipSpeed()","1abb7192":"YCCToken(uint256,string,uint8,string)","1abca540":"Toptech()","1abd409d":"champsForSaleCount()","1abe8385":"InvestmentToken()","1abebea8":"LogSetAuthority(address)","1ac10d11":"testGreatherThanOrEqual()","1ac10f1f":"setPixelRate(uint256)","1ac14219":"testEns()","1ac25a81":"RegisterDrupal()","1ac25e99":"extractBalanceProofSignature(address,uint32,uint192,bytes)","1ac33b3d":"createTrack(bytes32)","1ac39336":"GelatoCoin()","1ac3ddeb":"withdrawFee(address)","1ac46290":"setProviderInfo(uint256,string)","1ac4754b":"redeemInternal(address,bool)","1ac47963":"functionSeven()","1ac589b4":"setJoiningFee(uint256)","1ac58dd5":"kimsCreated()","1ac5c96f":"test_4_someTest()","1ac61e8c":"testBlobCreate()","1ac68a12":"HavvenGoldSupply()","1ac7e1f9":"CollectedAllFees(address,uint256)","1ac8a9b2":"teamlock()","1ac8aa4e":"minimowea()","1ac9180e":"tokenReinvest(uint256)","1ac96124":"numOfCommon()","1ac975ed":"UcCoinPriceChanged(uint256,uint256)","1ac9f70d":"multiplicate(address)","1aca00fd":"variable(uint256)","1aca120b":"updateAnimalSpecial(uint256,bool)","1acb2719":"getNextRequest(address,address)","1acb7077":"setCentsPerToken(uint256)","1acbf6e0":"alfatokenFee()","1acc26bc":"disableLimit()","1acc478a":"getContentMetrics(address,address,bytes32)","1acc57b8":"AGENCY_TOKEN_CAP()","1acd8237":"LEK(string,string,uint256,uint8)","1ace02a3":"RaptorsvsWizards425()","1ace4d05":"bigAmount()","1ace88a4":"realWorldPlayerTokenForPlayerTokenId(uint32)","1acf6485":"requestWithdrawalFromLimit(uint256,string)","1acfd02a":"changeAdmin(address,address)","1ad065f1":"prepare(uint256,address,address,uint256)","1ad11fd1":"TrieToken()","1ad2ad1a":"stopPresale()","1ad50586":"safePower(uint256,uint256)","1ad509f0":"MUIcoin()","1ad6037f":"LEXInContract()","1ad607da":"_addUserCity(address,uint256)","1ad614c3":"setRequireAuthorisation(bool)","1ad66d21":"earlyPurchasesLoaded()","1ad781b4":"PennyGrab()","1ad7c199":"callVote()","1ad874b4":"presaleOn()","1ad8f65b":"distribute_for_founders()","1ad8fde6":"changeSymbol(bytes32)","1ad95744":"START_ICO()","1ad9f190":"getUserHotGoldBalance(string)","1ada70a8":"lockupDuration()","1adadda8":"claimLockedTokens(address)","1adb4842":"setLockup_jishis(address,uint256,uint256)","1adb631b":"distributePuppyCoinMedium(address[])","1adbdfab":"SimpleApproveTransfer(address)","1adc36b9":"doesUserOwnCeleb(address,uint256)","1add5486":"Multiownable()","1add6bcf":"getDoubleKeccak256(uint256)","1adda83a":"calculateTokens(address,uint256,uint256)","1adf2bec":"CancelOrder()","1adf2d1a":"Offer(address,address,bytes,uint256,uint256,uint128,uint256)","1adf42fb":"setPreICO(bool)","1adf692f":"_changeSquarePrice(uint8,uint256)","1ae0a693":"SetApplicant(bytes32[])","1ae0b4d0":"master5invest()","1ae0c787":"getControlInfoMaxTotalImbalanceList()","1ae2379c":"excess()","1ae32b82":"disallowReceiver(address)","1ae3a94a":"devFeeRate()","1ae3d8d0":"protectedBalance(address,address)","1ae460e5":"isInPool()","1ae4dfb7":"getcardPrice(uint256)","1ae638f7":"times6()","1ae6b6ee":"cancelAuctionWhenPaused(address,uint256)","1ae6c09c":"showMyAnimalBalance()","1ae6d375":"AirSwapToken(address,address,uint256)","1ae7341f":"OneledgerToken()","1ae743ad":"withdraw_token_and_eth()","1ae7b7fb":"jackpotSmall()","1ae7b8e1":"newOffer(address,string)","1ae7ef0a":"QISHENG(uint256,string,string)","1ae8494e":"purchaseTopCompany(bytes32,bool)","1ae879e8":"walletOwner()","1ae8ab81":"setNickname(bytes32)","1ae8fc87":"addContract(address,address,uint256,string)","1ae97bd9":"updateName(bytes32)","1ae9fe6a":"cutOffBidID()","1aea4d0f":"setMaxSend(uint256)","1aea558a":"auditReport(address,uint256,uint256)","1aeb10a6":"testApprove()","1aebcb89":"getProfitPerShare()","1aec2cf9":"Subscribe(address)","1aece0db":"PRE_SALE_END_TIME()","1aed001e":"_miningOneSelf(address)","1aed8e1e":"GigERC20(uint256,string,uint8,string,bool,bool)","1aedefda":"includes(address)","1aedf542":"ercOwnerClaim()","1aee3f91":"PRESALE_LIMIT()","1aef8058":"DECIMAL_MULTIPLIER()","1aefce3b":"ratioVote(bool,uint8)","1af11767":"CauldronsMinigamePresale(uint32,address)","1af217ab":"maxTokenPurchase(address)","1af26fc2":"isJobExpired(bytes)","1af2c9fd":"numberOfInvestors()","1af31d7b":"GetPoolEntranceFee(string)","1af32223":"get_owner(bytes32)","1af36a78":"level1(address,bytes32,uint256)","1af39907":"_inMoney(uint256,address)","1af476a6":"setEggTotal(uint8,uint256)","1af47cc7":"addSellTokensRequest(string,uint256,uint256)","1af48c85":"checkCertificates(uint256)","1af50c5e":"setDisbursementAmount(uint256)","1af5163f":"TokenBurned(address,uint256)","1af5205c":"period3Numerator()","1af526b0":"getSell()","1af5dd41":"balanceOfComision(address)","1af62808":"getLicensePrice()","1af6b60f":"ScamSealToken()","1af716ba":"transferFrom(address,address,uint256,string)","1af77842":"setE93ContractAddress(address)","1af82fbf":"viewDividendCooldown()","1af855f8":"Funding(address,uint256)","1af88bc1":"GetPatientFromAddress(address)","1af8c18a":"InitBalanceFrom961e593b36920a767dad75f9fda07723231d9b77(address,uint256)","1af97fb7":"getBabyGen(uint16,uint16)","1afa6542":"AirCoin(uint256,string,uint8,string)","1afaa8bf":"crowdfundPercentOfTotal()","1afc540d":"set_saleAddress(address)","1afcc95b":"getCCH_edit_21()","1afccfa5":"Proposal(address,address,address,bytes,bool)","1afd08a2":"setConfirmationTime(uint256,uint256)","1afd96dc":"withdrawForThreeYear()","1afe3e10":"getCurrentPhaseDivisor()","1afe56aa":"markRead(uint256)","1aff30dd":"getGameStats()","1affa814":"getProviderPriv(uint256)","1affcd7e":"createCollectible(uint256,address,uint256,uint256)","1b005a38":"authorizerOne()","1b00fe51":"testHypothesis()","1b011bd9":"test_insert_findWithHint()","1b027b44":"getBuyPosition(bytes32,uint256)","1b03316f":"getSecond()","1b044be7":"setFundScheme(uint256,uint256)","1b04803e":"contractModifierAddress()","1b04a435":"durationSecondsIco()","1b0569b2":"IPToken()","1b05aeb5":"WinMatrix()","1b05c594":"newGame(uint256,uint256)","1b05ea8c":"CheckPrepare()","1b06128b":"burnLeftoverTokens(uint8)","1b06ec3b":"getAllTransactionIdsByEntityId(address)","1b0710b5":"TOZToken()","1b073c67":"XGEToken()","1b0762bb":"remunerationBalance()","1b076edc":"dataSource()","1b07fcc1":"linkImpact(string)","1b082009":"getCrowdsaleBalance()","1b088f70":"computeLeaf(uint256)","1b08d96f":"ret()","1b0a102c":"getPrediction(uint256,uint256)","1b0a5d4e":"totalPartnerSupply()","1b0a68f2":"decreaseMintApproval(address,uint256)","1b0b906b":"getMyPlayedAmount(address)","1b0ba14d":"InvestmentFailed()","1b0c72dc":"isRecipientActive(address,address)","1b0cb61f":"_whitelistAddress(address)","1b0d320f":"FriendsCoin()","1b0db7fe":"getAllValuesSum(uint256[])","1b0dbdaf":"manualReserve(address,uint256)","1b0dc452":"isAnOwner(address)","1b0e25e2":"onInitialized()","1b0e3061":"BCW(uint256,string,string)","1b0eaf78":"stop_or_resume_Contract(bool)","1b0f5395":"ChargeNetwork()","1b0f7ba9":"proxy(address,uint8,bytes)","1b0fa385":"transfeFrom(address,address,uint256)","1b0fc106":"acceptChallenge(uint256)","1b107f7b":"storeUnlockData(uint256,address,address,uint256,bytes32)","1b112541":"getPTicketSumByRound(uint256,address)","1b118984":"TOKEN_ICO1_LIMIT()","1b12b60f":"canBuyTokens(uint256)","1b130063":"sendPrize(address,uint256,string)","1b131bbd":"_split(uint256)","1b136c6f":"getPlayerRounds(uint256)","1b13756a":"getFirstBorrowAgreement(address,address)","1b14cd05":"verifyLockSignature(bytes32,uint256,address,address,uint256,uint256,bytes32,bytes)","1b1665ca":"updateLimitPerMonth(bytes32,uint256)","1b1686b6":"currentEthInvested()","1b17595f":"registerTrack(bytes32,uint256,bytes32,bytes32,bytes32)","1b181e58":"getOverTokens()","1b189efb":"EURsToken()","1b18f952":"test01()","1b18ffac":"random(uint256,int256,int256)","1b195a7c":"buildAddition(uint256)","1b19f6a3":"removeReferrer(bytes32)","1b1a7a58":"multiSendToken()","1b1b6069":"initEachPUST()","1b1c15d5":"tokensForInvestors()","1b1c6acf":"getUintField3()","1b1ccc47":"getDSTName()","1b1d6af8":"_PLUTOToken()","1b1d95ff":"getPow(uint256)","1b1da1af":"updateSharePrice(uint256,uint256)","1b1e5d5d":"rejectMany(address[])","1b1ef88d":"authorizedByUser(address,address)","1b1f2fb8":"preTGE()","1b203b9d":"checkAndCloseRound(bool)","1b2051f6":"tempTokensPeriodOf(address)","1b208786":"delegatedTransfer(address,address,uint256,uint256)","1b2212f5":"forbidDirectDebit()","1b23cfd2":"AceguyToken()","1b258d50":"withdraw(bytes32,address)","1b25d0e6":"POST_ICO()","1b26fa6a":"priceStep1()","1b27274b":"testPure()","1b27c873":"advisorsTokensFirstReleaseTime()","1b27c8f2":"takeBountyTokens()","1b27ca21":"MonthsProfit()","1b27e705":"_forwardFunds(uint256)","1b28591c":"escapeFunds(address,uint256)","1b28985e":"MotorToken()","1b29d70a":"weiRefund()","1b2a8715":"notIn(bytes32[],bytes32)","1b2ace9d":"lockedProvider(address)","1b2ae899":"removeModule(uint8,uint8)","1b2ae964":"BuyPriceChanged(uint256)","1b2bd803":"issueAtIco(address,uint256,uint256)","1b2be5f8":"transferredAtSupplyValue(address)","1b2bf378":"BLM()","1b2d26e9":"OwOWorldToken()","1b2d515f":"setA(bytes32)","1b2d93a0":"load(address,bool,address,address,address,address,address)","1b2dba8c":"setCertifierId(address,string)","1b2e4002":"LIZAToken(string,string,uint8,uint256)","1b2f1109":"sntController()","1b302a16":"tokenUnpause()","1b31abda":"getGameDetails(uint256)","1b31c5c2":"RESERVED_TOKENS_OPERATIONAL_EXPENSES()","1b328100":"valueToBeSent()","1b33157a":"buyTickets(uint256[],uint256,bytes)","1b33a497":"tranferToReserve()","1b33d412":"offer(uint256,address,uint256,address,uint256)","1b346a63":"testMoveWithTrust()","1b34737f":"setSCoinContractAddress(address,address)","1b347aae":"retrieveToken()","1b354a30":"kscIncreaseApproval(address,uint256,string)","1b357750":"setLegacyNFTAddress(address)","1b35f56f":"getCurrentlyRunningPhase()","1b360912":"transferTokensFromPartnersAddress(address,uint256)","1b369fad":"removeBlockListed(address)","1b36cbfc":"EtheremonDataEvent(address)","1b370abb":"getPreviousNode(bytes)","1b37cb3e":"VOCOToken()","1b3821e8":"addSentMessage(address,address,uint256)","1b385f34":"buyOmegaEgg()","1b3878f5":"addToEmployerTotalPaid(address,address,uint256)","1b391d09":"benefeciar()","1b393b9a":"emergencyRelease()","1b394dce":"_chkBuyerLmts(address,uint256)","1b397d79":"OurBank(address,address)","1b39f3d7":"timeset()","1b3a8e6f":"directionCount(int256,int256,int256,int256)","1b3a91ac":"addTiers(uint16,uint256[],uint256[])","1b3aaf06":"setRspTokenAddress(address)","1b3b5742":"PayJackpot()","1b3c72aa":"getAddressLevel()","1b3ca096":"MarketBase()","1b3d36de":"calculateToken(uint256)","1b3d803f":"TokenRegulatorService()","1b3e100d":"PRE_ICO_PRICE()","1b3e2002":"giftRock(uint256,address)","1b3e704a":"supplyICO(address)","1b3e8cda":"isEthPayable()","1b3ed722":"multiplier()","1b3efd15":"claimrefund(address)","1b3f2fd3":"checkAvailableTokens(address)","1b3f8a67":"addToSyncList(address)","1b3fddb8":"PRESALE_BONUS()","1b3ff96f":"getForecastCount(uint256,uint256,bool)","1b4032f5":"lastBlock_f7Hash_uint256()","1b40ee88":"sellArtwork(uint32)","1b411fc8":"createRound()","1b413d27":"getLuck()","1b414708":"hasDisclosureAgreement(uint256)","1b41c096":"setStartsAtUTC(uint256)","1b41c134":"UsernameDoesNotMatch(bytes32,bytes32)","1b426d8d":"LOG_ProofFailure(bytes32,address)","1b42b7ab":"decreaseSalesBalance(address,uint256)","1b42f904":"LogFreezerAddition(address,uint256)","1b437d0c":"compareLastCalldata(bytes)","1b44a5ef":"handleSingleItem(address,uint256,uint256,uint256,uint256)","1b44f449":"Chain3()","1b45c301":"assetManager(bytes32)","1b4646bf":"setReferalsMinInvestLimit(uint256)","1b464764":"withdrawAdvisor(address,uint256)","1b468ed8":"addHandlerToWhitelist(address)","1b476945":"devTokensIco1()","1b477633":"determinePlayer(bytes32[],bytes32[],int256[],uint8,bytes32,bytes32)","1b47dbbe":"IdentityVerifier(address)","1b482452":"getWinnerUrl(uint256)","1b49d82b":"joinClub(address)","1b4a2001":"minReserve()","1b4a93aa":"SetupFuseaNetwork(string,string,uint256,uint256,uint256,address,address)","1b4b1cfa":"isICOPeriod()","1b4b546f":"ChooseA()","1b4c19ac":"startSale(uint256,uint256,uint256,address,uint256,uint256)","1b4c5a10":"SupportFund()","1b4c84d2":"isTradeable()","1b4cd2de":"ICO_START_TIME()","1b4cd4ef":"depositPAXTR(uint256)","1b4d02c2":"cryptoAgent()","1b4d18c1":"rateOfSpecificTranche(uint256)","1b4f4285":"notifyNewAccount(address,address)","1b4f6c46":"acceptOwnership(bytes32)","1b4fa639":"ownerFinishContract()","1b4fa6ab":"getDefaultStackCheck()","1b503a09":"LogRmUser(address)","1b50ad09":"updateDuration(uint256)","1b5171f0":"BountyKilled(uint256,address)","1b517663":"mintPriceOffset()","1b520b68":"lethalBonusAtHitsLead(uint256)","1b52abde":"redeemRestore(address,uint256)","1b531d4b":"settings_added()","1b538bcc":"getCurrentVotes(uint256)","1b542aa7":"Swob()","1b55ba3a":"Start()","1b55c148":"BidPlaced(bytes32,uint8,address,uint256,bool,int32)","1b55ec45":"getTokenToBurn()","1b55fe4e":"setFourthAddressBalance(address)","1b561fe7":"getSeniorContract()","1b5631de":"ManualChangeStartDate(uint256,uint256)","1b5710ed":"_deleteAllPackedRevisionTimestamps(bytes32)","1b580620":"setOwner1(address)","1b58c88f":"restoreOwner(address)","1b58c943":"getNBallots()","1b5a8da6":"giveEthBankrollAddress()","1b5ac4b5":"abs(int256)","1b5ae2f7":"day0x1(address,address)","1b5c16bf":"setTargetRepMarketCapInAttoeth(uint256)","1b5c9ae3":"get_etc_balance(address)","1b5df453":"addUserWhoSell(address,address,uint256,uint256,uint256,uint256,uint256,uint256)","1b5e42f5":"amountOfUnitsOutsideAdminWallet()","1b5e75be":"evalParams(bytes32,address,address,bytes32,uint256[])","1b5ee6ae":"mintToken(int256,address,uint256)","1b5f03a6":"getRoute(string)","1b5f6cea":"P3DtoTokens_(uint256)","1b61a179":"mulbonus()","1b61f340":"finishADrop()","1b6282e3":"issuerDelegate()","1b64b172":"core(uint256,address)","1b65144d":"burnTokensForSale()","1b6527b4":"GetAssignedAddress(uint256)","1b655054":"dataAddress()","1b660f15":"EthIdentity(bytes32)","1b66303d":"request(bytes32,uint256,uint8)","1b66cb00":"setTargetToken(address)","1b672154":"setMEAAttributes(uint256,uint256)","1b677b08":"total_snt_claimed()","1b67ab2b":"StreamNetworkToken()","1b688565":"PUBLIC_RESERVED_PERSENTAGE()","1b697bb2":"setBuyerAddress(address)","1b6aa580":"developer_new_address_for_funds(address)","1b6ad60a":"transferFromWithReserving(address,address,uint256)","1b6aed05":"grant_token_from_offchain(address,uint256,string)","1b6b405c":"UnableToAcceptPayment(address,bytes8,uint256)","1b6b6d23":"LINK()","1b6b8656":"setBureau(address,address,address)","1b6bb739":"getThreeLastInvestors()","1b6bc433":"addMemberAcct(address)","1b6c104e":"marketingAllocationTokenSend(address,uint256)","1b6caad9":"setPersonaAttributes(bytes)","1b6e37ee":"thirdWeekBonusInWeek()","1b6e66aa":"rescueInvestor(address,uint256)","1b7035ea":"getAccountStatus()","1b709561":"UnlockCredits(address,uint256)","1b70a2e1":"TerpCoin()","1b72194f":"getUserDivs(address,uint256)","1b72410b":"EladCrowdsale()","1b728ed4":"getAssetRawMeta(uint256)","1b748399":"TeamCoin()","1b753dad":"Mithril()","1b75738a":"enable(address[])","1b760719":"addMember(address,string,uint256)","1b7623be":"payInterest(address,uint256)","1b76929c":"getActiveGames()","1b769e74":"testThrowsRestartNotUpdatable()","1b76dd7c":"disapprove(uint256,string)","1b773df1":"withdrawAll(string,uint256)","1b775638":"ContributionReceived(address,bool,uint8,uint256,uint256)","1b776808":"_updatePixelMapping(address,uint256,uint256,uint256,bytes32,bytes32)","1b78240f":"Fixie()","1b78e3c4":"processHunting(uint256,uint256,uint256[])","1b7949e2":"supply_increased()","1b79a2f3":"lastStageSubmitted()","1b79d406":"getWhoPiad(uint256,address,address,address,address,address,address,address)","1b7aad1b":"AMOUNT_TOKENS_FOR_SELL()","1b7b7b0d":"latiumBalance()","1b7b7c3d":"Partnership(address[],uint256)","1b7bbecb":"challengeExists(bytes32)","1b7be47e":"STQToken(address[])","1b7c058e":"getLicensePrice(address)","1b7ccc3d":"_registerLockedDeposits(bytes32,uint256,uint256)","1b7ce6f3":"disableTokens(uint256[])","1b7cf899":"recentActivity(uint256)","1b7d5f8c":"release18m()","1b7d83e5":"addDefaultOperator(address)","1b7d8aaf":"End8()","1b7db340":"sysAdmin()","1b7e0902":"getcardOwner(uint256)","1b7e78f6":"updateFirstChangeBlock(uint256)","1b7f00c1":"purchaseBundle(uint8,string)","1b800a3d":"watchPreferersTasks(address,uint256)","1b814f02":"splitFunds()","1b8202a7":"LegalContractManager()","1b825e89":"detachmentTime()","1b82f68f":"kingdomFactory()","1b83b823":"notifyPlayer(uint256)","1b841fea":"nextDerivativeTokenTime()","1b848606":"blacklistEscapeToken(address)","1b84e72d":"_createEscrow(address,address,uint256,uint256)","1b851e10":"LogDeposit(address,uint256)","1b855044":"getHash(uint256,uint256)","1b85aa49":"MIN_INVEST()","1b862027":"save(uint256)","1b8689b6":"getInvestorTokensPurchasesLength(address)","1b878f71":"setUpgrader(address)","1b87945e":"buyPointer(bytes32,bytes1[64])","1b87ccae":"getAssetIdItemType(uint256)","1b87d58a":"bonusMin()","1b88094d":"getRecipient()","1b880bcf":"KareToken()","1b89ee31":"closeBridge()","1b8a0b46":"WowDiaondToken(address)","1b8a9031":"BetPlaced(uint256,address,uint256,uint256)","1b8ab64d":"testTodo()","1b8b13a7":"getRewardPool()","1b8b3605":"setInvestorList(address)","1b8b4787":"TOKEN_SALE2()","1b8b921d":"call(address,bytes)","1b8bd57c":"getCardInfo(uint32)","1b8beafe":"BLOCK_DURATION()","1b8ca217":"getProperties(uint256)","1b8d0e60":"getMyBanker()","1b8db774":"_deadline()","1b8de48c":"distributeTCASH(address[])","1b8e61c7":"setEndTimePreIco(uint256)","1b8e94a1":"Rate()","1b8ef0bb":"getRemainingCapacity(uint256)","1b8f2610":"quickCloseChannel(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","1b8f3d23":"krakenTicker()","1b8f5d50":"multi()","1b8f66a4":"watchedURL(string,string)","1b8fc2f0":"setAllowedAddress(address)","1b8fc6e4":"marketorsTotalBalance()","1b900c27":"anotherOwner1()","1b924b7e":"enableInterface(string,address)","1b9265b8":"pay()","1b929940":"pushIntArray(bytes32,int256)","1b92ce6b":"WOCC()","1b93aa8d":"getPackage()","1b93f66d":"claimedAirdrop(address)","1b9414ae":"itemBid(uint256)","1b94198d":"sellingAccepted()","1b94413f":"transferEth(bytes32,address,uint256)","1b949f85":"lockContractOwner()","1b953909":"authorizeOperatorTranche(bytes32,address)","1b955df4":"changeRefund(uint8,uint256,uint8)","1b962c65":"decodeCurrency(bytes32)","1b963742":"AwesomeToken()","1b968160":"wipeAndFree(address,bytes32,uint256,uint256,address)","1b96b2f9":"masterMint(address,uint256)","1b97429d":"EthToUsdChanged(address,uint256,uint256)","1b981d7f":"packedToSubmissionBits(uint256)","1b987c41":"retrieveExternalTokens(address,address)","1b98c54f":"getProviderCurveLength(address,bytes32,int256)","1b98cd68":"updateAffiliate(address,uint8)","1b98f6ac":"setProviders(address[])","1b9900b8":"userRollDice(uint256)","1b995aa7":"BitCompare(uint256,uint256)","1b998dac":"updateMCs()","1b9a91a4":"withdrawEth(address,uint256)","1b9b0b23":"KruhftsToken()","1b9bfa3a":"_oldOwnersOf(uint256)","1b9c7f31":"Werbecoin()","1b9cbdfb":"priceOfToken()","1b9ceef1":"purchaseTokenInPublicSale()","1b9d1bed":"setPOOL_edit_18(string)","1b9d4c8e":"setBudget(address,address,uint256)","1b9db2ef":"getParticipant(uint256)","1b9dbcaf":"kittensIssued()","1b9e16ad":"getAccountInfo()","1b9e9a27":"createComponent(string)","1b9f9647":"accessMyWallet(address)","1b9fec58":"getBlockToHashForResults(uint256)","1ba1648a":"changeTokensOwner()","1ba1f10b":"updateTaxPercentages(uint256,uint256)","1ba22084":"ecadd(uint256[3],uint256[3])","1ba23f1e":"setAllowedMultivest(address,address)","1ba326c4":"calcShare(uint256,uint256,uint256)","1ba39a4c":"calcMult(uint256,bool)","1ba3afd3":"getLocalGame(uint16)","1ba46cfd":"assetAddress()","1ba527d6":"gkAddress()","1ba54100":"distributeEbyteForEBYTE(address[],address,uint256,uint256)","1ba5b3e8":"currentTotalAirdrop()","1ba5e63f":"tournamentQueueSize()","1ba5eec0":"nextTurn()","1ba60f9b":"availableDgxNg()","1ba6e1bd":"externalPurchase(address,string,string,uint256,uint256,uint256)","1ba7013b":"distributedBountyTotal()","1ba83c3c":"ChargingGas(uint256)","1ba88666":"isBiometricLockedOnlyOwner(address)","1ba8ef21":"electrolightTestnet()","1ba9146e":"PethToken(uint256,string,string,uint256)","1ba91c20":"foundationMultisig()","1ba9998b":"advanceRound()","1baaeb91":"getSignature(bytes4,uint256)","1bab0908":"hasValidParam(address,uint64,uint64,uint64,uint64,uint64,uint64)","1bab8148":"fulfillMintRequest(uint256,string)","1bacbf4e":"secureTransfer(uint256)","1bacfd66":"Vote(address,bytes)","1bad1d2e":"monitorWallet(address)","1bad3903":"stakeWithCurrentPeriod(uint256)","1bad5558":"withdraw3(address)","1bad9e8f":"getUserTokenInfos(address,uint256)","1bada3c0":"closeKYC()","1badbd5c":"increaseAssuranvePayments(address,uint256)","1badfbae":"setWhitelistBallot(address,bool)","1baf1494":"QToken(address,uint256)","1baf7122":"custodyStorage()","1baf823f":"NewUsername(address,string)","1bafc373":"confirmNewHash(uint256)","1baffe38":"withdrawEtherTo(address,uint256)","1bb00447":"CryptonomicaVerification()","1bb02ffb":"MWAV()","1bb0b762":"A2ABToken()","1bb0c665":"toHexString(address)","1bb1151a":"Error(uint64)","1bb1bf2e":"team1Query()","1bb2921b":"getProjectedPayout(uint16)","1bb3fb67":"operatorSendTranche(bytes32,address,address,uint256,bytes,bytes)","1bb4067b":"checkPoolDone(uint256)","1bb409c4":"QueryBonus()","1bb460cc":"ContributionReceived(address,uint256)","1bb47b44":"appendVestingEntry(address,uint256,uint256)","1bb534ba":"fundingRecipient()","1bb58beb":"RECToken(uint256,string,uint8,string)","1bb5f0a2":"registerBarcode(bytes9,string,string,string,string,string,string)","1bb63d0c":"Nova()","1bb6cb47":"getPlayer2()","1bb73a2a":"batchCreateAuthorDrawings()","1bb797da":"isIcoStage()","1bb7c3c2":"UpdatedDonationAddress(address)","1bb7cc99":"WHITELIST()","1bb8365f":"calculateGoldBuy(uint256,uint256)","1bb96dff":"AuctionStarted(uint256)","1bbb4f63":"LogMoneyline(int256,int256)","1bbb696a":"swapContracts(address)","1bbb9a99":"claimEthers(uint256)","1bbc4b83":"ERC20Interface()","1bbc7952":"getPropertySalePrice(uint16)","1bbc99c6":"UpdateDividendPartners(address[],uint256[])","1bbce9a2":"bidState(bytes32)","1bbe1813":"getTotalSpecials()","1bbe2ff3":"TransferEtherInitiationEvent(uint256,address,address,uint256)","1bbe9d8c":"addFunder(address)","1bbec4e7":"coldWallet2()","1bbef399":"isVoting()","1bbfb029":"addTx(address,address,uint256,string)","1bbfce0e":"bidOnBreedingAuctionTutorial(uint40)","1bbfdaaf":"selectElf(uint8,uint16)","1bc0585f":"stopTokenSale()","1bc08834":"stsc()","1bc125f3":"finishMintingSTO()","1bc2dd5a":"doesContractExist(address,address)","1bc390dd":"reconfig(string,string)","1bc3c855":"setWhiteListERC223(address)","1bc41284":"uncleRate()","1bc44200":"Dasabi_ioToken()","1bc44213":"MAX_BID_FRAC_BOT()","1bc4c81b":"QuizQuestion()","1bc4cdb9":"ReceiveFund(address,uint256)","1bc4d6b2":"XXXXToken()","1bc50b05":"canUpdateNextGamePotSplit()","1bc59aa6":"bountyAllocated()","1bc5ee1a":"transfer_eth_to_contract()","1bc84458":"getAddOnSupport(uint16)","1bca179b":"RentedBlock(uint256,uint256,uint256,uint256,address)","1bca5689":"havvensReceivedForEther(uint256)","1bca7d6d":"NigelFundSum()","1bca989e":"setTokenInfoMaxPerBlockImbalanceList(uint256[])","1bcad37a":"getTotalCost()","1bcb6fa2":"snapshotValidators(uint256)","1bcbce52":"isEarlyInvestorsTokenRaised(uint256)","1bcc9b1a":"TruPreSale(uint256,uint256,address,address)","1bcd57c7":"ContributionAmount()","1bcdb8e0":"responder(uint256,uint256,uint256,bytes5,bytes14,bytes5,uint256,uint256,uint256,uint256,uint256,uint256)","1bcdd57d":"writeNextId(uint256)","1bce6ff3":"begin()","1bceeaa7":"resell(address,string)","1bcf468b":"costOfToken()","1bcf5241":"countCliTasks()","1bcf5758":"getOccupies(uint8)","1bcf659d":"getMinTalent(uint256)","1bd0c431":"updateETH()","1bd13df1":"GetSummFee(uint256)","1bd16dbf":"preSaleDuration()","1bd2511a":"addEarlyAccessAddress(address,address)","1bd27296":"_fetchCancelledOrdersForMerchant(address)","1bd2b37c":"isMasterRecruitment()","1bd2c21c":"playBigger(uint256[])","1bd2d4cc":"getNextIndex(uint8)","1bd3553e":"TheTokenA()","1bd5363c":"getBPaddress()","1bd5d127":"NaviToken()","1bd60ae9":"buyerBalance(address)","1bd61eee":"updateHeartBeat()","1bd6f596":"right56(uint256)","1bd6fb9f":"LockedFunds(address,uint256)","1bd72647":"round0Target()","1bd8b041":"PRICE_INCREASE_SCALE()","1bd8f9ca":"challengeFee()","1bd95155":"stringToUint(string)","1bd983a4":"PlaceSellOrder(uint256,uint256)","1bd9a7e7":"LogNewWhitelistUser(address,uint256)","1bd9c46e":"setImporter()","1bda6d55":"publicSaleSoldTokens()","1bda84b3":"getOfferIdsByToken(address)","1bda8781":"Taouaf(uint256,string,uint8,string)","1bdb3f65":"ZoomToken()","1bdbabdd":"registerProduct(uint256,bytes32,bytes32,uint256,uint256)","1bdbce49":"setWhitelist(address,address,bool)","1bdc4038":"_updatePurchasingState(address,uint256)","1bdd193a":"placeStar(uint8,uint8,uint16,uint256)","1bddcf48":"_asyncTransfer(address,uint256)","1bde9998":"getWhitelistStatus(address,bytes32,address)","1bde9bc1":"rebatelvlEconomy(string,string,string,string,string)","1be05289":"DURATION()","1be0717f":"_reward()","1be0f1ad":"getSpinOutput(uint256,uint256,uint256,address)","1be0f793":"USDExchange(address)","1be16003":"Answer()","1be1bf7f":"TessrX()","1be20ca1":"TokenCAP()","1be22528":"TechnicalRise()","1be3175e":"mortgage(uint256)","1be35b0c":"statusOperation()","1be4aaa1":"getTokenInfoHeritor(address,address)","1be4da5b":"MateriaPrima()","1be64997":"BucketCreated(bytes32,uint256,uint64)","1be6ce57":"decreaseOwnershipTokenCount(address)","1be6dd64":"points()","1be70510":"acceptAdoptionOffer(bytes5)","1be73e2b":"_fhMoney(uint256,uint256,uint256,uint256,uint256,uint256)","1be7c5ef":"fullfillFounder()","1be863bf":"PushData()","1be88614":"onetimeLaunch(uint256)","1be8dbfd":"dsMul(uint256,uint256)","1bea4a61":"getObjIndex(uint64)","1bea67b7":"BFDToken()","1bea69e3":"isAdmin(address,string)","1bea8006":"tokenBalanceOf(address,address)","1beafada":"PROMETHEUS_PRICE_THRESHOLD()","1beb2615":"destruct(address)","1beb375d":"proxyManagementAddress()","1beb4b5e":"fetchAllVoteResultBySnapshotBlock(uint256)","1bebf13c":"sendOrderEvent(address,uint256,uint256,uint256,address,uint256)","1bef9059":"ProtocolToken()","1befcbaf":"buyRareEgg(uint8,uint256,address)","1befd26a":"setDesignatedReporterWasCorrect(bool)","1bf028b1":"OddMoney(address,uint256)","1bf049b9":"Prediction(uint24,uint24,bool)","1bf0635b":"setGoldFeeAddress(address)","1bf1de9b":"COMMISSION_PERCENTAGE()","1bf20668":"testAdminTransfer()","1bf219de":"Faucet(uint256,address)","1bf2a90a":"totalPostIcoContributorIdsAllocated()","1bf38b28":"addAccessor(address,address,uint8,address,string,uint32,string,string,bytes32,bytes32,uint8)","1bf426ba":"Spendelotto()","1bf498b6":"registAgent(address)","1bf57f41":"salesAddress(address)","1bf5b38a":"finalizeDonation(address)","1bf5f736":"endOfDay()","1bf651ff":"YBHY()","1bf678cf":"setOtherNTech3D(address)","1bf6ba7e":"_transferFromOwner(address,uint256)","1bf6c21b":"USD()","1bf6e00d":"frozenOf(address)","1bf6e939":"accManager()","1bf703b2":"addCategory(string,string)","1bf7628b":"firstHolder()","1bf7d749":"curves(uint256)","1bf831cf":"initialOperatorValue(address)","1bf8c094":"setOwnedToken(address,uint256,uint256)","1bf983a6":"getTokenInfoMaxTotalImbalanceList()","1bf9b325":"deletePublicKey(address)","1bf9b387":"setIcoRate(uint256)","1bf9def0":"Transferable()","1bfa5d8a":"hash_pubkey_to_pubkey(uint256,uint256)","1bfa90bf":"getIntField1()","1bfaf155":"foundersWallet()","1bfb7245":"tToken(address,uint256)","1bfba595":"incrementTotalIssuerCount()","1bfc596b":"presaleBonusAddressColdStorage()","1bfc8bd1":"setRequestIdToMultiRequestId(uint256,uint256)","1bfce853":"vestedAmount(uint256)","1bfd4858":"hash_db(bytes32)","1bfd6814":"TRANSFERABLE()","1bfe0308":"removeRole(address,string)","1bfe3508":"triggerRecoveryAddressChange(address)","1bfe7831":"AllLockAccounts(uint256)","1bfe783e":"MaxDropReward()","1bfea87f":"by(bytes32)","1bff4786":"etherDeltaInfo()","1bff4bfa":"beneficiaryTwo()","1bff4c07":"LukaCoin()","1c0019c4":"getCostForTrait(uint8)","1c014c60":"casinoBalance()","1c0183e3":"TweedentityRegistry()","1c02708d":"killContract()","1c02a63d":"SetEcosystemContract()","1c0463de":"isUpgradeAllowed()","1c05123d":"LicenseIssuer(string,string,string,uint256,uint256,address)","1c054b14":"bonusRangeCount()","1c057493":"withdrawERC721(uint256,uint256,address,uint256)","1c07f0a3":"getAccountKeys(uint256)","1c080404":"contributed3(address)","1c08366b":"tokenPCT(string,string,uint8)","1c084385":"WhitehatWithdraw(address,address,address,address)","1c085a21":"totalRaiseWei()","1c088897":"MINER_AUCTION_DURATION()","1c08c08e":"claimBond(uint256)","1c09496a":"transferWithSignature(address,uint256,uint256,bytes,uint256,bytes)","1c09c194":"testInsertMultipleProductsIntoCart()","1c0acbd5":"bidOnDklSiringAuction(uint256,uint256,uint8,bytes,uint256,uint256,bytes,uint256)","1c0ad646":"coreAddress()","1c0b6367":"processTransaction(bytes,uint256)","1c0bbe26":"createAccountForUser(address)","1c0c3d33":"mintAuthorizedBatchWithBalances(address[],uint256[])","1c0ce15f":"TUBE()","1c0d1274":"setCCH_edit_21(string)","1c0de1b3":"LogResult(bytes32,uint8,bytes,bytes)","1c0e0225":"minDonation()","1c0e7109":"addFreelancer(address,uint256[],address)","1c0f12b6":"transferFrom(uint256,address,address,uint256)","1c0f96bb":"ManagerProxyTargetMockV1(address)","1c0f9a7c":"requestEURPrice(string)","1c114b38":"canReadInDataObject(address,bytes32[])","1c11fce2":"requestToken(address,uint256)","1c135881":"testHardCap()","1c1401e7":"OWNER_TRANSFER_TOKENS()","1c140bdd":"addCampaign(string,string,string,address,address,address,string)","1c14179a":"GavCoin()","1c14b340":"passMessage(address,string)","1c152982":"addEditwalletContractAddress(bytes8,address)","1c15b285":"getAmbientHumidityControlLimits(bytes32)","1c1697ae":"get_presale_arbits_per_ether(address)","1c169ba5":"closed_()","1c16c3ad":"calcAirDropAmount(uint256)","1c177502":"LogCollectEth(uint256,uint256)","1c1935ce":"getHistoricPrice(uint256)","1c196d77":"returnSubscriptionDesposit(uint256)","1c1b8772":"update(address)","1c1bc850":"changePayee(address)","1c1bd814":"TIMEOUT_TIME()","1c1c2289":"userKey()","1c1d7517":"dedeNetwork()","1c1f6a3f":"removeTokenFrom(address,uint256)","1c20be7e":"getVestingBalance(address,address,address)","1c226164":"isAddressVoted(address,address)","1c22ac19":"aprovaDevolucao(bool)","1c22b196":"TransferTRAC()","1c22f765":"zhoudayiToken(uint256,string,uint8,string)","1c232194":"refundPreSale()","1c23281c":"GZSToken(uint256,string,uint8,string)","1c2353e1":"isCertifier(address)","1c235f5f":"getHipstermasterReq()","1c238e1f":"Signum(address,address)","1c23e280":"buyTicketsFor(address,uint256)","1c249494":"setStarted()","1c24f0bd":"applyForCertification(string,string,string,uint256,uint256,uint256,uint256,uint8,uint8,uint16)","1c25331d":"setMaximumNonWhitelistAmount(uint256)","1c25f452":"topupSupply(uint256)","1c27e291":"refundCoin(address)","1c27f30b":"Lover()","1c28b99e":"pressFee()","1c296b34":"cryptiblesAuctionContract()","1c2ac59d":"sosoToken()","1c2ac5ac":"IcoStatus()","1c2b1e54":"SalesManagerUpgradable()","1c2bbd18":"exchangeTemplate()","1c2d6356":"getActivityName(uint256)","1c2e2796":"ContractCallerProxy(address)","1c2f2f9f":"recoverAndSetSecretHash(string,bytes32)","1c2f38ff":"paid(uint64)","1c30549f":"set_rand_addr(address,uint256)","1c3101d3":"addRecipient(address)","1c3122ba":"BuyStartingSnails()","1c31f710":"setBeneficiary(address)","1c321f62":"executeLottery()","1c3274ff":"PlayX10()","1c338601":"setProviderInfoFields(uint256,string,string,uint256,string,address,uint8)","1c338644":"withdrawERC20Balance(address,address)","1c350d6b":"TRLToken()","1c35b76f":"VOLUME_BONUS_CONDITION()","1c35e7ba":"manualFinalizeRound()","1c363e14":"DeathFactor_v()","1c38f800":"currentIcoSupply()","1c398075":"sellClimateCoinsAgainstEther(uint256)","1c39b5c4":"Administrated()","1c39c375":"buyUninitializedPixelBlocks(uint256[],uint256[],uint256[],bytes32[])","1c3a36d0":"addComment(bytes3,string)","1c3a5713":"getProposalExternalTokenReward(bytes32,address)","1c3a8892":"closeRoom(uint256)","1c3ad417":"getBAS(bytes32,address)","1c3b093f":"Track(address,bytes,uint256,uint256)","1c3b3b9f":"expandPeriod(uint8)","1c3bc31f":"firstPreSaleEndDate1()","1c3c050c":"genTime()","1c3c0ea8":"setExecutor(address)","1c3c295e":"registerInstitutionAsset(string,string,address,address)","1c3cbf07":"TokenTest123()","1c3cf5d0":"setEditionPackPriceIncrease(uint8,uint256)","1c3d4f20":"ChangeBalance(address,uint256,address,uint256,uint256)","1c3db16d":"currentRuling(uint256)","1c3db9a8":"approveFlower(address,uint256)","1c3de07a":"calculateCoinSell(uint256)","1c3f2f8c":"dealsNumber()","1c3f7637":"isAllowedHICAddress(address)","1c3fe22d":"GaillardCrowdSale()","1c40baf5":"EUROCASH()","1c41d143":"KPTLToken()","1c41e2db":"getEducation()","1c423713":"addPromoCode(string,bytes32,uint256,uint8)","1c4261f4":"createGift(bytes32)","1c429165":"tryRollRoom(address,uint256,uint256)","1c42959c":"maximumCap()","1c42daf7":"winMeta(address,bytes32)","1c435872":"setInterRefreshLock(bool)","1c43814f":"registerAsSlaven(string)","1c43b4a6":"initAddressAsMultiOwner(address,string)","1c43d8b1":"EndEvent(bool)","1c442754":"participated(address,uint256)","1c448231":"SDToken()","1c44bac7":"tournamentBankCut()","1c465538":"DoFee(uint256)","1c465e87":"getTopOnce()","1c467dec":"HODLrSellWin(uint256)","1c47624b":"getUserProductContracts(address)","1c480cb6":"remove(int256,int256)","1c481767":"sendfrozen()","1c484766":"aloha()","1c484a34":"enableSuperDragon(bool)","1c488825":"MintTokens()","1c490883":"MelonBitIndex_Erc223Token()","1c49b101":"_preValidatePurchase(address,uint256,uint256,uint256)","1c49d19f":"finishRoundC()","1c4ad465":"custodyFactory()","1c4b0da6":"setMinSalePrice(uint256)","1c4b1ff7":"setGood(bytes32,uint256)","1c4b774b":"getReward(uint256)","1c4b8659":"getBoardSingleSpaceDetails(uint256,uint8,uint8)","1c4bcbb0":"distributePowerToAddress(address,uint256)","1c4be509":"forkTransfer(address,address,address,uint256)","1c4bfcfe":"BoxChange(address,uint256)","1c4c710b":"getAreaIndex(string)","1c4d5608":"getSchemeParameters(address,address)","1c4d749b":"GetContractStateActive()","1c4e6cd0":"NameReg()","1c4ef6c2":"ethPriceInEuroCent()","1c4fda10":"tokenSafe()","1c50e880":"cancelAuctionHashing(uint256,uint64)","1c51a8e0":"setConfigString(string)","1c533a09":"Trupee()","1c53faf8":"backSggCoinOwner()","1c5412f7":"_computeCut(uint256)","1c54220d":"c_centsPerTokenSecond()","1c545049":"maxPresaleEDUSupply()","1c548c78":"foreignBridgeProxyOwner()","1c54e565":"getNextUserId()","1c54fbab":"getShip(uint16,uint16,address,address)","1c558b71":"ORIUMCOIN()","1c560f68":"CreatePreSale(address,uint256)","1c5633d7":"setPeriodLength(uint256)","1c566ef2":"setOperationAttributes(string,uint256,string)","1c568925":"addPendingUserListArr(address)","1c572f8c":"getICOPercentage(uint8)","1c5736ee":"add_record(string)","1c575f7f":"sendDivsToBankroll()","1c57a386":"oraclize_query(string,bytes[1],uint256)","1c581205":"targetAmount(address)","1c58c3ff":"totalMineSupply()","1c58d0d2":"_unsafeDecodeTokenId(uint256)","1c5992ff":"Zandar()","1c59a667":"disableBlacklist(address[])","1c59c177":"FCCContribution()","1c5a3942":"BPPOL()","1c5a5a58":"getRandomNum(address,uint256)","1c5a5bc4":"createShip(uint256,string,uint256,uint256,uint256)","1c5a9005":"HashRemoved(address,string)","1c5a9d9c":"activate(address)","1c5be3d7":"updateTimestamp()","1c5ca530":"IprontoToken()","1c5caa6b":"Rate9()","1c5d3c60":"stateIsWaitingProofs(uint256)","1c5d9faa":"setNickname(string)","1c5daad7":"_maint_withdrawFromPool(uint256)","1c5eaa23":"findByModuleText(string)","1c5ef50b":"Rasper()","1c5f2810":"setnewowner(address)","1c5f3176":"someMethod4(uint256,uint256,uint256)","1c5f8675":"getMyTuple()","1c5fe1a4":"TeamAmount()","1c606dd3":"GetConstructCost(uint256,uint256)","1c607f14":"setDynamicArraySize(uint256)","1c60a158":"TEAM_TOKEN_AMOUNT()","1c60f3bb":"buyEthCards(uint256,uint256)","1c61babe":"CelsiusToken(uint256)","1c61bd38":"showValue()","1c61f2bc":"fuckingClaim2(bytes,bytes)","1c623ddd":"reward(bytes32,uint8,bytes32,bytes32,bytes32,uint256)","1c624a60":"qtyInitiators()","1c624d19":"mintObizcoinTokens(address,uint256)","1c637987":"_setAuctionStatus(bytes32,uint8)","1c638376":"setProductAttributesByRegulator(string,string,uint256,uint256,string)","1c63c6c3":"setPartData(uint256,uint256,uint256[])","1c64065d":"myInfraList(address,uint256)","1c6416ad":"pubaddr()","1c65706e":"allowInvest(address,address)","1c657c63":"setEtherInUSDInternal(string)","1c668855":"getGenotype(uint256)","1c674fba":"createRandomBox(string,address,uint64,uint256,uint128)","1c67a7aa":"TransCompleted()","1c67e9a6":"setTokenStatus(bool)","1c68571d":"bonusLimit1()","1c6868c8":"adjustBonusPrice()","1c68fe82":"listProperty()","1c69ad00":"balance0()","1c6a0cf8":"GuangPengChain()","1c6a866c":"Collect_accrued_interest_and_transfer(address,uint256)","1c6b69b7":"rateCent()","1c6b7c1d":"EtherTransfer(address,address,uint256)","1c6ba386":"_claimReward(address,uint256)","1c6ce9a3":"executeSendCapital(address,uint256)","1c6d31f7":"xxx()","1c6d4575":"getTokensAmountAllowedToWithdraw(uint256)","1c6d6483":"approveMappingProposal(address)","1c6debbb":"UnionChainSupply()","1c6e3899":"getTierId(uint256)","1c6ef374":"recordingResultsOfBet(bytes32,bytes32[],uint8[])","1c6f609b":"cooperativeClose(address,uint32,uint192,bytes,bytes)","1c6f634e":"oracleItQuery(string,string)","1c70362c":"setSettingValues(uint8,uint8,uint16,uint16,uint16,uint16,uint16,uint8,uint8,uint32,uint32,uint8)","1c7040cc":"setProxyCurator(address)","1c7106e6":"setOracleAPIAddress(address)","1c7276f5":"updateLuck(uint256,uint8)","1c72e225":"transformSeedToFlower(address,uint256)","1c7307f4":"get_topl_address(address,address)","1c732d83":"centsToWei(uint256)","1c73561f":"jobCompleted(bytes16,address,address,uint256,uint256)","1c73601e":"getUncorrelatedRN(uint256)","1c74d5c8":"Successor(address,address)","1c7564cb":"DWMP()","1c75b6b2":"setDevFee(uint256)","1c75f085":"teamAddress()","1c761245":"buyDOTCH(uint256)","1c762a27":"show_Balance_of_interest_bearing_deposit(address)","1c77a4ec":"Lemmon()","1c77c58c":"collectRoundLength()","1c7a08ef":"isActivate(uint256)","1c7a39e2":"_distributeRewards(address,address,uint256)","1c7a3c9d":"setExchangeContractAddress(address)","1c7a3d31":"updateNextOrderUser(address,address,uint256,address,address)","1c7b10aa":"merkleTreeRoots(uint256)","1c7b530a":"secondTotalSupply()","1c7bfdce":"test_votingWhenCertified()","1c7d5334":"DORCoin(address)","1c7f3a96":"getMarketCreatorSettlementFeeDivisor()","1c7f578a":"mintC()","1c7f6942":"getPlayerSpaceshipModelByIndex(address,uint256)","1c7f98ca":"getRunInfo()","1c800d64":"insert_helper(uint256,bool,uint256)","1c81525c":"NitinToken()","1c81bcfb":"dividendPathways()","1c81ed15":"raiseSupply(uint256)","1c8293c4":"PriceChanged(uint256,uint64)","1c82a013":"onOffCrowdSale(bool)","1c844171":"bakkaToken()","1c8499e5":"greeter()","1c857765":"sumElements(uint128[])","1c85d890":"productListing(bytes32)","1c85ee51":"getBasicIncome()","1c8670fc":"endEarlyStage4()","1c8685e0":"WXSLToken(uint256,string,string)","1c87055f":"Fund(address,address,address,address,address,address,address,address[])","1c870eee":"setUserPermission(address,bytes4)","1c878c97":"releaseLockAgencyLock1()","1c879c47":"getMarketHashes(bytes)","1c87deec":"returnTokenDepositState(address,bytes32)","1c895915":"getNumberOfPayments(uint256)","1c89f174":"calculateUserBid()","1c8a1e20":"membershipAddress()","1c8a3821":"AllocateFounderTokens(address)","1c8a7795":"archiveText(string)","1c8c4509":"addSiteSet(uint256,uint256)","1c8ca56d":"stopSelling(bool)","1c8cba3b":"getSubjectClaimSetSize(address,uint256,uint256)","1c8ce890":"disburse(address)","1c8d25bc":"proposed_beneficiary()","1c8d51e6":"getSentAmount()","1c8d5d38":"allowance(address,address,bytes32)","1c8dddbd":"editContributors(address[],uint256[])","1c8e9a6f":"commitWork(uint256)","1c8eac0f":"endFunding()","1c8f7570":"depositLogic(address,uint256,uint256,uint256)","1c90e9cf":"testwallet8()","1c9193c0":"TakeOut(uint256)","1c91a6b9":"startExit(uint256,bytes,bytes,bytes)","1c921e16":"claimHeirOwnership()","1c92b497":"crowdsaleInitialSupply()","1c92cab2":"auto_transfect(address[])","1c931313":"setDesignatedReportDueTimestamp(uint256)","1c931439":"getLockedContractAddress(address)","1c933e2f":"multiplyDecimalRoundPrecise(uint256,uint256)","1c946642":"intellisys()","1c949bdf":"setEtherollAddress(address)","1c95b42e":"payBonus()","1c95c89d":"authorizeForToken(address,address)","1c96b242":"balanceOfReal(address)","1c96ef03":"Presale(address,address,address)","1c9713bd":"transferTobucketOneContract(address)","1c973c57":"getSpecialityValue(uint256)","1c982066":"refreshGameTime()","1c983347":"maxBidPercent()","1c98680f":"_redeemByDefaultTranches(address,address,uint256,bytes,bytes)","1c990670":"realDividends(address)","1c991783":"mintUniqueTokenTo(address,string,uint256)","1c997344":"createBid(bytes32,address,uint256)","1c9981f8":"donate(address,address,bytes4)","1c99d341":"removeParty(uint256)","1c9a5ddf":"returnBox()","1c9ab3ad":"getBlockData(uint256)","1c9ad79d":"newCampaign(string,address,uint256,uint256,address)","1c9b612e":"ledTokensAllocated()","1c9c549d":"buyEggPrice()","1c9cae74":"removeScore(uint256,uint256)","1c9cafd7":"tan(int256)","1c9cf54c":"getStockAmount(address,uint256)","1c9e9999":"migrateDungeon(uint256,uint256,uint256,uint256,uint256,uint256,address)","1c9f289d":"setCCH_edit_6(string)","1c9fbb11":"finishPreSale3()","1c9fe5d7":"BRONZE_AMOUNT_TPT()","1c9feaa5":"isExecuted()","1ca0076c":"multisend2(address,address,address[],uint256[])","1ca03b8e":"senderHasRole(string)","1ca0a28d":"multiTransfer(address,address[],uint256[])","1ca19ece":"IsaDalawa()","1ca2d6b7":"WalletChange(address,uint256)","1ca2e94a":"setPresalePhase(uint8)","1ca3630a":"updateComponent(string)","1ca3d4b7":"icoPhase4End()","1ca4399b":"DEV_TEAM_HOLDER()","1ca43cef":"ADMISSION_TIME()","1ca46d61":"bigChicken()","1ca5df03":"multiVesting(address[],address,uint256[],uint256[],uint256[])","1ca60aeb":"setMeltingContract(address)","1ca750f4":"privateSaleTokensSold()","1ca7bcc7":"toBytes32(bytes,uint8)","1ca84592":"RA(address)","1ca84efc":"secondTTaxAmount()","1ca8b6cb":"totalTokenSupply()","1ca9ad47":"createLockingTokenVaults()","1ca9fb9d":"updateContract(uint256,uint256,uint256,uint256)","1caa0c6d":"saleExchangeRate5()","1caa5ccb":"startDapp(address,address)","1caba41f":"decimalUnits()","1cabc5ed":"userVoteFor(address,uint256,uint256)","1cabc785":"getPlayerDefend(uint256)","1cabe3ef":"pethPEReth(uint256)","1cac31d7":"setAdvisorsTokensWallet(address)","1cac7b7f":"MINERTA()","1cad5a40":"depositERC20(address,address,uint256)","1cadd93e":"initPlayers()","1cae7c2f":"TransferCoinsEther()","1cae947a":"firstPrivateLockedAmount()","1caf1752":"Coinvilla()","1cafc144":"distruggi()","1cb07902":"mintMore(address)","1cb08889":"MERIDIANERC20(string,string)","1cb0d481":"transferTokens(address,uint256[],uint256[])","1cb120d6":"ENSRegistry()","1cb1778a":"setup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256[],uint256[])","1cb20fe6":"Devcoin()","1cb252fe":"investorsTotal()","1cb2dbf6":"Reduction(string,address,uint256,uint256)","1cb3bbc0":"updateGlobalUnlockTime(uint256)","1cb3d9be":"grantEditorRights(address)","1cb5bfc4":"LogBet(bytes32,address,uint256,uint256,uint256,uint256)","1cb64196":"ethStore()","1cb6adec":"tubFab()","1cb78879":"TitleDelisted(uint256)","1cb82d79":"registrarOwner()","1cb9a02a":"calculateScore(uint256,uint256)","1cb9ce63":"makeCall(address,bytes)","1cba6f79":"_isERC721Contract(address,address,uint256,bytes)","1cbaaea7":"set_payment_details(uint256,string)","1cbaee2d":"saleStartTime()","1cbb67c4":"FooUser(address)","1cbc5ab1":"Buy(address,uint256,uint256)","1cbcb9b9":"BellaBluToken()","1cbcc77c":"test_suicide()","1cbd0519":"accountLevel(address)","1cbda93d":"p_update_mResalePlotDevPercent(uint256)","1cbea83d":"proposalReason(uint256)","1cbea99b":"getAddress(address[],bool,bool)","1cbeae5e":"winner(uint256)","1cbfbe47":"assignTokensToMultipleInvestors(address[],uint256[])","1cc0eb83":"kickcityWallet()","1cc13dff":"totalplayers()","1cc1cf46":"paymentInterval()","1cc1e7bc":"appendPacket(bytes)","1cc2502e":"auctionList()","1cc48f08":"getResolverAllowance(string,address)","1cc54204":"totalGenesisAddresses()","1cc69ac1":"assignNewParcel(int256,int256,address)","1cc6ba74":"testWIP()","1cc6ea05":"populateStringMember()","1cc6f13d":"setComplianceService(address,address)","1cc70934":"getPolicyLockedPercentage(uint8)","1cc72c04":"CheckPoolOwnership(string,address)","1cc78eb6":"RANGEEND_1()","1cc8092f":"FOURTH_TIER_DISCOUNT()","1cca13d3":"is_watched(address)","1ccb2601":"FoodWithdrawEvent(address,address,bool,uint256,uint256,uint256)","1ccc7013":"setPriceAt(uint16,uint16,uint8,uint256)","1ccd2706":"CatholicCoin()","1cce70d4":"getHowManyWinners()","1ccf6955":"getBets(uint256)","1ccf8abe":"phiWon()","1cd01e3a":"collectPercent()","1cd07895":"DmlToken(address,uint256)","1cd0b87f":"B33RToken()","1cd23711":"nouveauContrat(address,address[],uint256[])","1cd30149":"paybackRequired()","1cd3072b":"transferSub(address,address,uint256)","1cd30a3a":"randomGen(bytes32,uint256)","1cd3b754":"preICOcoinsLeft(uint256)","1cd45773":"getruns(address)","1cd58891":"requestRedemption(uint256,uint256,bool)","1cd60a85":"setFiscal(bytes32,bytes32,bytes32,uint256,uint256,uint256)","1cd732c1":"currentEthPrice()","1cd73845":"updatePremiumCalculator(address)","1cd76498":"crossForkFund()","1cd8b96c":"poolDLock()","1cd8d8a9":"checkTeam(address)","1cd95d2a":"_freeze(address,uint256,uint8)","1cda37f2":"eraseRecords(bytes32)","1cdadfae":"balanceNotEqual(address,uint256,string)","1cdb0989":"getMaxEmpruntable(address)","1cdb8571":"left2(uint256)","1cdc3f8a":"STQPreICO(address,address)","1cdc51e7":"requestRates()","1cdce200":"walletOne()","1cde0ff0":"withdrawScamEarnings()","1cde3cde":"BDIToken()","1cdeae52":"setSynopsis(string)","1cdef3ed":"agree(uint256,address)","1ce00c50":"registerUnlock()","1ce10a9d":"get_Sponsored_Amount_in_Job_By_Address(uint256,address)","1ce1e1b8":"White(address,uint256)","1ce26ecd":"addOwner()","1ce26faa":"fundingEndsAt()","1ce28e72":"getLimit(address)","1ce30927":"getOption(uint256,uint256)","1ce477d8":"createTransferEvent(bool,address,address,uint256)","1ce5e9a6":"getOption(uint256)","1ce62383":"expected()","1ce624d6":"Crypted_RPS()","1ce6717d":"CouponDeposit(address[2],uint256[8],uint256)","1ce6a810":"KBKJToken()","1ce7d9da":"ico_finish()","1ce7eff3":"bytecodeAt(address)","1ce817ab":"NoWinner(address,uint256,int256,string)","1ceb1b87":"setCanAcceptTokens(address,address)","1ceba89b":"getH3Bidder()","1cecb935":"isSignedNoEnc(uint16)","1ced2c75":"SpritzCoin()","1cedf8a3":"getDarknodeOwner(address)","1ceea715":"GetMyInvestFee()","1cef2b4e":"TokenCreated(address,uint256)","1cef3c13":"StandardTokenFreezer(address)","1cef92b1":"getRewardStatus(address)","1cf081f6":"changeProductionFee(uint256)","1cf196df":"changeCommissionFee(uint256)","1cf19ad7":"Mundo()","1cf1bb72":"releasedAmount(address)","1cf25dc9":"incentivisingAddress()","1cf28a65":"expand()","1cf28ae3":"_bonusTime1()","1cf2de25":"MinterUpdated(address,address)","1cf3d16d":"LogRegularityConfirmation(address,bool,bytes32)","1cf41a81":"deployContract(uint256)","1cf43b63":"extractExportFeeChargeLength()","1cf52f2b":"isActiveRegistrant(address)","1cf57f67":"future_round_coins()","1cf67724":"getImplChangeReq(bytes32)","1cf73c13":"setStake(uint256,uint256)","1cf74ece":"left56(uint256)","1cf91bf2":"setOwnerAtomsCount(address,uint256)","1cf9c88a":"addAction(string)","1cfa42d0":"isReleaseRecordExist(uint256)","1cfac68e":"BitSelectModerado()","1cfb4e1b":"InsureShares()","1cfb7c9a":"ifAllowed(string,address)","1cfbc7d0":"finalRewardPeriodEndBlock()","1cfc832e":"invalidateProposal(bytes32,bytes32)","1cfcc5bb":"checkGameSideAmount(uint256,uint256)","1cfce386":"calculateTarget()","1cfd11d5":"getDungeonDetails(uint256)","1cfdf90e":"updateWinnersList()","1cfe04a7":"canPay()","1cfe699e":"getFreezingSummaryOf(address)","1cfef64c":"SEELE_TOTAL_SUPPLY()","1cff272e":"show_Accrued_Interest(address)","1cff3e09":"testCreateBallotContract()","1cff79cd":"execute(address,bytes)","1cff87db":"burnMyQUATransferAndSendQUAToSomeone(uint256,address)","1d000b61":"BNT_TOKEN()","1d007f5f":"changeDAO(address)","1d010815":"createSaleAuctionERC20(uint256,address,address,uint256,uint256,uint256)","1d012c8e":"gameIsOver()","1d017b28":"setUnownedNumOfExoTokensBonus(uint256,uint32)","1d0192e1":"editEntity(address,bool,bytes32)","1d01ee9d":"BPX_per_ETH()","1d0205b8":"months(uint256)","1d029641":"rntTokenVault()","1d02fb06":"nCryptToken()","1d03842f":"onePlus(uint256)","1d048136":"setBaseStamina(uint256)","1d04c92b":"appendKeyValue(string,int256)","1d05bcb3":"dividendsRound()","1d05c57e":"_createCobeFriendWithTime(uint256,uint256,uint256,uint256,address,uint256,uint256)","1d05d1d8":"refundContributorEnd()","1d065dde":"_transferWithReward(address,address,uint256)","1d075862":"getUpgradeProposals()","1d079c20":"IETToken(address)","1d07b797":"destroyTheUniverse()","1d0806ae":"initialPrice()","1d08837b":"setBaseRate(uint256)","1d09ba2c":"right15(uint256)","1d0a3cb8":"suspendedPayments()","1d0ba36e":"transferToPartner(address)","1d0cc1e7":"fullfillTeamAddress()","1d0ced55":"IonicCoin()","1d0d35f5":"isContributor(address)","1d0d5992":"transferBetweenUsers()","1d0e8a4d":"isShop(address)","1d0f2c99":"setTarget(uint256,uint256)","1d103139":"commissionCheck()","1d107603":"totalInitialBalance()","1d111d13":"withdrawBNB()","1d121dfe":"communityGrantsAmount()","1d123801":"airDropNum()","1d124fe4":"setUtils2(address)","1d128687":"myDividendsNo()","1d12b52f":"AKBToken()","1d130935":"isSuspended()","1d143848":"issuer()","1d14e5ff":"crowdSaleDonate()","1d153624":"CIBNLiveInteractiveToken()","1d15f317":"SUFFICIENT_STATUS()","1d16d1bb":"setComponent(string,address)","1d16d9a0":"sendETH()","1d184872":"lastrandom()","1d18ee83":"getCurrentHardcap()","1d1997a0":"lengthNotEqual(int256[],uint256,string)","1d19a56d":"claimFeeRebate(uint256,bytes32,bytes32,bytes32,uint8)","1d19a78e":"deactivateHedge(address,uint256)","1d19ffc3":"uniqueIds(uint256)","1d1a696d":"contains(bytes32)","1d1a7c32":"concat(bytes,bytes1,bytes,bytes1)","1d1ac66a":"signOut(address)","1d1ada90":"manuallyAssignTokens(address,uint256)","1d1ca65b":"BROKER_RESERVE_ADDRESS()","1d1cc622":"CurrentDistribPublicSupply_()","1d1ce884":"VoteCommitted(address,uint256,uint256)","1d1eda5e":"setBonusesForTimes(uint32[],uint32[])","1d1eff42":"AccessRevoke(address)","1d1fe108":"burnInvestorTokens(address,uint256)","1d209605":"Controllable()","1d20a9c9":"setCardActive(bool)","1d211d74":"tokensToSale()","1d21f252":"getInvertedPrice(address)","1d231b2c":"_blackListed(address)","1d24190c":"GetGiftInfo(string)","1d24310d":"setTransferMode(bool)","1d2531f3":"is_alive()","1d25a5eb":"CGToken()","1d25bba2":"addSomeCWCsTo(address,uint256)","1d25c1a5":"get_remaining_quantity()","1d2627bb":"setEidooWallet(address)","1d263b53":"callSecondTarget()","1d263f67":"flip(bool)","1d27769f":"participate(string)","1d289e57":"regulationsFulfilled()","1d291990":"getNumberOfBid()","1d293500":"gamePayOutWinner(address)","1d296e8d":"geneLabAddress()","1d29de63":"clearAllCandidates()","1d2a6dcf":"getNumArchers()","1d2aa5b3":"skip()","1d2aabcb":"MicroBitcoinToken()","1d2af28b":"pay055loyal(address)","1d2b63bf":"GetNumber(address,uint256)","1d2b7155":"activateImportFeeChargeRecord(address)","1d2b8d96":"MintICO(address,address,uint256)","1d2bca17":"MyToken(uint256,string,uint8,string)","1d2bf543":"fetchCoinAge(address,address)","1d2c1b59":"query(uint256,bytes32,string,string,uint256,uint256)","1d2d4c34":"test_assert()","1d2d8400":"delegateToNewContract(address)","1d2d86dc":"setChecksum(bytes32)","1d2d9b06":"raiseEvent(string)","1d2dbb22":"CancelMyInvest()","1d2e18cd":"stageOneStart()","1d2e2cc4":"ENS()","1d2e5a3a":"setSale(bool)","1d2eda60":"DIUToken()","1d2ee278":"Angel()","1d2fd267":"getCarCurrentPriceAuction(uint32)","1d2fed16":"updateRates(bytes4[],uint256[],uint256)","1d300421":"NuruToken(uint256,uint256,string,string,uint8)","1d30d3db":"Transfer(address,address,string,uint256)","1d3231d4":"totalCommitted()","1d32a70c":"upgradeMining(uint256,uint256)","1d32ab99":"originTransfer(address,uint256)","1d32f106":"openZoneTeller(bytes2)","1d32f29a":"SetDescript(string)","1d33267a":"revokeGrant(uint256)","1d333265":"_removeCryptantFragments(address,uint256)","1d3390a1":"carefulSendWithFixedGas(address,uint256,uint256)","1d34be47":"updateRefund(uint256,uint256,uint256,bytes32)","1d34cf60":"getNumSuppliers()","1d351f53":"decreaseAllowanceToken(address,uint256)","1d356eef":"getDepositEtherForAddressValue()","1d3639ec":"preDGZTokensSold()","1d365669":"transferDirectoryToken(uint256,address,uint256)","1d36e06c":"tokenIndexToOwner(uint256)","1d36ee16":"RBC(uint256,string,string)","1d376a44":"PriceOracle(uint256)","1d3795e8":"startFreeGet()","1d37c8a6":"setPurchaseRate(uint256)","1d381240":"addKey(bytes32,uint256,uint256)","1d38869b":"ShopiBlock()","1d38bebd":"isInitialAuctionEnded()","1d38e433":"gasForIAD()","1d38fcda":"freeze(address[])","1d3a5dbe":"requiredPrefix()","1d3b9edf":"times(uint256,uint256)","1d3ce58d":"currentMintable()","1d3d4c0b":"make_contact(bytes32[])","1d3d93d4":"activateCurrency(address)","1d3e2d1b":"changeFriend(address,address)","1d3e43c8":"VCcoin()","1d3e904e":"BasicSPIKE()","1d3f6f1b":"setFounderMultiSigAddress(address)","1d3f864b":"campaignCaptain(uint256)","1d3f90c6":"bonusUnlockTime()","1d40bbcf":"_addMember(address)","1d411612":"EthernetCashAddress()","1d4233b9":"flushEth()","1d42cf72":"nochange()","1d433d52":"_getbonusRate()","1d43776e":"rngAddress()","1d43b653":"submitTransaction(address,uint256)","1d43cc98":"increaseTotalSupply(uint256)","1d4494f1":"changeApiUrl(string)","1d45e9e1":"notEqual(uint256[],uint256[],string)","1d461b83":"airdropMDL(address[],uint256)","1d47ae34":"YShare()","1d47f8c1":"getApprovals(address,uint256)","1d480d8b":"addRefBonusWithRefs(address,uint256)","1d49e081":"EXECUTE_EXTRA_GAS()","1d4a48b7":"Start7()","1d4a9209":"initializeTokenSale(uint256,uint256,uint256,uint256,address)","1d4ac2b6":"yearteam()","1d4b0796":"updateTxStats()","1d4b11e4":"ownerOfLandMany(int256[],int256[])","1d4be3df":"getFoundAddress()","1d4c8e5d":"removeAddressesFromBonuslist(address[])","1d4cecaa":"setInfo(uint256,bytes32,string)","1d4d691d":"fill(address,uint256,address,address,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","1d4d8656":"donateAuthor()","1d4d8808":"_getFeeHistory(uint32)","1d4eaf06":"StoreFile(uint256,bytes32,string,string,string,string,string,uint256,bytes)","1d4f2c6d":"setMythicalGravatar()","1d4f3e8b":"getCLottery()","1d4f9bbf":"NewTTL(bytes32,uint64)","1d50169c":"sendToken(address,uint256,uint256,uint256)","1d511879":"buyTokensPresale()","1d523047":"COMMUNITY_TOKENS()","1d523107":"SOFT_CAP_IN_TOKEN()","1d52573f":"set_address_B(address,address)","1d532a97":"increaseAssetsCertified(uint256)","1d5407aa":"helpCoinAddress()","1d5459f7":"updateFundAddress(address)","1d545d09":"crowdsaleEndTime()","1d54ab74":"_getRateIndex(uint256)","1d570166":"previligedAddApproval(address,address,uint256)","1d57bcf7":"ProofLibInterface()","1d590771":"TeuToken()","1d598d10":"BitcoinBlue()","1d59cde3":"retrieveEarnings(address)","1d5a9f3f":"object_types(uint256)","1d5aca61":"ZITRON()","1d5b26b1":"presaleMarket()","1d5b9efe":"mintAfterSale()","1d5c7ef5":"getPaymentToAddRemoveCountry(string,bool)","1d5de3fb":"ECOToken()","1d5e3350":"transferReservedTokens(uint256)","1d5e3f6d":"sumOfN(uint256,uint256,uint256,uint256)","1d5ea379":"newUserFrom(address,string,string,string)","1d5f624a":"unPaidBurnTokens(uint256)","1d5fe710":"finalizeCurrentStage()","1d60208a":"TrezorMultiSig2of3(address,address,address)","1d60993b":"stakeScale(uint256)","1d62a312":"thirdPreSaleDate()","1d62a40f":"DungeonChallenged(uint256,address,uint256,uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","1d62c5bf":"PublicSold()","1d6456c4":"_transfer(address,address,uint256,uint256)","1d645b12":"getEventInfo(uint256)","1d6477e1":"reclaimableLand()","1d64976b":"HBCM()","1d65551d":"updateRenExSettlementContract(address)","1d659153":"CanObtainChip(uint32)","1d65d60e":"PRE_ICO_MAX_TOKENS()","1d66105b":"buyDrangon()","1d66ff8e":"getInvestorDividends(address)","1d68463e":"CreateSWP(address,uint256)","1d68b449":"crowdClosed()","1d6916ab":"buyTicket(uint256,uint256,string)","1d693910":"Piezochain()","1d69ccdc":"SuccessfulVote(address,bytes32,bytes32)","1d6a8bda":"enableTokenTrade(address)","1d6b5d2c":"setDnaMixerAddress(address)","1d6b867c":"getGamePlayer(uint256)","1d6c0dfa":"setActiveHero(uint256)","1d6c263c":"Election()","1d6ca15d":"Presale(uint256,address,address,address,uint256,uint256,uint256,uint256)","1d6d8d60":"modifyMilestoneTo(address,uint8,uint8)","1d6f5e03":"PubkeyChanged(bytes32,bytes32,bytes32)","1d6f757d":"withdraw(uint256,uint8,bytes32,bytes32,uint256)","1d6fe151":"ROSCtoken(uint256,string,string)","1d704684":"setBinanceCoinPrice(uint256)","1d706777":"getCertifier(address)","1d7099d3":"payFromAllowance(address,address,address,uint256)","1d709ab4":"set_transfer_gas(uint256)","1d718288":"referralTokensAvailable()","1d71929d":"MIAMIcoin()","1d71a1cd":"newIncome(string)","1d724a7a":"getFounderStatus(address)","1d731345":"calculateRoom(uint256,uint256,uint256)","1d7315cc":"storedAmount()","1d732304":"generateRand(uint256)","1d73268a":"PHDToken(uint256,string,string)","1d733337":"participantRegistered(address)","1d73fb93":"autoTransfer(address,uint256)","1d747131":"getTotalApprovers()","1d74c1a8":"_addToFund(uint256,bool)","1d74f3a5":"DIRT()","1d75493a":"setWinnerPlaceDistribution(uint256,uint256)","1d755c8d":"recieveVote(address,bytes32)","1d759214":"minMinBuyETH()","1d75a4b9":"viewAuthorized()","1d7630f0":"signedTransferFromCheck(address,address,address,uint256,uint256,uint256,bytes32,address)","1d7747d1":"addAuthByCode(string,string)","1d777856":"tokensForBurn()","1d7786e3":"numToksSwitchedOver()","1d77d696":"setMockUint256(bytes4,uint256)","1d780960":"pauseGame(uint256,bool)","1d786cd0":"widthdrawEtherDelta(uint256)","1d7876e7":"transferBack()","1d78ca63":"AuctionClosed(address,uint256)","1d790c99":"parseData(bytes,uint256)","1d7915ad":"setSeed(uint256,uint256)","1d793e9a":"batchChangeChannel(address[],uint256[],uint256,uint256)","1d7add35":"appendPricePoints(uint64[])","1d7b46b2":"tokensPurchasedTotal()","1d7b5baf":"setUint(int256,bytes32,string,uint256)","1d7b6d58":"forkAndRedeem()","1d7bb2db":"CasinoCoin()","1d7bc449":"getCeleb(uint256)","1d7c5cd1":"userServicesLength(address)","1d7c8894":"issueGoldTokens(address,uint256)","1d7ca2be":"subAddressToWhiteList(address[])","1d7d1f17":"BFX()","1d7d8d2e":"EthereumPoint()","1d7e1f68":"getContentRank(address,uint256)","1d7f2e0c":"SecondNode(address,string,string)","1d7f8039":"mineMany(bytes32[])","1d7fb62f":"initVote(uint256)","1d80009a":"rootHash()","1d80e62a":"changeTransfersPaused(uint256)","1d814480":"provideInfoCourseBaseOnIdStudent(uint256)","1d81564d":"minutesInPeriod()","1d819ef0":"testEqualityAddr()","1d82e9c7":"EXTRA_GAS()","1d833aae":"drop(address,address[],uint256)","1d834409":"totalOrders()","1d834a1b":"insert(uint256,uint256)","1d836ae9":"EQUIEX()","1d83e3a9":"withdraw_(address)","1d846f5c":"currentCancellationResults()","1d849220":"getTokenSaleTime()","1d84f303":"ETPC()","1d8557d7":"updateState()","1d862a81":"getPop(uint256)","1d87614a":"OPTION_POOL_PERIOD()","1d87a65c":"createBattleboard(uint8)","1d88c05b":"successorAddress()","1d898f52":"IM()","1d89dbc9":"updateExchangeRate(uint8,uint256,uint256)","1d8a8db9":"ethRaisedAddress()","1d8aa5ec":"currentSettlementPhase()","1d8acf1b":"getBoolValues(bytes32)","1d8adb7a":"setMaxUserPayment(uint256)","1d8ae626":"Security(string,string)","1d8b13a6":"setPersonal(address)","1d8b4dd1":"createContractExoplanet(string,uint256,uint32,string,uint32,uint8,string)","1d8b70da":"order_received(string)","1d8bab91":"RDN()","1d8c61c0":"setTMEXAddress(address)","1d8c7c20":"internalSellTokenFromAdmin(address,uint256,bool,uint256)","1d8ceb44":"extractClosingSignature(address,uint32,uint192,bytes)","1d902fe9":"currentBonusRate()","1d9046ce":"transferShip(uint32,address,bool)","1d90824b":"getMinPrivateSaleCompanyBuy()","1d90c509":"cardPresale(uint16)","1d91bd9f":"transferPaymentAddress(address)","1d927f21":"userDraw(uint256)","1d93d8d9":"WaboToken()","1d9400c2":"ManagerProxyTargetMockV3(address)","1d9680a7":"oldWriteMessage(string)","1d96d4c9":"VIRES()","1d976e05":"transferMultiple(address,uint256[])","1d978f9e":"ContributionRegistered(bytes32,address,uint256)","1d981758":"__signatureIsValid__(address,bytes32,uint8,bytes32,bytes32)","1d98532f":"_computeTournamentCut(uint256)","1d98f3c5":"safeTransferChild(uint256,address,address,uint256)","1d991ffe":"IsBoilerValid(address,uint256)","1d9976e9":"LedgerRandomProofVerifier()","1d9b0783":"withdraw(uint128,address)","1d9b1d6f":"schedule(uint256,uint256)","1d9b1d85":"ReFund()","1d9bd2b9":"totalSoldOnICO()","1d9becf5":"CatAdopted(bytes5,uint256,address,address)","1d9caa69":"sendMessage(address,string,string,uint256)","1d9cfd6d":"setSale()","1d9d1bdc":"buyTradeConfir()","1d9e6c34":"compose(string,address,uint256[])","1d9f3cb5":"changeSaddleShopPrice(uint256,uint256)","1d9f68ad":"updateMaxBonusTickets(uint256)","1da05199":"hasAvailableCard()","1da09dd5":"getUserActionOnStory(bytes12,address)","1da0fb1b":"updateSettings(uint256,uint256,uint256,uint256,uint256,bool)","1da16e8b":"FirstSaudiToken()","1da26a8b":"setToken(address,address)","1da2d92b":"IDRT()","1da3f151":"presaleVolumeBonus(uint256)","1da4eb7a":"_secondUnlockAmmount()","1da4ed85":"setRewardPool(uint256)","1da55b9f":"YeedToken(uint256,address)","1da5f94d":"acceptableAddress()","1da6822c":"testThrowsTransferEnableNotTransferable()","1da74e77":"wtToken()","1da790a1":"showTopWinners()","1da83550":"setWinner(address,uint256,uint256,uint256)","1da83eab":"canDefrostReserveAndTeam()","1da88cbe":"getNew(address,bytes32)","1da93873":"baseTokenPrice()","1da97544":"ETHtoZWeirate()","1da97f36":"HunterCoin()","1da98538":"totalMEATonsClaimed()","1da9ea0c":"hardCapInTokens()","1daae314":"secondStagePriceOfTokenInWei()","1dab2271":"setSuggestedAdPrice(uint256,uint256)","1dacad8a":"CentralizedOracle(address,bytes)","1dacd8fd":"buyDisciple(uint256,uint256,uint256)","1dad202f":"ctz64(uint64)","1dad57fa":"notifyCollateralNotReturned(uint256)","1dad63e4":"ERC20Standard(uint256,string,bool)","1daee82d":"secondLockAmount()","1daf779f":"SDpay(uint256,string,uint8,string)","1db021c0":"mintedCoins()","1db046ad":"OneToken()","1db05ab8":"FXNOW()","1db087db":"_setAllocation(address,uint256)","1db0ad5a":"firstUnlockTime()","1db0ffe9":"ECHARGE()","1db19959":"RATE_SALESTAGELAST()","1db1c805":"setDefaultReputationForManufacturer(bytes32,bytes32)","1db256e4":"WCCCOIN()","1db29a20":"getPlotInfo(uint256)","1db2ea77":"_91_MR()","1db38da2":"ClaimExecuted(uint256,uint256,address)","1db4012d":"newProject(string,string,uint8,address[],address)","1db4b07f":"rntToken()","1db4d7a2":"returnBalance(address[2],uint256[8],uint8,bytes32[2])","1db580fa":"foundersAllocation()","1db5ca3b":"becomeAgent(uint256,uint256)","1db5f974":"highBonus()","1db625c3":"newInvestCommission(uint256)","1db71ffb":"doLoops(uint256)","1db834f0":"NextDouble(address,uint256)","1db87be8":"receivingAddress()","1db890a6":"getCassetteSize_()","1db894fc":"signToApproveTokenControlInfo()","1db93968":"transferProperty(uint16,address)","1db9ec2c":"ENDDATE()","1dba92ab":"setKeys(address,uint256)","1dbb0bff":"buyBlock(uint256,uint256,bytes32,bytes32,bytes32,bytes32)","1dbb9867":"buyEggFee()","1dbbda4d":"bytesToUint(bytes20)","1dbc04ae":"setVestingToken(address)","1dbcc5ad":"RiesGraham()","1dbd21c3":"Daereum()","1dbdd617":"LILITHCOIN()","1dbdd792":"MIDGRADE_TYPE_COUNT()","1dbde6c7":"maxTokenSupplyICOEND()","1dbe342d":"TRND()","1dbe6508":"bobClaimsDeposit(bytes32,uint256,uint256,address,address,bytes)","1dbf3bc7":"spend(uint256)","1dbf79a3":"TicketGlobalChain(uint256,string,string)","1dc05f17":"subtract(uint256)","1dc0819e":"_isBreedingPermitted(uint40,uint40)","1dc1166f":"horseSold(uint256)","1dc17cce":"VALUE_DISTRIBUTION_KEY_OWNERS()","1dc18c45":"editNode(uint256,address,bool,address,uint8,bool)","1dc18f7a":"hashAmount(uint256,uint256)","1dc1c5e3":"payMoney()","1dc30bdb":"payJackpot5()","1dc3ac22":"setOwnerNickName(address,string)","1dc436cd":"getIDChildRelationshipCountOperationParentProductPositionReferenceBinding(string,address,uint256,uint256)","1dc45248":"getMoveCount()","1dc45c6d":"spenderDecreaseApproval(address,uint256)","1dc55c2d":"GetDividends(address,uint256)","1dc615bc":"checkIfAllARTDistributed()","1dc76e78":"buyPlayerDataRecord(uint256,uint256,uint256)","1dc7f1b4":"getaddressname()","1dc82285":"oldBalance()","1dc8a3bb":"B123Token()","1dc9186a":"updateWeiAmountShare()","1dc9a3b9":"transferDomainOwnership(bytes32,address)","1dc9bb48":"hasDividends()","1dcb0d36":"goBackToPreSale()","1dcb304b":"fipsGenerate()","1dcb66ff":"coordinatesOf(uint256)","1dcd0305":"toStr(bytes32)","1dcd5312":"editMessage(string)","1dcd9b55":"substring(string,uint256,uint256)","1dcdf215":"getCoursesCount()","1dce0b5c":"getNoteKeysCount()","1dce77b8":"Linkmanagement()","1dce79cf":"blockchainExchange(uint256,int256,bytes32)","1dcea427":"erc20token()","1dd0c71b":"myPendingPayment()","1dd1349d":"getNameHash(bytes32)","1dd14317":"setProtocolVersion(address,bytes32)","1dd14a96":"totalSupplyPaillier()","1dd15fca":"tokenInWhiteList(address)","1dd16db6":"customBonus()","1dd17e7d":"setPreSaleParameters(uint256,uint256,uint256,uint256,uint256)","1dd300ce":"lastWithdrawal()","1dd46c1e":"getTxCount()","1dd4914b":"withdrawEtherOrThrow(uint256)","1dd49208":"getFeed(uint256,uint256,uint256)","1dd49cae":"remWhitelist(address[])","1dd5301a":"PRICE_PREBUY()","1dd572a0":"fortune_sell(uint256,uint256,uint256)","1dd637d8":"emergencyProtectedMode()","1dd6f85e":"CreateLOK(address,uint256)","1dd72454":"TransferManual(address,address,uint256,string)","1dd7335c":"allocateDividendsToWinners(uint256,address[],uint256[])","1dd7cf6d":"getHumanInfo(uint256)","1dd80586":"getPlayerSpaceshipBattleStakePaidById(uint256)","1dd85687":"adminSetEnviroment(uint256)","1dd8f053":"minPriceInWeiForIco()","1dd95a98":"AIRDROPS_COUNT()","1dd9a3cf":"_sendEthereum(uint256)","1dda5c7d":"testFailSubBalanceBelowZero()","1ddabf7a":"friends(address)","1ddb9105":"creditVault(uint256,address,uint256)","1ddc0ef0":"audit()","1ddd303d":"setV_R3(uint256)","1ddd39cc":"addcoinslimit()","1dddbf07":"confirmExchange(address,uint256)","1ddde716":"advisorsAccount()","1ddf147f":"assignedDoublrContract()","1ddf9729":"IncomeTaxCalc()","1ddfd7db":"supportsTradingPair(address,address,bytes32)","1de012cd":"TRUST()","1de032a5":"setIsStudio(address,address,bool)","1de0e877":"proposedControllerPendingUntil()","1de14175":"setDelegadoDeEscuelaVerify(bytes32)","1de1441f":"remainingEPXSupply()","1de1ee7b":"addPublicKey(bytes32,address)","1de21b76":"P1()","1de22867":"BeatTokenPurchased(address,address,uint256,uint256)","1de250bf":"bless(string,uint256)","1de26e16":"deposit(bytes32,uint256)","1de271a4":"cap_tmx()","1de28857":"getShareBalance()","1de38038":"makercoin(uint256)","1de3d4b9":"ReleaselockAddress(address)","1de4334a":"get_time_locked_contract(uint256)","1de46a78":"admin3()","1de473ea":"setC4FContractStatus(address,uint8)","1de54fcd":"unlockedNowBalanceOf(address)","1de7f3e3":"setBankrollpercentage(uint256)","1de95d74":"AREFWallet()","1de98d93":"deleteUserByEmail(bytes32)","1dea0c57":"getRealBet(uint256)","1dea157f":"getPaintingArtist(uint256)","1dea3f0c":"recordOffchainPurchase(address,uint256,uint256,string)","1dead827":"_percentSoldInICO()","1deb0a8f":"changeState(bool)","1deb112b":"initialSupplyPublicPreICO()","1deb9b9e":"EventBid(address,uint32)","1debbe2f":"addExp(uint256,uint32)","1dec8585":"getCurrentStageByTime()","1ded2d87":"Transaction(address[2],bytes,uint256,bytes32[2],uint256[3],bytes32[3],bytes,bytes)","1ded319d":"numberOfClaimed(address)","1ded587c":"Hotlist()","1dedc6f7":"consume()","1def4c9d":"TransferToBTCoE(uint256)","1def5033":"taskArray()","1df0187b":"BONUS_AMOUNTS_VALUES(uint256)","1df025d6":"updateGoalCheck()","1df0e359":"createForecasting(uint256,uint256,uint256)","1df13f28":"ICOBonusPercent2week()","1df19259":"Khabayan()","1df1ec82":"getProviderOwner(uint256)","1df224c1":"privateToken()","1df2bcbc":"setPresaleCont(address)","1df36e63":"delInvestor(address)","1df3e8a9":"GuardaProva(string,string,string,string)","1df411a6":"setOfferTime(uint256)","1df4241f":"StatEvent(string)","1df473bc":"newContract(bytes)","1df47aad":"ReplayProtection()","1df4ccfc":"totalFee()","1df4f144":"multiply(int256)","1df5a8f4":"GlobalBTC()","1df5e755":"Etherandom()","1df68102":"createSellOrder(uint256,uint256)","1df6d86e":"_buyLeader(uint256,uint256)","1df73f51":"getFreeSperm()","1df87cad":"raiseBuyOrderCancelled(address,uint256,uint256,uint256,uint256,uint256,int160)","1df8eaa2":"showAuthorizerTwoAmount()","1df93558":"fundingStartTime()","1df95786":"envelopes(uint256)","1dfa0cf6":"ConfirmDispose()","1dfa3ca8":"thirdPartyInvestments(address,uint256)","1dfbf227":"makeInvestment(address,string,uint256,uint256)","1dfc91d4":"TokenPresalePurchase(address,uint256,uint256)","1dfd04b9":"buyEmptyPixel(uint256)","1dfd1ddd":"ListNotValSince(uint256)","1dfde4a5":"test_insert_findWithHintPrevAtPosition()","1dffa3dc":"cancelJob(uint256)","1dffd012":"getUserManager()","1dffdbe6":"trade(string,uint256,uint256)","1e0018d6":"investor()","1e010439":"getBalance(uint256)","1e0197e2":"tournament()","1e01a0e6":"doit(address)","1e01a172":"issueDescription(uint256)","1e021b2b":"getproductstatus()","1e02bf62":"checkOutstandingQueries()","1e02f805":"newInvestment(address,uint256)","1e031a00":"QuickFlip()","1e0419d4":"finalWinner()","1e04e856":"depositEth(address,address)","1e04eee9":"mintChipUnsafely(uint256,bytes32)","1e0582e9":"_daysFromDate(uint256,uint256,uint256)","1e05e0c8":"bonusesForTimesCount()","1e0610f6":"getRealty(address,uint256)","1e063d98":"MRDSTSCoinToken()","1e06c41f":"saleStartUnixTime()","1e06e25e":"Zoo721(address)","1e075aba":"batchUnlockVestedTokens(address[])","1e08045d":"getOwnedTanks(address)","1e084558":"licenseInfo(uint256)","1e095eb3":"GHPToken()","1e0976f3":"receiveVerification(uint256,uint256,uint256,bool)","1e09e67b":"Rasthen()","1e0a0f60":"info_CanBeClaimed(uint256)","1e0a24b1":"revertIfReturnLessThanMin()","1e0b760c":"Cancel(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","1e0b8c87":"hasSkills(address,uint256,uint256,uint256)","1e0c60e2":"SGem()","1e0c7ed4":"setConfigBool(bytes32,bool)","1e0e17a2":"claimMistake(bytes32)","1e0e3925":"numElements()","1e0efae1":"claim_devidend()","1e0f6ed8":"TokenSaleFinished(uint256,uint256,uint256,uint256)","1e0f9795":"getNewFib(uint256)","1e11764e":"GameFinished(uint256,uint256,string,uint256,address)","1e120efb":"showEducationDetails(uint256)","1e1401f8":"getReturn(address,address,uint256)","1e141bb0":"releaseTime4()","1e14d823":"addMarketplaceContract(address)","1e16521b":"fulfillBurnRequest(uint256,string)","1e16980c":"setUnburnableWallet(address)","1e171d7c":"hasFunded()","1e172e90":"TransferHappened(uint256,bytes32,address,address)","1e1781af":"unfreezeAccount(address,bool)","1e179ae0":"getToken(bytes32,uint256)","1e17f292":"getAPRTx(uint256)","1e185b2a":"BTEcoin()","1e186e4c":"TestERC20()","1e18c404":"huroc()","1e191c0f":"goalSale()","1e1a48cf":"transferMethodId()","1e1a4eef":"setShareTokenAddress(address)","1e1a90a6":"onPayout(address,uint256)","1e1ad51c":"getFunding_Old(uint256)","1e1b13c0":"coinAge()","1e1b2e0f":"getLotteryPrizesLength(uint256)","1e1c72f4":"requestFreezeAccount(address,string)","1e1c86b7":"CCProject()","1e1d237e":"getSortedArray(uint256[])","1e1d696a":"changeLibAddress(address)","1e1ddacc":"saleController()","1e1e0a5e":"doHash(string,uint32,string,string)","1e1e3e0f":"vaultBalance(string)","1e20363a":"setTokenMetadataBaseURI(string)","1e204acf":"HODLrSoldWin(address,uint256,uint256,uint256)","1e20b4b9":"allocateAllUnsoldTokens(address)","1e215f70":"gbtAddress()","1e217bf8":"releaseUnclaimedFunds()","1e223143":"getFirst()","1e22648a":"setSnapshotBalance(address,uint256)","1e2273a7":"convert256ToReal(uint256)","1e22ffa5":"ClickRUB(uint256,string,string)","1e23300b":"createDiamond(string,address,string,string,string,string,string)","1e2466c6":"ICOTerminated()","1e24e029":"createRequestAsPayer(address[],int256[],address,uint256[],uint256[],string)","1e25dc54":"transFee()","1e2629e1":"initiateMigration(address,address,address)","1e26fd33":"setBool(bool)","1e273649":"getCountPartipants()","1e275d5f":"mock_getUInt(address,address)","1e279a37":"get_balance(address)","1e27a965":"JullarCrowdsale()","1e27ae4d":"getRecordHolder(uint256)","1e28a3a5":"attachCrowdsale(address,address)","1e28ba20":"YeojinToken()","1e28f29b":"initialTiers()","1e2a9d4c":"topup(address,address,uint256)","1e2aebf9":"ETHERCREDIT()","1e2b6db2":"getBdpEntryPoint(address[16])","1e2bdfdf":"setAdvPrice(uint256)","1e2c23b3":"toEth(uint256)","1e2c74f6":"kill(bool)","1e2ca0f3":"updateLeftLottery(address)","1e2d5651":"totalContrib()","1e2da3e9":"PawsCoin()","1e2def3a":"saleStopTimestamp()","1e2e35a4":"sellPoohs()","1e2e3a6b":"getExchanges()","1e2e7a06":"registrationTime()","1e2ed152":"ECO_SYSTEM_BONUS()","1e2f48da":"assertOwnersAreConsistent()","1e2fc4f7":"test_mint()","1e2fee94":"CatDestinity()","1e2ff94f":"currentTimestamp()","1e2ffcef":"Show_All_Company()","1e30397f":"isValidName(string)","1e30b599":"Processables()","1e31264d":"_premiumPricePer30Days()","1e3339f0":"MTT()","1e335962":"token_multiplier()","1e33a6d5":"setGasUsage(bytes4[5],uint256[5])","1e34c585":"setConfig(uint256,uint256)","1e35e567":"fetchOrderByIdWithMerchant(string)","1e36d755":"sendTokenToOwner()","1e372dd3":"Advanced_Anemoi(uint256,string,string)","1e375ab9":"claimReferralBonus()","1e38046c":"address3()","1e38a011":"setRoutePrice(uint256)","1e391738":"minimumGoalInWei()","1e39499d":"scheduleCall(address,bytes,uint256)","1e3a5831":"Claimable(address)","1e3b92b4":"getGalaxy(uint256)","1e3b9de5":"getClaimant(address)","1e3ba116":"_supportsAllInterfaces(address,bytes4[])","1e3ba941":"StexTalk()","1e3c73bd":"BdpPriceStorage(bytes8)","1e3c9352":"grant(address[])","1e3d9c04":"removeLink(address,bytes)","1e3e6369":"GetMySnail()","1e3ea569":"SentTokens(address,uint256,uint256,uint256)","1e3f11ee":"getPlayerGeneralAttr(uint64,uint8)","1e3faf22":"airdropNum1()","1e40375f":"killTo(address,bytes32)","1e4092e5":"FOUNDER_AMOUNT()","1e4146b0":"generateCombinationKey(uint8[4])","1e41583b":"reclaimElement()","1e41be58":"deleteApplication(string,bool)","1e41f63e":"viewAll(string)","1e42698b":"setScrapAuctionDuration(uint256)","1e440e02":"TKCDStandardToken(uint256,string,uint8,string)","1e442919":"getAccessoryLockStatus(uint64)","1e4433c4":"getVar(string)","1e44b919":"KAPAYcoin(uint256,string,string)","1e44c112":"find_strike(uint64,uint32,uint32)","1e44e6af":"setPI_edit_10(string)","1e4532f1":"balances_bonus(address)","1e45de61":"GetWinningAddress()","1e4623e1":"segmentHash(string,uint256,bytes32)","1e464460":"AscendGod()","1e466eee":"triggerVolcanoEruption()","1e49d5ab":"getUserInfoAndConfig(address)","1e4a126e":"BeforeChipObtain(uint32)","1e4adcf7":"weiDonated(address)","1e4b5652":"setKNCRate(uint256)","1e4ba4d4":"swap(uint256,address,address,uint256,uint256,uint256,uint256)","1e4bb033":"HcoinToken()","1e4bd42c":"claimAllTokens()","1e4bdf27":"TransferActive()","1e4bffde":"_getBegin(int256)","1e4c6e7e":"gatito()","1e4c6f7c":"base_token_seed_amount()","1e4c7736":"updateManyLandData(int256[],int256[],string)","1e4ccdc4":"resultDraw()","1e4d17c5":"setFundraiserAddress(address)","1e4df315":"HRChainERC20()","1e4df938":"referralPool()","1e4f95c7":"pipeMoney()","1e504c9c":"setRegisterPrice(uint256)","1e5140dd":"closeTradeProfile(bytes,bytes32)","1e516c32":"OMIVIATEST()","1e519c4c":"getCurrentModifier()","1e51a907":"getServiceNames(bytes32,address[],address)","1e51cb10":"_MineId()","1e5253a4":"RegisterShareholder(address)","1e5296ef":"getMySellOrdersBlackMarketComplete()","1e52aa52":"startBetRed()","1e52ca35":"ROLE_SUPER()","1e52f7b5":"accoutToPayLevel(address)","1e5330ca":"checkBetResult(uint8,address,bytes32,bytes32)","1e5393cf":"setDividendAndPayOut(uint32,uint32)","1e53a3a0":"SetContracts(address,address)","1e53efe0":"getBonusAmount(uint256)","1e542fd4":"AddLock(address,uint256,uint256,uint256,uint256)","1e550ca2":"carTaxiTokenAddress()","1e552efc":"MarnieCoin()","1e5571bc":"getTankSell(uint32)","1e561d5e":"createSellingProposition(address,uint256,uint256,uint256)","1e566dae":"_moveToken(address,address,uint256,bytes,address,bool)","1e567582":"gxc()","1e57e3bb":"EtherReceived(address,uint256)","1e580615":"cashIn()","1e5890c4":"saveResult(uint256)","1e59b53f":"Medallion()","1e59c529":"register(string,address)","1e5a652b":"MDICOStage1(address,address,uint256,uint256,uint256,uint256)","1e5b433b":"testTransferControl()","1e5bd14a":"setRegulator(address,bool)","1e5c6176":"BitChordCrowdsale(address,address)","1e5d1a4c":"End(string)","1e5d2e41":"geneCore(uint256,uint256,uint256)","1e5d2e78":"_updatePools(uint8,uint256)","1e5e668f":"fetchDataMain()","1e5e8aa9":"token_rate()","1e5f34af":"sub(uint8,uint8)","1e5f3569":"createEIP20(uint256,string,uint8,string)","1e5f35f3":"Prover()","1e5f9149":"getWinner(bytes32)","1e5fc8e7":"bonusThirdWeek()","1e5ff41a":"tier5()","1e6000c2":"AffiliateReceived(address,address,bool)","1e6090f4":"isContractDeprecated()","1e60ab84":"PalaceResidence()","1e625935":"SelfPayPreSale(uint256,uint256,uint256,uint256,uint256,address)","1e626456":"tokenFallbackData()","1e6288fa":"soldTokenValue()","1e629a75":"StartNextStage()","1e62a511":"cHWCtoEth()","1e62a915":"set_participant_topl_address(address,uint256)","1e62be25":"Bytes32Passer()","1e639798":"reset(address,address,address,address,address,address)","1e63b3d3":"bancorConverterAddress()","1e658b74":"_userSignUp(string,address)","1e659135":"PVBToken()","1e65dc88":"EtherMemes()","1e6704bd":"maintenanceSetAccountsList(address[])","1e688c14":"fulfillBounty(uint256,string)","1e6b0e44":"finderFee()","1e6b4c6f":"setStakePeriod(uint256)","1e6bd462":"getAllGamesCount()","1e6c3d0e":"BLACKCOIS()","1e6c593c":"checkClaim(string,string)","1e6d4180":"stageBonus()","1e6d58ce":"AHA_Token()","1e6efc83":"setRestartGamePeriod(uint256,string)","1e6f01a7":"setPI_edit_23(string)","1e6f9c1e":"adjust_Transfer_data(bool)","1e701780":"MICRODAO(address,uint256,uint256,uint256,address)","1e70a239":"getAllGiftTemplateIds()","1e711ec0":"plan_active_time()","1e7230c5":"benReady()","1e7231b6":"disablePhenomenon(bytes32)","1e724447":"icoTill()","1e725589":"getAddressesFromUsernames(string[])","1e72a7fc":"calculateVariation(uint64,uint64,int64)","1e72d642":"BezantToken()","1e737709":"getSourceValue(uint256,uint256,uint256)","1e73b362":"withdrawContractEther(uint256)","1e7401d9":"ArconaToken(uint256,uint256,address,address,address,address,address,address,address)","1e745e61":"createContest(string,uint256)","1e74a2d3":"getMinimumEndowment()","1e74c414":"WashExchange()","1e7527b0":"setOwner(uint32,int256,address)","1e75c12d":"ETLTokenPresale(address)","1e7769de":"tryForcePublic(uint16)","1e77933e":"change(address)","1e77b2e0":"updateRate(string,uint256)","1e78cfe1":"minimumPayout()","1e79933f":"removeTagByModuleType(uint8,bytes32[])","1e7a505f":"register(address,bytes32)","1e7a5bf7":"testMintAuth()","1e7ae71f":"owner1Of(uint256)","1e7be210":"whitelists(address)","1e7bef65":"setIncubatorContract(address)","1e7c20ac":"getCompte_24()","1e7c27cb":"ADMIN_CONTRACT()","1e7c402b":"test_percOf2()","1e7cedb7":"TKTToken()","1e7d84cb":"getproduuct(uint256)","1e7de8cc":"setChibiGEN0Price(uint256)","1e7e2064":"addPeers(address[])","1e7e4b5e":"PREISSUED_AMOUNT()","1e7ea8d5":"getFreelancerCategories(address,address)","1e801c8c":"sealForChanges(uint256)","1e81086d":"setDirectMintAgent(address,int256)","1e815fcd":"isBuyOpen()","1e81ccb2":"pings()","1e820325":"finalizeRound()","1e822140":"transferToLockedBalance(address,uint256)","1e829230":"createGrant(bytes32)","1e82965e":"DCTR()","1e83409a":"claim(address)","1e83bab7":"singleInvokeWith2Args(address,string,address,uint256)","1e83cdab":"extract()","1e83ce17":"houseFeeThreshold()","1e83e697":"setTokenOptions(bool,bool,bool)","1e841271":"setTestFee(uint256)","1e84c725":"emergencyTransfer(address,address,uint256)","1e85107c":"bonusPercentages(uint256)","1e8551e3":"voteRewardPerUnit(uint256)","1e85e8f0":"TLN_TOKEN_SYMBOL()","1e860d43":"setNewInvestorsList(address)","1e86ccf5":"setOperatorCommission(uint256)","1e871309":"rewards_id(uint256)","1e872f55":"setPlayerLastUpdateTime(address)","1e8784c9":"SabrinaToken()","1e87fe1d":"setSmallCapWhitelistParticipant(address,uint256)","1e8812f3":"BonusCrowdsale(uint256)","1e891c0a":"setTimelock(uint256)","1e892c21":"returnForRedemption(uint256,uint256,uint256)","1e893437":"stageClose()","1e8997ec":"PUNCToken()","1e89c83b":"read_where_gadget(uint256)","1e89d545":"multiTransfer(address[],uint256[])","1e8a98cf":"UP_totalBets()","1e8b0d03":"EventBankrupt()","1e8bf006":"getNumbersFromString(string,string,uint16)","1e8bf1f9":"readInt256s(bytes32[])","1e8c72b4":"incrUserAvailBal(address,uint256,bool)","1e8d1510":"KeyFund(uint256,uint256)","1e8d15f8":"LasVegas()","1e8f11ab":"candleCost()","1e8fba36":"fortifyClaim(address,uint16,uint256)","1e909841":"getEmployerContracts(address,address)","1e912334":"maxDonors()","1e923f1b":"myAddr_test()","1e924bf8":"tokensReleasedPerPeriod()","1e92a65c":"teamAmounts()","1e935ab1":"requestPause()","1e93c209":"powerPool()","1e93d358":"multiStake(uint256,uint256,uint256,uint256,uint256)","1e9447f3":"hasDuplicate(string)","1e9493d8":"ETH_MAX_GOAL()","1e962e62":"F0002Token()","1e96bf0e":"separate(address,uint256)","1e9824ee":"setExchangeRates(uint8,uint8)","1e982b40":"saleOverInTime()","1e98d334":"initRace(uint8[4])","1e98d54a":"addGlobalConstraint(address,int256,bytes32,address)","1e9a04a7":"secondRoundICOStart()","1e9a6272":"onDelivery()","1e9a6950":"redeem(address,uint256)","1e9b1312":"accountAddress()","1e9b91db":"VictorieumNewICO2Token()","1e9be6a1":"usdEthPrice()","1e9bf0da":"disown()","1e9cefa3":"updateEmployeeWallet(uint256,address)","1e9d2d28":"NewGame(uint256,bytes32,bytes32,bytes32,address,uint256)","1e9d3bc9":"LZXToken()","1e9d48cf":"checkUser(address)","1e9d8232":"TheGame(address)","1e9da16a":"n_domains()","1e9dd927":"kycVerify(address,bool)","1e9e541c":"TEAM_TOKENS2()","1e9e6949":"ActiveChanged(address,bool)","1e9e928e":"GBPValue()","1e9ea66a":"balanceEther10000000(uint256)","1e9eb554":"deathData_v14()","1e9f3c24":"ETH888CrowdsaleS1(address)","1e9f6dcb":"ticketsFaceToFaceSold()","1e9fcc77":"activateAllowance(address,address)","1ea06b9e":"_allowManualTokensGeneration()","1ea0d0de":"endRace()","1ea103d0":"Registra()","1ea134b9":"PeculiumOld()","1ea1380c":"getScores()","1ea1e522":"claimF()","1ea333ea":"_generateDutchAuction(uint256,uint256)","1ea3cae9":"addressToAccountMap()","1ea48870":"isFunder(address)","1ea5a292":"endorse(uint256,uint256)","1ea5efc4":"partner1_voted_update_marriage_status()","1ea6af82":"reward9()","1ea7b0f9":"Bilibit()","1ea82655":"generatePartnerTokens(uint256)","1ea8b099":"endMark()","1ea906b5":"leftTokens()","1ea90acd":"fetchOrdersForPayer()","1ea92826":"currentTierIndex()","1eaa6c4b":"firstTokenExchangeRate()","1eab0a95":"testingContracts()","1eabc116":"buy(uint16)","1eabef31":"YKToken()","1eada765":"getConditions(uint256)","1eae5ff9":"getWaitPreselled()","1eae85cb":"priceOfDate(uint256,uint256,uint256,uint256)","1eaec76f":"FENIX(uint256)","1eafe00c":"isAmendedEarlyPurchase(uint256)","1eb02078":"getUIntTypesCount(uint8[])","1eb21875":"artistManifestoFundAddress()","1eb22b45":"sellerDatabase(address,uint256)","1eb25d13":"InitialSupply()","1eb25e0a":"configure(uint256)","1eb3957b":"requestDelegatedFrom(address)","1eb42523":"update(address,address,address)","1eb4dac6":"endSecondWeekICO()","1eb55c51":"CEI()","1eb5cb66":"resume(string)","1eb5de94":"privateExchangeRate()","1eb5ea2e":"returnFunds()","1eb726af":"contractAddress(string)","1eb79e44":"gasForGR()","1eb8befb":"setNewMediator(address)","1eb92366":"setRecommenderMulti(address[],address[])","1eb96a5c":"cancelOwnershipOffer()","1eb96f7c":"MahalaToken()","1eba7c7a":"setDefaultClaim(string)","1ebb24bc":"_postTransferHook(address,address,uint256)","1ebbc515":"MakerWithdrewAsset(uint256)","1ebbe681":"getWinningById(uint256)","1ebcbc93":"transferAdminShip(address)","1ebcdba4":"getWactive(uint8)","1ebcf2fb":"reclaimParsecCredit()","1ebd8263":"setMinimumBuyAmount(uint256)","1ebd8e6d":"XEVENUE()","1ebdaf8b":"testNewAccountHasZeroBalance()","1ebdd39a":"getWithdrawalData(uint256)","1ebde78b":"getSecondsTimeLockedByString(string)","1ebe1827":"EthLongExercised(address[2],uint256[8],uint8,bytes32[2],uint256,uint256)","1ebe5051":"StarzToken()","1ebe5c0f":"sendWithAllOurGasExcept(address,uint256,uint256)","1ebe8105":"tokenPriceUSDWEI()","1ebeb80b":"getBools()","1ebebb9b":"_checkAndSub(bytes32,bytes32)","1ebedded":"setAllRates(uint256,uint256,uint256)","1ebeec82":"_withdrawNAC(address,uint256)","1ebf0d11":"sellAllAmount(address,address,uint256,address,uint256)","1ebf1f5b":"hasSellerGuarantee()","1ebf42e5":"TokenAFL(uint256,string,uint8,string)","1ebfa2df":"getDiscountsAmount()","1ebfa358":"dateToTimestamp(uint16,uint8,uint8)","1ebfdca0":"servicesLength()","1ec29a5f":"getPurchasedAmount()","1ec32d15":"companyWallet()","1ec41163":"lastWinnerAddress()","1ec42d50":"_createWarrior(uint256,address,uint256,uint256,uint256,uint256)","1ec68b92":"saveMetaData(address,bytes,bytes32,bytes32,bytes32,bytes,uint32,uint256,uint256,bytes,uint256)","1ec6b60a":"startVoting()","1ec6dba6":"SimpleSaleToken()","1ec75025":"developerWithdraw()","1ec762a4":"setlvlWebsite(string)","1ec7cda4":"addTokenInternal(address,address,uint256)","1ec7e345":"tokenValue()","1ec87b86":"getTravelPrice(uint256)","1ec8a460":"AdifyToken()","1ec8bb8c":"distributeReward(address,uint256)","1ec8d5f7":"initialReleaseDone()","1ec8f9ba":"purchaseTickets(uint256[])","1ec9c2c0":"Sub(uint256,uint256)","1ec9f7b5":"longTimeLock()","1ec9fc84":"pendingFeesWithdrawals(address)","1eca98ce":"transferToAdvisors(address,uint256)","1ecb3889":"EurocoinB()","1ecb450e":"Devpr()","1ecc05f2":"validDelegate(address,string,address)","1ecc56f2":"initTimeOf(uint256)","1ecc644f":"vestStage()","1ecca316":"nextFreeTier()","1ecd0d03":"PoSPerCent()","1ecd3f30":"tokenReserved4()","1ecd9f21":"calculateDrugBuy(uint256,uint256)","1ecdfd2f":"setIEIAddress(address)","1ecfd4c3":"takeToken()","1ecfe64d":"_jSub(uint256,uint256,uint256,uint256)","1ed01f61":"maxWagerWei()","1ed0c2cc":"LifeSet_004()","1ed0e01c":"ltdParams()","1ed113ae":"getSignature(bytes)","1ed1d0f7":"KryptoGiftsMessages()","1ed1f196":"pf(address)","1ed20347":"cfo()","1ed24195":"getPeriod()","1ed2730a":"createInvoice(uint256,address,address)","1ed358e6":"recycleAppearance(uint128[5],uint256,uint128)","1ed378a1":"getHybridizationPrice(uint256)","1ed454a5":"memberLevel(address)","1ed5336b":"changeExerciseprice(uint256[],uint256[],uint256[])","1ed5da2f":"Controller_Address1()","1ed64f7b":"is_king_for_sale()","1ed692c0":"finalizeCrowdfunding()","1ed6a6ab":"emitFeeAuthorityUpdated(address)","1ed6f423":"changeDescription(address,string)","1ed77dc8":"presaleWallet()","1ed7830e":"partnerWallet()","1ed83fd4":"setHash(string)","1ed8f023":"BlockableContract()","1ed96e32":"disableTransmit()","1eda49be":"AheVotingBrainfood2()","1eda61d4":"customBonuses(address)","1edb0e73":"GILToken()","1edc44ed":"GameCoinToken()","1edc5ce0":"SUPPLY_FOR_MARKETING()","1edc8f03":"withdrawalEth(uint256)","1edc8f91":"openAuction(uint256)","1edd19e1":"bidExpireBlockLength()","1edf0c1e":"lockAndDraw(address,bytes32,uint256)","1edf0c3d":"TESTTOKEN()","1edf49ff":"myFirstToken()","1edfdb48":"addjoinlist_odd(address,uint256)","1ee04a3d":"TLTContract()","1ee13d0a":"creditDao()","1ee1665d":"WAMToken()","1ee17afd":"Thief()","1ee185ad":"roleRemove(address,string)","1ee284b1":"rockOwners(address,uint256)","1ee2e3cf":"unsetBlacklist(address)","1ee2fe6a":"defreeze(address,uint256)","1ee392c6":"getMaxProfitAsPercentOfHouse()","1ee426e1":"Eth2preNSP(uint256)","1ee44a5e":"listRequire(string,uint256,uint256,uint256)","1ee45da0":"sellEndTime()","1ee53e56":"presaleRate(address)","1ee55080":"getMotherCount(uint32)","1ee5f936":"stopTeamTokenTransfer()","1ee7c4bc":"LogNewAllocation(address,uint8,uint256,uint256)","1ee7ccc7":"preIcoInvestorsAddresses(uint256)","1ee9f029":"PREICO_HARDCAP()","1eea92c1":"levelExpAdjustment()","1eeaa389":"lockSupply(bool)","1eeac5d5":"TradelizeToken(uint256)","1eeccead":"tokensAlreadyMinted()","1eed0347":"applicationNameHashTaken(bytes32,bool)","1eed0f27":"setPriceUSD(uint256)","1eed1192":"newUser(string)","1eed4e09":"getVoteBy(address)","1eee993a":"addChild(address)","1eef94bd":"setAwardedUnfreezePeriodSeconds(uint256)","1eefddb1":"grace()","1ef0625b":"player_2(uint256)","1ef085db":"price3rdWeek(uint256)","1ef09ccf":"executeDelegateCall(address,uint256,bytes)","1ef17972":"ChangeOwner(bytes32,address)","1ef2c6d1":"closeTurnByHand(uint256)","1ef31b0d":"erotixFund()","1ef3755d":"restart()","1ef410e2":"addAudit(uint256,bool)","1ef5b90f":"release_(address,uint256[],uint256[])","1ef60485":"returnAccounts()","1ef741fd":"interestPeriod_()","1ef75084":"getCompoundPlan(uint256)","1ef75b1a":"GGToken(address,string,string,uint256,uint256)","1ef7b68a":"purchaseReceiptById(bytes32)","1ef987c1":"getInvestedAmount(address)","1efad671":"isPreSaleReady()","1efb06e0":"LogNewWallet(uint256,address)","1efb17ee":"changeHouseAddress(address)","1efba6c2":"fixedPrice()","1efdebb2":"hodlersCount()","1efe3abf":"getNumTasks()","1eff2b2f":"advisorIssueVesting(address,uint256)","1effc0d8":"createPerRound()","1f00c55b":"TOKENS_CAP()","1f0276fc":"_getKey(bytes32,uint256)","1f03bc1b":"setNewUserBonusCardTradable(bool)","1f049a49":"tokensBank()","1f04b54c":"test_ConsensysReached()","1f04becc":"ppFinishTime()","1f05ff29":"fromWeiToFp(uint256)","1f065f56":"KangGuo()","1f06c859":"promises(uint256)","1f078962":"setFlowerContract(address)","1f078f56":"winTokens(uint256,address)","1f0815ce":"togglePromo(bool)","1f09b0a2":"getDisplayGenVault(uint256)","1f0a21ad":"setAdvisers(address[],uint256[])","1f0b2561":"getCurrentBonusPercentage()","1f0b5553":"setBalances()","1f0ba6c9":"trade()","1f0c03f4":"forwardEndTime(uint256)","1f0c1e0c":"getEventTokenAddress(bytes32,uint256)","1f0c5f26":"CashMove(uint256,bytes32,address,address)","1f0da298":"transferTokensAndEtherValue(address,address,uint256,uint256)","1f0de21c":"addrunmoney(address,uint256,uint256)","1f0f2ce4":"withdrawOrderRefund(uint256)","1f0f711f":"discontinue()","1f0fd191":"test_threeValidEqUint()","1f0fd905":"getAssetIdCargo(uint32)","1f101520":"preIcoMin()","1f107635":"ownerSetAdmin(address[])","1f1144dc":"ViewOffer(address,uint8)","1f11d503":"GameSicBo(string,uint256,uint256,uint256)","1f124116":"approveSettingUpdate(uint256,bool)","1f12da06":"getPropertyPrivateModeLastUpdateEarnUntil(uint16)","1f130761":"tokensSent()","1f130d1f":"insertAddress(address)","1f13b5ae":"NokuMasterToken(uint256,uint256)","1f13de92":"inEther(uint256)","1f13f165":"NecromeunToken()","1f14df69":"balances(address,bytes32)","1f150322":"LogUserUnregistered(address,address)","1f15bc1b":"disallowTransfersTo(address)","1f15e163":"LaunchRocket(uint32,uint32,uint32,uint32,uint32,uint32)","1f161533":"distributeXYZ(address[],uint256)","1f167829":"nextDraw()","1f16c8b9":"getEndDateOfCampaign(bytes32)","1f16fda4":"multiTransfer(address[],address,uint256[])","1f1836fa":"isPresalePurchase()","1f1886e4":"extendSale(uint256)","1f18e56e":"removeOwnersWithHowMany(address[],uint256)","1f194b9f":"getFreeKilo()","1f1953ad":"addPokemonToMaster(address,uint256)","1f1aea6e":"initSale3(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","1f1b11cc":"buyMinerFromSale(uint256)","1f1bd005":"getRocCoreAddress()","1f1bd692":"text()","1f1c827f":"StartGame(string,string)","1f1c84b7":"decreasePresetTransfer(address,uint256)","1f1cb62b":"peg()","1f1dc61b":"checkPayLoan()","1f1de456":"regName()","1f1e1295":"isApprove(uint256)","1f1e2cfa":"calcUnMaskedEarnings(address,uint256)","1f1e6c4e":"createCollectible(uint256,uint256,address)","1f1ea554":"HolahopToken()","1f1ec029":"updateKeyPrice(uint256)","1f1eef6b":"getContributionHashByIndex(uint256)","1f1f5e76":"addValueToContribution(uint256)","1f1f8240":"_parseIntScientific(string)","1f201d7e":"level_judgment(address,address)","1f201e39":"etherandomExecWithGasLimit(bytes32,bytes32,uint256,uint256)","1f20f762":"losingAmount(address,uint256)","1f212106":"startICOStage7()","1f218cf1":"ICO_PERIOD()","1f21f9af":"marketMaker()","1f220be0":"unlock(string,bytes32,address,address,uint256)","1f221d4c":"updatePublicityBalance(address,uint256)","1f227fc8":"importTokensFromSourceToken(address)","1f23a9bc":"getAcceptedAndRejectedVotes(uint256,uint256)","1f23c22b":"getOpenBids(bytes32)","1f25cfaf":"changeBot(address)","1f261939":"payBid(bytes32,uint256)","1f2698ab":"started()","1f275713":"prefixed(bytes32)","1f278d32":"MyartPoint()","1f27a8b5":"set_transferrable(bool)","1f28c821":"tokensPreMinted()","1f296600":"brickETHPrice()","1f299c1a":"updateRegistry(bytes32,address)","1f29bdcf":"setAStore(string,address,address)","1f2a3e06":"scissors()","1f2c6414":"getAddressBatchByUsername(bytes20[])","1f2d62bc":"gameStartedAtBlock()","1f2d8d66":"getNumberVote(uint256)","1f2dc5ef":"divisor()","1f2e5461":"LOUDEX()","1f2e886c":"testControllerTransferTriggersEvent()","1f2e97c8":"slaveWalletPercentInitialized()","1f2ea6e0":"dealership(address)","1f2ec9c9":"setHoldAmount(address,uint256,uint256)","1f2efa83":"allocateIntoHolding(address,uint256,uint256)","1f2f7fc3":"dispute(uint256,uint256)","1f305ec7":"removeFromKycTeam(address)","1f30edc7":"CTOSignature()","1f312375":"referralBonusRate()","1f32768e":"getSubscription(bytes32)","1f32c18f":"getDrink(uint256)","1f34556a":"changeMaxReward(uint256)","1f34563c":"newUser(string,string)","1f34d1d3":"registerAppVersion(bytes32,bytes32,address,bytes4[],address[])","1f35bc40":"setCrowdsaleAddress(address)","1f3634ed":"ink(bytes32)","1f368fa6":"ExtrabitToken()","1f378b8a":"refundEther(address)","1f38034c":"removeEmailAddress(string)","1f38c358":"allocateIds(uint32)","1f390975":"MAX_TOTAL_CONTRIBUTIONS()","1f3943df":"SURT(uint256)","1f39716c":"aggregateBet(uint256,uint256)","1f39a141":"getTokenAmount(uint256,address)","1f3a3a53":"mint(int256,uint256)","1f3a4c14":"addFreezableAddress(address)","1f3a7c0b":"FOUR_YEAR_KEEPING()","1f3a98d1":"getReferralRates()","1f3b3148":"endEpochTimestamp()","1f3bec3b":"secondarySaleReserveWallet()","1f3c99c3":"logout()","1f3ce938":"increasePresaleEndTime(uint256)","1f3ceb51":"getGameById(bytes32)","1f3d3261":"JustForward(uint256)","1f3dcc8d":"maxGasPricePenalty()","1f3e1c8d":"LogTokensPurchased(address,uint256,uint256,uint256)","1f3e50f6":"withdrawBCEO()","1f3e64e6":"getTXwithCode(address)","1f3ee21f":"setUsdEthValue(uint256)","1f3fd5ca":"PI_EDIT_1()","1f3fe8d1":"ICO_BONUS1_SLGN_LESS()","1f3fed8f":"tokensForMarketing()","1f400477":"inLendingMode()","1f402356":"markContractAsInited()","1f417317":"WalletSimple(address[])","1f42103c":"AworkerToken(uint256)","1f4356e4":"emissionFunds()","1f43f396":"startICOStage5()","1f4425f3":"checkCloseTimer()","1f44a40f":"airDropSame(address,address[],uint256)","1f44b1de":"ValithToken()","1f45006c":"checkEthRaised()","1f455922":"removeToken(string)","1f45ad5c":"modifyContentAccess(bytes32,bool,uint256)","1f461f0d":"withdrawableAmountFor(address)","1f468245":"calculateObtainedBUB(uint256)","1f46eb98":"agentPermission(address)","1f470b14":"lockUpAmountOf(address)","1f471ad0":"proxyMint(address,uint256)","1f47b50d":"MineablePOWCoin()","1f47ba29":"safeToMul(int256,int256)","1f4848ef":"setTakeFee(uint256)","1f48af0a":"updateWeapon(uint256,string,string,string)","1f48ff7c":"mintMarketMakerApproval()","1f49aff4":"ACLYDcid()","1f49caac":"canUseLock()","1f4a5c32":"confirmTransactionAfterExpiry(uint256)","1f4a6d32":"removeEth()","1f4ab41e":"createUser(bytes32,bytes32,uint256)","1f4ae468":"returnETHforNormalBuyers()","1f4b8e41":"getLastUpdateId()","1f4ca28f":"isAdvisorsTokensSecondReleased()","1f4d7ec4":"newParameterizerWithToken(uint256,string,uint8,string,uint256[])","1f4dba8e":"OPTinToken()","1f4dde9f":"Jade()","1f4e01d9":"absoluteEndBlock()","1f4e1504":"upgradeContract()","1f4e996b":"challenge(bool)","1f4f77b2":"timestampFromDate(uint256,uint256,uint256)","1f4f9ab1":"supervisorVote(uint256,bool)","1f4fc29c":"refShare()","1f502a13":"volumeDiscounts(uint256,string)","1f513660":"ctoAddress()","1f522595":"donationsCount()","1f52692b":"vaultOwner()","1f52cc35":"removeTrustedContracts(address[])","1f532b39":"getRelation(address)","1f534715":"ComplexChildToken(address,string,string,uint256,uint8,bool,int256,bool)","1f535833":"referralCodeAt(address,uint256)","1f53ac02":"setDevWallet(address)","1f54d80d":"verifyCustomer(address,bytes32,bytes32,uint8,bool,uint256)","1f5623f3":"ZebiToken()","1f572504":"JackToken()","1f57256f":"transferEth(uint256)","1f583087":"ClickGemTokenERC20(uint256,string,string)","1f59653c":"setprices(uint256,uint256)","1f59d30e":"unlockEarnings(address,uint256)","1f5a0bbe":"addExecutor(address)","1f5a177f":"registerVestingScheduleWithPercentage(address,address,address,uint256,uint256,uint256,uint256,uint256)","1f5a2a52":"getDamageValue(uint256)","1f5bb9f8":"Refund_TrustlessTransaction(uint256)","1f5bdf5d":"isRegisteredUser(address)","1f5c3a3c":"approveMultiple(address,uint256[])","1f5c6f67":"getOpeningTimeByStage(uint256)","1f5d0b4c":"address(address,address,uint256)","1f5dddab":"WithdrawContribution(uint256)","1f5dfcd5":"lastBlock_a7()","1f5e881f":"_buyTokens(address)","1f5e8f4c":"isRestricted()","1f5e9a2a":"CyberMilesToken()","1f5eeb13":"tokenSendFailuresCount()","1f6034fd":"getInt8FromByte(bytes14,uint256,bytes1)","1f60d9f7":"crowdfunding_allocation()","1f617a60":"setReceivable(address,bool)","1f6275bb":"issueTokenAndTransfer(uint256,uint256,address)","1f63a350":"settle(bytes32,bytes32,uint8,bytes32,bytes32)","1f64c1f2":"getInvestorInforValue(uint16)","1f66531d":"getEsgoTX(uint256)","1f67298d":"Daq()","1f677d8d":"ownershipLength()","1f68f20a":"baseRate()","1f69565f":"getTokenInfo(address)","1f69aa51":"left77(uint256)","1f69d230":"setMultiLedgerValue(string,address,address,uint256)","1f69f929":"teamVestingCounter()","1f6a1bf7":"lastDifficultyAdjustmentEthereumBlock()","1f6a1eb9":"execute(bytes,bytes)","1f6a3943":"icoBackend()","1f6b0a9d":"getReleaseLockfileURI(string,uint32,uint32,uint32,string,string)","1f6b28bf":"valueOf(string)","1f6b5b7d":"setRefundState()","1f6b9b97":"placeBet(uint8,int8,uint8,uint256)","1f6c0a9b":"ReleaseLockedBalance(address,uint256,uint256)","1f6c76f4":"reserveDeveloperTokens(address,uint256)","1f6ce1d3":"setDaySellAmount(uint256,uint256)","1f6d2086":"setCooldownIndex(uint256)","1f6d3d13":"AddrDevelopGroup()","1f6dc06c":"SetSaleStep(uint256)","1f6de588":"PiedPiperNetworkCoin()","1f6e5117":"getCallbackAddress()","1f6e6f3a":"DigitalThothToken()","1f6eb6e7":"escapeHatchCaller()","1f6ee77a":"setInitialData(address)","1f6eeb68":"canMintBurn()","1f6f3c0f":"getShipProductAmountByModel(uint16)","1f706c64":"EndTimeUpdated()","1f71f250":"updateTopicAddress(bytes15,address)","1f720e71":"testThrowTranferTooManyTokens()","1f7266e8":"owner_TransferFromTo(address,address,uint256)","1f7299c1":"processSell(address,uint256,uint256)","1f72d7d8":"increaseCap(int256)","1f7334e2":"TransferFlower(address,address,uint256)","1f74de51":"getAuditOutcome(address,bytes32)","1f772a34":"token_symbol()","1f77aac0":"queryUserContract(address,uint256)","1f790a94":"BananaGame()","1f794436":"getBlockHeader(int256)","1f7a41f1":"rawNameOf(address,address)","1f7a72f7":"bobClaimsDeposit(bytes32,uint256,bytes32,address,address)","1f7ab15d":"setdecimals(uint256)","1f7af1df":"canReceiveMintWhiteList()","1f7b4f30":"roll(uint256)","1f7b5318":"getBlocklancerToken()","1f7b6d32":"length()","1f7b8622":"getVotingDeadline()","1f7c4bf3":"AccessControl()","1f7ccc09":"initAssetFile(string,string,string,string,string,string)","1f7cdd9b":"unicornsGifted()","1f7d16f7":"managementWalletAddress()","1f7df96f":"registLogo(address,address,string)","1f7e3e72":"test_oneValidEqStringUint()","1f7e495b":"systemSupply()","1f7fe78b":"balanceAtSnapshot()","1f800e8e":"releaseVested()","1f803ac3":"getUnlockedTokens(address)","1f807736":"withdrawFreeAuctionBalances()","1f81582c":"returns()","1f816c6d":"hodlerReward()","1f820f52":"migrateEuroTokenOwner(address,uint256)","1f83bcd7":"withdrawlDeadline()","1f83d11a":"addMilestonesAndSeal(uint256[],uint256[],uint256[],uint256[])","1f83d75e":"updateProfileDetails(string)","1f83f440":"getPaymentByAddress(address)","1f86ab51":"confirmCollection()","1f86ffda":"UpdateBid(address,uint256,uint256)","1f8712af":"isValidPurchase(address)","1f871726":"getCategoryWorkClockTimeRef(uint256)","1f879433":"setSolver(address)","1f8814ad":"ElyERC20(uint256,string,uint8,string,bool,bool)","1f8864ac":"setStorageOwner(address)","1f887d56":"CryptoSagaDungeonVer1(address,address,address,address,address,uint32,uint256,uint256,uint32,uint256,uint32,uint32,uint32[4],bool)","1f8947c1":"extractUint(int256,bytes,uint256,uint256)","1f89e911":"getCompositionPrice(uint256)","1f8ac604":"mul0()","1f8ae3f0":"proofFailed(bool)","1f8c07b0":"startPhase(uint256,uint256,uint256)","1f8d1d50":"setTotal(uint256)","1f8d99a9":"assetIsRegistered(address)","1f8df2cd":"setGeneScientist(address,bool)","1f8e6fb3":"transferSale(address,uint256,uint256,uint256)","1f8e728c":"addMilestone(uint8,uint256[],uint8[])","1f8e9143":"AcceptsKDI(address)","1f8ea5e8":"EternalChainToken()","1f8eac47":"spentByTeam()","1f8f1d21":"addMember(uint256,address,bytes32)","1f8f69e3":"fechAllVoteResultForCurrent()","1f8f8100":"Tspace()","1f8fcc45":"Vantador(address)","1f903037":"getBytes32()","1f903b5d":"preSaleSpenderTxDetails(uint256)","1f90b2a5":"snapshotBlock()","1f90ffc8":"AddSupply(uint256)","1f91666d":"newOrganisation(string,string,string,uint8,bool)","1f91e309":"getBuyBackPrice(uint256)","1f922d06":"duplicate()","1f92f6b7":"setBtcUsdRate(uint256)","1f934299":"calcConfirmsNeeded(uint256,uint256)","1f960571":"picops_balances(address)","1f963f80":"getReportingWindowId(uint256)","1f96938d":"deliverSale(address,uint256)","1f96add4":"ChronoMint(address,address,address)","1f974fe4":"NExT()","1f979e23":"GetRigData(uint8)","1f97a238":"rejectCertificate(uint256)","1f97c00e":"tokenCreationMax()","1f97ea5d":"EDU_PER_ETH_PRE_SALE()","1f97f2ef":"issuedTokensForCommand()","1f98394d":"basicReward()","1f994137":"booleanStorage(bytes32)","1f995ef1":"HDCTestToken()","1f9988c9":"transferTokens(bytes32,address,uint256)","1f99c458":"listNamesLen()","1f99d862":"test_method_increaseTimeBy30000()","1f9a08ca":"reelIn(uint16,uint16,bytes32,bytes32)","1f9a391c":"setCanCreateGrants(address,bool)","1f9ab193":"place(uint8)","1f9c5580":"AMIS(address)","1f9c564f":"rubusOrangeAddress()","1f9c649f":"HashInvalidated(bytes32,string,uint256,uint256)","1f9d7ab8":"addTokens(uint256,string)","1f9ea25d":"_setDepositAccount(address)","1f9eba17":"bitcoinInvest(address,uint256,uint256)","1f9ecab1":"TowerImagesCoin()","1f9ef7fa":"getPayoutNumerator(uint8)","1f9f168e":"startNewRound(address)","1f9fed62":"checkMySellerOffer(address)","1fa03a2b":"isApprovedFor(address,address)","1fa08755":"upgradeDexterity(uint256)","1fa08ad8":"EtchReward(uint256)","1fa0914e":"buyStamps()","1fa096e6":"isInversor(address)","1fa0dc70":"saveReturnSatoshi(address,uint256)","1fa13a61":"longTermTokens()","1fa24aa7":"makePermanantlyTradable(uint8)","1fa30523":"doMint(address,uint256)","1fa3c372":"redeemTokens(bytes32)","1fa3cfaa":"bmc(uint256,uint256,address)","1fa4070c":"TestCoinVN()","1fa422a2":"earliestNextSettlementTimestamp()","1fa45291":"arrayOfClones(address)","1fa498ce":"messagetodovie()","1fa4c486":"PublicResolver()","1fa4d9de":"completedAddingParsels()","1fa4ea66":"reservationAddress()","1fa5e43b":"freezedBalanceOf(address)","1fa62fb7":"setCountrySlogan(uint256,string)","1fa6f19b":"getAddressForQuery(bytes32)","1fa96b96":"currentProposalResults(uint256)","1fa98406":"fundType()","1fa9d21f":"DASABI_IO_Contract()","1faae8b3":"getTypeValue(uint256)","1fab0265":"messiDev()","1fab3fd4":"setFinishedTx(address)","1fabb318":"MAX_ALLOWED_BY_STAGE_1()","1fabe6cf":"getActualCompletionDate(bytes16,address,address,uint256,uint256)","1fad4d46":"getShipOwner(uint32)","1fad4e79":"sevenWinnerWithdraw()","1fae75eb":"Xandra()","1fae9361":"changeTimes(uint8,uint8)","1faec182":"getBet(uint8,uint256)","1faf1ed4":"unlockTip()","1faf8995":"fillOrder(address,bytes32,uint256,bytes32)","1fafc2c8":"updateBusinessReserveAddress(address)","1fb00cdc":"investWithId(uint128)","1fb150c4":"_batch1_icosaleEndTimestamp()","1fb156ef":"ecmul(uint256[3],uint256)","1fb168ac":"setStopStatus(bool)","1fb1f18b":"getWinnings(address,uint256)","1fb25f07":"getCertification(bytes32)","1fb291cb":"registerInt(address,int256)","1fb2de2c":"sendTokensToTwo(address,address,uint256)","1fb2f2a0":"testUpdateLatestRevision()","1fb384cb":"RemoveRocketForSaleEvent(address,uint32)","1fb47fe8":"CulturePhilosophyFaithChain()","1fb4bcf8":"SetSaltPassword(bytes32,bytes32)","1fb4d1e7":"TheMutualCurrency()","1fb59f9d":"swapProxyTokens()","1fb6e99d":"paymentNeeded(uint64)","1fb82d26":"storeProof(string)","1fb8875d":"referralSent()","1fb8c0ed":"releaseEQUIWihtoutKYC()","1fb8d5de":"vaultUnlocked()","1fb97c34":"updateFirstAmount(bytes32,bytes32,uint256)","1fbab493":"checkPrice(address,address,bool,uint256,uint256)","1fbb408a":"RacingToken()","1fbb4def":"CalculateDividents(uint256)","1fbbf4bb":"setKillingGap(uint256)","1fbcf2c1":"_lotterySupply()","1fbd3564":"getContentsManager()","1fbd7771":"didSoftCapReached()","1fbd9a0b":"REFUNDSACTIVE()","1fbda78f":"LibraryToken()","1fbe1979":"rescue()","1fbe480e":"shipToMe(string,uint256)","1fbe7475":"findEndpointByAddress(address,address)","1fbeaa83":"PublicBatchTransfer(address,uint256)","1fbee6ed":"CNYTokenPlus(uint256,string,uint8,string)","1fbf7c3e":"increaseReserve(uint256)","1fbfe6f3":"auditReport(address,bool,bytes32,bytes32)","1fc03aa0":"getTypeByNumber(uint256)","1fc05f86":"minimalWei()","1fc06f0d":"niceGuys(uint256)","1fc083cf":"OurBit()","1fc0e5e9":"StartPaymens()","1fc1e25f":"listToken(address)","1fc242b9":"onVote(address,int256)","1fc24caa":"changeMaxTransactions(uint256)","1fc27ef2":"isIcoActive()","1fc2e0fb":"MinedThisYear()","1fc3a519":"computeReturn(uint256)","1fc5b4ee":"balancesByIndex(uint256,address)","1fc5c9b7":"setNextPeriod(uint256,uint256)","1fc62fce":"Trillionereum(address,address)","1fc6e13a":"getRoundKeyPrice(uint256)","1fc75e41":"preSaleWallet()","1fc7d658":"purchase(address[16],uint256)","1fc82e83":"allocateUnclaimedFees()","1fc86532":"endBlockBonus2()","1fc87587":"get_CountProfitsToken()","1fc928ae":"taxToken()","1fc97e34":"Genius()","1fc983fb":"ChelseavsArsenal()","1fca5278":"highScore()","1fca5fda":"IsRazRunning(uint256)","1fcafd8f":"FomoMasterCoin()","1fcb292d":"getTokenFunction(uint8)","1fcbbefa":"sendBooty(address,uint256)","1fcc02e8":"EthereumTestToken()","1fcc2515":"ChangeCrowner(address)","1fccc158":"tCampaignEnd()","1fcd08f0":"AaadharDemo()","1fcd7ea6":"getPOOL_edit_33()","1fcdfe14":"icoTokenAmount()","1fcf25be":"getTransactionSuccess(bytes32,uint256)","1fcf55ff":"withdrawApplication()","1fd01085":"_sellPresale(uint256)","1fd01de1":"_checkOnERC721Received(address,address,uint256,bytes)","1fd023ab":"FFCryptoCoinToken()","1fd22140":"CountCourses()","1fd2676f":"jackPotPercents()","1fd2e006":"changeClassFee(uint256,uint256)","1fd3dd97":"OneEtherEqualsInWei()","1fd41949":"setMaxInvestedLimit(uint256)","1fd476bd":"AutonomousSoftwareOrg(bytes32,uint8,uint8,bytes32)","1fd4b40c":"saleEtherCap()","1fd55a8a":"crowdsaleOpened()","1fd7b802":"ModifyMine(uint256,bool,string,uint256)","1fd7f431":"setCCH_edit_7(string)","1fd8088d":"minLimit()","1fd8291a":"endpresale()","1fd86a6a":"FundICO(uint256)","1fd96b69":"ManagedAccount(address,bool)","1fd97c12":"CNotesICO()","1fd982a5":"releaseForEarlyInvestor(address,uint256)","1fd9b2a4":"createValidatedRequest(address[3],address,uint256[12],uint256,bytes)","1fd9f187":"catNoLongerForSale(uint256)","1fda4271":"MindToken()","1fda5b45":"receivePlayerInfo(uint256,address,bytes32)","1fda8278":"drawCoach(uint256,address,address)","1fdaedf2":"BoomstarterPresale(address[],address,address,bool)","1fdaf3f2":"ServiceAgreement(string,string,uint8,uint256,uint256,uint256,address,address,uint256)","1fdb5a2b":"addInvestmentPreIco(address,uint256)","1fdba848":"BiekensToken()","1fdcf5a7":"lockEthBalance(address,uint256)","1fdd7695":"getbuyprice(uint256)","1fddbba4":"totalVUP()","1fde4607":"setCreditDaoFund(address)","1fde8469":"setExchangeRate(uint32)","1fdf071c":"approveMintAgent(address,bool)","1fdf6e0c":"protectKingdom()","1fdfa40d":"test_setupBoardRoomAndAssert()","1fdfec35":"calculateTotalDue(uint256,uint256)","1fe00a15":"individualMaxCapTokens()","1fe07274":"SDEToken(uint256,string,string)","1fe08e28":"how_many_arbits_do_i_have()","1fe0ff58":"finishRound(uint256)","1fe1516d":"sendToTeamEthContract()","1fe15db5":"MarketboardListingComplete(address,uint256,uint256,uint256)","1fe1b208":"totalavl()","1fe26e9d":"componentCount()","1fe2a6f2":"updateJugada(uint256,bool)","1fe2c933":"UpgradeByCredits(uint256,uint256)","1fe2d046":"assignRafflePrize(address)","1fe2e229":"getTotalTrust(address)","1fe3aec7":"CGCGToken()","1fe4ee7f":"getVoteItemDetails(uint256)","1fe51f82":"persistLimit()","1fe55867":"rew()","1fe6189e":"PARTNERS_ADDRESS()","1fe64f19":"MaximumHodlDurationChanged(uint256,uint256)","1fe74895":"Etherchicks()","1fe7b624":"resumeMint()","1fe7ff2c":"SpriteToken()","1fe8149e":"createTokenByHWC(address,uint256)","1fe8500e":"setItemRegistry(address)","1fe8629a":"giveMultipleItemsAndDestroyMultipleItems(address,uint256[],uint256[])","1fe93774":"totaleFrasi()","1fe97e45":"whoIsConcerned(address)","1fe9eabc":"setMax(uint256)","1fea96cd":"removeUserFromBlackList(address[])","1feac75b":"setCommissions(uint256,uint256)","1feaee17":"getSetupParametersByIndex(uint256)","1feb0c4f":"PreICOProxyBuyer(address,uint256,uint256)","1feb19d6":"initialize(uint256[],uint256[],uint256,address,uint256,address,address)","1feb3569":"transferToken_toBalance(address,uint256)","1fec0e96":"LogCampaignAdded(uint256,address,uint32,uint96,uint16,uint16,uint256)","1fec5a11":"Coin77()","1fec6dce":"createVestingPeriod(address,uint256,uint256,uint256,address,address)","1fedbc03":"getSharesPercentForPeriod(bytes32,uint256)","1fedd70b":"snipCoinToEtherExchangeRate()","1fee37c8":"ADDR_TKG_NODE()","1fee5c51":"set_min_max_FinneyPerSale(uint256,uint256)","1feef08e":"getTotal(uint256)","1ff13086":"size(int256)","1ff14311":"totalOutcomeAmounts(int256)","1ff1a378":"maxSalesAllowed()","1ff2c22b":"setCharityFund(address)","1ff42195":"minimum_cash_proof_amount()","1ff517ff":"totalDebt(address)","1ff5668c":"depositForDividends()","1ff5e17c":"_itemLength(uint256)","1ff6536c":"setCrowdSaleStart(uint256)","1ff6a54b":"cancelFavor()","1ff6ad55":"tokensForPeriod(uint256)","1ff6c241":"collectedUSD()","1ff75851":"updateICODate(uint256,uint256)","1ff76f86":"ROBReserveAllocation()","1ff7a278":"ownerNegTokens()","1ff858d0":"activateNextStage()","1ff8ac8a":"getFinalval()","1ff8d507":"toggleSwap()","1ff96c74":"getHonour(uint256)","1ffa27f9":"hasPermissions(address)","1ffa451c":"serviceTransfer(address,address,uint256)","1ffb6ca6":"unlockTransfer(address,uint256)","1ffbb064":"isAgent(address)","1ffbf32b":"MUSPRA()","1ffc973a":"HedgeCash()","1ffcb18c":"numQuestions()","1ffd3aef":"log10Floor(int256)","1ffd42ab":"getVotingScriptAction(uint256,uint256)","1ffd99f4":"saler()","1ffe3c9b":"UECToken(address,uint256)","1ffe4cca":"startline()","1fff2d8a":"payToPresale(address)","1fff5c2f":"bindEthereumAddress(address,bytes32)","1fff7a97":"CompositionPart(uint256,address)","1fffbe7a":"getJobSponsorships(uint256)","200138b9":"CrowdTmoney()","20020a3a":"createAsset(bytes,uint256,bytes,bytes,address)","20027275":"saleStartBlock()","2002c2f6":"slogans(uint64)","20033848":"MagixRecordsCoin()","20035e36":"icoEth()","200373c9":"fees_()","2004b6a6":"TheWhaleWins()","2004dff6":"Basics()","2004ffd9":"mintToken()","200538c6":"DTE()","200576b5":"TchainToken()","2005db6d":"preIco(uint256,uint256,uint256,uint256[],uint256[])","2007474e":"theRelayer(address)","20076659":"Arbitrator()","2008c2ca":"destPercent(address)","2009a059":"setLandProductionMultiplier(address)","200a252a":"PhanToken()","200aa519":"addCustomerwithToken(address,uint256,address)","200aac9f":"burnAZLTEST(uint256)","200b0fa6":"initVote(uint8)","200b894d":"assertEq(int256,int256,bytes32)","200b8951":"_distribute(address,uint256,uint256,uint256)","200c1f19":"premiumPacks()","200c7295":"whitelistAddress(address,uint256)","200c7770":"bountyDuration()","200cdf8e":"becomePickleRick()","200d10dc":"OrpheusOrganicsLaos()","200d2ed2":"status()","200deb8b":"MessageSent(string,string,string,uint256)","200ebe34":"addTokensToGive(address)","200ef97e":"payNTS()","200f29e3":"advisorAccount()","200fbcf0":"getFullyVestedAmount(address,address)","201035ed":"getGunsIds()","20104dca":"engCommunityAddress()","2010bdce":"removeSupervisor(address,address)","20120dce":"ADMIN_SET_TEST_RANDOM(string)","20130753":"testThrowSetNotRetractableNotOwner()","20145328":"changeMelonportAddress(address)","2014c515":"tgrNextPartInvestor()","2014d703":"approveAllArgs(address,uint256,address)","2014e1fb":"W0keAFCrowdsale(uint256,uint256,address,address,address[])","2014e5d1":"isRunning()","20150e21":"sendDividends(uint256)","20153d38":"EarlyAdoptersAmount()","20154e78":"unpausePVP()","20158c44":"fills(bytes32)","201745d5":"disown(bytes32,address)","2017af61":"initialTokensHolder()","2017ee03":"nextDealIndex()","20183926":"EngagementToken()","20185aa2":"liquidityWithdraw(uint256)","20188d4f":"getAdjustedContribution(address)","20190ccd":"startCirculation()","201bafee":"TroneriumSupply()","201dcd7a":"newChallenge(uint256,uint256)","201de654":"mnemonicsCount()","201e8f0e":"changeWhitelistCornerstoneStatuses(address[],bool)","201e908e":"blockDuration()","201f1506":"EthereumEra()","201f6e02":"oldAppreciationRateWei()","201f96e5":"setRepMarketCapInAttoeth(uint256)","20202965":"expired(bytes12)","20204fb7":"genericCall(address,bytes,address)","2020e9ea":"bid(uint16,uint16)","2021dfcb":"BONUS_DURATION_3()","20226e17":"valueOnContract()","2022936f":"BalanceClaim(address)","202329cb":"get_all_activityn(uint256)","2024617e":"initialize(string,string,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","20250264":"setData_5(uint256)","2025867b":"qualifiesAsCommunityBallot(uint16)","2025e52c":"createSaleTokensVault()","20260697":"createWallet(uint256,address[],bytes32)","20263e87":"incentiveTokenAddress()","2026a0a7":"change_sale_address(address,string)","20277ed7":"GWGFPLUS(uint256,string,string)","2027d2c6":"ETHLottery(address,uint256,uint256,uint256,address)","2027d746":"getCustomerCount()","2027e1d3":"COCO()","20281990":"ProposalAddedEvent(uint256,address,uint256,string)","20283da9":"trustedWithdrawETH(address,uint256)","202920ef":"FST()","2029e599":"addCode(string,string)","202a46cf":"limitEther()","202a6ce0":"NFXCoin()","202ac3bc":"withdraw(bytes,bytes,bytes32)","202b876a":"allocateToMarketingSupporter(address,uint256)","202bb36d":"JTBlockchain()","202bc7e7":"getIntervalCoefficientMultiplier(uint256,uint256,uint256,uint256)","202c413d":"setNickname(uint256,bytes32)","202ca027":"setPayrollAddress(address)","202d5123":"STRTToEth()","202d6eaf":"addInvestorsValue(uint256)","202e3924":"getOperation(uint256)","202ece74":"sendToWinner(uint16)","202feb77":"test_2_assertGasUsage100Boards()","2030762a":"PoolICO()","2030f721":"num_objects()","20323763":"addPerformance(string,uint32,uint8,uint8,uint8,uint16,bool)","2032677f":"roundOpen()","20334668":"verify(uint256,uint256,uint256[],uint256,uint256,uint256[],uint256[])","20339891":"addGridMember(address)","2033d9ae":"switchToDistributionMode(uint256)","2033de43":"setNewRatesCustom(uint256,uint256,uint256,uint256,uint256,uint256)","20352a6e":"ChildDeposit()","2035d6b4":"addAccountData(string,bytes)","20364306":"setMaxLinkedWalletCount(uint8)","2036e2f7":"getCurrentExchangeRate(uint256)","20375692":"initVesting()","2037fcbf":"withdrawInvestment(uint256)","2038d1e5":"setTokenMintFeeAbs(address,address,uint256)","2038e2e6":"timestampLast()","2038e80a":"mixFormula()","20392160":"round1Sold()","20396553":"safeMul(int256,int256)","203967a5":"toDie(bytes32)","203985d6":"getWeeklyTickets(address)","20398971":"abiOf(uint256)","20398b83":"sendPrepaidEthTweet(uint256,string,uint256)","2039b386":"isHashSigned(uint256)","2039d9fd":"depositERC20Token(address,uint256)","203a318f":"ico_startdate()","203a79f6":"cutoffTimestamp()","203ab888":"collectOriginalBet()","203b2352":"_checkOpenings(uint256)","203c03fa":"Coinflip()","203cbee2":"ownerPetTransfer(address,uint64)","203d39ff":"getOrderBook(address,address)","203dacb9":"PrivatePreSale()","203e0dc9":"SupbToken()","203e3204":"goldIfFreeze(address)","203faa89":"lastState(address)","203fb521":"addTransaction(address,uint256,bytes,uint256)","203fec23":"LogTransfer(address,address,uint256,string)","204009d2":"transferForMultiAddresses(address[],uint256[])","20409b47":"updateContent(string,uint256)","2041518d":"calculatePrice(uint256[],address)","2041b997":"tokenizeProperty(string,address)","20422fd9":"setAutoInvestByAdmin(address,bool)","204241cb":"leaveTeam(uint256)","2042495b":"changeUsed(address,int256)","2042e5c2":"removeWhiteList(address)","2043285d":"getMarketMakers()","2044b21b":"exceedsSaleCap(uint256)","204525e6":"mul256()","204605ad":"ngrzicoToken()","2047e4af":"updateTokensState(uint256,uint256)","2048cba4":"inGroup(address)","2048e5f7":"PaytherToken()","20495427":"setBreedingAuctionAddress(address,address)","204a88c5":"hasAgreement(bytes32)","204b21d1":"AVAILABLE_BONUS3_SUPPLY()","204b676a":"numVestingEntries(address)","204d3d65":"getCountPlayersOfTeam(uint256)","204e6749":"rewardToken(address,uint256,uint256)","2050c26e":"preSaleFourthCap()","205140c7":"totalClaimableTokens()","20514abf":"tktotal()","20522347":"changeEndDate(uint256,uint256)","20523d0d":"closeAgreementWithTimeout(bytes,uint8[2],bytes32[2],bytes32[2])","2052de16":"checkContinuousPurchase(uint256)","2053480e":"ActionMiningPlat(address,uint16,address)","205360e0":"setReward(uint64,uint256)","2053e690":"turnOffOraclize()","20544010":"getWinningsForRecordId(uint256,bool,bool)","20547a42":"increaseDailyTransactionVolumeReceiving(uint256)","2054b2c6":"assert(address,address)","2055c2ff":"SerchUserPurchase(address,address)","20566ae8":"initMonsterClassSiteSet()","2056ab36":"NewNodePriceTicker(string)","20572943":"SignedMessageOracle(bytes32,uint8,bytes32,bytes32)","205730fd":"SELL()","2057420b":"withdrawVault(uint256,address)","2058308d":"_addPropertyValue(bytes32,address)","20592076":"HeyToken()","2059c548":"exerciseOptionsDeadline()","205b1946":"hasContributed(address)","205b931e":"addOracles(address[])","205ba186":"DSJL()","205c2878":"withdrawTo(address,uint256)","205c7cf5":"issueCenturion(address)","205c9cc7":"w()","205d0063":"feeTakeExporter()","205d6c86":"purchaseEgg(uint64,uint16)","205dc0ee":"poolAddressCapTier1()","205e0e26":"advisersCliff()","205f3b58":"calculateOwnerCut(uint256)","2060a150":"props()","20610779":"deathData_a2()","20614514":"HHDToken()","20620f37":"onAuctionEnd(string)","206288d3":"deployBlockNumber()","2062e457":"setDirectPaymentThreshold(uint256)","2063165d":"union(uint256[],uint256[])","206369fa":"AthleteToken()","206465f7":"_getPendingOwner()","20647eb7":"externalFailure()","20651d5d":"batchTransferToken(address,address[],uint256[])","20654277":"ArtsCoinV1()","206545c2":"DIAMOND()","206607f2":"updateCanFetch(bool)","20675504":"hyperInterface()","2067c85c":"transferTokensFromMarketingAddress(address,uint256)","20688582":"saleIsRunning()","20689f29":"preSalePeriod()","2069381a":"multiPresaleMint(address[],uint256[])","20694db0":"addIssuer(address)","2069de94":"TonalQuantum()","2069f66c":"isPresalesNotEndedInAdvance()","2069fc46":"excludeAmbassadors(uint256,address)","206a44f3":"getNum(bytes,uint256)","206b64b4":"generateName(bytes16,uint256,uint256)","206cfd24":"cleanFinishedOperations(uint256)","206d0125":"getWithdrawnFromBatch(address,uint8)","206d1fde":"setMegaAddress(address)","206d468f":"PriceOracleInterface(address,address)","206ec7a1":"multisend(address,bytes32,address[],uint256[])","20701967":"confirmPlatformWithdrawal()","2070748c":"XeroBest()","20709b35":"jackpotPaused()","2070b6de":"donationPhase()","20714f88":"setSelfDestructBeneficiary(address)","2072343e":"MeowToken()","2072863b":"setCMO(address)","20729b83":"DistributeButtonIncome()","2072cde2":"NewsCash()","207368fc":"startSelling(uint256,uint256)","20745669":"ClaimedSignature(address,string)","2074cc86":"MikCoinToken()","2075281c":"Marko()","2075eec6":"tokenQuantities()","20768ee8":"getProposalID()","20770caf":"GRUCoin()","2079405b":"AmountToDistribute()","20799608":"convertDecimal(uint256)","2079fb9a":"signers(uint256)","207a6c33":"calculateCurrentVirus(address)","207a6d80":"TukBuk()","207aba24":"Migrate()","207acb53":"_calculateRequiredTokenBalance(uint256,uint256)","207b89e2":"purchaseLand()","207bd99d":"ableTransfer()","207beb59":"getRateIcoWithBonus()","207c64fb":"validate(address)","207cb710":"grantInvestorTokens(address)","207e6467":"pieBalances(address)","207f4f38":"contTransfer(address,uint256)","2080d8dc":"EVTCTLToken(address,uint256)","20813154":"deregister(bytes32)","2081e911":"Set()","208318bd":"Total_Amount()","20832219":"setOps(address,bool)","2083250d":"Atriark(uint256,string,uint8,string)","20834ed0":"AddPlayers(address,address)","20835e8c":"getBet()","2083c730":"_hatchEggs(address)","2083cbd8":"execAirDrop(address,address[],uint256[])","2083f44f":"lastFell()","20857295":"setErc20TokensContract(address)","2085f554":"approveAndCall(address,uint8)","2086ad60":"MiewGold()","20871322":"ForecastingFactory(address)","208838c8":"tokenPerWai()","20885d9e":"PGE02CH()","208904c7":"startFrom()","208972b4":"PartialPayment(uint256,address,address,uint256)","2089d0c9":"Swachhcoin(address)","208a099c":"createKitty(uint256,uint256,uint256,uint256,address)","208a9e37":"tweakRefundStatus()","208af09f":"setIsForking(bool)","208b080f":"changeExpiryLimit(uint256)","208b3116":"next(uint256,uint256)","208b7427":"AgriChainContext()","208c1019":"BLOCK_BASIC_PRICE()","208c8692":"mint(bytes,uint256,bytes,bytes)","208ca719":"SellIPG(uint256)","208df65f":"getValueByNumber(uint256)","208e1cc3":"writeConditions(uint256,string)","208e8914":"atFundDeposit()","208eba04":"_withdraw(address,uint256,address)","208ebf16":"lpBidVolume()","20907d9a":"BlockClout()","20909455":"triggerAirDrop(address[],uint256)","20909fa0":"communityCurrency()","2090b0a8":"m_allowPrivileged()","2090cf8b":"consultBalance(address)","2090d5e9":"lookupByProject(uint256)","2090d8a6":"trackOdd(uint256)","2090f3e3":"lethalBonusAtHitsLead()","209164d5":"_processPurchase(address,uint256,uint256)","20917902":"globalether()","2091f2d9":"ICOoverTimeStamp()","2092970f":"StartDistrib()","20940b13":"btcTransactionClaimed(uint256)","2094e9d8":"newJob(bytes32,bytes32)","20956341":"slice2(bytes,uint256)","2095f2d4":"endCrowdsale()","20965255":"getValue()","20968dc7":"rewardHistoryLengthOf(address)","2096b768":"getCoreAddress()","2096c958":"GEXAirDrop(address)","2096f2ff":"issueTokensMultiple(uint256[],uint256[])","2097dd04":"getLatestAuthorizedAddresses(uint256)","2097e5f0":"VaultbankToken()","209878b9":"lockReleaseTime()","20987e64":"addInvestment(address,uint256)","2098e37a":"LogBoonReleased(address,uint256,uint256,uint256)","2099940e":"freezOne()","209a5b8a":"moneySumAtSettlement(address,uint256,int256,uint256)","209ab711":"registerReferral(address)","209b7067":"CALLGToken(uint256,string,string)","209b80ce":"previousstageloser()","209bb163":"Ethex(address,address,uint256,uint256)","209cccd7":"channelCloseTimestamp(uint64)","209ebc08":"isPaid()","209f3c9c":"MINIMAL_PARTICIPATION()","20a0045a":"SALE_END_TIME()","20a0128e":"ICOEndDate()","20a09dec":"COMM_SUPPLY()","20a168b1":"coinsPerEth()","20a17b24":"dexWallet()","20a2b135":"forkThis()","20a3952b":"MyTestGameToken()","20a4e8f8":"_clearSnapshotDelegators(uint256,address)","20a60ace":"TokenBurner()","20a733df":"countPerformers()","20a7b2d7":"_setMintFeeProp(uint256)","20a7d5c3":"lend(uint256,bytes,address,bytes)","20a99bd0":"templates(address)","20aac36f":"getstopBlockNumber()","20aba08b":"rho()","20abf417":"stageFourCap()","20acbc83":"withdrawTokensFromWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","20ad3874":"vestingBonusMultiplierPrecision()","20ad8a81":"setTeamTokensPercent(uint256)","20ae2059":"setMaximumBet(uint256)","20af0841":"_payPayee(bytes32,address,uint256)","20af2042":"setCountPerStep(uint256)","20b023c8":"disavow()","20b0554e":"payoutBalance()","20b0747f":"start1stRound()","20b0961c":"pE(uint256,uint256,uint256,uint256)","20b0eafb":"PoWH4D()","20b0fe2c":"setGlobalParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint32)","20b1b0ab":"getStuckCoin(address,uint256)","20b1d054":"TAAS_VAULT()","20b27291":"setFinalized(bool)","20b28ade":"getIPFSHash()","20b2af52":"Author()","20b2d97b":"LiquidDemocracyRules(address,address[],uint256)","20b3c9c9":"InfinixSupply()","20b431aa":"dividendDivisor()","20b44b29":"lockTransfer(bool)","20b4577e":"numBonuses()","20b4fc29":"setBbAddress(string)","20b519bb":"setBarrierAsOpen(bool)","20b652ba":"chainedFunctions()","20b748f4":"REGULAR_TYPE3()","20b7ceb8":"R2Xtoken()","20ba5b60":"insert(bytes,bytes)","20bacfbd":"addDoc(string)","20bb0ef6":"originalHash(uint256)","20bb280b":"buy5(address[],address[],uint256[],bytes,bytes,bytes,bytes,bytes)","20bb2adf":"setAllowedTransferFrom(address,bool)","20bc4425":"getHost()","20bcbee5":"EarlyTokenSale(address,address)","20bd0475":"resetLotteryBalance()","20bd46b7":"drawTertiaryAWinners(uint256)","20bf0c52":"Derived(uint256)","20bf2f47":"_setAddresses(address,address,address)","20bf92ca":"oldSeeleToken()","20bfa95c":"bookAndCalcRemainingPremium()","20bfde8b":"s24(bytes1)","20bfec70":"WatchFees()","20c0b493":"getWarriorChestPrice()","20c12f16":"penalizeInactiveJuries(address[],uint256[])","20c21ba5":"_setTypeValue3(uint256)","20c28b85":"schelling(address)","20c2d5e4":"withdrawAffiliatePot(address)","20c2f40b":"doCalculate(uint256,bytes32)","20c381af":"cityPoolTotal()","20c3be47":"_createZombie(string,uint256)","20c5429b":"revoke(uint256)","20c5478f":"RtBCoin()","20c55a8a":"AirDropAFTK5May()","20c58794":"PHN()","20c5b497":"recoverAddressFromBalanceProof(bytes32,bytes32,uint256,bytes32,bytes)","20c5e29a":"increaseDailyTransactionVolumeSending(uint256)","20c726b4":"view_product(uint256)","20c8580f":"getBalanceEthContract()","20c8651b":"makeFee()","20c90167":"distributeCDD(address[],uint256,uint256)","20c93c62":"trackFee(uint256)","20c9d73c":"validCountryId(uint256)","20c9f377":"OneUpToken(address)","20ca0418":"getEscrowById(uint256)","20ca292e":"AUFBToken()","20cad613":"isVersionLogic(address,bytes32)","20caea39":"surprisePanda()","20cb27fb":"requireWhitelistingBeforeDeposit()","20cb7bce":"takeFee(address,address,uint256)","20cc6889":"getAvatarByNickname(string)","20cc7b4e":"changeToken(address,address)","20cd2141":"advisorLockUp_address()","20ce4c66":"getInteractive()","20ceb1bb":"SetCoinManager(address)","20ceb536":"grantToSetUnpausedWallet(address,bool)","20cf3e1f":"maintenance_mode()","20d00018":"jackpotTime()","20d01a7f":"ContestClosed(uint256,address[],address[])","20d0c13c":"getStatusModerator(address)","20d19181":"crowdsaleEndedBlock()","20d3a0b4":"unlockPeriod()","20d3fc20":"totalSeedStage()","20d615c2":"testControlTransferDisableNotEnabled()","20d71dad":"_repopTransaction(address,uint256,uint256)","20d76113":"admin_tokenBurn(uint256)","20d786b5":"withdrawalCounter()","20d7d367":"allowRegistryUpdate()","20d7d860":"ahmadToken(uint256)","20d8741f":"Feed()","20d8dad0":"checkWhitelisted(address)","20d95f90":"removeInt256(bytes32)","20d9822e":"setAnyoneCanCall(address,string,bool)","20d9a9e2":"getChallengeType(uint64,uint256)","20db0c7e":"B21Token(address,address,address,address,address)","20db31d6":"totalFortunes()","20db91e2":"createPartner(address,uint256,uint256,uint256)","20dc3d06":"bpLockUp(address)","20dc407a":"creditOwner()","20dc4677":"minPublicContribAmount()","20dcce99":"PRE_CROWDSALE_CAP()","20dce978":"setExchanger(address,address)","20dd60f5":"setEnvelopeType(uint256,uint256[2])","20df7f35":"DATE_TOKENS_UNLOCKED()","20dfcd27":"purchaseCountry(uint256)","20dffb08":"testCancelSellOrder()","20e07e7f":"changeCardCost(uint256)","20e0dc9f":"RTCoin(string,string,uint8)","20e1063e":"toekensForBTCandBonus()","20e12a43":"createRound(bytes32,bytes32)","20e25965":"timestampRelease()","20e33b13":"GoodBit()","20e3dbd4":"setConfig(address)","20e537c7":"isTransactionAlreadySettled(address,bytes32)","20e561f3":"BecomePharaoh(uint256)","20e57371":"ownerVault()","20e59116":"startChampionGame()","20e62bbc":"StreamityEscrow()","20e647e1":"checkBetColor(uint8,address,bytes32,bytes32)","20e65a42":"stakeForAirdrop(address,uint256,bytes)","20e6a2cb":"getStrField1()","20e6e921":"transfer(address,uint8)","20e76d31":"_solveGame(uint256,uint256,uint256)","20e87093":"getDSTSymbolBytes()","20e89790":"POWR()","20e979b1":"assignBank(address)","20e98bf4":"setNick(string)","20e9aac3":"playerTimestamp(address)","20ea2533":"authorizePayment(string,bytes32,address,uint256,uint256)","20ea31f8":"giveTo(uint256,address)","20ea8d86":"revokeConfirmation(uint256)","20eb2a87":"setContract(address,address,address,address,address)","20eb6dec":"frozenControl(address,uint256,uint256)","20eba3f2":"gamesLength()","20ec0f01":"lastBlock_v12Hash_uint256()","20ec75c2":"searchStartIndex()","20ed1a52":"badge(address,address,uint8)","20ed9451":"set_active_contract()","20edae5a":"createChallenge(uint256,string,uint256)","20ee0c94":"setUrl(bytes32)","20ee5445":"addToPrivileged(address)","20eea675":"ESOPOffered(address,address,uint32,uint32)","20eeba1f":"testConstructorUsingNewContract()","20ef57ed":"bumpCounter(uint256)","20f067a8":"PRETDESupply()","20f06c9b":"start_LOCKUP(uint256)","20f0751d":"turnOn(address)","20f0c28f":"MainContract(string,address,address,string)","20f0db91":"VerifCert(uint32,bool,bytes,bytes)","20f10ae7":"_supportsERC165Interface(address,bytes4)","20f10fdd":"tokenSupplyLimit()","20f1895c":"fechVoteSumNumForCandidate(address)","20f1d85b":"removeApprovedAddress(address)","20f317fb":"districtContractAddress()","20f320d0":"setBonusExtra(address,uint256)","20f361b3":"optionExercise(uint256)","20f3d413":"getTargetBlockNumber()","20f4014a":"ApolTestToken()","20f4914a":"changeMyString(string)","20f4d7aa":"redeemPayout()","20f541fa":"purchaseAsQualifiedPartner()","20f5a0b9":"readTeamByIndex(uint256)","20f5afdf":"OwnershipTransferInitiated(address)","20f5e8dd":"resetBalance()","20f65816":"extractToken(address,address)","20f71018":"Aqo()","20f727e2":"Caller(address)","20f756bd":"getArmySoldiersCount(uint256)","20f801d4":"payout(address,address,uint256)","20f86e9f":"_isBonusAvailable()","20fa6fd9":"ethSendSameValue(address[],uint256)","20fa70b0":"getAvailableWithdrawableCount(address,uint256)","20fb2bc2":"AllowClaimBTC(bool)","20fb36af":"Test8J()","20fb9bad":"LogSortedOffer(uint256)","20fc4881":"getCheckpoint(uint256)","20fcf2e5":"Castor()","20fd8861":"customerWallet()","20fea5cf":"getUserTaskAtIndex(uint256)","20fee8f1":"_timePer()","2100bf7a":"lolaToken()","21015328":"getLLV_edit_28()","21027354":"buyerHistory(address,uint256,uint256)","21029f47":"chickenHunt()","2102df31":"_totalDonations()","2104c2bb":"fundTeamInstant()","2104cdd2":"totalNumberOfScammers()","2104d832":"AddHelenium(address,uint256)","2104ebf1":"executeWithdraw(uint256)","2104fa0b":"skinIdToOwner(uint256)","21059e63":"createProposalAndPublish(bytes32,string)","2105c049":"setCSO(address)","21065f10":"mintInternal(address,address,uint256)","21067b3f":"startRoundWithFirstBet(uint256,uint256,uint256,bytes32)","210790c8":"signWholeConfiguration()","2107a796":"createGame(string,string,uint256,uint256,string,string,string,string,bool,string)","2108292e":"mint_(address,uint256)","210846ae":"is_kyced(address)","21090b31":"_decrementInventory(uint256,uint256)","210970c5":"update_count(uint256)","2109b408":"bitsMask()","2109cf80":"depositEth(address,uint256,bytes)","210a6eec":"sendMultipleAddress(address[],uint256[])","210a854b":"preIcoTokenHoldersAddresses(uint256)","210a8d0e":"changeGranularity(uint256)","210ab6af":"numOfJingles()","210ae4d5":"setTransferDisabled(uint256,bool)","210b7e0b":"tokenAllocation(address,uint256)","210ba961":"demurringFeeOwner()","210bc472":"ownerTokensMinted()","210bd306":"getCurrentHunterLicencePrice()","210c1f29":"closeBoard(uint256)","210c5a56":"_removeMinter(address)","210c5ff6":"getBlockNumber(bytes)","210d14b8":"burnPREICOTokens()","210d2bba":"PRICE_MULTIPLIER_PREICO2()","210dee2f":"setMigrateOut(bool)","210e2484":"icoDiscountPercentageLevel3()","210e734c":"isBoxItemId(uint256)","210e9a34":"getPendingReferals(address)","210f5dda":"createToken(string,string,uint8,uint256)","210fcbf6":"createPromoCutie(uint256,address)","210fd271":"sizeLimit()","210fe93b":"catIndexToAddress(uint256)","2110273d":"addToShareHoldersProfit(string,string)","21105d35":"addressForNonce(uint8)","21106109":"finalRate()","2110a57c":"User(address,bytes32)","2111006f":"create(address,address,bool)","21114904":"balanceOfEther(address)","2111871c":"endPreICOStage2()","2111c0f9":"freezeDeliverMuti(address[],uint256,uint256,uint256,uint256)","2111d1e2":"OnUpdateMessage()","21129137":"saleover()","2112e7fe":"getListGames()","2113342d":"totalDividendPoints()","2113aab4":"BTL_IMMORTAL()","21141c38":"updateInvestorFunds(uint256,uint256,address,uint128)","21141de0":"ReturnEthToEthero()","2114fd0f":"AxpireToken()","2115d328":"getSemiResult(uint256)","2115fd55":"RecievedEther(address,uint256)","21166476":"ARC()","2116b530":"ChangeOwner2(address)","21180138":"isCA(address,address)","21180722":"init(int256)","21187172":"Gate(address)","21188011":"maxIssuedWithAmountBasedBonus()","2119249f":"getNumTokens(uint256)","21194bc0":"devCutPercentage()","211a048a":"getFastestSpaceship()","211a04db":"totalToDistribute()","211a0f39":"ERC20TokenComplete(uint256)","211a1ba8":"changeTokenController()","211b2758":"changeBlockedTimeForInvestedTokens(uint256)","211b4f54":"startUpdate(uint256)","211b72a3":"sub1(uint256,uint256)","211db50d":"allowNewStakes()","211e28b6":"setLocked(bool)","211ed6c1":"freeTransfer()","211f0b93":"getCreateReputationTokenUniverse()","211f0ef9":"SaleOfChametz()","211f390e":"ECO_SYSTEM_HOLDER()","211feec5":"executeEtherDeltaSell(uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,bytes32,uint256)","211ff90c":"SpiceControlled(address)","2120e527":"stakingBonus(uint256,uint256,uint256)","21217668":"getDrawBlockNumberByWinner(uint256)","2121dc75":"isTransferable()","212257de":"changeCap(uint256,uint256,uint256)","2123015e":"test_insert_findWithHintNextIncreased()","2123476b":"startConstitutionPoll(address)","21235083":"cancelSubscription(uint256)","21241e44":"addressOfTokenUsedAsReward3()","2125b65b":"transfer(uint32,address,uint224)","2126a923":"reverse(address,uint256)","2127c30a":"setBlockHash(bytes32)","2127fe90":"addOnStage(address,uint256)","21288400":"lastPurchaseTick()","21289506":"MichaelCoin()","2128a580":"total_claim_codes()","212954dc":"setAddBonus(uint256,uint256)","2129e25a":"finalBalance()","212a6fd3":"CloseEntry()","212a850c":"showMyNumber()","212ac4b5":"UnicornChain()","212ac7d1":"mintNewSpinner(uint256,uint256,uint256)","212bf316":"setCaps(uint256,uint256)","212c3fce":"returnTokensToAirdropper(address)","212c5fea":"close(bool)","212c8157":"disallowTransfers()","212d6723":"payRoyalty()","212e2596":"sellOrderTotal()","212ebbd6":"addTokenLock(address,uint256,uint256)","212f6066":"enableInvestment(address[])","21309ae3":"setTimeBonuses(uint256[],uint256[])","2131c68c":"daoAddress()","2132626f":"_removeByIndex(uint256)","21326768":"finishGame(bytes32)","213294cd":"crowdsaleHasEnded()","2132ce0a":"BASE_AMO_TO_ETH_RATE()","2132eb23":"TreasurerToken()","21335ad5":"getDepositAggregate(address,uint256)","21338d1b":"rewardsWithdrawalProposed()","2133ddeb":"settleBetV1(uint256,uint8)","2133e3b9":"calculatePercentage(uint256,uint256)","213408da":"sendCreatorReward()","2134214b":"getPreorders(bytes32)","21346edd":"savedBalanceToken()","2134927e":"setAuctionParms(uint256,uint256,uint256)","21355869":"getAuctionTimeLimits(bytes32)","2135810e":"curRequestId()","2135d2e4":"lasttokencount()","213671bf":"mainSale_TokenCap()","213681cd":"getRecord(bytes32)","21370942":"updateEthPrice(uint256)","21376d07":"scheduledPayout()","2139c2aa":"setwinnerLimit(uint8)","213a2622":"offerAsSacrificeFromVault()","213a72a7":"LightofGalaxy()","213ac932":"addUser(address,uint256,uint8,bytes32,bytes32)","213ad495":"TimeWeekTwo()","213ae9ec":"newGame(uint256,bytes8,uint256,uint256,string)","213aedb8":"getAllGames(bool,uint256,uint256)","213b9eb8":"setAddr(string,address)","213c3375":"callCustomTokenFallback(address,address,uint256,string,bytes)","213d6771":"editionData(uint256)","213d8f4a":"setCurrentRewardNum(uint256)","213db226":"move(address,address,uint8,uint256)","213e609f":"getTknOfferAmount(uint256)","213e84d3":"maxIssueTokenLimit()","213ea6bb":"donationReceiver()","213f44ab":"getUserAddressList()","213f9ad4":"generateWinners(uint256)","213fe044":"getInstanceAddress(address)","213fe2b7":"getContracts(address)","21420a3d":"_depositTokens(address,uint256)","21424e7d":"ETHcollected()","2142adc9":"changeMargin(uint256)","21435e07":"setTokensWallet(address)","2143da91":"GameOfThrones()","214405fc":"addToWhitelist(address,uint256)","21446cfe":"unitDefense(uint256)","2145465a":"SOUNDBOY()","2145a455":"getRebackRate()","2145e36c":"testBitSetFailIndexOOB()","21462191":"bid3(address,uint8[],uint8[])","21464e71":"inOneYear()","2147783f":"smitToken()","21479265":"addToBlackList(address,address)","21484786":"notificationFee()","21486833":"maxRewardUnitsAvailable()","21491e82":"secondCurrentAmount()","214958ba":"BLOCKCURRICO()","214962d1":"identifierHash(string)","21499737":"setIco2Tokens(uint256)","2149c619":"functionThree(uint256,uint256,uint256,uint256)","214af6b9":"acceptTokensFromUsers(address,uint256)","214b146f":"storeName(uint256,string)","214bb60f":"finalised()","214c2a4b":"getServiceURI(address)","214c9d50":"WritedrawStatus()","214cdb80":"registerInterface(bytes4)","214dda84":"regularPhase()","214e52ca":"transferAllowed(address,address)","214e5f3a":"setForwardUpdateFeesTo(address)","214e8a47":"getSingleLocker(address)","214f71fe":"tokenFulfillmentDeposit(address[2],uint256,uint256[7],uint8,bytes32[2])","2150097f":"timerInfo()","2150c518":"getKeys()","2150c75d":"newItem(uint256,string,uint256)","2150cd56":"setRateAdmin(address)","2151f9a0":"TCT(string)","21520c5f":"calculatePayout(uint8,bool,uint256)","2152b483":"OWN_SmartContract_Allowed(address,bool)","2152c649":"LOVEYOUToken()","2152ebac":"getContributionAmount(uint256)","21537caf":"setRequiredBlockQueueTime(uint256)","21538acb":"approveCallGas()","2153bade":"ZJZJToken()","2153bf23":"x3Token()","21542702":"MakeBet(address,uint256)","215458b0":"salvageNotAllowedTokensSentToContract(address,uint256)","2154dc39":"maxMintable()","21554dca":"GetCurrentBonusStageTokenBalance()","2155af2f":"execute(address,uint256,bytes1[])","2156a96c":"getTotalSales()","2157320e":"votedAddress()","21575889":"distributionSupply()","2157ab24":"GetBankerRound(uint8)","21592a2b":"YaoMaoCoin(uint256,string,uint8,string)","21594110":"createProductionUnit1Beta()","215a3bcc":"setStatus(bytes32)","215a4862":"eligibleForBonus(uint256,address)","215a6ce4":"createBet(uint64,uint256)","215ac4be":"fillContract()","215ae66d":"mintForWebsites(address[],uint256[])","215afc5f":"totalTokenDistribution()","215b3e32":"fromBytes(bytes)","215b5411":"purchaseCallbackOnAccept(uint256,address[],uint256[])","215bad32":"TPTTransfer()","215bd303":"createWorkerPool(string,uint256,uint256,uint256,address)","215bf604":"addFreelancerFeedback(address,uint256,address,string,uint8)","215cb8df":"createIlliquidToken(address,uint256)","215cc031":"getAvatarByAddress(address)","215d6b61":"getTierOfMember(address)","215d902c":"extractString(bytes,uint8,uint256)","215de48a":"getParentCount(bytes32)","215de791":"getTankName(uint32)","215e25ea":"upgradeReferrer()","215f1cd1":"oraclizeSetWinner(uint256,uint256)","215f865e":"resetDropAddress(address)","215fce93":"changeExchangeRate(uint256)","216093aa":"getIsThirdPhase()","21614f62":"randomSkinAppearance()","2161d0e9":"tokensToP3D_(uint256)","21627dad":"getCart()","2163d49a":"lockedCore()","2163ef1a":"GangnamTokene(address,address)","216481d6":"icocontract()","21650145":"Revoked(bool)","2165e1aa":"withdrawRemainingBalanceForManualRecovery()","2165fef9":"allocateStrategicTokens()","21667940":"issueTokenAndApprove(uint256,address)","21670f22":"reward(address,uint256)","216716af":"ExoMiniumToken(address,address)","21687444":"newDAO(address)","2168c988":"transferToInternalLedger(uint256,bytes32)","2168ca06":"numberOfIndex()","216903f9":"confirmTx(bytes32)","216974cc":"refundNonCompliant(address)","216986b0":"entradaJugador(uint256)","216a5543":"getAllForSaleStatus()","216aa0ba":"proposalBlock()","216be181":"hodls(uint256)","216c1606":"_claimExistingCard(uint256,address)","216ced43":"setPenaltyDisbursal(address)","216d93d6":"pricers(uint256)","216de17a":"priceStage1()","216e2a97":"totalOrder()","216e3449":"changeToken(string,string)","216ea239":"miningResolve(uint256,uint256)","216ea5ec":"remainder(uint256,uint256)","216ec69b":"getColour()","216ecfa7":"Tbaol()","216ef940":"proxyUpgrade(address,address,bytes)","2170ebf7":"makerWithdrawEther(uint256)","2171454a":"bountiesKey(uint256)","2171526e":"Chewbaka()","21717ebf":"siringAuction()","2171dc73":"buyXaddr(address,address,uint256,string)","2172ac5a":"_requestExistsReverse(address,address)","217311ac":"getWords(uint64)","21733f6a":"sendDv(string)","2173a10f":"INITIAL_POLL_NONCE()","21745c15":"numberOfSales()","217477f6":"ICO_PERCENTAGE_3()","2174b88f":"transferBanker(address)","2174dcec":"ConfigPromoter(uint256)","21751df9":"BugBountyOne()","21752974":"compromiseContract()","21765510":"getLockedAvailable(address,string)","21765d23":"addLockedTime(address,uint256,uint256,uint256)","217720d7":"getHeldCoin(address,address)","21774f4b":"CUSTOMER_PERCENTAGE()","2177885d":"isOnAuction(uint40)","2177a36f":"getCountProof()","2178139d":"acceptAbstractToken_(uint256)","21795635":"TOTOAirdrop(address,address)","217987ad":"delBlackList(address)","2179f0f7":"EtherToken()","217aab68":"_updateCommission(uint256)","217ad35a":"minimalEther()","217af162":"whitelistKyberAddress(address)","217b97e4":"hatchMaxTime()","217bd046":"computePoolAmount()","217cab2b":"GetWhitelist(uint256)","217d9bbe":"depositExit(uint256,bytes)","217db8e8":"toBase(uint256,uint256,bytes8)","217f2d23":"CRVToken()","217fe6c6":"hasRole(address,string)","21815a1a":"updateHolderShareInfo(uint256)","21819e5c":"computeArtistTxFee(bytes32,uint256)","2181c11f":"batchNewAuctions(uint128[],uint256[],uint256[])","2182e6d8":"buy_lovelock(bytes32,string,string,string,uint256)","2182ebbf":"use(address,uint256,uint256,uint256,uint256,uint256,string)","2182f7b4":"MINIMUM_PURCHASE()","2182ff7e":"sellMNC(uint256)","21835af6":"__dig(uint256)","2183e390":"setTotle(address)","21842be3":"unlockTransfers()","218444ab":"Test2()","21844b08":"drWinChances(uint256)","21848580":"lastBlock_a14()","2184f977":"TRANSITION_WINDOW()","2184fe2c":"transferTechSupport(address)","2185072f":"SerpenSegmentCount()","21853009":"participantRoundRewarded(address,address,uint256)","21856b36":"interestOwed()","2185810b":"allowTransfers()","21858521":"tickets()","21860a05":"airdrop(address)","21861cce":"AUDITED_AND_APPROVED()","2187a833":"setGreenToken()","2187bdca":"getAllETH(address)","21887c3d":"has(address)","21895086":"RL(uint256,string,string,bool)","218a51e8":"UnFrozenTokenEvent(address,uint256)","218a7667":"addToBalances(address,uint256)","218a9640":"setTeamStatus(bool,uint256)","218bc5ec":"createBid(uint256,address,bytes32,bytes32,uint256,uint256)","218bd577":"enterGame()","218cd7a1":"POOPOO()","218d5637":"realSupplyWeight()","218d6ca2":"calcPurchase(uint256,uint256)","218d984b":"registryProxy()","218dd3dd":"checkIdentity(bytes32)","218e4562":"updateBalanceOf(uint256)","218e4a15":"getCooldown()","218e6877":"setDelegate(bool)","218e767d":"TokenFactory(address,address)","218eee82":"addAd(uint32,uint32,string,string,uint256)","218fbdec":"callWithdraw(address)","218fd1c4":"CompanyName()","218fe479":"generateRenown()","218ffb4c":"Fund(address,bytes32,address,uint256,uint256,address,address,address,address[],address[])","21901fa8":"WithdrawFunds(address,uint256)","219047f7":"MasternodeRewardSend(uint256)","2191207a":"setTAOFactoryAddress(address)","21914e29":"day2Start()","2191f4a9":"storjPrice()","219285d2":"presaleClosedManually()","2192b99d":"mintContributors(address[])","219356bc":"GxConstants()","21937192":"finishedSTOMinting()","21938610":"set0xExchange(address)","2193cdba":"send_all()","2194f3a2":"fundsWallet()","21956036":"SmartRouletteDividend()","2195845f":"withdrawAltcoinTokens(address)","21958a50":"AddressSeries(address)","2196ae0d":"hint(bytes32,string,bytes20)","2196feac":"createMarketItem(bytes16,bytes16[],bytes16[],uint256[])","2197021b":"proxyVotingContract()","21970c0c":"pay_royalty()","21974a74":"EtherNetworkConfig()","21978e58":"_removeSale(uint256)","2197b236":"Goldjunge()","21981514":"totalUnclaimedBidsAmount()","219862d0":"marketKebabs()","2198e780":"addDollarAmount(address,int160)","21998504":"setCompte_7(string)","2199d5cd":"registerUser(address)","219a6ead":"MICRO_DOLLARS_PER_BNTY_PRESALE()","219a6f04":"getFounderMember(uint256)","219bc76c":"currentRoundInitialized()","219c7ad1":"getwinningaddress10()","219caaa9":"reclaimChildOwnership(address)","219d0ece":"transferAdminship2(address)","219da4ac":"ResumeTokenContract()","219dabeb":"registerDeposit(address,uint256)","219dc688":"technicalPercent()","219df7ee":"ZTHTKN()","219f5052":"updatePokeMarketAddress(address)","219f72c9":"startICOStage3()","219fd010":"accredited()","21a19b2d":"neverdieSigner()","21a2ad3a":"nextSlasher()","21a2c72d":"BitcoinDublicate()","21a32e5c":"VanityCrowdsale(uint256,uint256,address)","21a33743":"DroidEIP20Token(uint256)","21a33e00":"gasReq()","21a389cc":"PRE_SALE_3WEEK_BONUS()","21a3fb85":"addValidator(address,bool)","21a49ec2":"LCoin()","21a4a5bb":"endDateOfSaleStageLast()","21a4c6c3":"openMarket(address)","21a4cdaf":"HDCToken()","21a5065e":"returnableTokens(address)","21a5c1c3":"buyItem2()","21a5dcfe":"multivestBuy(address,uint256)","21a638d8":"addTerminal(address,uint256,address)","21a6c649":"privatePresaleWallet()","21a6c7aa":"megabossCutPercentage()","21a78f68":"ref()","21a7d652":"EQUIPMENT_REWARD_TOKENS_NUMS()","21a804fc":"SphereToken()","21a83738":"getDragonPriceNo(uint256)","21a8a771":"setPort(uint16)","21a91d2b":"PrcntRate()","21a9cf34":"setTradeAddress(address)","21aa1706":"startPresaleTrading()","21aace42":"setTokenForSP(uint256)","21ab13ab":"maxBet(uint256)","21ab3074":"transferOwnershipOfStorage(address)","21ab561d":"MIN_BID_FRAC_BOT()","21ab7fb4":"marketplace_admin_controller()","21ab9177":"fixPlayerGraphic(uint256,string)","21abf58b":"feesB()","21ac01d8":"ClaimedTokens(address,uint256,uint256,uint256)","21ac5aba":"cityIndexToOwner(uint256)","21ac64af":"declareRCV(string)","21ac8967":"setPatentFee(uint256)","21b12a4b":"clearTransaction()","21b133ed":"icoTotalAmount()","21b1e5f8":"sendETH(address)","21b288d8":"endSecondBonus()","21b36a08":"setFee(uint64,uint256)","21b43777":"advisorCount()","21b48008":"getInvestorsETH(address,address)","21b4b3dc":"proposalsCnt()","21b55c42":"testConcat()","21b5b8dd":"extraBalance()","21b68d2b":"DyginoteToken()","21b6ac62":"lockGate()","21b6c321":"StoreProduct(bytes32,bytes1)","21b6fcbf":"SendFund(uint256,bytes32)","21b8092e":"setWithdrawalAddress(address)","21b8151e":"Mixer()","21b8b11e":"_addToDebtRegister(bytes4,uint256)","21b8d973":"returnHash(address[2],uint256[8])","21b920eb":"upgradeTank(uint32,uint8)","21bacf28":"getDefaultFee()","21bb79fe":"luckyDogInfo()","21bb86ab":"setExchange(uint256,uint256,uint256,uint256)","21bc84fd":"canCompose(string,uint256[],address,uint256)","21bc9a55":"buyTokens(address,address)","21bcc5e5":"multiBatchTransferFrom(uint256[],address[],address[])","21bdb26e":"maxPresaleSupply()","21bded12":"capitalPctBips()","21be2244":"PrivatePlacement(address,address,address,address,address)","21be26ed":"deauthorizeContractById(uint256)","21beba94":"lastTxBlockNum()","21beedf4":"BlocklancerToken()","21c0183e":"centralAdmin()","21c02472":"numberOfResolutions()","21c03a97":"setTradingOpen(bool)","21c0b342":"claim(address,address)","21c0e95d":"setBountyPool(address)","21c17ab8":"unproposeMilestones()","21c24081":"GDC(uint256,string,uint8,string)","21c26195":"distAirdrop(address,uint256)","21c4d650":"priceForBasePart()","21c5fb20":"Deposit_double_sum_paid_from_the_balance(uint256)","21c60ac6":"div(uint8,uint8)","21c60c74":"createMobster(string,uint256,uint256,uint256,string)","21c63a47":"getTicketCount()","21c6b951":"BetherCryptocurrency()","21c6d7b6":"BitbabeToken()","21c87627":"getUnlockedPercentage()","21c87ee8":"setMaxLevel(uint8)","21c882ef":"testGetCaseAtIndex()","21c88358":"anyTokenWithdrawal(address,uint256)","21c9a6b1":"localCheck(uint256,string,bytes32,bytes32,string,bytes32)","21cb1568":"registerArtwork(address,bytes32,uint256,string,string,uint256,address,bool,bool)","21cb18cd":"assignVested(address,uint256,uint64,uint64,uint64,bool)","21cbed35":"setOperationAttributesByRegulator(string,string,uint256,string)","21cda790":"tokensOwned(address)","21cdb03c":"shopShield()","21cde824":"fighterIndexToTeam(uint256)","21ce14a9":"injectTokens(address,uint256)","21cefec0":"tokenBuyRate()","21cf3514":"priceStalePeriod()","21cf5132":"setManualBonus(uint256,bool)","21cf9f22":"updPool(int8,uint256)","21d148ab":"weiForXau()","21d1a303":"checkRemained(uint256)","21d1b7a4":"TJ2()","21d269dc":"fastCashBank()","21d2daa0":"unFreezeToken(uint256)","21d3523c":"voteToHarvestFund()","21d36529":"feePercentage(uint256)","21d365af":"_processVestingRules(address,address)","21d376ce":"tokensOfOwner(bytes32)","21d3d2ee":"isMigrationFinished()","21d41bc2":"IRobo()","21d45bec":"getReverseFee(address,uint256)","21d4b08c":"numTicksTillAuctionStart(uint256)","21d50273":"createParty()","21d53fb9":"withdrawLockupTokens()","21d5c0f6":"finalizeAgent()","21d5cb51":"verifiedUser(bytes32)","21d65d80":"blockPart(uint64,uint64,uint64)","21d67daa":"internalFinishMinting()","21d6cdb6":"newPeriod(uint256)","21d739f1":"TokensIssued(address,uint256)","21d7bdff":"startCountDown()","21d800ec":"relayedMessages(bytes32)","21d80111":"getHero(uint256)","21d8ad4c":"getContractName(uint256)","21d9d5ba":"testRemoveLocked()","21da1719":"impl_unlock4Circulate(address,uint256)","21da94e7":"getSEScore()","21daae34":"getQuoteToBaseReturn(uint256)","21daf0f8":"TransferToReferrer(address,address,uint256,uint256,uint256)","21db06bc":"wolf4Balance()","21db087e":"getLevelCitizenById(uint256,uint256)","21db0f0d":"getImmortalsOnTheBattlefield(address)","21db2aa0":"getArtwork(uint32)","21dc04f4":"Vibranium()","21dc512e":"replaceSSPRegistry(address)","21dc74fa":"addWhiteLister(address,address)","21dcbbae":"HighJackpotHolder()","21de6b01":"setKtcAddress(address,bool)","21df0da7":"getToken()","21df2ea5":"getNewInstance(address)","21df8b9b":"addTotalBondValue(uint256,uint256)","21e01596":"logCall(uint256,uint256,uint256)","21e0f228":"winningNumbers()","21e2933a":"setBasicIncomeLimit(uint256)","21e38e81":"ownerCheck()","21e3cdd0":"voteDn(uint256)","21e5383a":"addBalance(address,uint256)","21e53d77":"_buyTokens(address,address)","21e5d0e4":"PRESALE_START_WEEK2()","21e5e2c4":"shareOf(address)","21e69b42":"dataMerkle(bytes32[],uint256,uint256)","21e6b53d":"transferTokenOwnership(address)","21e76826":"Gamblr()","21e866be":"getCompanyCreationCost()","21e88888":"setColor8(uint256,uint8)","21e92d49":"transferByOwner(address,uint256)","21e96b88":"setProxyManagementCurator(address)","21e9b296":"ExtractedTokens(address,address,uint256)","21ea2b8d":"delayOfICOEND()","21ec0129":"HAUZ()","21ec5981":"Jekyll_Island_Inc()","21ed0f64":"removeEmployee(uint256)","21ed46ad":"Dollars()","21ed47b3":"annualPos()","21edbe24":"pricesAndInventoriesOfDate(uint256,uint256,uint256[],uint256)","21ee102b":"removeExtension(address)","21ee6457":"set_sale_arbits_total(uint256)","21eeb9a7":"LogSaleCapReached(uint256,uint256)","21ef10f0":"revokeSelf()","21ef8368":"DataSentToAnotherContract(address,address,bytes)","21eff7fc":"getContribution(address)","21f032d3":"BitDAOToken()","21f0a727":"node_right_child(uint256)","21f0b382":"unblockClient(address)","21f118a6":"createByCOO(string,uint256,uint256)","21f1a18c":"battleRemove(uint256)","21f1b677":"updateTime(uint256,uint256)","21f222dd":"minWeiAmount()","21f2a9a9":"_getUnlockedTokensPercentage()","21f2ca3b":"unregisterUser(address)","21f2ed2e":"dividendDistributionEndTime()","21f35609":"CAT_FIRST()","21f38c6e":"bundlingEnabled()","21f3f338":"proposalCensorshipFee()","21f3ff41":"maxMultiRolls()","21f408be":"tk()","21f4911a":"addFiveParticipants(address,address,address,address,address)","21f4d29f":"getPoolHistory(uint256)","21f610d3":"endEarlyStage3()","21f6b513":"Airdropper(address,uint256)","21f72d82":"YODCToken()","21f7ac0d":"codeExportCost()","21f8a721":"getAddress(bytes32)","21f8dab6":"THRESHOLD4()","21f9a878":"NewHashnodeTestCoin()","21f9caef":"cancelOrder(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32,address)","21fa1730":"Ballot(string,string,string,uint256,address[],uint256[],uint256[])","21faf403":"getStatusLogCount()","21fb39d4":"WithdrawEvent(address,address,bool,uint256,uint256)","21fb9869":"getAdminLog(uint256)","21fc2cd1":"NounToken()","21fda809":"payment(address,address,uint256,address)","2200919f":"addVersion(string,address)","22009af6":"BASE_REWARD()","2200cdec":"finishPVE(uint256)","22017c5f":"DSTokenBase(uint256)","2202dcad":"FACTOR_7()","22039f89":"isServiceContract(address)","2203ab56":"ABI(bytes32,uint256)","2204ef4b":"getMeTokens(uint256)","22054fe0":"updInvestorEnabled(address,bool)","22057bc7":"getAllRevisionBlockNumbers(bytes20)","2206e837":"undisapprove(uint256)","220772a9":"starUpZero(uint256,uint256,uint256)","2207a93a":"etherInUSD()","22081c12":"processPayment()","22082c72":"getDoneSelfDropAmount(address)","2208ee1d":"_releaseTime()","2209e991":"sendBet(address,uint256)","220a0e36":"LoggedERC20(uint256,string,uint8,string,bool,bool)","220a2247":"givePermission(address,string)","220b4a73":"TCPC()","220c166c":"hatchingSpeed()","220c773a":"changeMarketingRecipient(address)","220d5d8d":"YioCoin()","220d7a7f":"NoteToken(uint256)","220d8707":"BONUS_DAY3_DURATION()","220d9944":"MailHustleCrowdsale()","220e44d0":"_buy(uint256,uint256,address)","220e5d06":"qshdrop(address[],uint256[])","220e693f":"ALLOC_ADVISORS()","220eb9b6":"run(uint256,bytes)","220ee9ec":"purchase_dates(address)","220eeab4":"BonumPreSale(uint256,uint256,address,address,uint256)","220f1202":"lowestAskAddress()","220f1aee":"createVoting(string,string,uint256,bytes32,address)","220f52c5":"whoIsTheOwner()","220f9dfd":"getFighterInfo(uint32,uint32)","220fde2e":"setSellPrice(uint16,uint256)","221067a1":"JULIAN_ALLOCATION()","221086af":"buyerBonus()","2210d525":"getRareAddress()","2210e0f7":"MassPay()","2211218a":"ARMtest()","2211944a":"ActiveAdmin()","2211c3b3":"eraseContribution(address)","22122cb3":"blockTokenFunds(address,uint256)","2212dbc3":"get_timestamp()","22132598":"numArtworks()","221353ca":"finalizeByAdmin()","22137935":"productsExported()","2213c7db":"tokenPreSaleRate()","2214f65d":"toWei(address,address,uint256)","221538f4":"BurnupHoldingCore(address,address)","22156bb2":"WerderCoin(uint256,string,uint8,string)","22159d89":"ticketsOwned(uint256)","2215fc82":"getONETIMESOLD()","2216573d":"internalIncreaseGoldKeyCounter(uint256)","22169ab3":"START_PRESALE_TIMESTAMP()","22174ebf":"TokenSBT()","2217bf78":"getReputationRewards(address,address,bytes32)","2219a95b":"DWBTPreICO(address,address,uint256,uint256,uint256,uint256)","221a66d9":"presaleFee()","221ab8e2":"setBlockResult(uint64,uint64,bytes32)","221b1c4a":"_NumOfStudentsPass()","221b30df":"btcPurchase(address,uint256)","221b5ec2":"setTimeBegin(uint256)","221b5fad":"getCardsCount()","221b850c":"changeInstallerEscrowAddress(address,string,address)","221d4dff":"create(string,uint256,string,string,uint8)","221e5da9":"GetContractStateEarlyTerminatedByTenant()","221e9370":"recordedCoinSupplyForRound(uint256)","221ed3cc":"CONSTELLATION()","221ed748":"shareCycle()","221ef94d":"userMigration(uint256)","222101d1":"vestingMappingSize()","222160c0":"isProposalExecutable(bytes32,uint256,address,bytes)","2221fb3e":"hasActiveBet()","22230fc4":"countFishAtBase()","22239e8e":"loanActivation()","2223a5da":"reserveCap()","2224044c":"calcWeiForTokensAmount(uint256)","22242382":"checkPriceAmount(uint256)","22245b64":"MAXCAP_TOKENS_ICO()","22246200":"deleteElementWithValue(uint256)","22250809":"BoardClaimed(uint256,uint256,address)","222594c5":"findModuleNameByAddress(address)","2226549e":"fixedLog2(uint256)","22284872":"Escrow(address)","22287914":"icoWallet()","2229d348":"attackMonster(uint256)","222a5343":"BOWTERC20()","222a95ee":"LastMsg()","222af991":"stringToUint(int256,string)","222b0d7d":"massRevoke(address[])","222b8947":"depositTokens(bytes32,uint256)","222c1390":"maxPublicSaleStage()","222cfe94":"myEtherBrosCount(address)","222d777a":"createEvent(string,uint256,uint8,uint256,uint256,uint64)","222d7e34":"currentRoundStart()","222f51e9":"getDailyHash()","222f5be0":"transferInternal(address,address,uint256)","22305fb7":"ShowSegmentation(address,uint256,uint256)","2231454f":"updateCampaignManagerContract(address,string)","223162e7":"WithdrawSharedExpense(address,address,uint256,uint256)","2231f72c":"setownership(uint16,uint16)","223208af":"walletName(address)","22326584":"WBE()","2233db62":"InvestorRegistry()","2233dbf4":"wantNewMinter(address)","22347d5b":"confirmTrade(address,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","22351b6b":"VibeToken()","22366844":"isRegistered()","223699c1":"units30percentExtra()","22372795":"HIT()","2237d55c":"setTargetDiscountValue1(uint256)","22384945":"checkPresaleBalance()","22393ef4":"bundleFirstTokens(address,uint256,uint256[])","223964bc":"queryAccounts(address)","2239c48a":"startUpgrade()","2239d43b":"uintMinimalSize(uint256)","2239e688":"getUrlFromKey(bytes32)","223a6399":"newAssociate(address)","223ab941":"transferForProjectTeam(address,uint256)","223b01db":"decimalsETHToUSD()","223b530e":"antiques()","223c217b":"withdrawTokenTo(address,address,uint256)","223c5939":"UnilotBonusTailToken(address)","223cd20e":"shareHolderByAddress(address)","223dad70":"sendMsgSndr(address,address)","223db315":"allow_refunds()","223dcc74":"left14(uint256)","223e5a9d":"pls()","223e97be":"setParent(uint256,uint256)","223e9f17":"_redeemSameClassAdoptedAxies(address,uint8,uint256)","223fcbc9":"_locked()","223ff4cc":"getShipsIds()","224076d4":"pegIsSetup()","22408401":"ArtSale(address,address,uint256,uint256,uint256,uint256,uint8,uint256)","2240b645":"GetClientCategory(address)","22412ded":"MyProducts(address,uint256)","2241a733":"GOLD_AMOUNT_XPER()","22425fa4":"feePeriodDuration()","22427047":"Payout(uint256)","22429085":"updateFees(uint256,uint256,uint256)","2242cf7f":"getConBal()","22434836":"setTimes(uint256,uint256)","2243fb15":"getHashratePerDay(address)","22446093":"editPerson(address,address,string,uint256)","2245675f":"setCustomerSignature(address,uint256)","22471e16":"identityApproved(address)","2247328c":"vote01YesCount()","224846de":"deletePaymentContract(uint8)","224854f7":"Trie()","224993c2":"setTimeBlock(uint256)","224a1775":"transferByOwner(address,uint256,uint256)","224a6ac3":"nextPE()","224a8174":"TESTER()","224a967c":"CTSCoin()","224b4bfd":"TYCOONCoin(uint256,string,string)","224b5c72":"consume(address,uint256)","224bed07":"transferIndexed(address,uint256)","224c1c9b":"getNonVestedBalanceOf(address)","224c4657":"createOrder(address[3],uint256[3])","224ccc49":"chainLastMessageHash(bytes32)","224d5d54":"wylouToken()","224dc278":"dis()","224e5efd":"DNACoin(address,address)","224e7462":"removeToken(bytes32)","224f127d":"LogNewWhitelistedAddress(address,address,uint8)","224f143a":"setme()","22500af0":"OwnershipTransfer(address,address)","22518a75":"getVotersCandidateVote()","2251a8a9":"isSubscribed(address,address,string)","22526635":"payOut(uint256,uint8,uint256)","22529fff":"getReferral(address,address)","2252d5c1":"exemptMeFromFees()","225386fe":"SimpleERC20()","2253fff1":"initialCongress(address)","22542fb6":"collectTokenPhaseStartTime()","225435c0":"detach()","22547931":"registerOperation(uint256,string)","22551da7":"double(address,bytes32,uint8,uint256)","22554f34":"getT()","22555bea":"UNITv2(address)","22556bd7":"createRound(string,bytes32[],uint256)","2255ad10":"RefugeCoin()","225640ab":"getOrCreatePreviousFeeWindow()","225682d1":"test_contractBalance()","2257406e":"getMemory(uint256)","2257defa":"removeCustomerFromBL(address,address)","2259315d":"TokenFactoryCN()","22593300":"Small(address)","2259d221":"LifeSet_005()","225a1d46":"PODH()","225a905f":"NewSubscription(address,address,uint256,uint256)","225b6574":"hasBase(address,uint64)","225c4011":"cyberEntry(address)","225c5567":"withdrawLeftTokens()","225ce00f":"_createAuction(uint256,string)","225cf990":"setAgriChainContext(address)","225cfd59":"addPromille(uint256,uint256)","225da7e5":"transferManagerFactory()","225f406a":"buyInSaturday()","225f9d7d":"stopIt()","225fce8d":"getGameByPlayer(address)","22609373":"calculateEthereumReceived(uint256)","2260b98b":"finalizeVoting()","226187dc":"maxPreICOTokenAmount()","2261c6d9":"AllowedAddressAdded(address)","2262cd94":"wroom()","22636e65":"setContractValue(address,string,uint256)","2263ae04":"POHD31()","2263e8b7":"routingCodes(uint256)","2263f2c5":"createTokens1()","22643a47":"JokerCoin()","226454c1":"getGoldDataDocumentation()","22657697":"priceForStage(uint256)","2265931d":"transferToken(address,uint256,uint8)","2265a94b":"ValyutaTestCoin()","22665bc9":"setICO(address,uint256)","22666da6":"makeGuess(uint256)","226685ee":"Visit()","22673030":"SALE_START()","2267b2e3":"veredictum()","2267b30d":"removeFounder(address)","22686250":"index(int256,uint256)","2268a358":"changeMultisig(address)","226942e6":"RollEvent(address,uint256,uint256,uint256,uint256)","2269d2ec":"addNewPotatoCoinsForSale(uint256)","2269f1c9":"voteA(uint256)","226ac321":"updateTokenRate(address,uint256)","226bf449":"addPackage(string,address)","226d2f86":"keyEmployeeAllocation()","226dd769":"howManyEtherInWeiToChangeSymbolName()","226e2b91":"setPaycarnita(uint256)","226e2d10":"manual()","226ee47c":"set_validator(address)","227185d6":"Send1Get2()","2272b0af":"csoAddress()","2272df67":"changeFounderAddress(address)","2272f879":"walletThree()","227326b1":"proposalPassed()","22734c0c":"createRawDeposit(address,uint256,uint256,uint256)","22742564":"quickConvertPrioritized(address[],uint256,uint256,uint256,uint8,bytes32,bytes32)","2274346b":"vaultContract()","22758a4a":"whitelister()","22760877":"getCurrentHeroOwners()","22763ae1":"stopInEmergency()","22766696":"bidEnd(uint256)","2276774c":"finalizeRemainders()","2277466b":"voteToClose()","22776478":"getDistrict(uint256)","2279295d":"resetPhoenixes()","22798c10":"MANHATTANPROXYACPBLVD()","2279fa4c":"numPayments()","227a7911":"etherGetBase()","227ac0cf":"GetPerSellInfo(uint16)","227ada37":"placeBet(uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","227bf6b8":"ethorseOracle(address,bytes32,string,bool)","227c74a7":"giveEntity(uint256,address)","227cade5":"maximumBet()","227d111e":"GetExistsCardList()","227d3fb4":"checkTxProof(bytes,uint256,bytes,bytes)","227d535f":"Wolk()","227dd788":"isFinal(bytes32[])","227e14e9":"currentDateTime()","227e26c4":"deleteChild(uint256)","227f592c":"TIXGeneration(address,address,address,address,address,uint256,uint256)","227f9633":"addOption(string,address,uint256)","227fb30b":"MosaiCoinContract()","227fda27":"BitcoinSamaritan()","2281411b":"allocateAndFreeze(address,uint256)","22817359":"_transferTokenToOwner()","22824bbd":"checkFind(address,address)","2282d9f2":"transferIsEnabled()","22848a0c":"TCTToken(uint256,string,string)","2284a6fa":"interest(uint8,bool,uint8)","2284b051":"gameRandon1()","2284e8fe":"push_or_update_key(uint256)","22855bf0":"CheckBest(uint256,address,address)","22855ef9":"registerTransfer(address,address,uint256)","22867d78":"repay(address,uint256)","2286b7de":"BONUS_ICO_STAGE1_PRE_SALE2()","2287d2ec":"donealready(uint256,address,bool)","2287dad2":"getTicketByHolderId(bytes32)","2287e96a":"withdrawEnabled()","2288193b":"testFundACampaign()","22888f35":"depositPremium(address[2],uint256[7],uint8,bytes32[2])","2288fad6":"earlyPurchases(uint256)","2289115b":"createPlanet(string,uint256)","228acf2f":"tokenTeam()","228b70d3":"registerNewPubKeyForHash(string,string)","228b7bf8":"Vasacoin()","228bbf45":"getItemsForSale(uint256,uint256)","228bff5a":"secToDays(uint256)","228c2df1":"hodl(address,uint256,uint256,uint256)","228c790c":"RudysToken()","228cb733":"reward()","228cc2aa":"maxQuanValues()","228ce144":"getKingdomType(string)","228d2820":"disableConversions(bool)","228d477f":"tokTakers(uint256,address)","228dff13":"setPepeName(uint256,bytes32)","228e41bd":"getdeptcount(uint256,address)","228e554a":"_refundBond(uint256,address)","228e892e":"icoStages(uint256)","228e92cf":"YuanLianToken()","229063fc":"discoveryCooldown(uint256)","2290d6e2":"entryFee_()","2290db50":"buyEnergy(address,address,uint256)","2290e106":"mintBuyerToken(address,uint256)","22923160":"updateWithdrawals(address,address,uint256,uint256)","229233b6":"FOR_FOUNDER()","22928b4d":"isIpoPeriodOver()","22928d6b":"removeUser(address,address)","22935caa":"setInitialAllocationUnlock(address)","22937ea9":"returnInt256(int256)","229460e7":"AdminstratorRemoved(address)","2294795d":"deuseth()","22949fb1":"TicketBought(address)","2294c48a":"initUsers()","2295115b":"adminWithdraw(address,uint256,address,uint256,uint8,bytes32,bytes32,uint256)","2295ee5b":"updateTokenBaseURI(string)","22968885":"getBalanceOfContract()","22969eac":"changeAuth(address)","22978e57":"unlockedAfter()","229824c4":"calculateTrade(uint256,uint256,uint256)","2298b9ce":"icoOver1()","229906b3":"updateStringSetting(uint256,string,address,string,string)","2299219d":"unlockTemporary(bytes32,address,bytes)","229a336b":"BodyMassIndex()","229a4978":"batFund()","229b04bf":"pauseMode()","229b5223":"weiScale()","229b9bc5":"buildingToUnitCount(uint256)","229cfc32":"calculateViralRewards(uint256)","229ddd9a":"foreignBuy(address,uint256,string)","229df5c6":"getSig(bytes)","229eb105":"payaFinished()","229f3e29":"presaleEnd()","229f4caf":"minBetPrice()","22a036dd":"ico2Bonus()","22a15848":"btcOracle()","22a1ec8f":"setSomething(address[])","22a27f3b":"getDeveloperAddress()","22a3eab5":"withdrawn_balances(bytes32)","22a4381d":"fromTokenDecimals(uint256)","22a47143":"Tokensale(address,address)","22a4993c":"getReferedCount(address)","22a635c4":"Hodl(address)","22a7118d":"buyTokensFor(uint256,address,uint256,bool)","22a7533b":"deathData_a19()","22a7906f":"getOwnedPointAtIndex(address,uint256)","22a7ac34":"rake()","22a7ba2b":"totalSupplyCrowdsale()","22a8fb18":"freezelvlAccount(address,bool)","22a90082":"setInterval(uint256)","22a92c45":"sendTokensToHold()","22a993ca":"getKun()","22aa7196":"refund_window_end_block()","22aab53a":"temperatureRange()","22aacad5":"incCounter()","22aaea91":"setCurrentAuctionId(uint256)","22ab9433":"getPrecomputedEToTheHalfToThe(uint256)","22abb147":"ResolutionAdded(address,uint256,string,string)","22ac5f40":"fulfillEscrow()","22ad3b76":"fiatFee()","22ae634f":"getInvestment(uint256)","22aef13c":"requestChangeRequirement(uint256,string)","22af00fa":"bets(uint256)","22af1b27":"UnpackAccessDChain(bytes)","22af47e3":"tokensIssuedAir()","22b01343":"initializeAssetsToThisApplication()","22b05ed2":"getStatus(string)","22b08180":"purchaseVideoGame(uint256)","22b0e99a":"EARTHToken()","22b0f6ee":"getStatusOfPayout(uint256)","22b11169":"setWalletOwnerAddress(address,address)","22b152a3":"liquidateLosing()","22b19192":"imAlive()","22b1a226":"withdrawPaymentsRegistrar(address,uint256)","22b1f39c":"currentInvoice()","22b263b2":"nextPlayerID()","22b2678a":"hasBalance(address)","22b28aa4":"resetTimes(uint256,uint256)","22b2ea22":"registerHWCDep(string)","22b2f178":"minimumDifficultyThresholdWei()","22b36d88":"stopTde(bool)","22b45ddc":"EarlyBackerDeposit(address,uint256)","22b4891d":"capICO()","22b524fe":"getFreelancer(address,uint256)","22b53192":"arr(bytes32)","22b53b4b":"accruedLiq(address)","22b6fe9e":"getAgreementSetCount()","22b6ffca":"isSignedUp(address)","22b79623":"resetEpocum(address)","22b87601":"testRemovePending()","22b930f7":"VESTING_1_DATE()","22b954f8":"poolFeeRate()","22b96b63":"getIPFSHash(address,bytes32)","22b9b712":"BETTING_OPENS()","22b9bd35":"adjustPrizePoolAfterWin(uint256,uint256)","22bac568":"grantAdditionalShares(address,uint256)","22bae392":"setBenecifiary(address)","22bb06d8":"marketting()","22bb4f53":"retentionMax()","22bbad0b":"instruments(uint256)","22bc0d6c":"appendEncryptedBid(bytes32,uint256)","22bc3b8e":"getArgument(uint256)","22bc98b1":"basicPresaleRate()","22bcabcd":"TOKENS_ACCELERATOR()","22bd6d3f":"hired()","22bdf293":"grantVestedEDEX(address,uint256)","22be9342":"resolve(uint256,uint256,bool)","22beb9b9":"scheduleDoIt(uint256)","22bf1a2a":"addrLockUp()","22bf2e24":"ROLE_STAFF()","22bf9d7c":"slashTranscoder(address,address,uint256,uint256)","22bfba59":"drawRandomUnitWinner()","22bfdcbb":"RaffleStrangeLoop(bytes32)","22c07ad3":"indFutureDeposit()","22c1d0d2":"_withdrawAmount(address,uint256)","22c21e6c":"ZHIHUIGUO()","22c25c50":"Addr7()","22c25d8f":"set_presale_arbits_total(address,uint256)","22c30931":"calculateStep(uint256)","22c4d98f":"hasAllowanceToRecieveTokens(address)","22c4f168":"setTransferFeeProp(uint256)","22c51659":"getWhitelistedZone(address)","22c5b279":"addLayer(address,uint256,bytes32)","22c61e73":"createContractPoo(string)","22c66ae7":"decimal_precission_difference_factor()","22c69b15":"tradeDAI(uint256,uint256)","22c6aad9":"pigcoin(uint256,string,string)","22c6ae15":"mul(uint64,uint64)","22c83245":"clearBlackAccount(address)","22c9427e":"recycleDividend(uint256)","22cacd6b":"setUSDBtc(uint256)","22cb1ec8":"teamTokensMinted()","22ccd000":"Blocksale(uint256,string,uint8,string)","22cd5ea8":"claimBet(bytes32)","22ce1f8f":"VixcoreToken2(uint256,string,string)","22ce61b2":"globalMetSupply()","22ce9bac":"numberOfVotesCast()","22ced0bd":"BTrustToken()","22cf1745":"USTToken(address,string,string,uint8)","22cf5011":"privilegedTransfer(address,uint256,bytes)","22cf981d":"proposeMintLocked(address,uint256)","22cfadc7":"isFundingNow()","22d0d31f":"OD1Coin(uint256)","22d122a9":"MyTestWallet7()","22d1bd32":"currentlyActive(bool)","22d2cfac":"getNextElement(uint256)","22d310f9":"setMarket2(address)","22d34212":"get_eth()","22d40b96":"defcon()","22d4e0fd":"pay2(address,uint256,address)","22d60d17":"tokensPerWei()","22d6eb87":"getInfo2(address,address,uint256)","22d7642e":"getScene(uint256)","22d85334":"isValidBicoinAddressPrefix(bytes)","22d8c8a8":"AddMaterial(address,uint256,uint256)","22d8cf5b":"CheckUserVote(uint8,uint8)","22d9f13e":"changeCUSD(address)","22da10b0":"checkPermissions(address)","22da3368":"IoMTToken()","22da5d04":"tokenCreationMaxPreICO()","22db2f7b":"processOffchainPayment(address,uint256)","22db4143":"BONUS_THRESHOLD()","22db61ab":"setunitDefenseMultiplier(address,address,uint256,uint256,bool)","22dbaf75":"test_oneInvalidEqBytes32()","22dbd0e4":"payComisionSponsor(address)","22dbf6d2":"reserveFeeToWallet(address,address)","22dc36e2":"processed(uint64)","22dc5a85":"ERC20address()","22dc8e71":"setIV_R1(uint256)","22dce86c":"getEscuelas()","22dd0d2c":"TEAM_KEEPING()","22dd9b8c":"templateSupply()","22ddde5b":"getLRCAmount(address)","22dde4cd":"secToNextMiningInterval()","22de2457":"clientVerifyKeyHash(bytes32,bytes32,bytes32,bytes32)","22df1caf":"grantPresaleTokens(address[],uint256[])","22e01192":"setPrice(string,uint256)","22e02b22":"ClaimEth()","22e113a3":"freezeTokens(address,bool,uint256)","22e12720":"MAX_HOLDERS()","22e256e2":"Addr5()","22e2b31f":"unlockAmount(address,uint256)","22e37189":"tklosses()","22e3989b":"multNumerator()","22e412ce":"strikePut()","22e465ee":"tolerantSub(uint256,uint256)","22e58557":"getFreeEggs()","22e5aa3a":"totalProportion()","22e62038":"close_bank()","22e63356":"setValueAgent(address)","22e67e71":"maxTime()","22e6f1d0":"giveGoldenTicket(address)","22e77ff3":"plz(address)","22e78480":"getGoldDataSku()","22e803c2":"transferBounty()","22e84682":"isValidContributorAddress(address,address)","22e8571d":"legalsAddress()","22e8c87d":"getUserData()","22e8c8fc":"gamble(uint256,uint256)","22e8df23":"ICO_MINIMUM_CONTRIBUTION()","22e91248":"getLeaf(uint256)","22e95f6c":"payout_normalizer()","22e9afca":"cofoundersSupplyVestingTranches()","22ea2231":"purchaseTokens(address,uint256)","22ea2d96":"getBookInfo()","22eb2c02":"viewPreSaleRefunds(address)","22ebb3ac":"DieselPricePeg()","22ebc4a0":"fpartSigned(int256)","22ec1244":"shaBid(bytes32,address,uint256,bytes32)","22ed6302":"setCrowdsale(address,uint256)","22ed96a0":"getInvestorsFee()","22ee1db4":"uint32At(uint32,bytes,uint256)","22ee46db":"VapeToken()","22ef83ef":"AuthInit(address)","22efee2d":"get_participant_num_of_pro_rata_tokens_alloted(address)","22f0e6ae":"MarketingMethodAddress()","22f0f2f9":"unlockContract()","22f16c8d":"checkDividends(address)","22f256f8":"buyIOD()","22f2f89a":"allOperationsCount()","22f3e2d4":"isActive()","22f43bb5":"seedGame()","22f4596f":"_maxSupply()","22f48627":"SIACASHCOIN()","22f4afb5":"relayKingContract()","22f4e916":"GdprCrowdsale(uint256,uint256,address)","22f607f6":"Escrow()","22f6af6e":"TokensBought(address,uint256,uint256,uint256)","22f6fa7a":"contractorTransfer_Bcoupon(address,uint256)","22f709dd":"getEther(address,address)","22f77d2a":"Refundable()","22f7be85":"setFlight(uint16,uint16,uint256,uint256)","22f7d1f8":"normalFunc()","22f85eaa":"buyOrder(uint256)","22f872a7":"allocateBounty()","22f8a2b8":"getDayOfWeek(uint256)","22f905ec":"GetPartNum(uint8)","22f93f16":"updatingViaOracle(string)","22fa1ff4":"MAX_PROMO_GIRLS()","22fa85ca":"testFailRegisterContractAgain()","22faa5db":"removeURL(string,uint256)","22faf03a":"setInstructor(string,uint256)","22fb5303":"_transferFromWithReference(address,address,uint256,string,address)","22fb71f1":"getGoldStatusVendorverify(address)","22fb730b":"claimerOfTwitterId(uint256)","22fbde38":"qtdePokemons(address)","22fbf1e8":"addDeveloper(address)","22fc3149":"setWhitelistThresholdBalanceInternal(uint256)","22fec5e7":"VEToken()","22fefe31":"devuelvePuntuaciones(bytes32)","22ff1110":"CancelSellOrder(bytes32,address,uint256,uint256,address)","22ff79d8":"USA()","23017a3a":"rewardVaultContract()","2301e7b7":"isInPreSaleState()","23020be5":"SetfirstTTax(uint256)","23023aa4":"_doCatchFish(uint16,uint16,bytes32)","23024408":"fund(address)","2302c948":"EtherDank()","2303084b":"hasTransfers(address)","23037a85":"setNextPrice(uint256)","23040327":"oraclize_query(string,bytes[4])","230434d2":"Technology5GCrowdsale(uint256,address,address)","2304ede4":"ADSToken(address,address)","230614fb":"batchTransferToken(address[])","23063da2":"Hellina()","230662f8":"changeSaleManager(address,address)","23087c04":"_isWinnerOf(address,address,address)","230894f8":"transferTileFromOwner(uint16,address)","2308a41c":"amountRaisedBy(uint256)","23098a9a":"burnAssessor(address)","230a1074":"getRegionCurrentImageId(uint256)","230a14c0":"RISK_LEVEL()","230a3c05":"constructWeaponTokenId(uint256,uint256,uint256)","230a8020":"getAddressValue(uint256)","230b1eb5":"totalReservedTokenAllocation()","230b9667":"getProviderInfoFields(uint256)","230b9da3":"parentContract()","230bd25d":"requestBounty()","230c50fe":"AuthorizePayments(bool)","230c96b9":"BuyTokensWithAffiliate(address)","230cf412":"test(uint256,int256,uint256,uint256,uint256)","230d3469":"canExchangeNum()","230d6ed8":"addCandidate(bytes32)","230dff66":"theclub()","230f49d9":"buy_token(address[])","230f6e83":"getCrydrViewStandardNameHash()","2310b384":"finalizeStake()","2311542e":"SSOrgToken(string,string,uint256)","2311bdb2":"isForgiven(string)","2311d39c":"dot()","2311dc0b":"postProduct(bytes32,bytes32,bytes1)","2311e345":"SaleFinalized(address,uint256)","23133115":"changeIncreaseStep(uint256)","23141fd0":"sendP(address,uint256)","23145ca0":"forceCheck()","23146c20":"getBuyerAddressPayment(address,uint256)","2314a5c8":"getReput(address)","2314aad6":"setExtensions(address)","2315550e":"add(address[],uint256[])","23158cae":"addBet(uint256,uint256)","23165b75":"acceptBidForPunk(uint256,uint256)","23169ec4":"medalName()","23169fca":"EDU_PER_ETH_EARLY_PRE_SALE()","2316d0cd":"deathData_a16()","2317880c":"requestArbitration(bytes32)","2317c28e":"mediaTokenIndex(uint256)","2317cd54":"_endRound()","2317ef67":"removeAsset(address,uint256)","2317f9f3":"setSanMaxAmount(uint256)","2318ffc7":"setRokBalance(address,uint256)","23191bf1":"finalizeByArbitrator(bytes32,bytes32)","231944e2":"moveUnits(uint256,uint256,uint256[])","23198b98":"setTokenHolderTribunal(address)","231a00cc":"changeBonusRate(uint256)","231a2be3":"minimumContributionPhase6()","231a439e":"setBlacklistDestroyer(address)","231ace68":"MiningRewardPerETHBlock()","231b0268":"firstBlock()","231b48aa":"settingsSetWeiPerMinToken(uint256)","231c1ce8":"unusedMethod(address)","231c1d43":"generate(uint256,string)","231cb6ab":"ENS_SUB_APP_NAME()","231d87e1":"competitorTeam(uint256)","231da56e":"getSenderValue()","231e0750":"register(bytes32,bytes32,bytes32,bytes32)","231e18a9":"pureFunc()","231fa805":"IsControledAddress(address)","23210c1a":"StfuToken()","23214fab":"maxProfitAsPercentOfHouse()","2321e625":"publicSaleSencPerMEth()","23221f1e":"getNbVersions(string,string)","2322f484":"balancesQuantity()","232397e2":"addAccount(uint256,uint16,bytes32,uint256)","2323a00e":"WagaToken()","23240d81":"getDailyTransactionVolumeReceiving()","23245216":"removeWhitelist(address[])","2324c67c":"getAllSignatureHashes(bytes4)","232523e8":"forceDivestOfAllInvestors()","23260a8b":"getPreviousPrice(bytes10)","23262615":"claimVaultOwnership()","23266dfe":"getOrganizersAddresses()","2326df93":"site_url()","2326ef22":"CreateDMSContract(address,bytes32,uint32)","2326faf9":"getResearchPerDay(address)","23285480":"RefundDeposit(address,uint256)","2329b4f7":"CryptDash()","232a2c1d":"executeSignatures(uint8[],bytes32[],bytes32[],bytes)","232a3060":"setFundManager(address)","232a6b9d":"signed()","232c4d24":"sub_fCode(string,uint256)","232c6bab":"delIndividualCertificate(string,bytes32)","232cae0b":"last_offer_id()","232db034":"abortFunding()","232e57c1":"optionSupply()","232e7e91":"getproduct(uint256,uint256)","232e9051":"gunsFund()","232fd216":"getPoolDone(uint256)","233023de":"setCertifierInfo(address,bool,string)","23306ed6":"getMinimumBond()","2330f247":"isAuthority(address)","233104d6":"setPresidenteDeMesa(bytes32)","233120aa":"getChainyURL()","2331af61":"transferActive()","23338b88":"delMinter(address)","23343af3":"setConfigAddress(address,address)","2334623f":"totalETM()","23350e4a":"regainEther()","23355749":"IkokoToken()","2335d307":"IFSActive(address,uint256,uint256)","2337d9f1":"endOfferingImpl()","23385089":"emitApprove(address,address,uint256)","23389c5a":"docs(uint256)","2338c002":"_applyShare(address,address,uint256)","233907a3":"signedApproveAndCallSig()","23394e46":"TripAlly()","2339dd43":"HcftSale(address,address)","233a04ec":"setEditionSales(uint8,uint256)","233a74c9":"currentTokenDistribution()","233aacf9":"Announce_winner(address,address,uint256)","233ab10d":"setBaseEthCapPerAddress(uint256)","233b39c9":"_initCardDetails(uint8,uint256)","233b7451":"lastStakedFor(address)","233bf71e":"FOCToken()","233d264a":"startTicker()","233de126":"odds()","233dedf1":"averageBlockTime()","233e0877":"Purchase(address)","233e3220":"renounceSuperInvestor()","233e5d00":"WorldStage()","233ff4b2":"_fund(uint256)","23400cf6":"getLOCCount()","2340903d":"EEZcoin(address)","23412ede":"StorageEnabled(bool)","2341a1af":"receivePlayerInfo(uint256,address,bytes32,uint256,uint8)","2341d778":"giveTix(uint256,address)","2342293d":"collectionFees()","23437d50":"discountICO()","23447982":"replaceManager(address)","2344acdf":"pauseOffset()","2344b0e5":"url_white_paper()","2344e4ec":"getHint(uint256)","23452b9c":"cancelOwnershipTransfer()","2345fe81":"xperToken()","234638df":"PreICOHardcap()","23471d18":"setStakeAddress(address)","2348238c":"transferPrimary(address)","23483e45":"delRosenCertAdmin(address)","2348f1ee":"lockAttemp()","234917d4":"getCallTargetBlock(bytes32)","2349748d":"MenoroCashSupply()","2349e719":"processStepsByStep(uint256,uint256)","234a0ee7":"appHub()","234a6ed8":"initializeToken(address)","234ae1a0":"WallDirectory()","234b2cb4":"whitelistApplication(string)","234c0ae5":"combine(uint256[],uint256)","234c4bd9":"deployStepThree()","234e0056":"COIN_SUPPLY_ICO_PHASE_1()","234e5273":"tittyContract()","234e5f16":"TIMETHRESHOLD()","234ea19c":"lockRate()","234f1eb6":"JVToken(address,address,address,uint256)","234f9db2":"getBalanceIco()","235029ee":"SQT()","23509e69":"donkeysEligibleForFees()","2350e762":"participantWithdrawIfMinimumFundingNotReached(uint256)","2351299a":"createTokensToOwner(uint256)","2351baca":"fechVoteNum(address)","2351c2f8":"get_tokenReward()","2352551f":"bbPublicSaleWallet()","23525826":"maxNumbPerSubscr()","23526a34":"turnOffSale()","235304b2":"updateNextGameInitalMinBetSize(uint256)","23533138":"seedMarket(uint256,uint256)","23537880":"TestSale()","23539cd4":"mintResource(uint16,uint256)","235422fb":"_medalUnFreeze()","23548b8b":"maxCap()","2354b3ed":"requestSatsPrice(string)","2354bda7":"auditGuess(uint256,string,uint8,uint256,uint8,uint256)","2354ecf7":"balanceOfOnUpdate(bool)","2355300f":"unspentCreditsWithdrawn()","2355c602":"queryToAddress(bytes32)","2356f46a":"Kontlo()","23571ac9":"seenHereA(uint256)","2357cd3b":"invadeAddress()","23584a21":"initStats(string,address,uint256)","23586685":"recordSale(uint256,uint256)","23587733":"DEVELOPER_BONUS()","2359116d":"refill(address,uint256,string)","23594797":"createContractRegion(string)","235977ca":"ParadiseTokenSale(address,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","2359bd08":"reinvestTokens(address)","235b1eb7":"getOverRate(uint8)","235bd895":"_getGameInfoPart1(address,uint256)","235c002d":"transferOther(address,address,uint256)","235c279f":"addEmitter(address)","235c9603":"getNextTranscoderInPool(address)","235e5d47":"isRoundEnd(uint32)","2360f5a1":"openSaleSupply()","2362189a":"defaultExchangeRate()","23624a10":"tokenFee(uint256)","23626067":"thirdCheckpointPrice()","23626df7":"setContractAddress(address,address)","2362b26d":"Awards(uint256)","23637e60":"votePrice(uint256,bool)","23647398":"testThrowRetractNotOwner()","23655d7b":"Fantom()","236571e2":"determineWinnerEven(string)","2365ceb3":"SetWagerData(bytes32,bytes15)","2367e1ae":"getLengthOfMatches()","2367f35d":"crowdsaleEnded()","23685b97":"bpToken()","2368d215":"multipleAddToWhitelist(address[])","236a160e":"isValidIssuance(uint256,uint256,uint256,uint256)","236a8d9d":"registerNode(uint256,uint256)","236ae025":"distributionThreshold()","236be3e2":"BlockcloudToken()","236dd0e8":"paidBidAllocationFee(bytes32)","236e06f6":"exchange(address,uint256,uint256)","236e1a15":"PromotionCoinMintFinished()","236ebbae":"setAuditNodePrice(uint256)","236ed5a6":"getVoterProposalsCount(address)","236ed8f3":"closeAuction(uint256)","236f86a1":"remainingTokens(address)","236ffad4":"initOwned(address)","237032da":"isBacker()","237082bd":"getCertifiedDocCount(address)","2371bb4b":"SetNumber(uint64)","23724ffd":"TransferManagerApproved(address)","237297a4":"claimWinner()","2372996a":"CUSTOM_ERC20_CREATE_SERVICE_NAME()","23732ad8":"OSTestToken()","2373f091":"_setMinter(address)","23749f69":"donationsEndedTime()","23751e95":"addRedbullQuest(address)","237548fa":"seriesFactory()","2375766a":"unlatchContract()","2375da83":"setIntArr(uint256,address)","2376fe70":"approveProxy(address,address,uint256)","23773f81":"calcTapAmount()","2378fe2d":"FAPFundDeposit2()","23797ed9":"getAppByIndex(uint256)","237a35b2":"professionalName()","237a4a7f":"requestOneUUID(address,uint256)","237b5e96":"child()","237c2b22":"MCTCrowdsale(uint256,uint256,uint256)","237d2628":"issueTokens(address,uint256,uint8)","237e9492":"executeProposal(uint256,bytes)","237f142a":"ownersLen()","237f1a21":"hasIdentity(address)","23807da8":"getInvoicingAddressCount(string)","2380c39d":"backUtcoinOwner()","2382534a":"STR()","2383b074":"getSurplus()","23845e4b":"getPoolSize()","2384c058":"account3()","23855c18":"updateDeposit(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","23855cd3":"setBalanceForUser(bytes32,uint256)","23858314":"sizeOfProviders()","238604f0":"SuperContract()","23866438":"joinChannel(bytes32,uint256[2])","23867979":"getHealBalance()","2386d33e":"_tenuousToken()","2387c87d":"setTokensSold(uint256)","2387e75e":"RequestBitcoinNodesValidation(address,address)","23898138":"MoneyCoin()","2389a290":"joinGame(address)","238a3fe1":"transferDistribution(address,uint256)","238ac933":"signer()","238bf375":"PROMETHEUS_MAX_PRICE()","238bfba2":"getChannelWith(address)","238c5b06":"icoDiscountPercentageLevel1()","238d3590":"getTotalTheoreticalSupply()","238dafe0":"enabled()","238e5b14":"burnAmount(address)","238e9de7":"StopFuseaNetworkDistribution()","238f7743":"unlockSecondTokens()","238fcbf8":"DISCOUNT_TOKEN_AMOUNT_T2()","2390507b":"COMMUNITY_ADVISERS_STAKE()","239131af":"NEXUS()","2391ddf3":"handleLuckyPending(uint256)","2391f0b3":"isProtect(bytes32,uint8)","23924cff":"TeamLockingPeriod6Months()","23926732":"ifDestory(address)","23949cd1":"setNFTContractAddress(address)","2394a797":"makeHybridization(uint256,uint256)","2394cc40":"transferInternally(address,address,uint256)","2395e9b6":"specialAllowed(address)","23967d78":"FOUNDATION_HOLDER()","2397e4d7":"sellToken(uint256)","2397f92b":"KNDToken()","23985742":"STANToken()","23987690":"indFuture()","2398a6a6":"sendPrize(uint256)","2398b8fc":"SCHEMA_HASH()","2399a5af":"balanceAdd(address,address,uint256)","2399e1f2":"addPromotionalCompany(string,uint256,uint256,uint256)","2399f870":"updateFlipAndMDT(address,uint256,address,uint256)","239a2545":"totalNights()","239ab208":"notifyAssessors(uint256,uint256)","239aee06":"execute(address,address,address,uint256)","239b6dd1":"QUINToken(uint256,string,string,uint256)","239bb5a6":"getConstructorString()","239c02ba":"OPSToken()","239d339b":"updateStageByTime()","239da1a3":"SportStarMaster()","239da7de":"getServiceFeeDenominator()","239e7881":"GEBEC()","239e83df":"guardedArrayReplace(bytes,bytes,bytes)","239f26ee":"BethereumERC223()","239f29dd":"setConsensusPercent(uint256)","239fcf0f":"Balance(address)","239fd68f":"setCurrentPricePerWei(uint256)","23a08d97":"totalPreICOavailible()","23a1b159":"maxTimeBonusPercent()","23a1bd8f":"Dancoin()","23a1c271":"setPongval(int8)","23a1e00e":"openLeaderboard(uint8,string)","23a24a33":"setBAA(bytes32,address,address)","23a2725a":"LeS3coin()","23a31463":"setBlockLock(bool)","23a3335c":"BuufmanToken()","23a36d2b":"mintToken(address,uint256,uint256)","23a37c09":"addRNTBContribution(address,uint256)","23a3ad72":"checkRole(address,uint8)","23a50727":"endStage(uint256,uint256)","23a52674":"expandX()","23a58576":"zeroBool()","23a6b8ca":"currentBeneficiaryCap()","23a8792e":"ChangeTokenPrice(uint256)","23a8edb5":"LociBackend()","23a90e5e":"getCustomerTxTimestampPaymentMCW(address,bytes32)","23a9a156":"SNL()","23aa6a17":"issueTokenAndApprove(uint256,uint256,address)","23aa7e12":"controllerDelegate()","23aba14f":"iCapToken()","23abea43":"getPlayerKeys(uint256,uint256)","23ac3fd4":"getPOOL_edit_32()","23ac4b03":"addQuickPromoBonus(uint256)","23ac9ae2":"CcStandardToken(uint256,string,uint8,string)","23add736":"claim(uint256,uint256,uint8,bytes,bytes)","23adeb05":"OneChance(address,address,address)","23ae4438":"getLastRoundInfo(uint256)","23aea69d":"isNextBudgetPlanMade()","23aed228":"selling()","23aedc62":"startSale(uint256[],uint256[],uint256,uint256)","23afba86":"Lancer()","23b0abeb":"showPhaseInfo(uint256)","23b0bbea":"getBullsmasterReq()","23b0db47":"delegate_2x(address,uint256[],address[],bytes32[])","23b1131c":"unlockDate2()","23b11bb1":"getPropertyLastUpdate(uint16)","23b11d8d":"addProxy(address)","23b17715":"AddressDescriptionAdded(address,string)","23b1ed54":"getConstantName()","23b1f8e4":"lastPriceUpdateTimestamp()","23b2b48f":"addressToAccountMap(address)","23b364ab":"getAvailableTicketCount()","23b37bb6":"sqrt(uint64)","23b3af89":"addHolder(address,address)","23b3b704":"calculateUntaxedEthereumReceived(uint256)","23b3c771":"getFreeShrimp()","23b44cfc":"assignNewParcel(int256,int256,address,string)","23b493fe":"getUserFiatBalance(string)","23b5aa8d":"STAT()","23b5b257":"tokenHasFreeTrial(address,address)","23b62b75":"mainWallet()","23b6ce11":"buyDiscipleItem(uint256,uint256,uint256,uint256)","23b6fc8b":"verifyUrl()","23b715cb":"updateShare(address[],address,uint256[],uint256)","23b7b140":"setFreezTime(uint256)","23b7ec3b":"ownerOf(uint32)","23b7fc86":"count_token_holders()","23b80995":"saleOver()","23b872dd":"transferFrom(address,address,uint256)","23b8feb0":"safeMul_dec(uint256,uint256)","23b98f92":"getPOOL_edit_6()","23ba3420":"t_Michail()","23ba467a":"isLastRound()","23bb1f69":"prepareToScore(uint32)","23bb8022":"getCurrentRateByTokenSold()","23bb81ae":"transferSoldToken(address,address,uint256)","23bba494":"setContribPeriod(uint256,uint256,uint256,uint256,uint256)","23bc29a0":"systemEndingPrice()","23bcaae9":"newPost(string)","23bd4d7a":"organization()","23bd9914":"_calcReward()","23bda0ee":"MyCurrency()","23be45e2":"matchOrders(bytes,bytes)","23bef5dd":"storeWelfare(address,string)","23bf0425":"fastEnd()","23bf2973":"tgeSettingsPartFounders()","23bfc777":"changeRoundDelay(uint256)","23c0889a":"initMinerData()","23c105a2":"eliminateFrom(address,uint256)","23c1236a":"burnFromByAddress(address,uint256,address)","23c2460d":"rate(uint16,uint256)","23c2b4ea":"finishPREICO()","23c2de55":"SmartContractCasino()","23c32d74":"cstToMicro()","23c3dae7":"NewTranch(uint256)","23c4841e":"ToggleFreezeBuying()","23c4948c":"getDonator(address)","23c5a088":"updateCost(uint256)","23c5c55a":"buyImagePriv(uint256)","23c5e967":"mul2Throw(uint256)","23c639fe":"getback(uint256,uint256)","23c69d2a":"currentDividend()","23c6bc39":"addressThreshold()","23c6c98b":"activeShareholdersArray(uint256)","23c731f5":"isCanList()","23c79ab3":"CoinFuns()","23c850db":"registerGold()","23c860a8":"INTREPID_SHIP_PRICE()","23c89a00":"requestSignature(bytes32[8],bytes)","23c94353":"currentTokenBalance()","23c99826":"getDictJob(address,uint32)","23cadd34":"move(address)","23cafc3d":"voteNoLockByAdminBatch(address[],address[],uint256[])","23cb7b19":"_influenceAlgorithm(uint8,uint256)","23cba56f":"bonusProgramEnded()","23cc16be":"burnInvestorTokens(address,address)","23cc3496":"_setRunesValue11(uint256)","23cc75a8":"finalizeICO()","23cc7615":"userIdIndex()","23cc9a90":"addParticipant(address,address,address)","23cd5090":"registerToProvider(address)","23cd7cd5":"Model()","23cdd8e8":"log(string,bytes)","23ceb6d8":"mintTokenEscrow(address,uint256)","23d0601d":"getAccountIdFromSignature(bytes32,bytes)","23d17a40":"addrBRXPay()","23d1ab35":"donationReceiverLocked()","23d1b8eb":"etherPayout()","23d1c95e":"addProposal(string,string)","23d1fe56":"s22(bytes1)","23d24f24":"LogEscrowEth(uint256)","23d2691b":"addAuditRequest(address,string,uint256)","23d27633":"EtherLite()","23d2b3aa":"HaoCoin()","23d32d6a":"generatedBytes()","23d34f84":"setGuessAnswer(string)","23d44dee":"collectedSignatures(address)","23d533c8":"EBCBToken()","23d5a686":"getSpaceshipUpgradeCount()","23d669db":"setValidationClosed(uint256)","23d6b008":"assignedAmountToTheFoundation()","23d6c92f":"setFreelancerParams(uint256)","23d71b26":"mtrTokenFallBack(address,uint256)","23d73ca5":"test_invalidEmptyNotOne()","23d7caee":"BitMineToken()","23d7e089":"getPotCost()","23d808da":"getMatch(uint8)","23d80d3a":"IfContractRegist(address)","23d862ed":"getAddressLockedLength(address,address)","23d88efd":"preIcoTokenSupply()","23d9ea80":"getOfferPriceCandy(uint256)","23da9c4b":"WhiteListAccess()","23db3e50":"_checkAreaAndCategory(uint256,uint256,uint256)","23dbf825":"distributionComplete()","23dc1314":"failSafeLimit()","23dc14c0":"AdAgency()","23dc210f":"transferToAddress(address,address,uint256)","23dc33b9":"reward6()","23dc3f72":"_checkGrid(uint256,uint256,uint256)","23dc42e7":"query1(uint256,string,string)","23dca40f":"Submit(uint256,bytes32,uint16)","23dccbd6":"LogFollow(uint256,address,uint256)","23dd03c3":"getLLV_edit_23()","23dd523d":"unregisterMember(uint256)","23dd797b":"setESOP(address,address)","23dddaba":"simpleVotingDapp(bytes32[])","23de1915":"NewTicket(address,bool)","23de6651":"emitTransfer(address,address,uint256)","23defc77":"setHeir(address)","23df9df5":"_refund(uint256)","23dfed97":"emitCategoryEvaluated(address,address,uint8,uint256,uint256)","23e1d351":"buyKeyUseBalance(uint256)","23e1d8d0":"failedTimestampLength()","23e1f881":"PendingOwnershipTransfer(address,address)","23e25f7d":"sendReserveBalance(address,uint256)","23e26c43":"datestart()","23e375dd":"_computePrice(uint256,uint256,uint256,uint256)","23e3d7a9":"updateDescriptiveInformation(address,string,string,string,string,bytes20)","23e3fbd5":"depositOf(address)","23e4172d":"testValidationOfDecrease()","23e44848":"DPToken()","23e4d669":"getPlayerPortfolio()","23e53b2e":"setSiringAuctionAddress(address,address)","23e5942a":"initWallets(address,address,address,address)","23e5d13c":"declareWinner(address,bool)","23e5e822":"mintToken(int256,address,uint256,address)","23e5f1c5":"hour()","23e798e6":"getDocumentIdWithName(string)","23e7a900":"setIcoEnd(uint256)","23e7d9b2":"createInvoice(bytes32,address,uint256,string)","23e8cefc":"encodeIfElse(uint256,uint256,uint256)","23e957b6":"calculateScore(address)","23e9637f":"setSoftCapInCents(uint256)","23e9c216":"setBounty(address,string,uint256)","23eac4bd":"setTokenOwner(uint256,address)","23eb0197":"giveMemberAllowance(address,uint256)","23eb3831":"PurchaseCapChanged(uint256)","23eb861c":"unchainedMultisigVersionMajor()","23ec5939":"returnInvestoramount(address,uint256)","23ec8f62":"ownerUnlockFund()","23ecb66f":"getPreviousDate(bytes32)","23ecc4a1":"claimAmountSet()","23ecf108":"MartinKoToken()","23ed0a2e":"registerWorker(uint256,uint256,bytes32,bytes32)","23ed476f":"treasurySent()","23edfb89":"cancelSaleWhenPaused(uint256)","23ef2e4f":"stopPreIcoMint()","23ef2e56":"setBAI(bytes32,address,int256)","23ef604f":"removeOwnedNote(address,uint256,uint256)","23f02f56":"crowdEther()","23f0b2b6":"getProfile(address,string)","23f14e86":"setAutoAddress(address,address)","23f1dbe0":"minBidPercentage()","23f2cbb0":"sponsorGas()","23f3ad03":"ParminderToken()","23f4c025":"Cherrio()","23f5c64f":"get_data_owner(address,address,string)","23f614dd":"TinyOracleLookup()","23f64051":"setClaimToken(bool)","23f64140":"depositAgent(uint256,uint256,uint256[],uint256[],uint256)","23f685dd":"getUnclaimedHalvingSubsidy(uint256)","23f6e4fb":"Registered(address,address,uint256,uint256,uint256)","23f7dc66":"hasReadership(address,uint256)","23f806b7":"tokenAdvisoryBountyTeam()","23f809f6":"generateAddAddressSchemaHash(address,bytes32)","23f907d9":"MAXIMUM_ETHER_SPEND()","23f938ee":"isTransferLock(address,address)","23fa370d":"suspendedUntil()","23fa495a":"setFlatFee(uint256)","23fcdb20":"getRequiredSigs()","23fd0176":"destroyCredits(uint256)","23fd4524":"OMT()","23fe073e":"BancorQuickConverter()","23fe1da1":"purchaseWithETH(address)","23fe5b90":"hardCapFundingGoalInCents()","23fe6146":"pushIssuers(address[])","23fed09e":"hasEnoughFund()","23ff2af0":"setAttrs(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","23ffcc3e":"PenchantICO()","2400b582":"_issue(address,address,uint256,bytes,bytes)","2401db10":"sendFunding(address,uint256)","24021127":"_setOriginationFee(uint256)","2402598c":"BNSToken()","24026bfb":"getMarketOrderTrust(uint256)","2402ae57":"YudizCoin()","24032866":"checkExecutionAuthorization(address,uint256)","24038339":"updatePriceAndDenominator(uint256,uint256)","24038d2e":"purchaseArmy(uint256)","2404608f":"getSignatures(string)","240557b8":"cleanTokensAmount(address,uint256)","2405b1a3":"SwissBit(uint256)","2405d03e":"refundTokensPurchase(address,uint256)","2405e3c6":"initial_supply()","24064617":"getMom(address)","2406cedb":"setPackageOwner(bytes32,address)","2406e626":"createPool(address,uint256,uint256,uint256,uint256,uint256,uint256)","2406e9fa":"playRandom(address)","240705eb":"withdrawWithFee(address,uint256,uint256)","24070feb":"_create(address,uint8,uint8)","240860f1":"setHasCommissionerAuction(uint32)","2408771e":"validateInvestmentGroups(address[])","240961db":"showPoolOwner(uint256)","2409dfa2":"drawback()","240ad8bd":"applyAsProvider(string,string,string,string)","240bd9e6":"DcorpProxyCreated(address,address)","240c2709":"toReserved(address,uint256)","240cf1fa":"changeOwnerSigned(address,uint8,bytes32,bytes32,address)","240dfd6e":"stopEnrollment()","240e07e0":"impl_apply4Redeem(address,uint256)","240e0b2e":"JinKuangLian()","240ecad5":"transferViaProxy(address,address,uint256)","24108475":"vote(uint256,string)","2411ca69":"startPrivatesaleDate()","2411e6a3":"NonEmissiveToken(address,string,uint8,string,string,uint256)","2412bdb8":"exchange(address)","2413372d":"TestETCCoin()","24141f14":"CRYPTOHEDGECoin(uint256,string,string)","2414b63e":"CasinoBank(uint256,address)","2414e134":"NEWCICO(address)","24153b73":"Tosh(uint256,string,uint8,string)","241673e8":"withdrawTokenToFounders()","24167745":"ShamelessUETRipoff()","2417f31d":"maxPresaleTokens()","2419217e":"teamAddresses(uint256)","2419ef4d":"Coverage()","241a2305":"MultiTransfer(address,address[],uint256[])","241b701f":"openPot()","241b88b6":"threeMillionTwoHundredThousand()","241d1108":"nextDerivativeToken()","241d2c76":"getCount(address,string)","241d7aea":"BeautyCoinToken()","241de9e9":"proxy(address,address,uint256,uint256)","241e0fa0":"updateBytes20inBytes(bytes,uint256,bytes20)","241ea03c":"Pregnant(address,uint256,uint256,uint256)","241f675d":"CMO_SHARE()","24206c2e":"updateTokenAddress(address,address)","2420703e":"transfer_tokens_through_proxy_to_contract(address,address,uint256)","2421101f":"returnAddress(address)","2422224e":"signatures(bytes32)","24223a3c":"allowanceItem(uint256,uint256,uint256,address)","2422d991":"getADR()","2423a088":"UNKNOWN_TYPE()","24241ebc":"challengeWithPastCustody(address,uint256,bytes32[],uint256[],bytes32[])","2424276c":"freezeMultiAccounts(address[],bool)","24248168":"getBracketScore(bytes8,bytes8,uint64)","24250852":"mintToPublic(address,string)","2425ce3e":"upgradeTank(uint256,uint8)","24263f77":"mintICOTokens(address,uint256)","24265000":"canCollect(uint16,uint16,uint8)","24265408":"FaucetManager(address,address[])","242654a2":"transferEnable()","242655d4":"prefixedEncode(address)","24270d1e":"get_arbits_max_contribution(address)","24272479":"_finishBet(uint256)","24280cc4":"createPuppySaleAuction(uint256,uint256,uint256,uint256)","24285ade":"AlpineMegalith(uint256,string,uint8,string)","24294b1f":"startFirstRound()","2429b755":"isPrivateSaleRunning()","2429ee2a":"isBountyPayStage()","242a60b5":"withdrawValue(bool)","242a7450":"validateTenant(address,bytes32,uint256)","242aa460":"presaleInvestors(address)","242aeac1":"DiscoverCoin()","242b0a73":"rewardPayedOf(address)","242be01a":"_setAppIfNew(bytes32,bytes32,address)","242c721e":"testSetOrganiserUsingDeployedContract()","242c9ce9":"_burnFrom(address,address,uint256)","242ce07b":"frozensTotal(address)","242d1259":"WeiWeiToken(address,uint256)","242d7dba":"totalAmountRaised()","242d9f69":"getOraclizeWinnerGasFee()","242db433":"getMarketManagerAddress()","242ddf37":"NewBook(bytes32,address,uint256)","242de145":"TokenCreationContract()","242ed69f":"setActiveTranscoders()","242fc36e":"cashback()","243056d6":"writeMerchandises(uint256,string)","2430731f":"cancelRecurringBillingInternal(uint256)","2430d881":"getLastAction(address)","2431676c":"getTotalWinsCount()","24318b5c":"numberOfHosting(address)","2431f164":"process_payment()","243222c0":"processFailedVerification(bytes32)","2432282d":"getLoanCountForAddress(address)","24323110":"McFlyCrowd(uint256,uint256,address,address,address,address,address,address,address,address,address,address,address,address,address)","2432eb23":"testThrowRetractLatestRevisionNotUpdatable()","2433c978":"setupOwners(address[])","2433f617":"getIIPTotalSupply()","24349551":"deleteContract(uint256,uint8[],bytes32[],bytes32[])","2434cf10":"UseBySoftware(address)","2434ec3e":"declareLost(address,bytes32)","243527a2":"addID(address,bytes32)","24355ea6":"isA(address)","24359879":"ownerAt(uint256)","24361cec":"picops_block()","2436219c":"doubleEntryPrice()","243669ad":"totalOwners()","2436b1d2":"NUM_COUNTRIES()","2436d4e3":"TwoStandardToken(uint256,string,uint8,string)","2436d5f8":"StorageBase(address)","2437160f":"TFTOKEN()","24372fa3":"SignCurrentVersion(string)","24378482":"bnOf(bytes32,bytes32)","2437e1c2":"setPresaleParams(uint256,uint32,uint32,uint256,uint256,uint256)","24386b3e":"testMultitransfer3()","243870bd":"createChannel(string,bytes,address,address,address[],uint256[],address,uint32[])","2438b674":"window2TokenExchangeRate()","2438db59":"setServices(address,address)","243a28eb":"returnedWei(address,uint256)","243af82d":"stageBuys(address)","243b22cf":"setGameResult(uint256)","243b2a39":"createDispute(bytes32,address,address,bytes32)","243c33a1":"testCreateShortId()","243d230c":"dateTo()","243d3827":"getRewardInfo(uint256)","243d51b4":"betD()","243dc8da":"getFoo()","243e280b":"publish(string)","243eb89f":"endIcoMainSale()","243f6b58":"removeKYC(address)","243f6e0c":"change_active(uint256)","243feeb0":"ADDR_TKG_ASSOCIATION()","24415953":"lengthEqual(int256[],uint256,string)","244159af":"getPriceOneToken()","24417f39":"getCostForHealth(uint8)","24425cbf":"TEST_CONTRIBUTION()","24429e34":"OliveGardensResort()","2442cfec":"putBtoWithStc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","2442e1cb":"getMilestone(uint256)","24434852":"buyOnBehalfWithCustomerId(address,uint128)","2443a30e":"ChangeInsurerOperationEvent(address,uint256)","2443f0ae":"derivePayoutDistributionHash(uint256[],bool)","24444749":"NUM_POTATOES()","2444d352":"setWhitelistOff()","24452f44":"tryBuy(uint256,uint256)","24453ed6":"getCustomerTxAmountMCW(address,bytes32)","24454fc4":"getTranscoderEarningsPoolForRound(address,uint256)","24455e7d":"createNetwork(string,string,uint256,uint256,uint256,uint256,uint8)","24457036":"LockChainFundDeposit()","2445caf1":"ERC20Token(uint256,string,string,uint8)","24463cbe":"AddressDailyReward(address)","2446e1de":"icoClose()","2447fe10":"initBridge()","2448fe2f":"redTeamSupply()","24496026":"removeQuoter(address)","244967b3":"start_game()","24497829":"ethFundAddress()","2449dd55":"sendCommission()","244b252a":"SaturnToken()","244b34c5":"Stage2Deadline()","244bfa6b":"buyCelebrity(uint256)","244c23ee":"Token(uint256,string,uint8,string)","244c757a":"getCurrentIcoNumber()","244c91d4":"setMaxIssuers(uint256)","244c96a1":"compareOrders(uint128,uint128,uint128,uint128)","244cb924":"EnableSelling(uint256)","244cee6d":"helloWorldWeb()","244d04f5":"finalizeTokensale()","244dad09":"createdUser(bytes32)","244ded7a":"ChangeOwnership(address)","244e0c87":"balanceOF(address)","244eab9e":"lovelock_price()","244eba55":"frozenDaysForBounty()","244f4894":"getWithdrawed(address)","244f828a":"SetHFee(uint16)","244fcd03":"removeRelease(bytes32,string)","24500e05":"tokenAdvisorPartners()","24503ab0":"setDefaultTransferGas(uint256)","24506e2a":"KoalaChain()","24516000":"getPOOL_edit_26()","24519a6a":"takeFee(address,address,uint256,uint256)","2451a899":"isSuccess(uint256)","2451b3d8":"accessProvider()","24528499":"_getSettingVariables()","24534192":"addMutagenFight(uint256,uint256)","2453ffa8":"orderCount()","24541f78":"getTransferProxy(uint32)","24545f82":"LULUToken()","2454d1f0":"incFightWin(uint256)","24562747":"tokensPerETH()","245678d6":"MINBET()","24571783":"NESTFAME()","2457d765":"CHSC()","2458d472":"getCurrentStage(uint256)","2458d606":"exchange(address,uint256,string,uint256)","2458f2a8":"swarmTree(uint256)","2458f679":"instContWallet()","245a03ec":"scheduleSetIt(uint256,uint256)","245a30ec":"setDataAuction(address)","245a367c":"GetParticipant(address,address)","245a6f74":"isProxyLegit(address)","245a810b":"addMetaData(bytes32,bytes32,bytes32,bytes32[],bytes32[])","245ae4a0":"slashUsername(bytes,uint256)","245b565d":"ballotEncryptionSeckey()","245ba519":"addVerifier(address,address)","245ccdb7":"setFeePrice(uint256)","245d1314":"signUserChange(address)","245d5556":"_deleteEntry(bytes32)","245e22de":"transferDirectly(address,address,uint256)","245e70f0":"_commitBallot(bytes32,bytes32,bytes32,address,uint64)","245f57a9":"asyncSendSilently(address,uint256)","245fa2ab":"newBankManager(address)","24600157":"CUBES()","2460053e":"LegionToken(uint256,string,string)","24600fc3":"withdrawFunds()","2460f09d":"MarketContract(string,address,address,uint256[5])","24612b5d":"GenbbyToken()","24619da7":"RechargeMain(address)","24627547":"vestingFunc(uint256,uint256,uint256,uint256,uint256,uint256)","2462a0d5":"funcFromC1()","2462f6f1":"setFadeoutStarts(address,uint32)","2463de5a":"getPastWinnerTimestamps()","24642510":"rechallengePossible()","24645254":"getBalance(uint8,address)","24645c5a":"totalTokenSale()","24646ce4":"getBuySellSum()","2464a69f":"_computePublisherCut(uint128)","24652ba2":"PeerBudsToken()","24664106":"mintRep(int256,address,uint256)","24667568":"ORGANIC(uint256,string,uint8,string)","24675116":"PK(uint8,bytes32)","24676ae3":"SmzdmToken()","246982c4":"getPerson(uint256)","2469a846":"terminateCrowdSale()","2469c14e":"setState(address,uint256)","246a3234":"getEthChfPrice()","246a44f8":"isNeedCloseCurrentGame()","246c01cd":"tryUpgrade(uint32,uint8)","246c02e6":"check_depth(uint16)","246cbacc":"test_twoInvalidEqAddress()","246d4098":"openToThePublic()","246d41a9":"incrementTotalVoters()","246eb968":"deleteUri(uint256)","246f02bb":"tickets_bought(string,uint256)","246f0ca4":"KuaiKanToken(uint256,string,uint8,string)","246f1e17":"createGuess(uint256,uint256,string,uint8,uint256,uint256,uint256[],bytes32[],uint8)","246f8b96":"removeOwner()","247121e3":"MakeAdministrator(address)","2471fa1c":"_building(uint256)","24724b5b":"changeAmisWallet(address)","24743d40":"f1(bytes32)","24749b59":"bonus(uint256)","2474a21c":"collectedEther()","2474e236":"TOKENS_MAXIMUM_SUPPLY()","247534cf":"WrapperLock(address,string,string,uint256,address,bool)","2475a9b3":"UTXORedeemed(bytes32,uint8,uint256,bytes,bytes,uint8,bytes32,bytes32,address,uint256)","24788429":"removeExecutor(address)","24788ed9":"ledgerContractAddr()","247956f1":"withdrawEtherInBatch(address[],uint256[])","24797d1b":"decreaseThreshold(uint256)","247ab51f":"markAsProcessed(uint256)","247aebbb":"tokensup(uint256)","247b127d":"MiIToken(uint256,string,uint8,string)","247b188b":"icoTotalSupply()","247b3bd6":"BitCronus()","247baa3e":"ALH2()","247bb39c":"privateOfferingCap()","247bb432":"test_addAndRemovePermissions()","247c6c70":"priceLC()","247cf1aa":"lengthNotEqual(bytes32[],uint256,string)","247cff43":"freezingManager()","247ecab5":"bonusDrop(address,uint256)","24804cef":"Deed()","24806d4a":"getBounsInRound(uint256)","2480d9e6":"saleAirdrop(address,uint256)","2481325a":"ExtremeCoin()","2481851a":"finalizeName(address,string)","24819384":"btycaddmoney(address,uint256)","2481f92c":"setClockAuction(address,uint256)","2483761f":"buy1ktickets()","24841bbd":"interfaceBurnTokens(address,uint256)","24845131":"proclaimDeath()","2484a023":"verifyTetherCurrency(address,uint256,string)","24850e10":"releaseFunds(bool)","24851914":"isTeam(address)","2485484d":"clearGenVaultAndMask(address,uint256,uint256,uint256)","24854bd8":"updateThirdExhangeRate(uint256)","248582b0":"receivePaymentForGoodsSoldEarly()","24860443":"toBytes2(bytes,bytes,uint256)","24863354":"saleOverReachMaxETH()","24876434":"addPriceTier(uint256)","24884fc2":"startPeTime()","24887c04":"SieChain()","24888154":"Buy(uint64)","24888b4a":"isVoterLocked(address)","24889e37":"removeAmountForAddresses(uint256[],address[])","2488fd55":"countPlayersInPosition()","24896a47":"signPA(uint32)","248b0dba":"toBytes16(bytes,bytes,uint256)","248baabd":"FUND_ADDR()","248c4439":"setFunctionOnePrice(uint256)","248c6380":"_tokenBankrollBuyIn(uint8)","248d14eb":"allowPriceUpdate()","248e150a":"getFirstAuctionsExtendableStartDate()","248e1993":"setMinTarget(uint256)","248e4dd4":"pank13()","248e86e6":"ProjectToken(uint256,string,uint8,string)","248ec326":"DAILY_LIMIT()","248fcccc":"CRSAccount()","24900d7c":"initializeAddresses(address,address,address,address,address)","24902e24":"LOG2_E()","2490be24":"exchangeEurToEth(uint256)","2490e13f":"editPieceData(uint256,string,string)","2490e16e":"getDirectBoughtTokens()","24924bf7":"maxParticipants()","249292b9":"testUnlockedDay()","2493097b":"finalizeDestruction()","24932186":"enterOrder(uint128)","24937124":"fetchPaidOrdersForMerchant()","2493a2f2":"setBonusTokenRateLevelOne(uint256)","2493d006":"openWeek()","2493d669":"AllowanceGranted(address,uint256)","24941147":"cancelProject(uint256)","24943c7d":"resolveDispute(bytes16,address,address,uint256,uint16,uint8,bytes32,bytes32,uint8)","2494aef9":"TOKEN_AMOUNT_ICO_STAGE1_PRE_SALE2()","2494e267":"CXLExchangeRate()","24953eaa":"removeAddressesFromWhitelist(address[])","249559ad":"computeVoteOutcome(uint256)","249586f2":"editPayoutSetting(uint8,uint16)","2495c0ce":"stopVote()","24968a70":"getHomePost(uint256)","2496a431":"robPantry(address,uint256)","2496b796":"sellMyTokensElixir()","249830d8":"setUnclaimedPlotPrice(uint256)","24992680":"SelfKeyCrowdsale(uint64,uint64,uint256)","24999c9c":"bonusSignalValue()","2499a533":"Purchase(address,uint256)","249a1120":"licenseTermsMaxCostPerSec(bytes32,bytes32)","249aa292":"preIcoPrice()","249b4d0b":"removeTrustedIssuer(address,bytes)","249b4d4f":"transferContractUser(address)","249b7c19":"presaleEndTime()","249bc291":"transferMintMaster(address)","249cb3fa":"canImplementInterfaceForAddress(bytes32,address)","249eae4d":"addInvestors(address[],uint256[])","249f1f22":"insertNodeSorted(uint256,address)","249f77ef":"CancelSimpleOffer(uint256)","249f7aa0":"exchangeRateChangesBlock()","249ff838":"getAddressByNames(bytes32[])","24a039c7":"CBToken(address,uint256)","24a084df":"sendValue(address,uint256)","24a12edf":"getAuctionIdForUserAndIdx(address,uint256)","24a1871e":"LOL2()","24a1c1e0":"addCertificateAndBind2Wallet(address,uint256,bytes32,bytes32)","24a1cd1e":"currentCoefficient()","24a20a25":"feed10(uint256)","24a23361":"getTeamAttribute(uint8,uint8,uint8,uint32[11])","24a27bd2":"tokensForAdvisory()","24a30e46":"m_claimingIsActive()","24a38383":"WhitelistedSmallCap(address,uint256)","24a3b013":"attachToToken(address)","24a434eb":"openCarousel()","24a43c51":"releaseMultiple(address[])","24a4411d":"DecoderTester(address,address,address,address,uint256)","24a47aeb":"merge(uint256)","24a4aff6":"adaCoin()","24a684e1":"get_perms(bytes32)","24a69051":"allowClaim(address)","24a6a409":"MINTY()","24a6ab0c":"freeSupply()","24a73e5f":"decreaseAllowance(address,uint256,bool)","24a779ca":"PELOMemberMap(address)","24a7d277":"removeAddressFromBlacklist(address,address)","24a80b31":"BusinessUnion(uint256,string,uint8,string)","24a852c6":"unset(bytes)","24a8e11d":"isAuthorized(address,address,bytes32)","24a9d3d9":"callAndReward(string,string,uint256)","24a9d853":"feeBps()","24aa62fe":"setObjectionPercent(uint256)","24aa6dd1":"ProxyManagementContract()","24aa93b9":"getVestedAdvisorTokens()","24abfc02":"getTournamentThresholdFee()","24ac4df1":"cancelNewOwnersCountRequest()","24ac4e65":"getServerUserNumber(address)","24accfa3":"refundMoney(uint256)","24acec2b":"PayeeWithdrawInterest(address,uint256,uint256)","24ad35e1":"PisangChain()","24addfc0":"swapMe()","24ae84cc":"participateCrowdsaleInvestor(address)","24aee933":"usePower(uint256,uint8,uint8,uint8,uint8[176])","24af4cdb":"setNewUserState(string,bytes,string)","24aff74d":"Debit(address,address)","24b04905":"gift()","24b06a96":"getAllElectionsOfOrganiser(address,address)","24b07165":"get_property_facility(uint256)","24b0ff0f":"approveTokensFromKingWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","24b1905b":"sendFirstBatch(address[],uint256[])","24b19da5":"TokenDistribution(address)","24b1a2fa":"disableArbiter(address)","24b1babf":"claimEarnings(uint256)","24b1bfdf":"resetToken()","24b27fc8":"CoquiToken()","24b2c2f6":"GYUToken()","24b33f5d":"_auction(uint256,address)","24b35ef2":"mintTokens(address,uint256,uint8,bytes32)","24b3940a":"sayGoodBye()","24b492d7":"SetInitData(uint256,uint256,uint256,uint256,uint256)","24b4cee0":"openBatch(uint256)","24b4ec3d":"buyOwn(address,uint256)","24b4fc8e":"closeChannelWithoutReceipt()","24b508a3":"listByGroup(string)","24b50e43":"getMsgHash(address)","24b51369":"tgrSettingsPartFounders()","24b570a9":"totalPot()","24b5c134":"numCities()","24b5efa6":"RewardClaimed(uint256,address,uint256)","24b6b8c0":"_safeTransfer(address,address,uint256,bytes)","24b6f7d3":"TestBathTx(uint256,uint8,string,string)","24b72667":"buyprices()","24b77f05":"acceptCounterStack(bytes32,bytes32)","24b79a1c":"ICO_PHASE3_BONUS_PERCENTAGE()","24b82a76":"voterReward(address,bytes32,uint256)","24b89fa7":"unlockStepLong()","24b8fbf6":"register(address,bytes)","24b94ac6":"atto()","24ba1a46":"isSpawnProxy(uint32,address)","24ba506d":"getNumberOfTransactions()","24baeb12":"initCrowdsaleToken(bytes32,bytes32,uint256)","24bb49d6":"balanceMinusFeesOutstanding()","24bb7734":"mainSaleDuration()","24bb7c26":"pausedPublic()","24bbd049":"mintOpen()","24bc4e92":"QueenXChain()","24bcdfbd":"tradeFee()","24bce60c":"freeze(address,uint256)","24bdaf95":"about(uint256)","24bdf96a":"getUserRefBalance(address)","24c034a7":"ERC721Auction(address)","24c05c72":"requestLoans(uint256)","24c0db84":"ico1receivedTotal()","24c12bf6":"code()","24c1f9c7":"stage_3_add()","24c2362b":"buyCrySolObject(uint256)","24c30182":"BleedFomo()","24c31975":"increaseJackpot(uint256,uint256,uint256)","24c33d33":"round_(uint256)","24c37507":"getMinBet()","24c4c9e4":"getCurrentPRETDEBonus()","24c4e3b9":"getPatientHealthData(address)","24c55380":"TicketPurchase(uint256,address,uint256)","24c65927":"createNewAuction(string,uint256)","24c65f35":"updateRefundGas()","24c6ef60":"SafeTokenTransfer()","24c74c1d":"LogClaim(address,uint256,uint256,uint256)","24c74c78":"certify(bytes32)","24c91c1b":"isDataResponseValid(address,address,address,string,bytes)","24c93343":"error(string)","24c9bf5e":"Prizes()","24ca77e5":"teamNum()","24ca984e":"addRouter(address)","24caf5e1":"sale_address()","24cb015a":"_ONE()","24cb57dc":"whitelistEntries(uint256,uint256)","24cc35a6":"_isTeam()","24cd2ae4":"beneficiaryUserIds(uint256)","24ce2562":"updateGameSpecifics(uint256,uint256,uint256,uint256)","24ce2917":"create(address,uint256,uint256,address,address)","24ce9d27":"sellOrder(address,uint256,uint256)","24cee3d6":"Change(address,address,address,uint256,uint256)","24d0cc0f":"getPayouts(address)","24d16a4d":"makeUnderlier(bytes32,address,int256)","24d1c28b":"changeVoteRules(uint256)","24d29cfb":"_removeSigner(address)","24d3048d":"cancelNode(string)","24d30d54":"enableMerge(bool)","24d3eaf3":"bonusEndTime333()","24d427a9":"print(address)","24d4e90a":"ln(uint256)","24d5336a":"deicmals()","24d6169c":"startLockPeriod()","24d6d601":"voteFor(address,uint256)","24d70dea":"hasEntered(address)","24d7378a":"m_totalTokens()","24d7806c":"isAdmin(address)","24d86f00":"decreaseStake(uint256,uint256)","24d89171":"changeNeedFightToAdult(uint256)","24d97a4a":"killme()","24da48a3":"updateMaxAllocation(uint256)","24da569a":"AGToken()","24daddc5":"setRestricted(bool)","24db1f50":"masFreezedTokens(address[],uint256[],uint256[])","24dbb91d":"BusinessCard(string,uint256,string,address)","24dc793f":"getKydy(uint256)","24dcd0ef":"transferFounders(address,uint256)","24dd24ed":"allowingClaimBTC()","24ddb58c":"performStepVerification(uint256,bytes,bytes,bytes)","24de30f1":"distributeEarlyBackerTokens(address,uint256)","24de3c0e":"gwei()","24de908d":"wins()","24df2d5b":"Filmpass()","24df75d9":"withdrawFromTicker(uint256)","24dfc9d7":"getBytes32(uint256)","24e04871":"horseForSale(uint256,uint256)","24e0be2e":"EVenToken()","24e1c3f3":"PRCT_ETH_OP()","24e1fa3a":"FIRST_WITHDRAW_RATE()","24e21cde":"sendTradeOffer(address,uint256[],uint256[])","24e2ca92":"withdrawSharedExpense(uint256,address)","24e2cda7":"TestOrder2(address)","24e2dbd3":"linkRecipientName(bytes32)","24e34476":"myStoredDividends()","24e5355e":"JerryToken()","24e581be":"transferAllToOwner()","24e5bdb9":"getEventsCount(string)","24e5eeaa":"slogan()","24e65e14":"Addr6()","24e7a38a":"setGeneScienceAddress(address)","24e7c824":"performTransfers(address[],uint256[])","24e846c7":"confirmedSaleEther()","24e8b3ec":"getClaimableRewards(bytes32)","24e998c3":"Ethershift()","24e9dad8":"_safeCall(address,uint256)","24ea8d1a":"Fortnitecoin()","24eaf1ea":"SendBadge(address,address,uint256)","24ec6f66":"cancelContest(uint32)","24ec7590":"minFee()","24ed1486":"getPeriodAliasFor(uint256,address)","24ed2d8b":"initOwnership(address,address)","24ed3dc0":"PolyAnalytixProjectToken()","24ed3e78":"BACKUP_THREE()","24eda713":"teamTwoWin()","24edc2a1":"WINT()","24ee0097":"myMethod(uint256,string)","24ee62ee":"secondWavePrice()","24ee9be4":"getVirtualBalance(address,address)","24eebc47":"SWAPCOINZ()","24efe4c3":"_addToClaimList(address,uint256)","24f07356":"batchIncreaseApproval(address[],uint256[])","24f073ad":"getTimeOfLastBid()","24f12f1e":"ProfitSharingMock(address)","24f159c2":"extensions()","24f1ec37":"multiAccessRecipient()","24f2cc02":"preIcoLimit()","24f32f82":"changeHardCap(uint256)","24f35549":"setup(uint256[])","24f3c639":"buyApprenticeChest(uint256)","24f481c8":"oracleItQuery(string,string,string,uint256,uint256)","24f48bc5":"setWatcher(address)","24f5445b":"transferFundToAccount()","24f55e29":"hasCompany(string)","24f618b6":"GetDOTRevokableHash(bytes32,uint32)","24f65ee7":"getTokenDecimals()","24f690ac":"cryptowars()","24f696fd":"LogFundTransfer(address,address,uint256,uint8)","24f731d5":"PlaceBet(uint256,bytes)","24f743dc":"freeSpaceOf(address)","24f74697":"callbackGasLimit()","24f7a980":"WaitStarted(uint256)","24f82526":"closeLong()","24f8fe9c":"EdgelessCasino(address,address,uint256,uint256)","24f91d83":"init(address,address,address,string)","24f9702e":"allocateArrayOfTokens(uint256,address[])","24f99ba4":"ChiMarket()","24fa6f3b":"requiredBlocksElapsedForVictory()","24fabb87":"setImageOwner(uint256,address)","24fad665":"enableMasterTransfers()","24fb563f":"PlayerTickets(address,uint256,uint256)","24fc253e":"eraIndex()","24fc65ed":"getId(uint256,uint256)","24fc70ff":"setBonusOn(bool)","24fcb80c":"parseAddress(bytes32)","24fcbc1c":"withdrowErc20(address,address,uint256)","24fd0a5c":"isAvailableForTransfer(uint64)","24fd2be1":"NationalCoin()","24fd5585":"fixedExp(uint256,uint8)","24fd6ec9":"zeroBonus()","24fe722e":"requestUnpause()","24fe73fe":"isRegularOrBoardMember(address)","24fe8e68":"MyToken(uint256,uint256,string,string,uint256,uint256)","24fef683":"OwnershipGranted(address)","24ffca71":"visitCost(uint8)","24ffea1a":"presaleToken()","25005498":"updateEntityNew(uint256,bool)","2500ec4a":"getDHand(uint32)","25010816":"get_length(uint256,uint256)","25012699":"KERNEL_APP()","25017e10":"transferSubscription(bytes32,address)","2501faa5":"triggerRecoveryAddressChangeFor(uint256,address)","2502c19c":"setRBInformationStoreAddress(address)","250312ce":"bleachAppearance(uint128,uint128)","2503dce8":"updatePublisherFee(address,uint16,address)","25052d02":"getMyTokensReturns()","250537fc":"_createCollectible(bytes32,address)","250540cf":"calcMaxWithdraw(address)","25059052":"WhitelistedLargeCap(address,uint256)","2505c445":"finalizedEthFundAddress()","2505f349":"setTokenMinter(uint256,address)","25062287":"_ownerDist()","25068a28":"freezeAllowance(address)","2506bfe7":"validateBySymbol(string)","25074d73":"Registered(string,uint256,address,string)","25084b04":"manualOverrideEditionHighestBidder(uint256,address)","25096f28":"KryptopyTokenMock()","2509f1b9":"SLP()","250a1c1d":"Validate(string,string,string,bool)","250a8dc2":"isAccountAddress(address)","250a93cb":"POEXToken(address,address)","250ac096":"BuyRoseCoin()","250b1154":"tokenRate3()","250b35e8":"BidSaved()","250bc504":"Ambassador()","250c95fe":"setMaxBuy(uint256,uint256)","250ccce4":"getOutStreamOf(address)","250d5bc8":"LineToken3()","250de298":"EthlanceSearchJobs(address)","250dea06":"modifyBalance(address,uint256)","250e7d61":"CROWDSALE_CLOSING_TIME()","250e816b":"getPeriodSealedPurchaseOrderFor(uint256,address)","250e87c9":"pyramid()","250ef961":"checkCorrectPurchase()","250fe144":"setInvoice(uint256,bool,string,string,string,string)","25100b4d":"placeBet(bytes32,string)","25102f27":"PRESALE_START_TIME()","25107a47":"TransactionRefundedAfterEscalation(uint256)","25112004":"XCNTToken()","25112743":"getSaleContractStartBlock(address)","251139f6":"setPrevContract(address)","25119b5f":"channelManagerByToken(address)","2511b182":"minBuyableAmount()","25128b02":"CampaignResumed(uint256)","25137f46":"setSalesPipeAllowance(address,uint256)","251481c8":"testDecodeTransfer(bytes)","2514a6b4":"withdrawDividends(uint256)","251506fa":"SendFart(string)","25161e70":"HKDHToken(uint256,string,string)","2516a18f":"setMintableToken(address)","2516af82":"createLottery(bytes32,uint256,uint256)","2516c6c6":"min_tokens()","2516d738":"secureAddOrderFunds(address,bool,uint128,uint128)","25174f0e":"getOwnerIndex(address)","25182e79":"winAmount4()","25185d3e":"freeBalance()","25192fca":"issuanceDraft(address)","2519a378":"finalizeReplaceTrueUSD()","251a8096":"total_wins_wei()","251aaf67":"dividendsPaidPerShare()","251b5f8e":"team_fund()","251c1aa3":"unlockTime()","251c7182":"seed_multiplier()","251d3589":"setUseEIP712(bool)","251d8ffb":"setNav(uint256)","251e3d7d":"registerMember(address,bytes,uint256)","251ed995":"walletSetWallet(address)","251fa3b1":"testFailRetractLatestRevisionNotOwner()","251fbe37":"get_training_index()","25200718":"requestAudit(string,uint256)","25209260":"PrepareRoll(uint256)","2520bf04":"shuffle()","2520d2e1":"readvalidrollsXaddr(address)","25221a4f":"addToBlacklistMulti(address[])","25223bd4":"donor()","25233782":"magicnumsig()","252348dc":"ratePerEth()","2524380f":"buy_Exchg_BkgChk(address,uint256,uint256,address,uint256)","25245b26":"sendEth(address[],uint256[])","25248587":"indexview(address)","252498a2":"setUrl(string)","25250519":"addGlobalAdmin(address,address)","2525aa78":"mintStart5()","2525f5c1":"cancelBid(address,bytes32)","25266f96":"isNewPlayerInBattle(string,address)","2526d960":"clawback()","2527331b":"transferToSimpleService(address,uint32,uint256,uint256,uint256)","252733f0":"registrantsPaid()","252786e4":"WatchBlockSizeInEther()","25280163":"RedFundCrowdsale(uint256,uint256,uint256,address,uint256)","25287c0e":"bonusesGiven()","2529b907":"setVaultDeposit(uint256)","2529d1a3":"fused()","252ba7a0":"userDeployCount(address)","252bb9c3":"PHOENIX_CORSAIR_EXTRACTION_BASE()","252cb4fe":"registerProposal(uint256,uint256[])","252ccac3":"getTotalActiveBets()","252cedc3":"sendERC20Tweet(uint256,string,string)","252d1578":"init(address[],uint256,uint256,uint256,uint256)","252d7eb3":"getCurrentPayoutIndex()","252dbc36":"setTokenPoolReward(uint256)","252e40b1":"secondsPerYear()","252edb76":"setUInt8(bytes32,bytes32,uint8)","252f14ba":"_addArbiter(address)","252f34a7":"loserOne()","252f4977":"destroyTokensInBntyTokenContract(address,uint256)","252fb38d":"bytes32string(bytes32)","253089b5":"smxTeamAddress()","2530c905":"rand(uint256)","25316ff5":"getBetUint(uint8,int8)","2531a36a":"getDesignatedReportDisputeDueTimestamp()","25327b75":"latestErc20TxRequest()","2533bb9d":"dataCentreAddr()","2533ff94":"LogPersonUpdate(address,uint256,uint256,string)","2534076e":"cancelRemoveOwnerRequest()","253459e3":"feesSeperateFromBalanceApproximately()","253515d5":"accruedBuyout(address)","2535b150":"cryptoJingles()","2535dd53":"getAvailableWithdrawInvestmentsForBeneficiary()","2535f762":"transferWithData(address,uint256,bytes)","25361060":"getReferralStatus(address)","2536d7f1":"endOfCrowdsale()","25384770":"reserveAllocated()","25387eed":"tallyTheVotes()","253abf4a":"processSalesForAllBuyers(uint256)","253bc579":"companyClaimed()","253bd7b7":"check(address,bytes32)","253c8bd4":"change_owner(address)","253caf94":"setTasksAddress(address)","253d8195":"SavingsBank()","253e3447":"numberOfSpritesOwnedByUser(address)","253e7fdf":"becomePacifistmaster()","253ebd92":"isTierJoined(address)","253f029c":"performUpdatePC()","253f055b":"getStage2End()","253f2809":"offerCollectibleForSale(uint256,uint256,int256,uint256)","253f5c38":"addtoLeaderboard(uint64,uint64,uint64)","253f89b0":"minContributionUSDc()","25400abc":"buyPuzzle(uint8)","25402e6c":"vcxCount()","2540424b":"isDefIndexInRange(uint8)","25406480":"extendPeriod(uint256)","2540c420":"phaseOneRate()","2541edcc":"oferta()","25435704":"updateTokenSupply(uint256)","254439fe":"addTokenList(address,uint32)","25449c54":"ArteumToken()","2545686d":"is_slot_in_bid(uint8,uint8,uint8)","2545a07a":"MOEToken()","25461328":"MSPMock(address)","25464902":"AUCC()","2546559c":"Demo()","2546de10":"vest(address,uint256,uint256)","254747a5":"checkAvailableAmount(address,uint256)","25476ed8":"settleAndWithdrawCfd(uint128)","254800d4":"vestingStart()","2548bbbd":"WithdrawalCreatedEvent(uint256,uint256,bytes)","25495998":"getMinimumConsumerDeposit()","25498152":"setBuyDividendPercentageFee(uint8,uint256,uint256)","2549ad8f":"MANHATTANPROXYCNVNTAVE()","2549e0b1":"getLockedBalance()","254a46f4":"cycleMintSupply()","254b302d":"revokeAllMyId()","254bd326":"getUserAddr(uint256)","254c70ac":"getPlayerData(uint32)","254c91b3":"testBitNotSetSuccess()","254d2e12":"GetDemolishCost(uint256,uint256)","254dacba":"BurnTokens(address,uint256,string)","254dcfe2":"lastActiveTransaction(address)","254fd745":"transferUCASH(address,uint256)","255016c8":"checkIfExploded()","255074a9":"addManualContributor(address,uint256)","2550c435":"CRYPTO_USD()","2551858e":"getFlags(bytes32)","2552317c":"lastBlockNumber()","25534a1e":"saleEtherReceived()","2553795a":"AragonSupply()","2553ac0d":"getPlayeds(uint256,address)","2553e0cb":"OwnedMortal()","2554a358":"queryCurrentTradablePrice()","2554b9b3":"kkkTokenSale(uint256,address)","2555611a":"AOKPAY()","25568fd7":"__setBeneficiaryForDasTokensChange(address)","2556befa":"feeBank(address)","255706f5":"start_service2(uint256,address)","25575a04":"peBalance()","25579702":"calculateDrugBuySimple(uint256)","25580656":"dataSourceGetRoundOfSixteenResult(uint256)","25583590":"_cancelAuction(uint256)","25585ee8":"diamondIndexToApproved(uint256)","255884ae":"discoveryPrice(uint256)","2559e0dd":"rateInSpecificTier(uint256)","255bd903":"signByBride()","255c8244":"amountRaisedPreSale()","255c8fee":"TestyTest()","255e2f81":"adjustDollarToEtherRatio(uint256)","255e444e":"scientists()","255e4685":"mintStart()","255eac5c":"newRegistration(address,uint256)","255f82e2":"sealed(uint256,bytes32)","25605c6a":"balanceOfSC()","2560a8c0":"houseedge()","2560baeb":"calculatePayrollBurnrate()","25616007":"getLandplayerFirstDefenderID(uint8,uint32)","25618ca8":"setBattleContractAddress(address,address)","2561ee35":"estimateBuyOrder(uint256,bool)","25625608":"FoundWinner(address,uint256)","2562b427":"declineKyc(address)","25630c9f":"fwithdrawal(uint256)","25635b68":"updateBaseInventory(uint256,uint256,uint16)","2564e1c4":"PaymentAddressFactory()","256540cd":"turnover()","256697df":"ibcDistributed()","25672ee6":"OpenBids(address,uint256,address,address,uint256,uint256)","256738d1":"AGT()","25686e15":"getMarketsRocId(uint256)","25687e28":"tuneLastStageStartAt(uint256)","256919c6":"fixSale()","25696308":"lastBlock_a10Hash_uint256()","25697337":"getLittAdminCount()","25698d89":"isLottery()","2569cd6c":"assistant()","256a9f81":"extendedTime()","256b8dfe":"Travelcash()","256bcaa0":"addToJackpot()","256bdaa4":"setEtherRate(uint16)","256c0926":"RocketPoolCrowdsale(address)","256c10a1":"market2021TokenCreated()","256c3232":"getPreICOBonusAmount(uint256,uint256)","256c5fc6":"LooisToken(uint256,string,uint8,string)","256df407":"test_spamFreeze()","256f992b":"organizers_percent()","256fa241":"distributeTokens(address[],uint256)","256fec88":"lastSender()","2570c13d":"GBCoin()","2570e31e":"getTokens(uint256,address)","2571a4ab":"MaxBetAmountChanged(uint256)","25731e97":"quitBanker()","257341a8":"vestingCountOf(address)","2573aa7d":"newShare(address)","2573ce27":"validateUserByHash(bytes32)","25746251":"canVote(uint256)","25750995":"updateChfCentsPerEth(uint256)","25756d90":"getWeaponRarityFromTokenId(uint256)","2575d47e":"EmitAccountChartDetails(address,uint256,uint256,uint256)","2576a779":"updateServiceFee(bytes32,uint256)","257714db":"getTransferRate(address)","257781e7":"deleteIPFSHash(bytes32)","2577929b":"settleContract(uint256)","257793f9":"getConstructorTouches()","2578117b":"getPotAsFixedPointForGameId(uint256)","25787747":"icoDuration()","2578e943":"RHYNOTE()","25799b18":"getUnapprovedArtists()","2579dd3c":"registrantToHopefulIds(address)","257bcd6a":"placeBet(uint256,bytes32,bytes32)","257c360d":"getCurrentBalanceForCampaign(bytes32)","257c88b5":"curQuater()","257d3db5":"setNumNumbers(uint256)","257d5995":"updateSinglePayout(address,uint256)","257d849f":"ZegartToken(uint256,string,string,string)","257d9bb8":"MINIMUM_AMOUNT()","257e0523":"addLockedTokeD(address)","257e1f8f":"endUpgrade()","257e5c69":"matchStake()","257ef522":"approveBountyTransfer(address)","257ef70b":"fillSellOrder(address,address,uint256,uint256)","257f9abf":"removeFromList(address)","257fc838":"setResolveValueGasLimit(uint256)","258072e5":"display_rate()","2580ce84":"totalAndRemainOf(uint256,address)","2581021c":"depositCollateralOnBehalfOfRecurse(address,address,bytes32,uint256)","258108da":"slaveWalletPercent()","25818751":"test_oneValidEqUint3()","2581c674":"testBitsOrFailIndexOOB()","2581f5a4":"distributeAirdrop(uint256,address[],uint256[])","2582bf2a":"updateDelegateKey(address)","258315b3":"ATC(uint256,string,uint8,string)","2583373c":"distributeAndUnlockTokens()","2583a1d9":"oraclizeQueryId()","2583b2e4":"totalWithdrawTokenAll()","2584295e":"userWhiteListContracts(address,address)","2587eb4e":"setRate(int256)","2588f9a5":"ReleaseAgentSet(address)","25892f92":"ApprovedBy(uint256,address)","2589af4a":"getProjectKudosByUsers(bytes32,address[])","258a61d6":"coordinateToIdentifier(uint256,uint256)","258a6ca6":"getStoryExpiry(bytes12)","258ae582":"verify(bytes32,bytes)","258b5a35":"challengeSettle(bytes,uint8[2],bytes32[2],bytes32[2])","258b5c06":"finalizeCrowdsale(uint256,uint256,uint256)","258b5da6":"recoverWETH()","258b85d4":"verifyHash(string,string)","258c047e":"getStatusEventClosed(bytes16)","258c0f1e":"deleteCaller(address)","258c2a2d":"Charity()","258c4f63":"channelManagerByToken(address,address)","258c5ddd":"softWithdraw()","258d3d6e":"PlayHallToken()","258da4b4":"seedStarted()","258dd544":"estimateSellOrder(uint256,bool)","258e60b6":"start(string)","258f6b8f":"GiveReferralRocket(uint16,address)","258fd4f3":"Stage1Allocation()","25910753":"addCourse(string,string,bytes32)","2591432d":"canary()","25925806":"tokensAllocatedForCs(address,address,address)","2592e921":"verifyParams()","2593ed21":"setICO1Phase()","2594b343":"walletTwo()","259653b8":"distributionClosed()","2596c93b":"manualBonusActive()","2596e62c":"test_oneValidEqBytesUint()","25973ef7":"CIFRCOINTOKEN()","25979983":"sendToAll(uint256)","25981559":"bluceTestCoin(uint256,string,string)","25982586":"AddressDemo()","259852f8":"updateGenVault(uint256)","2598ab9d":"createPromoSeedAuction(uint8,uint8,uint256,uint256,uint256,uint256,uint256,uint256)","25990d4d":"TokenFulfillment(address[2],uint256[8],uint256)","2599c661":"getgamecardsalemoneyuint256(uint256)","259a28cf":"UNLOCK_PERIOD()","259b2ce0":"whitelistRegistrants(address)","259b5181":"_batch2_rate()","259b5605":"PTL()","259bc6f5":"getWhiteUsers()","259c05f5":"DEV_TAX_DIVISOR()","259c29e8":"replaceShorter()","259c95c4":"_sendWebGiftToken(address,uint256)","259ceee5":"contractTokensTotal()","259d1cb4":"eth_decimal_num()","259d33c1":"roundStats(uint256)","259eb959":"privilegedTransfer(address,uint256,bytes,string)","259fddaf":"stakeCommunityTokens()","259fefcb":"angelAddress()","25a10a70":"getChild(address)","25a190c9":"inicializaStatusPossiveis()","25a2219f":"promotionsUsed()","25a30145":"preSaleTime()","25a31135":"Disable()","25a34aca":"returnMargin()","25a3ba49":"getCertKey(string)","25a42081":"setPriceStep3(uint256)","25a43ea5":"setts10(uint256,address)","25a50636":"completeBountyAddresses(address[])","25a52d9d":"curentWinner()","25a583a3":"_reAdjustDifficulty(uint256)","25a6c545":"generalInfo()","25a7650a":"beginGame(uint256)","25a78057":"DeClubToken(uint256,string,string)","25a86d56":"ETH_USD_EXCHANGE_CENTS()","25a8e6f9":"addNewEditor(address)","25a9d450":"getClientBalance()","25ab2d03":"getReturnSize(uint256)","25ab526d":"MITPurchase(address,address,uint256,uint256)","25ab9f43":"addDoubleChanceLine(uint256,string,uint256)","25abc312":"changeICOPrice(uint256)","25ac29da":"generateUrl(string,uint256)","25ace2a7":"checkExpired()","25ad7f2e":"OneStep()","25ad91ce":"createUser()","25adfc8f":"SetMaxMinersXblock(uint256)","25aeb4a2":"addPayment(uint256,string,int256,bool)","25aef744":"ValuePlaced(address,address,uint256)","25b05c88":"playerGameId(address)","25b10186":"INITIAL_PRICE_INCREMENT()","25b198eb":"inList(address)","25b1a072":"setGOPCreator(address)","25b29d84":"getEtherValue()","25b2ac77":"privateOfferingWallet()","25b31a97":"purchase(address)","25b3b5a8":"_totalMinedSupply()","25b3bfb8":"transferFrom0(address,address,uint256)","25b3edd9":"updateTraits(uint256)","25b5160c":"setICOPrice(uint256)","25b56727":"createProxy(address,address)","25b56dd4":"averageScrapPrice()","25b634c0":"approveDisbursement()","25b64bba":"signerConsumerNonce(address,address)","25b6ae80":"incSALESTATE()","25b72273":"SGT(address)","25b75b7b":"deregistrationDate()","25b825ab":"newMediaToken(uint256,uint8,string,string)","25b886eb":"constructors()","25b89c52":"AirDropToken()","25b901c8":"Refundlineinfo()","25ba0824":"grantOwners(address)","25ba0f51":"initContract(address,address)","25ba2d2e":"minimalPrice()","25bae118":"earlyPurchaseClosedAt()","25bb8e93":"_badgeUnFreeze(uint256)","25bccea2":"setFreeze(address)","25bd4639":"paymentId()","25bd713f":"tokensForPlatform()","25bdb2a8":"getSaleState()","25bdb73d":"benefitPercents()","25bdc110":"Resolve(bool,uint256)","25bddc18":"DGXCrowdsale(address,address)","25be124e":"token2()","25be53e7":"kickStartICO(address,uint256)","25c065b1":"minStakingAmount()","25c10247":"buyIPC()","25c2052f":"last_random()","25c24bc3":"folioToken()","25c302e4":"totalDonors()","25c48f30":"MYDECIMAL()","25c50f97":"enablePhenomenon(bytes32)","25c54456":"existsContract(address)","25c5ce04":"availableOnStage()","25c5d4d4":"tileDrop(address[])","25c62d5a":"MAX_TOKENS_AIRDROPS_BOUNTIES()","25c70a44":"moveToArea(uint16)","25c782d7":"addStageCrowdsale(address)","25c7cd17":"getCurrentLeaderOwners()","25c843b9":"comments()","25c9307d":"lastBetBlockNumber()","25c93df3":"rewardTokenAmount(uint256)","25c95538":"isRepeated(string)","25c972ff":"JoinGameAsBanker(uint8,uint256)","25ca5cc6":"candidateTillETHAssets()","25ca953d":"resetAirDrop(uint256,uint256)","25caa262":"getBal()","25caaa37":"getMyChicken()","25cb2bc6":"getBrokerAddress(uint256,uint256)","25cb366d":"manualMigrate(address)","25cb4f2c":"profitContainerAddress()","25cb5bc0":"getExpiryTime()","25cb6303":"isItIco()","25cb98d5":"removeVerifiedUser(address)","25cbd68e":"fifthTeamWithdrawal()","25cbe702":"tokenSupportLimit()","25cbeb0a":"DICIMALS()","25cbeb7e":"creatorsAddress()","25cc348f":"testDeployedValues()","25ccdb4c":"currentspudinfo()","25ccf381":"create_forwarder()","25ccf688":"KEO()","25cdca8d":"CommonWhitelist()","25cde42c":"addPayerRefundAddressAction(bytes32,bytes)","25ce77a0":"devuelveEncuestados(bytes32)","25ceb4b2":"submitBlock()","25cf512d":"setBytes32Value(bytes32,bytes32)","25cf98e5":"EduCloud()","25cfa566":"StartingPrice()","25d00041":"registrantIndex()","25d04034":"KT07Coin(uint256,string,uint8,string)","25d0b4ef":"minFundingGoal()","25d104d4":"returnVestingSchedule()","25d1da84":"revokeAll(bytes32,address)","25d30d8e":"cnt_per_Keos()","25d3a09d":"getProposal(string)","25d3b2c6":"check_array_add(address)","25d3bcd1":"saleHardcap()","25d3d0e3":"purchaseTimestamp()","25d4bdeb":"LookAtCollectedFees()","25d5971f":"withdrawStake(uint256)","25d5eafa":"total_points()","25d76e6d":"setCompte_27(string)","25d78d3b":"IcoPhaseManagement(address)","25d83bb3":"authorized_setCardPerkText(uint256,string)","25d85e12":"totalPopulation()","25d8a4b2":"SpiceToken()","25d8dcf2":"betAndFlip()","25d8f6a5":"dividendForHistory()","25d91125":"earlyWhitelistBeginTime()","25d92ee2":"updateFeeWallet(address,address)","25d988bb":"buy_token(address[],uint256,uint256)","25d998bb":"availableBalanceOf(address)","25d9d57d":"highTokensToSellGoal()","25d9ec83":"requestBuywithETH(address)","25dac5e3":"DocumentStored(uint256,uint256)","25db4dd0":"jackpotBlance()","25db6699":"tgrSettingsBlocksPerStage()","25dbe054":"setDonationUnlockTs(uint32)","25dccaf9":"postMessage(address,uint256,string)","25dd0ee6":"checkTotalBalance(uint256[])","25dd495a":"Recycle()","25ddda76":"changeMixEnable(bool)","25dfbfba":"addProduct(string,string,string,string,uint256)","25dfcf84":"saleAllocated()","25e023b3":"unlockOwnerBalance()","25e0671f":"areReservedTokensDistributed()","25e0c876":"sosTransfer(address,address,uint256)","25e11811":"addFunctions(address)","25e1350f":"insert_candidate(string,uint8,string,string)","25e16063":"withdrawEth(address)","25e1b5e4":"pricePerMessage()","25e1c6f7":"batchTransferORS(address[],uint256)","25e3172b":"AdminClaimAirdropMultiple(address[],uint256)","25e330fb":"_increaseRarity(uint256,bytes32)","25e37b2b":"delTournament(address)","25e3d3ba":"blockResult(uint64,uint64,uint64)","25e3d7b4":"assignSharedOwnership(address,uint256)","25e41da1":"getRandomValue(uint256)","25e524d3":"right8(uint256)","25e629f2":"fundraisingDelta()","25e65584":"getPlayerBossWannaCryData(address)","25e6c304":"totalPrizes()","25e6f516":"tokenDescription()","25e7514b":"remainAmount()","25e7c9ad":"getTotalAmountOfFirstInvestors(uint256)","25e7e3cf":"recoverAllEth()","25e89283":"mainSaleActive()","25e8f38c":"logUI(string,uint256)","25ea269e":"Scissors()","25eafb45":"AikcoinSupply()","25ede147":"depositSecretBid(bytes32,bytes)","25ee8abb":"winningTeamSet()","25eeecbc":"divisionByZero()","25ef9afa":"LOG_newSpinsContainer(bytes32,address,uint256,uint256)","25f08fc4":"decayedPriceOfTwitterId(uint256)","25f0f467":"updateTransferFeeRate(address,uint256)","25f0fd23":"_revoke(bytes32,address)","25f262c7":"draw(address[])","25f281b4":"changePriceSetter(address)","25f39a63":"div(int128,int128)","25f3da52":"GetBankAccountNumber()","25f3f2ef":"joinBuyRequest(uint256)","25f43ed5":"setMemsize(uint256)","25f4c703":"setFoundersPercent(uint256)","25f5cb1e":"getAllowedForTransferTokens(address)","25f5ec45":"getCheapestCardWager(address)","25f673f5":"Love(address,address,uint256)","25f731c8":"transferOwnershipBack()","25f885d0":"CashOut(bytes)","25f96b73":"ownerSupply()","25f9bfef":"CONTRACT_REGISTRY()","25f9f1e6":"lockOwnerBalance(uint256,uint256)","25fa0131":"isZero(address,string)","25fa5ae1":"createShapeShiftTransactionPost(string,string)","25fa8a4f":"_firstTokenId(address)","25fad06a":"clearances()","25fb439c":"POW33()","25fb66b9":"getHeroItems(uint256)","25fc575a":"deregisterToken(uint32)","25fc5f02":"HIPHOP()","25fc790f":"te()","25fcdad8":"complaint(address)","25fced01":"sellTokensPreIco()","25fd1e29":"REFUND_TIME_FRAME()","25fda176":"notify(address,uint256)","25fdb725":"MIN_CONTRIBUTION_ETH()","25feb519":"fifthTime()","25ff68dd":"Initialized(address,uint256)","25ffba04":"updateTokenStatus()","26000ba2":"updateBalanceOnFunding(uint256)","2601d1bc":"checkGameState()","2602bc8f":"_transfer(uint256,uint256,uint256,bytes32,string,uint256)","26030a34":"report(bytes32)","2603ace6":"unRegOwn(address,string,address)","2603f70c":"ownerDeclareRefundFinish()","26044feb":"fetchdivs()","26046743":"assetOwnerRemoved(bytes32,address,address)","2604b767":"getEggsSinceLastHatch(address,address)","2604f424":"FUTURE_DISTRIBUTE_LIMIT()","26052ef6":"getCurrentSolver(address)","2605b3c7":"participant(address)","26066ad5":"offer(uint256,bytes,uint256,bytes)","2606a10b":"report()","26070774":"Token(address)","26073003":"congratulationFromNoel()","26086c70":"triggerVersion(address)","2609037c":"requestArbitration(address,bytes32)","26091cbe":"OwnersBySpinner(uint256,uint256)","26093bbc":"safeIncrement(uint256,uint256)","26094c60":"setUnsoldTokensWallet(address)","260958a5":"getTransfer(bytes32)","260993f9":"registerSister(address)","260a5227":"buyOnBehalfWithSignedAddress(address,uint128,uint8,bytes32,bytes32)","260a54d3":"getCA(address,address)","260a818e":"unregister(bytes8)","260abfa5":"EnableMember(address)","260b0bc8":"payToOracle(uint256,uint256)","260b8f6e":"GetEvaluate(address,uint8)","260bf85a":"updateAmountToTakeAsRake(uint256)","260c2214":"setValid(uint256,bool)","260c3af1":"IcapTransfer(bytes32,address,bytes32,uint256)","260d387b":"blacklistUserForTransfers(address)","260e6885":"BazraCoinToken()","260e9640":"lock(uint256,uint256,uint256,uint256)","260ea6c9":"myDividendBalance()","260edaaa":"surplusTokens()","260f836d":"intercrypto_getInterCryptoPrice()","26109699":"Withdrew()","26111ab2":"addToSet(uint256,uint256)","2611341b":"submitApplication(address)","26119a0b":"changeFeeETH(uint256)","26121ff0":"f()","26134334":"getProjectKudos(bytes32)","2613ba9a":"PlatformDeposit(address,address)","2614195f":"getNameFee()","2614d4a4":"spendCredits(address,uint256)","2614fff6":"lengthOfCommonPrefix(bytes32,bytes32)","26161670":"donkeyRanking(uint256)","2616501d":"defaultRate()","261669ba":"HeroesToken()","26168eed":"getTestimonial(uint256)","261775f6":"BlokGrup()","2617fc13":"resetcardPrice()","26180224":"newChallenge(uint64,uint64)","261879ed":"addKitty(uint256,uint256,uint256[5])","26188437":"tokenReserved(address,uint256)","2618a571":"DEVELOPMENT_TEAM_CAP()","26195901":"numAnimals()","2619ba7f":"ETHFee()","261a323e":"exists(string)","261aa1c5":"additionalBonusPercent()","261ac279":"getApiByIdWithoutDynamics(uint256)","261b2c5e":"stepVestingDuration()","261b4205":"equalBytesToBytes(bytes,bytes)","261bd0f1":"BUY_BACK_BONUS()","261c085e":"registerChallenge(bytes32,uint256)","261c42dd":"getAllRevisionTimestamps(bytes20)","261cb08a":"burnPausedTime()","261de7c4":"right33(uint256)","261e9693":"balances4(uint256)","261eafc8":"addMasterTo(address,string,string,string,uint8,uint8,uint8,uint8,uint8,uint8,uint32,uint32)","261ed1d8":"farmCities(uint256)","262006e9":"getFirstDocumentIdBetweenDatesValidFrom(uint256,uint256)","262007c0":"getBetter()","26207bd1":"indices(int128)","26208591":"payDividendsTo(address)","2620f61c":"storeClaim(uint16,address,uint256)","2620fb2b":"getNextTime(address)","2620fd4a":"setupICO(uint256,uint256,uint256,uint256)","262199c3":"changeTokenOwner()","2621b6e3":"finalStageRefund()","2623297e":"zt()","26232a2e":"platformFee()","2623f687":"getRevenue(uint256)","2624597c":"createTokensForEvent(address,uint256,uint256,string)","2624b2d9":"EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH()","2624c4eb":"EtheremonEnergy(address)","2625e2e1":"post(address,address,bytes32)","26278f86":"unrestricted()","262799f7":"PaquariumTokenTest2(uint256,string,uint8,string)","262834da":"_addOperator(address)","2628803f":"migrateREP()","262933cb":"responseFromWS(address,uint256,bytes32)","26295b52":"createGalaxy(uint8,address)","262aa9fc":"DOGToken(uint256)","262af333":"sponseeAddress()","262af3dd":"getClassViewValue(uint256)","262b9f8c":"finishRoundA()","262bcb68":"mintBooster(address,uint32,uint8,uint8,uint32,uint24)","262c0b72":"getPayoutFreezePeriod()","262c3666":"forward(bytes32[],uint8,bytes32,bytes32)","262da6df":"TransferOwnershipOperationEvent(address,uint256)","262f8244":"HGSOCIAL(uint256,string,string)","262f8c0e":"addTimelock(address,uint256)","262fe547":"testCheckSavecEthBalance()","2630271d":"setlockaddress(address,bool)","2630c12f":"priceOracle()","2630d97d":"setAtomLev(uint256,uint8)","2630ee9f":"revealBid(bytes32,address,uint256,address,address,address,uint256,uint256)","2630ef36":"setNumOfTimesSteal(uint8)","263164b9":"getSalaryTokensTotalCount()","26316e58":"setMigrationMaster(address)","26324eff":"producers(address)","26325bd3":"allowEveryone()","2632924d":"left30(uint256)","2632bf20":"unblockMe()","2632fc3c":"MichiganvsLoyola()","2634592a":"logReportsDisputedCalled()","26345de2":"VendingMachine()","26348325":"smartContactForSale()","263570c0":"addStorage(string,address)","2635f4de":"registerLibrary(bytes,address)","2635f59f":"InterfaceToken()","263631b4":"euroCents2wei(uint256)","2637bb2e":"isTransferProxy(uint32,int256,address)","26381b05":"canReceiveTokens()","26387b07":"Fortune()","2638b25c":"seedEndTime()","263a6d79":"initiateTransaction(address,uint256,bytes)","263b694a":"MIMIMUM_CONTRIBUTION_AMOUNT_ICO()","263c0a8d":"_setLagParams(string,uint16,uint8)","263c493a":"enable_deposits(bool)","263c6ec0":"usdToTokens(uint256,uint8)","263ce6a0":"getWinningPrediction(address)","263d4878":"triggerRefund()","263d5ad0":"vaultPercentage()","263dffba":"_releaseVouchers(address,uint256,uint16)","263e3d5d":"terminateContract(uint256)","263e6d0d":"INDOPAY()","263e74e6":"computeBonus(uint16)","263e79b5":"addCreditScore(uint256,string)","263eb5b6":"assertEq8(bytes8,bytes8)","263ef0cf":"needRefoundETH(address,uint256)","263f6a42":"rateFeesNumerator()","263fa1ad":"XYZToken()","263fbd45":"getContractUpdatedTimeById(bytes32)","263fbef2":"District0xNetworkToken(address,address)","263ff8b9":"buildTokenId(uint256,uint256,uint256)","26407e36":"calculateSharesInTheRevenue(uint256,uint256)","26409047":"BDACoin()","2640b401":"SetRate(uint256)","2640f62c":"getTokenToEthOutputPrice(uint256)","26413760":"reducePlayersGooProduction(address,uint256)","2641d381":"totalNumberTokenSold()","26423259":"viewCoinSupplyAndFunding(bool)","2642567e":"coinData(address)","264282f2":"markTokens(address,uint256)","26428430":"_deleteInt(bytes32)","2643fc13":"spermlordReq()","2644f9f8":"getAssetsOwners(uint256)","26452036":"InitCountry(uint256,uint256)","264534be":"OMC(uint256,string,string)","26458beb":"firstPreSaleDate()","2646754d":"TestTokenA()","2646b176":"getPaimentStatus(address,uint256)","2646bce6":"LogWinner(uint8)","2646bfcb":"pay(uint256,uint128,address,bytes)","26470ae4":"getBonusFactor(uint256)","26476204":"stake(address)","26483bcd":"tokenMultiTransfer(address)","26484a44":"start3XPhase()","26487265":"contractExecuted()","26488531":"banMember(address,string)","2648a7e2":"EtherRedeemAccepted(address,uint256)","26493a6f":"setAllocateAgent(address,bool)","26496cab":"Milestone_IcoSuccessful(string)","2649cb10":"pNumberOfLockedTokens(address)","2649d62e":"multiMint(address,uint256)","264a3edc":"setPolls(address,address)","264a6d10":"get_next_asset_document_from_document(bytes32,bytes32)","264ae918":"withdrawChannel(address,uint256)","264b2b8e":"returnBalance(address)","264c22bb":"getAmountOfGene(uint256)","264c2cdc":"generateRandomNumber(address,uint8)","264c8e9a":"whatWasTheVal()","264caf14":"addVestor(address,uint256,uint256,uint256)","264d26e1":"ICO_CAP1()","264d7797":"tokensBought(address)","264dac0f":"endBorrowAgreement(string,uint256,uint256)","264e3018":"EtherDeltaHandler(address)","264f28fe":"getOwnerDeposit()","264f5718":"rondaSilla()","264f630d":"DonationReceived(address,uint256)","264faeb8":"getReportsCounter(uint256)","26500c84":"ResolverNode()","265028c2":"GetMaxBuyIn()","2650a47c":"withdrawEther(uint256,uint256)","26529836":"ADVISER_STAKE()","2652b4a5":"UDA()","2652c0f4":"hasVerifiedAttributeValue(address,uint256)","2652c757":"submitBracket(bytes32)","26532df8":"subZero(uint256,uint256)","2653ab19":"getMC(uint256)","2654e624":"ResumePayment()","265580f5":"setRegistryExecID(bytes32)","2655dd0b":"storeId(address,address,uint256)","26563b40":"whitelistManager()","2656455f":"claimEthFor(address)","2656b77d":"addToBattle(uint64)","26571388":"xpaExchange()","26591e79":"BONES()","2659d8ef":"setExchangeFormula(address)","265a3afd":"registerBase(bytes32)","265a8636":"_mintFish(address,uint32,uint8,uint8,uint8,bytes16)","265af6d1":"withdrawFundsAndPayRoyalties(uint256)","265b3e6c":"calculateIssueGoldFee(uint256,uint256,bool)","265b5d93":"getMaxLockAmount(uint256,uint256)","265c920f":"setBonusParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","265cdd88":"Bet(address,string,uint256)","265cfbbc":"Emitter()","265d900b":"wtech()","265dcbd3":"StandardTokenWrapper(address)","265f0393":"KryptopyCrowdsale(uint256,uint256,uint256,uint256,uint256,address)","265ffe2b":"ethMin()","26602470":"hashEIP712Message(bytes32)","2660316e":"plyrNames_(uint256,bytes32)","26605772":"renameTulip(uint256,bytes32)","2660b56c":"setData_2(string)","26617c28":"_setPaused(bool)","26625e46":"formatDecimals(uint256)","26627d80":"third_whitelistSupplier()","266361f5":"getLottoData(uint8)","26637579":"_removePlayer(uint256,uint256)","26638a38":"spin(int256)","2663a4ed":"byteToLower(bytes1)","26654d57":"refundParticipant(address,uint256,uint256,uint256,uint256)","266578d0":"_isRateActual(uint256)","26657c77":"Validate(string,string,string)","26663203":"withdrawFromEscrow(address,bytes32)","266710ca":"manualUpdateBalances_only_Dev()","266716f6":"GTSToken()","2667f407":"__proxy(address,bytes)","2668748d":"applyAuditorsCheckUpdate(address,address,uint64)","2669268b":"FUC(uint256,string,string)","266987ef":"p2pLocker(address)","26699576":"playSystem(uint256,address)","266b059e":"setSendAmount(uint256)","266b2eb5":"Conserve()","266bd375":"MyPizzaPieToken()","266c2132":"_prand()","266cc170":"Y2J()","266ce248":"createPlayer(uint16)","266cf109":"record()","266d7bda":"lockupEndTime()","266d8299":"DriveholicToken()","266fc436":"producedSilverCaps()","266fc5d5":"totalContributorsProfit()","2670bdf0":"setERC777(address)","2670cc14":"transfekbolPlutocrat(address)","267127ec":"getTokenSettings()","267177eb":"sendPayout(bytes32,uint256)","2671b61d":"OfferRouting(bytes32,bytes32,uint256,bytes)","2671e253":"resetTraps(uint256)","26728b14":"rewardPXL(address,uint256)","2672b3e2":"SplitterEtcToEth()","2672c952":"seed_coins()","26735c06":"TOTAL_POOL_COMMISSION()","26736363":"APRInflationToken(uint256)","26741c88":"IcoMessage()","26744071":"WLCoin()","26745909":"PRNG_Challenge()","26746f5f":"updateGenerationRatio(uint256,address)","26748804":"BlockPoints()","2674899b":"getSaleHour(uint256)","267490aa":"turnOnPresale()","26749ad7":"approvedContracts(address)","267502c9":"setAquarium(address)","2675c123":"CloseContract()","26760d1d":"setMaxTms(uint256)","26767298":"RimuoviMiner(address)","26767cfe":"shareProfits()","26768b83":"_emitDestruction()","2677ef1b":"_seal(address,address,uint256)","26782247":"pendingAdmin()","267822c1":"finalizeChangeBurnBounds()","267835a4":"_removeBurner(address)","26798494":"EusdContract(address,address,address,uint256,uint256,uint256)","26798680":"toReal(int216)","267acd6c":"getPricesPerInterval(uint8)","267b6922":"entries(bytes32)","267c4ae4":"exists()","267c8507":"authorizeManager(address)","267f20a2":"_transferTo(address,uint256)","267ff78c":"approveRequestUnpause()","26811c09":"NVBToken()","26815de3":"updateGoldPrice()","2682644f":"PURCHASE(address,uint256)","26826bf8":"setImage(bytes)","2682a0ac":"CrowdsaleTokenExt(string,string,uint256,uint256,bool,uint256)","26834988":"numListed()","26839e53":"getUintValues(bytes32)","26839f17":"depositEther(uint256)","26843251":"presale1_startdate()","268451a2":"testFail_set_price_unauth()","26848a86":"setPicture(string)","26848b68":"checkCrowdsaleBalance()","26866160":"secondsBetweenReadings()","2687c645":"contributeInternal(address,uint256)","26881518":"setupFee(address)","2688454a":"U()","268855a4":"ParsecCrowdsale(address,address,address)","26887303":"TourCashStandardToken(uint256,string,uint8,string)","268959e5":"removeAdmin(address,address)","268a4559":"competitionStatus()","268b0459":"getRecordBalance(address)","268b5344":"PlanetOfOwner(address)","268b946c":"toUint8Throw()","268bb78e":"propose(address,bytes,uint256,uint256)","268bc65d":"signatureDropMultipleAmount(address[],uint256[])","268c969a":"emergencyDrawingReset()","268cb5f7":"queryCost(address[])","268d50fe":"ownerSetHouseEdge(uint256)","268da061":"CRFtoken()","268e7075":"toBytes2(bytes)","268ea7f6":"ReInvest(uint256)","268eb055":"setDescription(uint64,bytes)","268ef7e8":"holdAddress1()","268efdaf":"StdInt64(int64)","268f1153":"changeState(uint8)","268fe426":"dailyReset()","2690f0d5":"foundationLock()","269106e9":"dayCycle()","2692281d":"requestChangeBurnBounds(uint256,uint256)","2692de22":"sendAllFunds(address)","2693c150":"getPlayersTickets(address)","2693eca0":"devSFTDestination()","2693ed9b":"calcTokenSold(uint256)","2693ee80":"bonusPool()","269445db":"phase_6_rate()","26949220":"withdrawWonCosFromGame(uint256,uint256,uint256)","2694f6bb":"Log1_fnc(address,bytes32,uint256,string,string,uint256,bytes1,uint256,uint256)","26961b8c":"Token99chain(uint256,string,uint8,string)","26965dad":"deployStepOne()","269695fe":"groomVow()","269714dd":"maximumTarget()","269724ef":"assertEq6(bytes6,bytes6)","26976e3f":"upgradedAddress()","26987b60":"currentIndex()","269975d0":"GameDetails(uint256)","2699a7e7":"setPOOL_edit_31(string)","2699c808":"tradeOption(address[3],uint256[3],uint256[2],bool,uint256,bool)","269a7c3f":"buyAndTransfer(address,address)","269aacc8":"getDividendPayout(uint256,uint256,uint256)","269b0737":"DaoCasinoToken()","269c4bca":"viewFoundersTokens()","269c6ece":"lockedTwoHasEnd()","269cdaac":"withdrawLockedTokens()","269de5a0":"EpicExchange()","269e4f3c":"refundWei()","269eb58c":"setFeeFromPayer()","269ecc6d":"backersAddresses(uint256)","269ecf28":"submitBuyOrderWithPosition(bytes32,uint256,uint256,uint64,bool)","269f4663":"approveMintTokens(address,uint256)","269f96c9":"presaleSoldTokens()","269fe82e":"calcBurnAmountFromFeeBurner(uint256)","26a09392":"addSecondaryAddress(address,address)","26a1529e":"amountOfStakeReturnedOnCancellation(uint256)","26a18375":"setAvailability(bool)","26a21575":"tokenRaised()","26a26f71":"TgeTeamReleasingScheduleContract()","26a3bd4e":"subtractBalance(address,address,uint256)","26a3f45d":"initOwner1(address)","26a4861c":"CROWDFUNDING_PERIOD()","26a49e37":"price(uint256)","26a4c847":"maxLendingItem()","26a4e8d2":"setTokenAddress(address)","26a52019":"agentMakeOrder(address,address,uint256,uint256,address)","26a65c10":"createDigitalArtFee()","26a6dfed":"toogleTransfers()","26a7985a":"getMaximumCallGas()","26a82e8b":"autoPreSaleSuccess(address,uint256)","26a8d1e5":"_changeManagerImpl(address)","26a934f5":"minResalePercentage()","26a9408c":"returnTokensFromHoldBountyAddress(uint256)","26a9de53":"verifiedTransferFrom(address,address,uint256)","26aa101f":"isTokenRegistered(address)","26aa7c58":"addBuyer(address,uint256)","26ab378b":"addMood(string)","26abc9ab":"CmctSale(address)","26abfe09":"burnUndistributed()","26ad3abc":"startTimeStage3()","26ad7b40":"_doesEveryTokenHaveLockupPeriod()","26ad8d1b":"getPositionStartTimestamp(bytes32)","26ae27d6":"lonmemay()","26aeba91":"FarziTokenSale()","26aebfac":"delPack(uint8,uint128)","26afe980":"queryOracle()","26b238d8":"doom()","26b3293f":"deposit(address,uint256,bytes32)","26b387bb":"pendingReturns(address)","26b3a6f8":"SelfKeyToken(uint256)","26b41613":"processFunding(address,address,uint256,uint256)","26b45b09":"rateTier4()","26b4ce7f":"NP(uint256,string,string)","26b51c8c":"finalBlock()","26b52faf":"firstWithdrawAmount()","26b66cb7":"amendedEarlyPurchases()","26b6c0b4":"settingsSwitchTransferAccess()","26b7d803":"getTotalBuyCount()","26b7fe35":"GainStuff(address,uint32,uint256)","26b85ee1":"myAddress()","26b85f0d":"mininumContributeUSD()","26b916b4":"Set_Interest_Rate(uint256)","26b92a0e":"SomniumToken()","26b93939":"Jokercoin()","26b9ce13":"setTransfersEnabled(bool)","26ba1c19":"addBagAndGiftAtTime(uint256,address,uint256)","26ba2e47":"paidETH(address)","26ba4319":"setDirector(address)","26baca1c":"getStats2()","26bca0f8":"get_my_info()","26bceb59":"mul256(uint256,uint256)","26bd4d96":"adPriceMultiple()","26bd78b9":"LogEvent(uint256,address,bytes4,bytes,uint256,uint256)","26bdd20b":"getNominatedMediator()","26bdd814":"refundPresale()","26bf02cf":"getBaseLevelUpFee()","26bf2051":"KickCommitteeVoteEvent(address,address)","26bfcde0":"GMCToken()","26bfd35c":"rewardAD()","26c009cb":"privateIcoSold()","26c0ad3a":"allowRefunding(bool)","26c19eba":"readValue(bytes32,uint8)","26c1e750":"planets(uint256)","26c21722":"getwithdrawEtherToAddressValue()","26c2bcb4":"checkBenefit(address)","26c30b50":"BITS(uint256,string,uint8,string)","26c32ff5":"demi(uint256,string,string)","26c387fa":"testFail_mint_without_add_authority_to_controller(int256)","26c3d6f8":"get_deposit_term(address,uint256)","26c435a9":"totalUsdFunding()","26c43d8f":"hodlerTotalCount()","26c47909":"SXCToken()","26c4b863":"XIOToken()","26c4fa3d":"setOfficialGameUrl(string)","26c5c154":"employeeAddress()","26c6d361":"FanCoin()","26c7edaa":"flip4(bytes)","26c81320":"lastgamewinner()","26c93389":"removeFreezableAddress(address)","26c989df":"holdBalance()","26c9959f":"LoveToken()","26c9bc42":"setTokenInformation(string,string,uint256)","26c9e547":"bestow(bytes32,uint256,address)","26cb2257":"outRate()","26cb83b9":"setDescrutionContractAddress(address)","26cbb8ff":"inviterRegister()","26cbe6f5":"getHeroAvailableAt(uint256)","26cc2256":"blockRewardAmount()","26ccd77a":"withdrawStuckEther(address)","26ce3da0":"collectRefund()","26cee3a7":"getPlayerId(bytes32,bytes32,address)","26cf53b9":"BTL_PERSIAN()","26cf660d":"trustedOrderbook()","26cf9165":"pixelgrid()","26cfc76f":"TriPinCoin()","26d0d75a":"ResolutionProposals(uint256)","26d111f5":"note()","26d29ce0":"refundBid(uint256)","26d2b840":"addDadRelation(address)","26d2cba5":"updateMetaData(bytes32,bytes32,bytes32,uint256,bytes32,bytes32)","26d2eb11":"stopPostIcoAndBurn()","26d312f7":"sendWebGiftToken(address,uint256)","26d3325d":"getExpectedPayment(uint256)","26d3bde5":"execCUSEOption()","26d3df61":"deedsOf(address)","26d3e7e8":"inititalSupply()","26d3e889":"testCreateWithParentsForeign2()","26d3ed0a":"isSpentCustomerTxPaymentForMCW(address,bytes32)","26d541b0":"totalPlayerCount()","26d64f3b":"readTeam(bytes32)","26d6eca3":"retrieveReward(uint256)","26d7b3b4":"unRegister()","26d83db8":"LoveYToken(uint256,string,uint8,string)","26da8e17":"ownerUpdateCostToCallOraclize(uint256)","26db3c0a":"tokenIssue(address,uint256)","26db7648":"proposedVersion()","26dcbcfc":"catPaymentCollector()","26dd1510":"pixelblockPrice(uint24,uint24,uint24,uint24)","26dd860a":"mintUniqueTokenTo(address,uint256,string)","26ddaebc":"getPriceWithBonus()","26dec45e":"getUserUsername(address)","26defa73":"addAuthority(address)","26df61f6":"permittedContractsCount()","26dfb6b4":"advteamPool()","26dfe583":"partialDivest(uint256)","26e010c8":"minInitialMarginAmount()","26e137c2":"getInterfaceImplementationStatus(address,bytes4)","26e23485":"renamingCostsPerChar()","26e33670":"NewQuiz(string,bytes32)","26e41a3e":"airdropTokens(bytes32,address[],uint256)","26e43db5":"TransferSell(address,address,uint256,string)","26e501a8":"BitonlineStore()","26e56c05":"SaleCapReached()","26e5ab38":"changeMaxWithdraw(uint256)","26e5afdf":"Yinfiniti()","26e5b0be":"stopMulti()","26e6050d":"setParamsIco(bool)","26e6074b":"frozenBalance()","26e683fb":"NotitiaToken()","26e72d31":"resetCurrentRoundSales()","26e770e9":"Information()","26e77179":"PaymentRefunding(uint256,address,uint256,string)","26e80650":"upPlayerRound(address,uint256,uint256,uint256,uint256,uint256,uint256)","26e89689":"applyForCertifition(address,string,uint256,string,uint256,bool)","26e8cd23":"bobMakesEthDeposit(bytes32,address,bytes20,bytes20,uint64)","26e90775":"calculatePrize(uint256,uint256,uint256)","26e97fce":"allowMint(address,uint256)","26e9fd9e":"remove(bytes20)","26ea66bf":"Mortal(address)","26ea74e2":"approvedDividendsOf(address)","26ea7ab8":"changeadmin(address)","26ea9268":"FEE_SELECT_MAX_VALUE()","26eaee92":"devReward()","26ebc8af":"UserAuthorizedForToken(address,address,address)","26ebe0bf":"totalCentsGathered()","26eca77c":"HelloGoldRound1Point5()","26ed274e":"decreaseBurnApproval(address,uint256)","26ed794b":"mobilinkTeamAddress()","26eda1ac":"putMessage(string)","26ef8ba1":"putEth()","26f08aec":"setotherchainstotalsupply(uint256)","26f09042":"testThrowNoFreeTokens()","26f1069f":"approvePresale(address)","26f21080":"allowedToTransferOf(address)","26f2458a":"RequestP(bytes32,bytes32)","26f35ff2":"activenessUpgrade(uint256,uint256)","26f3ceaf":"TSToken()","26f4739e":"LogBuyTokens(address,uint256,uint256)","26f489f6":"_updateCardPerkText(uint256,string)","26f4b3de":"userTakeOrder(address,address,uint256,uint256,address)","26f590f6":"setAttribute(string,string,bytes)","26f59b8b":"ProICOHardcap()","26f6ec3b":"getCities(uint256[])","26f743d0":"createGuess(uint256,uint256,uint256,uint256)","26f78835":"XXXChain()","26f86791":"_indexOf(string,string,uint256)","26f8abf9":"getRankOnePlayer(address)","26fa9082":"Enumivo()","26faae42":"addChild(address,bytes32,bytes32)","26facdb1":"TeamTokenDistribution(address)","26fae0d3":"setMaster(address)","26faf1e9":"SVLightIndex()","26faf9c2":"EatMeCoin(address)","26fc4c7f":"returnTokens(address,uint256)","26fd8422":"calculateEggBuy(uint256,uint256)","26fdb484":"OwnershipRevoked(address,address)","26fe18e2":"setMintingOracle(address,address)","26fe2024":"newRate(string)","26fe7cf2":"createStar(uint8,uint16,string,string)","26fe9951":"delegatedFrom()","26feba74":"MaorTestCoin()","26fed988":"addCancelledOrFilled(bytes32,uint256)","26ffa189":"setEnableWhiteList(bool)","2700615c":"_getShipInfo(uint256)","27018631":"icoBonus()","2701d40f":"ForSale()","2701ebd8":"NDT3()","27028aae":"voteOnBounty(uint128,uint256,bool)","27029e83":"BurnToken(address)","2703506f":"CouponDeposit(address[2],uint256[8],uint8,bytes32[2],uint256)","2703e545":"projectInfoPublic(address)","2704355c":"setGenesisCallerAddress(address)","2704e8e9":"addRemovableIdArrayItem(address,uint256[],string,string,string,address)","2704ead4":"_isValidSkin(address,uint256,uint256)","27053417":"_updateSeed()","270537c0":"lockReserveTokens(address)","2705ce6a":"setAuditorDelegate(address)","27066ebb":"getOwnedTokensIds(address)","27071f6a":"_tokenOfOwnerByIndex(address,uint256)","270835d0":"allocateBid4a(bytes32)","2708a710":"MintHelper(address,address,address)","2708db73":"requestLeave(uint256,string)","270a3856":"startDist()","270a5420":"buyFST()","270a8ef7":"existingMarketOrder(uint256)","270abf36":"getChickenAmount()","270ba309":"getRegistryDataInitialized()","270bb8ad":"setImmigration(address)","270bfc07":"fundingAccount()","270cf206":"ENSReverseRegister(address,string)","270cfee1":"getTokenAccount()","270d13fb":"isCoinIdUnique(uint16)","270dc9fd":"changeName(string,uint256)","270e4cf0":"buyerAddressTransfer(uint256,address,address)","270ef385":"CLAIM_AMOUNT()","270f611f":"burnBalances()","270f7219":"getJntController()","270f9359":"Exploit(address)","270fdd1a":"GricCoin()","27120de9":"numberOfStarsReserved()","27121069":"verify(bytes,uint8,bytes,bytes)","27121b76":"claimDailyLoot(uint256)","2712d916":"setSanTTTCost(uint256)","27132be6":"getCustomBuyerMappingCount(address)","27136e46":"changeTransactionService(address)","2713a1b4":"getUserWithdrawnBalance(address)","27150f01":"devFeeSize()","27151526":"nextBid()","27158b7b":"MFToken()","271619fb":"CreateContract(int256,int256,uint256,uint256,int256,address,string,uint256,int256,string,uint256)","27164f15":"getBuyOrdersInfo()","2716783d":"distributeERG(address[],uint256,uint256)","2716baa6":"startContruibute()","271761c0":"EventSuccessfulTraining(uint64,uint64,uint64)","271781ad":"getRestSumStageICO()","2717cc7c":"ParticipatedInVoting(address,address,bytes32,uint256)","27180e42":"wantItMoreThanYou(uint256)","27187991":"setEtherPrice(uint256)","271a50db":"setAgonFight(address)","271af8c1":"tokenCollector()","271b3e8a":"snakemasterReq()","271b5311":"getValidateSignatureAddress(address,string,uint256,uint8,bytes32,bytes32)","271bac4a":"setBonusPhase(bool)","271c34d7":"denyProposal(uint256)","271cacbf":"batchAddToWhitelist(uint256,address[])","271cd760":"getPackageDb()","271d9090":"HenryToken()","271dd15b":"getWinNumberAddress(uint256,uint256)","271dec50":"Invested(uint256,address,uint256,uint256)","271df6e5":"canLotteryFree()","271f88b4":"setAmount(uint256)","271fe8be":"buyNormal(address)","2720e4f6":"LC()","27213345":"totalSupplyToken()","2721a114":"queryWinner(string)","2722692c":"lastBlockSet()","2722c043":"raiseEventIfMinted(address,uint256)","27234ecc":"takeBalance(address,address,uint256,address)","2723639b":"getPixelAreaColor(uint256,uint256,uint256,uint256)","2724312a":"Micropayment(address)","27243160":"bookmark(string)","2724e032":"manualEndDay()","27258b22":"isRegistered(bytes32)","2726403a":"testCanTrade(address,address)","2726a530":"getHodlHasBeenWithdrawn(uint256)","2726b506":"getDeposit(address,uint256)","2726f061":"commitVotes(address[],bytes32[],bytes32[],bytes32[])","27270550":"swapAble(bool)","27275a35":"SuretlyToken()","2727d018":"PlusPayLite()","272870ac":"pausable(bool)","27295d7c":"updateMaxPhase2(uint256)","2729f44e":"addTxToRegistry(bytes32,bytes32,uint256,uint256,uint256)","272a33e8":"allocateBid2(bytes32)","272a3e16":"PlayerWon(uint256)","272a847f":"HAICrowdsale(uint256,uint256,uint256,address,uint256,uint256)","272ae0b5":"MIMIMUM_CONTRIBUTION_AMOUNT_PREICO()","272caf69":"stakeContractAddress()","272cda88":"EternalDB()","272d20e7":"amount_direct()","272e20fa":"__abort__()","272edeac":"currentMineTokenAmount()","27301964":"withdrawDevTokens(address,uint256)","2730e4a2":"_arrangeMasternodeFlow()","273123b7":"delBot(address)","27315b5f":"Settlement(address,address,uint256,string,string)","27329380":"getRecentPlayersCount()","27329b05":"enableBot(address)","27332624":"_lottery(uint256,address,address)","27341c8a":"isEmpty(string)","2734242b":"BunnyToken()","273696cd":"SetImplementation(address,address)","2736a558":"removeBackdoor()","2736f6d9":"setTokenAndRate(uint256,uint256)","2737033f":"initialize(address,uint256,uint256,uint256,uint256,uint256,address,address)","27374015":"functionFive()","27378684":"price4()","27380c2c":"updateAngelCardSeries(uint8,uint64,uint64)","2738154e":"checkRokBounty()","2738bf4d":"addLeaderboard(string,string,uint256)","2738ed25":"Player_Bettings(uint256,uint256)","27393390":"setTokensMultiplier(uint256)","273a041c":"_self()","273a5729":"eligibleTokens()","273afe15":"ParisToken()","273b1dd3":"RealMadridvsLiverpool()","273b1fb3":"betbucketOne()","273b465b":"verifiedAgeOver(address,uint256)","273ba6bb":"ICO()","273bc3c9":"numberOfThrones()","273ca81c":"getMegaBalance()","273cb593":"isMasterOfCeremonyRemovedPending()","273cbaa0":"getTokenList()","273cc2a5":"depositOpen()","273dd51f":"_distributeHorse()","273e2c78":"F2UPay()","273ea3e3":"incrementNumber()","273f1de7":"paySellerFee(bytes32,address,uint256)","273f4940":"set(bytes32,uint256)","273f9ace":"getNumbers(bytes32[])","273f9bed":"signedTransferFromCheck(address,address,address,address,uint256,uint256,uint256,bytes,address)","273fd520":"EthlanceFeedback(address)","2740509d":"urbitTeamTokensVault()","2740e64b":"getInitializeParentPayoutDistributionHashValue()","27413437":"grantFounderToken()","2741876a":"totalPresses()","2742d511":"setWhitelistedStatus(address,address,uint256)","27436b59":"getCarCount()","274465b4":"payForMyself(uint128)","27457b3b":"getMyInventory()","27458664":"enableTokenMinting()","274748e6":"setInactivityReleasePeriodForToken(address,bool,uint256)","2748503f":"ChangedOwner(address,address)","27486a7c":"combineCards(uint256[])","2748d7e4":"claimPlotWithData(uint256,string,string,string,string)","2749bd81":"getTimestamp(address,uint256)","274a1f29":"setNextLotteryTTMTokenId4(uint64)","274a9b1c":"addressToEtherContributed(address)","274acb35":"add(uint96,uint96)","274b1615":"keyValidations(address)","274b3df4":"deposit_eth()","274b9bc5":"ETHx2()","274bc107":"test_threeValidEqBytes()","274c343a":"HTCCToken()","274c7922":"privilegedAddress(uint256)","274db4d6":"_price_tokn_PRE()","274ed288":"debtBalanceOf(address,bytes4)","274f97bb":"buyReply(uint256,uint256)","274faa9f":"minContributionUnits()","274fadf6":"updateServiceDescription(address,uint32,string)","274ff7ce":"burnFrom(uint256)","27506099":"getCountPlayersOfOwner(uint256,address)","27507458":"isLive(uint256)","2750fc78":"setIsActive(bool)","275103fd":"hault()","27521702":"mint(int256,address,uint256,bool)","2752808a":"CAPcoin()","27538e90":"getCapabilityRoles(address,bytes4)","2753d7f2":"artworksFactory()","2753f254":"workedTodayInSeconds()","2754ff69":"test_2_ensureProposalExecution_increaseBlocksBy100()","2755a13b":"forceClose(uint256)","2755cd2d":"tip()","275601f6":"getAllProviderParams(address)","27566b80":"transferCollectedEther(address)","275676cf":"ClassicVolkswagen()","27567c4c":"setIsPoop(string)","2756d38a":"IonChain()","27571087":"getBonus(bytes32,uint8)","2757a07c":"SSDDTT(uint256,string,string)","2757e976":"transferredIndex()","2758743c":"LATINOToken()","27589224":"minBuyingRequestInterval()","275893a9":"updateMaintenanceAddress(address)","27593eee":"ChangedName(address,string)","27597f0a":"costForProductCycles(uint256,uint256)","2759ea4a":"lookupSprite(uint256)","275a1334":"buySellPrices()","275a329a":"BCASToken(uint256,string,string)","275a92cf":"TokenPurchase(uint256,uint256,address,address,uint256,uint256)","275acbe3":"ln(uint256,uint256,uint256)","275b6eb0":"calculateSeedSell(uint256)","275babee":"getRareInfo(uint256)","275be02c":"MRBLToken()","275bf230":"addAddressToAccount(address,address)","275c82ca":"GasUsed(uint256)","275cb687":"setNextPoolPercentage(uint256)","275ccb13":"computeLeaf(uint256[],uint256)","275d60bc":"getReturnAddress(address)","275e2d3f":"st4ckCount()","275e2f86":"MORCoin(uint256,uint256,uint256,address)","275e5da5":"probe(address)","275f3d92":"view_readyTime(address,address)","27608c24":"unsoldToken()","2760c57e":"lastPing()","276184ae":"erc20Address()","2762484a":"SBIToken()","2762cf10":"contract_transfer(uint256)","2763d8fb":"FabCoin()","2765faae":"MaximalInvestmentTimeTresholdChanged(uint256)","276605bc":"updateFundingStartBlock(uint256)","27669781":"emitInfo(uint256,uint256,address,uint256,uint256)","27678dca":"getHWCAddressCount()","27687d34":"advisersTokenTimelock()","276927c5":"sellSpaceship(uint256,uint256)","2769b96b":"updateItemPrice(uint256,uint256)","2769c89a":"setGameStartTime(uint256)","276a28a3":"isTokenLocked(uint256)","276b94e1":"copypaste()","276bf637":"isTimedout(uint256,uint256,uint256)","276c9d0a":"balanceOfOld(address)","276cd2e8":"BTTPERETH()","276e3968":"bits(uint256,uint256,uint256)","276e6472":"deleteById(string)","276ebc6a":"ChargeTest()","2770a488":"transferWithIndex(address,uint256,uint256)","2771083f":"setSpreadPercent(uint256)","27729e93":"openLottery(uint8)","2772dffd":"votes(bytes8)","27731e77":"setCCH_edit_9(string)","27734225":"getCommitteesNumber()","2774d052":"mintPresell(address,string)","277576ca":"theTurn()","27757c49":"isVariation()","2776a859":"computeResponseSecondHalf(uint16)","2776b163":"setstoredaddress(address)","27773ba2":"addrAirDrop()","27782e42":"refreshActiveShareholdersArray()","27783050":"getEntryHash(address,uint256,bytes32)","27793f87":"outcome()","277942db":"marriageLicenceImageIPFShash()","27796092":"t4tToken()","2779ea96":"addPostOnBoard(address,address,address)","2779eb52":"setUserRank(address)","277a6889":"calculateInterest(uint32,uint256)","277ad1f6":"amountSellForOneEth()","277ad5d8":"secondRoundMayDiscount()","277ad6d4":"PreSaleResumed()","277b2db6":"getPlayerVaults()","277b6527":"targetCrowdsale()","277b8ffc":"getBeneficialAddress()","277ccada":"unlistTrophy(uint256)","277ccde2":"getHKGPrice()","277d4725":"getEthereumToken()","277e1b16":"changeMaxDonationLimit(uint256)","277e1de7":"transferAccessory(address,address,uint64)","277e268e":"testFail_set_label_unauth()","277ea83d":"getTrustPlatform()","277f6331":"ETVRToken()","277fc0e9":"getSignature(address)","277fc17d":"daysToSeconds(uint256)","277fef99":"transferPoint(uint32,int256,address,bool)","27806a16":"DoxCoin()","2780d22b":"getMigrateMarketInFromNiblingCalled()","27810b6e":"burner()","27815883":"_setHairValue6(uint256)","27816235":"onSaleEnded()","27816932":"AdaptableToken(uint256,uint256)","2781c3d1":"ownerSetdiceRollAddress(address)","2782ca8d":"MINIMUM_PURCHASE_IN_USD()","27836f77":"setImageData(uint256)","2784ad48":"computePayment(uint256,uint256)","2784d868":"getMiniPoolEdit_2()","2784e3f3":"refundVotingTokens(address,address)","27854452":"allocateAgents(address)","2785ed21":"LogCertificationDocumentAdded(address,bytes32)","2785fb98":"getContributionETH(address)","27860587":"TXToken()","27869c57":"gluon()","2787fac2":"LordCoinPreICO(address,address,uint256,uint256,uint256,uint256)","27880e1f":"KyberNetwork(address)","2788f4f3":"OraclizeCallback(bytes32,string)","2789192f":"isConfirmedSettingsRequest(uint256)","27895f13":"_advanceClock(bytes32,uint256)","27899ce2":"allowNewReceiver(address)","27899d9b":"LGOToken()","278a3684":"advisorAmount()","278a4c4f":"setMasterToReferral(address,address)","278a5e7c":"cancelScript(address)","278ab692":"startDispute(address)","278af72c":"isSaleClockAuctionStorage()","278b8c0e":"cancelOrder(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","278bb4a2":"EthealDeposit(address,address)","278bee92":"_receiveMakePlant(address,uint256,uint256)","278c284c":"CrowdsaleToken(string,string,uint256,uint8)","278c3030":"phase_2_Time()","278c688e":"getBackToken(uint256)","278cc714":"getUsablePlayerFibokens(address)","278d6e5b":"funcArrayInArguments(address[],address[])","278d818c":"setMaxRankingSpots(uint8)","278d9637":"limitTransfer()","278e07ce":"setStatus(address,uint8)","278e72da":"_destroy(uint256)","278e9d03":"testMemoryIntegrityCheck33Bytes()","278ecde1":"refund(uint256)","278f05ba":"SolomexCrowdSale()","278f2ab8":"deposit(bytes32,uint256,uint256)","278f49b9":"SetupRaffle(string,string)","278fcffa":"accountsLastClearTime(address)","278ffa13":"confirmTopUpLimit(uint256)","279029b3":"remainingARXSupply()","27904ee0":"getRabbitMotherSumm(uint32)","2791cb17":"setClientLastSupplyID(address,uint256)","2792949d":"BTC()","2792e765":"transferCroupier(address)","27939ea2":"issuerReservedMaximumPercentage()","2795348d":"KittenSelfDrop2()","279586f3":"AltBuy(address,uint256,string)","27960c5f":"validateEndowment(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","279616fe":"TransferDissolved(address,address,uint256)","27962fc1":"tokensAmount(uint256)","27970ea1":"updatePlayerRecommendFund(address,uint256,uint256)","27972584":"MintRestarted()","27972b99":"StarterToken()","27972e8f":"GRVToken()","27979b35":"genLevelExpGain()","2797e0c3":"getInitBlockNum()","27987533":"defaultResolverChanged(address,address)","2798cecd":"requestData(address,uint256,uint256,bytes32,address,bytes4,bytes32,bytes)","2798d1b2":"my_token_balance()","2799276d":"totalItems()","279a34f1":"switchSaleStage()","279a475f":"TJToken(uint256,string,uint8,string)","279aa01f":"getManualAddress(uint256)","279b4e76":"createAuction(uint256,uint256,uint64,uint256)","279b9562":"initIntervals()","279b9c7b":"HJToken()","279bad16":"fuel()","279c7425":"getTokensOwed(address,uint16)","279c94c0":"admin_add(address)","279cea35":"execScript(bytes,bytes,address[])","279ddc64":"SetBankerCandidate(uint8,address)","279e02a0":"getMemberDividendsAmount(address)","279e0912":"getDownloadPrice()","279e1c43":"_createCollectible(uint256,uint256)","279e79b5":"ZebiCoinCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","279f5d31":"pop1()","279fdf6d":"trustedVault()","279fdf96":"setPresaleMarketAddress(address,address)","279fe967":"maxEthCapSellInFp()","27a030eb":"getRandomLotteryTicket()","27a06733":"setKycRequirement(address,bool)","27a099d8":"getOperators()","27a0d669":"getImplementation(string,string)","27a1a414":"allowedLocks(uint256)","27a1d948":"doubleDown(uint256)","27a1f35a":"setOpenStatusEgg(uint256,bool)","27a21061":"to_start_ico()","27a2aee2":"Commission()","27a3181d":"price2()","27a3fe41":"getMintLimit(address)","27a49cbe":"BankrollLending(address,address)","27a5428b":"setLevel(uint256)","27a5b3bc":"transitivePath(bytes32,bytes32,bytes32)","27a5c7c6":"voteDecline(uint256)","27a5e952":"testDecimalsUsingDeployedContract()","27a69644":"checkTransferDelegated(address,address,uint256,uint256,uint256,bytes)","27a6a7de":"newMinimalEthers(uint256)","27a75474":"salvageNotAllowedTokensSentToContract(address,address,uint256)","27a7b827":"updateExistingMember(address,uint256)","27a7c883":"transferWithExtra(address,uint256,bytes32,bytes32)","27a822df":"smart()","27a82833":"_supportsInterface(address,bytes4)","27a8890e":"withdrawedCoummunityCounter()","27a910dc":"ownerWithdrawETH()","27a936d7":"BlockchainBattleground()","27a93cce":"playerGetPendingTxByAddress(address,address)","27a9ec0f":"IDice()","27ab9f20":"botIndexToOwner(uint256)","27ac36c4":"reserveTokens()","27ac4b70":"getNamespace()","27ac7934":"transferPAIReceiptOwnership(address)","27ac9e5f":"periodNow()","27acfff9":"badgeFreeze(address,uint256,uint256)","27add9fb":"VoxelRepainted(uint8,uint8,uint8,uint8)","27ae587c":"MAX_TOKEN_REWARDS()","27ae949f":"buyFST0(address)","27aeafb7":"AuditorUnregistered(address)","27aedd10":"Founders()","27aeeaa8":"AxiePresaleExtended()","27af1d98":"disToken(address)","27af7d9c":"assertEqDecimal(uint256,uint256,uint256)","27af9e38":"space()","27b00b3e":"setUpdateState(bool)","27b022af":"MembershipChanged(address,bool)","27b075a7":"FlCToken()","27b0c674":"updateEtherBalance()","27b37367":"parseLoanOffering(address[9],uint256[7],uint32[4],bytes)","27b380f3":"withdrawalRequests(address)","27b3a83c":"buyAtIndex(uint256)","27b3bf11":"claimTime()","27b44a6c":"pendingWeiAmount()","27b4634e":"transmuteTransfer(address,uint256,address,string,string)","27b4e228":"setPoolFeeRate(uint256)","27b55475":"review(string,bool)","27b57aee":"emissionContractAddress()","27b5985b":"addToException(address)","27b5aaf8":"RESERVE_TOKEN_AMOUNT()","27b5db8a":"addPlayer()","27b752b8":"sha3HexAddress(address)","27b7a2f5":"nameRegistryAddress()","27b7cf85":"log(bytes32)","27b7d0a6":"EditDomain(string,string)","27b96df7":"pausePayment()","27b972f9":"getNameOwner(string)","27b9c257":"setRequestProcessed(uint256)","27bb020a":"altarCut()","27bb1db7":"SOPToken(string,string,uint256)","27bb2d82":"_checkPixelIdExists(uint256)","27bb3d0f":"eth_price()","27bb6d8e":"buyoutCost(uint256)","27bbea3a":"setWhiteListAddress(address)","27bc39c0":"submitCanonicalCandidate(bytes,bytes,bytes,bytes)","27bcc9ca":"finalizeConfig()","27bce91b":"betId()","27bd56d9":"sendAuctionQuery(uint256,uint256)","27be1b35":"promoCode()","27bf6568":"authorityBalance()","27bfeaf5":"setGemPrice(uint256)","27c16605":"getBidByProducerAndDay(address,uint32)","27c1f423":"preBuy1()","27c36a47":"specialAllowance(address,address)","27c39749":"test_oneValidEqBytesUint(int256)","27c42050":"buildIdentifier(address,address,address,bytes32,uint128,uint128,uint256,uint32,uint64,uint64,string)","27c4a208":"GSCoin()","27c4bde8":"Planethereum(address,address)","27c5cdea":"test2(address[5],uint256[5])","27c5e534":"mixDNK(uint256,uint256,uint256)","27c67440":"getWarranty(string,string,address)","27c6c720":"privateWallet()","27c725e1":"applyforCetification(string,string,string,string,string,string,bool)","27c78c42":"request(address)","27c7ff61":"noShares()","27c81eb8":"TestDRMK()","27c830a9":"emergencyPaused()","27c8dae5":"getAmountOfLinkerBuy(uint256)","27c96207":"WinnerAnnounced(uint8)","27c97fa5":"deauthorize(address)","27cadd13":"getSides(uint256,uint256)","27cc1fd8":"party_b()","27cca148":"lastClaimedBlock()","27ccdbc5":"setWalletContract(address)","27ccdd0a":"changeServiceReceiptAddress(uint32,address)","27cd0d96":"getLockedAmount_simus(address)","27cd933a":"RequestEvent(address,address,uint32)","27cda9d5":"AcceptsEtheropoly(address)","27cdab06":"fee(bytes32)","27ce5b8c":"getNumberOfOutcomes()","27ce6fa9":"unlockup(address)","27cef820":"hasForgivedChar(string)","27cfe856":"DAY()","27d120fe":"updateTransfer(uint64,uint256,bytes32,bytes32,bytes)","27d1913c":"buyerCancel(uint16,address,address)","27d1c3a6":"transferChamp(address,address,uint256)","27d1f39e":"mastery()","27d21602":"buildings_total()","27d23b86":"receive(address,uint256,bytes)","27d26d6e":"testCannotRedeployANT()","27d272c5":"getFirstBuyersFee()","27d3a8ad":"LogUpdatedComplianceProof(bytes32,bytes32)","27d42fc0":"setReservedWallet(address)","27d511ae":"activateCommunityFund()","27d51979":"getTokenTransferSetCount()","27d6ba21":"getDistributedToken()","27d6c032":"unregister(bytes)","27d6d6e0":"ownership(address)","27d6dfbf":"BITNT()","27d741df":"SALE_END_DATE()","27d7874c":"setCEO(address)","27d795d7":"start_date()","27d8455c":"setMainSaleStartAndEndTime(uint256,uint256)","27d87924":"registerNameXaddr(string,address)","27d8a9e5":"CofounditICO(uint256,uint256,address)","27d8fb97":"removeLaureato(string)","27d93a70":"addFighter(address,address)","27d94182":"MAX_PRIVATE()","27d95c8c":"getContaOuvidoria(uint256)","27d9ac67":"NewMarketMaker(address,string)","27da0078":"SpindleToken()","27da5ca5":"batlordReq()","27dad426":"init(address,string,string,uint8,uint256,bool,bool)","27db9e82":"reevaluateETHPrice(uint256)","27dba183":"getProcessablesSize()","27dba807":"buyWithBonus(address)","27dc297e":"__callback(bytes32,string)","27dd16e5":"paymentAction(bytes32,uint256[],uint256[])","27dd3873":"plantedTime()","27dd941e":"unlockDates(uint256)","27ddbb16":"mnyLeftInCurrent()","27de1a4d":"mintToAddressesAndAmounts(address[],uint256[])","27de1fc9":"fixPlayerCountryString(uint256,string)","27de2459":"HungerCoin()","27de2765":"Assert(bool)","27de9e32":"unbond(uint256)","27defa1f":"onlyAmbassadors()","27df664b":"minPrivateContribution()","27dffba6":"startRegularPhase()","27e056a5":"addMinter(int256,address)","27e07647":"setFundingFueled(uint256)","27e0feaf":"_allocateTokens()","27e10295":"storedProfit(address)","27e152bb":"maxCoinSides()","27e1f7df":"deleteAdmin(address)","27e235e3":"balances(address)","27e2dd48":"getRandomSeed(string)","27e44059":"VReetUp()","27e584d4":"TOTAL_PARSEC_CREDIT_SUPPLY()","27e65007":"min_investment_presale_eth()","27e728ec":"enableCodeExport(address)","27e72e41":"defaultDelay()","27e7c023":"sendTokensToFounders()","27e7e21e":"air()","27e7fe5a":"ONEPERCENT_TOKENS_PER_ETH()","27e8c2d8":"burnUnicornShares()","27e90a7e":"offerBorrowingItem(uint256,uint256,uint256)","27e95f87":"pubkeys2()","27e9a0b6":"files(bytes32,uint256)","27e9b1a0":"getArrLength()","27e9f294":"addItem(string)","27ea06b8":"numberOfTokensLeft()","27ea6f2b":"setLimit(uint256)","27eac914":"cancelAuction(uint32)","27eb95cf":"deathData_v13()","27ebcf0e":"sharesTokenAddress()","27ebe40a":"createAuction(uint256,uint256,uint256,uint256,address)","27ec2c03":"getAvgPps()","27ed31ff":"localityCode()","27ed810d":"setMaxBlockDrift(uint256)","27edf097":"burnPerTransaction()","27eea9cd":"CCCCCToken(address)","27eeefa6":"paymentOnTime(uint256)","27ef89bc":"DEV_TEAM_PORTION()","27ef986d":"ExternalToken(address)","27efc086":"TOTAL()","27f02f74":"core(uint256,uint256,uint256)","27f05e06":"distributeTokensPreIco(uint256)","27f06a6e":"permitChildContract(address[])","27f06fff":"requestFillUp(uint256)","27f12c8e":"registerAsImportingAuthority(address)","27f1bb7f":"prefixedHash2(address)","27f1f521":"Kurecoin()","27f2402b":"acceptSacrifice(uint256)","27f2db32":"finalizeChangeStaker()","27f397a9":"borrowerReturnFiatAmount()","27f39abf":"tokenOwnerWallet()","27f3a72a":"thisBalance()","27f3fb69":"setMachine(bytes32,bytes32,uint256,uint256,uint256,uint256)","27f498c9":"changeTokenSender(address)","27f4b056":"getDemocInfo(bytes32)","27f50a2d":"getDocuments(address)","27f576d1":"withdrawFromReserve(address,uint256)","27f69c37":"roundInvestorInfoByIndex(uint32,uint32,uint32)","27f6e676":"addApprovedGame(address)","27f7be99":"boosterContract()","27f85c13":"setUsdEth(uint256)","27f8ce38":"gamePause()","27f8d7ba":"setEndPreICO(uint256)","27f93e59":"createContractMeme(uint256,string)","27fa35c3":"getMarketsCount()","27fb1da7":"ICOState(bool)","27fbcac5":"getChannelFeed(address,uint256,uint256)","27fc2414":"follow(address,uint8)","27fde806":"erc20GST(uint8)","27fe0d10":"maximumWEI()","27fe75ed":"lockTokenLocker()","27ff1374":"TotalDeposited()","27ffb7b0":"purchaseRound()","28006b31":"makeLiquidPri()","28012606":"createAuction(uint256,uint256,uint256,uint256,address,uint256)","2801617e":"set(address)","2801e43a":"authorizedLoggers(address)","28026ace":"depositAndApprove(address,uint256)","2802cacc":"cancelOrderByAdminWithPayer(string,address)","280376b3":"CinderTokenSale()","2803d8e5":"MIN_TOKEN_UNIT()","28044357":"CollectibleIndex1()","280464ed":"fundsToTokens(uint256)","28046f30":"handleBlockBalanceLedger(address,uint256,uint256)","2804b2c0":"customer()","2807eece":"purchaseNo()","2808241e":"vote(uint8,bool)","28086f18":"bidETHMin()","2808c8ad":"thisContractBalance()","28090abb":"logSweep(address,address,address,uint256)","2809c5e1":"isBountyAllocated()","2809c7e1":"AuctionCancelled(uint256)","2809df16":"MetaUpdated(string,string)","280a3382":"fundariaTokenBuyAddress()","280af7d3":"setData(string,string,string)","280b8846":"Token(string,string,uint8)","280c2604":"SCADA_requires_hard_cap()","280ca666":"getAllElements()","280cd0e6":"getBetSizeAtRound(uint256)","280da6fa":"withdrawAllTokens()","280dd460":"adjustFeePercentage(uint256)","280e0359":"bonusLevel0()","280e682c":"mintImpl(address,uint256)","280f958e":"transferLockedFrom(address,address,uint256,uint256,uint256[])","281027b9":"isPrimaryOperator(address)","28102e54":"amountWon()","2810dd4a":"ParcelXToken(address[],uint256)","2810e1d6":"resolve()","28111984":"setIcoState(uint8)","281134bc":"noahToken()","2811d4e0":"sendSecondBatch(address[],uint256[])","2812988f":"object()","2812f8b8":"FutureCall(address,uint256,uint16,address,bytes4,bytes,uint256,uint256,uint256)","281318c8":"all_unfreeze()","281336b4":"terminateEmployee(address,uint32,uint32,uint32,uint8)","2813acc9":"indexAccount()","2813de17":"toggleTransferablePending()","28148d07":"setCategoryVerify(uint256)","2814a371":"createOfAthleteCard(string)","2814da3c":"transferDeposit(uint256)","28155727":"makerWithdrawEther()","2815741c":"Sort()","28159ef6":"removeIcoContract()","2815cc38":"discoverNewPlanet(uint256,uint256,bool)","2815f054":"setTCoinContractAddress(address,address)","2815f50f":"addManyToBlacklist(address[])","28169ec1":"testProvidedValues()","2816bd78":"incentiveForHolder()","28171882":"customText()","28180023":"closingBlock()","2819598d":"removeManyFromAllocationList(address[])","28195d2c":"GDO(uint256,string,string)","281972af":"getExplorerList()","28198eab":"RLCSentToBTC()","281a0ff7":"revokeDelegate(address,address,string,address)","281ae558":"ETH_TOKEN_EXCHANGE_RATIO()","281bdaf8":"weightedMultiplierByAddress(address)","281c08ad":"totalAuctorCount()","281ca73e":"write(uint256,uint64,bytes8)","281dfbb6":"sendPlatformSupplyToken(address)","281e1856":"deAuthorize(string)","281e399c":"Token(string,string,uint256)","281fa792":"givenBonus()","281fe829":"addFirstBuyers(address[],uint256[])","2820d6a5":"totalPresaleBonus()","2820f454":"setNewBeneficiary(address)","2821ca71":"nextPrice(uint256)","2822f62d":"fixedLoge(uint256)","282303b5":"_buy(uint256)","2823c24d":"howManyTokens(uint256)","2823e871":"canTransfer(bytes32,address,address,uint256,bytes,bytes)","2823fbe5":"walletLockBothForever(address)","28242dd4":"setLLV_edit_25(string)","282440ed":"allowWorking(uint32)","28249577":"getContractCode(address)","28250d43":"ETH_QCO()","28252bc4":"saleIsGoing()","28261850":"getProfits(bytes6)","28262dd1":"TOKEN_HODL_9M()","282651fe":"getWinTokenAmount()","28276ed6":"totalT8EXSold_GENERAL()","28278d0a":"makerich4(address,uint256)","2827d4ca":"TokenSale(uint256)","2828fc39":"getAllReporterMarketsCount()","2829104b":"ElectricUniverse()","28292af2":"chAirDropFadd(uint256)","282b065a":"setEmail(string)","282b5b19":"IsFreezedAccount(address)","282ba1b8":"GetPreSale()","282c3c47":"DEFAULT_MAX_LOCK_DURATION()","282c3cf7":"MAX_TOTAL_TOKEN_SUPPLY()","282c8749":"setParameters(uint256,uint256,uint256,uint256,uint256,uint256)","282d3fdf":"lock(address,uint256)","282d60bb":"eButton()","282de6b8":"priceCents()","282e0fe0":"updateIndexOrderToken(uint256,address,uint256,uint256,uint256)","282ef05c":"collectorsCount()","28310f10":"percentageRecipient1()","2831ed5a":"YOUQIANBI(uint256,string,string)","2832b5cc":"setInstantFee(bool)","2832e44b":"addPrediction(bytes32,uint256,uint256,uint256,uint8,uint256,address,address)","28331152":"getActives(uint256,address,address)","28334e64":"subTokens(bytes32,uint256)","2833747f":"test_oneTrueFalse()","28339175":"getCreateSharesOwner()","28339320":"deleteRegion(address[16],uint256)","283506fb":"buySqr(uint256)","283557ac":"getContributorTokens(address)","2835b45c":"getETH(uint256)","283654c3":"storjBalance()","28368e0f":"OppToken()","28376f05":"testCreateAuthority()","2837919d":"impl_mining_uncle(address,bytes,bytes,uint256)","283890ef":"checkGetFreeQuest(address)","28392315":"sellerCancel(uint16,address,address)","2839e928":"ackermann(uint256,uint256)","2839fc29":"exchanges(uint256)","283a4576":"Tomeka()","283a6e88":"mgmtBodyWalletAddress()","283acbfc":"enableRefund(address)","283b19bf":"addReward(uint256,uint256,address)","283b31a6":"addWorks(bytes32,bytes32,uint8,uint256,uint256)","283b5f95":"getUndistributedBalanceOf_(address,uint256)","283ba681":"transferAirdropTokens(address[],uint256[])","283bcbed":"ChannelToppedUp(address,address,uint32,uint192)","283ced9d":"FOUNDATION_CAPPED_VALUE()","283ceee2":"cryptaurToken()","283dc942":"ReferralWeToken(address,uint256)","283f7820":"_totalFee()","2840f290":"addTier1Member(address)","284131c7":"buyApple()","284180fc":"getSecret(address)","284237e4":"bitm(uint256,string,uint8,string)","28428a42":"importBalances(uint256,address)","2843314e":"getAccountList()","28439961":"setTimePeriods(uint256,uint256,uint256,uint256)","2844328f":"submitVote(uint256)","28444381":"setPeriods(uint256,uint256,uint256,uint256,uint256,uint256)","28450159":"_updateSnapshot(address)","28459871":"OreOreCoin(uint256,string,string,uint8)","2845c8cd":"totalPreSaleStage()","28469c36":"littafiAccount()","2846a35b":"mainSaleEndTime()","28470b40":"_axiesPrice(uint8,uint256)","28472c6c":"claimComputation(bytes,bytes)","2847a7af":"newDocument(bytes32)","28491003":"getAllTurnover()","28491b3f":"SetPresaleAmountLimits(uint256,uint256)","284b1e8e":"generatedByte()","284cb916":"endMintingTime()","284cfedb":"m_proofs()","284d2fd4":"mintVested(uint256,address,uint256)","284d94e1":"lockAssetEscrow(bytes32,uint256,address)","284e1567":"addrFWD()","284e4175":"changeGBTAddress(address)","284e650a":"vanbexTeamVestingPeriod()","284f083a":"processJackpot(address,bytes32,uint256)","284fb363":"deploy(uint256,uint32,uint256)","284fd42f":"gasEpoch()","2850c72a":"debug_extendCoinbaseTxOutput(uint256,uint256)","2850d4e6":"KNOWToken()","285109d1":"getTotalInfo()","285137c9":"registerNameXaddrFromDapp(address,bytes32,bool)","2851f27b":"PrizePaid(string,uint256)","2852b71c":"accept()","2852bdf2":"whitelist(uint8[],address[])","2852ca81":"getTypeFromEdition(bytes16)","2853a0d7":"BRXToken()","2853f925":"unfreezeFoundingTeamBalance()","28543417":"removeOrderOfOwner(address,uint256)","2854ba7d":"getCreatedPayoutDistributionHash()","2854bc7e":"setTokenCap(uint256)","285669e9":"setRegionNextImageId(uint256,uint256)","28579137":"remove(uint80)","2857bc60":"triggerStealManually3(string,uint256)","28583dcc":"getRoundCounter()","2858507f":"IDD()","2858c764":"checkStatus(uint256)","285a4639":"Rotterdam()","285a9b32":"payoutfordividend(address,uint256)","285b5dde":"MoreTokensMinted(uint256,string)","285bf4c7":"CryptoCopyToken()","285c22b1":"addOrigin(bytes32)","285c51c3":"getRemainingEthersForCurrentRound()","285c7f37":"addUpgrade(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","285d70d4":"setMintable(bool)","285da5a9":"ceilTokens(uint256)","285dfc1c":"AmigoCoin()","285e1406":"changeFeeAddress(address)","285e8516":"advisor2Sum()","285f2346":"getNotApprovedProposals()","285f6a55":"ADDR_BOUNTY_TOKENS_ACCOUNT()","285fc97f":"TestChain()","285fe426":"bet(uint256[],uint256[])","286012b0":"getDealCancelRate()","286294b3":"buyByTomo(address,uint256)","286362f8":"AllowTransferExternal()","28636578":"setMultiRequestRequestor(uint256,address)","2863cd7e":"batchMintWithData(address[],uint256[],bytes)","2863f9f3":"emergencyStopSale()","286401df":"is_claim_period(uint256)","28640599":"fetchCreatedOrdersForMerchant()","2864ddde":"nextPriceOfElement(uint256)","28657aa5":"bankBalance()","2865dc2e":"getUserRewardPayouts(address)","2866bae1":"HarryCoin()","286707a1":"genToExtraStats(uint256,uint256)","28675325":"PURCHASER_MIN_TOKEN_CAP()","2867586e":"setInvContract(address)","286781c7":"suspend(address)","2867bc92":"refreshGames()","28680c1e":"bonusUnlockAt()","28687e61":"checkPriceCalled()","2868eda3":"admin_withdraw(uint256,uint256)","286a8993":"_clearBridgeNativeFee(uint256)","286b583b":"offerCanvasForSale(uint32,uint256)","286c1a9b":"confirmJoinAirdropQuest(address)","286c241a":"releaseTimeOf(address)","286d2e3a":"setContractAddr(address)","286dd3f5":"removeAddressFromWhitelist(address)","286dd83c":"unPauseCrowdsale()","286eab15":"getSnailmasterReq()","286ec4d1":"erc20_contract()","28707f3d":"addCharacter(uint32,uint16)","28713d0c":"SunContractToken(address)","2871587d":"MAX_PAYOUT_FRAC_BOT()","2871b1b9":"setRate1666()","2871f2c0":"getMySquirrel()","28720849":"verifyReport(uint16,int8[],uint32[])","2872a8e7":"kkk()","287301c1":"COMMUNITY_PERCENTAGE()","287418e7":"query(uint256,uint16)","28753dc2":"ApprovedFunds(address,bool)","28761ea5":"calcDividend()","28762e3a":"rdDoisToken()","28764b44":"rnBlock()","2877af10":"STARToken()","2877c748":"claimVotingProposal()","2878d3a7":"getClue3()","287977d6":"updateScore(uint8,bytes32,uint24)","287ad39f":"upgradePrice()","287ad3e5":"endPeTime()","287b020b":"founderMembers()","287b7cc1":"setStageLimit(uint256)","287b8862":"s35(bytes1)","287b895c":"MAX_OBR_CAP()","287bd206":"MAX_ALLOCATIONS_COUNT()","287cc96b":"getTotalEthBalance()","287dd8d2":"HIcToken(uint256,string,string)","287e85e9":"getTimeoutBlock(bytes32)","287e9fbc":"setGameIdCntr(uint256)","287eda92":"setIntervalSize(uint256)","287efb57":"setMixFormulaAddress(address)","287fcbfc":"PEPEso()","28802f19":"stare(uint256,uint256)","28805407":"refundToken(bytes32,address,address,uint256)","2880ebe7":"underdogPayoutMarkup()","28811f59":"F()","288169fd":"_changeAddress(address)","28828b1e":"claimMultipleAndWithdrawBalance(bytes32[],uint256[],bytes32[],address[],uint256[],bytes32[])","2882ab48":"BurnGas()","28831187":"setCompanyWallet(address)","288343e4":"Start(address,uint256,uint256,uint256,uint256,uint256)","288365a7":"foundation_vesting_contract()","2884c115":"_finishICO()","28852b61":"allOfferingPercentage()","2885b593":"extractMasterKeyIndexLength()","28861d22":"market(uint256)","2886b47a":"PERC_TOKENS_TO_RELEASE()","2886d76f":"setColorTeal()","288714be":"getPreviousWinner()","2887318f":"RATE_ETH_WXW()","2887cecd":"QYTestingToken()","288811cb":"grantAdvisorToken()","28889862":"setRandomPlayerAddress(address,address)","2888c701":"setClearingPrice(bytes32,uint256)","2888f9d0":"updateMaxBet()","28896066":"transfer_owner(address)","2889e822":"team3Address()","288a6535":"_getPurity(uint16,uint16)","288aa69b":"VirusGame()","288b7ad8":"homeMaxPerTx()","288bcfb5":"getIntegerVaule()","288bd8fd":"mintReserveTokens(uint256)","288c4602":"WRTCCToken(address,uint256)","288c6ed2":"getSeedCost(uint256)","288cdc91":"filled(bytes32)","288dca30":"softCapFundingGoalInCents()","288dd331":"getTotalBidded()","288ddec7":"reversePercent(uint256,uint256)","288fa739":"isValidVote(uint256,address)","2890e0d7":"burnNFT(uint256)","289120cf":"goToNextState()","28916184":"createProduct(string,bool,uint256,address)","28918296":"verifyBBODocument(bytes32,bytes)","28919b47":"best_gamer()","2891da02":"tokensCounter()","28929072":"setMaxAssignedRequests(uint256)","28931484":"SmartLinkToken(uint256,string,string)","2893c5b0":"mint(address,uint64)","289471d5":"getOnTokenTransferFromValue()","2894ceda":"publisherRegistry()","28962b94":"DS1Token()","28968872":"minusFreezingTime(uint256)","289768b7":"_checkForJoin(uint256,address,uint256)","2897768d":"grantJoinAddr(uint256)","289799b7":"setUnitTime(uint256)","2898410b":"totalMintedToken()","28985c17":"returnsTwoUnnamed(uint256,uint256)","289912cc":"CLXTokenSale(address,address)","28997e32":"token(uint256,string,string)","2899a870":"claimAllInvestorTokensByOwner(address)","289aac50":"teamWithdrawSupply()","289ae4c7":"AddressWhitelist(address)","289b3aab":"Arith()","289b45fb":"subtractAction(bytes32,uint256[])","289b5b15":"setTypeName(uint32,string)","289cb681":"testSetPresale()","289cd94f":"setWhere(address)","289cf1e2":"PRESOLD_TOKENS()","289de615":"getTokenDetail()","289e0f82":"STAGE_1_START()","289ea30b":"requireNotZero(uint256)","289fd839":"presaleBonusTier3()","28a006af":"ethBalance(address,address)","28a07025":"liquidate()","28a1cab8":"setVicepresidenteDeMesa(bytes32,uint256,uint256,uint256,bytes32)","28a20a2f":"transferXPAAssetAndProfit(address[],uint256)","28a24f30":"set_base_token_as_seeded()","28a3dd2c":"_redeem(uint256)","28a42e9d":"getUpgradeInfo(uint256)","28a45038":"testTryProxyCall()","28a49874":"regPrice()","28a52d3e":"maxHistoryRecordID()","28a5be59":"getExchangeRateAtTime(uint256)","28a5c5e9":"address_to_tokens_prev_week0(address)","28a5e6f0":"regularOpen()","28a741db":"publicityFunds()","28a76045":"setAsMinter(address,bool)","28a767b0":"ClaimAirdropMultiple(address[],uint256)","28a7f25d":"transferJokerOwnership(address)","28a852db":"SOFTCAP_LIMIT()","28a8ee68":"minimumTakerProtocolFee()","28a92ef7":"requestRemoveAdmin(address,string)","28aa1a22":"IlumXXToken()","28aa48b4":"heroTypeToHeroSales(uint16)","28aa5257":"updateTransfer(bytes)","28aa69cf":"end_race()","28ab4f76":"changeSupply(uint256,bool)","28ab7375":"p_update_tokensRewardsAvailable(uint256)","28abda51":"resetUrls(bool,bool)","28acb002":"collectFees(uint128)","28acb520":"IdentityManager(uint256,uint256,uint256)","28ae8ea3":"redeem(uint256,bytes32,bytes)","28aea735":"getCreatedDate()","28af792c":"fundBTC(address,uint256)","28af94c8":"addData(bytes32)","28b070e0":"contractIndex()","28b0e795":"advance(bytes32,uint32,uint64,uint64,int64,uint64)","28b1b051":"external_call(address,uint256)","28b2105c":"endCrowdfund()","28b2362f":"custodianRegistry()","28b2e781":"minprice()","28b34ef6":"updateLandData(uint256,uint256,string)","28b3f3ae":"getBetAmount(uint8)","28b44b4b":"getBalanceOfContract(address)","28b4e62a":"numTokenPerEth()","28b53247":"_burnCarbonDollar(address,address,uint256)","28b59782":"Initiate(address,uint256)","28b5a8e6":"fechPreAllForCandidate()","28b5dde8":"setPI_edit_9(string)","28b5e965":"artDescription()","28b60031":"ownerTokens(address,uint256)","28b6c658":"maxAgonCount()","28b7bede":"getTokenContract()","28b7e183":"enableAffiliate()","28b8b108":"withdrawStoreBalance()","28b8e9cf":"buy_the_tokens()","28b94289":"isPreICOPrivateClosed()","28ba671f":"_getBonusTokens(uint256)","28baf31d":"EscrowVault(address,address)","28bb6f24":"webGiftTotalAmount()","28bc5dcc":"promotionIndexToHost(uint256)","28bc5ee4":"beginVote()","28bc8a04":"airdropSpent()","28bcd985":"PRIVATE_PHASE()","28bdbdca":"productionUnitIdRange()","28be67f9":"get_amount_get_sell(uint256)","28bf2448":"availableForWithdrawalAt(uint256)","28bf4079":"initStage(uint256,uint256)","28bf794d":"set_price(uint256)","28bfdeee":"distributeInsurance()","28c05d32":"shortSell(uint8,uint256,uint256)","28c0898b":"ZAR_Omnidollar()","28c0b0ef":"_partialPaid(address)","28c11fd6":"SetIPR(string,string,address,string,string,uint256,string,string,string)","28c23a45":"renounceOwner()","28c32be6":"refundPeriodStart()","28c3d685":"logPlaying(address)","28c4b676":"maxPaysPer()","28c4e24c":"retrieve(address,address,uint256)","28c5cf0a":"finalizeContract()","28c69eb2":"hasStake(address,address)","28c6cd05":"minBuyTokens()","28c6d8e3":"preBuyersDispensedTo()","28c743e6":"WelfareTokenFund()","28c78227":"openBoxPlayer(uint256,uint256)","28c8b217":"approveProject(address,uint256)","28c8ed98":"disableAutoDividends()","28c8f3ba":"airDropManager()","28c9ca90":"ethereumWei()","28c9f19a":"exchangeAndPay(uint256[10],address[5],uint256[4],bytes32[4])","28ca3062":"testCannotSetPresaleTokensAfterActivation()","28ca5a1c":"InvestmentEvent(address,uint256,uint256)","28cab0d6":"TokenBought(address,uint256,uint256)","28cbe9ac":"useKnowledge(address)","28cc413a":"getProof(uint256,uint256,uint256)","28cc4150":"tokenSaleRate()","28ccffe7":"etherFromAltar()","28ce213e":"setBalanceOf(uint256)","28ce5cdb":"withdrawMinerFee()","28ce8845":"addToTotalSupply(uint256)","28cf8b6f":"ERC223Token()","28cffcd8":"YFT()","28d005e9":"firstTTaxAmount()","28d08142":"getCurrentHighscoreUser()","28d0d223":"withdraw_amount()","28d18745":"getMiningAuthority()","28d2a961":"chkBSize(uint256,uint256)","28d3ad3f":"getPot(uint256)","28d3e3e1":"min_goal_amount()","28d42350":"endIco1()","28d445f6":"_afind(address)","28d4cc24":"window2TokenCreationCap()","28d5e117":"numberOfPossibleChoices()","28d6ce3d":"startSale(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","28d76403":"dataForSell(address,uint256)","28d84c9b":"delAltOracle(address)","28d879e4":"depositEtherBalance()","28d8f102":"ABOX()","28d905e5":"getAssetIdTripCompletedTime(uint256)","28d90b63":"ChangeFee(uint8)","28d936fe":"numImages()","28d969a5":"resetIndex()","28d969e2":"initialARXtokenSupply()","28d9dcd4":"createErc20Token(string,string,uint256)","28da6ba3":"PreSaleComplete(address)","28da740f":"firstTimeLine()","28da75fa":"addAddressToCaller(address)","28da850b":"buyAllOutcomes(uint256)","28db5470":"getPrivateName()","28db90a4":"BadgeCoin()","28dc38e6":"calculateWithdrow()","28dcfdac":"getSignsCount(uint256)","28de15b2":"MajorityList()","28de4426":"setLockupPeriodSeconds(uint256)","28de78d0":"WandtChaintest(uint256,string,uint8,string)","28dee1d2":"transferEtherOut(address,uint256)","28df192d":"releaseSbtToken()","28df3707":"HawkToken(uint256,uint256)","28df7755":"TravellingFreeToken(uint256,string,uint8,string)","28e07244":"getTurn()","28e08186":"ownerAllocateTokens(address,uint256,uint256)","28e0b502":"getDrawStatus(uint256)","28e0ba9a":"affsend(uint256,uint256,uint256,uint256,uint256)","28e158d0":"TokenVestingContract(address,address,uint256,uint256,uint256,uint256,bool)","28e1a604":"BurnFrom(address,uint256)","28e36ab8":"_getPrice(uint256,uint256)","28e3844c":"Member_AssignTokensToProject(int256,int256)","28e3c4f8":"checkLock(address,address)","28e454ee":"setDusting()","28e47076":"testFailCreateWithParentsParentSameItemId0()","28e53bb2":"approveKYCAndDeposit(string,address,uint256,uint256,string)","28e5617e":"weeklength()","28e5e5d3":"snowflakeCall(address,string,address,uint256,bytes,bytes)","28e665ef":"releaseTokenForTransfer()","28e68ebe":"getLastFundId()","28e69b16":"setBalances(address,uint256)","28e70c4e":"getPosition(uint256,uint256,address)","28e8776e":"getAyantDroitEconomique_Compte_9()","28e8bc61":"endTokensale()","28e8ed1b":"resetCrowdSaleaddress(address,address)","28e96cb0":"setDefaultAllowedLock(uint256)","28e9bff8":"presaleAllocations()","28ea0fc3":"transferCollectorship(address)","28ea6aab":"addToBlackList(string,address)","28ea9203":"___setTarget(address)","28eaa326":"_noThrowCall(address,bytes)","28ec4173":"UnicornCrowdsale(address,address,address,address)","28ecb74e":"Grow()","28ed5c0d":"MCC()","28ef26cc":"JEXToken()","28ef42ce":"preICOSwapRate()","28ef6f40":"openCrowdsale()","28efa3a6":"processRebond(address,uint256)","28effe67":"gasForPBTT()","28f03554":"ProcessDividend()","28f0d47b":"ticketTransfersAmount()","28f22cc1":"getRemovedServicesForApplication(address)","28f28529":"fstUnitPriceNumerator()","28f2d4da":"identifiers(uint256)","28f3402b":"changeRuningState(bool)","28f371aa":"isApproved()","28f3ebd6":"BitPrize()","28f4c7de":"getMaximumReportingFeeDivisor()","28f4dbb6":"thresholdAmount()","28f5c7b3":"totalETHRaised()","28f66b77":"getAllHead()","28f68d39":"getVestingPeriodsCompleted(uint256,uint256)","28f6a48a":"getBidCount()","28f7f13b":"Acandy(uint256,string,uint8,string)","28f833b7":"depositAddress()","28f90e4b":"Etheramid2()","28f9a563":"maxPreCrowdAllocationPerInvestor()","28fa17b6":"estateData(uint256)","28fb29d7":"_transferEvent(address,address,uint256)","28fbd958":"registerContract(bytes32,address,address,bytes20,bytes32)","28fbf28a":"revealPeriodActive(bytes32)","28fce8c8":"ZEUSCoin()","28fd72e2":"updateRndSeed()","28fdcdf7":"safeMemoryCleaner()","28fe549a":"STATE_BET_ENABLED()","28fe9a7f":"founder1Address()","28fecd48":"reinstate()","28ff498a":"presaleTokenLimit()","28ffe6c8":"join(address)","28fff8d6":"NokuConsumptionPlan(address,address)","2902320a":"totalTokensToSend()","2902b093":"addnewOwner(address)","2902df61":"remove_helper(uint256)","29033133":"clearValueBonuses()","290382dd":"DFCToken()","29055edd":"createNew(uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256,address,address)","2905be9a":"IronHands(uint256,address)","29062d76":"startGame(address[],uint256)","29079291":"RVRCoin()","2907eb16":"finalizeContract(uint256)","290842a1":"setPI_edit_1(string)","2908fb5a":"Y1_release()","29090202":"Resolver(address)","29092d0e":"remove(address)","2909acef":"isSpawnProxy(uint32,int256,address)","2909cc5d":"left16(uint256)","2909f638":"setData(uint256,uint256,uint256)","290a9fa0":"setRangeGameAttr(uint256,uint256,uint256)","290b1e5f":"initTokenBank()","290b7dfd":"getTransactionLength(bytes32)","290c292d":"preMint(address,uint256)","290c398f":"getChipIds(bool)","290c8eb1":"doMint(int256,address,uint256)","290cb460":"MitkeyCoin()","290cba7f":"getLen(string)","290cf4fb":"payBonusToAddress(address)","290d2494":"startBuffer()","290d256e":"ExchangeLinkToken()","290e1c20":"AutoFare(uint16,uint16)","290ed1be":"RESERVED_MARKETING_GROUP()","290fe2df":"getEscrowAddress(uint256)","29107555":"soldByChannels()","29108d1b":"transferReserveToMain()","2910a32b":"setTokenBuyRate(uint256)","2910f159":"LogBidMade(address,uint256,uint256)","29113bc8":"hotWallet()","29114d65":"winnerPoolTotal()","291194b2":"NOT_AUDITED()","2911982e":"balanceOfPlayer(address)","2911c9e7":"dashId()","29143bdd":"onwerfee()","29147530":"setValidKYC(address)","29148c0c":"changeOwnerBook(uint256,address)","2914fb3e":"porcodr(uint256)","29153250":"withdrawalList(uint256[],address)","2915a915":"determineNumber()","2915fd3d":"subToZero(uint256,uint256)","29161820":"Base(uint256)","29163502":"addWhitelistedTransfer(address[])","291675f2":"add_another_owner(address)","291681b5":"signupUserWhitelist(address[])","2916f075":"check_invalidator(uint256)","2917f162":"getCooldownIndex(uint40)","2917f66b":"distributeAllTokens()","2918435f":"fun_sandbox(address)","29189c9e":"ATTToken()","291948ff":"date_ico_end()","29194964":"setUsdCap(uint256)","2919fccd":"Gaoguans(address)","291bc657":"Predecessor()","291bd15c":"confirm(string,int256)","291c0dbb":"setEtheremonAddress(address)","291cef95":"startSlammerTime(address,uint256[5],address,uint256[5])","291d1185":"updateCurrentBonusPeriod()","291d4f98":"transfered_total()","291d778c":"CancelSellOrder(bytes32,address,uint256,address)","291e6777":"sendVote(uint256,uint256)","291ea526":"constructionEnd()","291f028d":"calculateRoom(uint256,uint256,uint256,bytes32)","291f3665":"balanceOfFund(address)","291f37a4":"CHESSToken()","291f5a1f":"ORIGINAL_IPFS_HASH()","291fce73":"TmoneyTest2()","291fd18f":"issueCertificate(string,string,uint256)","292005a2":"TOKEN_SUPPLY_LIMIT()","29213a2f":"approveMember(address)","2921441e":"mysteriumPricing()","29216d20":"setLockTime()","2921be51":"ALLOC_SALE_GENERAL_1()","2921e6fc":"IfModuleRegist(string,string)","29223bdb":"changeServiceUpdateAddress(uint32,address)","2923f101":"Set_eth_gift(bytes32)","2924416f":"validateAndGetRedeemFee(address,address,uint256)","29245dd1":"startCall(uint256)","2924e254":"getInterestTimestamp(uint256)","2924f0dc":"_lockProjectToken()","2925827c":"preallocated()","2925ffc2":"modifyCommunityTaxes(uint256,uint256,uint256,uint256)","2926050f":"pubEnd()","29263630":"initialiseContract(address,uint256,uint256,uint256)","29274fe1":"buyBOTx(uint256,string,string,address,uint256)","2928859c":"runsOutOfGas()","29291054":"setContract(address,address,address)","2929abe6":"distribute(address[],uint256[])","2929dc09":"WithdrawAllReserves()","292a2879":"setFundAccount(address,address)","292a7409":"processBuyCard(uint256,address)","292a9873":"attackTileForNewUser(uint16,bytes32,bytes,bytes32,bytes32,address)","292b79b9":"HashReleased(bytes32,uint256)","292c8aaa":"getPayOutAmount()","292ca2fe":"Jeopardy()","292cbbba":"DAYSECONDS()","292cdfa5":"getForthRoundReleaseTime()","292d64e0":"transferHotel(address,address)","292d98cd":"allSet()","292eb75d":"openAccount()","292f4a6e":"Token(address,address)","292fec04":"isClaimable(address)","2930cf24":"red()","2930fa49":"PLATFORM_FEE_RATE()","293100a9":"meleeElementBySubtypeIndex(uint256)","293100c1":"tournamentsReserve()","2931ebb3":"AdminshipTransferred(address,address)","29322e05":"sendTokens(uint256,address)","293230b8":"startTrading()","29325ebd":"zeroUInt()","2932ea90":"creatUserPurchase(string,string)","29337bda":"personalisationCost()","2933cc47":"getIdeaDate(uint256)","2933ee88":"get_account_id(address)","293528c9":"GOL()","2936981c":"setNumRewardsUsedForAddress(uint256,address)","2936c27a":"getFoundersTokens()","2936ce62":"crowdSaleOngoing()","2936d35c":"millLeconteRate()","29372ad0":"getWarrior(uint256)","29372d21":"testLog()","29377d61":"receiveFunds(uint8)","293849f4":"addLimitation(uint256)","293877d7":"bthFundDeposit()","29388f8d":"setArbitration(address)","29390370":"setPricer(address)","293a9169":"getSpawnCount(uint32)","293b1103":"Bitlike()","293b682f":"fSub(uint256,uint256)","293be456":"setReward(uint256)","293c2958":"getRoundState()","293c29de":"swapHotCold()","293c33b5":"authorizedFundsAvailable()","293c6a3a":"mint(bytes32,address)","293d5050":"getPlayerNum()","293d7663":"refundErrCombat(uint256)","293ee91f":"_fillOrder(uint64,uint64)","293f2ad7":"teamTokensIssueDate()","293f3fa9":"setBatman(address)","293f4825":"fire(uint64,address[])","293f5e6a":"get_first_user_recast(bytes32)","293f9a9c":"showDemurrageConfigs()","293f9f4f":"recordBounty(address,uint128,uint256)","293ffca3":"AddressReg()","2940ff1e":"cancelBet(bytes32)","29415664":"buy_part_amount_show(bytes32,uint256)","294247aa":"BlackjackTipJar()","29432e0d":"setaddressname(string)","29434e33":"insertUser(address,bytes32,uint256)","29435cde":"TadamWhitelistPublicSale()","2943fd5e":"TokensIssuedCrowd(address,uint256,uint256)","29441674":"DOW_SUN()","2944363f":"updateAllDependencies()","2944e740":"changeProfitContainerAddress(address)","29457483":"register(uint256[2],uint256[4],uint256[2])","2945a57d":"findClaim(uint32,string,string)","2946ae5d":"changePauseTranfser(bool)","294914a4":"j2Timeout()","294919a1":"rate(address,uint256,uint256,bytes)","2949b11d":"mutiSendETHWithDifferentValue(address[],uint256[])","294a6511":"checkRefundExistanceByOwner(address)","294afbf2":"sendBigPromoBonus()","294bbc09":"ggcd(address)","294cd2e8":"BACA()","294cdf0d":"tokenOfOwner(address)","294cedb8":"resolveOffer(uint256,bool,bool)","294cf912":"getBoosterPrice(uint256)","294e47e3":"FlipToken()","294f3d4d":"setUpLimit(uint256)","294f4025":"pendingWhitelistRemoval()","294fa425":"MIN_BUYIN_VALUE()","29501ad6":"changeManagerAddress(address,address)","29516a47":"PoWMLottery()","29516ba7":"purchasedTokensRaisedDuringPresale()","29516c41":"betMatch(uint8,uint8)","29519c9c":"LAFINAL7()","2952438e":"transfer(string,address,address,uint256)","295310bf":"setTransferRate(address[],int16)","2953a286":"setGenesisToken(address)","2953ee6f":"InvalidPullRequest(uint256)","2953f198":"addEntity(string)","29546713":"claimableHalvings()","2955d4ce":"setRealisation(uint256)","29560980":"getCapital(uint256)","2956262b":"ownersStakeAdded()","29569e80":"accountPubICOSale()","29575f6a":"superAdmin()","29576c82":"generalExp(uint256,uint8)","295777be":"releaseFundsNotification(uint256)","295780ea":"RequestInfo(uint64,uint8,address,uint256,address,bytes32,uint256,bytes32[])","2957ca33":"BONUSTWO_DATE()","2957d848":"batchWhitelistAddresses(address[])","2957da23":"ownerDestroy()","2957fef4":"redeemBalanceOf(address)","2958263a":"lastBucket()","29589f61":"tradeWithHint(address,uint256,address,address,uint256,uint256,address,bytes)","2959275d":"increaseCompanyCountByOne()","29594e4f":"hash(bytes32,address,uint256)","295961b1":"checkMinerQuest(address)","295a1cc2":"getNowTotal()","295a49ca":"Unclosed()","295a5212":"mode()","295a8b34":"update(uint256,uint256,bytes,bytes)","295b3299":"submitTopUpLimit(uint256)","295b4e17":"paid()","295c219c":"getMarketMakerAddress(address,address)","295c25d5":"addAmbassador(address)","295c39a5":"getNumMarkets()","295c6e4d":"setBytes32Slice(bytes,uint256,bytes32)","295d0eb5":"_buyAndCreateToken(uint256,bool,uint256)","295d2d69":"BotManageable(address)","295d4756":"PARSECS_TOTAL_AMOUNT()","295dad5e":"TriedToken()","295e0503":"transfreFrom(address,address,uint256)","295e1421":"getSaleOrderSeller(uint256)","295e3362":"getCutoffTime(uint256)","295f6ce7":"launchGame()","295fe611":"valueAtAddressLUT(uint256)","2960109d":"etherReceivedCrowd()","296032f2":"pauseContribution(bool)","29605e77":"transferOperator(address)","29610252":"payFee()","2961320c":"retrieveToken(address,address)","29638223":"greet(bytes)","29638eee":"GetTheWho()","2964a643":"checkPartner(address)","2964e4e6":"totalAccounted()","2965486a":"safeTokenWithdrawalFromCrowdsale(address,address,uint256)","2965558f":"getSignerIndex()","2965fa54":"ethers_collected()","2966d1b9":"unset(address)","2966e97b":"kscApprove(address,uint256,string)","29678a53":"playerInDraw()","29684907":"numerai()","29689a8c":"ergo()","2968d629":"YLCToken(uint256,string,uint8,string)","2968e640":"playerTakeOff(uint256)","29699a88":"viewSentBonuses()","2969b226":"batchTransferETHS(address[],uint256[])","2969d202":"weiBalance()","296b11b2":"getWeightedRandomArbiter(uint128)","296b76bb":"drawPhone()","296ba4ca":"LogValue(bytes32)","296ca48a":"weiLimitPerAddress()","296cab55":"setPresaleStartTime(uint256)","296cc401":"roundPrice()","296d84d5":"teamAdvisorsReserveTokensAddress()","296dbf31":"sendGameGift2(address,uint256)","296e3661":"removeClaim(uint32,string,string)","296ed88f":"testFailControllerInsufficientFundsTransferFrom()","296f1ce1":"getHasStartedState()","296f4000":"delegateApprove(address,uint256,address)","29700653":"fundTransfer()","297072a1":"cNiceGuyIdx()","2970c9c6":"TEAM_TOKENS_RESERVED()","29710388":"isProxy(address)","29712ebf":"accountBalancePublish(string,string,uint256,string,string,uint256)","29713781":"HumanToken(address,address)","29713f86":"cheapredeemvillage()","29723ade":"setMediumPrice(uint256)","29724d54":"offerOn(uint256)","2972b0f0":"isAuthorized(address,uint256)","29730ea4":"buyIdeas()","297398b5":"hourlyProduction()","2973e372":"isAlphaUpper(bytes1)","29745306":"tgrSetLive()","2974a822":"CustodianRegistry(address)","29750e85":"depositEndTime(address)","2975659d":"determineStatus()","2975c690":"SetLimited(address,bool)","29760657":"setStarDistance(uint8,uint16)","2977b1b1":"testAllowanceStartsAtZero()","29780a4e":"eventTransfer(address,address,uint256)","29781ec8":"addExemptedAccount(address)","29784d90":"shortenTde(uint256)","297882d5":"createDistrictOmni(uint8,uint8,uint8,uint8)","2978b826":"assignRevenue(uint256)","297a1f56":"carCount()","297a9dc4":"WalletFunded(address,uint256)","297b5dce":"private_setminRoll(uint256)","297c4143":"PUBLIC_START_TIME()","297c9cd9":"regStopTime()","297cb974":"FlightDelayAccessController(address)","297d1a34":"returnOwnership()","297d7964":"investors_locked(address)","297f119d":"transferToAdmin()","297f407b":"addWinner(address)","297f9af0":"membersCount()","29803b21":"join(string,string)","2980a7b6":"specialManagerOn(address)","2981155e":"weiPerDTH()","29816998":"right63(uint256)","2981cceb":"_mintFromDeposit(address,uint256)","29822734":"Win()","2982add7":"notContains(address)","29832c0f":"hasSigned(bytes32,address)","2983d752":"advisory()","29842d15":"TokenClaimed(address,address,uint256,uint256)","29846afe":"freezeAccount(address,uint256)","2984a077":"setFemaleBonus(address[])","2984bc4d":"getAreaInfo(address,uint256)","2984f486":"setBU(bytes32,uint256)","2984f999":"totalLockTokenAllocation()","298503d9":"createCategory(string,string,uint256)","298569f0":"SetApplicant(string,uint32,string,int256,string)","2985aacf":"getSponsorsN(uint256)","29864547":"feeIndex()","2986c0e5":"index()","2987ace5":"getCapsuleInfo(uint256)","2987c8f7":"checkProduct(bytes32)","2988e36b":"migrateBalance(address)","29893dcf":"checkKhFundDepositAddress()","298994c6":"getCET6InfoById(uint32)","2989ac22":"rollDie(address)","298a49da":"_0xDogecoin()","298aa634":"nextContributorToReturn()","298ac61c":"AgencyWallet(string)","298ad569":"CFOAddress()","298c0733":"send(address[])","298c154e":"addListing(string,string,uint256)","298c1e14":"COIN_PER_ETHER_SUPPORT()","298c3dc4":"addStrip(uint256,uint16,uint8,uint8,string,string,string,string,string,string)","298c3fc1":"changeFrozenBalance(address,uint256)","298c61e3":"TOTAL_TULIP_SUPPLY()","298d075f":"tokenPoolAddress()","298d3567":"depositBBO()","298d5f33":"getPI_edit_1()","298e4f79":"depositTokens(address,uint256,address)","298e685a":"getFrozen(address)","298fb0d2":"setEvenDistThresh(uint256)","298fbf1c":"ClaimBTC(string)","298febed":"towncrierCallback(uint64,uint64,bytes32)","2990194a":"setICOStage(uint256)","29913150":"createTicket(address,uint256)","29917954":"exitPool()","2991835f":"extract(address,address,uint256)","2991964c":"GameLoose(address,uint256,uint8,uint8,uint8,uint256,uint256)","29928852":"NoteChanged(string)","2993ed2d":"cancelSellOrder(address,uint256)","299453ca":"cb0f5ef7()","299550d9":"LogBetStart(uint256)","299599cc":"preICO(address,address,uint256,uint256)","29965a1d":"setInterfaceImplementer(address,bytes32,address)","2996f972":"tokenBurner()","29976934":"ModifyPublicKeySize(uint8)","2997ec89":"getStudentIDText(uint32)","29981db4":"setAdvocate(address,address)","2998dff2":"SuperUltraPowerCoin()","29991a5b":"checkMilestones(address[],uint256[])","29995f4c":"MoonStone()","2999c76b":"initNameSymbol(string,string)","299a017c":"getCurrentMilestone()","299a7bcc":"setOwner(address,address)","299af64b":"setContract(address,bytes32,bool)","299b861e":"changeUnitsPerEth(uint256)","299c55f7":"TOKEN_BOUNTY()","299cc524":"updateEarlyIncome(address,uint256)","299cdc9d":"changeEtherCost(uint256)","299df3f1":"WithdrawDividendsAndCoupons()","299e6b07":"Wallet(address)","299e7318":"resolveVoting()","299e7abb":"calculateWinners(uint32)","299e952f":"buyKeys(address)","299ed37a":"emergencyCall()","299ee814":"OraclizeBet()","299f5f1a":"cumAlienDeposits()","299f7200":"burnOwnership(address)","299ffcbc":"latestReleaseTime()","29a0097c":"internalSend(address,uint256)","29a00e7c":"calculatePurchaseReturn(uint256,uint256,uint32,uint256)","29a03d8d":"distributionReward(uint256,string,bytes32)","29a065bd":"getLOg(uint256)","29a19987":"teamVesting4Years()","29a2629c":"showRoundNum()","29a2aa2d":"thankYou(address)","29a2c27b":"finishLastCount()","29a2d339":"chknodenumber(uint256)","29a3fab9":"finilize()","29a40403":"submitCounterStack(bytes32,uint256,uint256,uint256,uint256,uint256)","29a52db6":"getCurrentUserLocalTokenBalance()","29a5c0f4":"WithdrawAllETH()","29a6344a":"removeSupporter(address)","29a64dd1":"startCrowdsalePhase2Date()","29a67202":"UHUGIN()","29a6f31b":"oraclize_query(uint256,string,string[2],uint256)","29a742aa":"HappyLifeCoin()","29a7d5c1":"joinAirdrop()","29a81222":"getOwnerName(uint8)","29a833ee":"getSumData(bytes32)","29a86dde":"getGameWin(uint256)","29a8cda5":"PolarisToken(address)","29a8fcd2":"Proxy(address,address,uint256,uint256,uint256)","29a9c91d":"setCurrentPeriod(uint256)","29aa1408":"getTotalFlips()","29aa7ec5":"removeSignature(string)","29aa9cbe":"min(int256,int256)","29aab068":"Pen(address)","29aacd10":"InitalPos()","29ab0ca7":"ownerSetResolverPercentage(uint256)","29abdeed":"addCoinBalance(address,uint256)","29ad27d7":"maxDays()","29ad4a34":"_transferMoneyMother(uint32,uint256)","29ae4c70":"isSenderEmergencyMultisig()","29aebf05":"initialMoySupply()","29aec173":"levelUp(uint256,uint16,uint16,uint16,uint16,uint16,uint16)","29b03cfd":"getBid(bytes32,uint256)","29b0de1e":"unsetManager(address)","29b0ffea":"numberOfPreviousEntries()","29b1ce4d":"addWhitelistedUserAddr(address)","29b1e640":"claimReporterReward(address)","29b20bb6":"numCharactersXType(uint8)","29b26bc1":"clearTradePreSignedHashing(address,address,bytes32,address,uint256,int256,string)","29b43a68":"createDepositAddressFor(address)","29b49825":"ADVISOR_POOL_INIT()","29b4d111":"price_start()","29b65a2e":"POCY()","29b6cdd5":"Alphacoin()","29b737ae":"LerToken()","29b84c9c":"transferExchange(uint256)","29b8caff":"totalInvestors()","29b8dab4":"currentBidNumber()","29b981bb":"operationAdress()","29b9f367":"addressDataProviders()","29ba1cb4":"setPrivelegedWallet(address,address)","29ba2e07":"TokenPoolExhausting(uint256)","29ba725a":"setTransformTarget_miner(address,uint256)","29ba7bb2":"initialOwner()","29ba8780":"executeTransaction(uint256,address)","29ba8d03":"getMigrateMarketInFromSiblingCalled()","29bb4bf2":"showCollectorsBalances()","29bc3b85":"isAccepted(uint256)","29bc5d0f":"finalyzeContract()","29bcb186":"transferToContributor(address,uint256)","29bd028a":"startIcoPreICO2ndRound()","29bd58b4":"revokeToken(address,uint256)","29bed3bf":"EthereumRoulette()","29bee342":"Get_Last_Value()","29bf56c3":"setUnitAttackIncreases(address,address,uint256,uint256,bool)","29bf960a":"getResultTable(uint256,uint256)","29c08ba2":"payPremium()","29c10e37":"filter(string)","29c19304":"setInitialVaribles(uint256,uint256,address,address,address)","29c1c61e":"modifyPowPrice(uint256,uint256)","29c1ee0d":"TOKENS_address()","29c3340f":"dividends_share()","29c36bb5":"feedAddress()","29c40d5f":"CheckSoilHumdtyException(bytes32,uint32)","29c50df4":"getEIN(address,address)","29c510b6":"reveal(bytes32,bytes32,address)","29c6647b":"addCET6(uint32,string,uint32,uint32,uint32,uint32)","29c71c1b":"modifyFeeShare(uint256)","29c78e0b":"Ethash()","29c886bf":"TokenCampaign(address,address,address,address,address,address,address,address,address,address,address)","29c8d3ce":"activateTokens(uint256)","29c8dae7":"create21PizzasTokens()","29c90b63":"onTapPollFinish(bool,uint256)","29c924cf":"setFundingGoal(uint256,bool)","29ca9dca":"updateRelay(address)","29caf0c9":"getStringValueByKey(string,string)","29cb924d":"getCurrentTime()","29cbdc86":"buyin(address,uint256)","29cca3ae":"getYouTubemasterReq()","29ccb4df":"getCompte_11()","29cd00f7":"approve(address,string)","29cd5777":"_tryEraseSingleNode(bytes32)","29cd62ea":"setPubkey(bytes32,bytes32,bytes32)","29cd7767":"_NT()","29cd92cf":"deleteHelper(bytes32)","29cdda23":"newVersion()","29ce0939":"Timeout(uint256,uint256)","29ce1ec5":"addFactory(address)","29ce3b69":"increaseApprovalAllArgs(address,uint256,address)","29ce7fc1":"getAllRightHand()","29cee59e":"finishCrowd()","29cf90f3":"sellUnicorn(uint256,uint256,uint256)","29d00d64":"ReloadKeys(uint256,uint256)","29d017b5":"TestWithConstructor(address,uint256[])","29d07c23":"registerForVoting()","29d0807b":"addone(uint256,uint256)","29d10b6e":"addSupervisor(address)","29d11b32":"btycbalanceOf(address)","29d24cbe":"TOKEN_SUPPLY_SEED_LIMIT()","29d287ec":"isFinishDateReached()","29d28aad":"Broker(address)","29d368e3":"curMax()","29d428ca":"requiredTokenAmount()","29d50682":"setupPlotOwnership(uint256,int256[],int256[])","29d56381":"balance_factor(uint256)","29d592bf":"arconaToken()","29d6ec95":"cancelBuy(uint256,uint256,uint256,uint256)","29d6f899":"BetOnBlue()","29d729ac":"ticket_addresses(uint256)","29d77446":"WhitelistSet(address)","29d91164":"delWhiteList(address,address)","29d98a7b":"change_individual_cap(uint256)","29da2fda":"UpdateToken()","29da3b4d":"removeBorrowingItem(uint256)","29da5738":"actionCount()","29daaa5e":"numFactories()","29dacb60":"getEthRaised()","29daf3ce":"create(bytes32,address,address,uint256)","29db191f":"approveForAll(uint256)","29db1a4f":"burnForInsurance(uint256)","29db3256":"getRandomBox(string)","29db8ec4":"getAccountSpendingRemaining(address)","29dbdd77":"updateDetails(bytes32)","29dcb0cf":"deadline()","29dd07eb":"KarlisToken()","29dd0b86":"lastSaleDate()","29dd0d7d":"requestBlokTokenOwnershipTransfer(address)","29dd8b26":"EGTToken()","29de91db":"setMsg(address,uint256)","29df8972":"Nilometer()","29dfdded":"addNewDonkey(address)","29e10c13":"getAd(uint256,uint256)","29e1ddb8":"freeLottoInfo()","29e206bd":"forceDivestAll(bool)","29e21cbd":"UIWish(address)","29e286c6":"boughtWithoutWhitelist()","29e2b478":"addAddressToWhitelist(address,address,uint256)","29e30910":"testThrowCreateExistingNonce()","29e341f1":"adminAddRole(uint256,address,uint256)","29e3ae3d":"virtualTradesSummedCount(bytes32)","29e46d3f":"openingTimePeriodOne()","29e5dab7":"BytomGoldToken()","29e614ee":"addDrop()","29e63cd7":"addImmutableContract(string,address)","29e67fce":"Rate2()","29e6b5be":"VPTToken()","29e6f3f8":"setPI_edit_6(string)","29e80a80":"_iWantXKeys(uint256)","29e81c79":"isJobCancel(address,bytes)","29e846df":"dividends(address,uint8)","29e8bc0a":"getShareToken(uint8)","29e94503":"VersionedBlob()","29e94ef6":"getProjectedJackpot()","29e99f07":"test(uint256)","29e9a3b9":"tokensReceived(address,address,uint256)","29e9afc9":"EnterCode(uint32)","29ea110c":"maxCapInCents()","29eae053":"setService(address,address)","29eae264":"EosChain()","29eae797":"oldController()","29ec09cc":"GetConfirmRound(address,uint8)","29ecd1e0":"PriceChanged(string,uint256)","29ed0f06":"BitcoinLegendToken()","29ed1297":"setItem(address,address,string,string,string,bool)","29ed82a1":"getDeflator()","29ed9a6a":"depositERC721(address,uint256,address)","29edd574":"buyCopper(uint256,uint256,uint8,bytes32,bytes32)","29edfbb8":"GetApplicant(address)","29ee0480":"FlatPricingExt(uint256)","29ee1580":"setMyPrice(uint256,uint256)","29ef1919":"discountPercent()","29ef5552":"setupZoomLvl(uint8,int256,int256,uint256)","29ef56b1":"getAskOrderBookStats()","29f0a422":"MakeTransfer(address,uint256)","29f11c8d":"edit(uint256,string,string)","29f1bff4":"withdrawFromChildDAO(uint256)","29f20618":"createLineItem(string,uint256,uint256,uint256,uint256[])","29f27577":"InvestorList(uint256)","29f321e4":"buy_Vault(uint256,bytes8)","29f3533c":"setPriceStalePeriod(uint256)","29f4071b":"RegistrationStatusChanged(address,bool,uint256)","29f46429":"WIE()","29f5fb9c":"icoTokenSales()","29f62f70":"logSendEvent()","29f69427":"o2Address()","29f6d9c3":"clearTokenApproval(address,uint256,bool)","29f75dc2":"samePooling()","29f799cb":"Studio()","29f7bd2f":"transferToContributionPool(uint256)","29f958dc":"publish(uint16,uint16,bytes4,string,bytes3)","29fa7266":"setSuperOwner(address)","29fb598e":"bountyTransfer(address,uint256)","29fc7bd8":"PERCENT_DIVIDER()","29fcfe2b":"VestingScheduleConfirmed(address,address,uint256,uint256,uint256,uint256,uint256)","29fcfeb0":"AUCTION_STARTED()","29fd06cf":"Qripplex()","29fd50eb":"libAddress()","29fd8201":"setReputationAddress(address)","29fec030":"MAX_DAILY_TOKEN_SOLO_SPEND()","29ff42e1":"revealHiddenPosition(uint32,int64[],bytes32,uint64,bytes16,bytes32,bytes32)","29ff4f53":"setReleaseAgent(address)","29ff7d04":"revertReservation(address,address)","2a004bd0":"deleteChannel(address,address,address,address,address)","2a00d284":"rewardReferrer(address,address,uint256,uint256)","2a00ff6f":"endianConvert256bit(uint256)","2a013925":"setFundingCap(uint256)","2a0213f6":"FeeOnAllocation(uint256,uint256)","2a022f22":"ALLOC_SALE_GENERAL_2()","2a035b6c":"endGame(address)","2a03b48b":"Campaign(uint256,uint256,uint256,address,address)","2a03ffa5":"CryptoGOToken()","2a0401f0":"confirmOrder(bytes32,bytes32)","2a040c16":"TemboCoin()","2a04e88a":"ethRateInUsdCents()","2a0763ce":"endGameConflict(uint8,uint256,uint256,int256,uint256,bytes32,bytes32)","2a095c14":"getCompte_3()","2a095fbe":"unlinkEID(bytes,bytes,address)","2a096397":"myDeposit()","2a0a3b53":"NewText(string,string)","2a0a5f50":"BidCanceled(uint256,uint256)","2a0acc6a":"ADMIN()","2a0b2617":"getAccountDetails(uint256)","2a0b9cb5":"check_authorization(address,address)","2a0bb7ea":"mulIsSafe(uint256,uint256)","2a0bba0e":"ImperoCoin()","2a0c5221":"battle(uint256,uint256)","2a0d06ec":"getTotalPctx10()","2a0d479f":"TutorialToken()","2a0d79ef":"totalSupply(bytes)","2a0deab4":"getDataAndOwner3(uint256,uint256,uint256,uint256)","2a0f189a":"setCallPtr(uint256)","2a0f3c35":"rentableSetup(uint256,uint256,uint256)","2a10abc3":"CrypteloERC20Address()","2a10ff23":"product2()","2a11b950":"contractEvents(uint256)","2a11ced0":"holders(uint256)","2a12b54d":"_transferToLock(address,uint256,uint256)","2a139f75":"PLATprice()","2a14314f":"satoeLocked()","2a14b80a":"partition()","2a151090":"canPerform(address,address,bytes32,uint256[])","2a16a9ee":"emitCategorySet(uint256,uint256,bytes32)","2a16cca4":"isApproved(address,uint256)","2a1727f8":"checkExistAddress(address)","2a174710":"getAttackForCost(uint32)","2a17e397":"multiTransferTightlyPacked(bytes32[])","2a1828fb":"attController()","2a18ca16":"currentSaleLimit()","2a19642c":"setSpawnProxy(uint32,address)","2a1a3303":"getNumberOfFlips(address)","2a1a8d4a":"updateIcoStatus()","2a1ab57e":"register(address[],uint256[])","2a1bbc34":"generate()","2a1be747":"rateFirstWeekEnd()","2a1c70e7":"Indemnisation_1()","2a1cdf7a":"enableReturnContribution()","2a1e37de":"armyCountBattlesLost(uint256)","2a1eafd9":"targetSupply()","2a1eb7cc":"MintToOwner(uint256)","2a1ef0ca":"teamAllocation(address)","2a1f63f8":"MiningRewardSent(address,address,uint256)","2a1fc45d":"decreaseArrayOfBeneficiariesBalances(address[],uint256[])","2a21566f":"grantPositionOwnership(bytes32,address,address)","2a21a3af":"isNormalUser(address)","2a22196d":"getVoucherDetails(uint256,uint256)","2a2235f2":"winAmount0()","2a226857":"AlbaritTokenV4(address,string,string,uint256,uint256)","2a228fc2":"processWithdrawals()","2a23475f":"blockCrowdsale(address)","2a23ac02":"eBitcoincash()","2a24b8e1":"instruct_4()","2a24f46c":"auctionEnd()","2a2514a2":"AceFundToken()","2a258842":"ETHOS()","2a2604dd":"bidRefund(uint256,uint256)","2a272974":"tokensIssuedForBonusRangeTwo()","2a27fd4a":"forGenesis()","2a286a19":"rewardSplitPercent()","2a286eda":"productAccounts(uint256)","2a2879d3":"createPromoCar(address,string,uint256)","2a28822e":"create(address,int256,address)","2a288272":"setUpgradesOwned(address,uint256)","2a28c610":"uint256_to_bytes(uint256)","2a292cce":"openCrowdSale(uint256)","2a29312a":"recoverAddressFromSignedMessage(bytes,bytes)","2a295c1f":"ChainMonstersCore()","2a29700f":"setForceExecuteOfContracts(bool)","2a2998a0":"houseFeeVal()","2a29c8d9":"getLoansLengthByClient()","2a29d109":"rewardController(address)","2a2a62f6":"removePrivelegedWallet(address)","2a2a6434":"register(bytes32,bytes32,address,bytes32,bytes32,string)","2a2ad4df":"ExpiringMembership()","2a2b48f5":"largestRetro()","2a2bb728":"ElephantsPaymentCoin()","2a2d78b0":"DeDeContract(address,uint256)","2a2dd486":"_computeAura(uint256,uint256)","2a2e00be":"MintingClosed(bool)","2a2e1320":"isEven(uint256)","2a2e2f0c":"convertInternal(address,address,uint256,uint256)","2a2e6358":"setMinRecharge(uint256)","2a2e6ee6":"countCrowdsalesForUser(address)","2a2eddde":"setVesting(address,uint256,uint256,uint256,uint256)","2a2f366c":"getPlayer(uint8[176],uint8,uint8)","2a2f7bda":"daysRemaining()","2a2fbd4b":"min_required_amount()","2a2fe110":"isCosignerSet()","2a304900":"getHunting(uint256,uint256)","2a305613":"transfer(uint152,uint152,uint256)","2a308b3a":"transfer(address,address,uint64)","2a30b0b8":"addARA(address)","2a316353":"JMTOKEN(uint256,string,string)","2a31c5b8":"_addBonusOfTop(address,uint256)","2a332b2a":"setLotteryAddress(address)","2a335c17":"getTotalSalaryBunny(uint32)","2a337d30":"submitMatch(bytes32,bytes32)","2a3386e5":"covmanagerAddress()","2a33fec6":"proceed()","2a3520e1":"addDataInstance()","2a3590b9":"mimetype()","2a35d251":"_move(uint256,address,address)","2a3602b2":"DayLimitMock(uint256)","2a369647":"getEndpointParams(address,bytes32,int256)","2a36b7ac":"TotalRate()","2a37d540":"CrowdToken()","2a37eaea":"buyWithHash(address,uint256,uint256,bytes32)","2a387bdd":"bsx(uint256,string,string)","2a388b1f":"cancelDeposit(bytes32,uint256,uint256)","2a389fdc":"Pray4Prey(uint128[],uint8[])","2a38d484":"getNumEntries(uint256)","2a3966ff":"setActiveStatusEgg(uint256,bool)","2a396734":"burnPXLRewardPXL(address,uint256,address,uint256)","2a39a069":"minInvestmentInWei()","2a39c1ea":"officialUrl()","2a3a236f":"setMasterContract(address)","2a3b1228":"RobotnikToken(address)","2a3c2c56":"getConversionFeeAmount(uint256)","2a3d05cc":"getSignedIndex()","2a3d30c2":"coinValue()","2a3dc703":"updateRewardLedger(address,uint256,uint256)","2a3de92f":"getCurrentBonusPct()","2a3e6ba1":"TOKEN_AMOUNT_ICO_STAGE1_PRE_SALE5()","2a3ec4ff":"takeICOInvestmentsEtherCommission(address,address)","2a3ef566":"EscapeCalled(uint256)","2a410068":"updateShares()","2a41360d":"processOfflinePurchase(address,uint256,int256)","2a41d1ff":"ArrAccountIsNotFrozen(uint256)","2a42e85f":"MiBoodleToken(uint256,uint256,uint256,uint256,uint256)","2a437269":"RCCCToken()","2a43b847":"TEACHToken()","2a43db3a":"Creature()","2a45a39a":"Post(address)","2a4654ab":"getAnimecard(uint256)","2a46d079":"MAT_UNIT()","2a472ae8":"checkIfCalled(bytes32)","2a4735c1":"EXOTokenSale(address,address,address)","2a47e08a":"Potato()","2a4802bc":"JINS()","2a4843a7":"freezeHeight()","2a486a28":"raisedETH()","2a48cabb":"testSwapTop()","2a491877":"lastTimeOf(address)","2a49222b":"isUsernameTaken(bytes32)","2a4a1a9b":"addFunds(address)","2a4a1b73":"vote(address,uint256,uint256)","2a4a8d68":"PRESALE_WEI_WITH_BONUS()","2a4a8e02":"stakedAmount(address,address)","2a4c7c6d":"initiateClaim(bytes32)","2a4caf67":"setDistenseAddress(address)","2a4d1a12":"CardExists(uint32)","2a4dc687":"callLib2(uint256)","2a4e0d55":"getTranscoderPoolSize()","2a4e4a84":"forx()","2a4ef2a3":"wpxTeamAddress()","2a4f1f21":"ACLYDTOKEN()","2a4f370f":"forTesting()","2a4ff14a":"Vlogchain(uint256,uint256)","2a50097b":"getPlayerBets(uint256,address)","2a501a43":"grantBonusDrops(address,uint256)","2a50d71d":"transferWithLock(address,uint256,uint256,uint256)","2a513dd9":"changeMinimum(uint256)","2a515949":"_attack(uint256,uint256,uint256,uint256)","2a523e89":"maxReferrerTokens()","2a52ee60":"createAuthority()","2a548276":"AddStaticProfit(address,uint16,uint256)","2a54d313":"pay(address,address,address,uint256,uint256,uint256)","2a555650":"HoneySuckleTimes()","2a55c47d":"TrumpFarmer()","2a55cab6":"UniCoinSize()","2a55feec":"isBuyer(address)","2a571b15":"strikersChecklist()","2a583b90":"withdrawRake()","2a5854d9":"getFreeSquirrel()","2a58b330":"nextOrderId()","2a595dd2":"GridcubeToken()","2a5b204a":"subCoinBalance(address,uint256)","2a5b51c3":"TokensIn(uint256)","2a5b68fd":"validate(bool)","2a5bfc7b":"isFunctionAuthorized(bytes32)","2a5c0e7c":"HomeBridge(uint256,address[],uint256,uint256,uint256)","2a5c2a64":"ITGCToken()","2a5c4675":"reservation()","2a5c65e4":"lookupInterest(uint256,uint256)","2a5c792a":"getAllTokens()","2a5cd45e":"getModuleIDByName(string)","2a5da7cd":"AnimatixToken()","2a5e695e":"Clean()","2a5eb26a":"BITCOINGAME()","2a5ed678":"currentContributionLimit()","2a5f6239":"_addReferrer(address,address)","2a5f6a0f":"setVariationCycle(uint256)","2a607962":"minCutValue()","2a608c0c":"VicoOwner()","2a60cf07":"FUTURE_DEVELOPMENT_FUND()","2a61ae19":"LockBalance(address)","2a61d47b":"getResourceSetCount()","2a62738b":"icoEndDate()","2a62b7fa":"IcoContract()","2a632eb5":"setUsdTokenPrice(uint256)","2a6389dc":"IsTransferFromOldContractDone()","2a649d6a":"returnFixed()","2a64e635":"simpleToken()","2a64fb63":"getSaleDate(bytes)","2a663686":"fpartSigned(int128)","2a666e01":"_fight(uint32,uint32)","2a66ede5":"giveMeETH()","2a677fb9":"getTokensForValue(uint256)","2a6852bf":"KOKOCoin()","2a6865e3":"PibbleToken()","2a69d486":"changeCraneStatus(bool)","2a69e1c6":"onlyWhitelistedCanDo()","2a69e7d9":"transfer(address,uint48)","2a6a5394":"TokenCappedCrowdsale(uint256)","2a6b157a":"CrowdsaleClosed(address)","2a6c703b":"RATING_EXPAND_INTERVAL()","2a6c7757":"kjhcoin()","2a6cc9bf":"QRReal()","2a6d474d":"usdPerEthMin()","2a6d6c08":"ReleasableAmount(address,uint256)","2a6dd48f":"approvedFor(uint256)","2a6dd8c9":"getPercent()","2a6dd9cb":"getInfoA(uint256)","2a6e3803":"getSoldAreasCount()","2a6e3e5e":"correct_check_match(uint256[39])","2a6efd76":"additionalRewards()","2a6f39ed":"deleteAllParents()","2a70214a":"TWD_Omnidollar()","2a707d2c":"personal_withdraw(string,uint256)","2a709b14":"tokenManager()","2a70d1e7":"registerInit(address)","2a711ab4":"voteTeam(bool)","2a714078":"triggerAuth()","2a71e729":"NAGACOIN()","2a724f2a":"reclaimAllAndBurn(address)","2a729061":"IDXToken()","2a7292d0":"createToken(uint256,address,uint256)","2a7318ac":"changePresaleEndDate(uint256)","2a73db5c":"GetContributorInformation(address)","2a741385":"subTokens(uint256,string)","2a745971":"BlockKing()","2a745ae6":"flowerAllowed(address,address)","2a74833d":"getUserSupportInTournament(uint256)","2a7575ee":"availableBalanceOf(address,address)","2a75a2ac":"addressFundAdministration()","2a75cb71":"removeOwnerRequest2(address)","2a764406":"CreateLRP(address,uint256)","2a76a169":"freezeMultipleAccounts(address[],bool[])","2a76ffae":"depositEtherForRefund()","2a774c27":"totAllocation()","2a776e3d":"setKYCLimited(address[])","2a7781cc":"postData(address,string,bytes32)","2a77b4af":"FEE_MUL()","2a77f2b7":"minMaxBuyETH()","2a7806e4":"noTokenLocked()","2a7813a4":"BitcoinBlackPearl()","2a781f78":"getKYCPresalePayload(bytes)","2a782802":"creatorBalances(address)","2a792f57":"buyAKeyWithAmount(uint256,address,uint256)","2a795d79":"bounty_allocation()","2a79fa0e":"TakePrize(uint256)","2a7a50a5":"Intro(string,string,string,string)","2a7a80a4":"trade(address,address,uint256,address,address,uint256,uint256,address,bytes)","2a7b0172":"dontSellRock(uint256)","2a7b2c93":"split(string)","2a7b3d4d":"resumeWhitelist()","2a7c24f1":"power(int256,int256)","2a7ca11f":"getMemeData(uint256)","2a7caaec":"FOUNDATION_WALLET()","2a7e0cc0":"createtoken(string,string,string,string,string,uint256)","2a7e5018":"timeVault(address)","2a7e60b6":"setRevealClosed(uint256)","2a7ef0cc":"IDEA()","2a7f26c4":"GetAllCurrencyIDs()","2a8014ca":"escrowAmount(address,uint256)","2a804835":"setCooldownEndBlock(uint256,uint64)","2a805069":"createToken(uint256,uint256)","2a808899":"getSkillCount(address)","2a8092df":"isMinting()","2a812941":"getInitializeDesignatedReporterAddressValue()","2a816e65":"factorWeight()","2a8219e2":"setFundingBlock(uint256,uint256,uint256)","2a827f99":"getTokenOwnerReward()","2a82fdbd":"approveAdd(uint256,address,bool)","2a835d67":"changePreIcoStartTime(uint256)","2a83cd70":"MrReaperToken()","2a845b9f":"ADPay()","2a8565b4":"GACT()","2a856fcf":"debit(bytes32[],uint256[],uint64[],uint8[],bytes32[],bytes32[])","2a858126":"tickerRegistry()","2a8587f9":"unAuthorized(address,address)","2a85a45d":"right38(uint256)","2a85b7dd":"getBackEtherFor(address)","2a862f1a":"notLessThan()","2a86eef3":"countDiscount(uint256)","2a874f34":"finishCampaign(bytes32)","2a87a86f":"shift(address,uint256,bool)","2a882d1d":"TokenHolderSnapshotter(address,address)","2a887299":"bid_threshold()","2a89d1bc":"TranchorToken(uint256,uint256,address,address)","2a89d6fd":"registerForGetTogether(address)","2a8a8b19":"bonusList()","2a8a8ebb":"unitStake()","2a8ab73c":"getProductOrderPayer(uint256)","2a8ade3a":"TotalCapacity()","2a8d1c61":"maxMask()","2a8d7baa":"claimCompanyReserve()","2a8de0ca":"DranMe()","2a8e251f":"BitcoinNature()","2a8e391d":"OperationsFund()","2a8eb9a3":"arpToken()","2a8ec8cc":"numberOfPledges()","2a8f368b":"RESERVED_COMPANY_GROUP()","2a8f6aa8":"TOKENS_FOR_OPERATIONS()","2a8faf95":"secondaryGasLimit()","2a8fd223":"Flagged(address,bool)","2a9043e4":"sellValue()","2a9046d8":"disableGeneration()","2a905318":"TOKEN_SYMBOL()","2a905ccc":"getAdminFee()","2a9078d6":"OWNERS()","2a909257":"MultiCappedCrowdsale(uint256,bytes32,uint256)","2a9121c7":"ethereumToTokens_(uint256)","2a91ab16":"doAirDrop(address[],address,uint256[],uint256)","2a922d54":"collectedAddresses(uint256)","2a92362c":"getPaid(uint256)","2a9278c5":"optionPoolLockTotal()","2a92bb17":"OPRAH()","2a92bffa":"setEditionPackPrice(uint8,uint256)","2a93b5bb":"pausePreIco()","2a943be1":"LIRAX(string,string,uint256,string)","2a952b2d":"process(bytes32)","2a952b4b":"setParents(uint256,uint256,uint256)","2a970043":"create(string,uint256,uint256,uint256)","2a98e802":"setPerformanceBonus(uint256)","2a9a86c1":"createBucket(bytes32[])","2a9b4921":"testManager(address)","2a9b6975":"SuperNanoCoin()","2a9b6dee":"pastFiveMinutes()","2a9ba092":"resizeIssuersArray(uint256)","2a9d04f0":"TOKEN_PRIVATE_SALE_CAP()","2a9e97f1":"matured_block_number()","2a9edf6f":"ownerSetStakeStartTime(uint256)","2a9f0fb2":"getPriceWithInterests(uint256)","2a9f1a79":"acceptPayment(address)","2a9fabd2":"betMatch(uint256,uint256)","2a9fb933":"MintExecuted(uint256,address,uint256)","2a9fb9b2":"userTransfer()","2aa0426c":"getAllBlocksByOwner(address)","2aa056cd":"shares_holders_count()","2aa073c5":"icoActive()","2aa0da47":"paymentSettings(string)","2aa1e848":"getPlayerAffT2(uint256)","2aa2b7eb":"T8CToken(address,uint256)","2aa2f7a4":"getOwnOrderByIndex(uint256)","2aa3177a":"self_store()","2aa37a41":"substractBalance(address,uint256)","2aa49dd7":"Pixiu()","2aa4c051":"setifoodDevAddress(address)","2aa531d9":"getPlayerData(address)","2aa5411f":"jadeRec(uint256,uint256)","2aa5ed61":"DayLimit(uint256)","2aa6f98b":"ledToken()","2aa71e24":"init(bytes32,address)","2aa852b3":"removeListener(address,address)","2aa8be8d":"createPermission(address,address,bytes4,address)","2aa9466b":"updateMyWorks(bytes32,address,address,bytes32,uint256,uint256)","2aaa308e":"finalize(address,address,address,address)","2aaa49f5":"percentageQuarter3()","2aaa9de1":"AlicToken()","2aab1351":"receiveFromSigned(address,bytes,uint256,uint8,bytes32,bytes32)","2aab22ff":"BonusReferrerCrowdsale(uint256)","2aab80dd":"optionPool()","2aabb48e":"nextContributionCap()","2aabffdf":"disableSaleAgent(address)","2aac6911":"poolBLock()","2aac8ad4":"getFirstAndSecondItem()","2aad292e":"setOperatingOfficer(address)","2aadafe8":"refundAdvertiser(address,uint256)","2aae7f26":"Arcturus()","2aae88f6":"removeFromGeneration(uint256,address)","2aaee1a5":"Drawer()","2aaef20c":"sixth_withdrawal(uint256)","2aaefa9f":"centsExchangeRate()","2aaf1685":"testControlCreateWithParentSameItemId()","2aafbf7c":"Getether()","2aafe9e7":"metToken()","2ab0252d":"getERC721AddrPawn(uint256)","2ab08396":"OwnersDb()","2ab0be77":"getTicketCode(uint256)","2ab0bf3c":"GetContributorData(address,uint256)","2ab13037":"votesNo()","2ab19a7e":"GoalMaximumReached(address,uint256,uint256)","2ab2174e":"subOnOneStage(address,uint256,uint256)","2ab22592":"updateWinnerBid(bool,bytes,uint256,bytes,bytes,bytes)","2ab24e3b":"commitVote(address,bytes32,bytes32,bytes32)","2ab26831":"getRateIco()","2ab28ce4":"buyTree(uint256,address)","2ab290fc":"updatejingzhi(uint256,string,uint256)","2ab34a91":"claimEnergy()","2ab4672a":"BatchCreateSaleAvgPrice(uint256[],uint256,uint256,uint256,uint64,address)","2ab4d052":"maxTotalSupply()","2ab4ebfa":"AddItem(address,address)","2ab6a50e":"payoutBigBonus(address)","2ab6f3f0":"BteamBets(uint256)","2ab6f8db":"renounceOperator()","2ab7173b":"lockup_startdate()","2ab72d2f":"assetIdOfToken(uint256)","2ab76377":"icoEndTimestampStage3()","2ab7961e":"aDeleteMessage(uint256,string,string)","2ab7d104":"_getAllRevisionIpfsHashes(bytes32)","2ab8de9b":"hash_ripemd160(string,uint256)","2ab8fc2d":"reservesPerTokenSrc(address,uint256)","2ab90d66":"ownerrestart()","2ab924d2":"HRCoin()","2abaa0c9":"picosCap()","2abaca23":"participate_in_arbits_presale_fiat(address,uint256)","2abd7fc8":"withdrawDao()","2abdbeb8":"forceOverStage()","2abdf1ef":"_update(string,uint256,string,uint256,uint256,uint256)","2abe4f60":"getInStake(uint256)","2abe5a2d":"getCandidate(uint32)","2abf2aae":"payMaxAuctionEther()","2abfab4d":"donationCount()","2abfaf1f":"setFreeTransfer(bool)","2abfbd28":"mintCommunityRewards()","2ac016ad":"addBackend(address)","2ac025ab":"removeAddressFromRole(address,string)","2ac08739":"getCurrentDuke(string)","2ac110c5":"icoPhase2Start()","2ac12622":"cancelled(bytes32)","2ac197c4":"IPMCOIN()","2ac1a995":"HiBTCToken()","2ac1db5a":"getEthToTokenUpdateOrderHint(uint32,uint128,uint128)","2ac20ed4":"createInitialDays(uint256)","2ac2af53":"updateParameters(bytes32)","2ac306b0":"BitCoin()","2ac364b4":"PalavraCoin()","2ac394a4":"durationBetweenRewardMints()","2ac48524":"getTokensCount(address)","2ac4a51d":"OVALExchangeToken()","2ac50df1":"tokenPriceOracle()","2ac68b78":"acceptPayment(address,uint256)","2ac69167":"StockLocation(string)","2ac6f15f":"exchangePreDGZTokens()","2ac71c16":"maxUSD()","2ac7f8ce":"CrowdSaleChanged(address)","2ac85e46":"isValidNode(uint256)","2ac87112":"ETHRaised()","2ac9bf09":"bid(uint256,uint256,uint256)","2aca2b16":"setInvestxPlatform(address)","2acada4d":"getAllAssets()","2acc204c":"killMeshPoint(int256,address,address,string,address)","2accf2f7":"splitFunds(address,address)","2acd1a95":"sling(string,string,string,string,uint256)","2acd2000":"removeFreezer(address)","2acd7e41":"transferOwnerToTest()","2acefd0f":"setCitySlogan(uint256,string)","2acf3908":"StealthGridToken(uint256,string,string)","2acf8551":"playMeta(address,address,uint256)","2ad02172":"MAX_PREICO_SUPPLY()","2ad0a4e9":"pauseNotice()","2ad11b9e":"getMinerals()","2ad12937":"OwnableToken()","2ad1bc09":"steal(int128,string,address)","2ad2a9f8":"transfer(bytes32,uint256,address)","2ad2ae2e":"collectLocalBounty(uint16,uint256)","2ad3274f":"UpgradeScheme()","2ad3509b":"ExcreteumToken()","2ad389e3":"constructHashRs1Rs2(bytes,bytes)","2ad3e8bc":"GreenChain()","2ad3ef70":"randContract()","2ad45312":"WEI_MINIMUM_PURCHASE()","2ad4d818":"userCreate(string,string)","2ad64a4d":"MAXCAP_TOKENS_PRE_ICO()","2ad8016e":"changeDiscount(uint256,uint256,uint256)","2ad8aaa6":"bonusAmmount(uint256)","2ad8d875":"getPayeeExpectedAmount(bytes32,uint8)","2ad8fbd2":"MerrierToken(string,string,uint256,uint256,bool)","2ad92740":"tokensPurchased(address)","2ad9527e":"h_pwd()","2ad95786":"winner(address)","2ad9618c":"startCrowdsale(uint256,uint256,uint256,uint256[],uint256[])","2ad99825":"setOwnerCutPercentage(uint256)","2ad9efc0":"UbayToken(address,uint256)","2ada2596":"getMember(address)","2adbb84d":"onFreezing()","2adbc396":"BurnableCrowdsaleToken(string,string,uint256,uint256,bool)","2adc2cd2":"COIN_PER_ETHER_ACTIVE()","2adc7da3":"setCentralBanker(address)","2add5a50":"cofounders(uint256)","2add78bb":"StartQ(string,string)","2addeab6":"getSolver(uint256)","2ade6c36":"getNodeAddress(bytes32)","2adf68bb":"UTPLToken()","2adf7d2f":"tenZero()","2ae1158d":"votingWeightOf(address,uint256,uint256,uint256)","2ae26d8e":"tenDecimalPlaces()","2ae3594a":"hit()","2ae418a4":"getPrivatePreSaleTokenBalance(address)","2ae4b85f":"MAX_HOST_PERCENT()","2ae524c2":"mintRiskTokens(address,uint256)","2ae6218d":"getBurnPrice()","2ae67563":"GameSicBo(string,uint256,uint256,uint256,address)","2ae72544":"length(int256)","2ae7c2df":"Ethernite()","2ae7c313":"Injected(address,uint256,uint256)","2ae8284a":"_newGame(uint256)","2ae8636d":"withdrawPRSTokens(address)","2ae87a70":"getNumContents(address,uint256)","2ae8a2d2":"sendFunds(address,uint256,uint256)","2ae8a7e3":"checkRole(address,bytes32)","2ae8b4a3":"actualGotETH(address)","2ae9782c":"MARRON()","2ae9c600":"protocolVersion()","2aea4d21":"sealer()","2aeaa291":"checkRewards()","2aeabfbf":"getLiquidityAndPositions(bytes32,address)","2aeacd4a":"exchangeTokensFromOtherContract(address,address,uint256)","2aebcbb6":"finishVote()","2aec3a71":"ProofOfHumanityAddOn()","2aec9466":"updateInfo(uint256,uint256,uint256)","2aed1390":"kyberContract()","2aed1905":"setMatchingEnabled(bool)","2aed256e":"inRangeToDisembark(uint16,uint16,address)","2aed7f3f":"reclaimContract(address)","2aee19c7":"testCreateWithNonce()","2aef3898":"ChangeMinSaleAmount(uint256)","2aef6ff6":"serviceTrasferFromDist(bytes32,address,uint256)","2aefb7c5":"funds_claimed()","2af004e7":"setReferralAddress(address,address)","2af05c4e":"lastMintingTime()","2af05d07":"unlockCurrentAvailableFunds()","2af0ac71":"getAmountSoldAfterPowerDay()","2af123b8":"diffHours(uint256,uint256)","2af1616d":"MissionToken(uint256,string,uint8,string)","2af1b5a2":"protectedUnlock(address,uint256,string)","2af1c247":"mint(string,uint256,uint8,string)","2af22e3b":"getJobs(address,uint256)","2af37ba0":"Donate(string)","2af38eab":"totalBspAmount()","2af39bab":"AssetBackedTokens(string,uint8,address)","2af3b7f8":"updateState(bytes32,uint256,bytes,bytes,bytes)","2af4c31e":"changeOwnership(address)","2af52312":"TRAToken(address)","2af5356a":"claimTeamTokens()","2af5cfdd":"priceOfEthOnEUR()","2af5e6b2":"setPriceEther(uint256)","2af6fb10":"ERC20TokenImpl()","2af7ac0a":"rtu(uint256)","2af7c4d7":"Certifiers()","2af7ceff":"testPrice(uint256)","2af7ecc7":"addRosenCertAdmin(address)","2af8afca":"dgt()","2af8b645":"release(bytes32,bytes32)","2af8fd94":"ISmartCert()","2afaca20":"buy(uint256,address,uint256)","2afb21bc":"InvestWithdraw()","2afb9fb1":"isCardTradeable(uint64)","2afbbacb":"canStake(address,uint256)","2afbc38f":"Annexe_SO_DIVA_SAS()","2afbe339":"QQQToken()","2afcdfbc":"createGen0Auction(uint256,uint256,uint256,uint256,uint256)","2afcf433":"PriceTwoEnable()","2afcf480":"invest(uint256)","2afd1a7d":"getReleasableAmount(address)","2afe4c37":"tokensleft()","2afe9f1e":"TestTokenContract()","2afed67e":"amountFundBounty()","2aff101c":"LinearDecayingTokenFunction()","2aff2843":"servusMultiSig()","2aff49d7":"setSizeAndRate(uint256,uint256)","2b000f00":"calculate_next_expected_wei(uint256,uint256,uint256,uint256)","2b00c6fd":"createHorseShoe1(uint256,uint256,address)","2b019692":"RYNote()","2b01bf51":"isValidMember(address)","2b028bbb":"LKCExchangeRate()","2b02d9af":"NIMBUS()","2b03b8d4":"IMDEXdeposit()","2b03d70e":"undisputeFavor()","2b04451a":"totalExtraOptions()","2b048f77":"getMyDeployAt(uint32,uint32)","2b04b478":"removeUsersFromGroup(bytes32,address[])","2b04d8f7":"takeOffer(uint256,address)","2b04e840":"getBalance(address,uint256)","2b05d346":"CallScheduled(address)","2b069816":"getJobValue(uint256)","2b071e47":"spread(address[],uint256[])","2b07682a":"withdrawFoundersTokens()","2b086b92":"convertToTMEX(uint256,address)","2b08fef7":"buy_token(address[],uint256)","2b093fe9":"TOKEN_MULTIPLIER()","2b0999f3":"initialYear()","2b09e707":"amountHives()","2b0aa1ed":"updateEthFee(uint256)","2b0ac7c4":"_createToken(uint256,uint256,uint256,uint256,uint256,address)","2b0cb194":"mintRawTokens(address,uint256)","2b0d0180":"luckyBuy()","2b0d0c6a":"afterFirstRefundRoundFundsReleaseNumerator()","2b0e16bf":"PRESALE_BALANCES()","2b0e64b3":"determineCommissions()","2b0ebfe9":"activatedJuryTokens(address)","2b0fbf72":"getMobster(uint256)","2b0fd89e":"ARcoin()","2b0fdb72":"MINIMUM_MANUAL_SIGN_PERIOD()","2b0ff02d":"listCard(uint64,uint128,uint128,uint24)","2b100a31":"setStatsSumHours(uint256,uint256)","2b1071c9":"testTransferToNullAuthority()","2b112e49":"getCirculatingSupply()","2b11e7f6":"SILVER_AMOUNT_SKL()","2b124245":"selfRegisterDINsWithResolver(address,uint256)","2b12553b":"saleExchangeRate()","2b13d799":"redeemedList(uint256)","2b1453dd":"addSwap(string)","2b146407":"PrivateSale()","2b14b712":"addClient(address,address,uint256)","2b14ca56":"sellFee()","2b151096":"placeSaleOrder(bytes8,bytes8,uint256,uint256,uint256)","2b15eb9b":"TongTong(string,string,uint256)","2b16b56a":"setIndex(uint256,uint256)","2b16f1ef":"nextPoolPercentage()","2b17355e":"balancesPrivate(address)","2b17b6a9":"bnbToken()","2b1841d2":"openCdp(uint256,uint256,uint256,address)","2b1857a5":"dividendPathways(address,uint256)","2b190f18":"getFreeTokens()","2b193ac4":"INITIAL_AC_SUPPLY()","2b198366":"addCertifier(address)","2b198808":"BloccaConto(address,bool)","2b1c511f":"getAvailability(address)","2b1c6982":"testTemp2()","2b1dd8da":"refundFees()","2b1e27f1":"migrateDomain(uint256,bytes32)","2b1e5016":"releaseTheHodl()","2b1ed01a":"warehouses()","2b1f7660":"PRZTToken(uint256,string,uint8,string)","2b1fcc10":"impl_cancelOrder(address,uint256,bool)","2b1fd58a":"acceptBid(uint256)","2b20e397":"registrar()","2b214618":"listAllBuyBalance(address,uint256,uint256)","2b21502f":"totalEthRcvd()","2b21d01b":"rateBTCxETH()","2b223264":"BitcoinBrand()","2b22a18c":"allocate8ProjectToken()","2b232741":"pullFromCirculation(uint8)","2b2443db":"canRaiseUsing(uint256)","2b2449b5":"setMaxCAP(uint256)","2b24aa6e":"rateA()","2b252d17":"_randomize(uint256,uint256)","2b25303b":"USDTUBE()","2b25a7e4":"giveKudos(address,uint256)","2b28d2d0":"totalFrozenAccountsMapping()","2b291eb6":"UserAddTicket(bytes)","2b29532b":"distributeLCASH(address[],uint256,uint256)","2b297f9e":"registerDao(address)","2b29908d":"BGB_address()","2b29fbfa":"testFail_voterNotCertified()","2b2b2882":"mintIcoTokenMultiple(address[],uint256[])","2b2badb3":"getAuditor(address)","2b2c71af":"doTradeofCollateral(address,address,uint256,uint256,uint256,uint256)","2b2c91b9":"refundApprove(address,uint256)","2b2dc12e":"RECEIVER_PAYOUT_THRESHOLD()","2b2e7159":"typeB()","2b2e76f3":"LA_wallet()","2b2f4d84":"setVestingParams(uint256,uint256,uint256)","2b2f88a8":"quantidadeDeAutorizacoes(address)","2b2fbd68":"minTicketEur()","2b302b60":"fairymasterReq()","2b30a84e":"rollTwo(address,uint8,uint8)","2b30d2b8":"invoke(uint256)","2b318568":"AddDynamicProfit(address,uint32,uint256)","2b321633":"testCloseChannel()","2b3297f9":"swapper()","2b337152":"totalissue()","2b343100":"newPlayerFee()","2b359e6b":"fundingTokens()","2b35d08a":"_computePrice(uint256)","2b36316e":"updateStageCap(uint256)","2b36a657":"profits()","2b379218":"globalDailySupply()","2b37d313":"tdeIssuer()","2b38ee56":"exitFee_()","2b3a4ae3":"adjustFeeEntitlement(address,uint256)","2b3b885d":"BGJC(uint256,string,string)","2b3c7562":"tierThreePurchase()","2b3da717":"BOBOTOKEN2()","2b3eae40":"MatchmasterTakeover(address,address,uint256)","2b3eb76c":"awardAmountPrime()","2b3ed526":"setFiatContract(address)","2b3ede1c":"WithdrawAll(address)","2b3f9f01":"_setSpendAvailable(uint256)","2b3fbbbb":"setPixelColor(uint16,uint16,uint24)","2b3ff9e9":"DLVO()","2b4143bd":"BasketRegistry()","2b4158cb":"buyFreePixels(uint256,uint256,uint256,uint256)","2b41a901":"grandTotalAllocated()","2b423b05":"changeRequiredMinor(uint256,bool,bytes)","2b42a89a":"setWhitelistOnlyPermission(bool)","2b42f4b2":"TokensCreated(address,uint256,uint256)","2b435366":"fund(address,bool)","2b4353f2":"payoutRate()","2b44d05f":"LISA()","2b44e5be":"distributeTokenToAddress(address,address,address,uint256)","2b44fd38":"dayLimit_()","2b455ac6":"insertMilestone(uint8,uint256,uint256,uint256)","2b459e81":"SpermLabsReborn()","2b45bcf9":"minimumHydroStakeUser()","2b4656c8":"initialize(address,address,address,uint256,uint256,uint256,uint256)","2b46e7f8":"SLUTZToken()","2b47571a":"resetWithdrawTimer(uint256)","2b47cb17":"TopToken()","2b49c9c2":"updateBanqueAddress(address)","2b49d425":"currentProposal()","2b49d9e5":"setFighters(uint32,uint32,uint256[])","2b4a27cb":"fechPreAllSumNumForCandidate()","2b4a2d0a":"getInfoFromCreateAuction(bytes)","2b4a3b31":"doTransferFrom(address,address,uint256)","2b4a964b":"networkGrowthAmount()","2b4bdf76":"getBdpController(address[16])","2b4ca103":"TXQToken(address,uint256)","2b4cbcc3":"getCombat(uint256)","2b4d0450":"BaseToken(string,string)","2b4d7c3e":"getPositionLender(bytes32)","2b4e8413":"userNumber()","2b4f79b3":"buyMessage(bytes32,uint256,string)","2b5129f5":"WaterMeterAcorn(bytes32,uint8,uint256,uint256,uint256)","2b513549":"mokenNameBytes32(uint256)","2b514749":"getTeamPrice(uint256[])","2b5184a6":"addSponsorship(address,address,uint256)","2b5187fd":"STCC()","2b521416":"features()","2b549b82":"createAuction(uint256,uint256,uint256,uint256,uint256,uint256,address)","2b54c3ce":"addToken(uint256,string)","2b554142":"redeemMany(address[],uint256[])","2b556813":"twitterDropMultipleAmount(address[],uint256[])","2b5570ad":"PatientFactory()","2b5630c2":"displayvehicledetails(address,uint256)","2b57298b":"getDate(uint256)","2b577ec4":"PREMINE_RELEASE(address,uint256,uint256)","2b58072f":"getDatasetsCount(address)","2b58150b":"setLotteryDuration(uint256)","2b587555":"privateTransfer(address,uint256)","2b58e202":"tokensOfOwnerFromIndex(address,uint256,uint256)","2b5914fe":"setUserName(string)","2b596a23":"balanceOfShares()","2b597e4d":"updateBool(bytes32,bool)","2b59d1fc":"borrar()","2b5ad2ad":"secondTimer()","2b5af004":"appendDecryptedBid(uint256,uint256,uint256,address,address,uint256,uint256,uint256)","2b5b6872":"AIRDROP_AMOUNT()","2b5da915":"Property(string,string,uint256,uint256)","2b5daa86":"newModule(string,address,bool,bool)","2b5f227e":"encodeBytes(bytes,uint8)","2b5faebd":"_calcTokens(uint256,uint256)","2b5fc4ce":"RSUNToken()","2b603c71":"allowances(address)","2b6133f5":"checkTierCap(uint8,uint256)","2b625874":"distributePeerTokens()","2b62ef2a":"CryptoCurrencyToken()","2b633f77":"ballotCancelingThreshold()","2b644ac8":"_setAvatarIfNoAvatarIsSet(address,uint256)","2b65d18a":"wireLimit()","2b65e040":"ownerPool()","2b664d8a":"getUsersByDocHash(bytes32)","2b680932":"ANNOUNCE_WINNER_DEADLINE()","2b68b9c6":"destruct()","2b68bb2d":"cancelContract()","2b68fc21":"guarenteedPaybackTime()","2b69f40d":"PaymentServ(address,address,address,address)","2b6a8b46":"addSpace(uint256,uint256,bytes,uint256,uint256,uint256,uint256,string,string,uint256)","2b6aa69d":"NewFunds(address,uint256)","2b6ada6d":"WalletWithDailyLimit(address[],uint256,uint256)","2b6b7c69":"airdropIndividual(address[],uint256[],uint256,uint256)","2b6bbc31":"testingOnly()","2b6bc920":"answerRequest()","2b6bd13a":"ChainInfo()","2b6c750f":"loseSponsor(uint32,int256)","2b6d7706":"transferTokensManuallyToMany(address[],uint256[],uint256)","2b6d7a66":"hasActivePass(address)","2b708fc9":"usageFee(bytes32,uint256)","2b70faf1":"game_paused()","2b711051":"investorsCount()","2b713d71":"rankToAddress(uint256)","2b71b0e5":"getStat()","2b7216e5":"donateToCampaign(uint256,uint256)","2b726758":"ETIC()","2b72c5fc":"FANCY(uint256,string,string)","2b73a83b":"CBS(string,string,uint8,uint256,uint256,uint256,bool,bool)","2b741ed6":"claimedFees(uint256,address)","2b7423ab":"average(uint256,uint256)","2b747a29":"buy_tickey(address)","2b750f4f":"DIVISOR_PRICE()","2b75289b":"placeBet(uint8,uint8,uint8,int256)","2b7568d9":"admin_withdraw_all(address)","2b7582c0":"sendEthForReward()","2b76823c":"ICOBuyer(address,address,uint256,uint256,uint256)","2b770ee9":"Ddjtab(uint256,string,string)","2b774d46":"XWALLET()","2b78194f":"GAS_REFUND()","2b7832b3":"adminCount()","2b783bc8":"addCredentials(bytes32,bool)","2b785960":"testBitAndSuccess()","2b788e33":"MAX_BOUNTYTOKENS_AMOUNT()","2b790ee4":"calcProfitFromTotalWon(uint256,uint256)","2b791053":"getDailyLimitRemaining()","2b791d6e":"storedDividendsOf(address)","2b79d7ba":"testFailMoveWithoutTrust()","2b7ac3f3":"verifier()","2b7b3a6c":"createBuildingAuction(uint32,uint8,uint8,uint8,uint8,uint8,bool)","2b7be84b":"AfterSchoolCrowdsaleToken()","2b7c3138":"MANETokenPartnerCrowdsale(uint256,uint256,address,address,address,address,address)","2b7ce9cd":"updateThresold(uint256)","2b7d13cc":"withdrawRemainingToken(uint256,address)","2b7d177b":"isvalidOrg(address,address)","2b7dd488":"totalLBSold_GENERAL_3()","2b7e063e":"GenOutChipsNum(uint256,uint256,uint256)","2b7e2169":"getTotalSell(uint256)","2b7e4295":"invadePlanets(uint256,uint256[],uint256[])","2b7ec7fe":"getLotInvested(uint256,address)","2b81b8a4":"alreadyRegisteredMessage()","2b82714f":"deliverAngelsREDAccounts(address[],uint256[])","2b828e4a":"addTx(bytes32,bytes4,address)","2b82aed6":"setPayerAddr(address)","2b82cf1f":"unFroze(address,uint256)","2b84aabe":"trust(uint8)","2b84fe83":"reserveFeeToBurn(address)","2b85ed9c":"purchaseCount()","2b860e6d":"transferToThroughVariable(address,uint256)","2b861629":"storeBlockHeader(bytes)","2b865dea":"airdropTokenDistributionMulti(address[],uint256[])","2b86d48a":"MDKToken(address)","2b876784":"ZHOUToken()","2b877dfd":"sendCoin(bytes4,bytes32,bytes32,uint256)","2b878c7c":"KYCValid(address)","2b88c42d":"buyItem1()","2b88cbbf":"getExcludes(uint256)","2b8a1c00":"t2tokenExchangeRate()","2b8a1c5a":"setGuardian(address,bool)","2b8a36e0":"freezeTransferTime()","2b8a789b":"ChangeGameHidden(address)","2b8af65b":"INTERFACE_SIGNATURE_ERC165()","2b8b09d4":"REDGIL()","2b8b1bc4":"transferAndFrostTokens(address,uint256,uint256)","2b8b6667":"deregister(address[])","2b8bbbe8":"add(uint256,address)","2b8c8a20":"Sale(address,uint256,uint256,uint256,string,uint256)","2b8cc346":"acceptRequest(address)","2b8cd2f7":"withdrawUncommittedTokens(uint256)","2b8cd5c6":"getComponentSupport(uint16)","2b8d0cd7":"setIcostart(bool)","2b8e4df1":"vest(bool)","2b8f2042":"withdraw_funds()","2b8f7a49":"depositMoney(string)","2b8f899e":"OzoneToken()","2b901a0a":"getOwnerByName(bytes32)","2b90557c":"minSet()","2b905bf6":"TEAM_WALLET()","2b90bb3a":"distributeGoTokens(address,address)","2b9122df":"getTimeTillEnd()","2b913151":"secondCapEndingBlock()","2b919aa6":"validPurchaseSize()","2b920a6b":"CampaignAccountFactory(address)","2b925b25":"minimumInvestment()","2b92b8e5":"hashValue()","2b92c776":"cancelBuyOrder(address,uint256,uint256,uint256,uint256)","2b9530d8":"transferTokens(address,uint256[])","2b956ff7":"getUserId(address)","2b968958":"revokeOwnership()","2b96a0a1":"getGamesMeta(uint256[])","2b96c00e":"abortGame(address,uint256)","2b97c6e4":"Cilox()","2b98222e":"getInstitutionByAddress(address)","2b985942":"LittleStoreERC20Token()","2b985f7c":"testNegatives(int256)","2b9897fb":"smallCapLimitOf(address)","2b991746":"approveFor(address,address,uint256)","2b99a087":"getLpIsWorking(int256)","2b99db6a":"tokensApproved()","2b99f359":"carOfByIndex(address,uint256)","2b99f3e1":"setIsTurnDataSaved(bool)","2b9a5c34":"_getTileAt(int32,int32)","2b9a7fae":"_updatePlayerOverrideId(uint256,uint256)","2b9b7573":"MAX_TRANSFERS()","2b9be92e":"GanaTokenAirdropper(address)","2b9cb4f8":"uniq(uint64[])","2b9cd08b":"submitAddOwnerTransaction(address)","2b9ce01e":"currentIcoTokenPrice()","2b9e05d1":"Betportchain(uint256,uint256)","2b9e5088":"filterTransactions(bool)","2b9e98b1":"changeFundingPercentages(uint256,uint256,address)","2b9edee9":"softCapReached()","2b9fd446":"isHatchOnCooldown()","2ba00198":"setBaseCap(uint256)","2ba0ab78":"EyeToken()","2ba0b09f":"AddNewCategory(bytes4,uint8,uint8,address)","2ba11f2a":"CONVERSION_DECIMAL_FACTOR()","2ba1e439":"createOraclizeCallback(bytes32,uint256,uint8,uint256)","2ba25366":"mintInBatches(address[],uint256[])","2ba29217":"canExecute(uint256,uint256)","2ba2d714":"LordXChain()","2ba2ed98":"setMagicNumber(uint256)","2ba5390f":"isFirstPartReleased()","2ba5b90d":"get_number_of_DBs()","2ba665e5":"getDoc(uint256)","2ba6d8fe":"PRESALE_WEI_CAP()","2ba73c15":"setCOO(address)","2ba7910a":"provider1()","2ba7fc87":"tgeIssuer()","2ba8b7e4":"getMinimumAuctionPrice(uint256)","2ba8f526":"OfferToGuardian(uint256,uint256)","2ba96462":"supportsERC165Interface(address,bytes4)","2ba996a5":"getListedTokens()","2baa2c58":"disqualifyBid(address,bool)","2baab935":"Fuschain(address,uint256)","2baabbf7":"finalSupply()","2babd014":"sellSecond(uint256)","2bac0b3b":"vendingCreateCollectible(uint256,uint256,address)","2bac276b":"badgeTransfer(address,uint256)","2baeceb7":"decrement()","2baf2acb":"mintTo(address,uint256,uint256)","2baf4f22":"_safeFalse()","2bafc817":"EpietherToken()","2bb03ab9":"earlyPresaleEDUSupply()","2bb03f6d":"ValidateCitySnapshot(address,uint256)","2bb0e10b":"serviceAccount()","2bb14104":"myData()","2bb20f4a":"soulsSold()","2bb22480":"calculateDrugSell(uint256)","2bb3dcc8":"totalInvocations()","2bb4c7d5":"STribeToken()","2bb51a05":"EDEX(address,uint256,uint256,uint256)","2bb685bc":"kill2()","2bb6ccf1":"delAuditAddress(address,address)","2bb70e54":"lockMasterTransfers()","2bb768f0":"adminGetCityData(address)","2bb81546":"getClaim(string)","2bb9cb1d":"buyXid(uint256,uint256,bytes32)","2bb9ffef":"startBalance()","2bba2d6d":"changeInvitedReward(uint256)","2bbb44b8":"adminCreat(address)","2bbc50b5":"getTotalInvestedEur()","2bbc9396":"periodICOStage2()","2bbd3c93":"ART_CONTRACT_ADDRESS()","2bbd59ca":"messages(bytes32)","2bbd84e8":"totalPurchaseValueInWei()","2bbd88f3":"LOBO()","2bbd9530":"unregisterAddress(bytes32)","2bbdb18a":"hasEnoughApproval(uint256,uint256)","2bbe62d6":"createSetup(address,uint256,uint256,bool,address,uint256)","2bbeac91":"lockTokenHolder()","2bbf532a":"isUnlocked(address)","2bbf54e8":"isBuyStopped()","2bc06a92":"canSend(address)","2bc0fe34":"infoMining(address)","2bc24d52":"IXTPaymentContract(address)","2bc31ca4":"developers()","2bc3217d":"forbid(address,address,bytes32)","2bc3656c":"buyTokensPreSale(address,uint256)","2bc38531":"setup(string)","2bc3a349":"GWTCrowdsale()","2bc402fa":"TOTAL_PREALLOCATION()","2bc40f9a":"setAddressUInt8(bytes32,bytes32,address,uint8)","2bc43fd9":"claim(address,uint256,uint256)","2bc46f27":"getQuestionIndex(uint256)","2bc4aa1a":"showInvestEther(uint256)","2bc53254":"priceFci()","2bc542a4":"votePublic(address,bool)","2bc57d73":"_doTransferFrom(address,address,uint256,bytes,address,bool)","2bc588ee":"release(uint256[],uint256[])","2bc5ca7a":"fullCycleSellBonds(uint256)","2bc5f9cb":"updateRateInWei()","2bc6597c":"depositsTillNow()","2bc67bde":"MIN_TASK_VALUE()","2bc80f3a":"T()","2bc85d5d":"updateTokenPriceProvider(address)","2bc86dc0":"AddBankerRound(uint8)","2bc89ff6":"REV()","2bc8ba53":"solicitaPagamento(uint256)","2bcb849c":"updateFeeProvider(address)","2bcbdf7f":"s29(bytes1)","2bcbe1b5":"getCelebrity(uint256)","2bcc79a7":"MockDeed(address)","2bccf04e":"createSale1()","2bce9e7b":"updateToken(address,uint256)","2bcef221":"signOne()","2bcf300e":"LC(uint256,string,string)","2bcf5760":"addToken(address,address,uint256,uint256,uint256,uint256)","2bcf892c":"div32(uint32,uint32)","2bcfcd7b":"getBonusAmount()","2bcfe0a6":"FitToken()","2bd00610":"numberOfCyclePlayers()","2bd0bb05":"totalSpentPerDay(uint256)","2bd0ce0f":"cancelBuyTokenOrder(uint64)","2bd152f0":"_getCollectibleDetails(uint256)","2bd185e5":"appendTokenHolders(address)","2bd21738":"CAIDCrowdsale(address,address)","2bd2523e":"cooAddReviewer(address)","2bd2a965":"openNextSale(uint256,bytes24,uint256,bytes24,uint256)","2bd30ca3":"costContract()","2bd4aa40":"total_amount(string,uint256,uint256)","2bd543c7":"calcTimedQuota(uint256,uint256,uint256,uint256)","2bd55918":"confirm_token_deposit()","2bd57604":"claimPlotMultiple(uint256[],uint256)","2bd579fc":"ico(uint256,uint256,uint256,uint256,uint256[],uint256[])","2bd5a48d":"finishMintingToken(uint256)","2bd5e353":"phase3Duration()","2bd71875":"hasMissedCheckpointSubmission()","2bd75c3c":"sendMarketingAndRNR()","2bd7cd17":"killToken()","2bd928e4":"commonDeposit(address,uint256)","2bd9530a":"editGas(uint256,uint256)","2bd97c6d":"getDawexSignature(string)","2bda04c5":"autoFreeze()","2bda1a55":"frozenReserveTeamRecipient()","2bda2a49":"BHIMToken()","2bda4eee":"getBridgeValidatorsInterfacesVersion()","2bdad637":"tokensSupply()","2bdb0d92":"getShareToken()","2bdb33c3":"getNumberOfDisputedDealsProPatient()","2bdb7097":"setRate(address,uint256)","2bdbc0ce":"ContractTokensReclaimed(uint256)","2bdc05c5":"assertEq26(bytes26,bytes26,bytes32)","2bdcd90d":"claimChip(uint256,string)","2bdd2290":"setBlockNum(uint256)","2bdd530b":"holderReferalTokens()","2bdd5958":"Purchased(address,uint256,uint256,uint256)","2bddb9b5":"canTransferIfLocked(address)","2bddc31c":"coauthor()","2bde41e1":"submitRing(address[3][],address,uint256[7][],uint256,uint8[1][],uint8,bool[],uint8[],bytes32[],bytes32[],uint256,uint16)","2bde8e96":"getGPShashRandomValue()","2bdf66d5":"SmartToken(string,string,uint8)","2bdfbd39":"finaliseCrowdsale()","2be09561":"startMint()","2be10384":"_removeKey(address)","2be29d71":"addressPartnerships()","2be2ad3c":"logUniverseForkedCalled()","2be2d95e":"amountOfInvestments()","2be2f085":"getCostForRace(uint8)","2be32dbb":"categoryCount()","2be3d1c9":"_getDroneDefaultAbility(uint256)","2be4a903":"removeUsers(address[])","2be4f3f5":"boardCost()","2be4fd9c":"getRemainManus()","2be51660":"calcTime()","2be521b2":"increaseBalance(address,address,uint256)","2be52293":"setExchangeOracle(address)","2be596ee":"unpauseInternal()","2be5e93a":"TOTAL_SUPPLY_UPPER_BOUND()","2be64f51":"RegisteredCampaign(address,uint256,address)","2be65e2a":"getFree()","2be65e45":"setMarketingRates(uint256,uint256,uint256)","2be6d43c":"ARKTagger_1_00()","2be6ec1f":"NULL_ENCRYPTION_ALGORITHM_ID()","2be79833":"nonFungibleRegistry()","2be86e01":"jcrUsdRate()","2be8c2a5":"transferTokensTo(address,uint256)","2be8f373":"changeWLMWallet(address)","2be90846":"enableBonus()","2be98d38":"HourglassV2()","2be9da97":"getBestAngel()","2beaead0":"lastDivideRewardTime()","2beaf416":"ShareXERC20()","2bec76fd":"maxBetCoinDice()","2becb6f7":"STARTING_SPERM()","2bed55b0":"buildDSEasyMultisig(uint256,uint256,uint256)","2bed69e0":"founderPercent()","2beea5c5":"testhash(uint256,uint256)","2beeaca4":"whitelist(address,string)","2bef4595":"authorize(address,address)","2bf04304":"whitelistAddresses(address[])","2bf0aeda":"DigiToken()","2bf1aa1d":"EthHodler(string,uint8,string)","2bf1f9da":"restart(bytes32,bytes)","2bf29ddb":"EventRedeemRisk(address,uint128,uint256,uint256)","2bf34551":"setRate340()","2bf34e60":"getUuid(uint256)","2bf37c42":"addFunds(uint256,address)","2bf435f9":"myMethod(string)","2bf4760b":"getEthPerfit(address)","2bf4d812":"AumentaToken(uint256,address)","2bf4e53d":"getCurrentShareholders()","2bf59135":"addLootbox(address,uint256)","2bf5a2ea":"mintForFounders()","2bf6e0a5":"setContract(address,address)","2bf7299b":"setMaxParticipants(uint256)","2bf79c94":"getTokenByOwner(address)","2bf7d279":"shouldRevertWithReturn(bool)","2bf7f6ba":"privateSell1LockEndTime()","2bf81dd3":"NPTToken()","2bf82843":"pay(address,uint128,string,uint32)","2bf885f0":"addNote(bytes32,bytes20,string)","2bf8faba":"AimiToken(address,uint256)","2bf9ab0b":"getPresellUpToTime()","2bfacd62":"calculateLockedBalance(address)","2bfaf3da":"Oracle(bytes32)","2bfc33ee":"KDI()","2bfc4c69":"getStringValue()","2bfd2a13":"calculate_dividend(uint256,uint256)","2bfd2e06":"buyBasicUnit(uint256,uint256)","2bfd91d4":"getMessageSigner(bytes32,uint8,bytes32,bytes32)","2bfda313":"getFile(uint256)","2bfe243f":"minStartPriceForCommishAuctions(uint128[])","2bfea0e4":"unpauseTransfer()","2bfefd5c":"calcMultiStage()","2bff4b66":"reapFarm(address,address)","2bff5630":"coachTakeOff(uint256)","2bff5fc4":"Incomplete()","2bffc7ed":"add(string,address)","2c011e7b":"winning_month()","2c01bb1c":"LogNewOwner(address)","2c01d52b":"_createRegion(string,address,uint256)","2c027eb9":"getDeployArrayLength(uint256)","2c02d622":"precalculate()","2c035157":"calculate_minimum_contribution()","2c044779":"getPublic()","2c04bf0c":"transferIXT(address,address,string)","2c052031":"getInsertPointForNumTokens(address,uint256,uint256)","2c0657c2":"additionalBonusAmounts(uint256)","2c06862b":"setCanBuy(bool)","2c07398d":"registerObserver(address)","2c0784ce":"send_DividendToAddress(address,uint256)","2c089048":"tokenCreationInit()","2c08ab0c":"ENJCrowdfund(uint256,address)","2c08eb0b":"changeTokensPerEther(uint256)","2c0994c1":"getMicroWalletAddress(uint256)","2c09bef7":"priceSetter()","2c0a036b":"resetICO()","2c0a33ef":"BethereumToken()","2c0a3f89":"castVote(uint256,uint256)","2c0a5c08":"BuyIn()","2c0a7e33":"pendingEthWithdrawal()","2c0aadc1":"nextGameInitialMinBetSize()","2c0b9685":"distributeeBTG(address[])","2c0bec2f":"sendCurrentPayment()","2c0c6488":"AirTrafficController(string,address[],address,address)","2c0c8563":"SetCoin(address,address)","2c0d0dbe":"AddProduct(uint256)","2c0d4e70":"RYNOTE()","2c0e0054":"lockInGuess(uint8)","2c0e3850":"storeInContract(address,address)","2c0f13a7":"icoStartTimestampStage3()","2c0f7b6f":"numCampaigns()","2c0fc8cb":"registerHandle(bytes32)","2c10e90c":"update(address[],uint256[])","2c1169ac":"ELOT()","2c12cc79":"HuumanStandardToken(uint256,string,uint8,string)","2c1352cf":"contacts(address)","2c135b93":"marketCap()","2c138236":"reservedTokensWallet()","2c142511":"_offlineHash(bytes32,bytes32,bytes32)","2c145eef":"DutchAuction(address,address,address,address,uint256,uint256,uint32)","2c154345":"getParticipantStake()","2c16c6ca":"addPrivilegeAddress(address)","2c16cd8a":"record(uint256)","2c174073":"PeriodSale(uint256,uint256)","2c181929":"getChainWork()","2c183fad":"mintTokenWithUnit(address,uint256)","2c197985":"VirtualExchange(address,address)","2c199889":"request(string)","2c19d480":"emitAccessGiven(address,bytes32)","2c19fbbb":"getUserTX(address,uint256)","2c1b17e4":"BonBonToken(address)","2c1b38ee":"isValidTokenId(uint256)","2c1bcb4f":"ContractLocked(uint256,string)","2c1cf6f6":"updateTradeStatus(bool)","2c1cf78b":"ETHinvested()","2c1d68d4":"countStakeHolders()","2c1e064b":"_translateWSIC(uint256)","2c1e6e48":"getADminFromDutchProxy(address)","2c1e816d":"setAdminAddress(address)","2c1ea461":"nextController()","2c1eed5f":"isPlayer(address,address)","2c1f1f8f":"getFreeBalances()","2c1fecfe":"isRefundable()","2c1ff9f8":"mInviteAddr()","2c203edd":"getOrderDetails(uint256,uint256)","2c2146aa":"verify(address,address)","2c215998":"updateStatus(string)","2c21ec94":"ethUpdates(uint256)","2c2206e4":"setAuditReportHash(uint256,string)","2c22af02":"cidTokenSupply()","2c22f2e2":"burnSplitPercent()","2c237912":"processSellRequestFiat(uint256,uint256)","2c244618":"calculateVestedOptions(uint256,uint256,uint256)","2c24909c":"getVotedTokensPerc()","2c24ecc7":"BecToken()","2c2622db":"LOCK_SLOTS()","2c2689b5":"getModuleAddress(string,string)","2c270617":"TempleDonationTrackingNote()","2c270c7e":"tokensFor1EthP2()","2c276699":"CheckOut(uint256)","2c27e581":"publicEndTime()","2c28aa1b":"RATE_FOR_WEEK3()","2c28f579":"goLive()","2c296656":"changeRequiredDevSignatures(uint256)","2c297478":"prolongH(uint256)","2c29eedd":"startPrivateSale(address,uint256,uint256)","2c2aa66c":"PokeCentral()","2c2aecf5":"isProcessNeeds()","2c2b4358":"setPercentOfPool(uint256[])","2c2bc50b":"LOWIQ()","2c2ccdfb":"kittyCoreAddress()","2c2da3cf":"expPercentage()","2c2de40a":"setMaximumSellableTokens(uint256)","2c2e3abe":"allocateFoundersTokens()","2c2fdc35":"getBalanceFromRound(address)","2c305abf":"updatePlayedNum(address,address,uint256)","2c308714":"returnBetAndOffer(uint64)","2c321ea1":"abToken()","2c327538":"ProofOfDiligenceToken()","2c329e99":"Last_block_number_and_bloctime_used()","2c344d14":"tokenRewardPreDGZ()","2c349627":"pauseToken()","2c34ce05":"increasedPrice()","2c34e6b9":"addDepositQuest(address)","2c354067":"executionBlockOf(uint256)","2c3599a5":"VINToken()","2c3788b1":"registerUserIfNeeded(uint256)","2c37a512":"bountyLockEndTime()","2c39d855":"confirmAndForward(address,uint256,bytes,bytes32,uint256,uint8,bytes32,bytes32)","2c39da94":"batchSend(address,uint160,uint256[])","2c3a15a0":"EidosToken(address,address)","2c3a1d5d":"Nerotoken()","2c3af973":"GStarToken()","2c3ba9e1":"addManyRegistered(address[])","2c3c42b2":"WLM()","2c3ca924":"handleProductionIncrease(address,uint256)","2c3ccb98":"levelUpByPenguinId(uint256)","2c3d3453":"csale()","2c3d38f0":"mintTokens(int256,uint256,address,address)","2c3dcdcf":"issueDuringICO(address,uint256)","2c3dfca7":"getPhException(bytes32)","2c3ee88c":"getRedeemAmount(uint256)","2c3f1304":"getSlotLength()","2c3f6a4f":"getMineCooldown(uint256)","2c3f9b80":"getActiveFlagRate(uint16)","2c408059":"getFallbackAddress()","2c409871":"MobileTokenAlert()","2c416754":"doBurn(address,address,uint256,bytes,bytes)","2c420201":"getDataCounterForSubject(uint256)","2c421074":"exploreETHFee()","2c425687":"EthTeamContract(string,string,address,uint64,uint64,address)","2c42f2e8":"toSendFromStorage()","2c4449ab":"_rankByNumber(uint256)","2c445273":"_payEthereumAndDistribute(uint256)","2c4464d4":"Dryad()","2c4482c5":"_assignCountry(uint256)","2c44a261":"updatePrivateSaleCloseTime(uint256)","2c45f068":"transfer(uint128,bytes16,uint32)","2c4617d7":"getMethodState(string)","2c46b205":"query()","2c46d8d5":"EndRound(uint256)","2c47413f":"ERC20PGEToken()","2c4806d8":"ordersFor()","2c4879d1":"AFWBurn(uint256)","2c4881ff":"withdrawMoneyByAdmin(uint256)","2c48e7db":"confirmTransfer(uint256)","2c4a84f7":"StaxToken()","2c4ab666":"enact_withdrawal_greater_equal(address,uint256,uint256)","2c4ac770":"sendMessage(address,bytes,bytes32)","2c4aecc1":"sampleBoolRetFalse()","2c4b2334":"setTeamWalletAddress(address)","2c4b27ae":"burnAirDrop(address[],address)","2c4bca2c":"crowdsaleDeadline()","2c4bf8bc":"increasePresetTransfer(address,uint256)","2c4c2719":"MAXIMUM_CAP()","2c4cb4be":"removeRegistryFromNameIndex(address)","2c4d25f5":"DeathFactor_ii()","2c4d4d18":"changeMinter(address)","2c4e55c5":"killedContract()","2c4e591b":"totalGames()","2c4e722e":"rate()","2c4e8885":"unLinkFromMasterWalletInternal(address,address)","2c4e9d2b":"AuctionWon(uint64,uint64,address,uint256)","2c4ee4d4":"ObirumTalk()","2c4fa8b2":"assignAnotherOwner(address)","2c5104f5":"MTC()","2c511788":"addToWhitelistAllocation(bool,address,uint8)","2c512d6e":"getTokens(address,uint256)","2c526196":"_mint(uint256)","2c52d930":"feeForArtWorkChangeRequest()","2c532a71":"ChangeCrowdSaleDate(uint8,uint256)","2c5337dd":"winnerAnnounced(address,uint256)","2c53f31b":"bonusWindow2EndTime()","2c54357f":"lifeReserveAllocation()","2c54de4f":"transferToken(address,address,address,uint256)","2c54e6d9":"getCanvasCount()","2c560ec0":"queryInfo()","2c56462f":"addAllowedContract(address)","2c566ae5":"length(address)","2c572eb5":"_isFuture(uint256)","2c574a94":"next_tower_index()","2c577347":"changeMakeFee(uint256)","2c57fdf4":"create(uint8,uint8,uint64,uint64)","2c580a35":"revokeAndReclaim()","2c58139c":"teamRelease(address)","2c5a736f":"distributeInitialFunds()","2c5af544":"isAllocatedLending()","2c5b3b5b":"UniverseChain()","2c5c8f7c":"getDailyProfitSumForAllUsers()","2c5c9dc5":"BeldenCoin(address)","2c5cb666":"setCollectFeeWindowReportingFees(uint256)","2c5d0546":"KuaiToken(address,uint256)","2c5d690d":"getBlocksUntilReset(address)","2c5e52d1":"CandyDropIsOpen()","2c5f5234":"collateralisationRatio()","2c5fac89":"isIcoSucceeded()","2c6009a6":"viewPeerToPeerMarketplaceTransactionFee()","2c60a055":"MapTest()","2c6105f9":"setElectedMediator()","2c6127c7":"availableBets()","2c629299":"allOperations()","2c62fa10":"assetsOf(address)","2c62ff2d":"deleteBool(bytes32)","2c638806":"totalPaymentsHeld()","2c63b326":"memoryArray(uint256)","2c642950":"createBallot(string,bytes32[],uint256)","2c642f51":"sendDividends(address,uint256)","2c64b05f":"LockEDUTeam()","2c664701":"profit_per_token()","2c66a604":"Blizzard()","2c678c64":"migrated()","2c67a8e5":"getItemsByOwner(address)","2c684eb6":"afterVoteNoCashBackTime()","2c684f30":"postListed(address,string,string,uint256,string,string,string)","2c68fcd4":"determineBonus(uint256,uint256,address)","2c69e64e":"refundBet(address)","2c69ed89":"BerryLake()","2c6a0140":"cutoffBlock()","2c6b2c92":"checkProfitLossSinceInvestorChange()","2c6b77e1":"admin_isPayable(bool)","2c6c1108":"autoTearDownAndDestruct()","2c6e38d0":"modifyNextPremiumSale(uint8,uint256)","2c6e4aea":"withdrawFundBeneficiary()","2c6e7598":"toAsciiString(address)","2c6e879f":"settingsSwitchState()","2c6ed612":"stringToBytes5(string)","2c6f11b8":"listApproval()","2c6f39fd":"setLicenseSalesContractAddress(address)","2c6fa230":"getServiceInformation(address,uint32)","2c6fa84c":"Pausable()","2c7077c0":"enableFeatures(uint256,bool)","2c70b7ca":"emitEntityResolution(address,address)","2c70d64e":"unVote()","2c710cc8":"closeInvest(uint256)","2c71d524":"IcoBonus(uint256)","2c71e60a":"grants(address,uint256)","2c71ecb6":"_startBlock()","2c72fdfc":"getProposals(uint256)","2c735ef8":"tradeStartTime()","2c757eed":"startPhase3(uint256)","2c7622b0":"txorigin()","2c767201":"admin_account()","2c76d586":"zint_bytes32ToString(bytes32)","2c78ba6f":"ArbTokFromHGame(uint256)","2c78bfdc":"burnCrown(uint256)","2c791826":"moiTestToken()","2c792276":"endRound(uint8)","2c79aea3":"minedTotalSupply()","2c7a64c7":"isOperationActive(bytes32)","2c7a8559":"setMaxGift(uint256)","2c7b0085":"PocketChain()","2c7ba564":"setTransferProxy(uint32,address)","2c7c4549":"PurchasableToken(uint256)","2c7cc1f0":"emergencyEthDrain(uint256)","2c7cce9e":"auctionMinPriceIncrease()","2c7e06a4":"rateEarlyStage1()","2c7ec2c2":"_fulfillPayment(address,address,uint256,uint256,address)","2c7ee894":"B2Lab_TokenPlus(address)","2c7ee946":"setting(uint256,uint256)","2c8082a6":"PiBetaSupply()","2c828e46":"TransferToken(address,uint256,uint256)","2c837334":"getPlot(uint256,uint256)","2c83d77e":"goforit()","2c84bfa6":"generate(address,bytes)","2c84d560":"OwnerWithdraw()","2c84e31f":"addAccounts(address,address,address[])","2c85448d":"isInt256ValidIn64(int256)","2c854d13":"AUTH_REMOVEOWNER()","2c8595bc":"updatePartnerMap(address,uint256,uint256,uint256)","2c85f8e0":"oraclize_query(string,string,string,uint256)","2c86033e":"checkAddressTeamOne(address)","2c8668d4":"withdrawNoLimit(address,uint256,uint256)","2c868287":"withdrawToTeamStep3(uint256)","2c86d091":"buyTokens(address,bytes32)","2c86d98e":"leverage()","2c86e3b4":"setContributor(string)","2c873761":"getMyDragons()","2c87aecc":"orders_sell_list(uint256)","2c87ba12":"getTitulaire_Compte_2()","2c882333":"vota_un_candidato(uint256)","2c887399":"confirm(bytes32,bytes32,bytes32,uint8,bytes32,bytes32)","2c88837e":"VotingRightsWithdrawn(address,uint256)","2c88fad9":"addWhitelistedAddr(address)","2c890550":"toPower2(uint256)","2c899ab6":"CecCoin()","2c89a84c":"ChronosAccessControl()","2c8ab429":"registerMeDao(address)","2c8ace6c":"TokenERC20(uint32,string,uint8,string,address)","2c8af2d8":"s_rand(address,uint256)","2c8b2ad7":"calculatePaymentGoal(uint256,uint256,uint256)","2c8b8b94":"addAccreditedInvestor(address,uint64,uint64,bool,bool,uint256,uint256)","2c8bcd1a":"createBid(uint256,address,address,bytes32,uint256,uint256)","2c8be60e":"ONO()","2c8c047a":"ownerOperationsAt(address,uint256)","2c8c28a7":"loadNewTickets(bytes32[])","2c8c892b":"allocateSalesTokens(address,uint256)","2c8ca0ea":"isFinish()","2c8cbe40":"setFreeze()","2c8df693":"ServiceProviderEnabled(address,bytes)","2c8e3ebb":"secondRefundRoundRateDenominator()","2c8ed4c4":"_toToken(uint256,uint256,uint256)","2c8ee2ec":"checkWin(uint256,address)","2c8f1b71":"socialIdentityOfClaimerAddress(uint256,address)","2c906ba2":"finishLottery()","2c90ccba":"getNextAuditByPrice(uint256,uint256)","2c91324c":"usersAddress(uint256)","2c915aa3":"assetAddresses()","2c92a2bc":"minWithdrawalThreshold()","2c92c071":"_addPayTable(uint16,uint16,uint16,uint16,uint16,uint16,uint16,uint16,uint16)","2c92e5b7":"BlockspacesToken()","2c92fb99":"getFilter(uint256)","2c948034":"longTermbudgetAllocAddress()","2c94a235":"profitTransferTimeSpan()","2c95ad52":"addItem(bytes32)","2c960569":"updatePriceOraclize()","2c9619ce":"FCOIN1036Token(uint256,string,string,uint256)","2c96bee2":"MultiSigTokenWallet(address[],uint256)","2c9868df":"approveAndCall(address,uint32,bytes)","2c98bf4a":"WelcomeMsg(string)","2c995e1b":"AllowTransferGlobal()","2c9a0a95":"getPricingStartsAt()","2c9a86d2":"payCarnita(uint256,uint256)","2c9afb18":"addrFabricContract()","2c9b1625":"FUTMOTO()","2c9c0fb5":"modifyTransferableHash(address,bool)","2c9cdfd9":"Provider(string,string)","2c9d6989":"withdrawDklBalance()","2c9ea1b7":"nextSkinId()","2c9f092f":"refundToOwner(address)","2c9f4f62":"isPurchased(uint256)","2c9f6792":"emaPeriods()","2c9f9fed":"tokenInit()","2c9fcd8c":"Donator()","2ca0228a":"initialTokenPrice()","2ca0c835":"referrerBonusCalculate(uint256)","2ca0d7ca":"batchTransfer1(address[],uint256)","2ca126f8":"endtime()","2ca15122":"sign()","2ca16a37":"publish(bytes32,string,uint256)","2ca1aa16":"currentSaleLimitPerAddress()","2ca1b7da":"CROWDSALE_ETH_WALLET()","2ca23c4f":"KapelaToken()","2ca2537e":"changeNotSoldTokens(address)","2ca26866":"Tccchain(uint256,string,string)","2ca33e70":"YoutubersCoin()","2ca36da0":"left39(uint256)","2ca38363":"priceEth()","2ca59abf":"changeCollateralTaker(address)","2ca5a623":"change_flag(uint256)","2ca5e3f5":"replyAlice(uint256)","2ca5e626":"getOrder(uint32[8])","2ca60d85":"versionIdent()","2ca6d2c0":"getAccountSize(address)","2ca76003":"checkWinner(uint32)","2ca781f1":"firstPay()","2ca8c6d3":"numberOfBets()","2ca8cbd0":"minePhx()","2ca9cbe8":"distributeToken(address,uint256)","2caafb54":"totalFreezeTokens()","2cab00de":"buildPrice()","2cab6c6a":"editTile(uint16,uint16,uint8,uint16,address)","2cacb97c":"GetProfitEarnedByPartner(address)","2cacd13a":"takeOrder(uint256,uint256,uint256)","2cad9404":"salvageFinished()","2cae0c76":"crowdSaleIsOver()","2cae249a":"rvDepositAddress()","2cae66d8":"encodeRequest(uint128,address,address,address,uint256,uint64,address,bytes)","2cae8ae4":"getPayload()","2cae9add":"rawTokenSupply()","2cae9ca1":"spendWithGas(address,uint256,uint256)","2caeb8fc":"checkMyUndistributedBalance(uint256)","2caef765":"setBoardController(address)","2caf1f15":"set_tickerQuery(string)","2cb0d48a":"setEditable(bool)","2cb0de18":"setFeeAccountToken(address)","2cb15864":"initialBlock()","2cb2f52e":"updateTokenMetadata(uint256,string)","2cb3ce8c":"TIER3_RATE()","2cb44156":"minterGivesCWC(address,uint256)","2cb4f63e":"price_target()","2cb51970":"_batch4_icosaleStartTimestamp()","2cb58378":"getStateRoot(bytes32)","2cb676be":"NVBSupply()","2cb6a435":"oneTimePrice()","2cb71af3":"startBuyback(uint256,uint256)","2cb8460c":"PlutusDex()","2cb856f3":"dgxContract()","2cb86824":"preIcoStartAt()","2cb8f2e9":"executeBet(uint256,bool)","2cba85c6":"popcontract()","2cbb827f":"withdrawToSelf(uint8)","2cbbbd2d":"SHIPToken(address,address)","2cbbd738":"getPoll(bytes32)","2cbcaba9":"SimpleICO()","2cbdb5fb":"addChunk3ToWhiteList()","2cbe679b":"Travelerscash()","2cbef0f3":"getAffiliateCommission()","2cbf1b12":"CirclePay()","2cbf1f0d":"left62(uint256)","2cbf4e27":"removeParticipant(address,address)","2cbf9cf6":"MintableToken()","2cbfd034":"intCallWithArray(uint8[4])","2cc0a28c":"_matchedTags(bytes32[],bytes32[])","2cc0b254":"init(address,bytes32)","2cc138be":"rewardStartTime()","2cc1b92a":"addr_communityBuildingToken()","2cc205d9":"totalStakedFor(address,address)","2cc27341":"setMinMargin(uint256)","2cc361a6":"removeTank(address)","2cc53743":"GxEvents(address)","2cc5cfd6":"withdrawDevelopersFund(address)","2cc5d662":"arawWallet()","2cc63332":"returnCoupon(address[2],uint256[8],uint8,bytes32[2])","2cc689f9":"markRewardsSet()","2cc695de":"addCertification(address)","2cc6cf4a":"BABI()","2cc6d768":"RecordingRefundVault(address)","2cc75331":"getTeamsOnLeaderboard()","2cc763e7":"milliPercent()","2cc7c475":"TokenSaleCreation(uint256,address)","2cc7fc36":"ICOPurchased(uint256)","2cc82225":"setPriceCreatingChannel(uint256)","2cc82655":"setPhase(uint256)","2cc88401":"wirePurchase(address,uint256)","2cc8b455":"recoverAddressFromWithdrawMessage(bytes32,address,uint256,bytes)","2cc92b2b":"isICOOpened()","2cc9636c":"buyerCancel(bytes16,address,address,uint256,uint16)","2cc9c151":"verifyOwnership(address)","2cca179d":"addPoll(uint256,uint256,bytes,uint8)","2cca23f1":"Timeless()","2cca5ce3":"setEngine(address,bool)","2cca664b":"totalPlayerWinnings()","2cca75d3":"StupidCoin()","2ccaa3e9":"getPropertyOwner(uint16)","2ccb1b30":"transferTo(address,uint256)","2ccbd053":"set(uint256,string,string,string,string,string)","2ccc452d":"pushByte(bytes32)","2ccc9057":"RATE_CROWDSALE_S3()","2ccce58a":"cancelGame(string)","2ccd0991":"extraData1FromHash(string,string,string,string,string)","2ccd9623":"referralManager()","2ccdbc25":"prometheusVouchersMinted()","2ccde4bd":"withdrawAllUncommittedTokens()","2cce0c60":"eth_to_usd()","2cce4abe":"_finishNoCallback()","2cce753a":"batchAddAddresses(address[])","2cce81aa":"getBlockHash(int256)","2ccf16f9":"CashPoints()","2ccf27bb":"PatrickHuynhToken()","2ccf8d40":"HVAL()","2ccfc58c":"FeesReceived(address,uint256)","2cd046eb":"countMembers()","2cd05122":"ZENOSEarlyPurchase()","2cd05248":"lastBlock_f3Hash_uint256()","2cd11849":"depositAdvisor(address,uint256)","2cd1bab2":"partnerID()","2cd2338f":"thawAddress(address)","2cd33a54":"eth_amount()","2cd3fd70":"BurnTokens(uint256)","2cd44064":"UNHCToken(uint256,string,string)","2cd53cfe":"addEducation(string)","2cd6305f":"unsellpause()","2cd64f65":"TokenMintGeneral()","2cd78450":"activateExportFeeChargeRecord(address)","2cd8c9ae":"fillPhase(uint8,uint256,uint256)","2cd9e233":"Quarters(address,uint256)","2cda1bf7":"titles(uint256)","2cdad41c":"isInspector(address)","2cdb0213":"dailyHourLimit()","2cdb8eec":"updateTokenValue(address,uint256)","2cdba70e":"_getMaxPooling()","2cdc1c74":"lister()","2cdcb1fc":"wrongManagerOrUnsetInClaimer()","2cddc488":"transferTaxes(address,bool)","2cde15d1":"weiTotalRaised()","2cdedd5c":"StateChannel(address,address,address,address,uint256,bytes)","2cdf2bfd":"sellPatent(uint16,uint256)","2cdf37d4":"_admin(uint256,uint256)","2cdf55af":"RC()","2ce04b20":"tokenLockoutPeriod()","2ce0a6ee":"setBalanceLimit(uint256)","2ce0b4f6":"ICO_FINISH()","2ce0ca6b":"setChainFees(uint256[10])","2ce14d90":"_willFallback()","2ce1ec67":"HelloCoin(uint256,string,uint8,string)","2ce20579":"mutagen2Face(uint256,uint256)","2ce21999":"fees_(uint256)","2ce2907b":"CryptoCourt(uint256,string,string)","2ce2d7c0":"completeRegionAuction(uint16)","2ce37b10":"getListCount()","2ce3d440":"updateAccount(address)","2ce47de4":"payWinners(uint32,uint32,uint256,bool,uint32,uint32)","2ce52d9b":"shareCycleSessionSize()","2ce5c284":"processed()","2ce5fb75":"getHorseShoe(uint256)","2ce68269":"registerByList(address[],bool)","2ce78fc0":"getDemande(uint256)","2ce7900b":"getTokenTimelockCount(address)","2ce82189":"balanceTransferred(address,uint256,bytes)","2ce90c11":"killTokens()","2ce91d08":"TokensWorld()","2ce92dfd":"updateMinGasForDrawing(uint32)","2ce946a5":"teame()","2cea0654":"setStateClosedIfClosed()","2cea53bd":"returnChametz()","2cea70e4":"isAds()","2cea905a":"IAMEPrivateSale()","2cea9442":"totalUsdRaised()","2cead42c":"_createIntention(address)","2cead658":"Companion()","2ceae552":"AVAILABLE_BONUS1_SUPPLY()","2ceb1bb3":"addPreEntranceMembers(address[],uint256,uint256)","2ced7cef":"log(string,string,string)","2cedc5ec":"enableTokenAiTransfers()","2ceee12e":"seeBidders()","2cef4dac":"updateMasterCopy()","2cefc429":"sellCard(uint8,uint256)","2cefeb07":"setname(string)","2cf033a0":"setNewTokenAddress(address)","2cf0be44":"transferToService(address,uint32,uint256,uint256,uint256)","2cf0d6ca":"PLAT()","2cf1a5fb":"airdropStatus()","2cf2f1d1":"rndReduceThreshold_()","2cf32bc9":"PayoutEarnings(address,uint256,uint8)","2cf3f1f3":"setTokenPerEther(uint256)","2cf42a6c":"cancelHybridization(uint256)","2cf45905":"addHpbNodeBatch(address[],bytes32[],bytes32[],bytes32[])","2cf4db51":"amountVote(bool,uint8)","2cf4e56f":"withdrawBounty()","2cf5346a":"totalSupplyAt(uint256,int256)","2cf5fe89":"maxChildCount()","2cf65a06":"logite(string)","2cf6b532":"STARL()","2cf6e740":"adminSum()","2cf75c11":"_generateLog(uint32,uint8,uint32,uint8,uint8,uint8)","2cf86006":"calculateDividends(uint256)","2cf8a1d6":"CCRToken()","2cf91024":"getFlightInfo(uint16,uint16)","2cf9185c":"getMyPlayedCount(address)","2cf975af":"isPreferredTokensAccount(address)","2cf99422":"publish(address)","2cfa606d":"tvcEthFund()","2cfa74da":"buyKeys(uint256,string)","2cfac6ec":"teamSupply()","2cfbb031":"claimReward(bytes)","2cfbd0b9":"addNewBlock(bytes32,bytes32,bytes32[])","2cfc1f4c":"updateGift(uint256,uint256,string,string)","2cfc42f5":"blacklistParty(address,address,bool)","2cfd10a0":"CrowdsaleMain()","2cfd3005":"mint(address,bytes32)","2cfd35bb":"employeeMigratesToNewESOP(address)","2cfdd7df":"newReward()","2cfed9f0":"setSpeaker(address,address)","2d0041c5":"setAmbassador(address,bool)","2d00b442":"_createBid(bytes32,address,uint256)","2d0104a5":"updateFirstDuel1(uint256)","2d014833":"e93Contract()","2d01564c":"littContentExists(bytes32)","2d019a71":"get_asset_info(bytes32)","2d021624":"BTBToken()","2d02a5b2":"setGoldPrice(uint256)","2d0335ab":"getNonce(address)","2d03c4eb":"nxcPerBcy()","2d040add":"updateRegistrationState(bool,uint256)","2d042a7f":"PonziRevolutionBeam()","2d045780":"isAllowedToBuyByAddressWithoutVerification(address)","2d04d07d":"goTokenCollection()","2d04f820":"DEV_WALLET()","2d06177a":"addManager(address)","2d062140":"SiringClockAuction()","2d067d4c":"isBurn()","2d06a1fa":"ALFA()","2d06fd13":"getTotalDeveloperCut()","2d077ad0":"Latch()","2d07bf2f":"CryptoHarborExchange()","2d087944":"hasBuyNowOffer(uint256)","2d08d408":"Send(address[],uint256[])","2d09839f":"tokens_push(address)","2d0a8809":"testAddVoters()","2d0b1451":"DevotteToken()","2d0b7d53":"registerVariation(uint256,address)","2d0cc13c":"MoonMinerToken(string,string,uint8,uint256)","2d0d4827":"startIco1(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","2d0d9c2a":"getCompletedGamesStatistics()","2d0d9e0f":"getUserProductsKeys(bytes32)","2d0daca8":"assertEq25(bytes25,bytes25,bytes32)","2d0e6636":"tokenToEtherAllowed()","2d0f5573":"right35(uint256)","2d0ff779":"claimEOSclassic()","2d103ed4":"addAllowedHICAddress(address)","2d10d4d1":"getCityActiveBuildings(uint256,uint256)","2d116186":"deityBalance()","2d118bbf":"getUserPaybackPool()","2d11fa16":"throwsWhenTransferingPresaleTokensBeforeCliff(address)","2d123aa4":"useDefaultRegistry()","2d126239":"calcAndGet()","2d126d2b":"indCommunityDeposit()","2d132467":"buyPreIcoTokens()","2d133eee":"KYC_THRESHOLD()","2d136dd6":"TrillionToken()","2d139417":"migrateToNewNewControllerContract()","2d13c164":"_computePayMoney(uint256,address)","2d144e6b":"totalPlayerSupply()","2d1608db":"YouLongToken()","2d162c70":"distrust(address,uint256,bytes)","2d171243":"getUnitsProduction(address,uint256,uint256)","2d17d956":"buildRequest(string)","2d19413c":"setJackpotToken(address,uint256,uint256,address,uint256,uint256,uint256)","2d1a330b":"marketmorties()","2d1a6477":"lengthEqual(address[],uint256,string)","2d1a67e1":"Ledger(address,uint256,uint256)","2d1b42f5":"encryptCounter(uint256)","2d1babed":"setRates(uint256)","2d1c56a9":"totalTxVolume()","2d1ced82":"priceBox1()","2d1d744a":"isPass()","2d1d9627":"changeAddress(bytes32,address)","2d1d9feb":"removeRRA(address)","2d1e0516":"setBal(bytes32,address,uint256)","2d1f0021":"NextItemID()","2d1f0097":"getData_18()","2d1fb389":"authorize(address,bool)","2d1fdef6":"extendDeadline(uint256,uint256)","2d202d24":"setNextOwner(address)","2d20fbf3":"ownedBonus(address)","2d215518":"pause(uint256,uint256)","2d217d43":"AntasCoin()","2d21ca88":"ICOTokenHardCap()","2d226a10":"allocateServusTokens()","2d22a4e3":"isPrivateInvestmentPhase()","2d22b464":"createEgg(string,bytes32)","2d241248":"getFeeBurnerAddress()","2d24447a":"LBCoinJ()","2d247cc6":"coinPriceInWei()","2d278518":"EtherReceived(uint256,address,uint256)","2d278e9e":"picosPerEther()","2d27c8cd":"ALLOC_SALE_GENERAL()","2d2800f1":"react()","2d287e43":"insert(bytes32)","2d2899b6":"getIntArray(bytes32)","2d28bb02":"setTokenStart(uint256)","2d28d4cf":"transferIfTokenAvailable(uint256,uint256,address)","2d28e89d":"MINIMUM_DURATION()","2d290d8b":"MAX_CROWD_SALE_TOKENS()","2d2925c7":"transferInitialTokens()","2d296bf1":"buyToken(uint256)","2d29842c":"upgradePhoenixStats(uint256)","2d29953f":"withdrawByFoundation(address,uint256)","2d29b29b":"migrateSome(address[])","2d29c72d":"stopUpgrading()","2d2bb154":"kycWallet()","2d2bcd37":"setRelayContractAddress(address)","2d2c44f2":"Vault()","2d2c5565":"TREASURY()","2d2c9ed8":"softcapReachedCallabck()","2d2d23f7":"Cordbank()","2d2e3bb2":"deleteFincontract(bytes32)","2d2f7e4d":"withdrawBidForStar(uint256)","2d2f8f9b":"getAddListSize()","2d2fa531":"hank()","2d2fe9d4":"stakeWaived_Eth()","2d30ae45":"distributeCrowdsaleTokens(address,uint256)","2d31908f":"PRICE_7()","2d31d9c9":"sales(bytes16)","2d31f270":"UNTToken()","2d328551":"numberOfHalvings()","2d345670":"revokeAdmin(address)","2d345799":"balanceOfPretty(address)","2d349a1f":"icoLtc()","2d34ba79":"setup(address,address)","2d354cf8":"_isContract(address,address)","2d358710":"HARJToken(address,string,uint8,string)","2d35a8a2":"candidatesCount()","2d364687":"toLucky()","2d36ad42":"cleanUp(address)","2d370378":"switchSaleAuctionERC20For(address,address,uint256)","2d3727bf":"CloseDiv()","2d37329a":"lastBlock_v4Hash_uint256()","2d37e6dc":"getCrowdsaleInfo()","2d381f84":"ATTR_GOLDENGOOSE()","2d38bf7a":"rewardEra()","2d3a926a":"computeCut(uint256)","2d3b3141":"ERC20Standard(uint256,string,string,bool)","2d3b4643":"coresale()","2d3b634c":"Crowdsale(uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","2d3b9e59":"isFinished(uint8)","2d3c5d28":"DonatedEthPayout(address,uint256)","2d3cb6bd":"mulX(uint256,uint256)","2d3d165d":"parameterizerFactory()","2d3d403a":"challengeContract(address,address,address)","2d3e2065":"minBetWei()","2d3e474a":"marketing()","2d3e579a":"hasRole(address,bytes32,address)","2d3e9efe":"mint(int256,bytes32,bytes,uint256[],bytes,bytes)","2d3ec656":"setMinimumIcoRate(uint256)","2d3ed075":"Certificate(bytes32,string)","2d3fb0d5":"getCrowdsaleState()","2d3fb721":"secondRoundICODiscount()","2d3fcc23":"beingVIP()","2d405b43":"Win(address,uint8,uint256,bytes32,bytes32,uint256)","2d40957f":"TheWinner()","2d4147e3":"bountyToken()","2d416b4d":"bindCertificate2Wallet(address,bytes32)","2d41777f":"SnapshotUpdated(address,uint256,uint256,string)","2d4194c7":"getAuditRequestBlockNumber(uint256)","2d41bc9b":"store(uint8[],uint256,uint256,uint256,uint256)","2d41c7a4":"Nikone()","2d434139":"addCustomerNReqAcc(address,address,address)","2d43573d":"landmarks(uint256)","2d4364ae":"placeTokens(address,uint256)","2d448c49":"setO2(address)","2d449b5e":"Etokenchain()","2d44c049":"modifyCreator(address,bool)","2d459dd6":"transfer(address,uint48,bytes)","2d45c78d":"requireAuthorisation()","2d46253f":"CommunityWithDraw()","2d462dbb":"rollLo()","2d467358":"LAPTOPTOKEN()","2d46a9ce":"getVestingCreatedAt(address,uint256)","2d46b54e":"hashMsg(bytes32,address,bytes32,address,uint256,bytes32,string,string)","2d46f5df":"registerProduct(address)","2d475386":"ownerWithdrawUnclaimedCredits()","2d47adcb":"BancorNetworkToken()","2d47c29e":"otherchainstotalsupply()","2d480a80":"thankYou()","2d483bec":"setNewRate(uint256)","2d48bcec":"pool_drain(address)","2d493910":"_computeNextPrice()","2d49f5fc":"verifyERC20(address)","2d49ffcd":"getLocked()","2d4a170a":"calculateBid(uint256)","2d4c4aea":"GOTGCOIN()","2d4d671f":"startRevealingPhase()","2d4e4472":"LandClaimExecuted(address,uint256,bytes)","2d4ede93":"deleteNode(address)","2d4f40c6":"setBotAddress(address)","2d4fd9dd":"rejectDispute(uint256)","2d501611":"PERCENT_BONUS()","2d50e2d5":"getSupercedesRegistryInterfaceID()","2d5132cd":"getOuvidoriaEnteNome(address)","2d5134f7":"setApplication(address,address)","2d52164b":"stopsell()","2d5216a5":"PHASE_CHALLENGE()","2d52d1a2":"rewardDistributionEnded()","2d54ab45":"initTokenSale(address,address,address,uint256,uint256,uint256)","2d54f04d":"changeVotingBlocks(uint256,uint256,uint256,uint256)","2d5505b6":"_setAreas(address,uint256)","2d550c0b":"optionality()","2d56acce":"setMinAcceptedInPublicSale(uint256,uint256)","2d56af6c":"burnCoin()","2d56d572":"releaseMany(address[],uint256[])","2d571013":"getFeedBackFeeAward(string)","2d571cc4":"createToken(uint256)","2d578304":"update(address,uint16,bool)","2d57b6c8":"getInvestorDeposit(address)","2d57ea40":"FundariaTokenBuy(address)","2d580ef6":"add(address,bytes32)","2d581e71":"add_user(address)","2d5858a3":"publicSoftCapReached()","2d58c9a2":"gy()","2d58fab1":"pauseCWC()","2d592a34":"sellKissBTC(uint256)","2d5949a0":"setNumMarkets(uint256)","2d596330":"bmcPlatform()","2d59680d":"pool_name()","2d598d7b":"isAccredited(address)","2d599750":"updateUrl(bytes32,string)","2d59dc12":"displayMessage()","2d59ea6c":"oscarGuindzbergAddress()","2d5a5d34":"blacklistAccount(address,bool)","2d5a858c":"checkCompanyNameAvailability(bytes32)","2d5b2e15":"CLIForGas()","2d5b778b":"refundingDeadline()","2d5b8d99":"paymentsOf()","2d5bbf60":"subscriptions(uint256)","2d5c3ed1":"KWHToken(address,uint256)","2d5cb5d5":"CryptoKitties()","2d5cd1d6":"getPrize(address)","2d5ea8e3":"numplayers()","2d5fd89f":"getClaimData1(uint256)","2d60a72c":"DEPOSITS_KEPT()","2d614ad2":"Webpuddg()","2d620e1e":"deedsOfOwner(address)","2d62ce38":"collectAirdrop(bytes32)","2d62f428":"coinIssuedSale()","2d63e9f4":"Registration(uint256,uint256,uint256,uint256,uint8,uint8,uint8,uint8,string)","2d63f728":"mintWithMetadata(address,uint256,string)","2d646742":"executeGameProposal(uint256,bytes)","2d658888":"RobotarTestToken(address)","2d6653a9":"seed_coins_vault1()","2d668da4":"returnAmountOfTmexAddressCanProduce(address)","2d66acf1":"fortune_open(uint256)","2d67a79e":"verifyAccount(address,string,string)","2d67bb91":"World()","2d6842b5":"admin_MinimalPayValue(uint256,uint256)","2d685f15":"takeSell(address,uint256,uint256,address)","2d68bad7":"withdrawForTo(address,address,uint256)","2d68bc6e":"saleProceedsEther(uint256)","2d68de95":"currentStageTokensCap()","2d690f28":"LogSetTokenPrice(uint256)","2d6a3482":"TradeListing(bytes32,address,address)","2d6acb3a":"RESERVE_POOL_ADDR()","2d6afbd0":"unlockWithSpend(uint256,address)","2d6b113a":"in_sharing_phase()","2d6c17a3":"rewind(uint256)","2d6c25fa":"recommendedPrice(uint16)","2d6c5a84":"reverter(uint256)","2d6d1646":"untokenize()","2d6d4caa":"addtoContributos(address,address,uint256,uint256)","2d6ddfda":"closeModifyCountdown()","2d6df368":"borrarRegistro(bytes32,bytes32)","2d6e2bb0":"regularHold()","2d6ef310":"closeGame(uint256)","2d6f70f7":"transferViaTokenTransferProxy(address,address,address,uint256)","2d6f8049":"setBountyTokensReserve(uint256)","2d6fc906":"setBonuses(uint256,uint256,uint256)","2d706a34":"isName(address)","2d710551":"UlleToken()","2d7243ef":"payTodayReward(address)","2d740722":"close_pre_ico()","2d75c39a":"_removeClearingPriceValidator(address)","2d762b0d":"changeTokenContractAddress(address)","2d76a85a":"PundiXCash()","2d76be2d":"player_getPendingTxByAddress(address,address)","2d76d7b0":"releaseTokensByAddress(address)","2d774da2":"isSetFund()","2d776793":"downvoteComment(bytes32,bytes32,bytes32)","2d7788db":"rejectRequest(uint256)","2d78737b":"CreateUpgradeCards(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","2d78b7fc":"_withdrawInvestorTokens(address)","2d7aa82b":"initialize(uint256,uint256,uint256,uint256,uint256,uint256)","2d7ae086":"MarkHours(bytes32,bytes32,int256,bool)","2d7af0f4":"transferLoan(bytes32,address)","2d7b299d":"setNote(string)","2d7b8c98":"returnInvestmentsTo(address)","2d7bf927":"Migrations2()","2d7c597f":"whois(bytes32)","2d7c93e9":"register_claim(string)","2d7cd4cd":"rand1()","2d7cdeb1":"withdraw(string,uint256,address,bytes)","2d7da889":"ruleA(uint256)","2d7dc81c":"sendAfterIco(uint256)","2d7deae2":"testDeployMultiSigWallet()","2d7e92a5":"CWCCTokenIssue(address)","2d7eba3f":"ganaBalance()","2d7ed15c":"BNB_TOKEN_PRICE_DENOM()","2d804ca2":"amountFilled(address,uint256,address,uint256,uint256,uint256,address)","2d806bfd":"createProduct(bytes32,bytes32,address[],int256,int256,address)","2d806cdd":"setRefund(address)","2d80bc86":"getNumberOfParticipantsOrigins()","2d80f13c":"EthlanceSponsor(address)","2d817a91":"withdraw(uint32[])","2d81844e":"_createPrecious(address,uint256,string)","2d81e877":"Gocc9()","2d826eda":"updatetoken(uint256,string,string,string,string,string,uint256,bool)","2d829146":"buyshares(address)","2d83549c":"escrows(bytes32)","2d839989":"clearingPriceCode()","2d83f5a3":"divAmt()","2d84c3e8":"_getSigner(bytes32,bytes)","2d852552":"CreditDAO()","2d85db6b":"ChangeEndByManager(uint256)","2d873f21":"CrowdDevAllocation(address)","2d87cdd6":"DmlContribution(address,uint256)","2d883a73":"getByIndex(uint256)","2d884a51":"icoOpeningTime()","2d888869":"toAddress(bytes)","2d88af4a":"setPauser(address)","2d88df6f":"lvePay(string,string,uint256)","2d89560a":"TOKEN_INFORMATION_ADDRESS()","2d897146":"changeBonusIncreasePercentage(uint256)","2d8a08b6":"DepositEvent(address,uint256)","2d8a4dca":"committeeKickVotes(address)","2d8aa855":"playerInput(address)","2d8c1c35":"level_up()","2d8d488c":"getProductContractCommissionWei(address)","2d8d96fa":"stockSellCertainOrder(uint256,uint256,uint256,uint256)","2d8df871":"alimtoken()","2d8e3250":"Version(string)","2d8e3278":"grantPermission(address)","2d8ebff1":"joinAndDeposit(uint256,uint256)","2d8ed84a":"getExpiryDate()","2d8f0981":"setPI_edit_14(string)","2d9029ca":"earlyResolve(bytes32,uint256,bytes32,bytes)","2d9068ed":"matchpoolAddress()","2d906a19":"Solario()","2d90ae94":"transferToOwner()","2d910376":"valueFromPercent(uint256,uint256)","2d91657b":"giveConsent(string,string)","2d91ad22":"Group_5()","2d91bf11":"foxcoin(uint256,string,string)","2d923561":"sellItem(uint256,uint256)","2d9240f3":"pauseCrowdSale(bool)","2d92b1c0":"setupPhases(uint256,uint256[],uint256[],uint256[],bool[])","2d92b371":"addVal(address,bytes32,address)","2d9346ab":"setAgentVerificationByAdmin(address,address,bytes32)","2d935d11":"calculateTokenOnlyBuyPrice(uint256)","2d936763":"hasTeamKeepingWithdraw()","2d937fe8":"isBeginnerQuestContract()","2d93a44e":"getEndClaimDate()","2d93d3ac":"getFirstStageWallet()","2d94d41e":"DEVCLASS_FTL_SPEED()","2d9525d6":"YankeesOrioles48()","2d957790":"testRemoteWithdraw(uint256,uint256,uint256,uint256,address,address,uint8,bytes32,bytes32,address)","2d958dfc":"Payout(address,address,uint256,uint256,bool)","2d95fdb5":"_isApprovedForAll(address,address)","2d962d0f":"burnLeftTokens()","2d969204":"KingJamesToken()","2d96a297":"addStore(uint256,uint256)","2d976404":"upgrade_token(address,address,string)","2d978678":"left23(uint256)","2d97fc5d":"rand(uint256,address)","2d980646":"allowanceEliminate(address,address)","2d985cfb":"testControlRestartNotUpdatable()","2d98d251":"ArtaoToken(uint256,string,string)","2d992bde":"applyAffiliate(address,uint256,uint256)","2d9a37d3":"getMaxPayout()","2d9abaed":"Purchase(uint256,address,address)","2d9b1530":"Electrocoin(uint256,uint256)","2d9b4ab7":"blnpereth()","2d9c3052":"createPaper(string,uint256,uint256)","2d9c6001":"prometheusVoucherSoldCount()","2d9d5ab7":"withdrawByAdmin(address,uint256,address,uint256,uint8,bytes32,bytes32)","2d9de472":"setVerified(uint256)","2d9e84b4":"userCampaignID(address,uint256)","2d9e87c5":"setRefundable(bool)","2d9e8ed6":"addEntryInYears(address,uint256,uint256)","2d9ec349":"TOKETH_PRESALE_THREE()","2d9eceb5":"BETHERcoin()","2d9f669d":"sendProportion(address,uint256)","2d9fab98":"suscribeTrial(uint256)","2d9ff1d0":"m_Owner2()","2da03409":"flushForwarderTokens(address,address)","2da09fac":"sellBkgAtExchg(uint256,uint256)","2da0c25c":"priceChanger()","2da0d1ea":"etherSold()","2da11b2e":"biddingClosed()","2da13d5e":"CONTRIBUTIONS_MIN()","2da1670f":"deAuthoriseSale(uint256,uint256)","2da2440c":"registerAuditor(address,address)","2da39239":"updateUserShares()","2da40888":"TaskUpdated(uint256,uint8)","2da40ac7":"emitTokens(address,uint256,uint256)","2da4dddd":"createSystemSaleAuction(uint32,bytes,uint16)","2da5a444":"deleteSire(uint32)","2da5b88e":"remoteSetWinner(uint256,uint256,uint256)","2da5deb4":"addBuyTokensRequest(string,string)","2da64861":"bulkReserveTokensForAddresses(address[],uint256[],bool[])","2da6a0d8":"getBomb(uint8)","2da6b8f8":"_getMinersAt(uint32,uint32)","2da7293e":"isSuperseded(address)","2da758b0":"ResearchAndDevelopment()","2da80893":"phase_3_rate()","2da8b2be":"TokenSubtracted(address,uint256,uint256)","2da8d3e6":"woe()","2da8f764":"submitVideo(string,string)","2da92e05":"setEmissionCap(uint256)","2da9b51e":"setBuilding(uint8[176],uint8,uint8,uint8)","2da9d048":"startQueue(address)","2dab0374":"sendFutureFundingBalance(address[],uint256[])","2dab3e7a":"setTransferPlan(address,uint256,bool)","2dab7ee2":"convertToBytes(uint8[])","2dabbeed":"reclaim(uint256)","2dac17cd":"getBattleKuns(uint256)","2dacdaf7":"_createGirl(string,address,uint256)","2dad2f97":"getLeastExpensiveShare(uint256,uint256)","2dad5872":"newAttack()","2dad6b6a":"_distributeToken(address)","2daddb32":"VVToken()","2dadf781":"KudosOrganisations(address)","2dae35c4":"RGXBonus(string,string,uint256,uint8)","2dae9878":"BankOwner_EnableConnectBankAccountToNewOwnerAddress()","2daeb49a":"fundPuppets()","2daedd52":"stake(bytes32,uint256,uint256)","2daf0e1c":"presaleLevel()","2db0d129":"VIDALCOIN()","2db237bb":"MARGIN_SPLIT_PERCENTAGE_BASE()","2db25e05":"getTrade(uint256)","2db26de1":"checkBalances(address[])","2db2caef":"rmExchangeAccount(address)","2db3dc12":"FrozenAccount_event(address,uint256)","2db4f279":"createRoom(string,uint256)","2db579f2":"ETHPToken()","2db59e2b":"MyOwned()","2db6ad32":"testEmpty()","2db6e0fe":"fixPlayerFlag(uint256,string)","2db6fa36":"batchAddToWhitelist(address[])","2db78d88":"adminSealBallot(uint32)","2db8069f":"makeMemberOfCommunity(address,uint256)","2db89533":"Auth(uint8,address)","2db9395a":"availableTo(address)","2db93fc7":"buyBag(uint256)","2db95aa9":"getTomatoCount()","2dba1a44":"stockCancelSellOrder(uint256,uint256,uint256)","2dba3614":"app_address()","2dba5cfa":"transferCoins(address,uint256)","2dba9e63":"EMACToken(uint256)","2dbacf5f":"premiumOpen()","2dbb9050":"setSecurityTokensPercent(uint256)","2dbc62cc":"BlindCroupierTokenDistribution(address[16],uint256[16])","2dbcc104":"getAddressFromList(uint256)","2dbce390":"setDepositary_function_control(uint256)","2dbd606e":"set_sale_address(address,bytes32)","2dbe713d":"EOSPlusToken()","2dbede89":"next(bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,bytes2)","2dbf7b98":"certificate()","2dbf8bf0":"getRolled()","2dbffa6a":"executeBuyRequest(uint256)","2dc03259":"registerUser(bytes32)","2dc03b22":"createNTVU()","2dc0562d":"taxWallet()","2dc09c39":"protectedReclaim(address,uint256)","2dc26661":"unlockOutcome(string,uint256)","2dc2dbf2":"makeSimpleDeal(address,address,uint256,bytes32)","2dc47153":"datafeed()","2dc62c4d":"MintProofOfStake()","2dc70b2a":"getCorrectedTotalBPOfTokens(uint256[])","2dc7a2e5":"testSetupMultisig()","2dc88138":"submitCoin(address,string)","2dc8b9de":"f1(address)","2dc8be64":"buyoutWallet()","2dc8d88d":"privatesale_beneficiary()","2dc95548":"adjustTokenExchangeRate(uint256)","2dc9ad7f":"multisend(address[],uint256)","2dc9b8f7":"createGuess(uint256,uint256,uint256,uint256,uint256)","2dc9d3e5":"placeSellTokenOrder(uint32,uint256)","2dca374f":"FBToken()","2dcac811":"TTNCoin(uint256)","2dcb4691":"EventBuyTank(address,uint256,uint256,uint256)","2dcb5c8d":"xaurumProxyWorking()","2dcbac97":"getGen(uint256)","2dcbfdfa":"endEarlyBird()","2dcca1f9":"TokenRetriever()","2dccba89":"MAX_DEPARTURE_LIM()","2dcd4e41":"getGain(uint256)","2dcdcd0c":"minChild(uint256)","2dce6a1f":"KHT(uint256,string,string)","2dcebd16":"setWorldTreasuryAddress(address)","2dd02e92":"weGotAWinner(address,uint256)","2dd0e79e":"getMarket_CommunitUsedTokens()","2dd117e0":"RESERVED_TOKENS_BOUNTIES_ADVISORS()","2dd1a932":"WE3TOKEN()","2dd1cc27":"MichCoin(uint256,uint256,uint256,uint256,uint256,uint256,address,address)","2dd28736":"view50()","2dd2995a":"ETHERCOINSupply()","2dd2f86b":"maxTokenSale()","2dd306f7":"getTearBalance()","2dd31807":"unlistOpenProposals(bytes32)","2dd34f0f":"Whitelistable(address)","2dd395ae":"SUN()","2dd3ed9a":"addWorkRecord(uint256,bytes16)","2dd40301":"amountJurors(uint256)","2dd407f9":"Vag()","2dd4f8d4":"totalSupplyYear()","2dd522c6":"ATN()","2dd5b58e":"setNewGameLogic(address)","2dd608ce":"setPreICOLimit(uint256)","2dd694ff":"EntryExistAlready(bytes32,uint256)","2dd6ba7e":"release_remain()","2dd7030b":"removeAuction(uint256)","2dd78759":"affAddr_()","2dd7ab99":"BlackSnail(uint256,string,uint8,string)","2dd81ed3":"CROWDSALE_REWARD_TOKENS_NUMS()","2dd854d4":"addLoanToPortfolio(uint256,uint256)","2dd8a25e":"MakeTransaction(address,uint256,uint256)","2dd96c84":"presaleGranteesMap(address)","2dda04fa":"enterContest(uint32,uint32[])","2dda30a7":"transferAndFreeze(address,uint256,uint256,uint256)","2ddae32d":"UTCoin()","2ddbc04a":"play2(address,uint256)","2ddbc97e":"addAuthor(address)","2ddbd13a":"total()","2ddc36ba":"BRC()","2ddcac03":"_checkLimit(uint256)","2ddcb21f":"limitSupply()","2ddd196f":"bookGuest(string)","2ddd6fa5":"incomingRandomNumberError(address)","2dddd8e0":"CROWDSALE_HARDCAP()","2dddf3e1":"request_withdrawal(uint256,uint256)","2dde1911":"balancesImporter2()","2dde7241":"priceWithDiscount(uint256,uint256)","2dde7dbc":"MAX_DTH()","2dde9aca":"deployment()","2dde9f81":"getLockWFee()","2ddea5fc":"enableEscapeHatch()","2ddeac16":"getForeignTokenBalance(address,address)","2de02bfa":"allocate(address,address,uint256)","2de16fdb":"fetchDayTokens()","2de1e234":"requestUSDPrice(string)","2de22cdb":"currentMintedTokens()","2de39dbe":"DifficultyOracle(uint256)","2de3ad02":"getUserWalletByUsername(string)","2de3cddc":"setCostToCreate(uint256)","2de40ce3":"registered()","2de4ca59":"Check()","2de4fbd8":"DaoRulesProposalAdded(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool,address)","2de541e0":"updateAvatarInfo(address,uint256,string,uint256)","2de5aaf7":"getAgent(uint256)","2de61d1f":"changeIcoTimeRange(uint256,uint256)","2de6fac6":"delKYC(address)","2de86c5b":"transferPlayerBudget(address)","2de896f6":"MaxTokensPerAccountUpdated(uint256)","2de90801":"hashtagToken()","2de954af":"fixedLog2(uint256,uint8)","2de9a13a":"ToGoConcert()","2dea5f6d":"markCombatStarted(uint256)","2dea82b4":"checkActualPrice()","2deb65c7":"GetPoolInformation()","2deb7571":"queryByAddr(address)","2deb79b6":"getStockShares(uint256)","2ded516e":"giftIsTo()","2dee466d":"getAllActiveAuctions()","2def6620":"unstake()","2df056bd":"ServiceProvider(string,string,string)","2df05a3e":"payoutIndex()","2df33eee":"ShareEstateTokenCrowdsale(address,address,uint256,uint256)","2df38460":"unFreeze(address,uint256)","2df39546":"_generateRandom(bytes32,uint32,uint32)","2df3f82a":"setClaim(string,string)","2df456d4":"SetAllPaymentsSent(uint256)","2df56bb2":"unitBattleEthCost(uint256)","2df5a559":"year4LockAddress()","2df5ce67":"WorkOrderCompleted(uint128,uint256,string)","2df6e80a":"cancelTradeOffer(bytes32)","2df7c637":"ensureCurrentStage()","2df80280":"lastState()","2df80c87":"privilegedMintLock()","2df8e00d":"becomeMortal(uint256)","2df939cd":"Banglatoken()","2df9feaa":"stopElection()","2dfaf204":"executeContract(uint128,uint128)","2dfd27e8":"fecharDoacoes()","2dfdaf59":"CheckSoilTempException(bytes32,uint32)","2dfdf0b5":"depositCount()","2dff0d0d":"getById(bytes32)","2dff3498":"Relay()","2dff692d":"orderStatus(bytes32)","2dff6941":"content(bytes32)","2dff7a2b":"authoriseMaker(address)","2e0025c1":"ROLE_BACKEND()","2e011136":"deployTokens(address[],uint256[])","2e012698":"validate(bytes32)","2e01783d":"calcprice()","2e0179b5":"increaseApprovalWithSender(address,address,uint256)","2e01d229":"Attacker(address)","2e02583c":"wordlist()","2e028287":"test_oneInvalidAssertFalse()","2e029c65":"HARDCAP_TOKENS_ICO()","2e02b24c":"PMCToken(address,uint256)","2e038aaf":"randaoAddress()","2e04d730":"BuyGoods(uint32)","2e05177f":"OpenTransferToken()","2e055bcc":"preSaleSupply()","2e05b37b":"settleFee(address,address,uint256,uint256)","2e06c756":"post(string,string,string,uint256,uint256,address)","2e071db3":"updateUserAge(address,uint256)","2e081f31":"pause_3()","2e08c3d1":"checkUserWhiteList(address)","2e08eb77":"InitialTreeICO()","2e09c32f":"playRound(address,uint256)","2e0a020e":"refunduingStartDate()","2e0b1834":"periodByDate()","2e0bee7b":"createCampaign(string,string,uint256[],uint256,uint256,uint256,uint256)","2e0c6c36":"RANGEEND_3()","2e0ca1ee":"first_pay()","2e0cb498":"hashValue(bytes32)","2e0de515":"setTip(uint256)","2e0dfafc":"addBlockListed(address)","2e0e11b2":"OrderMatchFailure(address,int256,address,int256,uint256,uint256)","2e0e5ce8":"getBonusNames()","2e0eb6fd":"Lucy()","2e0eb943":"doSend(address,address,uint256)","2e0ef395":"voteOnNewEntryFees_only_VIP(uint8)","2e0f2625":"DECIMALS()","2e0fb349":"mainSaleSecondEndDate()","2e0fc7a6":"updateContributor(address,uint256,uint256)","2e102ee4":"setGasPrice(uint8)","2e108133":"qshdrop(address[],uint256)","2e10870f":"makeAnotherContractOwnerOfToken(address)","2e10feff":"addSigByProvider(bytes32)","2e13bd10":"not()","2e14ef92":"mutiSendCoinWithSameValue(address,address[],uint256)","2e15ba63":"forwardData(bytes32,address)","2e16cf54":"retrieveWallet(address)","2e16e82e":"BitcoinCityCoin()","2e17de78":"unstake(uint256)","2e18270f":"receiveBTC(address,string,uint256,string)","2e18762c":"LogUpdateInvestorProfitSum(uint256)","2e18cead":"PrivateSale(address,uint256,uint256,uint256,uint256)","2e18d8a9":"becomeBullsmaster()","2e190d03":"IncreasingPriceCrowdsale(uint256,uint256)","2e19599c":"getTargetRepMarketCapMultiplier()","2e19d31b":"proposalText()","2e19ebdc":"pIDxName_(bytes32)","2e1a348e":"TicTacToeGame()","2e1a37ee":"TCToken()","2e1a7d4d":"withdraw(uint256)","2e1a9ffe":"getPepe(uint256)","2e1b2098":"PlayerCreated(uint8,address,uint256)","2e1b7f08":"SetClaimRate(uint256)","2e1bbe98":"setLimitEth(uint256)","2e1c1d63":"BoardMeetingClosed(uint256,uint256,bool)","2e1c49d9":"testInitalBalanceUsingNewContract()","2e1d22b6":"getPlayerDividend(address)","2e1dc4b8":"setTokenReward(address)","2e1dea6b":"updateHours()","2e1e786d":"setWhitelist(address[],address[],uint256[])","2e1eb7fe":"slice32(bytes,uint256)","2e1ef07a":"getAmountOfTokens(uint256,uint256)","2e1faf75":"transferToken(address,uint256,uint256)","2e1fbfcd":"getProposalObjectionByIndex(uint256)","2e20255e":"MasterToken(uint256,string,uint8,string)","2e20b66a":"setThings(address[],uint256[],uint256)","2e217405":"limitedWallets(address)","2e21b085":"lastPriceOf(uint256)","2e226c84":"rewardForDrawing()","2e23062d":"increaseBase()","2e2326d5":"isPrivileged(address)","2e247e4f":"SRGToken()","2e25aa96":"setCharPrice(uint256)","2e25d2a6":"marketPlace()","2e26328d":"RaiToken()","2e271ff3":"getEmail(address,address)","2e276499":"minPayment()","2e279344":"getLunckyInfo()","2e27c10a":"setPI_edit_25(string)","2e283b94":"TokenClaim4BTC(address,address,uint256,uint256,uint256,uint256)","2e28b3f5":"SGX_ADDRESS()","2e28d084":"setBytes(bytes32,bytes)","2e28fd42":"complete(uint256,string)","2e293e58":"setClientPaidUpTo(address,uint256)","2e297a44":"getSmartContractsLength()","2e298f75":"setPositiveGrowth(int256)","2e2a51bd":"WitdrawTokenToHolder(address,address,uint256)","2e2a6488":"evaluation_stage_block_size()","2e2aad44":"NIMFAToken(address,address,address,address,uint256,uint256)","2e2b3f61":"TokenCreated(address)","2e2b5809":"Insurechain(address,address)","2e2bac04":"addControllerContract(address)","2e2bec5c":"getMinerLevel(uint256)","2e2cce55":"icoRound5()","2e2d6ab1":"DelayedPayment(address,uint256,address,uint256)","2e2e4149":"minTomoContribution()","2e2ed6a7":"PALToken(uint256,address)","2e2fe8a9":"ZYL()","2e2ff7c6":"transferPreSaleTokens(address,uint256)","2e3196a5":"set(string,bytes32)","2e323f5d":"Update(uint256,uint256,string)","2e325020":"getStage(uint256)","2e33178a":"zRefundAllPlayers()","2e334452":"getPublicKey()","2e336eea":"testDieIfMinReturn0()","2e338df5":"transferInner(address,uint256)","2e33cd7a":"distructVault(bool)","2e340599":"info(uint256)","2e340823":"cancel(uint256[])","2e35d7a8":"companyTokensCurrent()","2e368e03":"beneficiariesPercentage(address[],uint256[])","2e36a709":"Error(uint256)","2e3712c4":"Bitelectroneum()","2e376ada":"whitelistIndexMap(address)","2e379264":"AIRDROP_CLAIM_AMMOUNT()","2e37fa97":"doneOptions()","2e39c2b1":"Prize(string,uint256,string)","2e39ff84":"isGeneSynthesis()","2e3a0a7c":"destroyMultipleItems(uint256[])","2e3a4d12":"handleRSMCUpdateTx(address,bytes32,uint256,address,uint256,address,uint256)","2e3a4def":"isTier2(address)","2e3a5611":"create(string,string,string,uint256,string,string,uint256,string)","2e3a71d5":"futureFundingBalance()","2e3acf6b":"contractPreICO()","2e3aff3b":"getSpinnerPrice(uint256)","2e3b3123":"_multiSet(address[],uint256[])","2e3b96bf":"developersTokens()","2e3be78d":"setPrecisionDirect(uint8)","2e3c2259":"playingNTVU()","2e3c9e99":"managerAddr()","2e3ca08c":"WALLET_MARKETING()","2e3cbb3b":"sellPop(address,uint256,uint256)","2e3ced61":"periodPreITO_startTime()","2e3db828":"getAddressForUsername(bytes32)","2e3edd0f":"ntsDepositAddress()","2e3fa349":"isLpStart()","2e4040b0":"releaseTeamTokensAfter6Months()","2e404c0f":"_setDOwner(bytes32,address)","2e4054cf":"vest2advisors(address,address)","2e4099bd":"transferAirdrop(address[],uint256,bytes)","2e414890":"challenge(uint256,uint256)","2e415444":"transferUniqueId(bytes32)","2e416162":"tkstest()","2e4176cf":"chairperson()","2e4216c1":"setMinInvestmentInWei(uint256)","2e42b012":"LockAccount(address)","2e42f80c":"CDC()","2e42f860":"toUint32(bytes)","2e430824":"trackable(address,address)","2e43bdfd":"approveDecrease(address,uint256)","2e440403":"rounding()","2e448f4b":"transferAngel(address,address,uint64)","2e450881":"PRESALETOKENMAXSALES()","2e465465":"provideIndex(string,uint256)","2e466373":"resumePlaying()","2e46cb09":"AddChipTempTime(uint32,uint256)","2e46ed94":"uint8ToString(uint8)","2e471d47":"addInvest()","2e478dd8":"provideCertificate(uint256,uint256)","2e4837ea":"pickUp()","2e48f65d":"UpdateMoney()","2e49d78b":"setStatus(uint8)","2e4a3657":"returnToken()","2e4ab29e":"technicalContract()","2e4b3d59":"setSecurityPercent(uint256)","2e4bd18a":"ApproveFinishMintingRequest()","2e4c4a9f":"lunyrPercentOfTotal()","2e4c697f":"pow(uint256,uint256)","2e4d2a09":"DMC()","2e4d3189":"withdrawal(address,uint256,uint256)","2e4d59c4":"CheckBalance(address)","2e4d8c8f":"exerciseToken()","2e4eaa15":"destroyToken()","2e4f43bf":"allOf(uint256)","2e4fd0ca":"addReferrer(uint256)","2e502569":"emitTransferred(address,address,uint256,address)","2e504bdb":"distributeTokens(uint256,uint256,uint256)","2e50e3ff":"simulateOptions(uint32,uint32,uint32,uint32,uint32,uint8,uint32)","2e5113b7":"benefit()","2e519ad5":"joinGameReferred(bytes32,address,uint8)","2e519dd5":"updateLottoParams(uint256,uint256,uint256)","2e51cdf6":"getAddressFromBytes(uint8,bytes)","2e52d606":"n()","2e532ba2":"getBackgroundImage(address,uint256)","2e533630":"sendBatches(address[],uint256[])","2e541234":"AllThingsTokens()","2e558a2d":"ETTToken()","2e56fd7a":"currentDelayOnNewLevel()","2e574191":"NEURAL()","2e58e65a":"getTokenInitialPrice()","2e597ada":"ChenToken()","2e599054":"depositETH(address,uint256)","2e5a6f17":"releaseAdvisorsTokens()","2e5a79fc":"_withdraw(string,address,uint256)","2e5ab94f":"BLOCKS_PER_PHASE()","2e5ac9b1":"createToken(address,address,address)","2e5b02ae":"setCrcWithdrawAccount(address)","2e5b2168":"maxBet()","2e5b4c43":"allowTrading()","2e5b604e":"lockBonus(address,uint256)","2e5c4cef":"RRRR_Token()","2e5cc103":"createDefaultEtherDog(uint256,uint256,uint256,address,uint256,uint256)","2e5d1042":"requestPayout(uint256,uint256,bytes32,uint256,uint256)","2e5d89bd":"BlockmoXyz()","2e5df0fe":"signUpDelegatedUser(string,address,uint8,bytes32,bytes32)","2e5e00e1":"_FIFTY()","2e5ec035":"_ApplicationRemoved(bytes32)","2e5fe746":"communityTokens()","2e609c10":"presaleStartsAt()","2e61319d":"getNumberOfAddresses()","2e617512":"getAddressFromName(bytes32)","2e62190c":"valueWithFee(uint256)","2e6245c6":"internalBalance()","2e62efbb":"getOpenOrderInfo(address,address)","2e63046d":"mybUSDPrice()","2e63756f":"PriIcoSale(address,uint256,uint256,address,address)","2e639fd5":"GetPlayerInfo()","2e63cfe1":"Twoandtwo()","2e63dc80":"get_description_url()","2e64bcf1":"weiWantedOf(address)","2e64cec1":"retrieve()","2e65280d":"ListNotValidated()","2e660475":"PonziTokenV3()","2e66ee1b":"currentStateToString()","2e69e69b":"getQuantity(address)","2e69e8c5":"CarolToken()","2e6aa830":"testInitialBalanceWithNewMetaCoin()","2e6b2662":"sponsoredBonusMin()","2e6b921c":"claimTokensByAdmin(address)","2e6bbde5":"_updateCurrentAnswer(bytes32,bytes32,uint32)","2e6ccbf6":"getFactorybyIndex(uint256)","2e6d18ec":"getRoomData(uint256)","2e6d561b":"sendUnsoldTokensToTreasury(address)","2e6e190e":"Play(uint256,uint256)","2e6e504a":"trusteeWithdraw()","2e6e795c":"shareHoldersOf(uint256)","2e6f2136":"emitToken(address,uint256)","2e6f3e4a":"PERCENT_RATE()","2e6f456c":"updateCrowd(uint256,uint256,uint256,uint8)","2e70bd4f":"mintOperationCount()","2e712cc1":"getAdminComission()","2e71e68f":"IDX()","2e72057e":"GetLiasonURL(uint256,uint256,uint256)","2e722561":"CrowdsaleController(uint256,address)","2e7248bf":"MINIMUM_SELLING_UCCOIN()","2e729daf":"totalTRsWagered()","2e73dba0":"FeneroToken()","2e76a6d4":"allocateMarketingTokens(address,uint256)","2e771b17":"Spent(address,uint256,string)","2e77b3d0":"annual_circulating_supply()","2e788443":"resolve(string,address,uint256)","2e788faf":"HOLODECKS()","2e78f9a7":"getCardValue(uint256)","2e79477f":"SGD()","2e799a77":"GainChip(address,uint32,bool)","2e79d702":"addPolicyRule(bytes4,address,bytes32,uint256,uint256)","2e7a26d6":"Delineto()","2e7a9409":"_winJackPot(address,string)","2e7bcc55":"put(bytes32,bytes32,bytes32)","2e7ceb0f":"THIRD_TIER_RATE()","2e7d6253":"Sale(address,address,address)","2e7db440":"prepurchase(uint32)","2e7dc6af":"src()","2e7e33df":"sendFunds(address,uint256,bytes)","2e7e9af8":"addDistributee(address,uint256)","2e7e9d82":"ModerateBill(uint256,bool)","2e7f5107":"_processCredit(address,uint256)","2e7f9127":"setSize(uint8,string)","2e7fa0bb":"ReyNetMax()","2e80a85d":"last_jack()","2e80cc56":"crowdSaleMin()","2e80d9b6":"QUORUM()","2e80e77c":"minimumWeiAmount()","2e817963":"set_sdl(address)","2e81cdda":"setItemOptions(address,uint256,uint256,uint8)","2e82aaf2":"lock(bytes32,uint256,uint256)","2e831cd1":"update_bitcoin_ratio(uint256)","2e834576":"tokensForEth(uint256)","2e83faee":"CustodianUpgradeable(address)","2e84a374":"reclaimEtherTo(address,uint256)","2e84bed8":"VESTING_2_AMOUNT()","2e84e8ca":"ItsComingHomeToken()","2e8511f0":"getReg1()","2e85dd54":"getGPSMaxEth()","2e860fc2":"setRaiseLimit(uint256)","2e867c77":"PRESALE_BONUS_PERCENT()","2e86cb13":"publicGetAsset(uint256,uint256)","2e875a9f":"RnMmasterReq()","2e87b461":"getPlayerFrontDataForMarketPlaceCards(uint256)","2e87edd9":"MINIMUM_PARTICIPATION_AMOUNT()","2e87f4a5":"_emitRoleAdded(address,uint8)","2e881918":"setVariantCount(uint256,uint256)","2e894203":"delLitAddress(address)","2e898ddc":"validateTemporalUnit(uint256)","2e8a34a7":"addTo(bytes32,uint256)","2e8ac384":"SmartIdentityRegistry()","2e8ac517":"TokensMinted(address,uint256,uint256)","2e8c0ac2":"balancing(int256,int256,uint256)","2e8c5793":"BonumPromoToken()","2e8cbf7d":"_determineAttack(uint256)","2e8e66b9":"newRequest(address)","2e8e9bb9":"Venuscoins()","2e90610d":"auditActivity(uint256,string,uint256,uint256)","2e9066b2":"lastBlock_v6()","2e90aae8":"cuck()","2e913118":"txTaskMap(uint256)","2e91812b":"setSmallCapWhitelistParticipants(address[],uint256)","2e92abdd":"withdrawDividends()","2e932961":"setTimeEnd(uint256)","2e93497e":"ownerRandomHash()","2e9392bb":"marketEggs()","2e9453c2":"stateOfICO()","2e94afe0":"EDN()","2e94c0df":"_withdrawTokens(address)","2e9501d6":"maxThreshold()","2e963adc":"timelocksContracts(address)","2e97766d":"getBlock()","2e97c5a5":"ethToLoveyRate()","2e97f1bb":"setCustomerTxAsSpent(address,bytes32)","2e984745":"partnerID(address)","2e9868f8":"issuerName()","2e986b54":"TransferMinimumFeeConfirmed(uint256,address,uint8)","2e98a401":"preCheckAndPay(string,uint256,address)","2e993994":"changeUnforked(address)","2e995fd7":"setOraclizeAllowance(uint256)","2e99df84":"InitiateTeams()","2e9a06fd":"isValidIPFSMultihash(bytes)","2e9a3869":"MORCO()","2e9b4414":"getSpawnLimit(uint32,int256,uint256)","2e9b50bd":"addPeer(address)","2e9bbbb8":"transferOwnershipUpdateToken(address)","2e9be9d5":"signWithdraw(address,address)","2e9c135b":"proxydeposit()","2e9c5e77":"doStackExtension(uint256)","2e9c91a8":"getStartParams(bytes32)","2e9efb8e":"commitToWeek(uint256,uint256)","2e9f86cd":"create0(uint256,bytes)","2ea0dfe1":"transferFrom(address,address,uint64)","2ea1f9aa":"getEpisodeLength()","2ea23b11":"testTransferFromDoesNotAllowTransferByAddressThatHasNotBeenApproved()","2ea38693":"testCreatePrizeUsingNewContract()","2ea3ad74":"finishPreIco()","2ea3f9fc":"gelerCompte(address,bool)","2ea459b8":"claimThrone(bytes)","2ea60e35":"fourthWeekBonus()","2ea68d4b":"LazyCoderCoin()","2ea6d6da":"absMin(int256,int256)","2ea7e0d2":"Test5(uint256)","2eaa7be9":"PoolSegregationCrowdsale(uint256)","2eaad0b0":"_getAllChildren(bytes32)","2eac3a7d":"divCashCoin()","2eac5a77":"Getscoins()","2eac5ca2":"deleteUsername(bytes20)","2eacfd0f":"admin_withdraw(uint256)","2ead28fa":"BBTToken(address)","2eadda54":"number_to_hash(uint256)","2eae0018":"setMaxChildCount(uint256)","2eae0d0a":"SetTimes(uint256,uint256)","2eaf7fe0":"buyTokenPostIco(address,uint256)","2eaf81f9":"concludeTournament(uint256,uint256)","2eafb9fa":"setMintTokenOwner(address,address)","2eafc2aa":"installWinner(uint256)","2eb0111c":"currentPhaseAddress()","2eb0b45a":"setGlobalsSize(uint256)","2eb1482a":"isHorseInStud(uint256)","2eb1ee9e":"CandyLand(address)","2eb255ec":"divpaid()","2eb2c2d6":"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)","2eb37466":"removeWhitelistedAddress(address,address)","2eb3a797":"getBetKey(uint256)","2eb44efc":"ICOSaleType()","2eb4a7ab":"merkleRoot()","2eb51417":"isWithinSaleLimit(uint256)","2eb516b8":"setGNR(address,address,address)","2eb56ad4":"getUserTokensByGame(address,uint32)","2eb5c61f":"testThrowsUpdateLatestRevisionEnforceRevisions()","2eb61d15":"getAdvisorStatus(address)","2eb67f53":"isERC20()","2eb73307":"internalRefund(address,uint256)","2eb9526e":"GetBoilersInfo()","2eb95fd4":"doHijack(uint256,uint256,uint256,uint256)","2eb96988":"getMetBalance()","2eb98d34":"hosp_count()","2eb9a518":"ChangeRateOfToken(uint256,uint256)","2eb9f831":"markAsFounder()","2eba1c40":"deleteName(address)","2eba9ca9":"liquidateUser(address,uint256)","2ebabea0":"preSaleRaise()","2ebba2cf":"unitsPerEthAt(uint256)","2ebbac6c":"ico4Cap()","2ebbc58c":"getAllRouter()","2ebc4293":"getEthereum()","2ebc760b":"AvPresale()","2ebd1e28":"setTokenAddr(address)","2ebd632a":"addSystem(address,address)","2ebd9242":"TOTAL_TOKENS_ICO()","2ebe14b0":"timeoutBlocks()","2ebec916":"withdrawalProfit()","2ebeee0f":"increaseMinPurchaseQty(uint256)","2ebfa208":"checkFreeze(uint256)","2ebfeaac":"setCCH_edit_33(string)","2ec0090a":"withdrawEtherBalance()","2ec0faad":"createPassport()","2ec19f0f":"itemTransfer(address)","2ec21efd":"OuCoin()","2ec29c59":"ICOSALE_BONUSJOINTTOKENS()","2ec2c246":"unregister(address)","2ec40ac8":"reached()","2ec449d7":"MedexTestToken()","2ec47069":"assignFoundationSupply(address)","2ec6b4f6":"getUnitCoinProductionMultiplier(address,address,uint256)","2ec6ea30":"Hodl()","2ec82b8f":"balanceOfInt(address)","2ec86103":"booleanToUInt(bool)","2ec90e34":"decrementOwnedArea(address,uint256)","2ec9322d":"returnStartTime(uint256)","2ec9ad44":"removeAccessor(address)","2ec9c537":"MyFiChain()","2eca51e2":"elements(uint256,uint256,uint256)","2ecb0d64":"getNumber(bytes32)","2ecb20d3":"fromHexChar(uint8)","2ecb9279":"yesHash()","2ecbd6d8":"allowedForWithdrawn()","2ecc8703":"guardInterval()","2ecca4e6":"_destroyNinja(uint256)","2ecd071e":"Freezed(address,uint64,uint256)","2ecd7020":"getTotalTokenSold()","2ecde40e":"getRefWallet(address,address)","2ece07c3":"setUserAirDropRate(uint32)","2ecf307e":"_addrNotNull(address)","2ecf66e4":"softCapToken()","2ed028da":"addGift(address,uint8)","2ed196bd":"ccLockedUpBalances(address)","2ed1a7f6":"setProposalTTL(uint256)","2ed1e521":"generateWinMatrix(uint16)","2ed1f26e":"unlockBatchOfAddresses(address[])","2ed20ec7":"Yiha()","2ed23a73":"_releaseTo(address)","2ed252cb":"toERC20(uint256,uint256,uint256)","2ed42bf7":"_config()","2ed44309":"setIcoParameters(uint256,uint256,uint256,uint256)","2ed4595a":"participantContributionInEth(address)","2ed4a2c7":"changeState(address,uint8)","2ed4b68a":"creditFundNIMFAAddress()","2ed5016a":"SolidStampRegisterAddress()","2ed5ca29":"recordFillOrder(bytes32,uint256,uint256)","2ed604c8":"secondsLive()","2ed73df6":"starterPackCardLevel()","2ed94f6c":"bulkWithdraw(address[])","2ed9859f":"hasSongWriterSigned(address)","2edb5389":"replenishTokens(address,uint256)","2edcc661":"crowdsaleStartDate()","2edcedc6":"parkingSwitches(address)","2edefc26":"founderMultiSigAddress()","2edf8042":"collectProvisions(uint256)","2ee01240":"getUnitJadeStealingMultiplier(address,address,uint256)","2ee057ca":"deallocateItem(uint256,uint256)","2ee07c00":"closeEvent(uint256)","2ee07cbf":"AxieClockAuction(uint256)","2ee119cb":"demint(address,uint256)","2ee1e64c":"toRLPItem(bytes,bool)","2ee3cf83":"cancelOrderByAdminWithMerchant(string,address)","2ee40908":"stakeFor(address,uint256)","2ee551bf":"RESERVED_BOUNTY_GROUP()","2ee5d2e3":"last_forwarder_created()","2ee6807a":"raiseCoinsDeducted(address,uint32,uint256)","2ee6f8b6":"changerType()","2ee6fe55":"_addOwnerPlayerToTeam(uint256,address,uint256,uint256)","2ee79ded":"change()","2ee86973":"resolveHTLC(uint256,uint256,uint256,bytes32,int256,bytes32,uint8,bytes32,bytes32)","2ee8dda9":"allocateFoundationToken()","2ee92639":"purchaseCancel(address)","2ee94319":"RecievedEth(address,uint256)","2eea1efe":"getCCH_edit_20()","2eebdeb8":"_setStakeHolder(address,uint256)","2eebe94f":"weiRaisedAmount()","2eecbc7f":"deployMeDao(string)","2eecc46c":"sendTokensToInvestor()","2eed0079":"createMicroModule(uint256,string,uint256,uint256,uint256,uint256,uint256)","2eee5a3e":"totalPresaleTokensYetToAllocate()","2eef13cd":"changeArt(bytes32,string,string,string,string,string,address)","2eef3d65":"query(bytes32,string)","2ef01862":"subscriptionDetails(uint256)","2ef0a28d":"seraphims(address)","2ef140ef":"send(address,uint256,uint256,uint256)","2ef22b34":"setExpRewards(uint256,uint256)","2ef2b51d":"OWNER_TAKE_SHARE()","2ef2d55e":"channelTimeout()","2ef2edb8":"endICOStage1()","2ef345e4":"DAppSky()","2ef35214":"setVestingRate(uint256)","2ef3a7e1":"setBalancePercentageLimit(uint256)","2ef3accc":"getPrice(string,uint256)","2ef4940f":"withdrawalsVotes()","2ef4d922":"revertMe()","2ef5c784":"allTimePlayers()","2ef6d6c0":"countWebsite(address)","2ef70523":"SVDelegation()","2ef75ebc":"STAGES_PERCENT_RATE()","2ef761d3":"buyTile(uint8,uint8)","2ef771ae":"hodlFor(uint256)","2ef875fb":"div10(uint256,uint8)","2ef8c22b":"FunWorldCoinToken()","2ef9b4aa":"EngkusTechResearch()","2ef9b5a7":"changeBonusMultiplier(uint256)","2efa3c87":"TokensSpent(address,uint256)","2efa79d3":"tokensFrozen()","2efaa460":"testActivateSale()","2efad59d":"EmployeeServ(address)","2efb3f04":"getNumberOfScams()","2efb77c4":"changeDates(uint256,uint256)","2efbb80c":"addMeaningToCovfefe(uint256,string)","2efc5013":"Ask(uint256,uint256,address)","2efcb5e0":"TransferCommissionToken(uint256)","2efd08df":"totalPaintingsCount()","2efd5632":"candyLandAddress()","2efeb4e5":"LogSale(address,uint256,uint256)","2effbada":"eligibleTestAndIncrement(address,uint256)","2f002511":"viewTotalPaid()","2f004218":"PERCENT_COMMISSION()","2f00b84a":"SECToken(uint256,string,string)","2f0160e7":"fromOtherCurrencies(uint256,address)","2f034f35":"PerformingMonthlyMinting(uint256)","2f038fd5":"enable(uint8)","2f0573d9":"DSToken(bytes32)","2f0579db":"_isBreedingPermitted(uint256,uint256)","2f0746bf":"unsetWildCardToken(uint256)","2f078b12":"HashGenerator()","2f087a28":"getTokenCap()","2f08acfa":"Extreme()","2f0989ec":"release12m()","2f0ae513":"calculateTotalWithdrawableTokenAmount(address,address)","2f0b0222":"numberOfRound()","2f0b15f6":"testGetUnset()","2f0b5cb5":"setTokenTransferPercentage(uint256,uint256)","2f0b9dcb":"getArray2()","2f0c2c7c":"getReward(uint32)","2f0c59e7":"DISTRIBUTION_INVESTORS()","2f0c9387":"TestCitySnapshot(address,uint256)","2f0cca79":"dataMerkle(uint256[],uint256,uint256)","2f0d2079":"getEventBanks(uint256)","2f0d8962":"ChangeFeed(bytes32,uint256)","2f0dbae1":"MaxICOpublicSupply()","2f0ddcb2":"getTechBonus2(uint256)","2f0e23fb":"purchaseEndTime()","2f0e3a6c":"status(address,address)","2f1017cb":"getwinnerloser()","2f109d2b":"afterWhtelisted(address)","2f113f27":"LOCK_STAKE()","2f12bc02":"LiquexPrivateSale()","2f1335cf":"splitFunds(uint256)","2f13b60c":"isExpired()","2f148f55":"showMoseEvent(uint32)","2f156f69":"deployTgeTeamVesting(address,uint256)","2f158162":"setHKHcoinAddress(address,address)","2f16753c":"ShellToken(uint256,string,uint8,string)","2f1766c5":"addCA(address,address,string,string,string,string,string,string)","2f17a466":"terminateSchedule(address)","2f186785":"showProfit(address)","2f18a920":"setDeputy(address)","2f1927cb":"prepareRoll(uint256,uint256,uint256)","2f194e40":"isMintDone()","2f1a2e72":"allocate(address,int64)","2f1a332a":"OwnerRandomNumber(uint256)","2f1a8177":"weiToBnty(uint256)","2f1a8b63":"modify_ICOEndDate(uint256)","2f1af169":"EscrowMyEther()","2f1afbac":"doAirdrop(address,address[],uint256[])","2f1c34ef":"buyStar(uint256)","2f1c6494":"tgeSettingsAmount()","2f1c935e":"setSkinContract(address)","2f1cae85":"isIssuable()","2f1cc35b":"getRoundBetNumber(uint256,uint256)","2f1d29fd":"HarjFarmer()","2f1d3e28":"sendAwardToLastWinner()","2f1d5a60":"setOperatorAddress(address)","2f1ddbe3":"nodalblockShortLink(uint256,string)","2f1de784":"getPoolsAllot(bytes32)","2f1e4968":"makeNewProposal(string,uint256)","2f1ee5e1":"recycleUnreceivedBonus(address,address)","2f1f1d43":"getownership2(uint16,uint256,uint256)","2f20270a":"addNewUrl(string)","2f2035ed":"test_feePoolShare_notTranscoder()","2f204237":"setupSaleContract(address)","2f212780":"KYCbit4()","2f220d7a":"executeEscrow(uint256,address)","2f237e82":"create(string,string,bytes)","2f24bdc7":"is_transaction(bytes32)","2f254d09":"UGVCToken()","2f262471":"GetPlayerCards(address)","2f265cf7":"totalVotesFor(bytes32)","2f26b5d1":"delayIcoEnd(uint256)","2f26f6f5":"getIsCompany(address)","2f2712f8":"getStat(bytes32,address)","2f274d91":"buyVotes(uint8)","2f2769d1":"assertEq(address,address,string)","2f2770db":"disable()","2f278ecb":"reverseBytes(bytes)","2f27b556":"card_start_minamount()","2f29d8c5":"elapsed()","2f2b348d":"setBeneficiary1(address)","2f2bd5ac":"testTransferCorrectlySendsTokens()","2f2c00f3":"PTMCrowdFund()","2f2d783e":"rewardRoto(address,bytes32,uint256)","2f2d9109":"changeAirdropTotalQty(uint256)","2f2dc6e2":"setCardsCount(uint256)","2f2e2d7f":"fstUnitPriceDenominator()","2f2e3cea":"userDividendsWei(address,address)","2f2ebe41":"setToken4Gas(uint256)","2f2f010c":"OCLotteryContract()","2f2f20c1":"INCH()","2f2f4859":"helloworld()","2f2f4a63":"buyWorldCupTeamToken(uint256)","2f30283e":"testSomething()","2f3085d6":"LEGAL_EXPENSES_TOKENS()","2f30c6f6":"set(uint256,address)","2f30cd5f":"addLockAddress(address,uint256)","2f310bad":"redeemToken()","2f318039":"isTransferable(address,address,uint256)","2f32013d":"Kolidat()","2f330041":"transfers(address,uint256[])","2f334131":"lastAddYear()","2f334652":"teamClaimed()","2f335a6a":"getTitulaire_Compte_9()","2f3423b8":"grantTokenStartNow(address,uint256,uint256,uint256)","2f347e48":"DigitalTicks()","2f34adb4":"airdropNum2()","2f34c645":"endBounty(address)","2f35a71e":"Blockchain()","2f366637":"buyTickets(uint256)","2f377902":"CandyDropOpen(bool)","2f379fc8":"isInStage2()","2f381df0":"London()","2f38262a":"GetBankBalance()","2f384523":"removeFunds(uint256)","2f386a8e":"sellingDisable()","2f38b55a":"_checkDetail(uint256,uint8)","2f39bf80":"LirkToken()","2f39f5cd":"PresaleMarket(address)","2f3a212e":"test_oneValidEqUint2()","2f3a26ee":"TransferTimeSet(uint256)","2f3b24d2":"GenesisManager(address,address,address,address)","2f3b5603":"setPayoutLimit(bool)","2f3c8bd1":"returnTokenBalance(address,bytes32)","2f3d8035":"grantVestedTokens(address,uint256,uint256,uint256)","2f3e5408":"takerFeePercent()","2f3e9bc5":"canSelfDestruct()","2f3f2092":"ARIONTOKEN()","2f3f234a":"RLCSentToETH()","2f3fecaa":"startOffering()","2f3ff501":"getDynamicElementAt(uint256)","2f401300":"EPAchain()","2f405bb7":"getCoversForPacks(uint256[])","2f408990":"testAccessPermissions()","2f430e17":"approveTx(uint8)","2f434748":"setMintAndBurnOwner(address)","2f443315":"get_liquidity_account(address)","2f455d51":"changeRate(uint8)","2f45aa21":"getblockRevenuePerTicket(uint256)","2f4675cd":"OranguSale(uint256,uint256,uint256,uint256,uint256,address,address,uint256,uint256)","2f46b3cc":"getMyReport(bytes32,bytes32)","2f46ba70":"DAOToken(string,string,uint256)","2f4736da":"_canTransferBatch(uint256)","2f47571f":"isCapabilityPublic(address,bytes4)","2f475c32":"withdrawPart(address,uint256)","2f482935":"SFTToken()","2f48ab7d":"usdt()","2f48c4aa":"setFoundersTokensWallet(address)","2f48f151":"addFee()","2f4a81df":"howManyOwnersDecide()","2f4c0b08":"joinGreatHarmon(string,string)","2f4c3a84":"transferPlayer(uint256)","2f4cf60f":"MultiSigWalletWithTimeLock(address[],uint256,uint256)","2f4e32f5":"FlexiERC20Token()","2f4e4c27":"ErrorContract()","2f4ea4ee":"release_1()","2f4ee5d4":"registerThrone(bytes,uint256,address,uint256,uint256)","2f4f3316":"isInstantiation(address)","2f4fda30":"BIG_NUMBER()","2f512b6b":"LomeliMultilpleTokens()","2f520081":"setPurchaseTimestamp(uint32,uint64)","2f53cc96":"CHINESE_EXCHANGE_3()","2f540d94":"BONUS_MID()","2f54a61e":"setClaimerForTile(uint16,address)","2f54bf6e":"isOwner(address)","2f553d31":"isCreated(bytes32)","2f554288":"listPrycto2()","2f554d53":"agreeFromPod()","2f5552f5":"KAL6Token()","2f55745b":"getPendingCrateForUserByIndex(address,uint256)","2f558ba0":"setFinish(uint256)","2f55f125":"decreaseAllowanceOrEmtpy(address,uint256)","2f56dc5f":"prepareContinuousPurchase()","2f570a23":"test(bytes)","2f576f20":"doNothing()","2f581480":"CandyCoinBigBang()","2f5867b3":"changeRates(uint8,uint256)","2f58768f":"contractors()","2f591a6a":"setRateForTransaction(uint256,address,uint256)","2f593404":"payoutCycleInDays()","2f597e71":"testLongInput()","2f598404":"getCatDetails(bytes5)","2f599242":"getEvaluationByStudentID(uint32,uint64)","2f5a5c5b":"timegame()","2f5bb661":"getNextVestingEntry(address)","2f5c3102":"Make_Deposit()","2f5c5a08":"setEthealToken(address,address)","2f5d3916":"testControllerApproveTriggersEvent()","2f5e80c3":"withdrawToken(address,uint16)","2f5e8d29":"setDAIRate(uint256,uint256)","2f5ebbaa":"marketState(address,uint256)","2f5f3b3c":"pointer()","2f605106":"getSponsor(uint256,uint256)","2f6113dc":"assignICOState(address,uint256,uint256,uint8)","2f6174ef":"getSig(bytes,uint8,bytes32,bytes32)","2f62a6ff":"fipsRegister(uint256,address,bytes)","2f634a90":"getOwner(address,uint256)","2f635c6a":"VolumeImbalanceRecorder(address)","2f63e2fa":"_incrementTokenBalance(uint16,uint16,uint8,address,uint256)","2f640a09":"setConfirmer(address)","2f646bd5":"ArmMoneyliFe()","2f65142c":"getTransfers()","2f653279":"getReceivedTrade(address,uint256)","2f658c3f":"Raffle(uint256)","2f65be54":"transferBonusEarnings()","2f661946":"cliffPeriod()","2f668c5c":"etherFeeMin()","2f66d5a7":"KPOP_ITEM_CONTRACT_ADDRESS()","2f6701b0":"withdrawalList(bytes32[],address)","2f674ab9":"maybeUpdate()","2f677038":"grantUserRole(bytes32,string,address)","2f67cf56":"eth_fallback(address,bytes)","2f684b83":"addDecimals(uint256,uint256)","2f695053":"getCertifierAtIndex(uint256)","2f69ca13":"createCounts(bytes32,address)","2f69f161":"getGameResultPrice(uint256)","2f6a638b":"GetMaxEther()","2f6a6e20":"calculateMaxEggG0(uint64)","2f6ae467":"transferDocument(bytes,address)","2f6b7bbd":"Gubberment()","2f6b8143":"wethBalance()","2f6b9099":"completeOrder(address,address,address,address,bytes32,uint256)","2f6c493c":"unlock(address)","2f6dc6b3":"removeBorrowingOfferItem(uint256)","2f6e2711":"Int256Oracle(int256)","2f6e931f":"changeBurnPausedTime(uint256)","2f6f1c68":"speciesSymbol(uint256)","2f700fb6":"autoJudge()","2f70197c":"_getBalanceFactor(bytes32)","2f7146cc":"setLockingTimestampFromTo(uint256,uint256)","2f71d022":"updateTokenInfo(string,string)","2f723c7f":"RewardHoDLers()","2f72d697":"GCOXOWNToken(string,string,uint8,uint256)","2f72ffaf":"getEmployerContractsByStatus(address,address,uint256[],uint256[])","2f73010a":"ratePerWeiFirstPhase()","2f7359a3":"TOKEN_STANDARD_ERC223()","2f73ef91":"getFundsWalletBalance()","2f743591":"burnFinished()","2f7442bb":"transferBounty(address,uint256)","2f745c59":"tokenOfOwnerByIndex(address,uint256)","2f75a929":"extractRepository(string)","2f76c31d":"roundTwoLimit()","2f77428e":"collectdustatcontract()","2f774e44":"getMsgSigner(bytes32,bytes)","2f77688b":"TestingUseCoin(uint256,string,string)","2f77dba4":"tokenPerEther()","2f781228":"IjasCoin()","2f781393":"setDiscountStep(uint256)","2f782b32":"weiContributed()","2f78bab1":"LockDiv(address,uint256)","2f78dc14":"ErrMsg(address,string)","2f7907e4":"calculateBestPrecision(uint256,uint256,uint256,uint256)","2f7981c2":"getWealthOfUser(address,address)","2f798500":"clockAuctionStorage()","2f7a163b":"nearestKnownBlockHash()","2f7a407b":"exchangeFormula()","2f7a7192":"capFiat()","2f7b3677":"getMetadataUrl(uint256)","2f7cdb0e":"DEV_DECIMALS()","2f7dbc9b":"fromInt256(int256)","2f7f3ecf":"findNextHour(uint256,bytes)","2f7f7f55":"approveFee()","2f80324c":"EURO()","2f8061d4":"repayment(address,uint256,address)","2f815ed1":"transferToContractCustom(address,address,uint256,bytes,string)","2f81bc71":"multiMint(address[],uint256[])","2f83e16d":"_allocateTokens(address)","2f83f781":"fetchSuccessfulSaleProceed()","2f851184":"H4DAddress()","2f85577f":"changeACAddress(address)","2f85f092":"destTokensAdvisors()","2f86282e":"CheckGameStart(bool)","2f865568":"liquidate(address)","2f869d26":"getAssetPoolAddress(address)","2f86f2ee":"MAX_OPEN_SOLD()","2f8803bb":"addressCOO()","2f885f79":"trakToken()","2f88ae5f":"setIco3Tokens(uint256)","2f899fec":"Pharmatron(uint256)","2f8a12fe":"setMsg2(string)","2f8abfbe":"roundIt(uint256)","2f8b023d":"allowedTransferFrom(address)","2f8b0250":"setEndTimeIcoStage1(uint256)","2f8bd891":"directMint(address,uint256)","2f8c239f":"giveAdvisers(address,uint256)","2f8c98c2":"flipMovingSwitchTo(bool)","2f8cfe0e":"deleteResources(address[],bytes4[])","2f8d2d19":"BurnAssignedFees(address,address,uint256)","2f8de810":"tokenPriceInWei()","2f8e7133":"lockBBK(uint256)","2f8f0c92":"canDeposit(bytes32,address)","2f8f175c":"seal(address,address,uint256)","2f8f8c0b":"approveCertificate(address)","2f8ffce8":"allItemsWrong()","2f9021fd":"withdrawToCooperate(address,uint256)","2f90daf4":"raisedForEther()","2f91822c":"ETHCollector()","2f91b591":"RemoveMinter(address)","2f923c59":"tokenCapForFirstMainStage()","2f926732":"register(bytes32,bytes32)","2f92acc5":"test_4_accessRestriction_execute_shouldThrow()","2f92b151":"HotLove()","2f92f5a0":"query1_fnc(uint256,string,string,uint256)","2f94afba":"cao()","2f94e335":"_createLambo(uint256,address,uint64)","2f95055e":"deleteHiddenPosition(uint32,int64[2],bytes16)","2f95b833":"requiredStackDepth()","2f969d43":"MAX_UNSOLD_RATIO()","2f977b3f":"newTask(string,string,uint256,uint256)","2f978ec0":"getProviderInfo(address,uint256)","2f98511c":"createHistory(bytes32,address,address)","2f991b5a":"hasMemberAccess(address)","2f99c6cc":"BENEFICIARY()","2f9a7c22":"TransferToWaves(uint256,string)","2f9a8bf2":"StreamerContractChanged(address,uint256)","2f9b3126":"founderShare()","2f9b4096":"removeExternalController(address)","2f9c1df6":"createDeposit(address,uint256,uint256)","2f9cb9aa":"getClosingTime()","2f9ffab9":"Airstayz()","2fa00e58":"fipsTransfer(bytes20,address)","2fa05208":"minimalGoalReached()","2fa06ff1":"exchangesLockEndingAt()","2fa07bfc":"_increaseApproval(address,uint256,address)","2fa146d8":"officialEmail()","2fa1df4f":"RIG()","2fa241fc":"playerBook()","2fa267fc":"ReadBible(uint16,uint16,uint16,uint16)","2fa26aaa":"minimalEthers()","2fa30d33":"calcResolve(address,uint256,uint256)","2fa3a41e":"testLowestTranch()","2fa3e006":"CreatedToken()","2fa49c06":"SetTxFee(uint256,uint256)","2fa4f694":"setAssessorPool(uint256,address,uint256)","2fa553d3":"sendMinerByOwner(address,uint256)","2fa5620a":"Mpay(uint256,string,string)","2fa61cd8":"generate(address)","2fa6512f":"clearWalletPending()","2fa69585":"strikeCall()","2fa78393":"returnUserBalance(address,address[2],uint256[7],uint8,bytes32[2])","2fa7cbfb":"getExecCost(uint256)","2fa80164":"AgruCoin()","2fa8591e":"TACTICALCRUISER()","2fa92dde":"jackpotConditionPercent()","2fa94fb3":"teamTrustAccount()","2fa975c5":"seatsList(address,uint256)","2fa99791":"completeOrderBySafePeriod()","2faa2998":"startICO_20_December()","2faa3014":"uintFunc(uint256,uint256)","2faa5e3c":"changeMerchantAccount(uint256,address)","2faa9bbb":"LockClaimed(address,uint256)","2faad46f":"addAllowedTransactor(address)","2fab662a":"_decreaseMintApprovalAfterMint(address,uint256)","2fabc174":"multFracCeiling(uint256,uint256,uint256)","2fac1a54":"newOrder(bool,uint256,uint256,uint256,uint256)","2fac1d36":"isReadyFor(address)","2facc4e8":"depositGovernance(uint256,address)","2faccbeb":"changerProprio(address)","2fad380d":"burnWithDecimals(uint256,uint256)","2fae43dc":"m_ETHPriceLowerBound()","2faebb20":"getBettersArrayLength()","2faef47a":"AbcToken()","2faef4e5":"getGranteesSize()","2faf1895":"saveContractEvent(string,string)","2faf9a93":"checkUnsold()","2fafb11d":"get_profit_by_roll_under(uint256,uint256)","2fb07482":"restoreWebGift(address)","2fb131d4":"preicoClosed()","2fb1746d":"turnOnTradable()","2fb1b25f":"sign(uint256)","2fb22cfa":"ECO_SYSTEM_STAKE()","2fb260f6":"EthertokenDelta(address,address,address,uint256,uint256,uint256)","2fb27669":"preSaleComplete()","2fb2a061":"rateForDays(uint256)","2fb2bcf4":"postTwit(string)","2fb2f3dd":"updateFrozenToken(address)","2fb556f7":"tokenNeedForBonusLevel0()","2fb565e8":"update(uint256,uint256)","2fb5b5f6":"setNextSnapshotBalance(address,uint256)","2fb61f7d":"dispute(address,bool,uint256)","2fb767c5":"failSubtractWhenALessThanB()","2fb840f5":"transferFrom(bytes32,bytes32,uint256)","2fb88284":"parseRLPHeader(bytes)","2fb9d203":"VoteSubmitted(address,bytes8)","2fbaba26":"setHash(uint256,string)","2fbac05c":"transferManagment1(address)","2fbbc9c9":"calcCoinsReceived(uint256)","2fbbde2d":"buyDrago()","2fbc0bf1":"getSalePrice()","2fbc2449":"COLETOKEN()","2fbc8353":"ownerCanBurn(bool)","2fbcf568":"getCurrentCryptantFragmentPrice()","2fbd2134":"_migrateExpiredCrates()","2fbd2432":"transferExternalToken(address,address,uint256)","2fbebd38":"foo(uint256)","2fbf6f73":"TRNDToken()","2fbfbc85":"PETTCOIN()","2fbfc252":"changeTeamETHAddress(address)","2fbfc376":"HRY(uint256,string,string)","2fbfe951":"change_min_amount(uint256)","2fbfeba9":"getTokenAddressByName(string)","2fc0aad3":"isNumericString(string)","2fc15517":"kelly()","2fc17e40":"TdeStopped(uint256)","2fc17f8b":"setCompte_3(string)","2fc35948":"SCWhitelist()","2fc3f13f":"WindowPeriodClosed(address,uint256)","2fc4eea0":"removeName(bytes32)","2fc516e3":"COMMON_BUDGET_AMOUNT()","2fc52220":"setPOOL_edit_19(string)","2fc5a8ec":"Joules()","2fc60405":"TANK_TYPE()","2fc64ff7":"organizer8()","2fc6e8b7":"isEnd()","2fc71565":"setMarketplaceAddress(address,address)","2fc761a6":"createItem(uint256,string,address,uint256,uint256,uint256,uint256)","2fc77d85":"TotalETHGivenToNorthPole()","2fc8124d":"setSecondWallet(address)","2fc84de8":"XCTToken()","2fc8c39d":"TADPOLE_BASE_REQ()","2fc94ba6":"getAddressArrayLength(bytes32)","2fc9a415":"_emitAccessGiven(address,bytes32)","2fca3b0d":"TBECrowdsale()","2fca5414":"isTAO(address)","2fcaa8fa":"removePresaleHolder(address)","2fcb20e9":"changeReserveTeamRecipient(address)","2fcb6628":"_stringGas(string,string)","2fcd410a":"MiniPoolEdit_2()","2fcd6075":"BlocktekUniversity(address)","2fcdeba1":"fund_owner()","2fce1291":"EcroContract(uint256,uint256,uint256,uint256,uint256)","2fcf84bf":"getEthereumFromPreIco()","2fd0f37e":"claimConsolationPrizeLoot(uint256,address)","2fd23817":"MFTU()","2fd3bd2e":"passFoundation()","2fd3dee8":"testDisputedValidMemoryAccessSequence()","2fd3fc9d":"bthFoundationWallet()","2fd463e1":"STARTMETADOLLAR()","2fd47643":"getRoundIssued()","2fd4ec28":"terminateIco()","2fd4f2f9":"changePreICODates(uint256,uint256)","2fd55265":"depositToken(address)","2fd5a13d":"GetClientCategory()","2fd5ecda":"b66AdvisorFundDepositAmt()","2fd6d40b":"getBetValueByGamble(uint8)","2fd949ca":"terminateContract()","2fd95a6f":"createGen0(uint256,uint256,uint16,bool)","2fd97c7d":"AllotAward()","2fda7166":"stopReceiveTicket()","2fdadc21":"sendtoA(uint256)","2fdae3c5":"addProposal(string)","2fdaf6af":"claim_tokens(address,uint256)","2fdb3e6c":"getBalanceETH(address)","2fdbb3d4":"cumAcceptedDeposits()","2fdc505e":"mine(bytes32)","2fdcfbd2":"sendToken(address,address,uint256)","2fdd653e":"getFortune(uint256)","2fdde1d4":"setUseTimeBasedBonus(bool)","2fddf859":"getLockedTokens_(address)","2fdeca37":"DEFAULT_TEXT()","2fdf15d5":"usernameToAddress(bytes32)","2fdf795a":"BOUNTY_TOKENS_PERCENT()","2fdfd2ae":"checkSecret()","2fe045fa":"initiateClaimDelegated(string,bytes32,uint8,bytes32,bytes32)","2fe1c0f8":"tokenTransfer(address,uint256,address[])","2fe20e94":"totalRestrictedTokens()","2fe29c78":"auctionIdToSeller(uint256)","2fe45a8d":"RetailSale(address,address,address,uint256,uint256,uint256,uint256)","2fe4b2d9":"submitSteak(address,address,bytes32)","2fe55632":"NexxusToken()","2fe69430":"TokenERC20(uint256,string,uint8,string)","2fe6a47c":"largestPro()","2fe6ecb2":"PHASE3_SUPPLY()","2fe71915":"request(uint256,address,address,bool)","2fe7a0bd":"burritoData(uint256)","2fe8ace3":"changeSuperOwnership(address)","2fe9541f":"addIssueBounty(string,uint256)","2fe97e3a":"approveAndCall(address,uint256,string)","2fe9950e":"adminSetDuel(uint256,uint256)","2fe99bdc":"insert(string,string,string)","2fe9e1a9":"change_address(uint256,address,address)","2fe9f821":"startRefunds()","2fea0c40":"revealBid(bytes32,uint256,address,address,bytes32,uint256,uint256)","2fea6915":"weiReqFund()","2fea7b22":"GetIndex(uint256,uint256,uint256)","2fea7b81":"getIdentity(address)","2fea9624":"DepositorsQty()","2feceb46":"extend_end_block(uint256)","2fed3c9e":"VoteCast(address,uint16)","2fed7da0":"getNextBackUserId()","2feda2fa":"POI()","2fee26ce":"addApp(address,uint32,uint32,string)","2feee782":"YWBToken()","2feef2ec":"expectedAmount()","2ff077be":"updateBettingOpensTime(bytes32,uint256)","2ff284c2":"computeFee(uint256,uint256)","2ff2e9dc":"INITIAL_SUPPLY()","2ff36e9b":"BTHBCoin()","2ff420ef":"CHF_CENT_PER_TOKEN()","2ff42757":"approveAndCall(address,address,address,uint256,bytes)","2ff4f24e":"createLoveStory(bytes16,bytes32,bytes32,uint256)","2ff50b51":"modifyEscrowPrice(uint256,uint256)","2ff59dec":"getEthartRevenueReward()","2ff59ee7":"miningIncentiveWallet()","2ff5e00c":"setAttaccContract(address)","2ff5ec3f":"armyTanksCount(uint256)","2ff6c55f":"DEVELOPMENT_FUND_LOCK_TIMESPAN()","2ff6fe76":"priceToken()","2ff76163":"getAdres(uint16)","2ff7a81f":"getAvgReportingGasPrice()","2ff92323":"oraclize_query(uint256,string,string[4])","2ff98d53":"getStageClosingTime(uint256)","2ff9b03a":"hackDecisive(address,uint256)","2ff9f017":"exchangeNominsForHavvensAtRate(uint256,uint256)","2ffa815b":"changeHouse_and_Owner_Addresses(address,address)","2ffb054e":"setMarketplaceManager(address)","2ffb8631":"getReleaseLockfileURI(bytes32)","2ffb9e64":"updateGasForXaurData(uint256,uint256)","2ffbf988":"packedBytes(uint256)","2ffc7b7e":"firstDiscountPrice()","2ffda1e0":"setBlackflag(uint256,bool)","2ffda952":"walletWithdrawTokens(uint256)","2ffdaa44":"BDToken()","2fff7bb3":"assignMultirequest(uint256)","2fffaa00":"Kingdom()","2fffb3f9":"getLockFundsReleaseTime(address)","2fffe0dd":"rocketArrivalTime(uint256)","2fffee92":"setContingencyFunds(address)","30007ed3":"tgeStartBlock()","30008b48":"pullDividendPayment(uint256)","30012940":"checkTeamFreezePeriodOver(address,address)","300182b8":"sale1(address,uint256)","30021bae":"SubDiv(uint256)","300240d6":"MAX_REGULAR()","300309f0":"setUserPaybackRate(uint256)","30043d4e":"AddedToHolder(address,uint256,uint256)","3004ea88":"EOSDRAM()","30067bc8":"setRegistrationOpen(bool)","3006f513":"coinSendDifferentValue(address[],uint256[])","30073514":"_allocation(address,address,address,address,address)","30074c6c":"publicSaleRaised()","30092ded":"changeVoteWeight(address,int256)","30093319":"_setRevealsCount(uint256,uint256)","3009a265":"isReg(address)","3009bc01":"claimFreeDragon()","300a1a7f":"mixWithStringFunc(int256,string,bool,string)","300a246f":"can_get(address,bytes12)","300a411e":"getRecording(address,uint256)","300abd61":"m_numMembers()","300ac0e9":"priceTimeToExpiration()","300b59da":"initTokens(address[],uint256[],bool,bool)","300ba0ec":"prevTweetTime()","300ba8ab":"_decode()","300c229f":"changeMaxDepositAmount(uint256)","300c3091":"setMigrationContractAddress(address)","300c7063":"SbToken()","300cc37a":"paySomeRewards(uint32,uint32)","300d55a5":"transferAdvisor1Tokens(address,uint256)","300d9e90":"icoOver3()","300e4b3c":"setminprice(uint256)","300e7b2d":"firstAuctionsExtendedDuration()","301058c9":"DURATION_PRESALE()","30106b17":"calckeys(uint256)","3010b5cd":"clearWizzType(uint256[2])","3010f39d":"playersToBetIndices(address,uint256)","3011b4c2":"CreateARTL(address,uint256)","30124349":"balanceLoc(address)","301249eb":"setPercentWeiMC(uint256)","3013ad89":"RangeToken()","3013ce29":"paymentToken()","30140053":"burnIcoTokens()","3015394c":"cancelRequest(uint256)","30155f5e":"setzAddress(address)","3015a521":"totalSignatures()","3016a439":"getImageBlurredAt(uint256)","3016e108":"removeGameMachine(address)","3017fe24":"callAPIVersion()","3018205f":"getController()","30183a2c":"GemstoneToken()","30184635":"getMinCap(address)","3018579e":"TokenSampleG()","30188fdf":"BFreeContract()","3018c90a":"getSubOrderStatus(uint256,address)","301997ae":"fundEscrow(address,uint256,uint256,uint256)","301a9b09":"startPhase(uint256,uint256,uint256,uint256)","301b9307":"getABsort()","301c42d7":"issueRateDecDuringICO()","301cbcb3":"STARTING_RICE()","301cf6e7":"payoutsPaused()","301d5209":"delegatecall_selfdestruct(address)","301d5eda":"change_start_block(uint256)","301dd027":"TIER_2_CAP()","301df7ab":"_create(address,uint256)","301ea971":"lockReleaseDate1Year()","301ecf82":"_createEtherBro(uint16,address)","301f0464":"ratePerEthPhase3()","301f2dac":"getRegionPrice(uint16)","301f93e0":"calculateEthereum(uint256)","301fbdef":"totalWeiToBeDistributed()","301fdb54":"getPayouts(int32,int32)","30203994":"stage2_price()","3020a18e":"setSaleEnabled(bool)","3020ea8a":"retrieveEarnings()","302155e5":"CHAToken()","30223c12":"del_product(uint256)","30226121":"CCXCrowdsale(address,address)","30228a12":"YouAreRichToken()","30230796":"setTradeABIHash(bytes32)","30231ea4":"canRenounce()","30232cb0":"buySeele(address)","3023641d":"removeTokenGrant(address)","30238687":"ALLOC_NEW_USERS()","3023d0c4":"Ethstick()","302579c6":"getWarlordChestPrice()","30257bf7":"getByAddress(address)","3026a128":"LOG_InvestorExit(address,uint256)","3026aedf":"getTopBidders()","30288f03":"setFile(string,string,uint256,string)","30289c61":"getDetails(address)","3029300f":"nextSellTime(address)","3029948a":"phase_2_bonus()","3029ba69":"withdrawBountyTokens(address,uint256)","302a4100":"decayedTransferFrom(address,address,uint256,address)","302a7ff3":"getDAdmin(bytes32)","302bcc57":"playerCount()","302bda24":"getSell(uint256,address,address)","302c46ba":"ReleaseTokenForTeamAdvisersPartners()","302d350e":"firstChainedCallback(uint256)","302dfe97":"commissionPer()","302eb389":"transferFund()","302f3915":"LockFunds(address,uint256)","302f4303":"setRandomGenerateMethod(uint8)","30311898":"Account(address)","3032236f":"depositAndVest(address,uint256,uint256,uint256,uint256)","30322b12":"weiForMcr()","30323542":"_delOwner(address)","30324370":"fetchOrderByIdWithPayer(string)","30324f55":"DutchAuctionToBuy(address,address,address)","30326c17":"proposal(uint256)","3032f951":"advisorsBalanceMap(address)","30332aea":"P2()","3033f4d3":"pastOneHour()","30347537":"STARTING_CAT()","30366d5f":"getEventsCount()","3036d769":"minGasPriceGwei()","3037408d":"balanceOfAtTime(address,uint256)","3037801e":"recordNum()","3037cea3":"knownRoleNames(bytes32,bytes32)","3037e694":"disburseDividends(uint256)","30381f5f":"getHistoricalDelegation(uint64)","30389c45":"round1BonusSteps()","3039b1ce":"changeETHLockingAddr(address)","3039e6f9":"CHARITY()","303a2372":"getDSP(address)","303a36e2":"getRow(uint256)","303a88b4":"convertRate(address,bytes32,bytes,uint256)","303b069f":"enableEmergencyWithdrawals()","303b5d3b":"toInt(string)","303b8144":"MobilinkToken()","303b9379":"SetLogFile(address)","303bef74":"deleteAllMessages(address)","303c2569":"payRakeInternal(address,uint256)","303d0870":"limitForChecklistId(uint8)","303e74df":"descriptor()","303ed73a":"setSkills(address,uint256,uint256[])","303ee989":"isPendingDeregistration(address)","303f5f51":"LEGEND()","303ff1d8":"YDTC()","30406423":"payJackpot()","30411a27":"testAddGains()","3041ba2a":"setForecasting(address)","3042b17d":"setUmkaAddress(string)","304318d3":"editDuration(uint256)","3043cbc5":"newTankType(uint256,uint256,uint32,uint32,uint32,uint32)","30443062":"penultimateFeePeriodStartTime()","3045a299":"Society(string,address)","3045aaf3":"Symbol()","3046868d":"AccountStructs(address)","3046fe26":"XulToken()","30473c2f":"getSelectedName()","30490e91":"processProposal(bytes32)","304a45c2":"getvalues()","304a87b7":"setOpenGroup(uint256)","304ab76a":"DebtTokenCreated(address,address,uint256)","304bac6f":"func_0A6E()","304c69ed":"_packItemData(address,uint256)","304cb3d8":"setTrusted(address,address,bool)","304d50b2":"addStar(address,uint8,uint8,uint16,uint8,uint8,uint8,uint256)","304d95a6":"RefundPoll(address,address,uint256,uint256,uint256,bool)","304dd754":"IsActive()","304ddebe":"eventSetWinner(uint256,address,uint256)","304de747":"MARKET_CAP_PER_ROUND()","304dfd33":"_onRandomFailed(bytes32)","304e48bb":"LogFundingReceived(address,uint256,uint256)","304f34a0":"splitBid(uint256)","304f5027":"myUserWallet(address)","304f8af4":"sendBountyTokens()","30500684":"addEarlyBird(address,uint256)","3050226a":"addTransferableAddresses(address[])","30507451":"receiveBonus()","305075db":"NormalizeRanks()","305094ab":"ispackagesaleClosed()","30509bca":"claimBalance()","3050caa4":"calculateStake(bytes8,bytes5)","3050f769":"transactionsClaimed(uint256)","3052b75e":"changeEndTime(uint256)","3053aedc":"capDoublingTimestamp()","3054c79a":"transform()","30573dfa":"auditGuess(uint256,string,uint8,bytes,uint256)","305788fa":"newTransferProposal(address,string)","3057d5e0":"residualAmountPromille()","305876a7":"isRoundOver()","305939b0":"setReceiptAsset(address,address)","305997c8":"addIsSafe(uint256,uint256)","30599ba7":"SOSBOTTOM()","30599fc5":"recoverTokens(uint256)","3059ac30":"Escrow(address,address)","305a67a8":"cancelListing(uint256)","305a762a":"getTicketsCountByBuyer(uint256,address)","305a99c1":"Kemonocoin()","305b73d9":"configure(address,address,uint256,uint8,bytes32,bytes32)","305bcfab":"TrustlessTransaction_Protection_Seconds()","305d6d31":"stopFundRaising()","305e3552":"eggPrice()","305eae79":"updateBusinessWallet(address,address)","305ec69e":"finish(address)","305ed015":"giveReward(address)","305f17d5":"setCrydrController(address)","305fcef3":"decide()","306023a3":"allocateTeamTokens()","3061d568":"GOC()","3061e0ef":"changeRecovery(address,address,address)","3062cd8a":"purchaseETH()","30630699":"testDisputedWriteDifferentValueInState()","306387a4":"dealStatus(uint256)","3064061b":"checkNotSmartContract(address)","3064448e":"ASCCToken()","30659e74":"moneyBack()","3065a575":"setAElfDevMultisig(address)","3065d22c":"setVariationProbably(uint256)","30677b83":"multiplierFactor()","306781c1":"getCurrentPayoutBlock()","3068bffd":"grantIssuer(address)","30690468":"atleastZero(int256)","306a2ea8":"disapproveUser(address,bytes32)","306a401d":"delMarketMakerAddress(address,address)","306a8589":"p_update_mNewPlotTaxPercent(uint256)","306ab1ba":"forwardFundsAmount(uint256)","306ae57b":"standAndRebet(uint256,uint8[],bytes32,uint8,uint8,bytes32,bytes32,uint256,bytes32,bytes32,bytes32)","306b031d":"getGenerationEndAt(uint256)","306b0d84":"SetSharedStorage(address,address)","306b4dea":"addQuantityListItem(bool,address,address,uint256,uint256)","306c4ebe":"getCurrentTrancheVolume(uint256)","306c7290":"eth_balance()","306d4ed9":"userHasWithdrawn(address)","306df22d":"GPSDestination(int256,int256,uint256)","306e3e99":"COMPANY_SHARE()","3070352b":"buyAMI(string)","3070c38b":"checkTermination()","30710f01":"Crack(address,uint256,uint256)","30725c46":"_ownerOfPopInAnyPlatform(uint256)","3072cf60":"_initialized()","3073530b":"release_2()","3073c916":"cancelEscrowByProvider(uint256)","3073ef42":"calculateOperationFee(uint32)","307482cf":"POINT_ROOTNODE_ROLE()","3074cca7":"change_data(bytes32)","3074f556":"Compra_Ticket(uint256,uint256)","307540f6":"keys()","30756ab6":"MyTestToken()","3075f552":"getMax()","30762e2e":"allowManuallyBurnTokens()","30765517":"fechAllSumNumForCandidateByStage(uint256)","3076dc42":"intervalDuration()","3076e56a":"tankOut()","3077fdf1":"startNewICORound(uint256,uint256)","3078db6c":"transferAuthority(address)","3079ddc3":"isCanBuy()","307a1f46":"paramsValid()","307c6f8e":"job(string,string,uint256,uint256)","307c7a0d":"withdrawExcessBalance(address,address)","307ca045":"get_amount_minus_fee(uint256)","307d2a90":"priceEUR()","307e38ca":"isICAP(address)","307e8614":"returnUserBalance(address[2],bytes32)","307edff8":"endTokenSale()","307f35e6":"AobcToken()","307f6244":"changeMedia(address)","307f6b12":"findWinners(uint256)","30807e8e":"updateCSV(string,uint256)","3080b9c7":"SocialBlock()","30818189":"bonus1()","3082538f":"decimalMultiplier()","30835cc5":"BDCC()","3083a4f9":"withdraw_2()","3083ab1f":"closeContest(uint32)","30840c31":"testControlCreateWithParentForeignNotInUse()","3084e3ac":"nDEX(address,address,address,address,uint256,uint256,uint256)","30852db8":"newGame(uint256,uint256,uint256)","30859963":"getAttrVal(uint64,uint8)","3085c91d":"SellOrderCanceled(uint32,address)","30865362":"withdrawRemainingRewards()","308655b1":"A2AToken()","3086719a":"_setTokenUri(uint256,string)","3087110a":"donors()","30880441":"borrowFor(address,address,uint256)","308879bf":"setVoteCost(uint256)","308a9717":"_distribute(address)","308af165":"lastProcessedDay()","308b2fdc":"getProposalValueByIndex(uint256)","308b7fea":"rakeToken()","308c0065":"currentPrice(uint32)","308d6613":"getSignData(uint256,uint8)","308dc720":"DissolveBusiness()","308dccac":"EtherMinerals()","308e1b2f":"ltcId()","308e25ac":"InvestorsToken()","308e63f4":"TigerToken(uint256,string,string)","308f505b":"sellSupply()","308fb3ee":"GrapeToken()","3090bef7":"releaseLockedBalance(address)","3091bc8b":"acceptAndPay(bytes32,uint256[],uint256[],uint256)","30920505":"createInvestContract(address,uint256,uint256)","3092afd5":"removeMinter(address)","3092e73f":"getNoOfTokensTransfer(uint32,uint256)","30935e4b":"LogOrderCancel(address,uint256,uint256)","309424fe":"get_all_names()","30943fcf":"ownerCounter()","30945443":"update(address,string,string)","309593ee":"emergencyThaw()","30962d4d":"KyberContirbutorWhitelist()","309652ec":"getPoolMoney()","3097324c":"saleShare()","3097f94c":"blok()","30982855":"setPublisherStake(bytes32,uint256)","30986dea":"timeToFinishPresale()","3098d33a":"payoutPartners()","309945ba":"collectedFees(uint256)","30996897":"placeBet(address)","309ab7e1":"getIsParticipate(address,uint256)","309b40b2":"liquidityStatus()","309b7ed3":"deleteParent(uint256)","309ba120":"upgradeClass(uint256)","309c1769":"ProspectorsObligationToken()","309c315d":"calcTokenPriceFactor()","309c3ee2":"_grandPVPWinnerReward(uint256)","309d094b":"RELEASE_DATE()","309d6669":"addVerification(address,string,string)","309d8210":"ICOPart()","309d9358":"XENTToken()","309e078a":"destTokensBounties()","309e21a9":"rewardPromille()","309e36ef":"getNumberOfAccounts()","309e6005":"batchTransferEther(address[],uint256)","309e63e5":"SimpleConstructorInt(uint256,uint256)","309f7421":"buildTeamMapping(string,string,string)","309f955a":"updateTopicDescription(bytes15,bytes32)","309fcbdd":"MakeTradable(bool)","30a0b231":"oraclize_query(uint256,string,bytes[])","30a1d746":"shareholdersWalletAddress()","30a24abd":"create(bytes4,bytes)","30a3160d":"approveInternal()","30a35ce2":"getPOOL_edit_20()","30a39d5d":"preCoinSentToEther()","30a3ce81":"getNumChips()","30a55316":"smsCertifier()","30a69955":"setFeeInfo(string)","30a69b53":"PlutocracyAchieved(string,string)","30a7351c":"removeFromApprovedAddress(address)","30a7a11c":"setRateEarlyStage1(uint256)","30a8b2c9":"NUM_TEAMS()","30a95aa7":"payService(address,uint256,uint32,string,uint64,uint64,uint64,uint64,uint64,uint64)","30a95e67":"withdraw_eth(uint256)","30a9ef5b":"checkTokBalance(address)","30aa311a":"QMQCoin()","30aa81c6":"getPayer()","30aacc0a":"setProjectAgent(address)","30ab0a16":"setInstructor(address,address,string,string)","30abac7b":"randomNext(uint256,uint256)","30abf433":"signBBODocument(bytes32,bytes)","30ac3052":"sendText(string,string)","30ac324b":"apply(uint256,uint256)","30acd249":"oneEtherInKicks()","30aceb89":"validateRequestParams(address[3],address,uint256[11],uint256,bytes,uint256)","30acedf1":"ownerFreezeTokens()","30ad12a6":"initializeFundraiserToken(address)","30adce0e":"etherReceived()","30ae8d0c":"Xinfin()","30af41b3":"getValidatorByIndex(uint256)","30b0e001":"airdropTokenDistribution(address,uint256)","30b0faab":"changeSettings(uint256,address,uint256)","30b2b8aa":"mintPresaleTokens(address,uint256)","30b3409e":"getInitialDeposit()","30b39a62":"withdraw(string,uint256)","30b3a90c":"_setCurrentPassportLogic(string)","30b4429e":"submitBlock(uint256,bytes)","30b5198f":"blockNumberUpdated()","30b57b1e":"player(bytes32)","30b66475":"VerifSignature(bytes,bytes)","30b66cee":"claimProxy()","30b69426":"calculate_eligible_token_balance(address,uint256)","30b7222f":"mintcoin()","30b751d9":"rivetzRelease(uint256)","30b823f7":"userGrowthAddress()","30b8f85d":"HSB()","30b9af98":"withdrawFunding()","30ba040a":"TOKENOMICX()","30ba2d4d":"eidooSigner()","30bb7499":"_batchActivenessUpgrade(uint256[],uint256[])","30bbb55e":"instructions()","30bd2ba9":"MassivelyMultiPlayerOnlineVideoGames()","30bd3eeb":"tokenRewards(address)","30bd60ef":"marginCall(bytes32,uint256)","30bdd344":"getPossibleWinAmount(uint256,uint256)","30bdf202":"RobinHood()","30be5990":"updateThirdChangeBlock(uint256)","30bf2d3e":"whaleBalance()","30bfeded":"EffectAdded(uint256,uint256[])","30c0f8d6":"scheduleTransaction(address,bytes)","30c2927d":"concludeUFT()","30c2fb04":"UserAuthManager(address)","30c308d8":"testInsertCase()","30c30a50":"authorizeMintFulfiller(address)","30c33da7":"_addPresale(uint256,uint256)","30c3eaa8":"grant()","30c47f77":"getEtherCoinPrice()","30c5375e":"ConstructHuntStart()","30c5a614":"ethereumToTokens_(uint256,uint256)","30c74e04":"tokenWithdraw()","30c8a488":"ERCToken()","30c8f372":"getTrustedShopCount()","30c93307":"GetPermissionIdx(uint256)","30c97068":"plockFlag()","30ca0a53":"DELEGATION_HASH_EIP712()","30cb14d2":"pop(bool)","30cc1d18":"airDropShadowTag()","30cc248e":"increaseProfit()","30ccc891":"testTransferHandlesNegativeAmountRequest()","30ccebb5":"getStatus(address)","30cd90b8":"transferToAddress(address,address,uint256,bytes)","30cd9ac6":"TokenAuctionCompleted(uint256,address,address,uint256)","30cdc195":"xclusivecoinSupply()","30cdcc63":"MAX_ISSUED_FROM_OTHER_CURRENCIES()","30cddc83":"checkIfCustodiesServedETH(address[])","30ce7b5d":"generateWinNumber()","30ce8bd5":"_rightChild(uint8)","30ced655":"EventRandomLedgerRevealed(address,uint256,uint256,uint256,address)","30cf7af6":"FreeZombieCount()","30cfac6c":"assignTo(uint256,address,uint256)","30d02d83":"batchWithdraw(uint256,uint256)","30d07d61":"getParticipantName(uint256,uint256)","30d12640":"disableWithdrawal()","30d15b0a":"lockInQuarterFinalPrize()","30d1c191":"MetaPoc(address)","30d2219b":"add(string,string,string,string,string,bytes32)","30d2474f":"buy1ticket()","30d281e0":"getChannelInfo()","30d323ae":"NHC()","30d4b967":"Octogram()","30d4d8d0":"_verifyHistoryInputOrRevert(bytes32,bytes32,bytes32,uint256,address)","30d500bf":"CFO()","30d636a0":"SmartVerifying()","30d65b72":"getPaymentsFor(address)","30d68214":"transactionReplay(address,uint256)","30d86516":"verifyTransferSignature(bytes32,address,uint8,bytes32,bytes32)","30d88a9e":"DISPLAY_VIDEO()","30d9161d":"cancelCreatorAuction(uint40)","30da4684":"buyPriceFinal()","30db7654":"activeBuy()","30dbb4e4":"isUnlocked(address,uint256)","30dcf0e8":"calculatedTokens(address,uint256)","30dd6a42":"totalSoldToken()","30dd9ee4":"confirmMinerQuest(address)","30de7e88":"FINXToken()","30df2c47":"currentSeller()","30df7727":"canRemove()","30dfc62f":"fundValueCount()","30dfe1da":"getTransactionCount(bool)","30e0789e":"_transfer(address,address,uint256)","30e07be0":"getMaxAmountToWager(uint256)","30e08a6e":"adjustMinter(address,bool,int256)","30e1e4e5":"freeze(address,uint256,uint256)","30e1f16f":"claimDividendAll()","30e26cb8":"disableBundling()","30e290e4":"Twitter()","30e34360":"setValue(bytes32,bytes15)","30e44278":"howVotesHasDispute(uint256)","30e45c14":"preSaleHasEnded()","30e4f9aa":"contractbalance()","30e57b67":"getNumberOfCrySolObjects()","30e5be52":"Prototype()","30e656d8":"addAnimal(uint256,bytes32,uint8)","30e6570b":"BucketSell(bytes32,uint256,address,uint256)","30e664f6":"getBuy()","30e6c333":"producedGoldCaps()","30e6d8d3":"addInitialInvestor(address)","30e7002c":"POCN()","30e76dae":"getContractEtherBalance()","30e77c75":"EthTranchePricing(uint256[])","30e804d1":"withdrawFromProject(address,address,uint256)","30e80864":"setTrustedAddr(address)","30e82803":"balanceOfByPartition(bytes32,address)","30e8b963":"reserveMember()","30e9c341":"updateTimeLock(uint256)","30e9f6ed":"STATUS_NO_DEAL()","30ea55a0":"updateEventStartsTime(bytes32,uint256)","30eaa9b5":"priceIncrease_20_February()","30eb4ba8":"setHoldDuration(uint256)","30ec0e2b":"setHolder(address,address,address)","30ec98a1":"OKFToken()","30ece116":"setOpeningTime()","30ed54ed":"setVestingToken(address,address)","30ee776c":"StopTransferToken()","30ef3d56":"takeNumber(uint256)","30efac4e":"changeCardPrice(uint256)","30efb8d3":"doUnpause()","30f1154f":"updateNodeIPFSHash(bytes)","30f12642":"createContractPreciousForEdition(address,uint256,string)","30f1fe82":"checkLength(string)","30f20847":"CandyBox()","30f24455":"_getProductShopInfo(uint256)","30f3f0db":"increase(uint256)","30f46b70":"power(uint8,uint8,uint8,uint8[176])","30f4f396":"UTBTokenTest(uint256,string,string)","30f4f4bb":"getMarketData(bytes32)","30f56d21":"RoundEndTime()","30f59c1b":"lastTicketBought(uint256)","30f6716f":"HFCoin()","30f6eb16":"mintedForAccountInBlock(address,uint256)","30f75890":"MilestonesEntity()","30f7cf80":"stox()","30f7f148":"ONEPAY()","30f857f3":"addPrivateSaleWithMonthlyLockup(address,uint256[],uint256)","30fa27cc":"_BTC()","30fa9ef3":"SantimentWhiteList()","30faa3e9":"compareHands(uint8,uint8)","30fb641b":"PurchaseFailed(address,uint256,uint8)","30fb6bfb":"setMessage(uint16,string)","30fb7541":"_createSkull(uint256,uint256,uint256,uint256,address)","30fba22f":"changeManipulatorAddress(address,bool)","30fbe411":"endIco3()","30fd300f":"registerBytes32(address,bytes32)","30fd7696":"createLoveStoryWithData(bytes16,bytes32,bytes32,uint256,string)","30fe86b7":"declarePulicOfferingPlan(uint256,uint256)","30fee9b1":"setICOtime(uint256,uint256)","30ff2ad5":"needVerifiedAccount(bool)","31002556":"getAmountToGive(bytes,uint256)","310092b9":"REFUND_TIME()","3100ef7b":"Fulcrum()","3101170b":"addPixelPayable(uint256,uint256,uint256,uint256,uint256)","31014853":"buySWL()","3101ab7f":"confirmEjectment()","3102b21a":"setAllocation(address[],uint256[])","3102be4c":"ownerHistoryOf(uint256)","3102deb7":"SetPlayerBetInfo(uint8,address,uint256,uint8)","3103fa26":"firePaidProposalEvent(address,uint256)","310441fa":"payees(address)","31047973":"lightpool()","3104b21a":"unApprove(address,uint256)","3106aa80":"getLLV_edit_21()","3106fea0":"voteOnProposal(uint256,bool,uint256)","31076417":"setTokenUSDRate(uint256)","310774a3":"setContractPreICO(address,address)","310781e7":"LogCertificationDbRegistered(address)","310815ee":"setDesignatedReporterShowed(bool)","31085c5f":"getAddressByNickname(string)","31088032":"MTOKEN()","310883a8":"player2Timestamp()","3108bd87":"voteNoLockBatch(address[],uint256[])","3108f0d7":"isNotZero(uint256,string)","310b065b":"cerotest()","310bc5fc":"newAsset(uint256,uint256,uint256,bytes32,bytes32,uint256,bytes32)","310bd74b":"reset(uint256)","310c0c1e":"minRollUnder()","310c87cc":"NFTAddress()","310ce4e2":"execute(bytes32,address,int256)","310d3f69":"token_description()","310e5ce7":"isBreedingMarket()","310ec4a7":"setAllowance(address,uint256)","310efb48":"setResult(uint256,uint256)","310eff5d":"pageByGroup(string,uint256)","310f4cdd":"mint(uint256,string,uint256,uint256,address)","3110235a":"maxInvest()","311028af":"initialTotalSupply()","311104f3":"getMintRequestsLength()","31119b4d":"changeDeveloper(address)","3111dcfd":"_nextAmount(uint8,uint256,uint256,uint256,uint256,uint256)","311277c1":"PHASE3_RATE()","3112fb6e":"BackToLife()","311325bd":"totalPledgedFees()","31134651":"donateToLovers(bytes32)","311385f4":"oraclize_query(string,bytes[3],uint256)","3113b8fa":"initDebris(bytes32,uint256,uint8)","311515a3":"disableInterface(string)","311551ad":"_getCalculationStartDate(bytes32)","311551d7":"MasternodeMinedTokens(address,uint256)","31159923":"isAllocatedICO()","3115b4c4":"bulkStoreHeader(bytes,uint256)","3115c3ee":"exploreEMONTFee()","3115d2ce":"ZitKOIN()","31170c0e":"Joyso(address,address)","3117d6bb":"request(bytes32,string,string)","31184dc3":"get2(uint256)","3118879a":"removeSurvey(bytes32)","3118dc71":"aSites(uint256)","3119255c":"setMinBetPerTx(uint256)","31198d19":"transferEthFromContract(address,uint256)","311a6c56":"rule(uint256,uint256)","311a985f":"testNotEnoughMemory()","311b2e98":"totalBetsMade()","311bcda6":"stage1Sale()","311c2644":"ironTokensaleRunning()","311d5a2a":"recordBalance(address)","311fb64f":"countInvestorsRefunded()","3120cefa":"NickoinToken()","31212a6b":"unicornRanchAddress()","3121369d":"validateRequiredStackDepth(uint256)","3121c7c0":"buyMultiplier()","312212c1":"stoptransfer()","312220bc":"payoutQuickBonus(address)","312253ae":"newOption(uint256,uint256,bytes32,bytes32)","31225ad1":"icoThreshold3()","31226f71":"writeMerchandises(uint8,string)","3123016d":"calcCostLevel(int256,int256[],uint256)","31230e23":"createWithParent(bytes32,bytes32,bytes32)","31232cd3":"pre_amount_stages(uint256)","312386b7":"techDevelopmentEthWallet()","3123bd9d":"memberProfitShare()","3124167b":"_getTokenAmount(uint256,bool,address,address)","312452b3":"mLoadAndReturn(uint256)","3125443d":"secondChangeBlock()","31277306":"buyByEth(address,uint256)","31288397":"payWithoutChecksum(uint128,address)","3128d1be":"buyName(string)","312975a6":"setReservedHolder(address,address,address)","312983dc":"LogForkAnnounced(string,string,uint256)","3129be35":"calculateCoinsPerWeiAndUpdateAvailableIcoCoins(uint256)","3129e6d4":"RATE_SALESTAGE3()","3129e773":"getItem(uint256)","312ad4b9":"banThreshold()","312c0684":"Organicco()","312cba69":"EternalStorageProxyForPayinMultisender(address)","312dae8a":"changeCrowdsaleClosingTime(uint256)","312defb4":"INITIAL_ENDTIME()","312df321":"p_update_mRefPercent(uint256)","312f8b19":"blockedTime(uint256)","31302244":"approveAsInvestor(address,int256)","3130e89d":"EtherShot()","313138e1":"tuneLambo(uint256,uint256)","313186e7":"_calculateTotalLockedBalance(address)","3131d8de":"etherflipContract()","31324b0a":"IOXOwned()","3132605d":"DinoToken(uint256)","313354dc":"maxSellable()","3133f2a7":"outstandingBalance()","31347482":"CSELToken(uint256,string,string)","3134e2e1":"_setCollectRoundLength(uint256)","3134e9be":"verifyLinkPrivateKey(address,address,address,address,uint8,bytes32,bytes32)","3134f4f1":"SpecialRatedCrowdsale()","3135471d":"privateEtherFunded()","3135ed16":"race_start_block()","313602d4":"claimRemainingTokens()","31361399":"setICODate(uint256)","31363c86":"esteem(bytes32,string,address)","3136fa86":"NeuroProtect()","3136fbb8":"totalBaseLareSoldInMainSale()","31375242":"ownerSetTreasury(address)","31378811":"updateUserDetailsInBulk(address[],uint256[],uint256[],uint256[])","3137f3d4":"FhnwToken()","31380c89":"TokenSale()","3138d328":"gameMining(address,uint256)","3138d8d5":"Bid(uint256,address,uint256,uint256)","3138ee5c":"getPermittedContracts()","31391828":"_computeTournamentIncentiveReward(uint256,uint256)","31399b4d":"indexOfOperator(address)","3139c691":"_isInWhiteAddresses(address)","313a9204":"addPurchased(address,address,uint256)","313aaf96":"Double(bytes32,uint8)","313b7b19":"finance()","313c4093":"newExit(address,uint256)","313ce567":"decimals()","313dab20":"treasuryBalance()","313f5a57":"tradeAirswap(address,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","313f944f":"externalPurchase(address,uint256)","313fc3fc":"getMyRevenue(uint256)","314094c2":"devfee()","3140b09e":"distributeBonusTokens()","314312d3":"setEtherDeltaExecutor(address)","31434041":"burnSTCDR(uint256,uint256)","3143d97c":"setTimeLock(uint256,uint256)","3143fd60":"dev_allocation()","314475b2":"TokenEntity()","31447a32":"KeplerTokenCrowdsale(uint256,address,address)","3144c859":"executeCode(bytes)","31462b96":"the_nominal_annual_interest_rate()","3146a6bb":"transferTeam(address,uint256)","3146d282":"HyperTestToken()","31477b9b":"getString(bytes32,bytes32)","31483bdc":"PushToken()","314848fa":"CICoin()","3148ac62":"InitialRateChange(uint256)","3148f14f":"modExp(uint256,uint256,uint256)","3149694a":"burnHackingAmount(address,string)","314989b2":"SimplePHXSalesContract()","3149c440":"transferDomain(bytes8,string,address)","314a05db":"ownerRetrieveContractConfig2()","314a522e":"getTermsContractParameters(bytes32)","314aabb5":"EthDice50()","314cd12c":"createPromoToken(uint256,address)","314dd783":"GoldiamICO()","314e0fb6":"scheduleTransaction(address,bytes,uint256[3],uint256)","314e39c3":"trustContract(address)","314e99a2":"abdicate()","314ec2e5":"set_sale_owner(address,bool)","314ef8cb":"Besiktas()","31503ec4":"setFeeWalletAddress(address)","3150456e":"GenChipIndex(uint256,uint8,uint256[],uint256[],uint256[])","3150a7da":"HarvestedBabyBrain()","3150efbd":"beneficiaryMultisig()","31511e61":"getAffiliateCount()","31513039":"transferTokensFromAnyWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","3151609e":"setMetadata(uint256,bytes32)","3151ecfc":"myDividends()","3152dd00":"fundingActive()","31543cf4":"getTemplate(uint256)","3154d790":"rentByAtom(uint256,uint256)","3155625c":"setCleide(uint256)","3155c856":"getTotalF5()","3156560e":"setApprover(address)","31577cc0":"getModuleIDByAddress(address)","3157be49":"imageVerified()","3157d347":"nonVestedTokens(uint64)","31580446":"acceptDividends(uint256)","3158f643":"ico1Ended()","315a095d":"withdrawTokens(uint256)","315a0a09":"BasicForecasting(address,uint256,address,address,address)","315a6001":"purchaseUniqueSpinner(string)","315a6d65":"withdrawTeamToken(address)","315ad5ce":"resetGroupInfo(uint256)","315b86da":"MNPYToken()","315ccd21":"MAX_ETHER()","315d142d":"GayCoin()","315d758f":"_setERC20compatibility(bool)","315e2f1b":"setTestString(string)","315e3124":"pack(bytes4,address)","315e6c0a":"UpgradedContract(uint256,address,address)","315ebe81":"LockedOutTokens(address,address,uint256,uint8,uint256,uint256)","315f81c5":"useVaults(uint256,uint256)","315fd022":"MyToken(uint256,uint256,string,string)","315fdea3":"TreasureChest()","315fe684":"getMyPrize()","31601d09":"AuctionCreated(uint256,uint256,uint256,address)","31606828":"registrationDeposit()","3160d63b":"removeSupport(address)","31616395":"crowdsaleContract()","3162360d":"_emitBoardRatingGiven(address,uint256,uint8)","31629388":"setPendingValue(uint256,bytes32)","31638ced":"getDatasetByIndex(uint256)","3163b41a":"AdjustableRoundsManager(address)","31641629":"releaseSomeKims(uint256)","31649233":"allocatedTotal()","316524e5":"setGene(uint256,bytes)","31657926":"ticketsOf(address)","3165b26e":"transferOnBehalf(address,uint256,uint256,uint8,bytes32,bytes32)","31666144":"BTCproxy()","31666156":"latestReferenceBlockNumber()","3166e133":"Metropolis()","3166f49f":"balances_for_refund(address)","31670619":"GROWCHAIN()","31670ea7":"resetWithdrawEtherToValues()","31671a02":"TokenClaim(address,address,uint256,uint256)","31671f57":"Litecoinprivate()","31677980":"migrationCompleted()","3167e9d2":"infoUrl()","316866bf":"getRatingsForAddress(address)","316943cc":"transferExtOwnership(address)","31694d6f":"TEAM_TOKENS_SUPPLY()","3169ff3e":"LooneyLottery()","316a0131":"viewWinningOption()","316b08a0":"scheduleTransaction(address,bytes,uint256[7],uint256)","316b13b4":"setMemberContract(address)","316b8cab":"Oogroll()","316bc682":"setKYCLockupIgnoring(bool)","316cb1b4":"withdrawKittenCoins()","316db7f2":"updateInfo(uint256)","316e539e":"currentStanding()","316f2f06":"requestUnclaimed()","316fb7c4":"updateGoal(uint256)","316fda0f":"cycleCount()","317053f8":"setStringMember(string)","31707a05":"initOwner(address,address)","31711884":"tokenRate()","31711abe":"bookkeep(address,uint256,uint256)","31719c69":"lastPriceSetDate()","31723abd":"DMTokenC()","31729a45":"setCommission(address,uint256)","31748401":"_investorAddresses(uint256)","3174cc87":"refundToBuyersIfSoftCapNotReached()","31757f2e":"collisionCount()","3176bd18":"MyTestingToken()","3176d373":"updatePriceFci(uint256,uint256)","3176e734":"addHiddenPosition(uint32,bytes32)","3176f912":"getPlayersBattlePower(address,address)","3177029f":"approveAndCall(address,uint256)","3177b83a":"isCustomerHasACC(address)","317830b4":"crowdsalePaused()","31787b91":"maxIcoDuration()","31798893":"DistributedSoFar()","317a71ea":"_removePendingRequestId(uint32)","317ab6dc":"getChampsCount()","317b4b76":"setPreIcoMin(uint256)","317c00be":"maxTokensPerArticle()","317c0ae9":"tokensByZecTx(string)","317c1291":"isCrowdFundActive()","317d5d9b":"rand(uint32)","317d7a2b":"depositInfo(uint256)","317d9453":"getContractTokenBalance()","317ebc79":"scoreTeams(uint32[],int32[],uint32[])","317ec08b":"removeMaliciousValidator(address)","317ed7dc":"rebateTwoFenzi_()","317ffcf2":"getCreateUnicornPrice()","31806aaf":"unlockBalanceByKey(uint256,uint256)","318077a1":"Logo(address,address,string)","31809eac":"dayAfterInMinutes()","3182c3aa":"createSale(uint256,uint256,uint256,string,uint256)","31836cb9":"testMiddleTranch()","31839753":"getVolumeBonusAmount(uint256,uint256)","3183a55c":"Alchemy(uint256,uint256)","3183ef3d":"_release(address)","31845f7d":"setPublic(uint256)","31852177":"ConsToken()","31852a02":"allocate6ProjectToken()","31859556":"startPreico()","3185a61e":"getSellOrder(uint80)","31861423":"_deleteAllPackedRevisionTimestamps(bytes20)","3186f390":"tokensToPartner()","3187878b":"Follor()","31885119":"mintSelf()","3188949a":"DIT()","3188c5b1":"updateTotalChild(address,address)","3188da5f":"meltCoin(address,uint256)","3188ed13":"UNSOLD_ALLOCATION_SIZE()","3189418f":"connect_to_nodelist()","318992d0":"RewireToken()","318a3fee":"relayTx(bytes,int256,int256[],int256,int256)","318b526c":"AIGInvestment()","318cbe20":"BountyBG()","318dbcae":"releaseFundsBuyer()","318e6c78":"getAdminAddress(address,address)","318f0fe9":"acceptRequest(address,address)","318fd7e4":"HomeChainToken(address)","318fd93d":"registerSeller(string,string)","31906ebd":"airdropTotal(address)","3190abc0":"addCustomer(string,string)","3192164f":"idle()","31921cad":"headerColor()","319288d8":"setNVTface(address)","3192b995":"developer_crowdsale_text(string)","3192cccb":"queryTokenGrant(address)","31933916":"getMessageCount()","3193c749":"placeBet(uint256,uint256,uint256,int256)","31950032":"createContract(bytes32,uint16,bytes8,uint256,uint32,string,uint32,uint64[],bytes8[],uint32,bytes32)","319609fa":"EtherPiggyBank()","31970bd8":"nextRangeID()","31978b99":"changeBoardMetadata(bytes32,bytes32,string)","3197cbb6":"endTime()","31985b51":"sendGiftCard(address,address)","3198a38f":"findAllCliWithPendingTask(address)","3198acad":"Billionsgame()","319983f8":"FoundationSupply()","31999749":"getTimePeriodsUsed(uint256)","319a2494":"getBlockOf(address)","319a30d4":"setConfiguration(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","319a9395":"setGlobalLock(bool)","319ae4b2":"spaceCount()","319af333":"log(string,address)","319b0cd2":"calculateRate(uint256)","319b0e75":"getTotalInvested(address)","319c068c":"current_round()","319c33cc":"setOrganization(string)","319c7748":"_KiwiToken()","319dac48":"polishRoughStone(uint256)","319db3be":"advisorWallet()","319df3bf":"icoManager()","319f0852":"MSCTToken(uint256,string,string)","319f21b6":"placeGame(uint8,uint256,uint256,uint8,bytes32,bytes32)","319f3930":"mintFraCoins(uint256)","319f7700":"SealCrowdsale()","319f9887":"SnowdenAffect()","31a02bce":"requestMint(address,uint256)","31a06772":"scrap(uint256)","31a079ca":"ArtexToken()","31a2aba8":"create(address,uint256,uint256,address,address,address)","31a360b4":"LUVITOKEN()","31a36424":"getAllAdmin()","31a38c89":"executed()","31a3a506":"closeFunding()","31a3b36f":"blockDotTimestamp()","31a3b873":"ICO_MIN_CAP()","31a40b62":"delAuthorized(address)","31a51f46":"getTransactionConfirms(bytes32,uint256)","31a642db":"getTransferInfoValue(address,uint256)","31a73991":"GetUserIdByAddress(address)","31a76bca":"FOUNDERS_VESTING_CLIFF()","31a7d4c2":"LogPause(uint256,bool)","31a83ca2":"oraclize_randomDS_setCommitment(bytes32,bytes32)","31a8aeb3":"stakeFrom(address,uint256)","31a95c7a":"redeemTokens(address,address,uint256)","31a97ff0":"noteInitialReportingGasPrice()","31a9b2f2":"maximumPurchase()","31aa01c4":"contributed2(address)","31aa91fc":"completeContribution(address)","31aaa74a":"accountParent(address)","31ab4066":"testAuthorityTryAuth()","31ab6055":"TMCoin()","31abdd2a":"calculateEthValueFromTokens(uint256,uint256)","31ac7253":"releaseState3()","31ac76c7":"getSiteTokenLength(uint256)","31ad6b62":"sendToEthertoteDevelopmentWallet()","31ad836e":"Flabba()","31ae0019":"KissBTC()","31ae450b":"getAdmins()","31ae6b6e":"isFactProviderInWhitelist(address,address)","31af56ed":"transTo(address,address,uint256)","31afa55f":"decreaseMonsterExp(uint64,uint32)","31b0795c":"registerAddress(address,address)","31b259cf":"setUser(address,address,string,string,string,bytes32)","31b27c44":"DeusMarketplace(address,address)","31b28664":"PAGE_SIZE()","31b29629":"ownerAddBankroll()","31b2d49c":"cancelOrder(address,address[5],uint256[8],bytes32,uint8,bytes32,bytes32)","31b31b88":"setTokenFee(uint256)","31b36c45":"CHECKgamberTwo()","31b39a56":"addWalletConfig(uint256,uint256,uint256,uint256)","31b3eb94":"withdrawPayments(address)","31b4784e":"lastUpdateOverall()","31b48f86":"setPeriods(uint32,uint256)","31b57b46":"initialize(address,address,bytes32,address,int256,bytes32,address,int256,bytes32,uint256)","31b59508":"LDIT()","31b5da2a":"numMC()","31b61ece":"getAllLeftHand()","31b62fae":"GetCardInfo(uint32)","31b6421e":"Approve(uint256,bool)","31b77da4":"getEmptyIndex()","31b7a196":"emitGenericLog(string,string)","31b7c458":"claimedAirdropTokens()","31b8b100":"Static()","31b93ae6":"MIN_PRESALE2()","31b97e45":"addGame(bytes32,bytes32)","31b9d81d":"kscBatchTransferToEcosystem(address,address[],uint256[],uint256,uint256[],string)","31ba7ede":"create(address,bytes32,address,bytes32,bytes32,address,bytes32)","31baa8ae":"getCitizenCharacteristics(uint256)","31bab608":"getVersionSelectors(bytes32,bytes32,bytes32)","31bac434":"unpauseMint(uint256)","31bae156":"getPartialAmountRoundedUp(uint256,uint256,uint256)","31bbb695":"takeCapital()","31bcce1c":"CryptoAtoms()","31bcd2b7":"sendTokens(uint256,uint256)","31bd1fa5":"levAddress()","31be23e4":"getLotteriesLength()","31be6985":"testBitXorSuccess()","31be6a17":"addNewGroup(bytes32,uint256,uint256)","31beedd9":"setOWhitelist(address[])","31bf0667":"tokensaleWallet()","31bf0b42":"setSB(uint256,uint16)","31c0018b":"listApi(uint256,bytes32,bytes32,string,string)","31c05b8f":"getWalletAddress(bytes8)","31c15301":"maxRandom(uint256,address,uint8)","31c1eea4":"delCEx(address)","31c29c25":"newContribution(address,uint256)","31c2b6e6":"animator()","31c2bd0b":"propose(address,bytes,uint256)","31c33669":"GetChequeInfo(string)","31c359fa":"getReferralAddress()","31c3e2c9":"VotingProxy(address,address)","31c3e456":"update(string,string,string)","31c420d4":"unfreezeTransfers()","31c42ca6":"testSell()","31c571f5":"setLastStellar(address,uint256,uint256,uint256)","31c5e407":"PaymentSubmitted(address,bytes8,uint256)","31c5e56b":"init(address,uint256,uint256,uint256,uint256,uint256,uint8)","31c6c4cf":"transferFromWithReference(address,address,uint256,bytes32,string)","31c78498":"Metadollar()","31c89d3e":"FromQueue(address,address)","31c91117":"withdrawAllEther()","31c9472a":"constantname()","31ca0bae":"DAO(address,uint256)","31ca208c":"greylist(address)","31ca4340":"GetTokenData(uint256)","31ca6b67":"setWinnerManually(uint256)","31cb27d7":"processHandEndSplit(uint256,uint256)","31cba838":"BOUNTY_ADDRESS()","31cbf288":"createContract(string,address,address,string)","31cbf5e3":"pay(uint256,address)","31ce6b47":"getTicketCounter()","31cfcf84":"IDAGToken()","31d03594":"getOfferPrice(uint256)","31d1c995":"_batch1_icosaleStartTimestamp()","31d29af1":"getMyWallet(address)","31d2f891":"crowdsaleAddress()","31d31647":"hasSenderVoted(uint256)","31d3518a":"IvoryToken()","31d35cb2":"getDayEthIn(uint256)","31d36cf0":"relaySellerCancel(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32)","31d397ef":"initialWallet()","31d4116f":"nextsize()","31d41325":"isMonethaAddress(address)","31d42bf2":"addBlackAccount(address)","31d4ac45":"bookWithLif(uint256,uint256,bytes,string,uint256[],bytes32)","31d4ed2e":"_isUnderLimit()","31d4fad4":"refundPayment(uint256,address,string)","31d6183b":"tokensToEth(uint256,uint256)","31d67353":"transfer_data(address,uint256,string)","31d694a0":"NEBC()","31d78a50":"signedApproveAndCall(address,address,address,uint256,bytes,uint256,uint256,bytes,address)","31d87de2":"setRBACAddress(address)","31d90e04":"canClaimPayout()","31d98b3f":"getPrice(bytes32)","31d9931f":"setOwnedTokensIndex(uint256,uint256)","31daabb7":"updateOwner(uint256)","31db4b95":"doTriggerAuth()","31db6c48":"TYPE_EXPLORER()","31db9efd":"right88(uint256)","31dbd8a5":"feeAuthority()","31de13e8":"tBonusStageEnd()","31de7e72":"iceFund()","31deb7e1":"nodeCost()","31e12c20":"setowner()","31e19cfa":"getStrategyCount()","31e396c8":"calculateYourValue1(uint256)","31e3e2fe":"WithDraw()","31e41fba":"_localFight(uint32,uint32)","31e5144c":"isAvailable(uint32)","31e574a5":"addProduct(address,uint256,string,string)","31e5f055":"one_card()","31e63199":"codename()","31e6a707":"getWalletInfoByIndex(uint256)","31e7b060":"constructProof(bytes32,bytes32[],bytes1[])","31e7bf9d":"Multivest(address)","31e88fee":"claimedPartnerPreICO(address)","31e8c7ba":"CertID()","31e8ebbb":"DenToken()","31e92f32":"blocksPerMonth()","31e99e2b":"getCurrentSmartSpeedPrice()","31e9e9c0":"unlockToken(address,uint256)","31e9ea8a":"PlaceBet(address,uint256,uint256,bool)","31e9ee7c":"currentIcoWallet()","31ea1a39":"cancelDeal(uint256)","31eaa5c9":"erc20CTH()","31ebd13f":"logAllStart()","31ee080d":"setComisionInvesorInTokens(address,bool)","31ee8277":"_createship(uint256,address)","31ef107f":"SetProfitAddr(address)","31ef916a":"approve_timed(address,uint256,uint256)","31f01140":"getUserInfoById(uint256)","31f0528e":"updateNextGameMinAndMaxBlockUntilGameEnd(uint256,uint256)","31f070d9":"getSet()","31f09265":"withdraw(address,uint256,bytes)","31f0fca1":"_addTokenToTranche(address,bytes32,uint256)","31f170c2":"coinSupply()","31f1fd2b":"setCriterionTime(uint256)","31f25330":"initialRound()","31f27c96":"isWarriorChest(uint256)","31f2c8a5":"whitelistedSenderAddresses()","31f2d72d":"TelegaSend(address)","31f3af90":"removeAuditorFromMultiRequestAssignment(uint256,address)","31f4a23f":"EtherDeltaWithdrawToken(address,uint256)","31f4f682":"investmentMin()","31f53447":"operatorProductCommissionInPerc()","31f607a5":"Coin_Character()","31f6eac8":"availableVolumeEtherDelta(address,uint256,address,uint256,uint256,uint256,address,uint256)","31f72b44":"NewPhase(uint8)","31f76043":"resetSymbol(string)","31f850e6":"create(address,uint256,uint256,uint256,bool,string)","31f9a211":"getOrderState(uint128)","31f9a8f2":"accessToken(address,uint256)","31f9c919":"mintingActive()","31fa0a45":"withdrawAdamcoins()","31fa76db":"short_tokens(uint256)","31fa7c84":"cancelRent(uint256,uint256)","31fa8e73":"payrolls()","31fa90d8":"stopIssuingIndividualTokens()","31fb4c1d":"preIcoFinishTime()","31fb67c2":"withdraw(string)","31fc5b18":"MIN_BID_FRAC_TOP()","31fd725a":"PassHasBeenSet(bytes32)","31fdb712":"getFlight()","31fea236":"testFailTransferFromWhenStopped()","31ff1ed9":"linkDirectly(string,uint256,uint256)","31ffc9fa":"DentacoinTimeLock()","3200aa7a":"startRoundB()","32013ac3":"preallocate(address,uint256,uint256)","320228ca":"minimunEth()","32033229":"writeAddr()","32035ca6":"madeOperatorForTokens(address,address,address,uint256,bytes,bytes)","3203fe4b":"softcap1Reached()","3204dbc5":"distributeELTC(address[])","3205c5c1":"intunderflow(uint256)","3205f5fc":"division()","3206163f":"Drawcolor(uint256,address,uint256,uint256)","32064946":"start_buyer(address,address,uint32)","32064db7":"left20(uint256)","320665a6":"BCCB()","3206b2c6":"getLog(uint256)","3207230d":"purchaseVehicleSpace(address,uint256,uint256)","3207408f":"PrivateSaleCents()","32075c49":"buySCTK(address,uint256)","3207b544":"BRI()","32083c44":"payoutForWagerAndOutcome(uint256,uint8)","320878d5":"BFYToken()","32089b74":"LEGLToken(uint256)","32098d4c":"setCalculateFloatingValue(uint256)","3209943e":"proceedsAddress()","3209c6de":"iterate_start()","3209e9e6":"setMinimum(uint256)","320a352a":"ExposureCollected(bytes32,address,uint256)","320a5018":"MilestoneInput()","320a6c73":"transferFor_(address,address,uint256)","320a98fd":"lock(string)","320b2ad9":"_pause()","320bebaa":"setPromoMinPurchaseEth(uint256)","320cffcd":"getCostForCards(uint256,uint256,uint256)","320d2800":"finalizeSale(address,uint256)","320d2fa0":"liquidationThresholdPercent()","320d4534":"setMinSwapAmount(uint256)","320d46d4":"canRegister(address)","320dc63a":"TotalSTC(uint256,uint256)","320e028d":"setCountryToken(address)","320e6c01":"set_default_approval_duration(uint256)","320ea024":"isVerificator(address)","320fdc75":"one(uint256,uint256)","321022a5":"updateSettlementInstitution(address)","3210318e":"PotaosBucks()","3211bb90":"OwnerAddFunds()","32121896":"GDK()","32139a0e":"platformOperatorNeumarkRewardShare()","32145dd2":"gamePlayerNumber()","321489d4":"getDataByIndex(uint256)","3214e6ba":"cpow2(address,uint256)","3215b483":"getTokensByMerkleProof(bytes32[],address,uint256)","3216255b":"setCertificate(string,string,string,string,string,string,string)","3217e44e":"RGHTC()","3218b99d":"gameStart()","3218ebcc":"SUBMISSIONREWARD()","32191017":"updateFeeForCurrentStakingInterval()","3219ac2a":"showMyVote()","3219e73f":"addScore(string)","321a7c8c":"createVestingByDurationAndSplits(address,uint256,uint256,uint256,uint256)","321b3157":"firstPartOfTeamTokensClaimed()","321bbc1c":"test_insert_findWithHintNextUpdateHead(int256)","321c48f2":"getTemplate()","321cb98a":"creationMaxCap()","321db4d4":"getQueryAddress()","321de1d4":"BuyToken(address,uint256,string)","321f4584":"DataRegistered(bytes32)","321f63a2":"HMToken()","322062b8":"FixBet31()","3220ad89":"refundSuccessful(address,bytes32)","3220b95a":"getEscrowOrder_seller(uint256)","32214874":"verifyAmount(address,uint256,uint256,bool)","3221e125":"addBag(uint256)","32227425":"stopReceiveTicket(uint256)","3222ae71":"airdropFinished()","322370ff":"BetexStorage()","32246e9f":"auctionEnd(uint256)","322471cf":"createAffiliate(uint256,uint64,uint64,address,address)","32254992":"getPrevHash(int256)","32255d90":"confirmShipping(uint256)","32258794":"removeAddressesFromBlacklist(address[])","322671cd":"_checkLockUp(address)","32268c01":"artistsArtworks(address,uint256)","3226a94e":"TRNCoin()","3227563a":"logPriceAfter()","3227bd8b":"DragonCoin()","3228556f":"setPOOL_edit_8(string)","3228afcb":"HyperIslandCoin()","32293954":"LogTokenPreissued(address,uint256)","322a5e5f":"balanceContract()","322a7050":"addHospital(uint256,string)","322a8957":"teamTokenTimelock()","322b1bc0":"getarray_length()","322b8c7e":"dKERNEL_PANIC()","322e5021":"Penalty(address,uint256)","322eccdc":"withdraw_all_admin(address)","323046b1":"date()","32307c67":"LCASH()","323082d7":"Vote(string)","3230d486":"getHeroRequiredExpForLevelUp(uint256)","323162a9":"getDisputeParticipants(uint256)","3231a2b9":"voteSnapshotBalanceAutoBatch(address[],uint256[])","32326b44":"Invested(address,uint256,uint128)","3232f204":"SPAMed()","32331418":"ExchangeTokenToZWC(address,address,uint256)","3233b455":"appFundDeposit()","3233c686":"claimerDeposit()","3233c791":"nextlotnumber()","32347487":"forwardFundsToWallet()","32353fbd":"resumeAuction()","323560b5":"ZebraToken(uint256,string,uint8,string)","32363b47":"period1End()","32363e0a":"calculateMultiplierAfterBurn(uint256,uint256,uint256)","323661f6":"releaseLockedBalance()","32366ea5":"isOMITokenContract()","32366fb9":"makeTomatoes(address)","32369e38":"GetPlayerDynamicRatio(address,uint256)","32373e25":"CREATED_STAR4()","323772ee":"unlocktime()","3237d63c":"tgeLive()","32383a69":"WashCrowdsale()","3238c832":"updateDBZHeroDetails(uint256,string,address,address,uint256)","32395c2b":"addPayee(address,address,uint256)","3239825c":"edCoreContract()","3239d232":"weekProcessed(uint256)","323a5e0b":"deposits()","323a73d9":"generateId(uint256,uint256,uint256)","323a7acb":"Joyreum()","323aca70":"InterCryptoNode()","323b1b87":"FreezeTokenTransfers(address,bool)","323b2c26":"MAX_RELEASE_DATE()","323bc818":"_createTeam(string,string,uint256,address)","323be1c5":"canPause()","323bf0b8":"icoPhase2EndTime()","323c20fa":"tokenPtx()","323c59c4":"Common()","323cb59b":"uncooperativeClose(address,uint32,uint192)","323d5c68":"sendPer()","323dc51a":"MomoToken(address,uint256)","323ded4d":"_getLegendaryPlusRarity(uint32)","323df879":"MILLION_TOKENS()","323e71fd":"turnOffCanUpdateFrontWindowAdjustmentRatio()","323ea3f9":"photoText()","323efacd":"checkAndCallSafeTransfer(address,address,uint256,bytes)","323f6fe0":"VESTING_OFFSET()","323fe92c":"setPriceAttr(uint8,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","32414926":"CarTaxiToken(address)","32418558":"stakeTokensManually(address,uint256,uint256)","32424aa3":"_decimals()","324298ff":"ArrayDemo()","32434a2e":"register(address,string)","324365b1":"createCollectible(uint256,uint256,address,address)","3243c791":"distributeDividends(uint256)","32443d7d":"developmentFundUnlockTime()","324536eb":"totalSupply_()","3245a55f":"mintFull(address,uint256)","3246887d":"setLedger(address)","3246bac5":"getGameIpfs(uint256)","3247dd8b":"ySignToken()","32484dab":"totalContributedUnits()","3248687a":"getLockSize(address)","32492f96":"getStellarBalance()","32495c58":"requiredEntries()","3249759c":"TAToken()","324a5562":"setMaxNumber(uint8)","324ab080":"MIN_BONUS()","324b0085":"createBlogger()","324b8ad2":"totalBurnLotsByAddress(address)","324b8d6e":"oracleConfig()","324c6add":"KBV01()","324cb3cb":"contractLocked()","324cf51a":"setPurchaseParamCount(uint256)","324da66f":"removePromoCode(bytes32)","324dd3b0":"getFighterArray(uint256[])","324ecd96":"power10(uint256)","3250e151":"PakEKO()","32513ce5":"newContractAddr()","32519e0e":"roundEth()","32525f09":"testTransferFromDoesNotAllowTransferOfMoreThanAllowedByDelegate()","325294e5":"calculateEthers(uint256)","3252b8fb":"returnGrantedToken(uint256)","3253277c":"badge(address,uint256)","3253ccdf":"burnNomins(uint256)","32546f7e":"HammerChain()","3254de48":"ITSEndTime()","32555f06":"dissBlock(uint256)","325586dc":"checkStateProof(bytes,uint256,bytes,bytes)","32564d82":"identifierToIndex(bytes32)","325654ae":"secondPrivateLockTime()","3257bd32":"getDepositorMultiplier(address)","3257d818":"hasResponded(bytes32)","32581fb0":"getArtefactById(uint256)","3258e255":"setWithdrawBeforeTime(uint256)","325a19f1":"created()","325ab9ac":"buildCharging()","325ad39b":"UltraNote()","325add98":"sellDaiForEth(uint256,uint256)","325c25a2":"auctionLength()","325c35c5":"setFightsAddress(address)","325cf9e6":"splitPayment()","325da1c0":"LogAllocateTicket(uint256,address,string)","325dfddf":"waittokens()","325ecf99":"addMarketingToken(uint256,uint128)","325f33e0":"checkUserByWallet()","325f9f41":"processShares(uint256)","32606387":"_draw3()","32608243":"Iou()","3260db59":"UnityToken(address,uint256)","32611e2b":"stage2_start()","32615457":"FullAssetRegistry()","32617353":"GoldBlockTickets()","32619375":"ChangeMiningReward(uint256)","3262207c":"isTransferProxy(uint32,address)","32624053":"blocksToWaitShort()","32624114":"isValidAccessMessage(address,uint8,bytes32,bytes32)","3262fd9a":"getMoney(uint256)","326360fe":"uncommittedTokenBalance()","32643513":"_computeContendersTotalHp(uint256,uint256,uint256,uint256,uint256,uint256)","32644829":"removePlayerFromBoard(bytes32,bytes32)","3264a34b":"getBoard()","3264a844":"hundredtimes()","3265bf5b":"registerPlayerToBoard(uint256)","3265c436":"btcsAddress()","32665ffb":"getProperty(uint256)","32666a31":"setMonsterObj(uint64,string,uint32,uint32,uint32)","326687b9":"onSale()","3266c856":"WanToken(address,uint256,uint256)","3266fb05":"lockedTime(address)","32670d10":"contributors_locked(address)","3267a2c5":"returnedToOwners()","3267db34":"setCurrentBadge(bytes32)","3268215c":"getPuppyAttributes(uint256)","3268419f":"PreSale(uint256,uint256,address,address,uint256)","32691d18":"updateLastTransactionTime(address)","326959cc":"MMMToken()","32696a92":"totalpatient()","326a794d":"safeMathSub(uint256,uint256)","326a7d77":"LEVEL_MAX_VALUE()","326abfce":"curent_mul()","326b0c7e":"BuyPresalePackage(uint8,address)","326b1001":"crowdSaleHardCap()","326b7a14":"WthdrawTo(address,uint256)","326cf61c":"toBytes(bytes32)","326dd62d":"migrationStartedTime()","326e8d60":"getTurnover(bytes32)","326fac6e":"getCurrentGames()","326fd584":"maxEtherCap()","32708966":"setMonsterIndexToApproved(uint256,address)","3270f753":"depositHouseTakeout()","327107f7":"targetToken()","32715bf2":"userContentByIndex(uint256)","32716063":"calcTotalFee(uint256,bool)","3272b28c":"allowedSenders()","32733a08":"balanceB()","32736fb0":"RoundsManager(address)","3273b110":"setMinDuration(uint32)","327419b7":"NeedsCoin()","327428b1":"Lockable(uint256)","32750350":"setcardaddress(address,address,uint256)","3276249f":"vrcWallet()","327683bb":"setIII_R3(uint256)","3276eaa9":"incrementContinuityNumber(uint32,int256)","32773ba3":"challengeExit(uint256,uint256,bytes,bytes,bytes,bytes)","3277bbda":"setUintF1IntF3AddressF3(uint256,int256,address)","32780d05":"closeChannel(bytes32,uint256,address,uint256,address,uint256,bytes32,bytes32,bytes,bytes)","3278ba2f":"getNumBounties()","3278c960":"terminateSelfDestruct()","3278dc67":"Founder()","327942a2":"move(bytes32,uint256)","32794823":"withdrawToOwnerCheck()","32797f44":"failedTimestampSecondsAt(uint16)","327a765a":"_getString(address,bytes32)","327a943a":"getUserAmount(address)","327b95b5":"USDXCoin()","327c0dd9":"resetLotteryManually()","327cc732":"registrantIndex(address)","327e36dc":"RefundVault(address,address[])","327efb0c":"supplylimitset()","327f0b6b":"pollTitle(uint256)","327fc33c":"isUpcoin()","32807be0":"PrymexPreICOCrowdsale(uint256,uint256,uint256,address)","3280922b":"TOKENS_SALE()","3280a836":"getPayment(uint256)","328175cd":"editorSignUp(address)","3281c4e1":"salesAllocation()","3281c4fa":"upRound(uint256,address,uint256,uint256,bool,uint256,uint256,uint256,uint256,uint256,uint256)","3281d576":"isContractMiniGame()","32820d5f":"setupWeiCaps(uint256,uint256)","328243d5":"changeSale(uint256,uint256,uint256,uint256)","32828d9e":"BbbToken(uint256,string,uint8,string)","32829a23":"OpenBankAccount()","3282aa8a":"individualMaxCapWei()","32833d51":"power(uint256,uint256,uint32,uint32)","3283f641":"task()","32846270":"goldSaleLimit()","3284d75c":"sendRefTVs(address)","3284fd79":"issue(address,uint32)","32859392":"dividendDecreaseFactor()","3285ecde":"tokensMintedDuringPreICO()","3285f406":"GetWithdrawalFunds(address)","3286b611":"Generate(address,address,uint256,uint256)","3286fb75":"addressNotSet(address,address)","3287c399":"isSignedBy(bytes32,address,bytes)","3287d0dc":"ownerLocked()","3287d0f6":"switchReserve(address)","3287db4b":"lockFunds(uint256,uint256)","3288eb0b":"ChineseCookies()","32892177":"TOKEN_VERSION()","328929e0":"Offer(address,address,bytes32,uint256,uint256,uint128)","32895c2a":"ERH()","3289e004":"redeemPackage(uint256,address,uint256,bytes32[])","3289fba6":"getSanPrevOwner(uint256)","328a2c2d":"updateStartDate(uint256,uint256)","328a8cc4":"addRestaurant(address)","328b10d7":"vestingStarts()","328c0ec0":"endPreICOTime()","328d15f4":"_getCurrentWeek()","328d8f72":"setEnabled(bool)","328db985":"getPotCnt(string)","328ede54":"DAFZOToken(address,address,address,address)","32902924":"signSendDiamond(bytes32,string,string,address,string,bytes16,uint256)","3290bd90":"getInfoFromBidding(bytes,bytes32)","3290ce29":"purchaseTokens()","3290f515":"addInterest(uint256)","32911111":"getroundinfo(uint32)","3291b39a":"addReserve(address,uint32,bool)","32921690":"checkDepth(address,uint256)","3292b71f":"transferCrowdSale(bool)","3292cd37":"payWithDailyFreePoint()","32931fbb":"left1(uint256)","329350ea":"storeOwnership(address,address)","3293d007":"isValidDateTime(uint256,uint256,uint256,uint256,uint256,uint256)","329430ca":"teamAllocated()","32947122":"updAirDropTokenDestroy(bool)","32948515":"QLinkToken()","3294ab00":"withdrawBtc(bytes,uint256)","3294c2d7":"updateDocument(uint256,uint256)","32958fcb":"boolToBytes32(bool)","3295feb3":"numAuthorities()","32967ea0":"isOlderOwner(address,address)","3296a373":"createPromoPerson(uint256,address,uint256)","3297ef5b":"voting_started()","32985244":"joyTokenContract()","3298caa3":"getDoneRegistrationAmount(address)","3298e6c8":"GanaPublicSale(address,address,address)","32990ad2":"rewardTokensForClient(address,uint256)","3299ad23":"PapushaToken()","329a23b8":"Wallet(address[])","329a27e7":"getWalletBalance()","329a88d5":"UBIATARPLAY_CAP()","329b1c92":"getReferral()","329b59d1":"fallback(uint256)","329b8f38":"yesCount(uint256)","329bfc33":"getCurrentWinner()","329c095b":"getLatestReading(string)","329ccce1":"vmaxEtherPerPurchase()","329cd958":"get_next_item_in_state_from_item(bytes32,bytes32)","329ce1b7":"delOwner(address,address)","329ce29e":"buyTile(uint256)","329d1a35":"testReentracyGuard()","329d1a8b":"depositIndex(uint256)","329d3346":"closeVote()","329d5f0f":"setApprovedUser(address)","329da011":"addNewToken(string,address,address)","329daf90":"onlyPauserMock()","329eac15":"phase2Price()","329f36b5":"BONUS_TIER_2_LIMIT()","329f5b21":"DiatomAirdrop(address,address)","32a16f4e":"isLocked(bytes32)","32a21a28":"registerInvitor(address,address)","32a2c5d0":"getContractAddress()","32a2fda7":"isPermissionGranted(address,string)","32a36e53":"enterRound(bool)","32a3869a":"getBonusPercentage(uint256)","32a3abbb":"LALATokenAddress()","32a42882":"buyPropertyInPXL(uint16,uint256)","32a45ac5":"addMessage(address,uint256,uint256)","32a521c1":"disallowToLock(address,address)","32a52fcd":"FOR_ICO()","32a54712":"DecalinxCoin()","32a55bb4":"swapActivity()","32a58dc2":"change_client_manager(address)","32a6baf6":"isTimePassed()","32a71b36":"AleaCoin()","32a7ae95":"deleteClaim(address)","32a7d7c2":"AddressOwnershipVerification()","32a7e45a":"eosBlanceOf()","32a80329":"getTokenTransferable()","32a8589a":"FercCoin()","32a89e50":"NextBabyIs(address,uint256)","32a8bb33":"getParticipantIds(string,uint256,uint256)","32a8d49e":"ADV_TEAM_TOKENS()","32a8e74c":"participateBuyback()","32a92229":"creditBalanceOf(address)","32a9df46":"setSecondBonus(uint256)","32aa952f":"UpdateSellAgentCreators(address,address)","32aae34d":"LogVoteToFreeze(address,uint256,uint8,bool)","32aaf9d7":"addCommissionAmount(uint256,address)","32ab6af0":"newRepoWithVersion(string,address,uint16[3],address,bytes)","32aba656":"stillAvailable()","32abff8e":"lastBlock_v5Hash_uint256()","32ac752b":"matches(string)","32ace499":"getNextOrderPrice(address,address,uint256)","32aeaddf":"lockingPeriodInMonths()","32af5858":"behalfBet(address,uint256,uint256)","32afa2f9":"claimEtherOwner(uint256)","32b12eac":"setFallback(address)","32b182c3":"eligible(address,uint256)","32b1ad5a":"checkContructIsLocked()","32b28b95":"edoPerWeiDecimals_()","32b30b64":"calculateUnsoldTokens()","32b3c323":"anyoneEndICO()","32b431da":"setPlanetAuctionAddress(address)","32b45055":"EREEBERRY()","32b4623a":"shareCertificate(string,string,string,address,address,string)","32b4b5ed":"openProvider(bool,string,string,uint256,string,uint8,bool,address)","32b4d74c":"getNumRemainingSeats()","32b525bb":"beginMotion(address)","32b5b2d1":"missedVerificationSlashAmount()","32b65a95":"getSplitCount(string)","32b680d6":"payReceiver(address)","32b693b0":"PetCoin()","32b6f97a":"UXDToken()","32b7214e":"setNextSnapshotTime(uint256)","32b734b7":"awardsEnd()","32b85a44":"currentWeight()","32b8c086":"testSuperUser(address)","32b98616":"updateCardDetail(uint256,uint256,bytes32)","32ba36d6":"EtherShare()","32ba4b8b":"RANGEEND_5()","32ba65aa":"clearBalance(address)","32baa8d9":"existingCategory(uint256)","32bafb2c":"withdrawMln(address,uint256)","32bb2c0d":"calc(uint256,uint256)","32bbb8cc":"mgrVotes(uint256)","32bbc1c8":"WEI_PER_USD()","32bc873d":"AZExchange(address,address,address,uint256,uint256,uint256)","32bc934c":"MILLION()","32bd8644":"MPYRefund(address,uint256)","32be9502":"getOwnerInAnyPlatformById(uint256)","32bf1def":"FACTOR_2()","32bf775d":"testControlTransferDisabled()","32bf9e5b":"AfricacoinToken()","32bfaa23":"initializeRefundableFundraiser(uint256)","32bfdc38":"ROC()","32c0c583":"setDenyPremium(bytes32,bool)","32c0f801":"tokenFacebook()","32c0fba5":"airDrop(address,address,uint256)","32c1eb82":"getActualRate()","32c22154":"livepeerToken()","32c26957":"isTimeout()","32c2ed9a":"inquire(uint256,uint256)","32c35352":"marketSale(uint256,string,address,address)","32c3de5d":"listCreatedTokens()","32c442d6":"Super87Coin()","32c468fa":"setPreFundingStartTime(uint256)","32c4903d":"getAllParents(bytes32)","32c514d5":"getJobDetailsIPFSHash(uint256)","32c66a9d":"Nome_vincitore()","32c6f294":"deadline120()","32c6f315":"exchangeIsRunning()","32c716b6":"dividendsAcc(address)","32c7de60":"_RamenCoin()","32c862ed":"inSalePeriod()","32c896d4":"REFERRAL_BONUS_LEVEL4()","32c9635b":"_getEthUsdPrice()","32c990b4":"getUserKeys(address)","32ca5587":"isWoidRegistred(address)","32ca966e":"toTileId(int32,int32)","32cae0a8":"userPoolFund()","32cb46e0":"totalContributedWei()","32cb6b0c":"MAX_SUPPLY()","32cb93d9":"getPaintingName(uint256)","32cc0105":"setAmountForDeal(uint256)","32cc6a9f":"modifyNextCap(uint256,uint256)","32cce1e4":"_unlockTokenByIndex(uint256)","32cd0487":"delist(address[])","32cd0b3d":"totalRemainSupply()","32cd3148":"CashmoneyToken()","32cd724a":"getStateStartTime(bytes32)","32ce92cb":"setFIRST_STEP_MULTIPLIER(uint16)","32cea83e":"birth(bytes)","32cee2eb":"getMinableSupply()","32cfbe90":"initialBalance(address)","32d05a53":"IdToAdress(uint256)","32d05c6d":"withdrawXPA(uint256,address)","32d17917":"SPECIALIST_THREE()","32d1ae2e":"RepairCenter(address,address)","32d2e55c":"subSafe(uint256,uint256)","32d2fb9f":"getRefRemainingTime(uint256)","32d33cd0":"isRedeemed(uint256)","32d3725b":"burnStage(uint256)","32d3b711":"getPI_edit_29()","32d540af":"_clearExtraReceivers()","32d5fe98":"revealCampaign(uint256,uint256)","32d68fd5":"transferFeeNum()","32d69342":"terminateServer(uint256,uint8)","32d6eeb5":"changeQueryDelay(uint256)","32d72694":"updateGameTimes(uint256,uint8)","32d79689":"currentNiceGuyIdx()","32d80490":"Dandy()","32d8a3bd":"initCommunityReputation(address)","32d8eee5":"testFailSetNotUpdatableNotOwner()","32da1329":"setStartEndTime(uint256,uint256)","32da3fe3":"upgradeComponent(uint256,address,address)","32da57cf":"getTheStocksTokens()","32da7448":"amout()","32da7840":"isWhitelistAgent(address)","32dae2a5":"maxAmountICO()","32db8e2b":"MAX_RECEIVED_PER_PERIOD()","32dbc7d4":"NECPToken()","32dbeb21":"GoalMinimumReached(address,uint256,uint256)","32dc04aa":"changeBlockTimeAverage(uint256)","32dc2a01":"setmsgprcnt(uint256)","32dc9e81":"functionFive(uint256,uint256,uint256,uint256)","32dcb01c":"createBytes32s(bytes32[],bytes32[])","32dea130":"finishCrowdsaleMinting()","32deac1b":"setThirdBonusPercent(uint256)","32df3068":"clearKeys(uint256)","32df52aa":"LigmaToken()","32e07a20":"howManyEthersToKillContract()","32e12734":"addSpecialOffer(address,uint8)","32e1ed24":"updateAccountOwner(bytes32)","32e26d24":"CROWD_WAVE1_BONUS()","32e30e84":"INTERFACE()","32e43a11":"dummy()","32e43b5b":"PlayerTransported(uint256,address,uint256,uint256)","32e459b4":"LogFinalized(uint256)","32e45b8b":"guessTotalBeanOf(uint256)","32e54f72":"proxyPayable(address,string,string)","32e5535a":"ticketString(uint256)","32e5645d":"_computeNextArtworkPrice()","32e5905b":"film()","32e5d676":"c_priceRiseTokenAmount()","32e5e595":"getTimestamp(string)","32e62358":"_platformSupply()","32e70029":"MGCGameToken()","32e7179a":"MintedLocked(address,uint256)","32e7c5bf":"B()","32e7ecd8":"tierMin(uint256)","32e7f81f":"allocateLiquid(address,uint256)","32e94e81":"setPlayerEngineersCount(address,uint256,uint256)","32e991cf":"sellScale()","32e99708":"getMiningTarget()","32eb2314":"OraclizeQueryTest()","32eb2564":"initGame()","32eb5e44":"getaddtime(address)","32ec39a4":"mntpMigrationsCount()","32ec7a4e":"_emitDayLimitChanged(bytes32,uint256,uint256)","32ec991c":"ballotOf(uint256,address)","32ed3d60":"startPoll(uint256,uint256,uint256)","32ef78c4":"remove_scribe(address)","32ef8dfa":"previousDistribution()","32f04209":"evReleaseFund(address,uint256)","32f05fd1":"releaseAndUnlock(address,uint256)","32f07d01":"LogRedeemNET(address,uint256,bytes32)","32f16c74":"claimPepe()","32f2129a":"getBetArr()","32f23601":"setSubTourFreezingPrice(uint256)","32f289cf":"claimToken(address)","32f2bb50":"HouseInfoListing(address)","32f402c5":"createGrant(address,uint256,uint256,bool,bool)","32f46374":"create(string,address[],address,address)","32f58fc8":"retrieveRemainingCoinsPostSale()","32f5ea27":"UbiRewardToken()","32f637db":"createVesting(address,address,uint256,uint256,uint256,uint256)","32f6438b":"setCFO(address,bool)","32f72c27":"remove(int256)","32f72e39":"setSubmissionDeposit(uint256)","32f7470b":"DATE_31_DEC_2018()","32f76c11":"didTradePosition(bytes32,address,address,uint256,uint256)","32f7b41b":"setCCH_edit_29(string)","32f8290c":"returnMachine()","32f896af":"getSettingIdByTAOName(address,string)","32f8d1e4":"RockCoin()","32f8db38":"mainSaleMinEth()","32f8e034":"finalizeIcoDate()","32fac3a3":"listAddresses(bool,bool,bool,bool,address[])","32fb082f":"hasOrderedRobotParts(uint256[])","32fb5833":"AutomatedExchange()","32fbe8d3":"setSavedBalance(uint256)","32fd8478":"artistCommission(uint256)","32fe334b":"totalEtherPaid()","32fe5afc":"setICOEthPrice(uint256)","32fefb4c":"add_account(address,address)","32ff6e21":"setAirDropToken(address)","32ffe442":"getExpectedPrice(address,address,uint256)","33007cdf":"deposit(address,uint152)","33012507":"addMemberInternal(address)","33016c6a":"FOUNDER_FUND_3()","3302363b":"_nextMonth1stDayTimestamp(uint256,uint256)","33026bb6":"addDeposit(address,uint256)","330278e0":"betPlaced(address,address,uint256,uint256)","3302ece0":"setStopDate(uint256)","33039d3d":"MAX_TOTAL_SUPPLY()","3305cf85":"weiToCap()","33065ac5":"firstTokenId(address)","330696c8":"PREMINER_CHANGED(address,address,address)","330738a3":"KetherHomepage(address,address)","3308ecf1":"coinanx()","3308f42d":"getPlayer()","33091bd2":"returnTokenBalance(address[2],uint256[7],uint8,bytes32[2])","33099beb":"theCyber()","330a4822":"_createOrder(address,uint256,uint256,uint256)","330aa207":"frozenAccountCoinByTime(address,uint256,uint256)","330ae38f":"disableAmbassadorPhase()","330ae7b3":"addUserBattleValue(address,uint256)","330c3fe5":"finalise(address)","330c4ce0":"burnedToken()","330ca427":"removeValidationPreSigned(address,bytes32,uint8,bytes32,bytes32,uint256)","330cbc75":"createEdition(uint256)","330d57f9":"maxbuyinQuantity()","330f412b":"MorphToken()","330f9588":"xrt()","330fb148":"setETHRateAgent(address,bool)","330fb4a3":"putEther()","330fd319":"MMTOKEN()","33102ff9":"openRoom(uint256,uint256)","33105218":"isVerifier(address)","331172f3":"getDisputeRoundDurationInSeconds()","33132860":"EcRecover(bytes32,bytes)","331350ee":"finishAllocation()","3313d27e":"verifyAllSigned(uint256,uint256[3],uint256[3],uint8[176])","3313d9bf":"bytesToString(bytes,bytes1)","3313e95d":"strcpy(string,uint256,string)","33140016":"feesByPeriod(address)","331450dc":"minerPreTime()","3314b33a":"BoardMeetings(uint256)","3314b62d":"AuPetitCoinToken()","3314c351":"Trade(address,uint256,address,uint256,address,address,uint256)","33158ba4":"openNetfRevenueRound(uint256)","331670c5":"getIsEnabled(uint256)","3316d122":"log(uint32,address,address,uint256,uint256,uint256)","331725b5":"callAndReward_0(string,string,uint256)","3317bbcc":"getLockedTokens()","3318d4a5":"incomeFees()","33195fca":"getApprobation(uint256,address,address)","3319bf1a":"upgradeGalleass(address)","331a6bf5":"setOwnerAddress(address)","331a72bb":"s7(bytes1)","331a72d1":"getRetractable(bytes32)","331a9d73":"availableSTCTokens()","331b6f66":"sizeOfAddress()","331c4594":"TalentICO()","331c55b4":"addTeamTimeMints(address,uint256,uint256,bool)","331c5d60":"LogSetName(string)","331d03d1":"BubToken(address)","331d8e5d":"unlock(address,address,bytes)","331e58a1":"adjustedRaised()","331e6b78":"setToNotForking()","331eac01":"SendPreReserved1()","331fbc1d":"tokensCreationMin()","331fef86":"bonusStrategy()","33210356":"setDelegadoDeDistrito(bytes32,uint256)","332129a7":"getJYPCBonus(uint256)","3321c76c":"RITUAL_COMPENSATION()","33223f1b":"materializeBalanceIfNeeded(address,uint256)","33228b9b":"E_AuctionFinished(address,uint256,address,uint256,uint256)","33232609":"blake2b(uint64[],uint64[],uint64)","33242b60":"getODEMClaim(address,bytes32)","332514d8":"totalT8EXSold_PRIVATE()","332559d3":"getcanuse(address)","33260fe7":"getInteractionPrice(address)","332659e0":"getBountyAddres()","33267961":"run2(uint256,bytes32[],uint256[],uint256,uint256,uint256,uint256)","3327057c":"Arina_judgment()","33271a3b":"getTokensPerWave(uint256)","33278aae":"setUntradeable()","3327f4fa":"setInstrumentRegistry(address)","33281815":"getRate(address,uint256,uint256)","33283e59":"usedReveralSupply()","33285fb4":"confirmAtkPlayerQuest(address)","33287446":"setMinTokensRequiredForMessage(uint256)","33289a46":"withdrawDeposit(uint256)","3328bd24":"lockAddress(address,uint256)","3328d3f0":"numberOfDates()","3328f396":"totalLevBlocks()","33291126":"_tavern(uint256)","332954c0":"YumeriumTeamWallet()","3329578b":"SpectrumNetwork()","33298e25":"invoke(uint256,uint256)","332a2219":"_goodAddress(address)","332ad859":"buyTokensBonus(uint256,uint256)","332ae26c":"test_insert_findNoHintUpdateHead()","332b0b34":"oraclize_randomDS_getSessionPubKeyHash()","332b3177":"totalTimelockedBeneficiaries()","332b9f06":"consumeNextOrderId()","332bb4c1":"approvalCallback(address,uint256,bytes)","332c26d6":"getSecretAtLevel(uint256)","332e1a81":"getContributors(bool,bool)","332e25be":"getCCH_edit_19()","332ea814":"amIAgent()","332ea9ed":"VRCoinCrowdsale(address)","332eb83e":"steal_reveal(address,uint256)","332ec5f9":"unblockMember(address)","332efa80":"clearNewOwnerBid(address,uint256)","332f7acf":"amountCollected()","332f7d6e":"Lpktransfer()","332f93a9":"nextPayoutGoal()","332fa285":"nextGameMaxBlock()","332fa5bb":"ownerCountInt()","332ff6f9":"Buyin(address,uint256,uint256,uint256)","3330a6bd":"set_min_max_CWCsPerReturn(uint256,uint256)","3331f391":"giftAsset(address,uint256)","33324445":"changeClientCategory(address,uint256)","3332baa3":"PreSaleDeadline()","3332f720":"transfer_remaining_funds_to_project()","333432fe":"_withdrawBonuses(bytes32,uint256)","3334f1f8":"getAmountWithBonus(uint256)","3335aa78":"eRefund(address,uint256,string)","33360632":"getNumParameters()","33360978":"EndTime()","3336d5e5":"addABaddress(address,address)","33377f32":"turnOnFurnace(bytes32,bytes32,bytes32,bytes32)","33379137":"transferCoinToUser(address,address,uint256)","333885a0":"createBill(address)","3339451b":"fireDeliveryProposalEvent(address,uint256)","33397816":"withdrawAccountBalance(address)","3339f96d":"floaksAddress()","333a653e":"PeakAssetCoin()","333ab570":"WeiSent(address,uint256)","333abd90":"acceptKinTokenOwnership()","333aed82":"nextGameSettings()","333bfec5":"delegatedSignedEscrow(bytes,address,address,address,uint256,uint256,uint256)","333cfa14":"checkBlockMature(uint256,uint256)","333dbda8":"paymentsInOtherCurrency(uint256,uint256)","333e1a72":"investorsLoses()","333e5180":"setOperatorPrivileges(uint256,address,bool)","333e99db":"isBlacklist(address)","333f55ed":"managerSelfRemove()","333f57b3":"contractStarted()","333f7f70":"changeFrozenStatus(address,address,bool)","33403a81":"_calculateWinner(uint256)","334191f7":"donatorReward()","3341b445":"proposals(address)","334249a7":"getProviderCountry(uint256)","334340d2":"EthCoin(address)","3343c18c":"AddBTCTransaction(address,uint256,uint256,bytes4)","334460a4":"createMetadata(bytes32,bytes32,bytes32,string,bytes32,bytes32,uint256)","3344e0b3":"WWW()","33455dd0":"PRICE_5()","3345854d":"NewGame(bytes32,bytes32,bytes32,address,uint256)","3345b65f":"listNextFourCards(uint128)","3345b784":"tokenSaleWeiMin()","33465c5f":"auctionStartTime(uint256)","3347d025":"teamUnlock3()","3348904b":"amountOfBets()","3348cad7":"_breedWith(uint40,uint40)","3348f537":"massClaimLimited(uint256,uint256)","33492138":"joinFraction(uint256,uint256,int16)","3349bc19":"nonActivationWithdrawal(address[2],uint256[7],uint8,bytes32[2])","334b8771":"AIRDROPBounce()","334b9f14":"initializeArray(uint256)","334c5997":"JavaSwapTest(uint256,string,string)","334cc3e5":"TimeDecayingTokenFactory(bool,address)","334d86bf":"getPI_edit_7()","334dc700":"CanaryV7Testnet()","334df120":"getBeneficiaryById(address,uint256)","334ef224":"testThrowsUpdateLatestRevisionNotOwner()","334ef43d":"tokensToCounter(uint256)","334f0611":"cnd()","334f22c7":"getUrl(bytes32)","334f45ec":"currentStepIndex()","334fe638":"getProvisionCreditsRemaining(address,uint32,uint256)","33500e26":"bid(uint8)","33506115":"setPauseSave()","335094c2":"setPreICOEnd(uint256)","3350ae36":"fitCollectedValueIntoRange(uint256)","3350b915":"setDungeonPreparationTime(uint256)","3350c3ba":"BlockEstateToken()","33512aa9":"getUserReward(address,bool,bool)","33513739":"lowerCeiling(uint256)","335154ed":"setRateSteps(uint256[],uint256[])","3351886e":"getFilm(uint256)","3351ee19":"donatePurchase(uint32)","33533e84":"NeterContract()","33545d48":"setIdentity(address,address,string)","3354741a":"eveFromEth(uint256,uint256)","335494a4":"getMintingPowerById(uint256)","3354d682":"destroyVoxel(uint8,uint8,uint8)","335611d9":"makeOrder(uint256,address,address,uint256,uint256)","3356294b":"setAyantDroitEconomique_Compte_3(uint256)","335665c4":"canBuyCompany(bytes32)","3357162b":"initialize(string,string,string,uint8,address,address,address,address)","335721b0":"NewResolver(bytes32,address)","33575f64":"buyRank(uint256)","3357db75":"SALE_ENDED()","33580959":"poolFees()","33588dfa":"doCalculateRoom(uint256,bytes32)","3358d2d3":"buildDSTokenFrontend()","33592a1f":"getProviderById(uint256)","335a6b7d":"Wicflight()","335aa61a":"setMaxPrizeOneDay(uint256)","335ae0cb":"GetEscrowBalance()","335b496e":"totalTransfersInSchedule()","335b52f2":"initGameAt()","335b61e8":"enableArea(string)","335b7c13":"phase5EndBlock()","335b942a":"arbitrateC4FContract(address,uint8)","335c8b63":"packPrice()","335d43a3":"Kubera()","335e8067":"tricklingSum()","335eb60f":"getCoursesLength()","335f463d":"DVChain(uint256,string,string)","335f5642":"getinfowin(address,uint256)","335f9303":"PunchToken()","335fba7e":"calculateRedeemReturn(uint256,uint256,uint32,uint256)","336077c3":"getApprovedBuyer(address,address)","3360ac90":"transferByOwner(uint256)","3360caa0":"publicSaleStart()","336120fe":"removeTokenList(address,uint32)","336137c8":"updateMember(address,uint256)","33613cbe":"getBondBalance(address)","33637d5a":"getPendingBlock(uint256)","33641775":"change_sale_address(address)","336481d4":"dSetCommunityBallotsEnabled(bytes32,bool)","3365aa3b":"description2()","3365d358":"addContractAddress(address,address)","336634bb":"MASIKIToken()","3366eeb2":"getLockedToken()","33670c1c":"SupportsInterfaceWithLookup()","33677c30":"recycling(address,uint256)","3367aeb2":"maxPVB()","33683ec6":"safeHolderOf(uint256)","3368a120":"dividendBalance()","3368db4f":"DCE_Coin()","3368e968":"init(bytes32[])","336989ae":"customers(address)","3369c33d":"pregnantDogs()","3369c3b6":"ReturnEthersFor(address,uint256)","3369dace":"flipTheCoinAndWin()","336abddc":"allocateCash()","336b739a":"setCovmanager(address)","336b9f80":"updatePublisherFee(address,uint16)","336c6d39":"setPrizePool(address)","336c9b97":"_updateEditionTypeLookupData(uint256,uint256)","336ce69e":"CyberyTokenSale()","336da059":"MAX_TOTAL_TOKEN_AMOUNT_OFFERED_TO_PUBLIC()","336e24aa":"getQuestionAnswerCount(uint256)","336fa72c":"addTransferableAddress(address)","3370204e":"enter(bytes8)","33705526":"p5()","337176cd":"getVideoGameItemOwner(uint256)","337188d9":"secSaleSpenderTxDetails(uint256)","33722c47":"testGetLawyerAtIndex()","33731c04":"plxToken()","3373739b":"usedTokens()","33739483":"etlContract()","33751fec":"WeatherToken()","33756534":"LogVote(address,bool,uint256)","33759ee1":"CrowdSaleTokenPurchase(address,address,uint256,uint256)","3375e38a":"CreatedBlock(uint256,uint256,uint256,address,bytes32,bytes32,bytes32,bytes32)","3376887a":"test_oneValidEqInt2()","3376e2dc":"callDividendAndUserRefund()","33771860":"setGoldContract(address)","337748b8":"StartFuseaNetworkDistribution()","3377f212":"set4RoundTime(uint256)","33783b9e":"PapaToken()","3378eb29":"ElectricQueue(address)","33791c36":"Fundraiser(address,address)","3379d7a3":"greedyowner()","337a693c":"AkiCoin(address)","337a8cdb":"allowMoveTokens()","337b1cf9":"setIpfsHash(bytes)","337b5988":"testSimpleNameRegister()","337b68ba":"takenProfit()","337bd656":"HashSolved(address,string,bytes32)","337c1e28":"getIndexRoot(bytes)","337c445d":"increaseWordSize(string)","337cc706":"transferContract(string,string,string,string,string)","337d2aea":"PHASE3_START_TIME()","337f4c46":"gameDeveloper()","3380104a":"Streamity()","3380c0d8":"cancelTransaction(uint256)","338116b0":"checkContract()","3381ffe0":"transferTrusteeOwnership(address)","338246e2":"minSwapAmount()","3382ac57":"customCreateTokens(address,uint256)","3382ddab":"tokenBurnAddress()","33833037":"allBalance()","33835161":"setConfig(uint256,uint256,uint256,uint256,uint256,uint256)","3383e335":"LogTake(bytes32,bytes32,address,address,address,address,uint128,uint128,uint64)","33840712":"checkImageInput(address[16],uint256,uint256,uint256[],bool,bool)","338410f2":"setUnicornBreeding(address)","33848008":"newDepositWallet(address)","33849e55":"voteOnSolution(uint256,uint256,bool)","3384d2af":"PARKToken()","3384e128":"soldSS()","33862708":"changeServiceAddress(address)","33862914":"SOYA()","33863ed9":"order(uint256,uint256)","3387e52f":"LLV_311_EDIT_3()","33882479":"multiplyDecimalRound(uint256,uint256)","3388e429":"ecrecoverDecode(bytes32,uint8,bytes32,bytes32)","3388fa72":"Duranium()","33893071":"checkMyWithdraw(address)","3389f273":"setManyAllocations(address[],uint256)","338a0261":"rhi()","338a1379":"_setPackedBlockNumber(bytes20,uint256)","338a63a4":"_createKitty(uint256,uint256,uint256,uint256,address)","338b5dea":"depositToken(address,uint256)","338bfcd6":"refundTokensPresale(address[])","338cdca1":"request()","338d43f6":"_decrementTokenBalance(uint16,uint16,uint8,address,uint256)","338dbf59":"startPrivateSale()","338dfafa":"HVNToken()","338e22ff":"ProcessablesMock()","338e4fd6":"setTokenForSale(uint256,uint256,bool)","338e579e":"tryFinalize()","338e93d1":"active_dividend(address)","338ed326":"createCustomCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256,address)","338ef191":"GetBetGamblers(uint256)","338f3039":"amountAvailableToWithdraw()","338f43a0":"getReservedTokensListValInTokens(address)","338f4ad6":"withdrawMineralTo(address,uint256)","338f4dd9":"limitTier2()","338ff5e3":"updateInvested(uint256)","33902973":"createReserveTokensVault()","33904cb1":"MasterNet(uint256,string,string)","33905d41":"highFunding()","3390e6c7":"getIsSecondPhaseBySoldedTokens()","33911763":"greenshoeActive()","3391c265":"transferManagment2(address)","33920f65":"getEarliestPosition(address)","33921b2c":"DEXHIGH_V1()","339282b7":"isRegisteredAuthority(address)","3392f927":"hasConverted(address)","3392ffc8":"testExp(int256,int256,uint256)","3393385f":"disableUpdates()","3393780f":"DdosMitigation()","3393b069":"nothingLib2()","3395dc70":"acceptTransfer(address,address,uint256)","33966cb6":"_bid(uint256,address,uint256)","33967c74":"isZero(bytes32,string)","3396c405":"tokensAreLiquid()","3396c780":"b21TeamTokensAddress()","3397ca17":"numBalanceRecords(address)","3397d5d5":"setTokenPrice(uint8)","33985caf":"Exera()","33989396":"requestNewEtherRealID(string,string,string)","339a7670":"mineToken(uint256)","339a95f6":"secondCrowdSaleEndDate()","339ab6f2":"getPurchaseAmount(address)","339ac174":"playerSurrender()","339b6b39":"isRevokedBefore(bytes32,uint256)","339cfb9a":"isHolderAddress(address,address)","339e23d1":"ownerVote(bytes32,uint256,address)","339e2604":"setPayBackRate(uint256)","339e2c45":"isRegisteredToFirm(string,address)","339e9550":"_sendReward(uint256)","339f890d":"setMinBlockPurchase(uint256)","339fd959":"getLockAmount(address,address)","339ff96d":"transferCommitment(address)","33a02a6d":"openLandEthSale()","33a02c22":"betAdded(uint256,uint256,address,uint256)","33a263e6":"peggedSymbol()","33a27f75":"estimateNextPotSeedAmount()","33a3b654":"managementAmount()","33a3d023":"finalizationCrowdsale()","33a3e669":"setClientLastPaidRate(address,uint8)","33a4ec8d":"NCMToken(uint256,string,string)","33a581cd":"createPeerWallet(address,address[],address[],uint256[])","33a581d2":"MAX_UINT256()","33a5ec7e":"changeTokenAmount(uint256)","33a7d2e3":"BONUS_DURATION_2()","33a8319e":"EtherJob()","33a87ade":"gasInTokens()","33a8c45a":"contact()","33a8dc1d":"nextPack(uint256)","33a9824a":"PopulStayToken()","33a99e04":"selectWinner()","33aac4aa":"BaseModule()","33ab0541":"setBaseLevelUpFee(uint256)","33ac2009":"countValidations()","33ac67c3":"ShowChargeCount(address)","33ac7256":"getParent(bytes32,uint256)","33ad9495":"WithdrawPotShare()","33adb264":"invokeTop()","33ae6e19":"distributeTimelockedTokens(address,uint256)","33ae7166":"tier4()","33ae88ad":"numberOfKingdoms()","33af060f":"accountInGoodStanding(bytes32)","33b0f7f7":"paidCreateWikiPage(string,string,string,uint256)","33b1503d":"PostWish(address,uint256,bytes,bytes,uint256,uint256)","33b16d93":"determineWinner()","33b186c1":"AdvisorsPartnersAmount()","33b19417":"NodeManager(address[])","33b1f812":"totalPromotions()","33b37915":"setOrderEnd()","33b3dc04":"castVote(string,uint8)","33b416db":"BaseICOToken(uint256)","33b56638":"testGetAllLawyers()","33b58484":"WEEKS_104()","33b5b62e":"minPurchase()","33b5fa75":"buyTokensWithRef(address)","33b6baf5":"developerAddr()","33b7d187":"getDCategory(bytes32,uint256)","33b85b73":"modifyCommunityRates(uint256,uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","33b8b1c1":"transferInt(address,address,uint256,bool)","33b8c29d":"updatePriceOfEth(uint256)","33b91db5":"GetTocPrice()","33b9d3f4":"_buyCoins(address,uint256)","33ba2ef9":"hipstermasterReq()","33bb70ee":"getCoinAge()","33bbae93":"end_date()","33bc1c5c":"publicSale()","33bc6283":"TruReputationToken()","33bd8036":"addressPayableFunc(address)","33bd943e":"abandonListingService(uint256)","33bebb77":"forceTransfer(address,address,uint256)","33bfaf4e":"MickeyToken()","33bffccc":"openPreSale()","33c023ef":"doInvestment(uint256,address,string,uint256,bool)","33c1420a":"raffle()","33c24bd3":"accountIds(uint256)","33c4a1d6":"SetScndOwner(address)","33c5da42":"setGaspriceMax(uint256)","33c6c1af":"setCentralAccount(address)","33c6cdd3":"modifyRatePlan(uint256,string,bytes32)","33c724ee":"setLosers()","33c74e79":"participantContribution(address)","33c77a6d":"pauseICO()","33c7b38f":"withdraw_to_eti()","33c7c026":"feePayment()","33c7d1cc":"restart(bool)","33c84990":"setNewClaimer(address,address)","33c8adce":"enterLeague(uint256[],uint256,bytes)","33c90632":"createTransferAuction(uint256,uint256,uint256,uint256)","33c91611":"safePay(uint256,uint256,address,bytes)","33c9b83c":"preIcoSoldTokens()","33c9ccf5":"isKeyOwner(bytes32,address)","33ca4773":"getBrandData(address)","33ca55d7":"requestTransferChildrenOwnership(address)","33caaa43":"tokenRewardContract()","33cbee23":"teamTwoDivsTotal()","33cc4f9f":"FIDAToken()","33cc9c3e":"getLuckyPendingSize()","33cd3383":"investmentsOf(address)","33cd7ede":"totalJackpotOdd()","33cdfc76":"accountOf()","33ce1cda":"JSJC()","33ce724a":"sendSoldTokens(address,uint256)","33ce7787":"transferInvestorAccount(address,address)","33ced321":"genLevelExp()","33cf3ca0":"icoDeadline()","33cf58f9":"Accepted()","33cfc5e3":"DEFToken()","33d020ae":"getManifestId(address,bytes32,bytes32)","33d072e2":"processFunds(address,uint256,uint256,bool)","33d0a56b":"Melt(address)","33d14097":"DoRollEvent(address,uint256,uint256,bool,bool,bool,bool,uint256,uint256,uint256)","33d1e5b9":"lockupAccount(address,address,uint256)","33d24dc4":"setTypeAdvantages()","33d2cea2":"getDiceWinAmount(uint256,uint256,uint256)","33d34bad":"nextlotnr()","33d52c71":"ico3Cap()","33d58ca6":"F2UToken()","33d59f0a":"setJobStatus(uint256,uint8)","33d5d29b":"containsOperator(address)","33d5e4ca":"LogErrorMsg(string)","33d634df":"getSpinResults(uint256,uint256,uint256,address)","33d63869":"icoReserveSupply()","33d64a6f":"Start_Resume_ICO()","33d6c065":"PenCrowdsale(uint256,address,address)","33d764a2":"transferPreSigned(bytes,address,uint256,uint256)","33d9529a":"Totalbalance(address[])","33d97457":"GRAPE_SECS_TO_GROW_VINE()","33da67a0":"setForceNsfw(uint16[],bool)","33daaa5e":"setMakerFeeRate(uint256)","33db82fd":"outToken()","33dd1b8a":"setAllowed(address,address,uint256)","33dd5fb8":"TransferAntique(bytes32,address,address)","33dddc3a":"openLootbox(address)","33de06d5":"changeEscapeHatchCaller(address)","33de61fb":"Marvin()","33de96c6":"cancelTransaction(address)","33decdc6":"returnVolAdjuster(uint256)","33df4155":"setSPARCAddress(address)","33dfc93c":"untokenizePosition(bytes32,address)","33dfe91d":"isDefValueInRange(uint8)","33e06ee7":"buyTokensAtRate(address,uint256)","33e11ec4":"getBcouponTransferCost()","33e13ecb":"Execution(uint256)","33e2df5c":"newTeamCreated(bytes32,bytes3,bytes3,bytes3,bytes3,bytes3,bytes3)","33e2df5d":"isTokenValid(string)","33e335a0":"fromPaymentGateway(address)","33e364cb":"resumeSale()","33e36c50":"FundsLoaded(uint256,address)","33e3e86a":"isValidSan(string)","33e5bce1":"allow_spend(address)","33e663a4":"BonusEarned(address,uint256)","33e665eb":"setMonsterAuctionAddress(address,address)","33e67012":"disableChain(uint256)","33e712fe":"functionEight()","33e747b3":"setCapAtWei(uint256)","33e7ed61":"submitPool(uint256)","33e7fb97":"modifyExecutorAddr(address)","33e85eac":"get_king_price()","33e8b084":"dePesoToken()","33e8b8ac":"setFounderAllocation(address,uint256)","33e8df7e":"get_property_address(uint256)","33e90f98":"migrateMntp(string)","33e9698c":"tokenIssueDeadline()","33ea3dc8":"getTransaction(uint256)","33ea7a2b":"setBundinha(string)","33ea80cb":"getProposalUint(int256,uint256)","33eb5564":"mid(uint256,uint256,uint256)","33eb647f":"ECNcoin()","33ee2297":"MintedGrey(address,uint256)","33eeb147":"isFrozen()","33ef5698":"setShareTradingEnabled(uint256,bool)","33f08327":"generate_paymentID(uint256)","33f1da25":"BiQToken(address,address,address,address)","33f1dfb5":"withdrawTokenByAdmin(address,uint256)","33f2da95":"test_insert_findWithHintNextUpdateTail(int256)","33f2e7f8":"takeOffer(uint256)","33f30a43":"getNarco(uint256)","33f3197e":"Bet(uint256,string)","33f327be":"FeemCoin()","33f3344c":"readQuantity(address,uint256)","33f35c40":"webdToken()","33f37304":"tTokens()","33f44026":"mintFoundingTeamTokens(address,uint256)","33f4406a":"addressCommunity()","33f472b9":"MPO()","33f50b1c":"extendICO()","33f707d1":"ownerWithdraw(uint256)","33f7c9fe":"UsersList()","33f8845d":"GetTotalRigCount()","33f88d22":"mintOwner(uint256)","33f8e8c7":"getUserTokenInfosLength()","33f9942b":"awardPoint(bytes32)","33f9b36f":"getIcoStartDate()","33fa59f0":"creationProfit()","33fb1e05":"withdrawChamp(uint256)","33fb9e35":"killSelf(uint256)","33fba1ed":"_getFightData(uint32)","33fbff32":"setSaler(address)","33fc56d9":"withdrawUnclaimed()","33fc5f47":"proposePurge(address,bytes32)","33fc6367":"updateRefundState()","33fcffa8":"Option(uint256,uint256,string,string,string,string,string,string,bytes32,address,string,address,uint256)","33fd066d":"doBalanceFor(address)","33fd40ec":"oraclize_query(string,bytes[4],uint256)","33fd9397":"buyBackPriceWei()","33fdb097":"BTSC()","33fdbbe5":"DECIMAL_FACTOR()","33ff588d":"ownerChangeRunning(bool)","3400a6dd":"crowdsale(uint256,uint256,uint256)","3400d00d":"PayTokens(address,uint256,uint256)","3401c277":"subtractAmount(address,uint256,uint256,uint256)","3402b841":"closeVoteCommitPhaseIfAllowed(address,bytes32,bytes32)","34032f4f":"teamSupply12Months()","3404ab6a":"calcEthersToTokens(uint256,uint8)","3405321d":"_setPrice(uint256,uint256)","34057a45":"rollAddress()","3405ae40":"setMaxSubscribers(uint256)","3405deed":"alwaysReverts(uint256)","34065b66":"getSmallBonus()","3406784d":"arbitrateC4FContract(uint8)","3406956a":"bountyTokenFund()","340695c0":"PRESALE_RATE()","3406e3fb":"singleTransGasCost()","340700e5":"Satochi4()","34075cbd":"proposalStatuses(uint256)","34083a28":"HoneyToken()","34085549":"buildAt(uint256,uint256,uint256)","340867a0":"setMiniPoolEdit_1(string)","3408f73a":"getStorage()","340955fc":"isNotDuplicateMembers(bytes32)","3409952b":"setStorageInterface(address)","340a247c":"getQueryCost(string)","340a773a":"LockedToken(uint256,string,string)","340adb29":"getExportingParty()","340dc485":"addEmailHash(uint256,address)","340ddda6":"MeatConversionCalculator(uint256,uint256)","340df28f":"finishUpgrade()","340e47f8":"activateStore(string,bool)","340e4fd5":"totalRequestsAmount()","340ea558":"isFavorEscrow(uint256,address)","340f4fea":"setBetExpirationBlocks(uint256)","340f5920":"winningTicketNumber(uint256)","340f5e4e":"get_all_num_levels()","340fef94":"MMMbCoinCrowdsale(uint256,uint256,uint256,address,address,address,address)","34100027":"withdrawLegalContingencyFunds()","34103ee4":"setCrowdsaleAgent(address)","3410452a":"getRequestsCount()","34106c89":"updateRenExTokens(address)","34107282":"signer1()","3410cbd5":"layersRec(uint256,uint256)","3410eb5b":"userRefundTo(address)","3410fe6e":"DIVISOR()","3411231c":"ANXToken()","341176d6":"crowdsaleManager()","34119d15":"setSellFeeBps(uint256)","3411c81c":"confirmations(uint256,address)","3411cb08":"getFreelanceAgent(address)","34122952":"build(uint256,int256,int256,uint8)","34127649":"JvaToken(address)","3412a15c":"testConnection()","3412a4ac":"setFundingEndTime(uint256)","34133df9":"TR()","341367ec":"getMaxCAP()","34140748":"_upgradeTo(address)","34145808":"totalRewardToken()","3415650e":"buyStatus()","3415bdd4":"buyAKeyWithDeposit(uint256,address,uint256)","3416f9d4":"subtractSafely(uint256,uint256)","34174331":"selfHybridization(uint256,uint256)","3417f8d3":"addHolder(address,uint256,uint256)","341855bf":"HappyBirthdayToken()","341881e6":"endPreIco()","34190567":"DebugInt(int256)","341912ad":"SOCIALXBOUNTY()","341b96c2":"WalletAddressChanged(address)","341b9cc2":"ValueToken(uint256,string,string)","341bcbc1":"endIco2()","341c3304":"presaleTokensSold()","341cc817":"preicobrandingWallet1Pct()","341ceb42":"updateAmountOfEachChoice(uint256,uint256)","341f13f2":"authorizeDeploy(address)","341f5ee2":"omsairam18()","341f6623":"toAddress(bytes32)","3422e048":"getFirstTokens()","3422ede1":"Vault(address,address,uint256,uint256,address,uint256)","3422f709":"totalSencCollected()","34231e72":"getMyTransferredWine()","342368e4":"SubFromDividends(uint256)","3423a768":"finalizePreICO(uint256)","342442bd":"lockTeamAndReserve()","342454c7":"isDigit(bytes1)","34247b9b":"changeDBAddress(address)","34253af5":"isICORunning()","34256ab2":"createQuote(uint256,bytes32,bytes32)","34265c48":"releaseTime(address)","34273351":"withdraw2(uint256)","34289460":"cleanupTo(address)","3428e7ba":"checkForNewDay()","342930aa":"peekHatch()","342b7e71":"setTokenList(address[])","342b88ba":"setIcoTier(uint256)","342ba8de":"getGen0IVs()","342bd327":"GenesisRewardPerBlock(address)","342c17cd":"finalReserveAllocation()","342ca5d6":"pricePointsLength()","342d9185":"pricePerTokenAtCurrentTier()","342d9a04":"challengeClearing(bytes32)","342e0260":"gettruelevel(address)","342e515c":"Electrium(uint256,string,uint8,string)","34302882":"ETY(address)","34302d82":"midTimeBonusLimit()","34306cb8":"placeMessage(string,bool)","34309e97":"tokensOwner()","3430f7b1":"TitleAdded(uint256,address,uint256,string,string,string,uint256)","3431024f":"disApproveUsers(address[])","3431a0be":"RegisterSeller(address,string,string,string,string)","3432000c":"kittiesContract()","343214ae":"isFundFreezePeriodEnded()","34334e9e":"removeBlacklistedUser(address)","34335c01":"getPresale2()","34354f93":"ABC()","3435dea2":"PoolJoined(uint8,uint8,uint256,uint256)","3435e5f3":"newChief(address,uint256)","3435ea80":"adduser(address,uint256)","34376542":"OwnerUpdate(address,address)","34376ca0":"authorizeBurner(address)","3438c758":"DelayedPayments(uint256,uint256,uint256)","34399ea8":"considerCurrentInterest()","3439b433":"RSPLT_E()","343a875d":"getUint8()","343a8d56":"Lucky888Token()","343aad82":"flow()","343ab4cd":"getMiningPoolAddres()","343ab68b":"getFreelancerContractsCount(address,address)","343bd7eb":"insertOwner(address)","343c018b":"GarudaToken()","343dbeb6":"isServiceRemoved(address,uint32)","343dfb7e":"referralPercent()","343efc6c":"WorthlessToken()","343f3acb":"GetAllBetIDs()","343f40a0":"testFailCreateSameItemId()","343ff8c7":"deductshares(uint256,address)","3440465e":"addElement(bytes32)","34406f33":"sha3Docs(bytes32)","344090f2":"Ownable1()","34409e38":"_generateNewSaddle(uint256,uint256,uint256,address)","3441ecf2":"Calculator()","34428440":"tokenExchangeRateMile1()","3442a868":"getBtcForkCoins()","3443c64a":"changeEEMWallet(address)","3444189b":"newKudosPoll(string,string,uint8,uint256,uint256,uint256)","34452f38":"disableMint()","3445679a":"USDto1ETH()","34457cbe":"ExponentialDecayingTokenFunction()","344605f4":"ETFloorPresale(address)","344615ab":"unSell()","3446bac4":"retirarDividendos()","34475d8d":"getERC721Addrs(uint256)","3447a7ef":"addInWhiteList(address)","3448348d":"getEventSize()","34484b47":"functionSix()","34486434":"ConsentFactory()","3448c7d6":"createHistory(bytes,address,address)","3448ec4a":"checkMatchBatch(address,uint256[16])","344929e4":"CTS(uint256,string,string)","3449387b":"GetFileLocation(bytes32)","3449f61c":"_getBonus(uint256,uint256)","344b8386":"firstYearPeriods()","344bcc7d":"signedTransferFrom(address,address,address,uint256,uint256,uint256,bytes,address)","344bcd7d":"allCrowdSaleTokens()","344c0dd5":"newChamp(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool,address)","344c5ea1":"Mino()","344c5fd6":"firstPeriodOfICO()","344cc2b8":"getAllBidsByAdunit(uint256)","344d1ef2":"getCarSelling(uint32)","344d9576":"ReinvestWallet()","344e23cf":"previligedBalanceOf(address)","344eca75":"amountRaisedICO()","345006b6":"getGenerationForCall(address)","34501134":"get_pre_kyc_bonus_denominator(address)","34516038":"getSellCount()","34523cbc":"numberOfWhitelists()","3452f51d":"push(address,uint128)","345393f0":"getOuLianPublicAddress()","34552a0a":"RegisteredContract(string,address)","34553a44":"getRequiredSubscribers()","34556035":"icoCompleteB()","345591ec":"inDistributionMode()","345607ab":"StoreProofOfUplinePaid(address,address,address,address,address,address,address,uint256)","34574ff3":"XFMSold()","345899fe":"addRoles(bytes32[],address,address)","34592491":"infoWithdraw2()","345942c8":"revealBet(address,string)","3459b1af":"SaleNew()","3459d2ba":"getTilePriceAuction()","3459fb6f":"unpack_data_groups(int256[],bool)","345a1ae4":"LASTTRIAL123()","345a3899":"Insurence()","345a4423":"win(uint8)","345a5fe4":"addRecoveryAddress(address,uint8)","345a8e5b":"uint2bytes(uint256)","345ac602":"fixAmount()","345b256a":"projectStorageVault()","345b3d3a":"newOrder(address,address,string,string,uint256,uint256,uint256)","345bc544":"maxAllowedBetInTokens()","345c8fca":"setFreezeTx(address)","345cad7e":"useItem(address,uint256,uint256)","345d116f":"LotteryRoundWinner(address,bytes4)","345da007":"setClassName(uint8,string)","345e2f91":"transferEarningsToOwner()","345e3416":"adminRetrieveDonations()","345efa4e":"CurrenseeCrowdsale(uint256,address,address)","345f342e":"concludeVoting(uint256)","345f58b2":"AcceessoryWrapper721()","34610182":"getFuelsIds()","34615bef":"_discipleVendPrice(uint256,uint256)","3461a5e8":"ARCO()","346223f5":"Cocoon(address[],address,address)","3462f32d":"execWithGasLimit(bytes32,bytes32,uint256,uint256)","3463934b":"Bqt_Token()","3463c5c7":"patentValidTime()","3463d76d":"databaseDownloadUrl()","34646163":"getDataset(address,uint256)","3464af6a":"testCopyAddress(address)","3464e4da":"grantTokensCommonPool(address,uint256)","3465d6d5":"record(address)","346692b7":"tokenKeys(uint256)","3466f07f":"DRAKE()","34686b73":"numberOfAddress()","346896c0":"getMinerLv1(address)","3468b4a8":"OxTokenInitialized(address)","3469a55b":"getDepositID(address)","3469acbb":"initCard2()","3469f6e2":"finalizeRound(uint256)","346a2f9e":"percentBank()","346a37d2":"markComplete(bytes32)","346b306a":"oraclize_query(string,string,string)","346b783c":"refundToPlayer(address)","346b7939":"icoReservedSupply()","346bfd9f":"eventBurn(address,uint256)","346c1aac":"getNextAvailableBond()","346c95df":"SuNFT()","346c96e9":"addFund(uint256)","346cabbc":"scheduleCall(address,bytes4,uint256,bytes,uint256)","346cf356":"tradeCards(address,uint256)","346e8cea":"allCarsInfo()","346f2eb7":"set_bonus_received(bool)","346f5991":"sendTokensToTeamLock(address)","346f8827":"addWineryOperation(bytes32,address,string,string,string,uint256,uint16,string)","346f9f95":"collectAddr()","346fc0dd":"maxCrowdsaleSupplyInWholeTokens()","346ff6b3":"getNumRounds()","346ffa4b":"changeValues1(bool,bool,bool,bool,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","34701db8":"totalTicketsSold()","34705c2f":"validateTransferAmount(address,uint256)","3470b833":"blackListERC223(address)","34716f67":"post(string,bytes20[])","3471728a":"masterContractAddress()","3471aef0":"handbreak()","3471b034":"Submission(uint256,string,address,address,uint256,string)","34721e08":"test0Alice()","3473bf30":"setEndingTime(uint256)","3473f5e4":"HashOfDB()","34746d86":"killTokensForGPower()","347518c7":"validPurchaseTime(uint256)","34757fa9":"correctPreICOPeriod(uint256)","34758cb3":"currentEggPrice(uint256)","3475c1e7":"attemptPublishOfArticle(uint256)","34762a94":"ethHandleIsRegistered(bytes32)","347632e8":"getShareholderAdressByID(uint256)","34763586":"FoundersAndPartnersTokensIssued(address,uint256,address,uint256)","34766ecc":"PauseOff(uint8)","3476aeb0":"signer2_proposal()","34771f81":"setData_5(string)","34776c6e":"DEAToken()","347820eb":"previousUpdateTime()","34785e79":"setEthRelief(address)","34786d1d":"totalTokensToTransfer()","3478ab86":"HYToken()","3478ac2b":"createShow(uint256)","3478dc44":"getRecordOffers(bytes32)","3479101f":"setProviderSupply(uint256,uint256,uint256)","34791ae5":"POPPToken()","3479f017":"ServiceContract(uint256,uint256[],uint256[],string,uint256,uint256,uint256[],uint256[],address,address,address,address,address)","347aa903":"SDOGE(uint256,string,uint8,string)","347aba23":"evePerEth()","347acf2f":"mintingFactories(uint256)","347b3923":"putProfit()","347b5193":"LiquexPrivateInvestment(address)","347caeb4":"PhxHell(address)","347cda88":"needsBlockFinalization()","347d5bc2":"setPayoutOdds(uint256)","347e26c0":"icoEtherContributed(address)","347f5f00":"TokenPurchase(address,uint256,uint256,uint256)","347f8f54":"_setDiscount(uint256,uint256)","347ff187":"changeAirAmount(uint256)","34805e7c":"targetBlockNumber(uint256)","34809ee7":"doge()","34810336":"discountEndTime()","34814e58":"transferBalanceWithFee(address,address,address,uint256,uint256,address)","34825a23":"playGame(uint256,uint256)","3482e0c9":"cancelAuthorization(address,address)","34831b79":"VENSale()","34833a6d":"icoBalanceOf(address,address)","34835560":"innerlockStartTime()","348378d0":"Whitelisted(address,uint256,uint256,uint32)","348508cf":"thirdDueDate()","34854101":"ETH_TO_WEI()","3486645f":"forkReceive(address,uint256)","3486fb30":"mintLockPeriodBatch(address[],uint256[],uint256)","3487d97c":"setPriceCredentialItemId(bytes32,bytes32)","348a653a":"CONFIG_DURATION()","348b1b7d":"temperatureMin()","348be311":"LogBidOpened(uint256,address,uint256,bytes32,uint256,uint256,uint256,bytes32)","348e9779":"Restart(uint256)","349136af":"BonusScheme()","3491a19d":"TokenDemo(string,string,uint8,uint256)","3491d0f1":"processTransactionFee(address,uint256)","349221be":"ColorCoin(address,address)","349296a5":"SaleAuction()","3493075e":"getLevelCitizenLength(uint256)","3494ab3d":"validEAContract(uint32,address)","3494f222":"issueSuperMetal(address,uint256)","3495015a":"UnlimitedIPToken()","349501b7":"checkDepth(uint256)","34950dcf":"approvedSubmissions(uint256)","34954a99":"updateBalance(address,address,uint256)","34955a2b":"setTavernContract(address)","3495b21e":"setNewReleaseEndTime(address,uint256,uint256)","349718ed":"MarketCoin()","34971dd6":"totalEtherCap()","34984add":"signedTransferFrom(address,address,address,uint256,uint256,uint256,bytes32,address)","34988b95":"ExToke()","3498aaaf":"LogAllowedFromAddress(address,bool)","3498b00f":"getSectionIndexFromIdentifier(uint256,uint256)","3498c518":"StageClosed(uint256)","349a1f03":"getNumSums()","349a373b":"batchcreatevillage(uint256)","349a6edb":"_purchaseTokens(uint256,address)","349aa97e":"ethereumToTokens2_(uint256)","349ab992":"divCutAdmin()","349ae23b":"collectFor(address)","349b586c":"isCrowdsaleFinalized()","349b6486":"revokeGrant(address,uint256)","349c1ee3":"enableCrowdsale()","349c3d75":"changeSaleBonusRate(uint256,uint8)","349c870c":"initChainLedger(address,address)","349ca600":"Tags()","349cdcac":"reLoadXid(uint256,uint256,uint256)","349d1661":"BuyToken(address,uint256,bytes32)","349d3dc5":"breedTimeout()","349d8b4e":"communityMultisig()","349dc329":"miner()","349eb329":"jsonCat(string,string)","349f7173":"lastOraclePrice()","349f939a":"SaleEnded(address,uint256)","349fcf85":"UpdateAddressPayForService(address,address)","349fdb09":"setUnPaused()","34a014dc":"lastWithdrawalTime()","34a042d8":"bountyPoolAddress()","34a2b766":"getMarketData(address,address)","34a3312e":"setStore(string,address,address)","34a3b820":"getNewFallbackDepositPeriod()","34a4a527":"getCountHolders()","34a4b10b":"allocatetokensAndWL(address,uint256,uint256)","34a503e8":"_utfStringLength(string)","34a5eaa9":"_createPerson(string,address,uint256)","34a6074e":"buyWithBalance()","34a6301e":"setmessager(string)","34a6d832":"canPurchase()","34a6e514":"updateTaskState(string,string)","34a7ed17":"wikiAddTokenTo(address,uint256)","34a814a3":"setMyEthBalance(address,uint256)","34a8c392":"webSite()","34a8eb53":"getarg_1_input()","34a8f866":"setMatured(uint32)","34a90d02":"lockAddress(address)","34a9918e":"DEWCOIN()","34a991db":"enableManager(address,bool)","34a9a1ae":"getTokenDefaultPartitions()","34a9bb34":"getCurrentPublicBracket()","34aa0e7f":"dividendRegistration()","34aa982a":"getInfoForDisputeAndValidate(bytes32,address,address,address)","34ab32e1":"minerTotalYears()","34ab8256":"RUDAWORLD()","34abd1b1":"updateMaxPhase3(uint256)","34ac6f5e":"AVAILABLE_FOUNDER_SUPPLY()","34acc716":"projectDone()","34ad1e53":"giveBalance(uint256,uint256,uint256)","34ad324c":"sendToOwners(uint256)","34ad6f00":"TimePassBy(string,uint256)","34ae6984":"view66()","34aeefd5":"RemovePlayer(address)","34af370f":"lockTime(address,uint256)","34b0e5ed":"icoPrice()","34b122cb":"addTokensToReturn(address,address,uint256,bool)","34b20591":"createERC20Token(uint256,string,uint8,string)","34b3ae71":"_distribute()","34b3b014":"resolveSupply()","34b4eef2":"setStartIcoPreICO2ndRound(uint256)","34b55235":"registerAffiliate(address,string)","34b63592":"addre(address)","34b73591":"DevMiningRewardTransfer(address,address,uint256)","34b768c7":"summonHero(address,uint8,int256)","34b7ac9b":"END_MINTING()","34b88e04":"claimCoreTokens(address,uint256)","34b8b690":"Yuri()","34b98747":"onlyOwnerGetTeamWallet()","34bafed3":"date_string(int8,int8,int16)","34bb1a9e":"founderTimeLock()","34bb3ee1":"updateEthICOVariables(uint256,uint256)","34bb447f":"getDiceWinAmount(uint256,uint256,bool)","34bbabbd":"RaffleTshirt(string,uint256)","34bc5156":"Crowdsale(uint256,address)","34bc98b7":"latestPing(uint256)","34bd08c4":"getLargeAmountBonus(uint256)","34bdcd0a":"getLedgerValue(string,address,address)","34bdea85":"setICO2Phase()","34bdf2c4":"setReference(address)","34be5fab":"mintParcelTokens(address,uint256)","34beb204":"ZZC(uint256,string,string)","34bed16c":"bountyRefund(address,uint256)","34bf97ea":"setBonuses(uint256[])","34c05ca8":"modifyMetadataHashes(uint256,bytes32,bytes32,bytes32[],bytes)","34c0c9c6":"RemoveApprovedAddress(address,address)","34c0d654":"setPackageDb(address)","34c19b93":"getCallGracePeriod(bytes32)","34c1b4ba":"sha(bytes)","34c1ef77":"publicSaleTokensAvailable()","34c2904b":"giveDividend(uint64)","34c2b620":"getNickname(uint256)","34c31392":"breakParentsHaveGreaterPriority(uint256,address)","34c3236a":"signatureDropSingleAmount(address[],uint256)","34c39d1c":"ThreeDLTokenDeposit()","34c42106":"BOXT()","34c5c059":"addEtherToSphere()","34c6766f":"getImportingAuthority()","34c6a9ae":"getTokenTimelockDetails(address,uint256)","34c721a9":"getExploreResult(uint256,uint256)","34c73884":"Mint()","34c757cf":"NBAT102(address,address,address,address,address)","34c7b8e8":"getReadMessages(address)","34c7dcf8":"proposedUserKey()","34c8e114":"reservedDestinations()","34c8ea26":"SetupiBird(string,string,uint256,uint256,uint256,address,address,uint256)","34caa999":"setMinimumFundingAmount(uint256)","34cac67e":"investorsArray(uint256)","34cad6b8":"retreiveTokens()","34cad836":"coinsaleDeadline()","34cbbef9":"EndRateChange(uint256)","34cc182b":"updateDiamond(string,string,uint256)","34cc4b8f":"ratePerWeiInPrivateSale()","34cdb15f":"addressToTimestamps(address,uint256)","34cdf78d":"blockHashes(uint256)","34cec84d":"maxCapCompanyInventory()","34d05b1f":"freezeDeliver(address,uint256,uint256,uint256,uint256)","34d09ff1":"DemoraCash()","34d0cb6d":"CNYToken()","34d2485c":"tribeTokens(address)","34d24bff":"no(uint256,string,uint256)","34d2c4cb":"mintProxyWithoutCap(address,uint256)","34d31de3":"length(uint8)","34d33f9f":"kycRefuse(address)","34d40382":"nextSection(bytes32)","34d4776b":"removeApprovalStatus(address)","34d4cd82":"getTokenForTeam(address,uint256)","34d55cd9":"SerpentCountDown()","34d56b0a":"Currentproposal()","34d5751a":"approveContractCall(address)","34d5f37b":"round(uint256)","34d5fc4b":"transferInitialAllocationWithTimedLock(address,uint256,uint256)","34d609ac":"auditorHasStaked(uint256,address)","34d64e50":"getDoneAirdropAmount(address)","34d71238":"sencBalance()","34d722c9":"minterAddress()","34d83dab":"PhaseICO()","34d8521b":"quarterlyWithdrawable()","34d8c24d":"init(uint256,uint256,address,address,address,address,uint256,uint256,address,uint256,uint256,bool,bool)","34d92490":"changeFuckyou()","34d95bf0":"ShitCloneslordAddress()","34d9aee3":"assertEq7(bytes7,bytes7)","34dbe44d":"getLastBlockNumberUsed()","34dc2176":"inventoryProduct(bytes32)","34dc3c32":"pricePerWei()","34dc864c":"YYYToken()","34dcfec4":"minimalETH()","34df4222":"hasBeenLinked(uint32,int256)","34df8b63":"PER_USER_MAX_AVATAR_COUNT()","34df9b60":"getCow(uint256)","34e19907":"setSwapFee(uint256)","34e1ad21":"EmontFrenzyTool(address)","34e22921":"Call()","34e23416":"lastcombo()","34e24640":"distr(address,uint256)","34e24853":"encode(address)","34e255a4":"WTechTestCoin()","34e415db":"growWeed(uint256)","34e41bbf":"RATE_DAY_1()","34e4c06d":"maxSupplyGenerable()","34e5a5f8":"getPlayerInfoWithRoundID(uint256)","34e5a692":"distribute(uint128)","34e5e97a":"assignProduct(uint256,uint256,uint256,uint256)","34e70cc2":"tub()","34e73122":"calculateFee(uint256,uint256)","34e73f6c":"getAuctionCost(bytes32,uint256)","34e7a57a":"nonWLBalanceOf(address)","34e80c34":"getKeys(address)","34e8980f":"bootUpHangouts()","34e8c679":"retrieveTokens(address,uint256)","34e8ecea":"FindTheCureCoin()","34e8f247":"setStartTimeIcoStage3(uint256)","34e98037":"batchAssignment(address[],uint256[])","34e9d146":"EstateToken(uint256)","34ea5fe5":"setNumeratorDenominator(uint256,uint256)","34eaa923":"moveEther(address,uint256)","34eac76f":"withdrawalDeployed()","34eaf154":"investorAmount(address)","34eafb11":"totalCount()","34eb0cf5":"isUserBlacklisted()","34eb3200":"setRequiredProgressOfPreviousDungeon(uint32)","34ebb615":"maxTokenToBuy()","34ec514b":"setInitialPrize()","34ec96bf":"dAddCategory(bytes32,bytes32,bool,uint256)","34ed557f":"setTokenIpfsHash(address,bytes32)","34eea4a2":"executeRoom(uint256)","34ef39f1":"owner_withdraw()","34ef801e":"wcOnCrowdsaleSuccess()","34efcb8e":"getPlanet(uint256)","34f00e83":"setCrowdsaleStart()","34f03321":"PCM(uint256)","34f0e39e":"addCurator(address)","34f10c39":"chkcan(address,uint256,uint256)","34f1f9b1":"lbToken()","34f20f31":"setExchangeRateAuth(address)","34f245c2":"hasSecondUnionIds(bytes32,bytes32)","34f25146":"numOfReleased()","34f2d1ec":"scheduleUnsoldAllocation()","34f361a4":"bonusSecondWeek()","34f50813":"PreICOToken(address)","34f64dfd":"bobMakesErc20Payment(bytes32,uint256,address,bytes20,address)","34f682e2":"GetPriceOfRigs(uint256,uint256,uint256)","34f6bef3":"allTokensDecimalsBalances()","34f6d0b3":"Congress(address)","34f732e8":"withdrawalLockTime()","34f8cc6d":"DrAgentToken()","34f9445e":"consumeEnergy(address,uint256)","34f96971":"lockedBalanceCount()","34fa0606":"getControlInfoTokenlist()","34fa17cb":"getTeamBet(string)","34fa37da":"grantTokens()","34fb032e":"getAddr(string,string)","34fb11ed":"setMintingFeeEnabled(bool)","34fc2591":"toggleFreeze()","34fc62ff":"_badgeOwnerChange(uint256,address)","34fcc3e7":"getBetting(uint256,address)","34fcf437":"setRate(uint256)","34fe00b1":"getDocumentMajorities()","34fe0cf5":"payFee(address,address,address,bytes32,address,address,bool)","34fe5473":"largestDonation()","34fec467":"transferAllowed()","34fee3e4":"AuctionSuccessful(uint256,uint256,address,uint256)","34ff37f3":"returnLongCouponAmount(address[3],bytes32,uint256)","34ffea2c":"token_iso_price()","35001a1a":"internalMint(address,uint256)","350078b8":"staticblock()","3500a48d":"transferCommunityCommune(uint256,address)","35013592":"getStageCap(uint256)","35020cb9":"getReferenceType(bytes32)","35021991":"PresaleStarted(uint256)","350279c6":"getStage3Cap()","3502be27":"TaxTillNow(uint256,uint256)","35039525":"isBarCode(bytes32)","350460f8":"basicTokensPerEth()","35046722":"getAddressBalance(address)","350486da":"AgiCrowdsaleMock(address,address,uint256,uint256,uint256,uint256,uint256)","35058a2a":"approveOperatorTo(address,address,bool)","3505e844":"userExists(address,address)","350604f1":"rakesOwing(address)","3506b32c":"FailedTransfer(address,uint256)","35082933":"setAdminWallet(address)","350845f5":"maxStage3AllocationPerInvestor()","35085b58":"weekThreeStart()","350896f7":"setEtherPriceManually(uint256)","3508eddb":"AnkitToken()","3508f2e8":"Monday(uint256,string,string)","350a6429":"minAmountETH()","350b4c6f":"setWLMTBounce(uint256)","350b4cb6":"BaseAirdrop(address,address)","350bb144":"createContractGirl(string)","350c0acf":"checkWithrawStock(address)","350c35e9":"withdrawCollateral(address,uint256)","350cf91c":"createManufacturer(address,address,string,string)","350d141e":"getWasApprovedBeforeDeadline()","350d9b96":"walletWithdraw(uint256)","350dbcc5":"get_Sponsors_list_by_Job(uint256)","350dd4a4":"Nettekcoin()","350ee628":"addVerifiedInfo(address,address,string,uint8,string,string)","350f4270":"specificTransfer(address,uint256)","350f9e01":"swypes()","350fbe2e":"calcNextDrawTime()","35100acc":"credit_token(address[],uint256)","35101d8e":"balancesForOutcome(uint8,address)","35105e3b":"executeChildDaoProposal()","35109cc6":"PRE_SALE_TOTAL_TOKENS()","3510b66c":"reduceTotalSupply(uint256)","3511c1af":"getMySnake()","3511ca9c":"Freezing(address,uint256,uint256)","351210b3":"BpxToken()","35126330":"GanaTokenLocker(address,address)","35130678":"additionalPreMine(uint256)","351314a5":"oIDIndex_()","3513651c":"Spin(address,int256,uint256)","35139014":"preICOstart()","3513cab2":"getWeeklyBuyVolume()","3513d339":"ForceSendTokens(address)","351509a8":"TEAM_ADDRESS()","3515519c":"getInitialval()","3516df21":"supplyBurn(uint256)","3517a740":"getNodeParent(bytes)","35181711":"SetStartTimeIco(uint256)","3519786f":"setAvailableFlat()","35197d6b":"sendData(address,uint256,uint256,bytes)","3519932e":"authorized_recordStashedPayout(uint256)","3519a2f8":"fundContract(uint256)","351a97f8":"accountKind(address)","351adcb0":"SocialPay()","351b68db":"SWAP_LENGTH()","351be6ad":"releaseProduct(address)","351bf518":"transferFeeRate()","351c2576":"completeFavor()","351c9133":"userkeys_push(address,uint64,uint64,uint64)","351dadf4":"support_ban_of(address)","351e46de":"setBLInterface(address)","351f42c3":"msgs(address,uint256)","351f98d9":"icnq()","35209715":"burritoPoolTotal()","35209821":"metadataContract()","35213a69":"abandonedFundWithdrawal()","35216bba":"enableTokenTransfer(bool)","3521d7da":"prvd()","3522e868":"changeLogicContractAddress(address)","35259f1a":"ThriveToken()","3525d66d":"CanvasFrag()","35269662":"importerBanker()","3527cae0":"_deleteUint(bytes32)","3528351d":"bouleDevMultisig()","3528a0c8":"GlobalTransfersLocked(bool)","3528c022":"days_interval()","3528f564":"allowancePerYear()","352a482f":"havedDistFoundCoin()","352a950c":"updateCnyBtcRate(uint256)","352bbdff":"referralContracts(address)","352c93b7":"getFess()","352d2790":"UUID4()","352d5cd0":"setPhaseSupply(uint256,uint256)","352e0891":"_isValidSignatureAndMethod(address,bytes)","352e1dff":"getWorkflowActivity(uint256,uint256)","352f43a8":"RongWQToken(uint256,string,uint8,string)","352f64f9":"getOwnerFee(uint256)","352fd696":"PERCENTAGE_OF_TOKENS_SOLD_IN_SALE()","352ff2bd":"setPreSaleRate(uint256)","352ffb9a":"Trident()","35300990":"propExists(bytes32)","353086e2":"MAX_BET_VALUE()","3530e895":"getClaimEst(address)","3531f0de":"LogWeiWithdrawn(address,uint256)","35347560":"getLamboAttributes(uint256)","35353b03":"parseAndRound(string,uint8)","353559cb":"Controller_Address3()","35359a3f":"tokenHolderAddress()","3535ab2a":"btcUsdRate()","3535cd52":"setDailyCosts(uint256)","3536046a":"getUInt(string)","35361909":"withdrawStart()","35371218":"closePositionDirectly(bytes32,uint256,address)","3538b13a":"MAX_TOKENS_FOUNDERS()","3538b9db":"test_twoValidEqBytes32()","35390714":"maximumFee()","353928d8":"helpRed()","35393197":"setReferer(address)","35396c1c":"createItem(uint256,uint256,uint256,uint256,uint256,uint256)","3539c468":"remainingTokenAmount()","353a3475":"setTargetAddress(address,address)","353ba8e9":"vvc(uint256,string,string)","353be218":"ToorToken()","353c0573":"burnInternal(address,uint256)","353d90ec":"numTickets()","353db436":"setCosts(uint128[])","353e65e9":"wallets(address,uint256)","353edf58":"presaleEndtime()","353f0e40":"getCurrGameInfoPart1()","353f1bc7":"setIsAllocatingInterest(bool)","353fe553":"BNDToken()","35400daf":"setTier2Participants(address[])","3540233b":"set_status_user(address,address,bool)","3540b529":"readIncUpdatedOn(string)","3540e96c":"tokenOWL()","35410f85":"KPCoin()","3541d365":"GPUMining()","3541fd53":"setStake(bytes32,uint256)","3541fe94":"teamVestingAddress()","354211c9":"TriwerToken()","35423643":"totalmoneyearned()","354271b4":"test_7_accessRestriction_UnderscoreRemoveMember_shouldThrow()","3542758f":"addOwner(address,string)","354284f2":"party()","3542aee2":"mintByOwner(address,uint256)","3542d0f6":"msgQPut(string)","35436725":"CoinMovement(address,address,int64)","3543b23c":"assign(address,string)","35446c78":"setAirDropPayableTag(bool,uint256)","3544a864":"whiteList()","354537da":"safeCloseSale()","3545acb0":"after_test_1_method()","354685fb":"setSellDividendPercent(uint256)","35468963":"rentModified(address,uint256,uint256)","354709dd":"trade(address,address,uint256,uint256,uint256,address,uint256)","3547800a":"lockTokens(address[],uint256[])","354836b9":"setIsReportingActive(bool)","3548fcd7":"getCardAttrs(uint256[])","35490ee9":"setPublicOfferPrice(uint256,uint256)","3549345e":"setPresalePrice(uint256)","35493e98":"icoEtherReceivedPreSecondSale()","35496d82":"POWHclone()","354a5137":"setWinnerTimeStatus(bool)","354b2735":"testDeploy()","354b7b1d":"updateVerified(address,bytes32)","354d68f2":"validate(address,address,bytes32,address,uint256,bytes32,address,uint256,bytes32,uint256,uint256)","354d7e40":"Payout()","354d89ee":"setTokenSaleContract(address)","354e1063":"setExtraConfig(uint256,uint256)","354e6ca7":"HippieCoinv2()","354eb40b":"emojisan()","354f1651":"completeBountyDistribution()","354f6398":"insert_candidate(string,uint8,string,string,string,string)","35509937":"changeWithdrawal(address,address)","3550b6d9":"getTokenAddressBySymbol(string)","3550e2e2":"changeBlockedTimeForBountyTokens(uint256)","3551a6ca":"nullifyFrom(address)","3551c8b9":"tokenesia()","355255f5":"totalSyndicateShares()","35527354":"submitNewHash(bytes32,uint256,uint256)","355274ea":"cap()","3552f552":"_random(uint256,uint256,uint256)","3552f9f6":"GetBetReadyTime()","3553f60d":"getPoolAdmin(uint256)","355421a8":"create(uint256,uint256,uint256,address,address)","355473d0":"setuped()","355474d2":"commitReading(address)","35548c02":"WINNERTAX_PRECENT()","35552dbc":"transferDSPRecord(address,address)","35554e58":"SearchUserPurchase(address,string)","3555fa90":"contractSpend(address,uint256)","35566ff0":"rewardSources(uint256)","3556afd8":"m_exchangeRate()","355784cb":"settleToken(bytes32,address,uint256,uint256)","35579f0c":"withdraw_token(address,address,uint256)","3557c1f6":"labAddress()","3557c70a":"removeMintingFactory(address)","3557d0e9":"testThrowIfNotExist()","35593bcf":"vestedAmountAvailable()","35595c95":"getSkillName(uint256)","355ae09c":"Fluzcoin()","355ba211":"emergencyOverwrite(bytes32,uint8,uint8)","355c6457":"tryToRecord(address,uint256)","355d59aa":"publicTokensAvailable()","355d7d03":"batchAllocate(address[],uint256[],uint256[])","355d7e05":"withdrawByMint(address,uint256)","355d8c64":"Uptrennd()","355dd1b3":"Donate_LuGoddess()","355e0c5d":"tokenUri()","355e1b84":"Mstcoin()","355e56b9":"Assembly(address)","355e6b43":"setCommission(uint256)","355eb2c0":"canWrite(string,address)","355f41a9":"pay(uint256,uint256,address,bytes)","355f51a0":"right49(uint256)","355f7ea7":"canUpdateNextGameMinAndMaxBlockUntilGameEnd()","355fd8db":"thirdTimeLine()","35603440":"sections(uint256)","3560f05e":"AsX()","356282db":"changeMinBidMultiplier(uint256)","3562a1db":"CoderForge()","3562fd20":"setUIntValue(bytes32,uint256)","35639e11":"updateMinGasPriceForDrawing(uint32)","356442b9":"lockPercentage()","356594ab":"EtherTransfer()","35671214":"prev(uint256)","3567950c":"blockchainExchange(uint256,uint256,bytes32)","3567d5ef":"BuyGoods(address,uint32)","3567d637":"getTransactionListLength()","3568bd39":"mintStart2()","3568fb04":"createUint256(bytes32,uint256)","356c22ec":"teamOne()","356ca551":"ZhkCoin(uint256,string,uint8,string)","356d414c":"transferFrom(address,address,address,uint256,uint256,bool,bool)","356d4a3a":"createJaroSleep(address,uint256)","356d6b24":"fifthBonusSalesEnds()","356e2927":"icoFinished()","356e7e9d":"mintToAccount(address,uint256)","356eeaab":"payAndReset()","356f056f":"releaseTime3()","356f083e":"_bytes32ToString(bytes32,bytes32)","356f55b7":"adminDropETH()","356f8964":"transferMed(address,uint256)","356f9865":"tokenPerWei()","356fefb3":"developer_edit_text_crowdsale(string,string)","357006c4":"Propellerhead()","3570c2ee":"PosRewards()","3570f217":"CarbonTOKEN()","3571e567":"PausableCappedDividendToken(uint256)","3572a28e":"EPT()","35734ba5":"ExternalSale(uint8,string,address,uint256,uint256)","35735226":"returnBonus()","3573df50":"CreateMND(address,uint256)","357401f5":"cancelBet(uint256)","35743ac9":"proposalActive(uint256)","3574da8c":"deployShop(address)","35759333":"checkList(uint256,address)","3575ecc6":"BreakbitsToken()","35765828":"addSystemUserEarnings(uint256)","3576a32f":"setBackupOwner(address)","3577d94e":"loanTerm()","35785e09":"sweepsState()","3578abf4":"QuintessenceToken()","3578b7b3":"setBuyPrice(uint256,string)","3578bb7f":"calculateScore(uint8[])","35796635":"numEndedGames()","3579c0df":"newAward()","357a0333":"initWithdrawal(address,uint256)","357a05cd":"cram(address,uint256,string)","357a05f1":"Crowdsale(address,address,address,address)","357a0ba2":"sgt()","357af806":"Restart()","357bd7d6":"ROHH()","357be177":"DemSoKhoaHoc()","357d0173":"removeArbiter(address,uint256)","357d4d1a":"ICloudSecAddress()","357ee486":"createDonationsBank()","357fe12a":"createPromoMonsterWithTokenId(uint32,bytes,address,uint256)","3580031a":"consumesGas()","358049ea":"setDiscountTime(uint64)","35804a88":"returnBook(uint256,address,address)","35815b95":"FACTOR()","35817773":"getContract(string)","3581b257":"_addDividendsForAddress(address,address)","35828c8d":"TransactionInitiated(uint256,address,address,address,address,address,uint256,bytes32)","358373bd":"withdrawalInterCrypto(string,string)","35842f74":"depositDai(uint256)","358455b4":"testDefaultWallet()","3584fa38":"setDelegate(uint8,address)","358507d7":"claimRefundOnUnsuccessfulEvent()","3585609b":"getJobCanCancelAfter(bytes16,address,address,uint256,uint256)","358564ee":"allocateLoyaltySpend(uint256)","358592ce":"_freeze(address,bool)","3585e500":"nTransfers()","35862824":"isIcoOpen()","35866368":"transferFromWithCustomReservingNet(address,address,uint256,uint256)","35875623":"get_list_deposit_key(address)","35876476":"initialize(address,address,address,address,address,address,address)","3587904b":"limitOfTeam()","3587b26c":"setAutoBuy(uint256)","3588aa0b":"BMV()","358a074c":"admin_isRequireData(bool)","358a08cb":"activate(address,uint256,address,uint256,uint256,uint256,bool,bool)","358a11b4":"change_data(string)","358a18b2":"ThePatriotCoin()","358a2a84":"toHorse(uint256)","358c24b1":"CONFIG_MIN_PLAYERS()","358cc6f6":"acceptKyc(address)","358cfa25":"setTotalEtherPool(uint256,uint8,bool)","358d1e26":"HitToken(string,string,uint8,uint256,address,address)","358d5dc2":"getIsCashed(uint256,uint256)","358dff07":"minEthPerTransaction()","358f7f3a":"numberRange()","358fa6c6":"calcBuyout(uint256)","358fcee9":"fetchdivs(address)","358ffd79":"Controller(address,address,uint256)","3590699d":"_newSchellingRoundEvent(uint256,uint256)","359170e6":"setTransfersEnabled()","3591a1a9":"canDrip(address,address)","3591f5bd":"removeSomeDETsFrom(address,uint256)","3591fadc":"STAGE_2_FINISH()","3592336c":"getRetailerStatus(address,address)","3592c3b5":"uintToString(uint256,uint256)","3592dfea":"updatePackage(uint256,string,address)","3592f369":"disableTokenSwapLock()","35930e13":"setMinimalRewardedBalance(uint256)","359320de":"getCurrentVelocity()","35953108":"removeAddressesFromWhitelist(address[],string)","359531f4":"allowCnsContracts(bytes32,address,bytes32)","35956083":"Parabola()","35956c42":"ABCPresale(uint256,uint256,address,address)","35958196":"getGamesPool(uint256[])","359582ca":"downstream()","3595b570":"copyBalance(address)","35960028":"payMeFor(uint16)","359627e5":"canPay(address,uint256)","35967501":"setManualOverride(bool)","35972f46":"techAccount()","35975a37":"setStart()","3597727c":"EtherDLT()","359803cd":"pauseMinting(bool)","359819cc":"Group(address,bytes32,address[])","359829db":"numOfBackers()","3598ac34":"Cider()","35995022":"getPhaseCount(uint256)","359976a7":"getCheckSum(bytes20)","359ae0f3":"set_Shops(address[],address[])","359bc19e":"finalize(uint64)","359c1912":"setUintF1(uint256)","359c1f72":"getGravatar(address)","359c8a93":"claimD()","359cc28e":"changeIcoDeadLine(uint256)","359cf2b7":"requestTokens()","359d04a2":"voteRuling(uint256,bool)","359d393d":"votes_against()","359d9277":"XXXXXXXX01(address,uint256)","359db8c8":"partialDistributeDivident(uint256,address[],address)","359dbafe":"validatorWrotePart(uint256,address)","359ef75b":"init(address,address,address,address,address)","359f517e":"confirmWithdrawal()","359fe132":"getSharesByShareOwner(address)","359fe780":"increaseMintApproval(address,uint256)","35a063b4":"abort()","35a07291":"makeAssessment(uint256,uint256,uint256,uint256)","35a1529b":"dripAmount()","35a1bf6e":"test_insert_findWithHintNextRemovedUpdateTail(int256)","35a1d95d":"requestSnapshots(uint256)","35a21728":"multiERC20Transfer(address,address[],uint256[])","35a23659":"miningTimePerTrip()","35a26787":"AuthAddr(address,address,address)","35a374dc":"issueLottery(uint8)","35a3a96f":"marketingRecipient()","35a3cfa0":"transferMarketallocationTokens(address,uint256)","35a3e83c":"getCurrencyDecimals(uint256)","35a3fbb0":"_triggerStashedPayoutTransfer(uint256)","35a4015d":"numberOfBudgetPlan()","35a49063":"personalityTypes()","35a4fa30":"createPromoWhale(address,string,uint256)","35a53379":"_increaseWinPotChance()","35a568b9":"setLockPostion(address,uint256,uint256,uint256)","35a5c43a":"get_FTVTOKEN_EURCENT(uint256)","35a5e06d":"getRoots()","35a5e8bf":"SectorUpdated(uint16,address,string,string,string,bool)","35a66ef8":"arrayOfAccountsThatHaveClaimed()","35a6861a":"login(address)","35a6c1e0":"totalPausedSeconds()","35a6ed92":"calculateBonusAmount(address,uint256,bytes32)","35a8076b":"Accounts(address,address)","35a951b8":"endTime(bytes32)","35a9731b":"approveRefund()","35a9a5c7":"setWithdrawAccount(address)","35a9c82f":"setSecret(bytes32)","35a9d051":"ETH_address()","35aa6bec":"checkExpectedTokens(uint256[],uint256)","35aa6c31":"getMoney(address,uint256)","35acac4e":"abort(string)","35acbcab":"makeStudentID(bytes)","35ad84f9":"buyFromValue(uint8)","35ad9581":"saleRateSecondDay()","35adc0c5":"sellerCancel(bytes16,address,address,uint256,uint16)","35ae20bb":"AddEthBalance(address,uint256)","35ae41c9":"godAutomaticCollectFee()","35aed70f":"getNumAnimalsXPlayerXType(address,uint8)","35af1986":"div27(uint256,uint256)","35af2c4f":"unsetIdentity(uint256,address,address)","35af5a9c":"MOTCToken(uint256,string,string)","35b05d1e":"purchaseRequest(uint256,uint256)","35b09a6e":"someFunction()","35b1097e":"communityTokensHolder()","35b1114a":"REQUEST_CANCELED_BY_BORROWER_STATUS()","35b11b72":"setColors(uint16,uint256[5],uint256)","35b21ceb":"totalChildTokens(uint256,address)","35b28153":"addAuthorization(address)","35b3caf0":"cancelOrderWithPayerByAdmin(string,address)","35b3ee0e":"NGA()","35b46459":"distribute(uint256,address[],uint256[],uint256)","35b4a6d9":"updateBTCPrice()","35b4a93e":"HSDJCoin()","35b55d98":"SUBSCRIPTION_MODULE()","35b643d4":"getBalanceTimestamp(uint256)","35b6a6c6":"tokensForAdvisors()","35b6cc03":"RankingBallGoldCrowdsale(bytes32[5])","35b6df5d":"BurnableCrowdsaleToken(string,string,uint256,uint256)","35b6eaea":"isPayed(address)","35b75391":"test_validProposalExecution()","35b7588f":"allowedMinting()","35b8e820":"getCandidate(uint256)","35b94b5d":"MIOTToken(uint256,string,string)","35ba1d0a":"closeOnBehalfOf(address,address,bytes32,uint256)","35ba66de":"ACATokenSale(address,address,uint256,uint256,uint256)","35ba9af8":"availableForWithdrawal()","35bb0398":"didSign(address,bytes32,uint8,bytes32,bytes32,uint8)","35bb3e16":"grantAdmin(address)","35bb5fd2":"isToonInterface()","35bbe70e":"getAllVoters()","35bce6e4":"transferMulti(address[],uint256[])","35bd8b94":"Noblebit(uint256,uint256)","35be7bf3":"getSecondRoundReleaseTime()","35bf82f6":"setChallengeFee(uint256)","35bf90ca":"getContributorByNumber(uint256)","35bfe158":"changeGoldIssueBurnFeeContract(address)","35c019e2":"LogFundTransfer(address,uint256)","35c05ab0":"hodlFor3y()","35c1d349":"participants(uint256)","35c23200":"computeNextPrice(uint256)","35c2d49d":"minInvestETH()","35c40fe3":"testParamOutOfBoundsFail()","35c42d7f":"getPetByIndex(address,uint256)","35c4de7a":"OracleRequest(address)","35c5b475":"getExpectedReturn()","35c648c5":"POMDA()","35c6511b":"endMiniGame()","35c699c4":"getUnclaimedEtherIfAny(uint256)","35c72df0":"bryan()","35c7421b":"testMinReturn32WithReturn()","35c77e6f":"configurer()","35c80c8c":"isCustodian(address)","35c8518b":"setCloseBlock(uint256)","35c914c2":"finishPayaning()","35c969ea":"Presale(address,address,address,uint256,uint256,uint256,uint256)","35c990d4":"getGameCalculationProgress(uint256)","35ca8ce1":"setPriceToRegSale()","35caecc3":"getPeriod(uint256,uint256)","35caf648":"DonationMatched(address,uint256)","35cb1f07":"wethDeposit()","35cb27b5":"minedToken(uint16)","35cbdc25":"AcceptsProofofHumanity(address)","35cbe716":"getRemainingAirdropSurplusAddressesLength()","35cc2d80":"isInState()","35cc59a9":"createSchema(bytes)","35cd2358":"setAffiliation(address,uint256)","35cd4cc4":"getLastKicker()","35cd78b3":"saveMetaData(address,bytes32,bytes32,bytes32,bytes,uint32,uint256,uint256,bytes,uint256)","35cf60df":"enableFreezePriceRateRecalc(uint256)","35d0b444":"LogRedeemToken(address,uint256)","35d129f6":"untag(string)","35d13969":"SendAllMoney()","35d1f606":"destroyCard(uint256)","35d1f869":"setAtomOwner(uint256,address)","35d357ac":"logCeiling(int256,uint8)","35d37dbb":"mgmtFeePercentage()","35d4a49a":"setSubFreezingPrice(uint256)","35d65132":"canClaimPayout(address)","35d6d214":"getBids(uint256[])","35d6d611":"DAY_LENGTH()","35d79fad":"CertificationDb(address,uint256,address)","35d7a052":"freeze(uint256,uint256)","35d7d09a":"next_diary_id()","35d7f149":"takeBuyOrder(address[3],uint256[3],uint256,uint8,bytes32,bytes32)","35d82d16":"setGeneralInfo(bool)","35d91b85":"cancelOrder_(address[7],uint256[7],uint8,uint8,uint8,bytes,bytes,bytes,uint8,bytes32,bytes32)","35d94797":"verifyBetMask(uint256)","35d97405":"dividends()","35d99f35":"masterMinter()","35d9ba1f":"getTill()","35d9ceee":"uintMax()","35da3c1a":"createNewGalaxy(string,uint256)","35daa731":"ordersCount()","35db2829":"sendStableReward(address,address,uint256,uint256)","35db2b72":"Winchain()","35de5e89":"setPixelBlockPrices(uint256[],uint256[],uint256[])","35de74b8":"PBC()","35decc5f":"updateTargetToken(address,uint256)","35dfcc92":"totalCastle()","35dffde5":"updateReleaseAmount(uint256)","35e04fab":"prePayment()","35e09095":"decTotalSupply(uint256)","35e0f450":"stageMaxBonusPercentage()","35e24a6b":"preICOstate()","35e49e5f":"sellBlocks(uint8,uint8,uint8,uint8,uint256)","35e4d30f":"nonzeroAddressesElementForApi(uint256,uint256)","35e5f617":"transfer_erc20(address,address,address,uint256)","35e608be":"addUpgrade(address,address,bytes)","35e60bd4":"setTransferLocked(bool)","35e64aaa":"transferLand(int256,int256,address)","35e6a7af":"addab()","35e6e5b6":"removedSalesAgent()","35e82f3a":"removeAddressFromBlacklist(address)","35e83446":"testInitialBalanceWithNewMySale()","35e9d83b":"transferToAddress(address,uint256,bytes)","35ea6821":"masternodeTransferOwnership(address)","35ea94ad":"TokenSold(address,uint256,uint256)","35eb5208":"registerAgent()","35eb702f":"getPlayerWinning(address,uint256)","35eb8479":"showBidder()","35ebbfd1":"weekTwoStart()","35ec6dab":"earlyWallet()","35ed3fd6":"BONUS_PERCENTAGE()","35ed548f":"getPositionRequiredDeposit(bytes32)","35ed64c3":"CZToken(string,string,uint8,uint256)","35ed663d":"ENJToken(address,address,address,address)","35ee2783":"Alarm()","35ee2f8a":"initCanOffsetTime()","35ee72c7":"ISSToken()","35eead41":"addNote(bytes32,string,string)","35eec76a":"privatePreSaleSoldTokens()","35f067cf":"updateTokenURIPrefix(string)","35f097f3":"isOnBattle(uint64)","35f0d665":"reloadStoreByName(uint256)","35f10cc3":"sendWinnings(address[],uint256[])","35f1bd11":"EcoCrypto()","35f21f0a":"GladiethersOraclize()","35f2507f":"recoverUser(address)","35f27b20":"collectAirDropTokenBack()","35f2fbaf":"_bid(address,uint256,uint256)","35f3cf85":"setSaleManagerAddress(address)","35f46994":"die()","35f4de27":"HumaniqICO(address)","35f64a30":"albosWallet()","35f6806b":"addNewAccount(string,address,uint256,uint256,uint256)","35f68424":"getTokensByBTC(uint256)","35f6c161":"createWallet(uint8)","35f79b83":"LordCoin()","35f7ff63":"stringStorage(bytes32)","35f80a1b":"UbiatarPlayVault(address,address,uint256)","35f82876":"fillOrderNoThrow(uint256,bytes)","35f84393":"contructor(string,string)","35f88860":"listScam(uint256,string,uint256)","35f8a2c6":"RefundableCrowdsale(uint32,uint32,uint256,address,uint256)","35f931cb":"AmberToken(uint256)","35f96a7d":"goldBought(uint256,address,bytes32,string,string,string,string,string)","35fa3128":"BTTSToken(address,string,string,uint8,uint256,bool,bool)","35fa3843":"setend()","35faa416":"sweep()","35facf78":"createProposal(string,uint256)","35fb2125":"onlyBouncerTransferOwnership(address)","35fb337c":"finalCap()","35fb8e36":"triggerTestEvent()","35fc3e90":"claimRefundEther(address)","35fc7506":"StatsSold()","35fd8877":"isCashBack(address)","35fe3660":"MID_GRADE_CATEGORY()","35ff058a":"pushArray(bytes32,uint256)","35ff217d":"CrowdfundFinalized(uint256)","35ff3a51":"getRaisedEther()","35ffa20d":"handleWithdraw(address,bytes32,address,address,uint256,uint256,bytes32,bytes32)","35ffbe74":"verifyClaim(bytes,uint256,uint256,uint256[],uint256[],uint256[],uint256[])","35ffd687":"getStageLimit(uint8)","360035c6":"RepoToken()","360038b5":"CheckOver()","3600af8b":"updateProfileImgurl(string)","3600e1e2":"controlLimits(address)","36013189":"randomness()","360184e9":"Fouracoin()","3601dd87":"TNTToken(uint256,string,uint8,string)","36025bf8":"licenseTermsHasMaxCost(bytes32,bytes32)","3602627d":"BdpImageStorage(bytes8)","3603b0b0":"MULTISIG_WALLET_ADDRESS()","36044ecc":"changeTokenReward(address)","3604caa1":"lockAddress(address[])","36054f51":"affiliatThreshold4()","360583c6":"getUsersGunsIds()","36066f71":"Token(address,string,uint8,string,address,address)","36067543":"FirstEtherLimit()","3606c983":"createClaimMsg(bytes32,string,string,address)","36080694":"deleteRate(bytes4)","360821e8":"setMinimumBitcoinToInvest(uint256)","3608672c":"liveBetexICO()","3608c9eb":"MULT_FACTOR()","360998e6":"Cryptex(address,address,address,uint256,uint256,uint256)","3609ac8f":"START_PRICE()","3609bf09":"updateBusiness(uint256,uint256)","360aa28b":"isVersionContract()","360aac67":"accountGameResult(address,uint256)","360b3b31":"setAirdropEnabled(bool)","360b8115":"VipMigration(address,uint256)","360c97dd":"frozenAnnually()","360c9ed0":"deprecateBodySubtype(uint8)","360cdf5e":"AsOyToken()","360e5f54":"TokenGift(address,uint256)","360ec1b8":"processPurchase(bytes32,int256[],int256[])","360ed9c2":"receiversCount()","360f1d07":"bonusRatePrivateSale()","360f6b21":"chargingSwitches(address)","360ff695":"timeTier3()","3610724e":"buyTokens(uint256)","361228ea":"weiForToken()","36127d7e":"updateEMA(uint256)","36134a4b":"shouldBeStarted()","3613b781":"revokeVesting(address,address)","36144c9a":"getUserReferrer(address)","3614ac6f":"test4_searchSameNode()","361698ff":"adminSetWorldSnapshot(uint256,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","36169d90":"sweep(address,uint256,uint8[],bytes32[],bytes32[])","36170ae5":"startingDateFunding()","36173764":"frozen(address,uint256)","3617653e":"powerContract()","3617d5c6":"viewIndexNumber()","36181026":"tryToFinalize()","361819e8":"RANGEEND_4()","36186868":"icoWeek2Bonus()","361893f7":"getBrand(address)","3618b290":"hodlFor2y()","3618c2a2":"removeAddressesSet(address)","36199817":"setFinalTimestampOfBonusPeriod(uint256)","3619cd99":"myHalfDividends()","361a4eb8":"Party()","361a5468":"testFailMoveWhenStopped()","361ae621":"LifMarketValidationMechanism(address,uint256,uint256,uint8,address)","361b5eaa":"token(bytes12)","361b94be":"contributorMinCap(address)","361bb340":"left48(uint256)","361bfc5b":"ETH_per_BRA()","361c14b0":"teamUnlock4()","361cac82":"marketStores()","361cc3ab":"getUserTotalPromoBonus(address,address)","361d004f":"changeBank(address)","361d292e":"getCarAuctionID(uint32)","361d4e53":"usedTokenBalance(address)","361d55be":"callback_ForUnderwriting(uint256,string,bytes)","361f10e5":"setSiteAccountAddress(address,address)","361fab25":"setSupplyLimit(uint256)","361fd603":"First_pay_clientmanager()","3620f56d":"addQuest(address)","3622b5ef":"PIGGY_BANK(address)","36234138":"registerPair(address,address)","362344b8":"MAX_YAYS()","3623c225":"bid(uint16,uint256)","3623f548":"getAllWinner()","36249140":"third_withdrawal(uint256)","36261907":"setting(address,address)","36262665":"getOwnershipTokenCount(address,address)","362698a2":"Unlocked(string,bytes32,address)","3626aae7":"getMedalType(uint256)","36274669":"Poll()","3627d195":"FuckToken()","3627d3a1":"mintPrivate(address,uint256)","36281b38":"uppercaseOf(string)","36285df7":"bonusWindow1EndTime()","3628731c":"addAddresses(address[])","3628ca60":"getEpisodeList()","3628e6f3":"BMTToken()","3629c8de":"activation()","362a0c27":"_withdrawWonCosFromGame(uint256,uint256,uint256)","362a198d":"nextBurnFeeAbs(uint256)","362a36b4":"bidFeePercents()","362af076":"createRequest(address[3],address,uint256[11],uint256,bytes)","362bd679":"updateFreeStorage(address,uint256)","362c160e":"changeWithdrawalDate(address,uint256)","362c78b9":"invitedReward()","362cb8ff":"icoSucceeded()","362cba6f":"PlotSale(uint256,uint256,address,address,uint256,bool)","362e2565":"returnDeposits()","362e4945":"lengthAddresses()","362e669a":"BarrosTest()","362ec5e2":"createProductionUnit5()","362f04c0":"participantCount()","362f5fb2":"getDogInfo(uint256)","362f74e7":"updateBatchSupport(bool)","362f8833":"stakeRoto(address,bytes32,uint256)","362fe943":"MainBridge(address,uint256,address[])","36304e91":"allFactories()","3631826a":"multiline(uint256,uint256)","3631ecd9":"privateStart()","36321001":"will()","363210c9":"_delegatecall(bytes32,uint256)","363221fe":"advisorTokens()","3632803f":"calculateGrapeSell(uint256)","3632b4d9":"withdrawCoin(bytes32,uint256)","36330b0c":"updateInitialZero(uint256)","363349be":"fillOrdersUpTo(address[5][],uint256[6][],uint256,bool,uint8[],bytes32[],bytes32[])","36335e19":"contributePublic()","3633b1ad":"createRealmSale(uint256,uint256,uint256)","3633c522":"GiftPoolContribution(address,uint256)","36344022":"testAuthorizedTransfer()","363487bc":"currentInterval()","3634a1b7":"createSeries(bytes32,string,bytes32,uint256)","3634b376":"GATcoin(uint256,string,string,uint8)","3634dcd8":"sub0(uint256,uint256)","36351c7c":"recharge(address,uint256)","36354b2f":"updateEtherAndtokenAmount(address,uint256,uint256)","3635e329":"getCurrentPeriodByEntity(uint256)","363626ad":"addressesToTotalWeiPlaced(address)","36371722":"chunk4IsAdded()","36382941":"changeTokenOwnerWalletAddress(address)","3638ae05":"transferETHtoProviders(address,address,uint256,address,uint256)","3638fb00":"transferOwnership(address,bytes32[3],bytes32[3],uint8[3])","3639dda5":"monthly_token_growth()","363a0903":"Creatable()","363a4708":"setMintFeeReceiver(address,address)","363ad06f":"getFrozenAmData(address,uint256)","363bc3a2":"alreadyAutoAirdropAmount()","363bf964":"setAddresses(address,address,address)","363c3747":"TestBalance(address)","363c51dc":"set_savings_goal(uint256)","363c6b81":"MAX_PENDING_REQUESTS()","363c76f3":"HLChain()","363c9bca":"runTimeAfterSoftCapReached()","363db35d":"IcoTotalSupply()","363dc725":"_unpackProtectionParams(uint256)","363dd19e":"summon()","363df59a":"UNGTToken(uint256,string,string)","363ef9dc":"APB()","363f7746":"validSignature(uint8,bytes32,bytes32)","363fa6b2":"renameChibi(uint256,string)","36400cd2":"ALM()","3640599c":"getPI_edit_6()","364083f4":"makeSale(uint256)","3640ca5b":"SupermarketKontrak()","3640e413":"YunPengToken(uint256,string,uint8,string)","3640f613":"cancelMatch(uint8)","3640f910":"LogEndSale(bool,uint256,uint256)","36422e49":"_createEtherDogWithTime(uint256,uint256,uint256,uint256,address,uint256,uint256)","3643d14b":"withdraw_to(address,uint256,uint256,uint256)","3645ebfb":"indFundDeposit()","36470665":"battleboardDataContract()","36471908":"ownerPerThousandShareForMating()","36475668":"getCommunityData(string)","3647b084":"setAmountBonuses(uint256[],uint256[])","3647b87a":"buildFactory()","364832cd":"isStrongHand()","36484ea0":"PHASE2_START_TIME()","36489775":"USDZAR(uint256)","364aa98d":"createDate(uint256,uint256,uint256,uint256)","364c7815":"addCredit(uint256,address)","364cc73e":"isEatingAndDrinking(address)","364d0b53":"getAddress(bytes32,uint8,bytes32,bytes32)","364d279a":"phase2Duration()","364d2a06":"queryCreatureOwner()","364ddb0e":"left52(uint256)","364ddc2d":"getmemberposition(uint256,address)","364deeef":"Sceatt()","364e022f":"buyProduct(string)","364e0af3":"_createEdition(string,uint256,uint256)","364e1c59":"publicsalesendTime()","364e69b7":"canBet(uint256)","364e74eb":"releaseTokenTime()","364ea9e7":"set(uint256,uint256,bool[],uint256[])","364ee75d":"getRoundEnd()","364f4896":"emission(address,address,uint256,uint16,uint16)","364f6695":"earlybird_coins()","365044a8":"priceDivider()","36516a8a":"publisherAddress()","3651b401":"commissionGetter()","3651b5df":"setTargetWallet(address,address)","36525c4e":"resetStorage()","36527357":"getUint(int256,address,string)","3653cf9f":"getOldESOP()","36540b3b":"amountFundPlatform()","36548b58":"arrayIndexOutOfBounds(uint256)","36555b85":"add(string,uint256)","36566f06":"togglePaused()","3656de21":"getProposalById(uint256)","3656eec2":"balanceOf(uint256,address)","36579ff6":"Burnable()","3657ba36":"getSharedAccountPw(bytes32,bytes32,bytes32)","36585cd3":"getBatchStartTimesLength()","3658964c":"totalBal(address)","3659078c":"DailyDivs()","3659467b":"registerName(uint256,bytes32)","3659887c":"isAlreadyUser(address,address)","3659a8b2":"bonusEnds1()","3659cfe6":"upgradeTo(address)","3659d90f":"month12Allocated()","365a5306":"loan(uint256)","365a86fc":"hub()","365af466":"failedWhitelist(address)","365b1b15":"upgradeKiOS()","365b29e8":"WEBPOUND()","365b5055":"isAccountFreezed(address,address)","365b94ad":"saleFinished()","365b98b2":"users(uint256)","365c2e95":"hasEnough(address,uint256)","365c81fb":"pubsaleRate()","365ccbef":"didTakeOrder(bytes32,address,uint256)","365ce233":"removeAccountReader(address,address)","365e304d":"DATE_31_DEC_2021()","365e808d":"transferFromHyperstakingdisbursementfund(address,uint256)","365ede48":"setReport(string,uint256,string)","365f6e9f":"getCellsSinceLastEvent(address)","365fe9fd":"isDistributionTransferred()","36600999":"fundRepository()","366077ee":"addToPot(uint256)","3660943d":"checkState(bytes)","3660a084":"transferSigner(address)","3660fcd0":"setGuestName(string)","36610cb9":"storeOptions(address,uint256)","36645e01":"Election(uint256,uint256,uint256,address)","3664a0ea":"getLastCallKey()","3664b12d":"erc223Activated()","36651d2a":"setDestoryAddress(address)","3665708e":"nextMinPlay()","3666750e":"fillHeldData(address[],uint256[])","3667551c":"Partial8Send()","36682d5d":"Transtoken()","366859c4":"job(address,address[],uint256)","3669acad":"_newChallenge(uint64,uint64,address,uint256)","366a4120":"release(uint256,uint256)","366a68dc":"setBlockLock(uint256)","366ac8e0":"LGCCoin()","366b6e9e":"secureUnapprove(bytes32)","366ba691":"CBX()","366bb03c":"totaTeamRemaining()","366bc343":"AssignFeeToWallet(address,address,uint256)","366bc401":"collectedUSDWEI()","366d2b4e":"CancelledBySeller(bytes32)","366df51d":"initializeMintableTokenFundraiser(string,string,uint8)","366dff9c":"walletAllowances(address,address,address[])","366e81d6":"TokenSold(uint256,uint256,uint256,address,address)","366e881a":"commitScores(uint256[],uint256[])","366f2d86":"paymentDue(address)","366f77b7":"checkChoice(uint8)","3670e072":"gettoday()","3672404e":"getServiceCount()","367265fb":"transferTokensManual(address,uint256)","36730467":"split(uint256,uint8,uint256,address[],address,uint256[])","36733fa0":"addRange(address,uint256)","36738b41":"Crowdsale(address,address,address,uint256,uint256,uint256,uint256,address,uint256)","36746413":"PrivateInvestment()","367488ce":"roulette(uint256)","36751a6b":"uploadCode(string,bytes)","36756935":"FinalConfirmation(address,bytes32)","36756a23":"constructor(address[],uint256)","3676049b":"setFundFeeAddress(address)","367605ca":"setApprovalForAll(address,address,bool)","36760fd2":"HULKtoken()","36767205":"increaseTokenLock(address,uint256)","3676b342":"createAddOn(string,uint256)","3677b5f2":"LATokenMinter(address,address)","3677c333":"authorizeBurnRequester(address)","3678933c":"isEpochDataSet()","3678f179":"crosairShipMinted()","367a0f97":"getReputationProblems(address,string)","367ad6ea":"redeemPack(uint256)","367afa7a":"_nextPrice(uint256)","367ba52c":"submitOrder(uint8,uint8,uint64,uint64,uint16,uint16,uint16,uint16,uint16,uint16,uint256)","367bbd78":"strlen(string)","367bc8d3":"TransmutedTransfer(address,address,uint256,address,string,string)","367bf2f9":"currentBlockHeight()","367c574f":"DIP_Pool()","367cad89":"alternative_Exchanges_links()","367ebb99":"deathData_a12()","367edd32":"enableContract()","367f0708":"ico1Raise()","367f20f6":"_unpackBaseDamageValue(uint256)","367f34de":"performALU()","36805961":"setStr(string,string)","368186ef":"DigiberyToken()","3682905e":"RICOStandardPoD()","36829419":"AddrInvestor()","3683b44a":"checkPrizeAlreadyReceived(address,uint256,uint256)","3683ec67":"CavsvsPacers425()","3683ef8e":"preSign(bytes32,address,bytes)","36840423":"AddAdrJullarTeam(address,address)","36842110":"wasCrowdsaleStoped()","36851957":"CustodianInterface(address)","36865384":"BuyShare(uint32,uint32,address,address)","3686ca3e":"beneficiaryWithdrawal()","3686d52a":"ppsBase()","3686edc7":"_getBmcDaysAmountForUser(bytes32,uint256,uint256)","3687e257":"TenantTerminate(string)","3687e921":"readInfo(address,uint256)","3687f24a":"setFee(uint128)","36880b82":"recordOwnerOf(bytes32)","368818aa":"FrozenMediaTokenFunds(address,address,bool)","3688632e":"setAvgSalesCount(uint256)","3688c272":"getTokenPriceListByIds(uint256[])","3688fa2c":"issue(address,uint64)","3689a651":"paymentFrom(uint256,bytes,address,address)","368a5773":"SpermLab()","368a5e34":"AIRDROPPER()","368aa9ca":"p_update_priceUpdateAmount(uint256)","368af7f3":"availablePonzi()","368b069d":"deployEscrowClone(address)","368b2842":"safeBatchTransfer(address,uint256[],uint256[],bytes)","368b3c81":"PTTYC(uint256,string,string)","368b8772":"setMessage(string)","368bf74e":"TEAM_LIMIT()","368d09d8":"requestOracleValue()","368d6b25":"setRushTimeChallengeRewardsPercent(uint256)","368daf8f":"goldMigrationsCount()","368dde4b":"currentCost()","368e5d4e":"BTC_SUISSE_TIER_4()","368e85ff":"IICO(uint256,uint256,uint256,uint256,uint256,address)","368f3492":"AnemoiSaleContract()","368f76a9":"bossCutPercentage()","36909ddd":"isATMHolder(address)","3690fd03":"CPLPrivate()","3691125a":"LianPaiToken()","36917dfa":"getPony(uint256)","3691dd11":"userApprove(address,uint256,uint256)","3692d61a":"log(string,bytes32)","3693396a":"getLastSignedTime()","36937781":"initialize_proposal()","369388cc":"EMISSION_FOR_BOUNTY()","3693db0a":"FOUNDER_ONE()","36944e49":"secondRefundRoundRateNumerator()","36945328":"setAddrContractCaller(address)","3694566e":"getRate(uint256,bytes32)","3694569e":"IHateEos(string)","3694629a":"getQuestionFinalizable(uint256)","3695507b":"IRC_PER_ETH_PRE_SALE()","3695672b":"newBurnableOpenPayment(address,uint256,bool,uint256,string)","36958413":"weaponEntities(uint256)","36965e3a":"SetAElfDevMultisig(address,address)","3697d0a7":"renderLandingHash()","3697efb2":"MinerEdgeCommunity()","3697f055":"withdrawFunding(uint256)","36988bc4":"currentLoanPerson()","3698de0a":"soliditySha3(bytes32)","369ac28f":"deltaTime()","369b1ce5":"initialBuy(address[])","369badf1":"getCreditsAtIndex(uint256)","369bcd64":"_checkPixelUnder(uint256)","369cbbb4":"checkMonthlyLimit(address)","369cd460":"totalPilfered()","369d32f1":"Items()","369d8138":"createAsset(string,string,string,uint256)","369de07d":"PDTX()","369e2422":"updateTokenPricePerUSD(uint256)","369e8c1d":"commit(address)","369f927f":"initBlockEpoch()","369fe962":"getDisputeMemorySize(uint256)","36a013c8":"LogInvestment(address,address,uint256)","36a09eae":"SetPriceMultiple(uint256)","36a0f511":"getPeriodMinting(uint256)","36a128c2":"MyJioCoin()","36a1bbfd":"baseTargetReached()","36a1c184":"IsArt()","36a1fb5f":"changeUserStatus(address,bool)","36a23dbf":"freezing(bool)","36a26b99":"END_TIME_PRESALE()","36a26fd9":"TokenDeactivated()","36a2f0f1":"changeLocked()","36a31de5":"getRequestOwner(uint256,uint256)","36a33f99":"isLimitMint()","36a3668a":"teamTokensPerPeriod()","36a36f7c":"betexStorage()","36a39882":"_proceedStage()","36a42675":"combineInterest(uint8,uint8)","36a4f2ba":"createBtcAddress(uint256,int256,uint256,int256)","36a60891":"setTrainingFeeMultiplier(uint256)","36a6412b":"buyMicroKeysWithHandle(string,bytes32)","36a6ad58":"mintPartnershipTokens()","36a716da":"createOrderHash(address,address[3],uint256[5],int256)","36a7cf1f":"setBallotFactory(address)","36a9f2f7":"xactionFeeNumerator()","36aa972e":"FullPayChain()","36ab0f15":"getNewAllowancesEffectuation()","36ab753e":"startRefunding()","36abffd4":"_receiveFunds()","36ac732e":"updateSecondChangeBlock(uint256)","36ad6e46":"SendTokensToFounders(uint256,uint256,uint256)","36add1df":"interestDistribution()","36ae22f0":"emitFeePeriodRollover(uint256)","36ae31ec":"getCatOwners()","36ae5040":"isMinted()","36aec5a3":"amountContributed(address)","36af1954":"withdrawnReadable()","36af50fd":"setSale(address)","36af8151":"setSpareRecommAddr(address)","36b024ab":"setTransferableDate(uint64)","36b09474":"winningNumbersPicked()","36b1315c":"min64(uint64,uint64)","36b19cd7":"adminWallet()","36b222b3":"fillOptionOrder(address[3],uint256[3],uint256[2],bool,uint8,bytes32[2])","36b2e0f9":"acceptBidForCollectible(uint256,uint256,uint256)","36b2fe94":"setPurchaseAdmin(address)","36b324ff":"unMap(address)","36b33415":"modifyMemberInfo(string,string,string,string)","36b3da05":"chargeBalance()","36b40bb6":"leftOnLastMint()","36b61e3c":"otc()","36b641c2":"MakeMyToken(string,string,uint256)","36b69367":"parentFees(address)","36b77107":"lastDeposit()","36b81feb":"Deed(address)","36b97fd5":"TestToken5(address,address,address,address,address,address,address,address)","36b9856d":"newOraclizeSetProof(string)","36bacc7c":"getTentativeWinningPayoutDistributionHash()","36bb9ffa":"MANHATTANPROXYPARKAVE()","36bc32a2":"expectedPayout(address)","36bcb4c9":"changeAge(uint8)","36bcb4cd":"ViteToken()","36bdee74":"totalETH()","36be2a73":"setLedger(uint8,int256)","36bee178":"add_to_withdraw_bounty()","36bf094b":"BonusPeriodsCount()","36bf2e15":"ERC20ImplUpgradeable(address)","36bf392b":"distributeInvestorsFee(uint256,uint256)","36bffe1e":"nextCommonTTMTokenId7()","36c0aada":"setValueAll(uint256)","36c0c834":"buySignature(bytes16)","36c1a50f":"notZeroNotSender(address)","36c28466":"Panel()","36c2a922":"KryptopyToken()","36c2d72d":"getTotalSlaves(address)","36c35f94":"finalize1()","36c4a520":"Volks()","36c4ad0c":"getEthFromKeys(uint256,uint256)","36c4db09":"setCOO(address,bytes)","36c4ff7a":"payoutAddr()","36c5787e":"setTokensWave(uint256,uint256[10])","36c5bf8c":"_ownerReleaseLimit()","36c5d724":"removeToken(uint256)","36c5ff5d":"addToTransactionDisallowedList(address)","36c61b60":"_buyToken(uint256,uint256,uint256)","36c63b8d":"AbstractVirtualToken()","36c6a410":"BatanCoin()","36c7d4bd":"processReinvest(uint256,uint256,uint256)","36c802a0":"priceStage2()","36c84de5":"getPlayerDataByAddress(address)","36c8af5d":"_getId()","36c8c0e9":"addBonusBatch(uint256[],address[])","36c8c5ee":"voteForCandidate(uint256)","36c8e831":"PhillionToken()","36c92c3f":"setRoundDuration(uint256)","36c9c62d":"transfer_opt(address,address,uint256)","36ca97d6":"tokenFeePercent()","36cb4c48":"log256(uint256)","36cb8098":"BouCrowdsale(uint256,address,address)","36cb8740":"test_3_accessRestriction_vote_shouldThrow()","36cbee23":"bountyFunds()","36cc17a7":"clientClaim(uint256,uint64)","36cc18b5":"setPriceIdv(bytes32,address)","36cc1ebb":"setCCH_edit_13(string)","36cc6a10":"modifyTokenFee()","36cd24aa":"prepareVote(bytes32,uint256)","36ce94bf":"bytesToAddress1(bytes)","36cf7c87":"dead()","36cfe3eb":"starbaseEarlyPurchase()","36d0288c":"CL()","36d02c94":"changeSettings(uint256,uint256)","36d03356":"setAdvisorsTeamAddress(address)","36d10e45":"LemonsRemainingToDrop()","36d1535d":"getEbola()","36d15f2a":"_validateSettleSignatures(bytes32,bytes,bytes,bytes,bytes)","36d18b67":"RED()","36d1f54b":"UnitedfansTokenCrowdsale(address)","36d22de7":"pokerbox(uint256,uint256)","36d300b3":"addAction(uint256,uint256,uint256)","36d373c0":"writeDefinitions(uint8,string)","36d38bd4":"scs()","36d43c24":"withdrawId()","36d505cf":"_breedWith(uint256,uint256,uint256)","36d61112":"getVendingStepQty(uint256)","36d647cf":"bonusLine()","36d81f07":"getUser1()","36d90c2d":"Dillionworldcoin()","36d9377e":"GetAllNode()","36d938d8":"Transaction(uint256,uint256,address,uint256,uint8,uint256,uint256,bytes)","36d95f56":"MIN_FUNDING_GOAL()","36da1471":"crowdSaleCheck()","36da4468":"supplier()","36da5cd8":"atomToken()","36da9ec9":"roundTwoRate()","36dac2cc":"getMeta(uint256)","36dc1dd2":"createBSMHash(string)","36dc58f6":"total_SDCC_supply()","36dd20a7":"getJobWorker(uint256)","36dd58f2":"dispatch(address,uint256,string)","36de44e0":"GFC(uint256,string,string,uint8,address)","36df05bc":"wholesaleLeft()","36df99b6":"blackswanToken()","36dfe260":"payOneTimeReward()","36e0004a":"multiSig()","36e05d94":"fundariaShare()","36e0e824":"asset(uint256,bytes)","36e0f6cc":"allowSell()","36e4e8fd":"tulipToOwner(uint256)","36e4f915":"claimToken(bytes32,string,address)","36e520bc":"verifyAddresses(address[])","36e61cf7":"decTap(uint256)","36e685f5":"setCLevelAddresses(address,address,address,address)","36e6b92e":"taskProcessedWithCosting(uint256,uint256)","36e73918":"getRegionNextImageId(uint256)","36e9f43f":"SMRDistributionVault()","36ea76e2":"Hyperion()","36ea8189":"DetailsUpdated(bytes32,bytes32,uint256)","36ea8702":"makeMetaPublic(uint256,bool)","36eb3aa9":"LGBT()","36eb5b47":"getResoSCParams()","36ebc4dc":"__allocateTokens(address)","36eda23f":"setRST(address)","36edbe17":"createPlayer(address,uint256)","36ee1f2b":"SDTToken()","36ee46f5":"killAnimal(uint8,uint16)","36ee7773":"getBallotsStorage()","36ee83f9":"getOrderPriceTotal(uint256)","36ee8812":"updateReleasedBalance()","36eec28e":"allocated4Year()","36ef0cea":"createStartingColors()","36ef1abb":"disburseDividends()","36ef6c82":"addEmbassyOfCountry(address,uint256)","36ef80db":"getId(address,address)","36f00e8a":"setFeeFlat(uint256)","36f19b77":"getPurchasedBlockhash(uint256)","36f2393e":"changeTokenURIPrefix(string)","36f26095":"minimalCap()","36f2b803":"Oceans8RT()","36f3dc2d":"STAGE_FOUR_ETHRaised()","36f54767":"VitaminToken(uint256,string,string)","36f656d8":"assertEq(string,string,string)","36f66528":"EtherDelta(address,uint256,uint256)","36f78d77":"newGroup(address[],uint256,uint256)","36f7992b":"putOnSale(uint256,uint256)","36f7ab5e":"contactInformation()","36f7cd70":"setPricePerStake(uint256)","36f8edc2":"getPlayerShipBattleLossesById(uint64)","36f93a99":"cofoundersSupplyVestingStartDate()","36f9825f":"accountIndex(uint256)","36f9f49c":"etherandomSeed()","36faa509":"ssps(uint64)","36fbedd3":"existsAuditorFromMultiRequestAssignment(uint256,address)","36fc75ee":"setRegsitrarAddress(address)","36ff37f4":"UpdateEvent()","36ffa905":"getMyProposals()","370014f2":"sendFundHome()","370097ac":"donotUSBDappToken()","370099d4":"airSwap()","370158ea":"info()","37016a5f":"getAuctionStartedAt(uint256)","3701fada":"PFC()","370292eb":"clearApproval(address[16],address,uint256)","3702ab03":"buyBasicCards(uint256,uint256)","37033be6":"processReservationFundContribution(address,uint256,uint256)","37034853":"ownerHistoryCount()","3703d911":"createItem(string,uint256,uint256,address,uint32,string,uint32)","370419e5":"arm()","37048f8f":"_newValidatorSetCallable()","37049b06":"getTier(uint32,uint256)","3705f69e":"canRelease()","37072ec7":"getHealthCitizens(uint256)","37074dae":"receivedEther(address)","37077409":"_updatePurchasingState(address)","3707a967":"putForExchange(uint256)","3707cfc1":"update(uint256,uint256,address)","3707ed7e":"gettops(address)","37086c8e":"airdropWithLockup(address,address,uint256,bytes)","3708c99e":"openWhitelistEndTime()","370943e3":"ZionToken()","370b6939":"AdminSetDrawer(address)","370b8c90":"info(bytes)","370c6001":"abortTransaction()","370d4c6e":"setGameOn(bool)","370d62ad":"anyRateIsStale(bytes4[])","370e052b":"addPreSaleTokensMulti(address[],uint256[])","370e9161":"rollDice(uint256,uint256)","370ec1c5":"_fillOrder(address,uint256)","370f2827":"finishJackpot(uint256,uint256)","370f388e":"MegaCandy(address)","370fb47b":"triggerTime()","370fc812":"set_stopsell(bool)","370fed6e":"setProfile(string,string,string,uint32)","37110967":"eTokensToSend(address,uint256)","371115d1":"LamboToken(uint256,string,uint8,string)","3711d9fb":"saleDuration()","3711e829":"withdrawnAmountForSalePromotion()","37126b38":"getTime5(address)","3712880c":"changeTokenExchangeRate(uint256)","37128a12":"initBoostData()","371303c0":"inc()","3713513a":"TOKENO()","3713ab41":"WPXSold()","37142391":"GetPartManager(uint8,uint256)","3714ae13":"newTokenPrice()","3714e274":"mintAllBonuses()","3715ae53":"sendApprovedTokensToInvestor(address,uint256)","37164433":"withdrawConfirm(uint256,address)","3716b8b4":"DonatorSetBanner(string)","3716bd22":"showCertificationDetails(uint256)","3716ca33":"updateGenerationRatio(uint256)","3716f65d":"withdrawDthShop(address)","3717798b":"auctionStarted(string)","3717a7a7":"Omnic(string,string,uint256,uint256)","3717f34c":"divRemain(uint256,uint256)","37180750":"getTaskKeyAtIndex(uint256)","3718766b":"EventQuitBattle(address,uint256)","37189157":"checkWithdrawalAvailability(address,address)","3718a923":"canShelf(string)","3719427e":"acceptDividends(uint256,uint32)","371a4ea8":"getProposalById(uint32)","371aa158":"init(address[],uint256[])","371ab702":"getMicroModuleByIdPart2(uint256)","371be589":"getconfig()","371c7dba":"setAllowPriceUpdate(bool)","371db7af":"BlockPaymentSystem()","371dd5ed":"initRound()","371e8e27":"gameResultsLogged()","371ecfde":"_directTransfer(address,uint256)","371f468c":"GlobalSuperGameToken(uint256,string,string)","371fe247":"_checkHashAndTransferExecutorFee(bytes32,bytes,address,uint256,uint256)","37205d76":"isCrowdSaleSetup()","3720e5b6":"E_AuctionStarted(address,uint256,uint256)","3721ee15":"ownerAccessoryCollection(address,uint256)","372210d1":"addGenesis(address,bool)","3723100d":"mutiEthTransfer(address[],uint256[])","37235758":"currentEndsAt()","3723bc0e":"shareholders()","3723f149":"FOUNDATION_SHARE()","37247af5":"_recalculateAvailable(address)","3724fb24":"tradeSpreadInvert()","372500ab":"claimRewards()","37253e35":"defrostTokens(uint256,uint256)","37254184":"jvCoin()","3725814a":"getMaxAddresses()","37258302":"SubwooferToken()","37268dbb":"_internalExchange(address,bytes4,uint256,bytes4,address,bool)","37270069":"maxWeiRaised()","37270936":"commander()","37271cc7":"withdrawBid()","37273b86":"PRICE_STAGE_PRESALE()","3727ae2d":"AthTokenBase()","3728aa4c":"saleCapReached()","3728bec2":"getCharacter(uint32)","3728f1f7":"EthereumOne()","37292eeb":"AVAILABLE_COMPANY_SUPPLY()","3729847b":"processSalesForSingleBuyer(uint256,address)","372a2a36":"DigitalArtChain()","372a49bd":"mspController()","372c1aff":"getPublicKeys(uint256)","372c6533":"START_DATE()","372c66e3":"updateAsset(uint256,string,string,string,uint256,address)","372cb1d9":"CallCount()","372cd183":"addAdmin(address,bytes32,bool)","372cd7ad":"clearAuthOfPermission(address)","372cfcc3":"noteSaleLocked(address,uint256,uint256,uint256)","372d6b27":"getStatistics()","372e80c3":"FLIPPINESS()","372ea717":"test_oneInvalidEmptyAddress()","372ed8cc":"setOraclizeDelay(uint256)","372f6bfe":"_refererUpdate(address,address)","372f88b6":"ICC()","372fc8d3":"HTSupply()","372ff945":"isInPhase(uint256)","37305e2a":"withdrawFromCustody(uint256,address,address)","37306299":"BurnableToken()","3730bb40":"yxkTOKEN()","37321bd7":"callstoredaddress(address)","37323d19":"LuckyETH()","3732c86b":"doubleTransferWithBurn(address,address,uint256,uint256)","3732e153":"ETHPrice()","37334878":"SHORTADDRTOKEN()","37339506":"restrictedPercent()","3733b378":"transferStackAndCall(address,uint256,uint256,uint256,uint256,uint256,bytes32)","3733faba":"forceStopCycle()","3733ffca":"convertTo(uint256,string,string)","37354a68":"luckyNumberOfAddress(address)","3735ab75":"buyCastle(address)","3735d57d":"PRESALE_BONUS_LIMIT()","3736d853":"setAverageBlockTime(uint256)","37371bc5":"getRandomRouter()","37375a43":"createContractEditionForCollection(string,uint256,uint256)","37376ca8":"cancelProposal(bytes32)","37383c2d":"getEventStart()","3738aa19":"ReleaseFundsToInvestor()","3738eb8a":"GolfCoin()","37391ce2":"testUnescapedQuoteInString()","373a1bc3":"scheduleCall(address,bytes4)","373a3af8":"intersect(uint256[],uint256[])","373a7c01":"fundTotalSupply()","373ae230":"checkLimit(address,address,uint256)","373c1df9":"test_3_destoryTokensAccrossBlocks_increaseBlocksBy1000()","373c98a2":"authCall(address,bytes32)","373d46b0":"IPOI(uint256)","373dde4f":"countPurchasedPixels()","373e0c80":"setFreezeAccount(address,bool)","373e441c":"addUserRole(string)","373eef4b":"ABsCoins(address,uint256)","373f5ff0":"COLOR_GREY()","3740eee9":"SetFund(address)","37411dc3":"createRandomZombie_Ether()","3741b92b":"jrecover_y(uint256,uint256)","3741c90b":"setAuthorizedWithdrawalAmount(uint256)","3743f0bf":"teamReserveAllocation()","3746010d":"createPrizeFighter(uint16,uint256,uint8,uint8,uint8,uint8,address)","3746b446":"Predictor()","37472c4b":"setDepository(address)","3749ea8e":"contribute(address,address,uint256,uint256)","374abace":"contractstarttime()","374aed97":"getCells()","374b8cda":"getTrade(uint256,address,address)","374b94c8":"MEC()","374ba203":"get_hosp1(uint256,uint256,uint256)","374bb090":"isAddressSet(address,address)","374bfba7":"claimFreeReferralPack()","374e164c":"addVirusDef(address,uint256)","374e9aa1":"stageForBlock(uint256)","374f7b7e":"checkLoanStatus(address,uint256)","375023f2":"total0xbtcReceived()","3750e05a":"TOKENS_BOUGHT()","37516ead":"microTip()","375188dc":"nextTask()","3751e6bc":"get_last_global_audit_document()","37525ff0":"listItemFromRegistry(uint256)","37531b45":"StudentCoin()","37542d10":"addReferrer()","37548549":"setRecipientString(string,string)","37567d49":"maintenanceDeactivateUser(address)","3756b62b":"toB32(uint256,address)","3756bb45":"noOfTicketsOwned(address)","3756e207":"ExtremiumToken()","37574b3d":"TOKEN_FOR_TEAM()","37593f46":"queryN_fnc(uint256,string,bytes,uint256)","375a8131":"addStudent(string,bytes32,string)","375b3c0a":"minStake()","375b74c3":"custodian()","375c0117":"BurnTokens(address,uint256,bool)","375c21b0":"random(bytes32,uint32)","375c405d":"canIssueIndividual()","375c4627":"supplyPICO(address)","375c86dd":"m_pools()","375d6d90":"received_ethers(address)","375d9dc6":"isLimited(address,address,uint256)","375dce69":"getIssuable()","375e3ea8":"payoutForBudget(uint256,uint256)","375e88bd":"increaseBTCRaised(uint256)","375f2b96":"getCost(uint8)","375f3a9d":"PERC_TOKENS_TO_INVESTOR()","375f4498":"SetEditMode()","3760153c":"ETHero()","37603132":"RollLottery(uint64)","3760ceb0":"WAITTIMEUNTILWITHDRAWORTRANSFER()","37612672":"producer()","3761a3d6":"buyUcCoins()","3761d23f":"setFeeDistributionAndStatusThreshold(uint8,uint8,uint256)","3761dea8":"MarketPlace(address,address,uint256,uint256,address)","37621da0":"setMinChildCount(uint256)","3762346b":"externalPurchaseTokens(address,uint256,uint256)","37624204":"endPreIcoDate()","37629dda":"getArticleItem(uint256,uint256)","3762f0fe":"initMembers()","37632065":"claimUnderlying(address[2],uint256[7],uint8,bytes32[2])","37633f29":"TokensGate(uint256,uint256,uint256,address)","37638119":"getHouseEdgeAmount(uint256,uint256)","3763965f":"private_profits()","3763d4b4":"generalSaleEndDate()","3764cf3f":"NUMUS()","3764e2be":"setup(string,string,uint256,uint256)","37664643":"retractLatestRevision(bytes32)","376678e3":"BABYT()","37668a8b":"create(bytes32,address,bytes32,address,bytes32)","3766baba":"transferAllFromForcibly(address,address)","3767aec6":"handleTimedTransitions()","3767ea7e":"setTotalCapacity(uint256)","37680f18":"ERC20Standard(uint256,string,string)","37681083":"incrementReputation(uint256)","3768304c":"autoMint()","37689317":"generateLockedTokens(uint256)","3768bd09":"mulToFraction(uint256,uint256,uint256)","3769862f":"isAllowedUser(address,uint256,address)","376a4ce0":"setstring(uint256,string)","376b9c25":"depositProvider()","376c7374":"w_Bounty()","376d1555":"sendAuto(address)","376d567c":"setMod(address)","376db394":"setFreeze(address,uint256)","376ed9c6":"totalHedgelyWinnings()","376edf93":"getBidsByAdslot(uint256,uint256)","376ef9b8":"fromContractAddr()","376fc790":"fullTransfer(address)","376fc952":"setMaxReferrerBonusRequirement(uint256)","376fe102":"userId(address)","376ff7f0":"isRefundAllowed()","377002fb":"beArbitrator()","37714274":"FrancevsArgentina()","37717342":"breedOwn(uint256,uint256)","3771ab97":"payDividents()","37721ab7":"getDougName(string)","377272b3":"createValue(address,uint256)","3772c371":"getprize()","3773930e":"ConfigureFunction(address,uint256,uint16,uint16,uint16)","377481ca":"unlockedAddress()","3774e6f5":"starbaseMarketingCampaign()","37751b35":"doTransfer(address,address,uint256)","3777261d":"approvedFactories(address)","37775807":"buyerBalances(address,address,uint256,address)","3777f5d0":"tokensPerWeiBonus333()","3778e5b2":"groupInfo(uint32)","37790454":"PrintWinningInfo(bytes32,uint256,uint256)","3779a3b6":"saleRunning()","377a0f53":"bankAccount()","377ab651":"nextTurn(uint256,uint256[3],uint8[176])","377b2009":"isCanSell()","377b47a3":"logIn()","377c6a3e":"eth(uint256,uint256)","377d54ce":"assertOnlyParticipants(uint256)","377d78ce":"defineProjectWallet(address)","377dda1a":"NamiCrowdSale(address,address,address)","37800bde":"calculateTransferFee(uint256)","37806f07":"galleryOne()","3781afbc":"_isCorrectFullBuyin(uint256)","3781d882":"setRate347()","3781e576":"isOperatorForTranche(bytes32,address,address)","37820c57":"bulkMint(address,string,uint256)","378252f2":"closeAuction()","37828c52":"OTHER_STAKE()","3782cae2":"set_max_contribution(uint256)","37831b97":"payReward(address,address,uint256,uint256)","37848b6b":"getOwnedShipCount(address)","3784f000":"setEndDate(uint256)","378525bd":"bestAngel()","378544df":"timeAfterSoftCap()","378652d2":"MultiTransper(address[],uint256)","3787a30a":"ownerWithdrawEth(address)","3787b748":"WalletChange(address)","3788036f":"isAgreementSigned(bytes32)","37881299":"getCompare()","37881810":"setCallbackAddress(address)","3788e371":"BaldcoinCore(string,string,uint8,uint64,uint64,uint16,uint256,address[])","37890f94":"maliceReported(address)","378a2178":"tallyVotes()","378aa701":"getCurrentState()","378afddb":"withdrawMYB()","378b6a89":"canContribute(address,uint256)","378bc89d":"findAddress(bytes32,bytes32)","378c0605":"buyTickets(address)","378c4c1c":"computeMerkleRoot(bytes,bytes)","378c7cd9":"logCheck(uint256,string,uint256)","378c93ad":"setClaimable(bool)","378ca888":"setMaxFinalizationTime(uint256)","378cdb62":"proxyList(uint256)","378dc3dc":"initialSupply()","378e061e":"inactive_payable()","378e0fc1":"checkKwhDeployerAddress()","378e25f2":"withdraw_2Completed()","378ebf93":"setTokenToEtherAllowed(bool)","378efa37":"divider()","37900d5a":"issuedFromOtherCurrencies()","3790613f":"minChildCount()","379080da":"PRICE_MULTIPLIER_PREICO1()","379119af":"SJT()","3791759c":"migrateFeesDueToFork()","3791792a":"mintPack(uint256,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","37918bcb":"declareMvpLaunched(uint256)","3792a018":"left8(uint256)","3792a865":"MacroTokenContract()","3792e117":"GaiaToken()","37930615":"extend(bytes16[],uint64)","3793c1e8":"get_num_of_uses(address,address)","3793ccb3":"isPlayerOnBoard(uint256,address)","37941589":"test123token(uint256,string,string)","3795ad25":"lockStartDate()","379607f5":"claim(uint256)","37960cd5":"publicKeySize()","379698c1":"calculatePie()","37970dbe":"shouldAirdrop()","379725ee":"queryName()","3797528e":"IllusionDust()","3797b4de":"forwardRemaining()","37981c32":"pre_maxGoal()","37983aed":"getMyCards(address)","37986d2b":"freezeAndConfiscate(address)","37989eb6":"setOwnerBurner(address)","379930f7":"WHEEL_SIZE()","379986d9":"executeBurnProposal(uint256)","379995c3":"getDealerAndLuckyInfo(uint256)","3799bbd3":"privatePresaleAllocatingToken()","3799c5eb":"test_insert_findWithHintPrevRemovedUpdateHead()","379abed8":"ANPlaceholder(address,address)","379b7589":"signedTransfer(address,address,uint256,uint256,uint256,bytes32,address)","379ba1d9":"setTradingStatus(bool)","379ba2ab":"exchangeForQIU()","379ba3b7":"currSaleActive()","379c1bd9":"createHorseShoe4(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","379c5131":"getByOwner(address)","379c5d3f":"ModuleToken(uint256)","379c8f6c":"_keepLastTransaction()","379ca09e":"priceStep5()","379dbdeb":"accessAllowance(address,address)","379e00d4":"maxTextLength()","379e2919":"setDevFeePercent(uint256)","379e9957":"fiveMatchPayoutInPercent()","379f946a":"initGeneralAttr(uint32,uint64)","379fed9a":"isMasterOfCeremonyRemoved()","37a0b958":"DATAToken()","37a14b52":"changeICODates(uint256,uint256,uint256)","37a1c540":"founder1Wallet()","37a1c84f":"registerNameResolver(string,address)","37a2890d":"eraByIndex(uint256)","37a28979":"setSettings(uint256,uint256)","37a30d3b":"current_price_atto_tokens_per_wei()","37a31079":"pointsLimit()","37a31895":"withdrawSelect(address)","37a366d8":"loggedBalances(address,uint256)","37a38bb1":"StateChanged(uint8,uint256,string)","37a3931f":"invalidate(address)","37a47106":"create(uint256,bytes32,uint256,uint256,uint256)","37a58bb4":"KudosPollFactory()","37a59139":"estimate(string)","37a5ae1f":"withdrawSingleBucket(address,uint256,uint256,uint256)","37a5fbab":"SaleStart()","37a66d85":"setPaused()","37a6b9f8":"recordCallback(address,uint256,bytes,bytes)","37a6d42b":"participant()","37a7095b":"LeviathanToken()","37a74f7e":"p_update_currentPlotEmpireScore(uint256)","37a7983b":"changeminContribAmount(uint256)","37a7b7d8":"feed()","37a7f2b7":"MIN()","37a87dfa":"updateList(address,address,bool)","37a91776":"OSATOKEN()","37a920f1":"Universe()","37aa1689":"getIcoDiscount()","37aa7f91":"isAuthorisedMaker(address)","37ab8f20":"notifyPlayer(uint256,uint256,uint256,uint256)","37ab9dcf":"getCPFee()","37ac8236":"getPunchCardsOf(address)","37ac9153":"Retrieve(string,address)","37adf3a3":"hasRefBonus()","37ae31c7":"DemSinhVienRequests()","37ae43a3":"BetOnHashV81()","37af5c32":"ANYtoken()","37aff76d":"getSystemAvaliableState()","37b0574a":"isClassic()","37b0786a":"icoInvestmentWei(address,uint256)","37b0ac71":"confirmTeamWithdrawal()","37b0f257":"setConfirmAddr(address)","37b34974":"reverse(bytes32)","37b475d4":"SOFT_CAPACITY()","37b4d863":"maxbet()","37b4f299":"IMTERC20()","37b54140":"buyTokensForAddress(address)","37b5dce4":"PDP()","37b6efeb":"engraveDefault(bytes32,string,string)","37b7bf11":"Tile(int256,int256)","37b89705":"getAgilityValue(uint256)","37b8cade":"raisedEthAmt()","37b8db1a":"executeVerdict(uint256,bool)","37b9756b":"totalIssuanceDebt_limitedSum()","37ba1b4d":"Fpgcchain(uint256,string,string)","37ba682d":"END_TIME()","37bb223e":"CUC()","37bb25bc":"withdrawalLimit(address)","37bd0d28":"howManyFucksGiven(uint256,bool)","37bd1868":"setHatchedEgg(uint64,uint64)","37bd78a0":"secondsTimeLocked()","37bdc146":"weiFounded()","37bdc99b":"release(uint256)","37be04b4":"EZStandardToken(uint256,string,uint8,string)","37be827d":"Sum()","37c08923":"totalContributions()","37c0a5ef":"Finished(uint256,uint8,uint8,uint8,uint8,uint8)","37c30a98":"round_()","37c345cd":"specialManagerAddressMap(address)","37c35157":"updateTerm(uint256)","37c390e3":"allow_move(uint16)","37c3d50d":"buyAlt(address,uint256,string)","37c43088":"hashesSize()","37c44802":"initMonsterClassConfig()","37c57718":"ListingBought(bytes32,address,uint256,uint256,uint256,address)","37c62ed6":"createUnicornPriceInCandy()","37c6fcba":"LandlordTerminate(uint256,string)","37c74948":"getPropertyPrivateMode(uint16)","37c75992":"mintingIsFinished()","37c8d21f":"echo(string,string)","37c8f1d1":"AIgathaToken(address,uint256,uint256,uint256,uint256,uint256)","37caa8b6":"getTop(uint256)","37cb3c86":"distributeSlotBuy(address,uint256,uint256)","37cc7761":"contractReservedBalance()","37cc7cc0":"bannedCycles(uint256)","37ceb05b":"getFixtures()","37cef791":"getRate(address)","37d004b3":"bulkRelayCMCT(address[],uint256[],bytes32)","37d0208c":"bribe()","37d044cd":"tokenCreationPreSaleCap()","37d05434":"getCurrentRoundIssued()","37d1eb35":"setOffChainManagerAddress(address)","37d2649a":"Ownedfunction()","37d2d350":"setBOPSAddress(address)","37d33438":"totalHedgelyInvested()","37d3433f":"calculateAmountBoughtPreICO(uint256)","37d35507":"tokenCreationMinConversion()","37d365de":"admin_set_shopStoreRegister(address,address)","37d3ec7a":"ZBillionaire()","37d45088":"transferAllowed_(uint256,address,address,uint256)","37d48628":"totalSaleCapUnits()","37d4fc84":"Alpha()","37d76636":"item(uint256,uint256,bytes)","37d876b6":"GVTTeamAllocator()","37d9d7fc":"getBytes32(bytes32,bytes32)","37d9ffd1":"registerClient(address,uint32,uint256)","37da8058":"in_top_n(uint256,uint256)","37daa09e":"getUpCount()","37dac676":"getPOOL_edit_8()","37daf0ed":"getETHBalanceInfo()","37db0703":"isClean(string)","37db12c4":"PausePayment()","37dbbac4":"deleteMyEntity(uint256)","37dc414b":"balanceOfTarget(address)","37dc4b14":"setSpeedBump(bool)","37dd186b":"removePermission(address,string)","37dd5dd6":"poicoin()","37dda1ae":"setTktPrice(uint256)","37de1334":"rand16(uint256,uint16,uint16)","37de84d0":"createGame(string,string,bytes32[],string,uint256,uint256,uint256,uint256,uint256)","37df00c9":"receiveToken(uint256)","37df4828":"buy_planet()","37df6c03":"setAccountC(address)","37dfc70c":"getInvitationMultiple()","37e05590":"setKYCManager(address)","37e0e290":"numTokensSold()","37e12ab7":"checkGoalReach(uint256)","37e15240":"addRecord(uint256)","37e16f40":"currentAfterIcoPeriod()","37e246ad":"isOnAuction(uint256)","37e29e93":"BlueHillMining()","37e50f39":"awardPrizes()","37e531c0":"fechVoteNumForCandidate(address,uint256)","37e582b9":"LogRefundsEnabled(address)","37e58bd8":"GlowEther()","37e6b280":"verifyCommit(uint256,uint256,uint8,bytes32,bytes32)","37e6e03b":"setMultisigPre(address)","37e7a739":"Token3G()","37e822b8":"addRank(uint256,uint256,uint256,string)","37e87c7d":"OwnerManage(uint256,uint256,uint256,uint256)","37e8c09e":"getBet(bytes32)","37e922d7":"TERMS_AND_CONDITION()","37e94529":"setHardCapDividends(uint256)","37e94853":"TakerBoughtAsset(address,uint256,uint256,uint256)","37e9af0c":"IsAdmin(address,address)","37e9ebb5":"getExists(bytes32[])","37ea010a":"transferWithRef(address,uint256,uint256)","37ea1f63":"getWithdrawalCounter()","37eb6f91":"LiquidSwapToken()","37ebd0e0":"whitelist(address,uint256,uint32)","37ec33b7":"startDateOfUseTeamTokens()","37ec757f":"getStrFromId(uint256)","37ed2bef":"tokensToLock()","37ed89b2":"BitcoinPro()","37ede426":"WhaleWater()","37ee1837":"isCrowdSaleRunning()","37ee3edb":"buyTokensWithReferrer(address)","37efa397":"cryptoRomeWallet()","37f03888":"panicButton(bool)","37f0fa43":"PricingDay(uint256)","37f1353f":"PayPoolEntranceFee(string)","37f13fd6":"prova2()","37f1a470":"appoint(address)","37f1e7f2":"getPrice(uint8)","37f26746":"Remainder(uint256)","37f2beed":"getProposalVoterList(uint256)","37f2eaf6":"addTransaction(address,uint256,bytes,bytes)","37f33bd5":"EvenCoin()","37f344ff":"WhitelistedEarlyParticipant(address,bool)","37f3cb24":"testInitialBalanceUsingDeployedContract()","37f42841":"queryBalance(address)","37f4494b":"castLine(uint16,uint16,bytes32)","37f46e7e":"mintTokensByETH(address,uint256)","37f4c00e":"anchorGasPrice()","37f4dfea":"unsafeWriteBytes(uint256,bytes)","37f50f57":"wishes()","37f50f5b":"leggiFrase(uint256)","37f531ea":"_addHolding(bytes12)","37f534b6":"Blocform(address)","37f57d05":"StarterTokenBase()","37f7151b":"MTPToken()","37f7c4d4":"pow2()","37f80a58":"INVESTMENT_CAP_ICO_PHASE_ONE_POUNDS()","37f83291":"monuments(uint256)","37f86dce":"giveupBid(uint256)","37f9034d":"getAnimal(uint32)","37f944cc":"raiseBy()","37fa33fe":"EVATOKEN()","37fb217a":"valueForTranches(uint256)","37fb7e21":"distributionAddress()","37fbd30f":"etherHolder()","37fbec96":"totalTaxed()","37fc55bf":"give(string,uint256,string)","37fc91e3":"balanceWosPoolToTeam()","37fcb747":"TestERC20Token()","37fcb779":"sendAllFeesToAddress(address)","37fd25c7":"balanceOf(address[],address)","37fd6128":"tokenRate15()","37fd686f":"balanceOf(string,address,address)","37ff2506":"PRESALE_CONTRACT()","37ff65da":"Bugis_Crowdsale()","3800a119":"closeGateway()","3800d0a3":"get_proposal_count()","38014395":"originalAuction()","3801cde7":"Foodiecoin()","3801e6b6":"Cloud(uint256,uint256,string,string,address)","3802a4a2":"getEthDealRange()","3802d3ef":"totalTokensEmitted()","38039479":"setCandidate(uint256,string,string)","3803b7d3":"readAddressList(address,uint256,uint256)","3803f80e":"cancelCall(bytes32,address)","3804482a":"setMaxDistributions(uint256)","3804ab8d":"getTokensOnAuction()","3804c73d":"gameStartBlock()","380547c0":"addCompany(string,address,uint256,bool)","3806153e":"tier2()","3806422a":"stagesCount()","38075446":"shouldStopCoinSelling()","3807aabd":"generate(address,uint256)","3807ba1b":"poi()","380862b2":"getSynthesizeApproved(uint256)","3808ac11":"DXN()","38095a4a":"fccController()","3809b240":"settlementContract(uint64)","3809c0bf":"doInfinite()","380b5450":"getPrecomputedEToThe(uint256)","380ba30c":"confirmPrint(bytes32)","380bbf78":"getTokenIdOfAddressAndIndex(address,address,uint256)","380bf002":"mintCountByTemplate(uint256)","380c686d":"setTokenPriceByOwner(uint256,uint256)","380c7a67":"authenticate()","380d831b":"endSale()","380e5e44":"makeProposal(string,string,uint256)","380e809e":"batchTransferFromMany(address[],address,uint256[])","380f3087":"addHashes(uint256)","380f3771":"viewRand()","3811264a":"ErrorLog(address,string)","38116187":"buySpike()","38118614":"sigTeamAndAdvisersEDUSupply()","3812783e":"getDeployedEvents()","38131bc5":"redeemOrSellCoinsToICO(uint256,uint256)","38132838":"setProviderSupply(uint256,uint256)","3813a7f2":"getWineIdentifierAt(address,uint256)","3813be76":"currentGameBalance()","3814253f":"grantFoundersTokens(address)","3814a7a3":"CardsBase()","3814b764":"setBridgeWidth(uint256)","381501e6":"SwapManager()","38151862":"SHSToken()","38151930":"isTokensPreIcoDistributed()","38158549":"NENCToken(uint256)","3815c742":"Koyo()","38164d41":"SGDsToken()","381656e2":"declineAll()","3816d4ee":"iICO()","381731be":"approveAndCall(address,uint256,uint256,bytes)","38178fbe":"addString(string,string)","3817ffda":"_limitedTotalIssuingCollateral(uint256)","3818657b":"isActiveFreelancer(address,address)","3818d907":"addPrecommitment(address,uint256)","38194aab":"_addNewCompanyTraders(uint256)","38198c65":"totalEtherGooResearchPool()","3819986e":"createNewPoll(string,uint256,uint256,uint256)","3819ea68":"SimpleMarket()","381a0161":"TRONIXGOLD()","381a730e":"withdraw_3()","381abeb5":"RonaldoChain()","381ae69a":"createReferee(address,address)","381c215f":"SEXYCOIN()","381cec91":"isVestingStarted()","381d5441":"roger()","381db641":"distributeTokenAndLock(address,uint256,uint256)","381ee645":"lastBlock_v0()","381f4b9e":"RRROToken()","381fe9ca":"DgxDemurrageCalculator(address,address,address,address)","38200801":"getExtensionPublication(string)","3820a686":"canBurn(address)","3821891e":"requestRegistration(string,address)","38218aa1":"getBettorInfo(uint256,uint256,address)","38219832":"spendEther(address,uint256)","38222858":"setThrowOnIncompatibleContract(bool)","3822de0f":"kvtToken()","38235781":"checkICO()","382396ee":"getGameStatus()","3823d66c":"withdrawn(bytes32)","3823df95":"testPop()","38241c16":"setKYC(address[],address[])","3824d8ee":"buy100DaoFor1Eth()","3824ea31":"getHighScore()","38266b22":"getData(address)","3827d0bf":"_createDank(string,address,uint256)","38280e6b":"setTokenDistributor(address)","38284f36":"release(uint256,uint256,uint256,uint8[],uint256,uint256,uint256,string,string)","38285534":"gameDeveloperSupply()","3828b522":"serviceApprovedBy(address,address)","3828becc":"setBountyAmount(uint256)","3829111f":"BuyNowEvent(address,address,uint256,uint256)","382964a5":"withdrawForTeam(address)","38299afd":"recommendPaused()","3829dd22":"tokensForOneEth()","382b6f69":"test_oneInvalidEqBytes()","382c52cd":"transferableTokens(address,uint256,uint256)","382cbc79":"userDelete(address)","382cf0a6":"gamesPlayed(uint256)","382d39bb":"planCount()","382d606b":"CROSAIR_VOUCHER_PRICE()","382db937":"finishContributionPeriod(uint256)","382df05d":"getInvestmentByAddress(address)","382e5272":"addGameRecord(address,uint256,uint256,uint256,uint256)","382ef945":"Contributed(address,uint256,uint256,uint256,uint256,uint256)","382f431b":"open(bytes)","382f8411":"_createPassport(address)","382faa6a":"cancelToken(uint256)","382fc09f":"CoinVilaStart()","382fd819":"kyc(address,address)","38300f19":"setCAORatio(uint256[])","38302989":"getUsernameForAddress(address)","3830901a":"assignImmortalsToBattle(uint256)","3830ceeb":"totalriskcoinsSupplys()","38310f49":"weiMinimumAmount()","3831a8d5":"BurgerKapija()","3832677d":"partsMinted()","38331353":"MoreAI()","38350541":"_ownerOf(uint256)","38353104":"setBlockDotTimestamp(uint256)","38360ed8":"balance(bytes32,string)","3836a6d2":"setKYCLevelsBulk(address[],uint8[])","3836d3f4":"JapanvsPoland()","3836fe6e":"addPermittedContract(address)","38376154":"setGasForOraclize(uint256)","3837e9bd":"getGooCostForUnit(uint256,uint256,uint256)","3838a099":"aboutItem(uint256)","383a194c":"buyUnicornWithEth(uint256)","383bb22a":"setMinorEditsAddr(address)","383cf18f":"getGovtApplicationsCount(string)","383e3a5d":"buyPriceAt(uint256)","383e4b27":"submitRing(address[4][],address,uint256[6][],uint256,uint8[1][],uint8,bool[],uint8[],bytes32[],bytes32[],address,uint16)","383e9a3a":"claimTokensFromTokenDistrict0xNetworkToken(address)","383eea0e":"transferDevship(address)","383f61b3":"refundPlayersInRoom(uint256)","383fcd3a":"getLastPlayDateTime(address,address)","383fe467":"transferTokenOwnership(address,address)","383fe6d3":"setCentsPerMonth(uint256)","3840369b":"triggerEvent(int256)","3840d63d":"unknownReserved()","38416341":"getbetData(uint8,int8,address)","38419800":"taylorToken()","38421476":"changePaused(bool)","3842c57c":"petCollection(uint256)","38436c60":"transferEgg(uint256,address)","38439bb6":"update_tree()","3844426c":"EST(uint256,string,string)","3844e1c4":"getClientBalance(address)","38453f29":"registerCat(uint256,uint256,uint256,uint256,uint256,uint256)","384711cc":"vestedAmount(address)","38471dd6":"athenians()","3847807a":"stopGamGetToken()","38478ae7":"setMinterContract(address)","38495d66":"updateVault(uint256)","3849794f":"setDataSourceAddress(address,address)","384a6494":"setStartPreSale(uint256)","384af0de":"setMinimumprice(uint256)","384b1393":"follow(uint256)","384b93f2":"pullTheLever()","384baa8a":"round1StartTime()","384bb70b":"getData_17()","384bfacb":"cofounderIndices(address)","384c3335":"requiredToAddress()","384c440b":"DISTRIBUTION_TEAM()","384c4d2f":"reserveFeesInBps(address)","384d0b12":"claimByProof(bytes32[],bytes32[],uint256)","384db9fc":"WithdrawEther(uint256)","384ddc32":"JM_ETH_ExchangeRate()","384e04c9":"setarg_2(uint256)","384e2bf5":"MNLTOKEN()","384e5018":"etherandomCallbackAddress()","384f58eb":"contract_owner()","384fae3b":"hashDataStream(address,string,bytes32)","38503f55":"AdjustDifficulty(uint256)","38516064":"getFeePool()","3852c53f":"battlesTillBattleCooldown()","3853682c":"Try(string)","38536878":"getOwed(address,address)","3854bc2e":"setUSD(uint256)","3855323f":"updateKey(address,uint256,address,address)","38556c3a":"contract8function2()","38557648":"executeSellOrder(address)","3855b3dc":"GetEscrowNotifierAddress()","3855cf0e":"Proxyable(address)","3855dcd6":"getContrarians_by_index(uint256)","3855f32e":"keysRec(uint256)","385794c4":"MAGENDAVID()","38597911":"appendKeyValue(string,uint256)","3859d609":"raccoltaMessaggi()","385ab2d7":"allowSelling()","385ae665":"getNumberOfAnnotations(address)","385af1c3":"setChainPrev(address)","385c0ecf":"whitelistMaxWei(uint256,address)","385cd083":"tgeActive()","385d8590":"Committed(address)","385df389":"tokenURIEdition(uint256)","385e27ed":"testSubtract()","385e9e2e":"MintNFT(address)","385fae43":"setBetclose(uint256)","385fb8a6":"STAGE_3_MAXCAP()","385fbe24":"ListingContractEntity()","385fea5c":"countCliManagers()","38613690":"agentAddress()","38616105":"LogDestroy(uint256)","3861ee08":"EventBuyCar(address,uint32,uint32)","3862822d":"buyHo(uint256)","3862e6ee":"getEvaluationCountByRecorderID(uint32)","3862ea9d":"lockedBitmask()","386304e4":"receiveFromGame()","38634337":"CrowdsaleToken(uint256,uint8,address,address)","386381db":"fundariaTokenAddress()","38644538":"setAdditionPrice(uint256)","38649b2a":"isConstructedOwned()","3865bf3a":"joinNetwork(address[6])","3866ecdd":"forceWithdrawToken(address)","38670cb4":"founders_address()","386741fa":"onSubNew(uint256,uint256)","386762fb":"withdrawSnowflakeBalanceFromVia(string,address,address,uint256,bytes,bytes)","386892d8":"endICOStage3()","38689772":"FixBet16()","38692ca6":"setRegistrationPeriod(uint8)","3869416b":"getDisputeStartTime()","3869eaff":"USEaddress()","3869ffd0":"newIteration()","386a646e":"QDToken()","386b5fe7":"aelfDevMultisig()","386c5a74":"LogFeeTopUp(uint256)","386c69f2":"setCanBurn(bool)","386ca47e":"minCompanyValue()","386dd46e":"BTK()","386e0d75":"setPopName(uint256,string)","386e2b29":"registHnsBatch(bytes32[],address[])","386e3441":"tokensIssuedPrivate()","386e69dc":"nextRoundStartsAt()","386ee512":"Crowdsale(uint256,uint256,uint256)","386f36f3":"Deployed(uint256,uint256,uint32)","386fcda8":"testCreateCostToken()","387008c2":"updateStatus(uint256,bool)","3871b694":"LogSell(address,uint256,uint256,uint256)","3871bdd7":"depositPresaleWithBonus(address,uint256,uint256,uint256)","38721fa4":"getOperationCost(uint256)","3872b3ec":"setCoolDungeon(uint32)","387349fc":"numberOfTokensToAvail50PercentDiscount()","38734c33":"OnContribution(address,bool,uint256,uint256,uint256)","3873eeb8":"approveForBurn(address,uint256)","38742685":"pegglebot()","38743904":"moderator()","38752e58":"batchApprove(uint256[],address)","38756a89":"getLevelsCount()","38759ce9":"getFhMoney(uint256,uint256,uint256,uint256)","38760f13":"NewAccreditedInvestor(address,address)","387621fb":"cleanupDelay()","3876c137":"FRAC_TOP()","3876df0e":"ProjectWithBonds(string,uint256,uint256)","3876e05e":"appWallet()","3876e6d3":"securityTokenVersion()","3876f81d":"getPeriodBounus()","38771242":"completedAt()","387787ed":"setProperty(address,bytes32,bytes32)","38785014":"lastBlock_f4Hash_uint256()","3878f423":"remainingInvocations()","3879aa23":"firstCheckpoint()","3879c9f3":"teamCliff()","387a54d9":"callInternalTransfer(address,address,uint256)","387a76ce":"tokenChanger()","387b6c2f":"OwnedResolver()","387be94f":"minimumAmountRequired()","387bef56":"nodeAllocation()","387c0cb4":"hashRegistrar()","387d3821":"increaseMarketValue(uint256,uint256)","387d49d4":"setBountyBeneficiariesCount(uint256)","387da66c":"MCoinToken()","387dd9e9":"slots(uint256)","387e01fd":"ITO_TOKENS_PERCENT()","387e7bb4":"SingularityTest4()","387eaedb":"jypcBonus()","387ed59b":"hardCapTxWei()","387f4172":"GorillaSale(uint256,uint256,uint256,address)","388085be":"module(address)","38811792":"disallowWrite(uint256,uint256)","38812e58":"setStartTime(uint64)","38813ee0":"allEther()","3882f333":"partnerSaleTokenValue()","3882f742":"exitStake()","3883aee2":"checkGoalsReached()","388415e5":"Exchange(address,uint256,address,uint256,uint256,address)","38848911":"AmountRaised(address,uint256)","3884d635":"airdrop()","3884f307":"withdrawTo(address,uint256,address,bytes)","38856ecb":"assertEq5(bytes5,bytes5,bytes32)","38857786":"presaledeadline()","3885ce81":"avgEtherBetValue()","3885fd3d":"sendEther(address,address,uint256)","3886b116":"chkConsul(address,uint256,bytes32)","3886c957":"tokenLedger()","38874945":"developersWallet()","388777f1":"setlimits(bytes32,uint32[],uint32[],uint8[])","38879da8":"Transfer(address,address,uint256,uint256,uint256,uint256)","3887abb7":"checkPeriod()","3888188d":"releaseLockFoundation()","3888624b":"trueOrFalse()","3888dca0":"q_test(string)","388911dc":"sudoEnabled()","3889c8dc":"Payiza()","388a1526":"defaultTreesPower()","388a74ab":"validPurchaseSize(address)","388aef5c":"WAIT_TIME()","388b5786":"econReserveTimeLock()","388b9f37":"LogTokenDistribution(address,uint256)","388ba4b5":"COIN_SUPPLY_MKT_TOTAL()","388e28f9":"stop_all()","388f2c39":"recover(bytes32,bytes32,bytes32,uint8)","388f3cd3":"cashin(address,uint256)","388f58cd":"addMarket(bytes6)","388fb0af":"reservedTokensPercent()","388fe911":"new_tablet_created(address,bytes32,address)","38905bea":"lulaToken()","38906dbd":"Token(uint8,uint256,string,string)","38909b68":"getBonusUnlockAt()","3890d77f":"esopState()","3891c320":"vote(int256)","3892be14":"payoutPreviousRoll()","3893966d":"distribute(address[],uint256[],uint8)","389435e8":"calculateTotalWithdrawableAmount(address)","389439bb":"OwnerSigneture(address[])","389441b2":"getvaluejoinlist_even(uint256)","38948c53":"finalizeable()","3894ca57":"catOwners(bytes5)","3894e516":"generateToken(string,uint256)","38953534":"BTCEX()","3895f466":"buyoutWithData(uint256,string,string,string,string)","38960027":"aliveSince()","38969d64":"changeZipper(address)","389755a7":"setDefaultTransferRate(uint16)","3898ee61":"generateTicketData(uint256,uint8,uint8)","3899ad41":"unlockSecondary()","389aa67c":"addOrder(string,address,uint256,uint256,string,address)","389ab31c":"networkDevelopmentWallet()","389ae4d1":"foundersKey()","389b5bd2":"CryptobullsCoin()","389b7533":"extendDeadline(uint256)","389b75d6":"resetPool(uint32)","389cabee":"ceoWallet()","389cd1ae":"setGasPrice(uint256,uint256,uint256)","389d9636":"buyDiamond(uint256)","389db4f1":"_adjustDifficulty()","389e40d2":"PACOIN(uint256,string,string)","389e4839":"setState(bytes32,bytes32)","389eb9f9":"withdrawalTime()","389ece2f":"changeTelephoneOwner(address)","389f0846":"balanceUpdate(address,address,int256)","38a003e0":"getOrderAddressesForDay(uint256)","38a0615f":"TabooToken()","38a0fc9a":"registerPool(string,uint256,uint256,uint256,uint256)","38a0fdde":"setSnapshot()","38a1187d":"calculateEthAmount(address,uint256,uint256,uint256)","38a18cbe":"createTradeContract(address,uint256,uint256,uint256)","38a211b7":"lockTopLevelDomainOwnershipTransfers()","38a21db8":"create(bytes32,bytes32[3],bytes32,bytes32)","38a2cd0f":"setData_3(string)","38a2fb4f":"TransferBaseContract(address)","38a326e4":"activatedSalesTotalCount()","38a332eb":"EndGame(address,uint8,uint256)","38a4045e":"despoit(uint256)","38a4ba0b":"getAdPriceHalfDay()","38a52fb1":"setEthPlan(address,uint256,uint256,bool)","38a57d0c":"buildShip(uint16,uint16,uint8,bytes32)","38a5e016":"acceptTokenOwnership()","38a699a4":"exists(bytes32)","38a6e813":"updateAllowedAddressesList(address,bool)","38a74bbf":"endGameInternal()","38a7543e":"issuers(address)","38a8a0ca":"DeadCow(address,uint256)","38a964d6":"getFeeValue(address)","38a9a6f8":"bonusPreset()","38a9f25a":"PlayerLab()","38aa156c":"getKeccak256Address(address,address)","38ab0287":"nextMintPossibleTime()","38ab8ef4":"RelentlessConscienceToken()","38abdf41":"CraigGrantShrimper()","38af3eed":"beneficiary()","38af4eff":"tokenCents()","38b025b2":"parseInt16Char(string)","38b09889":"VictorieumNewToken()","38b0ea85":"startRedemption(uint256)","38b15dab":"setMyTokenBalance(address,uint256)","38b3e983":"Better(uint256,uint256,uint256)","38b52627":"supportsInterfaces(address,bytes4[])","38b5491b":"getInvestmentProposal(uint256)","38b56ead":"setURIToken(string)","38b59359":"ChangeEthPrice(uint256)","38b59be6":"addPercents(uint256,uint256)","38b5e0fe":"numElementsEven()","38b6e407":"endGrantAuthentication(address)","38b7a530":"addToAvgRating(address,address,string,string,uint8)","38b88052":"staleTime()","38b90333":"CONTRACT_VERSION()","38b93440":"replaceModule(string,address,bool)","38b9499b":"circulationStartTime()","38b9d61e":"bonusLimit4()","38b9ef9c":"betWithRound(uint256,bytes32)","38bb3977":"JuventusvsRealMadrid()","38bbbceb":"test_failed_payment_nonthrowing_token()","38bbfa50":"__callback(bytes32,string,bytes)","38bbfc51":"FCOIN1050Token(uint256,string,string,uint256)","38bc01b5":"getAddresses(bytes32[])","38bc1b96":"_airdrop(address,uint256)","38bcdc1c":"getURL()","38bd44f3":"createSDCC(address,address,uint256)","38bd8357":"next_week_timestamp()","38bde636":"GoodBoyPoints()","38be706d":"__callback(uint256)","38beb446":"PlayerToken()","38beb67f":"getCertificateHash(address,address,uint256)","38bef35c":"CFCdistrubution()","38bf77c3":"setFeesPerTenThousand(uint256)","38c0ac5f":"signer2()","38c1b824":"transferBookKeeping(address,address)","38c20499":"accMinterTwo()","38c33862":"wineries(bytes32,uint256)","38c3d4ed":"PORNCASH()","38c4090b":"getMarketOrderValue(uint256)","38c4d4a6":"pairTransfer(address,uint256)","38c59de9":"getNumberInvestors()","38c5a3dc":"changeRealUnicornAddress(address)","38c67b73":"setCurrentStage(uint256)","38c68f8f":"right84(uint256)","38c72883":"DealFullyFunded(uint256)","38c73f9f":"by(bytes32,uint256)","38c7db75":"getUnredeemedBalance(address,address)","38c80857":"unlock1Y()","38c80fc3":"getWhitelistStatus(uint256,address)","38c8e611":"getPreorderInfo()","38c8ec85":"convert1(string,string)","38c9027a":"calc(uint256)","38c92ef0":"propose(bytes,address,string)","38c97949":"StandardGame()","38c9dbf3":"TEAM_STAKE()","38ca59cf":"createTargetedValentineRequest(string,string,string,address)","38ca60a2":"IBST()","38ca683b":"MARKTY()","38ca830c":"updateWhiteList(bool)","38caa2c6":"MaxCapReached(uint256)","38cb252f":"getBonusPercent()","38cb583d":"checkAndUpdateTokenForManual(uint256)","38cc17ee":"setGameState(bool)","38cc4831":"getAddress()","38cc639d":"_setUserAttribution(bytes32,address,uint256)","38cd2c1a":"TransferSellAgentSiteRegMulti(address[],uint256)","38cdaab1":"changeICOState(bool,bool)","38cde380":"changeWeight(uint256)","38ce1df8":"sideServicesCount()","38ce4d51":"canRedeemUTXO(bytes20,uint256,bytes32[])","38ce61b2":"transferAndFreeze(address,string,address,address,uint256,uint256,uint256)","38ceaf1b":"LicenseManager(address,string)","38cef1ab":"ESCBCoinPlaceholder(address,address)","38cf2087":"parametersAreSet()","38cf22e3":"getHoldingsSupply()","38d084b5":"address4a()","38d0e36f":"SBSEducationToken()","38d16011":"verifyKYC(address)","38d1ed57":"getTotalFeesDistributedCount()","38d28d4c":"setTicketCountMax(uint256)","38d28de3":"getGoldInfoWeight(address)","38d2b172":"lowCapTxWei()","38d33337":"RoundAHardCap()","38d335ef":"ShowTestB(bool)","38d40ced":"changelp15(address)","38d44ad5":"recall(uint256,string)","38d480a6":"bulletAddress()","38d4d73e":"isVotedGood(uint256)","38d52e0f":"asset()","38d560b6":"gmtAddress()","38d65020":"JackpotAccessControl()","38d67d88":"changeContractName(string,string)","38d762ef":"LogBurn(address,uint256)","38d7be3c":"WXBET()","38d888a6":"impToken()","38d93280":"ProfitContainer(address)","38dacaab":"teamTimeLock()","38db6dd3":"registerVoter(address)","38dbb74a":"initialize(uint256[],uint256[],uint256,address,uint256,address)","38dbdae1":"player3()","38dc25d1":"KMCToken()","38dc92bc":"NCP()","38dca34a":"AddStudent()","38dd22f0":"isOwnerOrAdmin(address,address)","38dea895":"auction(address)","38dec0fa":"RefundAdded(address,uint256)","38df6fb2":"CollateralPosted(address,uint64,uint256)","38dfe2f5":"getString2()","38e078b4":"FixBet76()","38e11779":"OriginalAddress(address,address)","38e1294c":"updateBuyStatus(bool)","38e288f1":"airdrop(address[],uint256,uint16)","38e29ef0":"ICO_BONUS_TIME_1()","38e2c296":"processJackpotDeposit(uint256,uint256,address)","38e3aaf1":"Error(uint256,uint256)","38e43840":"collected(address)","38e45c65":"endCall()","38e47639":"getHighWater()","38e48f06":"save(string)","38e48f70":"getDonation(address,uint256)","38e4b06b":"releasedTeam()","38e55e89":"SigmaToken()","38e586fd":"right5(uint256)","38e64f9e":"milestoneReached()","38e771ab":"refundAll()","38e7920a":"setTokenRate(uint256,uint256)","38e7a375":"textaaaToken(address,uint256)","38e8feed":"TokensTransfer(address,address,uint256)","38e91e41":"devHolder()","38e95d55":"amountToRaiseInUsdCents()","38e998a7":"buyLand(int32,int32)","38e9e6b5":"setClaimingCosts(uint256)","38ea1c4d":"setTransferCreditBot(address)","38eada1c":"addAddress(address)","38eaf913":"setDirectorNode(string)","38ec18c3":"changeAccountModifiers(address)","38ec6ba8":"getAddressOfName(string)","38ec8672":"newAvto(string)","38ec8736":"assertEq11(bytes11,bytes11)","38ecadac":"bountymanagerShare()","38ecdca9":"claimProduct(address,uint256)","38ed85b0":"_claim(address)","38eda0e5":"createCalcFunc()","38ededc9":"getNoteOwner(uint256,uint256)","38ee95ab":"_emitCapabilityRemoved(address,bytes4,uint8)","38eee93e":"scheduleCall(address,bytes,bytes,uint16,uint8,uint256[5])","38ef2dc0":"testSign2of3()","38eff6c6":"backETH(uint256)","38f0de1f":"_fFinish()","38f14845":"deleteUser(uint256)","38f196b2":"COR()","38f22b42":"viewSpecific(string,uint256)","38f41711":"updateCapAndExchangeRate()","38f42d41":"GameWin(address,uint256,uint8,uint8,uint8,uint256,uint256)","38f46240":"StartRefund()","38f4b734":"getShit()","38f4cc7a":"QtumToken()","38f50b6f":"modifyAuth(bytes8,bytes8,bool)","38f55e59":"doVote(bytes32)","38f736c5":"step(uint256,bool)","38f77d69":"getDistributeProfitsInfo()","38f817c5":"getUsersEnginesIds()","38f84614":"useGoldenTicket(string)","38f88ee0":"tokenOwnerRemove(address)","38f8f3cc":"quarter1()","38f98d09":"getWeaponValue(uint256)","38fa1570":"showDevCut()","38fa4029":"currentStageIndex()","38fab8c5":"lifToken()","38fdba18":"doSplit()","38fe48b8":"batchReturnUNT(uint256)","38fff2d0":"getPoolId()","390063f0":"fundsToMSF(uint256)","39009094":"Cooperium()","39009482":"returnTuple()","3900f8f6":"minusFreezingTime(uint256,uint256)","390209c1":"getMetadata(uint128)","390246b2":"bid(bytes32,uint8,bool,int32)","3902b9fc":"getBbAddress(address)","3902bf72":"donate(bytes32,bytes32,bytes)","3902cb92":"TERATO()","3902d417":"resumeAirdrop()","39035d56":"record(address,address)","39048f02":"setSchellingRoundReward(uint256)","3904c5c1":"sweepFunds(address,uint256)","3904e1bf":"userBuys(uint256,address)","39055172":"UpgradeTokens()","390576d9":"Sogan()","3905910e":"MultiEventsHistory(address)","3905cab8":"drpsToken()","39069d8c":"setRegistryAdmin(address)","3906f560":"SUPPLY_LIMIT()","39074f59":"getDelayedBonusAmount(address)","390a05a8":"getParticipantBalances()","390b4f0c":"NaGeBi()","390b8482":"fillWithHashes()","390c0ddd":"purchaseCollectible(uint256)","390c3434":"nextrafflenr()","390c5874":"getCashbackRate(address)","390ce0d3":"getSellOrder(uint256)","390d70f5":"getTransformTarget_miner(address)","390e16c1":"EXTENDED_SLACK_PERIOD()","390e4855":"MilestoneTracker(address,address,address)","390eca6b":"finish(string)","390ff134":"isApprovedFor(address,uint256)","39106821":"memberId(address)","3910814b":"diamondAuction()","391193ae":"getTotalF2()","3911e1e1":"totalEthxCollected()","3912253e":"betConditions()","39125215":"sendMultiSig(address,uint256,bytes,uint256,uint256,bytes)","3912572d":"TokenCLC(uint256,string,string)","3912657a":"lastBlock_f11Hash_uint256()","3912b99f":"FOUNDERS_SHARE()","391363b5":"reducetime()","3913848e":"changeMerchantChargingAccount(uint256,address,bool)","3913a0fe":"getPlayerAward(address)","3913d6e0":"burnEnergyAttributionToken(address,uint256)","3913f487":"RIPAC(uint256,string,uint8,string)","3914010a":"getPartnerCash(uint8,bool,address,bool,uint256)","3915111e":"getRoundPrize(uint256)","39166ee9":"holding(address)","391687e3":"raiseTraderRegistered(address)","3916a402":"ShowInfoStr(string)","391714f8":"closeSale(bool)","39179ef9":"BitcoinFast()","3917b761":"product2_sell()","39181e6c":"Monthprofitstart()","39192fd7":"mintReserveTokens(address,uint256)","391b11ce":"updatePartner2_vows(string)","391c44b2":"addToWhiteList(address,uint256,uint256)","391c918e":"transferFromOwner(address,address,uint256,uint256)","391d2eb4":"MottoCoin()","391ecc2c":"_setOwners(address[])","391efaf2":"getEscrowFullInfo(address)","391f2e96":"InvestCancel()","391f3b2d":"_nextPotJackpot(uint256)","39203874":"ALpay(uint256,string,string)","392087fd":"changeSoftCap(uint256)","392114b7":"sellingAccept(bool)","39221913":"_forwardT4T(uint256)","392327b5":"owner_set_fraction(uint256)","392338f5":"createPost(string,string)","39236bef":"claimGame(uint256)","3923afee":"allocateToEarlyContributor(address,uint256)","39246290":"getB2()","39246d75":"VersionModel()","3924b718":"m_tokenPrice()","3924f089":"getRunning()","392542fb":"unFreeze(bytes32)","39255494":"setAdminAccounts(address[3])","3925ad8a":"getRank07()","392603d3":"_getCsAddr()","3926384d":"setMaxWithdrawal(uint256)","392664e5":"GenesisAddressSale(address,address,uint256,uint256)","39269596":"endPrivateIco()","3927010d":"ownerPauseGame()","392752b9":"lifeFactor_iv()","3928bc8b":"setBoostData(uint256,address,uint256,uint256)","39293113":"earlyBirdCap()","39298633":"forceTransferFrom(address,address,uint256)","39298f4a":"listAssets(uint256,uint256,bool)","3929e43f":"proposalExpireAt(bytes32,uint256)","392a2cb6":"withdrawFromFailedLottery(uint32)","392aa4d5":"openRefund()","392c00a2":"mint(int256,address,uint256,bytes)","392c6238":"currentNiceGuyIndex()","392c623e":"docIndex()","392cb9ed":"DhaCoin(uint256,string,string)","392d42ae":"left38(uint256)","392da9b4":"fetchCancelledOrdersForMerchant(address)","392db91e":"genuine(address)","392e53cd":"isInitialized()","392e6678":"validCandidate(bytes32)","392eaafa":"HackDao()","392ec230":"PaymentForwarder(address,address)","392ec66b":"bobClaimsPayment(bytes32,uint256,address,address,bytes20,bytes)","392ecfa6":"buyWithTokens(bytes32)","392ee145":"jackPotA()","392f37e9":"metadata()","392f5f64":"roles()","392ffcfb":"test_twoValidAndInvalidEqAddress()","39300836":"fundCrowdfund()","3930d3dd":"minBuyETH()","3931845d":"registraAluno(address)","3931c9a8":"purchaseWithToken(uint256)","39332b05":"foreignBridgeErcToErcImplementation()","39333bbe":"tokenBankrollBuyIn()","39341dde":"unseatKing(address,uint256)","39347d52":"setMarketers(address)","39354244":"percentAllocationFeeNumerator()","3935ae8f":"POKERCOIN()","39363923":"invalidationBounty()","3936dbe4":"decimals(address,bytes32)","3936e99a":"releaseAssets(uint256)","39384126":"getCampaignValidById(bytes32)","3938bd78":"updatePayment(uint256,address)","3938faa1":"_emitErrorCode(uint256)","393a1955":"crowdfundingTarget()","393a4d34":"getStorageAddress()","393b011c":"setOwnerPercentage(uint256)","393b9b0f":"TransferPreAllocatedFunds(uint256,address,uint256)","393bb56e":"setApprovalStatus(address)","393bbbf8":"mokenName(uint256)","393cb7e3":"feesPerMillion()","393e0c63":"maxPreICOandICOSupply()","393e77c9":"minMonsterHit()","393eec7b":"setSafeToken(address)","393eefb8":"withdrawMyDividend()","393f4605":"getProviderWebsite(uint256)","393f7cd4":"init_dev_and_presale_allocation(address,address)","393fb37b":"gettruelevel(uint256,uint256)","39408c83":"icoFinishedDate()","3940e9ee":"total_supply()","3941456c":"frontendAddress()","39419d60":"grandConsolationRewards()","394218b1":"electNewMayor(address)","3942a979":"s6(bytes1)","39431308":"commissionPercentForCreator()","3943380c":"key()","3943807b":"insert(bytes,bytes,int256)","3943909e":"ScamStamp()","39443b8e":"canDeposit(uint256)","3944615c":"getCompanyAddress()","3944750d":"ACCEPT_EXCHANGE()","394479c5":"TestKeiosToken()","39451a88":"tokenBurn(uint256)","394580d2":"distributeManyTokens(address[])","394610cf":"tokensTotal()","39464884":"entryInfo(uint256)","3947050f":"randomTicket()","39478568":"isFounder()","39495f8e":"RealTract(uint256,string,string)","3949630e":"before_test_method()","3949b636":"doDaysFollowEachOther(uint256[])","394a0926":"addUnicorn(address,uint256)","394a3f61":"updateFollower(uint256,bool)","394a8698":"getTotalBondValue()","394b0ba9":"RetengoToken()","394bcb49":"updateClient(address)","394c21e7":"cancelOrder(address[5],uint256[6],uint256)","394cd121":"qryModuleDetail(string,string)","394d57a2":"EtherPriceUpdate(uint256)","394da86b":"WEECoin()","394dfffb":"GFCI(uint256,string,uint8,string)","394e0cdd":"standingOrdersByOwner(address,uint256)","394f4ec6":"User(bytes32,bytes32,bytes32,bytes32,bytes32)","394fc3a6":"MaecenasToken()","39500019":"voteWithSpecifiedAmounts(bytes32,uint256,uint256,uint256,address)","39500105":"egcd(int256,int256)","39509351":"increaseAllowance(address,uint256)","3950d1b2":"p1_duration()","3950f3a2":"disavowTokens()","39515e3c":"bonusOver30ETH()","39518b5e":"startingTime()","39527ed6":"withdrawTatAmount(uint256)","395382ee":"squareWins(uint256,uint256)","3953ca8b":"setPropertyRowColor(uint16,uint8,uint256)","3953f4a1":"setLastEditionOf(uint256,uint256)","3954a389":"c_MaximumFunds()","3954b4ee":"pricePerEther()","3955b070":"unhold(uint256)","3955b6af":"_createToken(uint256,address)","3955c147":"MatchmasterPrevails(address,address,uint256,uint256,uint256)","3955f0fe":"sellEggs()","3955f12e":"crowdSaleOn()","39564561":"isCapper(address)","3956e963":"Mydo()","39575795":"getBalances1()","395764ff":"OilToken(string,string,uint256)","3957f093":"calculateTokensAmountToSale(uint256,uint256)","39580054":"getOpponent()","3958884b":"unblock(bytes32)","3959b945":"getSolver(bytes32,string)","395a9ab3":"Success()","395acdeb":"lockedCounts()","395b6f71":"getOrderBookInfo(address)","395b9467":"totalSUM()","395c22c9":"submitNewPolicy(string,string,string,string,string,string,string,string)","395deefa":"RefreshDayBonus()","395ea0c9":"Medikia()","395eda08":"MINIPOOLS_LLV_FIFA_1()","395ede4d":"collectToken(address)","395eec79":"studInfo(uint256)","3960c001":"buy(uint32,uint16,uint32,bytes16,bytes32)","3960eddf":"SupeciesToken(uint256,string,uint8,string)","3960f787":"decrypt(uint256[])","39612b0e":"refundingIndex()","39614759":"toBase58Checked(uint256,bytes1)","39614e4f":"bytesToString(bytes)","39624847":"getNumWinners()","39625faf":"pokerbox()","3962c4ff":"TimeStart()","3962d9f1":"User(bytes32,bytes32,uint256)","3962f82d":"getTokensCount()","39631849":"transferOutBalance()","39633cee":"getCompte_39()","39635d13":"withdrawToTeamStep1(uint256)","39636504":"teamPool()","39637616":"setTimedCrowdsale(uint256,uint256)","39639fbd":"trackToken(address)","3963d0c1":"MonthlyPaySend(uint256,address)","39658245":"ChannelTimeout()","3965e75d":"cancelEnter(address)","3966291e":"StaticEthAvailables(address[])","396724c3":"getCCH_edit_1()","39673345":"EPCToken(string,string,string)","396773b7":"getHeader(uint256)","39681333":"get_last_global_audit_time()","396876bd":"mintAllowance()","39688256":"tokenHardCap()","39694f47":"totalUnClaimed()","396bf78a":"WalchainToken()","396c8228":"purchase(uint16,address)","396d1ddf":"totalAdvisor()","396e70e0":"reducePlayersJadeProduction(address,uint256)","396ed0ab":"Burn()","396ff799":"setFoundersTokensWalletMaster(address)","3970f698":"tokenForSale()","39714adb":"trackHolder(address)","397182ef":"buyInSharePrice()","3971ee42":"promo(address[])","3971eea1":"bidReferral(uint256,uint256)","3972323a":"lockedBalances(uint256)","39737ea4":"proposalData(string,address,uint256,bytes)","3973e87e":"betSizeFINNEY()","397412cb":"setMinPrivateSaleBuy(uint256)","39745791":"removeWhiteList(address[])","3974874b":"drop(address[],uint256)","3975e32b":"RequestTest(bytes32,bytes32)","3976304e":"topupEnergy(uint256)","397656c6":"enableTuneOption(uint256)","3976b022":"LOG_SuccessfulSend(address,uint256,uint256)","3976be0b":"DCToken(uint256,string,uint8,string)","39774576":"isMiBoodleToken()","39785281":"winAmount3()","39785550":"withdrawAnyERC20(address,address,uint256)","39787fbd":"payeeArray(uint256)","39788bc8":"approval()","397895f3":"HoldChanged(address,uint256,uint256)","397986a1":"setUpAllowance()","39799e5d":"test_updateKey_missingId()","397a6b3d":"PrizeResultCalculated(uint256,uint256[])","397ab649":"Bet(address,uint256,address,uint256,uint256,uint256,address,uint256)","397b3378":"rewardPoolSupply()","397b8b17":"buyTokensForFiat(address,uint256)","397b90a5":"issueReserveToken(uint256)","397de27f":"changeServicePercent(uint256)","397e0287":"setIdentityExtended(bool,bool,bool)","397e8091":"betFeeMin()","397e953f":"ERC721Contract()","397eb91b":"closeLoanOnBehalfOf(address,address,bytes32,uint256)","397edab9":"ChangeOperatorAccount(address)","397efdbc":"CodeMailStampSale()","397f2a71":"getNbNamespaces()","397fa015":"updateCrowdsaleInfo(address,string)","397fe617":"CROSAIR_PRICE_THRESHOLD()","3980b680":"isHolidayToday()","3982b10d":"read_collectors_addresses()","3982b55d":"XCareToken(uint256,string,string)","3983af00":"setYearTwoMultiplier(uint256)","3983d5c4":"calcBaseFee(uint256)","398427e6":"sendByCheque(address,uint256,bytes,uint256,uint8,bytes32,bytes32)","39846a67":"sol_clean(uint256,uint256)","39849771":"maxBetDivisor()","39849a67":"isSpaceExist(uint256)","3984a89b":"updateFamedStarOwner(uint256,address)","3984ae12":"bountiesMinted()","3985a4ab":"crowdsaleEndDeclarationTime()","398712b5":"clearTheSeason(uint32)","3987fcb4":"setGasForFLKD(uint256)","39882a2d":"setUseWhitelistFlag(bool)","39885b23":"finishPreSale()","3988bad8":"pendingRewardsOf(address)","39895801":"allowPublicTransfer()","3989c666":"setRate(uint256,uint256,uint256)","398ab9a7":"totalPrizePool()","398af892":"Jimtoken()","398b35b1":"setShouldBlockPublicTrade(bool)","398bd6b2":"Cancelled(address)","398c1a89":"migrateOutByPayout(uint256[],bool,uint256)","398c7424":"getBalanceTokenContract()","398d07f0":"LightLemonUnicorn()","398d3c37":"getAyantDroitEconomique_Compte_1()","398d92bb":"withdrawTokens(uint256,address)","398e92a5":"updatePlotPrice(uint256,uint256)","398eb93c":"NardoT2()","398f0970":"secondsInBlock()","398f2648":"change_max_amount(uint256)","39900dcc":"totalBuriedCapsules()","39901be8":"getBoosterData(uint256)","39903398":"test_twoFalseAsserts()","399075da":"RES(address,uint256,string,string,uint8)","39907af1":"getSecurityValue()","39909f0b":"withdrawFundToOwner()","3990b7c7":"registerGold(address,address,bytes32)","39918c4f":"crowdsaleAllocation()","3991c09d":"addMatch(uint256,uint256)","3992503d":"TRIPAGO()","39927ebe":"registerGame(address,bool)","3992b494":"energyContract()","3994789d":"onICO(address,uint256)","3994b883":"SoccerBet(address,address)","3994bce4":"SALE_CAP_USD()","3995943b":"FUND_FRAC_TOP()","39960940":"registryRequestWeight()","39965233":"awardPrizes(uint256)","3998e2a9":"EBCoin()","39995511":"freezeAllTransactions()","3999968c":"mintRefCredits(address,uint256)","3999bbce":"SmartBitcoin()","399a24b1":"invokeFallback()","399ae724":"init(address,uint256)","399c0425":"buyingPrice()","399c6f55":"NewStage(uint256,string,string,uint256)","399cd55f":"ReferralRewarded(address,address,address,uint256,uint256,uint256)","399d6465":"getLockAmount(address)","399d7bf5":"against_ban_of(address)","399e3ca8":"PrivateSaleFinished()","399e7195":"CentraAsiaWhiteList()","399f6248":"ContractOwnershipBurn()","399fa840":"removeItem(address)","399fd8d9":"getDiaryLength()","399fdb86":"testFailNormalWhitelistReset()","39a12c3b":"Trade(uint256,uint256,bytes32,address,address)","39a13fb3":"enableTokenSale()","39a1e9ff":"SmallProject()","39a1ec37":"getInvestorDatePayout(address)","39a248f3":"feecounter()","39a26069":"housePercent()","39a2616c":"_removeDefaultOperator(address)","39a2a7bd":"confirmDeposit(uint64)","39a2b580":"_initialDistribution()","39a2bc8d":"SynchroCoin(uint256,uint256,uint256,address)","39a2eb2a":"selectWinners(uint256)","39a3f168":"secondPeriodWindows()","39a45a5c":"createGun(uint256,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","39a5a400":"TOKEN_SOFT_CAP()","39a5fdda":"earlyBackerSupply()","39a6ea72":"getEndICO()","39a73978":"unpackInvestment(bytes32)","39a7919f":"changeSupply(uint256)","39a7c3d9":"onMint(address,address,uint256)","39a7cb16":"retrieveCurrentTokensToOwner()","39a87bd9":"left31(uint256)","39a897fc":"Builded(address,address)","39a89c1a":"getNumberOfCapsules()","39a90f7a":"IS_MAINNET()","39a9144b":"_isTokenDiscounted(uint256)","39a9e6c5":"clearRequests()","39aa7599":"ITDollar(uint256,string,uint8,string)","39aaba25":"get_status()","39ac2d9b":"SuperTroopersRTscore()","39ac3300":"EtalonTokenPresale(address,address)","39ac7a08":"isMember(address,address)","39ad0212":"purchasers(address)","39ad8847":"fifth_withdrawal(uint256)","39ade9aa":"dDeployBallot(bytes32,bytes32,bytes32,uint256)","39ae662c":"setFactors(uint256,uint256,uint256,string)","39aee3b1":"CCCoin()","39af0513":"backlog()","39af0a81":"OPENCUKUR()","39b09ed8":"is_owned(uint256)","39b0b6c2":"updatePosition(address,int256,uint256)","39b0bc59":"getNonce(address,uint256,bytes)","39b0bde9":"Constrctor()","39b21937":"issue(address,bytes32)","39b22120":"contractBurn(address,uint256)","39b2447e":"addCutie(uint40,uint256)","39b25269":"makeOrder(address,address,uint256,uint256,address,uint256)","39b25ad1":"XcelToken(address)","39b26735":"TicTokenERC20()","39b333d9":"Play(uint8,uint8,uint8,uint8)","39b35753":"authCancel(address)","39b37ab0":"fee(uint256)","39b3fba8":"setRabbitData(uint256,uint32,uint32,uint32,uint256,uint8,bytes32,bytes32)","39b50688":"cancelSellOrder()","39b55e74":"developReserveAllocation()","39b57835":"multWee(uint256,uint256)","39b5ca6d":"MintFinished(address)","39b61914":"DescriptionPublished(string,address)","39b651c6":"paymentContractAddress()","39b6b1e5":"cancelBid(address,uint256)","39b73122":"createDataset(string,uint256,string)","39b73771":"_b3(string,uint256)","39b7e62f":"GENPCoin()","39b80e1b":"recoverAddressFromCommonSignature(bytes32,uint256,address,address,uint256,address,address,uint256,bytes)","39b83b68":"allowBank(string,address,bool)","39b8ce98":"weiCollected()","39b8dc40":"sunsetWithdrawalPeriod()","39b8e0ff":"proposeAllocation(address,address,uint256)","39b8e63c":"getPI_edit_9()","39ba645b":"revokeKYC(address)","39bbaed2":"SNOOP()","39bc91fa":"OwnerICOsupply()","39bea1f0":"coindropsWallet()","39bef274":"setRegionCoordinates(uint256,uint256,uint256,uint256,uint256)","39bf03b4":"NBAOnlineLaunchPromotion()","39bf5462":"MANHATTANPROXYWSHWY()","39c0c415":"toB32(uint256,uint256)","39c0ea6e":"rateProperty(uint256)","39c1852d":"withdrawal_party_b_gets()","39c2697c":"DELIVERED_FEE_FLAG()","39c27bd4":"substr(string,uint256,uint256)","39c28e82":"SSPParametersChanged(address)","39c294be":"minMargin()","39c2f6a0":"setConfiguration(uint256,uint256,uint256,int256)","39c38266":"manualBuy(address,uint256)","39c480c9":"endDate2()","39c5a13e":"secondVestAmount()","39c5dde6":"setInitialOwners(address[],uint256[])","39c5f3fc":"getNetworkId()","39c64f1b":"setPOOL_edit_5(string)","39c670f0":"claimedAirdropTokens(address)","39c73169":"totalSupplySale1()","39c7967d":"vote(address,uint256,uint256,string)","39c79cfc":"HJHToken(uint256,uint256)","39c79e0c":"close(bytes32)","39c7a376":"LogCreate(address,uint256,uint256)","39c7b6fc":"getMaxSend()","39c98a1b":"getCarOwner(uint32)","39c9ffe3":"deleteTeam(bytes32)","39ca6e86":"registryBase()","39cace6d":"PradxToken()","39caf7bb":"makeSwap(address,uint256,bytes32)","39cc8a8e":"GorToken()","39ccdd49":"createRef(bytes32,string)","39cd9dba":"KiwiCoin()","39cdde32":"ecverify(bytes32,bytes,address)","39ce3983":"debatingPeriod()","39ce743e":"replaceCharacter(uint16,uint16)","39cef0b7":"issueTokensForAssets(uint256)","39cfc56a":"ETHERanate()","39d00f12":"transferTokens(uint256,address[],address)","39d05fdd":"cetokToken()","39d08c2a":"saleOngoing()","39d1f908":"actualBalance()","39d2036d":"_validateMaxSellAmount(uint256)","39d20a5f":"read_user(address)","39d216f2":"chefOwner()","39d26051":"getOrCacheTargetReporterGasCosts()","39d2be30":"setDistributedAutonomousExchange(address,address)","39d319e5":"unblockUser(address)","39d31e14":"CoroToken()","39d34323":"product3_sell()","39d428ea":"AddToken(address,address,uint256,bool,uint256)","39d4e21a":"addToSellList(uint256,uint256,uint256)","39d51cc0":"get_testing_index()","39d66fc0":"effectiveValue(bytes4,uint256,bytes4)","39d8db86":"setICOPhase()","39d8dc9b":"BEST()","39dad8f5":"minusTourFreezingTime(uint256,uint256)","39dba209":"keysRec(uint256,uint256,uint256)","39dc5ef2":"depositTokens(address,address,uint256)","39dd134c":"advisoryPool()","39dd437b":"isWithinICOLimit(uint256)","39dea537":"registerNickname(string)","39df1608":"setPongAddress(address)","39e028ba":"AdviserTimeLock(address,address)","39e0c751":"setDiscountStage(uint256,uint256,uint256,uint256)","39e1038f":"getaddressfocuscardid()","39e1e859":"exchangeRateFUTX()","39e20523":"setWriter(address)","39e22509":"isCustomerHasKYC(address)","39e2637f":"TokenERC20(uint256,string,string,address)","39e301ff":"numWinnersToPay(uint32)","39e31ceb":"addressNotUpgradable()","39e33636":"EKK()","39e3407b":"isInFinalState()","39e395e2":"bidOnSynthesizingAuction(uint256,uint256)","39e3af9b":"isCanceled(uint256)","39e3ea83":"checkNotConfirmed(bytes32,uint256)","39e44ca4":"oraclize_network_name()","39e46ebe":"Quotation(uint256,string)","39e4dc18":"sendETH(bytes32,bytes32)","39e525f9":"resolveCallback(uint256)","39e53ca3":"updateUsersIndex(bytes32,uint256)","39e54c34":"_takeOffItem(uint256,uint8)","39e5a487":"BETSQUARE()","39e613d9":"mintVested(address,uint256,uint256,uint256)","39e65b46":"setIsRentByAtom(uint256,uint128)","39e7fddc":"feeAddr()","39e84cef":"EXT_COMPANY_STAKE_TWO()","39e851a3":"_isApproved(address,uint256)","39e899ee":"setWhiteList(address)","39e8bd48":"killMeshPoint(address,address,string,address)","39e8d1a4":"round1EndTime()","39e9eda1":"BackupChanged(address,address)","39ea68ba":"transferEntityOwnerPush(address,address)","39eabf7f":"bar(string,string)","39eb3491":"getMaximumPlayers()","39eb54d2":"bookExtendedVisit(uint256)","39eba5f9":"XXXXXXXX02(address[],uint256)","39ec68a3":"getRound(uint256,uint256)","39ecacac":"addContribution(address,uint256)","39ecc94f":"scamStampTokenAddress()","39eda73b":"jsonUpdate(string,string,string)","39edb660":"priceForDate(uint256)","39ede2b1":"SubmitNote(string)","39ef16f2":"Test2J()","39ef9105":"PhenixToken(uint256,string,uint8,string)","39efa270":"setClout(address)","39f05521":"withdrawVestedTokens()","39f165c6":"ParticipantAdded(address,uint256,uint256)","39f36220":"addThing(string,bytes32,string,string)","39f47875":"totalAmountOfWeiPaidToUsers()","39f4da78":"setSucessor(address)","39f4debc":"fillOrderAuto()","39f5b6b6":"fundsTreasury()","39f636ab":"changeRequiredSignatures(uint256)","39f64289":"quarter2()","39f64b52":"calcTokenPrice()","39f663ec":"isFundingFailState()","39f73a48":"fee2()","39f8e560":"setRewardAddress(address,address)","39f931b2":"placesSold()","39f95e63":"finaliseICO()","39fb1043":"_callRecipient(address,address,address,uint256,bytes,bytes,bool)","39fb435d":"initSiteSet(uint256)","39fc04f4":"setGftFundWallet(address,address,uint256)","39fc978d":"createCeleb(string,uint256,uint256[6],uint256[6])","39fd2003":"QPSEToken()","39fd615c":"complexityForBtcAddressPrefixWithLength(bytes,uint256)","39fdc5b7":"setExpectedStart(uint256)","39fded47":"Swap(address)","39fdf2fd":"OVERALLSOLD()","39ff8ff9":"CreatedBallot(address,uint256,uint256,bytes32)","39ffb234":"createContractScientist(string)","39ffd774":"getNamelessTouches()","39ffe67c":"withdrawOld(address)","3a000f23":"preallocate()","3a0046a3":"preIcoTokenHolders(address)","3a015ef9":"transferpoints(address,uint256)","3a01e53a":"getActivity(uint16)","3a02263c":"newController()","3a024d1c":"withdrawRewardedTokens(address,uint256)","3a027b26":"countDownToEndCrowdsale()","3a02a2cc":"addValidated(address)","3a03171c":"HARD_CAP()","3a035edf":"sendWinnerPriceToAll(uint256,uint8)","3a03ce87":"lockBatch(address[],uint256[],uint256[],uint256[])","3a051334":"adjustMOTFeeDiscount(uint256)","3a05369f":"getMax(uint32[])","3a060bc9":"isOnLent(uint256)","3a062acd":"LogEscrow(uint256)","3a067e64":"transferJackpot(address)","3a079bda":"AmethystCoin()","3a07e78a":"icoIsFinishedDate()","3a080e93":"rebondFromUnbonded(address,uint256)","3a089d17":"addressLength(address)","3a0936ce":"contributeMsgValue(uint256[])","3a0a377b":"new_id()","3a0aec6c":"distributeDEXT(address[],uint256,uint256)","3a0d6350":"batchTransfer()","3a0d649a":"fundsToBank()","3a0e0418":"Prepare()","3a0e2475":"etherDonation(bool)","3a0f12dc":"grantTokensByShare(address,uint256,uint256)","3a0f5500":"lastBlock_a6Hash_uint256()","3a1053a1":"TokenBlockPay()","3a10a614":"get_hidden_layers(uint256[])","3a11aa20":"mutiSendETHWithSameValue(address[],uint256)","3a11b6cf":"AnotherParticipant(address,uint256,uint256)","3a122e65":"SPECTRUM()","3a12e933":"startPublicSale(uint256,uint256)","3a134c00":"isFreeTransferAllowed()","3a1460ac":"mint(address[16],address,uint256)","3a14bf4c":"binomial(uint256,uint256)","3a15021a":"confirmAndForwardOnBehalf(address,uint256,bytes,bytes32,uint256[2],uint8[2],bytes32[2],bytes32[2])","3a157860":"freezeBlock()","3a15bbee":"changeInvestmentFee(uint16)","3a15e7ca":"migrateFromLegacyRepContract()","3a16c51e":"readyOracles()","3a16e81e":"determinePID(address)","3a16f2ef":"crowdsaleStop(bool)","3a1767e5":"callerAdd(address,address)","3a178d99":"isAvailable(uint256)","3a180fee":"sellQuantity()","3a190e60":"LeeroyPoints()","3a1a635e":"createNewRevision(bytes20,bytes32)","3a1ca19e":"get_property_layout(uint256)","3a1d9a7d":"secondPriceTime()","3a1e08e0":"setAllowedTokens(address,uint256,address[])","3a1e7130":"teamBonuses(uint256)","3a20bade":"registerIncome(address,uint256)","3a20e9df":"getProduct(bytes32)","3a21cb9d":"vestingAgent()","3a21ec8d":"bleachPrice()","3a22a593":"advisorAllocatedTime()","3a22a94d":"lockedTokensOf(address)","3a232c2d":"getCurrentBonusInPercent()","3a23399c":"getBidCountByToken(address)","3a237322":"superchain()","3a23a483":"approveTransferManager(address)","3a24d701":"doSuicide()","3a2524c1":"enableAllowBuy()","3a253cee":"removeOwnerRequest(address)","3a256daa":"getProposalExecutionTime(bytes32,address)","3a257fdc":"checkFwdAddressUpgrade()","3a2647cf":"addMessageToQueue(string,string,uint256)","3a283d7d":"templates()","3a289d1b":"updateEscrowGoalReached()","3a2960e1":"numAllocations()","3a29c32e":"MCBA(uint256,string,string,address)","3a29ff34":"tokenClaims(bytes32,address)","3a2a0af2":"MCSToken()","3a2b4cdf":"addAgree(bytes32)","3a2b9c37":"GxCallableByDeploymentAdmin(address)","3a2bc42b":"fundPrize()","3a2c7a37":"ICOstate()","3a2d8784":"getDepositMultiplier()","3a2f1289":"BitQuickpay()","3a2f6e57":"transferAnyERC20Token(address,int256)","3a300490":"MarkRead()","3a300d6b":"updateAccountAmount(uint256,uint256)","3a30452a":"withdrawOverflow(address)","3a306682":"GSContract(uint256)","3a30cdec":"postWalletPayment(uint256)","3a311b84":"SimpleNameService()","3a31427b":"AcceptTxTaskEvent(address,uint256)","3a314b24":"SendETH(address)","3a319eff":"NZToken()","3a323bdf":"internalBurn(address,uint256)","3a32a387":"lockAmount(bytes32,bytes32,bytes32)","3a333d30":"TelewaveCoin()","3a338256":"getarg_1()","3a344ab8":"DragonToken(address)","3a349d20":"getOpenBidsByLine(bytes32)","3a34f09a":"getRandom(uint8,uint8,address)","3a357b1d":"isCrowdSaleStateICO()","3a36399e":"address1()","3a3650cf":"eurRaised()","3a365403":"maxWeis()","3a373db7":"batchTransferToken(address,address,uint8,bytes32[])","3a375a92":"allowsAllowance()","3a377c82":"_magic(uint256)","3a37a917":"KHCToken()","3a38a08c":"verifyOperation(address,uint32)","3a38b90f":"fusionChibis(uint256,uint256,uint256,string,string,uint8)","3a3ab672":"isOnWhitelist(address)","3a3af53f":"getMasterNodes(address,uint256)","3a3b0382":"PLATFORM_FUNDING_SUPPLY()","3a3b955b":"enableExchange(uint256)","3a3bc0cb":"feeCoownerAddress()","3a3bdf56":"claimOwnerFee(address)","3a3cd062":"clientWithdraw(uint256)","3a3d12d4":"numberOfItemsForSale()","3a3d523f":"setTokenLogic(address)","3a3e49fe":"referalAirdropsTokensAddress()","3a3e8e84":"getAuthorizer(uint256)","3a3eda84":"blockNumberForVictory()","3a3f7279":"getProductRetailer(uint256)","3a3f8239":"claimOrder(uint256)","3a3fdf05":"remainAirdrop()","3a4027bb":"createWithReward(string,bool,uint256,address)","3a40c544":"exchangeERC20(address,address,uint256)","3a4148de":"setPreSalesSpecialUser(address,uint256)","3a4268e7":"doCall(bytes32,address)","3a42f7de":"changeShop(address)","3a447341":"SplendSale(uint128,uint128,uint128,uint128,uint256,uint256,uint128,uint128,uint128,uint128,address,address,address,address,address,address)","3a45268b":"LocklistAddressenable(address)","3a45af86":"modifyProductLimit(bytes32,uint256)","3a45d3ef":"setAllowanceBeforeWithdrawal(address,address,uint256)","3a4634e4":"changeCrytiblesAddress(address)","3a470b9e":"removeAccountMinter(address)","3a47de24":"Match()","3a47e629":"nCurves()","3a48f8c1":"removeFreelancer(address,uint256[],address)","3a49b95a":"getMyInvestment()","3a4a4233":"how()","3a4a921e":"revokeVested()","3a4ac98a":"tokensToEth(uint256,bool)","3a4b3664":"ownerBurn(uint256)","3a4b4532":"comission()","3a4b5e6d":"disallowOwner()","3a4b66f1":"stake()","3a4b948f":"hardBurnSMS(address,uint256)","3a4bece2":"CollectFromTransaction(address,uint256)","3a4c11b0":"setHydroStakingMinimum(uint256)","3a4cb854":"BrehonContractFactory()","3a4cba05":"SetCustomerInfo(uint64,bytes18,bytes32,bytes11)","3a4dcc88":"TronToken(address,address,uint256,string,uint8,string)","3a4de190":"repost(bytes32)","3a4e3342":"rate_BTCUSD()","3a4f6999":"maxNumber()","3a4faf7f":"max64(uint64,uint64)","3a50083d":"getRealXaurCoined()","3a500ae7":"JOYToken()","3a501155":"crowdSaleBalance()","3a50ccb7":"getMilestoneBonus()","3a5167e9":"forwardCollectedEther()","3a518b95":"functionName4(bytes32)","3a51d246":"getBalance(string)","3a525983":"TotalICOSupply()","3a531998":"getDisputeRoundDurationSeconds()","3a537b0c":"deliver(address,uint256)","3a5381b5":"validator()","3a551c6d":"HarborPresale(address,uint256,uint256,uint256,address,uint256,uint256,uint256)","3a559de6":"iGniter()","3a55f1f1":"BitcoinBravado()","3a562b78":"getOwnTokens(address)","3a573e02":"_badgeTotalSupply()","3a579abc":"withdrawTokensForEtheeraTeam(uint256,address[])","3a57e698":"registerGuide(address)","3a5860c4":"ETHERCExchange()","3a5b2080":"updateEducation(uint256,string,uint16)","3a5b5bde":"encrypt(string)","3a5d73d1":"airdrppReward()","3a5dd603":"chunk2IsAdded()","3a5e2576":"updateOwnerPercentage(uint256)","3a5ec2f8":"lemonsDroppedToTheWorld()","3a5eefc0":"EOSpace()","3a5f32cd":"updatePriceFreq()","3a600ce7":"sendToken(address,address)","3a60703b":"_transfer(uint256,address,address,uint256)","3a6120c5":"stopThinking(uint256)","3a6128db":"setLLV_edit_5(string)","3a6157cf":"richDatabase(uint256)","3a61738d":"calcReward(address)","3a618d26":"triggerRsclearRefund()","3a61dbfe":"ownerAddWorkRecord(address,uint256,bytes16)","3a621018":"unFreezeAccounts(address[])","3a62244f":"activateTransfers()","3a62a9d7":"AddressRegistered(address,string)","3a62cd2e":"currentCapEther()","3a62f663":"getAllPelvic()","3a63d886":"resource()","3a645c6d":"getLastTranche()","3a6514c8":"OddCoin()","3a669dd9":"TokenVesting(address,uint256,uint256,uint256,bool)","3a66caef":"ColuLocalCurrency(string,string,uint8,uint256,string)","3a672722":"ccSupply()","3a674500":"finalizeApprovedContracts()","3a677696":"setMigrateFrom(address)","3a67a0f6":"disableTransfers()","3a689082":"withrawFee()","3a693759":"changeRescueAccount(address)","3a699294":"Schmeckle()","3a69ab39":"getItemId(bytes4)","3a69db94":"multiDynamic(uint256[2][])","3a6a0474":"VisualTechnologyToken()","3a6a2a69":"lockAssetHolder()","3a6a43f4":"marketingTokenAllocation()","3a6a4d2e":"distributeFunds()","3a6ab569":"setMemberInfo(address,bytes32)","3a6ddf70":"sendit(address,uint256)","3a6e3d98":"calcCommission(uint256)","3a6eb318":"getMiningReward(uint256)","3a6f85b1":"TIER2_BONUS()","3a6fbacb":"currentAmountReceivedDeposit1Ether18Decimals()","3a6ffc92":"GetBetResult()","3a70491e":"incrementBattles(uint256,bool)","3a70eabd":"GetMinerUnclaimedICOShare(address)","3a7104d1":"updateFlag()","3a71386f":"functionName2(bytes32)","3a7221e0":"bestInvestorInfo()","3a72cd49":"preSaleFinishedProcess(uint256)","3a7327a3":"setAccessLevel(address,uint256)","3a7343ba":"setBeneficiary(address,uint256,uint256,uint256)","3a73b0ad":"HypeToken()","3a740a63":"getBonus(address)","3a74a767":"_setAdmin(address)","3a74b05b":"changeDesigner(address)","3a74c05b":"updateMasternode(uint256)","3a750183":"_commitHash(bytes32)","3a752c31":"HARDCAP_TOKENS_PRE_ICO()","3a7562ee":"addLegitRaceAddress(address)","3a762f73":"getRunningRazInstance(uint256)","3a764462":"enableTokenTransfer()","3a76a282":"getBlocksTillMatthew()","3a76abff":"_eraseNode(uint256,bytes32[],bytes32)","3a7749c0":"bonusRatePeriodTwo()","3a774b48":"register(address,uint256,uint256,uint256)","3a777ce0":"_C_sendToToteLiquidatorWallet()","3a77c91a":"setNotes(string)","3a789ffb":"setMinAndMaxEthersForPublicSale(uint256,uint256)","3a78e324":"updateIsAttached(uint256,uint256)","3a79311f":"Ploutos()","3a79a55c":"needsLotteryFinalization()","3a7a1ba9":"EscapeHatchCalled(uint256)","3a7a302c":"LogCrowdsaleStarted()","3a7a52d2":"HasCard(address,uint32)","3a7bd7b5":"isMixGen()","3a7befc6":"checkUserTokenBalance(address)","3a7c92af":"LogWeekRate(uint32,uint256)","3a7d22bc":"getElement(uint256)","3a7d280c":"login(string)","3a7d8df3":"ClubToken()","3a7e6854":"setnewPlayerFee(uint256)","3a7f5e2c":"LogFundsUnlocked(address,uint256,uint256)","3a7fb796":"mintGreen(int256,address,uint256)","3a80bd25":"CoinVillaTalk()","3a830a96":"Leimen()","3a8343ee":"confirmCustodianChange(bytes32)","3a838636":"withdrawTeam(address)","3a842044":"getDeviceById(uint8)","3a8468f7":"isToOffChainAddress(address)","3a84f002":"commitDispute(uint256)","3a8504b5":"NewSale(address,uint256,uint256,bool)","3a876e88":"setMDAPPSale(address)","3a878528":"setlvlNominalValue(string)","3a88594d":"isOptionPairRegistered(address,uint256,address,uint256,uint256)","3a8a0a5c":"prizeMoneyAsset()","3a8a7907":"getbetData(int8,int8,address)","3a8ac516":"toKiwi(uint256)","3a8b069e":"depositCreator()","3a8ba4f6":"removeResolvers(address[],bool)","3a8bcc91":"startPrice(uint256)","3a8c5065":"developer_add_Exchanges(string)","3a8d1eb1":"creditWinner()","3a8d6e5e":"viewKYCAccepted(address)","3a8ed5c4":"deathFactor_v()","3a8f1585":"createChannel(uint256,address,address)","3a8fdd7d":"getExchangeCost(address,address,uint256,bytes)","3a903dfa":"LEYBAERT()","3a911d30":"getAppsCount(address)","3a9143e6":"CCHToken(uint256,string,string)","3a91db97":"onNewCampaign(uint256,address)","3a920766":"WALLET_TEAM()","3a9214d2":"AsiaPropertyCoin()","3a9253a3":"BurnMe(address)","3a92a590":"YuanTaiToken(uint256,string,uint8,string)","3a9407ec":"abstractFunc()","3a94ab31":"_upgradeTo(uint256,address)","3a95152d":"getEvaluationCountByStudentID(uint32)","3a9588ba":"changeOwnerWithTokens(address)","3a95a332":"left57(uint256)","3a95a3c8":"init(uint8,uint256)","3a963033":"_addIndexGame(address)","3a96d16d":"setInitialAllocationTimelock(address,uint32)","3a96df81":"bbwallet()","3a96fdd7":"compare(string,string)","3a98c533":"getElementOwners(uint256[])","3a98ef39":"totalShares()","3a9c0ae7":"issueDividendReward()","3a9c7d3d":"maxMultiplierByAddress(address)","3a9c9ffc":"historyCount()","3a9d8be8":"moveAccountOut()","3a9db5a7":"_withdrawBonus(address)","3a9e7433":"scheduleCall(bytes4,uint256,uint256,uint8)","3a9e9d0d":"prizeCooldowns(uint256)","3a9ebefd":"decrement(uint256)","3a9eea12":"Impressio()","3a9f967e":"TOKENS_SOFT_CAP()","3aa0145a":"getFinalAmount(uint256,uint8)","3aa0396a":"mintFromICO(address,uint256)","3aa0eafb":"registrarUsuario(bytes32,bytes32,bytes32,bytes32)","3aa2ad63":"_setPlayerId(uint256,uint256)","3aa36dd4":"GetSaleInfo_Presale(uint8)","3aa3f154":"TokenSale(address,address,uint256,uint256)","3aa3f75a":"isOpenForSale()","3aa435a5":"DST_TEAM()","3aa4868a":"computeCacheRoot(uint256,uint256,uint256[],uint256[],uint256)","3aa49656":"phase2MaxEtherCap()","3aa51e41":"vaultFunds()","3aa5f4f7":"changeTokenSettings(uint16,uint256,uint256)","3aa5fe59":"hashAddress(address)","3aa612b9":"FT_TEAM_FUND()","3aa6608e":"processOrder(uint128,uint256)","3aa6c4f9":"withdrawableBalanceOf(address)","3aa6f0ee":"getRedemptionRequest(uint256)","3aa718d5":"changeDeveloperCATDestinationAddress(address)","3aa7429c":"TestX()","3aa89e83":"preICOActive()","3aa90889":"frozenPauseTime()","3aa935cb":"setDonationProportion(uint256,uint256)","3aa9376c":"releaseTokenSaleJM(address,uint256)","3aa94b1d":"getCoinStats(uint256)","3aaa36e6":"Fees()","3aaa3f24":"setPhaseSold(uint256,uint256)","3aaa74b2":"withdrawTips()","3aab3306":"SmartController(address)","3aab47b2":"UnpackDOT(bytes)","3aac430c":"TAKE()","3aac7661":"changeMonsterNickname(uint256,string)","3aaec03d":"kingGladiator()","3aaec5c5":"addToWhiteList(address[],uint256)","3aaf1898":"supplement(uint256)","3aaf3232":"maxRoundDelay()","3ab1a494":"setWithdrawAddress(address)","3ab1b765":"MainstreetCrowdfund(uint256,uint256,uint256,uint256,uint256,address,address,address,address)","3ab1e703":"roundMoneyDown3SF(uint256)","3ab207a3":"Flash()","3ab2dcec":"countCows()","3ab337b9":"addData(uint8,string,string,string)","3ab3bfc1":"splitFunds(string)","3ab4c395":"STARTING_SQUIRREL()","3ab50a9c":"getVersion(string)","3ab55c44":"getCurrentTokenPriceICO(uint256)","3ab562f2":"nextTarget()","3ab5657d":"getSourceConstraint(uint256,uint256,uint256)","3ab58703":"coldStorageYears()","3ab64c33":"beneficiaryMultiSig()","3ab71189":"_detailsLength()","3ab81062":"GOGO()","3ab89b78":"testFailHitPresaleCapPreDistribute()","3ab8e61a":"querybalance2()","3ab8ee2f":"HonestisnetworkICOregulations()","3ab966f4":"lastTokenPriceWei()","3aba9e9b":"WiredToken()","3abbf56a":"_setHourlyValueDecayRate(uint128)","3abc2106":"suicideContract()","3abcf3e7":"checkAssetListLength()","3abd0136":"totalBuyers()","3abd3a68":"summPartnershipsAndExchanges()","3abd8e4e":"getother()","3abdad4e":"totalCascadingPercentage()","3abdf792":"BATTLE_POINT_DECIMALS()","3abe2280":"updateTemperature(uint8)","3abee034":"emitRLC(uint256)","3abf30fc":"hash(bytes32,uint256)","3ac07183":"setDeprecated(bytes32)","3ac0feac":"getApprovedProposals()","3ac14078":"SEEDWhitelist()","3ac140e8":"distributorCount()","3ac163a7":"RepToken(address,uint256,address)","3ac19acf":"GenChipLevel_General(uint256,uint256,uint256)","3ac256d8":"getCurrentMilestonePostponingProposalDuration()","3ac2f3cc":"YinchengToken(address,address)","3ac31e02":"icoBalance()","3ac39d4b":"updateDarknodeDeregisteredAt(address,uint256)","3ac3a2fe":"teamPrizeClaim(uint256)","3ac4217c":"setJackpot(address,uint256)","3ac46b25":"getWithdrawableAmountPES(address)","3ac46e6b":"Irb()","3ac4aeeb":"amountFunded(bytes32,string,address,address)","3ac5cb73":"GeometricPonzi()","3ac6dd9d":"createPromotionalPurchase(uint256,uint256,address,uint256)","3ac70266":"setType(uint256,uint256)","3ac7d6fe":"pendingAddress()","3ac7fe84":"TestUtils()","3ac87121":"currentWorkStagePercent()","3ac8858b":"setMinimalBet(uint256)","3ac8b026":"storeShip(uint16,uint16,uint8,uint256,bytes32)","3ac8ca63":"beginContrib()","3ac9a77a":"createGen0Auction(uint256,uint16,uint16,uint16,uint16,uint16)","3ac9dfa3":"AgrolotToken()","3aca3788":"UCCoinSaleIsOn(uint256)","3aca9ffd":"createNewMsgAwaitingAudit(string,uint256)","3acab680":"SafeMath()","3acacfbe":"capitalFundable()","3acbd9eb":"doesOwnBase(bytes32,address)","3acbe450":"sow(uint256)","3acc2712":"partialUnlockAngelsAccounts(address[])","3accb428":"distributionMinter()","3acce2b2":"addRecord(string,address,string,address)","3acd8b80":"initExAlice(address,uint256)","3acddfc1":"marker()","3ace049e":"allowedSenders(uint256)","3acf4f9f":"ownershipUnits(bytes32,address)","3acf597c":"globalParams()","3acfad2b":"toB32(uint256,address,bytes)","3acfc185":"moduleAddress(string)","3acfd909":"getOption(string)","3ad0486b":"Token_1()","3ad04d8f":"setupFundingTime(uint256,uint256)","3ad06d16":"upgradeTo(uint256,address)","3ad075ea":"maximumSellableTokens()","3ad0d840":"setAvailableSeats(uint256)","3ad10beb":"cup()","3ad10ef6":"devAddress()","3ad14af3":"add(uint32,uint32)","3ad15258":"getProfits()","3ad17019":"changeDepositStopTimeFromNow(uint256)","3ad213e0":"connectOrderUser(address,address,uint256,address)","3ad359cf":"setDelegateWallet(address)","3ad389f2":"SanJaviercoinforwe()","3ad49222":"getMinimumAmount(address)","3ad520d8":"interestArray(uint256)","3ad55b83":"Tyzon()","3ad5b3a2":"createFunding(address,uint256,uint256,uint256)","3ad6f8ac":"getMaxClaimableWeiAmount()","3ad7c15c":"setDefaultClaimPercentage(uint256)","3ad84c89":"TXOsaleTwo()","3ad9248c":"fillInvestorAccountWithBonus(address)","3ad9801d":"importReward(address,uint256)","3ad9a928":"setFeePercent(uint256,address)","3ad9f722":"sendPoolMoney(uint256)","3ada121c":"Ballot(address)","3adb2de7":"bet_this_spin()","3adb3ad5":"querySeed(uint256)","3adbb3a4":"mint(uint32,uint32,uint32)","3add5a99":"getContractCreationGas()","3adda69a":"doBuy()","3addedd3":"getCostForAttack(uint8)","3adf7280":"getTotalHashRate()","3adf96d7":"_createProxy(address)","3ae01f84":"USDOracle()","3ae033a0":"payBounties(address[],uint256[])","3ae0e63f":"BtradeWhiteList()","3ae15692":"EEFcoin(address)","3ae1786f":"returnTokens(uint256)","3ae192bd":"changeFactorySubscriptionFee(uint256)","3ae2119b":"selfKill()","3ae24412":"addAddWhitelist(address)","3ae25075":"_getBonusAmount(uint256,uint256)","3ae26afa":"getRate(bytes32,bytes)","3ae34403":"stage1Bonus()","3ae46aed":"UruguayvsPortugal()","3ae49204":"setWaracoinPerEther(uint256)","3ae4b008":"createBounty(string,address[],uint256)","3ae50ce7":"createPresaleUnicorns(uint256,address)","3ae69708":"cryptaurBackend()","3ae7cdfa":"fipsLegacyRegister(bytes20[],address)","3ae7f938":"hash(uint256,uint256,uint256,uint256)","3ae83bd4":"transferFreeze()","3ae9133d":"coupon(uint256,uint16,uint8,bytes32,bytes32)","3ae983a8":"OriginalMyAccessControl()","3ae9b510":"getLatestMajorTree(bytes32)","3ae9de9b":"StatusSecurity()","3aeac4e1":"withdrawToken(address,address)","3aeaccf5":"Address()","3aeb512c":"updateTranscoderWithFees(address,uint256,uint256)","3aeb6c71":"vestingPercent()","3aeb850a":"DaysTillUnlock()","3aebe2a3":"GluuTokenCrowdSale(uint256,uint256,uint256,uint256,uint256,uint256,address,address,uint256,address,address,address)","3aec4439":"NSCBurnToken()","3aec5458":"callEmitter(uint256)","3aecca37":"newManuscript(bytes32,string,address[])","3aecd0e3":"getTokenBalance(address)","3aedded5":"PUBLIC_SALES_3_RATE()","3aedf90a":"wei_raised()","3aedfb8b":"withdrawl()","3aee0254":"addWinner(uint256)","3aee69bb":"changeTeamAddress(address)","3aef157b":"wingsTokensReward()","3aef3900":"proposalContract()","3aefaa75":"computeHash(string)","3aefaeb8":"setTransferRate(uint256)","3af05903":"deleteApprovedWalletAddress(address)","3af0dbc1":"contributionsOf(address)","3af1e17e":"createCelebrity(string,address,address,uint256,uint256,bool,uint256[])","3af242fd":"_createTrainer(string,uint16,address)","3af2b770":"BOBOTOKEN3()","3af32abf":"isWhitelisted(address)","3af34254":"LogChangeAccountAddressForSponseeAddress(address)","3af39c21":"undefined()","3af3c72d":"changeBonusUntilDate(uint32)","3af3db55":"channelValidator(uint64,uint64)","3af3f24f":"totalCalls()","3af41dc2":"adminDeleteRegistry()","3af5b3aa":"month48Unlock()","3af5dbb6":"mandateInBlocks()","3af6486e":"testStartNewCampaign()","3af690c2":"claimId(bytes32,uint256)","3af74940":"setRemainingTokenHolder(address)","3af75ee1":"storeBlockWithFee(bytes,int256,bytes,int256)","3af76638":"deployAndSetANT(address)","3af7d71c":"LogN(address,bytes32,uint256,string,bytes,uint256,bytes1,uint256)","3af826a4":"auctionCancel(uint256)","3af8286f":"ContractFPC()","3af8470d":"Rate6()","3af88261":"deleteTokens(address,uint256)","3af8e4ab":"backupOwner()","3af90f35":"requiresAuction(bytes32)","3af91491":"convertMinimalToSignal(uint256)","3af923ff":"CreateRCN(address,uint256)","3af946d2":"testnetWithdrawn(address,uint256)","3af94817":"getPongvalRemote()","3af9e169":"setStartIcoMainICO(uint256)","3af9f8ac":"ArrowCOin()","3afa476c":"unstash(uint256)","3afa895f":"deleteSecondaryAddress(address,address)","3afb01d4":"testGetProgress()","3afbf039":"pastTenMinutes()","3afc7282":"getVoting(uint256)","3afd4b5e":"coef()","3afd716f":"setVIPLibraryAddress(address)","3afdbd83":"Activate(bytes32,string,string)","3afdce53":"newCrowdSale(string,string,string,uint256)","3afe3a8a":"GetEntityDelegatedRevoker(bytes32,uint8)","3b0007eb":"MinterChanged(address,address)","3b0107fc":"calculatePerformanceBonus(uint256)","3b011b30":"getSeedForTokenId(uint256)","3b016d83":"getAllBonus(uint256,uint256)","3b01788a":"throwIfSetPresaleTokensAfterActivation()","3b0363fa":"summFutureInvest()","3b039176":"CreateEvidence(bytes32,string)","3b040fb8":"failedKycCount()","3b048123":"onlyInEmergency()","3b048284":"totalCoinCap()","3b0506f7":"getVoteByAddress(address,uint256)","3b05a861":"setEthDepositAddress(address,address)","3b066dd7":"BunkToken()","3b06903e":"reassignModerator(address)","3b06a6fc":"toggleAuthorization(address,bytes32)","3b0732a4":"interaddtoken(address,uint256,uint256)","3b078de3":"changeIsPayableEnabledForAll()","3b079e10":"manualTransferToken()","3b0819b8":"create(uint256,uint256,address,address,uint256,uint256,address,uint256,bool)","3b08d35e":"setAuditReportBlockNumber(uint256,uint256)","3b098c8c":"assertEq13(bytes13,bytes13,bytes32)","3b0a895d":"setUsdEthRate(uint256)","3b0a9555":"_callReturn(address,bytes,uint256)","3b0ad68a":"InitializedToken(address)","3b0b037a":"getPriceChange(uint256)","3b0c197e":"getBook()","3b0d2764":"SNT(address)","3b0da260":"revokeVesting(address)","3b0da3b8":"updatePolicy2(bytes32,string,uint256,uint32,string)","3b0f0f2f":"getReferral(address)","3b0f343b":"getDividendAmount(address,address)","3b0f3ed3":"attend(uint32,string)","3b1019ef":"getAdvisersConsultantsTokens()","3b102248":"withdrawFromBalance(address,uint256)","3b107682":"DualIndex()","3b111bf3":"EtherTwitter()","3b116370":"GalacticX(uint256,string,string)","3b11b577":"CampaignOpen(uint256)","3b130649":"div256_128By256(uint256,uint256,uint256)","3b13873c":"addValidationPreSigned(address,bytes32,uint8,bytes32,bytes32,uint256)","3b13f8a6":"setDealerCut(uint8)","3b143184":"Congress(uint256,uint256,int256,address)","3b143b51":"untrustedProposals(uint256)","3b14ab12":"GetAquiredAssetBalance()","3b15a398":"rewardContributor(address,uint256)","3b161361":"VoidAccount(address,address,uint256)","3b1663be":"changeAdvisor(address)","3b16c27a":"ta()","3b16f5f6":"releaseMultiWithStage(address[])","3b172a32":"bancorToken()","3b172fb9":"AuctusToken()","3b17ebb1":"adminAddWinner()","3b192105":"_getLastDate()","3b19a17d":"resetOrderIdTo(uint256)","3b19c868":"BookingUpdate(address,uint256,uint8,uint256)","3b19d67a":"dateICO()","3b19e84a":"getTreasury()","3b1a4170":"cmulpow2(uint256)","3b1a520d":"testSimpleBurning()","3b1b69f9":"Upgradable(string)","3b1b8ca0":"trustedClients(address)","3b1bebd1":"referee()","3b1cbad8":"getArraySize()","3b1cda49":"GetBaseN(uint256)","3b1d21a2":"getCash()","3b1e2542":"updateToken(uint256,address,uint8)","3b1ecef0":"private_getGameState()","3b1ede9a":"LOOMIA2_ADDR()","3b1ef91c":"NeyrosNetwork()","3b1fe51b":"changeTimestamp(address,uint256,uint256)","3b20c3f3":"rocketLaunch(uint256)","3b215823":"taxFeeBps()","3b22263c":"move(uint16,uint8,uint8)","3b2269cf":"systemAcc()","3b22c8e3":"resolveGameByHand(uint32,uint32)","3b23a5ca":"switchStatus(bool)","3b242439":"ratioDenominator()","3b25a6b9":"processDeposits(address,uint256)","3b25cf37":"PintOd()","3b265d35":"MatchingEngine()","3b270710":"ico1stPrice()","3b278f2a":"icoPaused()","3b2812ad":"newWindow(uint8,uint256)","3b283ff9":"TransferAllowanceFor(address,bool)","3b29c470":"calcTokensAvailableToBuyback()","3b29fe55":"isSecondLockTimeEnd()","3b2aa8cd":"getWeaponEntity(uint256)","3b2b7fec":"setCompte_21(string)","3b2b8ce9":"setAirdropped(address)","3b2dbb7f":"token2Player(address,uint256)","3b2f3d4d":"BitCoin(address,uint256,uint256,uint256,address,address)","3b2fd34d":"backProjectXOwner()","3b2fe781":"sendEth(address[])","3b304147":"draw(uint256)","3b305964":"accBonusTokens()","3b30ba59":"ZRX_TOKEN_CONTRACT()","3b31cbad":"ContractFunded(address,uint256,uint256)","3b33175b":"setWhitelistIn(address,bool)","3b338da0":"getActionsCount(bytes)","3b33fe73":"setAuctionPrice(uint256)","3b340ceb":"DWEToken()","3b343a13":"getNodeAddress(bytes)","3b3493d3":"lost()","3b355af6":"baseData()","3b3561ea":"PresaleCapUpdated(uint256)","3b356d71":"playerKiller()","3b3571f1":"setMinHouseClassic(uint256)","3b357f4e":"determineInviter(uint256,bytes32)","3b35cde5":"Genesis(address)","3b360c7f":"getInvestorsAndTheirBalances()","3b3672bd":"getAddressLength()","3b37044d":"WWWToken(uint256,string,string)","3b3783e7":"ETHLotteryManager()","3b393b03":"Zorro02Token()","3b39becd":"isMainSaleRunning()","3b3a1a7a":"tokenIdPointer()","3b3ae670":"getBaseRandom()","3b3b57de":"addr(bytes32)","3b3c0717":"switchRecycleAllowed(bool)","3b3c594b":"updateOldToken(address)","3b3c5aed":"addSpecialRateConditions(address,uint256)","3b3d5b88":"completeUnlock(bytes32,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","3b3d9485":"calcRandomNumber()","3b3dca76":"rand()","3b3df3d5":"tradeIn(address,uint256)","3b3e672f":"transferBatch(address[],uint256[])","3b3fa917":"setStartTimePreIco(uint256)","3b3fb38b":"rebuySum(address)","3b404266":"getDeployAt(uint32,uint32)","3b4159da":"voteProposal(address,address,uint256,string,bytes)","3b41b5f2":"setTotalProjectEscrow(uint256)","3b421f9e":"greeter(bytes32)","3b424f09":"setPermission(address,bytes32,bool)","3b427b20":"changeWhitelistCornerstoneStatus(address,bool)","3b428c9b":"tokenForWei(uint256)","3b42dfad":"saleWeiLimitWithoutKYC()","3b434169":"setUsdPerHundredEth(uint256)","3b43fa0a":"DSAuth()","3b441344":"setOtherRich3D(address)","3b442edf":"deathData_a14()","3b44383f":"TokenERC20(uint256,string,string,uint8)","3b462d5b":"bounty(address[],uint256[])","3b46321f":"setMultisendLimit(uint256)","3b4656a1":"removeAssociatedAddress()","3b4664f0":"addToResult(int256)","3b46a7df":"ivote(bool)","3b46aca3":"fetchSnapshotBlockByIndex(uint256)","3b4700fa":"releaseLockToken()","3b470582":"getOverall()","3b4719d0":"getJockey(uint256)","3b47513b":"onlyWhitelisted(bytes,address,uint256,uint256,uint256)","3b478fc5":"ethUsdRate()","3b4793fc":"sendGift(address,uint256,string)","3b47d37a":"RealTimeRayTracing()","3b47dab6":"setSaleMinter(address,uint256)","3b4920b8":"batchMintPresaleTokens(address[],uint256[])","3b495d6b":"Petcoin()","3b496f53":"IssueAccepted(uint256)","3b49a77b":"hasConfirmed(bytes,address)","3b49c216":"_createSchedule(address,uint256,uint256,uint256,uint256,uint256)","3b49f84b":"TokenD(uint256,string,uint8,string)","3b4a00b4":"unPauseBuy()","3b4a20f2":"getExternalFundsRaised(string)","3b4a40cc":"ManagerAdded(address)","3b4b7808":"returnEthReceived()","3b4c4b25":"setSupply(uint256)","3b4cb5e5":"GoldFees()","3b4cc7a3":"totalCompanies()","3b4d75d8":"withdrawRemainPrivateCoin(uint256)","3b4d900a":"NANO()","3b4dbf8b":"setSecret(uint256)","3b4e06e6":"getTokenAmounts(uint256)","3b4e8dbf":"tokenDev()","3b4fb68f":"LXKToken()","3b52147f":"LogFundsCommitted(address,address,uint256,uint256,uint256,address)","3b5251b7":"getPlayerVoteRewards(address,uint256)","3b52f2be":"winnersLength()","3b53f274":"LogInt(string,uint256)","3b540814":"transferFundWallet(address)","3b545d2f":"etherToSendCharity()","3b5535b9":"getLastWeekStake(address)","3b55d26f":"workDone(address)","3b561709":"initTransferArr(address[],uint256[],uint256[])","3b563137":"transferBeer(address,uint256)","3b574beb":"minTokensToBuy()","3b57aa90":"setHash(address,uint16,bytes32)","3b57fdff":"emitMint(address,uint256)","3b58524d":"setAddress(address,address)","3b58d5d7":"getPremiumCarSupply(uint256)","3b58f49a":"setMinBounty(uint256)","3b591ea7":"AmountToForgeTheNextBlock()","3b594cd0":"_delegateAssetOwnerRemoved(bytes32,address)","3b599b18":"ChainclubToken()","3b5a3357":"transferForFinanceTeam(address,uint256)","3b5a938a":"kick(uint32)","3b5adcef":"reservedFundsCharging(address)","3b5ae589":"Bitcash()","3b5b64f4":"conversionsCount()","3b5c020d":"BOT_ELEMENT_4()","3b5dd70b":"bigBonusPercent()","3b5e295c":"maxmoneypercent()","3b5e5376":"baseComparable()","3b5f24eb":"percentile(uint256)","3b5f30db":"EKKChain()","3b5fdb83":"buyP3D()","3b615624":"getEndorsements(bytes32)","3b61db4c":"stopIco(address)","3b61f5f5":"ChangeAuctionMaster(address)","3b623c19":"StripperToken()","3b626b83":"getWidthrawStatFor(string)","3b630493":"DAPPToken()","3b632a74":"getInterMixed()","3b64e77e":"enableCrowdsaleRefund()","3b653755":"seedMarket(uint256)","3b663195":"init(bytes32)","3b664dc7":"addRoleForUser(address,string)","3b666e48":"getCurHash()","3b668059":"ContractBalance()","3b66c415":"EmergencyWithdrawalFailed(address)","3b66d02b":"tokenFallback(address,uint256)","3b68f8aa":"deleteDonator(address)","3b69eed4":"updatePlanetName(uint256,uint256,uint256,string)","3b6b639c":"luckyStoneEarning()","3b6b9a5e":"fuckingkill()","3b6c35c3":"MubsToken()","3b6c6c72":"SALE_MIN_CAP()","3b6cbaeb":"OverseasReturneesToken()","3b6d05c7":"mdtTeamAddress()","3b6d2544":"Found(uint8)","3b6dde13":"getRandomNumber(address)","3b6e2970":"ContractStakeToken(address)","3b6e31bb":"isAllowedToUpdateProxy(address)","3b6e750f":"isAcceptedToken(address)","3b6e8ec3":"doProvideMemoryAccesses(uint256,bytes32,uint256[],uint256[])","3b6ea083":"startTimeIco()","3b6ed0a7":"processSteps(uint256,uint256)","3b6ed992":"STBToken()","3b6eeb23":"HighestBidChanged(address,uint256)","3b704588":"BCT()","3b709e8d":"WeiN()","3b70b171":"saveBlock(string)","3b70cf44":"firstRoundCosmosEnd()","3b7104f2":"checkStatus()","3b7169fb":"setopVaultAddr(address)","3b72a1b6":"approveDeliverable(bytes32)","3b7404bc":"createDepositProxy(address)","3b746963":"minLimitPrivateSale()","3b750f86":"DDJDTCoin()","3b751f7f":"claimThroneRP(string)","3b7616ff":"fwdToResolver(bytes)","3b76594d":"depositFunds(uint256)","3b768433":"getByReferenceCode(bytes32)","3b77227c":"_addIndex(address)","3b7773cd":"WanchainContribution(address,uint256)","3b784e9e":"SafeOwnable()","3b789750":"transferAllFunds(address)","3b7a3b7f":"thisVotersName()","3b7a8ff5":"addInvestors(address[],uint256[],bool[])","3b7b9d83":"marketToken2021()","3b7bfda0":"boolStorage(bytes32)","3b7cbfcf":"depositPercents()","3b7d0946":"removePool(address)","3b7da659":"changeLocalCryptoContract(address,string)","3b7dc55e":"onMintCalled()","3b7e9825":"appendArray(uint8[],uint8)","3b7f7cfa":"getValidity()","3b7f9649":"localsTruth(address,uint256)","3b7ff404":"getVotersPartyVote()","3b809273":"unlockedReserveAndTeamFunds()","3b80938e":"setDeposit(address)","3b80fac0":"updateVisa(address,uint256,uint256,bytes32,uint256,uint256,uint256,uint256)","3b80fc5f":"elc()","3b81a5a4":"assertEq23(bytes23,bytes23,bytes32)","3b81b785":"showVotes(address)","3b81caf7":"TransferAdminPending(address)","3b825302":"deleteTokenGrant(address)","3b82fe0e":"sellItem(string,string,uint256,string)","3b84333e":"FaucetToken()","3b84bec7":"setTIME_TO_MAKE_TOMATOES(uint256)","3b84edbd":"setRNG(address)","3b85746f":"existsCountsByName(bytes32)","3b86758a":"window3TokenCreationCap()","3b8678de":"setDefenceBoss(uint256)","3b871b4a":"awards(uint256,uint256)","3b874521":"withdrow()","3b87ec2d":"ecoSystemFund()","3b882832":"updateIsReverted(bool)","3b8908f2":"investmentsCount()","3b89332e":"verify_signature(uint256[4],bytes32,uint256[2])","3b893c2d":"icoTotalBalance()","3b895f28":"stageTwo()","3b89a83a":"adminRefund()","3b89be73":"registerUser(address,string,uint256,uint256)","3b8a3d5e":"setPI_edit_4(string)","3b8b4a61":"createRefund()","3b8dbf6d":"operatorSendByTranche(bytes32,address,address,uint256,bytes,bytes)","3b8e2a26":"weiCapReached()","3b8e603c":"outputb(bytes32)","3b8e6f2e":"balanceAt(address,uint256)","3b8ea9e7":"getValuePayment(address,uint256)","3b8ecdf9":"right3(uint256)","3b8eee6d":"checkDistance(uint256,uint256)","3b8f0ef4":"counterRequest(uint256)","3b8ff7be":"getBB0()","3b8ffa5e":"addVoters(address[],bytes32[])","3b90176f":"getTotalNormalTokensByAddress(address)","3b903521":"setModel(address,uint256)","3b9056bf":"userWithdraw(uint256)","3b9178f7":"transferEntireStake(address)","3b91c253":"getSkillNames(uint256,uint256)","3b91ceef":"setMax(uint256,uint256)","3b91ee26":"agency()","3b92015e":"setTokenDiscountThreshold(uint256)","3b92d384":"barrierStrength()","3b92f3df":"payment(address)","3b930294":"voteTokenBalance(address)","3b932584":"buyTokens(address,string,string)","3b942742":"totalCoinSupply()","3b947d2b":"removeStablecoin(address)","3b949785":"raiseDollarsWithdrawalCancelled(address,uint160,int160)","3b94b012":"restartMinting(string)","3b957b67":"getSumAmountOfDisputedStepsProDoctor()","3b95f23e":"deactivatePackage(uint256)","3b968963":"shortAirdropTime()","3b971f9f":"_tokenPrice()","3b97e856":"tokenDecimals()","3b9855ea":"experienceToLevel(uint256)","3b9901cc":"getChannelsByRanks(address,uint256,uint256)","3b9927df":"HVZSupply()","3b996f40":"quarter(uint32,uint32,uint32,uint32)","3b99915d":"getMarketWallet()","3b9aa6f8":"getRare(string)","3b9aaae4":"avt()","3b9bbb2f":"withdrawTotalBalanceCommissionWei(address)","3b9bd54d":"ClientsHandler()","3b9c0fdc":"deleteRound(uint256)","3b9c67e1":"Press(uint256,uint256)","3b9c7ac2":"claimLockedTokens()","3b9ca2d0":"migrate(address,uint256,address)","3b9e1497":"updateVirus(address)","3b9e9c91":"testSettle()","3b9ed710":"caculateFill(uint256,uint256,uint256,uint256)","3b9f7d6b":"m_unclaimedHolderIdx()","3b9f87a5":"setNeedToReserve(uint256)","3b9ff58e":"Academicon(uint256,uint256)","3ba04463":"p_setInvestorsPercent(uint256,uint256)","3ba0b9a9":"exchangeRate()","3ba1356c":"earnedOf(address)","3ba15036":"getWei()","3ba2a67e":"lockFund(uint256)","3ba2aaf2":"setOwnerToken(address)","3ba2cfc1":"createBitcoinAddressPrefixTask(bytes,uint256,uint256,int256,uint256,int256)","3ba308dd":"preSaleTokenBalances()","3ba72b88":"checkAvailability(address,address)","3ba7ecc0":"BuzFinancialStrategy()","3ba86465":"oraclizeQueryCost()","3ba87e3e":"setMultiRequestFirstRequestId(uint256,uint256)","3ba8b0a8":"setPendingSignatureStatus(address,uint256)","3ba8c9a7":"mintingFinish()","3ba8f108":"SetOwner(string,address)","3ba93114":"getEtherMonsterInfo(uint256)","3baa8170":"setName(string,uint256)","3baad248":"delWhitelist(address,address[])","3bab3088":"DOCTokenSale()","3baba4d7":"milestonesLength()","3bac2837":"SSAToken()","3bacf5ed":"changeTokenHolder(address,address)","3badca25":"batchTransfers(address[],uint256[])","3bae15df":"deleteOwner()","3bae795e":"ActionAuction(address)","3baf35fb":"nPayments()","3baf4e1e":"newPayment(uint256,uint256)","3baf6e3f":"setReferral(address,address,uint256)","3baf77aa":"increaseClaimsBalance(address,uint256)","3bafc5c0":"removeBankroll(uint256)","3bb0cc55":"tokensReceived()","3bb168a1":"isPresaleFull(uint256)","3bb197cf":"icoPhaseAmount3()","3bb1a882":"TradeListing(address,address,address,uint256,uint256,uint256)","3bb28957":"p2_start()","3bb2dead":"resolveAddressLight(address)","3bb33d56":"checkAtkPlayerQuest(address)","3bb3a24d":"getTokenURI(uint256)","3bb4218a":"requireContractExists(uint256,bool)","3bb4497c":"getAllProviders()","3bb54b4c":"LOG_ContractStopped()","3bb5a02c":"unsetAllowedMultivest(address)","3bb5d604":"ExchangeWhitelist(address,address)","3bb66a7b":"getETHBalance(address)","3bb735e7":"Arrholders(uint256)","3bb81b60":"total_bet_purchased()","3bb8a87f":"getConsideredTokens()","3bb8bd85":"TICDist(uint256)","3bb8da29":"GetWorldData()","3bb91c77":"calculatePayout(uint256)","3bb9f133":"listSimpleService(uint32,string,uint256,address,address)","3bba16da":"ifClaimedNow(address)","3bba21dc":"swapTokenToEther(address,uint256,uint256)","3bba340c":"dateMainEnd()","3bba72c3":"TzTToken()","3bbac579":"isBot(address)","3bbacb55":"STVCOIN(uint256,string,string)","3bbb0025":"ownerOfRobot(uint256)","3bbb11a1":"getImageMetadata(uint256)","3bbb44ca":"eth_is_seeded()","3bbca7b4":"ImpToken(string,string,uint256,uint256)","3bbe0b5c":"OKFCrowdsale()","3bbed4a0":"setRecipient(address)","3bbf41d9":"GameState()","3bc0461a":"devFee(uint256)","3bc058c7":"setBS(bytes32,string)","3bc17b28":"round3TokensRemaning()","3bc17fc3":"CreateNewPool(address,address,uint256,uint256,uint256,bool,address[],uint256,uint256)","3bc19bba":"webGiftSentAmount()","3bc1e0f1":"depositCoin(bytes32,uint256)","3bc261bb":"balanceTokenContract()","3bc273b0":"changeWelcome(string)","3bc2859e":"blockOffset(uint256)","3bc2b866":"getBla()","3bc2bc42":"AddSubscriber(address,string,string)","3bc325ee":"withdrawTokenToInvestor()","3bc3c7f9":"ERC20Token(string,string,uint256,uint256)","3bc45598":"update_SRNT_price(uint256)","3bc47fbe":"campaignEnded()","3bc4be52":"ownersTokenIndex(address,uint256)","3bc518ea":"getTokenBySelf()","3bc578fe":"getClosingTimeByStage(uint256)","3bc58532":"hodler()","3bc5a0b7":"updateBytesSetting(uint256,bytes32,address,string,string)","3bc5b73e":"_saleSupply()","3bc5de30":"getData()","3bc5f48a":"addBook(string)","3bc6db30":"settleAndClose()","3bc70184":"getPurchase(uint256,uint256)","3bc756d0":"NACToken(uint256,string,uint8,string)","3bc764f7":"depositCPT(address,uint256,bytes32)","3bc7ebac":"pinnedCode()","3bc834fc":"usersAddress(address)","3bc867f5":"getLockedEth()","3bc91e28":"setCurrentRound(uint256)","3bc983d3":"decreaseAssuranvePayments(address,uint256)","3bca915f":"NickSterBate()","3bcb1edb":"_payoutDividends(address,address,uint256)","3bcbb6d8":"Zarina()","3bccbbbc":"phase3TokenSold()","3bcd6624":"approveTokensAndCall(address,uint256,uint256,bytes)","3bcdbd22":"TweedentityClaimer()","3bce14c8":"numberOfRecentPlayers()","3bceb170":"raisedByAddress(address)","3bced141":"transcodeReceiptHash(string,uint256,bytes32,bytes32,bytes)","3bcf7d22":"newBribedCitizen(address)","3bcff3b0":"getProjectCount()","3bd04d69":"addWhiteList(bytes32)","3bd099d3":"ICO_RATE()","3bd0a6e5":"clickButton()","3bd0aa47":"modifyItem(string,address,uint256,address,uint128)","3bd0dd47":"getBackEther()","3bd0f412":"changeMin(uint256)","3bd10bf1":"_seekOdd(uint256,uint256)","3bd137e0":"makerDAOMedianizer()","3bd3593f":"_PurchaseInsurance()","3bd4aab7":"_thirdLevelEth()","3bd575fa":"acceptTrustSC(address)","3bd5aceb":"nProposals()","3bd5c209":"getContractCreationData()","3bd6695e":"testCoin()","3bd74880":"HARDCAP()","3bd756b6":"addPrivateFund(address,uint256)","3bd794d0":"solveDispute(address,bytes32,address,bool)","3bd797b0":"Tasks(address,address)","3bd7a51a":"IfContractRegist(string,string,string,string)","3bd87ebd":"hardCapTime()","3bd89deb":"DAX()","3bdc5173":"disallowNorthPoleMinting()","3bdcaab9":"getEndpointBroker(address,bytes32,int256)","3bdd504a":"rateOfZNT()","3bde045f":"numberOfRounds()","3bde3072":"onAssetReceived(uint256,address,address,bytes,address,bytes)","3bde5ba8":"targetReached()","3bdebbe1":"withdrawERC20Token(address)","3bdf157a":"setoraclegasprice(uint256)","3bdf2c0c":"setBaseValue(uint256,uint256)","3bdfafac":"randomJackpot()","3bdff827":"StaticArbiter(address[])","3be08dab":"setAddress(address,address,address)","3be1212b":"approveValidDurationData(uint256)","3be1c410":"dev2Wallet2Pct()","3be1e952":"freezeTo(address,uint256,uint64)","3be272aa":"createRoom()","3be2b60c":"joinwithreferral(address)","3be31d63":"updateVerificationStatuses(address[],bool)","3be3a3f5":"setCloseTime(uint256)","3be3bdd9":"offTimeLock()","3be46378":"getAffiliate(uint256)","3be4ee30":"getUserTokenLocalBalance(address,address)","3be52c2c":"setStatusBurn(bool,bool)","3be546a2":"raiseDollarsAdded(address,uint160,int160)","3be554d4":"setCostPerDay(uint256)","3be59443":"_setOracle(address)","3be64ed7":"addPeriod(uint256,uint256,uint256)","3be6ccd9":"freezeWithdraw(address,uint256,uint256,bool)","3be746b6":"lockState(string)","3be75aa3":"shareLimit()","3be86ba1":"setIcoAgent(address,bool)","3be8fd6a":"setContent(string)","3be924fa":"hasAuth(string)","3be92863":"burnLotById(bytes32)","3be93b98":"createCountry(string,string,string,uint256)","3be94219":"purchaseAttack()","3be9cfb7":"changeDropper(address)","3bea92a3":"addToTipperQueue(uint256,address)","3bead271":"sale3(address,uint256)","3beb0044":"hminus(uint256,uint256)","3beb26c4":"setTime(uint256)","3beb4db1":"setIcoStage(uint256)","3bed33ce":"withdrawEther(uint256)","3bed93f2":"MAX_COLLECTORS()","3bee0613":"updateExchangeStatus(bool)","3bee8726":"getMaxContenders()","3beea695":"corruptElite()","3beedf6d":"lotteryAddress()","3befedea":"getPersonParents(uint256,bool)","3bf03e9e":"HelloWorldContract()","3bf11a6c":"initToken(address,address,uint256,uint256)","3bf12c88":"Rate1()","3bf13ded":"changERC20(address)","3bf17f75":"initializeCompanyTokens(uint256)","3bf2313d":"__transferToICAPWithReference(bytes32,uint256,string)","3bf2a861":"cancelOrder(bool,uint32)","3bf2b4cd":"approveDisband()","3bf2cade":"justPureFunction(int256)","3bf30f85":"execute(address[],bytes)","3bf329bf":"fraction(int216,int216)","3bf3d531":"miningThreePlat()","3bf47720":"totalTransfers()","3bf48672":"BattleToken(address)","3bf4ac5c":"day3Start()","3bf53a89":"unVoteAll()","3bf5b9c0":"getNumberByChoice(uint256)","3bf5f781":"Trendercoin()","3bf6de96":"max(uint256[])","3bf81b91":"testAddVoter()","3bf8f34a":"designatedReporterShowed()","3bf99b3f":"buyTokensByBTC(address,uint256)","3bf9b801":"_Hit()","3bfa0de9":"changeFundWallet2(address)","3bfa4449":"createFreeToken(string,address)","3bfb3246":"_detectInvestorGroup(uint256,address)","3bfb3c35":"fourthBonusEnds()","3bfca20f":"TokenToken(address)","3bfd7fd3":"incrementValue()","3bfdd7de":"transferManagment(address)","3bfecbf0":"setNeverdieSignerAddress(address)","3bfed5dc":"DolyToken2()","3bffb839":"Cryptolotto1Hour(address,address,address,address)","3bffd31e":"depositaPagamento()","3bfffc49":"getSumOfValues(uint256[])","3c0093a6":"MithrilToken()","3c01a9fa":"getEscapeRequests(uint32)","3c027d4f":"isTokenSelling(uint256)","3c0359a4":"certifications(uint256)","3c03d8be":"judgeAddress()","3c0471a2":"pregnantLinglongCats()","3c05187b":"execute(uint8,bytes32,bytes32,address,address,uint256,bytes,address,uint256)","3c067945":"fundBalance()","3c06ae68":"raiseBuyOrderMatched(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int160)","3c070b60":"dataSourceCallbackFinals(uint256,uint8[4])","3c077a48":"getAll(uint256)","3c0870ae":"challenge(uint256,uint256,uint256,bool)","3c096005":"managerAmount()","3c09ee26":"Token(address[],uint256)","3c0ab650":"buyAllAmount(address,address,uint256,address,uint256)","3c0afb59":"changeStartDate(uint256,uint256)","3c0b0279":"KhawCoin(uint256,string,string)","3c0b1c41":"AFTBToken()","3c0b8577":"getUserApproval(address)","3c0b9db2":"PolyDistribution(uint256)","3c0ba651":"getDutchAuctionToBuyAddress()","3c0cd36b":"manualPurchaseTokens(address,uint256)","3c0ce567":"fetchConfirm(address,bytes32)","3c0cfb3d":"mintMigrationTokens(address,uint256)","3c0dabdb":"getMidgradeCarSupply(uint256)","3c0dde1c":"_addPools(address,address)","3c0de47c":"probabilities()","3c0e1cc2":"revealPhaseMinSecondsWaitForClearMajority()","3c0e5d74":"frozenCheck(address,address)","3c0e6adc":"reset_individual_shares(address)","3c0f60ad":"setSecondaryStorage(address)","3c0f92e3":"supportAddOn(uint16,uint256)","3c0fc6ea":"kill(address[])","3c0fcdd1":"depositEgereg(uint256)","3c1008bb":"internal_transferFrom(address,address,uint256)","3c107402":"LongPlace(address[2],uint256[7],uint8,bytes32[2],uint256)","3c10d7cd":"bonusInPhase2()","3c11845e":"ContractConstructor(string)","3c11f969":"sentSecond()","3c121ef5":"is_empty()","3c126795":"OMIVIA()","3c130d90":"tokenURI()","3c133818":"winningVote(bytes32)","3c13ec32":"team1LockEndTime()","3c13fc33":"transferBase(uint256)","3c1593ab":"endFirstWeek()","3c15d28f":"createQuestion(string,address,uint128,uint256)","3c1650ff":"getData_23()","3c16761f":"SUM()","3c168093":"addOrder(uint256,uint256,address,address,uint256)","3c173bf0":"ZarfundsToken()","3c17494d":"set(uint16[],string,string,string,bool)","3c17622a":"setFreelancerSkills(address,address,uint256[])","3c17b656":"investmentGateway()","3c1800cd":"isPresaleEnd()","3c1853e7":"etherBack()","3c18d318":"sweeperOf(address)","3c198047":"RollToken()","3c19df06":"stakeCreativeCommonsContent(uint256,uint256,bytes8,uint256,string,string,string,string,uint256)","3c19fc06":"Holder()","3c1a7c6f":"getCountApplyForCertification()","3c1a7e2d":"adminWithdrawBCEO(uint8)","3c1a7eda":"certificate(bytes32,bytes32)","3c1a88d7":"blockTokens(address,uint256)","3c1ab2a3":"URL()","3c1b81a5":"getInstructor()","3c1b87f9":"setSettings(uint256,uint64,uint64,uint256)","3c1c423c":"getInfoLibra(bytes32)","3c1c5931":"promoCodeToContractAddress(bytes16)","3c1cc14e":"stopTokenSwap()","3c1ce6a5":"mintDigm(uint256)","3c1d28a3":"redeemLevAndFee(address)","3c1d7078":"BookCreated(address)","3c1e60a6":"tokenParametersSet()","3c1f1cb7":"ethSaver()","3c20307b":"CTWtoken()","3c203d44":"PreCrowdAllocation()","3c2040c1":"setInviteAdmin(address)","3c20485e":"limitIcoTokens()","3c205b05":"currAdminEpoch()","3c206900":"disableEmergencyBlock()","3c2087c9":"Withdrawal(address,uint16,uint256)","3c20d1a5":"getStageCap(uint8)","3c20ee6e":"_end()","3c21001d":"getMySentTradeOfferId()","3c21acc6":"extraMintArrayPending(address[])","3c21b968":"loadBalances(uint256[])","3c21db0a":"theGames(uint256)","3c21f0a1":"GHIToken(address)","3c21fa2e":"setELHeroTokenAddr(address)","3c226cd9":"ChangeDeadLine(uint256,bool,uint256)","3c22c935":"processMilestoneFinished()","3c232bb6":"set_traded_token_as_seeded()","3c237167":"getProductivityCitizens(uint256)","3c240a63":"updateFourthExhangeRate(uint256)","3c24550c":"isRefundTime()","3c263cf4":"savingPoints()","3c264820":"getWinningPayoutNumerator(uint256)","3c26777b":"StartedGame(address,uint256,uint256,uint256)","3c2698d5":"YUNLAI()","3c269b96":"setExchange(bool)","3c26cfe3":"drawLottery(string)","3c275e24":"getInfo(address,uint256,uint256)","3c276d86":"saleStartTimestamp()","3c278bd5":"lift(address)","3c279f1f":"submitWithdrawTokenTransaction(uint256,address,uint256)","3c28308a":"rndNo()","3c287a3f":"BitcoinDiamondToken()","3c28b9c0":"expirationInSeconds()","3c2aba9f":"manageApprovedTransferModule(address,bool)","3c2b0725":"delegateContract()","3c2b2508":"PREMINER_ADDED(address,address,uint256)","3c2c21a0":"scheduleCall(address,uint256,bytes4)","3c2c4b5e":"MASTER_WALLET()","3c2cf368":"BIGTTokenDeposit()","3c2d55e6":"GetSubscribers()","3c2d6447":"setIcoPercent(uint256)","3c2d70e9":"start(address,uint256)","3c2dba23":"stakedForPollID(address,bytes32)","3c2e2624":"transferManyDirect(address[],uint256)","3c2e2a75":"depositTokenForUser(address,uint256,address)","3c2e671e":"founder3Wallet()","3c2e6b32":"AquaSale(address,uint256,uint256,uint256,uint256,address,address,address,address,address,address,uint256)","3c2e7d54":"priv_inMainChain__(int256,int256)","3c2efb22":"isContributionRegistered(bytes32)","3c2f24af":"loopFor(uint256,uint256,uint256)","3c2f7df5":"incGen0Limit()","3c306250":"mybalance(address)","3c311f3c":"previous(uint256)","3c314a91":"playerGetPendingTxByAddress(address)","3c31762c":"setMinPurchaseValue(uint256)","3c31fa62":"setFeeRates(uint16,uint16,uint16)","3c324c2e":"totalCollectableToken()","3c32673f":"BTTSTokenUpdated(address,address)","3c329dc4":"delModule(string)","3c32d8ef":"getOffChainIdentity(address,address)","3c3313a8":"registerLoan(address)","3c335b0e":"getRetractable(bytes20)","3c33808d":"preallocateSecondStage(address,uint256,uint256)","3c33863c":"computeGroupPhasePoints(uint8,uint8)","3c33d473":"setLargeCapDelay(uint256)","3c345335":"addSignature(uint256)","3c347cbd":"_0xTestToken()","3c358483":"setData_10(string)","3c35a858":"processProcessableAllocations()","3c35c88a":"sendFundHome2()","3c37a88b":"stage4_start()","3c37b640":"commitHash(bytes32)","3c3861b6":"getRace(uint32)","3c389cc4":"erc20Impl()","3c391c95":"preSaleBonus2Time()","3c3a8c39":"UpcToken()","3c3ad016":"forceUpgrade(address[])","3c3b4b31":"getHouseTraits(uint256)","3c3b7995":"privateLimit()","3c3bdb7a":"changeExchange(address)","3c3be494":"dtCreateCityData(address,uint256,uint256)","3c3c22b3":"oldest()","3c3c88b1":"initializeOnTransfer()","3c3c9c23":"totalEth()","3c3ccc44":"startNextRound()","3c3ce17d":"insure()","3c3d1385":"tinhtong(uint256,uint256)","3c3d3af6":"amountInvested(address)","3c3d9ada":"_bctc(uint256,uint256,uint256,uint256,address)","3c3deb54":"contractCreatedTimestamp()","3c3e1662":"ctf_challenge_add_authorized_sender(address)","3c3e2447":"MINIMUM_BUY_AMOUNT()","3c3e6af4":"QTX()","3c3efdc9":"calculateEarnings(uint256)","3c3f4c63":"maxSpend()","3c3ff394":"IRECToken()","3c40066d":"investByLegalTender(address,uint256,uint256)","3c402bd1":"AMTBToken()","3c41c816":"EthlanceUser(address)","3c4293d8":"refund_my_ether()","3c42f95a":"setMetadata(string,uint256,bytes)","3c43b91d":"setStage2Ends(uint256)","3c444637":"setSaleBonus(uint256)","3c454d7f":"getper()","3c45b373":"addVoting(address,uint256)","3c46f604":"testDeleteCase()","3c473336":"isEndedTrack(bytes32)","3c4857a7":"_approve(uint256,address,address)","3c489238":"HappyFutureToken()","3c48d7de":"shapeshiftTransfer(uint256,string,string)","3c490a70":"getGlobal(uint256)","3c4961ff":"_processAirdrop(address,uint256)","3c49dde4":"registerDonation(address,uint256)","3c49ec88":"getMyKebabs()","3c49ff0c":"StarCoinPreSale(uint256,uint256,address,address,address,uint256,uint256,uint256)","3c4a2989":"POPCHAINCASH()","3c4a4b1e":"createTokenTimelock(address,uint256)","3c4b07de":"extUnlockBot(uint256,uint16)","3c4b303d":"token_decimals()","3c4b40b8":"fundingWallet()","3c4b5e2b":"setInviteeAccumulator(address,uint256)","3c4c51c9":"getClue()","3c4dbb17":"PriceWeekOne()","3c4e7d9f":"setESCBDevMultisig(address)","3c4ec769":"VCT()","3c4f3c12":"issueTokensSale(address,uint256)","3c4f5a66":"getActivePlayers()","3c4f5be3":"registrantOfToken(uint256)","3c50afe1":"_icoSupply()","3c50edbd":"getSidesById(uint256,uint256)","3c5192b7":"EscrowEscalation(uint256,uint256)","3c520944":"getPromoCodeForFish(bytes16)","3c526ef1":"_divideDecimalRound(uint256,uint256,uint256)","3c530ace":"registerProducer(address)","3c536938":"executeTransaction(uint256,uint256)","3c5395b2":"revokeAdmin(address,address)","3c53cb96":"lastBlock_v0Hash_uint256()","3c53dabe":"BeggarBetting()","3c540687":"txCount()","3c54ca8c":"trade(address,address)","3c54caa5":"reclaimTokens()","3c5524d8":"listContractByModuleName(string,string)","3c552556":"verify_signature(bytes32,uint8,bytes32,bytes32,address,address)","3c55563e":"cards_metal_total()","3c560064":"mintPartner(address,uint256)","3c566f0f":"shopStoreAddress(uint256)","3c56d236":"HashLotto()","3c56e2ae":"register(address,uint8,bytes32,bytes32)","3c56eae3":"setForceReadyTime(uint256)","3c5746dd":"recipientExtraMIT(address)","3c580e92":"setLocalGame(uint16,address)","3c584d86":"convertWT(uint256)","3c58795d":"hasFetchedProfit(address)","3c58d378":"lockChanges()","3c58ef44":"getWishIdxesAt(address)","3c594844":"leftToday()","3c5972ff":"multiSetWhiteList(uint256[])","3c59c17a":"AgentWallet()","3c5a12cb":"getVal(string)","3c5ad147":"Debug(string,uint256)","3c5b7d3f":"buyTkn(uint256)","3c5bd949":"mine_jade()","3c5bdcc4":"FCOIN0939Token(uint256,string,string,uint256)","3c5c6331":"addAddressToUniqueMap(address)","3c5d1812":"totalPhases()","3c5e270f":"teamSupplyAddress()","3c5e28d6":"setClientIdentRejectList(address[],uint8)","3c5e417e":"_mintApproveClear(address,address)","3c5e57e4":"_getRarity(uint8)","3c5e94dd":"bulkRegisterPoA(bytes32,bytes32,bytes32,uint256)","3c5f10a3":"winning_ticket()","3c5f2bf2":"getFullRace(uint256)","3c5fc608":"preDGZtoDGZExchangeRate()","3c617685":"SocialMediaPay()","3c61d003":"advertisingDeposit(uint256)","3c6251bd":"test_oneValidEqUint1()","3c627c9b":"releaseAndDistribute()","3c630356":"AirCrash()","3c63d000":"setBurnRequestStringMap(uint256,string,string)","3c6403b4":"GetAccountIsNotFrozenCount()","3c647fbd":"angelMaxAmount()","3c648ddd":"voteSvp01(bool)","3c64f9aa":"ClusterToken()","3c65c506":"adjust_difficulty()","3c6677d6":"promoBun(address,address)","3c667b13":"rentalsContract()","3c671e53":"collectPayout(address)","3c673470":"createGroup(address,bytes32,address[])","3c673c19":"deleteTopic(uint256)","3c67b6b7":"getClaimLeft(address)","3c67c51e":"testLogs()","3c67dad5":"revertLuckyCoin(address)","3c6806b8":"getDiary(uint256)","3c681da0":"getCandy(string)","3c6867c3":"CallBack(string,bytes32)","3c68eb81":"transferFunds()","3c695d4e":"authorityAddress()","3c69a5e6":"mintPresaleBonuses()","3c6a2929":"setArrIntF2ArrUintF3ArrBoolF1(int256[],uint256[],bool[])","3c6a71f7":"exchangeRatePreIco()","3c6aa9f1":"decimalsValue()","3c6b97c9":"TokenContribution()","3c6b9d8c":"captains()","3c6bb436":"val()","3c6bc24b":"getBrickDetail(uint256)","3c6bf582":"ElementBought(uint256,uint256,uint256,address,uint256,uint256,uint256)","3c6c67e2":"etherAllowance()","3c6d2610":"TalentToken(address)","3c6d2e19":"contributionsETH(address)","3c6d736d":"ZZZCoinERC20Token()","3c6d7b47":"setDebugNumber(uint256)","3c6dfba1":"buy(uint8,bytes6,uint32,uint32)","3c6e03d7":"thewhalegame()","3c6e5927":"getMonsterCurrentStats(uint64)","3c6ea2a5":"HooyToken()","3c6eab08":"KICKICOCrowdsale(address,address,address,address,address,address,address)","3c6ee392":"createTokens(uint256,uint256)","3c6f2cc4":"sendICOTokens(address,uint256)","3c704089":"DigitalCash()","3c7045fe":"takeEtherBack()","3c7066d1":"feeCMT(uint256)","3c7097a3":"setMaxCharId(uint32)","3c70bd42":"sell_(uint256)","3c716e08":"updateAuthority(address)","3c71b186":"ElementeumToken(uint256,address[],address[])","3c71b7b6":"validDelegateSignature(address,string,uint8,bytes32,bytes32,bytes32)","3c71faf2":"BMToken()","3c72751e":"lerp(uint256,uint256,uint256,uint256,uint256)","3c72a83e":"getKyberNetworkAddress()","3c72e9bf":"IMDEXadminWithdraw(address,uint256,address,uint256)","3c72f070":"initialTokensBalance()","3c73db77":"RecycleToken()","3c745371":"finalAddress()","3c745ad5":"nextProfile()","3c74db0f":"expirations(address)","3c76aa19":"CWCreturnQueryData()","3c771309":"setSiringRate(uint256,uint256)","3c774dbb":"buyChickenParkCoin(address)","3c775b08":"airdropLimit()","3c77b95c":"testExpUnroll16(int256,int256,uint256)","3c77e474":"_updateKeyPrice(uint256)","3c7818a1":"startRoundD()","3c78929e":"lockUntil()","3c78fe07":"getReceiver(uint32)","3c796430":"getOneTimePayment()","3c799547":"amountAvailable()","3c7a337a":"InDeepToken()","3c7a3aff":"commit()","3c7b3d90":"rewardAirdrop(address,uint256)","3c7b682d":"PunkOffered(uint256,uint256,address)","3c7b6869":"finishPresale(uint256)","3c7c2563":"createtoken(string,string,string,string)","3c7cc806":"validateOrderAuthorization_(bytes32,address,uint8,bytes32,bytes32)","3c7d6f30":"publicStartRegularPhase()","3c7e03c1":"getRelayingKing()","3c7e31f0":"addCutie(uint32,uint128,uint128,uint128,uint128)","3c7fdc70":"fibonacciNotify(uint256)","3c807878":"stageOne()","3c811ee0":"putSellOrder(address,uint256,uint256,uint256)","3c8161c5":"KVC(uint256,string,uint8,string)","3c816217":"killBoard(uint16)","3c81df21":"getMultisig()","3c8259b4":"SACoin()","3c837b7d":"changeSettings_only_Dev(uint256,uint256,uint8,uint8,uint256)","3c8394ac":"ICORaised()","3c83f7aa":"rateForPhase2()","3c842a26":"_Test_Oraclize()","3c847e52":"withdrawVested(address)","3c84f868":"set(int256,address,uint256)","3c8515b1":"_createCrypton(string,address,uint256,uint256,bool,uint8)","3c86063c":"insertInfo(string,uint256,uint256)","3c8766c6":"sendProfitsReward(address)","3c876c6f":"newIdShipProduct()","3c87b8ef":"get_player_state()","3c889e6f":"getBid(uint256)","3c889fe1":"masterCalculator(uint256)","3c890e4c":"getVoteStake(uint256,uint256,uint256,bool)","3c893718":"transferCity(address,address,uint256)","3c894475":"scheduleTransaction(address,bytes,uint8,uint256[6],uint256)","3c89f9d4":"accept(uint256,address[],uint256[])","3c8a072e":"temporalUnit()","3c8a321c":"setPaymentGatewayList(address)","3c8ac88e":"createIdentityWithCall(address,address,address,bytes)","3c8b0c55":"set_arbits_min_contribution(address,uint256)","3c8b6597":"addPrivateSaleTokensMulti(address[],uint256[])","3c8bb3e6":"wmultiply(uint256,uint256)","3c8bccd9":"getCommission(uint256)","3c8c681a":"RoundCSold()","3c8c6a1e":"sendToken(address,address,address,uint256)","3c8ca83d":"gameBeginTime()","3c8cd434":"getCabCoinsAmount()","3c8d284b":"receiveBtcPrice(uint256)","3c8da588":"priceInWei()","3c8e3b52":"getTotalPercent()","3c8e66fb":"calculateTotalDirectDebitAmount(uint256,uint256,uint256)","3c8eac87":"getTransactionState(uint256)","3c8f202e":"Dashicoin(uint256,string,uint8,string)","3c8f3278":"hmax(uint128,uint128)","3c8f96f1":"bonusTokens(uint256)","3c9046c9":"yearTwoClaimed()","3c9070b5":"ConsultaProva(address)","3c90861c":"Enigma()","3c90ee6a":"DNARtoGoldXchgRate()","3c918bae":"wallet3()","3c920d0d":"liquidityPoolTotal()","3c925f16":"getAccountHolder()","3c9266e0":"sendSalary(address)","3c9340ae":"orderForDays(bool[])","3c936e97":"lockBonusTokens(address,uint256,bytes1)","3c93d8be":"uint2hexstr(uint256)","3c941423":"getDesignatedCaller(bytes32,uint256)","3c959aca":"CheckTickets()","3c960be9":"transferFromSenderPaysFee(address,address,uint256,bytes)","3c961202":"getHighscore()","3c96a7a8":"withdrawOwnerFee()","3c96d048":"setnow(uint256)","3c9719a7":"getReleasableFunds(address)","3c984f4a":"sellTokensForEur(string,address,uint256,uint256)","3c993482":"_payfee()","3c9a4baa":"requestOutput(bytes)","3c9a5d59":"getAuditAuditor(uint256)","3c9ad41b":"tokenIssuedToday()","3c9af31c":"getSponsor(uint32,int256)","3c9c4001":"whitehat()","3c9c97f0":"setBlocksPerRound(uint64)","3c9d377d":"f5()","3c9d93b8":"removeAllowedAddress(address)","3c9ee04c":"previousstageplayer2()","3c9f861d":"totalBurn()","3c9ff012":"timeRangeCreateGen0()","3ca1595a":"addNewRaz(uint256,uint256,uint256,uint256,string)","3ca19952":"getBookingCount(address)","3ca22916":"dollarPerEtherRatio()","3ca520f5":"LaunchPartnersAmount()","3ca5c69c":"AllMake()","3ca5c8b8":"createFilmToken(string,uint256)","3ca6268e":"log(string,int256)","3ca63675":"getNumberOfVotes(uint128)","3ca65e77":"JMJToken()","3ca6a437":"assignedGameContract()","3ca6b228":"getEmployee(address,address)","3ca6c07a":"setTokenAdd(address)","3ca6d100":"create(string,string,uint256)","3ca6d5a9":"initialBuyPrice()","3ca7aad7":"xorReduce(uint8[],uint256)","3ca805ba":"pwrFloat(uint256,uint256,uint256,uint256)","3ca88a2f":"canBuy(uint256)","3ca8b002":"isDeploymentAdmin(address)","3ca95c89":"getCompte_26()","3ca967f3":"getCurrentExchangeRate()","3ca96e0e":"teamBonusAllocatedTokens()","3cab648a":"getModuleAddressByName(string)","3cac14c8":"returnArray()","3cac2387":"trustedTokens(address)","3cac38e4":"advanceStep()","3cacf895":"doPayments()","3cad71cf":"RetStatic(uint128)","3cad7c4e":"setLockQtyToAllowTrading(uint256)","3cae09ac":"silencePeriod()","3caebce4":"BRFToken()","3caed876":"submitTransaction()","3cb00fd2":"get_presale_iconiq_arbits_per_ether(address)","3cb025e2":"SimpleSafeToken()","3cb0b51b":"Redeem200AFTK16SeptSandbox()","3cb21103":"isAllowedFactProvider(address,address)","3cb260b2":"set_dimensions(uint256,uint256)","3cb27169":"receiverVestings(address,address)","3cb32f77":"currentHolders()","3cb3d027":"getTokenBankrollAddressFromTier(uint8)","3cb3ea68":"LAMBO_TYPE()","3cb40e16":"withdrawToOwner()","3cb4986a":"ZeusToken()","3cb4ff3c":"getActiveCards()","3cb579c1":"setValueParam(uint256)","3cb5bc74":"setMintLimits(uint256,uint256,uint256)","3cb5d100":"contributors(uint256)","3cb5d170":"sendTokenReleasedToBalanceInternal(address,address,address)","3cb5d1df":"TicTacPotato()","3cb6465e":"numOfWinner()","3cb6e20c":"LeadcoinSmartToken()","3cb802b9":"unclaimedDividends()","3cb83751":"getCofounderCount()","3cb8cfc8":"acceptTokens(address,uint256)","3cb8cfcd":"totalEthInWeiForPreIco()","3cb9032e":"getInvoicesCount(address,uint256)","3cb94596":"addressOf(bytes)","3cb960a6":"calcCORtoETC(uint256)","3cba3c77":"OperationalSplit(uint256)","3cba41bf":"store(bytes,address)","3cbcf9a4":"RatingToken(address,uint256)","3cbd4285":"addWinnigs(address[],uint256[])","3cbd6429":"playerId(address)","3cbdfcd9":"bountyTokensToAddress(address)","3cbe7309":"AgriChainDistribution()","3cbeb49a":"setColorBlue()","3cbec314":"FRUT()","3cbf41d2":"completeCrowdsale()","3cbfed74":"getBondBalance()","3cc0be9a":"setCompte_37(string)","3cc0fb45":"testFailRetractNotOwner()","3cc12603":"ABCToken(uint256)","3cc136e0":"destroyRoto(address,bytes32)","3cc1429c":"createEthAuction(uint256,address,uint256)","3cc15011":"_calculateExcessTokens(uint256,uint256)","3cc1635c":"deleteBooleanValue(bytes32)","3cc228fd":"minVotes()","3cc26b71":"admin_active_dividend(address)","3cc3c3b5":"terraformReserve()","3cc45596":"updateCar(uint256,bytes32,uint256,uint256,uint256,uint16,uint8,uint8,uint8,uint8,uint8)","3cc4c6ce":"resumeGame()","3cc54aae":"updateGenGuVault(uint256,uint256)","3cc626b6":"PotoToken()","3cc6441d":"Smile()","3cc71c3f":"COMMUNITY_ALLOWANCE_LIST()","3cc7508f":"uncooperativeClose(address,uint8,uint256)","3cc75749":"volumeType2()","3cc7790a":"GSI()","3cc7fd84":"infoTokenSilverRatio()","3cc86b80":"GetMoney(uint256,address)","3cc86b9a":"takeAllNotClaimedForRefundMoney()","3cc8daf7":"setNameOwner(bytes,address)","3cca2420":"contractData()","3cca779b":"gameOpen()","3ccad6fc":"getNamedAddresses()","3ccaf593":"createReport(string,string,string,string,uint8)","3ccb25a2":"setRequiredBlocksElapsedForVictory(uint256)","3ccb47cb":"roundPot()","3ccb4ae4":"initLocalNodeReputation(address)","3ccb6c31":"setWallet2(address)","3ccb7dc9":"CrowdFund(uint256,uint256)","3ccbad50":"initialize(address,address,address,address,address,bytes32,uint256,uint256,uint256,uint256,uint256)","3ccc5e2c":"icoSale()","3ccc8193":"lastWiningTicketNumber()","3cccfc1b":"promotionCommisionPercent()","3ccd1c7f":"getFactoryProfit(uint256,address)","3ccdbb28":"withdrawToken(address,uint256,address)","3ccf127e":"raisePreSale()","3ccf5861":"TOSInstitutionsIncentiveContract()","3ccf5c8f":"setDelegadoDeEscuelaVerify(bytes32,bytes32,uint256,uint256)","3ccfd60b":"withdraw()","3cd109cb":"addAuthorizedOwners(address)","3cd17060":"getProposalHash(string)","3cd1b6b1":"isSponsorable(address,uint256)","3cd21d88":"ClosePeriodEvent(uint256,uint256,uint256,uint256)","3cd260e6":"doWorkAndPayEBT()","3cd2df82":"calculateTokensWithoutBonus(uint256)","3cd35429":"DQCoin()","3cd36358":"_getApproved(address,uint256)","3cd510ee":"getWinNumbers(string,uint256,uint256)","3cd5d5fc":"Sacar_BlackList(address)","3cd5f8ea":"addCourse(address)","3cd78a2b":"addToSpecialRatesMapping(address,address,uint256)","3cd8045e":"splitter()","3cd99b70":"setMaxDepartureLim(uint256)","3cd9a0fa":"stage_2_maxcap()","3cda0103":"supplyOf(string)","3cda0b45":"contribute(bytes8)","3cda6524":"addUnlockedAddress(address,address)","3cdb01ae":"atxChangeAddrCount()","3cdb3aa6":"activateRefund()","3cdb9762":"getTokenBalance(string,address)","3cdb982b":"getNumeroDeOuvidorias()","3cdbd414":"multivestBuy(bytes32,uint8,bytes32,bytes32)","3cdd37e1":"WatchedWallet(address,address)","3cdd9262":"peMaxPerPerson()","3cde5627":"SendEtherToDex(uint256)","3cdf60e2":"TurkCoin()","3cdf6783":"withdrawDeferred()","3ce0a093":"getHash(bytes8)","3ce0c432":"TokenPurchased(address,address,uint256,uint256,bytes)","3ce123dc":"highBidder()","3ce1314f":"setUnlockStart(uint256)","3ce17f24":"_createPlayer(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","3ce1f4e7":"testFailUpdateLatestRevisionNotUpdatable()","3ce24239":"AddSharedAccount(bytes32,address,bytes32,bytes32,bytes32)","3ce276f5":"setFreezeTransfer(bool)","3ce32c0a":"AWAToken()","3ce3480a":"closeStageOne()","3ce39a3d":"proposeTx(address,uint256)","3ce54ac3":"testFailCreateWithParentParentSameItemId()","3ce5facd":"HeyfanToken()","3ce6d89b":"approveTaxData(uint256)","3ce70aac":"getDocumentSequence(bytes16,bytes32)","3ce716f9":"WalletChanged(address)","3ce7da3d":"setTokenSymbolName(string)","3ce819e2":"captcha()","3ce948c8":"Token_3()","3ce97eb9":"GetManifestoById(uint256)","3ce9d22e":"setupFinal(uint256)","3cea6965":"gasMin()","3ceb7783":"rankNumbers_()","3cebb4d7":"setOpGas(uint256,uint256,uint256)","3cebb823":"changeController(address)","3cebff9c":"airdropPool()","3cec21c8":"register_(uint256)","3cec475a":"connectTest()","3cec9309":"segmentSize()","3cecd719":"cleanup()","3cece78b":"__getEthPrice(uint256)","3cecf2e6":"exchangeRateArray(uint256)","3ced516c":"descriptionHashes(bytes32)","3ced842b":"make_offer()","3cedd004":"setMinimumInitialBudgetForAudits(uint256)","3cee32e3":"set_allow_withdraw_amount(uint256)","3ceeafa7":"amountOfTokensPoolA()","3cef162a":"allocatetokensAndWL(address,uint256)","3cef51c5":"maxWeiTier3()","3cefc1e0":"hasTokens(address)","3ceffd41":"TokenPurchased(address,uint256,uint256)","3cf0659a":"right25(uint256)","3cf26a33":"transferAssetOwner(address)","3cf274a5":"bighype()","3cf2eb85":"dispossess(address,uint256)","3cf39ed3":"ini_supply()","3cf3a338":"WithdrawTithes()","3cf3d6d8":"getAllCellInfo()","3cf3ecd7":"StartGuess_tw(string,string)","3cf3f105":"checkInvarience()","3cf43e08":"revertTokens(address,address)","3cf43e2c":"btcId()","3cf46fee":"RoundClose(uint256,uint256,uint8)","3cf5040a":"getHash(bytes32)","3cf52ffb":"proposedTimestamp()","3cf572a7":"setNotice(string)","3cf5da75":"getTokenInvocations()","3cf679a5":"lastBlock_v19Hash_uint256()","3cf682b8":"CikkaCoin()","3cf6ed95":"stageForDate(uint256)","3cf7cbdb":"showTimeLockValue(address)","3cf7d47b":"IncreaseInvestedWeiAmount(uint256,uint256)","3cf885c4":"isBitSet(uint256,uint8)","3cf8acec":"allocateBid5(bytes32)","3cf9db41":"drawWinner(uint256,uint8)","3cfa92de":"BAToken(address,address,uint256,uint256)","3cfaa9ed":"mintedWallets()","3cfaaca0":"DMRToken()","3cfac38e":"validatePrediction(bytes32,uint256,uint8)","3cfb35aa":"ensSubdomainRegistrarBase()","3cfba0e3":"ethBalances(address)","3cfc47ea":"getPostPoster(uint256)","3cfc83f5":"addGame(string,address)","3cfd1f80":"VirginToken()","3cfd78f3":"onlyBouncerAddExtension(address)","3cfd86f1":"CashPokerProToken()","3cfe25cf":"cap_ACE()","3cfe6731":"claimfordividend()","3cff5b66":"getIsAuth(address)","3d00b8e3":"buyTokens(uint256,uint256,bytes)","3d0141f6":"whatProposal(bytes32)","3d01bdec":"CTO()","3d02c85b":"rejectTokens(address,uint256)","3d03582f":"collectBack()","3d0383c2":"getthismuchethforyourspud(uint256)","3d03886a":"setRobotAddr(address)","3d03a284":"getMyBat()","3d03ec29":"createCoin()","3d05d0e6":"MintFToken()","3d06242a":"setVIPFee(uint256)","3d062adf":"deleteMember(address,address)","3d0673d4":"getTotalToken()","3d080bd9":"dateRelease3()","3d089bf6":"GlobalBusinessSystem(uint256,uint256,uint256,uint256,address)","3d092b3d":"getMatch(uint256)","3d0977e1":"CROWD_WEEK2_PERIOD()","3d0a8dab":"endExclusive()","3d0ab170":"feePerUnitOfCoin(uint256)","3d0ab7e8":"PresaleContribution(address,uint256)","3d0acdaa":"getReservedPercentageUnit(address)","3d0c3836":"emergencyERC20Drain(uint256)","3d0c46d0":"getMessagesCount()","3d0c4924":"MAXIMUM_SUPPLY()","3d0c7eb6":"purchaseTicket(uint256,address)","3d0c9cc4":"PACK_SIZE()","3d0e6afc":"crownFreeze(address,uint256,uint256)","3d0ed048":"delBlacklist(address)","3d0ef823":"DepositReturn(address,uint256)","3d0f963e":"updateWhitelist(address)","3d11fa43":"delUnicornContract(address)","3d124c9d":"PointGameParticipate(address,uint256,uint256)","3d125f03":"buyTokens(address,address,address,uint256)","3d126a45":"devTokensPercent()","3d126e57":"SparkChainToken()","3d13341c":"_bytes32(string)","3d13aec8":"save(address,uint256,uint256,uint256,string,string,uint256)","3d140d21":"approve(address,bool)","3d14263a":"FailedSend(address,uint256)","3d147789":"UpgradeCommited(address)","3d160de9":"pricesAreStale()","3d160e0b":"UNLOCK_PHASES()","3d1657ff":"getIncreaseBalance(uint256,uint256)","3d1678f4":"redeemEnableTime()","3d16991a":"getStep(bytes16)","3d17a2d8":"merchantHistory()","3d182c42":"private_SetPause(bool)","3d1843c3":"callAndFail()","3d18678e":"setFees(uint256)","3d18b912":"getReward()","3d18bb7f":"HP()","3d18c615":"LastProposalID()","3d18e7b5":"amIH1()","3d1930ac":"mintBounties(address)","3d19481f":"balancePreSale5()","3d1a653f":"Ticket_Ganador(uint256,uint256)","3d1aa963":"chargeFee(address,address,uint256)","3d1aac95":"setWalletToClientAccount(bytes32,address,bytes32)","3d1b9d00":"TRCToken()","3d1bd1bf":"totalLockedHavvens_byAvailableHavvens_limitedSum()","3d1ced2b":"candyuser(address,address,uint256)","3d1cefc4":"SurveyToken(uint256)","3d1d2202":"getMinersOnSale()","3d1d4703":"newTribe(string,string)","3d1e215d":"redistributeTokens(address,address)","3d1e40a7":"changeTimeWithoutUpdate(uint256)","3d1ea04a":"getUnitCoinProductionIncreases(address,address,uint256)","3d201fcf":"MatchEnd(uint256,string)","3d20d9b0":"BONUS_ICO_ROUND2()","3d20e09e":"lpBidPrice()","3d20e3d7":"SetMemberLevel(address,address,uint8)","3d21aa42":"sendApproval(address,uint256,address)","3d226146":"createEvent(bytes32,bytes32[],bytes16[],uint256[])","3d2271fd":"setBytesRaw(string)","3d228ce8":"presaleTokenCreationRate()","3d22d571":"userBanning(address)","3d235d88":"KPRToken()","3d23af26":"newRegistryWithToken(uint256,string,uint8,string,uint256[],string)","3d24081c":"randomSkinAppearance(uint256)","3d249031":"Multicoin()","3d26851a":"_transferFrom_byProxy(address,address,address,uint256)","3d2796f5":"Forwarder(address)","3d289a76":"irbg(address,uint256)","3d28bab2":"SetGasBuy(uint256)","3d28ce75":"ChooChooCoin()","3d28e2ac":"totalDividendPayOuts()","3d2a9b9b":"getPartIndexes(uint256)","3d2c8d18":"lastEvidenceCheck()","3d2ce522":"setdaily(uint256)","3d2d812f":"MultiTransferValues(address[],uint256[])","3d2d8263":"tokenFund()","3d2dea63":"transferAny(address,address,uint256)","3d2e7538":"IPv6Token()","3d2f5bda":"startVoting(uint256)","3d2fbd0a":"usdEstimateInContract()","3d30276b":"Presale(uint256,address)","3d30dbe9":"updateBonusEligibity(address)","3d316134":"maxTokensToSale()","3d31e97b":"appendDebtLedgerValue(uint256)","3d32cb63":"updateReputationScore(bytes32,bytes32)","3d330c49":"findElevenPmUtc(uint256)","3d34a3e7":"setStage2()","3d34f921":"HexelErc20Token(string,string,uint256,address)","3d35d7ba":"getBuyRate()","3d36f7dd":"assertCorrectAllocations()","3d37542b":"launchOutcome()","3d37ef8c":"RESERVED_PARTNERS_LOCKED_SIDE()","3d380ff3":"releaseBatch()","3d389faf":"buyEnable()","3d38abd9":"MercadoMoeda()","3d3984bf":"ironProcessed(address)","3d39c260":"managers(uint256)","3d3b1c02":"SendEtherToBoard(uint256)","3d3b1fdf":"STRAToken()","3d3b2056":"getReadableTime(uint256)","3d3b26a6":"inflate(address,uint256)","3d3b4738":"GXVCReplay(uint256,address)","3d3bc43e":"getMessageRequestHashUsingProviderAddress(address,uint256,address)","3d3c3f2d":"snapshotUpdate(address,uint256,string)","3d3c5c9f":"trustedFillOrderTransfer(address,address,uint256)","3d3cba10":"decrementIncome(address,uint256)","3d3da831":"valueAfterAddingPremium(uint256)","3d3eb22a":"desapprove(address)","3d3f5114":"MEW_CROWDSALE_FUND()","3d405342":"fechAllCandidatesBySnapshotBlock(uint256)","3d40c266":"takeSellTokenOrder(address[3],uint256[3],uint256,uint8,bytes32,bytes32)","3d412396":"JBXPERETH()","3d4197f0":"setVal(uint256)","3d424dc0":"ViewtBet(address)","3d4311e2":"getRoundCasteValues(uint256)","3d432808":"destroyTokens(uint256,address,uint256,uint8[],bytes32[],bytes32[])","3d436ea1":"getEthBullet()","3d438c1e":"TheHumanFund(uint256,string,uint8,string)","3d43bd1e":"replaceDSPRegistry(address)","3d44c476":"getLinkDigest(bytes32,address)","3d456aa5":"extendFreezeBy(uint256)","3d45b9ef":"TokenCLCC(uint256,string,string)","3d46b819":"getNonce(uint256)","3d472d4d":"devGiveBlockReward()","3d488c52":"getPackageNameOfCampaign(bytes32)","3d48c067":"testSmartContract(string)","3d493572":"setSoftCapReached()","3d49ba0f":"updateMemeUrl(uint256,string)","3d4a7c1e":"setStage1Ends(uint256)","3d4a8b4e":"ScholarToken()","3d4af864":"CatToken()","3d4b2c2c":"totalTokenBalance()","3d4ba37a":"setMajorityThreshold(uint256)","3d4d8d4f":"withdrawEarnings(address)","3d4ee7a0":"FundariaToken()","3d4ef007":"vestingCount(address)","3d509c97":"removeRewardToken(address)","3d532ac5":"SWEET(uint256,string,string)","3d532bde":"removeSchedules(uint256,uint256[])","3d536a2e":"joinGame(string)","3d54b48a":"CreaEther()","3d561f73":"getBattleboard(uint16)","3d565121":"lockup_enddate()","3d568185":"createSpecialCards(uint32,uint16,uint16)","3d56dca3":"getBecomeHostSignatureAddress(address,string,uint8,bytes32,bytes32)","3d582391":"setEndsAtUTC(uint256)","3d584063":"getManager(address)","3d58650a":"BreakCoinToken()","3d58d0c3":"DROP()","3d5905a9":"setHolderAddress(address,uint256)","3d595134":"changeDubiAddress(address)","3d59995c":"remoteSetWinner(uint256,string,uint256,uint256)","3d59cd60":"changeRoot(bytes32)","3d5a3016":"canGotoState(uint8)","3d5aed1d":"_subGene(uint256,uint256,uint256)","3d5b0124":"RCR()","3d5b2b4e":"GxDeploymentAdmins()","3d5bb7f4":"setDaVinci(address)","3d5d0720":"totalContributedETH()","3d5db1c2":"incrUserOnholdBal(address,uint256,bool)","3d5dfb63":"_Approval(address,address)","3d5dff53":"tokensOwed(address)","3d608572":"testControlCreateWithParentsSameItemId()","3d619212":"basePublicPlacement()","3d62fa80":"getByFromAndTo(uint256,uint256,uint256)","3d637ebe":"tokensCreationVIPsCap()","3d639d84":"_getItemPrice(uint256)","3d64125b":"balanceof(address)","3d6571e5":"blub()","3d65a59d":"ICG()","3d65cf9c":"initParams(address)","3d65ecdf":"payToProvider(address)","3d662cff":"tokenDestroy()","3d66da8e":"claimRefund(address,address)","3d6759ec":"_createAsset(address,uint256,uint256,uint256,address)","3d677067":"buyProp(uint256,uint256,uint256)","3d68011a":"PRCT_TEAM()","3d6839c6":"REAL(address)","3d6859f2":"investorInfo(address,uint256)","3d68d33f":"BTCP()","3d694f30":"approveSettingCreation(uint256,bool)","3d695002":"_addressNotNull(address)","3d69b403":"isOutcomeSet(bytes)","3d69f4d6":"outsourceDelivery(uint256,uint256,int256,int256,int256,int256)","3d6a2231":"DrepToken()","3d6a32bd":"createTradeContract(address,uint256,uint256,uint256,bool,bool)","3d6a3664":"setNewOracle(address)","3d6a58ea":"convertSgnToSga(uint256)","3d6a71e4":"endedAt()","3d6a9750":"ShowTickets(uint256,uint256,uint256)","3d6ab68f":"CREATE_PERMISSIONS_ROLE()","3d6ad962":"claimPrizes()","3d6b0cb7":"testFailCreateWithParentForeignNotInUse()","3d6b6c70":"increaseJackpot(uint256,bytes32,address,address,uint256)","3d6b7301":"readAddresses(bytes32[])","3d6bc807":"cancelEtherBroAuction(uint256)","3d6bcaef":"GetWagerData(bytes32)","3d6c4df7":"updateWallet(address,string)","3d6df0d5":"docHash()","3d6e38b8":"changedp1(address)","3d6e87c1":"cancelSaleByAddress(address)","3d6ea8b2":"confirmMany(bytes32[],address[],uint256[],uint8[],bytes32[],bytes32[])","3d6eec6b":"RootNo3(uint256,string,uint8,string)","3d6f3366":"TokenCrowdsale()","3d6fc91d":"SetDestination(address,address)","3d6fda19":"stopIssue()","3d709ff1":"getRemixCount(uint256)","3d724027":"setLock(address[],uint256[])","3d725831":"getFundedTokensByIndex(bytes32,string,uint256)","3d72c71b":"SimpleToken()","3d72f40f":"getUserP3DInfo()","3d73c2de":"reserveCATDestination()","3d73ddfc":"SGNL()","3d7403a3":"update(string)","3d741994":"preIcoStart()","3d747f67":"invalidateToken(address)","3d74e856":"setMinJackpotBet(uint256)","3d750b28":"found()","3d756973":"getWrapperData()","3d75c49e":"OEBCBank()","3d75e106":"ImportTestC()","3d7646f7":"getRok()","3d769e3d":"EXT_COMPANY_ONE()","3d76b7a3":"checkHash(uint256)","3d79c332":"ALU()","3d79d1c8":"bal()","3d7a8baf":"setQuoteKey(uint256)","3d7a8c0e":"POPKOIN()","3d7bed99":"addProxyForSender(address,address)","3d7c9f8c":"THB_Omnidollar()","3d7d3f5a":"createSaleAuction(uint256,uint256,uint256,uint256)","3d7daab3":"_isValidSignatureAndData(address,bytes)","3d7e1048":"TransferredUnlockedTokens(address,uint256,bytes32)","3d7f09a3":"editEtherLimit(uint256)","3d7f6536":"getGraffiti(uint256)","3d80b532":"balance(string)","3d80ea28":"claimUSInvestorTokens()","3d813d8b":"setBountyAmounts()","3d814377":"window3StartTime()","3d820a90":"TOKEN_RATE_PRESALE()","3d8270f5":"getContributor(address)","3d82cf5a":"maxBattleRounds()","3d82e1b1":"assertEq3(bytes3,bytes3,bytes32)","3d82f71e":"distributeEGOX(address[])","3d832080":"ownerSetJackpotOfHouseEdge(uint16)","3d83230f":"auctionSuccessful(uint256,uint128,address,address)","3d83ed36":"increaseQuota(uint256,uint256,address)","3d84b8c1":"mintedForAccount(address)","3d856c9b":"getCmasByOwner(address)","3d8731ac":"LOCK_MAX()","3d8807f8":"cardsOfOwner(address)","3d888aa5":"PerformAirDrop()","3d8a03af":"getMatch()","3d8a63e4":"scam()","3d8b41f3":"createBurnRequest()","3d8c3dc9":"addTotalSupply()","3d8c5af4":"oddsSingle(uint256)","3d8c9b8c":"purchaseWolk(address)","3d8d020a":"withdraw(address,address,address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","3d8d0db4":"totalBuyPrice(uint256,uint256)","3d8e0f4e":"checkRevert2(uint256)","3d8e1b7c":"sumICOStage6()","3d8e2947":"getFileAddress(bytes)","3d8f89d7":"setBooleanValue(string,bool)","3d908c82":"distributeTokensToAllUsers()","3d90d44d":"addPowerSource(address,uint256,uint256)","3d90eeb9":"getCartSubtotal(address)","3d91eec0":"NebbexToken(uint256,address)","3d922f90":"depositar()","3d9277f0":"unlockTip(bytes32)","3d9287fa":"whitelisted()","3d937410":"CokecoinTokenTest()","3d937824":"setCompte_35(string)","3d93a355":"InTokenTest12(uint256,string,uint8,string)","3d944953":"withdrawCollectedResources()","3d946410":"isPreSalePeriod()","3d946c53":"restartElection()","3d94e23b":"viewXCAT(address,address,bytes32)","3d955aa3":"poll(uint256)","3d956691":"tokensToSell()","3d957b0b":"third_bonus_amount()","3d960ec3":"round2Sold()","3d96c758":"TreeLim()","3d96fa3c":"getAllDelegatorAddress()","3d972839":"withdraw(uint16)","3d9aa932":"oraclize()","3d9ad7ce":"SENIUM()","3d9aeef0":"isBetStorage()","3d9af4d1":"setMigrateDueToNoReports(bool)","3d9ce89b":"scheduleCall(bytes4,bytes,uint256)","3d9dcb07":"getFamedStarByID(uint256)","3d9e23ca":"PartnersFund()","3d9e4233":"registerAlbum(bytes32[],bytes32[],bytes32[],bytes32[],bytes32,bytes32)","3d9f01fb":"renterOf(uint256)","3d9f923b":"updateDenomination(bytes8,address)","3da01325":"blockUser(address)","3da04e4a":"getUserGroups(address)","3da06d6c":"getTemporaryWinningFaction()","3da09d40":"Ripple()","3da0ac79":"compare()","3da1c0c3":"isVerifiedUser(address)","3da1eff5":"claimOwnerSupply()","3da1f79a":"revokeSignature(uint256)","3da216da":"LuckyMoneyToken(uint256,string,uint8,string)","3da32dc5":"FcsCoin()","3da368c0":"ETHcomeback820()","3da4ba4a":"AiboCoin(address,uint256)","3da55aba":"setZlotsAddress(address)","3da5c3ce":"puzzle(address,bytes32)","3da5d173":"ZeroExExchange(address,address)","3da611cd":"ContractEthLimitChanged(uint256,uint256)","3da64a06":"issueTokenToGuaranteedAddress(address,uint256,bytes)","3da69ff4":"Salome()","3da76788":"getDataLength()","3da79946":"allEthOUT()","3da80d66":"contains(address[],address)","3da98498":"Crowdtes()","3daa33d5":"buyAndSellPrice()","3daad222":"asmTransferFrom(address,address,address,uint256)","3dab45b6":"setMtdPreAmount(uint256)","3dabb0f6":"verifySignature(address,address,uint8,bytes32,bytes32)","3dac68b7":"setAddressAdv(address)","3daceda1":"createSyndicate(address,uint256,uint256,uint256,uint256)","3dad1583":"getAyes(uint256)","3dae94f0":"cumulativeIndexOf(uint256[],uint256)","3daee1b8":"weekThreeRate()","3daefe4b":"Election1()","3daf099f":"transferEthereum(uint256,address)","3daf31b5":"withDecimals(uint256,uint256)","3dafbf92":"SNPToken()","3db05068":"toForecastData(uint8,uint8,bool,uint8,uint8)","3db08826":"isProofValid(bytes32[],bytes32)","3db13fec":"PalletOneToken()","3db1c253":"projectFailed()","3db1f00a":"TOSMidHoldingContract()","3db2254b":"deleteAllReports()","3db2a12a":"Empty()","3db36b5f":"transferTokensFromTeamAddress(address,uint256)","3db3f2cf":"submitBid(address,bytes32)","3db62953":"currentExchangeSystem()","3db7a118":"blockDotDifficulty()","3db7c149":"SmartCityCrowdsale(address,address,address,uint256,uint256,uint256)","3db7e347":"contributorAt(uint256,uint256)","3db80346":"closeGroup(uint32)","3db8352d":"setEvaluator(uint256)","3db8433c":"setLeagueRosterAndCoreAndContestContractAddress(address,address,address)","3db8493a":"put(uint256,string,string)","3db9c4aa":"createIntention(address)","3dba0b57":"MCTTokenAddress()","3dba6197":"etherAccumulator()","3dbad089":"Contribute(address,address,uint256)","3dbae017":"EasyToken()","3dbae9f9":"startIcoTwo()","3dbb07ac":"s28(bytes1)","3dbb270d":"AshCashToken()","3dbb7f46":"setPrizeFundFactor(uint256)","3dbb874e":"getPetClaims(uint64)","3dbba05c":"callDefaultRelease()","3dbc7c69":"totalApproval(address)","3dbe56f0":"getUnfreezedTokens(address)","3dbe6469":"ChangeBuyer(address)","3dbedbd4":"StopICO()","3dc02266":"fipsRegister(uint256)","3dc09a70":"OwOToken()","3dc0d600":"nome_vincitore()","3dc11dd1":"ethSwapRate()","3dc1579a":"RELEASE_TIME()","3dc19db8":"addAdministator(address)","3dc1a6bc":"getSkillLength()","3dc1ef34":"limitMaxSupply()","3dc23486":"_addBalance(address,uint256,address)","3dc268a6":"oraclize_query(uint256,string,bytes[2],uint256)","3dc286ae":"getEncSeckey()","3dc37539":"reveal_test_data(int256[],int256)","3dc38fc1":"addCourse(uint256,uint256)","3dc4cac9":"Mycryptonline()","3dc58149":"getDepositRecord(address)","3dc5bf97":"acceptRegistrarTransfer(bytes32,uint256)","3dc60e52":"getKittyCount(address)","3dc6e9b0":"changeMaxLockDuration(uint256)","3dc7426e":"setMaximumMintableQuantity(address,uint256)","3dc7c549":"sumHardCapICO()","3dc7ea7f":"recently_added_address()","3dc9124e":"numOfLoadedCrowdsalePurchases()","3dcb0b81":"PollManagedFund(address,address,address,address,address,address,address,address[])","3dcb66db":"Storer()","3dcbab40":"UnFrozenFunds(address,uint256)","3dcbf7eb":"addAddressToAccountFor(address,bytes,bytes,address,bytes32)","3dcd351f":"getAllReceipt()","3dcd6176":"returnTokenBalance(address[2],bytes32)","3dce1ea9":"curPayoutId()","3dced193":"getPI_edit_33()","3dcf59ca":"initiateMigration(address,address)","3dcfbdd0":"getBrickAddress()","3dd00c42":"getMyMinersAt(uint32,uint32)","3dd02f06":"setCoinStorage(address,address)","3dd16673":"teamETHAddress()","3dd287d4":"monsterNFTContract()","3dd297da":"safeMultiply(uint256,uint256)","3dd2b811":"CSNO()","3dd2e0f0":"optionTotalTimes()","3dd35279":"memberIndex(address)","3dd5b2da":"withdrawContractETH()","3dd5e0ec":"NewSouth21Token()","3dd7609a":"ETHER_AMOUNT()","3dd7b14b":"optionPoolBalance()","3dd7c1b9":"newProduct(string,string,uint256,uint256)","3dd82637":"Transformers()","3dd83fe1":"newPlayer(address,uint256,uint256)","3dd86478":"isFromState(address,address,uint256)","3dd93a8a":"getUsersGeneratorsIds()","3dda1aff":"Football()","3dda37dc":"flags(address,address)","3dda7b1d":"fuddToken()","3ddac459":"changeminpresale(uint256)","3ddb77bd":"_distDay()","3ddc3277":"charityFoundationIdx()","3ddc8e9c":"fixedLoge(uint256,uint8)","3ddcbace":"Escrow(address,address,address)","3ddd4698":"registerNameXaddr(string,address,bool)","3ddd5313":"acceptPayments()","3dde1598":"redeemBattleCrates()","3dde3918":"removeAdministrators(address)","3de035bf":"endWork(uint256)","3de1a4bc":"getDepositPool()","3de24c17":"refundInvoice(address,address)","3de33a32":"doIssueTokens(address,uint256)","3de377ec":"mock(uint256)","3de39c11":"maxGasPrice()","3de3ebf8":"getPlayerEnergy(address)","3de3fbd9":"totalTokenRewards()","3de4ca9e":"Karma(address,address)","3de4eb17":"getAdopters()","3de696d3":"percentFeeTimes5()","3de6a03f":"checkStatusICAP(bytes32,uint256,string,address)","3de7dfb1":"Amount_of_Chi_for_One_ETH()","3de8c792":"BUYER_STEP_4(bytes32,uint256,bytes1,address)","3de8d340":"dividendsBlocks()","3de9c8e6":"haltFundraising()","3de9e4c6":"__transferFromWithReference(address,address,uint256,string)","3dea6b9a":"getMeme(uint256)","3deaa297":"transferAllDividends()","3deaa323":"minPurchaseLimit()","3dead9e8":"Mythereum()","3deaf6d4":"MAXIMUM_FIRST_DAY_CONTRIBUTION()","3deb23d2":"STANDARD_RATE()","3deb91c7":"setMinReserve(uint256)","3debd2d8":"sendToAddress(address,uint256)","3dec4cb3":"pre_ico_start()","3dedc36e":"getGunByIdPart2(uint256)","3dee7237":"amountOfBPs(address)","3def449b":"FipsNotary()","3defb962":"heartbeat()","3df08c6a":"privateSalesTokensSold()","3df16377":"make_move_and_claim_victory(uint256,uint8,uint8,uint8,uint8,uint8,uint8,uint8)","3df18d2a":"model(address)","3df18e0a":"bytes32ToHex(bytes32)","3df19507":"intToDec(uint256)","3df2b29d":"powerDown(address,address,uint256)","3df2b723":"adminClaimAirdropMultiple(address[],uint256[])","3df2d6fd":"FIGHTMONEY()","3df40c7a":"startPreIcoDate()","3df4a282":"setCurrentSaleDayAndBonus(uint8)","3df4ddf4":"first()","3df5140c":"setIsTokenCanBeSell(bool)","3df5958f":"VillanovavsRadford()","3df6b23c":"angelRound()","3df76482":"fipsPublishData(bytes20,bytes)","3df77c0e":"testBalanceOf()","3df7c86d":"mom()","3df86f79":"split32_20_12(bytes32)","3df91162":"getUpdatable(bytes20)","3df95fc9":"HAYATO()","3df96853":"carIdToRenter(uint256)","3dfa0384":"messageSenderAddress()","3dfa1c46":"LLV_v31_5()","3dfb4843":"renewDeed(bytes32)","3dfc42c8":"TdeFinalized(uint256)","3dfc6980":"set_verifiedUsersOnlyMode(bool)","3dfca2ad":"finishVoting(address,uint256)","3dfcdf2b":"CoinVila(address)","3dfd288a":"checkVotingForTransferWeiFromExchangeToPayment()","3dfd83c6":"SPARCToken()","3dfeac48":"MaximalInvestmentChanged(uint256)","3e00b910":"buyTokenPreIco(address,uint256)","3e011b11":"getTokensBackAFterCorwdsale()","3e032a3b":"slippage()","3e03c84f":"tokenIsLocked(address)","3e03d50f":"isTeam(uint256)","3e0448c2":"ChangedId(address,string)","3e045845":"issueSecurityTokens(address,uint256,uint256)","3e04bf23":"upgradeShip(uint32,uint8)","3e058664":"getBonusPercentRate()","3e05c964":"withdrawnByBeneficiary()","3e05ca7c":"get_PendingGains(address,address,uint256,bool)","3e05e01b":"ethReward()","3e0663e0":"AdminDrawProcess()","3e06be20":"downgradeToBasic(bytes32)","3e07905e":"endBuffer()","3e0807ca":"numberBtcUpdates()","3e0831e2":"putStoWithBto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","3e083f7d":"deals(uint256,uint256)","3e085c3d":"airDropToOldTokenHolders(address[])","3e085d0e":"transfer(address,uint48,bytes,string)","3e087d01":"addEligibleBurner(address)","3e0912ec":"KangEOS()","3e093f38":"testPullWithTrust()","3e09876a":"vehicleFound(address,uint256)","3e0a322d":"setStartTime(uint256)","3e0a51b4":"TweetAccount()","3e0a7ab5":"addONG_AUDIT(bytes32,string,string)","3e0aba92":"fourth_release(uint256)","3e0ad2d4":"TPC(uint256,string,string)","3e0aedaf":"TreePlusToken()","3e0b7eb2":"updateTranscoderWithRewards(address,uint256,uint256)","3e0c1f2a":"fetchNextSnapshotBlock()","3e0d4f4a":"ApproveContractorProposal()","3e0dfbdf":"getInvestorByAddress(address)","3e0efe67":"putBtcWithSto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","3e0fddbd":"ClaimHodlToken(address,uint256,uint256)","3e1092f2":"changeModuleRegisterOwner(string,string,address)","3e109a19":"minBid()","3e112bf3":"calcResult(uint256,uint256,uint256)","3e112ed7":"reserveCoins(address,uint256)","3e11456f":"PRIVATE_SALE_ACCOUNT()","3e11741f":"sellToken(address,uint256,uint256)","3e118dbe":"_version()","3e118f1f":"weiMinSaleIco()","3e11b765":"batchApprove(address[],uint256[])","3e11e378":"changeController(address,address)","3e127ab7":"maxPoly()","3e127e76":"safe_add(uint256)","3e129967":"SpaceWar()","3e1457a1":"initRates(uint256[],uint256[])","3e152d8e":"maxBonusTickets()","3e15346d":"removeGlobalConstraintPost(address,int256,address)","3e156601":"p_setMinInvestment(uint256)","3e15ef90":"GetDataPoint(uint256,uint256,bool,string)","3e165810":"initBMC(address,uint256,uint256,uint256,uint256)","3e175c0b":"goldUnFreeze()","3e17b882":"mutateCrabPart(uint256,uint256,uint256)","3e18117a":"AhooleeToken()","3e182d3f":"addSelctFight2Death(address,uint256,uint256,uint256,uint256)","3e18e78e":"endTimeinMinutes()","3e1a3376":"updateInvestorsComission(uint256)","3e1a420f":"publishRewardlessTaskListing(string,address,uint256,uint256)","3e1a9300":"getLastIndex()","3e1b0d29":"fechAllVotersBySnapshotBlock(uint256)","3e1b4645":"qualifiedAddress(address)","3e1b5b3e":"rateEarlyStage4()","3e1ba676":"subBountySupply(uint256)","3e1c01b5":"capitalAllocation()","3e1c2d5a":"RegisterKey(address,string)","3e1cc152":"fundWallet2()","3e1d8156":"Issue(uint256,address,uint256)","3e1da046":"isDelegateOf(address,bytes8)","3e1e292a":"testCopy(bytes)","3e1eab35":"VUTEST2()","3e1fd0da":"checkAccess(bytes32,address)","3e20f7fb":"HashnodeTestCoin()","3e214e96":"changeAirDroper(address)","3e2153bf":"viewBeneficiaryDetails(address)","3e21b00f":"C40Coin()","3e239e1a":"getHour(uint256)","3e23ee7e":"executeTrade(address,address,uint256,uint256,uint256)","3e23ee9c":"BlackHorseWallet()","3e24fcbf":"capHicsToken()","3e254a0c":"YTCOMMUNITY()","3e2557c5":"_price_tokn_ICO_second()","3e25e837":"withdrawCommission()","3e25fdd4":"getLastStellar()","3e260a2c":"allocateReserveTokens()","3e262e46":"getTradeOfferSender(uint256)","3e2640d6":"extendClosingTime(uint256)","3e2729bf":"isRevocated(bytes)","3e27e1be":"validateResetDeadTokens(uint256)","3e28912f":"getStrField3()","3e2d6cf6":"_emitWithdrawn(address,uint256,address)","3e2d7004":"getTokenRate()","3e2d7de1":"mintTokensWithIncludingInJackpot(address,uint256)","3e2ddb60":"changeMajorThreshold(address,uint256,bool,bytes)","3e2e806d":"rewardTokensFloor(address,uint256,uint32)","3e2ee39e":"debug_resetuser()","3e2fce37":"updAutoFreeze(bool)","3e2fe149":"getNewOwner()","3e30046a":"maxSale()","3e30838d":"delOperator(address)","3e313f28":"_changeColour(uint256,uint8,uint8,uint8)","3e31c77f":"setZoPrice(uint256)","3e321249":"PdexToken(address)","3e32224a":"BF1Token()","3e325589":"init(address,address,uint256,int8)","3e326048":"initWallet()","3e32bea2":"priceIncreasePerPurchase()","3e33c37b":"gameContext(uint256)","3e345bd8":"FatherToken()","3e34f34e":"isUserHasPermissonToModify(address,string)","3e351a45":"lotteryWinner()","3e352d49":"updateTokensForEtheeraTeam(uint256)","3e361281":"betsWon()","3e362c96":"bountyCount()","3e363696":"BuyWithPathwayFromBeneficiary(address,uint256)","3e3657a5":"addConfigEntryInt(bytes32,uint256)","3e3756db":"PauseOn(uint8)","3e379d64":"setBonus()","3e38a2b7":"delegateCount()","3e38dab8":"refundFlip(bytes32)","3e3926e4":"whitelist(address,uint256,uint256,uint32)","3e3b429a":"canPurchase(address)","3e3bc743":"AmazingDex(address)","3e3c9eae":"qsize()","3e3cba8f":"changeBalancesDB(address)","3e3ce4f3":"GSEN()","3e3d64e2":"hatchingsNeeded()","3e3dae41":"maximumSaleLimitUnits()","3e3deb8b":"MyMonsterCount(address)","3e3dff65":"GainsCalculated(address,uint256,uint256,uint256,uint256)","3e3e0b12":"stopMinting()","3e3ee859":"NewQuestion(string,bytes32)","3e3f4e24":"RealEstateCryptoFundAirdrop(address)","3e40aab4":"returnActions(uint256[8],uint256)","3e412533":"Easy()","3e415358":"transfer(address,uint256,address,address,uint256,uint8,bytes32,bytes32,uint256)","3e41d5eb":"addOwnersWithHowMany(address[],uint256)","3e427e89":"returnHostAndCreatorCut(uint256)","3e42ad79":"Instantium()","3e42ed80":"ProgressiveToken(string,uint8,string,uint256,uint256,uint256,address)","3e43b652":"betValueOf(address)","3e43e8b4":"AnimeToken(address,uint256)","3e441ef4":"SetItem(address,uint256,address)","3e445446":"STARTING_KILOS()","3e445506":"successfulPreSale()","3e44694f":"DID()","3e4476a3":"addAddressToJackpotParticipants(address,uint256)","3e450fff":"adminDeleteAccount()","3e4565d2":"testErrorUnauthorizedNameRegister2()","3e4604b3":"robotAddr()","3e460a84":"distributeBooking(uint256)","3e46eb60":"fortune_endauction(uint256)","3e476053":"moveFunds(address,uint256)","3e4852bd":"getGroupData(uint256)","3e4882fc":"AddressChangeConfirmed(address,address)","3e49077a":"createSaflokKey(bytes32,bytes32,bytes32,bytes32)","3e49776b":"VOLUME_5()","3e49820d":"changeTicketCap(uint256)","3e499dff":"addKYC(address)","3e49bed0":"setInt(bytes32,int256)","3e4a9263":"enforceSecondLock(address,address)","3e4b20cf":"updateGameSpecifics(uint256,uint256)","3e4b2570":"investorsAllocation()","3e4bdce4":"hasAccountPendingOrders(address)","3e4bee38":"GOLD()","3e4c0c82":"player_1(uint256)","3e4c9534":"getInvestmentMin()","3e4d914e":"lastBlock_f12Hash_uint256()","3e4e0432":"notifyOfArbitrationRequest(bytes32,address)","3e4f49e6":"state(uint256)","3e4ffa9b":"getImage(uint256,bytes32[],uint256,uint256)","3e5087cc":"testBasicThing()","3e50b0b8":"sendOwnerEther(address)","3e50de30":"calculateRewards()","3e510870":"transferOPSPool()","3e52d5c6":"openBoxes(uint256[])","3e531e0d":"queryGameStatus(uint256)","3e53ccee":"actualPriceDivisor(uint256)","3e5442bd":"getBitsoAddress()","3e546675":"DelegateDualOwnable(address,address)","3e55eab0":"parcipateCrowdsaleInvestor(address)","3e5615bc":"FourToken()","3e568fe7":"GetDaysInOffice()","3e56f9f9":"getPayout(uint256)","3e57324e":"EmergencyPause()","3e586a81":"BeatTokenEthPriceChanged(uint256)","3e589050":"changeKeys(string,bytes1[])","3e58a465":"getShareList()","3e58c58c":"send(address)","3e592d50":"ResourcesOwner(uint8,address)","3e5933fe":"removeAll(address[])","3e5a2024":"MyActive()","3e5ac28f":"toggleTransfers()","3e5b15e1":"addCoin(bytes4,address)","3e5b5e39":"addPrecommitment(address,uint256,bool)","3e5b7fec":"TwoPhaseAuction()","3e5beab9":"allowance(address)","3e5cee05":"issueIOU(string,uint256,address)","3e5d5cee":"sellPriceAtIndex(uint256)","3e5d901e":"autoTokenSent()","3e5daf02":"startRoundC()","3e5edb1d":"REFUND_LOCK_DURATION()","3e5efd92":"clearProcessedBet(uint256)","3e5fbedd":"NOTNCoin()","3e5fd9b5":"dEthereumlotteryNet(address,address,bool,address)","3e604f48":"registerAadharDetails(string,string,string)","3e6075a4":"battleCountOf()","3e60c83a":"acceptMediation(uint256)","3e62d835":"setNumberOfOutcomes(uint256)","3e650c15":"withdrawalUser()","3e65a153":"longMul(uint256,uint256)","3e675cb0":"changeMaxValueBetForEmission(uint256)","3e6784b8":"ATLToken()","3e68119b":"setDebugNumber2(uint256,uint256)","3e681375":"totalDropAmount()","3e68680a":"create(address,address)","3e68aa3a":"getTopWinners(uint256)","3e68dea3":"BaseAccountService(address,address)","3e693ffd":"AppSet(address)","3e6968b6":"getCurrentDay()","3e6a569a":"claimReward(address,string)","3e6a6a31":"beneficiarySend()","3e6b16d9":"setShowInterval(uint256)","3e6c0637":"getFirstStartableIndex()","3e6d4e12":"getOptional(uint40)","3e6d6a6b":"setAdvisorAddress(address)","3e6d6d0b":"removeMastercardUser(address)","3e6d6d26":"withdrawAllTokens(uint256)","3e6d9770":"investments(address,uint256)","3e6e0adf":"whiteListPeriod()","3e6e2a73":"_mintEstate(address,string)","3e6eaa03":"mint(uint32,address)","3e6f118a":"blastOff(address)","3e6f4160":"roundParameters(uint256)","3e709982":"isDefValid(uint8,uint8,uint8,uint8,uint8)","3e715da2":"logPromiseFulfilled(uint256)","3e721015":"getFunds(uint256)","3e72b2bb":"addMembers(address[],uint256[])","3e72df41":"ff(string)","3e76018b":"getNextMinimumBet()","3e7614cd":"TIER3_PRICE()","3e764fdb":"_getNewFloorGene(uint256)","3e774409":"_mint(address,address,uint256,bytes,bytes)","3e77dcfb":"setPercentages(uint8,uint8,uint8,uint8,uint8,uint8)","3e786d80":"DickheadCash()","3e788ba3":"getRequestState(address,address)","3e78afd8":"ReferrerBonusTokensTaken(address,uint256)","3e78cf7a":"transactionFeeMin()","3e798e83":"calculateUserCommission(uint256)","3e799335":"RefundManager()","3e79e4c2":"customerPolicies(address,uint256)","3e7b684d":"NBAT(address,address,address,address,address)","3e7bb43c":"transferKycOwnerShip(address,address)","3e7cb0d3":"verify(uint256,bool)","3e7d081a":"emitBoardClosed(uint256,bool)","3e7d1acc":"currentAllocationLength()","3e7e250e":"GetDynamicCardAmount(uint32,uint256)","3e7e30ba":"poolPercentage()","3e7e42fa":"initialCreatorAccount(uint8)","3e7e70a4":"tokenBuyerWallet()","3e7e730d":"addressToReceiverToAmountAllowed(address,address)","3e7f26a5":"heroIdToBuyer(uint256)","3e7f54a9":"updateAppInstance()","3e803343":"subIsSafe(uint256,uint256)","3e80cbc6":"adminUpdateWallet(address)","3e81ba66":"preBountyAdded()","3e81d56e":"calculateProviderFee(uint256)","3e82055a":"addSignature(uint256,bytes16,bytes)","3e82eca7":"getAddressOne(address)","3e83f6cd":"Nickelcoin()","3e83fe36":"getMyShares()","3e84b266":"priorityPassContractAddress()","3e853128":"getGasForXau(address)","3e85713d":"marketingReserve()","3e85755a":"bonusInPreSalePhase2()","3e859fcb":"updateCap(uint256,uint256)","3e8616c8":"setBullAmount(uint256)","3e867089":"setDelegadoDeEscuela(bytes32,bytes32,uint256)","3e8686cc":"getSubmission(uint256)","3e86a2e5":"transferToAddress(address,uint256,bool,bytes)","3e870d63":"subHashrate(address,uint256)","3e8786a1":"reclaimFund(address)","3e87d301":"tokenPriceInEuroCents()","3e8817aa":"getPaymentAmount()","3e88d93b":"getRecorderID(address)","3e89340f":"lockStatus()","3e8a0585":"Bidding()","3e8a0bc9":"lockdown()","3e8a76e4":"CommerceBlockToken(address)","3e8a9439":"proposalDestination()","3e8b1dd7":"claim(bytes32,uint256,uint256,uint8,bytes32,bytes32)","3e8be2e1":"reTweetRewardPool()","3e8c34e5":"cardboardUnicornTokenAddress()","3e8cc273":"doBlockContract()","3e8ce607":"successfully_closed()","3e8cee07":"getPOOL_edit_5()","3e8cfa26":"Nut(uint256,string,uint8,string)","3e8d6e9f":"multyTx(address[100],uint256[100])","3e8d97e7":"underwriteToken()","3e8eca23":"plusFreezingTime(uint256)","3e8f5b90":"setConfig(string,uint256)","3e8f682f":"setETHFee(uint256)","3e8ff43f":"converterType()","3e904876":"devexit()","3e9196b4":"NokuTokenBurner(address)","3e91a622":"LOCToken()","3e92128c":"gettruelevel(address,uint256)","3e92fa26":"claimComputation(bytes,bytes,uint256)","3e9491a2":"revenue()","3e94c904":"collectionOf(address)","3e955225":"getN()","3e95c9b6":"MOONTRAIL()","3e95f06d":"_handleProductionDecrease(address,uint256)","3e96c107":"People(uint256,string,uint8,string)","3e96d28e":"setReleaseAgent()","3e96e868":"addRole(string)","3e9744da":"walletBountyAndAdvisors()","3e9761b4":"projectIndex(uint256)","3e97db0d":"changeMainWallet(address)","3e97ee6c":"isOwnerOfAllPlayerCards(uint256[],address)","3e98039a":"multiOwnerSides()","3e9836c6":"oraclizeGas()","3e98b93a":"getAvatarCount(address)","3e99633f":"haltIEO()","3e997e71":"isPeronalLock(address)","3e99a35e":"BitMantas()","3e99c395":"isValidPublicKey(uint256,uint256)","3e99d2c9":"Foo(string,string)","3e99e26a":"SellableToken(address,address,address,uint256,uint256,uint256,uint256)","3e9b4c24":"CNToken()","3e9bee1b":"getBalanceDivis(address)","3e9c77f9":"ListingRegistry(uint8,uint8,uint8,uint8)","3e9e9f26":"distributeCallback(uint256,uint256,address[])","3e9eb6c1":"recursive_read(uint256)","3e9ed7e4":"burnSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","3e9f9664":"withdrawItem(address,uint256)","3ea053eb":"deactivate(address)","3ea0fb3e":"getCurrentPrice(uint32)","3ea11222":"createGame(uint256,address)","3ea14a4f":"escFund()","3ea252eb":"finalOptions()","3ea2cde5":"addFiatCurrencyRaised(uint256)","3ea376fc":"changeAdmin(address,address,bytes32[3],bytes32[3],uint8[3])","3ea3c2bb":"_updateFundingGoal()","3ea3e42f":"AgriChainRootData()","3ea3f6c5":"activateRegistrar()","3ea51dc2":"ZIRC()","3ea556da":"getEtherForTokens(uint256,uint8)","3ea5cdba":"MIN_INVESTMENT_ICO_PHASE_ONE_POUNDS()","3ea69d76":"setEmployee(address,bytes32,bool)","3ea6c986":"ltcRaised()","3ea75e3d":"addJobContractMessage(address,address,address,string,uint256)","3ea79cb1":"MSCToken()","3ea89fd1":"popQueue()","3ea97009":"initialToken()","3eaa7643":"eligibilityRate()","3eaa8128":"buyCovfefe(uint256)","3eaab2dc":"FabotCoin()","3eaaf86b":"_totalSupply()","3eac48a0":"getTotalVoter(address,address)","3eac5cac":"PayingBackContract()","3ead67b5":"changeContractOwner(address)","3eadb6db":"nextPhase()","3eae396f":"GodzSwapGodzEtherCompliance()","3eae8ac8":"SkillChainPresale(uint256,uint256,uint256,address,uint256,address,address)","3eaf5d9f":"tick()","3eaf7591":"makeVote(uint256)","3eaf9923":"right68(uint256)","3eafec21":"sellTokens(address,address,uint256)","3eb10ab3":"FundAccount()","3eb1d777":"setStage(uint256)","3eb1eb1a":"issuingBody()","3eb2a37d":"priceCreatingChannelChanged(uint256,uint256)","3eb2b5ad":"addTeamMember(address)","3eb2cb02":"totalSquareStakesByUser(address,uint256,uint256)","3eb34e09":"AlterContactName(bytes32,address,bytes32)","3eb3aaad":"_getClosingObligation(bytes32)","3eb51dc4":"releaseForTeamAndAdvisor(address,uint256)","3eb54d80":"Pele()","3eb578bf":"ADVISER_STAKE2()","3eb5caca":"setProductType(uint8,string)","3eb610f5":"_requestContractApprove(bytes32,address)","3eb76b9c":"castVote(uint256)","3eb78420":"mainFundAccount()","3eb7dbc0":"FoxTradingToken()","3eb96aed":"DrunkCoin()","3eba223c":"CopyTokens()","3eba9ed2":"setBooleanValue(bytes32,bool)","3ebb047f":"allowanceTransfer()","3ebb2a17":"CreateTokenToMarket(address,uint256)","3ebb2d6b":"instructOracleToDistribute(uint256)","3ebbf394":"BergCoin()","3ebc2ab3":"isCompromised(address)","3ebc457a":"closeCurrentFeePeriod()","3ebd6092":"checkPermission(uint8,address)","3ebdc754":"setDiscipleSale(uint256,uint256)","3ebfc934":"transferFrom(address,address,string)","3ebfdaaf":"Swap()","3ebfde04":"proceedPreIcoTransactions(address[],uint256[])","3ec045a6":"auditor()","3ec16194":"calculateShares(uint256)","3ec1d668":"Vendor(bytes,uint256)","3ec27341":"getConfigAddress()","3ec27c4a":"setTimeRangeGen0(uint256)","3ec36b99":"commitVotes(uint256[],bytes32[],uint256[],uint256[])","3ec3aedc":"executeSell(address,uint256,uint256)","3ec414c8":"editMeta(string,uint256)","3ec48a2e":"move()","3ec548b6":"initLottery(uint16,uint256,uint8,bytes32)","3ec6a4c4":"getContributorsCount(address)","3ec6dac2":"getSize(bytes32)","3ec862a8":"hatchEggs(address)","3ec8d571":"TronToken(address,address)","3ec8ec5a":"getFinish()","3eca264e":"getWithdraw(address)","3eca443b":"generatedTokensSale()","3eca48db":"BonusesAllMinted(address)","3ecae564":"canSend(address,address,bytes32,uint256,bytes)","3ecafef5":"isIcoStart()","3ecb9884":"frozensDetail(address)","3ecbbf39":"list(address,address)","3ecbf72a":"_find(address)","3eccca1e":"transferAllTokens(address,address)","3eccd456":"initializeSale(address[5],uint256[6],uint8,bytes32,bytes32,uint256,uint256)","3ece9c61":"teamHoldAmount()","3ecf965f":"rateETH_BCDT()","3ed01e02":"takerDispute(uint256,uint256,uint256)","3ed03798":"addToStat(uint256,uint256)","3ed0619b":"stabilityBoardProxy()","3ed08dc9":"balanceOfEthFee()","3ed0a373":"getDepositAtIndex(uint256)","3ed0f52c":"setCustomBonus(address,bool,bool,address)","3ed10b92":"allowances()","3ed23f91":"BlockPayeeToken(uint256,string,string)","3ed28f39":"getUniCoinSize()","3ed2d908":"buyerTokenName()","3ed35855":"removePayee(address)","3ed38181":"setInvalid()","3ed3d6a6":"getthird(uint256[])","3ed4006b":"OwnerCashout()","3ed4c4c8":"phaseAddtlInfo(uint256)","3ed58536":"record_human_readable_blockhash()","3ed5d456":"finishReplayPhase(uint256)","3ed620a4":"updatePrices(uint256,uint256,uint256)","3ed66d3d":"sellMintingAddress(uint256,uint256)","3ed70628":"SCPSToken(uint256,string,string)","3ed72caf":"icoTokenAddress()","3ed731bc":"makeCollectibleUnavailableToSale(address,uint256,uint256,uint256)","3ed7530d":"amountOfPerRelease()","3ed8ff25":"TotalFeesReceived()","3ed9bc86":"initializeToken()","3eda009b":"rewardRound(uint256)","3eda062c":"updateTap(uint256)","3eda7b88":"contractorTransferFrom_Scoupon(address,address,uint256)","3edab9d0":"AuctionCanceled()","3edaf264":"stopBounty()","3edbd76e":"GetChallengeCreator(uint256)","3edc65d3":"recordWithdraw(address)","3edc69b8":"maxAbsKindness()","3edcd61f":"times8()","3edd1128":"deposit(address,uint256,bool)","3edd90e7":"NewOwner(address)","3edddc0a":"incrementWrite()","3edef04b":"limitPreIcoTokens()","3edfd954":"mint(address,uint256,uint256,uint256,string)","3edfe35e":"ethPriceInCents()","3ee066e5":"sspRegistry()","3ee0c627":"currentBadge()","3ee2dd16":"FunGame()","3ee39cee":"testCannotActivateBeforeDeployingANT()","3ee3f499":"validateHash(bytes32)","3ee5313f":"SetState(uint256)","3ee58d13":"testBurnGuyAuth()","3ee5f2e4":"BreakToken()","3ee6d933":"rndInit_()","3ee6de34":"work(bytes32[])","3ee71e85":"NortontokenERC20(uint256,string,string)","3ee788e1":"_updateLoveStory(bytes16,bytes32,bytes32,uint256,string)","3ee7ab85":"airdropUpdateToken(address[],uint256[])","3ee822f4":"setAllLocations(uint256[])","3ee8747a":"isOrganisationExits(address)","3ee89a63":"withcom()","3ee90a29":"FOUNDER_STAKE()","3ee9d648":"lastGameId()","3eea5150":"milkTotalSupply()","3eeafccc":"getCountryStats(uint256)","3eeb3235":"geCompoundTimestampsFor24Months(uint256)","3eebc589":"isMarketManager()","3eed3822":"bigPrice()","3eed5d17":"Cipher()","3eeda7d3":"deliverTokens(address,uint256,string,bool)","3eedabcf":"getMelonAsset()","3eedf7d8":"getCurrentAuctionPrices(uint128[])","3eee36c6":"_split(uint256,uint256,uint256)","3eee83f1":"addAcceptedToken(address)","3eeeb1c3":"fastEscape()","3eefe239":"mintReservedTokens()","3eefef7b":"testFailTransferFromSelfNonArbitrarySize()","3ef06b6b":"previousprice()","3ef0784e":"configurationGenericCrowdsale(address,uint256,uint256)","3ef13367":"flushTokens(address)","3ef37e30":"REFUND_PERCENT()","3ef39571":"isRequireData()","3ef4691f":"MyFreeCoin(uint256,string,uint8,string)","3ef4c16b":"withdrawVPC0xTokens(address)","3ef4f4ca":"world(uint256)","3ef5aee9":"maxProportion()","3ef5d325":"getBaseValue(uint256)","3ef5e445":"subtract(uint256,uint256)","3ef5f368":"payMultiple(uint256)","3ef7c687":"getExpiringUnitList()","3ef84fcb":"withdrawCommonCoin(uint256)","3ef87414":"getRevisionCount(bytes20)","3ef8e872":"numberOfTokensOfOwner(address)","3ef8ec78":"announce_numbers(uint8,uint8,uint8,uint8,uint32,bytes32)","3ef92150":"ICO(uint256)","3efa31b0":"initialAddress(address)","3efa8d51":"feesD()","3efab21b":"icoTokensIssued()","3efb537e":"getPastGameResults(uint256)","3efb760d":"nextLevel()","3efcad6d":"EMPR()","3efcd2e0":"transferPreSigned(address,uint256,uint256,uint256,uint8,bytes)","3efd1403":"createGame(uint8,bytes32)","3efe54d4":"percentWeiDividend()","3efe6441":"getRemainingToken()","3efea4d1":"buy(uint256,uint256,uint256,uint256,string,string,string)","3eff1ef3":"DYBToken()","3f001dd7":"MIC(uint256,string,string)","3f003d59":"removeAddressFromGrantAccess(address)","3f00f5aa":"HAOToken()","3f01dc99":"ETHFINEX_FEE()","3f01e642":"roundCount(uint256,uint256)","3f0218ac":"startThirdPhase()","3f021e2e":"oracalize_gaslimit()","3f02e4f0":"getTotalValidTk()","3f03aab4":"communityAddr_()","3f045e61":"inArray(address[],address)","3f047053":"songTokenExchange()","3f04b06d":"shareLove(address,address,uint256)","3f050f02":"subdomainSale()","3f056d2a":"StrongHoldTEST()","3f06e17c":"changeDonation(address)","3f073031":"addCredits()","3f07618d":"createDragon(address,uint256,uint256,uint256,uint256,uint240)","3f08882f":"assertIsWhitelisted(address)","3f089de9":"GameRefunded(uint256)","3f09ba9c":"TupleDemo()","3f0a0797":"exchangeContract()","3f0a9f65":"requiredBlockConfirmations()","3f0adce9":"setSmallWalletAddress(address)","3f0b67e9":"_addIndex(address,address)","3f0b70b6":"itgTokenTransfer(uint256,bool)","3f0cea3f":"withdrawOwner(address)","3f0cf183":"MockSale(uint256,uint256,address,address)","3f0d9ad5":"contractBalance_()","3f0ec70b":"RequestFactory(address)","3f0ed0df":"setContract(string,address)","3f0f7248":"SpaCoin()","3f109205":"setFoundationInterface(address)","3f10dea6":"canUse(address,uint256)","3f10f08a":"nextCommonTTMTokenId3()","3f117b85":"setPaymentContractAddress(address)","3f1199e6":"buried(address)","3f11e43d":"newEtherdelta(address)","3f124f1d":"totalMintContracts()","3f13d339":"getTxnNum(address,uint256)","3f14710d":"GameEnded(address,address,uint256,uint256,uint8)","3f14e2db":"withdrawfund()","3f152d11":"Coin(address)","3f15457f":"ens()","3f174064":"crowdsalePause()","3f181ef2":"getTotalUniqueCards()","3f18400e":"owlmasterReq()","3f1887e9":"Gamblers_Until_Jackpot()","3f18acb4":"CarRoute(string)","3f19bfbf":"allocateLedTokens()","3f19d043":"getContributions(address)","3f1a1cac":"useSingleItem(uint256,uint256,uint256)","3f1a3d9e":"dropEnabled()","3f1ae30f":"ReverseConfirmTransaction(uint256)","3f1b1267":"icoSince()","3f1bfdee":"testFailCreateShortIdAlreadyExists()","3f1da980":"lastBlock_v11Hash_uint256()","3f1e600a":"PHASE_3_PRICE()","3f1f59a4":"ICO_START2()","3f1f8f68":"seventh_withdrawal(uint256)","3f202951":"SampleCrowdsale(uint256,uint256,uint256,uint256,address)","3f20fa9e":"requestDispute(bytes16,address,address,uint256,uint256)","3f2266c2":"ownerAngelCollection(address,uint256)","3f22b0fb":"last50plushacker()","3f23503d":"minBtcValue()","3f23a566":"mintingCap()","3f242990":"tokenHardcap()","3f24ef7c":"setGidMax(uint8)","3f250493":"Crowdsaled()","3f257776":"getN2ControlLimits(bytes32)","3f265ddd":"FructusToken()","3f266242":"getSubjectCountByAddress(address)","3f26c5ee":"addMilestone(uint256,uint256,uint256,uint256,string,string)","3f26fa01":"InvestmentPolicyChanged(bool,bool,bool,address,address)","3f27e9e1":"recoverAddressFromBalanceProofUpdateMessage(bytes32,bytes32,uint256,bytes32,bytes,bytes)","3f27f105":"batchTransferSame(address[],uint256)","3f2885cb":"publish(string,string,address,bytes32)","3f288f05":"addPubKeyHash(bytes20,uint8,bytes,bytes)","3f28b20e":"Bemo()","3f28e9fb":"createBounty(uint256)","3f28f24c":"claim_rest_of_tokens_and_selfdestruct()","3f2965f0":"registerSeller(address)","3f29cd27":"set(bytes12,bytes32,uint40)","3f2b1040":"enableTokenWithdrawals()","3f2c0e35":"getNumberOfRequest()","3f2cb5d4":"popEducation()","3f2cba2b":"airdropMVP(address[],uint256)","3f2cdb53":"setETHPriceLowerBound(uint256)","3f2e0564":"setIcoWallet(address)","3f2e907c":"resumeTransferToken()","3f2e917c":"changeLimits(uint256)","3f2eed3b":"publicPresale()","3f2f1596":"setupTreasury(address,uint256)","3f2f46b4":"revealRock(string)","3f31281a":"changeUserKey(address)","3f3173f3":"MyTokenyy()","3f31b3ac":"extCustomerPolicies(bytes32,uint256)","3f3246a0":"getLastBuyer()","3f32aa70":"removeFromWhiteList(bytes32,address)","3f32af65":"calculateFare(string,string)","3f33252d":"changeDisown(uint256)","3f332792":"getGiftsCounter()","3f34dd5c":"setVestingAmoundAndApproveCrowdsale(address,address,address)","3f35d033":"transferToContract(address,uint256,bytes)","3f36d33d":"getpotReward()","3f37c9d4":"servicePercentage()","3f384026":"setStatusBuySell(bool,bool)","3f392b42":"trade(address[5],uint256[11],uint8[3],bytes32[6])","3f3935d1":"confirmReverse(string)","3f395781":"Capsule(uint256,address)","3f3a1ed2":"alottTokensExchange(address,uint256)","3f3a279d":"getBetResult()","3f3a4966":"getVotingPower(uint256,uint256,address)","3f3a78d5":"rateAngelDay()","3f3bdc6c":"upgradeAllowance(address,address)","3f3c212d":"kittenTalk()","3f3c51c3":"Setmyadress(address)","3f3c594c":"TestingToken()","3f3cde05":"whitelistFilteringSwitch()","3f3d83c3":"purchasable()","3f3e4c11":"setMaxTotalSupply(uint256)","3f3edfa4":"RootCoin()","3f3f43a8":"setPreDGZtoDgzRate(uint256)","3f402dfc":"CreateGameIco(address,uint256)","3f40adb8":"createPetition(string,string,uint256,bool,string)","3f415772":"releaseExists(bytes32)","3f419c40":"getMessageMaxCharacters()","3f423afe":"DIVISOR_STAKE()","3f4263ef":"x(uint256)","3f430616":"getThirdRoundReleaseTime()","3f43c7cf":"open(uint256,uint256,uint256,string)","3f444db1":"internalDoRoll(bytes32,bytes32,uint256,uint256,uint256)","3f44d89f":"NigerianNairaToken()","3f450915":"_mateWith(uint256,uint256,uint8)","3f4628c1":"disputeLimitedReporters()","3f46a2ea":"DucLongToken()","3f478372":"newDeposit(uint256)","3f479562":"kingGladiatorFounder()","3f47e662":"decimals(uint256)","3f487b8b":"securityGuardLastCheckin()","3f48ae1a":"initInsecure(address)","3f493a1d":"Playforfreetoken()","3f497d52":"batchAirDrop(address,address,address[],uint256)","3f4a6484":"removeCapper(address)","3f4acbe8":"_teamTax(uint256,bool)","3f4ad13d":"LOTE(uint256,string,string)","3f4b1401":"releaseDragonTokens()","3f4ba83a":"unpause()","3f4be889":"callContractAddress()","3f4c0733":"batchTransferEtherWithSameAmount(address[],uint256)","3f4c89ca":"show_minimum_amount()","3f4d2fc2":"addConnector(address,uint32,bool)","3f4d97f0":"TOTAL_TEAM_TOKENS()","3f4dd268":"releaseTokens(uint256,uint256)","3f4e5ab9":"getB1()","3f4e6d66":"CryptoFamous(address)","3f4e95d7":"investorsAccounts(address)","3f4eb701":"updateUnderlying(string,uint256)","3f4f057f":"candidateBlockNumberHash()","3f4f070c":"newSpaceshipUpgrade(bytes1,uint8,uint256)","3f4f3075":"setRenewable(uint256,bool)","3f4f50c8":"EvtUnlock(address,uint256)","3f50331d":"batchTransferPaidTokens(address[],uint256[])","3f516018":"setCreator(address)","3f5174df":"numberOfEarlyPurchases()","3f5228c7":"fifishICO()","3f52c660":"TokenPerETH()","3f52e589":"setStartingTime(uint256)","3f541d08":"burnTokens(address,address)","3f541ffc":"exchangeEtherForHavvens()","3f549d87":"contributeByOracle(address,uint256)","3f55b895":"delegate(uint8,bytes32,bytes32)","3f572432":"investment(uint256,address,string,uint256)","3f5750c6":"distributeCoins()","3f576af0":"GoodDayTokens()","3f579f42":"executeTransaction(address,uint256,bytes)","3f58774b":"ecbuy(uint256)","3f58a043":"ceoEtherBalance()","3f58f8c0":"voteRuling(uint256,uint256,uint256[])","3f590062":"getTokenCreationTime(string)","3f59b1ab":"TokenImpl(string,string,uint256)","3f59e45a":"bincentiveLogger()","3f5a0bdd":"selfDestruct(address)","3f5a9e22":"getAmountOfTitties()","3f5ab2fe":"seed_eth()","3f5adb8e":"LIRAX()","3f5b7675":"periodTwo()","3f5bc9b6":"makeACall(address,uint256)","3f5c6a50":"MinimumDonation()","3f5cbdb6":"returnWei()","3f5cd055":"advisorsVesting()","3f5d0203":"getCreationWeiCost()","3f5d2b79":"CrowdsaleFinished(uint256,uint256)","3f5d8056":"currRound()","3f5e268f":"convictInitial(uint256,uint256)","3f5e3ec1":"changeTransactionStorage(address)","3f5ea068":"addLockAccount(address,uint256)","3f5f5217":"sellAth(uint256)","3f601972":"TotalToken()","3f606cfc":"enableAutoSeller()","3f60efa2":"HANDLE()","3f615272":"sendICO(address,uint256,address)","3f61dcf6":"enableTransfering()","3f62c084":"collectMessage(address,address,uint256)","3f635e30":"ethTransfer(uint256,address,uint256)","3f64a7ab":"devFeePercent()","3f64b318":"initSale(address,address,address,address)","3f651bab":"TOURNAMENT_ENDS()","3f65d97f":"removeEndorsement(bytes32,bytes32)","3f67364a":"PayValsToList(address[],uint256[])","3f67a94e":"getOffChainAddresses()","3f683b6a":"isStopped()","3f6849eb":"listedMonForMon(uint64)","3f686170":"freezeAll(bool)","3f69034f":"enableGeneration()","3f697ce9":"startBlock(address)","3f69babd":"cancelEvent(uint256)","3f6a2c97":"calculatePoints()","3f6a6792":"Bribed(uint256,uint256)","3f6b33c4":"ping(address,uint256,uint256)","3f6b5fde":"generate(address,string)","3f6b6f2e":"Airdrop()","3f6c0696":"superMint(address,uint256,uint256)","3f6c0c60":"isTransferNotExpired(uint256,uint256)","3f6c3567":"listSales(uint256)","3f6c4a1b":"getTeamA(uint256)","3f6c4cfd":"withdrawBountyAndAdvisory()","3f6c71c5":"edgePigmentR()","3f6c95fe":"increaseLotteryBalance(uint256)","3f6d8256":"validatorFee()","3f6dd911":"multisig_owner()","3f6ddb75":"Allocated(address,uint256,bool)","3f6ea2a8":"MIN_LEADER_FRAC_TOP()","3f6ec73a":"itemVoteUp(address,uint256)","3f6f7ed6":"updateEthRate(uint256)","3f6fa655":"resolved()","3f6fff4e":"closeCycle(uint256)","3f70c2b4":"getProductById(uint256)","3f720922":"setConfig(uint256,uint256,uint256,uint256,uint256)","3f723c62":"addRecord(string,string,string)","3f73365f":"getOneFree(address)","3f738402":"goalIncrement()","3f74a3b7":"MINIMUM_VESTING_PERIOD()","3f74a8be":"totalEthJackpotCollected()","3f74fecb":"DSTrueFallbackTest()","3f751ad0":"addTxToCustomerRegistry(address,uint256,uint256)","3f7525bf":"getAddressesSet()","3f76fbd3":"dhopakcoin()","3f77b560":"newDocument(bytes)","3f77e1e9":"testFee()","3f79a0a9":"NewGame(bytes32,bytes32,bytes32,bytes32,address,uint256)","3f7a0270":"setN(uint256)","3f7aea39":"getCET4ById(uint32)","3f7b2ea9":"testMintInvalid()","3f7b54f9":"DevChangeMiningReward(uint256)","3f7b6be8":"createProductionUnit2()","3f7c42a7":"setJob(address,uint256,address,string,string,uint256[],uint256,uint256,uint8[],uint8,bool,address[])","3f7ca612":"FMWL()","3f7d5361":"changeSafetyLimit(uint256)","3f7d72d8":"rSetE(address)","3f7da39a":"whitelisterAddress()","3f7e2120":"CloseGift()","3f7eabc9":"setRobot(address)","3f7eb0fe":"func_1()","3f7f2eda":"Order(address,uint256,address,uint256,uint256,uint256,address)","3f7f4f17":"getUserAccountBalance(address)","3f7f6d23":"BuyWithBonus(address,address,uint256,uint256,uint256)","3f7f8b24":"getAllocationProposal(uint256)","3f7f9faf":"attachTicker(address)","3f80135f":"test_threeInvalidEqAddress()","3f801f91":"proxyAssert(address,uint8,bytes)","3f802220":"ProposalAdded(uint256)","3f802ca0":"singleValueBatchTransfer(address[],uint256)","3f806783":"potSizeChanged(uint256)","3f807199":"changeParticipants(address[])","3f80a82b":"getbuyPrice()","3f80db69":"_totalTokenSold()","3f811b80":"createContract(bytes32)","3f8126d5":"GetStatus(uint256)","3f817449":"tokenSmartcontract()","3f81e4be":"lastBlock_a9Hash_uint256()","3f82065b":"setDiscipleVend(uint256,uint256)","3f82e2c6":"PUBLIC_RESOLVER_NODE()","3f836dcf":"addAsAddress(bytes32,address)","3f83acff":"get_contract(bytes32)","3f8416fb":"doUpgrade(address)","3f85be9c":"calcChanges(uint256,uint256,uint256)","3f85f916":"founderContract()","3f862a19":"remainUserTokenBalance(address)","3f87f870":"checkRequest(string,string,string)","3f883dfb":"transferExternalValue(bytes32[])","3f887fad":"buyShares(uint256,uint8,uint256,uint256)","3f89b09c":"update_fee(uint256,uint256)","3f8a04aa":"getCurrentUserPromoBonus()","3f8a4c13":"previousSnailPot()","3f8a92b3":"setmangeruser(address,bool)","3f8ae6d9":"GetUserExpire(address)","3f8af40c":"amendedEarlyPurchases(uint256)","3f8b0a1d":"getIssuedBy()","3f8c2582":"ethSale(address)","3f8c75a6":"_createLicense(uint256,uint256,address,uint256,address)","3f8cfba6":"lifeVestingStages()","3f8d9568":"buyins(address)","3f8d95bd":"_delete(address)","3f8df98d":"calculateMyReward(uint256)","3f8e0298":"parseTicket(uint256)","3f8f0714":"SimpleLife()","3f900962":"manualRaffle()","3f914aef":"setWhitelistAddress(address,bool)","3f923f9d":"NIZIGEN()","3f92edaf":"getMaxDropsPerTx()","3f935379":"_isSingleFlag(uint256)","3f94904a":"bankValReserve()","3f95c0c2":"timeboundTest(address,uint256,uint256)","3f9628e8":"addOldWithdrawals(address[],uint256[])","3f966082":"exchangesOwner()","3f96f3a3":"toInt()","3f97b106":"GetSuspend()","3f97d995":"VALIDITY()","3f982b74":"createInitialAllotment(string,uint256)","3f9942ff":"canceled()","3f9945d2":"ByThePeople(address)","3f99a12b":"saleEndBlock()","3f99fa54":"addInitialMember(address,uint256)","3f9a3886":"OWNERS_ALLOCATED_TOKENS()","3f9af464":"AK4Token()","3f9b250a":"getDocument(uint256)","3f9b8fdc":"updateAllowedTransfers(address,address,bool)","3f9c7822":"print(int256,uint256)","3f9cbd65":"mainSaleTokenWallet()","3f9ce517":"getRefAddress()","3f9d0954":"FarChainToken()","3f9d95ed":"addAcceptedToken(address,uint256,uint256)","3f9e0eb7":"_getDaysInMonth(uint256,uint256)","3f9e23e5":"migrationFinished()","3f9e3494":"ReleaseSupply(address,uint256,uint256)","3f9e50fd":"LitToken()","3f9e9a37":"getBonusesAmount(uint256)","3f9e9df2":"removeInWhiteList(address)","3f9f5b68":"setPreviousID(uint256,int256)","3f9f7779":"BitCronus1()","3fa10e0a":"CountryJackpot()","3fa1436e":"updateTokenSaleState()","3fa1930d":"getPlayerBet(uint256)","3fa19804":"updateTeller(int8,bytes16,int8,int16,bool)","3fa21806":"lastHash()","3fa2dd2a":"getStage2Cap()","3fa2fe7a":"getActiveUserCount()","3fa40f94":"mintTokens(address[])","3fa4687b":"bytesToAddres(bytes)","3fa4ed06":"updateValue(bytes32,uint256)","3fa4f245":"value()","3fa54ed8":"setTileTypeAt(uint16,uint16,uint8,uint16)","3fa58b61":"Whitelistable()","3fa6010f":"setGallerySixPrice(uint256)","3fa615b0":"minCap()","3fa6497f":"AdminAddFunds()","3fa68836":"removeParticipant(uint8)","3fa69faa":"testtoken()","3fa8543a":"IMEXToken()","3fa8a7b8":"releaseTokenOwnership(address)","3fa911ae":"refundAllowed()","3fa9fcf8":"createPlayer()","3faaef28":"BurnFSATokens(uint256)","3faaffdb":"SCToken()","3fab8fb0":"EatToken()","3fabf8c0":"developmentAuditPromotionTokensPercent()","3fac68d5":"payOff()","3facd57c":"registerBill(uint256,address,address,uint256,uint256,uint256)","3facdfb6":"gatFund()","3fad1834":"getRequestCount()","3fad9ae0":"question()","3fadbd3e":"minTokenPurchase()","3fadc388":"current_plot_price()","3fae1928":"timenow()","3faed436":"setXTVTokenAirdropStatus(bool)","3faf511f":"vouch(bytes32)","3faff9d5":"purchaseTokens(uint256,address,bool)","3fb0b2c9":"CancelRoundAndRefundAll()","3fb18aec":"contains(string,string)","3fb1ab52":"_getUserSupportForTeamInTournament(uint256,uint256)","3fb1fed4":"startingExchangePrice()","3fb23166":"TeamVesting()","3fb23865":"fundingStatus()","3fb27b85":"seal()","3fb326ba":"MAX_ETHER_CONTR()","3fb39b8b":"rewardBeneficiary(address,uint256)","3fb3bec2":"deactivateTime()","3fb3ec28":"delegatedAmountsByDelegate(address)","3fb48c4c":"AAACoin()","3fb51a76":"frozenDaysforTestExchange()","3fb58819":"getMinGasPrice()","3fb5c1cb":"setNumber(uint256)","3fb64e75":"gameInProgress()","3fb655a3":"CPLTokenDeposit()","3fb8b692":"affiliateAddresses(uint256)","3fb92b10":"gameNbr()","3fb97857":"getCouponMulFactor()","3fbb539d":"scheduleCall(address,bytes,uint256,bytes)","3fbb8f98":"drawTertiaryDWinners(uint256)","3fbc2a1e":"preSaleTLYperETH()","3fbc6345":"Token_Remaining()","3fbd40fd":"ProcessDraw()","3fbda23f":"CharityToken()","3fbfdefc":"checkMyAging(address)","3fbffca6":"getTeamB(uint256)","3fbffcef":"bidsCount()","3fc0234d":"train1(uint256,uint256)","3fc15f15":"mainToken()","3fc22c51":"buyPreSaleTokens(address)","3fc3e53f":"Funding()","3fc44ab3":"setCustomEvent(uint256,uint256,bool,string,uint256)","3fc499b2":"ihomekey()","3fc4caa1":"levelThreeBonus(uint256)","3fc4e866":"RudiantoToken()","3fc50b92":"agingTime()","3fc523c7":"test_fourInvalidEqUint()","3fc5b69b":"set_sale_arbits_per_ether(uint256)","3fc5ed50":"_openGameResult(uint256,string)","3fc6a97a":"sellNow()","3fc6bc94":"payDAO()","3fc6d75a":"crowdsaleTokenPrice()","3fc7e3d5":"volumeType3()","3fc821ee":"getStackholderConfirmationCount(uint256)","3fc86d32":"newInvestor(uint16,address,uint256,uint256)","3fc8b029":"testSaleHasOwnerOnCreation()","3fc8ca58":"JetherToken()","3fc8cef3":"weth()","3fc90f7c":"addresses1(uint256)","3fc98bd5":"robotInfo(uint256)","3fcb21d3":"ecoFundingSupply()","3fcce626":"setDeprecated(address,string,string)","3fcd06fa":"checkMinimalGoal()","3fcdd2d3":"transfertoken(uint256,address)","3fce1b82":"addAnimal(uint8)","3fcead58":"TKRPToken()","3fd01a77":"is_purchase_allowed()","3fd0f727":"isIcoTrue()","3fd1f232":"LookAtAllTheseTastyFees()","3fd2300d":"curveIntegral(uint256)","3fd2799d":"newShortPosition(address[7],uint256[4],uint32[3])","3fd29369":"offer(string,string,string,uint256)","3fd3370a":"FooTime()","3fd3a371":"stageThreeEnd()","3fd3c997":"assetProxies(bytes4)","3fd68ca7":"lastCheckedToken()","3fd6b1db":"InoCoin(uint256,string,string)","3fd76a98":"MANAGEMENT_LOCKED_ALLOC()","3fd8b02f":"lockPeriod()","3fd8cc4e":"isPermitted(address)","3fd8cd9b":"ETHReturn(address,uint256)","3fd94686":"changeEligibleDonkeys(uint256)","3fd97621":"testTransferHandlesTooLargeRequest()","3fd9c56d":"checkDoubledProfit(uint256,uint256)","3fda1281":"get_keys()","3fda417a":"LADCoin(uint256,string,string)","3fda5389":"fill(uint256)","3fda926e":"addGame(address,string)","3fdb3628":"aggregateCDPValues(bytes32)","3fdb372a":"buildWinery()","3fdb571f":"reGround(uint256)","3fdb705b":"platformTokenSupply()","3fdb8cbd":"dt()","3fdbb6c7":"RATE_THRESHOLD_PERCENTAGE()","3fdccd8d":"setDCNForGas(uint256)","3fdcef0d":"PRICE_BEFORE_SOFTCAP()","3fdcefe0":"doSelfdestruct()","3fddd97d":"XCoin(uint256,string,string)","3fdddf01":"EGGS_TO_HATCH_1PACIFIST()","3fdde728":"MTP_PER_ETH_SALE()","3fddee64":"isAgency(address)","3fded490":"referralDiscountPercentage(address)","3fdeef90":"fstSold()","3fe0522c":"setTravelCore(address)","3fe14e03":"setAuthor(string)","3fe3347a":"assetType()","3fe3df76":"leaf_from_address_and_num_tokens(address,uint256)","3fe3f427":"depositTokens(address,address,uint256,uint256,bytes32)","3fe43020":"decreaseRepAvailableForExtraBondPayouts(uint256)","3fe43822":"Collect(uint256)","3fe75b8d":"Unity()","3fe97ead":"left49(uint256)","3fe9bf0e":"createContract(bytes,uint256)","3fe9f2a4":"EventCentsPerEtherChanged(uint256,uint256)","3fe9f2b2":"totalPublicFundingSupply()","3fea1c2b":"getIHand(uint32)","3fea2313":"ProposalAdded(address,address,uint256)","3feab517":"DreamCoin(uint256,string,uint8,string)","3feb1bd8":"transfer(bytes32,address,uint256)","3feb4f83":"BankeraToken(uint256,uint64)","3feb5f2b":"investors(uint256)","3febb070":"backlogAmount()","3febe823":"ClapClapToken()","3fec0561":"addclip(address)","3fec156b":"timeLockTeam(address)","3fec1a75":"setIcoDiscount(uint256)","3fec4a4c":"queryjingzhi(uint256,string)","3fec91a4":"addProposal(uint256)","3fecde21":"setTilePrice(uint8,uint256,address)","3feced03":"minAmountWei()","3fed491f":"testStoreBalanceAfterCheckout()","3fedcc31":"transfer(uint256,address,address,address,uint256,bytes,bytes)","3fee28b1":"logEthTx(bytes32)","3fefc25d":"getFundByManager(address)","3fefdb01":"setStageGenomes(uint8,string,string,string,string,string)","3feff510":"showMainERC20()","3feff76d":"tokenaddress()","3ff00ba5":"airdropMinting(address[],uint256[])","3ff0a1e5":"FoundToken()","3ff0ab0b":"updateUserDetails(bytes32)","3ff11c8b":"right85(uint256)","3ff1a578":"IsCheckNeeded(uint256,uint256)","3ff1d68f":"_totalXT()","3ff1dcf6":"PermianICO()","3ff1e05b":"viewBalance()","3ff20c8a":"setPause(uint8)","3ff26c01":"catches(address)","3ff33185":"newCaller(address)","3ff42b92":"marketingAddr()","3ff4d491":"checkFile(bytes32)","3ff5481d":"cancelSellBlock(uint256,uint256)","3ff54c71":"issueTokens(address)","3ff66381":"ACCC()","3ff69113":"myEntityCount()","3ff7f21c":"mulFactor()","3ff8c954":"addAnimals(uint8)","3ff8da5f":"recipient3()","3ff98455":"set_participant(address,address,uint256,uint256,uint256,bool,uint8)","3ff9a877":"makeXID(uint256)","3ffa274a":"transfersAllowedTo(address)","3ffb8f27":"changeMinter(address,int256,address)","3ffbd47f":"register(string,string)","3ffc2832":"_buyIcsTokens(address,uint256)","3ffc813f":"toCompare(uint256,uint256)","3ffd2798":"distributeAdviserBounty(address,uint256,bool)","3ffdabda":"poi_token()","3ffe5eb7":"claimWork(uint256,uint256[2],bytes32)","3fffebbd":"setBonusUser(address)","400002c4":"modifyOpenStatus(bool)","4000164d":"getClaimData2(uint256)","4000601f":"sellStakes(address,address,uint256,uint256)","4000aea0":"transferAndCall(address,uint256,bytes)","4000d5c3":"BACTest1Token(uint256,string,uint8,string)","4001261e":"activeTier()","40015d99":"getProviderInfo(uint256)","4001cee6":"getPeerOwnership(address)","4001e364":"SendEthOff()","4002d3fd":"LargeFunction()","4002eda6":"nextRoundId()","4002f0b0":"CheckCourse(uint256)","400351cb":"applyForCandidate(string,uint256,string,string,string,uint256,bool)","4004b6da":"getAmbassador(address)","40058f61":"TIER2()","40066733":"getTotalVotersCount()","40067c91":"VoteFactory()","4006ccc5":"exchangeRatio()","400718ea":"expressBuyNumSec(uint256,uint256[],uint256[])","40079df0":"getDividendIndex(uint256,int256)","40086158":"calculateHash()","40086aa0":"directDebit(address,address)","400a44b2":"EE(uint256,string,uint8,string)","400a4deb":"sendPresaleTokens()","400aaab7":"CTOC()","400aae08":"isInCurrentGeneration(address)","400adee3":"releaseByCount(address,uint256)","400b56e5":"setReg2(uint256)","400b8bf8":"releaseMintTokens()","400ba069":"calculateFee(uint256,address)","400bb308":"SimpleTGE(address,uint256,uint256,uint256,uint256)","400bbbd8":"rebalanceGetTokensToSellAndBuy()","400d1f45":"dtGetEthBalance(address)","400e3949":"numProposals()","400eb4f5":"ParaType()","400ee783":"TOKENS_LOCKED_1Y_TOTAL()","400f7a1e":"getPairInfo(address,address)","400ff9a4":"BuyGold()","4010a018":"fundAvailable(address)","40111f6d":"RESERVED_TOKENS_BACE_TEAM()","40117f50":"CanalToken()","4011baf9":"MARKETING_POOL_TOKENS()","401214a7":"updateParams(uint256,uint256,uint256,uint256,uint256)","40128db3":"registerAsDelegate(bytes32)","40129a40":"updateAddress(bytes32,address)","4012e02e":"Info()","401356f1":"Salt()","40135913":"releaseImpl(uint256)","4014c1c7":"changeMutagen2FaceContract(address)","4015e83b":"renExTokensContract()","401611ed":"acceptEndorsement(bytes32,bytes32)","4016535a":"parseBlock(bytes,uint256)","4016e969":"allowOwner()","4018e263":"stageTwoCap()","40193883":"goal()","40193d17":"getPongvalConstant()","40194596":"RealBloq()","4019fc54":"masterTokenBalanceHolder()","401b57b5":"transferLockedToken(uint256)","401bd3fe":"distributeEth(address[],uint256[])","401c3ba1":"LogClaimRefund(address,uint256)","401d7175":"_buyShip(uint256,address)","401dc09f":"setGeneSynthesisAddress(address,address)","401e3367":"transferFrom(address,address,uint256,bytes32)","401e77de":"GameCreated(bytes32,address,string,string,uint16,uint64)","401f2be5":"collectRemainingFunds()","40202f9d":"LogTransaction(address,uint256)","4021581a":"dollarBalance(address)","40217452":"ProdBToken()","40217786":"setRatePerOneEther(uint256)","4021d93c":"Alibabacoin()","40220b03":"previousVersion(bytes32,bytes32)","40222b64":"allocationsIndex(uint256)","40229e14":"B_Com()","4023da38":"Bacini(uint256,string,uint8,string)","40243ecd":"SimplePaymentChannel(address,uint256)","402456c0":"bank1Val()","4024a33e":"stageBonusPercentage(uint256)","4024db80":"license(bytes32)","4024eb2a":"approveAndCallN(address,uint256,uint256)","4025005a":"SmartIdentity()","4025b22d":"getShip(uint256)","4025b293":"redeemAllOutcomes(bytes32,uint256)","4025b5a8":"ownerUpdateContractBalance(uint256)","40267e53":"updateWhitelistBatch(address[],uint8)","4026b261":"PlatoToken()","4026c101":"deathFactor_iii()","4026eb92":"endround()","4027522c":"DanetonToken()","40275f73":"addMapping(string)","40275f85":"getPersonalDepositAddress(address)","40277604":"collectedFeesInTwei()","40278124":"setListedTime(uint256)","4027d4d8":"spendFromSwap(bytes32,uint256,address)","4028354b":"PlaceADiceBet(uint8)","40285ad5":"setfees(uint256)","4028db79":"isFrozenAccount(address)","402914f5":"claimable(address)","402962bc":"deleteAddressesFromWhitelist(address[])","4029a3ce":"mintMany(address[],uint256[])","402a1533":"angelAmountRemaining()","402b2bca":"IcoStartDate()","402bf0ab":"_delHolder(address)","402c5644":"XNON()","402c569c":"unlockBonusTokensClaim()","402caccd":"RANGESTART_6()","402d1c9c":"CONFIG_MAX_EXPOSURE_MUL()","402d5f2e":"unlockTokenPriceChange()","402d8883":"repay()","402e46b9":"finito()","402e6230":"getTotalGambles()","402e912f":"issuedInsurance()","402eb694":"reliabilityPercentage()","40307cdd":"setCOMMUNITY_POOL_ADDR(address)","4030bc19":"sendRTB(address,uint256)","4030ddc0":"blockVContractAddr()","4031f60d":"INMCOIN()","40326686":"paymentsFinished(uint256)","4032b72b":"addKeeper(address)","4033236e":"getProofOfStakeReward(address,address)","4033c268":"isFullInvest(address,bytes5)","4033cd77":"applyForCertification(string,string,string,uint256,bool)","403446bd":"getPlayersFibokens()","4034af00":"setWhitelistInternal(address,bool)","4034b817":"loadVersion(address)","4034cfed":"fundWallet1()","403575f7":"setMaxMessagesTop(int32)","4035d16a":"createPromoCovfefe(address,string,string,uint16,uint256)","403639d5":"StartSale(address,uint256,uint256,address,address,uint256,uint256,uint256)","40365852":"roundStart()","4036778f":"reveal(uint256,bytes32)","4036ab78":"getType(uint256)","4036ff30":"changeHouseCutPercentage(uint256)","403911a6":"tokenSaleStart()","40394dcc":"freezeAccountByTime(address,uint256)","403988c6":"setCustodianName(address,bytes32)","403a0a78":"placeBet(uint256,uint256,uint256,uint256,bytes32,bytes32,uint256)","403a734a":"MMMbCoin(uint256)","403a8f53":"registerForRaffle2()","403abbc7":"updateFirstActiveGamble()","403b0cfd":"LogErr(uint256)","403b3757":"getValueTip(uint256)","403b7d9b":"secondRoundICOEnd()","403bb94e":"StatsEthereumRaised()","403c617e":"Hydrogen()","403c9fa8":"getPot()","403d8a6a":"initialMartialTimes()","403dca55":"totalIssuedSynths(bytes4)","403de107":"executeDecision(uint256)","403e73ea":"_DemSinhVienDat()","403f6cff":"putInWinnerPool(uint256)","403fbf54":"initiateEthUsdOracleUpdate(address)","40400fa7":"getBurnedItemCount()","404239f6":"validateLegalRate(uint256,uint256,bool)","40426fb0":"stopIssuing(uint256)","4042b66f":"weiRaised()","40440891":"Donate_some_amount_and_save_your_stake_rewards(uint256)","40441eec":"balance2()","40445a4f":"numTiers()","4044856a":"preIcoEthers()","4044e8ec":"cancelOrderWithPayer(string,address)","4045c846":"setAccreditationActive(bytes32,bytes32,bool)","404635db":"_canBreedViaAuction(uint256,uint256)","404704b9":"sendBounty(address,uint256)","40477126":"exchangeTokens(uint256)","404823d1":"wagerPool()","40482475":"startTokenSwap()","4048c449":"getParent(bytes32)","40490a90":"getMultiplier()","40496aef":"SecuredWithRoles(string,address)","404983fb":"addsm(uint256,uint256)","40499ae8":"approvedTill()","404a9272":"promoEndTime()","404ae80c":"_randomCardSetIndex(uint256,uint256)","404cbffb":"entityList(uint256)","404cf932":"mintStart3()","404d0e3e":"gen0CreationLimit()","404ed1fa":"_founder_two()","404ef602":"disapproveToSell(uint256)","404efc53":"left26(uint256)","404f8dc8":"KRW_Omnidollar()","404fdfdf":"_setTempHeroPower()","4050a394":"getWishName(uint256)","40510399":"miningKing()","40512dcc":"TotalDividendsPerShare()","405136fa":"multiSendEth()","40517083":"dig(uint256)","4051ddac":"getSummary()","4051ed26":"BONUS_SLAB()","40520f85":"tokenToEtherRate()","40523946":"spectreTeam()","40528f98":"ownerUnlock(address,uint256)","4052c02a":"ProToken(uint256,string,uint8,string)","405353b5":"NPToken()","4053873c":"_safeTransferTkn(address,address,uint256)","4053c797":"save(bytes32)","40543538":"get_asset_events_count(bytes32)","4054f5de":"EthVentures3()","40556191":"getCrowdsaleWhitelist()","40557cf1":"saleRate()","40557e87":"totalBondSupply_BEAR()","405665fb":"isMeInWhiteList()","4056675e":"transferTokenOwnership()","4056f8a8":"minimumTokens()","4056fe06":"MAX_GOAL_EBC()","405710a8":"sentTokensToCompany()","40582f13":"getWeiRaised()","405871e5":"SealPrivateCrowdsale()","4059240c":"intervalNow()","405a66da":"claimOtherTokens(address)","405abb41":"updateRate(uint256,uint256)","405b8816":"testIsContractZero()","405bd7bb":"getCurrentNumberOfVoters()","405c649c":"timeLeft(address)","405c6f6e":"addDelegate(string)","405cae3b":"LOG_SpinExecuted(bytes32,address,uint256,uint256,uint256)","405cb7f6":"KimJCoin()","405d3adf":"exchange(bytes4,uint256,bytes4,address)","405dd87c":"EAT()","405df338":"start_PREICO()","405f63e7":"MANHATTANPROXY9THCOLAVE()","405f8006":"BlocToken()","405fea2f":"setTokenAudit(address,address,address,address)","4060d9f5":"isCarSpecial(uint256)","40621412":"BetexICO(uint256,uint256,uint256,address,address,address)","4063d563":"advertise(address)","406499d2":"Redhorse()","40650c91":"MIN_CONTRIBUTION()","40652435":"BURENCY()","40654e14":"balanceOfEth(address)","40656963":"contribute(bool)","40664496":"getTransferFee(address,address,uint256)","4066fdea":"feeProvider()","4067ffda":"transactionsOnForHolder(address)","406838b3":"etoken2()","40684172":"getICORaisedAmount()","406843ee":"recommendProportion()","4068665d":"TokenVesting(address,uint256,uint256,uint256,bool,address)","40695363":"floor()","40695625":"testRetractLatestRevision()","40698729":"withdrawERC20s(address,uint256)","4069925a":"releaseVested(address)","4069de8b":"MultiSender(address,address)","406a0e61":"VOLUME_50()","406a1180":"FATRANSOM()","406a318e":"getCitationRecordsLength(bytes32)","406a6f60":"attachToken(address)","406af848":"ArenplayToken()","406b0593":"tokenHoldersByIndex()","406b9394":"level0(address,bytes32,uint256)","406c22d3":"getLocalNodeReputation(address)","406c52d5":"changeElectorate(address)","406c5590":"FILO()","406c6633":"moveToNextCeiling()","406c92b5":"PRIVATE_SALE_MAX_ETHER()","406d7e98":"isAllowingTransfers()","406d81c7":"safeSendFunds(address,uint256)","406f1d22":"crowdSaleApprove(address,uint256)","406f390c":"_unsafeCall(address,uint256)","407001c6":"TruSale(uint256,uint256,address,address)","4070372d":"earlyInvestorsMintedTokens()","40710587":"usersCanSell(bool)","407167b6":"cantEntidades()","40716fc7":"DunderBet()","4071f89b":"payCharity()","40722e3e":"getNameReaderId(bytes32)","407235ba":"LogStop()","407255b5":"getWhitelistByIndex(uint256,address)","4072eee2":"getTopic(address,uint256)","4073002e":"AssetCollectionNum()","40731c24":"getPost(uint256)","40732c89":"makeDeposit()","40734387":"termination()","407456d1":"fundsOf()","407489ff":"concat_nodes(address[])","4074c648":"createPromoCollectibleWithMining(uint256,address,uint256,uint256,uint256,uint256)","407532bb":"presaleFundingTargetInEther()","40753a76":"addSupply(uint256)","40754714":"blockClient(address)","407617e5":"updateAmountIncrease(uint256)","4076a248":"BetPower()","40773279":"pay_Bounty(address,uint256)","407787e6":"Division(uint256,uint256)","4077aa14":"coreStaffAmount()","4077aaf8":"totalBountyTokens()","4077ef5d":"getMiniPoolEdit_4()","40784ebd":"slashInvalidUsername(string,uint256,uint256)","40786dec":"mint(bytes32,uint256,bytes32)","4078fca8":"feeETH()","40799f4c":"currentDayRate10000()","407a5c92":"getAdminLogN()","407a6727":"totalVIP()","407b899b":"returnInt64(int64)","407c554a":"getTSTTokenAddress()","407ca6f8":"BsktToken(address[],uint256[],uint256,string,string)","407cba67":"buyKNOW()","407cfe5e":"get_all_players()","407d0cd0":"addGame(string,uint256,bytes32[])","407d1a0c":"unstoreHorsey(uint256)","407d552a":"jackpotTokenWinRewardRate()","407e5e5d":"newVoting(bytes,string)","407e9588":"rejectMintRequest(uint256,string)","407e9e2c":"setcommissionCompany(uint256)","407ea214":"getPortion(uint256,address)","407ed2e2":"ComputeSell(uint256)","407f56e5":"HEAL()","407f8001":"secondsPerPeriod()","407fb687":"exchangeEtherForNomins()","407fc2e8":"eggsSold()","407fcc31":"tokenPriceUSD()","407fce7b":"left12(uint256)","4080277f":"guhb(address)","408056e4":"weiMinInvestment()","408057c4":"getStockCount(address)","40806f7c":"getAvailableFees()","40807049":"transferManyLands(uint256,uint256[],address)","40809acd":"stake(uint256,uint256,address,address)","40809f9d":"calcEma(uint256,uint256,uint32,uint256)","4080c884":"XstarToken()","40811e90":"transferDataAuthority(address)","4081c065":"massGrant(address[])","4081d916":"checkPlayerExists(address)","408275bb":"transferToVault(bytes32,address,address,uint256)","40828698":"s(address,address,uint256)","4082b499":"totalNumberOfPurchases()","4082defb":"isBasicAccount(address)","408318ae":"addAllowCnsContract(bytes32,address,bytes32)","4083c555":"Oasis(uint256,string,uint8,string)","4083cdbb":"changeTokensLimit(uint256)","4083e2af":"getFinalRoundPoints(uint160)","4083e935":"transferEthersInternal()","40844a8d":"safeDeduct(uint256,uint256)","40848af5":"markMyWord(bytes32,uint32)","4084c3ab":"finalizedBlock()","40857e02":"create(address,address,uint256,bytes32,int256)","4086b620":"sweepsCreationTime()","408760b8":"setAngelLastVsBattleTime(uint64)","40876f6e":"getMaxMakerAmount(address,address,bytes)","4087908f":"RicoToken()","40884c52":"getOracles()","40890bc2":"getCurrentProvider()","408938d0":"testUpdatePackageDb()","4089462d":"registerPackage(bytes32,string)","40896550":"bountyTotal()","4089b170":"totalPayouts()","4089d22a":"buyDepo(address)","408a2ac9":"addNewSupplier(address,address,uint256)","408a8094":"releaseTeamTokensAfter24Months()","408aee81":"removeVendorByAddress(address)","408b9945":"getBuyerNumber()","408bcbda":"getBalancesLength()","408bf4c3":"getAllCompanies()","408c1932":"distributeDisputeFunds(address,address,address,address,uint8,bool,address,uint256,uint256,uint8)","408cfe24":"iToken()","408d407d":"getClaimData(uint256,uint256,uint256)","408d5773":"createContractCovfefe(string,string,uint16)","408d947e":"SmartToken(string,string)","408d9e35":"ExecutorChanged(address)","408e097c":"createDestructibleCloneToken(address,uint256,string,uint8,string,bool)","408e2727":"votingActive()","408e2eb4":"ico2Tokens()","408ee7fe":"addAlerter(address)","408fef2e":"requiredMessageLength()","40901b08":"p_setLimitedReferralsMode(bool)","40908298":"allowedAddress(address)","4090cb64":"getWToken()","4090e696":"GetMinCost(uint256,uint256,uint256)","4091adf5":"onlyOwnerGetCompanyWallet()","4091ca4c":"gettopuser(address)","4091f4c6":"refreshMonarchyGames()","409242fc":"citation(uint256)","4092a611":"upVote(bytes12,bytes12)","4092acdd":"tokenFulfillmentDeposit(address[2],uint256[8],uint8,bytes32[2])","4092e2c2":"addMember(bytes32,address)","409315ce":"executePure()","4093b49c":"votes_for()","4094ac75":"ProofOfWeakHandsClassic()","4094ef5e":"addDataRequest(string)","40953102":"scheduleCall(address,uint256,bytes,uint256,uint256,uint8,uint256)","40954254":"addPublicSalesSpecialUser(address)","4095fbba":"SubmitTransaction(bytes32)","40966a97":"CMCEthereumTicker(address,uint256)","40976b60":"setNewAgent(address)","4097d865":"increaseRound()","40980953":"setWhitelistOff(bool)","40992e9d":"getTotalAirDroppedAmount()","40998845":"_recordName(address)","409a3d8f":"ALLANCOIN()","409b479c":"GetTotalPlayers()","409bc43c":"changePersonalMaxcap(uint256)","409bd95b":"getProductionTimeBusiness(uint256)","409c7baf":"BONUS_MIN_DURATION()","409c962e":"view34()","409dba83":"calcKeysReceived(uint256)","409e81a4":"Create(uint256,uint256,uint256,uint256,bool)","409ed1db":"setCCH_edit_5(string)","409f2607":"ESCOToken()","409f33c1":"sumPublicSale()","409fb4c0":"configMaxKeys()","409fc358":"canGiveMoneyBack()","40a0dd4b":"updateStateBasedOnTime()","40a141ff":"removeValidator(address)","40a19a71":"BLOCKSUNTILCLEANUPSTACK()","40a1b96e":"getTickets(uint8)","40a1f4d5":"invalidateStage(uint256)","40a1f87d":"getTotalLockedTokensPerUser(address)","40a203c4":"CoinVillaIssued()","40a2bfc1":"setXPAAssets(address)","40a3a9c7":"createTokenLocker(address,address)","40a3d246":"toggle()","40a401d0":"setMonsterIndexToOwner(uint256,address)","40a45440":"getPlayerBetNumbers(address)","40a49a96":"searchSmallestInvestor()","40a4c3cc":"loanCreator()","40a4c580":"validateTransfer(address,address,uint256,bytes,bytes)","40a50a5e":"setNormalBuyLimit(uint256)","40a51199":"PubPresale(address,address,address)","40a53017":"FeedEgg()","40a53ab9":"replaceAuditorRegistry(address)","40a5737f":"setIndex(uint256)","40a57cb8":"makeAdmin(address,bool)","40a5bfc5":"PentacoreToken()","40a72363":"sigTeamAndAdvisersAddress()","40a7ed8b":"uintFunc(uint256,uint256,uint256)","40a8a96c":"KingdomCreatedEvent(uint256)","40a915a5":"setTokensLocked(bool)","40a92f0f":"setMinSign(uint40)","40aab81b":"UpdatedBlock(uint256,uint256,bytes32,bytes32,bytes32,bytes32,address)","40aad0fe":"getUserPair(address)","40ab2634":"lastBlock_f8()","40ab4879":"pePrice()","40ab7b8c":"bnt()","40ac40b2":"setInvitationMultiple(uint256)","40ac89a2":"returnInvestment()","40acbee3":"TokenFactoryAirdropToken()","40acf805":"setCompanyInfo(bytes32,string)","40ad654c":"transferForVote(address,uint256)","40adf94e":"setOraclizeGasPrice(uint256,uint256)","40ae0851":"withdrawEtc(address,uint256)","40aec640":"bonusState()","40aee1a9":"numHashTypes()","40af1a45":"PrivateSaleDays()","40b00033":"deposit(string,uint256,bytes,uint8,bytes32,bytes32)","40b0a77f":"updateInstantTrade(address)","40b0c3d1":"DiligenceToken()","40b12b40":"testIsTrue()","40b14606":"getOverPLayer()","40b1ad52":"slashReservedUsername(string,bytes32[],uint256)","40b31937":"pledgeDecline(uint256)","40b359f5":"markTaskCompleted(address,bytes32)","40b43701":"getSetting(uint256)","40b5336d":"_updateDepositCountry(uint256,uint256,uint256)","40b5886b":"getHotWalletAddress()","40b5ce01":"fightStartTime()","40b60b85":"forceBuyback(address)","40b61fe9":"removeOperator(address,address)","40b6290f":"acceptSale()","40b6c71f":"EthLyteToken()","40b73897":"getFeeWindow(uint256)","40b74c91":"dislikeArtist(address)","40b7802d":"GiveUpTheDough(address)","40b7b240":"calculateAmount(address)","40b80684":"TOKEN_AMOUNT_ICO_STAGE1_PRE_SALE4()","40b8783d":"raiseSlammer(bytes32,bytes32,bytes32)","40b8d53a":"startFeeExit(address,uint256)","40b98253":"canContribute()","40ba0e94":"getRegion(uint256)","40bb28e8":"watchVideoB(address)","40bb8474":"RENEETOKEN()","40bbf5b9":"ChunksToken()","40bc9308":"startTimeRound1()","40bcff15":"bet1000_01eth()","40bd8720":"_changeOslikiFoundation(address)","40bdd3e9":"bytesEqual(bytes,bytes)","40bea8d2":"lockedEndTimeOf(address)","40beafc9":"depositToTWI(uint256)","40beee2b":"setPermanentPlatinumLevel(address,string)","40bf6424":"removalPrice()","40bff23d":"_createCard(uint256,address)","40c05401":"getWithdrawableAmountFIIT(address)","40c0bcb9":"checkBetNumber(uint8,address,bytes32,bytes32)","40c0c5ff":"PityToken()","40c0ece3":"updateMyReturns(uint256)","40c10f19":"mint(address,uint256)","40c243c9":"totalEthRefunded()","40c2dc4a":"getCCH_edit_6()","40c3198e":"getBenzByOwner(address)","40c3418c":"sendCrowdsaleBalance(address,uint256)","40c36524":"getFreeHatchCnt()","40c37ed2":"sellGameLockedToken(uint256)","40c3a6db":"MaxNumberOfBetsChanged(uint256)","40c3b187":"left37(uint256)","40c3b18e":"approveTransferableToggle()","40c44c5b":"DivisibleFirstCommonsForumToken()","40c44f6a":"setNewCFO(address)","40c48c8d":"setNewPriceInFinney(uint256)","40c48dfa":"Entropy()","40c558b2":"releaseCatIndexUpperBound(uint256)","40c58b2b":"get_foreign_balance(address)","40c5b34e":"currentPhaseId()","40c65003":"bonusEnds()","40c657c7":"buyTokens(address,uint256,uint256,uint256,uint256)","40c73d17":"changeAnimator(address)","40c7535b":"TangToken()","40c7e279":"requiredPlayers()","40c7e707":"contributeBTC(address,uint256)","40c85a59":"getLestCommonMulArray(uint256)","40c87214":"_startNewMiningEpoch()","40c8a90a":"GetLastMsg()","40c91c05":"submod(uint256,uint256,uint256)","40c92ae6":"multisigwallet(address[],uint256)","40c97617":"getReferralAddressShare()","40c9adcf":"_cancelOffer(uint256)","40c9e804":"SanityRates(address)","40ca0f05":"W0keAFPresale(uint256,uint256,uint256,address)","40ca925d":"ChannelManagerContract(address,address)","40caae06":"setOwner()","40cc1239":"TokenEmission(string,string,uint8,uint256)","40cc35ce":"teamWithdrawalProposed()","40cc8854":"bite(bytes32)","40cd988d":"refundBroadcaster(uint256)","40cde403":"exchangeBalanceOf(address)","40ce1d43":"EWWCOIN()","40ce5062":"isPublicSaleNoBonus()","40ceb451":"increasePromoCreatedCount()","40d0a103":"MarketOrderEvent(uint256,uint128,uint8,uint16,uint256,uint256)","40d113da":"sqrtAsm(uint256)","40d1d255":"claimEndTime()","40d21e6a":"getRelations(uint256)","40d22cf8":"completedTasks(uint256)","40d2e73c":"VanHardwareResourcesChain()","40d32df9":"MetaIdentityManager(uint256,uint256,uint256,address)","40d3d25a":"playersStorage(address)","40d40a72":"MANAGE_CAP()","40d48958":"_endTime()","40d67116":"setTokensPerOneETH(uint256)","40d681cb":"setupPresaleClaim()","40d699b7":"deathData_a4()","40d75432":"provideExchangeRate(uint256,uint256,uint256)","40d7b7b8":"dollarPrice()","40d7f7e8":"Staked(address,bytes32,uint256,uint256,uint256,uint256)","40d815cf":"Cyberium()","40d84b52":"updateCase(address,uint256)","40d8c74f":"checkForPayout()","40d96e6c":"finalizeSale3()","40da948f":"updateUnit(uint256)","40db4b09":"tokensOwedByInterval(uint256,uint256,uint256)","40dca307":"buyCoinsUpdateState(uint256)","40dda9af":"USER_LOCK_BLOCKS()","40de2784":"buildICOStageTwo()","40debefd":"SomeCoin(string,string,uint8)","40dee0c5":"LogRedeem(address,uint256,bytes32)","40df280e":"alliesContract()","40df78b6":"bankBurnFrom(address,uint256)","40e0653c":"_getLevel(uint256)","40e099ac":"makePromise(uint256)","40e15134":"presaleDist()","40e1e62b":"RedSoxYankees412()","40e2ad58":"buyOwnedPixels(bytes32)","40e31490":"killAnimal(uint16)","40e40765":"setTokenSaleHardCap(uint256)","40e424ee":"chooseWinner(bytes32)","40e4ebf4":"GenDayRatio(uint256)","40e50d00":"gcsc(uint256)","40e58ee5":"cancel(uint256)","40e5f3cb":"getEtherBalanceOnCrowdsale()","40e63ef3":"getPubKeyByHash(string)","40e687a9":"blockno()","40e6b00a":"createRefundPoll()","40e7261d":"Golem()","40e87f13":"dropTokenV2(address[])","40ebe5bc":"SHARD()","40ec0b6a":"isCurioAuction()","40ecb7f2":"isTransferValid(address,address,uint256)","40ed79f4":"hashimoto(bytes32,bytes8,uint256[],uint256[],uint256)","40eddc4e":"getCollectedEther()","40ee2485":"CryptoCovfefes()","40eedabb":"leader()","40ef4704":"getState(bytes10)","40ef78a7":"getExploreData(uint256)","40f03605":"existingContribution(address,address)","40f04616":"_buyDiscountTTW(uint256,uint256,address,address)","40f0a21f":"ceil(uint256)","40f10af2":"revokeAttribute(address,address,string,bytes)","40f12a02":"getPureWeaponDamageFromTokenId(uint256)","40f13c0f":"mintingFoundersFinish()","40f13db5":"addWhitelisted(address,address)","40f19da7":"isFinish(bytes32,bytes32)","40f29da3":"testReturnsProductInformation()","40f2a50b":"findDsp(address)","40f313b9":"ImportRemappingTestA()","40f354f3":"insertTopic(bytes15,address,string,string)","40f3633e":"icoMin()","40f3b6f1":"yourShares(address)","40f3c364":"ProjectTag()","40f47d41":"registerNameByCOO(string,address)","40f523f9":"TourMEToken()","40f54c08":"TrumpCoins()","40f56cfb":"PYPToken()","40f5c954":"sumICOStage8USD()","40f5ed88":"XPS()","40f702b4":"userInfo(string,uint256)","40f81cb5":"providerAllowance(address,bool)","40f828a2":"setLiquid(bool)","40f9b34c":"BetrTokenPurchase(address,address,uint256,uint256)","40f9c62c":"setLargeWalletAddress(address)","40f9cdf9":"get_tokens_count(uint256)","40fa368c":"getOrderHash(bytes32,uint256[2],address,bool,uint96)","40fa61f7":"upgradeFee()","40fc5e7a":"upgradeableTarget()","40fdef80":"administration(uint256,string,uint256,uint256,address)","40fdf515":"issuetender(address,uint256,uint256)","40fe90d0":"setFreezeOut(address[],bool)","40ff26ba":"adminAdd(address,string)","40ff38b2":"rootDomain()","40fff80c":"setCommissionAddress(address)","41002439":"amIReady(address,address)","410085df":"refund(address,uint256)","410090db":"ChangeEmissionGrowthCoefficient(uint8)","410158cd":"Winsshar(address)","4102bf5c":"getAvailableAmount(address[8],uint256[6],uint256,uint8,bytes32,bytes32)","4102f4e8":"mToken(address,uint256)","41031b1d":"NutzEnabled(address,address)","4103257e":"ReceivedETH(address,uint256)","410366c1":"settleDispute(bytes32,uint256,uint256)","4103c4c4":"OwnedHelper()","410453ae":"serverEndGame(uint32,int256,bytes32,bytes32,uint256,address,address,bytes)","4104df21":"cardsMinted()","4105048d":"Revealed(uint256,uint8)","410520f7":"PrivateReserveCoin()","4105e02f":"remark1()","41061c04":"addVestingMember(address,address,uint256,uint256,uint256)","410646e0":"getUnclaimedAmount(address,uint16)","41068ae2":"LicenseCore()","41080cfa":"getLLV_edit_7()","41095b60":"voteForUltimateOutcome(bytes,uint16)","410968d8":"MajLastNotVal()","41097886":"LogAirDrop(address,uint256)","4109a71a":"CerttifyCrowdsale(address,address,address)","410a1d32":"getDonation(address)","410a1db1":"setCommunityPool(address)","410a6734":"setAllBlockHashes()","410a68b5":"setOraclizeCallbackGasPrice(uint256)","410ace1f":"EOSBetSlots()","410af6b6":"allowAddressDelegate(address,address)","410b1da8":"currentTotalSupply()","410bf4bf":"CloudMoolah()","410c2601":"testGetAccountBalance()","410c47a0":"bb(uint256)","410c8005":"SetReciver(address)","410c83a3":"get_amount_get_buy(uint256)","410cbcc6":"YaoToken(uint256)","410da27d":"surveyEndAt()","410dbad6":"setaddress(address,address,address,address)","410dcc42":"setSeedHash(uint256,bytes32)","410e05b3":"bdevIssue(address,uint256)","410e7b42":"TestCoin()","410e8340":"checkAndConfirm(address,bytes32)","41104ef9":"GlobalOperatorChanged(address,address)","41107bee":"parseSums(bytes)","4110a489":"validatorsState(address)","4110b2c9":"addCapital()","411273d8":"getTokenToEthAddOrderHint(uint128,uint128)","4112987c":"strConcat(string,string,string)","4112b7f1":"tryGetNameOwner(bytes)","4112ea75":"SongTokenExchangeContractSet(address,address,bool)","41130267":"fxxkicotestToken()","4113d05b":"createGen0TokenWithDna(uint256)","41161aac":"X(uint256,string,string)","41163f7c":"deedCount()","4116dfc3":"getMetaDataCount(address,bytes32)","411735ee":"getAddressGains(address)","41179685":"finalizeContruibute()","4118cbc9":"setTokenExchangeRate(address,uint256)","41192788":"refund(address,address[],uint256[])","41193c18":"blockPlaylist(string)","411a1714":"setOperational(address[],bool)","411a1ac1":"BitcoinEye()","411a3dcf":"forward(address,uint256,uint256)","411a42ea":"ConeTest()","411a492e":"getNumOfLotteryTickets()","411ae567":"setSlogan(uint256,bytes)","411b007e":"founders()","411b65ef":"setPropertyLastUpdate(uint16,uint256)","411c4e72":"ModifyFeeFraction(uint256)","411cc791":"transferWithParams(address,uint256,uint256,uint256,uint256)","411d3021":"MahalaCoin()","411d6e19":"USDETH()","411dddb2":"TrueVeganCoinPresale()","411e6832":"tokenObj()","411f93d1":"transferTicket(address,address)","411fcce5":"BitcoinSoft()","41203243":"dateOfBonusRelease()","4120a236":"FreeNapkins()","4120a800":"PrepareRollEvent(address,uint256)","4120bcec":"forceRecoverCollateralOnBehalfOf(address,bytes32,address)","41215aff":"NewUpgradeMaster(address)","4121b9f8":"SBECoin()","41224405":"get_planet_price()","41225b0e":"broadcastSchellingRound(uint256,uint256)","412282cd":"addOwnerAccount(address)","41228803":"updateBalance(address,uint256,bool)","4123057e":"update_oraclize()","41237fd5":"levBlocks(address)","4123a0ac":"deleteToken()","4123a482":"transferTx(address,uint256)","4123cb6b":"m_numOwners()","41240314":"teamTwoSharePrice()","4124a6a7":"getLockedFunds()","41252b55":"FreezeTransfers(address,bool)","41264107":"TEChain()","412648bf":"setAvatarIndex(uint256)","412661c4":"_setAuth(address,address)","412664ae":"sendToken(address,uint256)","41266ae8":"Composed(uint256,address,uint32[5],uint32[5],string,string,uint8[20])","4126d29e":"justFailRequire()","412740c5":"balanceWithInterest(address)","41275358":"feeAddress()","4127d54a":"tokensForPresale1()","41282fe0":"usersCanUnfreeze()","41288e76":"sendEtherToMultisig()","412956ce":"goBackToPrivateSale()","412988e7":"subSupply(uint256)","4129912c":"misub(uint64,uint64)","4129a9d5":"newIcoRound(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4129b2c9":"getWinner(uint256)","4129b8ed":"remainingTokenHolder()","4129d7d1":"MessageSent(address,address,uint256,string,string,uint256)","412a5a6d":"createContract()","412a7be0":"athlete()","412b2ee0":"forkMe()","412c0b58":"initiate(bytes32,address,bytes32,uint256)","412c0c2d":"getWin(uint256)","412c7dfb":"FOUNDER_WALET()","412cbc06":"assetsCount(address)","412e829f":"LoveTracker()","412ec94f":"updateTokenPoolAddress(address)","412edecd":"setDAOAndMultiSig(address,address)","412eee05":"enactProp(uint256)","412f83b6":"getDelegatorUnbondingLock(address,uint256)","41300d03":"secondBonusRate()","41304fac":"log(string)","413100e0":"getLeftoverWei(address)","4131775e":"_removeUserCity(address,uint256)","4131f609":"verifyWining(uint256,uint256,uint256,bytes,bytes,bool,bytes32,bytes32)","41326679":"inVaults()","4132bae8":"calculateRAUS()","4133e7a1":"GxCancelOrders(address)","41348053":"ratePlanOfVendor(uint256,uint256)","413499f1":"deleteVoters()","4134a92a":"registerResource(bytes32,uint256,bytes32,string)","41354590":"setAtomIsBuy(uint256,uint128)","413699de":"setOwnerName(address,string)","4136aa35":"isAlive()","41388aed":"TokenHash(string,string,uint8,uint256)","41388c71":"DolyToken()","41395efa":"dgxBalance()","41398b15":"ethAddress()","413992b3":"createWarranty(string,string,address,uint256,uint256,uint256)","413a7f9a":"MethNSupply()","413ab4a8":"_reserve()","413abc3d":"min_share_price()","413bac7a":"jackpotinfo()","413bba97":"withdraw(uint256,bytes,address[])","413bc8eb":"TableDeRapprochement_322()","413c6d13":"setAddressValue(string,address)","413d18cb":"currentMessage(uint256)","413d7b08":"mainSaleTLYperETH()","413d9c3a":"LOCK_TIME()","413dc451":"countPerfClients(address)","413e31a8":"Testita()","413e4aaf":"calculateOwnerFee(uint256)","413e90e7":"putHashes(uint256)","413e920d":"oneMillion()","413ed292":"logState(string,uint8)","413f50da":"addAddressToWhitelist(uint256,address)","413f7d4c":"SECONDS_BETWEEN_ROUNDS()","414053be":"best_adjustment_for(bool,uint128)","41409437":"publishMetaData(bytes32,bytes1)","4141a121":"ETHERlemon()","4142f460":"segundos()","4143125f":"dusttorafflepot()","41431908":"setManagerAddress(address)","41434351":"oneday()","41445fd2":"c4c()","41446e0a":"bankersAcceptanceOfDeal()","4145aa9d":"grantMythexTokens(address,uint256)","41461bad":"gracePeriodStartBlock()","414689ff":"unlockAmount()","4146e099":"getCurRoundInfo()","4147060a":"LogRequirementChange(uint256)","41470877":"returnVesting()","4147e15e":"verifyOptionPoolMembers(address)","4147ffe5":"bitfwdToken()","41481372":"Fight(uint256,uint256,bool,bool)","4149953d":"transferRestore(address,address,uint256)","414b49a2":"setFreeLOT(address)","414b7ad6":"updateAff(uint256,uint256,uint256,uint256)","414b85e4":"isPreIco(uint256)","414bbda2":"declineCoins(address,uint256)","414c2aab":"MemberHandler(string,address)","414c377b":"updateSaleLimit(uint256)","414c4a8d":"maxAmountToSell()","414ceac0":"investorAddFee(uint256)","414d784e":"DECIMAL_ZEROS()","414db054":"Loss(address,uint8,uint256,bytes32,bytes32,uint256,uint256)","414db89e":"tokenForSale(uint256)","414e2e9e":"walkTowardsBlock(uint256)","414ee145":"lastBlock_f18Hash_uint256()","415016f4":"getBalance(uint16)","4150f4cd":"setSysAcc(address)","415194fb":"referral_ledger(address)","41522e41":"setHighWater(uint256)","41524433":"sellKissBTCWithCallback(uint256,address,uint256)","4153090e":"startFavorEscrow(uint256,uint256,uint256)","41533ba7":"getRateByTime()","4153d65b":"securePay(uint256)","4153d751":"onTransferOwnership(address,address)","41541318":"createPromoNinja(uint256,address)","4154aede":"refund(address,uint256,address)","415510df":"addressPreSale()","41554a2e":"issua(uint256)","41555acd":"storeOwner(address)","41562e69":"insertNodeBatch(bytes32,bytes32[2][5])","41566585":"whitelistAddress(address)","4156fdb7":"createSwap(uint256)","41583c4b":"_updateCardClaimerAddress(uint256,address)","4158506a":"participantsLength()","41585a0c":"increaseCount(bytes32)","41587b08":"addWeapon(uint8[176],uint8,uint8)","4158d848":"fundChecking()","41595f04":"ALLOC_RESERVED()","4159712a":"LogOwnerEthWithdrawn(address,uint256,string)","415a0d46":"_preValidateTokenTransfer(address,uint256)","415bc701":"HCPTToken()","415bd3fa":"_report(bool,string)","415c7593":"autoRentByAtom(uint256,uint256)","415dd7d8":"newRandomValue(bytes,address,uint256)","415eea1b":"vaultNum()","415ef37c":"weiSold()","415efb15":"setup(string,string,string,uint256,string,string,uint256)","415f1240":"liquidate(uint256)","415f47ea":"decodeOrderUserId(uint256)","415f9498":"commission2()","415fad10":"test_threeInvalidEqInt()","415ffba7":"close(uint256,bytes)","416108e2":"ERRLCoin()","4162169f":"dao()","416232af":"CampaignContract(address,address,address,address,uint256,string)","4163afb6":"MANHATTANPROXY8THAVE()","4163b5a4":"weiUsdRate()","4163d75d":"delPokemonFromSellingList(address,uint256)","4165295a":"getMixParticipantIdByAddress(bytes32,uint256,address,address)","416608a9":"updateTemplate(uint256,uint256,uint256,string,string)","4166c1fd":"getElevation(uint8,uint8)","4166eab4":"zeastadscredits()","41676f15":"isOrganizer(address)","4167c2fd":"setVaults(address,address,address,address,address)","416851a0":"testOracleQuery(string,string)","4168614a":"volumeBonus(uint256)","4168de57":"teamIssueVesting(address,uint256)","41696fa8":"updateMyEntity(uint256,bytes32,bytes32,bool,address,uint256,uint256)","416a1b62":"Liquet()","416ae768":"getUserState(address)","416bc7f6":"createSplitter(address[],string)","416c0d38":"adminRetrieveContractConfig()","416c3f16":"eligibleAmount(address,uint256)","416c6383":"testConcatMemory31Bytes()","416c8701":"beyond()","416c9627":"updatePresaleBonus(uint256)","416ccd02":"limitVIP()","416cf34e":"ULCToken(address,uint256)","416da702":"TOKEN_USDCENT_PRICE()","416dc762":"endThirdPeriodTimestamp()","416dffb0":"cleanupURLs()","416e517e":"setOutcome(uint256)","416e6d5e":"balanceManager()","416e70f6":"linkToMasterWallet(address,address)","416f222a":"submitBid(uint256,uint256,uint256)","416f5483":"changeEthAddress(address)","41709748":"getTotalDrone()","4170a419":"setCCH_edit_34(string)","4170e191":"MiniMeBaseCrowdsale(address)","4170ee08":"reVote(uint256)","41713a37":"directTradeAllowed()","41718066":"hitFoundationPrecent()","417297a0":"issueTokensSale(address[])","4172d080":"tokenExchangeRate()","41733f7a":"fooToken()","4173b181":"setWeiPrice(uint256)","4173c27a":"REEFToken()","4173ffbc":"getRand(uint256,uint256)","41744dd4":"feeRatio()","4174a943":"Deposited(address,address,address,uint256)","4174f1a5":"TOKEN_RATE()","4175b307":"addAddresses(address[],string)","41760afc":"_setEventsHistory(address)","41763225":"createRewardCollectible(uint8,uint8,uint256,address,uint256,uint256,uint256)","4176368f":"paymentSizeE()","4176ce68":"IsAuthority(address)","41771b62":"changeFees(uint8)","4177340d":"openGamePlayNo(uint256)","4177afa6":"TIER_2_BUYIN()","4178617f":"addAllowedToken(address)","41796bea":"OfferCreated(uint256,bytes,address)","41799883":"decreaseSoldSaleSupply(uint256)","417a2909":"getUpdateTimes()","417a767e":"getBetsBlock()","417a7d60":"checkMessageData(address)","417b3409":"DownloadMusic(uint256,address,uint256)","417b86fb":"getPolicyDetailsByHash(bytes32)","417ba840":"checkMemberLevel(address)","417c73a7":"addToBlackList(address)","417c8d40":"SEK_Omnidollar()","417cb353":"totalDecimals()","417d5fb4":"advisersPeriodsNumber()","417de5b5":"mintAirdropToken(uint256)","417e8e67":"getCompoundedInterest(uint256,uint256,uint256)","417ea2dc":"platformSupplyRemaining()","417f204e":"GATC(uint256,string,string)","417fd6b6":"setMinBidAmount(uint256)","41808d4a":"test_remove_tail()","4180b70d":"KKday()","4180c2d5":"payout(address[])","4180f6ec":"RESERVED_TOKENS_FOUNDERS_TEAM()","4181641b":"engrave(string,bytes32)","41829445":"createNewCE(bytes32)","4182e5eb":"deleteContract(uint256,address,uint8[],bytes32[],bytes32[])","4182fa46":"getHouseAddressShare()","41831218":"maxPerPersion()","41832bed":"generateOrderHashes(address[4],uint256[8])","4183689f":"initSignetures()","4183f0b3":"startCardSale()","41843aa5":"subusermoney(address,uint256)","4184907e":"ESPlatts()","41852eb2":"BuyToken()","418599cb":"SerenityTeamAllocator()","4185f8eb":"receiveEth()","4185fdc5":"decreaseFrozen(address,uint256)","41863a7d":"victorieumICO1Token()","41867384":"new_bonus_for_next_period()","41868769":"CallAborted(address,bytes)","4187a193":"stageThreeStart()","41883b78":"withdrawHouseEarnings()","4188d79c":"releaseExists(string,uint32,uint32,uint32,string,string)","418939c0":"fillBid()","4189a68e":"sell(uint256,address)","418ae602":"verificationAddressHoldersListCountMap(address)","418bc2ee":"updateHatchingRange(uint16,uint16)","418bc76c":"gasForKWH()","418c7de1":"currentFulfillment(string)","418ca0c7":"subOnStage(address,uint256,uint256)","418cb077":"CustomToken()","418cf199":"setEstimateCost(uint256,uint256)","418d4dcc":"collectPayoutForAddress(address,address)","418d75b6":"getBuyerOption()","418f1487":"confirmDividendsFromPot()","418f3a9b":"Invest(address,uint32,uint32,uint256)","4190af2e":"walletTokenReservation()","4190cfc1":"getAllQuestionAddresses()","4190f365":"PUBLIC_MAX_CONTRIBUTION()","41910104":"returnSuspendedPayments(address)","41910112":"DecentBetToken(address,address,address,uint256,uint256,uint256)","41910f90":"BASE_RATE()","41923c0c":"PRICE_ICO1()","419259ef":"reissueCert(bytes32,bytes,bytes32,uint256,bytes32,bytes,uint256)","4192610e":"callThisToStop()","419308f7":"getPreviousNode(bytes32)","4193b8b7":"bytesToUint(int256,bytes)","4193e15f":"OrbusToken()","419469fe":"calculateCellSell(uint256)","41953e90":"CoinTel()","4196cd4a":"stateIndexToApproved(uint256)","4196fad9":"mop()","419759f5":"depositAmount()","41976e09":"getPrice(address)","4198d24a":"mintAllocations()","4198e94d":"setbounty(uint256)","419945f8":"ExpiringMarket(uint256)","4199dbe6":"avvia_votazioni()","419a3de6":"allotItem(uint256,uint256)","419a88b6":"XPA()","419ab31e":"USERS_address()","419bd6c0":"Nairotex()","419ce264":"ercToNativeBridgesAllowed()","419db07b":"generousFee()","419e6e5c":"getTotalNamesCount()","419e7589":"setProviderDetails(uint256,string,string,uint256,string,uint8,address)","419eafdc":"winPercent(uint256)","419ef898":"IBRToken()","419f6a3a":"isAirdropOver()","419ffa03":"fipsRegister(address)","41a0894d":"getReferrals(address)","41a08aaf":"judge(uint256,bool)","41a0be7b":"renameHorsey(uint256,string)","41a1053f":"strRemoveLastCharacter(string)","41a1a582":"getOwnerPayout(uint256)","41a1d66c":"sendTokensToExchange(uint256)","41a2625f":"endPreico()","41a28df6":"setAdminAddr(address)","41a292be":"calcPriceAt(uint256)","41a41523":"TIMEDEX()","41a42ba2":"updateNetworkConnection(string,string,address)","41a461fb":"SDAToken()","41a49409":"setWhitelistManager(address)","41a494c5":"award()","41a4c309":"_burnApproveClear(address,address)","41a4c5bf":"changeBonus(uint256,uint256,uint256,uint256,uint256)","41a51d00":"total0xbtcBalance()","41a5518f":"getMineInfoInDay(address,uint256,uint256)","41a59cef":"SDGT(uint256,string,uint8,string)","41a5b33d":"withdrawFromToken(address,address,uint256)","41a6cfda":"ROSCcoin(uint256,string,string)","41a6f46e":"FIESTA()","41a70b4c":"addArgumentToRequestString(uint256,bytes32,bytes32)","41a76287":"updateUintSetting(uint256,uint256,address,string,string)","41a7726a":"subscribe(address)","41a806ca":"addFamily(address)","41a82cc1":"ruleB(uint256)","41a84a0d":"getTokensForContribution(address,uint16)","41a928fe":"downTick(uint256,uint256)","41a943e2":"addAdmin(address,address,bool,bool,bytes32)","41aaccb0":"claim_eth_by_address()","41abe705":"doCount(address)","41ac59b7":"massTransfer(address[])","41ac5dd0":"updateFulfillment(uint256,uint256,string)","41ad3f57":"chickenToAltar(uint256)","41ad5c72":"createGroup(bytes32,uint256)","41ad785e":"payAndDonate(address,address)","41adb3f5":"saveInfo(string)","41ade6b7":"setRegisteredFirm(string,bool)","41aeaea7":"restWei()","41aed7cb":"isActiveEmployer(address,address)","41af1524":"verificationCodeHash()","41affe19":"publicSaleWallets(uint256)","41b0b4cd":"distributedTeamStakes()","41b2485b":"fiatContract()","41b280d2":"getTXwithCode(bytes32)","41b3203c":"PlaySimpleGame(uint8,bool)","41b3a0d9":"contractEnabled()","41b3d185":"minDeposit()","41b44392":"removeDarknode(address)","41b4a626":"cashSale(address,uint256)","41b4be87":"getPoolbyGtype(uint8)","41b5467a":"getUnpaidPerfit(uint32,uint32,uint256)","41b6f6ce":"getStatusDeal(bytes32)","41b6fcf7":"paymentDigest(bytes32,uint256)","41b80184":"lastProfitTransferTimestamp()","41b8547c":"Dev_Supply()","41b94f10":"_toTaxed(uint256)","41b989d0":"CashDeposit(address,uint256)","41b9c14c":"getShipsByOwner()","41b9dc2b":"has(bytes32,bytes32)","41ba4738":"GOLD_AMOUNT_NDC()","41ba9a17":"removeMilestones(uint8)","41bb0559":"symbol(string)","41bb26d3":"handlePayment(address)","41bb50f7":"eachIssuedAmount()","41bc0b6a":"LivepeerVerifier(address,address,string)","41bc2bea":"setProviderOwner(uint256,address)","41bc7b1f":"getOracleDetails()","41bcd712":"RTPToken()","41bd84aa":"_removeAffiliate(uint256)","41be0a14":"SPOT9()","41be44d5":"XAUDToken()","41be84cf":"getWingsValue(uint256)","41becaef":"tokenIssueIndex()","41beef9d":"getSpareRecommAddr()","41c06b2a":"_reached(uint256)","41c0aa0e":"lockUnsoldTokens(address)","41c0dc59":"PAYOUT_FRAC_TOP()","41c0e1b5":"kill()","41c12a70":"voteNo()","41c14eb4":"BrokerImp(address,address,uint256,address)","41c173e2":"preICO(address,uint256)","41c1f017":"CONFIG_MAX_EXPOSURE_DIV()","41c1f5b4":"dreamToken()","41c1f60e":"instruct_5()","41c2c8f6":"FutaToken()","41c3e7c7":"report(address,bytes32,uint256[],bool)","41c41025":"updateFunders(address,bytes32,string,uint256)","41c41923":"freeze_contract()","41c46ff7":"PALToken8(uint256,address)","41c5cf5c":"ICOend()","41c61383":"totalClaims()","41c6f609":"registerNewMember(address,uint256)","41c7eb41":"populateTrancheRates()","41c8146c":"changeTimeBonuses(uint256,uint256,uint256,uint256,uint256,uint256)","41c838cb":"getSANitized(string)","41c8b1de":"lendingInterestRatePercentage()","41c8ba1e":"MIN_CONTRIBUTION_CHF()","41c9692b":"phase1Duration()","41c96964":"getInvestorInfo(uint256)","41c9c72d":"updateDelegatorRewards(address[],uint256[])","41ca641e":"getShareholders()","41ca7242":"maxCapPre()","41caea7d":"EventWithdraw(address,uint256)","41cbd6ea":"getTrustedPartner(address)","41cbfc7b":"getKeysByType(uint256)","41cc0aa5":"RET_MUL()","41cc8912":"renameToken(string,string)","41ccf987":"ownedPool()","41cd47bf":"FEE_NUMERATOR()","41cdd253":"TestFMA(uint256,string,string)","41ce7f23":"BACToken(uint256,string,uint8,string)","41ce909f":"Bitroneum()","41ce979d":"VanityReleased(string)","41ce9f0e":"setBZRxTokenContractAddress(address)","41cfbb96":"test_someOtherFalseTest()","41d003cb":"setBonusCreationRate(uint256)","41d00774":"CoefRew()","41d00b1d":"EBIToken()","41d03085":"NEWONE()","41d09fbe":"sendWinnings()","41d0fcb6":"setSanctuaryAddress(address,address)","41d15b54":"createProductionUnitTokenContract(uint8,uint8,uint8,uint256,uint256,uint256,uint256)","41d1a4d6":"getStrategyAtIndex(uint256)","41d1da19":"Cloudeb()","41d20767":"ethMinContribution()","41d2c748":"applyCoeff(uint256,address)","41d31feb":"get_read_only_keys()","41d45f4a":"UNEK()","41d4a1ab":"bonusToken()","41d4a39e":"setCrowdsaleClosed(bool,bool)","41d5da6b":"getMyStatus(bytes32,bytes32)","41d5e10c":"BittwattToken(uint256)","41d5f7ac":"eligibleAmountCheck(address,uint256)","41d76a9c":"firstTime()","41d80050":"FundsGot(address,uint256)","41d875dc":"setStr(uint256,string)","41d8bc5f":"setExchangeRateOracle(address)","41d9cc43":"forgeItems(uint256,uint256)","41da7538":"getJadeProduction(address)","41da7555":"ownerPercentage()","41db1875":"makeBuyOrder(address,uint256)","41db61e1":"toGMT(uint256)","41db7e16":"RGN()","41db8c93":"_startCrowdsale(address,uint256)","41dbb51e":"IsFrozen()","41dbbb61":"SmartexFundsManager()","41dbe546":"HedeCoin()","41dc02cf":"changePatentSale(uint16,uint256)","41dcf454":"tokenURI(uint256,string)","41de2164":"getPhaseStartTime(uint256)","41de4181":"fireDepositToChildEvent(uint256)","41de4f16":"queenchUSBToken()","41dedc58":"gradeinfo()","41defd82":"cancelJobByAdmin(bytes32,uint256,address,uint256)","41df696e":"start_play_quiz(string,string)","41dfed3a":"viewCurrentPrice()","41e0b5d4":"Fenerbahce()","41e0c407":"getStudentCount()","41e1234e":"presaleFemaleStart()","41e14251":"devuelveUsers()","41e18398":"batchTransferFromManyToMany(address[],address[],uint256[])","41e34be9":"unitSellable(uint256)","41e3a6b5":"updateSplitBalances()","41e50814":"DEVCoin(uint256,uint256)","41e62be6":"VRToken()","41e6fd4b":"hasSecret(uint256)","41e7a787":"ERC223StandardToken(string,string,uint8,address,uint256)","41e7c47e":"FBR2()","41e884d4":"viewLastClaimedDividend(address,address)","41e8b94c":"isThereABlockAtCoordinates(uint16,uint16)","41e8da52":"makeBet(uint256,uint256,address,uint256,uint256)","41e8fe9f":"EventRandomLedgerRevealed(address,uint256,uint256,address)","41e906e5":"getExercised(address)","41ea5127":"BaseAuction()","41ea59a9":"isFoundationSupplyAssigned()","41eb1a4a":"setUintCoinProduction(address,address,uint256,uint256,bool)","41eb24bb":"renouncePauser(address)","41ebb063":"KRHCoin(uint256,string,uint8,string)","41ebe9c6":"ScarcecoinStart()","41ecd1cd":"withdrawOwnerUnrevealed(uint256,address)","41ece976":"updateMinInvestmentForPreIco(uint256)","41ecf95b":"ParticipantJoined(uint8,uint16,uint32,address)","41ed2c12":"marketManager()","41eddf00":"checkIfCurrentlyActive(uint256)","41ee903e":"clear(uint256,uint256)","41eeb105":"doRelease(bytes16,address,address,uint256,uint16,uint128)","41ef3879":"stage1_price()","41ef6bb7":"uncirculatedSupplyCount()","41ef858f":"whitelistAddress(address,address,uint256)","41ef9184":"Pretorian()","41f18b43":"claimEarlyIncomebyAddress(address)","41f1d4dd":"whitelistControl()","41f1e76c":"minFundingGoalReached()","41f1f3e5":"getPayeeIndex(bytes32,address,address)","41f2ce14":"setABalance(address,uint256)","41f31724":"Tzedakah()","41f36984":"collectGamePayout(uint256,uint256)","41f4793a":"getCurrentImpeachmentVotesSupporting()","41f48ebf":"currentIco()","41f4ab98":"addManyToPresaleWhitelist(address[])","41f4fcaf":"isDrop(uint256,address)","41f51941":"doActivateSale(address)","41f59e81":"initBonuses()","41f64b85":"deleteBag(uint256)","41f65507":"pendingOracleA()","41f6e77e":"FindTheCureCoin2()","41f70465":"startCoinOffering(uint256,uint256,uint256,uint256)","41f77260":"withdrawSyndicateTokens()","41f8a524":"Verificator()","41f99b69":"setWithdrawalCoolingPeriod(uint256)","41f99e2f":"getPostDonationAmount(address,uint256)","41fa4876":"multiBlockRandomGen(uint256,uint256)","41fade8f":"getconfig(address)","41fb55c6":"mMaxAppCode()","41fbb050":"foundation()","41fcb0f7":"buyNapkins(address)","41fd32cf":"SafecontractsTREXCrowdfunding()","41fe0a24":"buyCrystalDemand(uint256,uint256,string,string)","41fee898":"refundPercent()","41ff4275":"_calculateUnlockedTokens(uint256,uint256,uint256,uint256,uint8)","41ffbc1f":"ringIndex()","42007fd3":"MarkRazAsComplete(uint256)","4202d214":"isActiveUser(address)","4203ea57":"minInvestmentPreICO()","4204f7d5":"deployMinersTest(uint32,address,uint32[],uint32[],uint32[])","4205875f":"ROUND_6_PRESALE_BONUS()","4205e5af":"pauseClosingTime()","4206311b":"TimeLockSend(address,address,uint256)","420714bd":"requestIndex()","42071a73":"bltRetained()","4207d648":"directorJurisdication()","42091137":"addStringSetting(string,string,address,address,string)","42091e76":"saltoken(address,address)","42095679":"lindyhanCoin()","420977d8":"viewStudent(uint256)","4209fff1":"isUser(address)","420a83e7":"tokenHolder()","420a8ac8":"NanoPyramid()","420a8b76":"Dancer()","420aa07d":"serviceTrasferToDist(bytes32,uint256)","420aadb8":"_execute()","420ae446":"allocatetokensAndWLExp(address,uint256,uint256)","420b5fe0":"initializeVestingFor(address)","420b81f6":"peekData()","420b9921":"ecsubtract(uint256,uint256,uint256,uint256,uint256,uint256)","420c96ea":"newArtwork(bytes32,uint256,string,string,string,uint256)","420d0ba4":"nobodyCanDoThis()","420d23fd":"POOL_EDIT_1()","420d4a02":"getUnlockedAmount(address)","420d4bdd":"CRYPTAU()","420dd15a":"getLast(string)","420ddaa6":"encodeKYCFlag(bool)","420e1f51":"tokenExchanges()","420e7ea6":"tokenAmountRasied()","420ef2b3":"TargetHash()","4210ad0e":"newBurnableOpenPayment(address,uint256)","42111339":"contributeLocal()","42118f51":"manualLCs()","4212616b":"localsUser()","4214352d":"write_what_where_gadget(uint256,uint256)","4214d52f":"updateIndex(address,address)","421521b1":"finalizeOpenSale()","42154e9c":"countAddress()","42159ca3":"getMaxDelayDays()","4215a39b":"getCreateMarketNumOutcomesValue()","4215da7d":"investorsStorage()","4216503c":"setFunStr(string)","42170736":"secondPhaseStartTime()","421715c2":"canBorrow()","42173c98":"purchaseCompany(bytes32,bool)","42193473":"DUST_LIMIT()","421a5727":"stealPot()","421ae949":"thawTokenTransfers()","421aeba2":"setEditedFalse(address)","421aeda6":"Set_your_game_number(string)","421b2395":"UltiCoinICO()","421b2d8b":"addUser(address)","421c0d9c":"unregisterDsp(address)","421d72e2":"isPaymentForked(uint256)","421db384":"leftICOTokens()","421e2dc2":"getPartnerAmount(address)","421e52e3":"card_gold_minamount()","421ed7dd":"balancesInitialized()","4220324b":"mainSaleStart()","42207083":"getGameRoundOpen(uint256,uint256)","4221115c":"SfomoToken(uint256,string,string)","42226e02":"setMaxEth(uint256)","42235da6":"minimumTarget()","4223ac0f":"ABCToken()","4223ad89":"NewRefundTransaction(uint256,uint88)","4224f2ca":"HzxhcToken(address,address)","42261ea4":"cancelSale(address[])","422624d2":"destroycontract(address)","422627c3":"getDna(uint256)","42263aa2":"set_token_address(address)","422752bf":"getPartialAmountFloor(uint256,uint256,uint256)","42279e82":"removeFromPreSaleRefunds(address,uint256)","422810ea":"transData(address,uint256,bytes)","42285bc5":"_ensureRef(address)","42287b66":"createPromoPerson(address,string,uint256)","4228974c":"Videos()","4229616d":"collectPercentOfFees(uint256)","4229c35e":"setItemPrice(uint256,uint256)","422b00bb":"dataentryclerk()","422b1c70":"setMinweiAmount(uint256)","422b423e":"getCheatWarrant()","422b7964":"_approve(uint256,address)","422c29a4":"getWallets(address)","422c3ad9":"changeEndTime(address,uint256,uint256)","422cbb48":"MarkosToken()","422d3374":"tbitfwdToken()","422d37c4":"mintWithEvent(int256,address,uint256)","422d4cd6":"increasePayout(uint256,uint256,uint256)","422dabac":"allocateEther(uint256,address)","422e33f3":"migrationNewAddress(address)","422e82a7":"EthToCoins1()","422f1043":"addLiquidity(uint256,uint256,uint256)","422f3a2c":"nestedFirstAnyToSome(uint256,uint256)","422fcbd5":"MCST()","4230bb10":"badgeLedger()","42317bbc":"flipRefundSwitchTo(bool)","42318e3d":"percent(uint256,uint256)","4231a2c3":"getLastRound()","4231e2d7":"transferFreezership(address)","4231ee16":"addInBountyProgramMap(address)","42320732":"allSupply()","423252f9":"buscarDocumentoPorTitulo(bytes32)","4232a399":"XC()","42340458":"disable(uint8)","42346c5e":"parseInt(string)","423592ce":"startTde()","4235e336":"BetDirectory()","4235e98e":"Buy(uint8,string,string)","42367389":"test_twoValidEqInt2()","4236b312":"dealContract(uint256,string,uint256,uint256,string)","4236da98":"INTREPID_PRICE_INCREMENT()","42382353":"restartTheQueue()","4238b84c":"DMBToken()","423948fd":"changeCollateralAmount(uint256)","42399220":"setCampaignOwnerById(bytes32,address)","423a7954":"developerfee()","423a968d":"_setRSPScienceAddress(address)","423b1ca3":"battleContract()","423c3a48":"burnTokens(address,address,uint256)","423c485a":"depositFee(uint256)","423d4ef2":"createChannel()","423da88e":"Unix_Timestamp_Binary_Trading(uint256)","423dcf29":"dustToEtherPrice()","423e1298":"setDoNotAutoRefundTo(bool)","423e7e79":"_dispatchEarnings()","423f0b6e":"replaceModule(address)","423f6cef":"safeTransfer(address,uint256)","423fb140":"CrowdsaleToken(string,string,uint256,uint256)","423fcd5e":"_promo()","42402c2c":"fipsTransferMulti(bytes20[],address)","4240a978":"ICO_TILL()","42419336":"ICO_BONUS_RATE()","42427bf8":"upgradeController(address,address)","4243cb36":"payConversionFromTransaction(uint256,address,uint256)","4244e09f":"getBetterBettingInfo(address)","4245508a":"getRoundMaxNumberOfBets(uint256)","424592ca":"calculateDistributedIntervalEarning(uint256,uint256)","424599c4":"seedSaleTokenLeft(address)","4245b0f7":"Lottery()","4245d48e":"getHashes()","4245f3da":"tokenOfOwnerByIndex(uint256)","42465a1e":"getTokenUnits(address)","42469e97":"_setBonusRate(uint256)","4246ad24":"calculateMinedCoinsForTX(uint256,uint256)","4247f52d":"DoRoll()","4248083b":"approveUser(address,uint256)","4248afe8":"addCrowdSaleTokensMulti(address[],uint256[])","424976f9":"registryRead(bytes32,bytes32)","42498389":"transferLimitedFundToAccount(address,uint256)","424a8993":"selectOfferingProposal(uint8)","424a8c0d":"constructorReconToken(address,string,string,uint8,uint256,bool,bool)","424aa0e5":"StockusToken()","424b828f":"CharityReservesWallet()","424bc2e9":"newGame(string,string)","424d6bb1":"changeApi(address,address)","424ddaac":"get_available_interest_amount()","424e418f":"setMinSecondaryAmount(uint256)","424e94da":"VoteHub(address)","424ea3b2":"refund_deposits(string)","424ea872":"startTimestampIco()","424eb9fe":"getInitBalance(address)","424f9947":"privateIcoBonus()","424fa9ec":"Prismacoin()","424fed48":"EBPtandardToken(uint256,string,uint8,string)","424fffda":"updateContact(string)","4251447a":"WhiteListSet(address,uint256)","42516f1d":"startAirdropBy0Eth()","425189e0":"getFashion(uint256)","4251a7a4":"totalNihilum()","4251ecb4":"nMsg()","42526e4e":"bytesToAddress(bytes)","425432b1":"tokensPerAddress(address)","42545825":"hasVoted(address,uint256)","4254704f":"TOKEN_CLAIM_WAIT_PERIOD()","4254b155":"register(bytes32,string,address,address,address)","425543f1":"CreateDummyPlayer(bytes32,uint8,uint256,address)","4255e808":"jackpotContract()","42565405":"setNeuroChainAddress(string)","42569ff3":"limitedPrinter()","4256dbe3":"setReserve(uint256)","4256fa5a":"timeToBorn()","4256fa9f":"exchangeTokens(address,uint256)","4257347e":"freezeAccountToken(address,uint256,uint256)","42577935":"createPanda(uint256,uint256)","4257d3e0":"currentGameBlockNumber()","42585b34":"getSnap(uint256)","42587795":"deploySimpleContract(string,string,uint256)","4258cb76":"Ultracash()","4258d771":"funding_ended()","425946e3":"setCurrentMember(address)","4259701b":"getSocialAccountPw(bytes32,bytes32)","4259b52e":"configurationCrowdsale(address,uint256,uint256,address,uint256[],uint256,uint256,uint8)","425adae7":"isBonusEnabled()","425d4980":"mintAddress()","425d512a":"setDAOContract(address)","425e0d3c":"BasicToken(uint256,string,uint256,string)","425f7857":"taxTokenCreated()","4260c779":"start_ico()","42616d21":"goldTotalSupply()","42618b91":"buyRoundKey(uint256)","426201ef":"lastBlock_v19()","42623360":"stakeOf(address)","426365ad":"setForceOffsetAmount(uint256,uint256)","42636c09":"existIdAfterVersion(bytes32)","4263ed83":"hasNextSeedHashA()","4264b4e0":"ownerPayout()","4266806b":"cf1Wallet2Pct()","4266873f":"setAicPrice(uint256)","426695c6":"getDeedId(bytes32,uint256)","4267e19c":"getOwnedTokensIndex(uint256)","42686bbe":"GetPartLimit(uint8,uint256)","4268a257":"updateRoundInformation()","4268db7d":"cite(string,string)","4269d8ef":"_safeSend(address,uint256)","426a0af3":"updateManyLandData(uint256,uint256[],string)","426a8493":"approve(address,uint256,uint256)","426aa87f":"deleteRecording(uint256)","426ad3f5":"getChainName(uint32)","426b7113":"tokensSoldPre()","426bc60c":"Educoin(uint256,string,uint8,string)","426d4f22":"expandNegative128BitCast(uint256)","426d5ef1":"oraclizeCallbacks(bytes32)","426d70fa":"isPrivateIcoActive()","426e0b20":"daoStakeClaimed()","426e5ae6":"senderTokenBalance()","426e6f8e":"updateValueAndMint(uint256,uint256)","426eae45":"bondingManager()","426eb017":"uri(address)","426f5531":"maxAllProfit()","426fa499":"isIcoStarted()","426fe411":"contributorDeposit()","4270d48a":"nextmarketoffer()","42714978":"removeInvestor(address)","427163dc":"refundBid(bytes32)","4272f2d5":"heroTokenContract()","4273601c":"factoryOwner()","4273bc59":"bids_sorted_refunded()","42740286":"maxMintPoS()","42750020":"tokensCreated()","42753e7e":"isInSale()","4276016f":"oversightAddress()","427654da":"getDailyLimitUsed()","42767018":"smallRate()","4276d082":"FrozenEther()","42772947":"callEndRoundControl()","4277b5b1":"check(address,address,address,uint256)","4277e497":"PaymentRejected(address,bytes8,uint256)","4277e823":"TravelHelperToken(address,address,address,address,address,address)","42787798":"grantedContracts(address)","4278ff31":"setTangibleAssetAddress(address)","427913f2":"getClaimedFinancialData()","4279523e":"serviceChangeOwner(address)","427982f2":"tokenSaleMax()","427a2fc2":"getClaim(uint256,uint256)","427ac5e4":"checkForUpdates()","427b59d3":"HiPrecious()","427b72fc":"proofFailed(address,uint256)","427c854d":"_createSkull(uint256,uint256,uint256,address)","427c9aca":"LogPayoutFailed(address,uint256,uint256)","427d5f2e":"tierAmountCaps(uint256)","427da275":"redeemUTXO(uint256,bytes32[],bytes,bool,uint8,bytes32,bytes32)","427e024a":"AdministratorRemoved(address,address)","427e332f":"lastBlock_a8()","427eebfc":"returnOwnershipOfToken()","427f0b00":"roundInfo(uint256)","427f56ff":"bonusAllocAddress()","427f9614":"getReference(bytes32)","427fa1d2":"getLastNode(address)","427fc2df":"preIcoPeriod()","4280606b":"addCondition(bytes32,bytes32,address,int256,bytes32,address,int256,bytes32)","4281267b":"buyLCARS()","4281a651":"SponsoredItemGooRaffle()","4281b13f":"getAllbetByNum(uint8,int8)","4281b34b":"play(uint256,uint256[])","42836c2e":"hasAddress(address,address)","4283fbe5":"dummyGasBurner()","42842e0e":"safeTransferFrom(address,address,uint256)","42846c09":"Bonus(address)","42849570":"myReward()","4285d477":"teamTokensFreeze(address)","428657f7":"storeNewVesting(address,string,uint256)","4286ed3e":"callBtoWithStc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","4287eef9":"fechStageBlockByIndex(uint256)","4287f14a":"teamReserve()","428840f6":"fadd()","4288d759":"betOf(address)","4289c781":"setSellPrice(uint256,string)","428a2ece":"createTokenVault(uint256)","428a8120":"tier0Total()","428afcd1":"setUpgraded(uint256)","428be33f":"ReleaseFundsAndTokens()","428c91ae":"genAddressFromGTIN13date(string,string)","428d475a":"beConstant()","428d5630":"mintOnDemand(address,uint256)","428d64bd":"getShares(address,bytes32[])","428e2d64":"getMsg(address)","428e357b":"getUInt8(bytes32,bytes32)","428e5aaa":"addToPrize()","428eb006":"batchAirdropWithLock(address[],uint256,bool)","428eb5cf":"getRandomNumber(int256,int256)","428f180c":"minimumSpend()","428f4146":"SimplePHXExchange()","42906029":"newManager()","42909a9e":"create_game()","4290a5b9":"uninject(address)","4290bd4d":"isTokenOfferedToken(address)","4290db52":"burnFromAnotherAccount(address,uint256)","4290e6b6":"setTokenName(address,uint256,string)","42915914":"test_dispersal()","4292327c":"_isMyLeague(uint8)","42923409":"ArinToken()","4292a797":"ZAZA()","4293253c":"tokenSaleLowerLimit()","429374f3":"ScorpioCoin(address)","42946d88":"getIGOAccoountByAddr(address)","4294857f":"isRevoked(bytes32)","42948e18":"getSenderAddress()","4294bea0":"BarcelonavsRoma()","4294cdb2":"BixcPro(uint256,string,uint8,string)","42958b54":"issue(address[],uint256)","42966c68":"burn(uint256)","4296a9cb":"getNodeRightChild(bytes)","4296b4a7":"freezePlayer(address)","42974b1e":"freeReferralPacksClaimed()","42980e20":"LifeToken()","429838e0":"Allow_Entries()","42992dd5":"icoStartTimestampStage2()","4299431e":"REALMock(address)","42995e12":"canReceiveMintWhitelist()","4299c213":"lastReading(address)","4299f706":"PonziScheme(uint256)","429a2591":"convertAmountToTokens(uint256)","429aa0a4":"DAILYC()","429adcb9":"minSumICOStage7USD()","429b62e5":"admins(address)","429b92bf":"getProposalName(uint256)","429c1561":"setReputationProblems(address,string)","429c6e5b":"getClaimedAmount(uint256)","429cddca":"selectOwnerAddressForTransactionFee(address)","429d15ba":"testCorrectFunctionIsCalledOnTransfer()","429d6a69":"walletBeneficiary()","429f3b48":"blockAccount(uint256)","42a04fea":"getBadges()","42a1928b":"initSale(uint256,uint256,uint256)","42a19c71":"giveProjectTokens(address,uint256)","42a1f3eb":"ProvToken()","42a37176":"showMyEtherBalance()","42a38a00":"mediatorWallet()","42a4af66":"updateCatReleasePrice(uint32,uint256)","42a5000d":"startPRESALE()","42a63361":"updateTribeProducts(address)","42a657fd":"primaryListing()","42a6617d":"stepTwoRate()","42a66f68":"totalRate()","42a6739b":"acceptRandom(bytes32,bytes)","42a6b21a":"getContributionLimit(address)","42a6c4dd":"getBidByToken(address,uint256,uint256)","42a745cb":"testBitEqualSuccess()","42a787fa":"determinePlayer(int128,uint128,uint8,bytes32,bytes32)","42a7a8e0":"SmartzToken()","42a7c40e":"ThiccCoin()","42a7cfd5":"naturalUnit()","42a8f2f4":"internalTransfer()","42abfde8":"getLunckyIndex(uint256)","42ad2c6f":"maxPreIcoDuration()","42ae07c0":"RateRemove(address)","42ae0a16":"crowdsaleBalance()","42aeba30":"Shipment(address,address,string,string,int256,int256,uint256,uint256)","42af2478":"PartialFundsTransfer(uint256)","42af4821":"TUDOR()","42af8f0c":"buy(uint256,uint256,address,address,address)","42b07d6d":"cashBackFromProject(address)","42b1295a":"addMultipleAllowedAddresses(address[])","42b2106c":"FoundationTransferred(address,address)","42b222bd":"showTokenValue(address)","42b31b1f":"Elythrium()","42b38674":"isValidValidatorSignature(address,bytes32,address,bytes)","42b41aa4":"sendCoin(address,address,address,uint256)","42b4632e":"canPropose(address)","42b4807a":"getRegionCoordinates(uint256)","42b4ef95":"Helper()","42b50a7a":"getOrderById(uint256)","42b594cb":"buyTicketByEth(uint256,bytes32,bytes32,bytes32)","42b5a2a9":"maxTxGasPrice()","42b614a9":"round_after()","42b64a59":"VisionX()","42b8c415":"balanceTotal()","42bb5709":"FundsTransfer()","42bb66c4":"setInvest(uint256,uint256)","42bd0959":"setIsBuyByAtom(uint256,uint128)","42be5eea":"thing(string,string,uint8,string)","42be9307":"changeSale(bool)","42beb58b":"setPreSaleOff()","42bf1270":"cslToken()","42bf41ae":"drainStrayEther(uint256)","42bf4431":"orderMatchTest(uint256,uint256,uint256,int256,uint256,uint256,address,address,int256)","42bf5347":"getUserFreezeInfo(address,uint256)","42bf8db3":"getRate(string,uint64)","42bff0d0":"setExchangeAdapterManager(address)","42c01f66":"setRateEarlyStage3(uint256)","42c1867b":"mintAgents(address)","42c1ea29":"evidenceInterval()","42c23db5":"AddToDividends(uint256)","42c2d31a":"EtheremonToken(address,address,address,address)","42c304be":"accountsListLength()","42c3301a":"showJackpotThisRd()","42c469e0":"GameSpiritCoin()","42c501a1":"LogOwnerTransfer(address,uint256)","42c50f75":"TeamMembersAmount()","42c549c0":"getMilestones(uint256)","42c5d7ad":"sendAdvisorsBalance(address,uint256)","42c62865":"withdrawsCount()","42c6498a":"genesisTime()","42c65ae5":"eUSD()","42c69566":"get_address(address,string)","42c71f1d":"getApp(bytes32)","42c74c73":"EPVToken()","42c7551e":"tokenRemain()","42c7ea5f":"totalNumberAvailable()","42c80fc9":"isUpgraded()","42c81f45":"MLB_Legal()","42c8705b":"Mine()","42c87205":"VirgoContract()","42c96767":"EtherHiLo()","42ca08cf":"applyFadeoutToOptions(uint32,uint32,uint32,uint256,uint256)","42ca2fe3":"FCOIN1110Token(uint256,string,string,uint256)","42cb1fbc":"ETHER()","42cbb15c":"getBlockNumber()","42cc6b04":"addAuthorizedEditAgent(address)","42cde4e8":"threshold()","42cdfe37":"tokenWithdrawEther(address)","42ce0555":"DisableSuicide()","42ce0aff":"registerAndValidateToken(address,string,string,uint256,uint256)","42ce0f30":"testThrowUpdateLatestRevisionNotOwner()","42ce1488":"upload(string)","42cf0a4b":"increaseEthBalance(address,uint256)","42cf0e72":"searchByOwner(address)","42cf2f81":"getSequence(bytes)","42cfd792":"postJob(uint256,uint256,uint256,bytes32)","42cffda9":"TREETOKEN()","42d01878":"keyRequired()","42d02b30":"HARD_CAP_IN_TOKENS()","42d16748":"getMinDailyWithdrawalLimit()","42d1b202":"_adoptSameClassAxies(address,uint8,uint256,address)","42d1f17f":"bankrollerTable()","42d2c127":"getStagesBeginEnd()","42d46a9a":"castVote(uint256,uint256,bytes32,string,bytes32)","42d544fb":"disallowSale()","42d596e0":"isPoint(int256,uint256,uint256)","42d64601":"pacifistmasterReq()","42d7cc8e":"Tx(address,uint256,string)","42d8f5be":"customPayment(address,uint256)","42d928fc":"SWIFTSCO(address)","42d9643c":"KYCLimitValue()","42da3b6b":"getAmount(uint256,address)","42daf6ee":"icoStartP6()","42dbad44":"makerOf(string)","42dbcdba":"weiRaised(address)","42dca9ea":"getManifestIdsByRegistrant(address)","42dd519c":"getClients(uint256)","42dd96f7":"killswitch()","42df7085":"ROLE_EXCHANGER()","42dfb036":"calcRateFromQty(uint256,uint256,uint256,uint256)","42e06ee7":"HotCold()","42e11316":"claimReadership(uint256,string)","42e1452a":"PolarisUniversalToken()","42e15c74":"managedTokenLedger()","42e16015":"AddedBlackList(address)","42e296d3":"soundEffects(uint256,uint256)","42e2d18c":"presaleIsRunning()","42e2da09":"QuantorPreSale(uint256,uint256,address,address,address,uint256,uint256,uint256)","42e2f54c":"shutDownFund(address)","42e35f63":"addGoal(string)","42e3b919":"NMFToken()","42e49d5a":"FUNDING_GOAL()","42e4d72b":"oxen()","42e5033e":"mainSaleEndDate()","42e59afa":"reloadRound(address,uint256)","42e5b9f1":"totalDistributedDividends()","42e5d5c8":"getPI_edit_17()","42e5da0d":"UpdatePlatformContract(string,address)","42e6377f":"LabtorumToken()","42e6c88a":"approveObjectReception(uint256)","42e7ba7b":"hasManagerAccess(address)","42e8051c":"testExternal()","42e81b0c":"dislikeCelebrity(uint256,uint256)","42e86d27":"callData(address,bytes)","42e90c33":"Store()","42e9555e":"getProviderLastSupplyID(uint256)","42e956f6":"addtoMarketingBusinessDev(address,address,uint256,uint256)","42e9c6ce":"pullTokens(address)","42ea74c0":"getTokenPriceInWEI()","42eabc29":"posibleRedemptionOf(address)","42ead91f":"getMegabox(uint256)","42eafaf5":"showFPInfoAll()","42ec38e2":"tokenOf(address)","42ed00da":"getSenderArmyDetails()","42ed567c":"tmpQuerySeed(uint256,uint256)","42ed5816":"ethDailyLimit()","42ed6072":"publicBattlepm2()","42ee4e0b":"ICO_PRICE5()","42ef4c1a":"hodlerTime6M()","42ef8c76":"alsToken()","42efdebf":"exchangeAdmin()","42f030e4":"minusTourFreezingTime(uint256)","42f0b07e":"BountyFund()","42f0ca0d":"setPreSaleEndDate(uint256)","42f1181e":"addAuthorizedAddress(address)","42f362aa":"registerNameCore(uint256,address,uint256,bytes32,bool,bool)","42f39381":"presaleRate()","42f39a6f":"ARXPackageSale()","42f3f7e0":"activate_reserve()","42f45790":"testAddress(address)","42f57e4c":"enableUser(address,bool)","42f5d95d":"AllUnLock()","42f6208e":"lock(address[])","42f6487a":"payment()","42f6e389":"isModule(address)","42f81580":"CLAIM_DEADLINE()","42f85ce5":"pay(address,uint256,uint256[])","42f88548":"updateRegionPixelPrice(address[16],uint256,uint256)","42f88699":"ExShellToken()","42f9192a":"nameFilter(string)","42f91e9e":"BcxssToken()","42f989e2":"setUnlockTimeStamp(uint256)","42f98b14":"buyIssuerTokens()","42f9b306":"teamLockTransfer(address,uint256)","42fa3967":"toSlice(bytes,uint32)","42fa98e0":"Orange()","42fba0f5":"grantedTokensHardCap()","42fbbc9c":"managerPercentage(bytes32)","42fc63be":"DebugHash(bytes)","42fd6acc":"checkProof(bytes32[],bytes32)","42fd7d4c":"_buy(address)","42fdbed7":"isDeDeContract(address)","42fea02b":"confirmPayer(uint256,uint256)","42feba84":"arbiterResponseRate(address)","42ff1c1a":"getMetadataURL()","42ffb76b":"getWorkflowName()","4300705d":"withdrawGTO()","4300e8ef":"addContract(address,string)","4301b55b":"MintOpened()","4301cbe5":"getAllNames(string)","43021054":"BTestToken(address,string,string,uint256,uint256)","43021202":"fundValuePublish(uint256,uint256,uint256)","4302b3c8":"myTotalSupply()","43031e9b":"getSumOfPlayers()","4303707e":"generateRandomNumber(uint256)","43039433":"handleReturnData()","43046844":"placeBet(uint8)","4304a43f":"updatedBalance()","4304a6b9":"setUnfreezeStartTime(uint256)","430558c2":"buyGifto()","43062ea7":"changePurchaseCap(uint256)","4306cc3f":"queryEarnings(address)","4307d081":"jazzxToken()","4308a36b":"getIcoPrice()","43090357":"readUserPurchasedToday(address)","4309b4b2":"getPollIdentifier(address,bytes32,bytes32)","430a74b7":"CrypcenToken()","430ab56a":"sendAllLocalEthers(address)","430ae7a2":"AvtcToken()","430bf08a":"vaultAddress()","430c2081":"isApprovedOrOwner(address,uint256)","430c2a69":"crdjetToken()","430c73c5":"setMarketAddress(address,address)","430ca46f":"finishAuction()","430d2803":"getTotalPossibleTokens()","430d6eb2":"ParadiseToken(address)","430de98a":"GetCardNumber(uint8,uint8)","430e484a":"setupNetwork()","430ecff8":"blksze()","430fe5f0":"changeWorkerPrice(uint256)","430fe9c1":"getDate()","4310033d":"Gotoken()","43102eab":"isItConstantinopleYet()","43104d92":"addMultipleRecordsStrict(uint256[])","43107290":"createRequest(address,address[],int256[],address,string)","43114842":"acceptChallenge(uint256,uint256,uint256)","4311de8f":"ownerWithdraw()","43128a4c":"feeUSD()","4312f19c":"setTransferEmittables(address,bool,bool)","4312fece":"addAddressToIndex(address,address)","43133b07":"gameBeginPlayNo()","4313b9e5":"setup(uint256)","4313de82":"closeBidOrder()","4314162d":"untsqm()","431454fb":"totalMintedBountyTokens()","43146f36":"resetBet()","431562b9":"countWithdraws()","43156db6":"withdrawOldToken(address,uint256)","4315f545":"proofType_NONE()","43160e3d":"rootOfTrust()","4316abbb":"newJester(address)","4316fae5":"NABC()","43171485":"tokensHasSoldOut()","4317f04a":"Transfer(address,string,address)","431851ad":"NenoToken()","431993b9":"endPrivate()","4319dfd9":"defence(address,uint256,uint16,bytes,uint256[])","431a4d46":"getContractSample(string)","431ab1f2":"xmasFundWallet()","431ab233":"allOperations(uint256)","431adcb1":"isSellOpen()","431bff74":"MINING_POOL_AMOUNT()","431cc3dd":"batchWithdraw(address[])","431d6256":"Conversion(address,address,address,uint256,uint256,uint256,uint256)","431dac16":"registerUser(address,string,uint256,uint256,uint256,string,bool)","431dbd9e":"getLatestRaffleInfo()","431dc4b6":"current_period()","431dc892":"OwnedProxy(address)","431e0a48":"AnteilToken()","431e83ce":"absMaxFee()","431ef9b5":"OptionsConversionOffered(address,address,uint32,uint32)","431f188c":"set_presale_arbits_per_ether(uint256)","431f21da":"createAuction(uint256,uint256,uint256,uint256)","431f63c9":"setTokenPrice(address,uint256)","4320ea1c":"CrowdsaleBase(uint256,uint256,uint256,address,address[])","43212413":"Addr2()","43212c3c":"getHighestMilesAt(uint256)","43214675":"setMintAgent(address,bool)","43216a11":"MAX_NUM_AVAIL()","43226631":"CURRENTLY_ISSUED()","4322b73b":"getAdd(uint256)","43235a24":"_transferProperty(uint16,address,uint256,uint256,uint8,address)","43243797":"fundsOf(address)","43245816":"tokensToEther_(uint256)","43245953":"CoinToken(uint256,string,uint8,string)","4324aa21":"classOf(uint256)","4324ae4f":"PhoenixExchangeDeposit()","4325f6bb":"OfferToCastle(uint256,uint256)","432607fc":"cancel(address,address,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","4326e22b":"getMerkleTreeRoot(bytes20,uint8)","4326f3f6":"setMinimumPriceCount(uint256)","4327115b":"_AddedToGeneration(address,uint256)","4327979a":"getPaymentParams(uint8)","4327acda":"addDeal(address,address,address,uint256,uint256,uint256,uint256,string,uint256)","4328894f":"showReportForMonth(uint16,uint8)","4329db46":"transferETH(uint256)","432a042b":"makeRegistration(bytes32)","432a3dfb":"roundState(uint256,uint256)","432a805b":"changeDailyRate(bytes32,uint256)","432a84d9":"ownerDepositInterest()","432a89aa":"GetBuildingParam(uint256)","432af6e9":"calculateTokensForMonth(address)","432b3f85":"fetchVoteResultForCandidateBySnapshotBlock(address,uint256)","432ba8be":"voterToBallotID(address)","432c4209":"IQT_DECIMALSFACTOR()","432c685f":"trustClient(address)","432ce549":"sendToUser(address,address,uint256)","432ced04":"reserve(bytes32)","432d7a1e":"_dividendsOutstanding(address)","432e83c5":"resetReferedCount(address)","432e8946":"disableTransfer(address)","432f0d20":"EVA(uint256)","432f3223":"AceFund()","432f3c22":"request_until()","43302ff3":"getMaintainFee()","4330301f":"_ratio()","4331576f":"BITVM()","4331e00f":"pay_claimed(address)","4331e8dd":"setLeader(address)","433288a2":"setCurrency(string,address,address,uint8,bool)","4334614a":"isBurner(address)","4334a8a5":"CHAD()","433503f6":"ChangeEmissionSumm(uint256)","4335b046":"CRAWDSALE_EARLYBIRD_END_DAY()","4335dfc0":"getPurchaseTimestamp()","43361a6e":"MineralBase()","4336a5a8":"EtherGold()","433740f8":"Purchase(address,uint256,uint32)","4337b391":"PriceDiscovery(address,address)","433836dc":"scheduleTransaction(address,bytes,uint8,uint256[3],uint256)","43386ea9":"getUniqueValue(uint256)","433900db":"presaleTokensLimit()","433914c9":"VeChainX()","43398685":"BancorFormula()","4339bc30":"changePool(address)","433a8323":"UnityCoin()","433adb05":"tokensReserved()","433b409f":"BTTSTokenListing(address,address,string,string,uint8,uint256,bool,bool)","433b64b1":"eventId(uint256)","433b77c7":"getCampaignOwnerById(bytes32)","433bb0e4":"fillOrder(address,address,address,bytes32,address,address,uint256)","433bd924":"getBreed(uint32)","433c39ff":"transferVoteController(address)","433cdc26":"PriceAdjusted(uint256,uint256)","433d0f33":"canUserCancelArtwork(address,address)","433d4aab":"resolve(uint8,uint8)","433d7110":"provas(address)","433e852d":"flushDividends(uint256)","433fc1da":"Bandit()","43406182":"enableLotteryGiveHunt()","43409bc5":"linkData(bytes)","4341274f":"_sameClassAxiesPrice(uint8,uint256)","4341aebc":"distributeTokensToRank(uint256[],uint256)","43428e45":"minimumNumberOfBlocksToEndGame()","4342e966":"approve(address,uint8)","4342ffe5":"changeMinimumContributionForPrivatePhase(uint256)","4343ede6":"currentStageNumber()","43441a2c":"totalGivenBountyTokens()","4344f73d":"AssToken()","4345c7c9":"_upgradeTo(string,address)","434622fe":"additionalMint()","43463b98":"getconf()","43463c3a":"UnityToken(uint256)","4346aa58":"ITTM()","4346ea77":"PrimasToken()","43471101":"getSenderFunds(address)","434786f4":"getBalacne()","434847e0":"withDrawFees()","4349168e":"GenesisSalesPriceCount()","434a55eb":"bonusFirstTwoDaysPeriod()","434afdfc":"totalObol()","434b1208":"rescueOrder(uint256)","434b14e7":"randomGen(uint256)","434b349c":"LCEToken()","434b635e":"getMaxBetAmount(uint256)","434c4498":"EthperPoe()","434cb64c":"startNextGeneration()","434d16f5":"rotate_left(uint32,uint32)","434d185c":"getKingdomOwner(string)","434df07e":"NewSerpent(uint256)","434e0618":"addMedicalProviderReply(address,string,string)","434e6a55":"addWebsite(address,string)","434ea7d3":"_lottery5(uint256,address,address)","434ec416":"EXT_COMPANY_STAKE_ONE()","434f5f27":"checked_in(address)","434f811b":"partIndexToApproved(uint256)","434fb2ae":"PRICE_MULTIPLIER_ICO3()","435010d8":"SrcToken()","43503fac":"getWord(uint256)","43509138":"div(int256,int256)","43516832":"getSuppliers()","43525d73":"MAX_FUNDING_SUPPLY()","435263ef":"ecosystemWallet()","4352e407":"RozetkaCoins()","4352fa9f":"setPrices(address[],uint256[])","4353401f":"NetkillerAdvancedTokenAirDrop(uint256,string,string,uint256)","43543242":"isSignatureOkay(address,bytes32,uint256[3])","4355644d":"addMonths(uint256,uint256)","43558826":"exchangequeue(address)","43559743":"edgePigment(uint8)","43562bd0":"NextRewardBonus()","4356f35b":"addIntermediary(address)","43574d9e":"owner2Of(uint256)","4357855e":"fulfill(bytes32,uint256)","43579fe8":"deleteShop()","4357b3de":"getCrowdsaleTier(address,bytes32,uint256)","4357da58":"pausePreSale()","4357e20f":"MinSlippageFactorSet(uint256,uint256,address)","4357e289":"Multiplexer(address,address[])","43581c80":"tdeFundsRaisedInWei()","4358630f":"Certificate(address,address,address,address,address)","4358c156":"isBonus()","43596b8b":"getLLV_edit_25()","435a0803":"testNowClock()","435a1220":"createERC20TokenNetwork(address,address)","435ad5c1":"getMixedStack(bytes32)","435adacc":"EtherrateUpd(uint256,uint256)","435ae547":"ResumeTokenAllOperation()","435afa54":"changeRepoSettings(uint256,uint8,uint8)","435bb6b9":"nextJackpotTime()","435c35b6":"startGeneralSale()","435ce40a":"isAccount(address,address)","435cebda":"createMember(address,address,bool,bool)","435cf753":"winCount(bytes32,address,address)","435dc3fb":"setGenesisAddress(address,address,uint256)","435e119e":"SetupRaffle(uint256)","435e33a5":"TokenRewardsAdded(address,uint256)","435f02f9":"ACIFToken()","435ffe94":"setHello(string)","4360617b":"Sell(bytes32,address,uint256,uint256,address,address)","4360f90f":"getOfferState(bytes)","436108ce":"changePasswd(bytes32,address,uint8,bytes32,bytes32)","4361443f":"getClaim(address,bytes32)","43614f8b":"endFinalStage1()","4361b3f9":"TokensCreated(address,uint256)","43620f24":"startWork(uint256,bytes32,bytes32)","43626c52":"AllInvestorsRefunded(uint256)","4362c088":"affiliateLevel()","4362c116":"transfert(address,uint256)","43634c39":"useSuperPowers()","436393ab":"AlrzshTest()","4363e888":"withdrawERC20Tokens(address,address,address,uint256)","43655fd3":"votesItem(address,uint8)","436577ae":"createIssuance(uint256,uint256,uint256,uint256,string,string,uint8,uint256)","4365e11e":"BingoLight()","43668efa":"ProposalAdd(uint256,address,string)","4366af55":"RTC(uint256,string,string)","43677ca7":"checkInternalBalance()","4367aa3c":"_isReserveUnlocked()","4368600c":"initDeposit()","436962b4":"_setTarget(address)","4369a2c2":"charityAmtToCharity(address)","4369c250":"rewardsFactor()","436a66e7":"length(string)","436a88c1":"DEV_FEE()","436b6158":"card2PowerConverter(uint256[])","436b8fa5":"Salman_nomaniTestCoin()","436d4ff5":"hash(string,address)","436d796c":"startPreIco(uint256)","436d8fd6":"setGameBanker(address)","436da5fe":"transferLog(uint256)","436e1e2e":"computeAirdrop(address)","436e388d":"enterWallet()","436ee4af":"SEEDS_TO_HATCH_1RICE()","436f64ac":"rInFp()","436fdc0e":"getBattleCardsInfo(uint256)","436fedc3":"getRegionUpdatedAt(uint256)","43700afe":"strConcat(string,string,string,string,string,string)","43703b0e":"getEventData(bytes)","437159de":"SYCPrivateEarlyPurchase()","4371c465":"isWeekEnd(uint256)","4371e46e":"blockCount(uint64)","43722993":"NPSTToken(address)","43722b09":"extOwner()","437257bd":"handlePointer(uint256,int256,uint256)","4372df99":"getNotaryForSeller(address)","4373f3b4":"setFunding(uint256,uint256,uint256,uint256,uint256,bool,uint256)","4374356b":"DRUGS_TO_PRODUCE_1KILO()","437583a9":"updateReserveToken()","4376890e":"egcToken()","437764df":"getBridgeMode()","43777117":"getMarketOptions()","4377cf65":"numberOfContributors()","4377d12c":"ChooseWHGReturnAddress(uint256)","437852b6":"getRefererAddress(bytes)","4378a6e3":"getAttributes(uint256)","437933cc":"setDataFeedHash(string)","437a8ae6":"multiple()","437b1a1d":"KITTY_BURN_LIMIT()","437c58a8":"YourtekToken()","437c9162":"pre_mined_supply()","437cfa4a":"setContractICOAddress(address)","437d07d5":"mktCoinCap()","437dbf49":"_isAuctionAble(uint256)","437f5b65":"isLUNVault()","437f6a4b":"userMakeOrder(address,address,uint256,uint256,address)","437fa667":"appAccountsLength()","4380ab6d":"clock(bytes32)","438195f9":"MAX_WHITELISTED_COUNT()","4381a07b":"setCustomDisputeFee(bytes32,uint256)","4381e1c5":"verificationAddressHoldersListNumberMap(address,uint256)","4383603b":"setAllowHalfLife(bool)","43846074":"getPreviousDarknodes(address,uint256)","43846fc8":"shortLock()","4384d53a":"BunnyCoin()","43859632":"hasVoted(uint256,address)","43863045":"addUintSetting(string,uint256,address,address,string)","438652e0":"addTransferWhiteList(address)","4386fe0d":"changeMinTokenSale(uint256)","43876776":"setPubKey(uint256,uint256)","4387d35a":"lockedWallet()","43886946":"getPlayerTeam(uint256)","43894ac3":"setMintMarketMakerApproval(address,address,address)","438af924":"buy(uint256,bool,uint256)","438b2aed":"setSettings(uint256,uint256,uint256)","438b7b99":"setProfitRatio(uint256)","438b9ff2":"payForUrl(address,string)","438c3585":"releaseTokensBlock()","438c3aff":"contractIds(uint256)","438c9068":"ownersProductCommissionInPerc()","438c9509":"test_invalidTokenFreeze()","438cd2d3":"UnPause()","438d1bd7":"storeBubbleSort(uint256[])","438d359e":"buyXname(bytes32)","438e1316":"next(uint80)","438e15fc":"contains(uint256,uint256)","438f1eee":"PowZoneToken()","4390921e":"distributeOne(address,uint256)","43909d76":"EthCannabis(address)","4390a4f8":"batchTransferToken(address,address,address,uint8,bytes32[])","439198af":"timeLeftToContestStart()","4392281e":"SCTX()","43923258":"addAddressToAccessControl(address,uint8)","43925cc3":"getRoomPlayers(uint256)","43927707":"NehalCoin()","43928cfd":"addClient(address)","439370b1":"depositEth()","4394cc96":"versionBase(bytes32,bytes32)","43951999":"getReportingWindowForForkEndTime()","4395dc06":"getTokenInfoTokenList()","43973140":"check_lock_period(address,address)","439766ce":"pauseContract()","43977911":"addFreezeList(address)","4398da85":"tokensPercentageForKeyHolder()","4398fbd6":"treeWater(uint256,uint256)","439abc5b":"getLockByIdx(address,address,uint32)","439b91c4":"addBlockeddUser(address)","439be05c":"getLoanFilledAmount(bytes32)","439d4265":"recordToTransfer(address,uint256,uint256)","439d7275":"issuerSymbol()","439e10e5":"createUniqueSpinner(string,address,uint256)","439e97c4":"alertCreators(uint256)","439f5ac2":"getEndTime()","439f7d3c":"getSponsor(uint32)","439fab91":"initialize(bytes)","43a085c2":"ProsperPresaleToken(address,string,string,uint256,uint8)","43a335d6":"CreditCarToken()","43a4344f":"calcNetworkFee(uint256)","43a44f1e":"bonusTimes(address)","43a468c8":"delegateBalanceOf(address)","43a47345":"floatHolder()","43a47ae2":"EthTermDeposits()","43a61a8e":"rootOwnerOf(uint256)","43a68f3a":"NegToken(uint256,string,uint8,string)","43a6e680":"DonationSentButNotDoubled(address,uint256)","43a77530":"serviceAgent()","43a78b50":"MyAddress()","43a7f749":"getInitialPriceOfToken(uint256)","43a8775a":"amountOfBagTypes()","43a886ea":"filterBrick(uint256,bytes32[],uint256,uint256,uint256)","43a88da6":"buyOpen()","43a8d9d5":"authorizeWithdrawal()","43a92f24":"getAvatarInfo(uint256)","43aa8784":"endedGameCount()","43ab599f":"EPSCoin()","43ab850b":"setDividends(uint32)","43abab26":"whitelist_addys(address[])","43acb067":"ChefICO()","43acd7bc":"Bailout()","43ae2695":"propertyToken()","43aefca0":"withdrawThetokens(address)","43af755a":"blockedDeadLine()","43b03d37":"i(address,address,uint256)","43b0e8df":"set(uint256,uint256,uint256)","43b114fd":"getMyCoins()","43b12e95":"BCEToken()","43b1938d":"getPhaseSale(uint256,uint256)","43b1c529":"getSig(string,bytes4)","43b25452":"createPortfolio(uint256)","43b3181c":"AIOS()","43b3769e":"checkStatus(address,uint256,string,address)","43b3aa46":"getTokenAmountOf(address)","43b50d8e":"evKickoff(address,uint256,uint256)","43b5126d":"getVendingPrice(uint256)","43b6c7d0":"setClaimedFlag(bool)","43b6caf3":"setMintPerBlock(uint256)","43b7d9c8":"ITToken()","43b7fd58":"RoomRoundAdd(uint8)","43b812ef":"r2VaultAddr()","43b89c62":"getTransactionAtIndex(address,uint256)","43b8aedf":"gimmeTendies(address,uint256)","43b978b3":"playerNames(address)","43ba2cf5":"transferPreSaleTokens(uint256,address)","43bb6a63":"getmemreqscount(uint256)","43bc1612":"artist()","43bc867e":"claimStupidFluffyPink(uint64)","43bcf52a":"bbdToken()","43bd262e":"injectAvatarService(address)","43bd6e6f":"changeColorYellow()","43bdaacb":"getPlayerInternalWallet()","43bddf40":"horses()","43bdfb72":"updatedTime()","43bf63e8":"priceInWeiEdition(uint256)","43bf718e":"getHashOfTheProposalDocument()","43bf74ef":"setKYC(address,uint256,uint8,uint256)","43bff765":"tokensPerMicroEther()","43c09e77":"updateNote(uint64,uint16,bytes12,bytes)","43c0d38c":"getSlotId(address,uint256)","43c14b22":"revokeVote()","43c1598d":"maxProfitDivisor()","43c1f0ed":"timeBeforeJackpot()","43c238db":"POMCOIN()","43c273c7":"DevSupply_Released()","43c29522":"PUBLICSALE_USD_PER_MSENC()","43c33ac9":"submitShares(uint256,uint256)","43c35651":"completeCrowdSale()","43c3658e":"EmporeumToken()","43c37393":"solveTask(uint256,uint256)","43c569f4":"TotalWin()","43c5d889":"locationOf(bytes,uint256)","43c639e7":"ownerResetLockedShares()","43c6b1f2":"_transferAsset(address,address,uint256)","43c6d558":"SportsBet(string,uint256)","43c6e10d":"getAffiliateCommision()","43c6eff1":"submitClaim(uint256,uint256,uint256,uint256,bool)","43c8124d":"PoolAdvisors()","43c885ba":"inited()","43c8c30e":"removeModeratorship()","43c9a189":"allocate1ProjectToken()","43ca46dd":"_ownsToken(address,uint256)","43ca57bc":"getRetailerStatus(address)","43ca78a2":"getNotaryInfo(address)","43ca86c6":"nukeApps()","43ca9d26":"onNewCampaign(uint256,address,uint256)","43cade1c":"reStartPreIco()","43caf0dc":"distroyToken(address)","43cb0af7":"getBytesArrayLength(bytes32)","43cb2b03":"getCurrentTokenCost()","43cb3189":"ETHZToken()","43cbbce6":"icoRound2()","43cc113b":"holdersBonus(address)","43cd1638":"deposit3()","43cd2c40":"UpdateForecast(bytes32,bytes32,bytes32,bytes12)","43cd5ea1":"sendBussinessByOwner(address,uint256)","43cd9655":"XBTexToken()","43cdaad2":"modelId()","43cdc49e":"unlockTokens(address,uint64)","43ce179e":"issueOwnerMore(uint256)","43ce7422":"getMyEggs()","43cf5f0c":"PunaniSupply()","43cfbd65":"getCompanyName()","43cfd44c":"recover_unclaimed_bets()","43cffefe":"challenge(bytes32,string)","43d018a0":"whitelistMaxTok(address)","43d0ee54":"userRounds(address)","43d111ae":"binScan(uint256,address)","43d1498b":"setCoAuthor(address)","43d1be7b":"setPresalePhase()","43d24a5e":"addUpdater(address)","43d32e9c":"getSellPrice()","43d3a4c1":"getTotalVoters(uint256)","43d42780":"icoSoldTokens()","43d4759f":"HuuuumanStandardToken(uint256,string,uint8,string)","43d47f82":"ProjectFund()","43d4b78b":"stateIsWaitingReplay(uint256)","43d5773b":"SpaceCraftCore()","43d64976":"OwnershipDeleted(address,address)","43d6add1":"accessoryOnLeaderboards(uint64)","43d6cac5":"removeTokenMetadata(uint256)","43d6ec16":"LIFEFORM()","43d6fab6":"RegularContract()","43d726d6":"close()","43d77c7b":"platContract()","43d7bfcb":"mintBountyTokens(address[],uint256)","43d7cce6":"getToken(address,uint256)","43d84d49":"updateCrowdsaleInfo(string)","43d8b570":"isTeamVestingInitiated()","43d9e070":"sencSold()","43db053e":"withdrawDevShare()","43db24ad":"EthereumWings()","43db5324":"ownerSetCanMining(bool)","43db7821":"BINKEY()","43dbb2de":"MAX_ETH_FUND()","43dc3ab2":"register(address[])","43dc7233":"getTokenCreationRate()","43dcbc86":"hasNotaryBeenAdded(address)","43dd8b30":"updateWhitelistMapping(address[],address,bool)","43ddc1b0":"callETH(address)","43de34dc":"impl_cancelRedeem(address,uint256)","43de6f90":"createHero(string,uint16,uint16)","43de82f3":"revealVote(uint256,uint8,bytes32,bytes32,uint32,bytes32)","43deb064":"LemonSelfDrop()","43deb8e5":"START_SKO1_UNITS()","43ded8e3":"MyGlobeToken(uint256,string,string)","43defc10":"getVendorByAddress(address)","43defdac":"AudtStandardToken(uint256,string,uint8,string)","43e08ad1":"addHash(bytes32)","43e09695":"deactivatePass(bytes32)","43e0c65a":"allowToBurn(address)","43e0dfdd":"Leverage()","43e1b94f":"AnyName()","43e1eb82":"setSiftContractAddress(address)","43e204b3":"isTokenLock(address,address)","43e20f97":"getPoolbyGtype(int8)","43e271ad":"woodworksCities(uint256)","43e2e504":"GetBalance(address)","43e332c5":"Last_block_number_and_blockhash_used()","43e3e527":"Weko()","43e41c44":"Kotlind()","43e4cef1":"processPrivatePurchase(uint256,address)","43e6125d":"Badge(address)","43e6cc40":"issueTokens(uint256[])","43e6cc64":"StopToken()","43e72c5a":"totalPotHomeTeam()","43e74f46":"sendPrepaidEthTweet(uint256,string,string,string)","43e76a26":"SellerRequestedCancel(bytes32)","43e7aa1d":"commitPhaseLength()","43e91384":"setICOEndDate(uint256)","43e92866":"reservingPercentage()","43ea0313":"setRitualFee(uint256)","43ea8d7b":"newWithdraWallet(address)","43eb37e2":"initChargeJNT(address,string)","43eb5ac7":"getData_21()","43ec31e2":"TdToken(address)","43ec3f38":"toSliceB32(bytes32)","43ed2863":"StandardToken(string,string,uint8)","43ee67cf":"_transferFallback(address,uint256,bytes)","43f0179b":"takerFee()","43f29372":"redeemWinningTokens()","43f294a6":"setCrowdsaleStop()","43f3d27c":"setPrPercent(uint256)","43f415d0":"executeDecayFunction(uint256,int256,int256,uint256,uint256)","43f46a5c":"getPolicyState(uint256)","43f48fbd":"rates()","43f4cb4b":"GetCurrentTypeDuration(uint256)","43f58f9f":"createNetwork(string,uint256,uint256,uint256,uint256)","43f6c643":"purchaseRequest(uint256)","43f6c741":"HGToken()","43f70917":"create(address,address,address,address,address,address)","43f70f60":"dna5(uint256)","43f73a3d":"UpdateCurrency(uint256,string,string,string,string)","43f76b98":"generateLuckyNumbers(uint256)","43f8c639":"tickets100kprice()","43f97628":"EcosystemFund()","43f98345":"calculateAllReclaimedNow()","43f98a56":"tradingDate()","43f99e68":"refundExternalPurchase(address,uint256,uint256)","43fb86d2":"getGameLength()","43fce818":"createAngelCardSeries(uint8,uint256,uint64,uint8,uint16,uint64)","43fd377a":"ChannelNew(address,address,address,address,uint256,uint256,uint256)","43fd6b21":"revokeStackholderConfirmation(uint256)","43fe32fc":"activateProvider(address)","43fedd01":"setDisputeData(uint256[3])","44004cc1":"withdrawERC20(address,address,uint256)","44013585":"setPaymentTime(address,uint256)","44017cd6":"test_BondPostedButNoMajority()","44019db3":"testCreateWithParents()","4401a6e4":"safeSend(address)","4401c905":"INTREPID_PRICE_THRESHOLD()","4401ff5c":"sellShares(bytes,uint8,uint256,uint256)","440208c3":"right12(uint256)","440235c0":"changeTrade(address,address)","44030e71":"getIsBlockRevenueCalculated(uint256)","44036b6f":"setFeePercentTenths(uint256)","44036c41":"getTrustedTransferDestinationValue()","4403e2ab":"nextLotteryTTWTokenId3()","4403ee2b":"setIFS(address,uint256)","44048aa5":"getContributorUSD(address)","440574eb":"adminUpdatePayout(uint256,uint256,uint256,bool)","4406face":"lock(string,string)","4406fbab":"NectarCrowdsale(uint256,uint256,uint256,address,address)","44074cc7":"MaxCoin()","4407a75d":"BasicCrowdsale(address,address,address,string,string,address,uint256,uint256)","440878c4":"store(bytes,address,uint256,uint8)","4408c38a":"HIKEN(uint256,string,uint8,string)","4408f3f9":"place_bet(uint8)","44090448":"to(bytes32,uint256)","440961c3":"adjustPointsDecayFactor(uint256)","44097d70":"costWei()","440991bd":"freezeDuration()","440a16c4":"SEC(uint256,string,string)","440a7a0c":"unblockFirstStake()","440a926a":"home(uint256)","440adb38":"BullsFundToken()","440d2437":"designatedReport()","440d2ad0":"PRICELESS()","440f19ba":"draw(bytes32,uint256)","440f807e":"loadMesa(bytes32,bytes32[],uint8[])","4410121f":"test_voteSpammingFor()","441156cf":"Plutaneum()","4411b8f8":"disputeFavor()","4411c36f":"avgTokenlossValue()","441230e4":"registerHandle(bytes32,bytes32,address)","4412e104":"getZombiesByOwner(address)","4413a688":"setPreallocations()","4414356b":"sale3Accepting()","44146c26":"setExpectedTimes(uint256,uint256)","441478c3":"prepareToRewardProcess()","4414a5c8":"totalLose()","4414d940":"napkinPrice()","4415516b":"getType(uint16)","4415a0bf":"preSaleDiscountPrice()","441628f1":"sendTokensToBountyWallet(address)","441666c5":"SimpleContract()","441691f2":"LexitToken()","44169752":"WALLET_ADDR()","4417bc66":"VESTED_TEAM_ADVISORS_SHARE()","4417f4db":"burnOWL(address,uint256)","44187d45":"HerdiusToken()","44188b72":"openPreICOPublic()","44191d9d":"TokensCreated(address,address,uint256)","44195fd2":"ApolloSeptemFinalized()","4419cd81":"isContractNodeOwner()","4419da33":"changeInvestorAddress(address,address)","4419f969":"QuaLed()","441a174c":"multiCallTightlyPacked(bytes32[],address)","441a2ee3":"Mangocoin()","441a3e70":"withdraw(uint256,uint256)","441b09d9":"allShares()","441b1b44":"getPartialValue(uint256,uint256,uint256)","441b4f01":"investContractDeposited()","441c3499":"getRefers()","441c77c0":"revealPeriodActive(uint256)","441d6a61":"timeWait()","441deede":"getSafeContract(address)","441e354c":"_checkoutCost()","441ea478":"GetLandId(uint256)","442085b2":"contributorCap(address)","4420e486":"register(address)","44210bbd":"claimPlotWithData(uint256,uint256,string,string,string,string)","44219b05":"getGamePlayingStatus()","442484ff":"ExtTokenPurchase(address,address,uint256)","44249f04":"tokensForCharity()","4425c0eb":"claimWhitelistPack(bool)","4425d66d":"backup_exchangeEthStb(uint256,uint256)","44261964":"claimFullPrize(address)","44268655":"addCroupier(address)","4426cdc9":"changeEtherContract(address)","44276733":"getRole(address)","442890d5":"getContractOwner()","4428b072":"getReply(bytes32,uint256,uint256)","44292e88":"setZRXToken(address)","442a494f":"NewRegistrar(address)","442b7ffb":"pow2(uint256)","442b8c79":"addYears(uint256,uint256)","442bc74f":"placeQuestion(uint256,uint8,uint256,string)","442cbcb3":"addParticipant(address,uint8)","442cf0ee":"sellTokensForLtc(string,address,uint256,uint256)","442d0927":"isSellPossible()","442d1759":"GIRLToken()","442d27dc":"getLoanTuple(uint256)","442d31ca":"ChefToken()","442dfae2":"mktSupply()","442e1079":"MIN_ICO_GOAL()","442e501d":"createDeposit(address,uint256)","442eb683":"YouthToken()","442edd03":"listItem(uint256,uint256,address)","442efdc1":"MigrateController(address)","442f52ab":"bilateralCancel(address,address,address,address,bytes32)","44304edf":"TGCTokenBase(uint256,string,string,uint8)","44314116":"totalRollsByUser()","44326354":"pauseITO()","4432ce5f":"setTradersProxyContract(address)","44337ea1":"addToBlacklist(address)","4433a440":"ADXSold()","44346e3b":"cancelOngoingTxByAdmin(bytes32)","44348a78":"referralIndex(uint256)","44350d5f":"neo()","4435947c":"CoinyMcCoinface(uint256,string,uint8,string)","4435f1c3":"SlashToken()","4437152a":"setPool(address)","44377ebb":"getTokenAmount(uint256,uint8)","4437e7a0":"FlogmallAirdropper(address,uint256)","4438744b":"unlockGrant()","44389678":"isAcceptedExportingAuthority(address)","4438c8ab":"ExchangeRate()","4438cf6f":"burnRestTokens()","4438d222":"userHasKYC(address)","4439ab32":"addRecordEntry(address)","4439defa":"getNonce(bytes32[])","443ace5b":"InitiateWhaleCard()","443af072":"percentToPresalersFromICO()","443afe2b":"bssTotalSuply()","443b22e6":"ActiveSalesPhase()","443bd56f":"getHandleOwner(bytes32)","443bdc43":"setStepOneRate(uint256)","443d4c9c":"sendPayout()","443d8967":"batchWithdraw(uint128[],address[],uint256[],uint128[])","443de10c":"getCurrentStaked(address)","443e1cf7":"isFightClockAuction()","443f19f4":"numberOfTokens(uint256,uint256)","443f41d5":"tokenDeposit(address,uint256)","443f45a4":"awardprize(uint256)","443f577e":"getTotalBalance(bytes4)","443f95dc":"allStart()","444115f6":"acceptOffer(uint256,string)","444195a3":"partnersFundAddress()","4441bbd9":"schemaRegistry()","444257a3":"_includes(string[3],string)","4442bf02":"closeArea(uint256)","444316e8":"MiniMeToken(address,uint256,string,uint8,string)","44431e52":"minOVC()","44440a59":"isDistributionReady()","44447f47":"lockTokenSupply()","4444c51f":"_recalculateTopQuestionsOnVote(uint256,uint256,uint256)","4444e3cd":"totalSupply(address,bytes32)","444581da":"createCloneToken(string,uint8,string,uint256,bool,address)","4445b569":"voteWeightOf(uint256,uint256)","4446bb11":"verify_signature(bytes32,uint8,bytes32,bytes32,address)","4446c98c":"foundersFundTimelock1Address()","4447e48c":"configureKeys(uint32,bytes32,bytes32,uint32,bool)","44482ab8":"w0keAFPresaleAddress()","4448604b":"testFailPreDistribute()","4448f5fb":"getEscapeRequestsCount(uint32)","4449307b":"addKycAddress(address,bool)","44495d7e":"migrateGold(string)","444b0c90":"bonusThirdWeekPeriod()","444b6048":"setMerchantDealsHistory(address)","444bb28d":"TownCrier()","444c3d9a":"isCompetitionActive()","444c8daf":"tipoCongelamento()","444cef88":"sentToken()","444d95b0":"proofs(bytes32)","444da733":"isRoundEnd()","444da951":"extractWei(uint256)","444dd6f3":"Elcoin()","444e8b43":"pubkeys1(uint256)","444e984b":"triggerAttack(uint32)","444fda82":"subYears(uint256,uint256)","44501404":"goldPrice()","445045cc":"_bid(uint256,uint256,address)","4451967c":"FOUNDATION_POOL_ADDR()","4451cfd9":"DeductFees(address,uint256)","4451d89f":"claimToken()","44525ace":"roundLatLng(uint8,int256)","445264db":"adventurePresale()","44536d27":"Create_AutoGame(uint256)","44539c72":"setManyWhitelist(address[],bool)","44540e57":"ownerBurnOccurred()","44554cef":"getRedbulls()","44558192":"FMT_Crowdsale()","44559f80":"start_token_time()","44566fe0":"HumanStandardToken()","4456eda2":"isOperator()","44578558":"addPlayerMapping(string,string,uint256,uint256,uint256)","4457ce5b":"CCH_LLV_303()","4457d5f0":"createProject(string,string,uint256,address)","44587e3e":"_setNumber(uint256)","4458ddca":"ChristCoin()","44598c11":"hasOfferingStarted()","445a7a23":"isOracleProxy()","445b8477":"transferAuditor(address)","445cb2df":"getVoting(bytes32)","445d1397":"maxTransfers()","445d1eff":"_getMyDividents(bool)","445d60d3":"placeBuyRequest(uint256,uint256,uint256)","445d688b":"COTTToken()","445d9936":"setTempHeroPower()","445df0ac":"last_completed_migration()","445df9d6":"getAllPrices()","445e4979":"_rejectCertificate(uint256,bool)","445f153a":"showBlockmaticsCertificate()","44602a7d":"testFallbackReturn()","44605ea0":"phase_1_remaining_tokens()","4460fb6d":"burn(address,bytes32,uint256)","4461550b":"devETHDestination()","44621145":"goodsOK(uint256)","446294ad":"multiAccessGetOwners()","446298e2":"Rubid()","446303f3":"preSaleCap()","4464aec7":"testTryGet()","4464c35e":"GNTAllocation(address)","4465e38c":"EligmaTokenContract()","4466862a":"randomtest()","44669e40":"purgeVoter(address,uint256)","44673b2d":"NextOwner()","44691f2b":"Dispute()","44691f7e":"hasStarted()","4469981f":"arrayInfoForDeposit(uint256)","446a7974":"Fokitol()","446b512e":"orderedTokens(address)","446bffba":"add(bytes32)","446c0955":"addWifi(string,string)","446d5aa4":"getAttributes(address)","446da9c2":"xper()","446dba8f":"getBonus(uint256,address)","446dde9b":"MilestoneCashBackTime()","446e0b40":"onSubExecuted(uint256)","446e5079":"SendDividend(address,uint256,uint256)","446f608c":"EscrowEscalation(uint256,uint256,address)","446f6c1f":"sellStorj(uint256)","446fbcd1":"CredSign()","446fcf22":"refundPlayer(address)","44708f7d":"change_time_stamp_status(uint256,uint256,string)","4470da90":"register(bytes32,bytes32,address,bytes32,bytes32)","44710181":"parseChannelCompatible(bytes)","44720ed5":"TigerCash()","4472287e":"numDistributions()","4472d3bc":"getShopOwnerAllProductList(string)","447400bf":"mutate(uint256,uint256)","4474809f":"tournamentEndBlock()","4474e057":"ICOSwapRate()","44751760":"read(bytes,uint256)","44751e3c":"starCoinAddress()","447615df":"Whitelist(address,uint256)","44767548":"rectangle(uint256,uint256)","4476d66a":"mintedInBlock(uint256)","4476e9a9":"epcwallet(address)","44772899":"round6StartTime()","44773a6c":"sendToMultipleAccount(address[],uint256[])","4477c5da":"stopFunding()","44781a00":"notEqual(bool,bool,string)","447843cf":"approveChild(address,address)","447885f0":"get(bytes32,address,address)","4478fbb2":"chOwner(address,bool)","44795c13":"RecoverySha256(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","447a64c4":"usdContribution(address,uint256)","447cd682":"scheduleTransaction(address,uint256)","447d7a1d":"_toLower(string)","447e2dc6":"c(address,address)","447e52a0":"answerQuestion(uint256,string)","447e6967":"endPublicSaleStage()","447ee48f":"maxUserCreatedPerformance()","447fa561":"CAST()","447fa8b7":"setDex(address)","447fbbe3":"manualSendEther(address,address,uint256)","447ffa91":"MineCooldown(uint256)","44804664":"OriginSportToken(address)","44816e2d":"readhistoricalrounds()","4481a486":"transferECOMTokenToContract(uint256)","448246c3":"updateReferralMasks(uint256)","44830788":"estimateTokensWithActualPayment(uint256)","44831edf":"developmentTeamTokensMinted()","44834aca":"buyerAddress()","44845c28":"MediaCash()","4484780b":"checkRecentInvestment(address)","4484a2a6":"forceBuyback(address,uint256)","4484d92b":"getTotalCommission(uint32)","4485cece":"EndTimeChanged(uint256)","4485d32c":"storePortfolio(uint256,uint256[],uint256[],uint256[])","4486598e":"zeeshanabbc()","44866955":"champion()","4487b392":"removeVerified(address)","448883d7":"claimTax()","4488ca9b":"hasApproval(address,address)","4488cc43":"_addExcluded(address)","44890014":"setFxBpsRate(string,uint256,string)","4489b2ec":"getABaddressByIndex(uint256)","448a064f":"YunMint(address)","448a0ceb":"setRoughSupply(uint256)","448a5e11":"mintForDisputeCrowdsourcer(int256,uint256)","448a5f0b":"getTestimonialCount()","448a627c":"SetConfirmRound(bytes32,uint8,bool)","448a9915":"oneBillion()","448b1f29":"tokensForTrivial()","448c0341":"FXRATE()","448c6656":"nodePhases()","448d76a3":"grantReserveSupply()","448d8910":"solve(int8)","448f1ec1":"tranferPresaleTokens(address,uint256)","448f30a3":"nothing()","448f8c86":"Acentiex()","44909c99":"Doftcoin()","4490efe3":"EthernetCashWebsite()","449106ac":"stageCap()","4491fe8f":"onlyPay()","44938e94":"checkPartner(address,address)","4493b8a4":"addrDevTeam()","4493ff1c":"vestedBalanceOf(address,address)","44947b9d":"getOutcomeOfSecondPeriodByEntity(uint256)","4494fd9f":"getGame()","4495147b":"RtcCoin(uint256)","4495bbf7":"DOXYCOIN()","44964dcb":"theList()","4496a7ea":"_getCurrentRoundInfo()","4497ce22":"getLicenseReimbursement(address)","4498acba":"provenAddress(address,bool)","44997a58":"MinusToken()","4499af81":"setChainLedger(address)","4499e043":"UNSOLD_ALLOCATION_EXPONENT()","449a058d":"getParentsLength()","449a09a4":"interfaceAddr(address,string)","449a52f8":"mintTo(address,uint256)","449c198d":"setSealed()","449c7ad3":"withdrawHouseCutFromGame(uint256)","449d0eb1":"checkAccountSchedule(address)","449d0f29":"disavowCrowdsourcers()","449d1ba4":"fundBountyAndTeam()","449d2712":"LEF()","449daa9a":"setCostPerEnergy(uint256)","449de356":"isIncluded(uint256)","449e815d":"getPrice(address,uint256)","449ed7e0":"callback(bytes32,string)","44a08b36":"checkAccess(string,address)","44a0d68a":"setCost(uint256)","44a17516":"Configurable()","44a2542a":"initiateRefund(bytes32)","44a2d0d2":"contributorsKeys(uint256)","44a3982d":"getTokenPriceForPeriod(uint256)","44a3bb82":"getGameIndex()","44a5450f":"PRESALE_WALLET()","44a5b69c":"Reederem(uint256)","44a60878":"DCXToken(string,string,uint256,string)","44a6a8f0":"getDonationLength()","44a71bc6":"fundingMaxCapInWei()","44a7a992":"ParametersChanged(uint256,uint256,uint256)","44a926f9":"assigned_shares()","44a9ff76":"getLastHatchPrice(address)","44aa470a":"addressVerified(address,string)","44aa5782":"LagToken()","44aa768f":"getLLV_edit_26()","44aa8b0e":"createAgreement(string,string,uint8,uint256,uint256,uint256,address,address,uint256)","44ab1c2f":"calcHouseEdge(uint256)","44ab6970":"redeemBool()","44ab6efa":"comB_()","44abc212":"adminWithdrawEIP777(address,uint256,address,address,bool,uint256,uint8,bytes32,bytes32,uint256)","44abd790":"makePlant(uint256,uint256)","44ac423a":"Collect(uint256,uint256)","44ac9d81":"resumePreSale()","44acb8da":"crowdsaleTokenSupply()","44ace7c3":"Tribe(address,string,string,address)","44ad5535":"ProofOfContractSnipers()","44ae0567":"advisorsReleased()","44ae2c03":"getAppNickname()","44ae58f6":"Bittrees(uint256,string,string)","44af11a3":"startBuyBackOne()","44af18c2":"goolaTeamAddress()","44af1f4b":"replaceOfficials(address[])","44af24d6":"getCurrentPercentage(address)","44af946f":"calculateEndTime()","44afda9c":"_isValidBaseLayersOnly(uint256[],uint256)","44b0245d":"addPurchased(uint256,uint256,uint256)","44b07838":"setPaidPackage(uint256,uint256,uint256,uint256)","44b07a3e":"newProposal(uint256,string,bytes32)","44b11f26":"Registry(bytes32,uint16)","44b1231f":"vestedAmount()","44b1d6e3":"DEXLITE()","44b1e09d":"checkTargetReached()","44b1e61a":"isFirstInit()","44b20e7a":"drawNum_()","44b28d59":"enableMint()","44b2a172":"cards_metal(uint256)","44b49958":"presaleEtherRaised()","44b4d279":"payoutDividends()","44b55187":"DollarToken()","44b55c3a":"setParking(uint32)","44b70d79":"LiquidityNetwork()","44b76b9e":"ICOTimer()","44b77680":"init(address,address,uint256[])","44b786a1":"setRate_BTCUSD(uint256)","44b7a3b7":"_createScrapPartAuction(uint256)","44b8074c":"changeTotalAmount()","44b81854":"STSTEST1()","44b81a77":"BitcoinToken()","44b88a6d":"scannedBronzeCaps()","44b8ccda":"EthLongExercised(address[2],uint256[8],uint256)","44b9cab5":"roundBlockCount_()","44b9efb2":"setInputData(uint256,uint256,uint256)","44ba16a2":"COLOR_PINK()","44bb3b2f":"stopBlock()","44bb60cf":"sigDestinationApprove()","44bc3e27":"BetWEA(address,uint256)","44bd7186":"GestiToken()","44bd7b71":"setBountyPercent(uint256)","44bec848":"thirdRoundPercent()","44bee639":"distributeSupply(address,uint256)","44bfa56e":"getBytesValue(bytes32)","44c010c6":"_getReferralBonus(uint256)","44c040a6":"MyAdvancedToken(uint256,string,string,address)","44c11fe4":"currentTransferableTokens(address)","44c18aa7":"setPayout(uint256)","44c20957":"setPhase(uint8,uint256,uint256,uint256)","44c20e6f":"retrieveExcessEther()","44c2dd71":"HSCToken(uint256,string,string,address)","44c3cb29":"validPlayer(uint256,address)","44c3cc68":"BasePoll(address,address,uint256,uint256,bool)","44c47561":"whiteListed()","44c4bf10":"setBlacklist(bool)","44c4dc31":"totalContributedAmount()","44c4dcc1":"purchasedAmount(address)","44c526c1":"devRewardClaimed()","44c55801":"setVaribles(string,string,uint256)","44c5bbf8":"updateStatus(address,uint8)","44c5e758":"getCustomerPolicyCount(address)","44c63eec":"vesting()","44c71ef2":"changeSaleSettings(address,address,uint256,uint256,uint256)","44c73459":"weiPerBlock()","44c7d6ef":"claimStake(uint256)","44c9716a":"BVA()","44c9af28":"getState(uint256)","44c9e83d":"purchaseAuthorizer()","44ca361f":"Log1(string,uint256)","44caa8d6":"isArrAccountIsFrozen(address)","44cb1c33":"lastTokens(address)","44cc129e":"count_bytes(uint256)","44cc5f7e":"m_externalMintingEnabled()","44cc7f5e":"validWithdrawToken(address,address,uint256)","44ccbed0":"getAssetCollectedOreBallances(uint256)","44cef69b":"CreateTokenToOperation(address,uint256)","44cf262a":"addressChangeBlock(address)","44cff104":"setMarketManagerAddress(address,address)","44d02c2a":"infoICO()","44d03ac6":"BlockhashFetch(address)","44d0afbc":"signingLogic()","44d15446":"setDevelopmentAuditPromotionTokensPercent(uint256)","44d19d2b":"reservedSupply()","44d1a074":"marketsubscribers()","44d1a9ae":"setCardDrawPrice(uint256)","44d345f9":"UnclaimedRewardTransfer(uint256,uint256)","44d4fd19":"Now()","44d60e67":"TransferAssets(address,uint256,address)","44d6d259":"AdminAdded(address)","44d75fa9":"updateMinorTree(bytes32)","44d7e4ed":"stopIssuing()","44d9bc5f":"gameEndTime()","44daf94a":"showEthBalance()","44dbb571":"SALE_START_TIME()","44dbc282":"processCallback(bool,address,address,uint256)","44dc028d":"lockedtokensOf(address)","44dc4dec":"registerForRace(uint256)","44dd4b3b":"lookupGeneration(uint256)","44dd4b5e":"scheduleTransaction(address,uint256,bytes)","44dedf4d":"returnFundsForUsers(address[])","44defdfd":"paidInstallments()","44df8e70":"burn()","44dfdce0":"getNameOwner(bytes)","44e02dbc":"returnCollateral(uint256)","44e14e59":"lockReferralTokens(uint256,address,uint256)","44e191fa":"increaseApproveAndCall(address,uint256,bytes)","44e2024f":"createNewFreelanceContract(string)","44e20fd2":"EasyPocketCoin(uint256,string,uint8,string)","44e2651c":"whiteListOf(address)","44e2adeb":"claimedFlag()","44e2cc24":"JackpotTimer()","44e2f9ad":"buyerInfoOf(address)","44e43cb8":"depositRevenue()","44e44e0d":"Profeee()","44e4c366":"rmTrusted(address)","44e4d226":"alreadyVoted(string)","44e52420":"TRADERSCOIN()","44e5d154":"GenesisGlobalTestToken()","44e63717":"LaboToken()","44e66ee2":"updateMeterValue(uint256,uint8,uint256)","44e780b7":"PrepareRollEvent(address,uint256,uint256,uint256)","44e78d93":"wipeDAI(uint256,uint256)","44e796de":"doubleBonusArray(address[])","44e7faa4":"limitedWalletsManager()","44e86b2f":"left71(uint256)","44e880c1":"gasAfter_()","44ea4a7c":"TokenCreated(uint8,uint8)","44ea54fe":"changeSoundcoinsContract(address)","44ec1a0d":"getContestStatusForDateAdmin(uint32)","44ec2c03":"addTransaction(uint256,uint256,uint256,uint16,bytes32,uint256)","44eccf16":"PSTBCoin()","44ed9039":"FLTTToken()","44edf6b2":"preIcoEndDate()","44ee398b":"secondThawDate()","44ee3a1c":"extendLock(uint256)","44eef96c":"sellShip(uint32,uint256,uint256,uint256)","44ef231b":"argumentCount()","44f04404":"forging(uint256,uint256)","44f06bc7":"getChampStats(uint256)","44f09d2a":"createDungeon(uint256,uint256,address)","44f0a4a8":"tdeStartTime()","44f0c3ce":"totalLost(address)","44f11e7e":"tokenBoughtPerTime(uint256)","44f1bbad":"giftRatioOf(address)","44f1beed":"Marble()","44f1ee5b":"Proof(address)","44f2428a":"adjustL(uint256)","44f252a0":"confiscate(address)","44f26d89":"forceUnstake(address)","44f27e30":"getAuctionData(uint256)","44f34576":"setTokensBought(uint256)","44f38756":"icoState()","44f396fa":"startStage2()","44f39803":"setBubbled(address)","44f5e447":"operatorFeeAcct()","44f6d70c":"giftOwnerByIndex(address,uint256)","44f7335b":"_verifyAvailability(uint256)","44f75cbd":"isAffiliate()","44f7636c":"publicOfferingWallet()","44f7787f":"ln(uint256,uint256)","44f7d03d":"valueOf(uint8,bool)","44f84579":"JP_winner()","44f96b36":"getRemainingPartnerTokensAllocation()","44f96bc6":"matured_timestamp()","44f977de":"setStore(string,address,uint256)","44f9ac5c":"getPendingWithdrawals(uint256)","44f9d060":"_getMinimum(bytes32)","44fa961d":"deleteLawyer(address)","44fa9ca6":"oracleIsUpdating()","44faa139":"Withdraw(uint32)","44fb5a1a":"Category(string)","44fbaf08":"bountyAmountLeft()","44fbc1ef":"Dollar()","44fbe5f5":"NewBiggestDick(string,string,uint256)","44fc2a9b":"NOLLYCOINCrowdFund()","44fc364c":"setMarket3(address)","44fc709e":"set_property_facility(uint256,bool,bool,string)","44fc83dd":"LogTokenReward(address,uint256)","44fc9361":"maximumInvestmentInWei()","44fcbd79":"getLocksForAddress(address,uint256)","44fd1557":"ERC20Token(string)","44fd584d":"cancelLeaseOffer(uint8)","44fdbf5b":"releaseAllTokens()","44fddeb7":"BLOCKAPPS()","44fe2eb0":"totalPaidDividends()","44fe7cd5":"Eliminated(address)","44ff5a3e":"CWC_Address()","44fff35c":"openCrowdfund()","4500054f":"isCancellable()","45004310":"signUpUser(string)","4500e64f":"showLockValues(address,address)","4504169a":"_createFlower(uint256,uint256,uint256,uint256,address)","45044611":"TimeCapsule()","45048ced":"Presale(uint256,uint256,uint256,uint256,address)","450531e7":"aidPoolTokens()","4505d53f":"unclaimedPoolsPresent()","45061bf8":"tsc()","4506e64d":"putOn(uint256,uint256)","45078531":"PRESALE_LEVEL_5()","4507a545":"shouldBeTrusted(address,address)","4507fccf":"addDeal(uint256,bytes32,bytes32,uint256,bytes32,bytes32)","45083f73":"appendTranch(uint256,uint256)","4509052f":"scannedCaps()","4509fd81":"partnersPercent()","450a03dd":"getKunsNum()","450a9105":"setYctContractAddress(address)","450b6079":"RetRisk(uint128)","450c4b7b":"LogTokensBought(address,uint256,uint256,uint256,uint256)","450c99d3":"etherRealID(address,address,string,string,bool)","450cabcb":"publicGetExchangeRate()","450d94ef":"TransactionConfirmedAfterEscalation(uint256)","450db8da":"ContractUpgrade(address)","450dccf6":"cancelOrderWithMerchantByAdmin(string,address)","450e2ed3":"startNextCycle()","450eefae":"execute(address,uint256,string)","450efe21":"getTokens(address)","45102ca7":"generateCarId(uint256)","451048e2":"isALCDistributed()","45104b16":"EXECUTION_GAS_OVERHEAD()","45115a17":"PUBG()","4511cc7d":"Transfer_nodata_enabled()","45126711":"createRandomNumber(string)","4512b39b":"sendAndFreeze(address,uint256,uint64)","4513a44e":"Saturn()","4513a7f4":"IsTransferTempFromOldContractDone()","451450ec":"upgrade(uint256,uint256)","45145281":"CurrencyFactory(address,address)","451512ed":"forceDispute(uint256)","451515db":"addProduct(uint256,uint256,bytes32,address)","45152b14":"makeUnicTaskHashId(address)","45164b3e":"TRANSFER_PROXY_VEFX()","451659d9":"exchange(uint256,bytes8,bytes8)","45166351":"FRB()","4516b707":"DCOIN()","45176f8d":"CloutToken(uint256,address)","4517a273":"releasePremine()","4517bd42":"RetractRoutingDR(bytes32,bytes32,uint256,bytes)","4518982c":"firstBonusTokensLimit()","45190584":"remainPantry()","45199e0a":"getPendingList()","4519a069":"toUint32(bytes,bytes,uint256)","4519c454":"tokenFallbackExpanded(address,uint256,bytes,address)","4519ef8e":"getMinutes(address,address)","451b5f47":"preMaxContribution()","451bd752":"currentUniqueSpinnerPrice()","451bedb3":"getSettingsChangeConfirmationCount(uint256)","451beefc":"addressToSplittersCreated(address,uint256)","451c3d80":"acceptedToken()","451cd22d":"clnAddress()","451d65d3":"Debug(uint256,address,string)","451df00f":"SongTokenRemoved(address,bool)","451e3ec5":"_createName(bytes32,address)","451e422e":"windowPeriod()","451f0601":"advisersPartners()","451f7763":"admin_set_payable(bool)","451febcc":"equal(bytes32[],bytes32[],string)","452030c4":"end_PRIVATESALE()","4520d416":"getReserveminted()","45232370":"fechVoteMainInfo()","45239b90":"setBeneficiary()","4523be0d":"Daily()","4524c70b":"addEmployee(address,bytes32,bytes32,uint256,uint256)","4525f804":"constructor(address,address)","45261106":"maxBetsPerBlock()","4526196e":"addressB()","45262b05":"setDefaultExecuteTime(uint256)","45266d7e":"BrandAdded(address,address,string,bool)","452757f6":"changeContainer(address)","452766a5":"EGGS_TO_HATCH_1Cat()","45278394":"updateDemurrageReporter()","45279c81":"effectiveMaxBet()","4527b4b6":"HGUATToken()","4528f3ec":"lastPurchase()","45293f0e":"Luckybuy()","4529cae7":"getTotalPlayers()","4529cd71":"SOFT_CAP_IN_ETHER()","4529cd8a":"AdvertisementStorage()","452a33f0":"grantTrophy(address,bytes32)","452a344f":"MintStarted()","452ae331":"attack(address,uint256,uint256)","452af6c6":"ForegroundPaymentResult(bool,uint256,address,uint256)","452b7757":"AirDropPayBitsR3(address[])","452ccadb":"changeBountyFulfillmentAmount(uint256,uint256)","452d44dc":"checkBothNotNull()","452ddecc":"startBallot()","452e0d25":"sURL()","452e880b":"readArticle(string)","452e9acb":"setMsgHash(bytes32)","452fa483":"TOXToken()","452fbc41":"USN(address,address,bytes,uint256,uint256,uint128)","45301024":"ownerDispute(uint256,uint256,uint256)","4530a6c6":"getWishTribute(uint256)","4531aaa3":"EverydayTokenStandardToken(uint256,string,uint8,string)","45327fef":"calcSharePriceAndAllocateFees()","45334894":"setTeleportPrice(uint256)","4533f779":"determineWinnerOdd(string)","45350759":"addTier(uint256,uint256)","45350b6b":"readFromStorageView()","45362978":"query1(string,string)","4536be70":"periodITO_hardCapInWei()","4537544c":"makeAccountIterable(address)","4537b7de":"developingFund()","45385448":"BEERS()","45387d2c":"_getTournamentSupportAmount(uint256)","4538b7ec":"CallExecuted(address,uint256,uint256,uint256,bool)","453920cb":"changeTokenName(string,string)","45395b03":"tokensIssuedOwner()","4539bf18":"date01Feb2019()","453a6e0d":"getAmountConverted()","453aa450":"vote_proposed_address(string,string)","453b7eab":"totalControlledBalance()","453c2310":"maxPerWallet()","453ca7ee":"RewAddr()","453cbb11":"canConvertTokens()","453cddaf":"performPhase()","453dc243":"setWoodAddress(address)","453dd97f":"getDevWallet()","453dfcae":"payExtraTokens(uint256)","453e5a2c":"registerMarket(bytes32,address,address)","453e6fa0":"schedulableAmount()","453eca78":"getRealmNum()","453fe8cb":"calcUnMaskedEarnings(address)","453fef69":"setPrepaid(address,uint256,uint256,string,uint256)","454052ea":"relent()","45406101":"TTCToken(address)","45408a8a":"minCashout()","4540a396":"importBalancesOf(address[])","45411c8d":"checkAllowedTier(address,address,uint8)","45414df1":"b2s(bytes)","4541c39c":"to_end_ico()","4541e154":"sumICOStage4()","45426082":"countdownDecrement()","4543754f":"totalUserStakes(address)","4543f79e":"withdrawERC20ToOwner(address)","454431c1":"RangeGameWithITG(address,uint256)","454481dd":"nextLotteryTTMTokenId4()","45448a28":"approveAddOwnerRequest()","4544ad22":"allByAuthor(address,uint256)","4544c48c":"distributeWinnings(uint256)","454584e6":"_setProviderInvitedUser(uint256,address,bool)","45458643":"setPI_edit_16(string)","45461e78":"MToken()","4546ad06":"sendProposal(string)","4548821c":"ExBatallionCoin()","45488ac1":"buyStake()","45493057":"validateClaimTokens(address)","454a2266":"dhopakexchange(address,address,address,uint256,uint256,uint256)","454a2958":"foundersTokenTimelock()","454a2ab3":"bid(uint256)","454aa6cf":"getPhoenix(uint256)","454b0172":"Created(address,address,address)","454b0608":"migrate(uint256)","454bccd0":"mininumContributeWei()","454bf426":"sysFeePermillage()","454c57ee":"getStockBuyOrderPrices(uint256)","454c5d34":"allocateBalance(uint256,address)","454c87b3":"matured()","454ca9fd":"get_my_tokens()","454ccc2f":"totalAngels()","454d3e24":"investorsBalance()","454d9bb4":"MerkleMine(address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256)","454dd6d2":"GetMinimumBet_Ether()","454dfaaf":"claimSale()","454f7b8f":"totalPayout()","455052b9":"getInstanceMetadata(uint256)","4550fa72":"isConsensusObtained(uint256)","4551b1d7":"ProxyPayment(address,address)","4551dd59":"isCrowdsale()","455259cb":"getGasPrice()","45528aa8":"addItemToInternal(address,uint256,uint256,uint256,uint256,uint256,uint256)","4553c343":"getEarningMetrics(address,bytes32)","4553fd4d":"token_ratio2()","455501d3":"Submission(address,uint8[])","45550a51":"recoverAddressFromSignature(bytes32,bytes)","455530a6":"TestRandomNumber()","45556969":"DealerSocketCoin()","4555d5c9":"proxyType()","4555db10":"tokenRecovery(address,address,uint256)","4556611e":"weiToShare(uint256)","45576f94":"createToken(string)","455770a4":"setIcoPhase1(uint256,uint256)","455778ed":"advisorsTokensSecondReleaseTime()","45579b1f":"transferShares(uint256,address)","4557a579":"addWeapon(uint256,string,string,string,address)","4557b4bb":"init(uint256,address,address)","4557c70d":"CrowdWallet(address,address,uint256)","45585afe":"manageInvitations(uint256,address[],address[])","4558850c":"apps(bytes32,bytes32)","4558d717":"changePaymentToken(address)","45590ec8":"addTag(uint256,string)","45596e2e":"setFeeRate(uint256)","45598b4a":"cancelCampaign(uint256)","45599136":"tokenFee()","4559b2e8":"holderAdvisorsTokens()","455a2a37":"MyAdvancedToken(uint256,string,uint8,string)","455a380d":"getTotalAmoutStageAddress(address)","455b33ab":"gambler2()","455bf142":"refundeesListLength()","455c06e4":"mintTokens(address,int256,uint256)","455c7050":"EscrowManager()","455ca9bd":"refundTokens(address)","455d4077":"_startLockup()","455d86b8":"revenueShareOwnerAddress()","455dc46d":"nextMinimumEpochInterval()","455df579":"left84(uint256)","455ea98c":"getInUse(bytes32)","455eb777":"canStake(address,uint256,uint256,bytes8,uint256,string,string,string,string,uint256,uint256)","455ef8f9":"coinsCount()","455f1725":"getTotalAmountOfBlocks()","455f6f31":"totalTokensBurnt()","455fd623":"totalWithdraw()","455fea46":"getTankDetails(uint32)","455ff9a4":"lastBlock_v16Hash_uint256()","456176eb":"PCDStartTime()","45622c31":"setContractAllowance(address,uint256)","45624260":"getNumPositionOperation(string,address,string)","45626ecb":"removeStages()","45629402":"changeDefaultWithdraw(address,address)","4563b743":"getPAAttributes(uint32)","4563f30a":"transfersPaused()","45644fd6":"removeOracles(address[])","45645572":"presale(address,uint256,uint256)","4564ea36":"forceVoidExternal()","45653a6d":"creater()","45656757":"p1_start()","45668923":"Aikcoin()","45668f2b":"ORACLIZE_GAS()","45669c8d":"protectedTransferToMint(uint256,bytes32)","4567a6a7":"getXCPlugin()","4567c5f7":"buySharePriv(uint256)","45680e09":"createPixels(uint256)","4568fb50":"finishRoundAndStartNew()","4569db8a":"getCustomerTxAmountKWh(address,bytes32)","456a09c8":"withdraw(uint256[],uint256[],address)","456c2892":"finalizeLottery()","456c64e0":"getGamesOdds(uint256[])","456c8cac":"saleStopped()","456cb7c6":"authorized()","456cbafc":"AddressWarsBeta()","456cee82":"setAmountPerEther(uint256)","456f3c3b":"internalIcoFinished(uint256)","456fe579":"notate(address,uint256,uint256,uint256[])","4570160e":"MotionToken()","45705906":"isLeading4FF(address)","45705d93":"BwinToken()","457094cc":"fire()","45710074":"sell()","45714c7b":"TOKEN_CLAIM_WAITING_PERIOD()","4571a7f1":"maxStage()","4571d4c4":"FutureCall(address,uint256,uint16,address,bytes,bytes,uint256,uint256,uint256)","45734d2b":"sizeOfInt(uint16)","45737b1e":"changeEndDate(uint256)","457391e5":"createGame(bytes32)","4573a421":"ico4Sold()","4574dea5":"setBreedingFee(uint256)","45751137":"newDeposit(address,uint256,uint256)","457556c2":"getUBetChecks()","45755dd6":"returnFunds(uint256)","457610e5":"cancelTransaction(bytes32,string,bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)","4576a635":"setCategoryCap(uint256,uint256)","457750a4":"marketIncentivesAllocation()","457770d8":"PreICO(address,address,uint256,uint256)","4577942c":"lastTransactionTime()","45787fed":"WolframExchangeTimes()","45788ce2":"prev(address)","4579268a":"getOffer(uint256)","45798593":"Certification(string,string,string,string,string,string,string)","4579c805":"createDistritoVerify(uint256)","457a21bc":"GullitCoin()","457a893f":"upPlayer(address,bytes32,uint256,uint256,uint256,uint256)","457b4e1b":"_setMoreDetails(uint256,uint256,uint256,uint256,uint256,address)","457bb613":"initializeUsers()","457c600c":"getItemAllowanceAmount(uint256,address,address)","457ce032":"getTokensFromExchange(address,uint256)","457cf77a":"couponToken()","457d13ca":"getPlayerBet(string,address)","457dd8b3":"setMasterKey(address)","457e5521":"getAllPolicies()","457e8fc7":"calculateReward(uint32,address,address)","457eff2f":"GetMySnails()","457f4d41":"hammer()","457f55fb":"updateRightLottery()","4580a950":"setDecreaseRepAvailableForExtraBondPayouts(bool)","4580cc5e":"setFinished(uint256,uint256)","458284fb":"setACLRole7123909213907581092(address)","45837e5f":"updateLandData(uint256,string)","4584117e":"mintParts(uint16,address)","4584afe5":"buyLambo()","45850658":"closeAssignmentsIfOpen()","4585ad02":"delayDefaultAction()","4586a517":"addTotalSponsored(address,address,uint256)","4586e4ab":"balanceInPlay()","45871918":"raceToBaseStats(uint256)","4587327a":"doAirdrop(address[],uint256)","45874c93":"PersonaIdentity()","4587501e":"baseIcoPrice()","4588c1ef":"setPI_edit_2(string)","45895620":"getAvatar(address,uint256)","458a645d":"resolveDeposit()","458b1471":"mintingFinishedTime()","458c9ca4":"year3Unlock()","458d5968":"getMyTokensEmits()","458d96bb":"transferLockedMultiply(address[],uint256[],uint256[],uint256[])","458da775":"_makePlant(address,uint256,uint256)","458e18d7":"AMLOveCoinVoting(address)","458e78d5":"getSchellingRound(uint256)","458efde3":"vest()","458f837f":"minSumICOStage1USD()","458fa428":"summDividendReserve()","458ff74f":"authorizeBurnFulfiller(address)","45906baf":"Restrictable()","45909a6f":"getBalanceOfUser(address)","4591a980":"verifyStep(uint256,bytes,bytes,bytes)","4591b7c6":"fillBonds(address)","4591c060":"fork()","4592282e":"LBC()","4592cd1d":"claimContractOwnership()","4592fec8":"returnBids(uint256,address)","459348dc":"BISTEXToken()","45934d0b":"getIdentityName()","45941a38":"lastTimeOfNewCredit()","45945a45":"isRoundActive()","459469e0":"FundsRegistry(address[],uint256,address)","4594762a":"getSkill(uint256,uint256,uint256)","459497fc":"ownerAddressInLUT(uint256)","4594d06a":"delMinter(int256,address)","45950cd4":"selfairdrop()","4595343f":"dividendsRightsOf_(address)","459659a4":"Exchange(address)","45967555":"deployedContracts(address,uint256)","45977d03":"upgrade(uint256)","45977ebb":"LINCToken()","4597dc8e":"CooldownThreshold()","45983b24":"isReferralSupported()","4599308f":"buyCow()","459a2192":"cardDetailsList(uint256)","459a585a":"testCreateToken()","459a6589":"transferInGame(address,address,uint256)","459ae9b3":"addMembers(address,bytes32,address[])","459b0d97":"SimpleConstructorBytes(bytes32,bytes32)","459b2cd6":"OwnableWithRecovery(address[],uint8)","459b3926":"Airdrop_Limit()","459c7d0b":"tokenIcoUsdCentPrice()","459cb2be":"agreedTermination(uint256)","459ccde6":"modifyRandomNumber2(uint256)","459ebb8c":"BCMtest()","459ec508":"betOnColumn(uint8)","459f93f7":"getBuyers(uint256,address)","45a132d4":"LemonSelfDrop1()","45a15388":"marketPrice()","45a1b92c":"onBurn(address,uint256)","45a1d72a":"_tobuy(uint256,address,uint256,uint256)","45a1f1b9":"getInitials()","45a2556c":"getBucketOwedAmount(uint256)","45a2a3df":"withdrawTeamPerfit()","45a37bd6":"kycManagerWallet()","45a3816c":"forfietCollat()","45a3b0bf":"resolveFailPledge()","45a3c7c6":"_createReleaseAuction(uint256,uint256,uint256,uint256,uint256)","45a40478":"downs(address)","45a45695":"baseTargetInWei()","45a48de6":"getBigPromoRemainingBlocks()","45a4a39c":"completePost(address,address)","45a727de":"checkForUpdaterUpdate()","45a743d1":"TOTAL_AIRDROPPED_TOKENS()","45a7b991":"getContributionHashes()","45a88ff6":"claimPlotMultiple(uint256[])","45a8d80e":"PiPiCoin()","45aa257a":"VICCoin()","45aa324c":"start_service(address,uint32)","45aa6e98":"tokensCreated(uint256,uint256)","45aa7f69":"OffMenuMorselToken()","45aa83d8":"blockoptions()","45ab17bf":"setRefunding()","45ab63b9":"walletFeesInBps(address)","45ab8e07":"CoinsdomCoin(uint256)","45abc063":"totalLoadedRefund()","45abe20a":"investorsIndex(uint256)","45acc490":"executeAmendmentMandate(uint256)","45ad35bc":"lastCallAddress()","45ad55cc":"PRE_ICO_DURATION()","45ade051":"getUtilizationRate(uint256,uint256)","45ae47fd":"CardFactory()","45aeff61":"getStockKey(bytes6,bytes6)","45af4bc2":"JJToken()","45af7ceb":"invalidateHash(bytes32)","45b0f6d2":"sealBurner(bytes32)","45b17abb":"distribute_private_sale_fund(address,uint256,uint256)","45b1c336":"icoWeek3Bonus()","45b21736":"getCBAStatusMessageLength(address)","45b26383":"contributeFund(string)","45b30e7a":"GTBToken()","45b35f56":"getAllRewards()","45b3fe42":"Y()","45b426f2":"option30symbol()","45b50255":"getBooking(string,uint256,uint256)","45b5143b":"TUMITOKEN(uint256,string,uint8,string)","45b581a2":"getPotentialProfit(address,string)","45b5a47a":"GetEther()","45b64133":"HHRLocker()","45b660bd":"IssueTokensToInvestors(address,uint256)","45b6ccfd":"MAX_MIDGRADE()","45b727f3":"getShop(uint256)","45b748ab":"SSPUnregistered(address)","45b7d5da":"setFrozenAccount(address,bool)","45b7fdd4":"TheGreatWishOfChina()","45b8bafc":"floorLog2(uint256)","45b8c0c2":"parcelGzeWithBonusOffList()","45b8fa03":"TokenLongExercised(address[2],uint256[8],uint256,uint256)","45b9ca21":"getEther(uint128)","45bae1eb":"carAccts(uint256)","45bae539":"getContributeParticipant()","45bbee71":"rmAsset(address)","45bbf9b5":"TotalPayment(uint256)","45bcd68f":"BitVideoCoin()","45bd3752":"intMemoryArray(int256)","45bd7f03":"addBountyAddresses(address[])","45bda564":"SPECIALIST_STAKE_THREE()","45bddbb8":"thanksAllGenesisUsers()","45bdfedb":"getAdrByIndex(uint256)","45be66eb":"SportsBet()","45beb6e0":"matchAgainstBook(uint128,uint256,uint256,uint256)","45bf5cb2":"testInitialBoardUsingDeployedContract()","45bfdca6":"addWalletAddresses(uint256,address)","45c08718":"updateCredit(address)","45c1234c":"Sent(address,uint256,string,string)","45c12560":"LogMoneyToPreICO(address,uint256,string)","45c1523a":"OzsToken()","45c16a22":"getSaleStage()","45c1c9fc":"setBuyEnable(bool)","45c35fd5":"publicOfferingTokens()","45c38053":"tankAllowance()","45c41132":"_emitPaymentReleased(uint256)","45c41478":"getMarkets(bytes,address)","45c46619":"addWhitelistedBurn(address)","45c531f3":"secondDiscountPrice()","45c5904f":"malangtoken()","45c5b8ac":"set_game(address)","45c5de81":"listTeamTokens(uint256)","45c654eb":"TravelToken()","45c6a874":"adminMultiSig()","45c7a092":"isValidSignature(address,uint40,uint40,uint128,uint256,uint8,bytes32,bytes32)","45c8b1a6":"unfreeze(address)","45c8e118":"view44()","45c917ec":"closeDeposit()","45c9a11a":"maxProfitPercentage()","45c9a558":"getPeriods()","45ca25ed":"changeName(address,string)","45cb3dde":"withdrawTime()","45cb3f4d":"highestBidPrice()","45cb4559":"gameGiftUserTotalTimes()","45cb9994":"Lookup()","45cbf879":"getStageByBlockNumber(uint256)","45cc13c3":"tokenize()","45cc50ce":"endTimeIco()","45ccd426":"ObokContract()","45cd4820":"participate(address,uint256,bytes32,address)","45cdb714":"changeColorWhite()","45ce0dc1":"addLambo(string,uint256,bool)","45ce691a":"buy(uint256,uint256,uint256,uint256,uint256,uint256)","45ce86eb":"whitelistApplication(bytes32)","45cf093a":"sumDividend()","45cf8467":"getSqr(uint256)","45cfad3e":"TOKEN_PRICE_N()","45cfcc42":"getKeyVotes(string,string)","45d0695f":"arr(uint256,uint256)","45d1b657":"PRE_SALE_3000_ETH()","45d27edf":"forward_method(bytes,address,uint256,bytes)","45d30a17":"releasedAmount()","45d3292b":"receiveDonation()","45d3b8db":"superAddress()","45d3cc81":"getAnimal(uint256)","45d4cf2b":"createPrivilege(string,address,address)","45d5149f":"minContributionAmount()","45d53788":"numOrders()","45d58a4e":"getWalletOut()","45d607fe":"referralFee_()","45d63b07":"BrokerNekoNetwork()","45d63b66":"recommit(uint256)","45d6c9db":"PVP_BATTLE()","45d78d08":"getTokenAllocations()","45d7fd3e":"setCreationAddress(address)","45d8a232":"targetTime()","45d8a6df":"tablePrices(uint256)","45d9a1ce":"withdrawBalance(address,address,uint256)","45d9bd15":"getBookmarks()","45da75d3":"setPresidenteDeMesaVerify(bytes32,uint256,uint256,uint256)","45dafed2":"Marcellocoin()","45db72ff":"lastLoveLetter()","45dc16ca":"trade(uint256[12],address[4],uint8[2],bytes32[4])","45dc3dd8":"setMin(uint256)","45dcb788":"dataSourceGetRoundOfSixteen(uint256)","45ddc85d":"voteOf(uint256,address)","45ddcf99":"unlockUntradeableCards(address)","45de2567":"transferTokens(uint256,uint256)","45df30d2":"transferPlusFee(uint256)","45df925f":"ratingList()","45dfe7f3":"restrictedWallet()","45e05f43":"affiliate()","45e09e54":"getBoard(uint256)","45e0e324":"FoodStore()","45e0e412":"forwardTokens(address,uint256)","45e231a6":"XCONToken()","45e26105":"updateMaintenanceMode(bool)","45e29057":"_myLuckyNumber()","45e3553e":"setMaxProtoId(uint16)","45e373ed":"getCertificateById(string)","45e381a9":"set_minFinneyPerHedgeTransfer(uint256)","45e39705":"addMember(string,address)","45e3b8c0":"SHOP()","45e41468":"placeSell(address,uint256,uint256)","45e479f6":"GetDiv()","45e4c361":"rteamVaultAddr()","45e4db40":"addTxInBuffer(address,uint256,uint256,uint256,uint256)","45e4fd6e":"listItem(uint256,address,string)","45e5da07":"ETHAssets()","45e5fd8b":"nonActivationShortWithdrawal(address[2],uint256[7],uint8,bytes32[2])","45e7e140":"getReservedPercentageDecimals(address)","45e7e14b":"ReputationUpdated(string,uint256,uint256,string,string,address)","45e82175":"level_5_percent()","45e8baa7":"checkSignatures(bytes,bytes,bytes,address)","45e93903":"SpooksterCoin()","45e965cd":"strConcat(string,string,string,string)","45ea375f":"viewPot()","45eada10":"setProvider2(address)","45eb4b28":"destinationAddress20()","45eb7c8e":"CompleteAddOn(uint256,address)","45ebc145":"publish(uint256,string,string,string,bool)","45ebe153":"moveIcoEndDateByOneMonth(uint256)","45ec26ac":"distributedCount()","45ec7670":"WallStreetCoin()","45ec9e87":"Eurovision()","45ecd02f":"isActiveMember(address)","45ed68e8":"defaultSalePrice()","45ede900":"setPropertyOwnerSalePrice(uint16,address,uint256)","45ee49b9":"getUltimateOutcomes(bytes)","45ee9151":"BountyTransfer(address,address,uint256)","45ef8217":"clear_market()","45f00b06":"setNewTalentsAndPartnerships(address)","45f03f31":"EthereumLottery(address,address,address)","45f09140":"chargebackCoins(uint256,address)","45f0db24":"get_coin(uint256)","45f11fc8":"trancheAmountPct()","45f23f10":"crowdsaleFundsWallet()","45f28e77":"genToStartPrice(uint256)","45f32b02":"currentModifier()","45f32b6d":"totalCirculating()","45f32e77":"currBlock()","45f45449":"EtherCash()","45f472fc":"saltNHash()","45f4c1ba":"pay(uint128,address)","45f536f7":"sendPer2()","45f63927":"increaseGame()","45f67eb4":"setTolerance(bytes32,uint256)","45f6ee41":"setPrice(uint16,uint16,uint8,uint256)","45f7f249":"totalAllocated()","45f826da":"setMinimumInvestment(uint256)","45f8567c":"paySmartContract(bytes32,address[],uint256[])","45f8f1e8":"RajTestICO(address)","45f9072b":"setColorOrange()","45f988a4":"priceT2()","45f99d51":"claimFailed()","45fa4045":"getVestingPeriodNumber()","45fa53e7":"pieAccounts(uint256)","45fb0cd6":"addMultipleAddressesToCappedAddresses(address[])","45fbe9cb":"spawnChild(string)","45fbfbca":"investment()","45fc916c":"setPricingPlan(address)","45fcceb4":"foundersTokensReserve()","45fd2478":"_getShipType(uint256)","45fd3666":"isTurnDataSaved()","45fd4040":"addAllowCnsContract(address,bytes32,address,bytes32)","45fd865a":"HazzaToken()","45fd9e23":"claimOwnership1()","45fdef65":"addCandidate(address,bytes32,bytes32)","45fe5850":"OrganFunction(string,string)","45fe5a83":"deliveryTime()","45fe5aea":"useKey(address,uint256)","45fe6e2a":"Scheduler()","45febc32":"BugisNet()","45ff59b2":"createTokensForCrypton()","45ff8b75":"get_HoldersProfit(uint256,address)","45ff8fde":"request(bytes32,uint256,uint8,uint256)","460123cf":"findAddressByEndpoint(string)","4601cded":"getNumSides()","46021deb":"getLastAuctionedShipId()","4603032a":"withdrawByTeam(address,uint256)","46032178":"MigrateAgentSet(address)","460485e0":"fundsWithdrawnByOwners()","46051eb7":"getProductHistoryUser(bytes32)","46054144":"ASIEX()","46055acd":"Decline(address)","46057b70":"timeOver()","46061579":"check1(uint256)","4606ccd1":"spinAllTokens()","4607c26e":"periodsPassed()","4607ef57":"preICOTokenRewardRemaining()","46080a94":"subResearch(address,uint256)","46082aaf":"approveDeprecation(uint256,address,bool)","460885ab":"_createNewLottery()","46091499":"transferFrom(address,address[],uint256[])","46093b0e":"setOracleAddress(address,address)","460a6507":"giveReward(address,address,uint256)","460ab47b":"proposeChangeOwner(address,address)","460ad570":"newOraclizeResult(bytes32,string)","460b4a45":"getTotalBonusesAmountAvailable(bytes32)","460c1a7a":"cancelOrders()","460c3be5":"owner_LockUpdateTokenAccount(address,bool)","460d674b":"keyFromIndex(uint256)","460e2049":"getPlayers(uint256)","460f740e":"createData(string,string,string)","460fce3b":"milestoneStarted(uint256)","4610a448":"vestingBeneficiaryForIndex(uint256)","461105c7":"withdrawBoth(uint256,uint256)","4611636e":"erc20VGC(uint8)","46116e6f":"sireAllowedToAddress(uint256)","4611a5e3":"calcRefund(address,address)","4611efde":"changeTBrate(uint256)","4611fb0e":"RSC()","4612b88d":"deleteDiniRequest(uint256)","46134e33":"getPrivateSaleEndDate()","46141657":"SetdivForTank(uint256)","4614185a":"IkuraTransfer(address,address,uint256)","46143a39":"setMessageSpan(uint16)","4614689c":"showWinners(uint256)","4614874e":"createEscrow(address,uint256)","46156ea0":"odds(uint256)","461645bf":"window()","4616caa9":"pushCoin(uint256,address,string)","4616fc3f":"setSystemSaleAddress(address)","46172c04":"calculateRewardForAddressAt(address,address,uint256)","461751e6":"resetMistCallLoad()","46183d06":"getTktPrice()","46190e16":"getSpecId(bytes)","46190ec4":"nextId(address)","461998fc":"cancelRecurringPayment(address)","4619aa19":"pvpOwnerCut()","4619c0ca":"insertBeneficiaries(address,address,uint256,uint256,uint256)","461a2df9":"PretherICO()","461a4478":"resolve(string)","461ac019":"deployedTime()","461ad9e9":"saveGenCode(address,uint256,string)","461c89b3":"massMint(uint8[],address[],uint256[])","461db9ad":"GoCryptoCoin()","461df016":"getQuantities(address)","461e0be5":"ElphToken()","461efbf8":"testEtherFundMeCrowdfunding()","461f48cb":"setUsersBounty(address[],uint256[])","461fd83b":"myEtherBros(address)","46203efe":"frozenAccountCoinByHour(address,uint256,uint256)","46205ac3":"hodlFor1y()","4620adbb":"tokenPricePerUSD()","4621a5d9":"activateRevenueShareReference(uint256)","4621e552":"decreaseRemainLockedOf(address,uint256,uint256)","462219f8":"batchTransfer(bytes32,address[],address,uint256[])","46226514":"isPresidenteDeMesa()","46238c69":"nextRedemptionRequest(uint256)","4623beb6":"InterestTest(address,address)","4623c81e":"TIMELOCK_DURATION()","4623c91d":"setValidator(address,bool)","4624321e":"decreaseApprovalWithData(address,uint256,bytes)","46256be7":"getAgentAdressById(uint256)","46272a6d":"mySavings()","4627de42":"getIncrease()","46280a80":"sell(uint8,uint256,uint256)","46285e45":"checkBalanceAt(address,uint256)","46286c18":"_validateUserActive(address)","46287ddb":"rateLastWeekEnd()","4628b375":"TokenLeft()","4628bc22":"teamTokensVesting()","4628e45e":"ABAToken()","4629e619":"raceNum()","4629ffea":"newToken(string,string)","462a8e05":"setRabbitSirePrice(uint32,uint256)","462aa19e":"setToken(address,bytes)","462b2fca":"isRedeemLocked(address)","462c1bff":"H4D()","462c6070":"getLockedAmount_jishis(address)","462c6edb":"highBonusRate()","462dcfa0":"newMaster(address)","462e91ec":"addCandidate(string)","462f9a28":"get(bytes32,bytes32,uint256)","463079b5":"resetFactories()","4630a0ee":"changeTicketPrice(uint256)","4630d82e":"upgradeTokens(uint256)","4630f1d5":"toggleKillSwitch()","463107d4":"buyerfeeDivide()","46315237":"fiveHours()","46317712":"lastDebtLedgerEntry()","463193c7":"startselfdrop()","4631db54":"_burnTokens(uint256)","4631e15b":"assertEq15(bytes15,bytes15)","46325b48":"CTCoin()","46336cd3":"read(uint256,uint64)","4634009a":"getIdx(string,string,uint256)","46340b37":"RakugoPresale(uint256,uint256,uint256,address)","46348e0b":"calculateArea(uint256)","4634d81c":"getDividends(address)","4634ea79":"countCurrentPayment()","46352ad9":"transferToGrowthReserve()","4635b449":"raisedUSD()","4635ecd5":"lastTicketNumber()","4636a159":"newPhoneToAddr(address,uint256)","4636db04":"changeBid(bytes32,uint8,uint8)","4636e095":"acceptBet(uint32)","4637c85d":"wildcardTokenId()","4637d827":"trust(address)","4637de3c":"removeMod(address)","4637fd1a":"_transferEther(address,uint256)","463959fa":"minJackpotBet()","4639888b":"jockeyForSale(uint256,uint256)","463ac31b":"buyStore()","463c3347":"getMyLandMultiplier()","463c75b3":"GreenworldFarmToken()","463cde9e":"PUBGtoken(uint256,string,string)","463cf730":"maxEthCapBuyInFp()","463d3cda":"acceptExternalTransfer(string,uint256,string,uint256)","463d50b8":"transferFromVault(address,address,uint256)","463d5ce1":"isUserWithdrawalTime()","463dcf0a":"merge(address,uint256,uint256)","463dfae6":"setTrg(address)","463ee88a":"createBusiness(uint256,uint256,uint256)","463f2c21":"giveCredits(address,uint256)","463f7a7d":"_updateDependencies()","463f7a89":"getProperty(bytes32)","463fb5f1":"Bogotcoin()","463fbb76":"setTransportationFeeMultiplier(uint256)","46405ffc":"OhNoToken()","464066f5":"vote03NoCount()","4640f28d":"createPlayerToken()","4641257d":"harvest()","464299f9":"getReturnFromMonster(uint64)","46435fa1":"createPiranhaToken(string,address,uint256,uint8,uint8)","4643db5b":"DonationClaimed(address[2],uint256[8],uint256,uint256)","4644d17e":"getAirDropTokens()","4646939e":"updateWhitelistMapping(address[],bool)","464695b3":"tokensSoldTo(address)","4646f62a":"setAvatarFrom(address,string)","46478e91":"increaseGlobalInterestAmount(uint256)","46479541":"setWalletId(address)","4647d0c6":"CUNCoin()","464858c6":"NVT()","46488459":"getTopMigrationDestination()","4649bfee":"setCCH_edit_25(string)","464ae89f":"SponsoredLink()","464bb7a3":"findAccess(address)","464cccc8":"round4Cap()","464cecb8":"getHyper(address)","464d1208":"claimReward(address,address,uint256,address,uint256)","464da87e":"cofoundersSupplyVestingTranchesIssued()","464deba6":"TridentToken(uint256,string,uint8,string)","464e1d46":"setBalanceOfAddr(address,uint256)","464e47b4":"wasSoftCapMet()","464f37c9":"trustedChildRefund()","46503676":"_useCitizenAsLumberjack(address,uint16,uint16,uint8,uint256)","46503c01":"KansasvsClemson()","4650c308":"genericCall(address,bytes)","465105f0":"releaseAllETH()","46517145":"createNewCardType(uint256,uint256,uint256,uint256)","4651f716":"assertEq14(bytes14,bytes14)","4651ff39":"setopen()","4652e9fe":"getStartDateOfPlan()","46530c34":"activityExist(uint256)","46533d60":"setNewReleasePeriod(address,uint256,uint256)","46534649":"referralBalanceOf(address)","46538e07":"checkExistsOwnedMedal(uint64)","4653a1fa":"setAttackBoostCap(uint256)","4654b6e2":"addMonsterObj(uint64,uint256,uint32,address,string,string)","46567a07":"getTotal(address[],uint256[],uint256)","46570653":"_share(uint256)","4657681b":"set_num_of_uses(address,address,uint8)","4657ad8e":"payTxFees(bytes32,uint256)","4657d848":"getVendorIds(uint256,uint256)","46581235":"unlockToken(address,uint16)","465941e5":"ATMHolders(uint256)","4659f42a":"withdrawAfter(address)","465a092d":"PRESALE_ETH_CAP()","465aaeb7":"windowBonusMax()","465af554":"setLockJackpots(address)","465b43d0":"joy()","465c2cec":"SmartBonds()","465c8ce0":"getRobot(uint256,uint256,uint256)","465ce877":"HashnodeTenaraCoin()","465d1cbe":"getDepositsAmountLeft(uint256)","465d5c27":"_tokenIsApproved(address,uint256)","465d6e1a":"CAUSE()","465e759b":"testRestart()","465e920e":"getLineData(uint256)","465f1d07":"CrowdTmoney5()","465f41b1":"multiOwner(address[])","465fa408":"calculatePriceForTokens(uint256)","465fe311":"KEP()","46601278":"TotalTOkenSupply()","46602ce7":"FOUNDERS_POOL_ADDR()","4661bb98":"setClassWhitelist(uint32,bool)","46621234":"tmpAddr2contractAddr(address)","4662299a":"issuanceFinished()","4662fbdf":"promotorSale()","466339fb":"_rewards(uint256,uint256)","46642921":"changeModerator(address)","4664611e":"winningNumber()","4664b235":"bytes32_to_bytes(bytes,bytes,bytes)","4664fe1b":"changeMinFunds(uint256)","4665096d":"expiration()","46653287":"createInitialTokens(address,uint256)","466551f1":"LinqToken()","466559e2":"S26ICO()","46656c46":"OxToken()","4665975d":"registerCustodian(address,address)","46682cab":"canFinishTournament()","46683308":"freezeAccountForLogic(address,bool)","46689c64":"startPlaceOrder(uint256,address)","4668b43b":"updateTelegram(uint256,string)","4668f372":"MaxMiningReward()","466916ca":"pauseStatus()","466985f3":"escape(uint256)","4669e680":"getPreEntranceMemberCount()","466a3443":"getIndividualPercent()","466ae314":"forwardedOutcomeSetTimestamp()","466bb312":"getDeposited(address)","466bc3bd":"GOXX(uint256,string,string)","466bf275":"getFreeToad()","466c35fc":"MINT_ADDRESS()","466c3a2b":"getChecksumAlgorithmCount()","466ccac0":"forSale()","466cf98f":"giftBalance(address)","466df592":"votingPeriodBlockNumber()","466e37e7":"newTapProposalFromTokenHolders(uint256)","466e561f":"updateReserve(address,uint8,bool,uint256)","466ebdf6":"setAddressOut(address)","466f0004":"getData_10()","466f8870":"Solar()","4671e65e":"proposeEmergencyWithdrawal(address)","4672f555":"pow(int128,int128)","46743691":"transferPublisherRecord(address,address)","467523fa":"setBuyerRate(address,uint256)","46755c68":"setEndingBlock(uint256)","46758d0b":"setAgentRate(address,uint256)","4676b897":"balanceOfUnclaimed(address)","467730fb":"toFound()","4677b540":"ATOToken()","4677fe53":"validUnitId(uint256)","467aeec9":"addShareholderAddress(address)","467d7289":"clearRound(uint256,uint256,bytes32,bool,uint256,uint256,uint256,uint256)","467de087":"withdrawAdvisorsTokens(address,uint256)","467eb43f":"verifyIdentity(address,bytes32,uint256)","467ed261":"getDSTNameBytes()","467f0b7b":"del_rank(uint256)","467f85e4":"DividendPayment(uint256,uint256)","468014e1":"startTimeSale1()","46804137":"bonusStep()","46807803":"_payoutMining(uint256,address)","4681067d":"incAdminEpoch()","468129a5":"setUnit(uint256,uint256,uint256)","46817362":"importersBanksDraftMaturityDate()","46822869":"BTFM()","4682ff71":"redeemMarketingToken(string)","4683ef63":"delayedOwner()","46848114":"startOffering(uint256,uint256,uint256,uint256,bool)","4686030f":"promethExecute()","468628e1":"getActivityById(uint256,uint256)","46862c8f":"mintOnce(string,address,uint256)","4686753d":"Crowdfunding()","46875458":"ARM()","4688a372":"withdraw(address,bytes8)","4689ab4d":"right21(uint256)","468a0413":"parseResult(bytes32,string,address)","468ae69d":"multiMint(address[],uint256[],string)","468b0c1d":"AllPay()","468b0fcd":"preSaleGoalReached()","468b0fe2":"setBridgeNode(address,address,bool)","468b3b33":"unlockedBalanceOf(address,uint256)","468c17d7":"_sendMsgSndr(address,address)","468e1b53":"DEC15Contract()","468e4509":"setAutoridadElectoral(bytes32)","468ed002":"INITIAL_VUP_TOKEN_SUPPLY()","468eeece":"revertGame(address)","468f02d2":"getUnderlyingPrice()","468f3dcd":"getTokenHoldersCount()","46904840":"feeRecipient()","46906982":"amountRaisedEth()","46911b64":"testDisputedWriteValid()","46912a4d":"PERC_TOKENS_TO_BIZDEV()","4691a998":"addVesting(address,uint256,uint256)","4692a481":"WilliamCoin()","4692d7e3":"BitQ()","4693667a":"changeMdtFoundationAddress(address)","469450cc":"disableLockDown()","4694fe85":"isUseContractFreeze()","469506bf":"getFinalSeed(uint256,uint256)","469507c6":"transferReward(uint256,address)","4695cf7a":"getSteakPrize()","4696890e":"ethworld()","469737d5":"forceRejectVotes(bytes32,address)","46975b9a":"swypeCode()","4697f05d":"setAllowed(address,bool)","4698ad05":"transferWhileLocked(address,uint256)","4698d110":"numMembers()","4698d920":"setMintAuditApproval(address,address,address)","4698da9d":"releaseVestedTokens(address,address)","469912d7":"Crowdsale(uint256,address,address)","46999ee5":"addNamespaceMember(string,address)","469a6947":"unlockTimeOf(address)","469aaa98":"BitSTDLogic(address)","469ab1e3":"contractNameHash()","469bb426":"failedDonations(address)","469c62a6":"buy_tokens()","469c7f4d":"transferOwner2(address)","469c8110":"sendMessage(string)","469c8dbb":"ExternalSale(uint8,bytes32,address,uint256,uint256)","469e2d5c":"submitPresetTransferes()","469e9067":"records(address)","469ef000":"hasValue(address[],address)","469f4c41":"setPreIcoStatus(uint256)","46a06ddb":"getPreviligedallowed(address,address)","46a06eb9":"LogTimedTransition(uint256,uint8)","46a1749a":"AgingTransfer(address,address,uint256,uint256)","46a1cd08":"getAvailableReward(address)","46a1d95f":"closeMarket(bytes)","46a1fabf":"Withdraw(address,uint256,uint256,bool,bool,string)","46a2679a":"getSubpotsCount(uint256)","46a2b53e":"GAS_REQUIREMENT()","46a3e290":"Defreeze(address,address,uint256)","46a3ec67":"TheAnswerIs(string)","46a54e15":"privatesale_start_time()","46a5b318":"DutchAuction(address,uint256)","46a5bf0c":"airDropStage()","46a60e99":"buyRoseGRLC(bytes32,string,uint256)","46a672bd":"createCard(string)","46a6c499":"freezeMyFunds(uint256,uint256)","46a7551d":"isOnBattle(address,uint64)","46a79a4e":"changeGameSettings(uint256,uint256,uint256,uint256,uint256,uint8,bool,uint256)","46a9d680":"EthereumGold()","46aa6644":"sendAllFeeToAddress(address)","46aaf139":"getSignersCount(bytes32)","46ab3d5e":"evaluateProposalMarket(uint256)","46abf8a8":"setVariables(uint8,uint16,uint16,uint16)","46ace8fd":"removeServer(string)","46ad5859":"getTokensRemaining()","46ade2de":"RESERVED_TOKENS_FOR_PRE_ICO()","46ae38a8":"getHexSymbol(string)","46aee903":"changeminBuy(uint256)","46af23f5":"InstantLottery(address,address,bool,address)","46afb963":"CrowdsaleState()","46b04e53":"PlayerInfoPerZone(uint256,uint256)","46b1d3be":"endTimePreICO()","46b207b8":"checkExpiry()","46b249b9":"tokenSaleOnHold()","46b305d6":"lockBetsForWithdraw()","46b33bc2":"getDonebountyAmount(address)","46b33e05":"getFreeTurtle()","46b4320c":"showUserBalance(address)","46b45af7":"isMintable()","46b55416":"subBuy(bytes32,bytes32,bytes32,address)","46b56bf6":"contract_sha256()","46b5d107":"testFailMintGuyNoAuth(int256)","46b5e202":"set_num_levels(uint256,uint256)","46b61083":"GoDigit(uint256,string,string)","46b65ffd":"getModule(uint8,uint256)","46b7068c":"returneth(bytes32)","46b753a2":"setChargeFeePool(address)","46b77d9f":"areFundsReleasedToBudget()","46b84cad":"getPackageById(uint256)","46b8c49e":"setReserveData(address,uint256,address)","46b98d0c":"startContract(bytes32,uint64)","46ba6f61":"setSuppressedGame(uint256,bool)","46ba7783":"setDistributionMinter(address)","46bb2833":"founderAddress()","46bbb6cf":"removeSshKey(string)","46bc29bf":"getGoldMigration(uint256)","46bdca9a":"equal(string,string)","46be2310":"export(bytes8,address,address,uint256,uint256,bytes)","46be2e0c":"left32(uint256)","46be6f87":"newGame(uint8,string,string,bytes32)","46be96c3":"amountFilled(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","46be9c48":"lockState()","46bf3df3":"_setWallets(address,address,address,address)","46bf5864":"ERC223Token_STA()","46c017b5":"zhuchu(uint256)","46c068c3":"testEndsWith()","46c092b2":"presaleGuaranteedLimit(address)","46c13d28":"changeAccessTokenFee(address,string,uint256,uint256)","46c2997a":"notMoreThan()","46c3166f":"testThrowRetractLatestRevisionNotOwner()","46c34832":"WinnerProvidedHash()","46c49c58":"CustomToken(string,string,uint8,uint256)","46c4e533":"withdrawUpdate(bytes32,uint256,address,address,uint256,uint256,bytes32,bytes,bytes)","46c52b1a":"blockHexCoordsValid(int8,int8)","46c59373":"ethManagementPropagate()","46c66b27":"_transferAll(address,uint256)","46c6f325":"TEACHTokenToken()","46c715fa":"original()","46c797e2":"updateMarriageLicenceImageIPFShash(bytes)","46c7c126":"getChallenges()","46c968db":"blocktubeClip(string,uint256,uint256,uint256)","46c9b457":"privatePreSalePrice()","46ca48a2":"freeAmount(address)","46caf5e8":"BTB()","46cc3179":"getComponent(string,string)","46cc43fb":"decodedSecret()","46cd9b23":"_triggerNewPVPContender(address,uint256,uint256)","46cdb099":"shareholderID(address)","46ce33d4":"clearLockBalance(address)","46cee8f7":"TemporaryPyramid()","46cf1bb5":"lockState(address,uint256)","46cf6d2e":"_validate(uint256,uint256,uint256,uint256,uint256)","46cffffd":"NewAreaStatus(uint256,uint8,uint8,uint8,uint8,uint256)","46d0a022":"transfer(address,address,address,address[],uint256[])","46d0e892":"makeOptions(uint256,address,uint256)","46d0eb60":"addAlias(address,string)","46d0fb60":"isUserLicenseValid(address,string)","46d1501a":"PoP()","46d17bfd":"LongBought(address[2],uint256[2],uint8,bytes32[3],uint256)","46d17c3a":"Unregister(address,uint256)","46d1c605":"balanceOfButter(address)","46d22c70":"canBreedWith(uint256,uint256)","46d24cbb":"refundedWei()","46d36fa0":"ChristopherRobinRT()","46d46a6a":"CashTelex()","46d47cdf":"testFailCreateWithParentsParentNotInUse0()","46d5688e":"RATE_CROWDSALE_S1()","46d64aa2":"Kuberand()","46d667db":"setBytes32(bytes)","46d6b1e8":"getChampsForSale()","46d6c93b":"addFeed()","46d7195d":"vote_until()","46d73def":"hasHalted()","46d7df42":"setTokenContactInformation(string)","46d89444":"getCrowdsaleTierList()","46d95146":"anvlTechToken()","46db63d7":"rewardUser(uint256,address,uint256)","46dbf9b0":"pickupProduct(uint256)","46ddb7db":"setAccountBalance(address,uint256)","46de0fb1":"isFrozen(address,address)","46deb279":"ElementUpgraded(uint256,uint256,uint256,address,uint256,uint256,uint256)","46df1578":"refferBonus()","46df2ccb":"setRate(uint256,uint256)","46e04a2f":"claimTokens(uint256)","46e06634":"approveKYC(address,bool,uint256,string)","46e0c223":"_createOfAthlete(address,string,address,uint256,uint256,uint256)","46e184da":"Olife()","46e1bfbb":"acceptAtGroup(address,uint256)","46e1f732":"investorsProcessed()","46e1fa55":"_removeDefaultOperatorByTranche(bytes32,address)","46e2577a":"addProvider(address)","46e2a174":"preIcoTokensSold()","46e33afc":"getFACTOR()","46e34823":"tan(uint256,string,string)","46e36060":"subBalances(address[],uint256[])","46e3cb1a":"sellTradeConfir()","46e44f63":"getCheckRecordTS(bytes)","46e4959d":"mintMulti(address[],uint256[])","46e4d35d":"numOfLoadedEarlyPurchases()","46e5500f":"LogFinalized(address,uint256)","46e5c323":"largestHODLERBalance()","46e6ffdd":"OwnableStorage()","46e767bc":"Log2(address,bytes32,uint256,string,string,string,uint256,bytes1,uint256,uint256)","46e780b0":"getLinkHash(address)","46e7ccac":"isAuthorizer(address)","46e87b1e":"RgiftTokenSale()","46e93dbc":"maturityProcess(string,bool,uint256,uint256)","46e9ab22":"Gateway()","46e9e3c2":"reclaimPeriod()","46ea2552":"transferManager()","46eac50e":"superTransfer(address,uint256)","46eba0c1":"fundWithdraw(address,uint256)","46ebb5e2":"TimedPresaleCrowdsale(uint256,uint256,uint256,uint256)","46ec56c5":"getNumInvestments()","46ed24a3":"setAirdropToken(uint256)","46ed3199":"ATCToken()","46edef6c":"accICO()","46eea9a1":"secondStageRaised()","46eeed5f":"rolloverFee(address,uint256,uint256)","46ef6660":"createTokenContract(address,bytes32)","46f02832":"queryPermissions()","46f04694":"periodICOStage8()","46f0975a":"signers()","46f19888":"get_total_info()","46f24c6a":"functionSix(uint256,uint256,uint256,uint256)","46f25cad":"setAuthor(string,string,address)","46f2e880":"payForMyselfWithChecksum(uint128,bytes1)","46f42dff":"Win(uint256,uint256,uint256,address,uint256)","46f43f15":"StierBitToken()","46f74c6d":"setArbitrationPercentage(uint8)","46f76648":"getTotalEthSended()","46f7a883":"BuyTicket(uint8,uint8,uint8)","46f7cf87":"insert(address,uint256,address,address)","46f84dc4":"grantPermission(address,address,bytes4,address)","46f8e5ec":"getBlocksUntilStart()","46f92818":"setCreditDaoAddress(address)","46f99063":"totalSent()","46f9bedf":"costPerTicket()","46fa14e5":"MyFeed2Token()","46fa2574":"preIcoMembers(address)","46fae630":"getAllCardsAttack()","46fbf68e":"isPauser(address)","46fc9037":"__beneficiaryTransfer(uint256)","46fcafe2":"etherContributions(address)","46fcff4c":"availableFunds()","46fd9446":"setUsdEtherPrice(uint256)","46fde171":"closeCdp(address,uint256,uint256,address)","46fe2edb":"reserveIAMDestination()","46fec37b":"LogBounty256(address,uint256,string)","46ff099d":"cancelOrderByPayer(string)","46ff43dc":"totalInCents()","46ff4ce6":"betRedCoin()","46ff64f3":"setOraclizeRoundGasFee(uint256)","46ff7eac":"depositContrac(uint256)","46ffb216":"m_startTimestamp()","46ffdfbc":"getMax(uint16[])","47002c6d":"TOTAL_RECEIVED_ETH()","47006460":"maximumInitialBuyoutPrice(uint256)","4700d305":"panic()","4700dc57":"setFirstBonusTokensLimit(uint256)","4700fada":"GVToken(address,address)","47021780":"QSBH()","47026d90":"Volkstest3()","47028fcf":"getSponsorshipAmount(address,uint256)","4702d115":"dataCalc(uint256,uint256)","4702fa12":"_getCurrentRound()","47040cb4":"getStateProofAndHash(bytes,uint256)","47048c7b":"getMemberBoss(address)","47055321":"deduct(address,uint256)","4705b55b":"XCOIN()","4705d888":"getlastmoney()","47062402":"buyFee()","47064d6a":"setData(string)","4706840e":"destroykill()","4706c375":"_withdrawEquity(address,uint256)","4707f44f":"tokensOfOwnerByIndex(address,uint256)","47085958":"SetIndustry(string)","47089f62":"addVerified(address,bytes32)","470905b1":"Founder3()","470a5f4e":"reinvest(uint256,bytes32)","470b1984":"investedBTC()","470b1f7c":"AnetCoin()","470b2867":"tablet_owner()","470b6e0e":"addStackholderTransaction(address,bool)","470bb62b":"record(string,string)","470ca291":"referrerLevel3Ether()","470d7722":"batchAddAddresses(address[],uint256[])","470e872c":"transferBill(address)","47102a5d":"ETC(address,uint256)","4710411d":"twenty_percent_of_amount()","4710c5bf":"preSale3()","4710c63c":"excavation()","4710cfd7":"nContract()","47115192":"voteCut()","4711748d":"setNDCContractAddress(address)","4711dbe1":"registrationBounty()","4713f29b":"setBuyingCostumeRate(uint256)","47146b28":"setFiscal(uint256,uint256,bytes32)","4714c0aa":"proxyAccountingCreation(address,uint256,uint256)","47156810":"scheduleNewDerivativeToken(address,address,uint256)","4715b308":"decreaseApprovalPreSignedCheck(address,address,uint256,uint256,uint256,uint8,bytes)","47166f62":"Quarkchain(uint256,uint256)","47170eb8":"LogEtherTransfer(address,uint256,uint256)","4717dea9":"getTicket(address)","4717f25a":"charonsBoat()","4717f97c":"getResults()","4718d108":"_transfer(address,address,string)","4718dc4d":"payOutVoterById(uint256)","47198cd1":"get_baseAmount(uint256)","471a20e7":"getResponses(uint256,uint256)","471a2270":"Lottery(uint8)","471a23c8":"burnMe(uint256)","471ab294":"handleTokensFromOtherContracts(address,address,uint256)","471ad963":"redeemProposalFunds(bytes32)","471b37cf":"VESTING_ADVISOR_DURATION()","471c95db":"TransferFees(address,uint256)","471d0481":"randomB()","471d4118":"releaseTimeFund()","471d66cb":"exceedsMaxInvocations()","471eab5c":"removeAllowedSender(address)","471efce5":"tokensForPreICO()","471efe66":"set_addresses(address,address)","471f11ec":"purchaseTown(uint256)","471f4722":"setOnSaleAmount(uint256)","471f7cdf":"favoriteNumber()","471fabfd":"eexploitOwnn()","472016da":"playersAddresses(uint256)","47202819":"unregisterInit(address)","4721ed6f":"enableRedemption()","47220f25":"maxPremiumDragonsCount()","4722361c":"canStartSettling(bytes32,address)","4722b4a5":"getFeeParameters()","47237f47":"freeStorage(uint256)","47241a27":"setAdditionalBonusPercent(uint8)","47244212":"Product(string)","472457cb":"addDragonName(uint256,string)","47249b1a":"GetEventInfo()","4725211b":"recordNameCount()","47255591":"setOuverture_des_droits(uint256)","4725d544":"_utoa(uint256,uint8)","47274dbe":"disableUser(address,address)","4727925a":"KEKEcon()","4728537c":"lockupBalanceOf(address)","4728d3ae":"CreatedEDU(address,uint256)","472905ca":"makeAdmin(address)","47293d15":"getAddressesCount()","472aa7df":"createProduct(bytes32,uint128,uint256)","472ad331":"InvestmentsCount()","472b6492":"AddEth()","472b6efa":"getWinRate(uint8)","472c681f":"addPack(address[],uint24[],uint24[],uint16)","472ca5e4":"allocateBid3(bytes32)","472d35b9":"setFeeManager(address)","472e1910":"verifyOpenSignature(address,bytes,bytes32)","472eb03d":"payLoan()","472f36e2":"Allocated(address,uint256)","472fdb67":"totalTokensReserve()","4730725d":"addToTimeLockedList(address)","4730bf06":"STAGE_1()","4732a7dc":"setMigrationAddress(address)","47337aab":"Btencoin()","4733a341":"SubmitClaim(address,string,string)","4733dc8f":"transferProxy(address,address,uint256)","4734922a":"generateOrderByAdmin(address,address,uint256,string,string,string)","473528b2":"_updatePurchasingState(address,uint256,uint256)","473533e6":"estimatedWeight()","47355ba5":"PiplToken()","47356bd9":"show_automated_Buy_price()","47356dd8":"getServiceUpdateAddresses(address,uint32)","4735b35f":"createDiamondAuction(uint256,uint256,uint256,uint256)","4735c747":"CrowdsaleToken(string,string,uint256,uint8,address,bool)","4735e00a":"CollectibleBought(uint256,uint256,uint256,address,address)","4736786b":"EthereumUnionToken()","47369a7c":"getPositionDeedHolder(bytes32)","4736b531":"TdeStarted(uint256)","47372325":"getChannelSize(address)","47373033":"enableStartBattle(string)","473753cb":"batchCancel()","47378145":"getBlockNumber(bytes32)","4737e852":"viewContractHoldingToken()","47387404":"_getGameStartAuctionMoney()","47395ced":"append(string,string,string)","473a223d":"getClosingTime(bytes32)","473aa2a5":"getFile(bytes32)","473ae9fe":"testCreateWithParent()","473b0d46":"setMinContribution(uint256)","473b4c53":"BrehonContract(address,address,uint256,bytes32,address,uint256,uint256,address,uint256,uint256,address,uint256,uint256)","473bc223":"gameName()","473bca32":"secondAllocation()","473ca96c":"win()","473e9408":"_getAttributesOfToken(uint256)","473edf73":"Award(address,uint256)","473f0117":"contributionID(uint256,address,uint256)","473f1803":"claimRewardForUser(uint256,address)","4740a08b":"getEggData(uint256)","474154bc":"divIsSafe(uint256,uint256)","47416aec":"setTokenContract()","4741b95c":"setPercentFrozenWhenBought(uint256)","47428855":"assertEq32(bytes32,bytes32)","47430b36":"parnter()","474448c4":"finishResolveFund(bytes32,string)","47448e8a":"set(bytes32,string,bytes32)","4746041f":"burnIndexedFrom(address,uint256)","4746cef8":"_confirmAndCheck(address,bytes32)","47471183":"freeOf(uint256)","474740b1":"batchLimit()","4748f7c2":"icoPhase1TimeBonusInPercentage()","47492352":"ROLE_PAUSE_ADMIN()","474a5a09":"AssetBackedToken(uint256,string,uint8,string)","474a88cb":"failsafe()","474b2541":"setRevision(address)","474bbab2":"calculateTokensToSend(uint256,uint256)","474c0868":"getActiveBuySize(bytes32)","474cdca2":"countTotalInvestors()","474ce368":"Computer()","474ce872":"promisee()","474ceb4d":"setCrowdsaleDate(uint256,uint256,uint256,uint256)","474d904b":"totalTokensWithoutBonuses(address)","474da79a":"contracts(uint256)","474e9e74":"MaxICOSellSupply()","474ea7e9":"Cyrus()","474f067f":"setType(bytes32,string)","474fa131":"extraMintArrayPendingProcess(uint256)","47516910":"FileHash()","4751757a":"Metronome()","475289da":"numberOfMoods()","475297bc":"closeBets(bytes16,bytes16,uint256,uint256)","4752a3ce":"StdUInt32(uint32)","47535d7b":"isOpen()","47540b31":"setTeamAddress(address,address,address)","4754a311":"StatusContract()","4754d136":"rerollFee()","47556b73":"isSuperInvestor(address)","4757ace4":"milestoneCompleted(uint256)","4757f1d2":"redeemAllOutcomes(uint256,uint256)","47582291":"totalstakeamount()","4758871d":"FOUNDER_EXCHANGE_RATE()","4758b9cd":"checkNumber()","47593ae7":"oldPrice()","475a2ac6":"mainSale(address,uint256)","475a9fa9":"issueTokens(address,uint256)","475abbb7":"PLATAMOUNT()","475b54c9":"AdvancedOwnable()","475b723a":"setRate362()","475c051d":"grantPermissionBatch(address[],string)","475c3001":"FinishTokenSale()","475c420c":"setHelpMeTokenParts(address[])","475c578c":"walletPercentage()","475c5ed1":"contributedToSTO(address)","475c7605":"ImpeachmentSupport(address,uint256)","475ca435":"get_record_by_row(uint256)","475d41f9":"SISKCoin()","475d599b":"wolf2Balance()","475e0062":"RoundEnd()","475e4c0f":"buscarDocumentoPorHash(bytes32)","475ec95a":"PRESALE_MINIMUM_FUNDING()","475fd055":"supplyLeftAtOrigin()","4760eee3":"getStartersProxyAddress()","47615fa1":"RankScore(address)","47625694":"getPerformance(uint256)","476343ee":"withdrawFees()","47635dac":"transferContract(address)","4763e3fe":"LOG_ZeroSend()","4766551d":"getExCoins()","47665ae8":"setMaxEthPerAddress(uint256)","4766ae68":"RareToken()","476711cb":"currentPeriodEtherCollected()","4767aeec":"_getaward(uint256)","4767d305":"EventCreateRisk(address,uint128,uint256,uint256)","476810b5":"ico1Min()","4768136e":"MelonWallet()","47683f00":"isInTier2(address)","47688c74":"userAmount()","47695e60":"MENTORS()","4769ed8f":"buyFromRC(address,uint256,uint256)","476a29e2":"pauseStateSwithcer()","476a4558":"DigitalMaterai(uint256)","476a73ec":"transferEthToMultisig()","476aa607":"saleHardCapReached()","476b7e3b":"readyToFulfill()","476c089a":"finalyze()","476c494c":"newAnswer(uint256,uint256)","476c9f41":"SecurityToken(string,string)","476d7c13":"userToNumCities(bytes32)","476e04c7":"NewMessage(string)","476e4aa4":"Remove(uint256)","476e6172":"getCurrentPlayer()","476fe919":"setReleaseTime(address,uint256)","4770ca3c":"AddBTCTransactionFromArray(address[],uint256[],uint256[],bytes4[])","47722218":"setKycAdmin(address)","4772eb77":"callDisableCallback(string)","47734892":"getUserBalance(address)","4773e0be":"didCloseLoan(bytes32,address,bool,uint256)","4774027c":"changeOffchainUploaderAddress(address)","477492dc":"MAIN_COIN_PER_ETHER_ICO()","4774ef06":"forwardGas(address,uint256)","47751b98":"validUpgradeId(uint256)","477523c2":"flushERC20(address)","47767c5d":"CRYPTOZOLToken()","4776ed69":"AngelTokensHolder(address,address,address)","477721e9":"FrozenContract(bool)","4777338c":"lastPricePaid()","4777c1f4":"setUnownedPriceInEth(uint256,uint256)","4777dbcf":"EternalStorageProxyForStormMultisender(address)","477801b1":"getLastRoundResults_by_index(uint256)","47786d37":"setCap(uint256)","47786f51":"HODL()","4778a5be":"orderSubmitted(bytes32)","4778dfb8":"balanceById(uint256)","47799da8":"last()","4779fad9":"setMentorsTokensPercent(uint256)","477a0eb3":"removeAtIndex(bytes32[],uint256)","477a7042":"getCanvasState(uint32)","477adb83":"eggtracker()","477af741":"firstMaxAmount()","477bda31":"qnt10k()","477bddaa":"setContractAddress(address)","477cdbb5":"create(uint256,uint256,uint256,address)","477ce277":"cost(address,uint256,bytes,bytes)","477d47b5":"viewPreSaleRefundsInMainSale(address)","477d6c6c":"_emitBoardCreated(uint256,bytes32,bytes32,address,uint256,uint256,uint256,bool)","477eab0a":"taxman()","477fe4e6":"payForTask(uint256)","477ff120":"addTokenAddress(address,address)","47803e97":"tokensOnHold()","4780eac1":"wethContract()","47810b3e":"LTY()","47816131":"EphronTestCoin(uint256,uint256,uint256,string,string,uint256)","4782f6fc":"removeOwners()","4783c35b":"multisig()","478573ca":"getMainWallets()","47858c79":"finalizedUpgrade()","478609f7":"mintTokens(int256,address,uint256,uint256)","4786cfea":"_estimateSupply(uint256,uint256,uint256,uint256)","47872b42":"unsealBid(bytes32,uint256,bytes32)","4787513a":"tokenHoldersCount()","4787e261":"calcQuickPromoBonus(uint256)","47883fd9":"product4_luckybuyTracker()","4788cabf":"getContractId()","4789aaef":"EthereumDice()","478aa69e":"unauthorizeUser(address)","478ae93c":"playToWin(uint256)","478b2f8b":"trieValue(bytes,bytes,bytes,bytes32)","478bdce2":"WinningNumbersEvent(uint256,string)","478c4238":"p_update_mResalePlotOwnerPercent(uint256)","478c4e0e":"resetData()","478cd032":"getLevelAmount(uint256)","478d2136":"proposalsByShareholder()","478db7e7":"getDataTrackingParameters(uint256)","478e25bf":"resetAction(bytes32)","478e7d7f":"getSponsorableJobs()","478f0735":"Jamatoken()","478f796a":"ownersWallet()","478f7b52":"mainSaleMinPaymentWei()","478f7eca":"CnytCoin()","47913dfe":"staticArrayChangeValue(int8,uint256)","47923d6f":"_addDividendsForAddress(address)","479245bb":"_transferOwnership(address,address)","4793017d":"stageLending()","47930567":"hashPosition(uint32,int64[2],bytes16)","4793504e":"Divider(uint256)","4793cebe":"allocateRemainingTokens()","479487e3":"getCar(string)","479564d5":"getAssociatedTAOSettingDeprecation(bytes32)","4795ac60":"collectPayment(uint256)","47963cf8":"COINEIUM()","47966bc2":"spam()","4797debe":"approveAmountAndSetFirstUseTime(uint256,address,uint256,uint256)","4797f21b":"setLog(address)","479834ca":"generateRandomMonster(uint8[14],uint32)","4798a2e3":"limorico()","47992b25":"DST_RESERVE()","479a4ae9":"isSHA256HashRegistered(bytes32)","479a5d53":"setOtherMigrationSources(address[])","479ad4c3":"removeListing(uint256)","479b321e":"CyberCash()","479ba3a5":"_resetPlayRound()","479ba7ae":"rewardsOf(address)","479d29f4":"BiyuleCoin(uint256,string,string)","479e24e6":"setNewInvestCommission(uint256)","479e393c":"getBettingStastics()","479e840f":"playValue()","479ed225":"getMyGameCompleted(address,uint256)","479f8d33":"threeHotHoursDuration()","479fb784":"approveBalancesWaitingKYC(address[])","47a08955":"_Deposit(address,address,uint256)","47a0fd7e":"shieldsUp()","47a11f26":"lIKETOKEN(uint256,string,string)","47a1a2d6":"usdCollected()","47a21679":"sellKeys(uint256,uint256,bytes32)","47a21eda":"buySharesFor(address)","47a22ca4":"devChangeMiningReward(uint256)","47a34bcb":"getBlockMaxVotes(uint256,uint256)","47a36afd":"totalFeeFlows()","47a42ff7":"buy_sale()","47a5046a":"isKYCRequiredToReceiveFunds()","47a5b1b3":"addApprovedContractAddress(address)","47a64f44":"lockAccount(address)","47a66b57":"addUserEndorsement(address,bool,string,string)","47a68cd4":"EOSBetDice()","47a69105":"NewSmartSharingContract(string,uint256,uint256,string,string,string,string)","47a69dfd":"Vegetoken(uint256,string,uint8,string)","47a6e601":"getATMHoldersNumber()","47a7aad5":"_vest(address,uint256,uint256,bool)","47a8205f":"privateWeiRaised()","47a90325":"maxCapEcosystem()","47a98ed2":"WithdrawFailed(address,uint256,bool)","47a99264":"setBwServiceValidCaller(address)","47a9fd81":"rob(address)","47aa7cd4":"setPoolStatus()","47aaf4eb":"resetOldAndSetNewDiscounts(uint256[],uint256[])","47ab58ec":"valuationAndCutOff()","47ac704f":"oldTokenSale()","47ad396b":"setFundingRules(address,uint256,uint256,uint256,uint256,uint256)","47aee603":"DIW(address,uint256)","47aef0a9":"battles()","47af954d":"creationAddress()","47af9957":"pauseTransfers()","47afa4e4":"change_pre_ico_start(uint256)","47b24f15":"LavaWallet(address)","47b272c0":"startMining(uint256)","47b27b8b":"unblockTokens(address,address,uint256)","47b27fd0":"testIsComplete()","47b3aff8":"bundles(uint8)","47b40ba2":"betFreeGame(uint256,uint8)","47b47102":"bakeCookie(string)","47b4e272":"depositBTC(address,uint256,uint256,bytes32)","47b4f943":"canmint()","47b55a9d":"pendingWhitelistAddition()","47b5acfd":"getProposalPublishedAt(bytes32,bytes32)","47b5dd54":"burnedTokens()","47b60ec0":"investorsGrantsAmount()","47b64eb0":"setServerAddress(address)","47b6ab59":"Token(address,uint256,string,string,uint8)","47b7142b":"safeSubtrZJF(uint256,uint256)","47b72b89":"getdeptmembershipstatus(uint256,address)","47b79a31":"remainingTransfered()","47b79a40":"manVault(uint256)","47b82bec":"FUTURAX()","47b84579":"getCompte_30()","47b87e48":"GetSaleInfo(uint8)","47b8b30b":"toCancel()","47b950b6":"setWorkerDtPort(uint256)","47b989af":"MyReferrer()","47b98c2e":"RDWToken()","47ba65d2":"get(bytes8)","47bafa82":"refundingComplete()","47bb0613":"deactivateContract(address,address)","47bb159d":"getByFromAndToCount(uint256,uint256)","47bb1883":"computeReward(uint256)","47bb89f0":"balance(uint256)","47bba01d":"inactivateSelf()","47bbe867":"purchaseMembership()","47bc1f94":"tokenSaleSupplyRemaining()","47bc3e51":"mintBounty(address[],uint256[])","47bc7093":"removeIssuer(address)","47bda66d":"createAMIS(address)","47bdb7f4":"transferDisable(bytes20)","47bdc8b4":"oraclize_query(string,bytes[5],uint256)","47bdeedf":"getPlayerUsableTokensCount()","47be11ae":"addArrayItem(address,string,string,uint256)","47be7bce":"formulaPrecision()","47bf7924":"ClaimSHIT(address,uint256)","47c05c22":"massSending(address[])","47c0ea6b":"_invest(address,uint256)","47c1303a":"MeetsOne()","47c14648":"claimTokenReserveLife()","47c17bac":"getMonsterDexSize(address)","47c1b5cf":"setGGEFee(uint8)","47c1caff":"getDividendsOf_(address,bool)","47c23bff":"setproduct(string,string,uint256,uint256)","47c3114e":"OpenContract()","47c35910":"authorize(address,address,uint256)","47c3ebf3":"is_presale_open()","47c421b5":"changeOracle(address)","47c51f73":"VisibilityDemo()","47c55045":"transferTokensFromTeamAddress1(address,uint256)","47c66140":"getProposalVotes(uint256)","47c6ecc0":"TokenFrozen(bool,string)","47c705b9":"Update(uint256,address,address,string)","47c7b6e2":"initEthDeal(bytes32,address,bytes20,bytes20)","47c7e6a8":"getAssetPackName(uint256)","47c81699":"set(string,string,uint256)","47c81f22":"TTT(uint256,string,uint8,string)","47c848e4":"_toPct(uint256,uint256)","47c85634":"setEmergencyWithdrawAddress(address)","47c8771c":"rsVerifyPoint(uint256,uint256)","47c8cc69":"getCurrentTDEBonus()","47c8efa7":"name1()","47c9301f":"erc20MRL(uint8)","47c98521":"rewardTheWinner(uint8)","47c9f9e8":"getNextTimeAirdropJoin(address)","47ca16a2":"setMaximumClaimPriceWeiRP(uint256)","47ca78d7":"paymentFallBack(address,uint256)","47cade2b":"unlockPublic()","47cb1b35":"getDailyJackpot(uint32)","47cb7a68":"timeLeft(uint256)","47cbc4f1":"HasNoElement()","47ccca02":"nft()","47cd3fda":"removeTransferRate(address)","47cda525":"TribeProducts()","47ce07d7":"NewPassManager(address,address,address,address)","47cf6f76":"isVotingActive()","47cf7e1d":"calcDoubleBindedBlindHash256(string,address,address)","47cfbaf4":"DMDPangea()","47d01637":"ProofOfCommunity()","47d04c71":"getWithdrawCount()","47d0dd3c":"COPIthereum(uint256,string,string)","47d1045f":"setNextSeedHash(uint256)","47d137c5":"unFrozen()","47d1d135":"setPixelColor(uint256,uint32)","47d20373":"stages()","47d289a9":"setDapCarToken(address)","47d3856a":"awardPot(string,uint256)","47d38af4":"NaNoDigitalToken()","47d3def9":"listAddress(address,uint256)","47d3ed10":"newDepositContract(address,address)","47d4106f":"CryptoSagaArenaRecord(address,uint8,uint8)","47d42c73":"PaymentStatusBlockNum(address,address)","47d52d86":"getMessageValue()","47d54bff":"finishedAt()","47d5d5b5":"ERC721TokenMock(string,string)","47d690b4":"limitDateCrowdWave1()","47d6cd6b":"_airdropAmount()","47d70f74":"icoEndBlock()","47d8167d":"buyBack(uint256,uint256)","47d83127":"sendFrom(bytes32,address,uint256)","47d84bab":"MultiSigStub(address[],uint256)","47d8fcb3":"emergencySetABackend(bytes32,address)","47d98eb4":"QUASI()","47d9b0aa":"FXTOKEN()","47da115a":"changeETH2Token(uint256)","47daf09c":"SmthToken()","47db0a24":"buyCreditsAndSpend(string,uint256,uint8,address,uint256)","47dd33fb":"VerumToken()","47dd5138":"EPSBets()","47dd5172":"perAddressCap()","47ddb165":"HODLIT()","47ddf87e":"allTimeJackpot()","47de074f":"getNodes(uint256)","47de3b76":"addSubmittal(bytes,address)","47df1cff":"callTokenTransferFrom(address,uint256)","47e0d54a":"winningTickets()","47e122dc":"earlyBirdTokenRate()","47e17101":"PRIZE_TOKENS()","47e17349":"addBonuses(uint256)","47e1d550":"getGameInfo(uint256)","47e20183":"point(address)","47e2688d":"getFinalSupply()","47e271b8":"getWeeklyLotteryParticipants(uint256)","47e2a6f9":"GetSellingTokenSymbol()","47e2b978":"RESERVED_COMPANY_UNLOCK_AT()","47e2d3f5":"zeroInt()","47e40553":"nextRound()","47e46806":"toString()","47e4ddf2":"createFreeze(uint256,uint256)","47e4e65e":"INFLIV()","47e51d38":"getConfigs(bytes32[])","47e57351":"withdrawTokensFromKingWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","47e5912a":"decreaseTokens(address,uint256)","47e5bec3":"closeTransaction(uint256)","47e60236":"setICOaddr(address,bool)","47e621b7":"backingToken()","47e6924f":"sanityRatesContract()","47e74409":"leadingGang()","47e7bce6":"roundStartedTimestamp()","47e7ef24":"deposit(address,uint256)","47e81c5f":"setBuildingContract(address)","47e87fcd":"maxSaleBalance()","47e9633c":"PaymentAuthorized(uint256,address,uint256)","47e99232":"doRebuy()","47ea13df":"setCurrentOwnerFeePercent(uint256)","47eacc78":"rateAngel()","47eafefc":"mainStartTime()","47eb86f1":"changeTokenPrice(uint256,uint256,uint256)","47ec8138":"transferWithLock(address,uint256,uint32)","47ec8d82":"AltSocialAccountPw(bytes32,bytes32,bytes32)","47ec8e21":"be()","47ecb665":"telegram()","47ed0112":"setAddressFundReferal(address)","47ee0394":"addToWhiteList(address)","47ee0a69":"decreaseApprovalInternal(address,uint256)","47ee2992":"COINS_PER_ETH()","47eeb75f":"claimMethodABI()","47eed11e":"test_fourInvalidFalseEqLog()","47eef00a":"issueUnsoldToken()","47ef01a1":"deleteRegion(uint256)","47ef55fe":"buyCore(uint256,uint256,uint256)","47f03d0b":"getFallbackDeposit()","47f07880":"ChatLinkToken()","47f1d8d7":"minBalanceForAccounts()","47f2748a":"getMixerTypes()","47f280aa":"DefaultToken(string,string,uint256,address)","47f3d794":"configure(uint256,uint8,uint256,uint256,uint256,uint256)","47f3dde5":"rewards(address,address,uint256,uint256)","47f4034a":"getUnitJadeStealingIncreases(address,address,uint256)","47f5666f":"getSanIdFromName(string)","47f57b32":"retract()","47f61a47":"Habits()","47f66790":"addThing(string,string,bytes32,bytes32)","47f66d15":"bestPromouterInfo()","47f67eab":"setActionPrice(string,uint256)","47f710a7":"free_transfer()","47f7af67":"sealdate()","47f7b304":"ownerApproves(uint256)","47f7d412":"withdrawFrozen()","47f8b863":"getNextCutoffTime()","47f95923":"alterPeerToPeerMarketplaceTransactionFee(uint256)","47f980e5":"claimTokenAddress(address)","47f9aa9f":"auditors(address)","47f9c371":"Proof_of_Stake()","47fa061e":"deposited(uint8,address)","47fa15e2":"ICOSuccess()","47fa1cbd":"evIssueManagementFee(address,uint256,uint256,bool)","47fa5648":"Minewar()","47fafe7d":"setAccountProvider(uint8,address)","47fb0bed":"checkSender()","47fc216e":"getEventsLength()","47fc4306":"contractWithdraw()","47fc822f":"setTargetContract(address)","47fdbfb7":"StageChanged(string)","47fee755":"getGeneralAttr(uint32,uint8)","47ff6d7b":"buildId(address,uint256)","480111b0":"potShare(address)","4801206e":"OodlebitToken()","480140ca":"checkSidePledge(uint256)","48016c04":"assertEqDecimal(int256,int256,uint256)","480184a9":"getNewToken(uint256)","48025070":"setGivenReadings(bytes32,bool,bool)","48027610":"transferPaidOut(address,address,uint256)","4803724e":"removeLock()","4803b482":"UpdatedBlockingState(address,uint256,uint256,uint256)","480443b7":"validateBSM(string,address,uint8,bytes32,bytes32)","4804a623":"getflag()","4804e06f":"firstStageMintingDate()","4804e1a2":"transferBlocked()","4804e2a5":"WalletConnector(uint256,address)","4805b069":"NCRToken()","4806249e":"badgerWallet()","4806a0bd":"declineTradeOffer(uint256)","4806b2d2":"getPoolPrices()","4807270b":"cancelOffer(uint16)","480744e0":"setOwnerAsAdmin()","4808bf1c":"paymentsByCustomer()","480a434d":"baseprice()","480b1f21":"rateWin()","480b70bd":"scheduleCall(address,bytes4,uint256,uint256)","480b890d":"setPercentRate(uint256)","480b9122":"DebugClock(uint256)","480b9707":"updateSecondWallet(address)","480bc31f":"getTotalPot()","480c6ca5":"getTokensIssued()","480d3b2f":"manualCheckInvestmentRequired(uint256,uint256)","480d7504":"getMineTokenAmount()","480e2f8e":"LastContributorChanged(address)","4810034a":"AirDropper(address[],uint256[])","48103077":"set_tokens_received()","48107843":"getNextCallSibling(address)","4811647c":"withdrawTip(uint256)","4811af4a":"preIcoMax()","4811c070":"team1Address()","4812663f":"nAuditorsRequired()","4813d8a6":"isAllowedToMint(address)","4813e3e5":"halvingCycle()","48144ef6":"BillHenryTestCoin()","481456f9":"probability()","48146113":"userDeposit()","48146341":"updateMaxGasPrice(uint256)","481531e9":"FeeToken()","48156d9c":"Loss(address,uint8,uint256,bytes32,bytes32,uint256)","4815ccea":"confirmAndForwardOnBehalfWithRevert(address,uint256,bytes,bytes32,uint256[2],uint8[2],bytes32[2],bytes32[2])","4815d4a9":"SECOND_SUPPLY()","4815d83f":"setBountyTeamUnfreezeTime(uint256)","4817c3e2":"_modifyTopUpLimit(uint256)","4817db70":"approveAndCall1(address,uint256,bytes)","4819d270":"approveRobot(address,uint256)","481a3fc4":"close(address,uint256,uint256)","481a4f2a":"fundLockTransferFrom(address,address,uint256)","481ae5d0":"setColdLedger(address)","481af3d3":"kittyIndexToApproved(uint256)","481b3dbb":"CentsToken()","481b659d":"permitPermanentApproval(address)","481c6a75":"manager()","481d3bd5":"setRegionUpdatedAt(uint256,uint256)","481dbaa4":"amountWithTip(uint256)","481ed14c":"YetAnotherUselessToken()","481ef4fd":"getAdPriceDay()","481f9555":"ALLOC_SC()","481fb72a":"numRentStatuses()","481fcbf4":"ApolloCoinTokenSale(uint256,uint256,uint256)","4820059f":"setDisallowedForMinting(address,address)","482076b6":"preICOHolders(address)","4820946a":"getContributorRemainingSaleAmount(address)","48224f67":"SUPPLY_FOR_SALE()","4822d008":"hexControllerAddr()","4825fc0d":"_ownerWallet()","48261921":"getLotteryPrizeInfo(uint256,uint256)","4826a425":"sub_codicefiscale(string,uint256)","4826e9c5":"UTC2MYT()","482717a4":"GetAddrCallQty(address)","482769f3":"distributeFunds(uint256,uint256)","482871ed":"_transferSigner(address)","4828a833":"MultiTransfer()","4828f4a2":"recover(uint256,uint8,uint256,uint256)","48293aae":"showKeys(uint256)","482961e1":"updateReading(uint256,uint256)","4829b393":"Tombola()","482a0bc9":"computeTokenAmountAll(uint256)","482ae8a2":"lastBlock_v8Hash_uint256()","482b27c9":"GetAdminAddress()","482ccedd":"_payFees(address,uint256,bytes4)","482d3af0":"allOwnerOperations(address)","482d51e0":"startNewGame()","482d7d5a":"_mine(uint256)","482da403":"buyme()","482f63b0":"postMessage(bytes32,bytes)","482fbae2":"_resultToRoll(string)","4830868b":"setPrWallet(address)","4830d5d9":"removeRestriction()","4830e266":"buyReferral(address)","4830e636":"setFreeClaimAllowance(address,uint256)","4830fd5f":"TotalLose()","48318cbc":"newIdTankProduct()","48330262":"priceIncrease_20_January()","48330cf6":"updateAvailability(uint256)","48335238":"FrozenFunds(address,bool)","48338323":"getRanomSecret()","48338756":"withdrawArbFunds()","4833c47c":"getTokenByBid(uint32)","483699f4":"tokensFor1EthP6()","4836f823":"salesRates(uint256)","48370565":"tradeValue(address)","4837715a":"___initialize(address,address,address)","48378eea":"getBool2()","4837e2fa":"amountOfLegs()","48389870":"cutToInvestorsDividendPool(uint256)","4838d165":"blackList(address)","483a15ed":"getManagerFor(address)","483a20b2":"setCrowdsale(address)","483a6cf9":"transferForExchange(address,uint256,string)","483a83df":"setKYC(address)","483b04e3":"angelExchangeRate()","483b1a76":"isInPassFilter(address)","483ba09e":"setBitcoinBridge(address)","483c8400":"MIN_FUNDING()","483c8abd":"UpSuccess(string,address)","483d31e9":"sfc(uint256,string,string)","483d45bd":"getProvider()","483d8b77":"onehour()","483e3956":"killPoll()","483e7872":"changeRealZipper(address)","483ea316":"bindOrderStakes(address,int256)","483eef18":"comminglerSellsProductSKUWithProRataIngred(address,uint256,string,uint256,string,string)","483f1b18":"MigratedTokens(address,uint256)","483f31ab":"consume(uint256)","483f5082":"getPriceTicket()","483f69c0":"HPToken()","483fa94b":"placeorder(uint256,uint256)","48401f1a":"joinBytes(bytes,bytes,bytes)","48403ad4":"preICOtokensSold()","48410f80":"hexToString(bytes32)","48419aed":"tokensRemainingStage1()","484293a7":"VertexCoin()","4842f639":"setBreedingAddr(address,address)","4843b358":"withdrawalsAllowed()","484412e5":"A5DToken()","48447983":"QiMingCoinToken(uint256,string,uint8,string)","4844f367":"placeBet(string,string)","484595fa":"encode(uint256,uint256,uint256)","4845d3f8":"closingTimeExtensionPeriod()","4845d40c":"withdrawATokens(address)","4846f559":"getIsWinnerSelected()","4847a79c":"_transfer(address,uint256)","48481979":"getHorsey(uint256)","48481b8a":"ElepigCrowdsale(uint256,uint256,uint256,address,uint256,uint256,address,address,address)","4848b1a5":"setData(uint256,uint256)","484916a3":"NewInvestor(address,uint32,uint256)","48498729":"_fetchOrdersForPayer(address)","484b8d33":"setWalletAmount(address,uint256)","484b973c":"ownerMint(address,uint256)","484c4056":"Redeemed(address,uint256,uint256,uint256)","484c8675":"allocateTokens(address[])","484c98af":"supplyAtIndex(uint256)","484cb173":"MiddleClass()","484db63f":"firstRate()","484dd086":"preFundingStart()","484dd472":"shobozilToken()","484ec26c":"onPayout(uint256,uint256)","484eccb4":"lastGen0SalePrices(uint256)","484f4bc0":"noStoresSet()","484f5a61":"GetChallengeInformation(uint256)","48509d2c":"updateCapsAndRate(uint256,uint256,uint256,uint256)","48519189":"MonedaAlcala(string,string)","4852a273":"setWhitelistStatus(address,address,bool)","4852e54b":"SolarNA(address[],uint256[])","48538112":"totalRaisedAmountInCny()","485458a1":"GetContractStageTermination()","48546971":"closeIco()","4854bde0":"pvt_plmt_set()","485587a2":"employeePoolTokens()","48558be7":"getOnTokenTransferValueValue()","48560630":"bonus3Ends()","4857d52d":"setLiquidityParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","48582a2a":"units40percentExtra()","48593bae":"getEnumValue()","48594f43":"powerAddr()","4859f430":"registerVehicle(string,string,uint8,address)","485ac9fd":"_canSetGameOver()","485c5e96":"generateTokensAll(address[],uint256[])","485cc955":"initialize(address,address)","485d5d7b":"TSTORZCv1()","485d5dd2":"DayInSecs()","485d7d94":"removeAuthorized(address)","485d992c":"getDoc(address)","485dc6cf":"create21KittiesTokens()","485e16a5":"summReserve()","485e35d3":"updateWhiteList(address,address,bool)","485e82d7":"tokenIdsForTeam(uint32)","485f2ce3":"AccendiCassaAutomatica()","485f7a7e":"preSaleAllotment()","4860165c":"destroyIdentifier(bytes32)","48601a7d":"getTxnNum()","486083fe":"itemLottery()","48612fc0":"IAHCToken()","486201ab":"deapprove()","48624e44":"ATTPlaceHolder(address,address,address)","4862e650":"setVerificationCodeHash(string)","48636254":"setWhiteBacker(address,bool)","4863ba17":"setLibraryAddress(address)","4863ed97":"setCoins(address,address)","48640aba":"phase1WeiRaised()","48642e21":"bleachDailyLimit()","4864d140":"baseAmount()","4864d8d9":"activeStage()","48650338":"withdrawDividends(address)","48655faa":"setMintingOracle(address)","486575a5":"reducePledgedFees(uint256)","4865a24a":"strToBytes(string)","4865c7bf":"timeInfo()","4866352b":"scrapCounter()","48664c16":"transferPreSignedHashing(address,address,address,uint256,uint256,uint256)","4867ec4f":"decodeParamOp(uint256)","4868204b":"FundTransfer(address,uint256,uint256)","48686205":"DevConSchoolReward()","48688367":"fundMintingAgent()","4868ab47":"Yumerium()","4869687b":"getAgreedMediators()","4869854a":"StfuTokenCrowdsale()","486a03e0":"approveMappingProposal(address,address)","486a7e6b":"burnAmount()","486b7217":"getnumber()","486c182c":"minAcceptEther()","486c363d":"_transfer_token(address,address,uint256)","486c50f3":"getDiscountHourglass(bytes32,uint8)","486d6aa8":"factorReward()","486de794":"_pay(address,uint256)","486e66da":"hungry(uint256)","486e97ad":"VLUToken()","486ea48d":"Nodes()","486fc7e8":"tokenOwnership(address)","48700c7c":"EVEN()","48709183":"bountyBeneficiariesCount()","4870b81d":"transferToWallet()","4870dd9a":"PERCENT_DIVISOR()","4871052b":"LogSignature(address,bytes)","48719120":"renewFarmerCertificate(address,uint256)","4871c4c1":"ownerWithdrawTo()","48724227":"KickOwned()","487260bb":"startBlockBonus()","487269fb":"VLCToken()","48727dca":"TradeBitToken()","4873c721":"_remainingBlocks(address)","48749616":"getPoolInformation()","4874a41f":"Tfarm()","4874e62d":"concat(string,string,string)","48758697":"getRarity(uint256)","487621cc":"addNewbond(uint256)","4876a339":"accept1(uint256,uint256)","4876f3e5":"comfirmRedeem(uint256)","48794149":"credosReserveAllocation()","487a5057":"getGameStart(address,uint256)","487a6e32":"deliver(uint64,bytes32,uint64,bytes32)","487a8043":"receiveApproval(address,uint256,address,bytes,bytes)","487a9e27":"USD_CAP()","487cd86f":"right34(uint256)","487e1d1f":"getNameOfAddress(address,address)","487f3f06":"team_address_count()","487ff8b6":"winningaddr()","48803406":"removeFundAccount(address)","48807db1":"getPI_edit_12()","4881148e":"safeGetPartialAmountFloor(uint256,uint256,uint256)","4881ae73":"add(uint16,uint16)","48823786":"allstocksFund()","4882419d":"isEpocum()","48839789":"ProofOfAIDS()","4883b6ce":"CryptoTorch()","4883c9dc":"prevHodlers()","48849c5a":"blockTransferFrom(address)","4884f459":"buyListing(uint256)","4885b254":"batchTransferFrom(address,address[],uint256[])","4885d732":"TokensAllocated(address,uint256,uint256)","488683f3":"_Token(string,string)","48868ac8":"sanityCheck(bytes32,bytes32)","4886d2d5":"setIsOver(bool)","48870630":"abi()","488725a0":"versions(address)","48887c8b":"setFreeAlien(uint16)","48889813":"mintedPercentOfTokens()","4888c619":"cryptocompareBtcOracleUrl(bytes32)","48894ad6":"FiveBalance()","488981cd":"countCourse()","4889ca88":"receiveApproval(address,uint256,address)","488a24c6":"isWalletContract()","488a6705":"AddConsentData(uint256)","488ab2c0":"TOKEN_EXCHANGE_RATE()","488b3538":"shares(address,bytes32,int256)","488b380b":"setLpIsStart(bool)","488bfa0b":"claimPaymentTokens(address,uint256)","488c1709":"setRefundAgent(address)","488c65fc":"stakeWithSignature(bytes32,uint256,uint256,uint256,uint256,bytes)","488c7951":"abstractFn(uint256)","488cec69":"tokensAreAvailable()","488dc208":"updateUrl(address,bytes32[5],address)","488ede8b":"getUserRating(address,address)","488f1e43":"getSellingInfoByIndex(uint256)","488f231f":"createAssociation(uint256,uint256)","488f3b6a":"tryCloseRoom(address,uint256,uint256)","488fdb81":"buyFrom(string,address)","48900438":"getAllowedAmountAndPendingPeriods(address,address,bytes32)","48906c27":"evaluateMany(address,uint256,uint256[],uint256[],uint8[])","48916211":"checkSigs(bytes32,bytes32,uint256,bytes)","48917d5d":"lastDrawTs()","4891c06a":"contributionPool()","4891f401":"PRICE_1()","4892f0af":"tokenPorter()","489306eb":"oraclize_query(string,string)","48931352":"TOTAL_SUPPLY_CAP()","4893de2a":"rewardUnicornAmount()","4893ed5b":"proposedUserKeyPendingUntil()","48940815":"doTriggerJackpot()","48941312":"CoinAdvisorCrowdSale(address,address,uint256,uint256)","4894e37f":"__callback(bytes,string,bytes)","48957fb8":"getAyantDroitEconomique_Compte_4()","4896672e":"updateSalePrice(uint256,uint256)","489667e6":"_isSynthesizingAllowed(uint256,uint256)","489807a5":"Donate(uint256,uint256)","4898556e":"SaleStopped(address,uint256)","4898722d":"setSink(address[],uint256[])","48989182":"ethMax()","489979a3":"allocateTopupToken(address,uint256,uint256)","4899e4c6":"addrDistribution()","489acecc":"requireMultiple(uint256)","489b1636":"icoPhaseCountdown()","489b5046":"GetBankerCandidate(uint8)","489ba092":"setNameLink(string,string)","489c1202":"isGuard(address)","489c14fd":"pathAdvisorVault()","489c18b0":"getLocksLength()","489d2104":"changePaymentContract(address)","489d2844":"notifyBuyToken(address,uint256,uint256)","489d426e":"ratePreSale()","489da639":"COIN_SUPPLY_COMPANY_TOTAL()","489e5656":"MAX_CANVAS_NAME_LENGTH()","489f3c88":"ping(address,uint256,uint256,uint256)","489fde35":"setEnforce(bool)","48a0c8dd":"isDepositable()","48a0d754":"available()","48a0fa29":"toggleTokenExchange()","48a15250":"setBurnRequestUintMap(uint256,string,uint256)","48a16b8c":"_itoa(int256,uint8)","48a1befb":"UserFactory(address)","48a3cbdf":"fundTeam()","48a46bd3":"isRejected(address)","48a490fb":"transferFromTreasury(address,uint256)","48a50a54":"saleClosedTimestamp()","48a54fc5":"checkContract(bytes32)","48a5d7bb":"AssetPool(address,uint256,uint256,uint256,uint256)","48a60b6c":"getPlayerBets()","48a73e96":"getFreeNapkins()","48a76740":"TokenData(uint256,uint256)","48a7f1f9":"proposeOfferingContract(address,address)","48a860dd":"confirmTransactionAfterExpiryFee(uint256)","48a87fa8":"emptyTTT()","48a8b427":"calculateShareCrystal(uint256)","48a935e2":"setIndividualCaps(address[],uint256[])","48a9866b":"kill(address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","48aa71f4":"isInCrowdsale()","48aac336":"getNumberOfParticipantsPerLevel()","48ab41d3":"getPOOL_edit_3()","48ac0f3c":"CORPORATE_SUPPLY()","48acce46":"ponziAddress()","48acd9b1":"changeFeeAccount2(address)","48ad5cd0":"product3()","48adfbdb":"getModerator()","48afc0fe":"FOMO3DLite()","48afd1b3":"hasReturns(address,uint256)","48afe4f5":"currentPersonalLimit(address)","48b15166":"blockTime()","48b17b64":"currSaleComplete()","48b24b88":"IAM_PER_ETH_BASE_RATE()","48b43020":"_setDistrictAddresss(address,address)","48b45d92":"isRequestApprove(bytes32)","48b49fa7":"buyGem(uint256)","48b4d3a4":"EmitTransactionIds(uint256[])","48b52c7d":"_transferFrom(address,address,uint256,string)","48b537ce":"MaggieToken()","48b5677f":"delegatedSignedRemittance(bytes,address,address,address,uint256,uint256,uint256)","48b59dd6":"changeCourse(uint256,uint256)","48b5b15c":"testHasCorrectPriceForMultistage()","48b5de18":"setEscapeHatch(address)","48b741de":"greaterPriceMsgComparator(uint256,uint256)","48b75044":"release(address,address)","48b84cde":"testCreateElectionOptions()","48b8ff83":"tokensForArtist()","48b9ed30":"getdisdone()","48b9f88f":"blockDiff()","48ba2d51":"LogBidRewardClaimed(uint256,address,uint256)","48bafd0e":"newGame(string)","48bb4067":"teamIssuedTimestamp(address)","48bb4347":"_checkOpenings()","48bc2a21":"bonusSecondIco()","48bc3e2a":"twoStepRate()","48bc4edf":"startAndSetParams(uint256,uint256)","48bd64c0":"getArrayHashLibry(bytes16)","48bdaaff":"TradeStatus(address,address,uint256,uint256)","48be4030":"INDToken()","48beae6a":"kkTestCoin1()","48bf51f5":"setInterestRatePunitory(uint256)","48bf9179":"Extradecoin(address,address)","48bf9cea":"serialNumberIsUsed(string)","48c0b782":"intermediariesCount()","48c0dc5b":"Inonit(uint256,string,string,string)","48c1ee9b":"wadmin_transferOr(address)","48c20a24":"getChildsAmount(address)","48c22f3f":"RateClient(uint256)","48c26e22":"purchaseRate()","48c2f845":"purchased_tokens()","48c40dbd":"transferTokensThroughProxyToContract(address,address,uint256)","48c44712":"refundERC20(address,address,uint256)","48c4cae9":"setNameReaderId(bytes32,bytes32)","48c4d7ce":"descendingCount()","48c54b9d":"claimTokens()","48c5be67":"numDistributionsRemaining()","48c6af04":"test_oneInvalidEqString()","48c6e2f7":"BaoFengCheng(uint256,string,uint8,string)","48c7a0bf":"SharePrice()","48c7f438":"setOldest()","48c81c16":"GamersToken()","48c834c0":"tier4Rate()","48c875cf":"resetRequest(string)","48c8cd41":"dateTime()","48c91284":"setM1(address)","48c981e2":"sendEther(address)","48c9ecf8":"allowTokenOperations(address)","48cb5aeb":"Easticoin(uint256,string,string)","48cc38e1":"nestedFirstAllToAll2(uint256)","48cc7b6e":"startForge()","48cd4cb1":"startBlock()","48cd65d9":"getInPlayGames()","48ce382d":"addActivityAccount(address,uint256,string)","48cebd67":"presaleSold()","48cf9e5c":"getGroupIndex(uint256)","48cfa939":"minContribution_mBTC()","48cfc6c6":"crowdSaleEnabled()","48d0aff3":"drainexcess()","48d21789":"burnFunction(address,uint256)","48d24f35":"transferMintingAddress(address,address)","48d26dd1":"finalizeType()","48d2df48":"userBuys(address)","48d317ce":"stepTwo(int256)","48d34bc6":"getHashInternal(address,uint256,uint256,uint256,uint256)","48d37a58":"withdrawPrize()","48d453ee":"gcEndTime()","48d47e7e":"clc()","48d4eaf7":"storeData(bool,uint256,address,bytes32,string)","48d51a0d":"submitProposal(bytes32,uint32,uint32)","48d597e5":"addFromMapping(uint256,uint256)","48d5a5c0":"consensusAddress(address)","48d6002a":"otherPlayer(address,address[])","48d6047c":"WhitelistWalletUpdated(address)","48d64fd5":"changeTradeTracker(address)","48d6ca55":"getChangeFeeAmount(uint256)","48d7de63":"setTenant(bytes32,address,uint256,string)","48d82608":"InvestmentPolicyChanged(bool,bool,address)","48d848d0":"returnBoolean(bool)","48d8bb3f":"setIco(address,address)","48d9614d":"GetFee()","48d9a374":"blockTransfer(address,uint256)","48da08e6":"SilverCoin()","48da1532":"node_side(uint256)","48da60af":"limitClosedSale()","48da95b8":"VirtualExchange(address)","48db409a":"createContract(bytes32,uint16,bytes32,uint256,uint64,bytes32,uint64,bytes32,uint64)","48db5f89":"player()","48ddc01f":"changeFisherMansFeeCalculator(address)","48dddca8":"minSpend()","48de0cdc":"withdrawInBatch(address[],address[],uint256[])","48dfe175":"tier3Total()","48e021e9":"weiCostOfToken()","48e06300":"isEquipedAny2(address,uint256,uint256)","48e071d4":"denyUser(address)","48e0f410":"fundRaising()","48e11f70":"OMGCatCoin()","48e12ae3":"getAllowancePeriod()","48e1a760":"getttttttt(uint256)","48e1c18b":"itemsOwned(address)","48e252ab":"CryptoMilitary()","48e25bd2":"WinToken()","48e278f9":"NauticusToken()","48e37220":"presaleDateStart()","48e3a033":"mulPay(address[],uint256[])","48e3a064":"StandardCampaign(string,uint256,uint256,address,address)","48e4e297":"allowedToPurchase()","48e591ac":"getVote(address,address,uint32)","48e5c71f":"whoIS(string,bool)","48e61782":"left4(uint256)","48e66722":"getRedeemRequestsLength()","48e68e30":"synthesizeWithAuto(uint256,uint256)","48e6b393":"test_logs()","48e7575d":"ecrecoverFromSig(bytes32,bytes32)","48e76563":"oraclize_setNetworkName(string)","48e7a100":"reparametrizeMultisig(bytes32,uint256)","48e837b9":"createGame(uint256)","48e9657d":"getSignatureAtIndex(string,uint256)","48e9f1ea":"EPXCrowdsale()","48ea97be":"tokenSalePausedDuration()","48eaa435":"safeExp(uint256,uint256)","48eab053":"fourthTeamWithdrawal()","48eaeb72":"BPCC(uint256,string,string)","48eb76ee":"attacker()","48ec8a0c":"getSecurityLimits()","48ed190a":"lastBlock_f11()","48ed1e3b":"LookUpAvailableDivInt(address)","48ed3e00":"date610()","48ed994c":"newLottery(uint256)","48edbf1d":"SKS()","48ef245b":"createFaucet(string)","48ef5aa8":"UpdateMaintaining(bool)","48ef670e":"UportRegistry(address)","48f05187":"scheduleCall(address,bytes4,bytes,uint256)","48f082e8":"dayToMinusToken()","48f0b8e3":"getNumberOfGamesCompleted()","48f134f6":"closeSetup()","48f1e9c2":"getCertificationDocument(address,uint256)","48f2090b":"distributionPercent()","48f213e0":"PER_USER_AMOUNT()","48f221b6":"changePartner1(address)","48f36144":"claimOracle()","48f3e6f4":"getFourthAddressBalance()","48f549a4":"CreateToken(address,uint8,uint16)","48f6647b":"matchWithTheirs(uint256,uint128,uint16)","48f69212":"YELLQASH()","48f7f2a3":"daoFactory()","48f83e86":"authorizeAccess(address,address)","48f8fe69":"fnv(uint256,uint256)","48f918e0":"reclaimLeftoverEth()","48f95a7d":"depositsCountForUser(address)","48f9e246":"requestImplChange(address)","48fab2b0":"emitOracleUpdated(address)","48fb7332":"INTREPID_MAX_PRICE()","48fc66e9":"NzmLToken()","48fcb4e8":"getFrozenAccountCoinCount(address)","48fdb8c1":"partnernames()","48fee60f":"Criptohubcoin()","48fefd9b":"supportsToken(string,address,address)","48fefed2":"setNewGreeting(string)","48ff05b8":"removeUint256(bytes32)","48ff0c47":"testF4(uint256)","48ff1387":"rebuy(uint256)","48ff15b3":"acceptManager()","48ff30ff":"Breakup(uint256)","48ff6525":"applyRedenomination()","490052a8":"playerRoll(uint8,uint8)","49007329":"CCCRSale(address)","4900b48c":"checkOracle(address,address,address,bytes32,uint256[])","4901a205":"canShelf(string,address)","490203a7":"getMiningReward()","4902d163":"pendingOwnedOwner()","4902e4aa":"removeSuperAdmin(address)","490377a7":"setParameters(address)","4903c401":"Admins(address,address,address)","49041903":"getGame(uint64)","49044cc5":"premiumValue()","49051c1d":"threshold2()","49055da2":"getCurrGameInfoPart2()","4905c5b0":"_isUserInGame(address)","4905c769":"newLoan(bytes32,bytes32,bytes32,address,uint256,uint256,uint256,uint256,uint256,uint256,address)","490618d1":"deregisterBroker(address)","4906da1e":"getMaxEther()","4907cd0f":"subscribe(address,uint256,uint256,uint256)","490825a9":"testControlTransferEnableNotTransferable()","49082bef":"TWO_YEAR_KEEPING()","4908d1de":"allUnsoldTokensAllocated()","490a32c6":"message(bytes32)","490a65c8":"PlutonDistribution()","490a6dac":"setWinner(uint256,bytes32,uint256,uint256,bytes32)","490b4f92":"coinAgeForAddressAt(address,address,uint256)","490bf04f":"rateToEther()","490c58f0":"addTokenTo(address,uint256)","490cce74":"FincontractMarketplace()","490d6d11":"Resume()","490e25c1":"C4FEscrow(address,uint256,address,uint256,uint8)","490e2bd1":"Autolen()","490f027a":"setPrizes(uint256[28])","490f611e":"Or(bytes32,bytes32)","490fc399":"votedKickoff(uint256,address)","490fdbd7":"transferTile(uint16,uint16,uint8,address)","490fea4d":"addBounty(address,address,uint256)","491045af":"LifeSet_002()","491274a8":"presaleContributorCount()","49135b0f":"getAllAlgos()","4913732e":"buyTokenFromModerator(uint256,address,uint256,bool)","49137bca":"reading_cards()","4913ec88":"EnergisToken()","49144618":"Wasted(address,uint256,uint256)","4914fb27":"approveWithdrawal(address)","4915ef4a":"refund_contract_eth_value()","49164b41":"CryptoDivert()","491737f2":"ico3cap()","491759aa":"sendEthTweet(string,string,string)","4917c302":"ACCEPTED_AMOUNT()","4918d588":"test_BondPostedAndOverMajority()","491a6155":"REFERRAL_BONUS_PERMILLE()","491a7904":"transferTokenTo(uint256,address)","491abe0c":"servicePayment(uint256)","491b0712":"snpb(uint256)","491b8c45":"setWARTokenAddress(address)","491c8e08":"lastBlock_a6()","491cfc1c":"setNextRoundDuration(uint256)","491d525a":"pMintTokens(uint256,int256,address,uint256,uint256)","491d75f4":"configurationTokenTranchePricing(uint256[])","491dcfe9":"batchActive()","491e0df0":"totalContributorsContribution()","491e55db":"GAME_COST()","491e74f3":"YICHAINCoin()","491eeb3a":"resumeInvest()","491fd263":"updateMessage(uint256,bytes32)","49200d77":"numberOfOutcomes()","4920781b":"GATcoin(uint256,string,string)","4920adcc":"MysteriumCrowdsale(address,address,uint256,uint256)","4920ff15":"SetHome(string)","49212c92":"preValidateChecks(address,uint256,uint256)","4921a91a":"giveMe()","4921cea6":"transferFeeOwner()","4921e147":"setMinWeiToPurchase(uint256)","4921f9e9":"AnonReport(uint256)","4922d481":"recovery(address)","49231598":"fetchAllVotersBySnapshotBlock(uint256)","49231b28":"changeRates(uint256,uint256)","49239e10":"refundStageStartTime()","492430f6":"DissolutionRoom(uint8,bool)","4924d397":"Respond(address,uint256)","49251b18":"FrozenFunds(address,address,string)","4925480e":"fireAdmin(address)","49260304":"nDEX()","4926248f":"setListener(address,address)","49264032":"Spendcoin()","49266f2f":"maxBidEth()","4927f408":"Vertex_Token(uint256,address,uint256)","49285b58":"getVotingToChangeKeys()","492abc67":"signerIsApproved(bytes32,bytes)","492b3bf7":"baseTokenCapPerAddress()","492b67ea":"Etherdoc()","492b8d45":"POWToken()","492bd276":"getIntervals()","492c0325":"calculateNewRate(uint256,uint256)","492c70fb":"swipeToken()","492c981b":"entryInformation(address,bytes32)","492cc769":"buy(string)","492d06cf":"unFreeze(uint8)","492dda05":"reTweetReward()","492e333f":"allocate5ProjectToken()","492e672e":"DCETToken()","492eec25":"bountyOfflineTokens()","492f190d":"availableCommission()","492f8724":"subscriptionStatus(uint256)","492fb343":"feeBeneficiary()","492fea53":"_createPet(uint256,uint256,address,uint256,uint256,uint256,uint256)","4931b3b4":"setData_30(string)","4932a80b":"unownedPlanet(uint256)","4932ce32":"changeGame(address,uint256)","4932f35e":"NomToken()","49330cb8":"getVote(uint256,uint256)","493322c0":"calculateRewardInternal(address,address,uint256)","49336245":"getEntry(bytes)","49337227":"testCanCloneAfterTransfer()","49339f0f":"Delegate(address)","4934453a":"TPIToken()","4935b3b6":"PDTC()","4935e740":"withdrawMyFunds()","49361cfe":"lastInvestmentTime()","493770cc":"setTransferStatus(bool)","4938649a":"stopEverything()","49386f26":"getlistedItems()","493953de":"addOwnToken()","49399729":"minimumBidAmount()","4939bfde":"requestedBy()","4939ce85":"CLASS_BEAST()","493a64e4":"SetParticipantRole(address,address,uint8)","493a7209":"stopBuy()","493a8d0c":"tokenActive()","493b284e":"exchangeNominsForHavvens(uint256)","493bccc8":"awardMissedBlockBonus(address,bytes32)","493ca31a":"EPAYCLUB()","493caeea":"removeMemberWithAddress(address)","493dbd02":"forceEndGame(address)","493f8d30":"read_demurrage_config_underlying()","493fcf1c":"taxRateNumerator()","49403183":"isPassed(uint256)","49404d25":"lastBlock_v13()","494054f4":"createNota(string,string)","49407a44":"claimEther(uint256)","4940c807":"sumElements(uint8[])","49416e45":"RCD()","4941d059":"editRestrictedAddress(address,bool)","4941d296":"periodITO_startTime()","49420759":"changeWithdrawable(uint256)","494278e3":"getgamecardaddress(uint256)","4942a71f":"getFromBank(uint256)","49432923":"participationHistory(address)","49433942":"PointerChanged(uint8)","49435c0d":"whitelistSupplier()","49437210":"getUpdatable(bytes32)","49440b91":"lockMntpTransfers(bool)","49441fc3":"MIN_ETHER_CONTR()","4945a575":"childApproved(address,uint256)","494630cd":"PullRequestAlreadyClaimed(uint256,uint256,bool)","49463b8e":"SeeleToken()","49465a50":"changeTakerDeadline(uint256)","49465d33":"lastPriceFeed()","4946c574":"getTransformMineInDay(address,uint256,uint256)","4946e206":"rescueCat(bytes32)","4947c8d0":"setFinishTime(uint256)","49480bc1":"releasePrivilege()","49484450":"ProofOfNoSnipers()","4948c2db":"stage4_price()","4948d91d":"SicBo(address)","4948e51a":"freezeToken(address,uint256)","49499e14":"setCompte_15(string)","4949d9fa":"bankrolledBy(address)","494ac14c":"LOTTERY()","494b46f9":"_changeAdmin(address,address)","494b5e0f":"setUserFactoryContract(address)","494b90e8":"teamPoolAddress()","494bf608":"distributeEther()","494c2a0f":"STQCrowdsale(address[],address,address)","494cf333":"getAddressUIntMapping(address)","494cfc6c":"getTokens(uint256,uint256)","494d93cc":"result_block()","494e49a4":"createAccountWithBalance(string,uint16)","494e4bc3":"fundtransfer(address,uint256)","494fb622":"SetData(uint256,string,string,string,string)","494fee7d":"estimateDistribution(address)","4950b392":"exerciseCall(uint256,uint256,uint256)","49517b41":"addSolution(uint256,string,string,string,string,string)","4951a18f":"crowdsaleCap()","495289be":"setIssuer(address,bool)","4952d2dd":"logPromiseUnfulfillable(uint256,address,uint256)","4953b57d":"isAdminOwnersValid()","49550d66":"tryTakeBack(uint256,uint256)","4955a79e":"transferOwnershipOperation()","4955f280":"createContractPerson(string)","4956cf1c":"migrating()","4956eaf0":"deploy(address,uint256)","49570293":"_addPurchasedTo(address,uint256)","49573edd":"tgeSettingsChange(uint256,uint256)","495816b4":"BOUNTY_TOKENS_AMOUNT()","49582509":"ICO_ON()","49582a20":"initializeSupply(uint256,uint256,uint256)","4958abb7":"switchFeePolicy(bool)","4958ace2":"restartSale(address)","49593f53":"submit(string,uint64,uint32,uint32,bytes32)","49596a65":"initProject(string,string,string)","495b3bcc":"LSEscrowContract()","495bbcae":"testNeededBalanceForContractCreation()","495bf26b":"lengthOf(string)","495c167f":"sumPayments()","495c5891":"getTotalAuthorizedForPayment()","495c9588":"minEligibility()","495ccca3":"WEEFundWallet()","495d32cb":"par()","495d7b26":"processScore(bytes32,string)","495df195":"CollectEarning()","495e1b3d":"etherEscrowAddress()","495f9bae":"getProposalVoterVotesCount(uint256,address)","495fe25b":"transferTo(address,uint256,bytes)","49602f5c":"OpusToken()","49606455":"take(bytes32,uint128)","49606d51":"Nihilum()","4960ae42":"numberOfVerifiers()","4960d2bc":"getLandTaxRate(uint256)","496128ec":"prosperaToken()","49614e91":"isRegisteredAddress(address,address)","4961b40c":"getReleaseValidator()","4962aa66":"discountedRates(uint256)","4962ab01":"removeMembers(address,bytes32,address[])","4962ad08":"approveAlgo()","4962b964":"getPuppetCount()","49630dda":"removeQuestion(address)","4963513e":"Reserved(bytes32,address)","49649fbf":"withdrawAllFunds()","4965fc89":"getForfeited(address)","49661fcf":"stage2Tokens()","49671d28":"setAmountSoldPerPeriod(uint256)","496a698d":"currentAuction()","496bd844":"round_up_division(int256,int256)","496be2cf":"atxControllerAddr()","496c4fad":"setPriceAgent(address)","496c5ad8":"throwsWhenGettingTokensWithStoppedSale()","496e41d2":"quotaUsed(address)","496fbeb3":"transportationFeeMultiplier()","496fc976":"setC4FContractProvider(address,address)","496fd2c5":"ICOStartToken(uint256)","4970fb36":"armagedeon(address[])","4971129d":"CatTransfer(address,address,uint256)","49713811":"winnersCount()","49714815":"ownerKillContract()","49716f5a":"originalTotalWeight()","4973219d":"outputi(uint256)","497347b2":"_storeContent(address,string,uint256,bytes32,address)","4973dbf6":"RATE_ETH_CUE()","4973dd25":"unBlockExternalTransfer()","49741098":"admin_set_min_pay(uint256)","497484f6":"applyBonus(uint256,uint8)","4974af1f":"testPublic(uint256[20])","4974bc27":"download()","4974da81":"addWord(string)","49752baf":"chronoBankPlatform()","49755b9e":"issueSynths(bytes4,uint256)","4975d202":"balanceOfOwner()","4975e893":"getProposalCreatedAt(bytes32,bytes32)","49776581":"getDocumentUpdatedVersionId(uint256)","497777d5":"collect(bytes32)","4977d6a4":"DreamToken()","49786571":"Economeme()","4978ddcc":"transferAPIOwnership(address)","4979440a":"getHighestBid()","4979c012":"ClosingTimeForCloning()","4979d6ec":"setUserManagerContract(address)","497a7b48":"taskRewardVote(bytes32,uint256)","497aed49":"PRIMARY_START_PRICE()","497b383e":"buyReferTokens(address,uint8)","497b8018":"getBallotOptNumber()","497cc504":"claimE()","497cd327":"TMONEY272708()","497cd426":"updateRewardDistributor(address)","497d709d":"icoNumberBalanceOf(address,uint256)","497dbce9":"_assertAmount(uint8,uint256,uint256,uint256,uint256,uint256,uint256,uint8,uint256)","497dd0cb":"migrateContributors(address[])","497f3132":"getLastRegistration(string,int256)","497fb5b9":"tokensWithdrawn()","498022ea":"evalTransitionState()","49813e26":"MenovaToken()","4981b3ca":"performSell(address[8],uint256[6],uint256,uint256,uint8,bytes32,bytes32)","49843982":"Coin(uint256)","4985acee":"getTransferFromToValue()","4985b325":"addSurplus()","49866ec0":"finishTokensSale(uint256)","4988ef98":"LOCK_TOKENS_DURATION()","4989ae8e":"RESERVED_TOKENS_FOUNDERS()","4989b0b6":"setCustomBuyerLimit(address,address,uint256)","498a37f0":"setSmallInvestor(address,uint256,uint256)","498a3944":"setNameWriterId(bytes32,bytes32)","498a4c2d":"startBlockNumber()","498a690f":"issuingRecordAdd(uint256,bytes32,uint256,uint256,uint256,string,uint256)","498a6de7":"setRevenueContract(address)","498b7718":"J8T_DECIMALS_FACTOR()","498be109":"FAPFounderFund()","498c07f3":"startCrowdsale1(address)","498cb7cb":"setDelegadoDeEscuelaVerify(bytes32,uint256,uint256)","498cc70d":"getResult(string)","498d2ae0":"getMintRequestAddressMap(uint256,int256,string)","498e78b1":"unregisterManager(address,address)","498e87a9":"setPI_edit_21(string)","498eecb2":"getLimitedReportersDisputeBondToken()","498f27ae":"countCampaigns(address)","498f6fbe":"NewSubscription(address,uint256,uint256)","498fd833":"priceDT()","498ff49a":"repayImmediately(uint256)","49911610":"getDay(uint16)","49912f88":"appeal(uint256,bytes)","49917511":"buyCoinsCrowdSale(address,uint256,address)","49926028":"typeHash()","49937e25":"buyPrimordialToken()","49942483":"ICO_PHASE2_BONUS_PERCENTAGE()","49942ccb":"scheduleCall(bytes,bytes,uint256,uint256)","49943a13":"PARTICIPATION_FEE()","49955431":"cupi()","4995b458":"week()","4995e9fb":"FOUNDER_ADDRESS2()","4996e899":"getGuaranteedContributorsLenght()","49970e16":"forwardPlay(address,address,bytes,bytes32,bytes)","499831f2":"pauseGame()","4998ce40":"setbonusTokens(uint256)","49996698":"trustedAddressSize()","499a1bcd":"setAQL(address,uint256)","499a8fea":"setClue3(string)","499ac979":"redistributeTokensForAddresses(uint256,address[])","499af77c":"current_spin_number()","499caf09":"secondTime()","499cd176":"endAttack(address,address,bool,uint256,uint256,uint256,uint256)","499cf7ce":"BOXEX()","499d1081":"mint(address,uint256,uint128)","499dae56":"getMultiRequestRequestor(uint256)","499e2c81":"getOrCreateWaitingBoard(uint256)","499e6c10":"isTheContract()","499fa529":"ALLOC_SALE()","499fd141":"getDrupeCoin()","499ff236":"maxAnonymousContribution()","49a0a3b3":"resetTokens(address[],uint256[])","49a0c976":"unlockEmission()","49a0e681":"rst()","49a24a7d":"DolyToken4()","49a3d2bb":"updateAllowed(address,address,uint256)","49a51839":"EGGS_TO_HATCH_1LOBSTER()","49a634f0":"LTS()","49a67b55":"commitStart(bytes32)","49a69078":"lastBlock_f5()","49a6a4de":"showAssetInfo(bytes32)","49a742eb":"validRate(uint256)","49a76444":"Hygen()","49a7a26d":"solver()","49a86c9e":"addToAccesslist(address)","49a8d337":"lockedTeamAllocationTokens()","49a92910":"setPlayer(address,uint64,uint64,uint64,uint64,uint64,uint64)","49a9d5ad":"CGENToken(uint256)","49aa480a":"VixCoin()","49aa4ee2":"removeVote()","49aafad7":"allowedToBurn(uint256)","49ab1d86":"setGeneLab(address)","49abee50":"phaseStart()","49abf2d6":"staticoins(uint256)","49acce72":"AnkitVictoContractToken()","49adf14f":"Claim_TRAC_1850()","49adf314":"_updateDividends(address)","49ae1f17":"KWHToken(address,address,address)","49ae9b31":"canReadName(address,bytes32)","49af0af1":"baseEthCap()","49af63a9":"setWaitTime(uint8)","49afc6e5":"tokenBalance(uint256)","49afcc0e":"dataSourceGetSemiResult(uint256)","49b11f24":"dailyAuctionStartTime()","49b1b2d9":"newBonus_and_newPeriod()","49b2f5ff":"technicalCommunitySupply()","49b3b29f":"costs(uint256)","49b40402":"exchangeThreshold()","49b48e66":"setCheckOwner(bool)","49b54685":"updateDps(uint256)","49b5b541":"compute(address,uint256)","49b6313c":"getCurrentSellOffer(uint32)","49b71e47":"distributeWinnerPool(string,uint256)","49b76501":"getStorageRate()","49b7a9c2":"dividendManagerAddress()","49b7ef6c":"lockedSell()","49b85a16":"kycAddress()","49b88203":"declareProjectDefault()","49b88919":"setImageDescriptor(uint256,uint16)","49b8f5d9":"tokensDuringPhaseOne()","49b90557":"isAuditor(address)","49b9734d":"changeMainEndTime(uint256)","49b9a2d0":"address_to_tickets(address)","49b9a7af":"lastPriceUpdateTime()","49ba5a48":"checkSavedEthBalance(address)","49babd2a":"initiate(address,uint256,bytes32,address)","49bac542":"E4RowEscrowU()","49bedf42":"setLookup(address)","49beee4f":"adjust_Transfer_nodata(bool)","49bf2caf":"disputeTransaction(uint256)","49bf66d3":"addRegistryIntoNameIndex(address)","49bfb061":"txFeeDenominator()","49bff0d7":"setPI_edit_29(string)","49c03373":"changeGTOAddress(address)","49c04f27":"WorldBitEvent(address,bytes2,bytes2,uint256,uint256,string,string,string,string)","49c15bd9":"Purchase()","49c16cc3":"CMCLToken(uint256,string,string)","49c16e15":"toUint()","49c1ad0f":"gotoNextState()","49c1d54d":"trusteeAddress()","49c2a1a6":"createProposal(string)","49c3567c":"ArbaCoin(uint256,string,string)","49c37f8c":"main(address,address)","49c3a91e":"getSponsorshipsTotal(address,uint256)","49c462d7":"createInvite(bytes)","49c53b2d":"doMidnightRun()","49c6353c":"getInvId()","49c71fa8":"unholdTeamTokens()","49c7634f":"WorldwideGiftCode()","49c83e86":"unlist(address,uint256)","49c91267":"getSeedByWinner(address)","49c9d17a":"updateReceivers(address[])","49c9dcf5":"awardRafflePrize(address,uint256)","49ca30ab":"receiveIndex(uint256,uint256,uint256,uint256,bool)","49ca7656":"changeOwnerOfMonethaUserClaimStorage(address)","49ca8cc9":"getEventId(address,bytes32)","49cacb12":"dropOwner(address)","49cbe338":"tryRead(uint64)","49cc2eb1":"Fairsale(uint256,uint256)","49cc635d":"receivePlayerInfo(uint256,address,bytes32,uint256)","49cc8513":"_geneOfCrab(uint256)","49cc954b":"twoYearsPassed()","49cd4554":"afterIco(uint256)","49ce0a11":"hexToken()","49ce5804":"setSectorOwnerCut(uint256)","49cf211e":"storenumber()","49cf2eae":"certifierAddress()","49cf5f1b":"DSProxy(address)","49d0cd85":"functionSignatures()","49d10b64":"updateRegistry()","49d246e5":"getBetBasic()","49d24ae8":"withdrawAdmin(uint40)","49d2ca11":"Election(address,address,address,address,address)","49d3060f":"selectWinner50()","49d45693":"changeminprivatesale(uint256)","49d463e6":"sendBoard(bytes10,uint256,uint8,bytes32,bytes32)","49d4a344":"right99(uint256)","49d55d9d":"receiveTransfer(uint256)","49d596fe":"FSM()","49d689f4":"setJackpotAddress(address,address)","49d7e0b3":"mutiTransferFrom(address,address[],uint256[])","49d800a1":"ReleaseableToken(uint256,uint256,uint256)","49d834cd":"TSTEST()","49d8ef13":"ETHERFUNDME_ONLINE_FEE()","49d94871":"bonusRates(address)","49d94c83":"CappedCrowdsale(uint256)","49da847b":"iPay()","49daca7a":"tradeAddress()","49dbdf30":"initializeRefund()","49dc2b83":"miningFinished()","49dc5376":"getTokensBack(uint256)","49dc8fab":"Menu06(address,address,uint256)","49dcbc5e":"sendEth(address,uint256)","49dcd756":"getCurrentEthCapPerAddress()","49dd0fe3":"minechain()","49dd1262":"updatePrices()","49dd2880":"Gold(address,uint256)","49de0485":"addContributorManually(address,uint256,uint256)","49de3995":"EthlanceMessage(address)","49df7208":"addMember(address,bytes32)","49df728c":"withdrawTokens(address)","49e09da6":"genesisTransfer(address,uint256)","49e0cf2a":"createComunity(bytes32,bytes32)","49e0dada":"level_4_percent()","49e123c8":"monsterHealth()","49e1432c":"donateToPot()","49e1c2b7":"ATMToken()","49e284d1":"ZoologicalGarden()","49e347ae":"getContents(uint256[],uint256)","49e4347b":"completeICO()","49e44f44":"ManagerProxy(address,bytes32)","49e4b3e5":"setPermissionManager(address)","49e51970":"CostilNetworkToken()","49e588df":"refundSubmission(address,uint256)","49e627d2":"getPreIcoTokenHoldersAddressesCount()","49e65440":"setSymbol(bytes32)","49e67544":"TeamFund()","49e6c454":"getMyEntityOwner(uint256)","49e77c8b":"hasEnoughTokensToPurchase(address,uint8)","49e9449a":"presalesCap()","49e9cee9":"GetMaxPrestigeLevel()","49ea33df":"icoEndDatetime()","49ead9b4":"createAsset(string,uint256,uint256)","49eb6d6f":"NumberAddresses()","49ec1ff0":"setSoftwareTokensWallet(address)","49ec7c3f":"giveBirth(uint256,uint256,uint256,bytes)","49edfb94":"FEE_OWNER()","49edfed9":"getEtherForStakes(uint256)","49ee161b":"getLockPosition1(address)","49ee2ae1":"getAllJingles(address)","49ee39ba":"nullBonusMessage()","49ee6c50":"getNewItemId(bytes32)","49ee72fc":"addCountryCities(uint256,uint256[],uint256,uint256)","49eee1a4":"setRoundRate(uint256,uint256,uint256)","49ef026f":"raisedFunding()","49efdbbf":"purchaseShow(uint256)","49f00964":"founders_2()","49f02baf":"YondToken()","49f0726d":"Centhereum()","49f0c90d":"adminSetAccountAdministrator(address)","49f12aa7":"hashState(address,uint256,uint256)","49f16ad1":"setTransferEnabled()","49f194a1":"setIco(address)","49f1fa67":"GetLiasonName(uint256,uint256,uint256)","49f202ff":"getTokenIdByIndex(uint256)","49f209af":"testThrow_3_invalidOwner_accessRestrictionThrow()","49f22b4a":"biddingComponent()","49f27c25":"ProdEToken()","49f298c6":"wallock()","49f2a049":"registerInternal(string)","49f30178":"nextFinalTimeout()","49f307a6":"setNewPriceToItem(string,uint256,uint256)","49f41a42":"updateAgent(address)","49f4cc17":"transferAssets(address,address,uint256)","49f4f5da":"XLifeCoin()","49f6444e":"buyLuckyStone()","49f65ce4":"handleDividends()","49f73d3d":"calculateCountryCut(uint256)","49f7825b":"lockAddressByKYC(address)","49f9231d":"LightCoinToken()","49f97939":"notEqual(string,string,string)","49f9b0f7":"calculateSaleReturn(uint256,uint256,uint32,uint256)","49f9c0e4":"transferEth(uint256,address)","49f9e95e":"withdraw_arbitrary_token(address,uint256)","49f9f4d0":"burnOwnerTokens(uint256)","49fa84ef":"hon1ninja()","49fa991f":"removeAttestation(address)","49fb2dc5":"add_to_association(uint256,uint256,uint256)","49fcea4a":"Lyfecoin()","49fcfce7":"saleInited()","49fd5791":"_removeLastOwnerHoldingsFromToken(address,uint256,uint256)","49fd5f64":"getAllAssembly(address)","49fdaea6":"isBrickOwner(uint256,address,address)","49fe5261":"CROSAIR_PRICE_INCREMENT()","49ffeb8f":"recursiveCalculation()","4a0023cd":"findAuraComposite(uint64,uint64)","4a00a522":"homebase(int256,int256)","4a00dc38":"getAreaPrice(uint8,uint8,uint8,uint8)","4a013296":"canEscapeTo(uint32,uint32)","4a024928":"D00KIE()","4a03707c":"draw(address,uint256)","4a03e7e3":"TrinityContract(address,address,uint256)","4a042f0d":"joinBattle(uint256)","4a046d82":"usdPerEther()","4a0473fe":"votings_(address)","4a0483c5":"trustedAddressLUT(uint256)","4a0767cc":"setIsPreventedAddr(address,bool,bool)","4a084736":"updateTokenToEthOrderWHint(uint32,uint128,uint128,uint32,int256)","4a09d3cf":"withdrawAdvisersTokens(address,uint256)","4a0a7f2d":"doDistributionRange(uint256,address[],uint256[])","4a0af245":"startPreSale(address,uint256,uint256,uint256)","4a0b132a":"TIME_TO_MAKE_1_SHITCLONE()","4a0ba49d":"pay(address,address,address,uint256)","4a0bb6a4":"WeQuest()","4a0cd926":"addBankerAddress(address)","4a0d89ba":"getSwap(uint256)","4a0d8b53":"setHasMaxPurchaseLimit(bool)","4a0f0bfe":"ServiceRegistry(address)","4a0f3134":"FundTransfered(address,uint256)","4a0f5974":"left27(uint256)","4a122266":"getForwardPurchaseFeesTo()","4a12389a":"MyToken(string,string,uint8,address)","4a123e1d":"setLev2(uint256)","4a1281c6":"numTokensIssued()","4a1311f9":"openingManualyMining()","4a14e3b2":"SentAmountToOwner(uint256,address)","4a150e2c":"getDonationsCount(address)","4a15ebce":"addCbAddress(address,bytes1,address)","4a16673b":"shouldSelectWinner()","4a168859":"getAvaIcoAmount()","4a169e4b":"setCoinInfo(address)","4a173383":"determineWinner(address,uint256,bytes32)","4a1753a6":"setCurrentGame(address)","4a176017":"finalizeAdd(uint256,address)","4a176ba5":"getaddr(uint256)","4a17bbde":"getEventId()","4a180cb3":"removeSpecialFeeTake(uint256)","4a184f51":"startCrowdsale(address,address)","4a186d69":"buyTokenFor(address)","4a187785":"aaandItBurnsBurnsBurns(address,uint256)","4a18c25e":"EUEBToken()","4a197057":"GameEnded(uint256,address,uint256,uint256,uint256,uint8,uint8)","4a1993e4":"firstDepositDate()","4a1a27a8":"qtAccount()","4a1a342b":"getOrderMoneyEscrowed(bytes32)","4a1a3ded":"createNewTask(uint256,uint256)","4a1a650d":"RecordNum()","4a1a89f1":"PHXTKNADDR()","4a1aa767":"claim_victory(uint256,uint8,uint8,uint8)","4a1ad538":"checkTransferMultipleDelegated(address,address[],uint256[],uint256,uint256,bytes)","4a1b504f":"distributeBonus(address[])","4a1b98b2":"exchangeUnderwrite(address,uint256)","4a1ba4ba":"Multibot()","4a1c13cd":"setIcoStartDate(uint256)","4a1c6549":"ETHBITA()","4a1d08af":"drawRandomItemWinner()","4a1df335":"addressCEO()","4a1e004c":"blockedTimeForInvestedTokens()","4a1f05f0":"setSaleImg(uint256,bool,address,uint256)","4a1f0bf6":"inheritToNextGeneration(address)","4a1f11a7":"MT()","4a1fb241":"fttIssued()","4a1fe393":"withdrawEther(uint32)","4a208c38":"setIV_R2(uint256)","4a21f8f7":"joinToPool(uint256,uint256)","4a222b74":"ecoLock23()","4a22c7fb":"tokens_rewards_allocated()","4a23418a":"foundersTokensWallet()","4a2388ff":"setAllowedForMinting(address,address)","4a23dc52":"FileStore()","4a2479c0":"initialOwnersShares()","4a24edd6":"startSale(uint256,uint256,uint256,uint256)","4a24f6d9":"getVendorApplicationScoringTrackCount(string)","4a254431":"MappingProposalIssued(address,address,uint256)","4a25780b":"RedRibbonCoin()","4a25b2fd":"deductCoin(address,uint256)","4a26410b":"SetGenesisBuyPrice(uint256)","4a268f52":"ExchBtcToken()","4a26920b":"sendTokens(address,address,address[],uint256[])","4a2697fc":"balanceOfIssuer()","4a272bff":"GetHoga(address,uint32,bool)","4a275a1e":"Blockdrop(address)","4a280a55":"transferFrom(address,address,address,uint256,bytes)","4a2929ee":"betLockTime()","4a2951d2":"AsianCapitalChain(uint256,string,uint8,string)","4a2a197e":"addBonus(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4a2a4ebc":"countries(uint8)","4a2b0c38":"DividendProfit()","4a2b22f9":"GameBase()","4a2c3204":"getUserFLCEarned(address,address)","4a2cd48f":"getPreviousDate(bytes10)","4a2d5b6b":"getReleaseRatios(address)","4a2db4d8":"GetWinCards()","4a2dfbb4":"artWorkChangeRequest(uint256,string,uint8,bytes32,bytes32)","4a2e7752":"hashBid(address,uint256,address,address,address,uint256,uint256)","4a2ee75f":"addArticle(bytes,bool)","4a2f2333":"BitcoinMobile()","4a2f37a6":"updateItemTraits(uint256,uint256)","4a2fb1e4":"_mentors()","4a2fed3d":"test_SixtyPercentRules()","4a2ff078":"getRateFor(string)","4a303d30":"optAddressIntoHolding(address,uint256)","4a30f976":"censorship(uint256,bool,bool)","4a31259f":"totalNtsSoldWithBonus()","4a31dee2":"setTokenIdByIndex(uint256,uint256)","4a3270d7":"bytesStorage(bytes32)","4a330319":"tokensaleEndTime()","4a3310b8":"hasConfirmed(bytes32,address,address)","4a334c1c":"closePlacingPhase()","4a348da9":"getProductCount()","4a35035a":"dropNumber()","4a3573f1":"assignReservedTokens(address,uint8,uint256)","4a35d3ba":"SetBuildingSale(uint256,uint256,uint256,uint256)","4a35db7c":"restartValidation()","4a363fbc":"testNetworkDeployment()","4a366c46":"Th0m4z()","4a367140":"FoundersContract(address)","4a367827":"mintingStopDate()","4a367c68":"PrivateSaleStartTime()","4a367d73":"UpgradeMaster()","4a36870a":"firstRewardPeriodPercent()","4a36df25":"setMigrateContract(address)","4a375bc4":"FlagUint(uint256)","4a376c97":"OpenToThePublic()","4a37b5f7":"MyWill(address,string,string,string,address)","4a382c36":"freezeAccount(address,bool,uint256)","4a387bef":"removeLock(address)","4a393149":"onTransfer(address,address,uint256)","4a398c11":"SWIFTStandardToken(uint256,string,uint8,string)","4a39a5f4":"ALC_DECIMALSFACTOR()","4a3a835c":"withdrawAfterEnd()","4a3a87e2":"CreateProxyWithControllerAndRecoveryKey(address,address,uint256,uint256)","4a3a92f6":"minusFreezingTime(uint256,uint64)","4a3b0eec":"authorizeOpen(uint256,bool,string)","4a3b68cc":"referrers(address)","4a3bd672":"time1()","4a3bf377":"totalVotesFor(string)","4a3c4375":"getAllConsentTemplates()","4a3cdf21":"m_ETHPriceLastUpdate()","4a3d239c":"weiWithdrawed()","4a3d3510":"updateVotesOnTransfer(address,address)","4a3d3c09":"castleMinBrick()","4a3d5ec9":"ProofImpl(address)","4a3d72a1":"balancesContract()","4a3db7e7":"_generate(uint256,address)","4a3e2b21":"unpaid(bytes12)","4a3e4f90":"scamFlags(address)","4a3e8078":"emissionAddressUpdate(address)","4a3f17e7":"hodlers(address)","4a40e85b":"setMAYExchangeRate(uint256)","4a411f5a":"EventLuckyNumberRequested(address,uint256,uint256,uint8,address)","4a418fb7":"numOfTransferableCompanysTokens()","4a41d1ac":"verify(address,bytes)","4a41d6f5":"_clearAllApproval()","4a41e045":"getUint8(int8)","4a420138":"scheduleHeartbeat()","4a4226a5":"TeamHeadsChoice(address)","4a42a397":"TakeSellOrder(bytes32,address,uint256,uint256,uint256,address,address)","4a42d99b":"donGameGiftLineTime()","4a443471":"_money()","4a44664b":"withdrawVPCxTokens(address)","4a44bdb8":"getBlock(uint256,uint256)","4a4507ff":"testInitialBalance()","4a45b60b":"unregister(address,address)","4a45beed":"Accept(bytes32,string)","4a45d2e6":"setParam(uint256)","4a4666c1":"addAuthorizer(address)","4a4753bc":"BonusesDistributed()","4a48314f":"hodlerTime3M()","4a49ac4c":"removeFromBlackList(address)","4a4a2569":"getAudCentWeiPrice()","4a4a26d7":"EnChangToken()","4a4a2a97":"performReentrancyAttack()","4a4a2b52":"unfreezeAdministrationContract()","4a4b4eb0":"WISDOMCOIN()","4a4b674a":"setPenalty(uint256)","4a4b7202":"PPBC_API()","4a4b7de6":"deedContract()","4a4baed7":"setTokenControlInfos()","4a4c1bcd":"LeviusDAO()","4a4c560d":"whitelistUser(address)","4a4c5e59":"proceedTokenDeals(uint256)","4a4c82c6":"_resetSpentToday()","4a4e3bd5":"emergencyUnpause()","4a4e5776":"stepDuration()","4a4e6f95":"addFeedOut(address,address,int256,uint256,uint256)","4a4e8884":"getUserAddress(bytes32)","4a4ede50":"transferSalesAgentPermissions(address)","4a4ef738":"addAddressToPrivateWhiteList(address,uint256)","4a4f76d5":"getInitializeEndTime()","4a4fbeec":"isLocked(address)","4a4fd24d":"addMileagePoint(address,uint256,int256)","4a5033eb":"Reverted()","4a504a94":"Confirmation(address,uint256)","4a50c3a7":"EtherToWei(uint256)","4a5163b5":"numDefinedGames()","4a51dcea":"TIER3_CAP()","4a522e4e":"winCosFromGame(uint256,uint256,string)","4a52a5f8":"TerraFirma()","4a52e506":"enableLostAndFound(address,uint256,address)","4a53c127":"setTargetDiscountValue7(uint256)","4a54315c":"registerUser(bytes32,string)","4a54fb0a":"updateProduct(bytes32,string,address,uint256,uint8,uint256)","4a55308c":"firstSellPrice()","4a562d81":"returnDeed(address)","4a574d18":"bonusMode()","4a5791e0":"UnFreezeProduct(uint256)","4a57c032":"IcoDiscountLevelsChanged(address,uint256,uint256)","4a57e1c9":"finalizeTransaction(uint256)","4a588d87":"CYB(uint256,string,string)","4a5891ac":"changeEternalStorageContractAddress(address)","4a58c409":"changeStartSale(uint256)","4a58cf22":"totalSupplyInWei()","4a58db19":"addDeposit()","4a5a3d76":"setETHPriceManually(uint256)","4a5a831b":"EthlanceConfig(address)","4a5baa1b":"VULCAN_POD_EXTRACTION_BASE()","4a5c2d6e":"Change(address,uint256,address,uint256,address)","4a5c8f1a":"getEarnEachBlock()","4a5db3b5":"authorizeAddress(address)","4a5dcb5b":"Candy(address,address)","4a5dcdc9":"RANGEEND_9()","4a5dddd2":"proxyPurchase(address)","4a5df250":"nextContributionCaps(uint256)","4a5e1cf3":"initLottery(uint16,uint256,uint8)","4a5e4fa8":"setExpReward(uint32)","4a5e70c0":"ObitanChainToken()","4a5ecc66":"Sale(address,address)","4a5fca4f":"offChainTokens()","4a5ff749":"teamAddr()","4a601994":"WesTechToken()","4a606c53":"_db()","4a60751f":"refundingEndtime()","4a61179b":"MANHATTANPROXY11THWEAVE()","4a617faa":"shaBid(bytes32,uint256,bytes32)","4a617fba":"gooDepositDivPercent()","4a61f347":"resetEditionLimits(uint256)","4a61fc1e":"getWinners(bytes32)","4a6213a1":"MAKERDAO_FEED_MULTIPLIER()","4a624310":"getAngelInfoByTile(uint16,uint8)","4a627e61":"someValue()","4a62cc73":"auditQueueExists()","4a62f5eb":"_isTokenActive()","4a63464d":"adminClaimAirdrop(address,uint256)","4a635d05":"testCampaignGoalReached()","4a63864b":"RATE_RATIO_SCALE()","4a63b3d3":"lockBlock()","4a63f8a4":"presellTimer()","4a6458ae":"Rescued(address,uint256,uint256)","4a64c23f":"removeCbAddress(address)","4a661152":"get_exchange_wei()","4a66ddff":"twin_contract()","4a67fa7d":"setLotteryFee(uint256)","4a681b1b":"EXPECTED()","4a683a65":"addBTCTransaction(uint256,bytes16,address)","4a68492c":"setTransferAgentStatus(address,bool)","4a6a225e":"proxyPayment(address,bytes4,bytes)","4a6aac33":"DATE_31_DEC_2020()","4a6b0b05":"NewArtwork(address,bytes32,uint256,string,string,uint256,address,bool,bool)","4a6b8cf6":"setPretgeAddress(address)","4a6b9473":"registerActionEvent(bytes32)","4a6bb4a5":"updateWallet(address,address)","4a6bfa2d":"salesActive()","4a6c121d":"uintToBytes32(uint256,uint256)","4a6cfca7":"getAccessory(uint256,uint256)","4a6d0292":"addSale(address)","4a6de5c3":"_getAvailableBalance()","4a6e2ffe":"calculateReferral(uint8)","4a6f2691":"setBoolF1(bool)","4a7004b9":"getTotalTokenDepositByAddress(address)","4a700545":"PrivateSaleAddress()","4a701fc3":"setownerInfo(address,bytes32,bytes32,bytes32)","4a7084bb":"setPublicOfferDate(uint256,uint256,uint256)","4a714378":"toggleVending(uint256,uint256)","4a714c24":"payers(address)","4a7160a2":"addSet(bytes32)","4a716adf":"transferVotes(uint256,address)","4a719a27":"getTargetRepMarketCapInAttoeth()","4a71a768":"setWeiCapPerAddress(uint256)","4a71d469":"collectRev()","4a720287":"setEarlyEndTime(uint256)","4a729fe1":"pay(address,bytes12)","4a733ded":"paybackContribution(uint256)","4a738bea":"withdrawWithFee(address,uint256,bytes32,address,uint256,bool)","4a74ca99":"disconnectOrderPrice(address,address,uint256,uint256)","4a751072":"rateBoundaries(uint256)","4a7510fc":"StealResources(uint256)","4a75c0ff":"StoreDocument(bytes32,string,string)","4a75e6c3":"servicePayment(address,uint256)","4a75e741":"add_owner(address)","4a765625":"AliParsafar()","4a76564e":"tokenReleased()","4a76869f":"commitOrder(string)","4a768eaa":"buytoken(address,uint256)","4a7759f8":"BALL()","4a776104":"canFinishPVP()","4a77f870":"migrateAll()","4a78a594":"getClaim(string,string,address,uint256)","4a78cdba":"jackPot()","4a7902d2":"changeRoot(address)","4a790540":"getPastWinnerPrizes()","4a793c0c":"cidTotalTokenSupply()","4a797494":"priceRound3()","4a7987a2":"setProvider(bytes32,address)","4a79d50c":"title()","4a7b1acc":"MapDemo()","4a7b26ec":"join_game(uint256)","4a7b7ec3":"mintMarketMakerCancel(address,address)","4a7b8f21":"addHarvestOperationEndorsement(string,bool,string,string)","4a7bb697":"AssignGGCPoolOwner(address)","4a7c7e46":"uintToAscii(uint256)","4a7cb0f5":"FoundationRequested(address,address,bytes32)","4a7d505c":"initBetType()","4a7d8bcc":"getCurrentTokenPricepreICO(uint256)","4a7d9f0f":"getSettlementPeriodEnd()","4a7dd523":"generate(uint256)","4a7de068":"finalizeSetDelegatedFrom()","4a7e00de":"rejectCompanyAllocation(address)","4a7e049e":"getFullCompany(address,uint256)","4a7e130e":"remainTime()","4a7ffcbc":"daoContract()","4a800b98":"cancelChampSale(uint256)","4a803387":"insert(uint256,uint256,uint256)","4a8075ac":"SaleAuction(address)","4a80dcab":"getProjectMilestonesCount(bytes32)","4a80f2ba":"registerKey(string)","4a812023":"logUniverseForked()","4a81db9a":"moneybackaddr()","4a81dc0f":"forceUpdatePrizes(uint256[])","4a82534b":"create(address,address,address,uint256,uint8,uint8,uint256)","4a825c68":"checkRoundEnd()","4a826823":"setCastle(uint64,uint64,uint64,uint64,uint64,uint64)","4a82804e":"setNewMessage(string)","4a8302a2":"SynixToken(uint256,string,uint8,string)","4a8305b4":"newCoinOwner(address)","4a838caf":"ethfortnite()","4a83cfa9":"burnMedal(uint256)","4a84fa81":"checkRokSold()","4a85223b":"addUser(address,string,string,int256,string)","4a85280e":"isAuthorizedAddress(address)","4a85512f":"awardInvation(bytes32)","4a85d0d5":"HeliumNetwork()","4a85dbcd":"setVal(string,uint256)","4a8646c3":"HomeLoansToken(uint256,string,uint256,string)","4a8671f1":"newWallet()","4a867488":"setVestingPercent(uint256)","4a87b419":"cancelApproveFee()","4a87e08a":"BUY_CITY_FEE()","4a881ac6":"addAddressDescription(string,address)","4a88eb89":"altDeposits()","4a88f9c7":"exFees(uint256)","4a891e7f":"FinalizeMove(address,string,string)","4a896384":"ask()","4a8967a6":"_today()","4a8a6eac":"CarRegistered(uint256)","4a8a83db":"calculateVestedTokensTime(uint256,uint256,uint256,uint256,uint256)","4a8b2b27":"testOne()","4a8b5389":"allocateBountyAndEcosystemTokens()","4a8beaf4":"decline(string)","4a8c1fb4":"isActivated()","4a8c2d64":"TopsXToken(uint256,string,uint8,string)","4a8c3129":"MultiOwners()","4a8cbae1":"charityPercent()","4a8e4d78":"getDuesIn(uint256)","4a8e5651":"resultAccept()","4a8ef4bd":"setOrderBookAcount(address)","4a8ef851":"pushTicketSetToAccount(uint256,uint256)","4a909d5f":"transferWithLockup(address,uint256,uint256)","4a910046":"getLastHash()","4a914e8c":"calculateTotalExpenseWithdrawableAmount()","4a915ea2":"votedHarvest()","4a91e536":"getWinnerDetails(uint256)","4a91ec80":"prospectors_dev_allocation()","4a91ee2a":"allowByPassword(bytes8,bytes)","4a91f195":"totalBought()","4a923199":"maximumTNB()","4a92fa06":"createPromoRide(address,string,bytes7,uint256)","4a92fb3a":"proxyTransfer(address,address,uint256)","4a943eb3":"numsuccesses()","4a945f8d":"setAddresses(address,address,address,address)","4a947bdb":"putMatingRequest(uint256,uint256)","4a950db6":"tradetxToken()","4a950f00":"TurkeyBurgerToken(uint256)","4a955659":"_getNewLotteryCreatedAt()","4a96712e":"confirm(bytes32,address,uint256,uint8,bytes32,bytes32)","4a96d129":"OfferTime()","4a975d6b":"allocateRestrictedTokenTo(bytes32,bytes32,bytes32,uint256)","4a980b49":"IRideToken()","4a98146a":"VILLAGE_START_PRICE()","4a994d22":"_getReleaseDate(uint256)","4a994eef":"setDelegate(address,bool)","4a9952c7":"setMintTokenOwner(int256,address,address)","4a9a6f15":"getFromFaucet(string)","4a9b3f95":"personUpdateName(uint256,string)","4a9b5c2e":"CREATOR_TOKEN_END()","4a9bdb65":"byuoutCount()","4a9cdfad":"setPlayerLAff(uint256,uint256)","4a9d367b":"RecipientChanged(address,address)","4a9d9172":"test_testableStandardCampaignAbsolvementAfterPayout()","4a9f0110":"setSellDailyLimit(uint256,bytes2,uint256)","4a9f6d4a":"setMaxPreCrowdAllocationPerInvestor(uint256)","4a9fefc7":"getReferrer(address)","4aa16737":"enter(uint8)","4aa1acb3":"withdrawEth(uint256,bytes)","4aa1d21b":"transferDryRun(address,address,uint256,uint256)","4aa1dde4":"isDisclosureFullySigned(uint256)","4aa2f0f5":"HKD_Omnidollar()","4aa3fcd3":"_getSkillConfigs()","4aa41e53":"minFinneyPerHedgeTransfer()","4aa47a50":"isIntermediateVault()","4aa4ba9b":"storeBatch(string)","4aa5a05d":"maxP1Cap()","4aa5b398":"voteCurrentResult()","4aa669d8":"Buy_Wall_level_in_wei()","4aa66b28":"getBonus(uint256)","4aa678c3":"getMyUnlockValue()","4aa6c09a":"setTargetDiscountValue3(uint256)","4aa735c0":"BST()","4aa74c27":"_emitFuture(bytes32,uint256,uint256,uint256)","4aa77c71":"Visualrocktoken()","4aa83079":"setSaleContractFinalised(address)","4aa880c1":"SetFactoryParams(bool,bool,uint256)","4aa8e57e":"buyBox1()","4aa8e773":"Cancel()","4aab421d":"tgrAmountCollected()","4aab8c14":"setPonzi(uint8,uint256)","4aabcec7":"SimpleWallet()","4aac390a":"hasLanguage(address,address,uint256)","4aac75a7":"setMainSaleDates(uint256,uint256)","4aaca86d":"saleStage()","4aacd437":"freezeAccountPartialy(address,uint256)","4aaceed3":"icoBonus2()","4aada45f":"KittensDroped(uint256,uint256)","4aae385f":"preSaleFirstStartDate()","4aaf4a12":"getOwner(string)","4aaf6b86":"contract_state()","4ab0c0ee":"testConcatMemory32Bytes()","4ab0fc08":"setDefaultURIEnd(string)","4ab1c98f":"requestControllerContractMigration(address)","4ab24cf3":"pornToken()","4ab273f0":"SellEggs()","4ab320b4":"viewSettingsChange(uint256)","4ab358c7":"recoverFunds(uint256)","4ab3bbdc":"_brokerFeeDistribute(uint256,uint256,uint256,uint256)","4ab3bc23":"getSelfCardDatas()","4ab3d487":"newEntry(uint256)","4ab40ac6":"allOpenTradesAmounts()","4ab5439b":"TEAM_POOL_ADDR()","4ab54530":"inPreSale1Period()","4ab5cc82":"latestValue()","4ab6d337":"getContributorsLength()","4ab74a1e":"tok()","4ab7508a":"multiWallet()","4ab788cb":"prebridge()","4ab798f1":"toggleTransfer()","4ab7cbfe":"getMinerHalvingHashRateOf(address)","4ab89400":"cancelRefund(address)","4ab9792d":"setTokenFrom(address)","4aba5f34":"getCandidatesList()","4aba76a3":"ESlotsToken()","4aba7f96":"setMixGenAddress(address,address)","4abad407":"startCrowdfund(uint256)","4abb525a":"moonIncContract()","4abb9d39":"depletable()","4abc8652":"inPrivateSalePeriod()","4abd89bd":"MDICOStage2(address,address,uint256,uint256,uint256,uint256)","4abd8e01":"putStcWithBtc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","4abd8f65":"updateEnabled()","4abdf2e0":"setWithdrawLimit(uint256)","4abe1a62":"settleEtherPolicy(address[],uint256[],uint256[],uint256[])","4abe34f2":"TecToken(string,string,uint8,uint256)","4abefa36":"getEmployees()","4abfacfd":"createTeam(string,string,uint32,uint32,uint256)","4abfbbe3":"getBlockInfo(uint8,uint8)","4ac0d66e":"newGreeting(string)","4ac1ad78":"getWeekday(uint256)","4ac1b5ff":"GoldmintUnsold(address,address)","4ac25224":"isChannelOpen()","4ac2d103":"miningReward()","4ac36201":"Yachtco()","4ac365c2":"DividendTransfered(uint256,address,uint256,uint256,uint256)","4ac38f13":"BlupassToken()","4ac39f37":"unsafeIsSigned(uint16)","4ac429f2":"ConstantinopleCheckFunction()","4ac54245":"_fulfill(bytes32)","4ac5aae5":"getTotalBonus()","4ac5dea9":"getRoundPointer(uint256,uint256)","4ac6b2be":"getCheckRecordCreator(bytes)","4ac6d5f4":"frostTokens()","4ac79795":"removeLogic(address)","4ac7becf":"SimpleSign()","4ac84218":"RequiredFeeNotMet(uint256,uint256)","4ac84242":"CWT(uint256,string,string)","4ac87af7":"frozenToken(uint256,string)","4ac87e47":"Bittwatt(uint256)","4ac8a529":"createDispute(uint256)","4ac9f0d7":"behalfer()","4ac9f881":"takeSellOrder(address[3],uint256[3],uint256,uint8,bytes32,bytes32)","4ac9fc37":"updateConvertionRate(uint256)","4acb17c8":"getPeggedTokenAddress(address,address,uint256)","4acb232b":"percentWeiMC()","4acb3e59":"QCOToken(address,address,address,address,address)","4acc50eb":"Invoked(address,address,bool,uint256)","4acceeea":"togglePrebrdige()","4acd058e":"auctionBonus(uint256)","4acd44db":"offChainManager()","4acd4d5c":"mintLockCashout(address,uint256)","4acdc150":"setupCrowdsale(uint256)","4acdd29a":"statusPred(address,uint256[],uint256)","4acddfa0":"register(address,string,uint256,string,string,string,bytes20)","4ace9ccc":"ratePlansOfVendor(uint256,uint256,uint256)","4acea254":"inviteAmountLimit()","4acefeb1":"ethartArtAwarded()","4acf071c":"setStepTwoTime(uint256,uint256)","4acf4a27":"withdraw(uint128,address,uint256,uint128)","4acf8867":"PillarToken(address,address)","4ad07b0e":"oracleOutcomes(bytes32,address)","4ad0a529":"currentMigrationTarget()","4ad1cbad":"withdrawTeamTokens(address,uint256)","4ad25557":"getMonsterNum(uint256)","4ad27ae1":"claimInternal(address,address)","4ad37241":"destroyCard(uint256,uint16)","4ad37538":"DJPToken()","4ad42500":"ico26()","4ad447ba":"PutinCoin()","4ad4fa5d":"ERC223()","4ad59c54":"overpays(address)","4ad5a68c":"returnIdImage(uint32)","4ad5f440":"totalIcoTokensSold()","4ad6e648":"fightFactor()","4ad6f9f3":"checkTx(string)","4ad7799f":"VestingReleased(address,uint256)","4ad857a1":"etherSent(uint256)","4ad88363":"reset_application(address)","4ad8c869":"reCommentReward()","4ad8c938":"createSiringAuction(uint256,uint256,uint256,uint256)","4ad9d7ab":"getGoldStatusRegistered(address)","4ada218b":"tradingEnabled()","4ada3b32":"approvedAccount(address,bool)","4adaedef":"send_allowed()","4adaf5f6":"changeFundOwner(address)","4adaf748":"eBlockPower()","4adbe551":"whitelistAdmin()","4adc0b09":"setMembershipPrice(uint8,uint256)","4adcbd19":"isThisHardforkedVersion()","4adf6591":"setReportTimestamp(uint256)","4ae00041":"call(address,bytes,uint256)","4ae0ac60":"FobsCoin()","4ae0f543":"publicAllocation()","4ae12e9f":"FHFToken()","4ae184f2":"createStandingOrder(address,uint256,uint256,uint256,string)","4ae2b849":"PHASE_DURATION()","4ae2c351":"createCrowdsaleTiers(bytes32[],uint256[],uint256[],uint256[],uint256[],bool[],bool[])","4ae3164d":"getNewGens(address,uint256)","4ae34a96":"changelp16(address)","4ae34bb1":"EfectiveToken()","4ae3643f":"phase_4_token_price()","4ae4dd6b":"KeyRewardPool(uint256,address,address)","4ae4e9ea":"m_currentTokensSold()","4ae51a9a":"transferDevTokens(address)","4ae55dd0":"amendedEarlyPurchaseIndexes()","4ae5d478":"setNodesVars(address)","4ae5eecb":"getUserP3DDivEarnings(address)","4ae6ab70":"_getRevisionTimestamp(bytes20,uint256)","4ae85627":"grindUnicorns(uint256)","4ae86038":"MultiBonusCrowdsale()","4ae8c55f":"getWwLength()","4ae8ef06":"setLastTier(uint16)","4ae8f9fb":"FSCP()","4ae90a40":"isNotaryAdditionValid(address,address,uint256,uint256,string,bytes)","4ae931cc":"setPresellUpToTime(uint256)","4ae96e77":"setTransformTarget(uint256)","4ae9af61":"getBotStats(uint256,uint256)","4aea0aec":"lendFee()","4aea5f0f":"Artcoin(address,uint256,uint256)","4aea7aa9":"SetIDChain(address,address)","4aeb0241":"LisaToken()","4aeba1a5":"removeCustomerService(address)","4aec4677":"migrateLosingTokens()","4aec6416":"removeTransferAndCallWhitelist(address)","4aecf91d":"_emitContractRemoved(address,address)","4aed8a76":"inPreSalePeriod()","4aeda70d":"changeAuctionContract(address)","4aeddad0":"ConvertBkp(uint256)","4aef05a5":"addSongWriter(string,uint256,address)","4aef8b7c":"_isOddFlag(uint256)","4aefc3c4":"ContributionStateChanged(address,uint8)","4af153a9":"_message(uint256)","4af165cb":"EPause(address,string)","4af1b8a7":"pullAddr()","4af1f96a":"getActiveSellSize(bytes32)","4af27ba2":"_redeem(address,address,uint256,bytes,bytes)","4af350eb":"transferTokens(address,uint256,address)","4af4a127":"bonusPeriod()","4af4c191":"TIER4_RATE()","4af54311":"burnSomeTokens(uint256)","4af56cb0":"getUseRegistry()","4af69189":"sponsoredJackpotToken()","4af6ffc2":"attest(uint256)","4af7eedf":"VID(uint256,string,uint8,string)","4af80f0e":"setConversionWhitelist(address)","4af98f1b":"setFeeDivider(uint256)","4afb07c4":"getAccountActivity(address)","4afb09c2":"listDTH()","4afbac9c":"removeFromTokenList(address,uint256)","4afbb7d7":"getDepositary_function()","4afc0476":"RedPillCoin()","4afc7774":"_is()","4afce471":"test_requires_depth(uint16)","4afd74ff":"getRefunded(address)","4afd8a19":"getLendingInfo(address,uint256)","4afd8a98":"testEthIcoToken()","4afdcbde":"pauseOperator()","4afe2f80":"setRate(uint8)","4afe62b5":"placeBet(uint256,uint256)","4affb863":"isPartner(address,address)","4b00ebfb":"CheckExecution(string)","4b013f85":"_addVestor(address,uint256,uint256,uint256,bool)","4b023cf8":"setFeeAccount(address)","4b02e328":"IncorrectFee(address,uint256)","4b0304ab":"DonationReceived(address,uint256,uint256)","4b031397":"killAdminOnly()","4b031d0f":"shortSellShares(bytes,uint8,uint256,uint256)","4b03a15e":"_terminateSchedule(address)","4b042c0b":"specialsInfo(uint256)","4b05de75":"seventhTeamWithdrawal()","4b0697e4":"Manager(address)","4b06e1c7":"declareWininingFighter(address)","4b06fb28":"eatUnicornsAlive()","4b0720a7":"customGasPrice()","4b079fa6":"ownerof()","4b084d49":"checkEnd()","4b089b12":"withdrawManagerBonus()","4b09b72a":"reserveAmount()","4b09ebb2":"e_exp(uint256)","4b0a0d04":"checkRequestSignature(bytes,address[],uint256,bytes)","4b0ad8fa":"getStakedShop(address)","4b0adf6c":"MintingAgentChanged(address,bool)","4b0babdd":"releaseTokens(uint256)","4b0bbf84":"addEntropy()","4b0bddd2":"setAdmin(address,bool)","4b0c79aa":"turnOnOraclize()","4b0d5417":"disableSellToken()","4b0daadb":"getStaticArray()","4b0df486":"assertEq23(bytes23,bytes23)","4b0e2c90":"enableInternalLock()","4b0e5044":"HoldToken(address)","4b0e7216":"setBurnAddress(address)","4b0ee02a":"totalBalanceOf(address)","4b0f43fd":"canExecute(address,uint256)","4b106893":"inactive_withdraw(address)","4b11281e":"returnCreatorAddress(bytes32,uint8,bytes32[2])","4b11452c":"changeFoundationAddress(address)","4b114691":"playerInfo(address)","4b1146ca":"TOKEN_SUPPLY_BOUNTY_LIMIT()","4b11982e":"setCooldown(uint64)","4b11e7a0":"getVotingStart()","4b12416c":"setHeroTokenContract(address)","4b12dd39":"BTSCoin()","4b1325ea":"setNewOwnersCountToApprove(uint256)","4b143bb5":"harapan()","4b14e003":"transferAll(address,address)","4b16304f":"setTokenAddress(address,bytes)","4b1700df":"TokenListingManager()","4b1740ad":"tier3()","4b17bdd8":"transferTokensFrom(address,address,address,uint256)","4b18be1d":"moveLeftOvertokensToartistPool()","4b19eb09":"isStatePublic()","4b1a5773":"createSwapTarget(bytes20,address,address,uint256,address)","4b1be424":"getVotesBetweenFor(uint256,uint256,uint256,address)","4b1c5597":"dissolveFund()","4b1c8506":"bonusesList(uint256)","4b1cab4e":"calculateEthToToken(uint256,uint256)","4b1cdc2d":"token6DivsOwing(address)","4b1cff0b":"pot_()","4b1d00ee":"releasedCount()","4b1d29b4":"maxLockPeriod()","4b1dc225":"founderWithdrawablePhase3()","4b1dd21a":"getWhitelistLimit(address)","4b1dd591":"firstDiscountCap()","4b1ebc5a":"perpetuum()","4b1ec20c":"setPropertyPrivateMode(uint16,bool)","4b1ef6e1":"getMyRecord(address,uint256)","4b1f15d1":"updateDragonPrice(uint256)","4b1fb6d4":"removeNacFromNetf(uint256)","4b1fe17e":"ENSResolver(address)","4b200fac":"ClearCoin()","4b20ae39":"create(address,address,address,uint256,uint256,uint256,uint256)","4b21433a":"CoolICOToken()","4b21a587":"sellerfeeDivide()","4b21aaae":"getBondPrice(uint256)","4b2233df":"buyTokenSub(uint256,address)","4b227176":"pID_()","4b236401":"claimPlot(uint256,uint256)","4b242252":"levelByToken(uint256)","4b24ea47":"controllerAddress()","4b24f3a6":"setJackpotFee(uint256)","4b24f7aa":"CSpacesToken()","4b24fd0d":"getKeyType(address)","4b256137":"lockingContract()","4b259b5c":"getCumulativeAllowance()","4b25bfce":"whitelist(uint256,address)","4b269a00":"withdraw(int256[])","4b2702b3":"TokenSwitch(address,address,bool)","4b272c4a":"Greenbit()","4b274458":"getUncleAmount(uint256)","4b27a2ca":"fechVoteMainInfoForVoterBySnapshotBlock(address,uint256)","4b28a674":"organizer2()","4b28bdc2":"allRevealed()","4b2930d0":"IsICOrunning()","4b29c448":"setGoal(uint256)","4b2a4e18":"TradersWallet()","4b2a649c":"ECRecoverWrapper(string,uint8,bytes32,bytes32)","4b2acaa0":"openGateway()","4b2ba0dd":"originalSupply()","4b2be022":"BinaxToken()","4b2c0706":"getPeriod(uint256)","4b2c2596":"MerchantDealsHistory(string)","4b2c89d5":"redeemDeposits()","4b2cbc9d":"etherCollected()","4b2d5164":"transfer_tokens_after_ICO(address[],uint256)","4b2f249a":"isTileLive(uint16,uint8)","4b2f9eb7":"declareNewMaster(address)","4b313043":"preIcoMaxLasts()","4b314b34":"LogPause()","4b319713":"totalWithdrawn()","4b321502":"addHours(uint256,uint256)","4b331ca0":"getCitation(uint256)","4b33eac2":"updateTicketStructure(uint256,bytes32[],uint256[],uint256[],uint256[],uint256[],uint256[])","4b341aed":"totalStakedFor(address)","4b3544d5":"Jakov()","4b35ae33":"setTimeLimited(uint256)","4b369820":"setEntry(string)","4b36bca9":"WagerGames()","4b3727fb":"SshKey()","4b374fbe":"BTEN()","4b376513":"lastBlock_v13Hash_uint256()","4b376e45":"BoodooToken()","4b37c73f":"removeFactory(address)","4b37cf47":"littIsCapsule(bytes32)","4b3881ff":"StakeDestroyed(uint256,uint256,address,bytes32)","4b3955a5":"tier0LOT()","4b396ade":"TicketMultiTear(string,string[],uint256[])","4b3985a4":"shareTime()","4b398a5c":"mainnetLocked()","4b3a5fa6":"saleStartFirstDayEnd()","4b3ab5bf":"paySubscriptionFee()","4b3ab9c5":"getShare(address)","4b3afdd2":"setEthernautsStorageContract(address)","4b3b1d69":"notZero(uint256)","4b3b548f":"preMine()","4b3b6168":"SetNewBigContract(address)","4b3c45db":"getDealDataByNumber(uint256)","4b3ce14d":"set_minUETsPerReturnMoreThan(uint256)","4b3d81b6":"initialBlockTimestamp()","4b3ec03a":"TEAM_ACCOUNT()","4b3f3987":"_updateLock(uint256,address)","4b419b5f":"setcardPrice(uint256,uint256)","4b41c74a":"Ticker()","4b41cb60":"withdrawPreSigned(address,uint256,address,uint256,uint256,address,uint8,bytes32,bytes32)","4b41eb4a":"ZyryanovKubSU2018()","4b41f4df":"transferableTime()","4b42d208":"getUint8FromByte32(bytes32,uint8)","4b432966":"max_fortunes()","4b43b582":"changeAdminWallet(address)","4b43dc51":"testTokensAreLockedDuringSale()","4b449cba":"auctionEndTime()","4b452958":"_setStakingEpochStartBlock(uint256)","4b467105":"walletCommunityReserve()","4b467157":"stopEmergencyWithdrawal()","4b468b0e":"JDAnteil()","4b469490":"RichToken(address)","4b471dd0":"setWithdrawalAndReinvestmentContracts(address,address)","4b496444":"azatipToken()","4b4a456a":"ChargeFix(uint256)","4b4a5088":"switchCompatible20(bool)","4b4af4db":"allocateTeam(address,uint256)","4b4b6338":"MECoin(uint256)","4b4b87c0":"PowerCoin()","4b4bb75b":"DSToken(string,string)","4b4c01f4":"RobincoinERC20(uint256,string,string)","4b4c0d7c":"BONUS2()","4b4c2039":"_B_sendToEthertoteDevelopmentWallet()","4b4e23e1":"TIMESTAMP_BUCKET_SIZE()","4b4e38df":"GetCurrentPoolAmount()","4b4f8e36":"addCZRLock(address,uint256,uint256,uint256)","4b4f90ef":"saleIsOn()","4b504ecd":"logNewPlayer(address)","4b50c9f0":"getGameStartTime()","4b513e82":"RegistrantApproval(address)","4b5243b5":"ETGTestCoin()","4b52f48f":"withdrawLeft()","4b52f89b":"setGiftToken(address)","4b530090":"nextDiscountTTWTokenId1()","4b534c48":"unlockProjectToken()","4b54d131":"wipeProposedActions()","4b54f1fb":"S1Coin()","4b561a16":"getMatchInfo(uint256)","4b563657":"setMessages(bytes32,bytes)","4b56b10d":"preIco()","4b56cd27":"depositBoth(address,uint256)","4b56dcf4":"LogChangeIsPayableEnabled()","4b57b0be":"wethToken()","4b57ed55":"EnonRToken()","4b57fbaf":"SetMinChequeValue(uint256)","4b5830b4":"SENC_CONTRACT_ADDRESS()","4b58484d":"_createPlayer(address,address)","4b58d0bb":"reserveFundAddress()","4b59e880":"puzzle(address,bytes32,bytes32)","4b5a0e65":"getWinningStageInfo()","4b5a726d":"getProgramInfo(uint256)","4b5c0234":"throwsWhenHittingHardCap()","4b5c4277":"log(string,string)","4b5dc8cb":"roundMoneyDown3SFExt(uint256)","4b5dcad7":"ServiceStation(address)","4b5e8d63":"registerInvestor()","4b5f297a":"hasAttribute(address,uint256)","4b5f2fa4":"TravelZediToken(uint256,string,uint8,string)","4b5f3e0a":"getDate(bytes32)","4b5fd350":"withdrawHeldToken(uint256,uint256,uint256,uint256)","4b5fea8a":"milestoneRecipients(uint256)","4b602673":"artworks(uint256)","4b603a83":"mintTokens_(address,uint256,address)","4b61cf17":"SWLPerEther()","4b623178":"removeFromPublicWhitelist(address)","4b627107":"setValidatorDescription(address,string)","4b62e0d9":"buyIns(uint256)","4b63036d":"holderContract()","4b63189c":"softcapPreSale()","4b63e601":"scheduleCall(address,uint256,bytes)","4b641f52":"coinbaseInit()","4b64a00f":"DiscountApplied(uint256,uint256,uint256)","4b64e492":"execute(address)","4b650d0b":"getPlayerClickCount(uint256,address)","4b656b41":"totalWeiRaisedDuringPhase1()","4b66cb7e":"teamHolder()","4b6753bc":"closingTime()","4b67f6af":"name2()","4b689cf0":"setCommunityAccountOwner(address)","4b69c3d4":"getRegistryDataVendor()","4b6a3334":"setEtherPrices(uint256,uint256)","4b6a8604":"setBiddingRate(uint256,uint256)","4b6a9f1d":"STORES_TO_UPGRADE_1CENTER()","4b6acafb":"totalDividend()","4b6ad918":"isCurrentUserRefAvailable()","4b6b2300":"updateTopicAssetClass(bytes15,string)","4b6bc655":"isFreeze(address,address)","4b6bdf1d":"poker()","4b6c144a":"getClaimById(string)","4b6dfe4e":"initialFundBalance()","4b6e7d78":"Data()","4b6ea677":"oracleURL()","4b6ede29":"Users()","4b702afa":"accountS()","4b70cec4":"getTime(address)","4b71bff3":"airdropReward()","4b726f61":"checkCustomer(string,string)","4b729aff":"buyNumber(uint256)","4b72bbaf":"getSirePrice(uint32)","4b739b61":"payByEth(uint256)","4b73ca04":"flipsCompleted()","4b741395":"requestNewMint(address,uint256)","4b749535":"hardCapTokens()","4b750334":"sellPrice()","4b75f046":"tokensIssuedCrowd()","4b75f54f":"formula()","4b760612":"localsCointoken(uint256,string,uint8,uint256,string,string)","4b763fe7":"PersistLimitChanged(uint256)","4b766b95":"markRewardsSet(string)","4b76cb13":"get_status_user(address,address)","4b76fe19":"EtherPredict()","4b778445":"addRound(uint256,uint256,uint256)","4b77b8d3":"stopCrowdfunding()","4b77c468":"invite(address)","4b77d17d":"is_king_found()","4b7829f1":"token_claim_waiting_period()","4b7863fe":"setIBalance(uint256,uint256)","4b78ab61":"notarizationList(uint256)","4b798b82":"setFixes(string,string)","4b79e8ef":"getVariablesForDapp()","4b7a5cc6":"PLATINUM_AMOUNT_NDC()","4b7a7a14":"PresaleFirst(uint256,uint256,address,address)","4b7ae9f6":"returnMe()","4b7b2ed1":"confirmTransaction(address)","4b7b45b4":"DreamMaker()","4b7bb8e3":"CfoAddress()","4b7c1d2c":"TransactionConfirmed(uint256,uint256)","4b7e23b3":"ShapeshiftBotLookup()","4b7fa6db":"viewFn(uint256)","4b7fcee7":"ownerPausePayouts(bool)","4b802dde":"rentals()","4b803095":"processReferralSystem(address,address)","4b813478":"FinishBallot(uint256)","4b81780e":"ADDR_MAYA_ASSOCIATION()","4b82d416":"preSaleSecondEndDate()","4b82ee28":"frozenDaysForEarlyInvestor()","4b82f437":"setFirstReporterCompensationCheck(uint256)","4b836181":"BuyTicket(address)","4b8399f4":"setEnum()","4b841fa9":"redeem(string,uint256,uint256,uint8,bytes32,bytes32)","4b84ee81":"LogAddTokenPairWhitelist(address,address)","4b851b23":"hasDefaultRelease()","4b852c03":"setDuration(uint64)","4b855c62":"purchaseKingdom(string,string,bool,address)","4b8574ad":"AttestationManager()","4b85fd55":"setAutoBirthFee(uint256)","4b8624c4":"BONUS()","4b865846":"suspend(uint256)","4b866981":"LP(uint256,string,string)","4b869e15":"investeth2017()","4b86c225":"lock(address,address,uint256,uint256)","4b86faba":"claimHodlReward()","4b86fc5b":"isEligible(address,string,string)","4b8772c1":"buyUnit(uint256,uint256)","4b886f09":"VantageCoin(uint256,string,uint8,string)","4b891518":"_grantAccess(uint256,address)","4b89c41d":"setClosingTime(uint256)","4b8a3529":"borrow(address,uint256)","4b8adcf7":"pauseContribution()","4b8b4cee":"postExternalPayment(address,uint256,uint256,uint8,uint256)","4b8b704e":"icoTokensCount()","4b8b7a2a":"addCourse(string,uint256,string,string,string,string)","4b8ca215":"Ornament()","4b8d12f0":"migrateAddress()","4b8dbd1a":"VRFtoken()","4b8dc588":"closeRefundVault(bool)","4b8e1ba8":"isMinter(int256,address)","4b8e31a2":"_erc20token()","4b8e38db":"test(uint32[26],uint32[4])","4b8f4b5e":"MordernToken()","4b8f9f87":"ownerSetMinJackpoBet(uint256)","4b8feb4f":"multiSigWallet()","4b901b72":"balanceOfByTranche(bytes32,address)","4b9081bf":"getBonusSale(uint256,uint256)","4b90ac86":"isBountySent()","4b9143f7":"setSold(uint256)","4b915a68":"aliceClaimsDeposit(bytes32,uint256,address,address,bytes20)","4b91ab35":"unfollow(bytes32)","4b922b12":"getDataColla_AB_01(string)","4b92738e":"migrateBalances(address[])","4b92f39e":"tradingClass(address)","4b930503":"registerName(address,string)","4b931600":"evaluateCategory(address,uint8,uint256,uint256)","4b932327":"novaluetoken(uint256,string,string)","4b93fec0":"BetContract()","4b944b9b":"post(bytes32,bytes32)","4b94f50e":"getTokenPrice()","4b95dcc0":"ViberateCrowdsale()","4b960794":"spotsLeft()","4b963025":"addUniqueSaleTokensMulti(address[],uint256[])","4b96b0ee":"registerZone(bytes8)","4b96f855":"burnPercentageDefault()","4b97aed9":"numOptions()","4b97e6cc":"withdrawEthBalanceSave()","4b991bde":"challenge(uint64,uint256,bytes,bytes,bytes)","4b997d9a":"sendTokens(uint256,address,bool)","4b99f0c5":"setTradingPairCutoffs(bytes20,uint256)","4b9a22af":"teamWon()","4b9b808d":"setResetVoteKindnessEvery(uint256)","4b9c4358":"betPlaced(address,uint256,uint256)","4b9c78e5":"buyEngineer(uint256[])","4b9cdbe7":"addCurrencyInternal(uint256)","4b9ce83c":"recordAssetPrice(uint128,uint128,uint128)","4b9d5047":"PlutoToken()","4b9d8624":"getLinks(address)","4b9de7a2":"dataIdentifiers(uint256)","4b9de81e":"endTimeRound2()","4b9e7ecd":"test_1_restrictDoubleVote_shouldThrow()","4b9eb771":"CAT_PER_ETH_FIRST_EARLY_BIRD_RATE()","4b9ed302":"setEarlyInvestorsBonus(uint256)","4b9ee106":"setMetaBetWeight(uint256)","4b9eea9b":"decodeKYCFlag(uint128)","4b9f5c98":"vote(bool)","4b9faf4c":"setTokenBalance(uint256,bool)","4ba034dc":"unlockGrowthPoolTokenSupply()","4ba0dd3c":"BotFarmer()","4ba1f098":"acceptRequest(uint256)","4ba20050":"getProduct()","4ba2363a":"pot()","4ba26466":"TPP2018TOKEN()","4ba2ab8a":"RockPaperScissorsAdvanced()","4ba2d5ff":"setThreePowerAges(uint256,uint256,uint256,uint256,uint256,uint256)","4ba336e5":"calculatePoolCut(uint256)","4ba4079a":"enableSwitch(bytes32)","4ba4c16b":"guess(uint8)","4ba4d784":"getMinutes(uint256)","4ba5b7b3":"crowdsaleRefund()","4ba6e72e":"advisoryTotalSupply()","4ba71f3c":"OxToken(address)","4ba79dfe":"removeAddress(address)","4ba8fde0":"_computeIncentiveCut(uint256,uint256)","4ba90201":"setFinishPreICO(uint256)","4ba9bb67":"arr(address,address,uint256)","4ba9fb71":"closeAskOrder()","4baa39be":"editBet(uint256,uint256,uint256)","4baa8160":"triggerAttack(uint32,uint128)","4baa9dc7":"addCashback(string,address,uint256[],uint256[])","4baaab80":"MyToken(string,string,uint256,uint256,address,address)","4bab0236":"wercoin()","4bad0881":"P4WDToken()","4bad294d":"asFunc(uint256)","4bad3327":"_mul(uint256,uint256)","4bae2ef1":"referrerBonus()","4bae6659":"fixedDeposit(uint256)","4baf4a76":"addToWhiteListMultiple(address[],address[])","4baf7a30":"TypesToBytes()","4bafa2a4":"totalMIT()","4bafa437":"setSECOND_STEP_MULTIPLIER(uint16)","4baffdc6":"_withdrawHoldVault(uint256)","4bb017a1":"destroySalesManager(address)","4bb07665":"whitelistUser(address,uint128)","4bb13055":"returnAllAvailableFunds()","4bb13e63":"setTripleRoomMin(uint256)","4bb22b5a":"execReturnValue(uint256)","4bb24399":"survive(address,address,uint256)","4bb278f3":"finalize()","4bb2e417":"SokToken()","4bb32e8c":"setDNoEditors(bytes32)","4bb37790":"restrictionExpiraton()","4bb4b260":"cashAllOut()","4bb593b2":"updateUser(address,string,uint256,uint256,uint256,string,bool)","4bb6e766":"checkTransferAllowed(address,address)","4bb72dea":"setPriceStep4(uint256)","4bb77d9d":"updateRates(uint256[])","4bb8596e":"managerSet()","4bb89c4d":"sendBounty()","4bb9962f":"HexelErc20Token(string,string,uint256)","4bba32fb":"round3StartTime()","4bba38b8":"getRef(address,address)","4bba863e":"getEthOfferor(uint256)","4bba8a58":"RepostiX(address,address)","4bbaa946":"getAllArea()","4bbb216c":"_target(address)","4bbb58b2":"setVirusInfo(uint256,uint256)","4bbbe0cc":"exporter()","4bbc142c":"allowOwnership(address)","4bbc2a4a":"changebank(address)","4bbcc1bc":"payoutSelf(address)","4bbcd6e8":"buyPresaleTokens(address)","4bbd3061":"DateCreateToken()","4bbf2c69":"excludeInvestor(address)","4bbf3a7a":"swapToken(uint256)","4bc091a3":"getCrowdsaleStartAndEndTimes()","4bc18a64":"deleteLock(address,uint8)","4bc1aa42":"VESTING_ADVISOR_CLIFF()","4bc24ec5":"right61(uint256)","4bc2a657":"setVoter(address)","4bc32ea2":"getBidCountForAuction(uint256)","4bc36600":"reorganizeMembers()","4bc3b153":"REWARD_FORWARD_POSITION()","4bc3df81":"BuyBooster(uint256)","4bc4549c":"todaySold()","4bc4d2ba":"KIN_PER_WEI()","4bc4e892":"startNextEra(bytes32)","4bc53249":"toB32(uint256,bytes,uint256,address)","4bc57a7c":"Medis()","4bc5d101":"CreatorWithdraw(uint256)","4bc70b1e":"withdrawFunds(uint16)","4bc8c477":"VirtualRealEstate()","4bc935d7":"verifyProof(bytes32[],bytes32,bytes32)","4bc9fdc2":"calcMaxWithdraw()","4bca4626":"ethWeiRaised()","4bca5cc0":"_setAdmin(address,bool)","4bca7f95":"NigeriaNairaToken()","4bca893d":"Count(uint256,uint256)","4bcb776f":"sliceIndexThrow()","4bcbcd89":"getEngineerLv1(address)","4bcd245d":"gameStatusSet(bool)","4bce2e9b":"totalEnjSold()","4bce79a1":"getAllSocialAccounts(bytes32)","4bcf244b":"ECRecoverWrapperF(bytes32,uint8,bytes32,bytes32)","4bcf74b2":"AccountMinterAdded(address,address)","4bcf8645":"returnFundsToClient()","4bd09c2a":"distributeTokens(address[],uint256[])","4bd1c253":"ChipExists(uint32)","4bd21127":"setAdminLevel(address,uint8)","4bd22521":"Electricity(string,string)","4bd22766":"refundETH(address,uint256)","4bd3a225":"setMultiplePreSalesSpecialUsers(address[],uint256)","4bd3af72":"sellGolds()","4bd3b4c6":"allowAuditor(address)","4bd4ddb9":"testThrow_invalidZeroValue1()","4bd4e770":"CheckSign(string,string)","4bd50dcf":"sendFromContract(address,uint256)","4bd544e8":"isEligibleToPlay(address)","4bd54f04":"dynamic()","4bd5610d":"jsonCat(string,string,int256)","4bd58c92":"LogBuyForFiat(address,uint256)","4bd67ced":"get_last_asset_document(bytes32)","4bd70ea3":"testFailGetUnset()","4bd7730b":"Senpona(uint256,string,uint8,string)","4bd79ac1":"lastCalculationRewardTime()","4bd889b4":"removePersonalLock(address)","4bd8ae6f":"endCoinFlip(bytes32,bytes32,bytes32)","4bd9d76c":"payUnderwriter()","4bda2ad0":"addNote(bytes20,string)","4bda3f2b":"test_insert_findWithHintPrevUpdateTail()","4bda87b5":"GCHToken(string,string,uint8,uint256)","4bdb7369":"hasBoughtEgg(address)","4bdbb944":"GodviewChain(uint256,string,uint8,string)","4bdbea2f":"latestBalanceCheck(address)","4bdc44ae":"setNote(uint256,bytes20,string)","4bdc4ffe":"ProposalTallied(uint256,uint256,uint256,bool)","4bdd6a8e":"KPOPIO_CONTRACT_ADDRESS()","4bde38c8":"platform()","4bdec44a":"VotingRightsGranted(address,uint256)","4bdf1b0e":"receiveApproval(address,uint256)","4bdf6667":"IsGenesisAddress(address)","4bdf7e8b":"_updateExperience(address)","4bdfa061":"postGenesisSales(bytes32,uint256,uint256)","4bdfa999":"Given(uint256,address)","4bdfbb75":"isCanvasFinished(uint32)","4be02f32":"getPlayerWithdrawal(uint256,uint256)","4be04fd9":"getMyLastScore()","4be185f0":"editionOf(uint256)","4be36323":"bonusRoundId_()","4be366d5":"purch(address,address,uint256)","4be39f2f":"FEED2()","4be422ae":"logOut()","4be42c08":"updateRewardAmount(bytes32,bytes32,uint256)","4be5739e":"PUBLIC_SALE_LIMIT()","4be62668":"MainSaleDistributed()","4be6c20a":"Error(uint8,address,address)","4be7183a":"init(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4be7ced7":"withdraw_team_fund(address)","4be860eb":"getMinGas()","4be9b992":"THRESHOLD3()","4be9d332":"jsonCat(string,string,string)","4bea4df7":"addLeaderboard(string,uint256)","4beb031b":"numBallots()","4beb536e":"allWagered()","4beb9e32":"approveByAddress(address)","4bebbf14":"setother(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4bebdab7":"uintArrayToString(uint256[])","4bec8335":"changeSafeguardStatus()","4becfd56":"getCurrentGameInitialMinBetSize()","4bed33b8":"SHARE_PURCHASERS()","4bed6c23":"donationAmount()","4bed81c8":"getWalletUser(uint152)","4beda18b":"BILLION()","4bee09e1":"changeTicket(address)","4bef6de9":"determinePrize(uint256)","4bef71ac":"changeColorTeal()","4befc326":"temperatureMax()","4bf003fa":"After(uint256,bytes32)","4bf02421":"calculateAttributeTotals(uint256)","4bf0d331":"canDeposit(address)","4bf1b68d":"setTokenSupplier(address)","4bf2c7c9":"setBurnFee(uint256)","4bf2d314":"setAdvisoryPool(address)","4bf365df":"mintable()","4bf49313":"requestPayment(uint256,uint256,string,address)","4bf4e421":"client_address()","4bf5ac36":"saleAgent2()","4bf69206":"stakeFor(address)","4bf79cd9":"OutCloud(address,address)","4bf80d39":"giveConsent()","4bf899a3":"buyPosition(address,uint256)","4bf8e7a2":"getPriceInPastAuction(address,address,uint256)","4bf9407f":"changeRecipientAddress(address)","4bf96e60":"nextPurchasableBlocknumber()","4bfa0d11":"TDEEndDate()","4bfa798a":"getWarlordChestAvailable()","4bfad14d":"WinnerPicked(uint8,address,uint16)","4bfaf2e8":"getPendingVersionTimestamp()","4bfbe5df":"eventDate()","4bfc4782":"change_a(address)","4bfde393":"myWinShare()","4bfe2779":"setETHRate(uint256)","4bfe642d":"proWallet()","4bff1b95":"STARTING_KEBAB()","4bff5009":"getUserByName(string)","4bff8e51":"_runAdvanceClock(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4bffc5e4":"allowance(address,uint256,uint256)","4c007b35":"BigerToken()","4c0348ee":"nInvalidatedHashes()","4c04f7f2":"addTranslatorContent(address)","4c05a636":"Registrar(bytes32,uint256)","4c05b40e":"createShortId(bytes32,bytes32)","4c05df98":"startEarlyBird()","4c062c81":"moveNapkinsTo(uint256,address)","4c07fb4f":"editAddressDescription(address,string)","4c081138":"assign(uint256)","4c097cb4":"trigger(bytes32)","4c0999c7":"bytes32ToBytes(bytes32)","4c0a6532":"lrcTokenAddress()","4c0aac9a":"WithdrawFunds()","4c0b1c90":"getMarketer()","4c0b2973":"mfrOf(bytes32)","4c0bcfe5":"getTransferableBalance(address)","4c0bd3ef":"getLLV_edit_16()","4c0c0ac2":"rewardsAllocation()","4c0ddea8":"decodeTokenImbalanceData(uint256)","4c0e207a":"__outputCallback(uint256)","4c0e9e6a":"acquisitionsWallet()","4c0eceb5":"plusOnePonzi()","4c0ee2e1":"unPausePriceRaise()","4c0eed51":"addMarketMaker(address,address)","4c10d0a5":"addFrostTokensMulti(address[],uint256[],uint256[])","4c123019":"tokenFallback(address,address,uint256,bytes)","4c125e79":"cancel(uint64)","4c12b33f":"burning()","4c12d8b9":"recipientETH(address)","4c12f8bb":"creditCEO()","4c13017e":"Transfer(bytes32,address,uint256)","4c1334a8":"GoodTo(uint256,string,string)","4c1344b7":"isGuilty(address)","4c136ea8":"totalEDUSAllocated()","4c13fbb2":"ImageToken()","4c146f38":"getFrontEndTokenBalanceOf(address)","4c14743b":"UnlockedBalanceOf(address)","4c148efb":"CollectPayment(address,address,uint256)","4c14f334":"getCouponBonus(string)","4c15469c":"tresholds()","4c1674e5":"descOf(uint256)","4c167a6e":"approvePreSigned(bytes,address,uint256,uint256)","4c1736a0":"subFrozen(address,uint256,uint256,bool)","4c174ef0":"isWitness(address,address)","4c176b21":"WALLET_SALE()","4c17b322":"performRead2()","4c182a95":"doDeveloperGrant()","4c18e57e":"PositiveWhuffiesSent(address,address,uint256,string)","4c18e960":"allowRecurringBilling(uint256,uint256,uint256,uint256)","4c19a199":"openGameResult(uint256,uint256,uint256,string)","4c19dd1c":"VicDemToken()","4c1b2446":"transmitInteger(address,bytes,bytes,uint256,uint16)","4c1b64cb":"deleteAccount(address)","4c1b8ffd":"voteCost()","4c1bbef8":"claimerKey()","4c1ccadf":"SmartexInvoice(address,address)","4c1d1fde":"withdrawTokens(address,uint256,uint256)","4c1d79ee":"setSalePeriod(string)","4c1d9d48":"tokenIndexById(uint256)","4c1e4169":"BIZDEV_WALLET()","4c1f20ec":"CEO_TEAM()","4c1f524f":"convertToMiniTtc(uint256)","4c1f7635":"getAccountRest(address)","4c1f85ae":"updateHydroMap(address,uint256,uint256)","4c1fbde8":"getPlayerColor(uint256,address)","4c20179e":"devAllocation()","4c2067c7":"expired()","4c207ac8":"setTraps(uint256,uint16,bytes)","4c21eb07":"put(string)","4c21fa45":"getNoteByIndex(uint256)","4c2233a5":"withdrawAll(uint256,address)","4c228656":"advisorsAllocationTokenSend(address,uint256)","4c22a8d1":"kvcAdd(uint256,uint256)","4c22b792":"calc_wei_rewards(uint256,uint256,uint256)","4c22c119":"isUser()","4c2324bb":"toBytes(uint256[])","4c23ba50":"removePeer(address)","4c25162a":"Babatoken()","4c2516de":"swapToken(uint256,address)","4c25727b":"viewPollData(uint8)","4c258eb1":"getQtyFilledOrCancelledFromOrder(bytes32)","4c25deb5":"USER_GROWTH_TOKENS_RESERVED()","4c26064b":"MVGcoin(uint256,string,string)","4c266e11":"setExchangeGroup(address,uint256)","4c26aaa2":"TokenExchange()","4c26b6eb":"total_buy()","4c281603":"getPlayerMax(uint256)","4c28a043":"adminGetFeeDial()","4c294188":"customer_tickets(address,uint256)","4c2a664b":"purchaseNotes(uint256)","4c2a799f":"checkFileProof(bytes32,bytes32[10],uint256[4],bytes32[],uint256)","4c2bc9a9":"assertEq26(bytes26,bytes26)","4c2bd226":"getDescriptionHash(address)","4c2d0378":"getAllTransactionIds()","4c2d71b3":"setConfigAddress(bytes32,address)","4c2d8649":"transferComplete(address,uint256,bytes)","4c2db6d8":"buyCoin(uint16)","4c2f04a4":"AddMessage(address,uint256,string)","4c2fac53":"requireFunction()","4c2fc8b2":"acceptProposedMilestones(bytes32)","4c2fe456":"right94(uint256)","4c2ff0ae":"getLLV_edit_31()","4c3052de":"submissionGasPriceLimit()","4c316f70":"mineCoins(uint256)","4c31a0ca":"mintFoundersRewards(address,int256)","4c31df50":"nextroundsolsforhire()","4c3221e1":"complexityForBtcAddressPrefix(bytes)","4c32a444":"_onCanvasCreated(uint256)","4c330471":"getReferralBalance()","4c33fe94":"cancel(address)","4c34c8de":"USDCToken()","4c34d7e9":"UNITED_NATIONS_FUND()","4c352323":"getNewVoting(uint256,bytes32[],address[],uint256[])","4c364ceb":"createAccessory(uint8)","4c36c36e":"resolveBet(uint256)","4c36cf16":"addRoundPrice(uint256,uint256,uint256,address[])","4c37077f":"chargeBuyer(uint256,address,uint256,uint256)","4c381350":"meteredPrice(uint256)","4c382d99":"terminateEmployee(address,uint32,uint8)","4c38661d":"lastPing(address)","4c387d82":"NSCToken()","4c38c366":"reLoadXaddr(uint256)","4c3997d4":"cancelBuyAuction(uint256,address)","4c3a00cb":"totalTradeRecords()","4c3a1a1a":"returnUserGrowthPoolTokens(address,uint256)","4c3a6ae0":"isMultiSigWallet()","4c3a9675":"ManagerProxyTargetMockV2(address)","4c3acb86":"debug(string,string)","4c3b67b4":"withdraw_for(address)","4c3ba268":"getBySemanticVersion(uint16[3])","4c3bf0b5":"changeInitialCost(uint256)","4c3d1f00":"EthDailyLimitChange(uint256)","4c3dff01":"InitialBasicBalance()","4c3ec50b":"FarziToken()","4c3eea9e":"generalLog(uint256)","4c3ef6dc":"minimumTokenThreshold()","4c3f333f":"Kalypso()","4c3f8ec0":"Tier_Wildcat_Registration()","4c409b80":"ChangeWallet(address,address)","4c413139":"minutesToPost()","4c418879":"getMyDino()","4c41a6c7":"blockThreshold()","4c41bf9d":"getOnBurnTargetValue()","4c4316c7":"donate(uint64,uint64,address,uint256)","4c433843":"parityOwner()","4c439436":"getTicketsAtAdress(address,address)","4c44d53f":"test_fourInvalidEqBytes32Message()","4c45c7ec":"setPhase(uint8,uint256,uint256,uint256,uint256,uint256)","4c466d37":"signer(bytes)","4c46e52c":"trancheOneBalanceOf(address)","4c46fb73":"stageCaps(uint256)","4c471cde":"scheduleCall(address,bytes4,bytes,uint256,uint256,uint8,uint256)","4c4766e8":"KittenRegistry()","4c478b62":"ERC827TokenMock(address,uint256)","4c47e9ee":"setLockedConfig(address[],uint256[],uint256[])","4c480c2a":"ownerCandidat()","4c4870c6":"checkGoal()","4c488dac":"getChannelValidUntil(bytes)","4c49515d":"presaleTokensIssued()","4c4a386f":"refundEnabled()","4c4a4c67":"assertEq2(bytes2,bytes2)","4c4a9761":"tokenRate4()","4c4aea87":"getReleaseData(bytes32)","4c4bf936":"landData(int256,int256)","4c4c23dd":"upgradeGreatCoin(address)","4c4c447e":"cancelBattle(uint256)","4c4cb69e":"INVEST_AMOUNT()","4c4cea5a":"completeAt()","4c4cfc3b":"tokensForEcosystem()","4c4d07e7":"isBouncer(address)","4c4d460e":"LogCampaignCreated(address)","4c4dc6e0":"docCount()","4c4deecb":"__callback(uint256,string)","4c4e03f2":"_getExtraParam(bytes)","4c4e829c":"TransactionRevoked(uint256)","4c4efef7":"totalCLNcustodian()","4c4f1386":"WartecToken()","4c4fa89a":"getChildBranch(bytes32)","4c50ea27":"RHOC(uint256,address)","4c515fb5":"TEAM_VESTING_CLIFF()","4c51b021":"substract_individual_shares(uint256)","4c524be4":"selectWinner(uint256)","4c53adb0":"blackFridayEndBlock()","4c54cc1d":"managerETHaddress()","4c56e992":"refillContract()","4c574afe":"unblockSecondStake()","4c575fcc":"numberOfRawEarlyPurchases()","4c57fc28":"setTokenMintFeeReceiver(address,address,address,address)","4c5802c1":"getPhaseAddress()","4c585ce4":"approveMultipleUsers(address[])","4c5879cf":"WidinShares()","4c58994c":"TrypCrowdsale()","4c594c1e":"limitDateCrowdWave3()","4c59b47c":"EthereumLottery(address,address)","4c59f021":"CakCrowdsale(uint256,uint256,uint256,address)","4c5a2044":"licenseCostDenominator()","4c5a82cb":"reportTemperature(int8[],uint32[])","4c5a94fe":"_removeToken(address,uint256)","4c5b632a":"addcoin(string,string)","4c5be574":"getOdds()","4c5cbe9a":"getBalancesForTeam(address)","4c5d6d93":"totalCrowdSale()","4c5df57a":"createLoan(address,address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,string)","4c5df737":"addCar(string,string,string,uint16,string,address)","4c5f338b":"CheckStudentofCourse(uint256)","4c610ba4":"totalRewardThisYear()","4c611268":"balanceOfUnclaimedCookie(address)","4c6226fc":"oraclizeFee()","4c62a644":"withdrawComission()","4c64384c":"maxPrivateSale()","4c64cf92":"mint_time_locked_token(address,uint256)","4c65b2b3":"ethOwner()","4c65c62e":"AgentContracteGalaxy(address,address,address,uint256,uint256)","4c661a2c":"DaoOwnershipTransferred(address,address)","4c66326d":"deregisterCallback(address)","4c6686d8":"CONFIG_FEES()","4c66bcc1":"WorldWideLoveToken()","4c67567a":"firstLockAmount()","4c676725":"fundTeamCompany()","4c68df67":"totalReserve()","4c69c00f":"setOracleAddress(address)","4c69ec93":"changeReceiver(address,address)","4c6a3334":"buyEthLootbox(address)","4c6adb31":"firstReporterCompensationCheck(address)","4c6b25b1":"results(bytes32)","4c6b6cad":"newProposal(string,bytes)","4c6c27a1":"judgeCustom(bytes32,bytes32,bytes32,uint256,bytes32,uint256[4],bytes32[10],uint256[4],bytes32[])","4c6c6a5c":"upgradeFrom(address,address,uint256)","4c6c8bc3":"distribute(address[],uint256[],bytes32[])","4c6d1d9e":"checkOutTag(string)","4c6d350b":"approveShutdown(uint256)","4c6d8aac":"hasParameters()","4c6e4453":"EcoLend()","4c6e5926":"send_to_side_chain(uint256,address,uint256)","4c6ebbbe":"maxIcoTokenLimit()","4c6fc20f":"setDisbursingAddr(address)","4c703ccd":"FirstERC20TestToken()","4c70b6b2":"deList(address)","4c714ed4":"DescriptionChanged(string,string)","4c7241f8":"Potentl()","4c738909":"getMyBalance()","4c73eef6":"card_black_minamount()","4c743c45":"FCTOKEN()","4c750bca":"bountyFunds(address,uint256)","4c75dc8f":"EFOcallBack(string)","4c75fbca":"getThirdAddressBalance()","4c76318e":"award(bytes32)","4c77a28d":"AppleCoin()","4c77c0e2":"period2Numerator()","4c77e5ba":"getAddressValue(bytes32)","4c780596":"UpgradeSpace(uint8,uint16)","4c783bf5":"isControllable()","4c78529e":"setOfficialUrl(string)","4c78b276":"getShare(address,uint256)","4c7940c5":"getWithFrozenStockBalance(address,address,uint256)","4c79afe0":"EventBuyShip(address,uint32,uint32)","4c7a0271":"buyMiner(uint256[8])","4c7a2254":"checkMyWithdraw()","4c7a5c0f":"ArtifactCoin(address)","4c7ab28d":"setMaxToSell(uint256)","4c7ae3ac":"getNameFromKoikeToken()","4c7b18fd":"ratioUpdateTime()","4c7b8fba":"contributionHashes(uint256)","4c7c3ca1":"KryptopyCrowdsaleMock(uint256,uint256,uint256,uint256,uint256,address)","4c7c71fe":"startTimes()","4c7ce18a":"withdrawReturns()","4c7cfd9b":"MarketboardListingPriceChanged(uint256,uint256)","4c7d3e3f":"icoIsClosed()","4c7d7d3f":"standardToken()","4c7e6bab":"tokensPerCentsDayOne()","4c7f0bdd":"isBackend(address)","4c7f74df":"EtherDelta(address,address,address,uint256,uint256,uint256)","4c7fa728":"getPlayerLeftDividend(address)","4c808da8":"StageUpdated(string,string)","4c80b03b":"minTransAmount()","4c80c937":"getEpochData(uint256,uint256)","4c80f5c1":"minimumAmountToParticipate()","4c813d6d":"sendItDv(string)","4c81a1db":"addressPayableFunc(address,address)","4c81c4d7":"startStage2Time()","4c81e13a":"incentiveDistributionRoundDenominator()","4c81e48b":"testToUint()","4c8316a6":"showTokensStaked()","4c833532":"resumeTransfer()","4c839beb":"getContributionTokens(address)","4c840214":"getBackToken(address,address,uint256)","4c841e5d":"_setBlacklistedUser(address)","4c85a8f3":"isAllowedToMint(address,address)","4c85b425":"buyShares(address)","4c85d2e6":"addImmigrationOfCountry(address,uint256)","4c86c2e5":"setPortUpdate(uint16)","4c86e97b":"bonusTokensLeft()","4c873c48":"tokenSetup(address,address,address)","4c87effd":"delete(bytes32)","4c88bc26":"YEAR_TWO_SUPPLY()","4c899118":"getProposalFromID(bytes32,uint256)","4c89c4c7":"getHash(bytes10,uint8)","4c8b16f4":"setTimeStep(uint256)","4c8b8ca7":"distroyBuyerToken(uint256)","4c8bae93":"_isTradeable(uint256)","4c8c121e":"getGameHash(address,uint256)","4c8cab79":"largestStake()","4c8cc20b":"toContentID(address,string,string,address,uint256)","4c8d1e42":"DockCrowdsale(uint256,address,address)","4c8f3562":"computeCooldownSeconds(uint16,uint16)","4c8f4810":"buyMCT(address,uint256)","4c8fe526":"next()","4c90aaeb":"randomize(bytes32)","4c9151e6":"TransferStarted(address,address,uint256[],uint256)","4c922a9f":"changeColorPurple()","4c9297fa":"scheduleStart(uint256)","4c93505f":"setRevoke(bool)","4c9362aa":"addActiveUserListArr(address)","4c93c1a6":"GetUpTickPrice(uint256)","4c9478ce":"_yearThreeClaimed()","4c947c86":"getInitInputDataBytes(address,address,address,address)","4c94ac6a":"clearMilestones()","4c9599f2":"validityDate()","4c95baf3":"compoundingFreq()","4c95ca9c":"setRatePreICO(uint256)","4c95cb98":"OracleBase()","4c966822":"winnerWithdrawal()","4c96a389":"deploy(address)","4c96f0cc":"transferAllTokens()","4c96f281":"getAllPublishers()","4c97057a":"LogWinner(string)","4c970b2f":"foo(int256)","4c977972":"Soft_Cap()","4c97c836":"upgradeConstitution(uint256)","4c982872":"ElextroCoin()","4c985dfb":"newTokens(address,uint256)","4c98aec9":"CASHX()","4c990cc7":"startAirdrop(address[],uint256[])","4c9b30b4":"allow(bytes8)","4c9b60dc":"changeUserEthAddress(address,address)","4c9b760d":"changeMaxContribution(address,uint256)","4c9e2779":"balancesLocked2Y()","4c9e502e":"totalLoanAmount()","4c9ed763":"requestTokensBack()","4c9f166d":"bettingAllowed()","4c9f45eb":"repossessionBountyPerHundred()","4c9f66c7":"feePot()","4ca0a305":"GlobalIdolCoinToken()","4ca14270":"AddressChanged(string,address,address)","4ca15352":"airDropCount_()","4ca168cf":"register(bytes,uint256,address,string,uint256)","4ca18ebd":"reject(uint256,string,uint256)","4ca1c417":"isValidNameLength(string)","4ca1fad8":"addRequest(uint256)","4ca3a111":"getWeiPriceMicroKeys()","4ca3e9b8":"getProjectAddress(uint256)","4ca40518":"ReBornEnergyCoin(uint256,string,uint8,string)","4ca43f41":"transferAny(address[],uint256)","4ca50f59":"sellsTokens()","4ca5558c":"AllCaptcha()","4ca63a84":"TimeLimitedStoppable()","4ca64b3a":"bulkTransfer(address[],uint256)","4ca6ba2f":"AporooToken(uint256,string,uint8,string)","4ca6d7e6":"tier2Time()","4ca6fcfc":"registerVIP(address,address,uint256)","4ca7fbd0":"updateTokenPriceWeekTwo()","4ca82b52":"finalLoos()","4ca8b0d0":"registerExistingThrone(bytes,address,uint256,uint256)","4ca8c1e8":"isInMaintainance()","4ca92e08":"deductExtraBalance(address,uint256)","4ca98997":"getAmount(uint256,uint256)","4ca9b258":"contributorRefund()","4caa1a09":"_calculatePaymentToOwner(uint256)","4caa7f37":"withdrawSnowflakeBalanceFromVia(string,address,string,uint256,bytes,bytes)","4cad12e0":"orders_sell_price(address)","4cad3438":"setRateFinalStage1(uint256)","4cad42d3":"testWager()","4cae5f99":"loanRepaymentNotification(uint256)","4caeebd0":"STAGE_FOUR_TIME_END()","4caf6231":"COLOR_WHITE()","4cb0c7a1":"getOrdersOfVendor(address,uint256,uint256,bool)","4cb10ed3":"hasStartTimePassed(bytes32)","4cb44f8d":"getConfigEntryAddr(bytes32)","4cb532db":"socWarefareAddr()","4cb5465f":"transferWithLock(address,bytes32,uint256,uint256)","4cb5a45d":"GSUMedal()","4cb5ef77":"closeVoteRevealPhaseIfAllowed(address,bytes32,bytes32)","4cb5f1c6":"totalsum()","4cb6bf73":"FZTToken(address)","4cb6d6af":"finalizeCrowdsale(address)","4cb6f4a5":"voteRequest(uint256)","4cb71b9b":"getAllReleaseHashes()","4cb79536":"presaleStartBlock()","4cb7da65":"abortMatch(uint256)","4cb7dd6f":"popLeader(address)","4cb84b9a":"getIcoCap()","4cb85312":"_addInvestor(address)","4cb85356":"BranchSender(uint256,bytes32)","4cb88ad8":"ABEToken()","4cb93ff8":"capTokenAmount()","4cba4ca4":"updateGene(uint256,bytes)","4cba5c6a":"setResults(uint256[4])","4cba67ce":"addAddressToAccountForUser(address,bytes,bytes,address,bytes32)","4cbabcdc":"invest(bool)","4cbac3d2":"calculatePurchasedTokens(uint256,uint256)","4cbb4a0a":"_removeTokenFromAllTokensEnumeration(uint256)","4cbb7532":"setBorrowAgreement(uint256,uint256,string,string)","4cbbb987":"DOSXToken()","4cbc07f2":"weisPerBigToken()","4cbc49ad":"claimRewardManually(address)","4cbc82cd":"getTrackByArtist(address,uint256)","4cbd2b74":"allowanceByLegacy(address,address)","4cbe02a5":"createAuthorDrawings(bytes32,bytes32,address,string)","4cbe552c":"myEntityStructs(uint256)","4cbee813":"logout(string)","4cbf3d4c":"getNumbersOfPick(uint256,uint8)","4cbf6ba4":"hasDNSRecords(bytes32,bytes32)","4cbf867d":"intervalSecs()","4cbfafd9":"DefaultReleaseDelayed()","4cbfbf47":"REAPER_INTREPID_MAX_CARGO()","4cc05a71":"withdrawCount()","4cc09eac":"tokenRatePre()","4cc0a885":"maxRevealSeconds()","4cc0ee3c":"modifyDescription(address,string)","4cc22528":"setRateForOrder(bytes32,uint256)","4cc22f9d":"getSaleEnd()","4cc2a4bb":"_preValidateTransfer(address,address,uint256)","4cc2b5d0":"addPolicy(bytes32,uint256,uint256,uint256,string)","4cc2c0fe":"getTotalFor(uint256,uint256)","4cc3a6b0":"ConvertQuote(uint256)","4cc45f50":"changeAddressQueen(address)","4cc47910":"oraclizeQueryIdsToBetIndices(bytes32)","4cc53838":"getSaleContractTargetEtherMin(address)","4cc60757":"getOperator(address,address)","4cc6083a":"totalTrading()","4cc62409":"EOSOwned()","4cc653c8":"calculateDividends_(uint256)","4cc682ee":"getPubKeyHash(bytes20,uint8)","4cc747c8":"unlistAllOpenProposals()","4cc78983":"setPreviousDungeoonId(uint32)","4cc7a88d":"sendLoveToken(uint64,string,string,string)","4cc82215":"remove(uint256)","4cc87328":"adminWithdrawMiscTokens(address,uint256)","4cc885d4":"right65(uint256)","4cc9f4e1":"lockTokenController()","4ccb5a33":"canClosePot(string)","4ccb908f":"auctionSuccessBonus()","4ccbd06b":"MIN_DEPARTURE_LIM()","4ccbe888":"getLongExtra()","4ccbf17b":"presaleAddressAmountHolder()","4ccc4c36":"getPendingOracleFor(address)","4ccc5da0":"sold(bytes32)","4cccb7ba":"unrestrictedWithdraw(uint128,address,uint256,uint128)","4ccd0e1e":"Flippitt(string,string,uint8,uint256,string)","4cce4d63":"addNewCompany(string,uint256,uint256,uint256,uint256)","4ccee9b6":"getAddr(bytes32)","4cceeccd":"setFee(uint32,address)","4ccef7e0":"averageSoldPrice()","4ccf05cd":"CompanyTokenPushed(address,uint256)","4ccf8a35":"TokenSupplied(address,uint256,uint256)","4cd06a5f":"iterateNext(uint256)","4cd08d03":"register(string,string,string)","4cd11943":"NewManualInvestor(address,uint256)","4cd18a83":"gimmeEtherr()","4cd217b7":"getPreEntranceTo()","4cd273d1":"tilePrice()","4cd280bc":"popClient()","4cd28aa6":"_queue(address,address)","4cd2b343":"RedBlueToken()","4cd36fb7":"Mine(address,uint256,uint256)","4cd3745d":"getRandomClassId(uint256)","4cd412d5":"transferEnabled()","4cd44519":"stageTokensBought(uint8)","4cd52207":"_claim(address,uint256,bool)","4cd5af91":"CrowdFundClosed(uint256)","4cd5d776":"FundingWithdrawn(address,uint256)","4cd7699a":"eventCardRangeMax()","4cd85837":"mintICOTokens(address,uint256,uint256)","4cd88b76":"initialize(string,string)","4cd995da":"registerCompany(address,string)","4cd9c3e4":"crowdsaleEndsAt()","4cdabb16":"MAX_PREMIUM()","4cdb48e4":"isValidNym(address)","4cdc6a73":"Marriage()","4cdc9549":"_isApprovedOrOwner(address,uint256)","4cdc9c63":"genesisBlock()","4cdcb334":"transferrers(address)","4cdd3002":"setNote(uint256,bytes32,bytes20,string,string)","4cdd3b43":"getScoreForName(string)","4cddae28":"recharge()","4cdfc605":"Refund_user()","4ce0032f":"TutorialToken(address)","4ce01d86":"totalBetValue()","4ce02a33":"overdraftCliff()","4ce053ab":"approveAndPayout(uint16)","4ce0ef95":"getStatus(address,uint256)","4ce11c52":"children(bytes32)","4ce149d7":"setCandyLandSale(address)","4ce14f8c":"FOMOCoin()","4ce18d6b":"getAmount(bytes)","4ce18ec3":"addInterval(uint256,uint256,uint256,bytes32)","4ce197f3":"GetTempStuffExpire(address,uint32)","4ce1e317":"TeamAndAdvisorsAllocation(address,uint256)","4ce309f8":"getElection(address,address,uint256)","4ce37426":"EtherOlympics()","4ce4f927":"getJackpot(uint256)","4ce51b92":"WithdrawSpecialEth(address,uint256)","4ce56c5d":"ethAvailable()","4ce61604":"InitializedTier(uint256,address)","4ce63074":"test_increaseBlockBy5000()","4ce6962c":"numPurchasers()","4ce6a521":"emitAdditionalTokens()","4ce6a74e":"testerNonReentrant()","4ce7033d":"LogWithdraw(address,uint256)","4ce71fac":"getRegionPurchasePixelPrice(uint256)","4ce75274":"setEnableSell(bool)","4ce99591":"Vegan()","4cea7af0":"MembershipChanged(address)","4ceab75e":"newIdTank()","4ceab858":"multiplex_add(address)","4ceaeb35":"PleasePayMe(uint256,uint256)","4ceb0173":"to(bytes32,bool)","4ceba015":"LogCollect(uint256)","4cec73b1":"checkClaimTokenByAddress(address)","4cecac6d":"requestReward()","4ced0a26":"SetData(string,string)","4ced4734":"isPreSale()","4cedf74e":"get_party1()","4cedfc02":"TornadoChain()","4cedfc0c":"activateWhitelist(bool)","4cee81cb":"Marriage(address,address,string,string)","4cef0cb9":"usdPerEthMax()","4cef0ff6":"approveMore(address,uint256)","4cef2221":"ZazToken()","4cef5a5c":"negligibleRateDiff()","4cf00716":"getCreateFeeTokenFeeWindowValue()","4cf045d5":"addSoftwareExecRecord(bytes32,bytes32,uint256,uint256)","4cf0afca":"changeWallet(address,uint8)","4cf1115d":"ethFee()","4cf125de":"Ledger()","4cf127bf":"modelSupply()","4cf178c6":"POWEROFTHREE()","4cf2010e":"addCar(uint256)","4cf21f5f":"CFNDToken()","4cf2c2a2":"Dexter()","4cf2e2dc":"GameStart()","4cf32de3":"getNumTransactions()","4cf33010":"purchaseShare(uint256)","4cf373e6":"addFortune(string)","4cf37429":"AMOCoinSale(address,address)","4cf43440":"Megaloh()","4cf439d8":"_addToPools(address)","4cf4a292":"getHouseEdge()","4cf50009":"genesisCreation()","4cf52fa2":"buyBulkPremiumCar(address,uint256[],address)","4cf5b6c7":"millWeiRate()","4cf61aba":"_canTransfer(bytes32,address,address,address,uint256,bytes,bytes)","4cf6475d":"getPlayerShipCount(address)","4cf76cca":"thirdDiscountPrice()","4cf78170":"allowedAddress()","4cf812ea":"rateRoundSeed()","4cf8b0f5":"BlipToken(string,string)","4cf8dce7":"balanceOfOre(address)","4cf91026":"isAirdropping()","4cf93599":"getPaidInfo(string)","4cf95c21":"shareholderIsToken()","4cf96509":"safeWithdrawalAll()","4cfb4c28":"roundProfit(address,uint256)","4cfc4d30":"VESTING_DURATION()","4cfd5a82":"phaseOneLimit()","4cfddcfb":"getMarketOrderCategory(uint256)","4cfe3e7f":"debitAccount(address,uint256)","4cfe4c69":"getProviderRateHistory(uint256,uint256,uint8)","4cfe50cb":"BAFCToken()","4cfe59a7":"simulateWithdrawalAmount(address,address)","4cfe62c7":"transferRole(string,address)","4cfea68a":"blocksPerDay()","4cfef220":"getSpankPoints(address,uint256)","4cff5d75":"setTokenAllocator(address)","4cff6ae5":"AltToken(address)","4cff7a82":"createDefaultGames()","4d003070":"timestamp(bytes32)","4d015fcc":"Pong()","4d0217b7":"firstSaleComplete()","4d023404":"removeIntermediary(address)","4d02438b":"getMaximumBetHome()","4d02a8fb":"judgeFakeToken(uint256)","4d047055":"monsterIdToNickname(uint256)","4d053af6":"removeAds(address)","4d056f6d":"coolDown()","4d057803":"TEAM_LOCK_TIME()","4d05a822":"JusticeTokenV2()","4d06068a":"airdropToken()","4d0633f6":"assignedAmountToCornerstoneInvestment()","4d07b23d":"buyPrice(uint8)","4d08e0b4":"mediaTokensName(address)","4d0a32db":"minAmount(address)","4d0a391c":"addPayment(uint256,uint256)","4d0a5dbd":"addPermission(address)","4d0ad141":"CAP_USD()","4d0b2a29":"NUM_TILES()","4d0c381a":"Token99(uint256,address)","4d0c5be4":"redemptionLocked(address)","4d0c69d9":"EnterSwap(uint256,uint256,bool,address)","4d0cac9d":"sendCancelValue(address,uint256,bool)","4d0d1cb9":"processTransfer(address,address,uint256,bytes)","4d0d35ff":"getPlayerAddr(uint256)","4d0d80a2":"_getRandom(uint32)","4d0de225":"getWorkerBalance(address)","4d0e8a5f":"MYEX()","4d126774":"validateWhitelisted(address)","4d1271e3":"VersionedToken(address)","4d129486":"max_shares_to_sell()","4d129fb5":"startPre()","4d12b695":"unbanUser(address)","4d12fca4":"exchanger()","4d130369":"interestPaid(address)","4d130e64":"_collectFee(address,address,uint256)","4d134f2f":"createAddresses(bytes32[],address[])","4d13507d":"releaseFund(address)","4d1387b4":"changeRatio(uint256,uint256)","4d13a583":"PrepaidTokensClaimedEvent(address,uint256,uint256,uint256)","4d13c565":"bVideoCost()","4d13d134":"publicAllocatingToken()","4d140467":"EARLY_CONTRIBUTOR_VESTING_CLIFF()","4d14c57e":"claimBasicResources()","4d14e344":"numberOfChoices()","4d15642a":"startMEAMission(uint256,uint256,uint8,uint256)","4d15d797":"_exists(int256,int256)","4d1636c3":"onSold(address,uint256,uint256)","4d16dd41":"communityUnvested()","4d17ed11":"LUVIToken()","4d17f7fc":"sta()","4d182bfc":"getEpisodeDataRandom(uint256,uint256,uint256)","4d1975b4":"gameCount()","4d199766":"WEI_CAP()","4d19cdf8":"DME()","4d1a08cd":"MIN_LIMIT()","4d1a9763":"T8CToken(address)","4d1b93b3":"allowedTransferWallet()","4d1bc2df":"expertThreshold()","4d1bd1fa":"product2_luckybuyTracker()","4d1bfe99":"BenefitGameToken()","4d1c43b2":"ETHUSDPRICE()","4d1c5f83":"EditMode()","4d1ed74b":"maxGuaranteedLimit()","4d1f8c31":"owner(uint64)","4d1f97ba":"LastResult(address,uint8,uint256)","4d1ff181":"setPaymentEnabled(bool)","4d207d9a":"identify(address)","4d20b992":"setLargeCapWhitelistParticipants(address[],uint256[])","4d20d4bc":"BET_TYPEHASH()","4d21a24c":"generateLockId()","4d22b9c8":"DMSContract()","4d22d1d1":"vestTime()","4d2301cc":"getEthBalance(address)","4d238c8e":"addValidator(address)","4d23aaa8":"foreignBuy(address,uint256,uint256)","4d242bbc":"adjustTotalSupplyCheckpoints()","4d253629":"updateChangeAttemptCount(address)","4d25cc91":"transfer_token(address,uint256)","4d268ddd":"payImporterBankForGoodsBought()","4d27a548":"rICO(address,address)","4d28ca02":"addMultipleContracts(bytes32,bytes32,bytes32,bytes32,address[],bytes32)","4d298265":"isWhitelistedPresale(address)","4d2a16e6":"myTradeValue()","4d2a30c1":"customerDepositedEther()","4d2a99a5":"GVOptionProgram(address,address,address)","4d2b1444":"WAITING_TIME()","4d2c29a0":"tokenOfferingAddr()","4d2d0a3d":"token_totalSupply()","4d2d35bc":"TokenPartners(address,address,uint256)","4d2db81f":"alreadySold()","4d2e9d04":"ShowDepositInfo(address)","4d2ee8e7":"GetLoanInfo(uint256,bool)","4d2efe4e":"collectOwedDividends()","4d305073":"uintRound(uint256,uint256)","4d307e3f":"getCurrentReward(address)","4d30b6be":"balanceOf(address,bytes32)","4d314b5a":"ERC20MIST(uint256,string,string)","4d318b0e":"tallyVotes(uint256)","4d32a117":"documentsIds(uint256)","4d32ef8c":"hurifymint(address,uint256,uint256)","4d3314f4":"TotalFee()","4d33e6d7":"hasDisputeSolved(uint256)","4d341bbc":"findSubscriberIndex(address)","4d3465fd":"weicap()","4d34dce1":"AHS(uint256,bytes32,bytes32)","4d358a00":"PreSale(address,address)","4d366398":"runPeerBalance()","4d36dd87":"finalizeTransferChild(uint256)","4d37ec46":"__generateOrderHashes__(address[4],uint256[8])","4d380a0d":"revealBid(uint256,uint256,bytes32)","4d3820eb":"registerUser()","4d3830e5":"releaseFunds(uint16,address,address)","4d387d35":"lockAccount(address,address,uint256)","4d38f6c5":"signTruelove(bytes32,string,string)","4d3915e9":"testF3(uint256)","4d392341":"ICO_BONUS1_RATE()","4d392e49":"getSubjectById(uint256)","4d395384":"configString()","4d399cb3":"updateWhitelist(address,uint8)","4d39ed06":"initialFoundersAmount()","4d39f535":"transferFrom(uint40)","4d39fa7d":"getMultiplierAtTime(uint256)","4d3a01b1":"setLongAirdropPicker(address)","4d3a2f10":"lastReceivedMessage(address)","4d3b915e":"minTokenSale()","4d3bdb82":"KickcityToken()","4d3cd84e":"setCanAnyMint(bool,int256)","4d3ceef1":"freezeCheck(address,uint256)","4d3cf035":"tokens2ether(uint256)","4d3cfbcd":"NextStep(uint8)","4d3d096b":"isExist(string)","4d3d14f2":"calculateTransferFee(address,address,uint256)","4d3e7682":"DataSellToken()","4d3ec092":"LogReplaceToken(address,uint256)","4d3eff3c":"setICOSpec(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4d3f0a6e":"becomeRenown()","4d3fac53":"getRatingRange(uint256,uint256,uint256)","4d40ed9c":"setSanMaxFree(uint256)","4d40f03c":"SovietCoin()","4d414c18":"Victim()","4d41fee4":"logit()","4d425812":"getCountryCount()","4d428204":"getTransferTime()","4d4282e9":"bytes32IsEmpty(bytes32)","4d42b0e5":"getUserLogin(address)","4d42c7e4":"getTotalIndividualWeiAmount(address)","4d42c952":"destroyedToken()","4d42fc66":"gen0Profit()","4d437034":"getInvestedTokenBalance(address)","4d437a62":"TPCToken()","4d4439fa":"ZipperMultisigFactory(address)","4d444fac":"isDepositAllowed()","4d4479a8":"FLC_address()","4d44f108":"checkProof(bytes32)","4d4549fb":"GDCNumber1()","4d4582a1":"submitChallenge(bytes32,bytes32)","4d461ed1":"completeSale()","4d46474a":"option10symbol()","4d474898":"mine(uint256)","4d474d63":"MAPT()","4d4765dc":"complete_buy_exchange()","4d47ae8c":"setPartyB(address)","4d47ce56":"seek(uint256,uint256,bool)","4d47feaa":"ShareholderDB(uint256)","4d480faa":"setMaxDelay(uint256,uint256)","4d486406":"addEmbassy(address)","4d492b50":"transferMulti(address[])","4d493f24":"maximumTokenIssue()","4d49451c":"candidateExchange()","4d4a919f":"bailout()","4d4aa77f":"getTicketDetails(int256,uint256,uint256,address)","4d4af36f":"setMins(uint256,uint256)","4d4b1a88":"addTokenTrust(address)","4d4b298e":"creditAccount(address)","4d4b3202":"getTrustedTransferSourceValue()","4d4ba1d7":"changeDivestFee(uint256)","4d4c277d":"MAINTENANCE_FEE_PERCENT()","4d4d2b1c":"hasVoted(address,address)","4d4eeaa8":"logoPng()","4d50169e":"distributionThresholds(uint256)","4d50d5f2":"firstPreSaleEndDate2()","4d51fad6":"Bittoq(uint256,string,uint8,string)","4d52a512":"getSoftCap()","4d536c03":"buySaleNonReferral(uint8)","4d536f9f":"validateNameExt(bytes)","4d536fe3":"doit()","4d53c30f":"t4tRaised()","4d547ada":"worker()","4d54dc96":"isNonlistedUser(address)","4d55a924":"KudosRouter()","4d561721":"etherandomSetNetwork()","4d562c82":"freezeProhibited()","4d56a130":"BitfuryToken()","4d586512":"_rand(uint256,uint256)","4d589c5b":"curatorIDOf(address)","4d58e413":"pushDividendPaymentToAddresses(uint256,address[])","4d597b2d":"totalTokensCompany()","4d5a1173":"calculateMaximumBurnAmount(uint256,uint256,uint256)","4d5a225c":"ethCoin()","4d5ad11e":"getAnnualGrantsLength()","4d5b0081":"reward(address,address)","4d5b080c":"scheduleTransaction(uint256,address,uint256)","4d5b335d":"mintHeroAsset(address,uint256)","4d5b608b":"testTransfer(address)","4d5b85f1":"createLighthouse(uint256,uint256,string)","4d5c07aa":"CryptoSim()","4d5d528a":"FeibeiContract()","4d5de6ba":"stageThreeSupply()","4d5e58a4":"purchasedTokensRaised()","4d5e9a2a":"getInterestRatePunitory(uint256)","4d5eceac":"nextAssigneeIndex()","4d5f327c":"supportsToken()","4d5fc38a":"amountOfGames()","4d610837":"indPreSale()","4d61537f":"secretSigner()","4d620299":"postSale(address,bytes32,uint256)","4d622831":"getLast()","4d624906":"PriceChanged(address,uint256,uint256)","4d628c44":"setWagerWinner(uint256,address)","4d62a9da":"MindCoin()","4d62f83c":"_distributeAuctionTax(uint256,address)","4d655aff":"db()","4d65beb1":"getVipInfo(uint256)","4d66a3ab":"testtxorigin()","4d66d44d":"ArtToujourICO(uint256,uint256,uint256,uint256,uint256,address)","4d677d32":"Manager(address,address,address)","4d6804c2":"transferTokensFromVault(address,address,uint256)","4d68282f":"releaseFunds(uint256)","4d689543":"mmLibAddress()","4d6a26be":"tryOpenRoom(address,uint256,uint256,uint256)","4d6a7d33":"collect(address,uint32[])","4d6a813a":"isCutieCore()","4d6aa2e5":"generateReferralAddress(address)","4d6aed53":"getIssued()","4d6b3d83":"Brave()","4d6bc04e":"totalPerTokenPayout()","4d6c3427":"REGULAR_TYPE_COUNT()","4d6c3b6b":"setCompte_4(string)","4d6f58d5":"proveOwnership(bytes,int256)","4d70d1d7":"generateId(uint256)","4d712228":"Storesumdata(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,uint64)","4d71d6be":"finalizeDelegation()","4d720209":"withdrawDistributionCRL()","4d722c4c":"checkWinner(address)","4d729be4":"calculateFishermansFee()","4d730d51":"numOfPurchasedTokensOnEpBy(address)","4d73452e":"START_WEEK_3()","4d7439cb":"getBusiness(uint256)","4d7480ea":"_allowPublishSecret()","4d74d3b4":"setMetadataContractAddress(address)","4d754715":"burningEnabled()","4d7559a8":"totalGoldSupply()","4d7569ac":"TOKEN_SUPPLY_CROWD()","4d77551a":"eleventhTime()","4d782655":"confirmCertificate(uint256)","4d782cbc":"executeSellOrder()","4d78fdc6":"unblockAccount(address)","4d794cfc":"START_ETH_TO_CENTS()","4d79874e":"validateLandTakeover(address,uint256,uint256)","4d79ddb2":"getVotesForItemFromVoterIndex(uint256,uint256,uint256)","4d7a7577":"DURATION_VIPPLACEMENT()","4d7ad1dd":"deleteProposal(bytes32,string)","4d7ad205":"gasRewardPercent()","4d7b8d2f":"DWBTICO(address,address,uint256,uint256,uint256,uint256)","4d7b9bd5":"checkBalance(address,uint256)","4d7ba587":"setDecider(address)","4d7bc8c9":"removeCompanion(address)","4d7c0192":"changeCanUpgrade(bool)","4d7c7485":"getActiveFlag(uint16)","4d7d003f":"dropCoinsSingle(address[],uint256)","4d7d13e1":"getUniqueIdOfPlayerByPlayerAndCountryID(uint256)","4d7d87b2":"prodTokens(address,uint256)","4d7d8a60":"marriageDate()","4d7d9a91":"transferCoadminship(address)","4d7dcfbd":"parseVarInt(bytes,uint256)","4d7e2a6a":"Token_Unlocked()","4d7e897f":"rollOne(address,uint8)","4d7ec628":"requestToken()","4d7ece70":"advisorVesting(address[],uint256[])","4d7edc15":"assignTokens(address,uint256)","4d7ee4ee":"changeGlobalOperator(address)","4d804e60":"WITHDRAWAL_TRIGGER_AMOUNT()","4d80bf14":"NewManager()","4d82f25c":"VestingTrustee(address)","4d831535":"allocatePVT_InvTokens(address[],uint256[])","4d83ffdd":"createUser(address,uint256,bytes32)","4d840bcc":"isWithdrawable()","4d843acd":"getSalaryTokensTotalAddress(uint256)","4d846a99":"getMin(uint128[])","4d846c8e":"getCurrentCandyAmount()","4d84ba37":"depositsAddress()","4d85006d":"Incredibles2RT()","4d853ee5":"founder()","4d8589c5":"getProofOfStakeRewardUpdateToken(address,address)","4d85b8d0":"checkEndOfChallenge()","4d86b498":"BucoTestCoin()","4d87a49b":"updateInvVault(uint256,uint256)","4d882c97":"EthPenis()","4d88a639":"getOrder(uint80)","4d88a8cf":"getExitBySlotId(uint64)","4d894d24":"getLevelByIndex(uint256)","4d8a666b":"EnterEntidadesdonaciones(address)","4d8a9310":"isCrowdsaleStopped()","4d8b7056":"Dd(address,address)","4d8bd784":"getGuestToken()","4d8c10a6":"AJCMToken()","4d8c3ea6":"getTxVoteDetails(bytes32)","4d8c61c1":"LogChangeTimestamp(address,uint256,uint256)","4d8caa7e":"setTokensPerWei(uint256)","4d8d9e92":"tokensPerSecond()","4d8dcc7a":"initDeposit(uint256)","4d8de4fc":"unbond(bytes32,uint256)","4d8e15f2":"KockToken()","4d8f00f4":"RatingsContract(address,address)","4d8fef1c":"produceWiner()","4d908a55":"InitiateCars()","4d909110":"EtherBank()","4d912393":"mintReservation(address[],uint256[])","4d918282":"addmoney(address,uint256,uint256)","4d91c096":"stakeCommence()","4d91d4f1":"incrementBasketsMinted(uint256,address)","4d9250c4":"TakeMyEther()","4d936889":"ConsentTemplate(string,uint256,string,string,string)","4d93d1db":"EventCreateAngel(address,uint64)","4d94994c":"lucky_number()","4d94cee7":"opetWallet()","4d9577af":"getFirstMilestoneStartsAt()","4d95a7a2":"tokensToRecieve(uint256)","4d95c76c":"activeCanvasCount()","4d964da6":"GBBCOIN(uint256,string,string)","4d96e062":"whenStakeCanBeReturned()","4d986c8f":"icoSalesSupply()","4d98a6ff":"createGroup(string,string,string,uint256,uint256,uint256,uint256,uint256,bool)","4d99055c":"getBonus(uint256,address,uint256)","4d9994e8":"setAccountNickname(string)","4d999756":"tokensPreICO()","4d9a3136":"findByName(string)","4d9a81d4":"IsDistribStarted()","4d9aa424":"crowdsaleEnd()","4d9b3735":"getFunds()","4d9b3d5d":"getbalance()","4d9b8fcf":"allowTransfer(address,bool)","4d9bcac4":"getProviderParameter(address,bytes32)","4d9c1bf3":"payTokenBatch(bytes32[],uint256[],address,address,bytes)","4d9e40af":"TOKEN_CREATORS_SUPPLY()","4d9e4e22":"Etheria()","4d9fb121":"Trade()","4d9fcee9":"getExportingAuthority()","4da07fe5":"getCardType(uint32)","4da0a4fc":"promoToken()","4da1397c":"durationOfLock()","4da1668d":"giftNFT(address,uint256,uint256)","4da1b25d":"weiFundingCap()","4da1e0b7":"cancelTokenSale(uint256,address,bool)","4da2317f":"payoutAll()","4da25c74":"triCmp(uint256,uint256)","4da2906b":"updateUser(bytes32,bytes32,bytes32,bytes32,bytes32)","4da2b48e":"getCat(uint256)","4da36913":"migrationIndex()","4da3b6db":"otherF3D_()","4da47ba0":"TokenSale(address,uint256)","4da51208":"OKMcoin(uint256,string,uint8,string)","4da5160f":"getFirstDocumentIdStartingAtValidFrom(uint256)","4da5598a":"syndicatePrecision()","4da5d4c0":"isEthernautsExplore()","4da5ed85":"disableContinuousDelivery()","4da74ee6":"setVoteIntention(uint256,bool,bool,string)","4da7c5d6":"LendingBlockTokenEvent(address)","4da837e3":"transferDevelopment(address)","4da845b3":"swapWinner()","4da8a771":"INHERITANCECrowdsale(uint256,uint256,uint256)","4da946d9":"TakeOffWorldwide()","4da9cb07":"LilithToken(uint256,string,string,uint8)","4daa1208":"SetPoolCreationFee(uint256)","4daaa98f":"doReward()","4daade18":"TravelCoinToken()","4daadff9":"extractCLNfromMarketMaker()","4dab54fd":"removeFromInxWhitelist(address)","4dab63ff":"_unpackItemData(uint256)","4dabb674":"changePhaseToNormalLife()","4dac7d6f":"renewableOf(uint256)","4dad66f5":"divForTank()","4dad9003":"transferManyLand(int256[],int256[],address)","4daea42a":"TOWN_INCREASE_RATE()","4daf490c":"getFarm()","4daf890a":"invokeLottery()","4dafdc50":"exchangeId()","4db0040e":"createWonderNotAuction(string)","4db08aea":"SALE()","4db08e5b":"getSaleContractTokensMinted(address)","4db19e7e":"assertEq(bool,bool,string)","4db1ba5a":"repossessionBountyPerTen()","4db1c7b2":"changeId(uint256,uint256)","4db208ba":"Titanization()","4db2beef":"distroyToken(uint256)","4db347a3":"acceptChallenge(address)","4db3c6d7":"buyTokensWithReferal(address)","4db3da83":"scheduleCall(bytes4)","4db3eef8":"delegateFromBonus(uint88)","4db4eae6":"_topBonus()","4db4eff0":"hatchCoins(address)","4db52924":"setNumMessagesSigned(bytes32,uint256)","4db53a70":"VTest()","4db59565":"getHistoryRoundInfo(uint256)","4db5d52b":"getWagerOwner(address)","4db61d21":"compareNoCase(string,string)","4db6397f":"calculatePlayerValue(address)","4db77d9d":"getMaxJump(uint256)","4db8349e":"buyerToSentWeiOf(address)","4db8cbc9":"wordCounter()","4db94441":"limitAgentBets()","4db9bfe6":"getPostVoteCount(uint256)","4dbaa16b":"recoverLeftoversPreICO()","4dbac733":"INITIAL_RATE()","4dbb1964":"setSalesAgent(address)","4dbb37eb":"checkLeftToken()","4dbb4da5":"increaseMaxContribTime()","4dbb51f6":"Hashfex()","4dbbddff":"BOBTokenVesting(address,uint256,uint256,uint256,bool)","4dbbfcc6":"stageLength()","4dbc355a":"releaseTeam()","4dbdb0fd":"signUpForPVP(uint256)","4dbddc18":"getPoolID()","4dbe5889":"ownerClaim()","4dbf27cc":"follow(address)","4dbfb6fb":"PredictionMarket(uint256)","4dc0884f":"playerCards(uint256)","4dc08ce2":"GameWon(uint256,address)","4dc133a5":"stopTge(bool)","4dc13951":"vendingAttachedState()","4dc189ef":"createContractWhale(string)","4dc18c02":"finalSendTokens()","4dc1dbec":"priceToMint()","4dc266b4":"submitAnswerReveal(bytes32,bytes32,uint256,uint256)","4dc2c67a":"veriPass(string)","4dc3141b":"CalcAll()","4dc3ba8f":"assignVoterMoreVotes(address,uint256)","4dc3f289":"changeCommonDiscount(uint256)","4dc41210":"preStartTime()","4dc415de":"reject()","4dc43eaf":"setTreasury(uint256,uint256)","4dc49b25":"InitialPointUnit()","4dc59196":"icoAllocation()","4dc5c69f":"getTotalDiscount(address)","4dc5c771":"dividendsAccount()","4dc5fa4e":"MEDIA_SUPPORT_WALLET()","4dc65411":"GEM()","4dc666b3":"sendTokensManually(address,uint256,uint256)","4dc6b523":"divestFee()","4dc73428":"transferFromByModule(address,address,uint256,bool)","4dc7cc55":"terminateAlt()","4dc7d31b":"transferRwrd(uint256)","4dc8ed02":"ICObonusStages(uint256)","4dc958e1":"addToBounty(uint256)","4dc996d5":"updatetoken(string,string,string,string)","4dca2770":"BecomeMemberCandidate(bytes32)","4dcad927":"tokensSoldTotal()","4dcb05f9":"depositBond(uint256)","4dcbb8ee":"getAllAuditors()","4dcc889d":"Conference(string,uint256,uint256,uint256,string)","4dcd4fb1":"MetaChanged(bytes32,bytes32,bytes32)","4dcd85d8":"setPriceOfApis(uint256)","4dce4142":"opVaultAddr()","4dcee2e0":"hashes(uint16)","4dcf2917":"allowUpgrades()","4dcf7430":"receiveTokenLoot(uint256[],uint256,uint8,bytes32,bytes32)","4dd0f157":"getWinnerType(uint256)","4dd12329":"rightSharePrice()","4dd19434":"getLeaf2(uint256)","4dd1e81c":"tokenBuyable(uint256,uint256)","4dd33832":"tokensSoldAtIco()","4dd36a0e":"buyTokens(uint8,address)","4dd37f19":"getHashRateOfCurrentHalving(address)","4dd3e575":"endMinting(bool)","4dd4547d":"fireOnChanged(bytes32,uint256[])","4dd49680":"SetEvaluate(uint32,uint8,uint8)","4dd49ab4":"get(bytes,uint256)","4dd49e08":"deliverTokens(address,uint256)","4dd5df8c":"setPOOL_edit_16(string)","4dd60ff9":"buyNDC(uint256,uint256,uint8,bytes32,bytes32)","4dd7f293":"Kayako()","4dd83243":"hasNextKey(uint256)","4dd83cb1":"refreshPublicFundingTime(uint256,uint256)","4dd850fb":"UfoPonzi()","4dd8aefd":"DTT()","4dd93bd3":"getInvestmentValue()","4dd9e437":"transferUserToUser(address,address,address,uint256)","4dda1764":"CafeMaker()","4dda71a8":"newAuction(uint128,uint256,uint256)","4ddad616":"genesMarket()","4ddb5f01":"ROPCOIN()","4ddbf2b3":"teamTokenFund()","4ddc36df":"renounceClearingPriceValidator()","4ddc8f74":"SPEX()","4ddd108a":"money()","4ddd648b":"buyer_profit_pool_amount()","4ddddd4c":"SearchIPR(string)","4dde3fe1":"redemptionAddress()","4dde8de6":"registerUBetCheck(address,string,string,string,uint256,string,int256)","4ddfd20f":"offer_id()","4de0089a":"becomeHipstermaster()","4de037c7":"getTitulaire_Compte_8()","4de0cdf2":"setICOParams(uint256,uint256,uint256)","4de1454f":"targetReached(uint256)","4de16053":"getLockProductCount()","4de162e4":"extractAccountLength()","4de1fc55":"submitAnswer(uint256[],uint256[])","4de2578c":"reproduce(uint8,address,uint256)","4de260a2":"hack()","4de261ef":"presalecap()","4de2d5d5":"checkPrize()","4de2eee9":"zapVillain(uint256,uint256)","4de2f146":"SentAmountToNeighbours(uint256,address)","4de315ea":"unlockAddressToken(address)","4de4145f":"_transferSenderPaysFee_byProxy(address,address,uint256)","4de4f479":"RiskPrice()","4de504cd":"setTransferLockFree()","4de5120e":"lastWithdrawalTime(address)","4de62cd6":"removeGemmyMusicLock(address)","4de799c2":"cancelTeamWithdrawal()","4de85639":"failDivideFractionalByZero()","4de8a799":"addPrivateSaleBuyer(address,uint256)","4de90f34":"minForNewTopic()","4de94320":"logic_contract()","4de946bf":"ideaProofDocument(bytes,uint256)","4de952c7":"cmulpow2(address,uint256)","4de970fd":"RATE4()","4de9e482":"ENDHarvest()","4dea208b":"upgradeKingdomType(string,uint256)","4dea4d15":"setConfig(uint64,string,uint256,uint256,address,string)","4deaad5f":"reverseBytes(uint256)","4deb68a3":"auctionStart(bytes32,uint256,uint256)","4deb9f47":"UnlockRig(uint8)","4deba2e0":"LogCreateToken(address,uint256)","4dec5dc4":"employeeExerciseOptions(bool)","4dec9b57":"testView()","4ded452e":"InviteCreated(address)","4ded6e89":"airdropParticipants()","4ded9bfe":"releaseMultiAccounts(address[])","4dee529a":"Muggelo()","4def0453":"setContentURI(uint256,string)","4defd1bf":"setCrowdsaleManager(address)","4df0b78a":"withdrewThisYear()","4df0ca7e":"EarlyAdoptersAddress()","4df17cdc":"maxEtherInvestment()","4df28ae4":"capTime()","4df34124":"RyxEx(address,address,address,uint256,uint256,uint256)","4df3ad68":"setTokenPriceInCent(uint256)","4df498b2":"getPreSaleEnd()","4df53a0f":"testSetApprovalDb()","4df62441":"percentOfPresaleSold()","4df65873":"getDefaultRgb(address)","4df679e3":"BonusAllocation(address,string,string,uint256)","4df68ada":"enable(bool)","4df6b45d":"delegateTransferFrom(address,address,uint256,address)","4df6ca2a":"setQuestionFee(uint256)","4df6d6cc":"allowedRecipients(address)","4df7e3d0":"b()","4df86126":"SECONDS_PER_HOUR()","4df93196":"Joe223()","4dfa2722":"CryptoWuxiaVoting()","4dfa3f18":"createNewUser(string,string)","4dfad511":"_redeem(address,uint256)","4dfb10bc":"realVotedSupply()","4dfb4807":"etherTotal()","4dfc7aa1":"existsDistrito(uint256)","4dfc97c5":"policyTokenBalance()","4dfcf67a":"NeroSupply()","4dfd14b2":"EMACCrowdsale(uint256,uint256,uint256,address,address)","4dfd1b02":"setUint8(int8,uint8)","4dfd964f":"TSTCallAPI()","4dfdc21f":"maxNum()","4dfdebe9":"ClientQty()","4dfe28e7":"releasedTokenOf(address)","4dfe950d":"purgeUpgrade()","4dfff04f":"approveSiring(address,uint256)","4e010942":"LogOraclizeCallback(uint256,bytes32,string,bytes)","4e0128fb":"watchPrice()","4e012918":"whitelister_address()","4e017994":"capEth()","4e01bb60":"RefundPeriodOver()","4e01bd10":"emergencyTokenWithdrawal(uint256)","4e02107a":"getWeddingData()","4e022f11":"setSpark(address)","4e023fc9":"FakeXUC()","4e028c67":"SAC()","4e02ed40":"CESCoin(uint256,string,string)","4e039d26":"setPreallocationWhitelist(address,bool)","4e0416a6":"DaoRulesProposalAdded(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool,address,uint256)","4e054a67":"setBlacklist(address)","4e05ded6":"ClassicCheck()","4e06369c":"getPurchasableAmount()","4e077f2a":"addGasEther()","4e07a7a5":"thirdStageMinted()","4e088eb7":"stopPrivateSale()","4e0896a1":"teamIndexToExist(uint256)","4e0a0f21":"preICOstartTime()","4e0a3379":"setCFO(address)","4e0ade00":"SmartWallet(address,address,address)","4e0b7888":"_updateStage()","4e0ba39d":"reserveAdd(uint256,uint256,uint256,uint256)","4e0be991":"removeChild(address,address)","4e0c4a9c":"setCommissioner(address)","4e0ce969":"moduleToken(uint256,uint8)","4e0d93a3":"increasePriceForNeighbours(uint256)","4e0e9675":"isIdentity(address)","4e0f1064":"getMonthlyTransactionVolumeReceiving()","4e102951":"can_claim(address,address,address)","4e1053cc":"RobinHoodPonzi()","4e10c212":"TxAttackWallet()","4e10c3ee":"transferWithoutReward(address,uint256)","4e116eb8":"unRegisterCertificationDb(address)","4e1243b6":"AddClaim(uint32,string,bytes32,bytes32,address,uint32)","4e12e51a":"getBonusList()","4e1339fe":"HALT()","4e13f066":"RedSoxRays48()","4e140274":"isDiscount()","4e1415ab":"testThrowExecuteSellOrderDaoChallengeRefusesZeroFunds()","4e14e4c8":"CyberCapitalInvestToken()","4e153418":"CreateLottery(uint32)","4e159a05":"clacCooperateNeedLockAmount(uint256)","4e15dfe9":"wholeTokensPerEth()","4e16bef5":"jack_max()","4e16e0c7":"participantCanParticipate(address)","4e18405d":"TOTAL_ARK()","4e18c1a7":"IcoPhaseAmountsChanged(uint256,uint256,uint256,uint256)","4e191701":"lamboPresaleAddress()","4e194cc0":"getCreateFeeToken()","4e195faf":"totalEthereumRaised()","4e19c112":"deleteOwner(address,uint8)","4e1a150b":"netherToken()","4e1a1853":"ParentCoinAddress(address)","4e1a50b7":"setBonuses(uint256,uint256,uint256,uint256)","4e1bdfdf":"withdrawOlder()","4e1dc0d7":"LAYA()","4e1f6c14":"FUTURE_WALLET()","4e1fa837":"TestERC721()","4e205cee":"signedApproveAndCallHash(address,address,uint256,bytes32,uint256,uint256)","4e209678":"testFailBreach()","4e2133ba":"addExchangePartnerAddressAndRate(address,uint256)","4e21f25e":"soldPresale()","4e22102b":"LIMITS_END_DATE()","4e2280c4":"clearQuickBuyPath()","4e228d8f":"ExchangeableToken(address)","4e23176c":"buyRBCTokens()","4e232730":"ownerOn(address)","4e233065":"delKeyValue(uint256,bytes32)","4e23a144":"fundUser(address,uint256)","4e25658e":"setSegment(string,uint32,uint32,string,string,string,string)","4e2567d0":"addToAccountList(address)","4e25c92e":"ttlSply()","4e2611ae":"vnetToken()","4e2659a8":"createTeam(bytes32,bytes3,bytes3,bytes3,bytes3,bytes3,bytes3)","4e26c95e":"EASYLIFE(uint256,string,string)","4e272768":"remove_bounty()","4e2743b3":"setStack(uint256,uint256)","4e275295":"tokensSell()","4e2786fb":"roundNumber()","4e27e916":"voteLock(address)","4e2808da":"cancelOwnership()","4e280fd6":"SolarioToken()","4e284af1":"INCENT_FUND_NON_VESTING()","4e285acb":"setsendgoods(uint256)","4e29cba6":"disbursements(uint256)","4e2a953a":"gameStartedAt()","4e2aae36":"setzUint256(uint256,int256)","4e2ab933":"transferFrom(address,address,uint256,bytes,string)","4e2ad943":"mainSaleBonusEndTime()","4e2b57fe":"mincap()","4e2ba115":"DFVToken()","4e2bd9ce":"rescind(address)","4e2bdfd4":"getBetMutableData()","4e2c9524":"upgradeDuties()","4e2de9e1":"setGzeBonusOffList(uint256)","4e2e8a10":"setTime3(address,uint256)","4e2e94f7":"MAX_PRE_SALE_AMOUNT()","4e2f220c":"createCentralizedOracle(bytes)","4e2f2af4":"PayoutRedemption(uint256,uint256,uint256)","4e2fa68f":"crowdsaleStarts()","4e2fd44e":"setPriv(address)","4e304bfb":"CRAIC()","4e30506f":"dropLast()","4e30a66c":"safeToAdd(uint256,uint256)","4e317ead":"cancelTemplateProposal(address,uint256)","4e31aea3":"firstThawDate()","4e329bd3":"HealthCoin(uint256)","4e358ce7":"DITCOIN()","4e35aacf":"createCompany(string,uint256)","4e360eaf":"EmergencyStopActivated()","4e3673a6":"connectCrowdsaleContract(address)","4e36fddf":"XdacTokenCrowdsale(address,uint256[],uint256[],uint256)","4e37af4e":"offlineCallback(bytes32)","4e38413f":"setBytes32(bytes32,bytes32,bytes32,bool)","4e385512":"setCampaignValidity(bytes32,bool)","4e38f205":"generateWithdrawalHash(string,uint256,address)","4e390f2a":"initLottery(uint256,uint256,uint256,uint256)","4e395e2a":"isExecutable(uint256)","4e3acafe":"Cr1tikalIsShort()","4e3b33d4":"prepareRefund()","4e3b52fe":"metaCoin()","4e3c2f47":"getCardDivs(uint256,uint256)","4e3c50a0":"addBuyTokensRequest(address,string,string)","4e3d2745":"ManoloToken()","4e3d539a":"newChainlinkWithENS(address,bytes32)","4e3dc2f1":"STAT_MAX()","4e3df857":"removeEA(uint32)","4e3e4035":"notEqual(int256,int256,string)","4e400bda":"getSenderStatus(address,uint256)","4e406167":"setContractICO(address)","4e4081ef":"pregnantBots()","4e41108d":"Bank()","4e417a98":"callData()","4e41a1fb":"symbol(uint256)","4e41ebf6":"createCommissionerAuction(uint32,uint256,uint256,uint256)","4e42b632":"WEBcoin()","4e43502a":"BDSMTOKEN(uint256,string,uint8,string)","4e43603a":"getUserStats(address)","4e448ffa":"winnerLuckyNumber()","4e44b5cc":"Kiwi(address,uint256,string,string,uint8,uint8)","4e44c855":"setGameStatus()","4e44d956":"configureMinter(address,uint256)","4e458cc2":"setNewEndTime(uint256)","4e458eb6":"posstoken()","4e45fba9":"getProviderDetails(address,uint256)","4e46fc2c":"finalizePreICO()","4e47d99a":"WubCoin(address)","4e485c52":"closeTransfer()","4e48a495":"checkTransfer(address,address,uint256,uint256)","4e4965ff":"AIPAY()","4e49954e":"createReceipt(address,string)","4e49acac":"setParams(address)","4e4ab830":"amIOwner()","4e4ac577":"claimFeesForRound(address,uint256)","4e4afa1b":"minimumTickets()","4e4cf65c":"forwardMoney()","4e4d02db":"DeathFactor_iii()","4e4d3e56":"get_funds_left_for_reinvestment()","4e4e2d6d":"PaymentForwarded(address,uint256,uint128,address)","4e4e7862":"addWithdrawal(address,address,uint256)","4e4f776c":"TCT(uint256,string,uint8,string)","4e4fbee1":"renounceProxyManager()","4e4fe306":"getData(uint256,uint256)","4e500760":"CreditUnits()","4e504313":"Addr3()","4e505367":"initialTokenAmount()","4e51193b":"sealTimestamp()","4e5141eb":"buyTokens(uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","4e5146a9":"hexToAscii(uint8)","4e520a94":"getNumRecords(address)","4e521a2a":"INCUToken()","4e523b91":"MonethaToken(address,uint256)","4e52622b":"eth6DivsOwing(address)","4e52678e":"digix()","4e53a0b9":"update(address[],uint256[],uint256[],uint256[])","4e53b564":"adminTransferContractBalance(uint256)","4e542bff":"_triggerPVPSignUp(uint256,uint256)","4e542c5f":"deleteById(uint256)","4e543b26":"setResolver(address)","4e5497de":"BuyoutDividend(address,address,uint256,uint256,uint256)","4e55936d":"NorthPoleMintingEnabled()","4e56925f":"updateMasternodeAsTeamMember(address)","4e57d27d":"_getAllRevisionTimestamps(bytes20)","4e58e920":"officialFacebook()","4e599551":"getPreviousWinners()","4e59f947":"SucToken()","4e5a33c5":"executeTokenRepartition(uint256)","4e5aabe6":"resetStellarBalance()","4e5ac744":"PDPCoin()","4e5acb1a":"changeAutherOwner(address)","4e5b0d29":"getVisaEntered(address,uint256,uint256)","4e5b3cb8":"EtherusPreSale(address,address,address,address)","4e5b5f54":"purchasePresale(address,uint256)","4e5c0595":"tokenAdvisorsAllocated()","4e5d49a0":"DariumToken(address)","4e5d7186":"LogAccountRegistered(address,address,bytes32,bytes32,bytes32,bytes32)","4e5d793f":"setAsset(address,uint256,uint256,uint256)","4e5d8edd":"VOLUME_70()","4e5ed65b":"_indexAccount(address)","4e5f13bc":"landPriceCurrent()","4e5f8751":"newInvestWallet(address)","4e605688":"setBtcBuyer(address)","4e6093f8":"HeirChanged(address,address)","4e6106c5":"getRealisation()","4e61c362":"transferMul(address,uint256)","4e61df06":"DigixbotEthereum(address)","4e61efc5":"getWizzTypeOf(uint256)","4e637fab":"DepositsTransferred(address,uint256)","4e659145":"levPerUser()","4e6630b0":"ethBalance()","4e68354e":"LogLockStateTransition(uint8,uint8)","4e6885f3":"depositPresale(address)","4e6944cf":"totalStaticoinSupplys()","4e696d3c":"startCoinSale(uint256,address)","4e69d560":"getStatus()","4e6ab570":"insert_order(address,bool,uint32,uint128)","4e6b29ee":"returnIsParentAddress(address)","4e6b558a":"removeVerifiedAddress(address)","4e6b97f3":"transferMultiSameVaule(address[],uint256)","4e6ba0a9":"testCreateCostMultisig()","4e6c61aa":"testFailAddForeignChildNotChild()","4e6d1405":"invoices(uint256)","4e6d35ea":"currentlyReleased()","4e6d739d":"getSupernovaBalance()","4e6d73da":"LogUserUserRemovedFromWhiteList(address)","4e6e5d69":"unMint(address)","4e6e6928":"latestFriend()","4e6ec247":"_mint(address,uint256)","4e6f42ba":"changeSeizedTokensWallet(address)","4e6fedb7":"remainOfStage(address,uint256)","4e705549":"setDefinition(uint8,uint8,uint8,uint8,uint8)","4e7073f1":"setMinETH(uint256)","4e70a604":"Withdrawal(uint256)","4e70b1dc":"num()","4e7196c7":"setReg1(uint256)","4e71d92d":"claim()","4e71e0c8":"claimOwnership()","4e724f0f":"numBlocksLocked()","4e725b7a":"test_hasClaimableShares_nonZeroClaimableStake()","4e72ec91":"setPointer(uint8)","4e72f19e":"SendFundsToReceiver(uint256)","4e730025":"register(uint256,uint256,uint8,uint8,uint8,uint8,string)","4e7343ea":"verifyOrder(address,uint256,uint256,address)","4e7344d5":"ABitcoin()","4e7355d6":"RegistrantRemoval(address)","4e7445c8":"drainRemainingToken(address)","4e7455d0":"createMilestones(uint256,bool,uint256)","4e7602d3":"setRecipients(address[])","4e761a91":"STEP_SIZE()","4e76a725":"test_withAssertTrue()","4e76a846":"numParticipants()","4e76f5d2":"GetMinimumBet_ether()","4e77a38e":"releaseTrickleDownBonuses()","4e78e0c2":"setVerificationSlashingPeriod(uint256)","4e79909c":"WithdrawalApproved(uint256,uint256,bool,uint256,bytes)","4e79fd7c":"stepLockedToken()","4e7a540b":"doUpgradeInternal(address)","4e7a6978":"PersianTokenICO(uint256,uint256)","4e7ad367":"fireEventLog1Anonym()","4e7b1ce1":"PayNihilumToContract()","4e7ceacb":"getFeeAddress()","4e7cff38":"toBytes20(bytes,uint256)","4e7d656a":"EtherSpermBank()","4e7dbb29":"TTARD()","4e7e96f1":"buyBackInvestedValue()","4e7ec0e4":"setGlobalTimeVault(uint256)","4e7ec7e3":"RANGEEND_6()","4e7f1264":"leaveMessage(string)","4e7f9b19":"getReport(uint256)","4e80f241":"YCStandardToken(uint256,string,uint8,string)","4e8127f6":"icoSupply()","4e815698":"removeBlacklistAddress(address,address)","4e8182c8":"addJugada(uint256,string,string,uint256,uint256)","4e81b17d":"createMonthlyBill(uint8,uint256,uint256)","4e81eec9":"EventProductEndSale(uint32)","4e8204a4":"NewRoundStarted(address,uint256,uint256,uint256,uint256,uint256,uint256)","4e82844d":"countWishes()","4e82c134":"getAddressFromUsername(string)","4e83977a":"validationWallet()","4e840bea":"IGTToken()","4e84c614":"getWaitingState()","4e860ebb":"disableTokenIssuance()","4e876ecc":"directSellRate()","4e87c715":"DEFAULT_INITIAL_COST()","4e880082":"distributeTheSameAmountOfTokens(address[],uint256)","4e89eb98":"bonusDicrement()","4e8a411b":"deallocate(address,address,uint256)","4e8afc5f":"getRegister(string,bytes32)","4e8b759c":"BuyOrdersOf(address,uint256)","4e8b75d0":"IRtokenChain(uint256,string,string)","4e8be64d":"TokenToken(uint256,string,string)","4e8c2927":"FreeToken()","4e8eaa13":"cancelAuction(uint256,address)","4e8ec73e":"jockeyPr(uint256)","4e8f05d1":"setGrowthTokensWallet(address)","4e8f7fdf":"allocateTokenForTeam(address)","4e8fb35c":"referralBountyTokensAddress()","4e91025e":"Liquidate(address,uint256,uint256,uint256,uint256)","4e91ca3a":"updateModuleStatus(address,bool)","4e91db08":"setBytes32(bytes32,bytes32)","4e91f906":"getNewPetCard(uint8,uint8)","4e922731":"calcRefBonus(uint256)","4e926eab":"getInviteePIDs()","4e9282af":"setBDApprove(uint256,bytes)","4e930483":"addbtycmoney(address,uint256)","4e9384da":"addSecondPreferences(bytes32[],bool)","4e938539":"preSaleSecondBonus()","4e93bf32":"maximumBuyBackAmountInWEI()","4e9466f7":"withdrawToMany(address[])","4e94917a":"Claim_TRAC_20000()","4e94c829":"getAugur()","4e94fbcf":"setIntervalCoefficient(bytes2,uint256,uint256,uint256)","4e954f87":"IsEthereum()","4e961921":"getCurrentTokenRate()","4e96ea53":"addContract(address,address,address,string)","4e97bcfc":"EmergencyStop()","4e98323c":"setReturnAgent(address)","4e9833ac":"changeHoldingTaxInterval(uint256)","4e989a5b":"importPlayers(address,address[])","4e98a5b3":"receiveAssets(uint256)","4e99b800":"tokenBaseURI()","4e9b5db0":"BASEPRICE()","4e9c6b1f":"million()","4e9cf5b1":"changeOperational(bytes32,bool)","4e9de828":"registerAuthContract(address)","4e9e456b":"oraclize_query(uint256,string,bytes[1])","4e9ec8a6":"transferETHtoContract(uint256)","4e9ee738":"test_8_basicTransfersBetweenAccounts_increaseBlocksBy300()","4e9f0f06":"GimmerTokenSale(address,address,uint256,uint256)","4e9f9d37":"startTimeTwo()","4e9faaba":"_sell(address,uint256)","4e9feee6":"changeFrozenTime(uint256)","4ea05686":"countSet()","4ea0db6c":"HardCapReached(address,uint256)","4ea10c74":"FounderAllocationTokens()","4ea14479":"setProjectToVerify(address,uint256)","4ea1fcb6":"getWithdrawAmount(address)","4ea201cc":"betInfo()","4ea28ee6":"MyToken(uint256,uint256)","4ea2ea9f":"allocLastTxRewardByHand()","4ea2f66a":"_claimIfNeededThenSteal(uint256,uint256,address,uint8,bytes32,bytes32,uint256,uint256)","4ea34cdb":"getActionContract(address)","4ea37fec":"presaleStartTimestamp()","4ea412f4":"setPrice3(uint256)","4ea44358":"setGen0Step(uint256)","4ea5195a":"participantRoundCalced(address,address,uint256)","4ea5a6ac":"getRocIndexToOwner(uint256)","4ea611cd":"setPartnerDurance(uint256,uint256)","4ea640da":"ManoAntrasToken()","4ea66c38":"buyinInternal(address,uint256)","4ea6c89e":"isPreviousStageFinalized()","4ea73b07":"APOTokenCrowdsale()","4ea7d483":"priceStar5Now()","4ea801c5":"writeRate(string,uint256)","4ea8b6d0":"changeProfilePicture(bytes32)","4ea9560e":"FoshaAirdrop()","4ea9a27a":"registerHolder(bytes32,address,uint256)","4ea9ea71":"_submitTransaction(address,uint256,bytes,bytes,address)","4eaaad7b":"left72(uint256)","4eab3998":"Allocations()","4ead4771":"getBIDList()","4eae51f4":"getHeirs()","4eae8e30":"isSenderApprovedFor(uint256)","4eaef8a2":"getCEOHashing(address,uint256)","4eb03f6e":"updateMinter(address)","4eb054e6":"createPinMoTrade(bool,uint256,uint256)","4eb06f61":"manualLockFunds()","4eb09bf4":"getParametersHash(uint256,uint256,uint256,uint256,address,address)","4eb1483d":"IcoAddress()","4eb166af":"right73(uint256)","4eb1e71c":"HashTestCoin()","4eb1f578":"saleValve(bool)","4eb21301":"currentSaleCap()","4eb259aa":"burnAndReturnAfterEnded(address)","4eb2a8fb":"Banear_Oraculo(address)","4eb3148e":"feesTakenFromPrize(uint256,uint256)","4eb333c7":"setSynthesizingAuctionAddress(address,address)","4eb37fe7":"Tournament(uint256,uint256,uint256,uint256,uint256)","4eb396cd":"mintByMintable(address,uint256)","4eb421e5":"MockFailUpgradeableToken()","4eb4fe80":"getBackLendingItem(uint64)","4eb5162e":"collectSellFee()","4eb56999":"claimRefundVaultOwnership()","4eb665af":"setLockDuration(uint256)","4eb7221a":"nameRegistry()","4eb7d857":"getSite(uint256)","4eb81ba4":"getSchellingRoundDetails()","4eb8ffb4":"ORACLIZE_GAS_LIMIT()","4eb933bf":"withdraw(bytes32[],address[],uint256[],uint64[],uint8[],bytes32[],bytes32[])","4eb94102":"setAuctionManagerAddress(address,address)","4eb94872":"Err(string)","4eb95b97":"DropNotice(uint256,string,string,string)","4ebab5cf":"specificApprove(address,uint256)","4ebc31f3":"managerETHcandidatAddress()","4ebc7a9c":"processReinvest(address,bool)","4ebcdc2b":"SwapStarted(uint256)","4ebd7741":"extraMint(address)","4ebe2d46":"createMultisig()","4ebfa8bc":"getUserBettingInfo(address,uint256)","4ebfd6e8":"freeForAll()","4ec06982":"paybackToDepositer(address,uint256)","4ec0744d":"UtrustToken()","4ec1646d":"claimFreeAnimalFromAnimalFactory(string,string)","4ec18db9":"poolSize()","4ec19512":"calculateRunway()","4ec1adf1":"callAMethod2(uint256)","4ec24fa0":"getManagementProxy(uint32,int256)","4ec2b417":"getBankKYC(address)","4ec2cde6":"totalSupplyForCrowdsaleAndMint()","4ec2d0b6":"buyMiner(uint256[])","4ec32507":"parentBlockInterval()","4ec42e8e":"antToken()","4ec4878b":"donateJackpot()","4ec6396d":"TransChain()","4ec6a61a":"InitializeCoinToUser(address)","4ec70fde":"publicMin()","4ec7344e":"MetaFoxToken()","4ec735ae":"revokePermission(address,address,bytes4)","4ec79937":"approve(bytes32,bool)","4ec7a6e7":"externalSale(address,uint256,uint256,uint256)","4ec7b58b":"delSaleOwner(address)","4ec7ddc0":"addCommitteeVote(address)","4ec883d1":"editRestrictedAddress(address)","4ec8a8ff":"unpausecontract()","4ec9ef9c":"calculateTokenPurchase(uint256,uint256)","4eca4b19":"sendCoins(address,address,uint256)","4ecb02aa":"firstTierDiscountUpperLimitEther()","4ecb1390":"saleTokens(address,uint256)","4ecb35c4":"confirmations(address)","4ecb5e79":"IamGROOT()","4ecb8d0f":"transferOwnershipSend(address)","4ecc6eab":"setDefaultBuyerLastPaidAt(uint256)","4ecc7f59":"assignPreicoTokens()","4ecd4aa9":"createRequestAsPayeeAction(address[],bytes,int256[],address,bytes,string)","4ecd73e2":"DistributeDividends(uint256)","4ecd81b3":"redeemUTXO(uint256,bytes32[],bytes,bool,uint8,bytes32,bytes32,address)","4ecdf165":"rareIdRange()","4ecf77d3":"getUnfinishedGames()","4ed0694f":"kkICOTest77()","4ed0efd1":"selfdestructs()","4ed250bf":"freezeTime(uint256,uint256)","4ed3881e":"setTokenTransferIdentifier(string,bytes4)","4ed3885e":"set(string)","4ed4831a":"all(bool[7])","4ed4d42a":"transferTokenAddress(address)","4ed577bb":"IssuedToken(string,string,uint256,uint256)","4ed600d1":"confirmVestingSchedule(uint256,uint256,uint256,uint256)","4ed767a1":"totalFinalised()","4ed7cb10":"XXXXXXXX10(address)","4ed8579e":"setGPSMaxEth(uint256)","4ed87713":"ADVISORS()","4edac8ac":"num_claimed()","4edba7bf":"adapterEnabled()","4edbca6e":"getCategory(uint256,uint256)","4edbe9f7":"MintCommandBonus()","4edc689d":"allowAddress(address,bool)","4edc8ccf":"registerEIP777Interface()","4edccd31":"replace_square(uint256,bool,uint256,address)","4edce4e1":"push(int256,bool)","4edd0d07":"setConsumeTokenAddress(address)","4edd74e8":"reservesBalance()","4eddbd8d":"getCurrentPrice(uint128,uint128,uint24,uint64)","4ede23c8":"addressNotNull(address)","4edefd31":"setExpireDelay(uint256)","4edefe83":"doBroadcast()","4ee0ab0d":"forceEnd()","4ee0b9a9":"DaoHubVerify()","4ee0cb8a":"CutieBit()","4ee0cd98":"setFundMintingAgent(address)","4ee0d066":"setTotalsContract(address)","4ee16aba":"contributeToPurse(uint256)","4ee1d045":"secPerBlock()","4ee29ec5":"getNumberOfAssertions(uint128)","4ee2a3df":"setTargetDiscountValue2(uint256)","4ee2cd7e":"balanceOfAt(address,uint256)","4ee3659d":"AGC()","4ee3ad07":"HareemCoin()","4ee3c579":"DurioToken(string,string,uint8,uint256)","4ee3dc91":"publicToken()","4ee4d731":"enableMETTransfers()","4ee4d8fa":"isGlobalConstraintRegistered(address,int256,address)","4ee51a27":"airdropTokens(address[])","4ee67d33":"Etheradium()","4ee7ca3a":"erc20FOBS(string,uint8,string)","4ee9eb70":"InformRebuyTo(uint256,address)","4eea636f":"GROWCHAIN(uint256,string,string)","4eea9a8d":"withdraw2(address)","4eec0185":"aomracoin()","4eec44b4":"beforeBalanceChanges(address)","4eeca076":"Counter()","4eecafdb":"ifEndGetting()","4eed8a45":"LogTokenAllocation(address,uint256,uint256)","4eed965e":"_createGame(string,address,uint256)","4eee121f":"setOrCacheTargetReporterGasCosts(uint256)","4eee424a":"removeClaim(bytes32)","4eee59b3":"guess(string)","4eee8c25":"tokenBuyCost()","4eee966f":"setTokenInformation(string,string)","4eeea29d":"transferPreSaleBalance(address,uint256)","4eeedef1":"BCALAttToken()","4eeee8ac":"updateFighterBattleStats(uint256,uint64,uint16,uint64,uint16,uint16)","4eef440c":"bonusLevel0PercentModifier()","4eef683d":"PALAIR()","4ef02cf3":"preicoEndDate()","4ef05de3":"evacuate()","4ef1a23a":"manualInsuranceResolution(bytes32,uint8,bytes32)","4ef20030":"_setTokenMeta(uint256,bytes)","4ef37628":"getChallengeNumber()","4ef39b75":"finalize(address)","4ef3f235":"changeMaintenanceTime(uint256,uint256)","4ef45cac":"Announcements()","4ef50711":"apply4Redeem(uint256)","4ef5710a":"WatchNumberOfPlayerInCurrentRound()","4ef65c3b":"setUint(uint256)","4ef6b8ce":"Certificate()","4ef8086a":"switchManagerAndRemoveOldOne()","4ef83a70":"withDrawEth(uint256)","4ef85140":"CAOsale(uint256,uint256,string,string)","4ef8885f":"getSocialAccountPw(bytes32,bytes32,bytes32)","4ef8ff33":"MIN_INVESTMENT()","4ef94e34":"setMilestones(uint32[],uint8[],uint32[])","4ef98616":"CelebsPartyGate()","4efa45a1":"addAddressSetting(string,address,address,address,string)","4efb023e":"totalModerators()","4efb04ff":"created_contracts(address)","4efb7296":"updatePlotData(uint256,string,string)","4efbb734":"PublisherRegistryReplaced(address,address)","4efbe933":"buyForHackerGold(uint256)","4efc067f":"getAuraValue(uint256)","4efcc69e":"ExMoneyToken(uint256,string,string,address)","4efd1551":"add(address,address,uint256,uint256)","4efd9e2c":"updateMinContribution(uint256)","4efdd4f9":"viewUnclaimedResearchDividends()","4efddcd9":"artWorkChangeByAdmin(uint256,string,uint256)","4efeb2cf":"crowdDistribution()","4eff13dc":"OFFER_SIZE()","4eff86e7":"RBFToken(uint256,string,string)","4f0016d0":"endContract(uint256,uint256,uint8,bytes32,bytes32)","4f002522":"set_creature_builder(address)","4f011d9d":"getIntermediary(uint256)","4f013184":"investInTheSystem()","4f013ea6":"_THOUSAND()","4f01541e":"setReceiverAddress(address,address)","4f01d77e":"manual_lottery(bytes32)","4f02c420":"minted()","4f03c340":"proposeTx(address)","4f046439":"updatePurchaseSize(uint256)","4f04a36e":"setDesignatedReportPayoutHash(bytes32)","4f04af35":"CORReserveAllocation()","4f052648":"XaurumDataContract()","4f052b82":"UNLOCK_OUTINGRESERVE()","4f057506":"Limit()","4f059a43":"getClaimAmountForBlock()","4f062c5a":"getTier(uint256)","4f065672":"Start(string,bytes32)","4f0693a1":"BONUS_LATCH()","4f069517":"removePublicSalesSpecialUser(address)","4f07307b":"setLoanCreator(address)","4f073130":"takeOrder(bool,uint256,uint256)","4f07a663":"close(address,uint32,uint192,bytes,bytes)","4f07b5f0":"startSale(uint256,uint256,uint256,uint256,uint256,address)","4f07cc4f":"ETH_MIN_LIMIT()","4f082843":"enableChain(uint256)","4f084c0c":"payLast(uint256)","4f089298":"Etch(bytes32)","4f089898":"updateBlackListTrader(address,bool)","4f090ab4":"burnPrimordialToken(uint256)","4f0913ef":"MANHATTANPROXY6THST()","4f09cfc5":"changeDiviRate(uint256)","4f09eba7":"proxyApprove(address,uint256,bytes32)","4f0a195e":"totalBasicIncome()","4f0a746f":"blacklistAddress(address,address)","4f0a97b9":"test_basicThrow()","4f0b0deb":"gameCreate()","4f0b584e":"getCCH_edit_18()","4f0b8374":"addToPrivilegedList(address)","4f0b9a2b":"KarTokenERC20(uint256,string,string)","4f0c563f":"depositBonus()","4f0ca055":"getMiniPoolEdit_5()","4f0cae88":"balanceThis(address)","4f0cc59d":"swapID(address,bytes32,uint256)","4f0cd27b":"getCount(address)","4f0cdd29":"getAddressByUserName(string)","4f0cf7e1":"fillTradesInfo(bytes32,uint256,uint256[])","4f0d8533":"addNewStreetType(string)","4f0ddd27":"getTemplate(string,string)","4f0e3333":"wedaddress()","4f0e3dad":"USD_GOAL()","4f0e760a":"_takeOwnershipOfTokenFrom(uint256,address)","4f0e8656":"showAdmin()","4f0eaf96":"oraclizeCallbackGas()","4f0f4aa9":"getNode(uint256)","4f0f539e":"getActiveMessage()","4f0f97ab":"TokenForSale()","4f1069ad":"serchIndexByAddress(address)","4f10a0bd":"_createAvatar(string,address,uint256)","4f10acc1":"updateGoldFeeData(uint256)","4f1157aa":"EtheriumWall(string)","4f118ad7":"GenericToken(string,uint8,string,uint256)","4f11ca65":"distributeTeamTokens()","4f11e07d":"getProof(address,uint8,bytes32)","4f139314":"compensateLatestMonarch(uint256)","4f13e130":"fightAsuriMonster()","4f13fc0a":"setCompte_30(string)","4f150787":"batchFillOrKillOrders(address[5][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[])","4f161245":"getUIntValue(string)","4f162f8f":"icoEndTimestampStage4()","4f18d6fb":"BITAD()","4f190ed2":"changeDekzAddress(address)","4f192fa3":"MajestyAssetsJunction()","4f197ee7":"transferPackageOwner(string,address)","4f19e977":"INVALID_ORDER_SIGNATURE(bytes32)","4f1a5b86":"tokenReserved1()","4f1a7678":"getInsuranceDataByID(uint64)","4f1a892b":"setSectionForSale(uint256,uint256)","4f1ae61a":"releaseFeesAndBountyJM(address,uint256)","4f1afb63":"ownerforce()","4f1b2d4f":"toBool()","4f1bbc4d":"SuccessAuctionEvent(address,address,uint256,uint256)","4f1c3417":"getSpawnProxy(uint32,int256)","4f1c3b66":"setAccountData(address,uint8,bytes32)","4f1c8d0f":"milkBalanceOf(address)","4f1d38c0":"activeCrowdsalePhase3(uint256)","4f1d76ef":"buyabletoken()","4f1e0d0b":"getGoldInfoCustodian(address)","4f1e4334":"setMinBalanceForContractCreation(uint256)","4f1ea770":"bc(uint256,address)","4f1eb4b2":"proposalInProgress()","4f1ef286":"upgradeToAndCall(address,bytes)","4f1f421b":"SuMain()","4f1f99aa":"changeOzreal(address)","4f1fa7ef":"streamityContractAddress()","4f20f35a":"payExpenses(address,uint256)","4f219ceb":"getPlayRate(uint256,uint256)","4f223fe3":"StatefulFactory(string,string,string)","4f224baa":"setMetaBaseUrl(string)","4f2253d4":"addStudent(string,string,string,bytes32)","4f22bcf8":"allocationAddressList(uint256)","4f232f77":"transferFromRoot(address,address,uint256)","4f238029":"getSaleAuctionAddress()","4f23cce0":"ownerBetsCount(address)","4f23e50a":"defineReward(string,address,uint256,uint256)","4f24186a":"newProposal(string)","4f242cde":"startICO(uint256,address)","4f245ef7":"auctionStart()","4f248409":"endICO()","4f24e471":"numRewardsAvailableSetForChildAddress(address)","4f255b80":"getCharacterIndex(uint32)","4f256693":"addFile(bytes32,bytes32)","4f2578ba":"getVestedFounderTokens()","4f25a319":"PUBLICSALE_STARTTIMESTAMP()","4f25d6dd":"solveTime()","4f25ec6e":"_transferFee(address,uint256,address)","4f25eced":"distributeAmount()","4f26ef80":"buyAd(uint256,string,string)","4f271740":"UNFREEZE_DATE()","4f27869e":"defaultExit(uint256,bytes,bytes32,bytes,bytes,bytes32,bytes,bytes)","4f27ce68":"setSlogan(uint64,string)","4f27de64":"ByteExtractor()","4f28216a":"lowContributionAward(address)","4f284594":"info_TotalSupply()","4f28af6a":"handleBet(uint256)","4f28c443":"AIRDROP_TOKENS_PERCENT()","4f297b2b":"TokensGiven(address,uint256)","4f2989af":"indexExists(bytes32)","4f2996ab":"getBalanceByEscrowId(uint256)","4f2af869":"lastCalculatedToken()","4f2b0e41":"preSaleFund()","4f2be91f":"add()","4f2c9196":"getUsedBySoftwareLength()","4f2cd9cc":"auditConfirm()","4f2d7ab5":"contributionMinimum()","4f2eebc3":"PreSaleStartTime()","4f318dd8":"confirmVestingSchedule(uint256,uint256,uint256,uint256,uint256)","4f31cc51":"frozenTokenTransfer(address,uint256,uint8)","4f31e3ec":"minRoundSize()","4f32c65b":"emitFuture(bytes32,uint256,uint256,uint256)","4f32de0a":"request_payout_holder()","4f33428a":"setConsolationRewardsRequiredFaith(uint256)","4f33a013":"artHash()","4f346a7d":"emit(address,uint256,uint256)","4f348b46":"getTokenAmountOnAdd(uint256)","4f3655a8":"verifyBet(uint256,uint256)","4f36fbdc":"setMinMaxPriceInWei(uint256,uint256)","4f36fec8":"hardCapSale()","4f3741b5":"RateChanged(address,uint256,uint256,uint256)","4f37edfd":"burnAndRetrieve(uint256)","4f383934":"setMyTokenList(address[])","4f39ca59":"drop(bytes32)","4f3b1fb6":"unlock(string,address,bytes32,string)","4f3b8938":"mythexTokenAddress()","4f3bb920":"lockDownPeriod()","4f3d057a":"push(string)","4f3d1416":"SetOriginator(string,string,string,string,string,string,string,string,string,address,string)","4f3d1c27":"setLpMaxVolume(uint256)","4f3d3003":"participantRoundValue(address,address,uint256)","4f3d520c":"getClearance(address)","4f3ded8a":"getFinalPaymentAmount()","4f3df0a8":"getRemainingTimeOf(uint256)","4f3f2cbc":"changeFeeModifiers(address)","4f3f4211":"awardDailyLottery(address,uint256)","4f3f5746":"participatingIn(address)","4f3fc162":"removeOriginByIndex(uint256)","4f3fd173":"get10Animals(uint16)","4f3fed94":"tokenIncrease()","4f4027d0":"SHAREHOLDERS_SHARE()","4f4200e5":"setAddressOfERC20Token(address,address)","4f424da3":"Bounties_Wallet()","4f438a12":"provideTransactionFeedback(uint256,uint8,bytes32)","4f438ddb":"changePercent(uint256,uint8)","4f44728d":"ownerChangeOwner(address)","4f4522b0":"getIntelligenceValue(uint256)","4f452b9a":"isStormBirdContract()","4f4548f9":"registerAudit(bytes32,bytes,bool)","4f45779f":"mintTokensWithinTime(address,uint256)","4f45c308":"DocumentSigned(uint256,address)","4f466ce6":"TOTAL_T8EXTOKEN_SUPPLY()","4f4821e1":"createGiftTemplate(uint256,uint256,string,string)","4f48e46d":"get_all_payment(uint256)","4f494cad":"createAuction(uint256,uint128,uint128)","4f495513":"privateSaleTokens(address,uint256)","4f4a69c8":"TestTokkSale()","4f4b30ba":"dropManualState()","4f4b890a":"getCET6ById(uint32)","4f4cd650":"getAllTellers()","4f4d022b":"upgradeQualificationByTokens()","4f4d4728":"offeringEnded()","4f4df442":"approve(address,uint256,uint256,uint256)","4f4e1b74":"founderSwitchRequest(bytes32,bytes32)","4f4e47f1":"stopAirdrop()","4f4ec991":"PubToken(uint256)","4f4ef121":"firstBonusSalesEnds()","4f4f23ef":"SundayFundayToken()","4f4fa5a6":"removeReferral(address)","4f501f27":"changeOuts(address,address,address)","4f504d72":"getBalanceInPlay()","4f511102":"setDeveloper(address,address)","4f51bf46":"getBidIdList()","4f52b2bc":"findLockupIfCTD(address)","4f52ccfa":"beneficiary1()","4f53126a":"pauseGame(bool)","4f538ae1":"rain(address[],uint256)","4f53e83e":"smartProperty(uint256,string,uint8,string,address,uint256,uint256,uint256)","4f54f4d8":"getMatchDetails(bytes32)","4f5539c0":"SetPrice(uint256)","4f556b23":"onceoutTimePer()","4f558e79":"exists(uint256)","4f55f292":"convertIntoHtlc(bytes32,address,uint256,uint256,uint256,bytes32)","4f573cb2":"withdrawRevenue()","4f57641c":"getHorse(uint256)","4f58704c":"ARI()","4f58d5c9":"getTokenUSDRate()","4f5963fb":"calculateYourValueEven(uint256)","4f5a4eb9":"setAssetOwner(uint256,address)","4f5af739":"getBirthTime(uint256)","4f5b3318":"dateEndIco()","4f5b9f23":"power2(uint256,uint256,uint32,uint32)","4f5ba601":"airdropOn()","4f5c6e0a":"bonusOne(uint256)","4f5d06c2":"getPurchasePrice(uint256,uint256)","4f5d5295":"chairBalance()","4f5e6a8d":"whitelistedTransfer(address)","4f5f560a":"founderOf(uint256)","4f5fca97":"LimitEther()","4f5fcb34":"authorize(string)","4f6065e0":"get_presale_arbits_total(address)","4f60ae2e":"DividendReceived(address,uint256)","4f60f334":"multiAccessAddOwner(address)","4f610e74":"getDeclaration()","4f617b81":"unsetSectionForSale(uint256)","4f61db15":"VEGAS()","4f61ff8b":"kyberNetworkContract()","4f6247f8":"setThirdAddressBalance(address)","4f645993":"lastMiningBlock()","4f64808d":"createCustody(address)","4f64aa09":"advisorsLock()","4f64b2be":"tokens(uint256)","4f653f09":"_scheduleTournament()","4f655a61":"setMinimum(uint256,bool)","4f65cc3c":"ethToTokens(uint256,bool)","4f6716d3":"whitelistAddressArray(address[])","4f674164":"addBookSigner(bytes16,address)","4f67498e":"updateUSeqIndex()","4f6754d7":"tenEndTime()","4f67bd9e":"numberFor(uint256)","4f67fe22":"LOG_OwnerAddressChanged(address,address)","4f69dd3d":"triggerWithdraw(address)","4f6a441c":"getRandom8(uint8,uint8)","4f6a461a":"CatalogPlayers()","4f6acaa1":"getLedgerCount(string)","4f6adf48":"setPayOuts(uint256,string)","4f6b1a70":"vuePayETHDestination()","4f6b472d":"tokenSupplies()","4f6c3372":"CrowdSale_Halt()","4f6c63ea":"TeamRegistered(string,address,string,bool)","4f6c87fb":"STARTToken()","4f6cb43f":"advisers()","4f6ccce7":"tokenByIndex(uint256)","4f6d04e7":"createSeedCollectible(uint8,uint8,uint256,address,uint256,uint256,uint256)","4f6d150d":"LuvCoin(uint256)","4f6d20a9":"getRewardForAddress(address,address)","4f6d3aed":"refundGas()","4f6d97ed":"MakeTransaction(address,uint256,uint256,string,string,uint8)","4f6d9e16":"_settleAndRestart()","4f6dcf74":"PoS()","4f6de831":"testComplexCombination()","4f6fcc46":"getAirdropList()","4f7035b4":"DeleteAllRequests()","4f7132c0":"TokenDemo(uint256,string,uint8,string)","4f71473e":"withdrawAll(address,address[])","4f71ef81":"parse(bytes32)","4f72e1c3":"buyChamp(uint256)","4f731087":"checkTokenBalance()","4f734965":"setBBDPrice(uint256)","4f73928a":"setComment(bytes3,string)","4f739ff0":"addHouseStake()","4f73b7fa":"EthernityFinancialOracle()","4f73b8e6":"STAKE_BONUS_MIN_THRESHOLD()","4f73f1f8":"withdrawToAdress(address,uint256)","4f73f71d":"getOwlmasterReq()","4f7474cb":"closeAnnouncement(uint256)","4f74acfe":"buyEggs()","4f74d4f6":"ftechiz()","4f755fe7":"financialAccount()","4f75af3a":"tokensSuppliedFromReferral()","4f75c464":"startExit(bytes32[],uint256)","4f75e930":"UNLOCKINTERVAL()","4f76a077":"addInvestorToWhiteList(address)","4f76c87c":"createSportEvent(string,uint8,uint256)","4f76cb02":"testGetBitFailIndexOOB()","4f772420":"changeFundContract(address)","4f779753":"DimaCoin()","4f77feec":"getPositionInterestRate(bytes32)","4f79409f":"LogBuy(address,uint256)","4f7ac7ab":"toteLiquidatorWallet()","4f7aede9":"add(uint8,address,uint256)","4f7baec0":"test_mint(int256)","4f7cd683":"setReportRegistrationFee(uint256)","4f7d4951":"addVIP(address)","4f7d5de9":"setTimeRC(uint256,uint256)","4f7d87ac":"PoiseToken()","4f7dad6a":"buyToken(uint256,string,string)","4f7e7086":"iconiqToken()","4f7eb571":"getHowMuchUntilHardCap_(uint256)","4f7fc13f":"CLIENT_TIME_TO_DECIDE()","4f801270":"releasableBalanceOf(address)","4f803516":"getOrCreatePreviousPreviousFeeWindow()","4f8115a2":"tokensAddress(uint256)","4f817a2a":"tInstance()","4f81b930":"_sendFunds(address,uint256)","4f829ee8":"set2(uint256,uint256)","4f82ff41":"isCertified(uint256)","4f83fe64":"timeLocked(address)","4f840761":"demandTrial(uint256)","4f840c2b":"setMigrateToAddress(address)","4f8411e5":"_approvedFor(address,uint256)","4f851d73":"BineuroToken()","4f85769a":"closingTimePeriodOne()","4f8632ba":"user()","4f868b94":"etherSince20()","4f86bde2":"BuyFromFollower(address)","4f879ff0":"StackLottery()","4f883783":"CheckProofOfOwnership(bytes32)","4f88cc3c":"returnAllPollStakes(bytes32)","4f895031":"finalizeSale(uint256,uint256,uint128)","4f896d4f":"resolve(uint256)","4f8b9e64":"getBuyersList()","4f8c2a8a":"block02w()","4f8d40e1":"closeTournament(bytes32)","4f8da1fe":"RewardWallet(address,address,address,uint256)","4f8dd40a":"getOpinion(uint256)","4f8e2fdf":"LinkToken()","4f8e624e":"Greeter(string)","4f8fb544":"erc223Received(address,uint256,address,uint256)","4f8fc8ef":"setNonceForPublicKeyX(uint256,uint256)","4f8fe6a4":"THREE_YEAR_KEEPING()","4f8ffd1f":"set_contrib_arbits_min(uint256)","4f9000a0":"nextPrizePoolPercent()","4f932d44":"_generateIdentity(uint256,uint256,uint256,uint256)","4f935945":"capReached()","4f93995d":"saleNotEnd()","4f93b9e8":"setCommunityLock(address)","4f945a8a":"transferOwnCoins(address,uint256)","4f9559b1":"cancelOrdersUpTo(uint256)","4f958146":"LongLegs()","4f95a04b":"ethTransfer(address,uint256)","4f95ddec":"shopStorePrice()","4f95e960":"getTotalDropsOf(address)","4f961a6b":"RATE_TIER3()","4f962b72":"setPriceRate(uint256,uint256)","4f9660ed":"sendToTeam()","4f968868":"PauseTokenContract()","4f96ab8e":"retrieveUportInfo()","4f96baf1":"createNewAccount(address)","4f96bc00":"records(bytes32,uint16,bytes32,uint16)","4f96cddd":"calculatePreBonus(uint256)","4f96decf":"migratePlayerData1(uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","4f96e039":"waitingOracles()","4f96f446":"tier1LOT()","4f96fba7":"setAuditAssignBlockNumber(uint256,uint256)","4f97f97f":"lastCrowdsale()","4f9899c3":"PythonCoin()","4f995d08":"getPeople()","4f996a07":"callerDel(address,address)","4f99a96e":"getBorrowingItemByObjId(uint64)","4f99b7c5":"currentDate()","4f99b82d":"setBurntWalletAddress(address,address)","4f9b7bc8":"totalTokensSale()","4f9bf601":"totalTxFeePercent()","4f9bfdac":"OVISBOOKED_BONUSTOKENS()","4f9c5253":"Store(string)","4f9c5bf3":"airdrop_percent()","4f9d482a":"HALF_TIME()","4f9d719e":"testEvent()","4f9de158":"_sendTokens(address)","4f9ea1c3":"flightDone(uint32)","4f9ebe09":"getDonationPrice()","4fa037c4":"setTokenMintFeeProp(address,address,uint256)","4fa07325":"adddraw(uint256)","4fa0a4b7":"_getCanvas(uint32)","4fa10cfc":"getdata()","4fa11dd2":"setAirdorpList(address[],bool)","4fa20a52":"isDelayed()","4fa232fe":"getIcoDeflator()","4fa2cb50":"solved(string,string)","4fa3d029":"setSTFactory(address)","4fa3eeff":"withdraw3()","4fa406ee":"BeforeChipCost(uint32)","4fa43991":"getArtistTrack(bytes32,address)","4fa48a88":"isSameDay(uint256,uint256)","4fa4a531":"getbackTB(uint256)","4fa4d01a":"_averageSalePrice(uint256,uint256)","4fa519fa":"setValue()","4fa65d58":"WRLToken()","4fa679d8":"forward(uint256)","4fa6a6d5":"crowdSaleStartTimestamp()","4fa6caf6":"getSigner(bytes32,uint256)","4fa6cde4":"requestEthUsd(uint256)","4fa7e353":"pledgeFees(uint256)","4fa87fd3":"frozenFunds(address,uint256)","4fa88720":"setBypassStatus(address,bool)","4fa972e1":"maxSupplyForEra()","4fa99402":"spinnerCountsByType(uint256)","4fa99dd0":"Matching_Ethers()","4fa9b5d5":"seed_base_token()","4fa9e4dc":"getArticlesOwn()","4faa2d54":"getTimeElapsed()","4faa8a26":"depositEtherFor(address)","4fab2035":"newSchellingRound(uint256,uint256)","4fab2ca4":"testGetFrontend()","4fac7e41":"getOwnedTokenIds(address)","4fac9c65":"bonussale_WeiRaised()","4faca8f4":"sendTokenTeamAdvisor(address,address)","4fad404a":"confirmProposal(string,uint256)","4fad5c8a":"depositAgent(uint256,uint256,string,string)","4fad96dd":"DST_ICO()","4fae3254":"setMaxAuditDuration(uint256)","4faea4d6":"FrankTestToken1()","4faed396":"checkVotingForSendWeiFromExchange()","4faf9420":"airdropFor(address)","4fafee40":"lottoPrice()","4fb057ad":"ContractInstantiation(address,address)","4fb0a3cd":"claimTeamReserve()","4fb0d95e":"getLocalBountyBalance(uint16)","4fb19db5":"dollarCost()","4fb2e45d":"transferOwner(address)","4fb30d8b":"txs()","4fb31a6a":"replaceProto(uint16,uint8,uint8,uint8,uint8,uint8,uint8)","4fb34523":"deployStepFour()","4fb3d3b1":"getUserHistory(address)","4fb3fef7":"totalExecutedPerDay(uint256)","4fb46d5c":"getRoundStatuses(uint16)","4fb4bcec":"step5()","4fb4e833":"entryStorage(bytes32)","4fb4f5a3":"ETHMCoin()","4fb55858":"setTargetDiscountValue4(uint256)","4fb67111":"utfStringLength(bytes4)","4fb764c9":"orders()","4fb7f1d7":"getPastWinnerAddresses()","4fb8843c":"getAllBonus()","4fba68c5":"pWhitelist(address)","4fbc7e11":"enableTokenWithdrawals(address,bool)","4fbd051d":"verifyCertification(address,uint256)","4fbda01f":"LogPenaltyDisbursed(address,uint256,address,address)","4fbe30d4":"changeTokenRate(uint256)","4fbea8ea":"approveKyber(address[])","4fbf6e9f":"getFish(uint32)","4fbf6fbb":"getMultiRequestLastRequestId(uint256)","4fc0ee17":"setCreditMCCurator(address)","4fc28f68":"getUndistributedBalanceOf(address,uint256)","4fc2d3be":"setBaseExchangeRate(uint256)","4fc3f41a":"setCooldown(uint256)","4fc4b5a0":"highEtherBonusValue()","4fc573c7":"addrDevelopment()","4fc59e6b":"set_Rate(uint256)","4fc5a549":"StartAuction(string,uint256)","4fc63e02":"ExToke(address,address,address,uint256,uint256,uint256)","4fc78cf1":"add_reward()","4fc7a47d":"extra_time_bought()","4fc84791":"senderAddress()","4fc91633":"setNotLessThan(uint256)","4fc9584a":"messageSpanStep()","4fc9c91a":"identityOf(bytes32)","4fca3159":"rawBuy(bytes32)","4fca329a":"drawBookLotto()","4fcaadae":"_createDivCard(string,address,uint256,uint256)","4fcb2968":"kingSpirit()","4fcb9e2f":"getLastPayoutDate()","4fcc30d9":"AuctionSuccessful(uint256,uint256,address)","4fcc9e07":"getDynamicArraySize()","4fced032":"OneKeyToken(uint256,string,string)","4fcf1f39":"revealWinner(string)","4fcf8210":"eraseRecord(bytes32)","4fd0fcb6":"partnerAmountLimit(address)","4fd1519c":"getValidDurationBlocksData()","4fd23dd4":"transferMulti(address,address,address,address,address,address,address,address,address,address,uint256)","4fd2ee52":"getTargetContactPubKey(bytes32,address)","4fd394ba":"getMax(uint128[])","4fd3d125":"onlyAdminsCanDoThis()","4fd4dbaa":"_emitError(bytes32)","4fd61333":"DataChanged(bytes32,address,string,string)","4fd6194d":"setup(string,address[])","4fd64591":"tokenClient()","4fd6b325":"test_5_generateSecondAccountBalance_increaseBlocksBy1000()","4fd6e8ac":"andTheWinnerIs()","4fd6ff6e":"CROSAIR_SHIP_PRICE()","4fd7718b":"firstStageDuration()","4fd798b1":"TsingDaToken()","4fd81926":"setMaxDividendDepth(uint256)","4fd839c6":"getRabbitDNK(uint32)","4fd8411c":"AddressChangeRequested(address,address)","4fd88a1c":"spendFunds(address,uint256,string)","4fd9c9ac":"ExposureClosed(bytes32,address,uint256,uint256)","4fdb7c47":"RtbRpay(address,uint256)","4fdb91ab":"TOKEN_AMOUNT_ICO_STAGE1_PRE_SALE1()","4fdbe2c3":"changeFoundationAddress(address,string,address)","4fdc1a70":"icoCore(uint256)","4fdc4295":"_offerCanvasForSaleInternal(uint32,uint256,address)","4fdc53f6":"setTokenOwner(address,uint256)","4fdc5f65":"LiverpoolvsManCity()","4fdd228d":"ownerOfPosition(bytes32)","4fde7cd9":"tokenToFounder()","4fdf4c9a":"Icebox(uint256)","4fdf64ce":"totalBorrowingItem()","4fdf8a03":"VLTMultisig()","4fdfcd42":"removeBytes32s(bytes32[])","4fe01d38":"setTokenReward(uint256)","4fe06988":"toTimestamp(uint256,uint256,uint256)","4fe0bd1e":"fundsAvailable()","4fe0ff1a":"submitInitialMerkleState(bytes32,uint64,bytes32[],uint256[],uint256,uint256,bytes32,uint256[2],bytes32,bytes32,uint8)","4fe2e15a":"checkTicket(uint256,uint256)","4fe2f085":"INVESTORS_TOKENS_RESERVED()","4fe47cb4":"emitStoreAndPay()","4fe47f70":"setMaxAmount(uint256)","4fe50bc6":"baseTokenGetRate()","4fe51ee6":"ValkyrieNetwork()","4fe5c2b4":"Vidnix()","4fe5f587":"CCXToken()","4fe61b9e":"disableBonus()","4fe6adb4":"NewToken(string,string,string,address)","4fe71e95":"withdrawUserReward()","4fe72439":"DEVELOPER_SUPPLY()","4fe7940b":"show_Balance_available_for_Sale_in_ETH_equivalent()","4fe81ffd":"artistsArtworks()","4fe82444":"addEthContribution(address,address,uint256)","4fe85563":"RAGTOKEN()","4fe87fe0":"FundsWithdrawnEvent(address,address,uint256)","4fe8b1a8":"changesoldierreplenishrate(uint256)","4fe8b4c1":"deleteData(uint256)","4fe8d03f":"bountyTokensTransferred()","4fe9cc63":"InitHostBalance(address,uint256)","4fea572e":"ERC20Token(string,string,uint8)","4febb4f9":"WorldCupTeam(address,string)","4febe793":"NewText(string,string,address,uint256)","4fecf22d":"delegateManagement(address)","4fecf9cf":"Helex()","4fed1c94":"isTokenForSale(uint256)","4fed6a10":"teamTimelock()","4fed9a60":"Bonus(uint256,uint256)","4fedebf6":"numOfTeam()","4fee13fc":"startAuction(uint256,uint256)","4fee2437":"tokensaleStartTime()","4fee5360":"transferLike(address,uint256)","4fee63da":"securitiesOf(address)","4feeb18a":"priceQuerySent()","4ff0b071":"SILENT_Token()","4ff13571":"x2()","4ff1ddec":"TransactionConfirmedAfterExpiry(uint256,uint256)","4ff2bcb7":"getStageBonus(uint256,uint256)","4ff30c5f":"nextMintPossibleDate()","4ff3a989":"BLOCK()","4ff44fda":"_holding()","4ff45d73":"unapproveDisbursement()","4ff4ab6c":"ticketsOwners(address,uint256)","4ff57e9f":"airdropAndBurn()","4ff62627":"convertCore(address,uint256,uint256)","4ff6aa46":"deactivateTeam()","4ff6e86e":"getProviderPublicKey(address)","4ff7ff32":"withdrawERC20Tokens(address)","4ff92d6f":"getAssignedSupply()","4ffb01ce":"RemoveEvidence(bytes32)","4ffb32d3":"BlackSnailE()","4ffb861e":"_addAuthorization(address,address)","4ffc9204":"centralBankAddress()","4ffcd9df":"exchangeRates()","4ffcfefe":"m_weiBalances(address)","4ffd23a7":"sell(uint32)","50003ca6":"calculate(address)","5000a443":"jingZhiManager()","50010427":"bet(address,uint256,uint256,uint256)","50013a53":"LICERIOToken()","5001780b":"maxFundingGoal()","5001f3b5":"base()","50020560":"Accessible()","5002b2b9":"FusoraToken()","50035eb8":"getInUse(bytes20)","5003c2cc":"setPriceProgression(uint16)","5003c81d":"ERC223StandardTokenFactory(address)","5003d58f":"returnTokenBalance(address[2],uint256[8],uint8,bytes32[2])","5003e4d1":"Token(uint256,string,uint8,string,address)","5003efca":"extendedTokenCap()","50048174":"addItemLendingList(address,uint256)","5004e7a6":"CoinFast()","50050769":"changeRegistrationFee(uint256)","50051c20":"CELToken()","50058508":"getPubkey(address,address)","5005ba47":"setDestroyEnabled(bool)","50060f34":"getBatch(address,uint8)","5006bf0b":"internalExecuteDelegatecall(address,uint256,bytes)","5006e60a":"ownershipToCreator()","5007364f":"getLeaderboard(uint16)","50077f00":"jsonCat(string,string,uint256)","5007e47e":"getIntrospectionRegistry()","5007ec95":"IbzCoin()","5007ff15":"GridcubePlatformToken()","500844dd":"setTotalStakingHistory()","5008b7dd":"buyProduct(address,address,uint256)","5008cfcc":"votePerETH()","5008f699":"setRollover(uint256)","5009432d":"MAX_PRIVATE_FUNDING_SUPPLY()","500b6b3e":"calculationTotalSupply()","500b9426":"accountLocked(address)","500c6755":"DepositAmount(uint256,uint16)","500c6f21":"setManagementFeeChargePercentage(uint256,uint256)","500d22db":"setData_14(string)","500e73a4":"SSChainToken()","500e9eaa":"finishZeroDistribution()","500ec41b":"setAirState(bool)","50107c77":"addThing(string,bytes32,string,bytes32)","501146b4":"_updateNextPeriodPoints(address,uint256)","50114925":"transferDelegated(address,address,uint256,uint256,uint256,uint256,bytes)","50116afb":"decreaseAssetsCertified(uint256)","5011e399":"replaceSigner(address,uint256,uint8,bytes32,bytes32)","5012416f":"processAndCheckParam(string,address,uint8[],bytes32[],bytes32[])","50125546":"cancelRequest(bytes32)","50127418":"Question(address,string,uint256,uint256,string)","5012adca":"packInfo(address,bytes)","5012eb67":"trFee()","50133d50":"MinimumViableToken(uint256)","5013bb79":"TheTokenB()","50140fe5":"distributeBountyTokens(address,uint256)","50148ed2":"initEpochBalance()","5014a18e":"node_parent(uint256)","501578ca":"EntryAdded(bytes32,uint256,uint256)","50159de6":"ownerRemoveCeo(address)","5016128e":"isLock(address)","5016b9b1":"buyFromBlackMarket(uint256,uint256)","5016d29f":"refundedAmount(address)","5017f1f1":"constructor_()","50180944":"NEST()","50188301":"withdrawable()","5018a0fd":"withdrawAddr(address)","50192ae6":"test_31_assertGasUsage50Boards()","501957b8":"getManifest(address,bytes32,bytes32)","50197646":"rId()","501a4d68":"changeNameSymbol(string,string)","501a7a74":"uint256Min(uint256,uint256)","501b0b18":"receiveLoanOwnership(address,bytes32)","501bae76":"setr2VaultAddr(address)","501bfb60":"transferStampsToOwner(uint256)","501c5205":"_updateLandData(uint256,uint256,string)","501e3a2c":"_icoPercent()","501e8428":"getPart(bytes,uint256)","501fdd5d":"setSpecID(bytes32)","5020dcf4":"convertToEach(uint256,string,uint256)","5021051e":"setInflation()","50213c9f":"EXPERTS_POOL_ADDR()","5021783a":"addPerformer(address,string,uint8,string)","5021e534":"_dividendsSum(uint256[])","5022238f":"AVAILABLE_IN_PRE_SALE()","50228201":"getCollector()","5022d232":"CelebrityBreederToken()","5022e940":"experty()","50234173":"addNotary(address,uint256,uint256,string)","5023d124":"TestFactory()","50240158":"rejectContribution(address)","50240a34":"onLotteryInsurance(address)","502414e4":"marketMaker(string)","50248cd1":"ownerYHT()","50259cd3":"privatePreICOFreeBonusPercent()","5025b9ae":"expire(uint256,uint256,uint8,bytes,bytes,bytes)","5028594a":"setBlockDotGasLimit(uint256)","502a86bf":"gameGiftUserDayTimes()","502aa3b5":"usersList(uint256)","502b31d2":"splitEther()","502b8bda":"synths(bytes4)","502be15e":"unregisterByList(address[],bool)","502c9bd5":"userAddresses(uint256)","502cc114":"KittyToken()","502d7599":"IssueTokens(address,uint256,uint256)","502dadb0":"disableWhitelist(address[])","502e3b46":"EffectAdded(uint256,uint8[])","502f2dee":"sendFromTeamWallet(address,uint256)","502fe251":"getUidLastUpdate(string)","5030c325":"signBuyer(uint256)","503129c3":"ISC()","50312c9e":"checkContractBalance()","503248fe":"minPriceForMiningUpgrade()","5032f33b":"TokenLocker(address,address)","50357beb":"buyCard(uint256,address)","5036258b":"disableAddress(address)","50364825":"InsertImage(string)","503667bd":"_burnFor(address,uint256)","503687bc":"getTokenReleasePercentage()","5036d610":"Presale()","50372085":"isTokenContract()","503765c6":"LOCKTokenCOINLock(address,uint256,uint256,uint256)","5037ec62":"changeDelay(uint256)","5038c9c5":"getListingAtPosition(uint64)","50391932":"findContractVersionByAddress(address)","503919b1":"unblockTokens(address)","50392bcc":"CleanFoodCrypto()","50395188":"tan_lian()","5039c62c":"inviteHandler(bytes32)","503a0ef8":"requestLoans(address,uint256)","503a3609":"mainSaleSecondStartDate()","503adbf6":"changeableToken(uint16)","503b64c0":"setRequestProcessed(uint256,uint256)","503c449f":"decreasePregnantCounter()","503c849e":"cashOutRate()","503caa1b":"performPayout()","503caa53":"phase2TokenPriceInEth()","503de95b":"newCash()","503e11de":"getAssetIdCargoArray(uint32)","503e9d33":"changeWeTrustSigner(address)","503eb429":"destEthFoundation()","503ef9fe":"changeFeeAmt(uint8)","50400128":"RiskPrice(uint128)","5040307c":"amountOfOrderQueue()","50405fdf":"setMemberLevel(address,uint8)","50409041":"_computeSalesCut(uint256)","5040c6e7":"HardCap()","50411552":"challengeWinnerReward(uint256)","50416b93":"batchClaim(uint256,uint256)","5041742a":"bidOnEthSiringAuction(uint256,uint256,uint8,bytes)","50428f84":"insertLastPlys(uint256)","504291f0":"maxToSell()","5042ffbe":"contributeInIco()","504321e0":"toTeamEthContract()","504334c2":"setNameSymbol(string,string)","50449d9d":"whiteListPreSaleDuration()","5044b112":"getChecksumCount()","50473c82":"deathData_f15()","50479065":"cancelCreation()","5047b337":"changeName(bytes16)","5047f867":"setAirdropParams(bool,uint256)","5049b238":"potentialWinner()","5049f497":"nominate(address,address)","504ac982":"transfer(string,string)","504b0ae8":"LOG_ValueIsTooBig()","504b122f":"readMulti(bytes32,bytes32[])","504b91b5":"GeishaCoin()","504b97ae":"getcertifieddata(uint256)","504bcde7":"getAuctionTokenIDsOfOwner(address)","504c9582":"PARTNERS_SHARE()","504cceac":"purchaseTokens(uint256,address)","504d080b":"getActions()","504d27fd":"transferAmount()","504f1671":"getSize(address)","504f5e56":"floor(uint256)","504f6085":"serviceTransfer(address,uint256)","504fac70":"getGiftTemplateById(uint256)","504fbb19":"LifeChain(uint256,string,string)","50500934":"right28(uint256)","50500fac":"LaunchPartnersAddress()","50512420":"getPlayerDiscount(address)","505158bb":"getRecordsCount()","50515d5a":"resolveDispute(bytes16,bool)","50520b1f":"contribution()","5052587f":"Show_automated_Sell_price()","5052abad":"viewContribution(address)","50548d85":"LogMakeDeposit(address,uint256,string)","5054e8bf":"collectDevFees()","5055225f":"preSaleStartDate()","5055557a":"perform_selfdestruct(uint256)","50558dd5":"setPropheth(address)","5055d7c3":"withdrawnMelon()","50560a1a":"_oraclizeQueueWinner(bool)","5056a36a":"AuthorizationSet(address,bool)","5056b309":"getSetting()","5058c460":"safeWithdraw(address,uint256)","5058f013":"periodWeek()","505903ba":"GetEthBalance()","50591478":"getChainDrawingsByChainID(bytes32)","5059fad1":"transferIssuer(uint256,address,address)","505a202b":"priceChangeName()","505a7bce":"pullEther(uint256,address)","505ba497":"processInvestment(address,uint256,address)","505c3c58":"MasAnu()","505c3d5e":"piecesOwned()","505da5c7":"_bonusToFighters(uint32,uint8,uint256)","505e71d0":"test_twoInvalidFalseEqLog()","505ed108":"createPetCardSeries(uint8,uint32)","505f2697":"rejectCertification()","505fb46c":"add(uint256,uint256,uint256)","505ff574":"register(address,uint256,bool)","506092f7":"getAmbientLightException(bytes32)","50609cea":"onTokenTransferCalled()","5061029d":"MINE()","50613afe":"getDropNotice()","5062ef16":"readOpentasks()","50635394":"claimBonus()","50635e2f":"CYPHERX()","50636a68":"ERC223Token(uint256)","50637dd2":"stageName()","5063f361":"addMembers(bytes32,address[])","50648403":"registerWithInviterID(uint256)","506535f3":"verify(address,bytes32,uint8,bytes32,bytes32)","50655d8c":"maker()","5065cbab":"geteth(address)","50669508":"DatasetHub()","50669a03":"unpauseToken()","5066a9ac":"setLPTargetPostion(uint256)","5066e2bd":"teamKeepingWithdraw(uint256)","5067f32d":"KALToken()","50685c81":"SwarmRedistribution()","50692d9a":"toContentID(address,string,string,address,bytes32)","50699e89":"requestBuywithFX(uint256)","5069a6a6":"calculateKebabSell(uint256)","506a0aaa":"reverseSplitTokensBeforeDistribution(uint256)","506a6a10":"tokenBonusForThird()","506aaede":"issueDividend()","506b56da":"centralBanker()","506bd3a6":"removeExchanger(address)","506bff11":"left7(uint256)","506cb188":"NewOrder(uint256,address,address,address,uint256,uint256,uint256,uint256)","506cf560":"blackil()","506d54c7":"getBigWinner()","506d9ebd":"getData_8()","506dc7e1":"getUsageDetails()","506e106c":"setToS(string)","506ec095":"periodEnd()","506ee1ef":"traderNonces(address)","50710ef5":"_finalRoundWinnersFight()","50713dc0":"transferOwnershipManualMinter(address)","5071fcf0":"recoverSouls(address[],uint256[],uint256[])","5072a21b":"_createPotato(uint256,uint256,uint256,uint256,address)","5073eda3":"setPOOL_edit_25(string)","5074449d":"isTradable()","50750497":"VestingTransfer(address,address,uint256,uint256)","50754fac":"totalNetworkCollateralisation()","5076d445":"AdminClaimAirdrop(address,uint256)","5077ac0e":"registerImage(uint256,bytes,uint256)","507843f8":"assemblyShamir(uint256,uint256,uint256,uint256)","50787341":"normalizedEarlyPurchases()","507959e1":"newBeneficiary(address)","507a83ea":"arand(address,uint256)","507a8e40":"AssetToken(uint256,string,uint8,string,address)","507afbec":"processBuyAmount(uint256)","507b3450":"getKNCRateRangeSignatures()","507d17bb":"MultiplyContract(address,address,uint256,uint256,uint256,uint256)","507d5954":"stopCrowdsale()","507d8887":"setCompte_19(string)","507e7888":"subscribe(string)","507e97a9":"setBUA(bytes32,uint256,address)","507eeff9":"trade(address[2],address,bytes,bytes)","50807ecc":"getSellerfee()","50818fbb":"internalGetHowMuchUntilHardCap(uint256)","50833515":"RestartReceivingContributions()","508335e6":"maxRentPeriod()","508343d6":"initiateEscrow(uint64,uint256,uint256,address,address,address,address)","5083b29f":"changeBookingFee(uint256)","508493bc":"tokens(address,address)","50849c3b":"placeoffer(uint256,uint256)","5084b2a3":"MintAuthority(address)","5084da18":"fipsOwner(bytes20)","5085c9f1":"numTokensInCurrentCompactData()","50867236":"debug_token_balanceof_faucet()","50872d1e":"onTransferFrom(address,address,address,uint256)","50872e32":"EUROQUINNToken(uint256,string,string,uint256)","50875b6c":"remainingLockDate()","508762c1":"right10(uint256)","5087abc7":"joinOutBattle(string)","50894456":"manuallyMakeOraclizeCall(uint256,uint256,bool,bool,bool)","508a0a9e":"NitrToken()","508a8976":"saleSuspended()","508ab47a":"showPoolContract(uint256)","508b0955":"testNoTokensTwoCalls()","508bb866":"getMyBet(uint256)","508cde13":"getMappingID(string,address)","508d0f57":"getNumberOfPeriods(uint256,uint256)","508d60aa":"teamETHUnlock2()","508df5df":"numResponseOptions()","508e3718":"setValidKYC(bool)","508f352d":"heapSort(uint16[])","508f46a0":"getGameSettings()","50904081":"purchasesCount()","509065b8":"mintTokensForFirstStage()","50909851":"ownerEmit()","5091c49e":"bonusSeed()","5091e7c4":"selfdestroy()","5091f881":"updateArtistCommission(uint256,uint256)","50921b6c":"EGGS_TO_HATCH_1CROCS()","509239c0":"amountContributedBy(address)","50928ba4":"canCreateGames()","5092f97e":"Company()","50930ca5":"doFailingTransferFrom()","50933a0f":"Bitnusu()","5093cb38":"setEtherDelta(address)","5093dc7d":"setValue(int256)","50944a8f":"setMembership(address)","509484d5":"setStakeContract(address)","509515b5":"getWinnerAccount()","50963bc4":"returnTokensTo(address)","50965f57":"currentWulinMasterPrice()","50977faf":"fetchTokenBalance()","5097e51f":"Public()","509a13dd":"RoundId()","509a7e54":"getRoot(bytes32,uint64,bytes)","509bf2bf":"axe()","509c3fc8":"createTestNetContract(address,address,address,uint256,uint256,uint256)","509c5df6":"reservedFunds()","509c5eee":"ASGToken()","509c90b3":"callTokenFallback(address,address,uint256,bytes)","509cd360":"Board()","509d6d72":"mediumPrice()","509d8c72":"VALUE()","509f0fe4":"setupFundingTime(uint256,uint256,uint256)","509f6ff8":"AquaToken(uint256,string,string,uint8,uint8,address)","509f7cf2":"testingForFun(uint256[])","509f8633":"create_account()","50a09d60":"SaleIsLive()","50a0f733":"final_shares_sold()","50a107cc":"setVotingPhase()","50a13702":"denyChangesMultitoken(uint256)","50a14ea4":"returnPreSaleTokens(address,uint256)","50a1676e":"createdAt(uint256)","50a1debd":"robAll()","50a22ee1":"BancorGasPriceLimit(uint256)","50a3bd39":"enterPool()","50a49f5f":"getBurnDelegates()","50a58b3f":"exist(address,address[])","50a5c872":"host_reveal(uint256)","50a5ebd9":"updateSpaceshipStatus()","50a675fe":"QQBToken(address)","50a6887c":"UpgradedNodelist()","50a6b423":"settlementPayOut(bytes32,uint256)","50a7755e":"newDad()","50a82265":"EventEmergencyStop()","50a8246f":"testRIPEMD160()","50a85d36":"DeathNode()","50a8d2b9":"getNumSigsOwned(bytes32)","50a9b541":"bootyToken()","50a9e127":"backup()","50a9eddb":"testControlSetNotUpdatableNotOwner()","50ab6f7f":"getMsgs()","50ac9828":"FileData()","50ad2f76":"vendGuardian(uint256)","50ad7321":"GPSDecayingTokenEnvironment(uint256,uint256)","50adc70a":"winning_country_string()","50adcdb7":"fundToken()","50ae28ea":"StandardCertificate(string,string,string,string,uint256)","50ae85d8":"reservedAddr()","50aeddcf":"censorChatMessage(uint256)","50b0021c":"currentRandom()","50b04a4e":"getCountryById(uint8)","50b066b2":"changelp13(address)","50b149a9":"setPriceStep1(uint256)","50b1a697":"toReferrer(uint256)","50b1ab69":"PET(uint256,string,string)","50b1f058":"fetchPaidOrdersForPayer(address)","50b2ae66":"transferChips(address,address,uint256)","50b44712":"tickets(uint256)","50b48c5e":"autonomousConverter()","50b58c06":"JuggernautToken()","50b5bc93":"unlockFirstTokens()","50b62939":"getAddressBalance(address,address)","50b6ba0b":"getWtoken(uint8)","50b79722":"setSanLength(uint256,uint256)","50b7b7a2":"setRating(bytes32,uint256)","50b7e942":"acquireTokens(uint256,uint256,address,uint256)","50b82a48":"objectSack()","50b91881":"setKycWhitelist(address,address,bool)","50b926fd":"UnityToken()","50b93b3b":"sendBuzzCafe()","50b9963f":"_continueTokenPurchase(address,uint256)","50b9c428":"oraclizeGasLimit()","50baa622":"withdrawToken(uint256)","50bacea9":"icoPhaseAmount1()","50bb117a":"defrostDate(address)","50bb4e7f":"mintWithTokenURI(address,uint256,string)","50bc051e":"lockedForAsset(bytes32)","50bc373d":"regionAvailable(uint256,uint256)","50bc4ae6":"_joinToProvider(uint256,address)","50bc6bba":"createSaleAuction(uint40,uint128,uint128,uint40)","50bd1933":"UberDelta()","50bda35a":"setCharge(bool)","50bda77e":"updateJobRate(bytes32,uint256)","50be7503":"giveToken(address,uint256,address,bool)","50beb835":"getDeploy(uint256,uint256)","50beca78":"isTrainer(address)","50bed043":"sendFunds(address,uint8,uint256)","50bfeadc":"initialTokens()","50c007c6":"verifyTx(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[5])","50c0f2b9":"licenseTermsRegistry()","50c15c93":"depositChecking(address,uint32)","50c2e4f6":"ADVISOR_SUPPLY()","50c34878":"priceOfAUnicornInFinney()","50c35227":"central_account()","50c38479":"resetCurrentTokenOfferingRaised()","50c3e676":"resolveErrorReport(uint256,bool)","50c40877":"Nai()","50c42921":"replicate()","50c4b64c":"_unpackAuraValue(uint256)","50c4ebc4":"finalTimestampOfBonusPeriod()","50c5c99a":"setScrapyard(address)","50c67734":"setPricingStrategy(address)","50c6784d":"ShareableMock(address[],uint256)","50c6a4e0":"_buyPixelBlock(uint256,uint256,uint256,uint256,bytes32)","50c6ef88":"setChampsName(uint256,string)","50c7ac75":"addint8(int8,int8)","50c8512b":"CollectibleNoLongerForSale(uint256,uint256)","50c88103":"setEruptionThreshold(uint256)","50c8dbd2":"totalBlocksMined()","50c90136":"fixedLog(uint256)","50c90af0":"unLockAddr()","50c946fe":"getNode(bytes32)","50ca6227":"getTokenInfoData()","50ca73c8":"aSetLaunch(uint256)","50cc5d4b":"totalWeiVolume()","50cca1e1":"rejectMail(uint256)","50ccf36b":"getWeiPriceOneUsd()","50cd4df2":"o()","50cd4f3f":"ScratchTickets(string,uint256,uint256,address)","50cdbb6b":"setEarlyParticipantWhitelist(address,uint256)","50ce761d":"NumberCreated(address)","50cee5a0":"addToWallet(address,uint256)","50cf20dd":"richtestff(uint256,string,uint8,string)","50cf569c":"getUserAttribution(bytes32,address)","50d00b95":"authorizeProcessor(address,address,string,string)","50d0b060":"createVestingForFounder(address)","50d12a72":"payReferrer(address,uint256)","50d17749":"BuyLimits(uint256,uint256)","50d279bd":"changeRewardMintingAmount(uint256,int256)","50d2bfab":"set_exchange_rate(uint256[])","50d491ab":"userGetPendingTxByAddress(address,address)","50d4a2b9":"crowdsaleGoalReached()","50d4bf15":"buy100ktickets()","50d50324":"stopSaleDepo()","50d5914a":"TOKENS_PER_ETHER_PRESALE()","50d6d893":"_rejectTransaction(uint256,address)","50d78f7d":"QueryFrozenCoins(address)","50d7bf09":"record(string,string,string,address,bool,string,string,string)","50d7d290":"withdraw_refund()","50d7da00":"GSH(uint256,string,string)","50d808d4":"StartTradable()","50d80fef":"addOffChainAddress(address,address)","50d8bcf3":"SMLToken(address)","50d925fb":"REBELCOIN()","50d9b932":"PatronOneWithdrawal()","50d9d472":"numberOfAuctions()","50da9f6d":"SellENS()","50dad350":"Hodling(bool)","50db7247":"maxCapPreSale()","50dc26ec":"TokenUser(address)","50dc43a1":"addGameMachine(address)","50dc4bfe":"addUserFeedback(address,uint256,address,string,string,string,string,string,string,uint8)","50dcce5a":"upPrice()","50ddd6f7":"addToEmployerAvgRating(address,address,uint8)","50de84c1":"CesiraeToken()","50deda1c":"addtoken(address,uint256,uint256)","50dede35":"marketDrugs()","50df10c3":"lockTill(address,uint256)","50df7eb4":"unsoldTokensAmount()","50df8f71":"isReady(uint256)","50e01e16":"Registered(address,bytes4,string)","50e036ff":"allowedContractsCount()","50e06b57":"Etherization()","50e08ddb":"devidendsOf(address)","50e14731":"BKEXComToken()","50e17308":"maxMineSize()","50e17975":"_badgeFreeze(uint256)","50e1b95a":"getShipProductClassByModel(uint16)","50e26c23":"getAssetBaseInfo()","50e27f2d":"TicTacToeLockedState(address,address,address,address,address)","50e28cb3":"SECOND_USER_CUT()","50e2ccad":"CoreTeamAndFoundersSupply()","50e343d0":"prWallet()","50e37961":"setWhitelisting(address,uint128)","50e38e63":"groupMemberInfo(uint32,address)","50e3b157":"sharesValue(uint256)","50e43c9c":"c(address,int256,int256)","50e4b069":"set0xExchangeWrapper(address)","50e513ac":"destroyUser()","50e59eb3":"isMinter()","50e706fb":"getProposalFunds(uint256)","50e72f61":"Break()","50e78690":"getHomeGasPrice(bytes)","50e7dde2":"setParetoToken(address)","50e81a3b":"setProviderCompleted(bool)","50e81e08":"_releaseToken(address)","50e84925":"saleEnd3()","50e8587e":"multiApprove(address[],uint256[])","50e86e1e":"setOwnerValidateAddress(address)","50e878df":"updateOrderAmount(address,address,uint256,address,uint256,bool)","50e9f948":"initialFiatPerEthRate()","50ea1932":"lookupISO3116_1_alpha_2(bytes)","50ea1c95":"MyIdolCoinToken()","50ea53db":"transferIncorrectDisputeBondsToWinningReportingToken()","50ea9274":"TokenRefund(address,uint256)","50eb2d02":"BBNToken()","50eb7ec4":"SupercarToken()","50eba4eb":"voteSnapshotBalanceBatch(address[],uint256[])","50ec2a6a":"batchCancel(address[5][],uint256[6][],uint256[])","50ec5903":"blackListSwithcer(address)","50ec6b1b":"getNamelistLength()","50ed2a2c":"poke(uint128,uint32)","50ed6264":"lastStakings(address)","50edd8c2":"nestedFirstAnyToAny(uint256)","50ee6de2":"candyLand()","50eebaf7":"mininumPurchaseTokenQuantity()","50ef3bae":"getQuestionVote(string,uint256)","50efc7c0":"districtToBuildingsCount(uint256)","50f07cf9":"setReadingDelay(uint256)","50f0880e":"sendLimitTokensToCompany(uint256)","50f0f83d":"getTransferFromFromValue()","50f1179a":"setPriceOfAss(uint256,uint256)","50f1c695":"authorizedLoggers()","50f2fb7f":"getCalls()","50f3dd7a":"assembleUnicorn()","50f4556b":"WhiteRhino()","50f462a4":"validationFailed(address)","50f46eef":"calcToken(uint256)","50f49db1":"getSlideEndTime(uint256)","50f4f9f8":"addShare(address,uint256)","50f503c1":"isSspRegistered(address)","50f5ef78":"getWork(address,address,uint256)","50f71526":"necashToken()","50f7c204":"maxTokenSupply()","50f8fc97":"LogCertificationDocumentRemoved(address,bytes32)","50f91ee3":"withdrawTokensRemaining()","50f956db":"nextAmount()","50f96b5d":"minEthPerNotification()","50f9b39e":"getReward(address,uint256,uint256)","50fa5d13":"stage4BeginTime()","50fb5a92":"buyWithReferral(uint128)","50fcff5c":"extCheckHalfLife()","50fdb01a":"setNewWinner(address,uint256)","50fe533b":"getLevitatingBirds(bytes32,uint64)","50feacc5":"PriceManual()","50fed3b4":"buy(address,uint256,uint256,uint256,bool)","50fef2e4":"tokenAirdropLeft()","50ff0761":"R_N_D_WALLET()","50ff2015":"endAtBlock()","50ff722b":"getChannelsGuids()","50ffbe81":"checkBan(address)","51003cab":"minimumIcoRate()","510040cb":"releaseLocked()","5100602a":"preallocate(address,uint256)","5100db6f":"SYCC()","51017702":"isOutcomeSet(bytes32)","5101880f":"CPXWallet()","510219cd":"defaultAuctionDuration()","51027320":"EUNOMIA()","5102ad69":"setImpactRegistry(address)","5102bc9d":"setTitle(uint256,string)","5102e238":"test_oneInvalidEqAddress()","5103a5a3":"certify(address,bytes32)","5104a3a7":"burnedTokensCount()","5104cb5c":"refundOnBehalf(address)","5105df3b":"buyTicketByEth(uint256,bytes32,bytes32,bytes32,bytes32)","5106b8fe":"transfer(address,address[],uint256)","510792c8":"hydroPartnerMap(uint256,address)","5107c0a8":"FBEE()","5107fde8":"lockedTeam()","510a3e2a":"round2Bonus()","510ae121":"Yangshuai(uint256,string,uint8,string)","510b1529":"issueTranche(uint256)","510bf040":"launchVesting()","510c27ad":"getOracleList()","510c58c9":"Gig9()","510c8243":"CategoryDeleted(uint256)","510ccb43":"getRewards(address[])","510de15a":"ICOSaleExtended(uint256)","510e23eb":"invalidEarlyPurchaseIndexes(uint256)","510e4235":"_createForecast(uint256,uint256,uint256)","510ea296":"_createDiamond(string,address,string,string,string,string)","510ec598":"computeCurrentReward(address,address)","510ef1ce":"changeQuarterSeason(int8)","510ef1de":"setTokenMetadata(uint256,string)","510f44cb":"TestFactoryUser()","510fbf8d":"setValue(address,string)","511075a9":"getIpfsForAssets(uint256[])","5110d31c":"TradeEthShop(address,uint256)","5111249e":"checkMultOverflow(uint256,uint256)","51114b24":"interSendWithOtherEvent(address,uint256)","51118f1d":"transferFromSystem(address,address,uint256)","5112f02c":"getCard()","51131017":"setUpdateGasCost(uint256)","511354a1":"phase2MaxTokenForSale()","5113d5f7":"BTCETC(uint256)","51142cc3":"secondStageCap()","5114a9aa":"TheBestICO()","5114cb52":"makePayment(uint256)","51172285":"TwoAfrica(uint256,string,string)","51175e01":"setNumRewardsAvailableForAddresses(uint256[],address[])","51180c63":"removeValue(bytes32)","51192814":"GenesisBuyPrice(address,address)","51193bad":"LUVTOKEN()","5119a342":"GetUserInfo()","511aae8b":"addFreelancerContract(address,address,uint256)","511acd53":"TOKEN_RATE_30_PERCENT_BONUS()","511b1df9":"addr(string)","511b445b":"nowperiod()","511bb41c":"rebateTwoFenmu_()","511bc0f6":"_addOwner(address)","511c5d66":"SetAddressForReturn(address)","511d2299":"processBNBContribution()","511e2613":"getoddAndEvenBets(uint256,uint256)","511e5639":"KamuToken()","511e84ce":"setIsAutoRestart(bool)","511eb8da":"confirmOrder(address,address,address,address,bytes32)","511fa487":"getMinSell(address)","5120429c":"TokenSold(uint256,uint256)","51206d81":"getRefWallet()","5120bb20":"transactionsOn()","5120f028":"sendAmount(uint256,address)","512202d7":"getOuvidoriaEndpoint(int256,address)","51223fdc":"LogClaim(uint256,address,uint256)","512267b0":"rewardScarcityFactor()","51228c4e":"addReferralProfit(address,address,uint256)","5122c6d1":"onSell(bytes32,uint256,address,uint256,address,uint256,address,address,uint256,uint256,uint256)","512392cc":"BITCOIMINIG()","51239fde":"multiDistribute(address[])","5123e1fa":"etch(address[])","51243676":"LogBookTicket(uint256,address,string)","5124ae95":"getNonces(address)","51252412":"crowdsaleTargetBRA()","51254729":"CynkciarzToken()","512570d6":"updateBrand(address,string,bool)","5125796a":"changeOraclizeProofType(bytes1)","51259770":"GetEthShop(address)","51274842":"logEvent(uint256,string,uint256,uint16,address,uint256,uint256)","5127a94a":"getRaisedAmount(string)","5127cab5":"rateFirstRound()","5128ab7b":"GetSaleInfo_Airdrop(uint8)","5129096c":"INGCL()","51290d06":"cofounderB()","51297cc6":"airDropTokenEnabled()","512a9c33":"startCrowdsale(string,string,uint8,uint256,uint256,uint256,uint256,uint256,uint256,address,string)","512b64c6":"_productDoesNotExist(uint256)","512b658d":"mintToAddress(uint256,address)","512c0b9c":"randomDS_updateSessionPubKeysHash(bytes32[])","512d62df":"getClass(uint256)","512d8a87":"EdwanzToken()","512dd020":"getItemsCount()","512f1e64":"orderBookLength()","512f8f92":"changeLottery(address)","512f9890":"airDropFinished()","512fcd60":"changeOwner3(address)","512ff2c9":"CHEXToken(address,address,uint256,uint256)","51306a80":"_isVotable(bytes32)","5130b405":"setMinimumBidAmount(uint256)","5130c857":"forking()","5131d3e9":"setUseFreeze(bool)","5131f01d":"available_shares()","51327a6a":"emptyToWallet()","513284c6":"createShop(address)","5132faca":"stakeTokenContract()","51331732":"ICO_start()","51331ad7":"getRoleManager()","513419e3":"updateStartTimeManually(uint256,uint256)","513485fc":"CallRejected(address,bytes32)","51349d5f":"scheduleTier(uint256,uint256)","5135077b":"setContentName(string)","51355362":"transferWithFee(address,uint256,uint256)","51355cfb":"getTier(uint256,uint256)","51356817":"doPull(address,uint256)","5135d28d":"getScore(uint256,uint256,uint256[])","5135dffa":"NonActivationWithdrawal(address[2],uint256[8],uint256)","5135f714":"Basic(address)","5136099c":"premium(bool,address,address,address,address[],uint256[])","513611e5":"setStatusTransferFrom(bool)","5136260d":"getLockedFundsReleaseTime()","51379adb":"Crowdsale(address[],uint256,uint256)","5137aa7b":"reveal(bytes32,uint256,bytes32)","5137dd99":"only666()","5137de7a":"privateReleaseTime()","5138574b":"setNextCommonTTMTokenId3(uint64)","51392041":"getDividendTokenBalanceOf(address)","513a0149":"setRocCoreAddress(address)","513a976e":"YaqootToken()","513ad9cb":"EvTokenRm(uint256,uint256,uint256)","513cb145":"convertToUSD(uint256,uint256)","513d085b":"Pandemica()","513d16a7":"setFundingStartTime(uint256)","513de1d3":"changeDivisor(uint256)","513f7d1e":"tokenValue(address)","513f99e7":"tokenFrozen(uint256)","513fdce9":"addClearingPriceValidator(address)","51401d4d":"gameMaxBetAmount()","51404cbe":"forceDivestOfOneInvestor(address)","51409f51":"currentTradingSystem()","5142ba74":"rolloverFeePeriod()","5142bc1e":"getAllowedRangeOfChoices()","5142c3ec":"assertEq13(bytes13,bytes13)","51430cb3":"claimMaxAmount()","51431800":"getSendableEther()","5143284d":"start4NormalPeriod()","5143659d":"claimCooldowns()","51436641":"convertToMiniCQS(uint256)","5143821e":"_moveToArea(uint16,address)","514385be":"disableConnectorPurchases(address,bool)","5143a9fe":"deposit(address,uint256,address,bytes)","5143e246":"mintLocked(address,uint256)","5143eea2":"addOwnerFromRecovery(address,address)","514403b3":"setnodemoney(address,uint256)","5144417c":"news()","51446e85":"CITRUX()","51464905":"updateGoldInvestor(address)","5146585a":"calcInterestRateNumerator(uint256)","5146690e":"reservesWallet()","5147af92":"buyGasLimit()","51489551":"getToken(bool)","5148ccb9":"DynamicCeiling(address,address)","5148de8d":"minimumTimeBeforeUpdate()","5149ffcb":"calculateSubmissionIndex(uint256)","514a48ae":"_changeApproveDate(uint256)","514a88ae":"revokeSchedule(address,address,address,address)","514ae8a6":"MagneticsToken(uint256)","514b13f2":"presaleConversionRate()","514d6e07":"horseShoeFS(uint256)","514d7067":"workOrderCallback(address,string,string,string)","514d717c":"developReserveWallet()","514dcfe3":"seller_accept()","514ec8ae":"TOKEN_CENTS()","514f0330":"changeProtocolFeeRecipient(address)","514f310f":"_NewChallenge(address,bytes32,uint256)","514fcac7":"cancelOrder(uint256)","515053c6":"depositBond(address,uint256)","5150e8ce":"CPPGToken()","515134b3":"TianZhuCoin()","5151e2cc":"GREENBIT()","5152249c":"Paladin(uint256,string,string)","51524e5b":"AirDrop(address[],uint256[])","5152abf9":"OrderCancelled(bytes32)","515361f6":"assertEq(address,address)","515371a3":"getWinnerAddress(uint256)","5154865a":"crowdFundAddress()","51548a2d":"TOKEN_AMOUNT_ICO_STAGE2()","5155287a":"whitelistedMin(address)","51553205":"PreSale(address)","5155bafa":"maxPeriods()","5155d9c6":"getPetCardSeries(uint8)","51560da9":"topDogInfo()","51563527":"passDao()","51576510":"bountiesWallet()","51582ef3":"sendProxyTransaction(address,uint256,uint256,bytes)","51584916":"allowexternalContract(address,uint256,bool)","5158c829":"RECFCO(address,address)","5158ea5e":"disallowUsers(address,address[])","51593759":"carCountOf(address)","515a20ba":"setExpiration(uint256)","515b1e41":"zss()","515b3557":"STARTING_CROCS()","515c1457":"emitTransfer(address,address,bytes32,uint256,string)","515cbcb4":"dropCoinsMulti(address[],uint256[])","515ced53":"best_submission_index()","515d4503":"getBarCodeDataAtIndex(bytes32,uint256)","515d4d52":"totalAmountsBet(uint256)","515da4b9":"transactionList()","515f128b":"COMMUNITY_POOL_TOKENS()","515f25ae":"launchShipOnMEA(uint256,uint8)","515fdde3":"migrateFunds(address,address[])","51602590":"threeHotHoursPriceOfTokenInWei()","51605d80":"imageHash()","5160a21e":"AddDomainInfoDocument(string,string)","51613683":"crowdSaleStart()","5162b2b2":"isAddressWhitelist(address,address)","5163311e":"getLastWinnerTicket()","51640fee":"getCertificate(uint256)","5164bb4d":"getCurrentStinkyLinkys()","51651003":"redenom_dao_fund()","516517ab":"make(uint256)","51656af5":"GuigsTokenSale(uint256,uint256,uint256,uint256,address,address,address,uint256)","51656f08":"AgesToken()","5165749e":"createToken(string,string,uint8,uint256,address)","516583fe":"depositFrom(uint256)","5165a03d":"payout(uint256,bytes32,bytes32,uint8)","5166b68f":"unfreezeTransfersUntil(string)","5166cf3d":"canAttack(address,address)","5168afa4":"getPackageHash(bytes,uint8,uint8,uint8)","5169ed0e":"getCCH_edit_29()","516a6b22":"PingoToken()","516ae993":"setChargeFee(uint256)","516af259":"setCurrentStage()","516b48fb":"insertList1(uint256,string,string,string,string,string)","516c731c":"setOwner(address,bool)","516cbe1a":"efwtest()","516cd39b":"revokePermissionFrom(address)","516d70c3":"lockAllocationAddress(address)","516dde43":"expiryDate()","516de876":"go(bytes16)","516e7be7":"contractFailed()","516e9aec":"lockAndDraw(address,uint256)","516ed622":"registerDINs(uint256)","516edc99":"UNITYCOIN()","516f279e":"location()","516f6afd":"Project_Enable(uint256)","516f8986":"TOKENADDRESS()","5170a9d0":"returnSender()","517125fa":"minTokensForSale()","51714d2d":"CIRCLECOIN()","517186f3":"ownerModOperator(address,bool,uint256)","5171bdec":"AllocationProcessed(address,address,uint256)","51720b41":"targetContractId()","51731f21":"changeFreezeTrading(bool)","51751612":"EtchToken()","51758666":"getMesa(uint256)","5175f65c":"_ownerApproved(address,uint256)","51764a94":"Lesson_3(address,uint256)","51768e4d":"updateItem(uint256,string,uint256,uint256,uint256)","51777183":"private_setRandomAPI_extract(string)","5177942a":"setFeeRate(uint8)","51780fdb":"w(address,address,uint256)","51784a75":"withdrawPlat()","517880df":"secondaryICO(bool)","51788439":"hashRequest(address,address,uint256,uint256,address)","517a626f":"getUserLengthOnEther()","517a70d4":"mintAmount3()","517a9d64":"share(address,address)","517afbcf":"votingController()","517b1d8f":"setRegionCurrentPixelPrice(uint256,uint256)","517b2fa8":"depositDaiFor(uint256,address)","517c48c3":"LATPToken()","517c8b12":"GetTicketOwner()","517cf73e":"getSupplyRate(address,uint256,uint256)","517d95fa":"addusermoney(address,uint256)","517e62ab":"getTxTimestampPaymentKWh(bytes32)","517ebace":"eosOf(address)","517ee2e8":"CSLottery()","517ee30d":"CreateHOLY(address,uint256)","517f4a23":"SalesManager()","517f6c51":"HardcodedCrowdsale(uint256,uint256,uint256,uint256,address)","517fe4de":"showUser(address)","51804743":"LandAccessControl(address)","5180629d":"transferByOwnerContract(address,uint256)","5181500d":"ExoplanetToken()","51819edb":"emergencyWithdrawParsecs(uint256)","5181aa01":"RELEASE_END()","51838717":"addSmartContract(address)","51843b06":"supporterBalances(address)","51846028":"setColorsX8(uint16[8],uint256[40],uint256)","518496b2":"proposedWithdrawal()","5184c96d":"escrowList()","5184cc43":"getFactor()","5184ffc9":"setAmbiAddress(address,bytes)","51858e27":"emergencyPause()","5185b724":"allocateReservedTokens(address,uint256)","51867b19":"withdrawnFrom(address)","5187527f":"reversePurchase(address)","5187a7d7":"GetSign(string,address)","51883f6e":"RecievedAnonDonation(address,uint256)","5188875b":"withdrawalToken()","51888969":"weiRaisedPreIco()","5188f996":"addContract(bytes32,address)","51892c0f":"BIGER(address)","51892f07":"changeMintingAddress(address)","518995cd":"addClip(string)","518ab2a8":"tokensSold()","518ada3b":"GetUserBets(address)","518adacd":"notifyAuthority(string,string)","518b1a33":"ALLOC_LIQUID_TEAM()","518b4372":"getInvoices(address,uint256)","518b7a29":"totalDETsSold()","518bddd9":"getCustomer(string)","518bed3f":"calculateTokensAmount(uint256)","518c0f17":"tokensOnThisChain()","518d3b64":"getTotalSent()","518d6c2d":"_preApprove(address)","518d7981":"adjustBalance(address,address,int256)","518e62db":"createOrder(address,address,uint256,uint256,uint256)","518fd40e":"cdtTokenAddress()","5190674b":"resignAsCurator(address)","51906bb0":"endTimeStamp()","51913124":"batchTransferMSM(address[],uint256[])","5191e37f":"listMultipleItems(uint256[],uint256,uint8)","51922341":"transferICOFundingToWallet(uint256)","5192f3c0":"boolToInt(bool)","519559ed":"contractMax()","5195e8c5":"mintData()","51965e75":"getRocrocId(uint256)","51971109":"UntungWaluyo()","51973391":"sentBonus()","51973ec9":"log()","5197c7aa":"getX()","519903f1":"unionBalance()","51992fcb":"addTokenAddress(address)","519936db":"StartAuction(string,uint256,uint256)","5199f1de":"lastYearTotalSupply()","519a078f":"getCommunitybyIndex(uint256)","519a1a41":"getSetup(address,bytes32)","519a73c3":"stopAcceptingDonation()","519af30e":"withdrawAllEth()","519be2f5":"resetDemo()","519bf602":"reward8()","519c6377":"signup(string)","519d1059":"setPurchased(address,address,uint256,uint256)","519e55da":"getStorage(string)","519e9a92":"Log2(address,bytes32,uint256,string,string,string,uint256,bytes1)","519ee19e":"tokenSold()","519f9590":"appointNewCFO(address)","51a073fb":"removeFromSpecialRatesMapping(address,address)","51a0aff0":"stockBuyOrder(uint256,uint256,uint256)","51a0c395":"myUsingOraclize()","51a11e94":"tokenIssued()","51a14c9f":"GetPartWeight(uint8,uint256)","51a1ad6b":"VikkyTokenAirdrop(address,address)","51a1c192":"get_solution()","51a282ae":"bidEMONTIncrement()","51a28572":"SALE0_RATE()","51a36e34":"changeCrowdfundContract(address)","51a3aed5":"getCompanyPreferences(string)","51a4cd73":"sellCoins(uint256)","51a4f7f2":"Har(address,address,address,uint256,uint256,uint256)","51a5f2f2":"ConsultingHalf(address,address)","51a6b851":"actual_feedout()","51a76924":"getSpeed(uint64,uint64)","51a784e3":"currentCirculating()","51a88a38":"PictureLibraryCoin(uint256)","51a8c3d7":"PausableCrowdsale(bool)","51a9111a":"BONUS_PRE_ICO()","51aa0199":"ethereumPrice()","51aa0a30":"modifyPMTAccount(address)","51aadcdf":"crowdSaleContract()","51ab351c":"BONUSONE_DATE()","51ab720d":"numOfTimesSteal()","51ac0d10":"getTimeBasedBonusRate()","51ad0299":"Ship(string,uint256)","51ae7f95":"COMPANY_TOKENS_LOCK_PERIOD()","51ae8754":"calcSectionTickets(uint256[],uint256[])","51af083b":"MONTH_IN_MINUTES()","51afc4af":"_getMinAuctionSeconds()","51b07a96":"getUSDT(uint256)","51b0b931":"updataLockPercent()","51b2270f":"getICOLength()","51b30900":"generateMemoryProof(uint256[],uint256)","51b3666f":"applyBooster(uint256,uint256)","51b3d7b9":"_transferWithReference(address,uint256,string)","51b41b62":"getAllOwnersOfCard(address)","51b42b00":"deactivate()","51b46399":"triggerUnpauseEvent()","51b488d4":"throwsWhenGettingTokensInNotInitiatedSale()","51b546af":"EDCoreVersion1(address,address,address,address)","51b59341":"MoncryptToken()","51b644c0":"roundedDiv(uint256,uint256)","51b6914a":"Lara(uint256)","51b699cd":"isAuthorised(address)","51b6fe96":"distributeTokens(address,address[],uint256[])","51b72a9a":"removeActivator(address)","51b79495":"performFeelessTransaction(address,address,bytes,uint256,bytes)","51b79d55":"maxPremium()","51b95400":"SophosToken()","51b98927":"_withdrawProfit()","51b9a2f8":"ballotVoters(uint32,address)","51b9c785":"step_level()","51ba24c7":"Token_ExchangeValue()","51ba5f04":"registerImpact(string,uint256,uint256)","51ba7534":"LastExec()","51babf0c":"sellToken(address,uint256,uint256,bool)","51bba1cc":"itemTransferred(bytes32,uint256,address,address)","51bcc53e":"checkFloatingOwnSupply(address,uint256,bool,uint256)","51bdd585":"currentChallenge()","51bdf229":"DummyContract(uint256,uint256,uint256[10])","51be2361":"InterCrypto_Wallet()","51c03b85":"makeBid(uint16)","51c08f4d":"gameTimeOut()","51c13af3":"MAX_ALLOWED_BOUNTY()","51c15991":"endGamblingParty(uint256,int256,int256)","51c1ae00":"DGClubCoin()","51c1bba1":"offlineGame(address)","51c221ec":"holderReserveTokens()","51c3934f":"getContractsByStatus(address,uint256,uint8)","51c3a2c6":"CPCEFundDeposit()","51c3a5d3":"getPollsSize()","51c3b8a6":"setFreezing(address,uint256,uint256,uint8)","51c40c6f":"setIntrospectionRegistry(address)","51c4e395":"logMarketCreatedCalled()","51c54c68":"buySprite(uint256)","51c54ec6":"transferAllBalance(address)","51c5d54d":"rateSecondWeekEnd()","51c65298":"exportFund()","51c69b12":"twoMonthsLater()","51c72c87":"ProofTeamVote(address)","51c74a9e":"addCertificate(bytes,bytes,bytes,address)","51c81f01":"setBursar(address)","51c85565":"nextTournamentBank()","51c875d2":"DB()","51c8d4d0":"get_arbits_whitelist(address,address)","51c8e02a":"setStore(int256)","51c9b233":"changepublicbonus(uint256)","51ca0eb8":"FACTOR_PRESALE()","51ca6966":"RefundableCrowdsale()","51ca7a94":"addNodes(string,address)","51cb21ff":"getgamecardname(uint256)","51cb6ecd":"addRandomFight2Death(uint256)","51cb860a":"setAccountNote(string)","51cb9712":"newExpertise(uint256,uint256)","51cc391d":"MULTI_SIG()","51cc4d1d":"payDemurrage(address,address)","51cc508d":"Zeinun()","51cc7cbe":"PawCoin()","51cd7c0f":"MatchPayoff(uint256,uint256,uint256,uint256)","51ce3207":"getStockOwnerInfo(address,address)","51cf6b22":"burnInvestorTokens(address,address,uint256)","51cfa44b":"getStarTotalSupply(uint8)","51cfc731":"transferFromContract(address[],uint256[])","51cfdd58":"Dewcoin()","51cff8d9":"withdraw(address)","51d10161":"boughtToday(address)","51d20c7c":"Exchange_ETH2LuToken(uint256)","51d24a33":"addNewBoard(bytes32,string)","51d28a7e":"saleTokenPrice()","51d2a8fe":"BIKSPRO(uint256,string,uint8,string)","51d2cc8f":"grid(uint256)","51d31822":"setMarketAddr(address)","51d34040":"returnBet(bytes32)","51d38d5f":"addDeveloper(address,string)","51d467f5":"getLogFillArguments()","51d53bee":"HRHToken(uint256,string,uint8,string)","51d550d2":"getPendingBalance(address)","51d59a20":"impl_incomeOf10k()","51d5d98d":"hasEnoughTokensLeft(uint256)","51d5f44f":"saleHero(uint256)","51d6e547":"getNonce(bytes)","51d74ce5":"SetWageredWei(bytes32,uint256)","51d75dc6":"BUYER_STEP_2(bytes32)","51d962e1":"endRelease()","51d977a6":"TEST()","51d997b2":"isAbstainAllow()","51dabd45":"disapproveAll(address)","51dbc419":"_drainGame(bytes32,address,uint256[10])","51dc7659":"winNum()","51dc7f7d":"setPreferredCurrency(address,bytes4)","51dd3164":"getCurrentMinimum()","51dd8119":"announceFork(string,string,uint256)","51de097f":"e_Withdraw(uint256,uint256,uint256)","51de5541":"castUpgradeVote(uint8,address,bool)","51dea0ae":"updateOwnerShares(address[],uint256[])","51ded741":"rateThirdWeekEnd()","51df6d27":"GlobalLotteryToken()","51df9db9":"newPrice()","51dfc14d":"tokensOfferedOf(address)","51e00935":"Arrays()","51e09631":"totalVestedTokens()","51e0e26b":"allowedContracts(address)","51e10aa6":"calculateToFund()","51e16546":"_payFee(uint128,address)","51e1d427":"boolMemoryArray()","51e1ee12":"ContractorProposalClosed(uint256,uint256,address,uint256)","51e22125":"addPresaleWhitelist(address,uint256)","51e4eb07":"setContributionLockPeriod(uint256)","51e51b55":"startPreSalePhase()","51e55767":"getWeiPerContributor(address)","51e699a8":"setMainSaleDates(uint256)","51e6edee":"RETZO()","51e7f12e":"_doDestroyTokens(address,uint256)","51e82eec":"totalSetCredit()","51e94406":"weiRaisedPreSale()","51e946d5":"freezeAddress(address)","51ea468b":"getSupportersAddress()","51eace10":"unfreezeStartTime()","51eb5e93":"overdraftPeriodLength()","51ebe2f1":"bursarAddress()","51ec4285":"unvote(uint256)","51ec4525":"first_player()","51ec4fc7":"limitAddress(address)","51ec8433":"STTadmin2()","51ecfd16":"getCatPrice(uint256)","51ed17a4":"reservedTokensList(address)","51ed8288":"buyNFT(uint256)","51ed96b9":"enableContribPeriod()","51edbdbb":"setForeignBridgeErcToErcImplementation(address)","51edffed":"identifierIsOriginal(uint256)","51ee387d":"dividendsAvailable(address)","51ee43e5":"lottery(int8)","51eec810":"setCapitalization(uint256)","51eecc23":"setupBounty(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","51f1333e":"relievePool(uint256)","51f1fa97":"POHStartTime()","51f2f1d1":"timeTransferbleUntil()","51f364d5":"currentCostToPress()","51f3a7bd":"CoinFlip()","51f3b4bd":"collectFees(uint256,address)","51f468c0":"setClaimPrice(uint256)","51f4ec50":"setWriterId(bytes32,bytes32)","51f514d3":"computePayeeBalance(address,address,uint256)","51f550be":"IcoSupply()","51f59db2":"test_claimShares_emptyFeePool_notTranscoder()","51f68d80":"calculateLRCUnlockAmount(uint256,uint256)","51f6d8c6":"setBalances(address[],address,uint256[])","51f6f870":"createMicroModule(uint256)","51f80746":"DXBToken()","51f91066":"tag()","51f93215":"bond(bytes32,uint256)","51f96d33":"verifySignature(address,address,address,uint8,bytes32,bytes32)","51f9ff35":"lastDividendIncreaseDate()","51fa5810":"getEnginesIds()","51fa7efd":"returnAmountToMainAccount(uint256)","51fab7ff":"transferRemaining()","51fae45d":"astroIDPool()","51fafb72":"setSubscribe()","51fafd95":"cashierAddr()","51fb012d":"whitelistEnabled()","51fb3043":"tokensForPresale2()","51fb4001":"rateIcoMainSale()","51fba575":"NRB_Users()","51fbd91e":"donationsReceiver_()","51fbfe9d":"migrationCountComplete()","51fc6f59":"TokenManagerEntity()","51fd2c69":"quantityHeldInCustodyOfExchange(address)","51fdaf92":"checkExpiredfunds()","51ff1a06":"PaparazzoToken()","51ff4847":"signature()","51ffcab3":"bid(uint32)","51ffd9e7":"getRatePerTimeUnits(uint256,uint256)","52006050":"setBurnBounds(uint256,uint256)","5200d643":"OPENING_TIME()","52013484":"CalcWinnersAndReward(uint256[],uint256)","52019dc3":"payTokens()","5201effb":"setCompletionTime(uint256)","520282d0":"getBcouponAllocationFactor()","5202b615":"numberOfClosedGames()","52030899":"preSaleBlockNumber()","5204cfe1":"OpenRedEnvelope(string)","520543ab":"endStage2()","52058d8a":"tokenSupplyCap()","5205b80f":"getLeftToken()","52063985":"unlockAddr()","5206fea3":"_transfer(string,string,uint256)","5207c391":"setWhitelistedBatch(address[],uint256)","5208a157":"getCardsFromHash(uint256,uint256,uint256)","5208ce36":"STQPreICOTestHelper(address,address)","52091047":"changeVotingRules(address,uint256,uint256)","520929b6":"AlgeriaToken()","520aea97":"setNote(uint256,bytes32,bytes20,string)","520b1b65":"testGetAllCases()","520ba154":"changeAcct2(address)","520bbba3":"generateRequestAttestationSchemaHash(address,address,address,bytes32,uint256[],bytes32)","520bf4d8":"SmallInts()","520c37b7":"setOCGFee(address)","520c3db7":"relayRelease(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32)","520c5828":"whitelisting()","520c7c8c":"bountiesAllocation()","520c7d6f":"PAYOUT_ATTEMPT_INTERVAL()","520ce36a":"Permian()","520ce39e":"DamnRocks()","520e12d7":"getCertAddressByID(string)","520e7b0e":"offer_energy(uint32,uint32,uint64,uint64)","520e8143":"returnTokenToWallet()","520eb620":"getTemplateByProposal(address,uint8)","520ee757":"NewSandwichTicket(string,address,string,string)","520fa2c1":"BetleyToken()","520fd799":"Nplay()","52108d4c":"setCCH_edit_30(string)","5210eb56":"targetAddress()","5211ac2e":"withdrawWei()","5211e91e":"CSTToken()","5211f843":"bbNetworkGrowthWallet()","52122abf":"JackpotHits()","52125b86":"eventcount()","5212e6ea":"firstExtendedBonusSalesEnds()","5213cca8":"AdvisorPoolAddress()","52146744":"AteamBets(uint256)","52159bcf":"CreateCityData(address,uint256,uint256)","5215ad0b":"batchTransfer(address,address[],uint256)","5215cb88":"onPresaleComplete()","5216509a":"numCandidates()","5216aeec":"totalInvested()","5217b774":"redeem_withdraw(address,address,uint256)","5217cdff":"greyToken()","52180208":"take(address,uint256)","52185f0e":"isWithinAllocation(address,uint256)","5218bfbb":"getOffer(bytes32,address)","5218c37d":"bulkRejectTransfers(uint256[],uint256[])","5218f3b3":"CoinStocker()","52194acf":"addBank(address,address,uint256)","52196812":"getLoanCount()","5219823a":"hashMessage(bytes)","52199094":"setBurningPercentage(uint256)","5219a72a":"mcgregortoken()","5219ffb8":"withdraw_tokens_for(address)","521af962":"DataBrokerDaoToken(address)","521b20ec":"highestBidAddress()","521b601a":"setData_26(string)","521b7499":"setStageVolumeBonuses(uint256,uint256[],uint8[])","521be69c":"applyTokens(address,uint256)","521c82be":"getCCH_edit_17()","521cd656":"playersAmounts(address)","521ceba7":"pusherTracker_()","521d56c6":"regeneration()","521d80f8":"fundsTransfered()","521e5770":"fechCurrentSnapshotBlockIndex()","521eb273":"wallet()","521ec3af":"MGLTToken()","521ee1ae":"purchaseFor(address,address)","521f4195":"isOwn(address,uint64)","521fba45":"setTokenInfo(string,address,address)","521fba71":"getRandom256()","521fbd3a":"deploytime()","521fd5be":"getSingleBet(uint32,uint32)","52200a13":"getNumHolders(uint256)","522103fa":"changeUnicorn(uint256,address)","5222cd8a":"Deal(bool,uint8)","5223478a":"setIsPoop(bool)","52238fdd":"calculateFees(uint256)","522471fc":"setTotalWithdraw(uint256,address,uint256,address,bytes,bytes)","5224dfbe":"mainTokensPerDollar()","52251884":"setForwardPurchaseFeesTo(address)","52253542":"playSingleDiceBet(uint256,uint256)","5225528e":"getBadAddresses()","522567c8":"transferedTokenOf(address)","52256d44":"MuratCoin()","522577e9":"totalIncome()","522637e7":"CMCLToken(uint256,string,string,address)","52279295":"interestRatePerCycle()","52288195":"Sell(uint256)","5229c56f":"getDecreaseAllowancePreSignedHash(address,address,uint256,uint256,uint256)","522a6cf3":"computeMilkSellPrice()","522afaec":"increase(address,uint256)","522bb704":"run(address)","522c8401":"bidOnSiring(uint256,uint256,uint256)","522dba5b":"GoldTokenMinter()","522dc0b1":"walletsFromUser()","522dd549":"advisor3Sum()","522de7d3":"verifySubmissionIndex(uint256,uint256,uint256)","522e1177":"complete()","522e2d3c":"BiathlonToken(address,address,string,string,uint256,address)","522e35fb":"changeIssueManager(address)","522e4c8a":"addStaff(address)","522f6815":"withdrawEther(address,uint256)","522f9585":"setNewWallet2(address)","52306f4a":"isCBE(address)","52314508":"registerOutcome(string,uint256)","5232d457":"PayoutEvent(uint256,address,uint256)","52337ab0":"interact()","52346412":"transfers(address[],uint256[])","52353e5b":"assetsOnDeposit()","52357779":"currentRId_()","523615aa":"AddApprovedAddress(address,address)","52374af1":"bitPremiumToken()","52375093":"m_lastDay()","5237d235":"getRightToken()","5237e325":"getAdIdByCat(uint256,uint256)","52380eba":"entitled()","52380f65":"MoneyAddedForRefund(address,uint256,uint256)","52388c1b":"AndreisToken()","523898f4":"cooperativeClose(address,uint8,uint256,bytes,bytes)","523934bb":"registerExport(bytes8,bytes8,uint256)","52393d45":"SGDT()","523a0b0d":"privateMaxEtherCap()","523a3f08":"withdrawReward(uint256)","523ad959":"bullAmount()","523aee69":"changeTokenContract(address)","523afb0d":"bet(bool)","523b6ae3":"MycoinToken(address,address)","523c02f5":"getRateForExternal(string)","523ccfa8":"isKnownCall(address)","523d897e":"wsub(uint128,uint128)","523da442":"getCurrentBonusTier()","523deadb":"getOwner(address,address)","523e27d4":"currentInvestor()","523e57be":"mintForHolders(address[],uint256[])","523e9551":"increaseCap(uint256)","523f110e":"updateRegion(address[16],uint256,uint256,uint256[],bool,bool,uint8[128],bool,address)","523f52c6":"setTgeIssuer(address)","523f53a6":"IntigoTest()","523f891c":"totalEligibleVotes()","523fba7f":"tokenBalances(address)","5240346d":"TV()","52405f56":"getMilestoneInformation(uint256)","52411891":"add(uint256[2])","52415840":"testMe()","5241590d":"addToAddressBalancesInfo(address,uint256)","52416347":"ParameterSet(string,string)","5241b39d":"renewal()","52437187":"callLib(uint256)","5244128a":"_claimableTokens(address)","52441d7d":"getCurrentUserShareBonus()","52447ad2":"doMint(int256,uint256)","52447d92":"burn_from(address,address,uint256)","5244d9a8":"removeIdentifier(bytes32)","5244ed87":"joinToTrack(uint256)","524559a3":"periodPreICO()","5245849e":"allowedAmountToTransferToPool()","5246a8df":"verifySig(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,uint256,address,bytes,address,address)","52476ceb":"shareTimeGap()","524773ce":"burnCount()","5247b9e9":"firstMintRound0For(address[],uint256[],bool[])","5248f2c8":"removeBankroll()","52494a14":"_isOwner()","5249be25":"tokenPriceUsd()","524a2ed9":"setBAUU(bytes32,address,uint256,uint256)","524a8131":"STARTING_ASSET_BASE()","524aa413":"ValidateWorldSnapshot(uint256)","524aae98":"getPromoLOTEarnt(uint256)","524b5cb9":"approveMintDelegate(address,int256)","524bd747":"getNbDemandes()","524d5ddb":"wagerPool5()","524d7daf":"verifyGame(uint256)","524d81d3":"numContracts()","524dcda3":"MINT_LOCK_DURATION_IN_WEEKS()","524e1149":"joinCreateGame()","524e2444":"setPI_edit_32(string)","524e4e61":"testDistribution()","524e65b9":"_getWinnerBetted(uint32,uint32)","524e915d":"player4Timestamp()","524eb29c":"setRequestBurnerContract(address)","524ee639":"setSpaceImpulse(address)","524f3889":"getPrice(string)","524fa7b9":"whitelistAdd(address)","52507790":"transferAfterDeadline()","52512599":"latpToken()","5251a343":"stopPurchaseTokens()","52529852":"W0kiT0ken()","5252cb2f":"generateUnsoldTokens(uint256)","525417f1":"getNextKeyTime()","52541b68":"takeAGuess(uint8)","525426fd":"increaseUSDRaised(uint256)","52545021":"AkshayToken(uint256,string,string)","52548946":"isSimple()","5254a38c":"onERC721Received(uint256,address,bytes)","5254b595":"TransferIndex()","5254b660":"canDeCompose(string)","5254c846":"getAction(uint8)","525550ea":"rescueAddress()","52556421":"getIssuer()","52556a46":"State(address[])","52558c2b":"CSPTToken()","5255a07b":"HeroTokenAuction(uint256)","5256a36e":"MAX_ICO_GOAL()","5256fcaf":"_giveRNG(uint256,uint256)","52573529":"setupPeg(address,address)","52578012":"createService(string)","5257c2b3":"soldTokenInPresale()","5257c508":"ico1Cap()","5257c825":"registerNameXIDFromDapp(address,bytes32,uint256,bool,uint8)","5257cd90":"randomNumbers(uint256)","5259347d":"default_helper()","52595c0d":"getOraFee()","5259fcb4":"centsRaised()","525a0ac8":"Claim(address,uint256,bool,string)","525a8cf0":"add_product(uint256,uint256,string,string,string,string,string)","525b25b1":"getDeploymentReward()","525b3fe3":"presaleLimit()","525c3966":"GMCB()","525d0537":"getWinnerFunds(uint256[])","525f8a5c":"setSaleStartTime(uint256)","525ffb7c":"ownersPayed()","52608d85":"rateEth()","5260de57":"numberOfTokensPerUser()","52613423":"OLOVE(uint256,string,string)","52617234":"changeSalePeriod(uint256,uint256)","5261ee83":"amountOfOwners()","5262c873":"calcGain()","52631ab4":"lastNonce()","52638d75":"create(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","5263ba87":"getLatestPatchTree(bytes32,uint32,uint32)","5263dbf3":"RooToken()","52642070":"DinarETHCrypto()","526441bb":"ExecutionFailure(uint256)","5264ff53":"test_forAgainst()","5265440c":"checkIsAttached(uint256)","5265565e":"_ecosysSupply()","5265a078":"getMemoryWordsLog2()","5265db80":"setPriceRatePhase1(uint256)","526606c9":"addFreezer(address)","52666403":"lockRewardToken(address)","5266cc7b":"init(address,uint256[],uint256,uint256,uint256,uint256,uint8,string,string,uint8,bool)","52675be3":"getElectionName(uint256)","5267bd0c":"allowedRefund()","5267e681":"Tokens_Per_Dollar_Numerator()","526825af":"updateFcontracts(uint256)","526938f8":"left35(uint256)","5269660c":"createInvestment(uint8[])","526a6b48":"transferTo(address,uint256,bytes,bytes)","526a99c8":"getJackpotLoseSide(address,address)","526aadc2":"mintBaseLockedTokens(address,uint256,uint256,uint256)","526b71f4":"InvestboxToken()","526b8462":"getPersiansOnTheBattlefield(address)","526b91d1":"transferSysAdmin(address)","526ba9fa":"TSB()","526bc7fa":"getGenCode()","526cb803":"getAllOfferingProposals(address)","526de5ea":"addChunk2ToWhiteList()","526e4d79":"requestRemainingTokens()","526e7f3a":"AWD()","526f652d":"propertyIdToOwner(uint256)","526ff1f0":"TLB()","52700ef0":"_changeClosingTime()","52704644":"transferFromInternalstaffdisbursementfund(address,uint256)","52709725":"owner2()","5270aa7d":"EtherGoToken()","5270d70d":"readBytes32s(bytes32[])","5271027b":"rentFlatDaily(uint256)","5271309f":"migrationInfoSetter()","52736814":"dutchAuctionToBuy()","52748cfe":"addDataResponseToOrder(address,address,address,string,bytes)","52753640":"registerXRateProvider(address)","52757292":"getEventSecond(uint256)","527596bf":"getDeployedChildContracts()","5276b91c":"BlackHToken()","52772264":"Contract(bytes32)","52774565":"getMyLockedFunds()","527749a4":"add_bounty(uint256,bytes32)","5277fda5":"bookWithEth(uint256,uint256,bytes,string,uint256[],bytes32)","52782648":"emitSkillAreasSet(address,uint256)","527942ac":"secondWeekPreICOBonusEstimate()","52798dae":"buyTicketByEarnings(uint256,uint256,string)","5279a5f8":"levelThreeTokenNum()","527aea0a":"getWeiBalance(address,address)","527ba1e1":"setIV_S(uint256)","527c08ec":"Max_CAP()","527d8f12":"ping(uint256,bool)","527f0900":"IncPrivateSupply(uint256)","527f4ff1":"setTransferAddressUser(address,address)","52802121":"depositEther(address)","528050a9":"salePreiodChanged(uint256)","5280b8ad":"getAmountBounus(uint256)","5280c3ee":"dealToken()","52810d5e":"UnitToken(uint256,string,string)","52812053":"outstandingQuarters()","5281947d":"cancelAdoptionOffer(bytes5)","5281bbe9":"contractExpirationTime()","5282f649":"risedUSD()","5283f339":"getAddress(address,string)","5283fd87":"giveReward(uint256[4],bool,uint32[4])","52848d8d":"kcck256strstr(string,string)","5284a4c7":"allocateReferalBonus(address)","5284b044":"Products()","5284e3d8":"RobotTradingIco(address)","5284e660":"_getEndOfLastMiningDay()","52855882":"confirmAddress(bytes16)","52860ea2":"ADDITIONAL_BONUS_DENOM()","528626fc":"updateNextStealTimeByOperator(uint32)","52879334":"requireNotZero(address)","52879ba6":"roleCheck(string,address,address)","5287ce12":"getDepositInfo(address)","52883fc6":"addTokenBalance(address,address,uint256)","52892478":"disburseAuthorizedPayment(uint256)","52892baf":"localConst()","52894449":"lastBlock_f17Hash_uint256()","528976de":"issueRefunds(address[])","528a683c":"keyExists(string,string)","528b5176":"zgetOtherContract()","528b8ed8":"MaxBusiness()","528ce7de":"withdrawByRndNo(uint256)","528d4156":"authorizedCreateTokens(address,uint256)","528d8797":"ModiTokenERC20(uint256,string,string)","528d9479":"FeeUpdated(uint256,uint256)","528eb417":"Demome()","528ebdd5":"noSales()","528eedcb":"sendSafe(address,address,uint256)","528ef5a1":"UNINAcoin()","528fa135":"changeStartTime(uint64)","528fd7b0":"manualPayExpiredDuel()","52909fc2":"dynamicExchangeChecks(bytes,uint256)","5290d773":"amountBurned()","52911bd8":"doesOwnEthHandle(bytes32,address)","52916687":"setAuditRegistrar(uint256,address)","52929a0c":"disable_throwing()","5292af1f":"sendBalance(address)","5292c1a9":"testThrowsRestartEnforceRevisions()","5292c8f1":"validContribution(address,address,uint256)","5293a436":"EscapeHatchCallerChanged(address)","5293f22f":"EOSRegistration(string)","5294157f":"sendWithAllOurGasExceptExt(address,uint256,uint256)","5294188b":"randomizerLottery(bytes32,address)","5294409f":"Mineable()","5294924d":"getMyLastFreeLotteryTimestamp()","5294bb2b":"unpayPooling()","5294d0e8":"tokensUnlockable(address,bytes32)","52954e5a":"makerTransferAsset(address,uint256)","52959d16":"ambiC()","5296085e":"callServer(address,uint256)","529865c9":"preBuy2()","5299ccc6":"isSubjectApproved()","529a7d6c":"BurnProposalAdded(uint256,address,uint256)","529ae0bf":"maxEthPerAddress()","529af369":"createAndSellAllAmountPayEth(address,address,address,address,uint256)","529b8e60":"ergebnis()","529d15cc":"sequence()","529d4800":"getLockedWalletGroup(address)","529db099":"viewAllControls(bool)","529dbdb5":"getMs(uint256)","529e65e1":"removeShopModerator(address)","529e6713":"setCustodyFactory(address)","529f0fb8":"setFee2(uint256)","52a00779":"bountyDelivered()","52a08c29":"jackpotPersent()","52a0b5ac":"registerBasket(address,address,string,string,address[],uint256[])","52a0cf38":"p2pUnlocker(address)","52a16bb0":"amountSold()","52a2695c":"isReachedGoal()","52a2720c":"extraTokensTransferred()","52a27baf":"read_user_daily_limit(address)","52a36938":"initDisabled()","52a554a1":"voteBoardProposal(uint256,address,bool)","52a5b002":"lastInterestCycle()","52a6f970":"ZHEY()","52a74b82":"getDebugNumber()","52a7cae5":"BitAlphaAirdrop(address[])","52a80129":"unlistQualifiedPartner(address)","52a82b65":"digest()","52a8aeab":"controller1()","52a8fe93":"kscBurnWhenUseInSidechain(address,uint256,string)","52a9039c":"allocations(address)","52a94adb":"TRMCrowdsale()","52a982d3":"distributeTokensRange(uint256,uint256)","52a9a35e":"retireAdmin(address)","52a9cd2d":"changeOwnerVault(address)","52aa2ae9":"enterPreSale()","52aadf3b":"generateLuckFactor(uint128)","52aaead8":"priceLastUpdated()","52ac3235":"amountOfQuotations()","52ac882c":"retirementManager()","52ad2aa8":"__getStore(uint256)","52ad4116":"getCrowdsaleStartAndEndTimes(address,bytes32)","52ad6468":"SHARE_FOUNDATION()","52ae68f6":"getRoundBonusPot(uint256)","52af1c04":"parseMessage(bytes)","52af719f":"initialize(uint256,address[],address)","52af89af":"getsum(uint256[])","52afbc33":"scheduleCall(address,bytes4,bytes32,uint256,uint8,uint256)","52b1e14a":"insertUser(address,string,uint256)","52b33d64":"clientmanagerShare()","52b4be89":"totalBuyCardNumber()","52b566e4":"CitiDynamicsCoin()","52b5e85c":"firstPhaseEndTime()","52b5ff39":"RBAC()","52b75219":"freezeToken(address,uint256,uint256)","52b7fddb":"createMechVRC(uint256,address)","52b860eb":"tokenBonusForFifth()","52baee20":"getAllHpbNodesByStageNum(uint256)","52bafbfa":"vestingBeneficiaryForIndex(address,uint256)","52bafde9":"playersSignedUp()","52bbde34":"BiddingRing(address,uint256)","52bca4c3":"phaseOneCap()","52bd6945":"sellReply(uint256,uint256,uint256)","52bd9914":"TimeEnd()","52bddee6":"uintCeil(uint256,uint256)","52bf74b3":"airDropCoin(uint256)","52c05ca5":"setWeiPerBlock(uint256)","52c0b9f7":"ICO_START3()","52c1c03a":"removeUnlockedAddress(address,address)","52c1d3d5":"ZenomeCrowdsale()","52c204d0":"ICOMeetupToken()","52c22a72":"cancelContract(address,address,uint256,string)","52c28fab":"add(address,address)","52c34e68":"getStandardRobot()","52c53cb7":"checkPoint(int256,uint8,int256,uint16)","52c5785b":"purchaseTokensPreSale(address)","52c5b4cc":"setAuthorizations(address,address[])","52c5d892":"withdrawOwnersFunds()","52c700ea":"crowdsaleStop()","52c743d2":"callDestination()","52c76b8e":"TokenGame(uint256)","52c76de9":"addDiscountPhase(string,uint8,uint256,uint256)","52c8df64":"getFund(uint256)","52c91d43":"getLinkedWETHAddress()","52c944b2":"removeFromTokenLocked(address[])","52c98e33":"checkClaim(address,uint256,uint256)","52c9b906":"founderTokenWithdrawnPhase1()","52cb2a7b":"calcTransfer(uint256)","52cb36cd":"_getUtTotal()","52cb7688":"suspendSale(bool)","52cbfe09":"summAirdrop()","52cc5fdc":"retrieveMyEth(string)","52cd972d":"PreSaleCloseTime()","52ceac34":"bytesToUint(bytes,int256,bytes)","52cf4078":"transfertWDiscount(address,uint256)","52cf46d4":"transferAllowed(address,uint256)","52cfd41f":"advisorFee()","52d005d6":"findNewExchangeContract()","52d08730":"DogeCoin()","52d0bf14":"setDataColla_AA_02(string,string)","52d214a7":"removeUnitMultipliers(address,uint256,uint256,uint256)","52d23633":"getNumDividends()","52d28a17":"muscFundDeposit()","52d2d83d":"setBoolValue(bytes32,bool)","52d35197":"JLL()","52d3592a":"VoteExecuted(uint256)","52d3642d":"sellToContract()","52d3a9dd":"rentAuctionContract()","52d472eb":"rewardPercentage()","52d4747f":"BurnTokensFrom(address,uint256)","52d48a95":"getXPub(address)","52d4e76c":"ControllerRetiredForever(address)","52d50408":"statusContribution()","52d5ad25":"currentRecords()","52d63b7e":"setNextSale(address)","52d6804d":"minimum()","52d714e8":"approveMintingManager(address)","52d7d861":"AddrChanged(bytes32,address)","52d850d1":"tstinx()","52d8bfc2":"recoverEther()","52dbb027":"newModelShipProduct()","52dc09a5":"test_4_assertGasUsage700Boards()","52dca247":"ttlInvestCount()","52dd336a":"_tokenAllocate(uint8)","52e021c2":"securityReg(address)","52e0d025":"maxUserPayment()","52e0d0fa":"BIPOOH_DAO_32_a()","52e11d12":"DanCoin()","52e1ea89":"setDonator(address)","52e2525f":"ownerSetFee(uint256)","52e2f9ea":"MerculetToken(uint256,uint8,string,string)","52e32a55":"bounty0xToken()","52e34245":"disputeTX(uint256)","52e3d369":"saleConversionRate()","52e40d96":"PPKToken()","52e43613":"approveToMint(uint256)","52e536ad":"icoLeftSupply()","52e578ad":"LOG_EmergencyAutoStop()","52e57d1f":"makeLogError(uint8,uint256,uint256)","52e60b90":"setTalentCardAddress(address)","52e686a0":"EnableReturnFunds()","52e68c46":"list_token_ask(address)","52e8f2c3":"deleteRecord(uint256,string,string,bytes32)","52e94beb":"setPrice(uint256,bool)","52e97326":"changeTotalSupply(uint256)","52ea5667":"getMPbyIndex(uint256)","52ea8a71":"setRandomApiKey(string)","52eae80b":"doProvideStateRoots(uint256,bytes32,bytes32[])","52eb2580":"Tethered(address,string,string,uint256,uint32,uint256,uint256,string)","52eb5751":"MedicoHealthContract()","52ec8a58":"mint_and_transfer(address,uint256)","52ece9be":"freezeAllowance(uint256)","52ecf7c4":"pickWinner(uint256,bool,bool,bool,bool,bool,bool)","52efd35f":"INCENT_FUND_VESTING()","52efea6e":"clear()","52effe11":"transferOwnershipTo(address)","52f17ce9":"pomda()","52f18042":"addAdditionalBonusMember(address)","52f1e07b":"ethRefundAmount(uint256)","52f1f48c":"setInv3(address)","52f29a25":"nextPunkIndexToAssign()","52f37c40":"isHodler(address)","52f445ca":"setAssociatedContract(address)","52f46769":"InitializedTier(uint256,uint256,uint256,uint256,uint256)","52f50db7":"initiate(uint256,bytes20,address,address,uint256)","52f59e0e":"AICH()","52f62195":"picops_enabled()","52f662bb":"sendTokensToInvestors(address)","52f6747a":"rules()","52f6ca76":"deadDragons()","52f6ee58":"exponent()","52f775c8":"ViewSecretBet(address)","52f7c988":"setFee(uint256,uint256)","52f804a8":"burnPollStake(address,bytes32)","52f84b1b":"BlangsakToken()","52f8a766":"TimeStampSubstructOneDay()","52f9058b":"getFreeRickAndMorty()","52f91acf":"triggerDispute()","52f97117":"createContract(bool,string)","52fa1ac2":"createUnicornForCandy()","52fa2650":"withdrawPercents(uint64)","52fa3712":"makeBet(address,uint256,bytes32)","52fb0561":"setWhitelistedTransferer(address,bool)","52fba25c":"attack(address,uint256)","52fbeb57":"transferToContractWithCustomFallback(address,uint256,bytes,string)","52fc01f9":"func_1(uint256,uint256)","52fd2c15":"ServiceStation()","52fdcc65":"GAME_SUPPLY()","52fdeef5":"_addToFundHWC(uint256)","52fe8163":"randomDS_sessionPubKeysHash()","52fea23c":"teamAllocator()","52fedceb":"getMarketComissionRatio()","52fedefa":"decrementBalance(address,address,uint256)","52ffeb30":"highestBidTime()","52ffff99":"addAllowContractList(address)","5300a306":"changeTransactionFee(uint256)","5301fa52":"setPromoCode(address)","5302470a":"submitPlaintext(uint32,uint32,uint256,uint256)","530266c7":"getSellOrderInfo(address,address)","5302a136":"fourthPriceTime()","53030d91":"investmentAddress()","5303a5d7":"RESEARCH_DEVELOPMENT()","53043490":"ownerTransferFrom(address,address,uint256)","53047154":"createPromoMovie(address,string,uint256)","53055262":"awardMarble(uint256,address)","53055481":"totalDeposited(address)","53056351":"DIGIPLACEDS()","53067968":"GetSellingTokenContractAddress()","53069df6":"getRepaidAmount()","5306a5af":"LogRollbackTransfer(address,address,uint256)","530795fb":"initNormal()","5308db4b":"finalizeBundleIPFS(bytes32,string,bytes32)","5309ce38":"PrintLimiter(address,address,address,uint256)","530abf0f":"distributeTokensToContributor(uint256,uint256)","530b1e1a":"recording(address,uint256)","530c435f":"whaleWantMyEther()","530c4ca6":"setGames(address)","530c6868":"getContributorETH(address)","530d26b0":"MattewWon(string,address,uint256,uint256)","530d44f4":"normalRate()","530dfad3":"addItemToUserDebt(address,bytes32)","530e3543":"addMemberToGroup(address,uint256)","530e784f":"setPriceOracle(address)","53105fbc":"tokenConversionFactor()","5310f0f4":"priceInUsd()","531163c1":"TOKEN_MAIN_CAP()","53127b88":"encrypt(uint32[26],uint32[4])","5312918b":"VestingEndedByOwner(address,uint256,uint256)","5312aa24":"Bigchaintoken()","5312ab19":"HoviiExchange()","5312b4bb":"pyrBalanceOf(address)","53135ca0":"presaleActive()","5313d890":"_markCredit(address,uint256)","53147d4f":"TokenCrowdsale(uint256,uint256,address,uint256,address,address)","531571a9":"connectTokens(address,address)","5315810e":"isSponsor(uint32,int256,uint32)","53176195":"witnesses()","53179413":"transfersBlocked()","5317e444":"removeUserPermission(address,bytes4)","5319418a":"transferLockedBalance(address)","5319ae10":"generateInstance(address[2],bytes,bytes32[2],uint256[3],bytes32[3],bytes,bytes)","531a7f29":"dateProductCompleted()","531b6d98":"LogHodlSetStake(address,address,uint256)","531b97d7":"oneCentOfWei()","531c1b33":"getOperatingBudget()","531c267e":"getGameResolverData(uint256)","531c8628":"amount_referral_invest()","531c9a56":"iPayStar()","531ca478":"VantageCrowdsale(uint256,uint256,uint256,uint256,uint256,address)","531ce262":"bankWithdraw(address,uint256)","531d1974":"testThrowRetractLatestRevisionEnforceRevisions()","531e1ee0":"EarlyPurchaseInvalidated(uint256)","531e4827":"poolTimeLastMinted()","531ebce5":"getReceiverAddress()","531ef079":"setBvToBpFee(uint256)","531efbee":"_score(bytes32)","531f4c40":"accept(bytes32,bytes32)","531ff93b":"setMrkContract(address)","53214e5a":"kilo()","53216223":"TravelCoin()","5321fe04":"subFromBalance(address,address,uint256)","5322f0c5":"getChannelOwner(bytes)","5322f9d1":"switchSale()","532399d9":"setTransContractLocked(bool)","5323c6cf":"calcCostsBuying(bytes,uint256,uint256[],uint8,uint256)","5323df9e":"getShipDetails(uint32)","53240172":"midiv(uint64,uint64)","53251389":"addBridgeNativeFeeReceivers(uint256)","5325dc16":"test_validShouldBe3()","53269475":"loveToken()","5326ba37":"setSaleAuctionERC20Address(address,address)","53270910":"deedOfOwnerByIndex(address,uint256)","5327f96e":"OwnerTransfer(address,address)","53286957":"CuboToken(uint256)","53290b3a":"setStateLoading()","53290b44":"getBalanceOf(address,address)","53290d1c":"founderGrant(address,uint256,uint256,uint256,uint8)","53295e44":"OtcgateToken(uint256,uint8,string,string,address)","53297b71":"completeReleaseAuction(uint256)","5329c681":"checkTimeout(uint256)","532af7d2":"calculateResult(uint256,uint256)","532b581c":"round2()","532b5f86":"createBytes32(bytes32,bytes32)","532c3dc5":"nAuditors()","532da8f9":"getDelayDays(uint256)","532e4849":"setTokenUriPrefix(string)","532e7e6a":"calcEarningsSelling(bytes,uint256,uint256[],uint8,uint256)","532e87e4":"setTimeForCrowdsalePeriods()","532eb619":"_sellTokens(uint8,address)","532f1041":"setFormat(bool)","532f1179":"refundsEnabled()","532fb092":"isApproveConfirm(uint256)","532ff308":"setBonusRates(uint256[],uint256[])","532ff568":"Tutancoin()","533019cb":"kyberReserve()","5330a4c6":"buyMicroKeys(string)","5330bc61":"disallowTransfer(address,bool)","533178e5":"get_rate()","53322527":"EthlanceViews(address)","5332510b":"EthernautsLogic()","533265e6":"Database()","53329856":"secondBuyPrice()","5333c507":"allowTransferFor(address,bool)","5333ee4d":"buyEgg(uint256,uint256)","533425a5":"icoPeriod()","5334398f":"addRecordwithReward(bytes32,string,string,address)","53344481":"isInTier1(address)","5334c231":"currentSwapRate()","533574ca":"getLastDividends(uint256)","53358fc4":"castVote(address)","5336cd16":"_getEndIndexKey(uint256)","5337421a":"TrumpBingo()","5337448e":"payWinners()","53376d1f":"revokeAuthentication(address)","5337fa10":"awardPoint(int256,bytes32)","5338b3e4":"miningTokenLeftInCurrent()","533945df":"editMemeTemplate(uint256,string,string,string,string)","53397be3":"lastConsolationPrize(uint256)","53398119":"emergency(bool)","533a645c":"minTx()","533ae8e5":"inTipperQueue(uint256,address)","533b180e":"LAcoin()","533c023b":"getGroupRight(string,string)","533d4270":"ClipperCoin(uint256,uint8,string,string)","533da8df":"getAreaOwner(string)","533de9e5":"addSmartContractByAddress(address)","533e00ec":"approveAndDo(address,uint256,address,bytes32,string)","533f6730":"clearInventory(uint256)","53400e7f":"debugNow()","534104df":"UnilotTailEther(uint256,address)","5341903b":"upgradeMe(address)","5341d618":"setDataColla_AB_02(string,string)","5342da41":"testBeyond()","5343e6a4":"rateFinalStage1()","5343f1a0":"cancelOrderWithMerchant(string,address)","534439a3":"mintingDec()","53448316":"MIN_SALE_AMOUNT()","53449d26":"TourPool()","534514ee":"adminCharge_p3()","53458f5e":"defaultTreesOwner()","5345c415":"LogOwnerAdded(address)","534607fb":"info_OwnerOfContract()","53462d6b":"getReleaseTime()","53462fd8":"NCPTokenDeposit()","5346dcc5":"calculateTokensEnabledforAirdrop(address[],uint256)","5347d58c":"Paradime01()","534844a2":"withdrawAmount()","534878fb":"reply(address,address,bytes32,bytes32)","53488f0a":"activateAuction(uint256)","5348ac95":"makeTokensTransferable()","53490c67":"earlySuccessBlock()","53490fbb":"EPR()","53497794":"RepublicKey(address[])","534992c8":"showTokenBalance(address)","5349a335":"setThirdAdmin(address)","5349cdb6":"Testcoin()","5349efdc":"generatetoken(uint256)","534a2f7c":"WTechCoin()","534b0391":"getVerifiedInfo(address,address,string)","534c2609":"checkBtcRequestSignature(bytes,bytes,uint256,bytes)","534d5acb":"initialBSTSupply()","534d5ce3":"RobaToken()","534ddf19":"reclaimContributionDefault(address)","534e05c1":"_goldFreeze(uint256)","534e2645":"getLucy()","534e3f81":"finishPVP()","534eb1d4":"offerBonus(uint256)","534f6a2d":"LogGrantClaimed(bytes32,uint256)","53501052":"extraTokensPercent()","53511819":"triggerAssertError()","53515226":"getEtherProceedsAccount()","5351ad81":"FrellyToken()","5352aadb":"allowedBetAmount()","5352b889":"isNewRound()","53537303":"bonusRatePeriodOne()","5353a2d8":"changeName(string)","5353e168":"rlc_team()","53547d3f":"mintBooty()","53554015":"newZeusPriceTicker(string)","53556559":"exchange(uint256)","5355ee2f":"CryptoSneakersCoin()","535779ef":"removeFromAddresses(address)","5357b989":"calculateFee(uint256,uint256,uint256)","53584939":"bytesToBytes32(bytes,uint256)","5358677c":"BACKUP_FOUR()","5358c119":"getFaucetByCreator()","535999aa":"getarg_3_input()","535a920c":"setLANDRegistry(address)","535b27dd":"BitImageTokenSale()","535b4e58":"adminResetLottery()","535bf003":"appVersionList(bytes32)","535c69b6":"setEthAuction(address)","535d1ab3":"claimWork(uint256,uint256,uint256)","535d3f22":"RankingBallGoldToken(address)","535d4156":"killWithBenefits()","535d9289":"RDPTicks()","535dc2b0":"_b1(string,uint256,string)","535e401c":"check(bytes32,bytes32,bytes)","535f23ad":"mainSaleStartDate()","53601ec5":"_transferFees(uint256,uint256[],uint256)","5360cd82":"GetContractInfo(string)","53613273":"setTymTokensWallet(address)","53613769":"setDistributorAmount(address,bool,uint256)","53613dd3":"creatorFeePercent()","536253a9":"getRandomForContractClanwar(uint256,uint256)","53636220":"depositToExchange(uint256,uint256)","53645caa":"rewardDays()","5364e45d":"setStartBalance(uint256)","5364f721":"getArbInfo(uint256)","536529dd":"WarpSpeed()","5365939c":"unlockedTokensInternal(address)","5365ccf7":"CCH_MENA_1()","53663c0b":"distributeAIC(address[],uint256)","53667f10":"getContracts(address,address[],uint256)","5366d0fd":"operationalExpensesWallet()","5366f338":"publishFor(bytes12,address)","53677154":"placeAnswer(uint256,string)","5368cc55":"getBack2()","536942b6":"finalizeAndRestart()","536a3ddc":"currentGameId()","536aace8":"setUserSignupTokens(uint256)","536bd93a":"SetAccessoryDataContact(address)","536c1ddd":"SampleERC23Token(address,uint256)","536c26e5":"MiniMeIrrevocableVestedToken(address,address,uint256,string,uint8,string,bool)","536c2e4a":"sendEmail(address,string,bytes32,string)","536c8c15":"jurySize()","536c9a7f":"dividendFundAddress()","536cb736":"setPreUri2(string)","536cfceb":"todaysSupply()","536d888b":"isServiceOwner(bytes32,address)","536d97c2":"setDividendsPercent(uint256,uint256)","536db4a8":"getParametersHash(uint256[14])","536dd8f9":"maxTokensToSold()","536e08bc":"getTokensBalance(uint256)","536e2800":"buyForWorkOrder(uint256,address,address,address,string,address,address)","536e3f6a":"getOracleData(uint256)","537038c3":"BOUNTY_PERCENT()","5370a049":"thebank()","5370e3d4":"Ozreal()","53718569":"generateRandomStats(string)","537187a3":"transferWithMsg(address,uint256,string)","53719b6e":"lockedTokens(address,uint256)","5371e490":"Presalezillion()","53729273":"getLLV_edit_9()","5372a9ce":"addService(address)","5372c1db":"PeriodicTokenVesting(address,uint256,uint256,uint256,uint256,bool)","53734dc5":"refundContribution()","53738a4c":"distributeOwnedTokensFromOtherContracts(address,address,uint256)","53749313":"PortToken()","5374eec3":"hijack(uint256,uint256)","5375a828":"createLibraryWithFounder(string,string,address)","5375f182":"IronHandsCoin()","5376a03d":"getProfitOrLoss(address,address,uint256,uint256)","53770f9a":"isStateless()","53775572":"_claimOreAndClear(uint32,uint8)","53779c11":"claimDividendByIndex(address,uint256)","5377f047":"allowedMultivests(address)","53790097":"Exhibition()","53799e7d":"frozenType(string)","537a082c":"withdrawSaleRequest(uint256)","537a924c":"Pay()","537afe94":"eastadscreditsx()","537b9c93":"NotFomo3D()","537bf9a3":"updatePermissionName(address,bytes32)","537ca660":"_setPetValue13(uint256)","537dbb80":"claimUserToken(address)","537df3b6":"removeFromBlacklist(address)","537f5312":"updateSymbol(string)","537f74fc":"_transferFrom_byProxy(address,address,address,uint256,bytes)","537fcd6b":"_computeAndSetBaseParameters16_18_22(uint256)","537fdf59":"user_redeem()","538082af":"UKG_FUND()","53811553":"getCertificate(bytes32,bytes32,bytes32)","53813af8":"getmy(address)","5381464c":"PRE_SALE_START_TIME()","53819e85":"getTotalComission(address)","53822cda":"createShortId(bytes32)","53844552":"addPayees(address[],uint256[])","5384527a":"tokenResend()","5384602d":"craetePartnerBytes(address,address)","5384734e":"isConfirmedStackholder(uint256)","53850db3":"getParticipantById(uint256)","538548c5":"recevedEthFromEvabot(address,uint256)","538564de":"assegna_diritto_di_voto(address)","5385726e":"maxTIPSupply()","53865562":"CLOSING_TIME()","5386b7ad":"dtTestWorldSnapshot(uint256)","538739fa":"operatorManager(address[],uint8)","538741c5":"getAllowedContracts()","5387a233":"feeLottery()","538811cf":"hasAllocated()","5388842c":"mintTicket(address,string)","53892496":"finney2LemoRate()","538a289a":"getSandwichInfo(uint256)","538a3f0e":"initializeFactory(address)","538a849c":"newRound(uint256,uint256,uint256,uint256,uint256,bytes32,uint256)","538a8c21":"giveawayReserve()","538b9618":"createElectionVerify(bytes32,bytes32[])","538c91b2":"validCandidate(string)","538d1267":"Announcement()","538df6f2":"claimedPrepaidUnits()","538dfcac":"contributionRejected()","538e0759":"refill()","538e0ff4":"totUsers()","538e8ae0":"assertEq19(bytes19,bytes19,bytes32)","538eae06":"ZuperToken()","538f5997":"getBalanceSize()","538fb98c":"getCarProductCurrentPrice(uint32)","53900bdd":"incirculation()","5392279d":"CryptoWCRC(uint256,uint256,bool,address,address)","539407f6":"committeesNumber()","53941a74":"addInviteId(uint256)","5394772a":"MIN_BET_VALUE()","5394e49e":"getRandomPosition(uint8,uint8)","53954574":"withDrawBack()","5395dbb1":"createSchedule(address,uint256,uint256,uint256,uint256,uint256)","5397c83c":"distr0(address,uint256)","53994d51":"ThreeDJSToken(uint256)","53999040":"buyLandForCandy(uint256)","53999339":"prepareLiquidityReserve()","539af982":"changeStartDate(string)","539b9648":"icoSmartcontract()","539c0f14":"deposit2()","539e2bfb":"secondChainedCallback(uint256)","539f70d8":"setOperationState(uint8)","539ff41a":"ADVISORS_WALLET()","539ffb77":"cancelRedeem(uint256)","539fffc9":"WithdrawPrize()","53a01f68":"createWizzPanda(uint256[2],uint256,address)","53a023d1":"EUSBToken()","53a04b05":"play(uint8)","53a06609":"_incrementInventory(uint256,uint256)","53a1c51e":"getInitializeMarketValue()","53a3b71e":"tossIntoTheFire()","53a40850":"userHasPattern(address)","53a454e0":"SubtractAmount(uint256)","53a47bb7":"nominatedOwner()","53a4c8a3":"TriggminePresale()","53a4caee":"getMajorThreshold(address)","53a50f0f":"addDeal(uint256,uint256,string,string,uint256,bytes32)","53a5e2d9":"teamGrantsAmount()","53a5e68f":"CircusToken(address)","53a636dd":"updatePrice(uint256,uint256,string)","53a6e2c9":"Mantapjar()","53a73f6e":"setTotum(address)","53a8b307":"getObjective()","53a94aa6":"_computeNextSeedPrice(uint256,uint256)","53a9698a":"isProviderFor(uint256,address)","53a97873":"getPrice(bytes10)","53a9fc9c":"ELVToken()","53aa3f5e":"getUInt(bytes32,bytes32)","53aa7dcd":"setCallerFee(uint256)","53aaa63f":"collectBack2()","53aab098":"addPriceFeed(uint256,uint256,uint256,uint256,bytes)","53aab434":"buyIn()","53aaef7d":"weiToTokens(uint256)","53aaf7c7":"OperatorProductCommissionChanged(uint256)","53abf7f4":"parseTrade(bytes)","53ac36f4":"DropReward()","53acae4a":"RANGESTART_4()","53acb23f":"unlockPriceChange()","53adce21":"getGroup(address)","53ae8de6":"modify_Presale1StartDate(uint256)","53af5d10":"closingAddress()","53afda90":"initDiscounts(uint256[],uint256[])","53b0b620":"allocateBid1(address,bytes32)","53b15f31":"get_asset_details(bytes32)","53b1b49b":"Human()","53b239c7":"setPoWtfContract(address)","53b2dd41":"WGCToken()","53b382ea":"manuallyEnded()","53b5015c":"getClientSupply(address)","53b5306b":"getUnfreezingPrice(uint256)","53b54f5e":"transferWithoutDecimals(address,uint256)","53b5b427":"team4LockEndTime()","53b64b0b":"setNumDepositsSigned(bytes32,uint256)","53b6f766":"addTotalIndividualWeiAmount(address,uint256)","53b7a59b":"destinationWallet()","53b7b2e9":"cEthereumlotteryNet(bytes)","53b86342":"withdrawOwnersMoney()","53b8e278":"upgradedContract()","53b90b5b":"addWalletEmail(address,string)","53b93358":"_getPoS(address)","53ba11d0":"icoWalletAddress()","53babaf9":"processStellarReward()","53bad0b9":"boschcoin()","53bb2eb6":"buyOffer(uint256,uint256,address,bytes32)","53bc147e":"lastKickoffDateBuffer()","53bc1c12":"getJobState(uint256)","53bc1d9b":"ONTOPToken(uint256,string,string)","53bc373d":"SIT(address)","53bc7399":"play_stone()","53bc7d62":"setInvalidWithReturn()","53bd353b":"EarlyTokenSale(uint256,uint256,address,address)","53bd755a":"__setTokenPrice(uint256)","53bd8bdb":"isRequestExecutable(uint32)","53beb1f8":"checkHalfLife()","53bfd3d0":"getUserTearAward(address,uint256,uint256)","53c048ce":"TICToken()","53c06966":"startMining(address)","53c194af":"createIco(uint256,uint256,uint256,uint256,uint256,address)","53c1b31f":"MooToken(uint256,string,string)","53c24064":"EasyMineTokenWallet()","53c2828f":"rentalBalanceRemaining()","53c2e8ab":"FacebookCoin()","53c3419b":"bet(uint256,uint256,uint256,uint256,uint256,uint256)","53c37276":"frozenDaysForPreICO()","53c3a57d":"recalcFlags()","53c3cc1f":"ResumeEmergencyStop()","53c3fe8a":"hasICOClosed()","53c4aeac":"crowsaleSlots(uint256)","53c549da":"LemonContract()","53c64fbc":"peekQueue()","53c66d90":"YEEToken()","53c7186c":"test_token_creation()","53c7801c":"second_round_start()","53c8388e":"updateMetadata(uint256,string)","53c84526":"setSmartAffiliateContract(address)","53c86cfc":"UvoCash()","53c9843f":"preIcoCashedOut()","53ca1aa8":"GOLD_TO_COLLECT_1SWORD()","53cae7b8":"distributeAirdropMultiPresale(address[],uint256[],uint256[])","53caf582":"testThrowSetNotUpdatableNotOwner()","53cb26c6":"preciseDecimalToDecimal(uint256)","53cb430f":"setoldtoken(address)","53cc2fae":"unFreezeAccount(address)","53cc3e7a":"sysPrice()","53ce0a71":"USACoin()","53ce7de9":"participantIndex()","53ce910e":"getSafeKey(uint256)","53cea153":"claimableOwnerEth(uint256)","53ceee6c":"icoBuy()","53cf4d2b":"indexshow(address)","53cf51bc":"rewardSent()","53cfdda3":"setMonthlyPrice(uint256)","53d0f255":"STEP()","53d142a7":"setTokenInfo(uint16,string,address,uint64,uint256)","53d3e848":"abortICO()","53d3ed60":"isBotAt(address,uint64)","53d3eeee":"profitsRatePercent()","53d413c5":"removeKey(bytes32,uint256)","53d590bc":"softUndelete(bytes32)","53d69b07":"setPreSaleStartAndEndTime(uint256,uint256)","53d6fd59":"setWhitelist(address,bool)","53d70700":"setVotingParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","53d736ed":"CreateCard(uint256,string,string,string,string)","53d73718":"voting_info()","53d74fdf":"totalHolders()","53d797c9":"GetGoodsInfo(uint32)","53d7edbc":"_crowdsalePaused()","53d838b6":"getMatchAwayPlayers(uint256)","53d97e65":"setPrizes(uint32[])","53d99c2a":"tokenToEthRate()","53d9d910":"create(address[],uint256,uint256)","53da0c7e":"bonusesForAmountsCount()","53da4859":"ACT()","53dad947":"oraclizeContract()","53db1deb":"DredgrSwap()","53db5fdb":"getCreatorTAOSettingDeprecation(bytes32)","53db6b21":"AUMToken()","53dba812":"Horizon0x()","53dc4cf1":"Greedy()","53dd1902":"strcat(bytes,string,bytes,string)","53dd8881":"tweakDailyDividends(uint256,uint256)","53de63e3":"isMasterWallet(address)","53e0b78f":"LandClaimContractSet(address)","53e0c46d":"nuoyilian(uint256,string,uint8,string)","53e1509c":"addExchangePartnerTargetAddress(address)","53e1a169":"doPayment(address)","53e1ead9":"companyAddress()","53e215f4":"getNodeInfo(uint256)","53e3926c":"compareNums()","53e4d8ef":"admin_set_withdrawable(bool)","53e4e607":"get_parameters()","53e551ff":"createContractItem(string,bytes32,address,address)","53e68147":"emissionInternal(uint256)","53e68720":"sendToBeneficiary()","53e7168b":"setUInt(bytes32,bytes32,uint256)","53e7daf2":"NewStandardToken(uint256,string,uint8,string)","53e86a88":"contributorsTotal()","53e8c040":"Winn()","53e9574a":"FOUNDERS_TOKENS_PERCENT()","53e9dcae":"attributeType(uint256)","53ea04fe":"AgencyLock2()","53ebf6bd":"setContractLock(bool)","53ecbdd2":"getTankType(uint256)","53ed5143":"getAll()","53ed589b":"LogNewProvider(address,string,bytes32)","53ee9114":"PassDao()","53eeb430":"allPurchasedSprites(uint256)","53ef5e03":"amount5()","53ef6781":"_start()","53efb13f":"setContractDurationInDays(uint16)","53f072e3":"numApis()","53f11cb3":"asm_clean(uint256,uint256)","53f24e33":"isUpgradeInterface()","53f25ca6":"isNameEmpty()","53f3807c":"STATE_PLAYING()","53f4a519":"queryResource()","53f4b36f":"calcFin()","53f4db01":"totalWeiRaised()","53f63bb3":"setPreSaleFinishDate(uint256)","53f65cf7":"forceRecoverCollateral(bytes32,address)","53f6740d":"setKpopItemContractAddress(address,address)","53f6ef28":"EUFBToken()","53f6f01f":"ADVISOR_STAKE_TWO()","53f754e0":"tokensDue(uint256)","53f818d6":"checkBetValue()","53f81ef8":"getSubscriptionTo(bytes32)","53f8e415":"SetDonateStep(uint256)","53f92e49":"UnableToRejectPayment(address,bytes8,uint256)","53f95cc6":"THIRD_TIER_DISCOUNT()","53f9ca96":"CCC(uint256,string,string)","53f9ec67":"setIsInvalid(bool)","53faa9a9":"changeRecovery(address,address)","53fafd15":"makeTransfer(uint256)","53fb9233":"checkDocument(string)","53fc3923":"safeAdd40(uint40,uint40)","53fc79d1":"setTargetDiscountValue5(uint256)","53fd0670":"sellArtworks(uint32[])","53fe189c":"setAElfMultisig(address)","53fe7a59":"PURCHASER_MAX_TOKEN_CAP_DAY1()","53fefd7d":"changeMaxDeposit(uint256)","53ff7766":"_escrowTheAOPaymentEarning(bytes32,uint256,uint256,uint256)","53ffab1d":"disableconstruction()","53ffe1f9":"setRentalPricePerSecond(uint256)","5400a93e":"payoutMatch(uint256,uint8,bool)","54019949":"getShopOwnerCategorizedProducts(string,string)","540273bb":"changejp1(address)","54032862":"ZapCloud()","5403a0e5":"getTeamToken()","5404bbf7":"getEntropy()","54057aa6":"setPriceClaim(uint256)","5405e4f4":"SMILE()","54063f4e":"sendETHfromContract()","54070f83":"getTournamentAdmissionBlock()","54091a20":"removeFromTransactionDisallowedList(address)","540a5e4e":"cs()","540a9db3":"getVestingAccount(address)","540ae26f":"MassERC20Sender(address)","540b2255":"_invest(address,address)","540b34a0":"listMOC()","540c755f":"ethWithdraw()","540c97c8":"getAllRevisionIpfsHashes(bytes20)","540cafe0":"storeHeaderWithFee(bytes,int256,address)","540cc484":"getPreSaleTokensSold()","540cf75e":"getPendingPresaleTokens(address)","540d888e":"SendTaxFee(address,address,address,uint256)","540d915e":"serviceGroupChange(address,uint8)","540e2f5b":"customTokenDefrosting(address[])","540ea6db":"getuseraddress(uint256)","540f3d6d":"feeProcess()","540f5631":"isUnderwriter()","540fd4df":"addressFundFoundation()","54105974":"AdHiveToken(address,string,string,uint256,uint256)","54107401":"declareLove(string,string)","5410ac50":"raiseCap(uint256)","5411029d":"_validSignature(address,uint256,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","54114dee":"Caps()","5412af17":"Watsondog()","541334f6":"isUnicornContract(address)","5413d6f4":"ImmlaToken(address)","54147ecb":"withdrawForTokens(address)","54149777":"getAirDropedToday()","54149975":"DeleteToken()","54151bc3":"createPostboyAccount(uint256,uint256,bytes16)","54153f91":"getArrIntField1()","5415b8f8":"setAssetFeesList(address[],uint256[],uint256[])","5415f3a7":"buyStudioStake(address,uint256)","5416707c":"getEthOfferAmount(uint256)","5416995e":"TGCToken()","54186bab":"SolarDaoToken()","5418796c":"pubKeyToEthereumAddress(bytes)","5418bea9":"getCountReadyPlayerByTrackId(uint256)","5418ecdd":"setTokenHash(uint256,uint256)","54192046":"setAuctionStart(address,address,uint256)","541a01ed":"presaleTokenVault()","541a3656":"optionOrderCancelled(bytes32)","541ac2b3":"locked_since()","541aea0f":"put(uint256,uint256)","541afaf6":"getWarriorDistributedRandom(uint256)","541b2173":"IKT(uint256,string,uint8,string)","541bb358":"setRarityTargetValue(uint8,uint256)","541c15eb":"changeLock(address,uint256,uint256)","541d920c":"commit(bytes,string)","541dc9ba":"redeemPreSale(address,address)","541e22ea":"sendRefBonuses()","541e34a7":"QuantumPay()","541ee050":"bonusEnd10()","541f631a":"transferInternal(address,uint256)","54203101":"CTWorld()","54204ad4":"triple()","54215767":"upgradeTradeProfileImplementation(address)","54217c21":"Q2(address)","542241d0":"fifthExtendedBonusSalesEnds()","5422cf34":"sellPop(uint256,uint256)","54238645":"closeICO()","5423a05d":"GoToken(address,address,address,address,uint256)","54244518":"coinIssuedRewardPool()","54260cb6":"getBuyLandInfo(address,uint256)","5427789c":"MINT_AMOUNT()","54279bdd":"createAuction(uint256,uint256,address)","5427e4e1":"APS(string,string,uint256)","5427e8fa":"getTicketIsPaid(uint256)","54280260":"balancesLocked()","54290065":"getAsksCount()","54292c53":"rewardAvailableCurrentDistribution()","5429a417":"getBasicBallotsPer30Days()","5429d4b5":"mitfwdToken()","542a3368":"randomly_select_index(uint256[])","542a90bd":"remove_quote(bytes32,bytes32)","542aa99f":"stopSetup()","542aee37":"getTotalTonsClaimed()","542b5111":"MANXERC20()","542b9a40":"ProjectOwner_DisableProject(int256)","542bdb4d":"testMathOverloaded()","542bee82":"addGlobalBlockValueBalance(uint256)","542c8f37":"isOnSell(uint256)","542cad3d":"setCopaCoreAddress(address)","542cae98":"checkGameOverByUser()","542ccddb":"claimRoundReward(uint16,address)","542ceaad":"countRequest()","542cfdf0":"extendItem(address,uint256)","542d397c":"tokensBlocked()","542d3e34":"NewImage(uint256,uint8,uint8,uint8,uint8,string,string,string)","542d8dc0":"Mag50()","542de573":"BITHALALToken()","542df7c7":"getGameConstants()","542e898e":"STC()","542fce21":"KergToken(uint256,string,uint8,string)","542fd556":"getMakerProjects(address)","54311422":"giveTokens(uint256)","54313b22":"tonextround()","5431dfb8":"stage3Sale()","5432202a":"isServiceAccount()","54353f2f":"example()","543577f3":"LandManagement(address)","543594b8":"verifySignature(uint8,bytes32,bytes32,address,bytes32)","5435a774":"Permissioned()","5435bac8":"itemsForSaleLimit(uint256,uint256)","5435dbd4":"CPF()","54361699":"registerContributorPool(address,uint256,int256)","54367179":"updateRealWorldPlayer(uint32,uint128,uint64,uint32,bool,bool)","5436c163":"createVillain(string,uint256,uint256,uint256)","5436e5a0":"getValueByHash(bytes32)","54370a8d":"QueryMyBonus(address)","5437988d":"setVerifier(address)","5437b39b":"hasUnprocessedDividends(address)","5437e401":"withdraw(address,bool)","5437f098":"changeStartBlock(uint256)","54385526":"setStatus(uint8,uint8,string)","5438a64e":"getContractSigners(bytes32)","5438c5d2":"hasListener()","54392a96":"simTotalObligation(bytes)","5439af13":"getIdeaDescription(uint256)","5439c6a1":"nonFungibleByIndex(uint256,uint128)","5439e185":"buyTreeTokens(address,uint256)","5439f5d2":"TimeToken(uint256,string,uint8,string)","543a3d62":"token_call()","543a86f6":"dblShaFlip(bytes)","543a9ce4":"setAStore(string,address)","543ad1df":"MIN_TIMEOUT()","543b4f6f":"endTimeTwo()","543ba50a":"FundsDeposited(address,uint256)","543e0a7b":"stringsEqual(string)","543e10b4":"contributeTo(address,uint256)","543e4dcd":"testFailUntrustedTransferFrom()","543e9954":"freeBalanceOf(address)","543e9c10":"containsAdmin(address)","543f8101":"activateOversightAddress(address)","54400c60":"right19(uint256)","544082e5":"authorShare()","54409599":"SHIVToken()","54413d29":"withdrawAllForAccount(address,address[])","544447bb":"unicornToken()","5445cbf3":"assetsCertified()","5445e38c":"_isCycleValid(uint256)","5446b604":"unlockMintDate2()","5446d669":"ShitToken()","544736e6":"isStarted()","544743d6":"getCharAt(uint256)","5447ad71":"newGame(bytes32)","5447b86f":"ipart(int256)","5447c05d":"updateTemplateReputation(address,uint8)","5447fab0":"serviceController()","5448c674":"IBCA()","544a026b":"protectCharacter(uint32,uint8)","544aa2cf":"LOG_BetLost(address,uint256,uint256)","544b1b24":"onlyHarvest(uint256)","544b9606":"ICO_BONUS2_SLGN_LESS()","544be427":"finalizeBurnUtility(address,uint256)","544c465c":"calcReward(uint256)","544cdbda":"send_to_owner(address,uint256,uint32)","544cfead":"reignBlocks()","544d6544":"transferPrivateSale(address,uint256)","544d8ca2":"registerLog(string,string,uint256)","544d9723":"itemAt(uint256)","544f113b":"startingAmount()","544f43e3":"getRatePlansOfVendor(uint256,uint256,uint256,bool)","544ffc9c":"proposalVotes(uint256)","5451436d":"EthLyte()","54517ddf":"transferFromByCrowdsale(address,address,uint256)","5451a1e1":"addressFounders()","5451cbcc":"ZEToken()","5451fb26":"increaseLoanOnBehalfOf(address,bytes32,uint256,uint256)","5452644d":"createNewDynamicPaymentAddress(uint256,address)","5452b7d4":"getReservedTokens(uint256)","545305fb":"finalizeCrowdsaleAndToken()","5453095b":"buyMNC(string)","545342a0":"ZaiZaiCoin()","5453f4e7":"createTokenUri(address,address,address,address,address,address,address,uint256)","545464ff":"ConsentFactory(string,address)","5454fb7c":"ico1Sold()","54557250":"getAgentIdByPositionBet(uint256)","545599ff":"END_DATE()","5455e1b8":"setAddressesThatCanList(bool,address[])","54567923":"addServiceReward(uint256)","54569a86":"Needit()","5456d8d2":"removeSpecialBonusConditions(address)","54573835":"withdrawEtherInternal(address,address,uint256)","54573cfc":"setRule(uint256,uint256,uint256,uint256)","545842ff":"redeemLevAndFeeToStakers(address[])","545921d9":"providerRegistry()","545a153a":"getId(uint256)","545a5896":"changeSolidStampContract(address)","545ae0f6":"TokenFundTransfer(uint256)","545b2f0d":"getUpgradeAmt(uint256)","545c50f0":"pointRootNode(int256,address)","545c5a02":"setStepTwoLockEndTime(uint256)","545c5d54":"deliveryService(uint256,uint256,uint256)","545d2e29":"invalidateAdvertiserRefund(uint256)","545d5988":"claimCheckPriceReward()","545d8b55":"minCapFail()","545e6362":"PRE_ICO_BONUS_TIME_1()","545e7c61":"deploy(address,address)","545f6837":"returnSenderBalance()","54604eec":"stopAssign()","54605549":"setCoinBalance(address,uint256,uint8,bool)","5460687c":"test_chain2_3()","5460ef10":"sendWithExtraGas(address,uint256,uint256)","54610cea":"setProvider(address,uint256,uint256)","54612e27":"freeze(bytes32,bytes32,uint256,bytes)","54616911":"burnICOTokens()","54619b69":"eAccessTOKEN()","546216f1":"winningScore()","54622cef":"multiMintPreIco(address[],uint256[])","5462870d":"multisigAddress()","5463a2e4":"reasonableDiffInBps(address)","546434e3":"TwoStageSale(bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address,uint256,uint256,uint256)","546455b5":"assert3(uint256)","54653352":"beView()","54657f0a":"setHiddenCurves(bytes32[])","54659685":"getTicketsCount(address)","54659d99":"SPINFund()","546639cf":"JacksToken(uint256)","546668bb":"conquesting()","54672768":"Instrument()","54674ebc":"HackableToken()","54675320":"EventProduct(uint32,string,uint32,uint32,uint256,uint256,uint256,uint256)","5467e0a7":"redemption()","5467f508":"indPresaleDeposit()","5468e4e1":"setGameStateFusion(bool)","5469a173":"getFifthRoundReleaseTime()","5469aabb":"_diviSplit(uint256,address,address,uint256)","546b270d":"getServer(uint256)","546b48b1":"makeSimpleBundle(uint256,address,bytes32,bytes32)","546c2b93":"paid(uint256,uint256,bytes32)","546d08fe":"dividendAddress()","546dc0ac":"collectAsset(address,uint256)","546dc71c":"approveWithdrawAddress(address,address,bool)","546dd883":"privateAmount()","546e1959":"changeOwnerStart(address)","546e428c":"modifySender(address,bool)","546ea281":"currentAction()","546efd98":"indiFundAndSocialVault()","547069bf":"crowdsaleWeiRaised()","5470b13b":"getWallet(uint256)","5470f6db":"setMaxSet(uint256)","547173da":"endPresaleDate()","54717ea9":"getValueBonusTokens(uint256,uint256)","54718917":"determineWinner(string)","5471d5d8":"VetLite(uint256,uint256)","5471dd4c":"FourthAddressBalance()","54722412":"OfferZone()","54734f7d":"setBoardAdd(address)","54738157":"OwnerCloseContract()","5473b4e9":"getTransactionConfirmCount(bytes32,uint256)","5473c701":"test_oneInvalidFalseEqLog()","54741525":"getTransactionCount(bool,bool)","54741f8d":"getMemBestPromouter()","5474d4d7":"_transferBag(address,address,uint256)","5474fbd3":"isDayThirtyChecked()","547505e3":"tokenAdministrator()","5475c22e":"bindOrderFunds(address,bool,int256)","5476bd72":"addToken(address,address)","5476ea9e":"auctionAddress()","5476f49d":"m_totalAppCount()","5477d33f":"price_constant1()","5477e571":"handleMultipleItems(address,uint256,uint256,uint256,uint256,uint256)","54786b4e":"getDSTSymbol()","5478786c":"IDLE()","5478dbb7":"play(uint256[3])","5478f06f":"updateMDTRewardAmount(uint256)","5478f468":"getHistoryLength()","54790b7d":"isOvertime()","547916ea":"finishRound()","54791f36":"_transferWithReference(address,uint256,string,address)","5479d940":"isUpgradable()","547a5168":"TomocoinTokens()","547a5eee":"setWhitelistSetter(address)","547ac053":"saveInitialParametersToStorage(uint256,uint256,uint256,address)","547c165f":"getApprenticeChestAvailable()","547c1b6a":"SALE_START_DATE()","547c4137":"setLLV_edit_32(string)","547c8011":"DemocraticPalette()","547cae29":"uintToString(uint16)","547cbaa5":"addFrozen(address,uint256,uint256,bool)","547dd162":"_newAgon(uint64,uint64,address,uint256)","547dfaf5":"WthdrawAllToCreator()","547e3f06":"changeReceiver(address)","547e6a5b":"simulate(uint256,uint8,uint8,uint8,uint8,uint8,uint8[176])","547eeac1":"acceptTransfer()","547fd950":"getTotalFrozenBalance()","54812d17":"initialize(address,address,uint256,uint256,address,uint256)","54817301":"setFreezeEnd(uint256)","5481c1ff":"referBenefitRate()","5481f43e":"getProviderTitle(address)","54823e66":"getStateHash(uint256)","54828eb7":"placeBetEven(uint256)","54829cad":"dubi()","5482d73c":"getDocument(bytes16,uint256)","5482d88e":"telcoin()","54830df7":"getApprovedTokenCount()","54840c6e":"tradable()","5484b5bf":"thelocation()","5485868a":"roundFactory()","5485bb82":"w_Team()","5486dfb3":"distributeSupply()","548707cd":"_bid(uint40,uint128)","54876921":"withdrawMoney(uint256)","5487e055":"PRICE_MID()","5488cc80":"currentCheckpointId()","548942e1":"UbecoinICO()","548ad42e":"chfScale()","548b273a":"outstandingEther()","548b5e6b":"contractStartDate_()","548c0ef4":"getRank(address)","548c20be":"getMyName(bytes32)","548d4a54":"updateTransferFeeRate(uint256)","548d91b1":"getPage(uint256[],uint256,uint256,bool)","548db174":"removeFromWhitelist(address[])","548dd51e":"newContract(address,address,uint256)","548e0846":"lastCallBlock(address)","548f896c":"setHouseEdgeMinimumAmount(uint256)","548fe136":"doWorkAndPayTOT()","549060bb":"Competition(address,address,address,uint256,uint256,uint256,uint256,uint256)","54919a6c":"sendTokensSingleValue(address[],uint256)","549215a3":"amendEpoch(uint256)","54924aec":"adminsDisabledForever()","549262ba":"put()","5493a7f4":"importAmountForAddress(uint256,address,address)","549400bd":"valuee(uint256)","549503e5":"executeSell(address,uint256)","5495699f":"teamFund()","5495794b":"initialWei()","5495ca36":"MDC9Token(uint256,string,uint8,string)","549737e3":"setIBalance3(uint256,uint256,uint256)","549767c7":"balanceSpot(address)","5498e9e5":"AmericanAirlinesCoin()","5498eae4":"PAYA()","54990b15":"sendTranche(bytes32,address,uint256,bytes)","54999f6d":"initAmount()","5499c84e":"changeBonus(uint256,uint256,uint8)","5499dca5":"getMyStake()","549a9ffd":"changePiranhaName(uint256,string)","549aa194":"unreleasedAmount()","549bc193":"changeSwitchTime(uint256)","549bf4bf":"Liberty()","549bf9b9":"SFCapitalToken(string,string,uint8,uint256)","549c4627":"depositsOpen()","549c6bbb":"refundTokens(address,uint256)","549c7b58":"getAgon(uint256)","549caf35":"oxced()","549cbc7a":"startSale(uint256,uint256,uint256,address)","549d5e3b":"claimByAddress(address,address)","549d776a":"upgradeContract(uint256,address)","549ddcbd":"setFreezeHybridizationsCount(uint256,uint256)","549df19f":"resetAllWallets()","549eca74":"fpDiv(uint256,uint256)","54a019e2":"FOUNDER_FUND_2()","54a035aa":"_evaluateCategory(address,uint8,uint256,uint256)","54a04d2f":"setMigrateAgent(address)","54a0ebf5":"updateEntityName(uint256,bytes32)","54a1b431":"getVoteDetails(uint256)","54a1e232":"setSellOrdersContract(address)","54a28ded":"bhCheck()","54a325a6":"setKyberNetwork(address)","54a46211":"_removeInvestor(address)","54a598b0":"globalTokenTransferLock()","54a6c8c4":"toSmallrtc(uint256)","54a6ff68":"isVersionLogic()","54a874b4":"isSolved(address)","54a8b217":"qryModules()","54a8ca69":"transferAnyMEPToken(address,uint256)","54a8ed7b":"USD_CENT_PER_GZE()","54a9409e":"charge(address,uint256,uint256)","54a9de1c":"referrerBonus(address)","54aa0546":"MCNC()","54aa4e44":"setDisableBuyingTime(uint256)","54aac764":"SALE2_CAP()","54ab5561":"setOwnerTwo(address)","54ac2119":"EMJACTestToken()","54aca207":"iwithdrawal(uint256)","54acbe7b":"setSaleShare(uint256,bool,address,uint256)","54accc88":"OOREDOOCHAIN()","54ad2d22":"BitcoinCrown()","54ad7e1c":"setDividendDistributionPool(address)","54ad9718":"feePrice()","54adb7b1":"doNotAllocateBid(bytes32)","54adc686":"claimRewards(bytes32[],uint256[])","54ae8492":"CustodialForward()","54aee843":"MANHATTANPROXYMANAVE()","54af0d4c":"validAfter(address)","54af3548":"getSigner(address,uint256,address,uint256,bytes32,bytes32,uint8)","54afc9a9":"MyFirstToken()","54b025c5":"deleteRole(address)","54b02ba4":"cutoff()","54b2a080":"valueAtIndexHasNext(uint256)","54b302c5":"maximumDeposit()","54b3fa58":"ServiceTask(string)","54b48428":"endTGE()","54b49859":"fmpContractAddress()","54b51fcc":"testNumberOfElements()","54b61723":"round3Cap()","54b67057":"setTranformed(uint64,uint64)","54b6a520":"ICOFinished()","54b6ba95":"durationInDays()","54b6ed85":"AddNewCurrency(string,string,string,string)","54b7636e":"isKYCVerified(address)","54b84910":"needToReserve()","54b8c024":"fieldOrder()","54b8d5e3":"getName(bytes32)","54b8dd66":"countryItems(uint256,uint256,uint256)","54b8dfcb":"settleBuyer(address,uint256)","54b9b4fa":"UNLOCK_TEAM_1()","54ba34b5":"available_slots()","54ba7daa":"enter(bytes,bytes)","54bbd376":"getNextDate(uint32)","54bc16f2":"Exchanges()","54bdbd4d":"changeMinPeriod(uint32)","54be50a5":"lastHoldingTax()","54beb2f4":"ProfitSharing(address)","54bec662":"removeValidation(address,bytes32)","54bef3b4":"getPlayerVaultsHelper(uint256,uint256,uint256,uint256,uint256)","54bf3a73":"playerToDungeonID(address)","54c0775f":"GetItems(address)","54c15020":"awardReferalBonus()","54c15b82":"isGeneScience()","54c29ce6":"assertOperationIsConsistent(bytes32)","54c35a3c":"setup(address,address,address,address)","54c3b0c4":"icoPhase3EndTime()","54c41fb9":"viewMerkleHash(uint16,uint8,uint8)","54c51813":"setFreelancer(bool,string,uint256,uint8,uint256[],uint256[],string)","54c552db":"setNumber(bytes32,uint256)","54c5aee1":"collectReward()","54c5b696":"maxBonus()","54c5f850":"withdrawTokensFromAnyWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","54c72ead":"_getHardCap()","54c86628":"etsContract()","54c91295":"getEloScore(address)","54c916a1":"setOCPTokenContract(address)","54c93a4e":"lockTeamTokens()","54c990cf":"periodTimeFrame(uint256)","54c9cc44":"changePlayersName(string)","54ca435f":"PRESS_MARKETING()","54ca9095":"newEntity(bytes32,bytes32,uint256,uint256)","54cacaba":"QuarkChain()","54caf101":"bonus(uint256,uint8)","54cb5081":"getPromoMinPurchaseEth()","54cbe1e6":"gamePayoutResolver(address,uint256)","54cbffc4":"LimitOfMinutes()","54cc463b":"PreICOPrice()","54cc61bc":"Krown(uint256,string,uint8,string,address)","54ccdb0d":"seriesCSupply()","54ce0851":"round5TokensRemaning()","54ce7616":"TestTalk()","54cecb21":"AuthPending(address)","54cf2aeb":"swapFee()","54cf6668":"setEarlyInvestorExchangeRate(uint256)","54cfcd1b":"DEAWCOIN()","54cfe7d0":"nextForkName()","54d03b5c":"changeFeeMake(uint256)","54d05ad2":"changelp10(address)","54d06009":"whiteListAddress()","54d15005":"isDestroyed(string)","54d15347":"adminSuspendDeposit(bool)","54d18864":"totalProjectToken()","54d1b356":"GetBankerProfit(uint8)","54d1f77c":"UnpaidDivInt()","54d24f33":"TOKEN_PRESALE_LIMIT()","54d271fb":"unpause_1()","54d29b9a":"bidderWhitelist(uint256)","54d2a34a":"getHouseFee()","54d30c87":"release(uint256,bool)","54d3f3e4":"getTopInfoDetail(address)","54d41bbd":"unregisterAdmin(address)","54d4b7b2":"DateOfDeath()","54d4da57":"extractInvoicedLength()","54d50378":"winner_pool_amount()","54d5e127":"withdrawSettle(bytes32,bytes32)","54d68405":"LogFundAnswerBounty(bytes32,uint256,uint256,address)","54d6a2b7":"cancelSwap(uint256)","54d734e2":"createSubscriptionOffer(uint256,uint16,uint256,uint256,uint256,uint256,uint256,bytes)","54d79868":"getPositionBalance(bytes32)","54d7c34d":"transferAidrop()","54d87002":"showContributed()","54d89c92":"numberParticipants()","54d92ba9":"getCurrAuctionPriceTankID(uint256)","54d9d6f8":"findNextDay(uint256,bytes)","54da44db":"GetUserBetsInRaz(address,uint256)","54da5393":"Utils()","54da80c9":"Patney()","54dacb96":"numWhitelisted()","54daedc3":"transferCoins(address)","54db4547":"ethbuy(uint256)","54dcc49b":"_withdraw(address,uint256,bool,uint256)","54dcfb9b":"LinkToken(uint256,string,string,address)","54dd1da4":"releaseVestedTokens()","54ddd5d6":"retrieveRefund()","54dea00a":"getTokenRate(address)","54dfbca8":"setExtra(uint256,address)","54dfefb4":"DEEPPAYMENT()","54e030b7":"bonusDistributionAddress()","54e031cb":"setLockAccInfo(address,string)","54e08f76":"theInvestor()","54e0b451":"claimReward(bytes32,uint256)","54e0b464":"ICO_ADDR()","54e16753":"BLUECoin()","54e2cf2d":"_getPartLevel(bytes,uint256)","54e2dc8d":"getAdditionalTime(uint256)","54e30c37":"earlyBirdPrice()","54e33cf0":"getRewardsIndex()","54e35054":"getRoundResultInfoWithRoundID(uint256)","54e35ba2":"issueTokens(uint256,uint256)","54e4df26":"test_0_testGenerateTokens()","54e707a0":"START_WEEK_2()","54e76d74":"minimumPoolPurchase()","54e7aed8":"Frozenable(address)","54e7e98c":"PiexT(uint256,string,uint8,string)","54e8561b":"RDOCrowdsale(address,address)","54e8e4e4":"Test_SignedInteger_AdditionOverflow(int256)","54e921cb":"setFreezeMustCalculate(uint256,bool)","54e9244e":"orderFills()","54e9d5e1":"refundDonation(address)","54ea1538":"sellDrago(uint256)","54ea1af9":"flyDrop(address[],uint256[])","54ea4000":"identify(address[])","54eae3e6":"streamEnd()","54eb3f74":"getOptionState(address[2],uint256[7])","54eb9e88":"_preValidateICOPurchase(address,uint256)","54ec5d9b":"weiRaisedRound()","54ec6a43":"taxPaid()","54ecaba4":"COMPETITION_VERSION()","54ecd994":"ALLOC_BOUNTIES()","54ed08c8":"getPurchasedTokens(address)","54ed44f7":"generateCostFromAttributes(uint8[14])","54ed7b6e":"addHash(bytes)","54ee4d4b":"addCommunityGrant(address,uint256)","54eea796":"setEpochLength(uint256)","54ef356f":"isUserAdmitted(address)","54ef9c3c":"getEpisodeBranchData(uint256,uint256)","54f10ed0":"IknewToken()","54f11256":"retrieveCadvsLeftInRefunding()","54f12a2c":"isAllowed(string,string)","54f1469c":"shuffle(uint256[])","54f1bb4b":"Etheraffle(address,address,address,address)","54f363a3":"addition(uint256,uint256)","54f47346":"lastBlock_f12()","54f47be7":"transformSettingContract()","54f4824d":"myLastRef(address)","54f50f1b":"nicknameOf(uint256)","54f5164b":"isLocked(bytes32,uint256)","54f51d32":"SetCitySnapshot(address,uint256,bool,uint256,uint256,uint256,uint256)","54f5675c":"OfferedForSale(uint256)","54f56df1":"Shop(address)","54f60aea":"ONE_EMONT()","54f6127f":"getData(bytes32)","54f63105":"maxMintingPower()","54f63ee5":"resumePresale()","54f703f8":"factor()","54f78dad":"setBalanceSheet(address)","54f7b493":"getMinimumFundsInEuroCents()","54f7dd8c":"lotOfOwnerByIndex(address,uint256)","54f81786":"startTokenVotes(address[10])","54f83483":"needsTick()","54f8c2df":"getShipName(uint32)","54f9962a":"getAffiliateLevel()","54f9cbb3":"newVote(uint256,string)","54fa8044":"sendKrs(address,uint256)","54fac919":"decay()","54fbde65":"USDWEI()","54fbed37":"tokenIsBeingTransferred(address,address,uint256)","54fc85ac":"maxEth()","54fd4d50":"version()","54fef819":"throwsWhenRedeployingANT()","54ffb323":"MaxOffer()","54ffe626":"_getBonusTokenAmount(uint256,uint256)","550052b5":"iaOnInvested(address,uint256,bool)","5502109e":"actualCap()","550271c9":"Candle()","5502be83":"getBountiesByParticipant(address)","55036214":"priceRound2()","5503a659":"smallponzi()","5503d9ba":"numberOfPledgeAdmins()","55042668":"jobStarted(bytes16,address,address,uint256,uint256)","55044042":"CreateGUNS(address,uint256)","5504bf71":"attackerPrizeByToken(bytes32,address,address)","5504f45e":"getFrontEndTokenSupply(address)","5505075b":"validArb(address,uint256)","550538f6":"getOneTimeCosts()","550563ba":"Iscm(uint256,string,string)","55061ccc":"setImageBlurredAt(uint256,uint256)","55064d85":"exists(uint256,uint256,uint256)","5506aa6c":"weiMaximumGoal()","55072fef":"PRIVATE()","5507a82e":"setCalculatorAddress(address)","5507e9c0":"lockForAll(bool)","5509b160":"weightLostPartLimit()","5509f0f3":"minPurchasePreICO()","550b1f48":"eighthTime()","550b47b8":"setCoinPrice(uint256)","550bcd8d":"testThrowUpdateLatestRevisionEnforceRevisions()","550c99c6":"_createCutie(uint40,uint40,uint16,uint16,uint256,address,uint40)","550d8dca":"secondPeriodSupply()","550dd006":"calcCostsBuying(uint256,uint8,uint8,uint256)","550e4f2b":"withdrawRemainingIPCToken()","550ed1f0":"getMaxBetAmount()","550ed61b":"jpyc()","55107916":"distributeMarketingShares()","5510f804":"acceptToken()","5510f8d7":"forkApprove(address,address,address,uint256)","55119b1a":"addBeneficiary(address,uint256,uint256,uint256,uint256)","55121498":"getLenderBalance(uint256)","55126d30":"LogEvent(address,uint256,uint256,string)","5512a353":"BONUSROLL()","5512a8d8":"myohoTest()","551336c5":"prophecise(bytes32,bytes32)","55138534":"Transaction()","55138d97":"addCar(address[4],uint256,uint256)","55139163":"refereesRateBonus()","5513a2ac":"claimByProof(address,bytes32[],bytes32[],uint256)","5513a34e":"getProductHistoryPrice(bytes32)","5514738f":"_packWarriorPvpData(uint256,uint256,uint256,uint256,uint256)","55152b9d":"DxChainToken()","55161913":"charge()","5516b6c5":"SECCoinSold()","55173bb1":"ColaTokenToken()","55176f51":"FOUNDATION_POOL_TOKENS_VESTED()","55177ef1":"addressCoreSupply()","55181fba":"TEXBToken()","55186c99":"auditorCanWithdrawStake(uint256,address)","55189100":"payRewards(address,uint256)","551a450a":"tokenIdToListing(bytes5)","551cacfd":"extractEther(address)","551dc401":"StateChanged(uint8)","551e2e39":"changeDefaults(uint256,uint256,uint256,uint256,bool)","551e44ca":"withdrawTokenForUser(uint256)","551e4c27":"setPeggleBot(string)","551e6ba6":"BoardRoom(address)","551ef860":"newRole(bytes32,address[])","551f3108":"versionSelectors(bytes32,bytes32,address)","551f8e2a":"add(address,address,uint256)","5520002a":"viewSharesSold()","552033c4":"RAY()","552079dc":"fallback()","55207a07":"changeMood(string)","55212c89":"seeleToken()","55219d5a":"tokenAllowed(address)","5521d17b":"betOnColor(bool)","552200f5":"check_part_location(uint256)","55234ec0":"remaining()","5523ec91":"fghcoin()","552405b0":"createCommunity(string,string,string,string,uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","55241077":"setValue(uint256)","55247a52":"wantToBeWhale()","5524defd":"onPayoutFailure(address,uint256)","552548b5":"setMaxDiscountPermille(uint256)","55258a11":"updateAllScores()","5525d87f":"setOracleQueryType(string)","55265669":"showSupply()","55274378":"updateInterCrypto()","55291dbd":"claimEther()","552984b3":"stabilize()","552a41a3":"getRemainingBountyTokens()","552a6915":"getGood(uint256)","552ac31e":"prod(address,bytes32,uint128)","552b71aa":"executeDistributeCapital(uint256)","552c190e":"_DoubleDown()","552d2d5c":"getPerson(address)","552e387d":"XBVHandler(address,uint256)","552eb9e2":"ETStarPresale(address,uint256,uint256)","552f1270":"startWeek(address,uint8)","552f27f5":"setupEventsAdmin(address)","552f8224":"fechAllForCandidate()","552fee9d":"airdropTokens(address,uint256,uint256)","55302ebd":"hasUnionId(bytes32)","5530c519":"validate_pko(address,bytes32,bytes)","5531680c":"transferableBlock()","55325d87":"prizeWinners(uint256)","55326893":"setPOOL_edit_24(string)","5532edf2":"autorizadoraNuncaAutorizouCandidata(address,address)","5533639e":"toB32(bytes,uint256,bytes32,bytes)","5533ffad":"setUserNotifications(bool[],bool,uint8[],uint8)","5534236e":"AirDropPromo(string,string)","55347cce":"Setuppackagesale(uint256,uint256)","55348d9b":"addBeneficiaryVestor(address,uint256,uint256,uint256,uint256)","55352638":"updatePresaleMaxWei(uint256)","553543c5":"tokenSoldPreSale()","553594e4":"getActionHistorySize()","5535cd2f":"setPOOL_edit_1(string)","5535e7a8":"GameCreated(address,address,uint256,uint256,bytes32)","55367ba9":"pauseSale()","55368442":"removeMetadataObject(string)","5536deb6":"finalizePhase()","5536e2d6":"OCTACrypto()","5537f0ef":"betFinalize(uint256,uint8)","55380ed8":"GOOGToken()","5538210e":"tokenSweep(address,address)","5538689c":"changePartner3(address)","5538c964":"getPartnerInfo(uint256)","55390b0d":"PrestoToken()","5539a9c2":"refreshPublicFundingPersonalEthLimit(uint256)","5539d400":"authorizedAddress()","553a48fd":"isFunctionRemoveAuthorizedAddress(bytes)","553a5c85":"mintedTotally()","553a90b8":"updateStopGameOnNextRound(bool)","553aaafe":"MSPPlaceHolder(address,address,address,address)","553b196f":"setPurchasingPaused(bool)","553b6975":"setAmbassador(address)","553b6f83":"lastOracleFee()","553b74aa":"getNumberWallets()","553bf56d":"accept(uint256,string,uint256)","553c02ec":"getCountryBet(uint256)","553c6de9":"getPreIcoInvestor(uint256)","553cc48d":"Player(string)","553cd9c6":"MLC()","553d0d12":"transferTokensThroughProxy(address,address,uint256)","553df021":"deal()","553eb4db":"registerRewards(address[],uint256[],uint256)","553ec6be":"batchCancelSale(uint256[])","553f4fb3":"requestRand()","553f9157":"completeSale(uint256,uint256)","553fd043":"setMoneyRange(uint256)","553fd8ee":"ALLOC_FOUNDATION()","5540e6c1":"iMMCoinsellPrice()","55416e06":"voteA()","5541b817":"_leftChild(uint8)","554249b3":"delegateIncreaseApproval(address,uint256,address)","55426bad":"processPresaleOrEarlyContributors(address[],uint256[])","55427b42":"getBalanceofModifiedWeth()","5542f680":"retrieveToken(uint256)","55434bc9":"ToggleFreezeSelling()","55456f58":"maxcap()","554571db":"updateNarco(uint256,string,string)","5545f12b":"OnChainOrderBookV013bFactory()","5545f584":"soldForForth()","554600fa":"setOraclizeTimeTolerance(uint256)","554644d5":"_removeHolding(bytes12)","554652ce":"airdropToken(address[],uint256[])","554680f2":"updateActivation()","5546a12c":"setInformation(string,string)","5546e1ab":"getMyRefund()","554803c7":"RTCCOINTOKEN(uint256,string,string)","55485779":"minGas4Accts()","5548c837":"Deposit(address,address,uint256)","554917f5":"processMyRefund()","55491da8":"distributeJST(address[],uint256,uint256)","55494d1e":"fillBuyOrder(address,address,uint256,uint256,uint256)","5549563c":"claimManyTokenFor(address[])","5549ce5e":"WarriorSanctuary(address,uint32[])","5549ce6d":"ticketTransfersPerAmount(uint256)","5549f46c":"CustomerInsert(string,address,string,int256)","554a854e":"TransferCryptibles(address,uint256)","554ad7ff":"queryNTVUs(uint256,uint256)","554bab3c":"updatePauser(address)","554d0429":"getArrBoolField2()","554d184b":"getPrices(address,address[],address[])","554d27ca":"createOffer(address,uint256,uint256,bool,uint256)","554d578d":"getCap()","554d758e":"houseStatsOf(address)","554dbfc2":"EMISSION_FOR_SALESTAGE6()","554e6c61":"getTargetBNumber()","554ed8b6":"escrowTransferList(uint256)","5550e4f3":"blackBoxAddress()","5551b6b6":"isDelegateEnable()","5551d1b7":"isAllowToIssue()","5552a483":"newOffer(address,uint256,string,uint256,uint256)","5552d1cb":"prizeIncr()","55532953":"LOCKED_ADDRESS()","5553dc1e":"THToken()","55540004":"createCampaign(address,uint256,string)","5555d6d6":"exist(uint256,address)","55560fd5":"mLoadAndReturn(address)","55566036":"getGamePool(uint256)","5556db65":"totalMined()","5556f3f6":"RareCards()","55575ddb":"setRevokeAddress(address)","55589cdd":"addressOf(address,string)","5558e1c3":"setMinToken(uint256)","555984fd":"cancelMintRequest(uint256,string)","5559d8d9":"getClamTax()","555aaff6":"calculate_range_attempt(uint256,uint256)","555ab116":"AhooleeTokenSale(uint256,uint256,uint256,address,address,uint256,uint256,uint256)","555ae2c6":"STQPreICOBase(address)","555af8f4":"addressFundHolder()","555b6162":"allBalances()","555be5bd":"assignNewPlanet(address,uint256,uint256,uint256,string,string,string)","555befa8":"set1RoundTime(uint256)","555c4758":"distributeTimelockedTokens(address[],uint256[],uint256[],uint256[])","555d8e3c":"_printACourse(uint256)","555db767":"test_2_accessRestriction_newProposal_shouldThrow()","555e6582":"executeMintProposal(uint256)","555ea48c":"becomeHost(bytes32,uint8,bytes32,bytes32,string,string,string)","555f323a":"totalBurnedTokens()","555f498a":"getInvestorsTokens(address,uint256)","555fe48a":"batchTransferFrom(address,address,uint32[])","55605eee":"claimTokenReserveEcon()","5560ada8":"rateAddress(address,uint256)","5560d365":"horseShoeForSale(uint256,uint256)","55616107":"setCOOAddress(address,address)","55619911":"emergencyTransfer(uint256,address)","5561c0e2":"registerChain(bytes8,uint256)","5563d919":"cancelCraftingAuction(uint256)","55642be7":"getRoundBets(uint16)","55642cf9":"CappedBonusSale(uint256)","55642e53":"blacklist(bytes32)","5564a08e":"setGame()","5565ca9d":"buyShip(uint16,uint16,uint8,bytes32)","5565ee7a":"exchangePointToCoin(address,uint256,string)","556665db":"expireTimeLimit()","55674064":"totalSupplyWithoutDecimals()","55674efe":"BondkickToken(string,string,uint8,uint256,int256)","55684aa6":"originBurn(uint256)","55688000":"burnIndexedFromByAddress(address,address,uint256)","5568fd5d":"icoPhase2End()","5569e58c":"EthereumPocket()","5569f5d0":"preSaleFinished()","5569fc0b":"CreateSale(uint256,uint256,uint256,uint64,address)","556a3689":"mint_Crowdsale(address)","556b22c1":"get_record_count()","556b6384":"removeBlacklistDestroyer(address)","556bcece":"reinvest_color(address,uint256,uint256,uint256)","556cbc03":"setDefaultWhitelistVestingParameters(uint256,uint256,uint256,uint256,uint256)","556d5139":"getAverageTokenPrice(address)","556db16a":"validatePurchase(address,uint256)","556e2eb9":"TBL4TokenSale()","556e56d1":"BurnupGameFinance(address)","556e6edc":"indice()","556ed30e":"deactivated()","556f0dc7":"granularity()","556fe562":"notEqual(bytes32,bytes32,string)","55710346":"createTokensFromOther(address,uint256,address)","557119db":"withdrawForCharity(address)","5571954d":"_distributeRegistrationBonus(address)","55728d04":"setIssuer(address,uint256)","5572f9c6":"exchangeEther(uint256)","55737391":"LBRSMultitransfer(address,address)","5573a34c":"FP_SCALE()","5573c582":"walletTransfer(address,address,uint256)","5574cff5":"LOVEYOUFOREVER()","55764c81":"updatedTokensPerEth(uint256)","55765e9a":"createMeme(string,uint256)","5576af7d":"TransactionConfirmedAfterDispute(uint256,uint256)","5576b791":"transferWithVesting(address,uint256)","5577e89f":"testEqualityUint()","5578b51e":"CorelliCoin(uint256,string,string)","5578d24e":"addOldPresidents(uint256[],address[])","5579996d":"CHW()","5579ac74":"dna3(uint256)","5579ff8e":"walletBlogs()","557b0dc9":"addCar(string,string,string,uint16,string)","557bed40":"SocialMediaPayToken()","557d0195":"SuomenMarkka()","557d0479":"aidrop(address[],uint256)","557dc796":"endRoundSeed()","557ed1ba":"getTime()","557f4bc9":"changeContractOwnership(address)","557f9ea6":"aDeposit(uint256,uint256)","557feee1":"setRegionCurrentImageId(uint256,uint256)","5581004d":"createThrone(bytes,uint256,uint256,uint256,uint256)","55810d11":"appFund()","5581800c":"isCappedInEther()","5581be8d":"privatePresaleSupply()","558225fc":"setAtomSons(uint256,uint32)","558234f0":"USD_PURCHASE_AMOUNT_REQUIRING_ID()","5582c08d":"startMonarchyGameReward()","5582df33":"performInitialAllocations()","558305f9":"isFreezeEnabled()","55832ffc":"purchaseStartTime()","5583318a":"TOL()","55838881":"STAGE_ONE_BET_LIMIT()","55843fda":"getAdOwner(uint256)","5584c4f9":"getActiveProposals()","558599ea":"SQR_TOKEN_DECIMALS()","55866c8d":"isRefunded(uint256)","55869af1":"fromVersion()","558790d8":"testInitialTokenBalanceShouldBeZero()","5588227e":"restCrowdSaleAddress(address)","55889d01":"setMaxLockPeriod(uint256)","5588b929":"streamerContract()","558a8f47":"sendFutureSupplyToken(address,uint256)","558b5aab":"setSellingToken(address,uint256,uint256)","558da2e3":"preSaleprice()","558e223f":"_buyPutToOpen(uint256,uint256,uint256,uint256,address)","558e44d3":"MAX_FEE_PERCENTAGE()","558f285f":"unsetMyIdentity(uint256)","558f46c8":"getZTKChecks()","55909da3":"spreadTokens()","5590e4d2":"toBytes32(bool)","55915b97":"initialSuppy()","55923471":"fiveHourCap()","55923cc5":"ElementToken(string,string,uint256,uint8)","5592d687":"settleBounty(uint128)","5592fc71":"getLotteryWinners()","55947d16":"XJJ()","5594e88c":"delegateToken(address,address)","559510d8":"left53(uint256)","55951e15":"dollarToLoveyRate()","55954b49":"initVesting(address,uint256)","559659fa":"getTotalRefund()","55976b05":"depositNotification(uint256)","5597801a":"addwhitelistedBatch(address[],address)","5597e9dd":"setCompte_36(string)","5597f3a5":"createRecord(string,uint256,address,string,string,string)","5598c576":"reveal_move(bytes32,uint8,bytes32,bytes32)","5598f8cc":"getCampaign(uint256)","559ac092":"getAirdropIdsByContractAddress(address)","559b0432":"yearCap()","559b0ed5":"giveBackOwnership(address)","559b1df4":"TokenStoreUpdated(address,address)","559b678c":"IsLimitPart(uint8,uint256)","559e5e06":"updateTokenAge()","559ec80d":"settleDeposit()","559ed339":"setTokens()","559f05dc":"canTrade(address)","559fb6f5":"assertAvailable(uint256)","559fd7ee":"setYearOneMultiplier(uint256)","55a01845":"forceFinished()","55a05335":"totalDragonLotteryNumber()","55a129bd":"Tier(uint256,uint256,uint256,uint256,uint256,uint256)","55a36746":"newDigitalContract(string,address[])","55a373d6":"tokenContract()","55a392ac":"ExerciseEndTime()","55a3f425":"getBalanaceOf(address)","55a53ed0":"EtherSteem()","55a5a8d4":"DHUBTest02()","55a5dc3c":"SpegniCassaAutomatica()","55a5f702":"right45(uint256)","55a6b827":"setPrices(uint32,uint32)","55a85240":"random(bytes32,uint32,uint256)","55a964a7":"distributeALLY(address[],uint256,uint256)","55a9794a":"extract(uint256,uint256[])","55a9a87c":"fightMonster(uint16,uint8,uint8)","55aa8ad4":"Filesystem()","55ab314e":"setOrders(uint224,uint32,uint8,uint8,uint64,uint64,uint64)","55ad798f":"removeRobot(address)","55ae603e":"sell(uint16,uint16,uint8,address,uint256)","55aea767":"batchClaim(uint256)","55aed629":"SpinnersByAddress(address,uint256)","55af5c59":"editBalanceOf(address,uint256)","55afb12d":"isStbMintedForStaEx()","55afee43":"validateKYC(address,bool)","55aff5ba":"minTokParticipate()","55aff703":"updatedBet(uint256)","55b09c58":"myuseOf(address)","55b1182c":"stakeholdersPoolAddress()","55b12570":"TransferError(address,uint256)","55b1aa23":"DEEPPASA()","55b23f4c":"econVestingStages()","55b2bb0f":"MIN_FUND()","55b32c83":"sendFoundation()","55b37685":"balancePreSale3()","55b4bb4b":"HeavyLitecoin()","55b4f231":"vestTokensDetail(address,uint256,uint256,uint256,bool,uint256)","55b5ec64":"proceeds()","55b62dcf":"getThresold(uint256)","55b6ec79":"endCall(bytes32,uint256,uint8,bytes32,bytes32)","55b6ed5c":"allowances(address,address)","55b700af":"PRESALERATE()","55b71344":"FlexibleToken(string,string,uint8,uint256)","55b726bc":"adjustRate(uint256)","55b72f38":"getLongitude()","55b775ea":"setFeed(address)","55b8415e":"processReward()","55b860e1":"_updateDiscount(uint256,uint256)","55b8ef5e":"UserInfo()","55b93031":"minNumber()","55b954ad":"getRestTokenBalance()","55b9b9cf":"PXLToken(uint256,uint256,uint256,address,address)","55b9ca40":"withdrawCell(uint256)","55ba13da":"VaN(address)","55ba343f":"getMarket(bytes)","55bb34e5":"enableEmission(bool)","55bc0f07":"returnLongTokenAmount(address[3],bytes32)","55bc8725":"bannedAddresses(address)","55bcaf06":"halfMultiplier()","55bdd4ac":"offerCatForSaleToAddress(uint256,uint256,address)","55be1168":"view42()","55bf3dbb":"OrangeToken()","55bf5656":"crowdfundStartDate()","55bfe5b1":"chfRate()","55c01345":"coupon()","55c081d4":"setTier(address)","55c0a5f4":"appendSource(address[],uint256[])","55c1743d":"SEOS(uint256)","55c1e611":"cancelBets()","55c208ad":"TimeDecayingTokenBoundaryRange(uint256,uint256,uint256,uint256,address)","55c28ed0":"zeuscoin()","55c2a0ac":"addQuantity(address,address,uint256,uint256)","55c33624":"mock_set(address,address,uint256,uint256)","55c39193":"removeBoardOnUser(address,address)","55c47867":"withdrawTokensForCloudexchangeTeam(uint256,address[])","55c4a8bf":"vig()","55c4b226":"pushUpdate()","55c4c5b3":"Cartycoin(uint256,string,string)","55c4e704":"enableAgency(address)","55c60500":"setRemainAirdrop(uint256)","55c623c6":"bidEth(uint256)","55c64ce1":"resetReward()","55c797ce":"setBonusWallet(address)","55c79f49":"payToEvaluator(uint256,uint256)","55c81595":"raffleState()","55c81ae9":"recipientContainer()","55c8c6fd":"tokensSupplied()","55c94f04":"closePosition(bytes32,uint256,address,address,bytes)","55c9e290":"DOI()","55ca92f8":"createBallot(uint256,uint256,address,string)","55cacda5":"minimumEpochInterval()","55cb155a":"WebcoinToken(uint256,address[])","55cb61ca":"EthTransferContract(address)","55cc4e57":"setIssuer(address)","55cd1915":"GA_chain()","55ce15f4":"transferAmount(address,uint256,uint256)","55ce3b9a":"setFundWallet(address)","55ce596b":"flowingHairAddress()","55ce76e6":"feeAmountThreshold()","55cf1008":"numberOfValidPartners(uint256,uint256)","55cf969d":"transferReverseProxy(address,address,uint256,uint256,uint8,bytes32,bytes32)","55cfa833":"clientmanager()","55d0012d":"signupUserWhitelist(address[],uint256[])","55d04877":"_payRefund(bytes32)","55d13efe":"sha_data_group(int256[],int256)","55d17201":"OHC_Crowdsale(uint256,uint256,uint256,address)","55d17251":"CROWDSALE_CAP()","55d1b4d3":"softCapPrice()","55d1c5c7":"getEuroCollected()","55d1f799":"triggerSkill(uint32[11][32],uint8[32],uint8[4][31],uint8[3][3][31],uint8[5][11][32],uint16[11][32],uint32[3][11][32])","55d28f20":"configure(address,address,address)","55d374e9":"setPrices(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","55d39bc0":"setETHPriceUpperBound(uint256)","55d4956f":"setEndSaleDate(uint256)","55d55a76":"isActionAccount(address)","55d56ddd":"_adoptAxies(address,uint8,uint256,address)","55d595d1":"rollbackContract(uint256,address)","55d66c3e":"getMarketOrderWorkerpoolOwner(uint256)","55d67ba0":"Begin(string)","55d6d06e":"XIDToken()","55d6f3c0":"Telephone()","55d72a7d":"ActionStarUp(address)","55d7592d":"emergencyETHDrain()","55d79248":"miningTenPlat()","55d7fe2b":"RATE_SALESTAGE5()","55d8bbd5":"beginSell()","55d9275e":"payMoneytoAuthor(address)","55dac078":"SecuredNotes()","55daf6e6":"setInitialOwners(address[],uint256[],uint256[])","55db4092":"setTOS(address,bool)","55dc3b65":"DAVCoin()","55dd16cd":"CrowdsalePhase1(uint256)","55dd574c":"startPreSale()","55dd8171":"bbFounderCoreStaffWallet()","55ddc9f0":"mainSaleFirstStartDate()","55de28ae":"burnBadge(uint256)","55de5a93":"getCurrentEdition()","55de97ac":"OBR_Duration()","55deb8fc":"tell(uint256)","55df34f2":"leftOverTokens()","55dfb430":"Test1(int256)","55dfc97c":"limitSupplyPerYear()","55e0aece":"getListingService(uint8)","55e1726c":"LogSetStageStartTime(bytes32,uint256)","55e17544":"Tardis()","55e21474":"firstRoundCosmosTokensLimit()","55e2305e":"preauthorize(address)","55e37cec":"discountRatePreIco()","55e38f9b":"canAddNewClient(address)","55e3f086":"startRound()","55e40d98":"updateItem(uint256,string,uint256[6])","55e447aa":"queryBalanceOf(address)","55e46476":"createA()","55e61dcd":"operationsInQueue(uint256)","55e6b18e":"victorieumStaticToken()","55e6fc50":"deposit_fee()","55e79d29":"regex()","55e7a663":"setLowerPricePercentage(uint256)","55e7db94":"GBCToken()","55e97e93":"closeGenesis()","55e9c358":"weekLength()","55e9caa1":"log_move_fees(address,address,uint256)","55ea14f2":"atomicxSupply()","55ea2cf3":"GameBit()","55eb27c8":"getActualUserTokenBalance(address)","55ebcc83":"Market(bytes,uint256)","55ec4da9":"VaultMint(address)","55ec671a":"canBet()","55ee684d":"initLogo()","55ee6afb":"Wallet(address,address)","55eed9de":"developerFunds()","55ef2913":"isOperatorAuthorizedFor(address,address)","55efe565":"Caligula()","55f03816":"orderOnSaleAuction(uint256,uint256)","55f0690d":"transferAndLockMulti(address[],uint256[],uint256[])","55f0d02c":"ResidualValue(uint256,string,string)","55f13278":"presaleTokenCreationCap()","55f14c30":"minter2()","55f150f1":"desc()","55f1a3c8":"disableTokenSale()","55f21eb7":"getProvider(address)","55f25e3f":"getLavaTypedDataHash(bytes,address,address,address,uint256,uint256,uint256,uint256)","55f28260":"getOwnerAt(uint256)","55f29166":"cancelUpgrade()","55f2dcb2":"GouBi()","55f2de40":"abioSold()","55f39677":"phase2WeiRaised()","55f3c49c":"bookrequest(uint256)","55f413c9":"presale3_startdate()","55f48a46":"CUSTOM_ERC20_BURN_SERVICE_NAME()","55f54552":"setPaySize(uint256)","55f57510":"positions(address)","55f5856f":"transferToLimited(address,address,uint256,uint8)","55f6a412":"modify_NovumAddress(address)","55f78af8":"getLockBalance(address)","55f804b3":"setBaseURI(string)","55f82589":"tryExec(address,uint256)","55f86501":"exec(bytes)","55f92d23":"privateSaleContribution(address,uint256)","55f953e6":"getTokensCountOfUser(address)","55fa1348":"minimum_donation()","55fb8cee":"userCountsInAccount(uint256)","55fb9765":"UniversalGamingCoin()","55fbc8c2":"UpdateEthBalance(uint256,uint256)","55fbf10e":"PanterX(uint256,string,uint8,string)","55fe13ea":"setBuyingEscrowAddress(address)","55fecb0b":"payTheWinner()","55ff440a":"castStringToUInt(string)","55ff85c3":"returnBet(uint32)","56000acf":"processPayment(address,uint256,bool)","56003f0f":"createTemporary(bytes32)","5600e827":"elapsedMonthsFromICOStart()","5600f04f":"url()","5601477b":"addMilestone(uint256,uint256)","5601da3d":"innerTransfer(address,address,uint256,uint256)","5601eaea":"execute(uint256,uint256)","56025c9e":"DatareumCrowdsale(address)","5602a812":"sumICOStage5USD()","5602c05f":"AREF()","560334c6":"angelPool()","5603a50d":"checkVesting(uint256,uint256)","5603ac35":"NewBudget(address,uint256)","5603b9f9":"registerReferral(address,address)","56048edc":"getThresold()","56049a86":"riddle()","5604af49":"battleProvider()","560667f1":"setDocToAddress(address,bytes)","56075a98":"becomePlayer()","56078480":"GoneTrippinToken()","560791a9":"returnHolder(uint256)","5607a548":"m_ownerIndex()","5607f324":"checkLicense(address,address)","5607f408":"freezeTokens(address)","56084329":"SAATCoin()","5608b6d9":"changeprivatebonus(uint256)","5609825e":"partyOwnsAsset(address,address,string)","56098295":"getCandidateVotesByIndex(uint256)","560a665a":"buyTokensByReferrer(address,address)","560bb612":"SignatureValidator(address)","560bd3ec":"addCollaborate(uint256,address,bytes32,uint256)","560cb0a5":"SikobaContinuousSale(uint256)","560d3ca5":"toEXTwei(uint256)","560ecab5":"setSellCeiling(uint256)","560ed6a1":"refundEther()","560ef1bf":"getLockedToken(address)","560f5d4b":"currentStateSales()","561015e2":"notEqual(uint256,uint256,string)","56104861":"addEjariRule(string,string,uint256,uint256)","56105a08":"DgxSwap()","56111751":"respond(uint256,uint256,bytes32)","561187ae":"russianBounty()","5611bf3e":"AlerterAdded(address,bool)","56129134":"createPromoKitty(uint256,address)","561296e4":"GetReferralDataOfAddress(address)","5612acd3":"getScenariosInfo(bytes32)","5612e139":"getWebsite(address,uint256)","56131736":"wcf(address,uint256)","561337eb":"contractMessage()","5613680a":"whitelistInvestors(address[])","561387b1":"setPrice(string,string,string,uint256)","5614678c":"calculateDayOwnerCut_(uint256)","5615f415":"q2()","56161605":"TestGOATToken()","5616cafd":"setGasForCLI(uint256)","5616f7df":"getHatchCooldown(uint256)","5617fb0d":"TKDToken()","56189cb4":"approveInternal(address,address,uint256)","561960b5":"activateStartBlockOf(address)","56196d87":"pickReward(uint256)","56196dc9":"getTagByModuleType(uint8)","561a0d65":"serviceClaimOwnership()","561a28df":"market2018TokenCreated()","561a4873":"buyAd(string,string,string,uint256,uint8,address)","561b1d72":"iDeal()","561bbe1e":"getluckyprize()","561cce0a":"LONG()","561cd462":"balanceOfETH(address)","561e91a1":"makeBet()","561ef5b6":"for_sale()","561f1ba1":"sendToken(address,address,uint256,uint256)","561f39c0":"getGameMaker()","561fe29c":"createDeposit(address)","56200819":"updatePayoutAddress(address)","5620d1d7":"lastCompleteEpoch()","56216916":"changeFinishSale(uint256)","5621df99":"ESMBCoin()","5622d195":"SvEnsRegistry()","562328ec":"LogBidConfirmed(bytes32,address,bytes32)","5623715b":"updateUpgradePoll(address)","56238b02":"setTokensPerEth(uint256)","56240b38":"PalestinePound()","56242e07":"customerDeposit()","56247e6d":"createKingdom(address,string,string,uint256,bool)","5624e064":"makePurchase(address,uint32)","562557f7":"accountsUsed(uint256,uint256)","56257ae1":"getFUTTotalSupply()","562605f1":"refundOn()","56264d6c":"setMaxTickets(uint256)","5626e246":"Stage2Allocation()","56277619":"setFiatRaisedConvertedToWei(uint256)","5628d443":"BTYCT(uint256,string,string)","5628fc09":"initialize(address,address,uint256,uint256,uint256,uint256,uint256,address,address,address,address,address)","5629365b":"playerWithdraw(uint256)","5629c69e":"ArtBC(uint256,string,uint8,string)","5629c6d9":"doExecution(address)","5629e70b":"NobarToken(uint256,string,string)","562b2ebc":"orderCalldataCanMatch(bytes,bytes,bytes,bytes)","562bde28":"transferMyName(address)","562bfb9f":"getAllCardsModifier()","562c45da":"withdrawDragonsPrime()","562c4784":"targets(address)","562c82ec":"aboveSevenBets()","562c9dfa":"test2_verlappingIntervalNewNode()","562cad23":"startCycle()","562cb622":"setAffiliateLevel(uint256)","562cc70c":"minWeiWhitelistInvestment()","562d4570":"refundStart(address,uint256,address)","562df3d5":"COMMISSION()","562e9df9":"addressTeam()","562ea884":"Explain()","562fa0df":"deposit(address,address[],uint256[])","56304e33":"addBalanceBlocks(address)","563183fc":"maskerOf(address)","56318820":"setTokenSwarmHash(address,bytes)","56323b5d":"BenderCoin()","5632b1fa":"payrolls(uint256)","56330403":"getDocsCount(string)","5633af60":"HeliumNetworkAddress()","5633c442":"lockedUpCount(address)","563433d7":"setStock(address)","5634653d":"verificationCountInt()","5634c88c":"sumOfNGeom(uint256,uint256,uint256)","563540a2":"startQueueing()","5636548f":"enableWithdrawal(bool)","56378983":"validTokenAmount(uint256)","56387fa3":"toogleMinting()","56394455":"getStageStartDate()","56397c35":"ledger()","5639bb3c":"buyPriceEth()","5639d152":"NewRC(address)","5639eb64":"IngridIsAHorribleHumanCoin(uint256,string,uint8,string)","563ad62b":"ConfToken()","563b1358":"approvePack(address)","563b54b9":"getQueuesLength()","563baca1":"fundForBounty()","563bd001":"tokenPriceForPreICO()","563bef94":"ShipSellMaster()","563bf264":"slash(address,address,address)","563c23a0":"timePaused()","563c78b0":"SendPreReserved4()","563ed6d0":"delAdminAddress(address,address)","563fce0b":"mappings()","56410637":"ethernautsStorage()","56411a0f":"ChrizzxToken()","56412d85":"getVote(uint256,uint32)","56416147":"getopenDdaListAssets()","56423986":"DecreaseTheAllowance(address,uint256)","56430201":"InvestmentMade(address,uint256,uint256,string,bytes)","5643a711":"increaseMonsterExp(uint64,uint32)","56442869":"destroyCrowdsale()","56447520":"dteamVaultAddr4()","56451bc2":"removeBalances(address[],uint256[])","564566a8":"isSaleActive()","5646435b":"burnTokens(address,address,address,uint256)","564952d5":"trickleSum()","5649efbc":"superFeed()","564a187f":"getPopRemainingAsFixedPointForGameId(uint256)","564a565d":"disputes(uint256)","564a6b94":"cos(uint16)","564ad142":"testSubItem(bytes,uint256)","564ca533":"setRelayedMessages(bytes32,bool)","564e406f":"changeAgencyOwner(address)","564ef91d":"PRNG()","564f8d23":"rightmost_leaf(uint256)","564f9728":"get_row(uint256,uint256)","5650e5e0":"Couchain(uint256,string,string)","565118f7":"lockReleaseDate2year()","565135ce":"removeUsersWhitelistB(address[])","5651ce38":"priceStepDuration()","56522390":"addEditTokenFee(bytes8,uint256,uint256)","565287c9":"votar(uint256,bytes32)","5652ced0":"OpnMind()","5652ec7e":"GnosisIssued()","5653de64":"tokenSold(uint256)","56544af0":"taxTillNow()","5654a341":"gameIndex()","5654b526":"sumHardCapICOStage8()","5654edb8":"btcUpdates(uint256)","56553a95":"transferIssue(address,uint256)","5655c490":"setProviderCurrentRate(uint256,uint8)","5655e37b":"CONTRIBUTION_MAX_NO_WHITELIST()","56570671":"GetContractStageLiving()","565707a8":"getDErc20(bytes32)","56575bd7":"setParticipateDailyLootContribution(uint256)","5658d212":"getFactoryForCountry(string)","565974d3":"details()","56597e65":"circulationCap()","5659856c":"addApprovedAddresses(address[],uint8)","565a2e2c":"getBeneficiary()","565a2ecf":"classicTransfer(address)","565a7c4c":"epm_system()","565af6a8":"referralRegistration(address,address)","565b3324":"intMin()","565cee48":"ALLOC_ILLIQUID_TEAM()","565e2220":"view24()","565e4fa1":"subtractScalar(int256[],int256)","565eab8e":"TransferMyGGTokens()","565ed5a2":"LogMigrationFinalized(address,address,address)","565f2da9":"lockTokensForTeamAndReserve(address)","565f3624":"testArgOutOfBoundsFail()","565fd2a7":"registerCoinData(address,uint256,uint256)","5660000a":"tokenRewardRate()","566038fb":"cancelTransferRight(address)","56605326":"DTFCToken()","56610400":"Proposals()","566150a3":"GenerateTokenContract()","5661ba15":"setDungeonTokenContract(address)","5661bcd8":"saosao3()","56624ce6":"minVoteWeightK()","56630bce":"KycVerified(address,bool)","56632637":"node_dupes(uint256)","5663896e":"setSecondsPerBlock(uint256)","56639a8e":"fixUSDPriceTime()","56639ef6":"PikewoodFund()","56640afe":"getCampaignLength(uint256)","5664a5a3":"MonsterCreatorInterface()","5666496a":"_applyForCertifation(string,uint256,bool,string,string,uint256)","5666da53":"RYXEX(address,address,address,uint256,uint256,uint256)","566735d8":"PreVNK(uint256,string,string,uint8)","5669c94f":"issueToken(address,string)","566a3cb5":"getTokensHolder()","566b28f0":"m_tokenDiscountThreshold()","566bbee7":"EventCentsPerTokenChanged(uint256,uint256)","566bd6c3":"offerSigner()","566c20fc":"writeMessage(string,string,string,string)","566c23ad":"setLock(bytes32,string)","566c37de":"teamTokenHolder()","566c8ed2":"TCI_client(bytes32,address,address)","566da66c":"OwnableContract()","566dccf4":"enableSaleAgent(address)","566dd702":"chargeAdvertiser(address,uint256,uint256,address)","566e638e":"createCard(address,uint16[5],uint16)","566e78fe":"TokenDistributionMock(uint256)","566eebd8":"test_claimShares_emptyRewardPool_notTranscoder()","566f4ac5":"payMasters()","566fc6de":"getProfitPercent()","566fca87":"GazpromCoin()","5670d6f1":"stopAirdrop(bool)","5670ef72":"setConfigs(bytes32[],uint256[])","56715761":"minDuration()","567188da":"getTotalBuyBySkull(uint256)","5671ec30":"totalCardCount()","5672f548":"physicalString()","5674a3ed":"runLottery()","5675527f":"EtherIco(address,uint256,uint256)","5675db9c":"setShouldGenerateDna(bool)","5675ef9d":"BetPlaced(bytes32,uint8,address,bool,uint256,int32)","56765c51":"WITHDRAWAL_WINDOW()","56768538":"registerForeignAddress(address)","5676d075":"hardCapETHInWeiValue()","56780085":"TOKEN_DECIMAL_MULTIPLIER()","56782e5b":"hplus(uint256,uint256)","5678494f":"ProvePrivKey(bytes32,uint8,bytes32,bytes32,bytes32,bytes32,address,uint256)","5678524f":"nextBuyoutPrice(uint256)","5679623b":"initializationDelay()","567990ae":"LogNoticeMsg(address,uint256,string)","567a03a7":"grantBurner(address,bool)","567a0f35":"testHitSoftCapPreDistribute()","567a9c79":"claimedBountyTokens(address)","567c08e2":"set_minFinneyToKeep(uint256)","567c31f7":"taxEarningsAvailable()","567c5b70":"getTicketParticipant(uint256)","567cc2b6":"setProduction(uint256)","567dbf18":"__forward(address,uint256,uint256,bytes)","567e75c4":"getLoanState(uint256)","5680a3ad":"childExists(address,uint256)","56813535":"const_contract_eth_value()","56814312":"NekoToken()","5681e00b":"getContractMetrics()","56820930":"purchaseMakeCard(uint256)","56826ee6":"receiveApproval(address,address,uint256,bytes)","568287ee":"ShopperlyGlobalToken()","5682d43d":"checkWithdrawAddress(address,bytes32,address)","56833b16":"AYA()","5683a9e0":"LASTTRIAL456()","56841b36":"payToReferer(address,uint256,string)","56845ca0":"updateProposalOwner(uint256,address)","56848c05":"awardMILsTo(address,uint256)","5684c219":"getReportingPeriodDurationInSeconds()","568531cc":"accountRegistryLogic()","5685f6bd":"DELTA_Token()","56860ddc":"GTDNToken()","56861322":"RecievedTip(address,uint256)","56861450":"isAtLeast(int256,int256,string)","5686b54b":"cancelAgreement(uint256)","5687f2b8":"emitApproval(address,address,uint256)","56885cd8":"crowdfunding()","56891412":"totalLocked()","568a2c55":"setNewStart(uint256)","568a8077":"gameResult(uint256,address)","568ab21e":"enter(bytes32)","568b5915":"votesMaskByOperation(bytes32)","568c2163":"END_OF_MINT_DATE()","568d13eb":"calculateRegionInitialSalePixelPrice(uint256)","568d3900":"getAgentIdByAddress(address)","568f57e1":"removeFromApproveList(address)","568f7830":"SECoin(uint256,string,string)","568f910d":"createPost(address,address,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","568f9ce1":"activateDevice(bytes32)","5690d326":"initialize(address,address,uint256,address[],address,address,address,uint256,uint256,address)","5692b273":"finalTier()","5692e367":"decodedExpiration()","5692e54e":"test_0_ensureRegistryFunctions()","5693077a":"registerCampaign(uint256,address)","56930b55":"tokenOperationsFinished()","56939048":"disqualified(address,uint256)","5695dd8c":"FindX()","5695fa58":"getTotalDistributed()","56963c31":"setDistributeAgent(address,bool)","56979da7":"assignmentsClosed()","5698176a":"getPlayersPoints(address)","56982986":"lastBlock_a11()","5698fb44":"getTokenBonus()","56990301":"FoundersVesting(address,address)","56996f6b":"TDESupplyRemaining()","56997fb4":"potReserve()","5699c7b1":"getPendingWithdrawal(address,address)","569a7aab":"isLowercase(bytes32)","569aa0d8":"getPlayerSubmissionFromCompetition(string,uint8,address)","569bf836":"GYTToken(uint256,string,uint8,string)","569c5f6d":"getSum()","569ca935":"_setRolePermissions(address,address)","569d623f":"setEstimatedWeight(uint256)","569eaf61":"isPaidOut(uint256)","569f76e1":"teamOneDivsTotal()","569fa9f9":"releaseRecordsCount()","56a041fc":"exception(address,address)","56a060a2":"isTradingOpen()","56a24be0":"getPositionCallTimestamp(bytes32)","56a3015c":"Generation()","56a3f4ef":"collectMyReturn()","56a49b7a":"getStakeLockedStatus(address)","56a4e7f9":"GetGlobalProduction()","56a61fc4":"_trainPart2(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","56a620aa":"decreaseAfterBurn(address,address,uint256)","56a6d9ef":"transferBalance(address,uint256)","56a70646":"giveBackEthers()","56a7564e":"undistributedTokens()","56a765c4":"whitelistBonusAmount()","56a7b0bf":"Burner(address,address)","56a807d9":"mintvestedTokens(address,uint256)","56a8a270":"competitionAddress()","56a9399d":"YUNXIN3Token(uint256,string,uint8,string)","56a9a68b":"updateAllowances()","56aa3892":"FooContract(address)","56aa772f":"Use_EmergencyCode(uint256)","56aa7cef":"PaymentFinished()","56ab4b5d":"TokenPurchased(address,uint256,uint256,uint256,uint256,uint256)","56abf07c":"giftStar(uint256,address)","56ac1efa":"AcceptsProof(address)","56ad2931":"_moveToken(address,address,uint256,bytes,bool)","56ad41c8":"XandraSupply()","56ad609e":"Addr1()","56ad9f57":"CROWDSALE_SUPPLY()","56ae89a3":"UpdateUserBitFlag(address,uint256)","56af3f2b":"PredatexTiga()","56af4d4e":"AanshuToken()","56afd6e3":"howMuchCanIContributeNow()","56afeed6":"SQUIRREL_BOOST()","56b00cb5":"Horizon0x(uint256,string,string)","56b0443f":"getMarketPrice(uint8)","56b09382":"creditDaoAddress()","56b15308":"deleteProvider(address)","56b1ddbb":"HDT()","56b2c5bb":"doSucceedingTransfer()","56b30aec":"getPendingWithdrawlListCount()","56b30f33":"minAmountForDeal()","56b32da1":"gameStarter()","56b49ef0":"AuctusWhitelist(uint256,uint256)","56b4d760":"getHeroOwner(uint256)","56b54bae":"blockRewardContract()","56b558d3":"kingContract()","56b5d0eb":"_replaceModuleHandler(address)","56b6274b":"verifyEmail(address,string)","56b62e2d":"JetCoin()","56b63df7":"tokenLocks(address)","56b644b0":"changeRake(uint256)","56b6cb70":"foundersTokensWalletSlave()","56b6dbe9":"AustraliavsPeru()","56b7538b":"nextRoundDonation()","56b760f2":"numFabrics()","56b83dc5":"info_Symbol()","56b86bc2":"EtherDogCore()","56b8c164":"getCreatorTAOSetting(bytes32)","56b8c724":"transfer(address,uint256,string)","56b8edf0":"TransferEther(uint256)","56b9a8ab":"tokenSales()","56b9e9de":"getBrehonContract(bytes32)","56bb4d4a":"ICO4Period()","56bb9b43":"getAppCode(address)","56bc0c5e":"UserManager()","56bccf91":"depositTokens(address)","56bd182d":"privateSupply()","56bd928a":"platformLaunchDate()","56bdb5c4":"isMainSaleBonusTime()","56bdc4ae":"TokenLoot(address,address,address,address,address,address,address,address,address,address)","56c11ba3":"priceSelectFight2Death()","56c190ec":"processRefundEther(address,uint256)","56c21897":"PowerCoin(uint256,string,string)","56c23836":"transferDirect(address,uint256)","56c26f25":"getPlayerOwner(uint256)","56c290b8":"t_wallet()","56c2c1f6":"VESTING_TEAM_CLIFF()","56c38b2e":"vestingGrant(address,address,uint256,uint256)","56c3e31a":"mintContract(address,uint256)","56c4339f":"isMainBridgeContract()","56c46ac2":"getLockedContract(address,address)","56c49c2a":"contractFeeMinAmount()","56c4b246":"WrapperLock(address,string,string,uint256,address)","56c4e05a":"_balance()","56c51ea2":"getRestrictionStatus(uint256)","56c5df29":"PCFF()","56c686b1":"getPendingWithdrawl()","56c6a608":"WeBuyAnyHouse()","56c7627e":"tokenLimit()","56c7eb7c":"_destroyTokens(address,uint256)","56c7f461":"refundContributors()","56c82ae5":"sendBalanceForDevelop(uint256)","56c88f5f":"mintAll(address)","56c8c30c":"maxPossibleWithdrawal()","56c8e12e":"refundBalance(address)","56c8eaba":"KRE8()","56ca528f":"right18(uint256)","56ca623e":"toString(address)","56ca7143":"INITIAL_FUND_BALANCE()","56ca8d75":"setBuyingAmountRanges(uint256[])","56cac2e0":"letItRain(uint8,uint256)","56cb6655":"stopTokenMinting()","56cba008":"stopSales()","56ccdadb":"last_roll()","56ccf300":"ToptalToken()","56cd26eb":"Digiblock()","56ce0e6c":"updateMetadata(string,string)","56ce3f5c":"dCoinswapToken()","56ce4bc5":"receiveEtherFromForegroundAddress(address,address,uint256,address)","56ce6377":"WaveVoteContractRegistery()","56cea4b2":"addressFounders1()","56cff99f":"calcGav()","56d0adac":"freeToExtraMinting()","56d0bc9a":"updateProfileEmail(string)","56d13e6e":"setMaxReferrerBonus(uint256)","56d1c866":"getMsg(string)","56d1d4a2":"setExchangeThreshold(uint256)","56d26468":"appBase(bytes32,address)","56d27150":"TheMMORPGToken()","56d2ec1b":"internalBurn(uint256)","56d399e8":"stakingRequirement()","56d3e57d":"_generateRandomNumber()","56d400a1":"approveDispute(uint256)","56d40468":"lockBountyTokens(uint256,address,uint256)","56d44694":"PRICE_4()","56d58452":"containsSender()","56d59777":"setAdministrator(address[])","56d5f541":"_getApprovedAddress(uint256)","56d6cad0":"iFx()","56d73ad1":"getCertifierDb()","56d7bc54":"altCreateTokens(address,uint256)","56d7c0da":"ChooseAwea()","56d7c2c8":"transferERC20Token(address)","56d88e27":"len()","56d89b1f":"AuctusBonusDistribution()","56d906c7":"setBounty(address[],uint256[])","56d95932":"getActualTokensPerEther()","56d9bb9a":"viewAllCertificate(address)","56d9c0e3":"requestReading(address)","56da7743":"getBetsNums(address,uint256)","56da934e":"addTowardsTarget(uint256,uint256)","56daf2c1":"paymentWeiOwed(uint256)","56daf906":"THAW_CYCLE_LENGTH()","56db3df0":"weiForToken(uint256)","56dbc007":"isChild(address,address)","56dcd2fa":"ICO_LEVEL_3()","56ddbe7a":"setVRC(address,address,uint256)","56ddeea2":"getIcoDiscountPercentage()","56ddf404":"Executed(string)","56de9219":"Arina_amount()","56de96db":"setState(uint8)","56dfe628":"viewa2(address)","56e19e6e":"DDNToken(uint256,string,uint8,string)","56e1c40d":"burnFeeNumerator()","56e27ce6":"LuxToken()","56e2eab8":"listAddress(address,uint256,uint256)","56e39c58":"ProtectedTransfer(address,address,uint256,bytes32)","56e3df97":"getGeneration(uint256)","56e40a32":"auctionEthEnd(address,uint256,uint256,bytes)","56e428fc":"LogAccessChanged(address,address,bytes32,address,uint8,uint8)","56e44954":"setExchangeRates(address)","56e49287":"auctionsEndTime()","56e4b68b":"supervisor()","56e4bc1f":"payed()","56e4e073":"TestETHToken()","56e523e2":"OpenSourceChainToken(address)","56e52cbb":"getMinWeiForDInit()","56e567e5":"balanceOfa(address)","56e5cf2e":"setBytesArray(bytes32,bytes32[])","56e5e12b":"fundariaPoolAddress()","56e60a31":"TokenExchangeFailed(address,uint256)","56e62326":"createMultiple(uint256[],uint256[],uint256[],address)","56e721b3":"_getRefBonus(uint256)","56e789eb":"checkTotalSold()","56e7bcd1":"putUsername(string)","56e7f6c7":"layerCount()","56e83e81":"randao()","56e8596f":"grantContributorTokens(address)","56e8b3ac":"PabloPlusToken()","56e8efd4":"EventNotarise(address,bytes,bytes)","56e8f53e":"_crownTotalSupply()","56e97617":"bullcrapToken()","56e9ae71":"OCTCOIN()","56e9d1f3":"deList(bytes32)","56e9ec88":"equipmentItem(uint256[],uint256[],uint256)","56eaf1c0":"commissionPoints()","56eb5a79":"Bags()","56ebb303":"rewardContributors(address[],uint256[])","56ebd52d":"STRAAToken()","56ed8636":"membershipStatus(address)","56eeb3b0":"startAtBlockNumber()","56ef9296":"getMultiRequestFirstRequestId(uint256)","56f10988":"GDCNumber4()","56f1594e":"UpdateMoneyAt(address)","56f19703":"rejectedBookingfc(uint256)","56f1d2dc":"increaseSystemCreatedCount()","56f1dd6b":"ifoodDev()","56f2b308":"GDCNumber2()","56f2eb90":"pendingRewardsToMint()","56f2fc89":"deployIdeas(address)","56f399a7":"getContractInvoices(uint256,uint8)","56f43352":"tradingFee()","56f464ea":"releaseFundsWhenBothSigned()","56f50473":"downPayment()","56f66f4c":"reportResult(uint32[],int8[],uint32,uint32,uint32,uint32,bytes32)","56f6e184":"addToWhitelist(uint8,address)","56f7cafe":"registry_exec_id()","56f91399":"trCut()","56f99fcb":"freezeLottery(uint32,bool)","56fa47f0":"split(address)","56fa9f6b":"allowRating(address,address,uint256)","56fadf8e":"createItem(string,uint256,uint256,address,uint256[6])","56fb46d7":"COOPERATE_REWARD()","56fb8a34":"getPivot(uint256,uint256,uint256)","56fbd029":"Saflok(bytes32,bytes32,bytes32,bytes32)","56fbdca3":"whitelistInvestor(uint256)","56fbf488":"setPrix(uint256,uint256)","56fc35d3":"BunzolaToken()","56fc6dae":"getUpline()","56fcb29f":"selfPayout()","56ff2318":"usersWithdrew(address)","56ff55d1":"_isSchemeRegistered(address,address)","56ff83c8":"crowdsaleWallet()","56ff918d":"getNextKillingAfter()","57006864":"checkBetParity(uint8)","5700cb10":"getMainRemainCoins()","57014fee":"domainOwner(string,string)","57016ded":"transfer_to_reserves(address,uint256,uint256)","57019b37":"setControllerAddress(address,address)","5701ac59":"calculateReferralFee(uint256,uint256)","5701e9c0":"TrustlessTransaction_Refunded(uint256,uint256)","570200c0":"setStarterPack(uint256,uint16)","5702b530":"byteToString(bytes1)","57035b60":"SWIZERStandardToken(uint256,string,uint8,string)","570468f0":"SupportRemoved(address)","5704b927":"ASXC(uint256,string,string)","57056261":"insert(uint256,bytes32[])","5705b612":"getUserId(address,address)","5706d99a":"STAGES()","5707812e":"addToLists(address,bool,bool,bool,bool)","5709013e":"changeToStage(uint8)","570919a6":"retrunError()","5709d7bd":"DevPromotionsMarketingWallet()","570a2a16":"right53(uint256)","570a8496":"uploadData(bytes32[])","570b615a":"tournamentDataIPFSHash()","570bc25f":"makeOrder(address,address[5],uint256[8],bytes32,uint8,bytes32,bytes32)","570ca735":"operator()","570d2f8f":"trustedWallet()","570d31b7":"ConsultaRegistro(bytes32)","570e0db5":"addDestination(bytes32)","570e6729":"getOptionHash(address[3],uint256[3])","570e997d":"gettnode(address)","570f65c4":"getProjectArbitrationFees(bytes32)","570fceb0":"updateHashrate(address,uint256)","570fe8c3":"cancel_payment(uint256)","571080ae":"getMyLobster()","5710ac73":"unlock(address,address[],uint256[])","5710de14":"newProof()","5710ed95":"contractBlock()","5711b311":"executeRemoveAuthorizedAddress(uint256)","571218fa":"priceModel()","57128ec1":"userGrowPoolAddress()","57135859":"BBBToken(uint256,string,string)","57138106":"verifyKyc(address)","5713fcb7":"compatible20()","5714db23":"AdvisoryPool(address,address)","5714e01f":"ownsAddress(string,address,address)","5714f6a1":"getTotalAvailableRelays()","57157189":"getListMarkets(address,uint256)","5715b530":"claimReservedTokens(string,address,uint256,string)","5715c5b7":"getTokenAddressByIndex(uint256)","57163cc3":"initAtx(address,address,address,uint256)","57183698":"addProject(uint256)","57183c82":"instantiations(address,uint256)","5718b760":"withdrawSize(address)","5718b994":"checkEvent(address,bytes,bytes,uint256)","571959e0":"getServiceProvider()","57199334":"insertUser(address,bytes32,bytes32,bytes32,uint256)","5719a565":"SignerChanged(address)","5719dd22":"getTokenListLength()","571a045d":"change_game_stic(string)","571a0830":"withdrawAndKill()","571a1f66":"erc165UpdateCache(address,bytes4)","571a26a0":"auctions(uint256)","571af13b":"unlock10PercentTokensInBatch()","571b0227":"createUserLottery(uint32,uint32)","571b3d52":"createCitizen(address,uint16,uint16,uint8,bytes32,bytes32,bytes32)","571c4539":"askQuestion(address,uint256,string,address[])","571e4a6d":"addEngineer(address,uint256,uint256)","571ec8d9":"addBoardScore(bytes32,bytes32,uint256)","571fe016":"MAX_SALE_SUPPLY()","57204a1d":"unlockat()","57207703":"initBank(uint256)","5720988b":"QLANCE()","57211ac0":"getPaidOut(address)","5721b89a":"withdrawNoMoney(bytes32,address)","5721e419":"getBuyer(address)","5722e24a":"setLogger(address)","57230ff8":"createCity(uint256)","57240913":"vouched(bytes32,uint256)","57241f8e":"tokensOnSale()","5724630c":"Disbursed(address,uint256)","57246c1c":"getPartnerCash(uint8,bool)","57246d23":"jackpotSize()","57257a67":"startPrivateSales()","5725b8c5":"_initRandom()","57263ce1":"_isProviderValid(uint256)","57266803":"casinoWithdraw(uint256)","57271a93":"bountyP()","57277b92":"storeEth()","5727dc5c":"BB()","5727e25d":"getCurrentRoundId()","5727e30b":"makeOraclizeQuery(uint256,string,string,uint256)","5727eec0":"speed_limit()","572816ef":"audit(uint8,uint8,uint256)","57282b96":"bobMakesErc20Deposit(bytes32,uint256,address,bytes20,bytes20,address,uint64)","57292af8":"bonusRateOneEth()","572b130f":"addItem(uint256,uint256,uint256,uint256)","572b7a03":"minimumFeePlusDividendsPercentage()","572bcb3e":"setLockByPass(address[],bool)","572bcfe1":"deliverRewardedTokens(address,uint256,string)","572c1517":"transfer(uint256,string,bytes)","572c62ca":"poolSale()","572d5298":"setProduct(string)","572e85ec":"getCurrentPhase(uint256)","572f37b4":"notePrepurchase(address,uint256,uint256)","5731d433":"balanceInLottery(uint32,address)","5731d9cb":"seriesInfo(bytes32)","5731d9e3":"onefive()","5731f357":"oraclize_query(uint256,string,string,string)","5732788a":"validateCompanyName(bytes32)","57329424":"getPorscheByOwner(address)","5732a273":"backup_drawdown_amount(uint256)","573328ef":"advertising()","57332f08":"Lexcoin()","57344e6f":"getCredit(address)","57347f24":"playerWithDraw(uint256)","573618f3":"eXchangeQualityCoin()","5736c9d4":"getStageBuyers(uint8,uint16,uint8)","57381228":"betInStageAndReturnExcess(uint256,uint256)","57381ee4":"sendTokens(address,uint256,uint256,bytes32)","57386c2a":"smallId()","5738fa56":"hasDataStream(bytes32)","57393674":"exhaustFusion(uint256)","573939de":"_resetFrozenInfo(address)","573c0bd3":"updateValue(uint256)","573d2411":"VeraCoinPreSale(uint256,uint256,address,address,uint256,uint256,uint256,uint256)","573d3a23":"makeTransfer(uint256,uint256,uint256,bytes32)","573d559f":"_handleCoolDown(uint256)","573d72b7":"PERIOD_AFTERSALE_NOT_TRANSFERABLE_IN_SEC()","573dea96":"toWei()","573f642d":"_productDigest()","573f7af5":"mintNFTsForSale(uint256[],bytes32[],uint256[])","57400cf3":"currentJackPot()","57405301":"creatorad()","57408a98":"getNode(int256)","5740a4be":"CertifyDelegate(address,uint256)","5740d43c":"setDeprecated(address,bool)","57417e78":"insetMoney()","5741fbce":"isPresellOpen()","574356b4":"VULCAN_PROMETHEUS()","5743cee0":"BwwToken()","57446636":"createContractOfAthlete(string,address,uint256,uint256,uint256)","574479e6":"currentPot()","574490cd":"ERC721Address()","57451104":"bonus_for_add_stage()","57478e38":"Free_Ether_A_Day_Funds_Return()","5747baf5":"Roles()","574844f4":"BLMFund()","574a5e31":"weiPerAtom()","574a89e9":"GOOGLE()","574bea92":"bonusPhaseOneDeadline()","574c339a":"HackerSpaceBarneysToken()","574c8776":"addAddressesToRole(address[],string)","574cc0fe":"addManyToWhitelist(address[],uint16,uint256)","574d6554":"setIPFSHash(string,string)","574e9063":"crowdfundPercentOfTokens()","574edd28":"updatePropertyData(uint256,string)","574f9a81":"setAttr0(uint256)","5750644a":"setProviderParameter(bytes32,bytes)","5750abfa":"BONUS_TIMES(uint256)","5750daa0":"GameToken()","57518243":"addToWhitelist(address,address)","575185ed":"createGroup()","5751892f":"increaseProjectCompleteLevel()","57530017":"setReservedTokensWallet(address)","57536e64":"GuessTheRandomNumberChallenge()","5753a6b2":"construct(bytes32,string,bytes32,address,uint128,uint256,uint64,uint64,uint256)","57548f32":"_tokenPurchased(address,address,uint256)","5754a042":"attempts()","5754aadc":"getEntryByName(bytes32)","57553101":"updateDetails(string,string,string)","5756572e":"Show_the_name_of_Option_B()","5757a66a":"_deployBallotChecks(bytes32,uint64)","5757dcdf":"getCooldownIndexFromGeneration(uint16)","5758537b":"payBonusAffiliate(address,uint256)","57593c23":"TokensDelegated(address,uint256,address)","57595e2a":"get_previous_global_audit_document(bytes32)","57597321":"_findpos(uint256,uint256)","57599dff":"curatorAddressOf(uint256)","575a4187":"getClaimableStake()","575a7722":"setPOOL_edit_29(string)","575ab848":"MatCashToken()","575b4071":"currentPeriodEndTimestamp()","575b6efe":"EARLY_INVESTORS_SUPPLY_LIMIT()","575b8cc8":"kcck256str(string)","575cb0f6":"block()","575cea6b":"getUserReferrals(address)","575d462a":"phase1EndBlock()","575dfc4a":"Sale(uint256,uint256,uint256,uint256,address,address,uint256,uint256,uint256,uint256,string,string,uint8)","575eaf98":"fractionalize(address)","575ed3de":"ViewGold()","575f7832":"InterestFinal(address,address)","5760168b":"ElearningCoin(uint256,string,uint8,string)","576077e2":"realtransfer(address[],uint256[])","57607ddd":"PUBLIC_SALE_END()","57611ba3":"offerCollectibleForSaleToAddress(uint256,uint256,uint256,address)","57614c2a":"resetLockReleaseTime(address,uint256)","576168fc":"partnerAddress()","57623d59":"AttachAsset(uint256)","5762a880":"standFeeBefore500()","5762f25f":"test_1_validShouldBe5()","57635dc1":"validate(address[5],address,uint256[12],uint256,bytes,uint256)","5763e103":"powercontract()","57646d5d":"OkkamiToken()","57650592":"getPlayerBackDataForMarketPlaceCards(uint256)","57651be6":"replaceUser(address)","57652f13":"assingAdminship(address,uint8)","5765a796":"addRegistered(address)","5765cc2a":"setmessiDevAddress(address)","5765dd1a":"MTC(address,address,address,address,address,address,address)","57670366":"getTargetReportsPerReporter()","576709a2":"finishingWithdrawing()","5767b9ab":"retrieveV(uint256)","5768bc4a":"_createArmy(string,string,uint256,uint256,uint256)","5768fca3":"paymentDestination()","57693e9a":"NBB()","576b8bba":"SeedMemberCanDraw()","576bc138":"NKCToken()","576c3de7":"getTier(uint16)","576c51bc":"countOfPublicKey()","576cecdc":"checkStubs(bytes32,bytes32,address)","576cfdd7":"window2EndTime()","576d067b":"StageOneDisable()","576d1ce1":"internalVerifyCert(bytes32,bytes32,address)","576d4e13":"_createLinglongCat(uint256,uint256,uint256,uint256,address)","576e6d4e":"_buyXaddr(address,uint256,bytes32)","576eac66":"setFundingGoal(uint256)","576f35e3":"setBatchSize(uint256)","576f7e31":"getApprovedBuyerMappingCount(address)","576f9cba":"isInDirectory(address)","577000a3":"onlyPartnersOrAdmin(address)","57712f37":"CappedBurnToken(uint256)","577131ac":"bankrupt(address[])","57717090":"transferWinnings(uint256,address)","5771d6e4":"readMessage(string)","57727a04":"ZZCoinToken()","5772ae70":"setLoanManager(address)","5773faf9":"modifyVariable(address,uint256,uint256,uint256,uint256)","5774ce4d":"sendBonus(address,address,uint256)","5775b57e":"totalBuyOrdersOf(address)","57764094":"getRate(uint256)","57771a23":"del(uint256)","5778472a":"getOrder(bytes32)","57786394":"feeMake()","57788716":"doKeccak256(uint256)","577890f6":"presaleFallBackCalled()","5778bec2":"Deal()","57796e1c":"setVote(uint256,uint256)","577a75a0":"CRAWDSALE_END_DAY()","577bd336":"progress()","577c78f1":"SitcomToken()","577ccfe0":"tokenFrozenUntilNotice()","577ec5ae":"cookieProductionMultiplier()","577ef53d":"SetA(uint256)","577f7133":"PHOENIX_CORSAIR()","57806705":"addpatient(uint256,uint256,string)","5781d9e7":"isRegisteredRetailer(address,address)","57820829":"UP_etherWin()","578242c3":"CompositeCoinCrowdsale(uint256)","57831809":"payoutCount()","57835720":"setSetupCompleted()","578436a7":"CoinDisplayNetwork()","57850fc7":"getPotentialAmount(address)","578551aa":"goods(uint32)","5785b3f9":"VIRALTOKEN()","57861e65":"VVDBCrowdsale(address,address)","5786a552":"registerEmployee(address)","5786cbdc":"sendBackSurplusEth()","5786f28c":"regionsIsPurchased(uint256)","5786fd40":"getProductsCount()","57875631":"setAccessPolicy(address,address)","578799b3":"QRTok()","57880042":"bulkPurchageEgg()","57880c04":"releaseForce(address,uint256[],uint256[])","57885380":"ChannelAudited(uint256)","5788a081":"ownerAddressMap(address)","57894c1b":"createClone(address)","57895ca2":"setManagerContract(address)","5789a722":"LocusToken()","5789b1cd":"transferAdminMessage(address,address)","5789baa5":"isUnlockedBoth(address)","578a791d":"setExchangeFeeRate(uint256)","578aa665":"_createToken(string,address,uint256)","578affb4":"Logger(string,bool)","578b08e2":"GPUxToken()","578b2dab":"euroTeams(uint256)","578b3a56":"normaliseCardIndices(uint256[])","578bbdc1":"isSaleContract(address)","578bcc20":"reduceDebt(address,address,uint256)","578bcf35":"distributed(address)","578bcfca":"AddedToHolder(address,uint256,uint8,uint256)","578c3485":"iWantToKillMyself()","578c6642":"BONUS_BATCH()","578cf4a9":"testTemp1()","578d52b6":"GetDidPayOut(bytes32)","578de482":"OCE()","578de8aa":"addressToAsciiString(address,address)","578e2f7d":"verifiPost(uint256,bool)","578e9825":"burnEscrow(uint256)","578ee866":"getCurrentTimeBonusRate()","578f9658":"shopTome()","578ff67a":"new_hash(bytes32)","57901b19":"genRandomArray(uint256,uint256,uint256)","57902a75":"rateTier2()","579078cf":"TestAnyChain()","5790de2c":"ProposalAdded(uint256,address,uint256,bool,string)","579140e8":"BITSEACoinERC20Token(uint256,string,string,uint256)","579140f4":"tokenInitialized()","57915897":"faucet(uint256)","57918052":"setPriceIncreasingRatio(uint16)","5792b512":"Bettereum()","5792e1de":"CheckCarToken()","5792e262":"registration_fee()","579327fd":"TOTAL_ETHER_HARD_CAP()","5793511f":"playersList()","57938b2a":"requestCancellationMinimumTime()","5793bfdc":"createSDC(address,address,uint256,uint256)","579424e7":"HOWLToken()","579425b7":"feeBurnerContract()","57945e3e":"anyAssetHasChanges()","57945ed1":"FindMyFish_EnterBarcode(bytes9)","57946897":"Test11()","57946a86":"SPEKToken()","57950697":"testState()","57955f3b":"ExampleIntervalTree()","579599bd":"canCreateEdition(uint256,uint8)","57978a75":"updateInviteInfo(address,uint8)","5797cd52":"Settle(uint32,uint32)","57987d38":"PSCN()","57988a55":"card_gold_first()","57989b4c":"IsCityNameExist(bytes32)","5798d5bc":"rSetA(address)","579952fc":"transferFromTo(address,address,uint256)","579b9499":"estimatePurchasePayment(uint256,uint256)","579badf6":"UniversalFunction(uint8,bytes32,bytes32,bytes32,bytes32,bytes32)","579cd3ca":"conversionFee()","579cdf17":"getAdminName(address)","579d4f7a":"changeHouseFeePercent(uint256)","579d5fba":"debug_hash3Int(uint256)","579da090":"needUpdate()","579db769":"getIudex(address)","579e0b87":"assignAnotherOwner2(address)","579f0789":"BNN_ALLOCATION()","579f20d8":"submitProxyVote(bytes32[5],bytes)","579f61d8":"valueDelete(string)","579fc25e":"contractFallback(address,uint256,bytes)","579fe761":"vote(uint80,uint80)","579fea7d":"setDolRate(uint256)","57a0685b":"privateSaleMinEth()","57a15c4f":"createOffspring(address,string,uint256,uint256)","57a1a58e":"setCycleResetTime(uint256)","57a218e6":"WeSource(bytes32)","57a27a76":"checkCompletedCrowdsale()","57a2e60c":"VoiceCoin()","57a373a1":"uintInArray(uint256,uint256,int256,uint256[],uint256)","57a533e9":"logPromiseCreated(uint256,address,uint256,uint256)","57a756d3":"walletC()","57a83f25":"TKRToken()","57a858fc":"shares(uint256)","57a8c01f":"registerUser(address,uint256,uint256,uint256,uint256)","57a967ca":"waitingForClaimTokens()","57a96dd0":"proxyTransferWithReference(address,uint256,bytes32,string,address)","57a9838a":"Tronerium()","57aaafe2":"toggleArtworkVisibility(uint256)","57aaf08b":"getAlgosByCreator(address)","57abd75d":"_weiToMth(uint256)","57acc118":"setForward(address)","57ad693b":"MIN_UPDATE(bytes32,uint256)","57adc83a":"angelTime()","57aeb5c8":"convertToMiniCFT(uint256)","57aee888":"_eraseNodeHierarchy(uint256,bytes32[],bytes32)","57aeeb25":"becomeSquirrelmaster()","57af3eec":"STARTING_HIPSTER()","57afb890":"collectRemaining()","57b001f9":"unpause(address)","57b07cd9":"getReleaseHash(uint256)","57b16811":"totalsInfo()","57b34be7":"_moveStage()","57b394bf":"walletWithdrawal(address,uint256,uint256)","57b45386":"removeCode(string)","57b473e2":"okamiMinPurchase_()","57b543e2":"getOwnersLength()","57b69e72":"_kittenContract()","57b70510":"parseResult(bytes)","57b7247e":"UserWallet(address,address)","57b7a0b6":"Paye()","57b8e8c3":"devcon2Token()","57ba8652":"getRank02()","57babe2e":"collectedBcy()","57bbf921":"salesaccount()","57bcccb6":"revokePermanentApproval(address)","57bce8b0":"sendWei()","57bcfc09":"HomeChain()","57bd2a65":"allocated3Year()","57bd4f7b":"getTime1(address)","57bf04be":"changeOwnedOwnershipto(address)","57bf66d4":"accountForIncrease(uint256,uint256)","57bfab93":"getAllABaddress()","57c07055":"scheduleCall(address,address,bytes4,bytes32,uint256,uint8,uint256)","57c19b4f":"postFreezeDestination()","57c1a709":"travelUnitFee()","57c1f9e2":"removeDistributor(address)","57c1feca":"BonusChanged(uint256,uint256,uint8)","57c393fa":"transferSuperuser(address)","57c3b376":"updateRandContract(address)","57c3f997":"isReserved(address)","57c508d3":"IsThisExternal()","57c60982":"calcProfit(address)","57c67ad1":"RobotTradingIco()","57c6c642":"MultiTranser()","57c85787":"batchMint(address[],uint256[],uint128[])","57c8b724":"addPresetTransfer(address,uint256)","57ca94fa":"_addUser(address)","57cb2fc4":"getInt8()","57cb48c9":"issuerTokenName()","57cb4947":"mintRequest(address,uint256,uint256)","57cc2d52":"testStoresParentChallenge()","57cc5941":"getTileClaimerAndBlockValue(uint16)","57ccbe28":"isPreICOPrivateOpened()","57ccc80e":"putSmartContractOnSale(bool)","57cd23a6":"TeamLockingPeriod24Months()","57cd650d":"sealDataStream(address,address,uint256,bytes32,uint256,bytes32)","57cdd078":"isIcoInProgress()","57cdf799":"createContractItem(string,bytes32)","57ce0ec0":"MIN_PRE_ICO_SLOGN_COLLECTED()","57cea5c0":"weaponTokenIdToDamageForEncounter(uint256,uint256)","57cf9add":"showOwnerContract()","57cfd296":"getFurnace(address)","57cfeeee":"transfer(address,uint256,bytes32)","57cff409":"tpt()","57cff437":"getKunsByOwner(address)","57d0354b":"NothingToCancel(address)","57d083b5":"_evaluateSkill(address,uint8,uint256,uint256,uint256)","57d13917":"getCompany(uint256)","57d15c6a":"_time()","57d17805":"getTokensSold(uint256)","57d1c582":"TokenData(address,uint256,address)","57d25a0f":"retrieveAssets(address)","57d4021b":"nextPayoutWhenPyramidBalanceTotalsApproximately()","57d444fd":"detachController()","57d4617b":"getAllocatedTokenAddress(address,address,uint256)","57d4f398":"unfreezeBalance(address)","57d55116":"_safeApprove(address,uint256)","57d55367":"publishResult(uint32,string)","57d56267":"getModuleCount()","57d5927f":"LogOraclizeCall(uint256,bytes32,string,uint256)","57d5939c":"IsValidated(string)","57d61f3c":"TokensSold(address,uint256)","57d62a30":"accountFeeModifiers(address)","57d6f5f2":"canLogIn(address)","57d70c0b":"getIcoRuleList()","57d713d5":"getPendingUserCount()","57d775f8":"epochLength()","57d786da":"_checkPolicyEnabled(uint8)","57d93329":"endCrowdsalePhase3Date()","57d9fd41":"orderLastDate()","57da1fb2":"isMonsterChampionship()","57da9166":"Dodol()","57db8024":"adminDeposit(address)","57dbefdd":"addExcluded(address,address)","57dc2658":"setLastCrowdsale(address)","57dc561f":"assignTokenIJK(address,uint256)","57dc5d9d":"adminer()","57dc9760":"DaoChallenge()","57dd2f26":"AntriexToken(uint256,string,string)","57dd8366":"jackpotGuaranteed()","57ddf217":"gameoverGetYUM(uint256)","57de26a4":"read()","57df844b":"getTokenTotalSupply()","57e07140":"testTransferFromCorrectlyAllowsDelegationOfTokenOwnership()","57e0b222":"ERC20Store(address)","57e18886":"reserveTokens(address,uint256,uint256,uint256)","57e1fae2":"transferChild(address,address,uint256)","57e233e2":"hardcapUSD()","57e25a79":"PullPaymentCapable()","57e2880d":"scheduleTransaction(uint256,uint256)","57e49ca8":"safeTransferChild(address,address,uint256)","57e4e95d":"burnerChangeable()","57e53d4e":"currentStageETHContributions()","57e5be05":"current_mul()","57e5eea5":"getCurrentBonus()","57e60c27":"removeAccountReader(address)","57e6a64c":"AddrRewardPlan()","57e6a6af":"METS6()","57e6c2f4":"isAuthorized()","57e71cd7":"setPreIcoHardCap(uint256)","57e7afd0":"addIPFSFile(string,uint256,string,bytes32,uint256)","57e871e7":"blockNumber()","57e8f401":"getUserLandLimit(address)","57e984cf":"changeMonthlyRate(bytes32,uint256)","57ea563a":"tokensByLtcTx(string)","57ea89b6":"Withdraw()","57eabab4":"defaultMintingAddress()","57eaeddf":"_isContract()","57eb3431":"recordPresalePurchase(address,uint256)","57eb95a7":"trainSpecial(uint256,uint256,uint256[2])","57ebc286":"approve_fixed(address,uint256,uint256)","57ebc7a8":"logLargeContribution(address,address,uint256)","57ee24af":"getNum(bytes32,uint256)","57ef58c1":"canDefrostAdvisors()","57f011b6":"destTokensEarlyInvestors()","57f032e7":"changeAgent(address)","57f04d2b":"updateLedger(uint256,address[],address,uint256[],uint256[])","57f1935f":"refundTokens(address,address)","57f196fa":"lastBidID()","57f1f6ca":"rareStartPrice(uint256)","57f232e1":"buyFucks()","57f2c6b7":"withdrawOfferForCollectible(uint256,uint256,int256)","57f2d763":"LongTerm()","57f32591":"changePriceChangeName(uint256)","57f46cbe":"collect(uint256[])","57f47bf9":"sh_doAgree()","57f4d5ec":"processDividends(address,uint256)","57f5abe5":"setERC20TotalPromo(uint256,uint256)","57f6280e":"FundManager()","57f65e24":"setArray(bytes32,string[])","57f664ed":"TOKENS_ALLOCATED_TO_PROOF()","57f70b21":"WorldToken(uint256,string,uint8,string)","57f7b905":"balanceBonusOf(address)","57f86b6a":"theRiver()","57f91458":"sacredToken()","57f94c82":"airDropTokenIssuedTotal()","57fa7044":"_changeCycleValue(uint256,uint256)","57faa161":"TokenBonusGiven(address,uint256)","57fbac06":"setAllowTransferExternal(bool)","57fbb9df":"withdrawContractBalance(address)","57fc3991":"returnTokens(address,address,uint256)","57fc8a20":"custom(address,bytes)","57fc990f":"_createAuction(uint256,uint256,uint256,uint256,address)","57fdf2b2":"transferrableBalance(address,uint256)","57fe5a5f":"FREEREWARDPPOINT()","57ffd7cc":"createNewContract(uint256,address,address,address)","57ffd863":"deleteHiddenPosition(bytes32)","5800827c":"mintExtraTokens(int256,uint256)","580101c8":"startingSnailAmount()","580215fc":"transferFinal()","580225d5":"HomeBridge(uint256,address[])","58022de4":"recoverSigner(bytes32,bytes32,bytes32,uint8)","58022e3f":"AkbulutTokenICO()","5802c695":"setPendingValue(uint256,bool)","5802f02d":"SavingsAccount()","58047913":"getWrappedContract()","58056392":"setLockBalance(address)","58057468":"confirmTransferOwner()","58057d81":"transferDomainToBuyer(uint64)","58058304":"clearFund(uint256)","580588a1":"havedAirDrop()","58062e66":"VIRTVEN()","5806ba15":"InbotToken(string,string,uint8)","580709cb":"downTheDrainImmediate()","58074d8b":"keyIndex()","5807630f":"transferEthToOnwer()","5807703d":"getMainGasPrice(bytes)","580786cf":"getRoundOpen(uint256)","58078a5a":"_checkAndAdd(bytes32,bytes32)","58079e7b":"setStartOfPresale(uint256)","580822da":"CoinLordToken(address)","5808e1c2":"betOnNumber(uint256)","5808ee15":"setDefroster(address)","5809ea99":"hitPrice()","580b72e1":"approveTokens(address,uint256,uint256)","580bd977":"distributeFunds(uint8)","580bdf3c":"disableBetting_only_Dev()","580c0fd8":"COMIKETCOIN()","580c2ae9":"numberOfPurchasers()","580c5072":"IsPremature(uint256)","580cf318":"tokenRemainCap()","580e77d4":"startMainSale()","580ea491":"PatronageRegistry(address)","580efd6b":"totalWageredForAddress(address,address)","580f2427":"LeeSungCoin()","580f3904":"requestTokens(address)","581191f7":"DNATIXToken()","5812f78a":"A2UToken()","58144fbd":"covmanAddress()","58150c8b":"GameRegistry()","581515fd":"howManyEtherInWeiToBecomeOwner()","5815528c":"setInviterEdge(uint256)","581627bc":"ownerWithdrawl(uint256)","58163c23":"calcBonus(uint256,bool)","5816ba9d":"unFrozen(address)","58172da1":"payBankroll()","581732dc":"setLev1(uint256)","5817465c":"RidgeToken()","58178168":"punkIndexToAddress(uint256)","581847d6":"changeDeveloperSFTDestinationAddress(address)","58189259":"CerradoToken()","5819dde2":"getNumbersFromBytes(bytes3)","581a3aea":"ActiveSCO(bool,uint256)","581a81c1":"setMinHouse(uint256)","581aa8a3":"SRVSKCOIN()","581bdd23":"createCampaignAndChannels(address,uint256,string,address[],address[],address[],uint256[],address,string,bytes,uint32[])","581c1f47":"isFreeze(address,uint256)","581c281c":"getVotingStatus()","581c5ae6":"invest(address,uint8)","581c71d0":"ifClaimedNowPublic()","581ca8bb":"adjustCash(address,int160,string)","581d1015":"publicsalesTokenPriceInWei()","581d1d04":"devTokensIco3()","581d416a":"Paid(uint256)","581e69de":"pauseRoundD()","581f1125":"returnUnsoldSafeSmall()","581f3c50":"createAndOpen(address,address)","581fc2ad":"getNextReleaseTimeOf(address,address)","581ff6e2":"VerifyPublishedResults(uint16)","5820c9ae":"round4()","5820dce5":"abbuchen(uint256)","5821c831":"AcceleratorStart()","58226a76":"isInTime()","58229d91":"MasToken()","58240d5f":"listPrycto4()","582420bb":"calculateMatchPrice_(address[14],uint256[14],uint8[6],bytes,bytes,bytes,bytes,bytes,bytes)","582518ac":"updateclaimableTokens(address,uint16)","582527f8":"setNewData(uint256)","5825884f":"setOwner2(address)","5826344b":"frozenAccount()","582681d2":"compareDateTimesForContract(uint256,uint256)","582747ba":"PLCCToken()","58275869":"ETHReceived()","5827834a":"DecenturionToken(uint256)","5827b250":"completeInitialization()","5827c0c8":"SSE()","5828fa47":"ThawTokenTransfers(address,bool)","58292a3d":"emission(uint256)","58294575":"updateComplianceAddress(address)","5829d310":"entries(int256)","582a466a":"burnGasAndFree(address,uint256,address,address[],bytes)","582a5c83":"HWGCToken()","582ab0b4":"setup(uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","582b4019":"updateCheckHourly(bool)","582b6add":"isDataSourceCallback()","582b6fe4":"crowdsaleUncappedTime()","582bd287":"snapshotDelegators(uint256,address)","582ca57b":"get_associations()","582cca06":"SafeCoin()","582d14f8":"updateHpbNodeWithString(address,string,string)","582d2d32":"removeFreeRoom()","582d6033":"listDda(address,uint256,uint256)","582d9008":"willyWantTalkToken()","582ee26e":"PendingFees(address)","582f5009":"calculateBonusToken(uint256)","58306772":"getAmountOfEtherSell(uint256)","5830da9c":"Escrow(address,uint256,uint256,bool,address)","5830f2ea":"subPrivateSale(uint256)","58317685":"getBuy(uint256,address,address)","5831e95d":"_burn(address,address,uint256,bytes,bytes)","58339a40":"CryptoScalper()","58341922":"totalSupplyLocked()","5835ac93":"extract(uint256,uint256,uint256)","5836746d":"deployStep()","58371ccd":"endSaleTime()","5837bb11":"ALLOC_FOUNDER()","5837e083":"move_history(uint256)","58392aaa":"setSibling(address)","583ae991":"BitCharityToken()","583b4715":"createTitty(uint256,string,uint256,address,string)","583ba757":"getrestrictTime(address)","583be14e":"isCampaignRegistered(uint256)","583c4be9":"PurchaseUnlocked()","583d175f":"clientClaim(address,uint64)","583d5435":"queryTokensOf(address)","583dbacc":"specialKitties(uint256)","583dbc09":"updateBonuses(address,bool)","583ed080":"End7()","583f0ae6":"purchaseMembership(address,address)","583f18ff":"totalRemainingTokens()","583fe287":"ReussitexCoin()","584084d9":"_setString(bytes32,string)","5840b0f8":"getPixelData(uint256)","5840f4ec":"applyRate(uint256,uint256)","58410259":"onBuy(bytes32,uint256,address,uint256,uint256,address,uint256,uint256,address,address,uint256,uint256)","58413194":"lmda()","5841b9bf":"kingCost()","58428322":"grantAccessDeploy(address)","58439b9f":"EtheraffleLOTPromo(address,address)","5843b811":"_setPendingUpgradeabilityOwner(address)","58441a58":"minimumBid(string)","58451f97":"totalAccounts()","58453569":"initializeSpendLimit(uint256)","58453fef":"updateBalance(uint256,uint256)","5845d13c":"NamdoToken()","58462b36":"contBuy(address,uint256)","58463e11":"FeedBackedCall()","58469cd1":"generateStakeForDelegationSchemaHash(address,uint256,bytes32,bytes32,uint256[],bytes32,uint256)","58476a7a":"mintForSale(address,uint256)","58480d41":"setVotesPerProposal(uint256)","584855f0":"shopShoes()","58487bee":"request(uint8,address,bytes4,uint256,bytes32[])","5848a7fa":"getOwnerPotatoes(address)","58491ad9":"ICNQCrowdsale(uint256,uint256,uint256,address,uint256,address)","58491ecb":"companyPeriodsElapsed()","5849cf77":"registerDINWithResolver(address,address)","5849f66b":"claim_ico()","584af2c3":"approveOwnerTransfer(bytes32)","584df977":"LimitPerUserEBC()","584e492a":"arr(address,uint256)","584e86ad":"suggestUrl(bytes32,bytes32)","584ed064":"getBattleCardList(address)","5851166c":"endOfRound()","58516661":"agents()","5851bc4f":"FJH()","5851f1e2":"trexdevshop()","58525fda":"tokenAllocation()","5852f5c1":"buildingToUnits(uint256,uint256)","58541aba":"jackpotLastPayout()","58543fbd":"getRoomIdxByNameElseLargest(string)","5855279e":"whitelistAccounts(address[])","5855da3d":"extractAddress(bytes,uint256)","5856db43":"isIcoClosed()","585789cd":"startPreDistribution(uint256,uint256,address,address,address)","5857b86f":"getAuctionByAuctionId(uint64)","5858e7d0":"bigBearCoin()","5858ef10":"testErrorNonOwnerCantBreach()","58593578":"toss(bool)","585a8aba":"getCredit(address,address)","585a9385":"icoProceeding()","585ac3e8":"icoEnded()","585b0f05":"BitcoinMax()","585b143a":"getVariableReleasableAmount(address)","585b7752":"setOraclizeString(string,string,string,string)","585bc25b":"weiRaisedDuringRound(uint8)","585bc523":"cooAddManager(address)","585bf3e4":"totalLux()","585c6fc9":"EtherHealth()","585ce259":"VitToken()","585d2133":"newDeliverable(uint256)","585da351":"setUnitAttackMultiplier(address,address,uint256,uint256,bool)","585e1af6":"hard_cap()","585eb90c":"withDrawAmount(uint256)","585f9b7a":"addVoteOption(uint256,string)","58613568":"estimateNeumarkReward(uint256)","58619076":"OwnerRemoved(address)","58620daf":"RegistryAddress()","58623642":"minStartDelay()","5862fd31":"ethCrowdsale()","5863115e":"parseId(uint256)","586360ce":"distributedTokens()","5864c56c":"numberOfSuccessfulPings()","5865c60c":"getOperator(address)","58669d6d":"updateMinimal(uint256)","586a2d02":"Anastomos()","586a2d79":"_decreaseBalance(address,uint256)","586a4be5":"Bitsurge()","586a52e0":"GenerationSupply()","586a69fa":"getMaximumStackCheck()","586a94ba":"MassivelyMultiplayerOnlineGameToken()","586ab7a9":"MYSYMBOL()","586ac27d":"ProofOfPassiveDividends()","586b1c8f":"DetherCore()","586ccfa7":"deathData_f11()","586cf767":"MintedEthCappedCrowdsale(address,address,uint256,uint256,uint256,uint256)","586cf845":"setTierEndTime()","586dd1d5":"CCXTokenERC20()","586e416e":"updateMaxWei(uint256)","586e8283":"deliveredEth()","586facb4":"adminSetMarket(address,uint8,uint256)","586fc5b5":"lastMint()","58708479":"setWinningChance(uint256)","587097ab":"test_FiftySixPercent()","58712633":"GetCommission()","587181d1":"getVaultLock(address)","5872282d":"icoReferralBonusInPercentage()","5872fe45":"getAccountAddress(address)","5873533d":"playGame(uint256)","587378a4":"updateQualifiedPartnerCapAmount(address,uint256)","5873cbe6":"setFile(string,string,uint256,address)","587419d5":"depositStartTime()","58750784":"getUniqueKey(string,string,uint32)","5875caaf":"objectKnife()","587631eb":"PlayX5()","587695cd":"tokenGiveAway()","58769981":"transferAdminship1(address)","5876d2ef":"rwGas()","58793050":"Setup()","58793ad4":"submitHKGProposal(uint256,string)","5879f7ad":"myDroneList(address,uint256)","587ac47c":"sendFromAdvisorWallet(address,uint256)","587af98d":"GetConfirmRound(bytes32,uint8)","587b060e":"_setUpgradeContract(address,address)","587c2b8e":"setContributionDates(uint64,uint64)","587cde1e":"delegates(address)","587d6a20":"ICOactive()","587f2e50":"putInStud(uint256,uint256,uint256)","587fa8dc":"closeHouse()","587fae93":"release(uint8,address)","58802e24":"BancarCrowdsale()","5880b7da":"CAAction(address)","588100d4":"DIP_TGE()","588198c4":"getBonusByETH(uint256)","5882128d":"tradeActive()","588268a8":"tokensForCreators()","58838594":"anacoContract()","5884afe1":"setBetLimit(uint256,uint256)","5884f2f5":"GeneralUpdate(uint256,uint256,uint256)","5885c626":"allocateTokensToMany(address[],uint256[])","58864d04":"Clost(uint256,string,string,uint256)","588666e2":"updatePriceManualy(uint256)","5886c51e":"setnotice(string,string)","58883688":"setAvailableToken()","58888b40":"_calculateUnlockedTokens(uint256,uint256,uint256,uint8,uint256)","58892f63":"setCrowdsaleStartDate(uint256)","588a9db5":"CoreBuyShare(address,address,uint32,uint256,uint32,address,address)","588b1578":"contractEth()","588b5c7b":"approveExchange(address,address)","588bf28b":"addBonusForOneHolder(address,uint256)","588bf923":"removeEmailHash(uint256)","588c2a6d":"WithdrawReserve(address)","588cbbea":"changeSettings(uint64,uint8,uint8,uint8,uint8)","588cff4c":"emitPublicCapabilityRemoved(address,bytes4)","588d376f":"BoleroToken()","588d6a17":"findSemiRandomWinner(uint16)","588dadc6":"contestChampion(uint256)","588e6b83":"giveTurnToPlay(address)","588e730c":"numOfMythical()","588ec17f":"minContributionInUsdCents()","588ee29b":"debug()","588f27e6":"CloudCredit()","588f7e12":"lotteryRatio()","588f85b3":"IHPM()","588f9acc":"toggle(address)","58902cc6":"sendFromGftWallet(address,uint256)","5891215c":"getAllGas()","58919155":"DOGE()","5891c8aa":"removeExceptAddress(address,address)","58924b81":"getClaim(address,string)","589316f6":"level_2_amount()","58931f7a":"buyWhiteByName(bytes32)","58932f50":"btcTokenBoughtAddress()","58933dbc":"totalTokensRemind()","5893d481":"rndTmEth_(uint256,uint256)","58950108":"BucksCoin()","58958be3":"_getTxDataBlockNumber(address,bytes32)","58963c85":"setBilateral(bytes32,bool,bool)","5896521b":"getCurrentTotalFunders()","5896749a":"getAssetRate(address)","5896f37f":"getDistritos()","5897164a":"ADDR_MAYA_ORG()","589737fb":"getOwnPartnerMessage(uint256)","5897a1c6":"getValueToInvest()","5897a5a0":"setupInitialState()","5897e3e4":"splitTheBet(address)","5898f402":"compaundIntrest(uint256,bytes5,uint256,uint256)","58990372":"changeColorBlue()","589a1743":"creatorOf(uint256)","589b88bd":"pauseRoundC()","589c6beb":"_deleteDefender(uint32,uint8)","589d7a3c":"setupViaAuthority(string,string,string,string,address,uint8,bytes32,bytes32,uint256)","589dca45":"_emitEmission(bytes32,address,uint256)","589e5edd":"InvestorsQty()","589e74be":"giveSticker(address,uint256)","589f30c7":"FAPFundDeposit5()","589fd72a":"vehicleDates()","58a0bcdd":"checkPayout(address,uint32)","58a122a2":"cancelRequestUnpause()","58a191c3":"changeFactorySetupFee(uint256)","58a1cabf":"lastPayoutTime()","58a2982a":"_deleteSmallestBidder()","58a356d0":"sendMoney(uint32)","58a383fd":"jsonArrayLength(string,string)","58a3d1a1":"getUnclaimedTokenAmount(address,address)","58a4903f":"cards()","58a50ce8":"setEtherAddress(address)","58a53130":"getABaddress(uint256)","58a5b0f6":"tournamentStartTime()","58a687ec":"finalizeSale()","58a70a15":"acceptReturning(uint256)","58a74333":"singularDTVFund()","58a79319":"GetWildCardOwner(uint256)","58a87b69":"withdrawTokenFromCrowdsale(address)","58aa0f1b":"numOfRare()","58aabdf8":"MaxMinersXblock()","58aaf48a":"gasForShuffle()","58ab010d":"buyParticipationTokens(uint256)","58aba00f":"updateManager(address)","58acf31b":"findJob(uint256)","58ad4673":"LEXTokensContract()","58ae6242":"AOIS()","58ae8bcf":"voteInMasterKey(address)","58af7794":"create_payment(uint256,uint256,bytes32,bytes32,uint256,address,bytes32)","58b092d7":"addRaiseTapProposal(string,uint256)","58b0a2aa":"setPriorityPassContract(address)","58b1effb":"bidOfBidder(address,uint256)","58b1f29c":"refundBounty(uint256)","58b255ea":"fechVoteNumForCandidate(address)","58b435fb":"MeritICO()","58b4370b":"round(int256)","58b4a3c4":"testInitalBalance()","58b4c035":"createNewGoBoard(uint256)","58b5525d":"depositCharge()","58b5e775":"batchAllocateExp(address[],uint256[],uint256[])","58b8dc61":"promoCreationPlayerCount()","58b92d57":"UserAuthorized(address,address)","58b9dcef":"registerVotingPrepareFailure()","58bad3eb":"setEarlyParticipantWhitelist(address,bool)","58bafdbc":"contribute(address,uint256,uint256,bytes)","58bb7d70":"checkEthSold()","58bc3456":"addtokensWL(address,uint256,uint256)","58bcdb5e":"collectCredits(address)","58be0830":"_refSystem(address)","58be98dd":"migrateBlockjack()","58beec9f":"summBounty()","58bf7067":"setBlockedAccount(address,bool)","58c0bde0":"feeNewThread()","58c1c328":"_validateId(bytes32)","58c23767":"setCXLExchangeRate(uint256)","58c264f6":"preico_holdersAmountInvestWithBonus()","58c31603":"loanCollectionNotification(uint256)","58c3b0eb":"updateTokensApproved()","58c3b870":"memo()","58c3c193":"newBatch(bytes32)","58c56f1e":"C20Token()","58c60d5e":"gracePeriodCap()","58c62b12":"SingularDTVWorkshopFee()","58c6bce8":"getCustomBuyerForIndex(address,uint256)","58c6f08b":"takeTokensBack()","58c721ce":"majorEvents(uint256)","58c75136":"currentPremiumSale()","58c757ba":"associateWithSig(bytes32,bytes32,address,uint256,uint256,bytes32,bytes32,uint8)","58c8c0a7":"getVoteNumberList()","58c8ca0c":"_clearInventory(uint256)","58c9e484":"buyPoints(uint256)","58ca5419":"CheckBest(uint256,address)","58cb7323":"MainnetETCSurvey()","58cc13f3":"asserts(bool)","58cda0ab":"requestData(address,address,uint256)","58cdddf9":"getRoundDifficultyBlock(uint32)","58ce4b48":"setFundingStartTime(uint256,uint256)","58cea888":"getWinOutcome(bytes16)","58cf7c71":"unfreezePrice()","58cf9570":"transferFeeRate(address)","58d0390b":"getCurrentICORoundInfo()","58d10aae":"BlackJack()","58d162da":"potSplit_()","58d168b7":"generatePermutationKey(uint8[4])","58d1aebd":"claim(string,string,string,bytes32,bytes)","58d213ae":"InToken()","58d25b93":"LogSendFunds(address,uint8,uint256)","58d2ab45":"numberOfPixels()","58d37dc5":"lastMintingAmount()","58d38231":"broughtSprites(uint256)","58d3b2c8":"babyBornEndVoting(string,uint256)","58d3b617":"Notifier(string)","58d3ce8a":"thirdExchangeRate()","58d40f7e":"existsUserByEmail(bytes32)","58d4e051":"YSS(uint256,string,string,uint8,address)","58d63255":"GandhiJi()","58d6a99e":"CTChinaCoin()","58d75180":"ECToken()","58d782be":"getLotteryDetails(uint16)","58d7bf80":"reserveRate()","58d80a8c":"doSetSettings(uint64,uint64,uint256)","58d8652e":"addIssue(string)","58d8f76f":"getPlayerBet(uint256,uint256,address)","58d90108":"COLOR_RED()","58d9e758":"DeleteUserByID(uint32)","58d9f95d":"VIETNAMTOKENTEST()","58d9fa04":"addUser(uint256,address)","58da3ca9":"jdecompose(uint256,uint256,uint256)","58da9bbc":"getAssetPackData(uint256)","58db3258":"removeFromPrivateWhitelist(address)","58dc03f9":"TigerCashToken()","58dc2a8b":"RESEARCH_AND_DEVELOPMENT_WALLET()","58dd0eb1":"propose(address,string,string,string,string,uint256,uint256,uint256,uint256)","58dd6f23":"setTokenTransfer(bool)","58df0383":"burnFinish()","58df8ed8":"adminGetEnabled()","58dfb058":"LNCH()","58e039bd":"listContractByModTextAndCttName(string,string,uint256,uint256)","58e0a9d7":"YanToken()","58e1c174":"RTI()","58e29e17":"initiateProof()","58e2cd76":"watch(address)","58e3815c":"BASalesPrice()","58e3e914":"devuelveNombreApp(address)","58e46275":"calculateTheEndPrice(uint256)","58e55365":"marketingBalance()","58e59c32":"get_entry(uint256,uint256,uint256)","58e5d5a5":"PunkBought(uint256,uint256,address,address)","58e61e12":"contribute(uint256[],bool,uint256)","58e66522":"CoolTourToken()","58e69c5a":"hashimoto(bytes32,bytes8,uint256,uint256[],uint256[],uint256,uint256)","58e71b15":"Organization()","58e756b6":"NewQ(string,bytes32)","58e77a92":"setSelfPretorian(address,address,address)","58e85e03":"LogTokensBought(address,uint256)","58e868c9":"DisableMember(address)","58e879f3":"nextThaw()","58e8922b":"payImportTax(address,uint256)","58e92fb0":"setFreezeForPEInvestors(uint256,address,uint256)","58e9a706":"checkLargeContributionsLock(address,address,uint256)","58e9b208":"Controlled()","58ea80e5":"setThroneCreationPrice(uint256)","58eae004":"awardBuyers()","58eafc37":"addVirusDefence(uint256)","58ebde43":"generic_holder()","58ec63bc":"setAccountMilestone(address,uint8)","58ecaa45":"StgThreebonusEnds()","58ed766d":"priceETHUSD()","58eda67a":"get_Holders(uint256)","58edaa9c":"getController(uint256)","58edbc84":"mkDelegation(bytes32,bytes32,uint256)","58ef82a0":"setMilFold(address)","58efa06f":"bytesToBytes5(bytes)","58efe3cd":"changeLink(bytes,address)","58f0cbc7":"changeTiming(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","58f10528":"eggExists(uint256)","58f11566":"ReserveAccount()","58f1490f":"addTransaction(address,uint256,bytes,bytes,uint256)","58f24f3d":"transferFromGate()","58f33e98":"isTaker(address)","58f35f10":"createT513(uint256,address)","58f3a115":"tokenDistribution(address[])","58f3da21":"adminGetContractBalance()","58f4be1e":"getIntention(uint256)","58f4f160":"Halo3D()","58f5382e":"challenge(string)","58f65330":"_checkPixelUnderLeft(uint256)","58f693de":"tokenForSP()","58f7f6d2":"BNB()","58f816bf":"redeployProduct(bytes32)","58f8e99e":"Jackypot()","58f94f13":"CarParkCoin()","58fa67f9":"calculateMintTotal(uint256,uint256,int256)","58fa812b":"TRANSFERS_PER_TRANSACTION()","58fb9f36":"_addBonus(uint256)","58fc0151":"getRequired(address,uint256,bool,uint256)","58fd6aec":"register(bytes32,string,string)","58fd6fe2":"getBonusMultiplier(uint256)","58fd955c":"rateETHUSD()","58fd989b":"getLockedStructPulseLockHash(address,address,uint256)","58fe54a1":"GetBoilerInfo(address,uint256)","58fe8847":"BIRC()","58feb4a3":"earlyCommunityAddress()","58ff7613":"RxEALSaleContractExtended()","5900477a":"settleCancel(bytes,bytes)","5900a09c":"addFunder(address,address,uint256,uint256)","59011400":"RewardDAO(address,address,address)","59015ed5":"getAccountModifiers()","59016c79":"getContent()","59032232":"setPatch(uint256,uint8,uint8)","59032614":"FipsTransfer(bytes20,address,address)","5903eff2":"root_10(uint256)","5903f01b":"giveEthBankRollAddress()","5904941b":"CoinealToken()","590528a9":"sellShares(uint256,uint8,uint256,uint256)","590589fd":"WithdrawToMember(address,uint256)","5905b171":"getNextAssignedRequest(uint256)","5905d314":"Added(bytes32)","5905e1c5":"askPrice(address)","590731b7":"secondarySaleCut()","590791f2":"getOwnerBalance()","59084ea9":"setWhitelistedWallet(address,bool)","5908984b":"foreignPurchase(address,uint256)","59092c29":"XtremCoin()","5909e897":"buyRate(uint256,uint256)","590a1c78":"LogBidFailed(address,uint256,uint256)","590a4595":"createNewChain(bytes)","590ba734":"getUint(int256)","590d431a":"wavesId()","590d5a67":"multipleTokenDistribute(uint256)","590daaec":"setTokenDeskProxy(address)","590def78":"IndonesiaRupiah()","590e1ae3":"refund()","590efa59":"setContrAddr(address,address)","590efee1":"isExec()","590f9ece":"getShow(uint256)","590fcc5b":"debugVal2()","591016bc":"generateId(bytes32,address)","591090ee":"ELIXAddressSet()","5910a18b":"addEntry(bytes32)","5910ce39":"_mint(string,string,uint8,uint256,bool,uint256)","591108a5":"setIcoStart(uint256)","59111d83":"add32(uint32,uint32)","59112e79":"payCow()","59117bae":"getRoomID(uint256)","59118221":"setTokenData(uint256,bytes32[])","59118ff2":"amount4()","5911fb9a":"setRate(address,address,uint256)","59125397":"indexedDocs(uint256)","59137533":"PillowCoin()","5913cacc":"unlockBonusDrop(address,uint256)","59144baa":"setFundContract(address)","591451fe":"setHostingProfitAddress(address)","5914589c":"RLC()","59151701":"VerifiedUser(bytes32,address)","591552da":"currentFee(address)","5915589e":"Dataset(address,string,uint256,string)","59161e57":"releseToken(address)","59167b9d":"setTokenContract(uint256,address,uint8[],bytes32[],bytes32[])","59167fcc":"getUserAccountInfo()","59169d06":"setBountyTokensPercent(uint256)","5916c2c9":"NeuroWire()","59179dbd":"createSaleAuction(uint256,uint256,uint256,uint256,uint256,uint256)","59187cec":"getEarningAmount()","5918bc7f":"addTerms(string,string)","5918f00c":"fillOrder(address,address,uint256,address,uint256)","5918f348":"hmcAddress()","59193981":"token_sale_end_block()","59194d0c":"totalEthBalance()","59197f51":"ethEt4Rate()","59198827":"initiateDocumentVote(string,bytes32)","5919896f":"Taracoin()","5919978b":"create_safe(address,string,string)","591a0d87":"foundersWallet2()","591a6ec4":"toBeDistributedFree()","591a89b2":"Voted(address,bool,uint256)","591b05b1":"domainHtml(bytes32)","591b41c6":"Multisend()","591beea8":"guardIntervalFinished()","591c515f":"append(string,string)","591d5236":"getDifference(int256,int256)","591d8bd0":"constantFn(uint256)","591ead36":"SplitTransfer(address,uint256,uint256)","591f36a6":"updatePreICOMaxTokenSupply(uint256)","5920375c":"thaw()","59208b8a":"userRefundWithoutGuaranteeEther()","59214765":"sendBonus(address,uint256)","5922b831":"refundPlayers(uint256)","592311ed":"freeze(address,address,bool)","592341df":"whatsMyJuryNumber(uint256,address)","5923c7f9":"maxSaleToken()","59242d11":"SmartIndustrialToken()","59245ff3":"fundAnswerBounty(bytes32)","59249c46":"duper()","5924f811":"tier2Reached()","592572e2":"getLoanCanceledAmount(bytes32)","5925cfe3":"getCCH_edit_7()","5926651d":"addBeneficiary(address)","592685d5":"getWindowStart(address,address)","5926b55a":"setArray(bytes1[],bytes8[],bytes32[],int256[],uint256[],bool[])","5926c826":"Mitronex()","5926cf13":"setGameId(uint256)","59275c84":"minerAddress()","59276653":"getTicketCount(address,string)","59287ce9":"setPbulicOfferingPrice(uint256,uint256)","5928aedc":"setEndStage2(uint256)","5928bdc4":"LatiumLocker()","5928c7db":"changeDividendWallet(address)","5928e80c":"updateNoteTitle(uint64,bytes12)","59291e2f":"MinedBlocks()","59292ef3":"gasLimitDepositRelay()","59296490":"CharityCommonweal(uint256,string,uint8,string)","59296e7b":"getCredit()","5929b837":"_setRate()","592a5f9b":"ValidToken()","592a97de":"encodeUInt(uint8,uint256)","592af188":"GaonToken()","592b5d17":"haltFX()","592b700a":"updateRegistrar(address)","592b71ab":"isRequestingEscapeTo(uint32,int256,uint32)","592bd705":"setowner(address)","592c0f09":"onLotteryFinalized(uint32)","592c518f":"ADDR_TKG_CHARITY()","592d4c7e":"CAD_Omnidollar()","592dc0a6":"setAyantDroitEconomique_Compte_2(uint256)","592e6f59":"initialise()","592ea64f":"LLV_v30_12()","592eef5a":"postIdToDonationAmount(address,uint256)","592efdab":"presaleWhitelistTokensLimit()","59301cb2":"_callRecipient(bytes32,address,address,address,uint256,bytes,bytes,bool)","5930a295":"changeBetLimits(uint256,uint256)","5931228b":"endTimeDay()","59317ea2":"buyImplementation(address,uint64,uint256,uint8,bytes32,bytes32)","59318b2c":"unFrozenBalanceByIndex(uint256)","59328401":"getPlayerInfo(address)","5932c02c":"tradesCount()","59330b8e":"hashDetails(uint256,address,uint256,uint8)","59355736":"lockedBalanceOf(address)","59357045":"getDueTime(uint256)","5935fba5":"addContractor(address,uint256)","5936259c":"BullsFarmer()","59362835":"JPCoin()","5936387c":"checkOpposited(uint256,bool)","59366245":"bonusInPhase5()","5936812b":"changeLockedBalanceManually(address,uint256)","5937de14":"STATUS_DEAL_RELEASE()","5937e534":"appealSkip()","5937e86a":"setTokensQuantity(uint256[],uint248[])","5938748e":"changeVotingRules(address,address,uint256,uint256,uint256)","59388d78":"decreaseApprovalPreSignedHashing(address,address,uint256,uint256,uint256)","59391a67":"earlyResolve(bytes32,uint256,bytes)","5939a84e":"isLawyer(address)","5939dd31":"setEthartRevenueReward(uint256)","5939ee04":"registrationPeriod()","593a5bff":"KUISToken()","593a6297":"getPlayerLaff(uint256)","593aa283":"setMetadata(uint256,string)","593af09f":"assertEq20(bytes20,bytes20)","593af4f1":"_fYou(address,uint256,string,string)","593af56a":"editionType(uint256)","593b4530":"proxyMergeMint(uint256,bytes32,address[])","593b79fe":"toBytes(address)","593be1f8":"_removeAuctionManager(address)","593c993c":"presaleWeiContributed()","593cca56":"checkExplore(uint256,uint256)","593d280d":"KToken()","593ea3e7":"VERDICT()","593efdf1":"setCurrentPassportLogic(string)","593f3a6c":"AllMarkingsProcessed(address,uint256,uint256,uint256)","5940f55c":"setEncryptionPublicKey(string)","594151e0":"Dice()","5941bb80":"transferFromBatch(address[],uint256[])","5941d8d4":"RtbSettlementContract(address,address,address,uint256)","5941ff52":"impl_yield7Day()","59423a7f":"BuySnail(address)","59424b78":"approveArtist(address)","594337a9":"investorsLength()","5944427b":"getRequestResult(uint256)","5944b7d9":"setCCH_edit_1(string)","594548d5":"newStakesAllowed()","5945793d":"getCorrectedTotalBPOfAddress(address,address)","5945841b":"ELIXAddress()","5945bdc5":"token2GT()","59462295":"WhiteWallToken()","5946e7eb":"Tier_Rainmaker_Registration()","594733c6":"getInvestorId(address,address)","594742da":"forecastOfToken(uint256)","59475891":"TransferHash(bytes32,bytes32,uint256)","59478411":"modifyProductPrice(bytes32,uint256,uint256)","5947cc6a":"level_2_percent()","5947d616":"updateAskingPrice(uint256,string)","59485790":"_emitPricesUpdated(uint256,uint256)","5948f733":"getAddressArray(bytes32)","5949a8f7":"notifyDeposit(uint256)","5949e525":"fundingUnlockFractionInvert()","594aa668":"getCourseList(string)","594afcff":"tgrContributedAmount()","594b18b5":"_transferToLock(address,uint256,string)","594bbe8f":"Corolexcoin()","594de857":"getDealsCount()","594eda64":"getBackend()","594ffb4e":"setReferralFee(uint8)","5950cb8c":"setCasinoName(uint16,string,string)","5950cee4":"checkProviderSupported(address,address)","5950d395":"recallPercent()","5951317a":"doFinalizeSale()","59514593":"addFreezableAddresses(address[])","595210ad":"openDispute(string)","5953c806":"setSendCost(uint256)","5954c8c5":"manualWithdrawEther()","5954ee54":"actualPriceInCents()","595539cd":"modexp_naive(bytes,uint256,bytes)","5956b853":"soldAddresses(address)","5957eb17":"PeterToken()","5957ee49":"getProjectUsedTokens()","5958188d":"MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress(address[],uint256,uint256,address)","5958611e":"finishTime()","5958621e":"setRewardWallet(address)","595882b3":"mintAll()","5958978c":"day_blocks()","595a161b":"amountOfZeros(uint256,uint256)","595a30f1":"RateChanged(uint256)","595a4fc2":"recomputeAccountLastAverageBalance(address)","595a69e8":"add_address(address,address)","595a7273":"QbaseIssued()","595aed65":"_getChild(address,uint256,address,uint256)","595b1a3e":"getUsersLength()","595b35d1":"NUMBER_OF_COUNTRIES()","595c3f61":"FactomTalk()","595cb7a3":"changePrice(address,bytes32,uint256)","595d0392":"transferHoldFrom(address,address,uint256)","595d71a5":"MintFinished(uint256)","595da94d":"has_owners(uint256)","595dcb68":"BIFAToken()","595e1e20":"placeToken()","595e615f":"betPool(address)","595ecbb3":"Int256(uint256)","595ee7a4":"MajListVal()","595f0e5e":"test_CuratorRules()","595f40d6":"getDevelopersFee()","5960b74f":"advisorTimelock()","59622aa6":"maxAmountForSalePromotion()","5962581e":"isInRoundOneState()","59626877":"AiToken(uint256)","59627b84":"getReduce(uint256,uint256)","5962a941":"totalPurchases()","5962ad30":"dkSB(string)","59647984":"isValid(address,uint256)","5965e7c3":"SimpleCrowdsaleBase(address)","59667c24":"withdrawRound(uint256)","59679b0f":"_implementation()","5967dee8":"transferLOT()","5968c2a4":"getOrderTokenAllocationStatus(uint256)","596925d6":"expByTable(uint8)","596939f5":"addAgent(address,uint256)","5969549e":"modifyBeneficiary(bytes32,address)","59695754":"setMinimumPayout(uint256)","5969c0e1":"resetSignature(bytes32)","596a072c":"setOraGasLimit(uint32)","596a2735":"DICE_RANGE()","596aadaf":"transferFromCrowdsaleToUserAdoptionPool()","596b975a":"maxFunding()","596bda14":"_set9()","596c02fb":"assertEq22(bytes22,bytes22,bytes32)","596c0531":"bch()","596c49bd":"TimeControlled()","596c8976":"close(uint256,uint256)","596d6f08":"Blizzard(uint256,string,string)","596ea3db":"allowTransferTime()","596f3473":"applyToBeAReviewer()","596fab6c":"calculateLockAmount(uint256)","59704013":"setVar(string,string)","5970c40a":"addForecast(bytes32,uint256,uint8)","59716eed":"lockedEthBalanceOf(address)","59724977":"getwin011050(address,uint256)","59727e83":"registryTransfer(address,address,bytes32,uint256)","5972e062":"deleteNodeGroup(uint256,uint16)","5973016b":"Multiven()","59748c98":"plain()","5974ec50":"founderTokenUnlockPhase3()","59756526":"getJobHash(bytes16,address,address,uint256,uint256)","59758ebe":"repayLoan(address,uint256,string)","5975ce80":"mintApproveReset(address,address)","59761fcb":"test(address[5],uint256[5])","59764714":"MyDFSToken()","59769073":"totalBalancingTokens()","5976ddd0":"getScenarioNamesAndEventStatus(bytes32)","59770438":"getToken(address)","59780224":"joinGameWithInviterIDForAddress(uint256,address,address)","59790701":"updateFeeSchedule(uint256,uint256,uint256)","59793b3a":"derivativeTokens(uint256)","597c255f":"receiveChild(address,uint256,address,uint256)","597c69cc":"saveToColdWallet(uint256)","597cae8d":"getFeeWindowBurnAmountValue()","597d4601":"crowdsaleFinalized()","597d5c6e":"BiSaiToken(address,uint256)","597d6640":"getFreeFairy()","597df768":"buyPixelBlocks(uint256[],uint256[],uint256[],bytes32[])","597dfbaf":"confirmNode(uint256)","597e1fb5":"closed()","597ea5cc":"getUint8FromByte32(int8,bytes32,uint8)","597efd85":"UblastiToken(uint256,string,string)","597f7c35":"transferTechSupport(address,address)","597fef79":"funderBalance_()","59802e15":"makeBonus(address[],uint256[])","598052a3":"winPooling()","598077b9":"ownerPart()","5980d0d7":"_crowdSaleSupply()","5980e72d":"getSeedPercentageForGameId(uint256)","59810024":"VICETOKEN_ICO_IS_A_SCAM()","59813a0e":"allowToken(address,address,uint256,bool)","5981f187":"bookingBalanceOf(address,address)","5982688f":"revenueShareList(address)","59828c99":"FLIPPINESSROUNDBONUS()","5982a30f":"setFriendsFingersRateForCrowdsale(address,uint256)","5982a6bb":"DiipCoin()","59830bf4":"LogBidCompleted(bytes32,bytes32,bytes32)","5983ae4e":"hasher(address,bytes32,uint256)","59841fe9":"newRun(bytes32,address,string)","59849d30":"maxCreatorWithdraw()","5984d7ad":"buyHeart(address)","59852686":"transferEth()","5985ac40":"affiliateNetwork()","598647f8":"bid(uint256,uint256)","59869576":"TestERC20Token(string,string,uint8)","5986ce23":"setdteamVaultAddr1(address)","5986dbe4":"ccUserCount()","5987e370":"canJoin(uint256)","5987f859":"setInputs(string,string,string)","5988899c":"estimateDaiSaleProceeds(uint256)","59890fd2":"mod_product(uint256,uint256,string,string,string,string,string)","5989c283":"createChannelERC20(address,uint192)","598aa1fc":"checkEndorsement(address,uint256,address)","598ab2c9":"supplyRest()","598abc9c":"getListTeam(uint256)","598ac8f2":"permille(uint256)","598adef6":"addDepositor()","598af9e7":"allowance(address,address,uint256)","598b771d":"IOVContract()","598d34b7":"distributeBTR(address[])","598d772a":"changeEtherVault(address)","598db132":"setProviderIsForRent(uint256,bool)","598e3183":"newToken(string,string,uint256,address,uint256)","598e728a":"TIXIToken()","598e9eeb":"transferir(uint256,address)","598f512b":"Token(uint256,string,uint8,string,bool)","598f6dec":"reserveTimeLock()","5990e665":"NetworkSocietyToken()","59912df1":"totalTokensDestroyed()","59915fd3":"CheckRefundIsFair()","5991c0dd":"TSTEST3()","5991faf5":"contributors_countdownDate(address)","59923274":"sendFromBountyWallet(address,uint256)","59927044":"teamWallet()","5992f2a1":"_createVoter(string)","599312ec":"rescueCatHashCheck(bytes32)","599362d0":"_setBackgroundValue15(uint256)","59939e21":"getApprove(uint8)","599466fe":"abortCrowdfund()","5994d984":"TRUE()","59953744":"createVestingContract()","5996228e":"upgradeResistance(uint256)","599651f3":"setStartAuctionFee(uint256)","5996769e":"_getDefaultOperators(bool)","59970a08":"OneKeyToken(uint256,string,uint8,string)","59974e38":"distributeRewards(uint256)","5997ed4c":"DevFee()","59988dce":"newQuestioner(address)","5998e641":"getStrategyTokenByIndex(uint256,uint256)","5999917c":"get_cross_chain_nonce()","5999d385":"walletICO()","599b3e21":"buytokens2()","599b6808":"balanceList(uint256)","599c8761":"decodeParamsList(uint256)","599db6bd":"unsowed(address)","599dc6be":"setItemStoppedStatus(bool)","599efa6b":"refundEscrow(address,uint256)","59a02589":"ico_PRICE()","59a02652":"miningWarContractAddress()","59a0b995":"AiraEtherFunds(address,string,string)","59a0e583":"lastBlock_v9()","59a131e2":"CrankysLottery()","59a23200":"authorizeTransaction(uint256,address)","59a29c6f":"no_of_tokens()","59a2c86f":"requestPayout(uint256,address,address)","59a3e577":"createClaim(address[],uint256,address)","59a4669f":"increaseJackpot(string)","59a536b0":"presaleWei()","59a547b0":"recordCommission(uint256)","59a58647":"setMaxCards(uint256)","59a591be":"setCrowdsaleTimes(uint256,uint256,uint256)","59a5f12d":"player2()","59a69426":"setStatuses(address)","59a765f9":"sendInvoice(string,string,string,string)","59a78c1a":"deathData_v8()","59a7b3fe":"hourlyRate()","59a7f754":"acquireWildcard(uint16)","59a80f0f":"setCurs(uint256)","59a83074":"set_participant_num_of_pro_rata_tokens_alloted(address,uint256)","59a87bc1":"buy(uint256,uint256,address)","59a8b6a3":"OptaToken()","59a941a6":"setApp(string,string,string,uint256)","59a9a63f":"isVulnerable(uint64,int8)","59a9a980":"isCosd(string)","59aa80b8":"getTransfer(string,uint256)","59aaa456":"tryAltOracles(bytes32,uint256,uint256,uint256,bytes32,bytes32,uint8)","59aaaf86":"changeBlocPerEth(uint256)","59ab0306":"BuyTickets(uint256)","59ab0dd1":"JACKPOT_TOKENS_PERCENT()","59ac5b32":"createProject2()","59ac5c6d":"_shift(uint8)","59ac70ae":"totalTimeRange()","59acb42c":"createdAtBlock()","59acbcb1":"crownTransfer(address,uint256)","59adb2df":"returnUint256(uint256)","59adda9b":"checkOwnerFailedToSetTimeOnMeeting()","59ae2073":"GameNeedsTick(uint256,address,uint256)","59ae340e":"resumeMinting()","59ae6e34":"placeImage(uint8,uint8,uint8,uint8,string,string,string)","59aef196":"pauseCutoffTime()","59af143d":"beBanker()","59b09b25":"makeCount()","59b0a174":"transferLockUntil(address)","59b0d931":"removeBlockList(address)","59b112d8":"getServicesForApplication(address)","59b119dc":"ComeCoin()","59b11d6c":"setBetclose(bool)","59b17b43":"getTellerBalance(address)","59b25720":"fillUpTo(address[5][],uint256[6][],uint256,bool,uint8[],bytes32[],bytes32[])","59b2da20":"Raffled(uint256,address,uint256)","59b350fb":"time_of_token_swap_start()","59b36e3e":"partnerSaleWei(address)","59b373f2":"getExistsStatus(uint256)","59b4993c":"userAddressCheck(bytes32)","59b4ee89":"addVpf(bytes32,uint256,uint256,uint256,string,uint256,uint256[])","59b51bd1":"approveCertification()","59b563b5":"addRobot(address)","59b56a59":"HYIPToken(address,string,string,uint256,uint256)","59b58dba":"createCloneToken(address,uint256,string,string)","59b62658":"AddFishByToken(address,uint256)","59b6a0c9":"maxCapacity()","59b6f377":"transferFromContract(address,uint256,uint256)","59b79610":"sendUnsoldTDETokensToPlatform()","59b8d74e":"ACasadiAmiciToken()","59b910d6":"setStorageAddress(address)","59b9510a":"isAddressAllowedInPresale(address)","59b95f5a":"buyBlocks(uint8,uint8,uint8,uint8)","59b9a192":"buildToken(uint192,uint192,uint160,uint32)","59ba1dd5":"_fulfillPreapprovedPayment(address,address,uint256,address)","59ba2628":"transferCampaignCreator(address)","59ba59f1":"ETHFundDeposit()","59badbec":"CheckPhException(bytes32,uint32)","59baef40":"setNewController(address)","59bb6b5f":"TretanToken()","59bb7867":"setTournamentEntranceFeeCut(uint256)","59bc3d47":"Agreement()","59be5e45":"getTotalSoldTokens()","59be7e99":"getDonationAmount()","59be9cc0":"devTokensHolder()","59bed9ab":"Transacted(address,address,bytes32,address,uint256,bytes)","59befd58":"releaseTime2()","59bf1abe":"getBlackListStatus(address)","59bf5d39":"getReserve()","59bf77df":"confirmationCount(bytes32)","59bfd388":"setupPeriodForSecondStep(uint256,uint256)","59c13403":"FEE_MIN()","59c140be":"insertBonus(uint8,uint256,uint256)","59c14cf1":"mastery(address)","59c21fd8":"initDepth()","59c27917":"GenChipLevel_Extra(uint256,uint256,uint256)","59c281da":"openFirstRound(uint256,bytes32)","59c2aad0":"unitsToSell()","59c2af55":"StagedCrowdsale()","59c2b584":"reserve_fund()","59c2edee":"CrowdsaleContribution(address,uint256,uint256)","59c33f94":"PriceUpdate(uint256,address)","59c39094":"withdrawDate()","59c3f3e0":"setPoolContract(address)","59c3f7f0":"createWallets(uint256)","59c42f75":"unreleasedCount()","59c44539":"GotecoinToken()","59c4e612":"icoSoftcap()","59c55429":"refundBond(uint256)","59c634b0":"getContributorAmount()","59c656df":"allowRefunds()","59c77133":"createNewHodl(uint256)","59c7a893":"participantsOf(uint32)","59c87d70":"request(bytes32)","59c88347":"isEmitting()","59c8969e":"withdraw(address,uint256,bytes32[],uint256[],bytes32[],uint256)","59c8bf9c":"OrpheusMarinaBangkok()","59c8d647":"buy(bytes32,bytes32)","59cbf125":"GetETH(address,uint256)","59cc334a":"getItem(uint256,uint256)","59cc721c":"BONUS_TIER1()","59ce0a8f":"RuletkaIo()","59ce0bb8":"_saveParams(uint256[])","59ceb36f":"last_demurrageable_balance()","59cf3173":"Reclaim(uint256)","59cf901a":"preIcoTokensDistributed()","59cfaf6e":"gameWithdraw(uint256)","59d1d43c":"text(bytes32,string)","59d20b55":"committedValidators(uint256)","59d213fe":"contributePreSale()","59d27be8":"endEthGetToken()","59d2af39":"testFooSend()","59d313de":"MatchResetDeadline(uint256,uint256)","59d33d73":"bountyReserveTokens()","59d3ce47":"Activate()","59d3d57e":"totalUserLost()","59d3d632":"verifierAllocation()","59d3dad9":"miscNotLocked()","59d4447a":"MingToken()","59d52e2b":"XmonetaSale()","59d5335b":"refPercent()","59d55194":"getPet(uint256)","59d5d02a":"transferFee(address,address,uint256)","59d5dc11":"PhardusNetwork()","59d667a5":"bid(address,uint256)","59d6b35b":"lastProof()","59d7d46f":"doInvest(address,uint256,address)","59d89175":"setSellCommissionBps(uint256)","59d90c19":"addLockedAmount(uint256)","59d96db5":"terminate(uint256,string)","59d998e4":"transferHashOwnership(uint256,address)","59d9b2b7":"getTokenOwnership()","59dac714":"hashTo256(bytes)","59db5bac":"VisitCount()","59db9eb0":"deallocate(address,uint256)","59dc6d5c":"setDollarBalance(address,int160)","59dc735c":"getClient()","59dd35da":"ICOPrice()","59dd7ad4":"batchTransferFroms(address,address[],uint256[])","59dd8f34":"NRB_Tokens()","59dfdec8":"totalPlayCount()","59e026f7":"internalTransfer(address,address,uint256)","59e02dd7":"peek()","59e05c5f":"delay_pool_drain_block(uint256)","59e08fe1":"isSaleOver()","59e09fec":"getLockedAmount_dakehus(address)","59e0b91a":"LMOSupply()","59e0cf23":"setOraclize(address)","59e148fc":"getLastOfferId()","59e1667d":"testControlCreateWithForeignParentNotInUse()","59e20f69":"addJobInvitation(uint256,address,string)","59e23ccf":"computeBlockPrice(uint256,uint256,uint256)","59e2d30e":"testThrowBlobStoreNotRegistered()","59e30226":"getTradeOfferSenderItems(uint256)","59e33e35":"indexdate()","59e3e1ea":"testDivAdd(uint256,uint256,uint256,uint256)","59e415d3":"crowdETHTotal()","59e4c4ca":"createLover(string,string,string)","59e4eec9":"startMarket(uint32,uint256)","59e529cc":"extra_bonus()","59e54095":"getRefundValue()","59e541af":"getTokenInfoMaxPerBlockImbalanceList()","59e5d4b5":"hicsToken()","59e6800c":"depositToken(address,uint8,uint256)","59e777f6":"newHeir(address,uint256)","59e86488":"hasteamadjacency(uint16,uint16)","59e94862":"getEthToTokenOutputPrice(uint256)","59e994ca":"endTimeOfBids()","59e99db2":"_mint(bytes32,uint256,bytes32,address)","59e9fb1b":"IPFShash(string)","59ea2647":"yearTwoMultiplier()","59ea287d":"pre()","59ea6d80":"setNegativeArray(int256,int256)","59eb8224":"trancheCount()","59ebb321":"isManagementProxy(uint32,int256,address)","59ebbe35":"cancelFinishMintingRequest()","59ebeb90":"Open()","59ec29fe":"successICO()","59eca3e2":"manipulateSecret()","59eddf34":"getSchool(uint256,address)","59eecbf9":"assert1(bool)","59eee5c7":"hosting(uint256)","59efcb15":"execute(uint256,bytes)","59f02c4d":"getOraclizePolicyId(bytes32)","59f121a8":"setCreator()","59f1286d":"queryCredit(address)","59f47523":"newUserBonusCardTradable()","59f4bbd2":"indexPaidAffiliate()","59f568b9":"setDefaultNumberJuror(uint16)","59f5e0ce":"purchase(string)","59f61c74":"nextKey(uint256)","59f62cdc":"buyCalcAndPayout(address,uint256,uint256,uint256,uint256)","59f69ab6":"enforceWhitelist(bool)","59f769a9":"activeBalanceOf(address)","59f8714b":"changeableTokenCount()","59f96737":"convertMetToEth(uint256,uint256,int256)","59f96ae5":"postSellOrder(address,address,uint256,uint256)","59f974ce":"checkFundingGoalReached()","59f9a58f":"_vouchersInSharedPool(uint16)","59f9edd0":"sultantoken()","59fa0663":"setWhitelistOut(address,bool)","59fa34df":"findCurrentIndex(address)","59faf062":"bidPrice(bytes32)","59fb34bd":"_createRide(string,bytes7,address,uint256)","59fc2ba4":"DRONEXTOKEN()","59fd510a":"extraBalanceNeeded(uint256)","59fd95ae":"BTCCToken()","59fde1e0":"distributeRevenue(uint256)","59fe2720":"updatePollDescription(uint256,bytes,uint8)","59fe7279":"ADMINISTRATOR()","59ff5b55":"getMagicNumber()","59ff6473":"redistributeFees(uint256)","5a0024ae":"VerifyCheque(string,string)","5a0089d3":"getChildContractAddress(uint8)","5a012b17":"landsSold()","5a0178af":"update(uint256,uint256,bytes32)","5a018e01":"RESERVES_STAKE()","5a02dcde":"budgetWallet()","5a02ec19":"depositVault(uint256)","5a0391f2":"BuyForEtherTransaction(address,uint256,uint256,uint256,uint256)","5a04ce5b":"setMinBalance(uint32)","5a051c47":"_purchaseLoopFifo(uint256,uint256)","5a052dff":"buyPixel(address,uint16,uint24,string)","5a055a33":"Enterprise()","5a059a44":"composeJingle(address,uint256[5],uint256[5],string,string)","5a05fff0":"bountyRewards(address)","5a0646e2":"InitAssignCTC()","5a06f1e3":"TMEXAddressSet()","5a071517":"existPublicKey(address)","5a0718d0":"ICOadvisor1()","5a0753ac":"devFeeBalance()","5a079207":"Hydro()","5a083f54":"transferFromCheck(address,address,uint256)","5a09f2f4":"setHouseFee(uint256)","5a0ae8d5":"emitSkillRatingGiven(address,address,uint8,uint256,uint256,uint256,uint256)","5a0b7663":"getMaxResponseStates(uint256)","5a0ce676":"setParams(uint256,uint256,uint256)","5a0d9627":"updatePlayerMask(uint256,uint256,uint256,uint256,uint256)","5a0ebf94":"TokensReceived(address,uint256)","5a0f385a":"reverseTransfer(address,uint256)","5a0f3c40":"_foundationSupply()","5a1024d5":"setSinistre(uint256)","5a10d868":"Diyflex()","5a119ef2":"addIcoAddress(address)","5a1230bf":"computeCallKey(address,address,bytes4,bytes32,uint256,uint8,uint256)","5a129164":"vestingBeneficiary()","5a129e97":"byte32ToString(bytes1[32])","5a12b581":"GetUser(string)","5a13340f":"GetApplicant(bytes32)","5a140df0":"_remove(uint256)","5a142887":"grantAccessDeposit(address)","5a149f08":"finalizeNextUpgrade()","5a15656c":"developerCommissionFee(uint256)","5a15c373":"transferByOwner(address,address,uint256)","5a17877a":"LCDToken(address,address,address,address,address,address)","5a17aa41":"getContentTip(bytes32,address)","5a181478":"setPayoutCumulativeInterval(uint256)","5a182b8b":"SellLoan(uint256,uint256)","5a186c77":"init(address,uint256,uint256,uint256,uint256[],uint256,uint256,uint8)","5a18ae3d":"apply(string)","5a18f9ff":"isFundingNeeded(address,address)","5a1a1b67":"zTransferWinningBets()","5a1a8593":"bidBatch(uint256[],address)","5a1b0c0b":"LogBidCanceled(uint256)","5a1b472c":"getmykeyid(address)","5a1b96a2":"FiduxaCoinCrowdsale(uint256,uint256,uint256,uint256,uint256,address)","5a1bdaa1":"deusETH()","5a1cc358":"getChannelRank(address,uint256)","5a1e0a46":"cancelVote(uint8)","5a1e6ca1":"endRound(uint256)","5a1e6fc6":"setEmployeeAddress(uint256,address,address)","5a1e921b":"isTradeSupported(address,address,uint256)","5a1e9c79":"ProofOfKennyCoin()","5a1f3c28":"getCollection(uint256)","5a1f892c":"addPresaleContributors(address[])","5a2056ba":"rejectPayments()","5a212e99":"stringandbytes(bytes)","5a22d81a":"buyCEO()","5a236389":"getFileLoc(uint256)","5a237491":"nextWithdrawDayTeam()","5a23932b":"cryptaurus()","5a2450c3":"EventHub(address)","5a24c6a9":"chart_call()","5a272403":"SetAdmin(address)","5a275879":"toHex(address)","5a2791ed":"block24h()","5a28340a":"accessOperatingBudget(uint256)","5a297cae":"claimApis(address)","5a29ee7b":"sendRemaningBalanceToOwner(address)","5a2a3039":"setTopWinnerPrizes()","5a2a4452":"_addRole(address,string)","5a2a553f":"isCollateralWithinMargin(uint256,uint256,uint32)","5a2a75a9":"getTranscoderPoolMaxSize()","5a2b31d9":"B24Token()","5a2b488e":"calculateRefundedEth(uint256,uint256)","5a2bcc18":"mintAmount()","5a2bf25a":"setAddressValue(bytes32,address)","5a2c0f78":"mintMarketMakerApproval(address,address,uint256)","5a2de12f":"ChipTreasury()","5a2e311b":"capDefault()","5a2e4a11":"raisedWithdrawal()","5a2ee019":"m()","5a2f71d4":"setEquipmentTrainingFeeMultiplier(uint256)","5a2fe63a":"isInMainSale()","5a30b194":"__address0__()","5a317cb3":"SHA256HashRegister()","5a31ab2f":"PresaleClosed(bool)","5a325fb3":"_setPlatformFeeRate(uint128)","5a32d070":"trickleDownBonusesReleased()","5a3320ff":"isCrowdsaleOpen()","5a338506":"airdropToAddresses(address[],uint256)","5a34508b":"delistAddress(address)","5a34ced1":"disableFundingWallets(address,address)","5a353193":"KrakenPriceTicker()","5a353f98":"T20coin()","5a354e04":"ProxyUser(address)","5a35eb7c":"isWinSlot(uint256,uint256)","5a36c394":"executeOrder(uint256,address,address,uint256,uint256,uint256,uint256)","5a36e0da":"getProjectCreator(uint256)","5a36f4f3":"setMintableProperty(uint256,bytes32,bytes32)","5a37ae58":"Show_the_name_of_Option_A()","5a388a43":"MVM()","5a390a5f":"breedingMarket()","5a3a05bd":"subRegistrar(bytes32)","5a3a6ef8":"TXL()","5a3b7e42":"standard()","5a3c0287":"claimTokensFromTokenAiNetworkToken(address)","5a3c8826":"dynamicCeiling()","5a3dd13f":"getScoreTotal()","5a3e251f":"halvingPeriod()","5a3f2672":"tokensOf(address)","5a3f88f0":"changeGeneration(uint40,uint16)","5a4071fe":"lockInternalAccount(address,bool,uint256)","5a40bb8f":"setAllergies(bool)","5a40ec7e":"verify(uint256,uint256,uint256,string,bytes32[2],bytes,bytes)","5a41217e":"underMaintenance()","5a414ff6":"getAuthorizedOwners()","5a416920":"swapFor(address,uint256,address,address,uint256,uint256,uint8,bytes32,bytes32)","5a41d508":"setFlightPrice(uint256)","5a42e85f":"SICX()","5a4362e5":"closeDown()","5a43fa90":"getTokenProposalDetails(uint256)","5a4426bc":"proposeLOC(string,address,uint256,string,uint256)","5a444139":"canBurnWhiteList()","5a446215":"setNameAndSymbol(string,string)","5a4528c2":"distributionContract()","5a4537b0":"TransferableMultsig(uint256,address[])","5a46bb2b":"initChain(bytes,uint32)","5a46d3b5":"lockOf(address)","5a46f06c":"BANCOR_CONVERTER_FACTORY()","5a470aff":"setNthByte(uint256,uint256,uint8)","5a470b65":"gamePlayedStatus()","5a476e5a":"buyOrderBalances(bytes32)","5a481a7e":"ARBITRAGEToken(address)","5a4877c0":"timeLockedBeneficiariesDisbursedTo()","5a4a04a7":"OWNER_CLAWBACK_DATE()","5a4bffb8":"tokenPurchaseAmount(address)","5a4c07a0":"fillBlank()","5a4c822d":"setAdminPercent(uint256,uint256)","5a4cc5da":"Dunhil()","5a4d8e59":"getBAU2Length(bytes32,address)","5a4ded51":"tokenBuyCalc(uint256)","5a4e69f0":"KyberContirbutorWhitelistOptimized()","5a4fc9c5":"lookup(int256)","5a500066":"WSXToken()","5a5132be":"ambix()","5a51d1df":"sendReward(uint256[])","5a525491":"safeIndexOfTaskId(uint256)","5a527afb":"testFooApprove(uint256)","5a52da30":"didVoteForName(address,string)","5a52ecf6":"getSignedConfiguration()","5a531015":"getLotteryAtIndex(uint256)","5a5383ac":"canExitPool()","5a53fe20":"multiApprove(uint256[])","5a543683":"BuyerLotteryTimes(address)","5a54cd46":"proceedEtherDeals(uint256)","5a54e755":"hashMachine()","5a55c1f0":"getVote(uint256)","5a5638dc":"policyTokenBalanceFromEther()","5a56a31c":"FeeApplied(string,address,uint256)","5a57a901":"VIPSToken()","5a5804b3":"getAllocation(uint256)","5a589fc9":"authUser(string)","5a58cd4c":"deleteContract()","5a591a4e":"promotionDataRecord(address,uint256)","5a592380":"vestingPlans(uint256)","5a593a6e":"totalreleaseblances()","5a596aa4":"CheckBalance(address,address)","5a5b32b7":"_setHatValue10(uint256)","5a5c8068":"oraclize_setNetworkAuto()","5a5d096c":"isOwner(uint256,address)","5a5d3350":"KKToken()","5a5ddcf6":"startStopICO(bool)","5a5e0024":"SecondEtherLimit()","5a5e0074":"etherForOwner()","5a5e861e":"currentPayment()","5a5ebebf":"withdrawRent(address)","5a5ec54a":"neglectOwner()","5a609b96":"investorsIter()","5a61c40a":"setwithtoken(address)","5a625393":"ValueTokenBase(uint256,string,string,uint8)","5a628525":"reveal(address,bytes32)","5a628e17":"getWishIdxAt(address,uint256)","5a63cba0":"checkSaleLimit(uint256)","5a63feb8":"__targetExchangeAndSpendCallback(address,uint256)","5a648bc5":"WithdrawAll()","5a64ad95":"mintingFee()","5a64b786":"deposit_dividends()","5a650f45":"numBountyCredits()","5a6535fc":"call(bytes)","5a657452":"COD()","5a658f6b":"directorNode()","5a65f004":"isSynthesizeAllowed()","5a67a20d":"endingPrice()","5a67f389":"timeGone(uint256)","5a6814ec":"thisisfine()","5a686699":"post(uint128,uint32,address)","5a69fe0e":"TokenERC20(address)","5a6ad1e1":"multivestBuy(address,uint8,bytes32,bytes32)","5a6af33b":"subtrBalance(address,uint256)","5a6b26ba":"withdrawal(address,uint256)","5a6b3a79":"assignBounty(address,uint256)","5a6c6408":"updatePolicy(bytes32,address,uint32,uint32,uint256,uint256,bool)","5a6c787e":"updateWithMPO()","5a6cd237":"latestTokenBalance()","5a6d663c":"notifyTransfer(address,address,uint256)","5a6dad3c":"setFreelancerParams(uint256,uint256)","5a6e8980":"editusetaddress(uint256,string)","5a6f7aef":"tweakUpgrading()","5a703223":"GetToken(address,uint256)","5a70686a":"mintChip(bytes32)","5a70fe72":"GetInvestedAmount()","5a71be21":"ethEur()","5a732dd5":"CCPayoutArb()","5a74a715":"setWeiForMcr(uint256)","5a74dee5":"multiAccessRemoveOwnerD(address,address)","5a7511d0":"put(uint256,string)","5a753c6e":"getWarlordDistributedRandom(uint256)","5a75aa1c":"ChangeRate(uint256)","5a75b8d5":"currentHodlerId()","5a764631":"setSkillName(uint256,bytes32)","5a766620":"neglectGuess(int256)","5a768e4a":"ECONOMY_BOOST_TRADE()","5a769366":"sadf(address)","5a76e73e":"getNoOfTokens(uint256,uint256)","5a778cf9":"batchPresale(address[],uint256[])","5a78897b":"setFunctionSixPrice(uint256)","5a7a4c1e":"_applyPct(uint256,uint256)","5a7a8850":"rollWithSeed(bytes32)","5a7adf7f":"preSale()","5a7b4097":"fundBalanceOf(address,address)","5a7b57f2":"MadoffCoin()","5a7cb38f":"tokenTransferAddress()","5a7da6b5":"burnUpdateTokenFrom(address,uint256)","5a7db533":"getRef(address)","5a803611":"addDealerForSender(string)","5a81018a":"getClientCount()","5a811766":"replaceAdmin(address,address)","5a813fd5":"test_insert_findWithHintPrevAtPosition(int256)","5a8194d2":"getVersionIndex(bytes32,bytes32,bytes32)","5a81b5b9":"collectMegaJackpot(uint256)","5a825cbb":"getPayment(uint256,uint256)","5a851ffb":"calculateDiceWinner(bytes32,bytes32,uint256)","5a857565":"buyTokensInternal(address,uint256)","5a85d2fa":"playerSignUp(address)","5a861838":"addHpbNodeBatch(address[],bytes32[],bytes32[])","5a8654ad":"End6()","5a86c914":"getRateIcoWithBonusByDate(uint256)","5a87053e":"privateBonus()","5a87c380":"getRewardListLength()","5a8830e2":"partial_refund_my_ether()","5a88b15f":"Halo3DShrimpFarmer(address)","5a89b376":"contractDecimalsUpdate(uint256,bool)","5a8ac02d":"second()","5a8b1a9f":"upgradeTo(string,address)","5a8b55e2":"IsWildCardCreatedForCategory(string)","5a8bbba9":"createNewSecret(string,bytes32,bool)","5a8bbee1":"Group_4()","5a8cadb1":"migrateAll(address)","5a8cf571":"changeControlWallet(address)","5a8d580e":"forceNSFW(uint256)","5a8d6cea":"transferUnsoldIcoTokens()","5a8dd79f":"getDesignatedCaller(address,uint256)","5a8e9d66":"settle(address,uint32)","5a8ef28a":"GBP(uint256)","5a90a49e":"exemptFromFees(address)","5a9156f0":"LogAddUser(address)","5a91e5e9":"removeFabric(address,address)","5a93bf71":"delReferral(address,address)","5a93cc8f":"addBonus(address,uint256)","5a93f1a1":"_deleteCompany(bytes32)","5a9448e2":"multisigFunds()","5a94cd0c":"requestChangeStakingFees(uint80,uint80,uint80,int256,uint80,int256,uint256,int256,uint80,uint80,uint256)","5a95edd9":"OTHERCRUISER_FTL_SPEED()","5a960216":"ethUsd()","5a969f94":"InternationalModelChain()","5a975128":"minGamble()","5a979a5c":"LockContractOwner(address)","5a97b84a":"finishUserDistribution()","5a983451":"totalTokenMintedAngel()","5a992188":"getUserBet(uint256,uint256)","5a99719e":"getMaster()","5a998a09":"totalRoyalty()","5a99b525":"payoutRoyalties()","5a99d123":"unsetNotaio(address)","5a9a49c7":"verify(bytes32[],bytes32,bytes32)","5a9aa592":"currentWallet()","5a9b0b89":"getInfo()","5a9bb087":"claimContractTokens(address)","5a9c0a49":"setBasePrice(uint256[20],uint256,uint256,uint256,uint256)","5a9c2724":"create(string,string,address)","5a9c3ee4":"mainSaleDeadline()","5a9c84f3":"maximumTokensForSecond()","5a9cfac8":"hasPosts()","5a9d27dc":"createReleaseTokenAuction(string,uint256,uint256,uint256)","5a9d5c3c":"PCPP()","5a9e03ca":"isIssuedBefore(bytes32,uint256)","5a9e426b":"refundMe()","5a9e75a2":"maxBorrowAmount(address)","5a9e91df":"zlotsJackpot()","5a9f2def":"scheduleCall(bytes4,bytes,uint256,uint256)","5a9f97d1":"currentSaleDay()","5a9ffc35":"circulatingFame()","5aa00cc4":"_emitJobCanceled(uint256)","5aa037dc":"purchasedTokenBalanceOf(address)","5aa1eb4c":"createAdjudicator()","5aa23a52":"sendRewardBILL(address,uint256)","5aa3952a":"GERCoinCrowdsale(uint256,uint256,uint256,address)","5aa3d2b0":"purchasedAmountBy(address)","5aa4470f":"setLogicContract(address)","5aa451e9":"updateOfferingReputation(address,uint8)","5aa4c8a9":"addToMap(uint256,uint256)","5aa5b9d1":"LogPersonNew(address,uint256,uint256)","5aa61ec6":"getExchangeRatesLength()","5aa63592":"DeadMansSwitch(address,address,uint256)","5aa68ac0":"getParticipants()","5aa6b1f0":"reduceFiatCurrencyRaised(uint256)","5aa6cf97":"payout(uint256,uint256)","5aa720c3":"linkTaskToUser(address,address)","5aa77d3c":"pendingContractOwner()","5aa83129":"store(bytes,uint256,uint256,address)","5aa86386":"getMinNextBet(string)","5aa8a42c":"updateOwners(uint256,address[])","5aa8e281":"freezeAccountCoin(address,uint256)","5aa94a68":"computeResultVoteExtraInvestFeesRate()","5aa97a3b":"agreeNeg(string,uint256)","5aa97e16":"BBCPrimeEx()","5aa97eeb":"getMarkets(bytes32[],address)","5aaa250a":"TokensCappedCrowdsaleImpl(uint256,uint256,uint256,address,uint256)","5aaac1d1":"fundingMaxCapUSD()","5aab1822":"stateEndDate()","5aab25b6":"isRedenominated()","5aab4ac8":"motd()","5aac8aad":"ICO_TokenValue()","5aad0450":"addVestingAllocation(address,uint256)","5aad507b":"userTotalCredit(address)","5aad7c56":"calculatePMAFromFiat(uint256,string)","5aae456a":"potatoTotalSupply()","5aae843e":"doPreAllocations()","5aaec2b1":"isdelegatinglisted(address)","5ab01088":"joinPreSale(address,uint256)","5ab027b0":"masterAddress2()","5ab0e470":"getShortPositionState()","5ab14385":"doProxyAccounting(address,uint256,uint256)","5ab1a0e2":"JungleScratch()","5ab1bd53":"getRegistry()","5ab2ff61":"read_u64_array()","5ab30d95":"bobMakesEthPayment(bytes32,address,bytes20,uint64)","5ab31a60":"drawNumber(uint256,string)","5ab35302":"ProofofHumanity()","5ab3ae21":"privatesaleTokens()","5ab3ded3":"changeDonationWallet(address)","5ab3fbc9":"BGB_Token()","5ab47550":"firstDayCap()","5ab4f162":"getVote(address,address)","5ab50913":"_recalculateAirdrop(address)","5ab58d64":"totalLockedHavvens_limitedSum()","5ab5956e":"startICOStage6()","5ab5d07d":"CROWDSALE_MAX_ACES()","5ab68072":"carTaxiCrowdsale()","5ab6eb7a":"Tabbo()","5ab7603a":"multivestBuy(address,address,string)","5ab7f1a8":"donatedAmount()","5ab81246":"newItem(uint256,string,string)","5ab827f6":"claimableRefund()","5ab89248":"AAcontributors()","5ab92022":"frozenTransfer(address,uint256,uint256,bool)","5ab98b8d":"DragonReleaseableToken(address)","5ab9bb26":"changeBonus(uint8)","5abaaa01":"unicornTokenAddress()","5abacc89":"RANGESTART_9()","5abb37d6":"cancelGame(address)","5abc3339":"create(bytes32,bytes32,bytes32)","5abc52d4":"SALE2_RATE()","5abcc417":"createCastle(address,uint256,string,uint64,uint64,uint64,uint64,uint64,uint64)","5abd7728":"setMinTaskValue(uint256)","5abedab2":"getAllTheFunds()","5abfafe2":"holdAddress3()","5abfc588":"CreatedDebt(uint256,address)","5ac04bed":"CreateMUSC(address,uint256)","5ac0dc11":"doTimeoutForComplainant(uint256)","5ac14935":"test_0_createOpenController_test_methods()","5ac1caa0":"_getCurrentRound(uint256)","5ac207ff":"totalLossAmount()","5ac2523a":"minimalTokens()","5ac26ebd":"devuelveTodasEncuestas()","5ac31e68":"getOrdersForNotary(address)","5ac36d70":"setTeams(address[],uint256[])","5ac3835d":"verifyTransferSignature(address,address,uint8,bytes32,bytes32)","5ac44089":"setHardCapInCents(uint256)","5ac48043":"slice(uint256[],uint256,uint256)","5ac49ba1":"CORE_TEAM_TOKENS()","5ac5c4f7":"Out(uint256)","5ac5ec65":"UsableToken(uint256,string,uint8,string)","5ac5f82c":"computeBonus(uint256)","5ac72734":"tkt()","5ac77ad1":"isLockedOpen()","5ac7a8d0":"UTBToken(uint256,string,string)","5ac7b9f3":"reapFarm()","5ac801fe":"setName(bytes32)","5ac849d2":"liveBlocksNumber()","5ac87d76":"addToWhiteList(address,uint256)","5ac942a7":"getIdentifierByIndex(address,uint256)","5ac9e90f":"readLib()","5aca6153":"setJackpot(uint8[4])","5acb053b":"toggleDead()","5acb6787":"createRegion(uint256,uint256,uint256,uint256)","5acba201":"canOverride(address,address,address,uint256)","5acbd8e1":"ProxyStorage(address)","5acce36b":"getEndowmentBalance()","5ace5128":"_emitBoardClosed(uint256,bool)","5ace83d7":"approveWinner()","5acee3d6":"getFutureTransLength()","5acf061a":"validateContract(address)","5acf34df":"check_data(bytes32)","5acf36ca":"fwithdrawal(uint256,uint256)","5acfefee":"sendProfits()","5ad1854b":"advisersPeriodAmount()","5ad22eb3":"canonizedPLCR()","5ad35ac0":"numberOfTokensAllocated()","5ad550bc":"testAbsMax()","5ad55aa5":"setCurrentSchellingRound(uint256)","5ad5ca74":"createXMLYTrade(bool,uint256,uint256)","5ad64dc5":"deletePick(uint256)","5ad6ba47":"getChronus()","5ad701c2":"getTier()","5ad74742":"ICO_Contract()","5ad7c05c":"getUserRequests()","5ad82148":"getUserid(address)","5ad871d5":"CrowdWithUs(uint256,string,address,uint256)","5ad8803d":"mintAndCall(address,uint256,bytes,bytes)","5ad95948":"wmin(uint128,uint128)","5ad9ca10":"changeBonus(uint8,uint256,uint256)","5ada0f51":"setTkContractAddress(address,address)","5ada7bee":"updateVerifier(uint256)","5adada87":"getPaymentsHeld(address)","5adb5813":"_setTokenURIBase(string)","5adb6ddb":"unfreeze(address,address)","5adc02ab":"confirmWhitelistAddition(bytes32)","5adc0c68":"getAddTokenParameters()","5adcba0e":"getEntryStatus(address,uint32)","5adcf475":"loikikdidad()","5addc540":"forceToken()","5addcc8f":"finishFromDutchAuction()","5ade3f8f":"NectarChina()","5ade7c8a":"getMyChest(address)","5ade9c3a":"removePass(bytes32,address)","5adf292f":"updateKittenCoinsRemainingToDrop()","5adfafdf":"updateRewardPercentageByIndex(uint256,uint256)","5ae11d5d":"order(address,uint256,address,uint256,uint256)","5ae17907":"getLossCount(address)","5ae23da2":"host_claim_earnings(address)","5ae23f84":"getTimeRangeInfo()","5ae270aa":"GToken()","5ae28fc9":"setMaxAge(uint256)","5ae46e93":"RaffleDappBook(string,uint256)","5ae4c04a":"viewprice()","5ae59132":"havvensReceivedForNomins(uint256)","5ae5b24f":"eosPizzaSliceSafe()","5ae5df8f":"deleteRef(string)","5ae61377":"getMaxBusinessesPerCity(uint256)","5ae63989":"WaraCoin()","5ae7ab32":"revokeKey(address)","5ae81492":"canceloffer()","5ae82dfd":"ariseWarrior(uint256,address,uint256)","5ae8a1e0":"updateUserPolicy(bool,bool,bool,bool)","5ae8daea":"getRoundJackPot(uint256)","5ae9c4d8":"getLineData2(uint256)","5aea5955":"ltc()","5aea92f5":"LingYanToken()","5aea9905":"BitrustToken(address,address,address,uint256)","5aeb45dc":"TetherToken()","5aebd1cb":"isRefundable(address)","5aebf21a":"getProviderAdmin(address)","5aebfd14":"createFile(bytes)","5aec11d4":"canUnshelf(string)","5aec2247":"balanceOfPreSale(address)","5aec57d8":"NewRound(uint256,uint256,uint256)","5aec6259":"getUInt(bytes32)","5aed37ef":"manualWithdrawEtherAdditionalOnly()","5aed4fa0":"safetyCheck(uint256)","5aee1bc0":"AirdropBeggarsCommunity()","5aee9431":"method1()","5aeee9f9":"incFightLose(uint256)","5aef2447":"getClaim(uint256)","5aef447c":"presaleBonusTokens()","5aef7de6":"avatar()","5aefd89d":"Freezing()","5af0649e":"confirmNewNotary(address)","5af0dc98":"blockSkills(address,uint256[])","5af0e1ae":"MyWillCrowdsale(uint32,uint32,uint256,uint256)","5af0f053":"approveMove(address,bool)","5af123f4":"bonusRate()","5af14603":"GetSetting(uint8,uint8)","5af1cf27":"foundersWallet1()","5af25671":"HugMathou()","5af2f821":"getCounterProposals()","5af36e3e":"refund(uint256,uint256)","5af3d5bf":"CWCfallback(address,uint256,bytes)","5af3e9d7":"bonusLOT()","5af40b77":"buildPreICOStage()","5af4cd99":"canBurnAddress()","5af5f7ba":"setWhitelisting(bool)","5af6333d":"getGoldInfoSerial(address)","5af73f3f":"getMinimalBalance(uint256,address)","5af77fff":"Contract()","5af82abf":"director()","5af86018":"VPE_Token()","5af89094":"getPMul()","5af95010":"Lenders(address)","5af9f68f":"getTxPaymentMCW(bytes32)","5af9f9d5":"TheSchmeckle()","5afa5036":"isCertified(address)","5afa5bb6":"minValue2()","5afb408a":"Penchant()","5afb540c":"getTokenCount(bytes32,string)","5afbfd4f":"getPublicBattlePokemon2()","5afc190d":"DrawHouse()","5afc250f":"getDad(address)","5afc7e59":"issueFrts(address,address,uint256,uint256,uint256,address)","5afd7627":"setCrowdsaleCompleted()","5afdc02c":"_9_dataSmerti()","5afe16ca":"GetProfile(uint256)","5afe5207":"setTokenSaleAddress(address)","5afeb106":"Sqrt()","5afecaaa":"getAllArtworksByOwner()","5aff457f":"createAuctionFromArray(address,uint256[],uint256,uint256)","5aff59e3":"addrCanPurchase(address)","5aff7e54":"returnBalance(address,bytes32)","5affcbb0":"cancelIndexedSaleByAddress(address)","5b00763e":"ProofOfTrevonJames2()","5b0088fb":"setPlotData(uint256,string,string,string,string)","5b01b5b3":"teamEmail()","5b01e233":"getyestodayget()","5b02b729":"setLockUpPeriod(uint256)","5b04cbb5":"current_state()","5b04e512":"defaultLockin(address,uint256)","5b050e77":"isInGame()","5b053c04":"maxPreSale1Token()","5b054f9b":"chainStartTime()","5b060530":"createToken(string,string,uint256)","5b064754":"LogChiSale(address,uint256)","5b067cce":"testCreateCostMain()","5b06fc49":"HASHPERETH()","5b07371e":"getAttackRanking()","5b0783f3":"setCapRec(uint256[],uint256[],uint256)","5b07d7d6":"_generateGene()","5b09a518":"process(bytes32,bytes[])","5b0a3843":"emergencyWithdrawal()","5b0a6c58":"EasyMineIco(address)","5b0ad787":"getBonusSetter()","5b0b02ec":"deathData_f4()","5b0b7cc8":"payday(uint256)","5b0c12a1":"DeploymentInfo()","5b0cfcd8":"KillContract()","5b0d4eff":"mineral()","5b0d5b55":"getTankEarning(uint32)","5b0d823a":"referalFundBalanceMap(address)","5b0dad8e":"bcdcMultisig()","5b0e1a2f":"releaseMyTokens()","5b0e52b0":"unlockExternalTransfer()","5b0e70ff":"RetireHodl(uint256)","5b0e8b82":"admin_list()","5b0ec73e":"MNCToken()","5b0ef4a4":"getEtherTicket()","5b0efb03":"MintAndTransfer(address,uint256,bytes32)","5b0fc9c3":"setOwner(bytes32,address)","5b1052f1":"getCoinBySlotId(uint64)","5b10b796":"_removeCapper(address)","5b10d05d":"donotDKKDappToken()","5b113414":"mul(uint32,uint32)","5b11380d":"ExTokeB()","5b1214c6":"setCrowdsale(uint256,uint256,uint256)","5b1295d2":"LNDToken()","5b12f1b6":"getAuthorizeContractIds(uint256,uint256)","5b135806":"test_basicWithTwoAssertAfterThrow()","5b14f183":"isPaused(address)","5b151fd2":"fifty_fifty()","5b154394":"GANA()","5b15afb6":"isOuvidoriaCadastrada(address)","5b16ebb7":"isPool(address)","5b174f0b":"EtheremonTransform(address,address,address,address,address)","5b17b190":"onLEXpaContract()","5b18056b":"contributionCount()","5b195526":"getMyCenter()","5b195c86":"transfer(address,uint24)","5b196dae":"getOuvidoriaNome(address)","5b19a8f3":"prossWinOrLoss(uint256)","5b1a77fe":"sentTokensToBountyOwner()","5b1aa9b1":"eugToken()","5b1b5d90":"getTransfer(bytes32,uint256)","5b1b9316":"firstRoundCosmosStart()","5b1c1625":"prepareClaim(bytes32)","5b1c893a":"UBC()","5b1d0d1e":"getOwnerAccessoryCount(address)","5b1dac60":"getSharePrice()","5b1dadc7":"PRICE_PRESALE_WEEK2()","5b1ea858":"signedTransferSig()","5b1eca38":"getTotalDevs()","5b1fe0cb":"sendGift(uint256,address)","5b1fef12":"GetPVPData(address)","5b206edb":"initAmount_()","5b208f76":"PlayX2()","5b209615":"ecrecover1(bytes32,uint8,bytes32,bytes32)","5b21a8b0":"NILEX()","5b21ba6f":"calculateProfit(uint256)","5b21e539":"decline(uint256,bytes32,bytes)","5b225526":"permissions(address,bytes32)","5b225d25":"getLatestManifestByName(address,bytes32)","5b228f88":"CLCToken()","5b229869":"getSenderArmyCount()","5b2298c8":"getSumAmountOfDisputedDealsProPatient()","5b22bbd2":"maxRaiseAmount()","5b2329d4":"checkGoalReached(uint256)","5b23bf8a":"forcePayout()","5b24f87d":"addManyToAllocationList(address[],uint256[])","5b250462":"join_private_room(bytes32)","5b251342":"KAnsariCoin()","5b25c137":"kycVerifiedBonusBps()","5b25ed6a":"tokensLimit()","5b284ecd":"InsertRank(uint256,uint256,uint256)","5b28919c":"getShipType(uint256)","5b28ad15":"dna6(uint256)","5b290c1d":"continueRedeeming(uint256)","5b29f2e4":"icoSold()","5b2a0e96":"multiSend(address,address[],uint256)","5b2a372d":"setTxDataBlockNumber(bytes32,bytes)","5b2aa4ae":"getMatchInfoList01()","5b2b0168":"_refundTokensPurchase(address,uint256)","5b2b2194":"addRange(address)","5b2b345c":"TOKENS_ACCOUNT_MAX()","5b2c44e1":"updateWhitelistInternal(address,address,uint8)","5b2ccdec":"hirerCancel(bytes16,address,address,uint256,uint256)","5b2cdda3":"returnWalletAddress()","5b2d7ad1":"calculate_shares_and_return(uint256,uint256,uint256,uint256,uint256,uint256)","5b2e1eb1":"ETHPonzi()","5b2e299c":"Hypercoin()","5b2e39e0":"releaseEcosystemJM(address)","5b2e9a81":"UpdateSellAgentSiteReg(address)","5b2ec3a5":"createInternalAuction(bytes32,bytes32,uint256,uint256,uint256,string)","5b2f515b":"artistName()","5b2f8752":"claimLoss()","5b303e16":"eatUnicorns(uint256)","5b30535d":"updateFactorReward()","5b30a647":"checkapproval(uint256,address,bool)","5b31035d":"getReward(uint64)","5b325e94":"AddTransactionAgainstExistingEntity(address,uint256,uint256,string,string)","5b329058":"DSGroup(address[],uint256,uint256)","5b33233b":"increaseOwnershipTokenCount(address,address)","5b34b966":"incrementCounter()","5b34f4e2":"newUserAccount(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","5b353cfa":"PMC()","5b35f9c9":"rewardsWallet()","5b364f3b":"chkend(uint256)","5b366096":"changeHDXcontract(address)","5b36fea6":"transferToICAPWithReferenceCallGas()","5b372532":"press()","5b378d39":"ContractorCreated(address,address,address,address)","5b379044":"dateTier3()","5b37e150":"create(bytes32,bytes)","5b387273":"allowWhiteList()","5b38863a":"btcRateMax()","5b389666":"USDCryptoToken()","5b389dbb":"powerUpContract()","5b38a8e6":"updateAssets(address,int256)","5b3a4895":"totalInvestedWithBonuses()","5b3a6f9e":"DomusToken()","5b3b136a":"getMyTokens()","5b3b20e1":"CLN_PER_ETH()","5b3b449f":"incentiveTokensLimit()","5b3bab74":"NeCashTokenSale()","5b3be4d7":"mintAirDropTokens(uint256,address[])","5b3bf07a":"getPrizeNumbers()","5b3d386b":"transferAnyCaerusToken(address,uint256)","5b3d4b16":"SCUDO()","5b3ddbf2":"firstAuctionConcluded()","5b3de1c8":"getBankEth(string)","5b3ea961":"ChangeSharedExpense(uint256,uint256,uint256)","5b3f4d24":"PrelievoProprietario(uint256,uint256)","5b405418":"CallSpread()","5b4078de":"decodePriceFeed(uint256)","5b40a584":"curId()","5b40d5dd":"unlockInBatches(address[])","5b419a65":"join(bytes32,bytes32)","5b42109d":"getNarcoLocation(uint256)","5b4246d4":"proportion()","5b440596":"getWithdrawValue(address)","5b453810":"changeEtherBonuses(uint256,uint256,uint256,uint256,uint256,uint256)","5b454832":"declareDefaultAsBorrower(uint256)","5b45b999":"setMiniMeToken(address)","5b46016e":"KickTheCoinFactory()","5b467404":"getCounts(address)","5b472771":"level_8_amount()","5b475e22":"STARTING_ANTHILL()","5b477c53":"updoot(uint256)","5b4786ea":"getValusTokenIssuance(uint256,uint256)","5b48165f":"lastBlock_v17Hash_uint256()","5b482ec1":"disconnectModule()","5b485314":"IEFBR14()","5b48684e":"optIn()","5b48c11b":"regRefcode(bytes32)","5b48e66a":"changeCroStatus(address,uint8)","5b49ebdf":"GiantWeedKiller()","5b4a54a9":"isCrowdsaleOver()","5b4b1c0e":"orientation()","5b4b73a9":"setData(uint256)","5b4be32b":"setSellStatus(bool)","5b4c084a":"updateHpbNode(address,bytes32,bytes32)","5b4c3543":"options(bytes32)","5b4c6994":"setArbitratorI(address)","5b4cc249":"newSale(address,uint256,uint256)","5b4cc320":"onOwnershipTransfer(address,uint256,bytes)","5b4ccc9d":"addParticipants(address[])","5b4d20d2":"requireWhitelistedAddress()","5b4df1ca":"ROLE_CONTROLLER()","5b4ef70b":"eth(uint256)","5b4f472a":"tradingStarted()","5b4f5feb":"assignCardOwner(address,uint64)","5b500996":"bringuPort(address)","5b508cf0":"createRegulatorProxy(address)","5b511030":"activateSecondPreIco()","5b519132":"getInitHash(bytes32)","5b51a6d8":"getMintDelegates()","5b51acff":"migrationTarget()","5b525b2c":"changeItemName(uint256,string)","5b528aaf":"KaiKuangChain(uint256,string,string)","5b528ba1":"bonusPer(uint256)","5b52b9db":"WLMTfinney()","5b52c7fb":"GROWTH_SUPPLY()","5b530196":"tokensOfkitty(uint32)","5b53d291":"advisersTotal()","5b5416ca":"unfreezeTimestamp()","5b548ab4":"mixAuto(uint256,uint256)","5b54f077":"promissoryUnits()","5b55169c":"minContribAmount()","5b556bf0":"ZeroExHandler(address,address)","5b56be8b":"prevEndTime()","5b56d57f":"getGameStartBlock(uint256)","5b588f26":"cfoWithdraw(uint256)","5b59af9c":"OwnershipAdded(address,address)","5b5ae956":"Bytes4ToByteArrayWithLength4()","5b5aed3a":"identityExists(uint256)","5b5b45ef":"privateOfferingExchangeRate()","5b5bbb31":"changeSettings(uint64,uint64,uint8,uint8,uint16)","5b5c7705":"withdrawPlayer()","5b5cf8cf":"PacersvsCavaliers420()","5b5d1d88":"TMRToken()","5b5d2c8f":"updateValue(bytes32,uint256,uint256)","5b5ddb94":"read(bytes,uint256,uint256)","5b5e450b":"masterKeyIndex(uint256)","5b5e760c":"getTokenWinValue(uint256)","5b5e7bbe":"setAssetsOnDeposit(uint256)","5b5ecf19":"CryptoSagaArenaRecord(address,uint32,uint8,uint8)","5b5f8b88":"transerFrom(address,address,uint256)","5b5fa6ba":"ownerTemp()","5b60fa6b":"createTeam(uint256,uint256)","5b61291c":"aekS()","5b621b2c":"_setMintableProperty(uint256,bytes32,bytes32)","5b624b6e":"setinfo(string,string,string)","5b630d59":"EFH(uint256,string,uint8,string)","5b633cf2":"getItemsIdsByTypeAndOwner(string,address)","5b63831a":"getMinimumPurchaseVZTLimit()","5b6427fc":"nextNumberOfWagersToMinimumTimeout()","5b65b9ab":"setFee(uint256,uint256,uint256)","5b65da64":"getPhaseSupply(uint256)","5b6682aa":"Tom(uint256,string,uint8,string)","5b66cc84":"transferLog(address,uint256,string)","5b680aa6":"spentAllowance()","5b68a49d":"cancelVoteForCandidate(address,uint256)","5b68e09b":"appAccounts(uint256)","5b68f3a6":"Loggable()","5b6a42b8":"setNewMonster(uint256,uint32,address,string,string)","5b6a54bc":"adjustTransactionFee(uint256)","5b6a9eb4":"minCost()","5b6aa3c2":"isMinTokensReached()","5b6accb2":"manualBatchTransferToken(uint256[],address[])","5b6b431d":"Withdraw(uint256)","5b6beeb9":"getHash(string)","5b6c508c":"exitAll()","5b6ca99a":"setHint(string)","5b6e2492":"getDesignatedReporter()","5b6e7be2":"updateTokenBalance()","5b6edf78":"DISCOUNT_TOKEN_AMOUNT_T1()","5b7121f8":"getMinter(uint256)","5b714690":"valueBeforeFeesWereReduced(uint256)","5b715ae0":"referralProgrammeWallet()","5b7214b6":"m_ETHPriceUpperBound()","5b72c3b7":"eraFromMokenData(uint256)","5b72cdd0":"estimateBalanceOf(address)","5b73024a":"opAddr()","5b73b332":"extendTge(uint256)","5b7450fc":"isOperable(address)","5b752d5d":"getjackpot()","5b754491":"transferFromTx(address,address,address,uint256)","5b75dd8d":"getSubscription(address,address)","5b7633d0":"signerAddress()","5b764811":"_jMul(uint256,uint256,uint256,uint256)","5b766089":"isCreditor()","5b766196":"hasWon(address,uint256)","5b767e86":"getArbiter(address)","5b791420":"isProxyForSender(address,address)","5b7991cd":"extensionsCount()","5b79b275":"_currencyToToken(address,uint256,bytes)","5b79dbe5":"reserveForTeam(address,address,uint256,uint256)","5b7a50f7":"setOldToken(address)","5b7a78c8":"test1_overlappingIntervalSameNode()","5b7ab891":"BAT()","5b7b716c":"tgrSettingsMaxStages()","5b7b72c1":"createCloneToken(address,uint256,string,uint8,string,bool)","5b7baf64":"claimRefund(uint256)","5b7c2dad":"getUserPosition(address)","5b7c38ad":"getLLV_edit_22()","5b7ca9c6":"addPrizePool(uint256)","5b7d47a9":"betOnColor(bool,bool)","5b7d9043":"creditAccount(address,uint256)","5b7da338":"_balanceOf(uint256,bytes32)","5b7db24d":"addRemoveCountry(string,string,bool)","5b7dc56a":"updateLuckyblockSpend(bytes32,address[],uint256[],uint256)","5b7eed81":"T1898Token()","5b7f415c":"TOKEN_DECIMALS()","5b7fc27f":"getInitializParentUniverseValue()","5b7fd9b5":"brands(address)","5b806645":"badgeCount()","5b80f497":"getAvailableIds()","5b814e16":"freezing()","5b824208":"changeMinimumTimeBeforeUpdate(uint256)","5b82d694":"SetClaimFee(uint256,uint256)","5b8315e4":"TokenSCADAEntity()","5b833f1e":"nextTokenOwner()","5b839dd2":"initBonusSystem()","5b83b7f1":"investorExists(address)","5b84bb27":"MYTOKENNAME()","5b850d92":"PollCreated(address,address)","5b859394":"PunkBidEntered(uint256,uint256,address)","5b859500":"hardcapInEther()","5b863b5a":"ZenomeSale(address,address,uint256)","5b86914d":"bet_value()","5b869e68":"DeviceAddr()","5b86ce97":"buyEggWithToken(address)","5b86f599":"increaseBalance(address,uint256)","5b8710e5":"checkTransferRequirements(address,address,uint256)","5b87a2f2":"confirmreward()","5b8807d9":"claimReserveTokens()","5b88349d":"claimAirdrop()","5b889ab8":"ammount()","5b8943ff":"addAffiliate(address,address)","5b89a48a":"lockEpochsMap(address,uint256)","5b8aa811":"setRequiredParticipation(uint256)","5b8ad515":"isUtilityHolder(address)","5b8b4f91":"refererAllowed(address,address,address)","5b8bcb53":"CappedSale(uint256)","5b8be30c":"TheCoinSale()","5b8c6b58":"RoundBHardCap()","5b8d02d7":"payoutAddress()","5b8e48df":"swypes(address)","5b8fa846":"payDividends(string)","5b8fb4ae":"EthKing()","5b905b6c":"newProposal(string,bytes32,bytes32,bytes32,string,uint256,uint256)","5b90ed39":"emitEscrowUpdated(address)","5b91aa6b":"underNumber()","5b91fd60":"performTheMagicTrick()","5b9248aa":"correctResult(int8)","5b9283e7":"isInvalidEarlyPurchase(uint256)","5b92cdee":"bountyAffiliateWallet()","5b92e548":"CreateCBT(address,uint256)","5b93c2bc":"getWinnerAddressList()","5b940081":"releasableAmount()","5b945c0e":"getLableList()","5b947f36":"ItasToken()","5b94db27":"nominateOwner(address)","5b95f65e":"getAddressesByDocHash(bytes)","5b9632ca":"minValue1()","5b96c1e7":"oracleMasterCopy()","5b980628":"collectFunds()","5b984ff6":"enableWithdraw()","5b9900ce":"getWeiforTokens(uint256,uint256,uint256,uint32)","5b99cb2b":"joinGame(uint256,uint256,bytes32)","5b99df7f":"transferWithFee(address,address,uint256,address,address,uint256)","5b9a4690":"convertToMiniRYC(uint256)","5b9af12b":"addValue(uint256)","5b9b0609":"maxContribAmount()","5b9b44bf":"startDefinedGame(uint256)","5b9eb8ab":"CONVERSION_NUMINATOR()","5b9f7cbe":"createNode(bytes32,bytes32,bytes32,address)","5b9fdc30":"getSecret()","5ba05024":"getInsuranceByAddress(address)","5ba0cd78":"BitcoinZ()","5ba13abf":"createMulti(uint256,address[])","5ba17b2d":"NewtonTree()","5ba1a1d4":"viewKarmaVotesBySymbol(string,address)","5ba2dd22":"conflictRes()","5ba32008":"FDKToken()","5ba39782":"getCommentAccounts()","5ba3e63e":"MultiSigRules(address[])","5ba58955":"beneficiaryBalance(address)","5ba5b1b2":"setSoldPreSaleTokens(uint256)","5ba67330":"SendDivs()","5ba6c017":"setTotalSpentPerDay(uint256,uint256)","5ba83c0d":"getMEATime()","5ba87a4d":"getWithdrawedToken()","5ba88490":"privlocatumICO()","5ba88c28":"debug2()","5ba8c608":"activePoll()","5ba8eb42":"getClearance(address,address)","5ba91006":"Sports3D()","5ba92d7d":"_freeze(address,uint8)","5ba9e48e":"nextPriceOf(uint256)","5bab1a63":"totalEthxRecieved()","5babb758":"testSetUp()","5babe01b":"distributedBountyStakes()","5bac1e11":"ReclaimBegun()","5bad05bd":"hardCancelOrder(uint224)","5bad9fa7":"walletOut2()","5badbe4c":"requestCount()","5badcd08":"TokenFulfillment(address[2],uint256[7],uint8,bytes32[2],uint256)","5badf100":"fireOnChanged(bytes32)","5bae2120":"test_doubleVotingFor()","5bae3f75":"CategoryAdded(uint256,string)","5bae4e98":"getOwnerRating()","5bae510d":"deposits(uint32)","5bae8c36":"isNewParent(address)","5bae9ce9":"blacklisted()","5baef4f3":"INCREMENT_RATE()","5baf039f":"add(address,address,address,address)","5baf4a09":"ausgroupTransfer(address,uint256)","5bafecf5":"calculateFloatingValue(uint256,uint256,uint256,uint256,uint256,uint256)","5bb0fa46":"RESERVE_EXCHANGE_SHARE()","5bb18362":"isReadyToBear(uint256)","5bb2b102":"registerNameCore(uint256,address,uint256,bytes32,bool,bool,uint8)","5bb31436":"transferKnightOwnership(address)","5bb3e5f6":"fixNoCallback(bytes32)","5bb41203":"test_oneAssert()","5bb447a8":"NOTtoken()","5bb47808":"setFactory(address)","5bb4df3c":"assignFrom(address,address)","5bb59815":"claimWarranty(string,uint256,string)","5bb5b917":"insureClient(address,address,uint64)","5bb5bb86":"dtGetBuildingData(address,uint256)","5bb7cf11":"ERC20(address,uint256,string,uint8,string)","5bba11bd":"bonusTicketsPercentage()","5bba3307":"splTransferFrom(address,address,uint256,uint256)","5bba6a7c":"propagateRequest(address,uint256,bytes32,bytes32)","5bba7aa5":"_assignBlocks(bytes16,bytes16,uint8,uint8)","5bbb7c42":"CPCEFund()","5bbdc7c5":"accrueTeamTokens()","5bbe66a7":"lastBlock_a15Hash_uint256()","5bbe6790":"Electronero()","5bbe8a33":"EGYPTTEST()","5bbee518":"investmentETH()","5bbf9c94":"arbLocked(address)","5bbfd0d7":"mintedGBT()","5bbfe9b6":"_myGroupHelper()","5bc008a0":"getAccessLevel(address)","5bc02d5c":"GooGameConfig()","5bc07110":"numArticlesPublished()","5bc0b4db":"ONESATOSHIToken()","5bc22d1b":"getStart(uint256)","5bc34f71":"currentStep()","5bc4e163":"drainRemainingToken(address,uint256)","5bc550fe":"mining(bytes)","5bc5c1a8":"getRoundDividendPerBBTHelper(uint256)","5bc5cf42":"mocatoken()","5bc60cfc":"win(uint256)","5bc6d41d":"doDisableSellerCancel(bytes16,address,address,uint256,uint16,uint128)","5bc6e107":"GetEscrowCreationDate()","5bc72460":"alterBannedStatus(address,bool)","5bc7285f":"sumICOStage3USD()","5bc789d9":"tokenVault()","5bc7e259":"updateRelease(uint32,uint32,uint32,bytes,bool)","5bc8a672":"setDetachmentTime(uint256)","5bc91b2f":"createRound(uint256,uint256,uint256,uint256)","5bc97d73":"Purchase(address,uint256,uint256,uint256)","5bca7f38":"set_pre_kyc_iconiq_bonus_numerator(address,uint256)","5bcabf04":"baseUrl()","5bcafcf3":"ProfitByCard(address,uint32)","5bcb2fc6":"submit()","5bcbc0f9":"PRICE_DIVIDER()","5bcc1072":"addressesToChatMessagesLeft(address)","5bcc209d":"getTokenAmountForEther(uint256)","5bcc29d7":"setDefaultURIStart(string)","5bcc437c":"revokePastDelegations()","5bcc7928":"saleType()","5bcc8198":"tokenCommissionReceiver()","5bcd3dba":"ACAToken(uint256,address,address)","5bcf6674":"setMinimumAllowedWei(uint256)","5bd1b8c5":"countCars()","5bd1f067":"OONE()","5bd26361":"sentTokensToPartner()","5bd2cc9f":"Notified(address,uint256)","5bd4349b":"getTotalGames()","5bd475fd":"destTokensDevs()","5bd479ac":"SoccerBet(string)","5bd489e1":"HelperPortion()","5bd54fa3":"setCryptoSagaCardSwapContract(address)","5bd5e89c":"decreaseArrivalTime(uint256,uint256)","5bd674dd":"gallerySeven()","5bd74490":"regProxy(address,address)","5bd7b9fd":"Rbank()","5bd7c609":"getEtherDiceProfit(uint256)","5bd7ebc5":"changeMinInvest(uint256)","5bd91213":"TransferKO(address,address,uint256)","5bd9279c":"placeBuyNowOffer(uint256,uint256)","5bd948b1":"useEIP712()","5bd9749c":"initialValidators()","5bd9abfb":"CreateTestCoin()","5bd9e637":"buyLC()","5bd9ea2e":"out5Done()","5bda1af0":"startCrowd(uint256,uint256,uint256,uint8,uint8)","5bda8fa4":"setSecondTime(uint256)","5bdaa6dd":"Token_Price()","5bdaeba2":"PausableTokenMock(address,uint256)","5bdb280f":"RESERVES_SHARE()","5bdb9ddf":"changeStepPricesLimits(uint256,uint256,uint256)","5bdc3c53":"setImmigrationCtrl(address)","5bdcc165":"batchTrasferByValue(address[],uint256[])","5bdcd0b0":"lifetimePayouts()","5bdf7b4f":"initilSupply()","5bdfaaff":"ASIABITSToken(string,uint8,string)","5bdff855":"gettotalCardDivs(uint256)","5be0497e":"getAdjacentCells(uint8)","5be1d5c3":"buyBlueStarEgg(address,uint256,uint16)","5be2aca0":"tokenRegistryAddress()","5be4d442":"setTrustedContract(address,bool)","5be53284":"GlobaleCash()","5be54515":"assignBountryToReferals(address,uint256)","5be5d9e3":"XdacToken(uint256)","5be5e3ec":"castVote(uint256,uint256,uint256)","5be60644":"sendcdd(address,uint256,address)","5be62401":"createUserWithProxyAndRecovery(address,address,uint8[],uint256,uint256[],uint256[])","5be6affc":"CloverCoin(address)","5be6d2eb":"exitPot()","5be782d1":"WORLDMOBILITY()","5be7cc16":"transferAdminship(address)","5be7fde8":"releaseAll()","5be80e85":"markCompromised()","5be89fac":"dAlterPull(uint96)","5be989d1":"CRYPTOBITECOIN(uint256,string,string)","5bea05b1":"getUSDBtc()","5bea0e1c":"calculateDividend(uint256,address)","5bea2941":"LYBT3Token(uint256,string,uint8,string)","5bea641a":"change_admin_commission(uint256)","5beb1d8f":"currentIcoPhaseMinimum()","5beb3f61":"WhitelistedStatusUpdated(address,uint256)","5bebe2c6":"getData_32()","5bebefdc":"checkForInterest(uint256,bool)","5bec1496":"ChangeQuota(uint256)","5bec9e67":"infinite()","5becf24c":"confirmChannel(uint256)","5bee29b7":"retrieveData(uint256)","5bee29be":"setSalary(uint256,uint256,uint256)","5bef1208":"getModuleIDByHash(bytes32)","5bef95a2":"setFiscalVerify(uint256,uint256,bytes32)","5befbb9b":"calceth(uint256)","5bf042e5":"setTradeAddress(address,address)","5bf0cb1f":"isTransferAllowedadv()","5bf1f2f8":"numberOfAbilitiesSold(uint256)","5bf2a4e9":"contains(bytes32,bytes32)","5bf339b1":"DogCore()","5bf3a315":"isTrustedContract(address)","5bf4063d":"minEthValue()","5bf47d40":"bntyController()","5bf5c29c":"_createHero(uint256,address)","5bf5d54c":"currentStage()","5bf608b8":"getBuyer(uint256)","5bf72bb1":"use_test_data()","5bf85c28":"CryptomniumChain()","5bf8633a":"nftAddress()","5bf95e43":"strategicAllocated()","5bf9755e":"setUint256(uint256,uint256)","5bfb1dab":"EIP20Token(uint256,string,uint8,string)","5bfb8ff2":"getRegistration()","5bfbbe39":"_transfer_internal(address,address,uint256,bool,bytes)","5bfc61c0":"claimPlot(uint256)","5bfd1ab8":"unBlockAddress(address)","5bfd8efe":"blockSettlementHash(uint64,uint64)","5bfdab26":"queryWithdrawed(uint256)","5bfdb8b2":"crowdsaleStartingBlock()","5bfdc700":"registerData(address,int256,bytes,address)","5bff1aa8":"EOSCToken()","5bfface4":"setBuyComission(uint256)","5c003af9":"TOKEN_WITHDRAWAL_END_DATE()","5c004bcc":"sendFrom(address,address,uint256)","5c006f75":"changeHoldByAddressIndex(address,uint256,uint256,uint256)","5c00ad5e":"ShowPercent(address)","5c0133d9":"filled()","5c016b91":"ownerDisablePayee(address,address)","5c01943a":"bountiesBalance()","5c0252fe":"setOnlineTime()","5c025e03":"authorizeOperatorByTranche(bytes32,address)","5c0286c0":"changeLOT(uint256)","5c0305ec":"EUTBToken()","5c042d0f":"BiQCrowdFund(address,address,address)","5c044b86":"roundThreeTime()","5c04e9f8":"firstXRChangeBlock()","5c062d6c":"currentDifficulty()","5c06d880":"getRateWithoutBonus()","5c071492":"hardCapLow()","5c0796fd":"emitUserCreated(address,address,address,address,uint8[],uint256,uint256[],uint256[])","5c07993b":"investorInterest()","5c07ac94":"changeCrowdsaleRate(uint256)","5c084a25":"get_pvn_token_balance(address)","5c0a8177":"claimOCDividend()","5c0a9b8d":"transferToContractAddr(address,uint256)","5c0b51fb":"theList(address)","5c0ba18e":"BitBoscoin()","5c0cc07a":"TAXChain()","5c0e6166":"Bill(address,string,uint8,string,uint256,uint256,uint256,uint256,uint256)","5c0e6bc4":"icoTokenPrice()","5c0f82b7":"GetIdByAddr(address)","5c0f9a3e":"getStrandGenesisBlockHash(uint256)","5c0fc34c":"freedomcryptotoken(uint256,string,string)","5c0fed8e":"EOBIToken()","5c100cc2":"setPreIcoDiscount(uint256)","5c1020f9":"addPhenomenon(string,string,string,string,uint8)","5c102782":"reward(address,uint256,string)","5c10286a":"auctionsEnabled()","5c1098c3":"crowdSaleOverTimestamp()","5c109a59":"updateStatus(address,address,uint256)","5c10b2e8":"contributionsAddress()","5c10cab8":"collected_crowd_wei()","5c10ec87":"preSaleDurance()","5c10fe08":"proofOfWork(uint256)","5c12a0e8":"DroneShop()","5c12cd4b":"getPlayer(address)","5c12f040":"emergencyWithdraw(bool)","5c131d70":"burnMax()","5c135535":"gooBalanceOf(address)","5c1397de":"signup(bytes32)","5c13a439":"checkAccount()","5c13d06f":"checkLockedToken()","5c13e2b5":"end_ICOs()","5c142f2b":"freezeAccountWithToken(address,uint256)","5c146b80":"_existCaller(address)","5c148b47":"calcClaimableTokens()","5c1548fb":"getCollateral()","5c164624":"decisionOf(bytes32)","5c1671a6":"hasSameArrayLength(address[],uint256[])","5c16e323":"__executeOrderInputIsValid__(address[4],uint256[8],address,address)","5c17f9f4":"approve(address,uint256,bytes)","5c19a95c":"delegate(address)","5c1b3a68":"setPrvdWallet(address)","5c1b3ca1":"getConfigUint(int256,bytes32)","5c1b9377":"TestBNB(uint256,string,uint8,string)","5c1b94d1":"publicGetRound()","5c1bc695":"addSubDivision(address)","5c1d2215":"mintTokensLocked(address,uint256)","5c1f71af":"setAllowBurns(bool)","5c206c6b":"FreeTokensIssued(address,address,uint256)","5c206f41":"finalValue()","5c207547":"wantsBusiness(bytes32,bytes32,address)","5c20ad9e":"multiValueBatchTransfer(address[],uint256[])","5c20c1dc":"distributePuppyCoinSmall(address[])","5c20eec6":"twentyThirtyTokens()","5c221385":"preciowea()","5c221816":"burnAccountMoeny(address,uint256)","5c222bad":"getAsset()","5c22aaae":"setGameTransferFlag(address,bool)","5c2323e7":"authorizedToTransfer(address)","5c239e58":"createItemSaleMarkets(uint256,uint256)","5c23bdf5":"resolve(bytes32)","5c242c59":"query1(uint256,string,string,uint256)","5c243f03":"GetLengthofList()","5c251cbf":"releaseStake(address,bytes32,uint256,uint256,uint256,bool)","5c253f52":"o_novo_problema(uint256)","5c25e903":"_lockNinja(uint256,uint16)","5c261556":"initFrozenTokenMap()","5c26a007":"IsEnable()","5c272fb2":"Unblocked(address)","5c27bbf6":"CryptoCompare()","5c27cdc3":"mintTeamTokens(uint256)","5c28c7e0":"privateSaleList()","5c2930ad":"shareholders(address)","5c2a8763":"percentageToReinvest(address)","5c2b0287":"BOXSToken()","5c2b1119":"getTop()","5c2b18e9":"VestingFund(address,uint256,uint256,address)","5c2bdc9f":"GainCard2(address,uint32)","5c2c2005":"issuePrice()","5c2c8db7":"withdrawToAddress(address,address)","5c2cc46d":"findResNameByAddress(address)","5c2ccaba":"GslStandardToken(uint256,string,uint8,string)","5c2d0e53":"KUNAsToken()","5c2e7a00":"setTokenBurnFeeProp(address,address,uint256)","5c2e7a13":"QuestionStore(address)","5c2e891c":"ECAP()","5c2eb1ef":"honestisFortbackup()","5c2ee908":"updateWinners(address[])","5c3004da":"getPpls(uint32)","5c30be8e":"callOracle(address,uint256)","5c314df0":"MINER_STAKE()","5c31f93b":"unpublish()","5c320516":"changeAmount(uint256)","5c32460b":"isAddress(address)","5c328e3d":"getMyAcceptance(address,uint256)","5c35b4e1":"exchangers(address)","5c35f464":"_modAccountBalance(bytes32,uint256)","5c361091":"PeerBetting()","5c36901c":"isActive(bytes32)","5c36a0bb":"collect(int32,int32)","5c36b186":"ping()","5c36e11c":"identified(address,address,bytes32)","5c37a17c":"saySomething(bytes)","5c390f82":"tokenEquivalent(uint256,uint256)","5c39b671":"sendOwnerCommission()","5c39c1ab":"collectedAddressesCount()","5c39ec58":"addClaim(address,uint256,uint256,bytes,bytes,string)","5c3a4c3d":"startRick()","5c3c8c87":"putHere()","5c3cd827":"allOfferingSupply()","5c3cdec8":"getTotalFeeStake()","5c3d005d":"demote(address)","5c3d6a7d":"setSaleAuction(address,address)","5c3dcfde":"listedTokensAsBytes(uint256,uint256)","5c3e38ee":"updateMinSpend(uint256)","5c3e426c":"adminRetrieveDonations(address)","5c3f9765":"endDateClose()","5c3ffada":"getPlayerCardIdsForTeam(uint256)","5c40329e":"setPresaleTime(uint256,uint256)","5c40839f":"GenevExch(address,address,address,uint256,uint256,uint256)","5c40f6f4":"setStatus(bool)","5c416306":"extractApprovedIndexLength()","5c417695":"burnMana(uint256)","5c4271c9":"issueDividendRewardBips()","5c42d079":"getProvider(uint256)","5c4301f2":"multiExecute(address[],uint256)","5c435396":"show_the_name_of_Option_D()","5c43fce3":"showteam(address)","5c44a837":"RemainingTokenStockForSale()","5c44c3e5":"addAdv(address,string)","5c45079a":"dropToken(address,address[],uint256[])","5c45872e":"_addCategory(address,uint256,uint256)","5c4633a4":"_revealNumber(address)","5c469570":"ReiDoCoinToken()","5c473764":"RESERVE_FUND()","5c474f9e":"saleStarted()","5c475676":"getProposal(uint256,bytes32)","5c47e306":"advisorsTokensPercent()","5c47ead7":"getParticipantData(address)","5c481d8b":"convertToWei(bytes32,uint256)","5c492129":"totalGamesPlayed()","5c49660a":"privateIcoTokensForEther()","5c4978e0":"getCurrentYearGameMiningTokenCap(uint256)","5c49d96c":"nTickets()","5c4a627f":"totalPreICOAmount()","5c4b4c12":"transferPreSignedHashing(address,address,uint256,uint256)","5c4bade1":"transferEtherTo(address)","5c4bfa10":"buyout()","5c4c9f6f":"WithdrawToken(address)","5c4d3609":"getTargetDesignatedReportNoShowsDivisor()","5c4e10e8":"sendLimitTokensToFounder(uint256,uint256)","5c4f4024":"tryRoundEnd(uint256)","5c4fb1c5":"comisionGetter()","5c5020e7":"setValidatorStake(bytes32,uint256)","5c50c356":"getTotalBonded()","5c50c63a":"isTokenTransferLocked()","5c511a2a":"OrphanWalefareToken()","5c5204d6":"changeOwnerTo(address)","5c52b434":"Boxicoin()","5c52bba7":"countParticipants()","5c52c2f5":"resetSpentToday()","5c52e51e":"processPayout()","5c53ec59":"setReasonableDiff(address[],uint256[])","5c54305e":"InsufficientFunds(address,uint256,uint256)","5c552879":"bytesToBytes8(bytes)","5c552fab":"getMetadataUser(address)","5c5557e7":"setKWHForGas(uint256)","5c561fff":"removeAllowedTransactor(address)","5c56afa3":"priorTokensSent()","5c58ad8e":"processDiceBet(uint256,uint256,int256,bytes32,bytes32)","5c590683":"SomeRegister()","5c5991d4":"token_ratio()","5c5a8ad5":"LogBid(address,address,uint256,uint256,uint256)","5c5b9f8f":"depositTokens(address,uint256,uint256)","5c5ce16e":"NXTokenCoin()","5c5d625e":"getProof()","5c5dc9a0":"embark(uint16,uint16,uint256)","5c5df66a":"setRequiredExpIncreaseFactor(uint32)","5c5e0aca":"setGrowingMaxPerDay(uint256)","5c5e20b6":"revertAuction(uint256)","5c5e274e":"mMaxChainCode()","5c5e54c9":"hasBothAttributes(address,bytes32,bytes32)","5c5f786e":"s4(bytes1)","5c5f7c5b":"setAdvisorsTokensPercent(uint256)","5c60da1b":"implementation()","5c60f226":"deleteUser(address)","5c612167":"newMultiService(address[])","5c613a03":"bountyReservedBalanceOf(address)","5c617279":"registeredApps()","5c61c853":"getProposalIndex(uint256)","5c61d628":"changeFundingLimit(uint256,uint256)","5c61f9b4":"getBlockResult(uint256)","5c6224c9":"Operational(address)","5c622a0e":"getStatus(uint256)","5c622c09":"getIsSendingLocked(address)","5c629788":"totalLevel(uint256[])","5c634241":"CanaryV6()","5c64bb72":"getCurrentSale()","5c658165":"allowed(address,address)","5c659bdb":"declareHanged(address,uint256[])","5c665f89":"getFunds(address,bool)","5c66bd58":"addWeapon(address)","5c67a5db":"approvalRatio()","5c67ae76":"PRE_COIN_PER_ETHER_ICO()","5c67dd1e":"getBlockRoot(uint256,uint256)","5c67f7b0":"transferFromTgefund(address,uint256)","5c68908b":"CategoryCatalog()","5c693657":"setMaxPower(uint256)","5c69d5d6":"completeOrder(bytes32,uint256)","5c6a0246":"fundsClaimed()","5c6a6edd":"bloquear_contrato()","5c6ae355":"removeAuthorizeduser(address)","5c6baf3d":"createProxyAddressFor(address)","5c6bcad4":"transferFromOrigin(address,uint256)","5c6bd930":"calculateBonusToken(uint8,uint256)","5c6c8903":"Buy(address)","5c6cad31":"storeCryptoNames(string)","5c6ce321":"RDT()","5c6e0ebf":"getScenariosInfo(bytes32,string,string)","5c6eb2d2":"atl()","5c6eb7ae":"withdrawStock()","5c707f07":"setName(string,string)","5c714e90":"starterPackPrice()","5c71ae10":"EEZOToken()","5c71dec8":"FreezeAdmin()","5c72b160":"invalidatePendingWithdrawl(uint256)","5c72de09":"BONUS_ICO_ROUND3()","5c7460d6":"userRegistry()","5c752f6b":"incGen0Count()","5c7584b9":"isEarlyInvestors()","5c75df30":"churn()","5c76ca2d":"paidOut()","5c770267":"RefundVault()","5c7713d4":"CountCow(address)","5c77582f":"changeTeamCosts(uint256[])","5c78f9e2":"getDepositorsTokens()","5c796720":"CurrentIceDelta()","5c7a281d":"HugsByMathou()","5c7ae6e3":"ethDivsOwing(address)","5c7b0288":"gemAttackConversion()","5c7b35f8":"resetTokenOfAddress(address,uint256)","5c7b79f5":"cashOut(uint256)","5c7b9ccf":"BASE_POS()","5c7c43fa":"maximumBuyBack()","5c7c49c9":"validateKey(bytes32)","5c7c9aa4":"checkAccountState(address)","5c7cbb0f":"_decode(bytes32,bytes32)","5c7d6425":"setPVPEntranceFee(uint256)","5c7f3d9a":"hatchMorties(address)","5c7f7f63":"getGrantees()","5c7fe08e":"PURCHASE_AMOUNT_CAP()","5c803f19":"alarmRaised(uint256)","5c803f36":"empties(address)","5c80461e":"isInStage1()","5c80b448":"setMatingSeason(bool)","5c810f09":"disableSellerCancel(bytes16,address,address,uint256,uint16)","5c812737":"payoutMultiplier()","5c8136c2":"retrievedTokens()","5c81662e":"internalMint(uint8,address,uint256)","5c81b8f9":"MIRCOOToken()","5c852231":"updateSizeBonus(uint256)","5c85267b":"PaymentChannel(address,uint256)","5c85974f":"setTxLimit(uint256)","5c8747cd":"getSoftwareVersionRecords(uint32)","5c87e40f":"SignatureCheckerChanged(address)","5c88da6f":"getUSD()","5c894469":"getPlayersByTrackId(bytes32)","5c89c10d":"setBannedCycles(uint256[])","5c8a1053":"extend(string)","5c8a694e":"FundableToken()","5c8a733a":"b32toString(bytes32)","5c8b94e7":"applyWithdraw(address,uint256,uint256)","5c8c02b3":"getWinnerById(uint256)","5c8cb8c0":"DBIPToken(uint256)","5c8cf750":"cancelTransaction()","5c8d1a6b":"setAtomMoth(uint256,uint64)","5c8e7376":"stageEco()","5c8fe438":"books()","5c908ee5":"DawnX()","5c90b9a8":"createRequest(address[3],address,uint256[12],uint256,bytes)","5c919aa3":"getDemurrageableBalance()","5c91cdfa":"createPenguin(string,uint256,uint256)","5c91fa67":"test_3_assertGasUsage200Boards()","5c92abfd":"GameVerified(bytes32)","5c9302c9":"currentDay()","5c9442a1":"addAdminList(address[])","5c97404a":"domainPrice()","5c975abb":"paused()","5c978499":"checkValidityOfBalance()","5c979fe4":"setRegistrar(uint256,address)","5c97efd6":"updateIcoStartTime(uint256)","5c97f464":"WNTOToken()","5c9920fc":"vaultClosed()","5c9a7a8b":"getCarType(uint256)","5c9b62b4":"comprarSala()","5c9c5a6f":"checkGameIndex()","5c9cc81f":"getFundDetails(address)","5c9d0fb1":"CROWDSALE_ALLOWANCE()","5c9d4528":"mainCapInWei()","5c9fa6ad":"bidSpread(bytes32,bool,int32)","5ca11c34":"minSalePrice()","5ca177cb":"LINK(uint256)","5ca1bad5":"CallScheduled(bytes32)","5ca1c5a0":"getNodeValue(bytes)","5ca1cacc":"changeMinEth(uint256)","5ca1e165":"getRoot()","5ca20102":"_checkPixelUnderRight(uint256)","5ca21490":"BitMilleCrowdsale()","5ca26ff9":"updateGuPhrase()","5ca3400c":"WithBeneficiary(address)","5ca3bf76":"setSendErrorValue(address,uint256)","5ca48d8c":"tokensLocked(address,bytes32)","5ca4d4bb":"disableScriptExecutor(uint256)","5ca5b054":"metherToken()","5ca5b334":"enableManager(address)","5ca6fa4a":"Nostradamus()","5ca7f2f0":"LivepeerVerifier(address,address[],string)","5ca81139":"createOnDay(uint256)","5ca86447":"put(address,uint256,uint256,uint256,uint256)","5ca8bc52":"returnIt()","5ca8e2ad":"ModultradeStorage()","5ca91d7f":"faddress(address)","5caa0dec":"currentSeries()","5caaa536":"confirmReference(address,uint256,uint256)","5caabecf":"transferFromWithReservingNet(address,address,uint256)","5cac0176":"MJT()","5cac79b2":"LockedCrowdSale(address)","5cac8b27":"amazing()","5cacdf29":"testChickenCnt()","5cad249c":"getLastWinNumber()","5cad7cfb":"getCrowdsaleStatus()","5cade372":"payAllOut()","5cae7767":"removeTrustedPartner(address)","5caed029":"tokenDecimal()","5cafbafb":"newMember(address)","5caff1a7":"Criptolira()","5cb047e8":"toInt(bytes,uint8,uint8)","5cb0887c":"contractExists(address,address)","5cb0c16f":"totalInCirculation()","5cb10016":"offchainSale(address,uint256)","5cb1470e":"_createRabbitInGrade(uint256,address,uint8)","5cb18a6d":"fipsLegacyRegisterMulti(bytes20[],address,bytes)","5cb24756":"unitEthWei()","5cb2d86e":"totalBlockContribution(uint256)","5cb2ffb5":"updateMinCapEthOnce(uint256)","5cb318bf":"unregisterUser(address,address)","5cb3ce15":"calculateMemoryState(uint256)","5cb4502c":"SCORE_TO_WIN()","5cb4f548":"partnerInfo(address)","5cb5de63":"recReward(uint256,uint256)","5cb603dd":"_getYearIndex(uint256,uint256,uint256)","5cb7226d":"prePreIcoStartAt()","5cb732be":"refundToken()","5cb7dd98":"BlueChipGame()","5cb85cd2":"changeCost(uint256)","5cb8dd09":"isAllowed(address,bytes32)","5cb92dc7":"_enableRefunds()","5cb9ceaa":"okAddress(address,address)","5cba658f":"setState(address[],uint256[],address,uint256)","5cba6caa":"notarizeHash(uint256,string,string,bytes32,string,string,string)","5cbaa74b":"canAttack(address)","5cbad0b5":"sumHardCapICOStage1()","5cbb122c":"transferBctToken(address,uint256)","5cbb2ac3":"purchaseTokenPointer()","5cbb7caa":"getFriends(address)","5cbbdfc9":"currentApplicationEntityAddress()","5cbc65b2":"getplayersurplus()","5cbc85d0":"returnBounty(uint256)","5cbcb302":"pre_ico_allocation()","5cbdf177":"emailVerified()","5cbe5f8f":"DIV_DIST()","5cbee9ba":"releaseLockedTokens(address)","5cbf0850":"BTN()","5cbfdd8d":"preBuy(address,uint256,bool)","5cc15001":"getContent(bytes32)","5cc18780":"StabilizationFund()","5cc1ad7f":"toTileId(uint8,uint8)","5cc2e6aa":"getFirstAuctionsRemainingDuration()","5cc2f6d8":"_processPurchaseInWei(address,uint256)","5cc3623a":"currentSection()","5cc373c7":"TestJ()","5cc39659":"preSaleBonus2Amount()","5cc3c951":"purchase_with_dai(uint256,address,uint256,uint256,uint256,address,bytes)","5cc3f5d7":"Deauthorization(address,address)","5cc41dad":"initiateCertificate(bool,string,uint256,uint256,uint256,uint256)","5cc422a1":"sumofsquares(uint256,uint256)","5cc501ce":"testFailSetNotTransferableNotOwner()","5cc52fba":"claimTokensBC(uint8)","5cc57501":"_computeHeight(uint256,uint256,uint256)","5cc5c5cf":"jackpotDifficulty()","5cc5ca50":"formulaContract()","5cc8a6ed":"PRE_SALE_4WEEK_BONUS()","5cc8ce33":"dev_settledBalance()","5cc95422":"getVestingReleasedAmount(address,address)","5cca3905":"getDeveloperMiningPowerForGameId(uint256)","5ccb4f8f":"UmbrellaCoin()","5ccb5460":"ethInvestedDuringICO()","5ccb54c4":"BGD()","5ccbddeb":"IcelandvsCroatia()","5ccc3eaa":"roundMoneyUpToWholeFinney(uint256)","5ccd2f9b":"_deleteAllPackedRevisionBlockNumbers(bytes20)","5cce7dbb":"removeHolderAddress(bytes32,address,address)","5ccee1de":"newValidatorSet()","5ccf49ed":"isGenome()","5ccf9f43":"BonusCrowdsaleMock()","5ccfe157":"getDataById(uint8)","5cd03621":"periodRound()","5cd03a3f":"removeIdArrayItem(address,uint256[],string,address)","5cd137b4":"LogDonation(address,string)","5cd27e8d":"init3(int256[],int256)","5cd2f4d3":"approve(address,bytes32)","5cd31795":"HavenToken()","5cd31e83":"LastWillContract(address,address[],uint8[])","5cd3b917":"numberOfDeployedTokens()","5cd3f3a1":"decompress(bytes)","5cd42150":"KY8000Token()","5cd45e61":"getUuidsSize()","5cd48caa":"bet(uint256[],address)","5cd50b3f":"quater2()","5cd60dad":"add(address,int256)","5cd689e6":"sell_label(address,uint256)","5cd6bd0e":"getPlayerDividendByStage(uint256,uint256,address)","5cd72340":"SetEpochData(address,uint256,uint256)","5cd72b15":"setAllowedMultivest(address)","5cd7815b":"testInternalCall()","5cd7c8bc":"createLastDay()","5cd7d478":"isYesWinning()","5cd82ee5":"Act()","5cd85187":"MIN_ETHER()","5cd87c71":"supportsTradingPair(address,address)","5cd8d2ad":"buyAndTransfer(uint256,address,address)","5cd925cd":"assetSize()","5cd96091":"enable_refunds()","5cd9814f":"Mybalance()","5cda31dd":"GTN()","5cda4b41":"checkApproval(address,address)","5cdaab48":"previousEpoch()","5cdb0798":"burnMemberToken(address)","5cdb1bd7":"setRefundPercent(uint256)","5cdb88bc":"addClaim(string,string,uint256,string)","5cdbd2d1":"Constructor(string)","5cdc9eda":"peggedETHUSD()","5cdcf33d":"milieurs_per_eth()","5cdd7560":"STEToken()","5cdd95e3":"MintableToken(uint256,address,bool)","5cddb74b":"becomeShitClonelord()","5cddd93d":"referalsMinInvestLimit()","5cde15b9":"_Application(bytes32,uint256,string)","5cdf3450":"changeParticipationLimits(uint256,uint256)","5cdf76f8":"setServiceFee(uint256)","5cdfd08c":"managementFees()","5cdfe733":"fastBuyBonus()","5ce1d810":"SmartN()","5ce22019":"getEtherInContract()","5ce2fea1":"CleosContract()","5ce308a7":"addEntry(string,string)","5ce32aca":"getAirdrop(bytes32)","5ce398c4":"Riddle()","5ce3dec1":"self_destruct()","5ce49fbf":"amountBets()","5ce4f8dc":"PoWHrGlass()","5ce57b50":"setPenalizedStatus(uint256,address,bool)","5ce5ba9b":"queryParent()","5ce62aa4":"checkStoredFile(address)","5ce7514e":"allowPublicWithdraw()","5ce75c7c":"PRESALE_SECOND_DAY_START()","5ce7c7e0":"tokenSetCrowdsaleManager(address,address)","5ce800ac":"user_off_freeze()","5ce8050f":"BuildCoinUtilityToken()","5ce83f70":"updateEndsAt(uint256)","5ce885ee":"initial_withdrawal(uint256)","5ce94328":"balanceOf(uint152)","5ce97dbb":"totalAirdrop()","5ceaa0bf":"modifyCurrentHardCap(uint256)","5ceb8bc8":"isPromoPause()","5cebcbf0":"setMaxGamePerBlock(uint256)","5cec2054":"dteamVaultAddr1()","5cec4cb9":"fundsTokensHaveBeenMinted()","5cec5ded":"balanceComisionOf(address)","5cecd728":"setWillContents(address,bytes)","5cedff32":"takeTokensForBacking(address,uint256)","5cee9ea7":"buyNew(uint256,uint256,uint256)","5cef51a6":"BdpDataStorage(bytes8)","5cf00394":"getResoPeriod()","5cf054f8":"SetRewAddr(address)","5cf0769c":"ETHERCOIN()","5cf28fa4":"minDai()","5cf29ecf":"forOwner()","5cf2befc":"getEthAddressesLength()","5cf2f261":"ProofOfBitconnect()","5cf3125c":"NASDAQ()","5cf34bcf":"getMinFee()","5cf3508a":"whiteListControllerAddress()","5cf38f24":"togglePlotBlockedTag(uint256,bool)","5cf3cd96":"payNode(bytes32,bytes32)","5cf3d346":"names(address)","5cf469ca":"tokenPreSaleCap()","5cf4ee91":"getPrice(uint256,uint256)","5cf5ad2e":"registerNameCore(uint256,address,uint256,bytes32,bool)","5cf5e386":"guardian2()","5cf6040b":"ERC20Token(uint256,uint8,string,string)","5cf6208a":"oraclizeTimeTolerance()","5cf625f0":"OffChainManagerImpl(address,address)","5cf6a536":"InternetWall()","5cf6a763":"receiveApproval(address,int256,address,bytes)","5cf858aa":"TOKEN_ESCALE()","5cf89f1e":"setDateRelease(uint256)","5cf8ca60":"isCase(uint256)","5cfa353a":"updateTotalGasCost(uint256)","5cfae3ba":"UNPC()","5cfaf2ef":"setNameTAOPositionAddress(address)","5cfb4aa4":"getMessageTimestamp(uint256)","5cfbcdbb":"committedEther()","5cfc1a51":"capacity()","5cfc53c1":"calculateForValue(uint256)","5cfc6432":"EcosystemPart()","5cfd5f89":"product4_pot()","5cfd8c24":"ResetPonzi()","5cfe237a":"TCGC(address)","5cfea6fb":"TokensPerWei()","5cff876b":"carrotsCaught()","5d000c07":"getFreeFuck()","5d004e85":"getCommentsCountByAd(uint256)","5d01615f":"queryFusionData(uint256)","5d01b261":"_placeBet(uint256,address)","5d0213f7":"transferTokenOwnerShip(string,address)","5d029d1e":"indexedByTag(bytes32,uint256)","5d02b2f7":"hasPresaleEnded()","5d03147a":"ownership()","5d0341ba":"approvals(address)","5d036c8b":"payEther(address[],uint256[])","5d0413d1":"calculatePlotPrice()","5d04af9c":"iMMCoinbuyPrice()","5d064bab":"MoreGainCoin(uint256,string,string)","5d068051":"sendFees(address)","5d06a05c":"lockupAccounts(address[],uint256,uint256)","5d0792b7":"minimumInvest(uint256)","5d0808f2":"listedMartialsLength()","5d08225e":"getGidOfId(uint64)","5d088fc6":"changeRandomFight2DeathContract(address)","5d08c1ae":"salePaused()","5d09e625":"setMustSkipFee(address,address,bool)","5d0a740a":"GetSeries()","5d0a7628":"lockPresaleBalances()","5d0ad8d0":"testFail_set_owner_unauth()","5d0b6774":"counterFor(address)","5d0be9de":"softWithdrawRevenueFor(address)","5d0c0161":"IXCASHToken()","5d0cb15d":"TOKEN_SALE_SUPPLY()","5d0dd712":"bet_amount()","5d0e550a":"safetyModeOn()","5d0ef098":"burnUnsoldCoins()","5d0f4ee0":"isChampionAccount(address)","5d108ca2":"TokenChanged(address)","5d109aea":"maxResult()","5d10a60d":"createPost(string,string,bytes32)","5d113b03":"PayWinners(uint256,address)","5d121289":"addPreSaleEndDate(uint256)","5d123014":"setGameTax(uint8)","5d12ace4":"playGame(uint256,uint256,uint256)","5d12fc0c":"ONE_BILLION()","5d14076c":"lowercaseString(string)","5d145c5b":"setIcoTimeStartEnd(uint256,uint256)","5d14f925":"Invested(address,uint256,uint256,string)","5d15001e":"SupplyOp(uint256,uint256,uint256)","5d15b46a":"emitSkillCategoriesSet(address,uint256,uint256)","5d161310":"DataMining()","5d161c3f":"useAbility(uint256)","5d16a6f9":"lockedBalances(address,uint256)","5d16b8de":"take_back_money()","5d183b60":"supplyRound2()","5d184107":"AddCategory(string)","5d19212e":"markUserAsFounder(address)","5d19606e":"transferIssuer(uint256,address)","5d19a99f":"isLimitReached()","5d1a3b82":"getOutcome(bytes32)","5d1b45b5":"getEntityCount()","5d1b56c4":"TestUser(address,address,address,bytes32)","5d1bd962":"getArrayValue(uint256)","5d1be4e5":"deathData_f14()","5d1be58e":"pecunioToken()","5d1c01e0":"signedApproveAndCallCheck(address,address,uint256,bytes32,uint256,uint256,bytes32,address)","5d1c3171":"luck()","5d1c985b":"setReceivers(address,address,address)","5d1ca631":"getId()","5d1ce03f":"tokensRaisedDuringRound(uint8)","5d1e2d1b":"split(address,uint256)","5d1edfa0":"checkContributedETH(address)","5d1f8098":"RoshaanCoin()","5d200f84":"GetPlayer(uint256)","5d201596":"getCategoryInfo(address,uint256,uint256)","5d202249":"totalCollectedETH()","5d204869":"slice(bytes,bytes,uint256,uint256)","5d208872":"setTimesEnabled(uint8,bool)","5d216562":"changeLockTransfer(bool)","5d2195dc":"getToBalance(uint256)","5d2230d7":"numfails()","5d2247a5":"stakeAirdrop(uint256,bytes)","5d228eb0":"getProviderDetailFields(uint256)","5d22a352":"manualWithdrawToken(uint256)","5d22e222":"BTCAir()","5d2392d6":"latchContract()","5d239d3e":"getSlice(uint256,uint256)","5d240c58":"addExperience(uint256,uint256)","5d2434ec":"transferFromTangibleassetdisbursementfund(address,uint256)","5d25d021":"withdrawForeignTokensMultiple(address,address[],uint256)","5d267042":"PointlessToken()","5d268629":"Refund()","5d2694da":"BlackPearlETH()","5d270cdc":"setExpectedRate(address)","5d272468":"isLiquid()","5d27976a":"Final(string,string,uint8)","5d27bff3":"registerWithEncryption(string,string)","5d27e9a6":"SEPARATOR()","5d281384":"_isValidSignatureAndMethod(address,address,bytes)","5d285eca":"preICOspecial()","5d29206b":"createTokenEscrow(address,uint256,address)","5d293581":"ApplyForCertification(string,string,string,string,uint256)","5d2946f5":"futDevAddr()","5d295f67":"maxDGAME()","5d2973cd":"applyVIPLevel(address,uint256)","5d29bd40":"rollThree(address,uint8,uint8,uint8)","5d2a5d3d":"sentPreSaleTokens()","5d2a70a8":"getActualFee()","5d2a9b6a":"_randomIndex(uint256,uint8,uint8,uint8)","5d2aa757":"getSides(string,uint256)","5d2b811d":"getLastRegisterDate()","5d2bafed":"gee()","5d2c0af2":"Invest(address,bool,uint256,uint256,uint256)","5d2c53a7":"withdraw_funds(uint256)","5d2cce82":"LemonsDroppedToTheWorld()","5d2d5c37":"registered(string)","5d2dc5fa":"FraCoinAuct(string,uint256,address)","5d2dec87":"PRNG(address)","5d2fea9d":"reissuedTransactions(uint256)","5d302ba1":"UpgradeAgentEnabledToken(address)","5d306f34":"getRefundAmount(address)","5d307c6f":"giveToVoter(uint256,uint256)","5d3171d9":"transferFromPrivileged(address,address,uint256)","5d31c3bc":"deliveryApprove(address)","5d3235bd":"NutrioCoin()","5d3278f0":"LooneyFifty()","5d337b01":"largeSize()","5d3458ea":"DolToken()","5d346bd6":"addSaleOwner(address)","5d34b70c":"LavaDeposit(address)","5d354b4d":"foundingTime()","5d355804":"endPtopDeposit(address,address,bytes32)","5d359fbd":"transfer(address,uint64)","5d35a3d9":"approve(uint256,uint256)","5d3601d2":"_isRegularAddress(address)","5d36a791":"PartyToken()","5d36d182":"recycle(address,uint256)","5d37c840":"level_4_amount()","5d383eaa":"registerTokenPayment(address,uint256)","5d385031":"getCustomerTxOrigMcwTransfer(address,bytes32)","5d3899af":"place_to_push(uint256,bytes32)","5d397767":"publicBattlepm1()","5d3a08d7":"setNodePhases(address)","5d3a1f9d":"setText(string)","5d3a5e3b":"teamTokenAddress()","5d3a70f9":"YayyyToken()","5d3aac49":"PublishInterfaces()","5d3afb19":"CNYB()","5d3b2f37":"getNextGameId(address)","5d3bb19e":"XXXXXXXX09()","5d3c1d4c":"_getRequest(uint256)","5d3c7c9b":"AGASCrowdsale()","5d3c81a5":"feeWithdrawTokenAmount(address,uint256)","5d3ca4ab":"lotteryReinvest(string,uint256)","5d3cd79f":"endPrivateICO()","5d3d08a8":"cancelExchange(uint256)","5d3e64bf":"ttlPlayers()","5d3f4fe4":"withdrawMyTokens()","5d3fdd19":"updateDiscount(uint256)","5d40124e":"YunJiaMi(address,address,address,uint256,uint256,uint256)","5d40533f":"AnemoiToken()","5d40c0ae":"createAccessorySeries(uint8,uint32,uint256)","5d41363f":"rateRound1()","5d416cc2":"setIsTokenCanBeBuy(bool)","5d41dd6f":"ExampleToken(address[])","5d42513b":"test_withdraw()","5d428e08":"addTrader(address)","5d4293a0":"hatchPoohs(address)","5d439cf3":"transferEvent(address,address,uint256)","5d43e769":"batchTransfer(uint256,uint256[])","5d444ffb":"minMintingPower()","5d4453ba":"getGuess(address,uint8)","5d449d7d":"refererFeePercent()","5d44b508":"calculateRewardToWithdraw(uint32,address,address)","5d450bab":"setJobRating(address,uint8,uint256)","5d451a9a":"Wallet8()","5d4521dd":"updateWeedTotal(uint256,uint16)","5d452201":"ico()","5d4559ca":"get_coins_count()","5d45b4a7":"increaseMonthlyTransactionVolumeSending(uint256)","5d461de5":"sendAmount(address,uint256)","5d4626f6":"getInvoiceStatus(bytes32)","5d468d38":"releaseAuctionEnded(uint256)","5d47762d":"Member_AssingTokensToProject(uint256,uint256)","5d47f4f2":"CanHandleAuth(address)","5d484e17":"StaticEthAvailables()","5d485e5d":"_hostContent(address,bytes32,string,string,string)","5d495aea":"pickWinner()","5d49705b":"getEmployer(address,uint256)","5d49719d":"SHA3_512()","5d49c199":"finishPreSale2()","5d4a8f74":"ATTRToken()","5d4aaf1c":"registerWithUserAgreement(address,bytes32)","5d4befc0":"emitSynthAdded(bytes4,address)","5d4c5cca":"participantsForPreSale(address)","5d4d061e":"keyValueStorage()","5d4dda72":"DirectInput()","5d4e1e5c":"substract(uint256,uint256)","5d4f012b":"tgeCurrentStage()","5d4f30e7":"get_address(address)","5d50601b":"getsumdata1(bytes32)","5d506a2e":"minPotSum()","5d51b550":"haltCrowdsale()","5d52fe64":"buyRemaining(address)","5d54322d":"canPurchase(address,uint256)","5d5483b3":"WatchAppliedFeePercentage()","5d54cb1f":"is_transfer_allowed()","5d54e612":"whitelistAll()","5d552c72":"BasicToken()","5d5576f8":"renounceCapper()","5d56550a":"buyCore(address,uint256,string)","5d5655dd":"BOOKIE()","5d567259":"bobMakesErc20Deposit(bytes32,uint256,address,bytes20,address,uint64)","5d56e0a4":"developerMiningPower()","5d57135a":"KEBABER_TO_MAKE_1KEBAB()","5d582870":"requestInvestment(uint256,uint256,address)","5d585176":"GolemSupply()","5d586bfd":"deposit(string,address,uint256,string)","5d59072a":"OFFICAL_VOTING_DAY_OF_MONTH()","5d593462":"init(address,address,string,string,uint256,uint256)","5d5a1614":"STQCrowdsaleTestHelper(address[],address,address,address)","5d5aa277":"tokenSaleContract()","5d5b35f3":"dividendsTotal()","5d5b82fd":"Blockjack(address,address)","5d5b9021":"acceptTradeOffer(uint256)","5d5b92b1":"teamOneSharePrice()","5d5bc4cb":"BetOnRed()","5d5c3011":"ctyCoin()","5d5c606f":"DAOPolskaTokenICOregulations()","5d5d4fab":"TACTICALCRUISER_EXTRACTION_BASE()","5d5e22cd":"transferFromWithSender(address,address,address,uint256)","5d5e507b":"create_price()","5d61dd5a":"removeSingleAddressFromWhitelist(address)","5d62917b":"pickWinners(uint8,address,address,address,uint8,uint8,uint8)","5d63b758":"minAcceptedETH()","5d63b77c":"divideSafely(uint256,uint256)","5d644069":"request_face_proof(string,address)","5d6470a4":"STAGE_1_TIME()","5d64aa68":"dragonIndexToOwner(uint256)","5d651b62":"TimeLockSendCreated(address,address,uint256,address)","5d6542af":"way()","5d65432d":"IndorsePreSale()","5d65c37b":"Assessment(address,uint256,uint256,uint256,uint256)","5d666d3c":"getRurus(string)","5d667464":"usePrecompiledContracts(bytes32,uint8,bytes32,bytes32)","5d66ccf0":"updatePerSell(uint16,uint256,bool)","5d66d73f":"notarizeHash(uint256,string,string,uint256,bytes32)","5d671fc0":"switch_period()","5d6720b4":"getFreeMineral(address)","5d67830a":"doLogFighter(uint32,uint256,uint256)","5d685185":"periodITO_softCapInWei()","5d68564e":"ZontoToken()","5d6952d7":"changeSaleStartBlock(uint256)","5d69864e":"Bitscors()","5d69d600":"presold()","5d69f16f":"offerAsSacrifice()","5d69f68c":"getVotersName()","5d6af2af":"getOffChainRootAddress()","5d6b2f26":"destroyAllTokens()","5d6b70ae":"getSignedTable()","5d6b7798":"BCQ()","5d6c3ea7":"mined_coin_supply()","5d6c8e10":"getDHash(bytes13)","5d6cb67e":"ecosystemTokenSupply()","5d6cdfae":"EthereumPot()","5d6ceeb5":"returnMoneyToBuyers()","5d6d2992":"ownFiles(address,string,string)","5d705fe2":"MBCashSupply()","5d711db1":"get_candidates()","5d718818":"getHolderCountryCode(bytes32)","5d71cf46":"spendableAllowance(address,address)","5d723298":"PartialPayment(address,address,uint256)","5d728582":"hasAuthoritySignedSideToMain(address,bytes)","5d72b30d":"changePlayerName(uint256,string)","5d73e2bf":"startPlay(bytes32,uint8,bytes32,bytes32)","5d740d62":"YFJToken()","5d751443":"updateWebappMinBalance(uint256)","5d760b45":"forceWithdrawPayments(address)","5d766d35":"INITIAL_GLOBAL_DAILY_SUPPLY()","5d76a039":"PresaleReStarted()","5d771933":"BOUNTY_SUPPLY()","5d777893":"GetPlayers(uint8)","5d77aec8":"receiver3()","5d77d8d0":"getBlacklist(address)","5d78650e":"getAccountData(address)","5d796c05":"mintAuditCancel(address,address)","5d79eda7":"Digixbot(address)","5d7a6b10":"nextDerivativeTokenScheduled()","5d7b0758":"controllerMint(address,uint256)","5d7c3ad2":"ICO(address,address,uint256,uint256,uint256)","5d7c3b78":"costructor()","5d7c829d":"_messageToRecover(address,uint256)","5d7cf3e2":"Meltdown(uint256)","5d7e6b8d":"Schengencoin()","5d7e7219":"setFeeFor(address,uint128[2])","5d7e8c15":"ethToCents()","5d7e994a":"RewardStart()","5d801ec4":"SetmaxTokens(uint256)","5d80effc":"TimeBonusPricing(uint256[])","5d80f643":"Kujira()","5d818e6b":"recordDeal(uint256,address,uint32,uint32,bool,uint256)","5d81b206":"P3NGCT_v1(uint256,string,string)","5d8214db":"lastFactChangeValue()","5d8227e6":"FactoryBase(string,string,string)","5d82ddc8":"freezeEnabled()","5d8302f2":"CrypTollBoothToken(uint256,string,uint8,string)","5d831ca1":"FUT5()","5d8749ed":"workStages(uint256)","5d878b4f":"isInWhitelist(uint256,address)","5d88383e":"retrieveEth(address,uint256)","5d891d12":"foundersTokensWalletMaster()","5d895dac":"parse(string,uint256)","5d89c01a":"getCatIds()","5d8a776e":"award(address,uint256)","5d8aef9f":"_calculateLockedBalance(address,uint8)","5d8bc2a8":"assertEq12(bytes12,bytes12,bytes32)","5d8c5b87":"orderPlace(address,bool,uint256,uint256)","5d8ca2ac":"getApprovalsFor(address)","5d8d1585":"getUserInfo()","5d8d2904":"setKeyPermissions(bytes32,bool,bool,bool)","5d8d4415":"rawUseName(bytes32)","5d8dd304":"founderTokensAvailable()","5d8e0c2c":"isManualTradingAllowed()","5d8e7376":"DAOBalanceSnapShot()","5d8e772f":"gameCore(uint256,uint256,uint256,bytes32)","5d8f2640":"store(bytes32,bytes32,bytes32)","5d8f3b76":"createPercentageRequest(uint256)","5d90df32":"TRONIX()","5d9169f0":"ICO(address,address,address,address)","5d91e27b":"MVM24PeriodsCapUSD()","5d92e5d2":"ipyh()","5d946afa":"trashed(address)","5d94e35c":"contractRefundStarted()","5d94f108":"platformLogout(address,uint256)","5d956b3e":"changeGroveAddress(address)","5d95738b":"vHasVoted(uint256,address)","5d95a08b":"MizuCoin()","5d969f8f":"updateCustomerACC(address,address,address)","5d96ec65":"setAdministrator(address,string,bool)","5d975d70":"mx(bytes32)","5d977c02":"withdrawalFor(uint256,uint256)","5d9796eb":"WELTCOIN()","5d989a0c":"NyronChain_Crowdsale()","5d98d9ee":"ChannelCreated(string,address)","5d98fd9f":"Presale(address,address)","5d990791":"getDenominationByIndex(uint256)","5d99e02f":"myPinerTokenTest1()","5d9adc94":"withdrawPendingTransactions()","5d9c4f0f":"getFeeRecipient(address)","5d9d595c":"sendWingsRewardsOnce()","5d9d5b9a":"CreatedCAT(address,uint256)","5d9d8dd9":"makeupShiny(uint256)","5d9ec210":"signTransaction(uint256)","5d9fa6fc":"getContractBal()","5d9fd8b0":"listPersons()","5da01a5b":"configure(bytes32,bytes32,uint256,uint256,uint256,address)","5da03ff8":"EthergotchiOwnershipV2(address)","5da05e2e":"setCoinLimit(uint32)","5da08c42":"createSeedTeam(uint8,uint256[9],uint256[9])","5da0a987":"Run()","5da12d50":"Oduwacoin()","5da24f90":"closeTimer()","5da34093":"bonusRemain()","5da3d3d2":"minHEXCap()","5da47721":"getVIPLevel(address)","5da4a1d3":"setPercentage(uint256)","5da54cee":"DragonCrowdsale()","5da5a9b1":"ownerUpdateMinMaxNumber(uint256,uint256)","5da5f5ab":"Distribution()","5da6628a":"transferExt(address,uint256)","5da6bf67":"movePlayer(uint8[176],uint8,uint8,uint8)","5da6c418":"burnMintFrom(address,uint256)","5da6e035":"_openAndJoinCDPWETH(uint256)","5da6ec5b":"t8exToken()","5da85a16":"setCEx(address)","5da89ac0":"weiRefunded()","5da96520":"transferTeam2Tokens(address,uint256)","5da9781b":"readUint256s(bytes32[])","5da99f5e":"upgradeCardDamage(uint256)","5daa0c37":"referrerLinkedSales(bytes32)","5daa87a0":"Initialized()","5daab236":"runIco()","5dab2e0f":"left82(uint256)","5dac1601":"SimpleStablecoin()","5dac48bb":"approvePreSignedHashing(address,address,uint256,uint256)","5dac5682":"removeAuthorization(address,address)","5dac7044":"checkHardCap(uint256)","5dacf084":"THACO2()","5dada964":"expectedRateContract()","5dadf485":"takePosition(uint256)","5dae4e50":"makeItRain()","5daf08ca":"members(uint256)","5daf7514":"redeemTokens(uint256,uint256,bytes32[])","5daf8a71":"DestroyToken(uint256)","5db07aee":"mintFeeDenominator()","5db09db5":"getSplitPotAsFixedPointForGameId(uint256,bool)","5db17dab":"CDTToken(uint256)","5db2a233":"awailableDividends(address)","5db30bb1":"getMaxTotalSupply()","5db38c63":"nDemocs()","5db39a1e":"totalFails()","5db39d74":"HayaCoin()","5db3f963":"registerSimple()","5db3ffa5":"getUBetCheck(address,address)","5db42841":"createContractGameItem(string,uint256)","5db46961":"proxyExchange(address,uint256,string,bytes32)","5db4cd21":"ir()","5db524ad":"finishDividends()","5db5301f":"unsubcribe(address)","5db5d1fb":"startTimeTLP2()","5db5fc24":"alterInitialPricePerShare(uint256)","5db62dab":"getBalanceForUser(bytes32)","5db6687b":"Dev_TokenReleased()","5db6a31f":"transferBroker(address,uint256,uint256)","5db7ef3d":"intoverflow_mul(uint256)","5db8e202":"evaluateProposalAction(uint256)","5db8f084":"getNeighbourReward()","5dbb0ef8":"TuZaiCoin(uint256,string,uint8,string)","5dbbd139":"CentraSale()","5dbbfc47":"getMaxLoss(address)","5dbc374f":"UBCoin()","5dbe47e8":"contains(address)","5dc10a45":"whitelistMultiForTier(uint256,address[],uint256[],uint256[])","5dc11a89":"setNumTicks(uint256)","5dc1ba1b":"closeLotteryAndPickWinner()","5dc1bb52":"removeLocked(address,uint256)","5dc1c79d":"KANYE()","5dc2157d":"getBalancesOfAddress(address)","5dc22cce":"attackPlayer(address)","5dc2944a":"ratesForCurrencies(bytes4[])","5dc3d02d":"rc5()","5dc43f6e":"AddAuthority()","5dc49bf8":"SellENSCreated(address)","5dc4d8a6":"proposalTarget(uint256)","5dc4dcd1":"TicketPurchased(address,uint256,uint256,uint256,uint256)","5dc54308":"KickSportsManager()","5dc5aefe":"startIncentiveDistribution()","5dc6bfe4":"distributeLRN(address[],uint256)","5dc6f3df":"registerNameCore(uint256,address,bytes32,bool,bool)","5dc70cda":"_shareToPreviousOwner(address,uint256,uint256)","5dc774d7":"DrawingPrintToAddress(uint256)","5dc77e26":"andThen(string,address)","5dc824b9":"voteNoLock(address,uint256)","5dc86b85":"adminGetAmountAddressDial(address,address)","5dc94af6":"getTokensTotal()","5dc96d16":"burnEnabled()","5dca53d3":"right30(uint256)","5dcb6774":"_createBid(address,uint256,address,address,address,uint256,uint256)","5dcb71f2":"yoshicoin()","5dcb98c4":"CPO()","5dcbac7a":"registerBytes(address,bytes)","5dcbc01e":"addSellTokensRequest(string,string)","5dcbd8bb":"setLimit(uint16,uint64)","5dcc6dbc":"spawnAxie(uint256,address)","5dcd967d":"ndc()","5dcdddd1":"testSafeToAddFix()","5dce431b":"addGame(address,uint256)","5dce9948":"getTranscoder(address)","5dcf1b77":"fileMerkle(bytes32[],uint256,uint256)","5dcf451b":"CoinDogToken()","5dcf7c8c":"proxies(address,uint256)","5dd18a22":"setItemsNotForSale(uint256[])","5dd19463":"angelFoundationAddress()","5dd283cb":"pickSmallWinner()","5dd284e3":"getAllGoldTransactionsCount()","5dd39c12":"SOD()","5dd4599a":"usersCanTrade()","5dd48b04":"PURCHASE_PREMIUM_RATE()","5dd4a65f":"lookup(address,bytes32)","5dd588df":"isAuthorizedToTransferFrom(address,address,address)","5dd672ec":"latestBid()","5dd68acd":"setAddresses(address,address,address,address,address)","5dd68f36":"getTotalInvest()","5dd871a3":"canMint(uint256)","5dd8e1d5":"kek()","5dd8eb50":"rate4()","5dda837f":"mineBalance()","5ddae283":"transferRegistrars(bytes32)","5ddaf07f":"StarbaseToken(address,address,address)","5ddb2585":"icoStartTimestampStage4()","5ddbc632":"setHardCapToken(uint256)","5ddc98ba":"updateKYCWallet(address)","5ddd81b0":"firstPeriodCap()","5ddd8248":"setBurnerOwner(address,address)","5dddea66":"updateState(uint256,uint8,uint256)","5dde2066":"addBlocks(uint256,bytes,uint256[])","5ddf2998":"setOwnerValidatorAddress(address)","5de01497":"ownerWithdrawERC20Token(address,uint256)","5de047d3":"existPlatform(bytes32)","5de0e689":"startPromotion()","5de270c5":"adminFixCurve(uint32)","5de28ae0":"getStatus(bytes32)","5de2a21b":"onIncreaseApproval(address,address,uint256)","5de3ba97":"getAllIdentifiers()","5de40f30":"innerContract()","5de4381b":"_addItemToParent(bytes32,bytes32)","5de4c6fc":"lock(address,bool,uint256[],uint256[])","5de4ccb0":"upgradeAgent()","5de52fb7":"TakeMyEtherTeamAddress()","5de6dc55":"getTokensOfOwner(address)","5de6f040":"unlockFundrBal(bool)","5de7e350":"getTokensFromAddressEmits(address,address)","5de81534":"getEditionsCount(uint256)","5de910bc":"subSegmentation(address,uint256,uint256,uint256)","5de924bf":"DeepCoinToken()","5de97c8d":"setIntervalTimeAdjust(uint8)","5dea19f5":"getHolderExternalIdByAddress(address,address)","5deab0ec":"grantLoanOwnership(bytes32,address,address)","5debb827":"SCFToken()","5debc7af":"get_tokenTime()","5dec18d4":"motto()","5dec74f8":"_finishTheBattle(uint256,uint256,uint256,uint8)","5dec7d49":"Transaction(bytes32,bytes32,address,bytes,bytes32,bytes32,address,bytes,bytes32,uint256,uint256,bytes)","5ded0235":"iRide()","5ded1865":"getCategoryProducts(address,uint256,uint256,uint256,uint256,uint256,bool)","5dedd9cc":"resetWinners(uint256)","5dee2492":"AIR_2_SUPPLY()","5deeab39":"freeTokensIssued()","5deeffb2":"getSoftcapReached()","5def5814":"getByDistrict(uint256)","5defaec6":"createVirtualAddress()","5defe3d9":"grantAccessDeposit(address,address)","5deff965":"getEtherum()","5df285c8":"getBonusTokens(uint256,uint256,uint256)","5df29b4f":"settleBetUncleMerkleProof(bytes20,bytes20,uint40)","5df2df2f":"multiSendTokenComplete()","5df34ff2":"buyMintingAddress(uint256,uint256)","5df3bdb9":"ABRATOKEN()","5df3d87e":"bet1()","5df58352":"calculateScoresIfCellIsBought(address,address,uint256)","5df5f96f":"initialize(address,uint256,uint256,uint256,uint256,address)","5df607f0":"getMyEntry()","5df60977":"updateFrozenAddress(address)","5df6461d":"LOTTERY_FUND_SHARE()","5df6a6bc":"unbond()","5df70904":"giveToken(address,uint256,bool)","5df73398":"loadMesaVerify(bytes32,bytes32[],uint8[])","5df75bdf":"totalTokensICO2()","5df8122f":"setManager(address,address)","5df86d29":"etherInContract()","5df8d74e":"bytesCallWithArray(bytes,bytes32[4])","5df8f17b":"createVote(uint256,address[])","5df93f99":"MICL()","5df95255":"Rating(address,address,int256)","5dfb94cf":"nextBurnFeeProp(uint256)","5dfc09a4":"getCurrencySymbol()","5dfc273c":"Cloudbric(address)","5dfc2e4a":"noop()","5dfc3459":"maxIncrease()","5dfd1bff":"MeetingTimeSetFailure()","5dfd3278":"VOTE_AGAINST()","5dfde910":"STELLARGOLD()","5dfed2bb":"setCompte_14(string)","5dfee9bb":"refundTokens(uint256)","5dffe6dc":"contrEntrance(address)","5e0055e7":"ThreeStarToken()","5e007742":"Propethy()","5e00a177":"revokeVesting(address,string)","5e00b9a9":"incompletePercent(uint256[3])","5e00bd96":"DoNotBloodyDeployThisGetTheRightOne()","5e00e7b2":"getNoContributors()","5e01b2e6":"Gobi()","5e01d395":"getCapAtTime(uint32)","5e01eb5a":"getSender()","5e01ed34":"associatedAddresses(uint256)","5e02b84d":"Voiptoken()","5e031606":"round2TokensRemaning()","5e03d0c6":"getCreationDateOfHistoricalMetadata(string,uint256)","5e03d393":"setAccountFrozenStatus(address,bool)","5e04672b":"approveSynthesizing(address,address,uint256)","5e047822":"fundOf(address)","5e047975":"recoverSigner(bytes,address,uint256,uint256,uint256)","5e05bd6d":"timestampFromDateTime(uint256,uint256,uint256,uint256,uint256,uint256)","5e05e84d":"buyCells()","5e068da5":"proxyVersion()","5e06911e":"SpecialTrained(uint256,uint256,uint256,uint256[2])","5e079aa5":"giveEthFundAddress()","5e07c354":"vestingTokens()","5e07f240":"shiftBitsLeft(bytes,uint256)","5e0842d7":"VEToken(uint256,string,string)","5e08f5fa":"setCGO(address)","5e0a6049":"LOG_newGasLimit(uint256)","5e0b1259":"end_block()","5e0b1597":"_unpackRatingValue(uint256)","5e0b4cb6":"setData_2(uint256)","5e0b5d9b":"changeStartAndEndTime(uint256,uint256)","5e0be607":"unlockAllTokens()","5e0be75c":"setDividendPayout(uint256,uint256)","5e0c8c8c":"getCountSales(uint256,uint256)","5e0c923a":"RinneganToken()","5e0d0f30":"krsUsd()","5e0e2118":"removeSignature(string,int256)","5e0e2957":"dumpOut()","5e0fac2e":"unlockedBalance(address)","5e0fec6a":"knownReserved()","5e0ff394":"setCompetitionAdmin(address)","5e10177b":"confirmDelivery()","5e101e51":"editionController(uint256)","5e1045ec":"addWhiteList(address[])","5e11544b":"newPeriod()","5e11dc0b":"openDistribution()","5e123ce4":"gameStarted()","5e131fa2":"removeLocker(address,address)","5e1372f4":"lockup(address,uint256,uint256)","5e159cd4":"LogOwnerRemoved(address,address,address)","5e15d642":"totalNumberOfTokensForSale()","5e1665f3":"SmartParkApp()","5e172fa3":"allowtransferaddress(address)","5e17580a":"setTime5(address,uint256)","5e1758fa":"addPermission(address,bytes32)","5e17b694":"promisedTokens()","5e191293":"emitBoardRatingGiven(address,uint256,uint8)","5e1936d4":"testThrowSetNotTransferableNotOwner()","5e199157":"setWalletOut1(address)","5e199892":"forwardFee(uint256,address)","5e19b305":"isActive(uint32)","5e19d316":"clearICObyAddress(address)","5e19deda":"preCap()","5e1a01c3":"createAndJoinCDPAllDai()","5e1a6c17":"requesters(uint256)","5e1bd33e":"getBuildCost(int32,int32,bytes16)","5e1c8f89":"scoreOf(address,address)","5e1ce5b0":"phasePresale_To()","5e1d5482":"about()","5e1d7ae4":"changeFeeRebate(uint256)","5e1d832d":"giveChamp(address,uint256)","5e1d8cb7":"TextChanged(string)","5e1d9aba":"sanCurrentTotal()","5e1dca04":"shareholder1()","5e1e1004":"setPaymentAddress(address)","5e1e547d":"unsign(uint256)","5e1e5c88":"betByte()","5e1eabd2":"soldPerCurrentRound()","5e1f3fa8":"CREATE_REPO_ROLE()","5e1f56d9":"changeWalletOwner(address)","5e1fc56e":"close(uint64,uint256,bytes32,bytes32,bytes)","5e217162":"availableSTCDRTokensOF(address)","5e21f687":"getMarketID()","5e22a2fb":"getTokenIdByHash(string)","5e22b760":"buyDEV()","5e23464e":"TOTAL_REQUEST_TOKEN_SUPPLY()","5e24de11":"ownerSetCrowdsaleClosed(bool)","5e25495e":"getProviderSupply(uint256)","5e25f96d":"setYccContractAddress(address)","5e2642c9":"isInitialSupplied()","5e280e4e":"validateTransaction()","5e280f11":"endpoint()","5e29c47c":"walletCreatedTimestamp(address)","5e2a725c":"enableEmergencyBlock()","5e2cb4f1":"BluToken()","5e2d13af":"addONG_AUDIT(bytes32,string,string,bool)","5e2d1f0d":"withdrawAfterTime()","5e2d285a":"GICTLock(address,uint256,uint256,uint256)","5e2d3798":"ETHERberry()","5e2dff7a":"foundersTokensLockedPeriod()","5e2e555f":"RogisterToVoteOnTransfer(address)","5e2ea5bd":"FIRST_PHASE_MAX_SPAN()","5e2ea799":"currentFlowerPrice()","5e2fe372":"getLastOrderIndex()","5e3013f1":"PlayX30()","5e3045c8":"getImpactTotalValue(string)","5e30b8a6":"refund(address,address)","5e30c961":"premium(address,address)","5e31005d":"scoreThresholdParams(address)","5e310670":"cancelTokenToEthOrder(uint32)","5e311cd7":"largestDonor()","5e318e07":"withdrawFees(uint256)","5e326b92":"setPreSaleStatus(bool)","5e331e62":"iterate_get(uint256)","5e33f94d":"ApolloSeptemCappedCrowdsale()","5e35359e":"withdrawTokens(address,address,uint256)","5e355dcc":"PJRToken()","5e3568b8":"session()","5e377b51":"Jackpot()","5e383d21":"values(uint256)","5e38ab4c":"BabyCoin(uint256,string,string)","5e38c77d":"getProductHistoryDate(bytes32)","5e393973":"get_contrib_arbits_max()","5e3b456c":"creatTokens()","5e3ba8ac":"usersGetter()","5e3bb4cc":"minimalSuccessTokens()","5e3bcaf7":"Fee(address[],string,uint8,string)","5e3cb7b0":"setTotalUsdAmount(uint256)","5e3cbb7c":"dayWithdraw()","5e3ced74":"callSurplus()","5e3d3b8a":"isPREICO()","5e3dbedb":"getTokenDescriptions(address,uint256[])","5e3df83f":"setFundingtokens(uint256)","5e3e2687":"transferFromParent(address,uint256,address,uint256,bytes)","5e3e37d1":"XfiniteAsset()","5e3e6092":"newService()","5e3e9158":"createWine(string,string,string,string,string,string,bytes32)","5e3fa843":"registerContract(string,bytes)","5e402ae2":"getCurrentTokensPerEther()","5e402bb5":"setInfoTokenSilverRatio(string)","5e403a9c":"phase7Price()","5e404de3":"setMaximumCredit(uint256)","5e4293ba":"i_am_generous()","5e431709":"sealedBids(address,bytes32)","5e431a6f":"phasePublicSale1_To()","5e439f66":"changeAge(uint256)","5e43f719":"enablePublicTransfers()","5e44423c":"ChangePreSaleDates(uint256,uint256)","5e44daf3":"vote(uint256,int256)","5e44e0a4":"modifyHorseyTier(uint256,uint8)","5e46f419":"leed()","5e475bb6":"createKT(string)","5e48379a":"changePriceContract(address)","5e488540":"claimRefund(address,bytes32)","5e4887bd":"initializeTime()","5e48ce0f":"dequeue(bytes32)","5e48f58f":"PRESALE_PERCENTAGE_2()","5e49db8c":"getUsersFuelsIds()","5e49fbfc":"WOS()","5e4a1d36":"getSavingsBalance(address)","5e4a8a20":"setAppCode(bytes32,address)","5e4b587b":"_BLOCK_REWARD()","5e4b5f7d":"setColdAddress(address)","5e4ba17c":"remove(address[])","5e4e7cbc":"record(string,string,string,address,bool)","5e4f63ec":"extendLockPeriods(uint256,bool)","5e5098c2":"setmangerallow(address,uint256)","5e50f037":"reward(address,address,uint256,uint256,uint256)","5e511afa":"sendTokensBackToWallet()","5e5144eb":"change(address,address,uint256,uint256)","5e520c29":"tokensPerWei10()","5e5294b7":"endingTimestamp()","5e52a00b":"getReferrer()","5e53e2f9":"EXACOIN(uint256,string,string)","5e556a4a":"faucetTo(address,uint256)","5e5571ac":"pay(address,uint256,bytes32)","5e5650ef":"admin_set_Apply_Store_Id_Fee(address,address)","5e571440":"presalesTokenPriceInWei()","5e57966d":"addressToString(address)","5e58217d":"hardCapIco()","5e58331c":"SAGA()","5e585889":"claimDeposit(bytes32)","5e58f141":"shares(address,bytes,int256)","5e593cd3":"Funding_Setting_cashback_duration()","5e5a77e6":"getQuestionAnswer(uint256,uint256)","5e5a7eb0":"createCase(uint256,address,address,uint256)","5e5ae1fe":"invalidateAllPendingMints()","5e5b1e61":"closeTokensale()","5e5ca8d4":"BuyerSeller()","5e5d2adb":"HUBUToken()","5e5d4320":"deleteUser(bytes32)","5e5d73b5":"CloseSaleFund()","5e5d926c":"makeDai(uint256,address,address)","5e5de297":"getUidAsInteger(address,address)","5e5e305e":"bbAirdropWallet()","5e5e4cc5":"ownerToArmy(address)","5e5f2e26":"allowedTokens(uint256)","5e5f2e37":"startedNewVote(address,uint256,string,uint256)","5e5ff24b":"addUsersToGroup(bytes32,address[])","5e601fed":"changePaymentAddress(address,uint256)","5e604b60":"addWhiteListedContracts(address)","5e6096c5":"setMinimumTokenSell(uint256)","5e60d438":"LicerioToken()","5e615a6b":"getParams()","5e62463a":"TransferLimitedToken(uint256,address,address[],address)","5e62af4d":"grandJackpot(uint256,uint256)","5e64f392":"_completeTask(uint256)","5e6558e5":"addAtkPlayerQuest(address)","5e65db7f":"deleteThis(uint256)","5e66dfee":"regularPayment()","5e66eb1b":"phaseClaim()","5e675098":"addFoundation(address,uint256,uint256,uint256)","5e68ac2c":"Kingdom(string,address,address,address,uint256,uint256,uint256,uint256,uint256)","5e68d459":"_getRNGValue(uint256)","5e6911af":"hardcapReached()","5e6936ac":"HitToken(uint256,string,uint8,string)","5e6992e3":"rcnFundDeposit()","5e6a7777":"setCompte_39(string)","5e6ad49d":"_setCosignerAddress(address)","5e6b4ee5":"increaseRate(uint256,address)","5e6b7a5c":"getUnitsDefense(address,uint256,uint256)","5e6c5d77":"number_of_deals()","5e6cbd6d":"_getRandom(uint256,address)","5e6db193":"Bithenet()","5e6e91ac":"Mint(uint256,address,string)","5e6eb33a":"CampaignClosed(uint256)","5e6f6045":"vestingContract()","5e6fa5ea":"inclusionEnExchange()","5e6fc129":"isRecord(string)","5e6fc8b4":"getChildrenCount()","5e7037d0":"removeSpriteFromSale(uint256)","5e7051cd":"setQuickPromoInterval(uint128)","5e70a6dc":"increaseLock(uint256,uint256)","5e715c16":"ICO_CONTRACT()","5e717e2d":"readDeal(string,address)","5e71823b":"numPositions()","5e71c7fa":"testCheckRokSold()","5e733baa":"openEgg(uint64,uint16)","5e734f5c":"revealBid(bytes32,uint256,address,bytes32,bytes32,uint256,uint256)","5e73dd37":"tokenCapPhaseOne()","5e7591e2":"register(bytes32,address,address,bytes32,bytes32)","5e763377":"ModifyMarking(bytes32,uint256,uint256)","5e763946":"setTaxationPeriod(uint256)","5e76a101":"onlyOwnerSetTeamWallet(address)","5e7893e2":"showprize()","5e78998e":"BatLimitAsk()","5e7aa842":"createEvent(bytes32,bytes32[],address,uint256)","5e7b9832":"updateItem(uint256,uint8,uint8,uint256,uint256,uint256,uint256,uint256,bool,bool)","5e7be40d":"getBeneficiaries(address,address)","5e7c85b1":"totalContrib(address)","5e7cafa4":"startPayments(uint256,uint256)","5e7d6fd0":"airdropHasExpired(address,uint256)","5e7f092c":"_createNFTCollectible(uint8,uint256,address,uint256,uint256[5])","5e7f22c2":"postBuyOrder(address,address,uint256,uint256)","5e7f322b":"exchangeEthToEur(uint256)","5e8023d1":"cascades(uint256)","5e80377b":"buySaleReferred(uint8,address)","5e815320":"forward_pass2(uint256[],int256[],int256[],int256[],int256[],int256[])","5e816740":"rollDice(uint256,address)","5e81b958":"isNonFungibleItem(uint256)","5e81ba96":"DestroyedBy(uint256,address)","5e825564":"setFactory(address,address)","5e83b463":"placeBet(uint256,uint256,uint256,uint256,bytes32,bytes32)","5e84d723":"publicSupply()","5e850225":"closePeriod(uint256,uint256,uint256)","5e8507f8":"destTokensAngel()","5e855f14":"Dice(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","5e85db0a":"getMinSkills(uint256)","5e8714d5":"changeSaleAgent(address)","5e871f0c":"dividendDistributionDuration()","5e885c63":"getPack(uint8,uint128)","5e89d92a":"Credentials(bytes32,bool)","5e8a6044":"foundersFundTimelock3Address()","5e8a79e1":"setRef()","5e8aedce":"SubajToken()","5e8af735":"placeBet(uint256,string)","5e8be190":"getCar(uint256)","5e8c63bb":"vehicle_assembled(uint256)","5e8e9589":"_createPenguin(string,uint256,uint256)","5e8f5022":"issueTokensWithReferral(address,uint256)","5e8f6597":"distributeInvestorsTokens(address,uint256)","5e90852d":"proposeTransaction(address,uint256,bytes)","5e90a9ff":"_getLotteryNum(uint256,uint256)","5e916b46":"rinkeby2()","5e91ba21":"checkSecret(address,string,bytes32)","5e91c37d":"tokensSoldInPresale()","5e91c5ed":"specialTransfer(address,uint256)","5e91d8ec":"updateEmployee(address,uint256)","5e943a30":"calculateReferralBonus(uint256)","5e949fa0":"changeDestination(address)","5e956abf":"createMeshPoint(string)","5e959287":"getSignature(string)","5e95ff98":"updateFreeze(address)","5e968a49":"ownerSetMaxProfitAsPercentOfHouse(uint256)","5e97894a":"TNPC()","5e983156":"getJudgeVoted(uint256,address)","5e983d08":"setPrices()","5e986ec7":"PoezenVoting(uint256,uint256)","5e987d32":"last_slot()","5e98e4c7":"abstain()","5e9a1849":"numDonations()","5e9a31fb":"MINBET_perSPIN()","5e9a523c":"assetPrices(address)","5e9a8c42":"get_deal_state(uint256)","5e9afc0e":"ERC223TestToken(string,string,uint8,uint256,address)","5e9d2b1f":"roundSize()","5e9d2e7b":"exchangesWallet()","5e9dbcb7":"_tag(string,string)","5e9e2226":"setOraclizeWinnerGasFee(uint256)","5e9f9613":"availableReserve()","5ea050ec":"InitiateCompanies()","5ea102b0":"Base()","5ea187c9":"BuildByteArray(bytes)","5ea194a3":"createScalarEvent(address,address,int256,int256)","5ea1bb17":"winInternal(address,bytes32)","5ea1d6f8":"commissionRate()","5ea1fc6a":"NAME_SATOSHI()","5ea27e40":"PRESALE_END_TIME()","5ea36bd6":"MultiHolderVault(address,uint256)","5ea39624":"ATTR_SEEDED()","5ea3ad0a":"doWithdrawal(uint256)","5ea40983":"addMember(address,uint256,bool,string)","5ea4cf50":"AMPTToken()","5ea56918":"BIAToken()","5ea63913":"getInvestorBalance(address)","5ea6474d":"getPVPBattleResult(uint256,uint256,uint256)","5ea67956":"CrowdtesICO()","5ea81231":"ownerAddRole(address,string)","5ea81e07":"editAccountData(address,string,bytes)","5ea82efb":"MariaToken()","5ea8cd12":"setMinPrice(uint256)","5ea8cf00":"PardiICO()","5ea94bcf":"updateUserTrustRankForMultipleChannels(address,bytes12[],int256[])","5ea95215":"SpaceXToken()","5ea98520":"changeNewExchange(address)","5ea9caff":"FrozenFund(address,bool)","5eaa6ca4":"_cancelMarkets(uint256)","5eaaa699":"SALES_SUPPLY()","5eaad235":"getDataByDeviceId(uint8,uint8)","5eab15e4":"devuelveApps(bytes32)","5eabc684":"updateIssuanceData(address,uint256,uint256)","5eabe01e":"saleSuccessful()","5eac1414":"UNIQ(uint256,string,string)","5eac6239":"claimRewards(uint256[])","5eac85d5":"burnGasAndFreeFrom(address,uint256,address,address[],bytes)","5ead330c":"getDungeonFloorDetails(uint256)","5ead8846":"updateFundsOwner(bytes32,bytes32)","5eadd607":"debugResetSubmissions()","5eae177c":"isTransferAllowed(address,uint256)","5eaefac1":"reservePricing()","5eaefb31":"CARD_TAKE_SHARE()","5eafe515":"newDeveloper(address,string)","5eb08d8a":"setBurnRate(uint8)","5eb101c3":"capped()","5eb17cdb":"setBeginTime(uint256)","5eb19ad1":"recalcAmountWithFees(uint256,bool)","5eb19eda":"InitiatePlanets()","5eb1f936":"JBToken()","5eb28fb2":"Robot()","5eb332da":"updateAward(uint256)","5eb38bef":"setcommissionPer(uint256)","5eb3f639":"assertTrue(bool,bytes)","5eb456c1":"goldIssueBurnFee()","5eb51d3c":"setTrancheMinTx(uint256)","5eb53bfa":"test_standardCampaignConstructionValuesFailsDueToNoParameterValidation()","5eb604bc":"GongChuangToken()","5eb61aa9":"executeSignedCall(address,uint256,uint256,bytes,bytes)","5eb62178":"getMinAmount(address)","5eb62d75":"sendPrivateSaleTokens(address,uint256)","5eb6a78f":"gamesCounter()","5eb7413a":"lockedTokens(address)","5eb9bbf7":"founderTokenUnlockPhase4()","5eba2472":"Migrations3()","5ebad2ab":"GrowthPool_Supply()","5ebaf1db":"staker()","5ebb7077":"mkDomain(bytes32,address)","5ebc1db8":"positionScount1(address,address)","5ebc7826":"CasCoin()","5ebca187":"testFailTransferWhenStopped()","5ebcaf7e":"sendBuyAgent(int256,int256,int256,int256)","5ebcc621":"endFundraising()","5ebcfe50":"taxTransfer(address,address,uint256)","5ebd2196":"getMyBalanceDNT()","5ebd9a83":"add(bytes32,address,address)","5ebdd159":"tokenAvailable()","5ebe4746":"CCPLUS(uint256,string,string)","5ebe7c72":"reply(string)","5ebfed78":"buyRegion(uint256,uint256,uint256,string)","5ec01e4d":"random()","5ec0c707":"winnerFromGas(uint256)","5ec112a2":"setPreSaleOpened(bool)","5ec1b499":"AnythingAppTokenPreSale(address,address,address,uint256,uint256,uint256,uint256,uint256)","5ec1fc19":"convertMint(address,uint256)","5ec211a1":"accountOfN(address)","5ec2c7bf":"auctioneer()","5ec2dc8d":"depositReward()","5ec30be2":"assignListingDB(address)","5ec38bec":"updateFundWallet(address)","5ec3f160":"secondsInDay()","5ec4eb95":"GoldWhitelist(address,bool)","5ec5bc8e":"pushOrderOfOwner(address,uint256,bool)","5ec5bed6":"coupon(uint256,uint8,uint8,bytes32,bytes32)","5ec70cd2":"_getProviderPriv(uint256)","5ec72a90":"maxCumAcceptedDeposits()","5ec81130":"calcBonusRate()","5ec88c79":"getAccountLiquidity(address)","5ec93cb2":"withdrawal_gas()","5ec94770":"RhinexFundCoin()","5eca2aeb":"getBytesArrayIndex(bytes32,uint256)","5ecb16cd":"withdrawTokens(address[])","5ecb6594":"isCoreContract()","5ecb7d20":"testGetCaseCount()","5ecc33ac":"testPrivacy()","5ecc7975":"YUPVesting(address,uint256,uint256,uint256)","5ecd62b9":"divCut()","5ecf36f7":"Print(string,uint256)","5ecf71c5":"decreasePower(uint256)","5ecfdcfc":"KnownTokens(address,address,address)","5ecff851":"p_setDevAddress(address)","5ed0f3fd":"changeVariables(address[],uint256[],address,address,uint256,uint256,uint256,uint256,uint256,uint256)","5ed16294":"nacBalance()","5ed188c9":"MNTToken(address)","5ed18d95":"CollatLending()","5ed31991":"lastLockingTime()","5ed411e5":"setNewToken(address)","5ed4382f":"fourthStageMinting()","5ed49e9b":"ADVISERS_AND_FRIENDS_WALLET()","5ed4d7ae":"_getTokenAmount()","5ed50033":"myetherpay(uint256,string,string)","5ed5684c":"HCHToken(uint256,string,string)","5ed570f3":"toggleCanCreateGames()","5ed5ea28":"whiteListContract()","5ed65228":"sponsoredJackpotMin()","5ed66172":"getCertificateForWallet(address,address,address)","5ed66998":"usingOwnership()","5ed6a8e7":"setData_13(string)","5ed73bc7":"distribute(address,uint256,address[],uint256[],uint256)","5ed75366":"DEVELOPER_FEE_FRAC_TOP()","5ed7ca5b":"halt()","5ed81ebe":"getInspireTokens(address,address,uint256)","5ed84aa6":"getNymCenterAPIURL()","5ed85753":"ergoam(uint256,string,string)","5ed9ebfc":"soldTokens()","5eda17bc":"_tuneLambo(uint256,uint256)","5eda232d":"getTokenStakeByIndex(uint256)","5eda5b9a":"interestCollected()","5edabc99":"getPresaleEndTime()","5edb2fb3":"uint256ToBytes32(uint256)","5edc1ac8":"discountDecimal()","5edc9bff":"upgradeUnitMultipliers(address,uint256,uint256,uint256)","5edca2b4":"unsuccessfulWithdrawal()","5edd4436":"newOffer(bytes32,string)","5eddd157":"claim(uint256,uint256,bytes)","5edf34d4":"Transfer(address,address,address,address)","5edf413e":"burn(bytes32,address,uint256,bytes)","5edf8d3c":"SetAdOwner(uint256,address,address)","5edfa1f8":"calculateFees()","5edfd788":"completedGames()","5ee10f3b":"instruct_2()","5ee2a018":"deployMultiToken()","5ee2cec2":"issuerDateMinutes()","5ee345e4":"computeEndowment(uint256,uint256,uint256,uint256,uint256,uint256)","5ee4e3f8":"LocklistAddressisListed(address)","5ee58efc":"distribution()","5ee5e9ee":"SaleStarted(uint256,uint256,uint256)","5ee679f9":"removePolicyFrom(address)","5ee6cc38":"buyToken(address,address)","5ee7144c":"_removeTopic(string)","5ee759e8":"encodeCurrency(string)","5ee760a5":"hashHardCap(uint256,uint256)","5ee7b392":"sendToken_internal(address,uint256)","5ee7cd23":"isBCFBuyMarket()","5ee7e96d":"grant(address,uint256,uint256,uint256,uint256,bool)","5ee857d1":"test_insert_findWithHintPrevUpdateTail(int256)","5eeb9ff9":"get_transferLock()","5eebc031":"newReadAddr()","5eebea20":"pending(address)","5eec743b":"minContributionMainSale()","5eec9df0":"softCapWei()","5eecbad8":"getFunderByIndex(bytes32,string,uint256)","5eecdec0":"unLockup()","5eed1f1a":"setTotalIndividualWeiAmount(address,uint256)","5eed3dcb":"donorList(uint256)","5eed886b":"minimumPerTransaction()","5eedbceb":"emitTransferFeeUpdated(uint256)","5eee006a":"secondStageStartsAt()","5eee7078":"sendETH(uint256)","5eeeee22":"setMaxWin(uint8)","5ef013d0":"Ico()","5ef17eff":"getSettingValuesById(uint256)","5ef1bfdb":"landPriceWei()","5ef27d1a":"hasRazCompleted(uint256)","5ef2a3f4":"giveAwayInProgress()","5ef2c79a":"getMyNmBet(uint256,uint256)","5ef3f3d1":"voteRelease()","5ef3f9e1":"BETS_CLOSING_TIME()","5ef4d2af":"_calculateTokenAmount(uint256)","5ef4ed42":"setBattleTokenAddress(address,address)","5ef505c0":"discoveryBlocksUntilAllowed(uint256)","5ef572ad":"stageMgmtSystem()","5ef5cdb2":"doFailedOffer(uint256)","5ef6228c":"bytesToAddr(bytes)","5ef652ad":"EtherFarmDevSim()","5ef6543c":"YDMediaToken()","5ef6ad57":"Delivery()","5ef74958":"Epam()","5ef78561":"cashWallet(address)","5ef79434":"DATE_PRESALE_END()","5ef7ac4d":"startRedeem(uint256,bool)","5ef7b303":"getPI_edit_14()","5ef80c87":"create20ContractToy()","5ef82429":"tixPromo()","5ef8da77":"Altruism()","5ef97145":"BokkyPooBahsAutonomousRefundathonFacility()","5ef9dde8":"removeApprovedGame(address)","5eface14":"numStakersForPoll(bytes32)","5efb4dc5":"deathData_a7()","5efb8266":"setGoldContractAddress(address)","5efbb728":"transferold(address,uint256)","5efbcfba":"minWeiToBuy()","5efbdc47":"setLastBidId(bytes32)","5efc156f":"Roles2LibraryAdapter(address)","5efd1682":"transferPreSigned(address,address,uint256,uint256,uint256,bytes,bytes32,bytes32,uint8)","5efd3c41":"whiteListEndBlock()","5efdb1e4":"percentToTakeAsSeed()","5efe2fcf":"releasedLockedAmount()","5eff7dae":"getInstructors()","5eff8b48":"Prakashcoin()","5effd20d":"withdrawForAddress(address,uint256)","5f01b42f":"alloweRefund()","5f02116f":"claimRewards(uint256[],uint256[])","5f024e91":"testCheckEthBalance()","5f0379f5":"firstPriceChange()","5f038b6d":"refillFunds()","5f05b3e4":"HappyToken(uint256,string,uint8,string)","5f05b9df":"removeTWhitelist(address)","5f065346":"pay(address,uint256,uint256)","5f06541d":"resetOwner()","5f065b4a":"checkItem(bytes32)","5f06900b":"changeBattleFee(uint256)","5f073f49":"gatherDetails(uint64[])","5f07a3e5":"addAllNewTicket(uint256,bytes32[],uint256[],uint256[],uint256[])","5f07bd15":"take_fees_eth_owner()","5f09952e":"voteAllowTransactions(bool)","5f0b37e4":"VeritokenToken()","5f0d5296":"reserveAllowance()","5f0d995b":"developer_string_contract_verified(string,string)","5f0da25b":"sendDeposit(uint256,address,uint256,bytes32)","5f0da5c9":"create(string,address,address,address,address,bool)","5f0e3855":"ownerRefundUser(bytes32,address,uint256,uint256)","5f0edfb8":"create(bytes,bytes32,bytes1)","5f0f1f85":"transferProposalEnd()","5f0f7786":"IssuedToken(address[],uint256[],uint256,uint256,address,string,uint8,string)","5f0fc2e8":"RealMoneyToken()","5f104c5f":"SalesAgentPermissionsTransferred(address,address)","5f111074":"picopsCertifier()","5f112c68":"renounceMinter(address)","5f11301b":"setServiceURI(string)","5f1231ea":"getMemberInfo(address)","5f141a0f":"confirmWrite(bytes32,address)","5f14af16":"Subscribe(address,address,uint256,uint256,uint256)","5f14e108":"openTokensale(address)","5f159e60":"TimeBoundaryChanged(string,uint256)","5f167276":"getNumElements()","5f17114e":"TimeDeposit()","5f1768c1":"buyerHistory()","5f1845f6":"transferDecimalAmountFrom(address,address,uint256)","5f184eda":"withdrawFactoryResourceBalance(uint16)","5f185329":"submitOrder(bytes)","5f1877a8":"productPrice(string)","5f18aa0c":"decimals(bytes32)","5f196876":"allPromotions(uint256)","5f19c7b2":"doSetSettings(uint256)","5f1a6f4b":"BARL()","5f1b3ee6":"getAPAddressSize()","5f1b46ab":"inflateToken(address,uint256)","5f1ca2fc":"ReferralRegistered(address,address)","5f1d146e":"eeeeeeeeeeeee()","5f1d7037":"KEDToken()","5f1d804f":"checkTxProof(bytes32,bytes,uint256[],bytes,bytes)","5f1d90ae":"getCurrentOpinion()","5f1e1c28":"__transfer(address,address,uint256,bytes)","5f1e580d":"ETUToken()","5f1e8c1b":"MAX_MODULES()","5f1f6c5e":"delFromList(uint256,address[])","5f1fc571":"set_prices(uint256,uint256,uint256)","5f1ff549":"issued()","5f222da1":"latestMomentOf(uint256,address)","5f227bfc":"totalPlayerTokenContracts()","5f22c42f":"getBuyerReceipt(address)","5f238402":"lastAllowancePaymentTimestamp()","5f241c8e":"AnythingToken(uint256)","5f24f6fe":"setUpgradedAddress(address)","5f2536f7":"calculateMaxContribution(address)","5f27e47d":"GetWinnerAt(uint256)","5f27f6e3":"getPlayerGeneralAll(uint32)","5f27f946":"handleTokens(address,address,uint256)","5f28213b":"SCTC(uint256,string,string)","5f28b383":"minPerUser()","5f28cb74":"getSubscription(bytes32,address)","5f2961e1":"walletFounder1()","5f2a9f41":"MAX_GAS()","5f2aeae9":"executeCreator(uint256)","5f2af8d9":"Logocoin()","5f2b9ac0":"startPhase3()","5f2bb66e":"BatchTransfer(address)","5f2befb9":"hasTerminated()","5f2bf49a":"BitcoinRateUpdated(uint256,uint256)","5f2da7ec":"todayDays()","5f2e0c20":"giveConsent(uint8,bytes32,bytes32)","5f2e2b45":"freeFrom(address,uint256)","5f2e4b31":"testDisputedInvalidSequenceWrongWriteAddress()","5f2e686d":"Ethereum_eight_bagger()","5f2e8493":"addmoney(address,uint256)","5f2ebcf2":"GMRToken()","5f2ef12d":"tokenFactory(uint256)","5f2f83ba":"getMul(uint256)","5f2fb08e":"removeElement(address)","5f3040bf":"getMIRABALANCE()","5f304615":"earlyAllocation()","5f309123":"sale2(address,uint256)","5f30ed2a":"withdrawAmountFromToken(uint256,uint256)","5f31ea82":"holdTokenInvestors(uint256)","5f32714d":"ChannelSettled(address,address,uint32,uint192,uint192)","5f3292d7":"DMCTCoin()","5f330669":"dateMove(uint256)","5f33afdb":"preallocCoins()","5f33c5e1":"Payout(bytes32,address,address)","5f34165d":"isRightBranch()","5f3616eb":"getNextOnce(address,uint256,uint256,uint256)","5f3619b1":"getProfitFromSender()","5f373c22":"setHydroContractAddress(address)","5f37b43f":"_getType(uint256,uint256)","5f3893ef":"getReward(address,uint256,address)","5f399d28":"TokenIceBox(address)","5f39fd73":"approveUpdate(uint256,address,bool)","5f3aa2bb":"checkIfRewarded(bytes,uint256,bytes,bytes)","5f3bc04c":"addressFundInvestment()","5f3c15ed":"radtokenSupply()","5f3c23be":"isProposalNotExpired(bytes32,uint256)","5f3c6686":"challengeBook(address,address)","5f3c91ad":"accrueEther()","5f3ca167":"crowdSaleInitialized()","5f3cebcd":"incrementalInverse(uint256,uint256)","5f3d634f":"freezeMulti(address[],uint256[],uint256[],uint256[])","5f3d7fa1":"maxAttendees()","5f3e3db0":"increaseWeeklyTransactionVolumeSending(uint256)","5f3f703c":"gifter()","5f403edc":"addThenSub(uint256,uint256,uint256)","5f40fc27":"withdrawGoldMoney()","5f412d4f":"releaseTokenTransfer()","5f412ff1":"ownerEnablePayee(address,address)","5f41ccef":"multMint(address[],uint256[])","5f421776":"switchONfreeForAll()","5f429ba5":"Risk()","5f437e48":"settingsState()","5f43e49c":"isDataYes(bytes)","5f4402c5":"distributeTokenToAddressesAndAmounts(address,address,address[],uint256[])","5f45161f":"payToInviter(uint256)","5f45221d":"retrieveIncompleteProof(bytes32)","5f452df1":"approveCrowdsale(address)","5f456c1f":"assignedAmountToEcoReward()","5f45c179":"ABYSS(address,address[],address)","5f46d750":"amountOfDividendsPayouts()","5f4784a5":"allOf(address)","5f478f74":"Milestone(string,uint8)","5f47ba42":"Plendito()","5f4821ab":"ContractFactory()","5f4874e4":"multiTransfer(address[],address[],uint256[],string)","5f48f393":"maxAmount()","5f493f63":"convertToMini(uint256)","5f495491":"claimsCreated()","5f4964e0":"setMarketComissionRatio(uint256)","5f497a09":"adminCharge_p1()","5f49d562":"QSTPerEth()","5f4a47c3":"updateUpdater(address,string)","5f4b125b":"get_pre_kyc_bonus_numerator()","5f4b2873":"getDepositedValue(address)","5f4b9b4f":"getPolicyCount(address)","5f4c71f1":"getTotalETH()","5f4dd2d8":"mintPreico(address,uint256)","5f4eab65":"hasEditionInProgress(uint256)","5f4ed0b1":"rebalanceBucketsInternal()","5f4f35d5":"setFullName(string)","5f504a82":"ownerCandidate()","5f5082dd":"setLast(uint256,address)","5f51028d":"checkIsReleaseRecordExist(uint256)","5f515226":"checkBalance(address)","5f516131":"ReserveUnknown(bool,uint32,uint256,uint256)","5f51d526":"balanceMapPos(address)","5f51db02":"Memes()","5f52e9fd":"WithdrawCashForHardwareReturn(uint256)","5f538fd4":"openMigrationPhase()","5f539d69":"addContract(address)","5f53e077":"setPausedTransfers(bool)","5f5404af":"PriceProvider(string)","5f542c94":"emitAreaEvaluated(address,address,uint8,uint256)","5f54a1c7":"requestEndCall()","5f54ae17":"buy50Price()","5f54fa98":"conventionId()","5f56315b":"enableSell()","5f56b6fe":"safeWithdrawal(uint256)","5f56e134":"averageArtworkSalePrice()","5f5810ea":"UBIT2018069()","5f5868db":"freezedValue()","5f589599":"resultsPublished()","5f58ed2a":"disableBot(address,uint64)","5f596681":"setShpExchangeRate(uint256)","5f598510":"KVMToken()","5f59940c":"addressToSpentEther(address)","5f5a98ee":"dragonGirlLotteryPrice()","5f5bb161":"set(bytes20,uint256)","5f5d867b":"CryptoPoosToken()","5f5db5dc":"setVariables(string,address,uint256,int256,bool,bytes32,address[2],uint256[2],int256)","5f5df710":"updateCertifier(address)","5f5e38b6":"setBuyPrice(uint16,uint16,uint8,address,uint256)","5f5f23a0":"charityFactor()","5f5f2aef":"amendRetention(uint8,uint8)","5f5f62f9":"setControler(address)","5f5fa782":"getCurrencyByte(uint256,uint256)","5f5fca9a":"setEnforceAddressMatch(bool)","5f6076bf":"Access()","5f60a5d4":"CompleteWildcard(uint256,address)","5f60ef47":"get_heaps(uint256)","5f60f485":"updateStatus()","5f61a26e":"PRESALE_ETHER_MIN_CONTRIB()","5f61bf99":"claimG()","5f623e15":"divisible_units()","5f645f16":"setInputFile(uint256,bytes32)","5f647d5a":"ethSignedMessagePrefix()","5f64b55b":"tokenB()","5f65545d":"Raffle_Prize()","5f65d621":"setSkill(uint256,uint256,uint256,bytes32)","5f65d703":"setInfo(bytes32,uint256)","5f65faf1":"isProduct(bytes32)","5f677404":"INITIAL_VALUE()","5f68688f":"endFirstBonus()","5f68804e":"SimpleLotto()","5f689fed":"startPVE(uint256)","5f6a1301":"clearPending()","5f6a4546":"ROLE_REVIEWER()","5f6acfe9":"_updateRate(uint256,uint256)","5f6d0ded":"ReservationFund(address)","5f6dd297":"getProjectEndDate(bytes32)","5f6e388a":"ProofOfCloneWars()","5f6ea340":"revokeAccess(address,address)","5f6ecea0":"vestedTransfer(address,uint256,uint256)","5f6edff8":"assureDAppIsReady()","5f6f8b5f":"setExclude(address)","5f7033e5":"getCurrentStartTime()","5f704f3e":"updatePrice(bytes32,uint256)","5f70d9ac":"getBot(uint256)","5f7118c7":"setRevealOpen(uint256)","5f71249c":"changeOrganisationName(string)","5f722859":"updateHashValue(bytes32,bytes32)","5f723b50":"getInitialReportMinValue()","5f72a508":"playerPopMining(uint256,bool)","5f72f450":"check(uint256)","5f73d6c0":"promisedTokenBalance()","5f746233":"dispense(address)","5f74a5ec":"pecunioWallet()","5f74bbde":"vote(address,uint256)","5f74c16c":"getPrizePot()","5f75b5ef":"whitelistAddress(address,address)","5f75cb6b":"getCountTransferInsToken(address,address)","5f7619a4":"takeFee(uint256)","5f766118":"salutaAndonio()","5f76e49a":"addPerson(bytes32,bytes32,bytes32,bytes32,uint256,bytes32,address)","5f770d47":"HyperSale()","5f77ace0":"stop_token_time()","5f7807a4":"transferToUser(address,uint256)","5f788531":"buy5Price()","5f791c7c":"ZRSToken()","5f7a7bb5":"returnRegDate(address)","5f7b68be":"addKey(address)","5f7b73b2":"getInvestorCredit()","5f7b764f":"_getLuckySpaceshipMoney(uint256,uint256)","5f7bb7f1":"setMaxProfit(uint128)","5f7c944f":"mintAccount(uint256,uint256,uint16,bytes32,uint256)","5f7cbc39":"addressOfTokenUsedAsReward2()","5f7cfe49":"internalSalt(bytes32)","5f7d897e":"checkVendor()","5f7dfd3f":"totalPaidToFunders(bytes32)","5f7e61fa":"SendTo(address)","5f7e7138":"setDth(address)","5f7ee166":"setupOpenDistribution(uint256,uint256,address,address)","5f7eed5d":"LeajoeToken()","5f7f9482":"statusQuery()","5f800348":"balancesImporter1()","5f8162bb":"transferTokenContractOwnership(address)","5f824297":"SellOrderPlaced(uint32,address)","5f84d0f9":"tokenR0()","5f84e343":"Artemine()","5f84f302":"setInterestRate(uint256)","5f852975":"randomtests()","5f8534ae":"claimDeposit(uint256)","5f856dbf":"Token_AllowTransfer()","5f85abdc":"contains(int256,int256)","5f865912":"addContract(address,address,uint256,string,bool)","5f877108":"sendToCharger(uint256)","5f88bff0":"presaleFundingGoal()","5f88e83d":"checkAndCallTransfer(address,address,uint256,bytes)","5f88eade":"opened()","5f88ffed":"wallet10()","5f8909bd":"biddingPeriod()","5f8a3029":"Standard_4()","5f8a7eab":"getReleaseAmount()","5f8aaa69":"sourceToken()","5f8aaef7":"contractStakeToken()","5f8af054":"getMessageLength(string)","5f8b93d2":"SingularityTest13()","5f8bad42":"getCommunityBallotWeiPrice()","5f8c1fce":"nextBracket()","5f8c494f":"IntIDQuery(address)","5f8cb3f6":"bounty_paid()","5f8cf6c4":"SMILO_SALES_AMOUNT()","5f8cf7c5":"PermissionGroups()","5f8d96de":"getDeadline()","5f8e38e1":"depositERC20Compatible(address,uint256,uint256,uint256)","5f8eb4c7":"jsub(uint256,uint256,uint256,uint256,uint256,uint256)","5f8f0483":"buyBankerAgreementFromImporterBank()","5f9094f5":"GetCreditsPerEth()","5f9145ef":"RefundReceived(uint256)","5f918b05":"ServiceProviderDisabled(address,bytes)","5f91af39":"_increasePlayerDivis(address,uint256)","5f9209ad":"getPositioninterestPeriod(bytes32)","5f92dee8":"adminGetWorldSnapshot(uint256)","5f932d71":"walletSetSigner(address)","5f945733":"getTotalInvested()","5f94e3de":"setSecondaryOperator(address)","5f94e82c":"setBridgeValidatorsProxyOwner(address)","5f956244":"TribePlatform()","5f9590fc":"_isValidDataHash(bytes32,bytes)","5f95ad43":"HasNoEtherTest()","5f9602e8":"perClaim()","5f96d9fa":"gemSpeedConversion()","5f972df8":"_jDiv(uint256,uint256,uint256,uint256)","5f9973b9":"WeiToken()","5f99c1b2":"_landholderJackpot(uint256)","5f9a2c23":"endFourthWeek()","5f9aa94f":"SpiceRates(address,uint256)","5f9adf84":"getUserSentTradeOfferId(address,address)","5f9b71ce":"bet(uint256,address)","5f9bad28":"saleBonus()","5f9c84b5":"transferirSala(address,uint256)","5f9cb50d":"updateMasks(uint256,uint256,uint256,uint256,uint256)","5f9dfc79":"minBuyTokenAmount()","5f9e1080":"settleBet(uint256,address,uint256)","5f9f3f46":"MakeSharesFromAmount(uint256)","5f9f4734":"birthday()","5fa13b49":"shweta()","5fa21f1f":"enableBetting()","5fa27af0":"GITC()","5fa382ea":"getPixelsOwned(address)","5fa3df98":"changeKYCStatus(address,bool)","5fa413b0":"ownerShareInPercent()","5fa44602":"tokenCreationDate()","5fa458b7":"buysoldiers(uint256)","5fa51277":"emergencyExtract()","5fa513d5":"findPtr(uint256,uint256,uint256,uint256)","5fa58268":"approveRequestPause()","5fa60fc8":"DCAsset(address)","5fa67c00":"Credit(address,address)","5fa77dac":"all(bool[6])","5fa7b584":"removeToken(address)","5fa7dc56":"getCurrentRateWithBonus()","5fa7df6b":"setDelegateAndLockTokens(uint256,address)","5fa87163":"viewlisting(uint256,uint256)","5fa8c869":"_getRandomPartSubtype(uint256,uint8[])","5fab11a5":"startICO(uint256,uint256,uint256)","5fac4996":"findSignedSubscriberIndex(address)","5fad18e4":"Visualrockcoin()","5fad3b1a":"initialiseContract(address,uint256)","5fad663e":"expectedDividends(address)","5fae0576":"isWhitelistedAddress(address)","5faeb944":"setData_22(string)","5faeced2":"removeFromUserCounter(uint256)","5faf2880":"changeDna(uint256,uint256)","5faf6675":"forecastInfo(uint256)","5fb02f4d":"startContract()","5fb07a62":"getDrugs()","5fb0ac18":"birthDragon(uint256)","5fb130af":"retry(address)","5fb135f9":"distributeAff(uint256,uint256,uint256,uint256)","5fb1552c":"GanaLocker(address,address)","5fb1ef8e":"checkOrder(address)","5fb1f1d7":"getSketchesOnOffer()","5fb3b944":"privateSaleSoldTokens()","5fb3e119":"Auction()","5fb42c59":"goldListPeriod()","5fb437f2":"setWithdrowRate(uint256,uint256)","5fb4f78c":"finishConfiguration()","5fb500a5":"ETT(uint256,string,uint8,string)","5fb64fd6":"checkMembership(address)","5fb6bca2":"fighterCore()","5fb77b9c":"revealBracket(bytes8,bytes16)","5fb7a643":"enableServiceProvider(address,bytes)","5fb80f20":"weiPerAnimal()","5fb8dc8b":"MasternodeTransferred(address,address)","5fb8fed6":"PJR()","5fb93bb7":"transferDataEntryClerk(address)","5fba26a6":"getBorrowedBooksCount(uint256)","5fbaa390":"haltSale()","5fbabc49":"setSkill(uint32,uint8,uint32,uint32,uint32,uint32,uint32)","5fbddcf3":"isLivingMonarch()","5fbe4d1d":"tokenAddr()","5fbf17ac":"totalUBetCheckAmounts()","5fbf79a2":"EmergencyStopSell(bool)","5fbfd9f6":"crowdsaleController()","5fbff3e2":"preferentialRate()","5fbff3fc":"KuangJinLian()","5fc02dcd":"freezeAccountForOwner(address,bool)","5fc13e0f":"initTransaction(address,uint256,bytes)","5fc1a4b8":"treasurySupply()","5fc1afac":"forwarders_count()","5fc2b479":"unlock(address,uint256,uint8)","5fc2cb39":"buyTokensWithProperEvent(address,uint8)","5fc31aeb":"_rawGetTokenDelegation(address,address)","5fc378df":"sawcoin()","5fc3ea0b":"withdrawERC20(address,uint256,address)","5fc42ebf":"KTZ()","5fc483c5":"OnlyOwner()","5fc4a6f3":"getCurrentBonusSystem()","5fc5d48b":"burnUnsoldCoins(address)","5fc5e727":"investedSumOnIco()","5fc6bd17":"pendingParsecs()","5fc71288":"GOTPAY()","5fc75bf2":"viewCreatePetitionFee()","5fc8cc16":"returnAmountOfELIXAddressCanProduce(address)","5fc9309c":"transferFrom(address,address,uint256,address)","5fc93ed7":"BirthdayBoyClickHere()","5fc9d392":"setMessageStatus(bool)","5fc9e75e":"historyCountOf()","5fca5a92":"set_arbits_max_contribution(address,uint256)","5fcb568c":"release(string,uint32,uint32,uint32,string,string,string)","5fcba9ae":"DURIANX()","5fcbd5b6":"countDown()","5fcc2edb":"IndividualityTokenRoot(address)","5fcc6277":"changeModuleBudget(uint8,uint8,uint256)","5fcc7ea1":"nextScheduledQuery()","5fcc9d0f":"hardCapPreIco()","5fcce279":"announcementType()","5fccf40a":"redeemBonusLot()","5fccfda4":"postICOSale()","5fcd7fe6":"OWNER_TOKENS()","5fce627e":"hasArea(address,uint256)","5fceab11":"incomingTransaction(uint256)","5fcee7a0":"CEOAddress()","5fcf0455":"interestEarnedAccount()","5fcf92ef":"received_tokens()","5fd030c0":"setLicenseNFT(address)","5fd0526e":"getReleasableBonusAmount(uint256,address)","5fd0f8b2":"smartContractSaleEnded()","5fd1bbc4":"publicStartTime()","5fd23730":"LogSwapToken(address,uint256)","5fd33b1b":"freezeTrading()","5fd357fc":"PortfolioContent(uint256,uint256,uint256)","5fd4b08a":"getName(address)","5fd56dfc":"AllInOne()","5fd56e98":"whoHadTheBiggestDick(uint256)","5fd5e3b4":"newEvent(uint256,address[],uint256,uint256)","5fd65f0f":"swapStorage()","5fd72d16":"addAllowance(address,address,uint256)","5fd7793a":"setStreamerContract(address,uint256)","5fd8c710":"withdrawBalance()","5fd8d3d1":"maxInvestorCap()","5fd9d610":"verifyGameResult(bytes32)","5fd9dff6":"allowance(address,address,bytes)","5fd9e124":"pStopBlock()","5fd9e693":"Crear_rifa(uint256,address)","5fda0dc1":"isOnExchange(uint256)","5fda83f6":"TokenTransferDisallowed(uint256,address)","5fdba1de":"setIBalance5(uint256,uint256,uint256)","5fdbba04":"debatePeriodOf(uint256)","5fdc1a97":"AllSportsCoin()","5fdc9e0a":"dropSupply()","5fdcd306":"check_status()","5fde0ed5":"getCountBySeller(address)","5fde731c":"wdiv(uint256,uint256)","5fdf05d7":"two()","5fdf5357":"sortDescBy(uint256[],uint256[])","5fdf60fb":"circulation()","5fe07013":"revokePermission(address,bytes32)","5fe0e081":"changePeriod(uint256,uint256)","5fe16454":"Fragment()","5fe22c8b":"testFailTransferWithoutApproval()","5fe27ab0":"createHKG(address)","5fe2d689":"getInterest(uint256)","5fe36964":"TEAMS_TOTAL()","5fe3854e":"calculatePrice(uint256,bool)","5fe3b567":"comptroller()","5fe44141":"getRegistryDataRegistered()","5fe4c0f3":"validationTime()","5fe59b9d":"setMotd(string)","5fe5b825":"AuthComplete(address,address)","5fe6fb19":"ConsultaProva(string)","5fe736e9":"createContractPlayer(string,uint256)","5fe745ea":"unlockOwnFunds()","5fe75764":"specialAccounts(address)","5fe772c6":"buyStakes(address,address)","5fe78b9b":"_getCurrentBonus()","5fe825f8":"getHodlOwner(uint256)","5fe8e7cc":"getHolders()","5fe9219a":"transferToMainViaRelay(address,uint256,uint256)","5fe98f99":"_getPayOut()","5fea13f8":"distributeToken(address,uint256,uint256)","5fea3de9":"getDuration(uint256,uint256)","5fec4be9":"issue(address[],uint256[],uint16[])","5fec5d0b":"isDelegate(address,address)","5fed2091":"addLovers(bytes32,string,string)","5fed22a4":"payOffClientDebt(uint256,uint256)","5fed2edd":"pushArray(bytes32,bytes32)","5fee0aac":"giveBattleBonus(address,uint256)","5fee63c3":"calculatedTo()","5fee8a4b":"getCommitThreshold()","5fef2094":"qryModuleDetail(string)","5fef4d34":"setOwner(address,address,bool)","5ff149ba":"UpdateEthBalance(uint256,uint256,uint256,uint256)","5ff1569e":"developmentPercent()","5ff19392":"strToUnderlierType(bytes32)","5ff1a9c0":"setPlAAdress(address)","5ff3b980":"getCooloffPeriod()","5ff456cb":"refundToOwner(uint256,uint256)","5ff46857":"getEthToTokenMakerOrderIds(address)","5ff4909b":"setAbel(address)","5ff4ae32":"setGasForDCN(uint256)","5ff4f876":"NFTBalanceOf(address)","5ff63abc":"ETimesChain()","5ff65efe":"MaxPoSXblock()","5ff6b342":"getValidDurationNonce()","5ff6cbf3":"getMessages()","5ff6e9d0":"investtokens()","5ff77b22":"checkTeamToAdd(uint64,uint64,uint64)","5ff79c07":"DenmarkvsFrance()","5ff7ec2f":"SoldTokensFromCroupier(address,uint256,uint256)","5ff7f947":"setSinistre_effectif(uint256)","5ff85cc0":"feeUnit()","5ff8b778":"findWinners()","5ff97818":"setMetadata0(string)","5ffabbce":"teamReserveTimeLock()","5ffb1578":"pushArrayValue(uint256)","5ffbba3f":"relativeDateSave()","5ffc7cc7":"transferProfit(uint256,uint256)","5ffcb734":"setTokensControlInfo()","5ffcbe30":"voteForCandidateViaProxy(uint256,address)","5ffce121":"getTopCompanyCount()","5ffd59bd":"GetBalanceOwnerForTransfer(uint256)","5ffde7be":"priceUpdateInterval()","5fffad5a":"setselfdropvalue(uint256)","5fffb7c7":"changeTokenAddress(address,int256,address)","600005b3":"Delegation(address)","60003918":"AllWorksToken()","6000eb9f":"getTeamInvest(uint256,uint256)","6001279f":"decreaseApprovalByLegacy(address,address,uint256)","600160a3":"bet_luse()","6001b23e":"getCustomerTxAtIndex(address,uint256)","60027c25":"bankrollLockedUntil()","60035c3f":"swipeHoney()","600440cb":"upgradeMaster()","60048290":"Kanzhang()","60063887":"transferDebt(address,address,address,uint256)","6006eb9b":"Demor(uint256,string,string)","6006f178":"WitdrawLenderProfit()","600720c2":"sponsoredJackpotAmount()","6007c4f8":"isTokenSaleOngoing()","6007c836":"setIndividualMaxCap(uint256)","60084004":"getRectangleArea(uint256,uint256)","6008fb07":"EtherGit(address)","60095dcb":"stopCharging()","60098088":"deleteCar(uint256)","6009eed3":"crowdSaleOpen()","600a686e":"setResponse(address,string)","600b1ff2":"setBlackBox(address)","600c200e":"ANIToken(uint256,string,string)","600c523b":"LogIssue(address,uint256)","600cf0d9":"getOrdersOfOwner(address,uint256,uint256,bool)","600d05ac":"XZARToken()","600d0beb":"isInRaffle(address,address)","600d7003":"retrieveTokens()","600da23a":"checkTimeBonusPercentage()","600de26a":"getDigitFromUint(int256,uint256,uint256,uint8)","600e0ee7":"getMySeeds()","600e85b7":"tokenGrant(address,uint256)","600f8cfc":"registerByList(address[])","60104cef":"createGame(uint256,uint256)","60116397":"Registrar(address,bytes32,uint256)","6012042e":"verifyPayment(bytes32,uint256,uint256,uint8,bytes32,bytes32)","60136123":"NTToken()","6013aa44":"testControlCreateSameNonce()","6013d092":"tokenSaleLimit()","6014e37c":"getLLV_edit_15()","60154e85":"payComision()","60155673":"TEC_TEAM_WALLET()","601570ea":"getResponseString(uint256,bytes32)","6016db70":"getAssetMinAmount(address)","6016dd4a":"credentials(address)","60173ede":"FondoNetwork()","60175bcb":"ActivityCore(address,address)","6017bb61":"Death()","6017d51d":"testInt(int256)","6019061b":"createSale(uint256,uint256)","60192799":"steps()","60196008":"replaceLevel(uint256,uint256,uint256)","601a0e77":"pseudoRandomUint8(uint8)","601ab918":"CashBetCoin(uint256)","601b349c":"removeCollaborator(uint256,address)","601ba73a":"setMainSale(uint256)","601cd624":"transfersAreLocked()","601d3910":"reconcile(address[],int256[],uint8[],bytes32[],bytes32[])","601d54eb":"ZTCrowdsale(address,address,address,uint256)","601ee75e":"SPINToken(address,address,uint256,uint256)","601fba02":"activateBuyback(uint256,uint256)","601fc832":"getObserverAtIndex(uint256)","6020b90a":"_internalTransfer(address,address,uint256,bytes)","6020d2c5":"_newSaddle(uint256,uint256,uint256,bool,address)","60213b88":"getInitialWithdrawal()","60214c6f":"test_method()","60217267":"stakedBalance(address)","60219c7b":"totalTokensForSale()","6022e6f8":"createProposal(address,uint256,string,bytes)","602451ea":"showAuthorizerOneAmount()","60246c88":"getPoolInfo()","602501a1":"SGD_Omnidollar()","602512e1":"setDifficulty(uint256)","6025d3e5":"finalizeAll()","60261ce6":"deadlinePreIcoOne()","6026bb86":"battleUnitIdRange()","6026c151":"offerGanTokenForSale(uint256,uint256)","60274396":"createDutchAuctionToBuy(uint256,uint256,uint256,uint256)","60281080":"HBVToken()","6029755e":"_generatePersonalNumber(string,uint256)","60299843":"minWeightDeduct()","6029b13f":"collect(address,address,uint256,bytes32,bytes32,uint8)","6029bf9f":"distributeFees(uint256)","6029d66f":"setRecoveryContract(address)","6029f53f":"getOrderTakerTokenAmount()","602a3fee":"sendMiningProfit(address[],uint256)","602acca1":"InchainICO(address[],uint256)","602b7001":"updateRefundApplications(address,uint256,bool)","602bc62b":"getUnlockTime()","602cd226":"DelayedPayment(address,uint256,address)","602cf359":"IOXToken()","602d7d62":"stateFail(uint256)","602e2533":"_fee(uint256)","602e496c":"fundcruVaultLockTime()","602e6623":"minePool()","602ea880":"AlphoTestTokenCoin()","602fbd79":"afterCrowdSale()","603066a4":"foundationReserve()","60312cdd":"LazyToken()","60316801":"getTokenMetadata(uint256)","6031749c":"updatePassport(address,uint256,bytes32,bool)","60319f71":"EOEToken()","6032f4a6":"fulfill()","603318ad":"getContributions(uint256,address,address)","60339c7b":"resetUserPromoBonus(address,address)","6033abd5":"CafePayed()","6033cdc6":"voteToUpdateMaritalStatus()","60344938":"changeCongress(address)","603510cb":"USDYToken()","60351748":"genericAction(bytes32[],address)","603546b9":"UnMint(address,uint256)","603553df":"ReederemEvent(address,uint256,uint256,uint256)","603601d5":"esercita_potere_pubblico()","60368a33":"totalBribery()","60368f30":"XLedger()","603709e3":"get10Characters(uint16)","60393a55":"addPeriod(uint256,uint256)","6039c60c":"fiveTimes(address,uint256)","6039fbdb":"addTokens(address,uint256)","603a552e":"engineer()","603c1370":"onNewLoan(uint256,address,uint256)","603c5e52":"SetCreditsPerEth(uint256)","603ccf5e":"AMBASSADOR_SEVEN()","603d1b98":"guardian1()","603d1d1c":"setSellOpen(bool)","603d1ed9":"createdOn(uint256)","603daf9a":"getBuyer()","603e3a40":"bulkBuy(uint8[],bytes6[],uint32[],uint32[])","603f4d52":"saleState()","60425c48":"TokenSellPercentage()","604269d1":"isMain()","6042a760":"icapTransfer(bytes32,address,bytes32,uint256)","6042fbe1":"maxPower_()","60434dcf":"getGitHub()","60445142":"depositCntr()","604497a2":"_transferFrom(address,address,uint256,bytes,bool)","6044ce6e":"cancelAgonForce(uint64)","60456068":"appreciationStep()","60457034":"setVerificationStatus(bytes32,bool)","6045804f":"delManager()","60464627":"totalWithdrawals()","6046c37f":"activateEmergencyProtectedMode()","6046d718":"loggedTransfer(uint256,bytes32,address,address)","6046f71d":"getProposalEthReward(bytes32,address)","6047a00e":"bonusTokensPool()","6047f7f5":"getTotalBmcDaysAmount(uint256)","60483a3f":"submitEtherProposal(uint256,string)","6048e89e":"setEthToBeClaimed()","60493ea4":"ico4Raise()","604a4bc8":"createTrackFromBack(bytes32,uint256)","604a4f9d":"regularTicketPrice()","604a6fa9":"Random()","604aa2cb":"backResiliumOwner()","604b2399":"_hasFlag(uint256,uint256)","604bf292":"safeSubtrNCP(uint256,uint256)","604c0b60":"transferBuyer(address,uint256)","604c7ef4":"BCBtuCoin()","604ca461":"addStory(bytes12,bytes12,uint256,uint256)","604cc1a5":"startGiveaway(uint32,uint256)","604ce56c":"MAX_ACTIVE_CANVAS()","604d3943":"poolCut()","604e3588":"SmartDollar()","604e4732":"tryFinializeLastProposal()","604e5fb8":"structureIco(uint256)","604e7af6":"totalDropTransactions()","604f87d8":"transferFromCallGas()","604f90a8":"getGladiatorChestAvailable()","604fc446":"getAddOnNeeded(uint16)","60500245":"registerName(string,bool)","60506aff":"initialDeposit(address)","6050eeb4":"_createLibrary(string,string,address,address,uint256,uint256)","6051c7cd":"acquireTokens(uint256,uint256,address,uint256,address)","60521116":"showPoolInfo(uint256)","60528e7b":"proxyWithdraw(address)","6052a849":"getEtherToBuy(uint256,bool)","60536172":"takeOwnership()","60542557":"SmartExchange(string,string,uint8,uint256)","60546602":"isAbsent(bytes32)","6054da0b":"setNextCommonTTMTokenId8(uint64)","60566675":"LeoCoin()","6056969b":"announce(bytes32)","6057361d":"store(uint256)","60577043":"tixFund()","6057f2ca":"addDealer(string,address,uint256)","60583488":"get_info()","60585358":"getByte()","60589137":"ListingCancelled(bytes32,uint256)","60595433":"Pass()","6059838b":"tierTwoPurchase()","605a18c2":"setTokenTransferFeeProp(address,address,uint256)","605a42db":"superDragon(uint256)","605a8ea3":"AvailableCommission()","605ae1d0":"BIDTToken(address)","605b24be":"gcard(uint256,address)","605c0209":"ZorffToken()","605c2dbf":"ManagerChanged(address,address)","605c43de":"getBetById(uint256)","605cee71":"delWallet(uint256)","605de51d":"getTotalSponsorship(uint256)","605e5ee1":"delWhiteList(address)","605f2ca4":"distributeTokensToContributorByIndex(uint256)","605ff295":"CelebrityToken()","60608438":"setCurrentAndNextSnapshotBalance(address,uint256,uint256)","60616ae2":"BllotPro(bytes32[])","6061d692":"month30Unlock()","60621984":"Mining24(uint256,uint256)","606224f8":"sendPendingAmounts(uint256,uint256,address)","60643652":"maxEntrants()","6064d863":"revealedCeilings()","6065140b":"setKYCVerificationContract(address)","60654e47":"getLotteryBalance()","60659a92":"tokensAvailable()","6065fb33":"genesisAddress()","60662fe2":"TOKENS_TOTAL_SUPPLY()","60668e58":"getData_5()","6066b066":"isSaleMarket()","6066ed11":"getCombatsCount()","6067be79":"getInvestedSumToRound(uint256)","60689557":"Rock()","6069272c":"getAllEntityIds()","60694549":"withdrawUserPrize()","60699026":"mulSafe(uint256,uint256)","60699d92":"createPersonalTime(address,uint256)","606a1f7a":"EtheremonTrade(address,address,address,address)","606a405e":"getAddressPlayNumber(uint256,uint256,uint256)","606a7f01":"Addr4()","606a9584":"_forwardPoly(address,address,uint256)","606aed30":"withdrawOwedToken(uint256,uint256,uint256)","606baff8":"minCrowdsaleAllocation()","606bc9a5":"setOwnerHoverText(address,uint256[2])","606ce3bf":"set(uint256,uint256,uint256,uint256)","606d0d14":"executeOffer(uint256,bytes)","606d55b1":"getY(uint256,bool)","606da54e":"XBLContract_addr()","606dc104":"openRaceCount()","606deecd":"requestData()","606ec65d":"TransferUpdated(address,uint256)","60702417":"MakeERC20(uint256,uint256,string,string)","60704108":"getAssetProxy(bytes4)","60708ae3":"issueAndCommit(address,address,uint256,uint256)","6070f1be":"NodeMCU_Endpoint()","60711058":"getUserDeposit(address,uint256)","6071eb5c":"ecosystemReserve()","60721b7c":"debitAmountToRefund()","607267d3":"getPlayerRoundDividend(address,uint256)","60726abb":"copy()","60727416":"newUserFrom(address,string,string)","6072ec64":"auditData()","60733572":"setUnicornToken(address)","60734859":"changeSaleTokenLimit(uint256,uint256)","6073660a":"findNextDay(uint256,bytes2)","60737a7c":"FaucetToken(string,string,uint8)","6073d045":"userDepositedWei(address,address)","6074123c":"AthlierToken()","607485fe":"firstYearMinedTokenCap()","6074b806":"updateOrderbook(address)","607531b6":"bitownToken()","6075eb7d":"openChest(uint256)","6076a3d5":"setEarlyParams(bool,uint256,uint256)","60771261":"scalarBaseMult(uint256)","6077759c":"bubbleSortAllMatches()","6078268b":"advisorsTokens()","60785bd1":"easyUpdateMatriarch(address)","6078b87e":"communityPeriodLength()","60795d80":"requestAllowance()","607a124f":"setAttrs(address,address,address,uint8,uint256,uint256)","607af216":"getRepresentedDTH(address)","607b463a":"getCash(address)","607b9169":"toOwner()","607b9f97":"safetyWallet()","607cbaff":"viewPetitionShareholder(uint256)","607d35c4":"uint5ToStr(uint256[5])","607db616":"tokenAllocate()","607dbae5":"ProofOfIdleness()","607dc1d6":"createNewCSCResource(string,string,uint256)","607eaf70":"investorBankroll()","607ecd96":"checkAccBalance()","607fa5a4":"updateRequired(uint256)","60805e5a":"unlockAddress(address,bool)","60808037":"numTokensForContributor(uint256)","6080af05":"setVoterStakesContract(address)","6081f5cb":"calculateBonus(uint256)","60820d80":"getOwnedTokens()","60827be8":"IDChain()","60829f8a":"unstake(address,address,uint256)","6082a02c":"getPriceIdv(bytes32)","6082a6ad":"Punani()","60834493":"Veetune(uint256)","60836aa4":"changeDevCut(uint256)","6083e59a":"maxDeposit()","608427e6":"ApolloSeptemTokenPurchase(address,address,uint256,uint256)","608458eb":"TOKEN_FOR_SALE()","6084747f":"mostRecentBlock()","60851f28":"viewThirdLotOfClauses()","6085e6af":"tokenSellData()","6086e22f":"calculateInitialPayerDeposit(uint256)","608716ad":"CryptoMoviesToken()","60874b27":"SpankICO()","60887081":"IEOStarted()","6088a917":"artworkRegister()","6088caf3":"tier4Time()","608980eb":"intervalsAt(uint256,uint256,int256)","6089e3c4":"BitCashPlatform()","608bc08c":"airDrop(address,address,address[],uint256,bool,address)","608bd7f4":"setLong(address)","608be57f":"_startNextAccountingPeriod()","608cadb8":"Goldmint(address,address,address,address,address)","608cb457":"SLACK_PERIOD()","608cc40a":"createRules(address,address[])","608d031a":"checkMiningActive()","608d576b":"getMultiRequestRegistrar(uint256)","608d670a":"XfStandardToken(uint256,string,uint8,string)","608e7fa6":"addAlias(bytes32,address)","608e9122":"InbestToken()","608eaa6a":"setFiscalVerify(bytes32,uint256,uint256,uint256)","608eba96":"_createCard(uint256,uint256,address,address)","608f102e":"District0xContribution(address,address,address,address,address[])","608f1f7e":"DGDTalk()","608fc07a":"updateSalesWallet(address)","60900c88":"coinprice()","60909c51":"closeDataResponse(address,address,bool,bool,bytes)","6090befe":"setCompanyWalletAddress(address)","60913244":"botOnSale(uint256,uint256)","6092019a":"MAX_FUNDING()","6092e55b":"createCDPLeveragedDai(uint256)","60938601":"approveOnly()","6094fae8":"finishTransfer(uint256)","609526c2":"generateRandomNumber(uint256,uint256)","60953744":"Mul(uint256,uint256)","60958192":"getProposalTTL()","6095c2d5":"setExchangeCommissionAddress(address)","60961955":"addFakeVisitors()","609619b4":"SecurityDepositRegistryReplaced(address,address)","60965dc0":"firstRoundWMStart()","609669eb":"StopIcoManually()","6096bbde":"_getGameAuctionGap()","609725ef":"getCurrentPassportLogic()","60972a84":"reissuedTransactions()","60975988":"PING_ORACLE_INTERVAL()","60979759":"p_setOwner(address)","6097bca9":"atnSent()","60994bb0":"_createRoc(uint256,string,uint256,address)","6099af40":"setConfigBool(bytes,bool)","6099ecb2":"pendingRewards(address,uint256)","609a54b0":"get_all_sellable_token()","609ab538":"newSchellingRoundEvent(uint256,uint256)","609ada00":"logEntropyTxDetails(string,uint256)","609b5785":"_mainsaleSupply()","609b8394":"setAnimator(address)","609ba988":"approveAdvertiserCharges()","609bdc71":"MintableMultiownedTokenTestHelper(address[],uint256,address)","609bec67":"period3Denominator()","609bf323":"VestedTokenMock(address,uint256)","609bf6ba":"GetGuestCount()","609d2bc5":"oraclize_setConfig(bytes)","609da897":"setupCompleted()","609df32f":"listNode()","609e5ca4":"getTournamentAmt()","609ec605":"toBytes(bytes4)","609f8fe2":"verify(string,uint8,bytes32,bytes32)","609f9a8e":"betFromGame(uint32,bytes32)","609ff0fb":"developersRecipient()","609ff1bd":"winningProposal()","60a10fa7":"setBridgeHeight(uint256)","60a11672":"safeTransferFromWithData(address,address,uint256,bytes)","60a1623f":"_withdraw(string,string,bool)","60a1f397":"_evaluateArea(address,uint8,uint256)","60a22932":"totalSaledToken()","60a22fe4":"nextMinimumBond()","60a31921":"dividendsOf(address,address)","60a4a929":"Assigned(address,uint256,uint256)","60a4d104":"dteamVaultAddr2()","60a4d1a5":"AddNewCard(uint32,uint32,uint8,uint16,uint16,uint16,uint16,uint32[])","60a4d599":"getPreICOLength()","60a59bdb":"random_number()","60a60fd8":"testProxyCallWithValue()","60a64947":"getAdv(address)","60a703ea":"ReceivedOwnership(address)","60a72c29":"getAppData(address)","60aa0e1c":"ICO_token_supplyCap()","60aa6b9e":"changeDueDate(uint256)","60ab5852":"issueTokens()","60acf888":"token_transfer(address,address,uint256)","60ad2391":"settlement(uint256)","60ad5bd0":"getCountrySpots(uint16)","60ad970d":"getLoansForAddress(address,uint256)","60ad9d7b":"burnByAddress(address,uint256)","60ae1eb5":"buySaleCardFromSys()","60aeac18":"neverPayBack()","60aef331":"buyTokensBonus(address)","60af9f91":"masterRecruitment()","60b0b0f0":"contribute(uint256,address)","60b1e057":"EVMSCRIPT_REGISTRY_APP_ID()","60b1e173":"getProof(uint256,address,address)","60b2a56a":"drawWinner(uint256)","60b35739":"_multiMint(address[])","60b38880":"TemperatureMeasurementA(address,int8,int8,uint16,string)","60b431a4":"testGetSig()","60b4a8fd":"getLastBidId()","60b6aa92":"privateIcoEndTime()","60b6ff5c":"ioucoin()","60b73223":"refundMoney(address,address)","60b7b3f6":"getCurLotIndex()","60b82e2e":"getRandomNumberList()","60b831e5":"cancelCall(bytes32)","60b95da5":"YclDoCoins(uint256,string,uint8,string)","60b99afb":"getIconiqMaxInvestment(address)","60baabf3":"nizk_setup()","60bba03d":"setTeamMember(address,bool)","60bc59b7":"__addressToString(address,address)","60bc5a06":"airdropManually(address,uint256)","60bce2f4":"usdPerEth()","60bd409e":"setAllowSellLands(uint16)","60bd7a9d":"statuses()","60bddc04":"getRateScore(uint256)","60be3547":"newLottery(uint256,uint256)","60be5f70":"newUser(address,bytes20,uint64)","60bea672":"createPorscheTicket(address,uint256)","60bebe98":"translateTileToWidth(uint16)","60bf1d2f":"ownsHive(address)","60bf46ea":"setQuotePriority(address,uint256)","60bf4dd5":"PGO_INTERNAL_RESERVE_CAP()","60bf9a84":"getbetData(uint256,uint256,address)","60bfe04e":"setRewardOpen(uint256)","60bff45c":"_addHolder(address)","60c1461f":"setNewICOTime(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","60c17d1d":"freedWosPoolForSecondStage()","60c17eec":"eventPaid(address,uint256,uint256,uint256)","60c20c16":"addOffer(string,uint256,address)","60c2db45":"walletTwitter()","60c2f663":"toUINT128(uint256)","60c311fd":"doBurnFromContract(address,uint256)","60c31544":"exporterReceivedPayment()","60c326ea":"setModel(address)","60c46821":"fundContractForRefund()","60c5cc3a":"acceptProposal(uint256)","60c6171c":"calculateGoldBuySimple(uint256)","60c66c5c":"maxNumOfPayoutCycles()","60c6b3a5":"claim(bytes,address,uint256,uint8,bytes,bytes)","60c6ccb2":"removeMonsterIdMapping(address,uint64)","60c6ec6f":"validState()","60c71546":"enableTransferEarlier()","60c72285":"submitRemoveOwnerTransaction(address)","60c79d00":"setNumTranscoders(uint256)","60c7bb5a":"host_lottery(bytes32)","60c7d295":"cache()","60c82d6f":"addAddressToWhiteList(address,address)","60ca46cd":"toTokens(uint256)","60ca6890":"_submitTransaction(address,uint256,bytes,bytes,address,uint256)","60cb66d0":"sum(int256[])","60cb8884":"TokenBank()","60cb96be":"CollectibleIndex0()","60cc2e8c":"maxGoalReached(uint256)","60cce8a5":"getValuableTokenAmount()","60cd4ba4":"getTimeBasedBonus(uint256)","60ce03d5":"totalTokenIssued()","60cf7133":"testSetPermissions()","60cfc624":"setLLV_edit_26(string)","60cfd359":"mainSale()","60d12fa0":"getExecutive()","60d1c056":"usedPaymentSupply()","60d1ce36":"collectibleIndexToApproved(uint256)","60d26f01":"ownerTransferWei(address,uint256)","60d2bee9":"addArtistSignature(uint256,bytes)","60d3b4b0":"frwd()","60d3e4c5":"isDistributionInProgress()","60d4c79b":"burnOneBroGlobal(uint256)","60d50130":"FineArtsToken(uint256,string,string)","60d586f8":"getValue1()","60d60d2e":"countcomp()","60d60dad":"mainSaleFirstEndDate()","60d63425":"StakePool(string,string,uint8,uint256,uint256)","60d704db":"getBank()","60d8c2d2":"oneTokenWei()","60d938dc":"isPresaleActive()","60d975c9":"GG()","60d9c823":"removeClientAuthority(address)","60d9f0a8":"setNotarius(address)","60dab6be":"ActionAgon()","60dccd89":"getContentAccount(uint256)","60dd5f90":"getPolicy(string)","60ddd8e8":"sumICOStage2USD()","60dddfb1":"votingWeightOf(address,uint256)","60dde4c2":"queueFront()","60de94d0":"setCCH_edit_11(string)","60e036a0":"EtheremonAdventurePresale(uint256,uint256,uint256,uint256,uint256,uint256,address)","60e092c6":"cancelOrder(address,address)","60e11e16":"Lira()","60e232a9":"changeVault(address)","60e2f6e8":"createProxyAndCall(bytes)","60e30a02":"ChinaInvestmentExchangeToken(uint256,string,uint8,string)","60e393c6":"DEVELOPER2()","60e39f73":"PotatoToken()","60e45f04":"UBSexToken()","60e474e3":"_issue(address,uint256)","60e4c1ac":"LogReceived(address,uint256)","60e519c0":"computeMarginAmount()","60e587f9":"goldReward()","60e5ef3a":"getPrice(uint8,uint8)","60e65bb8":"startTrading(bool)","60e68a25":"dash()","60e6cfd8":"addKey(bytes32)","60e6fb26":"resumePurchases()","60e708b3":"balanceOfUnlockTokens(address)","60e794de":"stageDataStore(uint256)","60e7a381":"o_aprendiz(uint256)","60e805c5":"LogMigrationCanceled(address,address,address)","60e85674":"checkLogin(address)","60e99b77":"getProposalState(bytes32,bytes32)","60e9c78b":"isNeedCheckTickets()","60e9f17e":"CRDToken()","60ea110b":"fromToken(uint256,uint256,uint256)","60eabebd":"CreateAPP(address,uint256)","60eb2826":"Badge()","60ebb498":"adminCancelWithdrawal(address,uint160,string)","60edc4c4":"timeOf(uint256)","60ee66c9":"setSubcontinentDiscoveryVotingContract(address)","60ef6037":"buySaddleShop(uint256)","60f01452":"updateEggs()","60f14509":"hodl()","60f17941":"tokensGranted()","60f1d148":"getMaximumBetAway()","60f247b5":"confirmTransaction(uint256,address)","60f2b9af":"setDocumentData(string,string,string,string,string)","60f2e1c0":"buyAndCrave(string)","60f2f673":"setcoe(uint256)","60f38d91":"endEarlyStage1()","60f5ac86":"campaignOpen()","60f5d0d8":"ReloadKeys(uint256,uint256,uint256)","60f61a4c":"buyUnitRaffleTicket(uint256)","60f66701":"useCoupon(string)","60f69dc0":"partnerReservedSum()","60f6e71d":"KuendeToken()","60f6fb2e":"chunkedWeiMultiple()","60f75530":"countRemaining()","60f75f3b":"closeMarketOrder(uint256)","60f8af90":"refundRound()","60f8bbb8":"setPuppySports(address,address)","60f8dab7":"userRefund()","60f8e036":"manageStatus()","60f96a8f":"parent()","60fb4aa0":"founder4Wallet()","60fd0668":"WAVcoin()","60fd0e91":"mintlist(address[],uint256[])","60fd1e66":"_movePendingToSetting(uint256,uint8)","60fd902c":"gnosisToken()","60fdd1c9":"setStakeRate(bytes32,uint256)","60fdf8ff":"GameEnded(uint256,uint256,uint256)","60fe136e":"BogdanoffCoin()","60fe47b1":"set(uint256)","60fece43":"percentForTeam()","60ff77cc":"ledgerRecordAdd(uint256,bytes32,uint256,string,uint256,bytes32,uint256)","61001cd3":"testIsStarted()","61004364":"depositTokenTo(address,address,uint256,uint256)","6100b1e1":"resetDiscounts()","610103d9":"changeTxFee(uint256)","61012e15":"phaseLength()","6101a1f7":"unitStealingCapacity(uint256)","6101d16b":"getNumberOfSharesForAddress(uint256,address)","6101d4f5":"payTheMan(uint256)","6101f748":"FundsRegistryWalletConnector(address[],uint256)","61025532":"permitBurning(bool)","61027f78":"paying()","610285d2":"testControlRetractLatestRevisionDoesntHaveAdditionalRevisions()","6102c049":"getBatchNumber(address)","6102d419":"getEthForMetResult(uint256)","6102e4e4":"verifyProof(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[11])","610358ae":"removePrivelegedWallet(address,address)","61039bef":"releaseLocked(address)","6103ae75":"AGENCY_ADDR()","6103d70b":"withdrawPayments()","6103d915":"Winners(uint256)","6103dda6":"mutate(bytes32,bytes32)","6104464f":"previousPublishedVersion()","61046d8b":"setRLCPerETH(uint256)","61047ff4":"fibonacci(uint256)","6104d75a":"deathData_f13()","61050bb7":"_fetchPaidOrdersForPayer(address)","61053cd3":"tokensByUsdTx(string)","6105b499":"artCopyright()","6105c8af":"stubFunction(address,uint256)","61064b48":"GetInvestorAddress()","61064b5a":"processMarkings(address,uint256)","61066dc3":"enableServiceMode()","610757e4":"_wallet()","6108b5ff":"channel_deposit_bugbounty_limit()","6108bd0e":"sowCorn(address,uint8)","61096820":"CETH()","6109e255":"EtherSent(address,uint256)","6109ff33":"BihuaToken()","610b16ab":"onTransferStack(address,uint256,uint256,uint256,uint256,uint256,bytes32)","610b1abd":"lottery(uint256,uint256)","610bafaa":"getTotalBPOfAddress(address)","610bbebd":"Sensor()","610be654":"closeContract()","610c1d68":"addNtf(bytes32,uint256,address)","610c3009":"badgeName()","610cbcc7":"logHash(uint256)","610d006c":"getSourceConstraint(int256,uint256,uint256,uint256)","610d5de8":"validateEndowment(uint256,uint256,uint256,uint256,uint256)","610da891":"debug3()","610e9ed0":"postDisputeEth()","610efc86":"RegisterMine(string,uint256)","61101bed":"getTAmount(uint256,uint256)","611067a1":"Rate7()","61116d1d":"masternodeDeregister()","6111bd91":"cyberEntry2(address,bytes32)","6111ca21":"enroll(address,uint256)","6111dd02":"calcCostsSelling(uint256,uint8,uint8,uint256)","61129a80":"getEarlyIncomeMul(uint256)","6112c2ab":"summPartnerships()","6112c7c9":"RedirectChanged(address,uint256)","6112e8ac":"mint(address,uint256,uint8)","6113611f":"stakeVoted_Eth()","611408ff":"latestReleaseUrl()","6114dc0f":"lastFlight(address)","61150aae":"ethusd()","61161aae":"bury()","61162182":"storeDoc(string)","6116ec49":"VotingFinished(address,bool)","6117525b":"initialClaesOffering()","6117b80c":"getFixedAndShareFees()","6117c9db":"retainedTokensVault()","61186e23":"getCountdownDate()","611a20ae":"IotcToken(uint256,string,uint8,string)","611b4095":"isWhitelisted()","611c4662":"getPriceByDayIndex(uint16)","611c7f50":"Core()","611cb25f":"failStage()","611cb6aa":"Vault(address,uint256,uint256,uint256)","611daa7e":"EmergencyBalanceReset(uint256)","611eb470":"maximumICOCap()","611ef452":"cancelDelivery(string)","611efc09":"sale(address,uint256)","611f1fbe":"itsLikeChicago()","611f64f9":"setTokenPrice(uint128)","611f69de":"__proxy_motion(address,uint256,uint256,bytes)","611fd026":"showApproveToken(address)","61203265":"organizer()","6120ada7":"setAuto(uint256)","6120e125":"TUMIYUNTOKEN(uint256,string,uint8,string)","6120ffbc":"accountsPayableHeld()","61211087":"firstAuctionsHighestBidder()","6121e522":"teleportPrice()","612249fb":"communityContributionSupply()","6123218b":"registerPurchase(bytes32,address,uint256)","61235639":"AcreToken(address,address)","6123c63f":"removeEmbassy(address)","6123dfc3":"NoWinner(string)","6123f7ba":"onlyWithValidSignatureAndMethod(bytes)","61241c28":"setTokenRate(uint256)","612472fe":"toZT(uint256)","6124a577":"whitelistController()","6124e4e7":"dividendContract()","612544b3":"getReservedTokens(address)","6125fd20":"voteForRefund(bool)","6126cb99":"registerAsset(address,bytes32,bytes8,uint256,string,string,address[2],uint256[],bytes4[])","6127421d":"tokenPayments(address)","6127a1ad":"_setRarityValue1(uint256)","6127cfd9":"verify_withdraw()","6127f246":"getActiveTasks()","61282631":"tokenMintedSupply()","612845fc":"claimQueen(uint8)","612867c2":"calcRefund(bytes32)","6128a4f3":"investorsLosses()","61296540":"rewarded_refresh()","6129f25f":"setReferralPercent(uint256)","612a711f":"SimpleERC20Token(uint256,address)","612a7562":"setBountyRegistry(address)","612ab238":"balanceOfOnForHolder(address)","612acecc":"frozenForever()","612bfae2":"description4()","612c0968":"privateSaleRate()","612c56fa":"submitVote(uint256,bool)","612c9dea":"unreserveFor(address)","612d6061":"getExpectedMinReturn(address,address,uint256)","612d669e":"setMinStakingAmount(uint256)","612e45a3":"newProposal(address,uint256,string,bytes,uint256,bool)","612e731d":"TheGreatEtherRace(string)","612eb5e7":"revokePermission(uint8,address)","612ecc48":"MINIMUMCONTIB()","612ed785":"winningTeamIndex()","612ee726":"isOnAuctionToBuy(uint256)","612ef473":"betRevealed(uint256)","612ef6e9":"isRefundApplied(uint256)","612f2f37":"setMaintenance(bool)","612ff19e":"PolicyPool(address)","61301409":"minereum()","6130ced2":"UniCoin(uint256,string,string)","6130d537":"createPartnerPlayer(uint256,uint256,uint256,address)","61314ee3":"managerAddressMap(address)","6132ca1a":"getResult(uint32,int8)","6133a0eb":"PRE_SALE_300_ETH()","6135e084":"myDividendTokens()","6135f602":"contractPartTwo(uint256)","61362b68":"reInitialize(address,address)","613696eb":"burnCadvsLeftInRefunding()","6137412c":"monethaGateway()","6137d670":"submitWhitelistRemoval(address[])","6138889b":"distribute(address[])","61389e8b":"getTokensManual(address)","6139a008":"numTokensLimit()","6139faa6":"getAllTimes()","613a626b":"SnipCoin()","613bc081":"ExternalAccountWalletConnector(address)","613c36ae":"sendToStocks()","613d8fcc":"oracleCount()","613de7cb":"subWizard()","613e0fb8":"reservationWallet()","613e2de2":"getContractInfo(bytes32)","613f4594":"totalBetAmount()","613f5b9f":"TokenContractAddress(address,address)","613f5fe8":"MAX_USER_TOKENS_BALANCE()","613f7665":"getClosedSaleWallet()","613f8dac":"sellShitClones()","613fd87a":"calcBigPromoBonus(uint256)","613fd998":"messageSpecial()","613ff46f":"rewardPerNode()","6140128f":"getTupleDetails()","61402596":"setInitialSupply(uint256)","6140af43":"preICOcollected()","6140c54c":"createProxy(address)","6140ca78":"setIsMiningOpen(bool)","6141b54b":"FundsWithdrawn(uint256,address)","6141d5d0":"CoffeeToken(address)","6142101a":"last_buyer()","61425d79":"numRequesters()","61426df4":"STCListing()","6142e78f":"allowedAmountTransferedToPoolTotal()","6142ff70":"createShipment(address,string,string,int256,int256,uint256,uint256)","61432e81":"ConsumeGas(uint256)","6143a80a":"isGameEnded(bytes32)","6143abba":"totalCreatedOfType(uint256)","6144a8a1":"ZJFPrivate()","61461954":"execute()","61463838":"getMyPlumbers()","61463b64":"_hashToAscii(bytes32)","61465a32":"distribute(uint256,uint256,uint256,uint256)","61472fd4":"CSGOBets()","61476d55":"GetTotalAmountForMultiplicator()","614781f9":"atkBoss(uint256)","6147a55c":"SwapPaused(uint256)","6147bcb9":"getPVPState()","6148fed5":"pollMap(uint256)","614939b2":"allocateTokensForTeam()","61493b97":"set_minimum_payment(uint256)","61494714":"_createNewGame(uint64)","61496b83":"endSplitAgreement()","614984d1":"getUnicornGenByte(uint256,uint256)","614a31bf":"setII_R2(uint256)","614af914":"_updateMargins()","614b3e7f":"BCSToken()","614baf5c":"withdrawAffiliateRewards()","614bbc33":"privateContribution(address,uint256)","614be0c4":"getRemainShareAmountInternal(address)","614cb904":"isFinalizeAgent()","614d08f8":"CONTRACT_NAME()","614d5f07":"stepForPrice()","614d85e1":"timeOut()","614f2b3a":"_diff(uint256,uint256)","614f3994":"SpeedyNetwork()","615155dd":"getVesting(uint256)","61523f2e":"changeEthReward(uint256)","61537010":"Whitelisted(address,uint256,uint32)","6153b827":"BancorHandler(address)","6154274d":"deleteProposal(string)","61543801":"currentPeriodIndex()","6154c16f":"MineOwner(uint256)","6154db6e":"UroToken()","61558349":"BitTeamToken()","615664ba":"Market()","6156e892":"checkOnlyContractOwner()","61571ddd":"distributionFinishing()","6157c5ec":"getGoldInfoSku(address)","615815f5":"releaseSecondUnlock()","61584936":"sealedBids(bytes32)","615878c8":"SkrumbleCandyToken()","61591a7c":"personUpdateDOB(uint256,int256)","61592b85":"getOrderDetails(uint32)","615a4e0f":"ChangeMainAccount(address)","615a604f":"setMarketer(address)","615acbae":"Freeze()","615af5fb":"areTokensSended()","615c2971":"Gametest()","615dbebb":"setContract(address,address,address,address)","615df83a":"remainderHolder()","615dfa5c":"defaultParams()","615ea899":"changeHello(string)","615ef639":"tokensClaimedAirdrop()","615f9f1f":"testFailTransferNotEnabled()","615fa416":"totalAtom()","61616292":"STCBonus(uint256,uint256)","6161eb18":"_burn(address,uint256)","61625c3a":"setLockByPass(address,bool)","61632d4d":"institutionStageSetting()","616361a7":"getArrUintField3()","61641bdc":"add(bytes32,address)","61649472":"getPoolFreezePeriod()","6165234c":"setPermissions(address,bool)","61665e40":"_premoveByValue(address)","61669dfa":"setSpecialBonus(address,uint256)","61679629":"UniversalRewardProtocolToken()","616852e9":"GoldBought(uint256,address,bytes32,string,string,bytes32,string,string,bool)","61688a85":"Lwcoin()","6168ba3c":"getWeiAggregateMayInvest()","6168c9c3":"tosell(address,uint256,address,uint256,address,uint256,uint256)","6169a7ed":"CashForHardwareReturn()","616a0997":"TokenPurchase(address,address,uint8,uint256,uint256,uint256,uint256)","616a3420":"verifySig(bytes32,bytes,bytes)","616a6371":"SingleAccountRules(address)","616b40e3":"totalInvest()","616b59f6":"deleteBytes(bytes32)","616b829d":"SwappedTokens(address,uint256,uint256)","616c9469":"Finalized(address,uint256,uint256)","616ceda7":"setJOYTokenAddress(address,address)","616d1fab":"distributeToAlternateAddress(address,address)","616d5058":"userAccounts(uint256)","616d50c3":"GCToken()","616dcf0c":"calculateTotalSupply(uint256)","616e2fd0":"FortaToken()","616eba4a":"getLocksrootIdentifier(address,address,bytes32)","616f7bc9":"addAddressesSet(address)","616fbee7":"changeMinimumBet(uint256)","616fca9b":"adopt(address)","616fe92a":"emitFeePoolUpdated(address)","616ffe83":"read(string)","61708908":"prepareDisputeValid()","6170a23e":"transferTech(address)","6170b162":"join(bytes)","6170feec":"getWinIndex(address,uint256)","61711115":"RegistrationStatusChanged(address,bool)","61718141":"totalSupplyIsLocked()","61719785":"clockmaker()","6171d7fc":"adjustTotalCoins(int32)","61725795":"setAquaman(address)","6172c0df":"updateDeposit(address,uint256,uint256)","6172f071":"setIsAllTransfersLocked(bool)","6173a70c":"initRandom(address)","6173e456":"setAMLWhitelistedBulk(address[],bool[])","617421c9":"calTripleRoom(uint256,uint256,uint256,bytes32)","61751577":"addCET6(uint32,uint64,uint64,uint64,uint16,uint16,uint8,uint8,uint8)","6175adee":"icoStandardPrice()","6175bc9c":"preStartBlock()","6175f9e2":"dragonHandler(uint256)","617605a1":"Zillion()","61764f59":"BitDATAToken()","6176caed":"HeroTrained(uint256,address,uint256,uint256,uint256,uint256,bool,uint256)","617708dd":"getEscapeRequest(uint32,int256)","61774704":"verifyBid(bytes32,bytes32)","61775ee1":"onlyBouncerRemoveExtension(address)","6177a197":"GoGoPay()","6177fa04":"setGenerateAddr(address)","6178a8b1":"splitStarFunds()","6178ac90":"_createCompanies(bytes32[],bytes32[])","6178efee":"returnToken(uint256)","617914be":"AUTH_CHANGEOWNEDOWNER()","61794267":"oldExecuteDecayFunction(uint256,int256,int256,uint256,uint256)","61798287":"safeToNextIdx()","6179ed72":"ProofOfSecret()","617a0951":"feeModifiers()","617a2a15":"icoStartP2()","617ac9a1":"SOSRcoinToken()","617b293e":"getInvestStatus(uint256)","617b390b":"approvePreSigned(bytes,address,uint256,uint256,uint256)","617bb8f5":"reject(uint32,uint32)","617c2fb8":"sell_Exchg_Reg(uint256,uint256,address)","617d2c84":"PRIMEx()","617d3c47":"RemovalPriceSet(uint256)","617d6bb4":"distributeEarningsBasedOnNumberOfCells(address,address)","617e80b4":"getPlayerShipModelByIndex(address,uint256)","617ee3a7":"MoonInc()","617f171f":"reopenDO()","617f4e3e":"set_got_refunded()","617f8666":"testFailRestartNotOwner()","617fba04":"getRecord(address)","617fc592":"priceStages()","61806891":"idVerification(address,address,uint256)","6180e4ac":"getAvailableNumbersForRaz(uint256)","6181d565":"getExpectAmount(uint256,uint256,uint256)","6181fb0a":"ERC20(uint256)","618293ba":"_updateState(uint256,uint256)","61829677":"claimdivs()","61836b0e":"lastUpdateEtherPrice()","61837e41":"get_stats()","6183c5d6":"EthereumAI(address)","618407e5":"tokenDrain()","61840c69":"getSaleSold(uint256)","61851416":"modifyCurrentVideoGamePrice(uint256,uint256)","61851679":"Protecthor()","6185bb50":"AOC_available()","6186b3e3":"showMoneyTransfer(uint256)","6186fe71":"CloseForecasting(uint16)","6187ce34":"gameRandon2()","61886014":"combineDice(uint8,uint8)","61888b40":"_percentSoldInPreICO()","618943c3":"WhitelistItemChanged(address,bool,uint256,uint256)","6189be15":"columnround(uint256,uint256)","618a057a":"_bidFirstShip(uint256,address,address)","618a1ec2":"getGoldDepositOfAddress(address,address)","618b870f":"setAmount2Claim(uint256)","618c5772":"removeTransferableAddresses(address[])","618cb85b":"GitCoinCrowdsale(uint256,uint256,address,address)","618ce6d7":"setWhitelistedAddressMain(address[],bool)","618de286":"addWhiteListMulti(address[])","618ea1c4":"terra()","618fa9ce":"getBotBillingIndex(uint256,uint256)","618fb1a6":"unsoldContract()","61903971":"MajListAll()","6190c931":"unclaimedCreditsWithdrawn()","6190c9d5":"cycle()","6190e9ca":"authorizedTokenUsers(address,address)","61919a08":"getWorks(bytes32)","6191fe9d":"FFC()","61927adb":"setDelegatedFrom(address)","61930630":"tokenStore()","61931f39":"zGetBothContractBalances()","61936d0a":"Wings(address,address,address,address)","619385bd":"newShare(address,uint256)","619419d8":"setTopic(uint256,string)","6194416b":"getProof(string,string,string)","6194acb6":"_validateOrder(uint256,uint256,bytes32,address,uint256,uint256,uint256,uint256)","6195c713":"against_proposal()","61962265":"PRESALE_MAXIMUM_FUNDING()","6196ac5b":"RubidSupply()","619792ba":"OwnershipGranted(address,address)","6197aadd":"JANDA()","6197bbab":"createRareAuction(uint256,string)","61983863":"MintedTokenCappedCrowdsale(address,address,uint256,uint256,uint256,uint256)","6198e339":"unlock(uint256)","61990759":"maxRandom(uint256,address)","6199ca26":"AmbrosusSale()","619a794d":"setAtomIsReady(uint256,uint32)","619c83ed":"completeTransfer(uint256)","619c89fe":"changeForeignBridge(address)","619caafa":"Reward(address,uint256)","619cec73":"DSHAckCoin()","619cf5f9":"batchtransfer(address[],uint256[])","619d2671":"acceptContract()","619d3063":"getNftId(uint256,address,uint256)","619d36ef":"DRAW()","619d5194":"setLock(bool)","619e6e7c":"userWalletTokenBalances(address)","619ebc4f":"GetTimeWeightedBet(uint256,uint256)","619f5e72":"takeExcess()","619fabfd":"addMultiplePublicSalesSpecialUser(address[])","619fc641":"backup_exchangeStaStb(uint256,uint256)","61a00f6d":"Ballot(bytes32[])","61a12160":"getPendingAddReserveData()","61a1d8fa":"SchmeckleToken()","61a215e4":"Controller(address,address,address,address)","61a227b6":"mtdAmount()","61a23f42":"loadReferredInvestors(bytes32[],address[])","61a2493a":"Jancok()","61a255b5":"vote(string,string,uint256,bool)","61a25f07":"lotteryFinished()","61a2d076":"isWhitelistOnlyPermissionSet()","61a3a281":"deployDefaultVestingContract(address,uint256)","61a5c4bd":"updateTokenAmount(uint256)","61a65433":"pot_total()","61a65e2a":"discountSaleEnd()","61a71303":"setMainSaleTLYperETH(uint256)","61a76900":"decode(uint256)","61a7b2f5":"transferFromIco(address,uint256)","61a99c4b":"ethDeposits()","61aa19d3":"icoAmountBonus1()","61aa8d93":"processFee()","61ab8904":"updateStats(uint256,uint256,uint256)","61ad08b5":"setSupervisor(address,address)","61ad487c":"PRESALE_PERCENTAGE_3()","61adeef4":"setUUID4Bytes(bytes16)","61aebe59":"stopSell()","61af1abd":"increasePriceAndDifficulty()","61afd5ac":"denyAccess(address)","61b121f5":"OneCoinOneBeerToken()","61b1bd04":"HumanEvent(address,uint256,address,address)","61b20d8c":"retrieveFunds()","61b2bb37":"setHalfLifeTime(uint256)","61b3516e":"MyCoins()","61b3b8e3":"p_setInvestorFundPercent_out(uint256,uint256)","61b46d61":"buyHunterLicence()","61b65fbe":"UpdateRank(address,uint256,uint256)","61b6683c":"destroyedBots()","61b69abd":"createProxy(address,bytes)","61b6f889":"handleOffchainWhitelisted(address,bytes)","61b7542d":"absMax(int256,int256)","61b79ea4":"incentiveDistributionRound()","61b7d7f4":"FiveBalanceToken()","61b87f0d":"getTokenAddressIndex(address)","61b8ce8c":"nextId()","61b930ae":"ICOfundsReceiverAddress()","61b94bc7":"LiverpoolvsRoma()","61b9739a":"setPayTo(address)","61b97435":"Register(address,bytes4,bytes18)","61b98cb3":"buyShips(uint256,uint256,bool)","61b9c6a3":"useBottle(address,uint256)","61b9c9f4":"buySeat(string,string,string)","61ba228b":"LukSevenToken()","61ba3377":"WatchLastTime()","61ba89d4":"NSCDistributionContract()","61bb246c":"secondBonus()","61bb9c52":"baseValue()","61bc1a49":"depositBalance()","61bc221a":"counter()","61bc6c57":"unauthoriseAddress(address)","61bcbe6f":"goodluck(uint256)","61bd12e0":"FAILED_STATUS()","61bdc978":"unfreezeFrom(address,uint256)","61be8456":"updateMarketData(address,address,uint256,uint256,uint256)","61beb1d7":"createAuction(address,uint256,uint256,uint256)","61bec256":"setContractActive(bool,bool)","61bec4fd":"QLANCEGO()","61bedcdc":"registerEmployee(address,address)","61bf2829":"RegistrationStatusChanged(address,bool,uint256,uint256,uint256,uint256)","61bf49ee":"plots(uint256)","61bf7692":"withdrawFoundationFunds()","61bf9c2a":"updatePoolContract()","61bfdc5d":"PatentCoinPreICO(address,address)","61bfe61b":"testAddUser(address,uint256)","61bffe01":"addIdentities(bytes32[],bytes32[])","61c003a7":"buyerNumDeals()","61c028e7":"getTokenURI(address)","61c083b9":"updateInflationRate()","61c1f224":"Q8ECOIN()","61c2c9c0":"getHowMuchUntilHardCap()","61c2e349":"create_a_new_market(address,address,uint256,uint256,uint256)","61c3b7f1":"setCharityBeneficiary(address)","61c52660":"Said(address,bytes)","61c5623d":"Vanadium()","61c61309":"setTokenController(address,address)","61c651b9":"oneQuarterInSeconds()","61c6a8e4":"addMutagenFace(uint256,uint256)","61c6bc82":"create(string,string,uint8,address)","61c748c7":"TressexToken()","61c76231":"resetBeneficiaryList()","61c7eb81":"Millionaire()","61c91c69":"webGiftLineTime()","61c9559b":"get_arbits_presale_open()","61c99b92":"msgsender()","61cac1fb":"partnersReward()","61cb5a01":"testString(string)","61cc576d":"evaluateOdds()","61cd5683":"testToByte(bytes)","61cd756e":"prevRegistry()","61cd90b0":"revealY(uint256,uint256)","61cdb1d7":"getByMesa(uint256,uint256,uint256)","61cdd2dc":"rightAndRoles()","61cec717":"changeCurrentCirculating(uint256)","61cf6d1c":"investeth2018()","61d027b3":"treasury()","61d0ad9e":"TransferFunds(uint256,uint256)","61d11318":"RedEnvelope()","61d161ea":"unitsPerTransaction()","61d3ba8a":"addWhitelistAddresArray(address[])","61d3d7a6":"isUpgradeAgent()","61d3d902":"getPlayerReferrerID(uint256)","61d43971":"updateGasCost()","61d49ea8":"reveal(uint256,uint256,bytes32)","61d51df8":"SKYSWAP()","61d5593c":"calculatePoohSell(uint256)","61d585da":"state(bytes32)","61d5f225":"minBetSize()","61d60021":"getCourseID(address,address)","61d61998":"implementsERC721YC()","61d689fa":"register(uint8)","61d68b54":"requestConsent(address,address,uint256)","61d6d385":"withdrawUnsold()","61d7c713":"validPayDest()","61d81aed":"exitBuyRequest(uint256)","61d942f3":"_removeLicenseTerms(bytes32,bytes32)","61d97c41":"GetPartyRole(address,address)","61da1439":"read(bytes32)","61da46c4":"joinDraw(uint256)","61db17ab":"_validatePurchase(uint256)","61dbbc80":"LARGE_PURCHASE()","61dbfc3f":"changeConfig(uint32,uint256,uint8)","61dc648f":"LogExternal(uint256,address,bytes32)","61dcd7ab":"createTime()","61dd8d13":"DexAlpha()","61ddf923":"_getTokenAmount(address,uint256)","61df46f6":"DatCoin()","61df5c4d":"getEncounterResults(uint256,address)","61dfacf2":"removeBuildingFromServer(uint256,uint8[10],uint8[10],uint8)","61dfdae6":"setData(address)","61e01356":"randNonce()","61e062a4":"_emitHardcapFinishedManually()","61e0f7a8":"swypeCode(address)","61e1077d":"decreaseApprovalWithSender(address,address,uint256)","61e1fe91":"setFreeDino(uint16)","61e214d8":"isValidPurchase(uint256)","61e25d23":"numActiveTranscoders()","61e3564f":"approveAccount(address,bool)","61e360b7":"maximumIndividualCap()","61e3c944":"setUint(uint256,uint256)","61e3f0a4":"setTimeBasedBonus(uint256[],uint256[],uint256[])","61e42039":"priceString()","61e49344":"buyinReturn(address)","61e4a23a":"expireGame(uint256)","61e4fd2b":"approveEscrow(address,uint256)","61e539da":"testFailWrongAccountTransfers()","61e5f5f2":"balEth()","61e60550":"TransactionDisputed(uint256)","61e6e66b":"DestroyedBlackFunds(address,uint256)","61e76056":"denyByDelegate(bytes8,bytes8)","61e7662b":"getAccountSpendingLimit(address)","61e88f9a":"test_0_validOwner_construction()","61e8ee04":"TOXTToken()","61e91ea1":"getDataContractAddress()","61ea6ed7":"transferFromBase()","61eb2e1a":"UNITStagesManager(bool,address)","61eb3836":"getProjectStatus(address)","61eb71c1":"setSellable(bool)","61eba552":"getMetaData(uint256)","61ecc8b5":"isLogo(address)","61ed2094":"demicals()","61ed373b":"comment(uint256,bytes32,bytes32)","61ed8097":"SEOToken()","61eda968":"cancelAssessment()","61edfe6e":"p_setBankOfEthProfitPercent(uint256,uint256)","61ef265b":"spaceAfterReturns()","61ef669b":"dateTier2()","61ef8d91":"setErc20Rate(string,uint256)","61efc7db":"resolveDelegation(address,address)","61efc807":"transferbatch(address[],uint256[])","61f00da2":"OMIVIAToken()","61f127dd":"_price_tokn()","61f134fa":"OZRealestatesToken()","61f15236":"addHolder(address,uint256)","61f17532":"tune(uint256,uint256)","61f188de":"createTree(string,string)","61f1c5ba":"vaultWallet()","61f1d889":"setFlag(uint256,uint256)","61f2c8b0":"_addShareToNewOwner(address,uint256,uint256)","61f2de50":"spawn(uint256,address)","61f30408":"emitTimeAdded(uint256,uint256)","61f37dff":"calculateIcoTokenAmount(uint256)","61f3c006":"setRoundMaxPerUser(uint256,uint256)","61f3c62e":"remain()","61f3cfb1":"updateExistingRaz(uint256,uint256,uint256,uint256,uint256,string)","61f43285":"gubberment()","61f529af":"initEthMultiplicator(address)","61f54a79":"getNextUnsortedOffer(uint256)","61f61867":"addSettingDeprecation(uint256,uint256,address,address,address)","61f66dc4":"updateUserClaim(address,uint256)","61f6b429":"myAvailableFunds()","61f70161":"placeOrder(bytes16,address,address,uint256)","61f7025f":"fetchBalanceByAddress(address[])","61f721e8":"HGFCToken()","61f76d67":"withdrawEtherToOwner()","61f82156":"receiveCashback(uint256,address)","61f8cdd6":"transferETHToContract()","61f8e91a":"unitTestModifyStaker(uint256,uint256)","61f9ca4d":"modifyGroup(uint256,string,string,string,uint256,uint256,uint256,uint256,uint256,bool,uint256)","61f9e04d":"getWithdrawn(uint256)","61faee9e":"noTransfer(address)","61fba37d":"investorBalanceOf(address)","61fbdf4e":"gameIsCalculated(uint256)","61fc3790":"Monthprofitend()","61fc65a0":"checkBirth(uint256)","61fc703c":"Danku_demo()","61fd718f":"getOrderAllocatedToFundPool(uint256)","61fd8f1b":"sendTokensToCompany()","61fda640":"ownerUpdateContractBalance(uint256,uint256)","61fdfa9b":"returnDeed()","61fe51a1":"rootAuthority()","61fec3a4":"clearSponsorableJobApprovals(address,uint256,address[])","61ff715f":"deploy(uint256,bytes)","61ff8191":"CirculationEnabled()","6200979e":"AngelInvestmentAddr()","6201124f":"employeeDenyExerciseOptions()","6201510a":"getPreSaleRank(address,uint256)","62016083":"removeDestinationChain(bytes8)","62017ebc":"left46(uint256)","6201d683":"createTokenUri(string)","62024dce":"forceCrowdsaleRefund()","62026229":"validateLand(address,int256[],int256[])","62027c1e":"changeCJTeamWallet(address)","620346c6":"setStopReceive(bool)","6203f09f":"MAX_INVESTMENTS_BEFORE_MULTISIG_CHANGE()","62040de3":"numberOfBoardMeetings()","62040e50":"Bitscreen(bytes32,uint8,uint8,uint8,uint8,string)","62043bd8":"DIVIDER()","62059839":"_setOwner(uint256,address)","62066eb3":"getMinimumAmount()","6206880b":"contributorsLockdown()","62074c31":"getProjectMaker(bytes32)","62075af4":"giff(uint32,address)","6207c802":"getSubjectIdentById(uint256)","6207d239":"privSaled()","620892bd":"NRB_address()","620a9c95":"BITSToken(uint256,string,uint8,string)","620b0f23":"getMyAnthill()","620b2731":"_getClientProviderUID(address)","620b5cd2":"Crypto()","620b75df":"portfolioManager()","620d025c":"roundFunds()","620db609":"rubyToken()","620eb8ee":"setDisbursementEndTime(uint256)","620edb32":"allocatePrivateToken(address[],uint256[])","620ffe99":"testFooUdate(uint256)","6211db22":"querybalance1()","621277cb":"hardCaps(uint256)","62133a6c":"getPlanetName(uint256)","62135491":"distributeTokensToMembers(uint256,uint256)","62150b3f":"KaoPuToken(address,uint256)","6215be77":"depositToken(uint256)","6215f292":"updateBasePrice(uint256,uint256[],uint256[],uint16)","62161235":"getRandomNumber(uint16,uint8,address)","6216bde5":"TokensRewarded(address,address,uint256,address,uint256,uint256)","6217229b":"sellRate()","62173282":"updateMVNRate(uint256)","6217903f":"BNB_TOKEN_PRICE_NUM()","62182636":"setParams(uint256[],uint256[])","6218e5cd":"setGuardianVend(uint256,uint256)","6218fd8b":"icoEndsAt()","6219004d":"setPosttgeAddress(address)","621a25f8":"right66(uint256)","621a61ac":"STATE_NOT_FINISHED()","621ab11a":"bonustokn()","621b23e2":"getOwner(uint32)","621bc379":"setReverseRate(address,int16)","621bd8d7":"getPreviousReportingWindow()","621c3275":"disembark(uint16,uint16,uint256)","621d388c":"senderIsAdmin()","621de5ac":"AUSBToken()","621ded8b":"FinishCompetitionEvent(uint32)","621df4be":"getCurrentElectionCycleBlock()","621e9a45":"BAQToken()","621f7e45":"setPeriodRound(uint256)","621fb946":"getLLV_edit_27()","62205bd8":"privatesaleFinalized()","622104d9":"integration()","62219866":"getPercent(uint256,uint256)","6221c805":"supplyRound3()","6221dc20":"HackableETH()","6221e77b":"Logs(address,uint256,uint256)","622235e6":"getPage(address[],uint256,uint256,bool)","62228c17":"CTADevilleToken()","62246c41":"setNickName(bytes32)","62251182":"_withdrawOwnerTokens()","6225924e":"_mint(bytes32)","6225a8ad":"GetResult(uint256)","6225b759":"setForceExecuteOfUsers(bool)","6226bddb":"getProductStructById(uint256)","6226d4b2":"addAddressToAdmin(address)","6227ed6e":"createPerson(string,string,uint256,uint256,uint256)","6227fd3a":"firstItemWrong()","622a0a19":"playerBudget()","622a10fd":"CORECoin()","622a2d31":"setDistanceAndPrice(uint16,uint16)","622ac8ed":"countWishesAt(address)","622ae7aa":"getDeployedTokens()","622af809":"setMintContactAddress(address)","622b0b29":"StakeEvent(address,uint256,uint256,uint256)","622b2a3c":"validDelegate(address,bytes32,address)","622b6659":"doBigDrop(uint256,uint256,uint256,uint256)","622c77fe":"totalSupplyLocked2Y()","622d6c97":"ExecutionError(string)","622d82df":"Buddha()","622dda96":"chooseRandomNumber()","622ddaba":"getGenesForSaleBySeller(address)","622e5026":"Insurance()","622e88cb":"testBitsXorSuccess()","622f9730":"forward(bytes,address,address,uint256,bytes,address,uint256)","622fe39f":"getLoanData(uint256)","6230ebda":"defrostFrozenTokens()","6231775b":"miniGameId()","623195b0":"setABI(bytes32,uint256,bytes)","623406d2":"setRecordContract(address,address)","6235e3a2":"getAddressCreatorById(bytes32)","6235eef3":"getCurrentReportingWindow()","62362cc2":"COIN_SUPPLY_TOTAL()","623659b4":"doTransfer(address,address,uint256,uint256)","623670b2":"sendTokensToPartner()","62373537":"current_start_divholder()","6237564c":"isDopeRaiderDistrictsCore()","6239f13d":"triggerSoftCap()","623ba5c9":"callBackGasAmount()","623d2295":"Minado(address,address)","623d2b62":"getRequiredBetAmount(uint256)","623d5652":"projectExists(address)","623d5e56":"devolverBici()","623d96ed":"preDuration()","623decaa":"unlockedTokensOf(address)","623e4fb8":"BBCToken()","623eff55":"tokensTransferred()","62400e4c":"supplyOf(address)","6240282c":"LiquidDemocracyControllerFactory(address)","6240c7aa":"COENXToken()","6241bfd1":"Token(uint256)","6244326d":"humanityFund()","6244b7ed":"unWhiteListInvestor(address)","624522f9":"accountFrozen(address)","6245adff":"DirectlyDeposited(address,uint256)","6245eb07":"setProvenance(address,uint256)","62463079":"tier2End()","62464576":"stage_2_add()","62465f0a":"GenesisManager(address,address,address,address,uint256)","62469353":"firstDepositTimestamp()","6247c38f":"updateChargingRate(uint256)","6247cfd9":"priceForKeys(uint256,uint256)","6247f6f2":"whitelistToken(address)","62486d42":"getTokensAmount()","6248cf49":"_donationSupply()","6248d6bf":"getOracleMetaData(address)","6248fd10":"SLC()","62491332":"lockPurchase()","62492e9d":"preIcoBonus()","624964c3":"getBancorContractAddress()","6249a5c7":"UnpauseEvent()","624a8bc3":"MyTotalWithdrew()","624aba21":"_getWinCountWeight(uint256)","624adc4c":"OwnershipTransferCompleted(address)","624ae5c0":"rID_()","624ba0a4":"maxImports()","624bb58f":"marketingSupply()","624bb8b3":"setCBaddress(address,address,address)","624bd6c4":"depositToken(address,uint16,uint256)","624c3dbd":"imageUploadComplete(uint256)","624c5673":"USDollars()","624cc0a5":"teamMemberAtIndex(uint256)","624d4309":"USBcoin()","624dd6a9":"getInvestmentsByCountry(uint16)","624de3d9":"InterfaceSignature_ERC721Optional()","624dee7c":"_release(address,address,uint256)","624e3b36":"totalearners()","624ecda9":"Sleep()","624f011d":"doStop()","62502169":"sendCollateral(address,uint256)","62502fe7":"getNameDigest(string)","6250bfa3":"createOrder(bytes32,bytes32,address)","625101d5":"getOwnerMoney()","625126ed":"shift_left(uint32,uint32)","6251aee6":"icoPhase3End()","625295fd":"distributeCollectiblesTo(address)","6252c127":"onCrowdsaleEnd()","6252d651":"setForegroundColors(bytes3[])","62531721":"getStack(uint256)","6253367a":"queryChallenge(bytes32)","6254add1":"PRIVATE_SALE_POOL()","6254cf80":"setGameHostAddress(address)","62564c48":"getProposals()","62568d83":"min_buy_block()","62571cac":"getTodayOwnerName()","625785bb":"productionCardIdRange()","62581b79":"CubaazCoin()","6258683e":"devMiningRewardTransfer(address,uint256)","6258d524":"saveEther()","62598ae6":"PaymentExpected(bytes8)","62599964":"usesThem()","625a6726":"fixClock(bytes32,uint64)","625adaf2":"setTokens(address[])","625b666c":"Luxury()","625b8e60":"_redeemByPartition(bytes32,address,address,uint256,bytes,bytes)","625bc37b":"releaseTeamTokensAfter12Months()","625becbc":"showLockState(address)","625cbb23":"setWhiteListAddresses(address)","625cc465":"baseDonation()","625cfc46":"sellRateZeroQuantity(uint256)","625fcce7":"dealer_cut()","625fe9ec":"updateCrowdsale(uint256,uint256,uint256,uint256,uint256)","6260f55b":"ETH_USD()","62612c6d":"PatronTwoWithdrawal()","62614ae6":"BNT_CONVERTER()","6261c662":"bonusStart()","626263c5":"calculateEthToChargcoin(uint256)","626340b2":"block0()","626452df":"test_feePoolShare_noClaimableStake()","6266e135":"Gmt()","62674e93":"getStepFunctionData(address,uint256,uint256)","62676d78":"RANGEEND_8()","6267967b":"batchReservedTokenAllocation(address[],uint256[])","6267c456":"organizer7()","6268a0cd":"stakeSDC(address,address,uint256)","6268e921":"acceptGame()","6269420e":"seedAndPresaleTokenIssuedTotal()","62694b68":"lastSignedBlockNumber()","62695eae":"allowedTransfer(address)","62697f69":"getLLV_edit_17()","6269ae48":"tokenToContributor()","6269f9fc":"getGameId(string,string,uint16,uint64)","626a0e1c":"addSoundEffect(uint256,uint256[])","626a413a":"activateBounty(uint256,uint256)","626b1070":"beneficiaryDeposit(uint256)","626be567":"totalToken()","626c0a45":"stock(uint16,uint16,address,uint256)","626c6bc6":"ETO()","626d0358":"setTokenDefaultPartitions(bytes32[])","626d4a36":"right55(uint256)","626d666c":"theDao()","626e4675":"directorLockDays()","626e8fd3":"setBonusDate1(uint256)","626ebe39":"toggleReceiveEth()","626f9e20":"calculateMaxEthIssued()","626fc458":"finalizeTrade(address,uint256,address,uint256,uint256)","626fd353":"getSelection(uint256)","627045bf":"changeActiveNameIndexTo(uint256)","6270b780":"DebitClient(address)","62714a14":"getPhone(address)","62715547":"castVote(bytes32[])","62721129":"getMultiSigWallet()","6273106a":"payoutPool()","62731ff1":"onDeposit(address,address,uint256,uint256)","62735618":"finalizedCapital()","62738998":"getInt()","62744fee":"PallyCoin()","6274a35c":"team_total_lock_days()","6274ca4b":"setWeiPerUSDinTGE(uint256)","62751a06":"SFT_PER_ETH_FIRST_EARLY_BIRD_RATE()","6275448e":"batchApprove(address,uint32[])","62754563":"CelebsParty()","62765eb7":"receiveApproval(address,uint256,address,string)","6276b368":"rateOfCharging(address)","62770252":"needsFuneral(uint256)","62773951":"TrustReso(uint256[3],address,address,address[])","627749e6":"closeTime()","62779e15":"payFees()","62797ef5":"dayPotHighscore()","627992c7":"VULCAN_POD_MAX_CARGO()","627a326b":"getBytes32Slice(bytes,uint256)","627a3311":"QvoltaToken(address)","627aa6d2":"buyAndTransfer(address,address,bytes,uint8)","627adaa6":"revealMulti(uint256[],uint256[],uint256[],bool[],bytes32[])","627b3d9a":"BTCAUC()","627c2516":"WizardsvsCeltics()","627c2d1e":"getTX()","627c34ad":"removeSubscriber(address)","627c81ff":"erc20ContractByIndex(uint256,uint256)","627d6f9f":"get_multiple(uint256,uint256)","627e64d2":"getQuote(address,uint64)","627e667b":"StandardToken(address,uint256)","627eb56c":"setMaxContributionPhase1(uint256)","627f09c3":"setConfiguration(address)","627f22fe":"GiftMetadata(uint256)","627f47c6":"transferWithLock(address,uint256,uint256[])","627fd3bb":"addCbAddress(address,bytes1)","6280382a":"cancelTrade(address,uint256,address,uint256,uint256)","62806296":"transfer_coins(address,uint256)","6280b0bb":"batchRegularTransfer(bytes32[],bytes32[])","6283051f":"setOraclizeQuery(string)","6283440b":"wingsTokensReserv()","62838d8b":"getLastAddress(bytes32)","628392bd":"bonusPhase1()","62848f36":"tokenRate30()","6284ae41":"exitFee()","6284fd22":"getMyPubKey(bytes32)","62850233":"transferWithDividends(address,uint256)","6285a259":"calculateTokensEnabledOne(address,uint256)","6285d703":"NERO()","6288020f":"endThirdWeekICO()","6288a63c":"NotaryChain(uint256)","6288a9a3":"maxUserContribution()","62890063":"WhitePrivilegeToken()","62891b5d":"multiAccessChangeRequirement(uint256)","628a01ce":"stakingMintRate()","628b75bf":"slashDownRequest(uint256,address,uint256,bytes32)","628c225c":"roomNight(uint256)","628c2778":"DEXToken()","628c866e":"setCurrentActiveGameID(uint256)","628d5ef1":"setWeiUsdRate(uint256)","628da35e":"get_termAmount(uint256)","628dda8d":"VDGToken()","628e50b5":"brokerFee()","628e7a38":"_initializeVesting(address,uint256,bool)","628eaa88":"GeocashToken(uint256,uint256,uint256,address)","628ee84f":"in_dispute_phase()","6290a009":"bids_sorted_count()","62932301":"importer()","62935a98":"getContractDataSK()","6293a989":"TRONVSupply()","6293b5bb":"presaleMaxEtherCap()","6293fd1e":"payBack(address)","6294f858":"distributeFinancialAward(address[],uint256[])","6295c61a":"transferItem(address,address,uint256)","6297c16c":"deleteToken(uint256)","6297dbf4":"existsMesa(uint256)","62981b18":"deployBallot(bytes32,bytes32,bytes32,uint64[2],bool[2])","62985882":"VSTA(string,string,uint8,uint256)","62985b87":"NebuliToken()","62986e27":"Canary(address,uint16)","629873b2":"createRequestAsPayeeAction(address[],address[],int256[],address,address,string)","6298c93a":"usdCap()","6299a6ef":"update(int256)","6299f8cf":"stop(uint256)","629a9ce7":"coreTeamUnlockedAt()","629ad124":"chancesBought()","629aef56":"QuintToken(address)","629b656e":"PryzeToken()","629b9cb1":"takeProjectBonus(address,uint256)","629bc0b4":"getPlayerPayout(uint256)","629bf9a8":"updateMinMaxBetPrice(uint256,uint256)","629c1b67":"SoftCapReached()","629c37c2":"HSShopSaleFee()","629cefee":"adjustTiming(uint256,uint256)","629d0f2f":"teamd()","629d93db":"removePromo(bytes32)","629e89a0":"setMinDai(uint256)","629f1486":"YoonContract()","629f4028":"getVoteNum(address)","629f4b3b":"StatsTotal()","629fb53d":"getOrderbookLength()","62a09477":"changeOwner()","62a0b56b":"testUnset()","62a1029c":"YUPIE_PER_ETH_PRE_SALE()","62a144d9":"safeMod(uint256,uint256)","62a31c4a":"dynamicLength(bytes4,bytes)","62a36a54":"Application()","62a39ff7":"setShareHolder(address)","62a44fe9":"has_voted()","62a49ae3":"depositTokensFor(address,uint256,address)","62a4b230":"setLockedRatio(uint256)","62a4be31":"buyTokensByProxy(address)","62a4cd14":"endFunding(uint256)","62a51eee":"move(uint80,uint80)","62a52ed6":"set_price(bytes12,uint256)","62a59ade":"distributePuppyCoinCLarge(address[])","62a5af3b":"freeze()","62a76ce1":"accrueAdvisorsTokens(address,address,uint256)","62a7c5a6":"nextWithdrawDayFoundation()","62a80b42":"newToken(string,address)","62a87466":"STATE_DONATION_ROUND_1()","62a974b6":"vote01NoCount()","62aa9a00":"enehtoken()","62aabb9e":"SafeToken()","62aac84d":"setHaltSale(bool)","62aaf089":"getExchangeRate(uint256)","62ab1216":"updateWithOracle()","62ab8cc1":"howMany()","62abb560":"transferSuperOwnership(address)","62abda69":"totalIssuanceDebt()","62ac6115":"updateRequireKYC(bool)","62aca822":"setNation(address)","62ad1b83":"operatorSend(address,address,uint256,bytes,bytes)","62ad9bda":"newProvider(address,string,bytes32,uint256)","62addeed":"HumanX()","62ae4d29":"OBIMOLOGIA()","62aecc47":"totalBondSupply_BULL()","62aee544":"ADVISOR_SHARE()","62afd64a":"unpaidPercentage(bytes32)","62aff4d5":"commitPeriodStartedTimestamp(bytes32)","62b08e70":"setVotingContractAddress(address)","62b0ae87":"pack(bytes)","62b24189":"DepositToBankAccountFromDifferentAddress(uint32)","62b26f95":"totalFish()","62b3b833":"createCoupon(string)","62b40489":"businessPlannedPeriodEndTimestamp()","62b40918":"addPersonalCaps(address[],uint256)","62b40f9f":"destroy(address,address)","62b45318":"exchangeEtherForNominsAtRate(uint256)","62b4faa7":"Edujano(uint256,string,uint8,string)","62b52b49":"LADCToken()","62b6a282":"left42(uint256)","62b6a963":"_batch2_icosaleEndTimestamp()","62b6dc8e":"RektToken()","62b78bc4":"team_coins()","62b83c6b":"balanceAsCreator()","62b96a18":"teamUnvested()","62ba1649":"stopLottery(bool)","62ba4aef":"payInvoice(bytes32,uint256)","62ba9687":"toTimestamp(uint16,uint8,uint8,uint8,uint8)","62bb7533":"getTokenToEthOrderList()","62bb758f":"userSecurity(address)","62bc56e6":"getCompany(address)","62bc63c4":"getCozyAgain(uint256)","62bca778":"withdrawalFX(uint256)","62bd689c":"setBonusPercent(uint256)","62be3172":"Message(address,address,address,string)","62beaa82":"toData()","62bf6fa7":"medalDecimals()","62c01b2d":"apply_compensation(uint80)","62c06767":"sweep(address,address,uint256)","62c0e3b7":"SpoutMintableToken()","62c0ffa8":"getDCountedBasicBallotID(bytes32,uint256)","62c13ff3":"initSale(uint256,uint256)","62c19061":"getYearDay(uint256)","62c1adb0":"KittenCoin()","62c1f389":"swap(bytes32,address[5],uint256[6],uint8,bytes32,bytes32)","62c24067":"blockFunds(uint256)","62c2b7c8":"getTTTAddress(string)","62c335c1":"checkCallback(address,uint256,bytes,bytes)","62c375a7":"library15function()","62c3dd5a":"prepareForRefund()","62c3fdb2":"getFundsOwner(bytes32)","62c47064":"setArbitrator1and2(address,address)","62c48e20":"capFiatAndETH()","62c49256":"whitelistBasketFactory(address)","62c4c89e":"getMixParticipantByPubKey(uint256)","62c509c3":"XYTgas()","62c5aecc":"getEthToTokenAddOrderHint(uint128,uint128)","62c5c03a":"getbalance(uint256)","62c5c254":"changeFounderMultiSigAddress(address)","62c63e31":"NotFinalized(bytes32,bytes32)","62c655f5":"removeVoters(uint256[])","62c6beea":"_buy(uint256,address,uint256)","62c7855b":"getConfigBytes(bytes32)","62c7e96c":"deathData_f16()","62c7fa76":"lockStartTime()","62c95aa1":"getMaxTickets()","62c99e84":"_Approval(address,address,bytes32)","62c9da62":"setCompte_1(string)","62caf484":"GDCAcc03()","62cb1ac2":"validateOrderHash(bytes32,address,uint8,bytes32,bytes32)","62cdd872":"verifySignatures(uint8[],bytes32[],bytes32[],bytes32)","62ce071c":"publicTokenCap()","62ce7043":"reloadEarnings(uint256,uint256)","62cee7ad":"staffInfo()","62cf0197":"getVIATokens()","62cf54c8":"setDeposits(uint64,address,uint16,uint64)","62d020d9":"addVersion(address,string,string)","62d027bf":"GXVCSentByToken(uint256,address,uint256)","62d05c78":"cancelOffer()","62d0af7a":"set_BCDB_contract()","62d0ce45":"TOKEN_RATE_05_PERCENT_BONUS()","62d176cb":"buyTokens(bytes32,address)","62d1dac2":"setUnofficialApplicationSignUpFee(uint256)","62d1fee3":"addLegitDevAddress(address)","62d21602":"bkaddress()","62d246a4":"getBetsMas(uint32)","62d2c393":"GenkiProject()","62d2ecb9":"setMaxSpend(uint256)","62d3755b":"fullTokenWallet()","62d3b5c5":"maxAmmount()","62d55b6d":"VOTING_TIMESPAN()","62d576bd":"periodITO_mainCapInUSD()","62d590ac":"GrantToken(address,uint256,string)","62d5acb1":"rebateOneFenzi_()","62d6b7fb":"percentageOfRaisedAmountThatRemainsInContract()","62d7216c":"unregister(uint256,bytes)","62d72c08":"RozowkaCoin(uint256,string,string)","62d73eb8":"startElection()","62d91855":"delAdmin(address)","62d93527":"setBrokerFee(uint256)","62d966c9":"changeEmployee(address)","62d9c267":"ICOEnded()","62dbc55c":"DevTokensHolder(address,address,address)","62dbdfef":"CompanyToken()","62dbf261":"getTokensForEther(uint256)","62dc0133":"HIGHER_PRICE_RESET_PERCENTAGE()","62dc6e21":"PRESALE_PRICE()","62dc9ced":"Roulette(uint256)","62dd748c":"toUpper(string)","62dd9c71":"checkWinNobody(uint32)","62de871e":"startBattle(string)","62df5b7d":"BD0Token()","62e05175":"setMotionDB(address)","62e1de00":"test_polarBoardInstance()","62e23e9e":"NAME_NOT_AVAILABLE()","62e26e45":"loanCompleted(uint256,uint256)","62e28f7d":"channelModule(uint64)","62e2aa00":"burn(uint256,string,uint256)","62e2d0de":"get_foo()","62e4aeb8":"customExchange(address,address,uint256)","62e534d2":"setBlocklancerToken(address)","62e5b1f2":"_owns(address,address,uint256)","62e69886":"RecipientUpdated(address,address)","62e6e7c7":"disTrustDealer(address)","62e76013":"management(uint256)","62e7707e":"whitelistAddresses(address[],bool)","62e7ba3f":"consumptionPointer()","62e838ef":"returnBet()","62e881a4":"nextTournamentRound()","62e888bb":"STRIKE_PRICE()","62e8b948":"stepOneLockEndTime()","62e8e8ac":"changeTokenPrice(uint256,uint256)","62ea82db":"bids(address)","62eb0068":"redeemByPartition(bytes32,uint256,bytes)","62eb33e3":"cr()","62eb4c89":"is_started_payouts()","62eb5789":"setLLV_edit_33(string)","62eb6da1":"registeredToken()","62eba54c":"doesUserOwnItem(address,uint256)","62ebcdcf":"setRtmContract(address)","62ec8e53":"adminAddBallot(string,uint256,uint256)","62ed4f04":"SSBToken()","62ee0082":"setTokenContractsAddress(address)","62ee37aa":"InfluToken()","62ee4b26":"AUORANEX()","62ee6d29":"changeHashtoLowOrHigh(uint256)","62ee7b03":"startTakeToken()","62ee922b":"unofficialApplicationSignUpFee()","62ef0e65":"withdrawPresale(address[])","62ef1f81":"confirmPayment()","62ef7738":"total_money_back()","62f03290":"payRefund(bytes32,uint256)","62f2296e":"_transfer(address,address,uint256,string)","62f3ed92":"PowerQuantumCoin()","62f3febf":"isUserBlockedByContract(address)","62f44d8a":"Dadyys()","62f4ed90":"isAuthorized(bytes32)","62f54c18":"removeAllowedTokenInternal(address)","62f57ff6":"GudTesteContratoF()","62f5a23f":"transferToToken(address[])","62f5aa4c":"getAirdropIds()","62f5c2e3":"maxContributionPhase1()","62f5ed61":"add_to_bounty()","62f60954":"_reAdjustDifficulty()","62f63c6e":"EarthMedz()","62f69039":"unlockVault()","62f6cf7f":"getRegisteredModuleAt(uint256)","62f91eff":"AnythingAppToken()","62f927d4":"getDefaultReportingFeeDivisor()","62f96fc1":"splitBalanceAccordingToRatings(int256,int256,int256)","62fb09b2":"getRefDescr(uint256)","62fb0ff8":"morties_TO_HATCH_1RickAndMorty()","62fb6fe1":"getMonster(uint256)","62fb9697":"diffSeconds(uint256,uint256)","62fc178b":"gasPriceOraclize()","62fca3fa":"mintTokenBulk(address[],uint256[])","62fdaf1d":"removeFromBattle(uint64)","62fde48a":"LogDeposited(address,uint256)","62fe3b4d":"setEndOfPresale(uint256)","62fec51b":"icoEndTimestampStage2()","62feff3a":"developerAllocation()","62ffb195":"REFERRAL_REWARD_PERCENTAGE()","62ffb3bf":"trueUSD()","630061f3":"getTokensDistributeds()","6300c768":"takeEther(address,uint256)","63018e1a":"minTokensToSale()","63036f86":"totalIssuedEarlySale()","63037b0c":"payees(uint256)","6304335b":"betsCloseAt()","6304fa3a":"Test(uint256,string,uint8,string)","63052d82":"getOwnersIndex(address)","63055d79":"fetchRate()","6305d010":"registerTeam(string,address,string,bool)","63066434":"getPlayerVaults(uint256)","63069a35":"assign2(address,uint256)","63079315":"lengthOfCommonPrefix(bytes,bytes)","63086b5e":"afterSoftCapDuration()","6308769e":"LogFinishICO(address)","6308ae65":"managersCount()","6309242c":"setUserHatchRate()","630a9f94":"viewMemory(uint256)","630babac":"WhitelistParticipant(address)","630bae99":"payoutWithFee(uint256)","630bcd99":"drawRandomItem(string,uint256)","630c010e":"getElements(uint256[])","630cd1e9":"ratePrivateSaleStage()","630cea8e":"submitSignature(bytes,bytes)","630d0552":"ColorPurchased(address,address,uint256,uint256)","630d43cc":"DoroDiamond()","630db9ee":"getRemoveMarketCalled()","630dbe79":"StandardERC20Token(string,string,uint8)","630dc19d":"_payoutJackpot()","630dd52f":"TOKEN_TREASURY()","630e07f1":"RESERVED_TOKENS_FOR_ICO()","630e0ae6":"createPersonGen0(string,string,uint64,bool)","630eb125":"getAuditAssignBlockNumber(uint256)","630f1e6c":"withdrawAsset(bytes,uint256)","630f479e":"perStageNxc()","630f6f47":"betWithAff(address)","630fd0ac":"totalSupplied()","6310c722":"convert(address,uint256,uint256)","6310d902":"getAddressBoughtCount(uint16,address)","631121ca":"ISCToken()","63121665":"countPeriod(address,bytes5)","6313bd30":"DEP()","631407a2":"setTokenSupplierAddress(address)","6315592b":"orderModify(uint256,uint256,uint256)","63155d2b":"craft(uint16[16],uint16[16],uint16[16],uint16[16])","63157e2b":"issue(uint32,uint8,uint256,bool)","6316f6d1":"getNotConstant()","63175913":"StandardSale(bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","63176ad9":"changeDealDate(uint256,uint256)","6317cc5b":"tokenCapForThirdMainStage()","631859d0":"calculatePotentialPayout(uint256)","6319d32f":"DOJI()","631a4231":"createContract(string,string)","631a925c":"Weekycoin()","631b0520":"getPaimentTime(address,uint256)","631b3672":"roundSetUp()","631b7e83":"LogResult(bytes32,address,uint256,uint256,uint256,int256,bytes)","631bdb63":"playerCurrentlyRegistered(address)","631c07f0":"getBonusByDate()","631c42ae":"ethExchangeWallet()","631c56ef":"depth()","631ccb1d":"getInfoMarketItem(bytes16)","631d3f3b":"liveDragons()","631d551b":"FAMEToken()","631d9b1f":"LuxProject()","631dc853":"EquitySharingSystem()","631dd1a2":"transferFreeze(address,uint256)","631de4d6":"replace(address,address)","631e0c69":"addMessage(string,string)","631f0d66":"upgradeAddress()","631f637f":"preSaleMaxCapInWei()","631f9852":"isSealed()","6320212b":"refreshReputation(bytes32,address[])","63204648":"setMultiWallet(address)","6321f298":"MeraToken()","632261c3":"removeVendor(uint256)","63228b57":"KarmaToken(uint256,string,uint8,string)","6322bb39":"tradeEtherDelta(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,uint256)","6323b526":"transferFromTokenSell(address,address,uint256)","6323dc26":"GCRTokenERC20()","632447c9":"updateReward(address)","632473da":"CNC()","632488ff":"POOH()","6324af1f":"advisorsBalance()","6324e70b":"offerToLend(uint256,uint256,uint256)","63258462":"setHomeMaxPerTx(uint256)","63263858":"ethartArtReward()","6326cb5b":"_purchaseCompany(uint256)","6328af59":"YeedToken(uint256)","63299226":"teamOneId()","6329cfa5":"settleLend(bytes32[8],bytes,address,uint256,bytes,bytes,bytes,bytes)","632a3e52":"vestTokens(address,uint256)","632a8144":"midasFounderAddress()","632a9a52":"vote()","632ca5c9":"getArts()","632ccecd":"IkuraAssociation()","632ce0f8":"whoIsAdmin()","632e082a":"isMainFirstDay()","632e1dfe":"OWNER_ADDR()","632e2b95":"addWire(address,uint256,uint256)","632e44af":"distributeBonusTokensByList(address[])","632ebd6b":"changeIsOpenFlag(bool)","632f0ba6":"descriptionHashes(bytes)","632f83eb":"realWorldPlayerFromIndex(uint128)","632fbda4":"replaceController(address)","63301198":"AetherCore()","63302789":"TOKEN_FOUNDERS()","63304bc3":"m_lastFundsAmount()","6330ac09":"get_price(string)","6331e7d4":"beforeEach()","6331eae0":"saveTokenValues()","63334c58":"transferETC(address)","63340338":"fuint32(uint32)","633423be":"paymentAddress()","6335010d":"getVestingRevokeDate(address,address)","63365651":"InterfaceId_ERC721Enumerable()","63367f4d":"tagline()","6336ac19":"setTTGCoin(address)","63385ad1":"addNewAccount(address,uint256,uint256)","63385b64":"BerryToken()","633891c4":"getPlayerAff(uint256)","6338977e":"setMetadataUser(string)","6338f693":"Airdropped(address,address,uint256)","63391689":"withdrawForFourStep()","63392843":"decrease(bytes32)","63396109":"createGen0Token(address)","63397825":"changeMerchantAccount(address)","633982c5":"viewLatestEthTransactionRequest()","6339b5f6":"SUSIToken(uint256,string,string)","6339be39":"totalStarSupplyRemaining(uint8)","6339fbcb":"finishGame(uint32,bytes32)","633a6dde":"deathData_a9()","633a7574":"CowToken(address,address,uint256)","633ab5e0":"callchecked()","633b1954":"finalizeMigration(address)","633b4c04":"o_velho_problema(uint256,uint256)","633b5b1f":"presaleTotalWei()","633c78b5":"create(uint256[],uint256[])","633ce1d2":"premiumDomainK()","633d17eb":"toAscii()","633de6aa":"setTime2Rest(uint256,uint256)","633dfc70":"vote(bool,address)","633f7a82":"queryType()","6341b3fe":"subBrokerNum()","6341ca0b":"retrieveTokens(address,address)","634363f3":"amountOf()","63443679":"rateUpgrade(uint256)","6344a898":"setWeiRaiseLimit(uint256)","63453ae1":"distribute(address)","63456fa9":"getTokenById(uint8)","634663a5":"setPriceRatePhase2(uint256)","634667b2":"claimAndTransfer(address)","634710ae":"BYTC()","63472fad":"setVote(address,string,uint256,address,bool)","634758e5":"TodaNetwork()","6347a377":"nextAuction()","6347bb42":"SGACoin()","63482cf0":"eachUnlockCounts()","63488772":"WanersiLinkToken(uint256,string,string)","6348c4cf":"Money(address)","6348eae6":"neverPauseAgain()","634965da":"sendEther(uint256,address,address)","634993c6":"refill(bytes32)","6349cafa":"changePrice(uint16,uint256)","634b3df9":"minPriceInWeiForPre()","634b4a8f":"setOperater(address)","634b5043":"collectWinnings()","634b8dc3":"Altn()","634bc7db":"create(bytes32,bytes32)","634c5c51":"authorized_triggerStashedPayoutTransfer(uint256)","634c688a":"burnAllowed()","634d27c3":"getProviderIsForRent(uint256)","634d6e57":"investorFullInfo(address)","634df88e":"ENTA()","634e66ac":"admin_isWithdrawable(bool)","634eaff1":"ETERNAL_APPROVAL_VALUE()","634ec9f9":"buyKnowledge()","634ef3ce":"Mqthereum(uint256,string,string)","634ef8da":"_setSetting(string,uint256)","634f752b":"optionLibrary()","634fcb8e":"setupCrowdsale(address,bool)","634fe2a6":"others_prize()","63505ae8":"getBidsCount()","63506c16":"transferfromOwner(address,uint256)","6350b2c2":"mints(uint256)","6350ec6f":"changeYumAddress(address,address)","6351546d":"settleTransactionByMediatorFee(uint256,uint256)","635179ca":"setHiddenCeilings(bytes32[])","6352211e":"ownerOf(uint256)","6352585c":"ENCToken(uint256,string,uint8,string)","6352c538":"TokensWithdrawn(address,uint256)","63534dd8":"seedContract()","6353586b":"reward(address)","63542c26":"approvedToken(address,uint256,bytes)","635439ac":"updateCurrentGameCardId(uint256,uint256)","635550a6":"blockchainExchangeFrom(address,uint256,uint256,bytes32)","63558f5c":"transferEscrowship(address)","6355bf2f":"optionsSet()","635639b4":"_unpackPlayerData(uint256)","6356443e":"TokenPreSaleTransfer(address,address,uint256)","6356739d":"Sent(address,uint256,uint256)","63567673":"createBet(address,address,uint256,uint256,bytes32[])","63569ca8":"rewardProjectCompletion(uint256)","6356cdac":"Bonus(uint256)","6357cc12":"startpublicBattle(uint256,uint256)","6357ddaa":"getRandomTime(uint256)","63581c04":"setFactoryAsset(uint256,uint16)","63586d6a":"claimBondReward()","635875d9":"changeMinimumCommission(uint256,uint256)","6358aac0":"isInterestStatusUpdated()","6359036b":"redeemDaoBounty(bytes32,address)","63591d09":"poolMaxAmount()","635994fd":"create(address,bytes32,address,bytes32,address,bytes32)","6359a656":"EUnpause(address,string)","6359a974":"TOTAL_TOKENS_TO_DISTRIBUTE()","6359b5b1":"totalIssuingCollateral_limitedSum()","635a5d7b":"setHeartbeatTimeout(uint256)","635b9047":"ExpandCoin()","635ba8a1":"ApexTalk()","635ca669":"addBoardOnUser(address,address)","635cfda2":"Incrementer()","635d0239":"toUint(bytes,uint8,uint8)","635da243":"autorizar(address)","635e2abf":"_btcToken(address)","635eecea":"privateEventTokens()","635f6a79":"method3(string)","6360edc1":"getAllForPubKeyBetween(bytes32,uint256,uint256)","6360fc3f":"bought_tokens()","63615149":"withdraw(bytes32,bytes32)","63617328":"setJackpotCompleted()","6361d3e0":"unpauseActivity(uint16)","6361d9e9":"testConstructorUsingDeployedContract()","6362102d":"rebalanceEtherDelta(address,uint256)","63621532":"setGasUpperBound(uint256)","6362ffd3":"rebuyInformTime(address)","63637c87":"createNewPlayer(string)","636544be":"changeVeredictum(address)","63655ebb":"DiaryLog(uint256,bytes)","63657855":"_removeFromDebtRegister(bytes4,uint256)","6365dfd9":"RaisrToken()","63665f2e":"addAirdrop(address,uint256)","63669424":"EthBird()","6366b936":"freeUpTo(uint256)","63670e42":"UpdateSellAgentSiteReg(address,address)","636760a2":"Cyncrohnis()","636822fa":"FearOfMissingOut()","63689b4a":"moveTokens(address)","636a36e3":"ThingsbookChain()","636ae15d":"BROYALCOIN()","636b2ac3":"createDefaultGen0LinglongCat(uint256,address,uint256,uint256)","636b7e56":"pendingFunding()","636bb5ae":"CalculateStageValue()","636bd9dc":"cooAddress3()","636c6524":"Superpack()","636ca6c2":"EAAS()","636ce4d7":"BTL_SPARTAN()","636d37b1":"precrowdsalepricing(address,uint256)","636d98b1":"referrerPercent()","636f12fe":"b2sother(bytes32,bytes32)","636f6159":"tokenExchange()","636fa3c6":"preIcoToken()","636ff44e":"BAGToken()","63704e93":"getDocCount()","6370920e":"grant(address,uint256)","6370ef19":"updateDomainPrice(bytes32,uint256)","63722de4":"AllowSomeoneToViewMyKeys(address,string)","63723373":"checkSignature(address,uint8,bytes32,bytes32,bytes32)","63727449":"getMfgDetails(string)","6372ba1a":"dateEndICO()","63732cf0":"RCN()","63735598":"getPriceOfCampaign(bytes32)","6373786a":"SaturnPresale(address,address,uint256)","637431ae":"testCreatePricelevelUsingNewContract()","63746113":"resetCrowdSaleAddress(address)","63746b03":"createContractRide(string,bytes7)","63749225":"getPVPEntranceFee(uint256)","63750dfb":"changeLedger(address)","63755c16":"withdrawStandardTokens(address)","637666ce":"removeFromBlackList(string,address)","6376c910":"StageThreeEnable()","63772f33":"growthTokensPercent()","6377aaa6":"setAdsContractAddress(address)","6377ebca":"close_time()","6377ff20":"totalInactive()","6378378a":"NxahCoin()","63784191":"frozenForTeam()","63791e3c":"setPriceSetter(address)","63798661":"payPlace(uint256)","6379a852":"multiOperatorSend(address,address[],uint256[],bytes,bytes)","6379ed9d":"distributeFUD(address[],uint256,uint256)","637af51c":"updateUpdater(address)","637b2541":"_allocateTokens(address,uint256)","637b55eb":"exchangeEtherToToken()","637b93ed":"getInsuranceBalance(address)","637bcd2a":"userIsWhitelisted(address)","637c39d8":"systemAddresses(address,address)","637cc5c6":"XBlockToken()","637d3e00":"ProjectOwner_EnableProject(int256)","637dda3f":"getBalanceByIndex(uint256,address)","637e12f7":"getBlocksDesc(uint256,uint256)","637e86eb":"totBOTs()","637ea3e5":"setlogaddr(address)","637ec389":"activated_time_()","637fcf95":"getBoardMember(address)","63808773":"acceptContribution(bytes32)","63809953":"secondsPerDay()","6381ca26":"refundTransactionByMediator(uint256)","63820550":"OwnerEvents(address,uint8)","63822fdc":"addConsentTemplate(string,uint256,string,string,string)","6382789d":"currentLowestCount()","63839777":"getReturns(address,address)","63844a57":"mul32(uint32,uint32)","638560cf":"registerBool(address,bool)","6385cbbe":"minimalGoal()","6385f2fb":"DAZ()","63860139":"nextPrizePool()","63862fd5":"isSenderOriginalOwner()","6386c1c7":"getUserInfo(address)","63875261":"paladinAddress()","6388fafa":"niceguy1()","63891019":"testFailStartTooEarly()","63892068":"create(string,string,bool)","6389654e":"changeDailyWithdrawalLimit(uint256)","63897c7e":"changeSettings(string,string,uint256,uint256,address,address,address,address,uint256)","6389e019":"graceTransfer(address,uint256)","638a9ce9":"setProxy(address,bytes32)","638b1b14":"developmentAddress()","638b4463":"completeClosed()","638b9119":"soldCards()","638bcce3":"multilevel(uint256)","638c5ddc":"BonusListUpdated(address,address)","638d4788":"draw(uint8,uint8)","638dd56a":"getNumberOfEligibleMembers()","638e1e5d":"payTip()","638e3724":"Locker(address,uint256,address[],uint256[])","638eea8d":"PLATFORM_MONTHLY()","638f6575":"timeStarted()","638f8da4":"castleMaxLevelGap()","638fade2":"getMerchantPublicKey()","63905232":"balanceAll(address[])","63907180":"getDebrisNum(bytes32)","6390f519":"getNumTeams(uint16,uint8)","6391c315":"FundsWithdrawnAndTokenStareted(address)","6391d3b2":"getCountSenderLands(address)","63921a74":"canReceiveListing(bytes32,uint256,bool,address,uint256,uint256)","63929d3e":"getPendingKNCRateRange()","6392a51f":"balancesOf(address)","63937651":"batchTransferDiff(address[],uint256[])","6393b4eb":"expect(address,uint256,bytes,bytes32)","6394536d":"cosign(uint256,uint256)","639475ca":"TRIANGLE()","63958b5f":"sellSpecialTokensForPublicSale(address,uint256)","63981b33":"changedeposito(address)","63981bbc":"TotalSpenders()","63991a36":"getGenomeChildren(uint32,uint32)","639937d7":"maxSpinners()","639a9a67":"saleOpened()","639ab80b":"YTTD()","639bbb37":"donated()","639bd0bf":"proposeBountyTransfer(address,uint256)","639bef41":"setRecommender(address,address)","639cba6e":"getDetailsBattles(uint256)","639cd59c":"totalFeesAvailable(bytes4)","639d3e69":"listSubName(bytes32,bytes32,uint256,uint256,uint256)","639d57f2":"testGetBitSuccess()","639e01dd":"Team()","639ec4d2":"checkTokDev()","63a0557b":"teamAvailable(address)","63a0607b":"buyRock(uint256)","63a10042":"approveComponents()","63a1512e":"setOPM(address)","63a167f2":"collectorWeiCap()","63a24174":"GxCoinTotals(address)","63a2c393":"safeMulPercentage(uint256,uint256)","63a2de29":"crearJuegos()","63a2fdbf":"claimZeronium(uint64,uint64,uint64,uint64,uint64,uint64)","63a37503":"test_rewardPoolShare_noClaimableStake()","63a3c452":"getUnsold()","63a3cc80":"currentTotalTokenOffering()","63a3d383":"edoToken_()","63a411c0":"addDriver(address)","63a4b67b":"setArray(bytes32,uint256[])","63a599a4":"emergencyStop()","63a5bc71":"eitherAdminOrAdvisorCanDoThis()","63a6568f":"getPropertyLastUpdaterBecomePublic(uint16)","63a66d59":"bountyDeposit()","63a6cc7d":"getBuyers(uint16,uint8)","63a846f8":"admin(address)","63a8b945":"removeCounter(address,uint32)","63a8dac2":"changeSettings(uint256,uint256,uint256,uint8,uint256,uint256,uint8,uint8)","63a999cc":"uddr()","63a9c3d7":"verify(address)","63aa109c":"summFounders3()","63aa289b":"ownerTreesIds(address,uint256)","63ab7a25":"clearWaitPairBets()","63aba603":"AlphaToken(string,string)","63abc381":"alreadyParticipated(address)","63abfbaa":"tokensToFunds(uint256)","63abfd86":"CCChainToken()","63ac0f99":"depositBonus(address,uint256)","63ad0bbe":"templateProposals(address,uint256)","63ad803f":"EditTile(uint256,uint256,string,string,string,uint256)","63ae10fe":"getClientProviderUID(address)","63ae2bae":"updateUserCertification(string,string,string,string,uint16)","63ae71ca":"affiliateProgramWalletAddress()","63ae8d6c":"setBuyPrice(uint256)","63aea3e0":"PlayerInfo(uint256)","63aec5ce":"getActiveUserLists()","63af8570":"tokensToGenerate(uint256)","63b03896":"gcd(int256,int256)","63b0545f":"transferfrom(address,address,uint256)","63b0a5c3":"IdentityRegistry()","63b0e66a":"helper()","63b1152a":"releaseVault()","63b1806f":"NewReferralTransfer(address,address,uint256)","63b20117":"totalTokensSold()","63b2c2a9":"unlockTeamBBT(uint256,string)","63b3c007":"canDefrost()","63b3f4e6":"WinnerPayedTicketBought(address,address)","63b452fb":"ICO_RATE4()","63b45bd9":"socoreCheck()","63b4f786":"about(address,uint256)","63b56431":"PRCT100_ETH_OP()","63b57e34":"remainCap()","63b6240d":"computeEndowment(uint256,uint256,uint256,uint256,uint256)","63b68040":"lastBlock_v14Hash_uint256()","63b6b31f":"transferBalance(address)","63b700ff":"getStoryExpiryTime(bytes12)","63b75b59":"setAssetValue(uint64)","63b7f00a":"calculatePercentsFor(address)","63b80379":"AcceptDiscipleOffer(uint256)","63b82524":"ethReceivedPresaleTwo()","63b851b9":"updateMinimumEpochInterval(uint256)","63b87bb8":"openSale(uint256,uint256,uint256,uint256)","63b8bd44":"getBalanceofEthAgent()","63b8f7f7":"W4T()","63ba26fa":"QwasderToken()","63ba2c76":"toUintThrow()","63ba5e44":"fundem()","63ba7319":"BUILDING_PRICE()","63bafb96":"Log1(address,bytes32,uint256,string,string,uint256,bytes1,uint256,uint256)","63bb51a9":"setHash(address,bytes32,address,bytes32,uint256,uint256)","63bbe1b5":"transferAuthorizations()","63bce4e7":"softCapUsd()","63bd1d4a":"payout()","63be8fc8":"createNew(address)","63beeab1":"executeConstant()","63bf15c2":"_buildTimberCamp(address,uint256,bytes)","63bf8194":"mineFor(address,address,uint8,bytes32,bytes32)","63bf81cf":"createDiscipleSale(uint256,uint256,uint256,uint256,uint256)","63bf8d6a":"removeToken(uint8)","63bfe3d8":"SkillBeatsLuck()","63bfe52a":"addAddressToCraneList(address[])","63c05650":"addAddress(address,uint256)","63c06fe9":"mintForwarder(uint256,bytes32,address[],int256)","63c194f1":"NTFoundationAddr_()","63c1b753":"getAddressIndex(uint256)","63c281a1":"hitFoundationBalance()","63c3600b":"__stringToUint(string)","63c36549":"QueueIsEmpty()","63c37984":"thirdExchangeRatePeriod()","63c3e2e3":"clearTransferValue(uint256)","63c43415":"view60()","63c439a6":"secondCrowdSaleDate()","63c454ca":"ifFreeze(address)","63c4f031":"stop(bytes32)","63c6082f":"buyWithCustomerIdWithChecksum(uint128,bytes1)","63c65056":"TradeEthShop(uint256)","63c69f08":"getUserOrders(address)","63c6fe04":"addCities(bytes32[],uint256[],uint256[])","63c78e87":"withdrawEtherFromTrade(uint256)","63c7d473":"GoldAmountMelted()","63c988f9":"isAlive(uint8[176],uint8)","63ca7aaf":"FeeUpdated(address,address,uint256,uint256)","63cb2afb":"reserve1Address()","63cb344e":"setNctEthExchangeRate(uint256)","63cbab8c":"SELLER_STEP_1_OPEN()","63cc23ae":"Lesson_4(address,uint256)","63cc4aa2":"transferRemainingTokens()","63ccedfe":"MensariiCoin()","63cd1c51":"_createLottery()","63cd1da7":"dspcoin()","63cd44c9":"GetType(bytes32)","63cd99cb":"moo()","63cdcc57":"motionConfirming(uint256)","63cea450":"closePresale()","63ceb60d":"sponsor(uint256,address)","63cf1442":"JACK_DIST()","63cf2ef3":"limitLessThan(uint256,uint256)","63cf6ffa":"sellFish(uint16,uint16,uint8,address,uint256)","63d06dd4":"createContractPow(string,uint256,uint256)","63d08ae5":"Timebankc(uint256,string,string)","63d1055c":"proposeGame(string,string,uint256,bytes)","63d177e6":"unpauseICO()","63d17806":"operatingFund()","63d1e70e":"PHXroll()","63d256ce":"revoked()","63d29135":"SetEventData(uint256,string,string)","63d292d7":"STQCrowdsale(address[],address,address,address)","63d2be9d":"ratingOf(uint16)","63d36c0b":"calculateFinalPrice(uint8,uint8,uint256,uint256,uint256,uint256)","63d494ea":"becomeVoter()","63d4d4a9":"bonusRateInPercent0()","63d5243a":"getDaysPassedSinceLastTeamFundsBallot()","63d5502f":"presaleCap()","63d578c5":"ApolloSeptemTokenSpecialPurchase(address,address,uint256)","63d60745":"transferCreditsInternally(string,uint256,uint8,string)","63d64159":"max(uint8,uint8)","63d6519a":"CPCEPrivate()","63d6727a":"setStartStage3(uint256)","63d74226":"add_bounty()","63d7edb9":"VRCOIN_DECIMALS()","63d8c5b7":"RefundVaultWithCommission(address,address)","63d91851":"PUBLIC_CROWDSALE_CAP()","63d9b4b1":"sendGift(address,uint256)","63d9b770":"exploit()","63d9df85":"presaleContract()","63da5531":"tokenPerUsdNumerator()","63da9cf8":"signAttribute(uint256,uint256)","63db30e8":"minInvestedAmount()","63db3e63":"IPST()","63dc5400":"queryCurrentContractFunds()","63dcf376":"offChainPurchase(address,uint256,uint256)","63dcfa9e":"athleteAlreadyClaimed()","63ddbb99":"WBToken()","63ddc54d":"mmLib()","63de5323":"applicants(uint256)","63de6ad6":"purchaseCard(uint64)","63de882b":"wlStopBlock()","63deb2c5":"changeMemberAddress(address)","63def590":"untrustClient(address)","63df9769":"setReached(bool)","63e0c2f8":"whitelistAccount(address)","63e0f8c3":"StanleyNickels()","63e0f8c7":"referalBonus()","63e12cdc":"addCCUser(bytes32)","63e16fff":"nextGen()","63e1d57c":"getMaxSize()","63e27a63":"unlockTeamTokens(address)","63e2c349":"transferTokenAndLock(address,uint256)","63e321fe":"setDefaultHashes(uint8,uint8)","63e33e96":"totalSupplyUnits()","63e38ff3":"id_for_nym(uint256)","63e3fbbd":"StopQuiz()","63e49fcd":"startPtopDeposit(address,address,bytes32,uint256,uint256)","63e4bff4":"giveTo(address)","63e4e5cc":"bountyPercentage()","63e561b6":"checkOrder(uint32[])","63e60df5":"GolemNetworkToken(address,address,uint256,uint256)","63e79315":"TokenERC20(uint256,string,string,uint256)","63e8dd96":"getCurrentOwners()","63e94cee":"getStage0End()","63e95a3c":"isNegligable(uint256,uint256)","63ea0143":"setTotalDeposit(uint256,address,uint256,address)","63ea6e44":"NewKing(address,uint256)","63eaa14d":"relock(address,uint256,uint256,int256)","63eac2d4":"getMyFalcon()","63eb963a":"dat()","63ebb3cf":"isValidSubmitter(address,bytes32)","63ebd4ff":"getFunctionAuthorized(address,address,string,bytes32)","63ebf801":"ChelleToken()","63ec3eb5":"WHENToken(string,string,address,address,address)","63ec96b7":"LogVictory(uint256,uint8)","63ed6d5d":"LogWhitelistRemove(address)","63eda29d":"prevSeriesSelloutHours()","63ee7c8d":"totalEscrows()","63ee8b88":"ico2Sold()","63eeb79a":"setMinEsteemAmount(uint256)","63eed1d7":"Alice(address)","63ef8d9e":"resetLotto()","63f019f6":"canBurnSecurity(address,uint256)","63f07aa4":"preSaleTokens(uint256,uint256)","63f0ae2e":"ProfitDelivered(address,uint256)","63f0ca5a":"BOUNTY_TOKENS()","63f114f2":"checkWithdrawValueForAddress(address,uint256)","63f160e6":"sentReveal(uint256,address)","63f1a089":"_mint(uint256,uint256,uint256)","63f1a9dc":"LogInvestorMigrated(address,uint256,uint256,uint256)","63f1de17":"ICONSORT()","63f225a7":"addLOCtoLHT(address,address)","63f22c24":"checkDelegation(address)","63f2493f":"settleETHBatch(address[],int256[],uint256,uint256)","63f32f63":"Price(uint256)","63f3dbe5":"VESTING_CLIFF()","63f55fc0":"setHolderGroup(address,uint256)","63f5679e":"changeDragonsStatsContract(address)","63f6100d":"buySome(uint256,uint256,uint256,uint256)","63f6271f":"LEGLToken()","63f75343":"setF2mAddress(address,address)","63f80de3":"issueCoin(address,uint256,uint256)","63f8a211":"sellOneStep(uint256,uint256,address)","63f9cb0e":"HLWCOIN()","63fa32f1":"newWinner(uint256,uint256,address,uint256)","63fa9888":"PredatexDua()","63fb5a1a":"putBuyOrder(address,uint256,uint256,uint256)","63fbc7bc":"expectPayment(bytes8,bytes32)","63fc98e3":"judgeEnableForTransfer(address,uint256)","63fcabcb":"BilancioMinimoAccount(uint256)","63fcf5de":"addtoContributos2(address,address,uint256,uint256)","63fd420c":"payoutMining(uint256)","63fd7552":"owedAt(uint256)","63fd7eb0":"chickenOf(address)","63fd91dc":"signUpForTournament(uint256[])","63fd9e38":"minInvest()","63fdca37":"HitCash()","63feeaaf":"smartContractStartDate()","63ff195d":"stakeOnBehalf(address,uint256,bytes32,uint256,uint256,uint256)","63ff6125":"donateToFeePool(uint256)","64004ea5":"getUserTotalPromoBonus(address)","640075f3":"isPositionClosed(bytes32)","64009184":"threeHotHoursEnd()","64017ea7":"submitExit(uint64,address,uint256,address,uint256)","640191e2":"channelManagerAddresses()","64020842":"isDisavowed()","640241b8":"acceptOnwership()","64027fbb":"minbet()","6402aca9":"getAllCardAddressesPriceOfOwner(address)","6402efd3":"tier2Rate()","64030441":"addCardsHash(uint256,string)","6403a9ed":"getVoteCountForOption(uint8)","6404865e":"OneOhana()","6406605b":"MetadataUpdated(uint256,address,string)","640708d6":"PRIORITY_SALE_START()","64070b6f":"p_setNextRoundSeedPercent(uint256,uint256)","6407e432":"mintTokens(uint256,address,address)","640853bb":"amountSoldPerPeriod()","640959bc":"getQuoters()","6409a4e3":"giveTokens(address,uint256,string)","640a404a":"getgamecardpos(uint256)","640a4d0c":"_deposited(address,address,uint256)","640bdd70":"setDividendFee(uint256)","640c3dbd":"isChipPassword(uint256,string)","640d3017":"SetMinSum(uint256)","640d84b5":"SetApplicant(uint32[],uint64[],uint32[],uint64[],int256,uint64[])","640ec47a":"assertTrue(bool,bytes32)","640efb0d":"setTravelPrice(uint256)","640f244b":"findSuitableGen()","640fe1e9":"availableForWithdraw(address)","64100038":"deleteUserClaim(address)","64109848":"tokemon20()","64109ae0":"MAINT_PRICE()","6410c41a":"priviledgedAddressBurnUnsoldCoins()","6411273f":"tapFab()","6412aeb1":"setBountyTokens(uint256)","641579a6":"setMultiplier(uint256)","641620a2":"createMulti(uint256,uint256)","6416ec30":"Geet()","64179c1b":"ActivatedContract(uint256)","6417c08b":"implementsERC721d()","6417dec3":"setHSShopSaleFee(uint256)","6418345e":"updateMinimumInvestment(uint256)","6418b903":"transferRewardPool()","6418f643":"ClaimBlessings()","641a5f66":"getSendCoin()","641a8cb3":"MANHATTANPROXYBRDWY()","641ad8a9":"poolState()","641b58c2":"checkBet(uint256[],uint256[],uint256[],uint256,uint256)","641bbdfe":"claim(uint256,uint8,bytes32,bytes32,uint8)","641ca23f":"availableICO()","641d55e0":"buyClixToken()","641d6075":"getDailyWinners()","641e3f15":"notifyTokenIssued(uint256,uint256,uint256)","641e6b9d":"TestingEnabled()","641e8cca":"updateGameProprietaryData(uint256,string)","641e90de":"price5()","641f3b46":"isTokenExchange()","641f83a1":"calcEnvHash(bytes32)","6420e71c":"rateForPhase1()","64217bdf":"requestInterest(uint256,uint256)","6421fc04":"LockedMANA(uint256)","642231a6":"legendsCrowdfund()","6422816b":"betBLenght()","64228857":"getRevisionCount(bytes32)","642289f2":"MarketEnabled(address,address,address)","6423690f":"SmartDice()","64239cce":"purchaseUpAndSpend(uint256,uint256,bytes32)","6423b5f0":"miniMeToken()","6423db34":"Reset()","6423dbad":"getGreeter()","64245502":"STRegistrar()","6424bd8c":"Remove()","6424d686":"getEngineerCurrentVirus(address)","64253d2f":"HashnodeTest()","64256611":"collectedFunds()","6425fbed":"getJobStatus(bytes16,address,address,uint256,uint256)","64265b1a":"share_transfered(string)","6428366a":"payToGorgona()","6428925d":"toSTAR(uint256)","6428a652":"setPornstarsContractAddress(address,address)","6428fed4":"pendingJackpotForWinner()","6429161b":"createSaiLimitedEdition(uint256,address)","642ab4b1":"lastBidTime()","642b1759":"getMerkleLeave(uint256)","642b4a4d":"mainNetLaunchIncentiveReserveWallet()","642bdd15":"calculateNewPrice()","642c53e2":"GetData(bytes32,string,bytes32)","642c7aa2":"snatchHero(uint256)","642d345c":"byMaximum(bytes32,uint256)","642d63a3":"buyLottery(uint8)","642dfe55":"Bitmos(uint256,string,uint8,string)","642e8271":"NigeriavsArgentina()","642f1ddc":"nome_candidato_da_indice(uint256)","642f2eaf":"transactions(bytes32)","642f722c":"createRecord()","642f825a":"randomPetAuraBoost(uint64,uint8)","642fd0f6":"getPixelColour(uint256)","64308a6a":"_getPartSkillColor(bytes,uint256,uint256)","643124cf":"INZEI()","64319ae6":"updateUserEmail(address,string)","64322c9c":"drawingIdToCollectibles(uint256)","64325ddb":"currentClaimPrice()","6432679f":"getUserCapInWei(address)","64326c71":"getTotalGas()","64329400":"setHardParticipationCap(uint256)","6432dc4e":"sell_ppc()","6432e3cd":"CaDataContract()","6432e9e0":"calculatePayrollRunway()","6433ef42":"adjustWithdrawRate(uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32)","64341c0c":"getIPFSCode(bytes32)","643537aa":"getBFEX(address)","64362587":"SetRevealBlock(bytes32,uint32)","6436434e":"getAddressDnaIds(address)","6436b1b9":"getSpawningForCount(address)","64370755":"removeDistributionSources(address[])","64371977":"set(uint256,string)","64379150":"setNumberClaimToken(uint256)","6437ab0b":"checkCommitPeriod(bytes32)","64385828":"setDataColla_AB_01(string,string)","6438c43e":"getCurrentSchellingRound()","6438f449":"noviceDungeonId()","64392a80":"balanceOfOwnerInVault(address,address)","6439437e":"cloneIt()","643a7695":"verifyParticipant(address)","643ac0bd":"_unregisterAttack(bytes32)","643aff0f":"investorWallet()","643b18b6":"teamWallet_1()","643c6d1f":"PureChainToken()","643ce525":"teamLimit()","643d1be5":"setMainSaleStart(uint256)","643d6dc0":"getInfos()","643d71a2":"KODB(address)","643e1aa5":"SetStartTimeTLP2(uint256)","643e7365":"initialSaleContract()","643e77d8":"calculateProfit(uint8,uint256,uint256)","643f7cdd":"DAOpaidOut(address)","643f9b72":"SherolexToken()","643fcd27":"addieren(uint256,uint256)","64422ede":"createPoolsIfNeeded()","64422f3c":"multiDeltaBalances(address[],address,address[])","64425055":"returnedDataDecoded()","644280e2":"tokensForBounty()","6442af8d":"_totalRemaining()","644443ed":"addContractRole(bytes32,string)","64445d9e":"adminEditBallotOption(uint32,uint32,string)","6444a288":"setMinTokenForSP(uint256)","6446169b":"sellStar(uint256,uint256)","64461a55":"Synergy(address)","6446a339":"addAddressToPublicBuyerList(address)","6446afde":"getMappingElement(uint256)","6446ebd8":"deleteResources(address,address[],bytes4[])","644843f3":"LogNote(bytes4,address,bytes32,bytes32,uint256,bytes)","6448adc6":"tierLevel()","6448b46f":"pushCap(uint256)","6448b6cb":"closeVaultAccess()","644998ae":"maintain(int256,uint256,uint256)","644a3d42":"ANKR()","644a803d":"BlockTogether(address,uint256,uint256,uint256)","644a9db8":"sign(uint256,address,uint256)","644b1d1a":"CompetitionCompliance(address)","644b7a43":"getTokenByIndex(uint256)","644b7dc6":"_isOperatorFor(address,address)","644cf307":"preSaleBonus2Percent()","644d8164":"getDesc()","644d8cce":"burnMas(address[],uint256[],uint256)","644e4e4e":"LogVotes(uint8,uint256)","644e8b24":"getPrices(uint256,uint256,uint256[],uint256)","644fab74":"setTimeLock(address,uint256)","64506302":"okamiCurrentPurchase_()","6451447d":"buyoutFeePercentage()","6451ab58":"activeuser()","6452a10f":"emergencybeneficiary()","6452f344":"sayGoodbye()","6453558e":"founderTokenWithdrawnPhase3()","6455058e":"getStakedAudits(address)","6455780c":"getImportingParty()","6455cb97":"EPTest()","64561370":"oraclize_query(uint256,string,bytes[5],uint256)","6456d071":"addPatientReply(address,string,string,address)","64571245":"withdrawATN(address)","6457237b":"indexOf(uint256[],uint256)","64584b14":"executeOrders(address[],bool[],uint256[],uint256[],address[],address[],address[8][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[],uint256)","64584d16":"CardFootballers()","6458de1e":"ensOwnerPx()","6459361d":"setDetail(string)","6459a8dc":"PerseiToken()","645a8570":"teamAndAdvisorsAllocation()","645ac00b":"transferSignership(address)","645b8b1b":"status(address)","645bcd3a":"checkBasketExists(address)","645bd436":"clearDelegateAndUnlockTokens()","645c4625":"get_orderAddress(address,address,uint256,uint256,uint256)","645c6fae":"registerContract(bytes32,address)","645c9931":"SHPToken()","645c9ac8":"returnMixType()","645cd046":"bundleToken(uint256)","645d95d4":"LogBidAccepted(uint256,address,uint256,bytes32,uint256,bytes32)","645dbfd4":"updateRandom()","645dce72":"updateRelease(uint32,uint32,uint32,bytes20,bool)","645dfad7":"sellATR(uint256)","645e175c":"publicGetNote(uint64,bytes2)","645e6ddc":"bookingBalanceOf(address)","645f0d11":"toggleFactoryPower()","645f754a":"OZTToken()","6460c353":"PoWMiB()","64610c73":"ADA(uint256,string,string)","646156aa":"cancelTournament()","6461ed00":"TOTAL_TOKENS_SUPPLY()","6461fe39":"transferFromWithReference(address,address,uint256,string)","64631be6":"signatureOf(uint256,uint256)","6463d6bc":"getMaxBidder(uint256)","646439a3":"tradeStream()","64648589":"fundICO()","6464b107":"TRIUM(uint256,string,string)","6465d25a":"Aliencoin()","64663ea6":"withdrawAndSend(address,uint256)","646668b6":"getMaxBet()","64669d1b":"BadBitchCoin()","6466cfa1":"changeSellFee(uint256)","64679356":"Controller()","64679806":"last_number()","6468328e":"executeTransfer(address,uint256,bytes)","6468c099":"addAnimalType(uint128)","6469c348":"maintain()","6469c89b":"getNiceBets(uint256)","6469e87f":"isKickoffEnabled()","646cd69b":"postponeDueDate(uint256,uint256)","646cf24d":"assignTokenContract(address)","646d4f53":"PlayX100()","646d525a":"NetCents()","646d978b":"getKudosById(uint256)","646e90e7":"getAddBal()","646eba48":"releaseTokens(bool)","646f22c5":"getTicketsLeft()","646f2942":"CryptoJade()","646f7834":"lockCountingFromTime()","646fe5ee":"OwnershipTransferConfirmed(address,address)","646fec02":"ProposalAdded(uint256,address,uint256,string)","6470db2f":"removeAllowed(address)","647151b5":"sellUnicorn(uint256,uint256)","647308ee":"verifyWithdrawSignatures(bytes32,address,address,uint256,bytes,bytes)","64738c23":"makeOrder(address,address,address,uint256,uint256)","6473b34a":"batchAllocate(address[],uint256[])","6474dd4c":"LuckyWorldCupToken()","6475e3d3":"MIN_BET_AMOUNT()","6475e47d":"DGT_contract()","647734b2":"setValidationAddress(address)","64779ad7":"pausedOwnerAdmin()","647846a5":"feeToken()","64794403":"setAddressOfERC20Tocken(address,address)","647aac0c":"race(uint32)","647b5ced":"pubsaleCap()","647b6065":"tokenIdToOwnerArrayIndex(uint256)","647d02d2":"closeFail()","647d5f14":"dividendinfo()","647dd08c":"callSender(address,address,address,uint256,bytes,bytes)","647e61f1":"setLargeInvestorApproval(address,uint256)","647f7058":"Commitment()","64801da1":"reliefRatio()","64802918":"div(uint16,uint16)","6480d014":"preicostarted()","64812751":"finaliseState()","6481f081":"sellVouchers(uint256)","64821338":"hasVoted()","648236e3":"acceptBidForSketch(uint256,uint256)","64826b7a":"publicSaleCap()","6482c535":"rateOfParking(address)","64832c4c":"heatUp(address,uint256)","648345c8":"setMessage(uint256,string)","648351b9":"MarbellaCoin(uint256,string,uint8,string)","64836227":"notifyWatcher()","6483a330":"getPeriodInDispute(uint256)","6483ec25":"append(bytes32)","6484ae80":"_addCharacters(address,uint8)","648583b4":"updateCandidate(address,bytes32,string)","6485cc52":"GBP_Omnidollar()","6485d678":"setActive(bytes32,bool)","6485e2e5":"_removeController(address)","64861329":"DiamondProjectToken()","648619dc":"serviceUnpause()","648621ec":"xnotify(string)","64864ca6":"Expand(address)","64868f97":"roundTokenLeft(uint256)","6486aa51":"isConfirmed(bytes32)","64887334":"setCompactData(bytes14[],bytes14[],uint256,uint256[])","6488c20e":"TransferableChanged(bool)","64893fcb":"totalVestedAmount()","648a0c91":"updateExchange(address)","648a5903":"isShortPositionExpired()","648aa3b1":"getComponentByName(string)","648ad97f":"setMain(uint256,uint256,uint256,uint256,uint256)","648b3514":"CheckpointToken(string,string,uint256)","648b7ce8":"Increment()","648bf774":"recover(address,address)","648c51eb":"isMyPlanet(uint256)","648c925e":"backToAll(uint32)","648d6367":"DocumentaryContract()","648d7219":"setOCG(address)","648d9e26":"startPublicIco(address)","648e49e6":"dSET_XBL_ADDRESS(address)","648e625a":"confirmTransaction(uint256,address,uint256)","648f0bde":"Play(string)","648f4f0f":"tokenStoreAddress()","648fb06f":"mintMultiple(address[],uint256)","648fd473":"EBRK()","6490c7a8":"getArea(uint256)","64913477":"setMultisigWallet(address)","64916fcf":"WhitelistedCounterUpdated(uint256,uint256)","6491f0b7":"setLLV_edit_6(string)","64921844":"getTimePassed()","64928d24":"wasSaleEnded()","649371e0":"oracleCurrentInt()","649375da":"addEarned(uint256)","6493d7fc":"CircuitBreaker(address,address,uint256,uint256)","6493e64c":"upgradeTo(string)","6494b55b":"ceoAddCoo(address)","6494cde1":"endTransfer()","6494d477":"saltHash()","649564b3":"getOtherContractParticipant(address,uint256,address)","649677e1":"entranceFee()","64968f58":"set_presale_iconiq_arbits_per_ether(uint256)","6497129c":"getRoundNumber(uint256)","64976b4d":"setNplay(address)","64978c7f":"jembex()","6497b400":"_getFashionParam(uint256)","6497bd3a":"newPriceTicker(string)","6497d32e":"setCCH_edit_18(string)","6498156e":"preICOBuy()","64994978":"setFounder()","64996a43":"_computeCycleSkip()","6499e2d9":"ERC777DemoToken(string,string,uint256)","649ae9c6":"lockDate()","649c07d5":"is_contract(address)","649c0b21":"addressOfMSF()","649d56db":"getContractProps()","649e3c46":"createDoc(string,string,string,string)","649eea7f":"_transferCar(address,uint256,bool)","649efd6e":"mintForEverybody()","649f0153":"fiatBalance()","64a04d07":"ReconOwned()","64a08260":"adminRemoveRole(uint256,address,uint256)","64a20e2d":"getImpactDonor(string,uint256)","64a237f4":"VEGANToken()","64a31b80":"getRequiredReportsPerReporterForlimitedReporterMarkets()","64a41399":"contributeInCreditsToken()","64a48499":"getIntegerValue()","64a4a5d7":"testBitsEqualSuccess()","64a5a632":"getCompanyByName(bytes32)","64a640ef":"Bosscoin()","64a666f2":"getAuthorizedInsertAgents()","64a68943":"dividentSent(uint256,address,uint256)","64a7cc4b":"purchase(uint128)","64a7d7c7":"bidAuction(uint256)","64a80c0c":"openStream(address,uint256)","64a83d8b":"_removeTokenFromTranche(address,bytes32,uint256)","64aabe92":"tryExec(address,bytes,uint256)","64ab23c9":"finalizeChangeStakingFees()","64ab374b":"getUnreadMessagesArrayContent(uint256)","64ab4702":"voteWeightUnit(uint256)","64aba263":"setInternalInfo(address,uint256,uint256,uint256,uint256)","64ac12b1":"multisig(address[],uint256)","64ac2c4a":"WavesPresale()","64acdb77":"disablePurchasing()","64acef7d":"newBP(bool,address,uint256,uint256,string,string)","64ad6027":"updateOrderNumber3(uint256)","64adc403":"getUserRewardPayouts(address,address)","64ae4451":"stateIs(uint8)","64aea551":"randnum()","64afab72":"remove(address,bytes32)","64afcf2e":"minSecondsBetweenPublishing()","64b09402":"setMetadataProvider(address)","64b13270":"registerDeed(string,string)","64b2eb2c":"publicOfferingExchangeRate()","64b3302d":"safeMult(uint256,uint256)","64b3b844":"getSaleInfo(uint256)","64b494d9":"setValInt(uint256)","64b4e6eb":"payRef(address,uint256)","64b55e8b":"SULTANT()","64b7571f":"distributeDividends(address,uint256)","64b7f1d3":"Rules()","64b837ab":"stopBlockjack()","64b9ca08":"noAdvert()","64bc6a74":"AllPartnersSet(uint256)","64bc82c3":"delegateAddresses(uint256)","64bd3066":"dispute(address,bool)","64bd7013":"wait()","64bd87d6":"scheduleCall(address,bytes,bytes,uint256,uint256)","64be8453":"NewUserAdded(address,address)","64beb745":"lockOwnership(uint256)","64bebead":"_FreeDom()","64bfc9a5":"stopBountyMint()","64c176eb":"setSmartToken(address)","64c2555d":"buyDay(uint16,uint256,string)","64c27f2a":"isOwnerOrOps(address,address)","64c2b768":"powered_up()","64c33c33":"setPrice(uint16,uint16,uint8,address,uint256)","64c34364":"hodl(uint256,uint256,uint256)","64c37043":"buyRareItem(address,uint256,uint256)","64c403d4":"getETHx2(uint256)","64c40bbc":"DCoin()","64c422d0":"participantToUBObought(address)","64c487ef":"isStoppingIcoOnHardCap()","64c638d5":"withdrawTokenToClientAccount(bytes32,bytes32,address,uint256)","64c66395":"getUIntValue(uint256)","64c76117":"endDistribution()","64c7b3bf":"Journal(uint256)","64c7b78c":"addOrg(string,string,string,string,string,string)","64c877f1":"depositLiquidateThePool(uint256)","64c88d62":"calcDemurrage(uint256)","64c8cd8c":"unlockMinedBalances(uint256)","64c8e825":"PooCoin()","64c96322":"setAllocationOpen(uint256)","64c96572":"TokenLMTC(uint256,string,uint8,string)","64ca6478":"createImage(uint256[],uint256,uint256,bytes32[],string,string,string)","64cab0e3":"setCurrentPrizePool(bytes4)","64caf214":"setPlayerDetectGroup(address,address,uint8,uint32)","64cb5338":"FundedAmount(uint256)","64cbbd34":"WalletChanged(address,address)","64cbbdc7":"addDividendsForAddress(address,address)","64cbfdd6":"p_update_planetCryptoUtilsAddress(address)","64cc7327":"retrieve(string)","64cc7719":"getUserDataOnEther(uint256)","64ccd7a0":"getAutomatedReporterDisputeBondToken()","64cd1f69":"requestInvestment(uint256,uint256,bool)","64cd4a1a":"round4TokensRemaning()","64ce1068":"lockExpiration()","64ceed99":"foundersTimelock()","64cefc90":"fliqToken()","64cf6d71":"toBytes1(bytes,bytes,uint256)","64cf9167":"Numisma()","64d03095":"getSpecificTransaction(address,uint256,uint256)","64d03144":"Plaak(uint256)","64d05519":"createLastWill(address,string,string,string)","64d0bbc4":"increaseGenerationCount(uint256,uint8)","64d0d64c":"testControlCreateWithParentNotInUse()","64d0e83b":"jackpotWinCount()","64d12ec6":"getRevisionIpfsHash(bytes20,uint256)","64d17c08":"setServiceTokenAddress(address)","64d34045":"setCCH_edit_20(string)","64d3e7c9":"ReserveToken(string,string)","64d40354":"limitAmount(uint256,uint256)","64d4702f":"getNextKeyPrice(uint256)","64d4c819":"TYPE_HASH()","64d538d3":"StartIco()","64d563f1":"doubleClaimSegmentSlash(uint256,uint256,uint256,uint256)","64d57a03":"GainTempStuff(address,uint32,uint256)","64d582c0":"incentiveDistributionInterval()","64d5922f":"pingBlock()","64d5d024":"isValidBox(uint8,uint8,uint16)","64d6a95f":"changeGameParameters(uint256,uint256)","64d75891":"XXXXXXXX03(uint256)","64d79f20":"internalRegisterCertWithID(bytes32,bytes,bytes32,uint256,bytes32)","64d85348":"deleteOffer(address,address)","64d905c0":"awaitingParticipants()","64d98bd3":"ownerTransferJackpotToken(address,uint256)","64d98f6e":"isSolved()","64d9a9e9":"AirDropToken(string,string,uint8,bytes32,uint256)","64da8ad3":"settleSeller(address,uint256)","64dab033":"landmarkPriceStepDenominator()","64dab283":"getWHGDonationAddress()","64dad32f":"isTokenUser(address)","64db5aa8":"ARDBatchTransfer()","64dc68b8":"ILove0xBTC(string)","64dc807a":"burnUndistributedTokens(uint256)","64dd891a":"attack(uint256)","64ddc605":"lockupAccounts(address[],uint256[])","64dde40f":"isTournament()","64ddedc6":"Triangle(uint256)","64ddfa29":"getAdminAddresses()","64de4c1d":"setTatAddress(address,address)","64df049e":"protocolFeeRecipient()","64df19da":"removeCustomTimeLock(string)","64dfe85e":"Dsteem()","64e08644":"stakeRemainingToVote_Eth()","64e0bbc5":"checkMyTransactions()","64e19bdd":"ownerAirdrop(address,uint256)","64e1f38b":"howManyKeysCanBuy(uint256)","64e21c9e":"DirectFundingProcessed()","64e24f4b":"UpdateClientTokenAccount(address)","64e28148":"clear(address,uint256,uint256)","64e28636":"getLateFee(address)","64e2ec50":"collectOtherTokens(address)","64e2fdfa":"ToukenToken()","64e31d74":"RaffleLedger(string,uint256)","64e36d04":"hardCapInEther()","64e39b87":"setFundsWallet(address)","64e40eb9":"withdrawTokens(address,address,address,address)","64e4596e":"_getPVPContendersCut(uint256)","64e48fcd":"testResetBet()","64e48fde":"findPossibleDelegatorsOfRaw(bytes32)","64e4a8fb":"xaurCoined()","64e50fb9":"setIco()","64e593c0":"setStartTimeIco(uint256)","64e5c8be":"getRoundPrizeShare()","64e62afc":"setSegmentOwner(string,uint32,uint32,string,string)","64e749ff":"getPosition(bytes12)","64e779b1":"unmint(uint256)","64e7e4a4":"transferNotification(address,uint256,uint256)","64e8687f":"withdrawTalao(uint256)","64e8d682":"pre_startdate()","64eaa454":"crowdsaleAmountLeft()","64eaff54":"getSquirrelmasterReq()","64eb7327":"_getContent(bytes32)","64ebd70d":"the365address()","64ec8bdb":"creatorWithdraw()","64ed31fe":"authVotes(address)","64eda74b":"setIsFrozen(bool)","64eded20":"_getTokenAmountWithBonus(uint256)","64edfbf0":"purchase()","64ee49fe":"scheduleCall(address,uint256,bytes4,uint256,uint256,uint8)","64ef212e":"proxyTransferWithReference(address,uint256,bytes32,string)","64ef563c":"reveal_registration(uint256,address,address)","64f018d8":"issue(address,uint256,string,string)","64f05fd7":"calculateWithdrawableAmount()","64f06b39":"setPC(uint256)","64f101f0":"closeMint()","64f15430":"fundVesting(address,uint256)","64f1873b":"ICOstarttime()","64f39b47":"return_funds()","64f40a3c":"RESERVED_TOKENS_FUTURE_OPERATIONS()","64f42a99":"addUser(address,bytes32)","64f4b094":"getLowestBid(uint8)","64f54a17":"getLatestItemRaffleInfo()","64f65cc0":"setFinished()","64f67f33":"DIPToken()","64f6f7b9":"setup(address,uint256,uint256)","64f8ad1f":"get_default_approval_duration()","64f951e9":"sessionBlockSize()","64fa3070":"getEscrowFee(address)","64faf22c":"left18(uint256)","64fb7d68":"coinMinter(uint256,uint256)","64fc2d9d":"_tryCreateEtherMonster(uint256,uint256)","64fe5cde":"MAX_UINT48()","64ffb47b":"getTotalMicroKeys()","65011760":"DOCToken()","650271d2":"makeMove(uint8)","65030adb":"RESERVED_TOKENS_ICO()","65030e75":"setSecretContract(address,uint256)","6503178a":"setMinVeriAmount(uint32)","65033845":"XiaoshiToken()","65036ca9":"zethrBuyIn()","6503a701":"InitiatePayout(address,string,string)","6503e5ff":"mFUNDING_BONUS()","65045a2b":"bottomName()","650462ab":"tokensMasterNodes()","650500c1":"whatIsTheMeaningOfLife()","65050e27":"checkCandy(address)","65054e55":"claimSellerFunds(address,address,address,uint256)","65058f4c":"requestPayout()","65061957":"EMPTY_RESOURCE_SET_ID()","65066810":"WHITELIST_SALE_LIMIT()","650669d2":"getCompte_1()","6506b0d6":"setData(string,string,string,string,string,string)","6506b623":"rotateBitsLeft(bytes,uint256)","65084b76":"OpenRegistryRules(address)","6508978b":"updateLatestSaleState()","65089dd8":"freezeStatsSumHours(uint256)","65093661":"newCommunity(address)","650944a6":"beneficiaryStash(address)","650955d4":"HashToken()","65098bb3":"calculateCrossConnectorReturn(uint256,uint32,uint256,uint32,uint256)","6509c195":"setPartnerPool(uint256,uint256)","6509e776":"CC()","650b147d":"paidToPartners()","650c2b28":"tokensPerDollar()","650c4226":"changeFees(uint256,uint256,uint256,uint256)","650ce14c":"registerPublisher(address,bytes32[5])","650d0aa3":"ChangeFee(uint16)","650d22e8":"countryTimeLock()","650d5d6b":"get_status(uint256)","650d993b":"getCustomer()","650dd4fb":"_createCountry(string,uint256)","650e1505":"createLock(address,uint256,uint256)","650e85af":"setUserRoles(address,uint256)","650ee1ee":"NewSale(uint256,address,uint256)","651006c0":"getCreateMarketDenominationTokenValue()","6510076f":"giveTokensOne(address,uint256)","65103f6e":"hasFees()","651044a2":"BitcoinpalletToken()","6510cc17":"INITIAL_mulFactor()","6510ef4d":"oraclize_query(uint256,string,string[5])","65113528":"getBoosterType(uint256)","65114459":"getOpenPackageId()","6511a98b":"testRegisterProduct()","6511eadb":"marketingProfitAddress()","65121205":"calculateDevCut(uint256)","65121f68":"add1Y(address,uint256)","6512c9b5":"OwnersProductCommissionChanged(uint256)","65131f63":"getMembersOfTier(uint256)","65132ad3":"Police_3()","651398e6":"allocateTokenForAdvisor(address,uint256)","6513fafe":"resistWhiteList(address)","65141c20":"setRemixCount(uint256,uint256)","65147784":"Pasband()","65149a76":"calculateWinnings(bytes32,address)","6514aaca":"minimumCommission()","65153632":"assertEq11(bytes11,bytes11,bytes32)","65158b3b":"contributor(uint256)","6515c1fa":"defineMecenas(address)","6515c6a9":"paused2()","6515d28c":"getLockingTypeCount()","6516395a":"lockCustomer(address)","651680af":"stage5Deadline()","651738a3":"setMinScaled(int8)","6517ef33":"getNumberOfOrders(uint256)","65181ad3":"GET_METADATA()","6518361e":"SCT(uint256,string,uint8,string)","651883c1":"batchSpawnAssetWithCreator(address[],uint256[],uint256[],uint256[],address[])","6518ad22":"placeETHBid(uint8)","65195bc7":"DPNPlusToken()","6519fac2":"userExisted(address)","651bb617":"tokenlength()","651bc2fb":"reserveNIMFAAddress()","651bfd2d":"itemPrice(address,uint256,uint256)","651c2ff9":"preTge()","651c5c84":"TokenWalletHolder()","651c5d2d":"getGiver()","651c9e99":"GOGRN()","651cd08d":"validateStart(address,address)","651dd0de":"values(bytes12)","651ed944":"startPreICOStage()","651f066a":"playerBalance()","6520715a":"approveClaim(bytes32,string)","6520768d":"modName(string)","652084c0":"storeKey()","6520ca0d":"levelUpMining(uint256)","6520fde5":"auctionPaused()","652106d8":"tokenTribe(uint256)","65213840":"prizeMoney()","652139e2":"setAngelFinishDate(uint256)","65216a41":"airDrop(address[],uint256[])","6521c03c":"createContribution(address,uint256)","65225665":"getPlayerAddress(uint256)","65227c7d":"RenCap()","65228934":"setOperationsCallGas(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","6522bff1":"update(uint256,string,string,string)","65243f87":"findNextWeekday(uint256,bytes2)","6524f107":"BlobStore()","6525a233":"ORACLIZE_COMMISSION()","6525c29d":"rejectAdvertiserCharges()","6526db7a":"remove(uint256,uint256)","6526ecee":"KingOfTheEthill()","652740a7":"TransparencyRelayer(address)","6528ef46":"BBY(uint256,string,string)","6528f4cb":"getDivRate(uint256)","652918bc":"updateProfit(uint256)","6529abba":"setSellComission(uint256)","6529d1c9":"pricesOfDate(uint256,uint256,uint256[],uint256)","652b51eb":"RefundEnabled(uint256)","652b810c":"setInternalStakingAddress(address)","652ca8f4":"cofoundersSupplyDistributed()","652d38fc":"getTotalIn(address)","652da5ff":"b(bool)","652dad7b":"batchDecreaseApproval(address[],uint256[])","652db9ab":"_distribute(address,uint256)","652de5ad":"countPerfManagers()","652ebb4c":"tokenPriceInETH()","652edd41":"purchaseDatesEdition(uint256)","652f1f16":"addSignature(string)","652f6494":"treasuryOfficials(uint256)","652f78cc":"allocateCommunityToken(address[],uint256[])","6530b7f9":"_createDrink(string,address,uint256)","6530e008":"STAGE2_TIME_END()","6531041b":"updateMIN_CONTRIBUTION(uint256)","6531a708":"getHolderEditions(address)","6531dbff":"totalFundedEther()","65325871":"transferableTokensOf(address)","6532b646":"SFI()","65343fcb":"TrustEth()","6534b4e2":"IsPayoutReady__InfoFunction(bytes32)","6534eb76":"recycling(uint256)","653704b1":"_changeName(string,uint256)","65372147":"result()","65375f38":"updateCustomerKYC(address,address,address)","6537e401":"setIII_S(uint256)","653853c0":"AMLToken()","6539335a":"toTipoEnte(uint8)","65395242":"MathisTestToken()","65397d5e":"refundOIDIndex_()","653a8f14":"getNumTilesFromBoard(uint16)","653abf37":"setDecision(bytes32,address,address)","653c3174":"investorsNumber()","653c95b8":"getContribution(address,uint256)","653c968a":"Bethopia(address,address)","653c9eea":"isBS(address)","653cfd2f":"testTemp4()","653d1ca4":"getPI_edit_21()","653e2e0d":"setLastPositions()","653f23f8":"registerJuryMember(string,address)","653f7219":"AddVerifiedInfo(bytes32)","653fbca1":"payableEtherReceived()","653fcf4c":"pewdiepie()","65401882":"setDB(address)","6540742f":"MIN_BET()","6540dc07":"_destroyImpl()","6540fcc2":"PRICE_PRESALE_WEEK1()","654142c7":"getBoolField2()","65419516":"bettingStart()","654259dd":"availableAmount(address)","654286d1":"changeFrozenBalanceAll(uint8)","6542fed7":"evaluateShareholders(address,address)","65433e7f":"AntFundRobotToken()","654470fc":"getTotalSellingItem()","65449436":"CryptoConseilSuisse()","65450a90":"ACEBlock()","6545bed3":"Dice(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","65472731":"lastBlock_a5()","6547c080":"Renmin(uint256,string,uint8,string)","65483f69":"getBNTBalance(address)","65488541":"Harimid(uint256)","6548b40d":"depositErc20(address,uint256)","6548e9bc":"setRelayer(address)","65497caf":"limitDateSale()","654a1855":"CentToken(uint256,string,uint8,string)","654a95f2":"calculateEggSell(uint256,address)","654a9f69":"CappedCrowdsale(uint256,uint256,uint256,uint256,address)","654af496":"callDividend(address)","654b3110":"allowIssua()","654b6105":"DestiNeedToken()","654c2111":"Cash311()","654c6daf":"totalTeams()","654c7381":"listItem(uint256,uint256,address,bytes32)","654c8748":"setBitSTD(address,address)","654cf88c":"store(bytes32)","654d146a":"costAndBuyTokens(uint256,uint256)","654e27f9":"callBtoWithSto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","654e51e7":"setRewards(uint256,uint256)","654f18b1":"DragonPriceUpdated()","654f1ccb":"getGamesLength()","654f4575":"getTopN(uint256)","654f4b61":"bidHash()","654f7d40":"ETHERRED()","654f97a3":"setClaimStatus(bool)","655012a9":"sumPrice()","655042ee":"OSCoinToken()","655059db":"create(bytes32,bytes32[])","655187b2":"Aragon()","6551fb11":"localsStore(address,address)","65521111":"isAble(address,uint8)","6552a562":"updModule(string)","6552d8b4":"removeReceiver(address)","655330f4":"NLog(uint256)","65536ab3":"BFEXToken()","655388be":"walkTowardsBlock()","65538c73":"fireEventLog0()","65538da0":"preSaleOpened()","655391c9":"updateBaseTokenURI(string)","6553b03c":"cloneContractor(address,uint256)","65540940":"partnerAllocateRestrictedTokenTo(bytes32,bytes32,uint256)","6554d179":"attachedSystemActive()","65550e70":"getNextAvailableCard()","6555394b":"updatePrice(address,bytes32[],uint256[],uint256)","655584d6":"ChangeDate(uint32)","6556f767":"getBytes(address,bytes32)","6557a47c":"Tier_Wildcat()","6557b677":"lowTokensToSellGoal()","6557dfc8":"AnimeToken()","65581793":"S2()","6558488a":"scheduleSetBool(address,uint256,bool)","6559aeb2":"transferTimelocked(address,uint256)","6559c08d":"checkProblemsSolved()","655a4ebf":"revokeAttribute(address,address,bytes32,bytes)","655b08eb":"getRandom(uint256,uint256)","655b3667":"TOKEN_SUPPLY_AIRDROP_LIMIT()","655b97db":"ownershipLookup(address,uint256)","655bb0e8":"transferSubcontractsOwnership(address)","655bb565":"changeGasPrice(uint256)","655c737c":"getPositionOwedToken(bytes32)","655cc366":"LogGoalReached(address,uint256)","655d0862":"createSignedMessageOracle(bytes32,uint8,bytes32,bytes32)","655d225f":"myTime()","655d65c4":"limitSell(uint256)","655dc4c2":"getLawyerCount()","655e0d38":"changeBroker(address)","655e4224":"addEntryInSecondsPeriods(address,uint256,bool,uint256,uint256)","655e51f2":"MIN_GOAL_EBC()","655ec3e4":"transferSoul(address,address)","655f8294":"PreviousTime()","655fc4db":"vault_releaseDeposit()","655fcaf5":"feeReceiverWallet()","65604a11":"VESTING_WALLET()","6560a307":"suggestedGas()","656104f5":"_setOrganiser(address)","6561e6ba":"feeWithdraw()","6561e921":"becomeRenown(bytes32)","6561ffb9":"LOTTECHAIN()","65620283":"transferTokens(address[],uint256[])","65622cfd":"transferFor(address)","65630493":"ERC20Impl(address,address,address,address)","656362b5":"regFactory()","6563b2fc":"tokensLeftInPhase(int8)","6564a7af":"DeployENS()","6564ad28":"IFNToken(address,address,uint256,string,uint8,string)","65651b6e":"addSkillName(address,bytes32,address)","65670adc":"teamSupply18Months()","65675074":"getAllTokensOfUser(address)","65676c9e":"baseExchangeRate()","65679536":"month24Unlock()","65687008":"fundraiserAddress()","65688182":"recomputeLastAverageBalance(address)","65688cc9":"newGuard()","6568a279":"withdrawAll(address[])","656afdee":"register(string,bytes32)","656b275c":"expandY()","656b9952":"produce()","656ca11d":"CONFIG_FEES_MUL()","656d2f63":"ManagedAccount(address)","656d3091":"createEthSaleAuction(uint256,uint256)","656d677e":"releaseTotal()","656e8d6f":"getTutorialBabyGen(uint16)","656ea1f6":"snikerts()","656f416d":"uponTransferFrom(address,address,address,uint256)","656f64f5":"pendingGDPOracle()","656f6873":"ActualizePriceBeforeStart(uint256,uint256,uint256,uint256)","65704506":"currentGame(address)","657128a2":"altTokenOf(address,address)","657157e5":"canTrade(address,address)","657206ef":"getSignedAddresses()","6572ab5b":"shareCycleIndex()","6572ae13":"calculateWinner(uint256,uint256)","6573ee1e":"doFailingApprove()","6574bdd2":"newDream(address,string,string)","65757eeb":"removeDiscounts(uint256[])","65766b64":"stageBegin()","6577ab77":"_checkSeal(address,address,address,uint256)","65781994":"SESAPACToken()","65783c66":"checkTicket(uint32)","6578d920":"_canSendGameGift()","65791e46":"setTimeTransferAllowance(uint256)","65794de3":"secondStageDuration()","657a2ffa":"Register(uint8,string)","657a37ad":"depositAndSell(address,address,uint256)","657ad078":"moveOwner(uint256[3],uint256[4],uint8[176],bytes32,bytes32,uint8)","657ad479":"presalePerEth()","657ba57b":"show_The_name_of_option_C()","657c5dae":"ApproveTitle(uint256)","657d38b8":"endICOp3()","657db38d":"ten_wallet()","657edc11":"removeLootbox(address)","657f3ab0":"getPricePoint(uint256)","657f4783":"getRealGoldBought()","658030b3":"tokenInstance()","65826666":"executePullPayment(address,string)","658268c1":"StableCurrencyToken(uint256,string,string,uint256)","658311ab":"jackpotLevel()","658389cb":"isFromCountry(address,address,uint256)","6583e239":"STATUS_DEAL_APPROVE()","6584a5b5":"removeLock(address[])","6584ceb0":"StartNewEpoch()","6584fcce":"ATCReserveLocker()","658523d9":"StrategicToken()","65855010":"rateSale()","658577e9":"buyXid()","65857a5e":"parkingOn(address,uint256)","65859862":"add_arbits(address,address,uint256)","6585c27c":"getrandoms()","6585dc12":"enableRefundPeriod()","658612e9":"gasFee()","65862330":"TestableStandardCampaign(string,uint256,uint256,address,address)","65863b24":"getTotalCollectedPromoBonus()","6586bb25":"MAXIMUM_PARTICIPATION_AMOUNT()","6586bd51":"getNodalblockSender(string)","65879e72":"JED()","6587ab3d":"toggleSafetyMode()","6588875e":"ShutterToken()","6588c11c":"_startSwap()","658a5692":"_totalEthCollected()","658b98a9":"pointMultiplier()","658bc083":"initDistribution(address,address,uint256)","658bf147":"setArea(uint256,bytes32)","658c55ed":"saleProceedsFiat(uint256)","658cc376":"getCensuringCount(uint16)","658d3423":"getGameMinAmountByBet(uint256)","658dc76f":"addChunk4ToWhiteList()","658df3f7":"approveCompletedMilestone(uint256)","658e587f":"getWithdrawConfirmationCount(uint256)","658eefd1":"notifyRefundToken(uint256,address)","658f2ad6":"CrowdSale_Resume()","658fbfbc":"transferOnError(address,uint256)","659010e7":"m_spentToday()","65909081":"Brothel(address)","6590f0ed":"DUKCoin()","65921f02":"paladinEquity()","65926a20":"changeSaleOn(uint256)","6593643c":"CreateIND(address,uint256)","65937ab9":"isUpdateAuthorized(address,uint256)","659382fb":"payoutETH()","6594479f":"LTYP()","6594d99b":"isDataNo(bytes)","6594ea6c":"EGGS_TO_HATCH_1SQUIRREL()","65957bf5":"getShareToken(uint256)","6595c94e":"calculateTierBonus()","6596217b":"HAYATO_FTL_SPEED()","659621b5":"r0()","65968727":"innocoinToken()","6596cff3":"setCrowdsaleContract(address)","65975691":"getDividends(uint256,uint256)","6597a076":"getBonuses()","6598afb9":"yearlyBlockCount()","65995733":"getSalaryTokenValue(address,address,address)","65995cc8":"uploadAdvertisement(uint256,string,address,uint256)","659a46e8":"coinLockRmoveMultiple(address[])","659a7486":"inTradingTime()","659a9cbc":"coinsUnit(uint256)","659ae215":"saleDateFinish()","659b586e":"readQuantityList(address,uint256,uint256)","659b9c72":"UsersNumber()","659bd174":"TransferredTimelockedTokens(address,address,uint256)","659d1185":"angelTimeLock()","659d20eb":"getFoundersGames(address)","659d6bd1":"readPower()","659d7aaa":"sendEtherManually(address,uint256)","659de63b":"distributeToken(address[],uint256[])","659e0729":"getFirstAmount(bytes32,bytes32)","659e27b0":"setWhitelistingAddress(address,address)","659e69e9":"setDelegateAdmin(address,address,string,bool)","659eeabc":"tokensWithAmount()","659eeef1":"increasePaymentsBalance(address,uint256)","659f9e3c":"lastEpochBlockHeight()","659fb968":"getOracleOutcomes(bytes32[],address[])","65a096dc":"changeWithdrawableRound(uint256)","65a114f1":"resetTime()","65a178c0":"getTlength01()","65a20ef9":"hasRole(uint256,address,uint256)","65a31545":"doDeposit(address,uint256)","65a3d8f0":"setEtherCentPrice(uint256)","65a4c957":"resultsDelay()","65a4dfb3":"oraclize_query(uint256,string,string,string,uint256)","65a572dc":"EGREngravedToken()","65a5e708":"Upgraded(uint256)","65a5f1cd":"changeFoundation(address)","65a61ab4":"RWSC()","65a6bb29":"getAllOracles()","65a707bf":"DrugDealer()","65a7dcec":"addWinners()","65a8a483":"setColdWallet2(address)","65a91d4a":"createAmountFromTmedForAddress(uint256,address)","65aa96bd":"postJobOffer(uint256,address,uint256,uint256,uint256)","65aade1a":"getEmployeeId(address)","65ababe9":"createERC20Token(string,uint8,string,uint256)","65ac0d8b":"Withdrawl(address,uint256)","65ac2320":"ownerName()","65ac4341":"getTotalAmount()","65ac8c2a":"getSellOrdersInfo()","65ad9f34":"setHardCap(uint256,uint256)","65ae247e":"issueLockedTokensCustom(uint256,uint64)","65aebe7b":"ind(address,address)","65aec658":"_createCitizen(uint16,uint16,uint8,bytes32,bytes32,bytes32)","65af2a7d":"investedDDT(address)","65afa594":"Member_GetMyTokens()","65b040c8":"setPriceWithBonus(uint256)","65b051b8":"MEWSToken()","65b06136":"makePayouts()","65b0bc85":"createNameAndPoint(bytes32,address)","65b0d711":"updateApprovalOfToken(address[],bool)","65b0e5b3":"setethrate(uint256)","65b1c987":"resetBurntTokens()","65b1fdf4":"scheduleIssuePOIs()","65b27205":"testFailMintWhenStopped()","65b2a863":"revoke(string)","65b37d70":"HotManChain(uint256,string,uint8,string)","65b3a7ca":"isGameExpired(uint256)","65b686b0":"burnRemainTokenOffering()","65b6cd66":"setUserTransactions(string)","65b6d9e2":"a(uint256,string)","65b70e45":"UpMineLVL(uint256)","65b7a89d":"DeDeContract(address,address,address,uint256,uint256,address,address,uint256)","65b7b357":"getVotersAnswer()","65b892a1":"withdrawForOneStep()","65b980ab":"performTransaction(address,bytes32)","65b9e37d":"hardParticipationCap()","65ba12b8":"percentWeiJackpot()","65ba331b":"IcoStagePeriod(uint256)","65ba36c1":"interfaceHash(string)","65baf5db":"tier2Start()","65bb193e":"createInsurance(string,address)","65bbb26a":"Linamyd()","65bc35fa":"Streem(uint256,string,string,uint8)","65bcaf4a":"Ubiou(uint256,string,string)","65bcfbe7":"payouts(address)","65bdadf6":"ninthTime()","65bf1ffc":"authorizedStartTrading()","65bfdb0b":"_receiveChild(address,uint256,address,uint256)","65c04faf":"random(uint32,uint256)","65c09830":"changeStatusGame(uint8)","65c0eecf":"BitcoinLiza()","65c13fdb":"changeGasPriceLimit(uint256)","65c19af0":"getStringLength(string)","65c24799":"getYayNum(uint256)","65c2c60f":"checkName(bytes32)","65c2d3a0":"romper()","65c2e8a1":"bossAdmin()","65c2fab2":"NewIssue(address,uint256,uint256)","65c301ab":"getDriver(address)","65c40b07":"bonusesDates(uint256)","65c4a861":"cordY(uint256)","65c4b463":"_tag(bool,string)","65c5826f":"ENC()","65c5e683":"mine(address,uint8,bytes32,bytes32)","65c683cf":"metadataOfToken(uint256)","65c724cd":"dividendsCollected()","65c72840":"getDay(uint256)","65c7b711":"MockToken()","65c91b0b":"testFailTransferOnlyTrustedCaller()","65c95a6b":"setUFee(uint256)","65c9e51e":"setDepositPeriod(uint256,uint256)","65cacaa4":"getVaultAddress()","65ccb687":"PULSToken()","65cd048b":"setDividendFee(uint8)","65cd1bea":"PayToken(address,address,uint256)","65cd3686":"setIsSendingLocked(address,bool)","65ce47fb":"_myDecimal()","65ce5222":"specificTransferFrom(address,address,uint256)","65ce7395":"setMinVote(uint256)","65cf3a48":"bonusPrice()","65d0a890":"Daio(uint256)","65d0e4a7":"addBot(address,address)","65d1926d":"dropAddress()","65d1df24":"s2s()","65d27248":"setSellPrice(uint16,uint16,uint8,address,uint256)","65d300ea":"CreateAds(address,uint256)","65d43868":"allowedOracleChangePercent()","65d48d0b":"freezeBalancesOf(address)","65d4bdab":"targetEth()","65d51dd5":"_phase2Supply()","65d5b48d":"PRECOMMITMENT_VESTING_SECONDS()","65d61ad6":"PwdHasBeenSet(bytes32)","65d6759a":"getGenome(uint256)","65d68308":"receiveTokenLoot(uint256,uint256,uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","65d6dbbd":"unPromisedPop()","65d6e6a4":"jackpotMaxTime()","65d73851":"calculatePrizeCut(uint256)","65d7d3d0":"LegacyReputationToken()","65d80117":"getResource(string)","65d8a20a":"updateTransactionFeePercentage(uint8)","65d8e32e":"setProfileHash(string)","65d967b0":"ETH_HARD_CAP()","65d9d8e2":"depositEtherForUser(address)","65d9df9c":"totally_decrease_the_supply(uint256)","65d9f31e":"addressFounders3()","65d9f55a":"removeValidationPreSigned(address,bytes32,uint8,bytes32,bytes32,bytes32)","65da1cfc":"AdminClaimed(address,address)","65da5603":"produce(uint256)","65db63d0":"kittensDroppedToTheWorld()","65db6c8c":"OPTIONAL_POOL()","65dba2b3":"removeTeamMember(address,bytes32)","65dc128e":"p_setAirdropPercent(uint256,uint256)","65dc4e3a":"addCollateralMarket(address)","65ddf33b":"productsShipped()","65de1eb3":"getVendor(uint256)","65df517e":"CTHToken()","65df7933":"totalDevelopers()","65dfc20f":"setWalletFees(address,uint256)","65e00beb":"createFlowerAuction(uint256,uint256,uint256,uint256)","65e0c718":"DisputeResolved(bytes32)","65e0e117":"getSendersCalcTokens(address)","65e0e9a2":"preIcoState()","65e14731":"_kittenOwner()","65e16933":"buyPRETDETokensWithoutETH(address,uint256,uint256)","65e16a09":"transferadmin(address,address,uint256)","65e17c9d":"feeAccount()","65e1cc85":"foundersPercent()","65e21cb0":"transferNewBunny(address,uint32,uint256,uint256,uint32,uint32)","65e23ce3":"minimumEther()","65e2406a":"takeEthForExchange(uint256)","65e2409b":"getPlayerEnergyByAddress(address)","65e4349c":"NewStage(uint256,uint256)","65e44d06":"BITOToken()","65e47208":"lcBalance()","65e4ad9e":"isAuthorized(address,address)","65e60ef2":"read(bytes32,bytes32)","65e62ee6":"getInvestorKycLimit(bytes32,uint8)","65e7096d":"allMaskGu_()","65e7ee50":"RCCContractTest()","65e807ab":"getTokenLossValue(uint256)","65e83ae1":"getCrowdsaleTokens()","65e8faf6":"isValidIndex(uint256,uint256)","65e93b3f":"getUserVotes()","65e9cc4e":"contributionPending()","65ea19a8":"set_notary(address)","65ea2b77":"ethaddrc()","65ea62ff":"initTransfer(address,uint256,uint256)","65eb0dec":"changeAllowedTakerBetsPerMakerBet(uint256,uint256)","65ed16af":"_addBridgeNativeFee(uint256,uint256)","65ed6e23":"getAllocations()","65ed8a4a":"proposedTotal()","65eec589":"_markWithdraw(address,uint256)","65ef1a3f":"setHotWalletAddress(address,address)","65ef617d":"AdminWalletUpdated(address)","65ef7b95":"getStoreAddressById(uint256)","65efd3a3":"addCertAdmin(address,bytes32)","65f0a00b":"ONETIDC()","65f17913":"monarchsByNumber(uint256)","65f27bea":"testSubBalanceFailsBelowZero()","65f2bc2e":"unitsOneEthCanBuy()","65f3c31a":"Put(uint256)","65f41211":"validStoreDest()","65f42e7a":"APTV()","65f4d9f6":"failInvestPercents()","65f520a7":"kittyData()","65f5463e":"CLIP()","65f594a7":"revealCurve(uint256,uint256,uint256,bool,bytes32)","65f63c1b":"queryToken(uint256)","65f6a049":"sellGrimReapersAgainstEther(uint256)","65f6c15e":"ordersOf(uint256,uint256)","65f6d6a2":"FOUNDERS_TOKENS()","65f77c63":"getCertAddressByID(string,bytes32)","65f7aaff":"endRoundDecision()","65f84cbe":"_createWeightedMultiplierLot(address,uint256,uint256)","65f88c0d":"getNumUsers()","65f926ff":"getIdArrayItemsCount(address,address,string)","65f937ed":"sumOfAvailableIcoCoins()","65f97082":"startIco2(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","65fa2b97":"calculate_with_fees(uint256)","65fa2f7f":"getLastPrice(uint256)","65facff0":"_isMember()","65fae654":"Mychatcoin()","65fb99ba":"findUnConference(string)","65fba60d":"crowdsaleAllowance()","65fbc99f":"distributedSaleStakes()","65fc535b":"withdrawBenefit(address,uint256)","65fc783c":"getNumOfVoters()","65fcb49e":"maxContractBalance()","65fcf1b5":"releaseFirstUnlock()","65fddc81":"reducer()","65ff0f5a":"TradeListing(address,address,address,uint256,uint256,uint256,bool,bool)","65ff8220":"sampleContract()","65ffe43d":"lastFund()","66003666":"bountyTokens(address,uint256,string)","66005ede":"vc1Wallet4Pct()","6600811c":"tokenSaleHalted()","6600d282":"releaseAngelFirstVested()","6601345c":"changeTierController(address)","66013bdd":"withdrawToken(address,address,uint256,address,uint256,uint256,address)","6601cd77":"getExchangeDetails()","66025047":"isCategory(uint256,uint8)","660357f2":"removeWhiteListedContracts(address)","66035cc0":"adPriceHalfDay()","66040458":"signedApproveAndCall(address,address,uint256,bytes32,uint256,uint256,bytes32,address)","66042e7a":"etherToSendFund()","6604ca6b":"STO_KEY()","66056e8b":"destructSale()","6605bfda":"setTreasuryAddress(address)","6605ff66":"totalSales()","660686de":"cutBAU2Length(bytes32,address,uint256)","6606873b":"setMem(uint256)","6606b7d4":"democFee()","6606fe1e":"CABCrowdsale()","66081ec1":"JACKPOT_WALLET()","66092ea8":"ignited()","66098d4f":"plus(uint256,uint256)","66099706":"getChannelCred(address,uint256)","660a333e":"assetOwnerAdded(bytes32,address,address)","660aab8e":"profileOf(address,bytes32)","660b24b4":"emergencyTokenDrain(uint256)","660b7ad5":"rentDue(bytes32,string)","660ba74e":"_availableBetting(uint256,uint8,uint256)","660c325e":"evPayOut(address,uint256,address,uint256)","660c6813":"crowdsaleStopDate()","660d0d67":"dataStore()","660d5887":"registeredUsers()","660dee82":"addTask(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","660ef82d":"advisersAllocation()","660f77aa":"CVDToken()","6610a38a":"mountCitadel(address,address)","6610f7a8":"previousBurners(address)","6611611c":"MIN_INVESTEMENT()","6611f5f2":"ZTR_ETH_extra_price()","6612283d":"subdivisionEnabled()","66125b25":"boolFunc(bool,bool)","661309ac":"allowedTransfers(address)","6613221f":"burnLand(uint256)","66134794":"exploreCount()","6613ee9c":"_isSigned(address,address,bytes32,uint8,bytes32,bytes32)","66154885":"getIncomingValueAsEth()","6615827b":"LogEscrowEthReq(uint256)","6615dd83":"setSeedSourceB(address)","6615e357":"setPortfolio(bytes32,bytes32[],uint256[])","66161ed4":"setStopContract(bool)","66167617":"bet_various()","66167663":"subdomainTarget(string,string,string)","66168bd7":"depositTokens(address,uint256)","6616c886":"canSetBanker()","6617e11a":"NiceGuyTax()","66180bc7":"testTransferTwoTokensAndReturnFunds()","66188463":"decreaseApproval(address,uint256)","66188a26":"forwardable(address)","6618b008":"cancelSellOrder(address)","66194d72":"childToken(address,uint256)","661956fb":"depositInvestment()","661990bc":"earlyInvestorWallet()","661aba0d":"setMntpMigrated(address,bool,string)","661ad427":"setOraclizeUrl(string)","661b6dae":"eth2qiuRate()","661b9065":"getRelationWith(address)","661be157":"account_address()","661c866c":"requestNewEtherRealID(string,string,string,bool)","661d3470":"LUXREUM()","661e3605":"ConstructorContract(uint256)","661e5ec2":"getPlayerValues(uint8[],uint8[],uint8[])","661edfee":"rewardFor(address)","6620a935":"sendToOwner()","6620cc3c":"GanNFT()","6620ffd3":"getNumAnimalsXType(uint8)","66210532":"setVestingMasterAddress(address)","6621b7be":"fiatValueMultiplier()","66234c4a":"ReleaseManagerSet(address)","6623fc46":"unfreeze(uint256)","662457c6":"nextProposalID()","6625123b":"COINBIG()","662512f1":"testThrowTranferZeroTokens()","6625b349":"RESERVE_ALLOWANCE()","6626b26d":"off()","66272374":"setWithdrawRate(uint256)","662723bb":"bulkTransfer(uint32[],address[],uint256[])","66273fc6":"bountyTokenSupply()","6627ace5":"getDCommBallotsEnabled(bytes32)","662959cc":"southadvisor()","662a3b81":"getHouseAddressTwo()","662a6137":"developmentTokensWallet()","662a719b":"RewardHalvingTimePeriod()","662ad59b":"pixels()","662bca97":"SetInRate(uint256)","662c6230":"LogResultNoWinner(uint256,uint256,bytes)","662d2ec8":"freeze(address,uint256[],uint8[])","662d5aa9":"EduMetrix()","662da459":"newCostToken(uint256)","662dbe96":"getNodeHeight(bytes)","662de379":"registerAddress(bytes32,address)","662e2536":"cordZ(uint256)","662e3470":"getSectionIndexFromRaw(uint256,uint256)","662e4db0":"c_preICOBonusPercent()","662e4ee4":"changeowner(address)","662f0763":"sendTokenReward(address,uint256)","662f94c0":"approveBlacklistedAddressSpender(address)","662fa2fb":"ProofOfRarePepe()","662fac39":"mining()","662feffc":"addStore(string)","663083f6":"moneyTotal()","663152d1":"phaseOneEnd()","6631ff1d":"grantToken(address,uint256,uint256,uint256,uint256)","6632a507":"testSetupPrecondition()","6633a2bb":"_newPresserFee(uint256)","66341c97":"changelp14(address)","6634cec6":"findProductAndIndexById(uint256)","6634d917":"startEarlyStage2()","66357f57":"descriptionUpdate(string)","6635da25":"Voting(bool)","6635e0ea":"BlocklabTokenV1()","6635e511":"availableForInvestment()","66365082":"dealRevert(uint256)","6636fca8":"retainers(address)","6637324a":"Deploy(address,uint256,uint32,uint256)","6637b882":"setDao(address)","663890b1":"FinalizableCrowdsaleImpl(uint256,uint256,uint256,address)","66389f1f":"OwnerProclaimedDead(address,address,uint256)","6638c087":"createCloneToken(string,uint8,string,uint256,bool)","6638d82f":"freezeTo(address,uint256)","6639016b":"releaseETH()","663960cd":"NewWinner(address,uint8)","6639dc8e":"emissionLimit()","663a0ebb":"tokensAmount()","663a339d":"IsSetReferrer()","663b0534":"disablePayable()","663b3f62":"balancesImporter6()","663b8c5a":"_newTuneOption(uint32,uint32,uint256,bool,bool,uint128,uint64)","663bc990":"test_1()","663c01af":"getAllProductIds()","663c2e30":"claimPrize(bytes4)","663c920a":"redenomiValue()","663cebfc":"VeiagCrowdsale(uint256,uint256,uint256,uint256,address,address,address,address)","663d1e84":"createVotacion(bytes32,bytes32[],uint256[])","663d6612":"defaultOperatorsTranche(bytes32)","663e0f88":"getSpecifiedDecimal()","663e90d9":"setBuyNowListing(bytes32,uint256,bool)","663f2670":"AccountLinked(address,address)","663f70c3":"calculateBounty(uint256)","663f8549":"mintReserved(address,uint256,uint256)","663f9c0d":"loginState(address)","663fc7e0":"highRoller()","663ff5a9":"create(bytes32,address)","6640ca84":"AgreementPen(address)","6641179e":"artistsEditions(address)","66417115":"positionOfJingle(uint256)","6641cc27":"eliminarVotacion(bytes32)","6641cc64":"kycApproved(address)","6641ea08":"ROUND_DURATION()","6642c0bc":"executeExploit(address,address)","66435abf":"getWeight(bytes32)","6643caba":"generousDonation()","6645167d":"YourCrowdSale()","664519bd":"wwamICOcontractAddress()","6645c0dc":"transferVotes(address,uint256)","66476fcc":"flipTokenReward()","66479c08":"payOraclize(uint256)","6648cb52":"setPurchasePeriod(uint256)","66494ab6":"THAW_CYCLE_FUNDER()","6649dfd5":"preCrowdsaleOn()","664a1ad6":"fundWallet()","664abc0f":"packedToEndTime(uint256)","664b3350":"createTransfer(address,uint256,bytes)","664b885e":"AddNewPrestige(uint256,uint256,uint256)","664c7bf7":"ethEurFraction()","664d8629":"withdrawAuctionDklBalance()","664dcb93":"getMHTTotalSupply()","664dd24f":"getUserTransactionIndexes(address)","664e9704":"RATE()","664eb12e":"updateCompanyPrice(uint256,uint256)","664f4904":"sealMinter(bytes32)","66505d1d":"BitcoinisDumb()","665289d2":"adjustPriceAndOwnerOfPlayerDuringPresale(uint256,address,uint256)","66533014":"supportMessage(uint256)","6653be1a":"getGameCardId(uint256)","665502ec":"ContractToken(address,string,string,uint256)","66550624":"CityLifePlusToken()","66552e15":"addVestingForBeneficiaries(address[],uint256[])","6655d7dd":"RedeemTokens(uint256)","6655ff3d":"WebsiteHostingToken()","66566947":"associateWithTeam(bytes32)","66566abd":"multSender(address[],uint256[])","66576514":"mintDRSCoin()","665788f8":"firstCrowdSaleDate()","6657b2c0":"reloadTickets(uint256,uint256)","665814d8":"_presaleStartTimestamp()","6658238c":"Peculium()","665851bb":"wangxihaoToken(address,address)","665905c6":"manuallyResetGame()","665939cc":"setupFundingRate(uint256)","6659889d":"setPromoWallet(address)","66599a40":"setEtherPriceInPoundPences(uint32)","665a11ca":"liquidityPool()","665b0d5b":"_taskError(string)","665b1bc0":"_mint(string,uint256)","665b51ce":"getusedAPI()","665bcc32":"ProcessGames(uint256[],bool)","665beae7":"ExecutableBase(bytes)","665c0b8e":"purchaseMembership(address)","665ca475":"VUToken()","665d8a53":"MAIN_SALE_END_TIME()","665de19b":"mutiSendCoinWithDifferentValue(address,address[],uint256[])","665df460":"sqrt(int256)","665e06ac":"OATToken(address,uint256)","665eba29":"playerForceGameEnd(uint256)","665f09fa":"addCoinAmount(address,uint32)","665f5149":"JOZ()","665fb66a":"YBToken(uint256,string,uint8,string)","66605ba4":"rename(string)","66605c47":"GetBuildingData(uint256)","6660b210":"kMinStake()","6660da77":"addDiscountStruct(bytes32,uint256,uint256[2],uint256[],uint256[],uint256[])","6660ead1":"RANGEEND_11()","66612f66":"MAX_DAILY_COSIGN_SEND()","666192b9":"___upgradeToAndCall(address,bytes)","66625bbd":"revokeContract()","6662e4be":"isWinningBet(uint256)","66634a16":"getAnimalCount()","666375e5":"set_allow_contributions(bool)","6663bbec":"orderMatch(uint256,uint256,int256,uint256,uint256,address,uint8,bytes,bytes,int256)","66648dd3":"setRateIco(uint256)","6665e0fd":"tradeActive(address)","66663d78":"XPAAssets(uint256,address,address,address)","6666490c":"getPlayerSpaceshipBattleLossesById(uint256)","66666aa9":"rewardPool()","6666d22c":"timeBetweenRounds()","66671c30":"FBLFounderFund()","66671c71":"BaseScheduler(address,address)","66675c57":"updateDecimals(uint256)","66679ac7":"interfaceTransfer(address,address,uint256)","6668df7f":"subCoinAllowance(address,address,uint256)","6668ffc6":"isAuditor(address,address)","666923ea":"lastBlock_v15Hash_uint256()","6669749f":"HamzaCoin()","666a3427":"removeOwnership(address)","666afadc":"preparePreContribution(uint256,uint256,uint256)","666b7d32":"disableICO()","666b9132":"PartialCoin()","666be68a":"setIcoTokenSupply(uint256)","666c7ed0":"WIZE()","666cd4bd":"calcId(uint128,address,address,address,address,uint256,uint64,bytes)","666cdaa0":"getAnime(uint256)","666da64f":"claimShare()","666de8d5":"setSecretBonusFactor(uint256)","666e1b39":"owner(address)","666e587d":"fundICO(uint256,uint8)","666efa0a":"walletFees()","666f0354":"getMonthRefferals(address)","666f4cad":"totalWeiWagered()","666f6843":"reservedAddress()","666fc4d4":"minimunEthereumToInvest()","6670bdd8":"getDOwner(bytes32)","66731e95":"LogNewWhitelistUser(address,uint256,uint256)","667336d8":"available_without_bonus()","66734eb0":"MainController(address,address)","66735f4e":"_pickWinner()","667390c7":"SendmoneyTransfer(uint256)","6673ce2b":"Results_of_the_last_round()","6673d5c6":"totalSoldTokenCount()","6674bfaf":"closeOption(address[3],uint256[3])","6676871d":"reserved_funds()","6676aaa2":"MplusCrowdsaleB(address,address)","66772438":"computeResponse(uint16)","6677cef1":"getCrowdsaleManager()","6677febe":"get_all_accepted()","667815a2":"getCanSellBalance()","6678887f":"replacesOldContract()","66792ba1":"send(string)","667a2f58":"createDepositAddress()","667b39b9":"nameOfToken(uint256)","667cb72d":"soldIdeaWeiPreIco()","667d5d22":"wager()","667ec46c":"getCurrentTierStats()","667f1656":"preSaleBotReserve()","667f9510":"getBundinha()","667fc6b9":"IchigoToken()","66801384":"STAGE_2()","6680285a":"AuthorizedCreateToPrivate(address,uint256)","66802a92":"tokenGenerationState()","668038e0":"claimDividends()","66805de5":"closePool()","6680624e":"gasPriceMaximum()","66816e2a":"setBaseStrength(uint256)","6681b9fd":"fundsRaised()","66829b16":"changeToken(address)","6682eaf1":"setsecure(uint256)","6683381b":"setDiscountToken(address,uint256,uint256)","66836acf":"updateBlock(uint256,uint256,bytes32,bytes32,bytes32,bytes32)","6683ee49":"BlockPlanet()","6683f9ae":"isSettling(bytes32)","6684ffcd":"burnerSet()","66855dcc":"removeInt256s(bytes32[])","6686e174":"tokensReleasedAmount()","66874cc5":"brokers(address)","66875554":"resumeTokenSale()","66875a31":"FOUNDER_TWO()","668767bd":"transferFromForExchange(address,address,uint256,string)","6688e305":"EIP20(uint256,string,uint8,string)","66894d76":"releaseThreeHotHourTokens(address)","6689e28b":"distribution(uint8,address[],uint256[],uint256[])","668a0f02":"latestRound()","668a2001":"removeParticipant(address)","668a2f67":"boom(address)","668aa824":"oraclePrice()","668abff7":"lastRoundLengthUpdateStartBlock()","668ad45f":"MyToken(uint256,string,uint8,string,string)","668b1b7e":"AOCTrader()","668bd511":"BithelloToken()","668c1a46":"refundBNBContributor()","668c8573":"DATING()","668cc7d8":"registerContest()","668cf93d":"LOSER_LOCK_TIME()","668d5f48":"addBrick(uint256,string,string,uint32,string,bytes32[],uint256)","668e0f6a":"addEntry(string,string,string,string,address)","668e157f":"StandardQuickConverter()","668eef5b":"test_2_method()","668faae8":"CollectibleIndex3()","668fde45":"advSend(address,uint256,bytes)","66901c5b":"clearTimeMap()","66901efb":"getOwnerInfoByIndex(uint256)","66905ba0":"overwrite(string,string)","66907d13":"setNextOrderId(uint80)","6690864e":"setTeamAddress(address)","6690f30b":"set_Name(string)","66914614":"getJackpotTotalValue()","6691461a":"updateTokenAddress(address)","6693b694":"unfreezeSupply()","669459a7":"removeRegistryFromOwnerIndex(address)","66949b56":"endMatch(uint256,int256,int256)","6694e845":"numRewardedAxies(address,bool)","669529df":"removeFromWhitelistMultiple(address[])","669541d6":"setGasCost(uint128)","66957377":"batman()","669585a4":"_figthExecutor(address)","6695b592":"stemPriceInWei()","6695f930":"calculateAndSetRate(uint256)","6696ca51":"forceBurnFrom(address,uint256)","66971c8a":"setCurrentFundingRound(uint256)","66973129":"PHEPToken()","6697aa84":"getRequiredMinor()","6698baaa":"STAGE_TWO_TIME_END()","6698f141":"releaseTeamTokensAfter18Months()","6699d9cd":"Securities_2()","6699e4c7":"isReadyForClose(uint256)","669a55ec":"initialPrizeBov()","669a828b":"getProgramsValue()","669b7e69":"getBlockAddressCount(uint256)","669cab39":"cancelBetByOwner(uint256)","669d8dff":"AddorModifyRig(uint256,uint256,uint256,uint256)","669dafe8":"toWei(uint256)","669e48aa":"get(uint256,uint256)","669e6684":"_rebalanceTree(bytes32)","669eb768":"registerDonation(uint32)","669ee827":"RegisterDevice()","669ef86d":"getPriceByDayIndex(uint256)","669f6d80":"bountyRewardPercent()","66a03098":"receivedFrom(address)","66a0b81e":"safeMode(bytes4,bytes1,address)","66a11615":"revokeMintingManager(address)","66a192c6":"CurrentRate()","66a200ba":"TokenDemo(uint256,string,uint8,string,address,address,address,address)","66a23c01":"ETOKEN2()","66a26419":"cancel(address,uint256,address,address,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","66a39350":"FAIL_FLAG()","66a3de2a":"_safeTransferFrom(address,address,uint256,bytes)","66a4b6c0":"usdDecimals()","66a51d1d":"UcCoinMinimumSellingChanged(uint256,uint256)","66a659b3":"readcolorXteam()","66a65c99":"getLegacyCount()","66a6cf1a":"mateWithAuto(uint256,uint256,uint8,bytes)","66a78b40":"depositAgent(uint256,uint256,string,string,uint256)","66a78e6c":"maxReward()","66a857f4":"ChangeTokenSymbol(address)","66a8c45b":"StarmidFunc()","66a908a5":"foundersTokensUnlockTime()","66a9234c":"addPhase(uint256,uint256,uint256)","66a92cda":"releaseOnce()","66a9bc0d":"teamTokenVesting()","66aa01ca":"permittedAddresses(address)","66aa56c5":"initiate()","66aa6f26":"payFee(bytes)","66aa9aff":"adminDeposit()","66ab4e5f":"Grid(uint256,uint256,uint256)","66ab5290":"transferSgaToSgnHolder(address,uint256)","66ac777e":"rotate_right(uint32,uint32)","66ac8075":"payoutPrizes(address[])","66ad3ffc":"building(uint256)","66ad484c":"newfirst_player(address)","66adeb3a":"SmartToken()","66adeb8c":"transferBalance()","66adf835":"_setup(address,address,uint256,bool)","66adfbbd":"sgc(uint256)","66ae924b":"toUint16Throw()","66ae935f":"balanceEqual(address,uint256,string)","66aecfa7":"bankToCharm(string,uint256)","66aee0fc":"investorsProfit()","66aef95b":"increaseTimeIfBidBeforeEnd()","66af3914":"getTradeIsOpen()","66af77ca":"totalMarks()","66b005ee":"QueryUnlockTime(address)","66b0a536":"MomaCoin()","66b10f70":"learnMove(uint256,uint256)","66b3e4b9":"stageMarketing()","66b3f6bf":"invested(address)","66b3fe66":"setTimeScale(uint256)","66b42dcb":"register(address,string,uint256,string)","66b43da5":"computeSha3(uint256[8])","66b46149":"fstring(string)","66b464de":"goldBoxPrice()","66b4ad74":"KudanilToken()","66b52b93":"addMeByRC()","66b567da":"getNumMyHatchingUnits()","66b5e2d8":"getCountMembers()","66b625d4":"bountiesAllocAddress()","66b62bde":"isSetTeamWallet()","66b668de":"RFUDToken()","66b68516":"Finalized(address,uint256)","66b728d5":"getVoteOptionId(uint256,string)","66b7afbf":"init_level()","66b7d5c6":"receivedWais()","66b847e5":"assertQuantity(uint256)","66ba2670":"setOriginalPriceGen0()","66ba707f":"ConsultaRegistro(string)","66bab099":"getCurrentSupplyVote()","66badf4b":"BITCOINGAM()","66bb28be":"_transferMultiple(address,address[],uint256[])","66bb83b6":"batchlimits()","66bc0d6d":"withdrawFundsAndStartToken()","66bcc860":"TransferSiteReg(address,uint256)","66bd6ff6":"DecentralizedExchangeHotPotato()","66bd78fd":"getBalanceContract()","66be24ba":"blockUntil()","66bea821":"sendSupplyTokens(address,uint256)","66c0276e":"CryptonewsIndonesia(uint256,uint256)","66c0e5e0":"revealPhaseMinSecondsWaitForReveals()","66c14e0a":"dropCount()","66c2355c":"requestNameChange(string,string)","66c2aa0e":"getStackholderTransactionCount(bool,bool)","66c2ae95":"setHgtRates(uint256,uint256,uint256,uint256,uint256,uint256)","66c2d620":"getTot(uint256)","66c2d6a0":"BettingToken()","66c313c6":"ETHER_THRESHOLD()","66c31f12":"emitUserBinded(uint256,address,bool)","66c376a1":"setResult(uint32,int8,int8)","66c42517":"refundToken(bytes8,address,uint256)","66c5c4a0":"unfreezeAll()","66c5cdf8":"updateTotal(uint256)","66c618d4":"sameWhiteList(address,address)","66c630bc":"honourWhitelistEnd()","66c71952":"setDiscountPercent(uint256,uint256)","66c76592":"_raffleDraw()","66c7d1ed":"RozelCoin(uint256,string,string)","66c7fb77":"generateDeed(string,bytes)","66c82de8":"ContributorPool(address,uint256,int256,uint256,int256)","66c89a13":"getAssetEmmiter(uint256)","66c91053":"doubleTransfer(address,address,address,uint256,uint256)","66c99139":"trans(uint256)","66c9bc38":"etherExchangeLikeCoin()","66c9d697":"executeVerdict(bool)","66ca2bc0":"sendSignal(bytes32)","66cab1f3":"isSponsorshipRefunded(address,uint256)","66cc6064":"getPayout(uint256,uint256,uint256)","66cd0663":"setCrowdsaleFinished()","66ce10b7":"publicKeyVerify(uint256,uint256,uint256)","66ce3bd2":"walletBalanceOf(address)","66ce5c52":"minWeiToPurchase()","66cf058a":"endIcoSaleRound2()","66d003ac":"recipient()","66d10688":"getBoughtTicketCount()","66d11c1a":"ContractAddress()","66d12fad":"getStakeInOutcome(bytes32)","66d16cc3":"profit()","66d1cac9":"updatePost(uint256,string,string)","66d29324":"defrosting()","66d2da12":"setUser(address,address,string,string,bytes32,uint256,uint256,uint256[],string,string)","66d38203":"setup(address)","66d39035":"getContribution(bytes32,bytes32)","66d42b3f":"Betting(uint256,uint256)","66d49bab":"updateTotalSupply(uint256)","66d598f0":"E18()","66d5c8ed":"node_left_child(uint256)","66d5eb9b":"openZoneShop(bytes2)","66d76bb2":"rateETH_ROK()","66d7ffde":"left24(uint256)","66d8c463":"reveal(bytes32,string)","66d8d040":"dividendsRightsFixUpdate_(address,address,uint256)","66dacc48":"afterFirstRefundRoundFundsReleaseDenominator()","66db11e7":"nodeExists(bytes32,bytes32)","66db2a59":"competitorPAY(uint256)","66dc860a":"getBreedingFee(uint40,uint40)","66dd3bc0":"terminateAccount()","66de5a4f":"createWorkerPool(string,uint256,uint256,uint256)","66de6fa4":"isReachedLimit()","66de84ec":"withdrawBonus()","66df8fe6":"secondStageTotalSupply()","66e13d36":"stakeForWithLockup(address,address,uint256,bytes)","66e144f9":"Futurescoin()","66e159b8":"CreatedNIMFA(address,uint256)","66e16aff":"mdbToken()","66e1aa99":"assignCertificate(address,string,string,string,string)","66e1cebd":"getStakingGains(uint256)","66e20b51":"crowdsourcers()","66e20e77":"priceNumerator()","66e23276":"ADVISERS_SUPPLY()","66e264be":"p2Of(uint256)","66e305fd":"isEligible(address)","66e34dc6":"registerUsername(bytes32)","66e3c230":"callLibSet2(uint256)","66e3cb68":"upgradedFrom(address)","66e3e5e4":"contractTokenBalance(address)","66e41cb7":"test2()","66e41cd7":"GetTime(uint8)","66e4f8c8":"getLastSpinOutput(address)","66e5cb50":"stopTransfer(uint256)","66e61a31":"outProjectBinding(uint256,address,address)","66e65eb1":"checkLocked(address,uint256)","66e6c8af":"authorise(address)","66e7107e":"SCARABToken()","66e722b0":"SecurityToken(string,string,uint256,uint8,address,uint256,uint256,uint8,address,address,address)","66e72baa":"transferWithLock(address,uint256,uint256,uint32)","66e7ea0f":"incBalance(address,uint256)","66e84652":"resetContribution()","66e8a4d7":"testGetBonus()","66e8cd81":"allBalances(address,address[])","66e98c31":"createCoin(string,uint256,uint256,string,string,address)","66e99a11":"lxhcoin4()","66e9b336":"removeReturnableToken(address)","66eb463f":"changeRootAdmin(address)","66eb50b2":"startLeaderboard(uint64,uint64,uint64)","66eba165":"PlaceBuy(address,address,uint256,uint256,uint256)","66ec60c7":"getFineLevelOfUsername(string)","66ecc9e2":"require_limited_change(uint256)","66eccfbf":"token_batchTransfer(address,address[],uint256[])","66ecded4":"setRelativeAddress(address)","66eec532":"getSellerFullInfo(address)","66f0a3f6":"getTokenRemain()","66f1e438":"getMiniPoolEdit_7()","66f2d859":"setSellRatio(uint256)","66f36b34":"Birth(uint256,string,address,bytes32)","66f3882f":"setIcoPhase(uint256,uint256)","66f3a2b8":"totalPreBuyers()","66f4e1c7":"MAX_GRANTEE_TOKENS_ALLOWED()","66f516fe":"changeTimeAndMax(uint256,uint256)","66f5f332":"Log1_fnc(address,bytes32,uint256,string,string,uint256,bytes1,uint256)","66f7d730":"WithdrawalEnabled()","66f7d9da":"accumulatedHours()","66f83e91":"getRandom(address)","66f84d30":"setParent(uint256,string)","66f8bbe0":"DMarketToken(address,uint256,uint256,uint256,uint256)","66f8e86f":"MLQD()","66f928d3":"updateShareRuleGroup(uint256,uint256,uint256,uint256,uint256)","66f9785a":"EtherShuffle(address[])","66f99a11":"setOpenValueGasLimit(uint256)","66f9c99e":"setUpgradeAddress(address)","66fa2be9":"tickets(bytes4,uint256)","66fa6efb":"unverify(address,address)","66fb3831":"VALUEBACK()","66fbc154":"earlier()","66fc0dd7":"walletTeamAdvisors()","66fc6937":"lastCharge(address)","66fcf285":"distributeMulti(address[],uint256[])","66fd3cd8":"commit(bytes)","66fd555f":"Comission(address,bytes32,uint256)","66fda50b":"removeOracles(uint256,address[])","66fe16e9":"emitIssued(address,uint256)","66fe25a0":"IcoEndDate()","66fe825a":"Gruptecoin()","66ff8201":"GetChipNum(address,uint32)","66ffebb8":"changeHolderPercentage(uint256)","67013719":"enableControl(bool)","67016c14":"issueTokensToBuyer(uint256)","6702416e":"addDoctorTo(address,string,string,string,uint8,uint8,uint8,uint8,uint8,uint8,uint32,uint32)","67025dcf":"transferAll(address,uint256[])","670396e7":"CashToken()","6703c429":"ETCReturn(address,uint256)","67043001":"isEIP20Token()","67043cae":"registerOffChainDonation(address,uint256,uint256,string,bytes32)","67061a55":"teamSharePercent()","67069544":"issueAssetToAddress(bytes32,uint256,string,string,uint8,bool,address)","67069916":"OwnershipTransferCanceled()","670733b5":"setBitwordsWithdrawlAddress(address)","670744cf":"_createCobeFriend(uint256,uint256,uint256,uint256,address)","6707b8aa":"BestEtherSupply()","67080f6e":"testThrowsSetEnforceRevisionsNotOwner()","67084eb3":"houseBalance()","67085633":"getMyGenes()","67085dab":"bnCheck()","6708cc63":"becomeKing()","6708f91d":"Rurchase(address,uint256,uint256)","6709b337":"Token(string,string,uint256,bool,bool,string,string,uint256,uint256,uint256,bool)","670a1e6f":"getEligibleAmount(address,uint256)","670be445":"initialEPXSupply()","670c00d0":"getMotPrice(bytes32)","670c1500":"CoinCool()","670c314e":"TimeFinish()","670c3ac2":"priceUpdateTimeline()","670c884e":"setup(address,uint256,uint256,uint256,address)","670ca672":"NTVToken()","670d14b2":"keys(address)","670da6f8":"getOwnerPetCount(address)","670e2e7f":"DatumGenesisToken()","670e64c8":"setWhitelistingAgent(address,address,bool)","670eedba":"strConcat(string,string,string,string,string,string,string)","670f4bd4":"releaseDivTokens()","670f8755":"_0xZibitToken()","670fe0ff":"TootrTokenSale()","6710e801":"_createRabbit(uint256,uint256,uint256,uint256,uint256,address,uint8)","6712e0be":"tokenGenerationMin()","67130e8c":"getWeiOwed(address)","6713263d":"crowdsaleTokens()","6713640d":"TierStarterDividendAddress(address)","6713e230":"isTrusted(address,address)","67141690":"getEnabledTokensInformation()","67141732":"createContractCity(string)","6714cfe2":"GetLuckyGamblers(uint256)","671528d4":"isCapped()","6716a692":"setDVIP(address)","6718484f":"create(uint256,address,string,string)","67194bee":"AirdropClaim()","67198207":"EARLY_CONTRIBUTION_DURATION()","671baae3":"Sepp(uint256,string,uint8,string)","671bd594":"setBigPrice(uint256)","671bdc3d":"PrimebankCoin(uint256,address)","671c7d68":"test02()","671d3315":"bookAfternoonVisit(uint256)","671d6429":"setTreasurer(address)","671dacdc":"CalculateSqrt(uint256)","671de554":"mintPreICO(address,address,uint256,uint256,uint256)","671e4405":"isFinalize()","671ec66c":"setDomainOwner(bytes32,address)","671fa0a0":"Inscription(string)","6720ceb1":"sendPayment()","6721ebe2":"airdropThroughput()","67220fd7":"adminClaimAirdropMultiple(address[],uint256)","67221df0":"isPendingA(address)","672324ac":"cashInRate()","672350bd":"getFreeExtension(bytes32)","6723c20d":"testTrip(uint256[3])","6723eab5":"batchCreateETHCardAsset(uint8[],uint256[],uint256[],uint256[],address[])","67243482":"airdrop(address[],uint256[])","67249254":"mintWithLock(address,uint256,uint256,uint256)","672566a0":"Upgradeable()","6725bed6":"CCH_RE_2()","67268bbc":"removeTransfer(uint256)","67272999":"claimETH()","672781ed":"priceClaim()","6727cc2d":"removeWhiteListAddress(address[])","67286a83":"getGoldStatusAuditcount(address)","6728b711":"RealAssetToken()","672acef0":"participantCapTier2()","672c8dca":"ownerTakesAllNotClaimedFunds()","672ce152":"HodlBox(uint256)","672d2921":"zasxzasxqaq()","672e06d0":"withdrawForOneYear()","672e20fe":"allocateRemainingTokens(address)","672f412c":"setAllowDisbursePaymentWhenPaused(bool)","672fcd82":"createBet(uint256,bool)","67301dde":"IWWEE()","67316b3f":"addWhiteListAddress(address[])","67337d1a":"ReporterTokenSale()","673441db":"TokenAltPurchase(address,address,uint256,uint256,uint256,string,string)","673448dd":"isApproved(address)","673478c3":"getAssetIdOwnerIndex(uint256)","6735a1cc":"previousStage()","67374f3a":"setTargetWallet(address)","673756d8":"SOFT_CAP_EUR()","6737c877":"setAttributes(bytes)","6738426c":"enablesTransfers()","67387d6b":"testThrowCreateWithNonceExistingNonce()","67389944":"voteB(uint256)","67389d17":"SuppliedTo(address,uint256)","6739afca":"network()","6739f3a4":"getAuctionDuration(uint256)","6739fc52":"testOrd()","673a2a1f":"getPools()","673a456b":"setNumActiveTranscoders(uint256)","673a5ae3":"Sale(address,address,uint256,string,uint8,string,uint256,uint256,uint256,uint256,uint256,uint256)","673a7e28":"updatePrice()","673b57e9":"deauthorizeProvider(address)","673c0e53":"readAllFrzAcc()","673cd98e":"total_amount()","673df0e0":"horseMaster()","673f3807":"sell(uint256,uint8)","673fa8c9":"APaymentToken(uint256)","674106d8":"checkDragon(uint256)","67412045":"balanceOf(address,uint8)","6741629c":"wasEmergencyCancelled()","6741953e":"getPOOL_edit_15()","674197f8":"getBuyRequestCount()","67426ba4":"callgDistributed()","67441f52":"LOOMIA1()","6744ea49":"GetEscrowTokenSymbol()","67457022":"rmul(uint256,uint256)","67460c25":"createWikiPage(string,string,string,uint256)","67460d58":"setGate(uint256,uint16)","67465daf":"StorageExample()","6747830d":"calculateRequiredFillingAmount(uint256)","6747a33f":"accrualDeposits()","6747f09e":"cashOutFallbackAmount()","6748a0c6":"releaseFinalizationDate()","6748a106":"powLimit()","674942eb":"VOTING_PREPARE_TIMESPAN()","6749ec48":"issueLicenseNFT(bytes32)","674a1574":"claimedIdeas(address)","674a62d0":"coinIssuedMkt()","674aaa44":"transferToAnotherAddr(address,address,uint256,bytes32)","674b3bd5":"originalArtwork(bytes32,address)","674c20a1":"test0_firstInterval()","674c5eaf":"setReceiver3(address)","674c85a7":"mdiv(uint128,uint128)","674cc1f5":"getMarketHashes(bytes32[])","674d4691":"_getWeiValueOfTokens(uint256,bool)","674e4e0e":"extendUnlockDate(uint256)","674ea3cb":"closeAgreement(bytes,uint8[2],bytes32[2],bytes32[2])","674ebb3e":"cancelKimAuction(uint256)","674ed066":"minQuorumDivisor()","674ef6c3":"initializeTier(uint256,address)","674f220f":"previousOwner()","6751676f":"recentBuyers(uint256)","6751ad3d":"_insertAttackLog(uint256,uint256,uint16,uint32,uint8,uint32,bool)","67524d62":"setJackpotThreshold(uint256)","67532c8e":"sendPurchase()","67535a42":"setEthmainAddress(address,address)","6753a3c1":"setMajorEvent(string,string,string)","6753fc59":"PurchaseAdmin()","67541efa":"AlfaCoin()","67546967":"EthBtcEscrow()","6754ff3a":"addcrontime(address)","67550a35":"vox()","67551857":"clearAllRequest()","675518b8":"mintAndCreatePreIcoBitex(address,address)","67558b3a":"AzlanToken()","67561d93":"authorizeContract(address)","675629fe":"appendOnly()","6756b1ae":"GameTable()","67571f68":"handlePayouts_(uint256,uint256,uint256,address,address,address)","67578f65":"users(bytes20,uint8)","67579ad4":"currentwealth()","675879d5":"GrantedOrganization(bool)","6759fac0":"CatsToken(address)","675a4633":"dnaMixer()","675a54b9":"getHalvingOf(address)","675a690c":"setBleachDailyLimit(uint256)","675abc96":"corporateSupply()","675ac67a":"escrowCount()","675b09cd":"Niobium()","675c3048":"getTxTimestampPaymentMCW(bytes32)","675cef14":"etherMinimum()","675d43cf":"buyPixel(uint16,uint16,uint24)","675d9c35":"XRT()","675df16f":"updateSubmissionGasPriceLimit(uint256)","675ec1cf":"minimalUSD()","675f6537":"settleBet(bytes32)","675f6d1e":"callBackVariations()","675f818e":"disapproveInvestor(address)","675f9ad9":"initStages()","6760115a":"BuyerFund()","67602c59":"burnSequence()","67608d38":"ICO_TOKEN_SOFT_CAP()","676095b2":"profit2eggs()","67630f43":"buyNapkins()","6763150e":"setKyberAddress(address)","67636574":"consumed()","6763da56":"dish(string,address)","67642794":"_withdraw(address,uint256,bool)","676452f4":"t3tokenExchangeRate()","6764765d":"burnMyTokens(uint256)","67653f3b":"test_threeInvalidEqUint()","6765b49b":"getPunishXPA(address)","67669e29":"rocketIsLaunched(uint256)","6766d1ba":"getTimeUntilStart()","6766fafe":"disableTransferWhitelist()","676796b6":"releaseFounderCoins()","6767e368":"ValueTrader()","67682441":"UserUpdate(address,address)","6768893c":"AppHub()","6769d1f9":"soldToken()","6769eb46":"createMasker()","676a38d7":"get_current_price()","676a675a":"changeJohanNygrensAddress(address)","676aa496":"IbnzEtc20TestToken()","676b064e":"allForPopulate(uint256)","676b57ad":"getNays(uint256)","676c0d77":"updateTokenPrice(uint256)","676c902f":"drawNumbers()","676cb63d":"getMintingFinished()","676cdcd6":"BurnExecuted(uint256,address,uint256)","676cfec6":"rocks(uint256)","676d1d9c":"WEI_TO_COGS()","676d20ba":"WorkerToken(uint256,string,uint8,string)","676d23a5":"isChangePriceLocked()","676d2e62":"migrationMaster()","676d7769":"test_curatorDoesNotVeto()","676e2eb1":"_addDemoc(bytes32,address,address,bool)","676fc32b":"maximumTokensForThird()","67701187":"updateFighter(uint256,uint8,uint8,uint8,uint8,uint32,uint64,uint16,uint64,uint16,uint16)","6770260e":"ContributionMade(address,uint256)","67707337":"CryptocarToken()","6770da62":"_stealCardWithSocialIdentity(uint256,uint256)","67716abc":"learnFee()","677170e1":"_span(address,address)","677342ce":"sqrt(uint256)","6773b75f":"propertyIndexToApproved(uint256)","6774f8e1":"getMonarchyController()","67756fe9":"depositPayment(address)","6776ddd0":"currentHodler()","6776e56a":"validateProposedKingdomName(string)","6777d177":"icostarted()","6777e4eb":"dollarMultiplier()","677885d3":"BITIFEX()","677913e9":"setAmount(int32)","677978ec":"increaseTokenCap(uint256)","6779da43":"setAwardTokens(bool)","677a7444":"Votaciones(bytes32)","677a7735":"Shares(bytes32,bytes8,uint256,uint256)","677a8870":"TeamWallet()","677ab197":"processContribution()","677ab667":"INITIAL_STARTTIME()","677b1f0d":"_buyTokensFromSystem(uint256)","677ba3d3":"onTokenTransfer(address,address,uint256)","677bcb89":"regularMinPerPerson()","677c102d":"getHostOrders(address,address)","677cee54":"SafeConditionalHFTransfer()","677e2dc4":"setDailyPrice(uint256)","677e2ef2":"getReplyFee(uint256)","677e6fa4":"betOnColumn(uint256)","677ebf2c":"InvestmentAsset(address,address,address,string,string,uint256,uint256,uint256,address)","677f768d":"isOnTrading(uint256)","677ffb0d":"exerciseLong(address[2],uint256[8],uint8,bytes32[2])","6780a311":"transferStop()","6780b32e":"moveAccount(bytes32)","67814109":"_mintTimelocked(address,uint256,uint256)","6781cc04":"addPolicy(uint8,uint256[],uint8[])","678212d9":"tokensAuctioned()","67821686":"setETHUSDRate(uint256)","67823a4a":"limitDateCrowdWeek2()","678377d2":"core(address,uint256,address)","67845835":"Irapid()","67845daf":"claimTokensERC777(address,address,address,uint256,uint256,bytes,uint8,bytes32,bytes32)","67848d9c":"PayEther(address,uint256,uint256)","6784b075":"removeValidContract(address)","6784ccb7":"Deceum()","67854643":"getGenerationMemberLength(uint256)","6785744d":"phase1Price()","6785a8f6":"getCandidateIndexArray()","6785b500":"getChannelsAddresses()","67863c07":"earlybird()","6786ed0e":"setPriceRate(uint256)","6787416d":"NRM()","6788317a":"UnitySale(address,bool,uint256,uint256,uint256,uint256,uint256,uint256[])","678886b4":"updateTokens2PerEth(uint256)","678892c0":"rand_num()","67899248":"processKick()","678a1013":"monsterNFT()","678a6baf":"ROUND_3_PRESALE_BONUS()","678a7dca":"setShareFee(uint8)","678ae6a1":"updatePools(bytes32,uint256)","678bbf24":"getEarningsAmountByGoodsIndex(uint256)","678d2204":"shouldFail()","678d6eff":"createFuel(uint256)","678d9758":"setTile(uint256,string,string,uint256)","678dd961":"getProviderClosed(uint256)","678ee795":"ComputationService()","678f4467":"allocateTokenForTeam(address,uint256)","678f7033":"set_percent_reduction(uint256)","679019ba":"freezeDeliverMultiStandalone(address[],uint256[],uint256[],uint256,uint256)","67907404":"recruitNarco(uint256,string,string)","6790d2b5":"getRoomInfo(uint256)","6790f3fe":"getAccumulatedDistributionPercentage()","67923240":"hatchsubscribers(address)","6793c8e1":"currentMilestone(uint256)","6793d383":"registryContractAddress()","67946ea4":"getIdMax()","67955ffa":"maxGIRL()","679577a5":"getEmployerFeedbackOn(address,uint256)","6795dbcd":"getAddress(bytes32,string)","67975213":"AddSWAndClaim(string,string,bytes32,bytes32,bytes32,string,bytes32,bytes32,address,uint32)","6797b106":"strikePricePctX10()","6799c0e0":"vpe_per_Keos()","6799d737":"releaseForEcosystem()","679a7a46":"WhoisOwner()","679aefce":"getRate()","679b4567":"preicoStartDate()","679b948b":"switchSplitBonusValue(address,bool)","679b9935":"setLeagueRosterContractAddress(address,address)","679c0d40":"invariantBroken()","679d0ecb":"getMetForEthResult(uint256)","679d38e0":"selfdestruct()","679dffb4":"getProfit()","679e1149":"AcoraidaMonicaWantsToKnowTheNewAnswerHash(bytes32)","679e5977":"EventRemoveAdmin(address,address)","679ebf1a":"transferTicket(uint256,address)","679f4d63":"CEEDCOIN()","679f699e":"EOSERC20(uint256,string,string)","679fecd6":"refillArray(address[],uint256[])","67a09c23":"payment(address,uint256)","67a0a550":"_cancelOrderWithMerchant(string,address)","67a19b20":"withdrawEthMaker(uint256,address)","67a1b7dd":"addTicket(uint256,uint256,uint256)","67a1bd55":"withdrawStuck()","67a1d653":"YOO_UNIT()","67a1f526":"curatorWrite(uint256,bytes32[])","67a2072c":"setEtherHolder(address)","67a2534b":"test(address[5])","67a26cbc":"DuqueBrewingCompany()","67a27811":"BonusGranted(address,uint256)","67a3eb65":"totalHardCap()","67a449b8":"getLastRoundData()","67a4e7c4":"isDecentBetToken()","67a52fdb":"purchaseGold()","67a59d91":"scheduleCall(address,bytes,bytes,uint256,uint256,uint8)","67a5cd06":"drip(address)","67a6ae62":"TOKEN_RATE_25_PERCENT_BONUS()","67a7390d":"fundTransferred()","67a7804b":"influenceByToken(uint256)","67a884e5":"latestBidder()","67a88f78":"createBitcoinAddressPrefixTask(bytes,uint256,int256,uint256,int256,address)","67a9c971":"tgrSettingsAmount()","67aa23e2":"getTicketsByOwner(address)","67aa50ae":"updateBrokerVerifierContract(address)","67aa863f":"setXto2()","67ab263a":"thisIsTheEnd(address)","67ab4381":"UnConf(string,address)","67ab5486":"GET_MAX_UINT256()","67aba225":"sellableToken()","67acd805":"lowerMinWager(uint256)","67ae9e8f":"hybridizationList(uint256)","67af1c81":"getRoundIndex()","67af1cff":"ethRec(uint256,uint256)","67af26fb":"transferOtherFrom(address,address,address,uint256)","67aff484":"setUserRole(address,uint8,bool)","67aff919":"autoreleaseInterval()","67b07d48":"entangleQuanticCloudIOTData(uint256)","67b0e070":"FaceTech()","67b14a21":"getProposal(uint16,uint16)","67b16407":"buyCup()","67b16cd6":"getRealRndMaxTime(uint256)","67b172c9":"Bloxxor(address,address,address,uint256,uint256,uint256)","67b1f5df":"setExchange(address)","67b21506":"claimTokenReserveDevelop()","67b220a5":"unblock(address)","67b26cab":"getLastMaxInvestments()","67b327fa":"proposeMilestones(bytes)","67b40639":"Dain()","67b50af9":"gasAmount()","67b5496a":"loseWager(uint256)","67b55bf9":"getClickMetadata(uint256)","67b65656":"setStateStartTime(bytes32,uint256)","67b78d00":"fromHexChar(bytes1)","67b7a4aa":"START_PRICE_IN_CENTS()","67b7c034":"on()","67b7d525":"getBlockPointer()","67b830ad":"fillOrder(uint256)","67b886e8":"left97(uint256)","67bb474f":"allowBundling()","67bb6d63":"maxWiteList()","67bc480e":"MYSTERYCLASSICCOIN()","67bd15e3":"contractInitializationTime()","67bd69a6":"getLastDuel2()","67be0854":"partyHash(address,address,address,address)","67be5eac":"claimLeftTokens()","67be97a5":"BYToken()","67bea493":"whitelistedPools(address)","67beaccb":"scheduleCall(bytes)","67bfc445":"AddNewChallenge(uint256,uint256,uint256,uint256,uint256,bool,string)","67c21fe5":"setFiscalVerify(uint256,bytes32)","67c25a14":"TeamCreated(uint256,uint256[])","67c281a9":"validateContentHash(address,uint256,bytes32)","67c2a360":"authorizeUser(address)","67c33c80":"getInt8FromByte(bytes14,uint256)","67c353b3":"LKCTotalSupply()","67c36757":"IranToken()","67c3a6d9":"Khatamor()","67c3ad8e":"burnStake(uint256,address)","67c3e25e":"revokeAccessDeploy(address,address)","67c45872":"ZzStandardToken(uint256,string,uint8,string)","67c51be7":"viewTokensSold()","67c5d6b1":"multihash(bytes32,string)","67c623cf":"getTokenMetaData(uint256)","67c6e39c":"convert(address,uint256)","67c7f3a8":"setBwValidCaller(address)","67c84919":"issueByPartition(bytes32,address,uint256,bytes)","67c9b017":"getEthPrice()","67c9d266":"freezeUntil(address,bool)","67ca1fdf":"market_communityStorageVault()","67ca2298":"updateTokenName(uint256,string)","67cab29d":"testGetAbiVersion()","67cb103a":"PartnerUrl()","67cb61b6":"getChoice()","67cb9316":"get_header(uint256)","67cc4882":"TokenHolder()","67cd3f64":"UNLOCKSTART()","67cd5323":"PUBLIC_SALES_SPECIAL_USERS_RATE()","67cd64dc":"LENDXCOIN()","67cdbe8f":"newShip(uint16,uint256,uint256)","67cdc1c2":"percentageToTeamEthContract()","67ce38fb":"Vertex_Token(uint256,address)","67ce940d":"getOverhead()","67cf17c2":"transferPrimordialTokenFrom(address,address,uint256)","67cf7d9c":"createTeamTokens()","67cf91c9":"lastKickoffDate()","67cfdfc9":"getBrokerIncoming(address)","67d0661d":"doPause()","67d13f27":"receiveFromVendor(address,bytes32)","67d15775":"PromToken()","67d22967":"set_iconiq_pre_kyc_bonus_numerator(uint256)","67d326ef":"finalizeFundAddress(address)","67d3d0ec":"changeEthBalance(address,uint256)","67d3eff4":"setTeamWallet(address,address)","67d41253":"secondCheckpoint()","67d42a8b":"release(bytes32)","67d49909":"secondWinnerTimestamp()","67d4e98c":"RemoveShare(address,uint256,uint256)","67d4f541":"window1TotalSupply()","67d5fae1":"getPremiumCount()","67d6bcbf":"distributeBonusTokens(address)","67d6d142":"getPI_edit_19()","67d96c24":"compensatePreSaleInvestors(address[])","67da2831":"revealHiddenPosition(uint32,int64,bytes16)","67da299b":"mcrAmmountForGas()","67da7b7a":"LabCoin(uint256)","67dbaf93":"updateValueAndBurn(uint256,uint256)","67dbf587":"Bridge(uint256,uint256,address,address)","67dcec06":"WealthInternet(uint256)","67dd1730":"destPrecision(address)","67dd74ca":"buyTicket(uint256)","67dd7bb4":"tradingLocked()","67de698d":"adjustCap()","67de80db":"createMultiple(uint256[],uint256[],uint256[],address[],uint8[])","67de81e8":"fundSucceeded()","67deced2":"checkIn(uint256,string)","67df1187":"buysubscribers()","67df5189":"archiveCrowdsale(uint256)","67dfe2d3":"addEthForSell()","67e04a22":"initInviteAddr(address,uint256)","67e06858":"Add()","67e0badb":"getNum()","67e0d78f":"sendFundHomeAmt(uint256)","67e13ee0":"getDeveloper(address)","67e1aee9":"setStage1()","67e1c253":"getMyInviteCode()","67e22888":"bigMoney()","67e2a647":"createAwardTokens()","67e2d2ad":"wireInvestment(address,uint256,uint256)","67e33df5":"SwftCoin(uint256,string,uint8,string)","67e404ce":"sender()","67e4373f":"CARIToken()","67e445d9":"FOMO()","67e476d7":"getPublicSaleInfo(address)","67e4ac2c":"getAssets()","67e4d41d":"ProdAToken()","67e523bb":"iPeso()","67e53196":"getAuthByCode(string)","67e54367":"battleContractAddress()","67e5f18c":"getCurrentTierRatePercentage()","67e6869d":"Withdraw_4()","67e6bc2e":"hash(string,uint256,uint256,uint256)","67e6bf06":"testPresaleRefund()","67e70e99":"setselfrdroplist(address[])","67e7646f":"removeDelegate(address)","67e817f4":"XOV()","67e828bf":"source()","67e874c0":"testMeta(uint256)","67e8cd0f":"bidOf(bytes32,uint256)","67e8d3d2":"bonus2()","67e8f6e1":"_multipleTransfer(address,address[],uint256[])","67e902c7":"right92(uint256)","67e902d9":"ListingBought(uint256,uint256,uint256,address)","67e933f6":"checkCustomer(address,address)","67e94ae0":"listingFeeInWei()","67e988e7":"bountyAvailabilityTime()","67e9b860":"CreateSwap(uint256,uint256,bool,address)","67ea2fa0":"tasksSize()","67ea43bd":"producedBronzeCaps()","67eae672":"sendCoinFrom(address,uint256,address)","67eb5fbe":"_train(uint256,uint256,uint256,uint256)","67eb9bab":"createIssuerContract(string,string,string,uint256,uint256)","67ec00c0":"depositFrom(string,address,uint256)","67ec68c4":"winningNumbersFor(uint256)","67ecb82d":"transferAndLock(address,uint256,uint256,uint256,uint256)","67eccc12":"founderTokenWithdrawnPhase2()","67ed583f":"addPresaleHolder(address)","67edad0a":"preSaleSecondEtherCap()","67ee5f09":"getTotalDividends()","67eeba0c":"dailyLimit()","67ef5a37":"debugStuff()","67ef5cb9":"setPrice(uint32,uint32)","67efbab1":"changeAssignedAdmin(address,uint256,string)","67f01c04":"ETH(uint256)","67f04688":"LIMIT_TRANSFERS_PERIOD()","67f06f78":"_checkPixelAboveRight(uint256)","67f12ecf":"validate(address,uint256,uint256[101][])","67f17405":"majorEvent(bytes32,bytes,uint256)","67f4224f":"eventPause(bool)","67f690b5":"hasRequestedForMigration()","67f6a258":"verifyCert(bytes32,bytes32,address)","67f718a9":"getTokenIds()","67f76863":"EnishiCoin(address[])","67f809e9":"DynamicPyramid()","67f83481":"isFounderUser()","67f8a8b8":"emergencyRefund(address,uint256)","67f8ca42":"usingCanvasBoundaries()","67f8df84":"playerId(uint256)","67fad28d":"RCLTOKEN(uint256,string,string)","67fbb7ba":"ownerAddSanSlotBatch(address[],uint256[])","67fbd289":"destroyTokens(uint256)","67fc1c6a":"validateProposedMonarchName(string)","67fd9da3":"multicastTransfer(address[],uint256[],uint256[])","67fdc2fe":"CricketToken()","67fdd509":"setIdRange(uint256,uint256)","67fdff26":"REQUIRED()","67fe5a0c":"accepted()","67fe6b47":"contractIsCompleted(string)","67fe6f0e":"checkOverExceed(address)","68019d75":"COCTokenBase(uint256,string,string,uint8)","6801db98":"devoteToCar(string)","6802c8a1":"FreeCoin()","6802ff77":"seedSupply_()","6803641c":"claimAllTokensForInvestor(address)","680478b1":"offerAsSacrifice(address)","68049361":"teamWallet_4()","6805b84b":"getPaused()","680660d4":"bulkAddCompany(address[],uint256[])","6806fdce":"assignGenesisAddresses(address[])","6807b84d":"Timebound(uint256,uint256,bytes32)","6807f752":"deleteBuyRequestInternal(uint256)","680819eb":"setRate(bytes32,uint256)","680a50cb":"shortenDeadline(uint256)","680add7b":"preSoldSharesDistributed()","680b0c5c":"tresholds(uint256)","680b3bdf":"migrateAll(address[])","680b5eba":"setHouseAddressTwo(address)","680b9d49":"getStakedAddresses()","680bd2f4":"RiseCoinToken()","680c26bc":"ATP(address,address)","680caed2":"Contract(address)","680def61":"market2019TokenCreated()","680e354a":"setSaleWindow(uint256,uint256)","680e6c9b":"receiveTokens()","680eba27":"GEN0_CREATION_LIMIT()","680f07b4":"getinitializeFeeWindowIdValue()","680f0938":"pay_dividend(string)","680f0eda":"set_harvest_amount(uint256)","680fb685":"OpenClose(bool)","6810e139":"shopSack()","68111cce":"getProduct(string)","6811444a":"getLastComment(address)","68116177":"getbalance(address)","681185ab":"_extractRawResource(address,uint256,bytes)","68118e95":"numberOfBlocksToEndLimitationPeriod()","6811c332":"distributeTeamTokens(address,uint256)","681232ad":"cosigner()","68125a1b":"isFriend(address)","681312f5":"setRoundLength(uint256)","6813947f":"contributionOf(uint256,address)","681478ab":"LegacyRepToken(address,uint256,address)","68155ec1":"transferTokens(address,address,address,uint256)","6815c19c":"DropdCoin()","6815c992":"grantPermissionP(address,address,bytes32,uint256[])","681617c7":"changeEscapeCaller(address)","68163034":"defaultTimeoutLength()","6816521a":"teamAllocation()","6816d920":"guaranteedBuyersLimit()","6816fcd6":"evMgmtDistributed(address,uint256,uint256,bool)","6817031b":"setVault(address)","68171516":"assetMethodIsAllowed(address,bytes4)","68177733":"MixinToken()","6817c76c":"mintPrice()","681833d9":"bindAddr(address,bytes)","6818da44":"setPlatformManager(address)","68197360":"getVotes(uint256,address)","681b23dd":"senderETH()","681b3314":"get_pre_kyc_iconiq_bonus_numerator()","681b5651":"setEthToUSDRate(uint256)","681b742f":"changeFund(address)","681c2ad0":"getTknOfferPrice(uint256)","681c3251":"addTotalSuply(uint256)","681c7808":"setMinTime(uint40)","681c7e2b":"VAAToken()","681cb449":"VIcoin()","681ce98a":"getNextPrice()","681d52de":"tokenImporter()","681d8345":"getATMTotalSupply()","681e237d":"CommonToken()","681e3356":"transferBankOwnership(address)","681f01f2":"IsICOOver()","681f3e6d":"getUsername()","681f6486":"SimpleBid(address,uint256,uint256)","681f8116":"makeTradeable(uint8)","681fd129":"addInvestContract(address)","681fe70c":"isEmpty()","68203417":"thirdStage()","6820f8d2":"setOneContract(uint256)","68213256":"crr()","68216ca7":"addNewBranchInEpisode(uint256,uint256)","6821928b":"AddAuthority(address)","6822abae":"getMinimumCallCost(uint256)","68234a27":"getTransactionDescription(uint256)","68240412":"calculateWeiForStage(int256)","68250963":"preICODeadline()","682594db":"totalAllowedFreeze()","68259880":"ChangeOfRules(uint256,uint256,address)","6825c843":"_address(uint256)","682677e8":"TunDrMahathirMohammad()","6826ebf8":"r(bytes)","6827b9db":"getMonsterGender()","6827e764":"devFee()","682806a0":"ICOContract()","68281708":"restrict(address)","68283f4d":"claimBets()","6828d549":"rejectContribution(bytes32)","68296073":"setSnowflakeAddress(address,address)","682a5e89":"returnDuration(uint256)","682a90d2":"Store(bool,uint256)","682a9449":"setCustomerService(address,address,bool)","682ab756":"LogItemRegistered(address,uint256,uint256,bytes32,bytes32,bytes32)","682b6706":"___Kill()","682b7100":"deleteRoom(uint256)","682baa3a":"HATCH_COOLDOWN()","682bc77e":"setStarterPackOnSale(bool)","682bea5c":"setCallTable(uint256,uint256)","682d1138":"failExecute()","682d3bb0":"pdfCertificateProof(bytes)","682e1bb0":"isSTOProposed()","682e60a9":"presses()","682ed9ea":"sanMaxAmount()","682f3d36":"OrderMatch(address,int256,address,int256,uint256,uint256)","68302467":"paySeller(uint256)","68306e43":"dividends(address)","6830cdc4":"getJobCount(address)","6831c169":"totalPayedOut()","6831e272":"mintTokens(address,uint256,uint256)","683328bf":"takePet(uint64)","6833716f":"ProofShrimpFarmer(address)","6833d54f":"contains(string)","6833f60d":"triggerPause()","68342b33":"ownerInfoOf(uint256)","683431e2":"SelfDesctruction()","68347fdf":"ICO_MIN_DEPOSIT()","68348dfe":"_newGame(bytes32)","6835df3e":"SFT_PER_ETH_BASE_RATE()","6835f32c":"build(bytes)","68365eb7":"NewProject(address)","683674dc":"disconnectOrderUser(address,address,uint256,address)","683799e6":"setMaximumPurchaseFraction(uint256)","6837ff1e":"newContract(address)","68381874":"Trade(address,uint256,address,uint256,address,address,bytes32)","68381b96":"getHighestUnitPriceIdxFromSell()","68388b80":"banAccounts(address[])","6838e7c5":"PrinzeToken()","68393a4c":"getBonusByTime(uint256)","683a6858":"Recoverable()","683ad727":"getDeed(uint256)","683b4184":"inflation_complete()","683cde49":"upgradeBalanceOf(address)","683cecc2":"addressFunc(address)","683d4a4b":"minWithdrawalCoolingPeriod()","683d69e4":"checkEligibility(bytes32,address,address)","683de015":"switchUpgradable(bool)","683e0bcd":"ethPriceInUsd()","683e2929":"getPSlotLength(address)","683e3451":"CioCoinERC20Token(uint256,string,string,uint256)","683e70b6":"createWhaleTokens(address,uint256)","683f7f27":"removeParticipant(uint256)","68402460":"scheduleCall(address,bytes4,uint256,uint256,uint8,uint256)","68404cd9":"setValueSome(uint256,uint256)","6840721d":"searchReport(string)","6840c67d":"vestPartnerEquityReserve()","6840f8e8":"returnEth(address,uint256)","68412058":"getRank06()","68412063":"distributeTokens(address,uint256,uint64,uint64,bool,bool)","6841f253":"currentRoundLocked()","6841fd27":"remining(uint256)","68428a1b":"saleActive()","68437b58":"bet_purchased(address)","6843aef9":"increaseLockReward(uint256)","68445ce1":"insertNodeBefore(uint256,uint256,address)","68447a55":"fetchFunds()","68447c93":"referrer()","6844ab43":"testControlCreateSameItemId()","68458fcf":"assignInitialAddresses(address[],address)","6845950f":"getScriptActionsCount(bytes)","6846187f":"farmItems(address[],uint256[])","684641b4":"cumulativeInverse(uint256,uint256,uint256)","684649a6":"createProxy()","6846fe64":"_sellCallToClose(uint256,uint256,uint256,uint256,address)","684876a1":"migratePlayerRoundsData(uint256,uint256,uint256,uint256,uint256)","6849cb9d":"transferIssuer(address)","684b369e":"everisumToken()","684b49f5":"PriIcoSale2(address,uint256,uint256,address,address)","684bd9d6":"getRemainCount(address)","684d63bf":"mintAuditApproval()","684d9a04":"quarterSecond()","684e2345":"AishaCoin()","684ecd59":"getData_9()","684edea8":"ponziPriceInWei()","684efc40":"TravelNationCoin(uint256,string,uint8,string)","684f19c9":"WorldCupFactory(uint256)","684fa447":"AppAdded(address,string,address,uint256,bool)","684fbfdb":"sinLimited(int256,int216)","68503cdf":"getAvailableBalanceByAddress(address,address)","68504158":"toggleTransfers(bool)","68507757":"faucetBB0()","6850fa6d":"onoff()","6853367f":"withdrawDevelopersCut()","68533a1d":"closeUndercollaterizedPosition()","68536341":"ratePerOneEther()","6853920e":"removeRole(address,bytes32)","6853e3a4":"setToKnown(address)","685485fb":"eth_sent()","6854df55":"scannedDiamondCaps()","6854f668":"buyDragoOnBehalf(address)","6855ded3":"WHITELIST_END_DATE()","685705ae":"getWeiValue()","68573107":"batchMint(address[],uint256[])","6857ab40":"seq()","6857cb06":"manualTransfer(address,uint256)","68581ebd":"getJobs()","68583bc0":"FC1Token()","68586e57":"setPet(uint8,address,string,uint8,uint16,uint16,uint16)","6859274b":"checkMembership(bytes32,uint64,bytes)","6859d08f":"addToActiveGroup(address)","6859dc10":"rejectRequest(address,uint256)","685a73e0":"claimHodlRewardsFor(address[])","685adf5e":"ALDEToken(uint256,string,uint8,string)","685ae2a9":"itoEndTime()","685b2d8f":"transferPermissions(address)","685b47c7":"updatePresaleNumbers()","685c234a":"checkAuthorization(address,address)","685c60de":"transferERC23(address,uint256,bytes)","685ca194":"withdrawalAllowed(address)","685d1135":"recyclingRemainToken()","685e2486":"migration(address)","685e78fb":"SecondPriceAuction(address,address,address,address,address,uint256,uint256)","685ffd83":"registerNameXname(string,bytes32,bool)","6860dc1f":"isRefAvailable()","6860fd58":"Fees(uint256)","686174ec":"QQQTokenBase()","6861d3b8":"firstStageStartsAt()","68621711":"assetMeta()","68624bd7":"lockedValueOf(address)","68639a29":"setActivation(address)","6863d3c7":"CreatedIRC(address,uint256)","68649c8a":"setTiersInfo(uint8,uint256[],uint256[],uint256[],uint8[3][4])","68654ef8":"bonusBalanceOf(address)","68660b93":"updateDonateTokenAddress(address,uint256)","68664430":"supplyDAICO()","6866537d":"getCardPrice(uint256)","6866566a":"Priced(uint256)","6866da59":"_lockOrUnlockAmount(uint24,uint256,uint256,uint256,uint256,uint256,uint8)","686790e5":"freezeSignatureChecker()","6867edeb":"getBuyOrderPrices()","68690dd0":"NeedRefresh(uint256)","68699224":"offlineAdjust(uint256,uint256)","6869b20e":"saveToken(uint256)","6869fb30":"maxWeiTier0()","686b2812":"addWhitelistUsers(address[])","686b88cd":"calculateWinnerGameType1(uint256,uint256)","686caf04":"lastBlock_a1()","686d2d5c":"getCurrentBonusPct(uint256)","686d5e00":"unRegisterCampaign(uint256)","686da8ab":"UpdateRecord(uint256,address,uint256,bool)","686e2284":"isCosmosSale()","686e8aaa":"GetMoney()","686f21ba":"gainKarma(int256)","686f2c90":"collectAllFees()","686f4564":"redeemedCards()","686fa3f7":"getGameId(address,string,string,uint16,uint64)","68700891":"RLPReaderTest()","6870c65a":"InitialRateChange(uint256,uint256,uint256)","6870ef86":"getCurrentTokenFee()","68715a75":"GCCHToken()","6871819b":"getUserCollegeEducationDetails(string)","6871d26b":"addMeterPoint(int256,address,int256)","6872e300":"COPPER_AMOUNT_SKL()","68742da6":"withdrawFunds(address)","68750bbc":"sendReserveTokens()","6875b6eb":"changeRestrictions()","6875b746":"updateRelease(uint256)","6875c319":"escalateDisputeToMediator(uint256)","687711ec":"s25(bytes1)","6877dca7":"Token1_Transfer(address,address,uint256)","68788868":"decodedAmount()","6878ac7d":"applicableRate()","68794b87":"setState(string)","687981ac":"getValidatorIndex(uint64,address)","687a46c4":"upgradeQualificationByEther(uint256)","687a48a1":"getBurnedCarCount()","687bf382":"_useName(address,bytes32)","687c317c":"setTokensUsedForReinvestment(uint256)","687cc2fd":"preSaleTokensAvailable()","687cde1a":"tokenSelled()","687d493c":"EverOwnedTokens(address)","687d5aa9":"setBuyAllowed(bool)","687db864":"END_ICO_TIMESTAMP()","687e6b5f":"MavenCoin()","687e6f44":"withdrawEthers()","687f8427":"devCATDestination()","68802712":"get_hedge()","688057fc":"registerWalletForFeeSharing(address)","68808769":"backers(address,uint256)","6880ff5b":"secondReserveWallet()","6881385b":"payday()","6881f6f1":"minTradingStartTime()","688225d6":"onemonth()","688257e0":"SmartContractWorkshop(string)","688263d7":"largestPenisOwner()","6882d481":"priceStar4()","68832d14":"___proxyTarget()","6883477f":"canBePurchasedByEMONT(uint16)","688511bb":"timeoutBlock()","688521b4":"coinsIssuedTotal()","6885c572":"allowByDelegate(bytes8,bytes8)","6885edcd":"desiredPrice(uint256)","6885f63b":"TrustToken()","6886bf1c":"mostSent()","6886ce25":"ForkEthereum()","68873375":"CBRToken(uint256,string,string)","6887398d":"getContestTeamCount(uint32)","68879e5f":"RecoverySha3(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","68882b30":"buyCrab(uint256)","68888300":"updateAngelCardSeries(uint8)","68889db8":"setFreezingPeriod(address,bool,uint256)","68894a16":"changeMaxContribution(uint256)","68895979":"getUint256()","6889cf86":"icoOver5()","6889d646":"transferMoneyToOwner()","688a54dc":"ATxAsset()","688a7044":"CryptoRoulette()","688abbf7":"myDividends(bool)","688af37f":"QRL_Token()","688b410f":"sendTokenUpdate(address,uint256)","688b5c2b":"isMiningWarContract()","688ba636":"walletTeam()","688bf035":"calculateUSDcValue(uint256)","688cdba8":"ownerRate()","688cf404":"setAyantDroitEconomique_Compte_4(uint256)","688d3922":"isHardCapReached()","688d54b7":"getLLV_edit_34()","688dcfd7":"setProofType(bytes1)","688def07":"MMOToken()","688e69d8":"ownerPowerUpContract()","688f5ed2":"gracePeriodAfterRound1Target()","688fad5d":"updateIdentitySocialURL(address,bytes32)","68907360":"setRewardsContractHash(address,bytes32)","68915c14":"seedInvestors()","6891656e":"buyWithCustomerId(address,uint256,uint256,uint128,uint256,bool)","68927cd2":"isValidBNBContribution()","68934e54":"approveBurnDelegate(address)","6893cc22":"toUint(bytes32)","6893e8d2":"_setLimits(uint256,uint256)","6893f63f":"getTokensPerEth()","689490a0":"whitelistedAddresses()","68955fb1":"icoPhase()","6895adbb":"_addModule(address,bytes,uint256,uint256)","68963dee":"ICOMinTresholdReached(uint256)","68968564":"SaveYouAndMeToken()","6896a342":"ADVISOR_STAKE_ONE()","6896b999":"xConvertPrioritized(address[],uint256,uint256,bytes32,bytes32,uint256,uint256,uint8,bytes32,bytes32)","6896ef4b":"currentRoundIndex()","6896fabf":"getAccountBalance()","68970ab4":"Created(address,address,uint256,bool,uint256,string)","689786d0":"test_oneValidEqBytes32Message()","6897a1a2":"startingCostToPress()","6897c1b6":"PrepareToStart(string,uint256,uint256,uint256,address,address)","6897e974":"removeWhitelistAdmin(address)","689827b0":"modInverse(int256,int256)","6898730f":"eip20Transfer(address,address,uint256)","6898f148":"beforeSale()","6898f82b":"play(uint256)","68999d76":"exportTank(address,uint32)","6899d8c2":"recoverAll()","6899dac5":"finishVotingTeam(uint256)","689a4608":"Test20()","689a521d":"changeContractState(bool)","689b2d24":"AcceptsElyxr(address)","689b3e2d":"Moonraker(address,address)","689b732c":"FundValue(uint256,uint256,uint256,uint256)","689da08e":"dad()","689dcb02":"Buyin(address,uint256,uint256)","689e87c1":"GIRLBUFFERSIZE()","689effad":"BookingTimeUtils(address)","689f2456":"partial_refund()","689f3f99":"unclaimedPlotPrice()","689ffd82":"addressSalesSupply()","68a1e07f":"_currencyToToken(bytes,bytes)","68a287d8":"getTeamVault(address)","68a29a31":"balanceEthPrivate(address)","68a52509":"getLastOrderId()","68a52851":"setTokensContract(address)","68a596c7":"ownerToTokenIds(address,uint256)","68a59805":"setPayoutDistributionHash(bytes32)","68a67030":"finalizeSale1()","68a6b26b":"setWeiRaisedInPresale(uint256)","68a6e74b":"preICO()","68a72fba":"crowdTarget()","68a7d7ea":"setAgriChainData(address)","68a7e1c4":"setDelegadoDeEscuela(bytes32)","68a7effc":"getOrCreateCurrentFeeWindow()","68a7f6d6":"playerFastFlight(uint256,uint16)","68a8659d":"SellOrdersOf(address,uint256)","68a8c5eb":"WyvernDAOProxy()","68a958bc":"payrollSystem()","68a9674d":"depositFrom(address,address,uint256)","68a9de13":"changeEndtime(uint256)","68a9f31c":"secondOwner()","68aafcd9":"setUsageReportingAddress(address)","68ab3db2":"createDefaultGen0EtherDog(uint256,address,uint256,uint256)","68ab56ca":"get_bounty_count(uint256)","68abf22b":"BAC(uint256)","68acb7b7":"TOTAL_COMMUNITY_ALLOCATION()","68acfcbb":"changeLinkedAddress(address,address)","68ad1412":"registerUser(address,bytes32,address,bytes32,bytes32)","68ad6719":"valueChanged(string,string)","68aee9e8":"wed()","68af1378":"playerGuess(int8)","68af4971":"registerListening()","68afc7c4":"test_rewardPoolShare_isTranscoder()","68b017ec":"sarahtoken()","68b07ebb":"_getMaxAuctionSeconds()","68b0d82e":"TransferredGNS(address,address,uint256)","68b1a6d0":"GetBestWalletAddress(uint8)","68b2cee0":"removeAssetsOwner(address)","68b35396":"gemPerMiner()","68b43f38":"privateLockTime()","68b47d87":"SSOTHEALTH_FUNDS_ADDRESS()","68b49b78":"changeKey(address,address)","68b51ac7":"checkValidSignature(address,bytes)","68b5c351":"tokenTrueUSD()","68b670af":"wmulfloor(uint128,uint128)","68b6d55d":"potSize()","68b85aa5":"maxTimeout()","68b8c5a1":"numberOfAuthorizedPayments()","68b91201":"createInvestorTokenTimeLock(address,uint256,uint256,address)","68ba170c":"isRegisteredTranscoder(address)","68ba745c":"releaseTeamVested()","68bae934":"getAuctionItem(uint256)","68bba4d0":"HARD_CAP_T()","68bd6efa":"getContract(address,address)","68be7887":"getOrganisationByAddress(address)","68be8007":"_updateRegionOwner(address[16],uint256,address)","68be948d":"setRegisteringContractAddress(address)","68bee793":"LevelWhitelistedIICO(uint256,uint256,uint256,uint256,uint256,address,uint256)","68c14a61":"AirdropCentral()","68c197dd":"isWorkerPoolRegistered(address)","68c31649":"checkWithdrawAmount(address,uint256,uint256)","68c49cc9":"collectOtherTokens(address,address)","68c4cac6":"tokensPerEther1()","68c4eb74":"changeInvestorsAddress(address)","68c51f8e":"lhkjTNB()","68c64670":"RapidProfit(address)","68c646f3":"LifeFactor_i()","68c6b11a":"subtract(address,uint256)","68c6f45e":"issuedByStabilityBoard()","68c84260":"addEmployee(address,address[],uint256)","68c92b51":"doCall(address,uint256,bytes4,bytes32[])","68cbce31":"setWinner(uint256,uint256)","68cdafe6":"tokenTransfer(address,uint256)","68cdf759":"getReffAdd(string)","68ce77d0":"grant(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool)","68ce90ac":"handlePayment(address,uint256)","68cf5cf8":"setAdvisor(address)","68cff8a9":"notEmpty()","68d06724":"weisSoftCap()","68d12938":"setDonatorReward(uint8,uint256[],uint8)","68d155a0":"remove_participant()","68d317f1":"buildGame(address,string,string,uint256,uint256,uint8,uint8,uint8)","68d324e7":"changeCrowdSale(address)","68d32aed":"getVerifiedHashID(address,bytes32)","68d3fb7b":"initRegister()","68d5a014":"reveal(uint256,uint8[5],bytes32)","68d5cb1a":"purchaseBuilding(uint256,uint256,uint256)","68d64514":"getRemovableIdArrayItems(address,uint256,string,string,string)","68d6a790":"timeOfreservations(address)","68d77366":"Coinlancer()","68d7e4b5":"addDeal(uint256,string,string,uint256,string,bytes32,string)","68d7f8d6":"nextPrice(uint256,uint256)","68d830ae":"get_unlock_time()","68d85d3e":"CloudexchangeCrowdsale(uint256,address)","68d88c25":"serviceRedirect(address,address,uint256)","68d89792":"setCatAttributeValue(uint256,uint256,string)","68d967dd":"changeDoublr(address)","68da480b":"maxWeightBonus()","68da5ee5":"guess(uint256[])","68dae6bb":"RoundClose(uint256,uint8,uint256,bytes32)","68db96a6":"whitelistBonusRate()","68dbc6c1":"fortune_bid(uint256)","68dc3926":"unchanged(address)","68dc9528":"giveTokens(address,uint256)","68dd43f6":"maxNumInterests()","68df0d53":"_removeTokenFromOwnerEnumeration(address,uint256)","68df4dda":"removeWhitelistedTokenAddr(address)","68df5ca4":"testMinReturn0WithoutReturn()","68e03bf9":"setEthEurRate(uint256)","68e114db":"PFG(uint256,string,string,bool)","68e12fa8":"addressCallWithArray(address,address[3])","68e1569a":"parking()","68e1bba4":"eth_ratio()","68e1f526":"WeMediaChainToken()","68e2076a":"Hub()","68e39aac":"proxyWorking()","68e453ed":"totalSaled()","68e47f59":"accept(address,bool)","68e4bd99":"testSetBitSuccess()","68e5a07e":"getExcludes(uint256,uint256)","68e5e22f":"buyAnalysis(address)","68e67402":"RoomPlayersAdd(uint8,address,uint256,uint8)","68e757a0":"create_public_sale_token(address,uint256)","68e76403":"getTotalFeesCollectedCount()","68e7bdba":"disableApi(address)","68e7e309":"_saveVerification(address,address,uint32)","68eb59b0":"startGladiatorWithCoin(uint8,uint8,address)","68ebd450":"bioLock()","68ec8446":"RentartoICO()","68ec9dba":"emptyPendingUserList()","68eca613":"numShareholders()","68ecabcf":"ankcwdsleToken()","68ee137e":"bonusClaimedTokens()","68ef7946":"zazSupply()","68ef8661":"isValidParticipant(bytes32)","68efa030":"Dao1901()","68efb367":"exile(uint8,uint8,uint8,bytes4)","68f04bbb":"openAirDrop()","68f06b29":"redeemable(bytes32)","68f0bcaa":"atomicize(address[],uint256[],uint256[],bytes)","68f15aac":"DMChainToken(string,string,uint8,uint256)","68f16293":"transferCooldown()","68f169e1":"sellCut()","68f269b4":"RATE_ETH_TXK()","68f2ab8e":"Currency(string,string)","68f2c86a":"changeUserPerms(address,bool,bool,bool)","68f2d6e2":"GEN0_MINIMAL_PRICE()","68f319b1":"placeBet(uint8,bool,uint256,uint256,bytes32,uint8,bytes32,bytes32)","68f399f4":"BetSetAnswer(uint256)","68f5aa0f":"setShareholderDB(address)","68f5ccdf":"devFeePaid()","68f5d173":"addAdminister(address)","68f65f02":"ChangeShownDenomination(bool,bool,bool,bool)","68f67330":"finalizedCrowdfunding()","68f6e75f":"percent1()","68f7ef1b":"BLKToken(address)","68f88a26":"getMatchSummarizeInfo(uint256)","68f8957a":"setAyantDroitEconomique_Compte_1(uint256)","68f8fc10":"buyToken(address,uint256)","68f91814":"mainMultisigEther()","68f9dab2":"hash(bytes,bytes,uint256)","68fa8134":"removeAdministrator(address)","68faaa6f":"getTotalSellCount()","68fad504":"burnExtraTokens()","68faecdb":"depositedMYB(address)","68fb81b7":"iCoTokensSold()","68fbbab8":"giveMultipleItemsToMultipleRecipients(address[],uint256[])","68fbd0a8":"TPTSchedules()","68fcb6ee":"purchaseCard(uint256,uint256)","68fd0455":"contractorCancel(bytes16,address,address,uint256,uint256)","68fd22d3":"_addToList(address[],address)","68fe4405":"getBondHolder()","68ff8c4c":"UserList()","68fff456":"blackMask()","69008fb6":"buyTileAuction(uint8,uint256,address)","6900a3ae":"toString(uint256)","6901f668":"validate()","690252c8":"addSshKey(string)","69025b5f":"_addTokenToOwnerEnumeration(address,uint256)","6902a416":"AUMXToken()","69030397":"addLocker(address,address)","69032f15":"cantSetReferrer(address)","69043895":"exOwner(address)","6904c104":"getCampaignValidity(bytes32)","6904c94d":"company()","6904efc5":"BeatTokenIcoPhase3Started()","6904f583":"econVestingStage()","6905877a":"totalOwedForApi(uint256)","69061355":"claimOwnership(uint8,bytes32,bytes32)","6906679b":"getHistory(uint256,uint256)","6906a137":"checkCharger(uint256)","69070772":"MyFreeCoins(uint256,string,uint8,string)","69071418":"poolCLock()","6907baa9":"Campaign(address,address,address)","69081199":"WithdrawFunds(address)","69086c21":"a(bool,bool,bool)","6908d99c":"Extract(address,uint256)","6908ea00":"_checkVotes(uint256,bytes32,bytes32)","6909f5bf":"generateTokenWithAttributes(string,string,string)","690a946b":"getProjectEndDate(uint256)","690b1897":"AragonTokenSale(uint256,uint256,address,address,uint256,uint256,uint8,bytes32)","690c11d5":"getcoursesLenght()","690c5de8":"phase4Cap()","690cf0d1":"preSaleStarted()","690d0b1d":"STARCrowdsale()","690d23be":"getItemAmountOf(uint256,address)","690d3750":"lockBalances()","690d8320":"withdrawETH(address)","690e1d22":"showLockNum(address,address)","690e7c09":"open(uint256)","690eb3f8":"getTicketSumToRound(uint256)","690f2f8e":"_addTokenAddress(address)","690f411b":"VividoTokenTMP()","690f4559":"createPersonalDepositAddressFor(address)","690fa5df":"getPlayerRefById(uint256)","69102190":"checkCount(address)","69111865":"LINDOToken()","69115768":"hasItBeenReleased(uint256)","69129b4f":"StandardToken(uint256,string,string)","6912c8ba":"thirtyPercentWithBonus()","69132d43":"useBalanceOf(address)","69132f72":"SALE2_END()","6913a63c":"addGuard(address)","6913d82d":"adminSetBlock(uint256,uint256)","6914db60":"tokenMetadata(uint256)","6914f40f":"getPI_edit_27()","69161b9e":"addAddressToGrantAccess(address,uint256)","6917fd5e":"BONUS_ICO_PERIOD_ONE()","6919d09a":"Y(uint256,uint256)","6919ff17":"test_insert_findNoHintAtPosition(int256)","691a38ab":"canBeWhitelisted(bytes32)","691a3f64":"buyFrom(address)","691a5842":"totalEtherRaised()","691ae7c9":"setCandyPowerToken(address)","691b7ce0":"transferCMO(address)","691ba73a":"race()","691bf023":"LockTokens(address,uint256,string)","691bfc89":"goods(uint16,uint256)","691c65d4":"mintItem(address)","691c71bd":"endTime2()","691cdb51":"CoinoorCrowdsale(address,address,address,address,address,uint256)","691d58e7":"_applyRefund(uint256)","691d933a":"getDeedByAddress(string,uint256)","691de4a4":"add(string,bytes32)","691e9961":"we_test_token()","691ed382":"THIRD_TIER_SALE_START_TIME()","691edfda":"devAccount()","691f2216":"User_1()","691f3431":"name(bytes32)","691fb8ea":"jumpIn()","692058c2":"dex()","69205dfc":"TUNEZ()","6921278a":"rateFee()","69215eb3":"ethMined()","692193cc":"MarketplaceAccessor(address)","6921af97":"payOutBounty(address,address)","69229b43":"ChangeOwnerContract(address)","6922eb06":"sellPackToAddress(uint16,uint16,address)","692345ee":"elapsedPeriods()","692397a4":"testIssueTokens()","69244c55":"getIcoReward(uint256)","69245009":"cage()","6925ad77":"multiplex_target(address)","6925b015":"contributionBy(address)","6925ebb9":"fluxFeed(uint256,bool)","6926890b":"createSale3()","69269371":"newAmendment(string,uint256,uint256)","6926cc7b":"_canSetReferrer(address,address)","692740b6":"_areStakeAndWithdrawAllowed()","6927bc38":"_isValidSignature(address,bytes)","6927cac5":"trustedSender()","6927e45a":"TOKEN_SHARE_OF_ADVISORS()","6927f800":"Tango1Token()","69288540":"setDEV(address)","6929dd0b":"confirmOrderCompletionByDoctor(bytes16,bool)","692aa97e":"isOpened()","692ad3a9":"round(uint256,uint256,uint256,uint256)","692b3712":"DMINT()","692bf818":"isIntermediary(address)","692cd610":"nextRewardPlayNo()","692d9ee5":"SALE_TOKENS()","692dfe8e":"maxStakeHolders()","692f74aa":"getvehreqdetails(uint256,address)","69306f24":"numberOfCommittees()","69307c80":"rotateBits(bytes,int256)","6930a020":"bruler(uint256)","6930a7e9":"adminMode(bool)","6930c5da":"depositSavings(address,uint32)","6930fd2a":"claimAll(uint256)","693103a0":"addAffiliates(address[],uint256[])","69318a79":"makeComment(string)","6931b550":"claimEthers()","6931e19f":"productPrices(bytes32)","69328dec":"withdraw(address,uint256,address)","6932af36":"proxies(bytes32)","6932c9c5":"getSaleContractDepositAddress(address)","6932cf81":"getName(string)","69335938":"vestedDate()","693382a9":"addToWhiteList(bytes32,address)","693391fe":"createNewUser(address,address,string)","69347990":"ownerWithdrawl()","69358e2e":"getCompanyList()","6935a0d0":"addNewEventToBusiness(uint256,address,string,string,uint256,uint256,uint256,uint256)","6935a290":"OriginsTraceChainToken(address)","69361de3":"I21Token()","69361fe2":"FeeCalculated(uint256,uint256,uint256,uint256,uint256)","693649aa":"mintRewardCore(address,uint256,uint256,uint256,uint256,uint256)","6936c1cf":"XoloChain()","69389cac":"setPlayerForm(uint256,uint8)","6938d9b0":"allocatePresaleTokens(address,uint256,uint256)","6939864b":"lotteryState()","693ac4fb":"getProof(bytes)","693b2b3f":"ticketTransferersAmount(address)","693bd2d0":"cardContract()","693cf8ce":"amountToSeedNextRound(uint256)","693d0141":"retireWildEasy(uint64,uint64,uint64,uint64,uint64,uint64)","693d0df2":"claimFunds(address)","693dde5c":"getAppId()","693e2279":"burntFounder()","693e26dd":"createVirtualEntity()","693ec85e":"get(string)","6940030f":"disableTrade()","69401027":"acceptClockmaker()","694094fd":"M5Token()","69414e7b":"SaveCryptoNetwork()","6941a061":"IdxCoin()","69422924":"hasVotedOnDocumentPoll(uint8,bytes32)","69423429":"getMyDividendAmount()","694244f8":"PreSaleStart()","694278da":"publicKeyYForX(uint256)","69428d97":"OwnableSimple()","6942dc03":"EnvironToken()","6942eac7":"Currency()","6942eff7":"_unverifyAddress(address)","69431ab6":"TokenCreation(uint256,uint256,address,string,string,uint8)","69433e12":"setExchange(uint256)","6943935e":"DPOS()","69443bf4":"CTAuction(address,address)","694463a2":"totalEntrants()","69454b86":"pairs(address,address)","6945c5ea":"setPlatform(address)","6946e33b":"GXVCNoToken(uint256,address)","694702ec":"CommonTokensale(address,address,address,address,uint256,uint256)","694719d8":"MIN_REFUND_RATE_DELIMITER()","69488271":"AllocatePresale(address,uint256)","6949a058":"sendOwnerEther()","6949e1d4":"AngleToken()","6949ed67":"omec(uint256,string,string)","694a813f":"bet1deltaOf(uint256)","694b1727":"addServer(string,uint8,uint256,uint256)","694c00d1":"reclaimBySender(address,address,bytes32)","694c11eb":"buyCore(address,address)","694d3757":"isAuthDisabled(uint256)","694dcecc":"preCrowdsaleStartTime()","694df50a":"freezeAddress(address,bool)","694e0d5b":"StringPasser(uint8[])","694e4277":"payment(uint256,address,uint256,bool)","694e80c3":"changeThreshold(uint256)","694ebe05":"createEscrow(address,uint256,address,uint256)","694f5a08":"_clearTotalNormalTokensByAddress(address)","694f6276":"_approvedFor(address,uint40)","6951b995":"grantCompanyCoins(address,uint256)","695338b9":"ChillIssued()","6953ace4":"finalTokenExchangeRate()","6953ba9a":"nextStarIndexToAssign()","69541be8":"DefaultReverseResolver()","6954abee":"owner_supplied_eth()","69557669":"changeContracts(address,address,address,address,address)","6955c8fc":"getBuyPriceAndPreviousRecord(bytes32)","69569a51":"setFrontend(address)","6956f3d5":"_totalTokens()","69573648":"remove(bytes,bytes)","695741f8":"waitTimeBlocks()","69580f63":"setVendorName(address,bytes32)","6958420b":"arbYes(uint256,address,uint256,string,uint256)","69594cfa":"transactionLog(uint256)","69598efe":"totalPartitions()","69599168":"onEmergencyChanged(bool)","6959d5c7":"getCitationRecord(string,uint256)","695a4cad":"finishTransferFeePayment()","695a7e9d":"CheckAmbientLightException(bytes32,uint32)","695addc9":"newProposal(bytes32,address,uint256,bytes)","695b4700":"transfer_token_from(address,address,uint256)","695c5a26":"getCurrentPhaseCloseTime()","695ca8c8":"Rhodium()","695d027b":"EMoney(uint256,string,string)","695d7297":"updateRewardForDrawing(uint256)","695d7797":"makeWallet(uint256)","695dcfa4":"createContract(bytes32,uint16,bytes32,uint256,uint64,bytes32,uint64,bytes32,uint64,uint64)","695e1341":"UNGT()","695e2a30":"METAXCrowdSale()","695e54c3":"setCountWinnerPlace(uint256)","695ec793":"secondRelease()","695f9db3":"createRocSaleMarkets(uint256,uint256)","69606c61":"CompalTestCoin1(string,string,uint256,uint256)","6960947d":"stockSize()","6960a0ed":"getArtWorkChangeFee(uint256)","69615c0c":"TransferSalPay(address,address,uint256)","69623ae2":"addPlugin(address,address)","6962b010":"freezeEndsAt()","69632f56":"unitAttack(uint256)","69639749":"getMemberRole(address)","6965193f":"_processTransactionFee(address,uint256)","69652fcf":"resign()","69658cf3":"checkMyTokens()","69666811":"collectAllReturnBalance(address)","69671622":"depositToken(address,uint8,uint256,uint256)","69683080":"totalRestrictedAssignments()","6968ce29":"refundNonKYCInvestor()","6969d216":"topLevelDomainOwner(string)","6969d5d8":"appointAdministrator(address)","696a7253":"setConstraint(bytes32,bool,bool)","696b1030":"enableLimit()","696b5fb7":"getAssetID()","696bda86":"submitProposal(uint256,bytes)","696c58c4":"getRefund(address)","696c9c0a":"create(address,uint256,bytes)","696d25fb":"calcVestableToken(address)","696d7ee9":"airdropPrize(address)","696d816a":"endSell()","696df08e":"FULL_TOKEN_WALLET()","696e6a6a":"Octiron()","696e7a85":"listPrycto3()","696ecc55":"trade(uint256,uint16[],uint8,bytes32,bytes32)","696f541c":"getOrg(string)","696f8a95":"CrowdCoinICO(address,address,address)","696fcc7c":"abortTime()","696fd28a":"SBSToken()","696fd68c":"makeTransferable()","697025b6":"transferEnablingDate()","6970402c":"areAllTokensRegistered(address[],address)","69706d9d":"unlockAmounts(uint256)","6970f46b":"BitFwdToken()","69712ffa":"removeTokenLock()","69719706":"Huangdashi(uint256,string,uint8,string)","6971d64c":"func_0AB9()","69732d4b":"ProjectX()","6973a4f8":"backTransfer(address,uint256)","6973cf58":"createEthSiringAuction(uint256,uint256)","6973e6db":"extraDataToNbJurors(bytes)","6974c632":"getItemPriceById(string,uint256)","6975aa9f":"minGoalReached()","69766079":"buyin()","6977083e":"updateStrategyAddress(bytes15,address)","69774c2d":"topup()","69776b1b":"tranchePeriodInDays()","6977aa62":"mintUnreleasedCard(uint8,address)","6977d9de":"addEmployerTotalInvoiced(address,address,uint256)","69793570":"_deleteOperation(bytes32,bool)","697952af":"updateHolder(uint256,bytes32,bytes32,bytes32,bytes32)","697a2902":"HDhundun()","697a3083":"destroyforsecurities(uint256)","697a60b3":"updateContract(string,address)","697aefe2":"certificato(string)","697b139e":"changeGift(uint256)","697c37c5":"cd1(address)","697ca8bf":"getContributorInfo(address,string)","697cca66":"safeRelease()","697d1eaf":"getGroupTeamInvest(uint256,uint256)","697d2e19":"getDisputeTimeoutState(uint256)","697ee181":"DemeterCrowdsaleInstance()","697fa3e6":"forCommand()","697fa43d":"isBatchCeateDrawings()","697fb220":"addLockAddressInternal(address,uint256)","697fc672":"creatorClaimFundTransfer(uint256)","697fd39e":"randomNumberIncome()","6980f4fb":"heroTypeIds(uint16,uint256)","69810d0c":"TOTAL_SHIP()","69815435":"isAbove(uint256,uint256,string)","69817410":"investHappened(address,uint256)","69817dd4":"ProspectorsDevAllocation(address)","6981b5f4":"getLength(string)","6981c879":"updateDate(address)","69820a80":"birthBlock_()","698232fe":"balances1(uint256)","6982c6f4":"tickets100price()","6982f45a":"AutomobileCyberchainToken()","69833668":"allocateEndBlock()","69837721":"accForBounty()","6983f908":"isAllowedToBuyByAddress(address)","69843940":"getValue(bytes32)","6984d4a8":"getBigPromoPercent()","6985a022":"Pause()","6985a1b0":"endInstance(address,address)","6985c57e":"createRare(string,uint256)","6985e46e":"getConflictResolver()","6986ab82":"getNeedLockFundsFromPeriod(uint256,uint256)","6986d405":"elapsedDays()","6988e9cc":"tokenTotalSupply(address)","69898d64":"removeGift(uint256)","698a92fe":"CNKTToken(uint256,string,string)","698afd98":"withdrawFrom(string,address,uint256)","698bdd6f":"ViewtMyBets()","698c1d17":"CoinBX(address)","698d67aa":"registerBarcode(bytes9,bytes3,string,string,bytes19)","698d8a1e":"completeProvision(address,uint32,uint256,uint256)","698edc76":"getLawyer(address)","698f16aa":"pauseTrueUSD()","698f2e84":"setVirtualExchange(address)","698fbe92":"setWhitelisted(address,uint8)","69902ffb":"buyPerUnit(address,uint256)","699084f4":"CNBCoin(uint256,string,uint8,string)","69919447":"sclToken()","6991bad0":"number_of_token()","6991cb13":"EthlanceSponsorWallet()","69921c26":"checkAccount(address)","6993176a":"setMtdAmount(uint256)","69934ee7":"becomeRichest()","6993b507":"getDoublePeriod()","69940d79":"getRewardToken()","6994436e":"Shefo()","699450e8":"student()","699487c2":"getRecordNameToken(bytes32)","69949c77":"getRestricted()","6994a62b":"getRedemptionStatus(bytes32)","6994a7a0":"getPlayerAmount(uint256,uint256,address)","69950bd6":"addNewVendor(address)","69953501":"setUtils(address)","69958ab9":"cancelGame(uint256)","69972e07":"unvouch(bytes32,uint256)","6997545f":"SetParticipantStatus(address)","6997bcab":"totalSpending()","6997d166":"USER_VOTE(uint256,uint256)","6997f429":"MacroProxyContract()","69986073":"mainSaleSuccessfull()","6998a85b":"setTimeToBorn(uint256)","69995128":"updateAccount()","6999579f":"consolationRewardsClaimPercent()","69997696":"updateLoveStoryWithData(bytes16,bytes32,bytes32,string)","69997987":"distributeIQTToken()","6999d38f":"cancelBetByB(uint256)","699a195d":"addEA(string,string,string,uint32,address,address,string)","699a3a7f":"etherSince100()","699abb3c":"setTaxPercentage(uint256)","699ac46f":"mintTransfer(bytes32,uint256,bytes32,address)","699b328a":"randomize()","699be1bb":"lastBlock_v9Hash_uint256()","699c1687":"getProductBuyer(uint256)","699c181e":"currentTokenPerETH()","699c267a":"Jii()","699dc8ff":"proxyMintTokens(address,uint256,bytes32)","699dde66":"SiniCoin(string,uint256,uint8,string)","699ef40c":"updateProfileAboutMe(string)","699f0c72":"getOfferPriceEth(uint256)","699f1fa9":"thisIsFork()","699f200f":"addresses(bytes32)","699ffd88":"get_database_id()","69a0188a":"setHashToFalse(bytes32)","69a046f2":"wadd(uint128,uint128)","69a0b5c0":"isSolved(uint8[9][6])","69a1aa95":"bulkPurchageLand()","69a1b0e2":"claimB1()","69a1bca9":"refundSale()","69a26fb8":"BuyStatus(uint256)","69a300f6":"getRangeID(uint256)","69a3a65a":"HBXToken(address)","69a479e2":"IPETToken()","69a4c408":"AdminSupply()","69a4eda5":"calculatePositionProfit(uint256)","69a56df4":"testNewCounterValueAfterAIncrease()","69a5e902":"multiAccessCall(address,uint256,bytes)","69a683f1":"pollCompleted()","69a68f5f":"setPhase1AccountTokensMax(uint256)","69a69658":"createCoreRequestInternal(address,address[],int256[],string)","69a75868":"firstYearGameMiningTokenCap()","69a8c3bf":"CurrentGameId()","69a9e6b8":"togglePayment(uint256,string)","69aa2c9f":"burnMultNom()","69aaa388":"changeMultiSignatureWallet(address)","69aab7e3":"withdrawNAC(uint256)","69aad305":"getFromBalance(uint256)","69ab0005":"setThreshold(uint256,uint256,uint256)","69ab3404":"withdrawPartialDevelopersCut(uint256)","69ab7895":"get_payment_by_id(uint256,uint256)","69ab8c76":"ADVISORS_MONTHLY()","69ab8e52":"IsICONotStarted()","69ab98dd":"worldCupResultPart4()","69abed8f":"updateReferralBonus(uint256)","69ac5721":"unlockDate()","69ad56de":"_nextFifoStorageKey(uint256)","69add113":"tradeBancor(address[],uint256,uint256,address)","69addb6e":"IssueToken(uint256,address,uint256,uint256)","69ae7757":"registerAntique(bytes32)","69af0634":"cancelAllBuyOrders(address,uint256,uint256)","69b041bb":"swarmFundAddress()","69b0abea":"remainingPurchaseAmount()","69b144eb":"testThrowsCreateNewRevisionNotOwner()","69b29b51":"saleLimitReachedForCurrentStage()","69b31548":"ForwarderDeposited(address,uint256,bytes)","69b41170":"DELAY()","69b492f9":"weisMinInvestment()","69b4a1ef":"NUM_STAGES()","69b59e75":"collectFee(address)","69b5fb58":"setAuthorName(string)","69b6438e":"FUNDS_WALLET()","69b71e06":"unblockFunds(uint256)","69b7215d":"doesProofExist(bytes32)","69b7ca85":"getCaptainInfo(uint256)","69b8f38d":"ICO_PERCENTAGE_2()","69b94cf0":"_transferWithData(bytes32,address,address,address,uint256,bytes,bytes,bool)","69b9b787":"deposit2(address,address)","69b9e96b":"setBuyoutDividendPercentage(uint256)","69ba0fe9":"getStringValues(bytes32)","69ba3c06":"rejectErx20TransactionRequest()","69ba820e":"retrieveWalletForVanity(string)","69baa4ba":"TransferredToken(address,uint256)","69bb4dc2":"availableTokens()","69bba72f":"getAirdropStats(address)","69bc1a55":"testFail_doubleVoting()","69bc513a":"setGGEAddress(address)","69bcdb7d":"getCommitment(uint256)","69bd01c4":"getvalue()","69bd3436":"debatingPeriodInMinutes()","69bd4ec5":"processSellRequest(string,address,uint256,uint256)","69bdd5dd":"appSet()","69bdfd3a":"toContractDie(bytes,bytes,uint256)","69be51bb":"TOKENS_EARLY_BACKERS()","69bee8a1":"getWorkerPoolsCount(address)","69bef517":"balanceOfOnForHolderUpdate(address,uint256)","69c19d4c":"getOutcomeTokenDistribution(address)","69c1a712":"lastHeartbeat()","69c1da7c":"GetManifestoByCategory(string)","69c212f6":"getUserByAddress(address)","69c254b9":"getSSPRegistry()","69c261ed":"setFreelancerCategories(address,address,uint256[])","69c338ff":"SomeContract()","69c4113d":"setNewBudget(uint256,uint256,uint256,uint256)","69c46821":"checkReferrer(address)","69c5c229":"testControlUpdateLatestRevisionNotUpdatable()","69c5f36e":"getTokensForContribution(uint256)","69c63434":"RaffleInternetBook(string,uint256)","69c6a5d2":"derive_sha256(string,uint256)","69c6f18d":"_transferItem(address,address,uint256)","69c74033":"withdrawSnowflakeBalanceFrom(string,address,uint256)","69c7c180":"m_orderCount()","69c7e386":"decreaseICOStartTime(uint256)","69c87817":"minimumWithdraw()","69c89774":"removeWhitelistedTransfer(address[])","69c8b344":"ownedToken(address)","69c8c7ef":"subtrReferralDeposit(address,uint256)","69c92c5a":"removeAddressFromBackend(address)","69ca02dd":"Transfer(address,uint256)","69ca16fa":"eventLogHand()","69cb418a":"RTeamCoin()","69cbb042":"getEncPubkey()","69cbd0fe":"MintableBaseCrowdsale(address)","69ccacd4":"setPercent4(address,uint256)","69cd5df1":"icoTokens(uint256,uint256,uint256)","69cd61be":"lockOwner()","69cdba9a":"approveChangeOwner(uint256)","69cef46c":"uploadData(bytes)","69cf7ac3":"miningToken()","69d01268":"concatUInt(uint256)","69d0292d":"addPresale(address,uint256,uint256)","69d03738":"setNFTAddress(address)","69d0b5e2":"buyInMarket(uint256,uint256)","69d0e33c":"getPlayerPlayedTimes(uint256)","69d0ef84":"callAndFailWithDivisionByZero()","69d196e1":"canAcceptPayment(uint256)","69d19c19":"BDSM()","69d1d1ca":"postGoods(string,uint32,string,uint256)","69d20762":"MassivelymultiplayeronlineVideoGames()","69d24f63":"lifetime()","69d25ff2":"updateCustomFee(uint256,address,address,address,address)","69d29832":"startBonuses()","69d2ce29":"countGames()","69d38ed2":"FINAL_AML_DATE()","69d3b252":"newVox()","69d3e20e":"mint(uint128)","69d4e250":"_safeSubtract(uint256,uint256)","69d4f28e":"officialSold()","69d516b3":"acceptExecutorOwnership()","69d565a9":"closeWithoutCounterparty(bytes32,uint256,address)","69d58d41":"minimumContributionPhase5()","69d5f38a":"setMembershipPrice(uint256)","69d62bf4":"revertTransfer(uint256,uint256,uint256,uint256,uint256,uint256)","69d6b880":"mintAmount1()","69d714c3":"getLargeInvestorApproval(address)","69d77740":"left92(uint256)","69d79ad5":"moneySumAtSettlement(address,uint256,uint256,int256,uint256,uint256)","69d87ab1":"setETHUSDPrice(uint256)","69d89575":"releaseFunds()","69da1b43":"NonceTick(uint256)","69da66ea":"referralPromille()","69dae8b0":"callAndReward_3(string,string,uint256)","69db054c":"userComment(uint256)","69dbe3e1":"StepFunction(uint256,uint256,uint256)","69dceb6a":"getCoinAge(address,address,uint256)","69dd312f":"mintForContributorPool(uint256)","69dd4524":"crowdsaleTransfer(address,uint256)","69ddaad1":"resetQuote()","69dded0e":"validateSet(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","69de374d":"getProposalUint(uint256)","69de4e84":"NimCoin()","69ded293":"reserveBountyRecipient()","69df3671":"friendsWith(address)","69dfae6e":"productTokens(string)","69dfc66e":"TestableStandardSale(bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","69e01731":"setDesignatedReportDisputeDueTimestamp(uint256)","69e01e8d":"dividendsOwing()","69e0e346":"inWhiteList(address)","69e111ba":"needRelease()","69e15404":"feeAmount()","69e1b5ce":"NewStage()","69e22b20":"addRequest(address,string,string,address)","69e24b48":"getCrabStats(uint256)","69e255c9":"removeHorseOWN(uint256)","69e2c927":"canRecvEthDirect()","69e6bcdf":"smartUnBlockAddress(address)","69e6e6c9":"amountOfPopDeveloperShouldMine(uint256)","69e78499":"removeKey(address)","69e795be":"teamTokensCap()","69e7ae85":"ipfsAttributeLookup()","69e82500":"SoundbitToken()","69e8d80f":"ednation()","69e91994":"getReturnValue(uint256)","69e936f0":"isMultiply()","69e9ca8a":"calculatePayoutForAddress(address)","69ea1771":"updateRate(uint256)","69ea80d5":"HEIGHT()","69eac83a":"_emitOracleAdded(bytes4,address)","69eadd76":"canAcceptTokens_()","69eb6d32":"Annihilated(address,uint256,uint256)","69ebb7e9":"getCurrentRound(uint128)","69ecc3cf":"invalidate(bytes32)","69ed1b83":"callSomeFunctionViaInner2()","69ed87b0":"FeesCalculated(uint256,uint256)","69ed8a42":"LRKToken(uint256,uint256)","69edd4fe":"callElection(uint256)","69efe2bf":"stageAdmin()","69efe471":"transferLimits(address)","69f08449":"m_sale()","69f0a549":"mintOther(address,uint256)","69f10ce1":"issueRIU(address,uint256)","69f1256f":"createTokensFromEther()","69f173dc":"waveCap4()","69f18967":"testSetBitFailIndexOOB()","69f18b8c":"ROB()","69f30401":"bid(address,uint256[],uint256[])","69f3331d":"nextOwner()","69f35883":"updateBloomFilter(bytes,address,bytes32[])","69f3c66e":"Movieum()","69f40ebc":"forwardInvestorTransaction(address,bytes)","69f467c1":"unicorns(uint256)","69f4aefc":"LATPTransaction(uint256,uint256,uint256)","69f66950":"holderBountyTokens()","69f6b766":"getSumInByLottery(uint32)","69f80b4a":"addAddress(address,address,uint256,address)","69f80c7a":"additionPrice()","69f8408a":"MigratableToken()","69f8ef0c":"flushETH()","69f94209":"NewDrawReadyToPlay(uint256,bytes32,uint256,uint256)","69f95967":"vminEtherPerPurchase()","69f99001":"hashDataBlock(string)","69f9ad2f":"char(bytes1)","69fa2cae":"createMintableSale(uint256,uint256,uint256)","69fbad65":"_depositOldTokens(address,uint256,address)","69fbae6c":"_sendToTeam(uint256)","69fbfcc4":"upgradeStructure(uint256)","69fc3481":"fundsRaisedFinalized()","69fc551a":"create(address,uint256,string)","69fcbf70":"setPreSaleAmounts()","69fd75b1":"GUPToken(address,uint256)","69fe0e2d":"setFee(uint256)","69ff2d11":"TOT()","69ffa08a":"claimTokens(address,address)","69ffadc9":"TDz(uint256,string,uint8,string)","6a00da87":"sellBuyerTokens(uint256)","6a011ae5":"minRandomPrivilegeValue()","6a018302":"mul2Revert(uint256)","6a01b6e6":"createToken(uint256,uint256,uint256,uint256,uint8,uint256,address)","6a01f09c":"swapLimit()","6a02209c":"getMaxParticipants()","6a028692":"totalAvailableEdition(uint256)","6a0323b2":"MusiconomiToken()","6a0324b0":"_getBool(address,bytes32)","6a032a3b":"isTimelocked(address,address)","6a032a73":"generateTokensManually(uint256,address)","6a03eaf9":"finalizeTime()","6a048ddb":"createContractChar(string,uint256)","6a049b62":"_buyMulti(address,bytes32)","6a054250":"update(uint256,uint256,uint256)","6a0665a4":"calculateGoldSell(uint256)","6a06bf92":"enjinTeamAllocation()","6a07089f":"Contents()","6a08b403":"setFine(uint16)","6a092e79":"transferTokens(address,address)","6a0a1f8e":"claimGrant(uint256)","6a0ac115":"libpow2(address,uint256)","6a0b50e4":"pickFood(uint256,string,string,uint256)","6a0b96b7":"IkuraTransferFee(address,address,address,uint256)","6a0c3809":"likeArtist(address)","6a0c5068":"getParticipantesA()","6a0c5723":"getHasVoted(uint256,address)","6a0c8730":"getTransactionPrice()","6a0cd52e":"admin_commission_activated()","6a0d017c":"inviteReferee(address,address)","6a0d3450":"sentTokensToFounders()","6a0d783c":"Crowdsale(string,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","6a0e605f":"MyToken(uint256,string,uint8,string,address)","6a0e7c24":"teamVesting(address[],uint256[])","6a0f7b7c":"getProductContractClients(address)","6a0fd45c":"getMeter(string)","6a100f37":"startAuctionFee()","6a10ad64":"tokenAllocToCrowdsale()","6a10c71c":"secondsLeft(address)","6a10d4d6":"createToken(address,uint256)","6a11138c":"doRandom(uint64)","6a12209c":"setRequestLimit(uint256)","6a12b86c":"continueGeneration()","6a1353c9":"setMintPayoutThreshold(uint256)","6a13af72":"giveRiskToken(address,uint256)","6a140b27":"_transferToContract(address,address,uint256,bytes)","6a142015":"assignGenesisCallerAddress(address)","6a146024":"WAD()","6a14d131":"creatorsCreatedCount()","6a15a080":"distribute_NRT(uint256)","6a16ae40":"wct2()","6a172536":"firstPreSaleDate1()","6a1729aa":"paymentAffiliate(address)","6a19b647":"addSuperPlayer(address,bytes32,uint8)","6a1af8b8":"setHeroData(uint256,uint16,uint16,uint32,uint32,uint32,uint64,uint64)","6a1b52e1":"expirationCheck()","6a1be7c6":"approveCollateral(address,uint256)","6a1bf209":"setCCH_edit_8(string)","6a1c3a4c":"getLastAPPeriod()","6a1c6fc0":"costs(string,uint256)","6a1cd82c":"crowdsaleRaised()","6a1d8713":"setMaxReferrals(uint256)","6a1db1bf":"changeFee(uint256)","6a1dbf03":"getTokenMinted()","6a1eb83f":"MeDao(address,address,address,address,address,uint256)","6a1ecbbf":"maxHopefulsNumber()","6a1f9e19":"breakIt()","6a206137":"cancelOrder(address,uint256)","6a2129d6":"delegateRecordExists()","6a21857f":"manualSend(address,bytes5)","6a221688":"TokenSaleQueue(address,address,address,address,uint256,uint256,uint256)","6a226077":"bidOnBreedingAuction(uint256,uint256)","6a226a49":"addMessage(string)","6a22b09a":"lastAssigned()","6a23b9df":"sumICOStage2()","6a23e308":"getIncubatorHashing(address,uint8,uint256)","6a23e7cf":"setFeeDistributionAndStatusThreshold(uint8,uint8[5],uint256)","6a24d595":"ModifyVigencia(uint256)","6a25000c":"token_per_wei()","6a254198":"ClaimTokensEvent(address,uint256,uint256,uint256,uint256)","6a256b29":"settle(address)","6a261353":"Lesson_5(address,uint256)","6a263f02":"_sqrt(uint256)","6a26b7fe":"setClaimableToken(address)","6a272462":"sell(address,uint256,uint256)","6a27c41d":"revealVote(address,bytes32,bytes32,address,uint256,uint256)","6a280317":"isAuctionManager(address)","6a2875c1":"incrementDIDFromContributions(address,uint256)","6a28db13":"getQrLength()","6a28f000":"unfreeze()","6a28f828":"issueIndex()","6a29150e":"totalFundsWithdrawn()","6a293d04":"setAlias(string)","6a294a80":"maxActivatedSalesTotalCount()","6a29605f":"BOHUpgradeableToken(address)","6a2a4c06":"get_released_by_manager()","6a2a6657":"validateToken(address,uint256,uint256,uint256)","6a2aac2b":"flowerBalances(address)","6a2ab790":"PRIVATE_STAGE_MAX_CAP()","6a2b171a":"applyDiscount(address,uint256)","6a2b5656":"changeTransactionFeeRecipient(address)","6a2b9e9d":"ERC20WithMetadata(string)","6a2c1ace":"getStateHash(bytes,uint256)","6a2d1cb8":"MIN_INVEST_ETHER()","6a2d5028":"getRaisedAmountOnToken(address)","6a2dda87":"SettingAutoGame_BettingRankRange(uint256,uint256,uint256)","6a2ddfce":"dragonsStatsContract()","6a2e882b":"getBlockLimit()","6a2f78a6":"submitStakeholderTransaction(address,bool)","6a2f9536":"calculateFraction(uint256,uint256,uint256)","6a30eb24":"hogsmashToken()","6a310bac":"bizp()","6a327b7d":"getSupportManager()","6a33440a":"MANHATTANPROXY12THAVE()","6a3350c8":"invalidAirDrop(address)","6a33803b":"mintSaleTokens(uint256)","6a343df3":"allowPrice()","6a34480b":"MAX_INVESTORS()","6a357465":"payHours(address,uint256)","6a368486":"Ethraffle()","6a369137":"AfterSaleTransferableTime()","6a3845fe":"artTokenoken()","6a385043":"approveTokenTo(uint256,address)","6a385ae9":"getBalances(address,address[])","6a38c0fa":"DragonLock()","6a3a2119":"injectEther()","6a3b5aea":"setC4FContractProviderLock(address,bool)","6a3baaea":"newForge(bytes32,bytes32,address)","6a3bb8cc":"setFiscal(uint256,bytes32)","6a3c1198":"_projectCancelNew()","6a3c167b":"setInitialize(bool)","6a3c62a7":"beginReclaim()","6a3c7945":"RequestUpdated(uint256)","6a3d2a15":"AdvisorsAmount()","6a3d42ef":"ANT(address)","6a3d5a07":"AuctionCancelled(uint256,address,uint256)","6a3f3b97":"HolderBase(uint256)","6a3f5146":"auctionExpired()","6a3f79f4":"RaffleIssued(uint256,uint256,uint256)","6a3f89f4":"setProofImpl(address)","6a40515a":"enhancer()","6a40dbd6":"mintInvestor(address,uint256)","6a4113c7":"releaseLockFounders2()","6a41ade3":"walletCoreTeam()","6a420614":"setFreeCount(uint256)","6a420bbc":"setHaltPurchase(bool)","6a42b8f8":"delay()","6a4349a9":"getMicroModulesIds()","6a43aae7":"removeName(string)","6a43dc9a":"totalSupplyByLegacy()","6a4509f0":"paymentMax()","6a457ee9":"allocatedBonus()","6a470988":"getkEthPhiRate()","6a474002":"withdrawDividend()","6a47aa06":"halvingInterval()","6a48c04d":"GenExtWeightList(uint256,uint256,uint256)","6a4967d6":"addToWhitelist(address,uint256,uint8,uint8)","6a4987dc":"MARKETING_POOL_ADDR()","6a4a39e9":"presaleEndsAt()","6a4a6b6e":"_myAddressHelper()","6a4ad948":"setConvertionFee(uint256)","6a4aef9d":"fromReal(int256)","6a4b1b10":"setPresidenteDeMesaVerify(bytes32)","6a4b22da":"changeFallbackAccount(address)","6a4b27f4":"getRenter(address)","6a4b3eca":"checkBankBalance()","6a4b6aa5":"untrustedChildWithdraw()","6a4b8a3d":"BoxxToken()","6a4b96d5":"PledgePayed(uint256)","6a4c62ef":"getSecondUnionIds(bytes32)","6a4d4bb8":"getInvestorPosition(uint256)","6a4f5495":"test_0_ensureServiceRegistryFunctions()","6a4fcddb":"Remyt()","6a502578":"totalSoldOnPresale()","6a50e3df":"PayWinners(address,address,address)","6a514db7":"REOToken()","6a51b918":"cities(uint256)","6a523c5e":"depositForUser(address)","6a5371b8":"nextTier()","6a537e40":"getCollectiblePrice(uint256,uint256)","6a5392d7":"generatedGze()","6a53ab64":"undestroyable()","6a53f98a":"pendingTxs(uint256)","6a54932c":"processTransaction(address,uint256)","6a561c11":"ownerResumeGame()","6a561cb8":"testSender()","6a5690f6":"ICO_GOAL()","6a56a48b":"_getRandomMineralId()","6a570b98":"InGRedientToken()","6a585fa3":"tokensPerWei20()","6a596455":"getBatlordReq()","6a59d0a4":"transferAndLockForever(address,uint256)","6a59dc8c":"_unpackAgilityValue(uint256)","6a5a3625":"getTotalReqAmt(uint256[],uint256[])","6a5b0151":"setGasForKWH(uint256)","6a5b459c":"receivedWeiMin()","6a5bbc1d":"withdrawToOwner(uint256)","6a5c2cf2":"getTotalDividendsByAddress(address)","6a5c44a9":"STTadmin1()","6a5cf2d0":"WifiBonusCoin()","6a5d7206":"doSafeSendWData(address,bytes,uint256)","6a5da6e5":"followCampaign(uint256)","6a5e2650":"unlocked()","6a5fd362":"shitFund()","6a61e5fc":"setTokenPrice(uint256)","6a625bc8":"issueToMany(address[],uint256[])","6a627842":"mint(address)","6a62936b":"PLUTUSTOKEN()","6a630559":"tokenLocked()","6a630ee7":"__transferWithReference(address,uint256,string,address)","6a63606c":"set_tokens_total(uint256)","6a63d2f9":"getLastestRequestFundID()","6a643ce6":"setBB(bytes32,bytes)","6a64790c":"toWholeShareUnit(uint256)","6a666c86":"addressToPunkIndex()","6a66a693":"beneficiaryContract()","6a67acc5":"getAuctionData()","6a67ec63":"minimum_buy_value()","6a68d2d5":"nextGamePotSplit()","6a69424b":"PaymentTimer()","6a6ae271":"assertPause()","6a6b8077":"StartICO()","6a6ba5d7":"addressIsCrowdsale(address,address)","6a6c526e":"AcceptsLYNIA(address)","6a6d31db":"externalEnter()","6a6e79bb":"WithdrawPaymentForTest(address,uint256)","6a6e88ba":"getBuyerInfoAt(uint256)","6a6f03a0":"returntrueifcurrentplayerwinsround()","6a704d7b":"AddedToGeneration(address,uint256)","6a7149f6":"changeAgency(address)","6a71a584":"getFreeAllowance()","6a71df43":"amountOfTokensPoolB()","6a7245ef":"changeBurnBoundsOperation()","6a7254a3":"specUWallet()","6a7283ac":"buyTokenFromGame(address,address,address)","6a7301b8":"setDestroyer(address)","6a7360d8":"updateNav(uint256)","6a7381bd":"TokensBought(address,uint256,uint256,uint256,uint256,uint256)","6a739a9b":"getTokensUnlockedPercentage()","6a739c44":"checkRegistrationStatus(address)","6a73de2c":"ZZZToken(uint256,string,uint8,string)","6a745ce9":"PRESALE_ETH_RAISE()","6a748ecf":"upLimit()","6a749986":"issuePreferedTokens(uint256,uint256)","6a751710":"transferTraderBalance(address,address)","6a75f03d":"partnersAddress()","6a75fac0":"pullBack(address)","6a7625ca":"setRegionForSale(uint256,uint256,uint256)","6a76c522":"totalContractMiniGame()","6a7798ee":"EndAuction()","6a77e17a":"initialSeedFarmingAdress()","6a785191":"referralTokens(address,uint256)","6a7882f2":"requiredGoldIncreaseFactor()","6a7a88aa":"isValidSignature(address,address,bytes)","6a7b28a2":"show_the_minimum__reward_period()","6a7b988c":"votePopularity(bytes32)","6a7bf76a":"create_game(bytes32,uint32,uint32,uint8,uint16,uint8,address,uint256,bool)","6a7c09a0":"rewardPrivate()","6a7c0bae":"OWN_burnAddress(address,uint256)","6a7c0e81":"setBatchLimit(uint32)","6a7c4cdf":"H2G2()","6a7c594e":"CTVToken(uint256,string,uint8,string)","6a7d1a7e":"getPlayersUnitTickets(address)","6a7d3c1c":"FishbankChests(address)","6a7d6b52":"updateOldOwnerProfit(uint256)","6a7dabb9":"DEVCLASS_MAX_CARGO()","6a7eaf8f":"vestingRules()","6a7f42e4":"closeBetByCanceling(uint256)","6a7fc8b7":"setDailyWithdrawLimit(uint128)","6a8141a1":"ParrotCoin()","6a816548":"cancelOrder()","6a81af17":"setConfigClass(uint32,uint8,uint8,uint8,uint32)","6a822760":"betB()","6a8269b4":"frozenList(address)","6a8296d7":"_setPrizePoolAddress(address)","6a833a6c":"addDelegateSigned(address,uint8,bytes32,bytes32,string,address,uint256)","6a83662e":"getYESVotesByEntity(uint256)","6a83b924":"btycownerof()","6a84e143":"destroyUnsoldTokens()","6a85ac88":"answerCompare(uint256,bytes32)","6a85d12e":"changeOuts(address)","6a85e252":"ElementTransferred(uint256,uint256,uint256,address,uint256,uint256,uint256)","6a868363":"CreatedVUP(address,uint256)","6a86a0f0":"DCCAdvancedToken(uint256,string,string)","6a871e27":"airDropHeight()","6a87f66d":"specialManagerOff(address)","6a8896b6":"getPots()","6a893a8c":"stopWorkInternal()","6a897999":"drainStack(bytes32,bytes32)","6a89a51e":"_delete_()","6a8aa343":"m_maxTotalSupply()","6a8ae136":"getContractBalance(address,address)","6a8b9f7b":"BecomeSpiderQueen()","6a8ba0fa":"createPromoPet(uint256,address,uint256,uint256,uint256,uint256)","6a8be019":"cancelEscrow(uint256,uint256,address,uint256)","6a8c2437":"totalRescues()","6a8c9cce":"BITMUZE()","6a8cdb52":"setBondAddress(address)","6a8d0bf4":"ReceiverChanged(uint256,address,address)","6a8d3575":"UniversalToken(uint256,uint256,uint256)","6a8d7eb3":"isLSNFT()","6a8d86db":"rawTransfer(address,address,uint256)","6a8e8711":"max_bet()","6a8ef2d3":"getMyShitClone()","6a8f91ff":"createAccount(bytes32,bytes32,address,address)","6a907a78":"UserAddTicket(bytes5[])","6a90ac63":"unlockWithdrawals(uint256)","6a91205a":"rentLand(uint256,bool,uint256)","6a91431e":"RefundableCrowdsale(uint256,uint256)","6a914911":"getPlayerByBoard(bytes32,uint8)","6a92a8b8":"UserAddressLoaded(bytes32,string)","6a92fcf6":"paymentEnable()","6a931aa8":"tokenVendor2()","6a93316c":"getInvestorStatus(address)","6a938567":"isValid(bytes32)","6a9412bd":"refundAvailable(address)","6a95dff4":"NOBSToken()","6a96c63e":"getCreateUnicornFullPrice()","6a98085a":"totalAmountToWhale()","6a9812f9":"getPolicyByTaxCode(string,uint256)","6a993130":"Ownables()","6a9b4daf":"Etros()","6a9b515d":"TokenAuctionCreated(uint256,address,uint256)","6a9ba3ce":"maxCapNotReached()","6a9c97d6":"refundSender(address,uint256)","6a9cd450":"upgradeKernel(address)","6a9d02e9":"tokenFrozenSinceNotice()","6a9d2afd":"playToWinTest(uint256)","6a9d69a7":"rentalTotalTime()","6a9d7629":"getOpenInterestInAttoEth()","6a9db57a":"playerAmountOfBets(address)","6a9dc9a8":"enrollUser(address)","6a9e8480":"FinalLottery(address)","6a9e8f27":"stockTransfer(address,uint256,uint256)","6a9ecd21":"BidFailedEvent(address,uint256,string)","6aa084d7":"getBoardStatus(uint256)","6aa0fd32":"performRebalance(bool,address,uint256,bool,uint256,uint256,address,bytes)","6aa179d9":"_secondRoundLosersFight()","6aa3141f":"removeCustody(address,uint256)","6aa31b1f":"starSell()","6aa3bf8b":"finishBetFrom(address)","6aa3e64d":"emptyTo(address)","6aa4b3cc":"calculateId(address,bytes32)","6aa52288":"FisrtSupply(address,uint256)","6aa5b37f":"maxBuyLimit()","6aa5cdfa":"setLatestEdition(uint8)","6aa633b6":"isEnabled()","6aa66cd4":"targetDiscountValue10()","6aa68a15":"phase2EndBlock()","6aa737e0":"enableSellToken()","6aa8e220":"WeaponRegistry()","6aa96d7c":"Storychain()","6aa9c59b":"_addMinions(uint32,uint8,uint64)","6aa9c82b":"withdrawControl()","6aaaae68":"tokensForFoundersAndTeam()","6aaab6f2":"updateTreasury(address,uint256)","6aaacb3f":"CreateCaptainToken(address,uint256,uint32,uint32,uint32,uint32,uint32,uint256)","6aab223d":"bonusMatchPayoutInPercent()","6aaba012":"ErrorGenerator()","6aabd369":"verifyGame(uint256,bool)","6aad1a6b":"adminSetGasLimit(uint256)","6aad70b6":"getAddTokenSignatures()","6aaee3f7":"biAdvance(uint32,uint64[2],uint64[2],int64[2],uint64)","6aaf0a0d":"endRegisterTime()","6aafb887":"getNewMaxProfit(uint256,uint256)","6aafd194":"Fosha(uint256,uint256,uint256,uint256,uint256)","6ab03a7f":"OGPToken()","6ab09a5e":"listUsersBets()","6ab15436":"price(bool)","6ab22536":"SMEToken(uint256,uint256,uint256,uint256)","6ab28bc8":"lockedAmount()","6ab368f8":"Burned(address,address,uint256)","6ab3846b":"updateEndTime(uint256)","6ab3c5bd":"KING_WIN_MULTIPLE_PER()","6ab4936d":"presaleFail()","6ab5bcd0":"withdrawedTokens()","6ab71276":"getOwners(address,uint256)","6ab76510":"bulkTransferFrom(uint32[],address,address[],uint256[])","6ab872f0":"setMaxBetThresholdPct(uint256)","6ab8bd2b":"POOH_TO_CALL_1PLUMBER()","6ab92ba7":"PEPL()","6ab9aa21":"MAX_REVENUE()","6ab9eb45":"getItemAllowancePrice(uint256,address,address)","6aba2a0d":"donatorBonus(uint256)","6aba899b":"refundStartTime()","6abac115":"getActiveState()","6abacfa4":"etherMasterWallet()","6abb4a50":"getPartner()","6abb51a5":"_completeTask(uint256,uint256)","6abc3fe4":"directMintAgent()","6abd3b88":"getWins(uint256,uint256,uint256)","6abf31eb":"confirmTransaction(address,uint256,uint256)","6abfbf6f":"allowTokenContract(address)","6ac084fe":"OrderFilled(address,uint256)","6ac0bf9c":"transferableSynthetix(address)","6ac0fe25":"BUYER_STEP_5_CANCEL(bytes32)","6ac26d3d":"executeAddMemberProposal(uint256)","6ac290e7":"getFirstReferrer()","6ac29bcc":"FBR()","6ac3a100":"HLCN()","6ac47db5":"CloudbricSale(address,address)","6ac4d582":"registrants(uint256)","6ac4d97c":"createInitialCards(uint32,uint16,uint16)","6ac4e08b":"dynArrayFunc(int256[])","6ac4f8e4":"StocksAddress()","6ac50065":"getBidsByAdunit(uint256,uint256)","6ac50f2f":"sizeOfUserAddresses()","6ac54d62":"stopPreIcoAndBurn()","6ac54eb0":"posMint()","6ac59dd5":"setIcoParametersSet(bool)","6ac5db19":"max()","6ac6016f":"pepFarm(address,address,address,address,uint256)","6ac6205c":"addDataPoint(int256,uint256,bool,string)","6ac68f7f":"getBestBidder(uint256)","6ac777d3":"EEFucksToken()","6ac878f3":"multiTransferDecimals(address[],uint256[])","6ac96df8":"removeAddressesFromRole(address[],string)","6ac98840":"SGCC()","6acd58d4":"arrayIndexOf(address[],address,address)","6acd89f6":"Testerr()","6acd8e4a":"getAddedTime(uint256,uint256)","6acdf42b":"arrayOfNonTrivialAccounts(uint256)","6ace6dc8":"setApprovedBuyer(address,address,bool)","6ace7d87":"getLastCandidates()","6acf5cb3":"isUserKYCVerified(address)","6acfb852":"ZiggleToken()","6ad001a5":"metalworksCities(uint256)","6ad03feb":"GBTAddress()","6ad0d6ce":"_startNewRound(address)","6ad1246e":"content(string,uint256,uint256,address,uint256,uint256)","6ad1a6d5":"PauseTradable()","6ad1fe02":"sale()","6ad26611":"removeFee(address)","6ad2a0b3":"buildContract(address)","6ad34a7a":"BAILSToken(uint256)","6ad34dab":"getstartBlockNumber()","6ad35d1a":"CMO()","6ad38e61":"transmit(address,address,uint256)","6ad3f723":"getContentAddress()","6ad43a54":"setRateICO(uint256)","6ad44174":"getVolumebasedBonusRate(uint256)","6ad49245":"FundingManagerEntity()","6ad50ed4":"investmentEntryInfos()","6ad5b3ea":"walletAddress()","6ad60e3d":"BubbleToneToken(address)","6ad6d45b":"setLister(address)","6ad7541c":"Kokos()","6ad7aeb5":"BitsumCash()","6ad80326":"walletFounder3()","6ad95317":"batchInvests(address[],uint256[])","6ad95843":"icoUnitPrice()","6ada94e0":"setDataInt(string,string)","6adacb48":"priceStep4()","6adc674e":"WaltixToken()","6adcef6b":"payDividends(uint256)","6addb663":"tokenInfo()","6addc649":"weekBonuses(uint8)","6ade6cea":"currentstageplayer2()","6ade8aa2":"emptyWallet(address)","6ade9bd1":"tokensFortorch()","6adf3279":"leekStealOn_()","6ae00c4f":"ShareRoomDATA(address,string)","6ae0646a":"_computeRollFee(uint256)","6ae17283":"MinterAdded(address)","6ae22740":"reward7()","6ae38577":"accPreICO()","6ae413ab":"updateWebappAddress(address,address)","6ae459bd":"bulkMint(address[],uint256[])","6ae4feed":"subtract(address,address,uint256)","6ae6151e":"acceptOffer(bytes32,address,uint256)","6ae6921f":"_addPayee(address,uint256)","6ae6b459":"setLockup(uint256)","6ae76777":"addressBounty()","6ae81ae1":"icoPhase3TimeBonusInPercentage()","6ae85216":"countAssets(uint256)","6ae85e0d":"isAddressNotVoted(address,address)","6ae8f49a":"WebCoin()","6ae8fefa":"NetareumToken()","6ae9eea8":"s39(bytes1)","6aea5f1b":"current_supply()","6aea6cce":"breakCompleteness(uint256,uint256,address)","6aeaef97":"inheritedView()","6aeb1ce7":"m_paymentChannels(uint256)","6aebbbd9":"subUIntValue(bytes32,uint256)","6aebc603":"Villj()","6aebff5d":"lccxTeamAddress()","6aec47b4":"getBalancesAgent(uint256)","6aec82b3":"setSalesPipe(address)","6aec95cc":"registerBalanceForReference(address)","6aedc282":"MarriageContract(address,address,uint256,string)","6aede5cd":"globalTimeVault()","6aedf1d1":"SupportAdded(address)","6aeeec7f":"_setStakingEpochDuration(uint256)","6aefef17":"test01CrowdsaleInit()","6af04a57":"newContractAddress()","6af1fdf7":"delegateTokens(address,uint96)","6af2da2f":"testKeyedHash()","6af41534":"withholdToken()","6af422fc":"RSPLT_H()","6af53f2f":"MaPToken2()","6af58d83":"getMin(uint256)","6af630d1":"DARKNODE_FEES_DENOMINATOR()","6af6b06f":"setNextLotteryTTMTokenId9(uint64)","6af6e64a":"VendorRegistry(address)","6af78ab1":"startWeekFour()","6af79112":"priceInWei(uint256)","6af7dbbe":"sendPriceRequestToOracle(bytes16,uint256)","6af81d6f":"_mintCategory(string)","6af91799":"totalTokenSaled()","6afa0381":"minInvestmentLimit()","6afa7b80":"toETH()","6afb434f":"getPreIcoInvestment(address)","6afb92a1":"MeepCoin()","6afbd04f":"Mintable()","6afc3474":"saleRoundsSet()","6afe74c9":"test_oneValidEmptyAddress()","6afeada3":"finishBountyAt()","6aff1a64":"TIER2_PRICE()","6affdc39":"saleEndDate()","6affe07b":"CirclesTokenOffering(address,uint256,uint256,uint256,uint256,uint256,address)","6b0028b9":"initialSupplyInFrac()","6b007e4f":"logMarketFinalizedCalled()","6b015897":"minimumRewardWithdrawalLimit()","6b01acf5":"counterToTokens(uint256)","6b0235a0":"tla()","6b038742":"Archetypal()","6b03ed5f":"clearClaim()","6b041da2":"SEVENTNET()","6b04f110":"mint_for(address,uint256)","6b061d7a":"changeRestarTime(uint32)","6b06548c":"EarlyInvestorsTokensHolder(address,address,address)","6b068e01":"collectWorks(bytes32,bytes32)","6b069710":"scheduleCall(address,bytes,uint256,uint256,uint8)","6b06afe7":"getEcoSystemWallet()","6b06c3d4":"ActivateEscrow(uint256,uint256,uint256,uint256,address)","6b06ea88":"ElementToken(uint256,string,string)","6b074a07":"isProvider(address)","6b08a833":"EDUTURN()","6b08f2ef":"convertForPrioritized2(address[],uint256,uint256,address,uint256,uint8,bytes32,bytes32)","6b091695":"getReward(address,address)","6b097cd0":"KKOGToken()","6b0bfc80":"feedAndMultiply(uint256,uint256,string)","6b0c537b":"generateRequestId()","6b0c932d":"lastDay()","6b0c9d6a":"distributeA()","6b0cba9c":"getUniqHash()","6b0cc513":"_DifficultyCalulate(uint16,uint16)","6b0d0329":"getTicketInfo(uint256,uint256)","6b0dd90f":"getVote(address,uint256)","6b0dfb76":"getLandDefender(uint8,uint32)","6b0ead6a":"iudexIdToString(bytes32)","6b0f02e6":"firstExchangeRate()","6b0f182e":"changeCofounderA(address)","6b0f65d7":"indSeedDeposit()","6b1092f2":"ADV_BTY_SUPPLY()","6b11c87a":"RealEstateCryptoFundBounty(address)","6b11dabd":"MTYToken()","6b128b2f":"upgradeFinance(address)","6b12a7bf":"buyRealm(uint256,uint256,uint256)","6b13fabf":"SampleToken()","6b140854":"totalWinValue()","6b1426a4":"getWinners(uint256)","6b149aac":"Cryptassist()","6b14dfe1":"SPEED_STAT_MAX()","6b14ea36":"ASK_STAKE_RATIO()","6b153322":"activateCampaign(string,uint256)","6b15c47c":"tokenCalculate(uint256,uint256)","6b1781b6":"Emergency()","6b17864f":"CommunityPool(address,address)","6b1786bb":"cVideoCost()","6b178b90":"NBACoin()","6b178f47":"poolIssue()","6b190ee1":"MemeNetworkToken(address,uint256)","6b194a4a":"ALLOCATION_LOCK_END_TIMESTAMP()","6b1970ab":"TheCoin()","6b199471":"updateMasks(uint256,uint256,uint256)","6b19e692":"getPaymentSupply()","6b1ac900":"setPXLPropertyContract(address)","6b1af75e":"sendReward(address,address,uint256)","6b1b3997":"ChronoDragonPowerCoin()","6b1b68ad":"URMBToken(uint256,string,string,address)","6b1bfd33":"setFundAccount(address)","6b1c86fe":"sendBreakup(address)","6b1cb549":"orderMatch(uint256,uint256,uint256,int256,uint256,uint256,address,uint8,bytes32,bytes32,int256)","6b1d4db7":"ethToTokenSwapOutput(uint256,uint256)","6b1da364":"getWinnerInfo(uint256)","6b1e0420":"blockPendingTx(uint256)","6b1e564a":"challengeWinningOutcome(bytes32,uint16)","6b1f513b":"makeDailyInvest(uint256)","6b1f78c8":"joinSqr(uint256)","6b1fbfdb":"sendWithSignature(address,uint256,uint256,bytes,uint256,bytes)","6b1feeeb":"get_my_sig()","6b212960":"offer(address,uint256)","6b2148c2":"Deluxo()","6b21a636":"startDisbursement()","6b227a8f":"OrderApprovedPartTwo(bytes32,bytes,address,bytes,address,uint256,uint256,uint256,uint256,uint256,bool)","6b2327d2":"previewStageEndTime()","6b2351aa":"lockWithAfter(address,uint256,uint256)","6b235bdc":"ChangeBeneficiary(address)","6b236730":"solveChallenge(bytes32)","6b24d827":"WalletHolder()","6b252b47":"advisorsWallet()","6b256f57":"DAOSecurity(address,address,bytes,uint256,uint256,uint128)","6b259690":"feesPool()","6b263efa":"multiOwnableCreator()","6b270056":"Corporation()","6b27909d":"getStopLockTime()","6b27be9f":"mayorcoin()","6b281b64":"totalBalanceUp()","6b28d7a2":"blockTransfer()","6b28f834":"getPeggedTokenCount(address,address)","6b298df0":"disbursements(address)","6b2a2691":"winBrickReturn()","6b2a77ed":"End5()","6b2a86be":"dropToken(address[])","6b2accac":"toDRP(uint256)","6b2ae2ab":"Notify_String(string,string)","6b2bb92a":"finishTournament()","6b2c0f55":"removePauser(address)","6b2c116c":"AmateurPlatinumToken()","6b2cd752":"getGpgKey()","6b2ce4ce":"stakeForDuration(address,uint256,uint256,bytes)","6b2ce7f1":"togglePresale(bool)","6b2d95d4":"getLockedTokens(address)","6b2e36b0":"canUpdateAmountToTakeAsRake()","6b2ec90f":"_vestedDown(uint256,uint256,uint256,uint256)","6b2ed1c0":"sellFci(address,uint256)","6b2f4632":"totalEthereumBalance()","6b2f65b0":"isArtist(address)","6b2f68f5":"assertEq22(bytes22,bytes22)","6b2f73c2":"preICOLedger()","6b2fa6cc":"lastBlock_v7Hash_uint256()","6b2fafa9":"getHash(uint256)","6b2fd0e7":"catGenes(uint256)","6b3032c6":"getSingleGuessInfo(uint256)","6b308ee7":"subTourFreezingPrice()","6b30f243":"VCChainToken()","6b318270":"addFile(bytes32)","6b319f36":"tokenUnfreezeTime()","6b31ee01":"jackpot()","6b32bb25":"containsValue(address,uint256,string,uint8[])","6b32c591":"userClaimAmt()","6b334e49":"senderCheck(address,address)","6b335b8c":"buyXname(uint256,string)","6b33aeb8":"YSH()","6b33e45d":"setWithdrawTo(address)","6b3416b5":"transfer(uint256,uint256,uint256,uint256,uint256,uint256)","6b342eb8":"_minimumBuy()","6b3559e1":"mintAndSetData(address,uint256)","6b3578f2":"paymentEnabled()","6b35bed2":"addAirdropParticipants(address[])","6b35f7c1":"deleted()","6b36028e":"setReferenceType(bytes32,string)","6b361c80":"TokenPriceUpdated(uint256)","6b36a76e":"MIPCoin()","6b3868db":"getMemberByIdx(uint256)","6b3905c4":"getNextVestingTime(address)","6b392680":"setFeeAmount(uint256)","6b3a87d2":"WatchWinningPot()","6b3a8e90":"tournamentJackpot()","6b3ac430":"crowdsaleLive()","6b3ad4f8":"setColorWhite()","6b3b1d17":"tHasBeenPenalized(uint256,address)","6b3b261c":"addSpaceshipMoney(uint256)","6b3bc4b6":"ovcPerEther()","6b3c9757":"advisorSecondLockTime()","6b3ce49b":"getRoomBalance(uint256,uint256)","6b3cedd6":"mintTokensForCrowdsaleParticipants(address[],uint256[])","6b3d998c":"Apputoken()","6b3e2f97":"updateDiamond(string,string,string,string,string,uint256,uint256,string)","6b3e8ca0":"setPrePresaleTokens(uint256)","6b3ec0ac":"vestingExists(address)","6b3f5f84":"OwnerReclaim(address,uint256)","6b3f94ab":"GoldMintToken()","6b3fb674":"noHash()","6b3fdc5a":"oraclize_setNetwork(uint8)","6b3fdf16":"EXT_COMPANY_THREE()","6b3ffb91":"changevanity(string,address)","6b404955":"depositDelta()","6b407837":"sellerRequestCancel(bytes16,address,address,uint256,uint16)","6b4097b2":"_runAdvanceClock(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","6b40bba1":"requiredPeriodSeconds()","6b424d47":"h2g2()","6b425093":"sortTopPosts()","6b433ccf":"_totalLandholderTax(uint256)","6b440e9a":"finalAllocation()","6b441abc":"VIRTUALTALK()","6b453fac":"hardWeiCap()","6b454d4c":"next_item_index()","6b45adf3":"cellsOf(address)","6b45c9f2":"getPiece(uint256)","6b462936":"transferQueue(address[],uint256[])","6b4660f8":"getStockLength()","6b46c8c3":"payoutAmount()","6b475df7":"release6m()","6b486818":"hashFirst()","6b489028":"DEVCLASS()","6b4a6ded":"TOKENS_PER_ETHER()","6b4a8b78":"token_allowance(address,address)","6b4b1f3a":"stringToAddress(string,address)","6b4b63fa":"Bank_With_Interest()","6b4bfeae":"checkClaimExpiry()","6b4c0789":"freezeContract(bool)","6b4c5856":"WyeContract()","6b4ca2a8":"getMatchData()","6b4dd158":"getPrice(bytes)","6b4dff1f":"validateGasPrice(uint256)","6b4e243d":"callOperator(address,address,address,uint256,bytes,bytes,bool)","6b4e8bb0":"lastInflationUpdate()","6b4ed21b":"holdersCount()","6b4f518a":"preICOTokenReward()","6b4f6865":"unlockForWork(address,address,uint256)","6b50b6b3":"_multiSigWallet()","6b512327":"_deleteIPFSHash(bytes32)","6b523b68":"periodCrowdsale()","6b52a071":"SALE_FUNDS_ADDR()","6b52a86f":"DesTokenSale(address,address)","6b5396dc":"batchPresaleVesting(address[],uint256[],uint256[],uint256[],uint256[],uint256[])","6b5424b3":"HACHIKO()","6b54821f":"setupAuthentication(address,bool)","6b550dd3":"setAgriChainDocuments(address)","6b55264d":"setRegionName(uint16,string)","6b55ddd0":"getJobEmployerName(uint256)","6b55e991":"transferEther(address)","6b56476b":"removePost(address,address)","6b5648f5":"enabledMint()","6b565345":"CANAToken()","6b57825c":"getCurrentUserTotalPromoBonus()","6b57cb34":"lockedStagesNum(address)","6b584b10":"testFreeSpace()","6b588775":"rateOfSpecificTier(uint256)","6b58b2bc":"calculateInternalTokensAmount(uint256,uint256,uint256)","6b590248":"getDigit()","6b59084d":"test1()","6b59f495":"tokenized()","6b5a61ac":"changeTeamNIMFAAddress(address)","6b5ae41c":"execute0(address,uint256,bytes)","6b5aed93":"executeTransfer(string,string,uint256,uint256)","6b5b6285":"PBKtoken()","6b5bbf5f":"setCommunityMultisig(address)","6b5c4b16":"dateRelease12()","6b5c5f39":"croupier()","6b5c8fba":"confirmParties()","6b5ca27d":"finalizeCampaign(uint256)","6b5caec4":"setBot(address)","6b5cd8d0":"getWeaponDamageFromTokenId(uint256,uint256)","6b5d18fd":"getProposedIpfs(bytes32)","6b5d3287":"sellTokensForUsd(string,address,uint256,uint256)","6b5de05a":"tokensForTournament()","6b5e1a18":"payoutThreshold()","6b5e3ca4":"StaffWallet()","6b5e7b06":"getPenndingBalances()","6b60386d":"init(uint256,uint256,address,address,address,uint256,uint256,address,uint256,bool)","6b6093c2":"FreezeBalances(address)","6b61c3c7":"acceptBet(bytes32,bytes32,bytes32,bool)","6b628816":"getYumerium(address)","6b6292d9":"securityTokensPercent()","6b62cb1b":"createName(bytes32,address)","6b62cd65":"bankerAllDeposit()","6b634440":"tokensForPartners()","6b63d145":"OWNER_TOKENS_PERCENT()","6b6438cc":"payoutCursor_Id_()","6b64c769":"startAuction()","6b655e45":"getJuryMembers(uint256)","6b6566f0":"DiceOffline()","6b65a834":"ratePlanIsExist(uint256,uint256)","6b65be60":"usedPositions()","6b668601":"preSaleConversionRate()","6b676966":"tokenNeedForBonusLevel1()","6b683896":"getImplementation(string)","6b6872c7":"OeTestCoin()","6b68db6a":"FipsData(bytes20,address,bytes)","6b68dd4b":"tokensOfOwnerWithinRange(address,uint256,uint256)","6b693027":"collateralizations(address,uint256)","6b698377":"DogecoinPrivate()","6b69ac58":"upgradeHealth(uint256,uint256)","6b6a08dc":"hashRevealedPositions(uint32,int64[])","6b6a53fa":"testThrowsRestartNotOwner()","6b6b2740":"RetailLoyaltySystemBase(uint256,string,string,uint8)","6b6c5a7e":"getBracketData()","6b6cc239":"isMaintenanceMode()","6b6d294e":"worldCupResultPart3()","6b6d5c82":"encryptedBallots(uint256)","6b6e71b9":"makeTransaction(address,uint256,uint256)","6b6ece26":"ban(uint256)","6b6ee875":"tokenSealer(uint256)","6b6ef0ed":"transfer0(address,uint256)","6b6f4826":"minInvestmentICO()","6b6f4a9d":"discount()","6b7006d7":"lockMana(address,uint256)","6b709a36":"lockWorker(address,address)","6b7128ec":"getBetCount(uint256)","6b71d93b":"VerifiedProxy(uint256)","6b727312":"easyCommit(uint256,uint256,uint256)","6b7285d7":"transferP2P(uint256,address)","6b74401a":"BuyTokensDirect(address,uint72,uint88,uint88)","6b74c3d8":"getTxn(address,uint256,uint256)","6b755aa2":"reCommentRewardPool()","6b764632":"KongToken()","6b76484e":"swap(address,address)","6b76bd94":"CreateUser(string)","6b78aa08":"MarketHub(uint256)","6b790be4":"getWeightMinusFees()","6b792c4b":"emergencyWithdrawETH(uint256)","6b7976c8":"calculateObtainedINA(uint256)","6b7a247e":"setlvlSign(string)","6b7ae8dc":"foundationWallet()","6b7ae8e6":"left74(uint256)","6b7b0472":"getLastHash(bytes10)","6b7c0379":"HOPPToken()","6b7cc44f":"detail()","6b7d5205":"Diamond()","6b7d5dfd":"setTangibleAssetDisbursementAddress(address)","6b7d90ff":"unVerifyKyc(address)","6b7d9a5c":"createPromoPuppy(uint256,address,uint16,uint16,uint16,uint16)","6b7db8fc":"sendDividend(address,uint256)","6b7e4175":"EphronIndiaCoinICO(address,address,address)","6b7eba7d":"instantTransfer()","6b7f3a32":"Jojo(uint256,string,uint8,string)","6b7fad1b":"ethToDividendsNeeds()","6b7ffb92":"revote()","6b802108":"checkValidSignatureAndMethod(address,bytes)","6b8184e2":"ImpeachmentAccepted(address)","6b8263ed":"resumeOffering()","6b8287a6":"getetherpriceinUSD(address,uint256)","6b8393dd":"getSold(address,uint256)","6b847dc0":"setDayWithdraw(uint256)","6b8487be":"GigToken(bool)","6b84dfcd":"setTransferRight(address[],address[])","6b863578":"noVoteSum()","6b872309":"x(address,uint256,address,uint256,bytes32,bytes32)","6b87d9f7":"BUBBLEToken()","6b881724":"assetWallet()","6b886888":"isTemporary(bytes8)","6b88719a":"PHOENIX_CORSAIR_FTL_SPEED()","6b889cce":"call_test()","6b88f4ae":"resetIndex(uint256)","6b89be03":"getActiveShareholdersArrayLength()","6b89bfc7":"getStatusOf(address)","6b8ab97d":"reset(address)","6b8b3268":"mintCrown(uint256)","6b8c261e":"prizeByNow()","6b8c4c48":"setDaxInBtcSatoshi(uint256)","6b8c7180":"setupPeriodForPreSale(uint256,uint256)","6b8cc89d":"INVESTMENT_USER2()","6b8ce30e":"partnerInfo_for_Owner(address,bytes32,uint8,bytes32,bytes32)","6b8da9a2":"tgrLive()","6b8f155a":"numberWhitelisted()","6b8f9c43":"setPayoutWallet(address)","6b8fd600":"priceOfElements(uint256[])","6b8fe0f0":"NewPlayer(address,uint256)","6b8ff574":"getName(uint256)","6b90ce93":"simulated_snt()","6b915d43":"melonToken()","6b9168e6":"clearAngelsFromBoard(uint16)","6b919488":"removeOwner(uint256)","6b930927":"preTgeTokenSupply()","6b931cad":"replaceAdministrator(address,address)","6b944bd6":"GoBlock()","6b946680":"parentKidsLink(uint256,string,string)","6b94692a":"isPresaleBuyer(address)","6b95767d":"giftSpaceship(uint16,address)","6b962c27":"transaction_internal(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[4])","6b963f20":"changeOVISReservedToken(uint256,int256)","6b96668f":"setRateContract(address)","6b97be1f":"transferPayable(uint256)","6b97c6d7":"_transferOwnershipOfItemsStorage(address)","6b97e5eb":"UnicronToken()","6b9808a1":"buyWine()","6b98419a":"_approveFor(address,uint256)","6b9896ba":"AddAccountsInfo(address,uint256)","6b98c85c":"bltMasterToSale()","6b98d78c":"setLandSlogan(uint256,string)","6b99a13e":"editNumber(uint256)","6b9a1db9":"wanUnit()","6b9b1006":"TransactionRecorder()","6b9b2679":"setReserveForFoundersFirst(address)","6b9c1d22":"managementFeeWallet()","6b9c6116":"PULSCrowdsale()","6b9cadc1":"isValidMsgValue(uint256)","6b9cf534":"_minimumBuyAmount()","6b9da657":"sendNewEntry(string)","6b9db4e6":"getLock(address)","6b9f96ea":"flush()","6ba0b4f2":"isKnownSelector(bytes4)","6ba0b8bc":"getBonusPercent(uint256,uint256)","6ba0f114":"EtherChain()","6ba15807":"evntCreateContract(address,address,address,address,uint256,string)","6ba20015":"maxplayers()","6ba2482d":"GetUserNickName(address)","6ba2aefc":"transferMultisig(address,address,uint256)","6ba42aaa":"isKeeper(address)","6ba44d3c":"get_address(string)","6ba47299":"buyDiscountTTWByETH(uint256,address)","6ba4c290":"modifyEscrowPrice(uint256,uint256,uint256)","6ba4f143":"_setAuraValue23(uint256)","6ba4fadb":"changePhaseToPreICO2()","6ba55c6d":"coinIssuedFoundation()","6ba5ef0d":"setMin(uint96)","6ba6984c":"setHBT(uint256)","6ba6e2e0":"TGCToken(address)","6ba75608":"claimAssetPack(uint256)","6ba7d28a":"checkVestingWithFrozen(address)","6ba7e31c":"PriceSet(string,uint64,uint8)","6ba7ffd5":"requestCnt()","6ba8d421":"transferHackoinTokenOwnership(address)","6ba951c4":"EtherModifierTigro()","6ba9a40b":"withDrawBalance(uint256)","6ba9fd38":"openMinting()","6baa0f8e":"createSystemAuction(uint256)","6baa2ff7":"preSale(address,uint256)","6baae8e5":"_prand(uint256)","6bacc0fa":"hasSaleEnded()","6bacdc87":"InterestFreeLending(address,address,uint256,uint256)","6bacfe43":"getCCH_edit_16()","6bad77e1":"getNumProducts()","6bad8ed8":"freezingPercentage()","6bae05cf":"preRegister(address)","6bae116f":"getBonusMultipierInPercents(uint256)","6bb0ae10":"print(uint256)","6bb15940":"getCurrentSaleRate()","6bb1605b":"filehash()","6bb164c9":"isCantonEmployee(address)","6bb20f9b":"searchWhitelist(address,address)","6bb27584":"capRound1()","6bb2c12f":"createRequest(address[4],address,uint256[12],uint256,bytes)","6bb3130e":"disbursementWei()","6bb35840":"PowerGiggs()","6bb3c065":"round4Sold()","6bb4cf76":"createToken(string,string,uint8,address[],uint256[],uint256[])","6bb4d573":"evMinTokensReached(address,uint256,uint256)","6bb50f4c":"_openGamePlayNo(uint256)","6bb53c90":"ticket(uint256,uint256,uint256,uint256,uint256)","6bb56e8b":"crowdsaleEth()","6bb60475":"_insertSortMemory(uint32[11])","6bb6126e":"exec(address)","6bb6ea30":"createInterceptor()","6bb72c97":"numTokensInLottery()","6bb7b7a4":"rare()","6bb7f336":"updateUnsoldTokens()","6bb7f98e":"getHighestMilesOwnerAt(uint256)","6bb80acc":"_createCovfefe(string,string,uint16,address,uint256)","6bb80d51":"dividendPercentage()","6bb82e82":"addToWhitelist(address,uint256,bool)","6bb9b9ab":"getTodayDividendsByAddress(address)","6bba3f2f":"kappa()","6bba5c15":"changeParameters(uint256,uint8,uint256,uint256,uint256)","6bbadf09":"addPokemonDetails(string,uint256,uint256)","6bbae823":"LIMIT_STAR4()","6bbbc182":"addVerified(address[])","6bbbec85":"updateGameMeta(uint256,string,string)","6bbc5748":"FeeChanged(uint256)","6bbe0410":"NewTransaction(string,uint64,string,uint64,uint8)","6bbe24d4":"dataSourceGetQuarterResult(uint256)","6bbe6f7f":"buyCoinsPreview(uint256)","6bbea781":"getApproveValueFor(address)","6bbeb9de":"loginUser(address)","6bbeba8a":"setService(bytes,address)","6bbf54a4":"PCF()","6bbf592d":"bytesCallWithArray(bytes32[4])","6bc02730":"approveBreeding(address,uint256)","6bc0b3ba":"jackpotAddress()","6bc0f7fb":"isProxyLegit(address,address)","6bc1f1e4":"updatePriceAndInventories(uint256,uint256,uint256,uint256,uint256,uint16)","6bc21808":"CategoryAuction(address)","6bc2805d":"cancelAllEnter()","6bc31311":"EFFCoin(address)","6bc32c7b":"get_train_data_length()","6bc388b2":"canFreeze(address)","6bc3b437":"newService(string,string)","6bc3e0f0":"verifySecondHalf(uint256[4],uint256[4],uint256[4])","6bc3e4a8":"claimMultiple(address,uint256)","6bc46fb2":"totalHatcheryShrimp()","6bc5063c":"VestedTokensReleased(address,uint256)","6bc507b1":"getBlackflag(uint256,address)","6bc5b964":"getMemberWhisper(address)","6bc5c0cd":"releaseBonus()","6bc6147e":"unlockMainSaleToken()","6bc64e0f":"preSaleEnd()","6bc65778":"getAllProductList()","6bc789cd":"getONG_AUDIT(bytes32)","6bc85107":"isMemberInDescendant(address,bytes32)","6bc8a260":"getUserWinInTournament(uint256)","6bc99824":"VoltToken()","6bc9b0d7":"getPromiseIds(uint256,uint256,address,bool)","6bca81d4":"revealBid(bytes32,address,uint256,address,address,bytes32,uint256,uint256)","6bcaaed9":"PetmancoinToken()","6bcab76c":"setDApp(address)","6bcc035a":"getStatusAndOutcome()","6bcc28a9":"kittensRemainingToDrop()","6bcc311c":"tokensForBonus()","6bcc7241":"getPriceWei(uint256)","6bce23be":"setupTokenRate(uint256)","6bce6569":"reservedPercentTotal()","6bce8a96":"whitelistedAddressCount()","6bceead7":"setSquareWins(uint256,uint256,uint256)","6bd0021c":"bonusPhase()","6bd31a56":"hardCapLowUsd()","6bd37274":"Pixiu_Beta()","6bd3a1c3":"PresiamDrop()","6bd3d406":"totalPresale()","6bd46bd2":"setTokenBurnFeeReceiver(address,address,address,address)","6bd484c4":"oracleCallbackGasLimit()","6bd4dfce":"setStarterClass(uint256,uint32)","6bd5084a":"number_of_claims()","6bd50cef":"getConfiguration()","6bd58db5":"Total_Patient(uint256)","6bd5e26a":"lockTo(address,string)","6bd61a66":"nonHighestBidderRefund()","6bd6775f":"Presale(address,address,address,address,uint256,uint256)","6bd68a8f":"referralAmount()","6bd70a1f":"MIN_IVESTMENT()","6bd7e7dd":"CatBought(uint256,uint256,address,address)","6bd7eeeb":"maximumTokensForFirst()","6bd87c86":"Try2222()","6bd8fd12":"currentMinBid()","6bd92f7c":"activateAllowanceRecord(address,address)","6bd9b4da":"setMinETHin(uint256)","6bda3422":"Token(uint256,string,string)","6bdaa520":"forciblyRequest_callback()","6bdbc918":"BaseTransactionService(address,address)","6bdbf8e6":"concat()","6bdc06f5":"cancelRegistration(address)","6bdc1d2a":"GoldRex()","6bdc62b9":"composeJingle(string,uint256[5])","6bdc9546":"setCommunicationUri(bytes32)","6bdcdb2d":"getAutomatedReportDueTimestamp()","6bdcdeaa":"setMagicStore(address,address)","6bde2e7f":"_setBodyColorValue3(uint256)","6bdea7eb":"AddBonus(uint256)","6bdebcc9":"destory()","6bdee200":"enableTicker()","6bdee235":"Zeroexchange()","6bdfd723":"getNewEnglandBets(address)","6be00229":"exitAddress()","6be03bd2":"configTimeInc()","6be050d2":"FibokenUsed(uint8,address,uint256)","6be0c670":"chipSize()","6be13c92":"coldWallet()","6be202cf":"addSomeDETsTo(address,uint256)","6be24a47":"create(address,address,address,address,address,address,address,string,string,string)","6be2f28e":"totalAmountOfWeiCollected()","6be32e73":"tokenCallback(address,uint256,bytes)","6be343cc":"setFoundAcc(address)","6be39bda":"getTerms(bytes32)","6be4097c":"currentLotteryId()","6be422b2":"determinReferrer(address)","6be47418":"latchFciUserController(uint256,address)","6be47618":"deleteContract(uint8[],bytes32[],bytes32[])","6be4cf1f":"buyTokensFor(address)","6be4d9b0":"changeResolverAllowances(address[],uint256[])","6be505f5":"selectWinner(bytes32)","6be598b4":"SIGTToken()","6be5f4a6":"checkVictoryByScore(uint256)","6be60f8b":"underwrite(uint256)","6be67db3":"contractNameUpdate(string,bool)","6be6fa14":"getTransferFromValueValue()","6be80de7":"investorIDs(address)","6be82168":"NeycoinToken()","6be86f21":"bonussale_TokesSold()","6be9564a":"ListingBought(bytes5,uint256,uint256,address)","6be99794":"getTransferToValue()","6be9a8df":"GetGuestQueueNumber()","6be9f7a0":"emitDeposited(address,uint256,address)","6bea0b79":"getAccountData(address,string)","6bea8215":"createGenerator(uint256,string,uint256,uint256,uint256)","6bea989d":"AUTH_FREEZEACCOUNT()","6bea9d81":"BLOCKPIX_Coin()","6beace8f":"AllocateFounderTokens(address,uint256)","6beadfc7":"approveandcall(address,uint256)","6beb509d":"updateCanRefund(bool)","6bec32da":"mintToken(address,address,uint256)","6bec454a":"buyCity(uint256)","6bec51cc":"generate(address,address,uint256)","6bece548":"preSaleBonus1Time()","6bed09be":"buyTokensUpdateState()","6bed6de5":"sendObjectWithApproval(uint256,address)","6bedb845":"MultiSig()","6bee2cc3":"registerLottery(uint256)","6bee5131":"FW(uint256,string,uint8,string)","6bee73db":"testAllowance()","6bee76ea":"withdrawBond(address,uint256,uint256)","6bee9cfa":"offsetFeeRate()","6bef2a94":"earlyPurchaseTokenAmount()","6bef90f8":"VUP_PER_ETH_BASE_RATE()","6befa297":"WCT1(address)","6bf006c8":"capReached(uint256)","6bf06fde":"transferToNewContract(address,uint8,bytes32,bytes32,bool)","6bf0873a":"birth(uint256,uint64[])","6bf0a3bf":"LIQUID_ALLOCATION_PPM()","6bf0c7fd":"getBracket(address)","6bf0f4a1":"roll(uint8)","6bf13959":"endAtCheck(uint256)","6bf20a77":"unfrozenATAccount(address,address)","6bf2606a":"PATCH_VERSION()","6bf30259":"checkIncentivisingBalance()","6bf32504":"markAsFailed(string)","6bf341e7":"_fundowner()","6bf4223b":"getRoundEnd(uint256)","6bf42646":"holdTokenInvestorsCount()","6bf42ea5":"TokensBought(address,uint256,uint256,uint256,uint256,uint256,uint256)","6bf4398d":"saniwallet()","6bf51a18":"stepLockCheck()","6bf52ffa":"Vote()","6bf5595d":"CrowdSale(uint256,uint256,uint256,address)","6bf6dd6f":"associate(bytes32,bytes32[],address[])","6bf807fc":"unlockTimes(address)","6bf82d74":"ethFundMain()","6bf8b92d":"changeSeed(uint32)","6bf8bfab":"DutchAuction(address,uint256,uint256)","6bf8f85a":"forceFinish()","6bf91c63":"configOf(uint64)","6bf99bbf":"ICOResumed(uint256,uint256,uint256,uint256,uint256)","6bf9b3e7":"approveWithdraw(address,address,uint256)","6bf9b731":"claimFor(address,address,address)","6bf9e633":"winnerIsA()","6bfa379e":"readyTokens(address)","6bfa5edc":"operatingOfficerAddress()","6bfaa903":"increaseOwnershipTokenCount(address)","6bfae928":"calcReserve(uint256,uint256,uint256)","6bfb0d01":"itemCount()","6bfbbdf5":"DutchAuctionToCraft(address,address,address)","6bfbc9f7":"HongToken(uint256,string,uint8,string)","6bfbf5e6":"levelChanger()","6bfc8bb5":"setIPFSHash(bytes32,string)","6bfc9561":"sellStake()","6bfd9716":"SaleTracker(bool)","6bfdb7eb":"getBeneficiary(address,address)","6bfdd3dd":"_sanMint(uint256,address,string,string)","6bfe6bc0":"setEthPricies(uint8)","6bfee863":"CipherToken(uint256,string,string)","6bff1901":"coreTeamSupply()","6c00161a":"distributeWithMilestone(address,uint256,uint8)","6c00bb44":"AuctionSuccessful(address,uint256,uint256,address)","6c012923":"feeForSplitterCreation()","6c021968":"RefundTransfer(uint256,uint256,uint256,address)","6c026f59":"ii()","6c02a931":"tokenName()","6c0360eb":"baseURI()","6c03cd49":"getInviteRate()","6c04066f":"BlockLockSet(uint256)","6c042689":"endStage1()","6c043773":"sendPacket(address,bytes)","6c047c36":"evaluateProposalMetricStart(uint256)","6c049b89":"toggleCrossForking()","6c04c1c9":"LuckyEthereumLotteryToken()","6c050eae":"look()","6c052cd8":"getGroupMembers(bytes32)","6c054113":"setPhaseSale(uint256,uint256,uint256)","6c054ad0":"createContractor(address,address,bool,address,string,string,bool)","6c055ce2":"withdrawToPartner(address,uint256)","6c060a7a":"_batchPopularitySetting(uint256[],uint8[])","6c062806":"addAdminAddress(address,address)","6c062cc7":"Forge()","6c064d63":"_setCompositionPrice(uint256,uint256)","6c08729e":"TransferToSAToE(address,uint256)","6c08faf7":"getCaseCount()","6c096192":"fetchCreatedOrdersForPayer(address)","6c0a1117":"doCancelAll()","6c0a1605":"EthTurnWCG(uint256)","6c0b1e8c":"VESTING_START_TIME()","6c0b66b9":"PGO_UNLOCKED_LIQUIDITY_CAP()","6c0c27e1":"acceptBet(uint256)","6c0d2c8b":"getHeroPower(uint256,uint256)","6c0daed8":"getRate(string)","6c0db60e":"CatexToken()","6c0eb56f":"LOG_EmergencyWithdrawalProposed()","6c0ebc6c":"perform_withdrawal(address)","6c0f7ee7":"multiAddDSource(bytes32[],uint256[])","6c10dcdf":"ProvidenceCasinoToken()","6c118f46":"TimeWindowUpdated(uint256,uint256)","6c11bcd3":"sellTokens(uint256)","6c1247e5":"databaseContract()","6c131dbe":"multiMint(int256,uint256[])","6c1334bf":"SetDescript(string,string)","6c13b5f2":"totalReceive()","6c1475ad":"tryAdvance()","6c14bb42":"buyAutos(uint256)","6c14f2d1":"m_ETHPriceLastUpdateRequest()","6c150f42":"initLeftICOTokens()","6c15e8e6":"GlobalConstraintRegistrar(int256)","6c169818":"isFreezeAccount(address)","6c16c740":"Start9()","6c172095":"gameCenter()","6c17729b":"JoygoEOS(string,string,uint256,uint256,uint256,uint256,uint256,uint256)","6c182e99":"lastTokenIsTransferableDate(address)","6c188593":"setMinBetAmount(uint256)","6c189c46":"releaseAmisToken()","6c18cc1e":"firstSellHSShop(uint256,uint256,uint256)","6c194b59":"lastTransactionRec()","6c197ff5":"sell(address,uint256)","6c19e783":"setSigner(address)","6c1a5b8c":"TOKEN_TARGET()","6c1c6d93":"setVipAddress(address,address)","6c1c86f7":"PlanEX()","6c1d0157":"distributeMoney(address,address,uint256)","6c1d4fd9":"advisorsTokensThirdReleaseTime()","6c1e039a":"playerRoll(uint8,uint8,address)","6c1f05d2":"breakIdMaintenance(int128,address)","6c1f27fe":"icoBonus5()","6c1f2fb3":"ico3Sold()","6c1ff101":"Crowd()","6c204fd7":"certifyMany(bytes32[])","6c2066bf":"MAX_TOKENS_ADVISORS_PARTNERS()","6c20ceb4":"DeltaChainToken()","6c20d755":"getItemRafflePlayers(uint256)","6c20fcdd":"MerkleTreeRootAdded(uint8,bytes)","6c2187e7":"GameEnded(uint256,address,uint256,uint256,uint8,uint8)","6c224487":"DEHT()","6c226eef":"_processGameEnd()","6c231060":"buyCar(uint256)","6c237c1c":"admin_token_burn(uint256)","6c23c7b0":"canOperatorTransferByPartition(bytes32,address,address,uint256,bytes,bytes)","6c2412ae":"GetChipInfo(uint32)","6c241bb1":"getCityData(uint256)","6c24a76f":"getAvailableBalance(address)","6c24c87d":"latestSenderOf(uint256)","6c24e2db":"maskpot()","6c26493c":"MyTestToken1()","6c265dc3":"calcFeeE8(uint64,uint256,address)","6c26df09":"addFootballMatch(uint256)","6c27b211":"registerBalanceForReference(address,uint256)","6c28faee":"migration(address,uint256,bool)","6c295936":"changeOptional(uint40,uint64)","6c295e34":"Add_Doctor(uint256,uint256,string,string,string)","6c29d714":"totalMarketplaces()","6c2af4e5":"MithrilAxe()","6c2bcfdd":"MAXSALESCAP()","6c2c5a19":"addCarSigned(string,string,string,uint16,string,address,bytes32,bytes32,uint8)","6c2d5d26":"symbol(address,bytes32)","6c2ec9ef":"guess_tx(bytes32)","6c2f64fe":"removeContractAddress(address,address)","6c303e1b":"Bitescia()","6c3051c9":"setWonTeam(uint256)","6c30ba53":"setTitulaire_Compte_4(uint256)","6c30d170":"renounceIssuance()","6c30f765":"testing(uint256)","6c326a46":"prizeFundHWC()","6c32c0a6":"gap()","6c32e01c":"sendJackpot(address,uint256)","6c33e7eb":"setMockAddress(bytes4,address)","6c341889":"toUint(bytes,bytes,uint256)","6c343afc":"destTokens(address)","6c343ffe":"withdrawfunds()","6c349e57":"addrunmoney(address,uint256,uint256,uint256)","6c34c97a":"setFIRST_STEP_LIMIT(uint256)","6c376cc5":"maintenance()","6c3772fd":"totalpaidout()","6c3824ef":"removeTokens(address[])","6c38d4e4":"pauseMint(uint256)","6c3919fc":"getProviderCurrentRate(uint256)","6c39b7ee":"gamesPlayed()","6c3a208d":"VistaToken()","6c3aaab7":"snailPot()","6c3aacf9":"getTokenToEthOrder(uint32)","6c3b6591":"right83(uint256)","6c3c221b":"setFunctionTwoPrice(uint256)","6c3e6a75":"forceBonds(address)","6c3e6e0c":"iconomiTokenSupply()","6c3e8e19":"_vestedAmount(address)","6c3ea721":"memberHasRight(address,string)","6c4019f4":"createContest(string,address,uint32,uint64,uint64,uint128,uint128,uint32,uint32,uint8,uint32[])","6c4040c5":"firstSaleSpenderTxDetails(uint256)","6c419326":"STC(address,uint256,uint256,uint256)","6c43a2ca":"increaseAllowance(address,address,uint256)","6c4470fb":"participants()","6c456d0f":"getERCContractAddress()","6c457528":"createUsername(string)","6c463635":"getDistValues(string)","6c464c3d":"recieveRelocation(address,uint256)","6c46a2c5":"addOwners(address[])","6c46ae22":"phasePublicSale3_To()","6c4820bb":"callModifiedWithdraw(uint256)","6c48a097":"amount_investments()","6c494843":"multiAccessChangeOwnerD(address,address,address)","6c4b3197":"getSecureFees()","6c4be791":"hasAirdrop(address)","6c4bf16b":"icoOwner()","6c4c174f":"hack(address)","6c4ceaff":"getSourceHash(uint256,uint256,uint256)","6c4d032e":"SOFTCAP_TIME()","6c4d0c00":"wasGoalReached()","6c4d4f21":"setVotingProxy(address)","6c4d7c59":"getBetProps(bytes32)","6c4db7cc":"sendFoundersBalance(address[],uint256[])","6c4dfffe":"BIKS(uint256,string,uint8,string)","6c4e5c86":"decreaseLockBalance(address,uint256)","6c4e838a":"wantNewTokens(uint256[])","6c4e86af":"dailyGrowth_ppm()","6c4eca27":"tokenTransfer()","6c4ef21e":"canUnstakePartial(address,uint256,uint256,bytes8,uint256,uint256,uint256,uint256)","6c4f5e51":"testingContracts2(string)","6c4f8c65":"DeviceIsActivated(address)","6c4fbaa4":"requestCore()","6c4fe255":"p_setMaxInvestment(uint256)","6c5077b1":"MintPaused(bool)","6c5091e3":"getERC721AddrPawn(uint256,address)","6c50bc2e":"getGeneralLength()","6c510377":"transferOutAllEthers()","6c51af67":"setPOOL_edit_17(string)","6c525b13":"unregisterSelf(address)","6c525d04":"endMigration()","6c526503":"AmountRaised()","6c52660d":"checkIfNameValid(string)","6c530ee3":"weiPerEth()","6c5376c9":"addPassword(string,string,string)","6c543c08":"_emitSkillCategoriesSet(address,uint256,uint256)","6c54d1c1":"KRYPSTRONG()","6c54df52":"getCurrentPrice(address,uint256)","6c5541b5":"changeSpender(address)","6c556859":"createGame(string,string,uint256,uint256,string,string,string,string)","6c55e385":"minimalFreeze()","6c5649d8":"setCommunityBallotCentsPrice(uint256)","6c56a3f1":"startRelease()","6c56bf3e":"CreateARCD(address,uint256)","6c56bfc0":"InitiateGame()","6c572104":"TotalSantaCoinsGivenByNorthPole()","6c57c01f":"MAXIMUM_CONTRIBUTION()","6c57dbaa":"_max(uint256,uint8,uint256)","6c57f5a9":"isDisabled()","6c587491":"playGame(address,uint256)","6c595451":"addApp(string,address,uint256)","6c597e41":"getCreditBitAddress()","6c59fb29":"allocateToken()","6c5a7d1e":"setDisabled(bool)","6c5aad6e":"fetchOrderByIdWithMerchantByAdmin(string,address)","6c5aaf50":"getDelegateDetails(address)","6c5af719":"getHoldEarnings(address)","6c5b685f":"icoPart()","6c5bde2a":"CoInsureBlockToken()","6c5c671f":"cancelIntl()","6c5ca1fa":"exchangeRateRoundOne()","6c5ccfe8":"distributeFundsInEscrow(address,address,uint256,address)","6c5d2787":"setTymTokensPercent(uint256)","6c5d6156":"burn(address[])","6c5dc78b":"setPublicSaleFinishDate(uint256)","6c5dee17":"getFileAt(uint256)","6c5e9ac1":"cmpEq(uint256,uint256,bool)","6c5e9e18":"_phase1Supply()","6c5f71c7":"numberOfPingsReceived()","6c5f8394":"DeneumToken()","6c609906":"getTotalTokensAgainstAddress(address)","6c6101fd":"ContractManagementUpdate(string,address,address,bool)","6c610f53":"getMinUnitPrice(uint8)","6c617048":"reinvestFor(address)","6c6288e4":"Thechampcoin()","6c6295b8":"setValidRateDurationInBlocks(uint256)","6c64a678":"unfreezeToken()","6c658a2c":"UpdateICOPhase(address,uint256,uint256)","6c65c455":"swapETHMKR(uint256,uint256)","6c65fd6a":"isFreezer(address)","6c675ae6":"tokens_buy()","6c677d82":"SpentTokens(address,address,uint256)","6c68c837":"verifyBalanceProof(address,uint32,uint192,bytes)","6c698882":"getActualNum(uint256)","6c699905":"revealWinner()","6c69ab24":"multitokensCount()","6c6b23d2":"updateBalances(address,address)","6c6b298a":"getMigrateInBonusIfInForkWindowValue()","6c6b9870":"updAirDropTokenEnabled(bool)","6c6c21af":"CappedCrowdsale(uint256,uint256,uint256)","6c6c39fb":"votersLength()","6c6c7e05":"amountLocked()","6c6ce21a":"setInvoice(bytes32,uint256,bool,string,string,string,string)","6c6d2653":"CrowdsaleChanged(address,address)","6c6e5108":"StoriqaCash()","6c6eb9d1":"base(uint256)","6c6f1d93":"getContractCreationValue()","6c6f31f2":"allow(address,uint256)","6c6f360e":"userRegister()","6c6fbd70":"EnergiToken()","6c7018cf":"single_card()","6c706093":"logUniverseCreatedCalled()","6c70abda":"use(uint8,uint8,uint8,uint8[176])","6c70ad0d":"PublicMineCallsCount()","6c7113e4":"getFundManager()","6c712471":"testControlRetractLatestRevisionEnforceRevisions()","6c71b1aa":"setGasReq(uint256)","6c71d01d":"ratings(bytes32)","6c720446":"isVotingPrepare()","6c7272ce":"registerVendor(address,address)","6c73d230":"logResult(string)","6c741950":"setTTL(uint256)","6c749c26":"EXA()","6c74e341":"setFoundingTeam(uint256[],address[])","6c751622":"MacQueenToken()","6c7521cb":"updateReputationScoreInBulk(address[],uint256[])","6c767f20":"playerOneReveal(bytes32,bytes32)","6c768200":"burnByOwner(address)","6c76b8f4":"_changeReward(uint256)","6c779d57":"levelSplits(uint256)","6c77f989":"joinLottery()","6c780868":"getBurnLine()","6c784995":"getBeneficiaryMarket()","6c786b65":"bonusAccountCount()","6c787229":"availableOwnerWithdraw()","6c788a0d":"bookingFee()","6c789092":"Resource(bytes32,bytes32,bytes32,address)","6c78cb81":"ETCToken(address)","6c78da22":"getPrefixPrice(string)","6c79e379":"setGallerySevenPrice(uint256)","6c7afaba":"regSpots(uint16,uint16,bytes32)","6c7bc902":"tgrCurrentPartInvestor()","6c7c7c73":"bePure(uint256,uint256)","6c7c909f":"FreshWaterFlow()","6c7ca99f":"RequestBankrollPayment(address,uint256,uint256)","6c7cc6d8":"sell(uint256,address,bool)","6c7d4c4c":"unwhitelistAddress(address,address)","6c7dde15":"validPayBuff()","6c7de422":"investmoretokens()","6c7e0236":"isNotaryVeredictValid(address,address,address,bool,bool,bytes)","6c7e7082":"overflowAmount()","6c7f1542":"balanceOf(bytes32)","6c7f3f17":"totalBuys()","6c811247":"showPlayerSafeByAddress(address,uint256)","6c814509":"setAdAccount(address)","6c81fd6d":"AddModerator(address)","6c82337e":"payJackpot4()","6c825035":"withdrawLRC()","6c830f4b":"getCompletedTasks()","6c83444d":"FLOQI()","6c8381f8":"candidate()","6c8429fd":"jpMinBet()","6c843605":"BrownieCoin()","6c84a4bf":"tokenContributionCap()","6c84ae04":"setFirstYearAllowancePercentage(uint8)","6c85c727":"removeBankroll(uint256,string)","6c85cf67":"canTransfer(address,address)","6c86888b":"testTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address)","6c86ac5a":"getPublicData(uint256)","6c8716d8":"etherLowLimit()","6c876e5d":"s2(bytes1)","6c8830c5":"_maxtotalSupply()","6c8a59f2":"addresses6(uint256)","6c8ae38c":"r()","6c8b052a":"numStakers()","6c8b37eb":"MTRCToken(address,string,string,uint256,uint256)","6c8b4e60":"communityLock()","6c8d0b1e":"getSubscriberStatus()","6c8d0bcf":"getUserDAOsId(address,uint256)","6c8d65dc":"phepsToken()","6c8dea3b":"claim_ENS_name()","6c8e44c3":"ProductionUnitToken(address,uint8,uint8,uint8,uint256,uint256,uint256,uint256)","6c8e53e0":"PreSale()","6c8f093d":"PayForServiceCHLEvent(address,uint256)","6c8f455c":"checkMembership(bytes32,uint256,bytes32,bytes)","6c90c3df":"setCanClaim(bool,bool)","6c90fe09":"CcoindDigital()","6c912080":"minListingSeconds()","6c922038":"CMAPToken()","6c9230db":"getCurrentTimestamp()","6c94d0e4":"INBETToken()","6c953719":"CCASH(uint256,string,string)","6c958f74":"tokensOfferedOf()","6c963fc7":"PoWAdvCoinToken()","6c965a81":"claim(address,bytes32,string,bool,uint256,bytes32,uint256,bytes)","6c973248":"getVoteCount(uint256,uint256,uint256)","6c9784b1":"_getTokenRaised(uint256)","6c9789b0":"finalize(bool)","6c97a812":"UTExchangeRate()","6c97b731":"TimeEndChanged(string,uint256)","6c97c237":"firstSellSaddleShop(uint256,uint256,uint256)","6c981488":"paymentPeriods()","6c996bbd":"disputeOpened(address)","6c99b0da":"setFWDaddrETH(address)","6c9a1e2a":"setPOOL_edit_12(string)","6c9a5c61":"resolveExpiredBets(uint256)","6c9c1d41":"checkServiceFee(address)","6c9c2faf":"getSupply()","6c9c5944":"freeze(address,uint256,uint256,uint256)","6c9c97d8":"refundByToken(uint256)","6c9cb82f":"freeCash()","6c9d99da":"teamTokensWallet()","6c9e27d6":"ALLOC_WINGS()","6c9e89b6":"addVesting(address[],uint256[],uint256[])","6c9eafe7":"stillAllowed()","6c9f65c5":"getBidInfo(uint32)","6c9fa59e":"shareToken()","6c9fca89":"updateAppInstance(bytes32)","6ca0101e":"unopened_bid()","6ca06072":"getAttributeAdminAddr(address,bytes32)","6ca0f321":"setValue1(uint256)","6ca100fb":"firstWeekMainICOBonusEstimate()","6ca13df1":"decreaseOwnershipTokenCount(address,address)","6ca1f933":"setTest(uint256)","6ca32280":"percentageBuyBackFund()","6ca34ea2":"balances_(address)","6ca35ae4":"addDoctor(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","6ca3b5f6":"set_maxgasprice(uint256)","6ca3daf2":"_vouchersDistributed(uint16)","6ca3fc3b":"distributePrizes(uint256)","6ca562d6":"switchCompatible223ex(bool)","6ca596fa":"isPreICOClosed()","6ca5b5b0":"r1()","6ca5bdf2":"testIntDynArray(int256[])","6ca621bd":"setEmbassy(address)","6ca78a1c":"anyRequestAvailable()","6ca78a1e":"setBorrowerReturnEthPerFiatRate(uint256)","6ca7b99b":"getDirection(uint256,uint256)","6ca7c216":"gas()","6caa2bda":"OxyToken()","6caa736b":"fundDeposit()","6caabc6f":"addCompany(string,address,uint256)","6caca63a":"WhiteTigerToken()","6cad3fb0":"updateFeePercentage(uint256)","6cadd040":"EtherAuction()","6caddb04":"orders(uint256,address)","6cae8f67":"setSellableToken(address)","6caed305":"changeBonus(uint256,uint256)","6caf25ce":"price1()","6caf3673":"getPlayerSpaceshipBattleStakeById(uint256)","6cb04993":"forceNeuroChainAddress(address,string)","6cb0e9f0":"TXToken(address)","6cb136ba":"isActive(uint16)","6cb1630f":"withdrowTokens()","6cb24199":"withdraw(bytes32,uint256,address,uint256,address)","6cb30fee":"nettingContractsByAddress(address)","6cb31171":"_currentHalfYear()","6cb39448":"getMarketerKey()","6cb3c94e":"Filler()","6cb3d30a":"triggerTryAuth()","6cb3e8ef":"getApprovers()","6cb45694":"LogDisbursement(address,uint256)","6cb520c6":"_play(string,uint256)","6cb5291e":"ICO_PRICE1()","6cb5714c":"_sendByTranche(bytes32,address,address,address,uint256,bytes,bytes)","6cb5d070":"getCoinsSinceLastHatch(address)","6cb69c2c":"setDevTokensWallet(address)","6cb69f42":"getSystemInfo()","6cb6ea82":"CBITokenCrowdsale(uint256,uint256,uint256,uint256,uint256,address)","6cb7223c":"maxPurchaseOnce()","6cb76408":"returned()","6cb78983":"purchaseMIT(address)","6cb90a2c":"pre_ico()","6cb942ab":"GameItemNew()","6cba45b8":"setDayFirst()","6cbad471":"Rappo()","6cbae51b":"firstPreSaleDate2()","6cbaecbd":"normalRoomMin()","6cbb1afa":"setTokenBag(address)","6cbb9d19":"releaseEscrow(bytes20,address)","6cbc2ded":"endGame()","6cbc9ca0":"ADDR_OWNER()","6cbceeec":"theAddress()","6cbdb7d0":"takers(uint256)","6cbec01c":"Steel()","6cbef5a7":"sumVote()","6cbf3c8c":"ICO_POOL()","6cbf9c5e":"commitVote(uint256,bytes32,uint256,uint256)","6cc03315":"getPaymentLogN()","6cc09081":"getActualPrice()","6cc23437":"setIsContainerForFeeWindow(bool)","6cc25db7":"ticket()","6cc2c668":"_presaleEndTimestamp()","6cc301e3":"permitted(address)","6cc341f1":"getIndexOrder1(uint256)","6cc48d81":"_emitHeartBeat(bytes32,int256,int256)","6cc5ab24":"digithothToken()","6cc5f3ad":"getGames(uint256[])","6cc5fdaa":"setBytes32(bytes,bytes)","6cc61d86":"setSingleWithdrawMin(uint256)","6cc67aa5":"resetExplicitState(uint32,int64[2],int256,uint64,int8)","6cc6971b":"setNewStartDate(uint256)","6cc6cde1":"arbitrator()","6cc762d8":"lastWeiPricePerCWC()","6cc7d828":"investBalanceGot()","6cc919c8":"updateConfig(address)","6cc95f8d":"ALAX()","6cca5065":"QripplexToken()","6cca60ba":"gripWallet()","6cca7023":"DoubleSend(address,address,uint256)","6cca940a":"RusgasCrowdsale()","6ccab1f3":"wwasCoin()","6ccb5d02":"getShareholder(uint256)","6ccbb0ab":"withdrawBalances()","6ccbdbf9":"getHodlAmount(uint256)","6ccc3bdd":"whitelistBonusPercentage()","6ccce7a8":"getCapOfWei()","6ccd563d":"queueAuditRequest(uint256,uint256)","6ccd5cbe":"getClassInfo(uint32)","6ccd993b":"getDestroySharesFxpValueValue()","6ccde640":"getGoodPreset(bytes32)","6cce15d8":"ICOFails()","6ccf93d3":"HeyueToken(address,uint256)","6cd02297":"processOfflinePurchase(address,uint256)","6cd05e41":"takeAllTheMoney(address)","6cd0f102":"setHouseEdge(uint256)","6cd186ce":"setUncleSafeNr(uint256)","6cd1b26c":"setQueue(uint256)","6cd22eaf":"updateAuthority(address,bool)","6cd2ad56":"distributeTo(address)","6cd2b458":"splitsTotal(uint256,uint256)","6cd2f731":"setTimePerPeriod(uint256[5])","6cd38ea0":"NebulasToken(address,uint256)","6cd3d326":"getTotalChild(address,address)","6cd40993":"setNeironixProfitAddress(address)","6cd44d55":"pushOrderOfVendor(address,uint256,bool)","6cd49925":"currentLocation()","6cd51833":"initiateWithdraw(uint176,uint64)","6cd522f2":"getContributionRNTB(address)","6cd56641":"EYrickCoin()","6cd56878":"setDeveloperWallet(address)","6cd5c39b":"deployContract()","6cd6043a":"emitAndStore()","6cd61739":"getbuyprice()","6cd7d86e":"setClaimRepository(address)","6cd8015d":"setVestingWithDefaultSchedule(address,uint256)","6cd8f433":"canExport()","6cd8f772":"fights()","6cd8fa85":"burnTrusted(address,uint256)","6cd902d0":"Casa()","6cd9786a":"setCapETH(uint256)","6cd98f30":"getResponseQueryType(uint256)","6cd9db29":"sub_matricola(string,uint256)","6cdacfc4":"startStage(uint256,uint256,uint256)","6cdae459":"YuanBaoCoin()","6cdb3389":"getEntriesCountForCompetition(uint256)","6cdb711e":"ProposalAdded(uint256,address,uint256,uint256,address,uint256,uint256)","6cdc644d":"CMTC()","6cdcb1ca":"DEVELOPER_supply()","6cde3c75":"frozenAccountICO()","6cde6380":"setHash(uint256,bytes32)","6cde71ee":"enteredTotalAmount()","6cde95ee":"getAccountAllowance(address)","6cdf4c90":"ownerSetMinBet(uint256)","6cdf7cdf":"FRO()","6cdfcc6e":"getTokenList(address,uint8,uint256,uint256)","6cdffb3c":"fetchJugadas()","6ce066af":"Give(bytes32)","6ce079fe":"getNumGames()","6ce07efa":"AddSale(uint256,string,string,string,uint256)","6ce0a6a4":"SafeBoxCoin()","6ce12737":"OX_TOKEN()","6ce1417e":"Fund()","6ce15a54":"genericAction(address,bytes32[])","6ce27c7b":"DECIMAL_INDEX()","6ce37387":"KindAdsToken()","6ce3fc06":"sendPrize()","6ce41ab4":"Garuda()","6ce4499c":"adjustCoins(address,int32,string)","6ce4a9a8":"RAMTOKEN()","6ce5b3cf":"releaseHeldCoins()","6ce62c61":"changeAllowances(address[],uint256[])","6ce6833d":"test_updateKey_increaseNoHint()","6ce768dd":"GetMainInvestor()","6ce76ae3":"openOldCrates()","6ce7e739":"getBonusRate(uint256,uint256)","6ce912ab":"LongevityToken()","6cea50a1":"crowdSaleStarted()","6ceac6e1":"TankDeposit()","6ceba55e":"change_fee(uint256)","6cebad98":"newUser()","6cebd885":"waraCoinTransfer(address,uint256)","6cec0ceb":"setDenominator(uint256)","6cec7f92":"canManage(uint32,int256,address)","6ceccc82":"changeICOAddress(address)","6cecdad9":"UpdateAttribute(uint256,address,bytes32,bytes32)","6cedc6ea":"tHasSubmitted(uint256,address)","6cee0d8b":"checkIfAllIQTDistributed()","6cee2d45":"STTR(uint256,string,uint8,string,address,address)","6ceec70d":"whitelistAdd()","6cef5ff4":"FundingAssetAddress()","6cf124c6":"toJackPotfromEveryTicket()","6cf1a452":"chgExchangeRate(uint256)","6cf1cb29":"setGen0SellerAddress(address)","6cf27311":"randomNumbers(address)","6cf32dde":"getMyGolds()","6cf339f8":"CardiumToken()","6cf35782":"m_funds()","6cf3b9e9":"checkBalance(uint256[])","6cf3c25e":"small()","6cf3d099":"dropEnd()","6cf43347":"returnString()","6cf49694":"tweakDailyDividends(uint256)","6cf4c88f":"removeApprover(address)","6cf69811":"trade(address,uint256,address,address,uint256,bool)","6cf6d675":"unbondingPeriod()","6cf70679":"removeFees(uint256)","6cf72694":"OAToken()","6cf75170":"cancelVote(address,uint256,uint256)","6cf761d4":"getMinConfirmationsByAddr(address)","6cf7cff6":"icoETHContributionLimit()","6cf7da53":"setMinerPrice(uint256)","6cf843ac":"LuckyToken()","6cf9bbf8":"setJackpotFactor(uint256)","6cf9cc58":"registerResource(bytes,uint256,bytes,string)","6cf9ea99":"Rhinex()","6cfab740":"RequiredBondRules(address)","6cfb0a4a":"test_oneValidEqBytes()","6cfb2c9c":"payoutToAddress(address[])","6cfb7101":"_emitMonthLimitChanged(bytes32,uint256,uint256)","6cfb782f":"TestWithdraw()","6cfc4512":"authorSignUp(address)","6cfc4ac5":"getGameEnd()","6cfc82ed":"trancheSize()","6cfdc242":"isSalesManager()","6cfe5947":"getCurrentICOPhaseBonus()","6cfedade":"refundTeamTokens()","6cff6f9d":"payoutOrder()","6cff8244":"controllerSucceeded()","6cffa0cd":"_transter(uint256)","6cffd817":"burnByAmount(uint256)","6cfff605":"releaseThreeHotHourTokens()","6d011a12":"scribes_hisory(uint256)","6d013618":"mint(address,uint256,uint256,string,string)","6d01d12b":"XeToken()","6d022003":"ALLOC_SALE_PRIVATE()","6d029f6a":"totalYUPIESAllocated()","6d02a595":"_setMintFeeAbs(uint256)","6d03d3ec":"HolderAdded(address,uint256,uint256,uint256)","6d03fa87":"getReferer(address)","6d04f50d":"mtronix()","6d0501f6":"mediator()","6d052b37":"getRequestByIndex(uint256)","6d052f56":"testBitsSetSuccess()","6d05c24d":"calcWidthraw(string,uint256)","6d05cef4":"getStageSupplyLimit()","6d05da7e":"tranchesCount()","6d061b69":"deathData_a3()","6d064875":"transferEducatedTokenOwnership(address)","6d064962":"getOwnerByShipId(uint256)","6d069c10":"_updateRaceWinner(uint256,uint256)","6d06bf0d":"celebOf(uint256)","6d06de2d":"haveAttributes(address,bytes32,address,bytes32)","6d076966":"VESTING_1_AMOUNT()","6d0797fc":"_isMatingPermitted(uint256,uint256)","6d07e3de":"sexToken()","6d07f295":"minEatable()","6d081d83":"zero_fee_transaction(address,address,uint256)","6d082bbb":"startSpreadingBlock()","6d0831f0":"BNNToken()","6d08bad2":"currencyToHash(string)","6d08e8f9":"initiateChallengeWithPastCustody(address,uint256,bytes32[],uint256[],bytes32[])","6d09e2ec":"commitCurrency(address,uint256,uint256)","6d0a98cc":"blockResolveDispute(uint64,uint64,bytes)","6d0b5ee2":"TeamFundsTokens()","6d0ca12a":"tokensBack()","6d0cc895":"getVersions()","6d0def6c":"SimpleDividendToken()","6d0e5c03":"stampToken(uint256,uint256,uint256)","6d0ecb88":"SohaibCoin()","6d0f131a":"DrawEvent(uint256,uint8,uint8,uint8,uint256,uint256,uint256,uint256)","6d0f157d":"setAllFreeze(uint256,uint256)","6d0f2a84":"changeDefendFee(uint256)","6d0f8806":"refundAdveriser(uint256)","6d102f71":"acceptOrder(bytes16)","6d106885":"unitUserBalanceLimit()","6d1150de":"endCurrentPhaseIn(uint256)","6d11cf72":"berrycoin()","6d11fe82":"_initAwardInfo()","6d121b91":"getMaxCap10X()","6d12301c":"getBetValue(bytes32,uint8)","6d12fb5b":"setSellable(uint32,bool)","6d1478e9":"_addToDebtRegister(address,uint256)","6d14b2a8":"JackpotAmount()","6d156add":"finalizePRETDE()","6d15a659":"Distribution(address,address,uint256,uint256)","6d15cecd":"getTokenRaised()","6d15dc5a":"BetPayout()","6d15f208":"reject(string,uint256,uint16,address,uint256)","6d160f31":"confirmReservedTokens(address,uint256)","6d161bc1":"setdot(address)","6d1669e1":"approveAndCall(address,address,uint256,bytes)","6d16f79c":"__transferWithReference(address,uint256,string)","6d16fa41":"transferControl(address)","6d171f0e":"changeRemainingSupply(uint256)","6d17af94":"ContributionMinted(address,uint256,uint256)","6d181a42":"FTV(address,address,address,address,address)","6d1821aa":"OrenCoin()","6d1884e0":"getEvent(uint256)","6d189422":"EtherFlipRaffleToken()","6d18c778":"PSIToken()","6d18dc63":"ATTR_TRADABLE()","6d1909fc":"transferIDCContractOwnership(address)","6d1917b5":"maxPurchaseNonWhiteListed()","6d19ce04":"STARTING_Dragon()","6d1a0d34":"ShowTime()","6d1af018":"getAmountRaised()","6d1b229d":"burnTokens(uint256)","6d1d71c5":"Note(address,string)","6d1da953":"createWithNonce(bytes32,bytes)","6d1e1f8d":"updateSale(uint256,uint256,uint256)","6d1e2194":"SALES_ALLOCATION_PPM()","6d1e8095":"transferGameOwnership(address)","6d1e839c":"changeMaxCap(uint256)","6d1ea3fa":"approvedTokens(address)","6d1eab7d":"getRegistryVersion()","6d1f00a6":"ThroneMaker(uint256)","6d1f451b":"multiSigWalletAddress()","6d201095":"PRICE_PRESALE_START()","6d214c66":"MBSibalCoin()","6d21f638":"SmartshareStandardToken(uint256,string,uint8,string)","6d224b7b":"weiPerABIO()","6d236703":"createMemoryArray(uint256)","6d2381b3":"addressAndBalance()","6d23bf0b":"ingresarFondos()","6d23c516":"s8(bytes1)","6d23cda3":"sub(uint16,uint16)","6d245bda":"lockUnlockGamblingPartyForBetting(uint256,bool)","6d2570fe":"Before(uint256,bytes32)","6d25924d":"setn(uint256,uint256,uint256)","6d25ba1d":"setTechBonus1(uint256,string)","6d2666b9":"lockInLastSixteenPrize()","6d275e9e":"distributeEbyte(address[],address,uint256,uint256,uint256)","6d277279":"getAuctionsCreated(address)","6d278b29":"setHoldMax(uint256)","6d27a326":"turnOnFurnace(uint16[5],uint128)","6d28e805":"getInsurance(bytes32,uint256)","6d290d34":"setAllocation(address,uint256,uint256,uint256,uint256)","6d295e24":"callDefaultAction()","6d2980f6":"TEAM_LOCK_DURATION_PART1()","6d2a7c8b":"createAuction(uint256,uint256,uint256,uint256,address,uint64)","6d2ab982":"presaleFemaleDiscount()","6d2bf99c":"updatePercentBase(uint256,uint256,uint256)","6d2c51a7":"countrySupply(uint256)","6d2cb794":"airaTransfer(address,address,uint256)","6d2d4e52":"lockSupplierAndLockPosition1(address,address)","6d2d525d":"FFUELCoinTokenCrowdSale(uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,uint256)","6d2dd1a9":"getDividendsForOnePeriod(uint256,uint256,uint256,uint256)","6d2ff3d3":"Geniota(uint256,string,uint8,string)","6d301f38":"MIDO()","6d3036a7":"MAGNITUDE()","6d308c40":"changehiddenOwner(address)","6d30921c":"proceedDividends(uint256)","6d30d07f":"getMiniPoolEdit_6()","6d312683":"feeInCirculation()","6d320b17":"minimumEntryThreshold()","6d32a4a6":"finishRoundD()","6d32dc4b":"startElection(uint256)","6d338bd0":"setCCH_edit_22(string)","6d339f02":"_oldConfig()","6d33b42b":"changeLimit(uint256)","6d33f5a6":"updateNoteContent(uint64,bytes)","6d34a775":"getDatas()","6d35b1dc":"getExtraDays()","6d361694":"getModel(uint256)","6d36ebf8":"addPlayer(address,bytes32)","6d37a9dc":"LCT()","6d38156f":"getCountOfIntegerTypes(uint8[])","6d399eb7":"MAX_AIRDROP_VOLUME()","6d3b5f18":"getUserByID(uint256)","6d3c7ec5":"setDefaultPrice(uint256)","6d3d0a8f":"disagree()","6d3de7ea":"beManagerInsurance()","6d3e141e":"functional(address,uint256)","6d3e1a74":"PiBetaToken()","6d3e4502":"DatToDtrcDenominator()","6d3f008a":"FinalizedTier(uint256,uint256)","6d3f1277":"flagAndFinalize(uint256)","6d4045a8":"EXOSO()","6d40ee41":"CloseDonation()","6d40f3b0":"PHASE_OPEN()","6d417064":"expirationBlock()","6d41a3fb":"firstAuctionsExtendedChunkDuration()","6d425249":"minerNum()","6d435421":"transferOwnership(address,address)","6d43b489":"freeTokens(address,address,uint256)","6d4419e5":"listTopics()","6d44a9cf":"KudosPresaleTokenLockup(address,address)","6d4546a2":"changeTsaLink(string)","6d46398b":"newChannel(bytes32,address,address,bytes,uint256,bytes,bytes)","6d467f04":"ContractTransfer(address,address,uint256,bytes)","6d46c6f5":"referrer1Percent()","6d4717fe":"noFeesList()","6d47ab72":"sellers(address)","6d47fb71":"changeICO(address)","6d47fc60":"Changepro()","6d489314":"terminateLastMilestone(bytes32,address)","6d48ae25":"best_submission_accuracy()","6d492f54":"sendFyle(address,address,string)","6d493bf9":"SOLARCHAINToken(string,string,uint8,uint256)","6d498093":"presaleFinalized()","6d49817b":"refundPayment(address)","6d4a37ef":"cancelEscrow(bytes16,address,address,uint256)","6d4b38a2":"infraIndexToOwner(uint256)","6d4bae72":"_register2(address,bytes32)","6d4be70f":"ethereumSHA3(bytes20,uint24,uint32)","6d4c80ea":"removeNamespaceMember(string,address)","6d4ce63c":"get()","6d4d907c":"maxNumVotesPerAccount()","6d4ee68f":"SendBobsCoin()","6d4fd0ad":"isNull(address[])","6d4fd338":"PPToken()","6d4fe435":"counter_in()","6d505b49":"randgenNewHand()","6d50a2b5":"deleteAllBackgroundImages()","6d50ef2a":"timelockedTokensDisbursed()","6d510a64":"ourTEAM()","6d510f6c":"updatePartners(address)","6d5210d9":"showprize(address)","6d522b19":"multiAccessChangeRequirementD(uint256,address)","6d52f9d5":"mapToNewRange(uint256,uint256)","6d53393b":"getInitializeCreatorValue()","6d538264":"setMigrateAddress(address)","6d540318":"revokeOracle(address,uint256)","6d5433e6":"max(uint256,uint256)","6d54340a":"Blockbin()","6d544e6e":"setStackSize(uint256)","6d54ec91":"registerAndActivateDevice(bytes32,bytes32,bytes32)","6d568c43":"weiToCents(uint256)","6d56d9f4":"setAuction(uint256,uint256,uint256)","6d578781":"changeStageBlcok(uint256)","6d57b2b1":"tokenInitialDetails()","6d57dee4":"sendTokenAw(address,address,uint256)","6d57e2a9":"getAgonIdArray(address)","6d580320":"G2UFundDeposit()","6d580bcb":"FOUNDERS_CAP()","6d584266":"ALLOC_SALE_GENERAL_3()","6d5860d4":"revert(string)","6d58c88f":"changeDepositAddress(address)","6d599136":"personal_withdraw(uint256)","6d59c3be":"buyUFT(address)","6d5b0f6f":"transferCustodian(address,address)","6d5b9427":"onlyWithValidSignature(bytes)","6d5c1621":"LogInsert(address,uint256)","6d5cae52":"QiongB(uint256,string,uint8,string)","6d5d21a9":"setStubFund(address,address)","6d5d7612":"MAX_WITHDRAW_PCT_DAILY()","6d5da09a":"LockChain()","6d5e136d":"_getApproved(uint256)","6d5e3587":"needsEther(string)","6d5e53f6":"createInt256(bytes32,int256)","6d5e78f9":"depositorLimit()","6d5f3e15":"settleBet(address)","6d5f6639":"objectProposal(bytes32)","6d608402":"sendBPESOToken(address,uint256)","6d60bf39":"getPreEntranceFrom()","6d60e6b4":"trustAddress()","6d619daa":"storedValue()","6d624e86":"SideJobCoin()","6d62a4fe":"canTransfer(address,address,address,uint256)","6d63fa32":"getPixelNumber(bytes1,bytes1)","6d640637":"testBetId()","6d643308":"icoDeadLine()","6d64694f":"etherdelta()","6d64a472":"claimSalesAgent()","6d64abd6":"takeEther(address)","6d650b2d":"level_7_percent()","6d66264f":"specifyController(address)","6d6712d8":"hasPermission(address,address,bytes32)","6d6755a6":"gvpe_per_eos()","6d6908bd":"mintTokensBatch(uint256,address[])","6d69fcaf":"addSupportedToken(address)","6d6a01f6":"second_partner_address()","6d6a2859":"assetID()","6d6a4889":"nextReleaseTime()","6d6a6a4d":"decimalFactor()","6d6a761e":"setCouponToken(address)","6d6bc5f5":"identifierToCoordinate(uint256)","6d6c0ec4":"mintProxy(address,uint256)","6d6c2074":"totalTokensForSaleDuringICO3()","6d6caeb2":"poolCapUSD()","6d6d69b6":"allowedToSell()","6d6d70d9":"connectModule()","6d6dcbe7":"deleteResponse(uint256)","6d6e2710":"clearCrowdsaleOpenTimer()","6d6e8312":"addProviderAdmin(address)","6d6ead75":"reject(uint256,address,uint256,uint256,address)","6d6ebb01":"thawSomeTokens(address,uint256)","6d6f385c":"isSaleFinished()","6d6fa6b1":"FNKOSToken()","6d6fb665":"CUSTOM_ERC20_MINT_SERVICE_NAME()","6d701f0a":"Eos()","6d704159":"wdBefore()","6d705ebb":"register(address,uint256)","6d70f7ae":"isOperator(address)","6d717daf":"Albarit()","6d71be4c":"increaseReserve(uint256,uint256)","6d7221d5":"doubleClaimSegmentSlashAmount()","6d72da47":"addElection(address,uint256)","6d730453":"TokensTransferedToOwner(address,uint256)","6d736fac":"feeAccount2()","6d763a6e":"getLeaderboard()","6d771f77":"one_month()","6d773cd0":"balance_out()","6d77cad6":"isOperatorForPartition(bytes32,address,address)","6d77e144":"removeBlacklistItem(address)","6d786740":"billingPeriod()","6d788933":"_distribution(address[],uint256[])","6d78a434":"IntegrativeWalletToken(uint256,uint256,uint256,address)","6d78e48a":"candidateTillXPAAssets()","6d79207c":"SALE_DURATION()","6d796253":"configRoundKey()","6d7a0f89":"EmptiedToWallet(address)","6d7a2609":"setSpenderAddress(address)","6d7a37b6":"OCPresale(address,address,uint256)","6d7ab187":"AcceptsGMOON(address)","6d7b3706":"setfees(uint256,uint256,uint256,uint256)","6d7bc487":"RESERVED_TOKENS_FOR_FOUNDERS_AND_FOUNDATION()","6d7bd3fc":"BANCOR_FORMULA()","6d7cb00c":"CoinMarks(uint256,address)","6d7d083f":"handleFunds()","6d7da0b1":"MyContract()","6d7fa14e":"CQC(uint256,string,uint8,string)","6d7fd1bf":"getIpfs(uint256)","6d7fd8a3":"pauseRefund()","6d80244d":"createUnitOmni(uint32,address)","6d805b2d":"withdrawMana(uint256)","6d813e63":"owner_viewOnFlight()","6d81779b":"teamCap()","6d836cde":"updCouponBonusEnabled(bool)","6d8370e9":"upgradeTusdProxyImplTo(address)","6d842ad5":"NewBOP(address,address,uint256,uint256,string,string)","6d843c2f":"participatedInAirdrop(address)","6d84dbb0":"BeijingCoin()","6d853ab6":"isSubUser(address)","6d863fd7":"airDropSingleAmount(address[],uint256)","6d86ac59":"DUMPSACK()","6d8758c7":"editCuts(uint256[6])","6d877f91":"Bob()","6d87b65c":"setPropertySalePrice(uint16,uint256)","6d88885e":"schoolOrdering()","6d892f7e":"deauthorize(address,address)","6d893a5a":"deathData_a8()","6d8941cb":"smallBonusPercent()","6d8a3650":"dedex(address,address,address,uint256,uint256,uint256)","6d8a5f8f":"CAP_ICO()","6d8a74cb":"getRoom(uint256)","6d8a9f92":"setSavedEthBalance(address,uint256)","6d8ab124":"containsPosition(bytes32)","6d8b529a":"OwnerBase()","6d8c3912":"AicToken()","6d8d151b":"determineBonus(uint256)","6d8d16b9":"StandardToken(string,string,uint8,uint256)","6d8f01d1":"CEOSignature()","6d8f4221":"masternode()","6d8f83cf":"_getBonusAmount(uint256)","6d90164e":"GetPrice()","6d91acba":"proposalText(uint256)","6d9218e5":"Notes(address,address)","6d927db0":"withdrawBalanceMaxSteps(uint256)","6d94425c":"_maxPeriodSalesLimit()","6d94dce1":"createAndBookCanvas(address)","6d952117":"maxBuyPrice()","6d9634b7":"releaseTokens(address[])","6d963a81":"buyp3d(uint256)","6d96a2aa":"delegateAddress()","6d96b537":"_computeIncentiveReward(uint256,uint256)","6d974ee2":"AcceptRealmOffer(uint256)","6d97537a":"TestRushCoin()","6d97786e":"sell(address,uint256,string)","6d97c665":"tokenBonusForSecond()","6d9814e1":"BToken()","6d98571a":"generalTokens()","6d9860d0":"makeFinality(uint256,address,address,bytes32,bytes32,uint256,uint256)","6d98c5e7":"AppleToken(uint256,string,string,bool)","6d98e9fc":"totalWei()","6d98ee4e":"getInitialState()","6d991cce":"openGroupNumber()","6d99aafd":"Collected_Ether()","6d99f652":"resetRaffle()","6d9aa034":"setNamePublicKeyAddress(address)","6d9af813":"updateprice(uint256,uint256)","6d9b06e8":"setProposalDeposit(uint256)","6d9c2bda":"ADV_TEAM_LOCK_TIME()","6d9c8e86":"getCurrentSaddlePrice(uint256)","6d9cb37d":"govtAccount()","6d9cdbc6":"WALLET()","6d9cebb2":"setDiscount(uint8)","6d9d39b6":"isItOpen()","6d9d495f":"minMktTokens(address,uint256)","6d9dcdb9":"tgrNextPartContributor()","6d9f4eeb":"artistTrackCount(address)","6d9fed84":"getJackPotInfo()","6da05cc7":"sectionAvailable(uint256)","6da05f0f":"_requestRandom(uint256)","6da1339c":"_deposit(address,uint256)","6da1833c":"getInstitutionByName(string)","6da1d37a":"sumWei()","6da246ac":"approvePartnerAllocation(address)","6da28481":"balanceOfLockup(address)","6da36c06":"contract_admin()","6da3cd1a":"verifiedUsersOnlyMode()","6da44d61":"SportX()","6da49b83":"nodeCount()","6da4edff":"getPriceSpeedPercent()","6da4fd5c":"TheBeardToken()","6da4fe26":"nextReward()","6da50777":"FreddieToken(address)","6da61d1e":"payoutOf(address)","6da66355":"pause(string)","6da705f5":"isOwnerOfJob(address,bytes)","6da72e7a":"reclaimByReceiver(uint256,address,bytes32)","6da78903":"SwapCreated(address,uint256)","6da79a93":"bid(uint256,uint256,uint256,address)","6da84ec0":"calcMarketFee(bytes32,uint256)","6da9a969":"toBRFWEI(uint256)","6daa212f":"applyPayback(address,uint256)","6daa2d44":"raiseDispute()","6daa9f56":"setExhaustionTime(uint256)","6daaf67b":"REFERRAL_PROGRAMS()","6dabccc9":"setmsg(address)","6dabd069":"emission(address,uint256,bytes32,uint256)","6dac8bea":"PREMIUM_CATEGORY()","6dacda85":"LOCKPERIOD()","6dad2a91":"getWinningAmount()","6dae014c":"test_basic_sanity()","6dae022f":"verifyTx()","6daf0866":"Hungrify()","6dafc6b7":"destructOne(bytes32)","6db1218d":"getAPSchedule()","6db14a1c":"PaulSportsCoin()","6db17f8d":"KriptoNeed(uint256,string,uint8,string)","6db19eb8":"specialGym()","6db31c25":"pay(string,address,uint256,bool,bytes)","6db3a788":"createHero(string,uint256,uint256,uint256,uint256)","6db4ba51":"requireNotEmptyAddress(address)","6db4bbf0":"donotYYYDappToken()","6db5c8fd":"maxDuration()","6db5d3b7":"modifyCommission(uint256,uint256)","6db66268":"remainingTokensPerPeriod()","6db736df":"Writers(address)","6db75799":"set_amount(uint256,uint256)","6db76efd":"decreaseFrozenBalances(address,uint256)","6db7f77c":"requestEarlySettlement()","6db90900":"returnAllRoomsBalance()","6db9ec44":"IWTfund()","6db9ee4d":"MixenCoin()","6dba46ac":"aprMintAdjustment()","6dbb7bcd":"getExecutorRegistry()","6dbd6689":"gupSold()","6dbe060d":"hashTest(string)","6dbe21b8":"setBounty()","6dbe2ebc":"calcUserDivsTotal(address)","6dbe31eb":"testSubBalance()","6dbe4bee":"MoonToken(uint256,string,string)","6dbf8108":"withdrawBounty(address)","6dc043d7":"draw_number()","6dc0a997":"pushAllocation(address,uint256)","6dc12f1c":"EvMigration(address,uint256,uint256)","6dc1a075":"setMaxOpenAttacks(uint256)","6dc1f360":"VersionControl()","6dc214af":"bitCrystalEscrow()","6dc34462":"Timed(uint256,uint256,uint8)","6dc37dee":"changeReviewRules(uint256)","6dc3e97e":"addGame(bytes32,address,address,uint256)","6dc3edcf":"executeExecutable(uint256,uint256)","6dc455a4":"WinnerWithdrew(address,uint256,uint256)","6dc4faea":"withdrawnTeam()","6dc51f1e":"advisoryBoardFundManager()","6dc55f7e":"RANGEEND_7()","6dc56397":"career_path()","6dc57da6":"getTimestampOfDayStart(uint256)","6dc585b6":"toRICH(uint256)","6dc7a627":"canClaim()","6dc7d164":"addSignature(uint256,uint256,address)","6dc88e1f":"addAngelIdMapping(address,uint64)","6dc8dbd4":"calculateMaxTokensIssued()","6dc92426":"makeSellOrder(address,uint256,uint256)","6dc944f6":"withdrawTotalDevEarned()","6dc9ab89":"get_orderAddress(address,address,uint256,uint256,uint256,uint256)","6dca35da":"newCampaign(uint256,address,uint256)","6dcb0cf8":"typeOf(address)","6dcb672b":"EBanker()","6dcba059":"goToNextStep()","6dcd16d7":"computeBids(uint256)","6dcd6eb9":"withdrawPendingAmounts()","6dce14cd":"LBTokenSale(uint256,uint256,uint256)","6dcea85f":"setMarket(address)","6dd01116":"getWishContent(uint256)","6dd0c3d8":"setENGDevAddress(address)","6dd0c51e":"RESERVED_STAFF_GROUP()","6dd0d091":"retaliate()","6dd13a29":"ICOStarted(uint256,uint256,uint256,uint256)","6dd186c4":"YeYingOil()","6dd1f71c":"RTokenMain(uint256,string,string,uint8,address)","6dd22ccd":"getMixParticipant(bytes32,uint256,uint256)","6dd23b5b":"constructor(address,address,address)","6dd28241":"deprecatedSince()","6dd2bfca":"setDevfee(uint256)","6dd35c7b":"topBalance(address,uint256)","6dd3a823":"Neptun()","6dd40168":"preSaleMinimumWei()","6dd40905":"getQuestionVotesAllCount(string)","6dd43d1f":"attachSubscriptionModule(address)","6dd4927b":"reName(string,string)","6dd4c13c":"allowsSignup()","6dd5b69d":"getConfig(bytes32)","6dd5bb11":"oraclize_query(string)","6dd6e673":"buySanSlot(address,uint256)","6dd6e87b":"checkOut(int256)","6dd749ba":"getSpaceById(uint256)","6dd77c5d":"etherToUSDRate()","6dd7d8ea":"vote(address)","6dd8d3bf":"buy_energy(address,uint32,uint32,uint64,uint32,uint64)","6dd9fde9":"transferTokensToNonEthBuyer(address,uint256)","6dda1291":"hotPotatoPrize()","6dda9b24":"bva(address,uint256,address)","6ddc7e65":"gracePeriodAfterRound0Target()","6ddd07f8":"getEngineById(uint256)","6ddd707f":"TDTToken()","6dde33ea":"deathData_a13()","6dde8b18":"removeWhitelistedTransfer(address,address)","6ddf09c4":"ICToken()","6ddf12ae":"ecdouble(uint256[3])","6de00927":"GetUserRank(uint8,address)","6de09e28":"affiliatesAllocAddress()","6de0b375":"openBet(uint256)","6de12905":"updateMeta(string,string)","6de343cd":"SNTPlaceHolder(address,address,address,address)","6de3afc9":"EduCoin()","6de53001":"clearApproval(address,uint256)","6de5897c":"ECOMCASH()","6de60a07":"ContinueSuspendedEmployee(address,uint32,uint32)","6de6220b":"OwnerO()","6de65097":"OwnerRemoved(address,bytes32)","6de685f6":"START_TIME_SALE()","6de74bbe":"setratePreSale(uint256)","6de758a1":"PWGLToken(address,address)","6de79d17":"TIANYECoin()","6de7a31d":"getEvotTokenAddress()","6de84a4f":"bankMultisig()","6de996b4":"getPlayerSpaceshipAuctionPriceById(uint256)","6de9ebb1":"setBlogRegistry(address)","6de9f32b":"tokensMinted()","6dea2088":"MAX_FUNDS_RAISED_DURING_PRESALE()","6deaf623":"calculateEthToVibe(uint256,uint256)","6deb515d":"disapproveInvestorsInBulk(address[])","6dec665e":"motionWaiting(uint256)","6dec7a93":"setInfo(string,string,string)","6ded82f8":"isPaid(address)","6dee2032":"getOpenOrdersOf(address)","6dee275a":"c_STQperETH()","6deebae3":"subtract()","6deefc7a":"sellable()","6def1efc":"getPreviousFeeWindow()","6defbf80":"ready()","6defd595":"getCovfefe(uint256)","6defe0b9":"isTimeOver()","6defe888":"Criptomedicina()","6df006f3":"frozenToken()","6df03165":"setTimeOutAuthentication(uint256)","6df088bf":"winnerDecided(uint256,address,uint256)","6df0a7e7":"setContract(string,string)","6df0b557":"getPlayerSpaceshipAuctionById(uint256)","6df15719":"STWY()","6df1667c":"same(string,string)","6df26327":"additionalEmission()","6df26d14":"startEarlyStage1()","6df3edef":"getSavedBytes()","6df55024":"LogBuyTokens(address,uint256,string)","6df5ee2b":"withdrawPresale()","6df6ca7a":"getDivsBalance(address,address)","6df7f38f":"sellForBitcoin(address,uint256)","6df83012":"startLockUpSec()","6df8359f":"WorkOrderStarted(uint128)","6df86816":"ActionAgonPlat(address)","6df99d81":"CCH_TEL_AVIV_01()","6dfa8d99":"totalEarned()","6dfada86":"mintToken(address,uint256,address)","6dfc15a4":"changelp6(address)","6dfc2fa8":"isInProgress()","6dfe512e":"initPGOMonthlyInternalVault(address[],uint256[])","6dfe869b":"Preallocation(address,uint256)","6dfe8a34":"setSkillName(address,uint256,bytes32)","6dff8216":"cbAddresses()","6e008b35":"calculateResult()","6e034f4d":"tokensaleBuyTokens()","6e038c4f":"firstTotalSupply()","6e051dba":"ReserveTokensHolderMock(address,address,address)","6e0550e5":"stepOneEndTime()","6e0560c3":"doNotAutoRefund(address)","6e05d3ca":"Z1CoinGenesis(address)","6e064f6a":"HedglyStakingToken()","6e06a9ce":"changeTimeOneSession(uint256)","6e06ac9d":"UNSPAM(string,string,uint256,uint256,bool)","6e0712b1":"setIcoParams(uint256,uint256,uint256,uint256,bool,bool,uint32,uint32,uint256)","6e075e30":"reinvestAmount(uint256)","6e0763f3":"RPNCoin()","6e07979d":"tokenBlogs()","6e080d86":"register(string,string,bool,string,address,uint256,uint256)","6e083bc7":"credoEthExchangeRate()","6e094b67":"TPS()","6e09a4ab":"diff(uint256[],uint256[])","6e0b0c80":"MIToken()","6e0bd282":"destroy(bytes32)","6e0c7867":"createDataObject(bytes32,address,bytes32,address,bytes32)","6e0cd415":"isPositionCalled(bytes32)","6e0d98fe":"setProbabilities(uint32[])","6e0da3ee":"WoodToken(uint256,string,string)","6e0da971":"tokensSoldIco()","6e0dd984":"setCapUsd(uint256)","6e0e7e85":"withdrawERC20Compatible(bytes32,uint256,uint256,uint256[])","6e0f8d68":"stage_1_price()","6e0fb1c5":"FOUNDER2_STAKE()","6e101967":"set_iconiq_pre_kyc_bonus_denominator(uint256)","6e106628":"getWinningReportingParticipant()","6e114511":"decreaseTotalSupply(uint256)","6e1180f8":"setOversightAddress(address,bool)","6e120023":"TimestampScheduler(address,address,address)","6e125009":"contractTokensAvailable()","6e1286fc":"getReward(uint256[])","6e12b46e":"requiredPoints()","6e13cdfe":"claimH2()","6e140e6c":"TetherToken(uint256,string,string,uint8)","6e1479c0":"testControlCreateNewRevisionNotOwner()","6e14b71b":"PetsCoin()","6e15266a":"fifty_two_weeks()","6e164e23":"claimTokens(uint256,address)","6e16f9ed":"iBird()","6e173a7f":"storeBlockHeader(bytes,bytes)","6e17e7c2":"nextFieldIndex()","6e18980a":"transferByLegacy(address,address,uint256)","6e18eba5":"ethUSDPrice()","6e18ff05":"getRefInfo(address,address)","6e1907cc":"test21(uint256)","6e1a1336":"setString(string,string)","6e1b6bcc":"checkMyBet(address)","6e1bd323":"MAX_TOKEN()","6e1cf038":"getNumNiceBets(uint256)","6e1d3c0d":"sudoku()","6e1d7d5e":"EtherIbe()","6e1e063f":"claimableRefund(address)","6e1e34c7":"TokensBoughts(uint256)","6e1ece25":"totalFeesValue()","6e1f777d":"createTokenToTeam()","6e2117f7":"forFunction()","6e217d30":"setBuyCourse(uint256)","6e219667":"p3()","6e21fc87":"_airdrop(address)","6e223710":"getRockInfo(uint256)","6e224034":"totalCrowdCoin()","6e22aea0":"AIW(uint256,string,string)","6e22d33e":"getBytesValue(string)","6e22e32b":"setMonethaAddress(address,address,bool)","6e233918":"buyTank(uint32)","6e241c5c":"_createExoplanet(string,address,uint256,uint32,string,uint32,uint8,string)","6e247f29":"Transfer_of_authority_logic(address)","6e2653ca":"AirSwapHandler(address,address,address)","6e275bd2":"transferFrom(address,address,address,address,uint256)","6e27d889":"lockTokens(uint256)","6e2857f2":"setEscrow(address,address)","6e287154":"setLocalRevenuPercent(uint256)","6e293817":"transferWithReference(address,uint256,bytes32,string)","6e2a2d0a":"result_amount()","6e2adeee":"SweetToken(string,string,address)","6e2bf348":"getDiscountByAmount(uint256)","6e2c10a1":"unitedNations()","6e2c732d":"add(uint64,uint64)","6e2cde85":"drawPot(string,string)","6e2d53a6":"TreasureCoin()","6e2d604a":"thrash()","6e2da4b3":"proposeAction(address)","6e2db8d7":"addWhiteList(address,uint256)","6e2e2e4d":"showMessage(bytes32,uint256,string)","6e2e9c3b":"contributedUsd()","6e2e9ee1":"setKYCRequiredToReceiveFunds(bool)","6e2ede03":"getCollateralMarketsLength()","6e2edf30":"ETCSurvey(address)","6e2f0bb8":"newSaddleryCon(address)","6e2f10bd":"changeMerchantBeneficiaryAddress(uint256,address)","6e2f5f12":"sendToFaucet(uint256)","6e2fd470":"sharedExpenseWithdrawn()","6e30418b":"totalPlayerBalance()","6e30d411":"showDevBalance()","6e317da7":"changeRedeemer(address)","6e321105":"losePercent()","6e32295e":"mDestroyTokens(address,uint256)","6e329aa9":"getPotato()","6e32cf8e":"admin_transfer_tempLockAddress(address,uint256,uint256)","6e33bc13":"COINS_TO_HATCH_1STRIPPERS()","6e349188":"MAXSOLD_SUPPLY()","6e3532fa":"getSubscriptionFee()","6e353435":"inputauction(uint256,uint256,string)","6e353a1d":"emergencyWithdrawal(address)","6e359afa":"changeTrueUSDOperation()","6e36893a":"ICOInvestment(address,uint256,uint256,uint8)","6e3706c8":"PRE_DURATION()","6e377202":"isAuthed(address,address)","6e3825d2":"checkMyTicket(uint32)","6e39891c":"currentDividendAmount()","6e39eb85":"resetNumberOfCandidates()","6e3ae353":"changeOrigDev(address)","6e3aff90":"getOrderString()","6e3bbebd":"ZJLTToken()","6e3c5759":"claim_partnerPreICOTokens(address)","6e3d5a9d":"getTopCompanyBlocksInBetween()","6e3de78a":"UNFOMO(string,string,uint256,uint256,bool)","6e3e1318":"takeFee(uint32)","6e3e82f9":"_computeCut(uint256,uint256)","6e3f3f1a":"proposal(address,uint256,address)","6e3f7ba0":"TokenFrozen(uint256,string)","6e3f8550":"walletReserve()","6e403cd7":"sendBread(address,uint256)","6e40975d":"ICOToken()","6e415d37":"farewellTo(address)","6e417c69":"executeRequest(uint256)","6e41a78f":"DRC()","6e41b1ad":"nameTaken(uint256)","6e41efb2":"ThawTransfers(address,bool)","6e4264ce":"initiateDeposit()","6e4324a3":"Cryptopus()","6e439078":"makeLogCancel(address,address,address,address,uint256,uint256,uint256)","6e441752":"teamToken2019()","6e44fcea":"isHoldTokens()","6e459cf1":"CrowdSale(address,uint256)","6e4602c8":"TimereumX()","6e46408d":"indexOfOwners(address,address)","6e4647d6":"vendingCreateCollectible(uint256,address)","6e468a8a":"CelticsCoin()","6e48670f":"zeroSub(uint256,uint256)","6e48a035":"closeVote(uint256)","6e49b1e1":"AnythingAppTokenPreSale(address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","6e4a7b26":"initializeCoins()","6e4a9f4d":"Nguen()","6e4ac25f":"TokenData(address,address)","6e4b0222":"setactivelevel(uint256)","6e4bfb37":"GenaroTokenSale(uint256,uint256,address,uint256,bytes32)","6e4c42a0":"getGameSides()","6e4c9829":"amountsOf(address)","6e4ca716":"totalEthRecieved()","6e4dd931":"GetPotInfo()","6e4df96e":"produceWine()","6e4e5c1d":"revealedCurves()","6e4e87e0":"sendQuickPromoBonus()","6e4eb9cb":"getSeedsSinceLastEvent(address)","6e4ed796":"blocksPerRound()","6e4f33b0":"change_delay(uint256)","6e4f68b5":"PONO()","6e4f749e":"freezeMethod(address,bool)","6e500306":"Bst()","6e50640c":"WinikToken()","6e506ee4":"managementTokenAllocation()","6e50c39c":"serializeState(uint256,int256[2],uint256[2],int256,bytes32,address,uint256,uint256)","6e50eb3f":"setEndsAt(uint256)","6e51be3d":"UmmahDinar()","6e52dcd6":"pauseChannels()","6e5320d1":"changeTokenInformation(string,string)","6e53909a":"setLockAdmin(address,bool)","6e5390d2":"woodAddress()","6e5406e3":"_0xLitecoinToken()","6e54181e":"right75(uint256)","6e5452fe":"OUTCOME_RANGE()","6e553f65":"deposit(uint256,address)","6e555a18":"testCreateContract(bytes32,uint16,bytes32,uint256,uint64,bytes32,uint64,bytes32,uint64,uint64)","6e556725":"initialEndPrice()","6e56dce5":"collectEtherBack()","6e56e5eb":"_emitUserBinded(uint256,address,bool)","6e56e895":"test_defaultPermissions()","6e575537":"MAX_OWNER_PERS_SITE()","6e57e7e0":"payOut(address,uint128,int256)","6e581673":"buyPackWithERC20Tokens(uint8,address)","6e593210":"getActiveSellOrders(uint256)","6e596aef":"moveCeiling(uint256)","6e59e570":"sendToOtherBlockchain2(string,string,address)","6e59f3f3":"createChannel(address)","6e5ac882":"root(address)","6e5aef4d":"getInitTime(uint256)","6e5b064c":"basicPricePerEth()","6e5deca4":"YaoDun()","6e5ecdff":"updateDependencies()","6e5f375e":"setGameStartedDividendPercentage(uint256)","6e5fd38d":"registerMultiple(address[],bool)","6e609af2":"FulfillmentUpdated(uint256,uint256)","6e60cf61":"freedWinPoolToTeam()","6e6260fa":"thresholdNewTokenPair()","6e62825a":"SCDCToken1()","6e62cdab":"nextRoundWinner()","6e62de19":"fundFailed()","6e63015c":"getCertifiersCount()","6e630649":"changeState(uint256,uint8)","6e635673":"deletePullPayment(uint8,bytes32,bytes32,string,address,address)","6e638d3b":"claimIFSReward(address)","6e640f4c":"candidat()","6e658fbe":"myFundsExpireIn(uint256)","6e6656d8":"setCallStackSize(uint256)","6e66644d":"changeStakingFeesOperation()","6e667c35":"contentURI(uint256)","6e66cc38":"TraceToToken(address,uint256,uint256,address)","6e66f6e9":"tokenReward()","6e676b69":"changeVotingRules(uint256,uint256,uint256)","6e67b803":"bid3(address,uint256[],uint256[])","6e680ee7":"CREATORS_WALLET_ADDRESS()","6e68751c":"revokeVestedTokensFor(address)","6e68ec59":"getSoilHumdtyException(bytes32)","6e69e7d7":"maximumNumberOfLoops(uint256,uint256)","6e6a1dc3":"weightedVoteCountsOf(uint256,uint256)","6e6a42ec":"retraitStandard_1()","6e6b4bed":"getArt(string)","6e6b8004":"upgradeGemsSpecial()","6e6beb07":"PreSaleBuy()","6e6bfca0":"cancelJobByProvider(bytes32)","6e6c4c58":"CrowdTmoney2()","6e6ca42f":"RefundError(address,uint256)","6e6ca6f5":"getLastTransferred(address)","6e6d83d2":"cancelLoanRequestAtIndexByLender(uint256)","6e6d9a6c":"Token(address[],uint256[])","6e6e8a02":"addWhitelist(address,address[])","6e6ed399":"priceValidSeconds()","6e6f2fe5":"DentacoinToken()","6e6fe3d6":"ClaimMTU(bool)","6e6ff8a9":"lockDays()","6e70096e":"withdrawEarnings(uint256)","6e70cb07":"getAssetHolders()","6e70de82":"transitionState()","6e720693":"RevokeEvent(address,address,uint32)","6e722fcb":"getIsBonusClaimed(uint256,address)","6e725302":"getRatio(uint256,uint256,uint256)","6e730a67":"setSecondStageEndsAt(uint256)","6e733f50":"getCap(string)","6e743fa9":"punkBids(uint256)","6e74774a":"MHCTokenIssue(address)","6e752548":"finalizeStartTime()","6e754efb":"daysnumber()","6e761a73":"claimDevReward(address)","6e76a89f":"validateReserves()","6e76fb4c":"MemberRemoved(address)","6e779481":"ADVISORS_CAP()","6e77d4bb":"CryptoMountainsToken()","6e787a48":"correctOriginalSupply()","6e78e95f":"CryptoLeaders()","6e79ae56":"deleteOpenAction(string,string,string,string,string)","6e7a824f":"TestCoin(uint256,string,string)","6e7b698f":"drops(address[],uint256)","6e7bc3e5":"addContractOwner(address)","6e7c1700":"getJobName(uint256)","6e7c1c2b":"getWithdrawDigest(bytes32,address,uint256,uint64)","6e7c77b6":"testClaimTokens()","6e7d9dc6":"transferCreatureOwnership(address)","6e7e3b2b":"contributors()","6e7f26ab":"distributeToken(uint256,address[])","6e80a869":"minimalInvestmentInWei()","6e823b47":"controlledBurn(address,uint256)","6e82e86a":"getHash(uint256[])","6e843a74":"AgreementUrlRu()","6e8480e0":"TokenMetadata(string,uint8,string,string)","6e8595f5":"CheckAddressVerified(address)","6e861c0e":"deauthorizeContract(address)","6e880e4d":"PreminedAsset()","6e88147e":"tradeReport()","6e88274b":"GetBetBalance()","6e8851a9":"initSale2()","6e885bd7":"workerPoolHub()","6e88865a":"teamAddressFreezeTime()","6e88a7bd":"referrerFee()","6e88b4ef":"tgeStageBlockLeft()","6e88d5fa":"judgeFakeTokenAndTransfer(uint256,address)","6e899550":"setString(bytes32,string)","6e89d517":"Deposited(address,uint256,bytes)","6e8a3438":"TransferStatusChanged(bool)","6e8a3d4b":"SerpentIsRunning()","6e8a6d12":"updatePriceAddress(address)","6e8ab641":"Arbitragebit()","6e8ac0c8":"developersAllocation()","6e8add02":"setMainsale(address)","6e8b7c23":"numcalls()","6e8c2caf":"gameRunning()","6e8c57e6":"minBalanceToAllowContractCreation()","6e8d3007":"CapitalTechCrowdsale(address,address,address)","6e8d82af":"swapToken(address)","6e8dad74":"retrieveAccountBalance(bytes,bytes)","6e8dba91":"getInitialData()","6e8dc135":"WinnerSelected(address,uint256,uint256,uint256)","6e8ddc7a":"LuxArbitrageToken()","6e8de595":"setBoardMember(uint256,uint256,uint256)","6e8e39d1":"QRG(uint256,string,string)","6e8f7142":"put(address,string,string)","6e8f8d69":"getInvestorsCount(uint256)","6e900256":"addData(bytes32,bytes32,bytes32,bytes32[],uint256[],uint256[],uint256[],uint256[])","6e9067fb":"getRole(string)","6e90a590":"expectedTotalSupply()","6e914d97":"requestAdminTokenTransfer(address,address,uint256,string)","6e929838":"PAXToken(address,address,address,bool)","6e929d4c":"sendIBTCTokenToMultiAddr(address[],uint256[])","6e932270":"dewhitelist(address)","6e939d05":"moveFromState(bytes32,int8[128],uint256,uint256,bytes)","6e93dbdc":"koCommissionAccount()","6e940a29":"changeHost(address)","6e942390":"howMany(uint256,uint256)","6e942f82":"buildingCostWei()","6e947298":"getETHBalance()","6e94d278":"burnReputation(uint256,address,address)","6e95a066":"IouRootsPresaleToken(string,string,uint8)","6e96433f":"multiPartyTransferFrom(address,address[],uint256[])","6e96463f":"BonusesUpdated(address,bool)","6e965a89":"calculateWeeklyTokensSupply()","6e968bca":"getSidesArray(uint256)","6e96bbeb":"crowdsalePurchasesLoaded()","6e96dfd7":"_setPendingOwner(address)","6e97041e":"SCPS1Token()","6e970dfd":"retireMaster(address)","6e974fd6":"approveWalletFeeData(uint256)","6e977865":"dadFab()","6e978d91":"right90(uint256)","6e98a92b":"fundManagementAddress()","6e995bd9":"updateChannelState(uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","6e9960c3":"getAdmin()","6e997972":"modSymbol(string)","6e99d52f":"COOLDOWN_PERIOD()","6e9a41c3":"DraftCrowdsale(uint256,uint256,uint256)","6e9af3f7":"giveForce(address)","6e9b134e":"LogCancelDelivery(address,string)","6e9b41d4":"releaseForGoolaTeam()","6e9c3683":"getIndexByProposalId(bytes32)","6e9c4650":"prepaidUnits()","6e9c4d0a":"rateTenant(uint256)","6e9c931c":"stake(uint256,address,uint256)","6e9cfb79":"itemReturn()","6e9d3b9d":"AtoOneCoin(uint256,string,uint8,string)","6e9e48ef":"tokenIdToOwner(uint256)","6e9ffe2b":"updateTransferRestrictionVerifier(address)","6ea007b3":"dailyLimitLeft()","6ea056a9":"sweep(address,uint256)","6ea07a36":"recoverSimple(bytes32,uint8,uint256,uint256)","6ea11f65":"togglePublicMatches()","6ea141cb":"AddBonusToList(bytes32,uint256,uint256)","6ea150e2":"changeWithdrawTimeRange(uint256,uint256)","6ea16f3a":"tryRefund()","6ea16f81":"houseTraits(uint256,uint256)","6ea34ce4":"getPartById(uint256)","6ea38199":"getMoreAuctionDetails(uint256)","6ea3b6d1":"ICO_Finished()","6ea3f1cb":"GetFreebie()","6ea405d3":"Tax()","6ea412b1":"Exchanged(address,uint256)","6ea42555":"pack(uint256)","6ea451e4":"setSaleLimit(uint8)","6ea51811":"icoStartP4()","6ea521d9":"_voteAs(address,uint256,uint256,uint256,string)","6ea68360":"newMasterCopy()","6ea69c91":"closePositionOnBehalfOfRecurse(address,address,address,bytes32,uint256)","6ea6b71b":"tokensRaised()","6ea6d76d":"initGame(string,bool,uint256)","6ea6db3c":"token(uint256,string,uint8,string,address,uint256)","6ea6f0c3":"initializeTopUpLimit(uint256)","6ea7064b":"contractorProposal(uint256,address,uint256,string,bytes32,address,uint256,uint256,uint256)","6ea79583":"team_wallet()","6ea8efea":"getGameNum()","6ea928d9":"getSymbolHash()","6ea96bcd":"defaultBuyerLastPaidAt()","6eaa0f16":"CCTOKEN()","6eabb2f6":"getWineryOperation(string,address,uint256)","6eabcd69":"__abortFuse()","6eac86d4":"settleTransaction(bytes32)","6eaccf4c":"privilegedTransfer(address,address,uint256)","6eacd48a":"ownerPauseGame(bool)","6eadcc87":"tokenSetup(address,address,address,address,address)","6eaddad2":"setDevPercent(uint256)","6eadeba0":"resolve_block_hash(uint256)","6eae0843":"getTeam(uint16,uint8)","6eaefc87":"tokenExchangeRateBase()","6eafbe88":"ChangeTeamHolder(address,address)","6eb060ea":"setMinBuyPublic()","6eb09ce2":"ethbalance(address)","6eb1546d":"_removeBid(uint256)","6eb1e09a":"fechVoteMainInfoByStage(uint256)","6eb21929":"softcapReached()","6eb227ce":"getCurrentWeek()","6eb25ed8":"distributionOne(address)","6eb267ab":"CxNtoken(address)","6eb2a749":"isMaySale()","6eb2f0cc":"payShareholders(uint256)","6eb305aa":"getTimestampInSeconds()","6eb47ea7":"linkTeamToUser(address,bytes32)","6eb5197d":"getFirstAdmin()","6eb58224":"castDocumentVote(uint8,bytes32,bool)","6eb5ad4f":"lockPriceChange()","6eb5bef0":"addressSupporters()","6eb5ebae":"FidgETHSpinner()","6eb6ffa7":"initialQuorumPercent()","6eb769d2":"tokenTotalSold()","6eb7b4c2":"underdogInfo(uint256)","6eb7c67b":"_getEthPrice()","6eb85627":"Stalincoin()","6eb86537":"getAllPackage()","6eb91683":"donateForContractHealth()","6eba2b13":"getOrder(address)","6eba68f9":"ICOFactoryVersion()","6ebb6d80":"attack(address,uint8)","6ebbe863":"updatePublishContract(address)","6ebbfd5a":"addItemTo(address,uint256,uint256,uint256,uint256,uint256,uint256)","6ebc0af1":"tranche()","6ebc6200":"CURRENSEE(address,address,address)","6ebc8c86":"getContract(uint256)","6ebcf607":"_balances(address)","6ebd9d7f":"setApiRegistryContractAddress(address)","6ebdac12":"removeProductFromCart(uint256)","6ebe299f":"adventureDataContract()","6ebf10fe":"storeHeader(bytes,address)","6ebf5223":"ProofOfSheepM()","6ec012e7":"saleIndex()","6ec03f7a":"removeCrydrView(string)","6ec05f13":"EURWEI()","6ec069f8":"teamOneDivsUnclaimed()","6ec0ce6e":"_isController(address)","6ec232d3":"gasprice()","6ec236ed":"calculateTaskDeposit(uint256)","6ec23e53":"OPTIToken()","6ec25a06":"tokenCreated(address,uint256,string)","6ec2e979":"bothHaveAttribute(address,address,bytes32)","6ec32f9c":"getRepayAmount(uint256)","6ec386d3":"AutoChainTokenCandy()","6ec3af26":"addTrustedIssuer(address,bytes)","6ec40f9e":"GAME_POOL_INIT()","6ec4c951":"claimWithdraw(address,uint256)","6ec4e5b8":"callERC165SupportsInterface(address,bytes4)","6ec5239f":"setAvatar(string)","6ec62f29":"assertEq28(bytes28,bytes28)","6ec6d4a6":"setMinLimit(uint256)","6ec7743d":"getSubjectClaimSetEntryAt(address,uint256,uint256,uint256)","6ec84711":"organizer6()","6ec99dd0":"testGetBlobStore()","6ec9b125":"EtherSphere()","6eca017e":"releaseForYoobaTeam()","6eca4a50":"UKTTokenController(bytes32,bytes32)","6eca6a9e":"updateRecordName(uint256,string)","6ecb97cd":"getInitializeNumOutcomesValue()","6ecbb556":"UAPCrowdsale(uint256,uint256,uint256,address,address)","6ecc9ad9":"getInstallments(uint256)","6ecd1129":"nextAvailableLevel()","6ecd7b70":"CancelSale(uint256)","6ece5937":"endGame(uint256,string,address)","6ece7d88":"doVote(uint256,uint256)","6eced029":"getMsgGasAfter()","6ecf9f7b":"hype()","6ed0b9d7":"changeStage(uint8,uint256,uint256)","6ed28ed0":"store(uint256,uint256)","6ed2d8c6":"giantFYou(address,uint256)","6ed2fc5c":"PRESALE_WEI()","6ed33343":"dsp()","6ed33b98":"addSupportedToken(address,address,uint256,uint256,uint256)","6ed34394":"totalLockPrincipal()","6ed3f468":"sendsignature()","6ed40f9d":"isValid(string,string,uint256,uint256)","6ed43eb0":"getInvestorList(uint256)","6ed4d0c7":"dataCenterGetResult(bytes32)","6ed51d94":"isValidBuyOrder(address,address)","6ed55eb5":"setUserRating(address,uint8)","6ed5777e":"BuyHORSEtokens()","6ed5f880":"withdrawGTA(uint256)","6ed65dae":"sendCount()","6ed6da9e":"getUserById(uint256)","6ed6e17a":"updateCurGamePrizeInfoWithDraw(uint256,address,uint256)","6ed776b2":"createToken(address,address)","6ed7c013":"move_monsters()","6ed84231":"TOURNAMENT_BATTLE()","6ed89fbc":"_transport(uint256,uint256)","6ed963b7":"EthereumTravelCrowdsale(uint256,address,address)","6ed9c19f":"calculateMasked(address,uint256)","6ed9fd89":"avgGas(address)","6edb2e8a":"sellPropertyAndChangeOwnership(address)","6edb4cf6":"testThrowRetractLatestRevisionDoesntHaveAdditionalRevisions()","6edb9ab0":"batchDepositTo(address,address[],uint256[])","6edbba2e":"numFree()","6edbd134":"hasHash()","6edbeb1c":"verificationHoldersTimestampMap(address)","6edc7ba7":"getExchangeFunctionSignatures(address)","6ede2106":"EtherIn(address,uint256)","6ede696b":"PaymentProcessor(address)","6edf1cc4":"getWithdrawalForAddress(address,address,uint256)","6ee0400d":"ICOBonusPercent1week()","6ee1844e":"KnownOriginDigitalAsset(address)","6ee18573":"addWhitelistOperator(address)","6ee2627b":"maxFundLimit()","6ee2e362":"CleanCurrentRoomAndRound(address)","6ee2ed5d":"totalSpinners()","6ee31a18":"upgradeToken(address)","6ee3d453":"modifyGameItemPrice(uint256,uint256)","6ee4b475":"InitialBlockCount()","6ee5d676":"getSumCourse()","6ee61483":"changeBuyin(uint256)","6ee63f1f":"MineableToken()","6ee64345":"endMainSale()","6ee678ae":"_burn(address,address,uint256)","6ee74b3c":"Test5()","6ee7826f":"_getRoundedPrice(uint256)","6ee78aea":"isMultiple(uint256)","6ee7a063":"createInstance(address,bytes32,address,bytes32,bytes)","6ee8067f":"whitelistManagerAddr()","6ee84bb7":"SDD_Erc223Token()","6ee88301":"getRoomOwner(uint256)","6eea4820":"QBT()","6eeb553f":"pollBurnCompleted()","6eeb7a36":"setCreator(address,bool)","6eeba5c6":"short_party()","6eebad9e":"Jitech(uint256,string,uint8,string)","6eebb73f":"activateZone(int32[],int32[],uint8[],uint8[])","6eec21d6":"vault_deposit(address,uint256)","6eec2dd2":"Released(bytes32)","6eec3db6":"allocateAdvisorTokens()","6eecb7c2":"getDomainTypehash()","6eecf81a":"SetPrcntRate(uint256)","6eedc46d":"tokenWalletChange(address)","6eee2dad":"mintRewardTokens(address,uint256)","6eeeca03":"finalizeSale2()","6eef0326":"placeBetOdd(uint256)","6eef2cb7":"functionTwo()","6eef7a05":"bytesToString(bytes32)","6eef908f":"startReceiveTicket()","6ef0a5cf":"singleTransferToken(address,uint256)","6ef0c864":"SetDataAddress(address)","6ef0f37f":"setHome(address)","6ef181a8":"setRarityMultiplier(uint8)","6ef1a114":"transfersRemaining()","6ef1f3a6":"luckyOne(uint256)","6ef27042":"CentraToken()","6ef33b8f":"getInfo3(address,address)","6ef3732d":"fixDividendBalances(address,bool)","6ef3ef7e":"approveData(address,uint256,bytes)","6ef4e8db":"getCalcToken()","6ef61092":"withdrawn(address)","6ef72aaa":"BattleResult(address,address,uint256[],uint256[],bool,uint16,uint256,uint32,uint32)","6ef791bb":"WylSistContract()","6ef8c661":"addInfoListItem(bool,address,address,uint256,string)","6ef8d66d":"renouncePauser()","6ef958df":"changeSource(string,string,uint256)","6ef98b21":"withdrawOwner(uint256)","6ef9bc29":"phase3EndingAt()","6ef9e145":"weiBalances(address)","6efa0621":"SPPSeriesB(uint256,string,uint8,string)","6efa629d":"releaseFees()","6efa6a67":"PAYOUT_PCT()","6efab8f2":"overloadedMethod(address)","6efaf16c":"disableAutoSeller()","6efbb60a":"addONG(bytes32,string,string)","6efbd610":"coownerPrice()","6efd1adf":"RATE_EXPONENT()","6efd5974":"signedApproveHash(address,address,address,uint256,uint256,uint256)","6efe39a3":"getEncryptedKeyFromRequest(uint256,uint256)","6efef04d":"setLevelEndDate(uint256,uint256)","6eff96f2":"rafflepot()","6effb219":"changeCreditFundNIMFAAddress(address)","6effb579":"stop_sell(uint256)","6effdda7":"Trade(address,uint256,address,uint256,address,address)","6effe1c7":"startSale2Phase()","6effec50":"forwardCall(address,uint256,bytes)","6f00a3cf":"DumpDivs()","6f00ad8a":"lastmoney()","6f00fd97":"createTokenTransaction(address,uint256,uint256,uint256,uint256,address,uint256)","6f015889":"Activate(address,uint256,string)","6f0166c4":"GeoGems(address)","6f01d915":"addHedge(address,uint256,uint256,bytes3,bytes3,uint64,bytes32,bytes32)","6f020775":"totalCoinLock()","6f022ac4":"cancelMigration(address)","6f02483f":"EtherGang()","6f024899":"Destructible()","6f025aec":"MolikToken()","6f025c84":"MithrilDemo()","6f03e307":"setTiersInfo(uint8,uint256[],uint256[],uint256[],uint256[],uint8[])","6f03e4f9":"getClientBalances(address)","6f0470aa":"candidates()","6f04ff33":"increaseSalesBalance(address,uint256)","6f0503ad":"setDerivePayoutDistributionHash(bytes32)","6f05994e":"addBalanceFor(address,uint256)","6f0663f0":"RadioCoin()","6f069cfe":"technik()","6f06fdb3":"hasAgreement(uint256)","6f079f90":"getPricingEndsAt()","6f086122":"preSignedHashing(bytes8,address,address,uint256,uint256,uint256,uint8)","6f08effa":"manualBonus()","6f09240f":"runScript(bytes,bytes,address[])","6f0963b0":"isMemberBlocked(address)","6f096f75":"investorPayment(address,uint256)","6f0a150f":"restartRound(bool,bool)","6f0a74d5":"_8_poluchaetLesha()","6f0ac394":"getCP(address)","6f0b5180":"buyFor(address)","6f0cd3a6":"m_active()","6f0cfab6":"DNSResolver()","6f0d0a38":"CrocsFarmer()","6f0f45d2":"OPERATIONS_ADDRESS()","6f0fccab":"getTokenName(address)","6f0fdce8":"Task(address)","6f1003c4":"minEsteemAmount()","6f109879":"impl_transferMSM(address,address,uint256)","6f10d1a0":"addNewToken(bytes32,address,address)","6f10fdbd":"totalPlay()","6f117190":"getInitialTerrain(uint256,uint256)","6f11a859":"availableAirdrop(address)","6f1236e1":"ETHPriceProvider(string)","6f13b95d":"editTokensForHour(uint256)","6f13e01b":"EthVenturePlugin()","6f13eb09":"BlockChainZB(uint256,string,string)","6f1427b2":"icoInProgress()","6f147f5c":"addWhiteListed(address[],uint256[],uint256[])","6f14dc62":"storehouse(bytes32)","6f152670":"max_fundingGoal()","6f15847f":"recordInfo(bytes32,uint256,string)","6f159c4f":"founder_token()","6f16a595":"PRICE_MIN()","6f17a516":"ln_fixed3_lnr(uint256,uint256)","6f181303":"ScriptCallable()","6f18337d":"IHF(address,uint256)","6f18d3f5":"traded_token_is_seeded()","6f1a5b72":"updateTokenHolder(address)","6f1a78cc":"deleteWebsite(address)","6f1aa1f5":"requestTokenIssue(address,uint256,string)","6f1ae5de":"_itemRemoveMarkets(uint256)","6f1c8a51":"_getHash(address,bytes32)","6f1ca0c2":"preicoSupply()","6f1cecd8":"unreadMessages(address,uint256)","6f1db0b7":"createNewBid(string,uint256)","6f1e54c3":"sellMyTokensAmount(uint8,uint256)","6f1e6419":"MANHATTANPROXYYORKAVE()","6f1e738c":"updateISIN(string)","6f1fb766":"sealedBids()","6f200ce3":"transferBlock(address,address,uint256)","6f204f20":"getChannelInfo(address,address,uint8)","6f2130d3":"amountOfCRs(address)","6f2223c5":"getRefereeAddress(address)","6f227851":"USDValue()","6f2293ab":"transferFrom(address,address,uint256,bool)","6f22993c":"moveTokens(address,address,uint256)","6f22d6a5":"losses()","6f24fe30":"notifyPledgeNotPayed(uint256)","6f253319":"CurrentGoldPrice()","6f259077":"STAGE_ONE_TIME_END()","6f2594a0":"moduleMultiOwner(address)","6f264776":"buy10tickets()","6f264b2e":"requiredTokenAddress()","6f26d566":"dailyLottery()","6f28a853":"assertNotSpent(uint256,int256,bytes32,bytes32)","6f28ee09":"storeHash(string,string)","6f290893":"Refund(address,uint256,uint256,int256)","6f29c88a":"exchangedNum()","6f2b1226":"upgradeBank(address)","6f2f098b":"Cite(bytes32)","6f2f7a57":"getWinNumber()","6f2fc06b":"proxyPayments(address)","6f2feb0a":"approveAndSell(uint256,uint256)","6f307dc3":"underlying()","6f30e1ee":"PunkBidWithdrawn(uint256,uint256,address)","6f3165d3":"UpgradeRig(uint8,uint256)","6f320970":"vernamCrowdSale()","6f322fef":"Atra()","6f326ac6":"checkStorageProof(bytes32[],address)","6f32a937":"min256(uint256,uint256,uint256)","6f32b2ac":"setRSPScienceAddress(address)","6f32b4cb":"mainICOSecondWeekEndTime()","6f3355af":"isBreakingCap(uint256,uint256)","6f335870":"sections()","6f3395b2":"_tradeEtherDelta(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256)","6f33ae68":"HouseFeeUpdate(uint256)","6f341804":"activeteICO(uint256)","6f34a7ff":"sanctuary()","6f35c749":"SECONDS_OF_DAY()","6f362c2b":"latestSpender()","6f3640f7":"getRealUsdAmount()","6f36ce79":"insert_deal(address,address,uint64,uint128,uint32)","6f370b20":"Austriachain()","6f373cb7":"PullRequestClaimed(uint256,uint256)","6f374a12":"setBool()","6f37f48b":"firstToken(address)","6f38e410":"maxLevels()","6f3921ee":"extended()","6f3a7561":"SimpleAuction(address)","6f3ad341":"ICO_ONE()","6f3b2819":"secondChainHNw2()","6f3b4759":"lockMultiple(address[])","6f3b60d6":"latestOrderId()","6f3b6d00":"RESERVED_TEAM_SIDE()","6f3b8ce2":"getArrayAddress(bytes32)","6f3b97a4":"DeactivatedContract(uint256)","6f3bb97f":"unsetVipAddress(address,address)","6f3be1da":"lift_ban()","6f3be6b7":"ELEXTROCOIN()","6f3bf6ea":"GMC()","6f3c8566":"redeemWarriors()","6f3d8043":"valueAfterReducingFee(uint256)","6f3f6870":"CertAdmins(address)","6f3fe404":"updateBalances()","6f414fbb":"sale1Started()","6f4215b1":"setEthRate(uint256)","6f42879f":"wantsToFight(uint256,uint256)","6f42934d":"getTimePurchase()","6f42c901":"teamAddresses(address)","6f43233a":"getAnyAddressTokenBalance(address,address)","6f44c4d7":"recipientVIP()","6f4618d8":"firstReserveAllocation()","6f468289":"CONTRIB_PERIOD2_STAKE()","6f475e7f":"validateTransfer(address,address)","6f476cbc":"opMinted()","6f479f57":"changeSellingPrice(uint256,uint128)","6f47b075":"test_set_get_Policy()","6f47e218":"sharesRaised()","6f4812e2":"testFailControllerInsufficientFundsTransfer()","6f48455e":"checkMinMaxInvestment(uint256)","6f488063":"getPOOL_edit_7()","6f494049":"registerPublicKey(uint256,uint256)","6f49a3c0":"openChest()","6f4a2cd0":"distributeRewards()","6f4b31cc":"Bastonet()","6f4bda17":"numberOfPlayers()","6f4be234":"EMJAC()","6f4c6443":"invite(address,address)","6f4ca36e":"Tracto()","6f4ce56a":"indexOf(bytes32)","6f4d469b":"addMembers(address[])","6f4d6f5d":"ShitToken(address)","6f4d80e5":"m_state()","6f4db6a7":"hasRepeat(uint8[4])","6f4dd69c":"testSetBalanceUpdatesSupply()","6f4dfede":"GetExpireTime()","6f4eb87e":"test_removeFromRegistry()","6f4ebb70":"calculate_reward(uint256,address,uint256)","6f4efd53":"POTJ()","6f4f2ec3":"ERC20Template(string,string,uint8,uint256,address)","6f500df5":"claimCofounditTokens(address)","6f503750":"LogPermit(bytes32,bytes32,bytes32)","6f503e67":"vestingOf(address,uint256)","6f512e61":"setSgdToEthRate(uint256)","6f51d01f":"getUserBlockNumber(bytes32)","6f52167d":"payDuel(address,string,address,string)","6f53a48a":"Bitprize()","6f53da8f":"benefitFunds()","6f53df6c":"EtheraffleLOTPromo()","6f540fe0":"setCampaign(address)","6f54e4df":"candyper()","6f54e89e":"getMaximumFunds()","6f5736c6":"getFreeFalcon()","6f5831cb":"startTokensSale(address,uint256,uint256,uint256,uint256)","6f584bd8":"View_TrustlessTransaction_Info(uint256)","6f58659b":"totalRewardIssuedOut(address)","6f59a5cc":"curBubbleNumber()","6f5b286d":"tokenUnsold()","6f5cca83":"withdrawForCompany()","6f5d616b":"execPermissions(address)","6f5d64fa":"FSNASAddress()","6f5d712e":"TOTAL_TOKEN_CAP()","6f5da839":"Token(uint256,string,string,uint8)","6f5da961":"transferEntityOwnerPull(address)","6f5e7398":"dasToken()","6f5eb4b5":"publicSell(uint16)","6f5f20ce":"INITIAL()","6f5f7ba2":"CreatedYUPIE(address,uint256)","6f5f8f74":"Cryptoloans()","6f5f9498":"InitializedManager(address)","6f6007bb":"StartdatePresale()","6f609714":"FrameworkToken()","6f625567":"roleAdd(address,string)","6f62cba3":"resetUserRefBalance(address)","6f62e755":"changeGatewayAddr(uint32,address,string)","6f63d2ec":"left66(uint256)","6f64234e":"sendFunds(address,uint256)","6f64824b":"setErc677token(address)","6f64ccf5":"checkVestingTimestamp(address)","6f652e1a":"createOrder(address,uint256,uint256,uint256)","6f6541e0":"SetLot(uint256)","6f6640c1":"AnthillFarmer()","6f66d23b":"adminGetWorldData()","6f6781d3":"getPosition(uint8)","6f68d634":"acceptTrusteeOwnership()","6f68fffd":"setEndSaleTime(uint256)","6f691500":"getMySecondAmount()","6f698fb5":"setMinimumQuorum(uint256)","6f6aadfb":"SnovPresale()","6f6b32ad":"PVXToken()","6f6b6963":"VestingCreated(address,address,address,uint256,uint256,uint256,uint256,uint256)","6f6bdbe3":"specialUsers()","6f6c0244":"generateShortLink()","6f6c0759":"onlyPayForFuel()","6f6c7234":"setApoderadoVerify(bytes32,bytes32,bytes32)","6f6cd9f5":"isElectionPeriodProposal(uint256)","6f6d3694":"removeRound(uint256,uint256)","6f6eacee":"availbleToken()","6f6f828e":"removeAllTournamentContenders()","6f6f9bef":"getLandInfo(uint256)","6f6ff3bc":"setVesting(address)","6f7030f6":"calculateCuts(uint256)","6f704aa6":"TreasureToken(address,address)","6f70a22f":"deadlineThree()","6f70b9cb":"getWinningChildUniverse()","6f7154c8":"getIsStopFunding()","6f71f407":"freeze(address,uint8)","6f72fd20":"calculateBonus(uint256,uint256)","6f74174d":"finalizeIt(address)","6f741cff":"getPauserList()","6f7429ab":"modifyDescriptionManual(uint256,address,string)","6f7495cb":"unproducedCaps()","6f74dafe":"getGodAddress()","6f752f09":"backendContract()","6f75b00c":"removeBuyer(address)","6f75cd14":"DappToken()","6f766f20":"refundTRA()","6f7705c2":"becomeRichest(string)","6f77926b":"getUser(address)","6f784c5b":"totalAmountOnICO()","6f78ee0d":"rap(bytes32)","6f7920fd":"tokenCreationCap()","6f79301d":"getCreationTime(bytes32)","6f796d86":"JACK(string,string,uint8,uint256)","6f799cf9":"_amountRaised()","6f7b5a56":"getDEditorArbitraryData(bytes32,bytes)","6f7d9acf":"setupInitialSupply()","6f7f461d":"manager1()","6f7fc989":"teamIssue(address,uint256)","6f80602b":"NewOrleansCoin()","6f80dc23":"obfuscatedHashDataBlock(string,string)","6f8177f4":"MentalhealthToken()","6f81adf6":"Resilium()","6f81bdd8":"setRate(uint256,bool)","6f826a7d":"testIsEmpty(bytes)","6f82e068":"initialSupplyPerChildAddress()","6f838a8e":"TESTCOIN1()","6f8489af":"CreateGMT(address,uint256)","6f84eb6c":"setPatronReward(uint256)","6f853964":"setPriceCoeff(uint256)","6f8543a6":"CoWithdraw()","6f85c7e4":"WAITING_PERIOD()","6f85e62c":"buyTokens(string)","6f863c21":"inviteIter_()","6f872022":"setSectionForSaleToAddress(uint256,uint256,address)","6f874abb":"setgasUsed(uint256)","6f87dddd":"getPlayerStageKeys()","6f882086":"KNCBalance()","6f893e0d":"LeeroyPremiumToken()","6f8b44b0":"setMaxSupply(uint256)","6f8b7574":"createTransaction(address,address,uint256,string,uint256,uint256)","6f8c33a6":"getGoldDepositOfAddress(address)","6f8c3c0e":"MIToken(uint256,string,uint8,string)","6f8c3e4c":"SaraAndMauroToken()","6f8c9575":"yearFor(uint256)","6f8d3eb0":"withdrawPAXTR(uint256)","6f8d998c":"dist(uint256,uint256)","6f8dca87":"GetCost(uint256,uint256,uint256)","6f8e0a08":"getreward()","6f8e1fb6":"testOverflowResistantFraction()","6f8ee91c":"level_6_amount()","6f8f1de5":"mock_resetLatestPayday(address,address)","6f8fb2c3":"CROWDSALE_WEI_GOAL()","6f8fccd7":"BioChainCoin()","6f9090db":"setwinPercent(uint32)","6f90be06":"playFromBalance()","6f910c4b":"checkProviderOwnerSupply(uint256,bool)","6f9125a5":"pylonSelled()","6f9170f6":"isWhiteListed(address)","6f919068":"LogUnPause(bytes32)","6f91cec0":"ProvideWorkOrder(address,address,address,uint128)","6f92096b":"setGasForward(address)","6f923a7c":"LockSAToE()","6f925535":"revokeAccess(address,uint8)","6f92f186":"multiply(address)","6f93638e":"isSolvent(uint256,uint256)","6f941290":"SelfDropTokens(address,uint256)","6f9477c0":"BanAccount(address,bool)","6f947d6d":"_emitPublicCapabilityAdded(address,bytes4)","6f94e260":"buybackPriceOf(uint256)","6f94e502":"getVoter(uint256,uint256)","6f954161":"changePreJackpotBidLimit(uint256)","6f95dd0b":"RATE_DAY_21()","6f9607e5":"countYears()","6f964659":"depositMint(address,uint256,uint256)","6f969c2d":"getNonFungibleBaseType(uint256)","6f96f269":"Mehrancoin()","6f977413":"Property(string,string)","6f993a74":"rollFour(address,uint8,uint8,uint8,uint8)","6f9a023c":"theultimatepyramid()","6f9a5eab":"createTx(uint256,address,uint256)","6f9b0b7d":"getCurrentGameState(bytes32)","6f9b4c1d":"createCastleSale(uint256,uint256,uint256,uint256,uint256)","6f9ba978":"_reward(address)","6f9c3c8f":"fundReserve()","6f9c6194":"P2E()","6f9cd7b2":"mirtestToken()","6f9cdccd":"setMarketMaker(address,address)","6f9d257d":"CONFLICT_END_FINE()","6f9d73db":"BuyRocketForSaleEvent(address,address,uint32)","6f9f51c7":"RefundsDisabled()","6f9fb98a":"getContractBalance()","6f9fbd7c":"generateCrabHeart()","6f9fdd66":"trust()","6f9ff0fa":"GetDynamicCardNum(uint32,uint256)","6fa00f07":"agreementSignedAtBlock(address)","6fa01c8e":"init(bool,address,uint128,uint128,address,uint64,address,uint256)","6fa07d0d":"oraclize_query(uint256,string,bytes[5])","6fa0bf39":"getRankDynamic(uint256)","6fa1532e":"UpdateBalance(address,uint256,bool,address)","6fa15c21":"setPreIcoEndDate(uint256)","6fa23eac":"ShouWangXingAIGO(uint256,string,uint8,string)","6fa23f73":"setSupplyLimit(uint16,uint16)","6fa25d9a":"Log2_fnc(address,bytes32,uint256,string,string,string,uint256,bytes1,uint256)","6fa28249":"getClaimsIdByType(uint256)","6fa4095e":"emitHavvenUpdated(address)","6fa42742":"arbitrator_question_fees(address)","6fa4c766":"revertFunds(address,address,uint256)","6fa4f5f7":"setRefPercent(uint256)","6fa58335":"tgeDuration()","6fa64cd6":"miningIncentiveTokens()","6fa65c4f":"MICRODOLLARS_PER_DOLLAR()","6fa668f3":"weiForPayment()","6fa6ad21":"getDeprecated(bytes32)","6fa6c360":"validateTranscriptHash(address,uint256,bytes32)","6fa81a3a":"IcoTimeRangeChanged(address,uint256,uint256)","6fa87f66":"Moongang(uint256,uint256,uint256)","6fa88aa3":"BrazilvsCostaRica()","6fa8de90":"changeMeatParameters(uint256,uint256)","6fa9ba07":"ShowMsg(bytes)","6fa9e255":"LiftUpVets(string,string,uint8,uint256)","6faa22a5":"polyToken()","6faa52b3":"getOwnerHistoryAt(bytes32,uint256)","6faaeca2":"finishBallot(bytes32)","6fab5ddf":"Fal1out()","6fab94c1":"BitplusToken()","6fac46e5":"numberOfRazzes()","6fad0a4d":"KPOP_CELEB_CONTRACT_ADDRESS()","6fae3d76":"access(address)","6faed0e5":"set_master_exchange_rate(uint256)","6faf4803":"BitcoinDiamondTest()","6faf9323":"TokensPurchased(address,address,uint256,uint256)","6fb1eb0c":"commissionFee()","6fb1edcd":"sellAllOutcomes(uint256)","6fb2d01e":"calculateBonusForHours(uint256)","6fb37c18":"TChainToken()","6fb3ba9e":"setWorking(bool)","6fb438dc":"getTotal(uint256[])","6fb487fc":"getListener(address)","6fb4adff":"changeFundWallet(address)","6fb642de":"setActionContract(address,bool)","6fb65c7f":"grantReserveToken()","6fb66278":"ratePreICO()","6fb6fde6":"AuthAdmin(address,bool,uint256)","6fb7110f":"BuckySalary()","6fb7b52e":"addCheck(address,address,uint256,bool)","6fb7e588":"encodeTokenId(int256,int256)","6fb7f147":"getPendingExplore(address)","6fb7fc8b":"deltaBalances(address,address,address[])","6fb8a70d":"responseCounts(uint256)","6fb8b885":"RESERVED_TOKENS_FOR_ROI_ON_CAPITAL()","6fb93e15":"BuyARXtokens()","6fb99dfb":"EventRemoveManager(address,address)","6fb9a2b4":"newCrowdsale()","6fba4aa9":"GUOcoin()","6fba7544":"setMinStartingPrice(uint256)","6fbaaa1e":"currentMultiplier()","6fbb222a":"setExtendedPlayerAttributesForPlayer(uint256,uint8[])","6fbb439e":"assign(string)","6fbc15e9":"upgradeTo(address,bytes)","6fbc8456":"setUID(uint256,uint32)","6fbcd0f6":"AnitiToken(address,uint256,uint256)","6fbcd1fb":"_getAltarRecord(uint256)","6fbd6f6b":"acceptContactRequest(address)","6fbdae47":"getArrayInfoForDepositCount()","6fbde40d":"setSaleAuctionAddress(address)","6fbe769d":"cards_black_total()","6fbf466c":"unscannedCaps()","6fc141da":"lastPaydayTS()","6fc14837":"setMaxStake(uint256)","6fc1cbbd":"RexToken()","6fc21429":"setgamecardintro(uint256,string)","6fc351c2":"Elsevier(uint256,uint256)","6fc3911c":"checkVerificationStatus(address)","6fc39a38":"changeAgencyReceiver(address)","6fc3b0b6":"getTime4(address)","6fc3c817":"confirmer()","6fc4f2c2":"isOnPreAuction(uint256)","6fc559bb":"tokenGrants(uint256)","6fc651f3":"TokenAGC(uint256,string,string)","6fc65924":"getDisputeEndTime()","6fc6df36":"fYou(address,string,string)","6fc8e920":"icoBonus4EndDate()","6fc90a2f":"submitSolution(uint256,string,bytes)","6fc98ee1":"mintTokens(address,address,uint256)","6fc9958a":"initBundle(uint8,uint256)","6fc9d5e4":"changeCompareTo(uint256)","6fca2023":"getSharedAccountsLength()","6fcac869":"BONUS_4_DAYS()","6fcaea0c":"set_iconiq_presale_open(bool)","6fcb0153":"issuanceLastAverageBalance(address)","6fcb1500":"defaultSweeper()","6fcb4463":"signUpOn()","6fcbb546":"extractOre(string)","6fcc52e7":"gujarat()","6fcdcb3e":"setOwnerLink(address,uint256[2])","6fce2d65":"updateAccount(uint256,uint16,bytes32,uint16,bytes32)","6fceaea2":"convertToMiniGGC(uint256)","6fcebff8":"ConversionSentToShapeShift(uint256,address,address,uint256)","6fceecf8":"withdrawRestriction(address)","6fcfbe85":"FAFA(address)","6fd075fc":"addPlayer(address,uint256)","6fd09735":"createDistrito(uint256,address)","6fd1bdea":"setProduct(uint256)","6fd2e6d0":"TFFC()","6fd37039":"WebPaisa()","6fd396d6":"lastRewardTo()","6fd3a2bc":"createTokensManually(address,uint256)","6fd42b32":"safeWithdrawal(address)","6fd44086":"adviserSupply()","6fd463ed":"addressOfTokenUsedAsReward1()","6fd5036d":"userChannelsCount(address)","6fd507f2":"Tube()","6fd5790d":"getCuota(uint256)","6fd59b01":"foundationFundMultisig()","6fd5ab58":"getTextBytes96()","6fd5ae15":"level()","6fd63728":"feeFunds()","6fd7c035":"EventRedeemStatic(address,uint128,uint256,uint256)","6fd7c34c":"setMemberRegistry(address)","6fd8282f":"priceLastUpdateRequest()","6fd86d44":"emitAccountUnfrozen(address)","6fd902e1":"getCurrentBlockNumber()","6fd9101f":"ACAToken(uint256,address)","6fd9227e":"TokenSold(address,uint256,uint256,bool)","6fd98bee":"updateTimes(uint256,uint256)","6fda5534":"rockOwningHistory(address)","6fdada81":"proofOfRich(string,string)","6fdb4f42":"revokeUsers(address[])","6fdbc590":"CreateDil(string)","6fdc202f":"ownerTransfership(address)","6fdc45a3":"BangdiToken(address)","6fdca5e0":"setOpen(bool)","6fdcc8a9":"listRecords()","6fdd2ab4":"createStage(uint8,uint256,uint256,uint256,uint256)","6fdd5f58":"ShopKeeper(address)","6fde3dc0":"getRunesValue(uint256)","6fde8202":"upgradeabilityOwner()","6fde90bc":"setCCH_edit_2(string)","6fdf9a3f":"sendToRstForAddress(address)","6fdf9f28":"setBDError(uint256,bytes)","6fe00356":"investorIDs()","6fe02e98":"tier3Rate()","6fe0e395":"initialize(string,string,uint256,uint256)","6fe11695":"isMajority(uint256)","6fe12f07":"proverka6()","6fe1dbec":"sendSupportETH(address,uint256)","6fe1f6b4":"BAD_ERC20()","6fe33720":"YOTOKEN()","6fe356ea":"moduleIsExist(string)","6fe3a567":"tokenMigrated()","6fe3ef7c":"resolveEntityAddress(address)","6fe497f0":"lockStatus(address,bool)","6fe4c195":"lockAddress(address,address,uint256)","6fe5091e":"collectPayout(uint256)","6fe5b536":"testFailSetEnforceRevisionsNotOwner()","6fe64289":"RepuToken()","6fe665e9":"SlotMachine()","6fe691dc":"getUserTransactions()","6fe69dee":"RealtyCashToken()","6fe7567b":"_subPurchasedFrom(address,uint256)","6fe7f51c":"saleWasSet()","6fe83236":"getAllCardAddressesCountOfOwner(address)","6fe8c29e":"JEY()","6fe8f9c5":"freeTokens()","6fe9e7d7":"freezeUserFunds(address,address,uint256,uint256)","6fe9f632":"preICOrates(uint256)","6febfd02":"getSiteRewards(uint256)","6fee558c":"getHookOperatorContractAddress()","6fee8458":"burnExcess()","6feef2bf":"cancelTknOffer()","6fef4fa9":"setAllowedToSell(bool)","6ff026e7":"purchased_snt()","6ff03fc2":"_removeMaster(address)","6ff08dd6":"calcWhiteBase(uint256)","6ff10dd7":"TrioPeriodicTransfer(address)","6ff1c9bc":"emergencyWithdraw(address)","6ff1ed71":"pickUp(uint256)","6ff1f2b8":"refererPercent()","6ff26ebb":"longBuy()","6ff2817c":"batchDetachAssets(uint256[])","6ff28657":"Josephtoken()","6ff2c12a":"setMiniPoolEdit_6(string)","6ff36340":"eTimesChain()","6ff46ba7":"deathData_a10()","6ff5a670":"PortalToken()","6ff6c4b8":"setCreatorFeePercent(uint256)","6ff73201":"setCooldownTime(uint256)","6ff79410":"numberOfComponents(address)","6ff89159":"revokePermission(address,string)","6ff8a27e":"buyTokens(address,uint16,address)","6ff8e332":"allowedAirDropTokens()","6ff93476":"tokensAllocatedForFs(address,address)","6ff968c3":"successor()","6ff97f1d":"allTokens()","6ff9db5b":"msgHash(bytes)","6ffa1257":"etherSoftCap()","6ffa1caa":"double(int256)","6ffa1d48":"LogCreateICO(address,address,uint256)","6ffa1ea7":"getRegulatorProxy(uint256)","6ffb341e":"calculateKebabBuy(uint256,uint256)","6ffbff9c":"importMET(bytes8,bytes8,address[],bytes,bytes32[],uint256[],uint256[],bytes)","6ffc0896":"checkIfSuccess(bytes32)","6ffc13ab":"POMPAMCOIN()","6ffc22b8":"finalizeReservedAddress(address)","6ffcc719":"bet(uint256,uint256)","6ffe67f2":"autoDestruct()","6ffea7bd":"preToken()","6fff0652":"changePlayerTeam(uint256,uint256)","6fff15ee":"percPoints(uint256,uint256)","6fffffff":"HDK_Crowdsale()","70011870":"credexx(address,address,address,uint256,uint256,uint256)","7001a2a2":"elcoin()","7001fcc2":"closeImports()","700215d0":"SellFinishedAutos()","70021705":"watchVideoC(address)","7002a4e0":"setPartIndex(uint256,uint256[])","7003433a":"setRealityCheck(address)","70037a71":"setPresaleWhitelist(address,bool)","7003a1a3":"EosBlock()","7003ce6f":"UController()","70049c1c":"forwardEherToOwner()","7004a914":"ArbitraryLocker(address,uint256,uint256,uint256,uint256)","7006d538":"verificaCertificato(string,bytes32)","7007adc9":"finalBlockNumber()","7008a4a3":"firstWavePrice()","70090164":"PRIVATE_ADDRESS()","70097106":"addContent(string,string,uint256)","700a7db1":"setCriterionTime(address,uint256)","700b7025":"EthereumHotCoin()","700c9474":"addUsers(address[])","700d3230":"isPiSale()","700dd5eb":"AuthorityNotified(string,string)","700df1f6":"setMigrationStabitcoinAddress(string)","700e17b5":"setData(uint256,uint256,uint256,uint8[])","700e8660":"Marriage(string,address)","700ef803":"SafeBox()","700f3a1d":"addToken(string,int256,bytes)","700f4e40":"test_invalidProxyOwnershipTransfer()","700f55b2":"addTx(address,address,uint256,uint256)","700f9d03":"logEndBal()","7010129a":"tokenTransferVIP(address,uint256)","70101735":"releaseReservedTokens()","70103ea7":"setPaperFee(uint128)","70107c43":"_zthToken(address)","70119d06":"incBy(uint256)","70133e4f":"Xerium()","70144f8f":"activate_kill_switch()","70150282":"FMWorld(address,address,address)","701513c0":"addBooking(uint8,uint256)","70152dcf":"getPrivacyCoins()","7015913c":"end(bytes32)","70165470":"ICOFailed(uint256,uint256)","70183a4d":"stakingExpiration(bytes32)","70185b7e":"updateSafeBalance(uint256)","7018665b":"transferMS(address,uint256)","7018dcb9":"getCastleNum()","7018e950":"affiliatesAllocation()","701969e5":"Penny()","701adee0":"setRequireWhitelistedAddress(bool,address)","701b4063":"balanceOfAtBlock(address,uint256)","701b4631":"hasPayroll(address)","701b8826":"forwardTo(address,address,address,uint256,bytes)","701d9ced":"setTransferOCE(bool,bool)","701dfb92":"HTL()","701e1dfc":"lastInvestorsProfit()","701e5729":"canInvest(address,uint256,uint256)","701e5e71":"_purchaseCar(uint256)","701fd0f1":"reveal(bytes32)","702056de":"REKTtoken()","70206b05":"RepoHandler(address)","7020940a":"NewHope()","702123ae":"unitCoinProduction(uint256)","70212761":"saleFinalize()","7021fad7":"CheckoutLimDay(address,uint256)","70220023":"participantsFor3rdSale(address)","70228400":"isDonatedEthTransferred()","7022b58e":"confirm()","70232f00":"ClaimESC(address,uint256)","70239222":"testSHA256()","70239f0b":"serverEndGameConflictImpl(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,bytes32,bytes32,uint256,address)","70243248":"PeggleCoin()","70245bdc":"adoptCat()","7024ce7b":"BONUS_ICO_ROUND1()","702510be":"payoutSelf()","7025b3ac":"ROLE_KYC_VERIFIED_INVESTOR()","70260363":"setSignatures(bytes32,bytes)","702617e7":"ERC20(string,string,uint8)","70267867":"_addBridgeTokenFee(uint256,uint256)","70269774":"changeOwnerOfMonethaUsersClaimStorage(address)","7026aa04":"getProveHash(address,bytes32,string,bool,uint256,bytes32,uint256)","70279554":"budgetAllocation()","7028439e":"bonusPreIco()","70284d19":"grant(address)","7028875e":"changeStrikePrice(uint256)","7028b3b9":"GetConsentDataCount()","7029144c":"init(string,string)","702921f5":"month()","70296790":"clever()","702a3eff":"advisorsCliff()","702a5f4f":"setLLV_edit_31(string)","702b5f0b":"calcHash(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address)","702b7bc3":"insertValueBonus(uint8,uint256,uint256)","702c25ee":"nextMinimumPodSize()","702c728e":"changeCloudsPerEth(uint256)","702c789e":"select_bua_position(uint256)","702cbbae":"isTokenAvailable(uint256)","702d58d8":"JiJieHao(uint256,uint8,string,string)","702efdf3":"suspended()","702f23a6":"transferAndFreezeMulti(address[],bytes32[],address,address,uint256[],uint256[],uint256[])","702f9019":"Start_qui_qz(string,string)","702fc7da":"ReviewModel()","70316f00":"getUserPayedInCurrentRound(address)","70320126":"newWitness(address)","70320234":"calcBonusTokens(uint256)","70324b77":"darknodeBalances(address,address)","70328770":"logBalance(uint256)","7032d758":"SevillavsBayern()","7033e4a6":"supportsHistory()","7033f1ac":"TNTCoin()","7034c939":"test_2_destroyTokens()","7034d190":"MainSaleBuy()","70354053":"UCCoinSaleIsOff(uint256)","70357e79":"func_08D3()","70359b36":"makeSuperVisor(address)","7036f9d9":"force_partial_refund(address)","7037602a":"setAccountData(address,uint256,uint256)","7037ec6f":"payEntryFee()","70385f0d":"LogPolicyAccepted(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","70387c59":"hashVerification(bytes32)","70393686":"getCOOHashing(address,uint256)","703950ff":"viewKarmaVotes(uint256)","7039dcdc":"setBEY(address)","703a6beb":"getUnitsPerPeriod()","703aca29":"competitorExists()","703add31":"animatorAddress()","703b1411":"requestSellforFX(uint256)","703bf91f":"betSingle(uint256)","703c8a99":"_openProvider(bool,string,string,uint256,string,uint8,bool,address)","703dbd81":"setPI_edit_8(string)","703df793":"updateHardCap(uint256)","703e905b":"getIndexByHash(string)","703eb724":"addShare(address)","703ee574":"CoinvillaSupply()","703f5e8a":"CaDataAddress()","703fa81c":"DOSTToken()","7040bcc9":"createPlayer(uint256,uint256,string,string,string,string,string,string,address,uint256)","7040f3e5":"Allowance()","70416f7e":"getCurrentEthFee()","7041d925":"outsize(bytes4,bytes)","704248ec":"tokensale()","7043ca8e":"getOwnerNickName(address)","7044ce75":"setTKC(address)","70459be2":"transferLeftover()","7045b469":"TotlePrimary(address)","704691e1":"LuckToken()","70477e2b":"Rozium()","70480275":"addAdmin(address)","7049a425":"MarketboardListingDestroyed()","7049cd98":"LinglongCatCore()","704a60f1":"failUserRefund(uint256)","704b164d":"setTradeIsOpen(bool)","704b6c02":"setAdmin(address)","704d4051":"periodSalesLimit()","704d4ab1":"getLostAndFoundMaster()","704d4db0":"poolTotal()","704dcedd":"LSC(uint256,string,string,uint8)","704dd019":"changeFeeCut(uint8,uint8)","704e3dda":"TokenSalePaused(bool)","704e7437":"bountyPart()","704f1b94":"registerUser(string)","704f236c":"freezeAccount(address,address,bool)","70502c5a":"testDeleteItem()","70505653":"arbitrationAddress()","705099b9":"refundTicket(address,uint256)","7050a1ea":"TimetechToken()","7051a831":"setIsContainerForReportingParticipant(bool)","7051b075":"TransferToBuyer(address,address,uint256,address)","705211f4":"approveAccess(address)","7052dad9":"withdrawRemainingTokens(uint256)","7053fe8d":"finalize_contract()","70544b74":"emergencyDrain(uint256)","70544eb9":"hijackPrice()","7055011b":"escrowHistory(address,address,uint256,uint256)","7055060f":"bulkStoreHeader(bytes)","7055410b":"retrait_5()","70557298":"testTransferFrom()","7055d368":"vote(uint256,uint256[])","7056b50f":"blockstillcontracthackable()","7056d1f4":"burnLotIdsByAddress(address)","70578bda":"SPMTToken(address,uint256)","705791f2":"TOKEN_STARTED()","7057c20d":"CFD(address)","705882f2":"setPOOL_edit_22(string)","7058901e":"mtcDailyLimit()","70590ca2":"batch(uint256[],address[])","7059194e":"deletePlayer(uint256)","70597cb1":"startCompanySell()","70598a8e":"subTokenBalance(address,uint256)","705a3644":"block3()","705a940a":"disableBondingCurve()","705b164f":"acquireFreeEgg()","705b37f4":"getTotalF1()","705b5c27":"transferVestingMonthlyAmount(address)","705b7efd":"preSaleContributions()","705b8845":"askQuestion(string,string)","705bbf6b":"updatePrenup(string)","705bbfe6":"eastadscredits()","705bd32a":"fundDevelopment(string)","705ca5cd":"getMultiRequestIdGivenRequestId(uint256)","705d528d":"_addMoney(address,uint256)","705dae11":"cancelCraftAuction(uint256,address)","705e798e":"getLastRoundInfo()","705eeb90":"MultipleConstructorTest(bool)","705f4630":"chfCentsPerEth()","705f911d":"FareBase(uint16,uint16)","705fbf3d":"burnTokensAndRefund(address,address)","705fe7c6":"testEqualityBytes()","7060054d":"dynasty()","70606cda":"supportFreezeQuorum()","7060bfe4":"busyWork(address,uint256)","706194b9":"elenctraToken()","7061e777":"Etats_financiers_10111011()","70620168":"createBroker()","706247a1":"SetVotingDescripion(string)","7062640a":"newDeal(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","706332d1":"right46(uint256)","70634626":"getBTCAddr(bytes32,int256,bytes32,int256)","70646896":"DOWN_etherWin()","70646de9":"canSend(uint32,uint32)","7064aa96":"APPROVE_CONTRACT()","7064b5aa":"getPendingExploreItem(address)","7064d509":"tokenBonus()","7064e50c":"tokenIssuedMainSaleIco()","7064f0af":"COMPANY_ALLOCATION()","7065bedc":"getSettingValuesByTAOName(address,string)","7065cb48":"addOwner(address)","706605b9":"withdraw_arbitrary_token(address)","70660f7c":"stakeExistingContent(bytes32,uint256,uint256,bytes8,uint256)","70670a20":"Ethash(address[3])","7067e881":"RATE_FACTOR()","7067f915":"Constructed(address,uint256)","706910ff":"buy(uint256,address,uint256,uint256)","7069e746":"stakingEpochStartBlock()","706a3604":"sethardcap(uint256)","706a99fb":"codeExportEnabled()","706aba4a":"RNDInvestor()","706b5759":"RegisterDomain(string,string)","706df8d6":"getDonationInfo(uint256)","706dfe54":"getIssueState(uint256,bytes32)","706e11bc":"StartRebuy()","706e5b6e":"getOTCTotalSupply()","706eb3ab":"ethUSDOracle()","706ed71b":"Bomx()","706f6496":"goldRate()","706f6937":"airdropTokens(address[],uint256[])","706f8856":"jiGouTotalBalance()","706ff617":"mint(uint256,uint256,address,uint256)","70708a3c":"LocalToken()","70712939":"removeAuthorizedAddress(address)","70713209":"TJCoin()","7071688a":"getValidatorCount()","707188c1":"changeTime(uint256,uint256)","70720fe4":"_maxTokenSoldICO()","7072a977":"gasForOraclize()","7072aaa3":"newSubdomain(bytes32,bytes32,bytes32,address,address)","7072c6b1":"restricted()","70732188":"getUserTaskAtIndex(address,uint256)","7073c072":"getRegisteredUsers()","70740aab":"purpose()","70740ac9":"claimPrize()","707424fe":"contributorsIndex()","70743768":"voteStake(bytes32,uint256)","70747544":"currentCapLevel()","7074c091":"preSaleBonus1Percent()","7075b1d8":"latestMonarchInternal()","7076738b":"_emitWorkPaused(uint256,uint256)","70767f6c":"fillBidByAddress(address)","7076e27f":"riskcoins(uint256)","70775a59":"_generic(bytes,uint256,address)","707789c5":"setOpsAddress(address)","7077c11f":"SubOnHold(uint256,bool,address)","70780a7a":"shareholder2()","70788340":"Marcelo()","7078f424":"getHint(int256,uint256)","707913f0":"Add_totalLotteryValue()","707a4e96":"start(uint256,uint256,uint256,uint256)","707a7ab3":"acceptOwnerTransfer()","707a92b8":"FoodCoinToken(uint256,string,uint8,string)","707afb1d":"closest(uint256,uint256,address)","707b543d":"createNumber(uint256)","707ba39e":"VilzToken()","707bd28b":"endAirDrop()","707bda7a":"GetLastRoomAndRound(address)","707bdf58":"MaxTokens()","707c4f05":"sendAllFunds()","707c6b4d":"blocksInSecondCapPeriod()","707c750e":"sixthTime()","707d4349":"createPromoCity(address,string,uint256)","707d5fe1":"payoutBonuses()","707dd840":"TAGCASH()","707e8128":"all_referrals_count_by_address(address)","707f4ecd":"crowdTokensTLP2()","707fe454":"MODXCOIN()","70809757":"dispute(uint256,uint256,bytes32)","7081150a":"iconToken()","7081d5da":"getPoolAvgHatchPrice()","708238a0":"mainSaleFirstBonus()","708260b4":"teamToken2018()","7082b421":"parseBlockHeader()","7082d203":"lend(address,uint256,uint256)","70835d98":"CoinAllocation(address,int64,int64)","70835f6b":"approveAddTokenData(uint256)","70844f7a":"sendBadge(address,uint256)","708484db":"blikedUntil(address)","708547f3":"testUpdateLawyer()","70858679":"YDHTOKEN_M(string,string,uint256)","70859da8":"TokenReturn(address,address,uint256)","7085b579":"b2s(bytes32)","70862562":"distributeTokens(address,address,uint256)","7086528e":"DemocracyVote()","70876c98":"purchase(uint256,uint256)","7087b272":"Coneus()","7087ed2c":"getClaimSeed(address)","70887eb9":"totalSoldTokensWithBonus()","7088abf0":"WhiteListCrowdsale(uint256)","7089e4f0":"LogBuyEnabled(bool)","708a4947":"getOptionState(address[3],uint256[3])","708b2097":"TKCC(uint256,string,string)","708b34fe":"submitMessage(string)","708b9d01":"lockThreshold()","708bf79a":"updateMember(address,address,uint256,uint256,string,uint256)","708c2956":"YouGive(uint256,uint256,string,string,address,address)","708cfb25":"setTeamTokensHolder(address)","708d0c57":"updateResolver()","708d9fd3":"group_key_confirmed()","708da969":"verifyAddress(address,string)","708ddf7b":"submitted()","708e03d9":"distributionOfTokens()","708eef42":"transferOwnershipWithHowMany(address[],address,uint256)","708f29a6":"getTotalPayments()","708f8940":"getEXECUTION_GAS_OVERHEAD()","70905dce":"emergencyAdmin()","7091e0c5":"setNewOwner(address,uint256)","70926370":"EGGS_TO_HATCH_1BANKER()","70936880":"defaultWaitTime()","70936a6e":"freezeOf()","7093ab11":"privateSell2LockEndTime()","70948956":"PolicyPalNetworkToken(uint256,address)","7094d21e":"isSuccessOver()","70961774":"getBlockCreatedOn()","7096b6cb":"receiverContractAddress()","7097048a":"claimDerivativeTokens()","70983e91":"startBoardProposal(uint256,address)","70984e97":"bigBlind()","70985eb6":"setCrowdsaleContract(address,address)","7098ad13":"PropertyCoin()","7098e670":"getFincontractInfo(bytes32)","70994b31":"getCollectibleDetails(uint256)","709a36e6":"getMiningMeta(uint256)","709a5359":"updatepresaleRate(uint256)","709bc0ff":"AntitiredToken(uint256,string,uint8,string)","709be206":"registerCreatorsPools(address[],uint256,int256)","709cc16e":"NewCup(address,uint256)","709cf8c0":"saleTokensVault()","709d8c4e":"DSPLT_A()","709e6ed4":"upgradeIdRange()","709eaa93":"minerCreatedCount()","709ecb39":"findPublisher(address)","709ef231":"sellTokens(uint256,uint256,uint256)","709f5ccc":"setDivisor(uint256)","709f6f25":"setData_19(string)","709f84a4":"PriceStrategy()","70a0014e":"projectFundingFail()","70a01b3d":"addInvestor(address,bool)","70a0246a":"toPony(uint256)","70a06777":"getTankAuctionEntity(uint32)","70a08231":"balanceOf(address)","70a0c458":"getBindAccountAddress(string)","70a0f1fe":"numChametzForSale()","70a14c21":"LogBump(bytes32,bytes32,address,address,address,uint128,uint128,uint64)","70a2b84a":"toggleAvailability()","70a4fc11":"toggleDataViewWindow(uint256)","70a6c4bb":"receiverWithdraw()","70a7b3e8":"_validEstimate(uint256,uint256,uint256)","70a7e2dd":"getBunny(uint32)","70a8609e":"test_someOtherTest()","70a89986":"addContribution(address,uint256,uint256)","70a951ce":"TripCash()","70aac052":"getRequestedProductsBy(address)","70ab2359":"MAX_CROWDSALE_CAP()","70ab2822":"assertEq21(bytes21,bytes21,bytes32)","70ab8ba8":"creditUpdate()","70ac4bb9":"right32(uint256)","70ac62ec":"getTranslationLanguageList()","70ac970b":"test_24_assertGasUsage700Boards()","70aca69a":"lockUpEnd()","70acbe0e":"rate_change(uint256)","70aceae8":"upX(uint256)","70ad0cc6":"delAddr(uint256)","70ad858b":"infoWithdraw13()","70ae882f":"finishNextGame()","70ae92d2":"nonce(address)","70ae992a":"pubKeyToAddress(bytes)","70aecf61":"getContractReceiver(address)","70b0d4ac":"GetAccountIsNotFrozenForReturnCount()","70b1d9d4":"requestCanonicalFormat(bytes)","70b257a4":"pushClient(address,bytes32)","70b2a30f":"tokenToEth(uint256)","70b2ef56":"EntropyTestToken()","70b2fb05":"bettingEnd()","70b3b0e5":"countriesWallet()","70b3c7de":"CrypteloPublicSale(address,address,address,address)","70b3d68c":"signHash(uint256)","70b3db6f":"getCoinAge(address,uint256)","70b45ca0":"_rateFromDay(uint256)","70b57415":"product2_pot()","70b581ad":"finalize(string)","70b60760":"getNodeIdsLength()","70b7596b":"getWinnings()","70b7f9f3":"setTradingAllowed(address,bool)","70b80d77":"WCME()","70b8206c":"getRoundRefIncome(address,address,uint256)","70b8d29a":"saveMsgByAdmin(string,string)","70ba1113":"percent()","70ba3339":"cancelTransaction(bytes32)","70bab35d":"systemStartingPriceMin()","70bad87e":"revokeFarmerCertificate(address)","70bb478f":"makeTrade(address,address,uint256,uint256,uint256,uint256)","70bc52fb":"protectAddress(address,bool)","70bdd155":"oracle_price_decimals_factor()","70be4ffa":"testErrorUnauthorizedSetPackage()","70be564b":"Trump()","70be61d1":"ApplicationInFundingOrDevelopment()","70be89c1":"addAddressesToWhitelist(address[],uint256)","70be8a86":"ownedCoin(address,uint256)","70bf7b96":"_collect_fee(address,address,uint256)","70c0b647":"getOwed(address)","70c0c516":"directMintLimit()","70c0f689":"getApplicationState()","70c10578":"takeProfit()","70c18199":"getResponse(uint256)","70c1854e":"FLOCK()","70c31afc":"tokenImprint(uint256)","70c33b31":"changeGasRequired(uint256)","70c35951":"referralPercentOfTotal()","70c40842":"_setTokenOwner(address,uint256)","70c4488d":"validNick(string)","70c494fc":"ATC()","70c4ce24":"newListing(string,uint256,string)","70c4f2e1":"MIN_SHARE_OF_POWER()","70c55e1f":"getTradingPairCutoffs(address,address,address)","70c5f786":"TEAM_CAN_CLAIM_AFTER()","70c5fc9d":"clearTickets()","70c690f4":"MultiOwnable(address[],uint256)","70c6abf5":"resetAllData()","70c6b20c":"newEntity(uint256,uint256)","70c7e230":"change_status(string)","70c80630":"isOwner(uint32,int256,address,address)","70c8251d":"AttributesSet(address,uint256)","70c83314":"airDropToken(address,uint256)","70c8405b":"GiftGenerated(address,address,address,uint256,uint256,string)","70c8658a":"getNewRegistry()","70c8f8ad":"createFirstRound()","70c9edb7":"BTCRelayTools(address)","70ca4c26":"getLinkedAddress(address,address)","70ca6446":"AnotherMethod(uint256,uint256,uint256)","70cbed78":"oracleCallbackGasPrice()","70cc5e45":"kgtHolderCategory()","70ccd928":"hashesLength()","70cd89eb":"CRLperMicroEther()","70cd9bfd":"GPRDSQToken()","70cda533":"updateCoeff(address,uint8,uint128,uint256)","70cddf74":"addApproval(address,address,uint256,uint256)","70ce0765":"createPromoListing(uint256,uint256,uint256)","70ce90d5":"ConfirmManager()","70cef2b8":"getVisaPrice(address,uint256,uint256)","70cf7508":"isValidAirDropForIndividual()","70cfaa8d":"calledUpdate(address,address)","70cfab63":"chargeFeeAndLockEthBalance(address,uint256)","70d01861":"adminSetCity(address)","70d02691":"getAssetBalances(address)","70d07575":"awardTokens()","70d084c0":"SingularDTVCrowdfunding()","70d0c5d8":"EOUNCE()","70d0cc86":"getElementView(uint256)","70d12c31":"resetPeerWallet()","70d1383d":"createEditionMeta(uint256)","70d17adb":"isDrawn(uint256,address,uint256)","70d19a43":"itemCancelMarketsWhenPaused(uint256)","70d1cde4":"randomCount()","70d1e6b4":"minimalWeiTLP2()","70d22f14":"addHash(address)","70d25a9f":"lockUpAmountStrOf(address)","70d271ab":"StartCampaign()","70d290b5":"getDoneAddresses()","70d37810":"makersCount()","70d383dc":"createManyProxies(uint256,address,address)","70d4d119":"giftEth(address,uint256,string)","70d4d7b4":"promoGen0()","70d53be5":"find()","70d54287":"VantageToken()","70d5ae05":"burnAddress()","70d60adf":"acceptBid(string,uint64)","70d66693":"drainToken()","70d695f7":"VerifyEd25519Packed(bytes)","70d70e9b":"getCofounders()","70d72d63":"getAllPixels()","70d762c2":"basicDayPercent()","70d7a0e7":"authorizeKyc(address[])","70d81666":"LogS(string)","70d8915a":"getApplicationAddress()","70d94ed0":"getHoldAmount(address,uint256)","70d9f7dc":"awardItemRafflePrize(address,uint256)","70db69d6":"maxBuy()","70dbb783":"AMBASSADOR_TWO()","70dc4de5":"withdrawKRI(uint256)","70dc8259":"totalDistributedi()","70dc86cd":"EARLY_FOUNDERS_CAP()","70dd2e06":"setMinActivatedToken(uint256)","70ddeb03":"CRMTToken()","70de1e30":"getItemItemId(uint256)","70de8c6e":"start(string,uint64,uint8,uint32)","70dea79a":"timeout()","70df42e1":"changeBurnBounds(uint256,uint256)","70e0abb1":"returnInvestmentRecursive(uint256)","70e0bd61":"setTrustedMinterAddr(address)","70e18692":"cancelIncompleteOrders()","70e32ae7":"firstBonusLimitPercent()","70e3ccf7":"initMiaoMiaoAddress(address)","70e44c6a":"Withdrawal()","70e4b809":"_setBuyTime(uint256,uint32)","70e5bf4d":"queryVote(uint256)","70e6b2b9":"makePayableRegistration(bytes32)","70e6d387":"evolveCryptoAvatar(uint256,uint256,uint256,uint256,uint256)","70e71ea3":"etherandomSeedWithGasLimit(uint256)","70e7732d":"getSpecificSellerTransaction(address,address,uint256)","70e87aaf":"move(uint8)","70e8c1b3":"test_complexNewProposalAndVoting()","70e8dffa":"TokenHold(address,uint256)","70e9a612":"BariCoin()","70e9ff60":"cancelBuyOrder(address,uint256)","70eaa1b4":"Error(uint32)","70eae6c0":"travelTotalEarning()","70eb6424":"setSmsCertificationRequired(bool)","70ebf814":"addUntrustedSelfDelegation(bytes32,bytes32,bytes32[2])","70ed0ada":"getEthBalance()","70ed1664":"organizer3()","70ee555c":"returnTickets(uint256)","70ee9edd":"PublicMiningReward()","70ef14de":"Drops(uint256)","70f0c351":"purge()","70f0dfee":"MultisigWalletZeppelin(address[],uint256,uint256)","70f18295":"TokenPETER()","70f18bcd":"UnlockToken()","70f199d2":"indAddress()","70f37d27":"fundPool()","70f4c18c":"oracleQueryType()","70f5b71c":"createController(address,address)","70f5d3de":"WthdrawToCreator(uint256)","70f6489e":"WHOIS(address)","70f65977":"_migrateToken(address,address)","70f6ac15":"RegistrationDeposits(address,address)","70f6c906":"_refundWEICustomer(uint256,uint256)","70f705ba":"ChargersCount()","70f74228":"TokenATC(uint256,string,uint8,string)","70f79b84":"SEO()","70f80828":"reactions(uint256)","70f85731":"setPhaseEndingCriteria(uint256,uint256,uint256,uint256)","70f8de1f":"changeGasFee(uint256)","70f9c021":"forcePay(uint256,uint256)","70fa66db":"deauthorizeCasino(address,address,uint8,bytes32,bytes32)","70fbf6e5":"openGamePlayNos(uint256[])","70fd37cf":"totalInvestments()","70fde32c":"mul(uint96,uint96)","70fe19a3":"blocktubeFarming()","70ff6325":"withdrawTuneBalances()","70ffe53d":"mood()","71007509":"refundTokens()","7100a4e6":"addAccessory(uint256,string,uint256,uint256)","71026acc":"EXPECTED_START()","7102b728":"vested(address)","7102c138":"Standard_Token(uint256)","7102f74d":"recalcTokenPrice()","71037b1e":"flagUSInvestor(address)","71039256":"BUCToken()","7104a142":"getNumberOfVerifiers()","71056a78":"ChangeEtherGasProvider(address)","71061398":"getRoles()","7106312c":"emergencyAddr()","7106bd46":"mintContractByIndex(uint256)","7106cdb6":"CloudexchangeCrowdsale(uint256,uint256,uint256,address)","7107283f":"create_tablet(bytes32)","7107d7a6":"minBuy()","710908c9":"levelThreeBonus()","71098a35":"startStop()","71098e15":"totalSTC(uint256,uint256)","710ad128":"getHatchingEggData(address)","710b2d8c":"getAddressRatio(address)","710bf322":"proposeOwnership(address)","710c6705":"updateCapFlex(uint32)","710cba8b":"isAllowedOverrideAddress(address)","710d6a61":"unPauseTransfers()","710dff42":"isdrawadm(address)","710e5d2f":"setMaxFee(uint256)","710edb10":"multisignWallet()","710ee68e":"DOGEToken()","710f3953":"add_entity(string)","710fe6f8":"getWithdrawBalance()","710ffc72":"changeTribeOwner()","71101891":"DharmCoin()","711085b2":"arr(address,address,uint256,uint256,uint256)","7110ce25":"MyRefReward()","7110eed7":"createRegistryInstance(address,address)","7111abf2":"SessionOpen(uint256,uint256)","7111ed97":"TopPayCoin()","71135f8b":"setStopped()","7113d35d":"pickFood(uint256,string,string,uint256,uint256)","7113e5e2":"findKey(address,uint256,uint256,uint256)","71140942":"MIN_ETH_FUND()","71145486":"rebuildManagerList()","71147d32":"STRC_ADDR()","7114a96e":"transferReferral(address)","7114c13a":"sendTaster(address)","71156c73":"TheFund()","7115c8bd":"xdao(uint256,string,string)","7115c988":"Batch(address)","711619de":"setPubEnd(uint256)","711748a3":"removeModuleAtIndex(uint256)","71175249":"INEXToken()","7118f854":"icoSuccess()","711953ef":"setGameAddress(address)","7119a490":"setBtcPriceProvider(address)","7119c873":"transferSSPRecord(address,address)","711b4871":"getOptionBuyOrders(uint256,uint256)","711bf9b2":"setAuthorized(address,bool)","711bfa89":"month12companyUnlock()","711c2b94":"setTestMarket(bytes32,bool)","711caf40":"transferStep3(address)","711cbc26":"PartyRegistry()","711d11bf":"ev(string,address,uint256)","711d4407":"updateBonuses(address,address,bool)","711d649b":"getCatNames()","711f63bf":"toBytes32(bytes,bytes,uint256)","7120d381":"getUpdateTokenAge(address,address,uint256)","7120fab4":"discountCollect()","71215af6":"DAYS_28()","712173de":"CrowdsaleStarted(uint256)","71221e38":"RareCoinAuction(uint256)","7122e857":"setParticipantWhitelist(address,bool,uint256)","7123691e":"removeSERAPHIM(address)","71236b92":"Owner(address,uint256)","712394b6":"nexumToken()","71245f6e":"BTCValue()","7124abf3":"getLastPayouts()","7124c683":"setUpdateInterval(uint256)","7124d613":"changePaymentAddress(address)","71254d9b":"setFeesDistributionPercentages(uint256,uint256,uint256)","7126a855":"configure(uint256,uint256,uint256,uint256,uint256)","7126b6ff":"_grantAdmin(address)","71270b46":"initCards(uint256)","7128ad73":"PaymentReceived()","7128defb":"removeSupervisor(address)","712980a2":"banUser()","712a10bf":"COIN_SUPPLY_ICO_PHASE_2()","712a5094":"balanceOfTheContract()","712aa191":"isValidCustomerTxPaymentForKWh(address,bytes32)","712ac60e":"onRemoval(string)","712b1ed0":"triggerInput()","712bb1b8":"getDataColla_AA_01(string)","712c0c5a":"withdrawDirectDebit(address[],bool)","712c3f7a":"addressPartnershipsAndExchanges()","712ca0f8":"getOrder(string)","712dd575":"raiseSellOrderCancelled(address,uint256,uint256,uint256,uint256,uint256,int160)","712f22a0":"getVolumeBonus(uint256)","712f4d70":"_generateShortLink()","712f5e72":"SetRoundTime(uint256)","712f7790":"publicGetStatus()","713081d0":"setPromoter(address)","7130d7ce":"get_asset_event_details(bytes32,uint256)","7132d337":"citadelTransfer(address,uint256)","7132ebcd":"switchPaused(bool)","7133c0c0":"calcAmount(uint256,uint256)","713494d7":"setReferralFee(uint256)","7136982b":"getHolderCount()","7136d509":"playCEELO(bytes32,uint256[6])","7137047a":"setDealCancelRate(uint256)","7137b024":"Banliang()","7137e072":"getAllTemplateProposals(address)","7137ed47":"setProxyContract(address)","7138364b":"adventureItem()","7138bc92":"transfer(address,address,address)","7138e0c9":"divForSellBack()","7138ef52":"right9(uint256)","71393c60":"storeLedgersInIpfs()","713942f7":"getUserVerified(address)","713955e8":"ico2endTime()","71395818":"ItemsMarket()","71398637":"batchToApplyMilestone(uint8,address[])","7139b1ca":"balanceOfRoutingCode(bytes32)","7139b595":"withdrawDthShopAdmin(address,address)","713a7eef":"Xingqiub()","713b563f":"database()","713be000":"checkoutCart()","713be126":"changeRateSetter(address)","713d30c6":"updateState(int128,uint128,uint8,bytes32,bytes32)","713eba52":"OwnershipRequested(address,address,bytes32)","713ec905":"recordAddress()","713f5e4d":"sendEthToContract()","713fd253":"Limit_Amount()","713ffc3b":"setNextGameSettings(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","714064f3":"BreakableBond(address,address,uint256)","7140bdf3":"get_all_best_offers()","7141856d":"getNumProps()","7141aa8b":"getTitulaire_Compte_3()","7142087c":"allowTransferGlobal()","71427ac1":"SuperLitecoin()","7142b17d":"dataForOwner(address)","7142b191":"MultiplesaleAirdrop(address[],uint256[])","7143059f":"getParticipant(address)","714383ad":"HYPEToken()","71443c4d":"soldDragons()","714490ab":"WithdrawToBankroll()","7144e81e":"Cremit()","71450e30":"tierIndexByWeiAmount(uint256)","7145644c":"calculateBTS()","71461be9":"getCurrentMilestoneProcessed()","7146bd08":"MAX_PURCHASE()","71476f35":"clear(address,address,int256)","71478fae":"_getTokenIdFromBytes(bytes)","714897df":"MAX_VALIDATORS()","71489835":"isRed()","7148ba36":"_createCard(string,uint256)","71492685":"getTo()","714a2f13":"assertEq(int256,int256,string)","714b1443":"CancelBuyOrder(bytes32,address,uint256,address)","714b4465":"MakerTransferredEther(address,uint256)","714c5d9d":"BMT(uint256,string,uint8,uint256,string)","714ca446":"adopt(uint32,int256)","714ccf7b":"setVault(address,address)","714d497a":"maxPerExchangeBP()","714d582e":"sdc(address)","714d5fae":"cancelRemoveOwnerRequest2()","714d9537":"cancelEvent(bytes16)","714dc20d":"ownerChanged(address,address,address)","714e2ec9":"vanilCoin()","714e42a1":"getSaleRate(uint256)","715018a6":"renounceOwnership()","71506977":"EXCHANGE_RATE_DECIMALS()","7150773d":"donateFunds()","7150d8ae":"buyer()","71513e9d":"reSet()","71515a36":"SXSYCoin()","7152f800":"gameResult()","71535f0d":"tenthTime()","71543cfc":"unWhitelistUsers(address[])","71543f39":"Eetgccoin(uint256,string,string)","715469d0":"logoX()","7154ae61":"CheckNumbers(uint8[5])","7154b798":"addExploreData(address,uint256,uint256,uint256,uint256,uint256,uint256)","7154b8b5":"setPercent(uint256)","71551178":"testDisputedInvalidSequenceWrongReadAddress()","71560f80":"emulatePurchase(address,address,uint256,uint256)","715851a0":"getCheckingBalance(address)","71586383":"totalTokensReceived()","71587988":"setNewAddress(address)","71589d6b":"newponzi()","7158e346":"NatCoinCrowdsale(uint256,uint256,uint256,address)","7159271d":"publicsalestartTime()","71599987":"increasePendingTokenBalance(address,uint256)","7159a618":"operate()","7159db81":"lastTier()","715b208b":"getAllAddress()","715b99f8":"_isSignedPrefixed(address,address,bytes32,uint8,bytes32,bytes32)","715d4a64":"sellsubscribers()","715d574e":"CarboneumToken()","715db6ea":"TheMark()","715e0e4e":"repurchase(address,uint256)","715ed24b":"setVIPThreshold(uint256)","715eddda":"starbaseEpAmendment()","715ede94":"auction(bytes32)","715ef43d":"newPurchase(address,uint8,uint8)","715ef4ff":"resendFailedPayment(uint256)","715f8975":"JOINT_PER_ETH()","7160138c":"unlockedTeamStorageVault()","71608d05":"getBalanceModificationRounds(address,address)","71612620":"transferFST(address,uint256)","71616b84":"calculateTokenCrowsale(uint256,uint256)","7161c5df":"setBracketPrice(uint256,uint256)","7161c66d":"RunManager(bool)","716210d8":"addHodler(address,uint64)","7162f182":"resetRip()","716344f0":"preIcoEndTime()","716437b5":"testApproveTransfer()","71645971":"toList()","71658552":"getUint(address,bytes32)","71658896":"getTopic(uint256)","71674ee5":"maximumIcoRate()","7168e5d3":"ownerSetAdmin(address)","71697efa":"getSumWithdrawals()","7169a63e":"IcoCancelled()","7169afa6":"getOldFrozenAccount(address)","7169dd5d":"intial_supply()","716adc36":"setMyOracle2(address)","716af639":"minePoP(address,uint256)","716c0a31":"computingCharge(uint256)","716d3c6c":"adjustReward(uint256)","716e5604":"startItemRaffle(uint256,uint256)","716f10bf":"isWhitelistOn()","71716992":"ThankYouToken(uint256)","71726f69":"HOWEOToken()","7172a1f2":"testLedgerCreation()","7172d9f0":"OtomatizToken()","71740d16":"numDarknodesPreviousEpoch()","7174164b":"XPTToken()","71748a8b":"WSR(address)","7174ac9e":"setEscrowedTaskBalances(uint256,uint256)","71752d06":"getOwnerByItemTypeAndId(string,uint256)","7175d709":"SPARCAddress()","71765e74":"VendMultiSigWallet(address[],uint256)","71766ae3":"disableManuallyBurnTokens(bool)","71773fc2":"lasttimereduce()","7177a7dd":"canTransferTokens()","71781a79":"subToken(address,uint256)","71784312":"distributeVariable(uint256,address[],uint256[])","71793195":"__isFeatureEnabled(uint256)","7179d079":"mainFundBalance()","7179ed22":"autoPrice()","717a195a":"setOutcome(int256)","717a945a":"USD_Omnidollar()","717b3726":"transferFromBank(address,uint256)","717cb858":"ZUE()","717cee7d":"updatePeriodDuration(uint256)","717d5527":"getMoney(address)","717de52e":"creditCommons()","717e1418":"VebionX()","717e9745":"setNewControllerAddress(address)","717f24c6":"emergencyWithdraw(address,uint64)","717f6f7f":"MYCCToken(uint256)","717fecea":"vesting2Withdrawn()","717fedf0":"getFirstActiveDuel1()","717ffe91":"buyTokensAsset(address,address,uint256)","7180dd8a":"_giveToken(uint256,uint256)","718167c4":"AddValues(uint256,uint256)","718228fa":"totalTeamContributorIdsAllocated()","7182774d":"exchanged()","71827791":"nextContributorIndexToBeGivenTokens()","718350a9":"_removeMaliciousValidatorAuRa(address)","7183616c":"notarize(string)","7185354b":"changePerEthToBlocNumber(uint256)","7185393c":"updateAppExec(address)","7185637b":"DailyDivsSavings()","71857000":"setLogic(address)","7185acb8":"viewMyComponent(uint256)","7185f163":"stopTrading()","71863031":"isPublicIcoActive()","71868032":"addOffChainAddresses(address[])","71873971":"PROOF_TOKEN_WALLET()","71882ab0":"distributeContest()","7188c8a4":"reFunding()","71892e3f":"getMyKnowledge()","718aa629":"NEX()","718b0a32":"withdrawBuyDemand(uint256)","718bd6dd":"setRequestUntil(uint8)","718c025a":"ethPreAmount()","718c6569":"TimeSecondToken(uint256,string,string)","718cc769":"makeBet(uint256)","718d763a":"playerCost()","718da639":"addNewSecretHash(bytes32)","718da7ee":"setReceiver(address)","718df9d7":"getPlayerSpaceshipUpgradesById(uint256)","718dfb7e":"hasPreICOClosed()","718e6302":"play(string)","718e6c44":"isManageable(address)","718eaa50":"setLayerParent(address)","718ec079":"setMarketCreationCost(uint256)","718f81c2":"getCCH_edit_11()","71906087":"airdropToAdresses(address[],uint256)","719102d7":"createItem(uint256,uint256,uint256,uint32)","7191474b":"pendingUFT()","71929547":"OceanScapeCoinAdv(uint256,string,string)","7193ab70":"balanceUnlocked(address,address)","7193b1e4":"refundCfd(uint128)","7193f2f0":"supported(bytes32)","719591c7":"requestComputation(string,string,uint256,uint256)","7195d944":"dataOfPart(uint256,uint256,uint256)","7195eed2":"EtalonGlobalToken()","71974cbe":"lastBidBlock()","7197c6d2":"firstTTax()","719874da":"profitFromCrash()","7198801d":"getWorkTime(uint256,uint256)","7198e08c":"createLoveBlock(string,bool)","7199139f":"TheAbyssDAICO(address,address,address,address,address,address,address,address,address,address,address,address)","7199f6d4":"safedrawal(uint256)","719a0f8c":"removeOfficer(address)","719b2e07":"setDisputeRoundDurationInSeconds(uint256)","719c78ac":"setCodedate(uint256)","719c86e3":"team_lock_count()","719ce353":"Brokenwood()","719ce73e":"prizePool()","719f2fb7":"_calTeamAttribute(uint8,uint8,uint8,uint32[11])","719f3089":"getLocks(address)","719f8d3a":"checkIfWhiteListed(address)","71a009ad":"BRLTOKEN()","71a03078":"TMCToken(uint256,string,string)","71a04009":"newIssuer()","71a18bfb":"emergencyDrain(address)","71a2e46d":"OWN_transferOwnership(address)","71a2f964":"newPaymentAddress(address)","71a4dc5e":"getLuckyblockEarn(bytes32)","71a5367f":"setAllowPaymentsWhenPaused(bool)","71a66e7c":"addOrUpdateHolder(address)","71a67aa9":"getFunctionAuthorizationHash(address,address,string,bytes32)","71a7462e":"balance_(address,address)","71a7c439":"distribute21ST(address[],uint256)","71a80ba3":"setBurnFeeReceiver(address,address)","71a8270a":"buyObizcoinTokens(address)","71a8ba25":"getEtherBoxes(address)","71aa60fd":"calculateTokens(uint256)","71aad2dd":"preICOamountBonusLimits(uint256)","71ab0e3c":"sellDai(uint256,uint256,uint256,uint256)","71ac5c60":"WeToken(address,string,string,uint256,uint256)","71ad3e73":"isMakePermitted(uint256,uint256,address,address,uint256,uint256)","71ada3fb":"getCash(uint256,address)","71ae8f02":"fundingMinimumTargetInWei()","71ae973e":"createGen0Auction(string,string)","71aeae44":"hasBallotEnded(uint32)","71af5d0e":"setFailedVerificationSlashAmount(uint256)","71afc713":"marketingTokenAmount()","71b1d2d3":"RANGEEND_PRESALE()","71b22e61":"EnableRefund()","71b2354d":"MINC()","71b3659e":"currentTokenPrice()","71b397cf":"getCurrentRoundIsFinished()","71b45696":"StcToken()","71b475d0":"STQPreICO3(address,address)","71b4f4ef":"setDEXContractAddress(address)","71b505ad":"setLargeCapWhitelistParticipant(address,uint256)","71b5ee71":"allowTokenTransfer()","71b6663e":"play1(address,uint256)","71b6a376":"setNumberOfPlayers(uint256)","71b6d36d":"isNotaio(address)","71b6d6ea":"getAttributeTimestamp(address,bytes32)","71b7d5c4":"priceUpdateWaitingTime()","71b804ee":"getBettingPrice()","71b80b8f":"upgradeCardConfig(address)","71b9b646":"saleEnabled()","71ba3612":"Plasma()","71bad4d8":"jackpotMinimumAmount()","71bb263d":"contractPartThree(uint256)","71bb3cc8":"GivethCampaign(uint256,uint256,uint256,address,address)","71bbefc7":"payPlatformOutgoingTransactionCommission()","71bc9d62":"_generateDetail(uint256)","71bd1f47":"MinCapReached(uint256)","71bdb914":"softCapLimit()","71bdbc9a":"SetCityData(address,uint256,uint256,uint256,uint256,uint256,uint256)","71bde852":"_startNextCompetition(string,uint32,uint88,uint8,uint8,uint16,uint64,uint32,bytes32,uint32[])","71be0c27":"preSale5()","71be1851":"ShopDeployed(address,uint256,uint256,uint32)","71be8766":"Contribution(address,address,uint256)","71beae97":"currentCoinsCreatedPercentage()","71bf35b6":"minMinutesPeriods()","71bf439e":"CANVAS_WIDTH()","71bf5a95":"setENS(address)","71bfa03f":"getRedemptionBlockNumber()","71bfabca":"resultOf(uint256)","71bfd48b":"content(string,uint256,string,string,uint256)","71c02b7b":"BSAFE()","71c03d76":"get_rest(uint256)","71c10778":"weiToPresalersFromICO()","71c147fb":"addAccount(string,uint256,string,string,uint256)","71c157d1":"addInsuranceProduct(uint256,string)","71c1d196":"numContributors(uint256)","71c1dde5":"get_presale_arbits_per_ether()","71c2835e":"operater()","71c396cc":"migrationAddress()","71c4275a":"setWeight(bytes32,uint256)","71c4980b":"getBlanace()","71c57772":"eucDist2D(uint256,uint256,uint256,uint256)","71c58b25":"internalTransfer(uint256,uint256,uint256)","71c59097":"MainnetSurvey(uint256,string,bytes32[])","71c66459":"LogPaymentReceived(address,uint256)","71c6d4dc":"pearlContract()","71c6dc50":"ProofOfCraigGrant()","71c6e049":"addUsers(address,uint256)","71c78ce7":"totalAirDropped()","71c79588":"releaseName(bytes32)","71c7e923":"dDisableErc20OwnerClaim(bytes32)","71c80c67":"COOPET(uint256,string,uint8,string)","71c82c14":"setOraclizeGasPrice(uint256)","71c847b2":"detailsOfEdition(uint256)","71c85da2":"LogN(address,bytes32,uint256,string,bytes,uint256,bytes1,uint256,uint256)","71c8e333":"getSundownGraceTargetBlock()","71c93fc7":"processDiceRoll(address,uint8)","71c95040":"EFF(address)","71c9572b":"maxBidInCentsPerAddress()","71c9a754":"topiToken()","71c9e177":"SpudToDivs(uint256)","71ca2117":"isAuditorRegistered(address)","71ca337d":"ratio()","71cabfb8":"getYumerium(uint256,address)","71cacc9e":"addLotteryPrize(uint256,string,uint256,uint256)","71cb9769":"addIdentity(bytes32,bytes32)","71cbb22a":"fixed_value()","71cbef8a":"sendTokensAfterCrowdsale(uint256,uint256)","71cc4f35":"Alecrypto()","71cc805a":"refund(string,address)","71cce314":"Kolak()","71ce52ed":"senderIsAdvocate(address,address)","71ce9a4a":"forwardCallGas()","71ced69d":"mintNewDNC(address,uint256)","71cf586f":"CanISuscribeTrial(uint256)","71cf5979":"market_AcceptBid(uint256,uint256)","71cf866e":"_redeemIsAllowed(uint256)","71d06675":"getInteres(address)","71d0cf01":"setCustomerSignature(address,uint256,bytes)","71d0ed05":"betsKeys(uint256)","71d141f9":"doOraclize(bool)","71d1995e":"changeEmployee1(address)","71d30a17":"Match(address,address,bytes32,bytes32,uint256,uint256)","71d31a13":"withdrawTokens5(uint256)","71d3de1b":"setStates(uint256,uint256,uint256,uint256)","71d3de2b":"JincorToken()","71d49910":"_emitAreaSet(uint256,bytes32)","71d4aa3a":"fomo3D4eva()","71d4edaf":"setSaleLot4StartTime(uint256)","71d50cc8":"payBets(bytes32)","71d5af66":"Upfinex()","71d5afb5":"extendCrowdsale(uint256)","71d5b5dd":"getBonusPoolTotal()","71d5d1c2":"updatePrincipal(uint256,uint256,bool)","71d5ffbe":"totalETHWagered()","71d6dbe1":"isClaimSegmentVerified(uint256,uint256,uint256)","71d6e229":"queryRole()","71d76096":"ICOcollected()","71d7c621":"createDownRequest(address,uint256)","71d7e4a9":"transferTokens(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","71d87948":"FixedSupplyToken(string,string,uint256,uint8)","71d8d421":"_isValidLicense(uint256)","71d8d7af":"setMaxRate(uint256,uint256)","71d93cb0":"interuser(address)","71d9ffce":"priceChange()","71da0e63":"_getValidRandomGenes()","71daca00":"grantBackerToken()","71dc761e":"enableERC721()","71dd46a9":"left19(uint256)","71dd8862":"IndexOf()","71dd99fe":"BigRisk()","71ddd3ad":"multifunctioncoin()","71de2ffc":"claimRefund(bytes32)","71de6362":"certificateSigners(address)","71df8d09":"bigInt(uint256)","71dfc116":"Cryptolotto10Minutes(address,address,address,address)","71e030d3":"TokensTransferedToHold(address,uint256)","71e07813":"issueDevsTokens()","71e11354":"updateRegistration(string,string)","71e12726":"getBlockStats()","71e1fa95":"getHtlcTimeoutBlock(bytes32,bytes32)","71e28126":"canFinalize()","71e2a657":"addMinters(address[])","71e2d919":"lol()","71e30719":"ZEC()","71e365a0":"AICQ()","71e3c76e":"claimGrant(bytes32)","71e3c819":"DSToken(string)","71e3fdc4":"moveMintTokens(address,address,uint256)","71e4cfd7":"ROF()","71e5b9ec":"scanAddresses(address)","71e5ee5f":"arr(uint256)","71e60fe6":"testFailTransferEnableNotTransferable()","71e68cad":"claimUsername(bytes32)","71e70133":"TotalTokens()","71e777ae":"getMemBestInvestor()","71e928af":"issue(address)","71e9f016":"CompetitionChainContract(uint256,string,string)","71ea29df":"blockedContract()","71ea3aad":"CollectERC20(address,uint256)","71ea6c73":"VIBEXToken()","71ea87ee":"getPeriodRange(uint256)","71ea980c":"rewardPoolWallet()","71eb9710":"getDebitDigest(bytes32,uint256,uint64)","71ec4cc1":"depositPayout(uint256,uint256)","71ec98dd":"issueTokensFromOtherCurrency(address,uint256)","71ed4664":"refundTo(address)","71edfe35":"hashOfTheDocument()","71ee2ce1":"getResponses(uint256)","71ee329f":"useCaptainAbility(uint256)","71ee872f":"TransactionSettledByMediator(uint256,uint256,uint256,uint256,uint256)","71eee1f4":"IssueStateLoaded(bytes32,string)","71ef0d0f":"phxCoin()","71ef7862":"seventhTime()","71efb7f7":"SimpleSafeToken(uint256,uint8,string,string)","71efdc21":"usedTickets(uint256)","71efeff1":"transferCommunityBank(uint256,address)","71f027fa":"updateOwnerOfWeapon(uint256,address)","71f098c8":"LecBatchTransfer()","71f0ad64":"TestCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","71f11552":"changeDNNHoldingMultisig(address)","71f124c5":"getDropsOf(address)","71f16739":"_createContract(address,uint64)","71f297cc":"XaurumToken(address)","71f4c9ae":"GameClosed(uint256)","71f4f65e":"yearlyOwnerTokenWithdrawal()","71f52bf3":"connectorTokenCount()","71f5584f":"sponsoredLeaderboardDataContract()","71f64a68":"executeTopic()","71f6fb88":"transferWithReservingNet(address,uint256)","71f7aaca":"dragonIndexToApproved(uint256)","71f7ebf4":"_doTrade(address,address,uint256,uint256)","71f805bf":"numFpBits()","71f84164":"_sendTo(address,uint256)","71f8746f":"registerBuy()","71f90109":"hideDonations(address)","71f90fe6":"initializeABIHashForMod(uint256,bytes)","71f96211":"assetOf(address)","71f9b7f3":"addMultipleAddressesToPublicBuyerList(address[])","71f9ff89":"preICOcap()","71fa632f":"newVoterAllocation()","71fa7f37":"createNewProject(uint256,uint256,address)","71fcc672":"setCryptaurRewards(address)","71fdd6d3":"_canBreedWithViaAuction(uint256,uint256)","71feaac5":"greatgreatcoinERC20Token()","71ff01b0":"maxSupplyReached()","71ffcb16":"changeFeeAccount(address)","72004a65":"getPremiumStatus(bytes32)","72012ef6":"test_oneInvalidEqString2()","72016f75":"getNodeLength()","7202997e":"LogAccepted(uint256)","72030d03":"addresses2(uint256)","72052773":"deleteChallenge(bytes32)","72054df4":"compatible223ex()","72067d49":"getBountyBalance()","72076c57":"ColorBayToken()","72078e3b":"CORNERSTONEAMOUNT()","7207c19f":"MyToken(uint256)","7207d711":"RewardHalved()","7207f9ce":"transactionFeeMax()","7209036a":"fundReservCompany()","720b43e8":"intercrypto_cancelConversion(uint256)","720b7ee4":"getCardId(string)","720be6c7":"CrapToken1A()","720c142d":"setRNGCallbackGasPrice(uint256)","720c4798":"workshop()","720c5732":"TextMessage()","720de551":"deleteVoterForCandidate(uint256)","720e2a06":"GadielToken()","720ed642":"getModuleById(uint256)","720edd13":"theanswer()","720ee37c":"decrementBalance(address,uint256)","72104205":"rewardMint(address,uint256)","72108714":"updateHash(bytes32,bytes32,uint256)","72112ebc":"set_Total(uint256)","72117821":"GetTokenAddress(address)","72121dac":"FooToken()","7212b67e":"add_potion(uint16)","7212eadd":"trigger_game_end(uint256)","7213cff1":"hasLockedUp(address)","7213e335":"guthabenAnzeigen(address)","72142c67":"MSECStandardToken(uint256,string,uint8,string)","7214d6c3":"isUIntPublic()","721547eb":"maintainExternalContractTokenBalance(address,uint256)","7215513f":"addTokenClaim(uint256,uint256,uint256)","72159335":"voteInitiate(uint256,uint256,uint256,uint256,uint256,uint256)","7215b96d":"CheckAllowance(address)","7216ab38":"getByteFromBytes14(bytes14,uint256,bytes1)","7216b95c":"checkLicense(bytes32,uint8,bytes32,bytes32)","7216e02d":"getOracleByName(string)","7216ee00":"totalTrainer()","7217523c":"addDays(uint256,uint256)","721868f8":"queryTinyOracle(bytes)","72198ead":"setDSTMultiSig(address)","7219d7f7":"OrigamiTokenPurchase(address,uint256,uint256,uint256,uint256)","7219dd7f":"allocateTokenETHConvert(address,uint256)","7219fa11":"EIP20(uint256,string,string)","721a1f57":"endorseCredit(address,uint256,uint256)","721a37d2":"revokeTokens(address,uint256)","721b67ab":"CNYTokenPlus()","721bba59":"getTokenBasicData(address)","721c555e":"queryEscrow(address,address)","721d7d8e":"currentContract()","721dd850":"getOwnedAvatars()","721e117b":"getPurchaseRequirements(uint8)","721e9969":"getPressCount()","721ed9ec":"tokensICO()","721fa630":"pubs(uint256)","721fefac":"startNewDraw(uint256)","721ff138":"tokenMintCap()","7220426f":"verifyTokens(uint64,uint64)","7221a26a":"storeValue(uint256)","7221c3c0":"withdrawJackpotBalance(uint256)","72229abf":"setBetFee(uint256)","7222fe1e":"MNY()","72237d97":"setTargetDiscountValue10(uint256)","72239313":"addAccountMinter(address)","7223cd19":"set(address,int256,uint256)","7224267c":"addDeposit(address,uint256,uint256,uint256)","72258f96":"allergy(string)","72259875":"addCourse(string,uint256,uint256,uint256,string,string)","72262699":"forwardOnBehalf(address,uint256,bytes,uint256,uint8,bytes32,bytes32)","7226d055":"create(address,address,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","722713f7":"balanceOf()","7227bff2":"setTransferOwnership(address,address)","7227c5dd":"fundMark(uint256)","7227c7ce":"hashNext()","7228057f":"ibcFunded()","7228b9db":"etherCap()","7228becb":"crowdsaleDuration()","72298b82":"setEndTime(uint32)","722bb4a8":"getSuperManagerContractAddress()","722bd85a":"bonusForDate(uint256)","722c885a":"endSeedStage()","722d1267":"forceWithdrawTokensToAnAddress(address)","722d1d13":"setProductCompletionDate()","722ded24":"exeSequence(uint256,uint256[])","722e1677":"getTotalPublicKeysCount(address)","722e9c6d":"Luck()","722f0835":"startPrivatePreICO()","722fe823":"getActionHistoryItem(uint256)","72309714":"setPresellOpen(bool)","7230bce8":"add(uint256,string)","7230eb42":"AllocatedCrowdsaleMixin(address)","7230ef7f":"totalGen0()","72317e7b":"totalWeiRaisedDuringICO1()","7231af39":"getTotalGamesStarted()","72325c5b":"initSiriusFund()","72337396":"unholdFunds()","7233d860":"BitcoinRich()","7234ba0c":"MIN_CROWDSALE_TIME()","7235c8dd":"PeerReview(address,bytes)","7235d2b1":"maintenanceMode(bool)","7236f851":"exchangeByAdmin(uint256,address)","72378554":"sendToken(uint256,address)","7237e031":"tokenToEthTransferInput(uint256,uint256,uint256,address)","72388610":"paybackAll()","72388f7c":"mintSpecificCards(address,uint8,uint256[])","7238ccdb":"getLockInfo(address)","72397287":"createOfAthleteCard(string,string)","723b2b58":"getMemberListCount()","723c308f":"ahs()","723c37f7":"TokensTransferrable()","723e357a":"pushRound(uint256,uint256,uint256,uint256,bool)","723e435f":"setTokenRateInGwei(uint256)","723eb2cc":"hurmint(address,uint256)","723f291d":"cancelOpenBids(bytes32)","723fdfe5":"PaoTestToken()","724020be":"GSCT()","72405ab0":"approve(uint256,string)","7240976c":"trades(address,address)","7240eccf":"approveLess(address,uint256)","7240f67b":"countActiveType(uint256)","72411849":"ChangeTankSellMaster(address)","724121ae":"contentExists(uint256)","72413a3b":"VOLUME_BONUS()","72414501":"SMILO_FOUNDERS_AMOUNT()","7241450c":"deliver(address,uint256,string)","7241eb8c":"_bpto(uint256,uint256,uint256,uint256,address)","72422024":"lockMoneyOnCompoundCreation(address,uint256)","72432965":"AdvisorsAddress()","7243cfbb":"releasableAmount(address,address)","72440c31":"finalizeEndTime()","72453422":"directSellSupply()","7245f6e7":"stageEnd(uint256)","72460869":"test_threeFalseAssert()","72468368":"setBlockTargetDelay(uint256)","724693ce":"TokenSale(uint256,uint256,address,uint256)","7246de3d":"sanityCheck()","72470a14":"ShopManager(address)","7247390b":"vote_beneficiary(string)","72479140":"CreateTicket(address,uint8,uint8,uint8)","7247959a":"referral(address)","7247a50d":"virtualInvest(address,uint256)","7247aafd":"Callous()","72490c69":"GREENECO()","7249733c":"businessPercentage()","7249fbb6":"refund(bytes32)","724a6246":"claimSeasonPrize(address,int8)","724a8487":"getTargetBlocks()","724ae9d0":"getMinInvestment()","724bc3de":"getAirdropAmount(address)","724bdbaf":"externalTxs(uint8,bytes32)","724c8393":"changeCrown(address)","724dbf36":"isNewBattle(string)","724df10a":"alreadyWithdrawn()","724edf00":"startTokenDistribution()","724fcd4c":"buyAndSetDivPercentage(address,uint8,string)","7250dc36":"getMemberName(uint256,address)","7250e224":"addDistributor(address)","72511fb4":"EventAddressChange(address,address,uint256)","72519531":"BagholderAddr()","7252518c":"setLockend2(uint256)","7252bbf2":"ethBalanceOf(address)","725326dc":"setAllowedForTransfer(address,address)","7254895a":"readCards()","7254e1ba":"afterGeneratorHook()","72558b73":"destroyValue(address,uint256)","7255d729":"createGame()","7255f7ad":"getLastImageId()","72561235":"getCreditbitAddress()","72565e3f":"offChainMint(address,uint256)","7257dac1":"removeSomeUETsFrom(address,uint256)","7258b901":"masterCut()","72593831":"withdrow(address)","72593b4c":"ordersCanMatch_(address[14],uint256[18],uint8[8],bytes,bytes,bytes,bytes,bytes,bytes)","7259ac60":"Rethen()","7259bce3":"preSaleTokenPrice()","725a731d":"setPendingKNCRateRange(uint256,uint256)","725a7eea":"MEGA_HERO_MULTIPLIER()","725ad47f":"TransferERCXTokenInitiationEvent(uint256,address,string,address,address,uint256)","725c8bdd":"LMITOKEN()","725cedd3":"calculateReward()","725d8524":"getOption(bool,address,uint128,uint128,address,uint64)","725da7b4":"withdrawMicroDivs()","725e70a3":"getnumDeposits()","72601e77":"setOracleFee(uint256,uint256)","72601faa":"ROUND_DATA_COUNT()","726199b5":"notarizeHash(uint256,string,string,string,bytes32)","7261e469":"burn(address,uint128)","7261ffad":"spendGameLockedToken(address,uint256)","7262561c":"unsubscribe(address)","7262eb66":"PRE_ICO_POOL()","726300c7":"releaseEscrow(uint256,uint256)","72630a6d":"UpdateIndividualContributorCap(address,uint256)","7264727d":"STCToken()","7265d040":"startAtBlock()","72664744":"setDelegadoDeDistritoVerify(bytes32,uint256)","726678e7":"level2Bonus(uint256)","7266f4a4":"X3()","72670119":"payBonus1Address(address)","72675562":"extraTokensWallet()","7267a25b":"mainSaleMinimumWei()","7267f24a":"lrcReceived()","726802a4":"addAddressToAccount(address,bytes,bytes,bytes32)","7268475b":"ITSMToken()","7269a327":"isNonFungibleBaseType(uint256)","7269daa5":"requestChangeStaker(address)","726a3ad1":"removeReservedTokens(address)","726a431a":"TARGET_USER()","726ab4ef":"getParentHash(bytes)","726aeb20":"costToCreateGame()","726b23bf":"changeMinNac(uint256)","726b5bad":"endAirdrop()","726bd6bf":"oraclizePrice()","726c12c8":"FileDataInt()","726c6382":"Error()","726d0a28":"getRequest(address,uint256)","726d50ee":"totalCampaignsBy(address)","726d82a0":"SEN()","726df9cc":"grantService(address,address)","726ea051":"calculateCoinBuySimple(uint256)","726ee493":"withdrawStakeTokens(uint256)","726ef3da":"getCurrentWinnerMoveCount()","726f63f6":"setTokenOffering(address,uint256)","727089f1":"extractAllowanceLength()","72712bb8":"trophyAddress()","72729ff2":"amountRaisedInWei()","7272ad49":"decreaseApproval(address,uint256,bytes)","7274f35b":"getCoinIndex(bytes32,address)","72750dc1":"PANICPERIOD()","7275c8cb":"getRecord(bytes32,string)","72761e96":"execute_transfer(uint256,uint256)","727648a3":"submitWork(address,address,uint256,string)","7276509c":"purchaseBuilding()","72771d40":"sendList(address)","7277236b":"icoInvestment(address,uint256)","7278d080":"BTCEarth()","7278d623":"CurrentEntityState()","727a00a5":"LetsFunds()","727a666a":"totalLevelValue()","727a899a":"setHashes(uint8,string,string,string,string)","727b1cd6":"next_draw(bytes32,uint256,uint256,uint256,uint256,uint256)","727b4094":"transferStep()","727b4276":"setBitGuildToken(address)","727c2ff0":"purchaseWithGze(uint256)","727cdf87":"setCut(uint256)","727d508a":"isOpenForPublic()","727da487":"TTGOracle()","727e2422":"StudioToken()","727f0067":"nextHash()","727fc9fc":"SCAM()","72801b53":"isInTimeRange(uint256,uint256)","728064cd":"GetTotal()","7280850e":"getHandRank(uint32)","7281854d":"GetCategoryValue(uint8)","7282c5b1":"WithdrawFeeBalance(uint256,address,uint256)","72840e32":"rentPeriod()","72841e0c":"isMaxCapReached()","728435a0":"ReverseProposed(string,address)","7284e416":"description()","72850e7a":"priceNeedsUpdate()","728516c2":"getProjectedPayout(bool,uint256,uint256)","72852fe5":"attackTile(address,uint16,uint256,bool)","72855080":"demurringFeeDenum()","72879610":"sencHardCap()","728880c2":"payOutVoterByAddress(address)","7288b0a9":"numberOfPingsAttempted()","7288b50c":"engraveNamespace(string,string,bytes32)","72892f4f":"newPlay(uint256,uint256,address,uint256,uint256,uint256,uint256,uint256)","7289f28e":"setLastRound(uint256)","7289f9aa":"setDiscountedInvestor(address,bool)","728a6755":"buyBookLotto()","728addbc":"token_balanceOf(address)","728af7ec":"getInterest(uint256,uint256)","728b763c":"extendTde(uint256)","728cbc44":"userHeldTill(address)","728cd741":"SnapshotAndDistributePot()","728cf508":"bookingMetadataForKey()","728d0e2b":"accrueDividendandCoupons(uint256,uint256)","728d3dd2":"newRaceDistCon(address)","728d5e94":"baseTokensPerEther()","728de91c":"preSale(address,address,uint256)","728ec9f1":"YourCustomToken()","728f31e7":"setTransferEnablingDate(uint256)","728f3a21":"isApprovedWallet(address)","72909e28":"calculateIdeaSell(uint256)","7290c21d":"auctionCancelled(uint256,address)","7290f691":"horseShoePr(uint256)","72910be0":"setTitle(string)","7291acdf":"SaleWindowUpdated(uint256,uint256)","72923378":"RockPaperScissors(address,address,uint256)","72927b1e":"deleteEntryByName(bytes32)","72929b56":"getKudosPerProject(address)","7294789b":"getWhaleCard()","7296359a":"fog()","729680c3":"epsAddress()","7296dae6":"jsonCat(string,string,address)","7297be7f":"changeFixedCommissionFee(uint256)","72987457":"blocktrade()","7298b261":"_calcEditorKey(bytes)","7299054c":"random(uint256,uint256,uint256)","72998d8e":"LotteryGameLogic(address,address)","72998ee1":"addPreSalePurchaseTokens(address,uint256)","729ad39e":"airdrop(address[])","729aeea6":"isSetupRunning()","729b3881":"setNewRound(uint256)","729c04fd":"_yearTwoClaimed()","729cc83e":"getPlayerKeyCount()","729e3ef8":"YOPT(uint256,string,uint8,string)","729e6f2b":"getGameChance()","729ee75b":"updateUSDXGE(uint256)","729ef530":"additionalBonus()","729f0e8e":"cmct()","729f2439":"addK(uint256)","72a02f1d":"finalizeInit()","72a06b4d":"returnInt8(int8)","72a0c16e":"tulipToApproved(uint256)","72a1a8ae":"CanSignIn()","72a1b73f":"createSale(uint256,uint256,uint256,uint256,address)","72a1e258":"updateUser(address,string,uint256,uint256,uint256)","72a20c78":"powers()","72a22014":"firstAuctionsHighestBid()","72a22d51":"unlockValueOf(address)","72a2d90c":"quickWithdraw()","72a4a02f":"runPreMint()","72a4d94b":"release(bool)","72a503be":"transfer(address,address[],uint256[])","72a52851":"checkProof(bytes32[],bytes32,bytes32)","72a56d2c":"ICO_RATE1()","72a66507":"_isNewUser()","72a6a480":"_validRating(uint8)","72a7019c":"saleHardCapEther()","72a74d5b":"confirmOffer(uint256)","72a7655e":"timestampMint()","72a7b8ba":"multiDecreaseApproval(address[],uint256[])","72a7c229":"right41(uint256)","72a7d8c9":"lengthEqual(bytes32[],uint256,string)","72a7ff87":"isKYCRequiredToSendTokens()","72a85604":"min_amount()","72a86693":"ambassadorsNumber()","72a88673":"nthRoot(int256,int8)","72a984b2":"blockMinedAt()","72a9e232":"reserveFunds()","72aa18d7":"WALLET_ECOSYSTEM()","72aa343a":"removeProof(address,bytes32)","72aa9349":"maxTickets(uint256)","72aab7d7":"setGPSEndTime(uint16,uint8,uint8,uint8,uint8,uint8)","72abee88":"PreIco(uint256,uint256,address,uint256)","72acad56":"check_reward()","72ad21c7":"protection(uint32)","72ad3c9f":"OTCChain()","72ad5bbe":"_isErcToNativeBridge(address)","72adc407":"getGuardianVend(uint256)","72adcadd":"TOTAL_CONTRIBUTOR_COUNT()","72ae74dd":"getCoinRemains()","72ae9e54":"blocksCoordinates(uint256,uint256)","72af7b43":"SkyeCryptoPrivate(uint256,string,string)","72af805e":"sendPreIcoTokens(address,uint256)","72b0d90c":"withdrawTo(address)","72b28d27":"getNext(address,uint256,uint256,uint256)","72b2ee75":"investorsNum()","72b30d39":"setLLV_edit_30(string)","72b38ab9":"refundUser(address)","72b3936d":"EWBToken()","72b3f570":"endBuy()","72b44b2c":"getSaleReturn(address,uint256)","72b4e98f":"Aecium()","72b4f111":"COOPToken()","72b50845":"eliminateSDCC(address,address,uint256)","72b556c7":"emissionReleaseTime()","72b59c68":"createNote(uint16,bytes2,bytes12,bytes)","72b5e050":"LOCKED_ALLOCATION_PPM()","72b60682":"lockEndDate()","72b614af":"itemsPerPage()","72b7094a":"tokensPerEthPresale()","72b75585":"getOriginalClient()","72b7f893":"metaIncreaseApproval(address,uint256,bytes,uint256,uint256)","72b81b1c":"resolveLotteryByHand(uint32,uint32)","72b8a5cf":"bonusPersent()","72b8de14":"isChallengePeriodOver()","72b902a7":"setvolumebounus(uint256,uint256,uint256)","72b91e61":"seen(address)","72ba8259":"testMinting()","72baa12e":"withdrawQR(address)","72baa779":"setItoEndTime(uint256)","72bc56fe":"IsMultiFreeze(address,address[],bool)","72bc8fc6":"ether2tokens(uint256)","72bc8ff2":"isOMITokenLockContract()","72bc9240":"etherPerSale()","72be346c":"ZTR_ETH_initial_price()","72becdee":"_generic(bytes,address)","72bedcee":"operationState()","72bf079e":"adjustPrice(uint256)","72bff5ad":"freezeMintingFor(uint256)","72c03508":"contributorClaim()","72c0e7a4":"setThreshold(bytes32,uint256,uint256,address)","72c1591c":"testFail_basic_sanity()","72c174db":"mintTokensForAdvisors()","72c1df4c":"transferDirectorB(address)","72c27b62":"setFeeBps(uint256)","72c3015c":"mint(int256,address,string)","72c4639e":"SummRew()","72c4ae6b":"walletForCommunity()","72c537e6":"FirstCryptoBank(uint256,string,string)","72c5c349":"NinjaCore()","72c5cb63":"getAmountTransferred()","72c60b1d":"tokenAddressToAssetData(address)","72c691b2":"setWarTokenAddr(address)","72c70758":"setBountyFundWallet(address,address,uint256)","72c7c85a":"minority()","72c7e48d":"addAddressesToWhitelist(address[],string)","72c87075":"testBlockHeaderFetch()","72c91cdd":"maxTokenForPreSale()","72c9a5e3":"approveFST(address,uint256)","72c9e9e0":"placeBid(uint64)","72ca7fce":"TrueVeganCoin()","72cb8a89":"TokenWithdraw(address,uint256,address)","72cc1f5a":"knightAddress()","72ccd03a":"delWord(string)","72cd5576":"getImpactLinked(string)","72cd700b":"totalSupplyExpansionTokens()","72cd7b89":"foundationTarget()","72cde347":"setMiniPoolEdit_5(string)","72cee8ea":"getReferralProfit(address,address)","72cef34b":"getRevisionIpfsHash(bytes32,uint256)","72cf3b40":"recharge(bytes32,uint256,address)","72cfea69":"presaleClosingTime()","72d00e9f":"activeContracts(uint256)","72d0774a":"presaleFinishTime()","72d0979a":"AddBonusToListFromArray(bytes32[],uint256[],uint256[])","72d16358":"Oratium()","72d209f5":"processRequest(bytes32[],bytes5,address)","72d29f64":"setValidatorName(address,string)","72d2f8b8":"createHodler(address,bytes16,uint64)","72d32586":"STOREDIG()","72d32968":"withdrawBonus(uint256)","72d376b6":"proofTokensAllocated()","72d3880e":"mainICO()","72d39ee4":"Credo(address,address,uint256,uint256)","72d475db":"getTotalHeartsByDappId(uint256)","72d4b93c":"VitManToken()","72d5637f":"AxieCore()","72d5fe21":"changeProposer(address)","72d744e0":"feeFromTotalCost(uint256,uint256)","72d8c1c7":"ForestCoin()","72d8e442":"hasBeenRevealed(address,uint256)","72d9733e":"add_AUTO_MANU()","72d99675":"getCollectible(uint256)","72d9b86f":"unpauseCrowdsale()","72d9f13d":"setMaxEarningsClaimsRounds(uint256)","72dad9f9":"SuperCoinViewToken()","72db2339":"ERC677Transfer(address,address,uint256,bytes)","72dd236a":"setTokenOffering()","72dd529b":"totalsupply()","72dd52e3":"coinContract()","72dee32b":"getEndGameStatus()","72df02a7":"setMintThresholds(uint256,uint256,uint256)","72dff527":"drawTertiaryBWinners(uint256)","72e05569":"_sendRefund()","72e09d48":"mokenId(string)","72e0e984":"prime(uint256)","72e18c12":"placeSellOrder(uint256,uint256,uint256,uint256)","72e208eb":"targetAddr()","72e2cac8":"BONUS_WINDOW_4_END_TIME()","72e2f8f5":"checkFreeze(address)","72e38003":"treefs()","72e3c5c2":"toggleEmployeeSuspension(address,uint32)","72e3f040":"richestRoundId()","72e4030d":"_freezeTransfer(address,uint256)","72e496f3":"setRestrictedState(bool)","72e4f262":"annotationLength()","72e4f5cc":"CreateOffer_internal(uint8,bool)","72e5186c":"depositTo(uint256,address,uint256)","72e5c84f":"_getTokenBonus(uint256)","72e67d06":"setPendingManager(address)","72e6aca3":"isWithinICOTimeLimit()","72e6e21a":"exchangeableTokens()","72e861ee":"private_setRandomAPIKey(string)","72e87c35":"giveProduce(uint256,string)","72e8e6a4":"PublicMined(address,uint256)","72e91fee":"initialPartnerAccount(uint8)","72e98a79":"transferBZxOwnership(address)","72ea1eb0":"addressBytesFrom(address,uint256)","72ea2e6d":"finishInitialExchangingPeriod(uint256)","72ea4b3d":"TestToken(uint256,string,uint8,string)","72ea4b8c":"getNumInvestors()","72ea61e8":"dist_developer(address,uint256)","72ea7243":"generateLand()","72ea8bfe":"executeBet(address,address,bool,uint256)","72eab193":"COMPLIANCE()","72ead941":"getDelegate(address,uint8)","72eae629":"multiMintBounty(address[],uint256[])","72ebe2aa":"verifyYourBalance(address)","72ec1993":"enablerefund(address,address)","72ece81c":"_create_island(bytes32,address,uint256,uint256,uint256,uint256)","72ed2c7f":"setQualifiedInvestor(address,bool)","72eda05f":"tokensAllocatedToCrowdFund()","72ee91c2":"configSignOrganizers()","72eec3a7":"refundToken(bytes32,string,address,address)","72eefb8a":"getRareItemsOwner(uint256)","72ef149e":"whiteListRegistrationEndTime()","72ef5458":"transferTokenOPSPlatformTokens()","72ef6a08":"rgbLimit(uint256)","72ef90e4":"Shop(address,string,string,uint256,uint32)","72efa4ef":"Showcoin()","72f0424f":"getPriceToken()","72f12814":"_setIDLE(uint256)","72f1301a":"USCCToken()","72f159b7":"migratePlayerData2(uint256,address,uint256,uint256,uint256,uint256)","72f3b3c4":"ownerAbandonOverride(uint256)","72f41f11":"approvedRatio(uint256)","72f443be":"ChangeLicense(address,bool)","72f4ecab":"Balances()","72f4f5f9":"TOKEN_REFERRAL()","72f52a3e":"getAttoTokensAmountPerWeiInternal(uint256)","72f57f1f":"withdrawUnsoldTokens(address)","72f5ae5f":"setCertificationManager()","72f5bb30":"UKToken()","72f5fccd":"releaseToMgmtTeam(address,uint256)","72f65dea":"BitstartiToken(uint256,string,string)","72f69a72":"getBurnRequestsLength()","72f6c3b5":"coinPercentage()","72f702f3":"stakingToken()","72f71894":"backTTCOwner()","72f74af8":"crowdfundAddress()","72f79b56":"btcEthRate()","72f83d3a":"poolSub(uint256)","72faebdb":"addCustomerFromACC(address)","72faf84a":"tokenSTCDRforBurnInControlWallett()","72fb54e5":"PHASE_2_PRICE()","72fb6f75":"MIN_INVEST_SUPPORT()","72fb9703":"challenge(address)","72fc493d":"decFeeDeposit(uint256)","72fc75d7":"_changeTrancheIfNeeded()","72fd1a7c":"changeRateSale(uint256)","72fd8772":"toekensForOthers()","72fdbf25":"increaseDividendPayments(address,uint256)","72fecf84":"upgradeUnitId(uint256)","72ff1773":"bonus_percentage()","72ff285e":"_calculatePayout(bytes32,uint256)","72ff3d87":"signedBySystem(bytes32,bytes)","73032446":"censorAndCover(address,uint256,string)","730369a7":"tokensBounty()","7303a559":"getCreatorMetadata(string)","7303ed18":"trustedUniverseBuy(address,uint256)","73047e93":"timeslucky()","73053410":"newVersion(uint16[3],address,bytes)","73053f70":"tokenDeposit(address)","7305c695":"_orderTokens(address,uint256,uint256,address)","7305dce1":"createPromoCollectiblesWithMining(uint256[],address[],uint256[],uint256[],uint256[],uint256[])","73069f94":"_claimTokens(address)","730720b8":"testControllerValidTransfers()","730736c9":"DelSocialAccount(bytes32,bytes32,bytes32)","730740f8":"_resumeWork(uint256)","7307b805":"dismissTokenOperator(address)","73086e58":"isFreezeTimeout()","730a04fd":"ArnoldCoin()","730a0d80":"unhold(address)","730a1a16":"_medalUnFreeze(uint256)","730a3127":"RECORDICO(address,address,uint256,uint256,uint256,uint256)","730a9f1c":"UncleToken()","730ad454":"vote(bytes32,address,bool)","730b1952":"test_insert_updateHead()","730bdc96":"getHeroDetails(uint256)","730c1faa":"LogUnpause()","730c635a":"_checkToiletFlush(bool,uint256)","730d2221":"CWS(uint256,string,string)","730db1f8":"setNum(uint256,int256)","730e90b7":"addTipBalance(uint256,address,uint256)","730ef269":"getNumberOfItems()","730f2a96":"_transfer(address,address)","73107c99":"ICDStartTime()","7310c2e0":"Daisee()","73124ced":"transferLock()","73124ee9":"ContractDetector()","7312aaae":"singleWithdrawMax()","7312c065":"Receiver()","73137bd0":"buildInternalSalt(uint128,address,address,uint256,uint64)","73138e4f":"PRESALE_SUPPLY()","73139c0d":"getTokensForStage(uint256,uint256)","7313b3b1":"Drawing()","7313ee5a":"vestingPeriod()","7314221e":"_createDeveloper(string,uint256,uint256)","7315acc8":"getAllShareholdersOfArtwork(uint256)","7315af6f":"LandmarkCoin()","7315f446":"votedKickoff()","7316453e":"setPrice1(uint256)","7317a88d":"transferSingle(address,address,uint256)","7317c4f3":"replaceAnimal(uint8,uint16,bool)","731859bc":"batchLockArray(address[],uint256[])","7318b453":"setVotetUntil(uint8)","7319b43e":"playersList(uint256)","7319e5aa":"calculateBonus(address)","731a00f5":"calculateVestedTokens(uint256)","731a3b06":"unstakeFrom(address,uint256)","731ac7ed":"choosePerk(uint8)","731b185e":"LogSetPreICO(address,string)","731b3284":"Lockable()","731bed8b":"WithdrawalStarted(address,uint256)","731c2f81":"feeRebate()","731c7c62":"setServiceRegistryEntry(uint256,address)","731e1c94":"setLastPrice(uint256,uint256)","731e1ecd":"preMarketingSharesDistributed()","731f03fc":"setMinimumBuy(uint256)","731f49b7":"lastIdGen0()","731f93c5":"updateCertification(uint256,string,string,string,uint16)","731fb32e":"PRE_SALE_GMR_TOKEN_CAP()","73201667":"tokenUnlock(address,uint256,address,uint256)","73206348":"raiseDollarsWithdrew(address,uint160,int160)","7320753b":"approveConnection(address,address,uint256)","7321a17b":"getTotalBonusTokensByAddress(address)","7321ffa6":"distributeFunds(address,uint256,address,address,address)","73221a55":"unblock(address,bytes32)","732264b4":"getCommitmentsOf(address)","73228786":"setTokenAddresses(address[6])","7322dccd":"lastBlock_a16()","7323febe":"aa(uint256)","73251628":"doAirdrop(address)","732519d5":"getSellable(uint32)","73252322":"RandomProofFailed(bytes32,uint256,uint256)","73256a8d":"SharesChainTokenCrowdFunding(address,address,uint256,address,address,address)","7325b084":"GdprCash()","732606fc":"getCooldownIndexCount()","732617bb":"switchAdmin(address)","7326b901":"getPropertyCount()","7326cac8":"ethIn_()","732726d1":"increaseLockedAmount(address,uint256)","732783ac":"tokensBought()","7328c6ec":"submitNewContract(string,address[],string,bytes32)","7328f531":"evaluateSkill(address,uint8,uint256,uint256,uint256)","7329036a":"getBlocksLeftInCurrentKick()","732a37c9":"SnowdenAffact()","732b6963":"emitEnd()","732bdbbf":"clearApprovalAndTransfer(address[16],address,address,uint256)","732c227f":"contributionCaps(uint256)","732d2da4":"testHasCinderToken()","732d565b":"ONE_YEAR_KEEPING()","732e632e":"assemblyTest()","732e77d0":"EGGS_TO_HATCH_1SHRIMP()","732ef12c":"fee_registration()","732f5d0c":"AdvancePayplus()","732fe2ff":"buyerCapLowEther()","73305f14":"Quicketh()","7330aba2":"getOracleAddresses()","7330aca4":"_isTransferAllowed(address,address)","7330daac":"isOnList(address)","73311631":"addBrand(address,string)","733122aa":"fromMemory(uint8[])","73321f03":"GateToken()","733261bf":"bountyAdress()","7332b520":"getRewardsCount(uint256)","73333128":"out3Done()","73335b46":"GlobfoneToken()","73339a13":"setNetworkState(uint256)","7333fd00":"lock4Dividend(uint256)","73342168":"BFToken(string,string,uint8,uint256)","733452bc":"Descript()","733480b7":"transferToICAP(bytes32,uint256)","7334a63f":"whatWouldPurchaseDo(uint256,uint256)","7334b2d7":"isBurnWallet(address)","7334d5e2":"editSpecial(uint256,uint256,uint16)","73357018":"RATE2()","73373879":"RecoveryQuorum(address,address[])","733746ba":"Snickers()","73379c54":"SecretNoteUpdated(address,bytes32,bool)","7337c993":"initiate(uint256,bytes20,address,address,bool,uint256)","73383832":"barrierPrice()","73384fd5":"addMultipleAddressesToUncappedAddresses(address[])","7338c25c":"hasAttribute(address,bytes32)","7338ddcc":"acm()","7338faba":"setHardCapEther(uint256)","73396ff4":"getLoanToDepositRatio()","7339affc":"UbiqTalk()","733ad6e3":"BHMBLU()","733b679e":"PRESALE_LEVEL_2()","733bdef0":"getStakerInfo(address)","733bf2f2":"setPercentageCut(uint256)","733ccaba":"setResolver(string,address)","733d8053":"containsToken(address)","733dca75":"registerCoin(bytes4,string,string,address)","733e193c":"saleHasEnded()","733ef936":"drainFunds()","733efe16":"numSkinOfAccounts(address)","7342048a":"transferOwnershipOfContract(address)","7342c484":"airdropDistributedTokensAmount()","73440745":"listItem(uint256,uint256,address,bytes32,address)","73454fe4":"StuckOnStupidToken()","7345a3a2":"payExcess()","7345da39":"logPayerStatement(string)","73463965":"notifyPlaceSellOrder(uint256,uint256)","73463c9c":"ReceivedETH(address,uint8,uint256)","7346ec57":"tokensToWei(uint256)","73475373":"trySell(uint256,uint256)","73479f39":"totalT8EXSold_CORNERSTONE()","7347a25d":"BitcoinTrade()","7348ac1f":"ecoSupplyAddress()","73493f09":"getTokensCost(uint256)","734a2c72":"ProjectTestToken()","734a56f0":"preSaleEtherPaid()","734b4861":"addOpenAction(string,address,string)","734b9a87":"mod(uint64,uint64)","734bb97e":"checkcoursestudent(address)","734ce665":"newProposal(address,uint256,bytes32,bytes32)","734d8287":"unclaimedFees()","734e3015":"newMegabox(address,uint256,uint256)","734f2838":"FinishCompetition(uint32)","734f8a4d":"kycValid()","735056a3":"SpoolAmount()","73520a2b":"getReservedTokenDestinationList()","7352e4b8":"setAffiliate(address,address)","735307fb":"createTimeLockContract()","73535aa7":"PixelUpdate(uint32,uint8)","7353a21d":"queuedAmount()","7353f62b":"testGetApprovalDb()","73545d44":"landmarkOwnershipCount(address)","73549604":"getFinalTime(bytes32)","7354eb04":"rocCoreAddress()","7355303e":"_priceOf(uint256,uint256)","735631ad":"revokeTransaction(uint256)","7356a8a9":"getTile(bytes)","73580358":"ColorBayTestToken(uint256,string,string)","73582884":"releaseGrant(address,address,bool)","735958f2":"XPAAssetToken(string,string,uint256)","73596cfc":"Bitcoincredit()","73599205":"ProdDToken()","7359f5cf":"FundAddress()","735a3326":"getLeftTickets()","735a80b1":"test_voteSpammingAgainst()","735af2eb":"Rate10()","735b232c":"addWhitelistedTransfer(address)","735b266d":"icoStage1Deadline()","735b38a3":"getCardCanPresaleCount()","735b81ab":"circulationAt(uint256)","735bae84":"migrateRoundData(uint256,uint256,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","735bb742":"sha256Docs(bytes32)","735cfff2":"valueTotalSupply()","735d3e81":"updatedBalance(address)","735d45e1":"RADIUM()","735d8876":"getCurrentExpirationTime()","735dcc8b":"devfeetodev()","735e9cbb":"disableModule(bool)","735f11b4":"updateAndWithdraw(uint256,int256[2],uint256[2],int256,bytes32,address,uint256,uint256,uint256[3])","735fb8e0":"fundOwner()","7360ab6e":"mint(address,uint256,string,uint256,uint256,uint256,uint256,uint256,uint256)","73611c48":"send3MilWeiToPong()","73618371":"Molecule(uint256,string,string)","7362377b":"withdrawEther()","73627826":"getTime(uint256)","7362d9c8":"addWhitelistAdmin(address)","7363d85b":"TMEXAddress()","73646c91":"updateMirroir(address,address)","73654b6d":"userTransferFrom(address,address,uint256)","7365870b":"bet(uint256)","7365babe":"MIN_TOKEN_INVEST()","7365e1fd":"setPriceCutoff(uint256)","7365e2d7":"totalPresaleTokensSold()","736660ac":"determiningWinner()","7366794e":"distributeTokens(uint256)","73668b06":"XCCCrowdsale(address)","7366c68d":"calculateCommission(uint32)","7366e3ff":"raisedInPresale()","73671268":"vestToAddress(address,uint128)","73674ecc":"admin_deposit(uint256)","7367df4b":"Syndicate(uint256)","7367e302":"ContractCreationTransaction(bytes,uint256,uint256,address,uint256,uint8,uint256,uint256)","7367f156":"gameSettings(uint256,uint256)","73681818":"EICQ()","73688914":"owner1()","7368a8ce":"create(bytes32)","7368b3cb":"DinsteinCoin(uint256,uint256,uint256,string,string)","736a0102":"bonusETH()","736a1b9a":"AdjustClientAccountBalance(bytes32,bytes32,bytes32,string,uint256,string,uint256)","736b13ae":"setRefillFor(string,uint256,uint256)","736c24b5":"AdsharesToken(address,address,address,uint256)","736c3e82":"onPayment(address,uint256,bytes)","736c983a":"setCurrentRevision(address)","736d323a":"setPausable(bool)","736d7c52":"isAlreadyDelegate()","736d7ee9":"revokeAccess(address,int256,address)","736ead2c":"optionsCalculator()","736ec05c":"setMigrateTo(address)","736eec58":"TransferAnimalToAnotherUser(uint256,address)","736fafd3":"setPreIco()","736fe565":"withdrawAmount(address,uint256)","73705090":"teamOnePrefix()","7370a38d":"getNumPackages()","7372014e":"midnight()","73720de9":"receiveMonthlyNRT()","7372196c":"PHASE_4_PRICE()","7372c2b5":"pull(address,address,uint256)","73732024":"isDeposited(address)","737377fe":"getTokenVolumebasedBonusRateForPhase2(uint256)","7373af84":"numberOfNarcosByDistrict(uint8)","7373f41d":"getEthereumBalance()","73741171":"createVCXVault(uint256,address)","73743fbe":"prospectors_team()","7374b013":"buyTDETokensWithoutETH(address,uint256,uint256)","737517f5":"powerUp(address,uint256)","73752db4":"getKYCPayload(bytes)","7375c0c3":"PonderGoldToken()","7375e0fe":"testSimpleObject()","7375ed82":"LogLoss(address,uint256,uint256)","7376678b":"finalizePreSale()","7376fc8d":"right67(uint256)","73770c01":"Updater()","737732b2":"DEVELOPERS_BONUS()","7377a036":"CloudexchangeToken(address)","737a7698":"transferAssigner(address)","737aa5a0":"remainingTokensWallet()","737c2d8c":"checkAvailableTokens(address,address)","737c8ea1":"_getRevisionBlockNumber(bytes32,uint256)","737d5f39":"AccessAdmin()","737d8c8e":"ChangeTokenWalletAddress(address,address)","737e2835":"_minHouseEdgeClassic()","737e7d4f":"getByVersionId(uint256)","737f18ff":"_weiToVouchers(uint256)","7380fbf3":"removeMemberArrayToken(address,address,uint256)","73815ab7":"nfc_simplehq()","738198b4":"cast(uint256)","738228cd":"testUmlaut()","73826a93":"updateTokenDetails(string)","7382901e":"serverSeedHash()","73835f35":"checkIfEligable(address)","7383d709":"buyItem(uint256,address)","7383d8ee":"getEachBindAddressAccount()","73845cfa":"setLocked(address,uint256)","738486bd":"BeerCoin(uint256)","7385e1f3":"level_5_amount()","7386c2be":"Exilium()","7386f0a7":"reservedTokensDestinations(uint256)","7387479e":"reclaim_art_token()","73889677":"ownerLives()","73889f4a":"getHoldersCount()","7388fb2b":"AltTokenDistribution(address)","73898796":"Tier_Classic_Registration()","738a2679":"left85(uint256)","738a2cf8":"nextPaymentTime()","738b2fac":"setSignedPublicEncKey(string)","738b31b5":"minimumWithdrawal()","738c2931":"rewardTwo()","738d8d82":"numberWikiPages()","738ddabe":"getContentIndexedAccountCred(uint256,address,address)","738e6d78":"checkRefund(address)","738fa7a4":"userRank()","738fdd1a":"reg()","7390a673":"MyEtherTellerEntityDB()","7390c786":"getRandomResult()","739112da":"safeSubtrCPCE(uint256,uint256)","73913545":"fundVesting(uint256)","73916918":"getinfowinning(address,uint256)","73918980":"multiTransferEth(address[],uint256[])","73925694":"take(uint256,address[])","739294d2":"setAssignedID(address,address,uint256,string)","7392ce80":"TokenDeployed()","73930ce2":"validAmount()","73931bbf":"getGame(bytes32)","73932bfd":"withDrawal()","7393d262":"goldenTicketUsed(address,string)","7393e0b2":"DayTrader()","7394cb3f":"addLocationRecord(uint256,uint256,string,string)","73962b26":"isReleased(uint256)","73963bf0":"setIdArray(address,address,string,string,uint256[])","73964787":"batchAddCancelledOrFilled(bytes32[])","7397d5f1":"getMintForReportingParticipantAmountValue(int256)","73980d69":"dollarRaised()","739826c5":"changeAllowTransfer()","739838be":"DigitalEnthusiasts()","73984188":"delOwner(address)","739890f0":"disqualifyTeam(address)","7398ab18":"getPosition()","7399646a":"theRun()","73998758":"smpToken()","739ab361":"needApprovesToConfirm()","739b47ca":"recordWin(address)","739b5014":"Snatch(uint256,address,address)","739b6214":"doProveMemoryWrite(uint256,bytes32,bytes32[])","739b78ed":"LogSell(address,uint256,uint256)","739b8c48":"setForwardedOutcome()","739bdcff":"pricePause()","739beded":"mintSendTokens(int256)","739cb57d":"setEndtDate(uint256)","739d3307":"SetWho(address)","739d980e":"address(address,uint256)","739e40b7":"getMyPunchCards()","739e7f48":"TeamChoice(address,uint256)","739f2224":"SetActive(bool)","739f763e":"getListing(bytes5)","739f888c":"setNewEstimate(int256,int256)","739f9202":"dev_share()","73a070bc":"addressReserveFund()","73a077a4":"sub16(int16,int16)","73a17e6d":"setCompte_31(string)","73a19dd2":"Deposited(address,uint256,uint256)","73a1e7f5":"allReceivedEth()","73a1f366":"founderTokenCount()","73a22e62":"fetchPaidOrdersForMerchantByAdmin(address)","73a26a12":"CryptoDiamondCoin()","73a29b5e":"get_presale_arbits_sold()","73a2d1ff":"MexicovsSweden()","73a3d9e4":"canUpdatePercentToTakeAsSeed()","73a40efb":"_computeRarity(uint256,uint256,uint256,uint256,uint256,uint256)","73a4c307":"COMMUNITY_SUPPLY()","73a55389":"setRarePrice(uint256,uint256)","73a5717e":"BaironSupply()","73a5f508":"getAuditorRegistry()","73a699ad":"isGenesMarket()","73a72b18":"setFountainFoundationOwner(address)","73a75c1f":"addVineyard(string,uint16,uint24,uint32,uint16)","73a7b8b2":"storeStages(uint256[])","73a7dfda":"we()","73a80336":"prizeWon()","73a80b74":"_mintSqr(uint256,address,uint256,uint256)","73a91544":"showMigrationStabitcoinAddress(address)","73a95ddd":"redemptionPaused()","73a97787":"sgcToken()","73a97f42":"MetaRules(address,address[])","73aad472":"guaranteedBuyersBought(address)","73ab7503":"FlightPlan(address)","73abecbb":"kill1()","73ac4739":"getOnSellCardIds()","73acbcb2":"switchBleachAllowed(bool)","73ad2a15":"AllowedRecipientChanged(address,bool)","73ad468a":"maxBalance()","73ad6c2d":"setMarketplace(address)","73ae277b":"getDepositAddressVerify()","73aef263":"FDSToken()","73aef2b6":"unFrozenControl(address,uint256)","73af652c":"setCollectibleExposure(address)","73b1184e":"setupVote(uint256)","73b14098":"getTotalDevelopmentFundEarned()","73b1edce":"_lock(address)","73b24ca0":"indInflation()","73b2c384":"_computeBorder(uint256)","73b2e80e":"hasClaimed(address)","73b34271":"ETH420on49()","73b38101":"wipe(bytes32,uint256)","73b3dcde":"maxDestroyThreshold()","73b40a5c":"forwardTo(address,address,uint256,bytes)","73b4484f":"registerA(string,string,string,address)","73b47908":"_updateCounters(uint256,bytes32)","73b4df05":"createToken(string,address,uint256)","73b51d38":"startWork(string)","73b51f0b":"_tokenDelivery(address,address,uint256,uint256)","73b55eaf":"registerData(address,int256,bytes32,address)","73b5abaa":"PresaleDiscountPercentageChanged(address,uint8)","73b6656f":"relay(address)","73b68be8":"preicoAddresses()","73b6a48a":"GetDataRequest(uint256,bool,string,uint256)","73b793a8":"PrizeFund()","73b8a8c1":"MeetOneCommunityBonus()","73b913fa":"safeTransferManyFrom(address,address,uint256[])","73b972bc":"bonusTokensIssued()","73b9aa91":"account(address)","73baae7a":"KingKongCoin()","73bbda81":"standardTokenDefrosting(address[])","73bc1b2f":"customerPool()","73bc8b2f":"kvcSub(uint256,uint256)","73bc8b77":"SPIDER_BOOST()","73bda17e":"restrictedTokens()","73be0a99":"getData_7()","73be6ddd":"allowEscrow()","73bfb566":"withdrawFromProject(address,uint256)","73c107b3":"checkWins(uint256,uint256,uint256)","73c1af76":"deleteFreezeList(address)","73c24cb1":"Buy(uint256,address,uint256,uint256,uint256,bytes16,bytes32)","73c261f4":"getRegionUpdatedAtPurchasedAt(uint256)","73c28692":"disallowFunding()","73c2ec65":"sendbal(address,uint256)","73c32a71":"get_property_basic_info(uint256)","73c4726b":"minHouseStake(uint256)","73c4942a":"depositStopTime()","73c6a4ec":"acknowledgeCopieExecutoire(bytes32)","73c6aa7d":"ExchangeEfx()","73c74103":"recoverTokensTo(address,uint256)","73c8c4bf":"Leverages()","73c8d8a2":"setMaxPaymentInEther(uint256)","73c8de54":"issueByTranche(bytes32,address,uint256,bytes)","73c90b43":"calcBidAllocationFee(bytes32)","73ca1b28":"WHYPHY()","73cb0620":"fluffyCatAddress()","73cb8ab7":"enableTokensTransfer()","73cbd8ce":"getPublicSupply()","73cc3ec7":"iceFundDeposit()","73cc9153":"MeshPointManager()","73cce6f1":"presaleAllocateTokens()","73cd0a19":"allowanceBurn(address,address)","73cd148e":"VariableConstructor(string)","73cdcac4":"getPostsFromPublisher(address,string,uint256,bool,uint256)","73ce3c72":"UpStats(uint256,uint256,uint256,uint256)","73ce9920":"parseOrder(bytes)","73cf013c":"isBlacklist(address,address)","73cf8f97":"registryRequestSku()","73d00224":"swapTokens()","73d01ead":"prepareForMigration()","73d08bc5":"prefill(address[],uint256[])","73d0d693":"Set(address,uint32[],uint24[])","73d0fe48":"totalLockedHavvens()","73d28995":"isMidGrade(uint256)","73d31240":"removeGame(uint256)","73d3172e":"MXY_chain()","73d384c8":"hasDeposits(address)","73d45ba4":"owner_ActivatePOS(bool)","73d4a13a":"data()","73d4c0ff":"m_aOwner()","73d4d500":"transferPayable(address,address,uint256)","73d4d9f9":"checkMAC(bytes32,bytes32[],bytes32)","73d55379":"Beneficiary()","73d65c00":"GEN0_NO()","73d69720":"checkWhitelistAddressValue(address,uint256)","73d6c2ec":"init_ico(address)","73d901d6":"activityClosed()","73d9170d":"GKBToken(uint256,string,string)","73da968d":"buySection(uint256,uint256,string)","73dae7d6":"issueTokensForPrivateInvestor(uint256)","73db0844":"ETHUSD()","73db2350":"commentsLength()","73dc7635":"openAttacksCount(address)","73dd9073":"secondStage()","73de3570":"calcaultePrizes(uint256,uint256)","73de3e72":"_refundTokens()","73de975c":"alreadyMintedOnce()","73def2b7":"subFreezingPrice()","73df6b19":"visitLength(uint8)","73e1743a":"buildDSBasicAuthority()","73e1851b":"migrateMyTokens()","73e1c5c9":"getMyFreeCoin(address)","73e2212e":"changepresalebonus(uint256)","73e2d75f":"changeClons(address,uint8,bool)","73e2faa8":"destructionContractAddress()","73e30e49":"majorEventFunc(uint256,bytes,bytes)","73e3ce80":"fact()","73e3de70":"CardSwap(address,uint256,uint256)","73e3e7a7":"getAdultByAddress(address)","73e40ed4":"REWARD_SUPPLY()","73e4d829":"createLandmark(uint256,uint256,address,uint256)","73e52855":"crownUnFreeze()","73e538fc":"availableTokensOnCurrentStage()","73e55a57":"DAOstackPreSale(address,uint256,uint256)","73e58a75":"balanceTeam()","73e61cf2":"changingEnabled()","73e67a38":"GameGoldToken()","73e6fc1b":"parseUint(string,uint256)","73e7c8ce":"setErrorRest(bytes,uint256)","73e81d88":"TrustMarketHubToken()","73e87d74":"OTM()","73e888fd":"contribute(address)","73e8b3d4":"exist(bytes32)","73e9f3e6":"Crowdsale(address,uint256,uint256,uint256,address,address)","73eab74b":"SoulTransfer(address,address)","73eaddf0":"OMGBalance()","73ec6bb5":"AMOUNT_PER_PHASE()","73ec7df0":"joinCommunity(address)","73ecac3b":"setGiftTokenAmount(uint256)","73ece9c4":"setEmployee(address,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint8)","73eda3cc":"finalizePublicSale()","73eec3c5":"payoutDividends(address,uint256)","73eef753":"coinSendSameValue(address[],uint256)","73ef6357":"selectplayer()","73efc627":"addAction(bytes32,bytes32,string,uint256,bool,uint256,uint256,uint256,uint256,bytes32)","73f00fb3":"emissionlocked()","73f01104":"reveiveToken(address,uint256)","73f029cd":"setOrUpdateRecord(string,string,string,string,address,uint8,bytes32,bytes32)","73f03d53":"crowdSaleFinalized()","73f1e6d7":"resolveLotteryByOraclize(uint32,uint32)","73f28451":"tokensRate()","73f310df":"multiAccessRemoveOwner(address)","73f3312d":"setMentorsTokensWallet(address)","73f3bd1f":"earlyInvestors()","73f42561":"burned()","73f440fe":"prevRoundTweetId()","73f58acd":"createTeamTokenTimeLock(address,uint256,uint256,address)","73f5cfb1":"isPhaseValid(uint256)","73f5edce":"UpPlayerResult(string,address,uint256,uint256,uint256)","73f5f8ee":"tokensAvailableAtCurrentTier()","73f64212":"supplyMultiplier()","73f69bc5":"TrustedDocument()","73f8edc3":"configureMarketItem(uint256,uint8,uint8,uint8,string)","73f8fd4b":"getUserTokenBalance(address,address)","73f93a48":"getAccountContentTip(address,uint256)","73f9421d":"getUpgradeCardsInfo(uint256,uint256)","73f9d5a0":"eostContract()","73f9ff23":"RaffleMakersBook(string,uint256)","73fa9ce8":"getAmTokenBalance(address)","73fac6f0":"confirmReceived()","73fb7878":"dividendFor10kDaily()","73fba0e8":"airdropReserve()","73fc83fa":"updateDireccion(address,bool)","73fc8420":"deployedOn()","73fc9643":"calculateFLC(address,uint256)","73fcfea1":"withdrawPLAT()","73fddd16":"refundEndTime()","73fe1673":"cpow2(uint256)","73fe747c":"TransferCreators(address,uint256)","73fee090":"setfee(uint256)","73fef35a":"setStartTimeIcoStage2(uint256)","73ff4d48":"getPlayerForCard(uint256)","73ff81cc":"getOwnersCount()","73ffd5b7":"transferEther(uint256)","73ffd969":"setMap(uint256,uint256,uint256)","73ffecd0":"getPlayerHistories(address,uint256)","7400ed3b":"acceptDeposit(address,address,uint256)","74019f87":"BATSafe(address)","7401aaa3":"getPlayerRoundBought(uint256,uint256)","7401f9c0":"flag(uint256,address)","740227d1":"receiveFunds(address,uint256)","7402a9aa":"isFirstStageFinalized()","74030531":"bet(string)","7403db08":"getVerifiedHash(address,uint8,address,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32)","7403e980":"initPGOMonthlyPresaleVault(address[],uint256[])","74040424":"startPartnerSale(uint256)","74040cd2":"setBidFeePercents(uint256)","74041d1f":"liquidPledging()","74043a70":"FRPUSD()","740528a7":"GrantRevoked(address,uint256)","7405322e":"checkBalance(address,string)","74056b73":"crowdsaleMinUSD()","7405cee9":"CGCToken(uint256,string,string)","74063cc1":"tokenOfMakerByIndex(address,uint256)","74068480":"setPresaleFail()","7406d1a7":"updateRegistratorStatus(bool)","7406d943":"BIGTPrivate()","740707cf":"cancelSaleOfMintingAddress()","74087040":"testBitsNotEqualSuccess()","740907ea":"buySale(address)","74091685":"setReservesForExchangeTokensPercent(uint256)","7409e2eb":"swapTokenToToken(address,uint256,address,uint256)","740a2a90":"registerEmployer(string,string,bytes32,uint256,uint256,uint256[],string,string,string)","740ab8f4":"partitionsOf(address)","740b63f9":"set_hedgeAddress(address)","740b91b6":"horseOwnerIndex(uint256)","740d0a6f":"getAmbientHumidityException(bytes32)","740d73f3":"addToWhiteList(address[])","740e2a29":"setFundRepository(address)","740ed4e0":"addNewStakeDiceGame(uint256)","7411b2b2":"TrendNetworkToken()","741273d6":"testThrowRegisterContractAgain()","7412c223":"getCurrentTier()","74135154":"func1()","7413dcc3":"DelistTitle(uint256)","74141266":"arbiterList(uint256)","741430ad":"VINCToken()","7414edc4":"ERC20Token(string,string,uint8,uint256,address,uint256)","74151a2a":"retrieveUnsoldTokens()","74158cd8":"updateAdministratorKey(address,address)","7415fbdb":"_getGameInfoPart2(uint256)","74163ab1":"minsignupeth()","741677a5":"makeTrade(address,address,uint256,string)","741685e5":"EtherFuture()","7417040e":"numberOfParticipants()","7417575c":"_releaseEarning(bytes32,bytes32,bytes32,bool,address,uint8)","74182009":"CreateWolk(address,uint256)","74192209":"getTokenEnhanced(uint256,bool)","7419e77a":"setMarketplace(address,bool)","7419f190":"stakeStartTime()","741a35c4":"getTx(address,uint256)","741ad7a3":"transferDividends()","741b0508":"isSplitable()","741b2239":"unfreeze_period_time()","741b3c39":"depositBond()","741bcc93":"fillOrKillOrder(address[5],uint256[6],uint256,uint8,bytes32,bytes32)","741bd9c8":"ETHDeposir()","741be410":"getOpenPackageIdOfOneAgency(address)","741bef1a":"priceFeed()","741c251d":"changeGamemaster(address)","741cb9ce":"setCurve(address,bytes32,int256,int256[])","741cdf27":"Library()","741e2345":"registerMany(address,uint256,int256,uint256,bytes20,address,bytes)","741e3576":"getBonustokens(uint256)","741ed475":"AnkitVictoToken()","741f0434":"check(bytes20,uint32,int24[4],int24[4],uint32[4],bytes32[])","741f7034":"CrowdsaleToken(string,string,uint256,uint8,bool)","74214c92":"StandardERC223Token(uint256)","74220f3d":"burnApproval(address,address,uint256)","74229301":"isTokenized()","7422a127":"is_valid_event()","7423ab57":"Project_RemoveToken(uint256,uint256)","7423d96e":"txnTax()","7423e225":"getDataPointForSubject(int256,uint256,uint256,int256)","7424bab1":"currentAirdropAmount()","7424bebc":"bonusBasePoints()","7426172d":"addPurchaseFromOtherSource(address,string,uint256,uint256)","74268ff2":"deleteOffer(uint256)","74281f95":"FNAToken()","74287872":"investedAmountOf()","742887ff":"deleteAddress(address)","7428c5f4":"Gamble()","7428eed3":"IndieGameToken(string,string,uint8,uint256,address)","74294070":"_createItem(string,address,uint256,bytes32,address,address)","742978da":"getAssets(address)","7429c086":"repeat()","7429d78b":"SUCC(uint256,string,uint8,string)","7429f1eb":"multiAccessSetRecipientD(address,address)","7429fd67":"initHolderConfig()","742a1a56":"CCTE()","742a9fa0":"recursiveFloor(uint256,uint256,uint256)","742aa578":"AddressRecovered(address,address)","742b8b9d":"_CallRejected(bytes32,bytes15)","742ba8de":"declareProjectNotFunded()","742bff62":"SoftDude()","742c81e4":"approveOwnership()","742cd75d":"mintPCD(address,uint256)","742d5355":"calcTokenOwnerReward(uint256)","742d9f0b":"lastBlock_v7()","742d9fa3":"userOfferSubmitElement(uint256,uint256,uint256,uint256,uint256,uint256)","742e2ebd":"AllowedSet(address)","742e54b2":"_airdropSupply()","742f79d5":"preRate()","7430faf4":"fechSnapshotBlockByIndex(uint256)","7432542d":"_remainReward()","74331be7":"sete(address)","7434206e":"validateReceipt(string,uint256,bytes32,bytes32,bytes,bytes,bytes32)","743438ad":"id_for_address(address)","7434d180":"removeSmartContractByAddress(address)","7434e60d":"HamsterToken()","7435039d":"calculateBountyRewards(uint128)","743521c6":"rewardBountyMany(address[],uint256[])","7437681e":"maxTx()","74388347":"checkBetDozen(uint8,address,bytes32,bytes32)","74389991":"breakit()","7438b0df":"WIN_CUTOFF()","74396ed1":"makeWithdrawal(address,address,uint256,uint256)","74398d45":"setGlobalTokenTransferLock(bool)","7439a3bd":"verifyClaim(uint64)","7439e787":"getUserValues(address)","743a3252":"addAddressAsMultiOwner(address,string)","743ab538":"validateNameSignature(string,uint256,address,string,uint8,bytes32,bytes32)","743b179e":"giveRefund(address)","743b8e1a":"ROHH(uint256,string,string)","743bd681":"OWNERS_AUCTION_CUT()","743bdcef":"MAX_WITHDRAW_PCT_TX()","743c006b":"iWantXKeys(uint256,uint256)","743c6775":"investorBaseInfo(address)","743c7f6b":"setPreSaleDate(uint256)","743e0c9b":"receiveTokens(uint256)","743e92ee":"getNode()","743f78ab":"WalletSet(address)","743f978f":"addValueToCovfefe(uint256)","74400873":"execute(uint256,address,uint256,uint256)","744013c4":"Gnome()","74418368":"getAdvertisementStorageAddress()","7441b8bb":"lockBalance(address)","7442f427":"subUserTokenLocalBalance(address,uint256)","74439ca7":"classic()","74449ca4":"getContentCount()","7444b006":"transferCopyFrom(address)","7444b227":"getMidgradeCarsForVariant(uint256)","7445690b":"getLotteryClass(uint8[7],uint256)","744598cd":"Phase1AccountTokensMaxUpdated(uint256)","7445af4b":"pay_by_bond_contract(address,uint256)","7445d659":"foreignBridge()","74467a1e":"FOR_SALE()","7446ce1c":"addJob(bytes32,uint256)","74478bb3":"isClaimable()","74479db0":"fcontr()","7448d386":"getStageData(uint8,uint256)","744927fd":"getWinnerWithRank(uint8)","744a8f77":"chefPrice()","744b4b3f":"createNormalBank()","744bb8d2":"crowdsaleHardCap()","744bfe61":"withdrawFunds(uint256,address)","744c7c7f":"proposeMinting(uint256)","744c8c09":"chargeFee()","744d0a92":"MINI_GAME_BONUS()","744d8b4f":"recordWin(uint256,uint256)","744f4994":"getBrickIdsByOwner(address)","744f5f1a":"modifyTaxRate(uint256)","744f7c7d":"toUint256Safe(int256)","744fa2c8":"submitTokenToEthOrder(uint128,uint128)","7451bf71":"admin_transfer(address,address,uint256)","745332fe":"getRestarTime()","74536403":"getAvar()","74539f98":"getEventResolvers()","7453a417":"__address4__()","7453cfa1":"EtherPaint()","7453de96":"approveTransaction(uint256,uint256,string,uint256)","745400c9":"requestWithdraw(uint256)","74544e2d":"setGrandFactory(address)","7454e74c":"setAudit(address,address)","74552650":"left95(uint256)","7456be7d":"rent(uint256)","7456f2b9":"getDistributionTime()","74573f80":"lastPlayTimestamp()","7457412e":"THIRD_PARTY_LOCKUP_ADDR()","7457a9e1":"Coupon(uint256)","74580e2f":"changeCreator(address)","745828ef":"ProofOfLongHodlV2()","74583772":"adminSendTokens(address,uint256)","74590f64":"setApoderado(bytes32)","745911d5":"getHolidayByIndex_(uint256)","745944d5":"setCampaignValidById(bytes32,bool)","7459a5e1":"KriptoPark()","7459f2a3":"registerArbiter(uint256,uint256,uint256,uint256,uint256)","745a8be2":"flip32(bytes)","745ab73d":"BrainIsToken()","745ce3bb":"iaInvestedBy(address)","745ced49":"CORE_TEAM_PORTION()","745cf221":"ArjunaCoin()","745d1d64":"ethCollector()","745dcd4d":"stop(string)","745e77f9":"_createAnimecard(string,string,string,string,uint256,address)","745e9da2":"GameProgress(uint256,uint256,uint256)","745ea0c1":"registerNameXnameFromDapp(address,bytes32,bytes32,bool)","745f2860":"_buyTokens(address,uint256,uint8)","74601c3c":"availableToMint()","746022c2":"oneGetMoneyBack()","74607d91":"patient(uint256)","74609d0c":"createDApp(bytes32,uint32,bytes,bytes32)","746178ed":"escrowTokensWallet()","7461dbff":"setOwnerAirDropRate(uint32)","7462260b":"KEM()","7462beec":"renewSubscriptionByDays(uint256,uint256,uint256)","7462e4f9":"Etheropoly()","74635cfc":"setMembers(address[])","74646086":"StreamityTariff(address)","7464d5d8":"rewardDistributionStart()","74651594":"tgeSettingsChangeRequest(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","746584b4":"setMintingContractAddress(address)","7465df26":"totalAccessories(uint256)","74664b34":"interestNextInPercent()","7466b2d0":"transferIsPossible()","7466e67d":"mintToOtherCoinBuyer(address,uint256,string)","7466ee48":"getAppAddress(uint32)","74674256":"temroyToken()","746796f0":"_setProfitSharingParameters(uint128,uint128)","7467af07":"EladToken()","7467bc92":"disbursementHandler()","7467bcd9":"minPaymentWei()","74689990":"schedulePayoutOraclizeCall(uint256,bytes32,uint256)","746a9af2":"printCertificate(string,string,string,uint16,string)","746abc79":"distributeRegistrationBonus(address)","746ac67e":"PCNCrowdsale()","746c9171":"m_required()","746d3024":"perPrice()","746df633":"getTeamBallers(address)","746eff8c":"_cancelRolePermissions(address,address)","746f79d9":"TIER2_PERCENT()","746fc8d0":"right47(uint256)","74703123":"proceedKYC(address)","74707e0d":"deleteWallet(address,address)","747082b9":"FsTKAuthorityChanged(address)","7470a835":"OliToken(uint256,string,uint8,string)","7470f760":"createTeamTokenByPercentage()","74711285":"restartSale()","74715432":"renounceAuctionManager()","7471ea81":"IPayX()","7471f6f6":"buy_beer(uint256,uint256)","747293fb":"addCaller(address)","74748460":"balanceOfAtInternal(address,uint256)","7474dfd0":"_getBetAmount(bytes32)","74754282":"manufacturer()","747586b8":"setInt(int256)","74759f43":"numberOfInvestments()","7475baa6":"AirDropPayBitsBounty(address[])","7476865f":"ToggleMaintenance()","74772667":"changeMinContrib(uint256)","74775cdd":"buyAtPrice(uint256)","74780111":"assertEq16(bytes16,bytes16)","747853bc":"test_validBoardFundTransfer()","74796cc2":"getPlayersInGame(uint256)","7479aa04":"getCurrentRoundStartTime()","7479b9ac":"founderToken()","747ad1c1":"getPeriodIdx(uint256)","747bcd72":"SCORE_UNITARY_SLASH()","747c1d87":"getInvestorsAmount()","747cb030":"SALE_3WEEK_BONUS()","747d6dd0":"_getCrabPartBonuses(uint256)","747dff42":"getCurrentRoundInfo()","747e0670":"UseWish(string)","747f3380":"phoneNumber()","747fc0d2":"maxReferrals()","7480a676":"Cryptosquirrel()","74816d1e":"webGiftUnTransfer(address,address)","74817d9b":"startPublicSale(uint256)","74818530":"Creedex()","7481a8aa":"TokenizedSplitter(string,string,uint248)","7482e533":"EventLuckyNumberRevealed(address,uint256,uint256)","7483883d":"getOrAddMasterWallet(address)","74845024":"scribes_hisory_length()","748467b9":"callBtcWithSto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","7486a8e3":"get_publisher(bytes32)","748837b2":"getIsBonusUnlockExempt(uint256,address)","74888914":"setHatchDurationMultiByGeneration(uint32[])","7488aa3c":"getNextBonusIndex()","7488ad7c":"minDepositInCents()","74891e1b":"getCoinAgeInternal(address,address,uint256)","7489308f":"lpTargetPosition()","7489472a":"step_pay()","748949e8":"setGalleryFourPrice(uint256)","7489ec23":"cancelOrder(bytes32)","748b659d":"pauseCollectToken()","748b95b6":"decimls()","748ce291":"addRewardforNewContributor(address,uint256,string)","748d071d":"seriesCreated(bytes32)","748d1078":"updateDukeHistory(string,bool,string,address,uint256,uint256)","748dd2fc":"GAME_TYPE_DICE()","748de225":"getFreezeAccount(address)","748de5d3":"UpdateAddressPayForService(address)","748e4f40":"sendTokensToTeam(address)","748ed9a8":"getTargetIncorrectDesignatedReportMarketsDivisor()","748efab5":"_copyToBytes(uint256,bytes,uint256)","748f0810":"ProposalTallied(uint256,uint256,uint256,uint256,bool)","748f7215":"getUnlocktime()","748fa599":"someUnsafeAction(address)","748ffa5b":"cei(uint256,uint256)","74900c92":"MINIMUM_ETHER_SPEND()","74912463":"tokenEmission()","74914710":"getCrySolObjectsByOwner(address)","7491ef60":"PrecommitmentAdded(address,uint256)","7492384a":"backTixOwner()","7493357b":"reservedOwner()","7493539b":"KOALAPROJECT()","74935f11":"PLS()","74942868":"rate8_end_at()","74942c0f":"tokens_received()","7494ad81":"judge(uint256,address)","749510d4":"BOUNTY_FUND()","749555cd":"toggleIsLive()","7495a1e4":"buyFor(string,address)","7497a061":"getAuthorDrawings(uint256)","749843ea":"setPlatinumAddress(address,address)","74991569":"setVestingContract(address)","74998f33":"Infinix()","749a47b7":"minPreviewInterval()","749aa2d9":"endRound()","749b7820":"canBuy(address,uint256,uint256,uint256,bytes8)","749be0c0":"GetTotalPot()","749c190b":"getHashsLength()","749ca1f3":"setGameOnoff(uint256)","749cab54":"setBlocks(uint256,uint256)","749db2f6":"Contract(string,string,address)","749dd65d":"_currentMonth2ndDayTimestamp(uint256,uint256)","749e8b88":"BUYPRICE()","749e93fc":"actualPriceDivisor()","749ea598":"leaders(address)","749f1bc3":"agendaOf(address)","749f9889":"changeAllowedRecipients(address,bool)","749fe7c4":"getPlayerEnergy(uint32)","74a042b5":"ClaimEthersEvent(address,uint256,uint256,uint256,uint256)","74a0cd8c":"getCombinedWarriors()","74a205d9":"ZIMBOCOIN()","74a25d43":"startAuction(uint256,uint256,uint256,uint64)","74a32dd7":"TotalAirdropRequests()","74a37efc":"setSalary(uint256,uint256)","74a3c5d5":"getVestingAmountByNow(address)","74a46050":"offer(address,uint256,uint256)","74a76649":"payTheWinner(uint256)","74a7d6b9":"initNewPlayer(address,bytes)","74a7d77c":"sellTokensNow(uint256)","74a814fe":"getGeneral(uint32)","74a85571":"addAccount(address,uint256,bool)","74a8f103":"revoke(address)","74a93e6c":"setTokenHolder(address,address)","74a9446e":"_removeAllActiveTasksWithHoles(uint256,uint256)","74a9ced9":"createPoll(string)","74a9e440":"createProposal(uint256,address)","74aa9e2c":"PRESALE_RESERVERED_AMOUNT()","74aac084":"joinDelta()","74ab3e4b":"updateCardStatistics(address)","74ac5bb4":"erc20KGS(uint8)","74ac6112":"HOPE()","74acb5d6":"isAirdrop(address)","74acf0b1":"communityDevelopmentWallet()","74ad74e9":"getMinLockedAmount(address)","74ae26f7":"checkReleaseAmount(address)","74af10cf":"setNeedToGetFree(uint256)","74af3ee1":"getTournamentState()","74b00a6c":"convertNums(uint256[])","74b04fa7":"setArtistAccount(bytes16,address)","74b10ae5":"checkWhale(uint256)","74b26fa1":"delegateReferralTokensBulk(address[],uint88[])","74b27b9b":"indexextend(address)","74b38531":"stopBet()","74b39158":"validateAttack(address,address)","74b3ee18":"getFlag(string)","74b433bd":"TOKEN_SUPPLY_MKT()","74b491ff":"airdropCurrentTotal()","74b527b0":"getMintedCounts()","74b5545a":"delCertAdmin(address,bytes32)","74b57486":"DebugContract()","74b58489":"setWeiMinContribution(uint256)","74b58ae7":"setCCH_edit_10(string)","74b5fb06":"_payout()","74b67b27":"GameCoin()","74b78b26":"payeth1(address,uint256)","74b799af":"disableEdition(uint256)","74b874a6":"liquidationTimestamp()","74b9dc6b":"assertEq9(bytes9,bytes9,bytes32)","74b9f229":"buyTokensPreSale()","74bb3cb4":"getOrderActualTotalRefundHelper(uint256,uint256)","74bd6261":"AdsVenture()","74bdb7ee":"createApprovalEvent(bool,address,address,uint256)","74bde311":"scheduleNewDerivativeToken(address,uint256)","74be3c7f":"TRONV()","74bfb965":"addNewProxy(address)","74bff257":"getCartItemInfo(address,uint256)","74c06f5d":"saleHasFinished()","74c1328a":"bytesToUInt(bytes)","74c13fda":"defaultToken()","74c1438c":"DeepGold()","74c166e9":"phase1MaxTokenForSale()","74c16b23":"registryAdmin()","74c1b1c9":"refundOpen()","74c1d7d3":"_best(address,address)","74c21059":"totalInvested(uint256)","74c272b7":"Begin(string,string)","74c40f2e":"dexTestTransferFrom(address,address,address,uint256)","74c42e5d":"setuserlevel(address)","74c43f26":"setFundariaBonusFundAddress(address)","74c57fa1":"LogTeamTokensDelivered(address,uint256)","74c65206":"Buy_Offer(uint256,uint256,uint256)","74c6bd74":"privateSaleLockEndTime()","74c77b52":"SetupToken(string,string,uint256,uint256,uint256,address,address,uint256)","74c80467":"createNewElections()","74c85591":"fundDepositAddress()","74c90d0d":"sellAllCookies()","74c950fb":"TOKEN_TOTALSUPPLY()","74c97c99":"manaToken()","74cad0b7":"ForTester()","74cb55fb":"fundsDistributor()","74cc991c":"getBetValue(bytes32,uint8,uint8)","74ccd7cc":"walletLock(address,uint256,bool,bool)","74ccf06f":"addParsel(uint256,uint256,address[])","74cd5a31":"HXTtoken()","74cd5c0b":"getOneWithdrawRec(uint256)","74ce52ce":"Kildoneum()","74ce9067":"isCommitPhase()","74ce97fe":"year3LockAddress()","74cf6f49":"withdrawNoLimit(address,uint256)","74cfa35f":"ambassadorAddressOf(address)","74d04f83":"addtoPrivateSale(address,address,uint256,uint256)","74d050fb":"cardNumbersOf(uint256)","74d15357":"virtualc()","74d16c37":"getAssetsValue()","74d1eb3f":"MANToken(string,string,uint256,uint256)","74d21ae0":"unlike(uint256)","74d301d6":"sizeBonus()","74d33745":"REAPER_INTREPID_FTL_SPEED()","74d3475c":"PowerofBubble()","74d393f0":"setValue2(uint256)","74d3b7cd":"LTR3Token()","74d42916":"IINEToken()","74d4ab27":"fipsRegister()","74d50c1c":"TOPB()","74d53cc2":"sendReferral(address,uint256)","74d55ceb":"Rhemaxcoin()","74d5e1ea":"setteam(address,uint256)","74d5f2aa":"BoxTrade()","74d618cb":"setTransferActive(bool)","74d699b6":"Sale(string,uint256,address)","74d6aa1f":"getOrCreateFeeWindowForForkEndTime()","74d76bc4":"_getGameInfoPart3(address,uint256)","74d88c50":"submitEthToTokenOrder(uint128,uint128)","74d89c47":"testUpdateNameDb()","74d8b268":"getGunByIdPart1(uint256)","74d9c2ef":"tokenTosale()","74da564f":"registerMeOnTokenCore(address,address,uint256,string)","74dacc7a":"m_attaching_enabled()","74daf5cc":"setValidPriceDurationInBlocks(uint256)","74dbe5e6":"GetSpud(address)","74dc1e04":"TokensDestroyed(address,uint256)","74dcfd37":"NotakeyVerifierForICOP(address,address)","74dd7be9":"setCompte_42(string)","74de4ec4":"addReward(uint256)","74de8caf":"ERC20transfer(address,uint256,bytes)","74de9ebb":"MintEvent(uint256,address)","74dfcabc":"changeFreezeTransaction(string)","74dff9d8":"stopCycle()","74e00730":"DISTRIBUTION_COMMUNITY()","74e048d5":"settleBetUncleMerkleProof(uint256,uint40)","74e09606":"setSignatureTimeout(uint256)","74e104d3":"BITWORKCOIN()","74e29ee6":"deleteService(uint256)","74e4435f":"getUserAddress(uint256,bytes32)","74e4f31d":"ZJLToken()","74e5530d":"testHasRole()","74e57397":"BrandUpdated(address,address,string,bool)","74e59296":"MYE()","74e5b122":"changeGenerator(address)","74e5b186":"_mint(string,address)","74e60a48":"cancelOrder(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","74e7493b":"changeRate(uint256)","74e74f24":"rulesProposal(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","74e8288c":"SaiContest_Gaia()","74e95828":"_distributeWinnerAndLandholderJackpot(uint256,uint256)","74e99f87":"AIWEBToken()","74e9e102":"GetTempStuffList(address)","74ea9437":"transferICOToken(address,uint256)","74eac2e6":"Beruqtoken()","74ead7b7":"unstakePrimordialTokenFrom(address,uint256,uint256)","74eb7c90":"withdrawSaleManagerBalances()","74eb936b":"ethQuantity()","74eb9b68":"isAccountLocked(address)","74ebe3ec":"isSet(address)","74ec8682":"walletForETH()","74ec89cb":"H2CToken()","74ecf4b5":"getWinningNumber(uint256)","74eead66":"SFT_PER_ETH_SECOND_EARLY_BIRD_RATE()","74eedd46":"fundingEndTime()","74ef109b":"ChinaLifeCoin(uint256,string,uint8,string)","74f0314f":"SECONDS_PER_DAY()","74f059ad":"dateDefrost()","74f0765a":"mintSeq(address[])","74f079b8":"txCounter()","74f12933":"devPaid()","74f1d6ce":"keccak(address,address,uint256)","74f28eaf":"_set11()","74f47a7a":"nextDrawTime()","74f519db":"setLastTimestamp(uint256,uint256)","74f569e7":"EriCoin()","74f61642":"rewardsRedeemed()","74f760e4":"WithdrawWinnings(uint256)","74f78412":"market_DeclareBid(uint256)","74f78437":"FD(uint256,string,uint8,string)","74f79c8e":"DEFROST_INITIAL_PERCENT()","74f8d96e":"getRevisionBlockNumber(bytes20,uint256)","74f8f7ac":"increaseUpdateMetadataCounter(uint256)","74f91b56":"setXTVNetworkContractAddress(address)","74fa01c9":"MilcToken()","74fa4874":"getResultStatus(uint256)","74fa98f5":"setInviteCodeFree(string)","74fb381a":"inject(address,address)","74fbbc86":"rate(uint256,uint256,string)","74fc27c1":"xfitcoin()","74fcd919":"tokenMsg()","74fd08cd":"whatSatoshiSays()","74fd6176":"removeBulk(address[])","74fe6dea":"nameCat(bytes5,bytes32)","74fe9247":"AddRevocationBounty(bytes32)","74fefa2c":"findEndpointByAddress(int256,address)","74ff2324":"requestMinimum()","74ff90ba":"Disbursement(address,uint256,uint256)","74ffdcd0":"WEI_PER_ETH()","75012c35":"setBonusTokenInDays(address,uint256,uint256)","750142e6":"totalReward()","7501f741":"maxMint()","750225d0":"completeSale(uint256)","750240a2":"setMaxResolvedAgonId()","75030996":"getServiceName(address)","7503af06":"Test9J()","7503cda7":"getLogOwnerAddr()","7503cda9":"thinkLength()","7503e1b7":"tournaments(uint256)","750446a3":"howManyTokensAreReservedFor(address,address)","750482ba":"ownersBalance()","75048ebd":"claimUnsold(address)","7504aaaf":"updateTargetedMoney(uint256)","75052882":"modifyProductPrice(bytes32,uint256)","75056811":"accountClaimedReward(address)","75067219":"MAX_UCCOIN_SUPPLY()","75071c4c":"founderFund()","750732ec":"addVineyardByRegulator(string,string,uint16,uint24,uint32,uint16)","7507b2e5":"OVOToken()","7507ba39":"remit()","750852b3":"test_invalidThrowWithAsserts()","7508f147":"setOperationalReserveAddress(address)","75090ebf":"changeDomain(uint256,uint256,uint256,address)","750a687c":"GetRevealBlock(bytes32)","750a96ac":"_createPermission(address,address,bytes32,address)","750c47a1":"TOKEN_PER_ETHER()","750c77cb":"AccountMinterRemoved(address,address)","750cae6a":"enableBetting_only_Dev()","750cc645":"_sendToken(address,address,uint256)","750dd523":"getContractCreationTxOrigin()","750e1f59":"transfer(address,uint256,bytes1[])","750e443a":"voteAgainst(uint256)","750e75d5":"distributeJackpot(uint256)","750ee24a":"changeIcoEndBlock(uint256)","750f0acc":"withdraw(uint64)","750f2d81":"ChangeFreezeTime(uint256,uint256)","750f7daf":"hashBiometricTemplates(string,int256,string,string)","750fd1d1":"startTimeRefund()","7510a98c":"updateConfig(uint32,int256)","7510c5a0":"encoding_description()","75114bcc":"addPhrase(string)","7511828e":"Laxz()","7511ef65":"setWithdrawAddr(address)","7512071b":"doApprove(address)","75121c2c":"FCOIN1448Token(uint256,string,string,uint256)","751318f4":"bountyAdded()","7513eaa7":"HolyCoin()","75143ef2":"mintFinished()","75151f6b":"addCountryCode(uint256)","751559e8":"transactionfee()","7515b583":"exchangeCoin(uint256)","7515b84a":"releaseRoto(address,bytes32,uint256)","75160a20":"pay_royalties()","751634d9":"ChangeRules(uint256,uint256,uint256,uint256)","751686f7":"_maint_setBlockLimit(uint256)","75172a8b":"reserves()","7517b57e":"withdrawTaxEarning()","7517ea47":"configureSale(uint256,uint256,address,uint256,address,address,address,address)","751823f2":"changePartnerCoinPercentage(uint256)","751827ac":"setRareAddress(address,address)","7518af71":"VGWToken(address)","7518fa98":"tokensContract()","7519dd8e":"starsOf(uint256)","751a0225":"addElement(address,bytes32)","751a2d06":"Token_4()","751a9108":"balancesof(address)","751c4d70":"contributeDelegated(address,uint256)","751ce8fb":"sendRewardBlockCDN(address,uint256)","751d9e65":"WALLET_FOUNDER()","751e1079":"compareAndApprove(address,uint256,uint256)","751ecea0":"FUTURE_DEVELOPMENT_POOL()","751ef753":"toggle(uint256)","751fef65":"sellUnit(uint256,uint256)","7520320f":"registerCustomer(address)","7520767f":"createNew(string)","7520bf60":"gas_price_max()","75218a54":"getUserReactionCount()","75219e4e":"transfer(address,address,uint256,bool)","75229e28":"lockcheck(uint256)","7522aff5":"rejectContract(bytes32)","752329ec":"retainedEarning()","7523a46e":"HARITECOIN()","75247ccb":"_calculateReward(uint256)","75250e85":"limitDateCrowdWeek1()","752551c9":"_END_DATE()","75257013":"appendToDistributionList(string,address,uint256,uint8)","7526f98c":"getMin(uint16[])","7527313d":"minedBlock(uint256)","75286211":"finalizeChange()","75288d95":"platformSupply()","7528a6ab":"icoPhase4Start()","75298734":"getShare()","7529b1d9":"upgradeHasBegun()","752a3df6":"transferIfHardForked(address)","752b016d":"DeletePatient()","752bacce":"getExecPrice()","752bece8":"Minus(uint256,uint256)","752bf6f8":"sale_pause()","752c5628":"callSend(address,uint256)","752c8777":"setArenaPool(address)","752d2bfb":"addDividend(uint256)","752d349c":"depthCheck(int256,int256)","752da85a":"endContribution()","752dd0dc":"unfreezeBonuses()","752dd635":"ETHButton()","752efafc":"TIER5_RATE()","752f3c8c":"relinquishOwnershipAddress()","752faa51":"setLockedGroup(uint8,bool)","752fc70e":"howManyEthersToChangeSymbolName()","7530b54d":"PRESALE_LEVEL_3()","7530d99d":"addForgivedChar(string)","7530fe1d":"getContractMessages(uint256)","753117ff":"stealTheLeek()","7531e032":"resolveExchangeAddress()","75321c35":"TransferAgentSet(address,bool)","75321c4a":"getOpen(uint256)","75322e47":"change(uint256)","7532b4ac":"percent(uint256)","7532eaac":"signedTransfer(address,address,uint256,uint256,uint256,bytes,address)","7532ef1c":"accRecive()","75335702":"GSDToken()","753384fa":"TOKEN_BONUS_RATE()","7534a714":"checkExpectedTokens(address[],uint256[],uint256)","75355e34":"giveExchangeRateAdvice(uint256)","7535679a":"faucet(address,address)","7535927a":"importAmountForAddress(uint256,address)","7535c930":"priorityCap()","75367ab5":"addToWinners(address,uint256)","75383265":"TON()","753868e3":"lockContract()","753899e9":"alive()","7539189c":"getData_3()","75395a58":"finalizeBlock()","753af202":"SpermToken()","753b0dc1":"createFashion(address,uint16[9])","753b8c02":"EthernautsMarket(uint256)","753c619c":"emitTransferEvents(address,address[],uint256[])","753ca259":"PiXS()","753cb4eb":"fetchVoteNumForCandidate(address)","753cba93":"isPlatinumLevel(address,string)","753d764c":"unlistSubName(bytes32,bytes32)","753d93e4":"changePlatform(address)","753ded15":"failsOf(address)","753e88e5":"upgradeFrom(address,uint256)","753ea1be":"_transferCoins(address,address,address,uint256)","753ed1bd":"ceiling()","753f313f":"setPOOL_edit_26(string)","753f416a":"send1(address)","75401eac":"_isSaleContract()","7540b097":"inflateCount()","75421e93":"buyIcoTokens()","75424253":"BoughtToken(address,uint256)","75426ec8":"tokenFulfillmentDeposit(address[2],uint256,uint256[8],uint8,bytes32[2])","75428615":"getCallData(bytes32)","7542890d":"editIt(uint128,uint64,bytes32[],string,string,string)","75432ec4":"setStorageFee(uint256,address,uint256)","75438e49":"fillGas()","7543af9c":"amount3()","7543e3f0":"setReferral(address,address)","7544ac1f":"CSAToken(uint256,string,string)","75456b49":"fillIndexedBidByAddress(address,uint256)","75457583":"Return(address,address,uint256)","7545c449":"confirmOrderCompletionByPatient(bytes16,bool)","7545f9a1":"processTicketBuying(string,uint256,address)","7546006b":"ContractCall(address,uint256)","754628d0":"cancelTopUpLimit(uint256)","75479c34":"newPlayer()","7547c7a3":"stakeTokens(uint256)","7548014d":"recoverOnlyOnChainFunds()","7548f65b":"END_AMOUNT()","754a347a":"transferViolated(string)","754a77f5":"fcc()","754ad981":"MoveFish(uint256,uint256)","754c175e":"getTip()","754c301d":"sumOfFreezing(address)","754c3957":"benecifiary()","754c67ad":"setTokedoToken(address)","754d71e7":"getCurrentBuyOffer(uint32)","754db89b":"gameExists(bytes32)","754dea40":"setBackendOwner(address)","754e1764":"DiceRoll()","754e1e8e":"invalidateEarlyPurchase(uint256)","754efc98":"throwOnGasRefundFail()","754f579d":"ownerSetGameName(string)","754f9b37":"BasicAccessControl()","754fd352":"addOwnerFromRecovery(address,address,address)","75504b6e":"getAwardCost(uint256)","75524ffd":"mintBase()","75526ed5":"setServiceAccount(address,address,bool)","7553044b":"setUserServerPermission(address,string)","75543074":"getOrganisation(uint256)","75545949":"countMails()","75545cb2":"processMyVestingRules()","75549490":"isEarlyBird(address)","7554fffd":"successFee()","75556e32":"totalMaxBuyin()","7555bfd7":"exchangeAndWithdrawToken(uint256)","7556c9e9":"SilentNotaryToken()","7556e07f":"hasRate()","75570ea7":"closeBets(uint256)","7557b2ae":"Advertisement()","7558d81e":"contractProgress()","7558d9a6":"wallet_Mini_Address()","75593a39":"fixPrice()","755a11dc":"winnersPot()","755a29f4":"set_minCWCsPerSaleMoreThan(uint256)","755a8d31":"getBattleTeamSize()","755b5b75":"setNumUnits(uint256,uint256)","755b9d63":"_addOrder(address,uint64)","755bdcc1":"completeTrade(address)","755c020e":"withdrawALTokenss(address)","755c30a4":"earlyInvestorsBonus()","755cc41e":"mintTimes()","755d43d3":"calculateAmountReceived(uint256)","755d766c":"s27(bytes1)","755d80ab":"MintDarioToken(int256,address,int256,uint256)","755d98a3":"getTotalDividendPool()","755db762":"addVestingAddress(address,uint256)","755dc018":"FANBASEToken()","755e3e28":"tokensAllocated()","755f047b":"projectDescription()","755f12db":"totalTokensSoldInThisSale()","755f99c2":"AddNewSmallContract(address)","755fa815":"getAllIndexesByAddress(address)","755fd25c":"mintEditionCards(address,uint8,uint8)","75608264":"get_hash(uint8,bytes32)","7560a8d9":"_devTokens()","7560cab5":"createListing(bytes5,uint256,uint256)","75619ab5":"setDistributor(address)","7562b0cf":"process(address,uint256)","7563113b":"mintPromoEtherBro(uint16)","7563c81f":"WorldBetToken()","75640ef3":"calculateTotalMinePay(uint256,uint256)","75643e1f":"setReward(uint128)","75659508":"hasPayroll(address,address)","7565a2b6":"transferTokens(address,address,uint256,uint256,uint256)","7565d2eb":"coinfabrikAddress()","7565ef66":"getTodayLotteryNumber()","75661f4c":"calcPlayerICOPhaseKeys(uint256,uint256)","75662b0e":"ChainSign()","75669274":"XXXToken()","75678491":"AMSBToken()","7568353c":"isKilled(uint256,uint8)","7568a9af":"claimNametagToken(address,bytes32)","7568d562":"AssetToken(uint256,string,string,uint8,address)","75698524":"UpdateUSDETHPriceAfter(uint256)","7569b369":"updateUnclaimedDividend()","7569b3d7":"contributorsCount()","756a288e":"getStageTokensSold(uint8)","756a515f":"test_insert_findNoHintUpdateTail()","756abb98":"timeSlicesCount()","756af45f":"withdrawBalance(address)","756afcab":"Mari()","756b1140":"Readings()","756b397a":"GainmersSALE(uint256,uint256)","756bae5c":"finish(bytes32,bytes32)","756bf6e9":"Popcore(uint256,string,uint8,string)","756d5e0d":"EvGroupChanged(address,uint8,uint8)","756dc34a":"PHASE_NUMBER()","756e15e5":"test_spamApproveAndFreeze()","756e8ed3":"innerGuess(uint32,uint16,uint32,address)","756f6049":"CORE_NAMESPACE()","756f7ce8":"fundariaStakesFrozen()","756fb8c9":"getOptionChain()","756feedc":"KingXChainToken()","75700437":"query1_withGasLimit(uint256,string,string,uint256)","757007f6":"CONFIG_MIN_VALUE()","757085e3":"fetchAllVoteResultForCurrent()","7570acd4":"indVesting()","75718e2c":"_increaseTotalDivis(uint256,uint256)","7571ca36":"getTerminated()","75724990":"addShareholder(address,uint256)","7572ead0":"halfyearteam()","7572f341":"subtractWee(uint256,uint256)","757387d0":"nextInListToReturn()","75749f52":"LOCKED_BOARD_BONUS_TOKENS()","757501c5":"districtsCore()","7575594b":"buyShip(uint16)","75759319":"wthdraw(address,uint256)","7575db0a":"invalidateCache(bytes32)","7575ecf6":"validateAndLower(string)","75765249":"saveLottery(uint32,uint256,uint256)","75766294":"teamPeriodAmount()","757765f8":"setMaxBuyLimit(uint256)","75776fa4":"createPromoPony(uint256,address)","7577732e":"createController(address,address[],uint256)","75780127":"testExecuteSellOrderShouldIncreaseBuyerTokens()","75785afc":"createDefaultGen0CobeFriend(uint256,address,uint256,uint256)","757861eb":"start_play_and_gain(string,string)","75790787":"getFeeCollectedByAsset(address)","75792f0d":"_transferToICAPWithReference(bytes32,uint256,string,address)","75794a3c":"nextTokenId()","75796f76":"setWithdrawalWallet(address)","7579f2c9":"ArollaToken()","7579fcb3":"mintPackSaleCard(uint8,address)","757a449e":"approveWithIndex(address,uint256,uint256)","757a5522":"channelPartTimeout(uint64)","757a61b9":"buyAssetPack(address,uint256)","757bd312":"getCrystalWrapper(address,uint256)","757be78e":"PlayersStorage()","757ccd3b":"canCreate()","757d9b97":"getTradeRate(address,address)","757de573":"setOwnerCut(uint256)","757dfdcc":"SafeWalletCoin()","757e5e73":"_giveShares(address,uint256)","757f70fb":"SAMPLEToken()","757f7302":"updateStateChangeAgent(address,bool)","75806e6e":"setIssuerDelegate(address)","75811c15":"ownerChange(uint256,address)","75812019":"getBurningReward(uint256)","7581a8e6":"enableBurning()","7581aa5f":"setActivityState(bool)","7581d62f":"genesisProtocol()","75821d21":"changeTokenWallet(address)","75829def":"transferAdmin(address)","75830463":"checkBetLowhigh(uint8,address,bytes32,bytes32)","758357b8":"fstPrice()","7583902f":"getProviderInfo(address)","7583a523":"maxEarlyPresaleEDUSupply()","75846a5e":"ZoueToken()","75849902":"forwardPurchaseFeesTo()","75854fbd":"b(bool,bool)","75862df4":"TokenWithEStop(address)","75864416":"MeritToken(uint256)","7586cd45":"getPokemonCurrentPrice(uint256)","7586fcc5":"AutoCoin(string,string,uint8,uint256,uint256)","75872a5a":"evolveMonster(uint256,uint16)","75874f3e":"Divineum(uint256,string,uint8,string)","758822e6":"checkForValidity(string)","75885f6a":"approveAndCall(address,uint256,bytes1)","758866f0":"TOSToken()","7588f82b":"currentVestedAmount()","75892cf1":"convert(address,address,uint256,uint256)","75894e8c":"getEntity(address)","758971e8":"ownerTakeProfit(bool)","7589ca40":"BCV()","758b31df":"premiumMod()","758b5172":"setPlayersPerRound(uint256)","758befae":"tokenPresaleCap()","758e08d0":"Authorization(address)","758ed826":"addDAppContract(address)","758f39b8":"verifyProofOfStake(address,bytes32,uint64,uint256,bytes32[],uint256[],uint256,uint256)","758fabcd":"MAX_CONTRIBUTION_SLOTS()","759014f0":"getChallenge()","7591dfa0":"dmlToken()","759234ec":"POLE()","759242fd":"WorldReserveCurrency()","75924b95":"changeWinConfig(uint8[],uint8[])","7592550b":"transferHomeViaRelay(address,uint256,uint256)","759343d4":"sendTo(address,bytes,uint256)","7593473c":"set_brain(address)","7593ca71":"setExchangeInterval(uint256)","75949c13":"sendHalf(address)","7596732f":"MorzeF()","7597eede":"isHoliday(uint256)","7597fd6b":"escape(uint32,int256,uint32)","7599609d":"getEventForHousePlaceBet(uint256)","7599f8d9":"private_setRandomAPIURL(string)","759a2753":"StakeIncreased(string,address,uint256,uint256)","759b2ac4":"removeRole(uint256,address,uint256)","759bca86":"TEMWallet()","759c01dc":"SonDepTrai()","759c676d":"removeAddressToWhitelist(address)","759c7a58":"setAdOwner(uint256,address)","759e6558":"changelp9(address)","759f0914":"createObject(string)","759f8712":"nonActivationShortWithdrawal(address[2],uint256[8],uint8,bytes32[2])","75a0a7a4":"generateNumberWinnerQuery()","75a0ff93":"BTKToken()","75a2b407":"createPromoFighter(uint256,uint8,uint8,uint8,uint8,address)","75a35191":"Travelercoin()","75a374ee":"transferMined(address,uint256)","75a3eac0":"checkExistsOwnedAngel(uint64)","75a4894b":"setReaderId(bytes32,bytes32)","75a4e3a0":"unlock(bytes4)","75a52506":"display(bytes32)","75a53a8f":"changeTrusteeOwner()","75a5425a":"DTesh()","75a55a44":"CR7()","75a5b1ab":"registerDuration()","75a5ba80":"delegateDklSiringAuction(uint256,uint256,bytes,uint256)","75a66774":"stampDocument(bytes32,uint256)","75a6a332":"testThrowRetractNotRetractable()","75a6dbda":"delAdminUsrs(address)","75a73ed3":"createMessage(bytes32)","75a747dc":"_mint(address,uint256,bytes32)","75a75ba9":"TRANSFERS_ALLOWED()","75a806cd":"transferLoss(uint256,address)","75a88bcf":"getPreClaimTimeStamp(address)","75a90144":"voterExists(address)","75a90e02":"readisnameregistered(string)","75a949a3":"transferBlocToUsers()","75a94af5":"JadetToken()","75aa39bd":"getTeamScore(uint256)","75aa8705":"begin(bytes32)","75ab9782":"tokensToSend(address,address,address,uint256,bytes,bytes)","75ac3b08":"presaleEndBlock()","75ace438":"setRdCollectorAddress(address)","75ad319a":"makeLiquid(address)","75ad31a0":"vesting1Withdrawn()","75ad4787":"_processRefund(address,uint256)","75ad97bb":"_initSpaceship()","75ada3d3":"getLicenseReimbursement()","75ae267d":"setCanTransfer(bool)","75ae51ce":"minForceOffsetAmount()","75aecd8d":"ContributionAdded(uint256,address,uint256)","75af370f":"ChainToken()","75af65d1":"discounts()","75b03941":"retrieveGains()","75b0d9cd":"totalSupplyOf(uint256)","75b1e894":"ProposalLog(uint256)","75b238fc":"ADMIN_ROLE()","75b3a83e":"START_ICO_TIMESTAMP()","75b3ea8e":"calculateExcessTokens(uint256,uint256,uint256,uint256)","75b3f9f5":"currentRateLevel()","75b44aea":"getEthRate()","75b466d1":"sendOrderedTokens()","75b4d78c":"bonus()","75b5243d":"editBasePrice(uint256)","75b599c0":"changeFashionAttr(uint256,uint16[4],uint16[4],uint16)","75b5ec08":"DcatNetwork()","75b65abf":"claim(uint16,uint16,uint16,uint16)","75b77c4b":"PRICE_MAX()","75b88b82":"Beebit(bytes32)","75b8fa6f":"contractMoneyBalance()","75b91305":"_removeDeposits(address,uint256)","75b94133":"validatorReward()","75b975b7":"askArbitrator(address,bytes32)","75b99fb1":"HonestisnetworkICObalances()","75b9b357":"updateData(uint256,string,string)","75b9c384":"UpdatePay()","75b9fd47":"BuyAcorns()","75bac6fd":"getLastDeedTimestampByAddress(string)","75bae755":"AariTestToken()","75bba189":"setModerator(address)","75bbc15d":"isNeedDrawGame(uint256)","75bbc204":"addJackpotGuaranteed(uint256)","75bc369a":"_triggerCoolCountDown(uint256)","75bcf09f":"getFibo(uint256)","75bd3237":"listingExists(bytes32)","75be5846":"unlockForever()","75bedf12":"valueOf(uint256,uint256)","75bf4777":"Presale(address,uint256,uint256)","75bfb140":"teamInstantSent()","75c0ae13":"getSalaryTokenAddress(address,address,uint256)","75c14f7d":"buyoutAndSetReferrer(uint256,bool,uint256,uint256,address)","75c268f3":"rateFeesDenominator()","75c26c3f":"closeCrowdfund()","75c3039c":"finalizeCapReached()","75c34d94":"BitcoinElena()","75c48942":"restrictedVault()","75c4a4d6":"isClaimable(int8)","75c4aaa6":"addUnderDog(uint256)","75c4e9ec":"token_reward()","75c589a0":"getMinimumCallCost()","75c5efd8":"teamFundsAddress()","75c66e2f":"mintTokens(uint256,uint256,address)","75c69e39":"SOLUSCRSToken()","75c7d4e1":"sellMyTokensDaddy()","75c81ad0":"minProfit()","75c8a66e":"MANHATTANPROXY7THST()","75c8f04b":"addTenant(address)","75c9c4a4":"SQUIRREL_BASE_REQ()","75c9ee06":"teamFrozenTokens()","75c9f351":"maxTokenNum()","75ca1fad":"setcommissionPer(uint8)","75ca3b2e":"getKittyInfo(uint256)","75cb1bd1":"setWallets(address,address,address)","75cb2672":"configure(address)","75cbe239":"rulesProposals(uint256)","75cc21bd":"LogInvestshare(address,uint256)","75cc499f":"LogTokenPurchase(address,uint256,uint256)","75cc90b3":"ADMINS_COUNT()","75cd109a":"BurnSplit(uint256)","75cd51ed":"accountExists(address)","75ce2913":"pushOwnedToken(address,uint256)","75ce738e":"base_token()","75cf567a":"TOKEN_RATE_15_PERCENT_BONUS()","75cf77fb":"buyPoohs()","75d04628":"updateMatchStartTime(uint8,uint256)","75d049bb":"ApplyDividentsMultiplicator()","75d0c0dc":"contractName()","75d14478":"Chi_available()","75d16a1e":"JaxBox()","75d1722d":"_cancelOrderWithPayer(string,address)","75d2fd7f":"setERC20compatibility(bool)","75d32381":"Gave(uint256,address,address,uint256,uint256)","75d3bda6":"Product()","75d4066d":"getKeccak256(string,string)","75d4115e":"orderSubmitter(bytes32)","75d427e2":"greaterHash(bytes32,bytes32)","75d53a73":"approveMe(address)","75d57f44":"Benable()","75d5a7c6":"torchContractBalance()","75d60ba1":"PayToContract()","75d7036b":"getOuvidoriaEnteTipo(address)","75d7348a":"makeReferalBonus(uint256)","75d74f39":"get_s()","75d79399":"LogNotifyOfArbitrationRequest(bytes32,address)","75d7e4bd":"hydroTokenAddress()","75d7e8ea":"canTransferIfLocked(address,uint256)","75d9085a":"buyCardXname(uint256,string)","75d91db8":"cancelAuctionByMaster(uint256)","75d955f7":"realWorldPlayerMetadataForPlayerTokenId(uint32)","75d96718":"RELEASE()","75d9aa1a":"migrateFromLegacyReputationToken()","75da33bd":"tokpereth()","75dbc1aa":"LiquidHome()","75dc6471":"getSalesCity(uint256)","75dc7d8c":"calcFee(uint256)","75dcb701":"getBonusTierCount()","75dcb70a":"updateEditionTokenURI(uint256,string)","75dd3799":"NetWexCoin()","75dd82b8":"setPreMineAddress(address)","75ddbc4e":"setBalanceOfPendingToken(address,uint256)","75ddfa11":"ChannelBought(string,address,address)","75deadfa":"endTimes()","75df1fe8":"lockReleaseDate1year()","75df9fdb":"backVISTAcoinOwner()","75e01780":"startExchange()","75e0747e":"referrerBonus1()","75e2f405":"product1_luckybuyTracker()","75e2ff65":"setMigrationAgent(address)","75e3661e":"unblacklist(address)","75e372f2":"BlocklancerDataHolder()","75e3921c":"ETH_VTA()","75e39f26":"getHeroInfo(uint256)","75e3e4d4":"_sendTokens(address,address,uint256)","75e42744":"balanceOf(address,bytes32,address)","75e456c3":"validInvestment()","75e5598c":"ACTION_KEY()","75e6f675":"redemptionPercentageOfDistribution()","75e87642":"getRoundBetAmount(uint256,uint256)","75e88e3a":"getForceOffsetBooks(address)","75e8b1a3":"changeWithdrawnTime(uint256)","75e8f289":"depositWalletAddress()","75e8f757":"ERC20PreICO(address)","75e96908":"saveLifeEvent(string,string,string)","75e9c91f":"dropNectar(address[],uint256[])","75e9e3e2":"Ldt()","75ea1b68":"completeDeliverable(bytes32,address,address)","75ec899a":"addBodyParts(uint8[])","75ed5604":"referralLinkRequirement()","75ed8f89":"tOS(address)","75ee549c":"seteUSD(address)","75ee7315":"IcoPaused()","75ee85bd":"salsa20_8(uint256,uint256)","75eeadc3":"hasWon(uint256)","75f0a874":"marketingWallet()","75f12b21":"stopped()","75f208bf":"testFailCreateWithParentNotInUse()","75f289bc":"setDiscountBonus(uint256)","75f2e45d":"charityPayed()","75f33ed6":"EtherReceival(address,uint256)","75f40f40":"underdogPayoutFund()","75f41f4a":"initExchangeUser(uint256)","75f45878":"scheduleCall(bytes,bytes,uint256)","75f46563":"setVLTMultiSig(address)","75f6641f":"GoldBackedToken(address)","75f7cc4a":"PeriodStarted(uint256,uint256,uint256,uint256,uint256,uint256)","75f7d866":"tokenReserved2Deposit()","75f7e6f0":"saneIt()","75f829a9":"BetAccepted(uint256,uint8,address,uint256,uint256)","75f890ab":"setContract(address)","75f91ec8":"getTokenAmount()","75f96ead":"Guess(uint256)","75f9ae86":"setCertificateSigner(address,bool)","75f9e6da":"initialIssueMintingDate()","75fa1bd3":"_reserveTokens(address,uint256)","75fc8e3c":"goodbye()","75fcc6f1":"OWN_burnToken(address,uint256)","75fd4c23":"test_basicUnitTest()","75fd776a":"STRATEGIC_PARTNERS_POOL_ALLOCATION()","75fda973":"tokenDistributeInDividend()","75fe06dd":"claimXmasGift(address)","75fe2cb8":"setDnaExist(uint64,bool)","75fe2e33":"getMonsterObjId(address,uint256)","75ff0664":"ERC223TokenMock(address,uint256)","76005c26":"fulfillData(uint256,bytes32)","76014a2d":"senderETH(address)","760163af":"getLastGames()","76017bbd":"getRewardWei(address)","7603ac4b":"registerFileClosing(string,uint256,string,string)","7603b02d":"houseCommission()","76041376":"devTeamAddress()","76045702":"AcceptsDividendFacial(address)","7604b6d7":"testGetBlobStoreFromFullBlobId()","76052df8":"setPurchasable(bool)","760672df":"weiToTokensAtTime(uint256,uint256)","7606f781":"getMetrics()","7607422a":"CSCS(address)","76098303":"futxMiner()","7609c5a9":"transferFromToICAP(address,string,uint256)","760a221c":"LOCK_RELASE_TIME()","760a45cf":"lockStrategy(address)","760a812c":"ChangedNeighbourReward(uint256)","760a8c2a":"setActive()","760ac21b":"testFailBadTransfer()","760b8f62":"bonusAll()","760bb006":"isUser(bytes32)","760c1fa3":"loadX(uint8[],uint256,uint256,int256)","760cd8e1":"transferAgent()","760cfa57":"GeneratedERC20Contract()","760df4fe":"_isCarousal(uint256)","760e2cf3":"buyUpgradeCard(address,uint256,uint256)","760eab1a":"ZodiacCore()","760ee49c":"setCurrentState(bool)","760f7382":"shipTokens(address,uint256)","76102b3c":"PRICE_PRESALE_WEEK3()","76105fe7":"tarifOf(address)","7611f50d":"periodStage()","7612115d":"setTokenPartner(address)","76124dac":"vote(bytes32,uint256,address)","76124db7":"Update_TrustlessTransaction(uint256)","761390b9":"BCX()","76147a0e":"notification(address,uint256)","7614e727":"baseMineTokenAmount()","761522af":"TradeBits()","76164085":"seek(int256,int256,bool)","76165adf":"buy(address,address,uint256,uint256,uint256)","76167a89":"getMessageSender()","7617f814":"sumPreICO3()","7617fbbd":"PreOrder(address,address,address,address,address,bytes32,uint256,uint256,uint256,uint256,uint256)","76190f8f":"isSiringClockAuction()","76192200":"finishMinting(address)","7619317b":"redemptionWallet()","76196c88":"setDnsrr(bytes32,bytes)","76197591":"finalizedICO()","7619d22e":"LEGAL_EXPENSES_2_TOKENS()","761a832f":"setBaseRewards(uint256,uint256)","761aef78":"BuyTicket()","761b59ac":"crabPartDataFromGene(uint256)","761ba894":"getPremiumMultiplier()","761bb70a":"train3(uint256,uint256)","761c1cf9":"SetupGWT(string,string,uint256,uint256,uint256,address,address,uint256)","761c3688":"remark2()","761c4524":"SHARE_TEAM()","761c7cfe":"resolveChallenge(uint256)","761d9e68":"getUserPolicy(address)","761dc416":"Megaton()","761e0d2d":"DEFAULT_MINING_BIT()","761e64c4":"setPI_edit_31(string)","761fe6fe":"totalAmountsBetStage1(uint256)","76207a5b":"getOrderInfo(bool,uint256,uint256)","7620a65b":"Publisher()","7620f4bb":"fipsNotaryLegacy68b4()","76227f3b":"burnAdminAmount(uint256)","76235b49":"getUUIDS(bytes32)","76247776":"getDirectory()","762506b6":"lrs(uint256)","7625391a":"distribute(uint256,uint256)","762549e0":"minThresholdUnits()","76266ce9":"logResources()","76271346":"_parent(uint8)","76278e7b":"limitDatePresale()","7627c9ad":"grantTransferRight(address)","7627e941":"validateOrder_(address[7],uint256[7],uint8,uint8,uint8,bytes,bytes,bytes,uint8,bytes32,bytes32)","76285b5b":"_is360thDay()","76289f71":"setMasterAddress2(address)","7628e728":"PRE_ICO_TILL()","7629cca0":"ContractDisabled()","762a4f35":"updateClosingTime(uint256)","762a66a2":"getAuction(address,uint256)","762ac19d":"startICOPhaseOne()","762c38fd":"askQuestion(uint256,string,address,uint32,uint32,uint256)","762c7ab2":"setPercentForHelpCoin(uint256)","762ced87":"prcntRate()","762d739a":"vigencia()","762e3816":"TOURNAMENT_WALLET()","762ede1e":"ETHCONEarlyBirdToken()","762fdc0c":"getRatePlan(uint256,uint256)","762ffc42":"VanityReserved(address,string)","76305a89":"CoinCrowdICO(address,uint256,uint256)","763091ff":"initCreator(uint256)","76309e70":"CTT()","7630ad34":"getInfoD(uint256)","76319190":"removeSupportedToken(address)","76323253":"createRounds(uint256)","76324597":"dropStart()","763250e1":"GizerToken()","763265de":"setMaxCap(uint256)","7632b18b":"WICCrowdsale(address,uint256,uint256,uint256,address,address)","76338028":"functionCalls(bytes32)","763430b8":"mFUNDING_SALE_TIMESTAMP()","7634d45d":"titlesSold(address)","7634ecc0":"debitEqually(address[],uint256)","7634ed39":"saveNewAnchor(bytes32)","763542ce":"BucketBuy(bytes32,uint256,address,uint256)","7635761b":"getusersCount()","7635e1de":"changeTokenManager(address)","7635e409":"createZombie(uint8,bytes32,uint16,bool,address)","763730bd":"whitelistAddresses(address[],uint256,bool)","76375c5c":"splitterContract(address,uint256)","763770d2":"getTokensManual(address,address)","7637a12e":"GoldmintMigration(address,address)","7637da03":"MINER_STARTING_PRICE()","76385f2a":"PeriodOfAccount(address,uint256)","76389260":"EthlanceSearchFreelancers(address)","76390144":"getCorrectedStats(uint256)","76399bc6":"getFoundtionAddres()","763a6390":"setWeightLostPartLimit(uint8)","763a666a":"withdrawLiquidityPoolTokens(address,uint256)","763a738c":"allNames()","763ac589":"createStake(address,address,uint256,uint256,bytes)","763add8f":"KPCS(address)","763b144e":"EmpireCrowdsale(uint256,uint256,address,uint256,uint256,uint256)","763cbde0":"_addPassportLogic(string,address)","763cf9aa":"feed100(uint256)","763d2500":"getTotalNbOwners(uint256)","763e29ad":"CherishToken()","763f337e":"setAllowReferral(bool)","763f4011":"mintMarketing(address,uint256)","763fd2ab":"TOTAL_PRESALE_TOKENS()","763ffcec":"setupDisbursement(address,uint256,uint256)","7640304d":"_lastSnapshotId(address)","76405122":"buyImplementation(address,bytes32,uint256,uint8,bytes32,bytes32)","76418809":"private_withdrawBankFunds(address)","7641a8c6":"SetFinalBlock(uint256)","7641e6f3":"burn(uint256,string)","76421887":"OWNER_LOCK_BLOCKS()","7642249c":"mintadd()","76429844":"MultiSendToken()","7642dc0f":"calcVesting(address)","764300bf":"ALLOC_MARKETING()","764358e6":"logSweep(address,address,uint256)","764423a4":"buyerAddressTransfer(uint256,address,address,address)","764499e5":"GamePlayed(bytes32,bytes32)","7644d361":"hashMessage(string,string,string,uint16,string)","7644ecbf":"BallotO(address[],uint256[])","76456887":"startSecondPhase()","76466d42":"setAllowedContract(address,address)","7648c929":"returnRemainingEther()","7648f99b":"ProposalSubmitted(uint256,uint256,address,uint256,uint256,string,address,uint256,uint256)","764912ef":"totalTokenCount()","76495ce7":"tokensFor1EthP4()","76496e34":"earlyCommunitySupply()","764ab11b":"WalletV2(address,address)","764b08c3":"STATS_SIZE()","764c499b":"contract_terminated()","764c6dd3":"voteToFreeze(address)","764c86bd":"totalDistanceRun()","764c8e54":"depositBoth(uint256)","764c92f2":"trustedOrderTransfer(address,address,uint256)","764c98c1":"getIntArrayDynamic()","764c9d32":"sleepContract()","764d1e04":"getFreelancerParams()","764d9969":"XubiToken()","764e50eb":"priceUpdated(uint256,uint256,string)","764e5cd9":"getSkills(address,uint256)","764e971f":"add(uint256,bytes32)","764ea3fe":"walletEhterCrowdsale()","764f3aa8":"getTokenBalances(address)","764fe7d1":"totalMiners()","76520713":"setLock(string,bool)","7652ce3b":"getRoot(uint64,bytes)","7653740f":"addCbAddress(address,bytes1,bytes)","765388ae":"createCrab(uint256,uint256,uint256,uint256,bool)","7653d31c":"_clearQueue()","7653f795":"CarTaxiIco(address,address)","7655e825":"unsafeWriteUint8(uint256,uint8)","765718d7":"register(uint256,bytes)","76577eae":"distributeEarnings()","76586bcb":"doWithdrawal(address,uint256)","76587847":"buyDepots(uint256)","76587921":"transferFromWithNarrative(address,address,uint256,string)","7658c574":"setQuantityFactor(uint256)","7658d5ef":"totalICO()","76596a1a":"hasTeamMember(address)","7659de23":"snapshotBlockHeight()","7659fd71":"BitcoinProtocol()","765aa39e":"startMulti()","765af8bf":"getNumArtworksXType()","765b59d2":"getStatus(uint256,address,address)","765b8dee":"transferStep2(address)","765bfac6":"setEscuela(uint256)","765c9c7f":"bionic()","765dd7a0":"addTeamAddress(address)","765e0159":"getNext(address)","765f09f2":"GetCurrencyInformation(uint256)","7660473a":"EconomyTaxed(string,string,string,string,string)","7661129e":"updatePromoEthCommission(uint256)","76617156":"burnAmountAllowed(address)","7662850d":"init(uint256,uint256,uint256,uint256)","7662c9a7":"GetAskSeries(address)","7663265c":"_setGameSettings()","76636e73":"PREICO_BONUS()","76637dcd":"WhoIsTheContractMaster()","7663f171":"getCardIndexOfOwner(address,address)","7663f228":"testBurnThis()","7663f822":"exists(address,address)","76640648":"payforRefund()","7665f6a7":"setTransferOwnership(bool)","7666ee8f":"addCustomerToRegistry(address)","76671808":"currentEpoch()","766719f0":"optInXferGas()","766954b4":"hashString(string)","7669c0c4":"showPhaseCount()","766a3f2e":"Security_ConnectBankAccountToNewOwnerAddress(uint32,string)","766b0823":"addWhiteBackersByList(address[])","766b1818":"PYCToken()","766bd930":"Duanwu()","766d30aa":"setDefaultRecommAddr(address)","766d5235":"isOpening()","766d8365":"resetRoundStartTime(uint256)","766e33f4":"releaseStart()","766e4f2c":"issueTokensToUser(address,uint256)","766e866c":"setMaxGasRefund(uint256)","766e8b27":"tokensaleTokensPerEtherNow()","76703ef1":"AVIU()","767180d0":"impl_purchase(address,bool,bool)","767392b3":"equal(bool,bool,string)","7673faf0":"wallet4()","76740de0":"isPlayer()","767418b0":"alterBalance(uint256)","76745dbb":"increaseTotalStake(uint256)","76748f2a":"default_price()","7674cee3":"paymentMin()","76753b04":"ledgerUserBetContribution(address)","76775c10":"addReferrer(address,uint256)","76779829":"randomC()","767800de":"addr()","7678369a":"dayfund(address)","7678473d":"BTCDOGE(uint256)","7678f8bb":"getBid(int256)","76793f47":"kwhFund()","7679a816":"handleFund()","767a11ca":"verifiedAttributes(address)","767a99ee":"legalContract()","767b6190":"constructor(uint256)","767b79ed":"register(string,uint8)","767bc136":"cards_titanium_total()","767bcab5":"setRandomizer(address)","767c732e":"enterBidForCollectible(uint256,uint256,int256)","767c9d18":"getMigrateInAttoTokensValue()","767d65ba":"ASEChain()","767eb651":"getRemainingAmount(address,address)","767eb8ad":"isValidName(bytes16)","767f0215":"MAIN_SALE_BONUS_PERCENTAGE_PHASE3()","767f61ac":"putTitle(bytes32,string,bytes32,bytes32,bool,string)","767f7b01":"User(string,address)","767fa723":"getPresaleInfo()","767fb1c4":"RecoverableController(address,address,uint256,uint256)","76809973":"BeneficiaryChanged(address,address)","76809ce3":"decimal()","76814692":"BusToken()","76823637":"startNewTurn()","768255ca":"TokitRegistry(address)","7682e6ff":"getTrustSetting(address)","768356c1":"TUI_ADDRESS()","768433c2":"topFab()","76849376":"addNode(bytes32,address)","768549aa":"KpopItem()","76855764":"enableSudo(bool)","76858faf":"ViralToken()","7685e1df":"NPTToken(address)","7686136a":"updateCourseRate(address,uint256)","76865eea":"unHalt()","7686cea9":"etap()","76884153":"AirTransfer(address[],uint256,address)","76888a3e":"TheTokenF()","76890c58":"transferOut(address,uint256)","76894bd9":"tokensToEthereum(uint256,uint256)","76897b90":"setReserved(uint8,uint8)","768a3326":"myxTest()","768a3a7d":"GetSender()","768afcec":"buyKeys(uint256,string,string)","768b4ce0":"updateWorldScore(uint256,uint256)","768bd5cd":"THULYA()","768c326d":"validatePhaseDates(uint256,uint256)","768c9af4":"Approval(address,address,bytes32,bool)","768e7220":"ownerLockedBalance()","768f930d":"checkSignersByAddress(bytes32,uint256,uint256,uint256)","76907bc7":"setCoinBalance(address,uint256)","7690bee4":"NextGenHyip()","7690ed70":"_changeLockDate(uint256)","7691471c":"PRE_SALE_TOKEN_CAP()","76917b68":"updateMC(uint256)","76918f5d":"setAdPriceMultiple(uint256)","76922f78":"auctusPreSaleAddress()","7692ac94":"createEtherMonster(uint256,uint256,uint256)","7692ba9a":"claimOwnership(string,string,uint256,uint256)","7692c4d8":"testCantFinalizeNotEndedSale()","7693488b":"finalizeTokenSale()","76937a3f":"airDropCustom(address[],uint256[])","7694df16":"scaledRemainder()","76959b6a":"hasSDC(address,address,uint256)","7695be1d":"DaleOR()","7695d79b":"nftTokenCount()","769643bc":"reclaimTokenOwnership()","76965867":"getStakedBalance()","7696c042":"secondsPerMonth()","7696cf52":"bonusFirstWeekPeriod()","7696f0db":"frozenCellCount(address)","769794dd":"TildeCoin()","769796fe":"resetAction(uint256)","76992d7c":"SettingsChanged(uint256,uint256,uint8,uint8,uint8,uint8,bool)","769988b3":"p_update_mEmpireScoreMultiplier(uint256)","76999896":"KingOfTheEtherThrone()","769af180":"EGGS_TO_HATCH_1BAT()","769bf742":"unregisterRecord(bytes32)","769c9226":"setLockAll(bool)","769db61d":"addNewCard(uint256)","769dc523":"GetCategoryNumber(bytes4)","769e86cd":"getMyAccountBalance()","769edf6a":"createHash(uint256,address)","769f194f":"FOUNDERS_TOKENS_VESTED_2()","769ffb7d":"setDirectMintAgent(address)","76a04af5":"CompensateChips(address,uint32[])","76a133ca":"KabirTestToken2()","76a24f25":"originalPrice()","76a25c5c":"calculateReward(uint256,uint256,uint8)","76a310a5":"addAuction(uint32,uint256,uint256,uint8,uint32)","76a327fc":"hitMobster(uint256,uint256)","76a3f9c9":"addToWinningsArray(uint256,address)","76a43abc":"_createPony(uint256,uint256,uint256,uint256,address,uint16)","76a4a44d":"AssignGGEPoolOwner(address)","76a54c60":"sendEth(address)","76a5b431":"removeTip(address,bytes32)","76a5b5b9":"LogTransfer(address,address,uint256,bytes)","76a64cbf":"BasicToken(string,string,uint256,uint256)","76a6676a":"IssuerTransferred(uint256,address)","76a67a51":"pause(address)","76a684de":"denyAllowanceProxyAccess(address)","76a6bf52":"isExecuted(uint256)","76a766f7":"Dashgold()","76a85d54":"setExchangePrice(int256)","76a8bc10":"setExpiry(address,uint256)","76aa2f74":"increaseJackpot()","76aad651":"paymentSupply()","76ab5ea6":"changeDifficultyAndPrice(uint256,uint256)","76aba714":"refundMany(uint256,uint256)","76abc03b":"getShareDistribution(uint256)","76ac2323":"WinkSale(uint256,uint256,uint256,address)","76acb5e8":"BuyTicket(uint256)","76acb968":"TESTTOKEN1()","76ad3abf":"unregisterTraderAccount(address)","76ae684d":"setSaleOngoing(bool)","76aed2e1":"getTokenType(uint256)","76aef5e0":"doubleSend(uint256,address)","76af7837":"Loss(address,uint8,uint256)","76af9a1a":"balancePreSale4()","76b07186":"isPass(address)","76b088a9":"check_lock(address,address)","76b1514f":"getMaxFreeTeams()","76b15836":"changeStatusModerator(address,bool)","76b18618":"changeUnitsOneEthCanBuy(uint256)","76b1f3d3":"grantAccessToAddress(address)","76b3131e":"createvillage()","76b33367":"refundsIssued()","76b34d2f":"changeCrowdsale(bool)","76b39cf9":"activateInTestMode()","76b3c8a8":"getLotteryInfo(uint256)","76b547b8":"AthaYOGAToken(address,address)","76b5d926":"unreserve(uint256)","76b63576":"mintFounderTokens()","76b69d77":"apiRegistryContractAddress()","76b707b7":"getRelease()","76b95761":"setVestingStartDateTime(uint256)","76ba242c":"bonusTokens()","76ba6009":"approveRequest(bytes32)","76babef7":"Puzzled(address,bytes32,bytes32)","76bc21d9":"fireEventLog2Anonym()","76bc522c":"getZIndex(uint16)","76bd28bf":"ORNETCOIN()","76bd4220":"depositBank()","76bd4d2d":"submitProblem(uint256)","76bd5f3c":"changeMintedCappedIdx(address)","76be0b89":"HIROTOKEN()","76be166c":"toAsciiString()","76be6c24":"mintLVE(address,uint256,uint256)","76bef6b4":"getOneByOneRootHash(uint256)","76bf2392":"getCurrentDisplacement()","76bf8044":"pledge(bytes32)","76bf9f57":"wildcardCount()","76bfa5f6":"ProvideSale(address,address)","76bfba56":"depositForDividend(uint256)","76c158cf":"minBankerEther()","76c2c0aa":"oresLeft()","76c2c296":"SYSTEM_CREATION_LIMIT()","76c2f9e7":"HitToken(string,string,uint8,uint256,address,address,address,address)","76c30794":"mint0(address,uint256)","76c390fe":"Display()","76c3b445":"calculateTotalTokenPerContribution(uint256)","76c44a80":"openIEOStarted()","76c46a70":"changeUnitUserBalanceLimit(uint256)","76c6c685":"assertItDoesntThrow(string)","76c6dc8b":"isPosBitOne(uint256,uint256)","76c6fc9a":"checkOwnerShare(address)","76c70431":"CRCToken()","76c75958":"startCrowdsale(uint256,uint256,uint256,address)","76c7a3c7":"MIN_FEE()","76c7b434":"developersCut()","76c7fc55":"removeBorrower(address)","76c82e92":"minAcceptedAmountPresale()","76c87548":"scoreBracket(address)","76ca0225":"initTwo(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","76ca0c77":"scheduleCall(address,bytes,uint256,bytes,uint256)","76ca9e48":"indexPaidBonus()","76cb69e9":"KOIN(uint256,string,uint8,string)","76cb6f9b":"removeOffChainAddress(address,address)","76cba420":"stcOrginalBuy(uint256)","76cc1c5c":"landManagement()","76ccb1fe":"getSpinOutput(uint256,address,uint256)","76cce072":"setBlance(address,address,uint256)","76ccf063":"calSimpleRoom(uint256,uint256,uint256,bytes32)","76cd005d":"distillGodOwner()","76cd470c":"getCurrentAccountingPeriodId()","76cd7cbc":"sign(bytes)","76cd940e":"currentBatch()","76cdb03b":"bank()","76cfc366":"depositOffchain(address,uint256,uint256,bytes)","76d06add":"issueTokensWithCustomBonus(address,uint256,uint256,uint256)","76d0998f":"Odin2(address)","76d173a9":"addressAndBalance(address)","76d1d35e":"numberOwners()","76d260bb":"setInitialVaribles(address,address)","76d2d717":"GetFreeTokens()","76d33951":"bid(string,address)","76d380cb":"IrisTokenPrivatSale()","76d438b0":"sendReward(uint256,uint256)","76d47bf5":"unlockAddress(address,address)","76d57aad":"amountInLock(address,uint256)","76d57ad3":"getMixerInfo(bytes32,uint256)","76d60a91":"TokensMinted(address,uint256,uint8)","76d66f5d":"_Transfer(address,address,bytes32)","76d690bb":"BountyList()","76d6c296":"getPresale1()","76d6da67":"TokenMintingEnabled(address,bool)","76d738d9":"DAZToken()","76d75952":"getLabelType()","76d76b9d":"marketRegisterCost()","76d83cb3":"getTerminalCount()","76d865dd":"addAdminOwners(address,string,string)","76d8f03e":"getBonusCount()","76d92428":"setGatekeeperAddress(address)","76da5667":"admin_kill()","76dad223":"showNumber()","76db2e84":"setMinimumEtherAmount(uint256)","76db6c8d":"isRedeemable(address)","76db76f1":"clearNextPrizeTime()","76db7fd4":"setExchangeFlag(bool)","76db9b14":"CXTCContract()","76dbd108":"calculateProof(string)","76dc4c0a":"isFundRequestToken()","76dc6643":"threeHotHoursCapInWei()","76dc74cb":"sendHoldComisions()","76dc76e7":"getUserNumbersOnToken(address,uint256)","76dc97d9":"_saveMessage(uint256,uint256,address,string)","76dd1f86":"totalMintLimit()","76ddfc39":"MIN_HARD_CAP()","76de03d0":"weiTotalRefunded()","76de1684":"generateOrderByMerchantWithPayee(address,address,uint256,string,string,string)","76dffa4e":"MedCann()","76e00ed7":"_fromNanoNIL(uint256)","76e0f978":"navAdmin()","76e20e53":"getMyBets(uint256)","76e277c1":"ChickenFarm()","76e29114":"nfsPoolCount()","76e2bbc7":"paymentInternal(bytes32,uint256[])","76e403ec":"balancesLocked1Y(address)","76e40c9c":"lendEther()","76e44ed8":"lockAll()","76e4660c":"getSumAmountOfDisputedStepsProPatient()","76e4ca0d":"voteQuorum(uint256,bool)","76e4f921":"parachute()","76e51e96":"TokenModuleManager()","76e53221":"participationCaps(address)","76e55338":"mytest()","76e57d4b":"withdrawalAddressFixed()","76e5c0ca":"WineryOperations()","76e608c7":"buyExistFactory(uint256)","76e6d2b4":"unLock(address)","76e6dbc7":"tokenBaseRate()","76e702ee":"tokenDeliveryDue()","76e71dd8":"delegateTotalSupply()","76e7430e":"finally(address)","76e75e05":"getPurchaseRecord(address)","76e7b151":"GOFCoin(uint256)","76e83bcb":"listModule(uint256,bytes32,bytes32,string,bytes4)","76e92559":"totalMembers()","76e93db5":"totalMaxBuy()","76e9d4fb":"Hybrid(uint256,string,uint8,string)","76ea1c6a":"BuyOnSecondaryMarket(uint32)","76ea430a":"STAGE1_TIME_END()","76ea909d":"indSale()","76eaef99":"CatOffered(uint256,uint256,address)","76eb5ce0":"END_PREICO_TIMESTAMP()","76ec477d":"cancelGame(uint256,string,uint256)","76edb1b5":"ReleaseUpdate(uint256,uint256,uint256,string)","76edc29d":"TelegramOpenNetwork()","76ee2d68":"lokedMint(address,uint256,uint256)","76ee3a87":"mainICOStartTime()","76ef5d14":"divX(uint256)","76f10ad0":"getSnapshot(uint256)","76f14c98":"personalizeSquare(uint256,bytes,string,string)","76f187ab":"tokensTransferredToHold()","76f1dbd4":"Authenticate(address)","76f28a4f":"setMarket1(address)","76f2a59a":"instantMint(address,uint256)","76f30ca1":"toContentID(address,uint256,string,bytes)","76f31513":"decreseApproval(address,uint256)","76f3264b":"getProviderSupply(uint256,uint256)","76f36dec":"ETHC(uint256,string,uint8,string)","76f39b28":"SetMaxAllowedBetInTokens(uint256)","76f4d8ad":"exchangePlayerTokenCount()","76f6218a":"promoBonus()","76f660f6":"batchTransferFrom(address,address[],uint256)","76f6de69":"RTCCOINERC20(uint256,string,string)","76f70900":"oraclesCount()","76f75e7f":"orderList(uint256)","76f7c522":"hasOneStepWithdraw()","76f86e18":"order_buy(address,uint256)","76f88781":"pow2Constant()","76f9378d":"getWords(uint256)","76f95818":"stopFlagOn()","76f9b8d9":"getTokenInfoSignatures()","76f9e018":"greedIsGood(address,uint256)","76f9fd38":"castVote(string,uint16)","76fb7c72":"setAllowedAgentsForOtherSource(address,bool)","76fc53c0":"extDistributeBondFund()","76fd7951":"MacoTestCoin()","76fd7b11":"requestWeiPrice(string)","76fe192a":"forceResetPeriod()","76fe3efa":"itemNameAddress(uint256)","76fe47eb":"returnBooleanInverted(bool)","76fe8228":"getHorseSex(uint256)","76fede7a":"get_term_deposit_end_date(address)","76fee774":"getNewPetCard(uint8)","76fee8e0":"MineBlocksAddr()","76ff1d24":"MailhustleCrowdsale()","76ff87cc":"VYRAL_REWARDS()","76ffb887":"failure()","77002fcf":"getBadge(bytes32)","77009c5c":"EYCryptoTradingGOLD()","7701c52d":"withdrawMarginPreSignedHashing(address,address,uint256,uint256,uint256,uint256)","7701f361":"test_newProposalAndNotEnoughVotes()","7702b8e4":"confirmOneSell()","770342ee":"ChannelClosed(address,uint256)","7704533d":"arbitrationWallet()","77049457":"median()","770506c1":"withdrawMobileAppCoin(address)","7705b6f4":"claimBoard(uint256[81])","7706390b":"handover(uint256,address)","77073437":"alicoinToken()","77076855":"isInOpenMakeOrder(address)","77079f55":"YohoToken()","7707c69a":"set_sale_owner(address,address,bool)","7707e2b2":"withdrawHoldVault(uint256)","770850c8":"accountIndexOf(address)","770864ad":"addOpenMakeOrder(address,address,uint256)","77086d94":"addSpaces(uint256[],uint256[],bytes)","7708b441":"founderWithdrawablePhase2()","7708e321":"setaddress(address,address)","7708e43b":"getNumBets(uint256)","7708ea1d":"ROLE_CEO()","77097bfa":"testerReentrant()","77097fc8":"mint(uint256,string)","7709bc78":"contractExists(address)","7709c0d3":"setMaxWhitelists(uint256)","770ae2af":"setMinAllowedBetInEth(uint256)","770b210e":"canBuyLimit()","770b5414":"getCurrentData()","770b80b6":"returnBalanseToTarget()","770b8aab":"RecoveryModeActivated()","770bb9ae":"_createDrawings(bytes32,bytes32,address,string)","770c59b8":"purchaseParrot(uint256)","770c6bde":"removeItemLendingList(address,uint256)","770c6cbb":"WithDrawPreForkChildDAO()","770cde1b":"ContractExample(string)","770d64c6":"LogLate(address,uint256,uint256)","770d6591":"_setArmorValue8(uint256)","770d8e79":"ADDR_TKG_TEAM()","770e3106":"getAccountsCount()","770e9e85":"takeTheTorch(address)","770eaebe":"Send_Data(address,uint16)","770eb5bb":"set_label(bytes12,bytes32)","770f75b7":"fireCancelProposalEvent(address,uint256)","770f9feb":"clyckterium()","770fe154":"ApplyVote()","77109b05":"depositEther(address[2],uint256[7],uint8,bytes32[2])","7710f29f":"setupPeriodForICO(uint256,uint256)","77115c9d":"seedRoundEndTime()","771282f6":"currentSupply()","77129790":"Crowdsale(address,address,uint256,uint256,uint256)","7712acd2":"getABname(uint256)","7712c870":"slammerTime()","7713b431":"getContactsLength()","7713ba04":"setPI_edit_11(string)","77146255":"_nextTokenId(uint256)","771548e2":"moveAccount(bytes32,bytes32)","771602f7":"add(uint256,uint256)","77169fbd":"gainsOfVault(uint256,address)","7717403b":"ALLOC_CROWDSALE()","7718238f":"addFee(address,uint256)","7718ce93":"player5()","7719f57e":"Seedex420(uint256,string,uint8,string)","771a2af4":"getCitationRecordsLength(string)","771a3a1d":"taxRate()","771acf31":"fluffyCatCut()","771ad078":"BuyGenesis(address,address)","771ad635":"getContentCred(address,uint256)","771c04ae":"ARCToken(address,uint256,uint256)","771c288b":"next_stone_id()","771c3ec7":"setVendingAttachedState(uint256,uint256)","771c7ad1":"hotwalletAddress()","771cbe3d":"_mintCard(uint8,address)","771ce552":"readownerXname(string)","771d7b47":"finishedMigration()","771d9d05":"ecosystemAllocated()","771e4326":"wingsETHRewards()","771eee16":"freezeToken(bool)","771feb74":"getPrecious(uint256)","771ff086":"allocatenonCSTokens(address,uint256)","7720295a":"STARTING_CLAIM_PRICE_WEI()","7720e74c":"changeSaleEnd(uint256,uint256)","77215c8d":"getObserverCount()","772199a1":"getJob(address,uint256)","77226237":"isCompetitionAllowed(address)","77228659":"query2(uint256,string,string,string)","7722d01f":"TokenChanger(address,address)","77231e6c":"tokens_sold()","77233e90":"setTo(address)","7723e2f3":"ArtToken()","77241a5f":"makerDaoContract()","77248e3d":"claimReservedTokens()","7724bdbf":"setStatusInternal(address,uint8)","772506bb":"jackpotFraction()","77253984":"DPToken(uint256,string,string)","7725686f":"thawGlobalTransfers()","7726a59a":"WINNER_COUNTRY_CODE()","7726bed3":"setEnable(bool)","7727c9ad":"changeMinStake(bytes32,uint256)","77282b70":"polymathRegistry()","7728579a":"isIcoFinalized()","77287520":"donate(string,address,string,int256)","77289b50":"setMedium(uint8)","7728c75a":"LoanRepaid(address,address,uint256,string)","7728f48b":"destroyRobot(uint256)","772a3835":"customerExchangeFiat(uint256,address,string)","772b7a73":"getTxOrigMcwTransfer(bytes32)","772bcc79":"DexAgeTest()","772c1863":"increaseStellarBalance(uint256)","772c658b":"getVIPBounusRate(address)","772cb26b":"isStringEq(string,string)","772e6f03":"votingProposal(string,bytes32,uint256)","772fdcb1":"isContributorInLists(address)","77300338":"setActiveTimes(uint256[],uint256[])","773041ce":"setInvestor(address)","77312cdc":"setMultiETH(address[],uint256[])","773183e3":"buyEmptyLocation(uint256)","7731cd2a":"Acc(address)","7732b2a4":"getNextCrystalReward(address)","7732b322":"PinMoCrown()","773355bf":"script(bytes)","77337d37":"tstart()","7733f24f":"ratePreSaleStage()","77343408":"setURL(string)","7734da3c":"NewPassContractor(address,address,address,address)","7734e398":"setFirstBonus(uint256)","773531f3":"tokenOwnerBurner()","77364291":"taskInfo(uint256)","773721b3":"receivedCWCreturn(address,uint256)","77372213":"setName(bytes32,string)","77381082":"Virtonomi()","77390f8b":"_envelopes(string,address)","773984dd":"closeIt()","7739ad70":"markAsScam(address)","773a1154":"generateRandomNumber()","773a8597":"HashTokenAward(uint256,string,string)","773adc70":"getAllowedStepAmount()","773b5b5e":"maxUpdates()","773b82a3":"addPerson(bytes32,bytes32,uint256)","773b90db":"_lotteryCardNoSend(uint256)","773c3f50":"DPPToken()","773c5049":"solvency()","773c84ee":"exec(address,bytes,uint256,uint256)","773d33f5":"transferAndCallback(address,uint256,bytes)","773da57d":"DGZTokensWithdraw(address,uint256)","773dcb98":"startTransfers()","773dfb86":"_extendRound()","773e04a9":"log2Ceiling(int256)","773e1e84":"fight(uint32,uint16)","773e236b":"createLockbox(string,address,uint256,uint256,string,string,string,address[],string)","773e8b0f":"testDAO()","773ee5a3":"execute_transfer()","773eef36":"stopRefund()","773ef1cf":"saleOn()","773ef38e":"PRICE_RATE_SECOND()","773f4873":"Ecopay()","773f5edc":"guess(uint256,string)","773f7665":"processVIPBenefit(address,uint256)","773ff502":"LogMake(bytes32,bytes32,address,address,address,uint128,uint128,uint64)","7740f667":"mtStartTime()","77410c03":"adminLockdown()","774120fa":"merge(address)","77413267":"getAuctionByTokenId(uint256)","774190dd":"showUserPoolAddresses(address)","7741ad4e":"play_game(uint8)","7741b4ec":"RandomNumberFromSeed(uint256)","7741fc52":"LottoCount()","7742ede4":"IMARK()","77439e8b":"doYourThing(address,address)","77446767":"destinationOf(uint256,uint256)","77453df7":"Ex()","7745d3b1":"getUsername(address,address)","7746167f":"transferBlockValueToBattleValue(uint16,uint256)","77463b50":"getEggsToHatchDragon()","77467197":"tokensVested()","774685c7":"CPO_SHARE()","77469275":"getLegacyRepToken()","77472b6f":"minEtherCap()","7747c993":"competition(uint256)","77482b18":"getDeveloperFee()","7748b07e":"usersNTD(address)","7749d667":"getIncreaseTime(uint256)","7749e693":"setCategory(uint256,uint256,bytes32)","774a63a5":"CDSToken()","774a97cf":"getCurrentTapAmount()","774b71d6":"TokenPriceProposalSet(uint256,uint256,uint256)","774bafdf":"unlockMe()","774dba58":"playHome()","774e88dc":"hasUnlockDatePassed()","774eb322":"close(string,bytes32,uint8,bytes32,bytes32)","774f787a":"ShitsToken()","77507425":"buyerFunded(bool,address)","7750b2b1":"__setDeadline(uint256)","775146c3":"request(bytes32,uint256)","77517765":"getTotalActiveStake(uint256)","7752182b":"AddReserveToNetwork(address,bool)","77524af9":"wethTransfer(address,uint256)","775274a1":"requestRefund(bytes32)","77532fa8":"TotalClosedDeposits()","7753ec49":"in_registration_phase()","77542194":"setTokenTransferStatus(bool)","7754305c":"getURI()","7754ec29":"WinCoin()","7755a0f5":"ResolutionProposalSubmitted(uint256,uint256,address,string,string)","7756c908":"transferLocked(address,uint256)","7757fc5d":"withdrawalOpen()","7758bf86":"maxBridgeWidth()","7758c4f8":"quickBuy(uint256)","7758d407":"nextCommonTTWTokenId2()","775915ce":"stepTwoEndTime()","77598626":"TZCoin()","77599026":"calculateYourValue2(uint256)","775a25e3":"getTotal()","775a8f5e":"toBytes(uint256)","775ad527":"allow(address,address)","775af9df":"MiningRigFarmer()","775b9c13":"setWhiteList(address[])","775c300c":"deploy()","775c46cd":"startFunding(uint256,uint256)","775dec49":"keccak()","775e38f7":"NO_MONSTER()","775eb900":"signed(bytes32)","775ee3ef":"view56()","775f5ec0":"finishRitual(address)","775f731c":"addSomeUETsTo(address,uint256)","775fc127":"operation()","77609a41":"challengeCanBeResolved(bytes32)","7760da7f":"reclaimTokens(uint256)","77610ba2":"setDollar(uint256)","77617a7d":"BuyToyMoney()","776184b1":"test_oneValidEqString()","77620729":"forward(address,address,uint256,bytes,bytes32,bytes)","776247c4":"withdrawEthFromBalance()","77627a1d":"Goutex(uint256,string,uint8,string)","7762df18":"VVDB(address)","7762df25":"potentialOwner()","7762f046":"setContractBridgeAddress(address)","77640f9c":"setClaim(address,bytes32,bytes)","7764d878":"checkstatus()","7764f771":"getBackBNB()","776532de":"Numa()","7765c52c":"getAuctionStatus(uint256)","776676d6":"newRC(uint256,uint256)","77669b2d":"setCompte_33(string)","7767ecc3":"inSdcForAdmin(address,address,uint256,uint256)","7768dec0":"isTokenSale()","77695d39":"getDb(uint256)","77699a06":"reclaimExpiredSwap(bytes32,bytes32)","7769d384":"revokeAndPublish(address,bytes32,bytes32,address)","7769ea0a":"addPool(uint256)","776a038e":"PurchaseToken()","776ab634":"unpauseToken(uint256)","776b37e2":"editCertificate(string,address)","776b6b27":"setRoscaAddress(address)","776bf795":"pieceTransfered(uint256,address,address)","776c3b70":"setNewSalesManager(address)","776d1a01":"setTarget(address)","776d62f6":"costs()","776d89ba":"delPhase(uint256)","776dba67":"VioRewardERC20Token()","776df027":"testFailDisownNotOwner()","776e7fc1":"checkRedbullQuest(address)","776f3b99":"burnByPercentage(uint8,uint8)","776f9663":"PeerBet()","776fd7ce":"setEscrowTransfer(address,uint256,uint256,bool)","77703d29":"getBuyOrder(uint80)","7770bd15":"crowdSale()","777256c4":"Greeter()","77725b88":"SetFFSettings(address,address,uint256,uint256)","7772a380":"isInGeneration(address,uint256)","7772ba07":"setDelays(uint256,uint256)","77738ce7":"fundAccount(address,uint256,uint256)","7774c394":"isNecromancer(uint256)","7774d64c":"testCreateOrder()","7774e950":"createUnit(uint256)","7775eec9":"getCompte_29()","7776466c":"preSaleToken()","777665b8":"transferTOKENtoProviders(address,address,uint256,address,uint256)","77773d90":"amountOfTokensPerEther()","7777789f":"_mint(address,uint256,uint256[])","7777d088":"lotteryTokensPercent()","777850f9":"payAfter(address,uint256)","77790081":"updateMaritalStatus(string)","777955b1":"updateReferralGu(uint256)","7779b0e4":"_buyTokens(uint256,uint8,address,address)","777a5dc5":"explodePhoenix(uint256)","777ab367":"mk_contract_address(address,uint256)","777ac349":"totalWins()","777ac522":"_createTree(string,string,uint256)","777aff7d":"updateHistory(address,uint256)","777b4547":"ICO(address,address,address)","777c1bb2":"eosLITE(uint256,uint256)","777c658f":"getTotalDonations()","777dff4a":"transferCTO(address)","777e479d":"getRoundBlockNumber(uint256)","777e6b1c":"getEntitledFunds()","777e82ca":"BookERC20EthV1p1()","777e940c":"excessRefund(address,uint256)","777ecb74":"LogPaused()","777eceb8":"tokensForOneEther()","777f942d":"changeMinStake(address,bytes32,uint256)","777feff5":"getCertificationDbAtIndex(uint256)","7780ae85":"desimls()","77810380":"getRegistrationToken()","77818808":"Electrium()","7781eafa":"considerPerseus(uint256)","77826b0c":"setMaxReceiveEther(uint256)","778317c4":"setWinLossAmount(uint256,uint256)","77838c63":"distributedToOwner(uint256)","7783c06b":"newArt(string,string)","7785859f":"altCapitalization()","7785954b":"produceRandom(uint256)","778639cb":"checkValidFighter(address,address)","77863b61":"CrossWhitehatWithdraw(uint256,address)","7786b22d":"ELRUN()","77870bce":"BeatOrgTokenPostSale(address)","7787dfaf":"test_9a_transferShouldBeFalse()","77886028":"setTokensContractAddress(address,address)","7788d126":"REFERRAL_BONUS_LEVEL3()","77895ef4":"listedMonForClass(uint64)","7789f844":"backTokenOwner()","7789fc90":"createBet(bytes32,bytes32,uint256,uint8,uint16,uint16,uint16,uint8,uint256,uint8)","778a56ce":"toggleBurn()","778a5978":"guessNumber(uint16)","778b5aee":"getWalletsCount()","778c2cea":"onlyLocklistedCanDo()","778d00f0":"pushPrivateInvestment(uint256,uint256,address)","778d491e":"wd(uint256)","778e388e":"parseInt_(uint256)","7790a5d2":"Token_5()","77913fbc":"getModuleId(string)","7791dc1f":"AuthEnd()","77921952":"contributorCounter()","77922220":"getRegionProducts(address,uint256,uint256,uint256,uint256,uint256,bool)","77922e57":"batchCancel(address[],uint256[],uint256)","7793868c":"RostToken()","779454ff":"boardAddress()","77952161":"didDepositCollateral(bytes32,address,uint256)","7795820c":"getCommitment(bytes32)","7796fb95":"setSink(address)","7798e525":"countUBetChecks()","779972da":"setLockPeriod(uint256)","779997c3":"bump(bytes32)","779a3611":"makeBet(uint256,uint256,uint256)","779a5a7f":"getContributorByAddress(address)","779ad324":"getIEOId()","779b2e11":"getCurLevelKeyNum()","779b8dc0":"load(bool,address,address,address,address,address)","779beca0":"getNumOfSalesWithSameId(bytes)","779beedf":"registerWallet(address)","779c4a26":"getUserSponsorships(address)","779c9b19":"_emitCategorySet(uint256,uint256,bytes32)","779ce152":"WIN_PERCENT_PER_DISTANCE()","779d2e20":"setLawSupportProfitAddress(address)","779de55d":"paymentsByBenefactor()","779dec5b":"bZRxTokenContract()","779e170d":"isSaleOn()","779e5ad8":"gvOptionToken20()","77a0e875":"destTokensSit()","77a1ec4b":"hodlCountdown()","77a28225":"delegateFromReferral(uint88)","77a28461":"ownerSetupBankrollInterface(address)","77a28fec":"DealCancelRate(uint256)","77a3a0a2":"removeMarketFrom()","77a43129":"publicSellLockEndTime()","77a54b38":"checkForNewStellar(address,uint256)","77a54eb8":"blacklistAddresses(address[])","77a6acfb":"tokenDemo(uint256,string,string,address)","77a6cb64":"TokenEscrow()","77a714ae":"ERC721Token()","77a7354d":"addExperience(string)","77a74a20":"expressingTraits(uint256)","77a7d968":"walletBalances(address,address[])","77a7e6be":"getRefTotal(uint256)","77a8bc86":"untrustedExecuteRuling(uint256)","77a9037b":"updateLastVotedOnParameter(bytes32,address)","77a9e152":"redeemToken(uint256,uint32)","77aaafd2":"interfaceFrozenTransfer(address,address,uint256)","77aad873":"proposeLaborHourToken(address)","77ac3da5":"oraclize_query(uint256,string,string[1],uint256)","77acbb22":"manager2()","77ad619d":"get_commit_no()","77ae6c47":"requestBatchInsatalmentsLoans(uint256,uint128,uint256,uint24,uint40)","77afd7e6":"shitRate()","77b02a33":"getGameLock(address)","77b08df0":"Migrations4()","77b0c751":"getNextPayDay()","77b11de3":"setPlayerHasGetFree(address,address,bool)","77b1788e":"postTrade(bytes32,uint256)","77b19cd5":"getCallBaseGasPrice(bytes32)","77b1b2eb":"MAX_CANVAS_COUNT()","77b1bba6":"ChangeCollector(address)","77b1da93":"crowdSaleClosed()","77b2d590":"_set3()","77b38e2a":"MasternodeDeregistered(address,uint256)","77b440e9":"WALLET_FOUNDATION()","77b4a9c1":"getMakerBalance(address)","77b57073":"sponsorList(address)","77b68dae":"devDivRate()","77b71df0":"stake(int256)","77b74692":"setKYCAddress()","77b76ec3":"checkBalance(address,address)","77b77a4f":"PlatoPresale()","77b7b5f3":"returnCreator(uint256)","77b92c07":"Approve(uint256)","77bad015":"GetMyEgg()","77bb09eb":"addSweeper(address,address)","77bb5e34":"ChillCoin()","77bbc957":"returnReclaimed(uint256,address)","77bbf28a":"createDividend(uint256,uint256,address,uint256)","77bc222c":"_eraseSingleNode(bytes32)","77bc57e7":"Agencies()","77bd1bfe":"ITT(uint256,uint8,string,string)","77bd35fc":"claimPremium(address,uint256)","77bd775c":"setMinPurchaseAmt(uint256)","77bdab19":"OtoniToken()","77bdbccc":"registerCertificate(address)","77bde142":"setTargetBondingRate(uint256)","77bdfcfa":"cards_metal_check(address)","77bf8b91":"CelebSold(uint256,uint256,uint256,string,address,address)","77bf8e6f":"myShare()","77bf96d4":"claimProfitEquivalent()","77bf9776":"stopUpdate()","77bffc9a":"getRemainingStars(address)","77c07c19":"storageControllerAddress()","77c0891f":"setVotingParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","77c13323":"closing_requests(bytes32)","77c2f72e":"LightenToken()","77c2fb9b":"updateMokenName(uint256,string)","77c34ee7":"tokensRemainingIco()","77c427b7":"TemperatureMeasurementB(address,int8,int8)","77c4fd07":"availableEarlyPlayerShares()","77c626e3":"getStageAvailableTokens(uint256)","77c68aa7":"IGTMYR()","77c71396":"charityBeneficiary()","77c76449":"AVAILABLE_IN_MAIN()","77c78df9":"getCurrentLevel()","77c82476":"viewPetition(uint256)","77c846af":"changeUsername(string)","77c8d5a0":"computeTimeBonus()","77c90dd4":"VaporCoin()","77c93662":"sponsor()","77c9dd4b":"iOwner()","77ca4d11":"loadVotesForParticipant(bytes32,bytes32,uint8)","77caa61a":"updateExchangeRates()","77caa7e6":"endICOp2()","77caf711":"transferValue(uint256)","77cb6b7f":"AbccCoinToken()","77cb8edd":"_robot()","77cc437c":"institutionWallet()","77cdd2e5":"icoBtc()","77ce4fd1":"changeBlocksToExpire(uint256)","77ce52f8":"totalInfo()","77ce9bdd":"createPersonalDepositAddress(bytes32)","77cebd89":"isAllowedToBuy(bytes32)","77ceded8":"mintGrey(int256,address,uint256)","77cf0369":"totalPreICOavailibleWithBonus()","77cfe1c1":"isValid(string,address,uint256)","77cff22d":"init(address,address,uint256,uint256)","77d1f95d":"AntCoin()","77d223b2":"setLowestClaim(uint256,uint256)","77d2f203":"neg(uint256)","77d317d0":"destroy(uint256,string)","77d32e94":"ecrecovery(bytes32,bytes)","77d3550b":"commissionPercent()","77d447d6":"ContractorManagerSet(address)","77d4c48b":"arr(address)","77d4e5bc":"secondTimeLine()","77d555b7":"RateSetterChanged(address,address)","77d55755":"getMiningReward(bytes32)","77d56a04":"getReserveBalances()","77d58f21":"_safeContract(address,address,address,uint256,bytes)","77d630ae":"activationFee()","77d6a880":"saleOrNot()","77d6cfeb":"setGoalReached()","77d70b1f":"jackpots()","77d79d10":"getGame(uint8)","77d821a2":"testOnlyMultisigCanDeployANT()","77d83b81":"confirmGetFreeQuest(address)","77d89406":"bankerFeeDataRecord(address,uint256,uint256)","77d8ffc0":"getTokensFromBuy(address)","77d99ef5":"createBattleboard(uint256,uint8)","77d9d1fb":"maxHEXCap()","77da0add":"seeAsset(uint256)","77dac983":"abandonEscrowService(uint256)","77daeb80":"addDeal(address,address,address,uint256,uint256,uint256,uint256,string,uint256,uint256,bool)","77db5206":"checkStatus(address,uint256)","77dbbd76":"transferFrom(address,uint256,uint256)","77dc0413":"small_payout(uint256)","77dc657c":"checkPassword(bytes)","77dc6ac7":"tokensSelling()","77dcb4f9":"doPresaleMinting(address,uint256)","77dcba6d":"writeConversion(string,address,uint256,uint256)","77dd3323":"setts50(uint256,address)","77dd8ea7":"ethFnkRate1()","77df3013":"calculatePurchaseAndBonuses(address,uint256)","77dfec3c":"exchangeRateTimestamp()","77e13c10":"playerMakeBet(uint256,uint256,bytes32,uint8,bytes32,bytes32)","77e17039":"startSettlement()","77e17191":"COIN_SUPPLY_MARKETING_TOTAL()","77e19824":"numSubmissions()","77e26762":"getErbutongHao(uint256)","77e2965b":"updateTokenAge(address,address)","77e2a6ed":"openGiveAway()","77e2e5ce":"ICO_setParameters(address,uint256,uint256,uint256,uint256,address,uint256)","77e303d2":"_Deposit(bytes32,uint256,uint256)","77e49660":"addAddressAliasUnsafe(address,address)","77e4fb04":"testFailNotEnoughValue()","77e5bf84":"getTxGasprice()","77e5d8f8":"advisersUnvested()","77e5f6d0":"setGizerItemsContract(address)","77e60f42":"marginForMajority()","77e6bb15":"getCurrentBonusPercent()","77e71ee5":"getForkEndTime()","77e75b07":"mintAndAllocateZCO(address,uint256)","77e7645b":"CoinSaleActive()","77e7ff41":"kickTheCoin()","77e8a52e":"SEARCH()","77e91f26":"getAyantDroitEconomique_Compte_10()","77ea8c72":"RGLSToken()","77eaa420":"_clearAuthorization(address,address)","77eab3e3":"changeMinimumAmount(uint256)","77eb4c50":"hasSponsor(uint32)","77eb74a1":"PassportInterfaceID()","77ec0feb":"dividendPerToken()","77ee311c":"totalMember()","77eefa5a":"pullBack(address,address,uint256)","77ef2c91":"whitePaperHash()","77ef9581":"Registry(address)","77f051c3":"AcceptsToken3D(address)","77f122bd":"setBlockValueBalance(uint256)","77f172b6":"_wager(uint256)","77f18090":"Citizen()","77f18ed3":"isImmortal()","77f25566":"setOne(uint256)","77f27251":"paybackDelta()","77f2d0b0":"partnerInfo_for_Owner(address)","77f325df":"submitAnswer(bytes32,bytes32,uint256)","77f3293a":"endPreICO()","77f37cd1":"luckyBonus(uint256)","77f38024":"BountyPart()","77f3c0cd":"InvokeTransfer(address,uint256[],uint256)","77f3e3d1":"Bounty_Supply()","77f3f782":"UserBalances(address)","77f41164":"stageTwoClosed()","77f46346":"CheckIfIsAllowed(address)","77f48f94":"spin(bytes32)","77f50f97":"claimAdmin()","77f51246":"tokenIsLocked()","77f54a82":"setICOParams(uint256,uint32,uint32,uint256,uint256,bool)","77f6f7e8":"YoloToken()","77f74b6b":"getTimestamp(uint16,uint8,uint8,uint8,uint8,uint8)","77f83bce":"PruebaCoin()","77f8afc3":"FixSale(uint256)","77f929fb":"DeveloperCoin()","77f98616":"getTotalProduct()","77f9bc13":"getVendorApplicationStatusTrack(string,uint256)","77f9c101":"testDeployNewTokenWithTheTestContractAsOwner()","77f9c862":"GetSellOrderDetails(address)","77f9db33":"disableTokenTransfers()","77fa3d32":"addAuction(uint32,uint256,uint256,uint8,uint8)","77fa4c21":"getRewardPot()","77faba66":"setRewardPercentageK(uint256)","77faffa0":"nextround()","77fb6269":"migrateData(address,uint256,uint8)","77fbe611":"forTeamETH()","77fc35e5":"_burn(string)","77fcb91d":"forward(address,bool)","77fcbebe":"TokenLimitReached(uint256,uint256)","77fcc493":"TOKEN_MIN_PRICE_THRESHOLD()","77fcce68":"setSignatureValidatorApproval(address,bool)","77fd347a":"makePredictions(int16,string)","77fe2a0d":"unfrozePerDay()","77fe38a4":"transferToICAPWithReference(bytes32,uint256,string)","77fed1c7":"addOverview(uint256,string,string)","77ff24f4":"test0()","77ffd2e8":"setCurrencyExchangeRate(uint256,uint256,uint8)","780004ac":"systemFreeze(uint256,uint256)","7800313f":"getCurrentTokensByType(uint32)","7800a9f6":"getP3DInfo()","78013292":"optionAddress()","78018581":"Allysian()","7801fc3e":"totalReceivedEth()","780211a2":"refundOrder(address,address,address,bytes32,address,address)","78021e7c":"ownersOfToken(uint256)","780249cd":"DC()","7802857a":"BONUS_TIER_8_LIMIT()","7802cbaf":"addTokenOwnerReward(uint256)","7802f4e4":"nada(uint256)","78030b83":"makeWildCardToken(uint256)","78044965":"setACLRole8972381298910001230(address)","78044ba5":"transferToBuyer(address,uint256,address)","7804a5dc":"canCreate(address)","7805862f":"Unpause()","7805a548":"_createItem(uint256,uint256,uint256,uint256,address)","7805dd1c":"_totalUsersBets()","7807e826":"calculateWeiNeeded(address,uint256)","78080c9d":"rateStage1()","7808dc69":"createSale(uint256,uint256,address,address,address)","780900dc":"create(uint256)","7809231c":"DistributeAirdrop(address,uint256)","7809dd64":"_receiveRefund()","780a4d74":"RecipientUpdated(address,address,address)","780aa037":"receiveTokenFromContract(uint256)","780ae915":"completeMigration(address,uint256)","780aee73":"newGame(string,bytes32)","780bbe60":"createChamp(address)","780be5be":"AggiungiNegoziante(address)","780bfed0":"addPermission(bytes4,string,string,string)","780c4a73":"addCounter(address,uint32)","780c5316":"payMinAuctionEther()","780c5689":"writes(bytes32,address)","780cbf65":"_queryCallback(uint256,bytes)","780d2328":"recordVisit(address,string)","780e4b96":"setConsolationRewardsClaimPercent(uint256)","780f4987":"systemMessage(string)","780ff8d1":"viewLatestErc20TransactionRequest()","78108368":"atxRate()","78121b60":"KeyedCollection()","781224f4":"setVendorWallet(address)","78122f3a":"fail(string)","78127ee7":"GOLDBARToken()","781327de":"createStrategy(string,string,string,address[],uint256[],bytes32)","78152bbe":"setPresaleStart(uint256)","78155bf4":"PaymentCompleted(address,uint256,uint256)","78160d6b":"numChipsClaimed()","78166097":"isValidCustomer(address)","7817364d":"ChillTalk()","7817a60f":"acceptMember(address,string)","7817abee":"getOwnerRatingTuple()","7817eedd":"rawOwnerOf(bytes32)","78186f51":"etherPriceInDollarOut()","7819d30d":"updateNameResolver(string,address)","781a2cca":"Pay(uint256)","781a4a74":"getTokensIcoSold()","781c0db4":"finishFreeGet()","781c4dad":"tierNo()","781cc3d3":"cancelAction(bytes32)","781cd99d":"START_TIMESTAMP()","781db835":"_buyTokens(address,uint256)","781e48e4":"MYCareCoin()","781e9892":"cumulativeRatios()","781f5a83":"registerIdentity(address,address)","782037dc":"reserveTeamRecipient()","78205f67":"testThrowTransferEnableNotTransferable()","7820cd94":"flexibleRewardLevel(uint256)","7821a514":"addReserves(uint256)","7822b902":"setSaleAmountCap(uint256)","7822ed49":"bankAddress()","78231978":"totalSaleSupply()","782378d1":"MIC(uint256,string,uint8,string)","78238cf0":"setCmd_control(uint256)","7824407f":"tokenSupply()","78248880":"decreasePaymentsBalance(address,address,uint256)","7825396b":"setPrices(uint16[])","78258c41":"ZXToken()","78261878":"saleCompleted()","78263edf":"changeMaturity(uint256)","7826bbc3":"fstPrivateSalePortionDenominator()","7826bfa8":"ethereumLottery()","7826f28f":"S1()","7827b226":"froze_contract()","782841cd":"changeMintingState()","78296854":"origMktValue()","782a0170":"etherPriceInUSD()","782a2737":"vestingMap(address)","782addbd":"isInvulnerableByArea(uint256)","782b2340":"getStartIcoTimestamp()","782b3602":"taker()","782b9d50":"setCitizenAddress(address,address)","782c6ef8":"refundSender(address,uint256,uint256)","782c9689":"DeliverToClaimers(address[],uint256[])","782ce79c":"burnClosedToken(bytes32)","782da1ea":"transferFromInternal(address,address,uint256,bytes)","782e1e6c":"tokenTarget()","782e34c9":"ownerSafeWithdrawal()","782ec023":"transferMultiAddressFrom(address,address[],uint256[])","782f08ae":"setUri(uint256,string)","782fb5d4":"getVoteCounts(bytes32)","783110dc":"increaseStep()","78312435":"updateIssuer(address)","78321efb":"pushElement(uint256)","78329d61":"processPurchase(address,address,uint256,uint256)","7832bbf7":"temporaryEscapeHatch(address,uint256,bytes)","78330101":"ESlotsICOTokenDeployed(address)","783370b5":"setEditionLimits(uint256,uint8,uint8,uint8)","7834a504":"buyCoin(address)","78351502":"hasPastFreezTime()","78357e53":"Manager()","78367e46":"enterSmall()","783680a7":"ico2Min()","78375f14":"requireisfine(uint256)","78375f61":"BetTest111()","7837848c":"expire(bool)","7837e170":"lockBalance(address,uint256)","7838415b":"MeetOneToken()","783870eb":"rubusBlackAddress()","78388eb6":"allocationsOverTime(uint256)","78393237":"MAT_PARTNERS_SUPPLY_LIMIT()","783a2cca":"approveWithdrawal(address,uint256,bytes32,bytes32,uint256)","783ac3ee":"offThreshold()","783b4569":"rawRegister(bytes32)","783b7b1e":"sendJackpot(address)","783c2088":"lookupRegName(address)","783c8db0":"minimumFundingAmount()","783cc9dc":"CNNToken()","783ce458":"expmod(uint256,uint256,uint256)","783d5dec":"_limitTeamWithdraw(uint256,uint256,uint256,uint256,uint256)","783ddace":"mintAdvisersTokens(address,uint256)","783e7a06":"removeVerificatorAddress(address)","783f28e6":"adminUpdMinSign(uint256,uint256)","783f6af5":"people()","783f7b98":"setEtherQuota(uint256)","78405234":"indexOf(uint8[],uint8,bool)","7840c781":"_setTokenOwner(uint256,address)","78415956":"after_test_2_method()","7841a530":"set_tokens_sold(uint256)","7841b780":"isPaymentSettled(uint256)","78420d4a":"validateLock()","784279d8":"setSupportedTokens(address,bool)","7842a3a4":"payReward()","7842aded":"getLotteryMoney()","7842dca8":"allTime()","7843184b":"setMultiBonusTokens(address[],uint256[],uint256)","78446bc1":"timeLockPeriod()","7844ce81":"hodling()","78451d64":"SplitPayment(address[],uint256[])","78452d65":"CATContract(address,string)","784547a7":"isConfirmed(uint256)","7845b86e":"fundingRatePredictionBonusClaimWindow()","7845cbef":"GOLDT()","7845d5aa":"UpgradeAgentSet(address)","7845d76b":"tune(uint256,uint256,uint256,uint256)","7846188d":"_getCrabTotalStats(uint256)","7846c3c8":"minimumContributionPresalePhase2()","784712f2":"pendingPayouts(address)","78473485":"getSellDemand(uint256)","7847352a":"setBettingCondition(uint256,uint256)","7848033e":"distributeCHENDE(address[])","784813e0":"lookupBet(uint256,uint256)","78483632":"secondsaleOpen()","78489ed6":"compareIntValue(bytes32,int256,bytes1)","78498818":"getTokensBought()","784a3e40":"bountiesIssued()","784aa7d2":"setTitulaire_Compte_5(uint256)","784ba0f5":"yearteam_trade_date()","784d17f9":"DarkrenlandToken()","784f47ff":"reduceCredits(string,uint256,uint8,address)","784f6654":"activateMe(string)","784fcb94":"MARXToken()","784fdf26":"totalExternalSales()","7850a6b2":"transferDoftManagment(address)","7850b72f":"LSDCrowdsale()","7850c2ac":"holdersAllocatedAmount()","7850f0a4":"setPromotedGame(uint256,bool,string)","785105f6":"savedBalance()","7851bcbd":"safePerc(uint256,uint256)","78524b2e":"halveMinQuorum()","785250da":"kyberNetworkProxyContract()","78533046":"getMetaInfo(uint256)","78533e90":"setTokenMinter(address)","78537808":"union(address[],address[])","7853c945":"bitcoinKey()","7854216b":"autoAirdropAmount()","78547d5f":"processPurchase(address,uint256)","7854b798":"addauction(uint256,uint256,uint256,uint256,uint256,string,string)","78566845":"allocateTicket(uint256,address,string)","78572816":"addAffiliate(address,bytes32)","78579d7c":"addEntry(address,uint256,bool,uint256,uint256)","7857f6e7":"setReverseRate(address[],int16)","7857fcda":"assertEq3(bytes3,bytes3)","78581a46":"getBatchCreateDrawingsAddress()","785826a7":"sendReferrer(uint256)","78583275":"updateMinSale(uint256)","7858651e":"getConnection(address,address,bytes32)","7858eb7b":"setScore(string)","7858f93a":"addressFundTeam()","78591e1d":"findAllCliWithPendingTask()","7859f9e6":"purchaseCarAdv(uint256,string,string)","785b1eb4":"PayEIF()","785b804a":"transferEtherInitiation(address,uint256)","785bc758":"setBaseStorage(bytes4,uint256,string)","785cc997":"mint(uint256,string,bytes)","785ce7ca":"walletBlockOf(address)","785da817":"unterminateFunding()","785e9e86":"erc20()","785fa627":"prizeAmount()","785fb499":"burnFoundersTokens(uint256,uint256)","78607c33":"FundWithdrawed(uint256)","7860ed56":"secondItemWrong()","78629c0f":"lockAddressToken(address)","7862affa":"calculateTimeBonus(uint256)","78635049":"MarzCoin()","786420d1":"getEstate(uint256)","786431c1":"MAX_OPS()","78644a4a":"userOfferAcceptElement(uint256,uint256,uint256)","7865f463":"mmul(uint128,uint128)","7865f611":"LogBet(address,bool,uint256,uint256,bool)","7866ed6e":"getBloodline(uint256)","78670289":"MAX_END_BLOCK_NUMBER()","7867060d":"approveComponent(string)","78683654":"convertMainchainGPX(string,string)","7868c89d":"getRateByStage(uint256)","78698e45":"_updatePrices(uint256,uint256,uint16,uint256[],uint256[])","786ab4b6":"addAccountWithBalance(uint16)","786b844b":"closeGame()","786bfd76":"SimpleConstructorString(string,string)","786c5065":"closeDistribution()","786caff8":"claimerOfSocialIdentity(uint256,uint256)","786cf3ee":"DurioTEST()","786d02d0":"getHoldingsCount()","786d8a25":"test_falseEqNoLog()","786e06f3":"sendETHtoBoard(uint256)","786e4799":"removeRatePlan(uint256,uint256)","786ecf16":"doRestart()","786edae0":"registerEndpoint(string,int256)","786ef70a":"earnedEthWei()","786fb317":"requestOutput(bytes4)","787089bd":"PandoraToken(uint256,string,string)","787091e9":"EABToken(string,string)","7870f889":"MyWhiteList()","78710d37":"seven()","78710f72":"canBuyTokens()","787112be":"set_saleAgent(address)","78719ee8":"DAppNodePackageDirectory(address,address)","7871a9ff":"Crypterium()","78720063":"EligmaSupplyContract(address,address)","7872e3da":"disbursementDuration()","78730d65":"nextLotteryTTMTokenId9()","7873447b":"getFrozenAccountList()","7873832e":"SingularDTVLaunch(address,address,address,uint256,uint256,uint256,uint256,uint256)","787394fc":"setJackpotIncrement(uint256)","7873bc61":"contestant(uint256)","78744754":"getClassName(uint32)","7874b66f":"ReferralActivated(address)","7874d32c":"unblockTokenTime()","78753818":"MAIN_SALE_VALUE_CAP()","7875bbe2":"DividendPaid(address,uint256,uint256,uint256)","7875d41b":"takeBet(uint256,uint8)","78761590":"findTargetCell(uint256,uint256)","7877f72d":"getHours(uint256)","78782027":"enter(string,address)","7878903c":"hasPreSaleEnded()","7878b66a":"isPauseSave()","7879e19e":"CollectAllFees()","787a08a6":"cooldown()","787addc3":"FideliumToken(uint256,string,string)","787b586f":"setMediumProbability(uint8)","787b6725":"removeProduct(address)","787bd6f9":"setDistribution(uint256[5])","787c17d9":"privateSell1Token()","787c23e0":"whitelistWallet(address)","787ccb61":"replenishPool(uint256)","787d024d":"mintLzToken(address,address)","787d64e4":"m_multiOwnedRequired()","787dbaf1":"feedTweet(uint256,uint256,string)","787dc68f":"createPromoAthlete(address,string,address,uint256,uint256,uint256)","787dc9f1":"getFee(bytes8,uint256)","787e9137":"collectedTokens()","787ed1f8":"sayOwnerHello(string)","787ed54f":"payDividendsManually()","787eda49":"assertEq20(bytes20,bytes20,bytes32)","787f9710":"namespaceTaken(bytes32)","787f9cc3":"ManualPriceChange(uint256,uint256)","787fd167":"GameJoined(address,address,uint256,uint256,uint8,uint256)","788023ff":"changeShareable(address[],uint256)","78809c52":"ratePerEthPhase1()","788102ff":"reservedFundsParking(address)","788222ae":"tokenEmail()","78831239":"deleteTopic(bytes15)","78831b36":"setDividendsWallet(address)","7883985b":"addrExecutor()","78843a95":"isTier1(address)","7884e787":"getDni()","78862e69":"deathData_f9()","788649ea":"unfreezeAccount(address)","7886b526":"checkRecords(uint256[])","78879d74":"betAmountAfterRakeHasBeenWithdrawnAndProcessed(uint256)","78880f4a":"population()","7888e957":"storageToUint(int256,string)","788a8c8b":"ARBI()","788ac4a8":"Petrocoin()","788acd7e":"issueBounty(address,uint256,string,uint256,address,bool,address)","788b2ba2":"Stock(string,string,uint256,string,uint256)","788bb8df":"EUR_Omnidollar()","788bc78c":"setVersion(string)","788bc8c0":"tokensToUsd(uint256,uint8)","788c26b4":"createNewVesting(address,uint256,uint256,uint256,string,uint256,bool)","788c4023":"isWalletLocked_Receive(address)","788c5999":"mintMode()","788ce6f2":"icoAddress()","788d135b":"GoForLaunch()","788d1fa6":"setInt8(int8,int8)","788d3851":"voteOpen()","788d5881":"licenseTermsHasMinCost(bytes32,bytes32)","788e0760":"shpExchangeRate()","788e26e7":"sponsorDeposit()","788e2c3c":"getRoundRemaining()","788e31bf":"addBoolSetting(string,bool,address,address,string)","788e72a5":"purchaseProduct(bytes32,uint256)","788e7909":"testTransferFromDoesNotAllowTransferOfMoreThanExistingTokensByDelegate()","788efb9e":"get_taker_fee()","788fa540":"CANONICAL_PRICEFEED()","78912dee":"FINTRUX_RESERVE_FTX()","78912eae":"sendTransaction(address,uint256,uint256,string,uint256,bytes)","7891663d":"HDXToken()","78918e89":"deleteCell(address)","7892cabf":"mixGenes(uint256[2],uint256[2],uint256,uint256,uint256)","7892d29e":"calcTradeFee(uint256,uint256)","7892fd29":"ROUND_TIME()","7893d936":"associate(bytes32,bytes32)","7893f4c2":"DBToken()","7894aafa":"createDivCard(string,uint256,uint256)","7894d1d0":"makeConcept(address[],uint256[],uint256,bytes,address)","789533e9":"getTeamPrice(uint256)","78954b3b":"previousContract()","7895dd21":"claimTokensFromSeveralAuctionsAsSeller(address[],address[],uint256[],address)","7895f853":"isFundLocked()","78960df6":"policyCandyBalance()","7896904e":"DaaToken(string,uint8,string,uint256)","7896cd95":"exchangeEnableCost()","789770f4":"ethToToken()","7898278f":"emergencyFreezeAllAccounts(bool)","78984793":"setLimit(address[],uint256)","7898acef":"usernameOf(address)","7898b917":"getKey(address,string)","78990684":"closeAllSales()","789a12fd":"getRafflePlayers(uint256)","789b2e6c":"payDay()","789b4690":"diviRate()","789c617c":"intStorage(bytes32)","789c6740":"testEmptyCart()","789cf5e2":"auctionSumPlat()","789dfc91":"SafeNetToken(uint256)","789e4e53":"createContractCollection(string)","789ea7dc":"becomeBatlord()","789fdcb6":"DoMusicPayout(uint256)","78a17883":"_batch4_icosaleEndTimestamp()","78a1b7c2":"pct(uint256,uint256)","78a2157a":"erc20ECT(uint8)","78a29c66":"votesAvailable(address)","78a2e101":"TOKENS_FOR_PRESALE()","78a32742":"Pinged(address,uint256)","78a5b1b0":"blockHeaders(bytes32)","78a5f0ca":"withdraw_dao_fund(address)","78a62e9d":"isAppCode(uint32)","78a6c6d2":"createBreedingAuction(uint40,uint128,uint128,uint40)","78a70de5":"safeMathDiv(uint256,uint256)","78a71d78":"sendMail(address[],uint256,bytes32,uint256,bytes32,uint256)","78a72e0d":"encodeTransfer(uint96,address)","78a77b84":"closeRaffle()","78a7b804":"setKittyCoreAddress(address)","78a7e17d":"convert10MTI()","78a83232":"violaToken()","78a89567":"getTokenCount()","78a8b1fb":"ZTKGamers()","78a90a59":"presaleStop_13_December()","78a9e88a":"parseBitcoinComFeed(string)","78a9eeed":"listAll()","78aa08ed":"lotteryFee()","78aa34bf":"test_6_assertGasUsage2000Boards()","78abafaf":"limitAmount()","78abf854":"_budgetEndAndOfficalVotingTime(uint256)","78abfbeb":"finalization()","78ac19f9":"GexPayTest2Token()","78ad76e6":"DeBiToken()","78adf55e":"PreICOPart()","78ae12d8":"PRE_SALE_1000_ETH()","78ae88d1":"newDeal(uint256,uint256,uint256,uint256,uint256)","78af5058":"picosSold()","78af63ac":"btcRaised()","78afda07":"firstContractAddress()","78b04df0":"Play(address,uint256,uint256,uint256,uint256)","78b0cb23":"addGpgKey(string)","78b14f0a":"addCharity(address)","78b150bd":"contractUpgradable()","78b17bd1":"supercustomhash(bytes)","78b17ccf":"CANCELLATION_FEE()","78b226c4":"updateMemberAddress(address,address)","78b27221":"mintFungible(uint256,address[],uint256[])","78b290b5":"OPERATION_HOLDER()","78b29105":"forceBuy(address,address)","78b5a576":"updateDexterity(uint256,uint8)","78b6e20c":"untrackTreasuryToken(uint256)","78b71079":"hasEnoughGrantAmount(address,uint256)","78b83360":"freezingBalanceInfoOf(address,uint256)","78b8a6c2":"issueTokensInternal(address,uint256)","78b8c58c":"getTokenInfoNumToknes()","78b99c24":"pricingStrategy()","78ba24f2":"addContractBalance(uint256,uint256)","78bb5164":"whitelistLength()","78bb9e54":"niceguy4()","78bba530":"communityHolder()","78bc254b":"setPreIcoParameters(uint256,uint256,uint256,uint256)","78bc6460":"getCallGasPrice(bytes32)","78bca3e7":"NeuralNetwork()","78bcd39a":"accountLockCheck(bytes32)","78bd7935":"getAuction(uint256)","78be0496":"MTF(uint256,uint256)","78beda71":"createPromoMineral(bytes32,address,uint256,uint256)","78bee6b4":"transferToAnotherAddr(address,uint256,bytes32)","78bf2b53":"setToken(address,uint256)","78c01961":"EmitEntityIds(address[])","78c24e9b":"adminSetFeeDialNumber(uint256)","78c2c849":"burnUnicorns()","78c37a45":"amendCount()","78c38a79":"setOwnedArea(address,uint256)","78c3b3a5":"futureRoundWallet()","78c3df77":"addProfitPerShare(uint256,address)","78c3e2ec":"createTask(address,string,string,uint256)","78c3e7a4":"generateCardsFromClaimForOpponent(address,address)","78c3f298":"pvtTokens()","78c53533":"getPoolOwner()","78c5e86f":"crowdsaleClosedTime()","78c62ca4":"changeDestinationAddress(address)","78c68573":"getLineUpEnable_miner(address)","78c6d437":"founders_addr()","78c70a4e":"allowAddressToSendMoney(address,address)","78c7524d":"versionIndex(bytes32,bytes32,address)","78c83f71":"rebalance_insert(uint256)","78c8cda7":"removeWhitelist(address)","78c91d29":"getCountCanAdd()","78c9f9cf":"computeEarningsAmount(uint256,uint256,uint256,uint256,uint256)","78ca923d":"nearestKnownBlock()","78caa728":"getLLV_edit_12()","78cac18d":"updateInfo(address,address,uint256)","78cb2f56":"DENtoken()","78cc180b":"bpSaleIssue(address,uint256)","78ce14dd":"CryptotalksToken()","78ce341a":"enablePayable()","78cf19e9":"reserveTokens(address,uint256)","78cfccb5":"REDDCCOIN()","78cffc09":"set_location(uint256)","78d012a6":"roundIn()","78d0a415":"getDthTeller(address)","78d18198":"getNextSnapshotBalance(address)","78d18bef":"withdrawalsInitiated()","78d19e42":"MintableToken(uint256,string,uint8,string)","78d22ab0":"getStageMinWeiAmount(uint256)","78d34986":"updateKittensRemainingForSale()","78d3633b":"illiquidBalance(address)","78d38d1a":"SenegalvsColombia()","78d45eb6":"checkAccess(address,bytes1)","78d46c3f":"listSpriteForSale(uint256,uint256)","78d4e808":"fetchCancelledOrdersForPayerByAdmin(address)","78d55ac1":"MRCCToken(uint256,string,string)","78d5e123":"unstakeTokensManually(address)","78d63908":"doBuy(address,uint256,bool)","78d63c59":"AMFBToken()","78d6525f":"test_validEmptyEqEmpty()","78d6fd25":"getRecTransactions()","78d74f60":"LyCI(address,string,uint8,string,string)","78d7ccea":"ComputeEggsSinceLastHatch(address)","78d8615f":"addEvent(uint256,string,bytes32,bytes32,string,bytes32)","78d8e17b":"totalGenesisTokens()","78d8fed8":"setUnlock(bool)","78d9472f":"setDefendBoostMultiplier(uint256)","78d9b048":"teamPoolInstant()","78d9c387":"newContest(uint32,uint256,uint256,uint32,uint256,uint32)","78da32f2":"setUintF1F2F3(uint256,uint256,uint256)","78da7ba1":"presaleEndTimestamp()","78dbce5f":"GetStakingNow()","78dbfd91":"createBuyOrder(address,uint256,uint256,uint256)","78dc6b7e":"transferring(address,address,uint256)","78dc7017":"getYellowCards()","78dc70c0":"feePeriodStartTime()","78dda193":"getCarState()","78df0fe1":"getProfits(address)","78dfd3a9":"getNumParticipants(uint256)","78e03373":"operationalAddress()","78e24ab5":"SALE1_RATE()","78e2df0e":"soft_cap()","78e4ca77":"Connect4eth(address,address,uint256)","78e4d750":"PenPalToken()","78e5d841":"HaltableToken(address)","78e619df":"DOOMCOIN()","78e65d2e":"bridgeValidatorsImplementation()","78e7058e":"advisorsTokensHolder()","78e77477":"releasedAdvisorsTokens()","78e7e5ea":"LAND_ADDRESS()","78e80b39":"UserGetPrize()","78e8356c":"removeBet(string,uint256)","78e8488d":"gameGiftSentAmount()","78e870cd":"balances_available_for_crowdsale()","78e88c3c":"getMyFee(address)","78e89085":"Dispute(uint256)","78e8b8fc":"dataSourceCallbackGroup(uint256,uint8,uint8)","78e8cab5":"gcpm(uint256)","78e90190":"mokenBytes32(uint256)","78e95645":"noteChainFee()","78e97925":"startTime()","78e9f1ba":"minimumBetAmount()","78e9f81f":"assignRoleWithExpiration(address,bytes32,address,uint256)","78ea787b":"getDefaultAllowance(string)","78eb890b":"checkErrors()","78eba8fc":"icoCheckup()","78ec0adf":"scannedSilverCaps()","78ec1eb4":"checkIfEligable(address,address)","78ec383a":"MRC()","78ec6dbd":"Beth()","78ec81a0":"sendEarnings(address)","78ec96a0":"GREEN()","78eca227":"getBuyOrderInfo(address,address)","78ecabe6":"changeAvailableSpend(uint256)","78ed2178":"linkFileToTask(address,bytes32)","78ed43c1":"administrationContractFrozen()","78ed8dfd":"allocateUnsoldTokens()","78ed9156":"diary(uint64)","78ee6035":"cancelPledgePayment(uint256)","78eef9d4":"move_excess_for_bucket(uint256,uint256)","78efa1db":"COIN_SUPPLY_ICO_TIER_3()","78f0161a":"setGreyGreenPrice(uint8)","78f08268":"getUsersCount(address)","78f08f2e":"getLineStat(uint256)","78f13614":"ATTR_LEASABLE()","78f1a5ce":"addTeamAndAdvisoryMembers(address[])","78f2144b":"_originalBuyPrice()","78f22cc0":"getAuditRegistrar(uint256)","78f305c6":"getStartDate()","78f55622":"calCurrentVirus(address)","78f55de4":"sxpNumber()","78f5958f":"setblocksPerMonth(uint256)","78f5e0ec":"CampingCoin()","78f5e59f":"TOTAL_SUPPLY_VALUE()","78f74fbe":"tokenIssuedPrivateIco()","78f76779":"batchOrderTrade(uint8[2][],bytes32[4][],uint256[8][],address[6][])","78f79187":"DailyAndSnapshotable(uint256)","78f7aeee":"tokenAllocated()","78f7d9c6":"payBill(uint8,uint256)","78fad7bc":"champToken()","78faff96":"isSet(address,address)","78fbc9ea":"weiToCollect()","78fc3cb3":"canTransfer(address)","78fc52b3":"processDiceRoll(address,uint256)","78fca301":"Menu03(uint256)","78fd98d1":"freezeAmount(address,uint256)","78fddd69":"MedAIChain(uint256,string,uint8,string)","78fe2951":"enableService(uint256)","78ff54eb":"updateRestrictedVault(address)","7900438b":"registerDevice(bytes32,bytes32,bytes32)","79008da5":"addRandomTile(uint16,uint8)","790105ff":"withdrawEIP20Token(address)","79018524":"Token(uint256,address)","79032fa7":"storeHorsey(address,uint256,address,bytes32,uint8,uint8)","790377dc":"getLastAuditId(address)","7903d8c8":"canSend()","79049227":"lockupSeconds()","7904d388":"ethRec(uint256)","7904f688":"distributePrizes(uint16)","79053739":"damage(uint8[176],uint8,uint8)","790587d1":"updateIpfsGateway(string)","79061e96":"withdraw_ether()","7906305b":"upgradeTier(string)","790683d3":"getTopicByOffset(uint256)","79081feb":"getCardLeaseLength(uint8)","7908f25c":"thirdTeamWithdrawal()","79099e15":"MAX_USD_FUND()","7909da6f":"createExchange(uint256,uint256,uint256)","7909f569":"gasForFLKD()","790a091e":"test_rewardPoolShare_notTranscoder()","790b1656":"ThreeEtherFree()","790be9b5":"SETC(uint256,string,string)","790c33b8":"getReportingTokenOrZeroByPayoutDistributionHash(bytes32)","790ca413":"launchTime()","790cbfa0":"createMeshPoint(int256,string)","790d4e11":"getLosersOnePercent(uint256)","790dd0f5":"fuint256(uint256)","7910085d":"fipsIsRegistered(bytes20)","79103c2e":"RejectedApplication(address,uint256,string)","7910830a":"setCrowdSaleStatus(bool)","7910867b":"isApproved(uint256)","7911d80a":"Presale1Sold()","7912b0f1":"HOPEToken()","79132085":"APSP()","79141f80":"getBetInfo(uint256)","791455dd":"addPieceAndHash(string,string,string,address)","79147cf0":"_result()","79147d07":"UnsoldAllocation(uint256,address,uint256)","7914d10f":"setminContribution(uint256)","7915785e":"accountsToAllocate()","791581c6":"addTime(uint256,uint256)","7915c069":"register(string,address,address)","7915c9e0":"verifyTransfer(address,address,uint256,bool)","79162aeb":"pauseEmergence()","79164773":"nextForkBlockNumber()","7919233f":"emitWorkOrder(address,uint256)","7919792b":"doThrowOnDivByZero()","791af2b6":"dkBB(bytes32)","791af8e4":"totalExtraTokens()","791b1150":"notify_payment_reject(uint256)","791b51f1":"Consulting(address,address)","791bbe35":"TheDeadShitCoin()","791cbc4f":"stopConvertTokens()","791dd41c":"ownerOverride(uint256)","791f0333":"equalStrings(string,string)","792037e3":"shut(address,bytes32,address)","79203dc4":"totalAllocation()","7920d804":"getKing()","7920f72c":"_tag(int256,string)","79214878":"regionExists(uint256)","792166b8":"createEscrow(uint256,uint256,address,address)","79216aec":"ManagedToken(address,address[])","79216f5f":"add_monster(uint16,uint16,uint16)","79217982":"preIcoMinInvest()","79219a24":"getLockRecordCount()","7922841c":"registerAssetHeader(int256,string,string,string,string,string)","7923715b":"RPEICO_TOKEN_SUPPLY_LIMIT()","79250dcf":"getApprovePreSignedHash(address,address,uint256,uint256,uint256)","792544af":"get_DB_info(uint256)","79254bb8":"right29(uint256)","792651b0":"app_storage()","7927448a":"getTicketTime(bytes32)","7927bc0c":"list_token_bid(address)","792a152d":"addRegion(uint16,uint256,string)","792ad365":"lastBlock_f15Hash_uint256()","792b22c6":"returnCoupon(address[3],bytes32)","792b476b":"getPositionCount1(address,address)","792c02ea":"stagesLength()","792c91c2":"setRecordId(uint256,bytes32)","792cb544":"_setCertificateSigner(address,bool)","792e1ffc":"authorize(uint8,bytes32,bytes32,address)","792e79c5":"stealCardWithTwitterId(uint256)","79304063":"depositsSigned(bytes32)","7930a433":"withdrawDelta(uint256)","7930acd6":"getCCH_edit_27()","79318d81":"closeRefunds()","7931a765":"Issued(uint32,address)","793267f0":"vaildBalanceForTokenCreation(address)","79326c01":"isSaleOwner()","7932f07f":"getRegionBlockUpdatedAt(uint256)","793318eb":"MMMPCoin()","79332159":"Bet(address,address,uint256,uint256,uint256)","79341ca1":"getRoundAmtPot(uint256)","7934b50f":"_lockToken(uint256)","7934f4ed":"processPayment(uint256,bytes)","7935326b":"preICOTokensAllocated()","79362167":"getBillboard(address)","79372f9a":"ClaimReward()","7937f46d":"setBBO(address)","79381c80":"performRefund(bytes32,uint8,uint256,uint256)","7938cc42":"allocateProofTokens(uint256)","7939a10b":"getSellValue(uint256)","793a2cd1":"isPausedICO()","793a8c95":"owner_updatePayout(uint256)","793c0fd4":"authorizeSpender(address,bool)","793ca3fe":"getFirstCycleBlock()","793cd71e":"cashOut()","793cf430":"option30name()","793d424e":"getBLAddress()","793d7165":"fSqrt(uint256)","793dae12":"acceptSettlement()","793e9b0b":"OPTION_POOL_ALLOC()","793ec6c2":"turnOffCanUpdateBackWindowAdjustmentRatio()","79409b19":"EthToUsd()","79412da6":"withdrawalTokens(address,address,uint256)","7941a062":"getBlocksRemaining()","7941d7bd":"changeTokenOwnerByAdmin(uint256,address)","79420fb1":"tierTotal()","79428570":"getTeamId(uint256)","7943f2ec":"withdrawCoinToOwner(uint256)","79444ad3":"handleForTokenId(uint256)","7944875b":"StopSale()","7944b4b9":"mileStone(address,uint64,uint8)","79456cb6":"test_1_method()","79459ac3":"buy10(address[],address[],uint256[],bytes,bytes,bytes,bytes,bytes,bytes,bytes,bytes,bytes,bytes)","794752c7":"askForgiveness(string)","79480a4c":"getOrderValuesFromData(bytes)","79480fe3":"nextMintFeeAbs(uint256)","79485d41":"DeauthorizeServiceProvider(address,address)","7948a9c5":"TokensWithdraw(address,uint256)","7948f523":"setAmbiAddress(address,bytes32)","79491370":"closeSale(address)","79492f30":"allocationFor(uint256)","7949859e":"UpdateToeknLimitICO(address,uint256,uint256)","794ab0a8":"etherPriceInDollarIn()","794b0c62":"DAICO()","794b0e6b":"addExperience(address,uint256[],int32[])","794c0c68":"stakingEpoch()","794cea42":"search(address,address[])","794d0d8d":"WithdrawVault(address)","794df640":"updateUsdEthRate(uint256)","794e9434":"awardWeeklyLottery(address,uint256)","794ee205":"createMarriage(bytes32,bytes32,uint256,bytes32,bytes)","79501a83":"isBiometricLocked(address)","79502c55":"config()","7950c5f8":"verifyingKey()","7951357e":"Suspended()","79515566":"calcAllowedWeisToInvest(uint256)","7952a0ed":"MetaProject()","79530087":"BirCoin()","79538e47":"addVpf(bytes32,uint256,uint256,uint256,uint256,int256[])","7953ae77":"MainSaleDeadline()","7953e0ab":"dateEcoRelease3()","79544754":"getBonus(address,uint256,uint256)","79557e4f":"traded_token_balance()","7955a65f":"adminWithdraw(address[3],uint256[3],uint8,bytes32,bytes32)","7955dd45":"player_withdrawPendingTransactions()","795612d6":"buyItem()","79564072":"directorLockUntil()","7956f46a":"AggiungiProfessore(address)","7957170b":"getApproveRecord(uint256)","795741c8":"withdrawEscrowFees()","79583e22":"buyOrder(address,uint256,uint256)","7958533a":"meta(uint256,bytes32)","795a16e3":"setRecipient(string)","795b0e16":"TransferAllowed()","795b5b83":"createSaleCardToPlayer(uint256[],address,address)","795b9a6f":"scheduleCall(address,bytes4,uint256,bytes)","795bfd7b":"togglePreventDoublePurchases()","795c1713":"FCoinToken()","795c6437":"isWorkflowState()","795da78f":"coinsIssuedCmp()","795dbede":"idx()","795e09ef":"privilegedAccountsCount()","795e4547":"changeContractUpgradability(bool)","795ebb68":"setTokensDecimals(uint256)","795fcd6e":"RelentlessConscience1Token()","795ff8aa":"safeTokenWithdrawal(uint256)","7960d19b":"MediatedTransactions_Log(uint256)","79624add":"MAX_DAILY_SOLO_SPEND()","7962525c":"getRoundNumberOfBets(uint256)","79630bd8":"rate10()","7963b478":"assertEq28(bytes28,bytes28,bytes32)","79644576":"newProposal(uint256,address,uint256,string)","7964ea87":"claim(bytes32,uint256,bytes)","79655bd0":"getStages()","7965bb86":"STQPreICO2(address,address[])","79662bd5":"withdraw(string,address,uint256,string)","796676be":"urls(uint256)","796686a9":"book(uint256[],uint256)","7966c431":"subString(string,uint256,uint256)","796736f0":"tradeBalances(address,address,uint256,uint256,address,uint256,bytes32)","7967a50a":"preSaleEndDate()","7968196c":"amountRaisedInUsdCents()","79681c94":"buyRoundDataRecord(uint256,uint256)","79683e63":"inviteInit(address,address)","79687166":"uintToBytesForAddress(uint256)","79694f08":"topUpDelegate(address,address,uint32,uint192)","796a6ec9":"Credited(address,uint256,uint256)","796a8076":"updateAuctioneer(address)","796b89b9":"getBlockTimestamp()","796c0c78":"allocatedTokens(address,uint256)","796c5e5b":"saveHash(bytes8,string)","796c8902":"getInvestor()","796d67da":"numberOfProposals(bytes32)","796d8950":"StromkontoProxy()","796dc916":"pauseResumeContract(bool,bytes32)","796f6281":"tokenFront()","7970785d":"withdraw(address[],uint256[],address[])","79710f07":"drainERC20(address)","79716e43":"confirmTransaction(bytes32)","7972d079":"setMfgValues(string,string,string,string,string,string)","7973830a":"getMapValue(uint256)","7973b370":"ProudOfYourCoin()","7973c57f":"fechVoteNumForCandidateBySnapshotBlock(address,uint256)","7974a9e6":"publishOption(uint256,uint256,uint256)","7974f8fe":"changeTime(uint256)","7974fdbd":"secondStageRefund()","79753e82":"initAirdrop()","7975752c":"ScabbageToken()","79758d46":"reading_card_at(uint8)","7975c56e":"oraclize_query(uint256,string,string)","7975c609":"accountLevels()","7975ce28":"buyTokens(uint256,uint256)","7976eaa2":"getBonusTokens(uint256)","79770d5f":"minBidDifferenceInSzabo()","7977f708":"addRoleCapability(uint8,address,bytes4)","79787196":"killTotalSupply()","7978c7ed":"exotownToken()","7978f1b2":"licenseCostNumerator()","79798ccb":"startTokenSale()","79799193":"FreezedCash()","797a49b6":"createPoll(string,uint8)","797af627":"confirm(bytes32)","797b5877":"NCU(uint256,string,string)","797bfaf3":"ico1endTime()","797c6f3a":"advertisingUse(uint256,uint256)","797d660f":"getCandidateNumberList()","797d8b85":"calculateDividend()","797d9437":"loadedRefund()","797df209":"configureVesting(uint256,uint256)","797e2aec":"addCharacters(uint8)","797f6bb1":"raiseTraderUnregistered(address)","797f73ff":"alreadyClaimed()","797f87ba":"chests()","79808552":"cancel_lottery()","7980a1ab":"increasePaymentsBalance(address,address,uint256)","7981e7f1":"generateTokensByList(address[],uint256[])","7981fd67":"loikikd()","7982abf0":"testTransferGas()","7983eb31":"distributeEvenly(uint256)","798405fc":"Hold(address,address,uint256,uint256)","79843715":"crowdSaleMax()","79848daa":"setReleaseManager(address)","7984932e":"releaseNow(uint256,uint256,uint8[],uint256,uint256,uint256,string,string)","79853c7e":"payFromCampaign(bytes32,address,address)","79859a78":"setMaxAgonCount(uint256)","7985b860":"AboutBill(uint256)","7985ee8f":"deleteRewards()","7986c724":"BOUNTY_TOKENS_LIMIT()","7986cbfc":"getGroupbyIndex(uint256)","798764ec":"ShowCoinToken()","79878757":"passTokensToTheTeam()","79881b5a":"setPresaleStartsAt(uint256)","79885b91":"LIB()","79891359":"getOnePlayCoin()","798929da":"distributeCoins(address,uint256,uint256,uint256)","798974dd":"getNumProposals()","798a970b":"setUnitCoinProductionIncreases(address,address,uint256,uint256,bool)","798b18fd":"currentRateM()","798b3ecf":"processCooldown(uint16,uint256)","798b7a71":"callOnce()","798bede1":"advisorSupply()","798c1f2a":"do_bet(uint256)","798c6e0f":"clearStages()","798ce54f":"payoutPartial(uint256)","798d05fa":"getCountTeams()","798ec637":"transferEtherToSender(uint256)","798f3e85":"PublicTokenReleased(uint256)","798f9790":"getResoDetails()","798fd178":"getFrom()","79902299":"recalculateTotalFees()","79905753":"reclaimFundMultiple(address[])","7991c63a":"MetaChanged(uint256,bytes32,bytes32)","7992e39f":"TierAmount()","7993e5c2":"Devcon2TokenForTesting()","7994f55b":"setEndpointParams(bytes32,int256,bytes32[],int256)","79953633":"ownersProductAdded(address,uint256,address)","79955b4c":"richardAddr()","7995b15b":"nowInSeconds()","7995ba90":"withdrawExcessToken(address,address)","7995ed8c":"ClaimedWei(uint256)","79968b77":"sellLicense()","79974ce8":"MiningAttemptEvent(address,uint256,uint256,uint256,uint256)","79978630":"settleChannel(address,uint256,uint256,bytes32,address,uint256,uint256,bytes32)","7997b997":"doMelt(uint256,uint256)","79981387":"setWhiteList(address[],address,bool[])","79984882":"getProxyExecID(address)","79987504":"ECN(uint256,string,string)","7998a1c4":"identifier()","79991997":"enter(bytes32,bytes8,uint16)","799957d2":"TTC()","7999c7ca":"myUsername()","799a5359":"transferToken()","799ae223":"flipCoin()","799b3864":"getVersionLength()","799b7bb8":"PRE_ICO_ADDR()","799c0468":"withdrawMarketingAndCommunityOutreach()","799c7b69":"_resetGame()","799c8ef2":"callScheduler()","799cd333":"sign(bytes32)","799d916b":"getObjectValueByKey(string,string)","799dcf7e":"staticArrayTests()","799efef0":"setLockedWalletAmount(address,uint256,bool)","799f0c5d":"locked_funds_for_revealed_spins()","799f4079":"unholdSubscriptionOffer(uint256)","799f7043":"recordBet(bool,uint256)","79a0e5be":"changeMessage(uint16,string)","79a18b3a":"isRoundThreeSalePeriod(uint256)","79a1c1f6":"proposalStatus(bytes32)","79a1ed16":"WithdrawalQuick(address,uint256,uint256)","79a2bbec":"_addResources(address[],bytes4[])","79a2bfa5":"PRE_SALE_MIN_BUY()","79a34619":"startTimeMain()","79a3510d":"thisVoterExists()","79a37bd0":"tellTime()","79a410a7":"bonusesOf(address)","79a411ff":"ScareERC20Token()","79a4b4bd":"sellPrice(uint8)","79a4ee93":"testDeregisterCustomer()","79a6877f":"initializeToken(string,uint256,uint256)","79a7cfee":"setAddress(bytes32,bytes32,address)","79a7de4f":"buildId(address,uint256,bool)","79a8416e":"checkPayment()","79a84750":"createTokensTo(address,uint256)","79a85e6c":"getProductInfo(uint256)","79a87b19":"migrationDestination()","79a88683":"startCrowdsalePhase3Date()","79a8945c":"isDeveloper()","79a89b06":"releaseExpiredEscrow(address,address)","79a8ba40":"createRequest(uint256,address,uint256,string)","79a8f2fa":"processRoulette(address,uint256,bytes32,uint256)","79a958c2":"codeUpdateState()","79a9986c":"addBadge(string,uint256)","79a9e9ea":"IkuraToken()","79a9f14d":"getBcouponBalances(address)","79a9f23f":"transferAllowedAdd(address)","79a9fa1c":"buyback(uint256)","79a9fd36":"SUAPPToken()","79aa024e":"setAirdropAdmin(address,bool)","79aa668d":"setEventsContract(address)","79ab295f":"SALE1_CAP()","79abb2f5":"play_paper()","79aca4e0":"acceptSmartTokenOwnership()","79ae0c0a":"updatePrice(bytes32,uint32,uint64,uint32)","79ae1c36":"setStopDefrost()","79ae77cf":"OEM_Wallet()","79ae9c5e":"clearLC()","79af55e4":"increaseLockTime(uint256)","79af6547":"addLockStep(uint8,uint256)","79af8380":"addCrowdsaleContract(address)","79b0797c":"AmIPlayer1()","79b2614d":"currentMintNonce()","79b37a86":"usdRate()","79b45b18":"removeEmployeesWithExpiredSignaturesAndReturnFadeout()","79b466b0":"TOTAL_TEAMS()","79b4a2c7":"transferMultiAddress(address[],uint256[])","79b5b1d1":"EvaCurrency(string,string)","79b7b30b":"endTrading(bool,bool)","79b80455":"onTimeLock()","79b9a060":"changePayout(uint256)","79ba5097":"acceptOwnership()","79ba50b1":"LAME()","79baa8a9":"BasicIncome_CoFund()","79bae8a1":"test_failed_payment_throwing_token()","79bc2040":"canbuynum()","79bc46b3":"SELL_HARD_LIMIT()","79bcabf4":"Authority()","79bcae2a":"createFuel(uint256,string,uint256,uint256,uint256)","79bd04f2":"_bidLaterShip(uint256,uint256,address,address)","79bd42cf":"END_DURATION_BETTING_BLOCK()","79be02af":"Read(address)","79bed048":"turnOffCanUpdateAmountToTakeAsRake()","79bf8df3":"mModeratorKeys(uint256)","79bfaaeb":"visaLength(address,uint256)","79c0909e":"getRandomFromBlockHash(uint256,uint256)","79c0b9fb":"sanityCheck(uint256,uint256,int8,int8,int8)","79c0d5ae":"tokensInvested()","79c0f30e":"advancedThreshold()","79c12db5":"EventTicket(uint256,uint256)","79c20b41":"changeArtName(string,string)","79c30e49":"openCdp(uint256,uint256,uint256,uint256,address)","79c310a6":"increasePlayersJadeProduction(address,uint256)","79c3199d":"preIcoStartDate()","79c36409":"DifToken(uint256,string,uint8,string)","79c3dd32":"thirdLevelPrice()","79c3ddc1":"isPackageOwner(string,address,address)","79c3f694":"_getPVPFeeByLevel(uint256)","79c4264a":"earlyBirdMinPerPerson()","79c4264b":"matchCount()","79c597ff":"ends()","79c5ba97":"enterBidForGanToken(uint256)","79c5c6b6":"MyWill()","79c5cb1c":"createItem(string,uint256,uint256,uint256)","79c63c40":"dxfOpen()","79c65068":"mintToken(address,uint256)","79c66892":"EmrCrowdfund(uint256,uint256,string,string)","79c69195":"setParamsTotalSupply(uint256)","79c6a1b8":"registerAdmin(address,string)","79c6b667":"registerPoA(string,bytes32,uint64[],uint64[],address,address,string)","79c6c11a":"takeEther(uint256)","79c7180d":"Erc20SummaryLogic(address)","79c73464":"numAdrs()","79c749cd":"generateContentID(string)","79c74a38":"Fomo5d()","79c7c806":"proofExists(string)","79c7f38c":"_freezeAccount(address,bool)","79c84100":"getFreezeHourglass(bytes32,bytes32)","79c88f20":"datacoin()","79c8fe30":"setMaximumGasPrice(uint256)","79c9e396":"test_oneInvalidEqBytes2()","79ca0792":"beneficiaryMultiSigWithdraw(uint256)","79ca9ad4":"tokensToEth(uint256)","79caf670":"ethealController()","79cb5a2f":"setEtheraffle(address)","79cb650f":"testAliceFooKill()","79cb657a":"setRateStalePeriod(uint256)","79cc6790":"burnFrom(address,uint256)","79cc90c4":"repossess()","79ccd1a1":"BetherBank()","79cce1c5":"getReleaseHashes(uint256,uint256)","79cd421d":"ERCTestToken()","79ce0515":"removeCP(address,address)","79ce37e1":"deadline_modify(uint256,uint256)","79ce9fac":"transfer(bytes32,address)","79cef607":"_purchaseTokens(string,address,uint256)","79cf3a7a":"zeroOut()","79d007f7":"forceOffsetExtraFeeRate()","79d00c5d":"EasyCrowdsale()","79d10a76":"SedPosToken()","79d116ed":"setWhiteListingAdmin(address)","79d1d4fa":"verify(bytes,bytes,bytes,bytes32)","79d220ae":"setCrowdsaleOpenTimerFor(uint256)","79d2e48d":"upgradeFinalize()","79d303ae":"doStart()","79d3d547":"grantToken(address)","79d42bfe":"CLNRaised(address,address,uint256)","79d4fe00":"totalTokensICO3()","79d60cdf":"LongChain()","79d6348d":"sign(string)","79d68f79":"COIN_PER_ETHER_BOARD()","79d88d87":"forbid(bytes32,bytes32,bytes32)","79d8cc7b":"setFlights(uint16[],uint16[],uint256[],uint256[])","79d95c5a":"setMaxCap10X(uint256,string)","79d9e979":"minimumDealAmount()","79da06a2":"BlockSwapWrapperGolemNetworkToken()","79da9747":"switchCrowdsale()","79db228a":"RegisterList(address[],bool)","79db5f67":"removeRole(address,uint256)","79db671d":"upadateContributorsCount(uint256)","79db77a3":"removeStaffWhitelist(address[])","79dbdbb9":"CKYAdv(uint256,string,string)","79dc04c0":"BCTVToken(uint256,string,string)","79dc10a6":"takeOwnershipFeePercents()","79dd02cb":"PerfectCoinControl()","79dd822a":"setSignatureRest(bytes,uint256)","79ded380":"setRabbitMother(uint32,uint32)","79df2a4c":"ReferredInvestorAddition(address,address)","79df4fa2":"startDeposit()","79df896d":"ScandinavianEKrona()","79e05a36":"getUintField2()","79e097f0":"addVotePair(address,address)","79e0ef1b":"withdrawBalanceAmount(uint256)","79e0f59a":"setEarlyParicipantsWhitelist(address[],bool[],uint256[],uint256[])","79e1250d":"setTotalToken(uint256)","79e12f7e":"getBoardByHash(bytes32)","79e1c9dc":"changeAmountPerEther(uint256)","79e1fa2e":"convertToEur(uint256)","79e23483":"addLockValue(address,uint256)","79e2bbea":"getLifeVal()","79e35d0b":"poolcoin(uint256,string,string)","79e468ef":"createLand(address)","79e54e6e":"AleKoin()","79e58973":"coinBalanceOf()","79e58cfd":"transferIcoship(address)","79e79023":"KuaiMintableToken(address,uint256)","79e8b8eb":"lastSubTokenCreatorOf(uint256)","79eaaf61":"totalTiers()","79eac7c3":"confirmOccupancy()","79eb16d4":"calculateShareETH(address,uint256)","79eb26cc":"RANGE_SCALE()","79eba0b6":"showPrivateVars()","79ec3864":"getMemberAtAddress(address)","79ec4f19":"setStartAndEndTime(uint256,uint256)","79ed13a7":"availableOptions()","79ed3d69":"setNextCommonTTMTokenId2(uint64)","79edfa7d":"setMetadataUrl(string,string)","79ee54f7":"getRewards(address)","79eee392":"DEVELOPERS()","79ef6858":"addItemToMenu(bytes32,uint256)","79ef704e":"addLogic(address)","79efb507":"oldData()","79f00703":"setEthartArtReward(uint256)","79f015b2":"getCarProductName(uint32)","79f0b427":"log_demurrage_fees(address,address,uint256)","79f0c524":"ParseHeaderData(bytes)","79f0cd62":"revertTokensByKYC(address,address)","79f0f7b3":"safeMulWithPresent(uint256,uint256)","79f119cd":"PXP()","79f1433c":"post_energy_balance(int256)","79f16ba1":"ShanDianLian()","79f1987d":"thirdExtendedBonusSalesEnds()","79f1a6ef":"_noMatchingPairs()","79f3b481":"putTreeOnSale(uint256,uint256)","79f57e68":"getAsAddress(bytes32)","79f59f09":"ParsecTokenERC20()","79f645ea":"RANDOMIZER_RETRY_COUNT()","79f64720":"cancelAndReissue(address,address)","79f68f85":"forwardFunds(bool)","79f74fd5":"ControllerSet(address)","79f7a873":"isAtLeast(uint256,uint256,string)","79f7e600":"setApproveOwner(uint8,bool)","79f90d6c":"ownerPauseContract()","79f9578c":"queryBalanceMinter()","79f96600":"getCurrentFeeWindow()","79f9b10b":"registerAsExportingAuthority(address)","79f9cc72":"setGasLimits(uint256,uint256)","79fb18ac":"transferSmartTokenOwnership(address)","79fc3682":"addressBalances(address)","79fc4687":"receiveDividends()","79fd86cc":"airDrop_(address,address,address[],uint256)","79fd8c24":"PriceUpdate()","79fdf548":"updateTokenInvestorBalance(address,uint256)","79fe3b06":"setPercentTokensToSale(uint256)","79fed7cb":"checkMinContribution()","79ff69d9":"paymentSettle(uint256)","7a00698f":"_doProposal()","7a0092b5":"Aunder()","7a009c22":"increaseBank()","7a00cf46":"isCloseable()","7a00e2e3":"removeReferrer(address)","7a013105":"ico_start()","7a02a973":"resetStaking()","7a02dc06":"getInfo(bytes32)","7a02eb1d":"Maesawa()","7a039beb":"GXX()","7a041e7e":"fundsFromPreSale()","7a044323":"accumulated()","7a04581c":"getBetclose()","7a04855a":"EplusCoinToken()","7a04f9ea":"getPhaseExpiry()","7a060b53":"GOLD_AMOUNT_TPT()","7a07424e":"promotionRatio()","7a08339d":"setFakeTime(uint256)","7a091f95":"batchPunchIn(address[],uint64[])","7a09588b":"cashoutEOSBetStakeTokens_ALL()","7a096f53":"getTransfer(address,address)","7a09defe":"totalMonster()","7a0a2e00":"auctionEndHashing(uint256,uint256)","7a0b0a3f":"MAX_STAGE_1_LIMIT()","7a0b294c":"buyPresaleTokens()","7a0c396d":"giveMeNILs()","7a0ca1e2":"attach(address)","7a0d819e":"casinoDeposit()","7a0e03ec":"getUInt8Value(bytes32)","7a0e09aa":"getConsent(uint256)","7a0e2d1a":"updateUser(bytes32,bytes,bytes32,bytes32)","7a0ecfc2":"LogUpdatedInitialTimestamp(uint256)","7a0fee37":"MinerRandomNumber(uint256)","7a10f17b":"PIN_PRICE()","7a1126f0":"houseWithdraw(uint256)","7a118fdc":"SHNZ()","7a11dfb4":"redeemBounty(uint256,uint256,uint8,bytes32,bytes32)","7a12cabf":"owner_updateRelay(address,bool)","7a12cdb8":"cybToken()","7a1395aa":"setDecimals(uint8)","7a13d14c":"disputeAutomatedReport()","7a1439d7":"payOffClaim(bytes32,uint256)","7a14f465":"crosairSoldCount()","7a152c11":"unpause(uint256,uint256)","7a153043":"disbursements(address,uint256)","7a1593d6":"freeze(address,string,uint256,uint256,uint256)","7a15eb8d":"lottoIndex()","7a16c6dd":"setsetperiod(uint256)","7a16cbe3":"setData_4(uint256)","7a178741":"getMemberAddr(uint256)","7a17feff":"setTransferLimit(uint256)","7a186ebf":"WHITELISTED_PREMIUM_TIME()","7a1903f2":"checkBonus(uint256)","7a1a0604":"AuctusTokenSale(uint256,uint256)","7a1a7e7f":"itemCancelMarkets(uint256)","7a1ab407":"bountyOwnersTokens()","7a1ac566":"registerSale(address,address)","7a1aeb3c":"getTokenCount(bool)","7a1b26a8":"TransactionAccepted(uint256)","7a1b63bc":"buyCMTAgainstEther()","7a1bba3a":"TestFoo()","7a1bbb40":"getNegativeArray()","7a1bcae9":"playerDecision()","7a1bf7f6":"PreIcoClosedManually()","7a1c0063":"emitExecuted()","7a1c39cb":"setIII_R2(uint256)","7a1c44f8":"DappleAirdrops()","7a1cf806":"configureTokenDividend(address,bool,address,bytes)","7a1d66dd":"determinePosition(address,address)","7a1d8570":"getSendVal()","7a1e16bc":"signEscrow(uint256)","7a208990":"Arcus()","7a20ff15":"getWeiAllowedFromAddress(address)","7a223758":"detOwner()","7a22393b":"setTokenSeller(address)","7a233fb3":"redeemPrice()","7a26924f":"timeToFinishTokensSale()","7a2756f2":"getWager(uint256)","7a276bb6":"getDeveloper(uint256)","7a28399b":"approveProvider(address)","7a28e60f":"EXTRADECOIN(string,string,address)","7a28f8bc":"accountData()","7a290fe5":"burnRemainToken()","7a29332d":"buyAllOutcomes(uint256,uint256)","7a294055":"VoteReceived(string,address,uint256)","7a2a0456":"swapEtherToToken(address,uint256)","7a2a3931":"galleassetTransferFrom(address,address,uint256)","7a2a530d":"getAllDevices()","7a2b0587":"isReserve(address)","7a2b2dd7":"Metaexchange(address,address,address,uint256,uint256,uint256)","7a2b78e5":"findIndex(uint256,uint256)","7a2b9116":"checkValidTk(address)","7a2c1b71":"CheckProfit(address)","7a2c8506":"getUserReward(address,bool)","7a2cc6d8":"_createPermission(bytes32,address[],bytes4[])","7a2e1c61":"getSoldCountOfPackage(uint256)","7a2e41d1":"InitiateCryptoGamers()","7a2ecfdb":"setMostSent(uint256)","7a309005":"devSENSDestination()","7a30ebed":"holyFoundersFundDeposit()","7a3130e3":"migrateFrom(address,uint256)","7a314ce2":"FUND_GATHERING_TIME()","7a319590":"changeFees(uint256,uint256,uint256)","7a31ee21":"MinimumFundingGoalChanged(uint256)","7a32c84c":"getDonatee()","7a341bc7":"setFounder(address)","7a34cedb":"purchaseWithBTC(address,uint256,uint256)","7a350141":"BalanceChanged(address,address,uint256)","7a360ec3":"forwardWei()","7a3629dc":"setMinimumStakingRequirement(uint256)","7a362fe1":"ICO_START1()","7a366d14":"softCap(uint256)","7a38012e":"handleEarlySaleBuyers(address[],uint256[])","7a38417b":"delayOpeningTime(uint256)","7a386e88":"setupAmbi2(address)","7a387bc2":"returnNote(uint256)","7a38f9eb":"isZero(uint256)","7a396264":"winAmount2()","7a39bb28":"FirstPeriodCapUpdated(uint256,uint256)","7a3a0e84":"fundingGoal()","7a3aa8ea":"CoXxMoXx()","7a3abce9":"withdrawComB()","7a3b0b5d":"positive_terms_of_Service()","7a3c4c17":"currentPrice(uint256)","7a3cbbe4":"TIMER_STEP()","7a3d2e5c":"changeArtUrl(string)","7a3d4b1a":"createSwap(uint256,address)","7a3dae68":"_createKT(string)","7a3dbc16":"getInitialPrize(uint256)","7a3e0013":"setArbitrator0(address)","7a3e286b":"currentCollectRound()","7a3eeb57":"setdteamVaultAddr2(address)","7a3f5781":"setAllowRefunds(bool,uint256)","7a4058dd":"confirmDealCompletionByPatient(bytes16,bool)","7a40618d":"emitContractRemoved(address,address)","7a408454":"burn(bytes32,uint256)","7a4093b8":"SETUP_DONE()","7a427d98":"forceReturn()","7a42a9cd":"checkOwner(bytes32)","7a43cb62":"positionWeightOf(uint256,uint256)","7a442a9b":"isClaimable(string)","7a444072":"getDeveloper()","7a44d730":"PGM_Coin()","7a457855":"getNumeroMensajes()","7a468170":"ethCap()","7a4690fb":"TOKEN_SALE1_NORMAL()","7a476a42":"queryPublishedContractTemplate(uint256)","7a479160":"getRequestArgs(uint256)","7a4822d7":"addTransaction(address,uint256,string,bytes)","7a4843ca":"product3_luckybuyTracker()","7a48b408":"MCIM()","7a48f5c7":"start_pg_quiz(string,string)","7a4aa92f":"provideTeamHolderToken()","7a4b7075":"getMake(uint256)","7a4b762b":"synechronToken()","7a4bfebb":"FixedGameToken(bytes32,uint256,address)","7a4c2e9a":"access_hidden_layer(int256[],uint256[],uint256)","7a4c96ad":"vote(string,string,uint256)","7a4cac15":"removeUserAsset(address,uint256)","7a4e320c":"MINIMAL_PRE_ICO_INVESTMENT()","7a4e365d":"destroyFreezeFunds(address)","7a4f2fde":"decreaseSalesBalance(address,address,uint256)","7a4f7b92":"getInitializedFeeWindow()","7a4fb678":"Operation(uint8,bytes32[8])","7a504ceb":"endCrowdsale(uint256)","7a50aeb5":"ProofToken(address,address,uint256,string,string)","7a518d9f":"epoch_release_count()","7a51a611":"getOptionIdForPoll(uint256,uint256)","7a52ad76":"ChangeMainSaleDates(uint256,uint256)","7a530f03":"createPromoFlower(uint256,address)","7a5310b9":"confirm2stage()","7a53bcfc":"batchSend(address[],uint256[])","7a5402e9":"getPolicyData(uint256)","7a543a94":"isIcoFinished()","7a545b0c":"preIcoSold()","7a55cece":"PlusPay()","7a55d4bd":"getCurrentBragKing()","7a5615c0":"changeTokensPerUSD(uint256)","7a58b058":"read_max_dgx_available_daily()","7a58ce90":"CryptoLinkNet()","7a5977be":"MAX_TOKENS_ADVISORS()","7a5984c4":"burn(uint32)","7a5a35ad":"setUSDEth(uint256)","7a5a59ec":"angelAllocation()","7a5b4f59":"getMetadata()","7a5bed43":"deleteSharedAccount(bytes32,bytes32,bytes32)","7a5c8432":"paymentqueue()","7a5c9028":"getLengthClassPlayers(uint256,uint256)","7a5ced61":"batchcollecttaxes(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","7a5d5345":"signControllerChange(address)","7a5db3f3":"renounceInvestor()","7a5dbc21":"ipow(int256,int216)","7a5df22b":"getStakedAddress(address)","7a5e842a":"nizk_verifyproof(string,string,string,string,string,string,string)","7a5f5021":"closeBets(bytes32,bytes32,uint256,uint256)","7a5f715c":"SetCityName(bytes32)","7a5f973b":"INITIAL_SUBSIDY()","7a62b77c":"ShowChargeTime(address,uint256)","7a631201":"resetEvents()","7a63626c":"ownerIndexToERC20Balance(address,address)","7a63c290":"mintCapInTokens()","7a6506f6":"dividendsPayedIndex()","7a6543e2":"getRegistered()","7a654915":"BitcoinTRONIX()","7a657c53":"checkVotingForSendWeiFromPayment()","7a6615d4":"NewPAIReceipt(address)","7a66e5cf":"paySolutionReward(uint256,uint256)","7a67011f":"setMoneyline(int256,int256)","7a6838ec":"ownerBank()","7a690951":"_endBetListing(uint256)","7a6994dc":"getSpaceByIndex(uint256)","7a6a00bb":"balanceEthOf(address)","7a6a18cf":"CrowdsaleMintFinished()","7a6ad926":"getUint(bytes32,bytes32)","7a6adab6":"getAdsLength()","7a6b1c7c":"authAccess()","7a6b2a2c":"lookupAmountUserDonatedToCampaign(address,uint256)","7a6b456f":"countShips(uint16,uint16,uint8,bytes32)","7a6b8361":"zeroBytes()","7a6ba98c":"getHashKey(address,uint256)","7a6c7783":"_consume(address,uint256)","7a6cb1aa":"getReceiverVesting(address,address)","7a6ce2e1":"getMsgSender()","7a6d6f3d":"gettormow()","7a6d8030":"BLOCKMALL()","7a6e1384":"priceForBuyingCostume()","7a6e2b49":"payService(bytes32,address,address,uint256)","7a6e5949":"getwithdrawEthertoAmountValue()","7a6e9df7":"getTimestamp(bytes)","7a6e9e41":"withdrawSellDemand(uint256)","7a6ee304":"IAMRefundedForWei(address,uint256)","7a706ac7":"setBuyRatio(uint256)","7a70abda":"updateAvatar(uint256,uint256)","7a71055d":"setAvgMinedPerDay(uint256)","7a713023":"finalizeSettingDeprecation(uint256)","7a71dee0":"onePotWei()","7a72416f":"security_address()","7a72c30d":"checkMilestoneStateInvestorVotedNoVotingEndedNo()","7a72c32f":"Paraboloid()","7a740a68":"communityReservation()","7a74b672":"clearEndpoint(bytes32,int256)","7a766210":"XYZA()","7a766460":"getStake(address)","7a773293":"setMarketingRates(uint8,uint8,uint8)","7a783d91":"Leeroy(address)","7a78cccc":"DAMIToken(address)","7a78ee2c":"lastBlock_a12Hash_uint256()","7a791524":"setNextFeePercentage(uint8)","7a792fa0":"get_reward(uint256)","7a79940d":"getSharedAccountPw(bytes32,bytes32)","7a7cdfa9":"createT(string,string,string,string,string,string,uint256,uint256)","7a7d4937":"secondsPerBlock()","7a7ebd7b":"channels(bytes32)","7a80760e":"ERC20Token()","7a81f972":"releaseCelebrity(uint256)","7a824b1d":"cooperativeSettle(uint256,address,address,uint256,address,address,uint256,bytes,bytes)","7a827634":"_emitContractAdded(address,address)","7a828b28":"terminate(uint256)","7a837213":"setAllowedAccount(address)","7a83e89e":"_endBetBlock()","7a840a52":"PKBCoin()","7a84d13e":"getNumberOfCandidates()","7a852c7e":"transferTokensWei(address,uint256)","7a8566ae":"richToken()","7a85c02a":"tokensOfEdition(uint256)","7a85e031":"finalizeInternal()","7a86d3d6":"addWithdrawTransaction(address,uint256,bytes)","7a872547":"defaultInput()","7a875ade":"fishPromoHelpers(address)","7a87f51a":"emergency_eth_withdraw()","7a888ca9":"startOptionsSelling()","7a88aabb":"getAddressOfTokenUsedAsReward()","7a899cdc":"_setPermission(address,address,bytes32,bytes32)","7a8a5cf3":"totalMigratedIn()","7a8a8720":"firstUnitStartTime()","7a8b0114":"setA_ASM(uint256)","7a8b089b":"developerFundDeposit()","7a8bd25a":"get_bet_nfo(uint256)","7a8bd93e":"flipRewardAmount()","7a8df1b9":"getAffiliateInfo(address)","7a8e3d8d":"withdrawEth2Wallet(uint256)","7a8e832f":"MyBalance()","7a8f7be6":"HAYATO_EXTRACTION_BASE()","7a8fa666":"addPoweruser(address)","7a8fe3b1":"getProductBuyersWithUnconfirmedRequests(uint256)","7a9036cd":"registerFixedToken(bytes32,uint256,address)","7a906be0":"createAuction(uint256,uint128)","7a90a7a3":"feeBurnerWrapperContract()","7a9110d5":"klik()","7a91d5f9":"dilutePower(uint256,uint256)","7a91e53d":"isNotSelf(address,address)","7a926165":"manageAdmins(address,bool)","7a927429":"TokenValue(uint256,string,uint256)","7a935644":"I30Token()","7a93b917":"Lirux(string,string,uint256,string)","7a954d5d":"investedInPreICO()","7a95e305":"escrowedForAsset(bytes32)","7a95f174":"CGT()","7a960154":"numOfPurchasedTokensOnCsBy(address)","7a9839c2":"fun(uint256)","7a99b018":"withdrawClient()","7a99ba4f":"investETH(address)","7a99bb0a":"_getTokenAmount(uint256)","7a9a032d":"addProposal(string,uint256,uint256,string,string)","7a9b486d":"deposit(string,string)","7a9c960b":"DayDayToken(address)","7a9d366a":"debug_bool(bool)","7a9db28a":"_setPriceFactor(uint256)","7a9df8c0":"sellChickenParkCoin(uint256)","7a9e19de":"nextOffsetIndex()","7a9e5e4b":"setAuthority(address)","7a9ee2dc":"SogetiCoin()","7aa064ef":"intersubuser(address,uint256)","7aa0eb97":"LogSendTokens(address,uint256,string)","7aa11238":"Flow(uint256,string,string)","7aa1688e":"setUser(address,string,string,bool,bool,bool)","7aa1a77d":"rawWipeAttributes(bytes32,bytes32[])","7aa2096a":"setPI_edit_15(string)","7aa2bcd6":"bonusCompaignOpen()","7aa306a2":"numOwnerAddress()","7aa3295b":"trusted(address,address)","7aa356af":"phaseTwoRate()","7aa359f8":"changemem(uint256,bytes32)","7aa3803c":"takeRent(address)","7aa3976f":"DragonStone()","7aa3b39b":"_vest(address,uint256)","7aa3f6cb":"setKyberProxyAddress(address)","7aa3ff67":"AlterMediatorSettings(address,uint128)","7aa41ed5":"getNumPieces()","7aa50c56":"performDifferent(address,address[],uint256[])","7aa5a1a8":"set_eth_as_seeded()","7aa63a86":"getTotalElements()","7aa86e2f":"fetchProfit()","7aa98fb3":"timeLock(address,uint256,uint256)","7aa9a7f9":"getNumberThree()","7aaa3470":"getInterest(address)","7aaae78c":"preSaleBonus1Amount()","7aacd17d":"MyToken(string,string)","7aacf03c":"auctionIndex()","7aada63b":"maxEarlyStage()","7aae42c9":"endIcoPreICO()","7aaeb37c":"SimpleTGEContract()","7aaf334d":"offFreeze_Bounty(address)","7aaf58d7":"creatUserPurchase(address,address)","7aaf87d2":"getallresutl()","7ab0089e":"YiLiaoLian(uint256,string,string)","7ab03c25":"reserveTokensProjectAndFounders()","7ab0b998":"signRecoveryChange(address)","7ab13461":"decreasePrice(uint256)","7ab13ba9":"isProgress()","7ab14aae":"createBattle(address,uint256[],bytes32,uint256)","7ab21613":"getStopReceive()","7ab2af2b":"isRegistrationOpen()","7ab38e88":"issueTokensPresale(address,uint256)","7ab42bbd":"grantXPTokens(address,uint256)","7ab4e968":"oneEDG()","7ab528c9":"revokeDelegate(address,string,address)","7ab5e1e1":"reservedTokensFunctionality()","7ab61372":"totalRunePurchased()","7ab7a9fa":"aurasCompatible(uint64,uint8)","7ab7ab2e":"AcceptsHalo3D(address)","7ab7d55b":"calculateHash(uint256,uint256,uint256,bool,bytes32)","7ab7e492":"RANGESTART_2()","7ab7fa9f":"UBEX()","7ab91b3a":"hash(uint64[8])","7ab96fda":"testBalanceCanbeWithdrawn()","7aba2249":"StoppableMock()","7aba4d23":"delToken()","7aba6f37":"setLock()","7aba86d2":"bonusMax()","7abaf552":"nexium()","7abb03bc":"noticeWinner(uint8)","7abbe9c0":"DEFAULT_GAME_COST()","7abc06aa":"tokensPerCents_gte50kUsd()","7abccac9":"getTokenMetaData(address)","7abdf949":"getUpgradePrice(uint256)","7abe24d4":"Firechain(uint256,string,string)","7abeb6a0":"createMarket(address,address,uint24)","7abec356":"Deposit(address,uint256,int256)","7abf75fd":"CFNDCrowdsale()","7ac02331":"ethMultisigWallet()","7ac07dcc":"isCaller(address)","7ac1cb30":"setbili(uint256,uint256)","7ac26aeb":"getTag(string,uint256)","7ac37d58":"ownerTransferEther(address,uint256)","7ac3c02f":"getSigner()","7ac40b10":"thedate()","7ac4b05e":"returnMyMoney(uint256)","7ac4ed64":"getAddress(address,bytes32)","7ac59d43":"getSellerSignature(string)","7ac5bb54":"getFlight(uint16,uint16)","7ac5d8a9":"RoundNumber()","7ac6e6a8":"objectHelmet()","7ac7ef85":"Msg()","7ac81da5":"useProps(uint256[],uint16[],uint16[])","7ac8dc26":"subFundPrecent()","7ac91cc2":"testFailOwnedAuth()","7ac94409":"sixthExtendedBonusSalesEnds()","7ac9f013":"removeVal(address,bytes32,address)","7aca84a1":"createVaultAccess(uint256)","7aca97b5":"changeDeadline(uint256)","7acb3e67":"EthTraderDAO(address,bytes32,address,address,address)","7acb4b0f":"isGroupInPolicy(bytes32,bytes32)","7acb7757":"stake(uint256,address)","7acbfb65":"setOwner(uint256,uint256)","7acc0b20":"products(uint256)","7acc6f74":"addSingleAddressToWhitelist(address)","7acc8678":"transferAdminQuickly(address)","7acd0412":"newInvest(address,uint256,uint256)","7ace341b":"getCurrentOwner(uint256)","7ace41f2":"CoinvestToken(uint256)","7ace58d8":"changeBranch(uint256,uint8)","7acee816":"claimIFactor2(bytes32,bytes32)","7acf16c3":"findLowestBenefactor()","7acf4892":"isNotPaused()","7ad00589":"getAffiliateSenderPosCode(uint256)","7ad06be3":"recycleAppearance(uint128[5],uint256)","7ad0bf86":"exchangeRegulatorWallet()","7ad1428d":"m_record(string)","7ad157b9":"buy(uint256,address,bool)","7ad226dc":"refund(uint256,address)","7ad2856f":"info(string,uint8)","7ad28c51":"changeTimeLock(uint256)","7ad2a0ce":"doAirDrop(address[],address,uint256,uint256)","7ad3c119":"ContractInfo()","7ad3def2":"updateToken(address)","7ad4b0a4":"setAttribute(address,bytes32,bytes,uint256)","7ad53eae":"sani()","7ad59e20":"end_Dec_21_2017()","7ad5a045":"_ReparameterizationProposal(address,string,uint256,bytes32)","7ad77fd9":"firstWeek()","7ad8800f":"ShowPrice(string)","7ad9642f":"changeMiniumBet(uint256)","7ad979a3":"setupFund(string,address,uint256,uint256,address,address,address,address[],address[],uint8,bytes32,bytes32)","7adaa3f8":"right39(uint256)","7adac0e6":"stopTransfers()","7adb7ced":"ekkoBlock(uint256,string,uint8,string)","7adbf973":"setOracle(address)","7adc22d8":"bujankkoin()","7add0106":"initBronze()","7addc766":"ADDR_MAYA_MARKETING()","7ade8d6a":"Totti(string,string,uint256,uint256)","7adec1c9":"DepositAcceptedEvent(address,uint256)","7adee0e3":"setJoinDelta(uint256)","7adfec71":"allTasksCount()","7adff2cb":"auth(uint8,bytes32,bytes32)","7ae046d5":"joinGame(uint256,address,string)","7ae0c915":"SmartBondsSale()","7ae11443":"getCurrentStakingPeriod()","7ae145cb":"Badge(uint256,string,uint8,string)","7ae15a19":"createKingdom(string,uint256,uint256,uint256,uint256)","7ae1cfca":"getBool(bytes32)","7ae26546":"setApprovedContractAddress(address,bool)","7ae26773":"revokeAllowance(address,address)","7ae2a331":"goldenTicketFound(address)","7ae2aa34":"teamVestingStage()","7ae2b5c7":"min(uint256,uint256)","7ae316d0":"getTotalFee()","7ae38a95":"isDestructionStarted()","7ae488c3":"priceOfPlayer(uint256)","7ae4bff8":"changeStage(uint256)","7ae506ac":"minimumPurchaseValue()","7ae5dfe5":"TTC(uint256,string,uint8,string)","7ae68ada":"getReferralCode()","7ae6b763":"updatePartner1_will(string)","7ae7024c":"_realBalanceOnToken(address)","7ae74432":"PhilToken()","7ae77ecf":"onlyBouncerCreateContract(bytes)","7ae79345":"ZeroChain()","7ae79e86":"crowdfundEndsAt()","7ae81801":"userUpgradeElement(uint256,uint256,uint256)","7ae8b321":"withdrawGNT(uint256)","7ae8c854":"getMaturity(bytes32)","7ae9c430":"getMinFunds()","7ae9c856":"getassignTokensperType(uint8)","7aeaa864":"storePhoto(string)","7aeabb39":"lastPaymentDate()","7aeb0763":"habichnet()","7aeb9500":"getAutoInvestStatus(address)","7aec05b6":"TemroyToken()","7aec2277":"ValueCyberToken()","7aece878":"receiveObject(uint256,address)","7aef1cdc":"airDropDestinations(address)","7aef1d4d":"setMinEther(uint256)","7aef2226":"MIKETANGOBRAVO18Crowdsale(uint256,uint256,uint256,address,uint256,uint256,uint256)","7aef951c":"bid(string)","7aefec13":"followTraderPreSignedHashing(address,address,bytes32,uint256,address,uint256)","7af05516":"claimRewardTillRound(uint64)","7af0ed7e":"NewStatic()","7af1337b":"updateCrystal(address)","7af20a0a":"LITECORE()","7af2a28e":"createContractElement(string,uint256)","7af30442":"testToggleBitFailIndexOOB()","7af327a0":"deposito()","7af3670c":"NewToken()","7af52ade":"collectEntryFee()","7af5878e":"safeSend(address,address)","7af5dc37":"safeSub(int256,int256)","7af85411":"DisableReturnFunds()","7af8b87d":"verificationRate()","7af8c4f2":"changeTokenSaleAddress(address)","7af91032":"getPoolDoneCount()","7af915af":"setResourcesBanker(address)","7afa0c66":"lockedMonsterStatsCount()","7afa1eed":"generator()","7afa8388":"transferFromWithReferenceCallGas()","7afbe4f1":"Add(uint256,uint256)","7afc84df":"NKHOIToken()","7afcb524":"foundersBalance()","7afd4762":"auctionPriceLimit()","7afde96b":"isInPreSale()","7afea44f":"kycManager()","7aff5061":"penalizeNode()","7afff425":"reclaimAllocated()","7b01127c":"getValue(bytes32,bytes32)","7b012ff6":"IcoCap()","7b015ff7":"crowd_start_date()","7b02347d":"distributeRef(uint256,uint256)","7b02b2c9":"sendMsg(address,string)","7b02b6de":"initialChargeFee(uint256)","7b0383b2":"initializeDispute(uint256)","7b039576":"setCreditStatus(bool)","7b039bb6":"createVariation(uint256,uint256)","7b03e5f0":"_getUint(address,bytes32)","7b0472f0":"stake(uint256,uint256)","7b04a2d0":"onApprovalReceived(address,uint256,bytes)","7b04b1f8":"prePaidFee()","7b053195":"testItems(bytes)","7b05d785":"redeemTokens(string)","7b069edb":"createNewGame(string,uint8,uint256[],uint256[])","7b06e907":"teamAddressOne()","7b07788e":"removePrecondition(uint256)","7b0862e1":"getLatestSettingId(uint256)","7b0863de":"beginClosingPeriod()","7b088543":"setDollarForOneEtherRate(uint256)","7b0934ab":"KRTR()","7b0a2340":"issueBook(uint8)","7b0a3a8d":"maxRecords()","7b0a47ee":"rewardRate()","7b0a7bf8":"disableContactMint(address)","7b0b5b93":"MannaCoin(address,address)","7b0c15ff":"ApolloSeptemStarted()","7b0de015":"teamTokensAddress()","7b0f6f18":"executeArbitrage(address,uint256,address,bytes)","7b0f94ed":"advisoryEthWallet()","7b103999":"registry()","7b10a1d9":"changeInviteReward(uint256)","7b10b293":"requestMembership()","7b10e717":"received_wei()","7b1278e9":"setStageLength(uint256)","7b129c48":"TrueTHB()","7b12df39":"userProfits()","7b12e074":"getSiringWithId(uint256)","7b144a84":"testFunded(uint256)","7b146f6f":"contributorPoolAddr()","7b15013c":"JPPreICO()","7b151be0":"market_WithdrawWei()","7b16c028":"HumaniqICO(address,address,address)","7b16f7a0":"transferAll(uint256,address,address)","7b1707ee":"sendAliceBlue(address,uint16,uint256,bytes)","7b1760da":"computeCertHash(address,bytes32)","7b17e543":"user(uint32,uint32)","7b1837de":"fund(address,uint256)","7b19bbde":"fundValues(uint256)","7b1a4909":"transferETH(address,uint256)","7b1a547c":"registerAs(address,string,uint256,string,address)","7b1aa45f":"ownerDeposit()","7b1ae67a":"OrganicumOrders()","7b1b0c8a":"isWeekdayInsideTimestamps(uint256,uint256,uint256)","7b1b1de6":"pricePerToken()","7b1bc329":"bountySend(address,uint256)","7b1bd162":"NatureSeedToken()","7b1c5368":"fetchVoteMainInfoForVoter(address)","7b1c6c83":"MangGuoToken(string,string,uint8,uint256)","7b1c88be":"transferIncome(address,uint256)","7b1cbb13":"getChannelValue(bytes)","7b1cdd4f":"withdrawWallet3()","7b1e855a":"setBountyCoin(address)","7b1e8871":"_transferBilrew(address,address,uint256)","7b1f1f83":"SgdToWeiRateSet(uint256)","7b1f337d":"endingBlock()","7b23f37d":"ownerRandomNumber()","7b24343e":"salvageOtherTokensFromContract(address,address,uint256)","7b2454c2":"InvestmentAnalytics()","7b24d867":"TokensImport(address,uint256,uint256)","7b253fe6":"getWithdrawableAmountAS(address)","7b2581c2":"totalPurchase()","7b25aeca":"totalLimitUSD()","7b25de45":"isNewToken()","7b25ec58":"getTierTokens(uint8)","7b2643f2":"receiveNVT(uint256,uint256)","7b266b21":"durationh()","7b26de4b":"newPlayer(address,uint256,address)","7b26ff88":"JuryMemberAdded(string,address)","7b274afc":"stopIco()","7b27739c":"LSCKcoin()","7b283b71":"RATE_TIER1()","7b28aa4c":"orderCancel(address,uint256,address,uint256,uint256)","7b292909":"square(uint256)","7b294495":"lastActiveTs()","7b2abb34":"doProveMemoryRead(uint256,bytes32,bytes32[])","7b2b24e9":"isCurrentOrPastUser(address)","7b2bff9d":"getRobotsForUser(address)","7b2c5148":"catReleaseToPrice(uint32)","7b2c8905":"FailedToClaim(address,uint256)","7b2ca96c":"ProdPresale()","7b2d1b30":"getDragonPriceNo()","7b2d3b27":"getStageDiscount(uint8)","7b2e0046":"createAddress(bytes32,address)","7b2e5086":"withdrawFounderFunds()","7b2feaaa":"blockStart()","7b30074d":"trustedCancelOrderTransfer(address,address,uint256)","7b303965":"getStats(uint256)","7b304179":"createMainNetContract(uint256,uint256)","7b3051db":"get_minimum_trade()","7b30de25":"setConfig(string,string)","7b316db2":"enterBidForCollectible(uint256,uint256)","7b3179bc":"setEconomyParameters(uint128,uint128,uint128,uint128,uint128,uint128,uint128)","7b317ef6":"payoutPendingWithdrawl(uint256)","7b31db17":"intMax()","7b327104":"addBidToStack(bool)","7b32daf8":"contractTimeout()","7b3303b1":"startcrowdsale()","7b33e01a":"increaseApproval(address,uint256,bytes,string)","7b33fa25":"confirmReturn()","7b34203d":"getNumberOfDisputedStepsProPatient()","7b352962":"isFinished()","7b35819f":"setPresaleEndDate(uint32)","7b362143":"inactive_withdrawable()","7b36277e":"tier2Total()","7b367343":"IPv7Token()","7b370a01":"crowdsaleDistributedUnits()","7b37b6a3":"RAXToken()","7b38f391":"p1_white_duration()","7b3941d7":"Redeem(uint32)","7b395487":"voteForUltimateOutcome(bytes32,uint16)","7b3aa441":"contributeWithAddress(address)","7b3ae1f1":"addClaim(string)","7b3bfc35":"setRound(uint256,uint256,uint256,uint256,uint256,bool)","7b3c24ac":"compensate(uint256,address)","7b3ca1c6":"registerNameXname(string,bool)","7b3cf41a":"setExplosivePower(uint256,uint256)","7b3d398f":"getTicketHolderCount()","7b3d9338":"market_is_open()","7b3e2ce0":"BuyTicketUseVaultSeed(uint256)","7b3e5e7b":"amountRaised()","7b3ed808":"withdrawlOwner()","7b3f0fb7":"updateRevertSuspendedPayment(bool)","7b3fdcd8":"removeVerifier(address,address)","7b40b291":"RetractRoutingNS(bytes32,bytes32,uint256,bytes)","7b4126f4":"buyContent(bytes32,uint256,uint256,bytes8,string,address)","7b413985":"tokenValueInEther(uint256)","7b422184":"giveBirth(uint256,uint256)","7b424c0d":"changeRelease12m(address)","7b42f6f7":"intervalAt(uint256,uint256,int256,uint256)","7b436460":"Kubic()","7b436fa4":"garanteSystemDepositInOneFund()","7b43a8e6":"commits(address)","7b43adfb":"checkBalanceContract()","7b449206":"changeClearance(uint256,uint256,uint256,uint256,bool)","7b44eb51":"UPO(uint256,string,uint8,string)","7b464e93":"prescriptions(bytes32)","7b46b80b":"unfreeze(address,uint256)","7b473783":"EcoValueCoin()","7b47457f":"MintTokens(address,uint256)","7b47cb68":"lifeFactor_ii()","7b47ec1a":"burnToken(uint256)","7b48ba20":"testThrowDisownNotOwner()","7b48de6b":"returnTransactionPrices(uint256)","7b4938c3":"LinkNaturePower()","7b49e4c0":"DelphyToken(address[],uint256[])","7b4b5e4e":"changeYUMAddress(address,address)","7b4fcdcf":"GetAccess(address)","7b4fd96e":"token_price()","7b5005e8":"ZRXToken()","7b50a573":"functionOne(uint256,uint256,uint256,uint256)","7b510fe8":"getAccountInfo(address)","7b51c463":"hasDebris(bytes32,uint8)","7b523c35":"request(address,address,bytes,bytes,uint256,uint256)","7b5330a7":"getEntitlement()","7b540dd2":"ChangeHold(address,address,uint256,uint8)","7b54a994":"safeAdd(uint256,uint256,uint256,uint256)","7b550233":"deathData_v18()","7b55c8b5":"scheduleCall(address,bytes4,bytes,uint8,uint256[4])","7b55f66e":"manualCloseBet(uint16,uint16)","7b563e3a":"hourPotLeader()","7b564b7f":"test_insert_updateTail()","7b568081":"trade(address[],uint256,uint256)","7b575b33":"operate(bytes)","7b58120f":"preSaleSecondStartDate()","7b5825d5":"get_amount_buy(uint256)","7b58d46e":"changeWikiID_Name(uint256,string)","7b58d7ee":"Jawn()","7b599b5b":"COOLBTCEXCHANGE()","7b59af16":"registerName(string,address)","7b5a08c5":"TradeList(uint256)","7b5bc2e4":"isVoted()","7b5bd741":"getIdentityWallet(address)","7b5bee1d":"_getItem(uint256)","7b5c7b7b":"privilegedTransfer(address,uint256)","7b5cc75d":"lastDividendTime()","7b5d5d1a":"halvingStartBlock(uint256)","7b5e400d":"recipientsMap(bytes32)","7b5eb564":"approveWithData(address,uint256,bytes)","7b5ecb32":"test_twoValidEqUint2()","7b5f4fc9":"get_all_attender()","7b5f7267":"getTokenPriceUSDWEI()","7b61b201":"getHouseCard(uint8)","7b61c320":"tokenSymbol()","7b627879":"Conference()","7b632c41":"TimestampScheduler(address,address)","7b641fbc":"getMembers(bytes32)","7b647652":"LittleEthereumDoubler()","7b647d72":"BITIC()","7b65d0ec":"initialBuyCard(uint8,string,string,string)","7b663d30":"ChangeClaimAmount(uint256)","7b66c032":"HashBuxICO()","7b66e17f":"getDonator(uint256)","7b680deb":"SpiceUpPrizePool(address,uint256,string,uint256)","7b68533f":"earlybird_percentage()","7b68a8f0":"getPixelColor(uint256)","7b698602":"NEXMESH()","7b69db5c":"increment(int256,int256)","7b6a3e27":"out2Done()","7b6a6f4a":"roundUp(uint256)","7b6a912c":"etherCost()","7b6ae58f":"AMICoin()","7b6b3f46":"preMining()","7b6c0492":"allowanceSubId(address,uint256,uint256)","7b6c4b27":"BidRevealed(bytes32,address,uint256,uint8)","7b6c4dc7":"AgriChainProductionContract()","7b6c7a14":"transferAuthorship(address,bytes32)","7b6ccf85":"LogRefund(bytes32,address,uint256)","7b6d79f1":"cancelBet()","7b6d7a4a":"VoteIntentionSet(uint256,bool,bool)","7b6e7603":"levelClearTime()","7b6e8740":"changeCATDestinationAddress(address)","7b6f5a4c":"getCurrentRoundMinimumTime()","7b6ff689":"setImmediateAllowancePercentage(uint8)","7b70209f":"isBeneficiary()","7b7054c8":"__approve(address,uint256,address)","7b707e9c":"getNumberOfCreatedTokens()","7b70cdcd":"dayFor(uint256,uint256)","7b70ed51":"setAngelDate(uint256)","7b71aec8":"ethPropagate()","7b7330cc":"return_eth()","7b73aef8":"setNote(bytes32,bytes32)","7b73c2ef":"defaultDeadline()","7b74644d":"WKToken()","7b74e5c3":"buyByAddress(uint256,uint256)","7b755373":"amountPercentage(uint256,uint256)","7b75a302":"MatContract()","7b75ea7b":"rewardPayableDays()","7b760537":"updateLatestRevision(bytes20,bytes32)","7b7670f6":"gasForXaurDataUpdateAtBlock()","7b76ac91":"day()","7b775ec3":"wallet89()","7b777517":"teamVestingStages()","7b777ecc":"getMaxReportsPerLimitedReporterMarket()","7b77bbc8":"dyn_call(address,bytes)","7b789b3d":"agreement(bytes,bytes,bytes)","7b7a43eb":"setMINfinney(uint256)","7b7a720a":"chrissycoinToken()","7b7b81c5":"loikikdi()","7b7c343d":"setRequiredConfirmations(uint256)","7b7ccc66":"burnSaleTokens()","7b7d4655":"releaseTokenCornerstone()","7b7d6c68":"setController(address,address)","7b7d7225":"_approve(address,uint256)","7b7d8888":"permanentlyOwnMyCompany(bytes32)","7b7e97f1":"isIncluded(uint256,uint256)","7b807a51":"devTimeLock()","7b80889b":"lockedBalance()","7b80a0ca":"endEarlyStage2()","7b8108c6":"isIn(address,address[])","7b813089":"team4Token()","7b816719":"testToInt(bytes)","7b81c3cd":"claimIcoContribution(address)","7b8208b7":"destroyUselessContract()","7b821410":"createPlotVineyard(address)","7b82d9ee":"canDouble(address)","7b830854":"unlockTokenTransfers()","7b831c30":"isRoundEnded(uint256)","7b834bcc":"marketTime()","7b841eff":"turnOffCanUpdatePercentToTakeAsSeed()","7b84de4e":"StarFishCoin()","7b851f65":"hasIcoEnded()","7b86120a":"foundersReserve()","7b865061":"CAPToken(address)","7b87312a":"timeToOpenPresents()","7b875aab":"addrSale()","7b891cf7":"YBCLiveToken()","7b898c71":"_checkLoanBalance()","7b89a582":"Management()","7b89eef2":"getMyAverageDividendRate()","7b8a1898":"setStore(string)","7b8ac66b":"deliver(uint256,uint256)","7b8b7364":"isAddressVerified(address,address)","7b8b82a8":"createManyProxies(uint256,address,bytes)","7b8bf4fd":"set_fee(uint256,uint256,uint256)","7b8c0e0f":"offlineExchange(address,uint256)","7b8cfbe1":"howManyEtherInWeiToKillContract()","7b8d56e3":"setValue(uint256,uint256)","7b8d771e":"_buyTicket(uint256,address)","7b8d9930":"AxieDependency()","7b8de6d0":"executeTokenFallback(address,uint256,bytes)","7b8e3514":"allowedValidators(address,address)","7b8e7964":"JPGToken()","7b8e8bdd":"modifyCloseTime(uint256)","7b8eeb96":"StarMarket()","7b8f186e":"updateIdx()","7b8f2e07":"addCreature(uint16,uint8,uint8)","7b8fa867":"setAllowedAdd(address)","7b8fac4f":"AC(uint256,string,string)","7b907094":"solidityCompileVersion()","7b926c2a":"IFSBalances(address)","7b929c27":"development()","7b92a2de":"Reservation(address)","7b93253c":"validateClaim(address,bytes32)","7b9358a0":"changeRegistrationStatuses(address[],bool)","7b936934":"artistFees()","7b936ac2":"getCFO()","7b9417c8":"addAddressToWhitelist(address)","7b94ffb5":"grantBounty(address,uint16,string)","7b9504d5":"_isOwner(address,uint40)","7b965785":"EVER()","7b969dcd":"_checkPixelAboveLeft(uint256)","7b97008d":"purchaseTokens(uint256)","7b979b41":"leakEther()","7b97c621":"Transferred(bytes32,address,address)","7b991c1a":"findEmptySlot(uint32)","7b9940b6":"initambassadors_()","7b9a3f4c":"TotalFunds()","7b9a9926":"RESToken()","7b9b9c89":"augmintToken()","7b9c34e0":"requestRN(uint256)","7b9c4756":"SanchitToken()","7b9c5794":"test_YayIsOverSixtyPercent()","7b9c7437":"LUCToken(uint256)","7b9daba8":"wa()","7b9dbf95":"FulfillmentAccepted(uint256,address,uint256)","7b9dc066":"tokenTransfersFrozen()","7b9e5bec":"getAsBytes(uint256,uint256)","7b9e9073":"buyLimitSupplyMin()","7b9f87d3":"Setup(address,address)","7b9fa595":"_getCrowdsaleTokenAmount(uint256)","7ba016d0":"icoDiscountLevel2()","7ba04809":"assertFalse(bool,string)","7ba0e2e7":"mint(bytes)","7ba121ff":"EventBonusPercentChanged(uint256,uint256)","7ba1e407":"tokenBack(address[],uint256[])","7ba201c5":"refundSingleUser(address)","7ba22e1e":"changeWorkerBalance(address,uint256)","7ba36880":"_secondLevelEth()","7ba38916":"changeAdminFromBoard(address)","7ba3c804":"AiEXToken()","7ba3f08d":"grantPermissionTo(address)","7ba46004":"totalRuneWithdrawn()","7ba49b81":"lastMintedTimestamp(address)","7ba4a58a":"addressToken()","7ba5f145":"mod256(uint256,uint256)","7ba64e40":"removeBeneficiary(address,uint256)","7ba70bf2":"gettoken(address)","7ba79848":"processReferral(address,uint256,uint256)","7ba7acc9":"initTokenSale(address,address,uint256,uint256,uint256,uint256,uint256)","7ba7dcea":"setRefundable()","7ba8c064":"VotedEvent(uint256,address,bool,uint256,string)","7ba8c12d":"addWhitelistUser(address,uint256)","7ba992fc":"PeriodicTokenVesting(address,uint256,uint256,uint256,uint256,bool,address)","7baa4524":"emptyRemainingsToOwners()","7baa73c6":"_updateCreditedPoints(address)","7bab59f4":"feedTransfer(address,address,uint256)","7babf021":"RLCOIN(uint256,string,string,bool)","7babfffc":"transferDelegation(address)","7bacd526":"withdraw_admin(uint256)","7bacfb0c":"PresaleEndTimeChanged(uint256)","7badc7af":"gaveVote(address)","7bae0585":"approveMany(address[],uint256[])","7bae3f27":"changeTransferFeeOwner(address)","7bae50e0":"mintGen0Spinners()","7baf5b84":"startUnlock()","7baf71f9":"claimPrizePool(address,uint256)","7bb050cf":"migratePlayerPhrasesData(uint256,uint256,uint256)","7bb0688d":"claimedUsers()","7bb0aefe":"hasAuthoritySignedMainToSide(address,address,uint256,bytes32)","7bb0b3c6":"checkifCapHasReached()","7bb1a312":"transferToTeam(address,uint256)","7bb1efa1":"manualInitializeTreasure(uint256)","7bb20df6":"isExistingBattle(string)","7bb25d60":"withdrawInProgress()","7bb26a1b":"ethFoundDeposit()","7bb305ef":"set_foundtion_addr(address)","7bb31dbb":"calcBetResult(uint256,bytes32)","7bb333d6":"EBankerICO(address)","7bb34a23":"bva(address,uint256,uint256,address)","7bb3546b":"hgs()","7bb3ca86":"addReferralHashrate(address,uint256)","7bb43e6e":"returnUnsoldSafeXLarge()","7bb4493c":"FBI()","7bb476f5":"getAvailableAmount()","7bb4c4da":"nAuditorsAlarm()","7bb55287":"assignRaffleWinner(address)","7bb5e1d1":"Cowboy()","7bb6a4c6":"uno(uint256)","7bb6fc6b":"LoveToken(uint256,string,uint8,string)","7bb7adb6":"hugeContributionBound()","7bb866c1":"GetBoosterCount()","7bb8c4e5":"setCut(uint16)","7bb96acb":"getBlockHeight()","7bb98a68":"balances()","7bb9c776":"ticket(bool)","7bb9dc13":"setPublicSaleWallet(address)","7bba0613":"attackCountry(uint8)","7bbb3a60":"inactivityTimeout()","7bbba97e":"CreateEstate(address)","7bbbd75b":"_getNow0()","7bbbe9fd":"claimGameReward(address,uint256,uint256)","7bbc101b":"distributionStart()","7bbc33f0":"vet(address,bool)","7bbc5c01":"calcRefund(address)","7bbc816e":"UTCToken(uint256,string,string,uint256)","7bbd3f19":"removeLastRace()","7bbf2300":"claimAccountOwnership(string,string,uint256,uint256)","7bbf4a3f":"callers(address)","7bbfb0bd":"startTokenPriceWei()","7bbfbaee":"MAX_SUPPLY_USPN()","7bc046ef":"ClaimRemoved(address,address,bytes32,uint256)","7bc0e005":"setDirectDebit(bool)","7bc0ff20":"setupExportFee(address,uint256)","7bc120c2":"isView()","7bc14a67":"Initial_Supply()","7bc21b6b":"bbAdvisorWallet()","7bc25372":"UserCheckBalance(address)","7bc25da8":"Alaves()","7bc363f9":"serviceTransferOwnership(address)","7bc36e04":"setPrivateSalePrice(uint256)","7bc49a95":"play(uint256,uint256)","7bc4be40":"isGlobalLock()","7bc4d6a6":"testInitial1of3()","7bc58805":"balanceFinney()","7bc5af10":"getAwarding(address,bytes32)","7bc62dc3":"ALD()","7bc69bbc":"getBonusByRaised()","7bc6a02e":"isAutoridadElectoral()","7bc6aa07":"omniTeamAddress()","7bc74225":"getTotalStake()","7bc76388":"test_set_owner()","7bc775db":"GxOwned(address)","7bc835da":"UpdateConfirmed(address,address,uint256)","7bc8649f":"NewTKLNToken(address)","7bc89ae7":"registerNameXNAME(string,address)","7bc9165b":"offchainPayment(address)","7bc94872":"FinishReceivingContributions()","7bc9d4ba":"TielseEendrachtCombinatie()","7bc9eb8c":"p_setSoft_deadline_duration(uint256)","7bca38be":"heartbeatTimeout()","7bcaf585":"checkSignature(string,uint32,string,string,bytes32,bytes32,uint8)","7bcc1ff6":"allowanceInternal(address,address)","7bcc9c6f":"sendBackTokens()","7bcd7fad":"getRecordAtIndex(uint256)","7bcdc2f0":"_forwardApprove(address,uint256,address)","7bcdfd4f":"setEpochData(uint64,uint64,uint256)","7bce366f":"minBlockPurchase()","7bce89cc":"currentMarketRate()","7bd13f08":"recoverAddressFromBalanceProof(uint256,bytes32,uint256,bytes32,bytes)","7bd1a731":"deleteIdentity(string,string)","7bd216c6":"teamAddressThree()","7bd2593d":"XfiniteUtility()","7bd26969":"ChannelNew(address,address,address,uint256)","7bd2bea7":"gem()","7bd352b7":"relay(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32,uint8,uint128)","7bd379b3":"PaymentProcessed(address,uint256,uint256)","7bd3acbb":"pointArrayOf(uint256)","7bd53618":"TaiyuanCoin()","7bd63411":"defaultPercent()","7bd6c0e4":"setMigrationHost(address)","7bd703e8":"getBalanceInEth(address)","7bd7c0ac":"armyDronesCount(uint256)","7bd7c891":"becomeFalconmaster()","7bd85cb3":"LZLTokenDeposit()","7bd95a85":"rewardPoints(address)","7bd97ca7":"editMemeTemplate(uint256,string)","7bd9e8fd":"CTO_SHARE()","7bd9f47a":"Best_Bank_with_Interest()","7bdb7a90":"setCdRate(uint256)","7bdbab0c":"tokenMintInit()","7bdc011e":"Pray4Prey()","7bdc297c":"TimeLockedWallet(address,address,uint256)","7bdc60d9":"getTokenById(uint256)","7bde5628":"addNuja(address)","7bde7fcf":"maxApenSell()","7bde82f2":"redeem(uint256,address)","7bdef3f8":"gameMiningTokenCap()","7bdf9d56":"MANHATTANPROXY5THST()","7be00510":"lastInvest(address)","7be122a3":"isSchoolAllowed(uint256)","7be1e747":"initAddress()","7be266da":"isRegisteredInPreviousEpoch(address)","7be296d8":"filmamount()","7be2d5a2":"setDropNumber(uint8)","7be33b36":"getSoundcoinsAddress()","7be34109":"diffMonths(uint256,uint256)","7be4ce4b":"updateRngAddress(address)","7be4ed55":"fixPayAmt()","7be5b5ae":"setBuyDirectMode(bool,address)","7be68454":"optionsRegistryAddress()","7be6d2de":"transferToContract(address,uint256,bytes,bool)","7be80b39":"forceWithdraw()","7be8352e":"getPixelCount()","7be8630f":"lastHotPotatoHolder()","7be8f86b":"done(address)","7be96b1a":"AAA(address,uint256)","7bea7112":"TheOneToken()","7beb2e1e":"minNumbPerSubscr()","7beccd70":"revokeTransferManager(address)","7becd54a":"destErc20()","7bee30ce":"createSspAndChannels(address,uint256,string,address[],address[],uint256[],address,string,bytes,uint32[])","7bee86d6":"lastImageId()","7beeb945":"isRole(address)","7bef29f7":"BittechToken()","7bf08621":"payTo(address,uint256)","7bf0a8f3":"operationsTokens()","7bf0cd0d":"getTargetBlock(uint256)","7bf0e054":"getLotteryDetailsB(int256)","7bf1648a":"setContract(uint256,address,address)","7bf1a627":"ethToken()","7bf1ca1f":"TransferToken(address[],uint256,uint256)","7bf212f8":"getCondition(uint256)","7bf21aa4":"generatePresaleHouses()","7bf21ab8":"sellPBTTAgainstEther(uint256)","7bf26182":"calculateVestedTokens(bool,uint256,uint256,uint256,uint256,uint256,uint256)","7bf2bb10":"arbiters(address)","7bf3f900":"gameManagerPrimary()","7bf437e6":"transferCoinUserToUser(address,address,uint256)","7bf47cda":"cancelSellOrder(address,uint256,uint256,uint256,uint256)","7bf57ca8":"_taxesDue(address)","7bf5b04b":"processDividends()","7bf5b5d6":"distributeWalletTokens()","7bf6f26e":"setMaintenanceMode(bool)","7bf796dc":"SmartAgreement(bytes,address[])","7bf92690":"changeArrangerFee(uint256)","7bf992ac":"GoodKarma(uint256,string,uint8,string)","7bf9d052":"firstRankForFree()","7bfa6e1a":"gameShouldRestart()","7bfaad96":"addNode(bytes,address)","7bfb0934":"value(bytes32)","7bfbe091":"creatorRejectRequestFundTransfer(uint256)","7bfbfecb":"BurnCoin()","7bfe950c":"withdraw(address,address,uint256,uint256)","7bfe97ce":"IBMISOFT()","7bff0a01":"createRandomZombie(string)","7bff9797":"canTeamKeepingWithdraw(uint256)","7c0012d4":"ZiipToken()","7c0081f5":"petCardSeriesCollection(uint8)","7c0176df":"starUp(uint256,uint256,uint256,uint256)","7c0207cb":"isActiveTranscoder(address,uint256)","7c024fe2":"getNowTimestamp()","7c027ed9":"bonus01Start()","7c02e1ea":"addressChangeBlock()","7c03d6f9":"ApprovalFlower(address,address,uint256)","7c051d47":"seedSaleFinished()","7c052478":"setSports3DContract(address)","7c05ba7a":"accreditInvestor(address,address)","7c05caf3":"testCreateCostAuth()","7c0656ac":"LogEtherBounty(address,uint256,string)","7c06db04":"doManualTrade(address,address,uint256)","7c06eb7c":"IGTRMB()","7c0712ae":"setAdd(bytes32,address)","7c07329f":"returnUserBalance(address,address[2],uint256[8],uint8,bytes32[2])","7c078723":"saleExchangeRate4()","7c08ab5b":"BITToken()","7c098bc3":"getBonusPercent(uint256)","7c0a893d":"blockAccount(address)","7c0ab7be":"setBidding(uint40,uint256)","7c0b2484":"enableInviteOfSU(string)","7c0b582f":"WORLD1Coin()","7c0b8de2":"NFT()","7c0c19b3":"zrcoin(uint256,string,uint8,string)","7c0cc0be":"setActivator(address)","7c0d021e":"CreateIssue(uint256,uint256,uint256,address)","7c0e2a5a":"SetLockDate(uint256)","7c0efb8b":"revokeManagerPermission(address,string)","7c0f6b35":"getAllMembers()","7c0f884b":"SlidebitsTestToken(string,string)","7c0fbc31":"signedTransferCheck(address,address,uint256,uint256,uint256,bytes,address)","7c0ff00c":"WithdrawTokensToBankroll(uint256)","7c1008d5":"getLastTipTime(address,bytes32)","7c108f84":"UBToken()","7c10e00e":"setMinBetForOraclize(uint256)","7c116ec9":"respectRequiredToRecruit()","7c11ef87":"calcUSE(uint256,uint256,uint256)","7c1288b5":"distAgent()","7c129c1c":"voteXId(uint256,bool)","7c12b6f2":"_handleWin(uint256,uint256)","7c12f1a4":"addgamecard(string,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","7c132f2c":"crossForkBlockNumber()","7c134a38":"DetailedERC20()","7c13b331":"OysterShell()","7c13ed68":"setIPGInfo(address,address)","7c153534":"tokenFrom()","7c157d12":"_synthesizeWith(uint256,uint256)","7c1595f2":"setLockupContract(address)","7c161409":"BetexToken(uint256,uint256)","7c163fb8":"myLoveBlocks()","7c170237":"ElectroneumGold()","7c1716af":"payToken(bytes32,uint256,address,bytes)","7c17357d":"totalVesting()","7c17dc02":"AddFish()","7c183b4b":"LogRef(address,address)","7c18a32f":"deductionToken(address,uint256)","7c194295":"BurnableTokenMock(address,uint256)","7c197c09":"fullSupplyUnlocked()","7c19e1f0":"replaceInFrontRequest(address,uint256)","7c1a35d7":"RECYCLE_TIME()","7c1a4ee8":"SITExchanger(address,address,address)","7c1b6afe":"getGrantCount()","7c1b814f":"openCrowdFunding(bool,uint256,uint256)","7c1c05dd":"gapInPrimaryCrowdsaleAndSecondaryCrowdsale()","7c1c7860":"TMEDsalesToken()","7c1e5ced":"transferTemp(address,uint256)","7c1f9d5e":"tokenFeeMin()","7c204c27":"MinerX()","7c21ae12":"activeShareholdersArrayLength()","7c21c7e2":"getToggleOwner(uint256)","7c22232a":"playersPoints(address)","7c236c3b":"confirmStackholderTransaction(uint256)","7c23d1cb":"removeLevel(uint256)","7c2464f3":"startICOTime()","7c24b295":"votedYes()","7c24dfb0":"FundTransfer(address,string,uint256)","7c25d997":"getRarityValue(uint256)","7c25f260":"Government()","7c261929":"query(string)","7c262269":"isWorkFailState()","7c265200":"NameGame(uint256,uint256,uint256)","7c267b07":"Cryptrust()","7c280f44":"generate_random(uint256,string)","7c28ddc1":"fiatPerAssetUnit()","7c2926a8":"getHTLCHash(uint256,uint256,uint256,bytes32,int256)","7c29c514":"AgroeconomyToken()","7c29e89a":"mintUnlockTimeBatch(address[],uint256[],uint256)","7c2b00fc":"SGCL()","7c2b07e3":"EtherX()","7c2b11cd":"arraySum(uint256[])","7c2b606a":"isAddressManager(address)","7c2b8d0a":"votedFreeze(address)","7c2cf543":"ROLCToken()","7c2d2326":"PostIL()","7c2d86f7":"usePluginWhitelist()","7c2da7aa":"setValue(string,uint256)","7c2db5ff":"payoutX(address,uint256)","7c2e08a3":"isMinimumGoalReached()","7c2eb1c8":"distributeEther(uint256,uint256)","7c2efcba":"v()","7c2ffbb3":"returnRate()","7c3064f1":"refundStake()","7c313baa":"buyPriceAtIndex(uint256)","7c31975f":"SolClub()","7c320853":"initialSale()","7c331b52":"FlightDelayAddressResolver()","7c337086":"CryptoDegree()","7c33774d":"CluckCoin()","7c3382ae":"setIcoTokenExchangeRate(uint256)","7c33ebfd":"transferToMany(address[],uint256[])","7c34689b":"ACchainToken()","7c34752f":"stringToSig(string)","7c34e853":"getCombinedTotalHP(uint256,int256)","7c35384f":"addTradeRecord(uint256,uint256,uint256,uint256,address,address)","7c359dc3":"manualTokenTransfer(address,uint256)","7c35b6ed":"setPriceBeforeGoalReached(uint256)","7c35be7a":"isOpen(bytes32)","7c360d1e":"calculate(uint16,uint8)","7c3625e3":"SatoExchange()","7c366cb5":"LADToken()","7c372277":"ReserveTokensHolder(address,address,address)","7c37559e":"CreateGLX(address,uint256)","7c37605c":"startSellingGenes(uint256,uint256,address)","7c377d74":"getForkReputationGoal()","7c38ce18":"tokensIssuedLocked()","7c38ee53":"addContactRecord(string,string,string,address,string,string,int256,string,int256,address,string,int256)","7c396b83":"f6()","7c39759b":"kscBurnWhenMoveToMainnet(address,uint256,string)","7c399142":"ITSToken()","7c3a00fd":"interestRate()","7c3a1d32":"setWithdrawCreator(address)","7c3aef0e":"cardDescription(uint8)","7c3b1e06":"setcompany(string,uint256,string)","7c3ba89e":"early_bird_minimal()","7c3be5fb":"setVernamOriginalToken(address)","7c3bf42d":"applications(address)","7c3c0f89":"eastadsCredits()","7c3c2611":"Retained(address)","7c3c4c83":"ARBITRAGECrowdsale(address,address)","7c3d30fd":"_bid(uint256,uint256)","7c3e50ff":"balanceLocked(address,address)","7c3eef61":"AbyssToken(address,address[],address)","7c3fe278":"endSto()","7c3ffdee":"awardCup(uint8)","7c405325":"unlockTokens(uint256)","7c4057ae":"removeMasterNodes(address,uint256)","7c41de34":"_AwardedMissedBlockBonus(address,address,uint256,bytes32,uint256,uint256)","7c423f54":"getAlerters()","7c4338af":"getEarlyIncomeBalance(address)","7c434fbb":"AT(uint256,string,uint8,string)","7c435e6f":"updateEursPerEth(uint256)","7c436a6d":"ownerEnableRefunds()","7c437918":"addPreSaleBuyer(address,uint256)","7c44066c":"summCashwolf()","7c44546e":"SiliconValleyToken()","7c44f160":"Tier_Starter_Registration()","7c45ef6c":"stringToSig(string,string)","7c46a5e7":"Unhalted()","7c4734f4":"getParticipantsHash(address,address)","7c475ade":"IOV()","7c479343":"investSum()","7c47965e":"isInCurrentGeneration()","7c47ac44":"getProjectVerification(uint256)","7c47df2f":"removeEligibleBurner(address)","7c48bbda":"tokensIssued()","7c48f8e7":"penaltyFraction()","7c4a0552":"freezeBlocks()","7c4a7831":"concludeSeason(int8,uint256,uint256)","7c4aa44c":"saleStartEpoch()","7c4b414d":"depositTokens()","7c4c27c8":"isThisPuritanicalVersion()","7c4cafd9":"startSecondaryCrowdsale(uint256)","7c4d18bd":"setMockBool(bytes4,bool)","7c4d972b":"setRoundEnd(uint256,uint256)","7c4db77d":"saleWallet()","7c4deecb":"checkGameContinues()","7c4e7fbb":"QKL()","7c4ecead":"startPresale(uint256,uint256)","7c4edde7":"withdrawFrom(address,address,address[])","7c4f8958":"SPECIALIST_STAKE_ONE()","7c513a21":"arrIdx2lost(uint256)","7c519ffb":"setTrading()","7c524b2e":"set_sell(bool)","7c52b934":"getTokenOrder(uint256)","7c535f1f":"bonusAmount(uint256,address)","7c54aa1a":"deployCommunityBallot(bytes32,bytes32,uint128)","7c559d5f":"bonusPattern(uint256)","7c567bfe":"isSale(address)","7c56b798":"addProject(address)","7c56d40b":"LogFunderInitialized(address,address,string,uint256)","7c57ad45":"newAsset(string,uint256,string,string)","7c57d947":"tokenMinter(uint256)","7c5817e1":"indexOfProvider(address)","7c582304":"updateInvestmentTotal(address,uint256)","7c58a4ed":"canPlatformFundingWithdraw(uint256)","7c59cb3d":"setCSInterface(address)","7c59f828":"getWizzType(uint256[2])","7c5b4a37":"adminWithdraw(uint256)","7c5b5b06":"lastProcessedVaultId()","7c5bfe81":"INITIAL_EXCHANGEABLE_TOKENS_VOLUME()","7c5c2cef":"nPolls()","7c5ca5a6":"ICOFY()","7c5d4949":"calcInvesting(address)","7c5d7980":"addRC(address)","7c5df29b":"auctionDeklaEnd(address,uint256,uint256,bytes)","7c5e16fd":"MAX_ALLOWED_BY_STAGE_2()","7c5e2795":"INITIAL_PRICE()","7c5e6949":"setlvlUpdate(string)","7c5e83cc":"Bullex()","7c609885":"allowWorkersToContribute(address,address[],address)","7c60fa60":"minReq()","7c612409":"setClient(address,address,string,string,string)","7c61b482":"coinAgeRecordForAddress(address,address,uint256)","7c61d567":"transferRegion(uint256,uint256,address)","7c622a65":"TEBT()","7c623ce2":"boughtWithWhitelist()","7c62965e":"excess_withdraw()","7c62e2a4":"getDog(uint256)","7c63144e":"TokenUsed(uint8,uint8)","7c645c21":"getPlayerLength()","7c64ac43":"vestingEnds()","7c652e26":"CENT_DECIMALS()","7c654303":"isFunded()","7c65452c":"newValue()","7c65f503":"initVault()","7c66ae22":"play(uint256,uint256,address)","7c674695":"MarkedAsScam(address,address,uint256)","7c67fb9f":"MIN_STARTING_PRICE()","7c67fdf5":"bltOwnedAcc()","7c67ffe7":"ownerSetBankroll(address)","7c686c15":"setBonusPrice()","7c68e078":"_createMonster(uint256,uint256,uint256,uint256,uint256,bytes,address)","7c68ec4c":"_compareStrings(string,string)","7c695384":"bet(uint8,uint256)","7c699401":"getAllRevisionIpfsHashes(bytes32)","7c69b5d1":"NewDeposit(uint256)","7c69ef8d":"market2020TokenCreated()","7c6aafd1":"getRegularCarsForVariant(uint256)","7c6ac2af":"withdrawal_Lem(uint256)","7c6b2d6a":"setV_R1(uint256)","7c6b5b10":"amountFirst()","7c6bd3e8":"preGrant(address,uint256)","7c6bd96d":"extendStart(uint256)","7c6db9b5":"changeMinimumWei(uint256)","7c6e19a8":"UpdateTokenDailyExchangeAmount(address,address,uint256)","7c6e481c":"bancorChanger()","7c6e5809":"AEZtoken()","7c6e607d":"SuicideContract()","7c6e94e3":"migrationStarted()","7c6eb7bb":"generateNewRandom()","7c6fa5c2":"attackPrizeRatio(address)","7c6fb02a":"getCrydrViewStandardName()","7c6fb59d":"updateCreditBalance(address,uint256,uint256)","7c6fdec5":"getStrategyTokenPrice(uint256,uint256)","7c6fe7a9":"getAddressIdArray(address,uint256,string,string)","7c709fbe":"mxrjjToken()","7c70b205":"windowLength()","7c70c444":"DOXToken()","7c70e791":"removeInspector(address)","7c70e7fe":"currentRewardReleasePercentageRatePerYear()","7c71c0eb":"getIsProjectBonus()","7c72d868":"sendDividendsEthers()","7c72e273":"auctionFinalize(bytes32)","7c73f846":"getMinimumEndowment(uint256,uint256,uint256)","7c74d4d4":"JCCoin()","7c759d0d":"lock(address,uint256,uint256,uint256,uint256)","7c75c1b4":"distributeWithPolicy(address,uint256,uint8)","7c774111":"OF()","7c77b7c4":"getNumberOfDisputedDealsProDoctor()","7c77fad6":"AddMatch(string,string,uint256)","7c78cb13":"decrementQuantity(uint256)","7c7959e0":"CryptoNumismat()","7c796a83":"setGasUsage(uint256)","7c799e90":"str2bytes(string)","7c79c167":"stageHardcap(uint8)","7c79ebce":"expired(uint64)","7c7a52bf":"newChallenge(uint256,address)","7c7b0ff4":"getRide(uint256)","7c7b13b0":"PlayX50()","7c7c7695":"getAccountID(address)","7c7c7c3c":"SUPER_ADMIN()","7c7ce7df":"mintToPool(uint128,uint256,uint128)","7c7d14cf":"getPawnId(uint256)","7c7d809b":"saleEndUnixTime()","7c7dc098":"early_supporters_distribution(address[],address,address,uint256)","7c7dd391":"TokensWithdraw(address,address,uint256)","7c7ead51":"Wscchain(uint256,string,string)","7c7edd68":"PRHXToken()","7c7eeaa1":"hirerLastResortRefund(bytes16,address,address,uint256,uint256)","7c80bb4f":"getNameByAddress(address)","7c80feff":"getTokenIndicies(address,address[])","7c812015":"HedgeCoinCapitalToken()","7c81ff56":"TGE_SUPPLY()","7c8255db":"sendGifts(address[])","7c82a1d4":"reserveKY()","7c82eff7":"getZero(uint256)","7c831bd9":"rateCoefficient()","7c83b25c":"gettimelineandgoal()","7c83fdf7":"createFiatInvestorRequest(uint256)","7c842e5e":"updatePriceFromRealUnicornPrice()","7c84b40c":"makePrivate()","7c84c69b":"assertEq(bytes32,bytes32)","7c853cc1":"WithdrawFromKickTheCoin()","7c857566":"destructGame(address)","7c858e02":"smallestUnit()","7c85a757":"updateGooConfig(address)","7c85ab3a":"boardMemberCancel()","7c85df24":"setWHaddress(address)","7c871d31":"setIcoDates(uint256,uint256)","7c88e3d9":"mintBatch(address[],uint256[])","7c8af704":"resolveRound()","7c8b1fa2":"ShNShToken()","7c8c2234":"pushMilestone(uint16,string,string,uint64,bool)","7c8c6643":"unhint(bytes32)","7c8d56b8":"numeraiTransfer(address,uint256)","7c8db773":"CSE()","7c8dc575":"rejectConsent()","7c8de59a":"DCM(uint256,string,uint8,string)","7c8e040f":"confirmAtkBossQuest(address)","7c8e17e5":"teamOneTotalPlayers()","7c8e4e25":"credosReserveAccount()","7c8e8e69":"MarkLesterMiranda()","7c8f76a1":"issueTokens(address[],uint256[])","7c8f8278":"setTotalTokenSupply(uint256)","7c8ff8ac":"tokenProof(uint256)","7c905c9f":"preICOprice()","7c9143c9":"_hash(uint256,bytes32)","7c91e4eb":"DISTRIBUTION()","7c92a217":"c_MinFunds()","7c930a10":"ETHERECASHTOKEN(uint256,string,string)","7c935183":"test_deposit()","7c937700":"revokeAllVulnerable()","7c9473f6":"sellNoDecimals(address,uint256)","7c94830b":"kairosOwner()","7c9542bd":"LogWalletUpdated(address)","7c955583":"pendingWhitelistHash(address[])","7c95ef3f":"privatePlacementSupply()","7c9677be":"allocateTeamToken()","7c968f5d":"get_token_data_buyable(uint256)","7c96f680":"MyAdvancedToken(uint256)","7c97479b":"cardSupply()","7c976dbd":"tokenCreationCapOverall()","7c97ffe2":"DeusToken()","7c987ba4":"getMemberPayed(address)","7c989b45":"setBonus(uint256,uint256,uint256,uint256,uint256,uint256)","7c996d9e":"IndiaStocksCoin()","7c99922d":"founderTokensVested()","7c9b0892":"lnUpperBound(uint256,uint256)","7c9b387b":"maximumClaimPriceWei()","7c9c3d89":"mintCoinsForOldCollectibles(address,uint256,address)","7c9cbd38":"changeTeamTokens(address)","7c9cd7df":"changeDeveloper_only_Dev(address)","7c9d564f":"_pRand(uint256)","7c9d8bdb":"getBetsByCategory(bytes32)","7c9f4941":"SplitSend(address,address)","7c9fe2a7":"train2(uint256)","7ca005b3":"generateProof(string,address,address,uint8)","7ca013e6":"getRateToPxlAmount(uint256,uint256)","7ca01b2a":"getTestFour()","7ca1a66c":"resumeLotto()","7ca1cb48":"approveCurrencyTokenAddress(address,bool)","7ca21b37":"setMinPersonalCap(uint256)","7ca24d95":"changeEndTime(uint64)","7ca2795f":"AdvanceQueue()","7ca31724":"tokenId(address)","7ca54248":"lastSaleInHGT()","7ca55e00":"etherandomVerify(bytes32,bytes32,bytes32,uint256,uint256)","7ca5d8fa":"read_u8()","7ca60997":"rewardComment(address)","7ca63061":"LibraCreditNetwork(uint256,string,uint8,string)","7ca64683":"hasFiveStepWithdraw()","7ca823d5":"getAverageChainWork()","7ca828d0":"_canBreedWith(uint256,uint256)","7ca9429a":"getOfferCount(address,address)","7caae38c":"calluseraddress(address,address)","7cab5e8c":"removeApproval(address)","7cac4c7d":"JOY()","7cac9736":"computeResult()","7cad997f":"purchaseByEMONTImpl(uint16,uint256,uint64,address)","7cae6cb5":"determineEdition(uint256)","7cae8509":"delete_blockedAddress(address,address)","7caf3115":"MovieWorld()","7caf59d9":"addPullRequest(bytes32,bytes32,uint128)","7cb04b87":"running_id()","7cb070c7":"OPL()","7cb1442c":"f1(uint256,uint256)","7cb1bb0b":"setOraclizeGasExtraArtwork(uint32)","7cb25bc7":"dividendCount()","7cb2b79c":"setTokenManager(address)","7cb2c15b":"getTXdatabyCode(bytes32)","7cb34d2d":"register(bytes32,bytes32,bytes32,string)","7cb46307":"NewContent(bytes32)","7cb4e22a":"IEIP165()","7cb4ef0e":"getHashRateOf(address,uint256)","7cb51761":"setMaxPayments(uint256)","7cb56698":"rescueLostFighter(uint256,address)","7cb5d0ef":"Airchain(uint256,string,uint8,string)","7cb6a6b2":"generateContract(uint256,uint256)","7cb6b35d":"adjustLimitBetweenIssueAndNormal(uint256,bool)","7cb6cf3e":"ETH_SIGN_PREFIX()","7cb8adc7":"s9(bytes1)","7cb91d84":"slots_left()","7cb97b2b":"set_owner(address)","7cb9cf54":"removeSeller(address)","7cb9da88":"setIncludes(uint256,uint256)","7cba3f04":"PriceWeekThree()","7cbab0cb":"updatewallet(address)","7cbae071":"setPresalePerEth(uint256)","7cbb6934":"generateRandomNum()","7cbba335":"get_order_book_length(string)","7cbbf1da":"proofType_Native()","7cbc2373":"redeem(uint256,uint256)","7cbc4eb6":"lost(uint256)","7cbc6903":"totalBidCount()","7cbcc254":"__reset__()","7cbd3508":"_unpackExpValue(uint256)","7cbd5444":"isPriv()","7cbd9e8d":"existCaller(address)","7cbe0f32":"addOpenAction(string,string,string,string,string)","7cbe9e41":"DANKSIGNALS()","7cbf2bdc":"CapFlexed(uint32)","7cbfb8a5":"TransferTokens(address,uint256)","7cc07974":"HFTCrowdsale(address)","7cc08d53":"partProvider()","7cc0c3a7":"controllers()","7cc0e670":"freezeAccountForContract(address,bool)","7cc1303a":"trade(uint8[2],bytes32[4],uint256[7],address[6])","7cc1c640":"getActualPriceOfCardOnBuyAuction(uint256)","7cc1e28d":"setValidatorRewardPool(bytes32,uint256)","7cc1f867":"getContractInfo()","7cc2fe49":"setResourcesPrimaryManager(address)","7cc35d99":"historyIt()","7cc3ae8c":"endAt()","7cc3b48e":"withdrawKrowns(address,uint256)","7cc3beb2":"acceptArbiter()","7cc48875":"Slots()","7cc49427":"RemoveLock(address,uint256)","7cc4e55f":"lowestAskPrice()","7cc4ef14":"purchaseLand(uint256,uint256,uint256)","7cc589f9":"BlocklancerEmploymentContract(string,address)","7cc666da":"MoratoriumTransfers(uint256,address[],address[])","7cc9e4f0":"registerParticipant(address)","7ccaa9fa":"calcMerkle(bytes32[],uint256,uint256)","7ccc5aea":"DSPParametersChanged(address)","7ccc7e94":"inv_contract()","7ccce851":"isBlacklistedUser(address)","7ccd099d":"test_32_assertGasUsage100Boards()","7ccd3f79":"setAA(uint256)","7ccec110":"TestWorldSnapshot(uint256)","7ccefc52":"minimumMakerProtocolFee()","7ccf0d44":"_setAuctionObj(address,uint256,uint256)","7ccfd45a":"removeSubUser(address)","7cd022d4":"gen0PresaleLimit()","7cd07e47":"migrator()","7cd208b6":"requestRefunding()","7cd30fe3":"MarketingDevelopmentAddress()","7cd3229a":"board()","7cd3969d":"getUnsoldReceived(uint256,address,address)","7cd44272":"getConversionRate(address,address,uint256,uint256)","7cd4559c":"_rewardApprovers(address)","7cd49fde":"_counter()","7cd50577":"setTradable(bool)","7cd64c79":"AdvancedERC20(uint256,string,string)","7cd6a7fd":"setSettings(uint256)","7cd73941":"withdrawBAT(uint256)","7cd7c2bd":"setAnimalMeta(uint256,string)","7cd87ee9":"Libertax()","7cd9b0f8":"userHasHunterLicence(address)","7cda71a6":"preSaleTotalSupply()","7cdbae63":"addRegistryIntoTagsIndex(address)","7cdcc514":"replyThread(uint256,string,string)","7cdcdf23":"RenderTokenCrowdsale(uint256,uint256,uint256,uint256,address,address,address)","7cdd053a":"addRace(uint8,uint8,uint8)","7cdd8419":"getEtherPriceforDapp()","7cddc1de":"checkBonusTokenHoldingPeriodRemained(address)","7cde2a7e":"setCount(uint256,uint256)","7cdee6fb":"buySpaceship(uint16)","7cdef83c":"debtEngine()","7cdf6d0b":"TranslateME()","7cdf8ace":"adminCommand(uint8,address,uint256)","7ce01daf":"rollSystem(uint256,address)","7ce1b194":"ModernTokenPlus()","7ce1db53":"ShowNextCliff(address,uint256)","7ce1e2eb":"releasedBountyTokens()","7ce2432b":"lbrsToken()","7ce26195":"approveGame(address)","7ce2d863":"_calcCheckoutTime(uint256)","7ce335ac":"amountwon()","7ce3489b":"setFeePercent(uint256)","7ce50441":"updateTimer(uint256,uint256,uint256)","7ce52eb6":"distributePrizes()","7ce56303":"deployVestingContract(address,address,uint256,uint256,uint256,bool)","7ce5b85e":"transferBuy(address,uint256)","7ce5f9da":"DIYToken()","7ce645a6":"fundsAreAvailable()","7ce65725":"TEC()","7ce67d60":"initLoan()","7ce6e4ca":"getData_1()","7ce7c990":"transfer2(address,uint256)","7ce7d660":"CAF1(address)","7ce84784":"createtoken(string,string,uint256,address,address)","7ce85957":"setEthCollector(address)","7ce8e196":"test_claim()","7ce901e7":"TestContract(address)","7ceac0b8":"TokenSale(address,uint256,uint256)","7cead212":"dissolvedIndexToApproved(uint256)","7cec3a3a":"getBUS(bytes32,uint256)","7ced3d4c":"validArb2(address)","7ced55c2":"pvpPaused()","7cee8e70":"subTotalSponsored(address,address,uint256)","7cee919c":"getCurrentHash()","7cee9ee8":"placeBet(uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","7cef6047":"getNavHistory(uint256)","7cef6966":"addLaureato(string,string,string,bytes32)","7cefcc52":"burnedCount()","7cefd9f8":"initCrowdsale(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","7cf0ffcb":"forceDivestAll()","7cf12b90":"unFreeze()","7cf12ff8":"registryRequestSerialNumber()","7cf141fd":"removeGlobalAdmin(address,address)","7cf2b9e4":"updateVotingContractAddress(address)","7cf2f670":"Pinakion(address,address,uint256,string,uint8,string,bool)","7cf37493":"finalizeNOK()","7cf4c543":"createTransaction(uint256,address)","7cf52f3c":"getPrevRoundWinner(uint256)","7cf5d66f":"notifyTokensReceived(address,uint256)","7cf5dab0":"increment(uint256)","7cf62838":"EIP20ByteCode()","7cf6babf":"BasicSprout()","7cf6be2c":"createBid(bytes32,address,address,address,uint256,uint256,uint256)","7cf7b9f4":"determineDate()","7cf7e0e2":"VLCCoin()","7cf846c9":"registerManoContract(address,bool)","7cf90fcc":"addItem(address)","7cf99c33":"getIsMigratingFromLegacy()","7cfa1133":"Baxgold()","7cfb1e66":"TeamSum()","7cfb6052":"setPremium(int256)","7cfbc7a5":"setMaxBetAmount(uint256)","7cfe18c0":"internalCalculateEthersWithBonus(uint256)","7cfe19af":"A_Free_Ether_A_Day()","7cfe7a25":"BankhadCoin()","7cff33c7":"setMainSaleParameters(uint256,uint256,uint256)","7d007ac1":"setProposalDuration(uint256)","7d00818c":"allowedAddressesOf(address)","7d00848a":"getSinistre()","7d019f87":"isPreSaleClosed()","7d02bc1c":"getOldest()","7d02db72":"CryptoRUB()","7d036b0d":"finishProofPhase(uint256)","7d0381a7":"notify(address,uint256,uint8,uint8,uint8,uint256,uint256,bool)","7d0385c2":"createPromotionalRenewal(uint256,uint256)","7d03c394":"Logs2(uint256,uint256,uint256,uint256,uint256,uint256)","7d03e603":"GetUserExtraData2(address)","7d03f5f3":"newGame()","7d049675":"fechAllCandidatesByStage(uint256)","7d04d239":"setTokenMintApproveReset(address,address,address,address)","7d051cf3":"getTokensAcquired(address)","7d052a2e":"processReservationContribution(address,uint256)","7d06053b":"perturb(bytes32)","7d065c93":"getPayout()","7d075efb":"withdraw(address,address,address,bytes)","7d087715":"getwithdrawableAmount(address)","7d087f47":"gamblerevent(address,uint256)","7d091a7e":"pct(uint256,uint256,uint256)","7d094533":"announceVictory(string)","7d0981dd":"ModifyMine(address,bool,string,uint256)","7d09f560":"Equio(string,address,address,bytes32,uint256,uint256)","7d0a5e3b":"fightWIthMob(uint256,uint256)","7d0b4c8b":"withdrawEquity(uint256,bool)","7d0b4d60":"migrationEnded()","7d0bc9c6":"tier_action(uint8,uint256,uint256,uint8,uint256,uint256)","7d0bd79a":"publicSaleTokensPurchased()","7d0cf8b5":"Seele()","7d0e6aa9":"BitrootCoin()","7d0e6b6f":"setNextDiscountTTMTokenId1(uint64)","7d0e750d":"getMyTime()","7d0eb9b9":"RemoveVerifiedInfo(bytes32)","7d0f023d":"_deleteBytes(bytes32)","7d0f7528":"getFromList_(uint8,uint256)","7d1108f5":"getAssetData(uint256)","7d112d64":"authenticateVoter(string)","7d1157c8":"rawSendEther(bytes32)","7d1173b0":"DGAMEToken()","7d11f020":"oracleName()","7d124a02":"setRewardAddresses(address,address,address)","7d1286f6":"InterfaceId_ERC721Exists()","7d128d2e":"checkAgentSign(address,address,bytes32)","7d12b689":"checkPoolsDone()","7d136133":"SimpleATM()","7d13a256":"highFundingGoalReached()","7d14500a":"Sukiyaki()","7d14c8df":"setStaleTime(uint256)","7d150529":"countdownTimeLeft()","7d1541ad":"listDapp(string,string,string)","7d1710e4":"saleBalanceOf(address)","7d1842ec":"getPayeeBalance(bytes32,uint8)","7d18a197":"IndoAset()","7d19514d":"addFunds(uint256,uint256,bytes32,uint256)","7d19c777":"Emission(address,uint256,uint256,uint256,uint256,uint256)","7d19e292":"transferTokensToContractOwner(uint256)","7d19e596":"getEscrow(uint256)","7d19ec9d":"getUserAccount(bytes32)","7d1a6e3f":"compareTo(string,string)","7d1b2666":"fibokenCreatedCount()","7d1bd3ea":"setClientSupply(address,uint256,uint256)","7d1ca9fd":"setBeneficiary2(address)","7d1d0553":"convertToMiniUI(uint256)","7d1d7fb8":"settlementFee()","7d1e97a1":"cardTokenAddress()","7d1ea6d4":"m_token()","7d1f067c":"EthBankRoll(uint16)","7d1f561b":"set_pre_kyc_iconiq_bonus_denominator(uint256)","7d2026cd":"distributeWinnings()","7d2044cc":"AuctusStepVesting(address,uint256,uint256,uint256)","7d211c75":"peth()","7d21ce4d":"_Mint(address,uint256)","7d2211d6":"setStatus(string)","7d22e9df":"clearAllocatedAndSalaryTokens(address,address)","7d22f431":"delegatePercent(uint256,uint256,uint256)","7d230dfd":"wedding()","7d236928":"getGenesMarketAddress()","7d2402d6":"inPresale()","7d240b9c":"setLockToken(bool)","7d2429a8":"long_party()","7d242ae5":"setBasePrice(uint256,bytes)","7d24a8a1":"returnToken(address,uint256)","7d24cd18":"onExecuteMessage(address,uint256)","7d25d7cd":"tokensToTransfer(bytes32,address,address,address,uint256,bytes,bytes)","7d263245":"COOLDOWN_TIME()","7d264bad":"adexTeamAddress()","7d268ac1":"ArtworkCore()","7d27ecf9":"phase1TokenSold()","7d287697":"testTryGetUnset()","7d298ee3":"beforeExecute(address,uint256)","7d29beff":"placeVoxel(uint8,uint8,uint8,uint8)","7d29f868":"ChangeUSDto1ETH(uint256)","7d2a0f7a":"isWhiteListedValueValid(address,uint256)","7d2a47b9":"findShareholder(address)","7d2aeb8a":"releaseVestedTokens(uint256)","7d2b9cc0":"setRequiredSignatures(uint256)","7d2c93d7":"validateTypeReference(uint256,bool)","7d2d661f":"genLimit(uint256)","7d2d92ac":"withdrawTheUnsoldTokens()","7d2dfc30":"FourCrowdsale(uint256,uint256,uint256,uint256,address,address)","7d2f42c3":"updateRating(address,bool)","7d309331":"Bitceun()","7d3157bf":"confirmBeneficiary(uint256)","7d320ef8":"proofStorage_IPFS()","7d326635":"getLendingObjId(address,uint256)","7d32e7bd":"transfer(address,bytes32)","7d34c2e3":"setMarketingAndRNR(address)","7d34f5ac":"dailyTotals(uint256)","7d3533da":"ownerSetAllowPublicWithdraw(bool)","7d35f656":"count_customer_deposits()","7d363718":"BitcoinXChainToken()","7d363720":"getCurrentBonusFactor()","7d368f88":"afterEnded()","7d36e478":"ClaimBalance(address,uint256)","7d37fcba":"setManagementContractAddress(bool,address)","7d380265":"addOptionChain(uint256,string,uint256,uint256,bytes32,address,int256[])","7d38a772":"updateDeveloperMiningPower(uint256)","7d394f90":"addMasternode(address)","7d398a86":"SourceChanged(string,string,uint256)","7d3b2d81":"PayXToList(address[],uint256)","7d3bfaee":"withdrawSurprisePotUser(uint256,uint256,uint8,bytes32,bytes32)","7d3c42d2":"EtherBrosMaker()","7d3c5961":"middleTimestamp()","7d3c6da5":"CreateLudumTokens(address,uint256)","7d3d220d":"CitizenOne(uint256,address,uint256)","7d3d6522":"goalReached()","7d3dcbc3":"setTRM1BonusActive(bool)","7d3ee409":"setPatient(string,uint256,address,string,string,uint256,uint256)","7d3fa29e":"addressToGoldDeposit(address)","7d3fcaff":"getMatchReport(uint256)","7d40189a":"timeAdjustPlus()","7d40583d":"setRoleCapability(uint8,address,bytes4,bool)","7d408b44":"getMemberTokenRemain(address)","7d40e9e0":"purchasedAmountOf(address)","7d40eb25":"TITANCORE()","7d4120a9":"insChainToken()","7d41cc60":"modifyAuthorizedCaller(address,address)","7d426826":"INTREPID_VOUCHER_PRICE()","7d42af97":"PrivateSaleEndTime()","7d436d76":"consume(bytes32,bytes32[])","7d443e57":"getInitInfo()","7d445654":"lastLargestHODLERBalance()","7d4504e0":"totalETHraised()","7d451aa7":"zgetOwner()","7d457ac3":"CompensationSentEvent(address,uint256)","7d459c71":"Multiexshares()","7d46702b":"icoCollected()","7d472f1c":"xnotifications(uint256)","7d475c32":"LogAccessPolicyChanged(address,address,address)","7d478407":"gameEncryptedText()","7d47b4e7":"setAIRDROPPrice(uint256)","7d48441f":"_isContract(address)","7d487532":"setMember(bytes32,address,bool)","7d48dcd7":"onPurchase(address,address,uint256,uint256,uint256)","7d49300d":"initGame(address,uint256,uint256,uint256)","7d49e51d":"getSpaceshipUpgradePriceByModel(uint16,uint8)","7d4a899e":"SafeSender()","7d4af159":"marketMakerFee()","7d4c1403":"get(address,address,string)","7d4c258a":"Set(bytes32)","7d4c4a04":"saleStartSecondDayEnd()","7d4cb964":"MAX_ENTRIES()","7d4ce874":"maxInvEth()","7d4cf602":"buildDSBalanceDB()","7d4d3128":"startTransferToken()","7d4d42c5":"_addGraffiti(uint256,string,string)","7d4da754":"CoiinToken(address)","7d4deda1":"setAirLimitCount(uint32)","7d4e1353":"erc20TRFT(uint8)","7d4e1eb0":"stop_game()","7d4f0406":"PPY(uint256,string,string)","7d4f128b":"createLockTokenHistory(address,uint256,uint256)","7d4f1883":"closeMonthlyInvest()","7d50bef3":"account(address,address,uint256)","7d5224d3":"registerNewUser(address)","7d53223a":"setVestingReleasedAmount(address,address,uint256)","7d53409a":"setMaxbonds(uint256)","7d534aa0":"disableCharity()","7d549e99":"totalTokensMinted()","7d54a3ba":"CROWD_WAVE1_PERIOD()","7d55094d":"toggleMinting()","7d55758f":"underMint(address,uint256)","7d55923d":"click()","7d55f64d":"fixedFeeInWei()","7d564056":"getUserProperty()","7d564f11":"setsystemprice(uint256)","7d574678":"setICOIsFinished()","7d57a85c":"preIcoFinish()","7d57edf3":"HOPE(uint256,string,string)","7d580939":"_HOLDersPayRoll()","7d58eb76":"hasResolver(string,address)","7d59a938":"month6companyUnlock()","7d5a9b41":"init(uint256,uint256,address,uint256,uint256,uint256,address,uint256)","7d5bc9fe":"Account_balances(address)","7d5c1914":"getWalletInfo(address)","7d5db5e0":"Dagelas()","7d5dc538":"getToJackpot(uint256,uint256)","7d5dec2a":"multiplex_remove(address)","7d5f66f2":"mintBounties()","7d5fbcab":"setMystr(string)","7d5fec5a":"setOwner(uint8,uint8,address)","7d606100":"BetOverlap()","7d60b6ce":"setCommissionWallet(address)","7d60e291":"FIFTY_THOUSANDS_LIMIT()","7d60e343":"getFileListSize()","7d619d9b":"holdCoin(address,address)","7d61b9fe":"intervalsCount(bytes32)","7d61de37":"foundersRewardTime()","7d620130":"getCardCount()","7d635502":"buyEgg()","7d636d9b":"refferal(address)","7d63a93a":"REKT(uint256,address)","7d64bcb4":"finishMinting()","7d652335":"changeAssetsState(bool)","7d656a72":"NewPost(bytes32,uint256)","7d65b2f7":"hasCompleted()","7d65e3fe":"totalInterestCycles()","7d661e3c":"giveToken(address,uint256,string)","7d6651b9":"claimEthIfFailed()","7d683b95":"unsoldUnlockedAt()","7d684a9d":"RENEEKROM(address,address,address,uint256,uint256,uint256)","7d68582a":"manuallyExchangeContractPreDGZtoDGZ(address,uint256)","7d68bee7":"LogPollDeleted(bytes32)","7d692faf":"readMailByAdmin(uint256,bytes16)","7d6979e7":"canBeChanged(uint256)","7d69880b":"addBalance(uint256,uint256,uint256)","7d69f335":"changeColorRed()","7d6a59ed":"getInvoiceCount()","7d6a5f7b":"requireNotPaused()","7d6ad4cd":"triggerAutorelease()","7d6b4278":"outcomeState(address,uint256,uint256)","7d6bc260":"maxTiers()","7d6c1ff1":"addMake(address,uint256,uint256)","7d6c8388":"INVECH(uint256,string,string)","7d6c864e":"withDrawable()","7d6cf2df":"get_deploy_fee()","7d6d28ef":"setComisionInTokens()","7d6dc737":"getBylawsMinTimeInTheFutureForMeetingCreation()","7d6e061c":"getFinishDates()","7d6e3751":"_addVouchers(address,uint256)","7d6ebe94":"setDoubleClaimSegmentSlashAmount(uint256)","7d6f0d5f":"changeFundsWallet(address)","7d6f174e":"invalidateSignature(uint8,bytes32,bytes32)","7d6f3781":"userChallenge()","7d6fb089":"setBGXTokenInterface(address)","7d7106ad":"_updateStats(uint256,uint256)","7d71a19b":"setAccountInfo(address,address)","7d720296":"airSender()","7d722a30":"Funding_Setting_cashback_before_start_wait_duration()","7d72aa65":"addRole(address,string)","7d736d0d":"weekPotExpiration()","7d7452aa":"DSVCoin()","7d7714fb":"coinAllowance(address,address)","7d7786a3":"GetGuestName()","7d77c8f9":"allowTransferBetweenUsers()","7d780e2a":"blocked_amounts(address)","7d78b94d":"claimNihilum()","7d78ef4a":"BKKToken()","7d790630":"setContractFrozen(bool)","7d79265b":"REDEEM_METHOD()","7d79c192":"awayTeam()","7d7a1a80":"UCToken(uint256,string,string)","7d7a31b6":"max(uint64,uint64)","7d7a3a1a":"bittravelxToken()","7d7a9ca4":"MachineToken()","7d7b0099":"API()","7d7b2051":"finalizeExits(address)","7d7be90f":"Splitter(address[])","7d7c2a1c":"rebalance()","7d7c7258":"adminSendMoneyToUser(address,uint256)","7d7ca00c":"JSONpath_int(int256,string,string,uint256)","7d7d4a68":"start_service(address)","7d7e5e3d":"setFlagPair(uint256,bool,bool)","7d7eee42":"setPreSalePrice(uint256)","7d7f0050":"TradeEnabled(bool)","7d7f1699":"freeBet(address)","7d7fa215":"getSaleData()","7d7fef7e":"receivedEtherFrom(address)","7d802655":"delLimitedWalletAddress(address)","7d80def3":"setENDPhase()","7d81d62f":"doGroupRefundPayoutsSuccess(address[])","7d820414":"GeXCHANGE()","7d82bf73":"getBonusTokens(uint8)","7d836281":"getBetState(address)","7d83e527":"PensionCoin()","7d851a13":"signerIsWhitelisted(bytes32,bytes)","7d851c70":"getTokensBack()","7d85445d":"EducationToken()","7d85facd":"transferred()","7d862a7e":"changeDutchIdxAddr(address)","7d87bb7b":"HATCHING_COST()","7d87e97d":"makeMemberOfGroup(address,uint256)","7d882097":"totalDeposits()","7d882e9b":"resetWinner()","7d886976":"testMintGuyAuth(int256)","7d8966e4":"toggleSale()","7d8978db":"addCasino(uint16,uint256,string,string)","7d897ccd":"KPCSAdministrator()","7d89ae63":"__findRef(string)","7d89f040":"AddAmount(uint256)","7d8be627":"activateLineItem()","7d8c0c7c":"adminSetRegisterCost(uint256)","7d8ccd59":"debug_uint(uint256)","7d8cfd1a":"flag_hash()","7d8d4878":"updateETHEUR(uint256)","7d8f442e":"getPrice(uint40)","7d8f94a0":"slackUsersCap()","7d8fcfb4":"transferSuperAdminOwnership(address)","7d8fe090":"REFERRAL_BONUS_LEVEL5()","7d902311":"gameGiftLineTime()","7d917fcb":"Registered(bytes32,address)","7d919a43":"tohash(bytes32,address,address,uint256,uint8,bytes32,bytes32)","7d91da87":"buyPixelTokenFor(uint24,uint256,uint24,address)","7d9201cc":"rspToken()","7d921af0":"disableTimelock()","7d92561d":"NewBuyer(address,uint256,uint256)","7d92654c":"endRoundAndStartNextRound()","7d92bb6e":"getClaimKeys()","7d92f6be":"goldRegistry()","7d9375b8":"authorizeContract(address,string)","7d9383c3":"valid_creature(address)","7d93ccdf":"Halo3DDoublr(uint256,address)","7d940912":"addArea(uint256,uint8,uint8[],uint256,string,uint256,bool,uint32)","7d94792a":"seed()","7d94d4aa":"SergeToken()","7d95dcd7":"createPromoArtwork(string,string,uint32,address)","7d961218":"REGTMProc()","7d96f693":"getDepositAmount()","7d97597d":"DEFAULT_AUCTION_LENGTH()","7d97b1f6":"VestingScheme()","7d98ebac":"exchange(address,address,address,address,uint256,bytes)","7d9a4e2c":"safeToMultiply(uint256,uint256)","7d9a9046":"resolveDisputeBuyer(string)","7d9a9096":"icoFinishedAt()","7d9c68f7":"getUserBattleValue(address)","7d9d4bed":"secondStageEnd()","7d9d972d":"guardian3Vote()","7d9e5243":"BonusAmountUpdated(uint256)","7d9f298e":"setLockedState(bool)","7d9f6db5":"auction()","7d9f8cf2":"startFirstStage()","7d9fb742":"fourthRoundPercent()","7d9fc342":"PreICODays()","7da028d6":"SaleCompleted(address,uint256,uint256)","7da0389d":"referralProgram(address[],uint256[],uint256)","7da0399a":"CloseAuction(bytes32)","7da0e079":"_closeMotion(uint256)","7da16762":"executeParentDaoSplit()","7da208aa":"deleteArrayAddress(bytes32,uint256)","7da21a1a":"WaltonToken()","7da25928":"announcedTimeStamp()","7da3400b":"_contractExists(bytes32)","7da39157":"poWtfContract()","7da3c3ab":"revert()","7da3e219":"testInitialTokenBalance()","7da3f613":"lockAddress()","7da40b65":"isPlatformOrSupportManager(address)","7da4d24b":"activationOpen()","7da5efc8":"drop(address,address[],uint256[])","7da63c59":"changeValuePerToken(uint256)","7da7a437":"Clinicoin()","7da7d5ab":"nextGameRakePercent()","7da81364":"getProposalAction(uint256)","7daa10ce":"getMyInfo()","7daa9fcd":"buyGems()","7dab61b6":"setBlack(bool)","7dab84d8":"ShowTestU(string,uint256)","7dabb4d6":"addKycVerifiedInvestor(address)","7dac0547":"VIRGOToken()","7dac9048":"addArgumentToRequestUint(uint256,bytes32,uint256)","7dae6e95":"noOfTokenAlocatedPerICOPhase()","7daeef25":"objectTome()","7daf06fd":"withdrawPart(uint256)","7db0799f":"EnduranceToken()","7db12abc":"contractorWithdraw()","7db1c36f":"setFeedBackFee(string,uint256)","7db2cff8":"old_address()","7db33f99":"setLeaseCard(uint8,uint256,uint256)","7db4149d":"RegisterTokenTransaction(address,uint256,address)","7db42b6c":"AutoBusinessFinance()","7db45975":"register(uint256,uint256,bytes32,string,bytes32)","7db48416":"_getMinions(uint256)","7db6a91d":"checkDeck(uint8[],bytes32,bytes32)","7db6cbfc":"_addDefaultOperator(address)","7db724b6":"MAIN_QUESTION()","7db7c239":"tranchesPayedOut()","7db8782a":"uint256At(uint256,bytes,uint256)","7db91595":"setOwnedBonus()","7db9743b":"Registry()","7dbb82a8":"setLicenseTermsRegistry(address)","7dbbc0cd":"EliteShipperToken()","7dbbf2e6":"RecallTokensFromContract()","7dbc1d6f":"modifyPrivateList(address[],bool)","7dbc827b":"vestingWithdraw(address,uint256,uint256)","7dbc9fba":"amendClaim(uint8,uint8,uint8,uint8)","7dbd0139":"softCapOk()","7dbdab18":"CreatedAngel(uint64)","7dbdc2eb":"getQueryPrice()","7dbdf168":"EtherBetIO(address,address)","7dbecc54":"EDColiseum()","7dbece3c":"usdCurrencyFunding()","7dbedad5":"createReward(uint256,uint256)","7dbf1fe6":"Towers(uint256)","7dbf67a7":"setDebt(uint256)","7dbff420":"donationUnlockTs()","7dc0015d":"centToken()","7dc09e4a":"getRequestedProducts()","7dc0d1d0":"oracle()","7dc0d451":"CHINESE_EXCHANGE_2()","7dc10df5":"Jackpot(address,uint256,uint256,uint256)","7dc2268c":"minting()","7dc28eb2":"LOCKAMOUNT4()","7dc379fa":"getTicket(uint256)","7dc45e27":"setCryptoMatchValue(uint256,string)","7dc4feb7":"setConstraint(bytes32,address,address,uint256)","7dc5cc64":"getTotalDivis(uint256)","7dc5cd32":"_patternToNumber(bytes)","7dc673bc":"closeRegistration()","7dc6c3d9":"deactivateAdSlot()","7dc7363b":"LogNewTemplateProposal(address,address,address,uint256)","7dc74473":"tokenPrivateMax()","7dc79375":"delOracle(address)","7dc7c5a5":"debug1()","7dc7f7c4":"Pitcheum()","7dc8c73e":"canTokenUnlocked(uint256)","7dc8e069":"shorten_end_block(uint256)","7dc8f086":"getOutcomeCount()","7dcaf720":"getReadme()","7dcb422e":"setPresaleStartDate(uint32)","7dcb6b92":"testegy()","7dcbd078":"thirdPay()","7dcc3f0c":"LukapToken()","7dccd4d6":"setIndividualCertificate(string,bytes32,bytes32,bytes32)","7dcd17d9":"sumHardCapICO1()","7dcd277b":"SimpleTingToken()","7dcda7df":"initiateProviderCurve(bytes32,int256,int256[],address)","7dcdace2":"Deposit(address,uint256,uint256,bool,string)","7dce4595":"sendToken(address,uint256,string)","7dce6bdb":"freeCrawDeadline()","7dce8461":"GSENetwork()","7dce8dd4":"GenesisSalesCount()","7dcfb801":"veryAngry()","7dcfd3d5":"blockTransfers()","7dd003f1":"test_chain2_4()","7dd02c8e":"transferETHFromContract(address,uint256)","7dd07097":"tgeSettingsPartProject()","7dd0d61c":"check_hash(address,bytes32,bytes32)","7dd10e4f":"newUsers()","7dd15d40":"getData_13()","7dd1f126":"optionTaker(bytes32)","7dd256ff":"PATToken(address)","7dd26660":"getMegaboxIndex()","7dd2899f":"changeDividentContract(address)","7dd2e993":"removeTenant(uint256)","7dd3cf54":"ChangeCostByManager(uint256)","7dd45999":"lockDomainOwnershipTransfers()","7dd563c3":"setMainSaleParams(uint256,uint256,uint256,uint256)","7dd56411":"ownerOf(bytes32)","7dd91734":"compositeReputation(string)","7dd9d27f":"exiteEntidad(address)","7dd9f846":"buyCard(address,uint256)","7dd9fcf7":"latestprice()","7dda48a5":"WhatTimeIsNow()","7ddaa56a":"tokenContributionMin()","7ddb3c00":"total_pay_claimed()","7ddb5e65":"votingReward()","7ddbf0ed":"setLockedTokenAddress(address)","7ddbf1a7":"passFundsToTheTeam()","7ddc02d4":"isOwner(address,address)","7ddcbfd9":"TegTokensSale(uint256,string,string)","7ddd0ce1":"getBetDivisor(uint256)","7ddd130f":"PRBCoin()","7ddd20ba":"getRequiredStateNumbers(uint256)","7dddb66f":"collectOwnRew()","7dde0138":"modifySupplyLimit(uint256)","7ddfffbf":"mint(address,uint256,uint256,uint256,uint256,uint256,uint256)","7de06cfc":"startTge()","7de09476":"getSpecificBuyerTransaction(address,address,uint256)","7de0cc65":"preMcFlyWallet()","7de14129":"approveInvestor(address)","7de1a631":"confirmETH(bytes32)","7de295d2":"withdrawalsCTR()","7de2d523":"setbonus(uint256,uint256)","7de2e95c":"TransferCow(address,uint256)","7de2fe4d":"linkToMasterWalletInternal(address,address)","7de32b17":"CuratedTransfers(address,address[],address[])","7de36138":"setPreICO(address)","7de47b3f":"fundingGoalUSD()","7de4800f":"withdrawEscrow(bytes32)","7de480c6":"aiurExchangeOracle()","7de4ceb2":"DebugValue(string,uint256)","7de50c44":"TIME_LOCK_END()","7de548d8":"releaseStake(uint256,address,address)","7de576cd":"vote(uint16,uint256)","7de5ad89":"setJntController(address)","7de6c905":"LetItPlayToken(address,address,address,address,address,address,address,address)","7de77700":"bytes32ToBytes(bytes32,bytes32[],bytes32)","7de7a18d":"setShare(address)","7de7ea78":"TokenHNC(uint256,string,string)","7de7edef":"changeMasterCopy(address)","7de8bb63":"Commons()","7de976dc":"amountFundHolder()","7de9f212":"colorfilter(uint256)","7dea9118":"setIdentityName(bytes32)","7deb6025":"buy(uint256,address)","7debb959":"calculateAllocation(address)","7dec2299":"getStagesInfo()","7dec3d35":"FOUNDERS_WALLET()","7dec4ce8":"SettleBond(uint256)","7ded2210":"setPreIcoCap(uint256)","7dee2cad":"CancelMyInvestment()","7def2fdf":"changeStakeRate(address,bytes32,uint256)","7def7351":"teamTokensFirstShare()","7df02c0e":"getLinglongCat(uint256)","7df042a2":"totalRegularTokensSold()","7df19a78":"BetPlaced(address,uint256,uint8)","7df1f1b9":"borrower()","7df23b6a":"ReleaseOracle(address[])","7df2e3e3":"getRcdExchange(uint256)","7df38c5b":"wad()","7df3a229":"PissToken()","7df432c9":"minSelfBuyPrice()","7df4732e":"seeZombieStar(uint256)","7df47407":"SigProof()","7df4c235":"kolidat()","7df52ba8":"Arbitrate(uint32,uint32,bool)","7df545c7":"MaximumSellableTokensChanged(uint256)","7df54c73":"setMiniPoolEdit_4(string)","7df5f4ae":"_upper(bytes1)","7df65a1d":"getMinersByAddress(address,address)","7df68a8b":"addPeriod(uint256)","7df73e27":"isSigner(address)","7df7ec18":"test_invalidEmptyEqVal()","7df82cc9":"veztUsers(uint256)","7df83cd0":"getDepositWithdrawList(address,uint256[])","7df841cd":"setPlayerVirusDef(address,uint256)","7df855f2":"getAuditAddress(address,address)","7df8833a":"createEvent(string,uint256,uint32)","7df9bb31":"heredar()","7dfa0b3f":"canSell(address,uint8,uint8)","7dfa7d79":"claimUnsoldTokens()","7dfac5a2":"accMinterOne()","7dfb0ba5":"getRecordOffers(address)","7dfb6626":"withdrawRewards(bytes32)","7dfbc19c":"HaltTime()","7dfbdf6d":"returnFundsFor(address)","7dfc64ca":"getTotalBudget()","7dfce5e9":"withdrawExcessReserves()","7dfce6d7":"MAX_INTEREST_AMOUNT()","7dfda44c":"AssignAddress(uint256)","7dfe1674":"CTB(uint256,string,string)","7dfe4302":"privateSaleTokens(uint256,uint256)","7dfe7741":"InviteAccepted(address,address)","7dfebff3":"addEth(uint256,uint256)","7e007c1e":"minimumWEI()","7e00d6d6":"enablePurchase()","7e00d77a":"mintExtendedTokens()","7e01c088":"removeWhitelistedAddr(address)","7e029bde":"setEthUsd(uint256)","7e02bb0f":"finish(address,address,address)","7e03ad1a":"numImports()","7e057b8e":"IYMAYA()","7e06ec93":"MDOSToken(address,address)","7e070df6":"rootOwnerOf_(uint256)","7e07877a":"hasFailed(address,uint256)","7e080911":"TRUEToken(address)","7e08a846":"tokenCollectedOf(uint256,address)","7e09d09b":"theFloatMultiplier(uint256)","7e09f0aa":"predictMarket()","7e0a16b1":"forwardAllRaisedFunds()","7e0be7e3":"upgradeGooCost(uint256)","7e0c1792":"oracle_address()","7e0c240d":"LianJieToken()","7e0cfc3d":"truncate(uint8[],uint8)","7e0d149e":"getGameAddresses(uint256)","7e0d8b27":"leekStealToday_()","7e0e20ba":"HighGasAmount()","7e0e471d":"Licensium(uint256,string,uint8,string)","7e0f7a87":"getUnixTimeStamp()","7e1028b2":"_doTradeWithEth(address,uint256,address,uint256)","7e1055b6":"icoEndTime()","7e111f59":"sell_toContract(uint256)","7e11f453":"ETH_Rate()","7e12180e":"setSaleDuration(uint256)","7e133564":"donateDna(address,uint256,uint8)","7e13b0be":"changeTokenDecimals(uint256)","7e150d66":"maxTxSize()","7e1629ab":"token_transfer(address,address,uint256,bytes,string)","7e167198":"_preValidatePurchase(address,uint8,uint256)","7e168086":"preallocate(address,address,address,address)","7e16cfde":"getGameBlockNumber(uint256)","7e16eca0":"getContractTimestamps(bytes32)","7e1721ee":"LMAOtoken()","7e179816":"setRefShare(uint256)","7e18dd21":"motodoughToken()","7e1934f9":"swpFund()","7e199b70":"startCrowd(uint256,uint256,uint256)","7e1a6753":"Destruct()","7e1ab812":"utrToken()","7e1b52f6":"doftManager()","7e1c06b6":"newOwner(uint256)","7e1c0c09":"totalTokens()","7e1c4205":"query2(uint256,string,string,string,uint256)","7e1cae40":"changeRefundToken()","7e1cb559":"members(bytes32,address)","7e1cd79c":"Voting(bytes32[])","7e1db495":"addPendingWithdrawl(uint256,address,bool,bool)","7e1db516":"init3_block_height()","7e1e06ea":"EventTransferWasReset()","7e1e1ff6":"Giorgi()","7e1e447e":"total_wins_count()","7e1f2bb8":"createTokens(uint256)","7e1f89c8":"PRE_SALE_START()","7e20e7c0":"getRegistryDataMinter()","7e2224bd":"compress(bytes)","7e23f7cd":"teamKeepingLockEndBlock()","7e241c64":"getServiceNameByAddress(bytes32,address,address)","7e241dbf":"unlockMiner()","7e245fac":"PHXTKN()","7e24cb8f":"reservedFundLeft()","7e25ac5b":"destroyRewards()","7e25b7d6":"implements(address,bytes4)","7e266385":"setPrefix(uint8)","7e26639f":"saleLimit()","7e27133f":"tradingMonDataContract()","7e274f7e":"Reederem(string)","7e288822":"pendingWithdrawal()","7e298249":"setPriceInWei(uint256,uint256)","7e29d2a3":"TokenCoin4()","7e29dad0":"testBuyExceedHardLimit()","7e29f242":"changeDiscount(uint256,uint256,uint256,uint256)","7e2a0141":"removeToken(address[16],address,uint256)","7e2a6db8":"trusted()","7e2ac454":"disagree(bytes32,bytes32,bytes32[])","7e2bc821":"SaturnPresale(address,address,uint256,uint256,uint256)","7e2bef39":"calldata(uint256)","7e2bf3c6":"freezeCreditScore(address,uint256,string)","7e2c0459":"_transfer(bytes32,bytes32,uint256)","7e2c83fc":"seriesByAddress()","7e2ce380":"_calculateOwnerCut(uint256)","7e2e3958":"setBUS(bytes32,uint256,string)","7e2e756e":"testToUint32()","7e2f014f":"addResolversDelegated(string,address[],uint256[],uint8,bytes32,bytes32,uint256)","7e2f6e3b":"getReserveSupply()","7e2fc2b6":"_Crowdsale(address,uint256,uint256,address)","7e2fdb0c":"dataForBuy(address)","7e2ff5f9":"setPreSale()","7e300fc6":"crowsaleShare()","7e31c53a":"HodlWithdrawn(uint256,address,uint256)","7e32456d":"STRC_SUPPLY()","7e327168":"allocatePresaleTokens(address,string,uint256,string)","7e32a592":"repairTheCastle()","7e32baea":"TRIPToken()","7e32fc47":"registerAsset(string,bytes32)","7e331a99":"setUserMessage(string)","7e33e361":"setRowQuiter(bool)","7e340b01":"getLatestPayday(address,address)","7e342507":"gameIndexToBuy()","7e3475a8":"lockQtyToAllowTrading()","7e347b82":"REALCrowdsaleMock()","7e34dbe0":"deposit(uint256,uint256,uint8,bytes32,bytes32)","7e363ffa":"setupCost()","7e36edce":"RATE_DAY_28()","7e373bc0":"bulletAmount()","7e380099":"addOrgCertificate(string)","7e38b424":"reverseFiatPurchase(uint256)","7e38d065":"ADVISORS_AND_CONTRIBUTORS_TOKENS()","7e39082f":"escrowedMYB(address)","7e3bfa1d":"removeRecoveryAddress(address)","7e3d15ae":"nextHolder(address)","7e3d45ef":"gameMiningToken(uint16)","7e3d8813":"setup(address,uint256,uint256,uint8)","7e3da027":"approveAndCustomCall(address,uint256,bytes,bytes4)","7e3dbf96":"addr(bytes,bytes)","7e3df726":"EZEtherMarketplace()","7e3e40ec":"getRequiresKing(bytes)","7e3e7bdf":"checkReward(address,uint256,uint256)","7e3ef7cd":"getMyBalance(address)","7e3ef935":"setReleaseMake(uint256,bool)","7e3f2b2d":"getDocumentSignsCount(uint256)","7e3f5b70":"JFBToken()","7e3faec1":"GoldTxFeePool(address,address,bytes)","7e402eb0":"setSecondAdmin(address)","7e410427":"aDay()","7e4115ba":"toAddress(string)","7e4241b4":"ownerTake(uint256,address)","7e429f02":"burnMultDen()","7e42be1a":"quarantineAddress(address)","7e42f8b4":"setRefund(bool)","7e42f94d":"horsePr(uint256)","7e43185a":"showCollectorsAddresses()","7e4358c3":"used_in_contract_fees()","7e43828e":"bountyTokenWithdrawal()","7e441048":"hasCategory(address,uint256,uint256)","7e445d44":"setEndICO(uint256)","7e456808":"reclaimUnusedEtherBalance()","7e457b85":"startEarlyStage3()","7e458492":"addInspector(address)","7e45d15c":"___coinAddress()","7e466bb4":"forTeamCOT()","7e470882":"setStrF1(string)","7e482379":"totalEthInWeiForSecondIco()","7e4929c4":"priceBox2()","7e4930ae":"modifyCap(uint256)","7e495dae":"changeMinters(address,address,address)","7e4985c5":"LookUpAvailableDivLarge(address)","7e49aa05":"testSelfdestructIsRevertedWithMinReturn()","7e49d530":"fechVoteMainInfoBySnapshotBlock(uint256)","7e4a1731":"returnWallet()","7e4a82b1":"foreignBuyTest(uint256,uint256)","7e4b5eb5":"getPhControlLimits(bytes32)","7e4c3b2e":"requestRate(string,string,bool,uint256,uint256)","7e4d25c5":"Refundably_if_gasprice_more50gwei_Send_Votes_From_Your_Balance(address,uint256)","7e4d4495":"getEthCapPerAddress()","7e4d4653":"echoTest(uint256)","7e4d5ea1":"STARTDATE()","7e4e95d7":"airDropPercent_()","7e4eb35b":"left43(uint256)","7e4f1a9f":"AKMJCHAIN()","7e4f6b95":"MyAdvancedToken(uint256,string,string)","7e4f9397":"gSetAlive(bool)","7e4fdd0b":"SetherStarted()","7e545305":"firstBalance(address)","7e5465ba":"approve(address,address)","7e549814":"setEscrowedProjectPayees(uint256,address)","7e54b8e2":"AddCandidate(string)","7e551b75":"hashOf(uint256)","7e55a212":"JustTheTipCrowdsale(uint256,uint256,uint256,address)","7e55a311":"getPurchaseSeconds()","7e55b83c":"readValidDate(uint8)","7e55ec25":"CryptoPokemon()","7e569e66":"TDEContributorCount()","7e56d25f":"ReplyShare(uint256,string,bool,string)","7e56fde5":"calculateEggBuySimple(uint256)","7e5713d9":"setGenesisAddressArray(address[])","7e574098":"confirmEthTransactionRequest()","7e575524":"poolMintAmount()","7e577274":"onAuctionEnd(bytes32)","7e580d30":"ZCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","7e58f815":"pauseRoundA()","7e59092e":"getVersionById(uint256)","7e5912d7":"reputationHashSubmissions(address)","7e59d513":"deathData_f1()","7e5a4dde":"getMarriage(uint256)","7e5a66df":"uniqueSpinnerOwners(uint256)","7e5a9ed9":"updateHpbNodeBatch(address[],bytes32[],bytes32[],bytes32[])","7e5af26c":"BugisContract()","7e5b1cdd":"GOToken()","7e5c344a":"Upgrade(address,address,uint256)","7e5c86a2":"moveFundToOwner(uint256)","7e5cd5c1":"disableMinting()","7e5e190c":"getBaseTypeStats(uint256)","7e5fc6f4":"calculateIcoBonus(uint256,uint256,uint256)","7e600c87":"doSend(address,address,address,uint256,bytes,bytes,bool)","7e602078":"assertInvalidState(address)","7e60a4bf":"removeLockFunds(address[])","7e61c768":"isClient(address,address)","7e61e6ef":"GasWar()","7e621667":"sendFromOwn(address,uint256)","7e626e58":"getUnPurchasedProducts()","7e62eab8":"withdraw(int256)","7e638974":"CalculateFinalDistance(bytes32,bytes32,bytes32,bytes32)","7e63dd86":"seed_additional_token(uint256)","7e6503bb":"getActiveOrderCounts()","7e655ddd":"tokensSoldInThisRound()","7e6667c9":"Invoked(address,bool,uint256)","7e6688a2":"lastJackpotPayout()","7e668cd2":"fSqr(uint256)","7e66f15f":"nowSupply()","7e67429f":"switchToCrowdsale(string)","7e687a8b":"getTotalInvoicesCount(address,uint256[])","7e69671a":"distributeFees(uint256,uint256)","7e69ba22":"ethForTokens(uint256)","7e69e0fc":"ETH420on420()","7e6a0720":"removeClaim(uint32,int256,string,string)","7e6b867f":"insertProductIntoCart(uint256)","7e6bdb95":"getTransactionHashes(uint256,uint256,bool,bool)","7e6beae1":"team2018TokenCreated()","7e6c945c":"FileHashInt()","7e6d0fa0":"isWithdrawAllowed()","7e6d6928":"SmartBusinessToken()","7e6d86ff":"BOUNTIES_SHARE()","7e6dce9c":"throwIn()","7e6e65f3":"acceptSellOffer(uint32)","7e6eee20":"olympusTest()","7e6f6947":"setTokenBurnFeeAbs(address,address,uint256)","7e71496b":"TRCToken(uint256,string,string)","7e71572b":"_checkCap(uint256,uint256)","7e71ccd8":"HShoe_Limit()","7e71fb09":"transferOwnershipImmediately(address)","7e72fb52":"buyToken(address)","7e7307c5":"Contribute(bool,uint8)","7e737551":"setMaxWhitelistLength(uint256)","7e7388b1":"NewRiskAdr(address)","7e742432":"addNewDegree(string,bytes32)","7e74325f":"turn(address)","7e74a1ed":"depositRate()","7e754146":"getCurrentImpeachmentUrlDetails()","7e761240":"setMyName(bytes32,bytes32)","7e766e1f":"IonixxToken(uint256,string,string)","7e76b836":"minter1()","7e7712f2":"standardReleaseAmount()","7e773d9d":"testTimestamp()","7e77509e":"isRoundingErrorFloor(uint256,uint256,uint256)","7e779985":"isTransactionSuccessful(uint32)","7e77c503":"initialize(string,string,uint256,address,address)","7e780157":"PERCENT_100()","7e7894e4":"PendingETHs()","7e79a562":"TripPay(uint256,string,string)","7e79e8ba":"getEmail()","7e7a2fbf":"contribute_toTheGame()","7e7af34f":"setPostICOSale(bool)","7e7be158":"validatePurchaseAndDistributeFunds(uint24[],uint24[],uint256[])","7e7c16de":"secsPerBlock()","7e7c4243":"getTheBet(address)","7e7c8c6e":"catToken()","7e7d5689":"requireTrade(address)","7e7d76ad":"SPORT(uint256,string,uint8,string)","7e7db227":"lastAccountNum()","7e7dd581":"oldDBAddress()","7e7e4b47":"getOutcome()","7e7e5a75":"changeIdentityNarcoRespect()","7e7f1bfd":"total_refunded()","7e7f8e1e":"AddItem(uint256)","7e809973":"hash(address)","7e815fb4":"ScooterCoin()","7e81701a":"sitExchanger()","7e81b6aa":"KingdomFactory()","7e823bd1":"OMGToken()","7e82d0e6":"dbkWithdraw()","7e83027f":"setRegionForSaleToAddress(uint256,uint256,uint256,address)","7e8306ae":"profitrate()","7e83185b":"updateImageAddress(string)","7e835e86":"minechaincointest(uint256,string,uint8,string)","7e837ccc":"dispute_confirmed()","7e84adda":"setGameState(bytes32,int8[128],address)","7e85477f":"myInner1()","7e86e0f2":"BKFToken()","7e86f8e5":"blockedDeadLine(address)","7e873c2c":"uniq(uint256[])","7e87cf30":"tokenOpen()","7e888767":"getNumUsersToPayout(bytes32)","7e88f603":"returnDeposit()","7e893159":"changeIssuer(address)","7e8a9db9":"BasketEscrow(address,address,uint256)","7e8ab941":"_play(uint256,uint256)","7e8bca6f":"Tenteniy()","7e8bf1cd":"calculateCurrentMarketPixelPrice()","7e8c3ab6":"distributePartnerTokens()","7e8ca5f6":"unlockAdvisorTokens()","7e8d1a39":"finishIssuing()","7e8d2c19":"reserveForJackpot()","7e8e13e4":"Lesson_7(address,uint256)","7e8e353c":"setValidatorForND(uint256,uint256,uint256,uint256)","7e8e6d45":"setScaleContractAddress(address)","7e8ecf4f":"balanceOfInvestor(address)","7e8ff036":"submit(bytes32[])","7e904a48":"getNumContents(uint256)","7e904f7b":"stakePrimordialTokenFrom(address,uint256,uint256)","7e90819a":"unofficialApplicationSignUp(string)","7e9266bb":"ChallengeToken()","7e926b4b":"renounceOwnership(bool)","7e92a7e8":"getPublicBattlePokemon1()","7e93150b":"_transferHelper(uint256)","7e93163b":"tip(bytes32,bytes32)","7e932d32":"setFrozen(bool)","7e93810b":"playe1Bid()","7e93e4db":"KhabibvsMcGregor()","7e944756":"getPlayersCollection(address)","7e945935":"oneTokenInCents()","7e947347":"changeWeiCostOfToken(uint256)","7e94cf0c":"getValidityBondAttoeth()","7e951bc6":"update_coeff()","7e95385c":"setJackpot(address)","7e95cd27":"forbid(address)","7e95d2f6":"doSend(address,address,uint256,bytes,address,bytes,bool)","7e968195":"batchTransferETH(address[])","7e969692":"EthRateChange(uint256)","7e97ca29":"registeredInDay(address)","7e98bc8f":"Accumulate(address,uint256)","7e990ad8":"isRentals()","7e999cd9":"revokeMintDelegate(address,int256)","7e9a8685":"getWager(address)","7e9abb50":"getUnavailableTakerTokenAmount(bytes32)","7e9ad046":"upper(string)","7e9aef53":"elementsAreSet()","7e9b98ae":"transferFromWhiteList(address)","7e9ba301":"getResponseAddress()","7e9cd30c":"rescueLostHero(uint256,address)","7e9d2ac1":"burnAll(address)","7e9d7f68":"namiCrowdSaleAddr()","7e9de0bc":"buyTile(uint8,uint256,address)","7e9e1561":"getStakerFromDelegateKey(address)","7e9e1637":"getStockTotal(address)","7e9e1cb6":"Execution(bytes32)","7e9e3b3b":"RESERVED_TOKENS_BOUNTY()","7e9e3d51":"TokenERC20(string,string,uint8,address,uint256)","7e9e4b5d":"firstStageTokensSold()","7e9e511d":"issueAndActivateBounty(address,uint256,string,uint256,address,bool,address,uint256)","7e9e940a":"ClaimDisbursement(address,uint256)","7ea01c0d":"currentLowest()","7ea074b3":"GetJackpots()","7ea11880":"VestedPayment(uint256,uint256,uint256,uint256,uint256,address)","7ea15da1":"priceUpdateAt()","7ea17a1d":"ORACLIZEQUERYMAXTIME()","7ea1a871":"announce(uint256,uint256,uint256)","7ea1b7ba":"_closeSale()","7ea1e2d9":"ethpause()","7ea23fa6":"unlockEthBalance(address,uint256)","7ea2bbac":"getOwnerGennezise(address)","7ea2be2b":"log32(uint32)","7ea2ddeb":"randomNumber(address,uint256,uint256)","7ea2e31c":"EligmaMintingContract()","7ea2fc89":"cancelBetByPlayer(uint256)","7ea30d5d":"BuyCreditsByEth(uint256)","7ea310d4":"getCurrentPrice(uint40)","7ea31352":"getReadableStats()","7ea31ded":"isBuyBackOne()","7ea46993":"revokeMultiplePermissions(address,bytes32[])","7ea531e7":"_generateNewHorseShoe(uint256,uint256,address)","7ea5d50e":"tokenWinRatio()","7ea5e7d3":"reserveDeployment(address,bytes32,address,uint256,uint8,bytes32,bytes32)","7ea60eb8":"roleEditorAddress()","7ea61ed7":"withdrawInternal(address)","7ea6c6ba":"MemoLandCoin()","7ea80eb2":"_receiveBuyLandForCandy(address,uint256)","7ea83869":"increasePreSaleSupply(uint256)","7ea84748":"addPlayerOrder(address,uint256,uint256,uint256,uint256,uint256,uint256)","7ea868e1":"makeInvest(uint256,bytes5)","7ea8f250":"isRunningPreIco(uint256)","7ea94985":"calcHashes(uint32,uint32)","7ea95733":"emissionReleaseThreshold()","7ea9b2bc":"REQUEST_URL()","7eaa0c29":"LogTransactionFailed(bytes32,address)","7eaa4389":"finish(uint8,uint8,uint8)","7eab4e48":"openGiftFromSanta(address)","7eac7382":"getCAOAddres()","7eae1626":"getBack()","7eae6759":"_setBalance(address,uint256,uint256)","7eae75a8":"EtherMango()","7eaef50c":"over()","7eaf45f8":"SaveAccountBuyingGodz(address,uint256)","7eafcdb1":"updateGroupName(address,address,bytes32)","7eb13d8a":"_SetEducationQualificationOf(uint256)","7eb14990":"isBuyer(address,uint256)","7eb1bfb9":"feeWithdrawEthAll()","7eb30cd0":"checkTreeStructure(address,address)","7eb312b1":"SUCCESS_BONUS()","7eb41ce5":"modifyCfo(address)","7eb4b376":"UpgradeSpaceETH(uint8,uint256)","7eb52145":"_preValidateFinalization()","7eb5df39":"equal(uint256[],uint256[],string)","7eb60591":"NVISIONCASHTOKEN()","7eb6634c":"phasePresale_From()","7eb69ba1":"hint(int256,bytes32,string,bytes20)","7eb82601":"getHighestBlockNumber(uint256)","7eb96aa3":"setCurrentWeekPool(uint256)","7eb9f04a":"updatePriceInWei(uint256,uint256)","7eba7ba6":"getSlot(uint256)","7ebaaa60":"MemberBoughtToken(address,uint256,uint256,uint256,uint256,uint256)","7ebadcd8":"acceptPayments(bool)","7ebd02f8":"typeA()","7ebd89ee":"TokenSale(address)","7ebdab54":"setup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256[],uint256[],uint256[],uint256[],uint256[])","7ebdc478":"settleTimeout()","7ebdf4ac":"setMaxAllowedBetInEth(uint256)","7ebdf57d":"icoTimeBonusPhase1End()","7ebe7626":"FreezeTokensReleaseTime()","7ebedc34":"hasEndedIco()","7ebf65fd":"changeGasLimitOfSafeSend(uint32)","7ec0c39c":"whitelistPrincipleLockPercentage()","7ec0f30d":"ack(string)","7ec13996":"getBytes32Value(string)","7ec1c1aa":"acceptPAIReceiptOwnership()","7ec20127":"createPoolIfNeeded()","7ec2402f":"freezeSupply()","7ec27000":"AiTokenToken()","7ec2ae46":"setSparkDividends(address)","7ec2e264":"_generateCode(address,uint256)","7ec2fd36":"capReleaseTimestamp()","7ec2fd95":"DrawCom()","7ec36494":"osmCoin()","7ec3e63e":"getsubscribersSinceLastHatch(address)","7ec4a5a6":"requestReturn(address)","7ec4edbe":"offset(address,address)","7ec509c4":"external_call(address,uint256,uint256,bytes)","7ec54bdc":"eosShareDrop()","7ec62cf7":"MthereumToken()","7ec650db":"__mul(bytes,bytes)","7ec69c50":"changeWhitelistingStatus()","7ec72d3c":"setSwap(address,uint256)","7ec80c27":"priceStep6()","7ec8ff4f":"crosairVoucherSoldCount()","7ec9084d":"RRCoin()","7ec9290b":"setCouldTrade(uint256)","7ec9c3b8":"per()","7ecab507":"registerPresale(address,uint256,uint256,bool)","7ecacb95":"Example7()","7ecaf696":"createMultiple(uint256[],uint256[],uint256[],address[])","7ecb6475":"aggiungiFrase(string)","7ecc2b56":"availableSupply()","7eccc40a":"contains(uint256,address)","7ecdb299":"SetEthBalance(address,uint256)","7ecdbf61":"SPPSeriesA(uint256,string,uint8,string)","7ece75dd":"lockPeriodStart()","7ecedac9":"allInitialOwnersAssigned()","7ecef543":"_getAppliedPolicyIndex(address,uint8)","7ecf9142":"depositToken(address[2],uint256[7],uint8,bytes32[2])","7ecfa8a8":"ico(address,address,uint256,uint256,address[],uint256[])","7ecfae65":"invokeFor(address)","7ecfb675":"stdBalance()","7ed02af9":"acceptNegotiationTenant()","7ed02cbe":"fireLottery(uint8)","7ed040f2":"prod(bytes32,uint128)","7ed04cf2":"getTokenNames(address,uint256[])","7ed05315":"newGubberment()","7ed06cf3":"nativeProof_verify(string,bytes,bytes)","7ed0c3b2":"write(bytes)","7ed0f1c1":"redeemed(uint256)","7ed18aa5":"WhitelistUpdated(address,uint8)","7ed19af9":"multiAccessRevoke(bytes32)","7ed1ca6a":"BetExecuted(uint256,address,uint256)","7ed273e9":"_mintToken(uint256,string,address)","7ed32df6":"buyRtc()","7ed37b8d":"setPotato(string)","7ed40602":"IsICOstarted()","7ed4e321":"CakeToken()","7ed51b47":"getResult(uint256,uint256,uint256,uint256,uint256)","7ed57fa0":"pregnantHorses()","7ed5a6d4":"TYPE_EXPLORER_FREIGHTER()","7ed5d621":"Crowdsale(address,address,address,uint256,uint256,uint256)","7ed65c87":"closeProvider()","7ed7101d":"mainIcoStartBlock()","7ed77c9c":"setContract(bytes32,address)","7ed788c8":"push(address,uint256,uint256)","7ed83d50":"INCO()","7ed8a719":"addItem(string,string)","7ed8b225":"createMesaVerify(bytes32[])","7ed9c734":"burnRemainingToken(uint256)","7ed9d3a3":"_error(uint256,bytes32)","7eda09e8":"test_me(int256,int256,int256)","7edaabd8":"sendApprovedTokensToInvestor(address,uint256,string,string)","7edaca89":"DAToken(uint256,string,uint8,string)","7edba6c8":"sam()","7edd9060":"_nominCap()","7eddea21":"STAKEHOLDERS_POOL()","7ede036d":"minimumSupply()","7edea039":"private_addPermittedRoll(uint256)","7edebaf1":"buyXname(string)","7edee605":"receivePayment(uint256,uint256,bytes)","7ee0cda4":"validate(string,uint256)","7ee0d91c":"isKycRequired(address)","7ee212bb":"planetIndexToApproved(uint256)","7ee26b2e":"callKoikeToken(address,address,uint256)","7ee26e63":"_alreadyInList(address)","7ee2ea76":"isSafeHavenToken()","7ee42e6d":"_createToken(string,bytes5,address,uint256)","7ee54b82":"TYU(uint256,string,uint8,string)","7ee54eec":"onTicketPurchase(uint32,address,uint16[])","7ee55c97":"isICO()","7ee5c97a":"returnReferral(address)","7ee5eef2":"changeToPublicSale()","7ee62440":"highEtherBonusLimit()","7ee65635":"LookAtDepositsToPlay()","7ee6b2d0":"fundingMinCapInWei()","7ee7f42a":"MIN_RELEASE_DATE()","7ee80d17":"isScheduled()","7ee81902":"DatoDEX(address,address,address,uint256,uint256,uint256)","7ee8703a":"getProgressOfAddressAndId(address,address,uint32)","7ee96f6d":"getEnd(uint256)","7eeb5906":"createCountry(string,string,uint256)","7eec20a8":"cancelTask(uint256)","7eed2814":"transferAD()","7eee1ab6":"HahaCoin()","7eee288d":"unlock(address,uint256)","7eee56f9":"issueIcoCoins(address,uint256)","7eee6d1f":"getUserQuickPromoBonus(address,address)","7eeec2cf":"GigaWattToken()","7eefe47e":"editCode(uint256,string)","7ef01fb9":"totalLockedBonus()","7ef0356a":"littafiTimeCapsule(bytes32,string,string,string,string,uint256)","7ef039f8":"candySentAmount()","7ef09476":"transfer(uint64,address)","7ef1925b":"getShareRange(uint256,uint8)","7ef1a396":"YOU9COINToken(string,string,uint8,uint256)","7ef1ab2c":"payoutRange()","7ef224ee":"getContractOrNormal(address)","7ef26d42":"HardCapEthereum()","7ef2bd52":"currNumOfUpgrades()","7ef3bb63":"createKitties()","7ef3e741":"totalEtherReceived()","7ef4cabb":"nextSupplyAfterBlock()","7ef50298":"registry(bytes32)","7ef581cc":"whitelistAdmins()","7ef58e73":"totalGooProduction()","7ef59d01":"setTrader(address,bool)","7ef5b6ea":"refillTokens(uint256)","7ef5e6a2":"rescale(int128)","7ef61e28":"dayEthInLimit_()","7ef72eb5":"AlphaMarketCoin(address)","7ef7ce92":"revokeMint(uint256)","7ef81a34":"TestableTwoStageSale(bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address,uint256,uint256,uint256)","7ef9016e":"MultiTransferValue(address[],uint256)","7ef92867":"Faucet(address)","7ef95c6f":"extractAccountAllowanceRecordLength(address)","7efc05ae":"TUBECOIN()","7efc2315":"minPaymentForAnswer()","7efcbb33":"getTradeRecord(uint256)","7efce4ff":"TransactionRefunded(uint256,uint256)","7efce591":"TokenRDN(uint256)","7efd3441":"DynamicSKx2(uint256)","7efd9112":"decodeTokenId(uint256)","7efe0e76":"PhoenixFundDeposit()","7efe294c":"removeFromFreezedList(address)","7efe64ba":"InfinityHourglass()","7eff1465":"setAccountAllowance(address,address,uint256)","7eff275e":"changeProxyAdmin(address,address)","7effb427":"TTTToken()","7efff887":"topUpBalance()","7f002ffe":"setTradeable(bool)","7f004afa":"participantRoundChange(address,address,uint256)","7f006ce1":"reading_card_upright_at(uint8)","7f008a0a":"cancelSell()","7f01bb38":"getVestingRevocable(address,address)","7f053808":"approveAndAuction(uint256,uint256,uint256,uint256)","7f0554ca":"mntToken()","7f056637":"testExecuteSellOrder()","7f05c3a6":"supportAccounts(address)","7f067ff7":"Bitcoinsummit()","7f069942":"transferToBeneficiary()","7f070a9b":"withinRefundPeriod()","7f0899f2":"AddTicket(bytes5[])","7f08a250":"testPoint(uint256[3])","7f08ea8b":"getBetPool(uint256,uint256)","7f08ea8f":"getTotalTokensPerArray(uint256[])","7f09171b":"addAd(address,uint256,uint256,uint256,string,string)","7f095bfb":"multiSendB(uint256,uint256)","7f09ad64":"drainMe(uint256)","7f09bd1d":"setEthPreAmount(uint256)","7f09beca":"moveToWaves(string,uint256)","7f0a1bed":"bidderPlaceBid()","7f0b61f7":"ManagerEnabledEvent(address)","7f0bd881":"wanport()","7f0c949c":"setJurisdication(string)","7f0cd33c":"ApproveAndtransfer(address,uint256)","7f0d35e2":"totalPublicSaleWei()","7f0da94e":"cooloffIncrement()","7f0ed037":"setKickOff(uint8,uint256)","7f0f04a8":"unregister(bytes32,address,uint256,uint256,uint256)","7f0f09af":"EtherdeCoin()","7f102c16":"currentGameStatus()","7f10a3c0":"presaleBonusAddress()","7f1165c1":"getSencBalance()","7f1482b1":"round3Bonus()","7f15a21c":"modify(address,address,uint256)","7f15a6a3":"setCCH_edit_31(string)","7f16ab50":"replaceAuthorised(address,address)","7f1731b6":"unsetRegistrar(uint256,address)","7f17b05d":"OwnerAddress()","7f17b79d":"setGameCost(uint256)","7f17ce9b":"DIGIPLACED()","7f180db7":"kudos(uint256)","7f187d2d":"score(bytes32,string)","7f18b569":"setKncPerEthBaseRate()","7f18f10c":"setGeneContractAddress(address,address)","7f191255":"punchOut(address,uint64)","7f1926c7":"GagarinToken()","7f1a2a73":"getEmployerAvgRating(address,address)","7f1a4c1f":"withdrawContributorsTokens(address,uint256)","7f1a8749":"purchaseMakeAdv(uint256,string,string)","7f1b1e51":"testTooFewTokens()","7f1b8cc3":"getUsersByBalance()","7f1bb473":"daysFrom(uint256)","7f1bffc1":"_removeToken(uint256)","7f1c25d0":"HolaMundo()","7f1ce417":"isITOFinished()","7f1ebc4d":"reentrantGuard()","7f1ecfe0":"getCurrentBid()","7f1f0507":"publicRate()","7f205a74":"SALE_PRICE()","7f205c8c":"getOraclizeCallback(bytes32)","7f205f02":"changeBoolean()","7f21d498":"getMinBid(uint256)","7f23fb92":"setGenres(string)","7f2438cb":"sellFor(address,uint256)","7f25c1e4":"etherRaisedByState(uint256)","7f2609eb":"LogFinalizeMatch(uint256,uint8)","7f26fc7d":"removeCreator()","7f279a73":"Cashing(address,uint256)","7f2857b6":"viewFunc()","7f28c44f":"isIcoSuccessful()","7f290d2d":"ExpiringMarket(uint64)","7f293e02":"ChangeCoinCrowdsale()","7f294b10":"setPI_edit_26(string)","7f298f93":"crowdsaleEndBlock()","7f2a4784":"KYC_VERIFICATION_END_TIME()","7f2aeea4":"getType(bytes32)","7f2b06ed":"bonusLimit3()","7f2b88ea":"getThirdPhaseCap()","7f2c1633":"prenesiKovance(address,uint256)","7f2c4ca8":"getLastBlock()","7f2e01fb":"ListValidated()","7f2e0ec2":"remainRewards()","7f2e98ad":"PoissonData()","7f2f506b":"CLAIM_INTERVAL_DAYS()","7f300576":"startThrowing()","7f301b83":"setMetadataHash(string)","7f31b480":"changeMasterAddress(address,address)","7f31cbfa":"batchShareAmount(address[],uint256[],uint256,uint256,uint256)","7f32f6de":"isSoftCapCompleted()","7f33375b":"getReturnedData()","7f334bd1":"_generateRandomId(string)","7f33c1e1":"Ethurem()","7f3436ef":"addOrganisation(address,string,string,string)","7f349329":"currentRoundSupply()","7f3681f6":"setKNCRate()","7f3745ad":"execute_transfer_all(uint256)","7f3745db":"getTracksByArtist(address,uint256,uint256)","7f37b905":"salesCounter()","7f37fab6":"addActionToRole(string,string,string)","7f3800ba":"setMultihash(bytes32,string,bytes)","7f386b6c":"minimumPrice()","7f38a4a7":"updateUSDETH(uint256)","7f38b980":"setTokenDistributionPool(address)","7f38e526":"pendingPayments(address)","7f390088":"QYCC()","7f3a2472":"reserveIssue(address,uint256)","7f3a98b7":"burnMyBalance()","7f3ad651":"KayoToken(address,address,uint256,string,uint8,string,bool)","7f3bd56e":"disburse(address,uint256)","7f3c26b1":"rejectHours()","7f3c2c28":"registerContract(string,address)","7f3cb47b":"minimumAmountWei()","7f3cd28e":"tokenSalesByOwner(address,uint256)","7f3d5c4c":"ICOPaused()","7f3ded93":"voxFab()","7f3df4bb":"addBonus(uint32[],uint64[])","7f3e1841":"endSecondPeriodTimestamp()","7f3e4d1b":"setAtkNowForPlayer(address)","7f3f3398":"transferAndCallExpanded(address,uint256,bytes,address,address)","7f3f81c0":"confirmProposal(bytes32,address,uint256)","7f404b7f":"updateInt256(bytes32,int256)","7f40d9d8":"delayDonPhase(uint256,uint256)","7f4316ec":"getDefendPlayerList()","7f4384a8":"RichNiggas()","7f440d57":"getProjectReport(uint256)","7f445c24":"subRegistrar(string)","7f44fcfa":"_getPoints(uint256)","7f453951":"CBMDToken()","7f45b835":"getPrimaryRecord(string)","7f45ec91":"emitIssuance(uint256)","7f460693":"ownerPutCapital()","7f46550f":"CrowleyToken()","7f476471":"setRCContractAddress(address)","7f480f9d":"processDividends(address)","7f486ca6":"cancelChibiForFusion(uint256)","7f493ce6":"disableTokenTransferability()","7f497550":"scheduleTransfer(address,uint256,uint256)","7f498ffc":"setEnd(uint256)","7f4a1c52":"setExceed(uint256)","7f4a9691":"depositTokenToVault(address,uint256,uint256)","7f4ab1dd":"messageForTransferRestriction(uint8)","7f4ae68d":"restrictedAddress()","7f4af951":"pixelPrice(uint256,uint256)","7f4bf7d1":"Inerex(bytes32)","7f4c7064":"ESCROW_TOKENS_PERCENT()","7f4d5150":"CheckItemExists(uint256)","7f4d6aa4":"LogResumed()","7f4da132":"goldFee()","7f4db7fb":"testPrivate(uint256)","7f4e4669":"raiseInitialSupply(uint256)","7f4e4849":"getContractState()","7f4ec5a7":"toAddressThrow()","7f4ed2c7":"addToWhitelistMulti(address[])","7f4ed5ac":"sumHardCapICOStage2()","7f4edd72":"getAllAdIdsByUser(address)","7f4ef9d4":"getText(uint256)","7f4fd78e":"BTCCollected()","7f50c74b":"FIXED()","7f51bb1f":"updateTreasury(address)","7f52fcae":"tokenAmountPerUser()","7f5341da":"startTimeSale3()","7f5369f1":"DEFAULT_REVOCABLE()","7f5375c1":"getLastWin()","7f53b15d":"_ICOSale(address,uint256)","7f555b03":"erc20Proxy()","7f55b2d9":"cleanBalance()","7f55b87f":"createCountry(string)","7f564472":"resetAmountBonuses()","7f5651d7":"setNamehash(string,bytes32)","7f56c072":"SIEChain()","7f56c0b4":"setTeamFundWallet(address,address,uint256)","7f56ca73":"Volkstest2()","7f573a4f":"UNSOLD_SOLD_RATIO()","7f582b47":"howMuchWithdrawed()","7f58b9ee":"allQueryIds()","7f592be4":"TRANCHE2_ACCOUNT()","7f592cfe":"setLLV_edit_12(string)","7f5a259f":"FIXED_RATE()","7f5a285a":"notInWhitelistAllow()","7f5a448c":"switchToWhaleMode(bool)","7f5ae339":"isAdminister(address)","7f5b47cd":"eventApproval(address,address,uint256)","7f5b503c":"toB32(bytes,uint256,address)","7f5ba3cc":"REGULAR_TYPE2()","7f5ba79f":"registerNewProduct(uint256,string,string,string)","7f5bfe30":"PaymentExecuted(uint256,address,uint256)","7f5d85f8":"testBurnGuyWithTrust()","7f5dfd16":"approveProxy(address,address,uint256,uint8,bytes32,bytes32)","7f5e495d":"defaultLimits()","7f5f0d6a":"resumeIco()","7f5f17b1":"getCompte_8()","7f5f9128":"alreadyReservedForTeam()","7f601a50":"getHouseCardsNumber()","7f602231":"tip(bytes32,address,uint256)","7f60b20a":"getSlice(uint256,uint256,string)","7f60bb7c":"applyBonusAmount(address,uint256,bytes32)","7f6150cb":"getRoundCurKeyNo(uint256)","7f626f1a":"setStore(uint256)","7f630259":"getSuperReferrerRate(address)","7f63040b":"CompcoinCash()","7f630b4c":"share(string)","7f63af42":"deployConsortium(address)","7f64727b":"getTreesOnSale()","7f649783":"addToWhitelist(address[])","7f64c34e":"deadline365()","7f64d2d3":"NCAAChampionship()","7f654b1c":"setLatestPayday(address,address,uint256)","7f6578d3":"REFUND_PERIOD()","7f6597e0":"AcuteEthereumCloudMiningunion()","7f660b01":"FEE_COLLECTOR()","7f66af09":"card_titanium_first()","7f66ccbe":"EthereumVerge()","7f66d1f8":"mOnApprove(address,address,uint256)","7f671c1b":"insert(int128)","7f686259":"migrateBalancesFromLegacyRep(address[])","7f695f28":"isFlying()","7f6a731c":"donationAmountInWei()","7f6ae0c0":"canUpdateDeveloperMiningPower()","7f6d8955":"RegisterOne(uint32,address,address)","7f6ec891":"withdrawNonTopForTeam(address,uint256)","7f704657":"RESERVED_FOR_TEAM()","7f71f1f9":"controllerApproval(address,address,uint256)","7f725862":"_setNewEstimate(uint256,uint16)","7f7376e8":"launchSale()","7f74ac15":"ownerContract()","7f7575c9":"FixedSupplyCrowdsale(uint256,address,address,uint256)","7f760335":"PurchaseTokens(uint256,address)","7f761472":"canRedeemUTXOHash(bytes32,bytes32[])","7f7624d0":"MjolnirAddress()","7f7634ba":"winnerConfirmed()","7f76bd3a":"lastBlock_v18()","7f76d76d":"minCapIco()","7f784da7":"addNews(string)","7f78636a":"BASE_URL()","7f790b7b":"getCreateUniverseParentPayoutDistributionHashValue()","7f791790":"roll(uint16[],uint16)","7f791833":"toTimestamp(uint16,uint8,uint8,uint8)","7f792910":"setExchangeable(bool)","7f7977d1":"isFundraiser(address)","7f7985cf":"setEthUSD(address)","7f79cbfe":"MANHATTANPROXYLEXINGTONAVE()","7f7b1393":"getLocation(uint256)","7f7b17a0":"SetupPreSale(bool)","7f7c1491":"remove(address,address)","7f7d31dd":"sub32(uint32,uint32)","7f7d711e":"setRequireCustomerId(bool)","7f7dcdbf":"isContractOwner()","7f7de185":"handleProductionDecrease(address,uint256)","7f7fde8e":"sellAssets(address[],uint256[])","7f81f0b9":"setTransferLock(uint256)","7f83a4a6":"canRefund()","7f83bf7d":"setMinimumPayment(uint256)","7f84017f":"SELL_SOFT_LIMIT()","7f848ccb":"_packMakeData(address,uint256,uint256)","7f85066e":"Reflex()","7f853e7e":"MLCToken()","7f85c599":"addOrder(bytes32,address,uint256,uint256)","7f860330":"batchReturnEthIfFailed(uint256)","7f863cab":"Bid(address,uint256,address,uint256)","7f8661a1":"exit(uint256)","7f869d98":"stepFour(int256)","7f86cd3f":"parseLoanOfferRates(uint256[10],uint32[4])","7f86d985":"drunkness()","7f86f7f4":"walletPlatform()","7f877710":"recoverUnawardedMILs()","7f879229":"setSalesUser(address)","7f88616f":"onlyAdminAndNotInit()","7f89ce48":"initTiers(uint256[],uint256[])","7f8b8f48":"Ledger(address)","7f8b9478":"getImpliedRoot(bytes,bytes,uint256,bytes32[])","7f8c263f":"dragonBalance(address)","7f8d429e":"isFinalized(bytes32)","7f8d53c6":"put(address,uint256)","7f8dafef":"unsoldAllocationCount()","7f8fdcfb":"suspendDeposit()","7f9144ce":"token_member_order_pop(address,address,uint32)","7f91fb7d":"isSignedBy(address)","7f9245d0":"_clearTokenApproval(uint256)","7f924c4e":"testDeposit()","7f925c93":"withdrawSeller(address[2],uint256[7],uint8,bytes32[2])","7f93354b":"multiVoteNoLock(address[],uint256[])","7f9343ad":"playNumberSuit(uint256[])","7f93de95":"deposit100Percent()","7f947168":"TimeTransferAllowed()","7f949386":"updateMessage(uint256,string)","7f949ac0":"ethashContract()","7f94a8fa":"getWriteTimestamps(bytes32[])","7f95d6f6":"accountBalances(uint256)","7f95d919":"DistrFinished()","7f967a8c":"IsExchanged(address,string)","7f9785b0":"_resetList()","7f97e836":"didCommit(address,uint256)","7f98444f":"randomEnd()","7f99e11a":"isMiningOpen()","7f99f3c4":"MaybePerformOpen()","7f9ac04f":"balancesStaticoin()","7f9b48bc":"setCompte_9(string)","7f9bf9e4":"startMinting(string)","7f9c23e0":"_determineHitPoints(uint256)","7f9c8974":"getAssetCollectedOreBallancesArray(uint256)","7f9cbfc1":"checkPayments()","7f9d139a":"positionScount(address)","7f9d2044":"UniBowToken()","7f9d314e":"autoBirth(uint256)","7f9df012":"VoteRevealed(address,uint256,uint256,uint256)","7f9f5495":"levelTokens()","7fa0c10f":"DeleteUserByAddr(address)","7fa0c908":"newChow(address)","7fa22001":"assertEq0(bytes,bytes,bytes)","7fa24846":"SetSAToEContract(address)","7fa28d75":"transferRightIfApproved(address,bytes32)","7fa34e92":"preIcoAddr()","7fa39958":"RateAdd(address)","7fa3f3d0":"addLock(uint256)","7fa400e4":"totalTokensAvailableForSale()","7fa40a42":"sumICOStage8()","7fa44926":"setMinMaxInvestValue(uint256,uint256)","7fa4cacb":"setDestinationAddress(address)","7fa5aa9d":"registerPreSignedHashing(address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256)","7fa6c365":"phase3MaxTokenForSale()","7fa6c745":"_setNewStartTime()","7fa767bc":"createBox()","7fa7a7c8":"buyInWithAllBalance()","7fa7acf8":"createCertification(uint256,uint256)","7fa87949":"unblockAccountFunds(address,uint256)","7fa8c158":"startICO()","7fa9aa76":"owner_updateBaseFee(uint256)","7fab541c":"exec(bytes32,bytes)","7fab624b":"purchaseGenes(uint256,uint256,bool)","7fabbd7b":"unilateralRefund(bytes32)","7fabe1a5":"allPendingRefs()","7fad54e4":"distributeGame(uint8,uint256)","7fad9b53":"BASE_TEAM()","7faddcfb":"currentDistributionAmount()","7faff876":"updateUser(bytes32)","7fb00168":"CryptekZ()","7fb0a445":"systemSaleAddress()","7fb0fe14":"voteCandidateTwo()","7fb158c5":"ChannelSettled(address,address,uint32,uint192)","7fb181c1":"swapTime()","7fb191a5":"TokenVestingContract(address,address,bool,bool,bool,address)","7fb1a5ed":"AirdropController()","7fb33170":"transferAdmin(address,uint256)","7fb3d459":"GetChipsInfo(address)","7fb419b6":"WalletBoss()","7fb5d847":"delTransferWhiteList(address)","7fb5ff3e":"MNTP()","7fb7b5ed":"enableTeamWithdraw()","7fb9e405":"getTitulaire_Compte_10()","7fbb345e":"getInvestorsTokens(address,address)","7fbc0c48":"_mint(uint256,address,string,string)","7fbc9c55":"calculateMultiplierAfterConversion(uint256,uint256,uint256)","7fbcef65":"BTH(address[],uint256,address,uint256,uint256,uint256)","7fbd778a":"getTotalScientists()","7fbe0680":"MIN_PURCHASE_OTHERSALES()","7fbea955":"getCanvasByState(uint8)","7fbf28f7":"_withdrawDivis(address)","7fc29fc9":"authorisedMinter()","7fc32915":"ThrowbackThursdayToken()","7fc38e04":"SponsorshipReceived(string,string,string,uint256)","7fc3bb26":"endPostICO()","7fc3f49e":"getReinvestableTokenAmount(address)","7fc446f2":"changeCustomDefrostingRate(address,uint8)","7fc4d6c3":"isPhaseExist(address)","7fc53fb5":"returnInvestmentsToInternal(address)","7fc543ec":"_donations(uint256)","7fc55eb4":"ContributionWallet(address,address)","7fc56856":"IOXDistribution(address)","7fc5af95":"getWinnerList()","7fc5f05c":"changeVoters(bytes32,address,string)","7fc611f0":"multiCall()","7fc729c2":"_buy(address,uint256,bytes)","7fc7e643":"SetUp(uint256,uint256,uint256,address)","7fc88fe2":"timelockContractAddress()","7fc8b612":"interadduser(address,uint256)","7fc8fd9e":"Update_MediatedTransaction(uint256)","7fc90182":"Pool(uint256)","7fc90a5c":"batchAssignTokens(address[],uint256[],uint256[])","7fc96619":"getPartner(uint256)","7fca432e":"FHFTokenCrowdsale(address)","7fcac0fb":"USDBCoin()","7fcae430":"PendingApplication(address,uint256,string)","7fcaf666":"setString(string)","7fcb024a":"secondLockTime()","7fcb2386":"MorrowToken()","7fccb4ba":"transferAppOwner(bytes8,address)","7fcd3ce2":"maxBetPrice()","7fcdd1f0":"setConfirm(uint256)","7fcf3a2f":"throwFooBar()","7fcf440a":"getOwnerBalance(address)","7fcf532c":"Withdrawal(address,uint256)","7fcf64b2":"updateEarnedBy(uint256,uint256)","7fcfb422":"increaseApprovalWithData(address,uint256,bytes)","7fcfc4a0":"ApisToken()","7fd004fa":"submitWhitelistAddition(address[])","7fd13532":"whitelistMany(address[],uint256,uint256,uint32)","7fd169d6":"createGroup(string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","7fd19692":"setLockAddress(address,bool)","7fd2304f":"_maximumBuy()","7fd238ba":"doCoinage(address[],uint256[],uint256,uint256,uint256)","7fd26dd1":"tokenUsers(uint256)","7fd2ffa7":"InvestorWhiteListAddition(address)","7fd30df0":"mintBulk(address[],uint256[])","7fd39247":"setOwner(uint256,address)","7fd42617":"safeWithdraw()","7fd5bb31":"propose(address,bytes32,address[],bytes32[])","7fd5dd04":"APPROVE_OWNER()","7fd6f15c":"feePercent()","7fd751a8":"PRICE_ICO2()","7fd84609":"setOwnerThree(address)","7fd8601e":"deathData_v5()","7fd8d339":"changeicoBackend(address)","7fd8d51d":"stakeGLXForContributors()","7fd8ee68":"computeNameHashExt(bytes)","7fda8d52":"internalEnableRefunds()","7fdac6f1":"getCurrentCreditsExchanged()","7fdafafa":"totalTreePower()","7fdb5031":"transferableTokens(address,uint256)","7fdb5efb":"GDCAcc01()","7fdb6720":"teamFundAddress()","7fdbd0f2":"ERC721DutchAuction(address,uint256)","7fdc5bd6":"LANA()","7fdc8290":"isUnderscore(bytes1)","7fdd458d":"createWithParents(bytes32,bytes32,bytes32[])","7fdd5403":"clearApproval(uint256)","7fdd69f6":"setMaxAllowedReservingPercentage(uint256)","7fddc0de":"getBiddingInfo(uint16,address)","7fde1c8a":"addRole(address,uint256)","7fde24c7":"addToPrivateWhitelist(address)","7fdea25b":"newVoting(uint8)","7fdf6911":"checkRoundAndDraw(address)","7fdfbe1b":"getBytes(string,uint256,uint256)","7fe02f94":"fireFightResultsEvents(uint8[4])","7fe0518a":"asyncSend(address,uint256)","7fe09003":"NewBlock(uint256)","7fe0c38b":"JOCKEY_LIMIT()","7fe0ff52":"StorageFee(address,uint256)","7fe11990":"authoriseManyAccounts(address[])","7fe11adc":"resetStage(uint8)","7fe18cf7":"_getInStageIndex()","7fe1a801":"setBountyCampaign(address)","7fe1dc7e":"getToken(bytes)","7fe1feb0":"initEmployee1()","7fe23f62":"winPool()","7fe275d4":"culmulative_demurrage_collected()","7fe320ab":"mvpExists()","7fe38fc3":"etherwow()","7fe3dc2e":"getGasCost()","7fe551fd":"clearingPrice(bytes32)","7fe5850b":"_redeemByDefaultPartitions(address,address,uint256,bytes,bytes)","7fe60640":"updateBtsPoint(int256,uint16,int256,uint16)","7fe650b1":"finalizeICOOwner()","7fe6eee0":"fundingLimit()","7fe846ba":"isSubjectDestruction(uint256)","7fe864b8":"MAX_TOKEN_CAP()","7fe88885":"storeHash(bytes32)","7fe8ca66":"sendInput(int256,int256)","7fe97bc5":"getSqrY(uint256)","7fe98ae0":"updateEthICOThresholds(uint256,uint256,uint256,uint256)","7fe9d39c":"changebeginnerprotection(uint256)","7fea061a":"TimeTransferAllowanceChanged(string,uint256)","7fea0d4b":"beforeAll()","7feb4685":"Chende()","7febd721":"presaleAmountRemaining()","7fec1b7a":"WBT()","7fec5d33":"Eightk()","7fec8d38":"trigger()","7fecd538":"isWaiting()","7feda59a":"revokeAttribute(address,string,bytes)","7fee4ecb":"GAS_PER_DEPTH()","7feec9be":"sams(uint256,string,string)","7feed5b6":"price_exponent1()","7fef036e":"totalEntries()","7fef21d4":"getBoundingBox(uint256)","7fef2d38":"updateMatchInfo(uint256,string,uint64,uint64)","7fefde53":"WillRegistry()","7ff02139":"updateCrytal(address)","7ff0346b":"getContents(bytes32[])","7ff276bd":"totalEthFundCollected()","7ff2acb7":"getData_2()","7ff2c70a":"ipo_price()","7ff2cf93":"getcertifieddatacount()","7ff31d2b":"setData_28(string)","7ff3366f":"TeamAddress()","7ff44544":"GetCurrentSalePrice(uint256)","7ff44a91":"getAllKeyNum()","7ff4b630":"action(bytes32[])","7ff6ea1c":"WolkCreated(address,uint256)","7ff6f83a":"_distributeTax(uint256,address)","7ff701dd":"TrackerToken()","7ff70a89":"getOwnedTokenList(address)","7ff729fc":"fillUpProject(uint256,uint256)","7ff860f6":"batchCreateAssetSale(uint256[],uint256[],uint256[],uint256[])","7ff86a35":"HappyBirthday(address,uint256)","7ff91228":"Stake(address[],address,address,uint256,address)","7ff92d6e":"set_address__Arina(address,address)","7ff931bd":"lastWinningNumber()","7ff988c5":"setKtcAddress(address)","7ff9b596":"tokenPrice()","7ffaae3e":"balanceEth(address,address)","7ffb8577":"totalGains()","7ffc0712":"getLifeRate(uint256)","7ffc80cf":"queryRandomTryTime_()","7ffcb093":"addVoter(address,bytes32[])","7ffce58e":"getTokenForInvester(address,uint256)","7ffdf53e":"conversionRate()","7ffe8be1":"setKycAddress(address)","7fff9f1a":"getProposalVoteCount(uint256,uint256)","7fffb7bd":"HelloWorld()","80007e83":"isVerified()","80008794":"round1Target()","80009630":"setCore(address)","8001553a":"OwnerRemoval(address)","80017cbc":"cancelLine(uint256,string)","80033408":"CANSale()","8003524e":"calcDoHash(string,bytes32)","800362ae":"loveStoriesCount()","80054c5d":"FreedomToken()","80056b5b":"changeAdminPrivilege(address,bool)","80057b9a":"getColor(uint256)","80059593":"numberAccounts()","8005993e":"getProfileHash(address,address)","800626a6":"AIR_1_SUPPLY()","8006692f":"stage3Deadline()","8006745b":"getPayout(address)","8006a5d3":"delegateAddresses()","8006f807":"COBAIN()","8007604b":"Stage1Deadline()","80078a0f":"ForFood()","8007acbf":"getActiveShareholdersArray()","80087745":"closeInvest(bytes5)","8008d5bc":"inSale()","8009484b":"getMaxBetAmount(uint8)","80097484":"transfer(address,uint32)","80097a8e":"adjustedPotBalance()","800a320a":"TokenGameTransfer(address,uint256)","800ab784":"verifyMerkleProof(uint256,uint256)","800bbd1f":"getCountTokens(address,uint256)","800c5086":"giveERC20AllowanceToKyber(address[])","800c7e38":"getCurrentPageCount()","800d0f6a":"LCToken(uint256,string,uint8,string)","800d41a3":"newExitWallet(address)","800deda5":"yoyoTransfer(uint256,string,string)","800ed545":"MWSToken()","800edb9d":"changeCap(uint256)","800f8e52":"placeBetWithInviter(uint256,address)","80105295":"maxUserPower()","801137e7":"setDepositPercents(uint256)","80113832":"ORDER_MODIFY(address,address,uint256,uint256,uint256)","801145bd":"sig_to_add(bytes16)","801161b0":"setMain(address)","80117026":"FRAC_BOT()","801298fa":"changePaymentFlagger(address)","80130383":"LGCY()","801336cb":"STARTING_RickAndMorty()","8013f267":"calcUnMaskedGuEarnings(uint256)","8013f3a7":"dev2()","8014f238":"editCard(uint8,string,string,string)","801512af":"SvinChainToken()","8015a96d":"For_admin()","8015e6f3":"getDungeonPower(uint256)","8016b6ed":"getKeyValue(address,string)","80173a19":"geneManager()","8017732d":"LDT()","801a115d":"transfertCopieExecutoire(bytes32)","801a1467":"swapFor(address)","801aba56":"etherProceeds()","801b4189":"claimRental()","801c334e":"auctionIncreaseBid(bytes32)","801db9cc":"MIN_CAP()","801e2593":"maxAllowedAmount(address)","801f568e":"SpenderAuthorization(address,bool)","80200e12":"subFreelancerTotalInvoiced(address,address,uint256)","802028c9":"createDerivative(bool,uint8,uint256,uint256,bytes16,uint256,uint256)","802049ac":"setUpgradeableTarget(address)","8020f54e":"addAssetToNetwork(address)","8020fb77":"getCurPayTable()","8020fc1f":"isDeregistered(address)","802114a8":"_removeRole(address,string)","80218eeb":"tokensIssuedTillNow()","802293c2":"getResultblockHash(bytes32)","8022fb7a":"setFrozenCoin(bool)","8023769f":"getPCAddress()","8023ffbd":"getOverallSize()","80249468":"getUserHSCeducationDetails(string)","8024c400":"limitPerDay(uint256)","8025e303":"VERSION_NUMBER()","802608a2":"setExpirationDate(address)","802644a4":"fundingEndUnixTimestamp()","8026efaa":"token18KstepCAP()","8026fe24":"FundTransfer(address,uint256,uint256,bool)","80270b33":"CSCResource(string,string,uint256)","8027dece":"updateShare(address[],uint256[])","8028bdc4":"returnedCWC(address,uint256)","8028ce6b":"claimRefundsFor(address[])","80296dec":"admin_check(address)","802a350f":"addCustomerService(address)","802b1d93":"officiant()","802b45e2":"ISBCoin()","802b8453":"setPerventValue(uint256)","802bbab2":"ChainStarBase(uint256,string,string,uint8)","802c8cda":"_cancelEscrow(address,uint256)","802cd15f":"changeDistributor(address)","802d1848":"setLimitations(uint256,uint256,uint256)","802daa62":"latinotoken(uint256,string,uint8,string)","802de8fc":"setPremiumFactors(bytes32,uint256,uint256)","802deb22":"TokenTrader(address,uint256,uint256,bool)","802ea720":"getTotal(bytes)","802eb89c":"_getWeight(uint256)","802f2ffa":"_addPayment(address,uint256,uint256,uint8)","802f5bae":"ADDITIONAL_PORTION()","80311bf9":"buyCore(uint256,uint256,uint256,uint256)","8031233c":"inflationCompBPS()","80318be8":"transferOverride(address,address,uint256)","8031e85c":"calculatePremium(uint256,uint256,uint256,uint256,string,string,string)","80322cbd":"isNowApproved()","80325b2d":"queryN(uint256,string,bytes,uint256)","8032751b":"returnInvestments(uint256)","803287de":"_frozenTokens()","80330982":"sendEther(address,address)","80334b8f":"TomBit(uint256,string,uint8,string)","8033c643":"ROSCAv1(uint16,uint128,uint256,address[],uint16)","8033cc70":"StealthToken()","8033fe49":"releaseEnd()","80341744":"contactsAddresses(uint256)","803435d7":"startDefinedGameManually(uint256)","80355798":"isAlreadyUsed(uint256)","803587ae":"invalidateCertificate(bytes32)","8036b5db":"setPresidenteDeMesa(bytes32,uint256,uint256,bytes32)","8036d757":"getRateUpdateBlock(address)","80373436":"setSecondaryGameManager(address)","80378b78":"setShopRunning(address,bool)","8037bfe0":"unRedeemedMTU()","803965c4":"amountFixed()","803a62ea":"Register(uint256,address,address)","803b4c11":"OwnerUpdate(address)","803c64c3":"GetCardList(address)","803c6fa9":"getWeiTokensOwed(address)","803c8383":"getKey(address,address,uint32)","803cc0d0":"kscTransfer(address,uint256,string)","803d65ff":"_sendtoken(address,address,uint256)","803ea2ee":"MoneyTransfered(address,uint256)","803fbe5b":"paymentRegularTokens(uint256,uint256)","803fcd43":"check(address,address,address,address,uint256)","80402564":"addrList(uint256)","8040cac4":"testOverflow()","80412042":"decrementOwnedTokensLength(address)","8041fcc4":"AVMToken()","8042b215":"developerPctX10K()","8042fba5":"newEscrow(address,address,address,uint256,bytes32,bool)","8043154d":"post(address,bytes32,bytes32)","804327bb":"buyPreIcoTokens(uint256)","8043c9c0":"eventName()","8043cf2d":"mintB()","8044c67e":"updatePrizes(uint256[])","804518a8":"nic()","8047ba70":"getTokensAmountUnderCap(uint256)","8047cb93":"createGame(bytes32,uint256,address)","8047cf41":"init(uint256,string,uint8,string,address)","80496fd6":"CaData()","804afd9e":"vigAddress()","804afffb":"tokenIndexToPrice(uint256)","804b55d5":"finaliseAs(address)","804ba97a":"tryGet(bytes)","804c68aa":"allocateTCLRinTeamTokens()","804c7fa0":"_migrateExoplanet(uint256,string,uint256,uint32,string,uint32,uint8,string,address)","804d564c":"whitelist10Addresses(address[10])","804d77c8":"approveLoanIdentifier(bytes32)","804e11dc":"testThrowsDisownNotTransferable()","804e1c53":"_updateProfit(uint256,bool)","804e8063":"setAffiliateEdge(uint256)","804ee2b5":"addProduct(uint256,uint256,string)","804f82d3":"showLastBidValue()","804fe7ac":"acceptBid(address,bytes32,uint256,uint256,uint256,uint256,bytes32,uint8,bytes32,bytes32,uint8)","805013c2":"setPresalePhaseUInt(uint256)","80504271":"fundingExchangeRate()","80519ac7":"getItem(bytes,uint256)","8051d02d":"getBlockNumber(bytes20,uint8)","805210b7":"AmIPlayer2()","8052191e":"dip(address)","8052474d":"Name()","80528865":"changeWithdrawState(uint8)","80529172":"setUsdPerEthRate(uint256)","8054b2f2":"NKN()","805553e8":"randMod(uint256)","80559357":"setTokenAvailable(bool)","805593db":"storeProductReference(address)","8055d33a":"exchangeSgnForSga(address,uint256)","8055dbb5":"GetExchangePoint(uint8)","8055f9d7":"Moderated()","80560a0a":"setIsProjectBonus(bool)","8056696e":"loadController(address,address)","80570d69":"JoshuaCoin()","80571e93":"UranBank()","80576150":"BoughtViaJohan(address,uint256)","8057b96d":"buyTokensForSelf()","8057e0b0":"DutchAuction(address,uint256,uint256,uint256)","8059382a":"setGasInTokens(uint256)","805996f2":"AccountCreated(address)","80599e4b":"remove(string)","8059e804":"ethealMultisigWallet()","805abe6a":"destoy()","805b8455":"bumpRound(uint256)","805b90d6":"unlockTokensAmount(address)","805bc096":"Roll100()","805c2b6c":"broadcastOpinion(string)","805c3abd":"getPreviousHashUint()","805c3d89":"SimpleLSTDistribution(address,address,uint256,uint256,uint256,address)","805c733b":"lottoBalance()","805d2679":"rndIssue(address,uint256)","805e99e0":"isFirstRound()","805f4cfc":"TosTeamLockContract()","80603faa":"isTakePermitted(uint256,uint256,address,address,uint256,uint256)","80615ffa":"receiveApproval(address,bytes)","806186f3":"LogRewardAllocated(address,uint256,uint256)","8061a159":"TokenSoftCapReached(uint256)","8061d365":"FINANCE_CAP_PER_ROUND()","8062d3e6":"insertAndCheckDo(bytes32)","8063ab78":"setWalletsDelegate(address)","8064696b":"getOraclizePrice(string)","80657151":"patronRewardMultiplier()","8065eaa6":"CreatorWithdrawAll()","80661555":"commandMintBonus(address)","80664ba0":"ProofTeamVote()","80667509":"MYGREATTOKEN()","80667aa8":"CBN(address)","8066f3c8":"totalSTACoin()","8067f7ba":"read_i16()","80690e01":"IsAirdrop()","80691858":"GoalReached(address,uint256,bool)","8069dc2d":"ThundervsJazz()","806a2a3c":"investors_needed_until_jackpot()","806ad169":"getWithdrawal()","806ad57e":"addWorker(address)","806b0365":"changeBountyWallet(address)","806b39ab":"crownTotalSupply()","806b6c28":"GetCurrentTypeSalePrice(uint256)","806b984f":"lastBlock()","806ba6d6":"founder2()","806bd2b6":"challengeCooldownTime()","806c6188":"adjustMinimumPledgeAmount(uint256)","806cdc0b":"getBonusBalance(uint256,uint256)","806e085e":"transferBatch(address[],uint256)","806ee278":"collectionFunds()","806f208a":"invalidPayments(address[],uint256[])","806f3319":"multipleTokenDistribute(address,address[],uint256[])","80710f39":"withdrawAllToOwner()","8071a7ba":"PCTToken(address)","8071aa05":"multisend3(address[],uint256[],uint256[],address[],uint256[])","807283df":"Patronage(string,address,address)","80738c4d":"USTM01()","80744a9c":"LoyelaTestCoin()","8074e31d":"Victory(uint256,string,uint8,string)","8074f332":"droneIndexToOwner(uint256)","8074fe33":"minerCurrentChallenge()","80759f1f":"getRootHash()","8075acd0":"couponBonusEnabled()","80766b68":"Bitcoin1()","807693b6":"grantPermissionToChange(address,uint256,bool)","8076bd41":"set_sale_closed()","8076f005":"cancelledOrFinalized(bytes32)","8077ccf7":"etherTokens(address)","80780801":"LimitedSetup(uint256)","80787f2c":"terminateSale()","80788cba":"CancelSubscription(address,address)","807896d5":"voteProposal(uint256)","8078cc57":"_changeLicenseTerms(bytes32,bytes32,bool,uint256,bool,uint256)","807a599c":"mintFinish()","807a87ed":"YouAreHere(uint256)","807b08c7":"runScript(bytes)","807d2da3":"start_ICO()","807d782e":"crcWithdrawAccount()","807d94a7":"maxIssuableSynths(address,bytes4)","807e5cee":"WhitelistUnset(address)","807eb7cd":"sumICOStage1()","807f08ea":"totalDepositedEthers()","807f0ac5":"slice(bytes,uint256)","807f3bce":"adminGetLastSignedTime(address)","807fb834":"resetRaz(uint256)","80806362":"IssueTokenFactory()","808134c8":"setBoardMember(uint256,uint256)","8081a1e7":"ecmul(uint256,uint256,uint256)","8082a929":"holderAt(int256)","8082ee0d":"Exchange(address,string)","80833d78":"unauthorise(address)","80836cab":"enableUpdates()","8084ee58":"setMaxLimit(string,uint256,uint256,uint256)","8085de8b":"MOBToken()","808615ac":"stake(address,address)","8086b8ba":"accountOf(address)","80870bc1":"trackBuy(address,uint256,uint256)","808757ac":"getFreeBat()","8087da3a":"order_number()","8088e0b6":"turnOffCanUpdateNextGamePotSplit()","80892b8a":"calculateTokensReceived(uint256,uint256)","8089d001":"getHashOfBlock(uint256)","808a69e2":"tokenAddressesSet()","808ab1d6":"getCertificationDbCount()","808ac94d":"getWeaponIds()","808ae9f8":"MoveLearned(uint256,uint256)","808c1499":"setIcoPhase2(uint256,uint256)","808cf58e":"initial_reward()","808e0ae2":"platformLogin()","808f30f3":"BitEyeToken()","808f3652":"calcHash(string)","808f4d21":"incentivisingEffortsAddress()","808f8292":"Menu03()","808fc72c":"wasSaleStarted()","8090114f":"percentRate()","809051db":"ipfs_hash()","80906b13":"controllerClaim(address,uint256)","80908b11":"Advertisement(address,address,address)","8090b131":"fetchNumber()","8090d83c":"jackpotProportion()","8090e4d5":"core(uint256,uint256,uint256,uint256,uint256)","8090f92e":"revealVotes(uint256[],uint256[],uint256[])","8091bfc9":"STEM()","8091d7a5":"addCustomField(uint256,bytes32,bytes32)","8091f3bf":"launched()","8091fbe1":"gen0PresaleCount()","8091fc76":"isValidICOInvestment(address,uint256)","80921070":"AvocadoToken()","8092285e":"setODEMClaim(address,bytes32,bytes,bytes32)","809282b2":"EtherTower()","80929e5b":"setBurnable(bool)","80943252":"numGamesTimedOut()","80947d17":"Verification()","80948ddd":"calculateTokenToEth(uint256,uint256)","8094ebe3":"joinGame(address,uint256,address,address)","80956021":"Concept(address[],uint256[],uint256,bytes,address)","80956e8b":"setMintFeeProp(uint256)","80959721":"poster()","80959cb6":"getCloseAmounts(uint256,uint256,uint256)","8095ab76":"songWriterSign()","8095cc36":"createForecast(uint256,uint256,uint8,uint8,bool,uint8,uint8)","8096bac6":"setNewMaxDeposite(uint256)","80972a7d":"ok(uint256)","809837c1":"ITECToken(uint256,string,string)","809841aa":"getCompte_25()","8098e45e":"getRamdon()","8098f67c":"ApexIssued()","80994e15":"STUDToEth()","80999b71":"removeBaseWhitelist(address[])","80999cc0":"MarketplaceInformation(address)","8099f357":"milliTokensPaid()","809a6173":"testCompare()","809a812c":"immlaToken()","809a9e55":"getExpectedRate(address,address,uint256)","809ae91e":"setBattleStart(bool)","809b296d":"consumeOperation(bytes32,uint256)","809c5b9e":"votingDescription()","809d7902":"rejectBid(address,uint256)","809d8988":"getTribe(string)","809d9a94":"transferMonster(address,address,uint64)","809dab6a":"getAvailableBalance()","809e243d":"LanxangCash()","809e4a2d":"claimUnrented()","809e52b2":"updateExperience(uint256,uint32)","809ef92f":"crowdsaleStarted()","809f8cc9":"VersumToken(uint256,string,string)","809fc4f8":"MKRUSD()","809ffb20":"setShopModerator(address)","80a0155c":"RBACMock(address[])","80a0c461":"updateMinimumPodSize(uint256)","80a15ad9":"setRocketValues(uint256[],uint256,uint256[],uint256[],uint256[])","80a1a86b":"countPayment(address)","80a1ba6a":"getTimeLeftToNextCollect(address,uint256)","80a1ec2e":"initUser(uint256)","80a23ddf":"mintBadge(int256,address,uint256)","80a2ddad":"founder4()","80a37e23":"recordHighScore(uint256,address)","80a3a783":"presaleStartDate()","80a3f8b4":"getWorkflowName(uint256)","80a3f9b3":"bonusCapUSD()","80a429ee":"VitaminToken()","80a507c6":"is_started_bonuses()","80a51c5e":"ownerDeclareRefundStart()","80a54001":"parentToken()","80a5cca3":"approveViaProxy(address,address,uint256)","80a6ee7d":"totalTokenBetValue()","80a738bf":"withdrawHighscorePot(address)","80a92b67":"payReward(uint256,address,uint256)","80a973e6":"sendTeamBalance(address,uint256)","80a979e1":"crowdsaleTransfer(address,address,uint256)","80aa5757":"getEtherForTokensOld(uint256)","80aab099":"nextAllowancePeriod(bool)","80ab611e":"cancelRecurringPayment(bytes32)","80abb85b":"refereds(address)","80ac5448":"operatingAddress()","80ac613f":"BatchCreateSales(uint256[],uint256,uint256,uint64,address)","80ac80b0":"iterStart()","80acaafb":"profitDistribution()","80ad17b2":"removeSiteSet(uint256,uint256)","80ad2cf3":"setCap(address,uint256)","80adede0":"currentLoanAmount()","80ae4ebc":"_initialize()","80aed05f":"LooneyDice()","80af6002":"minimumICOCap()","80af6d79":"addEmissionProvider(address,uint256)","80afd844":"getPrivateFundAddres()","80afdea8":"appId()","80b022e8":"changeBurner(address)","80b20208":"thePot()","80b29f7c":"revokeDelegate(address,bytes32,address)","80b30c13":"tokensToSold()","80b38c2d":"ProcessTxFee()","80b3c3d8":"buyTokensWithIcon(address,uint256)","80b44c1b":"extraStatsForGen(uint256)","80b52136":"MoneyCoinCoin()","80b525ce":"BurnableTokenWrapper(address)","80b57824":"discount(uint32,uint256)","80b63e7e":"wakeUp(uint256)","80b6518a":"createEmptyTrack()","80b69199":"releaseBonusTokens(address,uint256,address,bytes1)","80b7ca90":"OrderList(address)","80b855d6":"ZiggyToken()","80b8e6d1":"changeWhitelistStatus(address,address,bool)","80ba4b75":"getActionsCount()","80bb3360":"exchangeToIco(address)","80bc150d":"Bounty(uint256)","80bc99cb":"teamLocker()","80bd0936":"Multivest()","80bd2723":"SecurityChainToken()","80be3cc4":"BurnTokensNew(uint256)","80bf099e":"orphantoken(address)","80bf549a":"maxICOSecondSupply()","80bf98f8":"makeSwapInternal()","80bfbe68":"setWhitelist(address,address,uint256)","80bfc599":"sellVouchers()","80bfe883":"wins(uint256)","80c05bc6":"random_callback(bytes32)","80c0a250":"fetchVoteResultForCandidate(address)","80c18d45":"addAddressToFounders(address)","80c190cf":"getReservedTokensListValInPercentage(address)","80c2fb7d":"currentTreasure()","80c30f3d":"buyContract(address,uint256)","80c324cf":"isBallotInProgress(uint32)","80c3780f":"schedules(address)","80c399f4":"refundInvestors()","80c3f96d":"addFarmer(address)","80c4237f":"tryToWin()","80c4e5c5":"changeSynthesizeAllowed(bool)","80c5bef8":"UGToken()","80c6ff73":"keepaliveBlock()","80c7507a":"getMigration(uint256)","80c80611":"Withdraw_3()","80c810d5":"MucToken()","80c81c16":"getStateInfo()","80c86c30":"CommonError(bytes)","80c8a270":"tokenReserved4Deposit()","80c8fde7":"perTokenAmount()","80c951bf":"currentClaimPriceInFinney()","80c96527":"getAssociatedTAOSetting(bytes32)","80c99dd2":"getPeriodicalBudget()","80ca7aec":"forceReseed()","80caac1d":"setTitleImage(string)","80cae007":"cleanOcean(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","80cd0015":"migrateUsername(bytes32,uint256,uint256,address)","80cd2464":"offer(uint256,uint256,uint256)","80cd5ac3":"newAppInstance(bytes32,address)","80cda248":"EGGS_TO_HATCH_1TOAD()","80cdc9c9":"RESTRICTED_PERIOD_DURATION()","80ce60d1":"setResult(uint8)","80cecea9":"transferToContract(address,uint256)","80cf264d":"getFirstPhaseCap()","80d07ce8":"Gifto()","80d10934":"freeXLMG()","80d1bd47":"jackpotHit()","80d1cb35":"getDeploymentBlock()","80d24e9d":"SISKTechnologyGroupToken()","80d2c1a6":"CatRescued(address,bytes5)","80d32dbb":"ChaoExToken()","80d32f85":"isSoftCapReached()","80d52ed9":"switchToNextRound()","80d563d7":"LogCancelContractProposal(address,address,uint256)","80d61012":"canReceive(bytes32,address,address,uint256,bytes,bytes)","80d7bcba":"incomingTokensTransactions()","80d7d81a":"giveMeBackMyMoney()","80d7f7ac":"TaxicToken()","80d7f92a":"_address(address,uint256)","80d85911":"initialize(uint256,uint256,uint256)","80d8b380":"setQtyStepFunction(address,int256[],int256[],int256[],int256[])","80d8ce23":"publishBytes(string,bytes)","80d95b42":"supplySeed()","80d9eaa6":"refCount()","80daa1c6":"setDiscountForPlayer(address,uint256,uint256)","80db79d9":"StructAndFor()","80dbb7d2":"RacingClubPresale()","80dbde63":"PI_EDIT_4()","80dcaf27":"getRefNumber()","80dcbff1":"getAdminArray()","80dce0b4":"getAwardTime()","80dceec4":"setHuntingPrice(uint256)","80ddcc62":"SUPPLY_HARD_CAP()","80ded586":"removeFromTokenHolders(address)","80dee9d1":"miningStorage()","80df2cee":"TeddyChain()","80df4123":"NucleusVisionTimeVestingTokensMinted(address,uint256,uint256,uint256,uint256)","80dfa34a":"saveBatch(string)","80dfb104":"setCoOwner1(address)","80dfee5c":"NewSale()","80e039f9":"rocketGetResourceValues(uint256)","80e0c053":"MassERC20Sender()","80e13b10":"CompanyTokenIssued(address,address,uint256,uint256)","80e15b56":"cancelCredit(address)","80e15f76":"setBuildPrice(uint256)","80e183a3":"CLASS_PLANT()","80e1b9c4":"finishBattle(uint256,address,address)","80e2517c":"TokensPerEther()","80e2653e":"setDougAddress(address)","80e2d53b":"rateWaitingEnd()","80e339fc":"balancewof()","80e37b5f":"maxIssuableNomins(address)","80e3f1ad":"toggleWhitelist(bool)","80e47e71":"maximumValueWithoutProofOfAddress()","80e52f31":"EtherCash1()","80e5d7b0":"Voted(uint256,uint256,uint256,bool,address)","80e5e069":"ITO_TOKENS()","80e64e8b":"buyBottle()","80e6bffb":"CalculateBankCredit()","80e74b04":"testControlUpdateLatestRevisionEnforceRevisions()","80e8b12a":"_createDungeon(uint256,uint256,uint256,uint256,uint256,uint256,address)","80e9071b":"reclaim()","80e9a1da":"STATUS_LENT()","80e9e9e1":"getClaimIdsByTopic(uint256)","80e9f98c":"getRacer(uint32,uint256)","80ea8273":"SetBonus(uint256)","80eb1cbc":"monsterIdToIVs(uint256,uint256)","80eb6b7f":"LogRemTokenPairWhitelist(address,address)","80ebb08e":"updateResult()","80ebed20":"createBook(address,address,address,uint256,int8)","80ec35ff":"awardByRndNo(uint256)","80ec4a96":"CrowdsaleFinished(uint256)","80ede329":"getDocumentDetails(uint256)","80edef8e":"owner_address()","80ee9792":"_ethDeposit()","80ef353d":"tryClose(bytes32)","80efa4af":"extBuyTokens(address,uint256,uint256)","80f034b1":"getContractBytecode(string)","80f03fa6":"getTotalPets()","80f183ce":"visitCost()","80f20363":"lockToken(uint256)","80f29894":"getWeiForCent(uint256)","80f2fa03":"getSellPrice(address)","80f34c14":"ContortedCoin()","80f393c8":"ProofOfIdiot()","80f3f094":"setGGCAddress(address)","80f41e76":"calcMintFee(uint256)","80f4432a":"inception()","80f4531f":"closeTimerElapsed()","80f4ab5f":"seeMyNumbers()","80f4bcb8":"tokenTeamAllocated()","80f55605":"market()","80f5a37c":"Crowdsale(address,address,address,uint256,uint256)","80f5e0a1":"shouldBoost(bytes32)","80f6c383":"setshares(uint256,address)","80f6d782":"swapAddress()","80f7d0ab":"storeReading(uint256)","80f7e238":"ANIMETOKEN()","80f86009":"Initialize()","80f89a31":"ballotNames(uint32)","80f89bce":"distributeDRMK(address[],uint256,uint256)","80f8d688":"redTeamAddress()","80f8ea60":"Put_BRTH_GFT(address)","80fa272f":"TokenWithMint(string,string,uint8,uint256)","80fa4517":"completedTasksCount()","80fa7902":"getPlayersBattleStats(address)","80fa7942":"tokensForReserve()","80fa860f":"executeElectionMandate(uint256)","80fc16c8":"setAffiliateFee(uint256)","80fe4958":"createBetWithPayable(bytes32,bytes32,bytes16,bytes32,uint256)","80febdbd":"updateMe(string)","81001f3c":"collectFee(address[])","810164f7":"getTotalBPOfAddress(address,address)","81016509":"getBtcRequestHash(bytes,bytes,uint256)","8102387d":"burnRedRibbonCoin(uint256)","81030e35":"ALAP()","810405d6":"numOfPurchases()","81042183":"ExpeditingToken()","81045ead":"getIndex()","8105aa55":"grantAdvisorTokens(address)","81064e2d":"getCreditorAmounts()","8106d57a":"getCityPendingBuildings(uint256,uint256)","8107b269":"Novatore()","81081184":"bursarPayOutNetContractBalance(address)","8108592c":"calcKncStake(uint256)","81086763":"placeNewBid(uint256)","81086918":"delAcceptedToken(address)","8108e54c":"marketAllocation()","810a192b":"transferCollateral(uint256)","810a217f":"pValidationState()","810a3919":"hard_limit()","810a882f":"setConfigBytes(bytes32,bytes32)","810ac3ce":"IssueOffer(address)","810ba058":"Public_Sale_SUPPLY()","810bbec3":"claimHelper()","810be182":"_updateCountries(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","810c0af8":"depositTokenByAdmin(address,address,uint256)","810cbbd0":"bat_match(uint256[39])","810cf6cb":"MRazaAnisTestCoin()","810d54a0":"lockBalanceChanges()","810e4ff0":"cashOut(address,address,uint256)","810e78ab":"declareIcoFinished()","810e9720":"GlobalCoin()","81104666":"advisoryWithdraw()","8111e0ad":"updateMaxTxGasPrice(uint256)","8111ecef":"FinalizeStage()","8111f24e":"isFreezed(address)","81120dd7":"myLastRef()","8112821f":"EthVentures()","8113e285":"withdrawTokenPayment()","8115a2ac":"getOnMintTargetValue()","8115f52d":"Evacuated(address)","8116c063":"claimOwnersEarnings()","811743e7":"fighterIndexToOwner(uint256)","81183633":"setStandard(bytes32)","8118e0ae":"dtValidateWorldSnapshot(uint256)","81193a30":"returnRequestCancel(uint256)","81195993":"allocateEcoFundToken(address[],uint256[])","8119c065":"swap()","8119f4ae":"getRoc(uint256)","811a0a85":"saleComplete()","811aecf4":"finishPhase()","811b1268":"noteSale(address,uint256,uint256)","811bab32":"GenesisCallerAddress()","811c626d":"changeIcoRoundEnding(uint256)","811c66ac":"nameSuccessor(address)","811de206":"isConfirmedByOwners(uint256)","811e1468":"computeAccount(uint256)","811e4f71":"DisburseEarnings()","811e539c":"campaign()","811ea6de":"transferToken(address,address,uint256,bool)","811f273d":"hasThreeYearWithdraw()","811fe466":"beginTime_()","81207183":"deployGLX()","8121b0d4":"verifyStoredData(bytes32)","8121dbc1":"MyPizzaPieTokenPreSale(uint256,uint256,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256)","8121ddd7":"RATE_DAY_7()","81236e47":"setUserYan(address,uint32)","812403f6":"bonusPhaseThreeDeadline()","81240b9c":"subWithdrawFor(address,address)","8124bb0f":"continueExecution()","81252548":"getContractServerBlackWhiteListType(string)","81252680":"getBaseQuick(bytes32)","8125c102":"BountySent(bytes32)","8125c6fd":"_getDividendsBalance(address)","8125ceb2":"showMessage()","8125fc44":"thirdPreSaleEndDate()","81263fed":"getStrandCount()","812699a9":"Quiricos()","81269a18":"voteBalance(address)","81269a56":"checkMintSolution(uint256,bytes32,bytes32,uint256)","8126c38a":"allPunksAssigned()","8126cb1e":"rejectRewards(uint256,string)","8126e4e3":"philanthropise(string)","81281be8":"placeBid(address,uint256,uint256,uint256)","81290a80":"AviciiCoin()","8129212e":"getCommonInitBlockNum()","8129519d":"setLoading(uint256)","8129aa75":"TransferFeeRateProposalAdded(uint256,address,uint256)","8129fc1c":"initialize()","812a4f47":"BeatTokenIcoPhase2Started()","812af8ec":"getAccountData()","812ba50c":"preEndBlock()","812c3251":"Escrow(address,address,uint256)","812c86e0":"updateTokenContract(address,string)","812cbf38":"sellFci(uint256)","812cddf2":"getSavedString()","812cf740":"ArrayPractice()","812d504d":"transferToOwner(address)","812d6c40":"changePercent(uint256)","812e1d1d":"APT(address)","812e6741":"Mountain(bytes32,uint256,uint256,uint256,address)","812ed5cc":"report(address,address,bytes)","812f55c3":"get10Ads(uint256)","812fd5d7":"payToProvider(uint256,address)","813051bc":"createGOP(address,string,uint256)","8130c9b2":"untrustedTokenNumerator(uint256)","8132581c":"amountRaisedInEth()","8132e223":"internalSafeTransferFrom(address,address,uint256,bytes)","81333d57":"LKB(uint256,string,string)","8134064b":"setMotherCount(uint32)","81350bd4":"releaseTimeTeamAdvisorsPartners()","8136c1b9":"registerUserOnToken(string)","8136f02d":"setAddressOfERC20OldToken(address,address)","8136fd26":"createJob(string,uint256,uint256,address)","81395866":"numberOfAdmins()","8139bc2f":"ecothereum()","813a573a":"CheckPurchaseCount(address,uint32)","813b024f":"addProductInUsd(uint256,uint256,bytes32)","813b65aa":"setNewCajutel(address)","813d13cb":"getBB(bytes32)","813d599f":"getValidatorAddress(int256)","813d6c9a":"bonusPercentage()","813d89e1":"artExplain()","813df488":"preMinedFund()","813e7847":"withdrawalNormal()","813e9aca":"init(address,uint256[],uint256,uint256,uint256,uint8)","813f4db4":"isStakingPeriod()","813f563a":"devsHolder()","813f5717":"LinkRevenue()","813fdec8":"getContestStatusForDate(uint32)","8140ce63":"kvtOwner()","8140d0dc":"setContact(string)","8141fd37":"tickRequiredLog()","8142453f":"_saveRequest(address,address,uint32)","8142a25a":"testAliceFooSend()","8142b8d7":"editGardener(uint256,uint256,uint256)","8143e3da":"allBonus(address,uint256)","8143eb2d":"gameOpened()","8143f8a8":"totalGas(bytes)","8144650a":"transferTokenTo(address,uint256)","814487c4":"addSuperReferrer(address,uint8)","8144ee2f":"adventureSettingContract()","8146f323":"isFinalised()","8147bcf7":"deletePlatform(bytes32)","8148d2fe":"getNodeId(bytes32,bytes32)","8149657b":"closeEthPool(uint256)","814971de":"issueReward(uint256,uint256,uint256[],uint256)","8149ea9b":"randomSkill()","814a78f4":"KM(uint256,string,string)","814ab9f1":"salesSupply()","814ae0ba":"gcf()","814b3fe0":"dividends(uint256)","814b53b0":"killCoin()","814c25fc":"setTokenInformation(bytes32,bytes32)","814c2aa1":"changeTotalExchange(uint256)","814e23c8":"calculatePayout(uint256,uint16)","814e3bd3":"ContribToken(uint256,string,string)","814e5c9b":"totalSaleAmount()","814e6d44":"_unpackIdValue(uint256)","814eba9e":"simPunitiveInterestRate(bytes)","814f737d":"phaseThreeEnd()","814f9201":"payUserIncomingTransactionCommission(address)","814fbd8f":"RefundBTC(string,uint256)","81508615":"getBeneficiaryDevelop()","81516c7b":"initialTIPsupply()","8152c7ed":"adminSetRandomInput(string)","81531c64":"Strike()","81547f25":"CONI()","8154b57c":"secondsAfter()","8154d4de":"setMarket(bytes32,bytes32)","81550287":"PRESALE_CLOSING_TIME()","81553709":"releaseEndTimeOfStage(address,uint256)","815639ea":"read_u64()","8156afdf":"Aletheia(address,address,address)","8157d4b5":"bindContract(address)","81580761":"getUniqueLineCount()","815847df":"_addBonusOfReferrer(address,uint256)","81584ff3":"CutieBitToken()","81587463":"sendTradeEvent(uint256[],address[])","81592aab":"instantUpdate()","81597d0c":"mintIcedToken(address,uint256)","815a4876":"setEthereumWallet(address)","815bc7a0":"vote_reward_pool_amount()","815c326d":"ProducerOperations()","815d1fe5":"RewardChannel(address,address,address)","815dcd36":"dailyAccounting()","815def1a":"changeAllocation(address,int256)","815eb7c1":"satoeContract()","815ec64a":"zReceiveFunds()","815f73f0":"m_walletAddress()","816036ae":"removeSmartContract(address)","8160b246":"BONUS_TIER3()","8160f0b5":"minimumQuorum()","81613a62":"LogPause(bytes32)","816163b1":"checkGameResult(bool)","81617f8f":"reLoadXaddr(uint256,address)","81619954":"DAOFactory(address,address,address)","8161c5e5":"main_balance()","8161dfa6":"EmailSent(address,uint256,string,string)","8161f0e1":"execID()","816273f6":"computeAmountBonus(uint256)","8162de9c":"getCryptoAvatar(uint256)","8162f631":"LogFunderInitialized(address,address,string,uint256,uint256)","8163681e":"isValidSignature(address,bytes32,uint8,bytes32,bytes32)","816413f8":"transferPreSignedHashing(address,address,address,uint256,uint256,uint256,bytes)","81641ff7":"casinoBank(address)","81646be8":"setCloseTime(uint256,uint256)","8165354e":"setOracleRegistry(address)","8165913d":"withdrawEthBalance(address,bytes)","81671042":"setOptionLibrary(address)","81676ecd":"FGorToken()","8167d996":"deAuthorize(address)","8168b41e":"TokenTWL(uint256,string,string)","816a873f":"createMorePaymentChannelsInternal(uint256)","816b6574":"LogCrowdsaleFinalized(bool)","816bf490":"transferTokens(uint256,address[],address,address)","816bff5f":"CIFCoin()","816c4ad1":"baseIntCalc()","816c66c9":"updateRank(bytes32,bytes32,uint256,bytes32,uint256)","816c76e3":"GoozeToken(uint256,string,uint8,string)","816c7da4":"approveAllAndCall(address,bytes)","816ca77c":"CollateralSeized(address,uint256)","816d199c":"SIGMA_FTL_SPEED()","816d3da9":"purchaseAdmin()","816d3dc1":"get_info(address)","816dbae4":"monethaVault()","816e117c":"setMaxSize(uint256)","816e24b0":"setupDeposits()","816ed336":"emitFeeSet(uint256,address)","816f3438":"maxFoundationCapUSD()","816f3f4d":"madKing()","816fceb7":"MultiTransaction(address,address[],uint256[])","816ffbab":"Uint256Oracle(int256,uint256)","81702c34":"refund_me()","8170733d":"MyBitFoundation()","81710c78":"getMyPolicies()","8171362a":"votingByXid(uint256,bool)","81715d8c":"pIdIter_()","817189df":"setEarlyLimits(uint256,uint256,uint256)","817246cf":"setsalesdeadline(uint256)","817287d0":"isOwnner(address)","8173832a":"LogUnsortedOffer(uint256)","8173b813":"setNumCities(uint256,uint256)","8173e363":"hard_cap_wei()","817472c0":"TOKEN_INIT(bytes32,bytes32,bytes32)","8174b6d7":"ownerCutPercentage()","81751312":"getAllCardsModifierPrimaryVal()","81758fb4":"bohwa()","8176419f":"SCCC(uint256,string,string)","81767aed":"getIdentifiers(address)","817725aa":"disableChangesMultitoken(uint256)","81776ba4":"backup_refund(uint256,uint256)","81777b78":"Take(bytes)","8177ffae":"PresaleContract(address)","81788e2b":"addAllowedAddress(address)","8178a943":"add_scribe(address)","8178ab99":"_transferFromSenderPaysFee_byProxy(address,address,address,uint256)","8179c2b3":"Result(uint256,address,uint256)","817ad683":"XHO()","817afff8":"_updateWithdrawCountry(uint256,uint256,uint256,uint256)","817b106e":"setChangeIdentityNarcoRespect(uint256)","817b1cd2":"totalStaked()","817b90fe":"getCategoryId()","817c1e52":"startICO(uint256,uint256,uint256,uint8)","817c7483":"settleLeague()","817c8966":"getLevel(address)","817d62a4":"shouldGetHighFive()","817e8332":"STAKE_BONUS_RATIO()","817e9d31":"setFactor(uint256)","817eca0c":"ConstructByEth(uint256,uint256)","817edbd2":"set(uint32,uint8)","817f0023":"recievePayment(address)","817f688f":"BLAAICOIN()","81807a07":"calculateBonusAmount(uint256)","818097c5":"getVotesForCandidate(address)","8180f2fc":"approve(address,uint256,bytes32)","81813963":"claimEDEX(address)","8181b029":"confirmImplChange(bytes32)","818211f8":"getProposalsNum(address,uint256)","8182173c":"PricesUpdated(address,uint256,uint256)","81824d53":"setData_1(uint256)","8182c6a7":"IssueToken(string,string)","81830593":"adminAddr()","818438ca":"getWizzPandaQuotaOf(uint256)","8185402b":"buyAllAmount(address,uint256,address,uint256)","8185b8e9":"getWeiPerCent()","81862f25":"newThreadComment(bytes32,bytes32,string)","81884756":"citationCount()","8188f71c":"holders()","81895b73":"registry(bytes32,address,address)","818a19b5":"FeeAddr1()","818a4b48":"preSaleMinAmount()","818ad300":"TeamVesting(address,uint256,uint256)","818b4564":"DefineType(address,uint32,string)","818c2858":"HPCToken(uint256,string,string)","818c606f":"NewAuction(address,uint256,uint256,uint256,uint64,uint256)","818d4b5d":"owns(address,uint256)","818e8cfa":"setLogoURL(string)","818f7d01":"checkTransferFunctionPrivateSale(address,address,uint256)","818f92c7":"createPurchaseOrder(address,uint256,uint256,bytes32)","818fd7a1":"beforeBuy()","81904676":"lastDistributedAmount()","8190cf07":"setRate_ETHUSD(uint256)","81915a67":"EventSetContract(address,string,address)","8191745f":"Description()","8191ab45":"setUsdConversionRate(uint256)","8191b9a2":"__tokenAndWalletBalancesMatch__(address,address,address)","8191d30f":"crossForking()","81923240":"mine(address)","8192433f":"receiveTokenDeposit(address,address,uint256)","8193327b":"test1Bob()","8193844b":"linkIssuerName(bytes32)","819384a2":"payoutToReferrer()","8194aff3":"Matchpool()","8195031f":"Bitsta()","819512cd":"buyTokens(address,uint256,address)","81961946":"NETR()","8196410b":"GustavoCoinCrowdsale(uint256,uint256,uint256,address)","8196b8c7":"getValueOrZero(bytes32)","81980c27":"SOLOBOT()","81981f7c":"getMyFranklin()","8198edbf":"getFeeRate(address)","819912a2":"setGame(address)","819927e7":"transferUserTokensTo(address,address,uint256)","819abe80":"giveFreeUnit(address,uint16)","819ad6d6":"EstimatedICOBonusAmount()","819b0293":"validPosition(uint256,uint256,address,uint256)","819b25ba":"reserve(uint256)","819b9773":"PaymentAvailable(address,uint256)","819c5773":"withdrawForMany(address[])","819cfdf1":"YFTToken(uint256,string,string)","819e3903":"LogTrade(uint256,address,uint256,address)","819ee03a":"InterfaceId_ERC721()","819f2494":"createOffer(uint64,uint256)","819f255a":"is_passcode_correct(uint256,bytes32)","819f5e24":"burnAndFinish()","819f8927":"setMilestonesList(uint256[],uint256[],uint256[])","81a00361":"YONDcoin()","81a03133":"authorizePayment(uint256)","81a084fd":"remainingGasRefundPool()","81a09bf0":"mergeMedal(uint256,uint256)","81a1384b":"LockedVotingTokens()","81a1fa02":"itemsCounts()","81a22b41":"PaymentsProcessed(address,uint256,uint256)","81a22bee":"reservePart()","81a238b5":"thirdWavePrice()","81a2568d":"setXToken(address)","81a2824f":"getUserBet()","81a28c28":"isSecured()","81a33a6f":"bytesToUInt(bytes32)","81a3b17f":"removeFace()","81a46662":"rolloverPercent()","81a4af15":"rewardTokens(address,uint256)","81a5ad6d":"YamatoCoinCrowdSale()","81a5e88b":"ICOCompleted(uint256)","81a60c0d":"getResults(uint256)","81a73ad5":"getTokenSymbol(address)","81a752ef":"removeSdaContract()","81a7a503":"ActiveProposalNum()","81a7ac54":"MAX_PERCENT_OF_SALE()","81a8e78a":"getGalaxies()","81a955b0":"editInfo(uint256,bytes)","81aa5067":"addLockedAccount(address,uint256,uint256)","81aa8a4b":"pre_PRICE()","81abb800":"lengthOfKeys(uint256,uint256)","81ac9b93":"AuctionCancelled(address,uint256,address)","81accd0b":"create(bytes1,bytes32,bytes32)","81add559":"partners()","81ade307":"query(string,string)","81ae20b2":"setInvestorsBatchSize(uint256)","81aea668":"atNow()","81aee4f4":"getNoteDesignatedReport()","81af0750":"Simt()","81af8949":"getPackBuy(address,address,uint256)","81af95fc":"startAuction(uint256,uint256,uint256,uint256,address)","81afc50d":"delegateCustodian(address,address)","81aff6ec":"get_presale_arbits_sold(address)","81b074ab":"user_on_freeze()","81b1c6bb":"getWinLoseAmountByBettingIdInGamblingParty(uint256,uint256)","81b23042":"burnMonster(uint64)","81b2d07b":"showBalance()","81b2dad9":"setByeSayer(address,bool)","81b3171c":"extGoalReached()","81b31cec":"setNextCommonTTWTokenId2(uint64)","81b3ea13":"getResponseError(uint256)","81b54498":"seedStartTime()","81b69494":"fee_ratio()","81b72d88":"startRequest_callback()","81b736e9":"createChild(uint256,address)","81b7c6e7":"stop_it()","81b7f157":"_updateSpendAvailable()","81b890fc":"setName(uint256,bytes16)","81b93757":"ADEVA()","81baf3ab":"sendTokens(address[],uint256[],address)","81baf55e":"processBuyRequest(string,address,uint256,uint256)","81baf820":"BlockScheduler(address)","81bb1277":"_calculatePointsAndRewards()","81bb2b20":"payFee(bytes32,uint256)","81bb59bf":"goodsNotOK(uint256)","81bb73af":"signArchive(bytes32,string)","81bb9470":"DNCEQUITY()","81bc3657":"migrateSinglePlanet(uint256,string,uint256,uint32,string,uint32,uint8,string,address)","81bc50ef":"getBUA(bytes32,uint256)","81bc8742":"BCToken(uint256,string,string)","81bd24d1":"revertTest()","81bd66fe":"upgradeMeAdmin(address)","81bdc78d":"getProposalAmount(uint16,uint16)","81bf1cff":"ThailandVsMyanmar()","81c0ddc3":"villageinfo(uint256)","81c1346d":"setFundsCreditDaoAddress(address)","81c2d4b6":"freeToken()","81c2d875":"getConsensusRules()","81c385b5":"safeWithdrawEther()","81c405c6":"registerCustomer(address,address,bytes32,uint256)","81c485e7":"getDiscipleSale(uint256)","81c4e1c8":"User(address,address,address)","81c56dfb":"d27d7bad()","81c59c8d":"getStrategyTokenCount(uint256)","81c5b206":"addMeToGame(uint256)","81c648e2":"betYours()","81c64ea2":"SixPlayerRoulette()","81c70870":"ClientUpdated(address,address)","81c79fd5":"transferMerchantProxy(address,address,uint256,uint256,uint8,bytes32,bytes32)","81c7ae3b":"miningEveryDay()","81c8149d":"timeOfLastProof()","81c8b563":"coinLockRemove(address)","81c92486":"ProcessRooms()","81c9786c":"administratorsLength()","81ca3ea1":"hasEitherAttribute(address,bytes32,bytes32)","81cb79ca":"createEmptyTrack(uint256)","81cbeaf0":"getValidated(address,address,uint256)","81cc49dd":"secondLoos()","81ccb678":"Confiscate(address,uint256)","81cd2ffb":"ConversionFeeUpdate(uint32,uint32)","81cd30a8":"round_c_begin_date()","81cd4570":"Moneytoken()","81cd5eec":"bonusPot()","81cd8194":"transferPrice()","81cd872a":"deals(bytes32)","81cda317":"MINTING_HARDCAP()","81cde1a9":"GOOD_ERC20()","81ce7184":"TestText()","81cebf7e":"vestingPaid()","81cedafc":"Nodalblock()","81cf7fef":"registerSmartID(string,string,string,bool,bool)","81d01ed3":"p2()","81d12c58":"requests(uint256)","81d136cb":"presaleAllocation()","81d16e0d":"_isDiamondVerified(string)","81d2c871":"SetMinFee(uint256)","81d2fd9c":"setFaucetAmount(uint256)","81d36f4e":"KEVINTOKEN()","81d38ada":"Remove_member(address,address)","81d38f2d":"SheetMusic(address)","81d3c435":"setAddresses(address)","81d434e9":"transferToICAP(string,uint256)","81d44053":"reading_length()","81d45a5c":"isPreICOPublicClosed()","81d5e753":"CuratedWithWarnings(address[],address,address[],address[])","81d693be":"claimDay(uint16)","81d6c866":"harvestabledivs()","81d77862":"newMostInviter_()","81d92ed4":"shp()","81d96005":"sigDestinationTransfer()","81d961e4":"eligible(uint256,uint256)","81d97051":"setOwnerOne(address)","81d9c5e4":"handleIncomingPayment(address)","81dafe0e":"calculateDuration(uint256)","81db6c28":"redeemVoucher(uint256,address,address[],uint256)","81dc66f4":"checkTankAuction(uint256)","81dca05c":"setAuthorization(address,address,bool)","81dd70db":"kickoffQuorumPercent()","81de10e2":"getContentAt(uint256)","81ded5b8":"numOfConfirmationNeeded()","81df464f":"totalRaisedIco()","81df893c":"withdrawMon(uint64)","81e1ccba":"stakingPercentage()","81e2ef3a":"ReceivedETH(address,uint256,uint256)","81e529cd":"setOwnerFreeDay(uint256)","81e559ae":"clientKeys(uint256,uint256)","81e69eff":"publishMetaData(bytes32)","81e6c686":"returnMaxGoal(uint256)","81e6e083":"getLifetime()","81e75dd0":"testPublicBuy()","81e7645f":"findFigures(uint256,uint256)","81e77878":"getChooses()","81e7a97e":"killMonster(uint16,uint8)","81e7e20e":"user(address)","81e7e329":"test_6_accessRestriction_removeMember_shouldThrow()","81e83991":"howMuchInEscrow()","81e8927b":"getValidationsCount()","81e8a1f7":"newRandomByte(bytes)","81e9abef":"_updateEarnedBy(uint256,uint256)","81ea4408":"getCodeHash(address)","81ea6834":"getEvilMortyAddress()","81eac2ee":"checkClientFunds(address)","81eaf99b":"lockSupply()","81eb3e01":"setValueStep1(uint256)","81ebd8de":"setDeveloperStatus(address,address,bool)","81ebdeea":"testThrowCreateWithNonceRetracted()","81ed8680":"pingTimestamp()","81edaae4":"serviceFee(address,uint256)","81edc308":"insertAndApprove(uint256,address[],uint256[])","81ef1b18":"startFundraising()","81ef93ae":"lastFueledFundingID()","81efc01d":"withdrawHouseStake(uint256)","81f0c440":"MikeChanCoin()","81f1a41b":"CROWD_SUPPLY()","81f1aad7":"setCancelApproveFee(uint256)","81f1d75c":"updateUserEmail(address,bytes32)","81f1f92a":"withdrawSoftwareProductDevelopment()","81f1fa93":"RKCAcquired(address,uint256,uint256)","81f2a3f1":"GetDownTickPrice(uint256)","81f2d44c":"getStarIdAtPosition(uint8,uint8,uint16)","81f2d4ee":"updatePartner2_will(string)","81f3e897":"getSettingData(uint256)","81f4f9bf":"ticketHolder()","81f59f51":"shareService(bytes32,address)","81f5f75c":"getApprovedProxies()","81f65883":"CompetitionStore()","81f6bf7d":"deleteCertificate(string)","81f6c7e5":"_release(uint256)","81f799e2":"reveal_end_time()","81f86241":"ExGirlfriendCoin()","81f8658a":"DATE_OPEN_ON_FLOOR()","81f8a6f7":"checkTokenSupported(address)","81f8b722":"LogIncomeAllocation(address,uint256)","81f91c4a":"transfer(address,bytes32[8])","81fab567":"maxPayments()","81fb1fb4":"participants(uint256,uint256)","81fb2585":"isOfficial(uint16)","81fb3803":"einzahlen()","81fbc084":"mul27(uint256,uint256)","81fbf0a5":"totSupply()","81fbffe1":"getGiftoAddress()","81fc4d90":"increaseLockAmount(bytes32,uint256)","81fc7f2b":"accountFrozenStatus(address)","81fcef3c":"bitcoinContract()","81fcfbcc":"allocateBountyTokens()","81fd63c2":"kanaabbcwalletcoin()","81fdbeff":"TransferCoinsFrom(address,address,uint256)","81fe5786":"max(int256,int256)","81fedc73":"Casinowo(uint256,string,uint8,string)","81feed27":"awardName(uint8)","81ff01f7":"REPOPCore()","81ff4d0b":"TEAM_TOKENS()","81ffdfab":"getTokenAmountForCampaign(bytes32)","82004053":"ownerSetZlotsAddress(address)","8200a57f":"changeOwner(address,address,bool,bytes)","8201ff14":"setNewTerrain(uint256,uint256,bytes32)","820203a3":"ztx()","82023707":"updateSecondUnionIds(bytes32,bytes32)","82024a14":"PromissoryToken(address,uint256)","820267ff":"diminishPool(uint256)","82027b6d":"isAllowed(bytes32,address)","8203e7f3":"justSendDonations()","8203f5fe":"initContract()","82043443":"transfer_(uint256,address,address,uint256)","820447fc":"TrimpoToken(uint256,string,string,address,address,address)","8204ecdd":"getFee(bytes)","82067cc0":"pauseRoundB()","8206ba89":"MAX_STAGE_2_LIMIT()","82076979":"TeamTokenHolder(address,address,address)","820776de":"DivsToRefundpot()","8207b07d":"lastPurchasePrice()","8208921d":"getWalletFor(address)","8208df23":"stack(address,uint256,uint256)","820935dd":"HDILToken()","82094fa4":"setAddressAdmin(address)","8209b38a":"Freecoins24()","8209d121":"a_viewSellOffersAtExchangeMacroansy(address,bool)","820a5f50":"fundedAmount()","820b9f1e":"kncPerETHRate()","820bec9d":"receivedETH()","820c05db":"FPINCOIN(uint256,string,string)","820c1dd0":"pollBurnQtyMax()","820c59bb":"GetIsPauded()","820c7468":"isVendorOf(address,address)","820c815e":"EGGS_TO_HATCH_1DINO()","820cfa06":"LogUserRemoved(address)","820dc540":"lockBalanceIndividual(address,uint256)","820e0d1f":"getChallenger(bytes32)","820e5e0b":"DividendRecycled(address,uint256,uint256,uint256,uint256)","820e79ed":"cstBalanceLimit()","820e93f5":"email()","820ecdaf":"iou_purchased(address)","820f52bc":"validPeriods()","820f9b85":"changeBetRange(uint256)","82100be6":"getWinningPayoutDistributionHash()","82100e3f":"deploymentBlock()","82104786":"Profit1000()","8210f13b":"BatchCancelSales(uint256[])","82123075":"safeExit()","82123cd2":"prizeReferee()","8213dafc":"setupAirDrop(bool,uint256,uint256)","82142370":"preICO(address)","82147bb4":"getGuardianNum()","8214fe03":"setMetadataChannels(string,string)","82154075":"Rentable()","8215c35d":"bincentiveErrand()","821648f4":"accessHolder(address)","8216ed6c":"getCompte_22()","82173d11":"KentKoinToken()","82189551":"buy(uint256,bytes)","8218e540":"insertHash(uint16,uint8,uint8,string)","821919fd":"getPetCanPresellCount()","821b771f":"targetBondingRate()","821b98f3":"closeTheoreticalClosedAuction(address,address,uint256)","821bee73":"vestings(uint256)","821c9a57":"test_testableStandardCampaignRefund()","821d7356":"setMainnetLocked(bool)","821e2491":"MyBetting()","821e4496":"isVerifiedCode(address,bytes32)","821e9169":"testFailControllerChargeMoreThanApproved()","821f830f":"addPack(address)","82202a15":"fetchCurrentSnapshotBlockIndex()","8220e945":"FactoryChangedEvent(address)","8221ac6f":"_createHolderId(address)","822221a6":"setContractToken(address,address)","82222674":"changeEndBlock(uint256)","822296d4":"isList()","8222a5ce":"insurance_Token()","8222aa1e":"settle(address,uint64,uint64,bytes)","8222b7e9":"getBonusPercentage()","8223188c":"Rose43()","82233b7a":"returnHostCut(uint256)","8224b76b":"StartOK()","8224ca2b":"SaleEDUSupply()","82251b99":"DRONECOIN()","822785e4":"_setTokenDescription(address,uint256,string)","82281104":"incise(uint256)","82286755":"MyRefundableCrowdsale(uint256)","82288e89":"setAccountIsNotFrozen(address,bool)","8229268b":"StageThreeDisable()","822942aa":"placeDeal(bytes16,address,address,uint256)","822a46ae":"setTiimPrivateSaleAddress(address)","822b08d0":"grantManagerPermission(address,string)","822b0be3":"teamTimeLock1()","822b1747":"_getEpicPlusRarity(uint32)","822bd0dd":"BOT_ELEMENT_3()","822c7671":"testControllerShouldBeSet()","822cba69":"setUint64(uint64)","822d487d":"getBrands()","822d9b4e":"onlyOwnerGetBountyWallet()","822daf60":"timeFactor()","822e1506":"_bonusRatio2()","822e57f1":"depositHelper(uint256)","822ee26c":"canMovetoken()","822f31e2":"AlexCoin()","822f7eb4":"setFeeReceAccount(address)","823113c7":"thresholdsByState(uint256)","823126d5":"_createToken(address,uint256)","8231ee98":"lastTimeGen0()","823213ef":"removeExclusiveRate(address)","823287b7":"chargeQuarterlyRate(bytes32,address)","8232e09e":"DeleteUser(address,address)","82330505":"setCommissionPoints(uint256,int256)","823374e3":"changeDedicatedProxy(address)","8233fbcb":"getTotalProfit(address)","82348bab":"setMinSlippageFactor(uint256)","823506af":"getData_29()","82351b43":"getLinearRelease()","82357105":"bl()","8236342c":"hashToPoint(bytes32)","82367b2d":"updatePrice(uint256,uint256)","8237ab8d":"IsSeedMember(address)","8237bbf0":"min_shares_to_sell()","82381c96":"WatchCurrentMultiplier()","8238520f":"getParentBranch()","8238b968":"BeatOrgTokenMainSale(address)","8238cc8f":"getFIRST_STEP_MULTIPLIER()","823914d9":"multisigETH()","82396bc6":"lnLimited(int128,int256)","82396f60":"getTokensInAction()","8239773a":"NePay()","8239b1e7":"getSequenceId(uint256)","8239b29d":"periodITO_hardCapInUSD()","823ab43b":"returnedTo(address)","823ac373":"verify(bytes32,bytes,address)","823b7475":"UpgradeAgentSet(address,address)","823ba0b8":"burnFormula()","823ba381":"InvestClose(uint256,uint256,uint256)","823bce43":"zasxzasx()","823c82ca":"FREEZE_PERIOD()","823e1832":"ChangeClientCategory(address,uint256)","823e569e":"controlWallet()","823e6e79":"validateBalance(address)","823edd48":"getComponentId(uint256,uint256)","823f57ca":"withdrawFromAmt()","82401f06":"transactionSwitch(bool)","82402743":"createPromoNarco(string,string,address)","8240ae4b":"challengeReparameterization(bytes32)","8242216d":"jackpotOfHouseEdge()","82425d7c":"hasNoBids()","82428323":"updatePeriodically(uint256)","82430c07":"_sendOwnership(address,address,uint256)","824338bd":"founderAllocation()","8243a036":"presaleFemaleTokensLimit()","8243fd61":"addMilestone(uint256,uint256,uint256,uint256,string)","8244208c":"FrescoToken()","8244b8c8":"findEndpointByAddress(int256,address,address)","8244ee58":"Amberella()","824563f6":"mintingContractAddress()","82457d53":"periodTable(uint256)","82474b1b":"teamName()","8248159e":"registerApprove(bytes32,uint8,bytes32,bytes32)","82484a36":"vestingToken(address)","82484c0b":"BetstreakICO()","824891f8":"changeMinimumCap(uint256)","82489311":"_buyNationInternal(uint8,uint256)","8248e722":"updateConfig(uint256,uint256)","824916b6":"playersAmounts()","82495626":"getVoteAccount(uint256,uint256,uint256)","824989c3":"changeLifetime(uint256)","824a5166":"ChannelCloseRequested(address,uint256)","824be3c7":"TheRichestWins()","824d1b4b":"preICOStartDate()","824d5603":"getIndex(uint16,uint16)","824d84d5":"createVestingContractWithFloatingPercent(address,uint256,uint256,address,uint256[])","824dbc9a":"changeMembership(address,uint256,bool,string)","824e5ebf":"distributeETHOS(address[],uint256)","824eddd9":"removeSupportedToken(address,address)","824eec3b":"editionOfTokenId(uint256)","824f0f7e":"tittyContractAddress()","824f2f1f":"globalConstraintsCount(address)","82507c5a":"Radix()","8250ea7d":"getReferralPool()","8250f7e5":"isInvestmentPermitted(address,uint256,uint256)","82518c2a":"exercisePut(uint256,uint256,uint256)","82520e07":"receiveFrom(address)","82528791":"setWallets(address,address,address,address,address)","8252ad9c":"totalAuction()","8252b2cf":"acceptCreatureOwnership()","8252e391":"transferInternal(address,address,uint256,bytes,bool,string)","825374ba":"buyATCToken()","8253adf1":"createBet(bytes16,bytes16,bytes16,bytes16,uint256,uint256)","82544c1f":"GoWalletToken()","8256687c":"addClaim(bytes12,bytes12)","82568a24":"p_update_planetCryptoCoinAddress(address)","82576dd6":"Laundromat(uint256,uint256)","8257f610":"canPurchase(uint256)","8258cbbd":"getContractETH()","825918ee":"delgodaddress(address,address)","82594f09":"iMaliToken(address)","825993ab":"totalCouponsUSD()","8259c78c":"depositPpm()","825a229e":"setEditor(address)","825b8b42":"buy(uint16[])","825bdb74":"setSecondaryManager(address)","825c3e36":"closeGame(bytes32,uint8)","825d7034":"RiptoBuxToken()","825e04d3":"dfs()","825edfd3":"getClassMechValue(uint256)","825f5a93":"RoundDSold()","825f6552":"SVET()","82609d51":"failedDonations()","82611dfe":"setOption(string,uint256)","8261b6bf":"receiveTokenLoot(uint256[9],uint256,uint8,bytes32,bytes32)","8261c4c7":"MINERS_HOLDER()","8261cfe4":"travelTo(uint256,uint256)","8261eb1b":"frtToken()","82629384":"shareStoredTokens(address,uint256)","8262963b":"setInfo(string,uint256)","8262fc7d":"addrBalance(address)","8263a938":"getProposalLength()","8263e953":"_claimSocialNetworkIdentity(uint256,uint256,address,uint8,bytes32,bytes32)","826446fa":"parse2wei(uint256)","82645725":"Planetagro(address)","82648222":"retrieveWCT2()","8264fe98":"buyPunk(uint256)","8265d137":"checkRegistrationStatus(bytes32,address)","8265d577":"TestreplayAnser(uint256)","8265dbc1":"bonusAndBountyTokens()","8265fb13":"optionPoolMembersAmount()","82661dc4":"splitDAO(uint256,address)","826679a1":"getFundSPBalance()","82672304":"GeneratePublicKey(string,string)","82672482":"vestingRegistered()","826776fa":"claimTeamTokens(address,uint256)","8267a9ee":"deleteIntValue(bytes32)","82688f14":"bn128_multiply(uint256[3])","8268efcd":"RunningAuctionsEvent(address,uint256,uint256,uint256)","82692679":"doSomething()","82699367":"CicadaToken()","8269cf4d":"seo(uint256)","8269d3c0":"buyTokensT4T(address)","8269df9b":"getLastCategory()","8269ee3d":"Issued(address,uint256,uint256)","826a483f":"_emitHashSet(address,bytes32,bytes32)","826a49c9":"removeGameInfoFromArray(uint256)","826c10d9":"exhaustBattle(uint256)","826c2447":"PGDToken()","826c69b8":"participantBalance(address)","826c6f73":"addServer(string,uint256)","826cc57a":"referral_address()","826d3379":"tierPrice(uint256)","826db6c8":"SLFYCoin()","826e9def":"initPresaleTokenVault(address[],uint256[])","826efb6d":"payBonus(address[])","826f57a1":"endBetting()","826f8a00":"createOrder(string,string,string,string,string,string)","827037d6":"modCEOAddress(address)","827037db":"icoStart()","8270c41e":"setPriceToken(uint256)","82712aeb":"purchaseWolkEstimate(uint256,address)","827147ce":"returnString(string)","8271bedc":"getUserBetsLength(uint256)","8272d083":"isSupported(address,bool)","82731247":"isB(address)","8273a411":"allBalancesOf(address)","82744368":"minimumEtherAmount()","82757f99":"withdrawTeamPot()","82760c88":"GoGlobals()","82766b1b":"setAmount(address[],uint256[])","82768708":"weiMinimumGoal()","8276bd19":"PROPOSED_STATUS()","8276ccf2":"setHeroName(uint256,string)","82771c8e":"isSane()","82771ff4":"endPlaceOrder(uint256)","82776521":"strConcats(string,string)","8278337a":"writeAttributeFor(bytes32)","8278fcea":"AirdropReward()","82790c19":"SideBridge(uint256,address[],uint256)","82797bea":"Preesh()","8279c7db":"setReceiverAddress(address)","8279ea54":"change_bounty_manager(address)","827aeb16":"_changeTittyPrice(uint256,uint256)","827bc64b":"setLeftoverTokensBuffer(uint256)","827bfbdf":"setLocation(string)","827c049e":"emission()","827c1e41":"getTittyByWpId(address,uint256)","827cc452":"withDrawMoney(uint256)","827d084a":"getActiveBusinessesPerCity(uint256)","827d7ba9":"Fosha(address)","827e4cf1":"manuallySetNumRewardsAvailableForChildAddress(address,address,uint256)","827ef325":"_parseMsgData(bytes)","827ef4c7":"m_fundsAddress()","827f143e":"setPresentMoney(uint256)","827f32c0":"generateTokens(address,uint256)","827fc57c":"ChickenFarmer()","827ffcea":"horas()","8280114b":"addressOfERC20Token()","828033da":"getFlag(uint256,string,string)","82803c22":"sell_tokens(uint256)","8280b498":"setFrozen(address,bool,uint256)","82812aed":"BuyPriceSet(uint256)","8281da38":"refundBet(address,bytes32)","8281feaa":"QuestionIs(string,string)","828282e9":"bonusRates(uint256)","8282e1e4":"SEPA()","828363b4":"transferAdviser(address[],uint256[])","828375e8":"computeTokensWithBonus(uint256)","82838c76":"subTotalSupply(uint256)","8284f2a7":"proposeGame(address)","82857a03":"approveAndCallWithSender(address,uint256,bytes4,bytes)","8285d272":"GOAL_REACHED_CRITERION()","82862275":"getDeadline(uint256)","82872491":"setCaps(uint256,uint256,uint256,uint256)","8287ccb4":"onDeposit(uint256)","8287d6ce":"_createDeposit(address,uint256,bool)","828806cd":"submitTransactionWithSignatures(address,uint256,uint8[],bytes32[],bytes32[])","8288196d":"THANKSTEST1()","8288edd0":"nonTransferrableBalances(address,address)","828909bd":"getIntValue()","82892dd9":"blockMember(address)","828a33b9":"FreeDiceCoin()","828ae96d":"cdc()","828c06cd":"expLimited(int256,int256)","828ca03c":"getTaskListSize()","828d671c":"dyn_sig()","828dfbca":"user_acq_address()","828eab0e":"defaultResolver()","828f1b42":"buyObject(address)","828f4057":"numberofGamePlay()","828f5fba":"air2(uint256,uint256,uint256)","828f717c":"fixPlayerID(uint256,uint256)","828f8581":"tokenTransferFunctionIdentifierMap(bytes32)","8290d1e0":"StandardTokenDeployable(string,string,uint256,uint256,address)","8290fe25":"finalizeExits(uint16)","8291286c":"contractId()","82914e5d":"getObjectData(bytes32[],uint8[])","82916381":"execute(address,uint256,uint256,bytes)","82917320":"increaseLockedBalance(address,address,uint256)","8293779c":"isOps(address,address)","82939b27":"getPreSaleData()","8293a114":"unbanAddress(address)","8294a796":"WelfareHandout(address,uint256,uint256,uint256,uint256)","829534d7":"m_pendingIndex()","8295a9ba":"checkDupe(string)","829644a6":"freelanceReinvest(address)","82964696":"ZSYCoin(uint256,string,string)","8297b90c":"PRESALE_LENGTH()","8297d46d":"BTL_ATHENIAN()","8298c3b5":"itemVoteDn(address,uint256)","8298c5dc":"last_winner()","829923bf":"admin_setAdmin(address,bool)","829965cc":"epochCount()","82996d9f":"rent()","829981fb":"FinalToken(uint256,string,string)","829a34c6":"getUserInfo(bytes20)","829a92f4":"hardcapChanged(uint256[])","829bd99c":"balanceOfByLegacy(address)","829c3428":"startTransfer()","829c38e1":"claimSolve(uint256[],uint256,uint256,bool)","829c3dee":"createDebt(bytes32[8],bytes,uint256)","829e9ece":"deathData_v16()","829ebdcd":"upgradeFor(address,uint256)","829ed3a5":"ownerTokenTransfer(address,address,uint256)","829efd71":"TonhaoCoin()","829f0667":"verify_sk_knowledge(uint256[2],uint256[2])","82a0888b":"totalSaleWei()","82a09cc5":"TokenCreated(uint256,address,string)","82a123ea":"WhitelistUpdated(uint256,string,uint256)","82a147cd":"addYouCollectContract(address,bool)","82a18331":"MOONCOINCONTRACT()","82a1ce1b":"setSourceToken(address)","82a352e4":"firstStagePriceOfTokenInWei()","82a35706":"tokenSoldPreICO()","82a3e5df":"STATE_CLAIM_ENABLED()","82a3f98d":"VOTING_PERIOD_DURATION()","82a5285d":"getMinBetAmount()","82a60a59":"CollectibleIndex2()","82a62137":"activateAccount(address)","82a66d93":"earlySponsor()","82a7cf1e":"ownerOf(uint16)","82a86cda":"getRarePLATInfo(uint256)","82a90545":"funComputeRoundTime(uint256)","82ab890a":"update(uint256)","82ab8a82":"startDeal(bytes32,uint256)","82ac1d99":"getNodeValue(bytes32)","82acaa39":"getChildrenAgainstAnimalId(uint256)","82ad5ecf":"yeedToken()","82ad6f35":"refund(address,address,uint256)","82ade405":"forceChooseRandomWinner()","82ade466":"getWithdraw(address,address,uint32,bytes32[],uint256)","82ae2227":"createUser(uint32,uint64)","82af3526":"addGift(address,uint16)","82afd23b":"isActive(uint256)","82b00403":"finalFundGoalReached()","82b022e0":"set_species(uint256)","82b0444e":"CityMayor()","82b0627c":"changeFundingTime(uint256)","82b0862f":"addBps(uint256,int256)","82b1ad50":"totalPrize()","82b1b4f3":"WithdrawToAdmin(uint256)","82b1b617":"ViewSellOrder(address)","82b1fb0d":"setGlobalMultisigWallet(address)","82b2a559":"buy(uint256,uint256,address,address)","82b2e257":"getTokenBalance()","82b2f95f":"DEVELOPER1()","82b49248":"BlockOne()","82b57b96":"MONUMENT_UN_FEE()","82b58599":"WeiHash(address)","82b68f4f":"actionVotedRate()","82b74b89":"lockTransfers()","82b7b500":"find(string)","82ba614f":"setRound(uint256,uint256)","82bb326b":"isGoldMigrated(address)","82bbcc2c":"removeIdArrayItem(address,uint256[],string,uint256)","82bbd1fe":"setlastprize()","82bbdbec":"nameAvailable(string)","82bbe9cc":"getGameFee(uint256)","82bc07e6":"lastRound()","82bcd463":"DAKUToken()","82bcef79":"increaseAllowanceProxy(address,address,uint256)","82be0ccd":"distributeTokensToApprovedUsers()","82be415d":"BonusDealer()","82bf6464":"DAOrewardAccount()","82bf9a75":"setPip(address)","82bfa9f2":"upgradeStorage(address)","82bfc739":"reLoadXaddr(address,uint256,uint256)","82bfefc8":"TOKEN()","82c00a50":"getCourseLength()","82c0287e":"deleteEtherBox(address)","82c058d9":"showTrnsactionLog(uint256)","82c0652a":"calcMultiplier()","82c174d0":"preSigned(bytes32,address)","82c198ef":"fxpDiv(int256,int256,int256)","82c20f84":"preSaleBonus3Percent()","82c26c6a":"GOCToken()","82c30220":"Earthcrypt()","82c4175d":"privateRate()","82c48f9e":"_batchTransfer(address,address[],uint256[])","82c51376":"LENRCoin(uint256,string,uint8,string)","82c59c81":"getGameBlocks(uint256)","82c6b2b6":"OfficalHold()","82c7340e":"GetPlayerRound(address)","82c7bac7":"callOnExchange(uint256,bytes4,address[5],uint256[8],bytes32,uint8,bytes32,bytes32)","82c7bf2f":"Zigger()","82c7f4d6":"setMessagefromdovie(string)","82c8ac27":"DatCrowdPreSale(address)","82c8c76f":"blocktube(uint256,string,uint8,string)","82c9004a":"computeArtistGenesisSaleFee(bytes32,uint256)","82c97b8d":"collectReward(address)","82ca116d":"changeBankAddress(address)","82cac6df":"lastRate()","82cb08aa":"MoveToBase(uint256)","82cb9df9":"addrFinance()","82cbb2e4":"Dagelane()","82cbdc0f":"create(string,string,string,address)","82ccef76":"GameEnded(address,address,uint256,uint256,uint8,uint8)","82cdc0fb":"setRunTimeAfterSoftCapReached(uint256)","82cdc93e":"getPlayerInstWinning(uint256,uint256,uint256)","82ce6523":"IWasFirstShareToken()","82cee91c":"BonusPeriodFor(uint256)","82cf114c":"setProfitAddress(address)","82cf2116":"transferAndAuction(uint256,address,uint256,uint256,uint64)","82cfd1e0":"turn_flag_OFF()","82cfee4d":"BitcoinSapphire()","82d1407c":"calcTicketEarnings(uint256,uint256)","82d18650":"minPay()","82d1bc89":"Darks(address,address)","82d22377":"infraIndexToApproved(uint256)","82d288c2":"setMintingCurator(address)","82d29195":"FundingStageNum()","82d2dcfb":"UETH()","82d33374":"updateLastTransactionTime(uint256)","82d40041":"getAbilitiesForCollectibleId(uint256)","82d419f5":"fullUnlockAngelsAccounts(address[])","82d4685c":"setAllocations(uint256,uint256,uint256,uint256,uint256,uint256)","82d559de":"catchMonster(address,uint256,uint32,string)","82d5eb98":"playerIdToExtendedAttributes(uint256,uint256)","82d708c4":"dividendRecentBuyersPercentage()","82d74005":"YUPTimelock(uint256,uint256,address,uint256)","82d82983":"RuralBank(uint256,address[])","82d8dff6":"getMaxPrice()","82d95df5":"setStartDate(uint256)","82d9ac39":"percentForBounty()","82d9b9bb":"turnOffCanUpdateNextGameMinAndMaxBlockUntilGameEnd()","82db9bd4":"setCaissa()","82dc107d":"SECOND_TIER_SALE_START_TIME()","82dc1ec4":"addPauser(address)","82dc5c9d":"UnionChain()","82dc7836":"openGate()","82dc87b6":"RefundPeriodStart()","82dced63":"testHitPresaleCapPresale()","82dd6012":"_aremoveByIndex(uint256)","82dd87dc":"deleteUser(uint256,uint256)","82de6df7":"getGameBegin()","82deb6cd":"m_publiclyDistributedTokens()","82decb49":"_maint_setCustomSeed(uint256)","82dfc5f7":"WETH_ADDR()","82dfe1fb":"changeTreeAttributes(uint256,string,string)","82e2f767":"finalizedNextUpgrade()","82e3036c":"StandardToken(string,string,uint8,uint256,address)","82e37b2c":"getPlayerName(uint256)","82e380ef":"auctionInformation(uint256)","82e41258":"unregisterPrefix(string)","82e43a3b":"TheFrozenSolidShitCoin()","82e46b75":"setCoin(address)","82e5d073":"getRewardTokenCount()","82e615fc":"bidRegistry()","82e61d79":"PayoutDividends(uint256,uint256)","82e6bbd2":"onlyBouncerExecuteDelegatecall(address,uint256,bytes)","82e6d3d6":"foundationSupply()","82e77165":"_setAllKeys(uint256,uint256)","82e93309":"importGenesisPairs(address[],address[])","82e94ac5":"eject()","82e96916":"setCoinPercent(uint256)","82e97740":"initAffiliate()","82ea3985":"clearNextArenaTime()","82ea97b3":"tokensForIco()","82ebaec4":"distributeTEST(address[])","82ebe9ba":"photoData()","82ec5ddc":"BioToken(address,address,address,address,address)","82ec623c":"_noThrowImplements(address,bytes4)","82edaf94":"tokenContractAddress()","82ee27cc":"setCoinBalance(address,uint32)","82ee282b":"thirdBonusSalesEnds()","82eed60c":"pauseCrowdsale(address)","82ef351a":"getTotalMonster()","82ef6483":"RabbitCore(string,string)","82ef8fa8":"adminClaim()","82f0151c":"MetaHash()","82f0622a":"teamReward()","82f0b31c":"getLife(bytes32)","82f0d875":"makeHash()","82f128f7":"MJOYToken()","82f16872":"raffle_balance()","82f19e3a":"deltaTFunc(uint256,uint256,uint256,uint256,uint256)","82f1ec1f":"getActivityAccountInfo(address)","82f2045c":"getEntitiesCount()","82f2a164":"addCET6(uint32,uint32,uint32)","82f2d8d7":"moveMarketData(uint256[],uint64[],uint64[],uint128[],address[])","82f39e2f":"mktTokenCap()","82f43303":"roundMax()","82f4b3a8":"badgeIfFreeze(address)","82f4ef73":"getStageName()","82f56556":"udgradeAttack(uint256,uint256)","82f5a3e1":"withdrawTotalBalanceDonateWei(address)","82f5e31b":"convertFromWei(bytes32,uint256)","82f66ff0":"RabbitCoin(uint256,string,string)","82f68dc4":"rankOf(uint256)","82f7325e":"CRYPTOVENO()","82f768d4":"tokenbeneficiary()","82f78260":"acupuncturecoin(uint256,string,string)","82f8152c":"account2()","82f858e8":"addresses4(uint256)","82f867a4":"BpsToken()","82f8767d":"SuperPAC()","82f87fdb":"checkFundingStateFailed()","82f8b6e9":"roundInterval()","82fa3421":"push(uint256,bytes32)","82fa7f8b":"weiPerWholeToken()","82fa9c0d":"isPersonalBonuses()","82fac352":"getPricesOfLatestTradeRecords(uint256)","82fb3b7c":"voteNoLockByAdmin()","82fb63c7":"getImageCurrentRegionId(uint256)","82fbbe47":"Ticked(uint256,uint256,uint256)","82fbdc9c":"register(bytes)","82fc49b8":"setCosignerAddress(address)","82fd5bac":"getDeal(uint256)","82fe1e46":"JaneToken()","82fef47d":"addToLists(address,bool,bool)","82ffee45":"approveRemoveOwnerRequest2()","82fffde0":"get_articolo(bytes,bytes10)","830010f3":"setReferrerRewards(uint256[])","8300399d":"aqwsaqws()","8301cfec":"backVenusCoinOwner()","8301fb2e":"cashOutTank(uint32)","8301fb61":"userHasSmartSpeed(address)","830245e3":"sumICOStage7()","830321be":"PGUC()","83037b81":"checkInterest(address)","830402c1":"startGameGas()","83054b6a":"GetConsentDirectiveCount()","8305d1c3":"GGGToken()","830639ac":"isWhitelisted(address,uint256)","83076a73":"updateCfo(address)","83084b3f":"setNotInWhitelistAllow(uint256)","8308c786":"minBlockGap()","8308d7e9":"set(address,uint256,uint256)","830953ab":"claimAmount()","830adf56":"get_previous_user_recast_from_item(bytes32,bytes32)","830b3a1e":"setIsFixed()","830b6868":"getPriceCredentialItemId(bytes32)","830b6b87":"MyOffer(uint256,string,uint8,string)","830cbbbd":"redeemToken(address,uint256)","830ced52":"TIER_1_CAP()","830d0627":"giveCdpToProxy(address,bytes32)","830d77d4":"ETHERONEUM()","830e8e64":"callAmendment(uint256)","830ef41b":"transferERC20(uint256,address,address,uint256)","830f2935":"icoAgent()","830f3d8a":"Diploma()","83100580":"PriceWeekTwo()","8310d61c":"getLastGame()","83111397":"blacklistAddr(address[])","831121dc":"getLockedStateAddress()","83123f30":"setRole(address,bytes32,bytes32,uint256)","83123fa6":"coinsIssuedIco()","8312a886":"tokenValueCount()","8314b490":"earlyContribList(uint256)","8314dcb4":"unAuthorizeContract(address)","83150a93":"opetTokenBalance()","83160d71":"setPrices(uint256,bool)","8316394e":"allow(bytes32,string,address,bool)","83186be0":"startICO_w1()","83187cf4":"cryptaurRecovery()","8318e40b":"transferBcoupons(address,uint256)","83197ef0":"destroy()","8319da07":"setOwnerCut(uint16)","831a1754":"TOKENS_HARD_CAP()","831a1a3c":"ECPoints()","831aab01":"setData_15(string)","831aba43":"referralsOf(address)","831b19c2":"KOToken()","831b3f67":"convertDustToEther(uint256)","831bb4f2":"setAcceptedLegacyAugmintToken(address,int256,bool)","831c2b82":"getChannel(bytes32)","831d3e09":"offFreezing()","831dc22c":"CATCrowdsale(uint256,uint256,uint256,address,address,address)","831e0485":"twitterIdOfClaimerAddress(address)","831e1deb":"changeExchange(uint256)","831e6270":"isSaleFinalized()","831e80f2":"create(string,string,uint8,uint256)","831ed348":"clearJoinedCrowdsales()","831f5ad2":"remainBalanced()","831f750e":"claim(address,string,string)","832018aa":"BitSelectProtegido()","832048d4":"TokenLoot(address,address,address,address,address,address)","83206e78":"marriedAt()","83212e74":"updatePreSaleCloseTime(uint256)","83219a8a":"editMetadata(uint256,string)","8322fff2":"ETH()","83234aa6":"FileInfoManager()","8323550b":"TUSD()","8323bebb":"TokenSold(address,uint256,uint256,uint256)","8324a852":"partner(address,address,uint256)","8325229a":"playerWithdraw(address)","83253cfa":"cancelMarginCallOnBehalfOf(address,bytes32)","83255d6e":"getOwnProducts()","8327a313":"test_initialize()","832880e7":"getUser()","83289567":"meetingDate()","8328b610":"setStakingRequirement(uint256)","8328dbcd":"migrationAgent()","8328e032":"setStandardPackPrice(uint256)","8329ac52":"voteForCandidate(string,string)","8329df0a":"allowReferrals()","832a66a2":"purchaseCardinal()","832b0dc3":"testThrowOnTransferToNullAddress()","832b2c60":"specialManagerAddressNumberMap(address)","832b9eb2":"MANHATTANPROXY6THAVE()","832bc28d":"getPoolHistoryCount()","832bff3a":"setForkEndTime(uint256)","832df980":"lockEmission()","832e02ef":"getUpgradeValue(address,uint256,uint256,uint256)","832f6412":"getCenturion(uint256)","832f6924":"shuliang()","83315b6e":"CONTRACT_FEATURES()","83318574":"maxPreSaleStage()","83324e8c":"numGroups()","833270d8":"preIcoEnd()","833331e8":"totalJadeProduction()","8334278d":"reserves(uint256)","83343d80":"deleteItem(bytes32)","833472ba":"TCOCOIN()","83347622":"newTeam(string,string)","83349122":"crowdsaleIsOpen()","8334d195":"viewToken(uint256)","8334e170":"SellableToken(address,address,address,uint256,uint256)","83366ab0":"addBytes(bytes32,bytes)","8337077b":"returnToken(string,address,uint256)","83370c25":"FFFToken()","833747f8":"getLovers(bytes32)","8337680a":"getMyCommitmentCount()","833888f0":"LAF()","83393882":"contracteeWithdraw(uint256)","8339e153":"SETPointerToken()","833abf3a":"registerAssetProxy(bytes4,address,address)","833b4596":"testApproveSetsAllowance()","833be5d5":"getTotalLoans()","833c202e":"UNITTransferWhiteList()","833cde52":"SaleToken()","833cf6fc":"TransCompleteds(address[])","833d56c7":"doSwarm(address,uint256)","833ea306":"soldForThird()","833eaa8b":"incise(address,uint256)","833eccc5":"batch_transfer(address[],uint256[])","833f43c2":"refill(address)","833ffb63":"removeOverride()","83405ddb":"unstakeCommunityTokens()","83408d73":"burnRemainingTokens()","8340f549":"deposit(address,address,uint256)","8341f26c":"icoTokenLimit()","834292a3":"CanYaCoin(address)","8342a9d9":"crowdfund()","8343816d":"AcceptCastleOffer(uint256)","8343e416":"asideTokensHaveBeenMinted()","83442b1e":"opt(address)","834472a5":"buildICOStageOne()","8344d26d":"TryUnLockCreatorBalance()","834614dd":"freeSub(address,uint8,bytes32)","8346378b":"transferBenship(address)","8346aa47":"spentParsecCredits()","8346d3c6":"MultiVesting(address)","8347a0d1":"issueTokenAndTransfer(uint256,address)","8348bfb9":"setICOAddress(address)","8348cf1e":"authorizeAmount(address,uint32)","8348d71f":"strConcats(string,string,string)","8348fe61":"createCenturion()","83492ff1":"deletePrice(string,string,string)","83499fdf":"BitcoinRed()","834b1aa1":"m_owner20()","834be978":"getRewardedSumByRound(uint256)","834c3351":"getGoldDataWeight()","834c6c84":"setCCH_edit_19(string)","834cc6fc":"createEscrow(address,address)","834d42c6":"serverForceGameEnd(uint8,uint256,uint256,int256,uint256,uint256)","834e0565":"GiveRNG(uint256)","834e476f":"newAuctionID()","834e6261":"CreateICO(address,uint256)","834ee417":"start_time()","834eebe8":"calculatePremium(uint256,uint256,uint256,string,string,string)","834f199d":"_calculateRequiredManaAmount(uint256)","834f54d0":"CarPark()","8350dfaf":"fetchdivstopot()","8350eb5e":"getHashInDataObject(bytes32[])","835164a0":"INBCToken(uint256,string,string)","8351a0d4":"getCumulativeProfit()","83525394":"NONE()","83537b5f":"test_threeValidEqInt()","8353bb51":"ROLE_STATE_PROVIDER()","8353c9c8":"SetFreezingEvent(address,uint256,uint256,uint8)","8353ffca":"Withdraw(uint256,address)","835409f0":"InfimonkCoin()","835436b4":"evictWorker(address)","835592f8":"passed(address)","8355c263":"frozenMinDeposit()","8355e15c":"withdrawTokens2(uint256)","8356027e":"unfrozenTokens()","83563dc6":"_getYear(uint256)","83565503":"setMember(address,bytes32,address,bool)","83565cc7":"additionalAction(bytes32,uint256[])","8356a5b5":"weekOneStart()","8357417d":"WithdrawDevFunds()","8357c2f0":"setAmountToReceive(uint256)","835850f9":"_bytesToAddress(bytes)","83586713":"computeResult(uint32,uint32)","835939d5":"vote(address,bool,string)","8359f045":"range(int256,int256,int256)","835a749d":"partialRedeem(uint256,address[])","835ac5ce":"softcapUSD()","835b3720":"setGeneKind(uint8)","835b42fc":"testThrowUpdateLatestRevisionNotUpdatable()","835b862f":"OneGameToken(address)","835bbd55":"reserveTokens(address)","835c1154":"checkInvestments(address)","835c19f3":"receivePayment()","835c6386":"isPurchasePossible()","835c853b":"notaryFee()","835cb53b":"MAXIMUM_NON_WHITELIST_AMOUNT()","835d2d2e":"executeTransfer()","835e119c":"availableSynths(uint256)","835e33e7":"DianJingToken()","835e98d7":"bonusShare()","835eb9f8":"ShieldNetwork()","835ec6ef":"CreateDDFT(address,uint256)","835f6775":"setBonusesForAmounts(uint32[],uint32[])","835fa3ac":"icoSuccessful()","835fc6ca":"withdrawal(uint256)","835fcab3":"NAME_HAWKING()","836028a2":"disputeOpen()","83607b02":"calculateDevCut_(uint256)","836115fe":"unlockedTokens(address)","83617782":"startLive()","83624c17":"getPartyA(bytes)","83627b8e":"getEmployeeId(address,address)","8362f6eb":"balanceSender(address)","83634ad7":"fnv(uint256)","83636209":"RecoveryKeccak256(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","83638710":"getOwnerOf(uint256)","83638c12":"GCOIN()","83640881":"getTokenOrdersLength()","8365172c":"num_levels()","8366437d":"RegisterUser(bytes32,bytes32[8])","83664dd3":"substituteManagerContract(address)","8366ee2b":"getPayeeLenght()","83672f3e":"setWallets(address,address,address,address)","8367e120":"apiUrl()","836826a6":"highestBet()","83685488":"TECHToken()","836880d3":"softcapAchieved()","8369ff08":"log2ForSmallNumber(uint256,uint256)","836a1040":"mint(uint256,address,uint256)","836a107f":"removeFromKYCList(address)","836a1e23":"collectExcess()","836adfd9":"libbibatchbacktest(uint64,uint32[],uint64[],uint64[],int64[],int64[])","836b680f":"createProductionUnit1()","836c67d7":"BAC()","836cca1d":"privateIcoMax()","836d6d66":"WeeklyLotteryB(address,uint256)","836d8b2a":"SolusPlatform()","836d9665":"removeUsersWhitelistA(address[])","836dea0b":"myEther()","836e4158":"numOrdersOf(address)","836e643f":"endStake(address,address,uint256)","836e8180":"round1()","836e9431":"updateUsersList()","83711c70":"ContributionResolved(bytes32,bool,address,address,uint256,uint256)","83714834":"factorial(uint256)","83714b27":"_safeMul(uint256,uint256)","837150cf":"paused(bool)","837197b2":"sendTokens(address)","8371e1e9":"rescale(int256)","83725a91":"Payment(address,address,uint256,uint256,address,uint8,uint256)","837356b1":"doNotAlwaysRequireCosignature()","837381fa":"withdrawFromContract(address,uint256)","837386ca":"candidateXPAAssets()","83739eda":"allocationsInitialised()","8373ae71":"cancelTradeOffer()","837564dd":"CNotes(string,string,uint8,uint256,uint256)","83771e56":"BSCToken(uint256,string,uint8,string)","83773de8":"_transfer(uint32,address)","83781340":"registerTradeProfile(bytes,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,bytes,uint256)","83786f8c":"getBalanceOfToken(address)","83788fce":"nextBlock()","8378ce42":"readStamped(bytes32)","837929b6":"getEventful()","83794502":"payForTask(uint256,uint256)","8379d75b":"BDC()","837a7ba5":"testThrowTransferDisabled()","837a8eb3":"CATWithdrawn(uint256)","837ada41":"cens()","837b68c8":"requestTokenExchange(uint256)","837cfb34":"LADYCoin(uint256,string,string)","837d52d8":"RAIT()","837e4cd9":"getNameAndAge()","837e60e6":"removePA(uint32)","837e6a94":"setOverride(address)","837e7cc6":"rollDice()","837f1bf7":"_appendTagged(string,string)","838006c0":"OwnableOZ()","83804c69":"verifyTransaction(bytes32,uint256,address,address,uint256,address,address,uint256,bytes32,bytes32,bytes,bytes)","8380edb7":"isUnlocked()","8381ada3":"GOLDEQ()","8381f58a":"number()","83829bf1":"Involve()","8382a574":"Factory(address,bytes32,address)","8382b460":"getSlashRewardPart(bytes32)","83835c01":"accuracy()","8383671b":"mintTokens1(address,uint256,uint256,bytes32)","8383bfc8":"EscrowFoundry()","83841e0c":"change(string,string)","838445e8":"EtherAds(address,address,address)","83852cf6":"setEnablePurchase(bool)","8385fa0f":"ESCROW_WALLET()","838661eb":"unfreeze_periods()","8386927a":"ToSponsor()","83876bc9":"newProposalInWei(address,uint256,string,bytes)","83879c15":"cooRemoveManager(address)","83894548":"getTokenBalanceOf(address)","838985d7":"gymFee()","8389f353":"setNumCities(uint256)","838a05e4":"part20Transfer()","838a48d6":"disableBlackListForever()","838bdce2":"team3Token()","838c29b6":"checkInterval()","838c63b7":"avgRate()","838ca346":"currentFunds()","838d6e05":"getChannelInfo(uint256,address,address)","838eb17e":"takeSnapshot(uint256,uint256)","838f0602":"SOLEToken(address,uint256)","838f5165":"refundFor(address[])","838f7f94":"getTotalAmountOf(uint256)","839006f2":"rescue(address)","8390b02a":"rfindPtr(uint256,uint256,uint256,uint256)","83914275":"getUserBonusBalanceByType(address,bytes1)","83917229":"_createGameItem(string,address,uint256,uint256)","8391a1c4":"get_table_size(uint256)","8391e45c":"dividendsOwing(address)","8391e48d":"WCoin(uint256,string,uint8,string)","83924dea":"MyTestToken(uint256,uint256,string,string)","83944a4b":"CreateWTE(address,uint256)","839484a7":"Iou_Token()","8394f639":"SimpleExchange(address,uint256)","83955bb2":"SpecialPurchased(address,uint256,uint256)","8395aa94":"PLATINUM_AMOUNT_SKL()","83960e3c":"importTokens(address,uint256,address)","8396392d":"add(string,string,string,address)","839655c8":"BetOnHardFork()","83973dc3":"withdrawBAT()","83975e7d":"PapaBearToken()","83979803":"setNewRateLevel(uint256,uint256)","8397a260":"getAction(bytes,uint256)","8397cc94":"tokenFallback(address,uint256,bytes32)","8397f3bc":"isBonusPayable(address,string,uint256,uint256,uint256,uint256)","839849c0":"changeBaseMultiplier(uint256)","83985082":"disarm()","839930ba":"getMinimumBet()","839972f9":"lockToken(address,uint256,uint256)","83999223":"release_all()","8399f93f":"reservedFund()","839a01be":"privateLockedAmount()","839acf14":"buyMonument(uint256,uint256)","839affc3":"batchDepositTokenTo(address[],address[],uint256[],uint256)","839b2386":"ReverseRegistrar()","839b240e":"setHardCapCrowdSale(uint256)","839b913e":"getTargetReportsPerLimitedReporterMarket()","839daf1d":"migrate2(address,uint40,uint40,address,address)","839dbbb1":"iconicsCount()","839df945":"commitments(bytes32)","839ea3c4":"startVotingTeam(uint256)","839ff719":"FML()","83a076be":"gift(uint256,address)","83a07765":"drawTicketCount()","83a18678":"total_racers()","83a1a3aa":"setC4FContractRequesterLock(address,bool)","83a1a4f2":"YesNo(string,string,string,string,string,string,bytes32,address,string,address,uint256)","83a1f52a":"GetManifestoByCategory(string,uint256,uint256)","83a287dd":"closeGame(bytes,address,uint256,uint256[],bytes,bytes)","83a37262":"stopQueueing(uint256)","83a41f93":"descentX()","83a4f2f5":"whitelistOperators(address)","83a51213":"takedaily(address)","83a51ad0":"oraclize_setConfig(bytes32)","83a6595f":"setMinDonation(uint256)","83a68993":"gameOp()","83a6ad6b":"grantAccessDeploy(address,address)","83a6b565":"payCommission(uint256,uint256)","83a7b701":"masternodeRegister()","83a9094f":"PRICE_RATE_THIRD()","83aa4958":"getContributeAmount()","83aa9985":"ownerTwo()","83ab12e7":"Auctions()","83abd7e2":"removeIdentifier(address,bytes32)","83ac44e6":"marketingAccount()","83ac4ae1":"_sendWinnings()","83ac98fe":"transfer_Different_amounts_of_assets_to_many(address[],uint256[])","83ae0839":"ETNToken()","83ae5266":"addCertificate(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,string,bytes32[],bytes32[])","83ae62c4":"_frozeAmount()","83aec57c":"getUsersForDate(uint32)","83af3c40":"getRemainingTokenAmount()","83b01a83":"updateTAOContentState(bytes32,address,bytes32,uint8,bytes32,bytes32)","83b14c0a":"toAddr(uint256)","83b23b40":"cEthereumlotteryNet()","83b2c476":"updateLibrary(address)","83b2d77f":"signFact(bytes16)","83b3999a":"addToAddresses(address,address)","83b3c85f":"pecul()","83b40eb7":"creditEqually(address[],uint256)","83b47a4d":"whitelist_addys(address[],bool)","83b4918b":"reinvest(uint256)","83b49485":"BurnablePayment(bool,address,uint256,uint256,string,string)","83b58323":"setTransferFeePercentage(uint256)","83b5ff8b":"ownerCut()","83b60a33":"transferToken(uint8,address,uint256)","83b665b9":"purchase(uint152,uint256)","83b83c1c":"setOpGas(uint256,uint256)","83b8b9f0":"ForceCloseContract()","83b8c8f6":"bonusLevel100()","83b9e9f7":"train3(uint256)","83ba3a97":"sendTeamSupplyToken(address)","83baa6f4":"presaleopeningTime()","83bd5f42":"distributeDevCut(uint256)","83bd72ba":"stopGame()","83be9d54":"placeBet(bytes32,address)","83bebcc2":"changeSellPriceForAthlete(uint256,uint256)","83bebced":"_rate()","83bf1cbc":"delayDefaultRelease()","83bf4609":"createTemplate(string)","83c08784":"Incrementer3()","83c0dd25":"LogNewAllocation(address,uint256)","83c10844":"percentLeftFromTotalRaised()","83c17c55":"setFactoryAddress(address)","83c1f2e6":"unlb()","83c218c2":"oraclizeId2proposalId(bytes32)","83c28ddc":"getRefundAmountForFunder(address)","83c28ecc":"getTokenWithdrawHold()","83c3bd6b":"isEqualLength(address[],uint256[])","83c4c2e9":"makeSuccessor(address)","83c4cc46":"StartCrowdsale(address,address,uint256)","83c51a38":"thesimplegame()","83c56fc8":"dailyTotals()","83c592cf":"stake(uint256,bytes32)","83c5e3c9":"removeBRA(address)","83c68f48":"AIChain()","83c6aa47":"arrangeUnsoldTokens(address,uint256)","83c75ed5":"setGatewayB(address)","83c7d7c1":"sumMultiplayer()","83c7f14c":"bytesToBytes4(bytes)","83c81bec":"Arbiter(address)","83c99722":"lockforTransfer()","83ca8632":"_getCrabPartData(uint256)","83cb2fee":"INITIAL_SEED_FARMING_AMOUNT()","83ccc2b5":"_0xBitcoinCash()","83ccc8b8":"getEtherContributed()","83ccdcc3":"detailsOfWindow()","83cd5e13":"debug_multiplehash(uint256,uint256)","83cdb517":"transfer_to_0(uint256)","83ce63b5":"doRouletteBet(bytes,uint256,bytes32,bytes32,bytes32)","83ce8a61":"changeMPO(address)","83cfab42":"unFreeze(address)","83cfbd7f":"revokeOwnership(address)","83cfc5f2":"changeNameRestricted(string)","83d158f0":"ShadowToken()","83d2421b":"setWorkerPort(uint256)","83d4f946":"round0EndTime()","83d51a38":"concatString(string)","83d52f36":"OpenAIChainToken()","83d53895":"interfaceSupported(address,bytes4)","83d6236c":"amIin()","83d66353":"LotteryGames()","83d67fc1":"_addAddressToGrantAccess(address,uint256)","83d7529f":"reservationFromBackend(uint256,bytes32,address,uint256,uint256)","83d852d9":"shutdownTransactions()","83d880d0":"setParticipationCap(address[],uint256)","83d8a90f":"theDonkeyKing()","83d8bae3":"listItem(uint256,uint256,uint256,address)","83d8e480":"registerCoin(address,string,string)","83da4d86":"ApolloCoinToken(uint256,uint256,address,address)","83db0680":"TOTALSHARES()","83db1548":"addPost(uint256,uint256)","83db8e31":"HMCToken()","83dbb27b":"invalidOrder(address)","83dbc55b":"verifyXOR(bytes32,bytes32,uint8)","83dbff4b":"get_first_item_in_state(bytes32)","83dc077d":"acceptContribution()","83dcecd3":"CompanyTokensIssued(address,uint256,uint256)","83dd7aa4":"setBankName(bytes32)","83de6ed6":"changeStageTwo()","83dea2a8":"renounceExcluded()","83df762f":"BDayToken()","83df7d21":"updFreezeEnabled(bool)","83dfd040":"isPresaleFull()","83dfe5fd":"C()","83e03c3d":"HumanERC223Token(uint256,string,uint8,string)","83e06ead":"setPercentages(uint256,uint256,uint256,uint256,uint256)","83e07382":"setMovePermissionStat(bool)","83e19248":"afterStart()","83e19a95":"MANAGEMENT_LOCKED_PERIOD()","83e1bb4f":"dequeueIngot()","83e219eb":"removeFromTotalSupply(uint256)","83e256dc":"gameIdGame(uint256)","83e2a0c4":"joinGame(address,uint256,address)","83e3607c":"fourthBonusSalesEnds()","83e48d43":"_sptc(uint256,uint256,uint256,uint256,address)","83e49c53":"burnWithData(address,uint256,bytes)","83e4eed0":"apply(string,string)","83e5cb26":"ownerAddCeo(address)","83e78b31":"bet(uint8,bool,uint8)","83e7f347":"ICOBank()","83e811a6":"founderLockup()","83e83b54":"payBounty()","83e8dbb8":"calculateSaleAmount(uint256,uint256)","83e99a93":"balanceOfUnclaimedTT(address)","83ea0620":"packageExists(string)","83ea5111":"MESH(uint256)","83eb7257":"companySupply()","83eb72ac":"getStrandDescription(uint256)","83ec0648":"BlockStackCoin()","83ec0bd2":"showPeopleInQueue()","83eca581":"setReferrerReward(uint256)","83edf023":"totalWeiRecieved()","83eed3d5":"queryN(uint256,string,bytes)","83eeecc0":"ethInWei()","83f0b184":"calculateMaxContribution()","83f0bb45":"_getPartSkillLevel(bytes,uint256,uint256)","83f11daf":"SetCandidatePrincipal(uint8,uint256)","83f1211b":"transfersLocked()","83f12f91":"grantFounderTokens(address)","83f12fec":"batchTransfer(address[],uint256)","83f13e7f":"setNewDividendContract(address)","83f2a8ca":"dividendsCalculated()","83f3c3df":"PaymentGot(bool)","83f537cc":"LendingBlockToken(address)","83f57fd7":"_addDemoc(bytes32,address)","83f5b46f":"refSystem()","83f5e360":"_unpackClassValue(uint256)","83f66212":"getTop11_20Messages()","83f6cc69":"transferAllowedOf(address)","83f6d9a4":"validateNameInternal(string)","83f7a095":"setCoefficient(bytes2,string,uint256)","83f7b8e1":"getNumberOfPhotos()","83f7e2d7":"reduce(uint256)","83f94db7":"upgradeImplementation(address)","83f95f13":"openClaim(string)","83f9a788":"BlockTubePrepaid(address)","83fa07fd":"fechAllCandidates(uint256)","83fa2039":"Dealer(address,address)","83fa7e02":"isSiringClockAuctionStorage()","83fa87f2":"activateAdSlot()","83fae425":"setPresaleAllocation(address,uint256)","83fb42ba":"proposeBurning(uint256)","83fbbc7a":"OnlineSocialChainToken(uint256,string,uint8,string)","83fbc2b4":"weiRised()","83fc58b4":"tranferOwnership(address)","83fcafbb":"GetPrizeFund()","83fcb85e":"revertFunction()","83fcf308":"getPropertyRating()","83fcf973":"unlockVestedTokens()","83fcfafe":"LooqCrowdsale()","83fd65d8":"setETHExpectedFee(address,uint256,uint256)","83fd8a64":"CBCK(uint256,string,string)","83fe05f1":"PutFreeEther()","83fe10e4":"isMetered()","83fee16d":"finalizeUpdate(uint256,address)","83ff0189":"buy_tickey_free()","83ff1bb6":"approve(string,uint8)","83ff5bf2":"Bittobit()","83ff9bec":"petCardDataContract()","8400c307":"isRecipientAllowed(address)","8401824f":"compactFraction(uint256,uint256,uint256)","84019cae":"WOWToken()","8401e614":"lengthOfPermissions()","8401f8d1":"addMultipleToWhitelist(address[])","8402181f":"pull(address,uint128)","8402ac99":"firstYearEnd()","84035e07":"amendEarlyPurchase(uint256,address,uint256,uint256)","8403be91":"isAppRegistered(address)","84048497":"listMultipleItems(uint256[],uint256[],address,bytes32[])","84054d3d":"cashout()","8406ab82":"deleteGame(address)","8406c079":"relayer()","84073164":"transferFromPie(uint256)","84083c89":"addWhitelistUser(address)","84086357":"crowdfundFinalized()","8408643a":"getBlockTimestamp32()","840880f2":"TeamLockingPeriod18Months()","8408cb9d":"setPreICOPrice(uint256)","840aab14":"_hasName(address)","840b7403":"computePayout(uint256,uint256)","840bc19c":"NON_PAYABLE_AMOUNT()","840c0ca9":"setMaximumClaimPriceWei(uint256)","840c401f":"pruneRestrictStock(address,uint256)","840cfffd":"burnIndexedByAddress(address,uint256)","840d7fb6":"createLottery(address,string,string,uint32,uint32,uint8)","840dea74":"COMBINED_WEI_GOAL()","840e2673":"startTransferTime()","840e78fd":"projects(address)","840eb43e":"removeLicenseTerms(bytes32,bytes32)","84100d5c":"selectRandomTrait()","841016d0":"setAdditionalOwners(address[])","8410956a":"initialise(address,uint256,uint256,uint256,uint256,uint256)","84109e50":"setTiimKyberGoAddress(address)","84120645":"setMasterRewardsPercent(uint256)","841237b7":"Wallet9()","841244a8":"FeedCreated(uint256,string)","84125e0b":"withdrawBalancesToNFC()","84126e01":"cancelPayment(string)","841302ce":"getHash1(uint8[5],uint8,bytes32)","84132cf5":"deposit(address,uint8,bytes32,bytes32)","84140c40":"delFromVestMap(address)","841410cd":"maxETHContribution()","84160ec0":"getAddressesAccounts()","84168c01":"tradesUnlock(address)","8417fa2f":"goPublic()","8418cd99":"contribute(address,uint256)","8418dc36":"teFoodsAddress()","84191f62":"changeController()","8419604e":"SendingBounty(bytes32,uint256,address)","8419c986":"foundTime()","841a12bd":"setKittyTokenAddress(address,address)","841b4cd8":"registerForRaffle3()","841baf2c":"m_tokensClaimed(address)","841d0ac3":"init_daylimit(uint256)","841e6ce9":"betFee()","841eb7f8":"paymentRewardTokens(uint256)","841efac4":"updateFieldss(uint256,uint8,uint256)","841f3729":"howManyTokensAreReservedForMe()","84219204":"minVotedTokensPerc()","8421ec8a":"MyCash()","842249cb":"weiTotalReceived()","8422927d":"cancelPayment(uint256)","8422b3bf":"RailzToken()","8423157b":"getWinAmount(uint256,uint256)","84248a51":"changeDrawFee(uint256)","84249ed0":"manualBuyPrice(uint256)","8424b40d":"setLotteryCore(address)","8424f952":"IMEIM()","84268051":"payoutToOwnerIsLimited()","84269ed9":"transferFrom(address,address,uint32)","8426a452":"getSellingItem(uint256)","84270db0":"selfdestructTokens()","84281dcc":"isBalanceSufficientForContractCreation(address)","8428cf83":"recoverAddress(bytes32,uint8,bytes32,bytes32)","84297029":"getIdxBatchByUsername(bytes20[])","84298882":"setLogo(uint256,string)","842a6415":"DTRC()","842acf9d":"mintDSBIToken(address,uint256)","842b6357":"checked_in()","842b8efa":"FailedMarking(bytes32,bytes32,uint256,int256)","842bc37b":"GetSmallCotractIndex(address)","842bfad2":"updateParticipantCapTier2(uint256)","842c17be":"firstStageMinted()","842c45c5":"ROBIES()","842e062f":"p_setCurrentRoundJackpotPercent(uint256,uint256)","842f10d1":"dropMultiple(address[])","842ff2bd":"numPolls()","84300859":"setTokenUnlock()","84304ee5":"chronus()","84311353":"totalAmountOfPurchasesInCny()","84313086":"divCutMaster()","84317008":"setprice(uint256,uint256)","84317143":"INITIAL_EARLYBIRD_TOKENS()","84321b41":"ligerAdminAddress()","843296d6":"DealCancelationReason(uint256,address,uint32,uint32,uint256,string)","8433acd1":"collectTokens()","8433d6f2":"from_Initialisation_to_cycleDeVie()","84344415":"chargeMoney()","84345b35":"createRandomZombie_ZOB_goldpack()","8434c80d":"cleanArray(uint256[])","843545be":"getPrinciple(uint256)","843584f1":"log_recast_fees(address,address,uint256)","8435be4b":"getLastFarm(uint8,uint8)","8435da61":"getTile(uint16,uint16,uint8)","8435f147":"bytes32Func(bytes32,bytes32)","8436bd4e":"MintyMcCringleToken()","84370813":"subscribe(uint256,uint256)","8437b2a5":"tier(uint256,uint256)","84385c6f":"assignOperator(address)","84386004":"channelsSold()","84394e6f":"addValidation()","8439f80d":"accumulatedBalanceOf(uint256)","843a7f74":"getCKNPriceNow()","843aa0db":"insert(uint256,uint256,uint256,uint256)","843ad7b5":"dailyMintable()","843b1a09":"spendNonce()","843b4386":"addComment(string)","843bd641":"itemExists(uint256)","843cbae4":"EtherBattleCoin()","843cfb9e":"vestingTotalPeriods()","843e240e":"getAuditContractUri(uint256)","843e8d27":"downVote(bytes12,bytes12)","843fcf90":"EOSGold()","843ff6f6":"getTitulaire_Compte_7()","8440b3b0":"BUY_INCREASE()","8440d167":"getCategory(address)","84413b65":"airdropAddress()","8441f89e":"deleteWitness(address)","8442171d":"bonusLimit2()","84429480":"TokensBought(address,uint256,uint256)","84429579":"getRunningTokenPairs(address[])","844323fa":"xtime()","8443f07c":"UVIDIFYTOKEN()","8444b391":"getUpgradeState()","84465fa5":"changeFeeOwner(address)","844669b3":"accountC()","844706a6":"UsdCapUpdated(uint256,uint256)","84477036":"tempTokensBalanceOf()","8447c02f":"takeAGuess(uint256)","8447c4fa":"LibraToken()","84488126":"isForceExecute(address)","844891a0":"ABTCETHER()","8449129e":"EthereumNova()","8449133b":"initQuoteBalance()","84491566":"getPrevRoundWinnerCount()","8449b0af":"PRICE_MULTIPLIER_ICO5()","8449d772":"withdrawM5()","844bdea4":"LhsToken(uint256,string,uint8,string)","844c3edc":"setThresholdSendToSafeWallet(uint256)","844c4264":"cycleEndTime()","844c7d95":"updateBalances(address,bytes32,string,address,uint256)","844d38ee":"view_get_Gains()","844d65c5":"whitelistedMax(address)","844dbf67":"RecurringPayment(address,uint256,uint256,address)","844e774d":"joinraffle()","844e89a9":"Unregistered(bytes32,uint256)","844ea6f9":"E25()","844ef097":"bridgeValidatorsOwner()","845051d3":"testContractsNotNull()","8450b12e":"getSupplyLimit(uint16)","8451738d":"rentHo(uint256)","8451d312":"showAllFunds()","845238fe":"lookup(address[],address,address,bool,bool)","84533794":"setEthRate(uint16)","845381c0":"FailedVote(address,string)","84539789":"useNeonMarbles(address)","8453a8c8":"Factom()","84545ef8":"setRegionPurchasedPixelPrice(uint256,uint256)","8454665d":"startingInsuranceBalance()","84553e16":"AccessAddress(address)","8456cb59":"pause()","84570d0d":"assertEq5(bytes5,bytes5)","84571235":"minimum_bet()","84585099":"TransferTo(address,uint256)","8458644c":"play(bytes32,address,address)","845890c3":"buyATR()","8458bd70":"getHp(uint256)","8459857f":"mentors()","845a51ec":"rewardPoolAddress()","845a7468":"getStakersAndAmounts()","845ab425":"getProjectDescription(uint256)","845b6aca":"buyBasicCards_Migrate(address,uint256,uint256)","845c8801":"checkHasPermissionForPack(address,address,uint256)","845d586f":"publicTransfersEnabled()","845dcc2b":"_isSoldOut()","845e76b3":"getStudentArray(bytes32)","845eaedb":"SmartVows(string,address,address,string,address,address,string,string,string,string,string,bytes,bytes)","845ec8de":"FOUNDER_EXCHANGE_SHARE()","845f5593":"initStages(uint32[],uint32[],uint128[],uint128[],uint128[],bool[])","846030a0":"hasClaimableShares()","84605d0d":"total_iou_withdrawn()","8460a9d9":"suicideSend(address)","84610618":"registerRequest(int256,int256)","846153b5":"registerAddresses(address[])","8462151c":"tokensOfOwner(address)","84622425":"onlyPrimaryMock()","8462df7f":"diff(uint256[],uint256)","8463bcf5":"countClients()","84644ec9":"addPromise(uint256)","8464878d":"emergency_used()","84653605":"DateCoin(uint256)","84658e2a":"sendtoken(address,uint256,address,uint256,address,uint256,address,uint256,address,uint256,address,uint256)","846639dc":"currentAwards()","8466c3e6":"aa()","846786f1":"openIco()","8467d9cf":"refundPayment(uint256,uint32,uint32,uint256,string)","8467f7cb":"resetContract(uint256)","84682fbb":"auxWorstPoints()","84691cd8":"grapesToProduceBottle()","84696810":"winningCountry()","846a09e1":"AddAuthorityAddress(address)","846a284e":"_addTicket(address,uint32,uint8)","846a5dde":"delayPayment(uint256,uint256)","846b055a":"startCrowdfund(uint256,uint256)","846b0ef0":"proxiedContribution(address)","846b23d4":"getEmployerInvoicesByStatus(address,address,uint8)","846b68e3":"MERCULET()","846e5851":"LogStudentUncertified(address,uint256,address)","846e832d":"getStateAt(uint256)","846e980d":"setFreeLobster(uint16)","846f1185":"sendEthProportion(address,bytes,uint256,uint256)","846f652b":"getSpawned(uint32)","8470ffd6":"_transfert(address,address,uint256)","84716854":"investInCharger(uint256)","84734476":"copyBytes(bytes,uint256,uint256,bytes,uint256)","8473e55f":"amountForSale()","8475bfed":"div18(uint256,uint256)","8475f6f9":"getPublicKeyG()","8476f105":"Menu08(uint256)","847760ee":"getArtToken(uint256)","847778ad":"edit(address,address)","84780009":"getFinishStatus()","84788f01":"mvnperethBonus()","847927ed":"icoEtherMaxCap()","847a1ca6":"raiseSellOrderCreated(address,uint32,uint32,uint80,uint256,int160)","847a5e99":"getPlayerStats()","847af92c":"setMintMode(uint256)","847bd61c":"processPurchase(uint256[])","847c096d":"removePresaleContributor(address)","847d97ab":"add(string,address,string,uint256)","847dc0a7":"percentageETHReserve()","847dc59e":"MicoinToken(uint256,string,string)","847dd67c":"buyEth(uint256)","847e09f2":"TOKEN_HARDCAP()","847e12c4":"FixyNetwork()","847e27d9":"wanToken()","847e2ba1":"revokeAccessMint(address)","847ec2de":"totalBunny()","847eefb6":"ICOHardcap()","847f2177":"Electron()","847f4a88":"stopSaleType(uint8)","847f8a10":"Refund(uint32)","8480021c":"crowdfundDeadline()","8480544e":"getCAOAmount()","848125ea":"issueBlockReward()","8481573e":"contractBalanceOf(address)","8482167e":"makeCall(address,uint256,bytes)","84837981":"BTCT()","8483dfcc":"isOverflow(uint256,uint256)","84841523":"Buttcoin()","8484dc24":"removeEmissionProvider(address,uint256)","8484ff59":"setTokenCollectable(bool)","8485b90c":"proposalAuthor()","84861e93":"auctionState(uint256)","84869679":"isDistributionDue(address)","8486d444":"_getUsdAmount(uint256)","848784e5":"transferPreSigned(bytes,address,uint256,uint256,uint256,uint256)","8487b73a":"Milestone_BankLicenseFailed(string)","84883795":"ico_rejected()","84885ed6":"getData_19()","8488e58a":"setReturnableToken(address)","848a0327":"dividendForYearly()","848a2130":"releaseChecksum(uint8)","848b3821":"fundingCapReached()","848b86e3":"updateWallet(address)","848c0a39":"buildLeft(address,uint256)","848dd14e":"CostStuff(address,uint32,uint256)","848e3442":"automaticThreshold()","848efb3d":"rentOut(uint256)","848f002f":"setBoolF1F2(bool,bool)","848f1470":"disableRefundPeriod()","848f6d8d":"OneBroGlobal()","848faed7":"BAI20()","84900b04":"whitelistContract()","8490d598":"wholeTokensReserved()","8491b49c":"rain(address[],uint256[])","84922374":"isDistConfig()","84924b60":"findAndPayTheWinner()","849292bc":"emitStateContractChanged(address)","8492aa9c":"getAddressNickname(address)","8493407b":"CorporateNews(uint256,string,uint8,string)","84934e40":"DappUpgraded(address,address,address)","8493a06e":"returnLongTokenAmount(address[3],bytes32,uint256)","84941984":"_removeTokenFromPartition(address,bytes32,uint256)","8497a8d8":"ESCToken()","84987faa":"getNodeRightChild(bytes32)","8498f706":"EthPalace()","84995370":"TheFoolRareToken()","8499bc63":"GeneBlockChainUserIDs(address)","8499ee3a":"newToken(string,uint8,string)","849a7337":"approveBountyTransfer(address,address)","849a7cb7":"convertBytes4ToArray(bytes4)","849aaf8e":"minimumValue()","849ab974":"HasOwner(address)","849ae5ea":"isBlockpassInvestor(address)","849bb2db":"withdrawServiceFee()","849cf588":"addSynth(address)","849d0d24":"TVCrowdsaleContract()","849d16d2":"BffDoomToken()","849d926b":"parseBlockHeader(bytes)","849e3dcd":"SangusToken()","849e6b17":"MakeBuyOrder(bytes32,address,uint256,uint256,address)","849e961a":"ICO_PRE_SALE()","849f94bf":"getMatchIndex(uint8)","84a014d8":"oneTimeSold(address)","84a0f604":"transferMultipleDifferentValues(uint256[],address[])","84a11df9":"ismaster()","84a1f5a5":"claimTokensFor(address[])","84a2f00b":"order(bytes32,uint256,uint256)","84a2f5a4":"MoonDust()","84a34caa":"BaseMPHToken()","84a37273":"addTransaction(address,uint256)","84a429a0":"createDklSiringAuction(uint256,uint256)","84a438de":"Course(string,string,uint256)","84a4974c":"MintAndTransferEXH(address,uint256,bytes32)","84a6469a":"setNewMintRequest(address,uint256)","84a64c12":"cancel1(uint256)","84a68690":"withdrawRequest(uint256,uint256,uint256,uint256)","84a6a68a":"releaseTeams(uint32,uint32[])","84a7b223":"Canary(address)","84a80c6b":"getB0()","84a83662":"changePassword(string,string)","84a97ab7":"removeAddressFromAccount(address,address)","84a9b91c":"capWEI()","84a9d711":"assertThrows(string)","84ab2cdb":"byte_to_bits(bytes1,uint256)","84ac33ec":"deregister(address)","84acdae7":"getAuctionStartBid()","84ad6ff3":"ReversibleDemo()","84ad8e8f":"discountPrice()","84aeb4f0":"getTokenContribution(address)","84afaa7c":"getReceiptAmount(uint256)","84afb526":"marketor()","84afd121":"bytesToUint2(bytes)","84b06191":"CampaignAccount(address,uint256)","84b08d41":"partner2_signed()","84b0e001":"setEventResult(string,uint32,uint8)","84b1fcb6":"TokenOwnedFund()","84b2e59d":"lower(string)","84b35fbb":"proposeFoundationTransfer(address)","84b366dc":"dest()","84b3b232":"depositofferToken()","84b4340b":"failWithReason(string)","84b46829":"San4Contract()","84b4d3f6":"determineGoalScoringCardIds(uint256[],uint256[],uint256)","84b60937":"getRollUnder(uint256,uint256)","84b735c2":"address1a()","84b76824":"cancelWithdraw()","84b7964f":"isClient(address)","84b79b3d":"eosBASE(uint256,uint256)","84b83a96":"finishChampionGame()","84b8d6a5":"Airdrop(address)","84b98987":"getPrice(address,string,string,string)","84b9a4a5":"SALE_STEP()","84ba2642":"mint(address,uint256,address,string)","84ba745e":"totalClass()","84bc8d2e":"read_purchase_at_index(uint256)","84bcd93e":"setSealableProperty(uint256,bytes32,bytes32)","84bcefd4":"collected()","84bd3a28":"TierRainmakerDividendAddress(address)","84bdaf85":"centsInPhaseOne()","84be4079":"Lendr(string,string,address)","84be414d":"KryptopyCrowdsaleMock(address)","84be59d1":"giftPool()","84beac36":"KRCToken(address)","84bf6fac":"mEtherValid()","84c019e3":"noBonusTokenRecipients()","84c14b25":"sellDentacoinsAgainstEther(uint256)","84c2473f":"mainIcoEndBlock()","84c344fe":"_register(bytes4,string)","84c3edf9":"getHoldAmountAccounts()","84c4ee9e":"getHivePot()","84c5c34d":"transferFromToICAPWithReference(address,string,uint256,string)","84c615e2":"giveKingdom(address,string,string,uint256)","84c64a19":"setApp(address,address)","84c6774c":"safeMathMul(uint256,uint256)","84c6a9fe":"setFABAcompanyTokensPercent(uint256)","84c6f650":"PAYOUT_TIME()","84c7bf4c":"setBlocking(address,address,bool)","84c830d3":"getDepositByIndex(address,uint256)","84c8d5fa":"xenograft(uint256,uint256,uint256)","84c8df88":"testMemoryIntegrityCheck31Bytes()","84c99b6d":"tokenIssuedAirDrop()","84ca65e0":"addOperationType(string,string)","84cb4fec":"_getBlocksPerYear(uint256)","84cba6da":"registerUsers(address[],uint256[])","84cbc92f":"buyPotato(uint256)","84cc315b":"getCurrentPrice(address)","84cdbb4b":"relaseLock()","84ce8f1e":"getTotalF3()","84cfa08c":"startKilling()","84cfc5aa":"WABnetwork(uint256,string,string)","84cfca00":"setMaxPlayers(uint8)","84d062b4":"updateEthToTokenOrder(uint32,uint128,uint128)","84d0aad8":"loadOldData()","84d24226":"claimableTokens(address)","84d2688c":"getDarknodePublicKey(address)","84d2731c":"namesOf(address)","84d43f66":"setAffiliateSetter(address)","84d46860":"getMyStageBet(uint256,uint256,uint256)","84d47dee":"DayDayCrowdsale(uint256,address,address)","84d4c178":"_escrowInflationBonus(bytes32,uint256,uint256,address,address,bool)","84d5d944":"transferAndLock(address,uint256,uint256)","84d60043":"CioCoinERC20180629Token(uint256,string,string,uint256)","84d61a32":"showFPInterest()","84d62f47":"bindSmartIdentityByRegulator(string,string,string)","84d6bd43":"requiredEvidence()","84d7c99d":"deleteUInt8Value(bytes32)","84d7ea12":"setMilestonesContractAddress(address)","84d80057":"hasDeadlinePassed(bytes32)","84d83f07":"GetLoanIdFromPortfolio(uint256,uint256)","84d8529f":"refundInternal(bytes32,address,address,uint256)","84d9390a":"TEAM_PERCENTAGE()","84d9bee2":"bidCC(uint256,bytes32)","84da7e38":"setColorRed()","84da92a7":"updateName(string)","84dac46e":"Fucksign()","84db71a3":"getRefereeRewards()","84db8d1e":"_nextPotTax(uint256)","84dc1028":"getBonustwo(uint256)","84dc2b10":"_saveData(address,bytes32,address,bytes32,uint256)","84dcde97":"removeSynth(bytes4)","84dd4332":"lastCallPUST()","84dd9591":"getTotalHoldAmount(address)","84df87c3":"SPITEST()","84dfb2bd":"setETHAddress(address)","84dfbfe2":"setLpFee(uint256)","84e0b689":"_yearThreeSupply()","84e10a90":"getTotals()","84e11251":"setMinInvestmentLimit(uint256)","84e192a7":"getArbiterCandidates()","84e1bf74":"emissionOn()","84e2341d":"internalSetDestinationMultisigWallet(address)","84e2d578":"OperationAddress()","84e336fc":"ANUNYA()","84e37ad9":"prefixedHash(uint256)","84e3ac94":"oneTokenInWei()","84e45689":"authorize(address[])","84e4c52b":"getTimeLockSecondsRemaining(uint256)","84e4d3a8":"freezeAccount(address,bool,uint256,uint256)","84e4d57f":"ApplyForCertification(string,string,string,uint256)","84e527ad":"IMDESale(uint256,uint128,uint256,uint256,uint128,string)","84e60e8b":"ico_promo_reward(address,uint256)","84e64a1f":"stageStartDate(uint8)","84e67523":"getSumAmountOfOpenSteps()","84e6ee4b":"setMainnetAccount(string)","84e70093":"cloneOrder(address,uint256,uint256,uint256)","84e700ee":"totalAllocatedPurchase()","84e7686b":"setAdmin(address[],bool)","84e77095":"GetEvidence(bytes32)","84e77da2":"updateKryptoroToken(address)","84e79842":"addAgent(address)","84e7e3d3":"MINT_INTERVAL()","84e83ee2":"SparksterToken()","84e85974":"YGO()","84e8a7df":"_soldOutside()","84e8b36e":"GetAskingTokenDecimal()","84e8bff9":"burnaftersale(uint256)","84e9ec37":"bonusTokenRateLevelFour()","84ea2e31":"GetDOTNumRevokableHashes(bytes32)","84eb11ce":"DoggyToken()","84eba00c":"tokenholder()","84ebd065":"NunesTestCoin()","84ebde52":"Under_the_Hood()","84ec480c":"marketToken2020()","84ecdaf6":"advanceState()","84ececf2":"userCreateSaleIfApproved(uint256,uint256,uint256,uint256)","84ed49a7":"isPoweruser(address)","84ef0778":"tokensIssuedTotal()","84efe4d6":"backSkinCoinOwner()","84eff1d0":"walunlock()","84f06570":"createAllTokens()","84f08cd9":"TokenContract(address)","84f10c35":"testTransferCreator()","84f19f37":"createVoting(bytes32)","84f1b0b8":"__flooredLog10__(uint256)","84f1bd4e":"fpart(int128)","84f1cdb7":"intFunc(int256,int256)","84f32395":"setAssetToExpire(uint256)","84f3597b":"availableRefunds()","84f54874":"startWeekThree()","84f85951":"founderWithdraw()","84f88cbf":"TonToken()","84f94221":"getRoot(bytes32)","84f9c928":"get_signature_block(address,address,bytes32)","84fa2c97":"totalCentsCollected()","84fae760":"hello(address)","84fb24a5":"_addCourse(uint256,string,uint16,uint16,string,string)","84fb427c":"_transferHolder(address,bool,uint256)","84fc8050":"nugget(uint256)","84fd176b":"bonusPhaseTwoDeadline()","84fd5477":"isAuthorizedAccount(address)","84fd7ef0":"TOKEN_FOUNDATION_CAP()","84fdab0d":"pickConsolationPrize(uint256[])","84fde1c6":"calculateScorersForTeamIds(uint256,uint256)","84fdec83":"ownerCanWithdraw()","84fe5029":"weiCap()","84feab93":"Emit_OffchainPaymentFlag(address,address,bool,bool)","84feed25":"VoxelX()","84ff2e45":"coreTeamTokenSupply()","84ff435f":"UpdateUserNickName(address,bytes32)","84ffc422":"BountiesTokensHolder(address,address,address)","84ffcb5d":"setContractsMiniGame(address)","85000a86":"TitleUpdated(uint256,uint256,string,string,string,uint256)","85002354":"ZillowBlockchain(uint256,uint256)","85003d30":"CollateralTransferCanceled(uint256)","85007e54":"Zakat()","8500d919":"getBorrower(uint256)","85011eec":"Movie(string,string,uint256)","8502293b":"newCs(address)","85025396":"setProviderClientsCount(uint256,uint256)","8502935a":"maxInflationRate()","850382c8":"prova3(uint256[])","8503a6bf":"ERC721TokenMock()","8503b6a5":"addProposal(address,uint256,address,string,uint256)","850595c1":"contributorID(uint256,address)","8505a074":"ClassyCoin()","85071d9c":"SCARABToken1()","8507bee8":"joinedCrowdsalesLenMax()","850895dc":"CheckValidDate(uint8,uint8,uint16)","8508a693":"doTeamMinting()","8508d88f":"sendICOSupplyToken(address,uint256)","85093668":"jackpotBank()","8509a001":"rewardDenominator()","850a1532":"voteSnapshotBalance(address,uint256)","850a2e78":"setResults(address,uint256,uint256[2])","850a4621":"emitActiveChanged(bool)","850a7eca":"endTimeLockedTokensAdvisor()","850c362a":"initCard1()","850d8a14":"CryptolottoToken()","850d9afb":"ENDTIME()","850db35d":"didPayInterest(bytes32,address,address,address,uint256,bool,uint256)","850e141a":"updateYearsSinceRelease()","850e2bc4":"setLLV_edit_22(string)","850e3760":"getShine(uint16)","850e47db":"KudoCoin()","850f2e2c":"findTileByAddress(uint16,uint16,address,address)","850fb62d":"transferProcess(address,address,uint256)","85107367":"stakeAddress()","8510b43f":"isSaleRunning()","85113156":"etherERC20()","8511b843":"addSpaceshipMoney(uint256,uint256,uint256)","85138313":"PureAirToken(uint256,string,uint8,string)","8513c619":"addManager(address,address)","8513db86":"test_threeValidAndInvalidEqAddress()","851545de":"transformAgent()","8515e413":"payUserOutgoingTransactionCommission()","851645e6":"getRandomUint(uint256)","85174a31":"transferToSelf(uint256,bytes)","85177f28":"EthReceived(address,uint256)","851a33e9":"getBylawsMilestoneMinPostponing()","851a61d7":"Dist(address,uint256,address)","851ad4d6":"getNumDragons()","851aea7a":"setUser(string,string,string,bytes32)","851b6ef2":"getAllVotes()","851bb3c3":"bonusEnds15()","851c0cf6":"bltMaster()","851c27de":"earlyStageSetting()","851c4414":"getEvabotContractAddress()","851c5bf6":"addVestTokenAllocation(address,uint256)","851c9d11":"DGB()","851cad90":"THOUSAND()","851cc7f9":"coinMultiplayer()","851d1c27":"_transferFrom(address,address,address,uint256)","851d46f3":"internalCheck()","851e6b3a":"buy100Price()","851ee3e2":"ApproveERC20()","851f9e20":"chargeOff(address)","85203aa2":"lengthNotEqual(uint256[],uint256,string)","85209ee0":"contractState()","85216449":"checkCustodian()","8521b59c":"addDataPoint(int256,uint256,bytes32)","852263aa":"LogThresholdChange(address,uint256)","8522ac8c":"testTransferOwnership()","85233869":"NumberOfMiners()","8523930a":"calculateNoOfTokensToSend()","85252e82":"setTransferFee(address,uint256)","85255ab0":"Nero()","8526492f":"getTokensAmount(uint256)","85265ee6":"press_address()","8526d092":"isValidContributorAddress(address)","85271fa1":"_validateUSDAmount(uint256)","85276721":"DevReward(address,uint256)","8527831b":"getIndex(bytes32)","8527c3b0":"changePriceRandomFight2Death(uint256)","8528b7b0":"WILDToken()","852980a0":"addCourses(string,string,string,string,string,string)","852987f3":"getRecoverSigner(uint40,uint256,uint8,bytes32,bytes32)","8529d576":"toUint(bytes)","852a6bd4":"getBalanceOfPlayer(address)","852a7d6c":"setExtraDistribution(address,uint256)","852ada4b":"nonFungibleOfOwnerByIndex(uint256,address,uint128)","852b6121":"setInitialBlockTimestamp(uint256)","852c061a":"axiesPrice(uint256,uint256,uint256)","852c5662":"adjustFlame(uint256)","852ccf2b":"YIYSToken(address,uint256)","852da11d":"tokenCreationCapPreICO()","852dbfc6":"pickURL()","852dc589":"setQuitLock(address)","852e9f46":"transferAndFreeze(address,uint256,uint256)","852ede8d":"removeToken(string,int256)","852f31c6":"teamStageSetting()","852f6662":"isProgramFactoryContract()","852f8b74":"getBookSigner(bytes16)","85307bef":"TronToken(address)","85318217":"RegisterMine(string,uint256,uint256)","8531bb56":"SaleHasEnded()","8532137c":"Lexzoom()","853255cc":"sum()","853262a2":"tgrSettingsPartContributorIncreasePerStage()","85349e01":"totalDeveloperCut_()","8534b3a8":"setParticipateFee(uint256)","853504f3":"OpenToken()","8535490f":"redeemEther(uint256)","853552d7":"_slotAddNew(address)","8535d2ec":"sendBatch(address[],uint256[])","8536a50e":"_setBurnFeeProp(uint256)","8536bf8f":"BuyIPG()","85370965":"distributeVault(uint256,uint256,uint256,uint256,uint256)","853717bb":"calcBurnAmount(uint256)","85378346":"getChancePowerWithBonus(address)","853828b6":"withdrawAll()","853a4ec2":"grantReserveToken(address)","853a9d32":"EGGS_TO_HATCH_1HIPSTER()","853b59d7":"phase_1_token_price()","853d814e":"MyFairToken()","853df275":"duel(address)","853e88fe":"hashVM()","853f636b":"sendAllTokensToFounder(uint256)","853f7e98":"BDLToken()","85423912":"setDiscipleItem(uint256,uint256)","854254e8":"buildLoanOrderStruct(bytes32,address[6],uint256[9])","85431ec8":"setRate333()","85439f82":"someFunction4()","8544023a":"nokuMasterToken()","85443a2b":"CampaignContract()","85444de3":"getChildChain(uint256)","85445829":"numMatches()","85448c59":"getBountyAddress()","85461f69":"calcReward(uint256,address)","854642e1":"mintNewDrawings(uint256)","8546d393":"Anatomia(uint256,uint256)","85473be1":"maximumCoinsPerAddress()","85476d6e":"GetCurrentTypeSaleItem(uint256)","854772ea":"getUserTotalReward(address,bool,bool,bool)","8547af30":"lastBidder()","8547bb3a":"publicSaleMode()","85482f89":"setOnePowerAge(uint256,uint256)","8548cc21":"allocateOwnerTokens()","8549b326":"isSettable(uint256,string)","8549d6f4":"MayanProtocolContract(uint256,uint256)","854a3d64":"LogStartSale(uint256,uint256)","854a9cc4":"ImpeachmentProposed(address,string,uint256,address)","854b1cdf":"curPayTableId()","854bb344":"NoblesseOblige()","854bec87":"payback()","854c2e1e":"HitToken(string,string,uint8,uint256,address,address,address)","854c4a0d":"DownSuccess(string,address)","854c584d":"AdsventureToken()","854cb674":"TheIlluminati()","854cd978":"ClaireToken()","854cff2f":"setWhitelist(address)","854e32cc":"revenueShareDistribution(address)","854e85c6":"lifeEvents(uint256)","854ecd23":"Vaynix()","854f1663":"setNonprofitDisbursementAddress(address)","854f1a1c":"VIVARefundVault(address)","854f3988":"eighth_withdrawal(uint256)","854f4817":"buyKissBTCWithCallback(address,uint256)","85502264":"deptcheckrespond(address)","85506473":"GnosisToken(address,address[],uint256[])","855085b8":"interCrypto()","8550aaf0":"BONUS_TIER_9_LIMIT()","8550cf46":"buyGameCoin(uint256)","855114c9":"buyNation(uint8)","85511d5f":"setEmergencyCode(uint256,uint256)","85512e5b":"EthlanceUser2(address)","8551884a":"authorizeListingService(address)","8551b896":"pre_tokensSold()","8551e3fe":"savePost(bytes32,uint256)","85522831":"numIntervals(uint256)","85528394":"currentClaimPriceWei()","85529636":"getSiteTokenId(uint256,uint256)","85530d7c":"setPetLastBreedingTime(uint64)","85535cc5":"setVaultAddress(address)","8553f6fb":"hardCapDividends()","855460d8":"externalBuy(address,uint256,uint256)","8554d60a":"addTenParticipants(address,address,address,address,address,address,address,address,address,address)","8554d92c":"verify(uint256,uint256,uint256,uint256,uint256)","85550c6b":"tradeKey(bytes32,bytes32)","8555cde9":"Permissioned(address,address,bool)","8555de47":"BlackPyramid()","85561120":"TPTToken(uint256)","85564b97":"MasterWithdraw()","85565585":"crowdsaleOwner()","85586e8a":"allocateCommunity(address,uint256)","85587375":"restartAssign()","855876d5":"countCliDreams(address)","8558c0af":"createBag(uint256)","8559fd88":"requestRandom(uint8)","855b7f5b":"getAdvancedTransfer(bytes32,bytes32)","855b842d":"isUserInBlackList(address)","855c145b":"specialManagerCountInt()","855c45e7":"EIP20Factory()","855c95f1":"createETHAuction(uint256,address,uint16,uint256)","855ce579":"setTwoPowerAges(uint256,uint256,uint256,uint256)","855ceb7d":"AirToken()","855d0700":"insertList2(uint256,uint256,uint256,uint256,string,uint256,string)","855d7c21":"updateTokenBaseRate(uint256)","855e0629":"setIconRate(uint256)","855eafa7":"get_maker_fee()","855f2b3a":"createGen0Auction(uint256[2])","855fe4c0":"ifSuccessfulSendFundsTo()","855fe6ed":"getConfigEntryInt(bytes32)","85602ad5":"getPreviousValidators()","85609b1c":"compose(string)","8561d136":"currentRunningAddress()","8561dc0b":"tokenPostIcoUsdCentPrice()","8562e452":"ADVISORS_SHARE()","8564b2cd":"listItem(uint256,uint256,address,uint256)","8564c284":"setCompte_34(string)","85652d1f":"getInvoiceAddress(uint256)","85654c9c":"setMembershipRoster(address)","85663119":"initialPrize()","85666a7c":"TEAM1()","85673296":"DepositBalance()","85673fb8":"follow(address,uint256,address)","8569cc4e":"release_4()","856a89fd":"drawRaffle(uint256)","856b3108":"UpdateInitiateContractAddress(address)","856b7d2c":"SignDividend(uint256)","856bb9cc":"addConsent(address)","856c0181":"countriesStatus()","856c486b":"WoodyToken()","856c6bd1":"checkRose(bytes32)","856c71dd":"isAvailable()","856c8922":"getGameRules(uint256)","856cddb0":"DummyOVOToken()","856dc78e":"getWarriors(uint256[])","856de136":"FAPFundDeposit3()","856deacf":"findTag(string)","856e8488":"erc20TokenContract()","856eb2d1":"submitTransactionWithSignaturesToken(address,address,uint256,uint8[],bytes32[],bytes32[])","856ed703":"currentCap()","856f3080":"WhatWasMyHash(bytes32)","8570153e":"publish(string,string,bytes,address[])","85716e2f":"changeAdminer(address)","8571baff":"SimpleCrowdsale(address,address,address,address)","8572e364":"scale(uint256,uint256,uint256,uint256,uint256)","8573d4aa":"OwnershipTransferPending(address,address)","8574ddf9":"snailmasterReq()","8575052a":"set_fees(uint256,uint256)","857512b4":"airdropCountLimit2()","85760377":"PixelTransfer(uint16,uint16,uint256,address,address)","857637c9":"ShopDexToken2()","85766cc3":"Calculation(string,string,string,string,address)","8577efc5":"DIGI()","8577ffc1":"unofficialUserSignUpFee()","857835f9":"getPostsFromIds(address[],string[],uint256[])","85787c8b":"encode(uint256[],uint256[])","85796a2d":"bonusClosingTime0()","8579c10e":"payDevelopersFund(address)","8579cbde":"getPrice(string,uint256,address)","857ac1c9":"TokensBurned(address,address,uint256)","857b3224":"setOAR(address)","857b575e":"qquizwinnerToken()","857b7dfc":"buyLittleDragonGirlLottery()","857ba7fb":"MAX_CONTRIB_CHECK_END_TIME()","857bcb2c":"adminAddTrustedCurrencyContract(address)","857cc1c4":"ExchangeGift(string)","857cd569":"FundDeposit(address,address)","857cdbb8":"getPublicKey(address)","857cfff9":"homeDailyLimit()","857d39d7":"CCH_LLV_FIFA_1()","857d4c07":"throwScraps(uint256)","857e6a99":"decreaseTokens(address,address,uint256)","857f4864":"getNextSnapshotTime()","857f54e4":"MonethaGateway(address,address)","8580563c":"finalize(bytes,bytes,bool)","8580b71b":"getLoanIDbyClient(uint256)","8580eb2f":"setFeeBalance(uint256)","858110a5":"proposeShutdown(uint256)","8581dc7c":"SociBit()","85820925":"getCompte_17()","8582ac21":"getIcoInfo()","8582b7dd":"OrxERC20()","8582e554":"transferBy(address,uint256)","858310d8":"getPreICOAddress(uint8)","85839731":"setKittyContractAddress(address,address)","8583b1b8":"_setUserInfo(address,uint256,uint256)","85861b15":"setUnboundedLimit(address,bool)","85867cd5":"BDSMtoken()","8586b2f0":"getPermission(address,string)","8586e75b":"ChangedResource(bytes32)","8587be6e":"ceil(uint256,uint256)","8587edbb":"lockEndBlock()","8588b2c5":"adopt(uint256)","85899cee":"CryptoThreeKingdoms()","8589c725":"deleteWork(uint256)","858ac4d8":"TransferOwner(address)","858c7559":"chainIDSeed()","858ced35":"setUser(address)","858e41b4":"lemonContract()","858e58d6":"RemapImportedNotUsed()","858f84e7":"WTFToken()","858fa2f5":"setArrayIndexValue(bytes32,uint256,address)","85903f67":"setUnofficialUserSignUpFee(uint256)","85908ffa":"buyTokensPostHook(address,uint256,uint256)","8592b778":"_rand()","8594bed0":"cancelMintRequest()","85952454":"newOwner(address)","8595c9ff":"diff(uint256[])","8595f8b1":"getGasPricePctOfBetValue()","8596982d":"getNotesCount()","8596d9ed":"transferInternal(address,uint256,address)","8597705f":"DataEquip(address)","8597eb6e":"ericukis(uint256,string,uint8,string)","859832e6":"locationsLength()","85984e69":"WavesCommunityToken()","859971dc":"initialFunding()","8599d0d8":"buildIdentifier(address,address,address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,string)","859a711d":"icoBonus2EndDate()","859b97fe":"cancelAuction(address,uint256)","859bbfee":"floatAdd()","859bcc71":"allowDisbursePaymentWhenPaused()","859ccc72":"setPlayerVirusNumber(address,uint256)","859d1bc7":"updateLeftLottery()","859da4e3":"transferParityOwnership(address)","859e25df":"giveProjectMoreVotes(address,uint256)","859e7d32":"getEpochData(uint256)","859f5717":"AuctionSuccessful(address,uint256,uint256)","859f63dc":"checkRewards(uint256[])","85a013e0":"setAnswer(uint256)","85a08f41":"buyLimitSupplyMax()","85a09f6f":"withdraw123()","85a10b30":"burningAdress()","85a143f4":"DailyRoi()","85a156af":"activityFunds()","85a17a1a":"isValidBet(uint8[4])","85a1c242":"PSM_PRICE()","85a227fd":"APC()","85a242d7":"teamTokensAccount()","85a2675b":"isConfirmedWithdraw(uint256)","85a26d7d":"getAllPeople()","85a2dd15":"hasAccess()","85a2f6af":"donateToken(address)","85a30c33":"changeContractAddress(address)","85a345e2":"disTrust(address)","85a34f4a":"getGameSums(uint256)","85a38635":"votingEnd()","85a49f2e":"verifyPass(address)","85a52584":"SettingsChanged()","85a735dd":"partAllocationLength()","85a8f42e":"diff(int256[],int256)","85aa6103":"auctions()","85aa6e09":"granted(address)","85aa92a7":"storageAddress()","85aaff62":"transcoder(uint256,uint256,uint256)","85ab0c19":"tokenProvenance(uint256)","85aba275":"assign(address)","85ac2f7b":"getListedTime()","85add95b":"Spike()","85ae067b":"func_040B()","85ae2f1c":"sunFinished()","85ae6d2d":"OfferingOpens(uint256,uint256)","85af4142":"verifyTeam(uint256)","85b018e9":"isSubjectRaiseTap(uint256)","85b09a01":"DIVC()","85b12c7c":"launch(uint256)","85b1423e":"returnAll()","85b142ed":"getAccountState(bytes32)","85b2ff8f":"getWeightedRandomMember(uint256)","85b31d7b":"myInfo()","85b39fc1":"CONTRACTIUM()","85b3c420":"createWeight(uint256)","85b3ed4e":"GoalReached(uint256,uint256)","85b443b6":"econReserveWallet()","85b4bb53":"getSettings()","85b51737":"addSafe(uint256,uint256)","85b6824f":"setMinterWallet(address)","85b688de":"PRIVATE_STAGE_START()","85b73d3c":"testCreateNewRevision()","85b75b1e":"toogleStatus()","85b86188":"isSaleClockAuction()","85b8c64a":"bonusFreeLOT()","85b8d86f":"CrowdSaleFinished(string)","85b923ca":"getCandidates(bytes32)","85b94536":"debug_judge(bytes32[13],uint256,bytes32[],bytes32[],bytes32,bytes32,uint256[4],bytes32[10],uint256[4])","85b9c729":"OnWithdrawTo(address,address,address,uint256,uint64)","85b9f607":"buyTokensWithGuarantee()","85ba0052":"stringToUintNormalize(string)","85ba9a99":"setMinimumHydroStakes(uint256,uint256)","85bac237":"addPayment(address,uint256)","85bb7d69":"answer()","85bb821b":"WTO()","85bb8e29":"continuousSale()","85bbb53a":"ancestorBuffPercentage()","85bdc4a2":"lastBlock_v16()","85bddb97":"addOnOneStage(address,uint256,uint256)","85bde3f2":"SaddlePr(uint256)","85be2f02":"SampleCrowdsaleToken(string,string,uint8,uint256)","85be8fe6":"confirmReceivedAt(uint256)","85bf96a0":"JOP(uint256)","85bfe55d":"getUserByEmail(bytes32)","85c07546":"TransformCoin()","85c09f26":"topTotalSupply()","85c1057b":"payAndHandle(uint256,address,uint256)","85c15d9a":"exchangeRates(address)","85c3649f":"registerSelf(bytes32)","85c373c3":"releaseAccount(address)","85c3bb6f":"getMsg2()","85c4e3d1":"sendSubscriptionBonus(address)","85c53cf1":"giveAccess(address,bytes32)","85c5e9f8":"mimin(uint64,uint64)","85c64029":"set_prices(uint8,uint8,uint8)","85c653ba":"Divsforall()","85c78fac":"retryOraclizeRequest(uint256)","85c7a953":"WithdrawFullBalanceFromBankAccount()","85c8d362":"CTM()","85c8f447":"totum()","85c95d30":"setResourcesOtherManager(address,uint8)","85c9dd72":"GCOXToken(string,string,uint8,uint256)","85ca165a":"count_donors()","85cb2e6e":"refreshEmissionReleaseTime()","85cb469a":"getIcoFund()","85cb4ea2":"getPunchCardsInternal(address)","85cba6b1":"getFallback()","85cba722":"EGLSold()","85cbc881":"totalUSDRaised()","85cc3114":"doDeposit(address)","85cc51c2":"destTokensTeam()","85cc6fba":"boomrToken()","85cc9a2b":"issueKey(bytes32,address)","85cdafa6":"teamOneVolume()","85cf61ef":"payRake(uint256)","85cfdec7":"buyKWHAgainstEther()","85d02c8a":"changeMaximumInvestmentsAllowed(uint256)","85d178f4":"withdrawWallet()","85d19a25":"getPositionId(uint256)","85d1be13":"preSaleSecondPrice()","85d3b5bd":"policyID(uint256)","85d45d34":"comments2()","85d51d19":"contributorETHBalance(address)","85d544be":"transferAndLockUntil(address,uint256,uint256)","85d559ee":"TbookToken(uint256,string,string)","85d5c971":"logTransfer(address,address,bytes32)","85d5e631":"disableTokenTransfers(bool)","85d61e2a":"supplyNum()","85d63cce":"REMAINING_SUPPLY()","85d71df1":"investxPlatform()","85d77e5f":"priceExpiration()","85d80458":"m_deployer()","85da1192":"setMaxFaucet(uint256)","85daafe6":"capitalRaisedTarget()","85dacd5b":"voteSnapshotBalanceAuto(address,uint256)","85db2dda":"PayoutQueueSize()","85db2e3a":"PoD()","85dc3004":"setFundAddress(address)","85dc6721":"emptyShipCargo(uint32)","85dcbb5a":"returnMember(address)","85dcee93":"descriptionHash()","85dcfbd4":"VernamWhiteListDeposit()","85dd1fbd":"bet_on_team_1()","85dd2148":"getSaleDate(bytes16)","85ddb747":"transferFromPosttgefund(address,uint256)","85ddf726":"dismissOperator(address)","85de4841":"uint2str(uint64)","85de4f72":"luckybuyTracker_()","85dee34c":"query2_withGasLimit(uint256,string,string,string,uint256)","85defaf4":"voteEnds()","85df508f":"tip_rate()","85df51fd":"blockHash(uint256)","85e00e4b":"bezpolToken()","85e040b1":"Invested(uint256,address,uint256)","85e050e4":"get_property_contact(uint256)","85e05445":"MartiniumToken()","85e0832c":"totalMintSupply()","85e1684c":"computeS(uint256,uint256)","85e344f7":"SmartInvestmentFundToken(address)","85e36cc2":"foundationAmount()","85e3f058":"getIdentity(uint256)","85e41e7e":"TokenFree(uint256)","85e436bf":"setBuyRate(uint256)","85e567d4":"verifyProof(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[1])","85e57f3c":"updateLogoUrl(bytes32,bytes32)","85e5908e":"Group_3()","85e5bb3a":"Security_AddPasswordSha3HashToBankAccount(bytes32)","85e5d7ee":"mintAll(uint256[])","85e5f08a":"updateVerifiedSign(address,address,string,uint8,string)","85e612e4":"getBirthYear()","85e61b4a":"processFundingSuccessfulFinished()","85e61e67":"set_arbits_whitelist(address,address,bool)","85e68531":"revokeAccess(address)","85e7d4cb":"CCC()","85e870b3":"default_rate()","85e91347":"initializeSaleWalletAddress()","85e99be4":"updateHighestPrices_(uint256,address)","85e9bd2b":"setAdminAddress(address,address)","85eac05f":"changeOwnerAddress(address)","85eb6109":"getAddressClaims(address,address,uint8)","85ec419a":"setTokenTwdt(address)","85ed5cf9":"resetAlias()","85eddeea":"setReward(address[],uint256[])","85edf68d":"initVestingStages()","85ee292c":"airdropTesterFinal(address[],uint256)","85ef4ae7":"f_internal()","85ef5a8a":"GermanCoin(address,address)","85efa3aa":"setHold(address)","85efb721":"fillTheBank()","85eff0ef":"hardcoreBattleWith(uint256,uint256)","85f01859":"setWord()","85f07a2b":"CALLER_EXCHANGE_SHARE()","85f07b64":"confirmedAmount()","85f07bbe":"MIN_PLAYERS()","85f0e72c":"uintToStr(uint256,uint256)","85f0f098":"allowWithdrawals()","85f16544":"EdgarRichardWunsche()","85f19bc4":"giveDividend()","85f255ea":"getUserFactoryContractAddress()","85f2aef2":"team()","85f2d854":"createManyDrinks()","85f2e4b1":"_strConcat(string,string,string,string)","85f3c568":"LogContribution(address,uint256,uint256)","85f45250":"addFunds(uint256,uint256)","85f517d4":"account3Address()","85f52912":"TGRUPToken()","85f52984":"addPrecondition(address)","85f59db3":"CheckN2Exception(bytes32,uint32)","85f63a4a":"preICOBeneficiaryAddress()","85f671a6":"requestWithdrawal(bytes32,uint64,bytes32[],uint256[],uint256[2],uint256)","85f67ae4":"addEpisode(address)","85f8c16d":"claimHours(int256)","85fa33eb":"declareDividend(uint256)","85fab341":"transferTokensAfterEndTime(address,uint256,uint256,uint256)","85fae602":"getInsurance(uint256)","85fbd17f":"PonzICO()","85fbdd47":"_order(uint256,uint256,uint8)","85fbdefc":"masterBalanceOf(bytes32,address)","85fcb4a8":"findPrevOrderId(uint128,uint128)","85fcd363":"votesArr(address)","85fceea8":"getCountSubscribers()","85fdeba7":"vendorAllocation()","85fe0448":"testThrowRestartNotUpdatable()","85fe551a":"ownerGrace()","85fe6200":"recordEndedGame(uint256)","85fed812":"ERC20Lookup()","85ff5e13":"SkinCoin()","85ff70de":"_payFees()","85ff96a7":"getTotalSellingMonsters()","86001519":"totalProfit()","86005b14":"allocateVestable(address,uint256,uint256,uint256)","8600e40b":"notifyWithdraw(address,uint256)","8600f2ec":"totalChildTokens(address,uint256)","86013322":"withdrawSaleBalances()","860241c2":"TAXToken()","8602c8b6":"countryofN(address)","8602c8d3":"ethSendDifferentValue(address[],uint256[])","8603d31a":"auctionDetails(uint256)","860427fc":"setGPSRatio(uint256)","86047946":"_processHistoryItem(bytes32,bytes32,uint256,address,address,uint256,bytes32,bool)","86048c9a":"totalCashout()","8605c97e":"setMarginThresholds(uint256,uint256)","86060884":"SafeGuard(bytes20,uint256,uint16)","86066750":"HelloWorld(string)","86068367":"DYITToken(uint256,string,string,uint8)","8606f905":"balanceOf(address,bytes)","86070cfe":"recoveryVaultAppId()","86073441":"signToApproveAddTokenData()","860772a9":"establishBorrowerReturnFiatPerEthRate(uint256)","860779e7":"setMinBuy(uint256)","860838a5":"frozenAccounts(address)","86096578":"getRetailer(uint256,address)","860aefcf":"limits()","860bb34a":"SIGMA()","860c5ed6":"testVote()","860c851a":"votePrice()","860caf69":"HashAdded(address,string,uint256)","860d7273":"masterKeyActive(address)","860e6185":"commitTo(bytes32)","860e9960":"BetPriceLimit()","860e9b0f":"updateRegistryPrice(uint256)","860f5048":"baseSupply()","861004ae":"Visus(address)","861080ae":"transferMembership(address)","8610f045":"withdrawOffer(uint256)","86115c1d":"MyPurchaseContract(address)","8611643a":"Withdraw(string,string)","86116c12":"PerkscoinToken(uint256)","86117319":"buy_the_tokens(bytes)","8611e330":"FishbankBoosters()","86127ecf":"oraclize(bytes32,bytes,bytes,bytes,string,bytes,bytes,uint256,bytes)","8612d049":"isLocked(address,address)","8612ee13":"addMatch(string,string,string,bool,uint8,uint8,uint256)","86145875":"contributeInternal(address,uint256,uint256)","861654f7":"updatefundingStartTime(uint256)","8616865d":"ReferredInvestorAdded(string,address)","8616bc8b":"contributedTotal()","8617457a":"start_()","86188c97":"fetchOrdersForMerchant()","86192c36":"privateOfferingPercentage()","861c3385":"blocksquare()","861c3a09":"queryByUser(bytes)","861c9c79":"transferToComposition(address,uint256)","861cab52":"canSendGameGift()","861d4e51":"NOETToken()","861d7daf":"deleteImage(uint256)","861dd0a5":"releaseCats(uint32,uint256,uint256,string)","861e2e43":"orderCore(uint256,uint256,uint256)","861e5d6a":"CryptoKotik()","861ec457":"SILVER_AMOUNT_TPT()","861ed3ea":"controllersByPartition(bytes32)","861f8a52":"testThrow_2_invalidOwner_accessRestrictionThrow()","861fcefb":"Token1Token()","86200842":"getSellDailyLimit(uint256,bytes2)","8620410b":"buyPrice()","86212913":"queryAuction()","86216ace":"NotThrowingToken(uint256)","8622031f":"setModuleAddress(string,address,bool)","862235f5":"EthertoteAdminAddress()","8622a689":"expiresAt()","86231246":"returnsOneNamed(uint256,uint256)","86231b9e":"contentHostPaidByAO(bytes32)","86237e7b":"setAngel(uint8,address,uint256,uint16)","862440e2":"setURI(uint256,string)","86260cfe":"UpdateUserEmail(string)","86269a88":"checkBetNumber(uint8)","86271d8b":"minPurchaseInEth()","8627df46":"buyTickets(uint256,uint256)","862882e5":"startAuction(string,uint256)","8628892e":"Initialize(address,address,bytes32,address,uint256,bytes32,address,uint256,bytes32,uint256)","8628aca9":"setIds(uint256,uint256)","862a4bf2":"tokenHolder(uint256)","862b092b":"getTokenName()","862b525c":"gameMiningTokenStartTime()","862b6683":"setValues(uint256,uint256,uint256,uint256)","862c5e16":"validatePurchase(address,uint256,int256[],int256[])","862cb14e":"DMI()","862cdef3":"auctionTank(uint256,uint256,uint256,uint256)","862d0d4b":"_weiToFinney(uint256)","862eb9c0":"setGoldReward(uint256)","862ed594":"XmonetaToken()","862fd38c":"concat(uint8,bytes32,bytes32)","86312b1b":"TripsCoin()","86314af9":"BetOnHashV84()","8631890e":"PLANET_PRICE()","86318bc4":"ethBioxRate2()","86321f95":"switchClaimerAndRemoveOldOne()","86323e85":"isSellingNow()","8633497f":"angelCurrentAmount()","863451dd":"donateEther()","86346c42":"awards(uint8)","86348afa":"ColorReserved(address,uint256)","863524b1":"partnersKey()","86356ab9":"finalizeRefunding()","8635b527":"resetPainting(uint256)","8635f45d":"getSpaceshipProductAttributesByModel(uint16)","863682f4":"getScore(uint32)","86377b63":"registerLoanReplaceDuplicated(address,uint256,uint256)","863843bc":"bonusSupply()","8638aa65":"DEBUG_MODE()","8639ae69":"getAllCrySolObjects()","8639b0d7":"getBalanceDiscrepancy()","863a0372":"hex2dec(uint256)","863a03e0":"salvage(address)","863ac22b":"EtherGame()","863b3b66":"purchaseThemedSpinner(string,uint256)","863c51a9":"setCustomerSignature(address,uint256,bytes32)","863c607c":"ReactioonToken()","863d62ac":"Goldmint(address,address,address,address,address,address)","863da000":"disburseAuthorizedPayments(uint256[])","863e24d6":"updateBonusTicketsPercentage(uint8)","863e76db":"ONE_DAY()","863e7e4b":"getCurrentPhraseInfo()","863e8320":"initGPS()","863f2a19":"adjustTime(uint256,uint256,uint256,uint256,uint256,uint256)","863f40ac":"syp1(address)","863f52b4":"makerBetsCount()","864059ac":"clearingPriceComponent()","86420710":"setReceivers(address[],uint256)","8642269e":"buyProduct(uint256)","86428900":"SetPeriodITO_startTime(uint256)","86432925":"profitDistributionContract()","8643d01d":"throwsSaleWalletIncorrectSaleAddress()","8644ddd9":"WOB(uint256,string,string)","86452295":"getPointOf(uint256)","86457702":"authorize(string,address)","8645a3da":"ATTR_PRODUCIBLE()","8646b5cb":"marketTotalEarning()","8646fb43":"Electrominer()","864757a8":"minFinneyToKeep()","8647a5dc":"getTimeLock(bytes32,bytes32)","86481d40":"getLevel(uint256)","864824a0":"phase9Price()","86485cdf":"setCurrentExchangeRate(uint256)","86489ba9":"initialize(address,address,uint256,uint256,uint256,uint256)","8648c0ce":"neumarkCap()","8648f24c":"changeVariables(uint256)","86496e2e":"TcToken(uint256,string,uint8,string)","8649c0a4":"SetEndTime(uint256,uint256)","864a1057":"Start4()","864a9a09":"__mod(bytes,bytes)","864aef45":"buyCard(address,uint256,uint256,uint256)","864af3f4":"Menu02(address[],uint256)","864b525c":"GoldDollar()","864c189b":"LBCToken()","864c2e94":"service_founder()","864ca300":"goldBalanceOf(address)","864ce5dc":"getWeekBonus(uint256)","864d1d72":"getUserCountByRole(string)","864d7e14":"approveAsset(uint256)","864da88c":"_clearBlocksProducers(uint256)","864dd17d":"Controller(address,address)","864e8cc1":"setMaxCharacters(uint256)","864f4e54":"PeerWalletsToken()","864fda69":"minNum()","864fff0a":"DealCompleted(uint256,address,uint32,uint32,bool,uint256)","86508380":"_getUncreditedPoints(address)","8650b6ef":"endTimePre()","86517df4":"concludePresale()","8651dc1e":"confirm(uint256,uint256)","865232fb":"setarg_3_input(uint256)","86544e11":"STARTING_SNAIL_COST()","8654b78d":"AttoresDigitalCertificates(address)","865508ef":"minSend()","86556071":"gracePeriodStart()","8655f0da":"copyAllHpbNodesByStageNum(uint256)","8656dcb6":"distributeTeam()","865733da":"MercuryCrowdsale()","86575e40":"changeName(string,string)","86578375":"withdrawFund(uint256,bool)","865891b0":"PlanToken()","8658b8b9":"checkPermission(address,address,bytes32)","86590955":"changeHeight(uint256)","86591bd6":"testFailMintWhenStopped(int256)","86598549":"_withdrawTokensFor(address)","8659d573":"getCountPosition(uint256,uint256)","865a4253":"prcSum()","865ad6c2":"levelUpCar(uint32,uint32,uint32)","865b0d30":"SingularityTest15()","865c79b2":"setImageDataLength(uint256,uint16,uint16)","865cc6a3":"getDErc20OwnerClaimEnabled(bytes32)","865dc0d9":"EndChanged(uint256,uint256,address)","865eb3d3":"getWorkerProfit()","865fd239":"transfer_token_ownership(address)","865fe035":"addressIco()","86602b6b":"testControlRetractLatestRevisionNotOwner()","86602c84":"frozenAmount(address)","86609b37":"_createCard(address,uint16,uint16)","8660b220":"buyerRate(address)","8660b32b":"getSumInByGame(uint32)","8660bb8b":"updateAllPixelDetails(uint256,uint8,uint8,uint8,uint256,string)","8660cbf5":"battleDecider()","8661009b":"checkPayments(uint256)","866192a2":"getLastAuditDocumentation(address)","866278a8":"level_7_amount()","86628eed":"weisDeposited(address)","86630b7b":"getSaleData(uint256)","86633571":"DestructibleMiniMeToken(address,address,uint256,string,uint8,string,bool,address)","8663b4c7":"StudyCoin()","866408eb":"getPlayerKeysCount()","86647821":"NeuroDAO(address,uint256)","86647bac":"getBountyArbiter(uint256)","8666107c":"eth_received()","86667435":"getPercent5(address)","8666fca5":"holdingsOf_BEAR(address)","86673464":"assertEq15(bytes15,bytes15,bytes32)","8668a416":"assignMultipleParcels(int256[],int256[],address)","8669ccf4":"getFreelancers(address,uint256)","8669e08c":"migrationFinishedTime()","866b5674":"totalBountyinWei()","866b9323":"mintForReportingParticipant(int256,uint256)","866c03eb":"_unmintedTokens()","866d840a":"setCompte_44(string)","866df234":"setLink(bytes)","866e5162":"oslikToken()","866f4555":"Basic23TokenMock(address,uint256)","866f6736":"trustedChildWithdraw()","867022d1":"Initialise(address)","86703c9c":"getProviderClientsCount(uint256)","86707026":"midEtherBonusLimit()","8670cc7c":"BlueDragon()","8670e183":"createLegendaryAuction(uint256,string)","8671090e":"setSavedBalanceToken(uint256)","86715acf":"BodyOneToken(address)","8671b894":"cancelOrder(uint256[3],bytes32,bytes32,uint8)","8671ef4d":"grg(address)","86723215":"createMarket(bytes,uint256,uint256,address)","8672e853":"LogOwnerAdded(address,address,address)","8672f1bc":"isProposalActive()","8673094f":"allGuGiven_()","867387d4":"BurnableToken(address[50])","86749d97":"ZOOToken()","8675cf9e":"MaxToken(uint256,string,string)","8676993f":"setTransformAgent(address)","86773cae":"setPromoEndTime(uint256)","8677ebe8":"isSigned(address,bytes32,uint8,bytes32,bytes32)","8678446e":"preSaleMinEth()","8678c2b9":"HodlEth(uint256)","867904b4":"issue(address,uint256)","86795e8d":"set_master(address)","867a66ac":"ownerCredit(address,uint256)","867b36fe":"setFiscalVerify(bytes32)","867b3d4b":"updateEtherPrice()","867b79a1":"withdrawalRange(uint256,uint256,address)","867befba":"SUV_TYPE()","867c0547":"newPonziFriend(uint256)","867c2857":"transferAgents(address)","867c6e23":"CryptoRides()","867c7eda":"getProposalByID(uint256)","867e248c":"feePercantage()","867e958f":"NAEC()","867ea029":"WESSToken()","867eed11":"privilegedTransferLock()","867f990a":"changePriceUSD(uint256)","867fbe6d":"AnotherOwnerAssigned(address)","86804aad":"queryData(address)","8680e52d":"emitJobOfferAccepted(uint256,address)","86813c53":"sellerIdOf(address)","86814819":"_prePurchaseAmount(uint256)","868149da":"TRONCLASSIC()","8681a07f":"ownerSetRandomApiKey(string)","868203ea":"ZeroChainToken()","86820a7d":"createInputData(uint256,uint256)","86834610":"registerEscapeRequest(uint32,int256,bool,uint32)","8683612b":"exists(bytes32,bytes32)","8683e4b4":"WHUToken()","86842bc2":"verifyNonces(bytes,uint64[],uint64[])","86845f9a":"theCyberGatekeeperTwo()","868467e6":"deliverTokens(uint256)","86849a6c":"TeamTailsChoice(address)","86852dca":"getElectionInfo()","86852fd7":"bountySupply()","86863ec6":"init(address,address,uint256)","86867740":"trueSupply()","86869eae":"totalClosedContracts()","8688b5fe":"getMyContractsByType(uint256)","86897cb8":"Addresses()","8689a500":"putToken()","868a8813":"calculateGrapeBuySimple(uint256)","868d2b62":"ZeusCoin()","868d5383":"transferFromWithData(address,address,uint256,bytes,bytes)","868defd0":"getRemovableIdArrayAddressItems(address,uint256,string,string,string)","868df7f6":"alterFeaturedLength(uint256)","868e3c52":"EosPizzaSliceSafe(address)","868eb6bf":"removeOrders(uint256,uint256)","868f2564":"Iconss(address,address)","868f9c57":"Administrator(string,address)","86908b3f":"TransferInternalLedgerAT(address,address,uint256,bytes32)","86908f93":"FFG(uint256,string,string)","8690d6d5":"CentrallyIssuedToken()","8691162a":"TlcCoin()","86913884":"ShroomeryFarmer()","8692ac86":"transferOwnershipNow(address)","86936ed5":"isReceiptClaimable(bytes8,bytes8,address[],bytes,bytes32[],uint256[],uint256[],bytes)","86954ecc":"Finished(uint256)","86964032":"getHash(address,uint256,uint256,uint256,uint256)","8696807d":"addABaddress(address,address,string)","8696eec4":"setTokedoTokenFeeDiscount(uint256)","86973b0f":"RewardDemoChannel(address,address,address)","86985bee":"getTeamSalary()","86994b71":"RND()","869984c8":"addrOwner()","8699a65f":"rewardsCount()","869ac8dc":"getReferenceCurrency(address,uint256)","869af1ff":"finishTransferGet()","869b22fd":"toEthertoteDevelopmentWallet()","869b3f6a":"testThrowsRetractNotOwner()","869c63c1":"batchOrderTrade(uint8[2][],bytes32[4][],uint256[7][],address[6][])","869c8bd4":"buyChannel(string)","869d436d":"approvedAddressLUT(uint256)","869d785f":"removeModerator(address)","869d7d93":"countLeadingZeros(uint256,uint256)","869e0e60":"decreaseSupply(uint256,address)","869f1c00":"presaleParticipationMinimum()","86a046d5":"lastRefrralsVault_()","86a17f29":"modifyLevelCap(uint256,uint256)","86a1ea7a":"HeliosToken()","86a2ef34":"Indemnisation_4()","86a2f98a":"getPersonalStakeForAddresses(address,address)","86a3171f":"removeAllAttachmentsFromCollectible(uint256)","86a33a0b":"RoundBSold()","86a3736e":"increaseTokenBalance(address,uint256)","86a3c902":"If(address,bytes32,bytes32)","86a3e0a7":"allocated1Year()","86a40e63":"_removeExcluded(address)","86a4f6ee":"MOM()","86a50535":"voteFor(uint256)","86a57f6f":"byteArrays(bytes1,bytes)","86a5ebe1":"getPlayerDetails(address,address)","86a5ff97":"changeStatus(string)","86a61c81":"medicos()","86a66dc3":"getVoteResults()","86a7b995":"maxContributionInWei()","86a8da37":"getNumWinners(uint256)","86a91ab4":"Scale(int256,bytes32)","86a9443e":"WellyPai()","86aa354a":"PUBLIC_SALES_2_PERIOD_END()","86aa552a":"lockAbsoluteDifference()","86aa6c09":"P3D_address()","86ab3f7b":"RESERVED_TOKENS_FOR_ICO_BONUSES()","86abfce9":"Voted(uint256,bool,address)","86acb16d":"register_creature(address)","86ace9b1":"setICOWeek1Bonus(uint256)","86ae5fec":"getParticipantCount(uint256)","86aecb9d":"_lotteryToken(uint256,address,address)","86af6ba5":"addDeed(address,uint256)","86afa110":"lockTrading()","86b08228":"getInvestorAddr(uint256)","86b0befc":"congress()","86b0fc9d":"startsWithDigit(string)","86b14583":"EzPoint()","86b27391":"startCrowdsale(uint256,uint256,uint256,uint8)","86b2be73":"ICO_RATE2()","86b35f79":"read_u16()","86b46694":"currentWave()","86b467f2":"tokenSaleContractAddress()","86b5e2b9":"dataSourceCallbackRoundOfSixteen(uint256,uint8)","86b6b721":"Anaco()","86b6ec6c":"showLastChange(address)","86b6f462":"updateMaxContribution(uint256)","86b714e2":"s()","86b715bd":"setAutoNewbond(bool)","86b76d6c":"MunishExchange(address)","86b7b8f6":"setBalanceHolder(address)","86b88af0":"setLLV_edit_10(string)","86b8f0a2":"teamAllocations()","86b945b0":"getRoundStatus()","86ba793e":"setProviderCountry(uint256,uint256)","86bb1b24":"pegEtherValues(uint256,uint256,uint256,uint256,uint256,uint256)","86bb1e03":"toCollect(uint256)","86bb5a48":"buyAsset(address)","86bb7121":"getBlocksPerRound()","86bb8f37":"claimReward(uint256,uint256)","86bc2338":"isConsumable()","86bd4ef7":"lockPayment(bytes32,address,uint256,address)","86bdea3f":"postTrade(bytes32,uint256,address)","86be3981":"dividendsForUser(address)","86be53d3":"isPresaleOn()","86beaece":"doPurchase(uint256,uint256,uint256,address,address,uint256)","86bfbd44":"setDailyPrices(uint256,uint256)","86c02e88":"allocateFundToken()","86c23d54":"EliteShipperToken(uint256,string,string)","86c2b53d":"EximchainToken()","86c2e8e3":"accept(uint256,address[],uint256[],uint256)","86c3ceae":"setVAtomOwner(string,string)","86c455ee":"team2LockEndTime()","86c57fcc":"b32ToBytes(bytes)","86c59418":"USDToken()","86c5bc1c":"totalExchanged(uint8,uint8)","86c6f66b":"buySilver(uint256,uint256,uint8,bytes32,bytes32)","86c8c491":"setTransferAdmin(address,bool)","86c99779":"blocktubeUser()","86ca32b5":"claimExist(string)","86cb034f":"KIBIS_Token()","86cb531b":"mintPartnerWithLock(address,uint256,uint256)","86cb5cdb":"feeForFirstArtWorkChangeRequest()","86cba22b":"getAllBuyers()","86cc5a1d":"testIsOptionPairRegistered(address,uint256,address,uint256,uint256)","86cd71be":"getNumberOfMinters()","86cdbae9":"append(string)","86ce0285":"allocateTokens(address,uint256)","86ce8327":"updateStarScore(address,uint256)","86ce9835":"transferMoney(address)","86cef432":"CONTRIB_PERIOD3_STAKE()","86cf1e39":"GetherCoin()","86d01727":"setPendingTaxParameters(address,uint256)","86d08447":"getTestThree()","86d0b46d":"foundersTokensPercent()","86d0b48c":"round3Sold()","86d12325":"preSaleDistributionContract()","86d1a69f":"release()","86d23143":"getLastAcceptedProposal(bytes32)","86d263fe":"MarketCollateralPool(address)","86d2ee85":"HOLDING_START()","86d2fe57":"privateSaleStartDate()","86d35ed9":"getCrypton(uint256)","86d3a2b8":"setContributorCap(uint256)","86d3cf0d":"crazyearners(uint256)","86d3f4b7":"ethRateURL()","86d4c423":"UBTC()","86d4ebf7":"test_BasicThrow()","86d4fe9c":"viewTokensRemaining()","86d4ff1d":"canSell(address)","86d518bf":"grantAccessMint(address)","86d53469":"sendPreSaleETH()","86d54fe1":"EtherFundMeCrowdfunding(string,string,string,uint256,uint256,uint256,address,address)","86d59996":"deleteValidationData()","86d5c5f9":"getPassportLogicRegistry()","86d6c8a0":"getTankProduct(uint32)","86d6c9d1":"canHolderTransfer()","86d74037":"distributeToken(address)","86d8aab4":"cancelMultipleOrders(address[3][],uint256[3][],uint8[],bytes32[],bytes32[])","86d922a9":"lastCallTime(address)","86d9b0c5":"make(address,uint256,bool)","86da69f0":"gamble()","86dbfa98":"DINTToken()","86dc88ff":"addMadeTX(address,uint256,uint256,uint256,uint256)","86dc8ace":"pendingVestingPool()","86dcbefc":"test_registerWithoutCertification()","86dd03bd":"setRedeemLevel(uint256)","86dd5e03":"setBossRoundNumber(uint256)","86de99dd":"SetStatus(uint256,uint256)","86def3b9":"getDukeDate(string)","86df3d5b":"getCreateOrderMinGasNeeded()","86e1e589":"NamiAddr()","86e261c9":"updateSecondAmount(bytes32,bytes32,uint256)","86e2c40c":"removeAffiliate(uint256)","86e3060d":"nextFlexibleReward()","86e32cb5":"setSpecialFeePercent(address,uint256)","86e32ed0":"setAllowedContract(address)","86e36ce2":"speechOfOwner(address)","86e37ae7":"tokensForFight()","86e399c1":"priceDivisor(uint256)","86e476dd":"communityAddress()","86e49407":"setFeeUnit(uint256)","86e4993c":"issue(uint256,uint256,address[],uint256[])","86e4a33e":"countBtcAddressLeadingOnes(bytes,uint256)","86e4e178":"CheckTickets(address,uint256,uint256)","86e58bef":"del_user(bytes32,bytes32)","86e58c0c":"getGalleassTokens(address,bytes32,uint256)","86e5ceb4":"previousRoundJackpot()","86e6361e":"setSellInfo(uint8,uint256,uint256)","86e6eee1":"INEX_Token()","86e8c57a":"secondroundprice()","86e92957":"lastDecimal(uint256)","86e97442":"mora(uint8)","86e99bdb":"XTOToken()","86eb3899":"lockPeriodForBuyers()","86ec6177":"endEvent()","86ec8f62":"validateTokenProperties(uint256)","86ecce90":"test_5_assertGasUsage1400Boards()","86ed60e9":"getSpawned(uint32,int256)","86ee8f01":"masterAddress1()","86efb94e":"addressHistoryOf(uint256)","86f10e8b":"divForEthertoteLiquidatorWallet()","86f1865d":"_bcto(uint256,uint256,uint256,uint256,address)","86f19dde":"phase6Price()","86f1f2d4":"mintDigitalArt(string)","86f254bf":"minConversionRate()","86f28fe3":"token_member_order(address,address,uint256)","86f2907a":"doesEventExist(bytes32)","86f2e5cf":"_setHairColorValue7(uint256)","86f32586":"checkIfFundingCompleteOrExpired()","86f328a9":"episodes(uint256)","86f35b7c":"FeeCalculation()","86f3c026":"UpdateMoney(address)","86f3d0cd":"limitedDeposit()","86f5114e":"voteName()","86f5bf88":"interestPermil()","86f6e410":"adminIsAdmin()","86f7313d":"ico_enddate()","86f7993e":"acceptCooOwnership()","86f79edb":"getMessage(uint256)","86f822fa":"DunkPayToken()","86f876e2":"hyperEnable(address,bool)","86f8950a":"getUnclaimedBalance(address)","86f8bce9":"tixFundDeposit()","86f8e4ef":"mintFinalize(address,uint256)","86fa0671":"tokenShareShow(address)","86fa18df":"throwsWhenTransferingFundsDuringSale()","86fb8715":"ArbitratedBuyDeposit(address,string)","86fbb494":"DigixbotConfiguration()","86fbeb8c":"investors(uint16)","86ffe00f":"preSaleMaxTokens()","87000d42":"clearBetMap()","8700522a":"setLandProductionMultiplierCCUser(bytes32,address)","8700ceb2":"sellCertainOrder(uint256,uint256,uint256)","87011092":"refundContributor()","8701a2f0":"finishBet()","8702735c":"setCapitol(uint256,uint256)","8703b7d8":"setPOOL_edit_4(string)","8703e506":"stage4Bonus()","87040a86":"AddHOLDer(address)","87045369":"setCanCall(address,address,bytes4,bool)","870488f9":"sendTokensToInvestors(address,uint256)","8704c6ac":"MAXIMUM_CONTRIBUTION_LIMITED_PERIOD_USD()","87055008":"euroLock()","8705ae63":"migrationChain(uint256)","8705f218":"RemoveOwnerAddress(address,address)","8705fcd4":"setFeeAddress(address)","87067595":"MagicToken(uint256,string,string)","8706ab57":"setE4RowPartner(address)","8706b052":"PGD()","8707ee3e":"formatDate(uint256)","8708b5b2":"sourcePrice()","870911ff":"onExchangeTokenToEther(address,uint256,uint256)","87092940":"calculateInterest(address,address)","8709bece":"availablePrivateICO()","870b399a":"LOCKUP_6M_ICO_TIMESTAMP()","870b8b94":"hasFiveYearWithdraw()","870baf84":"sendToGiveth()","870bb8c2":"CROWD_WEEK1_PERIOD()","870bfc75":"lockMultis()","870c426d":"getUniverse()","870dbae0":"TOTAL_MAX_CAP()","870e5405":"insert(bytes32,bytes32,int256)","870f0e27":"developmentLockEndTime()","870f892d":"getGTOAddress()","8710296f":"totalEarlyPurchaseRaised()","871105cc":"setVaultContractAddress(address)","871113c3":"oraclize_query(string,string[1],uint256)","87113b88":"managerListMap(uint256)","87114b8c":"versionInfo(uint256)","8711e4a9":"lockTimeout()","8712523e":"lastTransferBlock(address)","87127f85":"ZeonToken()","8712c1c5":"freeTotal()","87136940":"tokenRateInUsdCents()","871388c9":"SetGene(uint256,bool,uint64)","8713d931":"BONUS_100_250()","8714b028":"offers(uint256,uint256,uint256)","8715d65d":"TierWildcatDividendAddress(address)","87161e59":"commandGetBonus()","871625e2":"retraitStandard_2()","871745aa":"presaleAddTree(address,address)","87174c3e":"refundManager()","87178668":"RATE_DAY_14()","8717ef27":"setVotingParams(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","87182d47":"totalSecondICOSupply()","87191e41":"isWhalePaying()","87195d23":"getInstallments(bytes32)","87196863":"_lower(bytes1)","8719715e":"walletAvatar()","8719e8ac":"setStatus(uint256,bool)","871b4e3c":"getCardBuyAuction(uint256)","871c7aab":"total_freeze_term()","871caa98":"dataOf(uint256)","871cc9d4":"decrementNumber()","871ced4a":"HeartBoutToken()","871cf692":"pullEtherFromContractAfterPreICOPrivate()","871d3eab":"addExtraDays(uint256)","871da475":"GetSellPrice()","871e0155":"pushNodeGroup(uint256,uint16)","871e5fac":"contributorsCurrentPeriod()","871fe6e1":"_validateHardCap(uint256)","872053e6":"releaseThisBonuses()","8720bb42":"liantoken()","87210f63":"tokenMainSale()","87214728":"contractIsCanceled(string)","8721db89":"requireKyc(address[])","8722860e":"isThereAnOnGoingProposal()","8722d4d9":"enforceAddressMatch()","8723202e":"NewSmartSharingContract(string,uint256,uint256,string,string,string)","8724025e":"AENIGMAZ()","8724e751":"Panax()","87250a35":"getSkull(uint256)","872519cd":"VerifyAccount(address,bool)","872539e7":"numberOfLeafs()","872588ba":"lock(bytes32,bytes32,bytes32)","8725d6be":"createToken(uint256,uint256,uint256,address,uint8)","872628e8":"setPriceStep2(uint256)","8726baf7":"unapproveArtist(address)","87275aba":"preMinting(uint256,uint256,uint256,uint256)","8727b7fc":"calculateAmountBonus(uint256)","87280324":"callMe(bytes32)","87281fab":"VestingReleased(uint256)","87283f0f":"ActivationRequest(address,bytes32)","87287fd7":"setMinFee(uint8)","872887c2":"getPeriodStartTimestamp(uint256)","87297093":"previousWithdrawal()","8729fff4":"buyCommission()","872a7810":"revocable()","872b31b6":"_removeStakeholder(address)","872bac57":"UpdateEmployee(address,uint32,uint32,uint16)","872bc83a":"GCCExchangeCore()","872d637f":"DivvyUp(bytes32,bytes32,uint8,uint8,uint256,uint256,uint256,address)","872dbdab":"advert_machine()","872dd49b":"getMigrateOutAttoTokens()","872dd84b":"priceBeforeGoalReached()","872f2526":"getGuestOrders(address,address)","872f5459":"toUINT120(uint256)","872fe620":"withdrawByResque()","87319e1e":"changeContractRegisterOwner(string,string,string,string,address)","8731a8d9":"deposit(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256,string)","8731cce5":"PledgePaymentCanceled(uint256)","87324ef0":"ecrecover2(bytes32,uint8,bytes32,bytes32)","8732d065":"ignoreKYCLockup()","87330b85":"getString1()","87336473":"unblockTransfer()","87338e98":"jackPotBestHash()","8733d130":"ownerManualMinter()","8733d4e8":"identityOwner(address)","8733f360":"initialize(address,address,uint256,uint256,address,address,address,address,address,address,uint256)","8734ffc9":"authorizedETH(address)","87355084":"transferCrowdsale(address,uint256)","8736381a":"contractCount()","87369c4b":"BOUNTY_EXCHANGE_SHARE()","87369e04":"refundTransactions(uint256)","8736fd16":"getRefStatus(uint256)","87393bc6":"verifyFirstHalf(uint256[4],uint256[4])","8739cacf":"getJobRating(address,uint256)","8739f930":"queryGameHistoryLength()","873a2878":"acceptWork(uint256)","873a5690":"VikkyToken()","873ab2ce":"computeFeeRate(address)","873b3009":"getKeyRevisionNumber(uint32,int256)","873bdee0":"systemWithdraw(address,uint64)","873c56d7":"officialLimit()","873cb0ab":"redeemedKarmaOf(string)","873cdb03":"Litas()","873db84c":"queryN_fnc()","873dc3b3":"bountyOnlineGW()","873dc71d":"getCycleInfo()","873ebe6a":"collect(address[],uint256[])","873f610c":"Contractors(uint256)","873f9a6a":"registerDIN(address)","87407993":"inQuitLock(address)","8740b73d":"EthereumGoldPro()","87412a4b":"TeamAndPartnerTokensAllocated(address,address)","8741ab49":"setupCompleteFlag()","8741f15e":"tileBalance()","874252ef":"giveProgectTokens(address,uint256)","8742792f":"changeNameByEveryone(string)","8742fc3b":"getVoteResult()","8744e974":"CallOption(address,uint256,uint256,uint256,uint256,uint256)","87451d52":"addQuickPromoBonus()","8745ddb3":"jailAmountOf(address)","8746656f":"extendDuration(uint256)","874752b4":"SpiceMembers()","8747a674":"getWrapperBalance()","8747f9b1":"resultReject()","8748ecda":"Dynamic1_5x(uint256)","87491c60":"closeMinting()","874a7036":"placeNotes(uint256[],uint256[],uint256)","874b4fcc":"setSigningPublicKey(string)","874b953a":"changePrimaryApprovedWallet(address)","874d6d81":"getWeek()","874d73a7":"addLottery(string,uint32,uint32,uint32,uint32,uint32,uint32)","874f33a1":"doStuff()","874f874c":"reminderCalc(uint256,uint256)","874f8ef6":"getAdv(uint256,uint256)","874fe370":"finalizeTS()","874ff7ed":"YOYOW(address)","8750367e":"FundRequestPublicSeed(uint256,uint256,address)","8750c2d7":"priceInTokens()","8751775b":"cancelRewardsWithdrawal()","87521056":"createMineForToken(uint256,uint256,uint256,uint256)","87524581":"accounts(address,uint256)","87526b0a":"totalPendingPayments()","87528d5e":"setInitAttr(address[],uint256,uint256)","87529f0f":"getTeam(address)","8752cff2":"isUserExisted(address)","8753b16e":"requestOwnership(address)","87541c9e":"setLLV_edit_3(string)","87543ef6":"upgradeController()","87548fcf":"getTracks()","8754b1d1":"createPainting(address,uint256,uint256,uint8,uint8,uint256,uint256)","8754b29c":"buyCore(address,address,uint256)","87551db0":"getChecksum(string,string,string)","8755b065":"initialTransfers(address[],uint256[])","875606a1":"freezeTransfer()","8756f3e7":"LogErrorMsg(uint256,string)","8757a2cd":"test_depth(uint256,uint256)","8757d620":"firstBuy(string)","87585707":"buyVouchers()","87586b32":"getPI_edit_2()","8758ba8f":"approveForGeneLab(uint256)","875991eb":"dealLog(uint256[2],bytes32,bytes32,uint8)","875999e0":"getLastKeyTime()","8759afc9":"_initStages()","8759c2f1":"getHappinessCitizens(uint256)","8759d1c3":"sendReceivedTokens(address,address,uint256)","875a8dfc":"post(address,string)","875ac8f1":"PAYOUT_DATE()","875ad967":"DopeRaiderCore()","875c330c":"LogPush(address,uint128,string)","875c7143":"setSecondYearAllowancePercentage(uint8)","875cb3e5":"closeSuccess()","875dc0ee":"changePaymentDestination(address)","875de431":"phaseOneBonusPercent()","875e7bb4":"FactoringChain(address)","875ea5e7":"dividend(uint256)","875f0671":"crowdsaleStatus()","875f71a3":"ETHDistributor()","875fde3d":"createErc20Token(string,string,uint256,uint256)","876012fc":"composeJingle(string,uint32[5],uint8[20])","87609d1a":"__price()","8760b171":"getBPhashFromBPTokenId(address,uint256)","87612102":"loadRefund()","87615cb2":"enableRegulator(address,string)","8761fb7c":"escrowAdmin()","87627869":"setCopaMarketAddress(address)","8762d50b":"_xx()","87630a2e":"activateContract(address,address)","876339b8":"_sellPutToOpen(uint256,uint256,uint256,uint256,address)","8764159e":"findContractByModName(string,string)","8764edd0":"VerificationAccountOnJullar()","876588b8":"Apply_Store_Id_Fee()","876590c3":"setTeamPrice(uint256[],uint256[],uint256)","876777d0":"TTCoin()","87679684":"checkProof(bytes,uint256,bytes,bytes)","876848d3":"valid(uint80)","876911ca":"ArrAccountIsFrozen(uint256)","8769817a":"CROWD_WEEK1_BONUS()","87699aa6":"TOKENMOM()","8769bc7e":"currentSpiderOwner()","8769beea":"openESOP(uint32,bytes)","8769c281":"allowRefunds(bool)","8769c28c":"bogotacoin()","876b0946":"NucleusVisionToken()","876b0a95":"getDiceWinAmount(uint256,uint256,bool,bool)","876b1566":"getTokenHolders()","876ba3cd":"transferModeratorship(address)","876cf0ef":"getCrystals(address)","876da006":"TOKECOIN()","876e79f6":"targetDiscountValue7()","876ee240":"EthWuxia()","876f1c27":"replaceAnimal(uint16)","876f20b1":"crownSymbol()","876f5746":"ShitcoinCash()","876f9795":"mineSalary(uint256)","877046a2":"CGCCoin()","87708311":"OBEFAC(address)","87717cb1":"_hackoinToken()","8772a23a":"configured()","8772ae3c":"setMinimumBet(uint256)","87730ed7":"allocateFundsBulk(address[],uint256[])","87734d53":"getBet(address,uint256,uint256)","8773c0d0":"buySoul(address)","8774e5d0":"setPriceInWei(uint256)","87757835":"Ducker()","8775a557":"DadaCollectible()","877653f0":"_storeBalanceRecord(address)","8778205d":"TransferDisable(uint256)","8778c090":"arrayOfNonTrivialAccounts()","87793dc7":"invokeOnceFor(address)","877aaf4f":"tosToken()","877af5b4":"subFundAccount()","877b9a67":"isIssuer(address)","877c2184":"getIntValue(string)","877c3650":"getproductprices()","877c4f6e":"submitPeriod(uint256,bytes32,bytes32)","877cedb8":"Lockup12m(address)","877d481c":"startStage3()","877ddd77":"commission_ratio()","877f5618":"isAllowClaimBeforeFinalization()","87800ce2":"MD5FromMarketingKeywords(string)","87801cc3":"setNextRoundDonation(uint256)","87804708":"_validate()","8781249f":"getCntByRarity(uint8)","8781382e":"WBU()","878170d1":"fetchValue()","878314c9":"crowdsale_eth_fund()","878377e7":"RAM_Token()","8783bf1a":"EGGS_TO_HATCH_1DRAGON()","8783d407":"feeReplyThread()","87848727":"writedb(string,string,string)","87864af8":"UNFREEZE_TEAM_BOUNTY()","87873b6d":"MoneyTreeToken()","87874e02":"getNextAvailableLevel()","87877e4d":"setSponsor(string)","8787c9ff":"approveCertificate(address,address)","8787f75d":"Kodobit()","878808af":"tokensSoldGoal()","87881ede":"getStackholderConfirmations(uint256)","8789dfbf":"instContAllocatedTokens()","878a18ef":"tokensSentDev()","878c1484":"cause()","878d4204":"testInitialCrowdsale()","878d5ff7":"partnerInfo(address,address)","878de0ae":"userEndGameConflict(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,uint256,address,bytes,bytes32)","878e10e4":"SEHR_WALLET_ADDRESS()","878e8827":"getActionParameterByIndexes(uint256,uint256)","878eb368":"cancelAuctionWhenPaused(uint256)","878eb4ca":"serviceDeposit()","878ef7fe":"RealMadrid()","87902997":"acceptAndAdditionals(bytes32,uint256[])","87903097":"timeoutPlayer(uint256,address,uint256,uint8)","879125a4":"setMaximumRate(uint256)","87914c6f":"prolongateContract()","879206a2":"lastPayerOverflow()","87924815":"ownerAddressSize()","87925132":"PandaCore()","879281c4":"login(bytes32)","87932e0f":"setAddress(bytes32,address,address)","87934ec8":"skinCreatedLimit()","8793ae52":"getCurrentDaoStakeSupply()","87943859":"getRefBonus()","879499f4":"newUriBase(string)","87950f49":"setDistributorAddress(address)","879611bb":"removeGlobalConstraintPost(int256,address,int256,address)","8796a7ba":"totalPrivateSaleStage()","8796d43d":"activeToken()","8796ec86":"getDocumentHash(uint256)","879736b2":"swapValidatorKey(address,address)","87982928":"launchPeerWallet(address[],address[],uint256[])","879844b9":"crowdsaleAddressSet()","87986f52":"getOrderSupportCancel()","879a6f7a":"recoverWarriors(uint256[],address[])","879a83fc":"LogWithdraw(uint256)","879abc11":"applyRuntimeUpdate(address,address,uint256,uint256)","879b18b6":"getMemberCanVote(address)","879bfa27":"Investors()","879cffdf":"TokenBuy(address,uint256,uint256,string)","879d46fd":"DAOTrust(address,address,bytes,uint256,uint256,uint128)","879e4b1a":"empty(bytes32)","879e84ab":"minChequeValue()","879f30ad":"burnSent(uint256)","879f4dfe":"_getCampaign(bytes32)","879f9c96":"purchased()","87a01164":"teamTransferFreeze()","87a04b67":"KUYOOToken()","87a07692":"setWinner(string,uint8)","87a07adb":"getSharedAccounByIndex(uint256)","87a09877":"AdvisorGPX(address[],uint256)","87a16f12":"addScriptExecutor(address)","87a2a9d6":"_MAXIMUM_TARGET()","87a2afb3":"releaseBets()","87a378fb":"holdSubscription(uint256)","87a3903e":"buy(uint16,uint16,uint16,uint16)","87a3be75":"init(address,uint256[],address[])","87a3e445":"icoBonus4()","87a407a1":"setBurner(address,address,bool)","87a675ca":"DataContacts(address,address,address)","87a767e3":"removeCA(address,address)","87a796a1":"_fetchCancelledOrdersForPayer(address)","87a846a5":"getBonus(uint256,uint256,uint256)","87a88c43":"iDistribution()","87a91506":"PlayChainPromo()","87a97752":"setInitialEnemyCombination(uint32[4])","87a9a8ef":"totalSupplyAtCheckpoint()","87a9be0d":"BitSelectArrojado()","87a9c6c5":"buyAndTopup(address)","87aa14d2":"freezeEventOutcome(uint256,uint256)","87aa2bf9":"rmul(uint128,uint128)","87ab42b3":"MysteriumTokenDistribution()","87adab57":"VISTAcoin()","87ae00a3":"ZebiMainCrowdsale(uint256,uint256,uint256,address,uint256,uint256,address,address,address,uint256,uint256,uint256,uint256,int256,uint256)","87ae0dbe":"yearSeconds()","87af74ab":"calculateNumberOfNeighbours(uint256,address,address)","87afe179":"getTotalTicketSetsForRound(address,uint256)","87b01dc9":"setSale(uint256,bool,uint256)","87b0be48":"releaseTokens(address)","87b0d60c":"sumICO1()","87b15c0b":"periodITO_wei()","87b234ec":"createReferralGiveAways(uint256,uint256,address)","87b261ad":"coeff()","87b2fe7f":"luckynum()","87b30845":"exchangeDIDForEther(uint256)","87b3be7d":"Ring()","87b47e4f":"transSupply()","87b4e60a":"newTokens()","87b547e5":"balanceOfDirectoryToken(uint256)","87b551b5":"tokenPayout()","87b55705":"mintingThreshold()","87b57fa7":"GetMinerRigsCount(address,uint256)","87b5914c":"exchangeRateETHToUSD()","87b5c21f":"OCTWasteToEnergyJV()","87b5f114":"xpTokenAddress()","87b73795":"verifyKYC(address,address)","87b751ae":"TokenTrader(address,uint256,uint256,uint256,bool,bool)","87b7a068":"updatesAreAllowed()","87b8963c":"badgeDecimals()","87b9a544":"DataController(address)","87b9e310":"nominPool()","87ba67be":"nextLevelPercent()","87ba67dd":"Arascacoin()","87bb25b5":"UndermineComponent(uint256,address,uint256)","87bb675c":"indexTracker()","87bb6aa6":"_revealBid(bytes32,address,uint256,address,address,bytes32,uint256,uint256)","87bb7ae0":"getTicketPrice()","87bc0fc6":"TokenAirdrop(address,uint256)","87bc6906":"BitGuildTrade()","87bd499b":"lastLevelChangeBlock()","87be727b":"getSum(uint16)","87bea35f":"getCreatePrice(uint16,uint256)","87bf740b":"YYToken(uint256,string,uint8,string)","87bfce9e":"claimedYesterday()","87c00626":"calcTokensToEthers(uint256)","87c05510":"setNewlockAccount(address,uint256,uint256)","87c19bcb":"votelog(bool,address,uint256)","87c1be6e":"globalPause(bool)","87c1ed12":"transferToOwner(uint256)","87c23143":"totalEthBankrollCollected()","87c2ee62":"secondStageEndsAt()","87c38114":"Emojicoin()","87c4aaea":"totalTokenVested()","87c50df5":"erectBarrier(uint16,uint8,uint8)","87c55589":"blockTube(uint256,string,uint8,string)","87c5d1be":"LEDTEAM_TOKENS()","87c70d21":"expressReloadNums(uint256,uint256,uint256[])","87c79d1d":"getColors()","87c84933":"LogParticipation(address,uint256)","87c86277":"setPetName(string,uint64)","87c8ab7a":"changeAllowance(address,address,uint256)","87c95058":"setAdministrator(address,bool)","87cb15f7":"move(uint256)","87cc1e1c":"setExporterBank()","87ccb440":"getReg2()","87ccb57b":"testExecuteSellOrderShouldNotChangeBuyerBalance()","87ccccb3":"PublicMine()","87ccd8b3":"_isComplete(uint256)","87cef144":"updateVIPs(address)","87ceff09":"getBlockTime()","87cf34cf":"getUserContributionReclaimStatus(address)","87cf7768":"walletG()","87cfc1d8":"disableAgency(address)","87d14a36":"MaxPlayers()","87d25299":"tessrX()","87d2544d":"CMOSignature()","87d3525f":"CancelSimpleOffer_internal(uint256,bool)","87d36176":"False()","87d3764b":"ROLE_LEVEL_PROVIDER()","87d3a184":"makeZero(uint256)","87d4ca93":"escrowFrom(address,address,uint256)","87d517c9":"fetchInitialDetails(string)","87d5418f":"aSetEnd(uint256)","87d570c0":"OHGRiverResort()","87d5c6b8":"rentalElapsedTime()","87d67208":"changeIcoStartBlock(uint256)","87d741c9":"getPaidETHBack()","87d76f09":"calculateEstimateToken(uint256)","87d79f8a":"buyIceDrangon()","87d7d24d":"ownerconfirm()","87d803a3":"setResult(uint8,uint8,int8)","87d81789":"payments(uint256)","87d87090":"setMinRefEthPurchase(uint256)","87d9d224":"TokenDistribution(uint256,uint256,uint256,int256)","87da18ee":"getRankPriceEth(uint256)","87da3208":"CollateralToken(string,string,uint256,uint8)","87da9cad":"ApprovalToken(address,address,uint256)","87db03b7":"add(int256)","87dba600":"_set6()","87dc0c55":"getAuctionEnd()","87dcd2b6":"superOwner()","87dcfd2d":"numTokensLeft()","87ddc521":"rewardController(address,bytes5)","87dde4ad":"get_candidate(uint8)","87ddf6cd":"setAddressArrayIndex(bytes32,uint256,address)","87def081":"getFeeRecipient(int256)","87df4838":"CancelSell(uint256)","87dfc909":"queryMap(uint8,int256[],int256[])","87e06546":"PLATINUM_AMOUNT_XPER()","87e0f794":"TwistoToken()","87e1029a":"newStar(uint8,uint8,uint256)","87e12235":"_filiate()","87e19cc5":"EBETCrowdsale()","87e25e0e":"deleteCertificator(address)","87e412f4":"SecurityDeposit(address)","87e42622":"KONSTANTOR()","87e44935":"IDOToken()","87e46baf":"transferVoxel(address,uint8,uint8,uint8)","87e4e64d":"getBalanceMy()","87e6835f":"tokensDrukker(address,uint256)","87e70933":"VoteMusic(uint256,address)","87e7dc5f":"ICOStarted(uint256,uint256,uint256,uint256,uint256)","87e854d3":"addRate(address,uint8)","87e89845":"getBabyMommas(uint256)","87e8a980":"godChangeGod(address)","87e97e82":"AuctionStarted(bytes32,uint256)","87ea8581":"setTemp(uint40)","87ea8893":"PGGameToken()","87ea9d52":"INK()","87eba3c7":"GetBuyingTokenAddress()","87ebd76c":"initContract(string,string,uint256,uint256)","87ecaf0d":"check2(uint256,uint256)","87ed1bd0":"grantAccess(address,uint8)","87ed5112":"setApoderadoVerify(bytes32)","87ed90ba":"securityWallet()","87edb2f5":"decode(bytes,uint256,uint256,uint256,uint256,uint256)","87ede474":"MicinRasaJamur()","87eeddf8":"confirmAndExecuteWithdrawal()","87efeeb6":"singularDTVToken()","87f06ec0":"getForkDurationSeconds()","87f0b8c5":"getStrong(address)","87f0bf31":"addResources(address[],bytes4[])","87f0fae9":"setKingdomFactory()","87f162c8":"initialEBETSupply()","87f1e7f3":"c_softCapUsd()","87f24484":"hashPass()","87f29fdd":"removeDiscountPhase(uint256)","87f3e5d6":"contributorsOfCauldron(uint8)","87f404cd":"getContractRhemBalance()","87f40ba4":"supplyReserveVal()","87f503fd":"DEV_TEAM()","87f51ac2":"athToken()","87f5c846":"ethBalanceOfNoFee(address)","87f6be15":"houseCredits(address)","87f74e7c":"updCouponBonusConsumed(string,bool)","87f7cab9":"removePerson(bytes32)","87f7e2a1":"getTeamCost(uint256)","87f9534b":"getLinkedIn()","87fc00f7":"setTPTContractAddress(address)","87fcd708":"StartICO(uint256)","87fcdbc1":"updateConversionRate(uint256)","87fd0421":"TheEthereumLottery()","87fdc401":"make(address,uint256,bytes)","87feba8f":"getInstallmentDuration(uint256)","87fef15b":"purchase(bytes32,bytes32,bytes32)","87ffe5a7":"dataSourceGetRedCards()","8800052e":"preSaleTokensLeftForSale()","88016da5":"allocateFrom(address,address,uint256)","88017e05":"setContribution(uint256)","8801b4fc":"paused_()","8801c928":"createJob(bytes32,uint256)","88026706":"Template()","88034bc5":"CreateTIX(address,uint256)","88037e1c":"view_get_gameData()","88046818":"getFeeSharingWallets()","8804863f":"payWithToken(uint256,address,address)","8804d119":"sendNextRewardTo(address)","88053eef":"RebuyInformEvent(address,uint256)","88054039":"NordstromOnlineRetailDigitalCoin()","880613ee":"getMadeTXCount()","88064637":"registerAssetDetail(int256,string,string,string,string,string,string,int256)","88064b07":"setNextLotteryTTMTokenId10(uint64)","88065236":"approvedAmount(uint256,address)","88072700":"itemIndexToApproved(uint256)","8807592c":"_calculateCommission(uint256)","8807a110":"isCrowdsaleClosed()","8807a468":"getOrgByIndex(string,uint256)","8807f36e":"lastInitializedRound()","88088a54":"getTransformState()","8808f3d0":"canPledge(uint256,uint256)","8809540d":"globalReinitialization()","8809716c":"setDungeonDifficulty(uint256)","880a0664":"getRoundFinish(uint32)","880ad0af":"transferOwnership()","880ade5b":"foundNewGamblingParty(uint256,uint256,uint256,uint256,uint256,uint256)","880b36e7":"getLastCaller()","880b844f":"getRoundWeight(uint256,uint256)","880c0b9d":"lpAskPrice()","880c5f3d":"EtherBTC()","880c7864":"ResearchGroupAddr()","880cab29":"Founder2()","880cdc31":"updateOwner(address)","880dc4e6":"isWithdrawEnabled()","880e73a3":"OTA()","880e87ed":"setUnlimitedMode(bool,address)","880ead7e":"returnOtherCrypto(address)","880fc14c":"inRate()","88102583":"safeCastSigned(uint256)","881056ba":"GMR_TOKEN_SALE_CAP()","8810ac6c":"BuyCarFailed(address,uint256,uint256)","8810c990":"sha3(string)","88116d13":"checkReferalLink(uint256)","8811a0ae":"addressCount(address)","8811e191":"setDebugMode(bool)","8812e897":"getCurrentBonus(address)","8812ec52":"adviserWallet()","8813304b":"forwardOnBehalfWithRevert(address,uint256,bytes,uint256,uint8,bytes32,bytes32)","881362b4":"changeUserInfo(bytes32)","881461be":"burnAddress(address)","88149fb9":"beginTime()","8814fa3f":"Log0(string)","88157942":"icoStartP3()","8815ee86":"purchaserList(uint256)","8815f3d3":"judgement(bool)","8817a198":"priceToBuyInFinney()","8817ecde":"_getPeriodFor(uint256)","88180ff6":"underwrite(address,uint256)","88185aad":"airDropTokens(address[],uint256)","8819dd8e":"getCurrentPeriodKey()","881abe3e":"addProposalVote(uint256,address)","881adeaa":"abioToken()","881b2666":"xTokenPercent_()","881be8f7":"undo()","881c255e":"updateStageBySaled()","881cfeb6":"addInternal(address,address)","881d3bd0":"LongBought(address[2],uint256[3],uint8,bytes32[3],uint256)","881dac8e":"ECHO()","881ed6db":"lockStart()","881eeaa5":"createEstateWithMetadata(int256[],int256[],address,string)","881eff1e":"setMaxBet(uint256)","881fae6c":"endSTO()","881fcab3":"getShipProductCurrentPriceByModel(uint16)","881fcefc":"updateEnabled(string)","881fd690":"isSecondStageTokensMinted()","881fe0ce":"ZealconToken()","881fe258":"_emitRecord(bytes32,uint256,uint256,uint256)","88203417":"AthleteTestToken()","8820401a":"_tokenPurchase(uint256)","8820e2d6":"newVote(address,string,uint256,uint256,uint256,uint256)","8820f6bd":"economy()","8821bb43":"change_owned(address)","8822048e":"isTransferAllowed(address)","8823a9c0":"changeFeeTake(uint256)","8823da6c":"removeAccess(address)","88254efa":"hideSubcategory(uint256)","88257016":"getNthBallot(bytes32,uint256)","882645fe":"preICObonusMultipiersInPercent(uint256)","8826ce84":"uint8ToString(uint256)","8826fa2e":"setStakedBalances(uint256,address)","88275b68":"mintLockupTokens(address,uint256,uint256)","88279320":"prizeValue()","8827a985":"durationPhaseIndex()","8829a5a7":"transferAndWriteUrl(address,uint256,string)","882a1dee":"KrisTest()","882a1fa0":"getDivCard(uint256)","882b4e68":"User_2()","882bc3e1":"RemoveAllConsentDirectives()","882d851c":"tokenMinus(address,address,uint256)","882dd41e":"updateTokenBalance(uint256)","882e2606":"icoEndLine()","882e9709":"record(string,string,string,bool,string,string,string)","882ee532":"getBylawsMilestoneMaxPostponing()","882f327b":"addLock(address)","882f3e16":"forceWithdraw(address)","882f7e83":"changeRigoblockAddress(address)","88301f57":"subDevOne()","88308ca1":"hardCapInCents()","8830a718":"BTHRTokenSale(uint256,address)","8830e09a":"ATTContribution()","88318834":"abandon()","8831e9cf":"setPlatformWallet(address)","8832243a":"profitSharing()","8832bc29":"ETH_PRICE()","8832ebe8":"lolita()","88331b6f":"amountPower()","883356d9":"isBurnable()","8833ae6f":"aquaman()","8834277e":"emitErrorCode(uint256)","8834526a":"MARKET_CAP()","883462ca":"removeFromKyc(address)","8835097d":"assignedAmountToPrivateEquityFund()","88352a29":"signedApproveAndCallHash(address,address,address,uint256,bytes,uint256,uint256)","8835ba24":"Legolas()","88362d4b":"setDailyLimit(uint256,uint256)","88369d6b":"getTokenBalance(address,address,bytes32)","8836f3ef":"getNumberOfBounties()","8838af8a":"rarityMultiplier()","8838b68e":"etherLeft()","88394fdc":"startRoundA()","8839515c":"OWN_ChangeToken(string,string,uint8)","88398fbc":"PreSaleHardCap()","883a3ea8":"LottoNumberTest()","883a584c":"RichiumToken(uint256,string,string)","883a6476":"IsAirDropEnabled()","883a92e1":"setFreezeEndTime(uint256,uint256)","883ba26b":"getIsSettled()","883ba466":"changeHiddenOwnership(address)","883cd1a5":"cloudsPerEth()","883cdeb9":"newTrack()","883cf630":"resetBucket()","883d0ac6":"totalnSupply()","883dfaba":"getWinBalancesOf(address)","883fdd6f":"IWABOO()","88400fbe":"ICO_TEAM()","884095f6":"getWineryMappingID(string,string)","8841520b":"SpinnerCountsByAddress(address)","88416792":"usersPause()","88417820":"LBSN()","884179d8":"ipfsAttributeLookup(address)","8841937a":"setTileHp(uint16,uint8,uint32)","8841ac11":"buyItem(uint256,uint256,uint256,uint256)","8841dd3c":"thirdRewardPeriodPercent()","88426aec":"getStageDeadline(uint8)","8842bfa0":"Chain4()","8843641e":"removeAmountForAddress(uint256,address)","8843c1ba":"listAcceptedTokens()","8843c222":"MIN_ACCEPTED_AMOUNT_FINNEY()","8843ffba":"signup(uint256)","88445e29":"sha3(uint256)","884543c0":"TokenBought(address,uint256,uint256,uint256)","8846594b":"checkKYC(address)","8847092d":"upgradeMaterial(uint256)","884790de":"agentInvo(address)","8847df97":"ChangeEmissionRate(uint256)","88482233":"Lizambo()","884870c7":"setParameters(uint256,uint256)","884879d6":"startSecondStage()","88488c33":"finalizeTask(uint256)","8848fb0d":"addEmployerJob(address,address,uint256)","884a2308":"setCompte_5(string)","884a26da":"massBurn(uint8[],address[],uint256[])","884a47b4":"setNews(string)","884ade03":"ForceSeller(address)","884ae10b":"saleWalletAddress()","884b5dc2":"fill(uint256[])","884b850b":"BurnAssignedFees(address,address)","884bf67c":"getPrizePool()","884c1480":"LacesToken(uint256,string,string)","884c6440":"BuyItem(uint256)","884ca7b1":"getButtonPrice()","884edad9":"Withdraw(address,uint256)","884f3db0":"check_the_rule(address)","884fafcd":"totalJackpotEven()","88508a18":"getRecentPlayers()","885124c0":"Coin5941()","88516a89":"ownerFraction()","88519ea4":"availablePreICO()","8852024f":"max_TotalSupply_limit()","88524780":"saleAuctionERC20()","885349a2":"payToBank(uint256)","88535e90":"changeMinimumContributionForPublicPhase(uint256)","8853636b":"revealResult(uint256,bytes32)","885363eb":"landOf(address)","88537daf":"checkMiningAttempt(uint256,address)","88538c36":"candidateInformation(uint256)","885463fd":"strategicAllocation()","8854baa8":"AddReturnsMapping(uint256)","88550b6a":"getTokenBuyPrice()","88559aaf":"processAllocation(address,uint256)","8856cd84":"medicaxess()","8856d517":"GetReferralInfo()","8857322d":"DOLLAR_DECIMALS_MULTIPLIER()","885819c2":"getVatIdByAddress(string)","8858287b":"vendorCount()","8858ad6c":"Exploreon()","8858adc6":"setColor(uint16,uint24)","8858fa3b":"totalEthReceivedInWei()","8859c6d6":"operatorCampaignID(address,uint256)","885a3b75":"currentTotalSupply2()","885a5ec2":"lastBlock_f10()","885b63da":"setAuctionStartBid(uint256)","885b6cfb":"addZethrAddress(address)","885c69b5":"clearMetadata(address)","885e2750":"groupsCount()","885e401e":"lifeFactor_i()","885ec18e":"left6(uint256)","885f5011":"calcRatioNext()","8860805a":"extractMax()","8860bf94":"showworker()","8860d49f":"_transferInternal(string,address,string,address,string,uint256,uint256)","8861026f":"complianceWallet()","8862198a":"MasterContract(address)","8862d26a":"offeringType()","88631e18":"distribute(address,uint256,uint256,address[],address,uint256[])","88635b06":"createContractPerson(string,uint256,address)","8863c8d5":"concludeCrowdsale()","8863dd1a":"transferOwnerShip(address)","8863f31d":"Controller(address,address,address)","8864a5fd":"processPendingTickets()","8864d074":"RADCOIN()","8865015d":"g(uint256[20])","886588ac":"confirmVerbose(bytes32,address,uint256,bytes)","8865cbd6":"cancelAllOrdersByTradingPair(address,address,uint256)","88668d21":"getReplyRaw(bytes32,uint256)","88671acc":"FundAllocation()","88672f82":"setEtherRate(uint256)","88684aa5":"nextUnLockTime()","88685cd9":"releasePayment(uint256)","886b148d":"setPropertyPrivateModeEarnUntilLastUpdateBecomePublic(uint16,bool,uint256,uint256,uint256)","886b4954":"secToNextInterestPayout()","886bb359":"chown(address)","886bbe0c":"submitProof(bytes32,bytes32,uint256[],bytes,uint256)","886c0ee6":"Develop()","886d3db9":"uintToBytes32(uint256)","886d969b":"calc_partnerPercent(uint256)","886db803":"_setBigWinner(address,uint256,uint256)","886e549b":"PineappleArcadeTrophy(uint256)","886ed2d1":"enableRealWorldPlayerMinting(uint128[],bool[])","886ef644":"getRate(address,uint256)","8870155c":"getNumTknOfferors()","88702cc4":"debug_hash256Double(bytes)","88705f7d":"NeoCrowdsale(uint256,uint256)","8870985b":"getFreeBalance(address)","887159a2":"treatRemaintoken()","887240d0":"generateFileID(string,string,string,string)","887263cf":"EnigmaToken()","88727ba9":"_depositEthers(address)","8872bb2a":"_createElement(bytes32,uint256)","8872c094":"getUnsoldToken()","8872c68a":"sampleStorage()","8873704c":"addRequest(string,address)","8873d247":"THANKSTEST()","8874fa28":"CurrentRevision()","88753343":"maxResolvedAgonId()","88758581":"unregisterEmployee(address,address)","8875a40b":"endTimeTLP2()","88760a18":"loadStarbaseEarlyPurchases(address)","887651cc":"isAlreadyIn()","887699f3":"periodContributionOf(uint256)","88770cb0":"extendEndTime(uint256)","88776a7e":"testThrowTranferFromEmptyBalance()","88780b8e":"safeBalance()","88782386":"UnicornMilk()","8878356d":"testBetAmount()","88786272":"startingTimestamp()","8878990e":"changeCollateralSeizer(address)","8878adac":"refund_claims(string)","8878d726":"buySpecialBuilding(uint256,uint256,uint256)","8878db7f":"setCRYPTON_CUT(uint16)","887a8e33":"AgencyLock1()","887b00db":"TESTTESTICO(address,address,address,address)","887b1b0b":"recalculateTokensToBuyAfterSale(uint256,uint256[])","887bae74":"addReferenceParentWineryOperation(string,uint256,string,address,int256)","887bbef5":"setMinInvestment(uint256,uint256)","887bdcfc":"accountBalance(address,address)","887c3e5d":"updateAddress(bytes32,address,address)","887c4646":"approveIndexedByAddress(address,address,uint256)","887c4f68":"ludumTokensPerEther()","887c7f92":"remainingReserveSupply()","887ccc82":"getStake(uint256,uint256,address,bytes32)","887cfc3e":"orderToTransfer(address,address,address,uint256,string)","887d23a6":"isBeforeEndTime()","887d813d":"serviceGroupGet(address)","887e0c07":"runPlugin(address,uint40,uint256)","887e22b1":"tier5Time()","887f6178":"genericTransfer(address,uint256,bytes)","887ffc9c":"referalPayByNum(address,uint32)","88806b37":"transferZone(uint256,address)","8880a933":"transferTokensToNonEthBuyerToMany(address[],uint256[])","8881d3a2":"CompensationFailEvent(address,uint256)","8882349b":"vppToken()","88824bd1":"PonziUnlimited()","88827c16":"addPost(bytes32)","8882ddc9":"maxCharacters()","8883478e":"preicoAndAdvisors()","8883c52a":"getNumberOfAssetPacks()","88840671":"Milkcoin()","888419ed":"setData_8(string)","88849e71":"BasketToken(address[],uint256[],uint256)","8884b807":"getVoters(uint256,uint256)","8884cd7c":"changeBuyFlag(bool)","8884fbec":"checkTotalsAndMintTokens(address,uint256,bool)","8885f2a3":"setzBool(bool)","88865347":"grapesToBuildWinery()","88865ee3":"cleanupEven()","8886a667":"registerNameXIDFromDapp(address,bytes32,bool)","8886ca33":"getHeroBP(uint256)","88873eea":"blocktubeClip(string,uint256,uint256,address)","888764c8":"addBouncer(address)","888808ba":"Bittelux()","88888f61":"purchase(uint256,bytes32)","8889025a":"increaseJackpotTimeAfterBet()","88896a0d":"deliverPrize(address,bytes)","88897c37":"request_close()","888a3f79":"_approvedFor(bytes32,uint256)","888aab22":"addWithdrawal(address,uint256,uint256,uint256)","888ade0a":"publicKey(address)","888b6557":"minFundingGoalWei()","888d5917":"limitDateCrowdWave2()","888ea120":"saleDeadline()","888f2b13":"SALE_RATE()","88908546":"refund_eth_value()","889087b1":"meltCrystals(uint256[])","8890e13d":"isArenaContract()","88922e7a":"raiseAppeal()","889231c1":"promoLimit()","889258ea":"startICOStage1()","88929931":"UnlockDateExtended(uint256)","8892bb73":"createChildUniverse(bytes32,uint256[],bool)","8892d571":"withdraw_Leim(uint256)","8893240d":"setPeonyAddress(address)","88933e07":"getSMPTokensLeftForICO()","8893eb13":"getActivated()","88945187":"updatePurchasingState(address,uint256)","8894dd2b":"addEther()","88951352":"distributeTokens(address[])","889569cd":"getKoikeContract()","88968b94":"rateOwner(uint256)","88968bc3":"clearKyc(address[])","8897b1a7":"PRESALE_HARDCAP()","8897c1f4":"randomNumber(uint256,uint256,uint256,uint256,uint256,bytes32)","8897df9d":"addEpisode()","8899568c":"createDefaultZodiac(uint256,uint256,uint256,address,uint256,uint256)","8899fa0d":"onUnVote(address,int256)","8899fffd":"myFinneyValue()","889b59d9":"getDBallotsN(bytes32)","889c10dc":"addDelegate(address,address,bytes32,address,uint256)","889cd532":"upsertOne(address,uint256,bool,bool,uint256)","889d227d":"newPaymentAddress(address,bytes4)","889d9550":"getCryptoCupTokenContractAddress()","889e175e":"__slash__(address)","889e5073":"getStatus(address,address)","889eaa0d":"nextRate(uint256)","889f0c99":"withdrawFor_(address)","889fa1dc":"getFighter(uint256)","889fb53e":"incrementCoin(address,uint256,bool)","88a0e990":"BridgeTheChain()","88a12f7a":"_getUint(bytes4)","88a15f11":"secondMaxAmount()","88a17bde":"allocation()","88a1e895":"test2Fails()","88a2653c":"unwhitelistAddresses(address[])","88a2995d":"MyToken(uint256,uint256,string,string,uint256)","88a49164":"testErrorUnauthorizedTransfer()","88a4e86c":"balanceOfRaw()","88a525c4":"withdrawTokenBalance(uint256)","88a55c8b":"setBustRange(uint256)","88a6c749":"getFirstTranscoderInPool()","88a6cc53":"lockPurchasedTokensClaim(uint256)","88a74525":"fraction(int256,int256,int256)","88a79003":"addWhitelistInternal(address,address,bool)","88a7ca5c":"onTransferReceived(address,address,uint256,bytes)","88a89dd0":"add_to_buy_bounty()","88a8b341":"setVoteInternal(uint256,uint160,bool,bool)","88a8c95c":"changeDev(address)","88a8d602":"management()","88a95495":"removeFromMap(uint256[])","88aa1001":"checkJoinAirdropQuest(address)","88aa8bee":"getTokenDetails(address)","88aaa229":"AcceptsIDK(address)","88abc4a2":"coinIssuedPrivate()","88ac76ca":"cthereum(uint256,string,uint8,string)","88ad52f0":"DouYinToken()","88adbf8f":"addressOfTokenUsedAsReward()","88aebe00":"calculateWineBuy(uint256,uint256)","88aece7f":"setBuyOrdersContract(address)","88aed238":"ixix()","88af30c3":"_mainAddress()","88af6534":"VRF_EGG_COST()","88af883b":"adm_trasfer(address,address,uint256)","88af8ed4":"removeInvestor(bytes32)","88afdeba":"totalCreatedGame()","88afe426":"_removeAgonIdByOwner(address,uint64)","88b11ee2":"DZoneCoin(uint256,string,uint8,string)","88b2ed1a":"addPlotAndData(uint24[],string,string,uint256)","88b322c3":"setAdvisors(address)","88b3a538":"projectManagers(uint256)","88b44c85":"assertEq(uint256,uint256,string)","88b45046":"income()","88b4b861":"proposeTo(address)","88b51ac0":"gernerateVoting(uint256,uint256)","88b55641":"buyTokenIco(address,uint256)","88b59734":"vendueClosed()","88b75493":"getLastAuditAuditor(address)","88b7a17c":"functionName(bytes32)","88b7a89d":"test0_create()","88b7e6f5":"returnInt128(int128)","88b7f5e5":"advisersWallet()","88b8c487":"playerWithdraw()","88b9022f":"semanticVersion()","88b95242":"PricingEnergy(uint256)","88b9a469":"initVault(uint256)","88b9e10e":"seizeTokens(address,uint256)","88bac2b8":"Mediated_Transfer(uint256,address,address,uint256)","88bb0c73":"teamsReward()","88bb18fc":"mintDSBCToken(address,uint256)","88bb6e68":"AkershoekToken()","88bb9fb1":"MultivestSet(address)","88bc65e3":"getFreelancerAvgRating(address,address)","88bec9da":"deleteMember(uint256)","88bf60b7":"transferMinimumFee()","88bff117":"setDrop(bool,uint256,uint256)","88c058a5":"subDefence(uint256,uint256)","88c0b8a7":"setChangeFee(uint32)","88c0bc8e":"buyTokensWithReferrerAddress(address)","88c12be2":"deathData_f0()","88c190a4":"NiMingToken(uint256,string,uint8,string)","88c2a0bf":"giveBirth(uint256)","88c30278":"getMinerOffsetOf(address)","88c3ba85":"ParallelGambling()","88c3ffb0":"getRoundInfo(uint256)","88c463af":"contributorsOfCauldronRound(uint8,uint32)","88c4e888":"get_token_state()","88c55c47":"initializeVesting(address,uint256)","88c600d0":"CryptoCongress(address,uint256,uint256)","88c662aa":"getController(address)","88c6abf8":"currentIteration()","88c7b6e6":"CrowdSaleMacroansyA()","88c7e397":"buyable()","88c8475c":"batchFreezeAccount(address[],bool)","88c8da99":"deactivate_admin_comission()","88c912b8":"sendToAddressWithBonus(address,uint256,uint256)","88c91d24":"computeCooldownTime(uint128,uint256)","88c91fb1":"transferExtender(uint256)","88c9a7d5":"setPixels(uint32,uint32[],uint8[])","88c9cb3c":"timer()","88c9ebbd":"getKeyPrice(uint256)","88cac17d":"setNextLotteryTTWTokenId3(uint64)","88cb214e":"editWhitelist(address,bool)","88cb8a73":"setPixelBlockPrice(uint256,uint256,uint256)","88cbc84a":"buyInvestmentPackage(uint256)","88cbdf13":"toUint32Throw()","88cc58e4":"getFactory()","88cc81de":"PaymentExpectationCancelled(bytes8)","88cc852a":"notZero(address)","88cca295":"addressToPurchasedBlocks(address,uint256)","88ccf2b9":"SetTokenInfo(uint256,address,uint256,uint256)","88cd2d47":"UserCRUD()","88ce3048":"lastweek_winner3()","88cee87e":"adminRemoveRole(address,string)","88cf2bc6":"buyStarCoin()","88cf6648":"liquidationPriceWad()","88d0443d":"bounty_address()","88d0820e":"selfFreeze(bool,uint256)","88d0b42d":"getRecentActivity()","88d115af":"PonyCore()","88d116b8":"_createPlayer(string,uint256,address,uint256)","88d12a4d":"totalWeiReceived()","88d18ea4":"featureSprite(uint256)","88d21ff3":"pollExists(uint256)","88d2faf9":"publishMemberEvent(address,uint256)","88d450e4":"setArtistsAddressAndEnabledEdition(uint256,address,address)","88d52ef7":"poolContract()","88d60e27":"setPercentTokenAllocation(uint256,uint256,uint256)","88d695b2":"batchTransfer(address[],uint256[])","88d723ac":"TetherToken(uint256,string,string,uint256)","88d761f2":"finishMigration()","88d7cd97":"externalStorage()","88d7e087":"withdrawChi()","88d8c702":"Summary(address,uint128[])","88d8da5f":"equals(string,string)","88d937a3":"createnation(uint16[],string,uint256)","88d97c30":"getGroupPageCount(string)","88d9fc4d":"updateReserveVault(address)","88da9bfd":"getUserNumbersOnEther(uint256)","88db84bc":"getRequiredStateChanges()","88dbe7a7":"dividendBonus(address,uint256,uint256)","88dc0d49":"TRcoin()","88df13fa":"multiMint(uint256,uint256[])","88df31f0":"minDiscountEther()","88dfee60":"setOtherFounder(address,uint256)","88e01a98":"closeRound(uint256)","88e072b2":"checkTransfer(address,uint256)","88e114cc":"log_approve(address,address,uint256)","88e16190":"ItemCreatePrice()","88e2af0e":"initialBattle(uint256,uint256)","88e2ca21":"getClue4()","88e2da99":"randDelay()","88e2f29b":"updatedPrice()","88e3c5d6":"addVerifiedUser(address)","88e3cfda":"setResult(string)","88e3ffeb":"updateMinimumWeiRequired(uint256)","88e47f29":"_ChallengeSucceeded(uint256)","88e490eb":"getInfoCellBalance()","88e4b6ad":"calculatePotCut(uint256)","88e5581e":"twitterDropSingleAmount(address[],uint256)","88e62721":"revoke(address,bytes32)","88e67d96":"isAccess(address,string)","88e694aa":"MANNCOIN()","88e765ff":"maxBuyAmount()","88e814e6":"getTopPlayers()","88e85127":"ModeratorAdded(address,address,bool)","88e854e0":"SDR(uint256,string,string)","88e8e26a":"ServiceToken()","88e90253":"NewRateSet(uint256)","88e951dd":"totalContributors(uint256)","88e9d45d":"ButtonClickGameContract()","88e9fb4f":"keyEmployeesAllocatedFund()","88ea41b9":"setMinBet(uint256)","88ea70ee":"bountyTokensAddress()","88ea8ee5":"bonusCRS()","88ea8fd8":"manualUpdatePrice()","88eb615c":"LogWhiteListed(address,uint256)","88eb7af7":"_isHuman()","88eb944b":"addDedication(uint256,string)","88ebf975":"setDebt(uint256,address)","88ec6f42":"Cef()","88ec838f":"configParams()","88eccb09":"addLevel(uint256,uint256)","88ed8b36":"notRandomWithSeed(uint256,uint256)","88ede276":"hasBeenConstructed()","88ee4b2d":"_getIdIfValid(bytes32,uint256)","88eea4f3":"WhiteBitcoin()","88ef59fb":"releaseOldBalanceOf(address)","88efc97b":"activateEscapeHatch()","88efedf4":"AIRDROPS_PERIOD()","88f020bb":"drawWinner(uint8)","88f1ccf2":"cancelInvestment(address[])","88f2b12e":"SerpentHead()","88f34bc2":"depositAndVote(uint256,uint256,uint256)","88f53db1":"getDataRequest(uint256)","88f5eb36":"exchangeRateForBTC()","88f6d5a4":"constructCoinbaseTx(uint256,uint256)","88f7c6d6":"setExchangeStatus(bool,bool)","88f9ff98":"_random256()","88fabb3a":"SetMessage(string)","88fad42a":"EthereumRisen()","88fb4af0":"ShootRobinHood(uint256,string)","88fc0825":"unregisterNode(uint256)","88fc176c":"DucToken(uint256,string,uint8,string)","88fc65fb":"isTransferable(address,uint256)","88fcba88":"fundingDeadline(bytes32)","88fd0b6e":"getMembershipPrice(uint8)","88fd35e8":"setConfiguration(uint256,uint256,int256)","88fdf3d4":"setWinnerPrizes(uint32)","88fedd04":"houseProfit()","88ff2dcc":"createProject(string,address,address)","88ff9416":"initialize(address,address,address,address,address,address,address,address,uint256,uint256,uint256,uint256[])","88ffc33e":"bltMasterAcc()","88ffe867":"pledge()","89009ab0":"purchaseAd(uint256,uint256,string,string)","8901b9ae":"withdrawBalanceFromAdmin(uint256)","89020fe3":"PacifistFarmer()","89029d8c":"get_all(uint256,uint256)","89034082":"issueToken(address)","8905fd4f":"reclaimERC20(address)","89064fd2":"approveWithSender(address,address,uint256)","89065e9a":"getPlayerSpaceshipOwnerById(uint256)","89077ad2":"SharderToken()","8907e787":"isAccountWhitelisted(address)","89080102":"verifyDSHash(uint8,bytes,bytes)","8908017f":"calculatePhoenixPoolCut(uint256)","890814f8":"bountyValue(uint256,uint256)","8908e693":"setTokenCurator(address)","890a018d":"externalSales(uint8[],bytes32[],address[],uint256[],uint256[])","890a7ef7":"publish(bytes,string)","890a9917":"privateSaleMinContrAmount()","890ac366":"mintReserve()","890b2adc":"Reply(bytes32,bytes32,uint256)","890c6848":"WallCoin()","890d6908":"solve()","890e2a6b":"updInvestorPreSaleEnabled(address,bool)","890e839f":"isOnSale()","890e9d2f":"getAllowanceSpenderValue()","890ea91a":"creditsOf(uint256,address)","890eba68":"flag()","890ed1cb":"dealHouseCards()","890ede44":"TokenCoin5()","890f2168":"crowd_end_date()","8910b070":"NUC()","8910cd58":"substractLockedAmount(uint256)","89113858":"IHCToken(uint256,string,string)","8911cd9a":"silverPercentage()","8911cf0d":"unsafeResignOwnership()","8911e26b":"isUnrestricted()","89128b70":"get_submission_queue_length()","8912ab5c":"dropVotes(address[])","89135ae9":"setAdministrator(bytes32,bool)","891363a6":"lastCWCETH()","8913b809":"initPlayers(uint32,uint32)","891407c0":"purchaseTo(address,uint256)","8914f1e1":"getDepositAmountFor(address)","89158ff9":"assignDispute(string,address,string,address)","89165dcb":"changeEtherDeltaDeposit(address)","8916cbc6":"minRedeem(address,uint256,uint256)","8918485b":"setEthlanceSponsorContract(address)","8918ab1b":"Sumte()","89198fed":"fulfilled(bytes32,address)","8919e3b6":"VinzCoin(uint256,string,uint8,string)","891a2f31":"buyItem(string,uint256)","891a3e23":"gettotalEth()","891a8b85":"ethPriceInUSD()","891aab6a":"addStaffWhitelist(address[])","891acff7":"updatedPrice(string)","891c738a":"isTransPaused()","891d4fe8":"printContent()","891de9ed":"fromTLA(string)","891df671":"registeredAt(uint256)","891e6f43":"thisContract()","891e75bf":"preSaleCreated(uint256,uint256,uint256)","891f5ce5":"successfulFunding()","891fa67d":"PsyMultiSig(address[],uint256)","891fe103":"typeBuffPercentage()","89206411":"batchAttachAssets(uint256[])","8920bcf9":"mediaToken()","8921329f":"registerBlog(string)","89222698":"SetWriter(address,bool)","89224227":"haltDirectTrade()","892250a7":"commonBudgetAdress()","89225c5a":"bountyManagerAddress()","89231bcc":"getDataNum()","89233fbd":"getPlayerGuessNumbers()","892412f0":"availableInventoryOf(uint256)","89244e2a":"dateEnd()","8925d7bb":"getTotalBrags()","8925f9e9":"getWorseOrderId(bytes32)","89266fca":"tokensSoldOnPublicRound()","8926f723":"GMBCToken()","89273f15":"addStorage(string)","89281963":"setServicestationAddress(address,address)","89286abd":"freezeAccountTransfers(address)","892886e1":"PresaleTokenPurchase(address,address,uint256,uint256)","89291b05":"updateSubscription(address,bool,uint256)","892a0e42":"releaseToSeller()","892ad596":"changeTimes(uint256,uint256,uint256,uint256)","892c0214":"NumberOfCurrentBlockMiners()","892cd384":"CreditHydraToken()","892d31e8":"setEndCloseSale(uint256)","892db057":"isTokenEscapable(address)","892dfdf6":"transferDisabled()","892e0614":"distributeDivs(uint256)","892e243a":"directorName()","892e3f98":"setContributionInWei(uint256)","892e8dd9":"getViewDataByIndex(uint256)","892ee1a2":"removeUserFromBlacklist(address)","892ef672":"getACLRole8972381298910001230()","892f81df":"initializeTreasure(uint256)","89301afc":"Registrator()","8930c702":"updateWhitelist(address,address,uint8)","89311e6f":"startIco()","8931c998":"calculateTokenPresale(uint256,uint256)","89320239":"WHP()","89320771":"FDC(address,string)","89325127":"test_require()","89327ad5":"transfer_single_token_balances(address)","8932da79":"additional_price_money()","8932dc3d":"publishResult(string,string)","893372ca":"cancelPending(bytes32)","89337e84":"createTokens(bytes32[])","89341f6e":"TCASH()","89349217":"GamersCoin()","8934d115":"verifyUrl(string,string)","8935556d":"setDividends(uint256)","8935860d":"transferAgent(address)","8935b613":"setContentsManager(address)","8935ced5":"weightOf(uint256,address)","8936b8d4":"getCurrentRateInCents()","8937a0e8":"Guestbook()","8937d3dd":"Champion()","8937e223":"distoryAndSend(address)","8938656b":"getGeneratorsIds()","893880b6":"purchaseShareContract(address)","8939f5f6":"recoverCat(uint256)","893ae703":"bonusInPhase4()","893b746a":"cooperateRewardSupply()","893b8b0a":"getCategoricalMarketNumTicks(uint256)","893c1d31":"bountyReserveTokensDistributed()","893cebb3":"createSalesOffer(bytes32,address,uint256,bool)","893cf478":"chargeVerificationFee(address,address)","893d20e8":"getOwner()","893d4948":"JTEToken()","893fb18e":"buyout(uint256,bool,uint256,uint256)","89400fcc":"SkillCoin()","89402a72":"__default__()","8940aebe":"publicKey(uint256)","8940afe7":"testFailBurnGuyNoAuth()","8941db65":"addTime()","894306d5":"CanChange()","89443aac":"bttsVersion()","89452488":"NEBC(uint256,string,string)","8945a8af":"TOKEN_RESERVE1_CAP()","8945b1fc":"takeOwnership(string)","8945d643":"m_softCap()","8945e00d":"getForkCalled()","89462c38":"setContract2(address)","89465d2e":"dataForWithdraw(address)","8946d33f":"SplitterEthToEtc()","89473a0e":"PRCT100_D_TEAM()","89476069":"withdrawToken(address)","894766dd":"setTotalCoins(uint32)","89483926":"checkGainsToReceive()","894875cf":"_decimals18()","8948fe67":"wlDuration()","89495172":"convictFinal(uint256,uint256)","8949e109":"curReward()","894a62b3":"addContributionList(bytes10,string)","894a93e2":"tgeSettingsPartInvestorIncreasePerStage()","894b8d2e":"victorieumStatic1Token()","894ba833":"disableContract()","894ca160":"CanToken()","894cd9b6":"placeBuy(address,uint256,uint256)","894cdcc1":"ADXToken(address,address,uint256,uint256,uint256,address,uint256,address,uint256,address,uint256)","894d05b5":"buy_drink(uint256,uint256)","894d6ef9":"TripCoinTeamAddress()","894d7b08":"claimTokenBonus(address)","894e036d":"callAndReward_2(string,string,uint256)","894e5e1f":"GEE()","894e5f2d":"isUserAuthorized(address)","894ee6d9":"_getTimeValue(address,address)","894f6531":"SingleTokenLocker(address)","894fefeb":"TokenHeld()","89506a44":"MAX_TRANCHES()","89514f6e":"setSummary(string)","89519c50":"refundTokens(address,address,uint256)","895224db":"testControlBlobStoreNotRegistered()","89523d77":"removeProperty(bytes32)","895274bb":"getPlayerSpaceshipBattleLevelById(uint256)","8952877b":"storeProof(bytes32)","8952f965":"isTransferConfirmed(uint256)","8954f5b1":"winChoice()","895594f6":"setEarlyParticipantWhitelist(address,bool,uint256,uint256)","895595d5":"firstRoundICODiscount()","8955ed7e":"claimBalanceOwnership()","895678a2":"expireDelay()","89568a13":"TSTEST1()","895693a9":"getToBalance()","8956fceb":"addAlt(address,uint256,uint256)","89574144":"GXESwapper()","89578145":"checkIfYearHasPassed()","8957d6f2":"numOfLegendary()","8957f8bf":"getLastMoveTime(uint16)","89596409":"getMigrateState()","89597595":"HCLCToken(uint256,string,string)","8959cbfe":"punksOfferedForSale()","895a8cfb":"secondWeekMainICOBonusEstimate()","895ab68c":"canCallDefault(address)","895abac9":"landPriceCandy()","895b4da7":"RunSale()","895bf2e1":"tickets10price()","895c1596":"getExpectedTotalTokens()","895c1bdb":"setStatus(address,address,uint8)","895c4c39":"unlockDevSupply()","895c666a":"createCommonPlayer()","895cf354":"validCertificators(address)","895d4e1b":"getMiningDetail(uint256)","895e8b23":"_tokenExists(uint256)","895ec54c":"getPack(uint256)","895ee30d":"Purchase(address,address)","895f468b":"markAllRead()","89604ed0":"rebalance_delete(uint256,bool)","89611d0a":"checkIfSignedBy(bytes32,address)","89612f95":"setPrivateSaleTokensSold(uint256)","896131ca":"NewEntry(address)","896147e1":"ratePre()","8962aead":"setPOOL_edit_23(string)","896317b8":"getAssetType()","89637214":"presalePiTokensLimit()","896372b4":"addLogBlock(uint256,uint256,uint256,string)","89638de3":"setItemNotForSale(uint256)","8963c04b":"tokenSaleTokenBalance()","8963dab4":"getNodeId(bytes,bytes)","89658163":"setPath(uint256,uint256,bytes,bytes)","8966321e":"canTransfer(address,address,uint256,bool)","89666fd6":"adminSetPercentInvite(uint256,uint256)","8966768f":"confirmOracle(address,uint256)","89668a39":"addOpenRoomCount(address)","89675cac":"set(address,address)","89676b27":"storePrizeMoney()","89685242":"isValidPeriod(uint256)","8968c17c":"BlockchainCutiesCore()","8968db88":"GazeCoin()","89698f02":"recordContract()","8969fb5f":"USDETHRATE()","896a17a4":"releaseRestBalanceAndSend(address)","896ca3f4":"put_purchase_for(uint256,address,address,uint256,uint256,uint256,address,bytes)","896ce019":"getDailyTransactionVolumeSending()","896d505a":"setReport(uint256,bytes)","896d807a":"setAttribute(bytes32,string,uint256)","896e0349":"TokensClaimed(address,uint256)","896ed75a":"refuseAddress(address)","896f40dd":"ownerOnly()","897032e3":"ClipToken()","8970430e":"IcoContributed(address,uint256,uint256)","8970a0f4":"getFinalPayoutDistributionHash()","8970d84c":"_tokens()","89712af3":"longTermHolding()","8971739b":"getVIPCount()","8972feba":"reserveTokensGroup(address[],uint256[])","8973123c":"saleStartDate()","8973d0cf":"CoinwareToken()","8973e316":"resolveSellCityForEther(uint16)","8974372d":"payFund()","897463aa":"startContribution()","89749adb":"BuyTokens(uint256)","8975e45f":"currentNumberOfUnits()","89760e0a":"stateIndexToOwner(uint256)","89765328":"totalInvestmentOf(address)","8976762d":"setA_Signature(uint256)","8977f909":"UTCStart()","89781912":"setAllowedAddresses(address,bool)","8978fc79":"batchDistributeFees(uint256,uint256[])","89790192":"WithFee(address,uint256)","897a7dab":"createTokens(uint256[],address[],bytes32[],uint256[],uint256[],bytes32[])","897b0637":"setMinAmount(uint256)","897c41dd":"showInvestorVaultFull(address)","897c8613":"payContributorByAdress(address)","897cb036":"softCapTokens()","897cceee":"lockContract(bool)","897d2b10":"getPixelArray()","897d55cd":"migrationGetBoard(bytes32)","897e47f5":"setDateMainEnd(uint256)","89800cc2":"mtrContractAddress()","89804ddc":"getSagaExchanger()","89805f30":"s32(bytes1)","89805fc6":"PPCContract()","8980f11f":"recoverERC20(address,uint256)","89813984":"isWhitelistAddressListed(address)","8981a7ca":"actionA(uint256)","8981d077":"lockForWork(address,address,uint256)","8981d513":"owner(bytes12)","89826963":"changeICOStartTime(uint256)","8982b185":"buySEKU(uint256,uint256)","8982d772":"submitInitialEmptyState(bytes32,uint64,uint256[2],bytes32,bytes32,uint8)","898366d7":"ETH888CrowdsaleS2(address,address)","8983d2e9":"goldSymbol()","8984034f":"emitPriceUpdated(uint256,uint256)","898403c3":"getCurrentBlockTime()","8984e5dd":"_subBalance(address,uint256,address)","89850fae":"nextStep(uint256)","89852db2":"PARSEC_CREDITS_MINIMAL_AMOUNT()","89853691":"readUint256(bytes32)","89859b50":"updateLatestTree(bytes32)","8985a309":"setAllowedAddress(address,address)","8985abc8":"publicSaleAmount()","898644cc":"getFreeMiner(address)","89864915":"TyzonSupply()","89869163":"claimFailedConsensus(address)","8986ff32":"setEndTimeIcoStage3(uint256)","898855ed":"changeName(bytes32)","89885a59":"tokenOwnerOf(uint256)","8988b284":"isMod(address)","8988c1ff":"LogWhitelistUpdated(address)","8988d59e":"Transfer(address,address,uint256,address,bytes,bytes)","89895d53":"orderBlockNumber(bytes32)","89897104":"_buyRank(address,uint256)","8989851c":"operationList(uint256)","898a1813":"expectationsLeft()","898aa23b":"setPriceInCents(uint256)","898ad5ec":"set_arbits_presale_open(bool)","898c94b7":"SetDidPayOut(bytes32,bool)","898ce10c":"ChangeItemOwnerID(uint256,uint256)","898dc9b6":"setData_31(string)","898e3950":"addWinner(address,uint256,uint256)","898f767b":"precioether()","898fb033":"updateDescription(bytes)","898fdf94":"claimRate()","8991dede":"Falcon()","89920edf":"mintLockCashout(int256,address,uint256)","899231ef":"PRE_ICO_MINIMUM_CONTRIBUTION()","8992ae0e":"UBETCOIN_LEDGER_TO_LEDGER_ENTRY_DOCUMENT_PATH()","8993021b":"risks(bytes32)","899346c7":"nextPositionId()","89935c39":"getAmbientTempControlLimits(bytes32)","8994fa53":"TopUpMember()","89952097":"releaseRestBalance()","8995305e":"AsterionWorldToken()","89975389":"newVoting(string)","89976229":"setAmout(uint256)","8997f8cf":"getTokenUpdatedCounter(uint256)","8998470d":"tradeIntentOf(address)","8998ef19":"withdrawTokenMaker(address,uint256,address)","899942b8":"Devcon2Token()","899967b7":"redeemExcluded(address[],uint256[])","8999dd63":"ESoulToken()","899a0e7e":"OpenAIBlockChainToken()","899a1e36":"addBounty(address,uint256)","899aa65c":"Judged(uint256,bool,address,bytes32)","899ae006":"createBabies(uint256[],uint256[],uint256[],uint256[])","899b3414":"updateCoupleImageIPFShash(string)","899b53c9":"RICHToken()","899b64d9":"tokensPerEther_denominator()","899b6713":"VIRTToken()","899bf897":"isAllowedToRedeemNow()","899c0360":"getVIPRank(address)","899c4434":"testValidateTrade(address,address,address)","899d1556":"firstRoundICOTokensLimit()","899d840f":"PayPoker(string,string)","899e0fc9":"balanceOfPot()","899e37b9":"mintAndLock(address,uint256,uint256)","899e87f3":"AmountSet(address,uint256)","899ecf2b":"phase3EndBlock()","899f107d":"roomNightsOfOwner(uint256,uint256,bool)","899f9d29":"YCBToken()","89a0b679":"setContributor(address,address,bool,uint16,uint16,address)","89a2662f":"NeonCoin(uint256,string,string)","89a27984":"phepToken()","89a30271":"USDC()","89a3a00d":"addMinutes(uint256,uint256)","89a3e807":"Corban(address)","89a419e1":"set_stage_Days(uint256)","89a451fb":"getPriceChannel(string)","89a45223":"testFailCreateWithParentsParentNotInUse1()","89a4931d":"maxContributionAmountContract()","89a4bd1b":"foundationHashed()","89a4c1a0":"DevAddress()","89a5f2df":"privateSaleBonus()","89a69c0e":"setSubRegistrar(bytes32,address)","89a7adcc":"DelSocialAccount(bytes32,bytes32)","89a81e83":"validPurchase(uint256,uint256,uint256)","89a83701":"level(address,address,uint256)","89a9453a":"removeAllowedContracts(address[])","89a9d38e":"_approve(address,address,bytes32)","89a9d6b4":"tokensRemainingStage3()","89aaad29":"currencyUpdateAgent()","89abeb19":"ProcessGameExt(uint256)","89ad0a34":"setLocked(address,bool)","89ad0efd":"calculateAmountOfUnits(uint256,uint256)","89ad50e3":"CindicatorTalk()","89ada759":"availableBountyCount()","89ae1c90":"nativeReputation()","89aeca76":"registrars(address)","89af049d":"removeNacFromNLF(uint256)","89af175c":"RiservaETH(uint256)","89af2dce":"getBalanceFrom(address)","89afaf9d":"AddMod(address,address,bool)","89afcb44":"burn(address)","89b13814":"Killable()","89b1714b":"simpletransfer(address,uint256,uint256)","89b1802c":"feesRateCongres()","89b1fa0a":"ROLE_TRANSFER()","89b2050b":"addExtraBalance(address,uint256)","89b2b09e":"ABDEL_ADDRESS()","89b2df31":"getTurn(uint16)","89b337a7":"GetCityData()","89b38d2f":"getInvoicingAddressByIndex(string,uint256)","89b3f8c7":"Flames()","89b49d61":"checkCapNotReached(uint256)","89b4a36f":"Depot()","89b4c550":"checkAndSendPromoBonus(uint256)","89b51f94":"setCommunityAddress(address,address)","89b52360":"referralCount()","89b52b9b":"sendCoin(address[],uint256[],bytes32)","89b540aa":"FuckYou()","89b5b514":"maxFinalStage()","89b5ea24":"outputMoney(address,uint256)","89b61a85":"updateVeifyFee(uint256)","89b68f40":"releaseFounderTokens()","89b7e746":"getMyOpenedCount(address)","89b898b8":"batchConvertIntoHtlc(bytes32[],address[],uint256[],uint256[],uint256[],bytes32[])","89b8b492":"read(uint64)","89b8db55":"minBounty()","89b933cd":"serviceFallback(address,uint256,bytes,uint256)","89b9572f":"RBTToken()","89b97d07":"totalSite()","89ba3b23":"confirmDepositQuest(address)","89ba8e61":"getExplicitStrategyState()","89bb55c7":"apply(bytes32,uint256,string)","89bc0e6e":"UnitedToken()","89bc2006":"BagPackToken()","89bc455d":"THO()","89bca2d5":"addAuctionItem(uint256,uint256,address,uint256)","89bcbee2":"DemoToken()","89bcf968":"timeExpires()","89bdb217":"totalTeamFundMinted()","89be87a1":"openChannel()","89bfc6be":"PIVOTCHAIN()","89c0b25c":"openDispute(address,string)","89c1108d":"isTimeVault()","89c186d5":"addNewBusinessWallet(address)","89c18b48":"EtherusToken(address)","89c19ddb":"concat(string,string)","89c2443e":"executeSelfdestruct()","89c29b61":"calculatePaycheck(uint256)","89c44def":"sendMileStone(address,uint256,uint256)","89c5077f":"withdrawDevFee(address,uint256)","89c55845":"setBonus(uint8[5])","89c5ee3b":"executeAfterFinalize(bytes)","89c67976":"getAcceptance(bytes32,address)","89c698d4":"CrypteriumToken()","89c73565":"birthBlockThreshold()","89c766fd":"pause_for_maintenance()","89c77dfe":"mintValue()","89c7abfd":"removeAdministator(address)","89c7e70c":"BitliquorStandardToken(uint256,string,uint8,string)","89c98c06":"getMaxGasPrice()","89c9c44a":"EmontFrenzy(address)","89c9c586":"slopeDuration()","89c9e80f":"PotOwner()","89cb29dd":"nextEscrowId()","89cbc416":"tokensRedeemed()","89cc5c2b":"createdBlockOnRevealsPhase(uint256,address)","89cc5ea8":"bid(string,address,uint256)","89cc81c1":"contribute(bytes32)","89ccd39a":"set_address_A(address,address)","89ccf28c":"checkCapAndRecord(address,uint256)","89cd4b5e":"decidingBlock()","89cda6a8":"pausePVP()","89ce16cc":"maxRange()","89ce33bd":"delegateERC820Management(address)","89ce555c":"devFeesAddr()","89ced196":"setNotUpdatable(bytes32)","89cf5604":"releaseReserveTokens()","89cf9f94":"_reserveRefTokens(address,uint256)","89cfa823":"addPendingWithdrawal(address,address,uint256)","89cfd71b":"setPrivate(uint256)","89d2fca3":"DoctorChainToken()","89d3a15b":"addNewBlock(bytes32[],bytes32,bytes32)","89d3ed8d":"defineDiscountBorderLines()","89d410e9":"setIcoOwner(address,address)","89d4a66c":"internalDeposit(address,uint256)","89d59ee5":"createPersonalDepositAddress()","89d5da3b":"AlphaMarketICO(address[])","89d61942":"nextAuctionSupply(uint256)","89d61d77":"setOrganizer(address)","89d67775":"window1TokenCreationCap()","89d6d69d":"stampIndexToApproved(uint256)","89d700a5":"TheGTokenTest(uint256,string,uint8,string)","89d75221":"revokeSignToCancelAgreement(uint256)","89d77f82":"blocksToWaitLong()","89d86c5d":"getRetailer(uint256)","89d8b472":"_error(string)","89d8ca67":"drawPot(bytes32,bytes32)","89d8f96f":"getDirectOffersComissionRatio()","89d9b059":"refillRatifiedMintPool()","89d9ed38":"reserveFunds(address,address)","89da85d3":"getNumberOfArticles()","89dbeb64":"fundForAirdrop()","89dc8719":"getUserMaxPurchase(address)","89dcbbf9":"getFreeLobster()","89dcd64f":"saiTub()","89dd9e22":"changeBrick(uint256,string,string,string,bytes32[])","89ddeff3":"neurodao()","89de2581":"SetStorageContract(address,address)","89df1b01":"setMultiRequestLastRequestId(uint256,uint256)","89e198b4":"validContract(uint32,uint32,address)","89e2605d":"setReleaseAmountToCreator(uint256)","89e28a47":"getGameResults()","89e2c014":"allocateVestedTokens(address,uint256,uint256,uint256,uint256)","89e2d8bb":"handlePayableSharesDelta(uint256,uint256)","89e40af2":"stageSum(uint256)","89e42346":"enableRefund()","89e478f6":"minGasForDrawing()","89e4e22b":"pingDelta(uint256)","89e52771":"getTeamAddresses()","89e582c4":"FuturXe(uint256,string,string,uint8)","89e6359f":"preIcoEthers(address)","89e63a60":"conversionHashes(bytes32)","89e6579b":"registerExchange(address,address,bool,bytes4[])","89e6b5fb":"transferOwnership(address,bytes32)","89e7b8f6":"frozenFundsOf(address)","89e7f5cb":"OCZAPI()","89e85217":"teamBalance()","89e877a3":"activateWhitelist()","89e8beb3":"_strConcat(string,string)","89e94513":"advance(bytes15,uint32,uint64,uint64,int64,uint64)","89e96773":"BEY()","89ea2cb7":"onRefundPollFinish(bool)","89ea642f":"getString()","89ea770a":"grantTokensAdvisors(address,uint256)","89eaa610":"userAccess(address)","89eb313a":"isReadyToMate(uint256)","89eb4fee":"MYJ256()","89ebe846":"loyaltyWallet()","89ecd0e8":"disableAllowBuy()","89ed0b30":"setOraclizeGas(uint32)","89ed2ebf":"_transferDrone(address,address,uint256)","89ede784":"starbaseCrowdsale()","89edf114":"referralOwnerPercent()","89ee8758":"Daz()","89eea0eb":"tetherCount(address)","89eedf00":"setPdfHash(bytes,bytes)","89ef40e7":"numberOfHealthyGenerations()","89ef75b1":"purchaseWithPromoter(address,address)","89ef8292":"bulkTransfer(address[],uint256[],address)","89efa1b5":"registerEtherBalance(address)","89f0151c":"addAttribute(bytes32)","89f03ebc":"Incrementer2()","89f0ccba":"pre_start()","89f12d00":"minBlockNumber()","89f12ed9":"novaAddress()","89f182aa":"createMilestoneAcceptanceProposal()","89f1c26e":"minterTransferFrom(address,address,address,uint256)","89f1d38d":"Swap(uint256)","89f21090":"singleValueAirDrop(address[],uint256)","89f224a8":"EthlanceJob(address)","89f27d55":"transferItem(uint256,address,uint256)","89f37c45":"test_invalidThrow()","89f395de":"tos()","89f47b64":"doCrowdsaleMinting(address,uint256)","89f4ed7a":"getLastTag(uint256)","89f4fd57":"getUserProxy()","89f63f50":"teamb()","89f650fd":"next(bool)","89f6709c":"longRecord(address,uint256)","89f6e826":"drainRemainingToken()","89f71d53":"lastAction()","89f85a4b":"BalanceLocked(address,uint256,uint256,uint256)","89f8601e":"Engraved(address,bytes32)","89f88d7a":"Chess(bool)","89f8ab94":"lastRateUpdateTimesForCurrencies(bytes4[])","89f91592":"agreeWithdraw(uint256)","89f915f6":"getNumbers()","89f9b01e":"countingMeme()","89fa413d":"tradeRobot()","89facb20":"INTERVAL()","89fb75f9":"amountOfStage(address,uint256)","89fc01f6":"GetBidSeries(address)","89fcd099":"getApproval(address,address)","89fd14a1":"raiseTrivialThreshold(uint256)","89fdd81d":"PRE_ICO_LIMIT()","89fe141a":"maxSupplyPossible()","89fe253a":"BountyCampaingWallet()","89fe5273":"getTokensToSend(uint256)","89fe8507":"setNumbers(uint256)","89fee530":"CBSToken(string,string,uint8,uint256,uint256,uint256,bool,bool)","89ff7fe0":"getCurrentBlockNum()","8a007d86":"preSaleMinPaymentWei()","8a007f30":"endGame(uint256,string)","8a00a82f":"withdrawRewardFor(address)","8a010c22":"changeBankAccount(address)","8a0193ac":"getGameExpired(uint256)","8a024a3f":"releaseINAToken()","8a03ad86":"getUserAddressById(uint256)","8a0490db":"PrakashToken()","8a0520fb":"isApprovable(address,uint256)","8a054ac2":"d()","8a059493":"fetchRoundIndexBySnapshotBlock(uint256)","8a05ad20":"TokensIssued(address,address,uint256)","8a05e478":"instantiate(address,address,bytes32)","8a063d91":"rewardThree()","8a066045":"unescrowFrom(address,uint256)","8a06cb71":"get_config()","8a06ce1b":"setTotalSupply(address)","8a0807b7":"indexOf(string,string)","8a0904da":"mainSale_EndDate()","8a098cd7":"bucketManager()","8a0a53d5":"BicycleSupply()","8a0c47cd":"changeWallet(uint8,address)","8a0cbf50":"VCCoin(address)","8a0cc3c6":"SMILO_COMMUNITY_AMOUNT()","8a0e5a75":"addToPublicSaleWhitelist(address[])","8a0e859f":"isDiamondAuction()","8a0f1e52":"PlayerBet(uint256,uint256)","8a107a31":"generate(string,address,address,bytes32,uint256,uint256)","8a1129f1":"unfreeze_start_date()","8a120dc9":"testBitEqualFailIndexOOB()","8a124744":"SiuToken()","8a127931":"profit5eggs()","8a13796e":"CERB_Coin()","8a13aa4b":"takeEth()","8a13aa4f":"WorldToken()","8a13eea7":"erc20Token()","8a1489e3":"viewInvestorDividendHistory(uint256)","8a14f12c":"totalWagered()","8a155171":"availableForWithdrawal(address,address)","8a157df3":"createAuction(uint256,uint256,uint256,uint256,uint256)","8a157fae":"getEthBase()","8a1678a4":"LUMA()","8a17041a":"_founder_one()","8a17164c":"distributeTokenSaleJackpot(uint256,uint256)","8a172f2e":"getPawnEngine(uint256)","8a175ac2":"enableContribution(bool)","8a186788":"lookupIndex(uint256)","8a18a804":"UnsoldTokensBurnt(uint256)","8a18c55f":"SMT()","8a192c70":"setWLMTfinney(uint256)","8a194223":"Cryptolotto6Hours(address,address,address,address)","8a196437":"VRJToken()","8a19ac6d":"fechAllVoteResultPreRoundByBlock(uint256)","8a19b4d2":"addAdmin(address,address)","8a19c8bc":"currentRound()","8a19e355":"addToBalance(uint256)","8a1abbcf":"_getClientSupply(address,uint256,uint256)","8a1af4c4":"addOperator(address,address)","8a1b991d":"SBCE(uint256,uint256)","8a1bb169":"getJsonToTokens(string,uint256)","8a1bba96":"InvestorSum()","8a1bda63":"LogRedistributeTokens(address,uint8,uint256)","8a1be474":"CCNCrowdsale(address)","8a1d42f4":"setData_4(string)","8a1d8ae6":"x32323(uint32,string,uint8,string,address)","8a1dd162":"getPixel(uint256,uint256)","8a1e1404":"showFPLowerlim()","8a1f7a1b":"getMesa(uint256,uint256)","8a1fde4b":"setMaxwin(uint16)","8a20d00c":"buyTokensFromContract(uint256)","8a20f724":"currentRoundIndexByDate()","8a20f73c":"isInstrument(address)","8a213adb":"testFailMintGuyNoAuth()","8a237f27":"F2D()","8a2418ab":"nextSeedHashA()","8a24fd78":"convertGeneArray(uint256)","8a252194":"betGanjilGenap(bool)","8a252831":"asyncSend(address)","8a25aefa":"TEST_HOUSE()","8a2693e5":"kycVerification(address,address,uint256)","8a26d4c4":"GBTToken()","8a27a31c":"currentBanker()","8a27a51c":"transferGiveaway(address)","8a27a88b":"recoverAddressFromBalanceProofUpdateMessage(uint256,bytes32,uint256,bytes32,bytes,bytes)","8a294c60":"blacklisting(address)","8a29b77d":"receiveApproval(bytes)","8a2a0879":"TAUKEAYAM()","8a2a60ef":"foreignDailyLimit()","8a2ade34":"DonationClaimed(address[2],uint256[7],uint8,bytes32[2],uint256,uint256)","8a2ae2ab":"killTile(uint16,uint8)","8a2bfdf2":"add2Auction(uint256,uint256,uint256,uint256,uint256)","8a2cb24d":"castleExpAdjustment()","8a2e196c":"NTRYAvailableForSale()","8a2e2bf8":"updateLuckpool(uint256)","8a2e467c":"firstRoundTime()","8a2f6f94":"getRoleStatus(address)","8a30442e":"validTransfer(address,address,uint256,bool)","8a306c21":"mainSaleSupply()","8a31ffda":"replaceBoardMembers(address[])","8a323b38":"Contract(uint256,string,uint8,string)","8a329809":"setFeeContractAddress(address)","8a331846":"dividendParentsPercentage()","8a333b50":"max_supply()","8a33f585":"getOrder(address,uint32)","8a340eab":"BKToken()","8a341c83":"testErrorRootAuthorityChangeUnownedPackage()","8a34396a":"personalCapActive()","8a344477":"putDeed(bytes32,uint256,bytes32,bytes32,uint256,string)","8a349cc4":"subscribtionLittafi(uint256,string,string)","8a34bb24":"changeContractFee(uint256)","8a355a57":"removeProvider(address)","8a359d6e":"getEducationCitizens(uint256)","8a35b8c7":"invested(address,uint256)","8a35f788":"_getWinner()","8a36c3dc":"TeamToken(string,string,address)","8a36ebc2":"showSmallProfit()","8a36f5a2":"Debug(uint256)","8a38ab2c":"createCourse(string)","8a3907b9":"buyPerSell(uint16,bytes32)","8a394c4c":"eraseUnsoldPreSaleTokens()","8a39ebdc":"globalPresaleLimit()","8a3a84a8":"Total_Payouts()","8a3aa194":"endCrowdSaleTime()","8a3b0199":"transferOnBehalf(address,address,uint256)","8a3bacd1":"backup_drawdown()","8a3bc2bc":"iPropose(bytes,uint256,bool)","8a3c36cb":"DollHair()","8a3c44a5":"Constructor()","8a3d6290":"addBountyTransferredTokens(uint256)","8a3d7cdc":"tiles(uint256,uint256)","8a3db05f":"_myTokeName()","8a3e37c3":"StarbaseMarketingCampaign(address)","8a3e44d4":"assetMoveInformation(address,address)","8a3e99ff":"HighCastleToken()","8a3f6e2a":"transferFromAndDepositTokenFunction(address,uint256,address)","8a3f8a23":"queryChibi(uint256)","8a4068dd":"transfer()","8a40bd00":"allowedToUpgrade()","8a40c4c4":"Youdeum()","8a426b1b":"handleExternalBuyers(address[],uint256[],uint256[],uint256[])","8a42b68c":"approveOrderHash(bytes32)","8a42ebe9":"set(string,uint256)","8a433274":"executeVoting(uint256,bytes)","8a43fc7e":"return_rejected_payment(uint256)","8a449c2c":"VividoRaidenToken()","8a44ae91":"setAUM(uint256)","8a45242d":"newGame(bytes32,uint256,uint256,uint256)","8a45557e":"flowerTotalSupply()","8a4577ea":"returnTokensFromTeamAddress(uint256)","8a462fbc":"calculateNewPrice(uint256)","8a46467d":"reloadCore(address,uint256,uint256)","8a4660fe":"MINIMUM_INVESTMENT()","8a468e15":"TBowner()","8a469c16":"addGeneralMilestone(string,string,uint64)","8a46bf6d":"testFallback()","8a47cadb":"SunPowerToken(address,uint256)","8a48941f":"getDistributionFacts()","8a48ac03":"getAccounts()","8a49a3cc":"updateTrustScore(address,uint256,uint256)","8a4a8718":"GoinbitToken()","8a4a9aab":"xhstoken()","8a4af069":"TotalTokenSupply()","8a4b08d9":"getPriceRate()","8a4be59e":"incentiveDistributed()","8a4c81c2":"SEADToken(uint256,uint256,uint256)","8a4cae0e":"addVpf(bytes32,uint256,uint256,uint256,uint256,uint256,int256[])","8a4d5a67":"content()","8a4db4fa":"allowedToBuyBack()","8a4e3025":"addStaff(string,uint256)","8a4e4639":"pregnantPoniesies()","8a4e7a7c":"endCrowdsalePublic()","8a4ea479":"addUndergraduate(uint32,string,uint16,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","8a4fb16a":"getWithdrawal(uint256)","8a4fbead":"setTokenAllowance(address,uint256)","8a4fe8ac":"membersNumber()","8a505b4c":"setAutoBuyFee(uint256,uint256)","8a5144c0":"estProviderFee(address,uint256)","8a519fb9":"BlockChainEnterprise()","8a51d0fc":"totalEarlyInvSupply()","8a51e8ed":"_timeLimit()","8a529159":"KinguinKrowns()","8a53360f":"GrantUpdated(address,uint256,uint256)","8a53862d":"refundPartCollateral()","8a53c3b1":"TeamTokensHolderMock(address,address,address)","8a53f230":"noError()","8a545aec":"getEngineerPrizePool()","8a547932":"sendFounderAndTeamTokens()","8a54d6a4":"recordVotes(uint256[])","8a55b001":"Sleipnirwallet()","8a55d36e":"isStart()","8a5651e3":"EMISSION_FOR_PRESALE()","8a56b230":"setMiningWarInterface(address)","8a56ca45":"lastOwner()","8a56d115":"lagDefrost()","8a56e85e":"_createRandomDna(string)","8a56f3ee":"burnFrom(uint256,address)","8a56fe46":"orderExpired(address,address)","8a570230":"IDK()","8a585214":"BogpillToken()","8a5910a5":"RewardTimePeriod()","8a593cbe":"pre_ico(address,uint256)","8a59eb56":"updateStatus(bytes32)","8a5a68f4":"richtokenIndexToOwner(uint256)","8a5be698":"balanceOfDerivative()","8a5c19c0":"getWeekNo()","8a5c9098":"_mint(address,uint32,uint32,uint32)","8a5cca14":"AccountTransfersFrozen(address,bool)","8a5cf5ee":"quarter3()","8a5d815e":"finishContract()","8a5ddd9b":"emergencyAndHiddenCapToggle()","8a5ddf9d":"emergencyRedeem(uint256,address[])","8a5fb3ca":"currentFeePercentage()","8a604017":"pendingParticipants(uint256)","8a6083d2":"changeCrowdfundState()","8a609155":"totalUniquePlayers()","8a6158f7":"startSettlementProcess()","8a61a2a6":"NewKoth(uint256,uint256,address,uint256,uint256,uint256,uint256,uint256)","8a61b26d":"startICOPhaseTwo()","8a61bb91":"initiateBoardMemberVote(string,bytes32,address[])","8a61dcb7":"MiningReward()","8a626ba1":"offerPriceCandy(uint256)","8a6281f6":"getOwnerInfos()","8a62e9e9":"setIgnoreRequestIds(bytes32[],bool[])","8a62fd12":"NVTFallback(address,uint256,uint256)","8a6508ce":"removeCooldown(uint256)","8a653c93":"extGetLock(uint256)","8a654a64":"lockedAccountThresholdEth()","8a65d874":"userStats(address)","8a662b59":"SOLID()","8a6655d6":"vote(uint256,uint256,uint256)","8a6700e8":"Dex(address,address,address,uint256,uint256,uint256)","8a67456a":"contractPaused()","8a67c544":"setSchemaValidity(bytes32,bool)","8a67f04b":"_payoutMining(uint256,address,address)","8a67f4bf":"getRewardsBalance(address)","8a684f97":"EthMsig()","8a689784":"blocksDelay()","8a68ae3c":"transferPaladinOwnership(address)","8a69218c":"getLastRewardTime(uint256)","8a699023":"phase8Price()","8a69fead":"getTitulaire_Compte_1()","8a6a3584":"clearAccount(address)","8a6a8b6c":"getMonthlyTransactionVolumeSending()","8a6b114b":"getBet(address,uint256)","8a6b6877":"withdrawMineral(uint256)","8a6b9be4":"allowToWithdrawFromReserve()","8a6bc85a":"getInterestor(address)","8a6c02ae":"safeWithdrawal3(address)","8a6c0b26":"registerCreatorsPools(address[],uint256)","8a6d2d7b":"MATOU()","8a6d39b9":"Leak()","8a6db9c3":"minterAllowance(address)","8a6e0a8e":"_increaseApproval(address,address,uint256)","8a6ee066":"_releaseWithReward()","8a7097ce":"checkWithdrawalsgross(address)","8a7180ae":"team_token_percentage_max()","8a72ea6a":"offers(uint256)","8a738683":"sweep(address,bytes32)","8a7398e7":"getAllRoundRefIncome(address,address)","8a74b45c":"editApi(uint256,uint256,address,string)","8a74ee43":"allowTransferFrom(address)","8a74f69d":"transferMod(address)","8a758625":"setStrF1IntF2StrF2UintF2(string,int256,string,uint256)","8a75f56a":"setArbiterLocked(address,bool)","8a769d35":"miningTarget()","8a76a63e":"whitelistedInvestorCounter()","8a76d99b":"buyTicket(uint32,uint32,uint32,uint32,uint32,uint32)","8a775ab6":"RiskPrices(uint128[])","8a77ba1a":"companyVault()","8a78b7fb":"test_invalidProposalExecution()","8a78f5e2":"changeMember(address,bool,bool,uint256)","8a7a7e03":"ETH_PER_LARE()","8a7a8f46":"HJF()","8a7c20d7":"setReferralFund(uint256)","8a7c2ad7":"buyService(address,uint256,bytes)","8a7c2be2":"payEth(address,uint256,uint256)","8a7c2d6d":"hasOpenApplicationFromSource(address,address)","8a7c63c5":"privateStartTime()","8a7cc2ca":"RemapImported()","8a7d124b":"destroyToken(uint256)","8a7e30a1":"token_set()","8a7e5144":"addWhiteList(uint8,address,uint256)","8a7ed05c":"MAX_BID_FRAC_TOP()","8a7ef3df":"testFailCreateWithParentsParentSameItemId1()","8a7f1146":"RetrieveFunds()","8a7f800c":"preCensor(bool)","8a808acf":"Yaraq()","8a8090b8":"_setUint(bytes32,uint256)","8a80d9a3":"isRefundPaused()","8a80dfb1":"isFirstBadgeEle(uint256)","8a8146d0":"end_ICO_PreICO()","8a814cfe":"MyCrowdsale()","8a827eb9":"setSecondary(address)","8a82a09d":"MISTT1()","8a83d4a0":"burnMythexTokens(address,uint256)","8a863fbd":"juryOnlineWallet()","8a8672dc":"DINRegistry(uint256)","8a871c5f":"crosairVouchersMinted()","8a874084":"updateInteface(address,address)","8a87873a":"create(bytes32,address,bytes32[3],bytes32,bytes32)","8a87aeb9":"EthToOwner(address,address,uint256)","8a87b5c5":"dailyAdminAllowance()","8a87d8ea":"hasLicenseTerms(bytes32)","8a881e0e":"isExists(bytes32)","8a88c349":"addVestingMember(address,uint256,uint256,uint256)","8a88c4fe":"replaceOwnerIndexed(address,address,uint256)","8a890695":"logPurchaseViaFiat(address,uint256,bytes32)","8a892271":"initiateLocking(uint256)","8a89b338":"set_commandPercent(uint256)","8a8a0aab":"_b2(string,address)","8a8b4d61":"MediaBroadcast()","8a8b51b8":"setAddGas(address,uint256)","8a8b7deb":"CAT()","8a8b7e02":"whitelist_enabled()","8a8b98dd":"ETHT()","8a8bbd5c":"ThanhnvToken()","8a8bf82a":"batchTransferToken(address,address,bytes32[])","8a8c523c":"enableTrading()","8a8c8c42":"TokenCoin()","8a8cd78d":"setTurnoverTo(address,uint256)","8a8e2028":"getCurrentTranche(uint256)","8a8e3999":"_unsafeEncodeTokenId(int256,int256)","8a8e5239":"get_power(address)","8a8e5afb":"shaCommit(uint256)","8a8ede8a":"hasStatus(address,address,uint8)","8a8f1f25":"setAccountSpendingLimit(address,uint256,string)","8a8f5b79":"newXPAAssets()","8a905482":"createIpo(address,uint256,uint256,string,string)","8a926d0f":"maxTokenAmount()","8a933eac":"setSmartContractPrice(uint256)","8a93d70d":"MakerWithdrewEther(uint256)","8a93dbdf":"getInvestorDividend(address)","8a946339":"ERC20Token(string,string,uint256)","8a955876":"incrementCountSales(uint256,uint256)","8a957929":"setFeeAuthority(address)","8a957f15":"ccReleaseBlock()","8a95a746":"pie()","8a95addc":"NewPotentialOwner(address,address)","8a95f59f":"setHHRAddress(address)","8a96e27e":"CTTCToken()","8a973e17":"borrowEther(uint256)","8a97d915":"TokenMetadataUpdated(uint256,address,string)","8a983fbc":"KulouCoin()","8a98a9cc":"gen0SaleCount()","8a98cbd0":"SalePaused()","8a98deca":"setEtherCostOfEachToken(uint256)","8a9920b7":"emergentWithdraw()","8a99aa69":"_setStore(address)","8a99e917":"activatedPhases(uint256)","8a99fc87":"checkWhenContributorCanTransferOrWithdraw(address)","8a9b2b36":"_fillCardStruct(uint8,address,string,string,string)","8a9b35a7":"totalPresaleWei()","8a9b4067":"ren()","8a9b809b":"ChargCoinContract()","8a9ba931":"setContract(address,address,address,address,address,address,address)","8a9bb02a":"getRoundInfo(uint256,uint256)","8a9c497b":"totalBunniesCreated()","8a9c636c":"setAquiferInstituteCoinAdd(address)","8a9cb361":"hundredPercent()","8a9cba3c":"set_result_of_game(uint8)","8a9cf23a":"isEarlybird()","8a9d1fbf":"uniquePet(uint64)","8a9d3839":"setBountyWallet(address)","8a9d43e2":"getPlayerFee(uint256)","8a9d6bb1":"GEZI()","8a9d7982":"getActiveBetsRefund(address)","8a9e0876":"tokensReleased()","8a9e8671":"totalBid()","8a9f8a43":"set_block(uint256)","8a9fb135":"humaniqToken()","8a9fc475":"wipe(address,bytes32,uint256,address)","8a9ffb90":"transfer(string,string,bool)","8aa001fc":"getSecond(uint256)","8aa08617":"mintInitialTokens(address,uint256)","8aa0fdad":"mint(string,string)","8aa10435":"getContractVersion()","8aa14a07":"transferToAddress(address,uint256,bool)","8aa19ef7":"setOraclizeQueryGasPrice(uint256)","8aa2c280":"newAuction(uint128,uint256,uint256,uint256)","8aa31cbf":"ICO_PRICE8()","8aa33776":"setMsgPrice(uint256)","8aa35083":"PRE_CROWDSALE_DURATION()","8aa43284":"getNbProjects(string)","8aa4e240":"payoutOCDividend(address,address)","8aa4e315":"setExchangePrice(uint256)","8aa5440e":"setXCPlugin(address)","8aa5b2c3":"changeStartTime(uint256)","8aa6e6de":"approveMint(uint256)","8aa6f1b1":"setUltimateOutcome(bytes32)","8aa7d975":"DOCC()","8aa81eac":"ixentest()","8aa91406":"createIdea(address,address[],string)","8aa94f56":"updateUserCreatedPerformance(uint256)","8aa96f38":"collectAllocations()","8aa978be":"Pricing(address)","8aa986f6":"minimumContributionPhase2()","8aa99826":"IsTradeable()","8aaa559a":"ProtectedApi(address)","8aaaa197":"getCurrentRoundEndTime()","8aab811e":"setLOCdata(string,address,int256,address,uint256,string,uint256)","8aabb56f":"setMigrateIn(bool)","8aabe700":"refundTokensForAddress(address)","8aabff06":"getPVECooldown(uint256)","8aac0fa4":"transferGasFee(uint256)","8aac1708":"_deleteOperation(bytes32)","8aac61e9":"assetArray()","8aadf70a":"generateUniquePets(uint8)","8aae13cb":"getTokensByUSD(uint256)","8aae1f50":"withdrawOperationFees(uint32[])","8aae45be":"lastBonusMultiplier()","8aaf09a1":"getInitialInvestAddres()","8aaf699d":"sendCommunitySupplyToken(address,uint256)","8aafef65":"ITC(uint256,string,string)","8ab058b1":"AllocateToken(address[])","8ab11869":"sign(string,string,string,string)","8ab1a5d4":"sell(uint256,uint256,bool)","8ab1d681":"removeFromWhitelist(address)","8ab21fb6":"delegateVote()","8ab30e9f":"test_validShouldBe3_increaseBlocksBy100()","8ab3580c":"bigbomToken()","8ab3e33f":"removeKey(address,address)","8ab422a1":"addEmployee(uint256,string,string,string,string)","8ab476bf":"setDevelopers(address)","8ab49873":"isSubmitterAccepted(uint256,address)","8ab4ca8a":"lockRound(uint256)","8ab4d1ca":"PapyrusAirdrop(address)","8ab5212b":"teamVault()","8ab5fcc5":"setTypePrice(uint256,uint256)","8ab63380":"setContractAddresses(address,address,address)","8ab7f807":"applySettings(uint8,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","8ab8064f":"continueITO()","8ab8342e":"changeInsurerOperation()","8ab905d4":"existedOnWhitelist(address)","8abab8fb":"saleAccepting()","8abadb6b":"setAccountLevel(address,uint256)","8abb0e1f":"MRDSPrivateSale()","8abcb485":"InvestorBonusGet(address[])","8abdb005":"addCard(string,uint256,int256,string,uint256,uint256,address)","8abdf5aa":"serviceFee()","8abe09f2":"now()","8abe5593":"hashLength()","8abe59ea":"outcomeTokens(uint256)","8abe789b":"mulToResult(int256)","8abf344d":"callStages()","8ac01eaa":"SHARE_CRYSTAL()","8ac0ca36":"buyViaJohan()","8ac0e150":"fatigueBlock()","8ac0eef9":"changeUserKey()","8ac1a8d6":"weiRaiseLimit()","8ac1f290":"changelp20(address)","8ac2571f":"publish(address,bytes32,bytes32)","8ac27f5f":"investors()","8ac2c680":"minInvestment()","8ac341c6":"numModules()","8ac3ea2c":"recordEvaluation(uint32,uint32,uint8,uint8,uint8,uint8,uint8)","8ac44de2":"TBT_MINER()","8ac4e1d8":"TemperatureOracle()","8ac6a869":"isObsolete()","8ac78c80":"Docsign()","8ac81296":"ethTokenRatio()","8ac91be7":"unPause(bytes32)","8ac97efb":"whitelistDayCount()","8ac9fa73":"getTrustState()","8acb99ac":"owned(uint256)","8ace1732":"burnerOwner()","8ace4131":"CryptoTestCoin()","8aceaa4a":"GetTotalGamblerNum()","8acf94df":"setTierData(uint256,uint256,uint256)","8ad141ec":"updatePlayerContinusFund(address,uint256,uint256)","8ad14ee6":"setSuccessful()","8ad17f00":"setJackpotFeeRate(uint256)","8ad1896c":"bonusOptionsPromille()","8ad1d846":"getDebtorsDebts(address)","8ad20640":"allowedSinceReadable()","8ad2739b":"UMCCToken()","8ad2eaea":"has_token_sale_started()","8ad2f289":"checkPermission(address,address,bytes4)","8ad30473":"set_crowdsaleClosed(bool)","8ad46ba0":"b32toHexString(bytes32)","8ad476d7":"foundationReservation()","8ad47c47":"Dragon()","8ad5d779":"increaseOffsaleCountByOne()","8ad68253":"HostingDNS(uint256)","8ad682af":"ROLE_OWNER()","8ad9a976":"getServiceStat(uint64)","8ad9c8c3":"GetUserConAddr(string)","8ada066e":"getCounter()","8ada1957":"TOKEN_WALLET()","8ada80a2":"getWinnersLen()","8adb208d":"withdrawDukeOwnersMoney()","8adba5a9":"cap4(address)","8add359d":"WorkerPoolHub()","8adde811":"test2_addingSecond()","8addf3ca":"performUpdateMemsize()","8ade246a":"makeBet(uint256,address)","8ae0368b":"challengeNumber()","8ae06cf7":"SAFeth()","8ae0a7ec":"uniq(uint32[])","8ae18dfd":"setRemainingLockDate(uint256)","8ae1d8d4":"StatsTotalSupply()","8ae3beb2":"setPending(bool)","8ae4200a":"revokePrivilege(string)","8ae470a9":"set_time(uint256)","8ae475a9":"notorize(string)","8ae5e0ec":"allowManyTokens(address[],address,uint256[],bool[])","8ae5e372":"getMouthValue(uint256)","8ae63d6d":"blockNum()","8ae69807":"sendAirdrop(address[],bool)","8ae69caa":"getCountryOwnershipList()","8ae76b77":"createToken(uint256,address,bool,uint256)","8ae79c8c":"LovelockPayment(address,bytes32,uint256)","8ae83bf3":"DISPLAY_CLASSIQUE()","8ae85b80":"storeN(uint8[],uint256,uint256,uint256)","8ae881a6":"initMetadata(bytes32,bytes32,bytes32,string,bytes32,bytes32,uint256,uint256,uint256,uint256,address)","8ae8c1f3":"transferFromCrowdfund(address,uint256)","8ae986cf":"registrantApprove(address)","8aea12b6":"c_paymentChannelBonusPercent()","8aea2f6e":"totalFundingAmount()","8aeb8f98":"isNotEmpty(string,string)","8aebebd9":"restartCycle()","8aece8b0":"MRNToEth()","8aed434a":"oracle_values(uint256)","8aee0443":"getNumberOfPurchases()","8aee3a54":"enableATMExchange()","8aef16d0":"appendSupplyChanges(address,bool,uint256)","8aef91f5":"TimeLeftBeforeCrowdsale()","8af1bac9":"isMoron(address)","8af1c825":"SALE_MIN_BUY()","8af2c328":"buyTokensFor(address,uint256,uint256)","8af2ce26":"districtLimit()","8af2d152":"limit6()","8af49ab7":"maintain(uint256,uint256)","8af51833":"_transfer(address,string,address,string,uint256)","8af57597":"getSingleDeveloper(address)","8af6c259":"totalDuration()","8af784dc":"expectEventsExact(address)","8af82a2e":"getFirstUnsortedOffer()","8af9f493":"reap(address)","8afa08bd":"setDrawDate(uint256)","8afa46b1":"refunds()","8afa7c6a":"createBasket(string,string,address[],uint256[],address,uint256)","8afbcdd0":"setEmissions(uint256[])","8afbf669":"withdrawRemainingTokens()","8afc3605":"Ownable()","8afcf1c9":"_transferSignership(address)","8afdc26e":"currentIcoPhaseBonus()","8aff794d":"milestoneSystem()","8b00299b":"setSellComissionUnits(uint256)","8b008f0f":"setBuyBackPrice(uint256)","8b00c467":"growthTokensWallet()","8b0133d5":"calcBonus(uint256,uint256)","8b018bca":"maxDividendDepth()","8b021df4":"safePayback(address,uint256)","8b0254b6":"bilateralCancelOrder(bytes32)","8b02c8b2":"addFundTX(uint256,uint256)","8b034136":"totalBids()","8b036ee2":"PRE_SALE_BONUS_PERCENTAGE()","8b038f7f":"edrBalance()","8b03fcfd":"backersRedeemed(address)","8b043e08":"getPublisher(address)","8b044a50":"getCofounditTokenAddress()","8b0451d9":"CAT_PER_ETH_SECOND_EARLY_BIRD_RATE()","8b048091":"getTicketsSoldToday()","8b048645":"setCCH_edit_26(string)","8b05afd2":"saveBytes(bytes32)","8b06a662":"submitTotalSellOrder(bytes32,uint256,uint256)","8b072f0e":"migratePlayer(address,address,uint256,uint256,uint256)","8b073bb3":"changeStageBlock(uint256)","8b077355":"saleDistributorAddress()","8b07b006":"_tokensToSell()","8b07edba":"getI1()","8b08292d":"isValidAirDropForAll()","8b087f3f":"signToCancelAgreement(uint256)","8b092580":"preIcoHasEnded()","8b095904":"getBalancePercentageLimit()","8b0980d9":"Phoenixcurrency()","8b0b8820":"transactionStructFromBytesSeriality(bytes)","8b0b9cac":"setLatestTokenAllocation(address,address,uint256)","8b0b9ed4":"getWinningNumber()","8b0c7f67":"CROWD_WAVE2_PERIOD()","8b0d0258":"amount(uint256)","8b0e093c":"INEXTokenNew()","8b0e9f3f":"totalStake()","8b0ee5a3":"GAS_PRICE()","8b0fc015":"submitChoose(address,uint256)","8b0fc19a":"TokenSaleAfterSplit(uint256,uint256,uint256,address,address,bool,uint256)","8b10297c":"test_0_ensureControllerWorks()","8b104534":"tokensPerBatch()","8b1097c1":"setGeneMixerAddress(address,address)","8b110e0a":"MeshPoint(int256,string,address)","8b11fb3e":"secureTokenPay(uint256)","8b121c9d":"airdropMinting(address[],uint256[],int256)","8b121cf0":"TransactionEscalated(uint256)","8b122274":"setPriceIncrease(uint256)","8b128249":"MASSTokenPreSale(address,uint256,uint256)","8b12befe":"accrueBonusTokens(address,address,uint256)","8b12c25f":"updateReferralMasks(uint256,uint256)","8b12dc23":"DewToken()","8b133c56":"WatahaToken()","8b13b64b":"timeFrame()","8b13d4e0":"addTeamMember(address,bytes32,address)","8b13dd7b":"getAcceptance(address,uint256)","8b14251f":"setNarcosCoreAddress(address,address)","8b144851":"getCompanyWallet()","8b14592a":"EtherNex(uint256,string,string,uint8)","8b147245":"update(bytes32)","8b148ef6":"usedHashGuard(bytes32)","8b156d4c":"EthernautsUpgrade()","8b157515":"tokensInfoOfOwner(address)","8b15a605":"proposalDeposit()","8b169c7a":"coinageContract()","8b17ab2f":"calculateOptions(uint256[9],uint32,uint32,bool)","8b1928a5":"getAllergies()","8b19a476":"oraclize_query(string,string,uint256,uint256)","8b1acf9e":"ZcnoxToken()","8b1ad6c6":"AuctionFinished(address,uint256)","8b1b4036":"newTrade(string,string,uint256,uint256)","8b1b925f":"isValid(address)","8b1c80e2":"MAIN_SALE_BONUS_PERCENTAGE_PHASE2()","8b1c8792":"Blocktix(string,uint256,uint256)","8b1cc4f4":"tokenBurner(uint256)","8b1cf21c":"unlocked(uint256)","8b1cffe0":"newBrehonContract(address,address,uint256,bytes32,address,uint256,uint256,address,uint256,uint256,address,uint256,uint256)","8b1d37d4":"testUserCanSignUpAndLogin()","8b1d67f9":"initial_disbursement()","8b1db910":"hasSuicided()","8b1f3206":"addlockAccount(address,uint256,uint256)","8b20468b":"updatePalette(uint8,uint8,uint8,uint256)","8b20d082":"_getPlayerThemeEffect(bytes,uint256)","8b20d9fa":"get_probability(bytes32,uint32,uint32)","8b214d5d":"imOwner()","8b21d307":"createProxyAddress()","8b220a31":"addProcessableAllocation(address,uint256)","8b223943":"stage3BeginTime()","8b22c7b3":"keeppetToken()","8b22e1df":"raiseDay1()","8b23397a":"_getFashionParam(uint256,uint16,uint16,uint16)","8b235f04":"lastSignedBlockHash()","8b24793d":"revealCeiling(uint256,uint256,uint256,bool,bytes32)","8b24c3e0":"getRequiredMajor()","8b257d3d":"isValidSignature(bytes32,uint8,bytes32,bytes32)","8b259bdb":"setupIco(uint256,uint256)","8b278707":"addFeeFeedBack(address,string)","8b278a30":"updateBanThreshold(uint256)","8b27c179":"maxPlay()","8b281018":"sendFunds(uint256)","8b2886ca":"setNorthPoleAddress(address)","8b28ab1e":"calculateFee(address,uint256)","8b28df17":"NCCUyen()","8b2909cf":"tokensFromPreviousTokensale()","8b290a72":"employeeShare()","8b294960":"balanceInTranche()","8b299903":"turn()","8b29e88b":"icoTokenCap()","8b2a6f58":"cancelEpochUpTo(uint256)","8b2a81ed":"HashGardToken()","8b2a9606":"addDigitalArtSellingItem(uint256,uint128)","8b2ad32e":"getSketchesOnOfferWithHolder(address)","8b2ae073":"setCouponMulFactor(uint256)","8b2b423a":"privateSaleAmount()","8b2be40e":"firstCurrentAmount()","8b2c434c":"CryptoGiants()","8b2d2dca":"setAllowMarketplace(bool)","8b2d4ed1":"creatorsPoolAddrs(uint256)","8b2de796":"housePercentOfTotal()","8b2e2b07":"CAKSale()","8b2e31dc":"STARTING_LOBSTER()","8b2e41b2":"getPlayerShipBattleWinsById(uint64)","8b2e6dcf":"publish(bytes32)","8b2e92ce":"rewardAngel()","8b2ef965":"securityDepositRegistry()","8b2f1652":"transcoderStatus(address)","8b2f7af3":"CalculateAllocatedUcash()","8b3049e1":"lotteryByETH5(address)","8b31aaca":"ZOB()","8b31bd50":"appreciationRate()","8b322791":"confirmCrowdsaleEnd()","8b325902":"totalTokenMintedOpen()","8b3272dc":"setUseService(bool)","8b3294e5":"addRecipientUpdate(bytes32,bytes32)","8b32f62a":"TEAM_AMOUNT()","8b33b4b2":"operations()","8b343e8f":"getMemberCredit(address)","8b34839f":"claimTokensEnabled()","8b34a4b3":"nestedSecondAllToAll(uint256)","8b35a244":"partner2()","8b360f4d":"teamSupply24Months()","8b36ed08":"CmmToken()","8b37112b":"doReclaim(address,uint256)","8b37691b":"TxOriginContract()","8b37e656":"getCallScheduledBy(bytes32)","8b384f9f":"getMenu()","8b392dff":"mModerators(address)","8b39bdba":"tokensDaily()","8b3aa967":"getDepositDelta()","8b3ac630":"buyShip(uint256,address)","8b3c4f6f":"Register(bytes4)","8b3ca352":"CFL()","8b3caf37":"Operatable()","8b3cda96":"IotPC(bytes32,bytes20,uint256,address,uint256,uint256)","8b3d10bf":"BMCTToken()","8b3dd749":"getInitializationBlock()","8b3e23d9":"preIcoSupply()","8b3edbdf":"changeManufacturerWallet(address)","8b3f863f":"getUserType(address)","8b40594d":"tokenExchangeRatePreSale()","8b409cec":"addRelease(bytes32,string)","8b42ad37":"test_twoFalseAssertNoMessage()","8b43234b":"endPeriodB()","8b449ffd":"woyaoqianqian(uint256)","8b44af0e":"transferETHS(address[])","8b44c99a":"capture(bytes32)","8b44f194":"TBOT()","8b45ab24":"SoccerBet(string,uint256,address)","8b46e1f1":"getVercodesOfCampaign(bytes32)","8b473c3d":"getKeysByDeviceId(uint8,uint8)","8b477adb":"transferFromByLegacy(address,address,address,uint256)","8b47c10b":"ERC721token()","8b490893":"CBO()","8b49644d":"test_invalidProposalBytecode()","8b4a781c":"getVoters(bytes32)","8b4b891b":"Duarte()","8b4b8a26":"updatePriceTier(uint8,uint256)","8b4bf731":"setEtherPriceUSD(uint256)","8b4c40b0":"donateETH()","8b4c4307":"EstLiquidationCap()","8b4ce7ce":"updateRegionPixelPrice(uint256,uint256)","8b4d199e":"recordTransaction(address,uint256,uint64,uint64,uint64)","8b4d3f20":"Xin(uint256,string,string)","8b4d56de":"createAndJoinCDPDai(uint256)","8b4e79c2":"delegateFromPool(uint96)","8b4e8a6a":"MedED()","8b4ef7d4":"ContractAdded(string,address)","8b4fac8e":"testsignature()","8b4fff3e":"register(address,string,string,string,uint256,string)","8b50cd34":"attackTile(address,uint16,uint256,bool,bool)","8b51365b":"set82Mode(bool,bool)","8b519e09":"mainSaleEnd()","8b51ca42":"roleList(bytes32,bytes32,address)","8b51d13f":"getConfirmationCount(uint256)","8b52463a":"commissionerAuctionCancelled(uint32)","8b533562":"giftsOfOwner(address)","8b534dd3":"goldenTicketMoved(address)","8b53808b":"ForwardToEIF()","8b53cbaa":"addNode(string,uint8)","8b5406af":"angelLockingPeriod()","8b542d74":"test_twoValidEqInt()","8b543b80":"maximumCredit(address)","8b5462da":"getMy()","8b55c1b3":"pushPlayer(address)","8b56aff8":"createPromoMonster(uint256,address)","8b57192b":"Woleum()","8b57ebc6":"claimSegments()","8b57f150":"newUserReward()","8b587b82":"createPuppySiringAuctiona(uint256,uint256,uint256,uint256)","8b58c64c":"getUserCap(address)","8b595440":"setBurnAdminApproval(address,address,address)","8b5a17df":"frozedCount()","8b5a64fb":"registerNameXname(string,bytes32,bool,uint8)","8b5b1c9a":"setPools(uint16,uint16,uint16)","8b5b4228":"listTiers()","8b5b9ccc":"getPlayers()","8b5bc550":"WPAYReward()","8b5c37c3":"L19_Token()","8b5caa66":"backendWithdraw(address,uint256)","8b5dc8a5":"IsAllowed(address)","8b5de2d9":"FunFairSale()","8b5e331c":"HatchEgg()","8b5e6679":"setNewIco(uint256,uint256,uint256,uint256,uint256)","8b5f42ca":"addDataStream(address,string,bytes32)","8b603300":"updateLocation(int256,int256)","8b6084e4":"switchState()","8b615813":"fundLockTransfer(address,uint256)","8b629cbc":"m_ETHPriceUpdateInterval()","8b63c0e8":"returnTokenDepositState(address[2],uint256[7],uint8,bytes32[2])","8b63c86f":"setupRace(uint32,uint32)","8b64574b":"nextFreeze()","8b6497b9":"s41(bytes1)","8b649b94":"roundLength()","8b64b3af":"advisors_address()","8b64d70e":"owner_set_time_limit(uint256)","8b66bf68":"takeMyMoney(bytes32)","8b66d153":"STSTEST()","8b66e3b4":"hasPlayersInRound(uint256)","8b6715cd":"getTotalRankTokens()","8b673e7a":"setConfig()","8b67430e":"voteToCandidateIndex(uint256)","8b676ae8":"scheduleCall(address,bytes4,uint256,uint256,uint8,uint256,uint256)","8b67d56e":"getContributorsWallet()","8b67ef19":"distance(uint8,uint8,uint8,uint8)","8b68cd9d":"rndMax_()","8b692479":"addProduct(uint256,uint256)","8b6932f1":"saleTimeOver()","8b69759d":"removeAuthorizer(address)","8b699fbb":"KiemTra(uint256)","8b6aacc8":"stopSendWebGift()","8b6bd650":"ChangeCoinPresale()","8b6bf3dd":"intervalueToken(uint256,string,string)","8b6c1cfb":"totalHeldSupply()","8b6c69e5":"presaleLimitUnits()","8b6d6e48":"GoldPurityToken()","8b6d6f1d":"checksOn()","8b6df6bf":"DEMOHASHTOKEN(uint256,string,uint8,string)","8b6e10ac":"allBalances(address[],address)","8b6f8646":"CHCTokenERC20()","8b6f894f":"releaseEscrow(address)","8b6fb3ac":"GetOrganNumber()","8b6fc452":"tip(address,uint256)","8b7001d0":"ReceivedBCH(address,uint256,string)","8b7116e4":"reviewActiveMembers(uint256,uint256)","8b72a2ec":"transferPunk(address,uint256)","8b72ddf7":"setMinimalTokens(uint256)","8b7314e3":"BEToken()","8b73a46b":"getNumberOfMembers()","8b73c10e":"buyChibiWithFcf(string,string,uint8,uint256)","8b745ff2":"valueBlocked(address)","8b76e976":"setRef(uint256,address)","8b77071c":"profitEth()","8b79bb43":"MTelCoin()","8b7a01e3":"depositOwnership(address)","8b7afe2e":"contractBalance()","8b7b45d9":"hashSchema(string,string)","8b7bcc86":"numWinners()","8b7bf3eb":"getAdminCount()","8b7c34d4":"setCompte_12(string)","8b7d38a1":"sPerDate()","8b7d6b05":"makerUnlockedKnc(address)","8b7e7a2e":"TBEToken()","8b7f0ddd":"register(address,address,string,string,bytes32[],uint256,string)","8b7f4cb7":"_calcDate0(uint256)","8b7fe5be":"DonationEvent(address,uint256)","8b800e6f":"migrationCounter()","8b805e65":"setUsers(address)","8b80bd19":"Migrated(address,uint256)","8b810c36":"epoch(address)","8b81b1af":"getLastOwner()","8b8211a1":"closeSale1()","8b82f4bc":"PAYCOINLY()","8b83209b":"payee(uint256)","8b832705":"getAmountOfGrantAccessInvestor(address)","8b833318":"getArtworkGroup()","8b8373ca":"AMBASSADOR_SIX()","8b8414c4":"getPoaConsensus()","8b845c1d":"withdrawCommisionToAddressAltCoin(address,uint256)","8b8519a2":"frozenTimeOf(address)","8b859409":"setRelease(bytes32,bytes32,string)","8b863095":"setContractorProposal(uint256,bytes)","8b87c544":"getInventory(address)","8b87e3b6":"bountyMinted()","8b886d04":"setCatchable(uint32,bool)","8b88a687":"getCost(address)","8b88c9cf":"setSpaceCraftAddress(address,address)","8b8c1177":"changeTokenOffer(uint256)","8b8c5ed9":"scheduleUnderwriteOraclizeCall(uint256,bytes32)","8b8d7c04":"writeConditions(uint8,string)","8b8e5fe2":"secondRewardPeriodEndBlock()","8b8ecffa":"teamAndFoundersWallet()","8b8f8504":"NodeManager(address[],address[])","8b906ca5":"enterBidForSketch(uint256)","8b90a378":"STATE_DONATION_ROUND_2()","8b91124d":"getSubscriptionClosedAt(bytes32)","8b91d5f6":"PRICE_CROWDSALE()","8b91e9a2":"getSubscriptionNonce(bytes32)","8b91f4a3":"ProofOfBitConnect()","8b9299dc":"authorizeMany(address[50])","8b93509f":"addTeamtoBoard(uint16,address,uint8)","8b935fb1":"keys(uint256,uint256)","8b93d3fc":"stake(uint256,bytes32,uint256,uint256,uint256)","8b959014":"DPC(uint256,string,string)","8b9596ed":"Eladporat()","8b95ec0c":"testAddBalance()","8b96801e":"soldTokensCount()","8b969c33":"editTokenProperties(string,string,int256)","8b96e41c":"_preMcFly()","8b9724d1":"setExclusiveRate(address,uint256,uint16,uint32)","8b9726c1":"multiAccessCallD(address,uint256,bytes,address)","8b975028":"setCooldown(uint256,uint256,uint256)","8b9801b0":"TheHashSpeed()","8b9847a5":"AmazonBestsellerLabs(uint256,string,uint8,string)","8b986566":"TokenTESTToken()","8b9997fd":"getOwnerHoverText(address)","8b99b742":"arbitrateCancelCampaign()","8b9a167a":"aliceClaimsPayment(bytes32,uint256,address,address,bytes20,bytes)","8b9add74":"minCapReached()","8b9af5c1":"wmul(uint256,uint256)","8b9b1cbd":"withdrawRemainder()","8b9b62b1":"toB32(uint256,bytes,address)","8b9bde27":"setNameHashByWriter(address,bytes32,address,bytes32)","8b9c7a36":"initialStartPrice()","8b9ce6a6":"create(uint256,uint256,address,address,address,uint256,uint256,address,uint256,uint256,bool,bool)","8b9d6899":"lockedAmountOf(address)","8b9e2832":"mintRep(address,uint256)","8b9e4768":"_level()","8b9e5385":"MeterSlock(uint256,uint256,address)","8b9efe2d":"lastCountAddress()","8b9fae3f":"getETHback()","8b9ff6b6":"left91(uint256)","8ba19d4f":"EGGS_TO_HATCH_1CRAB()","8ba1c353":"_scaleExp(uint32,int32)","8ba1ebce":"updateGenVault(address)","8ba209b6":"isAccountVerified(address)","8ba28961":"spawn(uint32,int256,address)","8ba39ea8":"getChecksum()","8ba3ee95":"setConverterRamp(address)","8ba45307":"basePunish()","8ba47bdd":"ticker()","8ba4cc3c":"airdrop(address,uint256)","8ba5306b":"getDefaultRecommAddr()","8ba5758b":"HumanStandardToken(uint256,string,uint8,string,uint256)","8ba5807c":"raceCount()","8ba5882a":"manualOverrideEditionHighestBidAndBidder(uint256,address,uint256)","8ba64328":"getParentOperation(bytes32,uint8,uint8)","8ba677fa":"sendPremiumPack(uint256)","8ba7bdc4":"adminClaimTokenForUser(address)","8ba7e570":"executeCall(address,uint256,uint256,bytes)","8ba7e7f2":"createHash(address,bytes32,bytes32)","8ba88c9c":"internalRemoveManager(address)","8ba8da61":"payback(uint64)","8ba8ffc6":"buyGrapes()","8ba92763":"ABsCoin(address,uint256)","8ba93fcb":"magicStore()","8ba9a7bb":"FACTOR_4()","8ba9d9b0":"EmailSent(address,string,string)","8ba9f354":"testClearBitSuccess()","8baa28f7":"allocate(address,uint256,uint256,string,uint256)","8baa8b1f":"staker(bytes32,address)","8bab6718":"investorsInfo(address)","8bab8791":"testPkgUpdate()","8baba52a":"allStates()","8bace235":"kycAddresses(address)","8bace717":"getPresaleAllocation(address,address)","8baced64":"isInPool(address)","8bad5de9":"checkMinBalance(address)","8bad8d8e":"reserveManyTokens(uint256[],uint256)","8badbb8b":"ETPToken()","8bae2a03":"getStoredFib()","8baecc21":"revive(uint256)","8baeefce":"stopTrade()","8baf612f":"Ownable2()","8baf7a0c":"CryptoPrueba()","8bb04875":"executeRuling(uint256)","8bb0faee":"setRef(string,string)","8bb19439":"isPending(uint256,uint256)","8bb1a5ef":"executeDeal(uint256,string)","8bb204d4":"setCaptainIndexToCount(uint32,uint256)","8bb28de2":"minShare()","8bb307a2":"getMyTokenBalances()","8bb36848":"pollDataMultihash()","8bb55cae":"beforeExecuteForFutureBlockCall(address,uint256)","8bb5d9c3":"setCounter(uint256)","8bb64abe":"releasableBonus(address)","8bb75533":"split(string,string)","8bb7819f":"curMaxBet()","8bb87f5b":"isTank(address)","8bb88db6":"EtherSmart()","8bb8b2db":"getTokenPerEth()","8bb93173":"getNextTimeAtkPlayer(address)","8bb9fe58":"addStruct(uint256,string)","8bba143c":"getNumberOfContributors()","8bbade4e":"usdEth()","8bbb594a":"createActiveEdition(uint256,bytes32,uint256,uint256,uint256,address,uint256,uint256,string,uint256)","8bbb5af7":"test1Fails()","8bbb668b":"ItemSelling()","8bbb9fca":"buyPresale(address)","8bbbc7a2":"BitnanRewardToken(address)","8bbd309c":"BLTCoin(address)","8bbda7e3":"setContent(string,bytes)","8bbdcf67":"_createProduct(uint256,uint256,uint256,uint256,uint256)","8bbdfaa6":"approveChange(address,uint256,bool)","8bbe005d":"setGateGas(uint256)","8bbe4719":"donateToPool()","8bbec9e4":"WALLET_T8EX_ADMIN()","8bbf037c":"addService(string,string,int256,uint256,uint256,uint256)","8bbf51b7":"DOW_WED()","8bbf7330":"FlyCareToken()","8bc008e6":"xra()","8bc04eb7":"DECIMALSFACTOR()","8bc05609":"setNotaryAddress(address)","8bc05808":"addLockTokenAllocation(address,uint256)","8bc05833":"setTotalSupply()","8bc0b887":"initializeAfterTransfer()","8bc12fd1":"cancelOrder(address[4],uint256[7],bool,uint8,uint8,bytes32,bytes32)","8bc19bda":"setupRaffle(string)","8bc19c04":"getPlacedNotes()","8bc30096":"numDrops()","8bc4a65f":"unPackDecision(uint256)","8bc5816a":"startStage1()","8bc5aab0":"FundsRecovered()","8bc5b3c5":"getExchangeInfo()","8bc5f845":"sendToken(address[],uint256)","8bc6a72b":"adjustCut(uint256,uint256)","8bc70769":"BTToken(uint256,string,uint8,string)","8bc7fa9c":"getCrop(uint256)","8bc85b03":"bonusEnd()","8bc88d7c":"nameMiner(uint256,string)","8bc97754":"popcnt64(uint64)","8bc9b67f":"endOfGame(address)","8bca15d6":"balancesCanSell(address)","8bcad96a":"AdminstratorAdded(address)","8bcb4250":"_bytesToUint(bytes)","8bcb6f01":"getLoserAddressList()","8bcba0b2":"_transferToContract(address,uint256,bytes)","8bcba45a":"secondPartOfTeamTokensClaimed()","8bcbb60b":"betsArePayed(address,uint256)","8bccae3f":"tokensForCrowdsale()","8bccb1b4":"EosPizzaSlice(uint256)","8bccbf62":"setShares(address,uint256)","8bcd0680":"CrowdsaleiPRONTOLiveICO()","8bcddd5d":"getLogsNum(address,uint256)","8bcdecd7":"getIssuerStatus(address,address)","8bce09fa":"resolutionProposal(string,string,address,uint256)","8bcea54f":"viewComponent(address,uint256)","8bcf0eea":"GCAP()","8bcf649d":"GetRank(uint16)","8bcff416":"asyncSend(address,address,uint256)","8bd031fe":"submitIssue(uint256)","8bd0ba67":"addChild(address,address)","8bd0f12b":"_deleteBool(bytes32)","8bd1b610":"deleteTeller()","8bd25857":"joinManual(address,uint48)","8bd30ba1":"KekToken()","8bd317eb":"reclaim(address,uint256)","8bd379b5":"itDevAddr()","8bd50488":"Policy(string,address,address,string)","8bd50c1f":"privateSaleCloseTime()","8bd53bea":"oraclizeFees()","8bd56066":"WXC()","8bd5d30f":"scoreGroups(bytes32,bytes32,bytes32,bytes32)","8bd61f26":"tokensRemainder()","8bd66bb3":"ModifyMine(uint256,bool,string,uint256,string)","8bd6da16":"distributeXAIN(address[],uint256,uint256)","8bd76535":"currentExchangePrice()","8bd7920d":"BitcoinCashPrivate()","8bd7df6e":"sharePot()","8bd82b20":"getInCar()","8bd8669e":"transferAllTokensToOwner()","8bd87a69":"TimeMachineToken()","8bda1540":"getOldBalance(uint256,address)","8bdac196":"KLSToken(uint256,string,uint8,string)","8bdbbca9":"GameChannel(address,uint256,uint256,address,address,uint256)","8bdbee39":"str_length(string)","8bdc558d":"hash_ack()","8bdc5a5f":"withdraw(address,address,uint8,bytes32,bytes32)","8bde7fc3":"ClickButton()","8bdff161":"getBonus()","8be1049d":"getTypeFromIndex(uint256,uint256)","8be13d71":"countOpenPackage()","8be18df9":"getOutcomeOfFirstPeriodByEntity(uint256)","8be3a897":"_v3()","8be3df0a":"vipPlacementNotDistributed()","8be4339b":"packsPerClaim()","8be4886c":"PUBLIC_RESERVED()","8be52783":"decreaseApprovalPreSigned(bytes,address,uint256,uint256,uint256)","8be7a96a":"registerLockedTokens(address,uint256,uint256)","8be7f4f5":"FOUNDER_FUND_1()","8be7fe95":"CreateDigitalAssetToken(uint256,uint256,string,string,string,string)","8be8f944":"lastBlock_f6()","8be909a3":"mainSaleWeiCap()","8be90b52":"averageGasPrice()","8be94a45":"Gallery_MuYi_No1()","8be97285":"MIN_TOKENS_TO_EXCHANGE()","8be9ca21":"GerritCoin()","8bea6a39":"safeSubtr3DL(uint256,uint256)","8beac22d":"STAEtoken()","8beb1af1":"PresalePool(address,address,address,uint256,uint256)","8beb60b6":"setAdminFee(uint256)","8beb9f12":"moveBlockValue(uint8,uint8,uint8,uint8,uint256)","8bec5b31":"reserveOwnership(address)","8bec683f":"getID_control()","8bee241b":"delegateOperation()","8bee78e6":"buySharesFromListing(uint256)","8bef5222":"CONFIG_MAX_TICKETS()","8bef7ba5":"updateBalances(address)","8bf0af3e":"purchaseTokens(uint256,uint256)","8bf13a30":"UTCStop()","8bf34237":"addPartner(address)","8bf35316":"givePermission(address,address,uint256)","8bf4515c":"read(bytes)","8bf57f4e":"getTimestamp(address)","8bf60537":"setDividendManager(address)","8bf62f14":"EtheropolyShrimpFarmer(address)","8bf68690":"mintToken(uint256,address,uint256,bytes32,uint8)","8bf74527":"EMISSION_FOR_SALESTAGE7()","8bf85ef0":"SigmaIOToken()","8bf87123":"_transfer(address,address,uint40)","8bf8a338":"getAttribute(bytes32,string)","8bfa4b4e":"tokenAdvisor()","8bfac3bb":"updateBalances(address,bytes32,string,uint256)","8bfb07c9":"release(address,address,uint256)","8bfbc753":"setEthBonus(uint256)","8bfc2f33":"delegateDAOTokens(uint256)","8bfe0aec":"getNextExit(address)","8bfe4e0b":"GaillardToken()","8bfe88c5":"ArteufToken(address,address)","8bffc74d":"mainstreetToken()","8bfff5a0":"setPurchaseableMode(uint256,bool,uint256)","8c003134":"Raffle_ID()","8c00ce76":"unhalt_30day()","8c0124fb":"transferAndFreezeMulti(address[],uint256[],uint256[],uint256[])","8c02d13f":"MAX_NUMBER_OF_PREMIUM_SALES()","8c02e029":"save2(address,bytes,string)","8c041d7c":"editProfile(string,bool,string,bool,uint256,bool,bool,bool,string,bool)","8c042317":"startQuater()","8c04b985":"readSellTokenAmount()","8c063686":"getRelayAuthority()","8c06fa18":"PRICE_PREICO()","8c088d98":"winMultiplePer()","8c08ae0d":"withdrawEtherRemaining()","8c09138f":"fourth()","8c0989ab":"MultiServiceFactory(address)","8c09bfdc":"shake(uint256)","8c0a41f2":"gibtesnet()","8c0b1588":"createNFT(uint256,address,bytes32,bytes32,bytes4)","8c0b372d":"e6c65e93()","8c0b4ae5":"setGenesMarketAddress(address,address)","8c0bae5b":"releaseRedTeamTokens()","8c0c0368":"_confirmOneSell()","8c0c9c07":"updateCampaignAbi(string)","8c0cf897":"develop()","8c0d0c29":"mark()","8c0d4199":"lock(address,address,uint256,uint256,bool)","8c0d6593":"CustomDealICO(uint256,uint256,uint256,address,uint256,uint256)","8c0dacf2":"deleteRecord(bytes32)","8c0dee9c":"operatorTransferByPartition(bytes32,address,address,uint256,bytes,bytes)","8c0e156d":"scheduleCall(bytes4,uint256,uint256)","8c0e299a":"proposeCompanyAllocation(address,uint256)","8c0e2a31":"regProxy(address)","8c0e45f6":"test_openRegistryRules()","8c0ead61":"_updateMLBPlayerId(uint256,uint256)","8c0ec0d1":"changeClient(address)","8c0f082c":"setFLKDForGas(uint256)","8c0f8e11":"getWorkerScore(address)","8c0ff5b7":"maxWithdrawal()","8c10671c":"addManyToWhitelist(address[])","8c115322":"isP2PKH(bytes,uint256,uint256)","8c118cf1":"verify(uint256,uint256,uint256,string,string,bytes32[2])","8c12324a":"Mire()","8c1256b8":"Recovered(address,uint256)","8c12c35c":"BTWO_CLAIM_PERCENT()","8c12d8f0":"arithmetics(uint256,uint256)","8c133a77":"previligedBalances(address)","8c133c25":"changeBetPrice(uint256)","8c13aabe":"lockStages(uint256)","8c14db73":"testThrowsSaleWalletIncorrectBlock()","8c155b5b":"tradeForTokens(address[2],address,bytes,bytes)","8c156213":"generateHash(address,string)","8c160095":"deleteInt(bytes32)","8c165146":"initSale1()","8c165932":"sendShip(uint32,uint32,address)","8c167076":"setHoldersList(address)","8c172fa2":"getEvent(bytes32)","8c17c5ab":"setNowTime(uint256)","8c17fc91":"getWeaponsArmy2(uint256)","8c19773f":"addBlock(address)","8c19c175":"getStageState(uint256)","8c19d2ca":"setCombatWonTeam(uint256,uint128)","8c1ab426":"WithdrawalofFunds(uint256)","8c1c7acc":"icoThreshold2()","8c1d01c8":"defaultPayment()","8c1d4a0a":"GreenEcoMinerToken()","8c1d92af":"distributePresaleTokens(address[],uint256[])","8c1d9f30":"isValidCandidate(bytes32)","8c1e04a6":"updateGenerationDict(uint256,uint64)","8c1e21da":"tokenPreSale()","8c1f85e5":"FeeSetup(address,address,uint256)","8c206979":"_freeze(uint256)","8c2081b5":"RewardsCoin()","8c217d06":"zsjz(uint256,string,string)","8c21f6bb":"getLockedGroup(uint8)","8c21ffba":"supplyLockedB()","8c22ac8b":"Account_frozen(address)","8c2305fd":"stakeBela(uint256)","8c25466a":"mintPreSale(address,uint256)","8c254c0b":"walletDev()","8c259654":"getRegistryDataRegistry()","8c25f54e":"linkContracts(address)","8c261e2c":"getHashRightPad()","8c267b97":"cmoAddress()","8c26a340":"generateOrderByAdminWithPayee(address,address,address,uint256,string,string,string)","8c26c937":"STQPreICO3TestHelper(address,address)","8c26ebf7":"EgretiaToken()","8c272dba":"_buyin(address,uint256)","8c273a98":"getRefBonus(address)","8c2779f5":"gold_token_storage()","8c28c16e":"STAGE_TWO_ETHRaised()","8c28fd6e":"mintHelper()","8c2962b9":"setBuyAgent(address)","8c299d0c":"AdoptionOfferCancelled(bytes5)","8c29bce5":"setJoule(address)","8c2a5938":"setAllowedToBuyBack(bool)","8c2b8283":"WeiLaiExToken()","8c2d1549":"getTotalMined()","8c2d396f":"TelegramOpenNetworkContract()","8c2e6b3f":"ChangeSellRate(uint256)","8c2f04d9":"distributeUsingVaults(uint256,uint256,uint256,address)","8c2f6458":"calculatePreviousPrice(uint256)","8c30079a":"generateTeamTokens()","8c30779b":"getAvailableVestingAmount(address)","8c3088c6":"HeritableWallet(address,address,uint256)","8c308a71":"Anemoi(uint256,string,string)","8c3135f2":"poolTokenBalance()","8c31d67e":"getNoOfSoldToken()","8c324604":"MAX_TOKENS_EARLY_INVESTORS()","8c32c568":"Airdrop(address,uint256)","8c32e774":"isMaxTokensReached()","8c33417c":"WankCoin()","8c335b4b":"oceanBonus()","8c339a58":"QSHUCOIN()","8c33a5c4":"RESEARCH_AND_DEVELOPMENT_TOKENS_PERCENT()","8c343aee":"TestIssued()","8c346690":"toggleHalt(bool)","8c34dbec":"bitcoing()","8c363fda":"AbstractToken()","8c366dd3":"newinitialSupply(uint256)","8c3692c3":"popToken(address)","8c36ae89":"clearReward(address)","8c374d8d":"releaseApproval(address)","8c3753d7":"WEI_PER_FINNEY()","8c377ca6":"UnsetUsername(string,address)","8c379133":"Water(string,string)","8c37ce04":"MeetTokenBase()","8c37e152":"bountyTokensReserve()","8c37e31e":"setSpawningManager(address)","8c37edc4":"USN(address,address,bytes32,uint256,uint256,uint128)","8c382e22":"checkIsAssetPartOwner(bytes32,address)","8c3846e8":"ConsumerAddition(address)","8c38eddd":"_clearAddressFromCrowdsale(address)","8c39bf96":"DredgrSwapSolo(bytes5,bytes5,bytes32,bytes32,uint256,bytes32,bytes32,uint256)","8c39cb93":"makeClaim(bytes32,string,uint256,bytes32,uint256,uint256,uint8,uint256)","8c3b6f0e":"getCrystalGeneKindWeight(uint256)","8c3c00aa":"overdraftPeriodAmount()","8c3c4b34":"getSaleStatus()","8c3d5897":"MANHATTANPROXY2NDAVE()","8c3e1ff1":"modexp(bytes,uint256,bytes)","8c3e9e1a":"verifyYourself(string,uint256)","8c3f71b2":"_getCurrentTradableToken()","8c3f914a":"spread(bool)","8c3fae8c":"BeeUnity(uint256,string,string)","8c404cf1":"stablesCities(uint256)","8c41399c":"view30()","8c41d101":"LogAgreementAccepted(address)","8c421815":"RefundedTokens(address,uint256)","8c4406c1":"setInputName(uint256,uint256,uint256)","8c4430b4":"setFinalLotteryAddress(address)","8c44cb27":"creationQuantity()","8c44dfb5":"bids_computed_cursor()","8c45cf24":"addJobContractMessage(uint256,string)","8c461e97":"setValueAirDrop(uint256)","8c46c7cd":"betAmount_()","8c47ddcc":"refundOwner()","8c4899ab":"ownerOfPlanet(uint256,uint256,uint256)","8c497285":"ChangeAddressTrust(address,address,bool)","8c4a6f62":"delMinter(address,address)","8c4af723":"changeNewRoundDelay(uint256)","8c4b0c58":"FrozenProfit(address,bool)","8c4b0e7e":"setOrganiser(address)","8c4b7300":"ViewBet()","8c4b87d2":"chris()","8c4c26a3":"BunToken(address)","8c4c564d":"deletePoll(bytes32)","8c4d3193":"getOrderDealTimeInterval()","8c4d59d0":"ticketCounter()","8c4dd5cd":"Democracy()","8c4e3f32":"_setApprovalForAll(address,address,bool)","8c4e8c21":"nextMintTime()","8c4e9c50":"prepareSell(address,uint256)","8c4ef31a":"getremainTokensperType(uint8)","8c4f7dae":"getMatchCount()","8c500418":"getICODate()","8c50d756":"bidSuccess(uint256,address,uint256)","8c518026":"_preSale(address,uint256)","8c529628":"getVoteFromProposal(uint256,uint256)","8c52dc41":"enableRefunds()","8c5344fa":"countThisRecursive(uint256)","8c534d54":"getTokenTxnNum()","8c53f61d":"receiveETH(address)","8c546f81":"GNT()","8c549ef7":"COLOR_BROWN()","8c55041c":"Announcement(address[],uint256,uint256)","8c551742":"createItem(string,uint256)","8c55284a":"confirm(uint256,bool)","8c5597fd":"finalizeContributionEvent()","8c561592":"canUpdateInvoicingAddress(string,address)","8c564ebf":"freezeBypassing(address)","8c5871bf":"getLocksUnlockDate(address,uint256)","8c590917":"contribute(uint256,uint256)","8c590b5d":"getAllMatingAnimals()","8c59f7ca":"cancelOrder(address[5],uint256[6],bool,uint8,uint8,bytes32,bytes32)","8c59fba0":"DATP()","8c5a03bb":"SimpleDistributor()","8c5aae96":"LocalsMembership()","8c5ae183":"RemoveMod(address,address,bool)","8c5b830e":"getInviteeInfo(uint256)","8c5cc61c":"approvedreg(string,string,string,string)","8c5ce82a":"powerTest(uint256,uint256,uint32,uint32)","8c5d5e87":"ownerSetMod(bool)","8c5e06b1":"Channel(address,address)","8c5e2b0e":"MainSaleStart()","8c5f6d5a":"SetDebugExtra(uint32,uint8)","8c5f997e":"NewEntry(address,uint256,uint256,uint256)","8c5fb7fb":"modifyMember(string,string,string,string)","8c60e806":"closeContributions()","8c614502":"addCountry(address,uint256)","8c618066":"addressOfName(string)","8c6310ac":"NextOpen()","8c638152":"setApoderado(bytes32,bytes32,bytes32)","8c64400d":"updateTierDuration(uint256,uint256)","8c648117":"actualPrice()","8c6486c4":"sendRegistration()","8c64eb4f":"switchCrowdState()","8c655550":"advisorsAllocatedAmount()","8c6589b2":"getLastSTCPrice()","8c65f15d":"clearBonuses()","8c662ffa":"LogCollect(address,uint256,uint256)","8c663229":"lastSellPrice()","8c663ffc":"getBounsWithRoundID(uint256)","8c66c9fc":"findBest()","8c66d04f":"setFeeCalculator(address)","8c66f294":"distributeFeeRewards(address[],uint256)","8c676aaa":"CUZ()","8c67f63a":"calculatePayment(uint256)","8c682bde":"setWinnerAndWithdrawAllFunds(address)","8c6838ba":"getPost()","8c68bc3e":"SetContractorManager(address)","8c69554d":"OwnerRefunded(address,address,address,uint256)","8c69930d":"getNewFallbackDepositEffectuation()","8c69c559":"Crypbest()","8c6aefcf":"chip(uint256)","8c6b6085":"supportNewVoter(address,address)","8c6ba233":"isLateBy(address)","8c6c8323":"buyTokens(address,address,uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","8c6f2ec1":"setCompte_17(string)","8c6fc437":"standardICO(string,string,uint8,address,uint256[],uint256[],address[2],address[])","8c701ba8":"releaseRoots()","8c717138":"lastBlock_a1Hash_uint256()","8c71bed2":"unlockTeamTime()","8c71eaf1":"TokenBEN(uint256,string,uint8,string)","8c71ec16":"create(address,uint256,uint256,uint256)","8c7229cb":"pantura()","8c727fa3":"oldCirculatingSupply()","8c72c54e":"publisher()","8c72d4a4":"getStageTokenAmount(uint256,uint8)","8c733fdf":"weiToUsd(uint256)","8c73596c":"init(address,uint8,uint256,uint256,uint256,uint32,uint256)","8c748334":"cancelBuyOrder(uint256,uint256)","8c74c5c0":"bonusOff()","8c74d62c":"LockedInToken()","8c7565dc":"ADChainGrants(bytes32,bytes8,bytes32,bytes)","8c756b1d":"balanceByAd(address)","8c7698df":"lowerCase(bytes32)","8c76b4b7":"addTrustedContracts(address[])","8c771a8e":"newEscrow(address,uint256)","8c787768":"abbcwalletcoin()","8c789fb2":"setTokenBudget(address,uint256)","8c794114":"prizeWithdrawal()","8c79a24d":"refName(uint256)","8c79ca5d":"AddMember(address,uint256)","8c7a63ae":"getTokenInfo(uint256)","8c7a8140":"extractVestedOptionsComponents(uint256,uint256,uint256)","8c7c35b9":"internal_tester()","8c7c4016":"GameLogicContract()","8c7c9e0c":"eth()","8c7d1e8a":"MyKillerContract()","8c7d3241":"total_iou_available()","8c7d58aa":"isTimeExpired()","8c7dd9ec":"_canReveal(address,address)","8c7e1227":"setupStakingPriceFeed()","8c7e5008":"maxDonationInWei()","8c7e763b":"HSCC()","8c7f7806":"AfeliCoinPresale(address)","8c7fcd46":"BLVToken(uint256,string,string)","8c80fd90":"setMinStake(uint256)","8c812c51":"PhoenixExchangeFund()","8c817b6e":"registered(uint256,address)","8c82790b":"getReg3()","8c82dccb":"updateStatuses(bytes32[])","8c832ef4":"GalaxyCoin(uint256,string,string)","8c849f3f":"getMemes()","8c864dfe":"_updateChecksum()","8c86ec20":"NMC(uint256,string,string)","8c877527":"allowTransfert()","8c87b2fc":"Identity(bytes32,bytes32)","8c882958":"LEToken()","8c88512f":"initializeCrowdsale(address)","8c88752a":"ContributorList(uint256)","8c8885c8":"setDecimals(uint256)","8c88b85f":"_finalizeRound()","8c88d716":"transferIfRequirementsMet(address,address,uint256,bool)","8c89b1c7":"setINCENTIVE_POOL_ADDR(address)","8c8a03ac":"setBucketManager(address)","8c8a261a":"devMiningRewardChanges(uint256)","8c8a40bd":"hashNotFound(address)","8c8b31ab":"dhanaToken()","8c8b6fc5":"challengeSubmitted(bytes32,bytes32)","8c8b802e":"getLimitPeriod()","8c8b9d54":"setEmployeeStorage(address)","8c8bc5ce":"ChangeICOStart(uint256)","8c8d067f":"chosenProposal()","8c8d2ede":"team1()","8c8d36c2":"THANKSTEST3()","8c8d98a0":"toTimestamp(uint16,uint8,uint8)","8c8df7cd":"GOTokenCrowdsale()","8c8e2478":"convertTokens()","8c8e5f1f":"BlockTubePrepaid()","8c8e8fee":"token_address()","8c8ee490":"checkReleaseAt(address)","8c8f94f5":"DeletePrice(uint256)","8c8f95fb":"lockFunds(uint256)","8c8f9c0e":"issueTokenToAddress(address,uint256,uint256)","8c8fc30b":"addAd(uint32,uint32,string,string,string,uint256)","8c907c0d":"LanderToken(uint256,string,uint8,string)","8c90b2ea":"pay055(address)","8c9151ae":"voteProposal(uint256,bytes32)","8c91bd3e":"addMoves(uint256,uint256[2])","8c91daac":"startRoundSeed()","8c920a38":"testSanityCheck()","8c924e9c":"incrementRead()","8c93256e":"transferReward(address)","8c934d71":"forceRefundCfd(uint128)","8c937da3":"WALLET_LB_TEAM()","8c9425e4":"privateLockAddress()","8c943b6c":"setDistrictCode(bytes32)","8c944339":"setActiveSkin(uint256)","8c944bb2":"_createPrimordialLot(address,uint256,uint256,uint256)","8c945d38":"takeOffItem(uint256,uint8,address)","8c94db38":"MMCoin(uint256,string,string)","8c9512bc":"companyTokens()","8c9515ea":"doPayouts(uint256[49],address[49],uint256)","8c9540d3":"isCommittee(address)","8c95acee":"getTreshold(uint256)","8c96a2c9":"getAssetPackPrice(uint256)","8c96a538":"COO_SHARE()","8c96e34b":"betIsSettled()","8c98117c":"getBill(uint256,uint256)","8c988a46":"isLinkedWallet(address)","8c9924d5":"AddrMarketing()","8c9a4f13":"FundsTransferred(address,uint256)","8c9ae56f":"QueryPlayerBonus(address,uint256)","8c9b2cd1":"ModultradeProposal(address,address,address)","8c9c2977":"newMember(uint8,bytes32,address)","8c9ce20c":"_addressNotNull(address,address)","8c9cf205":"SignVersion(string,string)","8c9d8300":"withdrawForAdmin(address,uint256)","8c9dd650":"Etherlott()","8c9e81e5":"triggerICOState(bool)","8c9ecd00":"toDec()","8c9f7074":"setInterestFeePercent(uint256)","8c9f7b39":"endSale(address)","8c9f8935":"ClaimSet(address,address,bytes32,bytes32,uint256)","8c9fcfe2":"payForUpgrade(address,uint256)","8ca0dd20":"tgeCap()","8ca10f9b":"sendRemainingTokens(address)","8ca17755":"etheraffle()","8ca17995":"divest(uint256)","8ca3b448":"addUser(address,address)","8ca3c553":"setData(string,string)","8ca47688":"WhiteListUpdated(address,bool,address)","8ca4eef6":"getBuild(bytes32)","8ca517dd":"getActiveBuyDetails(bytes32)","8ca51f82":"setMinimumClaimValue(uint256)","8ca5d525":"removeAllowedHICAddress(address)","8ca5da35":"mintManual(address,uint256)","8ca6c287":"InsurContract()","8ca6f747":"potatoBalanceOf(address)","8ca74163":"BZCToken(address,uint256)","8ca79351":"ethPriceIn()","8ca84d40":"preparationPeriodTrainingFeeMultiplier()","8ca9ac01":"LogBeerClaimed(address,uint256)","8ca9e721":"finalizeCrowdSale()","8caa0083":"teamCount()","8caa5c91":"DataBase()","8caaaae6":"totalWeiPrice()","8caaab4d":"verifyProofOfStakeInternal(uint256,bytes32,bytes32,uint256,bytes32[],uint256[],uint256,uint256)","8caad7b5":"changeMinDepositAmount(uint256)","8caba7b7":"startCharging()","8cac1939":"TOKEN_TEAM()","8cac3b42":"addDividend()","8cac5f55":"feeForTheStakingInterval()","8cad5826":"FundTransfer(uint256,bytes32,address,address)","8cadaa5d":"TokenFreeze()","8cadd6a2":"getVestedBalance(uint256,uint256,uint256,uint256)","8cae013e":"signatureFunc(bytes)","8cae1374":"editBlock(uint8,uint8,uint256,int8[5])","8cae59dd":"heapSort(uint32[])","8cae711f":"mintLiquidToken(address,uint256)","8cb09d4d":"GCTToken()","8cb0a511":"approve(uint256,address,uint256)","8cb18ef6":"needFightToAdult()","8cb1b614":"setWhitelisted(address,address,uint256)","8cb1e9c1":"unlockedAt()","8cb240b0":"saasPayment(address,uint256)","8cb36aef":"requestCoinToUSD(string,bool,uint256,uint256)","8cb3728c":"getAllRevisionTimestamps(bytes32)","8cb39385":"getMinBid()","8cb3c89f":"loadEthBalances()","8cb47a2f":"CrowdForceSampleToken()","8cb5497c":"setOperator(bytes32,bool)","8cb56999":"GetExpireTime(uint256,uint256)","8cb5a0c0":"removeCoordinator(address)","8cb858cb":"PRCVToken(uint256,string,uint8,string)","8cb996df":"LogMigrationEnabled(address)","8cbb02ad":"Marijuana()","8cbb13e7":"TokenRHT()","8cbb6593":"SHNZ2()","8cbba6cf":"isPreWhiteListed(bytes32)","8cbbe25f":"NIMFA_PER_ETH_PRE_SALE()","8cbc8c0b":"lockholderNumber()","8cbcbca2":"_payChicken(address,uint256)","8cbdf1d1":"mintARC(address,uint256)","8cbe775a":"Bitdepositary()","8cbe898d":"CommitteeLimits(uint256,uint256)","8cbeb340":"ControlContract(address)","8cbf4145":"confirmPrintProxy(bytes32)","8cbfa1ec":"quoteAsk()","8cc02403":"cobrarImpuesto(uint256)","8cc04ebb":"_appendUintToString(string,uint256)","8cc17117":"forceRecoverCollateralInternal(address)","8cc2f547":"DiceGameCrowdsale(address)","8cc30c6f":"buyStageDataRecord(uint256,uint256,uint256,uint256)","8cc34ed7":"zilla_remaining()","8cc40d71":"dividend_amount()","8cc4ab11":"getPurchaseTimestampEnds()","8cc50ecd":"addBlock(string,uint256,string)","8cc519bf":"companyTimelock()","8cc51eda":"kitties(uint256)","8cc5510f":"setTeamAddress(address,bool)","8cc55473":"bulkTokenMint(address[],uint256[])","8cc57368":"getUserTokens(address,uint32)","8cc5cde2":"isLunyrToken()","8cc5e56e":"revokeLockByIndex(address,uint256)","8cc60a61":"isStoreActive(uint256)","8cc60eca":"SS()","8cc63bfb":"marketingFunds()","8cc6acce":"updateConfig(bytes)","8cc78a40":"option20symbol()","8cc7ea0e":"Xian()","8cc89e1b":"TCCoin()","8cc8baaf":"getBuyPriceTimes()","8cc8c236":"_transfer(address,uint256,bytes)","8cc9638c":"fundBurn(address,uint256)","8cc98bc3":"approveEliminate(address,uint256)","8cc99aa3":"getAmountForCurrentStage(uint256)","8cca5a3f":"withdrawWallet(address)","8cca8f64":"canClaimRefund(address)","8ccb381b":"tenthTotal()","8ccb4daf":"getPositionMaxDuration(bytes32)","8ccb59e8":"revealWinner(uint256)","8ccb9f2d":"del_admin(address)","8ccbd6da":"freezeToken()","8ccc04ea":"proofOfConceptCap()","8ccc4781":"Math(int256)","8cccc341":"initiateChallenge(address)","8cccf2df":"viewServiceReward()","8ccd227c":"gameRequestTokens(address,uint256)","8ccdcf80":"tokenSalePausedTime()","8cce10c8":"rank(address,address,uint256)","8cce49c9":"mokenData(uint256)","8cce7e92":"removeMarketFromWasCalled()","8cceb1e8":"notifyBurn(address[])","8cd0a573":"transferWithCustomReserving(address,uint256,uint256)","8cd0fc3d":"TRONClassic(uint256,string,string)","8cd221c9":"roundId()","8cd25904":"calculateAndCreateTokens(uint256)","8cd3751b":"newProposal(address,uint256,uint256,bool,bool,address,uint256,uint256,uint256,uint256)","8cd3f064":"acceptToken(address)","8cd41fae":"StartCompetition(uint8,uint8,uint8,uint8,uint80,uint32)","8cd41fd8":"referrerBonus2()","8cd42991":"getTimeRemaining(uint256)","8cd47415":"zkWithdrawTrusted(bytes32,uint256,address,uint256[2],uint256[],uint256[],uint256[],uint256)","8cd4d21a":"x(uint256,address)","8cd4fdf1":"maxGamble()","8cd53767":"withdraw(bytes32,address,address,uint256,uint256,bytes32,bytes,bytes,bytes32)","8cd5dce3":"setNextRoundRequiredBetAmount(uint256)","8cd6c7fa":"seedSingleSaleCount()","8cd70e72":"isInitalized()","8cd85846":"totalTranches()","8cd85dc2":"getWinNumbers(uint256)","8cd8bd05":"IanCoin()","8cd8db8a":"init(uint256,uint256,uint256)","8cd90e31":"EAToken(uint256,string,uint8,string)","8cda2a15":"SafePromo(string,string)","8cda4430":"lookupRoyalty(address)","8cdb1719":"approveCertification(uint256)","8cdbd8fb":"remainToken()","8cdc86a6":"sort()","8cdcbdef":"closeBlock()","8cdcdae1":"testControlUpdateLatestRevisionNotOwner()","8cde43dc":"getCrowdsaleMaxRaise(address,bytes32)","8cde4667":"BANKNET()","8cdf31fa":"Cryptoya()","8cdfb1e6":"transferIfHF(address)","8ce0080f":"updateGuMasks(uint256,uint256)","8ce05b54":"bornFamedStar(address,uint256)","8ce060fb":"FounderSwitchRequestEvent(address)","8ce0bae8":"Canceled(address,uint256,address,address,uint256,address,uint256,uint256)","8ce0bd46":"Deposit(address)","8ce113dc":"right60(uint256)","8ce187fd":"raisedUSD(uint256)","8ce25a93":"numAccounts()","8ce2ae2d":"creator_new()","8ce2e0ea":"addLastTwoAmbassadors(address,address)","8ce2f386":"AcceptsOmniDex(address)","8ce3ee62":"transferEmpire(address)","8ce450de":"assetThaw()","8ce4f1b2":"setGasRewardPercent(uint256)","8ce53e5b":"getMaximumInvestmentPerDay()","8ce5877c":"removeSpender(address)","8ce69b72":"USD_IN_ETH()","8ce74426":"protocol()","8ce795f5":"SerbiavsBrazil()","8ce7be01":"getUniqueSpinnerPrice()","8cea577a":"allowFunction(bytes32,bytes4)","8ceaa23f":"setAvailablePositions(uint256)","8cead4bf":"currentProfit()","8cec9176":"SimpleMultisigWallet(address[],uint256)","8cecd03e":"INVESTOR_TOKENS()","8cece594":"countClaimBackers()","8cecf66e":"_inverse(uint256)","8ceda04d":"getCounting(bytes32)","8cee8778":"crear(uint256)","8ceeaaa8":"getTodayOwnerAddress()","8ceedb47":"cage(uint256,uint256)","8cef1ed9":"xpectoTTF1Token()","8cef2b93":"CECNaypyidaw(address,uint256)","8cefad63":"setAirEndtime(uint256)","8cefaf1a":"setSalesEndTime(uint256)","8cf0c191":"rum()","8cf19975":"createLottery(string,uint256,uint256,uint256,uint256,uint256,uint256)","8cf1c5c4":"LogFeeEvacuation(uint256)","8cf20038":"engDevAddress()","8cf228cd":"DNNTDE()","8cf3313f":"calculateWeightedMultiplier(uint256,uint256,uint256,uint256)","8cf3562b":"DEC15Recursive()","8cf37ece":"InformRebuy(uint256)","8cf39a9c":"TicTacToe(address,address,uint256)","8cf3a181":"addRRA(address)","8cf3e683":"isAddressExcept(address,address)","8cf49cad":"ReleaseDate()","8cf4dbfb":"collectBalance()","8cf57cb9":"rewardAddress()","8cf5dbc6":"recruitHero()","8cf7b7a4":"slashAddressLikeUsername(string,uint256)","8cf7d906":"playAndFinishJackpot(uint256,uint256,uint256,uint256)","8cf80438":"winningBid()","8cf8151f":"appWasMade(bytes32)","8cf907fb":"EndRefund()","8cf92ade":"distributeBountyTokens(address[],uint256[])","8cf9f5e7":"getPreSelledInPool()","8cfa8eea":"getWeiToUsdExchangeRate()","8cfaabcc":"managementTransfer(address,uint256)","8cfae7e4":"TransferUnsoldTokensBackToTokenContract(address)","8cfb3088":"defaultExpiry()","8cfb7c02":"updatePopularity(bytes32,uint256)","8cfd6d4c":"CCH_LLV_FIFA_2()","8cfd8901":"_incBlock()","8cfdacb0":"STARTING_PACIFIST()","8cfe6a09":"tokensToEthereum_2(uint256)","8cff1990":"isSignedByAndrey()","8cffa21c":"getOwnedItems()","8d000903":"createTokenToMarket2018()","8d008989":"Multisig(address,address,address,address)","8d00abb6":"setAElfCommunityMultisig(address)","8d012295":"presaleVesting(address,uint256,uint256,uint256,uint256,uint256)","8d0128cb":"transferMintKey(address,int256)","8d01308c":"PRESALE_START_WEEK3()","8d03b102":"testing()","8d044c06":"unpauseRedemption()","8d049190":"mapWidth()","8d0515dc":"HenryMiniToken(uint256,string,uint8,string)","8d0522c5":"set_contrib_arbits_max(uint256)","8d0528ec":"Withdraw_referral()","8d05ad4e":"NLL()","8d062046":"testTokensAreTransferrableAfterSale()","8d068043":"requiredSignatures()","8d0716c4":"approveScoupons(address,uint256)","8d07ae9f":"getBidDetails(address)","8d086da4":"withdrawShares()","8d089930":"limitEndDate()","8d08eefa":"setCORAddress(address)","8d09b9cc":"TeCToken()","8d09c674":"Donated(address,uint256,uint256,uint256)","8d0a3b6d":"bonusByAmount()","8d0a5fbb":"getOrderCount()","8d0a73e3":"tokenDistributionStartTime()","8d0aadca":"playerDelayOnExit(address)","8d0ae472":"AsheToken()","8d0b3d9b":"_add(uint32,address)","8d0b4be5":"setXPContractAddress(address)","8d0bba03":"MINIMUM_CONTRIBUTION()","8d0caef5":"bonusStage1()","8d0cf786":"MatchAdded(uint256,uint8,uint16)","8d0d018c":"havedDistDevCoin()","8d0d27ba":"queryPlayerType(uint32[11])","8d0d3ccf":"getBonusTier()","8d0d877f":"LZZ()","8d0dd3c0":"setBUU(bytes32,uint256,uint256)","8d0e5136":"isPlayerInQueue(address)","8d0eda03":"isInvestorLocked()","8d0f403a":"adminAddAction(bytes32)","8d0f8cef":"drop(address,uint256)","8d0fc05a":"votesYes()","8d10215e":"grantAccess(uint256,uint256,string)","8d106690":"setPropertyFlag(uint16,uint8)","8d111ac6":"checkTokSold()","8d119d41":"AngelCoinV1()","8d121247":"changeProductionFeeRecipient(address)","8d12aba7":"IMCOToken()","8d134175":"CellTokens()","8d1343e0":"issueDate()","8d13d972":"getUsdFee(bytes32,uint256)","8d13ea34":"changeUserProjectExp(bytes32)","8d14670a":"multiUnlock(address[])","8d149b3c":"compareInts(int256,int256)","8d152d78":"pushBytesArray(bytes32,bytes32)","8d1540c1":"CoinBuy(uint256,address)","8d159787":"buyDragon(uint256)","8d15a218":"LogRedeem(address,uint256)","8d15b307":"privateEventActive()","8d16fd83":"sellDai(uint256,uint256,uint256)","8d17664d":"getSecret(uint256)","8d182f01":"removeSale(bytes32)","8d1a4b28":"getGame(address)","8d1a7765":"getPlayerGeneral(uint64)","8d1bc93d":"buyWuxiaMaster()","8d1c3b8b":"sHasDownvoted(uint256,uint256,address)","8d1c8048":"transport(uint256)","8d1ca4ec":"addGuess(int256)","8d1d1572":"transferFeeAddress()","8d1d22d8":"renameMonster(uint64,string)","8d1d2c21":"categoricalEvents(bytes32)","8d1d8639":"getcanuserun(address)","8d1dff6b":"mintTokens(uint256,address,bool)","8d1e6b56":"issueCompanyTokens()","8d1eaf78":"registrarInfo()","8d1fdf2f":"freeze(address)","8d20194d":"getWhiteUsersFrom(uint256,uint256)","8d215adc":"Bettings(uint256,uint256)","8d216186":"roll(uint256,bytes32)","8d22651e":"MAX_NUM_OF_CHOICES()","8d227fc0":"getPeriodInfo()","8d22b345":"getAppTokenCode(uint32)","8d24abbc":"closeAndTransferTokenOwnership()","8d24d147":"rvDeposit()","8d24f5bc":"tokensByBtcTx(string)","8d256b0a":"ExchangeRate(uint256)","8d258104":"setManager()","8d25827a":"countOpenPackageOfOneAgency(address)","8d259d65":"_sellCallToOpen(uint256,uint256,uint256,uint256,address)","8d25af04":"restartGame()","8d26d88f":"feeWithdrawTokenAmount(uint256)","8d26eb2b":"edgePigmentG()","8d272b0a":"TaeCoin()","8d2810fe":"GenesisBuyPrice(address)","8d288e93":"toRefund()","8d28da21":"ECT(uint256,string,uint8,string)","8d298851":"initialIssue()","8d29a239":"finalizeHoldingAndTeamTokens(uint256)","8d2a0910":"getTotalDividendsPaid()","8d2af65d":"claimTokenReserveFinan()","8d2c8ce8":"RrcToken()","8d2c929a":"bridgeNodes(address)","8d2d2563":"saleFirstEarlyBirdEndBlock()","8d2d3f41":"getKeyRevisionNumber(uint32)","8d2dcb2d":"TokenPool(address,address)","8d2ea8dc":"withdrawAvailableToken(address,address,uint256)","8d2f349f":"TransCompleteds()","8d2f7272":"CariToken()","8d300458":"updateInvested(address,uint256)","8d30241b":"HasGoods(uint32)","8d30d418":"ContractRemoved(address)","8d30e65d":"claimReservedTokens(address,uint256)","8d3121b3":"releasedTokenTotal()","8d317de2":"OctusToken()","8d323fdc":"LogAddressTokenCapChange(uint256,string)","8d331996":"setTimeWindow(uint256)","8d334529":"restrictions(address)","8d348b7c":"mintToClient(address,uint256)","8d357fa3":"getKeys(uint256)","8d35b9ce":"ARXpresale()","8d361e43":"removeSigners(address[])","8d361f6e":"bonusTokensDistributed()","8d375da2":"testMakeItFail()","8d37f52c":"addAgingTime(uint256)","8d38b237":"calculateCountOfInvestmetnsInQueue(uint256,uint256)","8d38f5a0":"Burn(address,uint256,bytes)","8d3945e4":"setCounter()","8d3965be":"buyerApprove(uint256,bytes)","8d3972d5":"FABIToken()","8d399ce3":"submit(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[])","8d3a5ded":"initPlatinum()","8d3af7eb":"withdrawLemontokens()","8d3b6d08":"registerSsp(address,uint8,uint16)","8d3bd1f8":"teamTokensGenerated()","8d3c7415":"JuzixTokenManager()","8d3d523b":"bet2Of(uint256)","8d3d6576":"maxContribution()","8d3d70df":"takeBet(uint256,address,uint256,uint256)","8d3d8587":"GanaPreSale(address,address,address)","8d3def46":"oryza()","8d3ef87d":"getuserlistlength(address)","8d3f0ed5":"allocateTokens(address,uint256,uint256)","8d3fd859":"sellFucks()","8d442ae0":"toUint8(bytes,bytes,uint256)","8d447e39":"getLatestWhitepaper(address)","8d44c90b":"BurnMyTokensAndSetAmountForNewBlockchain()","8d44f13b":"claimFromPool()","8d4572be":"rens()","8d45e221":"Partial23Transfer()","8d467f22":"getKeysFromEth(uint256,uint256)","8d472709":"contribute(address,address,uint256)","8d475461":"m_teamId()","8d4777c8":"claimGooDepositDividends(address,uint256,uint256)","8d47c7d7":"getTokenListed()","8d498158":"DaleoneToken()","8d49cd7f":"getTeam(uint32)","8d49da75":"stopCollection()","8d4a2d39":"addSeconds(uint256,uint256)","8d4d801c":"addRecipient(bytes32,string,string,address)","8d4d8e19":"unregisterAsDelegate()","8d4e4083":"isFinalized()","8d4e57e6":"ROLE_TOKEN_CREATOR()","8d4ea1ba":"addEtherForOraclize()","8d505019":"addNote(bytes32,string)","8d50b6d0":"doSelectDisputedStateRoot(uint256,bytes32,uint256)","8d51faec":"setOwnerTestValue(uint256)","8d521149":"bonus_received()","8d52a1fc":"setStrikePrice(uint256,uint256)","8d539b35":"resetPendingContribution(address)","8d53b208":"revokeAccess(bytes32,address)","8d551860":"horseNotForSale(uint256)","8d553538":"addSecondaryRecord(string,bool,string,bool,string,string,string)","8d5555f2":"priceFor(uint256)","8d55719e":"_withdrawEther(address)","8d55b6ac":"thirdRate()","8d56ac74":"REALEX()","8d56bc62":"Bankroi()","8d574383":"setDemurrageFrequency(uint256)","8d578bee":"totalSaleCap()","8d5802e2":"getAssetOwner(uint256)","8d59cc02":"register(address,string,string)","8d59d1f1":"donate(uint256,string)","8d5a225e":"assignReserveSupply(address)","8d5c4456":"pIndex()","8d5c84cd":"isStart(bytes32)","8d5cc102":"traded_token()","8d5ceeca":"checkShares(address)","8d5d1e97":"priceStar3()","8d5d88c9":"LTYG()","8d5dee05":"EGGS_TO_HATCH_1TURTLE()","8d5e4f9c":"BroFistCoin()","8d5f3f96":"nextInvestorsProfitSum()","8d5f8d1c":"forwardFundToCompanyWallet(uint256)","8d5fa05c":"setAreas(address,uint256)","8d6014a8":"FixedCeiling(uint256,uint256)","8d60be98":"ICO_TOKENS_PERCENT()","8d60e30b":"reward(address,uint256,bool,string)","8d60ed85":"setDevCutPercentage(uint256)","8d614474":"AdvancedEthVocToken(uint256,string,string)","8d622749":"award(address,address,string)","8d627e91":"isTryedFinishCrowdsale()","8d62b845":"isMakersSignatureValid(address,bytes,string,address)","8d63c77b":"WizardReplacedEvent(address,address)","8d63cfa7":"getPixelOwner(uint16,uint16)","8d647185":"setBaselineRate(uint256)","8d647d3a":"allowPrivateParticipant(address,uint256)","8d64bcf1":"maxWhitelistPurchaseWei()","8d65095e":"PI_EDIT_3()","8d656b83":"minWeiInvestment()","8d664d6a":"setFeeRates(uint8,uint8,uint8)","8d670a2e":"unlockPlayerFunds(address)","8d6731b0":"LudumToken()","8d688b6e":"EthPyramid()","8d68cf59":"sendFunds()","8d69121d":"addDocument(bytes32,string,string)","8d69ca74":"wdEthereum(uint256,address[])","8d69e95e":"serviceProvider()","8d6a2ed5":"minimumBuyAmount()","8d6a6d4b":"_allocatePromoTokens(address,uint256)","8d6a6fbd":"proxyTransfer(address,address,uint256,bytes,string)","8d6b5d3e":"getScouponAllocationFactor()","8d6c58ab":"isTransferToICAPAllowed(address,bytes32,uint256)","8d6cc56d":"updatePrice(uint256)","8d6cd879":"FOUNDATION_STAKE()","8d6cd8de":"buffPtr()","8d6e56e1":"manyInputsNoReturn(uint256,uint256,uint256,uint256)","8d6f24d4":"hash_msg()","8d702122":"ownerKill()","8d70650f":"getSiteId(uint256,uint256)","8d70baaa":"BattleOfTitansToken()","8d70c0ce":"transferToExchange(address,uint256,uint256)","8d7108e5":"isValidLocation(uint8,uint8,int8[5],int8[24])","8d711776":"sendCrypto(address,uint256)","8d7117d4":"etherRatio()","8d715d9d":"Backdoor()","8d71f131":"TOKEN_RESERVE2_CAP()","8d72920b":"getAllowedAmountToContribute(address)","8d72a473":"deductFunds(address,uint256)","8d72f856":"deleteVip(uint256)","8d734b30":"setupMintableAddress(address)","8d73c027":"mintWithApproval(address,uint256,address)","8d747928":"isDrivezyPrivateTokenAcceptable()","8d748148":"monitor(address,bool)","8d74fd52":"GlobalTourToken()","8d75533f":"mint(address,string,bytes)","8d7570fc":"doBurn(uint256)","8d75fe05":"mintedTokens()","8d7601c0":"addResolvers(address[],uint256[])","8d77090f":"TriggmineToken()","8d776457":"sellBNT(uint256)","8d78c90b":"EventUpgrade(address,address)","8d79283d":"query1_fnc()","8d792964":"TD(uint256,string,string,uint8)","8d7a55bf":"PubKeyHashTypeAdded(uint8)","8d7af473":"numberOfProposals()","8d7b5243":"minerTotalReward()","8d7cdcf4":"setLLV_edit_8(string)","8d7cffb7":"transferWrappedContractAdmin(address)","8d7d2e5b":"minerPreSupply()","8d7daf95":"isTokenPairWhitelisted(address,address)","8d7e5be0":"getClue1()","8d7e7958":"userGrowsPoolSupply()","8d7e8a57":"approveSpenders()","8d7eca6f":"FUNDING_END_TIMESTAMP()","8d7f26e9":"setIPAddress(bytes32,bytes32,address)","8d7fe693":"Helios()","8d8001ad":"updateMintingStatus(uint256)","8d809b0e":"project_wallet()","8d80c34e":"unblockAccount(uint256)","8d80c922":"getAddressById(uint256)","8d81a1ce":"setClamTax(uint256)","8d81a88f":"BP_ATHENIAN()","8d81e2c0":"getTankTotalEarned(uint32)","8d81f51e":"safeTransferChild(uint256,address,address,uint256,bytes)","8d822615":"setFeeForArtWorkChangeRequest(uint256)","8d835674":"euroRaised(uint256)","8d837f38":"getEthBalTeller(address)","8d83cc95":"getNextSnapshotBalanceOfMul(address[])","8d842fad":"stopPreICO()","8d84a7fd":"credit(string,uint256)","8d854fde":"getDisputeId()","8d859f3e":"PRICE()","8d85a70f":"Vote(address,uint256,bool)","8d860880":"CheckOut()","8d86484c":"setPercentUnfrozenAfterAwardedPerPeriod(uint256)","8d8660bc":"setQuantity(string,int256)","8d86faa6":"getAmountToGive(address,address,address,uint256,uint256,uint256,uint256,uint8,bytes32,bytes32,uint256)","8d87b102":"amountOfStakeToBeReturned(address,uint256)","8d8833bf":"periodPreITO_wei()","8d89873c":"updateAndGetRemaining()","8d8a7f07":"VLBRefundVault(address)","8d8acee9":"setupMultisig(address,address)","8d8b1b88":"mixGenes(uint256,uint256)","8d8bd44f":"TokenSaleFinished(string,address,uint256,uint256,uint256)","8d8c36e9":"purchasedBy(address)","8d8d22ba":"changeServiceAddress2(address)","8d8d50d0":"createUnicorn()","8d8d92fa":"theBid()","8d8e2ea9":"Tablow()","8d8e4561":"theGrid(uint256)","8d8e5da7":"emergencyWithdrawal(address,address,uint256)","8d8f2adb":"withdrawTokens()","8d8f7780":"GEE100()","8d8f95d1":"collectDrugs(address)","8d909ad9":"getSeedAndState(string,address)","8d91801a":"RxEALTestSaleContract()","8d91931f":"longLock()","8d91e803":"buyWhiteCore(uint256,uint256,uint256,uint256)","8d920b02":"rejectPayment(uint256)","8d927069":"getTrace(uint256)","8d927b34":"maxPendingBalances()","8d928af8":"getVault()","8d92910c":"isLegalAttack(uint256,uint256)","8d92c187":"testFinalize()","8d92ce46":"submitBlockHeaders(bytes)","8d92fdf3":"withdrawAsset(uint256)","8d93758e":"PRESALE_STAKE()","8d93eac2":"mintFeeNumerator()","8d93ec88":"poolWallet()","8d94053f":"verifyAutoridadElectoral(bytes32)","8d949635":"endRefundableTime()","8d949c8b":"D(uint256)","8d956f1e":"tokenTransfer(address)","8d95f245":"sellkey(uint256)","8d976d76":"investCommission()","8d977672":"tasks(uint256)","8d977d9e":"checkGameClosed(address)","8d98ee43":"_verifyAddress(address)","8d98f4e3":"getAllCardsDefence()","8d9940b9":"createRetainer()","8d995f94":"transferAndFreeze(address,uint256)","8d99b2eb":"endPoll()","8d9a7b49":"pricePerMessageChanged(uint256,uint256)","8d9ad08e":"getAllInvestments()","8d9afc0f":"getStageId()","8d9b449b":"addRevenueShareCurrency(address,string)","8d9d851c":"toggleVaultStateToAcive()","8d9e6e47":"setFinalICOPeriod()","8d9e8a76":"CMGG12StandardToken(uint256,string,uint8,string)","8d9efa3f":"LogPhaseSwitch(uint8)","8d9f39d1":"_clear(uint256)","8d9f95c4":"PresaleEntry(address,uint256)","8da03997":"getNativeReputation(address)","8da15531":"SimpleCoinToken()","8da16e48":"geraHash(string,string)","8da198cd":"simpleAssert(bool)","8da1e722":"minGamePlayAmount()","8da2a2a1":"reserveDistribute()","8da2defb":"WE(uint256,string,uint8,string)","8da2fc26":"Burn(address,uint256,uint256,bytes)","8da3d736":"addToList(uint256,address[])","8da46db4":"DistributeXcel(address)","8da4d3c9":"claimCount()","8da4d776":"newCommune(address)","8da58897":"starttime()","8da5cb5b":"owner()","8da5fd77":"unlockSecondaryTokens()","8da66e67":"LogCollectAmount(uint256)","8da76874":"mintFromTrustedContract(address,uint256)","8da7d0b5":"totalChildContracts(uint256)","8da8023c":"endTimeOfStage(address,uint256)","8da8524f":"LogFrozenStatus(bool,uint256)","8da87ac6":"addressFundPlatform()","8da8a5ae":"nativeBlockhash(uint256)","8da8f235":"_addController(address)","8da91d04":"unset(uint32[])","8da9b772":"getHello()","8daaaa2f":"HOUSE_EDGE()","8daaf0a2":"addTokens(address,address,uint256)","8dab38da":"BONUS1_LIMIT()","8dac0e8c":"GetEtherPrice()","8dac7191":"initialTokenOwner()","8dad52f4":"dive4(address)","8dae3d68":"awardLuckyCoin(uint256,uint256)","8dae5adc":"FundTransfer(address,address,address,uint256)","8dae9364":"_stakeAmountValid(address,uint256,uint256,bytes8,uint256,uint256)","8daed4c4":"allocateShareholder(address,uint32)","8daf08d9":"requestStempas(bytes32,address)","8daf4dcf":"getTournamentRate()","8daf5033":"TokenPurchased(address,address,uint256,uint256)","8db02d79":"Tiguan5Coin()","8db0816a":"claimC2()","8db0e83b":"getBytesArray(bytes32)","8db1296d":"token_creation_cap()","8db1ccac":"PUBLIC_SALES_1_RATE()","8db23385":"balanceOfTotalUnclaimedCookie()","8db261e0":"hardWithdrawAll()","8db49b57":"GrantDeleted(address,uint256)","8db4dad2":"contractSignedTime(string)","8db517fb":"GMQToken(uint256,string,string)","8db518f3":"ContractiumToken()","8db54c90":"getTotalSendingAmount(uint256[])","8db57994":"fundLoan()","8db6c17e":"ISCoin()","8db7183a":"dateMarketing()","8db783ce":"addHourToProject(uint256,uint256)","8db78a37":"setBountyVault(address)","8db7cd54":"getTournamentEntranceFee()","8db8053b":"mintPresaleTokens(uint256)","8db8f8bc":"ELACoin(uint256,string,string)","8db9653f":"getTotalIssued()","8db974e4":"optionTotalSupply()","8db9c13c":"removePolicy(uint8)","8dbb908a":"clearAllrequest()","8dbbbe10":"getFeeTake(uint256)","8dbc2fd1":"setNewEndtime(address,uint256,uint256)","8dbd7d54":"addCashier(address,address)","8dbdfae7":"referalBonusPercent()","8dbe3be5":"isCeilingStrategy()","8dbe6c33":"_setUserInfo(address,uint256,uint256,address)","8dc01209":"CJC()","8dc07e46":"picops_is_enabled()","8dc1c44d":"testFailCreateWithParentSameNonce()","8dc2a2cd":"GMCCERC20(uint256,string,string)","8dc401ae":"withdrawAllDevelopersCut()","8dc43256":"AFRTokenERC20(uint256,string,string)","8dc45377":"getDuel1(uint256)","8dc4c6ab":"recoverable(address)","8dc6af54":"UsdToTokenConvert(address,uint256)","8dc6e2f1":"onMarketFinalized()","8dc71928":"minimumTargetReached()","8dc73521":"clearLock(address)","8dc850dc":"currentCoinsCreatedInteger()","8dc889f6":"requestDisbursement(uint256)","8dc949e8":"SapienToken()","8dc95182":"AssignWhitelistManager(address)","8dc9650f":"claimdram()","8dc98851":"Billboard()","8dca05c9":"airFropPot_()","8dca5511":"usdPerEve()","8dca7a01":"unicornManagement()","8dcb25e0":"balanceOf2Internal(address,address)","8dcb8c21":"coinsFlipped()","8dcd555f":"_buyNextRank(address)","8dcd64cc":"createAndEndowD(uint256,uint256)","8dcd992e":"_setBabzBalanceOf(address,uint256)","8dcdfe12":"distributeCrowdsaleTokens(address,uint256,uint256)","8dcf7892":"setAllocateTokenDone()","8dcfdaad":"removeMany(address[])","8dcff4f9":"setupAssetOwningListener(address)","8dd05b56":"getImageDataLength(uint256,uint16)","8dd14802":"setBridge(address)","8dd1e732":"YYBToken()","8dd1e96c":"getAngelFundAddres()","8dd21b0f":"redTeamLockingPeriod()","8dd3c196":"addInvestment(bytes32)","8dd42808":"removeHolder(address)","8dd47d91":"Wthdraw()","8dd4f292":"getRemainingSellingToken()","8dd5ac24":"SaveToken()","8dd5e298":"canEnterPool(address)","8dd66012":"incChildren(uint256)","8dd6908e":"ambassadorMode()","8dd6ce79":"setRatePrices(uint256)","8dd745bb":"adminSendTokens(address,uint256,uint256)","8dd747ec":"balanceOfKyCToBeApproved(address)","8dd7d6d1":"newPuppet()","8dd7e44b":"withdrawalComplete()","8dd8596c":"sendDonation()","8dd9054b":"MATCoin()","8dda811c":"GameChannelBase(address,uint256,uint256,address,address,uint256)","8ddab3dc":"_preValidateRefill(address,uint256)","8ddab515":"MedicayunLink(uint256,string,string)","8ddb428a":"currentGeneration()","8ddc9aa7":"UpgradeProposed(address)","8ddcf81e":"get_deal_status(uint256)","8dde60fa":"transferCoin(address,uint256)","8dde907e":"FooBurnableToken()","8ddf52bd":"earlyContribShare()","8ddf792b":"setOraclizeGasLimit(uint256)","8de022b7":"dropAnchor(uint16,uint16)","8de04f87":"authorized_updateCardReserved1(uint256,uint8)","8de0ece7":"THEWOLF10XToken(uint256,uint256,uint256,uint256,address,address,address,address,string,uint256)","8de12845":"init(string,string,string,string)","8de1dcea":"rateAngelsDay()","8de21650":"getBooleanValue(string)","8de2947c":"chkLockedTokens(address,uint256)","8de2a051":"setUint(uint256,uint8,uint16,uint32,uint256)","8de3317d":"withdrawDRPU(uint256)","8de4f42f":"addNewAirdrop(uint256,string,uint256,address)","8de5104b":"startPreICOStage2()","8de575e4":"Veen()","8de69284":"subscribe(address,uint256)","8de69c3c":"AcceptsDailyDivs(address)","8de69f66":"allocateAdvisorTokens(address[],uint256[])","8de6b343":"deleteFromBlacklist(address)","8de74aa1":"setEstateRegistry(address)","8de85908":"ProjectCall(address,uint256)","8de8d47c":"sendObjectWithoutApproval(uint256,address)","8de8de61":"CC5Coin()","8de93222":"purchase(address,uint256)","8de9ee05":"TakeBuyOrder(bytes32,address,uint256,uint256,uint256,address,address)","8dea60cc":"CryptopediaCoin()","8dec1720":"invites(address)","8dec3daa":"destroy(uint256,address)","8dec818a":"LogPaused(bool)","8dede3f5":"pendingInvestContractsIndices(address)","8dedeca8":"costAndBuyTokens(uint256)","8dee53b9":"setBoardMember(uint256,uint256,uint256,uint256)","8def14f3":"ether_per_token()","8def1d3b":"distinctInvestors()","8def32b6":"addOrderBatch(bool[],uint128[],uint128[],uint32[],int256,bool[])","8defbc5e":"right31(uint256)","8df068ab":"initialTransferToDevTeam()","8df0fda1":"isApplicationExits(string,string)","8df10469":"refundInvestor(uint256)","8df15e19":"tokenLock(address,uint256)","8df1a8db":"ENJAllocation(address)","8df208b7":"StopQ()","8df272d2":"CosmoCoin(address,address)","8df301aa":"tradeKyber(address,uint256,uint256,address)","8df35abe":"setManagerAndClaimer(address,address)","8df388c1":"totalUnvestedAndUnreleasedTokens()","8df3a24c":"canAcceptBuyNow(uint256,address)","8df41c32":"allocationAddressICO()","8df465ea":"Zendad()","8df48935":"uncooperativeClose(address,uint32,uint192,bytes)","8df4d225":"GLXChain()","8df554b3":"Dividend()","8df583bd":"exchangeBBDBalance()","8df5fc7a":"_RewardClaimed(address,uint256,uint256)","8df61294":"totalAmountOfOrders()","8df6ad66":"isArrAccountIsNotFrozenForReturn(address)","8df6af63":"setCHGUSDPrice(uint256)","8df793d6":"leaseCard(uint8,string,string,string)","8df8228c":"x888()","8df87c66":"_getTokenLockType(uint256)","8df8ac87":"recevedTokenFromEvabot(address,uint256)","8df8c008":"getFreeTurtles()","8df8cc4c":"_removeOperator(address)","8dfa6fcb":"endTimeAddBonus()","8dfa703f":"BitkerToken()","8dfaf7f0":"getTeamsInfo()","8dfb015f":"increaseInvestedWei(uint256)","8dfb04fe":"getExistCell(address)","8dfb9950":"transferTokensManually(address,uint256,uint256)","8dfbcf36":"addCapper(address)","8dfced82":"amountBonusEnabled()","8dfd1242":"updateStarScoreInBulk(address[],uint256[])","8dfda5ae":"getIndexByAddress(address,address)","8dfde39d":"abi(bytes32)","8dfef745":"bonussale_StartDate()","8dff1762":"RpsGame()","8dff4abd":"activateRevenueShareIdentifier(string)","8dffe343":"kvcDiv(uint256,uint256)","8dffe5c0":"buyPlace(uint256,string)","8dfff9f2":"changePrepaymentFee(uint256)","8e005553":"setFee(uint16)","8e006db0":"setProductStock(bytes32,uint256)","8e007cfa":"giveEthxAddress()","8e008b59":"_createTeam(address,uint32[])","8e01d34b":"AddGoods(uint32,uint32,uint256,uint32,uint32,uint32,uint8,uint8,uint8)","8e0273bb":"Existing(address)","8e0294a8":"_removeProposal(address)","8e035ac1":"BetOnHashV82()","8e045031":"isTokenCollected(uint256,address)","8e048315":"investorDeposit(address,uint256)","8e0488a8":"transferirSalaDePara(address,address,uint256)","8e04977d":"currentLotteryValue()","8e056fe6":"setBirthBlock(uint256)","8e05beb3":"token(bool,address,address,address,address,address[],uint256[])","8e05d59d":"signToApproveTokenControlInfo(uint256)","8e05d8a5":"_computeNextGen0Price()","8e068b11":"virtualReserveBalance()","8e07d7da":"confirmKittyActions(uint256,uint256[8])","8e082555":"changeOwnship(address)","8e08b2ec":"MinesOnTrade(uint256)","8e08cf38":"updateBonus(uint256,uint256,uint256,uint256,uint256)","8e09c8cd":"addCallSpenderWhitelist(address)","8e09ead7":"isTokenBankroll(address,address)","8e0a5faa":"invariant(address)","8e0adbf5":"getLLV_edit_11()","8e0af993":"setPrivateFund(address,uint256,uint256)","8e0b017d":"setSellRate(uint256)","8e0bba69":"iown()","8e0c2882":"drain_alltokens(address,uint256)","8e0c36c4":"verifySeed(bytes32,bytes32)","8e0c8999":"zkWithdraw(bytes32,uint256,address,uint256[2],uint256[],uint256[],uint256[])","8e0d5075":"claimDividendsForBlock(uint256)","8e0db0d9":"keyAtIndex(uint256)","8e0e8fb2":"approveProvider(address,uint256)","8e0ea5cf":"ReturnTokensFor(address,address,uint256)","8e0eef8e":"getTicketValue(uint256,uint256)","8e0ef033":"defrostTokens()","8e0f65eb":"isBelow(int256,int256,string)","8e0f9b85":"Smartcarblockchain(address,uint256)","8e0fee1f":"withdrawRefBalance()","8e101867":"maxTotalAmount()","8e1069f3":"getPlayRecord(address,address)","8e10be33":"primaryOwner()","8e111ef6":"addressOfERC20Tocken()","8e120f36":"prepareToPayWinners(uint32)","8e1227b2":"KTCWhiteList()","8e12823b":"getCompanyHash(address)","8e13435b":"MathPractice()","8e14cc91":"CreateTokens()","8e151947":"newBitsoAddress(address)","8e15e94b":"countOfCell()","8e15fc87":"clearDeposits()","8e165058":"sendTokensToBuyers()","8e17de8b":"Controlled(address)","8e180733":"_validCrowdsale()","8e1876ee":"permaStop()","8e19899e":"withdraw(bytes32)","8e19ee4c":"Recovery(uint256,address,address)","8e1a1c30":"WithdrawLeftToOwner(uint256)","8e1a55fc":"build()","8e1aa2c4":"bts_address1()","8e1b9f42":"CROWDSALE_WALLET_ADDR()","8e1bb633":"triggerRecovery(uint256,address,uint8,bytes32,bytes32,uint256)","8e1d9545":"setTokenSaleHalt(bool)","8e1e2add":"tradeABIHash()","8e1e3e6c":"POMACOIN()","8e1e3eb1":"setMinBuyEth(uint256)","8e1eeb09":"BarrelAgedFOMO()","8e1f0614":"EGYPT()","8e1fda84":"WorkcoinCrowdsale(address)","8e1ffb19":"testThrowsRetractLatestRevisionEnforceRevisions()","8e207fa0":"getApproveValueValue()","8e22e8de":"Cryptolotto7Days(address,address,address,address)","8e236cea":"setAnnualPrice(uint256)","8e242d54":"withdrawSharesTo(address,uint256)","8e25071a":"setProxyCurrator(address)","8e263e6f":"firstAttack(address,uint256,uint256[],uint256[])","8e268934":"LogSendPOSTokens(address,uint256,string)","8e26a223":"getPoSReward(address,address)","8e26c09d":"waitPeriod()","8e26c30c":"carTransferState()","8e26e582":"_mintDataStream(address,uint256,bytes32,bytes32,uint256)","8e273ef4":"buyLicenseForERC20(address)","8e27d719":"deposit(string,uint256)","8e280dce":"findNextYear(uint256,bytes)","8e2832b7":"ethereumToTokens(uint256)","8e298549":"migrateListing(bytes32)","8e29d149":"claim_block()","8e2a37b2":"privateAllocated()","8e2a6470":"allocateShares(address,uint256)","8e2a8312":"EmjacToken()","8e2ab359":"_transferToAddress(address,address,uint256,bytes)","8e2ae564":"mintingDone()","8e2c6f4d":"initiateVerification(address,bytes,bytes)","8e2d0699":"getCompte_32()","8e2e0776":"doInitialDistribution(address,address,address)","8e2e2077":"setTokensForSaleCount(uint256,bool)","8e303097":"BestWallet(address)","8e3047d9":"getBonuses(address)","8e3047e0":"getCrossConnectorReturn(address,address,uint256)","8e3058f3":"getPostFromId(address,string,uint256)","8e3073a6":"getEth(uint256)","8e314783":"addTotalPaid(address,uint256,uint256)","8e316327":"calculateEggSell(uint256)","8e3177e1":"purchaseIpfsAfterTitle(bytes32)","8e32217a":"calculateTokensQtyByEther(uint256)","8e327dd3":"setInvestor(address,uint256)","8e32e421":"expiredTime()","8e3390b4":"contributeMethodABI()","8e339b66":"controllerApprove(address,address,uint256)","8e343516":"balanceWinPoolToWinSystem()","8e351097":"MintedTokenCappedCrowdsale(address,address,address,uint256,uint256,uint256,uint256)","8e3571c0":"testNewCounterValueAfterAIncreaseAndADecrease()","8e357b6f":"AirTrafficControllerROS(address,int256,address)","8e36a9f1":"Neurus()","8e370b3d":"UnsoldTokensReturned(address,uint256)","8e372dcd":"refineCoke(uint256)","8e37adec":"setAddressArr(address[])","8e37c1e0":"collectorWeiCollected()","8e391cb2":"ProxyERC223()","8e3957d9":"RandomNumber()","8e3ab913":"transferToMany(address,address[],uint256[],uint256,uint256,address)","8e3af93f":"finalizeMint(uint256)","8e3b4525":"setExchangeLimit(uint256)","8e3bd6fa":"SetTradeable(bool)","8e3d4e5e":"Fibonacci(bytes)","8e3d5303":"addRegistrar(address,string)","8e3d63e3":"multiSendEth(uint256,address[])","8e3d7ae7":"drawFortune()","8e3dbf53":"getSalesPartnerAmount(address)","8e3dcc60":"sell_spice_melange(uint256)","8e3e1d86":"fisherYates(uint256)","8e3ed7d7":"sendEthers(address,uint256)","8e406072":"getKingdomCount()","8e414295":"Elixer()","8e416b9b":"randomFight2DeathContract()","8e417b30":"GTokenContract(uint256,string,string)","8e424f16":"onlyOwnerSetCompanyWallet(address)","8e434b82":"DADCoin()","8e438b70":"ConpayToken()","8e43e70e":"ParentKidsLinkToken(uint256,string,string)","8e44e74e":"DEFROST_MONTHLY_PERCENT()","8e452fc0":"findAvailableGame(address)","8e4553a4":"script(address,bytes)","8e455a1d":"_createVote(uint256,uint256,uint256)","8e468a88":"donationMap(address)","8e46afa9":"getDefaultGracePeriod()","8e46b68b":"keysRec(uint256,uint256)","8e46f716":"CoinX(uint256,string,string)","8e46fbb2":"testBitsXorFailIndexOOB()","8e4748cf":"MintingERC20(uint256,uint256,string,uint8,string,bool,bool)","8e47b87b":"FundsReceived(address,uint256)","8e47dd03":"currentProfitPct()","8e48474a":"chooseWinner(string,string)","8e496832":"DataContract()","8e497470":"displayNick(address)","8e499bcf":"numTokens()","8e49a2c2":"turnmigrate()","8e49a41f":"getVestingFromContract(address,address)","8e49cf5c":"soldSoulBecause(address)","8e49dd3f":"Failed(uint256,address,uint256,address,address,uint256,address,uint256,uint256)","8e49ff47":"AntzToken()","8e4a23d6":"Unauthorized(address)","8e4a943d":"IcoResumed()","8e4ab74b":"BANKROLL()","8e4adf4e":"tokenUpgrader()","8e4afa51":"checkTransferToICAP(bytes32,uint256)","8e4b0190":"deleteWorkerAdress(address)","8e4bf820":"settleBet()","8e4c64c0":"grantsController()","8e4cb2a9":"balances_after_buy(address)","8e4d0a83":"setLockupList(address,address,uint256)","8e4d5053":"getcontractBalance()","8e4e0f03":"teamAndExpertsTokens()","8e4f9606":"updateReputationScore(address,uint256)","8e4fa788":"accountHasCurrentVote(address)","8e5051f0":"weiToOwner(address,address,uint256)","8e50a65d":"prepareDividends()","8e514018":"getRandomPrice()","8e5152d6":"addToAngelExperienceLevel(uint64,uint256)","8e51d624":"failsafe_addition(uint256,uint256)","8e52019d":"ECASH()","8e52cb51":"getRecordKey(bytes,bytes,bytes)","8e535ade":"lrcInitialBalance()","8e53d5e4":"cumulative(uint256)","8e53f4fb":"preicoSale()","8e543a12":"getLoanAmount(address,address)","8e550bd1":"lastNewInterest()","8e57d397":"modifyHorseyFeedingCounter(uint256,uint8)","8e588306":"getAutonomousSoftwareOrgInfo()","8e5919b6":"setEdoRate(uint256)","8e592caf":"KittyKendoCore()","8e599d50":"joinFunction()","8e59a15b":"checkMinGoal()","8e5b2899":"check(bytes20,uint24,uint32,bytes32[],uint16)","8e5c2e8a":"LogContractOwnershipChangeCompleted(address)","8e5d97a2":"releasePendingTransfer(uint256)","8e5e91ac":"executeStakeholderTransaction(uint256)","8e5ee9ec":"currencyToToken(bytes32[8],bytes)","8e5ef4ea":"DataShieldCoin(uint256,string,string)","8e5ef8fe":"ChivesToken()","8e604b1d":"queryItems(bytes32,uint256,bool[6],bool)","8e611cee":"deductFromUnminted(uint256)","8e62bbd9":"DigitalCoin()","8e62c982":"initialARXSupply()","8e634029":"communityContract()","8e637a33":"authorizePayment(string,address,uint256,uint256)","8e63d7e1":"getTopLevel(uint256,uint256)","8e63ef75":"icoEtherReceivedPrivateSale()","8e641963":"_mintCards(uint32)","8e64a720":"PlendsToken()","8e65f7e4":"logAllTransactions(address)","8e66ca5f":"setFirstBonusLimitPercent(uint256)","8e66da2f":"cancelBet(uint8,uint256)","8e66fea2":"TTCTokenERC20(uint256,string,string)","8e68f000":"oneTokenInWei(uint256,uint256)","8e690315":"AttributaOwners()","8e69367e":"RandomizedPriceFeedApi()","8e694807":"PHOENIX_CORSAIR_MAX_CARGO()","8e6954de":"totalFci()","8e69ceec":"dispatchTokens(address,uint256)","8e69e204":"getPeriodsWithdrawal(address,bytes32)","8e6a1b24":"PIXToken(address)","8e6a2afa":"MAX_PERIOD_COUNT()","8e6b5462":"setOrCacheDesignatedReportNoShowBond(uint256)","8e6b551c":"sumHardCapPublicSale()","8e6b77a2":"interestArray()","8e6b851d":"valueGet(string)","8e6bee97":"pay(uint256,bytes32)","8e6ce1b1":"getActiveSellDetails(bytes32)","8e6d2599":"_activeness2level(uint256)","8e6d531d":"setSubPromoter(address)","8e6d7db8":"updateInstitutionAsset(string,string,address,address)","8e6ddab1":"createMonster(uint256,uint256,uint256,uint256,uint256,bytes)","8e6df32f":"exerciseOptions(address,uint256,uint256,uint256,bool)","8e6f2353":"ln(int256)","8e6f843f":"EarlyExchangeRateChanged(uint256)","8e6fdd31":"raisedEth()","8e6ff99a":"addVineyard(bytes32,uint16,uint24,uint32,uint16)","8e70fdbc":"setIsNotAdmin(address,bool)","8e71decb":"findWinner()","8e71f4fd":"_hasAllSigs(address,address)","8e728fec":"configTimeInit()","8e7296b1":"MOACSupply()","8e72a926":"bankRollBeneficiary()","8e72ca91":"proxyIncreaseWithdrawalChunk()","8e735547":"getUserByEmailVerify(bytes32)","8e739461":"getBalance(bytes32)","8e73d42c":"lunyrMultisig()","8e7418cb":"isSecondRound()","8e744f54":"tranferMinterOwnership(address,address)","8e74a528":"avarageBlockTime()","8e752b40":"startTeamTrade()","8e7547cb":"setWithdrawWallet(address,address)","8e755125":"testIntFixedArray(int256[3])","8e7558cd":"closeStage(uint256)","8e75dd47":"companyCount()","8e760afe":"verify(bytes)","8e76581e":"getManifestId(address,bytes32,uint256)","8e767411":"setWhaleIncreaseLimit(uint256)","8e768288":"isSane(address)","8e76e3ba":"BillofLaden()","8e77304c":"YOUToken()","8e77afc5":"BSCore()","8e77d147":"transactionfeeAmount()","8e77fe2f":"blacklistAddresses(address)","8e77ff1f":"setMigrateTokenContract(address)","8e78f0f2":"remOperator(address)","8e7952c6":"davToken()","8e79dc91":"set_participant_arbits(address,uint256)","8e7a1697":"setDepot(uint256,uint256)","8e7a9687":"check_vote(string)","8e7b36be":"payFor(address)","8e7b90e4":"setTgeAddress(address)","8e7c9e50":"logFloor(int256,uint8)","8e7cb6e1":"getIndex(uint256)","8e7cd5a7":"distributeExternal(uint256,uint256,uint256,uint256)","8e7d0f44":"publicKeyConsensus()","8e7e060f":"buyCards(uint8)","8e7e34d7":"fromHex(string)","8e7e879f":"migrateAll(uint256[])","8e7e99b8":"TotalSupply(uint256,uint256,address)","8e7e9a3c":"calculatePrizes()","8e7ea5b2":"getWinner()","8e7fd292":"trySetSubnodeOwner(bytes32,address)","8e7fdc6c":"LogBetProperties(uint256)","8e7fffe8":"individualRoundCap()","8e80ade9":"hodlTokens(address,uint256,uint256)","8e818aa1":"acceptAdminWithdraw()","8e81bc9c":"addWhitelistedBurn(address,address)","8e81c579":"poolEthSold()","8e81c64d":"burnTokens(uint256,uint256)","8e821b24":"persians()","8e84844e":"changeWeight(address,address,uint256,uint256)","8e84d413":"isFree(uint256[],uint256)","8e854ed8":"getResult(uint256,uint8)","8e8556b4":"privateSaleEtherRaised()","8e86077b":"foundingTeamSupply()","8e8622f9":"_getTAOIdByName(string)","8e869843":"sellfloaksAgainstEther(uint256)","8e86d030":"getMessageRequestHash(address,uint256)","8e8758d8":"tokenAllowance(address,address,address)","8e87f57c":"setCompare(bytes2)","8e87fcbf":"transformFrom(address,uint256,uint256)","8e885cbb":"LARGE_PURCHASE_BONUS()","8e894a6f":"getTileIDByOwner(uint16,address)","8e89ad00":"setMaxDailyPerUser(uint256)","8e89f6e2":"Crowdsale(uint256,uint256,uint32,uint32,address,address,address,uint256,uint256,uint256,uint256,uint256)","8e8a3983":"paySomeone(address,address)","8e8a4a20":"userTenantHashExists(bytes32)","8e8afc34":"setSlaveServer(uint32)","8e8b34bc":"createNewSecurityDeposit(string,string,uint256)","8e8bc816":"TokenBonus(address,address,uint256)","8e8cf4a8":"getThisBalance()","8e8df687":"processedTokens()","8e8e4675":"gur(address,address)","8e8e75fb":"addExternalController(address)","8e8f1e84":"setPublicSaleParams(uint256,uint256,uint256,uint256)","8e8f39d3":"getBlockNumberM1()","8e8fe845":"IsDistribRuSTMingFalg_()","8e9030f4":"maximumNonWhitelistAmount()","8e90b71a":"changeStatus(bytes1,bytes32)","8e90ccbe":"Governance(address[],uint256,uint256)","8e90e1e9":"_createCutie(uint40,uint40,uint16,uint256,address,uint40)","8e9185cb":"NON_TRANSFERABLE_TIME()","8e9206a0":"EOM()","8e928076":"setMaxGas(uint256)","8e92aea3":"_fetch(uint256)","8e92ee66":"redeemShardsIntoPending()","8e93907b":"FamilyResourceControl(uint256,uint256,uint256,uint256,uint256[])","8e93c883":"setMarketingTokensWallet(address)","8e940bb7":"test_testableContributionCaseExpectFailure()","8e943c8b":"checkParticipants()","8e94a5f3":"sellerRefund(uint256)","8e955978":"pushProposal(address)","8e95b0cd":"getSponsorshipsTotalRefunded(address,uint256)","8e95b28b":"delegateUrl()","8e964de9":"COPPER_AMOUNT_XPER()","8e9674c8":"WEMACOIN()","8e96eb3e":"coePerEthOffset()","8e979bad":"setwinPercent(uint256)","8e984ccd":"joinGameAndBattle(uint256,uint256)","8e98c6b9":"getLeaderboardPlayers()","8e9a5890":"danGold()","8e9a7159":"LZLPrivate()","8e9aed2e":"HACHIROKU()","8e9b7ab8":"Partners(address)","8e9bf09c":"issueTokenToAddress(address,uint256)","8e9ccd04":"computeIndexId(address,bytes)","8e9e5c37":"requiringAuthorization()","8e9e697d":"reset(uint256,uint256,uint256,uint256,string)","8e9e8b14":"marketingPartnerSupply()","8e9f2738":"_transferAllArgs(address,address,uint256)","8e9f9072":"signedMessageECRECOVER(bytes32,bytes32,bytes32,uint8)","8ea04cb3":"getUpgradability(uint256,address,address,string)","8ea06c68":"BLMToken(uint256,uint256)","8ea0926a":"addBaseStats(uint256,uint8[8])","8ea0b540":"getProjectInformation(uint256)","8ea0d898":"DestroyedBy(address)","8ea1ee86":"DapCarToken()","8ea1ff21":"OwnedExample(address)","8ea25644":"XYY()","8ea390c1":"getOwedDividends(address)","8ea44bab":"setProviderAdmin(uint256,address)","8ea51696":"JRT()","8ea5220f":"devWallet()","8ea55bd7":"_pushContributor(address,bytes32)","8ea56e57":"ADV()","8ea64376":"opsAddress()","8ea67eb0":"ETCharPresale(address)","8ea69e37":"TestToken(uint256)","8ea6dd82":"BotAdded(address)","8ea7296b":"deleteChild(address)","8ea73a7c":"setDonationReward(uint256)","8ea74d95":"transferDaico(address)","8ea77300":"RELEASE_START()","8ea822d8":"createThings(bytes32[],uint16[],bytes32[],uint16[],uint88)","8ea83031":"swapContract()","8ea83681":"mintTreasuryTokens(address,uint256)","8ea8dc9d":"APP_MANAGER_ROLE()","8ea8e149":"removeService(address,address)","8ea8f83c":"activate(uint256,uint256)","8ea91bf3":"createVestedToken(address,uint256,uint256,uint256,uint256)","8ea95cbc":"lastDepositorAmount()","8ea98117":"setCoordinator(address)","8ea98db4":"Mmchain(uint256,string,string)","8eaa1e29":"getContentByData(address,uint256,string,string)","8eaa5d1c":"amount50kUsdInCents()","8eaa6ac0":"get(bytes32)","8eaa8d4f":"RefundedInvestor(address,uint256,uint256)","8eaa9c91":"Client()","8eaaeecf":"getUserCapInTokenWei(address,address)","8eac494c":"tierWhitelisted(uint256)","8eaeb531":"setAccountA(address)","8eaf1dab":"PRCT100_R2()","8eafe0f0":"getCustomerRating(string)","8eb04f02":"setRefundManagerContract(address)","8eb066ce":"init(address[5],uint256[6],uint8,bytes32,bytes32)","8eb0e73e":"bonusPctSteps(uint256)","8eb179ad":"maxHardCaphardcap()","8eb206d1":"deletePage(bytes32,bytes32)","8eb36e3d":"initData()","8eb3e0e3":"socERC20(uint256,string,string)","8eb45cbf":"frozenProfitDate()","8eb4e0ad":"batchRelay(bytes16[],address[],address[],uint256[],uint16[],uint128[],uint8[],bytes32[],bytes32[],uint8[])","8eb547d4":"squareOfSums(uint256,uint256)","8eb5a7ac":"changePermission(address,bool)","8eb5f650":"ETIN(uint256,string,string)","8eb6418e":"LoritaBi()","8eb64b3d":"multi(address[],uint256)","8eb64b61":"MAX_NON_SALE_SUPPLY()","8eb689f7":"giveFor(address)","8eb6d683":"coinAllowanceOf(address,address)","8eb6ffaa":"withdrawBloc(uint256)","8eb717fc":"increaseCap()","8eb76eed":"emitUserRatingGiven(address,address,uint256)","8eb7ffe8":"assignInBatches(address[],uint256[])","8eb831fe":"ChangeOperator(address)","8eb857f8":"getData_25()","8eb88c1b":"EvergreenHealthToken()","8eb89a61":"getPointsBalance()","8eb976ca":"assertEq17(bytes17,bytes17)","8eb98150":"NOT_ENDED_FINE()","8eba2966":"RESERVE_PORTION_MULTIPLIER()","8ebaae08":"createListing(uint256,uint256,uint256,address)","8ebac11b":"getHash(address,uint256,uint256,uint256)","8ebb2ce7":"setProfitContainerAddress(address)","8ebb5aee":"calculateTokenBuy(uint256,uint256)","8ebc266d":"getCurrentUSDCentToWeiRate()","8ebe555b":"allocateShares(uint256,uint256)","8ebed616":"CRF()","8ec3167f":"calculateGoalsFromAttributeTotals(uint256,uint256,uint256[],uint256[],uint256)","8ec3272d":"addPicture(string,bytes32,string,address)","8ec48bcb":"BitCharity()","8ec49939":"switchOFFfreeForAll()","8ec4dc95":"getPerson()","8ec521a8":"setupStakeholders(address[],uint256[],uint256[],bool[],uint256[],uint256[],uint256[])","8ec5a309":"testHash(string)","8ec5ff41":"isUid(string)","8ec63da9":"checkIsOnlyProxy(bytes32)","8ec6677d":"registerUsername(string,address)","8ec84812":"updateProfit()","8ec86497":"clearname()","8ec89e4f":"_isActive()","8ec8fcad":"ADV(uint256,string,string)","8ec9925e":"jackpotToken()","8ec9a5de":"getLeaf(bytes32,uint256)","8ecaa140":"_refundHighestBidder(uint256)","8ecbc4e9":"setNewBRXPay(address)","8ecc0643":"BuyAd(address,uint256,string,string,string,uint256,uint8,address)","8ecc0950":"returnToOwner()","8ecc107f":"buyUninitializedPixelBlock(uint256,uint256,uint256,bytes32)","8eccf58e":"getTokensCountPerEther()","8ecd2fe8":"testMul256By256()","8ece19f6":"setTokenLock()","8ece39cd":"startOraclize(uint256)","8ece85a4":"ETpay(uint256,string,string)","8ecebf34":"MorpheusToken()","8ecf0d0b":"getCreated()","8ecfc412":"workForce()","8ed06b62":"getShipPrice(uint256,uint256)","8ed08711":"saleMinimumWei()","8ed09bc9":"registerVoter(bytes32,address)","8ed0ac8b":"closeTrancheAddition()","8ed1858e":"distributeELTCSmall(address[])","8ed20fa0":"tokenWeiToSale()","8ed2395f":"ZCNYToken(address)","8ed33545":"sub_presale_arbits_sold(address,uint256)","8ed34751":"performHealthCheck(uint8)","8ed399ca":"teamWallet_2()","8ed3fa7c":"codexCoin()","8ed5047c":"updateCokeTotal(uint256,bool,uint16)","8ed5f2ca":"newTestableCampaign(string,uint256,uint256,address)","8ed67a44":"setPrice(uint16)","8ed6910f":"limitSell(uint256,uint256)","8ed7c3d3":"sendTokensManager(address,uint256)","8ed7ca93":"finishExam()","8ed8067e":"FundContract()","8ed882c5":"designatedReporterWasCorrect()","8ed91318":"nextAssetId()","8ed9be36":"temp(uint256,uint256,bytes32,bytes32)","8ed9fd75":"ICO_Supply()","8edb726d":"modifyEndFundingTime(uint256)","8edbf436":"getPriceInfo(address)","8edc4f8f":"isValidCap(uint256,uint256)","8edc707b":"adoptionOffers(bytes5)","8edcf21d":"getCurrentYearGameMiningRemainToken(uint16)","8edd6eb6":"getFund()","8eddc306":"__exchangerCallback(address,address,uint256)","8eddc804":"notifySale(uint256,uint256)","8eddf665":"onInvest()","8ede1817":"getReturnTime(uint256)","8ede3a34":"KeplerToken()","8ede74c1":"changeRage(uint256)","8ede94b4":"setLineUpEnable_miner(address,uint256)","8edeb15d":"donation()","8edec689":"wd()","8edfaef8":"getSetupParameters()","8edff3db":"getTerminal(uint256)","8ee030bd":"FaceterToken(address,address)","8ee070d9":"MYEMPEROR()","8ee0942b":"setSignatureROFR(bytes)","8ee0ffe8":"sendStakingContract()","8ee1409e":"TitanToken()","8ee17e0a":"MarvinCoin()","8ee21b8e":"get_default_keys()","8ee365fa":"removeAddressesFromAdmins(address[])","8ee36f05":"isVoted(address,uint256)","8ee3f472":"BoutsCrowdsale(uint256,uint256,uint256,address,address,address)","8ee3f72f":"PinCode()","8ee4d44b":"addAddressToOperators(address)","8ee4fd8a":"claimWithSignature(bytes)","8ee553cc":"getCroById(uint256)","8ee5a8b3":"UpgradeProposals(uint256)","8ee6540c":"seventeen()","8ee6f301":"readvalidrollsXteam(uint16)","8ee78046":"draw(address,uint8[])","8ee833cc":"isValidTenant(string,address,uint256)","8ee8a5c4":"Charity(string)","8ee93cf3":"post(string)","8ee97ff4":"VirtualRewardToken()","8eeb203e":"exchangeWeight()","8eeb33ff":"crowdSaleAddr()","8eeb3b0e":"KJCPerEthereum()","8eeb5073":"_bundle(address,uint256,uint256[])","8eeb5c97":"cancelDo(bytes32)","8eeb7d11":"unlockAllocationAddress(address)","8eeb8e5a":"MUC()","8eec5d70":"getPoolCount()","8eec6f7b":"lockETH(uint256)","8eec99c8":"setNewAdmin(address)","8eecddcf":"betBlockNumberOf(address)","8eecf64d":"createContractWithMeta(address,uint64,bytes,string)","8eee1cd6":"buyerExceededApprovedAmount(uint256,address)","8eef059e":"_lowerDown(uint256,address)","8ef0f09a":"createPromoPow(address,string,uint256,uint256,uint256)","8ef1a6b6":"makeProfit(uint256)","8ef1e886":"RESERVE_PERCENT_EVE()","8ef22afe":"getCostToCancel()","8ef25a7a":"KeplerTokenExtraSale(uint256,address,address)","8ef26a71":"coinSentToEther()","8ef28249":"totalGuesses()","8ef2826e":"HODLWallet(address[],uint256[])","8ef292fc":"BTM()","8ef326ea":"getCubeCount()","8ef44301":"tokenRecoveryFromTrade(address,address,address,uint256)","8ef47296":"StorageController(address,address,address,address)","8ef483eb":"getMyWager()","8ef490ea":"fullname()","8ef4c807":"lockedBalanceOf(address,uint256)","8ef53edf":"InitAssignOK()","8ef5ae21":"setupInfo(string,string,string)","8ef5ce28":"test1_addingFirst()","8ef5eaf0":"drop(address[])","8ef6e7fe":"build(string)","8ef6ed53":"_getRandom(uint256,uint256)","8ef72d15":"backEthRatio()","8ef79e91":"setTokenBaseURI(string)","8ef7c649":"getTicketPrice(uint8)","8ef8125e":"frontRunnerSetTimestamp()","8ef82010":"orderExecution(bytes32,uint256)","8ef85e04":"secondWeekTokenPrice()","8ef87843":"randomSkinAppearance(uint256,uint128)","8ef8f241":"getEmployerInfo()","8ef9c904":"NewAmbassador(address,address)","8efa00e2":"getPRETDETokenExchangeRate(uint256)","8efa23d1":"RELEASE_WALLET()","8efa3e21":"setIsMinter(address,address,bool)","8efbd512":"getAccountNumber(address)","8efc777f":"isBeta(bytes)","8efd4c75":"QUARTERLY_RELEASE()","8efd5f92":"divIntervalDays()","8efe6dc4":"changeMonthlyWithdrawLimit(uint256)","8efe7801":"showWinnersSort()","8efe8c1c":"EPTToken(address,address)","8eff3c29":"getRecords()","8effda0d":"IndorseSaleContract()","8f003a2d":"StarSportsToken()","8f00c0af":"has_contract_ended()","8f00cbfa":"winnerIndex()","8f00f49b":"totalAssetTokens()","8f0165e1":"min_pay_wei()","8f01932a":"mntpToMigrateTotal()","8f01e1e2":"getactiveleveltime(uint256)","8f02bb5b":"setTransferFee(uint256)","8f03850b":"numContributors()","8f038a5a":"initializeEthReceived()","8f039a10":"changelp8(address)","8f03f5c3":"firstUnlocked()","8f0427b1":"sellPosition(uint256)","8f049de5":"endBetRed()","8f054bf3":"referralList(address)","8f0563b9":"substring(string,int256)","8f061ef5":"Token(string,string,uint256,uint256)","8f06492d":"callOnRemoval()","8f0816bc":"PERKToken()","8f08288a":"clearBets()","8f08a60a":"transfer2(uint256,address[],uint256[],bytes,bytes,bytes,bytes)","8f08d44d":"burnAsset(uint256)","8f08e369":"withdrawApplication(address)","8f094efb":"getMineableSupply()","8f0a4c1b":"startPreSales()","8f0a6ecb":"returnBountyTokens(address,uint256)","8f0bc152":"claim(address,uint256,bytes)","8f0c724c":"setOperationsCallGas(uint256)","8f0d16da":"emitIssuersUpdated(address,bool)","8f0d3b8b":"_buy(uint256,uint256)","8f0d67ef":"activationTime(uint256)","8f0ec6b3":"ZanCoin()","8f10cad0":"StreampayToken()","8f10fd45":"getBuyCount()","8f112370":"addToAffiliate(address,uint256)","8f11e5f9":"checkWithdrawValue(uint256)","8f1224ce":"fixInvestment(address,uint256,uint256)","8f12355d":"assertEq7(bytes7,bytes7,bytes32)","8f1327c0":"getRound(uint256)","8f134025":"rewardSent(uint256)","8f13fd29":"setPriceValue(bytes32,uint256)","8f140568":"isServiceAddress()","8f142842":"getByAlias(string)","8f142907":"stables()","8f14b76b":"sendReferrer()","8f14d8a3":"reclaimContractTokens()","8f15024f":"ticketsSold()","8f152d0e":"vestingConfigured()","8f158e76":"remainingPublicSaleCap()","8f163497":"AgaCoin()","8f16eb1a":"setI_R1(uint256)","8f188b40":"migrateInvestor(address,uint256,uint256,uint256)","8f19ff45":"_handleTokensReceived(uint256)","8f1a422c":"minterWallet()","8f1a927a":"numTicksSinceAuctionStart(uint256)","8f1af992":"claimTwitterId(uint256,address,uint8,bytes32,bytes32)","8f1b0b02":"bulkTokenMint(address[],uint256)","8f1c204c":"test_fiveAssertFalse()","8f1cc85e":"SAGAcrowdSale(address)","8f1cc94e":"HashTypeAdded(uint8)","8f1d5f7e":"getLedgerNameHash()","8f1d8f41":"ethInvestment(address,uint256,uint256,uint256,uint256)","8f1d90b1":"tokenBearer()","8f1df4f7":"setPrices(uint256,uint256,uint256,uint8,uint256,uint256,uint256)","8f1eda37":"wmul(uint128,uint128)","8f1f761a":"Rewards_Supply()","8f1fc530":"startSplit()","8f1fc6bb":"testRemoveProductFromCart()","8f1fdbb9":"offerEth(uint256)","8f212eb7":"BITSDTokenInitialized(address)","8f217d6b":"lastChar(string)","8f22964d":"NegativeWhuffiesSent(address,address,uint256,string)","8f22d128":"testdigiToken()","8f24f2a3":"takeBuyOrder(address,uint256,uint256,uint256,address)","8f25159c":"getDayDepositLimit(uint256)","8f259117":"numcallsinternal()","8f25eec1":"BetWon(address,uint256,uint256)","8f26a5ab":"setSaleAgent2(address)","8f272c0b":"minor_partner_address()","8f2757d8":"Bitshopandearn()","8f282b87":"getSold()","8f283970":"changeAdmin(address)","8f287be5":"PitEur(address)","8f288526":"TokensPurchased(address,uint256)","8f288644":"getHighestBid(uint256)","8f2900d5":"timeLocks(uint256)","8f291158":"listBBO()","8f296759":"UTILITY_ROLE()","8f29f09a":"fetchPaidOrdersForMerchant(address)","8f2a3093":"freeBeerOnMe(string)","8f2a6d3e":"YOOBAToken(address,address,address,address,address)","8f2abe9a":"Voting(uint8,address,uint256)","8f2bab07":"getChainLength()","8f2be8e0":"MauiWowieToken()","8f2c2ab7":"checkAndCloseDeposit(uint256,bool)","8f2c3af8":"lastBlock_v10Hash_uint256()","8f2c44a2":"UnicornMilker()","8f2e695c":"ICO_state()","8f2e8d4a":"createTrack()","8f2e9ee7":"theDay(uint256)","8f2eabe1":"isValidatorFinalized(address)","8f2ec012":"dayToBlockNumber(uint256)","8f2ee2df":"mainPot()","8f2ef6b7":"CMGF()","8f303df9":"priceExpired()","8f30435d":"getCompetitionValues(string,uint8)","8f32106e":"CreateALLY(address,uint256)","8f32cf0c":"team_address()","8f32d59b":"isOwner()","8f33221e":"addContract(address,uint256,uint256)","8f33c285":"getAyantDroitEconomique_Compte_8()","8f33df77":"countAllVotes(uint256)","8f34296b":"Applied()","8f348cfe":"InsertProject(string,string,address,address,string,string,address)","8f34ac6e":"setCoOwner(address)","8f350624":"contributionOpen()","8f356f97":"lottoHighestNumber()","8f35a75e":"getInvestor(address)","8f36039c":"holdContract()","8f367001":"numTokensAbleToPurchase()","8f368359":"getTimeUntilInterestIncrease(bytes32)","8f3684bf":"returnTotalDividend()","8f36d03e":"_finishSpin(address)","8f36f8f1":"redeemStake(address,address,uint256,uint8,bytes32,bytes32)","8f37a0f9":"getTo(uint256)","8f382a00":"ETHEAL_UNIT()","8f38a896":"BRONZE_AMOUNT_XPER()","8f38bf34":"updatePrices(uint256,uint256[],uint16,uint256[],uint256[])","8f38d8cc":"S(string)","8f38f309":"buyXid(uint256,uint256)","8f3956a4":"ChangeUpgradeMaster(address)","8f395eb6":"addIntComparison(bytes32,int32,bytes1)","8f398180":"isUnknown(address)","8f3984b5":"setRole(address,string,bool)","8f3b6b84":"centsPerToken()","8f3b8c3a":"setTokennCrowdsale(address,uint256)","8f3bab85":"readFromCart(uint256)","8f3bed06":"pickUniquePacks(uint256[])","8f3de282":"onSealed(address,address,uint256)","8f3e568a":"findOutInterestByClientCategory(address,uint256,uint256)","8f3e8747":"getGasForMcrData()","8f3f50fc":"startICOTimestamp()","8f40104c":"init(address,uint256[],uint256,uint256,uint256,uint8,uint256,bool)","8f409b85":"Coin(uint256,string,uint8,string)","8f41e442":"breakTie(uint256)","8f420866":"DEFAULT_SEND_GAS()","8f426437":"getTankOwner(uint32)","8f42a864":"TitaToken()","8f43166b":"getGivenCount()","8f44097a":"TokenRDC(address,address,address)","8f449a05":"subscribe()","8f456125":"setCrowdSaleAddress(address)","8f4613d5":"left10(uint256)","8f4646b7":"transferPreSignedCheck(address,address,uint256,uint256,uint256,uint8,bytes)","8f46b586":"withdraw_team_fund(address,uint256)","8f4708bd":"mintingBountyFinish()","8f477c55":"updateLink(address,bytes)","8f4783f1":"_generateRealmSale(uint256,uint256)","8f47dd19":"bulkInit(address[],address[],uint256[])","8f484394":"manual_withdraw()","8f48c14a":"updateMinCompanyValue(uint256)","8f49a264":"provide_eth()","8f49ccf4":"reportUsage(uint256,uint256,address)","8f49da4b":"distributedToken()","8f4a2a51":"defaultWallet(address)","8f4b4b98":"messagesSigned(bytes32)","8f4ccce8":"startTokenVotes(address[15])","8f4ce746":"buyDeferredPresaleTokens(address)","8f4d8723":"_CallExecuted(address,bytes32)","8f4d874a":"referralTokensAddress()","8f4dc0d1":"updateAvailable(uint256,uint256,bool)","8f4e4321":"accountOf(uint256)","8f4e5158":"increaseFrozenBalances(address,uint256)","8f4ed333":"step2()","8f4f3c70":"DungeonChallenged(uint256,address,uint256,uint256,uint256,uint256,bool,uint256,uint256,uint256)","8f4fb958":"calculateRandomNumberByBlockhash(uint256,address)","8f4fde42":"crossForkCount()","8f4ffcb1":"receiveApproval(address,uint256,address,bytes)","8f50fb06":"getTrapInfo(uint256)","8f50fdd6":"walletAddressesSet()","8f512c47":"getSponsorships(address,address)","8f518475":"NewKoth(uint256,uint256,address,uint256,uint256,uint256)","8f52d420":"CryptoStrippers()","8f52da60":"technicalWallet()","8f535904":"CROWDSALE_REWARD_WALLET()","8f541730":"advisor1Sum()","8f55a850":"getArtistList()","8f56015f":"setRequirement(uint256)","8f5665ce":"nthWagerPrizeN()","8f571461":"ICOPRICE()","8f580996":"enablePurchasing()","8f58190e":"setLLV_edit_19(string)","8f581a53":"giveRegistration(address)","8f5949f9":"isContractActive()","8f5a5a39":"verifyPayment(bytes8)","8f5ab3ab":"transferdata(address,uint256,bytes)","8f5ab947":"getNextDropTime()","8f5b0b1c":"timeCheck()","8f5bae2e":"anchor(bytes32,uint256)","8f5bc587":"TokensForSale()","8f5c2eff":"getPurchaseInfo(uint256,uint256,uint256,uint256,uint256,bool)","8f5c5d40":"validTranscodingOptions(string)","8f5cbe36":"testCreateSale()","8f5cf7b9":"vestingStageTime()","8f5d23f6":"TOKENS_FOUNDATION()","8f5e0b3f":"UserBondByOffset(uint32)","8f5e514a":"diff(uint256,uint256)","8f5e619b":"publishEtherBox(bytes32,string,uint256)","8f5e9ca7":"acceptTOS(address,bool)","8f5f20c2":"LMA()","8f5f657d":"rateboc()","8f5fa4a4":"changeReceiverAddress(address)","8f608f4f":"exchangeRateMNY()","8f60cf17":"increaseSalesBalance(address,address,uint256)","8f6107ef":"MatthewWon(string,address,uint256,uint256)","8f612102":"createCarrier()","8f617fcd":"icoFinishTimestamp()","8f61da35":"getDebtLength()","8f620487":"expirationDate()","8f62077d":"getPlayerShips(address)","8f6218a3":"rollDices()","8f6245e1":"parseBool(bytes32)","8f627aab":"BlockIntervalCrowdsale(uint256)","8f62905f":"mintTokens(int256,uint256,uint256,address)","8f62b028":"updateUSeqgret()","8f632311":"doMint(address,uint256,bytes)","8f632a34":"MeetupToken(uint256,string,uint8,string)","8f6348b8":"stopFeeding()","8f63534a":"totalAuctionsCount()","8f64337d":"getHashedData(uint256,uint256,bytes32,bytes32,uint256)","8f652ec7":"_getVerifierInfo(address)","8f654175":"auditorAddress()","8f6612c9":"distributedAutonomousExchange()","8f679b2d":"EtheraffleICO()","8f67bd4d":"SBITokenCrowdsale(address,address)","8f67f9d7":"ILLIQUID_TOKENS()","8f6811a3":"mintTokensFor(address,uint256)","8f68b36f":"getMysubscribers()","8f68ca70":"setWhiteListContract(address,bool)","8f6963df":"initShareRule6()","8f699f6c":"calcInvalidKeys(uint256,uint256)","8f69fa25":"startLockingPeriod()","8f6a3deb":"_activateZoneLand(int32,int32,uint8,uint8)","8f6a7286":"refundMultipleUsers(address[])","8f6ac8d7":"FinalizableCrowdsale(uint256,uint256,uint256,address)","8f6b875a":"OWNER_POOL_COMMISSION()","8f6caf63":"sendPoint(uint32,uint32,int256,address)","8f6f3275":"getLease(uint8,uint256)","8f6f6115":"getOraclizePrice()","8f6f988c":"setUltimateOutcome(bytes)","8f6fa4c2":"ICO_details()","8f6fba8c":"FEATURE_TRANSFERS_ON_BEHALF()","8f70009d":"id_for_address(address,address)","8f701eaa":"addguess()","8f702afa":"sellerNumOpenDeals(address)","8f70585f":"bid(address,uint256,uint256,uint256)","8f70bfa0":"processDeposit()","8f70ccf7":"setTrading(bool)","8f7140ea":"receivePlayerNameList(uint256,bytes32)","8f717e80":"totalCreationCap()","8f71b3db":"etherToUSDrate()","8f71f3cb":"getBdpPriceStorage(address[16])","8f728516":"initNewGame()","8f729925":"receivePercent()","8f72e065":"StabitCoin(uint256)","8f72fc77":"getOrders(uint256,uint256)","8f731077":"extractAllowanceRecordLength(address)","8f73c5ae":"distributeReward()","8f7445e6":"setStageThirdBegin()","8f7451ae":"GetStoreInfo()","8f750271":"prose()","8f75362d":"emergencyWithdrawAdmin()","8f75374d":"incrementSupply()","8f754a1e":"affectedCount()","8f755c7c":"getOptionState(address[3],uint256[3],uint256[2],bool)","8f760988":"forceStopCyle()","8f76691a":"margin()","8f76a1f7":"lastClaimedRound(address)","8f76dfc3":"allTokenICO()","8f770ad0":"supplyCap()","8f77339f":"sendToken(uint256,uint256,uint256,string)","8f775839":"settled()","8f776ff1":"allowanceBalance()","8f778bb9":"setEmployer(string)","8f78b34a":"lockAccounts(address[],uint256[])","8f790507":"teamEthContract()","8f7a4738":"censure(uint16,uint32)","8f7a844b":"getAdminData()","8f7b7bce":"isTeamLockInPeriodOverIfTeamAddress(address)","8f7ba0a1":"registerbot()","8f7d33cf":"addCashback(string,uint256,address,uint256[],uint256[])","8f7d4dad":"getFirstPoints()","8f7d79da":"nextRoundMaxDonors()","8f7db6ee":"_setProviderSupply(uint256,uint256)","8f7dcfa3":"head()","8f7fe231":"ValidetherOracle()","8f80269d":"getClientSupply(address,uint256)","8f807f6b":"enqueue(address)","8f80b7bc":"registerTokenInternal(address,string)","8f80d339":"roundClaimICOKeys(uint256)","8f81ecfc":"removeChild(bytes32,bytes32)","8f81fd4a":"changeIcoDiscountPercentages(uint8,uint8,uint8)","8f828c9e":"totalSupplyAtInternal(uint256)","8f82b8c4":"getWhiteListCount()","8f8336b7":"setFeesMaxUptoCoin(uint256)","8f835871":"addRealWorldPlayers(uint128[],bool[])","8f83719c":"getTreasuryBalance(address,address)","8f83743f":"Fricacoin()","8f838478":"getInstantiationCount(address)","8f842851":"dateManager()","8f847076":"removeNFToken(address,uint256)","8f84aa09":"ownerAddress()","8f850163":"flipsWon()","8f855433":"newCreator()","8f85f92c":"isPoDEnded()","8f860c5f":"createWallet(address,address)","8f86f5ea":"finishSale()","8f872bb1":"advisorsAndAmbassadorsAddress()","8f87932c":"fix_amount(uint256)","8f87c84b":"transferOutEth()","8f87e387":"updateSspManagerContract(address,string)","8f88110d":"updateRecordWalletAddress(string,address)","8f88708b":"retrieve(uint256)","8f88a00e":"calculateRewardStructures()","8f88aed0":"populateFromItemRegistry(uint256[])","8f88b792":"createCampaign(string,uint256[3],uint256[],uint256,uint256,uint256,uint256)","8f8949e6":"setTotalCardCount(uint256)","8f8a5832":"reLoadXid(uint256,uint256)","8f8b2c9b":"totalEthJackpotRecieved()","8f8bbb8c":"ObjectedVote(bytes32,address,uint256)","8f8bcae6":"minting(address,address)","8f8bd64c":"calculateNetworkTokenBonusPercentage(uint256,uint256,uint256,uint256,uint256)","8f8bde82":"MicroDAO()","8f8c7c50":"_randomMeme()","8f8d322e":"melt(address,uint256)","8f8d49ac":"setStore(string,uint256)","8f8db737":"buyDirectInMarketplace(uint256)","8f8e7419":"sharedStorage()","8f8e8f9d":"refundETHToCustomer(address,address,uint256)","8f8eabea":"ZNA(uint256)","8f8eb474":"burnBid(uint256)","8f8f6b52":"freezTwo()","8f907195":"rpow(uint256,uint256)","8f9087f5":"hashBytes(bytes)","8f908cbd":"setCaptainTokenContract(address,address)","8f90f2bb":"getNewRabbit(address)","8f9139fb":"Pokecoin(uint256,address,address)","8f924560":"addEntity(string,uint256,uint256)","8f929c4a":"createAccount(bytes16,string)","8f92d308":"viewFeaturePetitionFee()","8f937574":"OwnerHelper()","8f93bffe":"getOrCacheReportingFeeDivisor()","8f940f63":"typeId()","8f94f6a0":"piTokensForSale()","8f9593f4":"winnerFirst(uint256,uint256)","8f96a1ea":"addThing(bytes32,bytes32,bytes32,bytes32)","8f975a64":"sendERC20(address,address,uint256)","8f97ad89":"claimTokensFor(address,address)","8f97cff0":"getPersonsCount()","8f97d03f":"IbizaERC20Token()","8f97e3a0":"requestPayout(uint256)","8f984115":"AUEBToken()","8f98767e":"fundingMaximumTargetInUsd()","8f98ce8f":"transferFeeNumerator()","8f98e0e1":"MBToken()","8f99d31b":"betLow()","8f99ea43":"setDividendDB(address)","8f99fdab":"SafeDeduct(uint256,uint256)","8f9a42b8":"philadelphiaBets()","8f9a57ef":"minSignId()","8f9a6da1":"queryOracle(string,string)","8f9abae1":"accessControlled()","8f9abe52":"isValidSellOrder(address,address)","8f9ade5e":"create(address,bytes32,uint256)","8f9b7eb7":"updateReleaseAmount()","8f9bbf16":"getSecurityTokenData(address)","8f9bf95d":"_payCommission(address)","8f9d1cba":"zss(address)","8f9d390a":"toteLiquidatorTransferComplete()","8f9de24b":"uniqueSpinnersActive()","8f9df278":"newEntry(int256,bool,uint256,int256,string,bytes32,address,uint256[])","8f9e1409":"removeSection(bytes32,bytes32)","8f9f5b2f":"getMemoryWrite(uint256,uint256)","8fa148f2":"currentRoundStartBlock()","8fa17580":"claimEgg(uint256,bytes32,bytes32)","8fa1ae05":"batchTransferSingleValue(address[],uint256)","8fa32111":"addInvestor(address[])","8fa366df":"changePhaseToICOweek3()","8fa3a84c":"validateTransaction(address)","8fa4c0b1":"tokenPlus(address,address,uint256)","8fa54b81":"setUserBattleValue(address,uint256)","8fa5614f":"getBylawsProposalVotingDuration()","8fa56215":"_createToken(string,string,string,uint256,address,uint256,uint256)","8fa566e8":"tokenIdOfUUID(string)","8fa5a6e9":"pmtAccount()","8fa65488":"startRefundInvestorsBallot()","8fa6da99":"Modultrade(address,address,address,address)","8fa81bb0":"PrivateSale(address,uint256)","8fa8b790":"cancelAuction()","8fa906b2":"addFounder(address,uint256)","8fa9cc09":"HeritableWalletFactory()","8fa9e55c":"signIn(address)","8faa6cb7":"partnersLockEnd()","8faa77b2":"deployers(uint256)","8faab3a7":"BatchAttachAssets(uint256[10])","8faad4c4":"createPromoTeam(string,address,uint256)","8fab0549":"setInvestorsPercentage(uint256)","8fabd326":"mPausedTime()","8fac3d3e":"feesGathered()","8fad8334":"_timeRemaining()","8fad8eec":"EnterRentToken()","8fadd08b":"betHigh()","8fae065c":"setStartIcoPreICO(uint256)","8fae4857":"finaliseChannel()","8fae8850":"ICOmint(address,uint256)","8faef6a5":"getTierForLastMiniting()","8faf682d":"payeeWithdrawCapital()","8faf850d":"addUser(bytes32)","8fafb286":"claimResearchDividends(address,uint256,uint256)","8fafebca":"TokensPurchased(address,uint256,uint256)","8fb0de08":"getCurrentRoundInfo2()","8fb197d1":"getUserDataOnToken(address,uint256)","8fb21a4b":"setMinReferrerBonus(uint256)","8fb25f82":"sellCells()","8fb29d6c":"pastAgreement(uint256)","8fb2f8b4":"isCollectTokenStart()","8fb2fbe1":"getTokenToEthUpdateOrderHint(uint32,uint128,uint128)","8fb48844":"noOfreservations(address)","8fb4b573":"start(uint256,uint256)","8fb50078":"joinProvider(address)","8fb51ccd":"QosinusCoin()","8fb5202b":"setFinancialAddress(address)","8fb5a482":"getPrices(address[])","8fb67f60":"aPurgeMessages()","8fb6d997":"updateStorageContract(address)","8fb74077":"HoursFromNow(uint256)","8fb74ae9":"isBannedUser(address)","8fb84bb0":"marketBuy(uint256)","8fb8f109":"addressToPersonId(address,address)","8fb96635":"decreaseBalance(address,uint256,uint256)","8fba273c":"m_investmentsByPaymentChannel(address)","8fba8d5c":"toHexString(uint256)","8fbb3c17":"CROWDSALE_PHASE_2_START()","8fbb9b49":"_isProduct(address)","8fbc3ecd":"BUFFER()","8fbc7eb0":"balanceOfToken(address,address,address)","8fbd4fa5":"claimPrizes(uint256,uint256,uint256,uint256)","8fbe382c":"totalFoundCoin()","8fbea5c9":"totalCommissionOwed()","8fbeee23":"sendOutEtherWithGasAmount(uint256)","8fc01623":"activatePackage(uint256)","8fc1d08b":"transferFromPublicAllocation(address,uint256)","8fc202ae":"currentKeyRound()","8fc264e0":"allocateTokens(uint256,uint256)","8fc3047d":"checkPrice()","8fc3c33b":"GenerateFortuneCookie(uint8)","8fc4ea4c":"ownerPetCollection(address,uint256)","8fc5668b":"processRequest()","8fc5efd4":"c_centsPerTokenFirst()","8fc5fd83":"FRPoint()","8fc6ad2d":"getParameterValueByTitle(bytes32)","8fc6bf7f":"ico3endTime()","8fc7a25d":"getEthAmount(uint256)","8fc8a134":"DepositBeneficiary(address,uint256)","8fc95403":"saleSecondEarlyBirdEndBlock()","8fc9bff6":"_claimRewardBlank(address,string)","8fca3057":"pastPlayRoundsCount()","8fcb4e5b":"transferShares(address,uint256)","8fcbeeb7":"getFreeDragon()","8fcc9cfb":"setMinDeposit(uint256)","8fcd558e":"GetDataRequestLength(uint256)","8fce0ee7":"secondLineWrong()","8fce6b07":"_addKeeper(address)","8fced626":"resolveBet()","8fcee83f":"getRoomStatus(uint256)","8fcf31e3":"createCardFromName(string)","8fd0290f":"YZChain(uint256,string,uint8,string)","8fd16541":"referrer2Percent()","8fd1b1f2":"maxCardUpgradeLevel()","8fd23762":"IOSToken()","8fd237e1":"setJackpotWinPercent(uint256)","8fd28bcf":"testFailAuthorityAuth()","8fd3ab80":"migrate()","8fd4f899":"setVipRate(uint256)","8fd57396":"winAmount5()","8fd5a39e":"distributeSMILE(address[],uint256)","8fd5d753":"EternalToken(uint256,string,string)","8fd5eb06":"_decodeSettle(bytes)","8fd611be":"eventManager()","8fd65890":"getCurrentAvailableFunds()","8fd712ae":"PRICE_STAGE_ONE()","8fd79669":"setPokemon(uint256,string,address,uint256,uint256)","8fd7aab6":"unfreezeAccount(address,uint256)","8fd88225":"GetChipList(address)","8fd8b429":"vanishCoins(uint256)","8fd90960":"UpgradeProposalSubmitted(uint256,uint256,address,address,address)","8fd9f1b4":"DaoRules()","8fda183a":"hasPoolRole(address)","8fda356d":"activateContract()","8fda5c8e":"creatorsPoolMintQuota()","8fdb385b":"Trc(uint256,string,string)","8fdb7189":"double()","8fdb72f3":"gzeEth()","8fdc054f":"purchaseCrates(uint8)","8fdc24ba":"left94(uint256)","8fdf51d5":"getMyAllAuction(address)","8fdf741a":"_batch3_rate()","8fdfac6b":"setMAXfinney(uint256)","8fe10615":"walletLocked(address)","8fe10ae4":"FundsAdded(address,uint256)","8fe13b92":"addExchange(bytes32,address)","8fe26bf5":"TailsToken(uint256)","8fe2b355":"getGameVars()","8fe2eb9e":"setSellDividendPercent(uint256,uint256)","8fe316fe":"withdrawNotification(uint256)","8fe3579f":"addCharacter(string,address,uint256)","8fe3ec6d":"setDefendBoostCap(uint256)","8fe44adf":"ico4Min()","8fe47625":"showMyTokenBalance(address)","8fe58eb9":"Triger()","8fe5f77d":"hackTenuous(address)","8fe60df1":"calculateCounterReceived(uint256)","8fe6677d":"addToWhitelistMultiple(address[])","8fe8a0a6":"abcLottoResolver()","8fe8a101":"isKilled()","8fe8cb79":"promotionIndexToClaimant(uint256)","8fe91976":"activateWithdrawal()","8fe92aed":"votedPerCent(address)","8fe9a12f":"BKUToken()","8fea1e4d":"decreaseAllowance(address,uint256,address)","8fea64bd":"Hourglass()","8feaa243":"callTest(address,address,uint256,bytes,string)","8feadcb7":"setPeriod(uint256,uint256,uint256)","8febb1e5":"getPlayerHasAff(uint256)","8fedc959":"hedgeAddress()","8fedd2f2":"getTestTwo()","8fee3dab":"updateStat(uint256,uint256,uint256,uint8,uint8)","8fee7687":"allocatePresaleTokens(address,uint256)","8fee7b57":"registerQuarterSeason(int8)","8ff0c391":"isBuyBackTwo()","8ff11282":"parseKey(bytes32)","8ff1a583":"ICO_HARDCAP()","8ff21e0d":"LogBounty(address,uint256,string)","8ff255d6":"getHighestPrice(uint256)","8ff49347":"LOG_InvestorCapitalUpdate(address,int256)","8ff591b4":"addMinutes(uint256)","8ff5cbc3":"ApproveERC20(address[])","8ff5f021":"tokenAlreadyUsed(uint256)","8ff6650a":"Lending(uint256,uint256,address,uint256,uint256,uint256)","8ff67e35":"EthereumPro()","8ff6c8dd":"ICOSaleEnd()","8ff6e971":"isSecondary(uint256)","8ff72293":"getLotteryStatus(uint256)","8ff813fd":"transferVester(address)","8ff82a97":"TransferLockedToken(address,address,uint256,uint256)","8ff8754c":"getShareIndexDebugForTestRPC()","8ff936ea":"NoahCoin()","8ff95fa8":"catNames(bytes5)","8ff9b84e":"newStorage(address)","8ffa9690":"getBoolValue(bytes32)","8ffb4dc7":"nextStage(bool)","8ffb5e67":"getEvents(uint256,string,uint256)","8ffbcb81":"endIcoSaleRound3()","8ffbd95b":"setFcfContractAddress(address,address)","8ffc024f":"login(address,address)","8ffc831a":"testMemoryIntegrityCheck32Bytes()","8ffcdc15":"ContractDeployed(address)","8ffd2a1b":"add(uint256,address,uint8,string,address,address,string)","8ffe9b94":"transferTo(address,address,uint256,uint256)","8ffeb5c8":"MyBoToken(uint256,string,uint8,string)","8ffec6ee":"vinciCap()","9000b3d6":"addVerifier(address)","9000fcaa":"killAllowanceContract()","900104da":"updateAddressInfo(address,address,uint256,bool,uint256,bool,uint256,bool,string,bool)","90014f06":"ownerSetJackpotOfHouseEdge(uint256)","90018343":"_forwardFundsWei(uint256)","9002dba4":"right17(uint256)","9003adfe":"collectedFees()","9003ff51":"XET2()","90042baf":"createContract(bytes)","90044d18":"phaseTwoBonusPercent()","90045412":"withdrawloss(address,address)","900526b3":"getAuthorizeContract(uint256)","90059aed":"_daysToDate(uint256)","90061292":"Bazzhtoken()","90063fd4":"payContributorByNumber(uint256)","90065125":"PropertySet(address)","900683d0":"subtraction(uint256,uint256)","90070cb3":"Contribution(address,address,address,uint256,uint256)","9007127b":"getIntValue(bytes32)","900726c2":"sellOpen()","9007cdf3":"TOXBToken()","9007d53f":"withdrawTokens4(uint256)","900863e7":"depositTeamPerfit(uint256)","900888a3":"unsetERC777(address)","9008d64f":"getHolderInfo(bytes32)","90099ece":"preIcoOpen()","900a0285":"double(bytes32,uint8,uint256)","900a974e":"end(string)","900b7b62":"getWorkerAddress(uint256)","900cf0cf":"epoch()","900cff49":"getEsgoTXFund(uint256)","900d33d9":"createContractCar(string)","900d3812":"registerTransaction(string,address,uint256)","900d6f39":"maxStage1AllocationPerInvestor()","900d85fa":"updatePreReleaseTree(bytes32)","900dd918":"newTransferManualTokensnewTransfer(address,address,uint256)","900ddb58":"WCF()","900e1248":"sendlimit()","900e1561":"changePersonalMincap(uint256)","900eb5a8":"currentValidators(uint256)","900f080a":"reveal(uint256[],bool[],bytes32[])","9010470d":"markAsComingAndFreeze()","90107afe":"setAddresses(address,address)","9010c70b":"defaultLockBlocksForPool()","9010f726":"getKeysByPurpose(uint256)","90126acf":"optionsExercised(bytes32,address,address)","9012c4a8":"updateFee(uint256)","90135fec":"maxReached()","9013ad18":"activateUser(address,address)","9013d1ed":"startChallengePeriod(bytes32,bytes,address)","9014b075":"clockairdrop()","90152ddb":"Liutestcoin(uint256,string,uint8,string)","9015e1dc":"getPlayerAddressById(uint256)","9016bc21":"client_address(address)","9017006e":"getDevFees()","901717d1":"one()","90171e57":"setBonusRound1(uint256)","9018c431":"serServerStatus(string,uint256)","901b2036":"totalSpins()","901b4301":"evacuate(address)","901b9249":"round(int256,int256,bool)","901c4e4f":"deployVault()","901c7518":"commRate(uint256)","901c947f":"showContractBalance()","901cea7b":"allocateEcosystemTokens()","901d7775":"voteOutMasterKey(address)","901da0df":"ownerTokenTransfer(address,uint256)","902025bd":"OfficalHolding()","9021c03d":"creditDividends(uint256)","9021dd30":"MinBetAmountChanged(uint256)","90232694":"toMemory(uint256,uint256)","90236e76":"Short()","9023c993":"YupieToken()","9025ab6d":"ethTransfertoKYC(uint256)","9025e64c":"networkId()","902650aa":"initCards()","9026ad2e":"AbstractSweeper(address)","9026bd65":"RaffleGraphBook(string,uint256)","9026dee8":"checkAdmin(address)","902753f4":"verificationOff(address)","9028353a":"founder2Address()","9028f20b":"bodyElementBySubtypeIndex(uint256)","9029444a":"getMemberAddress(uint256)","9029a32b":"updateRausPoint(uint16,int256,uint16)","902a83cd":"addReleaseAuction(uint256,uint256,uint256,uint256,uint256)","902ab12f":"TestTest()","902c0dcc":"BalancesInitialised()","902c3ad7":"LOOMIA1_ADDR()","902c6811":"ProtectedReclaim(address,address,uint256)","902c92b7":"playHand(uint8,uint8,uint8,uint8[5],uint8[],uint8[],uint8[])","902d55a5":"TOTAL_SUPPLY()","902e64e5":"Oath()","902eded3":"eip165Supported(address)","902f1492":"registerPayment(address,uint256)","90300e38":"calNewTokens(uint256,string)","90304341":"safeToSub(int256,int256)","9030e40f":"totalFundRaised()","903171ae":"foundationTokenWallet()","9031bd2f":"_buyTokensFromSeller(uint256)","90323075":"TrustlessTransferStatusModified(uint256,bool)","9032bfc8":"setDaySecond()","9032f1a9":"createBenzTicket(address,uint256)","9033de61":"FricaCoin()","90347678":"numclaimed()","9034b427":"numDonors()","9035b4ff":"Biniu(uint256,string,string)","9036420a":"Cosmo()","903833cc":"setMemorySize(uint256)","90393fc8":"maxPerTeam()","9039e01d":"newDay()","903a3ef6":"finalizeIco()","903a8298":"subscriptionCounter()","903b1f20":"enact_withdrawal_less(address,uint256,uint256)","903cc583":"calculateTokens(uint256,uint256)","903d0ac0":"publicAllocationTokens()","903d3340":"balanceOfFlower(address)","903d9b2f":"Webrypto()","903db106":"x(bool)","903e95a9":"DeskToken(address)","903f2c48":"isAuthenticating()","903ff4fc":"AssetDK3()","90414116":"Period()","9041bdeb":"BNW()","9041f2c8":"WithdrawProposalFund(uint256)","9041f960":"manageTransferLock(address,bool)","90427b6c":"dev4Wallet2Pct()","9042aa27":"paymentForkIndexes(uint256)","9042bbf3":"prizeClaimed()","9042dcd9":"prizeMoneyQuantity()","90430c00":"getVersionImplementations(bytes32,bytes32,bytes32)","90431b6e":"withdrawAllFromToken(uint256)","90445e9f":"getPlayerNb(uint256)","9046fefd":"NewCurator(address)","904740cd":"getOscar()","9047ad74":"activateProject(address)","90483aa1":"PowerLedger(address)","9048816f":"resultConfirmed()","9048f510":"createContractGame(string,uint256)","904a7d4c":"midasDeposit()","904aaf8f":"foreground()","904adc3d":"ERC23TokenMock(address,uint256)","904b46a1":"NEOToken()","904b67c2":"IcoClosedManually()","904bd6d0":"setTokensPerEther(uint256)","904c6094":"contractHash()","904cbd79":"depositCommission()","904d2248":"betHashOf(address)","904d3f47":"IADAddress()","904d5ed6":"Update_Cash_Proof_amount(uint256)","904da3d7":"Buyout(address,address,uint256,uint256,uint256,uint256)","904dc85d":"providerRewardLib(address)","904de64e":"TRSOffset()","904e1c88":"sales(bytes16,uint256)","90502c2e":"collectTokens(address[])","9050b560":"obligations()","9051d18a":"tokenEnabled(uint256)","90525c05":"devLimit()","905295e3":"unlockAccount(address)","9052b3d5":"_contains(address[],address)","9053ef56":"onReceivePrivate(address,address,uint256,bytes)","9053f420":"trade(address[8],uint256[6],uint256,uint8,bytes32,bytes32)","905473cf":"updateMaxJump(uint256,uint256)","9054bbb6":"INITIAL_TAP()","9054bdec":"toTimestamp(uint16,uint8,uint8,uint8,uint8,uint8)","9055172d":"UVDToken()","905529be":"startCrowdsales(uint256)","9055bc12":"QRToken()","9055ffb0":"trackTreasuryToken(uint256)","9057bc48":"canStopWork()","9057f289":"createListing(address,uint256,uint256,uint256,uint256)","9058c8a4":"setBuyFeeBps(uint256)","9058e228":"buy(address,bytes32)","90596dd1":"controllerBurn(address,uint256)","905a7649":"RegisterTransaction(address,uint256)","905a90fe":"numberImmortals()","905ae5f5":"fechCurrentStageIndex()","905b7256":"_rewardLotteryWinners(uint256,uint256)","905b8000":"CountStudentnRequests()","905bd5e4":"superTransfer(address,address,uint256)","905bebe9":"solveProblem(uint256)","905c949e":"AURIX()","905d326c":"_newCampaign()","905dca52":"haveEitherAttribute(address,bytes32,address,bytes32)","905e6e42":"JSON_Test()","9060091c":"setAmountToken(uint256)","90603bdb":"getEscrowsByOwner(address)","90604005":"cln()","9060e35d":"Voronezh()","9061a6e9":"increaseSoldSaleSupply(uint256)","9061aedd":"fundOnContract()","9061da22":"MANHATTANPROXYEASTENDAVE()","9062145a":"CreateXPA(address,uint256)","906273a3":"asyncTokenSend(address,uint256)","9062a445":"setGameAddress(address,address,address)","9063e860":"transferOrigin(address,uint256)","90645840":"newHash(uint256)","90646b4a":"setGateway(address)","9066314e":"toggleLastChance(bool)","90664cf5":"armyAircraftCarriersCount(uint256)","906686a6":"totalIssueTokenGenerated()","9066c472":"addRoyaltyReceiver(address,uint256)","90676901":"stallionWith(uint256,uint256)","9067b677":"getEndTime(uint256)","906802cf":"tokensUnlocked()","906860d9":"Whitelist(address,address)","906a114c":"getAllMoneyOut()","906a26e0":"softCap()","906ab111":"preIcoTokenSales()","906b23be":"TOKEN_FOUNDINGTEAM()","906ca728":"viewReservedTokens()","906d5785":"setTeamContract(address)","906d895d":"getAvailableSeats()","906e1ec0":"canWriteName(address,bytes32)","906e9400":"newManager(address)","9070222e":"getCardIdByRank(uint256)","9070b18d":"_getAllRevisionBlockNumbers(bytes32)","9070e8a5":"validContracts(address[])","90714770":"finalizeFirstStage()","9072d58a":"registerPullPayment(uint8,bytes32,bytes32,string,string,address,address,string,uint256,uint256,uint256,uint256,uint256)","907316a9":"_getEarnings(address,address,uint256)","90731848":"minPriceForNextRound(uint256)","9073280b":"SFTPRECOE()","9073576c":"UnfreezeAccountByTime(address)","90742e52":"initsegmentation(address,uint256,uint256)","90753533":"activateMainIco()","90754979":"sendPriceRequestToOracle(bytes16,bytes16)","9075726e":"SeeSourToken()","9075b10c":"LogWhiteListedMultiple(uint256)","9075becf":"multisigWallet()","9075f124":"setAccountVerified(address)","90762a8b":"ownerBurnToken(uint256)","907631fc":"toBool(bytes,uint256)","9076a38a":"getBackgroundImageCount(address)","9076aff7":"lastBlock_a4()","9076c166":"setAllocation(address,uint256)","9077309b":"burnSoupTokensForDay(uint256)","90778ab9":"issueToken(address,address,uint256,uint256,uint256,uint256)","9077dcfd":"submitCoding(string,uint256)","90785418":"addPiece(string,string,bytes32,address)","9078b596":"changePrice(bool)","90797634":"ident()","907a37c5":"getCandidateDetailOnElection(address,address,uint256,address,address)","907af6c0":"unit()","907b0305":"createERC20(address,uint256,string,uint8,string)","907b270b":"priceEthPerToken()","907b503d":"depositedToken(address)","907be394":"operationsFundAddress()","907c5082":"assignTeamTokens()","907dff97":"_emit(bytes,uint256,bytes32,bytes32,bytes32,bytes32)","907f67ee":"pauseBuyback()","907f7aa8":"cancelSellOfferInternal(uint32,bool)","9080345d":"Role(bytes32,address[])","9080c78c":"tixNumberforSale()","90810c77":"multivestBuy(address,address,uint256)","9081c3db":"markHours(bytes32,int256)","90825c28":"getMarketCap()","90828c78":"nextPromiseId()","90828cdd":"getCreateMarketUniverseValue()","90835848":"getCurrentRoundTotal()","90836822":"DXC()","90838e09":"totalInvested(address)","9083998b":"TechnoBit()","908408e3":"Initialized(address)","90843cd9":"fetchAllCreatedOrders()","90843d04":"numIncrement()","9084f1f9":"closeMotion(uint256)","90855c31":"ACT(uint256,string,string)","9085b77f":"allowed(address,bytes32,address,bytes4)","9085e88d":"giveBlockreward()","90862d1b":"unfreezeTokens(address)","908687a9":"Simoleon()","90869e9f":"getMartialNumber()","9086de3b":"isWhitelised(address,address)","90888aa1":"StakeObjects()","908921fc":"ceo()","90895e1c":"setAllocatedToken(address,address,address,uint256)","9089e0c2":"UnicornCoin()","9089f616":"removeClient(address)","908ab6a5":"roleHash(address,bytes32)","908b8cfc":"withdrawOperationalExpenses()","908c3a6a":"tokenUserCounter()","908ccc5e":"numberOfRecordEntries()","908d16de":"BountyAgentChanged(address,bool)","908da4e8":"timeTier1()","908dd411":"getFundAlterations()","908e049b":"destory(uint256)","908e2d2a":"maxCoinCap()","908e2f06":"mails_to_deliver()","908f68ee":"unrespondedCnt()","909006fc":"setDirectOffersComissionRatio(uint256)","90900df4":"addDebt(bytes32,uint256)","90905360":"setDividendsPercent(uint256)","9090ce1f":"CANCELATION_DATE()","90912d09":"pausingMechanismLocked()","9092b623":"PotOfEther()","90935301":"setCryptaurReserveFund(address)","90938792":"canVoteAs(uint32,int256,address)","9093bc3d":"addCoins(uint8,uint8,uint256)","9093f5d1":"ReverseBugBounty()","90949f11":"getNumberOne()","9094b22f":"setAttribute(address,address,string,bytes,uint256)","9094c763":"vote(uint32)","9095269d":"mintExtraTokens()","909540cb":"ERC165()","90954483":"createLandmark(string,address,uint256)","90957363":"removeFromFutureExpanstionMap(address)","9095b2cd":"IPcoin()","9095df68":"library2function()","90971fea":"ecrecoverWrapperView(uint8,bytes32,bytes32)","90972e89":"LogReceivedEther(address,address,uint256,string)","90974795":"getall()","90979943":"IRB()","909862b7":"updateSalary(address,address,uint256)","9098f074":"buyServiceByAdmin(uint64,uint64,address)","909c36b5":"newEntry(bytes32,bytes32,bytes32,bytes16,bytes1,bytes16,bytes32,bytes32)","909c9fca":"reclaimExpiredSwaps(bytes32,bytes32)","909d22c7":"many_cryptobanks()","909d2cc1":"hasTeam()","909d3bc9":"isIdle(address,uint64)","909d6877":"preSaleLimit()","909e4ab6":"getLog()","909e8f92":"unlockFirstPrivate()","909ec524":"KyberAirDrop(address)","909f2c3a":"ChangeNumber(string)","909f617e":"fill(address[5],uint256[6],uint256,bool,uint8,bytes32,bytes32)","90a08e70":"balanceOfUnclaimedGoo(address)","90a0a2ab":"GetPriceOfTroops(uint256,uint256,uint256)","90a1d580":"TSTEST2()","90a2005b":"transfer(bytes32[])","90a251da":"createNewTankWeapon()","90a25f28":"WeBetCrypto()","90a2e1ef":"emergencyReserve()","90a3d87e":"addLanguage(string)","90a4d287":"bovBatchDistributed()","90a53085":"votesCountByOperation(bytes32)","90a59ea1":"BasicAccountInfo(uint8)","90a5c7af":"Lesson_1(address,uint256)","90a6267a":"canRescue(address)","90a650e8":"UpgradeAgent(address)","90a70139":"pauseTransfer()","90a72a3f":"FundingCapSet(uint256)","90a744fe":"BossCoin()","90a7ba5b":"ticketsPurchased()","90a85119":"checkBetResult(uint8)","90a897c6":"frozenAddress(address)","90a971a8":"setPI_edit_27(string)","90a9cc02":"namiPresale()","90aa2185":"dailyCount()","90aa835c":"IsAuthorityAddress(address)","90ab54dc":"configureMigrate(bool,address)","90ab7d34":"deployRuntimeContract()","90abcb08":"TronyCurrencyContract(uint256,uint256)","90ac11a3":"designs(uint256)","90ac1866":"setMinGasPrice(uint256)","90ac3f4c":"_getTokenAmount(uint256,address)","90ac7588":"profitsLockedUntil()","90acc740":"transferCompanyTokens(address,uint256)","90ad304f":"ContractOwnershipTransferred(address)","90addc9a":"calculateMyRewardMax(address)","90ae144e":"swap_able()","90ae631d":"assignAll()","90ae6863":"gyCF()","90af1333":"allBoxNumbers()","90afca4c":"addPhases(uint256,uint256,bool,uint256,bool)","90b06593":"landClaim()","90b08a52":"getSendAmount()","90b0e078":"discountTime()","90b17f99":"directPaymentThreshold()","90b22d03":"set_parameters(uint256,uint256,uint256)","90b25207":"GoogleChainToken(address)","90b26043":"NameRegistered(address,uint256,string,uint256)","90b2ae49":"verifyDeployment(address,bytes32)","90b2ce6f":"mvnpereth()","90b30251":"is_finalized()","90b3195f":"SHAREPERIOD()","90b398ff":"SetFreeGWT(uint256)","90b3d963":"trade(uint64,uint64)","90b4cc05":"mintAdvisorTokens()","90b4cc72":"numTransactions()","90b5561d":"insert(uint256)","90b5e6d9":"presaleFinished()","90b625f9":"stockSellOrder(uint256,uint256,uint256)","90b67185":"setPrivilegeState(bool)","90b6b209":"bonuses()","90b6f7e6":"RashidToken()","90b7ddd7":"t02_createContractMac(bytes32,bytes32)","90b7df75":"addAuthByPhone(string,string)","90b98a11":"sendCoin(address,uint256)","90b9be4a":"RetailerManager(address)","90b9c31a":"purchaseFinished()","90ba0e6c":"getNumOfBettersForMatchAndPrice(uint256,uint256)","90ba34cc":"refundClaimAddress()","90baaa5c":"checkPoolEnd(uint256)","90bb5ad0":"Eth2USD(uint256)","90bb6153":"withdrawTokenBalance(address)","90bb807e":"getVolumeDiscountsCount()","90bc1693":"burn(uint128)","90bd301e":"_validCharm(string)","90bdb275":"costOfTxShares()","90bde517":"getUser(address,address)","90be0bd9":"enableAuthentication()","90bee6aa":"getTransformRate(address,uint256,uint256)","90bf0301":"changemp(address)","90bf348f":"crowdSaleMinAmount()","90bf495d":"tokensReleasedToEarlyInvestor()","90bf693b":"logoFee()","90bf87a3":"setRestriction(address,uint256)","90c1288e":"setAddressF1(address)","90c2365e":"_addWeiAmount(uint256)","90c26736":"countRecommendFund(uint256)","90c32295":"bountySent()","90c3a370":"AuctionMaster()","90c3f38f":"setDescription(string)","90c40776":"donotIronDappToken()","90c459a3":"lnLimited(int256,int256)","90c46985":"calculate_difficulty_attempt(uint256,uint256,uint256)","90c4ce57":"getReportingWindow(uint256)","90c6087b":"_getName(string,uint256)","90c6b18a":"CreationTime()","90c6d1b9":"SetFreeTokens(uint256)","90c79af9":"startAcceptingFundsBlock()","90c8a72d":"sendOwnerShares(address)","90c8abd3":"CreateCaptainToken(address,uint256,uint32,uint32,uint32,uint32,uint32,uint32)","90c985a1":"buyCertificate(uint256)","90c98a7b":"resolveRankBoard()","90c9d6f8":"BankerExit(uint8)","90ca20e5":"init_wallet(address[],uint256,uint256)","90ca27f3":"vote(string,uint8)","90ca38d9":"setAdvisorsTokens(uint256)","90ca9dbf":"getGradeByQuailty(uint16)","90caa2b4":"getFreezeUntilDetails()","90cad537":"poolMintRate()","90cb04e1":"buy(string,uint256,uint16)","90cb4854":"createTokens(address,uint256,uint256)","90cbcf92":"getFibonacci(uint256)","90cbfa19":"abort(address)","90ccdafb":"increaseArrayOfBeneficiariesBalances(address[],uint256[])","90cd0d06":"registerApproveRequest(bytes32,bytes)","90cd5860":"VehicleRTO(address)","90cd6170":"getActiveSkin(address)","90cd8020":"licenseTermsMinCostPerSec(bytes32,bytes32)","90cddcc5":"getEpisodeDetail(uint256)","90ce9e5b":"getPreIcoInvestorsAddressesCount()","90cf3fed":"AKAIITO()","90cf581c":"voteYes()","90cf72de":"_getCommonPlusRarity(uint32)","90cf76fa":"bundleOfOwner(address)","90cf7ab4":"existsUser(uint256)","90cfce5a":"setgetgoods(uint256)","90d16b30":"resolveDisputeBuyer(address,string)","90d19241":"_removeAddress(address)","90d1c593":"Summary(address,address[],address[],address[],uint128[])","90d22eeb":"setIcosMinLimit(uint256,uint256)","90d240c6":"get_data(uint256,uint256)","90d28075":"getBasketArranger(address)","90d2cd5c":"getCurrentUserBigPromoBonus()","90d2f727":"signedApproveAndCallCheck(address,address,address,uint256,bytes,uint256,uint256,bytes,address)","90d370ba":"canReceive(address)","90d49b9d":"setFeeWallet(address)","90d4bcc0":"inject()","90d4bd45":"wetCoin()","90d58a70":"tgrCurrentPartContributor()","90d61290":"traded(address,uint256)","90d63e5d":"addAuthor(bytes)","90d68bb6":"getCallTypes(uint256)","90d6b45f":"kyc()","90d783bb":"BEEFJERKY(address)","90d83301":"SPAM()","90d8a4be":"badge(bytes)","90da7c3c":"isGeneMixer()","90daaf67":"getMinimalDeposit()","90db2aa9":"SellOrder(uint256,address,uint256,uint256,uint256,uint256)","90db623f":"increaseApprovalAndCall(address,uint256,bytes)","90db78f9":"crowdsaleInfo()","90dbf4fc":"getRequestBaseInfo(uint256)","90dc0636":"GetHoldersCount()","90dcba22":"addressPeople()","90dd027e":"migrateFrom(address,uint256,uint256,uint256,bool)","90dd2395":"listPrycto6()","90dd9d17":"perSaleWithDrawal()","90de4495":"dive5(address)","90de8234":"adminMode()","90de9ed9":"TOKEN_SALE_CAP()","90df44b4":"addDocument(string,string,string,string,uint256,uint256)","90dfb092":"privatePresale()","90e10134":"burnAdminApproval()","90e10250":"setCreated()","90e1de68":"allowedForwards()","90e2160a":"setMaxUpdates(uint256)","90e2b94b":"t0special()","90e2d4cc":"refreshLockUpStatus()","90e33e9c":"totalDDTforInterest()","90e3c278":"getShares(uint256[128])","90e47957":"erc165InterfaceSupported(address,bytes4)","90e4a130":"getMyDonations()","90e50ba7":"registerAltPurchase(address,string,string,uint256)","90e517e7":"logoY()","90e575f5":"auctionEnds(string)","90e57cac":"confirmProposalAndTransferFunds(uint16,uint16)","90e64d13":"hasExpired()","90e72127":"closeOrder(address)","90e761cd":"recoverAddressFromSignature(uint64,uint256,bytes32,bytes32,bytes)","90e7760e":"makeLive()","90e7a074":"codexStakeContract()","90e8265d":"tierDuration(uint256)","90e8317c":"rateWorkerSkills(uint256,address,uint256,uint256,uint256[],uint8[])","90e8edd8":"JincorTokenPreSale(uint256,uint256,address,address,uint256,uint256,uint256,uint256,uint256)","90e8f758":"liveEtherSportCampaign()","90e99b09":"finishRestore()","90ea0fb8":"isSignedByEugene()","90eb9632":"PROMETHEUS_PRICE_INCREMENT()","90ebed43":"getNumberOfCourses()","90ec028d":"LogPollCreated(bytes32)","90ec57f1":"Approve(address,uint256)","90ed6bf4":"startWithdraw()","90ee2ec2":"FCCPlaceHolder(address,address,address)","90ee4331":"getStartClaimDate()","90eed0ce":"SetCert(uint32,bytes32)","90eede26":"COMM_ADDR()","90ef08a1":"getdrawtoken(address)","90f08b32":"contract2Address()","90f098bb":"setFeeTake(uint256)","90f0a5bd":"BecomeTadpolePrince()","90f0dbd5":"CRSAllocation()","90f0f4f4":"ReserveFundAmount()","90f0fef0":"test2ContractVote()","90f1d909":"Ixellion()","90f25eb3":"getPercentages()","90f2c86d":"convertToWei(uint256,string)","90f2dc88":"getObjClassId(uint64)","90f3b693":"initialIssueMinted()","90f3deb1":"getTeamUnlockAmountHelper(uint256)","90f4c33a":"transferSaleWallet(address)","90f4d2fd":"checkMaxCapReached()","90f50cd9":"setPromo(address[],uint8[])","90f52ade":"LOTT()","90f549ba":"getLockCountForAddress(address)","90f551ec":"offerBtcFromApp(address,uint256)","90f5c2ca":"canRef(address,address,uint256)","90f5f99d":"DHUBTest()","90f6b2b3":"getInvestorByValue(address,address)","90f81702":"BaseToken()","90f8c118":"hyip()","90fa17bb":"constructor()","90fa337d":"storeBlockWithFeeAndRecipient(bytes,int256,int256)","90fa775e":"_calculateInflationBonus(uint256,uint256,uint256)","90fa8910":"GetBasePrice(uint256,uint256)","90faa3e9":"setPrice(string,uint64,uint8)","90fab7ce":"just50Send()","90fad1e6":"remove_from_whitelist(address)","90faeb62":"DolarToday()","90fbf84e":"trustedFeeWindowTransfer(address,address,uint256)","90fc2a32":"CaptainGameConfig()","90fcf551":"getTRIOs()","90fd4300":"releaseState4()","90fd53ec":"farmTile(uint8,uint8,int8)","90fd5452":"blockState()","90fd67fc":"setDepositAddressVerify()","90fdf36b":"_vouchersToWei(uint256)","90fe5609":"startVoting(uint256,uint256)","91006745":"isAdmin(address,address)","91014fcc":"_updateWhitelist(address,uint8)","9102bcc8":"Teacher(address)","91030cb6":"lockPercent()","9103321d":"TOTAL_TOKENS_AVAILABLE()","91039c83":"updateEndTimeManually(uint256,uint256)","9103cfb6":"TheophanesToken()","9103e368":"winnerTimestamp()","9104b6f4":"getPendingWalletFeeData()","9104c316":"internalBurn(uint8,address,uint256)","9104dbd2":"_createCompany(string,address,uint256)","91051e06":"poolWithdraw()","910545ff":"TOKEN_PRESALE()","91057f53":"ERC20TokenCPN()","91060168":"fetchString(address,bytes4,bytes32)","9106d7ba":"totalSold()","910887bc":"setPublisherCut(address,uint256)","91093ba4":"setUintF1F2(uint256,uint256)","910cbda6":"buyTokensFor(address,address)","910d52ea":"getPaperFee()","910eba1d":"buyBonds(address)","910f3b52":"bidFromEtherScrolls(uint256,address)","910f5b81":"preIcoStartTime()","91104f82":"bountyTokenAmount()","911058df":"setMockedNow(uint256)","91125fb7":"thirdWeekBonus()","91127c1f":"_clearApproval(address,uint256)","91136d3f":"Settlement(uint8,bool)","911402f1":"masterServer()","9114557e":"vestedBalance(address)","911463d2":"setPOOL_edit_27(string)","911475cc":"incNonce()","91147dfa":"restoreContract()","91149e85":"resetOfferingStatus()","91152c5c":"airdropTokens()","911550f4":"getBetterOffer(uint256)","9115abf4":"getDetails(uint256,address)","9115ca43":"getPayerString()","9115e9ee":"ExtractEtherLeftOnContract(address)","911644fa":"maxIceDragonsCount()","9116ee03":"testHasCorrectPriceForStages()","91174790":"addEvidence(bytes32,uint256,bytes32)","91174cb6":"roundnum()","91176f39":"presaleUnlimitedStartBlock()","91177db4":"batchTransferFrom(uint256[],address,address)","9117c6df":"balanceOfReadable(address)","9117e32e":"expireOf(address)","91184159":"getOptionHash(address[3],uint256[3],uint256[2],bool)","9118575a":"setTokenSale(address,address,uint256)","91194aab":"tixFoundersDeposit()","9119e5fb":"submitTransactionWithSignatures(address,uint256,bytes,uint256,uint8[],bytes32[])","911a40c9":"ARPToken()","911a56bc":"totalSupplyWithZeroAddress()","911a739e":"winnerLimit()","911a9ac0":"preSeasonGame()","911adc1a":"pay(address,uint256,bytes)","911b5f4e":"sub(uint64,uint64)","911cec25":"getMountTokenIds(address,uint256,address)","911d0189":"minJackpot()","911d731a":"DWBTToken(uint256,uint256,uint256,uint256)","911d84cb":"updatePlayerRecommend(address,address)","911eb255":"approvePromise(address)","911ef2e9":"Voted(uint256,bool,address,uint256)","911ef508":"pausedTimestamp()","911fa5c9":"totalTokenSellAmount()","911ff22b":"EthereumRateUpdated(uint256,uint256)","911ffbdb":"lastRewards(address)","91214841":"usdraised()","912221d5":"tokenCost()","9122acd8":"KUYCToken()","912308dc":"withdrawToInvestor()","91240f44":"getReferee(address)","9124f1cf":"getOrderHash()","912525f4":"WideEnergy()","91256ed0":"freezeMustCalculate(uint256)","9125ecf1":"bountyVaultAddr()","9127bc2a":"FOUNDERS_TOKENS_LOCK_PERIOD()","9127d3d7":"EXPECTED_TOTAL_SUPPLY()","9127da7e":"RRcoinToken()","912875bc":"ICO_PRICE6()","91287962":"artworkRegister(address)","9128bbc6":"Tanaka()","91294ed1":"minContributionWei()","912bcb79":"betGame(uint256,uint8)","912c3fbf":"EYToken()","912c8b75":"claimGold(uint64,uint64,uint64,uint64)","912d6e28":"approveTokens(address,address,uint256)","912de8de":"fixBalance()","912eb6d9":"amountOfUBOsold()","912ee23d":"SaleStarted()","912f6ba4":"getAtheniansOnTheBattlefield(address)","912f6c71":"IssueIQTToken()","912f952f":"Ulti()","912ff8f6":"getServerState(uint256)","91301852":"CyberClassicToken()","91304f1f":"isKYCRequired()","913093aa":"initialSupply(address)","913158f7":"getIsland(uint256)","91318874":"setRates(uint32,uint32)","9131d803":"testSetFrontend()","91324514":"InfiCoin()","91324bea":"EscrowContract(address,address,uint256)","91329493":"charityCount()","9132b81d":"VotingStarted(address,uint256,uint256)","9132c26c":"calcSELLoffer(uint256)","9132dfca":"CATA()","913579b6":"updateWhiteListImplementation(bool)","913594ae":"JETUSA()","9135ac08":"addInInitialSupply(uint256)","91361f64":"getRankPriceCandy(uint256)","913683fc":"IODTOKEN()","9136d392":"KothWin(uint256,uint256,address,uint256,uint256,uint256,uint256,uint256)","91373711":"stopFlagOff()","9137471b":"setGoldBought(uint256)","91375e8d":"getGameEndTime()","91378400":"POSAddress()","91378456":"publicTGEEndBlockTimeStamp()","9137b6e6":"addAction(uint256,string,string,uint256,bytes32,uint256)","9137c1a7":"setStorage(address)","9137d10a":"refreshDirectSellParameter(uint256)","9137f9b1":"viewSecondLotOfClauses()","9138f38b":"claimTokensERC20(address,address,address,uint256,uint256,uint8,bytes32,bytes32)","913918a6":"changeSaleInfo(uint256,uint256,uint256,uint8,uint256)","913967d0":"getNextFeePercentage()","91398f25":"getTransferringFor(address)","913b1ecc":"setGroupWinner(uint256,uint256[])","913b2958":"appealRuling(uint256,uint256)","913cc77f":"setEthValueAmount(uint256)","913cf5ca":"eos()","913d23e2":"distributeMnyAfterSwap(address,uint256)","913d30b0":"LIDToken()","913d6906":"VotingToken(string,string,uint256,string,string,string,address,address,address,address)","913dd846":"PRESOLD_ADDRESS()","913e0887":"FundingRulesSet(address,uint256,uint256,uint256)","913e77ad":"collector()","913f424c":"_ecMul(uint256,uint256,uint256,uint256)","913f4766":"Refound(address,uint256)","913fb60b":"colorLeaderboard()","913fbd04":"aidPoolWallet()","913fc67a":"bidoohAdminAddress()","91404af8":"updateTokenRatio(uint256,uint256)","91407479":"Eth2USD_power18(uint256)","9140a101":"checkRegistrar()","9140a499":"updatePublicCheck()","9140f6ee":"releaseRestPreSaleTokens()","9140f968":"newInvestment()","91410c97":"stake_reward_rate()","91410e41":"getMyRecordCount(address)","91415ce9":"TRANSFERMANAGER_KEY()","9141bfae":"LogReveal(uint256,address,uint256)","9141d6f9":"unset(bytes32)","91421cf6":"ECRCTOKEN()","91423ef2":"getClientLastSupplyID(address)","91432155":"setBaseInterest(uint256)","91436eee":"issueLeftToken()","91441589":"run(bytes,uint8[4],uint8[2][4])","91449def":"_owns(address,uint256,bool)","9144f267":"ALBtoken()","91458ee8":"GameCreated(bytes32,string,string,uint16,uint64)","9145a7fd":"CrowdsaleEnded(uint256)","9147dd1b":"pricePresale()","9148018a":"getChatMessageAtIndex(uint256)","914810a3":"claimRepository()","91481123":"contestOverTime()","9148148b":"migrate_game_balance()","9148b237":"takeAllOrRevert(address[3][],uint256[3][],uint256[],uint8[],bytes32[],bytes32[],bytes4)","91492956":"getPrices(uint256)","914946aa":"getSignerAddresses()","914980d4":"setBonus(address,uint256,bool)","91499e2d":"disableService(uint256)","914a1e76":"getWinRate(address)","914a5b24":"popPlayer()","914ae352":"getCurrentNumberOfUsedServiceTokenWei()","914b7fd2":"calculateSellGoldFee(uint256,uint256)","914bdef8":"_transferWithData(address,address,address,uint256,bytes,bytes,bool)","914d581d":"fiatRaisedConvertedToWei()","914dde1c":"isProposed(address)","914de6d6":"MarketingAllocation(address,uint256)","914e1ee1":"resetSearchStartIndex()","914f716d":"BalanceHolder(address)","914ff398":"batchFill(address[5][],uint256[6][],uint256[],bool,uint8[],bytes32[],bytes32[])","915009a7":"getPaperFromMeta(uint256,uint256)","915015c5":"setColorBlack()","91508264":"getNextPrice(uint256,uint256)","9151c7e4":"GrandFraternityChain(uint256,string,string)","9152486c":"currentInitPart()","9152f0b2":"getLastRequestId(uint256)","9152f764":"WorldCup(string,string,uint256,uint256,string,uint256)","9153d09a":"stringFloatToUnsigned(string)","915489f6":"futureTokens()","91548ccf":"ticket_address_added(address)","91555559":"getNumWeiAddressMayInvest(address)","9155b01a":"setSelfClaim(bytes32,bytes32)","9155cc2c":"HitToken(string,string,uint8,uint256,uint8,uint8,address,address)","9156a003":"totalTokensIssued()","9156fb60":"addressERC20Token()","9157e556":"isQualitifiedAddress(address)","915a405f":"updateTransferMinimumFee(address,uint8)","915b5bfc":"NeoWorldCash()","915cfeac":"getTransferAgentStatus(address,bytes32,address)","915d44f6":"setRFFSessionsAdd(address)","915db230":"marketBuyOrdersNoThrow(uint256,bytes[])","915e1044":"strFunc(string)","915e5d44":"apply_compensation()","915ed87e":"LiveStarsTokenPresale(uint256,address,address,uint256,uint256,uint256,uint256,uint256)","915f3209":"changeMaximumValueDuringGuaranteedPeriod(uint256)","9160342e":"Sale(address)","91603691":"HDTTokenTest()","91607530":"RaisedByPartner(address,uint256,uint256,uint256)","9160aabc":"getPendingBetCount()","91613e4b":"FTC()","9161f789":"getRoundFunds()","9162a905":"GDCNumber5()","9162ab43":"MiningStolenPayout(address,address,uint256,uint256)","9163f897":"block6()","91647938":"saveMatchJoinAddr(uint256,address)","91656aa9":"changelp11(address)","916576c8":"fundForSale()","91658639":"ChampionSimple(uint256,uint256)","916635c6":"log_mint(address,uint256)","91667aef":"getTokensPurchased()","9166a449":"totalTokenSaleCap()","9166b10a":"IcoAbandoned(string)","9166cba4":"sai()","9167c5ad":"removeClientToken(uint256)","91684f8d":"MMR(address)","916891aa":"allocateReserveAndFounderTokens()","916a2b29":"_removeHorseFromStud(uint256)","916a476e":"save3(address,bytes,string)","916a4b57":"addPet(uint256,uint256,uint256,uint256,uint256,uint256)","916b5cfa":"TIMEstartICO()","916be4fe":"HELP4HUMANITY()","916c99fd":"getCampaignEndPointById(bytes32)","916dbc17":"getPlayersFromCompetition(string,uint8)","916dbc9e":"Coin786token18()","916df92a":"Round()","916dfea2":"getPersonalBonus(address)","916e5901":"teamTokensLock()","916e93f8":"ecrecoverFromVRS(bytes32,uint8,bytes32,bytes32)","916eb6eb":"SetRoundResult(uint8,uint8,uint8,uint8,uint8)","916f5de1":"_emitJobOfferAccepted(uint256,address)","916f7c23":"setSelled(uint256,bool)","91702ddc":"highCompose(uint256,uint256,uint256)","91704e1e":"getBid(bytes32)","917105d4":"_takeOwnershipOfToken(uint256)","917116f2":"NewSellPrice(uint256)","917180c7":"setColdWallet1SplitPercentage(uint256)","91735092":"assignToEarlyBirds(address[],uint256)","9173a610":"createGame(string,uint256,bytes32[])","917418c1":"setMinRoundSize(uint256)","917569a8":"weiPresaleMax()","917603e5":"getNumberOfMyGamesCompleted(address)","917640b5":"getSELabels()","91778b9c":"changePrice(uint8,uint256)","9178732f":"warriorsOnTheBattlefield(address)","917ada14":"testControlCreateShortIdAlreadyExists()","917b4f8b":"TQXToken()","917d009e":"getAuctionPrice(uint256)","917d2be2":"wolkGenesis(uint256,uint256,address)","917ec8e2":"removeApp(uint32,string)","917f635c":"wct()","917fcc5d":"addJobProposal(uint256,string,uint256)","917fd839":"buyGEN0Chibi(string,string,uint8,uint256)","91814577":"renameStoreTo(bytes32)","91816981":"getProfitPercentForData(uint256)","91828a2e":"extra_bonus_duration()","918307fd":"getRemainOfStage(address,uint256)","918359c6":"needsBirth()","91837535":"getgateway()","9183d360":"CreateINDI(address,uint256)","9183fd01":"getSeedPrice()","91854684":"pollBallot(uint256,uint256)","91858734":"takeControl()","918657cb":"token_information()","91872a91":"isEmpty(string,string)","9187300e":"getTokensForSale(bool)","91876e57":"withdrawAuctionBalances()","91878995":"MYCOIN()","9188451b":"transferUserGrowthPoolTokens(address,uint256)","91885e1d":"nextWeaponID()","918898a5":"frozenRules(address,uint256)","9188d312":"getCard(uint256)","9189a59e":"sweeper()","9189edd2":"Zinoder()","9189fec1":"guess(uint256)","918a15cf":"toEthSignedMessageHash(bytes32)","918a2e0c":"AccessoryCollection(uint256)","918b8326":"startSto()","918c00c6":"LogCommit(uint256,address,bytes32)","918c783a":"hasPurchased()","918ca01d":"BurnConfirmed(uint256,address,uint256)","918d407d":"acceptOffer(uint256,address)","918e2c3d":"GetUserExtraData3(address)","918f1bb5":"ProjectKudos()","918f49ec":"NDCOIN()","918f5f74":"setMinBonusTrigger(uint256)","918f644e":"getScriptsCount()","918f8674":"DENOMINATOR()","91914b30":"setTokenUrl(address,string)","91915ef8":"setCapacity(uint256)","91916a5e":"Test(uint256,uint256)","9191b520":"PlatinumToken(uint256,string,uint8,string)","919203a0":"moveTokensFromStockToSale(uint256)","91923d7f":"delSuperInvestor(address)","9192f48e":"setLocked(address)","9193b2e3":"request(address,uint256,uint256,address)","9193ba0b":"createForwarder(address)","91959fe3":"getCalFactor(uint32)","91962739":"setWhiteListOwner(address)","9196bdd5":"ggc(address)","9196e481":"getAllSteps()","91970cba":"saftInvestorAllocation()","919747fb":"depositFunds(address)","91975e22":"ManagerDisabledEvent(address)","91977c56":"setDTR(address)","919823df":"getHashExists(string)","919840ad":"check()","91988783":"IMDEXdepositToken(address,uint256)","9198e08c":"Linfinity()","919987bc":"rewardPool_()","9199a8bb":"dnnHoldingMultisig()","919a41dd":"endFight(uint256,uint256)","919aa4fa":"ZIGICOIN()","919acf1e":"getperiodlasttime(address,address)","919b30cf":"FTXToken()","919baade":"ProposalsEntity()","919be880":"createEscrow(bytes16,address,address,uint256)","919beeb1":"calculateRate()","919bf699":"EggsPurchased(address,uint256,uint32)","919c9d4a":"getAfterIcoPeriod(uint256)","919ca82d":"EtherprisesLLC()","919d3401":"MAXIMUM_ICO_TOKENS()","919d8bb2":"TokenTrader(address,address,address,uint256,uint256,uint256,uint256,bool,bool)","919e144c":"predict(uint16,uint8)","919e1967":"Ubiq()","919e7f42":"supportNewMoon(address)","919edc7c":"getChainySender(string)","919f31c2":"Ankr()","919f8cfc":"makerDepositEther()","919f90ca":"sendCommissionToOwner(uint256)","91a01414":"getPreviousBlock(uint256,uint256)","91a0ac6a":"equity()","91a0ba00":"icoRound1()","91a1896e":"setReserveForFoundersSecond(address)","91a1f16a":"getMaxWin()","91a266ac":"totalEthCharityRecieved()","91a34006":"getInitializeOutcomeValue()","91a3cec0":"receiveEtherFormOwner()","91a49300":"purchaseEnable()","91a553df":"developer_add_cost_of_transfers(string)","91a57544":"affiliatePercentage()","91a5b0c7":"bestSum(uint8[])","91a67e1e":"tokenFrozenUntilBlock()","91a73892":"getOrderStateHelper(uint256,uint256)","91a73a27":"cleanSellShareOutput()","91a7aa37":"Chain2()","91a852f6":"changeTicketFee(uint256)","91a89712":"link(address)","91a90014":"_updateTokenRates(uint256)","91aa94f1":"setPresidenteDeMesaVerify(bytes32,uint256,uint256,bytes32)","91aabeb5":"checkArea(uint32[],address)","91aac477":"addNacToNetf(uint256)","91aadff6":"OPEN_SALE_STAKE()","91aaf2e9":"presaleTokenAmount(address)","91ab0ca0":"authorisedContract()","91ac2c3f":"testCreateElection()","91ac46f5":"centRaised()","91ac7e65":"indexOf(uint256)","91ac96a9":"pendingWinners(uint256)","91acd8fb":"DEJToken()","91ad1ada":"VernamPrivatePreSale()","91ad27b4":"getInterval()","91ad48a1":"DataToSetting(uint8,bool,uint8)","91af8d14":"recalculateTopScores(uint256,uint256,uint256)","91afc432":"setUpdaterAddress(address)","91b1a02a":"SwissCryptoExchange(address,address,address,uint256,uint256,uint256)","91b22ebf":"getTokenAmountPerHeritor(address,address)","91b23419":"developerFund()","91b2413f":"HplusToken()","91b25b35":"revokeAndSetNewMember(uint8,bytes32,address)","91b2b30e":"LogI(uint256)","91b43d13":"fundingEndBlock()","91b4a0e7":"Difficulty()","91b4ded9":"lastPauseTime()","91b56822":"gameTick(uint256)","91b584f3":"_insertValidator(address,uint256)","91b6a086":"WithdrawToInvestor(address,uint256)","91b7ad06":"calculateTokens(address)","91b7d3e0":"redeemSurplusERC20(address)","91b7f5ed":"setPrice(uint256)","91b8a49a":"lastDonor()","91b97997":"endFirstWeekICO()","91b9b640":"getDApp(string)","91ba5d6a":"preICOMany(address[],uint256[])","91baabba":"CCLToken()","91bb2534":"impl_price()","91bb4816":"m_Database()","91bbb21a":"trialDeadline()","91bbb87b":"GetPurchaseInfo()","91bbbe4d":"_payoutTaxes(uint256)","91bbd6f6":"VeiagToken(address)","91bbdcc7":"convert()","91bc85a9":"SetTrustee(address)","91bc8a45":"bonusAdd()","91bdc458":"blockNewSpinnerPurchase(uint256)","91bdf9da":"isTen(uint8)","91be0b31":"setPriceChanger(uint256)","91be2f8d":"changeCCCoinAddress(address)","91be90c8":"_dust(address)","91bf9c50":"test_CampaignRulesFail()","91bfeb98":"CrystiumToken()","91c03391":"TraToken()","91c05b0b":"distribute(uint256)","91c11cae":"disputeTransaction(uint256,uint256)","91c1e2c1":"burnedBalanceOf(address)","91c20375":"setArtEsc(string,string)","91c23928":"divSafe(uint256,uint256)","91c259ea":"transferby(address,uint256)","91c27b2a":"setTransTimes(uint32)","91c3352e":"test_invalidEmptyEqVal1()","91c3e5ee":"rb(address)","91c3e7f8":"showlvzhou(address)","91c4529f":"isBlacklistSpender(address)","91c49026":"rebalanceEnclaves(address,uint256)","91c4c78f":"fund(address,uint160)","91c62a5a":"LogBounty(address,uint128,string)","91c71e2b":"disableLock(bool)","91c72d88":"holdSubscriptionOffer(uint256)","91c79a9a":"CON0217()","91c827a0":"AddOwnerAddress(address,address)","91c873cb":"getAdminContract(address,uint256)","91c8e336":"exchangeSupply()","91cadaf6":"evolvePrice()","91cb4316":"endOf24H()","91cb98af":"getPendingAmount(uint256)","91cca3db":"dev()","91cd242d":"setMeta(bytes32,bytes32,bytes32)","91cd450c":"AlienFarm()","91cd7e9a":"ChannelDeleted(address,address,address)","91cdecab":"TOTAL_DINOTOKEN_SUPPLY()","91ce8ca9":"IQTCrowdsale()","91ce8e04":"setTwo(uint256)","91cee1fd":"baseStats(uint256,uint256)","91cef6a8":"payAffiliate()","91cf2164":"transferFunction(address,address,uint256)","91cf7aca":"upgradeFrom(address,address)","91cfb7b6":"ceilings(uint256)","91d0b3fd":"_mine(address,uint256)","91d0dd17":"accrueCouponsPerXTokenETH()","91d15735":"left11(uint256)","91d15a91":"weiRaisedIco()","91d1addb":"plutocracylvlAchieved(string,string)","91d23a1a":"lastRewards()","91d2939d":"per(uint256,uint256)","91d4357b":"myBonus()","91d43b23":"right76(uint256)","91d462d9":"hashUnderlyingPrices(uint32,int256[])","91d558b7":"startCrowdsaleY0(address)","91d55c41":"RuiXueToken()","91d5d7d6":"out1Done()","91d6212a":"address5a()","91d625e5":"setupCore(string,string,address,uint256)","91d6367b":"reserveForTeam(address,uint256,uint256)","91d739ea":"updateRegistratorStatus(address,bool)","91d76bbb":"getTotalMigrated()","91d781ba":"kkTestICO1()","91d80948":"_checkAndCallTransfer(address,address,uint256,bytes)","91d8b14e":"BuyTickets()","91d91df3":"FesBerto()","91d96541":"refundedSat(address)","91da7aa8":"transferAndCall(address,uint256,uint256[])","91da9178":"WALLET_LB_ADMIN()","91dbd4c3":"payTournamentWinner(uint256)","91dc077b":"submitApplication(string,string,string,string,string,string,string,string)","91dc11fe":"setClaimParameters(uint256,uint256)","91dc1b1d":"mintCUSD(address,uint256)","91dc6d36":"pauseForDividend()","91dc956d":"addLog(string)","91ddadf4":"clock()","91de4f88":"claimCoreTeamsTokens(address)","91de5474":"getPurchaserCount()","91ded8fa":"getTokenByAddress(address)","91df0c08":"addReserve()","91df9562":"BSPToken()","91dfa960":"report(uint16,uint16)","91dfe428":"addFees(uint256,uint256)","91e05922":"contractICO()","91e078bb":"startAuction(uint256,uint256,uint256)","91e0a5a0":"checkHolderStep(address)","91e0b6c0":"ProofPublicVote()","91e0e39c":"resetDragonBalance(address,uint256)","91e1397d":"rcnFund()","91e192b7":"MintedToken(address,address,uint256)","91e1cc5a":"freezeAccount(address,uint256,uint256,uint256,uint256,uint256)","91e22c90":"interfacesSupported(address,bytes4[])","91e23a4d":"updateInterCryptonode(bytes32)","91e2f2c5":"HoQuToken(uint256)","91e30ec3":"buyDataRecord(uint256,uint256,uint256,uint256,uint256,uint256)","91e3387b":"numBrews()","91e50314":"isActivityCore()","91e52b91":"buySecond()","91e569c3":"recordBook(address)","91e59bcf":"testSetName()","91e6d028":"getFIRST_STEP_LIMIT()","91e7137d":"price2ndWeek(uint256)","91e732b6":"setInvestRestriction(uint256,uint8,bool)","91e79c72":"hodlerTotalValue()","91e7f7bc":"claimVotingRight()","91e8609f":"getParentId(bytes32,uint256)","91e863ca":"setBigPromoInterval(uint128)","91e88106":"abiLength(address[])","91e8d3dc":"testBitOrFailIndexOOB()","91e8fc34":"createPipe(uint256,uint256,bytes32)","91e9f106":"historyWinner(uint256)","91ea294e":"LogSetWithdrawer(address)","91ea4d07":"snatchedOn()","91ea59eb":"buyGuaranteed(address)","91ea8a05":"add(bytes32,bytes32,uint256)","91eb97ea":"pharmatrix(uint256)","91ebc861":"noFeeTransfer(address,uint256)","91ec1623":"_shutDown()","91ec845e":"isAtMost(int256,int256,string)","91ec910e":"OwnableImpl()","91ecda3c":"Menu10(address)","91ed6851":"createPromoCompany(address,string,uint256)","91ede45f":"Deposited(address,uint256,uint256,uint256)","91ee7bbf":"dispute(bool)","91ef14b4":"setApprove(address,address,uint256)","91f02379":"hundredKInvestor()","91f02f9c":"DelayChanged(uint256)","91f11a9c":"lastWinNumber()","91f1cf05":"crafting()","91f1f310":"totalOffers(uint256)","91f2700a":"drop(address)","91f2ebb8":"heir()","91f34dbd":"transfer(uint256,address[],uint256[],uint256[3],bytes,bytes,bytes)","91f39f10":"getContactAddressByIndex(uint256)","91f3c4a2":"GSY(uint256,string,string)","91f4b7ff":"soulBookPage(uint256)","91f5637a":"frozenBalanceCount()","91f5c3a8":"donateAndCreateGiver(address,uint64)","91f5f3c9":"MAX_TOKEN_GRANTEES()","91f6c7e6":"getCurrentICOPhase()","91f72ebb":"is128Bit(uint256)","91f7cfb9":"availableAmount()","91f85480":"updateValidOrg(address,address,bool)","91f90157":"highestBidder()","91f9bb85":"setAdvisorVault(address)","91f9f4a2":"getRateIncludingBonus()","91fa0555":"getParentAddress()","91fa196d":"getDesignatedReportReceivedTime()","91fa2df4":"addPaid(bytes32,uint256)","91fb4583":"reachedMajorityForTeam(uint256)","91fb9437":"isStoring()","91fc437e":"nameTaken(string)","91fc7c70":"TreeCoin()","91fd1c7d":"getSenderByHash(string)","91fdbb55":"releaseUrl(uint8)","91fdf6b1":"electActiveTranscoder(uint256,bytes32,uint256)","91fe5a64":"_totalBurnedTokens()","91fe7bab":"mintTokensWithApproval(address,uint256,address)","91fea350":"checkFreezeValue(uint256)","91fed1c0":"RaffleResult(uint256,uint256,address,address,address,uint256,bytes32)","91feea93":"withdrawBoth(address,uint256,uint256)","91ff6baf":"requestsFunded()","92008bfa":"setResourcesSecondaryManager(address)","9201ac94":"getCON()","9201de55":"bytes32ToString(bytes32)","92031600":"setBonuses(uint256[],uint256[],uint256[])","92039b87":"balanceVested(address)","9203cb9e":"forwardWin(address,address,bytes,bytes32,bytes)","9204764f":"setHookOperator(address)","9204b2bd":"maxVeriAmount()","9204c013":"QKCCoin()","9205ab3c":"sendRefund()","9205dce7":"Usdcoins()","9205ec4d":"refundSponsorship(address,uint256,uint256)","9205fbc2":"testAuthorityAuth()","92066346":"setCastleLootDistributionThreshold(uint256)","92069ebd":"_getMarketPrices()","920775d4":"subVirus(address,uint256)","92093dd6":"getLastResult()","92093e7d":"addUserRefBalance(address)","92099fdb":"refundableEthBalanceOf(address)","9209b3c0":"getCrtDetails(bytes)","9209eebe":"SentToContractor(uint256,uint256,address,uint256)","920b0280":"noIcoPeriod()","920b3a7e":"getFundersCount()","920bb680":"ledgerWallet()","920c94df":"BuyTicketForOther(address,uint8,uint8,uint8)","920dce19":"getAngelCardSeries(uint8)","920dd47b":"first_partner_address()","920dfe52":"EFARMCoin()","920e3c96":"setUserStatus(address,uint8)","920e4da9":"created(string,string,address,uint256)","920ffa26":"ownerOf(string)","9211448f":"finalizeClaim(bytes32,string)","921193cf":"changelp3(address)","921200ed":"setBonusTokenRateLevelFour(uint256)","9212051c":"numJobs()","921233b9":"addBuyRequest(bytes32,address)","92123470":"mintTo()","921237a4":"createPlayer(address,address)","92127126":"canTransferByPartition(bytes32,address,uint256,bytes)","9212d0c1":"closeBetsIfEventNotSuccess(bytes16,bytes16,uint256,uint256)","92140775":"prefixedTest(uint8,bytes32,bytes32,address,address)","92140bb9":"getTransactionByTransactionAndEntityId(address,uint256)","921456e7":"modifierEx()","921496a9":"adminWithdrawTokens(uint256)","9214b644":"married()","9214e527":"Crowdsale(uint32,uint32,uint256,address)","9215b58e":"GoldMineChain(uint256,string,uint8,string)","9216728a":"cooWallet()","9216b7ad":"winTokenReward()","9216cf13":"licenseSalesContractAddress()","921710e9":"getShareRewardPercent()","9217500c":"setFightAuctionAddress(address,address)","9217c438":"getOracleAddress(uint256)","921828ac":"commitProposal(string)","921b004b":"depositFunds(address,uint256)","921b15ae":"LaborHourToken(address,int256,string,uint256)","921b2d64":"mintTokens(int256,address,uint256)","921b45f7":"checkAndCloseDeposit(uint256)","921bd6f0":"upgradeTimestamp()","921d72ed":"CreatedAccessory(uint64)","921dec21":"registerNameXID(string,uint256,bool)","921e1537":"dailyHash()","921e7ba6":"withdrawCoins(string,address)","921f5dec":"getBlockVoter(uint256,address)","921f98bb":"resolveFailVote()","92202126":"ETU()","92207bd8":"getMyCarsIdxCount(uint256)","9220d426":"_nowDateTime()","9220d5fa":"DiminishToken(address,address)","92223e7a":"BlueRedTokenERC20(uint256,string,string)","9223de05":"contributionAmounts(address)","922427de":"canSort()","922497fc":"regularTokenMaxSales()","92250c6a":"localBuy(uint256,address,address)","922587ff":"addMintable(address)","9226084e":"tier_cap_1()","922775e3":"createNewTrade(address,uint256,uint256)","92277933":"abc()","9227bed6":"bucketAmount()","922856da":"getPicksForUser(address)","9228e90d":"developer_BSR()","9229c504":"new_mainPlayer(address)","9229e3cd":"submitProof(bytes32,bytes32[],uint256)","9229f3c1":"KVLToken()","922a8425":"paymode()","922b01ca":"walkTokenLots(address,address,uint256,uint256,bool,bool,bool)","922b041d":"_getStatsSumHours(uint256)","922ba128":"calculateCurrDynamicPrice()","922bedf7":"mintNFTsNotForSale(uint256[],bytes32[])","922c64ef":"batchDistributeTokens(address[],uint256[])","922da521":"RocketPoolPresale(address)","922dd59a":"icapTransfer(bytes,address,bytes,uint256)","922dd7d9":"generateKey()","922f17ce":"emptyEther()","922f7124":"changeStrategyAddress(address)","922fc84b":"taskProcessedNoCosting(uint256)","923020d9":"whitelistMainSaleAddress(address,bool)","9231e0f9":"setPresidenteDeMesaVerify(bytes32,uint256,bytes32)","923211f5":"showLiveDividends()","9232494e":"BANCOR_NETWORK()","9232fdb5":"addUserExp(address,uint256)","9233c030":"_reward(uint256)","9233c1d6":"battle(uint256[],uint256)","9233d561":"setUnpaidPercentage(bytes32,uint8)","92346ed7":"test1(bytes)","92348055":"sellSoul(string,uint256)","9234c1fd":"MAX_REVEAL_DURATION_IN_SECONDS()","92363a42":"createProduct(uint256,uint256,uint256,uint256,uint256)","923689e4":"startRecovery()","92369bd5":"calculateAndDecreasePhaseSupply(uint256)","9237a125":"seedDeposit()","9237e074":"manager(uint256,address,string,uint256,bool)","9237e61b":"InvestmentSucceeded(uint256)","9239520b":"setQuorumPercent(uint8)","923a1abb":"SBCE(uint256)","923a2e61":"JinGangCoin()","923a367f":"PBToken(address,address)","923a4227":"CiceroToken()","923a69ae":"getCardRevenue(uint8)","923b3e75":"publishContractTemplate(uint256,string,address,string,uint256,uint256,uint256,uint256,uint256,uint256,address)","923b9480":"getDatasCount()","923b9bae":"EventCreatePet(address,uint256)","923ce65f":"draftNewCard()","923d566d":"buyKey(uint256,uint256)","923db49b":"informOffChainBuy(address[],bytes32[])","923de8e2":"checkTransferAndCallDelegated(address,address,uint256,bytes,uint256,uint256,bytes)","923e1b84":"sendToEtheroll(uint256,uint256)","923e2645":"DonationGuestbook()","923f098e":"CLNRefunded(address,address,uint256)","923f1788":"convertChest(uint256)","923f8455":"BACE_ETH()","923f9bae":"testLedgerPayback()","923fa0fe":"ChildContract(uint8,address,bytes32)","92403b35":"tier2Count()","9240551b":"changeCurrentEtherRateInCents(uint256)","9240f699":"landmarkSize()","92414146":"preIcoWasSuccessful()","92414f92":"OpenDate(uint256)","92418cf6":"withdrawKncFee(uint256)","924320b5":"isMajorityShareholder(address)","9243e088":"setEnforceRevisions(bytes20)","9244c21e":"preicoUSD()","9244f496":"addAddressToWhiteList(address)","92450ac9":"setDataColla_AA_01(string,string)","9245290d":"changeFeeCollector(address)","9246177b":"changeTicketOwner(address)","9246ab77":"addWhitelist(address[],address)","9246e531":"getSignature(string,int256)","924720bd":"pizzaPrice()","9247ff59":"getAccountData(uint256)","9248019e":"addMonsterIdMapping(address,uint64)","924806a0":"returnToken(address)","9248d4ec":"getEthNeeded(uint256)","92491f21":"subTourFreezingTime()","9249993a":"BANCOR_GAS_PRICE_LIMIT()","9249bc75":"set_sale_open()","9249d865":"getAllLawyers()","924b1235":"price1stWeek(uint256)","924b39ae":"refundToWallet(address)","924b573a":"lastWagerTimeoutTimestamp()","924bb1d0":"updateETHPrice(uint256)","924c28c1":"ContractInterface(address,address,address)","924ca55e":"LindaPresale(uint256,uint256,uint256,uint256,uint256,address,address)","924ca61a":"coupon(address,address,uint256)","924dd50a":"startSelling(uint8,uint256,uint256,uint128)","924dedca":"getEpisodeDataCommand(uint256,uint256,uint256)","924e63f6":"setDisputeResolver(address)","924f6be0":"CONTEST_INTERVAL()","924fdaf6":"drawPorsche()","925012f6":"agingTimes(uint256)","9250640d":"INIT_TOKENS()","925074ca":"getAllPlots()","92509c16":"lock_by_manager()","9250b080":"picops_user()","925176d6":"sellRate(uint256,uint256,uint256)","92524725":"mintToMany(address[],uint256[])","9252e819":"IGCoin()","92535862":"custodyCounter()","92536070":"RoomManager()","925382c0":"setMigrated()","92541925":"skynacoin()","92549366":"remainingCapInEth()","9254c2a8":"changeTotalRemaining(uint256)","92550bdd":"applyMigrate(uint256)","9256759c":"addressFundAirdrop()","9256c71d":"getPriceFeedsByOwner(address)","92573a0c":"token_callg()","925753d3":"TokenGenerationDisabled()","92579f34":"Aracle()","92584d80":"finalize(bytes32)","92588071":"saveAddress()","9258c8f8":"Applicationcoin()","9258d5a3":"isIcoRunning()","925aa2ad":"purchaseWithEth()","925ac216":"isICOOpen()","925ad1e7":"collectAllForce(address[],address)","925b83a7":"getCobeFriend(uint256)","925cbdd1":"createCost(uint256)","925cd80d":"contract_start()","925d3ec8":"dDowngradeToBasic(bytes32)","925f2573":"batchTransferDirectoryToken(uint256,address[],uint256[])","925f7239":"veztUserRegistered(address)","9260587e":"_removeTokenFrom(address,uint256)","92609315":"addAuctionManager(address)","9260e726":"giveReward(uint256)","9260faf8":"issueForEuro(uint256)","9262bba9":"titsTokenAuthor()","9262d759":"getAddress(uint256,uint256)","9263b559":"ethReceivedMain()","9263e371":"mint(bytes32,string,string,string,string,string)","9264a169":"tranferFrom(address,address,uint256)","9264ee57":"valuePerMicroKey()","92656b6d":"calculateHash(address[],uint256[])","9265996c":"getEventResult(uint32)","92664190":"PriceUpdate(uint256,uint256)","92670dc8":"currentBonus(uint256)","9267a36d":"founderVestingContract()","9267b291":"getGameStarted()","9267daba":"depositToGateway(uint256)","9268037a":"FortressToken()","92682b5f":"PauseOn(uint256)","9268e2d6":"setCLOUDForGas(uint256)","92698814":"reserved(bytes32)","926994e6":"testFailSoftLimit()","9269c0a7":"setABalances(address[],uint256[])","9269e464":"bountyTokenAllocation()","926a2456":"cancelIndexedSale()","926a4765":"getRoundStart()","926a9af0":"distributeForFoundersAndTeam()","926aa0a8":"sendEthTo(address)","926b33c6":"playSpecificDoubles(uint256,uint256)","926baab2":"proofImpl()","926bd180":"isGameVerified(uint256)","926c196a":"depositAndTransfer(address,uint256,bytes)","926d212e":"createGenerator(uint256)","926dfd5e":"becomeYouTubemaster()","926f0c7b":"partnersFund()","926f949e":"calculateWolkToBurn(uint256)","9270040f":"drawHeroLottery(address,bool)","92708ce1":"aletoken(string)","92710c60":"finalizePublicICO()","92716054":"freezer()","9271b8df":"totalPaidToFunder(bytes32,address)","9271b997":"setHighScore(uint256)","92721b86":"dividendRate(address,uint256)","9272e3f5":"many_currencies()","927319ba":"DCCToken()","92731aaa":"changesLocked()","927332da":"MaxChildLevel(address)","92736527":"freezeGame(uint32,bool)","92749978":"minBets()","9274c16b":"tokensDistributedToContributors()","9275ddd7":"SetFreeQPY(uint256)","92760a3e":"loveName()","92763585":"uniquePetsCount()","927675b8":"run(bytes32[],bytes32[],bytes32[],bytes32[],bytes32[],bytes32[],bytes32[],bytes32[],uint256,uint256,uint256,uint256)","92771e0f":"getCertificateMetaData(bytes32,bytes32,bytes32,uint256)","927726ea":"_openPrize(uint32,uint32,uint256,uint256)","927731c8":"payDepositByCandidate()","9278c418":"targetWalletVerified()","9279011c":"nextroundlength()","927a11b6":"getBranch(uint256)","927a4a7b":"transferWithLockAfter(address,uint256,uint256)","927a90da":"icoOpen()","927aaa7c":"setGeneManager(address)","927ac4f5":"approveContractReceiveGameLockedToken(address)","927bcac3":"emergencySplitToggle()","927c4151":"finalizePresale(address)","927c60de":"BIKQuery(address)","927da105":"allowance(address,address,address)","927db818":"initPresale(address,uint256,uint256,uint256,uint256)","927db81f":"new_entity(address,string)","927e434b":"rocketAddFunds(uint256,uint256,uint256)","927e69e2":"_getBattleBonus(uint256,uint256,uint256,uint256,uint256)","927ed13a":"newClient(uint256,address)","927f1086":"MAX_RANDOM_DELAY()","927f4be0":"exhaustAfterBattle(uint256,uint256)","9280b836":"spreadGold(address,uint256)","9280df59":"Swapcoinz()","928161ca":"recoverFundsAndDestroy()","92817184":"redeemPurchasesForVendor(address)","928187a8":"BonumPreICO(address,uint256)","9281aa0b":"setWhitelisted(address,bool)","9281cd65":"changeApproval(address,uint256,uint256)","9281e270":"matchOrders(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)","92824c24":"changeClaimAddress(address)","92829174":"preCrowdsaleTokensWallet()","9283032c":"storeWeekUnclaimed()","9283da60":"TeamtokenRelease1()","9283e6cb":"acquisitionsStatus()","92842802":"changeTierAdmin(address)","928432c0":"releasedSteps()","92844ddd":"_setUserRole(address,uint8,bool)","92846ab6":"put_transfer(address,address,address,uint256,bool)","92848c9e":"create(uint256,uint256,uint256,uint256)","9284cb0c":"getTotalPreSelled()","9286904c":"set_doctor(uint256,uint256,string)","928693c6":"RusaToken()","928771bb":"janPot_()","92878bd0":"forwardFunds(address,uint256)","9287c877":"getNavLength()","92885e86":"CountryPurchased(uint256,address,uint256)","9288cebc":"totalRollsByUser(address)","92890b09":"SmithToken()","92893fb9":"hasAddressVoted()","92898900":"allowTokenTransfer(address)","928993dd":"setBuyComissionUnits(uint256)","928a00d2":"deleteCoin(uint256)","928b06b5":"EAsset()","928b4cd2":"preICOTokenHardCap()","928b685c":"_buyPutToClose(uint256,uint256,uint256,uint256,address)","928b792e":"withdrawBonuses(bytes32,uint256,address,uint256,address)","928c5fb3":"getArrIntField3()","928c82a2":"createAsset(string,string,string,uint256,address)","928d09dd":"coreTeamAddr()","928d20fc":"_unpackPetValue(uint256)","928d4144":"verify(uint256,uint256,string,uint8,bytes32,bytes32)","928d81c1":"withdrawERC20Token(address,uint256)","928e6592":"sellingPriceInDayOf(address)","928e6b16":"getUint(bytes4)","928f0cc7":"ChangeStartByManager(uint256)","928f16e3":"geCompoundTimestampsFor12Months(uint256)","928fca1d":"withDrawlocked()","928fd553":"Migrated(address,address,uint256)","929066f5":"isParticipant(address)","9291b1f3":"tradeDealConfirmed()","92925c3b":"supplyTokens()","9293cc10":"TOU(uint256,string,uint8,string)","9293eb2f":"totalScammedRepaid(address)","9293f41e":"sendInviteDividends(uint256,uint256,uint256,uint256[])","92940bf9":"transferERC20Token(address,address,uint256)","92946284":"_placeSellTokenOrder(address,uint32,uint256)","9294e012":"sendOracleData()","92956506":"StarxCoin()","9295d038":"loyaltyPart()","92968125":"getUserDetails(address,uint256)","92979037":"teamTwoDivsUnclaimed()","9297afa2":"Eliminate(address,uint256)","9297c24c":"command()","9297d758":"DiceManager()","929911be":"takeSnapshot(address)","9299e552":"cancelListing(bytes32)","9299f294":"_buy()","929a3c18":"EMGwithdraw(uint256)","929a79b1":"getTitle(uint256)","929aa851":"maximumTokensForFifth()","929ac519":"changeOwnersWallet(address)","929ba8bf":"transferFromRwrd()","929c4649":"startUpgrading()","929c52a7":"changeClosingTime(uint256)","929d2033":"takeUpWork()","929de7c9":"setData_21(string)","929e626e":"getShareDistribution(bytes32)","929e902d":"curVotes()","929ec537":"getLockedAmount(address)","929f11ea":"withdrawOwnerAmount()","929f8dd4":"createBet(address,address,uint256,bytes32[])","92a04621":"maxPurchaseNum()","92a08dd1":"getCustomField(uint256,bytes32)","92a0fd64":"reserveTokenWallet()","92a11827":"canRevokeVesting(address,address)","92a20d0c":"ANONIMX()","92a2b44b":"offerTkn(uint256,uint256)","92a38e71":"createOpenValentineRequest(string,string,string)","92a39634":"VoltOwned(address)","92a42704":"verifyOwnership()","92a48bea":"setOfferContract(address)","92a4cc25":"readFrom(uint256,int256)","92a5f340":"BasePrice()","92a69395":"setTotalAirDrop(uint256)","92a70756":"m_thawTS()","92a70c42":"deployerHash()","92a73fb8":"testbool(bool)","92a781d8":"changeBaseValue(uint256)","92a7843c":"lastRefundedIndex()","92a79148":"getCryptoVersusReward()","92a793d0":"release_3()","92a81127":"BasicMilestones(address,address,bool)","92a8424d":"setPercentageCW(uint256)","92a93d33":"payAltCoin(bytes32,address,address,uint256,uint256,bytes)","92aaa019":"Inventor()","92abb859":"overrideBlock()","92acb4d6":"contributorList(address)","92ad728b":"staff_2()","92ae0530":"canUpdateFrontWindowAdjustmentRatio()","92aea05a":"expLimited(int128,int256)","92af0605":"playSystem(uint8,uint8,uint8,address)","92af7ce0":"throwsWhenGettingTokensWithEndedSale()","92afac6d":"reserveY1()","92afc33a":"ROLE_MINTER()","92b03120":"CONTRIBUTION_START()","92b0c5b2":"pow(int256,int256)","92b0d721":"mold(bytes32,uint256)","92b0fed8":"ChannelFactory()","92b1696d":"CNYToken(uint256,string,uint8,string)","92b19872":"changemincap(uint256)","92b1b0ce":"RachelToken()","92b1b418":"tokenFallbackTest(address,uint256,bytes)","92b25a71":"Wallet(bytes32)","92b3228c":"getIreg()","92b39bf4":"assignPatient(uint256,uint256,uint256,uint256)","92b46390":"changeDevAddress(address)","92b4b68a":"get_bettor_nfo()","92b4bb50":"rps()","92b4ddeb":"phase_3_Time()","92b6641a":"hardCapHigh()","92b6ebfa":"getPreIcoBonus(uint256)","92b7bd27":"removeOwner_(address)","92b7bfbb":"TransferRate()","92b7d5b9":"getCurrentGaslimit()","92b863f3":"AbabPreICOToken()","92b87751":"_balanceOfUnclaimedMilk(address)","92b9308c":"getRespectiveValue(address)","92b96432":"setBpTime(uint256)","92b9fe8b":"Xenon()","92ba4ba6":"GridMember(string,uint256,bool,address,address)","92ba77ca":"setVeto(uint256,bool)","92bb3e6a":"setCoverImage(uint256,bytes)","92bbf6e8":"E()","92bc3251":"getCuts()","92bccb80":"pauseRedemption()","92bcf0d5":"ICO_PHASE2_LIMIT()","92bd38bc":"fundCampaign(uint256)","92bd3f16":"mainsaleTotalNumberTokenSold()","92bdf9ba":"lockedCollateral(address)","92be5d13":"setDelegadoDeEscuelaVerify(bytes32,bytes32,uint256)","92be675f":"Y1_lockedTokenAmount()","92bec526":"GameChannelConflict(address,uint256,uint256,address,address,uint256)","92bec5c3":"distribute(uint256,uint256,address)","92bf2bf1":"changeMinimumContribution(uint256)","92c00590":"getAddReserveSignatures()","92c00a3f":"transferState()","92c00f3c":"investorsTokens()","92c19394":"packStore(address)","92c2bcb4":"changeRecipient(address)","92c31e61":"ZOINToken()","92c40344":"getReferralCode(address)","92c4a5ed":"MinBetUpdate(uint256)","92c537e9":"hatchStartTime()","92c54f92":"sit(uint8)","92c5769d":"unlockAddressAfterITO(address,address)","92c6b697":"claimGanaTokens()","92c6bf28":"getWalletsData()","92c70af1":"MAX_UN_LOCK_TIMES()","92c787ae":"register_recurcively(uint256)","92c8412f":"buykey(uint256)","92c87280":"joinProvider(uint256)","92c88a40":"CollectibleToken()","92c8eb96":"DSFalseFallbackTest()","92c9a11a":"getPrices2(uint256,uint256,uint256)","92c9a926":"stateStartDate()","92c9a9e2":"activateDestruction()","92ca3a80":"SingleTransact(address,uint256,address,bytes)","92cb5f19":"TokenTemplate(uint256,string,uint8,string,address)","92cb9030":"getFeeWindowForForkEndTime()","92cbda09":"subbtycmoney(address,uint256)","92cbeb59":"OracleBitstamp()","92cc2c94":"drainRemainingTokens()","92cd1ff2":"ETH_DECIMALS()","92cd2b99":"asciiToUint(bytes1)","92cdb7d5":"deathData_a15()","92cf1d49":"setStop()","92cfd461":"_createMedal(address,uint8)","92cfebd6":"LanaCharleenToken(uint256,string,string)","92d09ceb":"collateralAmount()","92d09f22":"pendingInvestContracts(uint256)","92d0d153":"t()","92d16464":"gameIsOver(uint256)","92d1abb7":"CONVERTER_CONVERSION_WHITELIST()","92d25259":"iBlock()","92d267c1":"setEthUsdRateInCent(uint256)","92d282c1":"Send()","92d2f118":"burn(uint8)","92d33200":"MAX_CRATES_TO_SELL()","92d3be79":"escrowWallet()","92d42475":"bbReserveWallet()","92d44650":"tokenApproves()","92d4d9ac":"verify(bytes32,address,uint8,bytes32,bytes32)","92d519de":"ATSXToken(address,address)","92d588a0":"INITIAL_COINS_FOR_VIPPLACEMENT()","92d59aff":"Take_payout()","92d60433":"CirculatingSupply()","92d66313":"getYear(uint256)","92d68619":"Multiplication(int256)","92d69a39":"addNodesToList(string,address)","92d7b620":"judge(bytes32[13],uint256,bytes32[],bytes32[],bytes32,bytes32,uint256[4],bytes32[10],uint256[4])","92d7f787":"getAccountWhitelist(uint256,uint256)","92d8c8cf":"setupImportFee(address,uint256)","92d98e95":"content(string,uint256,address,uint256,uint256,uint256)","92d996d7":"getPopularityByOffset(uint256)","92d997bd":"QuantityInitial()","92d9e3b8":"isAcceptingPayments()","92da29d2":"validPurchase(uint256,uint256,bytes)","92da856d":"currentStepIndexAll()","92dac258":"getAuctionItems(uint256[])","92daec51":"setLastBuyer(address)","92dbf585":"appendEarlyPurchase(address,uint256,uint256)","92dcf35d":"fourthExchangeRatePeriod()","92dd1246":"updateListReq(uint256,uint256)","92dd38ea":"arrayaccess(uint256)","92df61e8":"withdrawTokensFor(address)","92df6e91":"fortune_limitbreak()","92df94ec":"updateDream(address,string,string)","92dff48a":"backers()","92e0ba2a":"goldBought()","92e11e24":"teamAmountLeft()","92e16740":"scheduleOraclize()","92e18d9f":"setYcmContractAddress(address)","92e1ab17":"includesAddressesSet(address)","92e33d14":"enableWithdraw(bool)","92e405ac":"transferPartner(address)","92e41c69":"identityEthAddress()","92e4226a":"nextTransferFeeAbs(uint256)","92e423b5":"agent(address)","92e4b733":"_transferTokens(address)","92e4b8a4":"collectAuthorizedPayment(uint256)","92e4cd75":"icoTokensUnsold()","92e598f3":"test_fourInvalidEqInt()","92e8438c":"issueTokensMulti(address[],uint256[])","92e8d866":"DailyGrowthUpdate(uint256)","92e9fd5e":"ColdWallet(address,address)","92eaa642":"transferLoveStory(bytes16,bytes32,bytes32,uint256)","92eada50":"lastBlock_a16Hash_uint256()","92eb35bc":"preSaleBonuses(uint256)","92ebf860":"invalidateTaskListingAtIndex(uint256)","92ec6ea8":"updateAsset(uint256,string,uint256)","92ecf577":"getCurrentTerm()","92ecf690":"grantToSetUnburnableWallet(address,bool)","92ed888b":"CcifToken()","92ee0334":"currentUser()","92eeee63":"createAndBuyAllAmount(address,address,address,uint256,address,uint256)","92eefe9b":"setController(address)","92efd277":"countOfDeedsByOwner(address)","92f00233":"minterContract()","92f00d37":"TalkToExpertToken()","92f1fc7d":"bytes32_to_bytes(bytes,bytes)","92f351f9":"openTimer()","92f461ed":"getTeamsOfOwner(address)","92f48846":"updateTokenSellAmount(uint256)","92f4d225":"spankToken()","92f52ddf":"DICE()","92f53757":"GLAM()","92f5cea7":"bytes32ToString(bytes32,bytes32)","92f692ea":"setInvitationValidPeriod(uint256)","92f6a74f":"totalTokenCapToCreate()","92f7ba17":"MELONPORT_COMPANY_STAKE()","92f8de45":"MXToken()","92f926e5":"makeMoveBro()","92f96115":"setPartialTransfers(address,bool)","92fa1453":"BankAccount()","92fb4acd":"terminatePackage(address)","92fb7ef8":"burnPoll(uint256)","92fd1c2d":"bat_match(uint256[])","92fd1f01":"getPayeeAddress(bytes32,uint8)","92fe028b":"PokerWinner()","92fe4098":"b32ToBytes(bytes32)","92fee51a":"setICORatio(uint256)","92ff0d31":"transferable()","92ff3751":"getMatchHomePlayers(uint256)","92ff4be4":"finalLottery()","92ff7859":"newFutureLottery(uint256,uint256)","93003033":"tokenSalesAll(uint256)","93004e62":"initPayoutTable(uint256,uint256)","93012d5f":"Loan(uint8)","9301eb36":"setItemOption(uint256,string)","9303633e":"tier_rate_2()","930429ea":"setFOUNDERS_POOL_ADDR(address)","93046a13":"withdrawEtherPayment()","9304ddc8":"setUnitCreationFee(uint256)","93051424":"KIUSToken()","9305b0f8":"WorldSafetySecurityToken()","9306099f":"GxOrders(address)","930622ed":"assignedAmountToMarketExpand()","9306635a":"PETRO(uint256,string,uint8,string)","93072684":"revokeDelegateSigned(address,uint8,bytes32,bytes32,bytes32,address)","9307ca0f":"houseKeep(int256,uint256)","93080cd4":"replaceChannelContractAddress(address)","9308151b":"crowdSaleTokens()","9308353f":"payin()","9308a865":"total_raised()","930916b2":"setInviteCode(string)","930a0daa":"checkMinimumQuota(address,uint256)","930a80b4":"testAuthorizedSetPackage()","930a9d92":"tradeOrder(address[3],uint256[5],int256,int256,uint8,bytes32,bytes32)","930ae8b0":"setSaleFlag(bool)","930b7a23":"approveOnce(address,uint256)","930bbbed":"changeBeedingCost(uint256)","930c0bba":"getWithdrawalEntryForFunder(address)","930c1198":"crowdsale(address,uint256)","930c2003":"victim()","930c57f3":"PublicSale(address,address,uint256,uint256,uint256)","930cb83e":"registerUsers(address[],uint256[],uint256[],uint256[],uint256[])","930cbf89":"ProposalAdded(uint256,address)","930cd62e":"getIcoInvestorsAddressesCount()","930d54b4":"revealSeckey(uint256,bytes32)","930db1ab":"setHijackPrice(uint256)","930ddb8e":"getIdea(address)","930e1173":"tokensReadyForRelease(uint256)","930e23b9":"_STCnContract()","930ed251":"getSavedVar()","930f5fbe":"setApplicationChecksum(bytes32)","930fed29":"EnkronosToken()","931010eb":"tokPrizes(uint256)","93107071":"PDAToken()","9310ba96":"TIX(uint256,address,uint256[],uint256[])","93119312":"returnMoney()","9312434e":"cryptocompareUsdOracleUrl(bytes32)","931274c8":"createContractScene(string,uint256[])","9312766d":"BSTokenData(address)","9313053e":"createItems(address)","93138faa":"isProviderParamInitialized(address,bytes32)","9313919a":"multipleShotTokenRepartition(uint256,uint256)","9313dc43":"claimTokensFromErc677(address,address)","9314be9d":"lock(bytes32,bytes32)","931634fd":"PGTBToken()","93167204":"teamTokensPercent()","931688cb":"updateBaseURI(string)","9316c3e7":"transferBulk(address[],uint256[])","931742d3":"commissionAddress()","9317cb37":"CUTOFF_PRESALE_ONE()","9317d6d3":"totalReceived(bytes32)","93183dc9":"paymentManager(address,uint256)","93192c65":"ProposalAdded(address,uint256,uint256,string,bytes32)","931983ad":"Connection(address,address)","9319f44d":"rateTierNormal()","931a4c5b":"maxContributionPhase2()","931a5256":"addOrder(uint256,uint256,address,address,uint256,address)","931b3385":"claimToken(address,string)","931c0040":"carrotsMultiplier()","931c6246":"VestingWallet(address)","931c8ba7":"count_products()","931cd0cc":"setBQL(uint256)","931dab50":"allocationAmount(uint256)","931df75f":"validateProposedThroneName(bytes)","931e44e2":"BuyLandsByEth(uint256)","931e7daa":"BettingKing()","931fbdd8":"Trenggalek()","9321cb7d":"SGT()","9321dc5f":"initRequest(uint256[])","9321e603":"changeMtcDailyLimit(uint256)","932354c1":"updateLocation(string)","93237833":"CONTRACT_HOLDER_BONUS()","9323eaad":"awardUnitRafflePrize(address,uint256)","9324dfff":"addWhitelistedTokenAddr(address)","93253a9d":"PublickOffering()","93257d33":"CheckForFloating(address,uint256)","93272baf":"getTokenType(address)","93275889":"ChangeTax(uint16)","9327891e":"testSetRole()","932838a1":"setCell(address,uint256)","9328bfc1":"getNumMessages(address,address)","9328fa02":"capitalAllocatedTo(address)","9329066c":"getJackpot()","93299395":"revokeEditAgentAuthorization(address)","9329f2fe":"postico_startdate()","932a0ee7":"getShowTextBytes96()","932a7b2e":"addApp(address,address)","932adda2":"newNode(bytes32,bytes32,bytes32,bytes32,bytes32)","932ae363":"buyerNumDeals(address)","932bead7":"updatePlanetURL(uint256,uint256,uint256,string)","932c1081":"closedHour(uint8)","932c360d":"SpaceRegistry()","932c90f3":"SUPPLY_FOR_TEAM()","932cd73e":"tokensReleasedToTeam()","932db761":"profitsFromBitnationDebitCard()","932def2e":"tgrCurrentStage()","932e1c76":"distributeEbyteForETH(address[])","932e2e95":"_withdrawEthereum(uint256)","932f4588":"RaffleResult(uint256,uint256,uint256,address,address,address,uint256,bytes32)","932f9f89":"testThrowInvalidProvider()","932fad1f":"totalWageredForOutcome(uint8)","932fd99f":"toHighestDenomination(uint256)","932fec40":"refundToken(address,address,uint256)","9330f97f":"removeDestinationByIndex(uint256)","93311632":"getTokenClaim(uint256)","93316cdf":"selltoken(uint256)","9331a922":"get_layer(uint256)","93320f2e":"expRequiredToReachLevel(uint256)","93325812":"addFreelancerTotalInvoiced(address,address,uint256)","93331892":"batch(address[],uint256)","9333a122":"ITECH()","9333cf5e":"communityPeriodAmount()","9333d6c0":"MILL()","933426f5":"GoolaToken(address,address,address)","93348f45":"ovedclaimBountyairdropMultiple(address[],uint256)","9334ab61":"Infos()","9334ad0d":"getVersions(address,bytes32,address,bytes32)","93358320":"withdrawOwnerToken(uint256)","9335dcb7":"ownerWallet()","93361078":"confirmStartWork(uint256)","9338cbdd":"monToTrainer(uint64)","93395d99":"TalksChain()","93399949":"GTDCStandardToken(uint256,string,uint8,string)","9339c01a":"validICOPurchase()","9339e942":"check_flag(bytes32)","933aa667":"isPermission(bytes4)","933ba413":"totalEthInWei()","933bf760":"extend_life_of_contract(uint256)","933c798c":"next_payout()","933dc51b":"setUint256(int256,uint256,uint256)","93402e17":"setRewardManger(address,address)","934076f1":"BetOnMatch(address)","9341231c":"sendOrThrow(address,uint256)","9341287d":"setMetadataUrlPrefix(string)","9341aa4e":"initializeDistribution(address)","9341bc00":"drones(uint256)","934209ce":"rank()","9342160b":"eligibleCheckAndIncrement(uint256,uint256)","93423e9c":"getAccountBalance(address)","934354e7":"finishSpin()","93437b52":"Fibremoney()","93439950":"test_chain2_2_increaseBlocksBy5()","9344a0b6":"addAddressToRegistry(address)","9344b0d6":"playerCompleteGames(address,uint256)","9344c50f":"getNameOf(address,address)","93465da6":"Error(uint128)","934689a9":"getTokenCreator(uint256)","93469800":"minPower_()","93470fa8":"listMultipleItems(uint256[],uint256,address,uint256)","93478221":"LogSender2(address,address)","934865d0":"TransactionBlocked(address,uint256)","9348b810":"contractorTransferFrom_Bcoupon(address,address,uint256)","9348caf7":"testBuyTenTokens()","9348cef7":"reveal(uint256,uint256)","9348ff61":"setUSDRaised(uint256)","9349ba44":"AirRopToken()","934a029d":"getVoteAtTxForUser(bytes32,address)","934a0b57":"AXXToken()","934aa023":"charity()","934bb037":"MainBank()","934bc29d":"exampleFunction(uint256)","934c563f":"dataOf(uint256,uint256)","934d8a2e":"TokToken()","934db458":"Big()","934e03a4":"toBool(bytes32)","934e860d":"addOnHold(uint256)","934ea572":"w_Reserv()","934f92af":"ZebiCoinTempMgr(address,address,address)","93503337":"isAllowed(bytes32,uint256)","9351327f":"USD_PER_ETHER()","935146d0":"createMatch(string,string,uint256,uint256)","93519d66":"requestClearing(bytes32)","9351a8d7":"managementWithdraw(uint256)","9352fad2":"run(string)","93545a79":"isAmountBonus()","93559bc6":"lifeCoin()","9355d6db":"MadTok()","9355eb25":"privilege()","935600ce":"subRegistrationPeriod(bytes32)","9356b1fe":"BWCHToken(uint256,string,string)","9356e87f":"getLastMulti()","935814a6":"confirmRewardsWithdrawal()","93588a14":"setTop(uint256,address,uint256,bool)","9358928b":"circulatingSupply()","935aae40":"MINIMUM_BET()","935b1624":"get_first_global_audit_document()","935b2b1f":"buyBox2()","935b7dbd":"buyFor(address,uint256,uint256)","935bb767":"setPrices(uint256,uint256,bool)","935c1fb1":"addressIndex(address)","935cac39":"internalTransferFrom(address,address,uint256)","935d29d6":"BPToken()","935d647f":"getPublicForSecretFor(bytes32)","935dfb71":"adjusted()","935e1533":"processFinishLottery(address)","935e97c2":"settleTransactionByMediator(uint256,uint256,uint256)","935eb35f":"addToBlacklist(address[])","935ebb78":"MAX_USD_FUNDING()","935eeddc":"CarUpdated(uint256)","935f43b2":"ipart(int128)","935f4c18":"sendPayment(address,uint256)","935fb955":"Mytoken(uint256)","93602379":"_transferCar(address,uint256)","936061cd":"claimWinner(address)","93608dfb":"earlySuccessTimestamp()","9360b138":"sendTokensTo(address[],uint256)","936224b8":"midEtherBonusValue()","93623fb8":"changeAcceptDice(bool)","936241b7":"hunterLicenceEarning()","93627f42":"globalMax()","9362917c":"FuckKuanLi()","9362e50e":"changeDeveloperSENSDestinationAddress(address)","936315d6":"canReveal(address)","93632ddd":"totalBNBContributed()","93634702":"isValidSignature(bytes32,address,bytes)","9363933c":"GizerItems()","9363a141":"getDepositCount()","9363c812":"floorPrice()","9363fb71":"totalFreeTokensDistributed()","9364003c":"HDC()","93643a5b":"fazzycoin()","936597da":"mLoadAndReturn(bool)","9366804f":"checkForJoin(uint256,address,uint256)","9366fd5c":"getEvaluationByRecorderID(uint32,uint64)","936710bf":"getBalanceOfAccount(address)","9367a863":"t_Andrey()","9367f8de":"SPCToken()","93683f3d":"changeReserveBountyRecipient(address)","9368f482":"_betterThan(address,address)","9368f72c":"burnFromToken(address,uint256)","93694f67":"opponent()","936b360d":"Tachyon(uint256,string,uint8,string)","936b603d":"contributorTokens()","936bbf9a":"totalPostIcoContributorIds()","936bfa40":"the120address()","936bfc63":"OrcERC20()","936c9bc9":"ICOdeadline()","936cfb0e":"transferInternal(address,address,uint256,bytes)","936d2b0f":"addProductAtId(uint256,string,uint8)","936e9904":"AUCoin()","936ec951":"afterEach()","936f67ea":"CryptoStorage()","936f8a40":"setMinBuy(uint256,uint256,uint256)","936fddcb":"VULCAN_PROMETHEUS_EXTRACTION_BASE()","93709788":"forwardManyTransaction(uint256[])","9370a07c":"TSVC()","9371c369":"applicationRejected(address,address)","9371de6e":"unsoldVUPDestination()","93720b2f":"giveAways(address,uint256,uint256)","93736419":"UpdateUserExpire(address,uint32)","9373ad6c":"inviteFinished()","9373b8bd":"claimAddresses(address[],uint256)","9373e2a1":"CircleCrowdsale(uint256,address)","9373f432":"setWithdrawWallet(address)","93741a3e":"iterate(string)","93742d83":"makeBet(uint8,uint8,uint8,uint8,uint8,uint8,address)","9374c487":"overshoot()","9374ec98":"whiteListMge()","9375206a":"setAllowed(address[],uint8,bool)","93762cff":"_resetMine()","93766a57":"trade(address,uint256,address,address,uint256,uint256,bool)","93768820":"isCommunityToken(address)","9377530f":"grandTotalClaimed()","93778e2d":"setCompte_6(string)","9378a9e2":"setUInt(uint256)","9378f08f":"ScamStampToken()","9379077f":"bookDayVisit(uint256)","93790f44":"getKey(address)","93791262":"performInit()","93796317":"InternationalTourismPublicChain(uint256,string,uint8,string)","93798ff5":"BuurmansToken()","9379d936":"calculateBonus(uint8,uint256,uint256)","937a7ac5":"moveStageWithdrawn()","937a9151":"WBIToken(uint256,string,string)","937adbe6":"isInTerm(address)","937b19ef":"EtherRoyalToken()","937b7cf1":"contractFallback(address,address,uint256,bytes)","937c0cdf":"priviledgedAddress()","937c0d0a":"aaa()","937c9e3c":"CandyLandSale(address)","937cde20":"hasPass(address)","937dc72f":"AppCoins()","937e09b1":"minimumContribution()","937e909b":"reservesPerTokenDest(address,uint256)","937ebbd2":"sendTokensToBountyOwner()","937ef8e3":"getUserReferralsProfit(address)","937f2e33":"claimMyTokens()","937f6e77":"setInfo(string)","937fd355":"initializeBasicFundraiser(uint256,uint256,uint256,address)","93806144":"getPunitoryInterest(uint256)","93808351":"setPriceInternal(address,uint256)","9380b8e7":"testFailAddingMembers()","93813782":"Tasoha()","938199a5":"getDateOfLastPayment()","9381da6e":"getEstateData(uint256)","9381e53f":"TokensCollected(address,uint256)","9381ebfa":"EUAHTOKEN()","9382ef65":"prvdWallet()","93830c74":"solUpDownVote(bool,uint32,address)","9383d4e6":"SingularityTest14()","93847d54":"TRLCoinSale(address)","9384f31e":"SingularityTest19()","93854494":"factHash()","93859188":"amount_bonus()","93867fb5":"roleAdmin()","9388b560":"TOKENS_ALLOCATED_TO_SERVUS()","938a465e":"TOKETH_PRESALE_ONE()","938ae4cc":"testThrowDisownNotTransferable()","938b5f32":"origin()","938b643b":"TimeToMeet()","938bcd67":"getChannelIdentifier(address,address)","938c4307":"scheduleCall(bytes4,bytes,uint16,uint8,uint256,uint256,uint256,uint256,uint256)","938d0444":"SmileToken()","938d2f46":"escrowDeletion(address,address,uint256)","938d9632":"activekey()","938da22d":"secondReleaseTime()","938db92e":"ICO_Tier()","938e6fcc":"MiningStart(uint256,uint256,uint256)","938f3cc4":"create(address,address,address,address,address,address,address,string,string)","938f407a":"removeFromWhitelistInternal(address,uint256)","938f6c5f":"getBountyTokens()","938f7064":"createTopic(string,string,uint256)","93904aae":"coinToBurn()","939090f8":"deposit4(address,address)","93920e8f":"invest(address[],uint256)","93924147":"MoveFromBase(uint256)","93928c91":"thirdBonus()","9392e5b5":"erase(uint256,uint256)","93930020":"getLastConsolationPrize()","9393c09c":"addFabric(address,address)","93940e0a":"INTLToken()","939528b1":"transferProposalCooldown()","939624ab":"removeStake(uint256)","9396a7f0":"getQuickBuyPathLength()","939729c1":"installerPercentage()","9397afcb":"PlayingCrypto()","9397f2a2":"weekOneRate()","939802af":"getDataForTokenId(uint256)","93986193":"realizedTokenBalance(address)","9398e0cd":"data(int256)","9398ecb6":"setMaxParcels(uint256)","939935cb":"startTimeInMinutes()","93997075":"AddCommitteeVoteEvent(address,address)","9399869d":"getContractCount()","9399dcfb":"PointGameProcess(address,uint256)","9399dd7e":"serverEndGameConflict(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,uint256,address,bytes,address,bytes32,bytes32)","939a470e":"updateDescriptionHash(string)","939a79ac":"demo(string)","939a8dc1":"CryptoPepeMarketToken()","939b73aa":"getAthlete(uint256)","939b7842":"approveMigration(uint256)","939bfc79":"TTAC()","939c0a66":"AirDrop()","939c23b6":"setProtectionForMyUnprotectedCrypton(uint256,uint256)","939cda3f":"DgxDemurrageReporter(address,address,address,address)","939d3ac4":"sendCommunity()","939d8729":"_postValidatePurchase(address,uint256,uint256)","939de809":"checkSale()","939e014e":"optionTransfer(address,uint256,uint256)","939e436c":"weiPerContributor(address)","939ea4f8":"bombs(uint8)","939fb3bf":"Owanble()","93a00d27":"rektCoinCashSafe()","93a09352":"setValue(string)","93a0c742":"getIdeaParties(uint256)","93a0dc08":"disableAffiliate()","93a2f88d":"gettopid(address)","93a2fa6c":"Emission(uint8,uint256)","93a31509":"LEXToken()","93a32f62":"assignToken(address)","93a378da":"addHodlerStake(address,uint256)","93a408d7":"priceUSD()","93a422bb":"updUserBlackList(address[],address[])","93a45612":"SetPresaleHandler(address)","93a52980":"getTotalEtherPool(uint8)","93a595f5":"repayLoan(address,uint256)","93a5a9da":"resignTrustee()","93a69ae0":"eForecastGambleToken()","93a8333e":"Count()","93a91682":"curPrice()","93a91f25":"setInitialAllocation(address[],bytes32[],uint256[])","93a95fa8":"superPowerFulDragonOwner()","93a962fc":"addUndergraduate(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","93a991af":"withdrawDai(uint256)","93aa3014":"BarryUtilityCoin()","93aa5ca8":"BITNOT(bytes32)","93aababc":"setlockBalance(address,uint256)","93aacd7d":"ownerLabel()","93abc530":"getSubscriptionOwner(bytes32)","93ac3638":"setAuctionAddress(address)","93ac3905":"lastGateway()","93ac5048":"BitallexToken()","93ac7c83":"EVTCToken(address,uint256)","93adf28b":"PumpAndDump()","93aef871":"checkSolved()","93af0292":"complete(address)","93af339f":"cardDrawPrice()","93af8ed4":"maybeChangePrice()","93afbdae":"repriceAuctions(uint256[],uint256[],uint256[],uint256)","93affe51":"getBoth()","93b14daa":"right14(uint256)","93b155af":"win(bytes32)","93b16ff5":"IkuraBurn(address,uint256)","93b1d4c7":"OfferingRegistry(address)","93b212bc":"subWithdraw(address)","93b21c8c":"destroyThreshold()","93b2467e":"totalSold(uint256)","93b30efc":"doSellerRequestCancel(bytes16,address,address,uint256,uint16,uint128)","93b3a368":"getCorrespondingIntegerValue(bytes32,uint8,uint256)","93b3bb35":"VisualFodderCoin()","93b4a73c":"KITTOKEN()","93b4c69b":"_assignRole(address,bytes32,address,uint256)","93b557db":"dSetArbitraryData(bytes32,bytes,bytes)","93b69f86":"getPlayerCoin(address,address,uint256)","93b71fe5":"Dao1901Votes(address)","93b7e7cb":"addCancellation(address)","93b8386d":"agencyOf(address)","93b8e90d":"isMasterAccount(address)","93ba3f15":"propose(address,uint256,bytes)","93baa6ef":"InterfaceImplementerSet(address,bytes32,address)","93bb3aee":"betAddressArray(uint256)","93bbafd1":"earlyBirdInvestments(address)","93bc771a":"ceoDevfund()","93bc96fa":"withdrawTo(uint256)","93bcabb7":"pullRow(uint256)","93bd0142":"ETHERDELTA_ADDR()","93bd1484":"mintApproveClear(address,address)","93bd27de":"IOweYou()","93bd4fc4":"depositAgent(uint256,uint256,uint256,string,uint256,string)","93bd90c4":"richtokenIndexToApproved(uint256)","93be0f83":"MSPT()","93bebdec":"corporationContract()","93c0771c":"getGamesPlayers(uint256)","93c166ec":"computeEndowment(uint256,uint256,uint256,uint256)","93c19e18":"rate0()","93c2c7f0":"getClosingSettle(bytes32)","93c2f482":"maxRound()","93c32e06":"changeFounder(address)","93c38965":"getData_15()","93c434e5":"getOptionInfo(uint256,uint256)","93c4ade0":"viewMaxShares()","93c5186c":"isNewPrice()","93c573c0":"maxChequeValue()","93c5ace0":"walletTokenTeam()","93c6475c":"processBet(uint8,uint256,uint256,int256,bytes32,bytes32)","93c69927":"sizeOfBool()","93c7ca84":"countBet()","93c7e009":"AddTrustedContractAddress(address,address)","93c8b0d4":"addForeignChild(bytes32,bytes32)","93c92b73":"exchangeRateArray()","93c94acb":"calculateRewards(uint256[3][3])","93c958f3":"ManufactorWallet(string)","93c98cbc":"ApplicationQualityCoin()","93c9b63e":"SGTCoin(uint256)","93ca5de7":"CIzTezt(string)","93cb1a4e":"originalHash()","93cc6d85":"transformDataContract()","93cc9162":"taskRejected(uint256,uint256)","93cca918":"place()","93cd22b8":"addAdministrators(address)","93cddbcf":"goldToEur()","93ce9791":"emergencyFinalize()","93cfd79f":"getVisitorCount()","93d07d07":"hoursCount()","93d087a2":"setData_33(string)","93d0de98":"AirDropContract()","93d1217e":"lastBlock_v3Hash_uint256()","93d18e92":"processOrder(bytes32)","93d22e52":"setEFContract(address,address,uint256)","93d3173a":"delegateDecreaseApproval(address,uint256,address)","93d4673f":"BTCTKN()","93d48b11":"zombieToken()","93d51daf":"amountofp3d()","93d5276b":"investInternal(address)","93d5825e":"calculateTokenSell(uint256)","93d5908a":"harapan(address,uint256)","93d5c520":"DelegateCallToken(uint256)","93d60990":"teamWithdraw(uint256)","93d68cfa":"preferredSaleStartTime()","93d759b8":"allowedAccount()","93d76f0e":"DEVELOP_CAP_PER_ROUND()","93d79105":"hashRelease(bytes32,bytes32)","93d7c6bf":"researchDivPercent()","93d81d58":"cancelSubscription(address)","93d84bf0":"oraclize_newRandomDSQuery(uint256,uint256,bytes,uint256)","93d865e3":"tokensFromPresale()","93d88409":"suspendSale()","93d90a4e":"HostingIcos()","93d91eae":"getFractionalAmount(uint256,uint256)","93d96049":"burn_lost()","93d9df16":"setCounter(int256)","93d9fd74":"getTitulaire_Compte_4()","93da1db1":"Profiterole(address,address,address)","93da4cfd":"getInvertedPriceInfo(address)","93dafba2":"getSubpot(uint256)","93db7716":"get_sale_arbits_sold()","93dc12e6":"closeProject(uint256)","93dd4133":"signedByCLevel(bytes32,bytes)","93dd738e":"notifyLegacyClaimed(address)","93dd9443":"Community()","93dd9866":"summEccles()","93de2527":"RegisterStaff(address,string,string,string)","93de6c51":"CHGUSDPRICE()","93dfbbcb":"setTokenExchangeRate(uint256,uint256,uint256)","93dfea8f":"ong()","93e02d13":"FallenLeaders()","93e1021a":"Participant()","93e1595d":"ATTR_CONSUMABLE()","93e24b7a":"teamVaultAddr()","93e3fca1":"stopGameOnNextRound()","93e426de":"MIN_WITHDRAW_WEI()","93e432d4":"refillGift()","93e43bbe":"getPost(bytes32)","93e4bf4f":"addPrecommitment(address,uint256,uint256)","93e5365f":"maxAddresses()","93e59dc1":"whitelist()","93e67bff":"IPFSHash()","93e7155b":"swapActivityHandler()","93e7d6c6":"createInviteName(bytes32)","93e84cd9":"play()","93e96174":"getNextDiniRequestId()","93e9a084":"lastTime()","93ea0e02":"batchTokenTransfer(address[],uint256[])","93eade00":"tokenAssignExchange(address,uint256,uint256)","93eb049d":"dp()","93eb33b3":"notifyDeathConfirmation()","93eb3c62":"Send(address,address,uint256)","93ed013d":"ecosystemAddr()","93ed4426":"extraBonus()","93eda78d":"getClaimData3(uint256)","93edaf59":"freezers(uint256)","93edbe36":"CHELCOIN()","93eeb3fb":"checkRate(address,address)","93eec1fb":"setName(uint8,uint8,string)","93efbdbb":"DPIcoWhitelist()","93f0bb51":"order(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","93f1b685":"LuckyPackage()","93f27be2":"_assignOverlfowData(uint256)","93f2ad91":"ExtremeToken()","93f2ba24":"testdiv256_128By256()","93f2fa04":"ThingToken()","93f32659":"getInitialWithdraw()","93f33b88":"notifySale(uint256,uint256,uint256)","93f43863":"getEmployerJobs(address,address)","93f5ddf2":"ICOStarted(uint256,uint256)","93f63e70":"setBenefit(address)","93f6fd85":"createCampaign(uint256,bytes32,bytes32,bytes32)","93f7cc99":"getPlayerAccount(address)","93f826c9":"portfolioSummary(address,address)","93f84cfe":"mintTeam(address,uint256)","93f85021":"numLeaders()","93f8e9f7":"mediumMod()","93fa47f1":"lockGoldTransfers(bool)","93faf781":"loggedAsStatement(uint256)","93fb28bd":"getUnitAttackMultiplier(address,address,uint256)","93fc2c8b":"winnerIsDraw()","93fc5ebb":"_secondRoundWinnersFight()","93fe0237":"updateWhitelist(uint256[],bool)","93fe4248":"deleteUIntValue(bytes32)","93fea184":"CONTRIBUTIONS_MAX()","93fea3fc":"supportValidator(address)","93feb13b":"ForceSendHelper(address)","93ff3e4a":"insertNewUser(uint32,bytes32,address,uint256,uint256,uint256,uint32,bool)","93fffddc":"previousContractAddress()","94002b57":"goldToken()","940064e3":"periodPreITO_hardCapInUSD()","94009bbc":"powerUp(address,address,uint256)","940147ac":"tribeProducts(address)","94014dc0":"weiRaisedPreICO()","94018e20":"removeRoles(bytes32[],address,address)","9401c82b":"CAECToken()","9401d547":"lockExternalTransfer()","9401e4e7":"TokensFlushed(address,uint256)","94025211":"refundToOtherProcess(address,uint256)","9403e8dd":"casino()","94044c75":"_invokeTokenRecipient(address,address,uint256,uint256,uint256,uint256)","94056c42":"mintTRCToken(address,uint256)","9405b406":"ProposalManager()","9405c78f":"setQuantity(uint256,uint256)","9405de64":"checkAllowance()","9405dfdd":"listingId()","94062a9d":"minBuyingAmount()","94066fb1":"cancelOfferAlice(uint256)","9406aea9":"startCall(uint256,uint8,bytes32,bytes32)","9406cf59":"setChallengeFeeMultiplier(uint256)","9406e273":"NBELToken()","94074b03":"getNetworkName()","94077c50":"updatePriceAgent(address)","9407a688":"allowedForwards(bytes32)","9407ea98":"setMarketplaceFee(uint256)","94081387":"administrate(uint256)","940834be":"MidnightCoin()","940900b8":"bookOvernightVisit(uint256)","94097168":"burnTokenBurn(uint256)","9409962f":"withdrawExtraTokens(address)","940a4e45":"distributeReward(uint256)","940a6cf5":"getAdministratorCount()","940a82a3":"distributeCTS(address[],uint256,uint256)","940aa73f":"setMinimumVotingWindow(uint256)","940b29b2":"etherReceivers(uint256)","940bb344":"burnUnsoldTokens()","940beaf5":"getTransactionIds(bool)","940c154b":"lockBet(uint256)","940c17c0":"CROWD_WEEK4_PERIOD()","940d0780":"AdmChange_README(string)","940d553f":"FoodTransferEvent(address,address,uint256,address,uint256,uint256)","940d5e08":"Alpon()","940d72ec":"buyPack(uint8)","940dab4c":"prefixedHash()","940dbf3e":"invokeOnce()","940de97e":"privateSaleStartTime()","940df414":"claimAddress(address,uint256)","940ebef7":"secondsRemaining()","940f02e0":"setDevelopersTokensWallet(address)","940f0661":"PrivateLedger()","940f851c":"Ballot(uint8)","940fae9e":"confirmBoosterQuest(address)","9410579d":"_calculatePriceComplement(uint8)","94106200":"testFailCreateSameNonce()","94107690":"checkPurchaseRecord(address)","9411c88b":"TokenContract(uint256)","9414d0bf":"initializeUsdReceived()","9415931d":"getLastDividendsAmount()","941660e5":"getRoundMaxPerUser(uint256)","9416893b":"addDemoData()","94169f25":"preIcoTotalCollected()","9416b423":"toLower(string)","94181d27":"lastReparation()","94182798":"dna4(uint256)","9418b8a6":"closeUsingTrustedRecipient(address,address,uint256)","9418d25a":"proveBuy(bytes,int256)","94194be4":"openingTimeB()","9419768d":"checkBetting(uint256,address)","941993f8":"changeCofounderB(address)","9419a2da":"setPaymentDetails(uint256,string)","9419f17c":"decraseTimeToAction(uint256)","9419fd29":"getWidth(uint256)","941a4bc7":"getPartnerCash(uint8,address)","941a5074":"controllar_account()","941a8486":"ownerChangeSellerfee(uint256)","941b0161":"addMarket(uint256,uint256,uint256,uint256)","941da7b8":"testExpiredBalance()","941e98a8":"EMISSION_FOR_SALESTAGE1()","941f9580":"rewardKey(address,uint256)","94201882":"artistEmail()","94224066":"setCityValues(uint256[],uint256,uint256[],uint256[])","942273bd":"SAMURAI()","942324c3":"getSponsoringCount(uint32)","94235f77":"apLockUp(address)","9423719b":"tokenBonusForFirst()","942385eb":"getPayroll()","9423f443":"submitGameResults(uint256)","9423fc54":"transferClearingFunction(address)","94248eaa":"isStateProjectInProgress()","9425753c":"licenseProductId(uint256)","9426e226":"validatorSet()","94272356":"_setReferrer(address,address)","9427aa96":"getBonus(uint256,uint256)","9427dfea":"ownerRecoverTokens(address)","942802e7":"VULCAN_POD_FTL_SPEED()","94282357":"EFASCOIN()","9428522a":"getNode(string)","9429d441":"reclaimBySender(uint256,address,address,bytes32)","942a8ad3":"getAQL(address)","942ab177":"MintToggle(bool)","942ab286":"buyTicket(uint256[],address,uint256,uint256)","942ac303":"goalInEthers()","942b765a":"getList()","942b90d3":"getRewardTable()","942bc8d4":"unpauseAngelToken()","942d468b":"transferArray(address[],uint256[])","942d73b1":"readAddr()","942dac28":"amounRefferalWon()","942ea466":"getNumber(address)","94306ecb":"AutoreleaseDelayed()","94313c5b":"getPositionOwedAmount(bytes32)","94313f9f":"cleanConsents(bytes32[],address[])","943153cf":"StonePaper()","9431e412":"getCommunityRates(uint256)","9431f5f0":"withdrawFees(bytes)","943215ae":"investmentFundWallet()","943250c4":"SquirtCoin()","9432c92c":"setStartTimeIcoStage1(uint256)","9432f0c7":"receiveClosePositionPayout(bytes32,uint256,address,address,address,uint256,uint256,bool)","9433a498":"totalFountainSupply()","9433a81e":"personIndexToApproved(uint256)","9434c981":"createNewMartial(uint256,uint256,uint256)","9434d765":"allocated12Months()","94353c70":"postMonForClass(uint64,uint32)","9435c887":"cancelBid()","9437563c":"logPriceBefore()","943814f0":"getWhitepaperAt(address,uint256)","9438cca8":"cancelEscrow(uint256,uint256)","9439060f":"getGameNumber(uint256)","943911bc":"getWorseOffer(uint256)","943a32bc":"Relay(address)","943a5e28":"RENEX_ATOMIC_SETTLEMENT_ID()","943b0747":"RewardOffer(address,address,bytes,uint256,uint256,uint128,uint256)","943b82f1":"getLimit(uint16)","943bd25d":"addNewBetAmount(uint256)","943dfef1":"bounty()","943e170d":"neededSignatures()","943e8216":"vote(uint256,uint8)","943eb504":"supplyLocked()","943fa364":"MPhoneSeller()","943fcc9d":"buyRoseETH(string)","943fd51c":"claim2Ply(uint64,uint64,uint64,uint64)","9440f01f":"buyCoins(address,uint256)","9441268b":"updateGlobalTokenAge()","944126f4":"acceptSupport()","94412943":"bountyOf(address)","9441e646":"addWhiteList(address,address)","9442936f":"d(address,address,uint256)","94429fa6":"withDrawAnyERC20Token(address,uint256)","9442fad9":"deployTokens(uint256[],address[])","94431f80":"getAvailableEtherCommissions()","94432deb":"fairsale_protection()","944358e0":"getContributedAmountInWei(address)","9443b9be":"TokenTimeLock(address)","9444991d":"getVotingListCount()","9445eb3a":"Terminate()","94465bf6":"adjustDuration(uint256)","94477104":"vestedOf(address)","9447fd0a":"until()","9448807a":"secondPay()","9448bcea":"getPlayerRoundNums(uint256,address)","94493c43":"getLockCount()","94495468":"totalTokenRice()","9449a361":"setStakeRequirements(uint256,uint256)","944a1a75":"CELION()","944abc22":"_updateCurrentPeriod()","944ac0c6":"MAIN_SALE_START_TIME()","944af2ae":"TegTokens(uint256,string,string)","944b7c3f":"getMaxNumberOfTokens()","944c1d97":"resetPeriod()","944c8929":"checkBeatingPrice(uint256,bool)","944da654":"editModule(uint256,uint256,address,bytes4)","944dc22c":"addRemovableIdArrayItem(address,uint256[],string,string,string,uint256)","944ea02d":"checkTokenBalanceState(address)","944ea477":"OPERATION_AMOUNT()","944f0499":"transferTokensFromTeamAddress2(address,uint256)","944f0e64":"tokenInfoParametersReady()","9450b1c8":"addCharityFundation(string,string,string)","9451bca7":"result_votes()","9451f865":"TestConf()","94525e12":"lowRate()","94532ced":"blockSettle(uint64,uint64,bytes)","9453b95d":"addOrUpdateAccounts(address[],uint256[],uint256[])","9453f381":"getBeneficiaryCash(address)","9453f767":"createOrder(string,address)","94543c15":"isDeprecated(address)","94544e64":"transferFeePercent()","94555d1a":"addSubscriber(address)","9455924f":"getTotalVolumeToken(address)","94566d25":"jobPost()","9456e5b5":"stockSet()","9456f7e9":"getHashByTokenId(uint256)","9456fbcc":"withdrawERC20(address,address)","94579680":"changeUserGrowthAddress(address)","9457c1dc":"enableMigration(address)","9457c68a":"forceEndCall()","9458434f":"mainWeiRaised()","94594625":"distributeAirdrop(address[],uint256)","9459c254":"refund(address,string,uint256,uint256,uint256)","945a2555":"queryPermissions(address)","945aab47":"tokenSaleCap()","945ade92":"initialDate()","945c6cf8":"burn_all_unsold()","945c7438":"sign(address,int256)","945c7c59":"distributeTokenSale(uint256,uint256,uint256,uint256)","945d7b7e":"tranchesSent()","945ddb52":"mainSaleTotalSupply()","945e5f24":"roughSupply()","94602869":"receiverWithdrawal(uint256)","9461446d":"setProcessingFee(uint256)","94615fc1":"setFreezingStatus(uint8)","946267ec":"mintComplete(uint256,int256)","9462eae5":"ChangeContractor(address)","9462f4bc":"bytarr(bytes32[])","94636cee":"createPromoMonster(uint32,bytes,address)","9463d582":"teamOneWin()","94642f96":"investorWhiteList(address)","94644764":"lookUpClaimerAddress(uint256,address)","94650fb8":"Goal()","94655f2b":"printMoney()","94658690":"parseUserInivte(uint256,uint256)","9465c114":"vanishToken(uint256)","946644cd":"fun()","94679ce7":"changeEtherPrice(uint256)","946941ec":"Contribute(bytes24)","946a893d":"shopDoublet()","946ad94d":"tokenContractEnableTransfers(bool)","946ae8df":"FMGHEALTHCARE()","946ba496":"ShishuToken(uint256,string,string)","946bcc30":"getFounder()","946bf4d7":"winningProject()","946c0344":"getChallenges(uint256)","946ca295":"userTransfer(address,uint256)","946d1480":"ethToUsd(uint256)","946d8806":"getMyPacifist()","946d9204":"initialize(address,address[])","946f8876":"updateTierStatus(uint256,uint256)","94704818":"fillOrder(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,uint256,bytes)","94705167":"enableArbiter(address)","94707a95":"_setRate(uint256)","9470b0bd":"withdrawFrom(address,uint256)","94727b41":"deleteProduct(bytes32)","9472b32c":"sale_period()","9472eb76":"setPayerString(string)","94737987":"referralProgram(bool,uint256)","94741017":"failCrowdsale()","94756e22":"VikoChain(string,string,address)","94759c36":"createQuote(uint256,uint256,bytes32)","9476760d":"AthletiCoin(address,address)","947721dd":"refundEndDate()","947846a4":"RefundableCrowdsale(uint256)","9478a7c9":"getReferralOf(address)","9478ab8c":"ethUsdPrice()","9478ba47":"calcUnclaimedFees(uint256)","9478f7cf":"_receiveEth()","9479f2c7":"STAKE_DEADLINE()","947a3168":"token_name()","947a36fb":"interval()","947aca55":"addMasterAccount(address)","947af462":"setBurnRequestAddressMap(uint256,string,address)","947bc72d":"MAX_TRANSFER_TIMSPAN()","947bd798":"rawManuallyMintTokens(address,uint256)","947cbc1e":"dariatest()","947e8a26":"TOKEN_MINTING()","947f7d1d":"newRandom()","947f8ede":"IcoCapChanged(address,uint256)","947f97cc":"getUnsoldTokens(uint256)","947f996d":"testGreatherThan()","947fd341":"getCoefficientMultiplier(string,string,string)","9480cd1a":"getPillarRoundsKitties(uint8,uint256)","94828ee8":"DelightToken()","94836dab":"sendFounders()","9483e91a":"withdraw(address,uint256,bytes,uint256)","9483f25c":"updateProfile(string,string,string,string)","948623dd":"buy(address,bytes,bytes32)","94868f7d":"airDropPayableTag()","948759d5":"transfermulti(address[],uint256[])","94876995":"isHandleAvailable(bytes32)","9489fa84":"calcSharePrice()","948a70d7":"SingularityTest16()","948b557a":"getDispute()","948b6790":"getTokensPrice(uint256,bool)","948bc5d6":"XfinityUtility()","948cd942":"getDronePot()","948cfd0c":"updateBootyBase(address)","948d902d":"getTokensByETH(uint256)","948e1a1c":"AVAILABLE_TOKENS()","948f1daa":"mintLockPeriod(address,uint256,uint256)","948f5076":"setCache(address)","949076b6":"ensureInterval()","94910d60":"createContract(address,address,uint256,string)","9491a8eb":"updatemktValue(uint256)","949201d7":"LOG_FailedSend(address,uint256)","94923fd7":"LogRevokeNotice(bytes32,address,uint256)","9492fbf7":"BGS()","94930138":"getLoanUnavailableAmount(bytes32)","949319b1":"verifyService(address)","9493242c":"returnLender(uint256)","9493ac07":"setBattleFee(uint256)","9493b9b0":"createMiner()","9493f012":"batchSafeTransferFrom(uint256[],address,address)","949430f0":"BTC_SUISSE_TIER_1()","94953294":"downTheDrain()","94954967":"setMaxWhitelistLengthInternal(uint256)","9495ad6c":"listExists(bytes32)","9495f8c6":"upgradableState()","9496df3f":"freezeQuorumPercent()","94974aea":"unlockedAtBlockNumber()","9497b7a1":"yearlyTeamAmount()","9498a265":"updateCertifier(address,address)","9498bef5":"overloadedMethod(address,uint256)","9498fb26":"ELIX()","94992b76":"ICOSTART()","94993e52":"_breedWith(uint256,uint256,address)","94996680":"setStartTimeStamp(uint256)","9499e018":"destructContract()","949a6868":"RefundTicket(address,uint256)","949a9d59":"receiveWithData(bytes)","949b56ef":"whitelistPrincipleLockPeriod()","949b9e10":"createHumanStandardToken(address[],uint256[],string,uint8,string)","949ba7c3":"GNCCrowdsale(address,address,address)","949c5099":"isAwaitingPRETDETokens(address)","949c89a0":"BitBaBeToken()","949cc9ea":"tokenSupplyBackedByGold()","949cfc64":"restTime(address)","949d225d":"size()","949db658":"rateProvider()","949dcdab":"forceWithDrawToInviter(address,uint256)","949dfa63":"calculatePurchaseReturn(uint256,uint256,uint8,uint256)","949e8acd":"myTokens()","949eabff":"fundsRaisedInWei()","949eb1c6":"bankersLimit()","949f80b0":"RandomExample()","949f80c5":"getResult(uint256,uint256)","94a08c69":"TOTALSUPPLY()","94a0b878":"fromTileId(uint16)","94a0c1cc":"cancelVoteForCandidateBySnapshotBlock(address,uint256,uint256)","94a1710d":"testNonOwnerCantBreach()","94a1be9c":"addVotes(uint256)","94a1d75c":"withdrawBidForSketch(uint256)","94a224c0":"withdrawExpenses()","94a2301e":"tokensInEth()","94a535fc":"TokenAdd(uint256,address)","94a53d41":"minimal()","94a5601a":"getMaxCap(address)","94a5c2e4":"maxValue()","94a5cccb":"deposit_period(uint256)","94a66da2":"GamePlayerCoin()","94a66df3":"objectGloves()","94a74249":"panicked()","94a771d7":"getReportTimestamp()","94a7ef15":"addWhitelistAddress(address)","94a80dd9":"getPoolValue(uint256)","94a82671":"unRegister(address,string,address)","94a89233":"isPluginInterface()","94aa6775":"newDeposit(address,address,uint256)","94aa8174":"AddParticipant(address,address,string,uint8,string,string,bytes32)","94ab9608":"XRRtoken()","94abbeaf":"PieToken()","94ad4f89":"icoDays()","94ae2341":"exchangeHelenium(uint256)","94ae4899":"onMintCalled(int256)","94ae7ac3":"allowanceAdd(address,uint256)","94aef022":"getVariables()","94af9da8":"createNewCombination(address)","94b0780f":"burntokens(uint256)","94b2ffc0":"StarterCoin(uint256,address)","94b31fbd":"getTokenAllowance(address,address,address)","94b367a3":"_takeOwnership(uint256,address)","94b44f3e":"addressToBlock(address[],bool)","94b4c93d":"MomentalyOwned()","94b5255b":"distributePreBuyersRewards(address[],uint256[])","94b5c9f3":"getChampReward(uint256)","94b5ed6d":"minorOwnerShares()","94b66386":"attackIsland(uint256,uint256)","94b67b1c":"getWeakenedDefensePower(uint256)","94b8896c":"holdAddress2()","94b8e58e":"resetWith(address,address)","94b8e72a":"Allocate(address,address,uint256,uint256,bool)","94b918de":"swap(uint256)","94b91deb":"construct()","94b91f06":"PARTNERS()","94b941db":"investorInfo(uint256)","94b9b62f":"getPacifistmasterReq()","94b9bdc4":"BlueDiamond()","94b9f152":"cancelConversion(uint256)","94bab061":"getVersionNo(bytes)","94bacfef":"distributeVLD(address[],uint256,uint256)","94bb136f":"minFinnRequired()","94bb7d64":"itemHistoryOfPlayer(uint256,address)","94bbfb56":"changeAffiliatePercentage(uint256)","94bc7df4":"BlocksToGo()","94bcdb4c":"Example2()","94bd5cb6":"newParityOwner()","94bdb93b":"MessageAdded(address,string,uint256)","94be2423":"setAtomGen(uint256,uint8)","94beb9b2":"ConstructBitcoinClue(bytes32,bytes32,bytes32,bytes32)","94bf804d":"mint(uint256,address)","94bf8862":"numBoards()","94c06a58":"descending()","94c0ac22":"ExchangeZWCToToken(address,address,uint256)","94c0f3e2":"PRESALE_PERCENTAGE_5()","94c176e4":"distributeAll(uint256)","94c19fb8":"LogSaleClosed(uint256,uint256)","94c1d810":"partFromProvider(uint256,address)","94c21ff3":"STATEMENT_HASH()","94c275ad":"maxConversionFee()","94c33163":"getTotalTokensSold()","94c33d90":"districtToBuildings(uint256,uint256)","94c3fa2e":"getLastBlockHashUsed()","94c41bdb":"getPreferedQtySold()","94c467d0":"banAuditor(address)","94c475ec":"setAltDeposits(uint256)","94c4e3c6":"_getVolumeBonus(uint256,uint256)","94c6116f":"getNextPeriodTimestamp()","94c62fb5":"SPARCPresale()","94c64a2e":"updateBtcRate(string,string)","94c69715":"bonusInPhase3()","94c70cb1":"bonusEnd20()","94c77969":"setTokenContract(address,uint8[],bytes32[],bytes32[])","94c87a84":"withrawAllEthOnContract()","94c89af5":"FeeProvider()","94c8cd62":"AreebaCoin()","94c90cac":"EliteCoin()","94c9b647":"sendTransaction(address,uint256,int256)","94ca9f90":"highestBalance()","94cace04":"enableMix()","94cb0947":"availableTokens(address)","94cc0898":"___test()","94ccbc1f":"transferPattern(bytes32,address,string,uint8,bytes32,bytes32)","94cdbea1":"SetDappinfo(string,address,address,string,string)","94cddaf1":"unlockTeamAndReserveTokens()","94cec87b":"preSale3Finished()","94cf9b1b":"FGCToken()","94cfb3d8":"getItemTempHolders(uint256)","94d0025e":"getNumberOfOpenSteps()","94d008ef":"mint(address,uint256,bytes)","94d02fff":"Authored(string,string,uint8,uint256)","94d036bf":"validInitialBuyoutPrice(uint256,uint256)","94d10c41":"spendUserBalance(uint32,uint64)","94d127a8":"calculateSeedBuy(uint256,uint256)","94d1330d":"spinnerCounts(uint256)","94d1b7e8":"triggerFailFlags()","94d26cb5":"getBetterOrderId(bytes32)","94d2b21b":"unauthorizedAddress()","94d2bdfe":"addSkill(bytes32)","94d2ca12":"getByAlias(bytes32)","94d2d7a7":"getCreatorAddress()","94d3d38d":"registerHello(bool,uint8,int64,int64,string,string)","94d3de83":"TeamVesting(address)","94d44f12":"createBattle(uint256)","94d453db":"MIN_INVESTMENT_PHASE1()","94d45856":"placeBet(bytes32,bytes32,bytes32)","94d54581":"EICQERC20()","94d5539d":"transferLocked(address,uint256,uint256,uint256[])","94d63afd":"left3(uint256)","94d645a8":"resolveClaim(address)","94d702a4":"tgeNextPartInvestor()","94d762c3":"Vault(address)","94d77363":"getTokenSold()","94d95f8f":"MAX_CONTRIBUTION()","94d96fa1":"BTC7200on420()","94d9c9c7":"setObserver(address)","94d9cf8f":"CreateProxyWithControllerAndRecovery(address,address[],uint256,uint256)","94da0746":"PRESALE_TOKEN_ALLOCATION()","94dafb16":"geteam(address)","94db4d05":"changeStakingContract(address)","94dba872":"o_automata(uint256)","94dbc70e":"lockState(address)","94dbe74e":"removeEscrow(address,address,uint256)","94dc7cec":"minBuyForPrize_()","94dc84ca":"AUTH_INITCONGRESS()","94ddc8c0":"submitBallot(bool)","94de3825":"_transferToAnotherAddr(address,uint256,bytes32)","94df682d":"loginVerify(bytes32)","94dfd38a":"test_invalidValue1EqValue2()","94e08fc2":"addProduct(bytes32,uint8,uint8)","94e09511":"sendTokenToPlatform(uint256)","94e0d371":"stage3()","94e0e328":"torchRunner()","94e0f844":"totalSellOrdersOf(address)","94e10784":"_getRate()","94e16386":"teammatesworld(address)","94e25c37":"unlockCustomer(address)","94e2662f":"setRequireWhitelistingBeforeDeposit(bool)","94e47e61":"create_block()","94e4a822":"split(address[])","94e4c808":"IPFSStore()","94e50e7a":"getSigner(address,uint40,uint40,uint128,uint256,uint8,bytes32,bytes32)","94e5b7e6":"getPlace(uint32)","94e5e890":"peculOldAdress()","94e8075d":"Development()","94e8767d":"uintToBytes(uint256)","94e93017":"_deployBallot(bytes32,bytes32,bytes32,uint256,bool,bool)","94eb463b":"Unset(address,uint32[])","94eba0b5":"StarCoin()","94ebd374":"purchaseAccessory(uint256,uint256,string,uint256)","94ec233f":"boolCallWithArray(bool,bool[4])","94ec3756":"resister(uint8,uint256,uint256)","94ec3a0d":"playersRequired()","94ed9b77":"append(address,address)","94eedaa4":"hirerReleaseFunds(bytes16,address,address,uint256,uint256)","94ef987e":"minimumPayment()","94efadea":"zoPrice()","94efafe9":"publishTemplate()","94effa14":"WithdrawETH(uint256)","94f0080c":"getBalancePremiumsPaid(address)","94f0b43c":"TripusCandyToken()","94f13f4a":"getGameItem(uint256)","94f183cb":"get_votes()","94f188be":"createIssuedToken(address[],uint256[],uint256,uint256,string,uint8,string)","94f29cb3":"medalIfFreeze(address)","94f2e623":"setLLV_edit_11(string)","94f2ed53":"_unlockNinja(uint256,uint16)","94f3217c":"MINIMUMINVESTMENTSALE()","94f38799":"GoChain()","94f3f81d":"removeAuthorization(address)","94f47146":"put(bytes)","94f5a1af":"LATOPreICO()","94f5ffd5":"betMake(uint256,uint8)","94f60a63":"getKudosLeft(address)","94f61134":"executeOrder(uint256)","94f649dd":"getDeposits(address)","94f6ba1c":"getMonsterClassBasic(uint32)","94f6e8ed":"initBallotProxy(uint8,bytes32,bytes32,bytes32[4])","94f75b96":"PerkToken()","94f7624f":"NAP()","94f8e954":"cancelInvestment()","94f92322":"getTotalPrediction(uint256,uint256)","94f976c3":"confirmProduct(uint256)","94fa3131":"claimBonus(uint16)","94fa5bcd":"setNewApproves()","94fabfb3":"getDocData(uint256)","94fb54d5":"euroThreshold(uint256)","94fb86c0":"referral_ledger()","94fd1c1c":"SAIToken(address,address,address)","94fdb8df":"HolyBible(uint16,uint16,uint16,uint16)","94fdbbb2":"createRedeemMessageHash(uint256,bytes4,bytes32,bytes32)","94fe344d":"SimpleToken(uint256,string,uint8,string,bool,bool)","94fe6ed1":"kTikTakCoin()","94ff1426":"_setTransmuterAddress(address)","94ff4b2b":"getServerFee(uint256)","94ffb819":"addApprover(address,string)","94ffe2c7":"PolicyRegistry(address)","95005a00":"LIANGToken()","95005b8b":"GetPlayerID(bytes32)","9500aa12":"MockController(address,address,address,address)","950108d7":"WithdrawForeign(address)","95029f34":"PendingOwner()","9502bb8a":"renounceMaster()","9502d761":"ProposalSubmitted(address,uint256)","950311ab":"setCurrentAction(uint256,uint8)","95032b62":"rand(uint256,uint256)","9503c4b4":"SmartRouletteToken()","95040933":"mrk_contract()","950463fc":"calculateRefundedEthWithDiscount(uint256)","9504f28a":"THBCToken()","95050862":"optimalExp(uint256)","95059465":"textFor(bytes32)","9505b2a7":"createPanda(uint256[2],uint256,uint256)","9506681f":"updateminContribution(uint256)","95066e33":"getTopic()","95068886":"change(address,uint256,address,uint256)","95069136":"requestLiquidation(uint256)","9506a57a":"Marriage(address)","9506a75c":"setChild(address,bytes32,bytes32,bool)","9507b53a":"SchedulableToken(address,uint256,uint256)","9507d39a":"get(uint256)","9508614b":"addStage()","9509a265":"allocateDividends()","9509ba0c":"getJackpotBalance()","950b5273":"currentARXtokenSupply()","950b550a":"fourth_withdrawal(uint256)","950c84e4":"presalePart()","950cb89e":"_editPriceOf(uint256,uint256,uint256)","950da0c8":"calculation()","950da0e6":"hasMinRating(address,address,uint8)","950dad19":"burnToken(address)","950dff20":"cancelCodeUpdate()","950ef8c7":"setAuthorityContractAddress(address)","950f4170":"gubbermentOverthrown()","950f9813":"rejectPartnerAllocation(address)","95101181":"removeAdminAddress(address)","9511309a":"setMinimumCollateralInEthAmount(uint256)","951166c0":"totalMessages()","9512243e":"TokenPurchase(address,address,uint256,uint256,uint256,uint256,uint256)","95127634":"upgradeOracle(address)","951303f5":"withdrawableAmount()","951367ad":"internalExchange(uint256)","951382bf":"mainSaleHasEnded()","95139780":"checkTokTotal()","951481b4":"addEmployee(uint256,uint256,string)","951506d3":"withdrawFeeRateE4()","9515a524":"BUSINESS_DEVELOPMENT_SUPPLY_LIMIT()","9515af55":"AetherClockAuction(address,uint256)","95163f39":"_finalizeStage()","9516a104":"getAllAddresses()","951717e2":"withdrawPrivateCoinByMan(address,uint256)","9518589a":"cost1token()","95199b24":"claimWin(bytes32,uint8,bytes32,bytes32)","9519e398":"aDeposit(uint256)","951b01c5":"setCertifierDb(address)","951b22fb":"swap(uint256,address,address,uint256,uint256,uint8,bytes32,bytes32)","951b26a3":"changeable()","951b73b1":"updateEndTimeManually(uint256)","951cfa47":"getScope()","951d0332":"_price_tokn_ICO1()","951d6c9c":"getDevRewardPercent()","951d86a4":"setBlockPerHour(uint256)","951e17a1":"totalSupplyForDivision()","951ea5f1":"setMarketingTokensPercent(uint256)","951f4a6e":"_triggerNFTEvent(address,address,uint256)","95206396":"numberLoop()","9520a06f":"DEFAULT_CREATION_LIMIT()","9520cc72":"EtherTradex()","9520f878":"NaxomartToken()","9521000c":"setOnlyShowPurchased(bool)","95210e59":"setBattleRemoveContractAddress(address,address)","95217ec9":"newAttack(uint32[])","9522ca89":"Message_To_Investors()","9524bdf8":"_refundTokenCustomer(uint256,uint256)","9525c0cc":"cancelVote(bytes32)","9525f382":"finalizeSettingCreation(uint256)","95260a29":"PEP()","95263183":"setACmarge(uint8)","95270cd1":"setOraclizeFee(uint256)","95275e5e":"minerLockTime()","95286077":"UBETCOIN_LEDGER_TO_LEDGER_ENTRY_DOCUMENT_SHA512()","952868b5":"onMaintenance()","9528724f":"votedFreeze()","952882fd":"addtoEarlyInvestors(address,address,uint256,uint256)","9528a278":"getAllInvestorPositions()","9528d109":"authorSigned(address)","9528fcb5":"numSubscribed()","952a84ed":"Rocketship()","952a9320":"HexanCoin(uint256,string,uint8,string)","952ad7cb":"forwardSomeFunds(uint256)","952b264c":"FundsReleased(uint256)","952c0f9f":"initGold()","952d6c22":"tokenSaleEnd()","952f2f6f":"setAccountIsFrozenByDate(address,uint256)","95306706":"logTraderTradingTx(string[])","953078cd":"withdrawDivsWithContract(address)","95311142":"dOwnerErc20Claim(bytes32)","9531c536":"ReceivedGBP(address,uint256)","9531d072":"refundETH(uint256)","953203b5":"doMigration(address)","9532c476":"setParcelUsd(uint256)","953307d8":"revealScissors(string)","95334db2":"toIndex(address)","953440f9":"nCeilings()","9534e637":"closePoll(uint256)","9535ce12":"getBool(string)","95360a02":"calCurrentCrystals(address)","95364a84":"isPresale()","953669be":"tokenHolders()","9536c05f":"doCheckSendBounds()","9536e0bb":"returnDirectPayments(address,bool,bool)","9537796f":"addSubscriptionBonus(address)","95377ad9":"testInequalityUint(int256)","9537e8d1":"signContract(uint256)","9538833c":"changeOwnerAccept()","9539c4de":"withheldAmount(address,address)","9539ed7e":"changeFlipper(address)","953a03ca":"minMillPurchase()","953a7fab":"testMoveBalance()","953aa435":"GetPrice(uint8)","953b42b3":"buyClusterToken()","953b7ef8":"withdrawTeamTokens()","953b8fb8":"targetAmount()","953bad32":"verificationAddressMap(address)","953e3450":"DaoRulesProposalAdded(uint256,uint256,uint256,uint256,uint256,uint256,bool)","953e474a":"setKoCommissionAccount(address)","954056f7":"setRedemptionWallet(address)","9540cb80":"End1()","9541945a":"registerNode(bytes16,uint16)","9541bc41":"getUSDAmount(uint256)","954290f4":"guessPassword(address,uint256,bool)","95437056":"AUTH_ADDOWNER()","95438548":"DONATION_RATE()","95441f9f":"ZEEWANTtoken()","95449ad5":"changeTimeInvest(uint256)","9545c42c":"minForExistingTopic()","95470497":"OTHERCRUISER_EXTRACTION_BASE()","95475c1f":"makeChild()","9547b44d":"Prepurchased(address,uint256,uint256)","95480879":"setDefaultMetadataURI(string)","9549355e":"oracalizeReading(uint256)","954969f6":"godSetInterfaceContract(address)","9549c330":"freezeFrom(address,uint256)","9549fea9":"MENSA(address)","954a5c19":"addPot()","954a8f8b":"TransferWithRef(address,address,uint256,uint256)","954ab4b2":"say()","954b2be9":"SelflleryYouToken()","954cbe3f":"mintSpecial(string,string,uint8,uint256,uint256)","954d2cfd":"updateUrl(address,bytes32[5])","954db474":"newProject(string,string,uint256)","954e8c2d":"buyShares(uint256,address,uint256,uint256)","954f3b20":"getTransferHash(address,address,uint256,uint256,uint256)","954ff2ad":"founderTokenWallet()","9550c023":"AllocationRevoked(address,address,uint256)","9551dd58":"listener()","955214d1":"LogRecordWin(address,uint256)","95522e54":"WeaponTokenize()","95523f7d":"newMember(string,uint256)","95533f17":"isTokenInList(address)","95534e00":"getAccountBlocks(address)","95535569":"LianBaoCoin()","9553652b":"Goldencloudtoken()","9553a19b":"BrengsTeamToken()","95543693":"ONE_DECIMAL_QUANTUM_ANZ_TOKEN_PRICE()","9554a202":"changeSwapperAdd(address)","9554c8e5":"getCrydrStorageAddress()","9554f920":"fillChannel(uint256)","9554fa12":"multiplies(uint256,uint256)","9555a942":"withdrawFrom(address,address,uint256)","9555c9d9":"capAdjusted()","95564837":"seed(uint256)","9556a31d":"GVOptionToken(address,string,string,uint256)","9556b05d":"OraclePoloniex()","95578ebd":"useDELEGATECALL()","95579063":"_bidderHasAnActiveBid(address,uint256,address)","9558abde":"sycCrowdsale()","9558e916":"teamWithdrawalRecipient()","9559225c":"debug_hash3Byte(bytes)","955b1535":"checkForNewLeader(uint256)","955b5e72":"CTCToken()","955d14cd":"getLastTime()","955d1721":"availableBalanceInLockingPeriodForInvestor(address)","955d4412":"addLocation(uint256)","955d4d16":"Wixlar()","955d50b7":"TestMasterToken(uint256,string,string)","955ef429":"closedown()","955f0460":"sgpc(uint256)","955ff603":"Viviox()","95607ced":"retrieveAll()","95608083":"_abortCurrentRound()","95612ec0":"allowInvestment()","95617dc3":"reportGame(string,uint8,bytes32,bytes32)","9561a038":"nextContributorIndex()","9561f0d8":"setTradingLive()","95621ccd":"theBet(uint256,uint256,uint256)","95623641":"marketAddress()","956248aa":"determinePayout(uint8,uint8,uint8)","95635b37":"addMiner(address,uint256,uint256)","9563dbcf":"setPeriods(uint256)","95645e34":"initialDistribution()","956483c1":"lastBlock_f14Hash_uint256()","95648f1b":"getFunctions()","95652e4f":"revokeAuthority(address,uint256)","95655f04":"getWilds(address)","9565f2fe":"AllCash()","9565feeb":"isBonusPeriod()","9566880b":"s16(bytes1)","95669952":"debtor(address,uint256)","95671958":"getFileListTail()","95671ed7":"logEvent(string,bool)","9567a161":"newBet()","95693aad":"CompositCoinCrowdsale(uint256)","956a2d03":"balance(bytes32,string,address)","956a2ea7":"setBidRegistry(address)","956a538a":"CoinsRemainAfterICO()","956a860d":"getMartialInfo(uint256)","956ab5d9":"getParetoBalance(address,address)","956b76f7":"setVicepresidenteDeMesa(bytes32,uint256,uint256,bytes32)","956cc859":"INIT_SUPPLY()","956d2172":"setAttackFee(uint256)","956e5f00":"LogEtheraffleChange(address,address,uint256)","956e958a":"dungeons(uint256)","956f4361":"getCampaignsByCountry(string)","956fd9df":"balanceOfPlayers(address)","956fffd3":"setFinishICO(uint256)","95701be3":"rolloverFeePeriodIfElapsed()","9570370f":"bondsOf(address)","95709441":"mintReputation(int256,uint256,address,address)","95722371":"storeX(uint8[],uint256,uint256,uint256,int256)","95722e66":"payPool()","95725d8a":"emitRoleAdded(address,uint8)","957287ce":"market2()","9574f4e1":"createMatch(string,string,uint256,string)","957563ec":"setProviderLock(bool)","95761c77":"SBCS()","9576b180":"initGoldData(uint256,bytes32,bytes32,bytes32)","9576bfbd":"setWhiteLister(address)","9576e5b3":"registerContract(address,bytes32,bool)","9577941d":"LogKill(bytes32,bytes32,address,address,address,uint128,uint128,uint64)","9578bce2":"setCreditsTokenPrice(uint256)","957908d1":"dequeue()","95792430":"grant(address,uint256,uint256,uint256,uint256,uint256,bool)","957a2772":"lastBlock_f9()","957a6254":"bonusScheme()","957aa3d1":"goldmintTeamAddress()","957aa58c":"live()","957ac9ad":"HappyBeeToken()","957b2807":"getPlayerPlayInfo(uint256,uint256,uint256)","957b2e56":"reinvestDividends()","957b52fb":"fidaPerEther()","957b781c":"mintBonus(address)","957b8d98":"publicsaleTokens()","957bb1e0":"bid(bytes32)","957c0ff2":"testNoTokensOneCall()","957d8250":"allocateBid(address,bytes32)","957dcb1e":"mintReservationTokens(address,uint256)","957e05d6":"setAllowTransferLocal(bool)","957f050b":"merchantAccount()","957f120e":"inPublicPreSalePeriod()","957f371f":"totalAmountOfEarlyPurchasesWithoutBonus()","957f9a0b":"tryFlush()","95803d6c":"STARTING_BULLS()","95805dad":"start(uint256)","9580811c":"setBalanceAdmin(address,uint256)","9580c4bc":"migrateFunds()","95816a16":"contributionCap()","958174a3":"ParentToken(uint256,string,uint8,string)","95818603":"fromTweiToFp(uint256)","958222aa":"isTokenTransferable()","95829738":"institutions(bytes32)","9583102a":"verify_send(address,uint256)","958343f9":"setOrderDealSpeed(uint256)","9583cf17":"claim_period()","9584894c":"getElementInfo(uint256)","9584fbfc":"TOKEN_SHARE_OF_TEAM()","9585a877":"isGameActivated()","958689d7":"emitMintEvent(address,uint256)","95878da6":"CurrentICOpublicSupply()","958799cb":"recordPurchase(address,uint256)","95880360":"setExchangeRatePreIco(uint256)","9588378e":"reputationOf(address,bytes32)","95883871":"TradeListing(address,address,address,uint256,uint256,bool)","958993a5":"allocatePrivatePresaleTokens()","958a3698":"setITTMultiSig(address)","958a41dd":"upgradeToAndCall(string,address,bytes)","958a9937":"createProduct(bytes32,uint128)","958b12b9":"ICOCap()","958b3f20":"final_fundraise()","958b6f55":"checkTokenVesting(address,uint256)","958c4be7":"makeCollectibleUnavailableToSale(address,uint256,uint256,int256,uint256)","958ce2d5":"Spoke(bytes16,string)","958d1725":"getChild(bytes32,uint256)","958e0028":"SoarCoin()","958f3624":"totalTokenWinValue()","958fde82":"newPinnedAppInstance(bytes32,address)","95907291":"CaptureTheFlag(string)","9590d4b9":"testCount()","9590ef13":"Option(string,string,uint8,uint256,address)","95910d46":"ownerPrimary()","95925814":"undo_deadline()","95929d22":"_updateNextAmount()","9592d424":"totalNodes()","95930b1c":"getAssetPacksUserCreated(address,address)","95932df3":"addCustody(address)","9593aa9a":"JTOKEN()","95949823":"setRemark2(string)","959499b6":"withdrawProfit()","95955d22":"escrowTransfer(address,address,uint256,uint256)","9595898a":"updateCard(uint256)","95966c3b":"get_eth_balance(address)","95969ba4":"enabledAddresses(address)","95977749":"IvoryTest()","95978868":"strConcat(string,string,string,string,string)","95980858":"currentText()","95982228":"Multiowned(address[],uint256)","95982f44":"GetLottery(uint8)","9598790d":"priceTokenSellWei()","95988a26":"proposalsRank()","95997c51":"withdraw(uint128,address,uint256)","9599ab63":"crowdsaleBonus(uint256)","959a1f08":"Hive()","959ac484":"push(uint256)","959b3fa0":"createSkin(uint128,uint256)","959b6916":"setCollectTokenTime(uint256)","959b8c3f":"authorizeOperator(address)","959c265b":"makePlayerID(address)","959ca192":"createCoupons(uint256)","959cb555":"address_register(address)","959d51f6":"W3SchoolToken(uint256,string,string,uint256)","959e4748":"totalIssuanceLastModified()","959e90ff":"totalTransactionCount(address)","959f601e":"getLimitMaxCrowdsale()","95a01505":"presaleStorageVault()","95a039ba":"getContractAddress(string,string,string,string)","95a078e8":"hasAccess(address)","95a08221":"tokensTotalSupply()","95a0f5eb":"totalMigrated()","95a0f9c7":"removeOffer(uint256)","95a1297a":"totalRewardsRedeemed()","95a13ff3":"polyComplianceAddress()","95a1c14d":"addThreeWayLine(uint256,string,uint256)","95a2251f":"redeem(address)","95a235ae":"set_deposit_address(address)","95a23c3a":"adminsPercent()","95a2d14b":"IcoCloseTime()","95a3bf6e":"getPayoutRequestedState()","95a3e2af":"isAddressFrozen(address)","95a47652":"getMintingStatus()","95a4f76d":"maxSaleNum()","95a50a9d":"monarch()","95a51233":"totalSupplyCeiling()","95a51669":"buyWithETH(address,uint256)","95a5418d":"_patternToNumber(bytes4)","95a59ac4":"PacificaToken()","95a5dfc0":"yes(uint256,string,uint256)","95a6f9ab":"makeProposal(string,uint256,uint256,uint256,uint256,address)","95a70863":"setOwner(uint16,address)","95a8c58d":"hasRole(address,uint8)","95aaa5d9":"BatakToken()","95ab32a3":"securityPercent()","95ad3d98":"ConnectCoin()","95addb90":"questions(bytes32)","95adfe72":"getPlayerPrice(uint256)","95ae0bf9":"extCreateNinja(uint256,uint256,uint256,uint256,address)","95ae66a5":"MilestonePricing(address,uint256,uint256[])","95af7006":"setFirstBonusPercent(uint256)","95afc05c":"withdrawRefunds()","95b1157d":"setLockAccount(address,uint256)","95b18bbe":"Created(address,uint256,uint256)","95b1e4f2":"addClaim(uint256,address,uint256,bytes32,bytes32,string)","95b1f93b":"changeStakerOperation()","95b2110a":"queryAirCrash(string)","95b25a1c":"Biograffi()","95b2d128":"TokenFund(address)","95b34f71":"_getTokens(uint256)","95b3559f":"CertifyDelegate(address)","95b3c92f":"TioToken()","95b3dc77":"setTransferableTime(uint256)","95b4b88d":"allowanceSub(address,uint256)","95b505f0":"getMigrateOutReporterValue()","95b537d5":"selfOn()","95b5d5ac":"token_ask(address,uint256)","95b68fe7":"getTokenToEthInputPrice(uint256)","95b6a08d":"canDisburseMultipleTimes()","95b71187":"getByFromCount(uint256)","95b7c348":"ICOCappedRefundableCrowdsale(uint256,uint256,uint256,address,address)","95b7ea26":"GetMaximumBet_ether()","95b7f0aa":"_removeAuction(address,uint256)","95b890d6":"purchaseTokensWithoutDevelopmentFund(uint256,address)","95b8cf55":"signalBackupWithdraw(address)","95b8fdef":"setCompte_22(string)","95b96e11":"PeriodEnd(uint16,uint256,uint64)","95b9bb68":"setCompositionAddress(address)","95ba64c9":"LogForbid(bytes32,bytes32,bytes32)","95bad022":"countTeam()","95bb733b":"CurrentCrowdsale(uint256,uint256,uint256,uint256,address,address,address)","95bb8d46":"publicSaleTransfer(address[],uint256[])","95bb9fcf":"getHolding(uint256)","95bbbe45":"transferFundWalletWallet(address)","95bc2673":"remove(bytes32)","95bc3bd0":"lockAmount(address)","95bc7eec":"payFunction()","95bc8515":"setHolder(address,uint256)","95bc9538":"changeStatus(uint8)","95bda19d":"register(address,uint256,address)","95bda742":"_create_user(address,address)","95bdca94":"isTyped(address,uint256)","95be55a6":"increasePrice_20_February()","95be7542":"CoinLLeague()","95be9ace":"NewDeal(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool,string)","95c02700":"ACN()","95c08f92":"investmentOf(address)","95c0954c":"ownerOfUUID(string)","95c0c3f6":"confirmGameEnded(bytes32)","95c0c447":"getLimitTypeOf(address)","95c0d65c":"editRank(uint256,uint256,uint256)","95c0e6c3":"transferOwnershipAtomic(address)","95c21ebf":"blueOs()","95c26d93":"thirdTierDiscountUpperLimitEther()","95c2d845":"driveCar(string)","95c303bc":"pyramid(address,uint256,bytes32)","95c30910":"unFreeze(address,address)","95c3be0b":"participantIndex(uint256)","95c3fc9b":"_setPowerBalanceOf(address,uint256)","95c43d84":"PHASE2_SUPPLY()","95c47416":"VoteOnMyTeslaColor()","95c4e59b":"AXIACOIN(address,address)","95c55798":"WZCoinToken()","95c5a2cc":"halfPercent(uint256)","95c5ed9d":"getVoterStatus(bytes32,address)","95c6fa61":"keyOf(bytes32,bytes32)","95c7a23f":"AutoBuy()","95c7b007":"setFreezeTx()","95c8d4ee":"grantAllocation(address,uint256,bool)","95c92d98":"viewTotalAffiliateCommissions()","95c93f8b":"setTierRates(uint256,uint256,uint256,uint256)","95c96554":"cancelVote()","95c97432":"nSubmittedHashes()","95c9f53f":"scaledDividendPerToken()","95cc2e8b":"DATE_ICO_START()","95cc74fe":"buyFromPartner(address)","95ccea67":"emergencyWithdraw(address,uint256)","95ccf8bf":"forward(address,address)","95cd73a2":"OpCoin()","95cd76fa":"getMaxOwners()","95ceb4b3":"winningProtocal()","95d12000":"ownerPercent()","95d22683":"MyUserName(string)","95d2b4b4":"_createMonster(uint256,address,uint256,bool,bool,bool)","95d38ea8":"mintableToken()","95d395dd":"XDToken()","95d47f2f":"lastBlock_f8Hash_uint256()","95d4f7dd":"primaryGasLimit()","95d5766c":"foundersContract()","95d5a1be":"SignatureReg()","95d5f6fd":"officialSite()","95d643a8":"earnings()","95d6718a":"grantOf(address)","95d697c4":"ProofOfReadToken(uint256,uint256,string,uint8,string)","95d793d9":"deposit(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","95d84b30":"_replaceContract(address)","95d84d99":"setColorPurple()","95d89b41":"symbol()","95d8f60d":"sumHardCapICOStage6()","95d9a030":"externalControllerCandidate()","95d9cc18":"setStdOwner(address,address)","95db03fe":"krypteum()","95dba6c9":"getHealthForCost(uint32)","95dbee2d":"gift(address,address,uint256)","95dcac25":"IGTSGD()","95dd489b":"winningsPerRound()","95ddb3a6":"setJewelContract(address)","95de00a2":"getReservedDestinationInfo(address,bytes32,address)","95dea05b":"cleanActions(bytes32[])","95e05110":"sumHardCapICOStage3()","95e16e97":"validateraffle()","95e19fab":"setup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256[],uint256[],uint256[])","95e1d9f7":"getGamesForAdmin(address)","95e2a953":"etherRatioForInvestor()","95e2c773":"privatePreICOdepositors(address)","95e396f9":"crowdsaleTokensWallet()","95e3c50b":"tokenToEthSwapInput(uint256,uint256,uint256)","95e3cd5c":"preAllocation(uint256,uint256)","95e4c1bf":"hasConfirmedRecord(bytes32)","95e4d456":"DUNGEON_CREATION_LIMIT()","95e517be":"Offer(address,string,address)","95e52d98":"documentsCount()","95e66ea1":"isLeftTokenIssued()","95e77a05":"testItemStrict(bytes)","95e7b3c5":"angelRate()","95e87385":"availableRef()","95e8a67e":"toB32(bytes,bytes)","95e8d644":"requestRemoveOwner(address,string)","95e8f3e7":"get_hash()","95e911a8":"feeBase()","95eb8f15":"Attempt(address,uint256)","95eced5f":"ZToken(uint256,string,string)","95ecef72":"gSetRunning(bool)","95ed857c":"mintPredefinedTokens()","95ee1221":"isCancelled()","95ee4cfd":"set_percentFeeTimes5(uint256)","95ee8bae":"getInt(address,bytes32)","95eeb240":"disableApproval()","95ef9178":"setTokenSaleContractAddress(address)","95f0684b":"getPackageNameHash(uint256)","95f0f107":"_setBridgeAmount(uint256,address)","95f1260b":"balanceToWithdraw()","95f17bce":"cancelCost()","95f20e88":"RANDCRYPT(uint256,string,string)","95f22405":"getImageInfo(uint256)","95f28272":"salesTokenHolder()","95f382bc":"depositVault(uint256,uint256)","95f47e4e":"setRegulatorAccessLevel(address,uint8)","95f5784f":"FIBASK()","95f59fe1":"vote(string,string,string)","95f62fb9":"registerDevices(bytes32[],bytes32[],bytes32[])","95f847fd":"transferToContract(address,uint256,uint256)","95f9432d":"ThankYouToken()","95fa7430":"get_iconiq_tokens(address,address)","95fbdcd9":"MeshToken()","95fbfa0d":"testBurningUndistributed()","95fc6354":"PLAYER_START_PERIODS()","95fc799f":"allocateRestrictedTokenToPartner(bytes32,bytes32,uint256)","95fcb00d":"addVesting(address,uint256)","95fdd612":"hasRequested(bytes32,address[])","95fe0e65":"createD(uint256)","95fe27d3":"SmartCripto()","95fe4608":"revokeCert(bytes32,bytes,bytes32,bool,uint256)","95fe5234":"setSubnodeOwner(bytes22,address)","95fe6865":"checkIfCanUseTokens(address,uint256)","95fe6f1d":"isAddressReserved(address)","95ff24e3":"SellTokens(address,uint256,uint256,uint256)","95ff3cc1":"getMyApples()","95ffff09":"getMyBananas()","960024ff":"rebuyStarted()","96002aef":"offerProductOwnership(bytes32,address)","9600ead9":"RESELLING_UNLOCK_COUNT()","9600ec92":"transfer(address[],address,uint256[])","9600f294":"refundTokenPayment(uint256,address,string,uint256,address)","9601065d":"reachedMajority(uint256)","96013c9c":"testLatestPkgGetter()","960173b5":"aliceClaimsDeposit(bytes32,uint256,uint256,address,address,bytes20)","9601deb8":"LogTransferOwnership(address,string)","96023032":"updateContractAddr(string,string,string,string,address)","9602339d":"AlfaTowerShares()","96023cbf":"registraToken(bytes32)","96026d61":"BucketAndValuationAndCommitted(uint256,uint256,uint256)","9602bb20":"AMBTICO()","9602e9d5":"withdrawDev()","960384a0":"getValue(string)","96038f8f":"ICO_Graphene()","9604702a":"matchExistingBids(bytes32)","960491d7":"setNextRndTime(uint32,uint32,uint32)","9604a24b":"getPoolCapSize(uint256)","960524e3":"getInvestorCount()","96063049":"rollDice(uint8)","96066cf9":"MintConfirmed(uint256,address,uint256)","96069ee1":"CIPToken(address,uint256)","96074e70":"addBeneficiary(address,uint256)","9607610a":"withdrawFor(address,uint256,uint8,bytes32,bytes32)","960787a2":"sendFoods(address[500],uint256[500])","9607a1db":"claimShare(uint256,bool)","9608088c":"setAddress(address,address,address,address)","960834f4":"dAddBallot(bytes32,uint256,uint256,bool)","9608740e":"verifyBid(uint256,bytes32)","9608e9df":"DataWasRecorded(address,uint256,bytes32,uint256,string)","960954af":"chargeAdvertisers(address[],uint256[],address[],uint256[])","960983f4":"addArtifact(string,string,bytes32)","9609e488":"TootyrCrowdSale()","960a48ae":"createPreIco(uint256,uint256,uint256,uint256,uint256,uint256,address)","960a57fc":"SHA256HashRegister(bytes32)","960ba088":"createFinancialStrategy()","960bfc9b":"_owns(address,uint64)","960bfe04":"setThreshold(uint256)","960d3f56":"impl_mining(address,uint256,bytes)","960d8cd3":"testFailUpdateLatestRevisionNotOwner()","960d94bb":"get_presale_goal()","960e55a8":"ChannelCloseRequested(address,address,uint32,uint192)","960e80b7":"trans()","960ecf0c":"addNewStage(uint256,uint256,uint256,uint256,uint256)","960fa70f":"synthGenes(uint256,uint256)","96102d7d":"ownerSetWallet(address)","9610e068":"GetAskingUnitPrice()","9610f0e6":"pveBattleFee()","96119f12":"SkribbleToken()","9611bfc5":"_getExistingTileAt(int32,int32)","96131049":"withdrawal(address)","96132521":"released()","9613bc90":"isEvolvementAllowed(uint256,uint256)","96147933":"ContractEnabled()","9614c769":"setDesc(string)","9615ecb2":"wasSuccess()","9616b410":"incFreezeIndex(uint256)","96176797":"LogTransition(bytes32,uint256)","96178c20":"totalSupply2()","9617d90d":"cartaxiToken()","96186b6e":"MAX_PERCENT_OF_PRESALE()","961891d5":"changeEscapeController(address)","9619367d":"minBet()","961a16f2":"secondExchangeRate()","961a9218":"setLLV_edit_17(string)","961a929c":"gasPriceLimit()","961b16a1":"addInTeamBalanceMap(address)","961b2b96":"assignBountyAddresses(address[])","961be391":"cash()","961c2470":"refundRoots()","961c9ae4":"createAuction(address,uint256,uint256,uint256,uint256)","961cc569":"airdropReceiversLimit()","961cd8ce":"ticketsForWithExcess(uint256)","961d1284":"isRefundingEnabled()","961d30cc":"getMasterNodesDates(address)","961d3cd3":"setExclude(address,bool)","961e99d9":"startBuyBackTwo()","961f1d96":"RANGESTART_3()","961ffc68":"GatewayInterfaceAddress()","9620b995":"transfterForProjectManagement(address,uint256)","96214735":"setDeployer(address)","962174b6":"LotteryClaveChain(address)","9621bcf7":"publishTaskListing(string,address,uint256,uint256,uint256,uint256)","9621f497":"SetMaxAirDropXblock(uint256)","96221dc9":"mulX(uint256)","962318b8":"teamKeepingPercentage()","96242f41":"getFrontEndTokenSupply()","96246eb8":"Zmbc()","9624e534":"setBlockDotNumber(uint256)","9625a6c6":"hardLimitICO()","9627bf02":"preIcoEndsAtChanged(uint256)","96283310":"setHouseAddressShare(uint256)","96284fb6":"getNizkStruct()","96286cc9":"isTokenOwner(address)","96289427":"transferRestTokensToOwner()","9629da17":"withdraw(uint64,address,address[],bytes32[],address[],uint256[])","962a64cd":"convert(string)","962aab81":"blockEnded()","962ba36f":"quarantine(address,address[],uint256[])","962ba969":"ExceedIOToken(uint256,string,string)","962c9898":"SOLUSToken()","962c9c8d":"MAX_VOTED_TOKEN_PERC()","962ca53e":"Cosby()","962d0c72":"overRaisedUnsend()","962dae57":"getPriceContract()","962ffeae":"totalCurrentFunders()","9630961d":"createRole(bytes32,address[])","9631c1bd":"FounderFeeInPercent()","9633303f":"setSrc(address)","96344d05":"creatorRequestFundTransfer()","963476e5":"listBackers()","9634ef56":"start_of_report_period()","9635024c":"TANDER()","96354f6d":"BONUS_ICO_STAGE1_PRE_SALE3()","9635eaf7":"fundsToAddress(address,uint256)","9635fc2c":"yahooOracleUrl(bytes32)","963630a3":"ETGOLDToken()","963632d3":"Prosperity()","96365d44":"poolBalance()","96370fa2":"savePic(string)","963749b6":"calculateWinnerPrize(uint256,uint256)","963812c3":"createItemId()","96382f0b":"gameStatus(bool)","96383c04":"setPrice(uint256,uint8)","96386ab3":"myMethod2(string)","96389bd7":"OwnedController(address,address)","9638a89c":"DataRecordIndexStructs(uint256)","963a9a13":"startInvite()","963c0724":"Lucky()","963c1121":"set_pre_kyc_iconiq_bonus_numerator(uint256)","963c11df":"totalScammed(address)","963c3397":"winning_year()","963c6017":"postGoldPeriod()","963d62fb":"tokenLossRatio()","963dd1dd":"Diatom()","963de4d2":"GetBet(uint256,uint256,bool)","963e2680":"setMinSiteTipPercentage(uint256)","963e63c7":"minValue()","96401470":"TutorialToken(uint256,string,uint8,string)","96406391":"setTokenDistribution()","9640da30":"ethRedeemed()","96419497":"PAXToken(bool)","9642a19c":"optInGas()","9642ccdf":"functionName(bytes20,address)","9642ddaf":"testMint()","9643aef4":"testControlCreateWithParentSameNonce()","9644fcbd":"changeMembership(address,bool,string)","96450a6d":"walletWithdraw()","9645337a":"removeOrder(uint256)","9645bae5":"newAuction(uint256,uint256)","964620d2":"TheMostPrivateCoinEver()","96463fc6":"createTrade(uint256,uint256)","96468249":"getFoundation(address)","96469132":"setPonziPriceInWei(uint256)","9646b85d":"getMintableAddress()","9646df4d":"presaleEnds()","9647259c":"dividendDistribution()","9647df97":"TES()","9648c9f4":"sessionId()","9649650c":"removeBank(address)","96497258":"withdrawOverdraftTokens(address,uint256)","964997a4":"MoacSupply()","9649ccaa":"updateSubscriptionOffer(uint256,uint256)","9649d98b":"restrict()","964a4ac7":"ULTRA_HERO_MULTIPLIER()","964ad434":"TIER1_CAP()","964afe08":"addSomething(uint256)","964b97de":"box2Star5()","964c0b40":"ExtensionCalled(bytes32[8])","964c7d84":"addressToBlock(address,bool)","964c836c":"receiveExecutionNotification()","964ecc09":"forceRefunding()","964f61f9":"getCosigner(uint256)","964f6dcd":"Elephant()","964f8fba":"totalDinoSold()","964fad94":"fundingGoalOf(uint256)","964fb96d":"test_init()","965232c0":"getTotalAllowed(address)","9652389c":"setPreSaleOn()","9652713e":"runSigned(uint40,uint256,address)","96532d1c":"mintingAllowed()","9653dee5":"tokenSwap()","9653f8a1":"etherBalances(address)","965447d9":"toPowerOfTwoThirds(uint256)","965582d6":"requestNewID(string,string,string)","9655943e":"validMCAmount()","9655e4b0":"sellIdeas()","965693ee":"TicketsPurchased(address,uint256[],uint256[],uint8[])","96574919":"removeStakerFromArray(address)","96577caa":"getLowWinPercent(uint256)","9657f8ad":"TopiToken()","96581de1":"registerPayments(address[],uint256[],uint256[])","9658522c":"createPlayerOnAuction(uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint8,bytes,string,uint256)","96594efb":"WorldBit(address,bytes2,bytes2,uint256,uint256,string,string,string,string)","9659867e":"mintCount()","965a324e":"OxShelterEye()","965a3b7e":"targetDemographics()","965acc73":"setCampaignBudgetById(bytes32,uint256)","965b0cc4":"signedApproveAndCallCheck(address,address,uint256,bytes,uint256,uint256,bytes,address)","965b2bae":"setFinancierParticipationAdd(address)","965b5aa8":"paySolutionRewardGoodRep(address,uint256)","965b71bc":"cfoWithdraw()","965bdf33":"SetAuditedAssetSize(uint256)","965be457":"registerApp(bytes32,address,bytes4[],address[])","965beae8":"bulkTokenSend(address[],uint256)","965c643f":"setReference(bytes32,string)","965c90e3":"getNodeByIndex(uint256)","965edec5":"_publishSecret()","96603e88":"hotPotatoHolder()","9660ab3a":"setContractUser(address,bool)","9660aeeb":"isMatching(int256,int256,int256)","96617ba4":"ClientsNotified(string,string)","966203e7":"Product(bytes32,bytes32,address[],int256,int256,address,address)","9662355e":"generateAttestForDelegationSchemaHash(address,address,uint256,bytes32,bytes32,uint256[],bytes32)","96637b10":"getEscuela(uint256)","9663871f":"recursiveRound(uint256,uint256,uint256)","9663a496":"awardBronze(address,address,address)","9663f88f":"getBlockHash()","96642cfc":"_isAuctionExist(uint256)","9664ca94":"date_string(string,int8,int8,int16)","9664d2d9":"resourceIndex(address,bytes4)","9665688e":"setGame(uint256,uint256,uint256,uint256,uint256,uint256)","966588d4":"cloneWithTwoPops(uint256,uint256)","9665b658":"changeExecutor(address)","9665ef09":"bitmask_show(address)","9665f170":"pregnantEtherDogs()","96661b04":"closeDataResponse(address,bool)","9666856d":"stopList(uint256)","9666cbfa":"getDeployedMatches()","9666e1f9":"isCosignerSet(uint256)","966704c2":"autoTransferLocked(uint256,uint256)","96682704":"TransferToReferral(address,uint256)","96686560":"Setup(string,string)","96687919":"_preSaleSupply()","9668b281":"AKContract()","966933ce":"DURATION_PER_VESTING()","96696da8":"getHives()","966a1961":"get_time()","966a360c":"newExchange(address,uint256,address,address,uint256)","966a3b29":"setJMETHExchangeRate(uint256)","966a7dca":"payOrder(string)","966aa252":"addProperty(bytes32,bytes32,bytes32,bytes32,bytes32,uint256,bytes32,bytes32,uint256)","966acb38":"testThrowTransferNotTransferable()","966aeece":"changeWhitelister(address)","966b3514":"contract_address()","966b7d91":"AdminChangedFundingWallet(address,address)","966dae0e":"factoryAddress()","966dcd26":"intertransfer(address,address,uint256)","966e6ead":"DefaultReleaseCalled()","966edae7":"lastBlock_a3()","966f697c":"_getSubscription(bytes32,address)","966ff650":"totalBurnt()","9670078c":"burnDNC(address,uint256)","9670591b":"giveAwayHoldership(address)","9670c0bc":"getPrecision()","9671ef91":"WEI_TO_INSIGHTS()","9673d6a3":"events(string)","96744afb":"ADDR_TEAM_TOKENS_ACCOUNT()","967506be":"deleteTokenAddress(address)","9675bb9c":"totlePrimary()","967743a8":"unlock20Done()","96778446":"addVestingUser(address,uint256)","967826df":"maxAllowedManualDistribution()","96784f45":"balanceOf2(address,address)","9678a1e8":"ProxyCreated(address,address)","9678df74":"MerlinCash(uint256,string,string)","9678eb05":"SafeDiv(uint256,uint256)","9678fb88":"TACTICALCRUISER_MAX_CARGO()","96793725":"registerWallet(address,address)","9679dd7d":"tokenLeft()","967a08f7":"raiseTransferEvent(address,address,uint256)","967b2692":"SaleCount()","967b3c21":"unitEpicGrowth()","967c33b3":"Deployer()","967dd0ae":"orderFor(address)","967e6e65":"getAge()","967e8611":"placeCube(uint64,uint64,uint64,uint256,uint256)","967f1cc6":"ownerPause()","967ff23e":"blocks()","96800dfd":"updateCap(string,uint256)","96817396":"bonus20end()","96821fc1":"MAX_MILESTONE()","96834e36":"ownerSetStandardFee(uint256)","9683d11d":"OHWOWW()","9683fe3e":"create(address,bytes32,uint256,address)","9684da1a":"createGenesisUniverse()","9684fe92":"interestCycleLength()","9685e736":"stopAvatarCreation()","96862e2d":"PattyCoin(uint256,string,string)","968790d0":"reclamaPagamento()","96879353":"CreateIco(address,uint256)","968803e3":"CYC()","96881d20":"CoinParkToken()","968858c8":"tokenreward()","9688738b":"TokenContract()","968908a3":"createMarketMaker(uint256,uint16,uint256)","968997fb":"FootballToken(uint256,string,uint8,string)","9689ac95":"TYPE_NOT_AVAILABLE()","9689e535":"CBCC()","968b12aa":"Crowdsale(uint256,uint256,uint256,address,uint256)","968bb12c":"setLegalFileLink(string)","968bd60d":"LogSendReward(address,address,string)","968be45d":"MYPPToken()","968d1cff":"percentForCommunity()","968d73d8":"start_service2(uint256,address,uint32)","968d901b":"getCurrentGame()","968ed600":"totalFunds()","968f0a6a":"getBidBySiteIndex(uint8,uint256)","968f9dc3":"EtherReserved(uint256)","968fc02a":"DogRace()","9690be37":"deleteGame(bytes32)","9690caa6":"Umint21()","9691a8bf":"changeIndividualCapInWei(uint256)","969235a4":"getSaleStart()","969283e2":"availableVolumeEnclaves(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","969295ae":"changeReferral(address)","96934e88":"isReward()","96937617":"Rpct()","96938d5b":"watchedAddress()","969464f6":"isCauldronExpired(uint8)","9694f039":"founderSupply()","96957869":"verifySignature(bytes32,uint8,bytes32,bytes32)","9695e3c0":"EOMarketToken()","9696e59a":"totumPhases()","9696ef66":"SLOTS()","9696fbf5":"Daschain(uint256,string,string)","96974e47":"setMinAllowedBetInTokens(uint256)","96984631":"RANGESTART_10()","9698d611":"setSaleManageContract(address)","9699ca16":"getPublicKey(bytes32,uint8,bytes32,bytes32)","969ac477":"PRIZE_POT_PERCENTAGE_MAX()","969be87e":"testGetNewItemId()","969bece3":"setRegionOnSale(uint16)","969bf358":"getCurrentTokenSaleId()","969ca0eb":"scavengeEscrow(uint64)","969cb4da":"changeSubmissionPrice(uint256)","969cb7c3":"getPublisher(uint256)","969d5b94":"changeMultiSigWallet(address)","969da324":"updatedEtherPrice(string)","969ddd71":"getMaxCap(address,uint256)","969e3756":"exchange(address,address,uint256)","969ea336":"maximumInWei()","969eb430":"updateVerifiersPerShard(uint256)","969ef40d":"updateFinishFlag()","969f1af4":"addMinerQuest(address)","969f8a83":"getConfirmations(bytes32)","969fa9d2":"EmergencyWithdrawalSucceeded(address,uint256)","969fbf12":"contructor()","96a04925":"retreiveTokens(address)","96a16793":"changeOraclizeAccountingSettings(uint256)","96a1e85c":"get_total_quantity()","96a34fc7":"exchangeToken(uint256,address,address)","96a44d35":"devuelveApproles(bytes32)","96a49d60":"getCircle()","96a51fde":"OilVisionShare()","96a566be":"PartnersNotSet(uint256)","96a625a5":"plantcToken()","96a68b91":"makeUndestroyable()","96a69d04":"totalSquareStakes(uint256,uint256)","96a6a748":"POHStopTime()","96a70169":"tradeETH(uint256)","96a77176":"setPresaleTwo()","96a7cf6a":"callDestruct()","96a80699":"postAllocateAuctionTimeMints(address,uint256,uint256)","96a942c7":"minTokenPurchaseAmount()","96a952a5":"setInstallmentsLoanData(uint128,uint256,uint24,uint40,uint32)","96a9df88":"_withdrawAirdrop(uint256,bytes)","96aa6305":"totalNotCompleted()","96aab4f6":"setBountyAddresses()","96ab97a5":"hasVested(address)","96ac591e":"postICO(address,address,address,address,address,address,uint256)","96ad4131":"getRequiredAdmin()","96ad6c8a":"deposit_address()","96ad704a":"addToken(address[16],address,uint256)","96adad2e":"sellStores()","96adfe42":"mintWithData(address,uint256,bytes)","96ae44f6":"addAcceptedArbiter(address)","96afb365":"reclaim(bytes32)","96afc450":"emissionRate()","96afccb3":"withdrawDonation(uint256)","96b116c6":"statusDoacao()","96b1348a":"claimTokenFunds(address)","96b1e4d4":"isFreeze(bytes32,bytes32)","96b2c923":"changePlatformWithdrawAccount(address)","96b47f0d":"soldOnStage()","96b55f7d":"tierCount()","96b58ac8":"tokensLeftForSale()","96b5a755":"cancelAuction(uint256)","96b5c5f4":"FeeWallet(address,uint256,uint256)","96b5f7b6":"ParallelWorld()","96b6af5a":"submitCustodianDoubleSign(address,uint256,bytes32[],uint256[],bytes32[])","96b76c23":"stand(uint256)","96b828b4":"Lock(uint256,uint16)","96b86436":"foundersAllocatedAmount()","96b86e1d":"PLCRVoting(address)","96b90b05":"Apex()","96b9a9d0":"medalBoostAndBurn(uint16,uint64)","96bb1fef":"claimStakingRewards(address)","96bba9a8":"slashSmallUsername(string,uint256)","96bc0f94":"onlyAdminsFriends()","96bc1a89":"getLockedAmount_investors(address)","96bc2287":"PRE_FUNDING_GOAL()","96bc3f3a":"getForecastScore(uint256)","96bc4a40":"bsWallet()","96bc5ab7":"setOracleURL(string)","96bcf236":"am_i_on_the_whitelist()","96bd09a1":"edit_safe(address,string,string)","96bd8dae":"transferAllowance(address,uint256)","96be8878":"team2Balance()","96bf15bf":"gamePrice()","96bf4ed5":"TOTAL_TOKENS_FOR_CROWDSALE()","96bf5022":"MRIDUL()","96bfc229":"isInWhiteList(address)","96c0fb8b":"setWhiteListInBatch(address[])","96c108c9":"assignToBeneficiary(address,uint256)","96c12acb":"Fuck()","96c14d92":"closeContract(bytes32,bytes32,uint256,uint256,uint64,uint64,bytes32,bytes32,bytes32,uint64)","96c16735":"UselessAirdroppedToken()","96c237b4":"getDeedInfo(address)","96c266ca":"developersKey()","96c28881":"fundraise_max()","96c2d498":"XTL()","96c2d4c9":"totalTipForDeveloper()","96c36170":"icoEtherBalances(address)","96c38294":"getETHUSD()","96c52fc3":"____forward(address,uint256,uint256,bytes)","96c5406d":"tokenFree()","96c5743a":"test03AliceBuyToken()","96c5ea93":"icoBeginDate()","96c62b27":"BalanceBook()","96c72144":"GrimReaperAddress()","96c74715":"NBW()","96c7a2a3":"BlockRxToken(uint256)","96c81be5":"unicornsOf(address)","96c824a8":"createAccountFundContract()","96c82e57":"totalWeight()","96c85b59":"TestBancorFormula()","96c8da45":"oneTokenInEur()","96ca7653":"LottixTest()","96cb4bc5":"RESERVED_ECOSYSTEM_GROUP()","96cc7be7":"updateCeleb(uint256,uint256[6],uint256[6])","96ccacb0":"hour_blocks()","96cdb027":"InstallerEscrow()","96ce0795":"denominator()","96cea3f7":"confirmWithdrawTransaction(uint256)","96ced078":"getPlayerNumbersInGame(uint256,address)","96cf5227":"changeLockTime(uint256)","96cfd124":"signedTransferHash(address,address,uint256,uint256,uint256)","96cfda06":"getCourseCount()","96cff3df":"getMinimumCallCost(uint256,uint256)","96d002a0":"subFundBalance()","96d02099":"rsplit()","96d122ea":"getStoreAddress(string)","96d195bd":"getWitnesses()","96d1c952":"filterBuyers(bool)","96d28e00":"spinDeposit()","96d2ede5":"preBalanceOf(address)","96d3196b":"getSumActiveToken()","96d373e5":"cast()","96d37936":"finishTokenMinting()","96d43cc6":"getMinimumFundingGoal()","96d46500":"ICO_CAP2()","96d4cb9b":"FipsRegistration(bytes20,address)","96d4d091":"advisorAddress()","96d4ebf1":"finneyPerToken()","96d4f640":"createOrder(address,uint256,address,uint256,uint256)","96d6401d":"TRANSFER_PROXY()","96d66cf8":"expertsAccount()","96d6c134":"coreVUPDestination()","96d7a9ed":"_menu(bytes32)","96d7f3f5":"lastTimeMinQuorumMet()","96d811b7":"TokenVesting(address)","96d8b050":"claimTokensToOwner(address)","96d8f4f3":"minimumDonation()","96d8fe3b":"_updateHistory(address,address)","96d99568":"MMMTokenCoin()","96d9a881":"manualDeleteEditionBids(uint256,address)","96da1fba":"sendETHToContributionWallet(uint256)","96da2848":"gasForCLI()","96dbab81":"stub()","96dbad1e":"sellCityForEther(uint16,uint256)","96dbb486":"updateFinishTime(uint256)","96dbbc5f":"Token_Description()","96dbe56e":"ImpCore(address)","96dc461f":"setBountyTokensCount(uint256)","96de0c20":"_makeWithdrawForPeriod(bytes32,uint256)","96de56d2":"getPlayerFlips(address,uint256)","96de6caa":"qtyValidators()","96de9c8c":"cnyBtcRate()","96dea936":"proposalData(uint256)","96df3540":"TLD_NODE()","96dfa78b":"price_per_eth()","96dfcbea":"checkState()","96dfcc21":"weAreClosed()","96e05fdb":"PaymentAccepted(address,bytes8,uint256)","96e0ef33":"send(address,address,address[],uint256[])","96e1a657":"timeBetweenEditions()","96e264ff":"ownerSetPayOutDivisor(uint256)","96e332f3":"mainSaleMaxTokens()","96e438a1":"reclaimDeposit(uint256)","96e4ee3d":"convert(uint256,uint256)","96e4f67d":"icoEtherReceivedMainSaleDay()","96e50a8c":"saveNonce(uint256)","96e583a9":"getLetter(uint256)","96e6e65f":"ETCN(uint256,string,string)","96e76fa7":"Unregistered(string,uint256)","96e83a40":"refund(uint256,address,address)","96e8cace":"dripMe()","96e8d14c":"newRecord(string,string,string)","96e9df8d":"deployNewContract()","96e9f6f2":"lastBlock_v12()","96ea7487":"Opacity()","96ea76b7":"OnWithdrawTo(address,address,uint256,uint64)","96ea8b9c":"referralPercentage()","96ea9f49":"FundTransfer(address,uint256,uint256,uint256,uint256)","96ebabba":"distributeSuccessfulCampaignFunds(uint256)","96ebfb89":"generalManager()","96ec1ca2":"tipUser(bytes32,bytes32,bool)","96ec6fec":"APP()","96ec7114":"COMMUNITY_SALE_START()","96ecf3c4":"subtractFrozenBalances(address,uint256)","96ed10a4":"issuePOIs()","96edb898":"callTokenFallback(address,address,uint256)","96ee03d6":"__concat(string[6])","96eecf95":"saleSuccessfullyFinished()","96ef7aa0":"cash_transfered(string)","96efbb9b":"getActiveItemAt(uint256)","96f099bc":"preSaleTokenRaised()","96f0aa8f":"findNextSecond(uint256,bytes)","96f1370d":"TotiMed()","96f17aa5":"potTarget()","96f2710d":"managerOn(address)","96f27b29":"getContract(bytes32,uint256)","96f36997":"CLIBUXCoin()","96f392f4":"elixir()","96f42876":"buyerAddressTransfer(address,address,address)","96f429ba":"stateIsFinishedReplay(uint256)","96f47800":"investInternal(address,uint128)","96f494d1":"printCourse0(uint256)","96f6706f":"cancelOfferBob(uint256)","96f68782":"right62(uint256)","96f76f11":"contractFinished()","96f7807a":"getDuel2(uint256)","96f93e65":"Expire(address,address)","96f9cffa":"shareBonus()","96fb2e62":"Party(string,address,string)","96fbab31":"getZombiesFullInfoByOwner(address)","96fc00c2":"setPresale(uint256,address,uint256[])","96fcbf65":"numOfSampleTypes()","96fcd214":"slaveServer()","96fd1df7":"isEndedTrack(uint256)","96fd550a":"betWithCredits(uint64)","96fe1338":"storageTime()","96fe5418":"contestEndTime()","96fe6e74":"external_oraclize_randomDS_setCommitment(bytes32,bytes32)","96fedaf7":"extraMinted()","96fef3f1":"submitTransactionToken(address,address,string,string,uint8[],bytes32[],bytes32[])","96ff0306":"retireWildHard(uint64,uint64,uint64,uint64,uint64,uint64)","96ff4483":"setTokenAsideAddresses(address,address,address)","96ff7631":"SetupYOU(string,string,uint256,uint256,uint256,address,address,uint256)","96ff7e97":"requestIdentity()","96ffa690":"countLocalRecursive(uint256)","96ffac0b":"setupRace(uint256,uint256,address)","97004255":"aliceClaimsPayment(bytes32,uint256,uint256,address,address,bytes)","9700d0f0":"stage_2_TokensSold()","970129be":"getCardInfo(uint256)","9702795d":"REFERRAL_SHARE_RATE()","97028899":"play(bytes1,bytes1)","97034ed0":"get_HoldersProfit(address,uint256)","970388b5":"setContractActive(bool)","9703ef35":"cancelBid(uint256)","9703fa2e":"airdropQty()","9704122c":"getFeeAmount(uint256)","97046afc":"burnProvider(address)","970574ac":"lnUpperBound32(uint256,uint256)","9705a592":"getUnprocessedQueryCount()","97062e8a":"ico3Bonus()","9707f708":"Totalsupply()","970875ce":"currentSnapshotId()","9708e250":"maxSellCap()","9709709a":"MomentumToken()","9709cdbc":"getExchangeGroupsKeyAt(uint256)","9709d040":"NewPayroll(address)","970a5fa8":"exchangeRateIdx(uint256)","970afd9b":"MAXIMUM_64_BIT_SIGNED_INTEGER_VALUE()","970db3df":"SPECIALIST_STAKE_TWO()","970e5904":"safeGetPartialAmountCeil(uint256,uint256,uint256)","97100be9":"setLiveTx()","97107d6d":"setProxy(address)","9710f014":"completeStatus(string)","971130b5":"MulaCoin()","9711715a":"snapshot()","9711e944":"Queue(uint256)","9711f20d":"isSanctuary()","971217b7":"values()","9712a57e":"purchasePotato(uint256)","9712a764":"takeBounty()","9712da8b":"getCompte_20()","971362c9":"partnerWithdraw()","9714378c":"extend(uint256)","97145273":"setHidden(address)","9714a27c":"miningOneFree()","9714f05c":"_minimumContribution()","9715a81f":"SurvivalRanchTestCoin()","9715d80e":"getCanShareProfitAccounts()","9715f05d":"OBSERVER(uint256,string,string)","97169426":"Owned1()","9717137a":"TLN_TOKEN_NAME()","97172664":"getIcoAddrCount(uint256)","97173a7a":"referalPayCount(address)","971751af":"lockAndDeliverTokens(address,uint256,bytes1)","9717ae9d":"DTCC_ILOW_5()","9717b2ae":"DividendsTransfered(address,uint256)","9717d76f":"getCandidatePosition(address,uint256)","9717df19":"fillFromQueue()","97187ac8":"coinSaleStarted()","9718b524":"newTreasury(address)","9719f290":"lockTeamTokens(address)","971a3593":"updateClosetime(uint256)","971a9091":"crystal()","971a9a29":"CbxeToken()","971b2b2e":"getFreelancerFeedbackOn(address,uint256)","971bd1b4":"estimateDistribution()","971c803f":"getMinimumStackCheck()","971ccc16":"addERC20Token(address)","971d2bd8":"getProposalByHash(bytes32)","971dbe0e":"getNbrOfPartyFor(address)","971e668f":"updateTokenToEthOrder(uint32,uint128,uint128)","971e80cb":"setWallet()","971ec3ce":"globecoin()","971f34a1":"SellPriceChanged(uint256)","971fe56b":"poolWeight()","971fff63":"setAdsStorageAddress(address)","972030bb":"mixGenesRabbits(uint256,uint256,uint256)","97203543":"getGuestCount()","972041e4":"getTokenTime(uint256)","97204d8e":"delegateProxyImplementation()","972072a2":"resolveChallenge(string)","9720dd5a":"kBit()","972161f7":"getFullState()","97217085":"maxBetDoubleDice()","9721dd4c":"GoldenChain()","972205d4":"Untethered(address,string,string,uint256,uint32,uint32,uint256,uint256,uint256)","97227325":"simulate_ico()","9722cdc6":"EarningsWithdrawal(uint256,address,uint256)","97235a1e":"receiveToken(address,uint256)","97246156":"HoQuBurner(address)","9724fc95":"getTotalProposalsCount()","9725b4a5":"BOXIcoin()","9725bd80":"preIcoEnded(uint256,string)","97267ae9":"startDividendDistribution()","972711cc":"KoreaShow(uint256,uint256,address,address)","97271615":"contract_newOwner()","9727e379":"addMeter(uint32,string,string)","97294e58":"register(address,string,address)","97296421":"joinTheHunt(string,string)","972973e7":"setOfferPrice(uint256)","97297467":"checkAndVerify(bytes)","972993e6":"b2bcToken()","97299d8a":"lendingDays()","9729d040":"_slashPower(address,uint256,bytes32)","9729ec26":"generateWarrior(uint256,uint256,uint256,uint256)","9729f9b9":"getBlockComission(uint256)","972ab95a":"bennylamToken()","972afc80":"ownerSetEmergencyStatus(bool)","972c169e":"datboiSupply()","972ca383":"MONTANATOKEN()","972d1ae2":"_getNextTokenId()","972e6151":"operationalReserveAddress()","972fa53f":"createTeam(string)","97304ced":"mintTokens(uint256)","973069f8":"transferRemaining(address,address,uint256)","97306c27":"getData3(uint256,uint256,uint256,uint256)","9730b305":"burnTokens(uint256,address)","9731a897":"famedStarMassToIds(uint256)","9733348a":"ProdToken()","9733dc79":"ManagerContract()","97346423":"HCOIN()","9734855d":"WhitelistAddressenable(address)","973516f2":"getH1Amount()","973549ea":"_setAddress(bytes32,address)","973628f6":"currentEra()","97365a0b":"safe(uint256,string,string)","97365df2":"sameOdd()","9736a590":"DistributedTokens(address,uint256)","9736aeb4":"OwnershipTransfered(address)","97374d89":"preIcoAllocation(uint256)","97379c32":"CBIX(string,string,uint256,uint8)","9737bc41":"ShineCoinToken(address,address,uint256,string,uint8,string,bool)","9738418c":"getVersions(bytes32)","973880e8":"getMinesInfo(uint256[])","973882e9":"returnPollStake(address,bytes32)","97388497":"getNumberOfRequests()","973885c0":"test_setMaxSize_decreaseSize()","9738968c":"canUpgrade()","9738b602":"getElementInfoView(uint256)","9738f92c":"transferLogicAuthority(address)","97391e2d":"PurchaseMade(address,bytes8,uint256)","9739203b":"view52()","9739951c":"tokenEmission(address,uint256)","9739db9d":"createOwnershipOffer(address)","973ad270":"removeArbitrator(address)","973b56e8":"MIN_FREEZE_DURATION()","973bc8cf":"getParticipantsChannel(address,address)","973cbc75":"testFailAppendTranch()","973d641e":"SplitPayment(address,address)","973dbfb7":"withdrawalValue()","973e315b":"setMigrateFromLegacyReputationToken(bool)","973e9b8b":"getAllowance()","973e9c5c":"Radiance()","973ea9d5":"team2Address()","973f6129":"adminArray(uint256)","973fcaef":"SIMCOIN()","973fe7ef":"secondWeekBonus()","97409192":"addRequest(uint256,string,string)","9740e4a2":"left87(uint256)","9741efe4":"currentBankroll()","974207fb":"logfolio(bytes32)","974238fd":"CreditMC()","97425a54":"ANMFutureVesting()","9742ca46":"setMiner(address)","9742d64a":"destroyBeneficiary(address)","974317dc":"ThreeDL()","9743ad98":"totalReservedAndBonusTokenAllocation()","9743c6c3":"joinMain()","9743dfc1":"jesterAutomaticCollectFee()","9743efe5":"kin()","974463d6":"ronerToken()","9744a1b1":"depositWithToken(bytes,uint256,uint256,uint256,uint256)","9745ac4d":"getResponseUint(int256,uint256,bytes32)","9745ad9c":"stageIT()","974626b4":"LotsaFucksToken()","97463b75":"getPOOL_edit_27()","974654c6":"finishPresale()","974654f4":"requiredGas()","9746f42b":"getBalanceTeam(address)","9747145b":"claimStorageForProxy(address,address,address)","974811fb":"tokensToEthereum_1(uint256,uint256)","9748334b":"PskERC20()","97487af8":"TOTAL_SUPPLY_ACES()","9748bf5b":"bucketValue(bytes32)","9748db00":"DragonKing(address,address,address,address)","9748dcdc":"punish(address,address,uint256)","97495cce":"rate_toTarget()","974a832d":"rejectCertificate(uint256,uint256)","974b2525":"removeBurningMan(address,uint256)","974bd64b":"PromissoryToken(bytes32,address,uint256)","974c86b5":"Buy()","974cf025":"lockDonationReceiver()","974e7dc9":"_getWeekTotalStake(uint256)","974ee3bb":"_updateLockUpAmountOf(address,address)","974ef924":"parseBool(string)","974fa121":"GiveAnAngelCS(uint256,address)","974fd2f3":"setLastBattleResult(uint64,uint16)","975057e7":"store()","97508f36":"pollNonce()","97514d90":"sellOrder(uint256)","97518f74":"_OmnesCoinToken()","975289fd":"getPriceVolume(uint256)","9752bcd3":"guaranteedBuyersLimit(address)","9752f163":"deployAgent()","975347b8":"removeAddressFromAccessControl(address,uint8)","97537bdf":"BotCoin()","9753a84e":"PCHAlN()","9754a4d9":"grantVestedTokens(address,uint256,uint64,uint64,uint64,bool,bool)","9754a7d8":"pauseSell()","97557f6a":"QTB(string,string,address)","9755a710":"hasWinner()","97566aa0":"getMintDigest(uint256,bytes32,bytes32)","97567579":"getTokenWithdrawalAllowance(address,address)","975739a5":"maxKudosToMember()","9757e8a3":"customerCount()","97584b3e":"_hasAvailability()","9758af1e":"doesEntryExist(bytes32)","9759512b":"LogRefund(uint256)","9759c160":"BuyCore(address,uint256,uint256)","975b123e":"get_firstbytes(bytes,address)","975bad75":"_createCountryId(uint256)","975be231":"emitPricesUpdated(uint256,uint256)","975c2308":"getHeir(uint256)","975c5cab":"getSanageLink(uint256)","975c95da":"ICO_PERCENTAGE_5()","975dfff9":"monsterIdToTradeable(uint256)","975e001a":"tokenBonusForForth()","975e463a":"addInvoice(address,uint256,uint256,uint256)","975e76b3":"transferAdvisorsToken(address,uint256)","97603560":"rescueTokens(uint256)","9760b450":"_Stand()","97614302":"playCount()","976160fa":"SetDesignatedRouterSRV(bytes32,uint256,bytes,bytes)","9761cd63":"reduceHatchCooldown(address,uint256)","97623b58":"removeContract(string)","97624631":"assertEq(bytes,bytes)","9762737a":"remove_branch(uint256,uint256,uint256)","9762e9ea":"icoStartedTime()","9762f802":"hardCapReached()","976371c9":"_isTokenOwner(address,uint256)","9764053b":"_price_tokn_ICO2()","9765b4d7":"autoSend()","9766178c":"tradeDealRequested()","97668720":"set_centralAccount(address)","97672729":"releaseLockedTokens(uint8)","97679646":"whitelistMinTok(address)","9767dae8":"userWithdrewWei(address,address)","9767fff7":"setImageOwner(address[16],uint256,address)","976898c7":"bid(string,string,string,string)","976934ac":"dCHF()","9769eacf":"setBuyOpen(bool)","9769f0b0":"sellToken()","976a0b82":"vettingTime()","976a77b6":"freeForCarrots(uint256)","976a8435":"units()","976b01c0":"setNotRetractable(bytes20)","976b59b5":"ElyxrShrimpFarmer(address)","976bd47d":"LOOMIA2()","976bdba4":"makeOrder(address,address,bytes32,uint256,uint256)","976c3d04":"calculateTokenPrice(uint256,uint256)","976d00f4":"auditSecret(bytes32)","976d16d5":"getTotalAccessories()","976d36d0":"totalSupply1()","976e0da9":"getNextPrice(uint256)","976e14d6":"salePriceWei()","976f37fd":"lowCompose(uint256,uint256)","976f6c92":"lastBlock_a19Hash_uint256()","976fcda7":"WithdrawlRemainingPAT()","97709cde":"ARK_VOTER_1_00(uint256,uint256,uint256,uint256,uint256,uint256)","97709ce7":"setRaffleAddress(address)","977174ff":"normalRoomMax()","9771ccc8":"removeERC20(uint256,address,uint256)","97722acf":"getCapOfToken()","9772c982":"scheduleCall(address,bytes4,bytes,uint256,uint256)","9773252a":"isInBonusList(address)","9773489a":"forceOffsetExecuteMaxFee()","97734b85":"BNB(uint256,string,uint8,string)","9773b22e":"_HachirokuToken()","9774c190":"ShieldCureToken()","977564ed":"Zylli()","977567a4":"ico(uint256,address,uint256)","977615a3":"startDatetime()","9776415f":"setConntractEnable(string,uint256)","9776aacf":"addToken(bytes32,address)","9777487d":"sponsorValue()","977785c5":"testInitalBalanceUsingDeployedContract()","97779e1b":"isStop()","9777a30e":"EYHToken()","9777aa49":"owner_endGetting()","97788180":"GetCitySnapshot()","9778a177":"ManualPurchase(address,address,uint256)","977919bf":"adjustFeeAmount(uint256)","97792f2f":"PembiCoinICO()","97799d47":"Tmc4(uint256,string,uint8,string)","9779dcd9":"sendInvestmentsToOwner()","9779e135":"CreateUpgradeCards(uint256,uint256,uint256,uint256,uint256,uint256)","977a5ec5":"hold(address,uint256)","977a8f1b":"logTokenTransfer(address,address,uint256)","977ab3c2":"mintarget()","977af81c":"changeMessage(bytes32,string,uint8,bytes32,bytes32)","977b055b":"maxPurchase()","977cdc7e":"completeDefaultOperators()","977d2c45":"totalWallets()","977d6276":"getOrderPriceInfo(address,address,uint256,uint256)","977d996d":"createEvent(uint256)","977e09e6":"addGameRecord(address,uint256,int256,uint256,uint256,address,uint256,uint256)","977ed151":"fetchCancelledOrdersForPayer()","977eda79":"txLog(uint256)","977f1213":"FucksToken()","977f3b05":"calculateRegionSalePixelPrice(uint256)","977f7c7e":"bet_on_team_2()","977f9e24":"offlineDonate(uint256,uint256)","977ff98f":"currentSaleAddress()","97810850":"setPlaySeed(address)","9781a37e":"setCooldown(address,uint256)","9781c3ca":"buyTokensSigned(address,bytes)","9782c9ef":"unfreezeTrading()","9782e1ec":"ProxyMock()","9783585d":"setState2WithStop(uint256,uint256)","9783bef4":"EighthContinentSocialMarketplaceToken(uint256,string,uint8,string)","978414bd":"transferZTXOwnership(address,address)","9784696c":"PauseOff(uint256)","97848574":"NevadaBlackBook(address)","9784af62":"createTokenContract(string,string,uint8,uint256)","9784f585":"crowdsaleHardEndTime()","97871e56":"EtherPush()","9787a6b3":"setUint8(int8,uint8,uint8)","97883d1f":"tokenPriceMultiplies(uint256)","9788a8e7":"HOU(uint256,string,uint8,string)","9788c342":"HardCapReached()","9788d5ff":"_updatePrices(address[],uint256[])","9789103f":"fallbackProposal(address)","9789f9da":"crowdsaleFinishTime()","978ab53b":"withdrawFundInsurance()","978afdc8":"getBountyAmount(address,address)","978bbdb9":"feeRate()","978bc247":"_checkSetSkill(uint256,address,uint8,uint256,uint256,uint256)","978c5b15":"LOCKED_2Y_DATE()","978ca331":"mintSub(address,uint256)","978cb570":"firstTimer()","978d5c0e":"ASCCoin()","978d602a":"withdrawETH(address,address)","978d6cff":"ICO_TOKENCAP()","978dabbe":"test_fourValidEqBytes32()","978f68b5":"cancelListing(bytes5)","978f8934":"createPromoKydy(uint256,address)","9790268b":"setRewardBlockThreshold(uint256)","97905a88":"recoveryKey()","97907827":"sharesHeld()","97911fd7":"MyGameToken()","97912c2f":"startPreICOTime()","979260bd":"reserve2Address()","97936258":"GetBaseN(uint256,uint256,uint256,uint256)","9793714f":"approveSettingDeprecation(uint256,bool)","9793ebf4":"getBooleanMapValue(string,address,address)","97950740":"roomForBirth()","9795a644":"BITWhaleBalance()","9795aabf":"setNewTokenOwner(address)","97971c69":"TwentyOneMillionToken(address,uint256)","97976d15":"raisedUsing(uint256)","9797f51f":"ELTToken(address,string,string,uint256,uint256,uint256,address)","9798532f":"_priceToTax(uint256)","9798a106":"isNullAddress(address)","9798dfc2":"ReinvestAmount()","9798e639":"distributeLCWP(address[],uint256)","97990635":"SmartInvestmentFundToken(address,address)","97992a04":"villainIndexToOwner(uint256)","97994b96":"changeOpenNumber(uint256)","97997ebb":"stakeWithdrawDisallowPeriod()","979a5e1a":"set_presale_arbits_sold(address,uint256)","979af14d":"checkAccount(string)","979b49de":"checkBonusTokenAmount(address)","979b6f6f":"RoundInfo()","979bc638":"withdrawBidForPunk(uint256)","979bfba7":"PUMPHODL()","979c2441":"times7()","979c7a38":"MultiWhitelist(address)","979ca729":"IcoContract(address,address,uint256,uint256,uint256)","979cf824":"tokenSaleEnabled()","979d6dc7":"HUT34_WALLET()","979e0f22":"AuctionResumed()","979e199d":"setProceedsAccount(address)","979e8852":"existsEscuela(uint256)","979f1976":"tryInsertSequenceId(uint256)","97a09338":"freeMoney()","97a0a3ec":"SpeedCashTokenContract()","97a1c2cd":"preSaleFirstDay()","97a1d3f7":"_emitHolderOperationalChanged(bytes32,bool)","97a28819":"resetDividends()","97a315ff":"CHF_Omnidollar()","97a33431":"toContractDie(bytes32,bytes32,uint256)","97a42022":"scanOutputs(bytes,uint256,uint256)","97a432ff":"addressesToUsernames(address)","97a53219":"setSwapToken(address,uint256,uint256,uint256,uint256,bool)","97a55722":"get_win_coefs()","97a6278e":"removeAgent(address)","97a629aa":"shareholdersBalance()","97a6ef4a":"AutoCoinToken()","97a7293d":"getCCH_edit_5()","97a75fe8":"seriesASupply()","97a7804e":"FrozenToken()","97a7cfb4":"takeTheTorch_(uint256,address,address)","97a8c6ec":"emitEvent(string,address,address,uint256,uint256,string,string)","97a95086":"getBAU(bytes32,address)","97a97005":"transferAllArgsYesAllowance(address,address,uint256,address)","97a989c2":"__getbalance()","97a993aa":"buyers(address)","97aa28b4":"publicUnlock(address,uint256)","97aaa73c":"timeBasedBonus(uint256)","97aab362":"setReg(address)","97aae114":"setDeprecatedManual(uint256,address,bool)","97ab4786":"reserved(uint8)","97ab5baa":"withdraw_if_failed()","97ab9e7a":"contestStartTime()","97aba7f9":"recoverSigner(bytes32,bytes)","97ac37de":"_purchase(address,uint16,address)","97ac3b51":"CHXToken()","97ac3cd9":"noMoreNextRoundSetting(bool)","97ac4a25":"isRoundActive(uint256)","97acb3bb":"addAction(address,bytes4,bytes32[])","97acb94d":"withdrawalFrom(address,address,uint256)","97ad1cbf":"alterDividendCooldown(uint256)","97ae4491":"serviceFeeWithdraw()","97aeb405":"IFIN()","97aeb7ad":"setTeamByAddress(uint8,address)","97aeecd0":"AtraToken()","97af34db":"listActiveBets()","97af77b8":"getVisaAmountPaid(address,uint256,uint256)","97af90ae":"_userRefund(address,address)","97afb40c":"request_withdrawal(address,uint256)","97b0484e":"TOKEN_ICO2_LIMIT()","97b081ef":"setOrderDealTimeInterval(uint256)","97b09aa6":"tokenSaleAgreement()","97b0ad7d":"Fizzy()","97b10976":"removeAmountForAddress(uint256,address,address)","97b150ca":"tokenAmountOf(address)","97b1b2b7":"getFundStatsMap()","97b1ff1d":"getNumberOfBeats()","97b27c46":"decision(bytes32,string,address[],uint256[])","97b2f556":"numPlayers()","97b3116e":"setPrePaidFee(uint256)","97b34e1f":"readBools(bytes32[])","97b3ab70":"BetComplete(bool,uint256,uint256,uint256,address,uint256,bool)","97b3b441":"isAvailable(uint40)","97b4ddac":"currentGenesisAddresses()","97b51442":"setMinimumWait(uint256)","97b61c68":"giveOwnership(uint256,address)","97b68b60":"finishFreeGetToken()","97b6cf42":"icoParametersSet()","97b73c5c":"setMockUint256(int256,bytes4,uint256)","97b740e2":"addAuction(uint40,uint40,uint128)","97b817c9":"beginGame(address,uint64)","97b9d025":"past_present_future()","97ba42b3":"getsometoken(address,uint256)","97ba89c9":"setBetUnit(uint256)","97bb0de0":"mintLockedTokens(uint256)","97bb2a63":"newvow(uint256,address)","97bd820a":"divRound(uint256,uint256)","97bdc7c8":"changeWhitelist(bool)","97bdc9cc":"setBytes(address,string)","97bec0ec":"unlockCZR(address,uint256)","97bfd8cb":"_setClassMechValue19(uint256)","97bff97f":"broadcastTransfer(address,address,uint256)","97c0262a":"commissionWallet()","97c06deb":"debit(address[],uint256[])","97c08da6":"assignBurner(address)","97c112d5":"ItemInfo(uint256)","97c25f95":"coupon(address,uint256)","97c2a9b7":"withdrawFoxt(address,uint256)","97c3ccd8":"ban(address)","97c414df":"registerAccount(address)","97c5ed1e":"showMeTheMoney(address,uint256)","97c6006e":"SetFreeQDA(uint256)","97c6e24d":"ARMOR()","97c8f311":"distributeTokens(address[],uint16[])","97c9085f":"fromBytes96(bytes32,bytes32,bytes32,uint8)","97c911d5":"InitMaster(address)","97c93398":"test_insert_atPosition()","97cb2c17":"getSpaceshipProductPriceByModel(uint16)","97cbdfc9":"transferAbnormalERC20Tokens(address,address,uint256)","97cc3070":"setOrderFill(bytes32,uint256)","97ccd07b":"medium()","97cd1829":"copyEntireGlofile(address)","97cda349":"getLargeBonus()","97cdcbfd":"trainEquipment(uint256,uint256,uint256)","97ce3a4b":"getUnitsInProduction(address,uint256,uint256)","97ce8c43":"setFashionSuitCount(uint16,uint256)","97ceb310":"setHardCapInEther(uint256)","97d02e00":"DaoChallenge(address)","97d0b02c":"setUserManager(address)","97d11588":"createStandardDerivative()","97d159e7":"setMinTransfer(uint256)","97d32a12":"afterCrowdsaleAddress()","97d33c33":"burnNotDistrTokens(uint256)","97d351b3":"_doTradeForEth(address,uint256,address)","97d3624c":"TransferableMeetupToken(string,string)","97d3c683":"priceStep8()","97d425cb":"canBeTransfered(address,uint256)","97d47a60":"registerAccountant(bytes,address)","97d4cfb9":"initialTokenSupply(address,uint256)","97d4f342":"playerOneCommit(bytes32)","97d551a1":"TEC_TOKENS_NUMS()","97d5c6a1":"setEndTime(uint256,uint64)","97d5f823":"sendPOSTokens()","97d61c46":"getRedeemValue(uint256)","97d63f93":"initSupply()","97d68c77":"resolveSupply(address)","97d6ce76":"companyTokensInitial()","97d6daba":"expropriate(uint256)","97d74abd":"dataSourceCallbackTeamId(uint256,uint8)","97d7f2ee":"FundToken()","97d814c3":"withdrawCeo(address)","97d88cd2":"subAllowance(address,address,uint256)","97d8a7e9":"getFreelancerHourlyRate(address,address)","97daa043":"register(bytes,address,address,uint256,bytes)","97db0a7b":"soccerGo()","97db7edb":"stopEmergency()","97db9a95":"changeAuthority(address,address)","97dbfc5a":"ICOEnabled()","97dc4a13":"airdrop(uint256)","97dc4c6f":"earlyBirdMaxPerPerson()","97dc97cb":"authorizedCaller()","97dd9892":"getCurrentRoundTeamCos()","97ddeb77":"LimitReached(address,uint256)","97dedb06":"strToBytes32(string)","97df212b":"getPersonaAttributes(address)","97df5028":"winProbability(address)","97df573e":"storageAddr()","97df8a50":"changeSuperContract(address)","97e10a79":"transferERC20(address,uint256,address)","97e12b0d":"lastRoundEndTimestamp()","97e1754c":"previousEntries(uint256)","97e18af3":"crowdsaleLock()","97e1d68d":"PRESALE_BASE_PRICE_IN_WEI()","97e1e9b5":"ILFManagerCandidateKeyHash()","97e1f48b":"userReinvest()","97e30fc4":"setPendingValue(uint256,address)","97e42023":"setRebuyThreshold(uint256)","97e484d2":"ElementeumTokenProxy(uint256,address[],address[])","97e4c28b":"transferPrefix(string,address)","97e4fdea":"pause_2()","97e4fea7":"exists(bytes8)","97e5d18a":"thirdLoos()","97e645f3":"isCallbackDone(address)","97e6c7f7":"getWeeklyDividends()","97e6dada":"_own(uint8)","97e851f6":"updateOptionalCommission(uint256,uint256,address)","97e8b490":"edit(uint256,address,uint256,string,string,string,string,uint256,address,uint256,string,string,string,string)","97e8e520":"stakeToMany(uint256[],uint256[])","97e92794":"digitalSignature()","97e950f7":"setMaxInvocations(uint256)","97e9a0bf":"contractPrice()","97e9beef":"withdrawUser(uint256,address)","97ea403d":"getCityResources(uint256)","97ea6e15":"bytesToBytes7(bytes1[7])","97eb0eab":"addAirdrop(address,uint256,bool)","97eb147d":"rlc_bounty()","97eb1800":"investorsStockInfo(address)","97ebe0d6":"approveTokenCollection(address,address,uint256)","97ec23cb":"getCreationTime(uint256)","97ec642c":"MAX_WITHDRAWAL()","97ec72b8":"STLHToken(string,string,uint8,uint256)","97ecd379":"nPlatCurTotalEth()","97ecfaab":"delWhitelist(address)","97ee041b":"incrementBasketsBurned(uint256,address)","97ee0a05":"SendPreReserved3()","97eea08b":"Mineral()","97eede11":"FACTOR_10()","97ef9779":"TransferBase(uint256,string,string)","97efff39":"amountToWithdrawOnDate(uint256)","97f1943c":"ROG()","97f22ea9":"addToPresaleWhitelist(address)","97f28419":"getAdminAddressIndex(address)","97f2b4b0":"isBetActive(bytes32)","97f2f5c3":"maxTokensForSale()","97f3016b":"finishLock()","97f3bb0c":"removeLocking(bool)","97f3c21e":"isUpgradeFinished()","97f3de37":"SetDataServerAddress(address)","97f46527":"getNextVestingQuantity(address)","97f58e91":"isLiquidating()","97f59897":"_nextOwner()","97f606eb":"ShowUnrelease(address,uint256)","97f735d5":"isBanned(address)","97f7b4f7":"getBid(address,uint256,uint256)","97f8fee1":"CORPAddress()","97f990f2":"KNOWLEDGE_TO_GET_1FRANKLIN()","97fa346d":"sellTank(uint32,uint256,uint256,uint256)","97fb070b":"registryRequestDocumentation()","97fb2a14":"JTU()","97fb2cea":"getCustomerAtIndex(uint256)","97fbbfd1":"CoinstocksToken(uint256,string,string)","97fc93ab":"cashBack(address)","97fcb54e":"transfer_eth(address,uint256)","97fce1bb":"setGameLogicContract(address)","97fcedba":"setTotalInvestedToken(address,uint256)","97fdf5f2":"FOUNDERS_TOKENS_VESTED_1()","97fe5ea3":"addAdvocatedTAOLogos(address,uint256)","97fe728a":"useName(string)","97fe9129":"setCCH_edit_27(string)","97feb926":"depositERC20(address,uint256)","97fed5f2":"TokenXGroup()","97ff335b":"AddNewCourse(string,string,string,string)","97ff5be4":"getData_12()","97ff6d10":"cancelPlatformWithdrawal()","98004a2a":"processContributions(address,uint256)","980054be":"icoIsFinished()","9800fc16":"removeAllowedContract(address)","98019a41":"adjustAddressWealthOnSale(uint256,address,address,uint256)","9801ca60":"getWeeklyTokensForHoldersAmount()","9801cb8e":"ProofOfExistence()","98024a8b":"getPartialAmount(uint256,uint256,uint256)","98024f18":"testThrowsTransferDisableNotEnabled()","9802dd1a":"Dpc()","98036e7a":"ADVISORS_PERCENTAGE()","98041ea3":"addMember(address,uint256)","980481e0":"isABatchOpen()","98057510":"addLockedTokeB(address,uint8,uint256)","980591f4":"pause(bool,string,address,uint256)","9805d7d2":"landsOf(address)","98063de4":"LogPollVoted(bytes32,address,uint256)","98066221":"FlowchainToken()","980934ec":"create(address,string,bytes32,uint256)","9809a38b":"supplyPerColor()","980b05e0":"_createCollectible(bytes32,uint256,uint256)","980b5335":"getAvailableAmountWithdrawal(address,bytes32)","980c2f21":"releaseForeignToken(address,uint256)","980cf053":"stage4Bounty()","980d75ab":"Readcoin()","980dc482":"addOrder(address,uint256,uint256,uint256)","980e6e08":"timeLeftToCook()","980e8c81":"FutureBlockCall(address,uint256,uint8,address,bytes,uint256,uint256,uint256)","980ee29f":"MakeDai(address,address,uint256,uint256)","980f62b1":"kickoff()","980f8e5e":"createPaper(string,bytes32,uint256,uint256[],address,address[])","980fb0aa":"abortByBroker()","980ff6c6":"executeProposal(bytes32)","981012f2":"AddressChecker()","9810e089":"return_owner()","98110106":"_ownerTransfer(address,address,address,uint256)","981101f5":"VERToken()","981111ef":"factorial()","9811c7c1":"target(uint256)","98123528":"numThings()","98129013":"left47(uint256)","981489b8":"setWidthrawFor(string,uint256,uint256)","9814d0ee":"isProposalEnded(bytes32)","981566ce":"LotteryCore(address)","9816006c":"DeWeiSecurityServiceToken()","98163597":"getTotalVolumeEth(address)","9816af58":"getUserPools(address)","98179c41":"burnBalance(address)","98182950":"TARGET_TOKENS_ADDRESS()","98191a20":"inPreSale3Period()","981a1327":"tokenToExchangeTransferOutput(uint256,uint256,uint256,uint256,address,address)","981a60f5":"extractNameFromData(bytes)","981ae401":"ACTION_TAX()","981b24d0":"totalSupplyAt(uint256)","981b405b":"willChangeCost()","981b69b7":"soldForFifth()","981c6946":"holderAdded(uint256,address)","981c80b3":"Maia(address)","981c9e07":"PBSU()","981cc7ae":"GetRichQuick()","981dd797":"process_contribution(address)","98203e6b":"setDeprecated()","982078b8":"requestTokensFromCrowdsale()","98221166":"changeTypeHash(bytes32)","982270e7":"setPOOL_edit_6(string)","98229465":"_isAuthorizedOrOwner(address)","982296a8":"emitEvent(string)","9822e501":"exchangeOwner(uint256,uint256)","98234a6c":"max_crowd_vitas()","982371b4":"cancelOrder(address,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","9824425a":"takeOrder(uint256,uint256,uint256,uint256)","982475a9":"approveKyc(address[])","982495c7":"attend(address[])","9824cec8":"CryptoTicketsICO(address,address,address,address,address,address,address,address,address,address)","9824e7f7":"userWalletTransferEther(address,address,uint256)","98251353":"grantedWallets(address,address)","98257d84":"changeDefaultTimeLock(uint256)","982657f3":"startGame(uint256,uint256,uint256,uint256)","98270d24":"atxToken()","982713e1":"ComplexExchanger(address,uint256,uint256,address[],uint256,address)","98278bc8":"DefaultSweeper(address)","9827a996":"terminateProject(bytes32)","98290c53":"stakeBelaSplit(uint256,address)","98296c54":"assertEq(uint256,uint256)","982a2376":"settingExist(uint256)","982a83eb":"createCrowdsale(uint256,address,string,string,uint256,uint256,uint256)","982a96e3":"bonusRemaining()","982b5dd2":"processVestingRules(address,address)","982b6689":"transferMultiple(uint256,address[])","982bb5d8":"setDepositsSigned(bytes32,bool)","982c0455":"getSpecifiedComment(address,uint256)","982e5721":"getRateNow()","982f4a21":"INFOCORP_DONATION()","983032c2":"newShare()","983086df":"HMTCrowdsale(address,uint256,uint256,uint256,address,address)","9830a8fd":"getCustomerTxRegistry(address)","9830aa07":"UBlockChain(address)","98313b10":"splitTokensAfterDistribution(uint256)","98315249":"getUsersMicroModulesIds()","9831ca4d":"joinMiniGame()","983234b6":"setAmounts(uint256,uint256)","9832ee65":"resultsWeightedByTokens()","98337afb":"largeCount()","983485e1":"buyEthereumToken()","98358f82":"cap_in_wei()","9835efaf":"setAmountToDistribute(uint256)","98366d1c":"isMint(int256,address)","98390730":"takeAllEther(address)","98391c94":"muteMe(bool)","9839eafd":"getTicketNumbers(uint256)","983a7f47":"setDNA(uint256,uint256)","983a8c8a":"_setRoles(address,uint8[])","983a95b2":"trackClick(address,address,address,address)","983b2d56":"addMinter(address)","983b94fb":"finalizeAuction(bytes32)","983bc49d":"currentBalance(address,address)","983c0a01":"closeCrowdsale()","983c4647":"TunTokenERC20()","983c7630":"setPermissionByAddress(uint8,address,bool)","983c8449":"VzanToken(uint256,string,string)","983ce499":"_set2()","983df7cd":"isOperatorAuthorizedBy(address,address)","983e1318":"Hack()","983ef725":"getDifficulty(uint256)","983f724b":"getCassetteType_()","9840a504":"NFCToken()","9840a6cd":"getSubscriptionValue(bytes32)","9840a8f8":"minAllowedBetInTokens()","98413ff1":"extensionByIndex(uint256)","98416339":"KRYPTONIUM()","98419ec5":"shouldThrowOnAttemptToTransferWhenNotOwner()","9841a2d8":"startSale1Phase()","9842692b":"_contractFallbackERC223(address,address,uint256)","984274af":"preTgeCap()","9842a37c":"__callback(uint256,bytes32)","9842ec30":"drawItemLottery(address,uint256)","9843e648":"setItemsEC(address,address)","9843eae3":"airdropActive()","984413b8":"_eraseNode(bytes32)","9844347b":"createCertificate(bytes,bytes,uint256,bytes)","98445e6f":"getCurrencyPayment(address,uint256)","9844613e":"ViewCoin()","984474fb":"price_token()","9844d5a7":"Martcoin(uint256,string,string)","984572d0":"privatePreICOBonusPercent()","9845b448":"PHASE5_START_TIME()","98475e30":"BTCETH(uint256)","9847d267":"GoodLuckCoin()","984809bf":"setPublicOfferingLimit(uint256,uint256)","984877b0":"GoalHitWithdrawl()","9848fef8":"tokensReleasedToEcosystem()","984a27be":"m_SMRMinter()","984a470a":"forwardedOutcome()","984a74f7":"TazitToken()","984ac378":"lotteryTitle()","984bc8c5":"placeTicket()","984c0450":"withdraw(bool,uint256)","984c14ac":"setupVolumeMultipliers(uint256[],uint256[],uint256[])","984ce0fd":"transfertoacc(string,uint256)","984d11fc":"validSupply()","984d4a93":"setAdminsAddress(address)","984ddfe8":"DevTokensHolderMock(address,address,address)","984e1ff4":"mock_setShouldSucceedTransfers(bool)","984e2829":"_updateState(address,int128,uint128,uint256)","984e5a0b":"FunKoin()","984ec03e":"_storeStakes(uint256,address,uint256,uint256,uint256,uint256,uint256)","984fba49":"removeInvestorFromWhiteList(address)","9850d32b":"maintainer()","98512d72":"round1TokensRemaning()","9851553b":"EthereumTravelToken(address,uint256,string,string)","9851663f":"_computeCurrentPrice(uint256,uint256,uint256,uint32)","98519340":"setParameters(uint32,uint32,uint32,uint32,uint32,uint32)","9851b2bd":"AIN()","9851fd9a":"eventStatus()","9852099c":"depositId()","9852595c":"released(address)","9853b234":"createPhoenix(uint256,uint256,uint256)","98544710":"setKeyHash(bytes32)","98547a45":"donacionCruzRoja()","985540b9":"remove(int8,int8)","98575188":"removeUser(address)","9857650c":"claimIFactor(bytes32,uint256)","9858cf19":"FREE_SUPPLY()","9859387b":"createAccount(address)","98593b7a":"SenseProtocol()","98596560":"get_activity_by_id(uint256,uint256)","98596726":"note(uint224)","98597629":"max_value()","98598905":"subVirusDef(address,uint256)","985989d2":"ROLE_UNDER_MINTER()","9859adf0":"_payByEth(uint256)","985a882c":"MINEX()","985b71f1":"calcBindedBlindHash256(string,address)","985bdd43":"isExchangeAlive()","985c7564":"getNextTournamentData()","985d43f1":"TOTAL_APC_SUPPLY()","985d5702":"ExShellStock()","985dea23":"getETH(uint256,address)","985df3a7":"setHeroAssetAddress(address)","985e2cdf":"updateExchange(address,address,bool,bytes4[])","985e4634":"CreateLPT(address,uint256)","985e4cd0":"sumBalanceOf(address)","985f26f6":"AddOwners(address[])","985fc7ea":"destructionAddress()","98603cca":"disableBurning()","98608111":"getStorageNameHash()","9860d0a5":"setTransferFee(uint32,uint32)","98636f32":"isException(address)","98646d68":"setNumDesignatedReportNoShows(uint256)","98650275":"renounceMinter()","98668b24":"tokensVotedForDisable()","98672215":"getTearAward(address,uint256,uint256)","98683105":"CCH_EDIT_1()","98686304":"Elance()","986876e6":"ChannelCreated(address,address,uint192)","98688a95":"Ai()","9869aca0":"setSchedule(uint256,uint256)","9869b736":"ONE_MILLION()","9869f1b7":"migrateTokens(address,address)","986b3a9a":"getCanvSize()","986b5676":"loveID()","986bb99a":"setPOOL_edit_30(string)","986bf5e8":"addAudit(bytes32,uint256,bytes32,uint8,bytes32,bytes32)","986c1938":"setRegistrarAuth(address)","986c7cc7":"BitArbToken()","986cc311":"executeProposal(uint256,uint256,uint256)","986ccc7f":"setHelper(address)","986d08a8":"OSECOIN()","986dcd4d":"setCycleLimit(uint256)","986e791a":"getString(bytes32)","986e7ed3":"AssignGGCOwner(address)","986ec464":"tokensLeftDrain(uint256)","986ee316":"VoteMemberCandidate(uint256)","986f3c9b":"addComment(address,address,bytes32,bytes32,bytes32)","986f737b":"onrs(uint256)","98702402":"refPercentage(address)","9870d7fe":"addOperator(address)","9871cb8f":"Moneto(address)","9871e4f2":"makeSubscriptionId(address,uint256)","9871e510":"hashExists(string)","9871ee02":"PCT()","98729c37":"_changeUpPrice(uint256)","9872a20a":"registerUInt(address,uint256)","98738f97":"preIcoBonuses(uint256)","9874a3d0":"WAIT_BLOCKS()","9874cdf4":"performRefund(bytes32,bytes32)","9874f5d7":"addString(string)","9875958c":"PlaceRocketForSale(uint32,uint80)","98764f22":"setPrice(uint32,uint64)","9876962a":"setstart()","9876ee61":"coinsAddresses(uint256)","98772e80":"disrupt()","987757dd":"settle(bytes32)","98779240":"transfersAllowDate()","9877bdff":"Alice()","9878cc51":"MELON_ASSET()","98791010":"deleteHpbNode(address)","987b7967":"BLOCKMALLToken()","987b904b":"BOUNTY_LIMIT()","987bc844":"HolikopterTokenToken()","987c6b9d":"swap(address,string,string,uint256,uint256,uint8,bytes32,bytes32,uint256)","987c9efd":"PayIreward()","987cb9b0":"updatePublicSale(uint256)","987cec61":"converted(uint256)","987d9768":"ILF(address)","987e565d":"buyKim(uint256)","987ea899":"addAssetManager(address)","987eae8f":"totalPets()","987f3bdb":"_playGame(uint256,uint256,uint256,bytes32)","987f710a":"TIME_TO_COOK()","987faf18":"prevJackpotsLength()","9880472f":"multiSigOutputAddress()","98804938":"deposit_eth(uint8,uint256)","98806bf0":"convertTokens(address)","98827d5e":"createCoins()","9882e15e":"withdrawOverdue(address,address)","9883521e":"presaleProcessed()","9883548a":"fint32(int32)","9883b9f4":"addAmendment(string)","98842c3b":"ipfsGet(uint256)","988483d4":"convertMsgValueToBytes20()","98864aaf":"getPropertyFlag(uint16)","98866c1a":"personUpdateDOD(uint256,int256)","98866ead":"_gensGenerate()","9886de1f":"multiTransfer(uint256,address[])","98876609":"create(bytes32,address,bytes32[])","98880043":"addGame(string,string,uint256,uint256)","9888103f":"buyTokensInternal(address)","988a18f6":"claimTokens(address[],address)","988a9fb5":"getTokenIdOfAddressAndIndex(address,uint256)","988b590f":"withdrawBSAFE(address,uint256)","988ba8e8":"finishPreSaleRound()","988bfcfa":"_buyToken(address,uint256)","988bfd47":"ProxyCreationAndExecute(address)","988da80f":"getUserName(uint256)","9890220b":"drain()","9890d6bc":"GetDisputesAtTheMoment()","9890eabe":"distributeDividendsOnTransferFrom(address,address,uint256)","9890f48a":"LocalStarRoster()","9891d61c":"getEnabledTokensLength()","9892003a":"TexasHoldem(string,uint8,uint8)","9892977b":"_attributeSale(address,uint256)","98934c0a":"payEther(address[],address,uint256[])","9893f27e":"allowancePresetTransfer(address)","9894221a":"SendCashForHardwareReturn()","98943c88":"getAllWeaponData(uint256)","9894ba7c":"transferOut(address)","98951b56":"approveProposal(uint256)","98951bfc":"foundersAmountLeft()","9895dd78":"setRegularTransTime(uint32[])","98968f15":"purchase(address,uint256,uint256)","98969906":"PassportToken()","9896b6cb":"testToUint16()","98973f2b":"setRestrictedAddress(address)","9897e8a5":"scalarEvents(bytes32)","98981756":"teamExists(uint256)","98983cc5":"isCrowdsalePaused()","9898e18c":"tokenSender()","9899276b":"getOwnedTokensLength(address)","9899722d":"newRateTime()","9899a2c5":"aliceClaimsDeposit(bytes32,uint256,bytes32,address,address,bytes20)","989a55fa":"_increaseApprovalAllArgs(address,uint256,address)","989b595f":"shuffleSeed(uint256)","989ceab1":"WhitelistAddressAdded(address,address)","989ced26":"updateTokenContract(address)","989db511":"Input()","989ddfce":"AdminDeleted(address)","989e4a8c":"_processPurchase(address,uint256,address)","98a05bb1":"deletePermission(address)","98a05cfb":"arbitroAprovaPagamento(bool)","98a0871d":"buyXaddr(address,uint256)","98a0bf6e":"ForeverChain()","98a0e1c8":"computeKnockoutPoints(uint8,uint8,uint8,uint8,uint8,uint8,bool)","98a10993":"finalizeWhenForked()","98a1803c":"ICONotCompleted()","98a1b397":"ROLE_OPERATOR()","98a1e1ba":"ownerSetLimits(uint256,uint256)","98a26497":"payCeo()","98a29a58":"testControlDisownNotTransferable()","98a2f59f":"ToLend()","98a30f76":"totalTokensPreICO()","98a322ae":"ownerComission()","98a33bfe":"addGlobalConstraint(int256,address,int256,bytes32,address)","98a34fef":"withdrawBeneficiary()","98a36ebf":"setTradeEventEnabled(bool)","98a42ec4":"verificationAddressNumberMap(address)","98a595a5":"requiresInitialization()","98a6a6c0":"isTokenSaleActive()","98a73afa":"getAwards(uint256)","98a7cafd":"setData_27(string)","98a87f7d":"CPCToken()","98a892c9":"getBylawsCashBackVoteRejectedDuration()","98a9ae44":"remaindersSet()","98a9bfd4":"is_max_goal_reached()","98ab1c72":"setBackgroundImage(uint256,bytes)","98aca922":"getReceiver()","98acd7a6":"getBaseToken()","98ad004c":"GetCollectionInfo()","98ad2f12":"getid(address)","98af629b":"winnerDecidedGas()","98b00ee0":"getFinalBytes()","98b01fe3":"totalBonusTokensIssued()","98b04c16":"SportistToken()","98b0787e":"playerTwoCommit(bytes32)","98b1e06a":"deposit(bytes)","98b23a29":"TimeShareEstate()","98b35e73":"saveReading(string,string)","98b3dfd6":"NamCoin(address)","98b41763":"publicGetAdvertisement(uint256)","98b547e0":"transfer_ownership(bytes32,address)","98b7db75":"PayForFlag(uint256)","98b90fe1":"closeOption(address[3],uint256[3],uint256[2],bool)","98b9a2dc":"changeWallet(address)","98b9d151":"InsuranceHolder(address,address)","98ba2453":"canSynthesizeWith(uint256,uint256)","98ba676d":"getEntry(uint256,uint256)","98bbc47e":"addPerson(uint256,string,string,string)","98bca41a":"removeSeenAddress(address)","98bcfbb8":"minimumTokensBeforeSale()","98bd359c":"deposit(address,uint128,string,uint32)","98bd5663":"confirmTime()","98bdf6f5":"tokenIdCounter()","98be22f7":"forfeitGame(uint256)","98be7c62":"minterFeePercent()","98be7df7":"releaseEthers()","98bf043d":"clearUnusedDeposit(uint256,uint256)","98bffb2a":"manualRecovery(address)","98c07938":"votersCount()","98c086d8":"_amountReq()","98c0bb94":"returnante(address)","98c16888":"SToekn()","98c20c00":"addToAllocation(uint256)","98c23836":"schellingDB()","98c31b1d":"addEvent(uint256,uint256,uint8,string,string)","98c39cc2":"AnubisToken()","98c5166c":"inResources(address,bytes4)","98c547b8":"setContentExtraData(bytes32,string)","98c562b3":"contributionsBySender()","98c66b7f":"_startTokenTransfer(uint256)","98c69648":"DEFAULT_NAME()","98c6a46f":"setPayoutDistributionId()","98c6e760":"migrateTo()","98c7458e":"getEventsByIds(uint256[])","98c83a16":"PRIVATE_SALE()","98c8bde6":"GICTBalance()","98c9cdf4":"getMinimumCallGas()","98c9faac":"cancelActiveAuction(uint40)","98ca667f":"FOUNDERS_SUPPLY()","98cb12dc":"isRandomPlayer()","98cb2342":"getNumEvenSplits()","98cba526":"TeamAndAdvisorsAllocation(address)","98cbb277":"Admined()","98cbefbe":"init(string,string,uint8,address)","98cc223f":"BiboToken()","98cc2c53":"VerifiedKYC(address)","98cc6754":"dumpBalance(address)","98cdf0ca":"updateConfig(uint16)","98ce476a":"EPTCrowdfund(address,address,uint256)","98cef4bd":"earlyBirds()","98cf6dd3":"deleteInvestorTokens(address,uint256)","98cf6f22":"queryN(string,bytes)","98cfa44e":"setFSTPrice(uint256,uint256)","98d0573e":"_getActiveMessageId()","98d07356":"getDepositValue()","98d0a6c7":"setBcouponAllocationFactor(uint256)","98d0b85f":"isNonZeroAccount(address)","98d0de03":"addPlayerToServer(uint256,uint256)","98d15134":"companiesManager()","98d24806":"GetPlayerById(uint256)","98d2e3b1":"calcTokenToWei(uint256)","98d30c50":"winnerCheck()","98d31a13":"AIR_2()","98d35f20":"anchors()","98d41484":"applySettings(uint8,uint256,uint256,uint256,uint256,uint256,uint256)","98d48567":"disapproveUserKYC(address)","98d4cacb":"_assemblyCall(address,uint256,bytes)","98d4e59c":"decreaseOffsaleCountByOne()","98d501ca":"OysterPearl()","98d5a1b1":"burnFromIco()","98d5fdca":"getPrice()","98d6ceb3":"BetSetAnswer(address,address,uint256)","98d6d8ed":"isPresaleStarted()","98d70779":"contRefer50x50()","98d714ac":"ethereumFromAltar()","98d7352f":"setTokenURI(address,string)","98d7456f":"ShowInfo(uint256)","98d764be":"Myastheniagravis()","98d78fe2":"soldDuringTokensale()","98d8adc0":"DividendDistribution(uint256,uint256)","98d8d7b4":"Vlicoin()","98da2133":"SEC_contract()","98da8121":"lock_vote_amount(bool)","98daa8c2":"changeJoysoWallet(address)","98dacb46":"setLockPostion(address,uint256,uint256,uint256,uint256)","98db173f":"calcaultePrizes()","98dc6ae2":"divX(uint256,uint256)","98dc8b44":"getStageIndex()","98dd0293":"changeBonusFrequency(uint32)","98dd0baa":"getNumOfLotto()","98dd4b7c":"getCountStakesToken()","98de4f35":"purchaseTokensfor82(uint256,address,uint256)","98de921f":"removeLoanFromPortfolio(uint256,uint256)","98dec601":"REGULAR_RATE()","98dedf30":"getBySchool(uint256,uint256)","98df3d00":"getNote(bytes32)","98df67c6":"revealSecret(uint256)","98e00e54":"getCallWindowSize()","98e02be7":"abandonShip()","98e09333":"valueGet(address,string)","98e0fb08":"ICO_TOKEN_SUPPLY_LIMIT()","98e12d12":"updateAnimal(uint256,string,string)","98e15065":"info256(string,uint256)","98e1a322":"LivepeerTokenFaucet(address,uint256,uint256)","98e1b410":"getMoney()","98e1b6cd":"stopPromotion()","98e23dcf":"finishPreSale5()","98e25733":"currentRoundNum()","98e314a2":"distributeDonationTokens()","98e364d6":"saasApiProfitAddress()","98e3d1d3":"getWineProductionRate()","98e4053f":"changeVerify(address)","98e47e49":"LoomToken()","98e4f581":"getSkin(uint256)","98e527d3":"getProposalsCount()","98e52f9a":"decreaseSupply(uint256)","98e54c55":"setAsTest()","98e6176a":"_isProxy(bytes32)","98e73df9":"hasOutstandingChallenges()","98e76e06":"buyValue()","98e7ea43":"reward(uint32[],address[])","98e8c54f":"testerCanReentrant()","98e8f365":"getYourRewardStock(address)","98ea1c51":"ecrecovery(bytes32,uint8,bytes32,bytes32)","98ea5fca":"depositEther()","98ea6536":"_beginOfICO()","98eaca94":"inKissBTC(uint256)","98eaf11c":"getBool(bytes32,bytes32)","98eb1096":"CalculateCreateFee(uint256)","98ec341d":"addThing(bytes32,string,string,bytes32)","98ec9095":"total_distribution()","98ecd12c":"test_mixValidEqBytes32Message()","98edc9ce":"distributeLottery()","98ef4b0b":"total_iou_purchased()","98ef5bf9":"BuyItem(uint256,string)","98f038ff":"migrateRegistry(uint256)","98f04128":"getRoundJackpot(uint256)","98f1312e":"MINT_CAP()","98f1e0e7":"sendTokensWindow(uint8)","98f20367":"Curatable()","98f22786":"FireToken()","98f23a6d":"createToken(string,string,uint32,uint256,uint256)","98f25c44":"removeCurator(address)","98f28571":"ClientOrderEvent(address,uint8,uint128,uint256)","98f2af3a":"createGame(uint32,uint64,uint32,uint32)","98f31c82":"price2Of(uint256)","98f32d1d":"getCatRequestPrices()","98f3b81a":"getShares(address,bytes32[],int256[])","98f3c443":"CROWDSALE_WEI_CAP()","98f423b2":"bitsmileToken()","98f42e3b":"payoutInvestors()","98f44c62":"resetTokenOwnerReward()","98f4b1b2":"rateOracle()","98f4f54f":"KhairulRamadhan()","98f52c52":"firstChainHNw1()","98f5ee5d":"spawningManager()","98f69aeb":"_addChildToParent(bytes32,bytes32)","98f6c7e5":"refereeInvitations(address)","98f6ff63":"unlock(string,address,address,uint256)","98f72f42":"COSS()","98f7ba63":"UBCToken()","98f8193b":"replaceTokenFix(address[],uint256[])","98f87496":"setRateFinalStage2(uint256)","98f8fe90":"accessCostMYB(uint256)","98f96c3a":"AboutKelvin()","98f9724f":"holderAmount()","98fa6c8a":"batchTransferETHs(address[],uint256[])","98faa9a1":"getStageBonus(uint256)","98fabd3a":"DAO()","98faf5d1":"TBsell()","98fb0ac5":"tokenGenerationEvent()","98fb2eca":"voteStopped()","98fc2e0a":"GetTickSize(uint256)","98fc55d8":"whitelist(address,uint256)","98fcc93e":"getNumberOfBets(uint256)","98fdb377":"REOC()","98fdfd8e":"changeMallcoinTokenAddress(address)","98fe2b49":"NotifierChanged(address,address)","98ff116d":"deposit3(address,address)","98ff1ba1":"tokensGenerated()","98ff8075":"claimBounty(address)","990030cc":"trusted_contracts(address)","9900c978":"ScudoCash()","99013562":"Reject(address,string)","99016142":"claim(uint256,address,uint256,bytes)","9901bc77":"YRX()","9902ef5b":"blockLeft()","990333be":"salesDeadline()","99035895":"approveERC20()","9903745f":"SetsecondTTaxAmount(uint256)","990386e8":"dailyRelease()","9903a2bd":"calcReleaseToken(address)","9903c29c":"SALE_MAX_CAP()","990460c1":"ownerKill(address)","990484a7":"valueToToken(address,uint256)","9904a68d":"requiredDays()","9904e174":"sellTokens()","9904ed8d":"Reputation()","990502d0":"GasBuy()","9905b744":"logUint(uint256)","99061a08":"AltCrowdfunding(address)","9906352f":"MANAGE_CAP_PER_ROUND()","9906f41c":"setDevelopeo(address)","9906f81b":"Entrant(address)","99076eca":"IHubToken()","990816bb":"BitcoinSilver()","9908b25b":"publicTransferToken(address[],uint256[])","9908d3cf":"AMEBToken()","99091c93":"insertLawyer(address,uint256)","990986dd":"getRawPendingAmount(uint256)","9909afed":"has(address,string)","9909d1a2":"createTestData()","990a6a64":"SC_locked()","990ae727":"clearZoDailyLimit()","990c5485":"proxyMergeMint2(uint256,bytes32,address[])","990c75ed":"getWhitelistedAmount(address,address)","990c8f79":"returnValue()","990ca3ff":"tokensToBeAllocated()","990cc5c9":"buyFromCurrentOwner(uint256)","990d6fd2":"getNextTranche(uint256)","990dec94":"signToResetAddTokenData()","990e178a":"_revealBlock(address)","990e1c9b":"withdrawStep()","990e2979":"submittedAmount()","990e713b":"buyTokens(address,uint256,bytes4,bytes32)","990e80a3":"setAddressOf(string,address)","990ed905":"setNewBonusScheme(uint256)","990eda99":"FreezeAddress()","990f3f53":"computeResponseSecondHalf(uint256,uint16)","990f412f":"setAssetHolder(address)","990fa439":"setLLV_edit_1(string)","99110d3c":"PRESALE_END_TIMESTAMP()","991162db":"getDank(uint256)","99116354":"errorAndRefund(string)","99119290":"getCryptodiamondAddress()","991257a2":"getSenderLands(address)","9913380e":"_getInt(address,bytes32)","9913dcbb":"AEFToken()","9914038a":"getBankRollGrowthForGameId(uint256)","99141a47":"iffun()","99142b5f":"send(address,string)","99154b49":"ARK()","9916233e":"LimitOrder(address,bool,uint256,uint256)","99166f7d":"getTotalAddresses()","991678bf":"LogRefundETH(address,uint256)","9916c350":"numberEthUpdates()","9917ccb8":"HongmenToken(uint256,string,uint8,string)","9918925d":"setClaim(address,bytes32,bytes32)","9919b1cc":"getContentsByRanks(address,uint256,uint256,uint256)","9919c9cf":"getGoldBackedByEachToken()","991a3b5e":"ARCD_FUND_DEPOSIT()","991a9fa9":"etherHasBeenReturnedToInvestors()","991b650d":"dataIdentifierCount()","991bcae8":"setup(address,address,address,address,address,uint256,uint256,uint256[])","991c9ae5":"set(uint32[],uint24[])","991cc283":"distributeICOTokens(address)","991d79b5":"EtheremonAsset(address,address,address)","991dd5b6":"read_user_purchase_at_index(address,uint256)","991e0139":"completeJob(bytes32)","991e47ff":"CoinWindow(uint256,string,string)","991e86bb":"c_maximumTokensSold()","991ef443":"publishers(uint64)","991f6798":"updateEQUIPrice(uint256)","991fa5af":"BinaryOption(address,address,address)","991feab5":"MMToken(uint256,string,uint8,string)","991ffd4e":"scheduleCall(address,bytes,bytes,uint256,uint256,uint8,uint256)","99209e33":"setEndOfCrowdsale(uint256)","9920ecb8":"buyPhaseTokens(address)","9921cac5":"AlbertCoin()","992204e6":"GoldFee()","9922ea86":"allocateTokens(uint256,address)","99244d1a":"testvalue()","99248d3e":"AxieAccessControl()","992495e2":"minerRandomNumber()","9924ab31":"CIVCoin()","9924ad7c":"ovatel()","9924ba1a":"updateInfo(address,address,uint256,uint256)","9925b9c1":"setMintFeeAbs(uint256)","9925d68e":"createPreSaleShip(string,uint256,uint256)","99260144":"rewardMintOwner(address,uint256)","9927482d":"proxy(address,string,address,uint256)","9928811b":"testBroken()","99288dbb":"saleOpen()","992a3e75":"changeBountyPaysTokens(uint256,bool,address)","992ae976":"isSafePunctuation(bytes1)","992b2f0f":"addSlogan(uint8,string)","992bb01e":"eval(bytes32[])","992bc0ce":"pay_to_OEM()","992c15fc":"MIN_VALUE()","992c3ff1":"TrekChain()","992c4435":"UETO()","992c870d":"transferName(bytes,address)","992cb59f":"getOrCreateDisputeCrowdsourcer(bytes32,uint256[],bool)","992d4196":"GNR(address)","992e0aa0":"purchaseBonus(uint256)","992e2a16":"getReportingEndTime()","992e74a9":"maxRefererTokens()","992e820e":"burnValue(address,uint256)","992ee4b6":"raiseTap(uint256)","992ee874":"WithdrawToken(address,uint256)","992fa380":"OmnisBit()","99304cd4":"AssetWithdraw(address,uint256)","993090d0":"adjustPrices(uint256,uint256)","9931a916":"TokenRK70Z()","99325442":"getCollectedOreBalances(address)","9932dc05":"codeToAddress(string)","9932fa28":"API2()","993301b2":"libbatchbacktest(bytes32,uint64,uint32[],uint64[],int64[])","9933a24a":"allowDirectDebit()","9933c6b5":"getPokemonLock(uint256)","9933d225":"addSpecial(address,uint16)","993480cf":"calculateRequiredVerifiers()","99348e90":"rewardsFunds(address,uint256)","99348f8e":"eggAvailable(uint16)","99352c42":"updateBtsPoint(uint16,int256,uint16)","99358876":"maxMintCookie()","9935935f":"setResolveHandler(bytes,address)","9935b968":"jesterBank()","9936746a":"DepositReceived(address,uint256)","99369801":"presaleTokenBalance()","99372321":"test(bytes32)","993783fc":"eraFromMokenData(bytes32)","99379718":"GimmerToken()","99384976":"setFounder(uint256,address)","9938579b":"getStatusTransferFrom()","9938b0de":"setPublisherCut(uint128)","9938be42":"getPOOL_edit_19()","9938fdd1":"downTick(address,uint256)","99393132":"onBurnCalled()","99395b1e":"OffMenuMorsel()","993ab58e":"setTournament(address)","993af624":"BrehonContract(address,address,uint256,address,uint256,uint256,address,uint256,uint256,address,uint256,uint256)","993b4f71":"transferBag(address,uint256)","993b8cde":"countPurchasedPixels(address[16])","993bcc63":"enableTokenBurn()","993c78fa":"getMintApproval(address)","993ca7e3":"RTB1()","993d1123":"BoltToken()","993d13bd":"PRE_ICO_MAX_CAP()","993d29fc":"Mindmap_Token(uint256,address)","993d3489":"investorShortInfo(address)","993eaefa":"TravelWithMeToken()","993eda02":"giveArtworks(uint8[],address,uint256)","993f3197":"TOSInstitutionsHoldingContract()","993fd4de":"setTokensSource(address)","99404433":"levelup(address,uint256)","99405ad7":"NewTokenSale(address,address)","9940fb5d":"convertToMeth()","99413b4e":"connectToken(address)","994162cd":"BasicTokenStorage()","99418a21":"signEthereum(bytes32)","9941e3d0":"setCallAddress(address)","9942aa4d":"create(address,address,address,address,address,address,address,string,string,string,string)","9942ce36":"_initializeLockupStages()","9942ec6f":"f2()","99433fc3":"GreenWorldFarmToken()","99434669":"fabricoin()","99439089":"validatorContract()","99444e30":"ICOprice()","9944b729":"withdrowTokens(address,uint256)","9944d5e7":"burntBounty()","99456542":"getLargeBonusStopTime()","9945e3d3":"redeem(bytes)","99464c89":"freezeAll()","9946b9a5":"disable(uint256)","994828a1":"BabyBearToken()","9948e493":"calcMarketFee(bytes,uint256)","99497349":"setData_29(string)","994977e5":"finalizeRent(uint256,uint256)","9949f0c8":"convertEthToWeth()","994a69d1":"centsToTokens(uint256)","994aca84":"TrenoToken()","994b1a0f":"changeDivCardAddress(address)","994cc574":"setAyantDroitEconomique_Compte_9(uint256)","994d3969":"whitelistStart()","994d3be3":"publishFunctionMessage(uint256,string,string,string)","994e5267":"SetMaxAttempt(uint8)","994f2e10":"getUpdateDerivePayoutDistributionHashValue()","994fb25f":"FileNameInt()","994fe290":"verificationListMap(uint256)","994ff619":"setKitty(address)","9950ace1":"rollRoom(uint256,address)","9951a2c8":"createTeamSaleAuction(uint8,uint256[9],uint256,uint256,uint256)","9951fc72":"TokenVesting()","99522297":"preCrowd_tokens_scaled()","9952b63d":"_receiveDonation(address,uint256)","995344da":"_updateVoucherMthEthRate()","99538898":"addTeamAddressInternal(address,uint256,uint256)","99540fe0":"normikaivo()","9954cf22":"JUST()","99552af1":"multiInvokeWith2Args(address,string,address[],uint256[])","99554e7b":"getNextFetchTime()","99554fb7":"distructVault()","99556615":"calculateProfitGameType2(uint256,uint256)","9956587e":"REGISTERFEE()","9956a28c":"mediumBuy()","995771b9":"CarnageToken()","995783d9":"ERC20(uint8)","9957ad05":"withdrawCreator()","9957f3e6":"KvantorToken()","99583417":"transferMultiple(address,uint256[],uint256[])","995893e6":"_createRole(bytes32,address[])","9958c661":"getstate(address)","9958d553":"max_creation_rate_per_second()","9958f045":"drasticMeasure()","995a15a8":"TouristToken()","995a299e":"setCurrentSeller(address)","995a2b52":"DeusETH(address)","995a7174":"_toLeconte(uint256)","995ab62e":"GAS_LIMIT_IN_WEI()","995b129f":"setAirDropManager(address,address)","995b2e2c":"getUnreadMessage(uint256)","995b40f3":"_getNextAuctionPrice()","995b4a80":"LogTokenSent(address,bool,string)","995b5aae":"feeInfo()","995cb4ec":"doWorkAndPayEAT()","995cc82b":"powerTotalSupply()","995cd653":"createSale(uint256,uint256,address)","995d9ab7":"getTags()","995e4339":"getResult(uint256)","995e599d":"ARCONA()","995f80e9":"NewSoftCap(uint256)","995fac11":"migration(address,address)","99600baa":"SVIP()","99603bfe":"CryptoDuelCoin()","9960d947":"grantKudos(address,uint256)","99613a3f":"metaSet(address,uint256)","9961476c":"MatchBetting(string,string,uint256,address,address,uint256)","996301e4":"claimTimeoutEnded(bytes32)","9963181e":"setAyantDroitEconomique_Compte_10(uint256)","9963a8e0":"fund(bytes32,string,address,uint256)","99645ba2":"changeStepLockFlag(bool)","9964622c":"_setPendingAnchorAdmin(address)","9964935e":"makePayout()","99649d06":"setInitialDeposit(uint256)","996517cf":"mintLimit()","99651db8":"addShares(uint256)","9965b3d6":"claimProxyOwnership()","9965ea53":"setPFManager(address)","99671dfb":"Sacacoin()","99678b43":"setFunctionThreePrice(uint256)","9968b87b":"SogetiTestCoin()","99693026":"setInitialState(address[],uint256[],address[],uint256[100][],uint256[],uint256,uint256,uint256,uint256)","99694cf2":"WIKICOIN(uint256,string,uint8,string)","9969b256":"sendOwnersBalance(address,uint256)","996a4be3":"uintToBytes(uint256,uint256)","996a8046":"__callback(bytes32,string,bool)","996b434a":"littID()","996b8b76":"updateIndividualCertificate(string,bytes32,bytes32,bytes32)","996cba68":"claim(address,address,uint256)","996ccf0b":"CockToken()","996d21aa":"privateTotalSupply()","996d2d65":"addAtkBossQuest(address)","996d310d":"resumeTransfer(uint256)","996ea781":"getOrganName()","996ec1f3":"BigBlockCoin()","996ed6e1":"TransactionSucceeded(address,uint256,string,address)","996f3247":"closeWall()","996f677b":"icoInvestmentsCount()","996f7602":"GetTotalMinerCount()","99704b65":"isAcceptedImportingAuthority(address)","997072f7":"getMemberCount()","9970e26b":"ParyToken(string,uint8,string)","9971b98d":"getDesign(uint256)","9971c6ce":"gupToken()","99721229":"amountForBonus()","9972b76c":"haltedFX()","9973b827":"totalLotteryValue()","997402f2":"liquidityAdd()","9975038c":"burnAll()","9975091a":"pausePreSaleRound()","997519f2":"SingularityNetTokenMock(address,uint256)","99753de7":"clear_level()","99755bab":"ICOCents()","9975c06b":"logDebug(string)","99761662":"YouWin(address,uint256,uint256)","997636ec":"play(string,uint256)","997664d7":"totalDividends()","997676c3":"checkWhitelistExist(address)","99767aa9":"FLC(uint256,string,string)","9976d32a":"coinOwner()","9976f5c5":"ProofOfDoge()","9976f9e1":"setAgriChainCultivation(address)","99771006":"GLORY()","99777d9d":"isPublicTokenReleased()","9977a108":"isCollected(address,bytes32)","9977b698":"startTokensSale(uint256,uint256,uint256,uint256)","99789670":"Initialized(uint256,uint256)","9978be95":"TOKENS_ADVISORS()","9978f01b":"setExchangeRate(address)","997995ec":"revealResultUncleMerkleProof(uint256,uint40)","9979b7aa":"CETACEA(address)","9979c009":"buyItem(uint256,uint256)","9979ef45":"placeBid(uint256)","997a0229":"_newPrice(uint256)","997a12fa":"attowethBalance()","997a2c1c":"numberOfMyComponents()","997aa31f":"sellChannel(string,uint256)","997bc6c9":"int2str(int256)","997c44e4":"setLockRate(uint256)","997c88ba":"calculateCurrentDistanceInRange(address)","997ce600":"endauction(uint256)","997cf69c":"dataset_sha256checksum()","997d2df8":"asserti(bool)","997d8473":"reserveBalanceMap(address)","997dd1c6":"dealHitCard()","997e02d9":"wormholeIsOpen()","997f0198":"setImageHeight(uint256,uint16)","997f35ac":"RewardOffer(address,address,bytes32,uint256,uint256,uint128)","997f50d8":"getCurrentTierHardcap()","997f51e6":"GAMToken()","997fdb1f":"setLockTime(address,uint256,uint256)","997ffd13":"quarterFourth()","99801bce":"dagheAcqua(uint256)","99808aff":"winningTicket(address)","9980dee2":"calculateHash(address,address,uint256,uint256,uint256)","9980ec86":"getAmount(uint256)","99817b47":"releaseVestedTokensForBeneficiary(address)","9981bd61":"requestTokenExchangeMax()","99820e96":"finishSunning()","9982257b":"hotQuestion(uint256,uint256,uint256)","998282e9":"winners(uint32,uint32[],uint64[])","9982e7ed":"updateBillionsCoinsRemainingToDrop()","998446a8":"acceptRequest(uint256,bytes)","99847f77":"addUnsoldTokens()","9984f30d":"setMaxValue(uint256)","99851eac":"updateCards(uint8,uint256[])","9986d936":"setRestrictedPercent(uint256)","9987680b":"play(address,bytes32)","99878d5b":"play_scissors()","99879bb9":"startTimeInSec()","9987b2d2":"getProposalIndex(address,uint256,bytes32)","99882cdb":"propose(bytes32)","9988807d":"centsReceived(address)","9989a5ae":"setLimitOfParticipants(uint256)","998a1f96":"preICORaised()","998ac104":"AIRDROP_TRANSIT_ADDRESS()","998b022e":"_mintPrimordialToken(address,uint256)","998b723b":"waterTree(uint256)","998b894a":"isLegalTime()","998bac16":"bulkTransfer(address[],address,uint256[])","998be0d7":"sendTokenToSingleAccount(address,uint256)","998c4f5a":"setEthExchangeWallet(address)","998cab7e":"getTransformTarget_pool(address)","998eb4cf":"getRank03()","998f9203":"INCash()","9990b3a3":"getPreSaleWallet()","9990db92":"CryptoSureToken()","999122f4":"BHK()","999377ec":"acceptBlokTokenOwnership()","9993fa94":"balanceOfSender()","9994e112":"AddContact(address,bytes32,bytes32,bytes32,bytes32,bytes32)","9995bbf7":"ethforp3dbuy()","99967819":"lastaction()","99999342":"GetBonusInv()","9999aae5":"EYTToken()","9999bd2e":"RATE_PRESALE()","999a9965":"setMany(uint256,int256,uint256,bytes,address,bytes)","999b078e":"isSoftCapHit()","999b5c72":"FASET(uint256,string,uint8,string)","999cbaf5":"Deposit(address,uint256,uint8,uint256)","999cef04":"PublishWorldCupResults(bytes32,bytes32,bytes32,bytes12)","999d350d":"totalBonusGiven()","999d3947":"getGenes(uint40)","999d46b9":"transferInterviewer(address)","999dd03e":"poolAddressCapTier2()","999eb6b1":"balanceOfThis()","999f18a6":"unsigned()","999f4b38":"sellDividendPercent()","999f5644":"Stoppable()","99a032ce":"isCurrentAccountReader(address,address)","99a03c70":"realBalanceOf(address)","99a17344":"setHiddenLogic(address)","99a1a412":"getModeratorCount()","99a2e1ec":"roundLatLngFull(uint8,int256)","99a3e03f":"testNegativeIntegerKeyValue()","99a3f0e8":"right70(uint256)","99a44e68":"BEXP()","99a48638":"packSettings(uint256)","99a48e17":"FinalizableToken(string,string,uint8,uint256,address,uint256,address[],uint256[])","99a5d747":"calculateFee(uint256)","99a6993b":"KCCTOKEN()","99a6f7d2":"createReserveTokens()","99a752d7":"setPriceETH(uint256)","99a79790":"startTimeSale2()","99a7b857":"FundsWithdrawal(address,uint256)","99a7b884":"getBuyerFullInfo(address)","99a7e9db":"get_presale_iconiq_arbits_per_ether()","99a856e3":"firstBonusRate()","99a88ec4":"upgrade(address,address)","99a8f2fe":"EncryptedToken()","99a9a04c":"BITStationERC20()","99a9ccb2":"preMinedSupply()","99aa5d97":"Pixel()","99aa93c8":"numSales()","99aba8e3":"distribute(address,uint256,uint256,uint256)","99abaabb":"addMarketToWasCalled()","99abd788":"FIRSTSALE_TOKENCAP()","99ac4569":"withdraw(uint64,address[],uint256)","99ad91c7":"AddAdmin(address,address)","99ae6a16":"Winner(address,uint32,uint32,uint256)","99aeade3":"iterateTable(uint256,uint256)","99aef94a":"getMyEntitySimple(uint256)","99af4114":"createPet(uint256,uint16,address)","99afb9b9":"createValidatedRequest(address[4],address,uint256[12],uint256,bytes)","99b0dc4d":"areAllUppercase(bytes16)","99b1adbf":"isUserMember(address)","99b22701":"delBackend(address)","99b29044":"getPropertyEarnUntil(uint16)","99b2a233":"offlineGuardianSold(uint256,address,uint256)","99b465cb":"currentSegment()","99b47af8":"reveal_test_data_groups_block_size()","99b4a0c6":"BTRL()","99b55343":"termsNumber()","99b58f06":"icoPushAddr(uint256,address)","99b5b2fa":"horseIndexPrice(uint256)","99b632e4":"winnovate()","99b6f5a1":"sendAdvisorsTokens()","99b721a5":"rewardEthAnd(address[])","99b77032":"setMinBuyLimit(uint256)","99b83f3d":"setMaxRedemption(uint256)","99b8a3f0":"charityBalance()","99b8e366":"reloadPlayerInfo(address)","99bac5c9":"setMinCustomerBalanceETH(uint256)","99bad2cd":"testAddExistingVoter()","99bb8134":"approveMany(address,uint256[])","99bb875c":"funeralAndBirth(bytes,int256,bytes)","99bc0aea":"expiryTime()","99bc826e":"intMemoryArray()","99bcb1a1":"thirdWeekMainICOBonusEstimate()","99bdc9c2":"AdminAddition(address)","99bea0bd":"AllForOne()","99c0058c":"getAttackPlayerList()","99c20c34":"percentToFoundersAfterICO()","99c24d85":"SetCurrentRoomAndRound(address,uint8,uint256,bool)","99c27d40":"updateGlobalMin(uint256)","99c2af56":"setRateEarlyStage2(uint256)","99c2b93b":"startCrowdsalePhase1Date()","99c2bb40":"listAssetDocumentsFrom(bytes32,bytes32,uint256,bool)","99c32025":"TwoPhaseTransfers(address[],address[])","99c4644a":"putIdentityProvider(address,string)","99c49852":"cancelOrder(address)","99c59bdc":"MadeBet(uint256,uint8,address)","99c69d40":"getPremiumsAvailable()","99c6d2de":"depositToken(address,uint256,uint256)","99c6da4a":"UTWD()","99c724ef":"skipInLine(uint256,uint256)","99c75517":"GetCompetitionInfo(uint32)","99c8055d":"Enable()","99c8268b":"totalBattle()","99c87629":"getFibonziPlayers()","99c8d556":"tax()","99c8fcba":"agreeBetWinner(uint256,uint8)","99cac223":"getBallotIndex(address,bytes32)","99caf208":"updatePendingManager(address,uint256)","99cb0823":"presaleBonus()","99cbc1b9":"Bet(address,bytes32,bytes32,uint256,uint8,uint16,uint16,uint16,uint8,uint256,uint8,address)","99cc00d1":"getImageHeight(uint256)","99ccbec6":"claimByTeam()","99ccf3da":"_increaseToken(address,uint256)","99ccfd34":"forkUpgrade(address,address)","99cd211d":"bountyTokensWallet()","99cd40aa":"_setBytes(bytes32,bytes)","99cdee0e":"own()","99ce00a9":"VREO_SALE_OPENING_TIME()","99ce12c1":"getAssetClaimString(uint256)","99ce919c":"goods(bytes32)","99ceb6e6":"BTCReceived()","99ceed71":"OwnerTokensBurned(uint256,uint256)","99cf5582":"burnVotes()","99cfe1e1":"issueCofoundersTokensIfPossible()","99cfe743":"TotalGenesisAddresses()","99cffe4d":"LinearBeam()","99d0f06c":"removeNotes(uint256[],uint256[],uint256)","99d136f5":"multiSend(address[])","99d18937":"getAllDSP()","99d1c413":"isEggFactory()","99d1d002":"debug_blockHeaderMerkle(bytes)","99d1e755":"getTeamWallets()","99d22e48":"founderAllocated()","99d3acd3":"EtherDeltaDepositToken(address,uint256)","99d413f4":"createDividendPercent()","99d4aec9":"getPurchaseRequests()","99d50d5d":"getComponents()","99d52baf":"test_startBool()","99d5af62":"unLockBatchAddr()","99d64ab0":"maximumFunding()","99d67084":"numberOfInvestorsToWithdraw()","99d786ca":"lastMonth()","99d792a2":"releasePrivateSupplyVested()","99d7dd25":"isEcoAllocated9()","99d80ed9":"addService(bytes32,uint256)","99d83b77":"BuyRC(address,bytes,uint256,uint256,uint256)","99d897f8":"sellForOtherCoins(address,address,uint256)","99d9b306":"trancheMinTx()","99d9d1e0":"KNB()","99db626c":"LOG_SpinExecuted(bytes32,address,uint256,uint256)","99db7eb7":"TapPoll(uint256,address,address,uint256,uint256,uint256)","99dbff01":"buyCourse(uint256,uint256)","99dc79d1":"getBracketScore(bytes8)","99dd1ed9":"estLiquidationCap()","99ddb29b":"addressType(address)","99de4fc5":"UNK()","99def960":"getcredibilityScore(bytes12,bytes12)","99df3d7a":"setFunctionAuthorized(address,string,bytes32)","99dfa711":"GetCurrentTypeStartTime(uint256)","99dfedb4":"getTeamSumSkills(uint256)","99e0021f":"mergencyCall()","99e0dd7c":"setTokenURIPrefix(string)","99e133f9":"init(address,address,address,address,address,address)","99e1cc47":"calculateAndSendRefund(address,uint256,uint256,uint256)","99e1d127":"filterWarriorAuras(uint256,uint256)","99e2ab0e":"UpdateMinFee(uint256)","99e3a723":"verifyOwner(bytes32,address,uint8,bytes32,bytes32)","99e47b2d":"DinoFarm()","99e487a9":"F2UPhone()","99e71b64":"secondBalance(address)","99e74ce8":"tokenIdToHeroInstance(uint256)","99e7c00a":"yaaay()","99e7cedf":"cobeneficiary()","99e8f303":"getM5Reward(address)","99e91527":"dequeueAuditRequest(uint256)","99e9376c":"buyWithCustomerId(uint128)","99ea0fd5":"disputeAllReporters()","99eb6603":"initalize(uint256)","99eb975c":"TransID()","99ec140d":"Tokensale()","99eca69f":"withdraw(uint256,address[])","99ecba80":"maxMinutesProposalPeriod()","99ed7b87":"getStrengthValue(uint256)","99ee9076":"defendFee()","99ef111c":"stopAddresses(address)","99eff1f7":"nextElectionIndex()","99f02ab5":"getWinnerContractAddress(uint256)","99f02b60":"IHFVesting(address,uint256)","99f07bed":"_clearCommittedValidators(uint256)","99f16c6e":"validateContribution(uint256)","99f1718a":"getSiteItem(uint256,uint256)","99f3379f":"getSolverAddress(bytes32,string)","99f3487b":"testBoolKeyValue()","99f49f0d":"vitPerWei()","99f4b251":"mine()","99f5c357":"modultradeStorage()","99f5c904":"momentValueOf(uint256,uint256)","99f6021d":"durationSec(bytes32)","99f65122":"getParam(uint256)","99f6a693":"setMasterName(uint256,string)","99f6d9af":"getTotalNumberOfRegisteredCompanies()","99f91c5d":"updateAllRewPaid()","99f9be87":"TEX()","99fa6ed7":"EthPledge()","99fb15d2":"distributionActive()","99fbe995":"Wallet(address[],uint256)","99fbf3a2":"setRentPrice(uint256,uint256)","99fca937":"amountOfEthersOwnerCanWithdraw()","99fd12f6":"etc()","99fd9489":"endCrowdsale(bool)","99fdc17e":"redenominatedValue(uint256)","99fe18b9":"fightBoss()","99fe6c88":"CashTCoin()","9a003b61":"checkRequiredChange(uint256,uint256)","9a008d7b":"startPaymentProcess(address)","9a01b4d5":"getChannel(address)","9a02d3ac":"unapproveWithdrawal(bytes32,bytes32,uint256)","9a02edfe":"maxTokensPerAccount()","9a033782":"addContractToTokenFallbackWhiteList(address,address)","9a037aa0":"setReferralBonus(uint256)","9a03d9a3":"setERC721Address(address)","9a03fe1d":"Div(uint256,uint256)","9a0475e9":"ASHLEY_ADDRESS()","9a04a4ed":"setOpenInterestInAttoEth(uint256)","9a04ab73":"safeAddI(int256,int256)","9a04b89e":"setGiftoAddress(address)","9a04e602":"mintBounty(address,string)","9a04f704":"guest()","9a04fc8b":"getNodeParent(bytes32)","9a05cd66":"_setNarcosCoreAddress(address,address)","9a065a60":"discountTokenAmount()","9a06671e":"CoinsRetrieved(address,uint256)","9a06b113":"createPool()","9a06c2d3":"getRnMmasterReq()","9a073742":"setFeesWithdrawalAddress(address)","9a0750d5":"tokenFundDeposit()","9a0846f1":"MyKidsEducationFund()","9a08623a":"withdrawFromToken()","9a0907c2":"contributeAndVest()","9a09a8ef":"getCoinByCount(uint64)","9a0af2ec":"getStLength()","9a0b2db3":"withdrawFeeEntitlement()","9a0ca07d":"changeLocked(bool)","9a0d4f40":"PRESALE_PERIOD()","9a0d6247":"withdraw(uint8,bytes32,bytes32,uint256,uint256)","9a0e4ebb":"multiMint(uint256[])","9a0e7d66":"getTotalVotes()","9a0e7e8e":"secondSaleDelivery(address,uint256)","9a0e9e50":"newPoll(uint256,uint256,uint256)","9a0f1561":"prizeDeposit()","9a10f719":"setFreezeAddress(address,bool)","9a10f819":"buyOracle(bytes,address)","9a114fb0":"_Challenge(bytes32,uint256,uint256,string)","9a116ca1":"implementationCall()","9a1295d9":"getPassportLogic(string)","9a14228e":"getEntryPrice()","9a158883":"BOBOToken()","9a15f4f3":"getBlockHeader(int256,int256)","9a160ad9":"MeissaToken()","9a163c44":"currentVotingAmount()","9a165f6c":"currentCapTokens()","9a166299":"getMyAddress()","9a167613":"forceConsume(uint256)","9a16a7e3":"getAccountInputSdcslength()","9a18a5ba":"NEXPARA(uint256,string,string)","9a19a953":"setInt8(int8)","9a1a661e":"entranceFeePool()","9a1ac4b2":"OpenAddressLottery()","9a1b420b":"OraclizeAddrResolver()","9a1ca8d2":"SALE_ETHER_MIN_CONTRIB()","9a1e7ea0":"randomSatoShiTime()","9a1e9dc3":"Buy(bytes32,address,uint256,uint256,address,address)","9a1f6a0f":"setPacksPerClaim(uint16)","9a1fd3d5":"armyPlanesCount(uint256)","9a1fdc10":"createHorseShoe10(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","9a1ff4f4":"Ruthenium()","9a202d47":"removeAdmin()","9a206ece":"isSpender(address)","9a20821b":"claim_winnings(address)","9a21213e":"_getProviderOwner(uint256)","9a2160a7":"currentBetNumber()","9a221876":"project_contract()","9a22dec5":"buyAllAmountPayEth(address,address,uint256,address)","9a234885":"storeUserDataHash(uint256,bytes32)","9a2392b2":"getFirstBuyNum(bytes32,bytes32)","9a23ab61":"XXXXXXXX06(address,address,uint256)","9a2457c1":"getMiningAttempt(uint256,address)","9a251185":"isValidCertificate(bytes32,bytes32,bytes32)","9a267230":"END_TS()","9a276186":"getLentTime(uint256)","9a27b7ed":"setBounty(address,uint256)","9a2828f3":"setTechnicalWallet(address)","9a285ffb":"myDividendsYes()","9a28910a":"PrivateSaleBuy()","9a29ccf7":"_determinePid(address)","9a2a1f75":"CrowdsaleLeviusDAO(address,address)","9a2a224a":"setWallet(address,address,address,address,address)","9a2b4bdf":"ChangeTotalSupply(uint256,uint256)","9a2d2692":"withdrawToPoolOwnerFee(uint256)","9a2dcadf":"fundoShares(uint256)","9a2e27f8":"presaleEndDate()","9a2e6b40":"vote(uint80,bool)","9a2f9e92":"keeCrytoken()","9a2fb8c1":"startTimePrivatePreICO()","9a307391":"operator(address)","9a314b8e":"Group(string)","9a317cca":"getHWCAddressByIndex(uint256)","9a31a5f0":"transferManual(address,uint256)","9a31ac53":"setLastRegistration(string,int256,uint256)","9a31b14e":"set_totalSupply(uint256)","9a323ac4":"MAXfinney()","9a3241a6":"AddParticipant(address,uint256)","9a325e52":"exchangeRateRoundTwo()","9a336fed":"removeTotalCoinLock()","9a33aff9":"startDocumentPoll(bytes32)","9a33c610":"addPA(string,string,string,address,address,uint32,uint32,address,address,uint32,string)","9a33e300":"projectName()","9a344170":"test_insert_full()","9a347dd9":"tokensToFunder()","9a35f886":"__dig_then_proxy(uint256)","9a36f932":"feeDivisor()","9a37d1b7":"distributeEbyteForETH(address[],uint256,uint256,uint256)","9a38330d":"setIssuer(address,address)","9a388bd2":"CORAddress()","9a38ac79":"requireAuthorisation(bool)","9a38aeb1":"verifySignature(address,uint256,bytes32)","9a38bfae":"voteHash(address)","9a3a8c85":"ExiliumToken()","9a3aed36":"setMainAdmin(address)","9a3c4158":"setEthWallet(address)","9a3ce541":"price(bytes12)","9a3d1f3f":"twentyThirtyVault()","9a3ea7cc":"provas(bytes32)","9a3fc66d":"iouTokens()","9a3fd1fb":"tokenFallBack(address,uint256,bytes)","9a3fdfd0":"bountyTokensPercent()","9a406338":"VESTING_DATE()","9a40a316":"betting(uint256,uint8,uint256)","9a40d8f5":"equal(address[],address[],string)","9a41c1e6":"walletToVault(address,uint256)","9a429d2f":"setDisclaimer(string)","9a42adb3":"change_ico_start(uint256)","9a42af48":"getLastPrice(bytes32,uint8)","9a42c935":"forLottesy()","9a42f3aa":"reveal(uint256,uint8,bytes32)","9a4363cb":"setlockall(bool)","9a436c9b":"burnBasisPoints()","9a4373a6":"_internalTransfer(address,address,uint256)","9a437da2":"lookupPriorLottery(uint256)","9a438c5f":"ChangeInsuranceFeesOperationEvent(uint80,uint80,uint80,uint80,uint256,uint80,uint80,uint256,uint256)","9a43e59a":"VAA()","9a4435c6":"BitcoinGame()","9a443955":"setNumVotesRequired(uint256)","9a44690e":"finalizeSettingUpdate(uint256)","9a454b99":"deployedAtBlock()","9a459f75":"setShortDescription(string)","9a45a263":"decentBetMultisig()","9a45e3fe":"getChannelExist(bytes32)","9a465b85":"lastBlock_a10()","9a46793e":"roundsManager()","9a471416":"bountyFunds(address[],uint256[])","9a47700f":"checkExpires(bytes32)","9a4772cd":"LogClaim(address,uint256,uint256)","9a478b49":"join(uint256,bytes32)","9a47cee3":"convertGene(uint8[48])","9a48007d":"hasHourlyRateWithinRange(address,address,uint256[],uint256[])","9a483a8e":"exerciseExpiredEmployeeOptions(address,bool)","9a48eb3e":"tokenTransferProxyContract()","9a49eab5":"MINER_CREATION_LIMIT()","9a4a0fb2":"centralBank()","9a4ac102":"tinyIPFShash(string)","9a4b19e4":"SiaCashCoin()","9a4b1d5c":"verifyTransfer(address,address,uint256)","9a4b87f1":"setDrop(bool)","9a4b8fc9":"lockInSemiFinalPrize()","9a4bca21":"setMintTap(uint256,int256)","9a4ca3cb":"itemsOfOwner(address)","9a4cbb92":"getDamage(uint256,uint256,uint256)","9a4cd266":"test_fourValidEqBool()","9a4d19f8":"getAmountAccredited(address)","9a4dfa87":"OfferCanceled(uint256,address)","9a4e36d9":"antiques(bytes32)","9a4e9bff":"FXPay()","9a4ed149":"getBlocksquareFee()","9a4f1e2c":"ETCrossPotatoPresale(uint256,uint256)","9a4f78cc":"decreaseShares(uint256,address)","9a4fd88d":"crowdsaleSucceeded()","9a4fdf66":"nextBro()","9a507d9b":"feeHoldingAddress()","9a508c8e":"finalizeUpgrade()","9a5199fc":"goodbye(uint256)","9a51a31a":"ToToken()","9a526b97":"setPreIco(address)","9a52b339":"checkInterest()","9a54596b":"Token(uint256,string,uint256,string,string,address)","9a5483e6":"addRole(uint256,address,uint256)","9a556a59":"getCooldown(uint256,uint16,uint8)","9a56193b":"getNumberOfDerivatives()","9a565169":"ETHERGOLD()","9a5666b8":"SVLightBallotBox(bytes32,uint64[2],bool[2])","9a571d9f":"isAlphaLower(bytes1)","9a573786":"getKeysManager()","9a581271":"cursedContract()","9a586d26":"MAX_SALE_VOLUME()","9a58c33d":"batchAssetTransfer(address,uint256[])","9a592415":"LostPayment(address,uint256)","9a593b9a":"startCrowdfund()","9a599e37":"burnfromAdmin(address,uint256)","9a5a2d4e":"lastTimePriceSet()","9a5a6483":"milliTokensSent()","9a5c0abc":"sellCards(uint256,uint256)","9a5dd735":"getRichest()","9a5e095c":"_buyTokensInCurrentStage(address,uint256,uint256)","9a5eb28f":"BUYER_CAP_LOW_USD()","9a5f17ee":"ccEndTime()","9a5f54b3":"getTetherInts(address,uint256)","9a6203e9":"getClosingObligation(bytes32)","9a628121":"random256()","9a62b752":"becomeTurtlemaster()","9a63157a":"addressBankPartners()","9a64a276":"findById(uint256)","9a650fd8":"isTerminated(address)","9a651f0b":"firstStageRefund()","9a6524f1":"TOKEN_CAP()","9a65ddec":"getAddressByName(string)","9a65ea26":"startMinting()","9a661e66":"getGratitudesSizeOf(address)","9a670bbc":"secondPreSaleEndDate()","9a68323c":"getRoundDetails()","9a684658":"_getBlockIndex(uint256,uint256)","9a6921e4":"getOpGas()","9a6a30a4":"reclaimEther(address)","9a6a68e9":"numberWinner()","9a6b32e1":"claim_reward(uint256,bytes32)","9a6b607f":"distributeTokensToMembers()","9a6bd379":"powerUp(uint256)","9a6ced6d":"bountyAgents(address)","9a6d3aaa":"bet(uint256,bool)","9a6d7cb8":"_canMateViaMarketplace(uint40,uint40)","9a6d9671":"combineMyGirls(uint256,uint256)","9a6dac14":"getLOTBalance(address,address)","9a6dfeff":"totalVotesForParty(uint256)","9a6e9914":"deleteArrayString(bytes32,uint256)","9a6ec511":"_buildId(address,uint256,bool)","9a6edad1":"Jupiter()","9a6f978d":"DIP()","9a6fb6df":"productionUnitTokenContractCount()","9a6fcbdd":"popElement()","9a6fe50c":"getLatestForContractAddress(address)","9a701075":"WITHDRAWAL_END()","9a702ad5":"AVAILABLE_JOINTTOKENS()","9a70855e":"exchangeFlag()","9a70eb1a":"onSaleAmount()","9a713233":"pre_end()","9a71825e":"sellKnowledge()","9a721302":"SUPPLY_FOR_BOOUNTY()","9a722769":"autoFinishTime()","9a727526":"getManagementInfo()","9a729d03":"token_bid(address,uint256)","9a72afb6":"setIsDisputeActive(bool)","9a730617":"init(address,uint256,uint256,uint256,uint256)","9a7394f5":"setData_34(string)","9a74adda":"moveAccountIn(address)","9a74c10c":"getDefaultReportingGasPrice()","9a751072":"applyChangeWalletAddress(address,address)","9a75aa06":"emitPublicCapabilityAdded(address,bytes4)","9a7614ee":"acceptEther(uint8)","9a7615a2":"burnOwner(uint256)","9a772bce":"TokenCappedCrowdsale(uint256,uint256,uint256)","9a7754d6":"StagedCrowdsale(uint256)","9a777d5d":"buyCoins()","9a7853cd":"postTX(address,string,uint256,uint256,uint256)","9a78afc6":"reduceDiv_()","9a78c066":"checkExistsInArray(address)","9a78c562":"setSellingTime(uint256,uint256)","9a797128":"withdrawed()","9a79f4a8":"testFailHeaderInsufficientFee()","9a7a3293":"NoFakeCoin()","9a7a7c11":"makeRoll(uint256)","9a7b5b7b":"tryClose()","9a7baa81":"EcomethToken()","9a7be471":"updateMinDeposit(uint256)","9a7d5211":"TheDigitalStandard()","9a7db5d9":"adminSendWorldBalance()","9a7e00ef":"acceptBet(uint64)","9a7e9e1f":"executeByAction()","9a7ee18c":"AccountIsNotFrozen(address)","9a7efb7f":"giftFor(address,address,uint256)","9a8061e8":"setLicenceShopPrice(bytes2,uint256)","9a80e52f":"updateTknPrice(uint256)","9a819e5e":"forceLiquidation()","9a82031e":"getRoundWinnigNumbers(uint32)","9a824f00":"transferTobucketTwoContract(address)","9a828a71":"oracalizeReading(uint256,string)","9a82a09a":"cancelled()","9a82c93c":"PRESALE_ENDTIMESTAMP()","9a82f890":"isOracle()","9a8318f4":"total_withdraw()","9a8335e0":"sendTo(string)","9a841413":"deleteDeployer(uint256)","9a84792b":"onReturned(address,uint256,uint256)","9a84d0c4":"addToken(address,string,string,string,uint8,bytes32,bytes32)","9a862c2d":"stage2StartTime()","9a863892":"NewProposal(uint256)","9a86acda":"getHeld(uint256)","9a86cd04":"shittyRand(uint256)","9a87ebb5":"changeAllowances(uint256,uint256)","9a880629":"dStartsNow()","9a880848":"attackhill(uint256)","9a881ab4":"payToFines(uint256)","9a882b7a":"createtoken(string,string,string,string,string)","9a891058":"keyIndex(bytes32)","9a89ad65":"within6Confirms(int256,int256)","9a8ae2fa":"changeLastFreeBlock(uint256)","9a8b3d8f":"getClientProjects(address)","9a8ca12c":"icoEnds()","9a8cea55":"testPush()","9a8cea82":"calculateDevFee(uint256)","9a8d10a3":"addData(uint256,bytes32)","9a8d36fa":"_openGameRange(uint256,uint256)","9a8d86c5":"CrowdSale_Finalize()","9a8e7b02":"ProposalClosed(uint256,uint8,uint256,uint256,bool,uint256,uint256)","9a8f09bd":"newKing(address)","9a8f139d":"getPercent1(address)","9a8f4dbf":"CancelSellOrder(uint32)","9a8f71f7":"saveData(bytes32,uint256)","9a8f72d1":"pruebacn123()","9a900e8c":"changeDepositWalletAddress(address)","9a903ca7":"allocateTokens(address,uint256,uint256,uint256)","9a9249a8":"_calculateCurrentPrice(uint256,uint256,uint256,uint256)","9a92b7e7":"EthVenturesFinal()","9a93e940":"testFailCreateNewRevisionNotUpdatable()","9a94ab9c":"addDelegate(address,string,address,uint256)","9a953408":"CHLORINETOKEN()","9a954af9":"getFreeToken()","9a956915":"icoInvestors(address)","9a95ca48":"presaleCapReached()","9a95d0e4":"DEEO()","9a960778":"SBK()","9a961416":"gameNext()","9a967e3b":"nextMember()","9a969768":"distributeProfits(uint256)","9a96f829":"devs()","9a97043b":"depositIdx(address)","9a98aa1e":"Scorpio(uint256,string,string)","9a98ac88":"GCSToken()","9a999359":"priceUpdatedTime()","9a99ebf4":"drainGame(bytes32,bytes32,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","9a99f7e0":"isModOrCreator()","9a9a5cdb":"checkEthBalance(address)","9a9b1709":"PGGamePlatform()","9a9b5323":"AlforroCoin()","9a9bc131":"aidrop(address[])","9a9c29f6":"settle(uint256,uint256)","9a9c437d":"CryptFillToken()","9a9c9c53":"DepositToBankAccount()","9a9d0935":"totalBountySupply()","9a9d6515":"APPC()","9a9e3fd8":"successful()","9a9ed624":"ProfitLoaded(address,uint256)","9a9f1304":"drawMini()","9aa035dd":"dev_multisig()","9aa03cc6":"calculateExchangeFee(uint256)","9aa07ed7":"DietEthereum()","9aa0a50e":"btcDeposits(bytes32)","9aa0ff7b":"SALE_END()","9aa1001b":"withdrawRewardPool(address,uint256)","9aa10ebf":"Story()","9aa13f04":"contractStart()","9aa1dab7":"removeOversight(address)","9aa26f06":"registerBytes32(address,bytes)","9aa287d9":"setIco1Tokens(uint256)","9aa3a443":"acceptContribution(address)","9aa4a64e":"set_patient(uint256,uint256,string,string)","9aa57922":"Bhtd()","9aa5ee73":"finalizeConfirmationPeriod()","9aa5f467":"phase_3_token_price()","9aa615ee":"initCrowdsale(uint256,uint256,uint256)","9aa72320":"EthereumCare(uint256,string,uint8,string)","9aa727f6":"mult(uint256,uint256)","9aa72b71":"shareAmount(address,uint256,uint256,uint256)","9aa74525":"increaseWithoutCounterparty(bytes32,uint256)","9aa84b0b":"blockNode(address)","9aa92f0c":"previousRounds(uint256)","9aa93224":"sendOre(address,uint256)","9aa99dc8":"ownerPauseJackpot(bool)","9aa9f27b":"privateSell2Address()","9aaa38a6":"ChangeComission(uint256)","9aaa3eec":"updateNickname(address,string)","9aaa4696":"transferRaw(address,uint256)","9aaa5750":"addGoldTransaction(string,int256)","9aaa6b4d":"getAttackAddress()","9aaac864":"isInitialBlockTimestampSet()","9aab0c7a":"BitUPToken()","9aac9e91":"EndPreSale()","9aacb10a":"setNewCreator(address,uint256)","9aacb18c":"getSolution(uint256,uint256)","9aae3d0e":"maxWeiTier1()","9aaf442c":"applyCensorship(uint256)","9aaf5e05":"allocateTokensBeforeOffering(address,uint256)","9aaf9f08":"getVersion(bytes32)","9aafbff0":"addEntryIn24WeekPeriods(address,uint256,bool,uint256)","9ab060de":"milestoneBonus()","9ab06fcb":"setPayment(address)","9ab102ac":"isAffiliated(address)","9ab1416c":"accept_B_coupons(address,uint256)","9ab1b484":"distributeTokens()","9ab1d468":"privateSaleTransfer(address[],uint256[])","9ab253cc":"transferToICAPWithReference(string,uint256,string)","9ab2cf0d":"checkLockedBalance(address,uint256)","9ab3161d":"AnimalFactory(address,address)","9ab361a2":"unlockTimeLine()","9ab3a1fd":"setMvpExists(bool)","9ab3bfd7":"Tier_Basic_Registration()","9ab42287":"getAllAnimalsByAddress(address)","9ab422f3":"register(string,uint256,uint256,uint256,uint256,address[])","9ab448d9":"updateForkValues()","9ab4833e":"viewToken()","9ab4b22f":"releasedBalance()","9ab4d3a8":"checkInvestorReturns(address)","9ab567ba":"batchTransferForSingleValue(address[],uint256)","9ab79905":"withDiscount(uint256,uint256)","9ab7d0b7":"setTheName(string)","9ab7f298":"add_user(bytes32,bytes32,int256)","9ab80f14":"BuyPrice()","9ab86b78":"getVoteHubDetails()","9ab90ba0":"realityID()","9ab95202":"babzBalanceOf(address)","9ab9ee73":"prPool()","9abb08ed":"migrateStateFromHost()","9abb2c16":"getAuctionsCountForUser(address)","9abb9e78":"powerDayEthPerPerson()","9abc03d2":"auctionsStartTime()","9abd3572":"claimDividend(uint256)","9abd7d50":"SelfDestructTime()","9abe275f":"closeChannel(address,bytes32,uint256,bytes32,bytes)","9abe3906":"closePreICO()","9abec159":"DISCOUNT_STAGE_THREE()","9abeddf8":"getLastUnionId(bytes32,uint8)","9abfba20":"DeleteBillModerator(address)","9ac08dfd":"receiveApproval(address,uint256,address,bytes1)","9ac17057":"execute(uint128,uint128)","9ac18b19":"REQUIRED_SIGNATURES()","9ac1f9a1":"add_commitment(uint256)","9ac22e5b":"test_oneTrueAndFalseAssert()","9ac233f3":"Monarchy()","9ac2ba20":"start_all()","9ac3317b":"grantMultiplePermissions(address,bytes32[])","9ac3fce6":"getBankReg(address)","9ac467f9":"getAllSigners(uint256)","9ac4fa49":"isAirdropStopped()","9ac50a62":"tenmatest()","9ac58d58":"get_len()","9ac785ba":"LockDate(uint256,uint256)","9ac8cd1b":"calcJackpotFee(uint256)","9ac97e84":"getNumDIDHolders()","9ac9940f":"assetOwner()","9aca6e2e":"calculate_total_shares(uint256,uint256)","9acab88c":"forwardFunds(uint256,address,address)","9acade7e":"testFailTransferDisableNotEnabled()","9acae9fc":"createChannel(bytes32,uint256,uint256)","9acb1506":"_createMeme(string,uint256,address)","9acb1ad4":"right37(uint256)","9acb3824":"getHorsesInStud()","9acba2af":"durationSeconds()","9acbdcab":"updateNoteButContent(uint64,uint16,bytes12)","9acd07b5":"closeChannel(uint8,uint256,bytes32[4])","9acd5e0e":"getGuestNotes(address,address)","9acdc0e3":"setCommunityTokensHolder(address)","9acf603b":"token_wallet_address()","9acf6ff4":"distributeRemaining()","9acfb1a8":"getCCH_edit_25()","9ad0a5ac":"addWhitelisted(address[],uint8[],uint256[])","9ad0c86c":"IouRootsToken(uint256,address,string,string,uint8)","9ad10d79":"PELOMemberIDMap(uint32)","9ad1b348":"getKNCRateRange()","9ad1c999":"setdevFeeAddress(address)","9ad25a68":"COSMOTokenERC20(uint256,string,string)","9ad26744":"removeAuthorizedAddressAtIndex(address,uint256)","9ad4eccf":"sentTokensToFounder()","9ad4f658":"CATToken(address,address,address,uint256,uint256)","9ad4f98e":"BlocksureInfo()","9ad55220":"getPrivate()","9ad5be7b":"setPlayValue(uint256)","9ad73f20":"runPluginSigned(address,uint40,uint40,uint128,uint256,uint8,bytes32,bytes32)","9ad74f81":"setAllowTransferGlobal(bool)","9ad7ebc3":"specialPoolsRate()","9ad89ac4":"settleCancel(bytes32[8],bytes)","9ad8b5b7":"addAttachmentToCollectible(uint256,uint256)","9ad900d6":"get_first_asset_document(bytes32)","9ada7a4c":"NumberTaken(uint256)","9adba14b":"logStr(string)","9adc15ef":"ShaBi()","9adcb5eb":"acceptBet(uint256,uint8)","9add2ad9":"MIN_ETH_TRANS()","9ade76f4":"VestingCreated(address,uint256,uint256)","9aded5dc":"deathData_a6()","9ae000c6":"WeedToken()","9ae0140c":"removeRoleCapability(uint8,address,bytes4)","9ae06672":"getDailyTimeLeft()","9ae066b0":"foundationDeposit()","9ae082a4":"PooShitToken()","9ae120dd":"closeZoneTeller(bytes2)","9ae13375":"groupDates(uint256)","9ae1a635":"Q500()","9ae1c4f8":"mintToken(uint256,int256)","9ae21121":"lastowner()","9ae2835c":"balanceOfIssuer(address)","9ae38844":"newMembers()","9ae466bf":"recipientETH()","9ae4e388":"ChangeClientTokenAccount(address,bool)","9ae51a1f":"getTeamlistSupportInTournament(uint256)","9ae568b1":"CreateSEEDS(address,uint256)","9ae5dc91":"setNTToken(address)","9ae6303d":"getHatchDurationByTimes()","9ae6309a":"currentMintableTokens()","9ae65eea":"addProposal(string,string,string,address)","9ae6892b":"transferOwnershipToken(address)","9ae6b186":"bZxTo0xV2Contract()","9ae6cac7":"SemainToken()","9ae6ef15":"getCumulativeIncome()","9ae7a909":"multiPartyTransfer(address[],uint256)","9ae8886a":"p()","9ae8ac3c":"TRADING_STARTED()","9ae8b6a1":"WMCToken()","9ae980a8":"setMinWager(uint256)","9ae9d383":"getnotice()","9ae9ff6a":"withdrawBeforeVoting(uint256)","9aea020b":"sellDeadline2()","9aea5485":"revealMove(uint256,uint8,uint8,string)","9aeb14a5":"sumHardCapPreICO()","9aeb5947":"payToCharm(string,uint256)","9aeb69a2":"withrawWin(address,uint256)","9aebdf7e":"updateJackpotLeft(uint256)","9aece83e":"set_manager(address)","9aecea62":"finalizeIPO()","9aeceb1d":"transferBallance()","9aecfb8a":"Etharea()","9aed58c6":"_destroyRobot(uint256)","9aed6ac9":"registerPresaleContributor(address,uint256)","9aedabca":"valueOfShares()","9aedb1f1":"setVotingQuestions(string,string)","9aee046b":"callOracle(uint256,uint256)","9aeea806":"MARKET_CHANGE(address)","9aef0c6c":"privateSaleClosingTime()","9aef319f":"closeBlacklistSwitch()","9aef8999":"removeWhiteList(bytes32)","9aefff29":"totalSupplyPreSale()","9af003bd":"ChangeConversionRate(uint256,uint256)","9af041aa":"currentSaleStage()","9af1d35a":"fees()","9af1ef32":"offerHelp(address,address)","9af22f9c":"Shiner()","9af25d07":"releasedRoundCount()","9af26b78":"finishMinting(bool)","9af28b65":"NEXT_POT_FRAC_TOP()","9af2b100":"Permissions()","9af2cad2":"CryptoCoin()","9af32035":"addIcoPurchaseInfo(uint256,uint256)","9af3352d":"updateGuReferral(uint256,uint256,uint256)","9af3b527":"getOwnerOfCardsCheapestWager(address,address)","9af4afb3":"BlueOs()","9af4b5c8":"isOwedFreeReferralPack(address)","9af55773":"minSumICOStage6USD()","9af605cb":"__proxy(address,bytes,uint256)","9af6489d":"CheckTree(address)","9af64d80":"previousstageplayer1()","9af6549a":"beneficiaryWithdraw()","9af75b29":"tokensMintedForOperations()","9af88ebd":"_createOpinionSet()","9af8c4ba":"respond(uint256,address,bytes)","9af8f5de":"totalEDUSLeft()","9af917f4":"addRentable(bytes32,uint256,uint256,uint256,uint256)","9af95a4b":"dateBonus(uint256)","9af9f012":"wavesAgent()","9afa3dc7":"ADVISOR_STAKE_THREE()","9afb24ab":"setCLIForGas(uint256)","9afb93cb":"buyTicket(uint256,string)","9afbe49a":"tokenAmountOfPeriod(uint256,address)","9afcfba3":"getBurnRequestStatus(uint256)","9afd46a3":"closeTurnByHand(uint32)","9afd8b1d":"LiteBoxToken(address,string,string,uint256,uint256)","9afd9d78":"rollback()","9afe340f":"OasisToken()","9afebd18":"contract_finish()","9afec0ae":"ESOPLegalWrapperIPFSHash()","9aff301f":"FightClockAuction(address,uint256)","9affa42d":"increaseApprovalBatch(address[],uint256[])","9b013aee":"getBidPrice(uint256)","9b01c7ac":"getFishIdByAddress(address)","9b02e258":"changelp12(address)","9b03a211":"transferPresaleTokens(address,uint256)","9b04564a":"proposeTeamWithdrawal(address)","9b046ed3":"getCharacterTraits(uint256)","9b05535f":"checkpointBlock()","9b059309":"GoshenCoinCash()","9b05934c":"calculateSecretHash(uint256,bool,bytes32)","9b0646f6":"wadmin_setContrAddr(address,address)","9b06e9f5":"seTJackpotPersent(uint256)","9b087b2d":"totalTransferred()","9b08a22f":"allowTransfer()","9b08ace1":"bonusSecondWeekPeriod()","9b092f73":"safemul(uint256,uint256)","9b09768a":"maximumPoolPurchase()","9b09dfbd":"addArrayItem(address,string,string,address)","9b0a4764":"AkirasToken()","9b0a541e":"LogAllowedToAddress(address,bool)","9b0a5e67":"buy(string,uint256,uint256)","9b0aac15":"maxTokenSupplyPublicSale()","9b0ac9b0":"refundTime()","9b0b5bb2":"MIN_BANKROLL()","9b0b9c07":"acceptBankDraft()","9b0c1e51":"BONUS_MAX_DURATION()","9b0d1b2c":"getSpawningFor(address)","9b0ec5ae":"newSeed()","9b0ee7b7":"updateAirdropEndTime(uint256)","9b0f2510":"placeLong(address[2],uint256[8],uint8,bytes32[2])","9b0facaa":"existIdBeforeVersion(bytes32)","9b10394c":"IsOnSale(uint32)","9b10e9f7":"rawDetailsOf(bytes32,bytes32)","9b110f4b":"GayPersonalAdsToken(uint256,string,uint8,string)","9b11503e":"PUBLIC_SALE_START()","9b121e7c":"wethWithdraw(uint256)","9b12664f":"referralMinimum()","9b129181":"LTE()","9b12a4a1":"setCanDisburseMultipleTimes(bool)","9b132392":"createTrainer(string,uint16)","9b139504":"addPlayer(string,address,uint256,uint256)","9b13d209":"buyGuardianRune(uint256,uint256,uint256,uint256)","9b15ef2e":"END_PRESALE_TIMESTAMP()","9b16250a":"finishSign(uint256)","9b164ce3":"TestApprove()","9b173d57":"withdrawPolicy(uint256,uint256,uint256,address)","9b17b2dc":"checkWeather()","9b181e39":"_isAccepted(address,address)","9b18d79a":"one_ether_usd_price()","9b19251a":"whitelist(address)","9b19a92b":"year1LockAddress()","9b1a78c0":"ClaimGMT(address,uint256)","9b1a9b23":"destinationAddress80()","9b1ad792":"destroyToken(address,uint256)","9b1b0ab3":"buyingEscrowAddress()","9b1b615e":"pool(uint256,uint256)","9b1b8f62":"_gapOfSquareSum(uint256,uint256)","9b1bb323":"initContract(address,address,address)","9b1cbccc":"finishDistribution()","9b1cdad4":"postBounty(uint128,uint256,string,uint256,uint256,uint256[8])","9b1d767f":"fstTotalSupply()","9b1d8032":"clz32(uint32)","9b1d834c":"genPot_()","9b1dd3e5":"pullRipCord()","9b1e3825":"approveFundTransferToSupplier(address)","9b1f46cd":"allMilk()","9b1f70d1":"BET_RELEASE_DATE()","9b1f9e74":"_burn(uint256)","9b1fe0d4":"isApprovedInvestor(address)","9b21003b":"notPauseable()","9b2112c7":"ShopDexToken()","9b217f90":"getVestingTime(address,uint256)","9b21929a":"TOTAL_SUPPLY_BOTTOM_BOUND()","9b227a97":"ETH_TLD_LABEL()","9b22c05d":"test(int256)","9b234a9e":"tokensByWavesTx(string)","9b248798":"_InsufficientFunds(address,uint256,uint256)","9b24b3b0":"getRoot(uint256)","9b250f76":"clientInit()","9b252b7e":"t3Token()","9b256f46":"changeRoundBlock()","9b25e6f1":"ReservedTokensDistributed(address,uint8,uint256)","9b263eca":"providerContract()","9b267540":"unblockTokens(address,uint256)","9b26bae3":"AliciaToken(string,string,uint8,uint256)","9b276964":"STARTING_BAT()","9b27bf3a":"setWhiteListStatus(bool)","9b2843e2":"randomDNA(uint256)","9b285582":"ChangeIp(bytes32,bytes32)","9b28db50":"getWalletId(address,bytes32)","9b28f644":"setupFunctionalAddresses(address,address)","9b28f75a":"reclaimBalanceTokens()","9b29a295":"Payable(address,uint256)","9b29cb23":"getDailyPayment()","9b29f133":"userCancelActiveGame(uint256)","9b2a9d19":"origDev()","9b2aab1d":"frozenAccountOf(address)","9b2b0031":"updateDescriptiveInformation(address,string,string,string,string)","9b2b89d4":"UCAL(uint256,string,uint8,string)","9b2bdc20":"claimAllowanceOwnership()","9b2cb5d8":"minAmount()","9b2d2cbd":"orePrice()","9b2e5d32":"claimItems(uint256,uint256)","9b2ea4bd":"setAddress(string,address)","9b30a187":"nextWave()","9b30c7db":"changePortalAddress(address)","9b311b17":"averageMinerSalePrice()","9b322b7e":"HuandeToken(uint256,string,uint8,string)","9b3235bf":"getAbel()","9b33093f":"createNew(address,address,uint256)","9b332a91":"payDate()","9b33d7b3":"createAuction(uint256,uint256,uint256,uint256,bool)","9b33f055":"cancelSubscriptionOffer(uint256)","9b343342":"getRandomPrice(uint256)","9b343525":"highestContribution()","9b343e35":"createChildContract(string,uint256,uint256)","9b347f42":"teamVesting2Years()","9b34ae03":"winningOutcome()","9b350e12":"isEscaping(uint32)","9b351087":"cancelTreeSell(uint256)","9b3544f6":"postAssertion(uint128,uint256,uint256,uint256)","9b35928f":"RXBbitToken()","9b35b35a":"lockTs()","9b36057c":"registerGame(address)","9b3662bf":"currentParticipants()","9b367370":"confirmBlackFlag(uint256,bool)","9b36c3bc":"setMaxTotalAmount(uint256)","9b3725e8":"stageGenomes(uint8)","9b39caef":"COIN_PER_ETHER()","9b39f377":"getAnimalByIdVisibility(uint256)","9b39f9bf":"remainingTokensForSale()","9b3a300b":"SNK(uint256,string,string)","9b3a36c0":"calculateTokensWithBonus(uint256)","9b3b24ba":"VESTING_AMOUNT()","9b3ba79f":"maxAllocation()","9b3bc6fb":"checkERC20Balance(address)","9b3cbdf6":"CrowdSale(address)","9b3d17b1":"tokenSPUsdCentPrice()","9b3dfce0":"isPoDStarted()","9b3e28cc":"TokenReceivingEchoDemo(address)","9b3e9a48":"changeFreezeTime(uint256,bool)","9b3ee16e":"initialize(address,address,uint256,uint256,address,address,address,address)","9b3fd75d":"beginGame(uint256,address,address)","9b3fdf4c":"EVMSCRIPT_REGISTRY_APP()","9b409510":"creditAdvertiser(address)","9b41a9c5":"SedoPoWToken()","9b41b00b":"Sorus()","9b426e62":"assignTester(address)","9b44cb3c":"lastTrade()","9b46301e":"playersPerRound()","9b46461e":"getAnimalIdAgainstAddress(address)","9b46a71c":"setContractCap(uint256)","9b4778e4":"get_arbits_sale_open()","9b480435":"setPublicPlacementNum(uint256)","9b487f3f":"_forwardTransferFromToICAPWithReference(address,bytes32,uint256,string,address)","9b49413c":"GetItemInfo(uint256)","9b4a6bdb":"test_spamVoting()","9b4a7fe9":"setCCH_edit_17(string)","9b4b2d77":"processOffchainTokenPurchase(address,uint256)","9b4b973d":"acceptSettlement(uint256,uint256)","9b4bb9f0":"schedulePriceUpdatesFixed(uint256[])","9b4c1290":"_getFishPrice(uint16,uint16,uint8,address)","9b4c1902":"getGovtApplicationByIndex(string,uint256)","9b4c7b70":"redemptionFundTotal()","9b4d54fc":"startCrowdsale2(address)","9b4d9ecc":"setGrowCost(uint256)","9b4e533e":"isLastWithdraw(address)","9b4f19c6":"getMonths()","9b4f1ecb":"initialCost()","9b504387":"controllerTransfer(address,address,uint256)","9b51e35a":"getSchemePermissions(address,address)","9b52cacc":"ListingCreated(bytes5,uint256,uint256,uint256,address)","9b539a17":"setEncryptKey(string)","9b53a396":"calcKicks(uint256)","9b53d87c":"isManagerEnabled(address)","9b550e55":"nextMineId()","9b563fa3":"save(uint256,string,string)","9b566564":"withdrawAirdrop(uint256,bytes)","9b56730d":"compoundInterest(uint256,uint256,uint256,uint256)","9b5696b0":"notCollectedAmountAfter24Hours()","9b56d6c9":"getCollateral(address)","9b5719a6":"setSalesContract(address)","9b58316a":"EBANKTOKEN()","9b58b463":"retire(address,address)","9b58e46b":"createProduct(string,bool,uint256)","9b5906e5":"getLifeCoin()","9b598caf":"pastProposalTimeRules()","9b59ffd7":"verifyGame(bool)","9b5a2e13":"setBadgeGiver(address)","9b5a66e6":"insertInPlace(uint8[],uint8)","9b5adea2":"setMinter()","9b5b094f":"ANMOToken()","9b5b4019":"EtherWild()","9b5b969f":"transferSub(address,uint256)","9b5c0b5e":"burnPerweiYearly()","9b5cc9f4":"transferOwner1(address)","9b5cfcdd":"account1Address()","9b5d2e78":"TPI()","9b5d7d0b":"addBalanceReplenishment(uint256,uint256,uint16,bytes32,uint256)","9b5d8e63":"Multiplexor()","9b5e5d8c":"newCustomFutureLottery(uint256,uint256,uint256,address,uint256)","9b5f8abb":"getAllSponsors()","9b5fde7d":"payOut(uint256,string)","9b601c4d":"getQueryPrice(string)","9b60a443":"payto1()","9b612a1b":"freezeStaking(address)","9b619d3b":"_deleteAllPackedRevisionBlockNumbers(bytes32)","9b61cf09":"MOBILITYCREDIT()","9b624e7b":"setRound(uint256)","9b632829":"refundAll(address)","9b6349a8":"TokenDCCB(uint256,string,string)","9b63d0f4":"core(bool)","9b63eb4b":"getTicketsByGameIndex(uint256)","9b666d7a":"cos(int256)","9b6687ac":"getNumPositionProduct(bytes32,uint8,string)","9b671604":"proposeVoter(bytes32)","9b678bfc":"calcRates()","9b67bfa3":"fiatValue(uint256)","9b6806c9":"getCompanyShareholders(uint256)","9b68c992":"SubmitSecretBet(bytes32)","9b69608f":"read_dgx_inventory_balance_ng()","9b69de79":"transferLockAmount(address,uint256)","9b6a2b2f":"spriteOwningHistory(address,uint256)","9b6a6709":"presaleMint(address,uint256)","9b6aa1fa":"TransferData(address,address,uint256,bytes)","9b6b838c":"reinvestment_share()","9b6c5283":"createPool(string,uint256,uint256)","9b6c56ec":"debt(address)","9b6d86d6":"adminSetRegistrationDisabled(bool)","9b6d96c5":"create(int256,int256,int256)","9b6dbc8a":"closeShop()","9b6e407d":"setPercentUnfrozenAfterBuyPerPeriod(uint256)","9b6ec1cb":"HerbsChainToken()","9b7143eb":"creditsClawbacked()","9b71a7c9":"addAddressToRole(address,string)","9b71dec3":"getVineyardCount(string,address)","9b727e80":"CNiteToken()","9b73a5d9":"hasTwoYearWithdraw()","9b743cbd":"allocated18Months()","9b7502c3":"getLastAuditExtradata(address)","9b769ce3":"JsCoin()","9b76a25c":"transferFee(address,address,address,uint256)","9b76c1de":"team3LockEndTime()","9b76fbd6":"_recordPlatformFee(uint256)","9b771346":"ImportTestB()","9b772524":"partner1_signed()","9b7750f1":"addBranchInEpisode(uint256,uint256)","9b77c21a":"getClaimStatus()","9b77d69f":"addTagByModuleType(uint8,bytes32[])","9b7812ff":"add_quote(bytes32,bytes32,uint256,uint256)","9b782070":"TSSECOND()","9b786d68":"profitSharing(address,string)","9b788752":"trade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,bool)","9b78cf9c":"medalFreeze(address,uint256,uint256)","9b7c08b8":"ERCToken(uint256)","9b7c288f":"lastDeploy(address)","9b7c5517":"committ_payment(uint256,uint256)","9b7d83e7":"porcoToken()","9b7defe3":"returnTokensFromHoldAdvisorsAddress(uint256)","9b7e5531":"ownershipDeadline()","9b7edbdb":"buyLimit(uint256)","9b7eeb12":"setScrapMinEndPrice(uint256)","9b7ef38c":"BatchUtils()","9b7f1687":"iUventaCoin()","9b7faaf0":"lockOver()","9b80c9e8":"payMoneytoOwner()","9b815057":"changeMakerDAO(address)","9b818ace":"SLChainToken(uint256,string,uint8,string)","9b819d38":"getNowTime()","9b81c8d3":"updateMeterValue(uint256)","9b82171f":"houseTotal()","9b828609":"reclaimContributionWithInterest(address)","9b82abdb":"LogBought(address,uint256,uint256,uint128)","9b831dcb":"RateUpdate(uint256)","9b8342d4":"getPlayerDividendByRound(address,uint256,uint256)","9b836d1a":"_payout(address,uint256)","9b8430eb":"distributeRevenue(uint256,uint8,uint8)","9b850322":"escrowDecision(uint256,uint256)","9b855a85":"releaseEQUITokens(bytes32,uint8,bytes32,bytes32)","9b85b9c9":"createDrug(bytes32,uint256)","9b85bc85":"CocacolaToken()","9b865999":"InitialOwnerAddress()","9b86975d":"ANemoiSaleContract()","9b880fee":"registerVestingSchedule(address,uint256,uint256,uint256,uint256)","9b8831df":"hasArtist(bytes32)","9b8906ae":"saleEnded()","9b894703":"maxTickets()","9b8a74f0":"cancelOffer(address)","9b8abe0b":"thousandtimes()","9b8b03a2":"strongHands(address)","9b8b365d":"deathData_a5()","9b8b6037":"findModuleVersionByAddress(address)","9b8b7160":"setPreFundingtokens(uint256)","9b8d1dd4":"CARDANOCLASSIC()","9b8d3064":"setFinance(address)","9b8d34d9":"addAgreement(bytes32,uint256,address[])","9b8da66c":"getEthFundDeposit()","9b8eb288":"setPercentWeiDividend(uint256)","9b8eb7b4":"getSocialAccountByIndex(uint256)","9b8f2493":"updateBurnBal(uint256)","9b8f5acf":"CyberChainToken()","9b8f5d4a":"setTilePosition(uint16,uint8,uint8)","9b8f7113":"dateSoftCapWasReached()","9b8fdf1b":"cancelExpectedPayment(bytes8)","9b901d00":"_createTeamSale(uint256[9],uint256,uint256,uint256,address)","9b9073e4":"allocationPool()","9b9111ee":"commonConfigure(address,address)","9b914973":"prebuyPortionTotal()","9b91f9be":"Gol()","9b922d97":"setCoinsaleactive(bool)","9b9279ec":"StartRefound(bool)","9b92adf3":"EnableTokenMinting(bool)","9b93aaf4":"addNewLoggerPermission(address,address)","9b945097":"getRandom(address,uint256,uint64)","9b9692f6":"TokensDistribution(address,uint256)","9b96c4ba":"AdvisorPart()","9b96eece":"getBalanceOf(address)","9b973803":"transfer10(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","9b97cee5":"getWorkCount()","9b985b30":"bountyMaxTokens()","9b986550":"getAllForPubKey(bytes32)","9b98a94b":"getLockTokens(address)","9b991d9b":"votingInfoTeam()","9b9958af":"getAllCardsClaimed()","9b99a8e2":"reserveTokenCount()","9b9a09a6":"HackContract()","9b9a236b":"SuperToken()","9b9a47e3":"getlastDividendPoints(address)","9b9b0b87":"mainICOFourthWeekEndTime()","9b9ba572":"oraclize_query(string,string[3])","9b9be9cb":"mainSale_TokesSold()","9b9bedf8":"getContractCreated()","9b9cc2ca":"getPrivateSaleAgentAddresses()","9b9ce1bc":"sendTokensBulk(address[],uint256[],uint256[])","9b9d0364":"_setFeeStructure(uint256,uint256,uint256)","9b9d2cc8":"RESERVED_TOKENS_ADVISORS()","9b9e07e1":"TeamtokenRelease3()","9ba11c0a":"coinunits()","9ba1a7d8":"preValidation()","9ba30c3b":"Healthcoin()","9ba319bf":"detangleQuanticCloudIOTData()","9ba33ab3":"refundLeftOverWei(uint256,uint256)","9ba3c2e0":"advisersAddr()","9ba3d8cf":"updatePromoFishCommission(uint256)","9ba4d4ee":"investedETH()","9ba4dbc2":"USDBTC(uint256)","9ba4eb5f":"SPINFundDeposit()","9ba58333":"AspirationCoin()","9ba5b4e9":"getEventHashes(bytes32[])","9ba65fff":"addNewcard(uint256)","9ba73d43":"deregisterCustomer(address,address)","9ba89492":"getNumAccounts()","9ba896cc":"refundTokensSale(address[])","9ba8975f":"changeFundsKeeper(address)","9ba8e37d":"withdrawFromToken(address,uint256)","9baa504e":"unrestrictedMint(address,uint256,uint128)","9bab0da3":"EVACASH()","9bab3988":"DongriToken(uint256)","9babdad6":"removeShareholder(address)","9bac6e8d":"currentMinter()","9bac8602":"testFailAddBalanceAboveOverflow()","9bacc97c":"specialAddress(address)","9bacf1ed":"createSynthesizingAuction(uint256,uint256)","9baddd98":"sendBountySupplyToken(address,uint256)","9bae56da":"getEstimatedRound(uint256)","9baeac78":"TOKEN_SUPPLY_PRESALE_LIMIT()","9baf7ffb":"etherToSendBankroll()","9bafd01a":"freeStorage(address)","9bafd22b":"DocumentCertoChainContract()","9bb00ae3":"ledgerCount()","9bb01b5f":"ElcoinDb(address)","9bb04895":"nominalValue()","9bb0e4df":"getUint(int256,bytes32,string)","9bb0f599":"hasToken(address)","9bb186d2":"MatchingMarket(uint64)","9bb192fd":"getVotes(uint32)","9bb1dbea":"commonWithdraw(uint256)","9bb1fd66":"force_stop()","9bb2ea5a":"setMaxValidators(uint256)","9bb32be3":"challengeFinality(uint256)","9bb3bcaa":"setArrIntField1(int256[])","9bb5239a":"CheckPrize(address,uint256)","9bb5c96c":"isContributorsRewarded()","9bb5ce30":"participationFee()","9bb5d450":"getMonsterCount()","9bb5f901":"UCToken()","9bb603bb":"create(string,string,uint8,string,bool)","9bb639a8":"changeTokenCostInEth(uint256)","9bb6831f":"millCap()","9bb74bbd":"tokensSoldToInvestors()","9bb848e7":"isRunningIco(uint256)","9bb84cd0":"addSellTokensRequest(address,string,uint256,uint256)","9bb8b563":"POKCC()","9bb8ec22":"SmartAdvancedCoin(uint256,string,string)","9bb8fde4":"startTimeStage1()","9bb90467":"initTokenAndBrackets()","9bbba3a8":"getTokensOnSale(address)","9bbc156b":"AllLock()","9bbc574a":"closeUser(address)","9bbdb25a":"getPartners(address,uint256)","9bbeafc1":"setMarketFees(bytes32,uint16,uint16,uint16,uint16,bool)","9bbedbbc":"deliver(address,address,uint256)","9bbfa582":"Lambotoken()","9bc0fd25":"setBlocklancerContractHolder(address)","9bc13360":"standardrate()","9bc2bc71":"createEvent(string)","9bc30adb":"upgradeBalance(address,uint256)","9bc3135b":"buyoutDividendPercentage()","9bc33b8a":"MediatedTransactions_TransactionHeight()","9bc52a39":"logClassic(string,uint8)","9bc53cec":"Moontrail()","9bc5689d":"NUM_OF_CHOICES()","9bc61d06":"MeetupContract(string,string,uint256,uint256,uint256)","9bc64cc8":"saiTap()","9bc6b571":"ChangeExtension(uint256,bool)","9bc6d815":"BestCountTokens(uint256)","9bc6f0ec":"createChildDeposits(uint256)","9bc706e8":"publishedCountOf(address)","9bc72d5f":"worstCaseRateFactorInBps()","9bc742fe":"setStepOneLockEndTime(uint256)","9bc85302":"burnUserTokens(address)","9bc896f9":"orderCancel(uint256)","9bc8e9ee":"setMintingDec(uint256)","9bca3596":"Ubecoin()","9bca8a1e":"setTableTypesSize(uint256)","9bcb8dff":"BallzToken()","9bcc2b27":"ctrlZee()","9bcc9123":"rejectNegotiation(address)","9bccfe49":"actionsCount()","9bcdd9e8":"forgetCube(address)","9bce51e3":"sendCrowdsaleTokens(address,address,uint256)","9bcef169":"getLeaderboard(string)","9bcf497b":"setUserPaybackPool(address)","9bcf7352":"setEnableInternalLock(bool)","9bcf8ca2":"addresses(uint256,uint256,uint256)","9bcf9ea2":"PIVOT()","9bcfcee8":"minting(address,address,address,address)","9bd03774":"TokenContractImpl(uint256,uint8,address,address)","9bd0a967":"isEndsWithHpb(string)","9bd1ff8b":"tokenFallback(address,address,uint256,bytes,string,uint256)","9bd26234":"contrubutedAmount(address)","9bd2af03":"trent()","9bd2d912":"ZipflaxToken()","9bd33457":"totalOnDeposit()","9bd3651b":"Authenticate(uint256,address,uint256)","9bd41f7c":"createToken(bytes32,string,string,string,string,string)","9bd4d455":"addMember(string,address,string,uint256,uint256)","9bd4e13e":"bettor_reward(address)","9bd4e925":"CROWDSALE_ETH_IN_WEI_FUND_MIN()","9bd5679e":"getCurrentICOExpirationTime()","9bd6030c":"nbagame()","9bd658d9":"whoOwnsYou()","9bd69528":"addToKyc(address)","9bd695b0":"hasRequiredSignaturesToValidate()","9bd6a4de":"initPublicityAddr()","9bd702e4":"sellCrab(uint256,uint256)","9bd7d688":"checkAncestors(uint32,address,uint64,uint64,uint64)","9bd80dcf":"calculateMasked(uint256,uint256)","9bd8e081":"gunsFundDeposit()","9bd90aae":"maxTokensToCreate()","9bd99195":"multiAccessChangeOwner(address,address)","9bd9bbc6":"send(address,uint256,bytes)","9bda8678":"externalDeposit(address,uint256)","9bdbb4c7":"market_WithdrawBid(uint256)","9bdc6523":"setUserWhiteListContract(address,bool)","9bdce046":"DICE_HIGHER()","9bdd070d":"withdrawTokenToDefault(address,address,uint256,uint256,uint256,address)","9bdd7cdb":"forceRelease(bytes32)","9bde88f0":"getcan(address)","9bdf5a7c":"Zenix()","9bdf6f62":"soldTokenCount()","9bdff8eb":"oracleB()","9be07908":"left79(uint256)","9be08a4e":"NCPPrivate()","9be0f105":"OxChainNetwork()","9be0fc75":"toggleDrop()","9be1eab7":"setContractStakeToken(address,address)","9be1fcee":"BankOwner_DisableConnectBankAccountToNewOwnerAddress()","9be2385a":"depositOldTokens(address,uint256,address)","9be2faed":"isSchemeRegistered(address,address)","9be2ff64":"setAllowPlayer(bool)","9be3b286":"endOffering()","9be4d15e":"split(bytes32,uint8,uint256)","9be50784":"drawBenz()","9be56c67":"support(uint256,uint256)","9be572f6":"getTotalUsers()","9be5ad78":"_saleState()","9be5b3b1":"MetadollarOption()","9be6178e":"acceptBet(bytes16,bytes16,bytes16,bool)","9be6d404":"destructSelf(address)","9be7f1dd":"buyerfee()","9be88a01":"_rotateLeft(bytes32)","9be8a212":"FoundersFund()","9be95517":"_createRandomMonster(uint32)","9bea62ad":"restore(uint256)","9beaa524":"getActivityName(uint256,uint256)","9bead36f":"resolveEntityAddressAndOwner(address)","9beb6c6b":"_saleFinalized()","9bed31e4":"setParameters(uint32,uint256,address)","9bedb2c7":"MyReferrals()","9bee3365":"sayYes()","9bee757b":"requestExecution(bytes,uint256)","9beebe20":"setTrustedTransfer(bool)","9beef73f":"stageDistributed()","9bef0c47":"getUserPictureByWallet(address)","9befa8b4":"DisqusBot()","9befd45a":"payFee(bytes32)","9bf0093c":"LIV()","9bf037e5":"BaseCrowdsale(address,address,address,uint256,uint256,uint256,uint256)","9bf070b5":"ethRaisedWithoutCompany()","9bf08a06":"joinArena()","9bf1c389":"stage_1_add()","9bf1f148":"requestAudit(address,bytes32,uint256)","9bf22189":"Validated(string)","9bf2926d":"Proposal(address,uint256,string)","9bf2ab46":"preSalesEndDate()","9bf30bac":"handleIncomingPayment(address,uint256)","9bf34e30":"ecrecover3(bytes32,uint8,bytes32,bytes32)","9bf39dce":"contributionTime()","9bf4c5c5":"destroyedNinjas()","9bf677e4":"phase_1_rate()","9bf68006":"testControlSetNotTransferableNotOwner()","9bf6b0a8":"withdrawForFiveStep()","9bf6deaf":"ChangeEmissionRateCoefficient(uint8)","9bf6eb60":"mintTokensExternal(address,uint256)","9bf74ae0":"periodICOStage1()","9bf7ef63":"verifyMultiSig(address,bytes32,bytes,uint256,uint256)","9bf865d0":"numberToAddress(uint256,address)","9bf8df7d":"recoverLost(address,address)","9bf97bd9":"get_deployed_forwarders()","9bf97e74":"BNN()","9bf9cd26":"PreSaleSold()","9bfa1f33":"ORDER_FILL(address,address,address,bool,uint256,uint256,uint256)","9bfa835b":"privateMin()","9bfa882e":"updateAddress(address,address)","9bfaa24b":"startTradable(bool)","9bfafdc2":"ERC223Transfer(address,address,uint256,bytes)","9bfb9717":"additional_incentive()","9bfb9752":"setTime1(address,uint256)","9bfba3c6":"ico2cap()","9bfc80fc":"TopSciFiVoter()","9bfd8d61":"totalStaked(address)","9bfdce3e":"deal(address,uint8)","9bfdd1bb":"setSchema(string,bytes32,string,uint256,uint256,uint256,uint256)","9bfdf68d":"requestLoans(uint256[],bytes32[])","9bfe171a":"STASToken()","9bfe7bd5":"getNumOrdersByOwner()","9bfeda53":"_getRewardTokenAmount()","9bff209d":"softSub(uint256,uint256)","9bff662c":"notify_payment_acceptance_request(uint256)","9c001bcc":"TOKEN_SHARE_OF_BOUNTY()","9c0051db":"setProfitTransferTimeSpan(uint256)","9c007973":"resolveDispute(bytes16,address,address,uint256,uint256,uint8)","9c01e1f5":"addNFToken(address,uint256)","9c01fdaa":"PimmelToken()","9c03b04f":"testItStoresAValue()","9c03f17f":"sencToken()","9c03facb":"sold(uint256)","9c041ebd":"create(address,address,address)","9c043783":"eachUnfreezeValue()","9c049dd0":"hydroStakingMinimum()","9c04e4e7":"pre_sale_end()","9c04ece9":"lastBlock_f7()","9c05093b":"setTeamTokensWallet(address)","9c05ba60":"getIndexName(bytes32)","9c066eab":"seeRaised()","9c0770fe":"ZIL()","9c07b2cd":"resetTotalSales()","9c080f5d":"showBalance(address)","9c08606c":"lockedDays()","9c08d549":"startICO(uint256,uint256)","9c0953cf":"setProducer(address,address,bool)","9c09a64c":"claimSMR()","9c09b32c":"ProcessTransaction(uint256)","9c09bb4e":"getBestMatch()","9c09c3bb":"attestForIdentity(address)","9c09c7c6":"addGuessWithRefund(int256)","9c09c835":"enableWhitelist(address[])","9c09f869":"PixelSelling()","9c0a4bbc":"AlwaysFail()","9c0b7c08":"terminateFunding()","9c0baa2d":"_getRate(uint256)","9c0bd57c":"withdrawDragons()","9c0c2238":"withDrawEther()","9c0cc30c":"getAllArtworks()","9c0d010e":"_checkOpenGame()","9c0df4f2":"blessings()","9c0e3f7a":"write(uint256,uint256)","9c0e7d66":"leftoverTokensBuffer()","9c0ee65b":"Hold(address,uint256,address,address,address)","9c0f16ed":"tokensOfTeamAndAdvisors()","9c0fc1e4":"AIC()","9c117f0f":"get1(uint256)","9c118238":"withdrawBalanceFromServer(address,uint256,bytes)","9c1193ea":"GreeterA(bytes)","9c121aff":"LogClaim(bytes32,address,uint256)","9c121b6d":"meltHorseShoe(uint256,address)","9c1230c1":"amount_stages()","9c128493":"Lol1CoinCoin()","9c12ca21":"setGroupBounty(address[],uint256)","9c12deab":"isVendor(address,address)","9c135572":"documentsIds()","9c147688":"bulkMint(uint32[],address[],uint256[])","9c14c77b":"getBuyTime(uint256)","9c14e25b":"DonQuixoteToken(address)","9c1500f0":"registerMany(address,uint256,int256,uint256,bytes,address,bytes)","9c15b047":"getInitialOwners()","9c15b04b":"showDividendsAvailable()","9c15be0b":"left65(uint256)","9c161d1a":"setNextImagePart(address[16],uint256,uint16,uint16,uint16,uint256[])","9c16667c":"getAnswer()","9c166d31":"LukaToken()","9c172f87":"EthVentures4()","9c1747e5":"addRewardPercentage(uint256)","9c1817e4":"Saddle_Limit()","9c19aa9f":"setOrderSupportCancel(uint256)","9c19f170":"TotalRaised(uint256)","9c1a056f":"visitLength()","9c1a32fe":"setTake(uint256)","9c1b9408":"preMultisigEther()","9c1b987c":"setComment(uint256,bytes3,string)","9c1b9c1b":"assignTokens(address,uint256,uint256,uint256,uint256)","9c1cb7cf":"PaymentStatusBlockNum(address)","9c1d8fa2":"GPN(uint256,string,string,address)","9c1d9790":"sendBatchCS(address[],uint256[])","9c1e03a0":"crowdsale()","9c1f020a":"sendCrowdsaleTokens(address,uint256)","9c1f332f":"returnLastBuyerIndex()","9c1f6133":"registerVIP()","9c1fcc4c":"logicAddress()","9c2062ad":"RISK()","9c2108eb":"transferGoldFromHotWallet(address,uint256,string)","9c211755":"RequstOwnership()","9c225b33":"teamAndAdvisorsAllocations(address)","9c2412a2":"monarchyStartReward()","9c24654c":"presalestartTime()","9c24ea40":"setLinkToken(address)","9c24eedb":"upvote(uint256,int256)","9c24fc55":"presaleBalances(address)","9c250dd8":"etherTransfer(address,uint256)","9c253011":"print(int256,address)","9c255312":"addressETHDeposit()","9c25d975":"packLocation(uint64,uint64,uint64)","9c2625fd":"TEAM_TOKENS0()","9c269c34":"TBL4Token()","9c27a6f4":"buyTicket(uint8,uint16[],address)","9c27ea08":"setNextLotteryTTMTokenId5(uint64)","9c27ff9b":"calculateFEE2Distribute()","9c286837":"devCut()","9c293792":"release_all(address)","9c2a7b89":"setTokenInfoHeritor(address,address,uint256)","9c2b1a95":"getManagementFee()","9c2c1b2b":"addDelegateSigned(address,uint8,bytes32,bytes32,bytes32,address,uint256)","9c2cdd5a":"MULTISIG_TKN()","9c2e29c6":"LocalLambosEscrows()","9c2ea2ec":"setEthExRate(uint256)","9c2f0067":"EPIToken(address,uint256)","9c2f4092":"DEVP()","9c2f5f8f":"closeCurrentGame(uint256)","9c2f7a43":"getCrystal(uint256)","9c2f88fa":"CoinBundleToken()","9c2fa55d":"buyFirst()","9c30936f":"removeCertificationDocumentFromSelf(bytes32)","9c31200b":"oraclize_query(uint256,string,bytes[1],uint256)","9c315684":"periodPreICOStage()","9c31c5ec":"setItemsContract(address)","9c323436":"getFixedEndTime(uint256)","9c33b66e":"checkAvailableTokens(address,uint256)","9c34a15f":"c(uint256,uint256)","9c34ae54":"setICODates(uint256,uint256,uint256,uint256,uint256,uint256)","9c351fec":"SNDToken(address,string,string,uint256,uint256)","9c36e141":"defaultTimeLock()","9c3723df":"windowBonusStep2()","9c38019b":"verifyProofOfMembershipInternal(uint256,bytes32[],bytes32,bytes32)","9c3807e6":"STARTING_STRIPPERS()","9c388d30":"LogAccountAmount(address,uint256)","9c392e5c":"VirginMToken()","9c39857b":"setTeamAdd(address)","9c3b936f":"killBalance(uint256)","9c3b9aa3":"MundoGamerToken(uint256,string,uint8,string)","9c3bcd65":"deliverPresaleFuelBalance(address,uint256)","9c3c7b2c":"transferredPresale()","9c3c97a1":"prohibitFreeze()","9c3db309":"getCurrentMiningDifficulty()","9c3e0f3f":"icoStarts()","9c3ed1ae":"unitsUserCanBuyLimit()","9c3f1e90":"orders(bytes32)","9c3f7ca2":"acceptOffer(uint256,uint256,bytes32)","9c3fe721":"finishedIssuerMinting()","9c402944":"sendAVR(address,uint256)","9c4063ce":"WALLET_T8EX_TEAM()","9c409e4d":"VoteOnTransfer(address)","9c40ea5c":"setGRForGas(uint256)","9c41adfd":"withdrawDepositById(uint256)","9c41e591":"XGoldToken()","9c4261b9":"VOLUME_EXTRA_BONUS_CONDITION()","9c43d950":"registration(uint256,uint256,uint256)","9c43eb54":"snapshotTimestamp()","9c44f090":"AlquilarBici()","9c45510d":"FootBallCoin()","9c472c70":"rateSecondWeek()","9c473bb2":"setTokenName(address,bytes32)","9c4780d8":"currentRoundNumber()","9c481c9e":"crowdsaleContractAddress()","9c489edb":"setNewExchangeAddress(address)","9c492b9e":"raisedFromFiat()","9c499b53":"getFeesAvailableForWithdraw()","9c4abe06":"getEthOfferPrice(uint256)","9c4ae2d0":"deploy(bytes,uint256)","9c4b653d":"sendFundsToMsgSender(uint256)","9c4b9c8a":"getFreezeTimestamp(address)","9c4baf27":"Skywalker(address,address)","9c4bcaa5":"setMinBuyPrivate()","9c4c557c":"startSale(bool)","9c4ca8cb":"IChain(address,uint256,uint256)","9c4de81f":"havven()","9c4e0f52":"setMaxTokenSellAmount(uint256)","9c4e3788":"earlyInitProjectSupply()","9c4eda5c":"balanceA()","9c4fc41a":"getWineCount()","9c4fc563":"_findParticipant(uint256)","9c50450f":"amountToCreate()","9c50e7ca":"tgeDateStart()","9c513bdd":"BwinCoin()","9c526380":"getUserTotalCredit(address,address)","9c52a7f1":"deny(address)","9c536640":"confSetupMixer(bytes32,uint256,uint256,uint256,uint256)","9c544e72":"removePending(address,uint256)","9c54b91f":"setApprovalCount(uint256)","9c54df64":"addAdmins(address[])","9c55519b":"optionsConversionDeadline()","9c561a42":"Wallet4()","9c566cad":"cards_start(uint256)","9c5686db":"isERC821()","9c579839":"QUOTE()","9c57d584":"verifyFingerprint(uint256,bytes,int256)","9c58b753":"getWriterId(bytes32)","9c58be11":"claimMyToken()","9c58c509":"buyIcoToken2(uint256)","9c591412":"lifeReserveWallet()","9c5b33ae":"wb()","9c5bbc89":"setApprovedAddress(address)","9c5c53b3":"lockBonusTokensClaim(uint256)","9c5d5e98":"JACKPOT_WINNER()","9c5d7030":"reimburseGas(uint256,address,uint256,uint256)","9c5d7291":"PhoneCoin()","9c5de58b":"startRC()","9c5e078f":"createBBODocument(bytes32)","9c5e108c":"_getFreezeTime(uint8)","9c5e9023":"confirmBeneficiary()","9c5fafa4":"balanceOfComisionHold(address)","9c6034a7":"sendIfNotForked()","9c60839e":"mintBonusTokensForGames(int256,uint256)","9c623683":"setWinner(uint256,address)","9c62622d":"IHate0xBTC(string)","9c632c77":"getServiceTokenAddress()","9c6393f2":"TokensWithdrawn(uint256)","9c639db4":"UltiCoin()","9c63dae5":"depositorCurrency(address)","9c644221":"PRICE_STAGE_ONE_BONUS()","9c66452e":"checkTime(bytes32,bytes32,uint256)","9c665819":"Talent()","9c66fe00":"priceOfLandmark(uint256)","9c6735c7":"ProfitRate()","9c675eaa":"ownerAddr()","9c67f06f":"registryStarted()","9c67f2fb":"returnEth4Sender(uint256)","9c681f86":"totalTokenTransfers()","9c6891c5":"set_bountyPercent(uint256)","9c68bd60":"payPledge(uint256)","9c695a7b":"_isInStage(uint256)","9c69763b":"setICOManager(address)","9c697750":"getRemainingLimit(address)","9c6a5bca":"RiptideCoin()","9c6a97ee":"deleteMyCat()","9c6c3439":"burnReputation(uint256)","9c6e199a":"sendTokensManually(address,address,uint256)","9c6e1d46":"emitJobCanceled(uint256)","9c6f87e9":"getPseudoRandomNumber()","9c700b70":"withdrawOwnerEth(uint256)","9c707dcf":"_mthToVouchers(uint256)","9c7081df":"prestige()","9c709343":"split(bool,address)","9c70b899":"KYC_ETH_LMT()","9c715535":"confirmPendingChange(address)","9c71d169":"OfferCancel(uint8)","9c71efef":"STARTING_CraigGrant()","9c71fda4":"WALLET_LB_RESERVED()","9c7264d7":"fillOrder(address,uint256)","9c73048b":"distributeCastleLoot()","9c732203":"DoDev(uint256)","9c737e8f":"fundPot()","9c7387c7":"finishContribution()","9c73ff7d":"DANK()","9c7409b0":"_getProtectionParams(uint256,uint256,uint256)","9c75089f":"Tresdk()","9c755f2f":"stuff()","9c756200":"ContractOwnerWithdraw(uint256)","9c756ec9":"PREICO_PERIOD()","9c76a6ac":"buybackPrice()","9c775e1f":"delegateApprove(address,uint256)","9c787ab2":"YUNXINToken(uint256,string,uint8,string)","9c7912ff":"setXzlkcjqowhoqhwoihsiaoquweizxoiuo(uint256)","9c792938":"estimate(uint256)","9c79af26":"issueExchangeRate(address,address,address,uint256,uint256,uint256)","9c7a39e6":"doCustomAirdrop2(address,address[],uint256[])","9c7ab767":"numSubscribers()","9c7b3c45":"TextToken()","9c7b3d79":"ARTISTCOIN()","9c7b7a2d":"SingleSourceIdentity()","9c7beb8a":"mintingAgents(address)","9c7c2498":"OnChainOrderBookV013b()","9c7c722b":"rename(string,string)","9c7dcdeb":"hostAccount()","9c7e6e6e":"checkRokBalance(address)","9c7e8a03":"addParticipant(address,address,uint256)","9c7eaac5":"makeTrade(address,address,uint256)","9c7ebb30":"SellTokens(uint256)","9c7ed6cb":"AgiCrowdsale(address,address,uint256,uint256,uint256,uint256,uint256)","9c81806d":"WithdrawSpecialEth(uint256)","9c81a5f6":"getVestingsCount(address)","9c821ac4":"testFailsIfReturnLessThanMin()","9c82f2a4":"setSwapper(address)","9c830beb":"setStateHolding()","9c839bdd":"nextWithdrawDayCommunity()","9c83a1e3":"deleteDeposit(address)","9c83b0a1":"ValeoTestToken()","9c841c16":"checkCorrectRate(bool,uint8)","9c84d1f7":"News()","9c84eebe":"ERC20Token(uint256,address)","9c851ebc":"new_entry()","9c85a28a":"infoMessage()","9c8615ac":"is_entity(address)","9c865645":"calculateFactorFlushDifficulty(uint256)","9c86b241":"createPromoArt()","9c88b7bf":"enableNewPurchasing(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","9c88cbb6":"getCurrentBracket()","9c893d73":"LinkCoinToken()","9c89a0e2":"getReputation(address)","9c89a10a":"presaleOwner()","9c89ddb5":"addCourse(string,address)","9c89e828":"BidSubmission(address,uint256)","9c8a5a56":"bribedCitizen()","9c8aeedd":"breakIdMaintenance2(uint256,address)","9c8bb5d0":"confirmBoardScore(bytes32,bytes32)","9c8bcd6d":"WbtToken()","9c8e1d50":"getChipValue()","9c8f8569":"Scc()","9c8f94bd":"widthrawBondFunds(address)","9c8f9f23":"removeLiquidity(uint256)","9c90224b":"assertEq1(bytes1,bytes1,bytes32)","9c908f61":"acceptTokens(address,uint256,uint256,uint256,uint256)","9c91ae20":"getGeneration(uint40)","9c91dd56":"paymentContract()","9c9205b6":"Token(address,address,uint256)","9c926061":"HashProject(address)","9c92bfda":"testReceiveSubmittal()","9c93a52f":"SALE_TOKENS_SUPPLY()","9c9421c3":"Testtoken()","9c94e6c6":"notice()","9c960cbb":"setAyantDroitEconomique_Compte_6(uint256)","9c97114b":"s(bytes)","9c977e43":"requestOraclizeBalance()","9c978442":"TransferToAllAccounts()","9c981fcb":"getString(string)","9c9a1061":"buy(bytes32)","9c9a2365":"getFungibleTokenAddress()","9c9a4b72":"TokenVesting(address,address)","9c9b1170":"setoraclelimitgas(uint256)","9c9b2e21":"addReward(address)","9c9b8fcc":"ALC_FOUNDATION_ADDRESS()","9c9c344c":"getTotalUpdates()","9c9cc12a":"getCatRelease(uint256)","9c9d07c1":"STARTING_DINO()","9c9de4dc":"INT(address)","9c9e2752":"SBGCrowdsale()","9c9ecedb":"InitialArray()","9c9ef44a":"setDiscountValueOn()","9c9ef978":"addDataToList(bytes32,bytes32,bytes32,bytes32)","9c9fb68b":"GetGamblerChoices(address)","9c9fe2a4":"FundsClaimed(address,uint256,string)","9c9fe83a":"setBA(bytes32,address)","9c9ff934":"ETH_HEROCOIN()","9ca0e5e1":"setGoldBonus(uint256)","9ca15d59":"oldInviteAddr()","9ca2b9e4":"AdvancedDeposit(bytes32,bytes32)","9ca3669d":"cancelCommissionerAuction(uint32)","9ca3c29c":"getCost(string)","9ca423b3":"referrals(address)","9ca44515":"ketqua()","9ca5454e":"distributes(uint256)","9ca5f4a7":"SafeERC20Helper()","9ca67a6e":"notapproved()","9ca6e670":"apply(uint256,uint256,string)","9ca74595":"BobMarleyCoin()","9ca75320":"searchNode(address)","9ca77f3c":"kingdomsByNumber(uint256)","9ca7c912":"ownerTime()","9caaa154":"setLuckPrice(uint256)","9caaa7f4":"get_this_balance()","9caab55a":"ParticipantAgent()","9caabfac":"dateEcoRelease9()","9cad74b0":"randomNumber(uint8,uint8)","9cadb159":"settleChannel(uint256,address,uint256,uint256,bytes32,address,uint256,uint256,bytes32)","9cae6100":"addAward(string)","9cae9e03":"getPropertyInfo(uint8)","9caeab45":"periodICOStage5()","9caf34c4":"getBalanceEth()","9caf9695":"paleyer2show(uint8,uint8,uint8,uint8,uint8)","9cb02e8c":"delayPhaseEndBy(uint256,uint256)","9cb04d18":"newPresale()","9cb157d9":"VNT()","9cb15a94":"FreeCoin(uint256,string,string)","9cb1e9fe":"cubicContract()","9cb21f6d":"ImperialCredits()","9cb230ec":"Lockup(address)","9cb29034":"CCECOIN()","9cb2b69b":"getCreated(uint256)","9cb31079":"setLowLimit(uint256)","9cb33309":"BasicTokenMock(address,uint256)","9cb35327":"ceilDiv(uint256,uint256)","9cb42db4":"PDS()","9cb481ea":"getBountyAmount(uint256)","9cb4b31c":"tokenTimelockAddress()","9cb64a2d":"debtor()","9cb6a504":"addColor(string,string)","9cb6ed7e":"escape(address)","9cb6fc77":"confirmUpgrade()","9cb74ab6":"mgmtInvestProject(address,uint256)","9cb7595a":"getBridgeInterfacesVersion()","9cb75b2f":"sendBonusEgg(address,uint256)","9cb78df8":"minSuccess()","9cb7de4b":"setHandler(address,bool)","9cb8a26a":"selfDestruct()","9cb931f9":"setReferralPromille(uint8)","9cb998dc":"increase(bytes32)","9cb9c14f":"Issuance(address,uint256)","9cba3559":"globalAmounts(uint256)","9cba60a7":"bitmask_check(address,uint256)","9cba713e":"reserveTreasury(uint256)","9cbad951":"withdrawAllTokensFromBalance()","9cbafcb6":"Pharamore()","9cbb165e":"isOnBorrow(uint256)","9cbb9460":"fetchOrdersForMerchantByAdmin(address)","9cbc2d62":"get_member_info(address)","9cbc87a3":"bytes32ArrayToString(bytes32[])","9cbcfcc7":"calculateGotTokens(uint256)","9cbd695f":"show(uint256,uint256)","9cbd7da5":"resumeICO()","9cbdffc6":"unblock()","9cbe5efd":"currentRoundId()","9cbf1b85":"exchangeRateAt()","9cbf73a9":"purchaserAddresses(uint256)","9cbf9e36":"createToken()","9cc04ea0":"newRecord(uint256)","9cc0c5e3":"experty_io()","9cc1c97b":"test_threeValidEqAddress()","9cc24569":"ExKnox(address,address)","9cc28aa0":"BdpOwnershipStorage(bytes8)","9cc2bcc6":"AhieldCureToken()","9cc33024":"setPresidenteDeMesa(bytes32,uint256,uint256,uint256,bytes32)","9cc3b949":"Bookmark()","9cc429dc":"getBattlesCount()","9cc477b2":"createFashion(address,uint16[9],uint16)","9cc4a319":"CarToken()","9cc4d3dd":"convertNumSec(uint256[],uint256[])","9cc4da3b":"WHAuthorizeAddress()","9cc579af":"MarketJob(address[],uint256[],uint256[],address,address,bytes)","9cc5dd95":"_removeOwnersAproves(address)","9cc73a6f":"raiseDay3()","9cc74299":"withdrawFromManager(uint256,address)","9cc7d917":"earlyBirdsAddress()","9cc7f708":"balanceOf(uint256)","9cc8295a":"EnoughClaims(uint256)","9cc84564":"envelopeCounts(address)","9cc9299e":"killSwap()","9cc946ee":"OlivToken()","9cc9b86d":"disableService(address)","9cca1c64":"getNonFungibleIndex(uint256)","9cca7ac3":"QueueDemandesEnCours()","9ccaec98":"getAuctionInfo(uint40)","9ccb6e8d":"SentToContractor(uint256,address,uint256)","9ccbbc6a":"minimumPowerUpSizeBabz()","9cccaea9":"StreamityContract()","9cccb272":"BatchPaint(uint8,uint256[],bytes3[],uint256[])","9cccd2a4":"getSumAmountOfSuccessfulSteps()","9ccd0b51":"getCountCourse()","9ccd7d86":"setWinery(address,address,bool)","9ccdd994":"Pume(uint256,string,string)","9ccf1a68":"prepareURL()","9ccfceed":"MANHATTANPROXY10THAMSTAVE()","9cd0126a":"gemHpConversion()","9cd01605":"exchangeAddress()","9cd04996":"DiscountedPreICO(uint256,uint256)","9cd08464":"transfer_eth_from_contract(address,uint256)","9cd08bae":"CevacToken(uint256,uint256)","9cd0c511":"depositMintAndPay(address,uint256,uint256)","9cd106a8":"cancelRecurringBilling(uint256)","9cd19074":"createKey(bytes32)","9cd1a121":"delegateTransfer(address,uint256,address)","9cd2021c":"mintRefs()","9cd22211":"getPlayerGameInfo(uint256,address)","9cd23707":"setTransferable(bool)","9cd3cb5d":"withdraw_token(address)","9cd417d7":"rejectCurrentValidation()","9cd43690":"GENTATOKEN()","9cd4fb47":"Tier_Classic()","9cd5c9a8":"setAssetWallet()","9cd70235":"setAmountToClaim(address,uint256)","9cd758d0":"setPOOL_edit_2(string)","9cd77457":"createInactivePreMintedEdition(uint256,bytes32,uint256,uint256,uint256,address,uint256,uint256,string,uint256,uint256)","9cd84ead":"APPToken612()","9cd994b4":"updateAuctionTime(uint256,uint256,uint256)","9cda1ec5":"setDistributor(address,bool,uint256)","9cda5a12":"calcPoseBits(uint256,uint256,uint256)","9cdacdb3":"Setup(address)","9cdaef4d":"_set4()","9cdaf438":"ARCCToken(address,uint256)","9cdb4fe8":"addEvidence(bytes32,uint256,bytes32,uint8,bytes32,bytes32)","9cdbaa21":"tokenTransferLocker()","9cdbc070":"addVoting(uint256)","9cdd2e76":"getHeroLocation(uint256)","9cdec2bb":"getCompte_18()","9cdee922":"RushCoin()","9cdf1872":"getOut()","9cdf4dd3":"Token(address,string,string)","9cdf8a1f":"WTBNToken()","9cdfa3df":"getAddrForPrivilege(address)","9ce04e35":"enableInvestorTransfer(address)","9ce21f3c":"fundingWalletAddress()","9ce2c7f2":"AumentaQuantitaVoti(uint256,address)","9ce318f6":"withdraw(uint8[],bytes32[],bytes32[],bytes)","9ce31fe1":"StudToken(uint256)","9ce3961f":"nextVersionAddress()","9ce3f461":"UP_winBets()","9ce51c7c":"sendNewTalentsAndPartnerships()","9ce682bd":"BetFromTransaction(address,uint256)","9ce80efc":"test_twoInvalidAssertFalse()","9ce840d4":"withdrawNotATokens(address)","9ce8fc4e":"LogForkSigned(uint256,bytes32)","9ce962ca":"payWallet()","9ce9e380":"_burnAllArgs(address,uint256)","9cea127f":"CMTTT()","9ceb5c6d":"icoBonus1EndDate()","9ceba90b":"startWeekFive()","9cec2789":"gettags(address)","9cecc80a":"setReserve(address)","9ced0e9b":"initialTime()","9ced5c29":"enableNode()","9cede14c":"checkAndGetSendersID()","9cee1773":"Mednus()","9cef2a6a":"addLand(address,uint256)","9cef8873":"reclaimLand(int256,int256)","9cef9cfe":"isNumBlack(uint8)","9cefa50b":"winner(uint256,bytes32)","9cf17d5f":"ScamCoin()","9cf21342":"AnimeCoin()","9cf21d90":"ETCH3dV()","9cf2c727":"sumHardCapICOStage7()","9cf3123b":"sellWolkEstimate(uint256,address)","9cf3566d":"promotionAllocate(address,uint256)","9cf4124f":"enableContinuousDelivery()","9cf48365":"getInvestedToken(address)","9cf488ad":"sendPlayerBack(uint256[])","9cf4910c":"preDistriToAcquiantancesEndTime()","9cf4cb1e":"_getVotes(uint256,uint256,uint256,address)","9cf5453d":"bid(address)","9cf55cfb":"sampleBoolRetTrue()","9cf5c613":"setVerified(address,bool)","9cf60b86":"addRefBalance(address,uint256)","9cf66013":"whitelistRegistrantsFlag(address)","9cf66997":"clearLand(int256[],int256[])","9cf6f1eb":"CBVO()","9cf78527":"UAPToken(address)","9cf8ccfd":"currentPlayers()","9cf9342e":"createContract(bool,string,bool)","9cf94943":"whitelistAdd(address[])","9cf9d4c0":"setPOOL_edit_9(string)","9cf9e3ab":"TokenReleased(address,uint256)","9cfa0f7c":"maxTokensToBuy()","9cfa750f":"isParticipant(uint64,address)","9cfad128":"calculateFee(address,bool,bool,uint256,uint256)","9cfcab47":"NovoToken()","9cfd5dc4":"validPurchase(uint256,address)","9cfda697":"setColorsX4(uint16[4],uint256[20],uint256)","9cfdd04d":"BCN()","9cfdfe42":"AXIS()","9cfe42da":"addBlacklist(address)","9cfe6c86":"count_tokens()","9cff53e0":"nDeposits()","9d000e78":"VUP_PER_ETH_PRE_SALE_RATE()","9d00ffa5":"isMessageValid(bytes)","9d01e730":"EarlyEndTimeChanged(uint256)","9d038cd3":"TEST1()","9d042f87":"dTimeoutCurrentStage()","9d0506ae":"checkData(bytes)","9d05414f":"Referral(address,address)","9d0617f9":"_send(address,uint256)","9d063ed8":"FIFSRegistrar(address,bytes32)","9d069353":"getAngel(uint64)","9d06a1d5":"removeFromWhiteList(string,address)","9d0714b2":"tgeSetLive()","9d079b18":"acceptProposal(bytes32)","9d07b653":"_createUnit(uint256,uint256,uint256,uint256,address)","9d07ff80":"ln_fixed3_lnr_18(uint256,uint256)","9d083222":"becomeMember()","9d0880a3":"transferUnsoldTokens(address)","9d09390b":"isValidAuthority(address,uint256)","9d097471":"getUserBounty(address)","9d09798f":"DemurringFee(address,uint256)","9d09f8e5":"changeRebackRate(uint256)","9d0b2c7a":"pendingStake(address,uint256)","9d0c0c35":"generateCrabGene(bool,bool)","9d0c1e6f":"walletETH()","9d0cfc2c":"closeDepositSubRound()","9d0d0a5a":"getTotalToggleGameDivsProduced()","9d0d9f1c":"azatipsToken()","9d0df9b5":"getPOOL_edit_11()","9d0e0cd3":"getTotalTAOsCount()","9d0e5871":"shipping(address)","9d0effdb":"revokePermission(address,address,bytes32)","9d0f17c8":"unsoldTokenIssued()","9d0f8763":"cancelOrderByAdmin(uint80,bool)","9d0fb699":"tokensToBeClaimed()","9d106954":"_getUserMinersAt(address,uint32,uint32)","9d1080c5":"UnilotToken()","9d10fda8":"escrow_fee_denominator()","9d118770":"destroy(uint256)","9d119a4e":"EmergencyUnPause()","9d119a7b":"getDepositTxMap(string)","9d11aaaa":"transferFeePercentage()","9d11f09f":"getTxAmountKWh(bytes32)","9d129afd":"prevBlock()","9d12e775":"zec()","9d13156c":"claimRefundOwed(uint256)","9d134185":"setauctionsystem(uint256,uint256)","9d139ff2":"LajokiCoin()","9d140fa2":"inPreSale2Period()","9d144f8a":"_preventedByNationalityBlacklist(address,uint256)","9d145866":"loadRate(uint256)","9d14f134":"getRepo(bytes32,string)","9d153495":"withdrawRefund(uint256)","9d1672c4":"getAffiliateRate()","9d16aca6":"changeExchangeContract(address)","9d170c5d":"getRef(string)","9d176556":"setDistConfig(address[],uint256[])","9d189473":"calculateAndMintTokens(address,uint256)","9d18e405":"approveAndBuyAffiliated(uint256,address,uint256,bool,address)","9d1a9ff9":"rebatePeriod_()","9d1acead":"periodPresale()","9d1b0fd1":"createProduct(bytes32,string,bytes32,bytes32)","9d1b464a":"currentPrice()","9d1b8945":"requestedRedeem(address,uint256)","9d1bbd7e":"CancelRoundAndRefundAll(uint256)","9d1be930":"autopayfee()","9d1c3f03":"isMaximumPreFundingGoalReached()","9d1c4d42":"buyAnalysis(uint256,uint256,address)","9d1d14e0":"setEtherExchangeLikeCoin(uint32)","9d1ddca5":"fiveYearGrace()","9d1e0d48":"buy(address,string,uint256,uint256,uint256,uint256)","9d1e351c":"totalBonusToken()","9d1e641b":"CROWD_WEEK3_BONUS()","9d1eb451":"MAT_CROWDSALE_SUPPLY_LIMIT()","9d1ebfd6":"nextReleaseAmount()","9d1eeb97":"redemptionBurn(address,uint256)","9d1f2800":"doPush(address,uint256)","9d1fd89c":"getFirstBorrowAgreementTool(address,address)","9d1ffed9":"_certify(bytes32)","9d2044e1":"setContrAddrAndCrwSale(bool,address,address,address,bool,bool)","9d20467a":"changeTiming(uint256,uint256)","9d209048":"getNode(address)","9d20b314":"TotalpresaleSupply()","9d210369":"resetMaxBonusThreshold()","9d210bdd":"getStoriesLength()","9d21328f":"sharedExpense()","9d21dd78":"getGameTime()","9d2235e7":"_leapYearsBefore(uint256)","9d22c693":"before_test_method_increaseTimeBy30000()","9d23c4c7":"tokenRegistry()","9d240cf2":"Workshop()","9d245238":"getWinNumbers(string)","9d248477":"BeaverCoin()","9d248e08":"burn3(uint256,uint256,uint256)","9d24c49f":"_payloadOffset(uint256)","9d24e482":"theWinner()","9d255663":"EthMonoPoly(address)","9d2620bf":"RealEstateCouponToken()","9d2668d4":"setPurchased(address,address,uint256)","9d273b20":"refundStatus()","9d2754a9":"createTokenToTax()","9d2777f4":"IntermediateWallet()","9d277a49":"unregisterPublisher(address)","9d2870c3":"LPAIToken()","9d29255b":"setCSCERC721(address)","9d29cac4":"getMonsterClass(uint32)","9d2a1eab":"GrantAdded(address,uint256)","9d2a8cf0":"unwhitelistAddress(address)","9d2ab46d":"BUZZToken()","9d2ae623":"depositJackPot()","9d2affd5":"transferFrom(address,address,address,address[],uint256)","9d2be721":"insertTopic(bytes15,address,bytes32,bytes15)","9d2cc436":"RESERVE()","9d2cd67c":"collect_main_fee()","9d2d912e":"futureDevLock()","9d2e4777":"vestingTransfer(address,uint256,uint32)","9d2ec188":"setFeeParams(uint256,uint256)","9d2f1cbb":"changeStakingFees(uint80,uint80,uint80,int256,uint80,int256,uint256,int256,uint80,uint80,uint256)","9d2fc3c8":"adjudicate(uint256,uint256)","9d2fcb8c":"setInvestmentAddress(address)","9d2ff29c":"ICDSupply()","9d30584c":"setHard_Cap(uint256)","9d327229":"fechVoteResultForCandidateByStage(address,uint256)","9d340b71":"buyTokensfor82()","9d3565ce":"transferOr(address)","9d35dcac":"NewUser(uint256,address,address,uint32)","9d36c500":"freeAnimalsLimit()","9d38cdbf":"OwnedUpgradeabilityProxy(address)","9d38cea3":"stopPreIco()","9d390d83":"setIsWeiAccepted(bool)","9d3995c2":"setHeroPost(address,uint256)","9d3ac6d5":"getBuyerContribution(address)","9d3acf23":"isResolvedForDefendant(uint256)","9d3aee8d":"st4ckHeight(uint256)","9d3c015e":"PChannel(address)","9d3c3b5d":"getArrayHashMarketItem(bytes16)","9d3c663f":"isBreakingCap(uint256,uint256,uint256,uint256)","9d3cc187":"changeSetRateAddress(address)","9d3d1d82":"userSponsorshipsPred(address,uint256[],uint256)","9d3d741c":"testAboveLength()","9d3d9b4d":"FETCOIN()","9d3de95a":"getPortfolioInfo(address,uint256)","9d3e069c":"StartDraw()","9d3e1ab8":"walletRemaining()","9d3ec1a7":"getMarriageDetails()","9d3f2e5f":"stakeEthForGas(uint256,address)","9d3fae04":"applyAuditorsCheckUpdate(address,address,uint256)","9d3fe4c2":"AGAVETHER(string,string)","9d4022c8":"OrderStatisticTree()","9d406a13":"getLocksLockedFor(address,uint256)","9d408b93":"gasBefore_()","9d4095cc":"getAmbientTempException(bytes32)","9d41198e":"startnewround()","9d41a9af":"getOccupation(address)","9d41d6fc":"testInitialBalanceWithNewRGXToken()","9d421ea7":"claimTeamToken()","9d42829a":"getGoldInfoDocumentation(address)","9d42d1a9":"sendEvent(uint256,bytes32)","9d4323be":"drainToken(address,uint256)","9d4327a0":"stockBuyCertainOrder(uint256,uint256,uint256,uint256)","9d433c71":"sharesOfSPS()","9d442102":"BuyRocketForSale(uint32)","9d44ac4f":"permissionExists(uint8,address)","9d44d93b":"delegateTransferAndCall(uint256,uint256,address,uint256,bytes,address,uint8,bytes32,bytes32)","9d44fca2":"computeEthConstant(uint256)","9d451c4d":"right77(uint256)","9d45b9d2":"soldTokensPreIco()","9d45d077":"raiseSellOrderMatched(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int160)","9d463520":"lastMintTime()","9d463b99":"addPool(uint256,uint256,uint256)","9d471837":"updateTextForHolder(bytes32,bytes)","9d478656":"sendp(address,uint256)","9d484693":"payouts(address,uint256)","9d4936f9":"MINING_OUTPUT()","9d4971b7":"getOrderLength()","9d499363":"faucetTokenAddress()","9d4ab2a3":"setInvestAgent(address)","9d4aba7c":"getTimestamp_()","9d4b1239":"tokensDistributedCrowdsale()","9d4c162d":"executeProposal(bytes32,int256)","9d4c5451":"minTokens()","9d4c662c":"sell_id()","9d4c7737":"creditStatus()","9d4c8eed":"getChildCount(address)","9d4cc8ad":"Poppins()","9d4cf268":"isERC165Interface(bytes32)","9d4d8db3":"Happy()","9d4e85ce":"getUserDeposits(address,address)","9d4ea0f3":"canMove(uint16,uint8,uint8)","9d4ff8ad":"enter(string)","9d5176fd":"getPremiumFactors(bytes32)","9d51d9b7":"setMaxBalance(uint256)","9d52f74b":"getFreezeGap(bytes32)","9d532041":"createCrowdsale(address,address,uint256,uint256,uint256,uint256,uint256,bool,uint8)","9d535056":"punterWaiting()","9d5367c5":"KIDToken()","9d53827f":"MAX_TRANSFER()","9d53f19e":"getInvestorInforMin(uint16)","9d54c79d":"notary()","9d54f419":"setUpdater(address)","9d55fba7":"updateCommission(uint256)","9d564d9a":"unlockTokens(address,uint256)","9d56998d":"my_message()","9d5708ff":"myTulipsBatched(uint256,uint16)","9d575582":"depositToken(address,uint256,address)","9d5779ce":"Site(string)","9d5839e3":"getFirstMilestone()","9d585f7f":"loanAmount()","9d58a5b6":"unitExists(uint256,uint256)","9d58aa41":"changeRestrictedtStatus(address,address,bool)","9d58b15d":"addMember(address,address)","9d59011e":"setAmount(uint128)","9d599cbf":"hashClaimable(bytes32)","9d59beb1":"listTokenFee()","9d5c6061":"getMsgGas()","9d5c6e20":"setPrivateSaleEndDate(uint256)","9d5c7be8":"collectionCountsOf(address)","9d5de12e":"STQPreSale(address,address)","9d5eab46":"setItemOption(address,uint256,uint256)","9d5eb078":"buyTemplate(uint256)","9d5efb6b":"tokenContractSupply()","9d5f2422":"createDifficultyOracle(uint256)","9d5f5cd3":"mktValue()","9d61193a":"passoverStartTime()","9d617fae":"pendingFills(address)","9d619dad":"currentTournamentBank()","9d61e624":"hardcapInEth()","9d625241":"powermayorCutPercentage()","9d62f07b":"BlockGrainCoin()","9d636359":"initialMarketSales()","9d63848a":"tokens()","9d64a5e5":"newFoundationCandidate()","9d64d474":"cancelExplorationByIndex(uint256)","9d652118":"presaleclosingTime()","9d66a9cd":"getDetail(uint256)","9d66e913":"callStcWithBto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","9d67b404":"addChunk6ToWhiteList()","9d68521a":"revokeOperatorTranche(bytes32,address)","9d69d5c6":"CERTIToken()","9d69fdff":"Ecometh()","9d6a4d77":"allotToken(uint256)","9d6abbcd":"unlockedEscrow(bytes32)","9d6abe4f":"getLink(address)","9d6ad799":"computeTokenWithBonus(uint256,address)","9d6adeaf":"HitToken(string,string,uint8,uint256)","9d6b74f8":"DISPLAY_CLASSIQUE_ET_VIDEO()","9d6bf036":"setIsLimited(bool,string)","9d6d22b5":"ProgrammerdaddysToken()","9d6d2321":"dividendsFull(address)","9d6d78e4":"chunk3IsAdded()","9d6d8598":"depositTokens(bool,uint256,address)","9d6dcf53":"Smilebitbuy(uint256,string,uint8,string)","9d6e0c22":"setBroker(address,address,uint256)","9d6e4eaa":"ReleasableToken(string,uint256,string,uint256)","9d6eaad5":"returnTokensToOwner(string)","9d6f78c1":"LineToken2()","9d6fa618":"requestTransferOwnership(address)","9d6fac6f":"cooldowns(uint256)","9d6fb020":"isRefunding()","9d70085e":"cap3(address)","9d707d03":"resetAuctionStart(address,address)","9d7150fe":"isAffiliateValid(address)","9d7233d4":"MIN_CONTRIBUTION_WEIS()","9d72d8d3":"luckyBuy(uint8)","9d733f0c":"submissionPrice()","9d735286":"forwardFunds()","9d7354c0":"BuyHandler(uint256)","9d735fc5":"RewardPoint()","9d73cecc":"validatePeer(address)","9d7437b8":"WALLET_ADVISOR()","9d74b37d":"getBool(address,bytes32)","9d74b959":"test_basicWithAssertBeforeThrow()","9d74fb7c":"ContributionMock()","9d75c113":"_joinCDP(bytes32,uint256)","9d7616a5":"preEtherCap()","9d76ea58":"tokenAddress()","9d770e49":"abstractResolver()","9d773a1b":"catsForSale(uint256)","9d77bd68":"luCat()","9d77e4f8":"getChainFees(uint256)","9d77f85a":"buyCollectible(uint256,uint256,int256)","9d79468a":"claimRewardTo(address,uint256,string)","9d7a63e9":"changeDripAmounts(uint256,uint256)","9d7acf74":"BluechipToken()","9d7b5621":"numberOfTokenId()","9d7b7636":"Neymar()","9d7b8887":"addAddressMappingProposal(address)","9d7bf73c":"PLUS()","9d7d6667":"multipliers()","9d7da479":"mintTokens1(int256,address,uint256,uint256,bytes32)","9d7e2730":"issueCoins(uint256,address)","9d7e6ca8":"setResponseAddress(address)","9d7eb375":"updateUserDetails(string)","9d80ac4d":"WithdrawedEthToWallet(uint256)","9d80c818":"addressCount()","9d815818":"validReleasedToken(uint256)","9d8168f0":"removeManyWhitelist(address[])","9d821c1a":"setManualSaleFlag(bool)","9d827eb9":"CreationFeeChangedEvent(uint256)","9d8374b4":"removeFromBlacklist(address,address)","9d837ccd":"ETH_CAP()","9d83ee1b":"getAllCardDatas()","9d84934d":"mintStartYear()","9d84ae69":"readAddress(bytes32)","9d856bdc":"queen()","9d858a80":"Pheonix(uint256,uint256)","9d85fca3":"findIndexFromRandomNumber(uint32)","9d866527":"Strange()","9d86ad52":"CloseIfBug()","9d86fd0c":"test_threeTrueAssert()","9d87a373":"transferFromMany(address[],address,uint256[],address)","9d87e7f0":"getWeiAvailableToReturn(address)","9d882b5d":"Sotoin()","9d88584e":"removeFamily(address)","9d888e86":"currentVersion()","9d88f3a1":"setLotteryAddress(address,address)","9d89add1":"createMechETH(uint256,address)","9d89e7d4":"challengeAmount()","9d8a0212":"costOfOneToken()","9d8a18ea":"VT(uint256,string,string)","9d8a8c43":"totalTokenMintedPreSale()","9d8abff3":"miningAttempts(uint256,address)","9d8b0834":"verifyLoanOfferingRecurse(address,address[9],uint256[7],uint32[4],bytes32,bytes)","9d8b157b":"teamCup()","9d8c3994":"giveAllToCharity()","9d8c428e":"addRoundMode(uint256,uint256,uint256)","9d8c7243":"CreateKRM(address,uint256)","9d8c997b":"getInfoByUnionId(bytes32)","9d8ca531":"closeLottery(uint256)","9d8cb45c":"foundationSupplyRemaining()","9d8d22f4":"grantReserveTokens(address)","9d8d911e":"_createCryptsy(uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,address)","9d8dbd20":"remove_kycer(address)","9d8df6dd":"cancelAdoptionRequest(bytes5)","9d8e2177":"UNIT()","9d8ee943":"right71(uint256)","9d8f2b17":"LCAP()","9d8f4c27":"priceUpdateAddress()","9d902fc0":"precisionFactor()","9d913c64":"addTokenLock(uint256,uint256)","9d9231b1":"_unpackLevelValue(uint256)","9d925fc8":"REFUND_RATE()","9d930f02":"newTeamOnEnd(uint64,uint64,uint64)","9d932a93":"validateSignature(bytes,bytes32)","9d94743a":"CND(address)","9d94a8fa":"_thresholdTwo()","9d94c343":"POSV()","9d94dac8":"fightEtherMonster()","9d95f1cc":"addNode(address)","9d963289":"NewLeader(address,uint8[])","9d96be58":"maxMintBlock()","9d96f200":"Factory(string)","9d97bcd7":"allocatePreICOTokens()","9d988d03":"X(address)","9d989b20":"chargeDailyRate(bytes32,address)","9d98cd78":"drawETH(uint256)","9d9a5e1c":"startPrivateICO()","9d9a7fe9":"completed()","9d9ab2d8":"setEtherUsdRate(uint16)","9d9ae444":"StatsReserved()","9d9aeb7f":"setInterestAllocationPercentage(uint256,uint256)","9d9afce9":"claimTokenReserve()","9d9b2e82":"RevenueSharingContract()","9d9b4d20":"DST_R_N_B_PROGRAM()","9d9b5342":"editInfo(string)","9d9bfb02":"throwsWhenNonMultisigDeploysANT()","9d9c9439":"tokenInitialised()","9d9c9a0d":"testControlCreateWithParentParentSameItemId()","9d9ca28d":"isWinner(address)","9d9cc8e9":"TestCrowdsale_Noname()","9d9d432f":"updateGenVault(address,uint256)","9d9db392":"makePayment(address,uint256,string)","9d9dcf81":"getXPL()","9d9fcc72":"checkWithdrawals(address)","9da065cb":"ReddyToken()","9da0c7b1":"nowCanProvideHash()","9da0d7d4":"dutchAuction()","9da0dc0a":"preICOWeiRaised()","9da1814c":"FremenTradeToken()","9da19acc":"isRedemptionReady()","9da1b02a":"createSale(uint256)","9da1bc7b":"updateBearCount(address)","9da26320":"registrations_confirmed()","9da2b791":"assignDNI(uint256)","9da30467":"payForOrderInTokens(uint256,address,uint256,address,uint256)","9da32c14":"Defapacoin()","9da43ef4":"getExtraPoints(uint32)","9da46ee3":"getPool(uint32)","9da59934":"getInbox(address,uint256)","9da5e0eb":"initDaylimit(uint256)","9da67e71":"OpenMoneyPresale()","9da680f3":"adjustRegistrationFee(uint256)","9da69180":"commitVote(uint256,bytes32)","9da78649":"getNewRecordInHistoryRecord(uint256)","9da8be21":"initWallet(address)","9da8e7e2":"createProxy(string)","9da9650e":"Cothereum(uint256,string,string)","9da9df3e":"withdrawContract()","9daa7b46":"STTCToken()","9daa9ecd":"percentAllocationFeeDenominator()","9daaae94":"setClient(bytes32,address)","9dab2054":"priceAt(uint256)","9dab3cd4":"userRight(address,bytes1,uint256)","9dab4607":"ACCEPT_DICE()","9dabff25":"sendReward(address)","9dac83e4":"allowWorker(address)","9dace789":"EOSGold(uint256,uint256)","9dad9382":"closeStream()","9dae2e80":"payoutDonations()","9daf57cf":"getBdpDataStorage(address[16])","9daf77a5":"GetContractStateTerminatedMisrep()","9daf9b6b":"insertNodeAfter(uint256,uint256,address)","9daf9ce3":"computeTotalEthAmount()","9dafb4df":"prizeOwner()","9dafbc13":"initBlock(uint256)","9db02721":"refuseWork()","9db028ab":"getMetadataHistoryLength(string)","9db069d8":"bountyOwner()","9db09a08":"createContractMovie(string)","9db1b8af":"msc()","9db1cafa":"SuccessLife()","9db28672":"isOfferingStarted()","9db340de":"eraseNodeHierarchy(uint256,bytes32[],bytes32)","9db3956e":"setDatabase(string,uint256)","9db40718":"SearchIPR(string,string)","9db4372c":"num_tickets_current_round()","9db4577f":"addListToWhiteList(address[])","9db5dbe4":"transferERC20(address,address,uint256)","9db67cd0":"funcFromC3()","9db70e19":"tokenIdToRank(uint256)","9db7ff9e":"changeGameRuningblock(uint256)","9db834fe":"setColorPink()","9db8d393":"setCostToCancel(uint256)","9db91e78":"insecureMode()","9dbbcca3":"ChangePreICOStart(uint256)","9dbc041c":"requiredBid(uint256)","9dbc4f9b":"participantDetails(uint256)","9dbd1b96":"getRecipient(bytes)","9dbda902":"getHighestMortgageRate()","9dbdfe0d":"LocusOne()","9dbe3501":"LongPlace(address[2],uint256[8],uint256)","9dbf0087":"TokenERC20(uint256,string,string)","9dbf0543":"price_constant()","9dbf5eca":"updateRelayer(address,bool)","9dbf7014":"depositMineral()","9dbfe1b8":"setSaleRate(uint256,uint256)","9dc04184":"allowDraw()","9dc080d3":"angelToken()","9dc10d15":"preAllocatedTokensVestingTime()","9dc11280":"numDataOf(uint256)","9dc1d961":"message(bytes32,bytes32,string,string)","9dc27fe3":"setICOStatus(bool)","9dc29fac":"burn(address,uint256)","9dc2c8f5":"fireEventLog4Anonym()","9dc35799":"updateReading(uint256)","9dc371bd":"ULTRIXCOIN()","9dc42f16":"_removeOwner(address)","9dc43f2d":"newEmployeePoolPromille()","9dc4b9c9":"currentLevel()","9dc4ca42":"getWalletDigest(bytes32,address)","9dc4ef99":"_registerArtist(address)","9dc5b35e":"saveData(uint256,bytes32,uint8,bytes32,bytes32,bytes32,address)","9dc64f8e":"getWidthrawPercFor(string)","9dc6c12b":"TaiwanRepublic(uint256,string,string)","9dc6f173":"LogBidAccepted(address,uint256,uint256)","9dc7a49a":"RegisterUsername(string)","9dc8832c":"JiucaiToken(uint256,uint8,string,string)","9dc905bb":"insertMilestone(uint8,uint256,uint256)","9dc90bd8":"GreeningDesertChainToken()","9dc9281b":"LjwToken3()","9dca362f":"createAccount()","9dca4e0a":"matchWinnerOk(uint8,uint8,uint8,uint8)","9dcb0f55":"fundingStartAt()","9dcb5c65":"resultsWeightedByEther()","9dcbed8b":"totalUnrestrictedTokens()","9dcbf7ea":"Rename(string,string)","9dccc5bf":"getRegistration(bytes32)","9dcd4beb":"optionExerciseSpan()","9dcee160":"voteC()","9dcf56b4":"proofType_TLSNotary()","9dd05af9":"setEarlyExchangeRate(uint256)","9dd0a30f":"iwithdrawal(uint256,uint256)","9dd0ff01":"max_bet_this_spin()","9dd1687e":"withdrawBasicTokens(address)","9dd21928":"whiteListAddress(address,bool)","9dd28e34":"registerVendor(uint256,bool,bytes,bytes)","9dd3045b":"TransferToken(address,uint256)","9dd373b9":"setStakingContract(address)","9dd409d3":"setPlayPrice(uint256,string)","9dd4fdd3":"MarketPrice()","9dd52927":"AuthorityController(address,address[],uint256,uint256,address)","9dd5b9a3":"_lockAllAmount()","9dd63c3a":"setOwnerPrice(uint256)","9dd74964":"dividendsSum()","9dd7b3c3":"getSellBallers()","9dd7e749":"getOffsaleCount()","9dd819cc":"test_fourValidEqInt()","9dd9c24b":"canPerform(address,bytes4)","9dda456a":"_firstLevelEth()","9ddae7f5":"determineOutcome(uint256,uint8[],uint8)","9ddaf5aa":"proofs(uint256)","9ddc4a47":"setTransformTarget_default(uint256)","9ddccc99":"TelonToken()","9ddd503e":"PlayChainToken()","9dde6eb6":"placeBidFromEtherScrolls(uint256)","9ddee5f9":"SlopeIncreased(uint256)","9ddf65e1":"AUTSCoin()","9ddf840d":"withdrawDivs()","9de0111f":"tokenWithdraw(uint256,address,uint256)","9de0eb04":"dappId()","9de12300":"updateICOmask(uint256,uint256)","9de18f9c":"controla(address,bytes32,bytes32)","9de2bd2f":"RYZToken()","9de2f796":"getMintAmount(uint256)","9de315f1":"getTargetContactPubKey(address)","9de39cb3":"testStartsWith()","9de4f41c":"seMurio()","9de518ba":"divertDividendsToBankroll()","9de66604":"erc20old()","9de6ba52":"ArtCore()","9de6c45b":"addBox(uint256,string,string,string,uint256,uint8)","9de6d9aa":"changeGasLimitAndPrice(uint256,uint256)","9de7d032":"createPerson(uint32,string,uint256)","9de8302f":"createGen0Auction(uint256,uint128,uint128,uint40)","9de8535e":"readiscolorregistered(uint256)","9de91ccd":"getCCH_edit_12()","9de9205a":"getNujaNumber()","9de92f7e":"submitInput()","9de9d57e":"multiDistributeAdviserBounty(uint256[],bool)","9de9f1b8":"payJackpot3()","9dea34ad":"currBetID()","9deab49e":"_processERC20TokenPackPurchase(uint8,address,address)","9deb0b41":"createConsentFile(address)","9dec2189":"metaApproveHash(address,uint256,uint256,uint256)","9dec365e":"setCrowdsaleTotal(uint256)","9deca9ee":"disputeRounds(uint256,uint256)","9decaecc":"addEntryInMonths(address,uint256,uint256)","9decde19":"repriceAuctions(uint256[],uint256[],uint256[],uint256,address)","9ded1817":"sendCryptoVersusReward()","9ded35c8":"unpauseChannels()","9df06411":"addDepotEth(address,uint256)","9df08a9f":"getStatusEventCloseSuccess(bytes16)","9df0a5df":"ADDR_MAYA_TEAM()","9df0c176":"createCategoricalEvent(address,address,uint8)","9df184ae":"stageTwoEnd()","9df196ec":"getWhitelistDetailsFor(address)","9df1e2b0":"transferOtherToken(address,address,uint256)","9df21154":"AddToDB(address)","9df21bfd":"updateShareAddress(address,address)","9df39b4a":"removeCitation(address)","9df4867c":"transferSectors(uint16[],address)","9df4d0fe":"isChallenged()","9df51b89":"claimProfits()","9df537c6":"increaseBeneficiaryBalance(address,uint256)","9df5a643":"setAllowClaimUser(address,address)","9df5cbda":"isSucceed(uint8)","9df806d6":"setBurnerAddress(address)","9df8f631":"Ur()","9df93754":"Log2(bool,string)","9df94560":"leekStealTracker_()","9df971c1":"subFees(uint256)","9df9a1db":"disableKYC()","9dfaa207":"OWNERS_AND_PARTNERS_ADDRESS()","9dfad52d":"Expand()","9dfb071c":"WHITELISTING_MAX_CONTRIBUTION()","9dfb64fd":"toggleRefunds()","9dfb9de8":"getPawnLoanId(uint256)","9dfbb584":"refundNonWhitelistedPerson(address)","9dfcc05c":"isExpiredDeadline()","9dfcf372":"Lescovex_CYC(uint256,string,string,address)","9dfd1de3":"Token20(uint256,string,string)","9dfd4e2f":"MAX_ETH()","9dfd8b02":"getBuilding(uint256)","9dfde201":"Price()","9dfe29b5":"nextTokenType()","9dfecdcc":"openLottery()","9dff78de":"buyAnts()","9dfffa36":"countUp(address)","9e0112b8":"RESERVED_RESERVE_GROUP()","9e014cf1":"PrepareRollEvent(address,uint256,uint256)","9e01f9b9":"getUser2()","9e0234a1":"PHILCOIN()","9e036add":"NBCL(uint256,string,uint8,string)","9e03a5d0":"AndxorLogger()","9e03c589":"Delinetod()","9e03c971":"BuyKeys(uint256)","9e05c118":"availableCount()","9e05de62":"setFeeSharingValue(uint256)","9e060fb6":"updAcceptAdminWithdraw(bool)","9e07d205":"attorneySign()","9e098d9f":"LjwToken5(address,address)","9e0a2280":"TOKEN_SALE_ALLOWANCE()","9e0b7a1c":"approveCertificate(uint256,uint256)","9e0c0152":"lola()","9e0cb27b":"fetchOrderByOrderIndex(uint256)","9e0cbb64":"usersSpriteOwningHistory(address)","9e0cea05":"buyerCount()","9e0d8126":"PreICOEndTime()","9e0f35a2":"transfersSuspended()","9e0fdb26":"cancelSwap()","9e1224ce":"lotteryCloseInsurance(uint16)","9e126449":"registerForRaffle()","9e12c9b9":"sellCoin(address,uint256)","9e12d725":"NewTokenGrant(address,address,uint256,uint64,uint64,uint64)","9e12f15b":"units50percentExtra()","9e136878":"Transferred(uint256)","9e13baa4":"BNCConverterFactory()","9e13d3e1":"VietnamGemstoneChain()","9e140cc8":"ENCRYPTION_KEY()","9e1533a9":"getFounderMembersInvest(address)","9e159db0":"Lambo()","9e15bc25":"totalInput()","9e163aca":"getDocumentsCount(bytes16)","9e179b91":"addFreeMineral(address,uint32)","9e1832b5":"ListingCreated(bytes32,address,uint256,uint256,uint256,uint256,address)","9e196881":"sellBlock(uint256,uint256,uint256)","9e1a00aa":"sendTo(address,uint256)","9e1a4d19":"tokenBalance()","9e1ad320":"XERA()","9e1b9078":"addLandRevenue(uint256,uint256,uint256)","9e1be663":"SeedMarket(uint256,uint256)","9e1bf732":"addNewTokenTo(address,uint256)","9e1c6d6b":"transferFromFund(address,uint256)","9e1d14f1":"getThresholdsLength()","9e1e1ca9":"monstersForSale(uint8)","9e1e60c7":"depositOffchain(address,uint256,uint256)","9e1e6528":"uncertify(address)","9e1f5599":"executeTokenTxn(uint256)","9e20437c":"digits()","9e206ed5":"blockSkills(uint256[])","9e208922":"scheduledTopUp()","9e20a9a0":"registerToken(uint32,address,uint8)","9e20afdf":"weekly_disbursement()","9e20b768":"distributedBonusStakes()","9e20f6c9":"walletEmail()","9e211ee8":"dayFinished(uint16)","9e213fb7":"callReplaceCallback(string,address)","9e2262f5":"testCreateCostData()","9e229c55":"StatEventI(string,uint256)","9e22bd72":"lengthArrayApproval()","9e231e2d":"abortGame(uint256)","9e23602e":"hasAllAttrs(uint256,bytes2)","9e238366":"getCraftingAuction(uint256)","9e239ace":"itemOwner(bytes32,uint256)","9e23c209":"removeDeveloper(address)","9e243259":"frozenRate()","9e24edca":"TOKEN_FOR_INVESTER()","9e251c6f":"DonationReceipt(address,string,uint256,uint256,uint256,bytes32)","9e254262":"contractDurationInDays()","9e254d13":"Child()","9e25ec01":"KAL5Token()","9e25fd58":"SotkoCoin()","9e27a305":"sachin()","9e281a98":"withdrawToken(address,uint256)","9e282328":"getEditionReleaseTime(uint256)","9e28739d":"LogAddressTokenCapCalculated(uint256,uint256,uint256,string)","9e288374":"getContributor(address,address)","9e28abaf":"ShareActive()","9e29559c":"teamKeepingQuota()","9e29739e":"setContributionLevel(address,uint8)","9e29eb0f":"getUsersAwaitingForTokens()","9e2abcb5":"getddd(uint256)","9e2d0478":"addNotaryToOrder(address,address,uint256,uint256,string,bytes)","9e2ed686":"cancel(address,bytes32)","9e2f04bf":"chooseWinner(uint256)","9e306d32":"MintableToken(uint256)","9e307955":"etherPrice()","9e30dd5f":"buyRareItem(uint256)","9e315d46":"payoutAmount(uint256)","9e31f9b6":"numGamesCheated()","9e321f42":"changeWhitelistOnly(bool)","9e3249ab":"setMinShards(uint8)","9e325b80":"SocialRemitToken(uint256,string,uint8,string)","9e326858":"private_AddGameBar(uint256,string,string,string)","9e331188":"startIco3(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","9e33f72c":"reclaimStarted()","9e34070f":"isClaimed(uint256)","9e340ffb":"endFreeGet()","9e34ba2f":"VUP_PER_ETH_ICO_TIER3_RATE()","9e34d78e":"getDrawCount(uint256)","9e352721":"PreBuy(uint256)","9e3572b5":"getCurrencyContract(bytes32)","9e35ff3e":"storeCarrotsCredit(address,uint32)","9e36fde7":"regName(string,address)","9e37273b":"getMintDigest(uint256,bytes32)","9e37c923":"subscriptionOf(address,address)","9e3809a9":"setFiscalVerify(bytes32,bytes32,bytes32,uint256,uint256,uint256)","9e385fa4":"raiseEmergency(bool)","9e38ac15":"ownerShip(address)","9e38c76e":"lockRedemption(bool)","9e39db38":"initChestsStore()","9e3a33b2":"_fetchPaidOrdersForMerchant(address)","9e3b34bf":"times()","9e3b77af":"lendingManager()","9e3b94f1":"CONFIRM_LIMIT()","9e3b9dc1":"secondTarget()","9e3c671c":"citizensAddresses()","9e3d0636":"numOfDeliveredCrowdsalePurchases()","9e3d1b99":"Bakt(address,bytes32,address)","9e3d2d06":"totalEtherBetValue()","9e3d49db":"walletBounties()","9e3d7809":"setParamsTransfer(bool)","9e3df458":"twentyThirtyAllocation()","9e3e230b":"setSubmissionClosed(uint256)","9e3e6878":"allCatsAssigned()","9e3edce9":"setImageHash(uint256,string)","9e3f1f71":"isPartOfOrg(string)","9e416812":"creditGameAddress()","9e4195f1":"releaseOrderStakes(address,uint256,uint256)","9e41a9cd":"viewCertificateByCourse(address,string)","9e41b73f":"getWeapon(uint256)","9e4307cf":"_95_ebetSmartContracti()","9e43692c":"FOUNDATION_POOL_TOKENS()","9e439ff8":"thirdPeriod()","9e455939":"getContractAddr()","9e459174":"_addDroneInternal(address)","9e45de73":"PieceTransferred(uint256,address,address)","9e45e0d0":"darknodeRegistry()","9e47214a":"isHarvestEnabled()","9e4734ba":"nextTimeout()","9e484dd4":"getMembersOfTierCount(uint256)","9e48d2fd":"setPayouts(uint256,string)","9e4902c9":"ZZCoin(address)","9e492aa6":"updateBLAddress(address)","9e497967":"CosmicPowerToken()","9e49e976":"importIssuerData(address[],uint256[])","9e4a5ade":"tokenICO()","9e4a613f":"setCertificate(string,string,string,uint256,uint256,string,string)","9e4a993b":"getGameStake(uint256,address)","9e4a9f2f":"SCComplianceService()","9e4ba1be":"testBuyTwoTokens()","9e4be339":"getPartners(address)","9e4bec3f":"senderIsProvider()","9e4c1357":"purposeWeiRate()","9e4d4d0c":"updateIcoEnding(uint256)","9e4ea320":"getterForTest(uint256)","9e4ece80":"getInvestorUnPaidAmount(address)","9e509af3":"NggaToken()","9e51051f":"initialRate()","9e524caa":"subMinutes(uint256,uint256)","9e5288a0":"getStep()","9e536132":"GetUserPools(address)","9e5406bf":"paymentWithCurrency(address,string,uint64,string)","9e551567":"PonziToken()","9e570d6f":"updateFighterStats(uint256,uint8,uint8,uint8,uint8,uint32)","9e584658":"newStandardCampaign(string,uint256,uint256,address)","9e58963f":"_clear(address)","9e58ad97":"getNormalCardList(address)","9e58cfd1":"decreaseBeneficiaryBalance(address,uint256)","9e58e1a7":"_addPartExperience(uint256,int32)","9e5914da":"setReferral(address)","9e59eb14":"getAllocated(address)","9e5ad3ea":"test_insert_findNoHintUpdateHead(int256)","9e5b241a":"getBorrowInfoByIndex(uint256)","9e5b53bb":"Crowdsale(uint256,uint256,string,string)","9e5cdaf0":"initialBankrollGrowthAmount()","9e5d0258":"regularDonations(uint256)","9e5d4c49":"executeCall(address,uint256,bytes)","9e5e86fa":"setEnforceKyc(bool)","9e5ece98":"updateLockDate(uint256)","9e5ee522":"tokensSoftcap()","9e5f1889":"partner2_address()","9e5faafc":"attack()","9e6031c6":"ZigZagToken()","9e60f8d6":"getPlayerSpaceshipBattleWinsById(uint256)","9e6371ba":"retire(address)","9e639858":"winPercent()","9e647aac":"getParameter(string)","9e6480fa":"A(uint256,string,string)","9e654dfa":"redeemForkedTokens()","9e65741e":"exchangePrice()","9e65a03a":"cancelSellCityForEther(uint16)","9e65c7e5":"updateLatestRevision(bytes20,bytes)","9e65fab0":"priceIsFrozen()","9e66cd38":"free(uint64)","9e67fa6a":"createArtwork(string,address,uint256)","9e686c0d":"getStaffLength()","9e687b6c":"retrieve(bytes32,address)","9e68ca82":"preValidatePurchase(address,uint256)","9e69383d":"TokenBatchTransfer()","9e697cd3":"startDateOfRestoreUnsoldTokens()","9e6985e2":"setbuyPrice(uint256)","9e6992b5":"BcengCoffeeToken()","9e69940d":"eachAirDropAmount()","9e69a6d2":"bountyTokensNotDistributed()","9e69c732":"take(string,string)","9e69f2bb":"premine()","9e6a5767":"previousTokenVesting()","9e6af2e3":"exchangeEthStb(uint256,uint256)","9e6afbda":"decreaseSpeed(uint256)","9e6bcba5":"getBoostFromTile(address,address,address,uint256)","9e6bdea0":"RegisterChallengeCreators(address,string)","9e6c0877":"__hasRole(uint256,uint256)","9e6cb42b":"voteEndTime()","9e6d4cd0":"joinRaceAndFinish(uint256,uint256)","9e6d6925":"setper(uint256,uint8,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","9e6d95c7":"checkHGame(uint256)","9e6eda18":"fee(address,uint256)","9e6f2ea2":"Kin()","9e6f505b":"BiigoToken(address,uint256)","9e6fb394":"companionsListCount()","9e7010a8":"Dashidai()","9e72942c":"getBoosters()","9e72a9d8":"sendToMarket(uint16)","9e750316":"pushBlock(uint256,uint256,bytes32,bytes32,string)","9e757e7f":"bookOVISSale(uint256,uint256,int256)","9e75a7c8":"bitplusAddress()","9e75c483":"busted(uint256,uint256,uint256,uint256)","9e761bbb":"beneficiaryList(uint256)","9e76e30d":"tokenRateUsd()","9e776ff5":"getTotalBattleboards()","9e79800d":"getOwner(uint16,uint8,uint8)","9e7a13ad":"people(uint256)","9e7b8d61":"giveRightToVote(address)","9e7cf86b":"changeSettings(uint256,uint256,uint256,uint256)","9e7d101e":"setMaxLeaders(uint256)","9e7d24df":"move(bytes32,uint256,uint256)","9e7e514b":"DiceGame()","9e7fec98":"owner_time_limit()","9e80138c":"LendConnect(address)","9e80b731":"test_threeValidAssertFalse()","9e80cab0":"ownerSetRecommendProportion(uint16)","9e8110e6":"setQuery(string)","9e813938":"expiresAfter(address,uint256)","9e817c03":"ROUND_LENGTH()","9e81c4b3":"sendFunds(address,uint256,uint256,uint256)","9e81e254":"_getMaximum(bytes32)","9e8385d6":"regadr(address)","9e83abe3":"newExit(address,uint256,uint32[])","9e84158e":"setPLATAddress(address,address)","9e845173":"getCCH_edit_34()","9e84d44d":"challengerConvicted(uint256)","9e8558a0":"setSellExchangeRate(uint256)","9e85742e":"approveEscrow(uint256,uint256)","9e86d7a8":"setVnt(address)","9e86f8c5":"RequestFactory(address,address,address)","9e86fb86":"investOffer(uint256,uint8[])","9e87a5cd":"getPriceFeed()","9e87c1c6":"getLastSingle()","9e87fac8":"Paused()","9e8836e2":"THORToken()","9e890cb3":"netAmountBought()","9e893d64":"TheUltimateWorldDigitalCurrency()","9e8a0f57":"getWinRate(uint256)","9e8a41f4":"getOutCar(uint256)","9e8ab40c":"ICOReserveWithdrawn()","9e8af7e9":"migrateInvestorFromHost(address)","9e8bf603":"curReleaseAmount()","9e8c3543":"setAuditAuditor(uint256,address)","9e8c39ed":"updateHolidayState(uint8,string)","9e8cfe20":"insert(int8,int8)","9e8e23b7":"lastBlock_v5()","9e8e3ef4":"nftExits(uint16,uint256)","9e8e4add":"changeTurnLast(uint256)","9e8ee59a":"addNewTicket(address,uint256,uint256,bool)","9e8f152c":"showLock(address)","9e8f2750":"withdrawInviteReward()","9e8fcbe9":"previousRoundId()","9e906157":"FundingRules()","9e90ce6c":"tokensIssuedForBonusRangeOne()","9e90f9aa":"blackHole()","9e916157":"STAGE_2_START()","9e9188ea":"setDividends(address)","9e918c0a":"setMaxArtworks(uint16)","9e9198c2":"layers(uint256)","9e920587":"testOwnedAuth()","9e92448e":"setRepAvailableForExtraBondPayouts(uint256)","9e925746":"_checkAndCallSafeTransfer(address,address,uint256,bytes)","9e92c991":"getTotalRollMade()","9e92dfd8":"getFiatTransactionsCount(string)","9e931e6b":"getRequesters(bytes32,uint256)","9e93d0e4":"reinvestReturns(uint256)","9e945ff2":"amendPurchase(uint256,address,uint256,uint256,uint256,string,uint256)","9e9548cb":"LabelSold(address)","9e95670d":"erc20Received(address,uint256,address,uint256)","9e9593ce":"RewardPoolAddress()","9e95f280":"setRatePreIco(uint256)","9e962b39":"minimumContributionPhase1()","9e964025":"bonusTokenThreshold()","9e965f7e":"revertSuspendedPayment()","9e96a23a":"give()","9e975ca6":"NSPToken()","9e976d38":"toMonth(string)","9e9785ad":"payoutCursor_Id()","9e985ea6":"changeControllerContract(address,address)","9e987b20":"treePot()","9e997121":"getConfigAddress(bytes)","9e9a783a":"canCallWithAssociation(address,address)","9e9a87e5":"agree(address)","9e9aed62":"contractTokenBalance()","9e9b6d06":"createOption(bool,address,uint128,uint128,address,uint64)","9e9ce791":"BrainLegitCoin()","9e9d0718":"Invested(address,uint256,uint256)","9e9d3aa4":"FirstBloodToken(address,address,uint256,uint256)","9e9e5b85":"ARIToken(address,address)","9e9ea24b":"PRE_ICO_TOKENS()","9e9eb444":"winFreeGo(uint256,uint256)","9e9ec9e3":"getHashAddresses()","9ea03ccb":"fundingUnlockPeriod()","9ea064b2":"getLevelConfig(uint32,uint32)","9ea0b8f0":"addTeamGrant(address,uint256,uint256,uint256)","9ea0c08c":"announcementName()","9ea134bf":"getRedeemableReputationStaker(bytes32,address)","9ea1b79d":"getContentChannel(uint256)","9ea2104d":"firstReleaseAmount()","9ea23080":"STQPreICO3TestHelper(address,address[])","9ea27016":"setTokenIdsIndex(uint256,uint256)","9ea28b5c":"VestingMemberAdded(address,uint256,uint256,uint256)","9ea30fae":"getPokemonOwner(uint256)","9ea407be":"updateTokensPerEth(uint256)","9ea480ec":"allowanceFlower(address,address)","9ea55bb0":"updateFeeAmount(uint256)","9ea57930":"stampIn(address,uint256,uint256)","9ea58112":"setLethalBonusAtHits(uint256)","9ea67876":"returnNumber(uint256)","9ea69541":"updateTileBlockValue(uint16,uint256)","9ea71c37":"getDesignatedReportingDurationSeconds()","9ea73895":"hitCharacter(uint16,uint16)","9ea76475":"subFreezingTime()","9ea776cd":"currentFundingRound()","9ea82706":"removeRealWorldPlayer(uint128)","9ea8a418":"updateFunds(uint256,uint256,uint256,bytes,bytes,bool,bytes32,bytes32)","9ea94877":"getLandIdByKey(bytes8)","9ea98d55":"intersect(address[],address[])","9eaa4812":"isLastMilestoneAccepted(bytes32)","9eab0e29":"FinalisedCrowdsale(uint256,uint256)","9eab503a":"dividendAddr()","9eab5253":"getMembers()","9eabebe7":"setTransferTime(uint256)","9eacc166":"transferAnyERC20Token(address,address,address,uint256)","9ead1478":"setMaxAnimals(uint16)","9ead1b00":"loanBalanceOf(address)","9ead7222":"tokenList(uint256)","9eadd77c":"roundMoneyDownNicelyET(uint256)","9eae2453":"setSchedule(bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,uint256)","9eae6555":"earlyContribList()","9eaeca9f":"getTokenReturnRate()","9eaeccf1":"TestToken(string,string,uint8,uint256)","9eaf17a1":"getCarveUpTokens()","9eb05f3a":"EarlySuccess()","9eb0ad03":"Exchange(address,address,address,uint256,uint256,uint256,uint256)","9eb180a7":"identifierToPrice(uint256)","9eb20aa7":"setPetLastTrainingTime(uint64)","9eb32fdb":"initializeContract()","9eb360cc":"updateRausPoint(int256,uint16,int256,uint16)","9eb44784":"getTokensForPresale()","9eb45706":"get_previous_asset_document_from_document(bytes32,bytes32)","9eb4da1c":"okamiTotalPurchase_()","9eb51bf1":"Goodluckcoin()","9eb59e00":"updateCursETHtoUSD(uint256)","9eb6c932":"ResetAllAmount()","9eb7294d":"transferRemainingTokens(address,uint256)","9eb7d170":"withdrawPendingBalance(address)","9eb81bd0":"unFreezeTransfers()","9eb866cc":"isBonusTime()","9eb8cbf3":"set_activity_details(uint256,string)","9eb9c68f":"stepBonusList(uint256)","9eb9dd3b":"getBetsProcessed()","9eba0196":"DYCOIN()","9ebafad6":"getLastAttackCount(uint256)","9ebb1250":"withdrawFinal()","9ebb5d3c":"getFreeCraigGrant()","9ebbf231":"setMinOrderSizeEth()","9ebc8c95":"isNeedLoan()","9ebca4ad":"setMasterRecruitmentAddress(address,address)","9ebe13a2":"END_ADDRESS()","9ebe4d98":"percentageQuarter2()","9ebf6d92":"Whitelist()","9ec0505a":"BING(uint256,string,string)","9ec12cfa":"sellsIngrWithoutDepletion(address,uint256,string)","9ec272b4":"getPremiumPack(uint256)","9ec32d45":"challengeWinningOutcome(bytes,uint16)","9ec35352":"returnRandom()","9ec3a90c":"verifyTimelock(bytes32,address,address,uint256,uint256,bytes32,bytes,bytes)","9ec40d1c":"checkCode(string)","9ec5a894":"rewards()","9ec68f0f":"multiSend(address,address[],uint256[])","9ec7486a":"GiveERC20()","9ec760df":"_sendMoney(address,uint256)","9ec7888f":"Available()","9ec79e99":"requestConsent()","9ec7e1c6":"nOS()","9ec8b026":"sort(uint256[])","9ec8eec9":"TokenImpl()","9ec92d42":"getSecondPhaseCap()","9eca085c":"isSupervisor()","9eca672c":"withdrawFor(address)","9ecbf341":"adminRescueFunds()","9eccf691":"setICOEnd(uint256)","9ece1d9c":"WeiToEther(uint256)","9ecf12cb":"HEART(uint256,string,string)","9ecf9037":"getNumberDonators()","9ed153c0":"master(address)","9ed1e4c6":"singleDigitBlock()","9ed26fe8":"setEtherInUSD(string)","9ed3b61b":"getTrustContract()","9ed3edf0":"transactionFee()","9ed44c91":"CharitySplit(uint256)","9ed474b3":"author2()","9ed49005":"completeIcoPart1()","9ed4ad43":"getMax(uint8[])","9ed53f88":"starExists(uint256)","9ed57360":"getPaintingSpeed(uint256)","9ed58c7a":"provideData(address,address,uint256,bytes)","9ed5c84c":"salePeriod()","9ed74a23":"createCloneToken(uint256,string,string)","9ed7772c":"OwnerSetPrizePool(address)","9ed78285":"GENEOS()","9ed78489":"Worldtvcoin()","9ed78df0":"PRESALE_TOKEN_SOFT_CAP()","9ed798be":"CrestToken()","9ed81bc9":"deregisterProducer(address)","9ed93318":"create(address)","9ed99951":"changeBntyController(address)","9eda7d23":"isContributor(uint256,address)","9edc7b44":"revokeStack(bytes32,uint256,uint256,uint256,uint256,uint256)","9edcebbb":"updateTabRap(bytes32)","9edd1bd2":"TestEvmStack()","9eddc441":"lockedAccountThresholdUsd()","9eddfb1b":"delay_pool_change_block(uint256)","9ede7a37":"voteCount(uint8,uint8,uint8)","9eded57a":"paybackLast()","9ededf77":"width()","9edf256d":"getShipPrice(uint256)","9edf42ff":"pendingNumbers(address)","9edfb647":"senderAllowedFor(address)","9edfb9ee":"acceptOwnershipOfVesting(address)","9ee035c9":"lookupCanonicalFormat(bytes)","9ee04661":"withdrawTeamFunds()","9ee06759":"setSquarePrice(uint8,uint256,address)","9ee0933f":"joinBounty(address)","9ee1bd0f":"whoIsOwner()","9ee22f9a":"setCompte_32(string)","9ee29ef2":"updateTargetToken(address,uint16,uint16)","9ee3518e":"setTeamMember(address,uint256)","9ee398ce":"getTierStartAndEndDates(uint256)","9ee484ce":"withdrawCerneuTokens(address)","9ee5451d":"PriceOneDisable()","9ee5555f":"setGovTax(uint8)","9ee60142":"_processBonus(address,uint256)","9ee61c9d":"testExistingVoteWeight()","9ee679e8":"requestWithdrawal(uint256)","9ee6a7c3":"onlineTime()","9ee6c0e1":"test_2_someTest()","9ee6ff70":"testSafeMul(uint256,uint256)","9ee71fae":"LogPolicyDeclined(uint256,bytes32)","9ee7fbd9":"extraRate(uint256,uint256)","9ee837f5":"total_empire_score()","9ee85a9f":"isPreSaleTokenRaised(uint256)","9ee8fa93":"yearLength()","9ee94556":"TestTokensMigration(address)","9ee9c8b5":"chetan(uint256,string,uint8,string)","9ee9dd5c":"vault_state()","9eea480f":"TotalRequestsAmount()","9eea4a3a":"address2()","9eea67e8":"_addPerk(uint8)","9eeaa7f4":"exitDuration()","9eeb30e6":"turnoff()","9eeb4920":"setLockup_simus(address,uint256,uint256)","9eeb5a6a":"Manageable()","9eeb6c11":"setBatchCeateDrawingsAddress(address,address)","9eeb79b2":"buildUrl(address,uint256,uint256)","9eec22e7":"reclaimEtherDeadline()","9eec4bac":"payoutFromContract()","9eec6e89":"TokenLogic(address,address,address)","9eed8369":"neWon()","9eee5787":"Standard_1()","9eee8041":"getPointSize(uint32,int256)","9eee85fe":"bookEarnings(address,uint256)","9eeea0d0":"PAOCoin()","9eeef510":"bidCustomAuction(uint256,uint256,address)","9eef6f65":"addRequest(address,address,bytes32)","9eefdd87":"enableAddress(address)","9eefde81":"BasicKNOW()","9ef0653c":"setICO4Phase()","9ef065bb":"fDiv(uint256,uint256)","9ef1204c":"vote(bytes32,uint256)","9ef13593":"decayedBalanceOf(address)","9ef1fbc4":"MudshotsToken()","9ef279d1":"burn(address[16],uint256)","9ef27b00":"closedAt()","9ef35c01":"setJackpotFeePercent(uint256)","9ef36bd1":"queueCount()","9ef40238":"getcoinsvotes(string)","9ef45a31":"someFunction2()","9ef46973":"guessFlip()","9ef48a31":"setBonusTokenRateLevelThree(uint256)","9ef5233f":"setByteSize(bytes32,uint256)","9ef53400":"getStaticArraySize()","9ef63e97":"paybackToOwner(address)","9ef6bf79":"store_ETH_to_contract()","9ef6ca0f":"left33(uint256)","9ef7a463":"exchangeRateForETH()","9ef7e723":"withdrawContractToken(uint256)","9ef887ec":"makeItRain(address[],uint256[])","9ef916ab":"setOriginalSupply()","9ef95545":"CheersWangToken()","9ef965d1":"RealEstateToken()","9ef974bb":"checkGlobalBalance()","9ef9df94":"transcoderTotalStake(address)","9efa776d":"tokenFallback(address,uint256,uint256[])","9efbae81":"FundTransfer(address,address,uint256)","9efbc411":"PICOPSCertifierUpdated(address,address)","9efc0190":"YORITEX()","9efc81fe":"minimal_token_sell()","9efc94a6":"kycLevel()","9efd1f0c":"startNextEra_(bytes32)","9efe6454":"Rena()","9efedc91":"getMyAccuAmount()","9efeefa5":"betAgainstUser(uint256,uint256)","9effb6a6":"CrowdFunding(string,string,string,uint256,address)","9f00237b":"minContribution(uint256)","9f005920":"accept(address)","9f00c0de":"btycsubmoney(address,uint256)","9f020d3a":"equalsNoCase(string,string)","9f022f05":"IMDEXsetAdmin(address,bool)","9f03711a":"withdrwleftovereth(uint256,address)","9f03c3b8":"hicsTokenPrice()","9f03d82f":"CGTToken()","9f047f3c":"fundProject(string)","9f04873d":"VILLAGE_INCREASE_RATE()","9f04996d":"bid(uint256,address)","9f052fea":"setMintRequestAddressMap(uint256,int256,string,address)","9f054b15":"SushiCoin()","9f05a36d":"getEnd()","9f0650d9":"etherPriceUSD()","9f06a579":"ViewBet(address,uint256)","9f06aa08":"collateralize(uint256)","9f0812cb":"_registerIfNeeded(uint256)","9f084b3a":"CAMS()","9f08a68c":"working()","9f08fc38":"subGlobalBlockValueBalance(uint256)","9f095e88":"asdf()","9f0a11ee":"buyPrice_wie()","9f0b17e3":"forward_transaction(address,uint256,bytes)","9f0b7f16":"Foo(string)","9f0be144":"getGreeksBattlePointsBy(address)","9f0d5f27":"depositAll(address)","9f0de490":"challengeOutcome(int256)","9f0e1986":"createGen0Auction(uint256,uint64)","9f0e3107":"get_timestamp(bytes32)","9f0e591b":"ABCDToken()","9f0e7d44":"companyReserves()","9f0eed0f":"GetCurrentICOCycle()","9f0f78ca":"profitsTotal()","9f10a990":"userEntries(address)","9f117317":"releaseManyStakes(uint256[],address[],address[])","9f118536":"initiated()","9f11e9cd":"setRegistrant(uint256,address)","9f126281":"updateFirstBuyer(bytes32,uint8,bytes32,address)","9f12fde0":"modifyBet(uint256,uint256)","9f1306cb":"P3DReceive()","9f132677":"MAX_CONTRIBUTION_WEIS()","9f13c4c7":"sealableProperties(uint256,bytes32)","9f147c41":"tokenPriceInCent()","9f15e729":"setgamecardname(uint256,string)","9f161d39":"BaseCrowdsale(uint256)","9f165304":"STAGE_PRESALE_ETHRaised()","9f166cf1":"multiBalanceOf(address,address[])","9f16b7d0":"setStarAuction(uint8,address,address)","9f16d65f":"fifthMonthEnd()","9f174c6f":"AIRDROP_SHARE()","9f180cf1":"calculateAccountValues(address)","9f181b5e":"tokenCount()","9f184dd5":"aggregateValues(address,address)","9f186edb":"setSpawner(address,bool)","9f19296b":"getGroupStatistic(uint256)","9f1aa404":"refundAllInvestorTokensPurchases(address)","9f1ae1c1":"FSATToken()","9f1ae6ac":"MAX_CARS_TO_GIFT()","9f1b3bad":"Receive()","9f1cda42":"ValidateEventStorage(bytes,bytes)","9f1eaa4c":"getUnsoldTokensWithDecimals(uint256,uint256)","9f1f07fe":"iWAMToken()","9f1f238e":"isChecksumValid(bytes32)","9f1f2d77":"_updateReferrerFor(address,address)","9f203255":"setAuditor(address)","9f204a47":"sendIncentivisation(address,uint256)","9f21edf6":"setLevelPAO(uint256,uint256,uint256,uint256)","9f223167":"ownerEth()","9f22af8e":"add2Y(address,uint256)","9f233c76":"Seiyuu()","9f237b43":"deathData_v9()","9f242bf5":"NUTScoin()","9f245957":"totalDiscountedItemsForSale()","9f275dec":"investBalanceOf(address)","9f2763d2":"newPurchase(string)","9f28f7c4":"toSCL(uint256)","9f28f8c2":"changeWhitelistedAddressCapAmount(address,uint256)","9f296b62":"getPaymentTotal(address)","9f29e1a1":"thisContractTokenBalance()","9f2a1471":"erc820Registry()","9f2a6374":"platformWalletAddress()","9f2b03b6":"LAB()","9f2b22c7":"CanYaCoin()","9f2bbcfd":"LoggerAuthorized(address)","9f2bc32b":"preITO()","9f2c1fd8":"ERC20(uint256,string,uint8,string)","9f2c9503":"mintAndLock(address,uint256)","9f2ccbcc":"buyAnimalsFromAnimalFactory(string,string)","9f2ce678":"vote(bytes32,bool)","9f2e0f9c":"managePlayer(address,uint256)","9f2e7ce3":"prevXRPCToken()","9f2eaf4e":"verifyCanWithdraw(address,address,uint256)","9f2ee8b8":"getBlocksByOwner(uint256,uint256,address)","9f2f077c":"totalTransformedTokens()","9f2f58ec":"void_race()","9f2ff221":"teama()","9f2ffaff":"_0xGoldToken()","9f30ca9a":"getOpenBidsByBidder(bytes32,address)","9f318ae8":"HKHCToken(address,uint256)","9f31de2e":"updateTokensForCloudexchangeTeam(uint256)","9f327124":"ReflexCoin()","9f329b15":"SpareCurrencyToken()","9f334696":"isNumRed(uint8)","9f337cce":"_createTeam(string,address,uint256)","9f33d9cb":"joinAsBuyer()","9f34ab0c":"PXGToken()","9f34ce14":"activateConflictResolution()","9f351fc0":"totalRedeemedCheque()","9f35910c":"getTeamOwner(uint32)","9f35caee":"getAllChainIDsOfUser(address)","9f35d3b2":"start(string,string,uint256,uint256,uint256,uint256)","9f37092a":"buyItem(address,uint256)","9f373a7a":"updateCandidate(address,string,string,uint256)","9f37b53f":"verificationSlashingPeriod()","9f396cff":"voteAgainst()","9f3c4416":"claimInheritance()","9f3ce55a":"sendMessage(address,uint256,bytes)","9f3d7b0b":"addProposal(address,uint256)","9f3e1846":"EscobarcoinToken()","9f3edbe1":"emissionStatusUpdate(bool)","9f3ef430":"payTokenHolderBasedOnTokenCount(address,uint256)","9f3f736a":"LIMITED_ADMIN()","9f3fab58":"a(bytes32)","9f3ff73a":"setExternalCurrencyProcessor(address)","9f406c8b":"isPreICOFinished()","9f408251":"TaTaTu()","9f4216e8":"userList(uint256)","9f4283fa":"jdaleveridgesyscoin()","9f43daf7":"sendEthTweet(string)","9f43ddd2":"expirationTimestamp()","9f44b34c":"EXT_COMPANY_TWO()","9f44fa19":"FeedbackUpdated(uint256,uint8,bytes32)","9f454f2b":"LEU(address,uint256)","9f45b45c":"getModuleByName(uint8,bytes32)","9f45c8ec":"nodeCheck(bytes32)","9f45f982":"PATH(uint256)","9f489e4e":"getDeposit(uint256,address)","9f494565":"LogMint(address,uint256)","9f49cefb":"addStage(uint256,uint256)","9f4aaaef":"asmName(address)","9f4ba0ee":"setInitialPrice(uint256)","9f4cd0ef":"current_item_index()","9f4e8405":"updatePaymentManager(address)","9f4f4808":"setCrowdfundAddress(address)","9f4f903e":"TicketToken()","9f4f9886":"getRateAt(uint256,uint256)","9f4fae14":"getAmountWeeklybyNum(uint32,uint8[4])","9f509ab1":"FUNDING_PRESALE_MAX()","9f5185b6":"EventCashOut(address,uint256)","9f51cf67":"balance_available_for_custom_voting()","9f5215dd":"availSupply()","9f5227c2":"confirmWithdrawal(address,string,uint256,string,address)","9f52b74e":"apt()","9f52f381":"startAllocation()","9f530cc9":"JACKPOT_CHANCE()","9f535821":"mint(uint256,uint256,string,uint8,bytes32,bytes32)","9f536edd":"setScore(address)","9f53e07b":"channelMaxSize()","9f544434":"sendFood(address,uint256)","9f548613":"MyUserToken(uint256,string,string)","9f549015":"Max_Mintable()","9f54c01c":"addProducer(bytes32,uint256,bytes1)","9f54c24f":"LogGive(address,uint256,string)","9f550293":"getTotalRaised()","9f55857d":"testBazMethod(uint32,bool)","9f55ecab":"currentVotingDate()","9f569ab4":"requestOfTime(address,uint256)","9f569e66":"sendTokensTo(address[],uint256[])","9f572048":"getCanvasByOwner(address)","9f5755ae":"announcement()","9f577c15":"setContractProvider(address)","9f57d16e":"getCurrentJackpot()","9f5892a7":"hash(string,uint256,uint256,address)","9f58d881":"executeOr(bytes32,bool)","9f591fa5":"deathData_v15()","9f59fc5a":"GetConsentDirectives()","9f5a5ff8":"Police_4()","9f5a851f":"configure(uint256,uint256,uint256,uint256,uint8,address)","9f5a9b7c":"getTotalBurnt()","9f5ac8f7":"creator(bytes32)","9f5b1d2c":"GITHUB_LINK()","9f5bd866":"setNodalblockURL(string)","9f5c11c4":"two_card()","9f5c671e":"MultipleErrorsContract()","9f5ce849":"CNT_Token()","9f5cfe03":"roundsCount()","9f5f0520":"myVault()","9f5f0826":"_bonusToPartners(uint256)","9f5f7c7f":"tokenSplit(address,address,address,uint256)","9f5ff50a":"calcTokens(uint256,uint256,uint256)","9f614b61":"addTitleTransfer(string,string,string)","9f6163ee":"lastBlock_v4()","9f621075":"ICO_AllowPayment()","9f624701":"DZONetwork()","9f6264d3":"setArray(bytes32,bytes32[])","9f62e202":"CrowdSale_AssignOwnership(address)","9f637851":"endICODate()","9f63f5c3":"approveLoan(address,uint256)","9f64b6fb":"sendAffiliateValue(uint256,address)","9f654dd2":"sellTokensIco()","9f659296":"createCardForAcquiredPlayers(uint256[],address)","9f65f242":"Itube()","9f665e1a":"offerAccepted(address,uint256)","9f668bba":"getGameIds()","9f674147":"accruedBonus(uint256,uint256)","9f674eb3":"myAccessLevel()","9f678cca":"drip()","9f6822b4":"startEscrow(bytes20,address,uint256)","9f684a0d":"disableATMExchange()","9f69b5a0":"updateEscrow(uint64,uint256,uint256)","9f6a4fbe":"CyteCoinERC20Token()","9f6b4cce":"BetPlaced(address,uint8,uint256)","9f6bd2a9":"isArbitrator(address)","9f6c20f6":"MRC(uint256,string,string)","9f6c3dbd":"join(address,address,uint256)","9f6dcd9d":"ETHtoZCOrate()","9f6e3456":"SOPHIYA()","9f6e4bb5":"weiAllowedToReceive(uint256,address)","9f6f99ee":"updateAPIPublicKey(bytes)","9f6fb2ba":"createRichContract(string)","9f6ff2e1":"EInvoicingRegistry()","9f70c3dc":"doWithdraw(address,address,uint256)","9f70db12":"removeEmployee(address,address)","9f727c27":"reclaimEther()","9f73bef1":"getSubjectsCount()","9f73dbc0":"getCurrTeamSizes()","9f7496ec":"_firstUnlockAmmount()","9f753df6":"MELON_BASE_UNIT()","9f75ccc8":"onSuccess()","9f75e990":"ReceivedCall()","9f7623b8":"sign(address,address)","9f769807":"setTokenState(address)","9f77920c":"Revoke(address)","9f789a0c":"setSchellingRoundDetails(uint256,uint256,uint256)","9f7904af":"available_with_bonus()","9f7a2ef5":"TEAMmint()","9f7a53a1":"sendBountyBalance(address,uint256)","9f7b0fc8":"getParent(address,uint256)","9f7b4579":"create(uint256,uint256)","9f7b967e":"SampleERC677Token(address,uint256)","9f7ba828":"getTokenToEthMakerOrderIds(address)","9f7c8851":"otherSupply()","9f7c94aa":"payoutWinners()","9f7d9f62":"deprecateDefenceSubtype(uint8)","9f7d9f92":"AggiungiMiner(address,bool)","9f7e03cc":"deposit70Percent()","9f7e1fed":"Lock(bytes)","9f7ed5b8":"startTimeTLP1()","9f7f0784":"appVersionListAt(bytes32,uint256)","9f7f2bd1":"createDog(uint256,address)","9f7f760c":"SimpleDice()","9f7ff381":"COMPLETION_STATUS()","9f8049ea":"distributeELTCLarge(address[])","9f807962":"buyMorties()","9f80d1b2":"presaleGoing()","9f810510":"ZONTEX()","9f8106cf":"transferAllUnsoldTokens(address)","9f819b13":"updateFunders(address,bytes32,string)","9f81c4d6":"bitcoingo()","9f83008a":"teamReserveWallet()","9f839d22":"getOptionPair(address,uint256,address,uint256,uint256)","9f853717":"duplicates(uint256)","9f855bd5":"shipLocation(uint16,uint16,address)","9f856de5":"doPurchase()","9f871242":"computeTokenAmount(uint256)","9f8743f7":"getRound()","9f87acd0":"exec(bytes32,bytes32,uint256)","9f87f419":"closeTierAddition()","9f881e0b":"MobSquads()","9f881f46":"checkPassed(address)","9f8970dd":"bountyTokensAccount()","9f8a13d7":"isActive(address)","9f8abede":"fixPermission(address,address,uint8,bool)","9f8adeb8":"givecandyto()","9f8ae5d3":"roundFourTime()","9f8aef2b":"ERC721Token(string,string)","9f8c45cf":"getQuestionDetails(uint256)","9f8c7c4c":"insertSums(uint256)","9f8e8209":"Cillionaire()","9f8f0dc3":"test_twoValidEqBool()","9f8f4c45":"developerPctX10()","9f8f4fb5":"withdrawAcquisitionsToken()","9f8ff91d":"getSponsorFee()","9f90279e":"f_priv()","9f903ff6":"setEmitter(address)","9f90688a":"SmartCityToken(address,uint256)","9f912d25":"abort(uint16)","9f915aca":"Tier_Starter()","9f91d145":"draftNewCardWithReferrer(address)","9f923388":"secondStageTokensSold()","9f9248c7":"DepositInterest(uint256,address,uint256,uint256)","9f927be7":"getNextCall(uint256)","9f941f69":"getDesignatedReportingEndTime()","9f943039":"Ethershares()","9f94d684":"irreducibleOf(address)","9f94fb7a":"endAtkBoss()","9f95de64":"transferToGrant(uint256,uint256)","9f961c5a":"salesPipe()","9f963c4e":"periodPercent()","9f96de0f":"getResourceCount()","9f9727ce":"QuotaManager(address)","9f977b21":"getBob(uint256)","9f97a024":"testEscapedQuoteInString()","9f97d937":"start_declaration()","9f97fdbb":"setDonationReceiver(address)","9f9827fa":"adviserPart()","9f98985d":"endGame(uint256,uint256)","9f98a45a":"fillOptionOrder(address[3],uint256[3],uint256[2],address,bool,uint96,uint8,bytes32[2])","9f98df30":"give(address[],uint256)","9f98e0f3":"addMerchant(address,string,string)","9f9936e7":"BullToken()","9f9938fa":"SILALAHI()","9f9a9b7d":"NDUXBase()","9f9ae633":"LademiA()","9f9b1048":"holderExists(address)","9f9b3d98":"softcap2Reached()","9f9b4c9d":"Unhalted(uint256)","9f9ea29d":"decodeLock(bytes)","9f9eac67":"ChangeName(string)","9f9f1fbe":"getRegionTax(uint16)","9f9f83dd":"remainingIssuableSynths(address,bytes4)","9f9fb968":"getDeposit(uint256)","9f9fe6bb":"acceptProvider(address)","9fa0f763":"buyDrugs()","9fa0fc4c":"pgoVault()","9fa2526f":"offline()","9fa45fa6":"sellMyStake()","9fa46754":"releaseBonus(address,uint256)","9fa4b6cb":"BetDex()","9fa50ab2":"voteDescription()","9fa5df9c":"decreaseAllowed(address,uint256)","9fa5e5d5":"setARKowner(address)","9fa6a6e3":"current()","9fa6f886":"NewParticipant(address,uint256,uint256,uint256)","9fa778d8":"UECToken()","9fa77b20":"reserveOf(address)","9fa80c6e":"rewardDistributionEnd()","9fa8e5a0":"SetEvaluate(uint32,uint8,uint64)","9fa92f9d":"home()","9fa9440c":"BDAYSALE()","9fa9559c":"getLastYearOfInflation()","9fa95bfe":"_emitJobPosted(uint256,address,uint256,uint256,uint256,bytes32,bool)","9fa987d5":"curPosition()","9fa9b04c":"ADVISOR_ONE()","9faa3c91":"beta()","9fab63c7":"ICOBIDToken()","9fabf4da":"remainigTokens()","9fac68cb":"burn(uint256,bool)","9fac6ddc":"withdrawLeftoverWei()","9fac9abf":"icoHasEnded()","9faceee4":"MemeToken()","9fad2dcb":"setTaxInBps(uint256)","9fae8fd8":"GayBananaToken()","9faea9c6":"setUnavailableFlat()","9faec3c9":"adminWithdraw(address,uint256,address,address,bool,uint256,uint8,bytes32,bytes32,uint256)","9faec927":"withdrawChunk()","9faefe0c":"sendNow(uint256)","9faf52ee":"teamTwoVolume()","9faf6fb6":"removeAddress(bytes32)","9faf7000":"manualSend(address,uint256)","9fafcf72":"PersonaRegistry(address)","9fb03244":"softcapMainSale()","9fb03c7f":"countLayersGasLimit(uint256)","9fb14d9b":"getRemainingBytesTrailingZs(uint256,bytes)","9fb1b5fb":"setJackpotGuaranteed(uint256)","9fb25d9e":"LeaderMessage()","9fb31475":"refundable(bytes32)","9fb3b7dc":"_setWeights(uint256[])","9fb3d489":"cancelProposalByCreator(uint256)","9fb42b1f":"numRequests()","9fb4c63d":"assertEq21(bytes21,bytes21)","9fb4d1b0":"_getDepth(uint256)","9fb52b6e":"dividendsGetPaid(uint256)","9fb5bdb9":"registerAsSeller(address,string,string,string,string)","9fb632c1":"private_withdrawBankFunds(address,uint256)","9fb65754":"FishProxy(address,address)","9fb65968":"presaleTokensDistributed()","9fb69839":"getTransactionInformation(uint256)","9fb6c796":"mint(bytes32,uint256,string)","9fb755d7":"setHotWallet(address)","9fb8657b":"getNodes(string)","9fb876c0":"getAllOwnersClaimPriceOfCard(address)","9fb8dd1a":"getBaseLockPercent()","9fb95205":"getWithdrawSum()","9fba2578":"summaryData(address)","9fbc6a1a":"EtherHellHydrant()","9fbdcef0":"setauctionotherfree(uint256)","9fbf538f":"addApprovedBattle(address)","9fc04ce2":"setMaxReferrerTokens(uint256)","9fc18031":"getNodesBatch(bytes32,bytes32)","9fc18d4b":"migrateDisabled()","9fc1d0e7":"forcedTransfer(address,address,uint256)","9fc1ff30":"InooviToken()","9fc20f60":"priceForSaleAdvertisement()","9fc21eeb":"wdrawBfr()","9fc23a74":"totalContractsAvailable()","9fc3587a":"releaseSupply(uint256)","9fc39549":"removeInvestorList(address[])","9fc3b4e7":"checkQuorum(uint256)","9fc3e53a":"controlstampdissolution(bool,uint256)","9fc53f30":"getIdByHash(bytes32)","9fc5852e":"BytePeachCoin()","9fc5ce2a":"initialMint()","9fc6ceac":"SponsorsQty()","9fc6d585":"percentageRecipient2()","9fc71314":"KontolToken()","9fc71b31":"transferToken(uint256)","9fc75354":"isMasternodeOwner(address)","9fc7a200":"startNumber()","9fc880f4":"weiRaisedAfterDiscounts()","9fc89294":"productTypes(uint8)","9fc8ed76":"serviceAtIndex(uint256)","9fc9141d":"calculateHash(bytes8,uint256,uint32)","9fc9278e":"returnAnyERC20Token(address,address,uint256)","9fc9ceb8":"HRWtoken(uint256,string,uint8,string,address)","9fc9d6c0":"FrannickToken()","9fcaa5ef":"extendMembership(uint256)","9fcb114c":"addSomeTokens(uint256)","9fcb29fc":"_assign(address,address,uint256)","9fcb7100":"approveAndCall(address,int256,bytes)","9fcbc6f1":"bitvimToken()","9fcbc738":"setIntermediate(address)","9fcc4767":"set_referral_fee(uint8)","9fcdec61":"buyPresale()","9fce2d80":"didCommit(bytes32,address)","9fce5c8e":"indexOf(address[],address)","9fce89a4":"intercrypto_recoverable()","9fcf11bb":"determineCurrentStage()","9fcf4115":"updateRoundEndTime(uint256)","9fcf89ee":"lastBlock_a13Hash_uint256()","9fd033ed":"isHolder(address,address)","9fd0506d":"pauser()","9fd1bd1f":"changeSelfAddress(address)","9fd1e7f6":"purchaseTokensERC20(uint256)","9fd3ad34":"setFunds(address,uint256)","9fd4da40":"totalInitialSupply()","9fd4f7d1":"replaceWizard(address)","9fd52984":"burnAfterSoldAmount()","9fd547fb":"PayeeWithdrawCapital(address,uint256)","9fd55832":"BrancheProportionalCrowdsale(uint256,uint256)","9fd64fea":"findAuditor(address)","9fd6adb3":"unVote(uint256)","9fd6d285":"AirdropMined(address,uint256)","9fd6db12":"mintingEnabled()","9fd7ca8a":"getCurrentTrancheIdx(uint256)","9fd859ee":"disablePreminer(address,address,address)","9fd8914d":"GameAAAToken()","9fd8b4f1":"redirectToPurchase()","9fd8bfb3":"voteCandidateOne()","9fd8c361":"CHECKgamberOne()","9fda3675":"MYYG()","9fda5ad2":"confirmedTimesByOwners()","9fda6271":"setElectionInfo(uint256,uint256,uint256)","9fdb35e7":"retriggerDrawOnOraclizeError()","9fdc0ea6":"getDirectoryLength()","9fdc3255":"_permittedPartnerTranferValue(address,uint256)","9fdc4d13":"isBuyable(string)","9fdc53b1":"registerLoanReplace(address,uint256)","9fdd32cd":"_drawFailure(uint32,uint8,string)","9fdd983f":"setAmount(uint256,uint256,uint256,uint256)","9fddd5a7":"SeedTestToken()","9fde4ef8":"winningOption()","9fdeeb5e":"teamVestingContractAddress()","9fdf057f":"setMiningToken(address)","9fdf9625":"seizeForWork(address,address,uint256,bool)","9fe005e8":"horseShoeNotForSale(uint256)","9fe03c59":"PayForPrivKey(address)","9fe14580":"BONUS_TIER_1_LIMIT()","9fe17cc2":"icoContractAddress()","9fe304a0":"catch_the_thief(address)","9fe34d9f":"isAllowedUser(address)","9fe39d85":"CHINESE_EXCHANGE_1()","9fe4712d":"schedule(address,bytes,uint256[8],uint256)","9fe4b663":"buyTokensInternal(address,uint256,string)","9fe5e868":"NewWallets(address,address)","9fe634b9":"getReleaseAuctionEndTime(uint256)","9fe6999a":"tokensFor1EthP5()","9fe72acd":"airDropsClaimed()","9fe7ac12":"removeBool(bytes32)","9fe7ba47":"updateFirstUnionIds(bytes32,bytes32)","9fe802f1":"transferEx(address,uint256)","9fe81f52":"changeTimeLimitMinutes(uint256)","9fe93231":"ICOEndedSuccessfuly(uint256,uint256)","9fe9bde0":"tripleRoomMin()","9fe9f623":"setTransferEnabled(bool)","9fe9fc1a":"SoldBlock(uint256,uint256,uint256,uint256,uint256,address)","9feb8d23":"amendClaim(uint8,uint8,uint8)","9fec4ac4":"SputnikPresale(address)","9fec8e3b":"addToWhiteListMultiple(address[])","9fec8e96":"claimedAmounts(address,address,uint256,address)","9fecb69f":"finishGame()","9fecf214":"XChain(uint256,string,string)","9fed35a6":"createBulkContributions(address[],uint256[])","9fed39c5":"numWhitelistedInvestors()","9feda172":"totalRice()","9fedb749":"setTeam(uint256,string)","9fee14ae":"getAllot(bytes32,uint8,uint8)","9fee597b":"extractEther()","9fef0ae1":"BetherFund()","9fef26ce":"buyTokens(address,uint256,string)","9fef93f8":"buyKey(uint256)","9ff00adc":"betOnOddEven(bool)","9ff031ce":"createEscrow(uint256,uint256,uint256,address,address)","9ff12bba":"removeContractMiniGame(address)","9ff1b56f":"lockInTime2()","9ff25fa4":"InitialDateChange(uint256,uint256)","9ff32b18":"grantAllowanceProxyAccess(address)","9ff33fd1":"getByInternalId(uint256)","9ff34878":"IPTVcontract()","9ff3487f":"ConsumerRemoval(address)","9ff36b54":"isClientPayed(uint256,address)","9ff390c1":"currentTotalBuyin()","9ff394a8":"goShort()","9ff4125a":"ICOendTime()","9ff47485":"isBetPossible()","9ff512fa":"getTransactionDetail(uint256)","9ff61487":"myBackerToken()","9ff652cb":"setToContractAddr(address)","9ff71ccb":"modifyCategory(uint256,string,string)","9ff7422d":"SurgeTestToken()","9ff7971b":"setWeiPerToken(uint256)","9ff8c63f":"issueMaxSynths(bytes4)","9ff9007d":"lastweek_winner1()","9ff93088":"settleGame(uint256,uint256)","9ffa0711":"CashOut(uint256)","9ffa43ce":"buyFST(address)","9ffaf32e":"resourceDelete(address,bytes4)","9ffb2ed5":"showRewards(address)","9ffbb57f":"SongTokenAdded(address,bool)","9ffc981f":"getDepositOwner(address)","9ffcc4c3":"getPayoutCumulativeInterval()","9ffd1c10":"TrueFlipICO(address,address,address,address,address,uint256)","9ffdb65a":"validateName(string)","9ffea547":"_purchaseOneUnitInStock(uint256)","9fff19ef":"_setValidatorWrotePart(uint256,address)","9fff37e0":"JACKPOT_SIZE()","a000812c":"Y1_lockedTokenReleaseTime()","a000aeb7":"weiReceived()","a0013419":"ShanxiCoin()","a001ecdd":"feePercentage()","a001ef87":"TestOneToken(string,uint8,string)","a00223ec":"_recordFirstClaimTimestamp(uint256)","a002b179":"getCandidateForApoderado(bytes32)","a003371e":"PreICOEarlyDays()","a003651d":"getNumberOfChoices(bytes32)","a0041286":"changeURL(string)","a00413bd":"resetReportTimestamp()","a004737a":"startPrePreIco(uint256)","a004ee5a":"isCustodianOf(address,address)","a00545b2":"claimPrize(address,uint16)","a00553a5":"WinnerIndex(uint256)","a005b87b":"NullMapTest()","a006b0e2":"_regName(bytes32)","a006e0e5":"phaseTwoLimit()","a0071552":"sellItem(uint256,uint256,uint256,uint256)","a007bc45":"getRateStages(uint256)","a008d288":"Pethreon(uint256)","a008d893":"isReferee(address)","a008f5eb":"_isNativeToErcBridge(address)","a0099b60":"deltaEFunc(uint256,uint256,uint256,uint256,uint256,uint256)","a00a3440":"mainSale1Limit()","a00a7a6d":"determineNewRoundMostInviter(uint256,uint256)","a00aede9":"scheduleCall(uint256,address)","a00afaa0":"ADMIN_GET_FEE()","a00b043e":"bonusTokenVault()","a00b603c":"getDNI()","a00c0a28":"Log2(string,uint256,uint256)","a00c3e72":"ExtendLife()","a00c9374":"afterSaleMinting(uint256)","a00ce377":"getIsContractValid()","a00ce6a5":"mintForReportingParticipant(address,uint256)","a00d7740":"setCUSDAddress(address)","a00d7b27":"myFirstHelloWorld()","a00dc9dd":"changesp1(address)","a00ddad1":"verifyBalance(address)","a00ec993":"setStarRate(uint256)","a00ee946":"existAccount(uint256)","a00f198a":"confirmOrder()","a00f64d6":"_soldOutsidePMZ()","a00f77e1":"getMemInvestor(address)","a00fd3c8":"register(uint256,string)","a00fd7c8":"getPayOut()","a00fe86b":"SaleAborted(uint256)","a00fff6f":"pendingManager()","a0109c9f":"incrementFee()","a0111086":"ParentFee()","a0113f18":"isCrowdsaleFull(address,bytes32)","a0129b00":"redeemSurplusETH()","a01317cb":"BlockHipo()","a0132df2":"validationTime(address)","a0135b2b":"updatefee(uint256)","a0135d04":"seSigner(address)","a013ab77":"isBuilt(uint256)","a013ad54":"BONUS_DURATION()","a013e4d0":"GouShiTokenFunc()","a014b9bd":"addReferralOf(address,address)","a015cb10":"claimOwnerEth(uint256)","a01701dc":"capPerAddress()","a01729a4":"communityCliff()","a0175360":"Approval(address,address,address,uint256)","a0175b96":"changeAllCosigners(uint256,address[],uint256[3],bytes,bytes,bytes)","a0179949":"feeAccount1()","a017ed35":"G12Coin(uint256,string,uint8,string)","a0187f91":"DataExternalValidation(address)","a018f2b2":"delegateProxyAssert(address,bytes)","a0193ff9":"allowed_contract()","a01a3a07":"LogTicket(uint256,address,uint256)","a01a478c":"getEnemyCombinationOfAddress(address,address)","a01a4cfa":"getMyInstancesOfAPackage(uint256)","a01b0c27":"getRegisteredContract(uint256,uint256)","a01bc729":"monster_attack(uint256)","a01bc8f6":"setdaily(uint256,uint256)","a01bfa79":"adminWithdrawBCEOPreSale()","a01c144e":"addPriceChange(uint256,uint256)","a01c489d":"setMaxFeeTrade(uint256)","a01c62f7":"isTransferLocked()","a01cb43d":"WithdrawFee(uint256)","a01de7ae":"BFToken()","a01e1a21":"setPendingReserveData(address,uint256,address)","a01eacc2":"Aerosyn()","a01fdbef":"approvePullRequest(bytes32)","a0214c1c":"mintClose()","a02172d3":"getAssData(uint256)","a0218b66":"getAccountAmount(uint256)","a021d76d":"deleteIssuer(uint256)","a022ac81":"test3Args()","a022c15e":"getTaskReward(bytes32)","a022da29":"increaseLoanOnBehalfOfRecurse(address,address,bytes32,uint256,uint256)","a022e283":"APOLLOCOIN_COMPANY_AMOUNT()","a0234a91":"supplyLockedA()","a023d4a7":"Redicon()","a023e7d3":"updateTrustRankAfterStoryExpiry(bytes12)","a024284d":"participantsForCustomSale(uint256,address)","a024ea16":"MAX_BOUNTY_ALLOCATED_TOKENS()","a025bcc3":"calculateFee(bool,bool,uint256,uint256)","a026348c":"pitboss()","a0263a5a":"addgodaddress(address,address)","a0268aea":"fcomToken()","a026946d":"ieth()","a026d7c4":"SunflowerToken()","a026da8c":"teamClaim(uint256)","a0270dbc":"resolve(uint8)","a02745af":"setarg_2_input(uint256)","a0275c05":"appendStock(uint256)","a02853ef":"BitcoinExchange()","a028554e":"setInitialMintingPowerOf(uint256)","a028aa1b":"distributeVariable(address[],uint256[])","a028d749":"caculateFee(address,uint256,uint8)","a02a338a":"tokensPerOneETH()","a02a34cd":"skinOfAccountById(address,uint256)","a02b114c":"setArray(bytes32,address[])","a02b161e":"unregister(uint256)","a02b1a51":"getPaid(bytes32)","a02b7fbe":"MANAGEMENT_TEAM_SUPPLY_LIMIT()","a02b9aac":"getPaymentDataByAddress(address)","a02c40e1":"qbxSourceToken()","a02c4b97":"holdAddress5()","a02c5279":"testIntegerKeyValue()","a02cf937":"feePct()","a02d2376":"SubContract()","a02e98df":"getAdd(bytes32)","a0305398":"getOtherMapValue(uint256)","a030b8e6":"restartsys()","a03189b3":"devPayed()","a0326040":"weekPot()","a0340625":"unfrozen()","a03435d1":"authorizerAddress()","a0345fca":"finalize(bytes)","a034b6cb":"vote(uint256,uint256,uint256,string)","a0354921":"setSTMPPrice(uint256)","a0355eca":"setTime(uint256,uint256)","a0355f4e":"decline(uint256)","a035b1fe":"price()","a036f0f8":"getUsableXPA(address)","a0376dfe":"getAskByUserID(uint32)","a0378730":"addReceivers(address[],uint256[])","a0385e1c":"superTransferFrom(address,address,uint256)","a038af35":"GetChallengeBetsInformation(uint256)","a0392897":"_decreaseApproval(address,address,uint256)","a039e3c7":"testSetNotTransferable()","a03b1ea9":"_getFee(uint256,uint256)","a03b66e5":"ZilleriumPresale()","a03c5832":"getPermissionParam(address,address,bytes32,uint256)","a03cc0b2":"setExchangeToken(address)","a03d0f06":"lockAccount(address,bool)","a03df051":"rentedLand()","a03eb806":"recoverAddressFromSignature(bytes32,uint256,address,address,uint256,address,address,uint256,bytes)","a03f254f":"getWebsocketUri()","a03f633a":"resetListing(bytes32)","a03fa7e3":"transferTo(address)","a03fb4c0":"makeTradeable()","a0417c9a":"updateAsset(uint256,string,uint256,uint256)","a0422d02":"COLOR_NOT_AVAILABLE()","a0422d31":"getApiById(uint256)","a0426fb2":"preSaleEnded()","a0428bbc":"balancesStaticoin(address)","a042b9c1":"newComment(bytes32,bytes32,string)","a04369f8":"addBoosterQuest(address)","a0437f63":"rewardBounty(address,uint256)","a043bb16":"tokensBoughtInBonusProgram()","a0440426":"purchaseProduct(uint256,uint256)","a044b070":"a(address,uint256)","a0452bfb":"dividendFee_()","a045fdff":"scheduleCall(address,bytes)","a0469b02":"inputToDigit(uint256)","a046c5f6":"NewStaticAdr(address)","a0472d6c":"blocksInADay()","a0489ac2":"draining()","a0493834":"unconfirmedSum()","a04a0908":"execute(address,bytes,uint256)","a04a59cc":"randMod()","a04a6ac8":"auctionEndPrice()","a04a85c0":"checkFrozen(address)","a04b3c2d":"mine_jade_ex(uint256)","a04bd02f":"getIsStartable(uint256)","a04cc350":"_addDefaultOperatorByTranche(bytes32,address)","a04ce2c5":"setArrayIndexValue(bytes32,uint256,uint256)","a04d4c60":"getDataColla_001_001(string)","a04da725":"SEXNToken()","a04e34bc":"weiAllowedToReceive(uint256,uint256,uint256,uint256)","a04f7bd1":"MMONToken()","a04fce5b":"MINDBODYToken()","a050975b":"requestReclaimContract(address)","a050d07d":"getNumWizards()","a05190f4":"BOT_ELEMENT_2()","a051b6b1":"phase_5_rate()","a052c595":"addTrustedPartner(address,string,string)","a052eae4":"writeStuff(uint256,int256,uint256)","a052f024":"addDonator(address)","a053ce1f":"referralRate()","a053eb9d":"OPERATION_STAKE()","a0548d2f":"redistributeLosingReputation()","a054cbea":"isPlatform()","a0557818":"getSireId(uint256)","a055d455":"run(uint40,uint256,address)","a055fe64":"_projectCommitNew(address)","a056469a":"extractFeeLength()","a0566330":"LJCJ()","a05693c6":"clearSmet()","a0572fda":"titleIds(uint256)","a0577762":"changeTechAccountAddress(address,address)","a0579801":"icoStoppedManually()","a057dade":"blackListUser(address,address)","a05809ff":"calculateTotalPayoutAmount()","a058ce51":"DigiCash1()","a059ffa6":"createNewTourament(uint256[])","a05a1218":"triggerStealManually2(string)","a05a70a7":"QTLToken(address)","a05b8ed8":"_execute(bytes32)","a05bba46":"getAllDepositorsCount()","a05c47ca":"ico2Max()","a05c7bda":"AuthorizeToTransfer(address)","a05d03fd":"currentSale()","a05d068d":"foundationTokensVested()","a05e1db7":"getBuyerfee()","a05e3bb0":"setBasicBallotsPer30Days(uint256)","a05e822a":"howManyOwners()","a05fc749":"CoinLotto(address)","a05fccef":"transferMultiple(address[],uint256[])","a0605a79":"ZTTBToken(uint256,string,string,uint8)","a060d498":"KillSwitchEngaged(address)","a060ecce":"checkPosition1(address,address,uint256)","a0617ad0":"totalMaxSupply()","a061eba0":"proposeVersion(address)","a0626939":"setFoundersTokensReserve(uint256)","a06285ed":"CharityInProgressSupply()","a062d5fe":"TOTAL_SATOSHI()","a063dae8":"equal(int256[],int256[],string)","a0641288":"redeemableBalance(address)","a064481e":"BokkyPooBahWuzHere()","a065a2bf":"distributeFAITH(address[],uint256,uint256)","a0660943":"computeSlaves(address,address)","a067412b":"assignInitialAddresses(address[])","a0684251":"remainder()","a068e8d3":"convict(uint256,uint256,uint256,uint256)","a068edb5":"determineOutcome()","a0695f24":"assertBalances()","a0695fc2":"startIcoOne()","a06ac637":"listUserRecasts(address,uint256,bool)","a06aceb2":"ATCController()","a06b7eb0":"decreaseLockedAmount(address,uint256)","a06c5a24":"monthlyPrice()","a06caae8":"TransactionSettled(uint256,uint256,uint256)","a06cab79":"Registrar(address,bytes32)","a06ced75":"RESERVE_LOCK_TIME()","a06d083c":"credit()","a06db7dc":"gracePeriod()","a06dd6dc":"emergencyFlush()","a06de4d9":"rand8(uint256,uint8,uint8)","a06e09f1":"PrivateSale(address)","a06e58ac":"isResolvedForComplainant(uint256)","a06ef4f2":"icoAmountBonus3()","a0712c3d":"feesRateTeam()","a0712d68":"mint(uint256)","a07245fd":"getHtlcPaymentBlock(bytes32,bytes32)","a0726b72":"getPresaleRaisedAmount()","a072f02b":"idvRegistry()","a0742666":"isParticipant(address,address)","a074d5ee":"unClaimedEther()","a0759e14":"setEmontRewards(uint256,uint256)","a075e164":"setup(uint256,uint256,uint256,bool)","a076da7a":"notifyExecuteSellOrder(uint256,uint256)","a076e223":"Declaration()","a077321c":"restrictUntil()","a0775baf":"AUTBToken()","a0776a59":"getTokenSupply(string)","a07778ec":"icoBonus3EndDate()","a077b298":"restrictions()","a077c657":"giveRightVote(address)","a078f737":"hasUserRole(address,uint8)","a0790cb7":"setFreezed(address,bool)","a0796236":"rejectWithdrawal(address)","a07b206f":"totalWhiteListed()","a07b2461":"proveIt(address,string)","a07c132b":"setPrevOwner(address)","a07c4fcf":"getTapRemaining()","a07c765f":"END_TIMESTAMP()","a07c7ce4":"burnable()","a07c8ed9":"changeName(bytes,bytes)","a07c9156":"UpdateWhiteListImplementation(bool)","a07da887":"deploy(address,uint256,uint8,address,uint256[])","a07daa65":"newRequest(uint256)","a07ead73":"setColdWallet1(address)","a07f0a98":"DEFROST_AFTER_MONTHS()","a07f3a56":"isAttended(address)","a07f3bb0":"UpgradeableStandard23TokenMock(address,uint256,bytes32,bytes32,uint256)","a07f5f84":"beneficiary3()","a07f8f19":"isCrowdSaleFinished()","a07fc020":"moveToRST()","a080249b":"BonusPoolSupply()","a08038be":"setPreferredCurrency(bytes4)","a080c8ba":"getLamboModel(uint256)","a081fc19":"deathData_f6()","a082022e":"Sell(address,address,uint256,uint256)","a0821be3":"availableBalance(address)","a0823111":"removeAffiliate(address,bytes32)","a08299f1":"divisionby0(uint256)","a082c86e":"DEADLINE()","a0831fdb":"BNBB(uint256,string,uint8,string)","a0836e28":"getaddressret(address,address)","a083cb48":"TokenBase(uint256,string,string)","a0844bb5":"_computeRarityBonus(uint256,uint256)","a0847a95":"updateRoundBalance(uint256)","a084af95":"Trust(address[],uint256,address,bytes)","a084ee76":"removeReturnAgent(address)","a0851928":"convert_valuation_to_art(uint256,uint256)","a0852bbd":"SynTokenAddress()","a0859845":"emitPreferredCurrencyChanged(address,bytes4)","a0876445":"artworkCount()","a0877304":"minSale()","a08783bf":"Moviecoin()","a087ac0c":"perDeadLine()","a087ae89":"calculatePeriodsCountAndNewTime(uint256,uint256)","a0893ef2":"releaseSupply()","a0895ec1":"LogUnfrozenTokens(string,address,uint256)","a089feea":"kill_switch()","a08aa298":"NewSupplyAdjuster(address)","a08b1447":"presaleAmountETH()","a08b3367":"EC()","a08c0908":"getFiatTransaction(string,uint256)","a08d3f83":"Etheropt(uint256,string,uint256,uint256,bytes32,address,int256[])","a08df770":"changeRecoveryFromRecovery(address)","a08e3f0e":"restTokensMoved()","a08e8b36":"totalFunctions()","a08ed1cb":"initUnstake()","a08f1b09":"getArrUintField2()","a08f8428":"BasicTokenWrapper(address)","a08fcabb":"setUint(bytes4,uint256)","a09037a9":"totalContracts()","a09107e1":"only6()","a0922e15":"calcTransferFee(uint256)","a0927a6a":"authorizedPayments(uint256)","a0929cda":"salvageTokensFromContract(address,address,uint256)","a092ae25":"getMyAllowance()","a094a031":"isReady()","a0954a49":"changeEarnings(uint256)","a09635b0":"_transferToICAP(uint256,bytes32,uint256,string,uint256)","a09686c4":"getRoundsCount()","a096ea1b":"bltRetainedAcc()","a0979332":"Bitcoineum()","a098a04b":"getRandomAnimalId()","a0996799":"getMyBulls()","a0997b66":"ROLE_RBAC_ADMIN()","a0999436":"ESOPAddress()","a099ad85":"workingState()","a099d079":"getEarlyIncomeByAddress(address)","a099e6be":"updateTokenExchangeRatio(uint256)","a09a05e0":"AllocateUnsoldTokens(address,address,uint256)","a09a1e22":"dealSellContract(uint256,string,uint256,uint256,string)","a09ae0aa":"absDiff(uint256,uint256)","a09b39ae":"WorldCup(string,string,uint256,uint256,string)","a09b7e2b":"totalPresaleBase()","a09cca93":"ownerTransferOwnership(address)","a09cec67":"_setData(uint256,uint256,uint256)","a09d4240":"UacCrowdsale(address,address,address,address,address,address,address,address[])","a09d4ae4":"returnTempTokens(address)","a09d9c09":"setTransferRate(address,int16)","a09ddd4f":"setSaleAgent(address,bool)","a09ddf4e":"getCurrentRgb(address)","a09de28d":"approveAndCall(address,uint256,bytes,address[],uint256[])","a09e3d0a":"getChildCount(bytes32)","a09e9c1d":"startBidding(uint256)","a09f6691":"LogGetMoneyBack(address,uint256,string)","a09f8659":"newConflictRes()","a09fb22e":"updateReputation(string,uint256,uint256,string,string,address)","a0a0d331":"COMPANY_WALLET()","a0a1082a":"createCustomVUP(address,uint256)","a0a2b573":"setTimestamp(uint256)","a0a2c11d":"ListValSince(uint256)","a0a2f629":"setReferralId(uint256,address)","a0a337e2":"getSetupFunctions()","a0a3ec6d":"getDividentsFromShare(uint256)","a0a4cb6c":"reveralSupply()","a0a4d9df":"batchTransferORSB(address[],uint256)","a0a5cd92":"OkapiToken()","a0a695fe":"registerTier1Users(address[])","a0a6e940":"finalizePresale()","a0a7131c":"test_twoValidAssertFalse()","a0a7299b":"feeInBps()","a0a76eb0":"charactersOf(address)","a0a7dc2e":"withdraw_1Completed()","a0a7e0f8":"GameCellCoin(uint256,string,uint8,string)","a0a8045e":"getEthUsdPrice()","a0a86de3":"PreSaleTokenSoldout()","a0a8e460":"contractVersion()","a0a95502":"reading_card_count()","a0a986f1":"price0()","a0aaa87f":"secondStageMinted()","a0ab2847":"tfg()","a0ab308c":"BidAskX()","a0ab7091":"_isCooldownReady(uint256,uint256)","a0ab9653":"execute(uint8[],bytes32[],bytes32[],address,uint256,bytes,address,uint256)","a0abdba0":"allocatorAddress()","a0ac47fe":"_ethereumToTokens(uint256)","a0ac5776":"claimBooty(uint256)","a0acb9dd":"getA(string)","a0ad04c0":"changePhaseToICO()","a0ad51a6":"KNOW()","a0aead4d":"getAssetCount()","a0af0127":"world(uint256,uint256,uint256)","a0af3252":"thirdCurrentAmount()","a0afd731":"dividendBalance(address)","a0afebbc":"emitContractAdded(address,address)","a0affbfd":"upgradeHGT(address)","a0b06190":"addOneUserIntoWhiteList(address)","a0b091e4":"sellMFCoins(uint256)","a0b1b385":"playerSetInput(address,uint256)","a0b1f668":"GetRandom_In52(uint256)","a0b28861":"createAndBuyAllAmountBuyEth(address,address,address,uint256,address,uint256)","a0b2995a":"GetParticipantRole(address,address)","a0b2becb":"getLastAcceptedProposals()","a0b31d58":"addPacksToNextPremiumSale(uint32[])","a0b3bef0":"NVBToken(uint256)","a0b4388a":"activateShip(uint32)","a0b43a4e":"getWinnerPot()","a0b45df2":"transferOwnershipAndToken(address)","a0b498a4":"issuedTokens(address)","a0b55095":"allGames(uint256)","a0b5cf5f":"changeResolverAllowancesDelegated(string,address[],uint256[],uint8,bytes32,bytes32,uint256)","a0b65332":"getProposalIdByIndex(uint256)","a0b70e87":"capTokens()","a0b76d49":"JToken()","a0b7967b":"getNextSequenceId()","a0b7dcb4":"_transferInternal(address,address,uint256,bytes,string)","a0b7ebbd":"isExistingPlayerInBattle(string,address)","a0b7f0f8":"updateContributorAddress(address,address)","a0b87d1e":"MuseumsChain()","a0b9e8d5":"getRaisedAmountOnEther()","a0b9f0e1":"checkPause()","a0bb233c":"changeFeeAndCheatWarrant(uint256,uint256)","a0bb7508":"_addSig(bytes32,address)","a0bc572b":"benefactor(uint256)","a0bcfc7f":"setBaseUri(string)","a0bd1ec1":"hodlerTransfer(address,uint256)","a0bd3c0f":"scheduleCall(address,bytes,bytes,uint256)","a0bdb04e":"tier1Start()","a0bdcd3a":"BCNewToken()","a0bde7e8":"getShareDistributionWithTimestamp(bytes32)","a0bde945":"buyCity(uint16)","a0be06f9":"adminFee()","a0be2d9d":"Inco(address)","a0bee465":"BrylliteToken(address,uint256)","a0befa94":"getStake(uint256,uint256)","a0bf0539":"_checkThreshold()","a0bf775f":"canTransferBefore(address)","a0c01e58":"divForPrice()","a0c07002":"ArcBlockToken()","a0c16fb6":"HuobiPoolToken()","a0c1ca34":"migrateIn(address,uint256)","a0c1e119":"unhaltFundraising()","a0c32df7":"TRMToken(address,string,string,uint256,uint256)","a0c354ea":"getSumAmountOfOpenDeals()","a0c3bc68":"setOverflowBounds(uint256,uint256)","a0c42ed1":"getPOOL_edit_12()","a0c567a2":"blackListActive()","a0c57eb4":"checkCrowdsaleState()","a0c642bd":"multisendFrom(address,address,address[],uint256[])","a0c66283":"ZEROCoin()","a0c66b43":"maxActiveCastle()","a0c6e65e":"getResourceBalance(uint16,address)","a0c73e7c":"HDAToken(uint256,string,string)","a0c86718":"assetOwnersIndexes()","a0c8ad10":"removeAuthorizedExternal(address,address)","a0c8c156":"emptyCart()","a0c8e0ff":"testCanSendEthToContractWhenCrowdsaleInProgress()","a0c95e24":"disableBuyingTime()","a0c96e43":"getCommissionTarget()","a0c97bce":"paySeller()","a0c99c51":"paymentInfo(address,string)","a0ca0a57":"backlogLength()","a0cce3d2":"getAssetIdCreator(uint256)","a0cde1f0":"finishCrowdCoin()","a0ce4ff8":"priya()","a0ce8a0e":"SingleSourceAuthority()","a0cecb3b":"findOutInterestByBank(uint256,uint256,uint256)","a0cf01d4":"MoneroGold()","a0cf17da":"amountFunded(bytes32,string,address)","a0cf8857":"setTransferFeeAbs(uint256)","a0cfbc1b":"getDeploytimeBlocktimeBlocknumber()","a0cfc196":"getNumWineryOperation(bytes32)","a0d045bc":"AppleToken()","a0d0b13d":"addBook(string,string,string,string)","a0d0be4f":"calculateValue(uint256,uint8)","a0d0ee3b":"buildTokenContract()","a0d121a9":"addPolicy(uint256,uint256)","a0d1de29":"sendSeedAndHash(bytes32,bytes32)","a0d1f9e9":"serviceIncreaseBalance(address,uint256)","a0d3253f":"spawn(uint32,address)","a0d39949":"_rewardUnnapprovers(address)","a0d46c87":"validateRequestParams(address[3],address,uint256[12],uint256,uint256)","a0d578f4":"isServerEnable(string)","a0d605c6":"addCertificationDocumentInternal(address,bytes32)","a0d63f7e":"setDistributionMinimum(uint16)","a0d7bb1b":"addReserve(address,bool)","a0d80e65":"internalNoter(uint256,uint256)","a0d81b21":"ConsentFile(address)","a0d87fc2":"burnFromOwner(address,uint256)","a0d8848c":"getTicketStartPrice()","a0d8ad85":"_updatePayment(uint256,address,uint256)","a0d8b4bd":"changePresaleDiscountPercentage(uint8)","a0d8b4e9":"ownerMintRate()","a0d8e231":"SmartpoolVersion()","a0d9669c":"test_invalidAddressNotZero()","a0da3236":"ActionMining(address,uint16)","a0da7d2e":"addressLocked(address)","a0db0a22":"right4(uint256)","a0db844f":"F2UPAY()","a0dbd8d6":"startBlockNumber_()","a0dbde9d":"logBase2(uint256,uint256,uint256)","a0dc6b74":"emergencyPay()","a0dce445":"nothingLib()","a0dd678b":"VCFToken()","a0ddb418":"currentKey()","a0dde02a":"AftabCoin()","a0df9538":"walletOwnerAddress()","a0dfc61f":"DICE_LOWER()","a0e06c8a":"weekPotHighscore()","a0e0c317":"getTradeOfferRecipient(uint256)","a0e1001e":"IiinoCoin(string,string,uint8,uint256,int256,uint256)","a0e16fed":"getFinalizationTime()","a0e1f42c":"addPurchaser(address)","a0e23ebd":"openAt()","a0e2abf7":"getFirstActiveGamble()","a0e4d7d4":"getManifestIdsByName(address,bytes32)","a0e5588a":"paymentAction(uint256,address,uint256)","a0e5bb69":"setPI_edit_17(string)","a0e5e821":"recordDealCancelReason(uint256,address,uint32,uint32,uint256,string)","a0e67e2b":"getOwners()","a0e6a44b":"getCustomerTxPaymentMCW(address,bytes32)","a0e724d3":"ReserveKnown(bool,address,uint256,uint256)","a0e7b4dc":"lastAmountSent()","a0e8b6b0":"the_address_for_option_A()","a0e8d21f":"join(address,string,string,uint256)","a0e8ef3d":"SetUSDPerETH_byContract(uint256)","a0ea0ef9":"constructionStart()","a0ea83dd":"SetSummRew(uint256)","a0eaa5dd":"lastTokenIsTransferableNumber(address)","a0eb5dd1":"AIRDROP_TOKENS()","a0ec4e09":"getUltimateOutcomes(bytes32[])","a0ec7f89":"transferPresaleTokens()","a0ed4cff":"MiniMeToken(address,address,uint256,string,uint8,string,bool)","a0ed6707":"EtopayNetwork()","a0eda9f2":"_transferFee(address,uint256,string)","a0edc204":"noOfPhases()","a0edc671":"USDtoHAV(uint256)","a0edcd7a":"burnPercentage100m()","a0ee153e":"isOwnerOrApproved(uint256,address)","a0ef8647":"BlueToken()","a0ef91df":"withdrawEth()","a0efe255":"m_categoriesCount()","a0f029fc":"ContractorInterface(address,address,address)","a0f04c38":"getKittyPower(uint256)","a0f0e95f":"DDJBTC()","a0f15b87":"registryICAP()","a0f1665b":"PriceSet(uint256,uint256)","a0f1ba62":"isOpenDistributionSetup()","a0f24ea7":"getTotalTokens(uint256,uint256)","a0f4a9a9":"Challenge()","a0f4d3df":"getRandomForContract(uint256,uint256)","a0f52da0":"startMigration(address)","a0f561ca":"ExtractDepositTime(address)","a0f61310":"FakeRelay(bytes)","a0f72985":"PassToken()","a0f78572":"Leaderboard()","a0f7bbcd":"sendTokensToAdvisors(address)","a0f82817":"Max()","a0f8be8c":"startOf(uint8)","a0fa0fb4":"ConstructorTest(uint256,uint256)","a0fa930a":"Ethercoin()","a0faf6a1":"getPortion(uint256,uint256,address)","a0fb1497":"deleteDocument(uint256)","a0fb7f57":"GMET()","a0fc4994":"setX(int256)","a0fe6202":"SHA256(string)","a0ff1705":"depositTokenFunction(address,uint256,address)","a0ffe7bb":"registerInNewMarketplace()","a0fffd5f":"rand(uint32,uint256)","a1007e68":"TokenAmountToPay()","a10132ad":"callbackGas()","a1013abb":"TOKENS_DISTRIBUTED()","a1017649":"updateWalletLock()","a101c2d3":"time_out()","a101f7cd":"bountyFee()","a1022294":"Guess(string)","a1029aff":"findTile(uint16,uint16,uint16)","a102e8a5":"addMeterpoint(int256,address,int256)","a103983c":"BitShopperToken()","a1049c06":"Zolox()","a104dcd4":"changeUpgradeAgent(address)","a104e5e1":"recordNewOwner(uint256,address)","a1057852":"addToken(address,uint256,string,string,string,string)","a106320a":"icoFinalized()","a1063d20":"addIntermediateAddress(address)","a106832b":"disableInitialAmbassadorStage()","a106dbc8":"participantsFor1stSale(address)","a106f0bf":"bonusAmtThreshold()","a107994e":"test_validProxyOwnershipTransfer()","a107ceb6":"affiliateUtility()","a10874d9":"SquirrelGims()","a1088571":"CEO()","a10889fa":"setVersion(uint32,uint32,uint32,string,string)","a10954fe":"reserveBalance()","a109a089":"addWalletAddress(address)","a109b8bd":"feesCal(address,uint256)","a10a7782":"defaultReputationReward()","a10b10f5":"setFriendsFingersWalletForCrowdsale(address,address)","a10b3ffd":"ALLOC_PARTNER()","a10bee85":"_transferFromWithReference(address,address,uint256,string)","a10c0fd5":"ROLE_MULTIOWNER()","a10c44fb":"s18(bytes1)","a10cda99":"isWhiteListed(address,address)","a10d4f56":"updateCaps(uint256[])","a10d6a51":"officialTelegram()","a10d80de":"quitBattle(uint256)","a10daf4b":"GroupMultiplier(uint256,uint256)","a10e057c":"preIcoMinimumWei()","a10e6d28":"arbitrationFeePerJuror()","a10ec6e5":"initialize(address[4],address,uint256[12],uint256,bytes)","a10edc55":"GeneralPurposeProfitSplitter()","a10ef122":"WWWToken()","a10f0f5a":"addField(string,uint256)","a10f42c4":"isICOEnded()","a10f43a3":"bountyReward()","a10f5610":"authoriseAddress(address)","a10fc32f":"setInstantTransfer(bool)","a110063a":"createGOP(address,string)","a1103f37":"attrUUID(address,uint256)","a110d350":"finalPot()","a1119bf2":"bountyFeeCount()","a111b0da":"InternationalTourismCoin(uint256,string,uint8,string)","a111bab9":"totalLockAmount()","a11223da":"airdropTokens(address[],uint256)","a1130d04":"createTemplateAndAskQuestion(string,string,address,uint32,uint32,uint256)","a1131e14":"withdrawSale3()","a113bf2c":"ZITOKEN()","a114b5ae":"_createZodiac(uint256,uint256,uint256,uint256,address,uint256)","a1155286":"deleteOrg(string)","a1155f5c":"buyBlockCDN()","a1158c43":"commissionCheck(uint256[],uint256[],uint256[],uint256)","a1159838":"removeFreeze(address)","a115e38f":"VirtueToken()","a11674b0":"divsOf(address)","a1169d72":"_payChain(uint256,address,uint256)","a11748fd":"ReceiveGBP(address,uint256)","a1183d50":"FixedSupplyToken()","a1188e56":"getCurrentDifficulty()","a118babd":"withdrawPayment()","a118ca27":"validateStep(uint256[],uint256[])","a118f249":"addAccess(address)","a1190a36":"withdrawOtherTokens(address)","a11976f6":"confirmTransactionAfterDisputeFee(uint256)","a119a65a":"gettodayget()","a11aab78":"createGame(uint256[],uint256[],uint256,uint256)","a11ab71a":"fundsToCommunity(uint256)","a11bab06":"GChain(uint256,string,uint8,string)","a11df9c7":"PlanetZeroToken()","a11e1645":"registrationRights(address)","a11e22d9":"toDate(uint256)","a11e7f5e":"get_iconiq_presale_open()","a11ed157":"setBirthFee(uint256)","a11f8de4":"FomoToken()","a1206d4e":"setUserContract(address)","a1207708":"confirmDividends()","a120fdbd":"dayTokenAddress()","a1210a69":"endIcoDate()","a1211bc0":"finalizeCampaign()","a121d8df":"testFailCreateWithParentSameItemId()","a122e060":"rateForPhase3()","a12301f5":"promethCount()","a1232723":"playerPrizes()","a123422e":"_setContributor(address,uint256)","a12396aa":"setName(uint256,bytes32)","a123c33e":"owner(uint256)","a12412f0":"CAT_PER_ETH_BASE_RATE()","a12433fa":"getLastAttack(uint256)","a1243ad3":"mintPartners(uint256)","a12498dd":"ownerEnablePayee(address)","a125c824":"setDefaultTokenURI(string)","a1264994":"setfounderAddress(address)","a126c5df":"GAS_TO_AUTHORIZE_EXECUTION()","a126d601":"closePosition(uint256)","a127cfb6":"LogRequestAccepted(address)","a12842cc":"sellMyTokens(uint8)","a1291f7f":"ownerTransfer(address,address,uint256)","a1298368":"stringEqual(string,string)","a129cb94":"summPremineBounty()","a129ecda":"SetdivForSellBack(uint256)","a12a52dc":"allOwners()","a12a6bb0":"KYC()","a12c2564":"preEndTime()","a12c7dd8":"presaleContribute(address,uint256)","a12cad70":"getPayer(bytes32)","a12d2de3":"withDrawToPoolOwnerFee(uint256)","a12d7e2c":"WubCoin()","a12da89f":"Deviser()","a12e429c":"getDiscipleNum()","a12e55d9":"rollIt()","a12e9670":"setMaxETHContribution(uint256)","a12ee7ba":"changeMaintainer(address)","a12f69e0":"divides(uint256,uint256)","a1315b7e":"createPricing()","a132a785":"removeOwner(address,bool,bytes)","a132aad1":"startPresale(uint256)","a132ab82":"startAirdropTime()","a132e336":"changeDeedPrice(uint256,uint256)","a1338118":"increaseAllowance(address,uint64)","a1344589":"vestedTo(address,address)","a1347622":"t_Michail2()","a1350c00":"migratePropertyOwnership(uint16[10])","a13615a5":"desposeBear(address)","a1365fda":"dev_streamsLength()","a136aadc":"getMinerHashRate(uint256)","a136c448":"updateTokenSellingPrice(uint256,uint256)","a1391297":"ETH_CLEAR()","a139dee2":"_deleteHybridization(uint256)","a13a7cee":"createChildren(uint32,uint32)","a13ae1ee":"updateTokens(address,int256)","a13c24c7":"BithubCommunityToken()","a13c58f7":"logCoinAgeRecord(address,address,uint256)","a13d2733":"updatePatientHealthData(string,string,uint256)","a13d3832":"deactivateTokenSwitch()","a13d8ec4":"generateFinished()","a13e3351":"transferRefPercents(uint256,address)","a13f9e58":"RESERVATION_CAP()","a1405522":"MilkCow(address)","a140a687":"localsService()","a140e4ee":"getDropNotices()","a140e79c":"setMinimumDebatePeriod(uint256)","a1410994":"intelligentmasschainToken()","a141ce6a":"packageOfferInfo(address,uint256)","a142040b":"Dil()","a142d608":"escapeHatch(address)","a1446287":"LKYToken(uint256,string,string)","a1448fa7":"secondRewardPeriodPercent()","a144a3e0":"whitelistTransferFrom(address,address,uint256)","a1450c8a":"XDRAC()","a1454830":"getExpirationTime(bytes32)","a145492a":"transferToPartnerAccount(address,uint256)","a145636b":"artworkIndex(uint256)","a14598e6":"changeBonusPercentage(uint256)","a14779c9":"airdropWallet()","a1490581":"Deal(address,uint256)","a1490d50":"getTradeHash(address,uint256,address,uint256,uint256)","a14977d5":"getCustomerTxCount(address)","a1498f50":"check_result()","a14a5648":"bonus02Start()","a14b877b":"refundEverybody()","a14c1c4f":"setSTO(address,uint256,uint256,uint8)","a14c36ce":"dGetPool(uint8,uint8)","a14c9bed":"resetCurrentIdTo(uint256)","a14cf394":"generateInitialCard(uint16)","a14d191c":"PausePublic(bool)","a14d427a":"transferBonusToken(address,uint256)","a14d6517":"tweetIt(string)","a14e0e4e":"runInit()","a14e88fe":"firstTokenCap()","a14ea9c0":"selfRegisterDIN()","a14eaada":"tipCreator()","a14fc1e7":"aDropedThisWeek()","a14ff857":"setBytes32(bytes32,bytes32,bytes32)","a150be7a":"distributionPreIcoCount()","a152479c":"_computeNextCommissionerPrice(uint128)","a152b23e":"UKW()","a15348fa":"TitleRegistry()","a1536211":"AtacToken()","a153b399":"ZeePinToken(address,address,uint256,uint256,uint256,uint256,uint256,uint256)","a15404b7":"createUnicornPrice()","a15454ba":"payTransactionFee(uint256)","a154aa36":"getTotalGoals()","a154ce82":"disableContract(address)","a155beb8":"buyerDatabase(address,uint256)","a156ce7b":"totalReimbursedWei()","a157696b":"setWhitelistedOnly(bool)","a1578d53":"EventBuyTank(address,uint32,uint32)","a157979c":"netOutcomeTokensSold(uint256)","a1580f1a":"damage()","a1581821":"transferWholeTokens(address,uint256)","a158e377":"statusICO()","a158e632":"lastLapId()","a1594d21":"DividendClaimed(uint256,address,uint256)","a159c548":"amountOfTokensPoolC()","a159c937":"getReferencePriceInfo(address,address)","a15a2289":"GameNumber()","a15a8613":"VoteCountPerProcess()","a15a9a15":"Presenca()","a15afb48":"Replicator()","a15b4d2d":"getAllCardByAddress(address,address)","a15b53ad":"pre_minContribution()","a15b9769":"addRandomClass(uint32)","a15bb363":"createBoardHash(bytes32,address)","a15c1788":"checkForLog(string)","a15cdbf7":"moveERC20Tokens(address,address,uint256)","a15d59ce":"totalVestedBalance()","a15db1c5":"_validateTokensAmount(uint256)","a15e3919":"getCrowdsaleUniqueBuyers(address,bytes32)","a16085ce":"the_address_for_option_D()","a16094d1":"burnMarketMakerApproval()","a160bdf5":"expiration(bytes12)","a1616429":"testBitOrSuccess()","a1616c92":"hasFreelancerMinRatingsCount(address,address,uint256)","a16249e2":"__min__(uint256,uint256)","a162a71f":"addToOwnerlist(address)","a162c04c":"buyTicketsFor(address)","a1636db0":"stepThree(int256)","a16383e2":"getTrustedTransferAttotokensValue()","a1639c6b":"customerConsents(address)","a163a624":"Test()","a163c090":"maxArtworks()","a164845a":"TheImmortalsPhoto(string,string,address,address)","a1654379":"isAllowed(address,address)","a1658fad":"canPerform(address,bytes32,uint256[])","a1659822":"UncursedToken()","a16618ae":"updateClientVersion()","a1663c48":"MIN_PRE_FUNDING_GOAL()","a1664ae2":"icoStartTimestampStage1()","a166b4b1":"addParticipant(address[])","a1672717":"getMinContributionInWei()","a1687d31":"isPlayer1sTurn()","a168d873":"gameAddress()","a1696076":"CCH_EDIT_3()","a1698315":"setExtraTokensWallet(address)","a169ce09":"boom()","a16a3179":"multiTransfer(address[],uint256)","a16bed3a":"changeTradeFee(uint256)","a16c6a73":"setClaim(uint256,uint256)","a16c86f7":"withdrawRefund(address)","a16cdbb1":"maxLockDuration()","a16d5960":"setPartner(address)","a16e5326":"CryptoSagaCorrectedHeroStats(address)","a16f3774":"getReservedTokens()","a16fa142":"generate_token_for(address,uint256)","a1702265":"keyEmployeesAllocation()","a17042cc":"getMsgValue()","a17177a1":"marketingTokensDistributed()","a171b694":"RefundIssued(address,uint256)","a172045d":"PUSH1()","a172db06":"portalAddress()","a1731366":"withdraw_to_reward_contract()","a173ba2f":"deathData_v2()","a1741d0f":"checkLiquidationValue(uint256)","a1743410":"_refundExceededValue(uint256,uint256)","a1744812":"setMaxCoordinate(uint16)","a174a8e9":"addNewColor(string)","a174c4c6":"mintAmount5()","a176d7c9":"createAndTransfer(address,uint256)","a176f6bc":"freezeTimeOf(address)","a1775db5":"isContract(address,address)","a1779a3d":"getFieldData(uint256)","a1784139":"updateChildMinLogos(address,uint256)","a1786803":"getCreationCost()","a1786d1b":"changeMessage(uint256,string)","a1787880":"createCustomToken(string,string,uint8)","a17a2685":"canUpdate()","a17a9e66":"A(uint256)","a17b229d":"total_fund()","a17ca853":"round(uint256,uint256)","a17cc7eb":"storedData(address)","a17d4228":"SingleApproval()","a17d5f44":"initializeWhitelist(address)","a17d713a":"stringToUint32(string)","a17dd26c":"buyWithReferral(address)","a17de881":"DigitalIntelligentToken()","a17e463c":"NbtToken()","a17ea25b":"getAppChainCode(uint32)","a17eb09f":"ExtraHolderContract(address,address[],uint256[])","a17ecf9e":"kill(uint256,address[],uint256[],uint8[],bytes32[],bytes32[])","a17eee56":"setGasRefundForClaimLoot(uint256)","a17f0bbd":"ICO_BONUS_TIME_3()","a17fa5f2":"fillRandomCars(uint256[],uint256)","a17feadb":"airdropAmounts(address[],uint256[])","a1804e67":"buyWithBalance(uint256,uint256,uint256)","a181b040":"SlammerTime(address)","a18232e8":"estimateTokenNumber(uint256)","a1826a9a":"CMK()","a182da60":"crowdSupply()","a1837d21":"ChangeBonus(uint256)","a183e9a5":"ErrorMessage(string)","a18473c2":"RequestCurrencyContractInterface(address,address,address)","a1848b61":"someMethod(uint256)","a1857f4a":"OTHERCRUISER_MAX_CARGO()","a1865376":"changePrice(uint256[],uint256)","a186e120":"setTokenTransferState(bool)","a18717a9":"addressToPass(address,bool)","a1883d26":"setTaxAddress(address)","a1885d9b":"whitelistWeiRaised()","a1888c34":"setGamblingFee(uint256,uint256)","a188b8fd":"accountAddressForSponseeAddress()","a188fcb8":"orderDepth(bytes32)","a189a487":"status(uint8)","a18a186b":"getCurrentOwner()","a18a2092":"changeTokenHolder(address)","a18a7bfc":"setReferrer(address)","a18bf6e9":"addFundAccount(address)","a18c1ab0":"burnToAddr()","a18c751e":"set(bytes,bytes)","a18ccc8a":"transferToWallet(uint256)","a18cd06c":"distribute(address,address)","a18dda19":"releasePayment(bytes32,address,uint256,address,uint256,uint256,address)","a18e0ce4":"addBorrowingItem(address,uint256,uint256,address,bool,uint256,uint256)","a18e133e":"registered_racers()","a18e2eb9":"left69(uint256)","a18ef171":"ALLN()","a18f43ef":"hasForfeitedBatch(address,uint8)","a18f7567":"Thecap()","a18f9b11":"drawWinners(uint256,uint256,uint256)","a1900c22":"takeTokenProfits(address)","a1903737":"addressOfTokenUsedAsReward5()","a1903eab":"submit(address)","a190500a":"tokenSecondPeriodPrice()","a1907386":"debugLatestPurchaseCentsValue()","a1920586":"offer(uint256,uint256)","a1920f36":"reservingStep()","a192274d":"initializeBread(uint256,string)","a192a425":"Founder1()","a192fdba":"bonusEnds10()","a1931ff9":"tryAnotherOne()","a1943113":"devWithdrawn()","a1945458":"getIdentityInfo()","a1960d80":"deferredKyc()","a19638e6":"betsCountToUseFreeBet()","a196593c":"findTenAmUtc(uint256)","a1965dca":"move(uint8,bytes,uint8,bytes32,bytes32)","a196981b":"withdrawCrowdsaleDragons()","a196bea0":"isDirectDebitEnable()","a1972fc4":"updateDividends(address)","a1975c38":"Token77G(address,address,address,uint256)","a197c042":"checkCustomer(address)","a197ec5d":"excessTokensBurnt()","a1988458":"readGlobalPurchasedToday()","a198a418":"LKLZ()","a1992419":"createCandidateOnElection(uint256,address,address,string)","a19b5493":"successed()","a19b8766":"transferTEST(address,uint256)","a19beba9":"addCompanion(address)","a19c1f01":"burnRemainder(uint256)","a19c406a":"newIdTankWeapon()","a19c9cd1":"getEthfromUSD()","a19cb5ee":"addHash()","a19db682":"defaultFoundersRewardTime()","a19e1d00":"bonusInPreSalePhase1()","a19e29a9":"claimUnsold(uint256)","a19ed39d":"finalizeFunding()","a19ee7a3":"changeMinMakerBetFund(uint256)","a19fab4c":"setWhitelisted(address,uint256)","a1a04486":"monthLength()","a1a0ee90":"LogPolicyApplied(uint256,address,bytes32,uint256)","a1a17ec3":"rentSign(uint256)","a1a1efe7":"addBallot(bytes32,bytes32,address)","a1a200c5":"getRankList()","a1a3e4c7":"UserIDChanged(address,bytes32)","a1a49a09":"unlockTimes(address,uint256)","a1a59f52":"_renew()","a1a5d118":"deployNetwork(address)","a1a66e56":"deductFunds(uint256)","a1a6d5fc":"transfer_(address,address,uint256)","a1a71a20":"buyCommon(address,uint256,uint256)","a1a71a83":"checkUsernameVerified(bytes32)","a1a7405a":"destTokensSgt()","a1a74aae":"removeMember(uint256)","a1a79f64":"_winAmount(uint128,uint16,uint16,bool)","a1a7e68b":"mintTreasuryTokens()","a1a85253":"ReturnBack()","a1a887b8":"isUserExists(address,address)","a1aab33f":"weight()","a1aad09d":"setBondPrice(uint256,uint256)","a1ab46d0":"DepositReceived(uint256)","a1ac727f":"airdrop(address,address[],uint256)","a1acd4b2":"AWD_SHARE()","a1acf069":"ArtChainToken()","a1ad2b99":"removeExchangeAccounts(address,address)","a1ad54e6":"holdingToken()","a1ad7cef":"tokenBurned()","a1adbb25":"addCandidate(bytes32,bytes32)","a1add510":"hasRelation(bytes32,bytes32,address)","a1aeb1c2":"paybackToOwner(address,uint256)","a1aec173":"COLOR_SILVER()","a1af90ad":"funcalls()","a1afaa19":"previligedUnLock(address,uint256)","a1b0f3a0":"userChallenge(uint256)","a1b140b6":"getDistributionStatus()","a1b162a8":"set_timeframes(uint256,uint256)","a1b16e5c":"returnAgents(address)","a1b1cb43":"hasAccess(address,uint8)","a1b1e507":"addMintingFactory(address)","a1b22154":"preemption()","a1b22c19":"delExcluded(address)","a1b235af":"popLanguage()","a1b258c1":"firstWeekBonus()","a1b289dd":"TulipToken()","a1b2acc1":"cancelApproval()","a1b35c79":"getSection(bytes32)","a1b39c38":"_removeMarkets(uint256)","a1b3ef4b":"flightDone()","a1b40946":"getWordIndex(string)","a1b4dd2d":"DXBCToken(address)","a1b4f57c":"joinBattle(string)","a1b5b581":"ymtest(uint256)","a1b608c9":"setMainPoolCutPercentage(uint256)","a1b64c86":"TokenMock(string,address)","a1b6b1b5":"updateUnlockData(address,address,uint256,bytes32)","a1b6d4ae":"REPLACES()","a1b77835":"getRefPercentsByIndex(uint256)","a1b7ae62":"setdirectorName(string)","a1b7ffb2":"_checkRequireERC20(address,uint256,bool,uint256)","a1b86605":"getHourglassBalance()","a1b8c40f":"lastDepositIndex()","a1b94c0b":"timeOfWin()","a1b9af31":"unlockBets()","a1b9cb8f":"getTitulaire_Compte_6()","a1b9e03f":"Unagold(address)","a1ba0331":"CoinTroops()","a1ba444d":"createOrder(uint256,uint256,uint256)","a1ba7554":"fibokenUsedCount()","a1bb6220":"halting()","a1bb7828":"make_transfer(address,uint256,uint256,bytes32)","a1bba310":"DonationDoubled(address,uint256)","a1bc13ad":"forgeItems(uint256,uint256,address)","a1bc76d1":"extendPRETDE(uint256)","a1bc7a8f":"sha3_512()","a1bd55c2":"TimeDecayingToken(address,uint256,string,uint8,string)","a1bda122":"returnInt16(int16)","a1bdd146":"setEndorsement(address,uint256,uint256)","a1be79a0":"equipUp(uint256[6])","a1bed0be":"GOAL()","a1bf8a9d":"endICO_w1()","a1bffefa":"emitCancelled()","a1c0539d":"scheduleCall(address,bytes4,bytes)","a1c14350":"getUpdateMarketPhaseCalled()","a1c1519a":"calcNewSkinAppearance(uint128,uint128)","a1c15f56":"CipherPlay(address,address)","a1c29db6":"MAX_FUNDING_AMOUNT()","a1c2f644":"address4()","a1c308d0":"ProspectorsGoldToken()","a1c448f1":"kingdomCreationFeeWei()","a1c4774b":"getCostToKick()","a1c4db02":"eth_meth()","a1c51915":"getB()","a1c68880":"final_share_price()","a1c6d088":"airDropTokenDestroy()","a1c80cea":"getUriCount(address)","a1c8ca7e":"removeClaim(address,bytes32)","a1c90a11":"updatePlayersCoinByPurchase(address,uint256)","a1c91040":"requestEvidence()","a1c93169":"DividendClaimed(address,uint256,uint256)","a1c934b6":"TestNetworkToken()","a1c95ac2":"GSIToken(uint256,string,uint8,string,address)","a1c9d235":"minimumElectionQuorum()","a1ca00c0":"ELIXAddressSetter()","a1ca70f4":"totalDiv()","a1ca8f8d":"LTRToken()","a1cb31b7":"_state()","a1cbae6c":"communityTokens2()","a1cd150d":"_calculateFee(uint256)","a1ce5ba7":"getIncentiveNum()","a1ce7e03":"openOrder(uint64,bytes,bytes32)","a1cea675":"cryptaurRewards()","a1ceb253":"mintAdvisorsTokens(uint256)","a1ceb359":"CryptoStrategiesIntelligence()","a1d0846c":"setPrices(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a1d0a48f":"addCurrency(string)","a1d0ab04":"allocateContributorsToken()","a1d10d11":"StoneLog(uint256,uint256)","a1d20653":"setVersion(bytes32,string)","a1d25205":"lowEth()","a1d27925":"personalContract()","a1d280d3":"releaseValue1()","a1d3612c":"DKS()","a1d36cb0":"checkClaimEntitlementofWallet(address,address)","a1d48aa8":"PaymentChannel(address,address,uint256)","a1d4c7ce":"_emitSkillRatingGiven(address,address,uint8,uint256,uint256,uint256,uint256)","a1d4c820":"Signum()","a1d53160":"Capital()","a1d5b36e":"calculateTxHash()","a1d61b07":"dateTier4()","a1d707a3":"setReleaseCar(uint256,bool)","a1d7d1dd":"setup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256[],uint256[],uint256[],uint256[])","a1d7ecbb":"updateShareETH(address)","a1d82cfd":"EBANK()","a1d86608":"_claimedSurroundingTiles(uint256)","a1d915b8":"ClaimTokens()","a1d91ee0":"technologyContract()","a1da2fb9":"retrieveDAOReward(bool)","a1da32be":"Shopiblock()","a1dab23e":"sellFloor()","a1dabfb2":"OAIToken(address,address)","a1db9782":"withdrawERC20(address,uint256)","a1dc139d":"setSigner(address,address,bool)","a1ddcd2d":"USDCX()","a1dddf70":"registerEthHandle(bytes32,address)","a1dea137":"checkBlacklist(address,address)","a1df7eb3":"YBKToken(string,string,uint256,uint256,string)","a1e03f57":"ratePerWeiInSelfDrop()","a1e04406":"preSale4Finished()","a1e0c2c9":"winnerCounter()","a1e15c33":"canuseOf(address)","a1e3b16d":"Crypseum()","a1e3c008":"mainSendTTC()","a1e4cb30":"investorsTotalSupply()","a1e4d3c2":"MembershipRoster()","a1e4eaf1":"updateUserBalance(uint256,bool,uint256,uint256,uint256,address,address)","a1e4f73d":"construct(bytes32,string,bytes32,address,uint128,uint256)","a1e51a79":"emitDestruction(uint256)","a1e564b1":"CashOut()","a1e59471":"HashBux()","a1e66038":"getTrusteeTable()","a1e6a255":"nextUserId()","a1e7e21c":"crowdsaleBurnAmount()","a1e89aec":"saleCount()","a1e8a780":"getAdPriceMultiple()","a1e93b63":"withdrawTipBalance(uint256,address,uint256)","a1e95792":"eatUnicornsAlive(uint256)","a1ea00bc":"isUserTakerFeeEnabled(address,uint256)","a1eb0bae":"eliminarjugador(uint256)","a1eb84b0":"transferOwnedOwnership(address,address)","a1ecb43c":"incrementLimitTeam()","a1ee7855":"ATT()","a1ee8c78":"issueToken()","a1ef9b8f":"reallocate(address,address,address,uint256)","a1f1aa66":"cancelVoteInternal(bytes32,address)","a1f1de65":"getPrizeAmount(uint256)","a1f24b3d":"getAssetDetails(uint256)","a1f36a78":"EROSCOIN()","a1f43f40":"UNICToken()","a1f4b9c8":"updatePlayerGen(address,uint256)","a1f54adf":"nextPremiumSale()","a1f56b0a":"getRollOutput(uint256,uint8,uint8,uint256,address)","a1f7f269":"_breedWith(uint256,uint256)","a1f841d7":"unlockFund()","a1f8adac":"investorList()","a1f8ea3b":"numOfDeliveredEarlyPurchases()","a1f902a7":"ComputeVestSpend(address)","a1f91057":"updateLock(bool)","a1fa39c4":"getRaisedPercents(address)","a1fa540d":"changeVotingBlocks(uint256,uint256,uint256,uint256,uint256)","a1fa566e":"getChannelPartners(bytes32)","a1fac24c":"Follow(bytes32,bytes32,bool)","a1fafe0c":"sendResidualAmount(uint256)","a1fb03f2":"GooCrowdsale(uint256,uint256,uint256,uint256,address)","a1fb1de9":"Message()","a1fb34c1":"setCustomExtraData(bytes32,uint256,bytes32,bytes32)","a1fc21f4":"setStaffDisbursementAddress(address)","a1fcc3bc":"stage2()","a1fd49b7":"getMFBalance(address)","a1fd92f5":"destinationMultisigWallet()","a1feba42":"tokensLocked()","a1ffba04":"PPGT()","a2008eb9":"acceptBidForStar(uint256,uint256)","a200dc73":"getNextShareholder(address)","a201222d":"recalculate(address)","a201bf26":"settleETH(bytes32)","a201d102":"VOTING_END_TIME()","a201ed8b":"transferMultiple(address[],uint256[],uint256)","a2023ff8":"setStartEndTimeTLP(uint256)","a202e476":"last_hash()","a20348c4":"ToPeriod()","a2035fef":"changeCustomTimeLock(string,uint256)","a20495d3":"Managed()","a20741dd":"getOperation(uint32)","a207b7fa":"SALE_FUND()","a208b3b7":"findFigures(uint256)","a2093e1b":"migrateCatOwnersFromPreviousContract(uint256,uint256)","a209a29c":"getStringValue(bytes32)","a20aede0":"phaseThreeRate()","a20b8ab3":"ttlInvestAmount()","a20bbb8b":"addBadge(uint24,int16,int16,uint24,uint256,string,string,string,uint256)","a20bc7fe":"allownce(address,address)","a20c15cf":"_generateCampaign(string,uint256[3],uint256[],uint256,uint256,uint256,uint256)","a20c404f":"ModifySettings(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a20cc495":"bytesFunc(bytes,bytes)","a20cd047":"moveTokenToAccount(address,uint256)","a20cf0e7":"setTokenNAVMicroUSD(uint256)","a20ddfb6":"getPartnerAddresses()","a20def62":"checkExistsOwnedAccessory(uint64)","a20e2525":"UnlockWei(uint256)","a20efba3":"mintGrey(address,uint256)","a20f46c6":"searchAddress(address)","a20f4ee6":"pixelCost()","a210a676":"buyBunny(uint32)","a210c6a9":"creatorPaid()","a210f934":"rateEarlyStage2()","a21174bb":"DefaultReverseResolver(address)","a2119377":"createToken(string,address)","a2119a3a":"allocateForRefund()","a2125232":"addItem(uint256,uint256)","a213051c":"individualMinPurchaseWei()","a21383cb":"permissibleTokenWithdrawal(uint256)","a213972c":"ViewBet2(address,uint256)","a213c280":"DayByDayToken()","a21515e3":"computed_shares_sold()","a2152e32":"testOracle()","a215457a":"transferBurnRole(address)","a215cd92":"setMinConversionRate(uint256)","a2167ac4":"_donations()","a216e0aa":"transferRobot(address,uint256)","a2177ff0":"getKeyLength()","a2187de0":"available_tokens()","a218d8ca":"clearAndDestoryAfterTwoWeeks()","a2190b46":"calculateTakerFee(address,uint256)","a21931ea":"CreateProposal(string,string,string,uint32,string,string,string,uint32,uint32)","a21a32cb":"Securities_1()","a21a65ae":"getIntArrayLength(bytes32)","a21d5b9f":"utilityLockedDate()","a21d942f":"checkResult()","a21df9f0":"THIRTY_DAYS()","a21e14fe":"reportInvalidDeposit(bytes32[])","a21ea6b7":"CrabCoin()","a21eea2a":"assertValidChallenger(address)","a21eef95":"getBarrierNum(uint16)","a21f0368":"History(uint256)","a21f74b8":"fundGooResearch(uint256)","a21f836e":"pubCount()","a21fbc92":"isAllowed()","a2200278":"checkStatus(bytes32)","a2200fbe":"AgreementUrlEn()","a220a90e":"transferLoveStoryWithData(bytes16,bytes32,bytes32,uint256,string)","a220d6c4":"tCampaignStart()","a2210352":"doRebuyTo(address)","a22107b4":"createRandomZombie(int256)","a222a52f":"firstPostIcoContributorId()","a222c98d":"declareWinnerForRaz(uint256,uint256)","a22304cd":"_specialDistribution(address,uint256)","a2233631":"withDrawal(address,address,uint256,bytes)","a2233c4d":"BancorConverterFactory()","a22352e2":"getDisputeFee(bytes32)","a2240eb0":"Scope()","a2248be0":"set_pre_kyc_bonus_numerator(uint256)","a224a5b3":"push_key(uint256,uint256,uint256)","a224c745":"setWhitelistAddress(address)","a224f4ce":"earningsFromScore(address,address)","a2252aaa":"referralProgramOwner()","a225d0be":"setTokensByWaveIndex(uint256,uint256,uint256)","a2261508":"tokenSpender()","a2267a3a":"newProposal(uint256,uint256,string)","a2271b15":"m_presaleFinished()","a22838b9":"ExecuteTrade(uint256,address,address,uint256,uint256)","a229090a":"dropTo(string)","a22913b5":"addTeamAddress(address,uint256,uint256)","a229b901":"transferApprover(address)","a22a31dd":"Forged(uint256)","a22b35ce":"_burnFrom(address,uint256)","a22b5a1c":"getFiles(bytes32)","a22b97f5":"withdrawOnBehalf(address)","a22ba787":"allocateETH(bool)","a22bb384":"GBAChain(uint256,address)","a22c81ec":"MIDGRADE_TYPE2()","a22cb465":"setApprovalForAll(address,bool)","a22cd657":"getImpactValue(string,address)","a22ce93d":"getActiveConsentTemplates()","a22d5a51":"deleteActivity(uint16)","a22dff2c":"getMainBalance()","a22e9009":"epm()","a22ec476":"setSireStop(uint32)","a22ed371":"mentalBalanceOf(address)","a22f2b2e":"set_lock_list(address,address,uint256)","a22fb98b":"updateBounty(string,uint256[])","a2302af9":"queryWinningTeam(uint256)","a2309ff8":"totalMinted()","a230c524":"isMember(address)","a231a84f":"ssp()","a232155d":"getbetresultfirst(address)","a2325259":"buyTokensWithUpdateRate(address,uint256)","a23281e6":"numPositionsExpired()","a2328e2e":"_FIVEHUNDRED()","a23291b6":"QUIOToken()","a232e64b":"createForum(string)","a235ae52":"setWithoutFee(address,bool)","a2362aca":"HyunJaeToken()","a2368e11":"setAirDrop(bool)","a236a3d7":"configRoundKeyAdd()","a236e665":"buyNac(address,uint256)","a236eb85":"subdivide(uint256,bool,bool,uint256,uint256,string,string)","a236f388":"getGameWin(address,uint256)","a23744f0":"tryCreateCheckRecord(bytes)","a2375d1e":"getC()","a237f4d8":"developerFundAddress()","a2393922":"getTokenDealRange()","a23951c8":"WidthdrawEarnings(uint256)","a239756d":"setRandom(uint256,uint256)","a239d260":"KinTokenSaleMock(address,uint256)","a23a373f":"DrawWinning(uint256,uint256)","a23a49c1":"setEscrowTokensWallet(address)","a23a5315":"SkyToken()","a23b5bd1":"getRandomUint256(uint256)","a23b791a":"Bitcoin()","a23bbb11":"GroupClosed(uint32,uint256)","a23bc6fe":"setTokenHolderAddress(address)","a23bec7b":"constrcutor()","a23bfd84":"weiPerCHF()","a23c3397":"getTokensPaidToGame(address)","a23c86c0":"allocateBulkTokens(address[],uint256[])","a23d20f4":"blockedDivisionJurisdictions(bytes32)","a23d3c35":"founderWallet()","a23d64c4":"isReturnRequested(address)","a23da130":"FundsRegistry(address[],uint256,address,address)","a23e21f7":"change(uint8,bytes32,bytes32,bytes20)","a23e3e89":"removeToken(address,uint256,uint256)","a23f41e2":"curs()","a2407c7b":"verifyUpdate(uint256,int256[2],uint256[2],int256,bytes32,address,uint256,uint256,uint256[3])","a240d8ad":"changeWeeklyRate(bytes32,uint256)","a241c089":"updateContract()","a2420f73":"EthermiumTokenList(address,address,uint256,uint256)","a24247f1":"getStartLockTime()","a242519b":"Technology3G(address)","a242f049":"ICOEndTime()","a243b6c1":"setPrice(uint256,uint256[],uint256[])","a243f512":"removeTrack(bytes32)","a244e03d":"definirMessage(string)","a244f365":"SbuyToken()","a245b774":"lockedFundsForthefuture()","a24636c1":"InvalidState(bytes)","a246d83b":"relaySellerCannotCancel(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32)","a2471fa5":"RecoverableWallet(address)","a2478c8d":"CT(uint256,string,string)","a247bc32":"payouts()","a24835d1":"destroy(address,uint256)","a248da12":"Exam()","a248de8f":"own(bytes32)","a248df4f":"XFC()","a249225e":"setAuthorizedUser(address,bool)","a2495ace":"transferCongress(address)","a2497b5c":"ETQuality()","a24a21fa":"TheBillionCoin()","a24bcf46":"calculateTokenAmount(uint256)","a24beff7":"closeBet(uint256)","a24c9737":"BUYER_CAP_HIGH_USD()","a24d23eb":"ProcessGame(uint256,uint256)","a24d9658":"revokeConsent(string)","a24dbe76":"StatusContribution()","a24e20de":"withdraw_dao_fund(address,uint256)","a24ea666":"withdrawedFundrasingPart()","a24ea868":"PROOF_MULTISIG()","a24ed4e5":"isLimitedWalletAddress(address)","a24ed8aa":"newLeader()","a24f1e82":"publiclyDistributedParts()","a25047a2":"hasEntry(address)","a25057de":"_transferToICAP(bytes32,uint256)","a250f43b":"verifiedWinnersLastCount()","a25236fe":"requestVotingRights(uint256)","a25277f3":"totalTokensCrowdSale()","a25287c5":"allowChangePrice()","a25367ff":"method2(bool)","a253c06e":"_circulatingSupply()","a25401ea":"PapyrusToken(address[],uint256[])","a254e662":"managementTokensDelivered()","a2550108":"alt_buyCollectible(uint256,uint256)","a2554c36":"walletForPresale()","a2558ee2":"holderReward()","a255d68d":"ticketTransferees(address,uint256)","a2564afc":"activatePermissionsBot(bytes32,bytes32)","a2564f7c":"randomNumberGen(uint256,uint256)","a2578f1c":"armyCountBattlesWon(uint256)","a258dafc":"getTopInfo(uint256)","a2594b83":"greylistMany(address[])","a2596576":"submitMint(int256,address,uint256)","a2596ebe":"returnTokensFromHoldProgectAddress(uint256)","a2597659":"changeMinAccEthers(uint256)","a25983e5":"lockTokens(address,uint256,uint256)","a25a34b1":"findPositionInMaxExpArrayTest(uint256)","a25b859d":"soldIdeaWeiIco()","a25b9384":"isUserAllowedToTransfer(address)","a25bc80c":"setPresaleState(uint8)","a25be434":"notifyTranferToken(uint256,address,address)","a25c1f3a":"presalePurchasesLoaded()","a25d8973":"createSale2()","a25e6898":"withdrawForeignTokens(address,address,uint256)","a25eb5d9":"exchangeToken()","a25f2d7e":"ReinvestmentWithdrawal(address,uint256)","a25f55d4":"getBatchSize()","a25f5e98":"doAdditionalMinting(address,uint256,int256)","a25fc8dc":"adminAddCity(string,uint256,uint16)","a25fdcec":"editPlanet(uint256,uint256,string,string)","a25ff42d":"HumanStandardToken2(uint256,string,uint8,string)","a2605dc1":"EventLuckyNumberRequested(address,uint256,uint256,uint8)","a2609759":"transferPreSignedMany(address,address[],uint256[],uint256,uint256,uint8,bytes32,bytes32)","a260c045":"PROMETHEUS_SHIP_LIMIT()","a260d8da":"makePresaleReady()","a26176b1":"testInequalityUint()","a2624afe":"raiseJackpot()","a262c092":"CollectChipBag()","a26329f0":"finalizeRefunds()","a2635401":"getCurrentGameId()","a263601c":"find_contribution(address)","a26388bb":"testRevert()","a263c7ba":"changeBuyPrice(uint256)","a263e793":"EdittedEntry(address,uint256)","a2644eb0":"withdrawFullTokenBalance(address)","a264f18e":"CROWDSALE_ETH_IN_WEI_ACCEPTED_MIN()","a2651d30":"purchaseAreaWithData(uint24[],uint24[],uint256[],string,string,uint256)","a2657960":"DolyToken3()","a26636f3":"StpacToken()","a266b0f2":"CoinStacks()","a266c820":"changeARIWallet(address)","a266f4da":"liquidateFund()","a26730e1":"minRelease()","a26759cb":"addFunds()","a267b5cf":"TokensTransfered(address,uint256)","a268b332":"testBitXorFailIndexOOB()","a269202f":"setHash(address,bytes32,address,bytes32,uint256)","a269e31f":"setPrices(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a26a1bc9":"clearLockUser(address,uint256)","a26ac680":"BoBoToKen()","a26b0e34":"dbVal(address,uint256)","a26b2d76":"StepCoin()","a26b8822":"tokensSoldExternal()","a26bddb4":"LockedTokens(address)","a26c7810":"mintToTeamAccounts()","a26d494d":"getEscrow(address)","a26d6de6":"LogWithdrawal(uint256)","a26d7b94":"isCrowdSaleClosed()","a26dbf26":"totalParticipants()","a26e1186":"deposit(string)","a26e7a6c":"_initOpinion(uint256,string)","a26efcf8":"startGame(bytes,address,uint256,uint256[],bytes)","a26f644c":"Transfer_of_authority_data(address)","a270907c":"Btcandres()","a270a737":"venue()","a270cdf3":"getMarketInfo(bytes32)","a2720018":"freelanceFillBonds(address)","a2729a01":"updateDelegatorWithEarnings(address,uint256)","a273079a":"addLog(string,string)","a2730c23":"EthToAFW(uint256)","a273738c":"preICOEndTime()","a27411d8":"Earthpayment()","a2741bdb":"MAX_CITIES()","a2744a22":"addProduct(uint256,uint256,string,uint256)","a275ee1b":"getDeployTime()","a27678c9":"preDGZToken()","a277051f":"userAddr()","a277b787":"CARXTOKEN()","a277d5b1":"totalTokensPurchased()","a277fa88":"setWhitelistOn()","a2788b58":"ConflictResolutionManager(address)","a278ce66":"backWindowAdjustmentRatio()","a278fdfb":"bidOnAuctionToBuy(uint256)","a27966dd":"finishselfdrop()","a2798f0a":"GetQueueNumber()","a279c488":"addPending(address,uint256)","a27a9e7f":"publicAmount()","a27aebbc":"extendTime(uint256)","a27b9bf4":"matchcoin(uint256,string,string)","a27c1756":"ECONOMY_BOOST()","a27c3a2d":"HngCoin(uint256,string,string)","a27c672a":"owner_reveal_and_commit(uint8,bytes32,bytes32)","a27c794b":"insertDetails(string,uint256,uint256)","a27c9af0":"gameDestroy()","a27d8298":"leader_3()","a27e0e67":"QLFY()","a27ee939":"payto3()","a280b3db":"preSaleBonus3Time()","a280ce8f":"distributeWinnerPot()","a280e67a":"leftnum()","a28103f2":"batchTransfer2(address[],uint256[])","a283063c":"ChargeFee()","a2832c97":"CappedDividendToken(uint256)","a283c9c5":"getLastBidAmount()","a283f907":"addOrderContract(address)","a283fd00":"getPendingPaymentAmount(address)","a284b6d3":"maxTicketAmount()","a28504b4":"isSwapDone()","a28555d5":"setTAOFamilyAddress(address)","a28576aa":"LogUserRegistered(address)","a285f19f":"signedTransfer(address,address,address,uint256,uint256,uint256,bytes,address)","a2860050":"estimateReturns(address,uint256)","a28641cc":"_buyTile(address,uint256,bytes)","a2866a78":"HouseICO()","a28812c2":"existingIds()","a288237c":"MeSum()","a288b609":"releaseOf(address)","a288fb1f":"setConfigUint(int256,bytes,uint256)","a2890972":"synthesize(uint16[5])","a289409b":"addAddressesToAdmins(address[])","a289673b":"fipsChangeOwner(bytes20,address,address)","a289d187":"depositDividend()","a28a1564":"GBToken()","a28b1ffd":"isLive(uint32,int256)","a28bc99a":"TipSmartToken()","a28c644d":"setACLRole5999294130779334338(address)","a28c76cc":"initialize(address,address,address,bytes32,uint256,uint256,uint256)","a28d0185":"removeComponent(uint256,uint256)","a28d57d8":"btc()","a28e68d3":"setOnceMintAmount(uint256)","a28ecf0b":"sendCryptedHand(bytes)","a28f19f8":"AddDroneItem(address,uint256,uint256)","a29063c1":"LuckyNumberImp()","a290f4f2":"logoPrice()","a2919502":"getWalletLibrary()","a29256bd":"Ethereum()","a292f7d3":"paymentEscrow()","a29337bd":"tokensToCompany()","a293688b":"triggerFindWinner()","a293cba1":"LETSCOIN_Token()","a293d1e8":"safeSub(uint256,uint256)","a29445a9":"EnclavesDEXProxy(address,address,address,address,uint256,uint256,address,bytes32,bytes32)","a294542f":"setPreSaleTLYperETH(uint256)","a2948cdf":"futureDevelopment()","a294ed7a":"voterAddressOf(uint256,uint256)","a2950fd8":"Birth(address,uint256,uint256,uint256,uint256,uint256)","a2958b76":"_transferOwnershipOfStorage(address)","a29626c2":"createSingleSeedAuction(uint8,uint8,uint256,uint256,uint256,uint256,uint256,uint256)","a296b323":"setTransfer(bool)","a296fed8":"HitToken(uint256,string,string)","a297d43c":"openDistributionContract()","a2987245":"getIntArrayIndex(bytes32,uint256)","a298ba7c":"AntiqueCoin(address,uint256)","a299b155":"setInitialTokensBalance()","a29aaad6":"MatreXaCrowdsale(uint256,uint256[],uint256[],uint256,uint256,uint256,uint256)","a29b7fa0":"TklnAirdropToken()","a29c3574":"OrgonToken()","a29cc6c8":"allocateVestedTokens(address,uint256,uint256)","a29cd847":"changeEndPreSale(uint256)","a29d4859":"drpuToken()","a29d578a":"changeABaddress(string,address)","a29dbf46":"isAllowedToSend(address,address)","a29f9fb9":"onChainAddresses(bytes32)","a29fe9b1":"UBOToken()","a29ff28d":"receivedStaAmount()","a2a02202":"smg(uint256)","a2a0d0fc":"pre_endTime()","a2a140f9":"MinInvestment()","a2a1521a":"SignalPylon(address)","a2a17629":"addrBroker()","a2a206c0":"ImperoITCoin()","a2a23fb2":"getVersionsLength()","a2a256b9":"AirDroppedTokens(uint256)","a2a3d051":"B3(uint256,string,uint8,string)","a2a483ee":"setCS(address)","a2a51ccd":"transferToCrowdsale(address,uint256)","a2a5243c":"_calculateExcessBonus(uint256,uint256)","a2a53c7c":"Exercise(uint256)","a2a6aa11":"TileClaimed(uint256,uint256,uint256,address)","a2a6ca27":"setMinPerTx(uint256)","a2a746e1":"moveToInitiator(address,address,uint256)","a2a8336f":"claimEtherSigner(uint256)","a2a84a5d":"zonesSwarmAddress()","a2a8e279":"getTokensForEther2(uint256,uint256)","a2a957bb":"setFee(uint256,uint256,uint256,uint256)","a2a96799":"totalSuply()","a2a9a6c1":"satellite()","a2a9d1ef":"initReverseENS(address)","a2aa0724":"enterLottey()","a2aaa10e":"DigiCrowdSale()","a2ab2686":"participatePresale()","a2ac0a1a":"getUserAssetBalance(address)","a2ac5360":"calculateFounderCut(uint256)","a2aca613":"buyLicense(address,address,string)","a2ad16ed":"WinEToken()","a2ad360f":"SUV()","a2ae72ec":"open_commitment(uint256)","a2ae86ac":"setUntsqm(uint256)","a2af0e37":"assignPlayer(string,address)","a2af5fe9":"content(string,string,string,uint256)","a2b038b3":"addOffChainRaisedContribution(address,uint256,uint256)","a2b0867d":"Admined(address)","a2b0f9f6":"setMaxWeiForVerificationLevels(uint256,uint256,uint256)","a2b144f0":"getGasForMcr()","a2b1da51":"inflat(uint256)","a2b21d7d":"trainSpecial(uint256,uint256,uint256[2],uint256[2])","a2b40d19":"changePrice(uint256)","a2b424b1":"firstPresaleEnd()","a2b475f3":"levelOneBonus(uint256)","a2b5591c":"oraclize_query(uint256,string,string[],uint256)","a2b60f43":"EmployeeMigrated(address,address,uint256,uint256)","a2b6cbe1":"deleteTxDataBlockNumber(bytes32)","a2b6f0ec":"addRewardToPendingWithdrawals(uint32)","a2b7976d":"bbye()","a2b7a18b":"BCE()","a2b7e23d":"queueMode()","a2b8891e":"getFreeKebaber()","a2b946aa":"getNewGame()","a2bad039":"getCompte_27()","a2bb5d48":"get_username(address)","a2bb635a":"WhitelistedAddress(uint256)","a2bbeac2":"Shares(string,string,uint256,uint256)","a2bc0e31":"testCheckRokTeam()","a2bc183f":"secondPlacePot()","a2bc1cd4":"getNumEthOfferors()","a2bc2eef":"CipherPlayToken(address,address)","a2bcb304":"setfanbei(uint256)","a2bccae9":"plyrRnds_(uint256,uint256)","a2bcee8b":"build_creature()","a2bd018c":"targetDiscountValue3()","a2be1761":"addDiscounts(address[],uint256)","a2be23cd":"BASIC_RATE()","a2be427d":"updatePlayer(uint256)","a2bf1d06":"DURATION_NONUSETEAM()","a2bf68b9":"membership()","a2bf6939":"setTokenValue(uint256)","a2bf6f7e":"ClaimedStatus(address)","a2bfae64":"mmin(uint128,uint128)","a2c030a5":"changeRootAuthority(address)","a2c17459":"getCreateUnicornFullPriceInCandy()","a2c25131":"LogItemUpdate(uint256)","a2c2ed9b":"killContract(uint256)","a2c3a542":"getFallbackDepositPeriod()","a2c3b256":"receiveCheck(address)","a2c3bd83":"TokenInvestment(address,address,uint256)","a2c41366":"getIcoBonus()","a2c44503":"doesUserHaveBalance(address)","a2c4895a":"encodeOperator(uint256,uint256)","a2c4a06f":"startTimeOne()","a2c4c336":"getPurchaseReturn(address,uint256)","a2c4d268":"addToRef(uint256)","a2c52c4d":"CoreMediator()","a2c6fa83":"transferFromStudio(address,address,uint256)","a2c77e68":"isLeftTokens(uint256)","a2c8b76b":"getPriceFor(uint256,uint256,uint256,uint256)","a2c93406":"blinc()","a2c99d47":"rateAfterValidation(uint256,bool)","a2c9d630":"manualPrice()","a2cc1f62":"disagree(address)","a2cdd471":"cc()","a2cdd82f":"setAuctionObj(address,uint256,uint256)","a2ce0f87":"min_contribution()","a2ce4215":"TOKEN_PREICO_CAP()","a2ce588d":"roundExpired()","a2cff990":"getHeroCurrentLevel(uint256)","a2d0b147":"RedTicket(uint256,address)","a2d0f942":"canRedeemUTXOHash(bytes32,bytes)","a2d10ba5":"kyber()","a2d1c624":"checkKingFounder(address)","a2d1cf11":"propheciseExecute(address)","a2d24c5e":"getFirstTranche()","a2d39bdb":"addKey(address,uint256)","a2d3e2be":"ReleaseTimeChanged(address,uint256,uint256)","a2d435d4":"icoTotalCollected()","a2d46832":"speech(uint16)","a2d4db9c":"newUpload(bytes32,string,uint16,bytes32)","a2d57853":"receiveApproval(address,uint256,bytes)","a2d5b8bf":"withdrawBoardMeetingFees()","a2d6a926":"CapCoinInternational()","a2d6d382":"videos(bytes32)","a2d6f8de":"startEarlyStage4()","a2d74227":"spendToken(uint256)","a2d74b29":"setJobHiringDone(uint256)","a2d819b4":"getSenderSig()","a2d83b5e":"update(address,uint256)","a2d89edf":"bountyInit()","a2d97fa7":"TimeLockr()","a2da2b47":"ausGroupReleaseDate()","a2da84f8":"setCAOAmount(uint256[])","a2db644e":"vestingTransfer(address,address,uint256)","a2dc7dcf":"initialize(address,address,address,address,address,address,address,address,address,uint256,uint256,uint256,uint256[])","a2dc9d9c":"ChangeMessage(string,string)","a2dcb5d4":"bindUserWithBoard(uint256,address)","a2dd2e96":"InitCancel(address)","a2dd3283":"setICOContract(address,address)","a2dd9dd3":"canMateWith(uint256,uint256)","a2de29d4":"setReleaseAmount(address,uint256)","a2de45b7":"Listed_Validated(uint256,string)","a2de5b50":"buyWithPromo(address)","a2dea26f":"sendAllocation(address)","a2deadbd":"getTransactionHash(bytes)","a2dee527":"setSaleBonus(address,address,uint256)","a2df26f5":"printMarket(int256)","a2df6c42":"splitFirst(string,string)","a2df7465":"DeepToken(address,address,address,address,address)","a2dfa2f0":"buySampleTokens(address)","a2e0ee3e":"theWinningReferral()","a2e1a8d8":"isOwnerAddress(address)","a2e23a51":"TAIL_EMISSION()","a2e2842e":"ChannelSecretRevealed(bytes32,address)","a2e2998c":"setPricePerMessage(uint256)","a2e3750c":"preSaleCSSC()","a2e38b54":"getTransactionIds()","a2e40e50":"endorse(bytes32)","a2e55e88":"IQB()","a2e5f168":"DaoAccount(address,address)","a2e62045":"update()","a2e65477":"changePeriod(uint256,uint256,uint256)","a2e7223e":"isNewPlayer(address)","a2e7241c":"citizensAddresses(uint256)","a2e800ad":"rounds()","a2e841ba":"getUnprocessedQueryBytes32(uint256)","a2e855a5":"batchFillOrKill(address[5][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[])","a2e91477":"publicSaleStarted()","a2ea2aaf":"CreateToken()","a2ea771f":"receivedTokenOf(address)","a2ea7c6e":"getSchema(bytes32)","a2ea80f9":"setPayableEnabled(bool)","a2ea9883":"OwnerChanged(address)","a2eaa896":"winningBidder(string)","a2eb0d01":"gift_CreateTINAmotleyLine(string)","a2eb164d":"lockUpdateTokenAccount(address,bool)","a2ebaa1d":"TEAM_PERCENT_EVE()","a2ebb20b":"icoHolder()","a2ec191a":"addDSource(string,uint256)","a2ec258f":"future()","a2ec5414":"getAllowanceExpiration()","a2ee1a27":"sellPrice_wie()","a2ee4000":"cancelSalesOffer(bytes32)","a2ee8669":"PussyToken(uint256,string,string)","a2eeb5d4":"pyramid(uint256)","a2f09dfa":"addFund()","a2f1607c":"_calcLockRewardPercentage()","a2f16d80":"dexWithdrawCollectedFees()","a2f182d4":"setLimits(uint256,uint256,uint256,uint256,uint256)","a2f23659":"VPCx()","a2f26fb2":"FTTIssued(address,address,uint256,uint256)","a2f3139c":"stagedVestedLockUpAmounts()","a2f35f44":"addNewAddress(address)","a2f37360":"addSponsorshipAmount(address,uint256,uint256)","a2f39dc6":"OLDSPTI()","a2f3ba5b":"setSynthetixState(address)","a2f3ede2":"computeNameHash(bytes)","a2f44e72":"p_update_action(uint256,address,address)","a2f45660":"Purchase(address,address,address)","a2f4f550":"getDataPointForSubject(uint256,uint256,int256)","a2f56b2c":"refundEth(bytes32,address,uint256)","a2f5ee48":"CarbonExchangeCoinToken()","a2f6e5fb":"ViewMyDivs(address)","a2f77bcc":"getGame(uint256)","a2f78d7a":"startICO(address,address)","a2f792d5":"AdministratorAdded(address,address)","a2f7a2e0":"changeIcoPhaseAmounts(uint256[])","a2f7b3a5":"instances(uint256)","a2f7b7fd":"callTokenFallbackIfNeeded(address,address,uint256,bytes)","a2f7f58f":"getBetAmountOf(uint256,uint256)","a2f91af2":"cage(uint256)","a2f95b44":"committeesArray(uint256)","a2f9eac6":"persons(uint256)","a2fa0157":"isAssetActive(address)","a2fb1175":"winners(uint256)","a2fb342d":"lend(address,uint256)","a2fb98fa":"starting_clones()","a2fba23c":"holderGroup(address)","a2fbe98c":"haveIWon()","a2fc0bd5":"BuyEvent(address,uint256,uint256,uint256)","a2fc2254":"LAFINAL3()","a2fcd1af":"amountRaisedInUsd()","a2fd0179":"unlockBatchOfAddressesAfterITO(address[])","a2fdea11":"getBonusCoefficient()","a2fe802b":"isExit()","a3000128":"getContributionHash(address,uint256)","a3006abf":"buyBoosterPack()","a3006f5f":"CETFToken()","a300aa66":"RIKCoin(address,address)","a300c6ae":"confirmCollRecv(uint256)","a300eadf":"_getAllParents(bytes32)","a3011a02":"WatcharaHashCoin1()","a301b493":"Milestone_IcoFailed(string)","a3022667":"modifyAllLevelCaps(uint256[])","a302fdf1":"WHITELIST_BONUS_RATE()","a3030b10":"getTournamentBattleResult(int256,int256,uint256,uint256,uint256)","a3031b77":"getTradeCount()","a3032f25":"claimTreshold()","a3035454":"WeiControllerFactory(address)","a30376b7":"getReferralCount(uint256)","a3045113":"payUp()","a304f625":"updateInheritedEarlyParticipantWhitelist(address,uint256)","a3053236":"SafeInvestments()","a305ac76":"futureHolder()","a306e754":"batchIssueTokens(uint256)","a3078815":"darknodeOwner(address)","a307b727":"refund(bytes32,string,address)","a30872db":"tierContract()","a308c2a7":"validReferralCode(string)","a30955af":"balanceToken()","a309800c":"_withdrawWei(uint256)","a309f2ee":"setBalanace(bytes32,address,uint256)","a309f589":"crowdsaleRatio()","a30a86fe":"setMainSaleParameters(uint256,uint256,uint256,uint256)","a30b5c69":"AttributeModel()","a30bdea4":"isOffchainWhitelisted(address,bytes)","a30c5f17":"get_root()","a30cc5f6":"multiFixed(uint256[2][6])","a30d5627":"ItemToken()","a30d59c9":"getEggsCount()","a30eb0ef":"freeTokenTime()","a30eddcc":"bitSlice(uint256,uint256,uint256)","a30ef9e7":"toBase32(bytes)","a30f786f":"allowedRewardTokens()","a30fb52d":"sendGameGift(address)","a30fbae1":"endBuyBackDate()","a310293e":"weiDonated()","a31052e8":"clearReleaseTime(address)","a3106b95":"setMinterAddress(address)","a310f36a":"test2(bytes,uint256)","a3111d7c":"withdrawListing(uint256,address,bytes32)","a311a08e":"setPartners(bool,uint256,uint256)","a311c7c2":"collateralisationRatio(address)","a311d157":"addContributor(address,uint256,uint256)","a311d970":"TokenTycoonIGO()","a311dd70":"setArray(uint8[10])","a31271f5":"updCrowdSaleEnabled(bool)","a313c371":"memberInfo(address)","a31477b4":"getSncTokenIssuance(uint256,uint256)","a314acfe":"attemptToClaimCard(address,address[3])","a314dc2d":"feePayed()","a3155013":"month60Allocated()","a315acf5":"minter_address()","a315cda0":"priceOfSmartContract()","a316aa93":"setActivityDetails(uint256,string)","a3179fe0":"getAccountsNumber()","a317abc7":"defaultMax()","a318d521":"disableBeforeActivation()","a3194d50":"setFinished(uint8,bool)","a319b232":"VTCoin(uint256,string,uint8,string)","a31a9752":"Payout(uint256,bool)","a31b858d":"_buyDiscountTTM(uint256,uint256,address,address)","a31c5436":"TOKEN_AMOUNT_PRE_ICO()","a31caec8":"AkilosToken()","a31cc317":"evaluateContract()","a31cd710":"_getExpMultiple(int256)","a31d291a":"HOHO(uint256,string,string)","a31d30a5":"WhitelistUpdated(uint256,string,address,uint256)","a31d5580":"Registrar(address,bytes32,address)","a31e3678":"addExceptAddress(address,address)","a31e5e97":"setHouseAddressOne(address)","a31e88c2":"numIntervals()","a31f2c52":"partner2_voted_update_prenup()","a31f61fc":"setGroupCap(address[],uint256)","a31f79fb":"slopeReleasePercentage()","a31ffa30":"setCtuContract(address)","a3201daa":"setPrices(uint256)","a3208c1e":"addUserIntoBlacklist(address)","a3210e87":"sendeth(address,uint256)","a3221c8e":"step8()","a3223d50":"ETHER_MIN_CONTRIB_USA()","a322accf":"tokenFallbackExpanded(address,uint256,bytes,address,address)","a322c40e":"toString(int256)","a322d49e":"FirstTradingEcosystemCoin()","a323a748":"SBT()","a323af85":"hasTwoStepWithdraw()","a323bdb4":"currentPublicSale()","a3240455":"offerStarForSale(uint256,uint256)","a3246549":"stageOneClosed()","a324ad24":"getMonth(uint256)","a324cca0":"optimalLog(uint256)","a324ed9f":"BurnUnsoldToken(uint256)","a324f8bf":"tanksBeforeTheNewTankType()","a32508a1":"Carpati()","a3262e57":"burnCoin(uint256)","a32710eb":"setRole(address,address)","a3273535":"tdeDuration()","a327a958":"numCourse()","a327c45d":"dev1()","a328f90b":"_nextBudgetStartAndEndAndOfficalVotingTime()","a3293c0e":"handToCards(uint32)","a32a6737":"setTotalDeposit(address,uint256,address)","a32ac9e1":"Bitcoin_IDToken(uint256,string,uint8,string)","a32af535":"depositAndFreeze(address,address)","a32affeb":"loadEarlyParticipantsWhitelist(address[],uint256[])","a32bf597":"getCurrentRound()","a32c3bd6":"GetBounty(address,uint256)","a32cb608":"getReverseRate(address)","a32ce11e":"approvals(address,address)","a32e935a":"allocateTokenForTeam()","a32f0f41":"testFailControllerUnapprovedTransferFrom()","a330814c":"unregisterAuditor(address,address)","a3316ccc":"RATE_SALESTAGE7()","a3318359":"sendPrizes()","a331939d":"freezeAdmin()","a331cd38":"toKeyValue(uint256,string)","a3322a12":"getFilesCount()","a332853a":"futureDevelopmentFundAddress()","a3330574":"checkAndMint(uint256)","a333658f":"addTreasuryManager(address)","a333f96d":"LogRefundProcessed(address,uint256)","a33467cf":"getClue2()","a334edf6":"consumeWine(uint256)","a3358ae4":"REAPER_INTREPID_EXTRACTION_BASE()","a335b828":"FUS()","a337840c":"setGuardianRune(uint256,uint256)","a338bd2c":"showTopBonusBalance()","a338eba5":"sendTokens(address[],uint256)","a3393a35":"getDrawEthAmount(uint256,address,uint256)","a3395a52":"searchTicketsXaddr(address)","a339aaf7":"addOracles(bytes4[],address[])","a339abd5":"crowdsaleOpeningTime()","a339c18f":"ACNNIco(uint256,uint256,uint256,address,address)","a339c21a":"addContractTestToBounty(address,address)","a33a5225":"allRefererTokens()","a33b7510":"shareAddEtherValue()","a33bea16":"GENEOSSale(uint256)","a33c0972":"tokenAllocToCompany()","a33cbc55":"TCI_admin()","a33d4968":"Tripler()","a33d5d9d":"EthDev()","a33d652e":"setFunding(uint256)","a33dd801":"setTreasuryBalance(uint256)","a33e1d16":"drapcoin()","a33e6b07":"AccountFrozen(address,bool)","a33e8d62":"RxEALTokenContract()","a33ed39d":"numRef()","a33eff5a":"createResource(bytes32,bytes32,bytes32)","a33f3939":"setNetwork()","a340295a":"setPhoenixOwners(address[19])","a340ceac":"transfekbolOwnership(address)","a340cf79":"paid(address)","a340d587":"offlinePurchase(address,uint256)","a3414653":"COIN_COST_ICO_TIER_1()","a3429689":"TaiCoin()","a3435da5":"BONUS_LEVEL_3()","a3451568":"airdropBatchTransfer(address[],uint256)","a3454712":"AssetCreated(address)","a34560be":"updateEtherCap(uint256)","a34574f0":"gamers()","a346b62d":"CaptainKitties()","a346e536":"week_winner()","a3472270":"mock_getAddress(uint256)","a347ef84":"calcpustprice(uint256,uint256)","a348ea79":"contests(address)","a34945db":"maxAllowedBetInEth()","a3494fdc":"expectRefund(uint256)","a349bfa2":"addOwner(address,uint256,uint256)","a349d683":"FRP()","a34ad6b6":"clockmint()","a34bbf51":"getGeneralInfo()","a34c6716":"testHashing(address,uint256,address,uint256,uint256,uint8,bytes32,bytes32,bytes32)","a34cc845":"win(address)","a34d2ff7":"votingBymy(bool)","a34d42b8":"setContractOwner(address)","a34d5312":"registryRequestVendor()","a34d5f82":"GiveBlockReward()","a34d7c11":"flipCoinWithEther(uint8,uint8)","a34d9270":"setMinInvestedLimit(uint256)","a34d942b":"FUXEToken()","a34dffba":"SILVER_AMOUNT_NDC()","a34e5990":"setTier(uint256,uint256)","a34e9e66":"approveBcoupons(address,uint256)","a34edc03":"assertTrue(bool,string)","a34f42a9":"LogRandom(uint256,uint256)","a34f82f4":"summFounders()","a34fc5ac":"_lockTokens(address,uint256)","a350539e":"makeBid(uint32)","a3508b17":"getOpenedStageIndex()","a35132ac":"SMSReward(address)","a3515b98":"initializeWeekData(uint256)","a352f1a8":"calcSHA3(bytes)","a3536b0c":"calculateHolderPiece(address)","a353c600":"Ponged(uint256,string)","a35523da":"currentLoanDayTime()","a356fdf3":"getPreICOPercentage(uint8)","a3577e93":"depositFunds(bytes,uint8[2],bytes32[2],bytes32[2])","a357880d":"whitelistedAddrs(address)","a3580695":"inSpecialSalePeriod()","a358aa18":"_transferFromInvestor(address,address,uint256)","a35a319b":"delFromBlackList(address)","a35aae9c":"roundID_()","a35ae3ab":"Bam()","a35bc497":"remainTime(uint256)","a35bd437":"toUSD()","a35bd591":"newRound(uint256)","a35bfcac":"ownerRemoveRole(address,string)","a35cad77":"maxLeaders()","a35cfa22":"make_move(uint256,uint8,uint8,uint8,uint8)","a35d631a":"PausableMock()","a35d6dd6":"rDEX()","a35d78a6":"_approvedGen1(address,uint256)","a35da419":"setlock(bool)","a35e617f":"setMaxCount(uint256)","a35e83ea":"getReplay(uint256,uint256)","a35f9514":"calcDstQty(uint256,uint256,uint256,uint256)","a360098f":"Immigration(address,address)","a360b26f":"Migrations()","a361b184":"move(bytes32,bytes32)","a3624b72":"finalizeTransferAddressType()","a362858a":"EthereumCashPro()","a36298c7":"totalLimit()","a362cf0c":"TrueWorld(uint256,string,string)","a363f269":"watchMovie()","a3641c84":"card_metal_first()","a364b5c1":"setProposalNames(bytes32[])","a365bd9f":"BaseToken(string,string,uint256)","a365f3cc":"Util()","a3666d23":"weekTwoPriceRiseBegin()","a367b891":"SplitPhaseDistribution(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","a367d99a":"investStart()","a367e565":"setIBalances(uint256[],uint256[])","a368107b":"SetRecordType(uint32)","a369658c":"TARGET_EVE()","a369b0ac":"depositsClosed()","a369bb28":"SaleWallet(address,uint256,address)","a36a0551":"createCarrierFromVault()","a36a48a5":"ETH500on719()","a36a7526":"setOp(address)","a36b15d0":"enableBundlingMultitoken(uint256)","a36b8af1":"LogItemModified(address,uint256,uint256,bytes32,bytes32,bytes32)","a36badd7":"hasJobRecommendations(address,address,uint256)","a36be43a":"SetFreeYOU(uint256)","a36be9a1":"paybackDeadline()","a36c2cbe":"informarOng(address)","a36c8ec2":"UpdateContractorAddress(address)","a36db282":"SendLCRTokens(address,address,uint256)","a36ddfae":"_0xForkTokenToken()","a36f127e":"removePresetTransfer(address)","a36f259d":"campaignOf(address)","a36ff98b":"team1Points()","a36ffd4d":"ADEToken()","a37173e9":"transfer_left_funds_to_project()","a37218ed":"MAMECOIN()","a3721adc":"contractCreationBlockNumber()","a37330ea":"getDestroyedWhenRoundOver()","a3743afc":"getProjectHour(uint256)","a374480a":"placeValue(address)","a3744828":"GetPriceByN(uint256)","a3747fef":"register(bytes,bytes)","a375de4f":"addTokensToBank(address,uint256)","a37641ff":"MAX_RING_SIZE()","a3766f88":"tokenVendor()","a376c19d":"setEventResult(string)","a377104c":"init(string,uint256,uint256,uint256)","a377b34e":"YoloToken(uint256)","a377ff17":"setHorseDataAddr(address,address)","a3787858":"resumeBlockNumber()","a37889a9":"createPromoGirl(uint256)","a378bba5":"gameEnds()","a3792985":"getBonusDropsOf(address)","a37936f9":"SuspendEmployee(address,uint32)","a379e626":"ownerPerThousandShareForBuying()","a37a3859":"configPerFund()","a37a778f":"SetIPR(string,string,address,string,string,uint256,string)","a37ba32a":"duration(bytes32)","a37be00f":"transferBackTo(uint256,address)","a37be75f":"ethBase()","a37c314d":"set_iconiq_tokens(address,address,uint256)","a37ccabc":"PositionBought(uint256,uint256,uint256,address,uint256,uint256)","a37d1556":"refAmount(address)","a37da615":"showInvestedNum(address)","a37dec33":"calculateWineSell(uint256,uint256)","a37e66f5":"ethPendingManagement()","a37e6f69":"failedByDeveloper()","a37f00f7":"getItemByTokenID(uint256)","a37fd390":"setHomeAdv(uint256,string)","a380dcb9":"wpp()","a381de54":"bonusAddress()","a382aee2":"fourthExchangeRate()","a382edfd":"SeeleGold()","a38320e6":"TITANToken()","a3833a13":"balanceOfColdWallet()","a3848b1a":"getMonsterIVs()","a384af00":"market_BuyForSale(uint256)","a384d6ff":"lowerBound()","a38591fc":"test_percOf1()","a3863d81":"buyTokensLowLevel(address,uint256)","a38717f4":"exFeeTotal()","a3875883":"etherPriceUSDWEI()","a387cf34":"closeTokenSale()","a3885413":"withdrawOwner(address,uint256)","a388a836":"DDAContract(address)","a3893a33":"changeExchanger(address)","a3895fff":"changeSymbol(string)","a389783e":"isApproved(address,address)","a389ef53":"receiveDeposit(uint256,uint256)","a38b68cb":"nonzeroAddressesLengthForApi(uint256)","a38b8469":"TokenADSVENTURE()","a38b9a19":"printQuotation()","a38c48b6":"createProductionUnit2Beta()","a38ce2b4":"revokeAddress()","a38deeab":"Grid(uint16,uint256,uint256,uint256)","a38eb622":"pauseBuy()","a38f18a0":"RedBlueToken3()","a3907d71":"enable()","a3908e1b":"convert(uint256)","a3912ec8":"receiveEther()","a3916164":"withdrawInvestments()","a391c15b":"div(uint256,uint256)","a3922eac":"setCategories(address,uint256,uint256)","a3926f14":"PixelsMain()","a392f54a":"giveMeCoins(uint256)","a3934de4":"Upgrade(uint256,address,address,address)","a39385de":"transferWithReferenceCallGas()","a393dc44":"_totalsupply()","a393fb0f":"reducemoney(address,uint256)","a39417f9":"LOG_NewBet(address,uint256)","a39495f0":"isPreallocated()","a395e2cc":"TPLAYToken(uint256,string,string,uint8)","a3961207":"amountOfRedemptionPayouts()","a3964cb9":"toB32(bytes,address,bytes)","a396541e":"getPongvalTxRetrievalAttempted()","a397d8e0":"getUnusedBalance(address)","a398063a":"setEmergentHalt(bool)","a3980dd7":"Readycoin()","a3988500":"CloudexchangeCrowdsale(uint256,uint256,address)","a398b89b":"receivedEther(address,uint256)","a39953b2":"startCrowdsale()","a399eb76":"ZoharTC()","a39a2b76":"dropUnitPrice()","a39a45b7":"replaceOwner(address)","a39a70a9":"developReserveTimeLock()","a39aaec6":"getCompte_37()","a39ab3a3":"bla(address)","a39ad747":"minVote()","a39b10d2":"lastBlock_a17()","a39db022":"changeBonus(uint256,uint256,uint256)","a39dc9be":"HOUR()","a39e1149":"getSECOND_STEP_MULTIPLIER()","a39eede8":"settleAssets()","a39f7449":"startTimer()","a39f9712":"sendTokensAfterBuy(address,uint256)","a39fa2f6":"VPE_address()","a39fac12":"getAddresses()","a3a06c54":"endICOPhase()","a3a0ee24":"evFreeze(address,uint256)","a3a183c1":"overflow(address)","a3a187cf":"TokenBought(address,uint256)","a3a1cd6d":"getNumberOfKnownPropertyAddresses()","a3a1d015":"failUserRefund(uint256[])","a3a27105":"stakeholderPayment(address)","a3a402a7":"deletefromblacklist(address)","a3a40323":"ArtificialNeuralNetwork()","a3a40ea5":"getCurrentPhase()","a3a4851a":"deliveryReject(address)","a3a48785":"unsetClaim(uint256)","a3a4a18b":"test_claimShares_emptyFeePool_isTranscoder()","a3a4ba31":"createChild()","a3a51983":"updateCurrentStage()","a3a5650a":"currentStageMaxSupply()","a3a6a43e":"approveUserKYC(address)","a3a6c73e":"_isIdExisted(string)","a3a7647c":"tier1Count()","a3a7b804":"changeMaxGasprice(uint256)","a3a7e7f3":"transferAll(address)","a3a81d40":"totalBGX()","a3a82678":"collectRef(address)","a3a9196a":"dexTestNormalTransfer(address,address,uint256)","a3a93721":"SYLVIe()","a3a9d67b":"AdviserCasperToken()","a3aa1913":"balanceDetails(address)","a3ab5045":"isNewTile(uint16)","a3aba50e":"referrerEnable()","a3ad1676":"isPurchasedEpisode(uint256,address)","a3adb958":"transferToggleRequester()","a3ae2f5c":"award(uint256,address)","a3ae88a0":"totalUSD()","a3b01f23":"intoverflow_add(uint256)","a3b0bff4":"getPersonalStakeActualAmounts(address,address)","a3b0c661":"setLineUpEnable_default(uint256)","a3b1dc52":"logEscapeHatchChanged(bool)","a3b2363d":"parentAddress(address)","a3b24dcd":"getSumsHash(address)","a3b2938d":"updateStatusInternal()","a3b2c41e":"readArticle(bytes32)","a3b34190":"unlockSecond()","a3b3fff1":"getVotingToChangeMinThreshold()","a3b42cba":"register(bytes8,bytes8,uint256)","a3b4ab48":"BBPToken(address,uint256)","a3b4b07f":"ACL_APP()","a3b6120c":"dateStart()","a3b62bc3":"AdminRemoved(address)","a3b65d29":"getarg_3()","a3b80993":"WorkValley()","a3b8cd3b":"_equipDownOne(address,uint16)","a3b922ca":"buyPandaERC20(address,address,uint256,uint256)","a3b959da":"change_dev(address)","a3b9b8d1":"receivePaymentForOraclize()","a3bbc294":"galleassTransferFrom(address,address,uint256)","a3bbf81b":"USACOIN()","a3bc3fce":"getFillOrderMinGasNeeded()","a3bc6163":"getMessageGas()","a3bdc655":"getRemainingTimeTillExpiration()","a3be094d":"countTokens(uint256)","a3bef4d7":"numVotes()","a3bf5b9a":"revokePermission(address)","a3bfdf47":"closeSession(uint256)","a3bfe069":"_sumActivePerks(uint8[32])","a3c07c6a":"removeHatchingTime()","a3c0a477":"crowdsaleIsActive()","a3c1954e":"supporter()","a3c1d83d":"forgiveMeOnBehalfOf(address)","a3c28dfc":"eventExists(uint256)","a3c2c462":"totalReceived()","a3c441e7":"setAdvisoryWallet(address)","a3c49da0":"DollarCoin()","a3c50b32":"orderDetails(bytes32)","a3c66c1d":"notEqual(bytes32[],bytes32[],string)","a3c68e3d":"CancelGameAfterResultsPublished()","a3c86bef":"AcademyToken(address)","a3c88b31":"addInternalBalance(uint256)","a3c8ef7a":"signedByWhiteHat()","a3c9df3f":"plutocrat()","a3c9fc7d":"_withdrawTo(uint256,uint256,uint256,uint256)","a3ca17b2":"getUSDETHPrice()","a3cb3e97":"removeHatchingTimeWithToken(address)","a3cb679d":"getTotalBets()","a3cbf67d":"NewBOP(address,address,address,uint256,bool,uint256,string)","a3cc8b9c":"changeRateUSD(uint256)","a3cd2d78":"nextReward(uint256)","a3cd4065":"ReceiveBTC(address,uint256)","a3cf3ec0":"lowestAddressReserving()","a3d07452":"fightAuction()","a3d2078b":"TokenSaleOpened()","a3d23e52":"round2Cap()","a3d3a265":"setCreditBond(address)","a3d4e4b5":"buyItem(uint8,uint8,uint256,uint256)","a3d53934":"MegaToken()","a3d5e8e0":"_update(uint256,string)","a3d5ec39":"PlynToken()","a3d646fe":"ETHEUR()","a3d658dc":"extendLiquidationPeriod(uint256)","a3d6f9a9":"publicKeys(address)","a3d7bd43":"doSend(address,uint256)","a3d823ad":"changeORACLIZE_GAS_LIMIT(uint256)","a3d87805":"TerraToken(uint256)","a3d88453":"isAvailableAccount(address)","a3d8fdd5":"totalAccessorySeries()","a3d94402":"safeMathAdd(uint256,uint256)","a3d9c3d1":"ApprovalHash(bytes32,bytes32,uint256)","a3dab216":"setOpeningClosingTime(uint256,uint256)","a3dc65a7":"wipe(address,bytes32,uint256)","a3dc8a7a":"exrate()","a3dcb4d2":"receiverAddr()","a3dceacb":"MessageSent(uint256,uint256,string,string)","a3dd2619":"getCurrentStatus()","a3dd2b3e":"projectInfo(address)","a3dd3aa7":"setGBT(address)","a3ddc24a":"purchaseDeposit(address,uint256)","a3de9354":"createDividendWithCheckpoint(uint256,uint256,uint256,int256)","a3def923":"create(address,bytes32)","a3df30b4":"GIDe()","a3df870a":"hentaisolo()","a3dfc364":"StartGame()","a3dfcb0d":"_setUniqueValue0(uint256)","a3dfdf30":"read_i64_array()","a3e135fa":"reclaimTokien(address,address,uint256)","a3e14d74":"getLowerBoundBlocksTillGameEnd()","a3e1f666":"getCreatorMetadataOfHistoricalMetadata(string,uint256)","a3e20625":"giveReputation(address,bool,string)","a3e20d71":"transferUnPaidFundAccount(address,uint256)","a3e29360":"ownedTicketIdList(address)","a3e298d1":"VIBETPerEther()","a3e2b1de":"getProjectArbiter(bytes32)","a3e2ce24":"getTokensAndAmounts()","a3e31246":"setLucky()","a3e3a8e0":"withdrawEthPool(uint256,uint256)","a3e486d1":"ptc_balance(address)","a3e4c0c4":"setRandomizer(uint256)","a3e667b3":"releaseMany(uint256,uint256)","a3e67610":"tokenOwner()","a3e7061d":"getPaintingIdAtIndex(uint256)","a3e76c0f":"receive()","a3e787b5":"FITToken()","a3e831b4":"NewTokenFromFactory(address,address,uint256)","a3e860fe":"DEFAULT_RATE()","a3e8b6db":"MetrumcoinShares()","a3ea1376":"removeListingInternal(uint64)","a3ea478f":"setTier1Participants(address[])","a3eb6436":"TOKETH_PRESALE_TWO()","a3ebb0b3":"getConsideration(uint256)","a3ebeab7":"testConcatMemory4Bytes()","a3ec138d":"voters(address)","a3ec5616":"next(bytes,bytes,bytes,bytes,bytes,bytes,bytes,uint256)","a3ecbc33":"DSPUnregistered(address)","a3efc756":"transferPreICOFunds()","a3f144ae":"OFFSET19700101()","a3f1bd35":"getDouble()","a3f1ee91":"RequirementChange(uint256)","a3f22739":"payout(uint256,uint256,bytes32,bytes32)","a3f2a813":"StartsAtChanged(uint256)","a3f2d2b5":"SZA(uint256,string,string,uint8)","a3f31b80":"teamPayment(address)","a3f36da3":"ProRataDistribution()","a3f3dd32":"Verifier(uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[])","a3f424c2":"verifyProof(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[10])","a3f4df7e":"NAME()","a3f5a178":"approveTakeover(uint256,address)","a3f5c03d":"launchInvestment()","a3f5c1d2":"nexus()","a3f66b46":"newQuestion(string)","a3f67d6d":"playersCount()","a3f70ed3":"party_a()","a3f7c989":"enableStorage(bool)","a3f7e26d":"finishMintingIssuer()","a3f8eace":"releasable(address)","a3f991a5":"totalPot_()","a3face0b":"setInteractionPrice(uint256)","a3faef60":"MicroBitCoin()","a3fb5917":"getFirstOrder()","a3fb8f15":"getRaisedPOLY()","a3fbbaae":"changeManager(address)","a3fc136a":"signedApproveSig()","a3fc32c8":"getWLInfo()","a3fc81cb":"buyTokensViaBackend(address,uint256)","a3fca677":"LogBuy(address,address,uint256,uint256)","a3fcafb9":"soldCoins()","a3fcf9bc":"operationsPercentOfTotal()","a3fd6d0e":"feePaid(bytes4,uint256)","a3fdfee3":"deny()","a3fe0dc7":"userCrateCount(address)","a3fe70cb":"exchangeEnd()","a3ff0ea2":"issueAsset(bytes32,uint256,string,string,uint8,bool,address)","a3ff31b5":"getTokenStatus(address)","a3ff428e":"angelCardSeriesCollection(uint8)","a3ffac0d":"td()","a400594d":"lockAddress(address,address)","a4009e23":"TEST_MODE()","a400be54":"coinSendSameValue(address,address[],uint256)","a401d24d":"assignToken(address,uint256)","a401e585":"withdraw_privatefund(bool)","a4036b1c":"getAdPriceHour()","a4039098":"StartCompetitionEvent(uint32)","a4039a2a":"createNonRepeatableVpfFactory(string,bytes32,uint256,uint256,int256[])","a404f291":"microRate()","a40544c3":"notifyCancelSellOrder()","a4055f62":"freezeAccounts(address[],bool,bool)","a40668f5":"testDeregisterProduct()","a407db23":"GHK()","a407ee79":"bytes32ToAlphabetString(bytes32)","a4083849":"right44(uint256)","a4086854":"approveTransfer(uint256,address)","a4093718":"issueToken(uint256,uint256)","a4094a0d":"calculateFeeForAccount(uint256,uint256,address)","a409eb7b":"hasRequested(address)","a40a485f":"deathData_v3()","a40a99ac":"getInsertPointForNumTokens(int256,address,uint256)","a40ae4b7":"_uintToBytes(uint256)","a40bc352":"crowdSalePause()","a40c0a54":"USDGamblingToken()","a40c5221":"updateTokenAmount(address,uint256,uint256)","a40c8ad0":"addGenesisCatGroup()","a40cd3f3":"minContributionInWei()","a40cee9c":"updateIdentityImageURL(address,bytes32)","a40d32fe":"minPaymentAmount()","a40e0b91":"testGoalReached()","a40edb07":"processVerification(bytes32,string)","a40f1796":"prefixedHash(address)","a40fbd2b":"makeKebabs(address)","a410424e":"isMoneySent()","a4109017":"VanityTransfered(address,address,string)","a410a7f2":"getParticipantTickets(address)","a410f4b1":"changeFeePercentage(uint8)","a412c6fc":"getRules(string)","a412f87c":"verifyInvestment(address,uint256)","a412fcc7":"defineType(string,uint8,uint8,uint32,uint8,uint32,uint8,uint32[5],uint32[5],uint32[5])","a413245a":"deductFromBond(address,uint256)","a41347e3":"usersCanTransfer()","a4136272":"MAX_TOKEN_SALES()","a4136862":"setGreeting(string)","a4144681":"RK40Z()","a414b00d":"SUNToken()","a414b379":"addContact(address)","a414e089":"Dimacoin()","a415833b":"numPurchasesOf(address)","a415965c":"refillMultiSigMintPool()","a415a93e":"initWithShips()","a415b8eb":"getCCH_edit_31()","a416b263":"charAt(bytes32,uint256)","a416b48c":"getActionCount(uint256)","a417357c":"unpauseTokens()","a419165e":"TokenCappedCrowdsale()","a41942a4":"transferCuratorship(address)","a419f1e7":"NewPlayerAdded(uint256,uint256)","a41a9445":"getStopTransfer(address)","a41b3887":"setPrefixPrice(uint256,uint256)","a41b9c31":"unconfirmAddress(address)","a41d0584":"fixAddress(address,uint256)","a41da348":"fomo3d()","a41dedcc":"testAbs()","a41e61a4":"minSaleBalance()","a41e7d51":"updateERC165Cache(address,bytes4)","a41f0069":"GershToken()","a41fd917":"getUnprocessedQueryList()","a41ff1e5":"maxMintingDays()","a4201125":"sanToLower(string)","a4202504":"getPhaseSold(uint256)","a4202615":"makeAdoptionOfferToAddress(bytes5,uint256,address)","a4204e39":"getQuotes()","a42214b2":"cancelAuctionEmergency(uint256)","a422b761":"tokensIssued(address)","a4230bd5":"addAdmin(address,bool)","a4238d31":"receiveBalanceUpdate(address)","a4245527":"getPaintingOriginal(uint256)","a424fa49":"NPXSToken()","a42533c8":"tubParamUpdate()","a4254fb4":"couponTokenBountyAddr()","a425b752":"destroyStake(address,bytes32,uint256,uint256)","a4262254":"calcFib(uint256)","a4268de6":"oracleItQuery(uint256,string,string,uint256,uint256)","a426cd19":"validPLAContract(uint32,uint32)","a4275535":"XTYF()","a4276533":"getProposalNum()","a427c5d9":"bonus(uint256,address[],address,uint256[])","a427ee36":"FruoCoinBETA()","a428033f":"minechaincoin(uint256,string,uint8,string)","a428517b":"Converted(address,uint256)","a4288d17":"tokensForReservedFund()","a429845e":"newCrowdsale(bytes32,uint256,uint256,uint256,uint256)","a42aa488":"checkRevert(uint256)","a42ac803":"getBonusAffiliate(uint256)","a42ad8b3":"NomuraDynamicsCoin()","a42b0d88":"advisorsPool()","a42b6bf1":"setStorageContract(address,bool)","a42cb160":"updatePlayerFund(uint256,address,uint256,uint256,uint256,uint256)","a42d630c":"SetupMultipliers(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a42dc008":"newKudosToken(string,string,string,uint8,address)","a42dce80":"setFeeCollector(address)","a42e16fd":"MultiSig(address[],uint256)","a42e36c6":"scheduleTransaction(address,bytes,uint8,uint256[5],uint256)","a42ea491":"MrFibreToken()","a42ec1bc":"reserveWallet(uint256)","a42ecd5c":"setRealRef(address,uint256)","a42ef788":"potSwap(uint256)","a42f126c":"charityClaim()","a42f1edb":"market1()","a42f3f9d":"getTAOCurrencyBalances(address,address,address,address)","a4316c46":"MarketingToken()","a4325485":"getCreatorBalance()","a432cdb0":"Tier_Rainmaker()","a432e6d6":"switchToNextPeriod()","a4331929":"createNew()","a433a0b9":"addRecordByProvider(bytes32,address,string,string)","a433d5c6":"IsActiveUser(address,address)","a433f390":"approveAndTransferFundToCreator()","a4341ab0":"setCount(address,uint256)","a4343ae9":"onContribution(uint256,address,uint256,uint256)","a43569b3":"getValidatorDescription(address)","a43655c4":"rejectRequestPause()","a4366a8a":"processPayment(address,uint256,uint256,uint256,bool)","a4368de7":"addBonus(string,uint256,uint256,uint256,uint256,string,uint256,string,uint256)","a437164b":"assignUserWallet(string,address)","a43772bd":"thirdXRChangeBlock()","a43796ce":"getSecretSigner()","a437ab52":"setDevelopersFee(uint8)","a437e07a":"signAuthorship()","a4381dd4":"StanleyToken()","a438d208":"VOTING_DURATION()","a43914da":"getRootEdge()","a4399263":"finalise()","a439d3fa":"ChangeOfRules(uint256,uint256,int256)","a43b2ed0":"Test6()","a43b5e46":"buyWeapon(uint256)","a43b7cd5":"carTaxiToken()","a43b92a2":"tournamentIncentiveCut()","a43b9423":"triggerPreJackpotLimit()","a43be57b":"endPresale()","a43c49fc":"mul16(int16,int16)","a43c5415":"lastBlock_a3Hash_uint256()","a43c6002":"getTokensByGame(uint32)","a43cbe1c":"setThirdPartyDepositorDisabled(bool)","a43d12a7":"getParticipantesB()","a43d76e9":"isValidPrice(uint256,uint256)","a43d8654":"getSeason(uint256)","a43dc510":"yesBuyer(uint256,uint256)","a43e04d8":"removeContract(bytes32)","a43e0c2b":"calclulateBonus(uint256)","a43ea59b":"PublicSale(address,address,address)","a43fecbc":"setUsername(bytes16)","a4406bcd":"placeSellOrder(uint256,uint256)","a44081d1":"startPhase1()","a440a190":"getKeyPrice()","a440b21a":"setPortfolioManager(address)","a440dd87":"sigExists(bytes32,address)","a441698b":"getStockOrderInfo(bool,uint256,uint256,uint256)","a441c302":"operationAddress()","a442414f":"sumInvested()","a4425c55":"lastInvestorsProfitSum()","a442b824":"respawnGame()","a442d820":"verifyExtraData(bytes32,bytes32,uint256)","a4430321":"eachPUSTprice()","a4438334":"updateSettings(uint256,uint256,bytes32)","a4439890":"sweepUnallocatedDividends()","a4439dc5":"commitPeriodActive(uint256)","a444502b":"whitelistAccount(address,uint256)","a4447515":"getMakerBetBasicInfo(uint256,address)","a444ae41":"sourceContract()","a444f5e9":"run(uint256)","a4453336":"depositGTA(uint256)","a4453a96":"totalBuyersMapping()","a4453ecf":"splitEth()","a445dc5a":"tokensBoughtWithBTC(address,uint256)","a445f30d":"setFeeDistributionAndStatusThreshold(uint8,uint16[5],uint256)","a4464252":"priceUnitFix(uint256)","a447089e":"eniggerToken()","a447405e":"_getTravelPrice(address,uint256)","a447ff4f":"DXContracts()","a4482f41":"setUniquenessIndex(uint32)","a448afda":"BalanceChanged(address,uint256)","a448f8e0":"OuterContract()","a449a62e":"setDSTWalletLMNO(address)","a44a00c3":"areTokensSold()","a44b1756":"getMyDrugs()","a44b47f7":"TotalSupply()","a44b6b74":"setColor(uint256,string)","a44cff28":"CypressOrganization(bytes,uint256)","a44d0eb3":"MAKJLEB()","a44da065":"NigerTokenICO()","a44dd0f1":"ico2Cap()","a44de4e7":"decreaseStepPct()","a44e09db":"wadmin_burn(uint256,bool)","a44ead73":"ApplyforCertification(string,string,string,string,string,string)","a44eda3c":"checkWithdraw(address,uint256,address)","a44f40e3":"optionPoolMembersUnlockTime()","a4502cb8":"setExportFee(address,uint256)","a45066e5":"SingularityTes25()","a4516bb1":"SnapshotTaken()","a4516fad":"currentGameNumber()","a4520aee":"collect(address[])","a45230ec":"get_amount_sell(uint256)","a4530b4b":"testUpdateProgress()","a4534ef7":"remainingSupply_()","a453b639":"wuguAddr()","a4546876":"roots(address)","a454b07b":"checkString(string)","a454c5dc":"unlockStep()","a45563ed":"UpdateSellAgentBounty(address,address)","a4563e03":"totalPendingWithdrawals()","a4575296":"pepFarm()","a457c2ae":"clientSeed()","a457c2d7":"decreaseAllowance(address,uint256)","a457e1c0":"purchaseAsset(uint256)","a457f27f":"card_titanium_minamount()","a45858b6":"setzUint256Array(uint256[2],int256)","a458e34f":"setNewContractManager(address)","a459ae28":"collectSellFee(address)","a45a7371":"executeUpdateTransferFeeRateProposal(uint256)","a45b1795":"getAllCardsModifierSecondaryVal()","a45c793f":"restore(uint8[176],uint8,uint8)","a45cbbf4":"sendAdvisorsTokens(address,uint256)","a45cd953":"canPurchase(address,address,uint256)","a45d82bd":"signArchive(bytes32,string,string)","a45e11ab":"orderMatchBuy(uint256,uint256,uint256,uint256,uint256)","a45e1a6e":"getTokenCounters(uint256)","a45e7cb5":"addEntry(string,string,string,string,string,address)","a45ee32c":"nameOfIdentity()","a45f2057":"caltoken()","a45f4bfc":"kittyIndexToOwner(uint256)","a45f5685":"setOwnerEarnings()","a45f71ff":"increaseApprovalPreSignedHashing(address,address,uint256,uint256,uint256)","a4604a33":"changeBuyFeePercent(uint256)","a460b817":"updateTicketStatus(uint256,uint8)","a460bd6c":"presaleRemaining()","a4618691":"squak()","a4619682":"registerWithDAI(uint256,address)","a461cadf":"WHOLE_ETHER()","a461fc82":"SELFDESTRUCT_DELAY()","a4620d67":"shareholder3()","a4623cc4":"addHero(string,address,uint256)","a462f87f":"AICoinToken()","a462fb7b":"getFinalAnswer(bytes32)","a4633704":"NotifyMe(address,address,uint256)","a463685f":"AllocatedCrowdsale(address,address,uint256,uint256,uint256,address)","a463a500":"setUpgradeHasBegun()","a464d265":"editor()","a4659ba2":"stakeConfirmed_Eth()","a465e6ba":"committeeKickVoters(address,address)","a46841e1":"cnyEthRate()","a4689d48":"getroundendtime()","a4699cad":"resetWithdrawls()","a469b809":"getBetAmount(bytes32)","a469e5aa":"getOwnerItemIds(address)","a46a1219":"AcceptRouting(bytes32,bytes32,uint256,bytes)","a46a891e":"fromBase(uint256,bytes8)","a46a96d9":"calculateRegionSalePixelPrice(address[16],uint256)","a46afef1":"getSponsoring(uint32)","a46b3e9b":"treasuryDemurrageAmount(uint256)","a46b6593":"sendCandy(address)","a46c3637":"getWinnerCount()","a46c792c":"assignAgent(address)","a46c8fee":"ItdFund()","a46d11dc":"gType()","a46dfb45":"ResolveChips(uint32[])","a46efdb5":"getTokensForPreSale(uint256,uint256)","a46f3c7a":"getLiveMaxBet()","a46fe83b":"numAssets()","a47001a8":"receiveEthPrice(uint256)","a470afa7":"Evernal(address)","a47255d7":"TimeWeekThree()","a472969c":"WithdrawFee()","a472c868":"_storeReward(address,int32)","a4754fac":"getValidated(uint256)","a475b5dd":"reveal()","a476f3d3":"demurringFeeNum()","a4776955":"setselfdroptoken(address)","a4785dfd":"ecverify(bytes32,uint8,bytes32,bytes32,address)","a47905cd":"getBondMultiplier(uint256,uint256)","a47abd0f":"testIsSuccessful()","a47ae542":"getCurrTotalInvest()","a47ae71f":"getCurrTypePrice(uint256)","a47b1a6c":"getContractsAddrs(address,address)","a47c4d64":"isAllocated3()","a47c6b84":"cofounderSwitchAddress(address)","a47ce954":"bonussale_TokenCap()","a47e7110":"AnnoMedal()","a47e713c":"ACCToken()","a47f519b":"CPCE()","a47fcc7c":"proposePartnerAllocation(address,uint256)","a4800172":"buyDiscountTTMByETH(uint256,address)","a48028aa":"valueOf(address)","a480ca79":"collectFees(address)","a481247c":"isKeyExist(address,address)","a48205cb":"emaValue()","a4821719":"buyToken()","a48255b7":"nextPVPBatleBlock()","a4828bca":"TrineChain()","a48296d9":"purchasePhoenix(uint256)","a484f413":"payJosh()","a48515fc":"castConstitutionVote(uint8,address,bool)","a48566ba":"serverSeed(address,bytes)","a487bcd8":"winners()","a487fd07":"ethFundsWallet()","a4893536":"_bonusToBettor(uint32,uint8,uint256)","a4898fd5":"deployContract(address)","a489a2c7":"sanityBounds()","a48a663c":"transferFromToICAPWithReference(address,bytes32,uint256,string)","a48bdb7c":"results()","a48be00b":"activateTokensForJury(uint256)","a48c98dd":"deployerAmount()","a48cef4a":"oracleInterfaceCountdown()","a48d9e70":"getIcoSupply()","a48de68b":"createPromoHero(uint256,address)","a48e1ff7":"BonusWithdrawn(address,uint256)","a48fb972":"_sendReward(address,address,uint256)","a49062d4":"MAX_LEVEL()","a490a697":"totalBadges()","a4923b8f":"placeIndexToOwner(uint256)","a492ef60":"Participant(string,address)","a4935f1f":"_tokenMetadata(uint256,string)","a4938313":"getAdvancedTransfer(bytes32,uint256)","a493b39f":"getAdPriceWeek()","a494411c":"allocateTokenForAdvisor(address)","a4945a07":"ftestnetico()","a494817b":"setIdle()","a4951771":"MeshPoint(string,address)","a4952f19":"LogPolicyPaidOut(uint256,uint256)","a4952f80":"getBytesName(string)","a49545ec":"useTokens(address,address,uint256,uint256)","a495c942":"set_topl_address(address,address,uint256)","a4963c0b":"SAPOVAM(address,string,string,uint256,uint256)","a49687d1":"stage4Deadline()","a4975aff":"raiseNumberOfCheckmarks(uint256)","a4978a15":"applyLOT(uint256)","a497d8c6":"privateTokenCap()","a497e674":"setAuctionDuration(uint256)","a4983079":"transferBalanceForPreSale(address,uint256)","a49886ce":"testToBytes32(bytes)","a499bc4a":"DECEX()","a49a1e7d":"setMetadata(string)","a49a42e1":"CrytoWorldCup()","a49bb55c":"currentRoundMultiplier()","a49c2bbb":"getBeneficiaryCash(bool)","a49cc76c":"createCurrency(string,string,uint8,uint256,string)","a49d03bc":"privateSell1Address()","a49d53a1":"SmartRevshare()","a49d6be2":"shekel()","a49e0ab1":"complex()","a49e4540":"mintCapInETH()","a49ea0ab":"rankOf(bytes)","a4a0d801":"valueOfContract()","a4a1485b":"createEthInvestorRequest(uint256)","a4a1a78d":"CertAdminAdded(address)","a4a1a9bc":"fightTeams(uint16,uint8,uint8)","a4a1e263":"getUsersCount()","a4a249d6":"quicksort(uint256[])","a4a2a9f6":"init(address,uint256,uint256)","a4a33638":"NAST()","a4a339ee":"doMint(uint256)","a4a3513c":"Accelerate(uint256)","a4a46f45":"LOG_InvestorEntrance(address,uint256)","a4a47582":"Pyrgressive()","a4a4c224":"setAngelLastBattleTime(uint64)","a4a5a46e":"EUNO()","a4a5e241":"setPrizeEndTime()","a4a5f550":"price_exponent2()","a4a6795a":"ReserveSupply()","a4a68e44":"userlogin(address)","a4a691ce":"parseResultCompatible(bytes)","a4a75c6e":"tokensSoldAmount()","a4a75edc":"registerDeal(address,address)","a4a7cf5c":"redeemWinnings(bytes32)","a4a83317":"emitChange(bytes32)","a4a85b22":"fund(address,address)","a4a8f8ea":"migrationHost()","a4a92dd0":"_createToken(string,address)","a4a94567":"setTokenContract(address,address)","a4aac6ec":"diff(int256[])","a4ab3e45":"buyerAddressTransfer(bytes32,address,address)","a4ab69cd":"cancelBuyOffer(uint32)","a4ac3e7d":"FrozenFu(address,bool)","a4acbcd6":"pregnantpuppies()","a4ad1a5f":"verEntidades()","a4adb24b":"createCourse(string,string,uint256)","a4adc2f7":"freezeTokens(uint256)","a4adc431":"fechVoteResultForCandidate()","a4adcde3":"getSingleGuessInfo(uint32)","a4ae32fd":"sampleBool(bool)","a4af1d1a":"totalPublicSaleStage()","a4afaeb0":"AutoKen()","a4b03f52":"internalLockAccount(address)","a4b06df2":"heapSort(uint8[])","a4b0a36f":"exchangeRateUSDToToken()","a4b159c0":"benefitMicros()","a4b16449":"transferTokensFromRetailersAddress(address,uint256)","a4b195ff":"numVoters(uint256)","a4b1b020":"transferLockedTokensBackToUser(uint256)","a4b1ce55":"scheduleCall(address,address,bytes4,bytes,uint8,uint16,uint256,uint256,uint256,uint256,uint256,uint256)","a4b31eb1":"bitWatt(uint256)","a4b32bd7":"modifyRent(uint256)","a4b3b042":"RDXToken()","a4b48828":"getOffer(address,address)","a4b52ef2":"hgt()","a4b5fa56":"blacklist()","a4b7459a":"transferFromToICAPWithReferenceCallGas()","a4b7f5ce":"resolutions(uint256)","a4b8a543":"sacarETH()","a4b8c2e7":"restart(bytes20,bytes32)","a4b910fb":"WithdrawToken(uint256)","a4b916e2":"mintB2BC(address,uint256)","a4ba2971":"addMemoryImageSlice(uint256,bytes)","a4ba5bdb":"Leonidas()","a4bad0ae":"vestingsBalance(address)","a4bb1324":"initGame(address,uint256,bytes32,bytes32,bytes32)","a4bb252e":"LogGameCreated(uint256)","a4bb43d2":"Beonbox()","a4bbded4":"MAX_ICO_SUPPLY()","a4bbf1a7":"LAUCHCONTRACT()","a4bc51d4":"PrivateSocialPlatform()","a4bce83c":"CSCToken()","a4bd7a20":"currentBoundary()","a4bd7b8d":"countApproval()","a4be2ea2":"HardClear()","a4be64a4":"warriorBlock()","a4beda63":"lockTime(address)","a4bef732":"userCancelOrder(address,address,uint256,uint256,address)","a4beffa7":"increaseInvestment()","a4bf594b":"CORENETCOIN(uint256,string,uint8,string)","a4c089be":"debug_finalizeBundleIPFS(bytes32,string,bytes32)","a4c0ed36":"onTokenTransfer(address,uint256,bytes)","a4c0fd51":"onlinenewsbalita()","a4c1e9c0":"depositToUser(address)","a4c3dfa4":"buff()","a4c3e789":"RUB_Omnidollar()","a4c44074":"setCashbackManager(address)","a4c4dfea":"WGNToken()","a4c4f172":"_arrayContains(uint8[],uint8)","a4c5bf66":"removeSkipPrice(uint256)","a4c64d78":"getContractDividends()","a4c6569b":"isWhiteListed(bytes32)","a4c673c5":"pauseInvest()","a4c6fcde":"allowEscrow(bool)","a4c756c7":"tokenAllocToTeam()","a4c7c7b3":"partner1()","a4c89322":"ethToTokens(uint256)","a4c8b35d":"moneyManager()","a4c93cab":"setDistributionSize(uint256)","a4c97967":"proof_of_public_key()","a4c9b0ca":"deleteTx(bytes32)","a4c9bb28":"VLOGCoin(uint256,string,string)","a4ca80be":"lockFile()","a4cae72b":"_createEtherDog(uint256,uint256,uint256,uint256,address)","a4caeb42":"periods()","a4ccd1ba":"breakevenLevel()","a4ce48c0":"addProposal(bytes32,uint256,bytes32)","a4ce8683":"create(string,string,uint8,address,string,address)","a4d1f29f":"BifrostToken()","a4d22c13":"enableDonation()","a4d28b62":"getMedalsBurned(uint16)","a4d33646":"setELIXAddress(address)","a4d4f070":"get_token()","a4d55686":"totalEthFundRecieved()","a4d575ce":"_forward(address,bytes)","a4d5a3a5":"airdropAmount(uint256)","a4d5a519":"TXwithCode(bytes32,uint256)","a4d5e30e":"removeHatchingTimeFee()","a4d66daf":"limit()","a4d66f1e":"calcReleaseToken(uint256)","a4d67d63":"finishGenerating()","a4d69fd3":"payoutMethodABI()","a4d6bb2b":"latestPayout()","a4d714c7":"addressToBytes2(address)","a4d72886":"PRE_ICO_RISK_PERCENTAGE()","a4d755ff":"setFactoryName(uint256,string)","a4d82f95":"Wallet6()","a4d840a8":"getInvestorInforMax(uint16)","a4d8b40a":"order2Shares(uint256)","a4d904ba":"foundersStake()","a4d91b02":"createtoken(string,string,string,string,string,string)","a4d924b6":"extractableFraction()","a4d95c76":"setRobotCoinContract(address)","a4d97569":"ACLYDCoinContract()","a4d99522":"setCryptaurRecovery(address)","a4da79a7":"_tokensOfOwner(address)","a4db2e9a":"initDao(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a4db8c73":"BieberToken()","a4dbafbb":"batchReturnTokens(uint256)","a4dbbbf1":"joinWithCandy(address,uint256,uint256)","a4dd73cd":"isMinimumValue()","a4ddf312":"numberOfPunksToReserve()","a4de3c19":"setFeeAccount(address,bool)","a4de64c4":"isFundedMini()","a4df0758":"isClaimed(address,address)","a4df320d":"end_LOCKUP()","a4df6c6a":"freezeTokens(address,uint256)","a4df8ca1":"See_TokenPurchaser_Number()","a4dff0a2":"zzz()","a4e01230":"RamenContract()","a4e02fcc":"transferProfit(address,uint256)","a4e24173":"getUsersArtefactsIds()","a4e2d634":"isLocked()","a4e3374b":"transferDelegated(address,address,uint256)","a4e339c1":"validate(address,uint256,bytes32,bytes,bytes32)","a4e360c8":"getApprovals(uint256)","a4e4a7bb":"avatar(address,bytes)","a4e6dd3a":"coinDrain()","a4e85358":"getTEth(uint256,uint256,uint256)","a4e8e360":"enterFreeRaffle(uint256[],uint256)","a4e9bcb8":"vxtestPrivateSale(address,address)","a4ea471f":"getBoardRowDetails(uint256,uint8)","a4eacb34":"removeFromBountyProgramMap(address)","a4eaec5f":"targer()","a4eb5710":"needReleaseFor(address)","a4eba44d":"setPriceCoolingPeriod()","a4ebf74d":"CorsariumAccessControl()","a4ec0620":"getAllCoins()","a4ec11b1":"getStepFunction(uint256)","a4ece52c":"pop()","a4ed22b6":"testInsertLawyer()","a4edff47":"addNote(string)","a4ee7c18":"_computeCommission(uint256)","a4eed4dd":"setupWhitelist(address,bool)","a4ef2cbb":"setWhiteListAgent(address)","a4efc580":"lastPriceCheck()","a4f0d9b1":"setCut(uint256,uint256)","a4f15498":"projectedPrizeForPlayer(address,uint256)","a4f2613d":"bid(string,string)","a4f28bdd":"fundingMinInEth()","a4f29aad":"setTokenName(string)","a4f35b65":"minTransfer()","a4f3fa10":"getToday()","a4f4662f":"getOwnersTokenIndex(address,uint256)","a4f5b8c1":"bonusCreationRate()","a4f63ec8":"setBytesArrayIndex(bytes32,uint256,bytes32)","a4f6d5ce":"BeeGims()","a4f7c2b7":"getLeftChildI(uint256)","a4f82f27":"allocationOf(address)","a4f89235":"SALE0_CAP()","a4f91a2e":"remainingOwner()","a4f927d5":"certifyAccount(address,bool)","a4f939a1":"_touched(address,address)","a4fa75cf":"StartIcoStage()","a4fa8d57":"reward(uint256,uint256)","a4fac56e":"rateForOnePTM(uint256)","a4faf89e":"incentivesOut(address[],uint256[])","a4fd3cea":"getToken(uint256,uint256)","a4fd6f56":"isEnded()","a4fda741":"usedResidualAmount()","a4fde8bc":"player_declare_taking_too_long()","a4fefad6":"_currentSupply()","a4ff83f5":"warriorsByPlayer(address,address)","a4ffd7fa":"noOfICOPhases()","a5007da7":"openEgg(uint256,uint256)","a50097f2":"getUserEthVolumeSaldo(address)","a501123d":"doRollBet(uint256,uint256,bytes32,bytes32,bytes32)","a501553e":"getAssetLength()","a501ab39":"sendToMe()","a501e88d":"Content()","a5021a17":"getNodePrice()","a5025222":"addressExists(address)","a502aae8":"getNextGenerationId()","a502bfbd":"invest(address,uint256,bytes)","a503473a":"mul2Assert(uint256)","a50395cf":"totalPetCardSeries()","a504bd0d":"nextTradeEvent()","a50643b7":"getPrizePoolSize()","a506e5dc":"transferLand(uint256,uint256,address)","a5075567":"RegistrationAntique(bytes32)","a50776dd":"managementLocked()","a508ae0f":"P2TCToken()","a508dd1d":"OldCanYaCoin()","a509b030":"recentActivityIdx()","a50a1fe6":"remainingAmount()","a50b21c8":"getInputData(uint256,uint256)","a50c386a":"exFeeRate()","a50cd8e7":"votesFor(address)","a50cf84e":"ICO_PHASE2_PERIOD()","a50d81c7":"mintForOwner(address)","a50e20c1":"checkProfit(address)","a50ec326":"deposite()","a50ed19b":"setCooldown(uint256,uint256)","a50edca0":"fiat()","a50f2a25":"AirdropSingle(address,uint256)","a510921e":"SaleStop()","a510f776":"setCompany()","a512fb25":"Purchased(address,uint256)","a5135634":"avalibleSTCTokens()","a51548a1":"CryptoPainting()","a515aaeb":"cdFee()","a5171828":"MillionDollarToken()","a5177400":"minimumContributionPhase3()","a5181756":"AdameToken()","a519419e":"depositoryDelegate()","a51a6054":"roundLeader()","a51a8682":"saleTransfer(address,uint256)","a51ad03f":"isFirstYear()","a51aea2d":"changeMaxMultiplier(uint256)","a51af4c5":"distributorAddress()","a51b79e3":"changeYumAddressTo(address,address)","a51ba542":"deleteMonsterIndexToApproved(uint256)","a51bb77a":"getInvoiceHashAddresses()","a51d5924":"transferMain(address,address,uint256)","a51d5f02":"RemoveOwners(address[])","a51db46b":"changeDX(address)","a51e62a1":"developmentAuditPromotionWallet()","a51e81bb":"TRexCoin()","a51f3782":"investor_getMediumInfo(address)","a51f41a0":"setConfig(uint256,uint256,string,string,uint256)","a51fbb3f":"approveTokensWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","a51fe113":"start(uint256,uint256,address)","a52079ea":"balanceBlocksIn(address,uint256,uint256)","a521036c":"feePaymentEnabled()","a5214f77":"setContext(bytes32,address)","a521ebfa":"refundPresale(address,uint256)","a521f09f":"Greenbow()","a522ad25":"withdrawTokens(address,address)","a523b88a":"like()","a524ce4f":"deliverPresaleTokenToClient(address,uint256)","a525663a":"updateOwnerProprietaryData(uint256,string)","a525f42c":"transferFromToICAP(address,bytes32,uint256)","a526c826":"ICOBuyer(address,address,uint256,uint256)","a526f74f":"PRICE_AFTER_SOFTCAP()","a527096e":"preallocate(address,uint256,uint256,uint256,uint256,uint256,uint256)","a5289158":"end(address,address)","a528cb4f":"currentNumberOfRares()","a528fec4":"setSecureFees(bool)","a5290f74":"phase_2_rate()","a5294f93":"CryptoTradeToken()","a5295ae4":"AaaToken(uint256,string,uint8,string)","a5298955":"setAllHatchConfigs(uint32[],uint256,uint32[])","a52a0f8e":"getIntervalCoefficientMultiplier(uint256,uint256,uint256)","a52b121e":"faucetThresholdSecs()","a52b2b88":"hasWon(address)","a52b904b":"ScoreToken(string,uint8,string,string)","a52bc175":"Essential()","a52c0512":"getNumIncorrectDesignatedReportMarkets()","a52c101e":"send(uint256)","a52c11a6":"setBalance(uint8,address,uint256)","a52c34c3":"shopSettings()","a52c9efd":"updateIncrease(uint256)","a52cf5a4":"HanlinTestToken(string,string)","a52dc2e7":"blockN()","a52e6180":"setDiamondAuctionAddress(address)","a52ef9b0":"look_for_node(address)","a52f365a":"dissmisPurse(uint256)","a52f89fa":"nujaBattleTransfer(address,uint256)","a5304fc3":"ownerSetJpMinBet(uint256)","a5313069":"StairStepDecayingTokenFunction()","a53260c1":"migrateEthers()","a53290ab":"getClassTransformInfo(uint32)","a53324b5":"mint(uint256,string,uint8,string)","a53367dc":"ICOBuy()","a533daf7":"investmentPositions()","a533fb8d":"_mintToPool(uint128,uint256,uint128)","a534150c":"feePpm()","a536ae38":"payBidAllocationFee(bytes32,uint256)","a536cffd":"assertEq6(bytes6,bytes6,bytes32)","a536dbe8":"getCurrentPrice(uint256,uint256,uint8)","a5374005":"paymentsProcessor()","a537b716":"applyWithdraw(address,uint256)","a53818ca":"setNodeAllocation(address)","a53830e3":"numVotes(address)","a538d287":"getMinMax()","a53a1adf":"approve(bytes32)","a53a4747":"setOperatingCost(uint32[5])","a53aeb4e":"accumulate()","a53b1c1e":"setInt256(int256)","a53bfcf5":"varTokenAllocation(uint256)","a53c6dd4":"splitComissions(uint256)","a53c7b45":"setGameStatus(bool,string)","a53cb8ca":"setWhitelistTokens(address,bool,uint256)","a53d5205":"stepTwoLockEndTime()","a53d66e4":"changeAuxPartner(address)","a53ec007":"changeAirLimitCount(uint256)","a53f0e14":"addGrant(address,uint256,bool)","a53f138a":"updateTeamsTableAttributes(uint256,uint256,uint256,uint256)","a54016a0":"set_price_in_micro_ether(uint256)","a5403b3b":"secondaryLedgerCount(string,address)","a540db73":"triggerCooldown(uint256)","a5410a66":"kycVerified(address)","a5417f64":"decreaseICOEndTime(uint256)","a541a2a2":"projectCreator()","a5422d8a":"mineSoul()","a542a02f":"lookupAllSprites(uint256)","a542c3d7":"stageDevelop()","a54315fd":"SetBuyoutPrice(uint256,uint256)","a543a7e5":"addLockUpData(address,uint256[],uint256[])","a543bae7":"createSwap(bytes20,address)","a5440fa0":"GetAll()","a54447aa":"purchaseCard(uint256)","a544594e":"donateDAI(uint256)","a544805c":"CentralityGiftShop()","a544f062":"finanReserveWallet()","a54527d5":"AllSpringChainToken()","a54580f2":"drive()","a545ff0c":"withdrawRemainingEthAfterAll()","a5460352":"_validatePurchase(address,uint256,uint256)","a54677e3":"getOptionTitleForPoll(uint256,uint256)","a5468081":"Pyramid(address)","a546cbf7":"core(uint256)","a546f2e7":"changeNewHDX20Contract(address)","a5473276":"slice(uint32[],uint8,uint8)","a5473f78":"withdrawOrderRefundToOrder(uint256)","a54799bd":"Person(string,address)","a547adce":"lastBlock_f16()","a547ec4c":"setTime(uint256,uint256,uint8)","a548617c":"SampleCrowdsale(uint256,uint256,uint256,address,uint256,string,string,uint8,uint256)","a5488a37":"allowTransactions()","a54940b1":"Devable()","a5496781":"NamiMultiSigWallet(address[],uint256)","a5496e60":"newProposal(uint256,string,string,uint256,uint256)","a549ac10":"mintNFTForSale(uint256,string,uint256)","a54a2b8b":"testBlockHashFetch()","a54b2a73":"burnPool()","a54baeda":"removeAllowedLock(uint256)","a54c2a9a":"removeListing(uint64)","a54cd4f7":"minParticipants()","a54d396e":"internalAction()","a54e1ec4":"SubpreferToken()","a54efb1e":"BKB()","a54ff9ac":"downvotePost(bytes32)","a5500c30":"setAirdropAmount(uint256)","a5502b01":"Total_Players()","a550f86d":"named(bytes32)","a5512db0":"setTSTC(address)","a5513af5":"checkPrevOwner(bytes32)","a55168ea":"SendEtherToAsset(uint256)","a551878e":"fix()","a551de87":"MonethaAddressSet(address,bool)","a55231f4":"declareEmergency(string)","a552c8a0":"LogSendFail(uint256,bytes32)","a553506e":"checkData(bytes32)","a5536fe7":"mutable()","a553748e":"listingActive(uint256)","a5537586":"conversionOfferedAt()","a553a597":"configure(uint256,uint256,uint8,address)","a553c4d2":"tier2LOT()","a553e1da":"getUserTokensCount(address)","a5541ca2":"AICT()","a554a72e":"POINTS_TO_SPEND()","a55526db":"touch()","a55545a9":"EthVocToken(uint256,string,string)","a556a057":"ZAPAX()","a557f834":"month24companyUnlock()","a558410a":"test_twoValidEqUint(int256)","a5584456":"addDiscount(address,uint256,uint256)","a559217c":"raisedEther()","a5595683":"lockBalance(address,uint256,uint256)","a559ec20":"upgradePendingExchange(address,uint256)","a55b13c8":"validOtherSource(string)","a55bbff9":"setDatePayout(address,uint256)","a55c51d8":"havven_escrow()","a55c974f":"tokenXstepCAP()","a55cab95":"getName(uint8,uint8)","a55cc1cc":"newTokenWeiPrice()","a55cd51c":"updateMaxBet(uint256)","a55d260d":"depositNoRef()","a55deccb":"locked(address[],uint256[])","a55e9370":"getDateCount()","a55ec39d":"BulkTransfer(address[],uint256[])","a55ee823":"BYN()","a56024d8":"deleteUserForUser(string,uint8,bytes32,bytes32)","a5603f02":"getCurEarlyIncomeByAddress(address)","a5609ab5":"enableDepositTo(bool)","a560a956":"duelAnotherCovfefe(uint256,uint256)","a5613724":"Start1()","a561b1c2":"executeBatchTransfer(address[],uint256[])","a56226ef":"officialApplicationSignUp(string)","a5622c94":"xEURCoin()","a5627d32":"callDeposit(uint256)","a564871f":"ctWallet()","a56539a4":"_addLock(uint256,uint96,address,uint256)","a565efff":"countWinners()","a566d383":"softCapCHF()","a5670c80":"get_sale_arbits_per_ether()","a56793ae":"addCoin(uint256)","a567d371":"prepareForRefund(address,address)","a568907a":"SUCToken(address)","a568a09d":"BuyShareWithDividends(uint32,uint256,uint32,address,address)","a56a1de0":"Mortal_HelloWorld()","a56b3d11":"setNewCdFee(uint128)","a56b60ee":"_removeFromBlacklist(address)","a56be205":"developer_new_price(string)","a56befd1":"required_number_players()","a56c2ac0":"totalWeiRefunded()","a56c5be1":"WithdrawConfirm(uint256,uint256)","a56d1de3":"valueOfVault(uint256,address)","a56d7601":"getPlayerTickets(address,uint256,uint256)","a56d96bb":"unmint(uint256,string)","a56dfe4a":"y()","a56e7213":"unpausePending()","a56e7bae":"getTitleAddress(uint256)","a56f2d5f":"AutoMOBILEtoken()","a56f5b53":"withdrawDonations(address)","a56f9bea":"KarTokenERC20Advanced(uint256,string,string)","a5705d17":"performUpdateStackPtr()","a572ba41":"CEL(uint256,string,uint8,string)","a5731c1c":"getTXSAddress(uint256)","a573a9f4":"Bilateral()","a57429e2":"getWinConditionInLibra(bytes32)","a5749710":"getCurrentBalance()","a574cea4":"getMetadata(uint256)","a5752034":"changeRound(uint256,uint256,uint256,uint256)","a57544da":"right36(uint256)","a5758552":"redeemTokens(address)","a5766aa6":"setFeePercentage(uint8)","a577efd4":"closePot(string)","a578ae32":"getApprobation(uint256,address)","a578e38a":"RadiumSupply()","a5790bde":"toBytes1(bytes)","a57918dc":"ptc_addr()","a579349a":"currentStageRemainingJM()","a579e461":"SetAdminContract(address,address)","a57a84a6":"sendPending()","a57c0919":"update(uint256,uint8,address,address,string,string)","a57c6e86":"sellTokens(address,uint256,uint256,address,bytes)","a57ce52f":"_removeKeeper(address)","a57d1560":"lottery(uint256)","a57d814b":"MONACOESTAT()","a57e768c":"SetLockAddress(address,bool)","a57f57f8":"TBToken()","a57f59c0":"getMatchInfoList02()","a57f6500":"readCTDdata(uint256)","a5804521":"StateChanged(bool,string)","a58079fc":"FIXED_PRESALE_USD_ETHER_PRICE()","a58091cd":"privateSaleSencPerMEth()","a58092b7":"getSanityRate(address,address)","a580a5b0":"setRepayment()","a58180b4":"_batchBuild(uint256[],int256[],int256[],uint8[])","a581a27a":"owner_balance()","a581c333":"getSHA256(bytes)","a581ff0e":"CopyrightExchangeToken(uint256,string,string)","a5820daa":"issueTokens(uint256)","a5828b7d":"payBonus(address)","a583535d":"addCutie(uint32,uint256,uint256)","a5841194":"sync(address)","a5842415":"Cubes(uint256)","a5843f08":"init(uint256,uint256)","a5847862":"sizeOfString(string)","a584d8cc":"startProduct(string,string,string,int256)","a58561ec":"DISCOUNT_STAGE_TWO()","a5857318":"getIdArrayItemsCount(address,uint256,string)","a586fd0f":"_substring(string,int256,int256)","a587686d":"addCardToEdition(uint8,string,uint8,uint8,uint256,uint256,uint256)","a5878c65":"addPrivatePresaleTokens(address,uint256,uint256)","a587c9f7":"bountyTokenAddress()","a587cd36":"DisableSetTransferable(address,bool)","a587da29":"setPackage(bytes,uint8,uint8,uint8,bytes)","a588a968":"rushitesticoToken()","a5891bb0":"modifyWhitelistMulti(address[],bool[])","a5898832":"getReferrerRewards()","a58ac1a1":"buyTokensInternal(uint256)","a58b2e43":"LendingLiquid()","a58b55a9":"StreamityEscrow(address)","a58b7eed":"setFlags(address,address,uint256)","a58ba458":"multiTransferTightlyPacked(bytes32[],address)","a58c07ee":"fetchOrderByIdWithPayerByAdmin(string,address)","a58c30c5":"block2()","a58d3ad1":"dumpCube(bytes,bytes32)","a58daf76":"setAuthorizedToDraw(address)","a58fd85b":"setReflectSwitch(bool)","a58ff4fc":"deletThisContract()","a590529e":"updateWithPositionHint(uint32,uint128,uint128,uint32)","a590799a":"refundInvestment(address,uint256)","a59162eb":"OWEToken()","a5917019":"SecurityDepositCreated(uint256,address,string,string,uint256)","a5917baf":"vestingVault()","a5917dea":"processInternalRequest(string,bool,uint256,uint256)","a591d4a6":"getMsgValueAfter()","a5925b5b":"clearAuthorization(address)","a59307e8":"Play(address,bytes1,uint256)","a593845f":"_rollCriticalDice()","a594056f":"getPriceInExoTokens(uint256)","a59455dc":"getPacket(uint256)","a594a117":"giveGen(uint256)","a594a236":"_updateClaims(string,string,string)","a594b29b":"PRE_SALE_START_4()","a595a94d":"_sendGameGift(address,uint256)","a595b655":"Gimli()","a595f2eb":"quantidadeDeAutorizacoesNecessariasParaUmaNovaOuvidoriaPoderSeCadastrar()","a5967039":"cancelMigration(address,address)","a5968cc6":"PresaleTokenVesting(address,uint256)","a5976f97":"allocateReservedFunds()","a59799e6":"updateAvatarInfo(uint256,string,uint256)","a5982885":"assertFalse(bool)","a5985e8c":"getLevel()","a5987c9e":"getMyKilo()","a5989dbe":"nines(uint256)","a599ef65":"enroll(uint256,uint256)","a59a3750":"getWeapon(uint8[176],uint8,uint8)","a59ac6dd":"buy(address,uint256,uint256)","a59aef4e":"nickOf(address)","a59af340":"isInvestorApproved(address)","a59b193a":"setRecord(bytes32,string,string)","a59b7de5":"consumeCoinForNova(address,uint256)","a59cacb2":"setMinWeiAllowed(uint256)","a59d6986":"recoverLostFunds()","a59d930b":"ownerSetEtherwowAddress(address)","a59dbfb7":"gift_Transfer(address,uint256)","a59def62":"ABYSS()","a59eca54":"getPlayerIdByAddress(address)","a59f3e0c":"enter(uint256)","a59f8a2b":"GFCB()","a59f9d56":"ChangetokenManagerAddress(address)","a5a01bc7":"addCarInit(address,uint32,uint32,uint32,uint64)","a5a0545f":"FCChainTokenTest(uint256,string,string)","a5a2286b":"ReserveAddress()","a5a2aa33":"purseExchange()","a5a2cb19":"buyUpgrade(uint256)","a5a2fc4a":"claimableFeesOf(address,uint256)","a5a32c3a":"GEMCHAIN()","a5a3ad0b":"ValidatorBond(address,address)","a5a45785":"setRescue(address,bool)","a5a54ea5":"SM()","a5a584a2":"QuestionToken()","a5a5f468":"WorldCupAuction(uint256,uint256,bool,address,address)","a5a65bba":"checkvehrespond(uint256,address)","a5a6a7b2":"after20Seconds()","a5a6d7b3":"sellMyBanana(uint256)","a5a7d086":"ethereumFoundationTickets()","a5a7dadf":"preCrowdsaleEndTime()","a5a83e4d":"right91(uint256)","a5a899ec":"halts()","a5a8c53d":"setmessiCommunityAddress(address)","a5a98d78":"inflate()","a5a9ba8d":"getSellReturn(uint256)","a5a9cf0d":"sixthTeamWithdrawal()","a5aa0545":"createHumanStandardToken(address,uint256,string,uint8,string)","a5aa4348":"setTitulaire_Compte_9(uint256)","a5aa542e":"remainingFunds()","a5ab3436":"Payouts(uint256,bool,address,uint256,uint256)","a5ab5479":"generateNum2Win()","a5ab89ff":"setHost(string)","a5abe7f6":"isConstant()","a5acb022":"LOG_BetWon(address,uint256,uint256)","a5acc46e":"PauseInfrastructure(bool)","a5acd206":"updateStateFromOracleFoo(address)","a5ad0588":"transferFrozenTokens(address,uint256)","a5ad1348":"checkPosition(address,address,uint256)","a5adb226":"setABackend(bytes32,address)","a5ade117":"candyPrice()","a5ae65ba":"getGen()","a5aeb9b7":"totalWeiContributed()","a5af66c5":"HowLongIsDisputeRevealStillRunning(uint256)","a5b067b3":"INKCToken()","a5b0930d":"getAddressArray()","a5b19937":"endVesting(address,address)","a5b1e13d":"settle(address,address,uint256,uint256)","a5b222c9":"setData_20(string)","a5b2235d":"register(address,address[])","a5b36a36":"stalePeriod()","a5b3720b":"BulkTransfer()","a5b3d1a9":"tenmarionCoin()","a5b4069e":"DataCoin(address)","a5b41c0e":"AK48Coin(uint256,string,string)","a5b4aaab":"editMilestone(uint256,uint256,uint256,uint256,uint256,string,string)","a5b4f7d3":"setAgentVerificationByAgent(bytes32,address)","a5b538f9":"nextBonusPayout()","a5b589ce":"mHostFee()","a5b6420e":"_setBool(bytes32,bool)","a5b6ea8f":"spin(uint256)","a5b70519":"multiValueAirdrop(address,address,address[],uint256[])","a5b75814":"bonusPhase3()","a5b781e1":"lockPostion1Add(uint8,address,uint256,uint256,uint8,uint256,uint8,uint256,uint8,uint256,uint8)","a5b78bfa":"NebulaToken()","a5b87ef7":"StgFourbonusEnds()","a5b9e922":"getContentTimetamp(uint256)","a5ba3b1e":"tokenClaims(uint256,address)","a5bb9162":"tokenadd(address,uint256)","a5bbc311":"getNCSTotalSupply()","a5bbc423":"withdrawByEmergency(string)","a5bbd67a":"lockedAddresses(address)","a5bbe7bf":"takeOrder(address,uint256,uint256)","a5bc770c":"tokensPerKEther()","a5bd1566":"getDiscipleVend(uint256)","a5bdbb28":"buyBlock(string,uint256,uint256,uint256,uint256)","a5be0c5e":"ERC20Proxy(string,string,uint8,address)","a5be1a4d":"multipleTransfer(address[],uint256)","a5beb4e5":"claimRefundFor(address)","a5bebf48":"founderTokenUnlockPhase1()","a5bf7aae":"CPSTestToken1()","a5bfa9a9":"claimToken(bytes32)","a5bfd16a":"getAllLoans()","a5c02493":"setChain(string,address,address,address)","a5c04bfe":"allocateTeamBonus(address,uint64,uint64,uint64)","a5c102a2":"setMinterFeePercent(uint256)","a5c12df9":"OpenANXToken(address)","a5c154b3":"setMiniPoolEdit_2(string)","a5c1db32":"CrosspaysToken()","a5c28b1e":"getGovtApplication(string,string)","a5c3eb03":"UbbCoin(uint256,string,string)","a5c464b3":"isOnSaleAny2(uint256,uint256)","a5c5436f":"preCaution()","a5c5463f":"getCurrentlyRunningTier()","a5c5762b":"PVT_INV_TOKENS()","a5c57b18":"BITDINERO()","a5c58944":"dSetEditorArbitraryData(bytes32,bytes,bytes)","a5c5edee":"updateGameMetadata(uint256,string,uint256,bytes32[])","a5c6ac0d":"percentagePerMonth()","a5c7ac13":"test_updateKey_decreaseNoHint()","a5c81622":"signedApprove(address,address,uint256,uint256,uint256,bytes32,address)","a5c860ba":"eth_minimum()","a5c8a201":"geth(uint256)","a5c8b7a1":"transferPublisher(address)","a5c978c0":"TIA()","a5c9cd82":"TOKEN_UNIT()","a5ca2afa":"VESTING_INTERVAL()","a5ca35f5":"Trade(uint256,address,uint256,address)","a5cae60c":"getAppInfo(uint32)","a5cb66c0":"ChronosCore(uint256,uint256,uint256,uint256)","a5cbe71c":"getCooldownEndBlock(uint256)","a5ccd855":"setConstractDeployTime(uint32)","a5ccfb06":"sellCard(uint256,uint256)","a5cd184e":"free(bytes32,uint256)","a5cd3fd0":"steemh()","a5cd761f":"getTokenOwner(uint256)","a5cd806b":"BONUS_PCT_IN_VREO_SALE_PHASE_1()","a5cda792":"distribution(address[],address,uint256[],uint256[])","a5ce0693":"endBlockBonus1()","a5ce3eb0":"totalPaidAmount()","a5ce413b":"unstakeTokens()","a5cf3898":"verifyExtraData(bytes32,uint256)","a5cf38da":"createCrowdsaleTiers(bytes32[],uint256[],uint256[],uint256[],bool[],bool[])","a5cf56f2":"ethReceivedPresale()","a5cf599c":"ENDING_TIME()","a5d048d3":"create(address,uint256,uint256,address)","a5d0bab1":"buyPartial(uint256,uint256)","a5d18cb6":"checkGameAmount(uint256)","a5d1c0c0":"gameTime()","a5d33c2b":"MessageSentToChannel(address,string,string,uint256)","a5d3845b":"tokenEventAddress()","a5d572c4":"fixedTotalSupply()","a5d57bb7":"ApproveAndDo(address,uint256,bytes32,string)","a5d5ca54":"PolyCustomers()","a5d5db0c":"depositCollateral(address,uint256)","a5d638f1":"transferOwnershipRequest(address)","a5d677ab":"getFileByIndex(bytes32)","a5d68bfd":"RATE_WHOLESALE()","a5d6d4c3":"mintAuthorizedBatch(address[],uint256[])","a5d7a14f":"ContractorProposalAdded(uint256,uint256,address,uint256,uint256)","a5d8628a":"AgriChainDescription()","a5d871c0":"AddressChanged(uint256,address)","a5d8746e":"canMakeBet()","a5d8b72b":"midasAdvisorOperateMarketingAddress()","a5d8cdf2":"deploy_time()","a5da0bf5":"addAfterId(address,uint32,uint128,uint128,uint32)","a5db83e4":"marketRegisterToken(address)","a5dcf458":"uintToBetsArray(uint256)","a5ddfef1":"getTotalAmountOfTokens(uint256)","a5de12ab":"ITBITSToken()","a5de3619":"admins()","a5de811f":"checkMyWithdraw(address,address)","a5def8cb":"numbOfFrozenAmCount(address)","a5dfd89a":"getPrize(address,uint256,bytes3,uint16)","a5dfee67":"testThrowsCreateNewRevisionNotUpdatable()","a5e00e53":"QNTU(address[],uint256[])","a5e108af":"addEmployerContract(address,address,uint256)","a5e11729":"maxPower()","a5e1c5b5":"setVal(bytes32,uint256)","a5e20eaa":"getProjectStartDate(bytes32)","a5e220c2":"Owner(address)","a5e2dbfb":"_scto(uint256,uint256,uint256,uint256,address)","a5e33048":"generateTokens()","a5e45bec":"range(uint256)","a5e4e9a0":"maxCWCsPerReturnLessThan()","a5e4fedc":"LogTransferFromOwner(address,address,uint256,uint256,uint256)","a5e52c08":"ImmediateProfit(address,uint256)","a5e53bfe":"checkRandomFromRandao(uint256)","a5e558a3":"MIN_FUND_AMOUNT()","a5e57fcf":"GetUserBitFlag(address)","a5e5e034":"swapTop(uint256)","a5e62f02":"fallbackRP()","a5e7131e":"transferFundsAdminOnly(address,uint256)","a5e767cd":"frozenAccount(address,address)","a5e7a31c":"summReserveFund()","a5e82807":"deletedTeamIds(uint256)","a5e8c5d6":"setVoteRight(address,uint256)","a5e90eee":"setManager(address,bool)","a5e9585f":"xxx(uint256)","a5e9fffa":"calculateAmount(address,uint256,uint256)","a5ea11da":"getParameters()","a5eb1c6d":"Ovation(uint256,string,string)","a5eb7a4e":"operated()","a5ebb9ef":"backERRLCoinOwner()","a5ebc10b":"blocktubeClip(string,uint256,uint256)","a5ebf389":"getMoneyTotals()","a5ec4fae":"changeBaseVerifierFee(uint256)","a5ecacae":"getContributionTime(uint256)","a5ece941":"marketingAddress()","a5eceaf1":"bet1000_1eth()","a5edcd9e":"ethtotalSupply()","a5ee79d3":"extendRequestTimeLock(bytes32)","a5ef0dd6":"setGen0Profit(uint256)","a5ef69ea":"icoEndAt()","a5ef9915":"jotAllowance()","a5f02b00":"markCombatEnded(uint256)","a5f0dea2":"saleFinalized()","a5f11474":"Tronix()","a5f128fb":"stopSelling(uint256)","a5f18c01":"getStartBlock()","a5f1e282":"lockedOf(address)","a5f257e7":"transferDividendToShares()","a5f26760":"updateTimeMintBalance(uint256)","a5f2a152":"transferTo(address,address,uint256)","a5f2e079":"borrowerReturnAmount()","a5f357de":"MAXROUNDS()","a5f3c23b":"add(int256,int256)","a5f4648c":"getNextTurnColor(uint256)","a5f4864d":"ELBT()","a5f4af33":"playerWithdrawPendingTransactions()","a5f4c6ff":"publicStart()","a5f732e5":"distributeLTCW(address[],uint256)","a5f75a5e":"dollars_per_kilo_ether()","a5f7823e":"onlyAdmin()","a5f7c148":"transfer(address,int256)","a5f8b874":"wasProxyStorageSet()","a5f8cdbb":"buyTicket(address)","a5f9b5c2":"gameRound()","a5f9fd99":"splitShare()","a5fa2490":"smxSold()","a5fa5e52":"showTime(address,address)","a5faa125":"getAuthor()","a5fadf93":"modify_Presale3StartDate(uint256)","a5fb929a":"userRewarderCount(address)","a5fba4e1":"isDistributionDue()","a5fbd808":"globalBurnAmount()","a5fbdd41":"updatePremiums(address)","a5fbf287":"isSupported(address,uint256)","a5fc2994":"sendStore(address,uint256)","a5fd0a18":"chargeChannel(uint256)","a5fd1838":"getBonus2(uint256)","a5fdc5de":"collateral(address)","a5fefcfd":"thirdMonthEnd()","a5ff2551":"LOCIcoin(uint256,string)","a60014e3":"buyCore(uint256)","a60110ee":"ProposalTalliedEvent(uint256,bool,bool)","a6021ace":"ERC20Address()","a6024524":"PRE_ICO_FINISH()","a6027d53":"IconomiTokenTest(uint256,string,uint8,string,uint256)","a6044f28":"virtualEntitiesCreated()","a604c1ad":"Blocker_send(address)","a6060fcb":"Bitdore(uint256,string,string)","a6065c96":"brokerVerifierContract(uint64)","a6066523":"payment_amount()","a6069146":"setItemRangeURI(uint256,string)","a6070967":"minSumICOStage8USD()","a60745aa":"getBountyData(uint256)","a608067b":"getDrugPrice(uint256)","a608a65b":"CryptoAdsToken(uint256)","a60956a6":"newItem(uint8,uint8,uint256,uint256,uint256,uint256,uint256,bool,bool,address)","a6099372":"payDiff(address,uint256)","a609e209":"BIRTHDAY()","a609f034":"getByteFromBytes14(bytes14,uint256)","a60b693d":"getTotalCap()","a60b8aa9":"minusTourFreezingTime(uint256,uint64)","a60bbcd3":"ModelCoordinator()","a60c8043":"totalDistributionAmountInWei()","a60c9cdb":"TheBolthDAICO(address,address,address,address,address,address,address,address)","a60dc38a":"convertToWei(uint256)","a60e043e":"CappedRefundableCrowdsale(uint256,uint256)","a60e8bd6":"setVotingProxy(uint8,address)","a60eb299":"setRewardGenerationComplete(bool)","a60f3588":"payoutIdx()","a610fe9b":"chargeHoldingTax()","a6113c0d":"getSynthesizationResult(address)","a6117f39":"validPrePurchase()","a611e0e6":"forceRentalEnd()","a612c638":"emergencyRestart()","a6138ed9":"pricer()","a613c42d":"NWT()","a6145ba2":"isAllowContribution()","a614d54e":"GlobalAdmin()","a6151a84":"isDestroyed()","a615237e":"rebrand(string,string)","a615d7ee":"withdrawTokenToInvestorOwner(address)","a6178731":"usingInterCrypto()","a617aff1":"brideAddr()","a61855a4":"changeCommonRebate(uint256)","a618993c":"setGBA(uint32)","a618f50c":"distributeSSENTE(address[])","a619486e":"masterCopy()","a61bd76d":"purgeInformation(uint256)","a61c48f0":"getPollResultsSize()","a61c5b82":"numStudentRequest()","a61d0aed":"maxBets()","a61d6829":"getPosterInfo(uint256,uint256)","a61e1fc1":"_shuffle(uint8[])","a61e67aa":"testFailMintGuyWhenStopped()","a61e9f4d":"momentBlockOf(uint256,uint256)","a61ef635":"translateToStartingTile(uint16)","a61fe970":"candyBalance()","a621344a":"setTokenWallet(address)","a621d679":"XPZ()","a6223a58":"testAccess(address)","a622510b":"TranslationService()","a623e9bf":"PresaleDistribution(address,address,uint256)","a62438e2":"getPeriodKey(uint256)","a6245974":"getUpgradeProposalCount()","a6248874":"totalFirstICOSupply()","a62533e6":"diffString(string,string)","a6256644":"setDonationsReceiver(address)","a625d78d":"MasterDeposit(address,address,uint256)","a626c089":"changeSettings(uint256,uint256,uint256)","a626c3fe":"assignBountyTokens(address,uint256)","a626f445":"GlobalPersonalInsuranceChain()","a62784e2":"setCCH_edit_3(string)","a6279dbd":"getPartialAmountCeil(uint256,uint256,uint256)","a62819ed":"AddExec(string)","a62875d9":"getMyPastWins(address)","a62a07dd":"release_dates(address)","a62a86a0":"associateWithTaskAddress(address)","a62adfec":"buyTokens(uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","a62ce8ce":"capitalization()","a62d4df3":"_absSubtraction(uint256,uint256)","a62d7801":"resumePhase()","a62d9ba3":"withdrawToPlatformFunding(uint256)","a62e4246":"CampaignBeneficiary()","a62e5a7d":"sellComission()","a62ea098":"buyLCRTokens()","a62f3503":"updateBankAmount()","a630a92e":"ownerTransferWeiFirstWallet(uint256)","a6314342":"deleteManager()","a63234e0":"issuerAddress()","a6327ffc":"convert2PlatinumToken(uint256)","a632a2e5":"setnumber(uint256)","a632d5e1":"MANHATTANPROXLENAV()","a633d8d4":"getDougAge(uint256)","a633f61f":"getPositionOwedAmountAtTime(bytes32,uint256,uint32)","a6345859":"setEscapeRequest(uint32,uint32)","a635d31e":"Vote(address,bool)","a635e7c5":"BuyEBETtokens()","a636f4a1":"VoterAdded(address)","a6372087":"starNoLongerForSale(uint256)","a63744e0":"addPoll(uint256,bytes,uint8)","a63832a0":"dateFunc(int256)","a6391823":"awardsOf(address,uint8)","a6393784":"BiddableEscrow(address)","a63a9fa6":"setNextSnapshotBlock(uint256)","a63aeed9":"tokenSaleResumedTime()","a63b91f4":"autoBurn()","a63c500f":"is_locked()","a63c7ba2":"payoutToBeneficiary()","a63d0be6":"findAndTrade(address,address,uint256,uint256)","a63d6f05":"setRewardLevel(uint256,uint256,uint256,uint256[],uint256[])","a63d914f":"confirmAction(uint256)","a63dcbd7":"updateRtbSettlementAbi(string)","a63e10fa":"getUnreadMessageCount(address)","a63f1350":"getParentUniverse()","a63f5e2a":"candyToken()","a63f8020":"scWithdrawCall(address)","a6403636":"resolve(uint8,bytes32,bytes32,bytes32)","a64085cc":"getAllClients(address)","a641d28e":"revokeDelegateSigned(address,uint8,bytes32,bytes32,string,address)","a641edc7":"BOC(uint256,string,string)","a6424d22":"setVigAddress(address)","a64278ce":"lost_and_found_master()","a642c032":"getEdition(uint256)","a643c1a0":"updateAddresses(address)","a6441979":"StexIssued()","a6459042":"agencyReceiver()","a645a33a":"VotingFinished(bool)","a645e840":"getCurrentGameInfo()","a645ff5f":"send(address[],uint256[])","a646f9ad":"userWithdraw()","a6472906":"getAxie(uint256)","a6474a58":"setnotice(string,string,string)","a647e8ec":"mint(address,uint256,uint256,uint256)","a6482858":"boxPrice()","a648567b":"placeBet(uint8,uint8)","a648fec2":"updateAllTurnover(uint256)","a6491545":"_giveToken(address,uint256)","a64968ac":"joyToken()","a64a1c0b":"totalSoldTokensWithoutBonus()","a64ad595":"getDelegator(address)","a64b0b62":"addDevReward()","a64b63a8":"ParcelXGPX(address[],uint256)","a64b6e5f":"transferTokens(address,address,uint256)","a64bb045":"Test7J()","a64c7e2a":"Crowdsale(address,address,address)","a64d1c09":"hashOrder(uint8,address,uint256,uint256,uint256,uint256)","a64ded31":"tttTokenAddress()","a64e7969":"balancesCannotSell(address)","a64e920d":"vrcCount()","a64ed8ba":"tokensCount()","a64f0ca4":"getEtherInEuroCents()","a64f197e":"allocateBid4b(bytes32)","a64f829a":"addDungeonRewards(uint256,uint256)","a64fa869":"PrezzoCMT(uint256,uint256)","a650ebbc":"transferFromInternalStakingfund(address,uint256)","a6515a98":"admined()","a652477b":"STSTEST3()","a6534b63":"EtherBet(address,uint256,uint256)","a65465ff":"pank15()","a65491d5":"yeezy()","a654cfab":"pots()","a655fb4e":"level_9_amount()","a6567a9a":"calculateNewTime(uint256,uint256)","a656e51f":"lastInvestorsProfitDay()","a657242b":"Hardcap()","a6572c87":"getemployee(address)","a657cb9c":"submitRedeem(uint256)","a6593562":"getamountvotes()","a65a26e8":"returnAddressList()","a65a7753":"Zentum()","a65ac961":"batchTransferValues(address[],uint256[])","a65ae513":"ownerDeclareFailure()","a65b37a1":"buyXname(bytes32,uint256)","a65b62c9":"priceRound(uint8)","a65c3097":"_distributeRest()","a65e91b8":"baseTokensSold()","a65eacdc":"delManager(address)","a65ecbeb":"getMaxTokenAvaliable()","a65f0f79":"Ethereal_Smart_ID(address,address,string,string,bool)","a65f1193":"weiToUsdCents(uint256)","a65f51c8":"gapTime_()","a6605a77":"_updateTradingVolume(uint256,address,address,uint256)","a660698e":"TheInternetDigitalCurrency()","a660a326":"balancesHold(address)","a660f827":"bonusEnds5()","a6624bf4":"ISBToken()","a6632904":"tier_cap_4()","a663b5de":"viewCoinsKarma(uint256)","a664225c":"exchangeFinished()","a6656096":"invalidateGame(uint256)","a6658dea":"BitSelectConservador()","a6661901":"totalNormalContributorIds()","a6662a3c":"initMetadataDisabled()","a6666f0f":"TTGCoin()","a6667e18":"RemoveWhitelist(address)","a666ff3c":"lockedTokenAddress()","a66712ae":"usersOfAccount(uint256,uint256)","a6674aa3":"Resigned(address)","a6678b60":"setJadeCoin(address,uint256,bool)","a668d7c9":"NiceGuyPonzi()","a66939ad":"hostileTakeover(address,uint256)","a669b56b":"pay_day()","a669c9f9":"registeredServices(address)","a669d972":"c_centsPerToken()","a66ac7bc":"payout(bytes32,bytes32)","a66b62e6":"gameOverByUser()","a66b7748":"follow(bytes32)","a66c0b1c":"setGoldmintTeamAddress(address)","a66c53b2":"buyCore(uint256,uint256,uint256,string)","a66cb0ee":"GetBonus()","a66d5ef7":"createNamespace(string)","a66db704":"getPOOL_edit_23()","a66ddf43":"mainSaleRateP3()","a66df701":"chargeFee(address)","a66e6e5c":"etoken2Symbol()","a66ee056":"internalTransfer(int256,address,address)","a66f32e5":"stage3Bounty()","a66f42c0":"boost()","a66f7ad6":"signRelease(uint256)","a66fd42b":"mintToggle(bool)","a670b9e7":"nestedSecondSome(uint256,uint256)","a670c133":"numTeamDeposits()","a6712778":"investBct(address)","a672990c":"whitelistContract(address,bool)","a6735023":"getProfilePicture(address,address)","a673b130":"Reserved(address,uint256[])","a6741cfd":"injectEtherToDividend()","a6747670":"senderToProxy()","a675807e":"totalLevs()","a675887e":"EtherReceivedFromRelay(address,uint256,address)","a676b174":"frozenAccountProfit()","a677fbd9":"example2Func()","a6780857":"fireEventLog0Anonym()","a6784488":"cleanOut()","a67909bd":"LOCKTC()","a6791568":"burnAllTokens(address)","a67a6eab":"bearToken()","a67ad1b2":"sellICloudSecsAgainstEther(uint256)","a67aee1f":"tokenConverter()","a67afd30":"vest2all(address,address)","a67ba5d2":"changeAdminCharges(uint256,uint256,uint256)","a67bb583":"tokenCapForSecondMainStage()","a67c2730":"getBonusPerShare()","a67c2dcb":"accept_ownership()","a67c8bc4":"mintFundsTokens()","a67cace9":"AIT_TokenERC20(uint256,string,string)","a67d2602":"getSafeAddr()","a67de805":"DWalletToken()","a67e91a8":"TOKENS_MAX()","a67eb8d7":"STRIMToken(address,address,uint256,uint256)","a67ebf73":"Voting(uint8,address,uint256,uint256)","a67f122f":"_1_vozrast()","a67f9997":"LIQUIDATION_RESERVE_RATIO()","a67fc3fa":"getRewardAmount(bytes32,bytes32)","a6801cbd":"reset(uint256,uint256,uint256)","a6808c3c":"_setAgilityValue17(uint256)","a6809af0":"setOdds(uint256)","a680baaf":"backendWallet()","a681bf23":"LegalBot()","a681f950":"setMinMax(uint256,uint256)","a6823189":"parseAddr(string)","a682dd4f":"SWAP(address,address,address)","a6832d53":"allowedTransfer(uint256)","a68393a2":"debug_getCoinbaseTxOutputLen(uint256)","a6843f34":"right48(uint256)","a6846026":"TokenMintingDisabled(address,bool)","a684bc9f":"tokenReserved3()","a684ff03":"bet(uint16,bytes32)","a68567ac":"IDToken()","a6856e9d":"JTEBIT(address,uint256)","a685a41e":"parseLoanOffering(address[9],uint256[7],uint32[4])","a685ae66":"minerTimeOfLastProof()","a685ea57":"getROFRStatus()","a68602fb":"SignalingDisabled(address,uint256)","a687be48":"RocketsAndResources()","a6885e88":"getStageData()","a6895b5a":"getDailyLimit()","a6896bdf":"isRightPosition(uint128,uint128,uint32,uint32)","a68a2884":"TournamentCore(address,address,address,address)","a68a76cc":"createForwarder()","a68b51ed":"addProposal(address,uint256,uint256,string,uint256,bytes)","a68b91ab":"getContractData()","a68c5ca1":"SDTToken(uint256,string,string)","a68c9bbb":"getBid(address,address)","a68cfb25":"getSecondAmount(bytes32,bytes32)","a68d9a62":"_setDownRequest(address,uint256,uint256,uint256)","a68dfb2d":"TTToken()","a68e27b7":"getLuckProps(address)","a68e4578":"totalLBSold_CORNERSTONE()","a68e5ad0":"depositTokensForTrading(uint256)","a68f0bc1":"TOTAL_LARE_FOR_SALE()","a68fff3f":"GenRandom(uint256,uint256)","a6903278":"beginBlock()","a69032ee":"proxyTransferFromToICAPWithReference(address,bytes32,uint256,string,address)","a69177b1":"addTotalSupplyAmount(uint256)","a6921956":"tokenStatus()","a692c2f9":"_toTileId(int32,int32)","a692d5ae":"migratePriceLeader(uint8,address,uint256)","a6934950":"_confirmOneBuy()","a69358aa":"voteForTap(bool)","a693600b":"poolAmount()","a69364fc":"ProofOfTheRich()","a6940238":"growth()","a69416f6":"getNodeType(address)","a6948cd9":"calculateArea(address[16],uint256)","a694dabd":"STARTING_SNAIL()","a694fc3a":"stake(uint256)","a69520aa":"alchemy(uint256)","a695cacf":"getGameIdsByCategory(bytes32)","a69709ae":"toHexString64(uint256)","a69722de":"validateDescription(string)","a6973fa1":"computeS(uint256)","a697ca14":"finishSingleLock(address,address)","a6980a17":"addPromo(bytes32,uint256,address,uint256,uint256)","a6983932":"SeckeyRevealed(bytes32)","a6988576":"walletTokenBounty()","a699cd20":"getGrowingControlStartAt()","a699d9b0":"saosao6()","a699fb18":"payoutWorth(address)","a69a2ad1":"totalBalances()","a69a5588":"set(bytes12,bytes32)","a69ade72":"LED_MULTISIG()","a69bd4a8":"regStartTime()","a69beaba":"vote(bytes32)","a69c22be":"getYays(uint256)","a69c5bbf":"bucketClosureTime(bytes32)","a69c6597":"getPlayerName()","a69cbb50":"_getEarlyBonus()","a69dde14":"checkPassiveAndNull(address)","a69df4b5":"unlock()","a69e894e":"createTokens(address,uint256)","a69eae7c":"changeAllowanceToMint(address)","a69f7d1f":"FOUNDATION_PERCENT()","a69f886a":"withdrawRaised(uint256)","a6a1858f":"whale()","a6a20ff6":"DSEasyMultisig(uint256,uint256,uint256,uint256)","a6a34dd3":"_setMinCardPrice(uint128)","a6a3a439":"getNumTransactions(address,uint256)","a6a3ba2b":"pausestatus()","a6a5bfe3":"getStage2Start()","a6a62d58":"lastBlock_f2()","a6a633af":"ROA()","a6a6a0d8":"becomeFrom()","a6a6f1c7":"registerLicense(string,string)","a6a86130":"usdToWei(uint256)","a6a9a099":"privateIcoMin()","a6aa7f7a":"onlyFounders()","a6ab1216":"getWeaponsArmy1(uint256)","a6ab36f2":"initialize(uint256,uint256,address)","a6aba1b5":"BitCoix()","a6abbad6":"assertEq16(bytes16,bytes16,bytes32)","a6ac9225":"getJackpotResults(uint256)","a6ad57e6":"difficultyScaleMultiplierLimit()","a6ae0aac":"coinbase()","a6afd5fd":"getBets()","a6b01e50":"isMultiOwner(address)","a6b05af6":"INITIAL_BONUSLIST_TOKENS()","a6b08498":"isOps()","a6b10dd1":"showToken_For_Circulation()","a6b11fb3":"factorial_ICO()","a6b165ee":"total_investors()","a6b197aa":"Order(address,uint256)","a6b1caa3":"gasScalar(uint256)","a6b206bf":"doSomething(uint256)","a6b26697":"EthRefundReceived(address,uint256)","a6b2c437":"confirmRequest(uint256)","a6b2df9b":"requestDocument(uint256,string)","a6b3abba":"getMyTokenBalance()","a6b402ec":"MGU()","a6b4492f":"servusToken()","a6b4b0f4":"testCreateGames(uint256)","a6b513ee":"finalPrice()","a6b55eec":"unlock(bytes16,uint32)","a6b57b5d":"sharesOwned(address,uint256)","a6b7fa36":"withdraw(uint32,uint192,bytes)","a6b87b52":"erc()","a6b909e1":"trades()","a6ba250c":"fechVoteInfoForVoterBySnapshotBlock(address,uint256)","a6bb012b":"penalizeInactiveArbitrators(address[],uint256[])","a6bb1667":"updateMatch(uint8,uint8,uint8)","a6bc18f9":"setTrader(address)","a6bd5427":"getOptionCount()","a6bd853b":"mtdPreAmount()","a6bdcc17":"isAtLeast(uint256,uint256)","a6bf3df0":"oraclize_query(string,string[2],uint256)","a6bf45a9":"getNumberOfDeedsByAddress(string)","a6c01cfd":"isInGeneration(uint256)","a6c09381":"_setPackedTimestamp(bytes32,uint256)","a6c0d5a8":"YukiChainToken()","a6c1d611":"getAngelLockStatus(uint64)","a6c1f87f":"partial_refund(address)","a6c216c2":"UpgradeEvent(address,address)","a6c226f0":"lock(address,address,uint256[],uint256[])","a6c23bc4":"setTokensPerUsdRate(uint256)","a6c24b38":"getRequiredPrice()","a6c2591e":"get_header(uint256,uint256)","a6c2f3b2":"getAllAgreements(uint256)","a6c30b29":"startGasCalculation()","a6c3e6b9":"author()","a6c4cce9":"registeredApps(address)","a6c4d58c":"MetronomeToken()","a6c4ec0e":"hasUser(address)","a6c5612e":"areTokensFree()","a6c58b63":"getJobStatus(uint256)","a6c62c90":"snake(uint256)","a6c662ea":"Cmc()","a6c66575":"processInviterBenefit(address,uint256)","a6c6aee1":"ODEEPToken()","a6c7bf8a":"setMasterWallet(address)","a6c7f715":"MoimToken(uint256,string,string)","a6c8210e":"getVotingParams()","a6c93349":"createContract(uint256,uint256,int256,int256,int256,int256)","a6c94d2e":"durationVoting()","a6c95de1":"transferBountyTokens(address,uint256)","a6c98142":"SquirrelFarmer()","a6ca0a98":"PARAMOUNT()","a6ca322b":"refundCompleted()","a6ca54bd":"lawEnforcementRole()","a6cb4654":"catchYou(address,uint256,uint256)","a6cb9e64":"scheduleCall(address,bytes,bytes)","a6cbcdd5":"numSignatures(bytes4)","a6cc0428":"withdrawCryptoCurrencyNetworkTokens(address)","a6cd5ba3":"MaxMasternodesAllowedChanged(uint8)","a6cd8c68":"Match_Maker()","a6ce25b2":"In(uint256)","a6ce69a2":"changeSupply()","a6ce8c29":"HandsOnToken(uint256,string,uint8,string)","a6cea881":"KayiToken()","a6ceaeb8":"getSoldTokens()","a6ceb1f3":"sendAirdrop(address[],uint256[])","a6cfaf2e":"MMC(uint256,string,string)","a6cfb7a3":"getBack(uint256)","a6cfbb7f":"revenueBalance()","a6d00693":"getMeshPointByCreator(int256)","a6d150e0":"updateWhitelists(address[],bool[])","a6d15124":"coinsLeftInTier()","a6d15963":"createChannel(address,uint192)","a6d23e10":"payments()","a6d2bff6":"getTeamTokens()","a6d34fa8":"JackpotPayoff(uint256,uint256,address)","a6d40d39":"unlockFounder(uint256)","a6d49dca":"emitTransferEvent(address,address,uint256)","a6d4b5c2":"getGroupResult(uint256)","a6d4e9da":"tokensByTx(uint8,string)","a6d544e9":"sumHardCapPreICO1()","a6d6d046":"LetsfairToken()","a6d72407":"interface()","a6d7d72e":"addTwinAddress(address)","a6d87f7d":"myReferralDividends()","a6d930bb":"FundCrowdsale()","a6d93a9a":"_sell(uint8,bytes6,uint32,uint32)","a6d958c6":"getLastInput()","a6d96af6":"_createCompany(bytes32,bytes32)","a6da1e7d":"depositAndLock(address,uint256,uint256)","a6da3761":"StoneumToken()","a6da467c":"buyCozyAffiliated(uint256,uint256,bool,address,address)","a6da54a3":"validCoordinate(uint256,uint256)","a6dacdd7":"right59(uint256)","a6dc0173":"BRFCrowdsale(uint256[3],uint256[3],uint256[3],uint256[3],address,uint256,uint256,address,uint256,address)","a6dc15bd":"PriceChanged(uint256)","a6dc1ada":"setMaxStage3AllocationPerInvestor(uint256)","a6dc6771":"third()","a6dc84f0":"balanceOfFrozen(address)","a6dcb12d":"candyTotalSupply()","a6dcc834":"getUserInventory(address,address)","a6dd06e1":"getPOOL_edit_34()","a6ddcc96":"FillBuyOrder(address,address,uint256,uint256,uint256,uint256,uint256)","a6ddce13":"setDisable(address,bool)","a6de42c8":"AuthorizedAddresses()","a6dea55e":"sendEthToAddress(address,address,uint256)","a6ded200":"redeem_funds(address,uint256,uint256,bytes32)","a6defd45":"ZeroHooStandardToken(uint256,string,uint8,string)","a6df0344":"REF_CREDITS_PER_AXIE()","a6df33a2":"creationInvestmentSupply()","a6df6c30":"minCWCsPerReturnMoreThan()","a6e0264a":"_checkMyVesting(address)","a6e158f8":"redeemTokens(uint256)","a6e16ba2":"testThrowsRetractLatestRevisionNotOwner()","a6e1bc7c":"IndoCrypt()","a6e26e96":"batlordAddress()","a6e2eab1":"recycleAfterEnd()","a6e315ff":"addExemptionAddress(address)","a6e3289d":"addNextMemberPayment(address,uint256,uint256)","a6e3fcf6":"setBaseTokensSold(uint256)","a6e4002e":"DividendManager(address)","a6e497b6":"getUserContractAddress(address)","a6e4ae01":"gcp(uint256)","a6e5291f":"UniversalGiftToken()","a6e5303a":"SLKToken()","a6e53b99":"PHASE1_ACCOUNT_TOKENS_MAX()","a6e5f2f5":"Show_Address_for_option_C()","a6e7469c":"getSendersHash(address)","a6e77af1":"setEntryPrice(uint256)","a6e7f409":"STATE_OWNED()","a6e81e7c":"refundWei(address,uint256)","a6e826e8":"startsecurities()","a6e8a859":"target2()","a6e9e95f":"setCoinAllowance(address,address,uint256)","a6ea7ad2":"dexTestTransfer(address,address,uint256)","a6eaab99":"DGCASH()","a6ebbe5a":"NewDeposit(uint256,uint256,address)","a6ec01f7":"clearPendingWithdrawal(address)","a6ec0708":"setCompte_28(string)","a6ec3022":"getCurrentYearRemainToken(uint16)","a6ecfff8":"is_btc()","a6ed563e":"getBytes32(bytes32)","a6ee5eed":"changeFinishPreSale(uint256)","a6ee6fd9":"max_schrems_addr()","a6eea7f3":"liquidationPeriod()","a6effaed":"DetailedERC20(string,string,uint8)","a6f07a5c":"bigbomMultiSigWallet()","a6f0cba6":"DarioAdministrator()","a6f0e577":"isLeapYear(uint16)","a6f1c939":"getPick(uint256)","a6f1fd51":"addDeposit(uint256)","a6f20445":"LogCancelReservation(address,uint256)","a6f257cc":"AgroTechFarmToken()","a6f2ae3a":"buy()","a6f2e80d":"lockFunds(address)","a6f2fd5c":"disable(bool)","a6f48c90":"freeCount()","a6f4ab2e":"setStalePeriod(uint256)","a6f55282":"addNacToNLF(uint256)","a6f57199":"CrowdsaleExtended(uint256)","a6f5a22b":"openShop()","a6f6a8a6":"_setPrices(uint256)","a6f6d8bb":"getObligation(bytes32,uint64)","a6f70594":"SpoutCrowdsale(address,uint256,uint256,address)","a6f7257a":"getSigns(uint256)","a6f7541c":"maroonToken()","a6f81668":"gameInfo(uint256)","a6f87bc6":"WumingToken(address,address)","a6f935f6":"exporterAcceptedIBankDraft()","a6f9885c":"MAX_LENGTH()","a6f99922":"EcologicalShield()","a6f9dae1":"changeOwner(address)","a6fb08ae":"contractWithdraw(uint256)","a6fb475f":"transferFrom(address,address,uint16[])","a6fbf3d2":"getInt(bytes32,bytes32)","a6fc2823":"continueIco()","a6fc5c03":"getCode(uint256)","a6fd0085":"sub(uint128,uint128)","a6fd2487":"recordName()","a6fd96b0":"MultiService(address,address[])","a6fda231":"ICO_RATE3()","a6fdedef":"aimeIncreasePerTrip()","a6fe178c":"getRegisteredExchanges()","a6fe7a28":"removeService(address,uint32)","a6fea6f4":"registerVendor(address)","a6ff20a3":"addVehicle(uint256,uint256,bytes32,bytes32,uint256,uint256)","a6ff85e2":"ReceiveDonate(address,uint256)","a6ffefae":"balancesListNumberMap(address)","a701229f":"ChangedOwner(address)","a7016023":"setOwnership(address)","a7021bc5":"executorAlive()","a70284be":"soldBeercoins()","a702be14":"feedSecondaryPot(uint256)","a703078c":"sortAuction(uint256[])","a7030a53":"extractAndStoreBitcoinAddresses(bytes32,uint256,bytes,bytes)","a703c751":"batchWhiteListInvestors(address[])","a705245e":"setReserveVault(address)","a70616de":"platformWithdrawalRecipient()","a7068d66":"addDelegate(address,bytes32,address,uint256)","a706a2e2":"requestUnlock(bytes32,address,bytes4,address)","a706d26e":"DragonTreasureToken(address,address,address)","a7070373":"setAllowance(address,address,address,uint256)","a707300f":"addAcceptedContribution(address,uint256,uint256)","a7074a82":"getCrowdsaleStatus(address,bytes32)","a707ce55":"changePass(bytes32)","a707fc81":"payback(uint64,address[])","a708142b":"addressSCComplianceService()","a7084516":"VictoryX(uint256,string,uint8,string)","a7086536":"withdrawOfferForCollectible(uint256,uint256)","a7096ac8":"addLogicVersion(uint256,address)","a70a92f7":"setLiquid0(bool)","a70a9ad7":"switchDeity(address)","a70b015d":"stageICO()","a70b21a3":"ReceiverPays()","a70beb13":"processSellOrder(uint256,uint256)","a70c41b4":"getTransferFromPreSignedHash(address,address,address,uint256,uint256,uint256)","a70ce015":"safeGetPercent(uint256,uint256)","a70d7006":"StinkyLinky()","a70e82d4":"changeFreeUntilDate(uint256)","a70f101c":"useEmergencyCode(uint256)","a70f84c3":"registerName(address,bytes32,uint256)","a70fc3ba":"setCap(uint256,string)","a70fc680":"fundraising()","a71168e3":"setTrainingScienceContract(address)","a7120433":"setItemContract(address)","a7134993":"lifeD(uint256)","a7134f73":"acquire()","a713a3f7":"loggedTotalSupply(uint256)","a7154d22":"cancel(address,uint32)","a7157c72":"withdrawToTeamStep2(uint256)","a715bf33":"ICO_PRICE()","a715df58":"setUnownedName(uint256,string)","a715ff59":"EtherandomProxy()","a716144a":"getStack(bytes32)","a7177ebf":"getSpellAbilityCost(uint8)","a718309f":"CryptoCurrencyExchange()","a7188b4e":"setEditModeBool(bool)","a718d11b":"addWhiteList(address,bool)","a718e288":"Robet(uint256,string,string)","a718e774":"closeWeeklyInvest()","a718f4b3":"searchJobs(address,uint256,uint256[],uint256[],uint8[][4],uint8,uint256[],uint256[],uint256)","a7194e2a":"returnTokensListOfAddresses()","a71962c2":"GAME_STARTED()","a719804d":"Spank(string,string,uint8,uint256,uint256)","a71a3dde":"DEFAULT_LOCK_COST_PER_HOUR()","a71acabc":"newSection(bytes32,bytes32,bytes32,uint256)","a71aec73":"isTradable(uint16)","a71b4c26":"auctionSumGwei()","a71bd1cd":"getCurrentDay(uint256,uint256)","a71be2c0":"Clip()","a71d6f9f":"setTRCExchangeRate(uint256)","a71d8181":"createCeleb(string,uint256)","a71e12e5":"JoinGameAsPlayer(uint8,uint256,uint8)","a71e46d3":"maxRecordID()","a71ee0c6":"changetradestatus(bool)","a71ef84d":"getVotingWinner(address)","a71f94c8":"scheduleSetUInt(address,uint256,uint256)","a71fa796":"addResearch(address,uint256)","a720cbb8":"create(address,address,address,string,string,address,uint256,uint256)","a720e0a8":"ebyteToken()","a720faa9":"maxPreICOSupply()","a721c06c":"LENTToken()","a721d9d9":"EmiratesCoin()","a721ebe8":"numberSyndicateMembers()","a72299dd":"MetadollarShare()","a7232aae":"setGPSMinEth(uint256)","a723761a":"investEtherForDID()","a723cda8":"AQUAOIN()","a7240d45":"updateTransaction(bytes32,uint256,address,uint256,address,uint256,bytes32,bytes32,bytes,bytes)","a72460d1":"getProviderEndpoints(address)","a724e54c":"newCollectible(uint256,string,uint256,uint256,uint256,string,uint256,string)","a724f68a":"CratesOpened(address,uint8)","a7256621":"addInt(uint256,int256)","a725c4a4":"StrategicPartners(address,uint256)","a725fa1f":"CpublicgoldToken(address)","a7261f79":"isPayableEnabledForAll()","a72670b8":"getReportingWindowByTimestamp(uint256)","a726be9a":"get_token_data(uint256)","a727390d":"GetDomainInfo(string)","a727632f":"Date_Finished()","a7281bbf":"CollectTaxes(uint256)","a728fa93":"getMyCraigGrant()","a7292c74":"amountEthRaised()","a72a05f7":"getReceiversCount()","a72aa163":"setPropertyMode(uint16,bool,uint32)","a72b1444":"minimumSupport()","a72dc52e":"fixedExpUnsafe(uint256)","a72dc950":"StageOneEnable()","a72ec7a0":"TokenLiquidityPlatform()","a72f3dea":"removePVPContender(uint256)","a72f5aaa":"preDistribute(address,uint256)","a72ff7de":"buySmartContract()","a7304287":"godUnpause()","a731c4ec":"addUserTokenLocalBalance(address,uint256)","a731f31a":"getBoxes(address)","a7321096":"mainSaleBonus()","a7322d9d":"DURATION_SALESTAGELAST()","a7324134":"parseLoanOffering(address[11],uint256[10],uint32[4],bytes)","a732d6c4":"calculateAffiliate(uint256,uint256,uint256)","a732f9ac":"increasePlayersGooProduction(address,uint256)","a733800d":"Shipia()","a73381d5":"EYInnovationCoin()","a733e21d":"twice(address,uint256)","a733f702":"isValidSize(uint256)","a73467bd":"TestCitySnapshotInternal(address,uint256)","a73598fd":"tryFinalizeStage()","a73638a7":"selectGod(uint16)","a7365ea9":"Gealena()","a7368afb":"allocateTokens(address[],uint256[])","a7374b21":"sendFundsInternal(uint256,address,bytes)","a737ec3d":"GxAdmins(address)","a737ecc9":"getProfitToAddress(uint256,address)","a7384c1e":"eth2erc20()","a739013f":"buy(address,address,uint256,bool)","a7397d27":"xaurForGasLimit()","a73b60f4":"buttonClicks()","a73b9bcb":"FTFExchangeToken()","a73c0ba2":"play(uint256,uint16,uint8)","a73c52e7":"getLastPerUser(address)","a73c7140":"amountTotal()","a73d633c":"addWhitelist(address,address)","a73d907e":"inboxIsEmpty(address)","a73e01cb":"WPTokensBaskets(address,address,address,address,address)","a73e38ce":"generateICOcrowdsale(uint256)","a73e9837":"newEnterWallet(address)","a73ee331":"MAIN_HOLDER_ADDR()","a73f7f8a":"addRole(address,bytes32)","a73fc4cd":"get_pre_kyc_iconiq_bonus_denominator(address)","a7403160":"vestingsReleasedRemain(address)","a74035b5":"setEvabotContractAddress(address)","a740a194":"getGasToReport()","a740a6fa":"clearRAM()","a740cf90":"TGIF(address)","a740de43":"nameLocked()","a7419b51":"setAirLiftPrice(uint256)","a742a942":"create(address,bytes32,address,address[],address,bytes32)","a7432434":"refferalPreICOBonus(address)","a743a61f":"checkStudentsApply()","a743fa50":"beneficiaryFunded(address)","a744a633":"getWeeklyTransactionVolumeReceiving()","a745863b":"startRebuyTime()","a745953e":"buyStarInitial(uint256,string)","a745ec70":"bountyDistributorAddress()","a7467039":"sharesToManager(uint256)","a747007f":"AffiliateProgram(address)","a7483f74":"CATFreezer(address,address)","a74905db":"reportProfit(int256,address)","a74915cf":"getadd()","a7491b48":"votesByAddress(address)","a7497fa5":"tge()","a749870d":"etherValueAllowStale(uint256)","a749e97b":"_setPaymentSchedual(uint256,uint256,bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,bytes2)","a74a1831":"post(bytes32)","a74baaa4":"amountOfHolders()","a74e01cf":"unFreezeAllTransactions()","a74e493f":"pregenTokens(address,uint256,uint256)","a74ecb12":"setMasterAddress1(address)","a74f277a":"MaintenanceUpdate(bool)","a7502a3f":"totalTeamWithdrawSupply()","a7507df2":"loveUrl()","a75252ea":"sellToAddress(uint256,address)","a75261f2":"certbot()","a75274e9":"setMarkup(uint256,uint256)","a752c2c5":"UniversalSchemeMock()","a75343bf":"claimOwnership2()","a753d6f2":"CreateProposal(string,string,string,string,string,string,uint32,uint32)","a753fd08":"setWinNetworkFee(uint256)","a7542448":"addRef(bytes32,bytes32)","a75439d1":"minValuePre()","a755a47e":"triggerAllRefunds()","a7560bec":"EBITOKEN()","a7565888":"m_Paused()","a75688b2":"oldMillionEther()","a75761f1":"returnUint16(uint16)","a7577542":"addCrowdSaleTokens(address,uint256)","a757ac4b":"privatesaleAddress()","a757fc42":"buyTwo(uint256,uint256,uint256,uint256)","a758ac6a":"MaecenasCrowdsale()","a759822b":"performCalculations()","a75a1d6c":"claimRefundTokens(address,address)","a75a4e4a":"updateScoreAndBalance(uint256,uint256,address,address)","a75a9049":"setInitialOwner(address,uint256)","a75aef40":"SYCEarlyPurchase()","a75c6f65":"updatedCirculation(string)","a75c8546":"determineDiscountRate()","a75c981d":"totaltokensold()","a75d0042":"signedTransferCheck(address,address,address,uint256,uint256,uint256,bytes,address)","a75dd0d4":"AddPrivateKey(string,string)","a75df814":"knownAddress(address)","a75e2853":"transferForICO(address,uint256)","a75eb727":"updateExistingRaz(uint256,uint256,uint256,uint256,uint256)","a75fe8e1":"removeWallet(address)","a7603a86":"getDefaultValidityBond()","a76044a4":"binary()","a760d1d0":"setRateAgain()","a760e442":"setLosers(uint256)","a76188b9":"setRewardPercentages(uint256,uint256,uint256,uint256,uint256)","a7633064":"getRandomType(uint16)","a7638346":"setFinaliseTime()","a7638c4d":"disableStakingPeriod()","a764eb45":"setCurrentIssuanceData(address,uint256)","a7651147":"loyaltySupply()","a76594bf":"getPlayersCount()","a7668eba":"calcTokenCost()","a766f3d1":"storeStub(address,bytes32,bytes32)","a76769a5":"fillOrderWithEth()","a76774f5":"jackpotCompleted()","a7677ee3":"AslanToken()","a767d8be":"preIcoMaxCap()","a76a155e":"getBetsFromAddress(address)","a76bb04e":"setRewardPoolWallet(address)","a76d368a":"candyPowerToken()","a76d50ad":"multipleTransfer(address[],uint256,uint256)","a76dd676":"TIER3_PERCENT()","a76decce":"_createNFT(uint256[5],address,uint256)","a76ee2d8":"fillBuyOrder(address,address,uint256,uint256,uint256,uint256)","a76eeab2":"updateVitality(uint256,uint8)","a76f3543":"getUpgradePointer()","a76f43a0":"bancorDaiSmartTokenRelay()","a77078e7":"withdrawForOp(address)","a7721e0f":"multiplyTokensSend(address[],uint256[])","a7724b16":"bingo()","a7728589":"setMintAgent(address,address)","a7731150":"StoreFile(bytes32,string,string,string,string,string,uint256,bytes)","a7737b93":"NumberOfPart()","a77384c1":"setTotalShares(uint256)","a773d98a":"getAssetIDHash()","a7741827":"deleteAllUris()","a7743462":"setFounderTokenWallet(address)","a774f163":"adjustDefaultSpritePrice(uint256,uint256)","a775511a":"isMainsalePeriod()","a775b1c4":"NAORIS_TEAM_TOKENS()","a7760d79":"preICOendTime()","a77674a7":"buy_energy(address,uint32,uint32,uint64)","a7771ee3":"isVoter(address)","a7775bd7":"YDToken()","a777aa5d":"changeMaxTokenSell(uint256)","a777d0dc":"hello(string)","a777deca":"thirdRelease()","a777eca9":"MinerRewardChanged(uint256)","a77a8230":"allowence(address,address)","a77aa49e":"setIntValue(bytes32,int256)","a77adc23":"WaxToken()","a77ae839":"approveRewards(uint256)","a77b2e37":"Coin()","a77b4d8b":"setBaseCurrency(address,bool)","a77b6efb":"mintCoins(uint256)","a77beea1":"transfer(address,address,address,address[],uint256)","a77c1b08":"checkTransfer(address)","a77c61f2":"cobinhoodUserIDs(address)","a77ee38c":"promoTypeNum()","a77f7c8c":"whitelistMany(address[])","a78036b7":"clearDeposits(address,uint256)","a7807b84":"transferByRelatedToken(address,address,uint256)","a78082aa":"TokenSafe(address)","a78085ef":"lockMainSaleToken()","a780b2f3":"parseRate(string)","a7811732":"totalERC20Contracts(uint256)","a78118a4":"onlyDevs()","a781384e":"TrivialToken(string,string,uint256,uint256,address,address,uint256,uint256,uint256,bytes32)","a7819ad7":"_challengePart2(uint256,uint256,uint256)","a783a4f1":"get_hash(uint16)","a78488af":"startTokenRaffle(uint256,address,uint256,bool)","a78488e1":"WSTO()","a784d969":"setAssetsCertified(uint256)","a784ef22":"_calculateScore(uint256,uint256,uint256,uint256)","a7859131":"m_initialSettingsSet()","a785b96a":"TDEStartDate()","a786c1d2":"BONUS_DAY1_DURATION()","a7878831":"splitTokens()","a78810f8":"subscribeMe(uint8,bytes32)","a788aa07":"test_threeValidEqUint(int256)","a789e29c":"getContributorData(address)","a78a43c1":"getAllTeamScores()","a78a651a":"processContribution(address)","a78adf57":"UserAddressRegistry()","a78adfec":"setButtonParams(uint256,uint256,uint32,uint32)","a78b3d96":"addSubOwner(address,address)","a78bcf6e":"changeBankroll(address)","a78c5476":"SaleStarted(uint256)","a78c81ea":"changInviteAmountLimit(uint256)","a78cb567":"getCosignerFee(uint256)","a78cdfed":"gana()","a78d4316":"_near(uint256)","a78db39c":"blockedUntil()","a78deefa":"isGameEnd()","a78e635c":"XToken()","a78e887c":"calculatePurchaseReturn(uint256,uint256,uint16,uint256)","a78f0489":"secondTierDiscountUpperLimitEther()","a78f16ba":"setWhitelistedStatusInternal(address,address,uint256)","a79094b7":"changePolyRegisterationFee(uint256)","a7909e47":"DAppReady()","a791c665":"WojakCoin()","a791da46":"buyXwithdrawForContract(address,uint256,uint256)","a7932d20":"marketToken2019()","a7944579":"sit()","a79726b7":"tokenSpin(uint256)","a7972a80":"MoviePass(string,string,uint8,uint256)","a7977ffc":"isWhiteListedAndAffiliate(address)","a7985ae4":"SNAILMASTER_INCREASE()","a7987b58":"LendroidSupportToken()","a799464c":"isMyInfra(uint256)","a7996adc":"_safePaymentActionAtIco(uint256,address,uint256)","a799de7e":"anotherTransferTo(address,uint256)","a79a3c30":"teamAlloacting()","a79a3cee":"isConfirmed()","a79a416d":"SetCommissionRate(uint256)","a79ac3be":"ReleaseTokenForReserveFund()","a79b2752":"validate(address[4],address,uint256[12],uint256,bytes,uint256)","a79c7faf":"test_threeInvalidEqBytes()","a79ca634":"_setSubnodeOwner(bytes32,address)","a79dad23":"GetBetNums(uint256)","a79deb4f":"acceptTradeDeal()","a79ec95a":"oneEtherIsHowMuchFST()","a79f26dc":"force()","a79f4773":"buy_ETH(uint256,bytes8)","a79f7412":"withdrawCoinExt(uint256)","a79fdbb4":"presalePaused()","a7a066b7":"AxtrustICO(uint256)","a7a0d537":"something()","a7a1019d":"tixPresale()","a7a1e0a7":"auditNTVUText(uint8,uint8,string)","a7a1ed72":"pass()","a7a260cf":"TokenDeployed(uint256)","a7a2720e":"processFunding(address,uint256)","a7a38f0b":"history(uint256)","a7a39daa":"getBrickIdsByBuilder(address)","a7a3ba54":"SponsorMusic(uint256,uint256,address)","a7a44eba":"getFirstUnionIds(bytes32)","a7a5e00b":"updateCustomer(address)","a7a604b2":"mintUptoCap()","a7a60580":"MeteorToken()","a7a62aee":"init(address,uint256,address,string,string)","a7a7be1a":"newWriteAddr()","a7a8add2":"setSaleAgentContract(address,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","a7a957ff":"getSaleDayNow()","a7aac32d":"withdrawAdvisorTokens()","a7aad3db":"voterReward(address,uint256,uint256)","a7ab6961":"withdrawalDelay()","a7abb8cc":"BM_MasterClass_Reserved()","a7abc124":"activate(bool,bool)","a7ace55d":"incrementDivisor()","a7ae9756":"startNewStakingInterval(uint256,uint256)","a7af0b99":"Nerdearla()","a7b0793b":"setAdvisorFundWallet(address,address,uint256)","a7b07acc":"AssetSplit(address,address,address,address)","a7b2042f":"phasePublicSale3_From()","a7b2bfc7":"multyTransfer(address[],uint256[])","a7b2d313":"LogAnswerReveal(bytes32,address,bytes32,bytes32,uint256,uint256)","a7b2d4cb":"remove(int256,address)","a7b2fc00":"updateTokenNameSymbolAddress(string,string,address)","a7b314ac":"stepProfit()","a7b3a6fc":"Mine(address,uint256,uint40)","a7b4b60f":"erc223Fallback(address,uint256,bytes)","a7b69ed9":"PostLicense()","a7b71dca":"getJobValue(bytes16,address,address,uint256,uint256)","a7b7eefb":"JustmakeToken()","a7b7f1d4":"getLatestUnitRaffleInfo()","a7b83225":"AgriChainSeal()","a7b86824":"lockup(address,uint256)","a7b88506":"canRead(address,bytes32)","a7b8c868":"startCrowdsaleTime()","a7b91780":"getTokensSale()","a7b94972":"newBen(address)","a7ba0cb5":"createChatRoom(bytes32)","a7ba44c3":"isFinalizerSane()","a7ba9fb1":"epsilon()","a7bb1cf4":"_setRarityBonusValue20(uint256)","a7bb5803":"splitSignature(bytes)","a7bb959a":"Apen()","a7bc2efd":"transferGroupIntertrade(uint256,address)","a7bc3cb9":"SafeLocked(uint256)","a7bc8c46":"howManyVoters(bytes32)","a7bd4791":"MakeItWeinSec()","a7bda7e3":"extractNameFromDataET(bytes)","a7bdf16e":"isValidBump(uint16[3],uint16[3])","a7be2648":"unTrackToken(address,uint16)","a7be85c6":"AUTHOR()","a7bf1b6c":"purchase(uint256,uint256,address,address)","a7bf1cbf":"unfreezeTransfersSince(string)","a7bf8921":"freezeContract(bool,uint8[],bytes32[],bytes32[])","a7c19841":"preSaleInit()","a7c1a708":"LogGameStarted(uint256)","a7c1a75b":"maxAuditDuration()","a7c1abf1":"decodeMessage(string)","a7c1e629":"cancelTransfer(address)","a7c25c5a":"setMileagePointPrice(uint256)","a7c368c0":"pushBuyerList(address)","a7c3ce60":"distributeRegisterFee(uint256,uint256,bytes32,uint8)","a7c3d71b":"icoStartTime()","a7c41e28":"zennitToken()","a7c4abdb":"calculateTokenAmount(uint256,uint256,uint256)","a7c5052e":"buildDSTokenRegistry()","a7c591c4":"setBest(uint8)","a7c5c2a2":"BirthFee()","a7c6c83a":"getMystr()","a7c6f483":"exchangeRateAuth()","a7c742c9":"CommissionEarnedEvent(address,uint256)","a7c7d2a0":"airdropValue()","a7c7e2a0":"assignOwner(address,address)","a7c7fdeb":"transferTokensToOwner()","a7c83514":"inflationChange()","a7c8e68a":"sealManualMigration(bool)","a7c961d5":"bonussale_Cap()","a7c98748":"test3_searchNext()","a7c99f2c":"changeCompetitionAddress(address)","a7c9d92f":"HammBones()","a7ca3010":"getWithdrawTransactionCount(bool,bool)","a7cac846":"weights(address)","a7cadc50":"Dagelan()","a7cb6edc":"tokenRestriction(address,bool)","a7cbe06f":"MaxFunds(address,uint256,uint256)","a7cc440e":"getCityResourceRichness(uint256)","a7cc90e9":"calculateCounters(uint256,uint256,uint256,uint256)","a7cd21ea":"transferPrivilege(string,address)","a7cd674e":"whitelist_enable()","a7cdc2ad":"getAddressExist(address)","a7cebd4d":"createActivity(uint16,uint16,uint128,uint64,uint64)","a7cec1d2":"DataStorage()","a7cf7edd":"mimul(uint64,uint64)","a7cfe365":"addAuction(uint40,uint256)","a7d0b6ce":"payoutForResult(uint256)","a7d0c490":"keybuy(uint256)","a7d0f8af":"callStoWithBto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","a7d2b73f":"SharkProxy()","a7d2d2ab":"AngelCoin()","a7d30400":"window1TokenExchangeRate()","a7d4549c":"test(uint8,bytes32,bytes32,address,address)","a7d4bbe6":"modexp(uint256,uint256,uint256)","a7d4e89d":"migrationOperator()","a7d512d6":"getCertificateInfoByNo(address,uint8)","a7d55b76":"tryDismissRoom(uint256)","a7d5d4fa":"approveAddToken()","a7d68896":"updateCap(uint256)","a7d77305":"chargeMonthlyRate(bytes32,address)","a7d8287d":"MyFreezeContract(address)","a7d82b00":"setGoldCertVerifier(string)","a7d89168":"getLockedAmount(address,address)","a7da611f":"commission_mom()","a7da74f8":"addQuoter(address)","a7daf6dd":"eligibleForDividence(address)","a7dbb402":"changeAddress(string,address)","a7dbfcaa":"setCostOfToken(uint256)","a7dc0aee":"test_threeValidEqString()","a7dd7a59":"unchainedMultisigVersionMinor()","a7dd7e37":"distrust()","a7de83e6":"generate(address,address)","a7de9c63":"quantityFactor()","a7dea7e4":"getMyPastLosses(address)","a7dee615":"_NewListingWhitelisted(bytes32)","a7dfc420":"investorAmountTokensToBuy(address)","a7dfc874":"unregister(bytes,address,uint256,bytes)","a7e03dcb":"mintPerBlock()","a7e1a8ee":"setAttributeType(uint256,string)","a7e1b516":"unban_user(address)","a7e1c4ac":"YunbeiToken(uint256,string,string)","a7e21e80":"hold(address)","a7e25683":"testShortOutput()","a7e2cca9":"setFinished(bool)","a7e328d4":"setSomeValues()","a7e33a0c":"sendChatMessage(string)","a7e350f7":"payOutGovernors()","a7e45699":"buyWildcardToken()","a7e47920":"createItems(uint256[],address[])","a7e48375":"MikadoToken()","a7e53987":"EthCapInWei()","a7e5a338":"HIDERA(uint256,string,string,uint256)","a7e5cb3e":"getWhoBet(address,uint256,uint256)","a7e5f1bc":"LogN_fnc(address,bytes32,uint256,string,bytes,uint256,bytes1,uint256,uint256)","a7e5f3c5":"likeBlock(uint256)","a7e74377":"_preValidateTransaction(address,uint256)","a7e74ab7":"setMx(bytes32,address)","a7e7d2f4":"BBXCoin()","a7e81d22":"lastBlock_f5Hash_uint256()","a7e86daa":"executeBidFor(address,uint256,uint256,uint256)","a7e93e87":"retractLatestRevision(bytes20)","a7e94542":"approve(address,uint32)","a7ea48cf":"CoinBroToken()","a7ead565":"FiO()","a7eb3848":"transferRewardWithoutFee(address,uint256)","a7eb685b":"mintFeeTokens(uint256)","a7eb891f":"isClientPaidUp(address)","a7ebc5bd":"privilegedAccountStatus(address)","a7ec619f":"getCurrentStageDiscount()","a7ecce5f":"removeQuitAccount(address)","a7ecd0ad":"getSpecialAddresses()","a7ee323e":"VULCAN_PROMETHEUS_FTL_SPEED()","a7eea700":"sale2Started()","a7eeea37":"NewContributor(uint256)","a7ef4329":"getHelloWorld()","a7f07011":"tradeExecutor()","a7f0b3de":"genesis()","a7f17bd5":"Bodcoin()","a7f18b5a":"setPOOL_edit_14(string)","a7f1b77a":"addReferralDeposit(address,uint256)","a7f2cc54":"feeCalculated()","a7f2f4e2":"getMembershipStatus(address)","a7f31e0a":"getCelda(uint256)","a7f32edd":"OfflineCastleSold(uint256,address,uint256)","a7f365ae":"setLockoutPeriod(uint256)","a7f36c2e":"setProviderPriv(uint256,bool)","a7f39d8a":"tokenSaleWeiGoal()","a7f3e70f":"setSaleTimes(uint256,uint256)","a7f43779":"remove()","a7f43acd":"reserveContract()","a7f49e1d":"maximumBuyBackAmountInCents()","a7f58c24":"computeInitialPrice(uint8)","a7f5eccc":"previousReturnValue()","a7f7417d":"preICOFreeBonusPercent()","a7f81863":"thirty_wallet()","a7f86c63":"_removeRoomNight(address,uint256)","a7f879ea":"teleportToken()","a7f8a53c":"ownerSetControllerAddress(address)","a7f8fbd4":"cancel_contract()","a7f95a92":"HardcodedCrowdsale(address)","a7f9801b":"TakedFunds()","a7f9df38":"investWithBitcoin(address,uint256)","a7f9fe72":"getAllRecords()","a7fab81a":"impl_redeem(address,uint256)","a7fb95f6":"changeTeamName(uint256,string)","a7fbe7ad":"safeLastDate()","a7fbed9e":"getCurrentPhaseIndex()","a7fc7a07":"addController(address)","a7fca953":"getSrcQty(address,address,uint256,uint256)","a7fdb4f5":"finishedSale()","a7ff0a4e":"TransferTokens()","a7ff2373":"multiSendFrom(address,address[],uint256[])","a7ff7a40":"MANACrowdsale()","a7ffb2db":"getMaximumRound(uint256)","a7ffe560":"batchSpawnAsset(address,uint256[],uint256[],uint256)","a8006dfe":"exec_admin()","a801ea25":"launchLotto()","a801fd63":"setNewValue()","a802257d":"addr_Saddlery()","a8026912":"setSource(address)","a802afa1":"minOfArray(uint256[])","a80325bd":"toB32(bytes)","a804903a":"FOUNDER2()","a80498f1":"AdvancedDeposit(bytes32,uint256)","a804cc7d":"setUser(address,address,string,string,bool,bool,bool)","a804da18":"cliffReleasePercentage()","a804fcb4":"COMMUNITY_PERCENT()","a805bfef":"addInvestors(address[],uint256[],uint256[],address[])","a8074b55":"bundlingDenied()","a807598e":"incluirUsuario(address)","a8077951":"updateLastBuyKeysPIDs(uint256,uint256)","a807ea0f":"newMostInviteTimes_()","a8083b74":"setContributionSettings(uint256,uint256,uint256)","a8084938":"CryptoCupToken()","a80955b1":"setFoundersTokenAllocation(uint256)","a80a60fb":"saleFirstPresaleEndBlock()","a80a9e40":"setActive(address,address,uint256)","a80acfd3":"DisableSelling()","a80aee59":"isActiveDelegate()","a80bf3e6":"tokenLocker()","a80bffb6":"tokensOfSell()","a80c609e":"tokenImbalanceData(address,uint256)","a80c89d2":"RollbackedContract(uint256,address,address)","a80d2fb4":"getPeerMessageCount(address,address)","a80d4e9a":"EtherAuction(uint256)","a80da0f1":"SpursvsWarriors419()","a80db9fb":"nextStealTimestamp()","a80dca57":"recharge(string)","a80de5ea":"lottery(uint8)","a80e3659":"testDisputedReadValid()","a80e6c01":"getClassPlayers(uint256,uint256,uint256)","a80f54ca":"transferToExchange(address,uint256)","a80f9e2d":"RankingBallGoldCustomToken(address)","a80fe377":"Goahead()","a8103621":"dividendsPayed()","a810385e":"setBla(string)","a8103c80":"SSHToken(uint256,string,uint8,string)","a81077a7":"usersRegistered()","a810a54c":"withdraw(bool)","a810bc13":"ETCharPresale_v2(address)","a8132a46":"hardCapInToken()","a8140c95":"OceanScapeCoin(uint256,string,string)","a8150e72":"removeOrderOfVendor(address,uint256)","a8154e17":"teamUnfreezeDate()","a815a85d":"getItemCounts()","a815ff15":"set(string,address)","a8164a84":"ThxMsg(address,string)","a816899e":"icoBalances(address)","a817163b":"BusTokenLock(address,address)","a817ccac":"threeParams()","a817d2de":"extract20(bytes32)","a817f668":"findPlayer(address)","a8181851":"dapCarToken()","a8182cd3":"serverCancelActiveGame(address,uint256)","a818a222":"TokenAdded(address,uint256,uint256)","a819515d":"updateParentTotalTheoreticalSupply()","a819819b":"sweepDeityCommission(uint256)","a819c36c":"ClapToken()","a81a3e4d":"hasOpenApplication(address)","a81afa57":"sellSpecialTokens(address,uint256)","a81c3bdf":"ethFundDeposit()","a81c804e":"addToWhitelistBulk(address[])","a81d18d7":"setTokenMeta(uint256[],uint256[],uint256[])","a81d3424":"getFrozenToken(address)","a81daf29":"ETHernitymining(address)","a81dfde0":"CBT()","a8201894":"getCurrAuctionPriceAuctionID(uint256)","a820b44d":"iterateStart()","a820d02e":"MarketingDevelopmentAmount()","a8222adf":"sellerNumOpenDeals()","a82375d1":"ToGoConcert(uint256,string,string)","a8239d0b":"getPrice(string,address)","a8243ff4":"getactlen()","a824bd9a":"autoSell(address,uint256)","a824e636":"walletSend(address,uint256,address)","a82524b2":"presaleStartTime()","a8267482":"msp()","a826b422":"addCbAddress(address,bytes1,address,bytes)","a826ee78":"submitResult(uint256,uint256[])","a8276d97":"SetcashOutTime(uint256)","a827ef0a":"EvLoveItemAdded(bytes32,address,uint256,uint256,string,string)","a828251e":"voteProposal(bytes32,address,address,uint256,bytes32,string,bytes)","a8287f79":"addProduct(address,uint256,string,string,string)","a828eec5":"pureFn(uint256)","a828f441":"redeemFromEscrow(uint64)","a82970d7":"SetWorldData(uint256,uint256,uint256,uint256,uint256)","a829c3d1":"requestArbitration(bytes32,uint256)","a829d8ec":"VUP_TOKEN_SUPPLY_TIER4()","a82aa270":"updatePick(uint256,uint256)","a82b3640":"getDrawP()","a82ba2d5":"renounceKeeper()","a82cb091":"BuyDoubler()","a82d1d1a":"TwinkleToken()","a82d4ac1":"Crowdfunding(address,address,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","a82e0dcc":"theCyberMessage(string)","a82e1374":"changePublicallocation(uint256)","a82e3179":"jingleContract()","a82fc94f":"issueTokensPresale(address[])","a8308665":"add5NewTraits(string,string,string,string,string,bool)","a8311aa8":"getParties()","a831751d":"addPartOwner(address)","a8319481":"cancelRole(address,address)","a831f0bb":"compareStringValue(bytes32,bytes32,bytes1)","a8321459":"topUpAvailable()","a8324a3f":"batchRestoreWebGift(address[])","a832d7df":"newSell(uint32,address,uint256)","a83332d5":"TokeniVOX(uint256,string,string)","a833386b":"toBytes32()","a833c7ab":"incentivisationAllocation()","a83467a1":"dividendcommission()","a8347f6a":"maxCrowdsaleCap()","a834c43d":"buyAccess(string)","a83500e0":"check_redeemed(string)","a8351c03":"pauseCrowdsale()","a83627de":"updatePeriod()","a8366fef":"TOKEN_STANDARD_ERC20()","a8370492":"setTrFee(uint256)","a8372511":"STCoin(uint256,string,string)","a837aeb2":"AdminStartDraw(string,bytes32)","a837c35e":"createAmountFromEXORForAddress(uint256,address,address)","a8385231":"sendTokensToAddress(uint256,address)","a839fc56":"setGoalAchieved(bool)","a83b1e21":"reply(string,bytes32)","a83cf7fe":"RefundVault(address)","a83e1d10":"getUserQuoteIds(address)","a83f9429":"extend1Week()","a840617f":"LogKycRefused(address,uint256)","a840d2a8":"GTO()","a8418d01":"BECToken(uint256,string,string)","a841da4b":"lockJackpots()","a841f1eb":"handleFunds(address,address,uint256)","a842375e":"refundToken(address)","a842f0f2":"upgradableContractAddress()","a843c51f":"transferContractOwnership(address)","a843c97f":"attack(uint256,uint256,uint256[])","a844545d":"completeMinting()","a84524a4":"getDetailedPollResults(uint256,uint256)","a84694c8":"permissionIndexOf(uint8,address)","a8469ce9":"MINING_REWARD()","a846c2fd":"payback(uint256)","a846fa37":"waitQuery()","a8474a30":"_computeRunes(uint256)","a847a1b3":"StarbasePresaleWallet(address[],uint256,uint256)","a847a71c":"isOnTrading(uint64)","a8484938":"doApprove(address,uint256)","a848e2ec":"tokenSupportSoftLimit()","a8492f46":"pickTicket(bytes4)","a84950df":"calculateTimeBonuses(uint256)","a8496426":"getOrderId()","a849cef8":"minDeposits(uint256)","a84a70aa":"lockedTime(uint256)","a84b9de0":"dequeueDouble()","a84c5330":"createNewRevision(bytes20,bytes)","a84c6362":"ICO_CAP4()","a84d073a":"interfaceMintTokens(address,uint256)","a84dd3a6":"teamWallet_3()","a84e5f40":"CRYPTONEREUM()","a84eb999":"removeAddresses(address[])","a84ebb58":"setVM(bytes32[10],uint256[4])","a84f3e5a":"overdraftUnvested()","a84f763b":"TokenTransferred(uint256,address,address)","a8514113":"_emitCategoryEvaluated(address,address,uint8,uint256,uint256)","a85165e0":"checkSubPrice(bytes32)","a851e2f6":"LogCreateNET(address,uint256)","a852995d":"bonus1StartETH()","a852d5ba":"emergency_withdraw(address)","a853d2cd":"getUserByUsername(bytes20)","a8542f66":"ANY()","a855d4ce":"uintStorage(bytes32)","a8565523":"AquaPay(string,uint256,uint8,string)","a8567a1c":"bidderUpdateBid()","a85688d2":"_rewardPoS()","a856b9c2":"lastRandom()","a85717d3":"open(bool)","a8575102":"getDnasCount()","a8590135":"issuanceEnabled()","a85923aa":"ZibPay()","a859a092":"minToken()","a859eb81":"BONUS_TIER_4_LIMIT()","a859fffe":"SweDexDividends()","a85a726d":"NewUser()","a85aba19":"setPreURI(string)","a85ade82":"FOUNDERS_VESTING_DURATION()","a85adeab":"endTimestamp()","a85b13b9":"claimBitNauticTokens()","a85c06b7":"_packRaceData(uint256,uint256,uint256,uint256)","a85d11b3":"verifyCode(bytes32,uint256)","a85d3179":"getMiningRate(address)","a85e07e2":"getMesa(uint256,uint256,uint256)","a85e59e4":"transferFrom(bytes,address,address,uint256)","a85ef579":"appendDarknode(address,address,uint256,bytes,uint256,uint256)","a85f3761":"repayments(uint256)","a85f5c2e":"tradingData()","a85ffd1a":"setAutoDistributionViaETHContributions(bool,bool)","a85ffe4f":"manualSell(address,uint256)","a860bfa2":"BRCToken()","a860d119":"communityTokenHolder()","a861baea":"presale_address()","a861e16f":"setEmployeeSalary(address,uint256,uint256)","a861f99a":"getClientPaidUpTo(address)","a8627c15":"LINICOIN()","a863f595":"Btczocker(uint256,string,uint8,string)","a86416e2":"CROWDSALE_PRICE()","a8644cd5":"contract_eth_value_bonus()","a86477ad":"offeringEnabled()","a8648aad":"TokenFunctions()","a8659216":"setInitialLockinDays(uint256)","a8660a78":"vestingStartTime()","a866665a":"ConsoToken()","a8670711":"isCloseSale()","a8681169":"withdrawWhiteList(uint256)","a868378b":"returnOfIncome(address,uint256)","a8683df7":"TokenMyUnicoin(uint256,string,string)","a868cd6f":"LogPolicyManualPayout(uint256,bytes32)","a868ec85":"setName(uint256,uint256)","a86abb3d":"allFilmsInfo(uint256)","a86b73f0":"toByte(uint8)","a86bc181":"EXPECTED_END()","a86c938b":"balanceOf(bytes8,address)","a86e3576":"symbol(address)","a86ed5e4":"thirdMaxAmount()","a86ee746":"restoreCutieToAddress(uint40,address)","a86f7212":"_allocatePlayerTokensTo(address,uint256)","a870a0a5":"getChannelClosingSettler(bytes32)","a870be8a":"setVendingStepValues(uint256,uint256,uint256)","a870ddc2":"moveTokensFromSaleToCirculating(address,uint256)","a871da91":"SHORT()","a871ffdc":"Getsafe(uint256)","a87253c7":"getlastuser()","a873b155":"GetMinimumBet()","a8740a71":"getCreditLedger(uint256)","a8754caa":"purchaserMapping(address)","a8756337":"getCurrentValidatorsLengthWithoutMoC()","a87595ce":"buynowPrice()","a875b2ed":"setIsBatch(bool)","a87607af":"Show_address_for_option_B()","a8762854":"numberInRaffle()","a8766017":"ARXToken()","a876a8a0":"_round()","a877b557":"TransferMinimumFeeExecuted(uint256,address,uint8)","a877db9f":"none()","a878ad27":"createTokenToOperation()","a878aee6":"withdrawAllTokens(address)","a8790533":"distribution(address[],address,uint256,uint256,uint256,uint256,uint256)","a879af45":"oldTokenBalance(address)","a879fcbb":"assetInfo(uint256)","a87af57b":"setTokenForSale(uint256,uint256,address,bool)","a87b1cd2":"whitelistedBeforeActivation(address)","a87b73c7":"StageOpened(uint256)","a87ced35":"startDispute(bytes32,address,int256)","a87d2321":"Gummy()","a87d8b6b":"walkClientOrders(address,uint128,uint128)","a87d942c":"getCount()","a87de9cc":"ADD(uint256,uint256)","a87e0c33":"newAgon(uint64,uint64)","a87e5d3f":"setPriceUpdateFrequency(uint256)","a87e7552":"isValid(bytes,bytes)","a87e8aad":"getMyCat()","a87ebcb5":"setJackpotMinimumAmount(uint256)","a87f32a2":"ownFiles(string,string,string)","a87f84fc":"updatePersonLocation(uint256,string)","a87ffd1d":"GenesisInitialSupply(address,address)","a880319d":"addToken(address,string,string,uint8,bytes,bytes)","a880531f":"getOraclizeCbAddress()","a8817403":"addFamedStar(string,uint256,uint256)","a881f85e":"clearTokenSale(uint256)","a8825650":"slice(bytes32[],uint256,uint256)","a8826602":"getAllCellIds()","a882d49f":"replaceMultisig(address)","a8834aac":"getPointer(uint8)","a8836844":"returnPayees()","a883aab3":"GlobalAmountCapHard()","a883b0c4":"changeRate(uint256,uint256)","a883fb90":"getPendingVersion()","a885508a":"removePermissionManager(address,bytes32)","a885dab6":"getTokensPerDay(uint256)","a8862fcc":"isEscaping(uint32,int256)","a8865bda":"masternodeIsValid(address)","a886d66f":"crowdsaleList(uint256)","a8870d6f":"mintingDataUpdatedAtBlock()","a887d816":"checkTransferRequirements(address,uint256)","a888e4c9":"releaseSingleAm()","a8893a6e":"getNumOfSalesWithSameId(bytes16)","a88b2562":"AZLTEST()","a88b61aa":"isIncreasedEnough(address)","a88be96b":"RESERVE_EXCHANGE_RATE()","a88c0a9f":"LAMP()","a88c5ef7":"NextPayout()","a88c906c":"_buyUninitializedPixelBlock(uint256,uint256,uint256,bytes32)","a88e34cb":"setERC20address(address)","a88ec6fa":"showUnpaidDepositPercent(address)","a88ef2d3":"CarlosToken()","a88fa4b4":"updateStartTimeManually(uint256)","a88fe42d":"setPrices(uint256,uint256,uint256)","a88fe73a":"discountValue10()","a89004c5":"modifyQuanticCloudIOTData(uint256,uint256)","a89026a3":"teamProfitAddress()","a890b7d9":"finalize(address,bool)","a890d257":"IsThisPrivate()","a8915c7e":"periodPreITO_weiPerToken()","a89171e3":"checkHasilBet(address)","a89196a6":"eraExists(bytes32)","a891af67":"megaCandy()","a891fdc3":"earlybirdEnded()","a8928b45":"withdraw_internal(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[4])","a8929183":"LinkyexToken(address,address)","a894878d":"createPromoMeme(address,uint256,string,uint256)","a8967557":"isPresaleClosed()","a896d92d":"isRegularAddress(address)","a8977041":"Plenum(uint8,uint256)","a8978434":"softResolveAnswer(uint256)","a8986327":"minTokenForSP()","a899e615":"raiseRatio()","a899ef57":"parentSnapshotId()","a89a4f09":"creatorBalanceChecker()","a89acca4":"setCrowdsaleDates(uint256,uint256)","a89ae4ba":"oracleAddress()","a89c5be0":"MAX_TOTAL_TOKEN_AMOUNT()","a89c8c5e":"setTokenAddresses(address,address)","a89cdad9":"nextSnapshotTime()","a89d1eb9":"foobarToken()","a89f173c":"setUint(int256,uint256,uint8,uint16,uint32,uint256)","a89f5f85":"cmp(uint256,uint256,bool)","a8a01c3e":"cvcOwner()","a8a1d27b":"firstRoundWMTokensLimit()","a8a403df":"MaptPresaleToken(address,address)","a8a4bf11":"startNewAuction(uint64,uint64,uint64,uint64)","a8a52747":"getRelayedSender(bytes16,uint8,uint128,uint8,bytes32,bytes32)","a8a54008":"registerAddress(address)","a8a5c22c":"refineCost()","a8a618e9":"draw_random_card(uint8)","a8a6e9df":"deliveryToken(uint256,uint256)","a8a77984":"StoreBytes(bytes)","a8a9aaa9":"TokenLayer(address,address)","a8aa1b31":"pair()","a8aa7e19":"buyTeamHandle(string)","a8aaa2a6":"StringMapper()","a8abe1fb":"getCET4ScoreById(uint32)","a8abe69a":"getTransactionIds(uint256,uint256,bool,bool)","a8ac262b":"phaseCrowdsale()","a8ae3745":"evaluateTokens(uint256,address)","a8ae3e4b":"getAllocatedTokenValue(address,address,address)","a8ae5eb8":"howManyTanks()","a8ae9046":"RFToken()","a8aeecd9":"getCostForBattleCards(uint256,uint256,uint256)","a8af232b":"withdrawTopUp()","a8af4ff5":"getRegistrationStatus(address)","a8af6e05":"emitHashSet(address,bytes32,bytes32)","a8af74f1":"calcTrackerCount(uint256)","a8afc538":"priceAtInitialAuction(uint256,uint256)","a8b0312c":"GameStatus(uint8,uint8,uint8,uint8)","a8b05162":"_changeTilePrice(uint8,uint256)","a8b151fd":"santaFundWallet()","a8b1895d":"leftLottery()","a8b25075":"allowTransfers(bool)","a8b26420":"isUInt64ValidIn64(uint64)","a8b31f04":"HHH3(string,string)","a8b322b6":"verifiedWinnersCount()","a8b415d2":"BanliangCoin()","a8b42f1f":"registerAsAnOpponent()","a8b50ee0":"getWinnningsLength()","a8b57f15":"VIPPurchase(address,address,uint256,uint256)","a8b60b93":"ackMsg(uint256,string)","a8b82c5b":"BaseAgriChainContract()","a8b86c4c":"ZchargeToken(uint256,string,string)","a8b8799f":"getRecordId(uint256)","a8b88268":"checkEarlybird(uint256)","a8b973a1":"bonusMultiplier()","a8b981d3":"FOURTH_RATE()","a8baa97d":"getPlayerDetectGroup(address)","a8bb76d4":"checkSettlement()","a8bbe5a4":"ERC20Voting(address)","a8bc362e":"KleynCoin()","a8bc3a6c":"whitelistedPlannedContributions()","a8bcbf3c":"payManagementBodyAmount(uint256)","a8bd9c32":"tokenIndexToApproved(uint256)","a8bda3e9":"getTRed(uint256,uint256,uint256)","a8beb2cf":"Lockup6m_20180801(address)","a8bfd57f":"getMinerOffset()","a8c0f15e":"addProperty(bytes32)","a8c10d78":"BetSubmission(uint256)","a8c12d7c":"PayMain(address)","a8c17ec2":"incremental(uint256)","a8c1a0b7":"BuyTokensExternal(address,string,uint72,uint88,uint88)","a8c23cb9":"isValid(bytes32,string,address,uint256,address)","a8c278a2":"verificationFee()","a8c2c4a7":"mainICOEndTime()","a8c310d5":"distributeAmounts(address[],uint256[])","a8c3d246":"LamaToken()","a8c3ec48":"oraclize_query(uint256,string,string[2])","a8c499a0":"lrcDeposited()","a8c4c8bc":"right64(uint256)","a8c65126":"determineNextRoundLength()","a8c69264":"setreleaseFinalizationDate(uint256)","a8c6e684":"addint16(int16,int16)","a8c89c5b":"payableEnabled()","a8c923e2":"BlockchainDevCoin()","a8c9f8ae":"unSoldTokens()","a8ca698b":"absSub(uint256,uint256)","a8cab3d1":"Frozen()","a8cb7b4f":"ownerRequired()","a8cbabb7":"blockCrowdsale()","a8cbb5de":"addMake(uint256)","a8ccef6c":"setClue2(string)","a8cd0a80":"getTest()","a8cdcebd":"exchangeIdsToOpenMakeOrderIds(uint256,address)","a8ce0e60":"QuestTestToken()","a8ce6b73":"calculateWithdraw(uint256,uint256,uint256,uint256)","a8d00e73":"dayLength()","a8d088bb":"getManagers()","a8d10fb8":"getOrgCount(string)","a8d18472":"estWolkToBurn(address,uint256)","a8d18bc0":"HireGoCrowdsale(uint256,address)","a8d1fcff":"cancelNewBallot()","a8d201ab":"removeNodeFromWhitelist(address)","a8d34ea5":"getCompte_10()","a8d3a63d":"pullEtherFromContractAfterICO()","a8d48709":"EARLYBIRD_PRICE_MULTIPLIER()","a8d49e64":"setWhitelistAdmin(address)","a8d4a03b":"heroes(uint256)","a8d4ee0f":"setOwnerExt()","a8d51f7e":"GiftToken(address)","a8d5308c":"bountymanager()","a8d5652e":"tokensPerTier()","a8d5efa3":"CATPayment(address,address,uint256)","a8d5fd65":"share()","a8d84b7c":"purchaseWithIndex(uint256,uint256)","a8d84fc3":"activeEnd()","a8d88127":"exists(int256,int256)","a8d8e055":"checkAddressBatch(address[])","a8d95496":"getHighestPriceOwnerAt(uint256)","a8d95fb2":"claim(address,string)","a8d99045":"totalSellCardNumber()","a8d9a89a":"initialICOCap()","a8d9e8a3":"sendFeeIfAvailable()","a8da6873":"_fetchCreatedOrdersForPayer(address)","a8dab783":"isPASigned(uint32)","a8db1837":"test_updateAndGetPrice()","a8db2445":"setCompany(address)","a8dc824c":"unlockSupply()","a8dd07dc":"totalBonus()","a8ddefab":"withdrawNacNetfRe(uint256)","a8df3e69":"post(address,address,uint256,string)","a8df7894":"investDirect(address,uint256)","a8df80ad":"Hellob()","a8df99a9":"_emitSkillsSet(address,uint256,uint256,uint256)","a8e02ccb":"activeCall(address)","a8e04f34":"disableInitialStage()","a8e1903c":"RevokeTokens(address)","a8e1b53f":"AICoin(address,uint256)","a8e3371a":"eduCash(uint256,string,string)","a8e3a6b6":"communityTokensCap()","a8e48a7e":"PausableCrowdsaleImplUnpaused(uint256,uint256,uint256,address)","a8e496b9":"toDay(uint256)","a8e4fb90":"proposer()","a8e553f5":"decrypt(uint32[26],uint32[4])","a8e5740c":"setOgToken(address)","a8e5e219":"jobStatus(uint256)","a8e5e4aa":"approveERC20(address,address,uint256)","a8e6e77b":"addManyAdmins(address[])","a8e6ee52":"goldCertVerifier()","a8e6f9dc":"set_property_address(uint256,string,address,string,string,string)","a8e70dd3":"unblockMessagesFrom(address)","a8e81844":"GeneBTC()","a8e8f677":"maxDice()","a8e91396":"setICOPriceatDollar(uint256)","a8e9b249":"versionSelectors(bytes32,bytes32)","a8ea8554":"changeAmount()","a8eaefd7":"TotalFee(address[])","a8ec9ffb":"CrowdsaleStageStarted(uint256,uint256,uint256,uint256,uint256)","a8ecc7f1":"rbac()","a8ed1be5":"bts_address2()","a8eee036":"Locality(string)","a8ef4b66":"PERMISSIONMANAGER_KEY()","a8ef6edd":"testTrusting()","a8f02555":"DXF_Tokens()","a8f03616":"ownerTokenSharePct()","a8f06876":"CETToken(uint256,string,string)","a8f07dcc":"minimum_investment()","a8f0d3a7":"getArrayBytes32(bytes32)","a8f0e6e2":"sellPriceOf(uint256)","a8f0ebeb":"decreaseClaimsBalance(address,uint256)","a8f0fbbd":"helloToken()","a8f11eb9":"autoDistribute()","a8f2ba4c":"bet_win()","a8f2d63b":"isPublicTokenSaleRunning()","a8f436df":"startEvaluating()","a8f56600":"model_accuracy_criteria()","a8f5bbd9":"initiateUser()","a8f5c673":"savePepe(uint256)","a8f653fa":"finalizeStage()","a8f6c913":"erc20Contract()","a8f6d313":"minimumFundingUSD()","a8f6d84d":"returnPercentage()","a8f6f1f0":"randomGenerateMethod()","a8f7e238":"getAdminsForGame(uint256)","a8f7f82d":"ICO_start_future(uint256)","a8f8884d":"botIndexToApproved(uint256)","a8f899a0":"LogBuyForInvestor(address,uint256,string)","a8f8c6de":"getCollaborated(uint256)","a8f8e2ae":"testFailIfReverts()","a8f927e9":"getLanguage()","a8f92b52":"MindCoin(uint256,string,string)","a8f9868e":"getTotalBalanceFor(address)","a8fa14b0":"disableContractUpgradability()","a8fa2fc6":"getCurrentDevReward()","a8fa5682":"dnsRecord(bytes32,bytes32,uint16)","a8fa6e14":"setLastRewardTime(uint256,uint256)","a8fa8e52":"valuePerToken()","a8fac082":"claimMonthlyDemurrage(uint256)","a8faf6f0":"SmartAirdrop()","a8fc1a2a":"realDevReward()","a8fc32de":"sendDividends()","a8fca0fc":"toRtc(uint256)","a8fd1026":"gemPerEther()","a8fdb290":"EtherToken(uint256,string,string)","a8fdf903":"_underMintNextTokenId(uint256)","a8fe43ce":"getVotingProxy(uint32,int256)","a8fe5465":"PRE_SALE_15_BONUS_MIN()","a8feda51":"processRefunds()","a8ffa37f":"gameTokenResolution(uint256,address,uint256,address,uint256)","a8ffa9d9":"addCandidato(string)","a9011990":"getOneDepositRec(uint256)","a90135df":"pgoInternalReserveWallet()","a9014b0f":"isListed(uint64)","a9018896":"refreshScore(uint8,bytes32)","a901aaa0":"AirRewardmaxTotalSupply()","a901ce92":"founderTokenWithdrawnPhase4()","a9030162":"refundFish(address,uint256)","a903073e":"getOwnerTeam(address)","a9036b43":"Minter(address,uint256,uint256,uint256)","a903741a":"TEAM_BONUS()","a904cc53":"withdrawEtherBalance(uint256)","a904e5c8":"TRM1BonusActive()","a9055b81":"makerRequiredKncStake(address)","a9059cbb":"transfer(address,uint256)","a905f4c0":"DUOLINGO(uint256,string,string,uint256)","a9061415":"getsellmoney(uint256)","a906f837":"relocationSwitch(bool,address)","a9076f9e":"setBidding(bool)","a908f2e3":"Faucet(string,address)","a9092c11":"numChoices()","a909d7d3":"removeTokenEmission(uint256)","a909fc56":"mint(int256,address)","a90a4ac2":"addStruct1(string)","a90a6427":"setPaydayFrequencyInDays(uint8)","a90a6952":"EmissiveErc223Token(address,string,uint8,string,string)","a90a8eea":"getDaysInYear(uint16)","a90ae887":"claimPayment(uint256,uint256,bytes)","a90b5e62":"setTokensContractAddress(address)","a90d3cda":"totalContributionsBy(uint256,address)","a90e0608":"icoFinalized(uint256)","a90e09e2":"addWhitelisted()","a90e65a3":"MinorPrizePayout(address,uint256,uint8)","a90eb2b9":"sendFundsToNextCycle(uint256,uint256)","a90f8e9a":"referredBy(address)","a90fcfa0":"_generateName(string,string)","a90fd971":"minerRelaseTime()","a90fdf20":"test_bytes(bytes)","a9112140":"change(address,uint256,uint256)","a91202d3":"createUser(bytes32,bytes32)","a9120f6d":"release_by_manager()","a913c43f":"getLockedAmount_jiedians(address)","a913eb24":"_price_token_ICO2()","a9142808":"logFollowerTradingTx(bytes32)","a9147e22":"setIsCheckStage(bool)","a9157518":"add5NewStreetNames(string,string,string,string,string)","a9171d56":"purchaseCallbackOnAcceptAndDistribute(uint256,address[],uint256[])","a9188878":"setPrimordialPrices(uint256,uint256)","a918c09c":"supplyFuel(uint256)","a91a1080":"getCase(uint256)","a91a39ad":"havedCrowdCoin()","a91aae63":"NihilCoin(uint256,string,uint8,string)","a91abdcb":"referralCut()","a91b2e9f":"getProfit(uint256)","a91bc3cd":"nextMinimumTimeout()","a91be87f":"addEarlylist(address[],address)","a91c39a9":"setEnergyCost(uint256)","a91ce985":"createOrder(address[3],uint256[4])","a91cec21":"ineRexToken()","a91cfecf":"Foosball()","a91d6c65":"initLockedBalanceOf(address)","a91d99db":"whitelistAddressesPresale(address[])","a91ed8c6":"mintReserve(address)","a91ee0dc":"setRegistry(address)","a91f559d":"NeLunaCoin()","a91faadf":"JoshContract()","a91fbb99":"MonetoSale(address,address)","a91fc821":"Registry(address,address,address)","a9203f3c":"getFlower(uint256)","a92100cb":"loop()","a921ba7d":"totalBattleboards()","a9221706":"_transferAndCall(address,address,uint256,bytes)","a9225743":"_commitBallot(bytes32,uint256,uint256,bool)","a92259fc":"AVAILABLE_TOTAL_SUPPLY()","a923ebac":"unbindEthereumAddress(address,bytes32)","a923fc40":"setInfo(string,string)","a9240e32":"setEtherRatioForOwner(uint256)","a924d3ca":"getMangers()","a924ee60":"disableTokenMinting()","a9250212":"publicationCount(address)","a925252a":"acceptAuctionResult(address,uint256,string)","a925d85e":"Exchange(address,address)","a926819f":"disableWallet(address)","a927f46b":"Etherwow()","a9287619":"buyXaddr(uint256,address)","a9293efe":"calculateSeasonScore(address,int8)","a92950f6":"chainWith(uint256,uint256)","a9298848":"askForALoan(address,uint256,uint256)","a92aafb0":"paused_1()","a92ab316":"EIN()","a92c300a":"getBidData(uint256)","a92c3231":"stageNumber()","a92ca27d":"editionInfo(uint256)","a92d5367":"changeTournamentTaxAmt(uint8)","a92d6a48":"disableAuthentication()","a92ec661":"isAfterStartTime()","a92f0c80":"TokenVesting(uint256,uint256,uint256)","a92f0cb9":"withdrawFailedOldOwnerTransferAmount()","a92fcf9c":"addRecord(string,string,string,bytes32,int64)","a9321573":"addExcluded(address)","a9324192":"walletOut1()","a932ed0d":"whitelistRemove(address)","a936444a":"POWH33()","a936c203":"reLoadXid()","a937c28b":"authorisedInvestors()","a937f12b":"TidealToken(address)","a9390454":"DevvotePrefund(address,address)","a9393452":"getAuctions(uint32,uint32)","a9396a1b":"getStageInfo()","a93a77c1":"available_percentage()","a93b1a65":"_referrerTax(uint256,bool)","a93b5331":"totalFundingSupply()","a93c1286":"Y2CASH()","a93d7c72":"quickChange(address[],uint256,uint256)","a93deda4":"Philanthropy(address,string,uint256,uint256,uint256,uint256,uint256)","a93e0386":"preSaleBonus4Amount()","a93e2b49":"YBQ()","a93e4044":"getCountTokensByLottery(uint32)","a93e8701":"BetCanceled(address,uint256)","a93fd5f1":"organizer5()","a940565e":"haveIBeenNaughty(address)","a9405923":"getParent(address)","a9405f4f":"HashToFileName(string)","a940d013":"ether_profit()","a9414cc3":"getPositionsAndTokensCnt(uint256)","a941be3c":"internalBuy(address,uint256,bool)","a941c8d6":"calculateWinningEntries()","a941ff21":"getCampaignEndDateById(bytes32)","a942bf05":"dDeployCommunityBallot(bytes32,bytes32,bytes32,uint128)","a942de01":"createSetup(uint256,uint256,address[])","a9430dcb":"Shabu()","a94385a0":"donateFromWallet(uint256)","a94387a6":"raiseBuyOrderCreated(address,uint32,uint32,uint80,uint256,int160)","a943c21f":"getVotingResult(address)","a9445499":"ZperMainSale(address,uint256,uint256,uint256)","a944f15b":"createAuction(address,uint16,uint16,uint256,uint64,uint16,uint16,uint64,uint256)","a94510ca":"withdraw_badge()","a9457d9c":"whatIsCurrentCap()","a945c5c3":"totalInvestments(uint256)","a945f90f":"partnersWallet()","a9466a88":"getAllScripts(uint256)","a946d7bb":"setMedalsClaimed(uint16)","a9472396":"getClientReward(uint256)","a94834a1":"openGameRange(uint256,uint256)","a948d72d":"ZethrBankroll()","a9496e73":"timeBeforeJackpotReset()","a949c637":"addOwner(address,address,address)","a949f3af":"getMyLastCollectHour(uint32)","a94a06e8":"findRegularTime()","a94ab274":"corePay(uint256,uint256,uint256,string,uint256)","a94c33a6":"Auxilium()","a94c468d":"RemoveRank(uint256,uint256)","a94c7c65":"limitedPrint(address,uint256)","a94e7ed4":"isSpecificallyApprovedFor(address,uint256)","a94feacc":"claimTokenWindowOpen()","a95022a6":"GoodTimeCoin(uint256,string,string)","a95055a8":"getPlayerBoardsIDs(bool)","a9505eb4":"maxOfArray(uint256[])","a950fb0e":"b64decode(bytes)","a9510f89":"totalAmountOfTokens()","a951c534":"_CallScheduled(bytes32)","a951c994":"setSetupComplete()","a951f28e":"dayaToken()","a951fad2":"CryptoX(uint256,uint256)","a9522f4e":"IsDividendAvailabe()","a95236ed":"DeDeTokenContract(address)","a95240c4":"memberShareCount()","a95281f0":"registerPoA(string,bytes32,uint256[],uint256[],address,address)","a952f268":"MAYExchangeRate()","a9535320":"TwoXJackpot()","a9538157":"increaseApprovalByLegacy(address,address,uint256)","a953d08d":"mintBounty(address,uint256)","a954736d":"cancelSellPop(uint256)","a9549f81":"getDAOId(uint256)","a954c209":"great(uint256)","a9550ecb":"getMonsterDefenseFromDna(uint256,uint256)","a9553d74":"phaseThreeBonusPercent()","a9559dd7":"updateBalance()","a95609ca":"editContribution(address,uint256,uint256,uint256,uint256)","a9572ac7":"setMulFactor(uint256)","a9580edd":"distribute(uint256,uint256,address,uint256)","a95824b4":"votingOpen()","a95836d1":"finalizeICO(address)","a958ffc4":"fundingDurationInHours()","a9593b98":"changeVote(uint256,uint256)","a9595472":"SOC()","a95a3887":"rolloutDividends(address)","a95bc9a7":"changeChannel(address,uint256,uint256,uint256)","a95bfd36":"adminAddBallotOption(uint32,string)","a95c372d":"fetch()","a95c4d62":"purchaseToken()","a95c5339":"checkGameRegiester(address)","a95d017d":"getRevisionBlockNumber(bytes32,uint256)","a95d580c":"withdrawEarnings(uint256,bool)","a95d85d8":"withdrawTo(uint256,address,bytes)","a95d9c14":"Uncloak()","a95ff7d5":"isDecentBetCrowdsale()","a9604239":"maxAmountRoundSeed()","a9607011":"HappyEthericHome()","a96088a5":"vernamToken()","a9612f72":"emitOwnershipChange(address,address,bytes32)","a9615f59":"platAuction()","a961e9e8":"startSaleTime()","a9625fa8":"MANHATTANPROXY3RDST()","a962a7d6":"set_burned(uint256)","a9636b9f":"Bytes32Oracle(bytes32)","a964bb9a":"configureLimit(uint16,uint16)","a964bea7":"CheckRevoke(address)","a96594d3":"nextLotteryTTMTokenId10()","a965a941":"getNote(uint256)","a965e5c1":"setBonusAddress(address,bool)","a96654ee":"transferredOwner(address)","a9671d8f":"getProductionOf(address)","a9671dd9":"enableProxy(address)","a967f3e7":"emitProjectCreated(uint256,uint256,address)","a968309d":"plutochain()","a968991b":"confirmed()","a9689d0f":"transactionFeeRate()","a968ad0e":"resetBonuses(address)","a968b97c":"verifyCodeLength(string)","a96948c6":"chefBalanceOf(address)","a969574d":"ratePreICOEnd()","a969f080":"QUIKKO()","a969ff0a":"collectFee(uint256)","a96a4998":"DEFROST_FACTOR()","a96a5a5b":"pwin()","a96af0f4":"saleSupply()","a96b1828":"GLOBALETHER()","a96b2dc0":"getCallCount()","a96b3ab8":"getDthShop(address)","a96c3e6e":"getPlayerAddr(string)","a96c4eb7":"Sold(uint32,address,address,uint256)","a96c6bfe":"setDeveloper(address,bool)","a96ce7aa":"unlock(string)","a96f45c7":"ETHTransfer(address,address,uint256)","a96f8668":"releaseTokens()","a96fb9b4":"testTokenA()","a970a23a":"internalUpdateRates(bytes4[],uint256[],uint256)","a970ef6e":"tokenContractDefined()","a9718d51":"getTransferValuebyArrd(address)","a971c23d":"minimumFeePercentage()","a9725a68":"LIMIT_STAR5()","a9726c1e":"withdraw_bounty()","a972a451":"sqrt(uint32)","a973e27c":"testFind()","a9740fdf":"SwapCreation(address,address,uint256,uint256,address)","a9743c68":"getCallPayout(bytes32)","a9746acf":"UserBought(address,uint256,uint256,uint256,uint256)","a974e21f":"HKIN(uint256,string,string)","a97501a3":"ManUvsTottenham()","a97583de":"_transferByPartition(bytes32,address,address,address,uint256,bytes,bytes)","a9758fcc":"CurationRightsTransferred(address,address)","a9764152":"createFunction(string,string)","a9767e14":"masternodeMineTokens()","a977449e":"unbanReferrer(address)","a977c71e":"changeQuota(uint256)","a9782954":"hunterOf(address)","a979169f":"updatePackage(uint256,string)","a9791aec":"tgeSetFinished()","a9797521":"bn128_is_on_curve(uint256[2],int256)","a97a6d63":"setWhitelisted(address,address,bool)","a97b8b48":"LOG_CurrentPercent(uint256)","a97b8b4d":"closeBallot()","a97c8eb4":"RTEToken()","a97cb561":"isTransferAgent(address,address)","a97cc114":"getTile(uint256)","a97d48fd":"sendContractFundsToAddress(uint256,address)","a97e5c93":"isOracle(address)","a97fc381":"toSlice(bytes)","a97fe7b6":"airDropTotalSupply()","a97ffd5e":"safeToSell(uint256)","a9804acb":"HealthyCoins(string,string,uint256)","a980bb9e":"isDisclosureSigned(uint256)","a9814d14":"Outcome()","a981daca":"testIntParserNegative()","a9820ead":"Ballot(bytes32[],bytes32[])","a9824288":"CTMC()","a9825b7c":"bonusUnsold()","a9831437":"setCreationPrice(uint256)","a9831edf":"unlockFundsAndPassEther()","a98325b6":"collectDividend()","a983637e":"BACHELORCHAIN()","a9839dd7":"exchg(address)","a983c932":"isValidContract(bytes32)","a983d414":"safeassert(bool)","a983dcc0":"setDefault(bytes32)","a983e1bb":"random(uint256,uint16)","a984cec2":"additionalPresaleInvestors()","a9850e26":"SellToyMoney(uint256)","a9854087":"closeAt()","a9856d6d":"initSale(address,address,uint256,string)","a985e6c6":"withdrawAirDrop(address[],uint256)","a986c969":"stand(address,uint8[],bytes32,uint8[],uint8[],bool[],uint256,bytes32,bytes32)","a986ef4a":"nextRoundCoolingTime()","a9872393":"racesInfo(uint256,uint8,address)","a9875d70":"stage4Start()","a987d4c6":"_mint(address,uint256,string)","a987d654":"restoreItem(uint256)","a987f9da":"Creation(uint256,string,address)","a9888148":"testFailRetractNotRetractable()","a988845a":"setNewMessageNumber2(string,uint256)","a988df4b":"bgb_per_eos()","a988e371":"taxPaid(address)","a988ea3a":"NETHtoken(uint256,string,string)","a98902e9":"LUNVault(address)","a98a6d19":"ICOWeiRaised()","a98a89c2":"buy1(address[],address[],uint256[],bytes)","a98ad199":"removePermittedContract(address)","a98af238":"setCCH_edit_16(string)","a98c439f":"buyTokensAltercoins(address,uint256)","a98ca17d":"exercise(uint256,uint256[3],address)","a98cb619":"transferGenesis(address)","a98d5961":"pickRandomAssetPosition(uint256,uint256,uint256)","a98e4e77":"getAccountCount()","a98ee0b7":"_getInitAuctionSeconds()","a98f81fd":"BEXAM()","a98f99d8":"removeDefaultOperatorByTranche(bytes32,address)","a9901c6b":"getIsCoinReg(bytes4)","a990dd52":"unitsOneEthCanBuybefore()","a9918dfc":"getCompte_36()","a991a24d":"getTenancy(uint256,uint256)","a991cb0e":"respond(uint256)","a991faf9":"getTotalDividendsAmount()","a99306e7":"addPVPContender(address,uint256)","a993772f":"isPreIcoFinish()","a993e180":"getFechaTax()","a9948f7e":"GetNbyPrice(uint256)","a996d6ce":"setBurner(address)","a996d72e":"OracleChainToken(uint256,string,uint8,string)","a9974338":"setB0xToken(address)","a997f82f":"setCrowdsaleStage(uint256)","a998146b":"allToken()","a9985260":"test_setMaxSize()","a9989b93":"tokenAddresses()","a998fdbe":"getWithdrawAmount(address,address)","a9995010":"CappedCrowdsale()","a99a353b":"SWAP(address,address)","a99a3f03":"PLAYER_TIMEOUT()","a99a3f98":"initSale(uint256,uint256,uint256,uint256,uint256,uint256)","a99a985b":"betOn(uint32,uint32,uint256,address)","a99aa366":"presaleDiscount()","a99b9e39":"ICO_START_DATE()","a99be610":"PreIcoMessage()","a99bf4fa":"Potential_Investors(address)","a99ce372":"VINE_CAPACITY_PER_LAND()","a99d8d48":"changeTransferable()","a99da6af":"finishDeal(uint256)","a99dca3f":"hi()","a99df9c3":"oneCentInWei()","a99e0a81":"maxICOFirstSupply()","a99e6465":"addTier2Member(address)","a99e7e29":"register(bytes,address)","a99f0d9f":"_addBallot(bytes32,uint256,uint256,bool)","a99fba7d":"calculatePlatformCommission(uint256)","a99fc5aa":"tempCharity()","a99ffb7b":"timestamp(bytes12)","a9a07af9":"incFightToDeathWin(uint256)","a9a0844b":"getSaleVolume()","a9a0b495":"getPreSignedHash(bytes4,address,uint256,bytes,uint256,uint256)","a9a11111":"QuadraticVoting()","a9a18dda":"totalEthReceived()","a9a1fb96":"releaseTokensForce(bytes32)","a9a26902":"changeBubbleWallet(address)","a9a29afa":"getRefundTxFee()","a9a343b3":"Puzzled(address,bytes32)","a9a3a9c5":"vxtest()","a9a3cef4":"LISKClassic()","a9a3da4a":"getRemainUtcoin()","a9a40c71":"getNumberOfOpenDeals()","a9a51f89":"changeTokens()","a9a5e3af":"removeOwners(address[])","a9a615e9":"setWhitelistedStatus(address,uint256)","a9a6e9b4":"distributeLCD(address[],uint256)","a9a8679b":"authorizeAccount(address)","a9a8fc84":"ItemCreated(address,uint256)","a9a9d7af":"sellerList(address)","a9a9e4f7":"_payloadOffset()","a9aac3e4":"registerWineOwner(address,string,string)","a9aad58c":"PAUSED()","a9aae07a":"setMinGas4Accts(uint256)","a9aaf116":"BillahChain()","a9ab9b46":"getAccountItems(address,uint256)","a9abe7be":"setIcoSecondWeekRate(uint256)","a9ac225c":"ProposalTallied(uint256,uint256,bool)","a9ac4c5f":"checkMonthlyLimit()","a9acc475":"getBlockValue()","a9adaecd":"calcStopPriceFactor()","a9add7dc":"setEvolvePrice(uint128)","a9ae8323":"presaleDateFinish()","a9aeb059":"updateCeiling()","a9b07600":"setIdArray(address,uint256,string,string,uint256[])","a9b0c5a4":"preIcoFinished()","a9b0e8d5":"Cscchain(uint256,string,string)","a9b11426":"getImageOwner(uint256)","a9b12c4c":"blocktime()","a9b1d507":"makeWallet()","a9b1ffd9":"totalChequeValue()","a9b2c135":"lockedYears()","a9b2ca9c":"changeDragonGen(uint256,uint256,uint8)","a9b2cc09":"getMaxContributionAmount()","a9b35240":"packageExists(bytes32)","a9b46030":"BurnableOpenPayment(address,uint256)","a9b48ba7":"WIN()","a9b4b780":"getWeight()","a9b542bd":"getDna1(uint256)","a9b551d2":"getAdministratorMoney(address)","a9b5ae83":"messageForPeace(string)","a9b69e7c":"deployersCount()","a9b6c8bc":"getAddress(bytes16)","a9b76504":"getContestTeam(uint32,uint32)","a9b7c3bf":"cooAddress1()","a9b86292":"totalSharePool()","a9b86924":"buyStoreByName(bytes32)","a9b8dad6":"level_3_percent()","a9b8f7b8":"ProtectTheCastle()","a9ba2b09":"releaseFine()","a9bb03a4":"deptrespond(address,address,string,bool)","a9bb3274":"UCCOIN_PER_ETHER()","a9bc5db1":"createHeld(address,uint256)","a9bf1c9f":"ENS_ROOT()","a9bfe5c7":"TokenBalance()","a9c0838d":"getPI_edit_3()","a9c1873c":"setTokenPerEth(uint256)","a9c1f2f1":"decayRate()","a9c2ac3a":"getBetIds(uint256)","a9c2e36c":"getFactoryAddress()","a9c32c35":"NewExchangeRate(uint256)","a9c38476":"latestEditionReleased()","a9c4429a":"getInvestmentPackageInformation(uint256)","a9c45fcb":"upgradeToAndCall(uint256,address,bytes)","a9c4d62e":"S25ICO()","a9c5c9df":"aval(uint256,address)","a9c6a624":"updateNumber(int256)","a9c6c714":"unsoldAllocationOraclizeGasLimit()","a9c70eaa":"getUint(uint256)","a9c73e80":"setText(string,string)","a9c7648f":"distributeToken(address[],uint256)","a9c76999":"totalProfit(address)","a9c8733c":"correct()","a9c8dfcd":"AuctionCreated(uint256,uint256,uint256,uint256)","a9c95328":"renameList(address,string)","a9ca2072":"getAccountValue(uint16,uint8,uint8)","a9ca6057":"baseball()","a9cb2227":"getPlayerRoundTeamBought(uint256,uint256,uint256)","a9cbd0a5":"percentageToEthertoteDevelopmentWallet()","a9cc077a":"TOKEN_PRICE_DENOM()","a9cc4718":"fail()","a9ccc3af":"isEtherSpaceUpgrade()","a9cd2be6":"createSlot(uint256,uint256)","a9cd9e06":"secureWithdraw(uint256,address)","a9cdf643":"TEAM_MEMBER_VAL()","a9cf037a":"EEYcoin(address)","a9d04bd8":"getStakingRequirementTime(address,uint256)","a9d05989":"ETFW()","a9d07519":"TokensCappedCrowdsale(uint256)","a9d0b164":"priceOfEthOnUSD()","a9d0ddc7":"addContractWithInfo(string,string)","a9d0fd87":"_updatePurchasingState(uint256,uint256,uint256,bool,address)","a9d2293d":"lastClaimBlock()","a9d23ace":"getBundleExpiredTimeOfEmail(string,uint8)","a9d2d87c":"Manual_Mint(address,uint256)","a9d3da74":"SimpleAuction()","a9d40b77":"buyOffspring(address,string,uint256,uint256,uint256)","a9d424e2":"buy(address,address,uint256,uint256)","a9d48032":"maxSpendToken()","a9d49f62":"searchInsertionPoint(uint256,uint256)","a9d4d6bc":"lastBlock_f1()","a9d5e255":"GACToken(uint256,uint256)","a9d66127":"cancelPawn(uint256,address,bool)","a9d66352":"minimum_deposit_amount()","a9d72f82":"alterFeaturePetitionFee(uint256)","a9d74013":"claimedToday()","a9d82f18":"realDEXToken()","a9d85266":"setValue(bytes32,bytes32,uint256)","a9d9f572":"Println(address,uint32,uint256,uint256,uint256,bool,uint32)","a9d9f644":"viewLockUpStatus(address)","a9da0fad":"setOutcome(uint8,uint8)","a9da1417":"DEXHIGH(address,address,address,uint256,uint256,uint256)","a9dab167":"extendLock(bytes32,uint256)","a9db06e5":"perAmountRaised()","a9db9ce6":"getOraclizeGasPrice()","a9dbaf25":"length(bytes32)","a9dbe76f":"confirmSeller(uint256,uint256)","a9dc1d54":"singularDTVCrowdfunding()","a9dc491d":"getResolver()","a9dd1225":"random(uint256,uint256)","a9dd6895":"acceptTransaction(uint256)","a9dda4df":"setAuctionAddress(address,address)","a9de5045":"acceptAction(bytes32)","a9de581b":"auctionWinnerMessageHash()","a9df1aa2":"WithdrawalNormal(address,uint256)","a9e044ae":"SetProjectTag(string)","a9e10bf2":"recieve()","a9e2bcfe":"oneRoll()","a9e2e084":"_createPoo(string,address,uint256)","a9e30f96":"TokenPK(uint256,string,uint8,string)","a9e3fd27":"contentHostPrice(bytes32)","a9e406d5":"_setProviderSupply(uint256,uint256,uint256)","a9e4d6ce":"UpdateTokenRate(address,address,uint256)","a9e5714b":"AgriChain()","a9e732bb":"cashout(uint256)","a9e79359":"payoutForTimeline(uint256,uint256)","a9e7c2e5":"claimToken(uint256)","a9e7cb10":"Mediation(address)","a9e7f730":"FreyrCoin()","a9e899ef":"challengeFeeMultiplier()","a9e8a6bb":"prolongBonusPreIco(uint256)","a9e8f2f0":"get_refund_vocean_addr_amount(uint256)","a9e931ab":"addRec4L8R(address,uint256)","a9e94aa2":"Sponsor()","a9e966b7":"setState(uint256)","a9ea1896":"priceT1()","a9ea4aaa":"EntryToken()","a9ea6454":"basicThreshold()","a9ea96f0":"setDevelopersTokensPercent(uint256)","a9ea9d17":"PURCHASES_BONUS()","a9ead91c":"addressToAsciiString(address)","a9ebeb25":"nextReferrerId_()","a9ec77d3":"PublicSale(address,address,address,address,uint256,uint256,uint256)","a9ed003d":"sister()","a9ed9cb8":"disallow(address)","a9eeaeee":"getSanSlots(address)","a9eed530":"reduceOrderQty(uint256,uint256)","a9f00221":"resetTokenOfAddress(address)","a9f036dc":"accCompany()","a9f0a590":"transferAdministratorship(address)","a9f12d8a":"RaliusToken()","a9f16529":"thisVotersChoice()","a9f2db37":"unlockTokens(address,address)","a9f5de42":"crowdsalePhase()","a9f69edb":"checkRole(uint256,address,uint256)","a9f6def0":"HonestDice()","a9f73dd2":"_getRarity(string,uint8,uint8)","a9f79f7d":"FXT(address)","a9f7c131":"updateDateOfPurchase(address,uint256)","a9f7d03b":"admin_typeOf(address)","a9f7e664":"transferTokens(address,uint256,uint256)","a9f7f7e5":"o_algoritmo(uint256)","a9f844a8":"PlayerBalance(address,uint256,uint256)","a9f8792e":"votingProxyContract()","a9f8ec6c":"AlarmClockTipFaucet()","a9f940c3":"addChain(string,string)","a9f951dc":"getNation(uint8)","a9f987b5":"UFOcoin()","a9f992b1":"BTC8000on420()","a9fab274":"burnAuditApproval()","a9fae422":"getParents(address)","a9fb11b3":"potAddup()","a9fb4385":"ContributeWithSender(bool,uint8,address)","a9fb8fe6":"getFeesByAsset(address)","a9fbc614":"lookupTicketHolder(uint256)","a9fc9501":"indexTheWorkcrew()","a9fcf76b":"setIntArray(bytes32,int256[])","a9fd1bd3":"TradeAffected(uint256,uint256)","a9fd3f42":"transferApprovedFunds()","a9fde745":"transferTrade(address,address,uint256)","a9feca22":"_emitOracleAdded(address)","a9ff2a5e":"transferTokensFromWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","aa01ac22":"gmAddress()","aa01ef7d":"finishVotingPublic(address,uint256)","aa02a90f":"majorityMargin()","aa03214c":"calcBonusPercent()","aa0372e7":"getItem(bytes32)","aa03dfaa":"createChannel(bytes32,address,uint256)","aa0465b8":"setPriceData(uint256,uint16,uint256,uint8)","aa049691":"changeAccount(address)","aa04e566":"getWhoPiad(address,address,address,address,address,address,address,uint256)","aa052bd1":"startPreSaleStage()","aa056d2a":"cloneWithPopAndBottle(uint256,uint256)","aa058a73":"right6(uint256)","aa05b852":"s34(bytes1)","aa065074":"StageVestingToken()","aa071061":"LogAccountModified(address,address,bytes32,bytes32,bytes32,bytes32)","aa077992":"getProductEarning(uint32)","aa08523d":"lockedCustomer(address)","aa08c9e6":"getCoverImageCount(address)","aa08dfd3":"setFeeParams(uint256,uint256,uint256,uint256,bytes)","aa09bab8":"usedTotalSupply()","aa0bf9ba":"calculateRawPoolAmount(uint256)","aa0cd6eb":"_distributePoolReward(uint256,address,uint256)","aa0cfcbf":"buynums(uint256)","aa0d30f3":"deduct_fees()","aa0d9fb5":"_aremoveByValue(address)","aa0e38b4":"Mobilink()","aa0f0d4a":"Team(bytes32,bytes32,address,bytes32)","aa10ce22":"addExchange(address)","aa10e8c2":"CreateAPool(string,string)","aa1199ea":"setApprove(bool)","aa121bbe":"ABIChanged(bytes32,uint256)","aa125d08":"timeWaitUnlock(address)","aa127ae3":"test_9_checkDestructionOverflow_shouldThrow()","aa13ca76":"getTokenPrices()","aa13e8c2":"waitingTime()","aa141ee2":"spartans()","aa14c39a":"submissionDeposit()","aa14fa5a":"ICObonus()","aa156645":"isWorker(address)","aa1589a9":"approveLeave(address,uint256,string,uint256,bytes32)","aa1614eb":"ethRetrieve()","aa17973c":"createRandomAtom()","aa17e768":"getParentI(uint256)","aa183877":"getMonkey()","aa188b29":"SandBoxERC20()","aa18c05c":"TRANSFER(address,address)","aa18f76a":"getAllowedAmount(address)","aa1953cc":"canAccess()","aa19ed77":"freezeTransfersUntil(uint256,string)","aa1b510e":"cheat()","aa1ba6a9":"totalWin()","aa1c31a3":"BatCave()","aa1cdce8":"allot(uint256)","aa1cf1cd":"dumpFreeTokens(address)","aa1cf23e":"_isIdle(address,uint256)","aa1d807f":"ESCBDevMultisig()","aa1d98af":"personIndexToOwner(uint256)","aa1e47ae":"MyCoin()","aa1e84de":"hash(bytes)","aa1f609f":"ETHER_MIN_CONTRIB_PRIVATE()","aa202aca":"testBytes32Len()","aa20e1e4":"updateMasterMinter(address)","aa216998":"INITIAL_SAPLLY()","aa2262a8":"prevCourse()","aa226780":"trade(address[11],uint256[11],uint8[2],bytes32[2],bytes32[2])","aa228cda":"reduceMul_()","aa22b56b":"getDAOById(bytes32)","aa235449":"SpencerToken()","aa237e21":"set(bool,uint256)","aa238110":"getCurrentPrice(uint16)","aa23cb19":"transferFromIndexed(address,address,uint256)","aa23e03d":"getIdentifier()","aa24da73":"MultiToken()","aa24e8aa":"numberOfAlternatives()","aa2529a2":"RefundChequeById(string)","aa2580c1":"startPreSaleRound()","aa258b2e":"TitlePurchased(address,uint256)","aa25c744":"getDenominationByName(bytes8)","aa25f57e":"setPartnerETHRewardsPercent(uint256)","aa271e1a":"isMinter(address)","aa272d4b":"getNodeIndexId(bytes)","aa2796fd":"payoutForMining(address,uint256)","aa27cdf2":"deleteSharedAccount(bytes32,bytes32,uint256)","aa283e76":"setMintPrice(uint256,int256)","aa284a4a":"ProofPublicVote(address)","aa289b15":"deleteOutStreamOf(address)","aa28b89f":"preICOStage()","aa29787e":"bonus15end()","aa2a006d":"OrderCancelled(uint256,uint256)","aa2a1c47":"getTotalCollectedFrom(uint64,address,address)","aa2b5d7d":"getMiningWarPlayerData(address)","aa2bebb7":"getFeeWindowByTimestamp(uint256)","aa2d5c05":"FillOrder(uint256,address,uint256)","aa2de6c3":"minimumPurchase()","aa2df88b":"_isTransferAllowed(address,address,uint256)","aa2e7ea0":"createSwap(bytes20,address,uint256,address)","aa2efbad":"nominsReceivedForEther(uint256)","aa2f7494":"createMobster(string,uint256,uint256)","aa2f892d":"requestRedeem(uint256)","aa2fc145":"numStageRecalc(uint256)","aa2fddc7":"transfer(string,address,uint256)","aa3022d0":"settotal(uint256)","aa306d79":"voteForCandidate_(uint256,address)","aa30abf1":"crowdsaleBurnAddress()","aa30b7e3":"hasEnoughValidSignatures(bytes,uint8[],bytes32[],bytes32[],address[],uint256)","aa31aee8":"getLockTime(address)","aa31e4a0":"setSelfHybridizationPrice(uint256)","aa33171f":"newPromotion(string,string,string,uint256,uint256,uint256,uint256)","aa332032":"NewRound(string,bytes32)","aa33ab1b":"getVoted(uint256)","aa3435c0":"setTokenInformation(string,string,uint8)","aa351cf5":"triggerShutdown(uint256)","aa352ca4":"withdrawOffer()","aa3633f3":"CreationFailedEvent(address,uint256,string)","aa366290":"forfeit(uint8)","aa367664":"fundingMaximumTargetInWei()","aa368c19":"createScore(string,string,uint256,uint256,uint256,uint256,string,string,string,string,string)","aa36aae8":"prolongCrowdsale()","aa36b52e":"_updateNeeded(uint256,uint256,uint256)","aa3744bd":"recipient1()","aa3801d8":"getTokenAddress(bytes)","aa391317":"returnUnsoldSafeMedium()","aa3ad4e4":"validate(address,address,uint256)","aa3aef50":"purchaseTicket(uint16,uint16[])","aa3ba179":"widthraw()","aa3dacac":"sideBetPercent_MAX()","aa3eb769":"sendPTokenFrom(address,uint256,address)","aa3ec0a9":"cid()","aa3ef248":"postFact(bytes16,address,string)","aa3f5087":"AuctusPreSaleDistribution()","aa404876":"RedBlueToken2()","aa41d605":"_estimateWeight(uint256,uint256,uint256,uint256,uint256)","aa421944":"setMaxVeriAmount(uint32)","aa430e64":"setTotalPhases(uint256)","aa4537b2":"referredBonusRate()","aa454e9c":"setBuyer(uint256)","aa45b11e":"setReferralAddressShare(uint256)","aa462a5a":"whenGameDies()","aa4859fd":"newBookingfc(uint256,address,uint256,uint256,uint256)","aa487f49":"PRESALE_PERCENTAGE_1()","aa4925d7":"subscribe(uint256,uint256,address)","aa497b9d":"scheduleCall(address,uint256,bytes,uint256,uint256,uint8)","aa4abe7f":"setMaxRate(uint256)","aa4ac835":"exportTankResetEarning(uint32)","aa4b4d0b":"test_v0()","aa4b62f3":"initData(address,uint256)","aa4b980e":"phase_1_bonus()","aa4bdd3b":"realEtherCapHash()","aa4cb547":"setMultihash(bytes32,bytes)","aa4cc01f":"checkIfCancelled(bytes32)","aa4cd810":"addMeterPoint(address,int256)","aa4ce2c6":"blockDotBlockHash(uint256)","aa4d4213":"getOldAllowance(address,address)","aa4d490b":"registerNameXaddrFromDapp(address,bytes32,address,bool)","aa4eaa72":"addToPreSaleWhitelist(address,address)","aa4ee730":"LastRiskPrice()","aa4f6012":"addSupply(address,uint256)","aa4fc0a1":"Talius()","aa510c8c":"getLinkToPostId(string)","aa513c71":"updateInfluencer(string,address,uint256,address)","aa51793c":"isLosingBet(uint256)","aa525c55":"removeMilestone(uint8)","aa52a251":"transferSnowflakeBalanceFrom(string,string,uint256)","aa52fbd4":"period2Denominator()","aa534161":"releasedTeamTokens()","aa53d504":"Bounty()","aa53d7d4":"gettotalReceivedTicket()","aa541c9f":"unfroze_contract()","aa54abb1":"setLSEscrowContractAddress(address)","aa54ad35":"tokenSaleAddr()","aa54e040":"change_rate(uint256)","aa5581ef":"weiMaximumLimit()","aa5583d7":"Connections()","aa55a1a2":"giveAdditionalTokens(address,uint256)","aa55b55f":"getCardTypeInfo(uint256)","aa56c8e7":"isCrowdsaleFinished()","aa585d56":"setPrice(uint256,uint256,uint256)","aa58d4df":"calculateWinnerGameType2(uint256,uint256)","aa590140":"length(int8)","aa59770f":"sendCreatorByOwner(address,uint256)","aa59b024":"CROSAIR_SHIP_LIMIT()","aa59fb7d":"ChemistryCore()","aa5a11c5":"removeTellerModerator(address)","aa5a20e5":"setUpgradeAgent(address,uint32)","aa5b7df8":"marketingTokensWallet()","aa5b95d1":"deathFactor_i()","aa5c02a3":"LETX()","aa5c3ab4":"rewardBalance()","aa5c88ca":"setFreezePercent(uint8)","aa5d4719":"getTransferable(bytes20)","aa5d6d5f":"dropWallet()","aa5dcecc":"allocator()","aa5dd215":"doAirDrop(address[],address,uint256[])","aa5df9e2":"ownersArr(uint256)","aa5e2500":"clearProposalNames()","aa5ebd7f":"removeAddressFromWhitelist(address,address)","aa60145b":"cancelPledge(address)","aa601a71":"setAllowChangePrice(bool)","aa601e86":"SimpleMultiSigWallet(address[],uint256)","aa613b29":"authenticate(string)","aa613faf":"U42Token()","aa616da1":"addSkillNames(address,bytes32[],address)","aa617f25":"getAdUrl(uint256)","aa61924a":"CREATE_VERSION_ROLE()","aa61fc58":"getAirdropList(address)","aa620192":"today(uint256)","aa6217eb":"getMaximumContributionPossible()","aa628c31":"timelock(address,uint256)","aa63dea4":"dateMainStart()","aa646ebb":"_mint(address,uint256,uint128)","aa647673":"getKingPoints()","aa64c43b":"transferPool(address,address,uint256)","aa64f3c6":"addWhiteListed(address[])","aa656a3a":"updateGameMoney(uint256,uint256,uint256,uint256)","aa657658":"setMigrationGate(address)","aa657815":"takeoffer(uint256,uint256)","aa65a6c0":"getTokenWithId(uint256)","aa65c1f1":"WinningOutcomeDeclared(uint8)","aa66797b":"RESERVE_SUPPLY()","aa677354":"register(address,address)","aa67bc04":"eraByName(bytes32)","aa67c919":"depositFor(address)","aa682682":"startBuyTime()","aa68894b":"ownerWithdrawAccount(address)","aa692151":"fbytes32(bytes32)","aa6aca58":"setDelegadoDeEscuelaVerify(bytes32,bytes32,uint8,uint8)","aa6b5d9f":"ElyToken(address,bool)","aa6b631a":"getSetting(string)","aa6be303":"debtors(address)","aa6bf687":"calculateBonus(bytes32,uint256)","aa6ca808":"getTokens()","aa6d5dce":"_withdrawAllFunds()","aa6d7de4":"Hash()","aa6e4858":"VoteAdvertisement(uint256,address)","aa6e6539":"chkUserDetails(address,address)","aa6ebdcb":"numberOfDAppNodePackages()","aa6f5bb6":"setCreateDigitalArtFee(uint128)","aa727e46":"MAX_PUBLIC_FUNDING_SUPPLY()","aa72f217":"bountyMktWallet()","aa72f725":"listAssetDocuments(bytes32,uint256,bool)","aa735dd6":"ZBAStandardToken(uint256,string,uint8,string)","aa736f57":"transferLocker(address)","aa743c85":"sixMatchPayoutInPercent()","aa74c9fc":"addressToURI(address)","aa74fad8":"buyNewInfra(uint256)","aa7517e1":"minimumBond()","aa7618d5":"increaseApprovalPreSigned(address,uint256,uint256,uint256,uint8,bytes)","aa7622c7":"finalizeSecondStage()","aa7629ab":"withdrawDRPS(uint256)","aa76994d":"numOverthrows()","aa772fa0":"WinningEvent(address[],address,uint256)","aa775278":"deallocateBalance(address)","aa77f26c":"vestedAmount(address,address)","aa78a883":"BDP()","aa79376e":"updatePlayersCookie(address)","aa799fdc":"ZeroxDinar()","aa79bc02":"maxTrophies()","aa7a7744":"isRegisteredPair(address,address)","aa7abc8d":"sellWonder(uint256,uint256)","aa7b6c59":"wirteData(string)","aa7bc1c0":"createTokenFunctions()","aa7be9a7":"watchVideoA(address)","aa7ca464":"didReveal(address,uint256)","aa7dcd84":"testUpdateAuthorityEvent()","aa7ebf43":"level_1_percent()","aa7f6a3f":"AirdropList(address[],uint256[])","aa7f6a61":"newPurchase(address,uint8,uint8,uint32)","aa804a80":"jdouble(uint256,uint256,uint256)","aa80eec8":"testCheckRokBounty()","aa8116be":"fundedPrincipal()","aa81f862":"numDepositsSigned(bytes32)","aa833a25":"TheTokenC()","aa848ee2":"setPrivateList(address)","aa84d4b1":"whitelistOff()","aa84edb8":"MYDLToken()","aa85048a":"TotalCrowdsaleSupply()","aa8596ea":"setGalleryFivePrice(uint256)","aa863759":"addtoTechOperation(address,address,uint256,uint256)","aa864e49":"remainingPoolOptions()","aa8675d1":"singleIDXMQty()","aa86fbc5":"HETCCStandardToken(uint256,string,uint8,string)","aa8713dd":"secondWeek()","aa877470":"isInsurance(address)","aa879119":"allowApprovee(address,bool)","aa87af1e":"voirMessage()","aa88bb5b":"resolveDispute(uint16,address,address,uint8)","aa89376a":"Example2(string)","aa8a0002":"raiseLimit()","aa8b20f6":"getAvatar()","aa8b76ea":"reclaimDividend(uint256)","aa8b99d2":"length(uint256)","aa8c217c":"amount()","aa8c5324":"prolongate()","aa8d11e3":"ThirdPartyVoter()","aa8d715d":"itemBalance(address)","aa8dd5a1":"GRForGas()","aa8dde58":"Repost(bytes32,bytes32,uint256)","aa8dea8c":"fipsAddToLedger(bytes20,address,bytes)","aa8e8fb0":"LTKN()","aa8f0269":"ScicoinsICO()","aa8f027b":"isEmoji()","aa8f365c":"test_invalidProposalValue()","aa8f44ec":"isSaleAddr(address)","aa91cc61":"rodToken()","aa91d5c5":"HappyEnding()","aa9224cd":"withdraw(uint32)","aa9246ef":"_parseIntScientific(string,uint256)","aa93038b":"reward_total()","aa931697":"minNac()","aa93334d":"currentPeriodStartBlock()","aa9449f2":"Test(address)","aa9454b5":"transferAndBuy(address,uint256,uint256,uint256)","aa954845":"isConfirmed(bytes)","aa9669c1":"roll(uint256,bytes)","aa974eff":"multitokens(uint256)","aa985a63":"distributeWei(uint256,uint256)","aa98a41a":"setGenesisAddressArray(address[],address)","aa98d57b":"calcCollectedFee(uint256)","aa99474f":"authorized_changeOwnership(address,address,uint256)","aa994ab8":"transferGIM(address,address,uint256)","aa999b4c":"mixDna(uint256,uint256,uint256)","aa99ebb6":"CheckTimestampsDuringOneDay(address)","aa99f4d0":"teamTwoId()","aa9a0912":"mulDiv(uint256,uint256,uint256)","aa9a2cf0":"host_percentage()","aa9a79f2":"SubBankerPrincipal(uint8,uint256)","aa9ad331":"NEON()","aa9b5ba8":"getPaidDIVDSchedule()","aa9cdaf4":"coinAge(address)","aa9e40e0":"confirmDebt(uint256)","aa9f3666":"ClassicToken(string,string,uint8,uint256)","aa9f37f0":"purchaseContract()","aa9f5477":"Nursicoin()","aa9fa274":"addExtraReceiver(uint256,address)","aaa006b2":"countPlayer()","aaa04812":"presaleEthAmountsProcessed()","aaa05e20":"cityTransferResources(uint256,uint256,uint256,uint256)","aaa08e9b":"testBonus()","aaa0f5cc":"userAlreadyBoughtEth(address)","aaa24d31":"deathData_f7()","aaa2b78f":"allowedWithdraw()","aaa2b8c8":"rootAddress()","aaa2fe13":"getMin(uint8[])","aaa3de26":"getUsersInfo()","aaa40bc7":"TUXToken()","aaa44e5c":"getAllIds()","aaa51ec6":"setStoreAddress(address,address)","aaa5a02a":"claimTimeout(bytes32)","aaa5ad61":"getTokensAvailable()","aaa668aa":"getUserTenantId(address)","aaa6bc40":"removeWhitelistedUserAddr(address)","aaa7062b":"posShare()","aaa71e45":"mininglock()","aaa7744b":"_subjectToFees(address,uint256)","aaa77f55":"wuxiaMaster()","aaa99809":"FlatPricingExt(uint256,bool)","aaaa3218":"EmpireCrowdsale(uint256,uint256,address,address,uint256,uint256,uint256)","aaab3025":"replaceAbility(uint256,string,bool,uint8,uint8,uint8,uint256,uint256)","aaab51c9":"close(uint256,bytes,uint256,uint8[],bytes32[],bytes32[])","aaabdf16":"reputationIRNNodeShare()","aaac205b":"ZeenCoin()","aaac50bd":"transferDisable(bytes32)","aaac8040":"referralAmount(uint256,bool)","aaac9718":"package()","aaad0c84":"isExisted(address)","aaadc832":"isRedeeming()","aaae05b2":"approvePreSignedCheck(address,address,uint256,uint256,uint256,uint8,bytes)","aaae7799":"insertUser(uint256,bytes32)","aaaea138":"testFailBurnWhenStopped()","aaaf8a52":"approvePrimordialToken(address,uint256)","aaaf9595":"_generateTokens(address,uint256)","aab0395b":"LandToken()","aab065e8":"LifChannels(address,uint256)","aab14d04":"orderState(bytes32)","aab27ad1":"depositaCaucao()","aab324ae":"transferAnyERC20Token(address,uint256,address)","aab32cfa":"VerifierRegistry(address,uint256)","aab402e5":"toggleSale(bool)","aab40661":"_fishAquarium(uint256)","aab52c33":"initGameTeam(uint8)","aab60ebc":"totalLockedRewardsOf(address)","aab633dc":"private_setmaxRoll(uint256)","aab6606e":"BalanceEth()","aab725b3":"icoTokensSold()","aab75253":"StaffPicks()","aab78bf5":"compensateLatestMonarch(uint256,uint256)","aab8f6e0":"airdropBy0Eth()","aab99609":"ApaAjaToken()","aab9f165":"processPayment(uint256,uint32,uint32,uint256)","aaba2fb8":"UnicornRanch()","aaba3e3b":"getSymbol(string)","aabb3d61":"MainBridge(uint256,address[],uint256,uint256,uint256)","aabbb8ca":"getInterfaceImplementer(address,bytes32)","aabbd0ce":"approveNewShorter(address)","aabd3904":"isCreating(uint256)","aabd46e3":"getMintRequestStringMap(uint256,int256,string)","aabd5b88":"_sold()","aabd971e":"presaleTransfersPaused()","aabda436":"fund_()","aabdf682":"FINTRUX_RESERVE()","aabe00c4":"verifyPreSupport(uint256)","aabe2fe3":"currentWinner()","aabe7dc4":"unlockRewardToken(address)","aabecb89":"setRate10(uint256)","aabf05cf":"set_presale_iconiq_arbits_per_ether(address,uint256)","aabf382b":"upgradeLevel(uint8)","aabf901a":"Distributor(uint256,address)","aac0d9c2":"CompanyReserve(address,uint256)","aac0e4c5":"getPendingSignatureStatus(address)","aac1335c":"tgeSettingsMaxStages()","aac1b0b7":"safeExchange(address,address,uint256)","aac1c80b":"getCompte_12()","aac24374":"setBoxPrice(uint256,uint256,uint256)","aac2c717":"buyXaddrWithInviteCode(address,uint256)","aac3e314":"setPrevOracle(address)","aac4e3a8":"whiteListingAdmin()","aac57b3a":"newAPM(bytes32,bytes32,address)","aac5ab61":"Crowdsale(address)","aac5ce9a":"Stakeholder()","aac67b05":"changeFactoryUsageFee(uint256)","aac6ba41":"setModel(address[],uint256[])","aac746ee":"getNameFromAddress(address)","aac74c92":"getPI_edit_30()","aac756b8":"setxiudao(address,uint256,bool)","aac80472":"getManagerAddress(uint256)","aac81654":"isNoEmptyTranches()","aac8788a":"setIncrementOpenInterest(bool)","aac878eb":"approveTransaction(uint256,bytes)","aacaa602":"getCurrentAmountBonusRate(uint256)","aacb15e6":"_validate(uint256,uint256,uint256,uint256)","aacb4442":"repaintVoxel(uint8,uint8,uint8,uint8)","aacbe4b3":"set_maxUETsPerReturnLessThan(uint256)","aacc3a16":"printAddress(address[3],address)","aacc5a17":"getRandom()","aacd572f":"private_setMinRollUnder(uint256)","aacd5a85":"orderTrade(uint256,uint256,uint256)","aacd9794":"setUniqueSpinnerPrice(uint256)","aacdb27b":"setPixel(uint32,uint32,uint8)","aacec70b":"createCrySolObject(string,uint256,uint16,uint16,uint8,uint8)","aacf3f2e":"contributionInCauldronRound(uint8,address,uint32)","aacf5328":"setVideoID(string,uint256)","aacfd352":"blockBeforeEncounter(uint256)","aacffccf":"getAccountOwner(bytes32)","aad00089":"tokenIssue(uint256)","aad0bb90":"TEMath(uint256,uint256,bool)","aad12029":"freezeAccounts(address[])","aad13b15":"fight(address,string)","aad2b723":"changeSigner(address)","aad3ec96":"claim(address,uint256)","aad41a41":"multisend(address[],uint256[])","aad429f1":"_buyCommonTTW(uint256,uint256,address,address)","aad52373":"ValidateAndStore(bytes,bytes)","aad55726":"getContract(address,uint256)","aad5632a":"generateNext()","aad62da2":"left89(uint256)","aad71040":"changeUnlockTime(uint256,uint256)","aad7152b":"updateTokenTransferAddress(address)","aad83ab3":"SpinTestToken()","aad85f7c":"setAchievedDate(uint256,uint64,uint64)","aad935af":"updateSellPossible(bool)","aad99ef1":"setPriceIncreaseScale(uint256)","aad9afee":"kingsMessage()","aada1cb3":"activateUniqueSpinners()","aada4b06":"saleIssue(address,uint256)","aadad773":"removeServer(uint256)","aadba3dc":"finishWhen()","aadbc52d":"addContractMember(address,bytes32,address)","aadbc5a0":"getMatches(uint256,address,uint256)","aadc0a9d":"sneakUpOn()","aadc1ac1":"approveLoan(uint256)","aadc3b72":"hasVoted(bytes32,address)","aadc8f23":"RogueProtocol(address)","aadd1b03":"donateEth()","aade1323":"_processUpdateFee(address[16],uint256)","aade53fe":"_removeCardSetAtIndex(uint256,uint256)","aade84ae":"TopIvy()","aade8dcc":"discountTokenPercent()","aade9bb4":"icoReturnBonus(uint256)","aadf017e":"_processReserve(address,uint256,address)","aadf1e73":"selectWinner30()","aadf6838":"getOldSchoolCoins()","aae07890":"setUnit(uint256)","aae07cd0":"getTokenLayers(uint256)","aae0ff1e":"incLuckyCoin(address,uint256)","aae1f5c3":"processDonate(address)","aae233b4":"cleanUpPreviousRound()","aae3d025":"transferClose()","aae3d031":"enableKYC()","aae40ddc":"getCurrentClaimerForTile(uint16)","aae4cbe4":"EcoToken()","aae62507":"getUnavailableValueT(bytes32)","aae755af":"m_currentUsdAccepted()","aae764c1":"assertFalse(bool,bytes32)","aae8312e":"getStakeholderTransactionCount(bool,bool)","aae8e1b3":"withdrawFlag(address,uint256,uint256)","aae99c66":"whitelistAddress(address[],bool)","aae9a4c7":"singleInvestorCap()","aae9d7ed":"__callback(bytes32,uint256)","aaea144d":"setPackage(bytes1[42])","aaea396c":"verifiedlist(address)","aaea4472":"LifeFactor_ii()","aaea44c4":"strConcat(bytes,string,bytes)","aaea53f3":"Channel(address,uint256)","aaeaa36c":"isBatchSupported()","aaead0f0":"initializeIndividualCapsFundraiser(uint256,uint256)","aaeb3255":"getInsuranceIDsByClient(address)","aaec0c03":"FireflyRegistrar(address,bytes32,address)","aaec2fa5":"getGirlsAuctionPrice(uint256)","aaecc9cf":"checkGameOver()","aaed2c3d":"getRewardRate(address,address)","aaed31c7":"createCoins(address)","aaed3c7d":"tokenBuyersAmount()","aaee686e":"confirmTransactionFee(uint256)","aaeea585":"DMToken()","aaef36b5":"CorvinusCoin()","aaf04471":"transferAndCallDelegated(address,address,uint256,bytes,uint256,uint256,uint256,bytes)","aaf05f3d":"f3()","aaf10f42":"getImplementation()","aaf13d10":"Wallet3()","aaf20486":"ProofOfLongHodl()","aaf3e4f4":"left88(uint256)","aaf47835":"acceptBuyOffer(uint32,uint256)","aaf49910":"sanMinLength()","aaf4f1ed":"setMinDailyPerUser(uint256)","aaf517f5":"GetRoundIndex(uint8)","aaf592bf":"receiveApproval(uint256[])","aaf5eb68":"PRECISION()","aaf73ef7":"registeredDeals()","aaf7e700":"setResetvalue(uint256)","aaf809f8":"_isUnique(uint256[],uint256)","aaf885f8":"getRazInstanceInformation(uint256,uint256)","aaf9419d":"latestNewRockForSale()","aaf9d13e":"buyTopDog(uint256,uint256)","aafa4827":"KOIOSTokenSale(address,uint256,uint256,uint256,uint256,address)","aafab1e8":"paymentsCount()","aafafbf3":"multiSendEth(address[])","aafb088e":"stageDuration()","aafba184":"removeShareholderListing(uint256)","aafbb120":"getSaleInfo(address)","aafbd3da":"create(bytes32,address,bytes32,bytes32,address,bytes32)","aafbe1c0":"NectarController(address,address)","aafd775e":"getLockedBalanceForUser(address,address)","aaff096d":"updateDarknodeRegistry(address)","aaff2a83":"totalRemainingTokensForSales()","aaffadf3":"minContribution()","aaffc4b6":"currentRoundCount()","ab004a97":"traded_token_seed_amount()","ab021884":"setMinimumPriceFusion(uint256)","ab022b28":"resetAirdropAmount()","ab02f27c":"Europium()","ab03cf46":"sendFunds(uint256,address,bytes)","ab03d0e8":"changeUnitsUserCanBuyLimitEth(uint256)","ab040107":"decline()","ab044622":"syndicateTokensWithdrawn()","ab045871":"Indemnisation_2()","ab051767":"userlogout(address)","ab05a69a":"InbotProxy(address,address,address,address)","ab05bfff":"setReleaseTime(uint256)","ab062643":"getNumTokensPurchased()","ab065d6c":"getProjectClient(bytes32)","ab067a5b":"periodSales()","ab06bea3":"reportContribution(address,uint256)","ab06da29":"setUTExchangeRate(uint256)","ab074225":"BLOOToken()","ab0783da":"mat()","ab07f054":"getLandPrice(int32,int32)","ab080aab":"SecondBiathlonToken(address,address,string,string,uint256,address)","ab08d048":"SPAYToken()","ab08f75b":"getMoneyline()","ab09ee80":"respond(uint256,uint256,uint256,uint256)","ab0a9865":"createGen0Dog(uint256)","ab0b29a5":"applySetMaxFeeTrade()","ab0bcc41":"saleStart()","ab0cba56":"ICO(uint256,uint256,uint256,uint256,address)","ab0cd5bc":"createMineForToken(uint256)","ab0ced0e":"checkContribution(address)","ab0cf8b7":"Wolf()","ab0d92dd":"totalPrice()","ab0da5a9":"reject(address)","ab0db220":"createBattle(uint256,uint256[],bytes32,uint256)","ab0e6765":"setEmployer(address,address,string)","ab0eda9e":"setAirdropAddress(address)","ab0facc0":"raiseLimit(uint256)","ab0fd373":"matchTimestamp(bytes32,bytes32)","ab0fe874":"purchaseCap()","ab108915":"createUser(address,bytes20,uint64)","ab1193fa":"PREMINE_ALLOCATION_ADDED(address,uint256)","ab11ebdd":"returnIcoTokens(address,uint256)","ab127a0c":"searchBestRate(address,address,uint256)","ab1377c0":"startSeedStage()","ab14a41f":"reentrancyHelper(address,bytes,uint256)","ab150226":"checkAdmin()","ab1547d2":"nextOpenRewardTime_()","ab15d70c":"updateFifthExhangeRate(uint256)","ab15f723":"pauseMints()","ab165623":"TalentEducationToken()","ab165831":"checkContractAddress(address)","ab16cef1":"addBigPromoBonus(uint256)","ab17176c":"VCCToken(uint256,string,string)","ab172cf5":"getCandidateByIndex(uint256)","ab179e9f":"currentReleaseCeiling()","ab17bad0":"setGasConsume(uint256)","ab18af27":"setDepositAddress(address)","ab18f6ac":"parseTimestampToYM(uint256)","ab19d396":"couponTokenCampaignAddr()","ab19fff9":"TokenFrank()","ab1a84da":"isCrowdfundCompleted()","ab1ac9f6":"BITSDToken()","ab1b1cb5":"getSubscriptionLastPaid()","ab1b3830":"EIForceCoin()","ab1b75f2":"burnUnpaidTokens()","ab1bef4e":"getDailyTickets(address)","ab1d3add":"assignDispute(string,address,string)","ab1d581b":"checkPet(uint64)","ab1e96e9":"migrationPeriod()","ab1ebb4d":"OneMillionToken()","ab1f7929":"setMigrationInfo(string)","ab207628":"getAffiliateAmount(uint256)","ab209e23":"Manifesto(uint256,uint256)","ab2191a2":"Satanshi()","ab21b055":"getTickets(string)","ab21d58a":"enableCharity()","ab225edc":"DepositFund()","ab22a640":"getVideoGameOwner(uint256)","ab22c561":"getVestingCliff(address,address)","ab231511":"lastWithdrawTime()","ab23c50d":"AirDropAFTK3SeptSandBox()","ab253ca6":"buyMinions(uint8)","ab2643a1":"commitCollateralToPool(address,uint256)","ab273016":"signProposal(uint256)","ab27be20":"mine(address,uint256)","ab27d755":"confirmOrder(bytes16)","ab2874cb":"buySlot(uint256)","ab28c704":"initialSupportAmount()","ab28e8af":"serviceTokensBurn(address,address)","ab2a4f8a":"transferRevenue(address,address,uint256)","ab2a5772":"setIcoHardCap(uint256)","ab2a6dc1":"dealsGetter(address,uint256)","ab2af349":"CallCancelled(bytes32)","ab2c8b16":"fundingLowcapReached()","ab2e5a1f":"play(uint256,uint256,uint256)","ab2ebcf1":"priceExpirationInterval()","ab2f0e51":"availableBalance()","ab32775c":"alreadyContains(uint256[],uint256,uint256)","ab331a34":"getProperty(string)","ab33cbcf":"inxCrowdsale()","ab34dc48":"monechainToken()","ab351270":"lottery(address,uint256)","ab3545e5":"getMember(uint256)","ab35678c":"trackCount()","ab3640c8":"processPayment(address,uint256,bytes32)","ab36e4a6":"milestonesCount()","ab37594b":"cancelOrderByMerchant(string)","ab383a6b":"getPropertyPrivateModeBecomePublic(uint16)","ab3860d0":"test_twoValidEqUint()","ab3a32c4":"refundAllExternalPurchase(address)","ab3a39c2":"scamSealTokenAddress()","ab3b87fe":"setOwner(address,uint256)","ab3bd81f":"changeTuneOption(uint32,uint32,uint256,bool,bool,uint128,bool,uint64,uint256)","ab3bfac4":"freezeBalance(address,uint256)","ab3c04d3":"BAKEToken()","ab3cdaf0":"PRE_ICO_BONUS_TIME_2()","ab3d2e74":"_clearApproval(uint256)","ab3d4e8b":"MembershipPurchase(address,uint256,uint256)","ab3dd698":"airdropDiff(uint256[],address[])","ab3e9c56":"ChangedInitialPrice(uint256)","ab3ed9f0":"DecisionToken()","ab3efa83":"tokenSafeLock(uint256,uint256,uint256,uint256)","ab3f22d5":"allocate(address,uint256,uint256)","ab3f699c":"getOrCreateNextFeeWindowWasCalled()","ab400d86":"updatePlayerEth(address,uint256,address)","ab40340a":"recordWithdraw(uint256,address,uint256)","ab40b01f":"getAddressAnswerKeccak256(uint256,address,address)","ab40b65a":"receiveapproval(address,uint256,address)","ab413a7e":"getScoreAndCount(address)","ab4215cc":"getDataOfGame()","ab430d49":"transferToken_toInvestBalance(address,uint256)","ab442c59":"getICOToken()","ab4459bc":"releaseBountyTokens()","ab447007":"setClaimDate(uint256)","ab45e2a0":"processPurchase(address)","ab464a4c":"launch_date()","ab464fa6":"transferMultiDiff(address[],uint256[])","ab46cc46":"add_attender(string[])","ab470f05":"getCaller()","ab473f48":"closeFunding(uint256)","ab47f1bf":"getFilledAmount(uint256)","ab4865ec":"boardTokensAddress()","ab486607":"getLeaderboardLength()","ab489f08":"toBytes(address[])","ab48f2f8":"PlayNow()","ab4955c2":"ReserveWalletUpdated(address,address)","ab4a2eb3":"getUnlockableTokens(address)","ab4b4def":"WITHDRAWAL_SCALE()","ab4bc414":"bitbgcToken()","ab4bf05e":"addSignature(string,int256,string)","ab4c4487":"getSystemSalePrices()","ab4d0ca9":"multiAdd(address[])","ab4e21c4":"OneBlocToken()","ab4e8ef1":"getAirdropTokens()","ab4ef895":"MB()","ab4f643c":"PublisherParametersChanged(address)","ab4fa078":"ListAllSince(uint256)","ab503e30":"SetminTokens(uint256)","ab50bc86":"PubRegistered(address)","ab50e7f2":"third_release(uint256)","ab5170b2":"getstr()","ab519020":"calcShare(uint256,uint256)","ab51937b":"startproduction()","ab519b0c":"prepare(uint256,address,address,uint256,bytes)","ab51b06f":"preSaleBonus()","ab531efd":"_encodeTokenId(uint256,uint256)","ab5366dd":"pendingOwner2()","ab54775d":"lookupSigName(address,address)","ab55979d":"changeStaker(address)","ab55d1cc":"getDAIBalance()","ab5690c4":"enableWithdrawals(address,address)","ab56c09e":"Placed(uint256,uint8,address)","ab5706ee":"setBaseSummonPrice(uint256)","ab5783c4":"StopGame(uint8)","ab582eb3":"kickOwner(address)","ab5841f2":"updateReserve(address,uint32,bool,uint256)","ab590032":"cleanAssetHolders()","ab5a7076":"RadiumToken(address)","ab5aa302":"_START_DATE()","ab5aea81":"Menu07(address)","ab5b4456":"use(uint256)","ab5db036":"refundICO(address)","ab5e28c5":"transfers()","ab5e5158":"setNewManager(address,address)","ab5ed150":"getOne()","ab5efded":"OmegaToken(address,address)","ab5f3380":"getVineyard(string,address,uint256)","ab5f6b91":"multiCreate(uint256,uint256,uint256)","ab5fa2c6":"setITO(address)","ab60443b":"changeInviteRate(uint256)","ab605eea":"fighterIndexToApproved(uint256)","ab60e4e5":"setWebGiftOnceMaxAmount(uint256)","ab60ffda":"exp()","ab61787a":"proofFailed(address,uint256,uint256)","ab619e5a":"StandardToken(string,string)","ab6231f1":"RefundedETH(address,uint256)","ab62438f":"submitImpeachmentProposal(string,address)","ab624cf1":"setPartyA(address)","ab630fc4":"kimsOnAuction()","ab635b48":"createTokenVestingContract(address)","ab643c07":"getAllBounties()","ab64611b":"BitmarkPaymentGateway(address)","ab651065":"setESCBCoin(address,address,address,uint256,uint256)","ab65c534":"SqueezeTheJuice()","ab65cda6":"getDial2Type(uint8)","ab65f20a":"mintCards(uint256[],address)","ab6680f3":"initAuction(uint256,uint256,uint256,uint256,uint256,address,bool)","ab67aa58":"transferFrom(address,address,uint256,bytes)","ab686d0a":"setFrontWindow(address)","ab6a5d95":"changeBoardAddress(address)","ab6a9f0e":"knockoutTeam(uint256,uint256)","ab6ad452":"unlockedBalance()","ab6ae424":"affWallet()","ab6b551e":"isSideBridgeContract()","ab6b7e22":"grantBounty(address,uint256)","ab6bfe78":"Hongshanchain(uint256,string,string)","ab6c291b":"getWiningType(uint256)","ab6c5f58":"removePlayer(uint256,uint8)","ab6cab71":"PoWH4DSupply()","ab6cb831":"UNIToken(uint256)","ab6cf42f":"isReservationFull()","ab6d8a9a":"gemFab()","ab6da028":"TOKEN_FOR_COMUNITY()","ab6db199":"dias()","ab6ddfa8":"holderBalance(address)","ab6def1c":"isShareToken()","ab6e1be4":"getTs()","ab6e4959":"depositsOfMember(address)","ab6e79ed":"getBaseToQuoteReturn(uint256)","ab6e9072":"admin_wallet()","ab6e988c":"playerVault(address)","ab6ef0b1":"purchaseLandWithCC(uint8,bytes32,uint256)","ab6f78f0":"SetRecord(address)","ab6f9e4a":"votesPerChoice(uint8)","ab700624":"toWidthString(string,uint256)","ab701ca3":"_upgradeabilityOwner()","ab702d48":"train2(uint256,uint256)","ab70bba7":"OtxToken()","ab70d0c5":"_getEndWeek(uint256,uint256)","ab70ee5c":"PoloneumToken()","ab71b8ac":"maxBountyTokens()","ab727094":"reinvestDivies()","ab731fd6":"ownerSetOverride(address,address,bool)","ab736b5d":"checkUniqueLockedTokenReceivers()","ab73e316":"next(address)","ab73f08e":"findOptionId(address)","ab74731d":"dividendPayment()","ab75a4a2":"angelWheelFinancing()","ab75e6c8":"DTXTestToken()","ab7748da":"Blocker_resume(bool)","ab779505":"NettingChannelContract(address,address,address,address,uint256)","ab77b178":"issueCoin(address,uint256)","ab7891f5":"deleteSiringWithId(uint256)","ab79fd26":"setBeginTimeTS(uint256)","ab7a162f":"getInterCryptoPrice()","ab7a9691":"isReleaseAgent(address)","ab7aa65d":"icoThresholdBonus2()","ab7af62f":"setAttackBoostMultipler(uint256)","ab7b347c":"BitcoinDominatorERC20Token()","ab7b47aa":"_generateInitialPattern()","ab7cb211":"allowBuy()","ab7ccc1c":"credit(uint256,uint256)","ab7df819":"Simscoin()","ab7e50ba":"GAX()","ab7e9dca":"getPrivilegedBalance(address)","ab7ebbce":"startPresale(address)","ab7ec692":"primoContratto()","ab7f8f12":"masicotestToken()","ab802509":"setMintAgent(address)","ab80c807":"RareCoin(address)","ab81e773":"left61(uint256)","ab82d9a0":"challenge(uint256)","ab831144":"parseUint(bytes32)","ab834bab":"atomicMatch_(address[14],uint256[18],uint8[8],bytes,bytes,bytes,bytes,bytes,bytes,uint8[2],bytes32[5])","ab840808":"migrateBasicData(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","ab8425d8":"set_amount(uint256)","ab84db68":"releaseArr()","ab850a85":"mintGold(uint256)","ab8530f8":"Mint(address,address,uint256)","ab8620dd":"getStageSoldTokens()","ab86ba3a":"bonus3()","ab86e0a6":"_setBalance(address,uint256)","ab87d816":"getPerson(uint32)","ab883d28":"multisendEther(address[],uint256[])","ab888539":"setIdentifier(address,bytes32)","ab889df9":"DoradoToken()","ab89641b":"getTlength50()","ab89d8c6":"WGWToken()","ab89f2c7":"getCurrentStageId()","ab89f870":"setMultiple(uint256)","ab8a0360":"Auth()","ab8a1595":"test_25_assertGasUsage1400Boards()","ab8a288b":"checkStoredFile(string)","ab8be231":"setMockedTime(uint256)","ab8ca6e9":"getBonusTier(uint8)","ab8d01b8":"transferFromToUpdateToken(address,address,uint256)","ab8d1daf":"payTokenOwner(address,uint256)","ab8d3dc1":"TokenPing(uint256)","ab8e0f6e":"Mmcchain(uint256,string,string)","ab8e5b01":"testGetLastTime()","ab8efb87":"UInt256(int256)","ab8f1957":"investedPeriods(uint256)","ab8f3c98":"validateBroadcasterSig(string,uint256,bytes32,bytes,address)","ab8feb02":"TKN()","ab90602c":"registerTicketsToUser(string,address,uint256)","ab90a8ac":"createSaleTokens()","ab90f855":"maxPromoToons()","ab911060":"assertOnlyFrom(uint256)","ab91154e":"ownerAddSanSlot(address,uint256)","ab91c7b0":"queueLength()","ab9213f3":"addAddressReferrals(address[],address[])","ab92670e":"Franc()","ab929fcd":"submitArticle(string,string,bool)","ab92f290":"addNewDividends(uint256)","ab948370":"KingToken()","ab948374":"gen0EndingPrice()","ab95b586":"getEventTimes()","ab9611f4":"setCancelableAt(uint256)","ab96cc4c":"receivedFunds()","ab96d498":"addPublicFundingWhiteList(address[])","ab96dd18":"earlyStageLasts()","ab97af6c":"initialCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address)","ab97d59d":"getTokenManager()","ab97e196":"revokeAmountVote(uint8)","ab98458e":"getUint80val()","ab989586":"WMCToken(uint256,string,string)","ab998660":"LockMechanismByOwner(address,uint256)","ab998939":"RequireDispose(address)","ab99deb8":"Expread()","ab99e48f":"requestMerge(uint256[])","ab9a5caa":"AEStoken()","ab9a78df":"priceOf(string)","ab9a81c3":"numOfBlocksInMinute()","ab9a913a":"generatedEve()","ab9ae1be":"isCrowdSaleStatePreSale()","ab9af166":"reduceCDFee(uint256)","ab9b8637":"medibitICO(address)","ab9c1758":"cancelMarginCallOnBehalfOfRecurse(address,address,bytes32)","ab9c20d0":"finalizationSuccessHook()","ab9cd37e":"withdraw(uint80)","ab9d8b8b":"circulatingTokens()","ab9d8e4b":"Thankfulness()","ab9dbd07":"getID()","ab9def41":"hardCapTokensAmount()","ab9fe3a1":"importBalances(address,address[])","aba00859":"decBalance(address,uint256)","aba01e5c":"impl_amountOfWorkpointQueue()","aba0e189":"checkGameStatus()","aba1017b":"despawnGladiatorAndAwardCoins(address)","aba133ea":"GVPE_Token()","aba13a2f":"_resetTiles()","aba16a02":"offerToChannels(uint256)","aba222ed":"nodeRegistrationEnabled()","aba23628":"mintPlayers(uint128[],uint256,uint256,uint256)","aba3d017":"windowAt(uint256)","aba46a93":"etapAddressesLimit()","aba47d1a":"getGrapesToBuildWinery()","aba61514":"priceT4()","aba683fa":"Etbccoin()","aba70319":"FreyrTokenLocker()","aba7ad0d":"lotteryFeeVal()","aba88037":"DARKNODE_FEES_NUMERATOR()","aba88766":"claimableHalvingsOf(address)","aba89198":"getCurrentCapacity()","aba8dfbd":"SecondBonus()","aba9650e":"createDepositContract(address)","abaa5f3e":"randomDS_getSessionPubKeyHash()","abaa9916":"allocate()","ababa4a7":"authorize()","ababb2dd":"_tryUnlockBalance(address)","ababe93d":"distributeBondFund()","ababf71b":"GetSummReward(uint256)","abacf5d7":"getBoardUpdateTime(uint256)","abad3466":"createtoken(string,string,uint256)","abadaf9a":"bonusAmount()","abadeb06":"teamPeriodsNumber()","abaed924":"executeOrders(address[],bool[],uint256[],uint256[],address[],address[],address[8][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[])","abaf1de9":"setPublicPrice(uint256,uint256)","abaf5880":"Crowdsale(uint256,uint256,uint256,address)","abaf9457":"localRevenuePercent()","abafaa16":"emitIssue(bytes32,uint256,address)","abb00601":"addUnpausedWallet(address)","abb151c8":"CCICoin()","abb1a33a":"SetHotLists(string)","abb21618":"changeAirdropValue(uint256)","abb254de":"developer_withdraw_ETH()","abb2874f":"DezToken()","abb29f70":"TinyOracleDispatch()","abb2d04b":"editName(string)","abb4108e":"addRoles(uint8[])","abb41fab":"_reward_masternode()","abb43397":"getCanvasBitmap(uint32)","abb46619":"DSCToken(uint256,address)","abb4fe2d":"MiningRigRentalsToken()","abb524a4":"PapyrusSalePhase1(address,address)","abb58d20":"Registry(address,address,address,string)","abb58fd3":"createLink(bytes32)","abb689e1":"payRedemption(uint256)","abb69a1a":"getInvoicesByStatus(address,uint256,uint8)","abb70034":"getChosenNumbers(address,uint256,uint256)","abb721ce":"_deposit()","abb743c8":"setUint(int256,uint256)","abb8c965":"_setOwner(address,bool)","abb9e0bf":"coinIssuedAdvisor()","abb9eef4":"YUNXIN2Token(uint256,string,uint8,string)","abba87c1":"_prestige()","abbadf55":"oobiqoo(address)","abbb4695":"setNotifier(address)","abbbf451":"getRound0MinDuration()","abbc54b0":"changePriceUpdateWaitingTime(uint256)","abbc5d2a":"levToll()","abbc8afa":"teamPoolForFrozenTokens()","abbcb24b":"LEGAL_EXPENSES_ADDR_2()","abbdc272":"checkGameStart()","abbe3056":"stage2Deadline()","abbef24e":"buyDaiWithEth(uint256)","abbf7228":"changeBlocks(uint256,uint256)","abbf94f8":"PlatoniusToken()","abbff658":"Ownable3()","abc1c9fe":"requestForRefund(uint256)","abc21702":"getPI_edit_25()","abc2a40a":"minInvestBTC()","abc2ab75":"FinalizeDispute(address)","abc33778":"Result(bytes32,address,uint256,bool)","abc38cf2":"submitNewClip()","abc3bc92":"getReferrerBalance(address)","abc40f41":"batchWrite(uint256,uint256,string)","abc4558e":"_requireRenewableProduct(uint256)","abc45ddc":"BANKOIN()","abc48a0d":"minerTotalSupply()","abc4cbd3":"transferForTeam(address,uint256)","abc6124f":"Bought(uint256,string,address,uint256,string,string)","abc63d00":"STARTING_TIME()","abc66e82":"dev_fee(uint256)","abc6affb":"publicGetUserHistory(address,uint256)","abc6fd0b":"disburse()","abc897f4":"removeMinterByValue(address)","abc8bc4c":"addBomb(uint8,uint256,uint8,uint8)","abc8c7af":"marketplace()","abc93aee":"left64(uint256)","abc9e8c0":"fetchOrdersForPayer(address)","abca7290":"feeDeposit()","abcafdf8":"prizeProjection(uint256,uint256)","abcb7fce":"getTokenAddressHashing(address,uint256)","abcb9934":"unlistToken(address)","abcc11d8":"lastResult()","abcc8a46":"LogEuroTokenOwnerMigrated(address,uint256)","abccb043":"modifyMaxContractBalance(uint256)","abcccdb1":"agentAddr_()","abcd0d9d":"getNewEndTime(uint256,uint256,uint256)","abcd7960":"equal(uint256,uint256,string)","abcdabcd":"aiGFJ()","abce03d0":"KoreaRepublicvsGermany()","abcf033c":"safeWithdrawalFromCrowdsale(address)","abcf1328":"InterestBank()","abd05acd":"createDklSaleAuction(uint256,uint256)","abd06c3b":"remove(bytes1,bytes1)","abd10e07":"failSafeAddWhenGreaterThanIntMax()","abd117fe":"GXCSentToETH()","abd188a8":"setKyberNetworkContract(address)","abd1a89c":"allocTokenHolder()","abd225e1":"isStarted(uint256)","abd23d95":"getNameByAddress(address,address)","abd2adbb":"columns()","abd2cc5f":"presaleClosed()","abd2ecb7":"isOnExchangeById(uint256)","abd437da":"balanceOfCall(address)","abd44556":"setBatchDetachCollectibles(uint256[])","abd49646":"makerDAO()","abd5100d":"referralAmountInvest(address)","abd5f3c7":"poolPrice()","abd6b000":"CryptoSagaCardSwapMerculet(address,address,address,address)","abd6cb3c":"firstStageRaised()","abd6ff8e":"setIntValue(string,int256)","abd70aa2":"getPoolBalance()","abd74e52":"getLastPriceFeedValues()","abd796bf":"addAllowedAddress(address,address)","abd7f8de":"doEmit(uint256,uint256)","abd8537f":"makeSmokeymon(string,uint8)","abd89e1e":"preICOmint(uint128)","abd8d939":"buyThroughProxy(address)","abd936ab":"delegateDklSaleAuction(uint256,uint256,bytes,uint256)","abd958eb":"getCurrentBlockValueAndSellPriceForTile(uint16)","abda35de":"inMaintainance()","abda78ed":"getAltOracles()","abdb5ea8":"repayBorrow(address,uint256)","abdbe6ca":"CrowdDreaming()","abdbf4a3":"UpdateAsk(address,uint256,uint256)","abdc5dee":"HumaniqToken(address)","abdd0c44":"marginCallOnBehalfOf(address,bytes32,uint256)","abdd11a8":"setOpeningTime(uint256)","abdd19d9":"setCityContract(address)","abdd2430":"AuctionCreated(address,uint256,uint256,uint256,uint256,uint256)","abdde3d1":"getEthToTokenOrder(uint32)","abde33f7":"right26(uint256)","abded6fd":"setANT(address,address,address)","abdf9566":"setData_16(string)","abdf9bda":"bountyProgam()","abe088a7":"financialOfficerAddress()","abe1d5a2":"ViewRawDeposit(uint256)","abe24a3d":"mulByFraction(uint256,uint256,uint256)","abe2a16e":"FeeRate()","abe2a18d":"stateChangeAgents(address)","abe3219c":"safeMode()","abe3d0e3":"logPurchase(address,uint256,uint256)","abe3dfd1":"setInitialRate(uint256)","abe4136f":"getNickname()","abe4932c":"createPostboyAccountForSomeone(uint256,uint256,bytes16)","abe5b120":"Registered(address,uint256,uint256,uint256)","abe65ec9":"_createDiamond(string,address,string,string,string,string,string)","abe6c54d":"deleteCandidates(address)","abe6e82f":"setAmountBonuses(uint256,uint256,uint256)","abe7008e":"getPlayerValue(uint8[],uint8)","abe756da":"dateRelease9()","abe75844":"preSaleFirstEndDate()","abe7b54e":"readWelfareDetails(address)","abe7c08e":"finishVoting(uint256)","abe7cc7b":"LOCK_END()","abe7f1ab":"remove(address,uint256)","abe7f6fe":"ensureAllowance(address,address,uint256)","abe8014a":"totalWeiRaisedDuringPreICO()","abe9717a":"A2ACrowdsale()","abe9f569":"oraclize_getPrice(string,uint256)","abea0804":"nAddresses()","abea8d79":"setMiningLeader(address)","abeb5f9f":"hasQuickBuyEtherToken()","abebb746":"_fillOrder(address,address,uint256,address,uint256,uint256,uint256)","abebb7f3":"MarketsContract()","abec0a00":"BLVK()","abed982b":"LockedUpTokensWithdrawn()","abedeab4":"init_claim(uint256)","abee967c":"initialReward()","abefe7ac":"canCreateUnit(uint256)","abf03e19":"end_ICO(uint256)","abf0661f":"_burnForDeposit(address,uint256)","abf0c538":"vestTokens()","abf17198":"getShipProductEarningByModel(uint16)","abf19801":"createVesting(address,uint256,uint256,uint256,uint256,bool,address)","abf26786":"item(uint256,bool,bytes)","abf2b5b9":"cancelMtr(uint256)","abf2e01c":"isElectionPeriod()","abf3260f":"highestEditionNumber()","abf45359":"preSaleTokenCap()","abf52f53":"independentSellerJoined(address,uint256,address)","abf567e1":"setStartTime(uint256,uint64)","abf64392":"withdrawInvalidated(uint256)","abf74a93":"pitFee()","abf74cda":"_issueTokens(address,uint256)","abf74d5f":"bury(uint256)","abf7b063":"totalSuperAdminsMapping()","abf7bfd8":"createUser(bytes32)","abf7f83e":"setBonuses(bool)","abf8de6b":"TrocarAdmin(address)","abf8fbb8":"BCB(uint256,string,string)","abfb589b":"revealBet(uint256,uint256)","abfb84a9":"TransferredPrefix(string,address,address)","abfc3db2":"MIN_UPDATE(bytes32)","abfc99a8":"setPeriodStart(uint256)","abfcb627":"subscribe(address,bytes32)","abfcb6f8":"checkInfo(uint256,address)","abfcc7d8":"endRound(uint256,uint256,address[],address[],bool)","abfccf3c":"REKTTokenSale(address,address,uint256)","abfd5c94":"addEntryInDays(address,uint256,uint256)","abfdcced":"setBool(bytes32,bool)","abfdd068":"getUserAuctionIds(address)","abfdfbe6":"setRentalPricePerDay(uint256)","abfe0472":"setMainLocation(uint16,uint16)","abfe35ad":"getStakingReward(uint256)","abfe40a8":"privateMint(uint256)","abfea3c5":"IraPid()","abfebfd9":"fifthWeekTokenPrice()","abff0110":"broker()","abff3fc1":"eventSaleEnd()","abffc9ac":"delistToken(address)","abffeffc":"create(address,address,address,address)","abfffa28":"foundersTokensDisbursed()","ac001725":"Goldic()","ac00c3e6":"teamEndTimestamp()","ac01367f":"CryptovoxelsProperty(string,string)","ac016a31":"label(bytes12)","ac01b83d":"getAllPlayers(uint256)","ac0250f7":"memberAt(uint256)","ac0287e2":"arrr(uint256[])","ac02c601":"TranferETH(address,uint256)","ac03f324":"transfer_status()","ac045aca":"soldSoulFor(address)","ac0496e1":"setItemToken(address)","ac04f5a7":"append(address)","ac05e0f7":"getBurnRequestUintMap(uint256,string)","ac05e15f":"manuallyMintTokens(address,uint256,uint256)","ac066073":"startTimePresale()","ac06e302":"SetupCrowdsale(uint256,uint256)","ac06eb81":"MDIVToken()","ac080f48":"getDebrisStatus(bytes32,uint8)","ac0840db":"resultsPublishedTime()","ac098ce9":"addAnn(string)","ac0a04b2":"signToApproveAddTokenData(uint256)","ac0a7223":"buyCost()","ac0ab476":"transferToContract(address,uint256,bool,bytes)","ac0b1786":"MeibangAccumulationAppreciationAllocation(uint256,string,uint8,string)","ac0ba9b1":"payUSDCToProvider(address,address,uint256)","ac0c103a":"a_palavra(bytes5)","ac0c518d":"preSaleTokenSold()","ac0ca722":"AutoreleaseTriggered()","ac0db69d":"Log(uint8)","ac0f3865":"LogTokensWithdrawn(address,uint256)","ac0f90e3":"checkCrowdsaleState(uint256)","ac0fdae5":"Record(address,string)","ac110d8e":"Take()","ac12319d":"adminPayout(uint256)","ac128f4f":"roundResults(uint256)","ac12bf92":"setAdminStatus(address,uint256)","ac12f3e9":"partner1_voted_update_prenup()","ac132dc3":"ProtectedUnlock(address,address,uint256)","ac133709":"getChannelParticipantInfo(address,address)","ac133d3b":"deploymentCost()","ac134c08":"rewards_amount(uint256)","ac13d9a6":"setPartnerContracts(address)","ac1424fd":"generateNewTicket(address)","ac145d80":"setOperationsCallGas(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","ac14c61e":"PresalePool(address,uint256,uint256,uint256)","ac151959":"setmaxprice(uint256)","ac1559d2":"totalTokensSent()","ac155a6c":"MatryxToken()","ac171101":"GAGARIN()","ac17cba4":"lemonsRemainingToDrop()","ac17d506":"getMemberData(address,address)","ac185644":"ownerTimeLastMinted()","ac1864b8":"treasuryManagers(uint256)","ac187542":"forceEndGame()","ac18de43":"removeManager(address)","ac194b07":"preIcoStartBlock()","ac19c726":"setKeepEth(bool)","ac1a13fb":"cancelOrder(uint256,uint32,uint32,uint256,string)","ac1a182c":"_calcProportion()","ac1a386a":"setWalletAddress(address)","ac1a7175":"lockUserInfo(address)","ac1aaa1a":"calticket(uint256)","ac1ad7d1":"tickerQuery()","ac1b14ff":"proxyCall(uint256)","ac1bc7e8":"updateDetails(string,string)","ac1c1443":"listProducts(address)","ac1c3d04":"generateToken()","ac1cb329":"withdrawBuyAgent()","ac1cd994":"seed_coins_vault2()","ac1d0609":"updateWhiteList(address,bool)","ac1d6fe2":"changeAllocation(int256)","ac1deea0":"RateUpdated(uint256,bytes32,uint256)","ac1e17df":"addHolder(address)","ac1e4734":"ORCA()","ac1e765b":"checkValidity(string,address,string)","ac1f7ca1":"totalFundsAvailable()","ac20902e":"NormalizeMoney()","ac20e2a0":"TOTAL_TOKENCAP()","ac210cc7":"wrapper()","ac216ae9":"setCheckBonus(bool)","ac218c6d":"addressICOManager()","ac21bacd":"TokenPriceChanged(uint256)","ac22b970":"_medalFreeze(uint256)","ac22cec8":"withdrawGasCost()","ac230e52":"getHeroName(uint256)","ac232383":"getAyantDroitEconomique_Compte_6()","ac246c3e":"TIME_TO_STALEMATE()","ac256e1d":"RiekCoin()","ac25f266":"add_to_whitelist(address)","ac26109e":"lockForOrder(address,uint256)","ac267435":"volumeType7()","ac270c37":"contractUp()","ac280cb9":"MAX_STANDARD_SALE_PACKS()","ac281ca6":"recordPayment(uint256,uint256,uint256)","ac28240d":"transferBackMANA(address,uint256)","ac283f5b":"Error(string,string)","ac28838b":"getPerson(bytes32)","ac28ff48":"collectableTokenBalance()","ac297d21":"vendDisciple(uint256)","ac2ac86c":"setSmallCapWhitelistParticipants(address[],uint256[])","ac2aefd2":"addPigment(uint256,uint256,uint256,uint256)","ac2c8bb5":"getTile(uint16)","ac2d456d":"setOracleCallbackGasPrice(uint256)","ac2d7ce5":"setNextLotteryTTWTokenId4(uint64)","ac2e043d":"whitelistMulti(address[],uint256[],uint256[])","ac2e064b":"set_maxCWCsPerSaleLessThan(uint256)","ac2e2c65":"JULIAN_ADDRESS()","ac2f0074":"polls(uint256)","ac307773":"claimFunds()","ac30da84":"BountyHunter()","ac3120a0":"LogContribution(address,uint256,uint256,uint256,uint256)","ac31818d":"Better_Bank_With_Interest()","ac3314a6":"issueLockedTokens(uint256)","ac336f7b":"getCurrentConsensus(string)","ac355ed3":"_salesprice()","ac35bdb4":"sub_session(string,uint256)","ac35caee":"transferWithReference(address,uint256,string)","ac360d3c":"TokenWrapper()","ac375770":"didWithdraw(address,uint256)","ac377553":"fillFromCollateral(uint256)","ac38eb07":"tokenIdForHandle(bytes32)","ac3910a2":"ballot()","ac3c27cf":"resolveDisputeSeller(address,string)","ac3c49e0":"getMarketMakerAddressFromToken(address)","ac3c9952":"batchTransfer(address,uint256[])","ac3cb72c":"addApproval(address,uint256)","ac3cdf78":"RANGEEND_10()","ac3d057d":"releaseBudget(address,uint256)","ac3d5084":"initialFrozenTime()","ac3d8558":"setExitStake(uint256)","ac3dc451":"TorontoRules(address,address[])","ac3dc9aa":"startBlockTimestamp()","ac3e6b2f":"testSetNotRetractable()","ac3e7d24":"addChainyData(string)","ac3fc432":"stampCreatedCount()","ac403817":"addresIndex()","ac41865a":"getPrice(address,address)","ac41b4a5":"SignalingEnabled(address,uint256)","ac42c3ec":"maxTokenBetValue()","ac42ea7d":"rejectBurnRequest(uint256,string)","ac42f301":"getNextForwardUserId()","ac42f446":"botPhase()","ac440d13":"CardsAccess()","ac4501d9":"splitTrade(uint256)","ac451185":"getGames(uint256,uint256)","ac45185d":"adminStewardship(address[2],uint256[7],uint8,bytes32[2])","ac457a9d":"ExposureOpened(bytes32,address,uint256,uint256,uint64,uint64)","ac460d66":"setTokensContract(address,address)","ac46a451":"OpsAddressChanged(address)","ac46fa22":"burnEscrow(uint256,uint256)","ac4746ab":"EPOCH_LENGTH()","ac4758cc":"Takafuly()","ac475e5c":"CheckTimeout()","ac476a05":"MarketMaker(address,address,uint256,uint256)","ac47981c":"issueCertificate(string,string,string,address,address,string)","ac480af9":"updateFirstDeposits(uint256)","ac482bff":"resume_PRIVATESALE()","ac48bd5a":"ethUSD()","ac48fcbc":"testTheMultipliers()","ac490b08":"parsha()","ac49dd5c":"removeTimelock(address)","ac4a743d":"ecoFundSupply()","ac4ab3fb":"hasRole(address,bytes32)","ac4abae1":"lockReleaseDate()","ac4b2bae":"newParameters(int256,uint256,int256,uint256)","ac4ba3ea":"initManager(uint256,uint256)","ac4bd53a":"currentLeader()","ac4bed68":"modifyHorsey(uint256,address,bytes32,uint8,uint8)","ac4c25b2":"void()","ac4c8bf3":"argCurMax()","ac4ce2c6":"setAddress(uint256,address)","ac4cfa4c":"calcAmount(address)","ac4d2e95":"ownerTokensFreeDay()","ac4d8a26":"setRepPriceInAttoEth(uint256)","ac4d965c":"notZeroAndNotSender(address)","ac4ddd9f":"retrieveTokens(address)","ac4df041":"donationClosed()","ac4e677c":"registerTrack(bytes32,uint256,bytes32,bytes32,bytes32,bool)","ac4e73f9":"proposeReverse(string,address)","ac4eefc5":"getGoldDataMinted()","ac4fb219":"enableLockFlag(bool)","ac50713a":"foundingTeamWallets(uint256)","ac509050":"getPlayerRoundsKitties(uint256,uint256)","ac50a466":"betfortoken()","ac50af76":"transferExcessTokensToReserve()","ac50b2e5":"getPlayerRoundNumbers(uint256,address)","ac51009e":"createBountyTokens()","ac51215b":"TokenRegistry(address,int256)","ac51a36a":"_unpackPetData(uint256)","ac51af8e":"transferWithBonus(address,uint256)","ac51d3a5":"smileyToken()","ac5277a4":"teamSupply6Months()","ac552cf2":"getCurrentDukePaid(string)","ac5553ce":"phaseDuration()","ac5555aa":"initialized(bytes32)","ac562666":"freezeCoin()","ac566953":"getInfra(uint256)","ac56c52b":"makeDealForTwo(string,uint256)","ac56f980":"setRealseTime(uint256)","ac588536":"delayPayout()","ac5895f6":"getSoilHumidityControlLimits(bytes32)","ac591e40":"SelectOne(uint256,uint256,uint256,uint256,uint256,string,address)","ac592944":"SendPreReserved2()","ac59eeeb":"recoverAddressFromWithdrawMessage(uint256,address,uint256,bytes)","ac59f0d9":"addToken(address,address,string)","ac5aaa5b":"toToteLiquidatorWallet()","ac5b3998":"assignLockedBalance(address,uint256)","ac5b3dbb":"Michael1011Token()","ac5c8535":"storeData(bytes)","ac5c867c":"sendCrowdsaleBalance(address,address,uint256)","ac5c915f":"burnBonuses()","ac5ce03b":"marriageProofDoc()","ac5cfc3d":"getMsgWaiting(uint256)","ac5d2dbf":"typeToken()","ac5d67e9":"lockAdvisorsTokens()","ac5d8745":"voteWithSpecifiedAmounts(bytes32,uint256,uint256,uint256)","ac5e7977":"receiverThree()","ac5e81a9":"historyPayout(address)","ac5ec9ef":"setAcceptPayment(bool)","ac5f91a0":"previousMinters()","ac6068b5":"isNotExpired()","ac60a6cd":"payInvoice(uint256)","ac60bbca":"userTokenStats(address,address)","ac60c969":"canFirstMint()","ac60da79":"TOKEN_SALE3()","ac61e92b":"createBet(uint256,uint256,uint256,uint256,bool)","ac624f52":"crowdSaleToken()","ac62ddb2":"validateMigrationIsPending(string,string)","ac62e250":"CertificationSet(string,address,uint256)","ac63208d":"SPRToken()","ac637c7a":"delegateTo(address)","ac64198b":"RSPLT_G()","ac6456df":"_betFailure(string,uint256,bool)","ac646756":"pause2()","ac656636":"getDepositReceipts(address,int256,uint8)","ac65b258":"PresalePool(uint256,address,uint256,uint256)","ac66777f":"multiCallTightlyPacked(bytes32[])","ac67857e":"ArtsCoin()","ac697fb5":"SkySwapToken()","ac69c09c":"changeVotingRules(address,uint256)","ac6a2b5d":"_withdraw(uint256)","ac6a4d6a":"fooInt()","ac6a602f":"getCompte_34()","ac6af280":"setRates(uint256,uint256)","ac6b02c4":"IFCC()","ac6b8e00":"transferLock(address,uint256,bool)","ac6bc853":"startSpin()","ac6c5251":"getWeight(address)","ac6d0316":"performUpdateCallPtr()","ac6d0fed":"nestedFirst(uint256)","ac6d8150":"getPayment(uint256,string)","ac6da90d":"qwercoin()","ac6e1237":"CrowdsaleEndedSuccessfuly(uint256,uint256)","ac6e2db6":"tokenCreationCapOne()","ac6ebb28":"CioCoinERC26Token(uint256,string,string,uint256)","ac6ee852":"newGanToken(uint256)","ac6eead3":"team_token_percentage_total()","ac6fe0ed":"Batchdrop(address)","ac700665":"getOrdersForBuyer(address)","ac700e63":"pauseMigration()","ac708f0c":"getProjectedBlockHash(uint256)","ac70a1ef":"getTreasures()","ac70e6c4":"level_9_percent()","ac71045e":"getOffer(address,uint256)","ac711cbb":"withdrawEtherAll()","ac71abde":"addAccounts(address[])","ac72200d":"getMinted()","ac72c120":"hasReverse(bytes32)","ac72cd7e":"BrokerInt(address)","ac73e97e":"lastMiningTime()","ac74bcde":"defaultNumberJuror()","ac74f2a8":"Bothereum(uint256,string,string)","ac767539":"testFailItemStoreNotRegistered()","ac76a499":"clientsAverageRating(address)","ac76fbf1":"GeoGame()","ac7709bc":"setTimedTransfer(uint256,uint256)","ac778b8f":"createCertificate(string,string,string)","ac77eb8e":"ZingToken()","ac781fbe":"TrustTokenERC20(uint256,string,string)","ac789e5f":"BlindAuction(uint256,uint256,address)","ac78dc16":"payTeam()","ac793a60":"createBet(uint256)","ac798bd3":"calculateArtCoinSupply()","ac798def":"set_sale_arbits_sold(uint256)","ac79a4b1":"getCreateMarketCreatorValue()","ac7a1b5b":"maxWithdraw()","ac7a722e":"updateETHPriceInCents()","ac7a95d5":"getNewShroom(uint256)","ac7b986f":"lotusWallet75Pct()","ac7bb2b4":"removeFromWhiteList(uint8,address)","ac7cda53":"changeRegisterBot(address)","ac7dce1d":"BsPresale_SNOV(address,address,uint256)","ac7e1e0a":"setEtherProceedsAccount(address)","ac7f0c48":"calculateWin()","ac7f9329":"AUTH_SETMINTAMOUNT()","ac7fc263":"multipliers(uint256)","ac7ffae3":"updt(uint256,string,uint256,uint256,string,string,address)","ac800b32":"transferCanaryOwnership(address)","ac82239f":"enableInvite(string,bytes32)","ac824fd9":"SHEX(uint256,string,uint8,string)","ac8261c9":"optionProgram()","ac828200":"_dlgtRet(uint64)","ac833fd9":"test_insert_findWithHintNextUpdateHead()","ac838774":"addauction(address,uint256,uint256,uint256,uint256,uint256,string,string)","ac8388a5":"callthis()","ac83ae55":"GAMEToken()","ac83e891":"BokkyPooBahsAutonomousRefundathonFund()","ac84ed4f":"TronClone()","ac856216":"setNumRewardsForTMEUser()","ac860a59":"_signPropertyByAgent(address,address,bytes32)","ac8641ee":"updateRefundWalletAddress(address)","ac8648a2":"mintFeeTokens(int256,uint256)","ac869cd8":"setFrozen(address,bool)","ac8860b9":"ProposalExecutedEvent(uint256)","ac88c8d8":"verifyAndLiquidate(address,address,address,uint256,uint256,uint256,uint256)","ac88ffb2":"feeWithdrawEthAmount(uint256)","ac890c4c":"unsetAllowedMultivest(address,address)","ac8a2af0":"updateShareholders(address)","ac8a584a":"removeOperator(address)","ac8aa236":"batchTransferVIP(address[],uint256[])","ac8aea24":"transferUnsoldToken()","ac8c5e8e":"buyLong(address[2],uint256[3],uint8,bytes32[3])","ac8d6030":"removeRequest(address)","ac8d6632":"addMasterNodes(address,uint256,uint256)","ac8dc6ea":"_decodeData(bytes)","ac8e88c2":"_updateSolvency(uint256)","ac8f539b":"emergencyDrain(address,uint256)","ac8fa644":"transfer_Same_Amounts_of_assets_to_many_addresses(address[],uint256)","ac8fbd09":"UpdatePoolTarget(uint256)","ac900c2d":"unregisterSeller(address)","ac92f4ae":"calldatacpy(uint256,uint256,uint256)","ac92fdb5":"getSaleDate(bytes16,uint256)","ac940823":"betOnLowHigh(bool)","ac957954":"transferDonations(bytes32,address)","ac95a2aa":"_createOriginalPainting(uint256,uint256,uint256)","ac95be9b":"testico()","ac9630fa":"publishGraduatingClass(string)","ac964f21":"numProducts()","ac9650d8":"multicall(bytes[])","ac9663a6":"approveByC(uint256,string)","ac96a0b3":"GYG()","ac96c65e":"doCancel(bytes32)","ac96f981":"authorizeAccess(address,int256,address)","ac978cea":"TeamHOMO()","ac979688":"transferAnyERC20TokenToBeneficiary(address,address,uint256)","ac97ad89":"getTokensFromAddressReturns(address,address)","ac985f0a":"townsSold()","ac9873c7":"CanaryV7()","ac988bdc":"_getStageIndex()","ac991b65":"double_blind_sha256(string,address,address)","ac996e7e":"resolvePledging()","ac99aa69":"recoverEthers()","ac99e0aa":"BitImageToken()","ac99f7b7":"_setStages(uint256,int256)","ac9a252a":"ownershipTransferred(address)","ac9a6515":"testTokenOwnershipAfterFinalize()","ac9b5671":"setVerifier(address,bool)","ac9b5c30":"getCreateMarketfeePerEthInWeiValue()","ac9c3b7a":"TokenTotal()","ac9c80af":"seed_additional_eth()","ac9cd354":"getTransferInfoCount(address)","ac9d7e0a":"raisevote()","ac9ef8a1":"changeMultisigs(address,address)","ac9f0222":"setState(bool)","ac9f2b7b":"callDeposit(address,address,uint256)","ac9f9d12":"FACHAINStandardToken(uint256,string,uint8,string)","aca00932":"calculateBaseTimeout()","aca15663":"transferToExchangeAddress(address,uint256)","aca19256":"_logRoundExtensionVolume(uint256)","aca233fd":"one_two(uint8)","aca31e61":"setEthPerToken(uint256)","aca34c11":"getPoolDetails()","aca62a5f":"convertAllOldTokens(uint256,uint256)","aca66aec":"DVIP()","aca67a8f":"getIsNFTAttached(uint256)","aca6fdf2":"getJobWorkerName(uint256)","aca7207a":"changeCoolDownTime(uint256)","aca7dcfe":"token_swap_supply()","aca7fdd4":"initialFunding(address,address,uint256)","aca867b3":"secure(address,uint256)","aca8dd6b":"test_threeInvalidEqString()","aca8e9dd":"setBillboard(string)","acaa78cd":"addTransferrer(address)","acaab181":"addSomeGas()","acab021c":"getTOS(address)","acab3e5d":"PricingStrategy()","acabbbc0":"getSlogan(uint64)","acabd1b9":"setFee3(uint256)","acac0b9f":"setMaxPerExchange(uint256)","acac9a9f":"undropped()","acad94ae":"humanStandardByteCode()","acada0d8":"SUNQToken()","acaf0278":"contractuallyOf(address,address)","acb02504":"getJobDescription(uint256)","acb02f7c":"VotePumpCoin0x()","acb09dde":"fechVoteNumForCandidate()","acb0bdc3":"isPolicyExist(bytes32)","acb10351":"setupDutchExchange(address,address,address,address,address,uint256,uint256)","acb1516f":"accreditationMember(address,address)","acb1e61f":"transferable(address)","acb2ad6f":"transferFee()","acb2d607":"TokenBet(address)","acb2fe3e":"checkBlackListAddress(address)","acb39d30":"tokenCreated()","acb3c073":"setSwap(address)","acb461df":"tavern(uint256)","acb5e570":"DepositClaimed(uint256,address,uint256)","acb62d7c":"clearConfig()","acb6a6aa":"_generateRandomNumber(bytes32,uint256)","acb6c69b":"setTrustedClient(address)","acb6ca94":"Nomid()","acb6e626":"ImageCoin(uint256,string,string)","acb6e9b1":"testControlItemStoreNotRegistered()","acb6f75c":"PreIco(uint256,address,uint256)","acb748e9":"RuletkaTestIo()","acb74e73":"canSaleInfo()","acb8726a":"distributeTax(uint256,uint256,uint256,uint256)","acb88986":"freeze(address,uint64)","acb894d2":"fint256(int256)","acb902f6":"secondHighestBid()","acb93f36":"ratePerHourInWei()","acb9656c":"setLockedTokens(address)","acb9d6f6":"getStageandPrice()","acbaed04":"TootyrTokenSale()","acbb471f":"EthermiumAffiliates(address)","acbb5759":"SetAction(address,uint256)","acbc272b":"newToken(string,string,uint256)","acbc3ff4":"keyFoundation()","acbc62ae":"TokitDeployer(address,address)","acbcabc0":"pantryT()","acbd9563":"buyPatent(uint16)","acbdb084":"RequirementChanged(uint256)","acbdb72c":"getSecondAdmin()","acbdea6c":"canUpdateBackWindowAdjustmentRatio()","acbe274d":"this_tablet_name()","acbf98a7":"endsWith()","acbfbaac":"getPOOL_edit_30()","acbfbd9e":"Unlock_Tokens(address)","acc02119":"DirectDemocracy()","acc05ccc":"AddressProxy()","acc0a246":"uint256At(bytes,uint256)","acc10f11":"collect(address,uint256,uint256)","acc12168":"on_block()","acc2508b":"payoutNow()","acc32da3":"validateIpfsDoc(address,uint256,bytes)","acc3b363":"ContractBHVC()","acc3c020":"investorsToWithdrawIter(uint256)","acc3e283":"test_insert_empty()","acc3e5d9":"deathFactor_ii()","acc58d24":"_removeStackholder(address)","acc5a0dc":"GetPrize()","acc68b2c":"usersRef(address)","acc69261":"addCompany(address,uint256)","acc79f74":"openMail(uint256)","acc7f8a8":"getCurrentDatetime()","acc823f8":"getSurname()","acc88c0d":"decayedBalanceOf(address,address)","acc8cb18":"pushTerm(string)","acc907a9":"getWinner(address,uint256)","acc9138e":"revealBid(bytes32)","acc9383a":"dist_privateSale(address,uint256)","acc93c9e":"setBonusThresholds(uint256[],uint256[])","acc99bb7":"allUnKycedEth()","acca2c24":"getFirmFromAuthority(address)","acca92e0":"finalize(uint32,bytes32)","accb2677":"createCarsTokens()","accb4219":"RISHABHToken(address,address)","accbdfd0":"IsDistribRunningFalg_()","accc4a61":"setPresaleOpeningClosingTime(uint256,uint256)","accd932b":"icoClosedManually()","accd962b":"tokensaleContributors(uint256)","acce4b10":"crowdsaleTargetReached()","accf80a4":"RelaunchedCrowdsale(address,address,uint256,uint256,uint256,uint256)","accf878a":"ActionPresell(address)","accfa48b":"changeRelease18m(address)","accfaeba":"LEGAL_EXPENSES_1_TOKENS()","acd00a5c":"fillAmount()","acd00dc1":"_emitCountryCodeChanged(uint256,uint256,uint256)","acd02c30":"disburseToken(address,address[],uint256[])","acd04c4c":"_setVersion(uint256)","acd105d1":"doomsday()","acd19170":"getarg_2()","acd1bdb4":"updateMinimumContribution(uint256)","acd256db":"setOraclizeBytes(uint256)","acd2988c":"setValidBwMarketCaller(address)","acd2e875":"refferedBy(address)","acd3057a":"jishituihuan(address,uint256)","acd3c39f":"frozenAccount(address,bool)","acd47b3a":"addAuditOrEvidence(bool,bytes32,uint256,bytes32,uint8,bytes32,bytes32)","acd47bc3":"COMMUNITY_BOUNTY_STAKE()","acd47e97":"TokenPurchase(address,address,uint256,uint256,bool)","acd485fe":"Balicoin()","acd4bca6":"vanbexTeamSupply()","acd4e110":"Amorcoin()","acd4e4aa":"SilverFiftyToken()","acd590d3":"preSale2Finished()","acd5b7b9":"stopAt()","acd5fb23":"isZero(int256,string)","acd6a40a":"testUntil()","acd6f096":"testThrowsIfSaleIsNotTokenController()","acd782b1":"setProtectionPrice(uint256)","acd78e3a":"getPayIdAndHeld(uint256)","acd84e24":"PLN()","acd9277f":"market_DeclareForSale(uint256,uint256)","acd94ccb":"frozenDaysForICO()","acd9930b":"setHoverText(uint256[2])","acd9fd65":"fun1(uint256)","acda01f6":"setPendingWalletFee(address,uint256)","acda28a1":"bacFund()","acda3e10":"UpdateEtherPriceNow()","acda6737":"TADPOLE_BOOST()","acdaa0d2":"payout(uint256[],address[],uint256[])","acdba7c2":"contract_num()","acdba91f":"setTokenExpectedFee(address,uint256,address)","acdc42f3":"failICO()","acdd1454":"mint(uint256,string,string,string)","acdd9c5c":"SetRegistrationContract(address)","acddb63c":"requestMortgage(uint256[6],string,uint256,uint8,bytes32,bytes32)","acddbe1c":"someFunction3()","acde39d9":"c4cfee()","acdec908":"getBetIdAtRound(uint256,uint256)","acdf4f18":"buyBack()","acdf67b3":"blockWithdrawBegin()","acdf7362":"setLock(address,address,uint256,uint256)","acdfa0ac":"acceptNameTranfer()","acdfb350":"hariKari()","ace1fab1":"withdrawReserve()","ace237f5":"pep()","ace30883":"absMinFee()","ace36da2":"setChain(address,address,address)","ace4283b":"getSecondsToExpiration()","ace45552":"endICOStage6()","ace51abc":"helperVerifyHash__(uint256,int256,int256[],int256,uint256,int256,int256[],int256)","ace523c4":"createReferendum(string,string,uint256,uint256)","ace80e0d":"bytesMemoryArray()","aceaa365":"_creditTo(address,uint256)","aceb87e1":"getUserBio(string)","acec0e1d":"setconf(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","acec338a":"setActive(bool)","acec460f":"tokenDataValue(uint256,uint256)","acec488d":"setAnnouncement(string)","aced1661":"keeper()","aced5935":"getConfig(address,string)","acedc33e":"setDecrementOpenInterest(bool)","acee57e1":"airDropPayableMoney()","aceecbc8":"disableSelling()","acef193e":"FundingCompleted(uint256,uint256)","acef6037":"transferToAddress(address,uint256)","acefb7bd":"JudgmentCoin()","acefd330":"createRandomNumber(uint256)","acf0dd57":"getRegionUrl(uint256)","acf197b1":"IcoRunnedManually()","acf1b06a":"systemCreatedCount()","acf1e9fa":"buyNinja(address)","acf2f478":"changeTradableFciInSession(bool)","acf3508e":"_isLatitude(int256)","acf36037":"getCountryData(uint256)","acf36e53":"addParent(address)","acf372ef":"SetMasterWallet(address)","acf400b2":"getSellOrdersBlackMarketComplete()","acf4280c":"buildDSApprovalDB()","acf50f55":"setItemForSale(uint256,uint256)","acf555b8":"regReferrers(address[])","acf5c689":"setRequiredBlockConfirmations(uint256)","acf5cfbf":"Spend(uint64,address,string)","acf67746":"getPlayerTeam(address)","acf6d918":"ChangeReturn(address,uint256)","acf7aea7":"getCountryLimit(uint256)","acf7c1d2":"updateJackpotBalance()","acf8bf2a":"channelCount()","acf94ed5":"fallbackTriggered()","acf975d6":"addCycleAddress(address)","acf97a65":"redistribute(address[])","acfabbe4":"updateCurrentPeriod()","acfb153d":"RoundTime()","acfb208b":"transferFee(uint16,uint64,address)","acfb2d95":"iHaveABiggerDick(string,string)","acfb4b26":"DIVIUMx2()","acfd18c6":"FOUNDATION_ADDRESS()","acfd35a0":"distributeSuccessfulCampaignEth(uint256)","acfd82f2":"grantOwnership(address)","acfdfd1c":"deploy(uint256,string,string,address)","acfe27d7":"Slashing(address,uint256,bytes32)","acfe711a":"Scientific()","acff2fce":"forceNSFW(uint256,bool)","acfff377":"rollDice(uint256)","ad00129e":"bonusOver100ETH()","ad00297a":"payDeposit(address,uint256,bytes)","ad003aeb":"setUserNotifications(address,address,bool[],bool,uint8[],uint8)","ad009062":"newVitaReward(address)","ad0096af":"transferFromWithCustomReserving(address,address,uint256,uint256)","ad01ed4c":"s3(bytes1)","ad0212df":"capitalNeeded()","ad0254a6":"BitGuildWhitelist()","ad03261e":"supportRebalance()","ad03abc5":"enableRealCap(uint256,uint256)","ad044f49":"totalFunded()","ad04592e":"owner_deposit()","ad04d74d":"buyCoreWithBalance(address,address,uint256)","ad0570c7":"setUsernameForAddress(bytes32,address)","ad07008f":"icoDiscountPercentageLevel2()","ad07220f":"forceTransferBalance(address,address,uint256)","ad075684":"TotalPayment()","ad0767bd":"RECORDPart()","ad076994":"verify(address,address,uint256)","ad076bfc":"debug_hash256Double_concat(bytes,bytes,bytes)","ad09019d":"oraclize_getNetworkName()","ad09202a":"confirmDealCompletionByDoctor(bytes16,bool)","ad093409":"getTicketOwner(uint256)","ad0a58c8":"checkAndDeclareWinner(uint32)","ad0a6cc3":"attackTileForExistingUser(uint16,uint256,bool)","ad0b2bec":"redeemWinnings()","ad0b38a2":"getAppId(string)","ad0b6013":"DEFAULTED_STATUS()","ad0bc739":"testConcatMemoryZeroLength()","ad0be174":"zHQNumber()","ad0c3dff":"icoStartedAt()","ad0d3713":"getTittyOwner(uint256)","ad0d4c3d":"HaiWang(uint256,string,string)","ad0dd79f":"usersWithdrew()","ad0e053b":"getPointerOwner(uint8)","ad0e13bb":"toB32(bytes,bytes,address)","ad0e8bc7":"givepoints(address,uint256)","ad0e9053":"set_pauseReturn(bool)","ad0f2916":"coinPrice()","ad108280":"BECTStandardToken(uint256,string,uint8,string)","ad1088e4":"didProve()","ad111feb":"DFSToken()","ad11cc1d":"claimC1()","ad11fe44":"revokeAllowance(address)","ad121e33":"fundFounder()","ad1288c8":"forkTransferFrom(address,address,address,address,uint256)","ad12cc0b":"removeLibrarian(address,address)","ad13eb02":"createScanner(uint256)","ad150aec":"calculateHeldTokenDistribution()","ad156d34":"AllocateBountyAndEcosystemTokens(address)","ad166aae":"MyTest(uint256,string,uint8,string)","ad180328":"_check(address,address,uint256)","ad188be0":"userBetContribution(address)","ad1896db":"resetElectionPeriod()","ad18ad0c":"quote(address,uint256,address)","ad1922b0":"setIcoCloseTime(uint256)","ad19bd26":"getVoteCommit(uint256,address)","ad19e993":"_callSender(bytes32,address,address,address,uint256,bytes,bytes)","ad1a17b4":"getPaymentCount(uint256)","ad1a38be":"_createNarco(string,string,address)","ad1a7d0c":"getBook(bytes32)","ad1aa252":"withdrawUnsentTokensForOwner()","ad1b3909":"coinage()","ad1be7c1":"softCapClose()","ad1c582a":"divUIntValue(bytes32,uint256)","ad1c5d6c":"updateShareCrystal()","ad1d0dcf":"exodus()","ad1def42":"registeredAddress(address)","ad1ef61e":"donkeyInvested(address)","ad203bd4":"subMonths(uint256,uint256)","ad207feb":"ethTeamWallet()","ad217ae5":"stats(uint256)","ad220cf1":"currentPrivateSale()","ad221195":"transferTokenFrom(address,address,uint256)","ad22453c":"BRANDS()","ad226122":"presaleFallBack(uint256)","ad22980a":"TopChainCoinMintFinished()","ad22ccc0":"committeeJoinVoters(address,address)","ad22d4a2":"get_last_item_in_state(bytes32)","ad2334a0":"spinnerModulus()","ad2377c1":"pausePriceRaise()","ad23ad92":"AfriHealthCoin()","ad23de63":"isAddressWhiteListed(address)","ad23e038":"HelloToken(uint256,string,uint8,string)","ad23fdc3":"deCompose(string)","ad23fde0":"breed(uint256[2],uint256[2],uint256)","ad247dd9":"permissonedAccounts(address)","ad24d512":"TECHNOBITToken()","ad25ce57":"bidOnSaleAuction(uint256)","ad266df8":"ARA(uint256,string,uint8,string)","ad26f6e1":"SetParticipantName(address,address,string)","ad27b14d":"cancelBet(bytes16)","ad28ff88":"blacklist(address,address)","ad295b26":"getDepositInstanceCount()","ad29ca6d":"eosCrowdsaleAddress()","ad29ddaa":"removeRound(uint256)","ad2a0a7b":"_changeEternalStorageContractAddress(address)","ad2a39d6":"secondStartTime()","ad2a9c5f":"MIN_CARD_PRICE()","ad2af501":"Games(uint256,string,uint8,string)","ad2b14d1":"changeCrowdsale(address)","ad2b1e03":"privilegedBurn(uint256)","ad2b260a":"decimalNum()","ad2ba325":"splitStr2Int(string,string)","ad2bb1b3":"blockAddress(address)","ad2bbf9c":"_redeemByTranche(bytes32,address,address,uint256,bytes,bytes)","ad2c1632":"ArenaplayToken()","ad2da239":"calculateVote(uint256,uint256,uint256)","ad2daa48":"roundTimeRemaining()","ad2de16d":"acceptTxTask(uint256)","ad2e1d49":"getHeirachy(bytes32)","ad2e6aff":"WithdrawEarnings()","ad2e8c9b":"getDuration()","ad2ec740":"PRICE_9()","ad2fad33":"setSpawnProxy(uint32,int256,address)","ad2fea7c":"removeMinter(int256,address)","ad317c23":"mileagePointPrice()","ad319bab":"TokenERC20AC(uint256,string,string)","ad31e845":"_tag(uint256,string)","ad3286fc":"AddToken(address,uint8)","ad32a40f":"Fund(address,address,address,address,address)","ad32f925":"makeAvailable()","ad3335b5":"setINNBCTokenAddress(address)","ad33513f":"refundAmount()","ad33e21d":"getReferralBonus(uint256)","ad3429be":"developmentTokens()","ad344465":"AccessorySeriesCollection(uint8)","ad344bbe":"sgtExchanger()","ad35bdb0":"extraSupply()","ad35dcd3":"AGAVE(string,string)","ad36c593":"getOwnerOfCampaign(bytes32)","ad3704c5":"getApplicantsLength()","ad374f5b":"enableClaimTokens(bool)","ad376113":"addDevReward(uint256)","ad379089":"canSettle(bytes32)","ad37c41b":"blackListEnabled()","ad381cb7":"getCurrentRoundIsActive()","ad38867e":"checkWinner()","ad388896":"setWinnerAndEndEvent(bytes32,bool,string)","ad389d5d":"isValidAdversary(uint8,uint8)","ad38bf22":"updateBlacklister(address)","ad38d6f1":"whitelistWallet()","ad38fba5":"transferEthTo(address,uint256)","ad395939":"withdrawContributorPot()","ad395ad3":"removeFromContractIDArray(address)","ad3a05ca":"BlackToken()","ad3b1b47":"withdrawFees(address,uint256)","ad3bf1f1":"refundPeriodOver()","ad3c0b9d":"CROWDSALE_DURATION()","ad3c8b22":"addSkipPrice(uint256)","ad3c901c":"getPendingById(uint256)","ad3cd883":"changeContractName(string)","ad3de14c":"getMap()","ad3e0ed2":"getAffiliateSenderPosAmount(uint256)","ad3eb71f":"plcrFactory()","ad3ef46d":"RealstateOceanProject1(address)","ad3f972e":"deleteChild(address,address)","ad3ff3c1":"houseAlwaysWins()","ad401842":"setDateMainStart(uint256)","ad40256f":"reclaimableOwner()","ad418e66":"strategicReserveSupply()","ad41b628":"MHCToken()","ad447a19":"getBalanceDB()","ad449198":"returnBorrower(uint256)","ad4493fe":"checkPoint(uint8,int256,uint16)","ad44c205":"Nudge()","ad44e73b":"unwhitelist(address[])","ad450b72":"SupplyLimitChanged(uint256,uint256)","ad452254":"BsToken_SNOV()","ad459a1c":"CurrentAirdropped()","ad468489":"register(bytes32,address,bytes32,bytes32,bytes32)","ad470886":"token_approve(address,address,uint256)","ad4749f4":"setupPeriodForFirstStep(uint256,uint256)","ad474b9a":"Engraved(address,string,string,bytes32)","ad475113":"PRESALE_BONUS_VOTING()","ad478dda":"investmentUpperBounds()","ad483188":"setCCH_edit_12(string)","ad48636a":"secondBonusSalesEnds()","ad487790":"reveal(bytes32,address)","ad487f3c":"LogFreeze()","ad48d611":"marketToken()","ad4946ee":"removeAddressFromNonzeroBalancesArray(uint256,address)","ad498ce1":"RATE_NO_DISCOUNT()","ad49f595":"checkAddress(address,address)","ad4a7bd9":"lockTokensForAs(address,address,address,address,address,address,address,address,address)","ad4ac3de":"LoveCoin()","ad4b243b":"buyOneMinuteLottery(uint256,uint8[],address,bool)","ad4b2ca4":"batchdrop(address[],uint256[])","ad4b558c":"monsterIndexToOwner(uint256)","ad4c05f1":"setResourceForStar(uint8[5],uint16[5],uint32[5])","ad4cd0d6":"stdlib()","ad4dde0f":"transferOwnershipOfItemsStorage(address)","ad4e2f77":"addDragon(address,uint256,uint256)","ad4e39f3":"getLendingItemInfo(address,uint256)","ad4f0e3a":"DevsmartCoinFive()","ad50039f":"setTechBonus2(uint256,string)","ad5022a5":"Votes()","ad506098":"WowMusicDiamondToken(address)","ad509c1d":"sendToken(address[],address[],uint256[])","ad50dd1f":"endPrivateSaleStage()","ad53322b":"donationAmountInWei(address)","ad534d9c":"logCoinAgeRecord(address,address,uint256,bool)","ad53be1d":"priceLeRT()","ad544dcb":"testSetNotUpdatable()","ad549e53":"set_participant_arbits_kyc_whitelist(address,bool)","ad5511a5":"_setTokenSeed(uint256,string)","ad559fd6":"setHigherPricePercentage(uint256)","ad562965":"getReceiptRoot(bytes32)","ad5632e6":"storeAuthenticity(string)","ad5688d8":"setCountryPicture(uint256,string)","ad5780af":"clearDNSZone(bytes32)","ad57a2df":"unrestrict()","ad57ceb4":"ethForMilestone()","ad58a7d2":"getSettingState(uint256)","ad59ffd1":"maxAmountBonus()","ad5a157d":"promoMoney()","ad5a8f29":"canEnterPool(address,uint256)","ad5b7189":"hasBooster(address)","ad5b896e":"refundMany(address[],uint256[])","ad5bfcb5":"getServiceStatByAddr(uint64,address)","ad5c1687":"offchainUpload(address[],uint256[])","ad5c4648":"WETH()","ad5c613d":"purchase(bytes)","ad5cd9e7":"startSTO()","ad5d2862":"getWinnings(uint256)","ad5d638d":"minFundedValue()","ad5dabb0":"assertYoungerBalance(uint256,uint256)","ad5dabca":"QatarCoin()","ad5e2cd0":"addPresale(address,uint256)","ad5e46cb":"hasError()","ad5f3433":"sumHardCapICOStage4()","ad5fb2b1":"seedVerification(string)","ad60540b":"MoccaCoin()","ad605729":"getParticipantCount()","ad606c72":"devWithdraw()","ad615f40":"getCrosCounter()","ad621b14":"BaoMaToken()","ad622d0e":"addDoctors(uint256,uint256,string)","ad62bda5":"setRoundLength(uint32)","ad62f1ca":"mintFor(uint256,address)","ad631abe":"BLO_PER_WEI()","ad63a469":"totalUsedTokens()","ad64ae4b":"registerModule(address)","ad64fa5c":"MINBET_forORACLIZE()","ad652cdd":"InternetMarket()","ad655998":"addAuthorizedInsertAgent(address)","ad65d76d":"ethToTokenTransferInput(uint256,uint256,address)","ad66de24":"impl_lock4Dividend(address,uint256)","ad66e52a":"etherBalance()","ad677d0b":"join(bytes32)","ad686011":"returnPurchase(address)","ad68ebf7":"migrate(address,uint256)","ad69644b":"setBestAngel(uint32)","ad69caa5":"expMod(uint256,uint256,uint256)","ad6a0546":"creatorsLocked()","ad6ad449":"HodlerMining()","ad6aefbb":"BeatTokenPreIcoStarted()","ad6b2c90":"getListTokens(address,uint256,uint256,uint256)","ad6b5d04":"amountClaimed()","ad6b9499":"getContactRecord(string)","ad6c8762":"paymentChannelsCount()","ad6cd14e":"EthLongExercised(address[2],uint256[8],uint256,uint256)","ad6d9b89":"bytetherOVAddress()","ad6dfe5c":"getPRewardId(address,uint256)","ad6e155e":"setContractPreICO(address)","ad6eba9f":"getSingleSubjectByAddress(address,uint256)","ad6eff22":"getUserType(address,address)","ad6f80ff":"getSignatures()","ad70810a":"getChainDrawings(uint256)","ad70fbc8":"QuickChain()","ad714012":"calculateMatchOutcomesForRoundId(int256)","ad71766e":"getWeiSoldToday(address)","ad717e8c":"_oraclizeQueueRound()","ad71a1fd":"MAX_SUPPLY_OF_TOKEN()","ad71c687":"registerSystem(string,string,string,string)","ad7222c1":"tokensAmountFrom(uint256)","ad723faa":"MChip()","ad72dce9":"buildFactory(uint8,uint256)","ad731de7":"createPromoCollectible(uint256,address,uint256)","ad732eea":"send(bytes20[])","ad7411e1":"CreateNertia(address,uint256)","ad7430cc":"RECEIVER()","ad74f9bc":"calculateCurrentPrice(uint256)","ad7554d9":"setDoubleRewardEndTime(uint64)","ad76325f":"finishProposalVoting(uint256)","ad7639fe":"TokenPurchase(address,address,uint256,uint256,string)","ad76423e":"DelphiToken()","ad764780":"OpenController(address)","ad7738b6":"MAX_TOTAL_ADOPTED_AXIES()","ad78dc8e":"totalWannaBuyAmount()","ad78f31a":"ticketStringFromAddressBytes(bytes32,address)","ad796b5d":"TOKEN_SUPPLY_AIR()","ad79c927":"TokenSwap(address,address,address)","ad7a14e1":"tokenRemainPublicSale()","ad7a5ff9":"autoDistributionViaETHContributions()","ad7a672f":"totalBalance()","ad7b09c5":"InitIcoController(address)","ad7b6884":"editContributors(address[],uint256[],uint256[])","ad7b6cb5":"bountySEEDSinWei(address[],uint256)","ad7bafc7":"mint(int256,address,uint256,uint256)","ad7bfd2d":"Cashchain()","ad7c66d0":"sellAllMilk()","ad7d59fc":"checkPlace()","ad7df080":"consul()","ad7e01c8":"wolkGenesis(uint256,uint256,uint256,address,address)","ad7e262c":"hasEmployerMinRatingsCount(address,address,uint256)","ad7e74f9":"addJobSkill(uint32,bytes32)","ad7e7cfc":"UpdateMaintenance(bool)","ad7ead58":"walletLock()","ad7eb560":"block5()","ad7ed3c2":"executeLottery(address)","ad7ed923":"ElepigToken()","ad7eee9f":"updateInt256s(bytes32[],int256[])","ad7f02b5":"balanceOf(address[16],address)","ad7f401b":"creatorInited()","ad7f9d76":"getInvestorBuyers()","ad7fa43c":"settleFeeSecondPart(address,uint256)","ad7fadc5":"buy(address,address)","ad7fff7c":"hasWorks(bytes32)","ad8088a5":"XdacToken()","ad80a7b4":"totalUndistributedDividends()","ad80ef94":"tokenExchanges(uint256)","ad810fe5":"holderIndex(uint256)","ad818071":"showStats()","ad81cd90":"villagesSold()","ad81d6f3":"createDefaultLinglongCat(uint256,uint256,uint256,address,uint256,uint256)","ad81f3be":"Barneys4HackerSpaceToken()","ad82ae61":"internalDoubleTransfer(address,address,uint256,address,uint256)","ad82dcac":"testBlockhashCorrectFee()","ad838107":"_checkDestination(address,address,uint256,bytes)","ad83bfce":"GetOwner(string)","ad845d2d":"toBytes()","ad84e1be":"createTokenContract(address)","ad84e2a6":"getCrab(uint256)","ad84eaab":"minimumPurchaseAmount()","ad869e1a":"_batch3_icosaleEndTimestamp()","ad86c10d":"GamingCoin(string,string,uint8)","ad86ee0b":"passOnContract()","ad8718c2":"Create(uint256,uint256,uint32)","ad8733ca":"multisend(address,address[],uint256[])","ad879a46":"cancelBetByA(uint256)","ad886326":"_isSignedOwner(bytes32)","ad889f03":"USER_TIMEOUT()","ad88d8a5":"try_pay(address,bytes12)","ad88f53e":"setFirstStageEndsAt(uint256)","ad89e64b":"_updateLandData(int256,int256,string)","ad8a9c8e":"ownerSetOwner(address)","ad8ae3ae":"poke(address,bytes32)","ad8b4698":"COMETUBU()","ad8b6657":"_createDrone(address,uint256,bool,bool)","ad8c3cd2":"setTank(address)","ad8ce06b":"gasPerTx(bytes4)","ad8d36cb":"CCH_EDIT_2()","ad8d5f48":"exec(address,bytes,uint256)","ad8ead69":"createTeam(string,uint256)","ad8ed335":"__proxy(address)","ad8f5008":"strike()","ad8f905d":"PoolPrize(uint8,uint8,uint256,uint256)","ad8fccf3":"freezeMulti(address[],bytes32[],uint256[],uint256[],uint256[])","ad906661":"add_to_ico()","ad913633":"getOriginalOwner()","ad9171df":"getRemainingLimit(address,address)","ad92e46c":"getNumBettings()","ad93640f":"TRANSFER_PROXY_V2()","ad94d901":"ownsAll(address,uint256[])","ad9657f4":"createCoin(uint16,string)","ad966a03":"_bytes32ToString(bytes32)","ad973d74":"addCustomer(address)","ad976c3e":"setData_24(string)","ad979417":"setPoolName(string,uint256)","ad98ebaf":"ProjectManager()","ad994621":"answerDeliveryChallenge(address[2],uint64,bytes32[],uint256[],uint256[2],uint256[2],uint256,bytes32[3],uint8,bytes32[])","ad9a9f17":"SINGLE_BLOCK_LEN()","ad9abf32":"payDividends(uint256,uint256,uint256)","ad9ac1bc":"addToAllocationList(address,uint256)","ad9b4fc5":"Win(address,uint8,uint256,bytes32,bytes32,uint256,uint256)","ad9b8024":"price(address,uint256)","ad9bdebb":"isReleasable()","ad9c280f":"setLoveUrl(string)","ad9d4ba3":"depositEth(address)","ad9df055":"adminClaimAirdrop(address)","ad9e3e85":"My2Token()","ad9ec17e":"setGreyToken()","ad9f20a6":"MIN_PRICE()","ad9f9a68":"withdraw_unclaimed_balance(uint256)","ad9fb75e":"teamDate()","ada0114c":"Firstsale()","ada018e1":"setBurnFeeAbs(uint256)","ada0618a":"CATSPACE()","ada06dac":"tokenSaleCosts()","ada14698":"killSwitch()","ada199dd":"setFoundersTokensPercent(uint256)","ada1a34b":"resetVoteKindnessEvery()","ada1a8f7":"VUP_PER_ETH_ICO_TIER2_RATE()","ada1b74e":"finalTokensIssueTime()","ada1f3ad":"ReferralContract(address,address,address)","ada24dfc":"KeberuntunganAcak()","ada2cced":"getNumberSuppliers()","ada44092":"addClient(bytes32)","ada4c022":"getAvailableWinnings(address,address)","ada5ba01":"getNodeIndexId(bytes32)","ada5cf63":"initializedBlock()","ada636ce":"compareStages(string,string)","ada65728":"Funding_Setting_funding_time_end()","ada69935":"PonicsToken(string,string,uint8,uint256)","ada6b1d9":"collectedCent()","ada6e537":"AuctusBountyDistribution()","ada7061b":"add_hard_limit(uint256)","ada791f9":"Airdrop(address,uint256,uint256,address)","ada8938f":"moedaToken()","ada8a7d5":"presaleTotalNumberTokenSold()","ada8cfcd":"removeUint256s(bytes32[])","ada8e5ef":"IsCanAllotAward()","ada993ad":"Airdrop(address,uint256,uint256)","adaa19cc":"TGMtoken()","adaa3c73":"enableBets()","adaa730e":"RollDice(address,uint256,uint256,uint256)","adaaa1e1":"addThing(bytes32,string,bytes32,string)","adaabaaa":"bonusEndDate()","adabc7f8":"changeTransferStep(uint8)","adacb0fa":"CloseChannel(bytes32,uint8,bytes32,bytes32,uint256)","adaccd74":"getNickname(address)","adad1cb1":"VisperNetwork()","adad4873":"distributePresale(address[],uint256[])","adad6d50":"KujiraFund()","adad9c4e":"increaseMaxCap(uint256)","adadb11f":"setJotter(address)","adadc77f":"unown()","adae08dd":"createItem(uint256,uint256)","adaea0b9":"fund(address,address,bool)","adaf28d1":"whichPeriod(address,uint256)","adaf7c84":"PreICOStartTime()","adaf8c79":"chargeOn(address,uint256)","adb187bb":"validRequest(bytes32[],bytes5,address)","adb1ad42":"HelloGoldToken(address)","adb1cd73":"getUnpaid()","adb1f640":"getScore(uint256,bytes32)","adb27ded":"tokenBonusTimes(uint256)","adb2e02f":"internalRegisterCert(bytes32,bytes,uint256)","adb37277":"setWebsiteUrl(string)","adb3a3a6":"deadlineToFreedTeamPool()","adb42139":"totalCrowdsale()","adb44a32":"updateUint256(bytes32,uint256)","adb4af3e":"getLatestUpdate()","adb4d990":"assigned()","adb506a6":"FACTOR_5()","adb5735c":"withdrawFor(address,address)","adb5777c":"getDrawBlockNumberByWinner(address)","adb5a4f1":"ListReservePairs(address,address,address,bool)","adb5a54d":"eccVerify(bytes32,uint8,bytes32,bytes32)","adb5da34":"_getClientPaidUpTo(address)","adb610a3":"currentNonce()","adb67c41":"XiongDiLianToken(address,address)","adb6859d":"directorTransferShareRequired()","adb6e8f5":"GetDislikeCount()","adb6f63f":"commitments(address,address)","adb746dc":"bltOwned()","adb77576":"etherLeaked(uint256)","adb8249e":"increaseApprovalPreSigned(bytes,address,uint256,uint256,uint256)","adb848df":"NZD_Omnidollar()","adb88cb9":"totalSupplyIco()","adb9066e":"COLDITION()","adba54e0":"commandPercent()","adbc9bed":"getRestWhite(uint256,uint256)","adbd9753":"issuingTokenOwner()","adbda5a8":"voteToKickoffNewFiscalYear()","adbde797":"updateTrustRankAfterStoryExpiry(bytes12,bytes12[])","adbe2f6f":"abortive(uint256)","adbefffe":"getAddressBetsForEvent(bytes32,address)","adbf29fd":"getPlayerDataForGame(uint256,address)","adbf54b7":"initialBalanceForMarketingCampaign()","adc02a64":"addAsset(string,address)","adc042bf":"mint(int256,uint128)","adc06ccd":"batchDoubleBalances(address[])","adc128eb":"Today()","adc1463a":"ZLCC()","adc1b956":"lastClaimed()","adc1db89":"SpaceKIMToken()","adc1f702":"LanaCharleen8()","adc20b1c":"lastMint(address)","adc23f03":"canClientTerminate(bytes32)","adc29028":"calcAndSetPlayerTotalCanAccept(address,uint256)","adc2c98a":"edge()","adc38b2f":"iterateTurn(uint16)","adc4739a":"setWLAddress(address)","adc4f654":"ChargeEnergy(uint256)","adc54d30":"transferFromPresale(address,uint256)","adc6d49d":"_executeTransaction(uint256,address)","adc73d46":"getPlayersOfOwner(address)","adc7d448":"_clearAttackLog(uint256)","adc84a42":"SVEToken()","adc87956":"teamVestTokenAllocation()","adc8b4cf":"empowerAdmin(address)","adc8f941":"addExclusionFromTokenUnlocks(address[])","adc9772e":"stake(address,uint256)","adca32e7":"setFiscal(uint256,uint256,uint256,bytes32)","adca8ac6":"addToTransferWhiteList(address,address)","adcaea0a":"simulated_snt(address)","adcb0993":"LILE()","adcccb6f":"Obirum()","adcd2632":"saleTeamAddress()","adcd4aaf":"sendNegativeWhuffies(address,string)","adcd905b":"setListener(address)","adcde05f":"averageKimSalePrice()","adce1c5f":"ensResolver()","adce80d5":"mStopped()","adcf4831":"registerAuditOutcome(address,bytes32,bool)","adcf59ee":"isOwnerOrOps(address)","adcf780a":"disallowTransferBetweenUsers()","add052b4":"getStateFunding()","add08f87":"coinbaseAmount()","add1cbc5":"TOKEN_TRANSFER_PROXY_CONTRACT()","add2af69":"releaseLockedTokensByIndex(address,uint256)","add37100":"getOrderHash(address,uint256,address,uint256,address,uint256,uint256,address)","add3bf39":"manualTransferTokensToInternal(address,uint256,uint256,uint256)","add3fa39":"sharing_confirmed()","add40ced":"getKeyID(bytes20,uint8)","add43c59":"EtherTopDog()","add466a4":"chfCentsPerTokenWhileBonus()","add4bfb0":"createDragon(uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint16,uint16)","add4c784":"getResult(bytes32)","add54303":"setBlock(uint256,uint256,string)","add5eb02":"setAdminVariables(uint256,uint256,uint256,uint256)","add68daf":"amountOfBidders(uint256)","add7690b":"period0End()","add769a3":"POOToken()","add82871":"strEqual(string,string)","add84df3":"changeGoal(uint256)","add94f25":"IDAP(address,address,address)","add98c70":"dispute(bytes32)","adda1d4d":"receiveListing(bytes32,uint256,bool,address,uint256,uint256)","adda8cf4":"Propvesta()","addace62":"getYesVotes()","addad094":"VLOGS()","addb246b":"MIN_SITE_ID()","addb51ff":"monsterCreator()","addd5099":"oracles(address)","addd7020":"minWei()","adddbacb":"tokenSellCap()","adde36bb":"betEven()","adde61ef":"_isUpdateAuthorized(address,uint256)","added436":"sendFromFund(uint256,address)","addf0813":"withdrawERC20Balance(uint256)","ade05b35":"commissionType()","ade077e3":"Ecoin()","ade0e93e":"withdrawals()","ade2f939":"lookupAllSince(uint256)","ade4637a":"transferFrozen()","ade53c4e":"GenChipsLevel(uint256,bool)","ade5a328":"YYXToken()","ade5e07d":"test_1_validOwner_accessRestriction()","ade60e9a":"modifyOwner()","ade645fa":"bonusPhase2()","ade6e2aa":"expiryTimestamp()","ade716e5":"activatedArbitrationTokens(address)","ade7a3ad":"totalParticipationAmount()","ade7dd7b":"storeInvestment(address,uint256)","adeaa851":"getTotalPrize()","adeb8dec":"setLocks(address[],uint256[])","adeba3a5":"payWithdraw(address)","adebf6f2":"isFungible(uint256)","adec07c7":"setPriceUpdateInterval(uint256)","adec3a92":"totalPonziInGame()","adeca283":"payeeArray()","adee3f4b":"getCodeType(uint256)","adefc37b":"sub(int256,int256)","adefd501":"ledMultiSig()","adf069ea":"startsWith(string,string)","adf07791":"tenant()","adf0c351":"add_participant()","adf13281":"mineFor(address,bytes32)","adf24dec":"setDemurringFee(uint32,uint32)","adf272ab":"vest(address,uint256,uint256,bool)","adf2cead":"mint(bytes32)","adf2d029":"calculateAdminTxHash()","adf2ef99":"ReichaCOIN()","adf2f978":"getCurrentDragonGirlLotteryNumber()","adf403ad":"capitalReserveWallet()","adf46a39":"createContractDank(string)","adf4a144":"startRefund()","adf4fa09":"addPurchased(address,address,uint256,uint256)","adf54e0c":"betOnLowHigh(bool,bool)","adf59f99":"query(uint256,string,string)","adf5d1cb":"YumeriumToken()","adf5e565":"verify(bytes,address,uint256,uint8,bytes,bytes)","adf60404":"THreeDBToken()","adf684ac":"ULChain(address,uint256)","adf6e486":"unPauseToken()","adf70883":"completeUnlockTime()","adf74fc9":"distributeELTCMedium(address[])","adf8a01b":"emitSkillEvaluated(address,address,uint8,uint256,uint256,uint256)","adf8f79d":"LOG_ContractResumed()","adf96752":"trade(address[13],uint256[15],uint8[2],bytes32[2],bytes32[2])","adf9a754":"forwardFundsToOwner()","adf9cd49":"totalWeiCap()","adf9ffea":"lockupOf(address)","adfa1f0c":"Pinged(string)","adfa820a":"deleteBlockState(bytes32)","adfa845a":"test_remove_notInList()","adfaae32":"lastMinedOn()","adfc36a3":"getAssembly(uint256)","adfceb9a":"proxyBuy(bytes32,address)","adfd5380":"preTgeBonus()","adfd7935":"setBridgeNode(address,bool)","adfdb75e":"setRedeemRequestLimitInterval(uint256)","adfdc12f":"createNewGame(string,string,string,uint256)","adfe1190":"components(uint16)","adfe6b80":"InvestAdd()","adfec5f5":"buy(bytes8)","adff2450":"getOuverture_effective()","adff5f36":"PanamavsTunisia()","adffe4db":"setFundingRules(address,bool,uint256,uint256,uint256,uint256,uint256)","adfff41d":"m_Data(address,uint256,uint256)","ae0041aa":"signalCount()","ae005a87":"ERC777DemoToken(string,string,uint256,uint256,uint8)","ae012367":"withdrawTopForTeam(address,uint256)","ae014f1d":"getUserNameByWallet(address)","ae01a8fb":"toCloseVote()","ae01ab47":"setFracoinAuction()","ae01c14f":"SendBid()","ae01dd06":"noteDesignatedReport()","ae01ed8a":"manualWithdrawalFallback(address,uint256)","ae024c40":"isTopic(bytes15)","ae0250c1":"showPoolNumber(address,address)","ae025faa":"newGroup()","ae0269aa":"VirtuePokerSale()","ae02ee5b":"pack(bytes,address,address,uint8,uint256)","ae035846":"END_TIME_SALE()","ae0395ad":"setFriendsFingersWallet(address)","ae03f754":"GongPanToken()","ae040b1d":"get_orderAddress(address,uint256,uint256,uint256)","ae041b90":"WRLCrowdsale()","ae043336":"dolRate()","ae04d45d":"setLockTime(uint256)","ae056477":"addInvestorBalance(address,uint256)","ae06494e":"createHNtokens(address)","ae065737":"tradePreToken(uint256,address,address,uint256,address)","ae06c1b7":"setFeePercentage(uint256)","ae0755d3":"popTransaction()","ae078036":"preICO_tokens()","ae08b8b3":"BUXCOINMONEYCONTRACT()","ae093eb7":"sendICOTokensBack(uint128)","ae0996fc":"getMyEOSKey()","ae0a6b28":"signature(string,bytes32)","ae0aba8c":"acceptPayment()","ae0b4edd":"cancelSellOrder(address[])","ae0b7bdb":"twoWeeks()","ae0bbe4d":"approveRecipient(address,bool)","ae0be41c":"periodPreITO_hardCapInWei()","ae0db13c":"totalBidEth()","ae0e5387":"networkReserveFund()","ae0e8725":"Checkable()","ae0e8f3f":"strategicLockup()","ae0eadbf":"isFirstStageTokensMinted()","ae0f6166":"subtract(int256)","ae101f31":"addStage(uint256,uint256,uint256,uint256)","ae104265":"calculatePrice(uint256)","ae117f3e":"getFSTBalance()","ae11cf73":"isVerfied()","ae11ea9b":"transferChild(address,address)","ae125f00":"mint(uint256,address,bytes32,bytes32,bytes4)","ae1345c4":"CharterCapital()","ae136d62":"firstBonusEnds()","ae13efe0":"batchFreeze(address[],bool)","ae152cf4":"oraclize_query(string,string,uint256)","ae154aab":"passOff()","ae15eb8e":"getCertificate()","ae1616b0":"airdropReserveWallet()","ae169a50":"claimReward(uint256)","ae180337":"withdrawBaseERC20(address)","ae181958":"_setNonlistedUser(address)","ae181f84":"passThroughTap(uint256)","ae188884":"sendOneEtherToMiner()","ae18f5ad":"issueContractAddress()","ae190819":"getBS(bytes32)","ae1a0b0c":"launchLength()","ae1a15e3":"PresaleFundCollector(address,uint256,uint256)","ae1a5611":"ratePerEthPhase2()","ae1a9a3e":"castToUint(int256)","ae1aafb9":"buyPredictForContract(address,uint8)","ae1adba2":"calculateStakeGains(uint256)","ae1b4beb":"buyFactorPromotion()","ae1b6405":"endICOTime()","ae1be1e4":"releaseLockedToken()","ae1c4062":"stopStage()","ae1c9437":"_stringsEqual(string,string)","ae1cad3a":"tip(address,string,uint256,string)","ae1d12a6":"WhyWhyToken(address)","ae1d3043":"teamTimeLock2()","ae1d4b4b":"GambleEther()","ae1dd78c":"sendEtherManually()","ae1e2096":"MAGICCOINERC20(uint256,string,string)","ae1e964e":"newOwnershipFeeProposal(uint256,string)","ae1f14ca":"mainSale_WeiRaised()","ae1f91b7":"updateMinMaxBetCount(uint256,uint256)","ae1fb61a":"TokenTransferProxy()","ae200c73":"joinGameTeam(bytes32,uint8)","ae2022c0":"getUint256Max(int256)","ae203146":"getAccountType(address)","ae2074c8":"addWhiteListAddress(address,address,uint256)","ae20bf15":"claimFreeEggs()","ae224633":"videos()","ae22c1be":"ShowRelease(address,uint256)","ae22e331":"_getCurrentSchellingRound()","ae249f2b":"destroyWhenRoundOver()","ae24e328":"tickerQueryData()","ae25532e":"getProxyId()","ae25753b":"wildcardsHeld(address,uint16)","ae25f630":"DownPlayerResult(string,address,uint256,uint256,uint256)","ae262114":"crowdSaleDragonPrice()","ae263730":"isOperationAllowed()","ae26588c":"removeTrustedContractAddress(address)","ae277584":"amountToSend()","ae27e3c6":"relu_activation(int256)","ae28b68c":"safeTransfer(address,uint256,uint256,bytes)","ae28e912":"teamTokenAmount()","ae2a0ce3":"JustinsToken()","ae2b4e16":"getBalanceInRemix(address)","ae2b5d3b":"_emitCountryCodeAdded(uint256,uint256,uint256)","ae2bd2bd":"clearAuction(address,address,uint256,uint256)","ae2c1506":"getRoundNumberOfBets(uint256,uint256)","ae2c923c":"OlympusLabsCore(address)","ae2cbc91":"Tradable()","ae2da5c5":"getLLV_edit_20()","ae2df7b3":"setImporterBank()","ae2e054c":"closeOrder(uint256,address)","ae2e933b":"feePool()","ae2f1f6f":"calculatePayerDeposit(uint256)","ae307098":"c_MinInvestmentInCents()","ae30d35d":"ARK_TROGLOg_1_00()","ae3125d9":"showTokenSaleClosingTime()","ae319f60":"_updatePurchasingState(uint256)","ae31deb9":"burnCrowdsale()","ae326221":"setSpawnProxy(uint16,address)","ae327322":"cantSetReferrer()","ae32ac7e":"TEAM_LOCK_DURATION_PART2()","ae32c399":"lastBlock_f1Hash_uint256()","ae353131":"BiquToken(uint256,string,string)","ae35707d":"sectionForSale(uint256)","ae35d21a":"CollectibleBidWithdrawn(uint256,uint256,uint256,address)","ae366735":"EQUIPMENT_REWARD_WALLET()","ae36c602":"createPromoItem(address,string,uint256)","ae36f6f9":"_batch4_rate()","ae382baa":"GainCard(address,uint32)","ae39279f":"sendFee()","ae3b2137":"getRoomSetCount(uint256)","ae3b748d":"setMinCap(uint256)","ae3b94b2":"_minimumTokens()","ae3baf4d":"mintableAmount()","ae3c697c":"getMyAvailableWine()","ae3d27ed":"Token_For_Circulation()","ae3d5047":"_changeSymbol(string)","ae3d7160":"compareByte(string,string)","ae3d81b8":"allowedJurisdictions(bytes32)","ae3f4a6c":"test_3_method()","ae3f84f3":"proofMultiSig()","ae3fc899":"CheckExchange(string)","ae404996":"oraclize_query(string,string[3],uint256)","ae40f72f":"testAdd()","ae41480b":"importEthers(address)","ae422c09":"sys()","ae42ce85":"update_oracalize()","ae436b5e":"getLimitedReporterMarketsCount()","ae44dea2":"bytesToUInt(bytes,bytes32)","ae44e840":"priceConfirmedOver500()","ae4538ce":"walletCompanyReserve()","ae457835":"buyTokensFor(address,uint64,uint256,uint8,bytes32,bytes32)","ae457dab":"bonusEnds20()","ae45850b":"schedulerAddress()","ae458ab6":"approve(uint64,address)","ae466db7":"withdrawPenaltyTokens()","ae46e284":"setPortfolio(uint256,bytes32[],uint8[])","ae479a63":"badgeSymbol()","ae47a290":"changeMaxBet(uint256)","ae487dad":"reset(uint256,uint256,uint256,uint256,uint256,uint256)","ae49165a":"getAncestor()","ae49a717":"EVNT()","ae4a7512":"mintICOTokensFromExternal(address,uint256)","ae4a8c88":"claimLoot(uint256,address)","ae4aadbb":"showTransferConfigs()","ae4ab7ce":"Put_DEDI_gift(address)","ae4ac63e":"STANDARD_BUYIN()","ae4b1b5b":"proxyStorage()","ae4b5cb8":"collectDonations(uint256,address)","ae4b76fe":"_createPiranha(string,address,uint256,uint8,uint256,uint8,uint8)","ae4c20af":"increaseICOcap(uint256)","ae4c5e45":"setStarNewOwner(uint256,address)","ae4cc757":"closeEarlyPurchase()","ae4d0ff7":"gen0StartingPrice()","ae4d1af6":"setup(bytes32,address,address)","ae4d42b8":"ptxTail()","ae4d503b":"withdrawOtherERC20Balance(uint256,address,address)","ae4e7fdf":"isMature()","ae4eba1f":"setOldE4(address,address)","ae4f1198":"publicationFeeInWei()","ae4f1476":"searchSeed()","ae4fbdeb":"LastValidated()","ae501c75":"LogLotteryResult(uint32,uint8,bytes32,bytes)","ae50d660":"setFilletPrice(uint16,uint16,uint8,uint256)","ae5103e8":"preSaleFourthPrice()","ae516449":"uintCeil(uint256,uint256,uint256)","ae51c484":"a(bool)","ae51db0d":"VesaStage2PreICO()","ae52026f":"icoSoftCap()","ae529499":"CurrentARXSupplyInWei()","ae530504":"setSetting(string,uint256)","ae53d79e":"ICO_PRICE7()","ae5409fb":"seedInvestorsReserve()","ae55c888":"getData(string)","ae55f1af":"artWorkChangeApprove(uint256,uint256,bool)","ae56e668":"setUnlockAddress(address,bool)","ae5942cd":"deletePermissions(address[])","ae59bd5a":"mintManually(address,uint256)","ae5a1460":"NewDigitalAsset(address,address)","ae5a17a7":"updateCharityAddress(address)","ae5a4a7f":"maxBatchAssignment()","ae5a9bb4":"operatorTransfer(address,uint256,bytes,bytes)","ae5a9d17":"getCompletedTransactions()","ae5adac7":"mintInCurrPeriodCount()","ae5b2540":"setApp(bytes32,bytes32,address)","ae5b6d89":"submitSteak(address,bytes32)","ae5c1816":"CreateKittyToken(address,uint256,uint32)","ae5c24bd":"getFirstElement()","ae5c37fd":"contributionsByIntel(uint256)","ae5c3f14":"getVipBrokerNum()","ae5c75aa":"getBadgeByKtUserId(uint256)","ae5c888d":"month60Unlock()","ae5d2cbe":"_getOwnerTokenByIndex(address,uint256)","ae5da7a0":"_generateGame(bytes32,bytes32,address,uint256[10])","ae5dbd43":"view_get_ResultData()","ae5e6cf4":"cancelReservation(uint256)","ae5ec2e9":"matching()","ae5f502e":"RoundSubmission(uint256)","ae601e4d":"IADForGas()","ae602223":"standFeeAfter500()","ae610b48":"sign(int256)","ae61fcda":"isEthernautsStorage()","ae6215d8":"getBlockHeight(bytes)","ae622c4b":"addToInxWhitelist(address)","ae62fd7c":"setCrowdSale(bool)","ae639329":"sendTo(address,address,uint256)","ae63b517":"ADVISORY_BOARD_TOKENS()","ae640923":"playerEndGame(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address,bytes)","ae6439c4":"icoSaleSoftCap()","ae6506f9":"getCurrentTierIndex()","ae665d5d":"MooguToken()","ae66d948":"getWithdrawn(address)","ae6751e2":"EmilTestCoin()","ae67701f":"ZperPreSale(address,uint256,uint256,uint256)","ae67b4c3":"evolveAxie(uint256,uint256)","ae68c80a":"AddRocket(uint32,uint64,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint64,uint32)","ae68fb83":"creditShareProvision(uint256,uint256)","ae69a893":"getHeirCount()","ae69ccdc":"GMSToken(uint256,string,uint8,string)","ae6a19af":"tokensSoldLimit()","ae6a1c30":"setApprovedWallet(address)","ae6a2435":"HOST_CUT()","ae6a70ee":"_tokenMetadata(uint256)","ae6b0792":"paymentManager(string,address,string,uint256,uint256)","ae6c0b03":"canWithdrawBond(uint256)","ae6caafd":"buyByBot(uint256,uint256,address)","ae6d8a52":"viewFourthLotOfClauses()","ae6dca72":"_allocate(address,uint256,uint256)","ae6e11dc":"terminateTokenLock()","ae6e22f1":"totalEther()","ae6f1db6":"payableFinneyReceived()","ae6f5bd2":"_calResultReturnIsWin(uint256,uint256)","ae702ba4":"isSubscriptionActive(bytes32,uint256)","ae70609e":"LogResult(uint256,address,uint256,uint256,uint256,int256,uint256,uint256)","ae708e7c":"totalConsideredFundedEther()","ae71d5da":"initProceeds(address,address)","ae721e45":"fetchOrdersForPayerByAdmin(address)","ae748575":"CGCM()","ae748837":"addTestimony(address)","ae75c4f7":"rewardsTokensVault()","ae75f9e6":"mock_resetLatestTokenAllocation(address,address)","ae76145d":"SEXcoin()","ae7635f2":"icoEndUnfrozeTokens()","ae764df3":"ICOWallet()","ae775b27":"betOnDozen(uint8)","ae77a6f4":"goldBalance()","ae77c237":"purchase(uint256,address)","ae77d51f":"m_chiefOwnerIndexBit()","ae788913":"AIHToken()","ae788b34":"ILFManagerCandidate()","ae799f4a":"TokenERC20(string,string,uint8,uint256)","ae7a45ba":"addZethrAddresses(address,address)","ae7a833d":"hydroContract()","ae7ad3fd":"setUpgradeabilityOwner(address)","ae7b0333":"executeOrder(address,uint256,uint256)","ae7b1620":"rushTimeChallengeRewardsPercent()","ae7b3825":"exchangeForETH(uint256)","ae7b6bd9":"getLatitude()","ae7b6daa":"numberOfCellsOwnedBy(address,address)","ae7c046b":"applyAllPermission(address,address)","ae7d00f3":"validationPrice()","ae7d0cac":"addShare(address,uint256,uint256)","ae7e23cc":"otherCoinsPurchase(bytes32,uint256)","ae7ed04c":"getLastBidForCanvas(uint32)","ae7f5da4":"lockPeriod2()","ae7fa597":"removePrize(uint16,address,uint256)","ae7fc1da":"_randMod(uint256,uint256)","ae7ffadc":"Bitway()","ae813029":"makeBid(uint16,uint256)","ae813ebb":"TokenFactoryAirdropCoin()","ae815843":"query(uint256,string,string,uint256)","ae817dd1":"doSendBounds(bytes32)","ae818340":"getProfiles(address[],string[])","ae81a54b":"factTeamOf(uint256)","ae81f51b":"mintTokens2(address,uint256,uint256)","ae8205e3":"insert(bytes32,int256)","ae82fcf4":"teamLocked()","ae83ed91":"HashBlock()","ae8421e1":"done()","ae850da9":"getNumberSources(uint256,uint256)","ae873405":"AVG_BLOCKS_24H()","ae873fa5":"PRESALE_MAX_RAISE()","ae87fc4b":"claimStatus()","ae87fd06":"gasPriceLimit_()","ae882412":"getTotalDivsProduced()","ae882cf1":"allowSpecies(uint16,uint16,address)","ae896b2e":"TPN()","ae89a29e":"maxHolderCount()","ae89aeb9":"getEscrowData(uint256)","ae8a6833":"InitialSettings()","ae8a7180":"setStartOfCrowdsale(uint256)","ae8a8690":"createActivePreMintedEdition(uint256,bytes32,uint256,uint256,uint256,address,uint256,uint256,string,uint256,uint256)","ae8b9d7b":"autoSolveGame(uint256,uint256,uint256)","ae8bce2c":"product1_pot()","ae8cdd59":"IBTC(uint256,string,string)","ae8dab48":"setUp(address,address,address,address,address,address,address)","ae8e2217":"SmartexController()","ae8e3b70":"Fin()","ae8efe46":"CheckEntity(bytes32)","ae8f1d29":"createPermission(bytes32,address[],bytes4[])","ae8f2328":"finishcrowdsale()","ae8f6489":"createAndBuyAllAmountPayEth(address,address,address,uint256,address)","ae9074ff":"internalSuccessOver()","ae90b213":"payee()","ae90e9f8":"returnToBuyersContinue()","ae91b691":"changeRefPercentage(uint256)","ae92b204":"getCurrFeeRate()","ae93e513":"cancelOfferForCity(uint256)","ae94bbf1":"getCarDetails(uint32)","ae94e448":"imax(int256,int256)","ae94ec05":"placeBuyTokenOrder(uint32)","ae954790":"Authorizable()","ae9569d0":"PLATPriceOracle()","ae95a7a4":"TacoToken(address,string,string,uint256,uint256)","ae95c24e":"issueMap(address)","ae96b094":"VergeDark()","ae96bf2c":"TakePot()","ae9759ff":"PRICE_MULTIPLIER_ICO2()","ae978f08":"getLatestTweet()","ae97dde8":"MAX_COMMISSION()","ae989d36":"homeTeam()","ae99847b":"daylimit(uint256)","ae999ece":"reserve(string)","ae99aa3c":"getMemberInfo(uint256)","ae99f03c":"SetAddresses(address[],address[],address[],address[])","ae9a0785":"getChannelPostCount(address)","ae9a9295":"YKC(uint256,string,uint8,string)","ae9aea6d":"maxMintQuantity()","ae9b051c":"withdrawSome(uint256)","ae9c1962":"withdrawCommunityPot()","ae9dc04c":"offerSketchForSaleToAddress(uint256,uint256,address)","ae9f96c7":"weightsApportion(uint256,uint256)","aea01c49":"stringToBytes(string,string)","aea09e6e":"crowdfundStartTime()","aea0e35f":"createMarket()","aea13844":"safeGiveByContract(uint256,address)","aea1935b":"confirmEndWork(uint256)","aea197fe":"CreateRecipt(string,uint256,string,string,string,string,string,uint256)","aea31fc7":"setProof(string,string)","aea398da":"paymentWalletAddress()","aea3ad8c":"supportKickoffQuorum(uint256)","aea40787":"SetOwned()","aea43a29":"addMassAddressToWhitelist(address[])","aea452ba":"isBinding(uint16)","aea48690":"incentivisingEffortsSupply()","aea57be4":"resumeIEO()","aea5b69f":"solutionInfo(uint256)","aea6022c":"change_metadata(uint256,string)","aea64763":"stopsale()","aea68d6b":"Shakedown0x()","aea6e1a4":"buyAnotherDrangon()","aea787a2":"showleveldetail(address)","aea8126f":"transferMSM(address,uint256)","aea8d47c":"getLatestContract(bytes32)","aea8dcca":"setTokenInfoMaxTotalImbalanceList(uint256[])","aea92852":"getDevIndex(address)","aea96513":"returnSecretVoteHash(uint256)","aea9b438":"getBuyerInstanceAddress(address)","aeaa3091":"getDealerValue(uint8[],uint8)","aeaaaa08":"proxyClaimTokens(address)","aeaabffe":"UnlockAll()","aeab24df":"reinvestDivsWithContract(address)","aeac3354":"Deal(address,address,address)","aeac529a":"TradingLife()","aeac538a":"ClimateCron()","aeaca25e":"getTotalJadeProduction()","aeacd658":"signProduct(string)","aead9e47":"claimAndWithdraw()","aeadbe24":"getTotalTokens(address)","aeae264b":"BeteventCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","aeaf5a37":"total_land_sold()","aeaf7fc1":"updateCandidate(address,bytes32,bytes32)","aeb00fda":"_getRacerCar(uint256)","aeb1355f":"getH2Amount()","aeb26733":"previligedApprove(address,address,uint256)","aeb27602":"addHash(string)","aeb2ffc1":"getQuery(uint256)","aeb37075":"DividendPaid(uint256)","aeb3ebd0":"LogContributorsPayout(address,uint256)","aeb447ff":"getLevelUpCost(address,address)","aeb47e2a":"COMMUNITY_POOL()","aeb4f0d3":"RegisterTwo(address,address)","aeb58dc5":"setPOOL_edit_15(string)","aeb669eb":"getHatchingEggId(address)","aeb754e5":"Auction(address,uint256)","aeb7614c":"bid(bytes32,bool,int32)","aeb7dd80":"_computeCurrentPrice(uint128,uint128,uint40,uint40)","aeb817ab":"etcSupply()","aeb89f14":"totle()","aeb8f966":"mintToken(address,uint256,int256)","aeb94f48":"getFreePacifist()","aeb9c40e":"isReadyToStart(uint256)","aebacd53":"PRE_BONUS()","aebad3a4":"getCaptainCount(uint32)","aebb2540":"setNewMultisig(address)","aebc0310":"updateOdds(uint256,uint256)","aebcd2d9":"AddSocialAccount(bytes32,bytes32,bytes32,bytes32)","aebd3f96":"receiveToken(address,uint256,address)","aebd4fcd":"shopStoreRegister()","aebe0224":"CollectibleTransfer(address,address,uint256,uint256)","aebe5523":"addTokenWalletInWhitelist(address)","aebf1e3d":"computeTokens(uint256)","aec02eb5":"ServiceContractResolver(address)","aec1914d":"surrender(bytes32)","aec1dd81":"updateNonClosingBalanceProof(address,address,bytes32,uint256,bytes32,bytes,bytes)","aec1ee7b":"STAT_MAX_VALUE()","aec205a5":"contractLaunched()","aec26c0e":"setLoanParameters(address,bytes32,uint256,uint256,uint256,uint256,uint256,string)","aec2f2d9":"first_bonus_duration()","aec30dc1":"minWeightPunish()","aec318f1":"enableMasterTransfers(bool)","aec3ab53":"_futureSupply()","aec4e0bb":"numberOfPunksReserved()","aec5ab08":"getAllDapps()","aec651fb":"getUserTokensByMatch(address,uint32)","aec72d8d":"STAGE_3()","aec77b63":"returnTokensInPool(address[],uint256[])","aec7f5b2":"JoustNum()","aec7f6f3":"compoundInterest(address)","aec8fae8":"getMemberAtKey(uint256)","aec9a987":"claimShare(address,address)","aec9c480":"includesSet(bytes32)","aecadd53":"grantTeamToken()","aecaf4ba":"addMoneyInternal(address,uint256)","aecbaaa1":"LogPayout(address,uint256,uint256)","aecbb5f1":"winAmount1()","aecbf70c":"Kisaan()","aeccee75":"_register(address,uint256,address)","aecd15e3":"getWithdrawalWallet()","aecd1fed":"setupToken(address,address)","aecd27fa":"linkCoin(address)","aecd46db":"testDepositCanbeWithdrawn()","aecdceef":"intToBytes(uint256,uint256)","aecfd412":"Group_2()","aed214fb":"setBooleanMapValue(string,address,address,bool)","aed29d07":"totalRewarded()","aed2e7d4":"addGen(uint256)","aed339ef":"storeHarvestOperation(bytes32,address,string,string,uint32,uint24,uint16,string)","aed362c1":"hasModerator()","aed396c6":"setStageBonus(uint256,uint256)","aed3ebe4":"TokenBCCO(uint256,string,string)","aed4839a":"transferFrom(uint256,address)","aed4aab6":"receiveERC20(address,uint256)","aed5c011":"payWithMerculet(uint256)","aed6512e":"callerAdd(address)","aed6d8d4":"GetStuffNum(address,uint32)","aed76aa4":"getInvestorDepositAmount(address)","aed82a99":"sin_table_lookup(uint256)","aed83846":"removeFromPrivateSaleWhitelist(address[])","aed89fed":"projectContract()","aed8e967":"getEndpoint()","aed8f3da":"partsPerBillion(uint256,uint256)","aeda10be":"ethselfToken()","aeda352b":"hasName(address)","aeda852f":"houses(uint256)","aedb1c8f":"executeContract()","aedb8621":"TMONEY()","aedb9eef":"LDXCToken(uint256)","aedbbf36":"deleteNote(uint64)","aedd18dc":"timeout(address)","aedd3acc":"currentSTCPrice()","aeddaa02":"DelVer(address,address)","aeddab95":"batchUnmount(address,uint256[],uint256)","aeddf677":"lockLimit()","aede4680":"firstReserveWallet()","aede879d":"whatIsMissing()","aedf5360":"icoCrowdsaleContract()","aee06324":"trickleUp()","aee0abaa":"authorizeMany(address[],uint256)","aee145f7":"addressReserve()","aee1b8a1":"XBStandardToken(uint256,string,uint8,string)","aee1d4d3":"blockCreationRate()","aee25613":"sendErc20(address,address[],uint256[])","aee2988d":"addressOps()","aee2dbbf":"getSaleOrdersBySeller(address)","aee338ef":"referalAddrByNum(address,uint32)","aee36731":"OrderApprovedPartOne(bytes32,address,address,address,uint256,uint256,address,uint8,uint8,address,uint8,bytes)","aee40270":"AddAddressToWhitelist(address)","aee4c502":"test_remove()","aee7052e":"startPhaseLength()","aee776ae":"stnExchange(address,uint256)","aee7e176":"finalBonus()","aee83b61":"TASOHATOKEN(uint256,string,string)","aee84f6b":"setTime(address,uint256)","aee8a3bd":"add2Auction(address,uint256,uint256,uint256,uint256,uint256)","aee92d33":"approveByLegacy(address,address,uint256)","aee98408":"versionIndex(bytes32,bytes32)","aee99e52":"getPresale()","aeeb96af":"Highlander()","aeec9ba0":"UpdateManifesto(uint256,bool,bool)","aeedc9e9":"GroupBuy()","aeeed0db":"buyXaddr(address)","aeefb9d1":"distributeEDNR(address[])","aeefb9eb":"PixelToken()","aef0004a":"outputAddress()","aef08617":"limitTier3()","aef093ce":"Doge2Token()","aef0ef2e":"test_validShouldBe3_2()","aef1b9b5":"test_threeInvalidFalseEqLog()","aef251a7":"tokenCtr()","aef3575e":"HandWinsView(address)","aef35e6a":"stage2Sale()","aef37284":"getReservedTokensListValInPercentageUnit(address)","aef3bc17":"getMemberInformation(uint8)","aef3fa6c":"AFROIN()","aef41e3a":"getItemIdsPagable(uint256,uint256)","aef5cbee":"VICToken()","aef5ddec":"Paper(string,address,uint256,uint256,address[],address)","aef721b8":"createSwap(uint256,uint256,address,address,address)","aef76dda":"createPresale(address,uint256,uint256)","aef7ad9c":"getSchellingRoundDetails(uint256)","aef88aba":"DDJATCoin()","aef8a536":"SCNToken(uint256,string,string)","aef95098":"setUrl(uint256,string)","aef983d0":"getDigitFromByte32(bytes32,uint8)","aef99eef":"Game()","aefa573d":"genCode()","aefa68f0":"ifInAllowedLocks(uint256)","aefa7550":"read_u32()","aefa7d98":"getContractAddress(uint256)","aefaacda":"finalTimeout()","aefb1643":"ownerSetPaused(bool)","aefb2dad":"ticketsFor(uint256,address)","aefb658e":"playerDayEthInLimit_()","aefbbf2a":"BANKROLLER()","aefc4ccb":"associatedContract()","aefc8c72":"unsealBid(bytes32,address,uint256,bytes32)","aefd0299":"makeWager()","aefe5ee0":"cashOutTank(uint256)","aefe696b":"changeColorPink()","aefe9ca0":"s40(bytes1)","aefea053":"timelockVault()","af0062e4":"sellable_tokens()","af00be12":"_sendToken(address,uint256,bytes)","af017526":"whitelistAddress(address,bool,uint256)","af01841e":"getownership(uint16)","af01866d":"insertSchedules(uint256,uint32[],uint256[])","af023335":"burnSynths(bytes4,uint256)","af02d47b":"currentBonusPercent()","af030d2c":"setResult(uint256,uint256,bytes32)","af03105b":"depositMintSince(address,uint256,uint256,uint256)","af0396ae":"PLDT()","af03e856":"MockUpgradeableToken()","af047106":"sumPreICO2()","af049ea9":"testFail_interface_call()","af04d0c0":"Deal(address,uint256,uint256)","af053b71":"CostToken()","af05fa10":"upgradedVersion()","af05fc63":"mulpow2(uint256)","af0638f6":"currentMaxPurchase()","af079dec":"setHardwareWallet(address)","af07c768":"Arte()","af080014":"nameChange(string,string)","af086d6f":"setTestVar(uint256)","af08e1ad":"get_arbits_presale_open(address)","af093f9c":"specificBatchCheck(uint256)","af09420b":"_addStackholder(address)","af0a078e":"tHasUpvoted(uint256,address)","af0aba4e":"setExpirationRequest(uint256)","af0ac4b7":"submitNextStage()","af0b4cc0":"minerTotalTime()","af0b7029":"KYCApprove(address[])","af0bbfb8":"registerEndpoint(int256,string)","af0bdb38":"to(address,bytes)","af0c09db":"getChosenNumber()","af0c9259":"Total_SoldToken()","af0cfe1f":"addArticolo(bytes,bytes10,bytes10,bytes)","af0def14":"startWonderAuction(string,address)","af0dfd3e":"blockPeriod()","af0e7ba3":"LeanFund()","af0eec40":"assignWarriorsToBattle(address,address,uint256,uint256)","af1034ab":"addUpdateGrantee(address,uint256)","af106b10":"oracCost()","af107749":"m_emissions(uint256)","af10b8cf":"totalBooty()","af10c810":"turnOff()","af123fe7":"makeDeposit(address,address,uint256)","af129dc2":"numTokensTotal()","af135ff5":"getMemberInfoLength()","af136dea":"setCheckInPeriod(uint256)","af1380ad":"_getTournamentBattles(uint256)","af13f1ad":"forSaleSupply()","af1484d0":"setForkReputationGoal(uint256)","af157c19":"getContributors()","af164016":"PersonalTime(address,uint256)","af16972c":"mining(uint256,bytes)","af1747aa":"checkDeck(bytes32,uint8[],bytes32)","af17dea6":"symbol_()","af191aa5":"isCertificateRegisteredAndValid(address)","af19f0d1":"CoinPreSale(uint256,uint256,address,address,uint256,uint256,uint256,uint256)","af1af4df":"feeBurnerWrapperProxyContract()","af1b5feb":"addWeiRaised(uint256)","af1b7d90":"take(uint256,uint256[4])","af1c084d":"adminName(address)","af1c7940":"fiatInvestorShare(address)","af1cd6d3":"test2(uint256,uint32)","af1cd9f6":"getGGCTokenBalance(address)","af1d06e8":"validateSignature(bytes32,uint8,bytes32,bytes32,address)","af1e19d9":"getPlayers(bytes32)","af1ee630":"getBdpOwnershipStorage(address[16])","af1ff972":"rateForCurrency(bytes4)","af2096ef":"MAX_PUBLIC_SOLD()","af20b964":"maximumFundingGoalInETH()","af21037f":"clearStartTime()","af224bdc":"parseAndStore(bytes)","af225fd6":"get_last_user_recast(bytes32)","af22fd8e":"NtsToken()","af23e1f1":"returnForMint(uint256,uint256,uint256)","af24cba2":"setLastAction(uint256,uint256,uint8)","af24d25c":"openTransfer()","af250a5e":"calculateAndTransferTokens(address,uint256)","af259886":"userToNumVillages(bytes32)","af261875":"t_ImmlaBountyTokenDepository()","af263ec9":"HomeToken(string,string,uint8,uint256)","af269745":"upgrader()","af2759f7":"timeUntilClaimAvaliable(address)","af2768ec":"commitMove(bytes32,bytes32)","af2780ee":"PERIOD_BLOCKS()","af27c7b3":"Security_HasPasswordSha3HashBeenAddedToBankAccount()","af28059d":"ChangeItemPrice(uint256)","af2885b2":"minimumEtherCommission()","af28a537":"totalRoundSeedAmount()","af299510":"HasBooster(address)","af29e720":"remainingGasFund(uint256)","af2a7fb2":"Brewers()","af2b114a":"Erc20SupplyToken(uint256,string,uint8,string)","af2b1925":"MarmotToken(uint256,string,uint8,string)","af2b2e5c":"ReVo()","af2b76ab":"airDropHero(uint16)","af2bf027":"minMaintenanceMarginAmount()","af2e285c":"setBidState(bytes32,uint8)","af2e2da9":"getValidatorName(address)","af2f0c46":"SupportComponent(uint256,address,uint256)","af2f9105":"_performWithdraw(address,address)","af2fa91c":"otherCurrenciesChecker()","af2fcc17":"globalMinPurchaseAmt()","af303a11":"salvageTokens(address,uint256)","af304bab":"getPriceByCredentialItemId(address,bytes32)","af30e4d6":"Log2(address,bytes32,uint256,string,string,string,uint256,bytes1,uint256)","af30e9f7":"transferICOTokens(address,uint256)","af30ee3f":"GOD()","af310f02":"NotCoin(string,string,uint8)","af314579":"isDayFirst()","af31f49b":"startNextAccountingPeriod()","af3309d8":"heartbeatCount()","af339ee4":"convertLotById(bytes32)","af33f8a5":"Order_execute(address,address,uint256,uint256)","af35314a":"INITIAL_TOKEN_FROM_COMPAIN()","af356eee":"preicoContractAddress()","af35ae27":"getRemainingTokens()","af35ae3e":"setSaddleShopSaleFee(uint256)","af35b3f1":"why()","af35c6c7":"enableTransfers()","af35dac2":"convertToCents(uint256,uint256,uint256)","af36778b":"aggregate()","af36e7a7":"removeUserWhitelist(address[])","af371115":"findCertificate(bytes)","af375838":"addBurnupGame(address)","af378ce5":"bust(uint256)","af38d757":"claimable()","af3996c3":"fourthStageMinted()","af3a4feb":"LOOMIA_LOOMIA_REMAINDER_ADDR()","af3cc6be":"MoxianCoin()","af3d8e43":"preICOTokenDelivery(address,uint256)","af3dc180":"ecosystemBuildingWallet()","af3e8a40":"orderMatch(bytes32)","af3f0ebe":"c_startTime()","af3f12bc":"profitSharingContract()","af408d89":"setStatus(bytes)","af40ce20":"revokeUnicorn(uint256)","af40dd2f":"AccessToken()","af418e4c":"setReclaimPeriod(uint256)","af422cce":"marketSellOrders(uint256,bytes[])","af42d106":"setKey(string)","af431f03":"setUser(address,string,uint256)","af43f597":"get_amount_minus_commission(uint256)","af448721":"refundMe(address,uint256)","af44e487":"overdraftPeriodsNumber()","af45118e":"createProposal(address,bool)","af45de05":"disableDonation()","af463d2a":"CentaToken()","af468682":"startsAt()","af46aa08":"stakeBalanceOf(address)","af475a9b":"setUSDPerETH(uint256)","af477528":"addMetadataObject(string)","af47c1af":"getActionByIndex(uint256)","af481be8":"mint(string,uint256,uint256,uint8,string)","af488ca3":"setLiquid(bool,uint256,bytes)","af489d5a":"_moveBalance(address)","af49a228":"DeshiCoin()","af49e321":"getHolderLimit(address)","af4a2984":"createPrizePool(uint256[])","af4a822d":"getCurrentTrancheIndex(uint256)","af4b382d":"PaquariumToken(uint256,string,uint8,string)","af4b3cab":"delBounty(address,address,uint256)","af4bed26":"setExchangeRateByOraclize(address,bytes32,string)","af4c14ee":"setAddressWhitelist(address,bool)","af4c2288":"getNumAcceptance(address)","af4c3d1d":"BPofMakerByIndex(address,uint256)","af4c6838":"tokenDeposited(address)","af4c9b3b":"withDrawalether(uint256)","af4cd457":"getOrCacheValidityBond()","af4d723c":"Libidocoin()","af4e3d37":"withdrawReservedTokens()","af4e4494":"TANKER_TYPE()","af4e99de":"getGameData()","af4fd9e7":"setValidLockingAmountToPeriod(uint256[3],uint256[3])","af500fb7":"readBytes32(bytes,uint256)","af50e0d3":"DeDeMasterContract(address)","af5177b1":"calcDrawCode()","af519bf5":"doesProofExist(uint256,bytes32)","af5260bf":"finalTime()","af52fbed":"retrieveWineData(bytes32)","af53dc6e":"contractbacklist()","af54e324":"upgrade_self(address)","af55bba0":"removeRegistryFromTagsIndex(address)","af5610dd":"isThisPreforkVersion()","af567633":"minPresaleWei()","af574319":"UpgradeProposal(address)","af577c4c":"unlockReserve()","af57d236":"STAGE_2_TIME()","af580d2c":"getPurchaseById(string)","af58574a":"getTierPosition(address)","af589421":"callerAdded(address)","af589572":"getAssetIdTripStartTime(uint256)","af58eda8":"findSeedAuthorized(address)","af598bc7":"winnerOf(uint256,uint256)","af599a8d":"_depositTokens(address,uint256,address)","af59c789":"setVendingAmount(uint256,uint256)","af5a3db8":"finaliseVoting(uint256)","af5a7625":"getFundInfo(bytes32,string,address)","af5b065a":"getMinimumPurchase()","af5b0ece":"getAmountContributed(address)","af5ba32a":"_fund(uint256,address)","af5c1020":"InfinityDataChain()","af5c295a":"checkMaxAllowed(address)","af5c4540":"getVoteTokens()","af5c6f38":"synthesize(uint16[5],uint256)","af5cfae8":"remainingInvestment()","af5d4013":"toteLiquidatorTranserComplete()","af5ee700":"buyTokenPerEther()","af604173":"ico_startTime()","af608fad":"isTimelockAllowed(address,address)","af60b50f":"CGCoinsToken()","af60dc4f":"SCMOXToken()","af6128c2":"calcTotal(uint256)","af62a708":"getCrystalKindWeight(uint256)","af62cfd2":"endBetBlue()","af63066e":"userRound(address)","af6337fd":"pausecontract()","af6375cd":"setNewStartTime(uint256)","af63da13":"getMemberRegistry()","af640d0f":"id()","af6499c5":"ActiveDigger()","af653861":"applyAndLockSettings()","af664f3a":"Bitkat()","af6682ab":"query(uint256,uint256)","af66c560":"convertData(bytes)","af66eb1f":"LogWithdraw(address)","af67cdc4":"HBToken()","af685482":"BonusChanged(uint8,uint8)","af68dd3f":"getBaseInfo(uint256)","af692e00":"getPullRequestById(bytes32)","af6972c0":"submitDeliveryCommitment(address[2],uint32,uint64[3],bytes32[],bytes32,uint256[2],uint256,bytes32,bytes32,uint8)","af6a2c5c":"JTCCtoken(uint256,string,string)","af6afce5":"min(int256[])","af6b08a1":"Sale(address,address,uint256,string,uint8,string,uint256,uint256,uint256)","af6b3615":"getInitialReportStakeSize()","af6b3d43":"roundSwitch()","af6bb824":"_cancelSale(uint256,address)","af6bd8ce":"durations(address)","af6c0f60":"bntToken()","af6c3021":"MaxReleasedBac()","af6c7f77":"crowdSaleStartTime()","af6cd244":"acceptAnswerAndFinalize(uint256,uint256)","af6d0437":"AtomicSwapRegistryConstructed()","af6ddad8":"shift_left(uint256,uint256)","af6df563":"withBonus(uint256,uint256)","af6e66e6":"Lockup36m(address)","af6f37a2":"getBasicTokenAmount(uint256)","af6f964d":"minReached()","af6fae22":"roomAvailable(string,uint256[],uint256)","af6fce9a":"RoyaltyInformationContractSet(address,address,bool)","af6fe8e2":"testGetToken()","af713566":"batch()","af713dda":"SUPPLY_FOR_PARTNERSHIPS()","af722ea7":"connectors(address,address)","af7296ec":"remainingBankroll()","af737da7":"_setClientLastPaidRate(address,uint8)","af738bbf":"setDepositoryDelegate(address)","af7520b9":"startingPriceOf(uint256)","af75ad2d":"createDispute(address)","af7665ce":"ethPriceFeed()","af769b54":"transferAcceptable(address)","af769eff":"Paper()","af76c4d2":"mined_blocks()","af76ccd7":"finishedPromotionIDs(uint256)","af77040e":"bonusIncreasePercentage()","af77649d":"paySmartContract(bytes32,uint256)","af77c473":"p_setGamePaused(bool)","af77ebee":"transfersOnOff(uint8)","af77f8bd":"setVIPBonus(uint256)","af7885b5":"listSubName(bytes32,uint256,uint256)","af78facf":"valueBonuses(uint256)","af7912a1":"bonusTake()","af791df2":"recoveryDone()","af794a4f":"tulips(uint256)","af79b437":"MintingDisabled()","af79ffde":"userInitialized()","af7a0899":"firstStageWallet()","af7a1762":"getBetfundingAddress()","af7a6164":"setMaxMessagesGlobal(int32)","af7b2eb7":"listAddresses(address[],uint256[])","af7bcf5e":"LigoToken(uint256,string,string)","af7bfd6c":"setValueAny(uint256)","af7c8f96":"changetokenBurnAddres(address)","af7d0eff":"setSellPrices(uint256)","af7d1890":"adminAddICO(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","af7d4b21":"RXPSale()","af7d5ebe":"change_p4(uint256)","af7d697e":"EnableTransfer()","af7d6ca3":"spend(address,uint256)","af7e8577":"TCCCoin()","af7ed9d7":"maxGasPriceInWei()","af7fdd76":"setModified()","af80562c":"testReceiveHash()","af819c67":"TTCSale(address,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","af81bd03":"_voteAndCheck(uint256)","af81c5b9":"addToken(address,uint256)","af8214ef":"LIMIT()","af82403c":"getNextNode(bytes32)","af8255ab":"updateProgress(uint256,uint256)","af825c78":"Hjjm()","af83782e":"setMinimumWishTribute(uint256)","af837832":"isPromo(address,address)","af83f252":"historyRed(uint256)","af8472b1":"consecutiveDeaths()","af84fb00":"withdrawAmount(uint256,uint16)","af8532e3":"roundDeadline()","af854db1":"allowedTransferDuringICO(uint256)","af857a84":"batchTrade(address[13][],uint256[15][],uint8[2][],bytes32[2][],bytes32[2][])","af862b6a":"ETH_withdraw(uint256)","af874a76":"isValid(address,address)","af87c366":"walletUnlock(address)","af87c833":"initiateProvider(uint256,bytes32)","af8927c1":"GetRealCost(address,uint32)","af8979fd":"confirmDeath()","af8996f1":"setPublicationFee(uint256)","af899735":"playGame()","af8a849c":"AllocationGranted(address,address,uint256,bool)","af8af39f":"setRate555()","af8b0ec7":"rewardRoto(address,uint256)","af8b7525":"CollectAndReduceFees(uint256)","af8b912d":"setVotingMachine(address)","af8c1946":"refundAllEther()","af8d5a48":"icoEndTimestampStage()","af8d7611":"setPointIdentifier(string,int256)","af8d98c9":"gameEndPlayNo()","af8d9f37":"addressContainsContract(address)","af8ec44c":"offerGanTokenForSaleToAddress(uint256,address,uint256)","af8f35c4":"_fallback()","af8f7fdf":"ProductUpdated(address,address,address,string,bool)","af8ff2f8":"runPreMint(address,uint256)","af906cf3":"setToken(uint256,address)","af91b947":"UnsuccessfulAttempt(address)","af91c5fd":"getVotersChoice()","af91e0bf":"freezeOracle()","af92080b":"downTick(address)","af92a693":"addRegistrar(address)","af933b57":"withdrawEther(address)","af93a6d1":"CatNamed(bytes5,bytes32)","af93aebb":"adjustPhaseBasedOnTime()","af93afdd":"Shipment(bytes,bytes,bytes,bytes,string,bytes,uint256,uint256,bytes,bytes,uint256,uint256,string,bytes,bytes,bytes)","af93e308":"HookToken(address,address,uint256)","af941129":"testMintGuyAuth()","af944fc7":"getQueueLenght()","af949df9":"isValidUser()","af9658cd":"custodianVerify(address)","af988341":"sendLink(string,string,string)","af9890aa":"GUS()","af98cfd6":"exchangeByBuyer(uint256,uint256)","af98f757":"cancelRequest(address)","af99a327":"finalizePartnerSale()","af9a3f9b":"hashName(string)","af9a51c6":"getComponents(uint16,uint8,uint256)","af9a91d9":"setDrawerFee(uint256)","af9afe73":"unmintTokens(address,uint256)","af9b192e":"RESERVE_AMOUNT()","af9b1cef":"transfer_funds_to_project()","af9b6bd2":"bidEMONTMin()","af9bbcc4":"unbanAccounts(address[])","af9c5e7a":"getWhitePlayer(bytes32)","af9cb8c0":"StartOfPayments(address,uint256)","af9cb9f6":"setRequiredStake(uint256)","af9dfd1a":"FoodTokenEmissionEvent(address,address,uint256,bool,uint256)","af9ee81d":"_unstake(address)","af9efd4c":"_api_PlaceBet()","af9f3e20":"BTCVERVIER()","af9f788c":"TankWithdrawSome(uint256)","af9fc8a8":"UHC()","afa01c90":"CollectibleIndex4()","afa03ac9":"doFailingTransfer()","afa0f8c9":"getUintCoinProduction(address,address,uint256)","afa12a8a":"roundEnds()","afa17725":"WillyCoin()","afa1d6c9":"mainSaleTokenRaised()","afa202ac":"setRolesContract(address)","afa25098":"returnCoins(uint256)","afa293d4":"getSource()","afa31744":"saleTokensAddress()","afa33fb8":"chkLockedB(address,uint256)","afa3a5d1":"SetdivForTransfer(uint256)","afa3de9b":"revokeUserLicense(address,string)","afa40bbd":"UNIT_PRICE()","afa4179d":"_getInvestorLockedAmount(address,address)","afa437c0":"callBackForRequestRandom(bytes32)","afa560b0":"transferToICAPCallGas()","afa5e0a9":"getCountry(uint256)","afa5e56a":"decExchangeBalanceOf(address,uint256)","afa5f45c":"changeDecimals(uint256)","afa60035":"doesAssetTokenExist(address)","afa60487":"getDocAsBytes64(uint256)","afa6c735":"PRICE_PRESALE()","afa72b9f":"CinderToken()","afa7a25f":"updateArtistsAccount(uint256,address)","afa902a0":"isAutoFowarding()","afa936b8":"deleteCertificate()","afa99860":"getTokenPrice(address,address)","afa9a86e":"tokensInPlay()","afa9f179":"toReal(int64)","afaaa654":"setEndIcoPreICO(uint256)","afaaf9f9":"DepositBroker()","afab2b0f":"inventoriesOfDate(uint256,uint256,uint256[])","afab729d":"EntrepreneurShop()","afabe8b4":"CALLToken(uint256,string,string)","afac8ed3":"rand(uint16,uint16)","aface2f1":"mintTokensFor(address,uint256,uint256)","afaebf3e":"setDispatcherAddress(address)","afaf6b2e":"AuditSafeGuard(bytes20)","afaf97e7":"privateSaleToken()","afb058ce":"teamTwoPrefix()","afb0db5f":"random3()","afb18fe7":"paymentTokenAddress()","afb2032b":"LuckChain()","afb390aa":"getIsSecondPhaseEndedByTime()","afb3a8e9":"accept2(uint256)","afb3ae7a":"SPECIALIST_ONE()","afb47bb3":"approveModeratorship()","afb4d2ee":"getM()","afb58d18":"setPriceOneToken(uint256,uint256)","afb688a2":"mineth()","afb6b9a5":"m_hardCap()","afb7e495":"eruptionThreshold()","afb95eed":"logApproval(address,address,bytes32)","afb97c20":"tokenTransferDelegate()","afbae469":"mediumSize()","afbb9d44":"ico1Bonus()","afbc4ebc":"OWNER_CUT()","afbcd19b":"CROWD_WAVE3_BONUS()","afbcd904":"setDataColla_001_001(string,string)","afbd3b7f":"minLot()","afbd8092":"CATRefundedForWei(address,uint256)","afbdaa05":"isInBlockFilter(address)","afbddfa9":"toggleFreezeTokensFlag()","afbde5c9":"getNumTopics()","afbea641":"SECToken()","afbec8df":"TheGrid()","afbfdd93":"Notonegoro()","afc01cb9":"getFinishTime()","afc0b5d3":"Crypto010()","afc0bf27":"registerName(string,address,bool)","afc0bf43":"setRecoveryInfo(bytes32,uint256)","afc0e324":"stringToBytes12(string)","afc17f80":"addLockedTokens(address,uint8,uint256,uint256)","afc24bfb":"getRules(uint8)","afc24e3d":"getChallengeAnswer(uint256)","afc2cc46":"SGEICO()","afc2f503":"allowEmployeeMigration(address,address)","afc361bc":"tokenFrozen()","afc3a2ad":"current_tier_sold_tokens()","afc3b688":"perc(uint256,uint256)","afc3c31f":"initDepositAccount()","afc48052":"mintBounty()","afc4a982":"PathCost(uint16,uint32)","afc6740e":"PricePerCafe()","afc6fe2e":"MaybePerformWithdraw()","afc75b1d":"SwissTrustToken()","afc797a6":"lastStealValue()","afc7c400":"ProICOPrice()","afc81953":"createGame(bytes32,uint256,uint256,bytes32,bytes)","afc83802":"setTotalWeiToBeDistributed(uint256)","afc88141":"WhitelistAddressdisable(address)","afc8fbc6":"MerkleAirDropToken(string,string,uint8,bytes32,uint256)","afca35e5":"QuadToken()","afcac546":"getByteSize(bytes32)","afcb0d3a":"place(int8)","afcc05c0":"buyRedirectFor(address)","afcc1286":"dtEnd()","afcc8676":"SMPLTSTToken()","afcced41":"CROWDSALE_GASPRICE_IN_WEI_MAX()","afcd565c":"createTile(uint16,uint8,uint8,uint8,uint32,uint16,uint64,uint64,address,uint8)","afcd6561":"getIdentifierFromSectionIndex(uint256)","afce2d62":"PoC()","afcee461":"DungeonRunAlpha()","afcf2fc4":"charityAddress()","afcfad6e":"getJobPayments(bytes32)","afd07e80":"getMiningWarRoundOfPlayer(address)","afd09bab":"quadrupler()","afd0a85a":"ListingCancelled(uint256,uint256)","afd0fd1d":"getDecimals(string)","afd20e33":"LOCKAMOUNT()","afd237bd":"getTxn(uint256)","afd23d4a":"STAGE_1_FINISH()","afd2d5f6":"OpinionToken()","afd3f79a":"_isCorrectQuarterBuyin(uint256)","afd42fd3":"addCloud(uint16,uint16,uint16,uint8,uint8)","afd51a6e":"updateLimit()","afd61d2c":"getBonusEgg(uint64)","afd6b607":"createRequestAsPayee(address[],address[],int256[],address,address,string)","afd7b21e":"companyCapital()","afd7b9ed":"angelStartTime()","afd7bf92":"noContract()","afd7d464":"FaradTokenSwap()","afd82067":"getScore()","afd8515e":"setTotumPhases(address)","afd8c8c4":"GasProxy(address,address)","afd8fd5f":"createToken(string,string,address)","afd925df":"setPermissionManager(address,address,bytes32)","afd9897e":"restTokens()","afda2dac":"jackPotC()","afda5460":"YDTToken()","afdac68d":"query(uint256)","afdb0970":"sendToBuyer()","afdbd499":"reclaimERC20(address,uint256)","afdc3823":"updateTlcTlr(uint256,uint8,uint8)","afdcd8ec":"RAZEN()","afdd4d23":"airDropValues(address,address,address[],uint256[])","afde86c1":"getHash2(address,bytes32)","afdebfe7":"setWeiRaised(uint256)","afdfaee7":"_preValidatePurchase(address,uint256,address)","afdfb804":"getVendors(uint256,uint256,bool)","afe007b6":"_transferAction(uint32,address,uint8)","afe0e33c":"reputationRewardLeft()","afe12e77":"withdrawWrongNode(bytes32,address)","afe14c19":"clean(address,address)","afe17129":"tokensStillInLockup()","afe18413":"placeOrder(address,uint256,address,uint256)","afe1d4cf":"setTechBonus3(uint256,string)","afe2ce0e":"setSaleAddr(address,bool)","afe38ade":"payoutWinners(uint256,address[],uint256[])","afe4720c":"toggleFeatured(uint256,string)","afe69bb0":"Create(bytes32,bytes32,address,address,address,uint64)","afe70413":"getCommissionForType(string)","afe80b8d":"newCmas(uint256,string)","afe8abbf":"transferPresaleCoins(address,uint256)","afe8b652":"countriesCount()","afe948ce":"OKEToken()","afe98be1":"calculateId(uint256,uint256,uint32,uint256)","afe9c776":"XITC()","afec91c4":"icoInstalled()","afed762b":"toSlice(string)","afef07da":"ico2receivedTotal()","afef0e28":"MARKETING_supply()","aff038e6":"sellForOtherCoins(address,uint256)","aff06fbd":"playerCancelActiveGame(uint256)","aff16621":"toSig(bytes)","aff177ca":"updateWhitelist(address[],bool)","aff1e0de":"crowdsaleTotal()","aff1f15f":"rate3()","aff21b00":"imOut()","aff21c65":"getMinimumEndowment(uint256)","aff23300":"UserWallet(address)","aff3a08e":"CreateFAP(address,uint256)","aff46572":"getMarketplaceContract()","aff4b849":"getMemberName(address)","aff4cbea":"SHIP_SLOTS()","aff57736":"getNumbersFromString(string,string,uint32)","aff5dff2":"getCreditsFor(string)","aff5edb1":"deregister()","aff6b3e8":"setupRace(uint256,uint256)","aff74c6d":"getTotalPeriods()","aff7bd49":"trackSell(address,uint256,uint256)","aff7fae4":"GodzSwapGodzEther(address,address,address)","aff8c7ab":"IkuraAuthority()","aff9b3cc":"getCarName(uint256)","aff9e954":"topOptions(uint256,uint256)","aff9f40d":"SaddleForSale(uint256,uint256)","affb62dd":"dAdd(bytes32,address)","affb672b":"realimmocoin(address)","affbe8ab":"ACNCToken()","affbf593":"withdrawExcess(address)","affc0670":"openVoting()","affca932":"changeFeeRate(uint256)","affcba25":"createNewMintableUser(address)","affcce10":"_unpackRaceData(uint256)","affd0dd4":"Funding_Setting_funding_time_start()","affe39c1":"owners()","affed0e0":"nonce()","affee29b":"submitEthToTokenOrderWHint(uint128,uint128,uint32,int256)","afff33f4":"GameEvent(uint256,address,uint8)","afff5064":"setBonusesForAmounts(uint256[],uint32[])","afff9720":"addrBounty()","b0005ff1":"validPresaleTrading()","b000c81b":"InitBetContract(address,address,uint256)","b000dec2":"total_token_sold()","b001134a":"balanceInTier()","b0011509":"calcMarketFee(uint256)","b00124c4":"epocum()","b00140aa":"getHash(bytes)","b0018bfc":"changeTokenName(string)","b0036d32":"mintByGateway(uint32,uint64,address,string)","b003dd86":"encode(uint256[])","b004079e":"lol(bytes32)","b0043308":"setaddAddressListItemSet(bool)","b00606a5":"confirm(bytes32,uint8,bytes32,bytes32)","b0062595":"KcashToken()","b006b86e":"_addEthereumAddress(uint256,address)","b006de0d":"initialBalanceForCrowdsale()","b006e2b0":"txhash(string)","b0070a30":"changeBeneficiary(uint256,address)","b00791fa":"proxy_contribution(address)","b0091773":"orderExecutionBlockTime(bytes32)","b009c50d":"DevxToken()","b00a0dbf":"allowanceTransfer(address,address)","b00a81fb":"buy(uint256,uint256,string,string,string,string,string)","b00b1239":"approveAndDeposit(address,uint256)","b00baa11":"DaicovoStandardToken(string,string,uint8)","b00bad50":"identifierToBuyoutPrice(uint256)","b00cdd9b":"preICOgoal()","b00d4c75":"singleLineWrong()","b00d70ca":"sollReserve()","b00dba63":"setTokenData(uint256,bytes32)","b00e8668":"can_refund()","b00eb9fe":"feeCalculator()","b00f9702":"setTeamPerfitAddr(address)","b010d80e":"ensureTokensAvailable(uint256)","b010d94a":"canExitPool(address)","b0112ef2":"changeReserveCATDestinationAddress(address)","b0119a22":"genOrder()","b011fcf1":"doWithdraw()","b0128c08":"getCeiling()","b013b369":"_errorBuyingTokens(string)","b013f637":"getNicknameByAddress(address)","b013fa91":"JadeCoinMining(address,uint256)","b01454dd":"vrc()","b015b81a":"amountToTakeAsRake(uint256)","b015c2ce":"FLOWToken()","b0166b04":"testTransferringMkr()","b016f9f2":"ThirdAddressBalance()","b0171fa4":"getCurrentGenerationId()","b0175308":"PriceDecimals()","b017c036":"rlc()","b017d808":"assertEq32(bytes32,bytes32,bytes32)","b01800f8":"createNewUser(bytes32,bytes,bytes32,bytes32,address)","b0181b3c":"setMyIdentity(bytes32,string,string)","b018d65a":"maxAffiliate()","b0192f9a":"auctionManager()","b019ffd2":"thirdDiscountCap()","b01a71d8":"setProvider1(address)","b01ab46d":"validPurchase(address)","b01afdab":"changeBaseValue(uint256,uint256,uint256,uint256,uint256,uint256)","b01b0304":"ExchangeRateChanged(uint256,uint256)","b01b299f":"setTokenPriceProposal(uint256,uint256,uint256)","b01b3b6c":"_createSale(uint256,uint256,uint256,uint64,address)","b01b8877":"setFundingFueled()","b01c60b7":"getPrices(uint256,uint256)","b01d3d9e":"ENTToken()","b01d54ed":"PolyAi(uint256,string,uint8,string)","b01d5b63":"purchaseFor(address,uint16,address)","b01d7a11":"sendTokensToFive(address,address,address,address,address,uint256)","b01e8308":"JointToken()","b01ead43":"returnToOwners()","b01eba14":"MIN_TOTAL_AMOUNT_GET_ETH()","b01f1571":"unitsPerEth()","b01f31c9":"hardcapInTokens()","b0203f3f":"totalAmountsBetStage2(uint256)","b020b188":"developmentToken()","b020d7a3":"_reinvest(bytes32,uint256)","b021cace":"RubyCoin()","b0228f8c":"icoEtherReceivedMainSale()","b02447e0":"bonusChangeTime()","b024abad":"GoTokenDutchAuction(address,address,address,address,address,address,uint256,uint256,uint256,uint256,uint256)","b024b2e3":"GridyToken()","b0251e6d":"setUserLocked(address,bool)","b0259633":"SHIPToken()","b025abf1":"step0Rate()","b025cc45":"deadlines(uint256)","b0267126":"advisorySupplyRemaining()","b0271023":"verifyFile(string)","b0273de1":"addVpf(bytes32,uint256,uint256,uint256,uint256,uint256[])","b028c059":"createMatch(uint256,string,string,int32,int256,uint64,uint64)","b028d73a":"isCrowdsaleAllowed()","b028ee13":"s2b(string)","b0293850":"claimBuyerFunds(address,address,address,uint256)","b029c2c8":"approve_unwanted_tokens(address,address,uint256)","b029d940":"setPlatinumAddress(address)","b02a2fd1":"withdrawLemonCoins()","b02a73a1":"sendTo(address,uint256,bytes)","b02af038":"bonusesSold()","b02b69d6":"addBonus(uint256,uint256)","b02bf4b9":"earn(address,uint256)","b02c43d0":"deposits(uint256)","b02c8054":"withdrawICO(uint256)","b02da8d8":"diamondBonus(uint256)","b02dbd07":"teamAllowance()","b02e8496":"processSellRequest(string,address,uint256,uint256,bool)","b02ef382":"SALE1_END()","b02f1edc":"TokenERC20(string,string)","b02f53ae":"testConcatStorage31Bytes()","b03031b7":"_askQuestion(bytes32,bytes32,address,uint32,uint32)","b0304813":"currentMilestone()","b03053b6":"createListing(uint256,uint256,uint256)","b0321d45":"ZJMToken(address,address)","b03260be":"scheduleTransaction(uint256,address,bytes)","b032fff4":"weiMaximumAmount()","b0335ffc":"setStage(uint256,uint256,uint256,uint256,uint256)","b033777f":"endCurrentGame()","b033a02b":"payDivsValue(uint256,string)","b033a6c3":"lookup(address,uint256)","b033cab9":"voterStakes()","b0340123":"votingToken()","b0347c56":"estimatePots()","b0349184":"clearRecords(bytes32[])","b034998b":"ChooseBwea()","b034d5aa":"Total_Deposits()","b034f3cf":"myLatestBid()","b0355b45":"LuHuToken(string,address)","b03645b5":"max_users()","b036ab65":"LemoSale(uint256,uint256,uint256)","b037e4f5":"MCoin()","b0388344":"readTaskCreatedOn(string)","b03903fd":"usernames()","b03941bc":"dropable()","b0397857":"secondaryListing()","b03b3a0a":"setPOOL_edit_13(string)","b03c4b33":"setLock(address,bool)","b03c6729":"inmax()","b03cf9bd":"MerkleAirdrop(address,bytes32)","b03d169c":"mineCount()","b03d5ce8":"PVCToken(address)","b03f75a5":"giveupBid(bytes32)","b04010c6":"fuse()","b0402d36":"LiveAuctionEvent(address,uint256,uint256,uint256,uint256)","b0407315":"purchaseWarehouseSpace(address,uint256,uint256)","b0408721":"buyVouchers(uint256)","b040d545":"tokenToTokenSwapOutput(uint256,uint256,uint256,uint256,address)","b0414a2d":"setMinimumGasLimit(uint256)","b0417e98":"checkVote()","b0419107":"_getNthNibbleOfBytes(uint256,bytes)","b0423141":"StringStorage(string)","b04247e9":"DentacoinAddress()","b04287b3":"sharesOfVault(uint256,address)","b0433fe9":"_supportsERC165(address)","b0445a77":"PRIME_VESTING_DATE()","b04464cd":"ChangeImage(string,uint256)","b0448884":"updatePrice(bytes10,uint32,uint64,uint32)","b04510d5":"xultoken()","b0459d49":"LoanStandard(address,address,uint256,uint256,uint256,uint256,uint256)","b0467deb":"getUser(uint256)","b0471d43":"primary_wallet()","b047dd06":"tokensale(address,uint256,uint256)","b047f245":"listForSale(uint16,uint256)","b047fb50":"cooAddress()","b048357d":"lastBlock_a15()","b0483c3f":"reload(uint256,uint256)","b048546f":"Divide(uint256,uint256)","b0485706":"read_u32_array()","b049474d":"disableSuicide()","b049d176":"cancelSellToBlackMarket(uint256,uint256,bool)","b04a1680":"GetConsentDirective(uint256)","b04a3f1c":"EndLottery()","b04b3f57":"isCustodian(address,address)","b04ca7f0":"dateAdmin()","b04d6638":"mangeFundAmount()","b04e74f2":"Gerritcoin()","b04e7668":"createCastleWithToken(address,uint32,string,uint64,uint64,uint64,uint64,uint64,uint64)","b04eb639":"subCrystal(address,uint256)","b04fc4e1":"superContract()","b05005a2":"lock(uint128,string,address,bytes16,uint32)","b050b49c":"rewardFoundersAndPartners()","b050f83a":"proportion(uint256,uint256,uint256)","b051d722":"loadRandom(uint256)","b052852f":"approveAllocation(address)","b0532349":"_destroyContract()","b054058a":"nSign(uint256)","b0544308":"newLockTimestamp(uint256)","b0545532":"numGamesCompleted()","b0547d8c":"deleteShopMods(address)","b0557bf1":"updateParams(uint256,uint256,uint256,uint256)","b055a62a":"INCRYPTHEDGE(uint256,string,string)","b055d1bc":"amountProportion()","b055fdf2":"isTarget()","b05609ce":"pricegreengrey()","b0560eba":"GuardaProva(address)","b056561a":"DATE_31_DEC_2022()","b056bb81":"RedSoxYankees410()","b0573de6":"getDefaultPartitions(address)","b0575069":"ap(address)","b05784b8":"retreive()","b0578878":"translate(address)","b05940f2":"getOpenAuctions()","b059c177":"_0_name(uint256)","b05a0071":"DET()","b05a47d9":"VocToken()","b05d8096":"setStr(string,uint256)","b05e390a":"TokenEther(string,string)","b05eb08d":"_isLeapYear(uint256)","b05fa837":"patronageContractForUsername(string)","b05fceba":"mDepositWallet()","b05fef55":"Issuer(address,address)","b0603326":"auctionStatus(bytes32)","b0604a26":"schedule()","b0604a9c":"testCantBuyTokensInStoppedSale()","b060b785":"getWithdrawableOperationFeeDatesAndAmount()","b060de3a":"withdrawAllOptions(address[])","b0619e85":"hasPermission(address,bytes32)","b0623074":"frozenTime(address)","b063152a":"generateHash(string)","b064bb56":"_ltoa(bool)","b064ca18":"userForceGameEnd(uint256)","b06576f3":"contrBonus(uint256[])","b0660c3d":"transfersAllowed()","b0667cf8":"queryPrice()","b066d3b7":"removeReputation(address,uint256)","b066dca9":"MERZhToken()","b066ef3c":"cooldown(uint32)","b0670cc9":"get_size()","b0671381":"isValidWalletSignature(bytes32,address,bytes)","b0673d57":"getItemStore(bytes32)","b0686584":"incNT()","b068776b":"SaleFinished(uint256)","b068b5b8":"getRank01()","b06939a2":"notEqual(address[],address[],string)","b0698763":"subdomainOwner(string,string)","b069dbf1":"sendFromContract(address,address[],uint256)","b06bcb40":"getAddressInfo(address,address)","b06c76d0":"totalMinedSupply()","b06df18e":"transfer(bytes20,address)","b06df2ae":"GetMyOrders()","b06e1e02":"changeTeamWallet(address)","b06e64ca":"maxTokensWithBonus()","b06eb03f":"DSEasyMultisig(uint256,uint256,uint256)","b06ee044":"totalBasicIncome(address)","b06eedf5":"getReferralBonusAmount(uint256)","b06f4d00":"AICoin(uint256)","b06f8d34":"redeemWallet()","b06fd1e3":"CRAWDSALE_START_DAY()","b06fe82e":"changeEtherRatioForOwner(uint256)","b07048d9":"remove_user(address)","b0705e44":"getMySword()","b070bbd4":"doCalculateRoom(uint256,uint256,uint256,bytes32,uint256)","b070bdc6":"all_obstacles()","b071cbe6":"hardcap()","b071fa2a":"SENC_HARD_CAP()","b0720613":"fundingMinInWei()","b072bd10":"usedSummReserve()","b0732278":"finishICO(address,address,address)","b073e2b7":"testMath()","b073f52b":"updateBalance(bytes32,uint8,int256)","b0756562":"addLottery(string,uint32,uint32,uint32)","b07576ac":"delMin()","b0759c3e":"lockInBatches(address[])","b0773d12":"payAndRemoveInvestor(uint16,uint256)","b07741fd":"refresherFee()","b077c09b":"readSample(bytes)","b0780bd8":"getDonationStats()","b0786de9":"NeptunSupply()","b078ffe8":"BitcoinUnicorn()","b0792570":"beneficiaryStake()","b0799375":"nameValue()","b079cf62":"getRandomDragon(uint256)","b07a3107":"isOraclizeQueued()","b07a6735":"processPrivateFunding(address)","b07bbefd":"updateValueAndMint(uint256,uint256,int256)","b07be1fe":"createThemedSpinner(string,uint256,address,uint256)","b07be207":"calculateTicketPrice()","b07c76e8":"LoggedDividend(uint256,string,uint8,string,bool,bool)","b07e4e34":"_unpackCycleValue(uint256)","b07ed982":"setMaxTokenSupply(uint256)","b07ee0d2":"erc20TokenTransfer(address,address)","b07f0a41":"exercise(uint256)","b07f1fa2":"init(address,uint256,uint256,uint256,uint256,uint256,uint256,bool,address)","b07f3025":"CROWDSALE_ETH_IN_WEI_FUND_MAX()","b081b9aa":"propose_beneficiary(address)","b081cfc5":"_thresholdOne()","b0827f42":"restrictedTokensDate()","b082b9c7":"getOrganisationCount()","b0837524":"minIcoTokenLimit()","b08428c1":"internalCalc(uint256)","b08480d4":"finishSettlement()","b08496dd":"_newSpaceshipProduct(uint16,bytes2,bytes2,bytes2,bytes2,uint256)","b08510a3":"setdissolvedcontract(address)","b0859b6f":"oraclize_setGasPrice(uint256)","b085a5af":"getMyWine()","b085b9a5":"Example()","b08639e3":"getRepAvailableForExtraBondPayouts()","b0867a5c":"joinGameRandom(uint8)","b086d5aa":"getUriSetCount()","b087b8bc":"getWorkflowCount()","b0882c4b":"newETHUSDPrice(string)","b0883120":"balanceOfBuyer()","b0885dd6":"distributeWithTransferFrom(address,address,address[],uint256[])","b0891f4f":"setTokenAgent()","b0894aa6":"getDateOfAcceptance()","b0898886":"claim_devidend_for(uint256)","b08a3619":"registerDepositAddress()","b08af3dd":"get_participant_num_of_uses(address)","b08b3410":"getStraightReleasableAmount(address)","b08ba6a1":"view22()","b08bbff0":"isUserAllowed(address,string)","b08c2915":"JP_winningHash()","b08c7730":"feeGame()","b08c9bd1":"refuseSale()","b08cfb84":"addWhitelistedAddress(address,address)","b08d2718":"ReleaseableToken(uint256,address)","b08db494":"toAddress(bytes,address)","b08e0d3e":"applyRefund(uint256,bool)","b08e0f4a":"manualWithdrawal(uint256)","b08f8e1d":"setContractHoldBalance(uint256)","b08f965e":"SSA()","b090c768":"LogSelectWinner(uint256,uint256,address,uint256,uint256,uint256)","b09173f6":"viewAffBonus(address)","b091a044":"transferRecord(address,address,uint256)","b092145e":"whitelist(address,address)","b0927de7":"newRepo(string,address)","b0933f25":"fixAdvance(uint256,uint64)","b0934d7d":"removeFromBlackList(address,address)","b0949833":"NineStandardToken(uint256,string,uint8,string)","b0950b8c":"canCloseVoteCommitPhase(address,bytes32,bytes32)","b09609d5":"LogMinting(address,uint256,uint256)","b097bdbd":"PRESALE_STARTTIMESTAMP()","b097c984":"setIEOAddress(uint256,address)","b098b86b":"ownsOrSelling(uint256)","b098bdba":"getAppeals(uint256)","b09938b8":"VormaToken()","b0994d4a":"authorizeOperator(address,bool)","b099cceb":"makeBet(bool)","b09ac6f2":"isUserProduct(bytes32,bytes32)","b09ad8a0":"upperBound()","b09afec1":"getTokenData(uint256)","b09b1a51":"buyUnicorn(uint256)","b09bc3bf":"try_to_get()","b09c0f30":"rewardWeekly(uint32,uint32)","b09c235e":"MargamCoin()","b09db392":"addressDevelopers()","b09df36a":"getFunctionSignatures()","b09f1266":"_symbol()","b09f168e":"tokenOfOwnerByRange(address,uint256,uint256)","b09f4af5":"executeLock(bytes16,address)","b0a0662a":"FIRSTSALE_BASE_PRICE_IN_WEI()","b0a08873":"adjustLoanParams(uint256,uint256,uint256)","b0a1bfa9":"updateFeeBalance(uint256)","b0a1c666":"newComment(bytes32,string)","b0a1e2b4":"disputeID()","b0a2365c":"percentTokensToSale()","b0a254a7":"addStackholder(address)","b0a267da":"userTipped(address,bytes32,uint256)","b0a54a76":"TN()","b0a5a57a":"createEmergencyFundReleaseProposal()","b0a5c979":"CheckAmbientHumdtyException(bytes32,uint32)","b0a66a84":"creator(bytes)","b0a6a5ab":"IoTonToken(uint256,string,string)","b0a6d947":"unfreeze(address[])","b0a77ef7":"WithdrawToSponsor(address,uint256)","b0a8489e":"btycBalanceOf(address)","b0a84974":"payedBalancesOf(address,uint256)","b0a8be37":"RegCost()","b0a91659":"FixProfit()","b0a94ef7":"Divest(uint256)","b0a9b0ff":"createTeam(string,string,uint256,uint256,address,uint256)","b0a9c7f4":"checkGameResult(address)","b0aa09f2":"mainSaleStartTime()","b0aab296":"getNextNode(bytes)","b0aae3fa":"passGateway()","b0abbc7b":"setData_23(string)","b0ac0ef2":"currentActiveGameID()","b0ac4c8c":"getLastData()","b0acc531":"reserveWave()","b0acd745":"EventCreateStatic(address,uint128,uint256,uint256)","b0acde14":"withdrawInternal(address,uint256,address[],uint256[])","b0ad38c4":"buildCity(string,uint256[2],uint256[2])","b0ad3a5f":"not(bool)","b0ae1d64":"getpurchaserAtIndex(uint256)","b0aed621":"addJugada(uint256,string,uint256,uint256)","b0af768b":"setTokenBurner(address)","b0b02c60":"setUpdateOperator(uint256,address)","b0b185c7":"allowedForwards(uint32)","b0b189ca":"sendToInvestor(address,uint256)","b0b24e2c":"ERC()","b0b2b499":"test_token_fall_back()","b0b315e7":"calculateMaxContributionUsd()","b0b3c9a6":"ETHERAFFLE()","b0b503f9":"MonyaToken()","b0b53a1f":"WSKYToken()","b0b60b06":"ZXGToken()","b0b773c4":"ESSgenesis()","b0b8579b":"hop()","b0b92263":"setTotalTokens(uint256)","b0b9603b":"saleTokens()","b0b99c7d":"createPotato(uint256,uint256,uint256,uint256,address)","b0ba621a":"SoapBox()","b0bb3759":"XPAAssets(uint256)","b0bc4d67":"preserveHolders(address,address,uint256)","b0bcc610":"scheduleTransaction(address)","b0bcd8f3":"preCrowdsaleOwner()","b0bd5888":"transferredTokens()","b0bdacc6":"setCoinAddress(address)","b0bebdf5":"endICOp1()","b0bed0ba":"selfBalance()","b0bed1e9":"SMSCoin()","b0bf092a":"getSoftCapInWeis()","b0bfe169":"changeAirdropLimit(uint256)","b0c0552f":"AuctionCreated(address,uint256,uint256,uint256,uint256)","b0c13bfb":"addDestroyer(address)","b0c1adac":"setPrice(uint256,bool,uint256)","b0c20e4a":"setRateProvider(address)","b0c2a163":"currentDifficultyWei()","b0c2ebfd":"NathalieToken(uint256,string,uint8,string)","b0c2ff43":"tokenAccountAddress()","b0c35c05":"autoBirthFee()","b0c39bbd":"setFreezeIn(address[],bool)","b0c42691":"frozenWallet2y()","b0c4b3bb":"dateEco()","b0c5134e":"forwardEther()","b0c577c1":"phase3TokenPriceInEth()","b0c6d7df":"clearMonsterReturnBalance(uint64)","b0c73bc6":"getInvitor(address)","b0c74430":"saysomething()","b0c7f709":"kingAutomaticCollectFee()","b0c80972":"setBalance(uint256,bool)","b0c8d2dc":"updateMeta(uint256,uint256,string)","b0c8f9dc":"add(string)","b0c95b1d":"SetAccess(address,uint256)","b0c9fec7":"ButtonClicked(address)","b0ca2e62":"VEC()","b0cae18a":"WDNA()","b0cb3299":"checkIfOnUncle(uint256,uint256)","b0cbaab2":"exp(int128)","b0cbc8b9":"callContractFunctionByAddress(address,string,address,address,uint256,uint256,bool,bool,string,string,bytes32,bytes32)","b0cbe292":"_extendBadges(uint256,address,uint256)","b0cc0596":"getUserOptOut(address,address)","b0cc3951":"manualEntry(bytes32,bytes32,uint256,uint256,address)","b0cccbc3":"setFreezeOracle(bool)","b0cccc84":"validResult()","b0ce8668":"IJC()","b0cee590":"TwiceAWeekCoin(uint256,string,uint8,string)","b0cf0dcb":"revokeTokenGrant(address,address,uint256)","b0cf35f5":"getNewFallbackDeposit()","b0d08d3d":"setTxCount(address,uint256)","b0d12477":"listMAS()","b0d138e8":"bounty_percent()","b0d13a25":"retrieveEther(uint256)","b0d1a26c":"advisorTimeLock()","b0d26478":"setIdentity(uint256,address,address,string)","b0d2b936":"_isTxExistWithArgs(bytes32,uint256)","b0d3a396":"ADDITIONAL_BONUS_NUM()","b0d3ef3d":"isOpenFor(address)","b0d4ff96":"getMadeTX(uint256)","b0d54bcf":"setTradingFee(uint256)","b0d56da6":"ElephantToken(uint256,string,string)","b0d60c2e":"rawTransferFrom(address,address,bytes32)","b0d65d29":"partialWithdrawal(uint256)","b0d66291":"migratebyowner(address)","b0d79497":"allowOrRestrictMigrations()","b0d7fd9a":"NewListing(uint256,uint256)","b0d81f94":"lockTokensForFs(address,address)","b0d8a83c":"Osmium()","b0d8b51f":"getOwnedTokenIds()","b0d997d9":"bitGuildContract()","b0d9fef9":"udfVUPDestination()","b0dbce71":"setStreamityContractAddress(address)","b0dc1666":"DacToken()","b0dc63eb":"startWineryProductByRegulator(string,string,string,string,int256)","b0dcbce5":"payWithPLAT(uint256)","b0dd15a6":"paint_pixel(uint256,bytes3,uint256)","b0dd2858":"TokenBuyPresale(address,uint256,uint256,string)","b0dd478a":"setCountdown(uint256[5])","b0ddaddd":"shareBalance(address,uint256)","b0de0c40":"getBalancesList(uint8)","b0de1cb7":"publish(uint64,bytes,uint64)","b0ded9ce":"fechAllCandidates()","b0df5f81":"_computeWings(uint256,uint256,uint256)","b0df9e53":"getCards()","b0e0346e":"UNLB()","b0e09ac0":"test_validShouldThrow()","b0e0ef09":"withdrawTokensFrom(address,address,address,uint256)","b0e12715":"makeTrade(address,address,uint256,uint256,uint256)","b0e16cce":"removedotchtooffer(uint256,uint256)","b0e1aaa5":"getNumPresaleTokensBought(address,address)","b0e1f553":"whiteListingContract()","b0e24364":"CaerusToken(address,uint256)","b0e37f79":"isChecker(address)","b0e4925c":"BCIA()","b0e547e8":"referrerLevel2Percent()","b0e572c8":"getStrategy(bytes15)","b0e5aa89":"bonusStage2SecondDay()","b0e657a7":"firstMintRound0(uint256)","b0e667a9":"bidSpaceship(uint256)","b0e757c5":"GameXChange()","b0e849fe":"auctusWhiteListAddress()","b0e8cba8":"toggleContractAccessForEverybody()","b0e9a1ef":"setHodlerTime(uint256)","b0ea1e2e":"START_TS()","b0ea8d8f":"getRedeemableTokensStaker(bytes32,address)","b0eb5162":"closeGeneralSale()","b0ebb261":"withdrawGift()","b0ebefbc":"distributeFoundersRewards(address[],uint256[],uint256[])","b0ec2bed":"test_8_accessRestriction_UnderscoreAddMember_shouldThrow()","b0ecc878":"calculateEthToAfterschool(uint256)","b0ecca8f":"LookAtLastTimePerZone(uint256)","b0ed439e":"getMaxHolder()","b0ed656c":"claim(bytes32,bytes32,bytes32)","b0ed9774":"changeTakeoutWallet(address)","b0ee60a3":"_addLicenseTerms(bytes32,bytes32,bool,uint256,bool,uint256)","b0eeefea":"YANKEES(address)","b0eefabe":"setArbitrator(address)","b0f07e44":"registerData()","b0f0c96a":"hello(uint256)","b0f11234":"getMessageCommunicationHash(address,uint256)","b0f239e9":"totalCheque()","b0f23d80":"SetCountryCode(uint16,string)","b0f2b72a":"set_value(uint256)","b0f32e55":"ContractFactory(uint8,uint8)","b0f42dc4":"isPure(uint256,uint256)","b0f471dd":"_partFromProvider(uint256,address)","b0f5ae72":"exchangeEtherOnTokens(address)","b0f69523":"rentOut(address,uint256,uint256)","b0f72665":"multiSigDev(bytes32)","b0f7d744":"getBoughtTime(address)","b0f85a10":"airEndtime()","b0f94b16":"batchFishAquarium(uint256[],address)","b0f9ba74":"destroyEternalStorage()","b0f9f315":"accountClaimedReward()","b0fa4926":"buyLicenseForETH()","b0fa5032":"DDToken()","b0fb3095":"transferDividendBalance(address,uint256)","b0fc2d72":"grantPurchasedTokens(address)","b0fc9bdf":"lilitoken()","b0fd035b":"safeWithdraw(uint256)","b0fd935b":"registerCertificationDb(address)","b0ff4210":"BAFC()","b1000f23":"_airdrop()","b100ad20":"incremCounter()","b102bfbe":"getOwner(bytes)","b102f52b":"enterLottery(uint32)","b103bb58":"setMaximalInvestment(uint256)","b103c1dd":"claimCofounditTokens()","b103ef5b":"buyfp(uint256,uint256)","b10477c9":"getAntsSinceLastCollect(address)","b104c509":"earlyInvestorSupply()","b1050da5":"newProposal(address,uint256,string,bytes)","b105126f":"initLottery(uint256,uint256,uint256,int256)","b1057e9c":"sell2(address)","b105be51":"BoonyToken()","b105c904":"intrepidVouchersMinted()","b1063c19":"setMiBoodleVault(address)","b106ef69":"Tutoreum()","b107baa1":"minimunBTCToInvest()","b107e815":"bet(uint32,uint8[4])","b107ea12":"setDefaultAQL(uint256)","b1084ce2":"currentNorsefire()","b108501f":"WINNER()","b10908ff":"ACO_Token()","b1091e1b":"Ez()","b1099347":"buysTokens()","b109bc6d":"getUpVoteCount(bytes12,bytes12)","b109e894":"PRICE_VARIABLE()","b10c7544":"getCmd()","b10c7dc4":"revokeMembership(uint8)","b10cf224":"userUnlockToken(uint256)","b10d539b":"MergeStatus()","b10d5a52":"setTechnicalPercent(uint256)","b10d6060":"StorageToken(address,address,address[],uint256,string,string,uint8)","b10d6b41":"getDocument(bytes32)","b10e4172":"remove(bytes32,bytes32)","b10eabe8":"ADDOCoin()","b10ec8da":"LogPrepareContribution(address,uint256,uint256,uint256)","b10ed487":"minimumInvest()","b10f8583":"update(uint256,uint256,bytes32,bytes32)","b1103200":"poolEthCap()","b1110c29":"createTokenUri(uint8,uint8,uint8,uint8)","b1112507":"bonusDeadlineDefault()","b112349e":"get_my_dni()","b1135686":"votesIter()","b113d9dc":"tokensale(address)","b11408b7":"free1Of(uint256)","b1144c9a":"presaleAllocations(address)","b114b96c":"left99(uint256)","b11560c5":"removeFromWhiteList(address[])","b115d28c":"transferDaxsToken(address,uint256)","b1174177":"LogWhitelistRemove(address,uint256)","b117a3e8":"kingBank()","b118060e":"stringLength(string)","b1186efb":"decode(bytes,uint256,uint256,uint256,uint256)","b11873d1":"BOSX()","b11888d6":"testThrowOnTransferWhenNotCreator()","b11894c9":"addBadToken(address)","b1194648":"setSaleWeiLimitWithoutKYC(uint256)","b1194bc4":"setGlobalDelegation(address)","b1199a87":"resetMeter(address)","b11a19e8":"toString(bytes32)","b11a1b89":"setCoinContract(address,address)","b11a2a97":"setEDUPrice(uint256,uint256,uint256)","b11a41fb":"AfrFballCoinToken()","b11b40a1":"getDna2(uint256)","b11c4fd8":"approveAndCallcode(address,uint256,bytes)","b11cc099":"winPrize()","b11ce2db":"addContractAddress(address)","b11d8bb8":"revealVote(uint256,uint256,uint256)","b11dd097":"initEmployee()","b11e0acb":"supplyAvailable()","b11e3889":"bulkDepositTo(uint256[])","b11e3b82":"createEvent(bytes32,bool,int256,int256,uint8,address,address,bytes32[])","b11ec3b3":"MENSA1(address)","b1202774":"ico4Max()","b120c16a":"setReputation(address,uint256)","b120e1ef":"setTokenSaleDistribution(uint256)","b12155a9":"burnTokens2(uint256)","b121a199":"_transfer(address,address,bytes32)","b122a0ef":"joinCommunity(uint256)","b1233451":"setTerm(uint256,string)","b1237eae":"withdrawAmountTo(uint256,address)","b123f68b":"LogAddress(address)","b12673b2":"token10MstepCAP()","b1267579":"totalTokenRaiseWei()","b126d0e5":"createAndSellAllAmount(address,address,address,uint256,address,uint256)","b126dc4d":"blockIndex(uint64,uint64)","b127221d":"ICO_BONUS()","b127326e":"masterTransfersEnabled()","b1273db1":"batchSetInvite(address[],uint256[],uint256[])","b1275f9a":"addPlayer(address)","b1276a42":"addCurrencyExchangeRate(uint256,uint8)","b1283e77":"markets(uint256)","b1288c11":"bytes32ToString(uint16)","b128ca5c":"adjustCap(uint256,uint256,uint256,uint256)","b129497c":"john()","b12a8229":"tokenSaleEndTime()","b12b714f":"_add(uint256,address)","b12dca5a":"ergebnis(uint256)","b12de559":"invalidateOrdersBefore(address,uint256)","b12dff65":"relaxFundingCap(uint256,uint256)","b12e1449":"reserveEscrow()","b12e3e60":"voltTransfer(address,address,uint256)","b12e4410":"getTokenAddress(bytes32)","b12e5f09":"OpsManaged()","b12e9c41":"SYS_Token()","b12ed9ef":"FCOIN1122Token(uint256,string,string,uint256)","b12f9eab":"finalizeSet()","b12fe826":"addMod(uint256,uint256,uint256)","b13170d6":"Change_approvePay(address,bool)","b1321ed7":"payOutPercentage()","b1330ca9":"startVoting(uint256,string)","b133f39b":"_shuffleParams(uint256,uint256,uint256,uint256)","b13413b0":"allocateTokensToTeamAndProjects(address,uint256)","b1343ee9":"paymentsByUserId(uint256)","b1344271":"slasher()","b1347e9d":"mintsub()","b1356488":"getEndDate()","b135bbb0":"nextGameId()","b1366d5b":"bet(uint256,uint256,address,bytes32)","b13770af":"determinTID(uint256,uint256)","b13795af":"GDCNumber3()","b138d500":"presaleAmount()","b138d838":"getContractEarnings()","b139275f":"transferto(uint256)","b139560b":"getCreateMarketEndTimeValue()","b139af17":"startSpaceship()","b139f780":"NRB_Common()","b13a2e1f":"chargeOwe(bytes32)","b13b4f2d":"wipe()","b13b6a2a":"_decreaseApproval(address,uint256,address)","b13bdfb6":"isAtMost(uint256,uint256,string)","b13c7047":"DragonKingTest(address,address,address,address)","b13c8fe0":"BILLION_TOKENS()","b13d5180":"checkAndCallApprove(address,uint256,bytes)","b13ef343":"Vesting()","b13fd2b8":"DividendAvailable(uint256)","b1401858":"levelOneBonus()","b1404198":"LogForwarded(address,uint256,bytes)","b1406a33":"buyNac(address)","b140bee5":"testFailBuyAfterClose()","b1418cf4":"payHouse()","b14201d0":"requestForArtistRegistration(bytes32,bytes32,bytes32)","b1429863":"test_oneFalseAssertNoMessage()","b1432cc3":"CrowdSale_Change_ReceiveWallet(address)","b1437e27":"tokenTotal()","b143c703":"createBarCodeData(bytes32,bytes32,int256,string)","b143c916":"getTeamPayouts(uint256,uint256)","b143d6fb":"setRunning()","b144a4d8":"DistributionSale()","b144adfb":"balance_of(address)","b14537b0":"maxContributor()","b145a5b8":"isInit()","b145c013":"checkPayout()","b146ba8e":"changeQuecoinAddress(address)","b146bdee":"cancelDigitalContract(string)","b14762bc":"setAirDropDestination(address)","b14781fb":"BITBalanceOf(address)","b148313e":"partnerSaleTokensPurchased()","b1483eee":"_TARGET_EPOCH_PER_PEDIOD()","b14904b4":"BTCET()","b14959dc":"setbonusDate(uint256)","b1498e29":"insert(string)","b149ece0":"joinPool(uint8)","b14a44ac":"_unregisterArtist(address)","b14cf5e0":"changeManager(address,address)","b14d703f":"Bitsonalite()","b14debe4":"getEthPhiRate()","b14e7bc1":"_isOperatorForPartition(bytes32,address,address)","b14ec275":"_createHero(uint256,uint256,uint256,uint256,address)","b14ecf18":"BlackSwan()","b14edac5":"destructo()","b14f2a39":"changeTreasury(address)","b14f6439":"finshCrowdsale()","b14f8432":"hasValidSubscription(bytes32,address)","b15089b1":"unlockBonusTokens(uint256,uint256,uint256)","b151c0c8":"ModuleRegistrar(address)","b15201b2":"MIN_TIME_EXPLORE()","b1523087":"_transfer(address,uint256,address)","b1527bd9":"CYFM()","b152f19e":"getFirstSchedulableBlock()","b152f6cf":"TOKEN_SUPPLY()","b152fbd1":"lockingRatio()","b1536051":"_contractFallback(address,address,uint256,bytes)","b154224e":"TimeLockMultisig(address,address[],uint256)","b1542d39":"_createCrab(uint256,uint256,uint256,uint256,bool)","b1546194":"TimeBoxToken()","b154dea6":"NULL_ENCRYPTION_ALGORITHM_DESCRIPTION_URI_ID()","b154f47c":"dev3Wallet2Pct()","b1557c2c":"lastContract()","b155c7d6":"devTokensIco2()","b155d434":"FINTIFLUSHKA()","b15651ff":"emissionPrice()","b156f79b":"FeeAddr2()","b1574b38":"toggleActive(string)","b157528b":"getERC20(address,address,address,uint256)","b157add3":"bonus_()","b157c5cd":"setJudge(address)","b15868eb":"GetVersions()","b15897cc":"setfreeze(bool)","b158a23f":"betOpen(uint256,string,string,string,string,bool)","b158b63f":"getBillOwner()","b1598725":"CultureTravelFoundationAddr()","b159bcff":"COMPANY_ACCOUNT()","b159beac":"MINIMUM_QUORUM()","b159d61b":"addSellerSig(string,string)","b15a3647":"trade(uint256,uint256[3],bytes32,bytes32,uint8)","b15a72d8":"wagerPool13()","b15aa5b7":"getSignHash(bytes32)","b15addec":"Test1()","b15b2c29":"GetContractStateEarlyTerminatedByTenantSecDep()","b15d6f35":"requestChangeInsurer(address)","b15dc523":"minFundInEther()","b15dcc25":"query(address,bytes2,uint256)","b15fbfe6":"getFromAmountBooks(address)","b16020a0":"STBIToken()","b160a86b":"setKycHash(bytes32)","b1610080":"TravelNote()","b1610d7e":"VOTING_PERIOD()","b16219c6":"feeWithdrawTokenAll()","b1622818":"softWithdrawRewardFor(address)","b162a382":"updateName(address,bytes32)","b163cc38":"addBalance()","b1643e96":"changeFeeEVOT(uint256)","b1648152":"setBetMinMax(uint256,uint256)","b1649a2d":"cancelOrder(address,address,address,address,bytes32)","b1652b2f":"playerRollDice(uint256,address)","b16562fe":"fipsRegister(address,bytes)","b165a332":"getPercentageBonusForIco(uint256)","b1662d58":"setModule(address,bool)","b16661bf":"joinAgreement(bytes,uint8,bytes32,bytes32)","b166b55a":"LogRemainingHalvingSubsidy(uint256,uint256)","b166c1ba":"sendProfit(address,uint256)","b167c34e":"getTxAtIndex(uint256)","b167d512":"allowedSince()","b167fe1b":"getExploreItem(uint256)","b168da8a":"getCustodianName(address)","b1699e2e":"C(bool)","b16a4a52":"TokensUnfrozen()","b16a867c":"summary()","b16ab3a3":"emergency_token_withdraw(address,address)","b16afaf6":"OChain()","b16b1e28":"getAddressField2()","b16b8485":"setExchangeStart(bool)","b16bd58f":"maxTokenlossValue()","b16c09f0":"clearIssuanceData(address)","b16c9e59":"flexibleReward()","b16d0839":"RootsToken()","b16d0e38":"IBG(string,string,uint8,uint256)","b16d1538":"nonEthWeiRaised()","b16d22a0":"StopPaymens()","b16d2fd1":"winnerTicket()","b16d8622":"maxICOSupply()","b16dd130":"baseKernel()","b16deab2":"CentrallyIssuedToken(address,string,string,uint256,uint256)","b16eaafa":"PetsToken(address)","b16f4a3a":"GPaid()","b1700e61":"trackAddresses(address)","b17076b2":"RemoveProofOfOwnership(bytes32)","b1718455":"NUM_COIN_PER_AXIE()","b171ae40":"ethSold()","b171b18f":"triggerInvestment()","b171dee6":"_setCategories(address,uint256,uint256)","b17216f5":"mintForwarder(uint256,bytes32,address)","b1723215":"TestPersandToken()","b17346fd":"finalizeSeedSale()","b174734c":"pendingOwner1()","b175a0d2":"BONUS_TIER_3_LIMIT()","b17607e9":"costoken()","b1766617":"ganTokenNoLongerForSale(uint256)","b176a0b4":"RabbitArena(address)","b1782d18":"tgrNumber()","b17922f6":"onlyRoles(address,uint16)","b179882d":"RESERVED_PRESALE_CAP()","b179f4d8":"G5()","b17a98b6":"withdrawAllToWithdrawalAddress()","b17a9e11":"confirmCustomer(uint256)","b17aa196":"_generateNewRandom()","b17acdcd":"collectFees(uint256)","b17b94c1":"testSystem()","b17c3f99":"confirmation(uint256)","b17c6ab8":"cancelSaleOrder(uint256)","b17d5938":"submitPool(address,uint256)","b17d8646":"EpisodeManager(address,address)","b17df316":"setMigratedBalance(address,uint256)","b17e8c4f":"tokensForplutonics()","b17eb9dc":"supporthill(uint256)","b17f0c1c":"tokenSaleWeiCap()","b17f5332":"EnterCode(uint256)","b17fc36d":"setSoftCapDeadline(uint256)","b18019bd":"_executeVote(uint256)","b1816f60":"TEMTicket(address,uint256,uint256)","b181954d":"addAttribute(string,bool,bytes32,string,string)","b18196f4":"GenexiToken()","b181a8fc":"resetContract()","b181d3d5":"GMF()","b1826ee7":"getLevelUpFeeByLevel(uint256)","b1829738":"setContractorsProfitAddress(address)","b184be81":"drain(address,uint256)","b18588fb":"updateGravatarName(string)","b185a8a4":"ChangedTokens(address,uint256)","b186eed8":"dealerDay()","b1871886":"growthReserve()","b1874b99":"INVESTMENT_USER1()","b187984f":"disableTransfer()","b187b6b1":"getBlockValueBalance()","b187bd26":"isPaused()","b1881225":"KEYS(uint256,string,uint8,string)","b188c70d":"feeMode()","b1895823":"mintMultiToken(address[],uint256[],uint256)","b189ad2a":"testErrorUnauthorizedAfterTransfer()","b189fd4c":"hash(uint256)","b18a02a4":"getPlayers(uint8)","b18a714e":"getReservedBalance(address)","b18a78e3":"currentBetAmount()","b18af4e3":"addProduct(bytes32,uint256,string,string,string)","b18bca4d":"countAbstentions()","b18c6847":"manualUpdateBalances()","b18d0c80":"getImageWidth(uint256)","b18de618":"EndQuestion()","b18e0ab8":"FooWallet(address[],uint256)","b18e4f5f":"appendKeyValue(string,string)","b18ef18c":"GlobalChain()","b18efff3":"GenesisCatsAdded(bytes5[16])","b18f1943":"ownersLength()","b1905727":"getPermissionManager(address,bytes32)","b19068c7":"minimumWager()","b19129b1":"addCustomertoBL(address,address)","b19183f2":"HodlReleased(bool)","b19208f3":"getPreIcoFunds()","b192da2d":"burnt()","b1933a0b":"getAllSharedAccounts(bytes32)","b1934151":"tokenScaleFactor()","b1936c24":"presaleOngoing()","b194073a":"getUmkaAddress(address)","b196aabb":"maximumBaseContribution()","b196f378":"weiLiquid()","b1972567":"lockAddresses(address)","b1976a02":"Get()","b197997a":"getCurrentYearMinedTokenCap(uint256)","b1987c7d":"NotaryPlatformToken()","b1989a2b":"calculateFadeoutToPool(uint32,uint256[9])","b198ef45":"checkVotingForAllowTransfer()","b1999937":"leapYearsBefore(uint256)","b19a4540":"allocatedEth()","b19a5f62":"placeOpenPurchaseOrder(address)","b19ab052":"withdrawEtherManually()","b19ab945":"maxBurnThreshold()","b19b1550":"FintechnicsPublic()","b19b2162":"refundFailedAuctionAmount()","b19bc02e":"Griddeth()","b19c0f5e":"registerForCompetition(address,address,address,address,address,uint256,uint8,bytes32,bytes32)","b19d134d":"reviseNumAvailable(uint256,uint256)","b19d4916":"setCompte_2(string)","b19d632b":"publish(bytes32,uint256)","b19e288c":"set_pauseCWC(bool)","b19f30e2":"changeKYCAddress(address)","b19faed8":"doSucceedingApprove()","b19fde5a":"getPresaleAllocation(address)","b1a00406":"getactendlen()","b1a0570d":"mintBIX(address,uint256,uint256,uint256)","b1a06ee7":"setPreSaleTokenExchangeRate(uint256)","b1a08010":"orderTrader(bytes32)","b1a11c92":"trashedTokens()","b1a1318a":"HolderAddress(uint256)","b1a1b3bc":"get_chronus()","b1a2bbd1":"TOTAL_TOKEN_CAP_OF_SALE()","b1a329d7":"optionPoolTotal()","b1a34e0d":"addClaim(uint256,uint256,address,bytes,bytes,string)","b1a3c6b4":"Balances_of(address)","b1a56055":"add_OEM()","b1a6676e":"isBurnActive()","b1a681c8":"receiveEtherAndData(bytes)","b1a6afd3":"declaration()","b1a7c005":"hashDelegatedTransfer(address,uint256,uint256,uint256)","b1a82e8f":"Jaak()","b1a8b25a":"returnBalanceToMainAccount()","b1a96135":"DMT_TotalSuply()","b1a997ac":"poke(address)","b1a9bd77":"settlementIsRunning()","b1a9f8a4":"_toString(bytes32[4],uint256,string)","b1aa6dfa":"finishInitOwners()","b1aac629":"addSoundEffect(uint256,uint8[])","b1ab0999":"supportKickoffQuorum()","b1ac478f":"_generateBattleReward(uint256,int32)","b1ad4c48":"getInvestorDividendsAmount(address)","b1adc241":"BalanceDB()","b1ae9017":"refundsall()","b1ae9887":"lastTreeId()","b1afe96b":"setMaxInvestorContributionInWei(uint256)","b1b2aef3":"testInsertProductIntoCart()","b1b30533":"contractTokenWithdrawToFreeTokens(address,uint256)","b1b3d3f6":"allow()","b1b5537c":"activateCycle(uint256)","b1b68fad":"makeTradable()","b1b6a6ed":"addPremineAllocation(address,uint256)","b1b6aecb":"SLMToken()","b1b79120":"setFightFactor(uint8)","b1b7c88f":"getPreSaleBonusRate(uint256)","b1b82922":"_getProviderRateHistory(uint256,uint256,uint8)","b1b96fdf":"giveTokens(address[],uint256)","b1b9e78d":"acceptOffer(address,uint256)","b1ba6ad7":"privateSaleAddress()","b1bb1a60":"serviceGroupChange(address,address,uint8)","b1bb4d35":"proxyMint(uint256,bytes32)","b1bb5855":"maxTicket()","b1bb5fde":"runningDebt()","b1bb7e0f":"verificationPeriod()","b1bbc6f5":"onlyBouncerSetGasRefund(bool)","b1bbd453":"winnerWithdraw(uint256)","b1bcc1b7":"depositOrder()","b1bd7683":"maxAvailableForSale()","b1bd7b80":"transEther()","b1beb3c0":"NonActivationWithdrawal(address[2],uint256[7],uint8,bytes32[2],uint256)","b1bf0510":"getJobsBoard(uint256)","b1c0e063":"cancel(address[3],uint256[4])","b1c0f2df":"maxWithWhitelist()","b1c16a2b":"HARD_CAP_TOKENS()","b1c19c4d":"LetItPlayTokenPromo()","b1c23704":"myMethod3(string)","b1c23ce6":"saleContributions()","b1c25586":"lockTokens(address,uint256)","b1c30210":"setValidationData(uint16,uint16,uint8,uint8,uint8,uint8,uint16)","b1c32b2b":"updateAngelLock(uint64,bool)","b1c3c97e":"increaseTotalWinningStake(uint256)","b1c4b70d":"confirmLawfulness(bool,bytes32)","b1c5f992":"setAffiliateRate(uint256)","b1c62e8a":"createProductionUnit4()","b1c6517a":"LookAtNumberOfPlayers()","b1c73525":"getKeccak256(uint256)","b1c8ac52":"minEthToContribute()","b1c90f6f":"ClaimingTimeLimit()","b1c9cc6c":"getSBounty()","b1c9fe6e":"phase()","b1ca3b3a":"_icoTokens()","b1cb0db3":"expires()","b1cb267b":"getE()","b1cb4217":"betContractUP()","b1cb43bf":"tokenToExchangeSwapInput(uint256,uint256,uint256,uint256,address)","b1cb574b":"setEarlyParticipantWhitelistMultiple(address[],bool[],uint256[],uint256[])","b1cb9425":"private_kill()","b1cc1d4d":"depositAndBundle(uint256)","b1cc38d0":"setShortPositionExpired()","b1cc4348":"placeWager()","b1cc7c60":"mintInterest(uint256)","b1cd221a":"redeem(address,uint256,string)","b1cd79de":"setlockaddress(address,uint256)","b1cdbe2a":"ELTC()","b1ce0a9b":"nextPayoutBlock()","b1ceb746":"acceptContribution(address,uint256)","b1cedd89":"PayPerkToken()","b1cee330":"arrayOfTokensByAddress(address)","b1cf404b":"sendTokensToOneAddress(address,uint256)","b1d006d6":"extendICO(uint256)","b1d0073b":"updateMaxNumMC(uint256)","b1d05422":"SendEmail(string,string)","b1d06c46":"moduleHandler(address[])","b1d0b725":"sellStatus()","b1d0fbc5":"uraniumplusToken()","b1d11f23":"setVesting(address,uint256,uint256,uint256,uint256,uint256,bool)","b1d17c98":"distributeTokens(address)","b1d1a159":"curRefNumber()","b1d1fed9":"multisigDXF()","b1d2372b":"JumboToken(string,string,uint256,uint256)","b1d27e3f":"setSmallPrice(uint256)","b1d3ea61":"salesContract()","b1d45fad":"HoneyBadger(address)","b1d5114c":"Hawk2(uint256,string,string)","b1d51d31":"pay(uint64,address)","b1d66003":"getRareItemInfo()","b1d6a2f0":"saleAgent()","b1d7ee21":"discountMultiplier()","b1d919ed":"LogCertifierDbChanged(address,address)","b1d9647e":"ecoBuilder()","b1db1cac":"gameGetTokenBankrollList()","b1db9c2e":"WordCoin()","b1dbb87a":"DEVELOPER_FEE_PERCENTAGE()","b1dbeb37":"PRTC()","b1dce014":"buildTeamMapping(uint256)","b1ddf52f":"getAuctionByIndex(uint256)","b1de4f0f":"setOwnerMaster(address,address)","b1de74d6":"LOG_SpinsContainerInfo(bytes32,address,uint256)","b1e045f7":"sponsoredJackpotMax()","b1e05e8a":"extractBytes32(bytes,uint256)","b1e19d45":"whitelistBurnFrom(address,uint256)","b1e1c18f":"addToManagementWhitelist(address)","b1e1ff3a":"tokenMetadata(string)","b1e254c7":"mock_clear()","b1e2a116":"playersToTotalBets(address)","b1e2cb03":"newLottery()","b1e2e1dc":"rollRoom(uint256)","b1e2e28c":"YUPIE_PER_ETH_SALE()","b1e3301f":"checkFlags(uint16,uint16)","b1e35242":"getMeOutOfHere()","b1e37921":"setDefaultMintingAddress(address)","b1e3dd57":"availableTokensAmount()","b1e50702":"setConfigSetupContract(address)","b1e5e2b7":"openBox(uint256)","b1e776e3":"updateMarketCap(uint256)","b1e834b0":"totalPreSaleTokenIssued()","b1e8aea8":"turnBackTime(uint256)","b1e8cca8":"openWormhole()","b1e9292f":"min256(uint256,uint256)","b1e9932b":"claimAndConvertFor(address[],uint256,uint256,address)","b1e9b21d":"deletePokemon(uint256)","b1e9ee64":"addressChangeRequests(address)","b1eac37e":"jackpotAmount()","b1eb2c10":"getForecast(bytes32,bytes32)","b1ebcce1":"setTxcode(uint256,uint256,uint256)","b1ecb343":"recentPlayersBack()","b1ed795e":"withdraw_all_eth()","b1ed8c99":"stageFourEnd()","b1eefcc1":"_changeOwnership(address,address,uint256)","b1ef2e97":"setXPROMO_MULTIPLIER(uint16)","b1efbd6f":"setMinimumEthereumToInvest(uint256)","b1efc755":"operationAmount()","b1efeece":"assignedSupply()","b1f0a72f":"getSubmittedStateRoot(uint256,uint256)","b1f0e40b":"finanVestingStage()","b1f253f6":"theDividendsOf(bool,address)","b1f25ffe":"calcFutureDebt(address,uint256)","b1f29590":"totalTulipCount()","b1f2e537":"setIsTokenTransferOpen(bool)","b1f32231":"awe()","b1f35246":"setActualMinerAddress(address)","b1f395ea":"addPauser_(address)","b1f3b35c":"listeners(uint256)","b1f3ec87":"SafeasyToken()","b1f42430":"ZitKOINCrowdsale(uint256,uint256,uint256,address,address)","b1f4ff90":"filters()","b1f525c6":"counter(uint256)","b1f56187":"debugBuy()","b1f5b6da":"setTokensLimit(uint256)","b1f6bd0d":"deleteInvoice(bytes32)","b1f8100d":"proposeNewOwner(address)","b1f864fb":"diamondIndexToOwner(uint256)","b1f9275f":"ENJ_UNIT()","b1f99cd5":"blockDotCoinbase()","b1fa884d":"FixedChain()","b1fc0792":"ICO_LEVEL_5()","b1fc756f":"getRefBonusPercent()","b1fc8466":"MAX_AVAILABLE_JOINTTOKENS()","b1fca956":"endTimeRound1()","b1fe1b4a":"weiRaisedICO()","b1fe3eef":"buyTokensFor(address,bytes32,uint256,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","b1fe5f58":"BIDDED()","b1fe933d":"incrementRedemptionAddressCount()","b2016bd4":"collateralToken()","b2019b8a":"EmtCrowdfund(uint256,uint256,string,string)","b202a9f4":"ERC223MintableToken(string,string,uint8,address)","b203bb99":"balance(address,address)","b204bb5d":"AddTicket()","b2057a6f":"inquireDividentAmount()","b205feb7":"stringToUint(string,int256,string)","b2067bd6":"ETHs(uint256,string,uint8,string)","b206eb42":"getImageDescriptor(uint256)","b207e32b":"testChangeRole()","b2085903":"Winner(address,uint32,uint32,uint32,uint256)","b208a600":"Nordic()","b20953f2":"isFiscal(bytes32)","b20a459d":"ZZZToken()","b20a4abb":"LogCustomSale(uint256,uint256,uint256,uint256)","b20a8779":"transferPreICOCollected()","b20b0ef5":"getAvailableCardCount()","b20b8403":"updateClaimFee(uint256)","b20baa00":"RegisteredToken(address,uint256,address,address)","b20bf95b":"setYearlyUSDSalary(address,address,uint256)","b20c0e43":"PHASE1_RATE()","b20c9f8b":"sellMaximumPossibleAmountOfTokens()","b20cc590":"allowedRoles(uint8)","b20cedc3":"getAdmin(address,bytes32)","b20d30a9":"setDailyLimit(uint256)","b20d3b1c":"vestingReleased(uint256,uint256,uint256,uint256,uint256)","b20de8f3":"TECHNOToken()","b20debeb":"Duckcoin()","b20e5a79":"getdecimals()","b20f41ab":"updateBaseComparable(int256)","b21089dc":"removeInvestmentPackage(uint256)","b210dac9":"confirmTransactionSig(bytes32)","b210e434":"functionThree()","b210f639":"PlatformAutonomyAddr()","b2112ce6":"beerContract()","b21287ae":"ToOwner()","b212a23e":"ethConvertRate()","b2138754":"verifyDocument(bytes32,bytes32[])","b213d77d":"editBalanceOf(address,address,uint256)","b2141ba4":"assertCompareBalance(uint256,uint256)","b21457e3":"getInvestorByIndex(uint256)","b214691c":"setAgent(address,address,bool)","b2148d38":"getBasicExtraBallotFeeWei()","b214ecda":"createGift(uint256,string,string)","b214faa5":"deposit(bytes32)","b215814b":"emtpyTo(address,address)","b215a879":"cg()","b215d2c9":"getCertainProducts(address,uint256,uint256,uint256,uint256,uint256,bool)","b215f30c":"changeWhitelist(address,address)","b2163482":"lockedAt()","b216c15d":"copyPopRequest()","b2170394":"getLastPaperFromContract(address,address)","b2173afd":"setzAddressesArray(address[2])","b21800d0":"TokenTransaction()","b2185bb1":"drawWinner()","b2186b05":"CrowdsaleSoftCapReached(uint256)","b2189168":"updateGame(uint256,string,uint256)","b2189d5a":"GetUserPELOBonus(address)","b218cf15":"registerToPool(address)","b2194fd8":"UinfoToken()","b219610a":"getRegionPurchasedAt(uint256)","b219c852":"firstStageTotalSupply()","b21a8be0":"isSuccessfulIco()","b21bce4c":"vote(bytes,bool)","b21c2475":"getWeiForRefund()","b21c2a68":"changeBZRxTokenContract(address)","b21ce425":"amountToTransfer()","b21cee7d":"get1TokenBuyPrice()","b21e4ebd":"itemOfOwnerByIndex(address,uint256)","b21ed44e":"percentForSale()","b2205a38":"xcertKyc()","b2210c91":"cashBalanceOf(address)","b22175db":"GetLikeCount()","b2225351":"verify(uint8)","b222cb0b":"selfRegister(bytes32)","b2237ba3":"setRatio(uint256)","b223d285":"releaseVanityUrl(string)","b2240566":"EOJ()","b2246f43":"Result(bytes32,address,uint256)","b224c40a":"vote(uint8,string)","b22528e4":"getUserEventsByIds(address,uint256[])","b225c23f":"updateCredit(address,uint256,uint256,uint256)","b225e08a":"whiteListTime()","b226ec29":"Gov(uint256,string,uint8,string)","b2280b48":"chairmanOf(uint256)","b2281442":"setMaxAbsKindness(int256)","b2288649":"lotteryBalance()","b22a7bfa":"migrateBalances(address,address[])","b22b2b66":"setKYCFull(address[])","b22c14c7":"multiPartyTransfer(address[],uint256[])","b22d9f50":"GallerionCoin()","b22dd140":"assetStaker(bytes32)","b22dd2ca":"R1()","b22e6fee":"get_pre_kyc_iconiq_bonus_denominator()","b230642d":"createSubscription(uint256,uint256,uint256)","b23096e9":"tokensTeamBlockedTimestamp()","b230eda1":"stageTwoSupply()","b2310cc5":"payRequstedSum(uint256,uint256)","b231e5cd":"STAGE_FOUNDATION()","b2322c40":"RabtestToken()","b2353d69":"updateRightLottery(address)","b2355b42":"setHomeDailyLimit(uint256)","b2356ad4":"tradingFeePercentage()","b2357392":"NewToken(uint256,string,uint8,string)","b23605eb":"PALToken99(uint256,address)","b2369f12":"getLockAccounts()","b236a3c9":"updateminAmount(uint256)","b236b068":"totalAlloctedToken()","b2378428":"LetsbetToken(address,address,address)","b237f7d4":"burnTokens(address)","b238724b":"setPendingValue(uint256,uint256)","b2389da8":"balanceOfFlurbo(address)","b238ad0e":"getDaysInMonth(uint8,uint16)","b2394040":"rateThirdWeek()","b239e2f1":"adventureHandler()","b23a0b90":"Henfruit()","b23a31e4":"getBrickIds()","b23b369b":"getPokemonLevel(uint256)","b23b4dd4":"incrementOwnedArea(address,uint256)","b23bc656":"setOverdraft(uint256,uint256)","b23c1f19":"mintTokenRewards(address,uint256)","b23d36b0":"isCheckStage()","b23d4854":"setTokenContractAddress(address)","b23db1be":"subtoken(address,uint256)","b23e35bf":"readLoveStory(bytes16)","b23f3594":"updateTeam(address)","b2401e1e":"nextDisbursement()","b2406905":"whoHasTheBiggestDick()","b240798e":"withdrawBet()","b241a020":"freeGameLockedToken(address,uint256)","b241b3b5":"getHarvestOperation(string,address)","b241ff03":"passPeriod()","b2427755":"minTrade()","b242c9c3":"getAmountRegistered()","b242e534":"transferOwnership(address,bool)","b24374a2":"omg()","b2444a70":"getParentA(uint256)","b2449d65":"YES()","b244b268":"SeeleCrowdSale(address,address,address)","b244c3f3":"ddftFundDeposit()","b2450b15":"openSoldTokens()","b24539a9":"getIcoTime()","b245923e":"proveIt(bytes32)","b245d6da":"coinIssuedIco()","b245fc92":"findNextMonth(uint256,bytes)","b2461b15":"upgradePermissionedSC(address,address)","b24626e9":"setAODevTeamAddresses(address,address)","b2467742":"CryptoPhoenixesCivilWar(address,address)","b2471e8e":"Fart(string)","b2478cfe":"recoveredIndex(address)","b247c525":"amountNeedToBeLock()","b247ed92":"getAllShipStats(uint32[])","b2481048":"newGlobalChanceNo()","b248e436":"IsBoilerExpire(address,uint256)","b248e4e1":"orderPriority(bytes32)","b2494df3":"getModules()","b2498a1f":"setPercent1(address,uint256)","b249bf01":"sendtoC(uint256)","b24a5425":"_setRoleCapability(uint8,address,bytes4,bool)","b24b09fd":"RefundEvent(address,uint256,uint256)","b24bf695":"getInvestorsAddresses()","b24c0a38":"setPreSaleParameters(uint256,uint256,uint256,uint256)","b24c35e4":"getRoundBetOrigin(uint256,uint256,uint256)","b24cb812":"removeAllowCnsContract(bytes32,address,bytes32)","b24ce5fa":"thirdCheckpoint()","b24d0c84":"addDat(string,string)","b24d8de2":"failedTemperaturesAt(uint16)","b24dced3":"setTransferFeeMin(uint256)","b24ec0b0":"LogStudentCertified(address,uint256,address,bytes32)","b250ce21":"CMC()","b251eb05":"MemberAdded(address)","b2523b67":"getReferenceAddressesOfCode(bytes32)","b252720b":"healthCheck()","b252ff2b":"threeHotHoursTokensCap()","b25302f6":"WineSupplyChain(address)","b25310b0":"DdosToken()","b25461ec":"cancelRequestPause()","b2549717":"setCalFactor(uint32,uint32)","b2550a53":"maxCyclePlayersConsidered()","b2552fc4":"annualInterest()","b2561417":"setMinimumGoal(uint256)","b2563a1b":"getMinimumLimit()","b256b093":"reservedForFounders()","b256dd6e":"WhosTheBossNow()","b2570b1c":"getBattleCardInfo(uint256,uint256,uint256)","b258eacf":"totalSupplyInt()","b2594125":"SurgeToken()","b2596a67":"levels(uint256)","b2596acd":"setForRent(uint256,uint256,uint256)","b25a00fd":"nativeToErcBridgesAllowed()","b25a7a9d":"calculateOwnership()","b25a80f4":"StoppableShareable(address[],uint256)","b25af26f":"applyForVisa(uint256,uint256)","b25ba6a7":"refundContribution(address,uint256)","b25bb3a7":"ownersGeneration()","b25c22b2":"approveMotion(uint256)","b25c372e":"prolongate(uint256)","b25cdccf":"fundingState()","b25e6181":"UnanimousConsent(address[])","b25e8973":"LBN()","b25ebbad":"_issueBitmark(address,bytes32,int256,uint256)","b25f539d":"registerUser(address,address,string,uint256)","b25f692a":"validateAndGetPurchaseTokens(address,address,uint256)","b25f8596":"PUBLIC_SALES_1_PERIOD_END()","b25fa92c":"adminAddRole(address,string)","b26041a1":"DELL()","b260c42a":"activate(uint256)","b261ce9c":"IsThisPublic()","b261f82f":"releaseAll(uint256,uint256)","b26209f6":"remainingFundsToEndAuction()","b2627ec0":"buyPriceAt()","b263c00c":"setV_R2(uint256)","b263f638":"minimalRewardedBalance()","b263f865":"usdPerHundredEth()","b263fb3f":"updateBasePriceAndMarketCap(uint256,uint256)","b2667cd0":"currentInvestment()","b266b828":"_sendTo(address,address,address,uint256,bytes,bytes,bool)","b266c661":"startDates(uint256)","b267f998":"addressFundBonus()","b2683aa6":"numberOfWagersToFinalTimeout()","b2684945":"usdSale(address,uint256)","b2686774":"sendFunds(uint256,address)","b269681d":"destination()","b269d584":"insertValue(uint256)","b269eaff":"imageGenerationCodeMD5()","b26b4f25":"changePrice(string)","b26c9779":"changeApproval(address,bool)","b26d9d6e":"IntermediateVault(address,uint256)","b26e4aed":"test_set_get_PremiumFactors()","b26eafe4":"lockUntil(uint256,string)","b26ee15c":"interfaceFreezeTokens(address,uint256)","b26ee5fe":"getTotalF4()","b26f72a4":"withdrawJOYTokens()","b26f7efc":"startGame(uint256,int256,address[])","b270b209":"BlocklanceContractHolder()","b27201ca":"investedFrom(address)","b272fa2d":"getMyHipster()","b273952a":"_isUserInternalLock()","b2741997":"BAIRON()","b274e48e":"setSaleStatus(bool,bool)","b2758411":"setUserDisplayName(string)","b275a9d8":"PackageContract()","b275ba3a":"registerUser(address,address,string)","b2774b17":"createOrSet(string,uint256,string)","b2775b02":"genBaseStats(uint256)","b2787e0c":"changeTransferAgentCA(address)","b2788540":"manuallyConfirmDonation(address,uint256,uint256,string,string)","b278b8df":"updateVoteInfo(address)","b27913a6":"LedgerUpdated(address,address)","b2792811":"getFreelancersJobContracts(address[],uint256)","b27a1f63":"horseFS(uint256)","b27b0755":"earlyBirdsSupply()","b27b7dd1":"removeStage(uint8)","b27b8415":"dailyHashExpires()","b27bcaea":"startBetBlue()","b27c0ccb":"ETASToken()","b27c4b92":"buyCore(address,uint256)","b27c4cde":"ethereumhorse()","b27d31de":"bulkTransferEther(address[],uint256[])","b27daded":"processorAddress()","b27e7244":"addDestinationChain(bytes8,address)","b27ea08d":"tokensRemainingPreIco()","b27eb3e5":"airDrop(uint16)","b27f829e":"removeNetworkMember(address)","b27f88fb":"endFifthWeek()","b280055b":"roleSetup(address)","b280a7e7":"changeSender(address)","b280a96e":"setUseAddr(address)","b280f180":"setRates(uint8,uint8,uint8)","b2813f19":"withdrawOrderTo(address,uint256)","b28175c4":"stor()","b281c478":"currentCluster()","b28241f9":"getCityPopulation(uint256)","b283f2f1":"accessoryDataContract()","b28448f4":"NewDeposit(uint256,uint256,uint256,address)","b2849055":"resetBalanceOfValues()","b284fc29":"investorsTokensPercent()","b285041d":"Satoshi()","b2852bec":"saveCash(address,uint256)","b2855b4f":"setFeeAddr(address)","b285643e":"leaderboardDataContract()","b2860396":"setstart(uint256)","b286a346":"SimpleAIToken(uint256,string,uint8,string)","b286ba8c":"heapSort(uint64[])","b2879d45":"setDRSCoinAddress(address)","b288d748":"reduceLockingTime(uint256)","b2893ba5":"next_balance()","b28945a5":"setApprovalForAllByContract(address,address,bool)","b28b3a6e":"famedStarNameToIds(bytes32)","b28bb2a0":"setStorageTime(uint256)","b28bf6af":"decreaseClaimsBalance(address,address,uint256)","b28c461c":"TOKEN_RATE_BASE_RATE()","b28c48bb":"NecashToken()","b28c747d":"getSentTransfersCount()","b28e5904":"Xflip()","b28eed93":"Listed_NotValidated(uint256,string)","b28f1433":"BHNNetwork()","b28f1ee3":"reserveSeats(uint256[],uint256)","b28f4c60":"isEmptyString(string,string)","b28f53fe":"setMinimumTokensForPurchase(uint256)","b28f6fa3":"isOnAuction(uint64)","b28fc973":"getEthBalanceOf(address)","b28fd472":"miaomiao()","b290ae06":"shrToken()","b290b9ce":"resetAllDelegations(bytes32)","b290e45b":"BonusIssued(address,uint256)","b2910826":"set_payments_processor(address)","b29120fe":"getHeartPrice()","b291820b":"Etherich()","b29212b5":"delAudit(address,address)","b2923cff":"TAXRATE()","b2931096":"hasClaimed(address,uint256)","b29387e5":"payWinnerManually2()","b295a00e":"getLimit()","b2963db6":"closeDailyInvest()","b29775c1":"isDiscountValue()","b297a35d":"_redeem(bytes32,address,address,uint256,bytes,bytes)","b298247e":"gift(uint256)","b2983281":"largeCapLimitOf(address)","b2984858":"ico1cap()","b2990de1":"getByToCount(uint256)","b299708d":"dspRegistry()","b29a0308":"logAnonymous(bytes,bytes,bytes,uint256)","b29a08f7":"ContractMadePermanent(string)","b29a3cfd":"getPI_edit_13()","b29a61c1":"investorBalances(address)","b29ae23f":"getDateOfSignature()","b29b3511":"getSpaceshipUpgradeTotalSoldByModel(uint16,uint8)","b29b5366":"setRentable(bool)","b29b5be7":"getMintAdminApproval(address,address)","b29b686a":"isWarrantyValid(address,string,string)","b29c2493":"token(uint256,string,uint8,string)","b29c62f4":"myAccount()","b29cbcec":"LogChangeMultiSigAddress(address)","b29d7914":"getRefResults(uint256)","b29e201c":"spread(address,address[],uint256[])","b29e9909":"sCVars()","b29f0835":"doIt()","b29f2e77":"sendWarriors(address,address,uint256)","b29f731d":"__tinyOracleCallback(uint256,bytes)","b29f7f9e":"removeODEMClaim(address,bytes32)","b29f9d3b":"unfreezeAccountWithToken(address,uint256)","b2a072c6":"passUndistributedEther()","b2a082b9":"suicaId()","b2a1449b":"out()","b2a1a022":"getGasPrice(string)","b2a1c540":"setMemberId(address,uint256)","b2a1de22":"whitelistedCount()","b2a29615":"Criptomedicina1()","b2a2a4e2":"complianceContract()","b2a3fd05":"WithdrawEth(uint256)","b2a4c897":"createTable()","b2a4efd4":"MASTERY_THRESHOLD()","b2a5a012":"setTokenReturnRate(uint256)","b2a5bc70":"_tokenLeft()","b2a68466":"OZENToken(uint256)","b2a6d21b":"COMPANY_RESERVE()","b2a7239d":"sklToken()","b2a780e4":"BITCLAVE_AMOUNT()","b2a7d1b7":"AssetsExplorer(address)","b2a840c0":"enable(string,uint256)","b2a87fc3":"targetToAchieve()","b2a8a6f3":"sendFLC(address,address,uint256)","b2a8ff45":"Tokens_Per_Dollar()","b2a91457":"OIA()","b2a9ab9c":"getTotalBraggedVolume()","b2aa8291":"MAINSALE_CAP()","b2aa9f0f":"increaseTotalSupply(address,uint256)","b2aac51f":"lookupUser(string)","b2aae005":"getBalanceOf(uint256)","b2ab526d":"approveUsers(address[])","b2ab530e":"testFailRetractLatestRevisionNotUpdatable()","b2ab70ba":"getMaxIterationsForRequestDividends()","b2ac1bbe":"buyInternal(address)","b2ac5407":"GMRTokenManager(address)","b2acbc13":"isOwner(bytes8,address)","b2ad1993":"BalanceNum()","b2ad35c0":"distributor_address()","b2ad3d44":"updateComplianceProof(bytes32,bytes32)","b2aeb260":"setHiringDone(address,uint256,address)","b2af9362":"isValidSignature(uint256,bytes)","b2b02109":"partnerSaleTokensAvailable()","b2b0aefb":"verifyPendingShares(uint256[],uint256[],uint256,uint256[],uint256[],bytes,bytes,uint256)","b2b106d6":"participate_in_arbits_presale_crypto()","b2b158e8":"setHolderAmount(uint256)","b2b28679":"getDelegationID(address,address)","b2b3abb1":"removeOrderFromList(bytes32)","b2b45df5":"init(address,string,string)","b2b4ae25":"isEntitled(address,address)","b2b5d93c":"Stop(bytes32)","b2b5f0cf":"IOBT()","b2b5f86f":"getLocality()","b2b5fbf5":"subDroneItem(address,uint256,uint256)","b2b6e37e":"_min256(uint256,uint256)","b2b74405":"PizzaParlor(address)","b2b7d0ce":"HakataCoin()","b2b877c1":"MithrilValkyrie()","b2b95adc":"finalizeChangeInsurer()","b2b96792":"proposeSettlement(uint256,uint256)","b2b98ed2":"Winner()","b2b99ec9":"removeNode(address)","b2ba0aa5":"feesPer10000()","b2ba97de":"team_and_angel_beneficiary()","b2bab02a":"startIssue()","b2bae511":"initSiteRewards(uint256)","b2baede4":"getListingContractAddress()","b2bb419f":"ActivateEscrow(uint256)","b2bb72bf":"getIndexInfo()","b2bbac16":"firstWeekPreICOBonusEstimate()","b2bbae69":"payForVote(address,bytes32,uint256)","b2bbe75e":"Sunshine()","b2bc2f68":"Kitcoins()","b2bc6c19":"PRICE_11()","b2bcf495":"_releasableAmount(address)","b2bd96b2":"AcceptsFUNDS(address)","b2bdc6b3":"adminAddMonument(string,uint256,uint16)","b2bdfa7b":"_owner()","b2be8180":"TombCore()","b2be8a0d":"getUserWalletTokenBalance(address,address)","b2bea9c1":"releasePurchasedTo(address,uint256)","b2bec979":"cashOutCar(uint32)","b2bf731d":"SPECTRE_BOUNTY_ADVISORY_DEV_TEAM_ALLOC()","b2bfd948":"checkNumbers(uint8[3])","b2c15f29":"updateLastTime(bytes32,bytes32)","b2c1d7dc":"BGToken()","b2c2196f":"MxRecordChanged(bytes32,address)","b2c26f94":"updateParameterValue(bytes32,uint256)","b2c2921a":"TeamBox()","b2c3429d":"VouchCoin()","b2c3609b":"Play(uint8)","b2c50b92":"retryWinners()","b2c5b208":"_returnReturnData(bool)","b2c60132":"wingsWallet()","b2c60690":"finalizeVoting(address)","b2c62d46":"endClaim()","b2c652f3":"getMarkets(uint256[128])","b2c6b6dd":"preSaleContract()","b2c7c90d":"bitcoin_ratio()","b2ca38fe":"GAP()","b2ca3ec4":"securityGuard()","b2cad9b7":"getLevel(uint32)","b2cb0a3d":"VESTING_TEAM_DURATION()","b2cb1ebd":"Typhoon()","b2cb26c1":"addMaster(uint32,string,uint16,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","b2cb3a9b":"getCurrentShare(address)","b2cb3e93":"COSSDemo()","b2cb9f05":"Total_Deposited()","b2cc0eb3":"SpaceCoinToken(address,string,string,uint256,uint256)","b2cc36fc":"restoreFromColdWallet()","b2cc4165":"getOrderAmount(address,address,uint256,address)","b2cca39d":"pausedTime()","b2ccc4ab":"getFameBalance(address)","b2ccda0e":"setPrimaryOperator(address)","b2cd67ef":"Klein()","b2cda083":"PassCommitteeRoom(address)","b2cefd2f":"LiteToken()","b2cf9814":"assetManagerIncome(address)","b2cfdfda":"stringToArray(string,string)","b2d111f6":"maxGasPriceValue()","b2d1289b":"DepositManager(address)","b2d138d2":"rspScience()","b2d14545":"fbytes2(bytes2)","b2d1573f":"getUserRank(address)","b2d1f9be":"buyStar(uint256,string,string)","b2d23b7d":"fetchVoteResult()","b2d27832":"vestingPeriodTime()","b2d318f7":"VeteranCoin(uint256,address)","b2d37165":"startMinting(bool)","b2d37e95":"remove_order(uint32)","b2d3e85e":"isPeriodAllTokensSold(uint256)","b2d444df":"TIM6(uint256,string,uint8,string)","b2d48237":"refferalsRateBonus()","b2d4ae5e":"__callback(bytes32,string,string)","b2d5362d":"contractTokenBalance(string)","b2d5ae44":"getRefund()","b2d5e8b1":"VALUE_OF_UTS()","b2d6bc83":"fundCapital()","b2d6fd0b":"id_for_address(address,address,address)","b2d8efe0":"crowdsaleOpen()","b2d96b81":"safeAssetData(uint256)","b2da302b":"Thrill()","b2dad155":"trim(string)","b2dad25d":"getNameOfAddress(address)","b2dae885":"SpecialArrays()","b2db1d23":"regularMaxPerPerson()","b2dd5c07":"registered(address)","b2dda6b5":"totalEthReleased()","b2de1a3f":"CONTRACT_PROVIDER_ADDRESS()","b2df8456":"sponge(uint256[9])","b2df8bad":"getAvailableCoinsForCurrentStage()","b2dfa399":"ZRX_TOKEN_ADDR()","b2e02430":"divRate()","b2e02fc1":"addRefund(uint256,uint8)","b2e0baee":"SunContractIco(uint256,address)","b2e235c2":"BitBall()","b2e2c1c9":"updateCondition(uint256,uint256,uint256,uint256)","b2e2c75f":"totalUsed()","b2e30440":"Ducaat()","b2e33c8f":"getCountPlayerByTrackId(uint256)","b2e357b4":"isLinkClaimed(address)","b2e37e18":"extDestroyNinja(uint256)","b2e3d212":"IndexCoin()","b2e4c183":"preICOBonusPercent()","b2e4d35d":"validate(uint256,uint256,uint256,uint256,string,string,string)","b2e545ac":"TokenGreeneum(uint256,string,uint8,string)","b2e5d3ba":"getBtcRate()","b2e6ceeb":"takeOwnership(uint256)","b2e752cb":"MINCAP_TOKENS()","b2e774ce":"deliver(address,uint256,bytes32)","b2e7c288":"recipientString()","b2e85b67":"getPlayerStatus(address,uint256)","b2e94e78":"stage1_start()","b2ea073f":"setGeneScienceAddress(address,address)","b2ea088d":"returnUnsold()","b2ea0a39":"changeMinDonationLimit(uint256)","b2ead7bb":"fundsOut()","b2eafd57":"getRewarder(uint256)","b2ebe1c5":"_determineCharacterType(uint256)","b2ed26f6":"addresses3(uint256)","b2ee95f9":"dateRelease6()","b2eed299":"getPOOL_edit_28()","b2ef089a":"isStateTokensale()","b2ef48b9":"buyTokensWithWei(address)","b2f05133":"set_trader(address)","b2f0575c":"FooMintToken(int256)","b2f094de":"BittechPresale(address)","b2f106c0":"determineReward(bytes32)","b2f1bb5b":"tellMeASecret(string)","b2f1fe99":"refundManyTransaction(uint256[])","b2f2303a":"BreakbitsERC20Token()","b2f24225":"set_minDETsPerReturnMoreThan(uint256)","b2f2588b":"sortNumbers(uint8[3])","b2f2b06d":"_createCar(string,address,uint256)","b2f3319e":"ToggleTestMode(bool)","b2f3d299":"loadFunds()","b2f3ded4":"allMarketsFinalized()","b2f40531":"shutdownTransactions(address)","b2f4bdb0":"createdTime()","b2f5a54c":"getInvestors()","b2f7e989":"sourceTokens()","b2fa1c9e":"isComplete()","b2fa9206":"cancelIco()","b2fadc78":"_getStorage()","b2fb3b90":"cancelActiveAuctionWhenPaused(uint40)","b2fcb395":"GoldenBullChainToken()","b2fce4ea":"delegateVote(int256,address)","b2fed358":"getsafemode()","b2ff7945":"setARR(address)","b3002be7":"burnNSPs(address,uint256)","b30054b4":"set_address_GIC(address,address)","b3007dc6":"rateFirstWeek()","b302ea1e":"setRaindropAddress(address)","b302ec4b":"LocklistedAddress()","b30300d7":"_increaseAllowance(address,uint256)","b3034371":"unilateralRuling(uint8,uint256,uint256)","b30387a4":"gen0Count()","b30390ce":"registerItem(uint256,uint256,bytes32,bytes32,bytes32)","b303cec0":"addAccountReader(address)","b303dcbd":"Owned()","b303f9f7":"releaseHTOSupply(address)","b304376c":"begins()","b30475b6":"totalWeiClaimed()","b304b2e1":"allocated()","b305836f":"feeWithdrawTokenAll(address)","b3066d49":"setContracts(address,address,address)","b3070c12":"ADVISOR_REWARD()","b3074b8a":"SUTokenContract()","b30779b1":"payCommission()","b3082d25":"CreateCards(uint256,uint256,uint256,uint256,uint256,bool)","b30841d9":"totalEras()","b3097a08":"heldTotal()","b30ab349":"getContent(address)","b30bca06":"sum(uint8[])","b30cf414":"unpauseSALE()","b30d1bb8":"isDisableEther()","b30d95a0":"changeBonus(uint256,uint256,uint256,uint256,uint256,uint256)","b30dbc67":"DeNetToken()","b30e4533":"ABBCToken()","b3113d3f":"hardCapPrivate()","b311db2f":"setAccountType(address,uint256)","b311ee0c":"refundClaimDeposit()","b312dc91":"currentPayout(address,address,bool)","b31394cb":"_checkThenTransfer(address,address,uint256)","b3139d38":"updateSlasher(address)","b3141c69":"localsReptoken(uint256,string,uint8,uint256,string,string)","b314a984":"burnRemain()","b3154db0":"check(address,address)","b31567d3":"LogRemoveWhiteListed(address)","b31597ad":"redeem(bytes32,bytes32)","b315e453":"multiWithdrawReward(uint256[])","b31610db":"getIndex(address)","b317d031":"STATUS_PAID()","b319c6b7":"cooldownTime()","b319e9fa":"distributeMultiple(address[],uint256[])","b31a17f0":"FtC()","b31a4047":"_convertBlueprint(string)","b31a404a":"withdrawOnNoAvailablePlan()","b31a4e0d":"allocatePresaleTokens(address,uint256,uint64,uint64)","b31ab1c3":"disconnectOrderUser(address,address,uint256,uint256,address,address)","b31ba590":"PlayerCreated(address,uint256)","b31c5c64":"kscDecreaseApproval(address,uint256,string)","b31c710a":"oldToken()","b31cbe9a":"getAlice(uint256)","b31cd1be":"secretTaken(bytes32)","b31cf984":"getProgram()","b31d61b0":"whitelistAddress(address[])","b31d7730":"presaleFinalizeAgent()","b31d8a6f":"FreeTokenAdded(address,uint256)","b31dcaad":"timeToUnlockDDHHMM()","b31e1d4d":"delegateVote(address)","b31e822b":"isAllowTransfer(address)","b31e8889":"setParticipantWhitelist(address[],bool)","b31f8f93":"tokensLeft()","b32022e8":"calculateKebabBuySimple(uint256)","b3204b8b":"setParent(address,address)","b3204cc3":"setLineUpEnable_pool(address,uint256)","b3205410":"getCustomerInfo(address)","b3206453":"destination(bytes4,bytes)","b3209136":"WakaWakaCoin()","b320f459":"removeBid(uint256)","b32142a0":"getProgramPercent(uint256)","b3215499":"ICOBonusPercent3week()","b3219d17":"calculatePurchaseBonus(uint256,uint256)","b322269e":"GameStart(uint256,uint256)","b32381ee":"addmoney(address,uint256,uint256,uint256)","b324c62a":"fastTokenSale(uint256)","b324e80d":"depositEscrow(address,uint256)","b324fb6b":"startTimePreICO()","b3253e0f":"lastScheduledTopUp()","b326124b":"tRegSaleStart()","b326c189":"hasOpenCommissionerAuction(uint128)","b3280830":"addLibrarian(address,address)","b3292ff0":"addSuperAdmin(address)","b329bf5c":"cancelTransfer(bytes32)","b32b2805":"getArmyFullData(uint256)","b32b664f":"wantItForFree(uint256)","b32b8e2c":"contains(uint256[],uint256)","b32c41d7":"crowdsaleTargetUBO()","b32c65c8":"contract_version()","b32c6a25":"GenesisToken()","b32cb292":"setStartICO(uint256)","b32cec45":"CROWDSALE_ACCOUNT()","b32dbcd8":"getNumKnights()","b32dc51c":"totalPhase1Donations()","b32e02e8":"_getRarePlusRarity(uint32)","b32e4207":"setzString(string)","b32f19f9":"showFreezedTokensAmount(address)","b32f4b9a":"Barbie()","b32fab4e":"moneyback()","b3311309":"SingularityTest5()","b3335e6b":"setICOStartDate(uint256)","b33381fe":"calcAmountEther(address,uint256,uint256)","b333adfc":"coursesLength()","b333b0ee":"_stake(bytes32,uint256,uint256,address)","b333ce0d":"icoFinish()","b3344593":"trackingNo()","b334e90b":"tadpoleReq()","b334fd07":"createFincontract(bytes32)","b3350f03":"forbiddenAction()","b33527d2":"CreateBAT(address,uint256)","b3369866":"indexOf(uint128[],uint128,bool)","b336ad83":"getByName(string)","b336f8a3":"GetNumberOfRigs()","b33712c5":"unpauseContract()","b337a20d":"verifyLockSignature(bytes32,address,address,uint256,uint256,bytes32,bytes)","b33926cb":"owner_withdraw(uint256)","b33a10de":"cards_titanium(uint256)","b33a2ea0":"lastBlock_v18Hash_uint256()","b33a8a11":"setTokenReference(address)","b33aca37":"Mcoin(uint256,string,uint8,string)","b33adbf1":"darPremio()","b33c4b1f":"end_now()","b33cb8f6":"CrowdsalePaused()","b33ceb2c":"AddGossip(address,string)","b33e8ee5":"exchangeTokensById(uint256,uint8,uint8)","b33fcc7a":"multiTransfer(uint256[])","b340a972":"getaddr(address,uint8)","b340d8cf":"encodePriceFeed(uint256,uint256,uint256,uint256)","b340f2b4":"showAssetDetails(bytes32)","b3413d9f":"_forwardFunds()","b34195a3":"ICOTokensInvested(address,uint256)","b3423eec":"requestWithdraw()","b34244e8":"setCBaddress(address,address)","b34253be":"FundsVault(address)","b342d7c0":"genEOS()","b34362be":"setParter(address,uint256,uint256)","b3446f85":"registerPlayer(string)","b3447ac9":"getBytes32Values(bytes32)","b344e002":"saleDeposit()","b3470e97":"addHashes128()","b3472edb":"getMaxProfit(uint256)","b3477201":"createPadlock(string)","b3480369":"_getWaitingBlocks(uint256)","b3481e61":"updateTeam(address,uint32,uint8[],uint32[])","b3485dca":"UpdatePrice(uint8,uint32)","b3487a71":"getBetWaitEndEther()","b348ddde":"ETH750on54()","b3490bfc":"allowTransfer(address)","b34937c9":"feedMessage(uint256,string,string)","b349b973":"_init()","b349dbdc":"nfsPoolTransfer(address,uint256)","b349f6c7":"attemptSpend(uint256)","b34b2c26":"Simpletokenq()","b34b4f69":"XingchenToken()","b34c28de":"calculateBurnGoldFee(uint256,uint256,bool)","b34c3610":"assert1()","b34c8afb":"getBaseAmount(address)","b34d471d":"bulkCreateLamboSale(uint256,uint256,uint256)","b34debac":"canUseResource(address)","b34e0c47":"getUserScore(address)","b34e7b9d":"getgamecardlength()","b34e97e8":"login()","b34f094f":"INTToken(uint256,string,uint8,string)","b34f0e5e":"CLAIM_STAGE()","b34f407d":"setPerformer(address)","b34f43c7":"SVDelegationV0101_1(address)","b34f594b":"setNodePrice(uint256)","b34f7b50":"_generateDiscipleSale(uint256,uint256,uint256,uint256)","b350723f":"_guarantedBid(uint256)","b3508654":"addController(address,bool)","b3508783":"TOKEN_MAX()","b35176e2":"show_number_of_days_since_bank_opening()","b3521607":"XYCCTEST()","b3527cfe":"Follow(uint256,address,uint256)","b3528158":"DASHABI(uint256)","b352867c":"setFreeExtension(bytes32,bool)","b3535fe2":"_setProviderInfoFields(uint256,string,string,uint256,string,address,uint8)","b35376b5":"getDiamond(string)","b3539c44":"getMintForReportingParticipantTargetValue(int256)","b3549265":"coloredTokenCount()","b3559460":"getGenerationSize(uint256)","b3562e6e":"getCrowdsaleTier(uint256)","b356a3a5":"PLATFORM_GROWTH_VESTING_AMOUNT()","b3570116":"mintIfNecessary(uint256)","b357a028":"SCISSORS()","b357a552":"claimAuctionableTokens(uint256)","b357b72f":"setMaxMarketOffers(int32)","b35861b4":"setERC20Address(address,address,uint256,uint256)","b358755e":"testerCanNotReentrant()","b35893f3":"setExporter()","b358e375":"JobsManager(address)","b359cedd":"getTime(string)","b35ae7e8":"ViotToken()","b35e7d45":"setCriticalBucket(uint256)","b35eeb46":"GenHeliosCoin()","b3610f37":"destroyCar()","b36117b2":"create18FilmsTokens()","b36216d3":"allTokensDecimalsBalancesWeights()","b3621e1a":"addAddress(address[])","b36234c2":"AltruismMode(address,uint256,uint256)","b36292eb":"TestingCoin()","b3629f79":"get_proposal_by_row(uint256)","b3643e3a":"createSale(address,uint256)","b36752ee":"addressFoundersShare()","b36763c9":"_owoAmount()","b367fb11":"platformTokens()","b36877c9":"DragonKing(address,address,uint8,uint8,uint8,uint16[])","b368cb10":"getProviderInvitedUser(uint256,address)","b369940c":"wingsETHRewardsPercent()","b3699d0b":"withdrawedTeamCounter()","b369af71":"intervalOf(uint256)","b36a06b5":"preSaleFirstBonus()","b36a0b15":"getSignDetails(uint256,uint8)","b36ada82":"mintingOracle()","b36af005":"Menu04()","b36b9ffd":"bountyManager()","b36ba252":"getSellOrderPrices()","b36c1284":"MaxSupply()","b36c14fe":"getWhitelistUser(address)","b36c8022":"UnfreezeAccount(address)","b36c973e":"payOutWinner(address)","b36d829b":"getwinningaddress01()","b36df681":"ExecutableBase()","b36eaad8":"createUserMeme(address,uint256,string,uint256)","b36f2c30":"maxWeiUnverified()","b36f8e8f":"allowManager()","b36fef76":"promoFishCommission()","b3710a80":"infraEthWallet()","b37139e6":"reduceCD(uint256,uint256)","b37217a4":"getRandomNumber(uint256)","b372bd31":"getCommissionBalanceWEIInfo()","b373a48b":"getOneself()","b373a61c":"priceRandomFight2Death()","b373a6cd":"sendTokens(address[])","b373f167":"transfer(address,uint256,bytes,string,bool)","b3745afa":"changeAllocator(address)","b3746849":"buyTokens(address,bytes)","b374db9a":"secondsTimeLockedDefault()","b3753107":"gweiBBDPriceInWei()","b375603c":"raffleId()","b375a72c":"getHashPicture(bytes32)","b375b95a":"getMaxRankingSpots()","b3760c80":"orderMatch(uint256,uint256,uint256,int256,uint256,uint256,address,uint8,bytes,bytes,int256)","b37610ad":"getKey(uint16,uint16)","b37681fd":"SetPlayerID(bytes32,uint16)","b376feba":"_unsafeTransfer(address,uint256)","b378e89b":"CreateToken(address,uint256)","b37983e2":"gasRequired()","b379d235":"setFlowerAuctionAddress(address)","b37a336d":"VESTING_DIV_RATE()","b37a5de7":"throughputToday()","b37a6a2c":"restartPrivatePlacement()","b37bcd94":"discountPeriod()","b37c191b":"rank(uint256)","b37c7dc0":"sub256(uint256,uint256)","b37cc2f0":"getUserEventsLength(address)","b37d61f8":"checkMyBalance()","b37d97b5":"addMany(address[])","b37dcce2":"trainingFeeMultiplier()","b37edb66":"FundingEntity()","b37edfb6":"checkChangeOwnerArgs(uint256,uint256)","b37f17ee":"migratingAmountBooks(address,address)","b3803956":"showPlayerFullScores(address)","b380b0d4":"setProfitPercentage(bytes32,uint256)","b380beac":"setTotalWizzPandaOf(uint256,uint256)","b380d365":"resolveDisputeSeller(string)","b381cfe5":"iotpowerToken()","b3822da8":"getContents(uint256[])","b38260fe":"totalAngelCardSeries()","b382b0d6":"createContract(uint256,uint8,uint256,uint256,address,address,address,address,address)","b38336de":"getCoinAmount(uint256)","b3834ed4":"getRefunded()","b38400ff":"getEndedGames()","b38415f3":"getConfigBytes(bytes)","b384abef":"vote(uint256,uint256)","b384e9b4":"incentivisationFundAddress()","b3850b2a":"total_reward_amount()","b385e7b6":"playerPrizes(address,uint256)","b387ed6d":"getCompetitionStatusOfHopefuls()","b387ef92":"currentOwner()","b38854be":"ownable()","b38928c5":"Vineyard(address)","b38b2261":"addValidation(bytes32)","b38bf811":"setMessagesSigned(bytes32,bool)","b38c1504":"TOTAL_LBTOKEN_SUPPLY()","b38c7e3a":"getStrong()","b38ce3e7":"deedIds(uint256)","b38d3ab4":"attackeePrizeByToken(bytes32,address,address)","b38de8ce":"DelGoods(uint32)","b38f974a":"buyFood(uint32)","b38fb813":"crowdsaleInit()","b38fced1":"availableThemedSpinners()","b3908dc1":"IPXToken()","b390c0ab":"burn(uint256,uint256)","b391983c":"getLimitAndPrice(uint256)","b3922c42":"TOKEN_INVESTORS()","b3924a58":"GreenMining()","b3927eeb":"Expended()","b3935caa":"trivenewstestToken()","b3936f95":"basis(uint256,uint256)","b3938edc":"changeETHUSD(uint256)","b393a5b5":"setKingdomCreationFeeWeiRP(uint256)","b393a759":"ipfsSet(string)","b393fa46":"fundersClaimed()","b3942cbd":"setTransferAllowed(bool)","b3947c17":"muldiv(uint256,uint256,uint256)","b395cb3c":"vest(address,uint256,uint256,uint256,uint256)","b395f278":"view_get_blockNumbers()","b3965083":"Pothereum(uint256,string,string)","b3965cec":"RefundPeriodStarted()","b3966dc9":"init(address,uint256,uint256,uint256,address,address,uint256)","b396d7ad":"heapSort(uint256[])","b3970f27":"updateHpbNodeBatch(address[],bytes32[],bytes32[])","b397657d":"endInitialization()","b397ffd8":"m_foundersTokensStorage()","b39852f9":"createGame(uint256,uint256,uint256,uint256,uint256,uint8)","b398924d":"RangeGameProcess(address,uint256)","b398e098":"setMaxETHAutoContributions(uint256)","b3997703":"Loser(string,string)","b399a9f8":"setFungibleTokenAddress(address,address)","b399b0bc":"remaining(address)","b39a64cd":"getNumCalled()","b39a69a3":"withdrawPROV(uint256)","b39a7fbe":"setBattleDeciderAddress(address)","b39ad6e0":"DonatorInteract(string)","b39c2944":"requiredAuthorities()","b39c8739":"Strikes()","b39ca258":"createOrder(address,bytes32,bytes32,address,uint256,uint256,uint256)","b39d49fe":"sellNapkins(uint256)","b39d66d0":"LiipCoin()","b39d6b7b":"DukatToken()","b39dcb1d":"showDepositEther()","b39e12cf":"contractManager()","b39e1c6c":"withdrawDirectDebit(address)","b39e7bc1":"RealEstate(uint256)","b39f4171":"payForOther(address)","b39f4483":"setPOOL_edit_28(string)","b3a06e75":"airdropSingleAmount(address,uint256)","b3a0b1ef":"basicInfoGetter()","b3a0e188":"firstReserveTimeLock()","b3a1362a":"setMessage(int256,string)","b3a1584a":"toAddr(bytes)","b3a18632":"stakeAOContent(uint256,uint256,bytes8,uint256,string,string,string,string,uint256,uint256)","b3a196e9":"presaleSupply()","b3a1ca52":"addressFundDigitalMarket()","b3a26071":"LiquetLottery()","b3a27842":"getEntity(uint256)","b3a2a6c0":"setOfficialWebsite(string)","b3a2a999":"nextWithdrawal(bytes16)","b3a3c4f6":"identifierToRentPeriod(uint256)","b3a3d671":"addAllowanceToRecieveToken(address[])","b3a41c65":"power(uint256,uint256,uint256,uint256,uint8)","b3a56077":"vestingPeriodLength()","b3a61c80":"tryNextTimeRange()","b3a6d09d":"tgrSettingsPartContributor()","b3a7cbf6":"XRRsale()","b3a810f7":"tournamentOwnersCut()","b3a844ae":"tokenClose()","b3a9afb7":"getQuickBuyEtherToken()","b3a9b5f6":"multiply(uint256,uint256,uint256)","b3aaa277":"validate(address[4],address,uint256[11],uint256,bytes,uint256)","b3aae830":"deployProject(uint256,string)","b3ab15fb":"setOperator(address)","b3ab715e":"getTileIDbyPosition(uint16,uint8)","b3ac149c":"getCurrBalance()","b3ac7acd":"ownerSetMaxProfitAsPercentOfHouse(uint8)","b3ad4600":"RedCarpetToken()","b3adc716":"is_banned(address)","b3ade772":"shipProducts(string,string)","b3adfa0c":"summLeskiw()","b3ae1d2c":"completeTransaction()","b3ae65d7":"initialBlockNumber()","b3aefb75":"getCap(address)","b3af4426":"jackpotTokenLoseRewardRate()","b3af88f0":"proposalPresent(string)","b3afe437":"SPECIALIST_TWO()","b3b0c83f":"withdrawEndTime()","b3b0cf86":"Birth(uint256,string,address)","b3b0eae5":"getPaidAmount(string)","b3b163c4":"getLatestVersion(address,bytes32,address,bytes32)","b3b294a6":"bonusOn()","b3b32dc0":"hasSeat(uint256)","b3b39809":"Filiate_Changed(address)","b3b4b21e":"ZZZCoinDistribution()","b3b4ec54":"acceptColuLocalNetworkOwnership()","b3b4fd0f":"affiliateProgram()","b3b51aa3":"recycleSkin(uint256[5],uint256)","b3b548eb":"submitPrice(uint256,uint256)","b3b55c0f":"ELTWagerLedger(address)","b3b5c0ee":"fillSellOrder(uint256,uint256,uint256)","b3b5eaa3":"dive2(address)","b3b5ec33":"onPollFinish(bool)","b3b5fc76":"getImagePartsCount(uint256)","b3b71063":"BitPeso()","b3b77a51":"lock(bytes32,uint256)","b3b789fb":"GetLogMessageInfo()","b3b78cc2":"crowdSaleZxcSupply()","b3b81d38":"changeMinContribution(uint256)","b3b85e7f":"buyAtoken()","b3b89158":"reserveUnlockTime()","b3b8c620":"icoRatio()","b3bb594c":"delivery(address,uint256)","b3bb8cd4":"_now()","b3bb8d44":"OwnerDefined()","b3bb9b58":"LiquidDemocracy(address,string,uint256)","b3bc5b10":"editDefinedGame(uint256,string,uint256,uint256,int256,uint256,uint256)","b3bd870a":"participated(address)","b3bf07a1":"balanceofSTCDR(address)","b3c06f50":"transferFrom(address,address,bytes32)","b3c0b7be":"createOracle(address,uint256,bytes32)","b3c10469":"hijackClones()","b3c185a7":"addNVTtoGame(uint256,uint256)","b3c199c1":"dividendFor(uint32)","b3c1a588":"parseMsgData(bytes)","b3c1ee88":"updateDescription(string,bytes32)","b3c1fe4f":"donationMultiplier()","b3c2083f":"sellVolumesNext(address,address)","b3c25835":"addUser(address,string,string,uint256)","b3c298ea":"angelInvestors()","b3c2e8fa":"ethPause()","b3c2eac1":"setStatus(bool,bool)","b3c3699f":"createLockedState()","b3c3bbbd":"betters()","b3c4a36b":"setupToken(address)","b3c4b54a":"updateDestination(bytes32,address)","b3c4ee17":"userOfferCancelElement(uint256,uint256,uint256)","b3c4f83b":"DoftToken()","b3c5209f":"limitation()","b3c5998d":"onTransfer(address)","b3c63629":"PTSDToken(uint256,string,uint8,string)","b3c6487b":"setCatPrice(uint256,uint256)","b3c7476c":"TOSLittleHodingContract()","b3c7618e":"getVoteRuling(uint256,uint256,uint256)","b3c7d097":"theDeal(uint256)","b3c9983a":"getPara(uint256,uint256)","b3ca07d1":"closeRound(bytes32,uint8)","b3caba5a":"setReferralAddress(address)","b3cb8885":"nextUnderdogPayout()","b3cba833":"getData_16()","b3cc167a":"bidIncrement()","b3cc35f0":"taxPerc()","b3cd95d3":"incRandNonce()","b3cdabfd":"funForOwner()","b3cea217":"ID()","b3cea9e2":"createRadar(uint256,string,uint256,uint256,uint256)","b3cffc6e":"contributeBTCs()","b3d14775":"getPOOL_edit_13()","b3d159bf":"SearchMyFiles(string)","b3d176c9":"setPOOL_edit_33(string)","b3d1958d":"flush(uint256)","b3d1b801":"getOwnerCars()","b3d1bd95":"_recordFeePayment(uint256)","b3d2b441":"grantTokens(address)","b3d34e1b":"WithdrawDevFunds(uint256)","b3d39e63":"deleteProposal(bytes32)","b3d3d37e":"takeSnapshot()","b3d4e279":"earlyBackerList()","b3d4e3f2":"makeVendorValid(uint256,bool)","b3d4e41f":"PURA()","b3d62a25":"matchDay()","b3d6e119":"lockedPeriod()","b3d73743":"box1Star4()","b3d76188":"pay(address,address,uint256)","b3d7ac6a":"transferCompensationEthers()","b3d8056d":"findString(bytes32)","b3d84a28":"FreezeProduct(uint256)","b3d91e41":"DECIMALFACTOR()","b3da4b09":"mintEnergyAttributionToken(address,uint256,string)","b3da6eed":"Alluma()","b3daa652":"CLIFF_DURATION()","b3daab8a":"updateInvestBalance(uint256)","b3dac57f":"cancelUpcomingEvent(uint256)","b3db410c":"allowTransferTimestamp()","b3db428b":"depositFor(address,address,uint256)","b3dc0e94":"transferSoldCoins(address,uint256)","b3dcc5eb":"mint_and_transfer(int256,address,uint256)","b3dd23e8":"BTC_SUISSE_TIER_2()","b3dd5b1a":"WavesBitcoinToken()","b3de019c":"changePrice(uint256,uint256)","b3de5cc0":"_getTimeLeft()","b3de648b":"f(uint256)","b3dedf5c":"BACToken()","b3dee386":"collect(uint16,uint16,uint8)","b3df27f4":"checkFundingGoal()","b3df5b45":"oxleytoken()","b3df8737":"left50(uint256)","b3dfcdc3":"Contribution(uint256)","b3e18ed9":"finisGame()","b3e1f523":"setUnpausedWallet(address,bool)","b3e2564a":"amendAmount(uint8,uint8,uint8)","b3e25665":"collaborateInMerge(address,int256,int256)","b3e33a74":"mintingGoal()","b3e366ab":"getLastMilestone()","b3e3cc34":"sellToBlackMarket(uint256,uint256)","b3e3d8b4":"startOrHoldCrowdSale(bool,bool,bool,uint256,bool)","b3e53d8a":"maxPresaleContributionEther()","b3e5519b":"getOpenBids(bytes32,uint8)","b3e6713e":"LogClaimTokens(address,uint256)","b3e6c19f":"OJCToken()","b3e7c201":"ethPromoHelpers(address)","b3e7c2bd":"getVote(bytes32,address)","b3e83761":"KanCoin(address)","b3e98f82":"viewClaimableInvestorDividendPool()","b3e99b77":"systemClaimAirdropMultiple(address[])","b3e9da0c":"businessersTotalBalance()","b3ea3924":"PointlessCoin(int256,uint256,string,uint8,string,address)","b3ea553b":"JoyCoin()","b3ea5984":"getIndexOfTarget(address[],address)","b3eaaa7e":"calculateCHGAmountToEther(uint256)","b3eae9ac":"WashingtonExchange()","b3eb3a86":"getClosedContract(bytes32)","b3ebc3da":"weiRaisedTotal()","b3ed1957":"USDMToken()","b3ed2081":"fixedExpTest(uint256,uint8)","b3ede13f":"addToPrizePool()","b3ee4564":"assertStillValid(uint256)","b3ee5307":"CountersUpdated(uint256,uint256)","b3ee7248":"getDate(uint32)","b3eee638":"icoEnablersTokensMinted()","b3ef0045":"decodedRecipient()","b3ef774b":"getNumOfTokensBonusOnPurchase(uint256)","b3f00674":"feeReceiver()","b3f05b97":"finalized()","b3f08078":"bookCanvasFor(uint32,address)","b3f15866":"CropOracle(address)","b3f17c20":"miningOne()","b3f1c0c9":"setIssuer(address,uint32)","b3f1f31b":"testRecurringClones()","b3f22cb4":"setLUCKContractAddress(address)","b3f2c866":"startDateOfSaleStageLast()","b3f2ecfd":"endDiscountTime()","b3f2fa99":"playersShareAllocation()","b3f3668c":"getprizeamount()","b3f3ab5c":"removeContributor(address)","b3f3dcf6":"reinvestSubdivsAmount(uint256)","b3f3e673":"switchPeriod()","b3f3e737":"SendWalletFees(address,address,address)","b3f4d235":"updateCnyEthRate(uint256)","b3f50029":"finishedGameWithdraw()","b3f523a8":"devuelveTodasApps()","b3f57bae":"tokenIncluded(address)","b3f5849f":"Battle7oken()","b3f5ab78":"noncex()","b3f691c2":"approvePendingCostume(uint256)","b3f841ba":"minimumNumberOfTokens()","b3f865f7":"rebalance(address,address,uint256)","b3f8bef1":"tgeSettingsAmountCollect()","b3f936f2":"getTypeName(uint32)","b3f98adc":"vote(uint8)","b3f9b6e1":"showPlayerScores(address)","b3fa24ef":"getUnlockSdc()","b3faa12d":"blockTokens(address)","b3fad72f":"deposited(address,uint256,string)","b3fb052a":"NTVUToken(uint8,uint256,uint256,uint256,uint256,uint256,bool,string,address)","b3fb14ad":"getGameResult()","b3fb59c1":"_setCardId(uint256,uint256,uint256)","b3fc0c83":"safeLock(uint256,uint256)","b3fc34d4":"specialSanMint(string,string,address,address)","b3fcb85b":"Sold_Token()","b3fdc99d":"signalTradeIntent(address)","b3feda02":"ASSET_MANAGER_WALLET()","b3ff0065":"CGC()","b3ff1112":"redeemFunds(uint256,uint256,uint256,bytes32)","b3ff277d":"totalWon()","b3ff8bfb":"BONUS_5_DAYS()","b4003de4":"removeFromTeamBalanceMap(address)","b4007cda":"emergencyFlag()","b400d149":"betOnNumber(uint8)","b40127f0":"bestmoney()","b4015034":"cancelExplorationByShip(uint256)","b401faf1":"claimWinnings()","b4022950":"collectFeesInEther(uint256)","b4024d9f":"testTransferNoMoreThanTokenBalance()","b4025b92":"deployProject(uint256,bytes32)","b4026ed5":"clearAuth(address)","b402973c":"SeeToken(uint256,string,string)","b4037767":"CryptoUniversityTuition()","b4038efe":"setVestTokenAllocationAddresses(address,address)","b403c290":"getwinningaddress50()","b404e001":"COMMISSION_PERCENT()","b4051397":"TokenEtcb(uint256,string,uint8,string)","b405c549":"waiting()","b40615c6":"soldTokensTotal()","b4068734":"drawWinner(uint32,int8)","b406cf39":"isPeriodTimePassed(uint256)","b406d386":"convertForPrioritized3(address[],uint256,uint256,address,uint256,uint256,uint8,bytes32,bytes32)","b4073060":"getLockListLen(address,address)","b407d1d2":"allocate7ProjectToken()","b408ac01":"totalCandyNo()","b4099ff7":"queryImage(address,bytes)","b409da05":"logDoubleIndex(bytes,bytes,bytes,uint256)","b40a5627":"bidCount()","b40a9304":"allocateDelayedTokens(address,uint256)","b40b234e":"DigitizeCoin()","b40bfd35":"AlexTestCoin()","b40d8d58":"hodlerTime9M()","b40e415e":"mutagen2FaceContract()","b40e4bec":"computeCap(uint256,uint256)","b40e76fa":"minePoP(address,uint256,uint256)","b40ee3b3":"NewSmartSharingContract(string,uint256,uint256,string,string,string,uint256,string)","b40ee8b4":"setCredit(address,uint256)","b40f0352":"refund(address,address[])","b40f6f4c":"buyOptions(address,uint256)","b41044c4":"btc_token(address,uint256)","b410a034":"issuanceRatio()","b4114165":"foundationFundTokenCountInWei()","b411e54f":"removePolicyFrom(address,uint8)","b411ee94":"hash(string)","b4123abb":"getBatch(address,address,uint256)","b412506b":"turnFaucetOff()","b41283bc":"parseTradeCompatible(bytes)","b412a2d7":"StartDateUpdated(uint256,uint256)","b412a4b7":"asideTokensMintDate()","b412b1e9":"getForestCount()","b412b445":"icoBonus3()","b412d4d6":"CafeDelivered()","b412d627":"TokenWin(address,uint256,uint256)","b4134e6e":"totalRedeemedValue()","b413c923":"setReservedTokens(uint256,address[],uint256[])","b4144b79":"getTradesByAddress(address)","b414d4b6":"frozenAccount(address)","b4150f17":"masterAuth()","b415c4ca":"total_burned_by_raffle()","b416bc93":"TokenAllowance()","b4174cb0":"right51(uint256)","b41762f9":"capIncreased()","b41960d4":"redeemGift(string,address)","b419bd17":"getNumCoins()","b419dd2d":"hashesUsed()","b419f447":"ZipcoinToken()","b419f73b":"proveIt(address,bytes32)","b41a6ce2":"changeSettings(uint64,uint64,uint8)","b41a9f22":"totalRedemptionIdValue(address,uint64)","b41b208e":"DLP()","b41b3967":"m_holders(uint256)","b41bfa6a":"ABLGenesisToken()","b41d989d":"angelsDayCooldownEnd()","b41e6640":"taxMan()","b41e79d4":"firstChangeBlock()","b41f511c":"trade(uint256[],uint256,uint8,bytes32,bytes32,bytes)","b41fc258":"balanceOfPaillier(address)","b4200294":"totalApprovedAmount()","b42072e4":"tokenExchanged()","b420feb2":"ethDepositAddress()","b4210257":"addInitiator(address)","b4214c8c":"LogWithdrawal(address,uint256)","b42220ad":"enableChangeChannel(bool)","b4223757":"modifyMilestoneFrom(address,uint8,uint8)","b423c31e":"catchYou(address,uint256)","b423d93f":"icoUsd()","b424bd83":"getLastOrderId(address)","b425282d":"getBonusPool(bool)","b4256888":"openTime()","b425bd43":"distributeTokenToAddressesAndAmountsWithoutHost(address,address[],uint256[])","b42748d3":"PSYT()","b4279df3":"initialization(address,address,address)","b427c148":"calculatePointsBlock(uint32)","b4288aa5":"EventBattle(address,uint64,uint64,uint64)","b42963f8":"executeUpdateTransferMinimumFeeProposal(uint256)","b429844c":"userBanned(address)","b429af5e":"changeBotAddress(address)","b429afeb":"isController(address)","b429f65a":"totalEtherCookieResearchPool()","b42a02b5":"updateDID(string,string)","b42a11f9":"refundAllCollateral()","b42a275e":"bankAmount()","b42a8bf9":"_distributeRevenue(uint256,uint256,uint8,uint8)","b42b14c4":"DCNForGas()","b42b8559":"createPreSale(uint256,uint256)","b42c6b4f":"getPumpRate()","b42d6bd2":"SunToken(uint256,string,uint8,string)","b42dfa0d":"gen()","b42e49ef":"rollFive(address,uint8,uint8,uint8,uint8,uint8)","b42e8923":"pushBAU2(bytes32,address,uint256)","b4307192":"Bible()","b430da3c":"migrateHero(uint256,address)","b431da0c":"JavaOwnerExample()","b43216bf":"cvsquare(uint256[],uint256)","b4328e5b":"TokenSale(uint256,uint256,uint256,uint256,uint256,uint256,address,address)","b4330e24":"transferred_total()","b43386cd":"testBalanceAfterDeposit()","b434486a":"getPriceRiseAndFeePercent(uint256)","b4349daf":"TOTAL_HAWKING()","b4350e69":"ARBITRAGING(address)","b43545bb":"ownerValidate(address)","b436db29":"deployNetwork(address,address)","b43716a0":"getMajorityThreshold()","b43740c0":"casamenteiroToken()","b4375dc9":"adminSetEnabled(bool)","b4380764":"totalTokenHolders()","b438a2d0":"RigIdle()","b438d018":"guessNumber(uint256)","b439548d":"getStudent()","b43959c0":"setMembershipStatus()","b4396d42":"SAKECOIN()","b439be79":"AHCToken()","b43bd069":"getNumPassingTokens(address,uint256,uint256)","b43c19a6":"monsterAuction()","b43c35a5":"p_update_action(uint256,address,address,uint256,string)","b43c39a7":"_setRenewable(uint256,bool)","b43d42ec":"revokeRatioVote(uint8)","b43d4851":"transferSupply(address)","b43d9ede":"setMapMaster(address)","b43dbffc":"BulletinBoard(address)","b43f8a5c":"registNameXname(string,string)","b4402991":"userVoteFor(address,uint256,uint256,uint256)","b440b5c7":"EthPyramid00XX()","b440bf39":"setMonethaGateway(address)","b440f7ff":"setInterestor(address,uint256,uint256)","b4421cbd":"isPreTokenSaleActive()","b4421e7c":"releaseFoundationJM(address)","b442649d":"IlluminaCoin()","b4427263":"createTokens()","b443a085":"boom(uint256)","b443c607":"verifyCestificate(address,uint256)","b444b606":"getNowTokenPrice()","b444ff41":"setFirstRoundPricing(uint256)","b44531d3":"test_payment()","b4454253":"timePassed()","b446b5aa":"addAuthorized(address,address)","b446e7b9":"outterlockStartTime()","b4472022":"AECTToken(uint256,string,string)","b4478d7d":"updateTurnover(bytes32,uint256)","b447968c":"enterWithReferral(uint256,address)","b447acfa":"doubleSomeVar()","b447cfd4":"InitQuantity(int32,string)","b448017b":"periodPREICO()","b449188a":"updateCirculation()","b4495b7d":"MIN_USD_FUND()","b44996c4":"checkProof(bytes32,bytes,uint256[],bytes,bytes)","b449c689":"testdata()","b44a5e64":"GreenMed()","b44b0836":"getEAAttributes(uint32)","b44ba774":"_existPublicKey(bytes32,address)","b44bd51d":"getConfig(string)","b44bd688":"recoverLost(address,uint256)","b44cac23":"addJobSponsorship(address,address,uint256,string,string,uint256)","b44d7325":"signedTransferFromHash(address,address,address,address,uint256,uint256,uint256)","b44df72d":"tokensClaimed()","b44e2ab9":"onlySignerMock()","b44ec921":"whiteListContract(address)","b44eccc9":"periodICO()","b44ed831":"isDailyUplimitReach(address,address,uint256)","b44ef712":"secondRefundRoundFinishTimestamp()","b44f776a":"Test22Coin()","b44f794f":"removeUserRole(address,uint8)","b44f8cda":"icoSaleDeposit()","b45105b2":"post(string,address,string)","b4512913":"voteStatus(bytes32,uint256)","b45156fc":"startDate2()","b451794e":"numberOfOrders()","b4538897":"ICO_PHASE3_AMOUNT()","b4539817":"Donator2()","b453afb8":"getMinDisplayPrice()","b453fb01":"feeReceiverContract()","b4542a70":"getLLV_edit_19()","b454c415":"rNo()","b454e62e":"addPool(bytes32,address,uint256,uint256,uint256,address)","b456d9e2":"activateCrowdSale()","b456ecc5":"GetHash(bytes)","b458189f":"setAccountB(address)","b4590cbe":"ICOStatus()","b4594c36":"numberOfQuestions()","b4596ea6":"setPlayerGeneralAttrAdd(uint64,uint8,uint32)","b459c3fe":"WithdrawUnclaimed()","b45a2712":"mintCapInUSD()","b45aff16":"pullBalance()","b45b290d":"finalizePretge()","b45b7a51":"TokenSold(uint256,uint256,address,address)","b45be89b":"toGiveBase()","b45c48dc":"Security_AddPasswordSha3HashToBankAccount(bytes)","b45cff5f":"houseBankRoll()","b45db978":"Centspooladdress()","b45dd873":"enableBurning(bool)","b45f6df2":"updateDayTokenFees(uint256)","b45fb209":"setNewMessageNumber(string,uint256)","b460481d":"redeemShares()","b46062ad":"setInterestRate()","b460af94":"withdraw(uint256,address,address)","b4612d78":"CD(uint256,string,uint8,string)","b4621d07":"LimitBottom()","b4628c8a":"ENSRegistrar()","b46300ec":"send()","b46310f6":"setBalanceOf(address,uint256)","b463a75c":"addTeam(address)","b463bcde":"testThrowsSetNotTransferableNotOwner()","b46452a1":"convertTokensAmountInWeiAtRate(uint256,uint256)","b464631b":"get(address,uint256)","b464d582":"checkHowManyOwners(uint256)","b464d99e":"startTimeEarlyBird()","b465307c":"validPayAmt()","b4654d98":"transferMinusFees(address,uint256,uint128,uint16)","b465e52f":"secondRefundPollDate()","b46631cd":"SetTestModeHands(uint256,uint256)","b466b76f":"fresh()","b4670002":"updateEntries(address[],bool)","b4679b06":"multiplyWithNumber(uint256)","b46801c2":"balanceUpdatesCount(address)","b4693d23":"changeOpeningClosingTime(uint256,uint256)","b469ba24":"updatePokemon(uint256,uint256,uint256)","b469d6c8":"setFundingLowcapReached(uint256)","b46a8a21":"support_proposal()","b46bcdaa":"entries(bytes4)","b46e42ec":"setClue4(string)","b46eeebb":"TOKEN_FUTURE_CAP()","b4706fa1":"tokenSalesCapReached()","b470aade":"periodDuration()","b471fade":"_withdrawal()","b473d3b6":"EjariRulesC()","b4745939":"convertEtherToDust()","b47481a9":"BajwaToken()","b4750ca0":"getMiniumInputEther()","b4755160":"mkhash(uint256,uint256,bytes32,string)","b4758e82":"tokenAssignExchange(address,uint256)","b475a1c8":"ALLOC_TEAM()","b4765db7":"transferFromToken(address,address,uint256)","b476de2e":"callURL(string,string,string,string)","b47779ce":"FivePercent4Ever()","b47784d9":"testControlDisownNotOwner()","b477e7d5":"getFullTicketDetails(int256,uint256,uint256)","b4781f63":"change_coef(uint256)","b4787dc5":"linkEID(bytes,bytes)","b478886d":"promethCost()","b478f416":"setBaseCurrency(address)","b47a7a67":"proveIt(string)","b47b2cfe":"retraitStandard_4()","b47b6116":"removeCapFreeAddress(address)","b47be3e4":"addToWhitelist(address,uint256,uint256)","b47c11e8":"fidget(address)","b47d7409":"disablePurchase()","b47d89ad":"Details()","b47dbf22":"minPurchaseAmount()","b47deb3c":"winner(uint256,uint256)","b47df046":"setGrantEnable(bool)","b47e4c6c":"getTestOne()","b47f817e":"confirmAllBuys()","b47f833c":"contains(int8,int8)","b47fa7e0":"DepositLimit(uint256)","b4800033":"set(bytes32,string)","b4801272":"Dust()","b480eac0":"setTarget(uint256)","b4816be9":"endOfRewardsConfirmed(bool)","b4819e76":"getTokenDescription(address,uint256)","b481cbc0":"withdrawJajalanTokens(address)","b4821203":"investInQueue(address,uint256)","b483c054":"setOtherFomo(address)","b484d371":"fundReferrel(address,uint256)","b484de0d":"GetHashedMove(string,string)","b484e532":"getMyMsg()","b48585e5":"ATM(uint256,string,uint8,string)","b4861ca5":"assertSaneBalance(uint256,uint256,uint256)","b48666ee":"silverSaleLimit()","b4873ac7":"setCEOAddress(address,address)","b487b699":"addData(address[],uint256[])","b488abd8":"ANACoin()","b488f00e":"runSuperPrivilegeLuckyDraw()","b4894b1d":"gaps(uint256)","b489b365":"authorizeStore(address)","b489c597":"limitPresale()","b48ae96f":"finalizeRoom(uint8)","b48b4204":"register(bytes32,uint256,address,string,uint256)","b48b73aa":"setDivBonus(uint256)","b48bc2ee":"transferDepositsToNewDao(address)","b48c6807":"EtherLinkToken()","b48d323f":"getLiveChallenges(uint256)","b48eea44":"isWhitelisted(string)","b48f4f5c":"PreICOCents()","b48fcdc0":"setConfiguration(uint256,uint256,uint256,uint256,uint256,uint256)","b4909307":"getData(address,address)","b490e79f":"getChosenFreelancer()","b4921774":"getReportsByReporter(address)","b4929d4c":"publicSell()","b492bd32":"setMulBonus(uint256)","b493b0d0":"GESToken()","b4942ad1":"transferByCoinOwner(address,address,uint256)","b4944333":"getPlayerEarning(address)","b494b49d":"variationProbably()","b494f1fb":"totalReservedTokenAllocated()","b49575a7":"CORENET()","b49593fe":"PREMIUM_SALE_PACK_COUNT()","b4961379":"private_setOracleFee(uint256)","b49651ef":"FAPFund()","b4972398":"CTCToken(address)","b497d17d":"TileUpdated(uint256)","b4980148":"numberOfStarsToReserve()","b49845f9":"EventClear()","b498e3e4":"NeverConfused()","b4999e85":"endBlockNumber()","b499a26f":"getHowManyLeftToDistribute(uint256)","b499b2ce":"doNotThrowOnValidDiv()","b49ce17f":"totalCapsules()","b49d3a53":"stopTokenTransfer()","b49e3b62":"getPenetration(uint256,uint256,uint256)","b49f4afd":"getBasePrice()","b49f57ad":"getLastLevel()","b4a09ba9":"canAccessExclusive(address)","b4a0a6b8":"Sgethereum(uint256,string,string)","b4a0e24c":"getQuotaCheck()","b4a176d3":"restoreRegistry()","b4a2251e":"getOp()","b4a3208a":"SUAppToken(uint256,string,string)","b4a357a2":"get_participant(address)","b4a39dfd":"getChildId(bytes32,uint256)","b4a4136d":"BIMI_DAO_31()","b4a516a6":"addRTO(uint256,address)","b4a523e8":"mintedTotallyByBridge(address)","b4a5ef58":"updateDefaultTimeoutPeriod(uint256)","b4a66678":"Numtokens()","b4a77b0e":"isUserBlocked(address)","b4a7a022":"_buyInBatch(uint256,address,uint256,uint256[],uint256)","b4a8dd5b":"updateTimestampLimit()","b4a8f3e6":"timeOfDeath()","b4a93d9b":"transferBasic(address,address,uint256)","b4a97fc1":"removeBottomUpChild(address,uint256,uint256)","b4a99a4e":"Owner()","b4a9d156":"changeWaitTimeUntilWithdrawOrTransfer(uint256)","b4aa24db":"uncheckedUpgrade(address)","b4ab271c":"giftIdToGift(uint256)","b4abda8b":"sendOwnershipAndCall(address,uint256,bytes)","b4abea24":"BONDS()","b4ac5452":"exerciseCUSE(address,uint256)","b4ac8ad9":"getRetailerBalances(address,address)","b4ad016d":"Socialife()","b4ad6b5b":"transferFromTo(address,address,uint256,bytes)","b4ae641c":"arrayLimit()","b4b063df":"addNewClaim(string,uint256,uint256,string,string)","b4b06a74":"GiftClaimed(address,uint256,uint256)","b4b097eb":"addNewState(string,uint256[])","b4b0a6e2":"ADULTEUM()","b4b14467":"submitTokenTransaction(address,address,uint256)","b4b179dc":"getAmountToGive(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes)","b4b1b6d9":"getRecordStateRequiredChanges()","b4b1d9c7":"getDescription(address)","b4b22b5e":"ico_allocation()","b4b2938a":"Finapse()","b4b2d3d8":"phase3Price()","b4b3b028":"AddChain(bytes)","b4b4ff0a":"setDateStartTransfer(uint256)","b4b54328":"getActualPeriod()","b4b598ce":"TEAM_FUND()","b4b5b48f":"tokenData(uint256)","b4b68490":"totalTokenCap()","b4b68dab":"createPermissionsBot(address)","b4b71450":"PlaceRocketForSaleEvent(address,uint32,uint80)","b4b7771d":"setInvadeAddr(address)","b4b857d8":"DepositEther(address)","b4b9cd62":"UpgradeRig(uint8,uint16)","b4b9d1f1":"lookup(uint256,uint256)","b4ba2a1b":"percentFrom(uint256,uint8)","b4ba2eaa":"moveEther()","b4ba349f":"sing()","b4ba9e11":"claimFor(address,address)","b4baf9ff":"HybridX()","b4bb1b0a":"isEscrowActive()","b4bb58fb":"mix(uint256,uint256)","b4bbfb9e":"StateTransition(uint256,uint256,uint256)","b4bc3564":"do_guess(uint256)","b4bcc23b":"setInvest(address,address)","b4bd5c75":"setupPREICOPeriod(uint256,uint256)","b4bd9e27":"isOver()","b4be6190":"getFreelancerHourlyRateCurrency(address,address)","b4bede85":"transferSenderPaysFee(address,uint256,bytes)","b4bee870":"ChangePoolName(string,string)","b4beff8a":"GetMinerICOData(address,uint256)","b4c045e4":"NHMToken()","b4c16970":"BigRedCoin()","b4c16ea5":"CREATED_PROMO()","b4c2aaee":"tokenPriceMin()","b4c2e22c":"_ownerOfLand(int256,int256)","b4c48026":"safeBlock()","b4c4e005":"testTransferToAcceptAuthority()","b4c555a7":"addCollaborateToCampaign(uint256,uint256)","b4c5c983":"setMainYouCollectContractAddresses(address,address,address,address[])","b4c64ab0":"Goo()","b4c65de3":"identify(string)","b4c65f7b":"bonusesByDates(uint256)","b4c7abaf":"waitTime(address,address)","b4c8c5c4":"isApprovedAddress(address)","b4c91611":"weiDistributed()","b4c93fc0":"setOneGroupJoinersCount(uint256)","b4c98496":"CreditAsiaCoin()","b4caf8be":"rewardPoolTokens()","b4cbdd8b":"setClaimSignerAddress(address)","b4cbff23":"disputeStartedFreeze(bytes32)","b4cc2181":"setPropertyBecomePublic(uint16,uint256)","b4cd3701":"PointGameWithITG(address,uint256)","b4cd8865":"getArrBoolField1()","b4cdd3b7":"buyCertainOrder(uint256,uint256)","b4cdeb78":"LarsGeburtstagsgruss()","b4ce8ae0":"updateCrowdsaleEndBlock(uint256)","b4cec530":"totalFailedOldOwnerTransferAmounts()","b4cf5648":"PRESALE()","b4cfd972":"ROUND_4_PRESALE_BONUS()","b4cff9f5":"depositBool(address)","b4d00d94":"setIcoCap(uint256)","b4d01e87":"urandom(bytes32,uint256)","b4d07c7d":"GetWorldSnapshot()","b4d07e81":"setString(bytes)","b4d0ccb6":"getVaultInterestPerDay()","b4d0e552":"rareStartPrice()","b4d11f35":"getReleased(address)","b4d12bfa":"withdrawStudios()","b4d14728":"setRateAddress()","b4d168f7":"getFundedTokenCount(bytes32,string)","b4d1c485":"unlockFunds()","b4d1d795":"PERIOD()","b4d314f2":"isWithinPeriod(address)","b4d3c122":"CXLTotalSupply()","b4d3ef5f":"contributedEth()","b4d40694":"getPreminer(address)","b4d462b3":"unlockDate3()","b4d49b62":"RemovedTokenHolder(address)","b4d510dd":"countOfSaleTokens()","b4d60cfd":"payoutMining(uint256,address,address)","b4d657cc":"modifyCurrentHeroPrice(uint256,uint256)","b4d6befe":"BuyForHKGTransaction(address,uint256,uint256,uint256,uint256)","b4d6d4c7":"getPackageData(bytes32)","b4d8166e":"northadvisor()","b4d85686":"deductFee()","b4d927d0":"moneyFreeze()","b4d9cc3a":"profitDisperser()","b4da40f3":"getBadBets(uint256)","b4da4baf":"OWPayoutArb()","b4da662c":"_acceptDividends(uint256)","b4dad588":"numPendingRequests()","b4daff13":"test(uint256,uint32)","b4db1fc1":"deleteCandidatesBatch(address[])","b4dbf642":"buyATicketFromContract(uint256)","b4dc3dc7":"unbundle(address,uint256)","b4de64bd":"Sarf()","b4def1e7":"completedTransfers()","b4e05b89":"getOwnedShips()","b4e0aa3e":"testCallBack(uint256)","b4e0b764":"minSumICOStage5USD()","b4e19f3e":"getBestGuessSecondPlaceTentativeWinningPayoutDistributionHash()","b4e1a78e":"correctExchangeRateBTCxETH(uint256)","b4e28f79":"test_TorontoRules()","b4e327ec":"MajListNotVal()","b4e3add2":"_createCollection(string)","b4e3c486":"addProposal(uint16,uint256,string)","b4e50c9b":"contributed4(address)","b4e51b7b":"sane()","b4e56e01":"setMerchantRate(address[],int16)","b4e6850b":"add(uint80,uint80,address,uint32,uint32,uint32,uint256)","b4e68dc1":"ERC721BasicToken()","b4e6f92b":"BuyTroop(uint256,uint256)","b4e7fe0c":"pendingOraclize()","b4e81236":"_verifyOptionPoolIncome(address,uint256)","b4e8c036":"ProofOfWeakFOMO()","b4e92f20":"getInitializeUniverseValue()","b4e9ac13":"getAddressRefundValue(address)","b4ecb847":"areTokensDistributedForAddress(address)","b4ed3622":"calculateDecayedBalance(uint256,address)","b4ed7ec3":"getVoteOption(uint256,uint256)","b4ed8bf8":"removePolicyAttribute(uint8,uint256)","b4ee4f81":"Sotko()","b4eecb54":"s_pwd()","b4eff690":"checkFlag(bytes)","b4f14b2b":"DragonsBurned()","b4f15310":"invalidateHash(uint256,uint256)","b4f181c6":"ethToUsdExchangeRate()","b4f20aa9":"executionOpen()","b4f272e3":"TOPToken(uint256,string,uint8,string)","b4f2bb6d":"getPoolIds()","b4f2dc7d":"approveDividends(uint256)","b4f2e8b8":"setFee(uint256,address)","b4f3625e":"fuelContract()","b4f3b453":"reserveTimelock()","b4f40c61":"k()","b4f48e08":"projectFoundersReserved()","b4f4e284":"addAdminWhitelist(address[])","b4f5a21a":"getCurrentPeriodIndex()","b4f5a6a6":"minPurchaseOnce()","b4f5b9b9":"affiliatThreshold3()","b4f5d282":"getImmed(bytes32)","b4f666da":"capToken()","b4f6aa56":"getForSalePrices(uint16)","b4f80eb9":"getPixel(uint256)","b4f82c6a":"readCompany(uint8)","b4f94b4f":"_transferByDefaultPartitions(address,address,address,uint256,bytes,bytes)","b4f9529c":"RemoveMember(address,address)","b4f96d60":"_calculateBonus(uint256,uint256)","b4f9b6c8":"kill(bytes32)","b4fadcad":"relayMetaTx(uint8,bytes32,bytes32,address,bytes)","b4fc0344":"getAdsCountByCat(uint256)","b4fc3e3b":"createSchedule(address,uint256,uint256,uint256,uint256)","b4fcf935":"revealBet(uint256,uint256,bool,bytes32)","b4fe3017":"Whitelist(address[],uint256)","b4ff4f3d":"setCanMint(address,bool,int256)","b4ff87f2":"_approveTransaction(uint256,address)","b4ffaece":"setReservedTokensListMultiple(address[],uint256[],uint256[])","b4fffa52":"min_value()","b5000405":"gifted()","b5004d1c":"currentPotSplit()","b500cc08":"toBase58(bytes)","b501671c":"KillingChainToken(address,address,address)","b501df23":"Mintloot()","b503a2b9":"categoryId()","b503fcf3":"totalToSale()","b5040f0a":"getLastSessionVote(uint256,address)","b5044e85":"BATO()","b5046219":"getDailyPrice()","b504adda":"LOG_BetLost(address,uint256,uint256,bytes32)","b505a3f2":"LOG_Payout(address,uint256)","b505c6ef":"releaseTokens(address,address,uint256)","b507f7c4":"_setBlockHash(uint256)","b508069b":"implChangeReqs(bytes32)","b508adb9":"isStateInit()","b5093f7c":"HasNoEther()","b50954b6":"cancelWaitingForOpponent()","b509bae5":"OpenFundFactory()","b509c090":"getCurrEthValue()","b50a0899":"seeZombieDna(uint256)","b50a89f3":"MyToken(uint256,string,string,uint8)","b50bf8cb":"getStakeholderConfirmations(uint256)","b50c77f2":"initWallet2of3()","b50d2b35":"currentTokensRemaining()","b50e44b8":"EXCHANGE()","b50e4610":"refoundTokens(uint256)","b50eb5d7":"KeyTokenSale(uint256,address)","b50f2832":"set_participant_num_of_uses(address,uint8)","b50fa90b":"verPlayer()","b50ff2b8":"hiddenCapTriggered()","b51051d4":"addDataPoint(uint256,bool,string)","b510dc2a":"setIcoAddress(address,uint256)","b510e42c":"ethOfKey()","b510fe45":"newIdShip()","b5116a93":"getMyOwed(address,address)","b5120c30":"canBeClosed()","b5125493":"organizer4()","b5128f66":"view38()","b512e8a6":"agtAtnReceived()","b512f98c":"TSFINAL()","b5133189":"anotherOwner2()","b51459fe":"canWithdraw()","b5147d64":"getAccountCoords(address)","b515622f":"_getBonus()","b5160d6f":"setFreeMem()","b516444a":"mine_success(bytes32)","b516ce40":"manageKey(uint256,uint256,uint256)","b516cf2e":"MainContract()","b5175571":"changeCheckDate(bool,uint256,uint256)","b517570a":"ICO_TIER_FIRST()","b518a776":"tmp()","b519719e":"assertCheck(bool)","b51996de":"setWalletWithdraw(address)","b519c05b":"updateAdditionalEmission(uint256,uint256)","b519cf31":"rateLimiter_()","b51aae5a":"ResetAirdrop(uint256)","b51abfcd":"BCBCOIN(uint256,string,string)","b51ac349":"_updateArtistLookupData(address,uint256)","b51ad456":"IsPreSaleEnabled()","b51bda59":"_depositForRenter(address,uint256)","b51be1db":"infytoken()","b51c3d2a":"maxImmortals()","b51c4f96":"getCodeSize(address)","b51d42a2":"customPedro(uint256,uint256,bool)","b51d93eb":"confirmNewOwner(address)","b51dfa9d":"buySupply()","b51f86c0":"getCrcWithdrawAccount()","b520b68c":"withdrawForeignTokens(address,bool)","b520c7e7":"getWeeklyVolume()","b5217c39":"TotalCrowdsaleContributions()","b521c106":"bonusDate()","b521d3bb":"gcpn(uint256)","b522739a":"register_node(string)","b52303b2":"TransferToExchange(address,address,uint256,uint256)","b5232ba3":"registerUserWallet(address,uint32)","b523d13c":"VernamCrowdSaleToken()","b5247199":"readPhaseData(uint256)","b524abcf":"totalSupply(bytes32)","b525256f":"BloxrouteToken()","b525ab8d":"min_balance_for_bonus()","b5268fa4":"DisableTransfer()","b527b0a6":"setSaleAuction(address)","b5281b31":"purchaseMysteriousEmblem()","b52923a0":"setCompte_11(string)","b5299ca6":"giveMeat()","b52a3d8d":"initCaps()","b52a467c":"buyGold(bytes32,string,string,bytes32,string,string,bool)","b52a5851":"burnUnsold()","b52a6a38":"atLastUnclaimedFeeAllocation()","b52ae3fc":"transferBlackFunds(address)","b52b925d":"investorProfit()","b52bb6b9":"TokenSale(address,address,address,uint256)","b52c0c35":"setPayOutPercentage(uint8)","b52c1d5b":"calculateSeed(uint256[],uint256)","b52c64c7":"addNewInsurance(bytes32,uint256,uint32,uint32,bytes32)","b52db3b9":"updateRecord(address,address,bool)","b52e0dc8":"getRateAt(uint256)","b52fddbd":"setCrowdsale(uint256,uint256)","b53148ad":"currentAmountOfTokensWithNoBonus()","b5319335":"promoCreationLimit()","b531a872":"icoStop()","b532073b":"OwnerChanged(address,address)","b5320cd6":"test_22_assertGasUsage100Boards()","b532e4cb":"addModerator(address)","b5338408":"_numDigits(uint256)","b533ff5f":"getLockedStructTimeToLock(address,address,uint256)","b534b5b7":"issuedTokens()","b5352fa7":"MuMuToken(uint256,string,string)","b53564ea":"setInvestors(uint256[],address[],uint256[],uint256)","b535b5c3":"hashExists(bytes32)","b535c741":"makeOldFucks(uint32)","b5364560":"clearApprovalForGeneLab(uint256)","b536c686":"burnedTokens(address)","b536fa63":"stopGracePeriod()","b537488c":"GanaToken()","b537752f":"transfer(address,address,uint256,uint256,bool,bool)","b537f5b5":"settleBet(bytes32,bytes32)","b5389c20":"timeToBeBurned()","b538c5ea":"addWorkerPool(address,address)","b538cefc":"subtractDarknodeFee(uint256)","b538d3bc":"addArbiter(address)","b539cd55":"maxProfit()","b53aab4c":"changeServicePercentage(uint256)","b53b0a75":"Startex()","b53b1f12":"findRankByCount(uint256,uint256,uint256,uint256)","b53b3f41":"LuckyTree(uint256,uint256,uint256,uint256)","b53c71b6":"addLifeEvent(string,string,string)","b53c7245":"set_min_contribution(uint256)","b53dfdb9":"getTeamFund()","b53e9dfe":"requiredContribution()","b53ea172":"calcBindedBlindHash3(string,address)","b53ea1b6":"replaceKey(address,address)","b53eb39f":"getSecondsToComplete(bytes16,address,address,uint256,uint256)","b53f4d94":"setPOOL_edit_32(string)","b53ffba0":"owner_testEnd()","b5402ec3":"manager_withdraw()","b54030d5":"recordNr()","b54050c2":"_updateStateIfExpired()","b54144b2":"Receipt(address,uint256,uint256)","b5417a52":"TEAM_VESTING_WALLET()","b541a778":"SampleOffer(address,bytes32,uint256,uint256,uint256)","b5432fcc":"setManagerAgent(address)","b5439012":"closeSale(address,uint256)","b543d4b4":"getMasterWallet(address)","b54430ce":"canSign()","b5444ef2":"becomeCoowner()","b5446457":"deleteRoomByIndex(uint256)","b544bf83":"lockTimestamp()","b545252c":"isNewDay()","b545ddf5":"calculateReleased()","b545f2a6":"cards_blue(uint256)","b547a726":"turnOff(address)","b547aeda":"spawn()","b547b7a1":"committeesMap(address)","b54811f1":"EtheremonTransform(address,address,address,address,address,address,address)","b5481743":"exchangeRateAgent()","b5483f28":"changeAddressJoker(address)","b548c6f6":"Transaction1()","b549793d":"scheduleCall(bytes4,bytes,uint256,uint256,uint8,uint256)","b549bdda":"XavierToken()","b549c6b3":"_transferInvestor(address,uint256)","b54a7987":"LogGetDeposit(address,uint256,string)","b54b1187":"setdteamVaultAddr4(address)","b54b4fb9":"getPriceOf(uint256)","b54beedc":"getCCH_edit_10()","b54c71eb":"weightedVoteCountsOf(uint256)","b54ca7b4":"setIncreaseK(uint256)","b54cd451":"updateFlightStatus(bytes32,uint256)","b54d6238":"releaseToken(uint256)","b54e7a4a":"sanitize(string)","b54eb822":"redistributionTimeout()","b54ef544":"buyStakeWithStarCoin(uint256,address)","b54f24a9":"getMappingID(string,address,address)","b55027a9":"maxMinutesFundingPeriod()","b550e634":"getTotalInvestmentsStored()","b551c373":"getTotalReputationSupply(bytes32)","b5522e89":"addContract(address,uint256)","b5531651":"Startable()","b553b715":"rewardDistributedUnits()","b55459d1":"User_5()","b5545a3c":"claimRefund()","b554f8eb":"withdrawAllWei(address)","b5554e73":"getPlayerJackpot(address,uint256)","b5558562":"tokenWithdraw(address)","b556188e":"finaliseTime()","b5563dcf":"BillOfSale()","b5565aac":"endPromotion(uint256)","b556861a":"add_tokens(address,uint256)","b556a895":"incFreezeHybridizationsCount(uint256)","b556ff26":"NewBid(bytes32,address,uint256)","b557478a":"refundClaimed(address)","b557a11d":"getReplyCount(bytes32)","b557c9a4":"slaveWalletInitialized()","b5581663":"airDropMultipleAmount(address[],uint256[])","b55845e7":"totalExchange()","b55867ea":"_goldUnFreeze(uint256)","b558a50c":"LongevityCrowdsale(address,uint256)","b558d1ea":"updateRate(address,uint256)","b558f334":"isRedemptionPermitted(address,uint256,uint256)","b559490d":"payVisa(uint256,uint256)","b559b0fe":"withdrawFromRemainingTokens(uint256)","b55a7d45":"multiplierPercent()","b55ad27e":"getBlipTokenAddress()","b55b089b":"bigTokensPerEther()","b55cdbf9":"setExtraBalance(address,uint256)","b55cff2d":"test_twoValidEqBytes()","b55da874":"create_private_room()","b55e31f4":"assertOrders(address,bytes32)","b55fc3d6":"UnregisterList(address[],bool)","b560b6da":"enableDistrict0xNetworkTokenTransfers()","b560c4de":"adminPayout()","b560d589":"getUserInvestBalance(address)","b561d5b3":"OrguraExchange()","b5622abc":"EuroGoldTest(uint256)","b563b75d":"getAdminRevenue()","b564561e":"register(bytes32[])","b56494c0":"validateBoard(uint256[81])","b56537ef":"isEASigned(uint32)","b566d0b4":"getContributorRemainingPresaleAmount(address)","b5674c68":"TokenGNO(uint256)","b5675ee4":"bookkeeping(uint8,uint8,uint256)","b56797fd":"getSaleHourNow()","b567a1e7":"ShopClosed(uint32)","b568e689":"getCrowdsaleWhitelist(address,bytes32)","b5692a67":"removeExemptionAddress(address)","b569a35f":"YSSYBToken(uint256,string,string)","b56a9f2c":"heartBeat()","b56aef62":"sampleTypes(uint32)","b56b2627":"add_owner(uint256,address)","b56b366b":"maliceReportedForBlock(address,uint256)","b56b5918":"TicketRefund(uint256,address,uint256)","b56b64d9":"disputing()","b56ccd93":"arr(address,address,address)","b56d3ccc":"select(bytes32,bytes32,bool)","b56d4717":"lockOwner(address)","b56e1bca":"setExchangeToken()","b56e2d76":"testRewardSS(string)","b56ea5cc":"specialApprove(uint256,bytes32,bytes)","b56ebf42":"GetNow()","b571324d":"ShareErc20(string,string,uint256)","b57228fd":"ChangeEmissionGrowthCoefficient(uint256)","b5725445":"setOptionalFeeSplit(address,uint256)","b5738a78":"SatoMotive()","b573a104":"secondStageTokenRate()","b5740cc2":"preSaleVault()","b5744134":"setLaunchDate(uint256)","b5754045":"disown(string,address)","b57566d8":"setvalue(string,string)","b5776339":"transferGDPOracle(address)","b5784f6f":"testMultiplePackages()","b57874ce":"addressToPass(address[],bool)","b578e764":"ACNN()","b579184f":"addContributor(address)","b57934e4":"haltCrowdSale()","b5794222":"destroyAndSendToStorageOwner()","b57980ce":"prepareContribution(uint256,uint256,uint256)","b579b6c5":"distributeToken(uint256,uint256,bool)","b579d7de":"RewardEnd()","b57adee3":"setBanker(address,uint256,uint256)","b57c5814":"getDonatorsNumber()","b57d5d27":"assertBalance()","b57dbdc6":"safeguard()","b57e55ec":"seeAllPlayers()","b57e6ea1":"tokenGenerationMax()","b57ff495":"triggerPauseEvent()","b5802ae6":"getCirculationCap(address)","b5809c9b":"COPPER_AMOUNT_TPT()","b580a7a1":"totalBalanceClaimed()","b580d205":"ChangeRate(uint256,uint256,uint256,uint256)","b58166f2":"lastRoot()","b581b725":"transferToken(bytes8,address,uint256)","b582ec5f":"j()","b58489ac":"isAuction(string)","b5848db4":"validateStartMegabox(address,uint256)","b585245b":"_callSender(address,address,address,uint256,bytes,bytes)","b58617d9":"CCRCrowdsale()","b58637e8":"approveToSell(uint256)","b5863ed7":"addContribution(address,uint256,uint256,uint256,uint256)","b58696ba":"test_ShouldPassButNoBondSoFail()","b587194e":"TokenMigration(address,uint256)","b587dc57":"openICO()","b587e3c7":"getRank04()","b5881422":"unsafeIsEth(uint16)","b588bfad":"writeMessage(string)","b588fdc1":"takeTokenContractOwnership()","b58aa6be":"checkWithdrawalAmount()","b58b9d5c":"getSaveData(address,address)","b58baa0d":"displayString()","b58c2d31":"addAddressManual(address)","b58d0651":"checkAllowedAddressFoTransfer(address,address)","b58d4885":"addNewTrait(string,bool)","b58de1d5":"JSONpath_int(string,string,uint256)","b58dff99":"gntContractAddress()","b58e5216":"allowBlocking(address,address)","b58e60db":"theWord()","b58ee9a3":"companyRemainingAllocation()","b58f4a24":"LOTTERY_FUND_ADDRESS()","b58fa125":"commit_end_time()","b58fc3e7":"distributeIncomeEther()","b5917478":"TYPE_FREIGHTER()","b5919b48":"toBuyBack()","b591fc69":"totalEtherContributed()","b5922a2b":"INITIAL_AIRDROP()","b592500e":"RICEBALLZ()","b59284ac":"unlinkAddress(address)","b592bb99":"SSDToken()","b592de3a":"sell(bytes32,uint256)","b5930872":"test_testablestandardcampaignDeploymentAndUse()","b5931f7c":"safeDiv(uint256,uint256)","b5932ee2":"DistrictsCore()","b5936da2":"seedEnded()","b594f086":"changeDuration(uint256)","b5950529":"CTSCToken()","b595181f":"ShapeshiftBot()","b595357b":"getLLV_edit_29()","b5957288":"getMatchBettingDetails(uint8)","b59589d1":"relay()","b595b8b5":"betOnColor(uint256)","b5962159":"moveMinions(uint8,uint8,uint32)","b5967e16":"updatePlayersGoo(address)","b59712af":"totalSupplyOfType(uint256)","b59724e8":"NewFunding(address,address,uint256,uint256,uint256,address)","b597842a":"TimeNow()","b597e784":"setTokenPriceInWei(uint256)","b5980f7d":"unverifyAddress(address)","b598afcb":"oraclize_query(string,bytes[5])","b598d3e8":"getMessages(address,uint256)","b598f882":"updateTokenRates(uint256)","b5999c12":"getPoohsSinceLastHatch(address)","b599aaec":"TheBitcoinCenterToken()","b599afc8":"totalBetCount()","b59a1598":"distributeGLAU(address[],uint256,uint256)","b59a1d37":"buy1(uint256)","b59a60db":"minContribute()","b59b0fc4":"modifyTokenPrice(uint256,uint256)","b59b44f5":"usePlayerFiboken()","b59b6acb":"GetDynamicCardAmountList(address)","b59bb5e3":"testcall(address)","b59bc382":"setReportingFeeDivisor(uint256)","b59ca0f6":"registerDINsWithResolver(address,address,uint256)","b59d689f":"grantStock(address,uint256,uint256)","b59d7fe6":"EtherbotsBase()","b59dd856":"GetCardInfo(uint8)","b59f16d1":"Set(bytes32,address,address)","b59ffdd3":"getFreeAnthill()","b5a01992":"setDDF(address)","b5a02db1":"totalHouseWinnings()","b5a030d8":"link(bytes32[],bytes32[],address[],uint8[],bytes32[],bytes32[])","b5a04829":"setLargeCapWhitelistParticipants(address[],uint256)","b5a0596e":"declareCheaters(address[])","b5a127e5":"minQuorum()","b5a1a64b":"lockedRewardsOf(address,address)","b5a27a21":"leave_square(uint256)","b5a29d11":"purchaseCRS(uint256)","b5a312c6":"mintlvlToken(address,uint256)","b5a46d5e":"whoOwner()","b5a4a146":"generateRnd(bytes,uint256,uint256)","b5a4e04a":"canFinalizeEarly()","b5a54627":"setPrimaryGameManager(address)","b5a5b8f5":"setPreSaleContract(address)","b5a60045":"setJob(uint256,string,string,uint256[],uint256,uint256,uint8[],uint8,bool,address[])","b5a678d7":"YouRyuCoin(uint256,string,string,uint8)","b5a6c525":"extractFrozenAccountLength()","b5a7900e":"nextroundsoldierreplenishrate()","b5a89065":"getUserData(address,string)","b5a8fa80":"VRChainToken(string,string,uint8,uint256)","b5a90793":"Sender(uint256,address[])","b5a9823f":"tier3Time()","b5a9de6e":"minEtherParticipate()","b5aab008":"WobToken()","b5aae6fc":"_setCurrentSecret(uint256)","b5aae91a":"handle_dividend(address,address)","b5ab05a5":"tokensHardCap()","b5ab58dc":"getAnswer(uint256)","b5ac7894":"partnerInfo_for_Partner(bytes32,uint8,bytes32,bytes32)","b5ac7c27":"payForOrder(uint256,address,uint256)","b5add717":"claim(uint256,uint256,uint256,uint256)","b5ade81b":"_BLOCKS_PER_READJUSTMENT()","b5ae4519":"endorsements()","b5ae64b2":"piStartTime()","b5aebc80":"donate(string)","b5aece02":"silverBoxAmountForSale()","b5af411f":"NXETToken()","b5afb120":"updateSkill(uint256,uint256,uint256,uint256)","b5afd61b":"maxForceOffsetAmount()","b5b12e75":"isApprovedFor(uint256,address)","b5b13462":"getUserTotalSales(address)","b5b1fc05":"getAdminFromMintedCappedProxy(address)","b5b26505":"DURATION_SALESTAGES()","b5b33eda":"scheduleCall(address,uint256)","b5b3fc07":"GlowToken()","b5b4d0d6":"COLLATERAL_HELD()","b5b52096":"fixedFeeInCWC()","b5b5a057":"changeMinimumDonation(uint256)","b5b64d24":"GetExistsChipList()","b5b73c63":"getUserSignedDocuments()","b5b77d7f":"executeSettingsChange(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","b5b7916b":"getMembershipType(address)","b5b7d767":"vpe_per_eos()","b5b86a51":"getReferralBalance(address)","b5b879c2":"mAlek()","b5b90a26":"addHash(bytes32[])","b5ba7074":"isBelow(uint256,uint256,string)","b5ba95a0":"ElectronicMusic()","b5ba9a7e":"getReferralPackageKind(bytes)","b5bab68e":"minLimitPublicSecondSale()","b5bb0ade":"agreementExists(bytes32)","b5bb5ee4":"withdrawMintTokens(address,uint256)","b5bd3eb9":"totalCredits()","b5bf15e5":"freeze(bool)","b5bf4c74":"RandomWinner()","b5bf6eb6":"incrementPrice()","b5bfdd73":"addDSource(string,bytes1,uint256)","b5c05570":"toggleLockIn()","b5c07eab":"metaBaseUrl()","b5c0c884":"refundLosersBids(uint256)","b5c12c09":"cancelRequest(uint32,string)","b5c12f4d":"setWhitelistRequired(bool)","b5c14adb":"setGamePaused(bool)","b5c150d4":"availableAmount(uint256)","b5c1662f":"addWei(address,address,uint256)","b5c18ea8":"rejectClearingPriceSubmission(address,address,bytes32,uint256)","b5c19d59":"betLastTime()","b5c1ac14":"toBE()","b5c2b889":"XTVBurned()","b5c2c600":"Gave(address)","b5c3a111":"depositCell(address,uint256)","b5c4147f":"getZoneShop(bytes2,bytes16)","b5c47f69":"megaRate()","b5c56797":"AIMToken()","b5c5a635":"incrementProgressOfAddressAndId(address,address,uint32)","b5c5f672":"withdraw(address,uint256,uint256)","b5c61e90":"TokenMigration(address)","b5c645bd":"record(bytes32)","b5c6b5a2":"FishFarmer()","b5c6e7d6":"getCountsByName(bytes32)","b5c73816":"ASSC()","b5c7a4e4":"validateReleasedToken(uint256)","b5c7b1fe":"claimTokenTokens(address)","b5c83592":"offerExists(uint256)","b5c8b021":"testMintableToken()","b5c8f317":"SimpleERC20Token()","b5c90917":"GetAllReferralAddresses()","b5c9cbbe":"setBalance(address,address,uint256)","b5c9fa0a":"setBountyRewardPercent(uint256)","b5caadf2":"setParams(address,address,address,uint256,uint256)","b5cab1ce":"tokenMetadataBaseURI()","b5cadc91":"convertForMultiple(address[],uint256[],uint256[],uint256[],address)","b5caf461":"removeAllApprove()","b5cb0611":"setCrowdsaleState()","b5cb15f7":"getUserCount()","b5cb6a17":"capDay3()","b5cc7e29":"unfreezeTokenTransfer(bool)","b5cc84f5":"getVatomOwner(string)","b5cc916c":"CITY_PRICE()","b5cd1821":"lastBlock_a0Hash_uint256()","b5ce3600":"thirdStageDuration()","b5cf852d":"triggerHiddenCap()","b5d011fd":"updateCalculator(address)","b5d02a56":"nextRand(uint256)","b5d03751":"YoutubeViews()","b5d0c747":"setApiCallsContractAddress(address)","b5d0f16e":"getGasScalar(uint256,uint256)","b5d11d39":"validatePurchase(uint256)","b5d11e99":"testInit()","b5d1220a":"hasPreviouslyEnteredCardIds(uint256[])","b5d125f1":"isApprenticeChest(uint256)","b5d1548c":"CCH_RE_1()","b5d1990d":"numRecords()","b5d1aedc":"COLOR_YELLOW()","b5d29f21":"authorizationPayment()","b5d347ed":"CryptoCityToken()","b5d34966":"unlockCapital(address,uint256)","b5d3a379":"CanaryTestnet()","b5d3a9c6":"groomSignedAt()","b5d446ab":"mokenEra(uint256)","b5d561bb":"migrateManual(address,bool)","b5d65f61":"partialRedeem(uint256,bytes32)","b5d6cbfe":"FSHN()","b5d76067":"Alter_TrustlessTransaction(uint256,bool)","b5d7df97":"Sign()","b5d7eca5":"token_was_created()","b5d8514b":"Arthimetic()","b5d86c86":"ownerOfCountryCount(address)","b5d89627":"getValidator(uint256)","b5d9ac79":"toB32(bytes,uint256)","b5d9f80b":"serverEndGameConflict(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address,bytes,address,bytes32,bytes32)","b5da0114":"isNull()","b5da2df4":"markAsImported(address,address)","b5dadb17":"whitelistThreshold()","b5db26cd":"manualOverrideEditionBid(uint256,address,uint256)","b5dba35b":"onlyMinterMock()","b5dc40c3":"getConfirmations(uint256)","b5dc9399":"fetchPaidOrdersForPayerByAdmin(address)","b5dcbb69":"takeRegion(uint16)","b5dd20e9":"createIsland(bytes32,uint256,address,uint256,uint256)","b5de8d4c":"getModule(address)","b5dea68c":"_addNewEscrow(address,address,address,uint8)","b5debaf5":"exp(uint256,uint256,uint256)","b5debd95":"totalAmountOfEarlyPurchasesInCny()","b5deeca7":"BaseRegistry()","b5df3ef8":"WillWithdraw(uint256)","b5dfad16":"specialSkinOfTokenId(uint256)","b5dfd153":"withdraw(uint256,uint256,address,uint256)","b5e02e84":"Exorbuxcom()","b5e11819":"disableContract(bool)","b5e12715":"updateRankList(address)","b5e1fe13":"thirdTokenExchangeRate()","b5e221c1":"winnerBidder()","b5e292d3":"processHandEnd(bool)","b5e3504a":"HumanX1()","b5e35248":"stage2NotReached()","b5e36417":"transfer(uint256[])","b5e4d6ce":"addOrder(bool,uint32,uint128,uint128,uint32,int256)","b5e4ece1":"LOG_GasLimitChanged(uint256,uint256)","b5e54406":"amountOfItem()","b5e574e9":"SetGasSell(uint256)","b5e59318":"SLPC_ERC20Token()","b5e71687":"getTeam4name(string)","b5e73249":"mint(address,uint256,bool,uint32)","b5e8077c":"_unpackWarriorId(uint256,uint256)","b5e82975":"setMintDone()","b5e872e0":"TransferFeeRateExecuted(uint256,address,uint256)","b5e8cf02":"burnReward(uint256)","b5e91891":"changeStock(address)","b5e989c7":"ballotOptions(uint32,uint32)","b5ea510a":"YOBTC()","b5eacc01":"investor(address,uint256,uint256)","b5ec85f0":"getOldBalanceOf(address)","b5ed298a":"proposeOwner(address)","b5ee6f3d":"isVotingPhaseOver()","b5eeee6e":"cleanSeedUp(address)","b5ef06d0":"changeDeveloperETHDestinationAddress(address)","b5ef649d":"GetChipUsedNum(uint32)","b5f09a39":"lockupDate()","b5f0f41b":"allowedTransferTo(address)","b5f12736":"CustomToken(uint256,string,string,uint256)","b5f16939":"saleRevenue()","b5f16e48":"setShareholder(address,bool)","b5f187b9":"changeFundWallet1(address)","b5f2054b":"getWinningsBalance(address)","b5f228d7":"LiquidityNetworkToken()","b5f26055":"restrictedStockSendTimeOf(address)","b5f3484d":"PaymentStatusTimeStamp(address)","b5f3e71a":"addAddressToAdminlist(address)","b5f45edf":"marketPoohs()","b5f50ef3":"claim_prize()","b5f529cf":"orderNotAccepted()","b5f5962a":"CALL_GAS_CEILING(uint256)","b5f59a92":"LUV_Crowdsale()","b5f5d582":"TPortToken()","b5f6b1f6":"setBonusThreshold(uint256)","b5f72d88":"beginProjectRound(string,uint256,uint256)","b5f78d11":"purchase(bytes8)","b5f7f636":"totalTokenSold()","b5f918ff":"roundOneAmount()","b5f9371a":"writerAccountSupply()","b5f9b1c2":"Bonds(uint32)","b5f9ca19":"doesPaymentExist(address,address)","b5fa2044":"SetPatentProperties(uint256,uint256)","b5fa77bd":"SetAddress(string,address)","b5fb19ed":"addressEccles()","b5fbc49f":"isAreaEnabled(string)","b5fcfbcc":"_getProviderAdmin(uint256)","b5fd76bb":"AddLocation(string)","b5fdeb23":"getMsg()","b5fe79db":"getInfoLevels()","b5fea522":"putBtcWithStc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","b5fecc30":"stockSupply(uint256)","b5ffa082":"StorageUpdated(address)","b6010fcd":"getItem(string)","b6013cef":"finalize(uint256,uint256)","b6015204":"receiver2()","b601818b":"newOwner(string)","b601e850":"loanMatured(address)","b6027026":"AOK()","b602a917":"changeTransferStats(bool)","b6030d35":"nProposals(uint256)","b6033daf":"getMintingPowerByAddress(address)","b6034964":"_endContestIfNeeded(address,uint256)","b6037759":"setStudentNumber(uint256)","b603cd80":"killMe()","b604a86e":"ratePublicSaleStage()","b604ad72":"create(string,string,uint8,uint256,address)","b604ed1b":"withdrawByGid(uint256)","b6055167":"receiveExternalProfits()","b6062b5b":"ICO_TOKENS()","b607068c":"getMyDividendRate()","b60710c0":"LogWithdrew(address,uint256)","b60761c4":"Internet(string,string)","b607ea45":"claimTilesForNewUser(bytes32,bytes,bytes32,bytes32,uint16[],address)","b60868be":"getFishAtBase(uint256)","b608c938":"releaseNextShares(uint256)","b6096ce9":"EloTest()","b609d0e6":"lastOracleUpdate()","b60a7405":"_addOwner_(address)","b60a82e0":"addSponsorship(address,uint256,uint256)","b60ad98d":"Board(address,bytes32)","b60afaa4":"distributeLCWP(address[],uint256,uint256)","b60b3c59":"otcPurchaseAndEscrow(uint256,address)","b60b7084":"builtOn()","b60b9fcb":"joinGame(uint256,uint256)","b60b9ff7":"Shopdex()","b60cc68b":"MIN_ICO_SLOGN_COLLECTED()","b60cee3c":"countAllSmartSharingContract()","b60d4288":"fund()","b60e00b9":"disableBets()","b60e2333":"joinTeam(uint256,address,uint256,uint256)","b60e6bc0":"tokenIdToApprovedRecipient(uint256)","b60e72cc":"log(string,uint256)","b60eb800":"addressSCEscrow()","b60f54f4":"SortingCoins()","b60f5b91":"isPreICO()","b60ffa9c":"setDistributeAgent(address)","b61012a9":"preICOparticipated(address)","b610c75e":"incrementTimestamp(uint256)","b611d649":"GteChainERC20()","b61241ed":"allocateTokens(address,uint256,address)","b612ac29":"BONUS_15_DAYS()","b61334b1":"setPayoutsWallet(address)","b6136dca":"alt()","b61386fb":"registerHandle(string)","b6139992":"issue(address,address,uint256)","b613df16":"_finishBet(bool,address)","b614213d":"maxPriceInWeiFromUser()","b615243a":"getExtraTokens(address)","b6172704":"isConfirmedStakeholder(uint256)","b61727ed":"_transferTo(address,address,uint256)","b6176a33":"addStakeholderTransaction(address,bool)","b617a4fd":"getClientCategory()","b617cf42":"removeExchange(address,uint256)","b618214a":"enableService(address)","b618387a":"registerBuyer(string,string)","b618cbba":"EvLoginfo(string,string)","b618d9a4":"checkStatus(address,address,uint256)","b6195134":"changeAdminToo(address)","b61992e7":"setPricePerBlockInWei(uint256)","b61a98cb":"updateMarriageLicenceImageIPFShash(string)","b61c0503":"fireEventLog1()","b61cb058":"setAvatarFee(uint256)","b61cbcd3":"nextGenome()","b61d27f6":"execute(address,uint256,bytes)","b61d4511":"maxPreIcoTokens()","b61daaee":"tokenBase()","b61e96a5":"requester()","b61f16e3":"getEarningsPool()","b61f36f7":"calculateWdxFee(uint256,uint256,uint256)","b61fa7c0":"doAirdrop2(address,address[],uint256)","b6206e67":"unitBattlePLATCost(uint256)","b6213490":"initialDrop()","b6215091":"Test2Token()","b621bd15":"SALES_END()","b622ab4a":"buyWithFunction(bytes4)","b6230a74":"icoStatusUpdated(address,string)","b623f5e5":"checkSetCosignerAddress(address)","b62418a1":"decrementOpenInterest(uint256)","b624fc54":"rafEnd()","b6253539":"needsInitialization()","b62596a2":"fundStorageVaultAddr()","b625dd87":"getUpdateTAOContentStateSignatureAddress(address,bytes32,address,bytes32,uint8,bytes32,bytes32)","b6261d0a":"acceptOffer(address)","b6266248":"refunded(uint32)","b626913f":"buy_block()","b627cf3b":"welcome()","b627ff04":"Sheep(string,string)","b6282d0d":"angelOnBattleboards(uint64)","b628672b":"setPreSaleHalt(bool)","b6288553":"decim()","b6294bde":"AdminGetFee()","b629d741":"transferUnownedPlanet(address,uint256)","b62c0b41":"MintByBTC(uint8,address,uint256)","b62c208f":"CryptoQuantumTradingFund()","b62c3a4f":"FinastraToken()","b62d4301":"testingSelfDestruct()","b62d4ce1":"canLayEgg(uint64,uint32,uint32)","b62eac16":"CrowdsaleProxy(address)","b62f0a6b":"YouTubemasterReq()","b62fc7c0":"buy2(address[],address[],uint256[],bytes,bytes)","b63005ec":"withdrawJuror()","b630230a":"MIN_CROWSALE_TIME()","b6304c2a":"KOINCONEKT()","b6307f0e":"nLuckyVoters()","b630aa48":"tokensSentPresale()","b630d706":"thisisfine(uint256)","b631c8e8":"_generateCastleSale(uint256,uint256,uint256,uint256)","b632d2e0":"SingularityTest20()","b633620c":"getTimestamp(uint256)","b6339418":"storeNumber(uint256)","b633b2ab":"getNextRoundTimestamp()","b633d272":"emitWorkResumed(uint256,uint256)","b633e4cd":"claimBalance(address)","b63423a3":"testCheckoutCart()","b63426b3":"Oxygen()","b634fc77":"FathomToken(address,address,uint256,address)","b6356251":"callThisContractBalance()","b63569c3":"developer_address_for_C(address)","b635a52d":"disconnectOrderPrice(address,address,uint256)","b635ba5f":"getEthValueAmount()","b6363cf2":"isOperator(address,address)","b63688d3":"setValidationOpen(uint256)","b637b269":"maximumValueDuringGuaranteedPeriod()","b637b7c4":"BZToken(uint256,string,string)","b638f72a":"_preICOSale(address,uint256)","b6397a42":"lotteryGiveHunt()","b639c9ec":"burnWarrior(uint256,address)","b63a35bf":"CTX_Cap()","b63a61d3":"auther_user()","b63adb3a":"preico(uint256,address,uint256,uint256)","b63bb5c6":"SNToken(uint256,string,string)","b63c2ac4":"setPowerContract(address)","b63c57f1":"buyForBitcoin(address,uint256)","b63ca981":"setHKGPrice(uint256)","b63cf3ca":"BitcoinDiamond()","b63deb24":"setSendProfitsReward(uint256)","b63df2a0":"approveControllerContractMigration()","b63e0cd8":"start(uint32)","b63e93dc":"ownerClawback()","b63ed405":"getWeiBalance()","b63f0d20":"newcheckToken()","b642c768":"_distributeTeamToken(uint256)","b642d58f":"INIT_DATE()","b6435f00":"getUsersAwaitingForTokensTop150(bool)","b6438092":"ManifestoCount()","b643f2c9":"stopDefrost()","b644ee41":"PRESALE_END_DATE()","b6469620":"getPersiansBattlePoints()","b64698cb":"_resolveAquarium(uint256)","b646c194":"addApprover(address)","b647990a":"countVotes()","b6481a92":"GotingToken()","b6496c6a":"addressLUTSize()","b64a097e":"info(bytes32)","b64afbe5":"participate(address,uint256)","b64b09d5":"invokeFallback(address)","b64bbd9e":"Finalizable()","b64c154a":"Klassicoin()","b64c1e7e":"claimForDeposit(address,address)","b64c4905":"sellVolumesCurrent(address,address)","b64c9326":"projectoperation_beneficiary()","b64d44f1":"TeamLockingPeriod12Months()","b64dc853":"onCompensated(address,uint256)","b64e2fc4":"getIncludes(uint256)","b64e8ad8":"addAllocationPartTwo(uint256)","b64eecb1":"transactionRequestCore()","b64f3cac":"getDSPRegistry()","b64ff429":"consent(bytes32[])","b64ff868":"getAdvertisers(bytes32,uint256)","b650048b":"unpausePlayerContracts(uint256,uint256)","b6506f25":"setLLV_edit_20(string)","b6508067":"lastTotalSupply()","b6509c12":"Ethereum_twelve_bagger()","b650bbef":"safetyInvariantCheck(uint256)","b65177ee":"ERC827Receiver()","b651cbaf":"add_level(address,bytes)","b652c822":"transferPosition(bytes32,address)","b652dc2f":"SOFT_CAP()","b65412b5":"refundPayment()","b65418f5":"raisedIcoValue()","b6549f75":"revoke()","b654bdb0":"HIBA()","b655d0c4":"getBaseRate()","b655e138":"sliceAddress(bytes,uint256)","b655f822":"Ballot()","b655fda2":"updateUserFullName(address,bytes32)","b656850a":"_getStakingEpoch()","b656e9f4":"isInTestMode()","b6576bdf":"getValue(bytes)","b657ae63":"eSendTokens(address,uint256)","b657c996":"control(address)","b6581516":"crossForkDistribution()","b6588ffd":"del()","b65a1350":"rateLastWeek()","b65a34f5":"CeffylToken()","b65ae769":"WithdrawSpecialToken(address,uint256)","b65b3f80":"exchangeAndSpend(address,uint256,address)","b65b4c9a":"sponsoredBonusMax()","b65b99a3":"_verifyDate(string,uint256)","b65bce8b":"ContractDisabledEvent(uint256)","b65be60d":"_updateLots(uint256)","b65c2611":"setUnfreezeTimestamp(uint256)","b65c2b40":"incrementLastTokenId()","b65c3a7f":"calcAmountAt(uint256,uint256,uint256)","b65cb801":"SnailToken(uint256,string,uint8,string)","b65d0807":"Carpio()","b65dc843":"crowdsaleMintingCap()","b65ddf2b":"addTipForDeveloper(uint256)","b65e1ab8":"setGoldmintFeeAccount(string)","b65f3bb5":"executeOffset(address,uint256,address,uint256)","b65f90e3":"split(uint8,bytes6,uint8)","b65ff419":"deleteNick()","b6607cc5":"AML_THRESHOLD()","b6608467":"updateShares(uint256)","b660d77c":"switchMPO(address,address)","b6615acc":"_isAllowed(address,uint256)","b661f55d":"saleTokensHaveBeenMinted()","b6622c0f":"updateDonor(address)","b6629d98":"placeBetEth(bytes)","b6629e20":"purchaseWithEth(uint256)","b662a73c":"freezeUpgrade()","b662dc9b":"OWNER_SUPPLY()","b662ef9c":"InsuranceMasterContract()","b6635be6":"setupComplete()","b663dc0a":"ONE_QUINTILLION()","b6644080":"ADMIN_GET_USD(uint256)","b66578dc":"nextSeedHashB()","b6660af4":"schelling(address,address,bool)","b667486d":"BetClosedNoWinningTeam(address,uint256)","b6674935":"minPot()","b66846fc":"offerToSell(uint256,uint256)","b668efe7":"PI_EDIT_2()","b6693f80":"phase_2_remaining_tokens()","b66a0e5d":"startSale()","b66a261c":"setSpread(uint256)","b66a323c":"claimThrone(string)","b66a94ef":"erc20ECHT(uint8)","b66aae65":"removeHoldByAddress(address)","b66afea3":"getOrCreateFeeWindowByTimestamp(uint256)","b66ce7cc":"Ignite()","b66d887a":"setSTGContractAddress(address)","b66dbdc5":"totalSupplyHistoryLength()","b66dd4b2":"lockFromSelf(uint256,string)","b66deb80":"removeEntry(address)","b66e68f2":"testFirst(bytes)","b66e7524":"getReportingStartTime()","b66f7a8b":"isEnded(uint256)","b6700930":"removeSet(bytes32)","b670a4b1":"unsoldTokens()","b670a910":"frontWindow()","b6712a4f":"gatFoundDeposit()","b6721bc4":"setMinPaymentForAnswer(uint256)","b6725bcf":"bitswift()","b672b4d4":"testTransferToken()","b672cf50":"balanceOf(uint128)","b6738bfb":"presalePiStart()","b673a75c":"crowdsaleAddr()","b673ddb7":"hasAirDropHero(uint16,address)","b674e749":"mock_contains(address,address)","b675271e":"contributeForDcorpMember(address)","b6755038":"_setPotValue(uint256,uint256)","b6757b50":"RocketPoolToken()","b67590aa":"batchTrade(address[11][],uint256[11][],uint8[2][],bytes32[2][],bytes32[2][])","b6761717":"pullEtherFromContract()","b67719fc":"WithdrawFunds(address,uint256,address)","b6791322":"createERC20(uint256,string,uint8,string)","b6791ad4":"getChain(uint256)","b67a77dd":"ART1(address)","b67aa257":"purchasePop(uint256)","b67b1a4d":"withdrawEtherOnlyOwner()","b67b60c7":"nextPrime(uint256)","b67b7163":"approve(string)","b67ba1b5":"killWallet()","b67c2893":"VitalLogging()","b67c838f":"Total_Paid_Out()","b67cb359":"feed1(uint256)","b67d4111":"getItemUri(uint256)","b67d50b5":"referrerBalanceOf(bytes32)","b67d77c5":"sub(uint256,uint256)","b67d8c69":"order_counter()","b67ddf20":"BlockICOdatetime()","b67e2064":"injectEtherFromIco()","b67e5b3b":"validPurchaseBonus(uint256)","b67f4eff":"sendTo(address,uint256,uint256)","b67f8b6d":"Master()","b67fabdf":"scheduleTransaction(address,uint256,uint256,bytes)","b68035a7":"COMMISSION_DIVIDER()","b6813b1c":"setcoe(uint256,uint256)","b6816590":"previousFounders(uint256)","b681f9f6":"resumeContribution()","b6823a66":"tournamentRewards()","b682c019":"pieceWanted()","b682da3e":"feesData()","b682ea1b":"_figthEnemy(address)","b6834572":"EOS()","b684101d":"emitExecuted(address,uint256,uint256,uint256)","b684ccad":"getDisputesToSolve()","b6854f96":"freezeToken(uint256)","b6868a69":"theFunction()","b686a635":"PossContract()","b686c983":"cancelLoanRequestAtIndexByBorrower(uint256)","b686d8b4":"holdingTaxInterval()","b686e44c":"SHA256ofArtwork()","b688524f":"_isCeo(address)","b688578c":"STAGE_3_START()","b6889e48":"globalChanceNo()","b688a363":"join()","b6893f7d":"DataContacts(address,address,address,address,address)","b6898845":"RPESALE_TOKEN_SUPPLY_LIMIT()","b689ca61":"sellsIntermediateGoodWithDepletion(address,uint256,string,uint256)","b689d5ac":"has()","b689d850":"FederatedOracleBytes8(uint8,uint8)","b68a06ba":"transfer_with_extra_gas(address,uint256)","b68c6ae3":"mtcLastDay()","b68cc035":"bonusLimit(uint256)","b68cf49f":"roundResolved()","b68d1809":"getDomain()","b68d1d4d":"addressInArray(address)","b68e15d6":"freezedAccounts(address)","b68e21ac":"FinishLottery()","b68e7f6e":"testCastVote()","b68e8552":"setRegionOwner(uint16,address,uint256)","b68e8760":"setBn(bytes32,bytes32,string)","b68ed11f":"preSaleSoldTokens()","b69065d6":"DevelopeoERC20(uint256,string,uint8,string,bool,bool)","b69147f2":"monthlyMinting()","b6926b52":"RaffleDraw()","b692c89d":"getRaised()","b6932ce7":"solicitaPagamento()","b694dbb5":"fromBytesToBytes32(bytes)","b695ecfd":"HonestHeart()","b696a6ad":"issue(uint256,address)","b6972146":"mul(int128,int128)","b6974d87":"cancelVoteForCashBack()","b6975ddb":"becomeSnakemaster()","b697fc93":"POT_DRAIN_TIME()","b6982c7f":"setup_race(uint256,uint256)","b6984002":"EQU(uint256,string,string)","b6992247":"getStakeholders()","b69924c3":"GetNextWithFunds(uint256,uint256)","b6994dc0":"RomanLanskoj()","b69a375d":"callback(uint256,string)","b69a8107":"setSkcAdderss(address)","b69b5611":"setOwnership(uint256,address,address)","b69ba46d":"publishMetaData(bytes32,bytes32,bytes1)","b69c0896":"BaseScheduler(address,address,uint256)","b69c2115":"approveRequest(bytes32,uint256)","b69e7d70":"random(uint256,uint256,address,uint256)","b69e9b1d":"getStaticElementAt(uint256)","b69ea1e9":"WineSpiritCoin()","b69ec629":"setBpToken(address)","b69ee531":"GBNC(string,string,uint256,uint8)","b69ef8a8":"balance()","b69f5ada":"totalUserProfit()","b69f917d":"addCosToGame(uint256,uint256,string)","b69fae22":"hashTransfer(address,address,bytes,uint256)","b6a0a119":"countDestinations()","b6a12f63":"setTokenMarketMaker(address,address,address,address)","b6a2b110":"SOCXSentToETH()","b6a324e0":"fundMe()","b6a46b3b":"create(string)","b6a48c2a":"abcLottoController()","b6a499ab":"_computePVPWarriorAura(uint256,uint256)","b6a4a0e9":"GogaTokens()","b6a5091a":"HuanHuiToken()","b6a59176":"getUsedCoreSupply()","b6a5d7de":"authorize(address)","b6a65665":"getGameData(uint256)","b6a79409":"necropolisContract()","b6a7b42c":"getMyTomatoes()","b6a8933b":"EXCHANGE_COMMISSION()","b6a96e45":"BuyCarCompleted(address,uint256)","b6a9ed31":"sellAnts()","b6abd4e7":"transfer_close()","b6ac24df":"updatePatchTree(bytes32)","b6ac4984":"tokenTransfersEnabled()","b6ac642a":"setWithdrawFee(uint256)","b6acabc1":"crowdFunding()","b6acc48c":"ICO_TOKEN_CAP()","b6acd931":"payDAPP(address,uint256,address)","b6ad4784":"resignTranscoder(address)","b6ad57d6":"paySmartContract(bytes32,address[],uint256[],bytes32)","b6add0f4":"initPrice()","b6ade100":"notifylvlClients(string,string)","b6ae90fb":"FuturOwner()","b6aeb4a2":"erc20VARA(uint8)","b6aeec7b":"CHATTER()","b6af3643":"setWithdrawalTime(uint256)","b6afd2ca":"listMembers()","b6b0eaca":"SMILEHEART()","b6b0f77b":"idToString(bytes32)","b6b18eff":"founderWithdrawablePhase1()","b6b1e359":"verifyIt(bool)","b6b2210c":"lockSell(bool)","b6b32c07":"presalePurchase(address[],address)","b6b35272":"isWhitelisted(address,address)","b6b3d325":"view40()","b6b425c7":"doSingleMigration(uint256)","b6b55f25":"deposit(uint256)","b6b57c9e":"setWhiteListContractAddress(address)","b6b57ebd":"finalizeWorkOrder(address,string,string,string)","b6b7032e":"rentalAccumulatedPrice()","b6b7e7eb":"toRLPItem(bytes)","b6b7e84d":"SGTExchangerMock(address,address,address)","b6b8c3cd":"m_categoriesCreator()","b6b9d57e":"propertyIndexToData(uint256)","b6ba1a98":"NIMFA_PER_ETH_SALE()","b6ba600a":"lockGNO(uint256)","b6baffe3":"getDifficulty()","b6bb38dc":"approveCetification(address)","b6bb3ade":"multiCall(address[],address,uint256[])","b6bba846":"sellTokensForDash(string,address,uint256,uint256)","b6bbafa2":"CrowdsaleStoneToken()","b6bbcf5b":"benchmarkRandom()","b6bcf354":"getCensuring(uint16)","b6bd387a":"lastRegionId()","b6bdedca":"MagnaChain()","b6be128a":"getPhoto(uint256)","b6beb400":"NuggetsToken()","b6bf1b3a":"mintForDisputeCrowdsourcer(uint256)","b6bf3bb3":"setBlackListERC20(address)","b6bf7318":"clz64(uint64)","b6c05255":"burnOwner(address,uint256)","b6c054ce":"restake(int256)","b6c0eca8":"LogRefund(address,uint256)","b6c1cb03":"transferFromWithComment(address,address,uint256,string)","b6c1eaad":"refundStarted()","b6c238b5":"starts(address)","b6c279ee":"setInputSize(uint256,uint256)","b6c32d71":"startStandardSale()","b6c37e58":"balancesRiskcoins(address)","b6c3987d":"validateHarCap(uint256)","b6c3e8cc":"increaseApprovalInternal(address,uint256)","b6c44bd1":"ZCash()","b6c47da1":"setSuperman(address)","b6c4da52":"addVestingRule(address,address,uint256,uint256)","b6c58236":"getOwner(uint32,int256)","b6c6ecd3":"getDial3Type(uint8)","b6c78f26":"HellaBank()","b6c88977":"finalizeCrowdfund()","b6c9f707":"ContractCreation(address,address)","b6ca878c":"addCard(bytes32,address,uint256,uint256,uint256,uint256)","b6ca8996":"CentrallyIssuedToken(address,string,string,uint256,uint256,uint256)","b6cb3777":"collectAnts(address)","b6cb405b":"getContractor()","b6cb5d72":"NFToken()","b6cb7f41":"fundsVault()","b6cba7eb":"recoverERC20Tokens(address,uint256)","b6ccc6ba":"signVer(address,bytes32,uint256,uint8,bytes32,bytes32)","b6cce5e2":"sponsor(uint256)","b6cd05e5":"withdrawAllTokensOnContract(uint256)","b6cd0b88":"setPersonalHash(bytes)","b6cdc815":"maixiaohetoken(uint256,string,uint8,string)","b6ce5581":"oraclize_query(string,string[5],uint256)","b6ceb489":"OWN_burn(uint256)","b6cf146c":"proposeMint(uint256)","b6cf3579":"PROVISIONING_supply()","b6d1d3d1":"setAirSender(address)","b6d1fbf9":"setXPERContractAddress(address)","b6d2a9b9":"SetupToken(string,string,uint256)","b6d31d97":"addToPrivateSaleWhitelist(address[])","b6d33511":"AKTestEther(address,address,address,uint256,uint256,uint256)","b6d34f12":"Emission(uint256,uint256,uint256)","b6d3faa3":"billingAmount()","b6d42ec3":"setApTime(uint256)","b6d5e8cd":"mintUniqueTokenTo(address,uint256)","b6d6164a":"reject(address,uint256,bytes,uint256)","b6d67a0b":"hasPlayerWon(uint8,uint256,bytes32,bytes32)","b6d6806c":"createEscrow(address,uint256,address)","b6d703ae":"confirmTotalTokenThreshold()","b6d7855a":"TokenName()","b6d7dbb2":"SAtomX()","b6d827bb":"WhitelisterChange(address,bool)","b6d8f59d":"WAN_TOTAL_SUPPLY()","b6d9721c":"getMerkleRootAndUnlockedAmount(bytes)","b6d9ef60":"setOracleFee(uint256)","b6dadbdf":"_createPart(uint8[4],address)","b6dadeb4":"getCardInsurance(uint256)","b6daea6c":"addAgency(address)","b6db75a0":"isAdmin()","b6dc1124":"private_setPauseState(bool)","b6dc572f":"addSubscription(address,bytes32,uint256)","b6dc8e25":"exchangedAmountToReceive(uint256)","b6ddcd14":"icoAccount()","b6ded5c1":"windowPeriodEnd()","b6df4906":"safeOwnerOf(uint256)","b6e087d6":"GunChain()","b6e119ab":"balanceOfEnvelopes()","b6e390ae":"First_pay_bountymanager()","b6e3943a":"AK4EtherDelta(address,address,address,uint256,uint256,uint256)","b6e3ca3c":"UpdatedExchangeRate(uint256)","b6e3cc1a":"authorCount()","b6e456bb":"getUInt()","b6e49fd9":"LocalEthereumEscrows()","b6e54bdf":"majority()","b6e76873":"getAction(uint256)","b6e7d90b":"delegatePass(bytes32,address)","b6e86e13":"createProxyImpl(address,bytes)","b6e8bac7":"anailNathrachOrthaBhaisIsBeathaDoChealDeanaimh(address[],uint256[])","b6e99235":"drawNumbers(uint256)","b6e9c2ac":"getUserBalance(bytes32)","b6ea62de":"kycApprove(address)","b6eb15c7":"gvOptionToken10()","b6eb7dae":"freedWosPoolToWosSystem()","b6ecd81c":"Vets()","b6ed0632":"cancelOrder(uint256,uint256)","b6ed3308":"setPriceOfEther(uint256,string)","b6ed9f15":"PFOffer(address,address,bytes,uint256,uint256,uint128)","b6eda884":"ads()","b6edc68f":"changeMicroPay(address)","b6edd743":"transferTokensTo(address)","b6ee48aa":"setContractSK(string,string)","b6ee8120":"realizedETH(address)","b6eeb6bb":"PREPURCHASER()","b6ef4454":"funderWithdraw()","b6ef78c2":"cancelCounterStack(bytes32,bytes32)","b6f020b2":"checkExistsItems(string)","b6f0391b":"setMap(string,string)","b6f085c7":"usernames(bytes20)","b6f0ecb1":"setAMLWhitelisted(address,bool)","b6f1a927":"CPAWallet()","b6f250ea":"determineWeights()","b6f29d50":"awardSellers()","b6f35624":"boughtAmountOf(address)","b6f36dcf":"owner3()","b6f3c071":"CyCo()","b6f3d256":"lowestBid()","b6f46b61":"claimBeercoins()","b6f46d4c":"RFQ(string,uint256,string)","b6f478de":"lifeVestingStage()","b6f4df34":"totalSupplyEdition(uint256)","b6f4f96c":"fundingThreshold()","b6f50c29":"setICO(address)","b6f529d6":"paused_2()","b6f5e0e6":"showProfileDetails()","b6f681ce":"ChangeOwner(address,address,uint256)","b6f687a2":"rewardKoth()","b6f6e8ae":"getMatches(uint256,bytes3)","b6f73bb9":"devuelveRoles(bytes32)","b6f7600d":"GetAllConsentData()","b6f7bfcd":"ADVISORS_ADDR()","b6f84764":"getRemainingUint(uint8,bytes)","b6f921ad":"check(string)","b6f98e53":"needsAllowancePayment()","b6f9fda5":"timeoutResolve(bytes32,uint256)","b6fac235":"callStcWithBtc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","b6fae6c7":"approveContract(bytes32)","b6fb4a14":"createNewSystem(string,uint8,uint8)","b6fb7e46":"endingBalance()","b6fb9f25":"redeemWithdrawalCertificate(string,uint256,address,bytes)","b6fc1043":"make(bool,uint8,uint256,uint256,bytes16,uint256,uint256)","b6fc276a":"preparationPeriodEquipmentTrainingFeeMultiplier()","b6fca0df":"sendAirDrops(address)","b6fda7ba":"allocateTokenForAdvisor()","b6fe87fb":"remoteBettingClose()","b6fef44c":"increaseArrivalTime(uint256,uint256)","b6ff5087":"notifyDeathCancellation()","b7009613":"canCall(address,address,bytes4)","b700967b":"modexp(uint256[],uint256,uint256[])","b7009c97":"StatPreICO()","b700f67a":"settleApproveRequest(bytes,bytes,bool,uint256)","b7019063":"EthereumDIDRegistry()","b7019744":"payBack(address,uint256)","b701dc14":"setBackEndAddress(address)","b7020c63":"getSpermlordReq()","b7028b1c":"CryptoRideCoin(uint256,string,uint8,string)","b702a879":"draw(uint256,address)","b703aa3a":"stopForge()","b703c75a":"getPresaleNumber()","b704b608":"weiToTokens(uint256,uint256)","b7056765":"implementsERC165InterfaceNoCache(address,bytes4)","b706b764":"HelpCoin()","b706f78e":"_mintTokens(int256,address,uint256)","b7073d2e":"insertCLNtoMarketMaker(address)","b7086f7b":"stopSale(address,uint256)","b70902bc":"debug4()","b7090bb5":"www_experty_io()","b70949c9":"editContributors(address[],uint256[],bool[],uint256[],uint256[])","b7098a32":"Bee()","b709df11":"getValue(address,address,address)","b70a7545":"GIFT(uint256,string,uint8,string)","b70ae49a":"execute_payment(uint256,bytes32)","b70b9717":"voitingStartTime()","b70c9acf":"stream(bytes32)","b70d0b3b":"ownerEdge()","b70d30bf":"returnTokens2(address,uint256)","b70dfb25":"SeleniumRichChain(uint256,string,uint8,string)","b70f0058":"_isApprovedBattle()","b70f4b13":"crowdfundContract()","b70f6ea8":"getDataPoint(uint256,uint256)","b70fadb7":"getAddressFromSan(string)","b70fbda1":"GoldRegistry()","b71051e2":"percentageOf(uint256,uint256)","b7107d00":"setSeller(address,address)","b710e8fe":"_restartsystem()","b711e18a":"_applyRefCredits(address,uint256)","b7133fa9":"test(uint256[5])","b7134feb":"icoMaxCap()","b713ef49":"developer_increase_price(uint256)","b714075e":"transferDevBalance(address,uint256)","b714e3cc":"GetDynamicRatio(uint256)","b71503fc":"FundsDrained(uint256)","b7159185":"shortShare()","b7160dee":"CVR()","b7161cc1":"VitaminTokenNew(uint256,string,string)","b71653a8":"setGalleryThreePrice(uint256)","b7167359":"contributed1(address)","b71698c7":"solutions(uint256)","b716e3f2":"addBoard(address,address)","b716f404":"raceOut(uint256)","b71738f1":"withdrawDthTeller(address)","b717cfe6":"CallTest()","b717dadf":"getEtherCountFor(address)","b7182b95":"getTokenOwner()","b719397f":"IsPreICO()","b719d032":"predecessor()","b719d1d0":"getRegInfo(address)","b71ab971":"getPlayerEarning(uint256)","b71c47a2":"surrender()","b71ce659":"GCA()","b71d1a0c":"_setPendingAdmin(address)","b71e0120":"limitBranchType()","b71e513b":"createGame(string,string,uint16,uint64)","b71e9c23":"throws()","b71f3cde":"onRefund(uint256,address,uint256)","b71f7f1c":"SuperFruit(uint256,string,string)","b71f8010":"setContract3(address)","b720a274":"_endOfICO()","b7213bd4":"readLog(uint256)","b72179ff":"viewFirstLotOfContractState()","b72218e3":"initialHolder()","b722875f":"giveBonus(address,uint256)","b722a9ef":"getPreviousShareholder(address)","b72314a1":"getGroupDescription(uint256)","b7232cd9":"enterBidForStar(uint256)","b723b34e":"mintTo(uint256,address)","b72413e4":"tokenDiscountPercentage(address)","b72481f8":"totalWinnings()","b725d84f":"PRICE_10()","b725e556":"UserOffers(address)","b7266456":"StandardToken()","b7268ef4":"rdiv(uint128,uint128)","b72703ac":"getPrev(address)","b72753d5":"updateItem(uint256,string,uint256,bool)","b7279ca6":"enableSweep(uint8[],bytes32[],bytes32[],address)","b727b194":"initialIssueMinting()","b7288f02":"freezeAccount(bool)","b72916ef":"getMsgValueBefore()","b7297cf3":"gameSettings()","b729d499":"dustPepe(uint256,address)","b72a0026":"APPToken()","b72a97e6":"updateTeamV(address)","b72b5a33":"NewBoardMember(address)","b72bedd0":"validation(uint256)","b72cacde":"approveByA(uint256,string)","b72ceab8":"alwaysRequireCosignature()","b72d0be5":"revocables(address)","b72e717d":"fromAddress(address)","b72f0e06":"LicenseCoin()","b72f547d":"startTransferGet()","b72f8ebb":"changeFreeBetValue(uint256)","b730aaaa":"Counting_CardPoint(uint256)","b730ee7f":"Anemoi()","b73112e5":"setCountryRank(uint256,string,uint256)","b73114b9":"purchaseCenturion(uint256)","b7312707":"fromHexChar(uint256)","b7317598":"claimI()","b7317806":"setEndOfICO(uint256)","b731e848":"left93(uint256)","b7324f8e":"PresaleClaimed(uint256)","b733e6a6":"LaunchContract(address,bool)","b73405a9":"roundMoneyDownNicely(uint256)","b734cbba":"setIcoDates(uint256,uint256,uint256,uint256,uint256)","b736ca82":"initialize(address,address,address,address,address,address,address,uint256,uint256,uint256,uint256)","b7375af7":"PresaleUnlimitedStarted(uint256)","b737ed1b":"getRandom(bytes32)","b737f5bd":"addOldInvestment(address,uint256,uint256)","b738169c":"betOnOddEven(bool,bool)","b7381a2c":"noteTokens(address,uint256)","b7384f6b":"initialOraclizeSettings()","b7387e66":"OpenBox(uint256)","b7388178":"getIsStoreSet(string)","b73974a1":"HIGH()","b73a9dbc":"variationCycle()","b73afe4f":"relocate()","b73b68e5":"lockTokens(address,uint256,bool)","b73c6ce9":"withdrawEarnings()","b73c71b2":"Test1Coin()","b73cb519":"changeIcoCap(uint256)","b73ded75":"setParams()","b73f02e4":"setActiveHashType(bytes32,bool)","b73f1e52":"fourthRelease()","b73fe29c":"getPeriodicalAR()","b73fe963":"noOfWaves()","b73fefe8":"rejectProposalAsHost(uint256)","b7403878":"updateLeaders_(address,uint256)","b741cb36":"setStageStartTime(bytes32,uint256)","b742398b":"trade(address,uint256,bytes,address,uint256,bytes)","b743f7b6":"giveEthCharityAddress()","b744a850":"getAssetTokenByIndex(uint256)","b744d2e6":"WithdrawEther(address)","b744d893":"DigiBlackCoin()","b7462833":"Blarity(address,uint256,uint256,uint256,address[],uint256[])","b7465a19":"setSlackUsersCap(uint256)","b746ec9f":"checkTotalPayouts()","b74746e7":"CharlieToken()","b747e025":"testFailMintNoAuth()","b7482509":"deposit(address,string)","b7491780":"_calculateNewHeroPower(uint256,uint256,uint256,uint256,uint256,bool,uint256)","b7491d65":"BiathlonNode(address,string,string,string)","b749b225":"bountyDrop(address[],uint256[])","b74a3266":"finalizeTemplate()","b74bc710":"LuckyDoubler()","b74bd09e":"rndGap_()","b74bd72b":"canTransfer(uint32,int256,address)","b74bee6a":"Mido()","b74c13f1":"storeAttachment(string)","b74cf3b6":"setVoterCount(uint256)","b74d13a5":"disableCheckArea()","b74d4103":"getForwardUpdateFeesTo()","b74d8e58":"getKittySkillScore(uint256)","b74db274":"VeryToken()","b74e20bb":"xCrypt(address,address,address,address)","b74e452b":"today()","b74e47ac":"getPartsOfOwner(address)","b74e825e":"DIVIDEND_FUND_FRAC_BOT()","b74f010f":"DreamCoin(uint256,string,string)","b74f312e":"changeTotalDistributed(uint256)","b74f32f2":"airdrop(address[],uint256,uint256,uint256)","b74feb18":"getRoundWinnerPot(uint256)","b74ffca7":"bookCab(uint256)","b75014c0":"startIcoMainSale()","b750948d":"canUserReleaseArtwork(address,address)","b750ac85":"LOG_HouseAddressChanged(address,address)","b751ecfc":"DomainIO(uint256,uint256)","b7526b79":"migrateDungeon(uint256,uint256)","b753485f":"currentGen()","b7538f3e":"ChangeClient(address)","b753a98c":"push(address,uint256)","b7540d9f":"freezed()","b756919d":"_handleEnergyTopup(address,uint256,uint256)","b7581c67":"vestingFounderAllocation()","b7595d3f":"getBoolField1()","b7598cca":"AreaPrice(uint256,uint256,uint256)","b759f954":"approve(uint256)","b75a0ac6":"setICOToken(address)","b75baa18":"w_futureDevelopment()","b75c2068":"lockShares()","b75c7d9e":"updateDealer(string,address,uint256)","b75c7dc6":"revoke(bytes32)","b75c7e62":"MedsupplyToken()","b75d7e50":"getExtrasData()","b75ece9c":"startFundingTime()","b75f4084":"finishInvesting()","b75f9b20":"commissionPCT()","b75fdf3a":"liquidityPoolTokens()","b760744f":"MytilcoinStorage()","b760c979":"TokenGranted(address,uint256)","b760e822":"minimumPurchaseInWei()","b760faf9":"depositTo(address)","b7614de7":"stakedByUser(address)","b7618a31":"rvt()","b761962c":"sampleMulti(bool,bytes32,int8,bytes4)","b761a16b":"JustmakeNewAccountsIssuer()","b7629dcb":"investorsAddress()","b762e6e8":"mintTimeLocked(address,uint256,uint256)","b762fbac":"changeFountainContractAddress(address)","b763150d":"registerCustomer(address,address)","b764132e":"CubaLibre()","b764311d":"RITToken()","b7643c5c":"_computePVPPetAura(uint256)","b7645ed4":"changeMaxCapUSD(uint256)","b76467c1":"Haltable()","b764e273":"failSend()","b764e8f5":"read_config()","b76564bd":"app()","b7656808":"minted(address,uint256)","b7656dc5":"transferFromPreSignedHashing(address,address,address,uint256,uint256,uint256)","b7663b08":"startICO_w2()","b7667603":"Goldplatina()","b76689a4":"createInviteID(address)","b766b562":"setBonusReceived(address,bool)","b76803b2":"cgoAddress()","b7682a81":"buyGanToken(uint256)","b768628f":"publishedWinningScoreThreshold()","b7688c8b":"ico_period()","b768cd5d":"modifyStartTime(uint256)","b768ce60":"getTotalVolumeToken()","b7692032":"Facebook()","b769e4c5":"LogCancelTemplateProposal(address,address,uint256)","b76b37dd":"toLotteryPool(uint256)","b76b3e39":"setICObyAddress(address,uint256)","b76b4ee2":"ManagerPermissionGrantedEvent(address,string)","b76b78fb":"getAllElement()","b76bf76b":"distributeTime()","b76c2e39":"LQX()","b76c3764":"NumberGame()","b76c5c9f":"sendAdvisorsBalance(address[],uint256[])","b76c8a2c":"SpartaTeamCoin()","b76c94e1":"fundsOf(uint256)","b76ce26c":"updatesolbuyrate()","b76d0edd":"Log1(address,bytes32,uint256,string,string,uint256,bytes1,uint256)","b76dfb28":"totalRemainInInventory()","b76e1324":"startCreatingAss(string,string,uint256,uint256,uint256)","b76e4890":"Tester()","b76e5e06":"getBA(bytes32)","b7700f33":"getManagerPubkey()","b77030a0":"setTau(address)","b770391b":"MineAffected(uint256,uint256)","b770485f":"specialContract()","b770486f":"investmentGuidesRewardsWithdrawn()","b770c7ef":"giftPlanet(uint256,uint256,address)","b7719ef5":"devWithdrawal(uint256,uint256)","b7742856":"mainSaleprice()","b774d3d7":"BankOwner_GetDonationsBalance()","b775553d":"setDividendCutPercentage(uint256)","b775c9ef":"etxAddress()","b7760c8f":"transfer(uint256,address)","b7764475":"ETHXBT()","b776fc15":"addItem(uint256,string,uint256)","b777b11e":"setBurnStart(bool)","b777cad7":"managerPrimary()","b7782455":"unicornAddress()","b77825d2":"getIndexOrder2(uint256)","b778809b":"initiateContract()","b778d4b4":"releaseToday()","b778e69e":"getPastWinnerEntries()","b77a284c":"transferAndCallWhitelist(address)","b77bf600":"transactionCount()","b77cd1c7":"refreshBalance(address)","b77d09c9":"gameGifIsOver()","b77d1597":"QAcoin()","b77d4876":"startTokensSale(address,uint256)","b77da4a0":"totalDevCoin()","b77e4185":"promotionsAvailable()","b77e60dd":"tokensaleSecondsToStart()","b77ebcbb":"Country_code(uint16)","b77f00b3":"preIcoPhaseCountdown()","b77f39fe":"recoverTokens()","b77fc549":"withdrawAffiliateCommission()","b77ffaf5":"changeInvestNum(uint256)","b7808600":"ClaimCrowdsale(uint256)","b780a659":"cryptoString()","b780ef58":"_transferRobot(address,address,uint256)","b7813355":"getTotalCollectedWei()","b781ad99":"ALLOC_SALE_CORNERSTONE()","b781afa7":"EverhuskCrowdsale(uint256,uint256,uint256,address)","b7825cfc":"addTask(bytes32,string)","b782fc9b":"getFirstActiveDuel2()","b7833cc3":"getWitness(uint256)","b783508c":"receiveAuction(address,uint256,uint256,uint256)","b78376e9":"addPayer(address)","b783969f":"GenkiProjectToken()","b783d6c7":"challengeRegistration(bytes32)","b7840731":"RedeemOraclize(uint256)","b7844170":"getSellUnitsInformations()","b7844aff":"NeuroToken()","b7845c97":"isPhase(uint256,uint256)","b785473c":"satRaised()","b7870845":"getCalculatedFees()","b787b91d":"registerVestingSchedule(address,address,address,uint256,uint256,uint256,uint256)","b7886b37":"checkReceivedUser(address)","b789321a":"priceRound4()","b7897485":"getCurrentBet()","b78aa7f4":"challengeChannel(bytes,bytes,bytes)","b78ae50a":"getCrystalsByKind(address,uint256)","b78b52df":"allocate(address,uint256)","b78b6087":"finalizeMigration()","b78b7232":"addFeedIn(address,address,int256,uint256,uint256)","b78b842d":"kyberNetwork()","b78bd4a5":"breakCookie(string)","b78be802":"emergency_withdraw(uint256,address)","b78be927":"ZYCoin(uint256,string,string)","b78c1517":"reservationFund()","b78c1853":"deleteOwnPeerReview()","b78d27dc":"bond(uint256,address)","b78d32cd":"BET()","b78da386":"withDrawFunds()","b78e4bfd":"jinglesInfo(uint256)","b78e5e26":"transferTokensFromBountyAddress(address,uint256)","b78f8389":"divideUpReward(uint256)","b78f9de7":"Sale()","b78fd7bc":"transferRemainingTokensToUserAdoptionPool(uint256)","b790301a":"PLN_Omnidollar()","b79047cc":"PricePredictionBettingGame(address)","b790505d":"set_compenstation(uint256)","b790634e":"getDepositRate()","b7909898":"allocateInitialBalances(address[],bytes32[],uint256[])","b790a77b":"_withdraw(address,uint256)","b790c32c":"transferAuditorRecord(address,address)","b7915e39":"getAllowedNotaries()","b791e8ed":"calcEffectiveOptionsForEmployee(address,uint32)","b791f3bc":"migrateAmountBooks(address)","b7928b4f":"getReason(uint256)","b792d022":"batchCreateSingleSeedAuction(uint8[],uint8[],uint256[],uint256[],uint256[],uint256)","b792e6ec":"init(uint256,address)","b792f5f6":"ret_luklen()","b7930507":"UNLOCKED_TIME()","b793233b":"icoEndTimestamp()","b7935f0a":"emergencySetDAdmin(bytes32,address)","b794004d":"YOU_BET_MINE_DOCUMENT_PATH()","b7942d78":"RegReader(address)","b79550be":"recoverFunds()","b795dffe":"purchaseKey(bytes32)","b796a339":"addRegistryIntoOwnerIndex(address,address)","b796c9b8":"Withdrawall(uint256,address[])","b7970d80":"rngCallbackGas()","b7975d1f":"getMyToad()","b797b5ba":"tgeCurrentPartInvestor()","b798b129":"finalizeEarlyBirds()","b7992c0b":"finalize3()","b799ba7e":"CalorieCoin(address,address,uint256)","b79a5539":"preTokenSalesCapReached()","b79a6231":"Tier_Basic()","b79af928":"totalSpentEth(address)","b79c5f7f":"IntentionToFund(address,uint256)","b79eb3a4":"AlterContactPubkey(address,bytes32,bytes32,bytes32,bytes32)","b79ec028":"setLevelup(uint8[4])","b7a025f9":"bZxTo0xContract()","b7a139bf":"firstRoundPercent()","b7a1affa":"DACContract()","b7a1c236":"LogChangeIsPayableEnabled(bool)","b7a1d003":"SessionClose(uint256,uint256,uint256,uint256,uint256)","b7a2cbcc":"lockedTransfers()","b7a2d99d":"withdrawAbleEther()","b7a2e1f2":"buy(string,string,uint256,address,address,address,address,bytes2)","b7a311fd":"TimoNetwork(uint256,string,string)","b7a3446c":"oldBalanceOf(address)","b7a40f21":"purchasePlanet(uint256)","b7a55438":"replaceOperator(address,address)","b7a693d7":"MaxSantaRewardPerToken()","b7a6b6a7":"AIREP()","b7a7612c":"setBtcEthRate(uint256)","b7a78911":"testMultitransfer2()","b7a8807c":"openingTime()","b7a90cf9":"BitAseanToken(uint256,string,uint8,string)","b7a9434b":"registerSpawned(uint32,int256)","b7a973bd":"setCompte_13(string)","b7a97a2b":"isValidChannel(uint256)","b7ab4db5":"getValidators()","b7ab7ade":"setAllowedContract(address[])","b7abf606":"modifyLocality(string)","b7ac5d3b":"marketingFundAddress()","b7acbd41":"checkSellerGuarantee(address)","b7acdca6":"addBet(uint256,address)","b7ad2432":"totalWindows()","b7adb169":"getPendingUserlists()","b7adb974":"lightingTransfer(address,address,address,uint256,uint32,bytes32)","b7ae74fd":"FreeCoin(address,uint256,uint256,uint256,uint256,uint256)","b7aec6a5":"scheduleCall(address,bytes,uint256,uint256,uint8,uint256)","b7aec6b1":"getSpecificEscrowTransaction(address,address,uint256)","b7b0422d":"init(uint256)","b7b172b3":"cashout(address,uint256)","b7b1b93f":"_createPixel(uint32,uint8,uint8,uint8,string)","b7b1d7f7":"isCrowdSaleActive()","b7b1e3cc":"getPropertyData(uint16,uint256,uint256)","b7b2a009":"getCardDetails(uint8)","b7b2bbc0":"WinnerSet(uint256,uint256,address)","b7b2c7d6":"batchFillOrders(address[5][],uint256[6][],uint256[],bool,uint8[],bytes32[],bytes32[])","b7b2e501":"makeInvisible(uint128)","b7b33765":"calculationOfPayment()","b7b3a56e":"overflow_lower()","b7b3b89a":"lockedVault()","b7b3ea98":"endContrib()","b7b4557c":"LogMigrationInitiated(address,address,address)","b7b47e31":"batchActivenessUpgrade(uint256[],uint256[])","b7b48388":"addThing(bytes32,bytes32,string,string)","b7b4ceb3":"CPCEIco()","b7b4fe13":"setWhitelistDemoc(address,bool)","b7b5709a":"freezeFrom(address,bool)","b7b57c3f":"getPartnerMessage(address,address,uint256)","b7b5e811":"getProjectBonus()","b7b6700b":"viewPlayerPayout(address)","b7b6e978":"unlockForOrder(address,uint256)","b7b747c5":"testDepositUsingDeployedContract()","b7b8533a":"expireAfter()","b7b96723":"right7(uint256)","b7b9dead":"MyAdvancedToken()","b7ba0ba0":"showAssetEvent(bytes32,uint256)","b7ba6050":"currentTokenOfferingRaised()","b7bae9b7":"exists(bytes,bytes)","b7bb018d":"unlockingBlock()","b7bb208b":"JobitToken()","b7bc2c84":"isFueled()","b7bc7653":"set_pauseDET(bool)","b7bc7cb8":"fixedExp(uint256)","b7bda68f":"taxAddress()","b7bdc7ef":"setDomainPrice(bytes32,uint256)","b7bedaf1":"setPreAddr(address)","b7bf356a":"taskExists(bytes32)","b7c03170":"CurrentState()","b7c14d7a":"payOutJackpot()","b7c251c3":"getRedeemedPeriods(bytes32,address,uint256)","b7c2ccb6":"getNodalblockTimestamp(string)","b7c38d02":"testControlCreateSameIpfsHashAndNonce()","b7c42cf0":"claimTokensICO(address)","b7c4b775":"setMaxGas(uint256,uint256)","b7c4bf17":"readyUp()","b7c52820":"addSentTrade(address,bytes32)","b7c54c6f":"getHKGOwned()","b7c55259":"endGame(uint256,address,address,address)","b7c5b181":"delegatedTransfer(address,address,uint256,string,uint256,bytes32,bytes,uint256)","b7c70c34":"seratioCoin()","b7c74cf6":"_calculatePayment(uint8)","b7c763b5":"getString(uint256)","b7c7986f":"getMarket_CommunitUnusedTokens()","b7c7ecbe":"setTitulaire_Compte_6(uint256)","b7c8561f":"removeDestroyer(address)","b7c8699d":"modifyGovtAccount(address)","b7c8a90a":"removeExclusionFromTokenUnlocks(address[])","b7c93330":"ResourcePoolTester()","b7c940f6":"SolarDaoTokenCrowdsale(address,address,uint256,uint256,uint256)","b7c97930":"registerPool(string,uint256,uint256)","b7c97fa0":"BEN()","b7c9da33":"buyTulips(uint32,uint16)","b7ca3086":"getSelfCount()","b7ca51e8":"starToken()","b7caf50a":"ticketsNum()","b7cb4830":"NERU()","b7cc2312":"bobClaimsPayment(bytes32,uint256,uint256,address,address,bytes20)","b7ccc466":"categoriesCount()","b7ccccaf":"bridgeValidatorsProxyOwner()","b7cce253":"maximumMainSaleRaise()","b7cdddcb":"claimEth()","b7cefd9f":"FlatEarth()","b7d02044":"deployToken(string,string,uint8,uint256)","b7d0628b":"getGameState()","b7d130ff":"isAuthorizedToSell(address)","b7d29e91":"NameChanged(bytes32,string)","b7d3a9c9":"setWhitelistAgent(address)","b7d3cb87":"countAllProposals()","b7d454a4":"setNotTransferable(bytes32)","b7d4dc0d":"unsetBase(address,uint64)","b7d4e5fd":"getX2(uint256)","b7d534a1":"addrToString(address)","b7d5d4c0":"piggyBank()","b7d5d74c":"balanceAtBlock(address,uint256)","b7d5ddc8":"setAssetClaimString(uint256,string,string)","b7d5e804":"remove(uint8,uint8)","b7d5ef4d":"BATokenFactory()","b7d65d17":"setUnitCoinProductionMultiplier(address,address,uint256,uint256,bool)","b7d6f432":"buyCar(address,uint256,bool,address,uint256)","b7d6f6c6":"WHALE(address)","b7d74fda":"DevelCoin(uint256,string,uint8,string)","b7d7acea":"externalGiftEth(address)","b7d89483":"AddressList(string,bool)","b7d8b1d9":"emitWorkStarted(uint256,uint256)","b7d9549c":"incrementPrice(uint256,address)","b7d9d7b9":"roundTwoAmount()","b7da166b":"_mint(address,address,uint256)","b7da5b0d":"TreatzCoin()","b7dacbf1":"setBackup(address)","b7db7f0f":"allowTransfer(address,address,address,uint256,bytes)","b7db87e8":"testFooArray()","b7dc2a9f":"weiMinimum()","b7dc3b18":"buy(uint256,string)","b7dc5c11":"priceGuaranteed()","b7dc8a32":"firstValidBlockNumber()","b7dc9d85":"ORDER_DONE(address,address,address,bool,uint256,uint256,uint256)","b7dcf6a9":"createPromoCollectible(uint8,uint8,uint256,address,uint256,uint256,uint256)","b7dd1d17":"getAllRevisionBlockNumbers(bytes32)","b7ddcb27":"InteractiveCrowdsaleToken(address,string,string,uint8,uint256)","b7de47d3":"getIndex(uint256,uint256)","b7dea35f":"hatchSeeds(address)","b7dec1b7":"GENESIS()","b7ded7cc":"purchaseHero(uint256)","b7df07a6":"receivePlayerInfo(address,string)","b7df7ef8":"AccountUnlocked(address)","b7df9289":"recvShrICO(address,uint256,uint256)","b7dfc8a5":"updateTokenPerEther(uint256)","b7e0308d":"priceStep2()","b7e05277":"private_DelGameBar(uint256)","b7e05d4f":"newProposallog(string)","b7e09773":"devTeamReinvest()","b7e1917c":"tokenAdmin()","b7e1b974":"getStr(uint256)","b7e1bce7":"ReceiverAddressChanged(address)","b7e1ecef":"addAttendantAndTransfer(string,string,bool)","b7e2263b":"getTotalMatches()","b7e24979":"addThing(bytes)","b7e28a3b":"certificationManager()","b7e2f504":"isPreSaleFinalised()","b7e39b4f":"setBalances(address[],uint256[])","b7e43a84":"maximumIssuerReservedUnits()","b7e45353":"forbidChecking(uint256)","b7e4a503":"Determine_Result(uint256,uint256)","b7e5cabb":"contractorsProfitAddress()","b7e621c3":"claimCompanyTokens()","b7e6bd34":"getTopic(bytes15)","b7e6dfe3":"GetApplicantAddress()","b7e82526":"GraybuxToken()","b7e83329":"ExportMaster()","b7e90262":"roleAdminAddress()","b7e92ede":"EtheRoox(address,address,address,uint256,uint256,uint256)","b7e9f193":"nextWithdrawal()","b7eb22b3":"getAccountsSize()","b7eb5e0a":"unlockAddress(address)","b7ec2086":"priceWei()","b7ec44b4":"asyncTransfer(address,uint256)","b7ecbaae":"removeWhitelistAddress(address)","b7ee2552":"ICOpaused()","b7eea206":"openLedgerAddress()","b7ef5fed":"claimRewards(uint16[],address)","b7efc1cd":"authorizeMintToken()","b7eff231":"oraclize_query(string,bytes[3])","b7efff16":"GANAPATI()","b7f01bfc":"tank()","b7f1489e":"setLosePercent(uint256)","b7f1e6af":"preferredSaleEndTime()","b7f2f33c":"transferRightIfApproved(address,bytes)","b7f37983":"getInvestmentRecordListLength()","b7f3ffed":"updateProfiterole(address,uint256)","b7f43a63":"brideVow()","b7f53c91":"CryptoSilver()","b7f545cc":"deployTokenContract(uint256,bool)","b7f603ff":"LimbToken()","b7f63665":"ttToken()","b7f6a75a":"XPAToken(address,address,uint256,uint256,uint256)","b7f6e74d":"unpositionFrom(address,address,uint256)","b7f79374":"DildoToken()","b7f84ae2":"icoPhaseTimeInterval()","b7f90f12":"decrementCount()","b7f927e6":"PROMETHEUS_VOUCHER_LIMIT()","b7f92b71":"reserveFund()","b7f9c4f6":"initCapsule(uint256)","b7fa265a":"_withdraw(bool)","b7fba4d3":"getProxy(address)","b7fc6612":"transferMany(address[],uint256[])","b7fcc321":"CryptoHoleToken()","b7fcfa69":"amountReceivedFromTransfer(uint256)","b7fd45a0":"EscrowICO()","b7fda832":"updateGenVaultAndMask(address,uint256)","b7fde9da":"mintCoins(address,uint256)","b7ff11be":"isAcceptedDcorpMember(address)","b7ff2aed":"withdrawMaker(address,uint256,address)","b8005f38":"execBoard()","b800b2fe":"BEZOS()","b800db55":"__isSenderInRole(uint256)","b8017221":"get_party2_balance()","b804dc56":"setRecallPercent(uint256)","b80509c5":"getCountsById(uint256)","b80540c0":"Adjudicator(address[],uint256,uint256)","b80546c2":"endPeriodA()","b805a5ca":"GetChip(uint32)","b8066bcb":"etherToken()","b8068a5f":"CATServicePaymentCollector(address)","b80756f0":"_calculateLockedBalance(address)","b80777ea":"timestamp()","b8077e28":"getTxOrigin()","b8079d49":"debitWalletLMNO(address,uint256)","b807ed76":"SANKEYSOLUTION()","b80825ff":"TheBittrip()","b808745c":"transferPass(bytes32,address)","b8087ac0":"goalMet()","b80907f2":"getReputationToken()","b809127e":"getQuickPromoBlockInterval()","b8093100":"giveBounty(uint256,address,address)","b80a30b7":"_getInvestorTokenAmount(address)","b80ac7df":"verifyProof(bytes32[],bytes32)","b80aedf2":"setReservedTokensList(address,uint256,uint256,uint256,bool)","b80cdcf6":"finishCrowdsale()","b80ced14":"LPCoinToken()","b80d3181":"annualPrice()","b80e63df":"baseTokenBalance(address)","b80ee369":"createCardForAcquiredPlayer(uint256,address)","b80f3532":"exchnageRate()","b8109e1a":"MeetingsEntity()","b810b81c":"Pixereum()","b810bfa4":"GDC(address,address,address,address,address)","b810d24b":"updMinPurchaseLimit(uint256)","b810fb43":"addressList(uint256)","b811215e":"initialCap()","b81168b4":"CNNTokenBase(uint256,string,string,uint8)","b8121385":"stopOperation()","b8121fe4":"viewPetitionSigner(uint256)","b8126a3e":"addSideService(address,uint256)","b812a6ce":"lastBlock_v11()","b813c627":"releasedSupply()","b813d939":"test_fourValidEqUint(int256)","b8144a72":"getBankRating(address)","b814660e":"AllowTransferLocal()","b8163641":"checkReceive(address)","b8174685":"_claimReward721(address,string)","b817e043":"JobMarket()","b818f9e4":"batchTransferFrom(address[],address[],uint256[])","b8198875":"StreamToken(uint256)","b81af39b":"declineMP(address,int256)","b81b0b6a":"claim(bytes32,string,string,address,bytes32,bytes32,uint8)","b81bb854":"createRequest(address,address[],address[],int256[],address,string)","b81c259e":"PexCash()","b81c6453":"vote(uint8,address)","b81ca723":"InitialCoinOfferingToken()","b81ccdd5":"cashilaTokenSupply()","b81ce8a7":"MicropaymentsNetwork()","b81db9da":"addUserValueName(bytes20)","b81df742":"minBuyLimit()","b81e3b19":"bankMoney()","b81e43fc":"getEventName()","b81ec822":"PRE_SALE_2WEEK_BONUS()","b81f39a8":"addToReserve()","b81ff45b":"getBalanceByAccount(string)","b8205d35":"IncentToken()","b820c41c":"iceToken()","b8216ea8":"redeemMany(address[])","b821da1b":"submitBid(uint256,uint256)","b821f815":"pay_winner(uint256)","b8225dec":"selfDestructInitiated()","b822b28a":"lastBlock_a8Hash_uint256()","b823aac7":"endICOTimestamp()","b823e991":"CourseCertification()","b8240a65":"UpdatedPrice(uint256)","b82465e9":"managerIncome(address)","b8248dff":"isValidOwner(address)","b82545e5":"judgeWin(uint256,uint256)","b8254880":"SurrusContract()","b8261f8f":"myEntityList(uint256)","b826d6d7":"DigiPulseToken()","b82852ec":"changeReserveIAMDestinationAddress(address)","b82864e0":"getHouseEdgeFee(uint8,uint256)","b828cfd2":"PRVTToken(uint256,string,uint8,string)","b8291bda":"Pomzon()","b829528e":"LotteryLog(address,string)","b82a0ce8":"bonusTime()","b82a65b2":"getReportingToken(uint256[])","b82a737c":"communityAmount()","b82b2a07":"makeProposal(uint8,uint8)","b82e6416":"doTimeoutForDefendant(uint256)","b82eb946":"_setStageLimit(uint256)","b82fb745":"saleEndAtBlock()","b82fcdeb":"tokensAllocatedForTeamAndReserve(address)","b82fd275":"removeFrozenTokenConfigurations(address[])","b82fedbb":"register(bytes32,address,bytes32,bytes32)","b8305b43":"HodlCreated(uint256,address,uint256,uint256)","b83069c5":"getStemPrice()","b830b305":"getpersonCount()","b830c538":"unassignRole(address,bytes32,address)","b8314c22":"whaleMax()","b831d137":"saleSharesSold()","b832004d":"setTokenInfoParametersReady()","b832679c":"setKmPards(address)","b832fdde":"NON_VESTED_TEAM_ADVISORS_SHARE()","b833ac27":"PolyToken(address)","b8341628":"mintingPreIcoFinish()","b834f6fb":"isMainChain()","b83506cf":"defaultBuyNowPrice()","b83520b3":"allowIcoExit(bool)","b835a7fe":"RubiksToken()","b8366bd1":"CorruptionCoin()","b837433c":"TEAM_ADVISORS_SHARE()","b837a3b8":"sendProfitsRewardBips()","b837c58e":"payTo()","b837c94f":"ASEBToken()","b8385339":"finalizeStage(uint256)","b8386f3b":"_gambling(uint256,bytes32,uint256)","b8388aca":"findBestRate(address,address,uint256)","b839e0d1":"lockedAllocatable()","b83a1bdc":"lastMineralUpdateTime()","b83a4da9":"totalWeiSale()","b83ace61":"setHouseEdge(uint256,uint256,uint256)","b83b4529":"FundsTransferredToMultisig(address,uint256)","b83c298e":"updateBoolSetting(uint256,bool,address,string,string)","b83d3f2c":"oraclizeSource()","b83dfdc9":"setInvestorData(address,uint256,uint256)","b83e1d14":"CountTokenUser(address,uint256,bool)","b83e4779":"OntologyToken(uint256,string,string)","b83e9662":"ParaTransfer()","b83fc6b6":"CrowdsaleClosed(uint256)","b8406a7e":"balanceOfLotteryNum(address)","b840a1db":"WhitelistChanged(address,bool)","b840b421":"OriginalVirtualOperation()","b8415b0c":"startDistribute()","b8416d2e":"exec(address,bytes32,bytes)","b84172e7":"getH1Bidder()","b842826c":"Built()","b842eef2":"test02BuyToken()","b8435050":"crowdsaleclosed()","b84391de":"setBetEndTime(uint256)","b8441be0":"setTransferAuthPermission(address,bool)","b8444c13":"forceVoidRace()","b845b51e":"IIPToken(uint256)","b845c9a2":"WEI()","b8471085":"PRIVATESALE_START_DATE()","b84738aa":"changeMinPay(uint256)","b848b944":"doSellerCancel(bytes16,address,address,uint256,uint16,uint128)","b8499750":"advisorLock()","b84a6849":"createShareToken(uint256)","b84aac5c":"decreaseApprovalPreSigned(address,uint256,uint256,uint256,uint8,bytes)","b84b05b2":"NetyulCrowdsale(address,uint256,uint256,uint256,address,address)","b84b276d":"second_whitelistSupplier()","b84b8b8c":"buyGoods()","b84c11da":"create(address,string,bytes32,uint256,address)","b84c35b3":"addCode(string,uint256)","b84c743b":"getReferencePrice(address,address)","b84c8246":"setSymbol(string)","b84cc017":"myBonus(uint256)","b84d2106":"shut(bytes32)","b84dda70":"tweakState()","b84dfbd2":"securityToken()","b84e1327":"checkIfContractCreatedHere(address)","b84e44ab":"setProviderLastSupplyID(uint256,uint256)","b84ebd7f":"createMechBTC(uint256,address)","b84ee1a4":"setTransferProxy(uint32,int256,address)","b84f1318":"AddNewCurrency(string,string,string)","b84fe73b":"voteAll(address)","b84fed88":"isMintContract(address)","b8500e5e":"purchaseRecordsNum()","b8506a3f":"tokensPerWei7()","b850ae36":"isRegular(uint256)","b851ed97":"bonusAllowed()","b8522043":"getUserList()","b8534ed1":"contractEndTime()","b8547736":"testBadWithGoodInterface(address,uint256,address,uint256)","b85477c5":"dealStatus()","b857a688":"Eth_Amount()","b858b39f":"PhotoAdded(address,address)","b85926e0":"VESTED_AMOUNT()","b85973c1":"overbidNation(uint8)","b8598f9e":"computeOppositePrice(uint16)","b85a6a20":"numComments()","b85bf538":"ownerSetBankersLimit(uint256)","b85c2f72":"submitEntry(uint256,uint256,uint256,uint256)","b85cf54e":"rewardPoolPercentage()","b85d6275":"RemoveModerator(address)","b85dfb80":"backers(address)","b85e0402":"AppCoinsIAB()","b85e0aca":"legacyRepContract()","b85e5915":"ExitPlincWithLoss(uint256)","b85e7df1":"setPresaleMode()","b85e84c0":"judgeFinality(bytes32[13],bytes32[],bytes32[],bytes32[10],uint256[4])","b85ea983":"countPortfolios(address)","b85eb295":"checkOwnershipAndAvailability(address,uint256[4])","b85ed17d":"getHolderByIndex(uint256,address)","b85f726a":"Cashier()","b861be22":"checkPermissions(address,address)","b8621759":"issueNewCoins(address,uint256)","b862d80d":"minBetVal()","b86397e7":"mFUNDING_CURRENT_DURATION()","b863bd37":"random(uint256)","b8642896":"ETSToken(address)","b864f5a9":"verify(uint256[],uint256[])","b8657988":"MYSUPERTOKEN()","b8661e2d":"getAllTeamsIds()","b86780b3":"restTokensBurned()","b867e8e6":"accrueDividendsPerXTokenETH()","b868723e":"endPrice()","b868a2ff":"update(uint256,uint256,bytes32[])","b8697dbd":"getLockByIndex(uint256)","b869f1e2":"SALE_CAP_IN_USD()","b86a1fb2":"adminPool()","b86a3582":"ETCH3dVs()","b86b14cd":"setRate1(uint256)","b86bc74f":"CERTIFIER()","b86c49e1":"getMarketsItemId(uint256)","b86c6b7b":"calculateCellBuy(uint256,uint256)","b86c9845":"MithrilSword()","b86dab46":"addToApprovedAddress(address)","b86df9db":"RewardRecycled(uint256,address,uint256,uint256,uint256)","b86e0657":"removeServer()","b86e321c":"withdrawReward(address)","b86ec38f":"REIMBURSABLE()","b86eeb69":"bountyTotalSupply()","b86f602c":"submitOrder(bytes,uint64,uint64,uint256,uint256,uint256)","b86f6aa7":"resetCollectedFees()","b8701689":"removeGlobalConstraintPre(int256,address,int256,address)","b870ecbb":"testNormalWhitelistAdd()","b870f613":"back(address,uint256)","b8716f3a":"_teamTransfer(address,uint256)","b8726395":"Mint(int256,uint256)","b873846f":"ArrayPasser(uint8[9])","b873e9a7":"trustedReportingParticipantTransfer(address,address,uint256)","b875a5e0":"rateThirdRound()","b8760ad3":"payStakingFee(address,uint256,uint80,uint80,uint256,address)","b87760ad":"uint256Tostr(uint256)","b8782d49":"PHASE2_RATE()","b8788453":"mainSale_StartDate()","b87aedcc":"recentPlayersFront()","b87b9ac3":"testExchangeRate(uint256)","b87ba329":"getMemoryTraceMeta(uint256)","b87c01e3":"GVPE_address()","b87c03c2":"multiAccessOwners(uint256)","b87c7d43":"setEthAmount(uint256)","b87cbafc":"bn128_check_pairing(uint256[12])","b87d8712":"RulesProposalSubmitted(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","b87dbf81":"handleAffiliate(uint256,uint256,uint256)","b87dddf6":"tokenFallback(address,uint256,bytes,string,uint256)","b87e461c":"scrapPercent()","b87e64ce":"DecentBetVault(address)","b87ee9d6":"setLLV_edit_4(string)","b87f9b98":"_stringToByte(string)","b87fb3db":"start_block()","b87fb721":"LogNewTemplate(uint256,address,string)","b87ff295":"MintTokens(int256,address,uint256)","b8803738":"total_user_eth_cap()","b88064ad":"peMinPerPerson()","b881604d":"removeStrip(uint256)","b8840d3d":"getDrug(uint256)","b88467c2":"getProjectEscrowAddress(bytes32)","b8847e9d":"haltRevealPeriod(bytes32)","b8850556":"ApplyAction(uint32,uint32,uint256,address,address)","b8851fea":"endDateStart()","b8852718":"transferLockedPart(address,uint256)","b8857936":"dtSetEthBalance(address,uint256)","b885acd8":"fourthWeekTokenPrice()","b885d560":"airDeliverStandalone(address[],uint256[])","b8867485":"proxyOf(uint256)","b8871f98":"_createEdition(uint256,bytes32,uint256,uint256,uint256,address,uint256,uint256,string,uint256,bool)","b8872fb7":"reinvest(address)","b8873077":"HUNT(uint256,uint256,uint256,uint256,address)","b88746b0":"previousDrawingClosed()","b8878171":"getPersiansBattlePointsBy(address)","b888690a":"deleteMessage(uint256)","b888a492":"isNewPayoutPeriod()","b888a66b":"tktPrice()","b88903f7":"TokenDrop(address,uint256)","b8894fe3":"mintTokenToBuyer(address,uint256,uint256)","b889d440":"markTokenSold(uint256)","b88a374c":"EarnEnoughMoney()","b88a529b":"getCurrentRate(uint256)","b88a802f":"claimReward()","b88ab668":"TBXToken()","b88c9148":"getFee(address)","b88d0169":"INITIAL_EMISSION_FACTOR()","b88d4fde":"safeTransferFrom(address,address,uint256,bytes)","b88d6aa7":"refund(bytes32,uint8,uint256,uint256)","b88e8518":"FluencePreSale(uint256,uint256,uint256)","b88e962f":"showEmployee(uint256,uint256,uint256)","b88eef53":"registryCreated()","b88f9936":"setMinTms(uint256)","b88fd16e":"developmentFundAddress()","b8901a41":"am_I_locked(address)","b8905649":"Crowdsale(address,uint256,uint256,address,address)","b8906755":"payProviderFee(address)","b890de6b":"thirdLineWrong()","b890ed85":"CryptoSagaCardSwapVer2(address,address,address,address)","b891656e":"thismanyblockstillthspudholderwins()","b8918710":"FangTangCoin(uint256,string,string,uint8,bool,uint256,uint256,uint256,uint256)","b893deb1":"getContestEndTime()","b89503f3":"getDiceWinAmount(uint256,uint256)","b895947a":"Janders()","b895c813":"registIcoAddress(address)","b896149c":"BLUEOS()","b8972db5":"sendToken()","b8973927":"setContractStart(bool)","b89761b8":"encoded_data()","b897b4f5":"multAirdrop(address[],uint256)","b8991ffb":"reject_payment(uint256,bytes32)","b899e1b7":"_setApp(bytes32,bytes32,address)","b89a73cb":"isShareholder(address)","b89bf71d":"safeWithdrawal4(address)","b89c5932":"setRequestLimitInterval(uint256)","b89c70c0":"calculateCoinBuy(uint256,uint256)","b89cd5bd":"icoPartner(address,uint256)","b89e066a":"MINCAP_TOKENS_PRE_ICO()","b89e8cbb":"getRemainingSellingTime()","b89f3025":"investExt(address,uint256)","b89fc89e":"setDistributionAddress(address)","b89fde71":"CheckAmbientTempException(bytes32,uint32)","b8a15b1d":"bobMakesErc20Payment(bytes32,uint256,address,bytes20,address,uint64)","b8a1e355":"doBet(uint256)","b8a1fdb6":"transferAndFreezing(address,uint256,uint256,uint256,uint8)","b8a24252":"checkpoints(uint256)","b8a25119":"setPresaleMode(bool)","b8a268c1":"getCloseFlag(bytes)","b8a32c7e":"claimTile(uint256,uint256,uint256)","b8a358e9":"canMintUtility(address,uint256)","b8a393b8":"openCompetition()","b8a3c6ea":"KPCSAdministrator(string)","b8a4a064":"applauseCashCrowdsale()","b8a4b858":"INVESTOR2()","b8a4db81":"addValueBonus(uint256,uint256)","b8a4f9ae":"addInFutureExpanstionMap(address)","b8a5368a":"gameStart(uint256)","b8a548c5":"SCTokens()","b8a582a9":"EtherMoney()","b8a582af":"logicVersion(address)","b8a67b6e":"GiroToken()","b8a67c3c":"expireDate()","b8a684f8":"CryptoSagaSwapPLAT(address,address,address,address)","b8a76f54":"setIPFSHash(string)","b8a7c78a":"CommunityAddress()","b8a80aac":"getItem(address,uint256)","b8a876ed":"Quitcoin()","b8aa0a34":"getSealDate()","b8aa4da8":"addMemberToBS(address)","b8aaae7a":"PXXToken()","b8aac3a5":"createAndSignBBODocument(bytes,bytes,address[],uint256)","b8ab9203":"secondRoundMayTokensLimit()","b8ab9883":"claimTimeoutEndedWithMove(bytes32,uint256,uint256)","b8aba8cf":"NewPayment(address,uint256)","b8abd184":"getInvestorKey(bytes32,uint8)","b8aca90b":"CurrentGame()","b8ad2abe":"addTokenGrant(address,uint256)","b8ad2fca":"claimMeme()","b8adaa11":"reject(uint256)","b8af146f":"subsm(uint256,uint256)","b8af21b9":"isLotteryClosed()","b8af6bc7":"getAgentsAmount()","b8afae78":"IPM2COIN()","b8afd597":"FinishRoundGamble()","b8b040a1":"xapo()","b8b0f533":"get_bitcoineum_contract_address()","b8b13e6b":"MaximumcoinStart()","b8b18915":"withdrawBonus(address)","b8b199e5":"_userSignUp(string,address,bool)","b8b19c27":"MultiOwnable(address[16],uint256[16])","b8b2052c":"setCrowdsale(address,address)","b8b23120":"getFlagPrice()","b8b27765":"payManagementBodyPercent(uint256)","b8b2bdad":"setBool(string,bool)","b8b2d490":"feePerSec()","b8b3d85b":"getFunderBalance(address)","b8b459bc":"OrderUpdated(uint256)","b8b4f1a0":"signContract()","b8b52652":"startFightA(uint256,uint256,bytes4)","b8b570f1":"Distributed()","b8b690e7":"__targetExchangeCallback(uint256)","b8b798be":"getYearlyUSDSalariesTotal()","b8b7b899":"receiveTransfer(address,uint256,address,bytes)","b8b7edb2":"hashToken()","b8b808cc":"getAddressFromNumber(uint256)","b8b85873":"purchaseArray(uint256)","b8b8d387":"myWeiValue()","b8b8fc3a":"getPI_edit_20()","b8ba427d":"RetDime()","b8ba532f":"developer_edit_name(string)","b8ba7c7f":"createGen0Auction(uint256,uint8,uint8,uint8,uint8)","b8baed2c":"calcTradeFeeMulti(uint256[],uint256[])","b8bb372c":"APIHeaven()","b8bcaad5":"_randomPack(uint256)","b8bce6d0":"dateEcoRelease12()","b8bcf6c9":"ico2ndPrice()","b8bd3dbb":"setMakerFee(uint256)","b8bdd8dd":"close(bytes)","b8bdf701":"initiateCreateSale(uint256,uint256,uint256,uint256)","b8be73ed":"offchainUploaderAddress()","b8beafd6":"buyVolumes(address,address)","b8bf029b":"list(address,uint256,uint256,uint256,uint256)","b8bf0f1f":"getRemainingBlocksUntilPayoutk()","b8c0517a":"splitStake(address,address,address,uint256)","b8c26d0b":"ContractWithParams(address)","b8c2a9e1":"getBidReports(uint256)","b8c375b6":"WavesToken()","b8c48f8c":"setInitialParent(int256,int256,int256)","b8c508e5":"MOBOL()","b8c52477":"_exchange(uint256,uint256)","b8c577ff":"setGrowth(uint32)","b8c58128":"setList(uint256,uint256[])","b8c65462":"preICOSaleStart()","b8c6a67e":"maxPendingParticipants()","b8c6d2e9":"BretCoin()","b8c6f579":"setAuction(address)","b8c766b8":"saleClosed()","b8c78391":"releaseableBalanceOf(address)","b8c7dea3":"stageCurrentSum(uint256)","b8c7e354":"tryToCompleteProject()","b8c86aa6":"getArraySettingResult()","b8c87a06":"setStage3()","b8c8fb73":"solve(uint256,uint256,uint256,uint256)","b8c92537":"acceptBidForCollectible(uint256,uint256,uint256,int256)","b8c9371d":"getPassOwner(bytes32)","b8c963a6":"atxContract()","b8c9c4d2":"burnResource(uint16,uint256)","b8c9d365":"h()","b8c9e4ed":"getStr()","b8c9e694":"getRaceMutation(uint32)","b8cb243d":"escrowTransfer(uint256,address)","b8cb40e0":"getDistributedTotal()","b8cb65ee":"removeTokens(uint256)","b8cc3c12":"depositToSubRound(uint256)","b8ccbd17":"removePermission(bytes4)","b8ccc682":"constructUrl(bytes32,uint256)","b8ccf4c7":"sendPositiveWhuffies(address,string)","b8cd0b94":"DoorLock()","b8cd4a8e":"joinCarveUpTen(uint256)","b8cd81ed":"raffleTokenReward()","b8ce670d":"burn(address,uint256,address)","b8cf14e7":"updateStatusPlayer()","b8cf2515":"currentFundrise()","b8d00d4a":"requestErc20Transfer(address,address,uint256)","b8d04f4e":"getReferrerAddress(address)","b8d08db2":"releaseCount()","b8d0cf4a":"setTokenPriceUSD(uint256)","b8d117fc":"bonusEnds4()","b8d1194c":"tokenGoal()","b8d16dbc":"isLeapYear(uint256)","b8d2f523":"no_aff()","b8d364bb":"allDistinct(address[5])","b8d3bfe3":"MeatGrindersAssociation(address,address,uint256,uint256,uint256,address)","b8d3d08a":"assertEq29(bytes29,bytes29)","b8d400d2":"fromEthers(uint256)","b8d415c9":"bntyMicrodollarPrice()","b8d46c9c":"setOrUpdateRecord2(string,string,string,string,address,uint8,bytes32,bytes32)","b8d4b642":"startICODate()","b8d4efb5":"validate_percent(uint8)","b8d55a91":"CPLToken()","b8d5b7f0":"maximumToken()","b8d73101":"expirationString()","b8d73849":"LogTokenDeposit(address,uint256,bytes)","b8d74f4b":"getAcceptedTokenAmount(address)","b8d85d23":"adminSetAddress(address)","b8d87069":"_removeContributor(uint256)","b8d94039":"writePosition(uint256,int256)","b8d94b95":"buildDSNullMap()","b8d9cbbe":"addMember(address,uint256,uint256,uint256)","b8daf1b1":"cancelChainlinkRequest(bytes32)","b8dbf876":"transferFromOwner(address,address,uint256)","b8dd3c55":"confirmSettingsChange(uint256)","b8dd7a5b":"numberOfWagersToMinimumTimeout()","b8ddc4df":"HPA_TokenERC20(uint256,string,string)","b8ddef1a":"IdeaCoin()","b8de3843":"allAmountRaised()","b8de85d8":"p_setBankOfEthAddress(address)","b8df17f0":"verifySigner(bytes32,uint8,bytes32,bytes32,uint256,uint8,uint256,bool)","b8df5ce3":"ownerInitialBalance()","b8e010de":"set()","b8e046d1":"MinexoDigital()","b8e0d08d":"increaseHardCap(uint256)","b8e0ffbe":"getPaymentsLength()","b8e2cfb1":"getMinMaxInvest()","b8e31ee7":"MithrilGauntlet()","b8e381e5":"subscriptions()","b8e3d8e8":"LOL()","b8e3e6da":"participateCrowdsaleAll()","b8e4189c":"updateHighestMiles_(uint256,address)","b8e42041":"invalidateOrdersBefore(address)","b8e44852":"chargeTokensForManagement()","b8e60467":"LRCMidTermHoldingContract(address,address)","b8e6a433":"calcFactorReward(uint256)","b8e920de":"buyTicketTest2(bytes)","b8e945fc":"setOwnerNick(uint256,string)","b8e9a6f0":"addLockedAccount(uint8,address,uint256)","b8e9ac71":"BICToken(uint256,string,string)","b8e9c22e":"getRate(address,uint256,bool,uint256)","b8eaffcc":"getnodeparam(address)","b8eb115e":"increaseDuration(uint256)","b8eb3546":"maxSell()","b8eb993d":"PUBLIC_SALE_TOKEN_CAP()","b8ebed78":"rightForInterest(uint256,bool)","b8ec59e4":"changeColorOrange()","b8eddde1":"paymentsOwed(address)","b8ef04e7":"_getRandomNumber(uint256,uint256)","b8ef5f4d":"nextGameSeedPercent()","b8ef9fcc":"cardAddressExists(address)","b8f20cfd":"myBalances()","b8f249e2":"testThrowsSaleWalletIncorrectSaleAddress()","b8f2690d":"TestDividendFund()","b8f28531":"notEqual(address,address,string)","b8f2954d":"addData(bytes32[],bytes32,bytes32,bytes32,uint256,uint256,uint256,uint256)","b8f2bbac":"modify_perms(bytes32,bytes32,int256)","b8f3b75d":"buyWithAddress(address)","b8f47481":"withdrawErc20ForAddress(address,address,uint256)","b8f48d3d":"setMaxRoundSize(uint256)","b8f53f36":"maxPrivateSaleStage()","b8f5e56c":"DeClub(uint256,string,string)","b8f6c219":"purchaseDatesToken(uint256)","b8f6d3ef":"getNodalblockData(string)","b8f6e7ff":"changeMarketStatus(uint8)","b8f71f26":"scheduleTransaction(uint256,address)","b8f75c0b":"bountyFactory()","b8f76562":"setWithdrawable(address)","b8f77005":"getQueueLength()","b8f78178":"createNameAndPoint(int256,bytes32,address)","b8f7a665":"isLive()","b8f7f41e":"drpCrowdsaleRecordedBalance()","b8f929ad":"saleWhitelist()","b8fa7778":"for_votes()","b8fbb72d":"COMMON_WITHDRAW_SUPPLY()","b8fbb87d":"isAssociatedAddressFor(uint256,address,address)","b8fbe499":"Cygnus()","b8fc7bd0":"setPresidenteDeMesaVerify(bytes32,uint256,uint256,uint256,bytes32)","b8fcf937":"myToken()","b8fd1e10":"updateBalancesContract(address)","b8fd1ffa":"addressToEtherOwed(address)","b8fe6f93":"triggerTransaction(uint256,uint256)","b8ffc962":"isMaxSupplyLocked()","b8ffd53f":"getStageStartTime(bytes32)","b8ffd64b":"PowTokenBase()","b9002e62":"delegatedFwd(address,bytes,uint256)","b900a870":"getApprenticeChestPrice()","b900da19":"calculateBonusPercentage(uint256)","b9019437":"eitherHaveAttribute(address,address,bytes32)","b9022e44":"updatePresaleWhitelist(address[],bool)","b90291c3":"changeWebsite(string)","b902c833":"switchfor()","b90306ad":"Burn(uint256)","b9037bc2":"unlockTokensForAddress(address)","b903a2a5":"MultiTransfer(address[],uint256)","b904088e":"maximumInvestment()","b9043235":"_create(uint256,address)","b90436ba":"MBT()","b9045c00":"InvestCoin()","b904ef4a":"delUIntValue(bytes32)","b9068d9e":"distributeFunds(uint256,address,address,address)","b906b7b7":"burnPercentage10m()","b9078616":"executeTrade(address,address,uint256,uint256)","b907996a":"Forwarder()","b9089280":"admin_del(address)","b908b008":"verifyTx(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[1])","b9093fc6":"addIdentity(address)","b9098b33":"krs()","b90a4df1":"ApushJoustUser(address,address)","b90ae5a1":"registrarAuth()","b90b0108":"iconcontract()","b90b09c0":"random_bool(uint8)","b90b1248":"extractTokenEth(uint256)","b90b9aea":"EOCToken(uint256,string,string)","b90c1dbb":"getCreationDate()","b90c8566":"Somplak()","b90c86a9":"LogOraclizeCall(uint256,bytes32,string)","b90c92e2":"FysicalToken()","b90cec6d":"AddOfficialApps(address)","b90d3d0c":"data(address)","b90d86b9":"autoMatch()","b90d89a0":"start_seller(address,address,uint32)","b90da496":"getRankTitle(uint256)","b90dcc58":"SAFEToken(uint256,string,string,uint8)","b90e6bd8":"userRound(address,uint256)","b90f1af1":"icoEndUnix()","b90f65a2":"canCancelBet()","b910378d":"getBI(bytes32)","b91038c7":"participate(address)","b9103e1f":"refundAction(bytes32)","b9106dd9":"setAllowAccess(address,bool)","b91070e8":"processEmergencyFundReleaseFinished()","b9119b87":"ChangeSwapperAddress(address)","b911f2fb":"settleCandyGetx(uint256)","b912950e":"buyItemRaffleTicket(uint256)","b91366b0":"upgradeReactor()","b9138584":"Deedcoin()","b9140422":"readMailByAdmin(uint256,bytes16,address)","b9144c96":"TokenMinted(address,uint256)","b9145944":"verifySig(address,bytes32,bytes)","b914cf7c":"leve1(address)","b9156830":"hasPriorDuplicate(string,uint256)","b9166178":"investorWallet(address)","b916c5ff":"redeemCoupons(uint256,string)","b916de59":"reset(address[])","b916e5d0":"goldenTokenId()","b916f8fd":"delistMon(uint64)","b9172dec":"changeStage(uint8)","b9174330":"gco(uint256,address)","b9186d7d":"priceOf(uint256)","b919be66":"useMultipleItem(uint256,uint256,uint256,uint256,uint256)","b91aedab":"transferLocked(address,uint256[],uint256[])","b91bb31c":"initLottery(uint256,uint256,uint256)","b91bf310":"initialChargeFeePool(address)","b91c771f":"replaceProduct(address,address,address,address)","b91d1aed":"createPassport(uint256,bytes32)","b91d3ace":"addDev(address)","b91d4001":"releaseTime()","b91d4a0f":"frontWindowAdjustmentRatio()","b91dee6c":"ResetUpdateState()","b91e3422":"premiumHold()","b91e4087":"validAddresses(address)","b91fe64b":"getLastDepositDate()","b9204d1c":"TeamVestTimeLimit()","b9209e33":"isVerified(address)","b920c799":"Insureum(uint256,uint256)","b9212662":"s13(bytes1)","b921e163":"increaseSupply(uint256)","b9223946":"endVote()","b9224385":"LogResultWinner(uint256,address,uint256,uint256,bytes)","b92289ef":"sendleftmoney(uint256,address)","b9235d08":"FlippedCoin(address,uint256,int256)","b923b205":"setWhitelist()","b9247673":"buyListing(bytes32,uint256)","b9256f7e":"newTickerQueryResult(string,bytes32)","b925af47":"creatorsTotalBalance()","b92620bd":"targetWallet()","b926bd06":"Prepurchased(address,uint256,uint256,uint128,uint256)","b9272a11":"_redeemAdoptedAxies(address,uint8,uint256)","b927ef43":"validatorSetApplyBlock()","b928024d":"tokensPerWeiBonus250()","b9291296":"useMyOldName(string)","b9292158":"getTimestamps(address)","b929709a":"getPOOL_edit_1()","b92984f8":"TokenGame()","b92a3961":"currentRoundBudget()","b92a56bf":"deathData_v10()","b92ae87c":"isSubscribed(address)","b92b9d6c":"replacePublisherRegistry(address)","b92cb5b8":"addBrick(uint256,string,string,uint256,string,bytes32[],uint256)","b92cc8cf":"isExisting(uint256)","b92cd8f1":"officalHolding()","b92ce1a7":"createRandomCharacter()","b92d6c2f":"TWCToken()","b92dd395":"setManagerPowerful(bool)","b92ddee6":"setStartTimeIco(uint256,uint256)","b92e9f9e":"reportWasCalled()","b92edfc6":"NumberOfAuctions()","b92f1986":"IMDEXinvalidateOrdersBefore(address,uint256)","b9308d9e":"updateName(address,string)","b9318b0c":"_born(uint256,uint256)","b931b484":"bountyTokensLeft()","b931bec5":"setContractErc20Token(address,address)","b9324db6":"upgradeCardShield(uint256)","b9330829":"maxUint256()","b935170b":"addShopOwner(string,string)","b93529bc":"tokenTicketPrice()","b9358ba4":"isApper(address)","b9359169":"GayPersonalAds()","b9364835":"getCatOwner(uint256)","b93651bb":"__initFuse()","b9368721":"balancesRiskcoins()","b93806ab":"setWinningNumbers(uint256,string)","b9381f3c":"checkCapsAndUpdate(uint256,uint256)","b93833c3":"changeRewardAmount(uint256)","b9384f12":"changeMinCapUSD(uint256)","b938b469":"SetRewardMultiAD(uint256)","b938bf42":"sendBounty(bytes32)","b93983dd":"StoxSmartTokenSale(address,address,uint256)","b93a4408":"setMintFrequency(uint256)","b93a50b0":"_setApprovalForAll(address,bool)","b93ab165":"getCurrentInfo()","b93c109f":"totalInterests()","b93c3de2":"getHistoryRoundList()","b93c7d42":"sellDividendPercentCandy()","b93dab0b":"getBetCount()","b93dc802":"setEth(uint128[2])","b93e0e39":"ROCK()","b93ea812":"subtract(int256,int256)","b93eb763":"x(int256,int256)","b93f9b0a":"getAddress(uint256)","b93fd2bf":"createCustomAtom(uint64,uint8,uint8,uint8,uint128,uint128,uint32)","b9408373":"USD_PER_ETH()","b940db1a":"sellAllDolAtOnce()","b9413c47":"totalReturnedCredit()","b9420310":"tokenSale()","b942394d":"getPercent2(address)","b94265b8":"addReferrer(address,address)","b9429069":"isFarmer(address)","b94371ec":"getWhitelistOwner()","b9447f7e":"customBuyerForIndex(uint256)","b944ef3c":"initialTraining()","b94512c7":"BioCoin()","b9459b70":"getCurrentLuckyStonePrice()","b9460d04":"updateTicketVault(uint256,uint256)","b94669e5":"interfaceThawTokens(address,uint256)","b9468f7e":"bid(uint256,bool)","b946c19c":"rankDataContract()","b946fab1":"maxAmountPresale()","b9474959":"_isTokenOperator(address,uint256)","b94761b4":"SetupAllowance(address,uint256)","b94776de":"mintUnlockTime(address,uint256,uint256)","b9478ade":"DylanCoin(uint256,string,string)","b948348c":"purchaseTicket(uint256)","b94844dd":"AAAToken()","b9484955":"getInvestorArray()","b9488546":"ownersCount()","b9499cd6":"Midwife()","b94b0a3a":"getFulfillment(uint256,uint256)","b94bae91":"setUser(address[])","b94bc7fe":"proofOfSalt(bytes32,uint8)","b94c3451":"techBuff()","b94cc52f":"mark(address,bytes32)","b94e3516":"TAKCoin()","b94e962a":"allocateTickets(uint256)","b94ee0fc":"Triunvirate(address[])","b94f5a6e":"eventPirze(address,uint8)","b94f969c":"investmentBTC()","b94fa03f":"requiredSharesToBeBoardMember()","b94fb4a3":"WaykiCoin()","b94fdaab":"upload_group_key(uint256[4])","b950556a":"setThingValid(bytes32[],bool)","b950ae2b":"changeTopWithdrawable(uint256)","b950f0a0":"rateTier3()","b95254f6":"setAsLotteryRunner(address,bool)","b952ab7b":"unclaimedTokensForInvestor(address)","b9531df3":"lowTimeBonusLimit()","b953a9ac":"getDocumentProposalCount()","b9541ad5":"resetReferee(address)","b95459e4":"moduleRegistry()","b95460f8":"open(address)","b954ca70":"setcapbounus(uint256,uint256,uint256)","b95594e5":"lineOfPlayers(uint256)","b9559685":"StateHolder()","b955b95c":"getKindOfPackage(address)","b955e60d":"roundData(uint256)","b956a8a6":"easyMineToken()","b9570c01":"transferAndCall(address,uint256,bytes32)","b957aeb6":"getUserReaction(uint256)","b957b886":"stackOffset(uint256)","b9582195":"SFXToken()","b958893e":"XTVAirDropped()","b9588adc":"getStageAttributes(uint8)","b958a5e1":"getPhoneByAddress(address)","b958abd5":"setA(string)","b9592e92":"setGM(address)","b9599f3a":"fetchUndistributedProfit()","b95a4baf":"daysSinceLaunch()","b95a8327":"marketGrapes()","b95af889":"processTransferToICAPResult(address,bytes32,uint256,bool)","b95bb4f8":"price(uint16)","b95c2740":"buy(address,bytes)","b95cbed6":"currentExpiryInterval()","b95d2a53":"deedUri(uint256)","b95f2be8":"_releaseVouchers(address,uint256)","b960a45f":"unpauseTrueUSD()","b960a6d4":"ITTMultisig()","b96144fd":"removeUsername()","b9615878":"getHeader(bytes32)","b961716b":"getActiveTier()","b961b1e0":"teamNamingIncome()","b96297b5":"killya()","b962de9a":"ProsperaToken(uint256,string,uint8,string)","b9632689":"numFunders()","b9635685":"JAJToken()","b963e1d0":"getPurpouse()","b964608d":"get_return_by_level(uint256)","b9649e52":"getPlayerPotWinning(uint256,uint256,uint256)","b96528fd":"pubAddress()","b9653382":"firstPeriodEndDate()","b965817d":"UBSCoin()","b9659d4a":"sibling()","b9668eb2":"settleUnclaimedPerTokenPayouts(address,address)","b966f350":"tokenMintingEnabled()","b96732d9":"TransferToSAToE(uint256)","b9676e72":"SPTToken()","b967a52e":"setContactInformation(string)","b968440a":"Finalized(uint256,uint256)","b968486e":"isLottoStarted()","b96890a1":"airdroptoken()","b96891e5":"getAddressesSize()","b9689cf3":"crowdsaleAirdropAddress()","b968a53c":"getBurnAddresses()","b969d399":"getBattleCooldown(uint64)","b96a39bd":"createPlayer(string,uint256,uint256)","b96b8edf":"changeAirdropQty(uint256)","b96bf2b5":"expressReloadNumSec(uint256,uint256,uint256[],uint256[])","b96c0866":"completeOrder(string)","b96c10ba":"_assign(address,address,address)","b96d64fb":"start_quiz_game(string,string)","b96dc22a":"enableLambo(uint256)","b96dc96d":"delCertificate(string)","b96e988b":"addressBilborough()","b96f54d1":"fixedReverse(uint256[10])","b96f8a39":"Voting()","b970e3d0":"JATICO()","b971667c":"calculateEmissionTokens(uint256,uint256,uint256,uint256)","b9717b23":"setOdd(uint256,uint256,uint256)","b971a1f8":"VivekTestToken()","b971b4e5":"setNotTransferable(bytes20)","b9727dc2":"getProjectClient(uint256)","b9727f50":"saveRevenueShareDistribution(address,uint256)","b97386d1":"reputationProblems(address,bytes32)","b973b286":"Imteaz()","b974b0a3":"allData()","b974ddcb":"getAnimalById(uint256)","b9750acf":"selfDestroy()","b97585d3":"addOldNickname(address,string)","b975ce23":"crownName()","b975d9c7":"setCCH_edit_32(string)","b976b35b":"uponTransfer(address,address,uint256)","b976f464":"authoriseAccount(address)","b9774f7b":"confirmations(uint256)","b9776301":"testTrustedTransferFrom()","b9789d7d":"ChangeDeadLine(uint256,uint256,string)","b97a6c12":"redeemForReportingParticipant()","b97a7d24":"getGoal()","b97af2c8":"setTokenDecimals(uint256)","b97b451e":"increaseApprovalPreSignedCheck(address,address,uint256,uint256,uint256,uint8,bytes)","b97b9df8":"AUACoin()","b97cab2c":"convert2Peony(uint256)","b97ce4d3":"distributionteamFinished()","b97d3627":"TosToken()","b97df70a":"setTokenReward(address,address)","b97e3b43":"setMintAgent(address,address,bool)","b97fd9e1":"releaseWallet(address)","b9812d9a":"getNextReportingWindow()","b981655f":"DebtManager()","b9818be1":"feeOwner()","b982e5c1":"testAddPending()","b9843c7c":"setUnavailable()","b9844d6f":"updateSelfDropStageState(uint256,uint256,uint256,uint256,uint256,uint256)","b9855c76":"restartPeriod()","b9858a28":"addContract(address,address)","b986b611":"withdrawAddressUpdate(address)","b986bb67":"STATUS_DESTROYED()","b9871548":"set_token_address(address,string)","b9879450":"CREATOR_TOKEN()","b987ae02":"fundWithdrawal(uint256)","b987bdac":"InterCrypto()","b987f688":"gettotalCards()","b9883b3f":"main(uint16,uint8,int256)","b988899f":"setBenificiary(address)","b988c505":"newProposal(address,uint256,string,bytes,uint64)","b9890a74":"initBonuses(string)","b989915c":"lastUsdPerEthChangeDate()","b989c7ee":"returnInt32(int32)","b989ffa7":"getArtist(bytes32)","b98a5418":"assignedAmountToAngelInvestment()","b98aacf0":"retreiveHrt(string)","b98b5f9c":"listPrycto1()","b98bafde":"Redeemed(uint32,address)","b98bcf16":"getPubKeyByHash(bytes28)","b98c90c2":"ECOS(address)","b98cb57e":"rinkeby()","b98d49a5":"getSponsorshipCount(address)","b98dbb50":"updateprojectDuration(address,uint256)","b98de7c7":"setLive()","b98e2769":"sketchNoLongerForSale(uint256)","b98ef00d":"disclosureList(uint256)","b98f0992":"TokenRK50Z()","b98f5932":"getUserExp(address)","b98fa504":"AddTower(uint32,uint16,uint16,uint256,uint256,uint16,uint16)","b98fb437":"getethused(address)","b98fdc36":"IconomiToken(uint256,string,uint8,string,uint256)","b990033e":"setNewRegister(string,bytes32,uint256)","b9902eef":"Rate8()","b9908cbb":"maximalIndividualContribution()","b9910c5f":"JixoCoin(uint256,string,string)","b991357c":"isAdvisorsTokensThirdReleased()","b99152d0":"balanceOfToken(address)","b991bc14":"direct_refunds(address[],uint256[])","b991f607":"Bank(uint256,uint256)","b9926d1d":"limitBuy(uint256)","b992812e":"hasIssued(address)","b9931d30":"getPlayerToken(uint32)","b9934b9e":"ownerResumeContract()","b99371a0":"GetPrestigeInfo(uint256)","b993a53e":"preSaleBalancesOf(address)","b993a91f":"migrationAccountCounter()","b993c871":"NGToken()","b995b014":"_exploreUsingEmont(address,uint256,uint256,uint256)","b995ce4d":"returnTokenAddress(uint256)","b99613cb":"getPlayRecordNoTurnData(address,address)","b99798e8":"accFounder()","b9980306":"processARvRevForecast()","b9981a67":"firstBalanceOf(address)","b9997819":"ownerSetHouseEdge(uint16)","b999abbc":"Spole()","b99a8a00":"exchange_coefficient()","b99ac856":"roundin(address)","b99b2f81":"myReferrals()","b99b951d":"claimTokensE(uint8)","b99c2b51":"_getWinAmount(uint8,uint8,uint8,uint24,uint256,uint256,uint256,uint256,uint256)","b99de11e":"endThirdWeek()","b99dfe18":"getPackage(uint256)","b99ec99a":"AuditorRegistryReplaced(address,address)","b99eccc1":"SplitWeighted(uint256)","b99f1d02":"claimClusters()","b99f247d":"ERGCOIN()","b99f48d5":"promisedPop()","b99f6073":"tokenPurchased()","b9a0157e":"setArrayIndexValue(bytes32,uint256,bytes32)","b9a0a708":"testChargesAmountApproved()","b9a0c1bb":"_approveRobot(uint256,address)","b9a1bd86":"registerPrivateContribution(address,uint256)","b9a2131b":"ContractTST()","b9a29d42":"getKevin()","b9a2de3a":"endAuction(uint256)","b9a30afb":"HelloGoldSale(address,address,address,address)","b9a41409":"gcpa(uint256)","b9a45aac":"whitelistAddress(address,bool)","b9a4a755":"afterApproveAction(uint256)","b9a4defe":"changeTargetAddress(address)","b9a52203":"saveRN(uint256)","b9a527b4":"book(address,address,uint256,uint256)","b9a54062":"getMaximumWritesPerStep()","b9a59b83":"isEngineerContract()","b9a5a2d9":"numberOfApprovedSteaks()","b9a5e073":"contracteesSize()","b9a60038":"totalTransactions()","b9a68300":"bountyOnlineWallet()","b9a6e94c":"buyTile(int32,int32)","b9a6f7b0":"BTHB()","b9a804fb":"ArrowTestCoin()","b9a82f80":"buyPepe(uint256)","b9a904f9":"testUnauthorizedSetBetaPackage()","b9aa8236":"getMaxAgonId()","b9aaaeee":"populateTierTokens()","b9ac0524":"icoEtherReceivedTotal()","b9ac38aa":"test_newProposalAndVoting()","b9aceb63":"BuyTicketUseVault(address,uint256)","b9ad36b9":"prophecise(bytes32)","b9ad771c":"registerHWCWit(string)","b9ae4bda":"associatedPubkeys(uint256)","b9ae7364":"pauseAuction()","b9af809e":"getMinEthersInvestment()","b9afd6e1":"returnChildAddressForParent(address)","b9b162c3":"calculateTop5HeroesPower(address,address,uint256)","b9b1c90c":"moveToSafetyWallet()","b9b237c2":"tokenFunded()","b9b26bd2":"registerBroker()","b9b2a331":"setAccPrice(uint256)","b9b2a890":"rewardDaily(uint32,uint32)","b9b2b5cd":"totalFeeCollected()","b9b3ded2":"createDividend(uint256,uint256)","b9b42602":"ethRefunds(address)","b9b43faa":"createInt256s(bytes32[],int256[])","b9b466ab":"myLoveBlockCount()","b9b6990b":"getUserBetsInARazInstance(uint256,uint256)","b9b6c2d4":"getAmountOwed(bytes32,address)","b9b7238b":"addInvestorBonusInPercent(address,uint8)","b9b7569b":"isGameLogicContract()","b9b7b68c":"limitbreak_contrib()","b9b842e5":"setCandyLand(address)","b9b8af0b":"halted()","b9b8c246":"invest(address,uint256)","b9b8e25d":"getRemainingTokensToSell()","b9b94997":"repossessBooking(address,uint256)","b9ba2926":"receivedCollateral()","b9bac5f8":"lockedUntilTime()","b9bcf81f":"getTlength10()","b9bd4f76":"newSale(uint256,uint256,uint8,uint256)","b9bda244":"sumICO()","b9bdbbbb":"FILMToken(uint256,string,uint8,string)","b9beadae":"testCantBuyTokensInEndedSale()","b9beeb8d":"DatingCoinToken()","b9bf068e":"getUncompensatedContributors(uint256,uint256)","b9c009f0":"checkContributorBalance(address)","b9c0d227":"defaultTokensPerWei()","b9c105cf":"getTaskRewardAndStatus(bytes32)","b9c1a60a":"econReserveAllocation()","b9c2c6fb":"removeMember(bytes32)","b9c2ee82":"upgradeController(address)","b9c3395f":"getTokenAmountBonus(uint256)","b9c3515c":"votingActive(bytes32)","b9c390aa":"SaferEcRecover()","b9c3a818":"TEAM_SUPPLY()","b9c4d0a7":"fundOrder(uint256)","b9c53d04":"SECCoin()","b9c5be85":"allocatePurchase(address,uint256,uint256)","b9c5eb90":"updateVoucherMthRate(uint256)","b9c7ce49":"totalIssuingCollateral()","b9c81f1d":"Membership()","b9c8464d":"extractFees(uint256)","b9c8559d":"RocketPoolReserveFund(address)","b9c89ff7":"getTargetRepMarketCapDivisor()","b9c97a44":"UnlockAccount(address)","b9c99e5e":"DepositUnfrozen(address,uint256)","b9caebf4":"del(address)","b9cb385d":"invitedInit(address,address)","b9cb5b5f":"HatchEggs()","b9cbbb62":"testInequalityAddr()","b9cc8b48":"oraclizeOn()","b9ccaed2":"getMesas()","b9cce72c":"addFlag(bool[2])","b9ce10d5":"Fyle(string,string,uint8,uint256)","b9ce795f":"createVoter(string)","b9ceda19":"updateTokenNameAndSymbol(string,string)","b9cf01a1":"Cardiology()","b9cf9d49":"getNextOrderUser(address,address,uint256,address)","b9d0a638":"Bro()","b9d1d49b":"minimumBalance()","b9d1ed4a":"ethDeposits(address)","b9d1fd60":"fundingMaxAmount(address)","b9d2fa35":"disableFundingWallets(address)","b9d3514d":"addEventToUser(address)","b9d36743":"priceToMint(uint256)","b9d414bd":"setSecurityTokensWallet(address)","b9d47fff":"mySubdividends()","b9d5205c":"SASH()","b9d54f6f":"setMinPurchaseLimit(uint256)","b9d5d7fe":"resetUserPicture(string)","b9d6257d":"DeletePool(string)","b9d677f9":"_buyProp(uint256,uint256,uint256)","b9d69a30":"sendTo(address,address,uint256,bytes)","b9d723eb":"startNewPeriod()","b9d7fdf4":"bonusTierSize()","b9d8350e":"getWeiFromUsdCents(uint256)","b9d92de8":"calculate(uint256)","b9da4033":"_randBySeed(uint256)","b9da706e":"LandSale(address,uint256,uint256,uint256)","b9da8360":"_setBattleContract(address,address)","b9db15b4":"getProduct(uint256)","b9db9a6d":"resetAllApproval()","b9dc25c5":"approvedUser()","b9dda7b8":"_ERC20Contract()","b9de1c41":"buyRaffleTicket(uint256)","b9deb729":"isTransferEnable()","b9dedc6a":"shareTransfer(address,address,uint256)","b9df2d22":"isGameRunning()","b9df819f":"receiveFunds(address,address,uint256)","b9dfaf3a":"setPriceChannelMaxSize(uint256)","b9e01aeb":"buySpaceshipUpgrade(uint256,uint16,uint8)","b9e04eea":"withdrawStuckEtherOfAmount(address,uint256)","b9e15a67":"coinAgeForAddress(address,address)","b9e16b65":"issueDescription()","b9e1aa03":"deposit(address,bytes32)","b9e205ae":"updateExchangeRate(uint256)","b9e290f9":"setValue(bytes32,address)","b9e328de":"GIDIDAX()","b9e3a8dd":"isCompositionOnlyWithBaseLayers()","b9e3e2db":"releaseDate()","b9e3ee01":"addNodeToWhitelist(address)","b9e448df":"OpenFund(bytes32,string)","b9e4d098":"setNewEndDate(uint256)","b9e58ab0":"setPropertyOwnerSalePricePrivateModeFlag(uint16,address,uint256,bool,uint8)","b9e5e2c4":"ratePerWeiInPreICO()","b9e6152b":"process(address)","b9e6ac68":"TabTradersToken(address,address)","b9e6edcf":"s15(bytes1)","b9e6f1d9":"get_amount()","b9e70ed6":"setLoanParameters(address,bytes32,uint256,uint256,uint256,uint256,uint256,uint256)","b9e722cd":"caddress()","b9e77649":"OVISBOOKED_TOKENS()","b9e7afd1":"__setSecretaryGeneral(address)","b9e7c061":"tempGetDataToCheck(uint256,uint256)","b9e7e2f9":"Beercoin()","b9e8574f":"getReservedDestinationInfo(address)","b9e95382":"store(uint32)","b9e99231":"EEM()","b9e9d1aa":"futureOwner()","b9e9e441":"exchangeTokensByAddress(uint256,address,address)","b9eb04f3":"hashPosition(uint32,int64,bytes16)","b9eb5511":"setPI_edit_5(string)","b9eca0c8":"gID_()","b9ed6df8":"withdrawEtherFromcontract(uint256)","b9ed93e9":"setWaitTimeBlocks(uint256)","b9edf911":"approveBulk(address[],uint256[])","b9ef7835":"infect(bytes32)","b9f10278":"EtherPredictx()","b9f14557":"unban(address)","b9f1fb62":"transferPrivateReservedUFT(address,uint256)","b9f2086b":"BlockWar()","b9f24e44":"freezeGame(uint256)","b9f256cd":"newProposalInEther(address,uint256,string,bytes)","b9f28076":"historyIdx(address)","b9f2d592":"maxAllowedReservingPercentage()","b9f308f2":"getEtherForTokens(uint256)","b9f37c86":"Registrar()","b9f4657d":"approve_tx(address,bytes)","b9f48cad":"performAction(address,bytes,uint256)","b9f4b5c2":"refundStart()","b9f615d7":"bankRollInvest()","b9f696d5":"setNote(uint256,bytes32,string)","b9f71934":"promotionsOfClaimant(address)","b9f7d242":"restoreAllPersistentTokens(uint256)","b9f89751":"withdrawAsCreator()","b9f96247":"SellMulti(uint256[],address)","b9f9d9a5":"test_insert_findNoHintAtPosition()","b9fa2055":"capETH()","b9fac520":"BIU()","b9fb0579":"Transfer_of_authority(address)","b9fb3ff8":"BOOYAHTEST()","b9fb7b8c":"Deposit_referral()","b9fbe331":"bonusTokenRateLevelOne()","b9fea3bb":"setBaseInfo(address)","b9feeb05":"GetCategoryCount(string)","b9ff5fcf":"getMakerBetDetails(uint256,address)","b9ffc576":"RevalootSwap()","ba001de3":"revokeBountyTokens(address,uint256)","ba00660f":"publicWithdraw()","ba00ab60":"cancelAuthorizations(address,address[])","ba0179b5":"confirm(uint256)","ba02021d":"redeemTicket(uint256,address)","ba029c97":"wei20()","ba02cf47":"MORTU()","ba02e9f2":"Coincirculationchain()","ba02f006":"_concat(string,string)","ba030c8c":"endRefundingingTime()","ba033fe1":"buyAndTransfer(uint256,address,address,bytes)","ba0410fb":"changeExhangeRate(uint8)","ba044799":"setDropable(bool)","ba057826":"MDXToken()","ba065e1f":"expired(uint256)","ba067f59":"setToSendLeft()","ba075da2":"undermineComponent(uint16,uint256)","ba081b8d":"PHOENIX_POOL()","ba086518":"delist(uint16)","ba087b9d":"balanceOfAtType(address,uint256,uint256)","ba08809d":"showTimeLock(address)","ba08f299":"decrementTotalIssuerCount()","ba09591e":"setSellFloor(uint256)","ba0a272b":"icoEtherReceivedPreFirstSale()","ba0a4ca9":"_safeGasStaticCall(address,bytes)","ba0a93a8":"getRankOnePlayer()","ba0b9788":"setTitulaire_Compte_7(uint256)","ba0bafb4":"currentWindow()","ba0bba40":"setup()","ba0bc2f4":"initialCardPrice()","ba0bf0c4":"weiMaxInvestment()","ba0bface":"managementBodyAddress()","ba0c1777":"ecoLock13()","ba0c9b54":"mcs()","ba0cf581":"findDispute(address)","ba0d291b":"CashMateToken()","ba0d46f3":"BoraToken(uint256)","ba0d94a8":"Bcigarcoin()","ba0df427":"sumOf(uint256[])","ba0e0f5e":"removeTrustedAccount(address)","ba0e6cc9":"removeVerified(address,address)","ba0e930a":"transferManager(address)","ba0f5b20":"getDarknodeBond(address)","ba0fbf0d":"_saleTokens()","ba102763":"etherToSendSecurityPool()","ba1066ed":"pendingAmount()","ba10db46":"transferEthHandleOwnership(bytes32,address)","ba112d50":"setDataEquip(address)","ba1162d7":"getFmLength()","ba119e5a":"SEBCToken()","ba11ecde":"preSaleOpen()","ba124401":"FrozenGuard()","ba13a572":"lottery()","ba14d606":"test(address,uint256)","ba151ad9":"USD_PER_TOKEN()","ba157d46":"setWebGiftEtherAmount(uint256)","ba15e52e":"getInfo(bytes20)","ba15fcaa":"Tremendoustoken()","ba16ae2d":"WBET()","ba16d600":"minReward()","ba16e00e":"bonusEnd05()","ba17e592":"performWrite1()","ba1803c1":"setCryptoJinglesContract(address)","ba181ac6":"setWhitelist(address,address)","ba1a2243":"setTokenPaymentCustomer()","ba1ad438":"newFee(uint256)","ba1af80f":"phase4Price()","ba1b44da":"getBoardRating(address,uint256)","ba1b6221":"calcUnMaskedGuEarnings(uint256,uint256)","ba1c0201":"evRefund(address,uint256,address,uint256,bool)","ba1c3b92":"setSalePeriod(uint256,uint256)","ba1ccbee":"getSupportedRolesCount()","ba1cd983":"unitCreationFee()","ba1d8d4f":"createAutoridadElectoral(bytes32,bytes32)","ba1f879f":"privateSale()","ba1fd9f4":"widraw(uint256,address,bytes32)","ba209dab":"rejectCertification(uint256)","ba20dda4":"getBeneficiary(bytes32)","ba21d62a":"Command(address,bytes)","ba2318ca":"totalSaleSupplyCap()","ba236abe":"getMyWinAmount(address)","ba255cd1":"liquidAllocatable()","ba25a585":"EventUpgradeTank(address,uint256,uint8)","ba25d944":"longDescription()","ba278e08":"setStartTime(uint256,uint256)","ba285f5d":"minimalPaymentInWei()","ba286ee3":"testRegisterCustomer()","ba2902fb":"rehancoin()","ba2a730b":"getAddressLastUpdate(address,address)","ba2a98f2":"closeZoneShop(bytes2)","ba2ab079":"changeEndPrivateSale(uint256)","ba2aee26":"addGains(address,uint256)","ba2d5c88":"MINBET_perTX()","ba2e84f9":"publicsalesCap()","ba2eb541":"isExpired(address)","ba2ee51f":"ICO_TOKENS_AMOUNT()","ba2ee65c":"manage()","ba2eebb4":"transferControl(bool)","ba2fa957":"markettingPercentage()","ba3019de":"fwdPaymentAndData(address,bytes)","ba3025d4":"epicenter_works_addr()","ba32348f":"reffUp(address)","ba32694c":"howCoin()","ba33a876":"VBToken()","ba34251b":"usdToEthPrice()","ba344304":"Lydian()","ba344743":"_rawTransfer(address,address,uint256)","ba346d11":"ArenaPool()","ba34c8f1":"setrate(uint256)","ba353925":"paymentDisable()","ba35749c":"deleteOffer(bytes32,address)","ba35b1d3":"TxMessage(uint256,uint8,uint256)","ba35c0be":"changeSelectFight2DeathContract(address)","ba35f38d":"eip20TransferFrom(address,address,address,uint256)","ba3603fd":"usdPerMEth()","ba36f423":"att()","ba3717c0":"setStrF1F2(string,string)","ba376923":"Cez()","ba377731":"getSupplyBalance(address,address)","ba37caa4":"exchangeStaStb(uint256,uint256)","ba386f0b":"propertyIdToAuction(uint256)","ba38743b":"GrabUnallocatedValue()","ba38c599":"announced()","ba391bb2":"perTokenPrice()","ba399ad2":"isInLockStage()","ba3b60ed":"rawVotes()","ba3c0067":"getTopPlayers(uint256)","ba3d0cb5":"retentionMin()","ba3dc67c":"startingPoint()","ba3eb50f":"TokenEther()","ba3eefc5":"makeInvestment(uint256)","ba3f41da":"beginCodeUpdate()","ba3f56f8":"startFinalStage2()","ba3f5a12":"tokenMultiplier()","ba3f8f2c":"getTokenPriceUSDWEI(uint256)","ba3f8f31":"ReleasingScheduleLinearContract(uint256,uint256,uint256)","ba3fc155":"ownerWithdrawal(uint256,address)","ba3fd8f7":"currChampion()","ba3fdb8f":"_createArt(uint256,address)","ba40aaa1":"setGiveAway(uint256)","ba414fa6":"failed()","ba41dc5b":"setwalletOne(address)","ba425379":"Ico_rejected(string)","ba429f33":"getRewardsContractHash(address)","ba42c8e5":"resolveSupervisorVote(uint256)","ba42fdb9":"handleLastProposal()","ba437b5d":"KOKC()","ba441560":"SetRedeemRate(uint256)","ba4442ab":"ReassingTokens(uint256,uint256)","ba44593c":"set(bytes32,address)","ba44bc0b":"UserMinMaxCrowdsale(uint256,uint256)","ba44f6a4":"RETHEN1()","ba452930":"stopPrivatePlacement()","ba454d60":"changeMaxEntries(uint256)","ba457dd1":"BreezeCoin()","ba45b0b8":"transfer(address,address)","ba4611d9":"getClaimCount()","ba463acd":"createPackage(uint256,uint256,uint256,string,uint256)","ba4670da":"onlyOwnerSetAdvWallet(address)","ba46adeb":"exerciseLong(address[2],uint256[7],uint8,bytes32[2])","ba470738":"changeRejectSetting(uint256,bool)","ba47c5f8":"inpreSalePeriod()","ba4823e1":"SoundcoinsToken(address)","ba485844":"func_0C0E()","ba487e62":"newCampaign(uint32,uint96,uint16,uint16)","ba490a03":"SpudToRotator(uint256,address)","ba49e21f":"getAttoTokensAmountPerWei(uint256)","ba4a579d":"canBetOnRound(uint256)","ba4bcd72":"currentAdmin()","ba4c206e":"removeCertificationDocumentInternal(address,bytes32)","ba4c825e":"_transfer(address,address,uint256,bool)","ba4d0c99":"conversion(uint256)","ba4d573f":"addSelctFight2Death(uint256,uint256,uint256)","ba4e1c38":"airdropTotalQty()","ba4feabd":"createEscuela(uint256,address)","ba50f965":"add_creature(uint256,address)","ba5129b9":"ethRateChanger()","ba51a6df":"changeRequirement(uint256)","ba51b1b4":"setTokenSymbol(string)","ba5233b2":"setPartnerQuota(address,uint256)","ba52688d":"approveCycle(bool)","ba53d9f3":"getSpartansOnTheBattlefield(address)","ba554374":"updateTranchRate(uint256,uint256)","ba5595d3":"numTokensAuctioned()","ba5673c3":"getChildrenLength(bytes32)","ba56763e":"getBidInfo(uint64)","ba56f6ee":"god()","ba57225d":"LogCrowdsaleEnd(bool)","ba575a39":"KOREKCHAIN()","ba59a75e":"bn128_map_to_G1(bytes32)","ba59f784":"ChessLotto()","ba5a2d33":"exitPool(address)","ba5abaf8":"startFightB(uint256,uint256,bytes4)","ba5b0e95":"CPCEIcoDeposit()","ba5c3a9d":"distributionList(uint256)","ba5c9bd6":"processReinvest(address,uint256,uint256,uint256)","ba5cb281":"uint32At(bytes,uint256)","ba5cb999":"RealTotalSupply()","ba5e286b":"getShipProductCount()","ba5eceb6":"borrowerBalance(address)","ba5f3e46":"getPlayerBetData(address)","ba61021f":"calcBonus()","ba612493":"getCurrentPassportLogicVersion()","ba61810c":"startNextPhase()","ba61a960":"Launched()","ba622884":"isManufacturerAddress()","ba622ddc":"getPlayerAnimals(address)","ba625fe6":"WineCoin()","ba629113":"contract12function2()","ba6361fb":"payme()","ba639d5a":"supplyRound1()","ba63abd6":"getPInvestedSumByRound(uint256,address)","ba63defb":"etherToSendJackpot()","ba6489e5":"getAccountReferrer(address)","ba65fa25":"getMerchantPublicKeyByAdmin(address)","ba66d7a6":"MDKICO(uint256,uint256,uint256,address,address)","ba6763ce":"withdrawBalanceFromStorageContract()","ba68693f":"PinZhiCoin()","ba693c86":"addsmartContractAdress(address)","ba69fcaa":"deleteStringValue(bytes32)","ba6a7e27":"AOABANK()","ba6afc50":"getIncentivesPool()","ba6b285a":"neuroChainAddresses(address)","ba6b5f96":"getChild(address,uint256,address,uint256)","ba6bbe55":"getPublicSaleTokensAvailable()","ba6c6490":"unlockTeamTokensTime()","ba6ca603":"ALDToken(uint256,string,uint8,string)","ba6cc6c3":"open(bytes32,address,uint32)","ba6dc506":"throwSlammerEvent(bytes32,address,address,uint256[10])","ba6f30e4":"sellCenturion(uint256,uint256)","ba6f4ab0":"burnCarbonDollar(address,uint256)","ba6ff8ad":"RTokenBase(uint256,string,string,uint8)","ba70d049":"DonateAdded(address,address,uint256)","ba70d54a":"ACTIVE_STATUS()","ba71c7f5":"setPricesManually(string)","ba723f99":"stopBid()","ba723fe2":"getRequestHash(bytes,bytes,uint256)","ba72cc36":"teamLock()","ba730e53":"getSellPrice(uint256)","ba7314ae":"AncestorHellNotes()","ba7325be":"indexOf(string,string,uint256)","ba736a99":"fetchOrderByIdWithWithPayer(string,address)","ba73737d":"AndiosCoin(uint256,string,uint8,string)","ba7435d9":"knightEquity()","ba75bbd8":"front()","ba75d0de":"minimumHydroStakeDelegatedUser()","ba76000e":"Add_Patient(uint256,uint256,string,string,string)","ba7607bf":"LogBidAccepted(bytes32,address,bytes32,address,bytes32,uint256)","ba76938b":"freezeDeposit(uint256)","ba76bfb7":"checkWithdrawalAvailable(address)","ba76e19b":"EthereumPrivateToken()","ba770154":"getUserPictureByUsername(string)","ba7705aa":"setIPFS(address,string,string)","ba773a70":"icoPrice_()","ba77ddc9":"PresaleFinalized(uint256)","ba780759":"EtherSportCrowdsale(uint256,uint256,address,address,address)","ba78a98a":"timelockEndTime()","ba78c773":"declineBid(string,uint64)","ba7a8149":"lockEtherPay()","ba7b86b9":"KhuuKoin()","ba7badeb":"nextVersion(address,bytes32)","ba7bd2aa":"withdrawTokens(uint256,uint256)","ba7bde55":"totalSupplyShares()","ba7bf7ff":"addcoinfee()","ba7c4af8":"revokeMyId(bytes32)","ba7cc631":"createKingdom(string,string,uint256,address,bool)","ba7ce849":"drawPool(uint256)","ba7d0b3c":"ETE()","ba7d619c":"returnTokensFromHoldAdditionalAddress(uint256)","ba7da724":"devVUPDestination()","ba7dc45f":"_removeOperation(bytes32)","ba7e424d":"isIcoEnded()","ba7e7cab":"getApprovalCount(uint256)","ba7ed2ff":"setMinInvestment(uint256)","ba7efcdd":"investmentLimit()","ba7fb1df":"getAddressToken()","ba8029bb":"setStartSale(uint256)","ba809390":"AccountReaderAdded(address,address)","ba80d787":"contributor()","ba80e058":"landingDiscount_ppc()","ba8118b1":"goNextRound()","ba81522f":"maxBlockDrift()","ba816496":"last50plusblocknr()","ba818f8d":"affiliateFee()","ba827243":"YangMaoZhuangYuan(uint256,string,uint8,string)","ba82bde2":"bindusertop(address,address)","ba82c897":"updateRewardToken(address,uint256)","ba82f55d":"ethsoccer48()","ba838b01":"EdCoinToken()","ba83c970":"closeSell()","ba83d63d":"getBidFreelancer(uint256)","ba847552":"isAddrCanCallServer(string,address)","ba84cb3f":"MobileApp()","ba85571c":"getPlayerInfoByAddress(address,uint256)","ba8661a2":"TimestampScheduler(address)","ba873f60":"setAssociation(address,bytes32,bytes32)","ba8747b3":"addReport(uint256,string,string)","ba874999":"getGameEngineAddress()","ba87ebfa":"IMDEXsetOwner(address)","ba87fdd4":"getSenderCities(address)","ba885446":"tokensPerAllocation()","ba88d537":"_getSenderStatus(uint256)","ba8a141f":"EnterCoin()","ba8a86c2":"whiteListedAddressPresale(address)","ba8ad39e":"grantToAllowBlocking(address,bool)","ba8af655":"returnAmountPledged(uint256,address)","ba8b7152":"BlockOfLifeToken()","ba8b9712":"adminRefundTokens(address,uint256)","ba8bb22a":"LIRAX(uint256)","ba8c0c9d":"getPropertyLastUpdater(uint16)","ba8c6980":"hasGrantAccess(address)","ba8cded7":"Bet(uint256)","ba8d045a":"tobuy(uint256,address,uint256)","ba8ef244":"getEvaluation(uint64)","ba8fb567":"startPhase2(uint256)","ba904eed":"removeRegistrar(address)","ba9072ea":"crownedTime()","ba907b7e":"testFailCreateWithParentsSameItemId()","ba90d553":"getContractsByType(uint256)","ba90f022":"modifyRecord(uint256,string,string,string,bytes32,int64)","ba9130a6":"execCustom(address,bytes,uint256,uint256)","ba91d87b":"mintForWorker(address,uint256)","ba922e04":"Karma(uint256)","ba92d382":"factory_address()","ba9316b7":"getExp(uint256,uint256)","ba9334a0":"testCombinators()","ba9398e9":"publicSaleEtherRaised()","ba93d980":"swapOpen()","ba941154":"newTapProposalFromCompany(uint256)","ba944118":"TMXGlobalToken(uint256,uint256,string,string,uint8)","ba953bc8":"KanadeCoin()","ba95b235":"sayNo()","ba95d63a":"leftSharePriceRateOfIncrease()","ba95df98":"releaseUserPrivateBonusTokens(address,uint256,address)","ba967a84":"addInit(address,address,address,address,uint256,string)","ba976ae5":"marketToken2018()","ba982c41":"tokensUnsold()","ba996aca":"getPlayerLevel(uint256)","ba99d1a6":"RATE_DAY_0()","ba9a061a":"START()","ba9a4d6e":"hasAddressVotedInBallot(uint32,address)","ba9a8b37":"convertibleTokenCount()","ba9a91a5":"SALT()","ba9a9e03":"StorageEnabled()","ba9ac37f":"mul(uint16,uint16)","ba9bb827":"CONTRIBUTION_MIN()","ba9bf757":"getPlatformBalance()","ba9c4637":"getMyPoints()","ba9d0638":"receivedCount()","ba9d407a":"GetAddressByName(bytes32)","ba9d4c09":"devuelveAppaddr(bytes32)","ba9e0907":"XJF()","ba9e9a86":"binarySearchForChallenge(uint256,uint256,bytes,uint256,bytes32[])","ba9ea413":"purchaseCostFiat(uint256)","baa0181d":"batchCancelOrders(address[5][],uint256[6][],uint256[])","baa0b806":"content(uint256)","baa23ac1":"SpecialDrawingRight()","baa24fce":"rightVotes()","baa28752":"listCenturion(uint256)","baa290d9":"DANSToken(address,address,uint256,uint256,uint256,address,uint256,address,uint256,address,uint256)","baa2e587":"confirmReception()","baa2edaf":"tokensDataProviders()","baa2ff01":"get_blockhash(uint256)","baa30f7b":"jackpotCount()","baa371d0":"DigiPulse()","baa3f7ee":"claimedOf(address)","baa3fc48":"calculate_proportional_reward(uint256,uint256,uint256)","baa40cd4":"mintForPrivateFiat(address,uint256)","baa40e5c":"getVote(string)","baa416b6":"CorsariumCore(address[],uint256[])","baa46bdd":"_createDistrict(uint256,uint256,uint256,uint256)","baa47694":"submitBlock(bytes32)","baa5eb5c":"isDspRegistered(address)","baa61df0":"tokenContractClaimTokens(address)","baa6ab81":"priceByPeriod()","baa70a8b":"LBCoinJ(string,string,uint256)","baa79dd3":"ethOdinRate2()","baa7d1f3":"MULTISIG_ETH()","baa83568":"requestColuLocalNetworkOwnershipTransfer(address)","baa8529c":"give(bytes32,address)","baa90366":"isThereACoinAtCoordinates(uint16,uint16)","baa92a05":"returnsenderbalance()","baa93b56":"crownIfFreeze(address)","baa9a8a9":"EtherbotsCore()","baa9da15":"soldTotal()","baa9e531":"totalTokensBought()","baaa3eef":"setDistValues(string,string,string,string,string)","baaa8b9a":"actualGotTokens(address)","baaac593":"LogWaterTree(uint256,address,uint256)","baab7a3a":"isSuccessDoneState()","baab89d5":"getLockedStructAmount(address,address,uint256)","baac2178":"MNLTToken()","baac274d":"getCustomerBalance(address)","baac4316":"sendTokensToMe(address,uint256)","baac5300":"createTokenProxy(address)","baad0828":"changeControllerInBntyTokenContract(address)","baad1532":"getMatchServer(uint256)","baad6c2e":"setInfoTier(string)","baadbca0":"newTickerQuery(string,bytes32)","baae172c":"setRefreshLockBalance(address)","baaee21f":"getLastN(bytes1,uint8)","baaeecb0":"getAllApproval()","baaefe5b":"priceInc()","baaf2d4f":"transferOtherERC20Token(address,uint256)","baaf4eef":"RESERVES_HOLDER()","bab1d921":"closeCurrentStage()","bab25514":"GRUToken()","bab2f2b5":"containsOnlyAlphaNumerics(string)","bab2f552":"currentCycle()","bab41142":"takerApproves(uint256)","bab41293":"getDataColla_001_002(string)","bab42b54":"test_campaignRules()","bab4e3b1":"getOwnedToken(address,uint256)","bab54f69":"_isExcluded(uint256)","bab5714c":"sendTeamSupplyToken(address,uint256)","bab58ec9":"periodITO_tokenPriceUSD()","bab5b64e":"spenderAddress()","bab5e2af":"LogBTHFoundationWalletChanged(address)","bab6d101":"checkClaimTokenByIndex(uint256)","bab6f9bf":"generateRevokeStakeForDelegationSchemaHash(uint256,uint256)","bab7b237":"totalRelease()","bab86ea8":"test(string,string)","bab8bd04":"clearAllRequests()","bab8fe40":"claimableTokens()","bab92a29":"get_owner_planets(uint256)","bab94366":"AppUpdated(address,string,address,uint256,bool)","bab95dba":"_getFeeAndNetAmount(uint256)","bab99890":"CPollo()","bab9c00c":"SmartSignature()","bab9fc63":"testFailCreateWithParentParentNotInUse()","baba4811":"recieveFunds()","babb019d":"enact_liquidation_less(address,uint256,uint256)","babb3e0b":"updateEthRate(string,string)","babbb78d":"teamTokenWallet()","babcc04c":"getLogsNum()","babcc539":"isAllowed(address)","babd222f":"addressToLarePurchased(address)","babd7012":"activeSupply()","babddb4c":"FundReturn(address,uint256,bool)","babe9394":"EasyMineToken(address,address,address,address)","babf2b2d":"EscrowMyEtherEntityDB()","babf5e37":"changeFree(uint256)","bac02609":"buyEarlyWhitelist(address)","bac03cd7":"totalContractBalance()","bac0b029":"BifreeToken()","bac0b276":"allocate(address,uint256,uint8)","bac127b9":"SecondAddressBalance()","bac15203":"unPauseContract()","bac18f9a":"handToBitmap(uint32)","bac1e2e0":"testBitsAndSuccess()","bac1e9f6":"getChannelSize(address,uint256)","bac21a22":"totalSupplyLimit()","bac37239":"addMarketMakerAddress(address,address)","bac506e0":"rf()","bac55edd":"setDnsDomains(string,string,string)","bac6068c":"inject(address,uint128)","bac6241f":"LookRevToken(address,uint256)","bac756e1":"PresaleToken(uint256,uint256)","bac79651":"setTokens(address,uint256)","bac7bb9f":"checkaddress()","bac7c252":"BTC10kon54()","bac97647":"uncleSafeNr()","bac9dbab":"ROLE_COO()","bacbe2da":"cancelVote(uint256)","bacc2753":"vestTo(address,uint256)","bacc2c42":"participate(uint256,uint256,uint256,uint256,uint256,uint256)","bacc58d7":"backManusOwner()","baccc92b":"RegulatorIfc(address)","bacd2a90":"mallocBudget(address,uint256)","bacd2e97":"executedCount()","bacd70b7":"callSomeFunctionViaInner3()","bacd8d88":"soldPercent()","bace4cf6":"Distribution(uint16,uint256,address)","bacef685":"createTokens(uint32,address)","bacf3f65":"secondPeriodOfICO()","bacf5f84":"_addBaseStats(uint256,uint8[8])","bacfddbc":"isDepositAddress(address)","bad09457":"test3(address[5],uint256[5],uint8,bytes32,bytes32)","bad16031":"isBlackjack()","bad19ead":"copyToAllUnits(uint256,uint256,uint256,uint256,uint256)","bad1f08f":"open(uint256,uint32,uint256)","bad2d6d2":"removeBlacklist(address,address)","bad4d623":"setAltDeposit(uint256)","bad568b1":"allowanceBcoupons(address,address)","bad69502":"getProviderRateHistory(uint256,uint256)","bad6b379":"changeCUSEaddress(address)","bad751bc":"createPeerReviewContract(address,bytes)","bad7726c":"checkDividendPaymentAvailable()","bad7d46a":"CreateOffer(uint8)","bad84416":"eligibleVotes(address)","bad845e6":"deleteProductInternal(bytes32)","bad84c9e":"getNumTicks()","bad9643b":"balance_wirthdraw()","badaba27":"packTable(uint256)","badae9b4":"addArgumentToRequestUint(int256,uint256,bytes32,uint256)","badb2e5a":"UpgradeRigETH(uint8,uint256)","badb97ff":"adminBurn(uint256)","badbaa3c":"setCallData()","badbbf34":"RBACWithAdmin()","badc9a52":"adminChanged(address,address)","badca131":"kill_and_withdraw(address)","badcf391":"sendMail(bytes16,bool)","badcfbcf":"withdrawSnowflakeBalance(address,uint256)","baddee6f":"listMultipleItems(uint256[],uint256,address)","bade1c54":"proposeReparameterization(string,uint256)","bade1ef9":"Birth(address,uint256,uint256,uint256)","bade6033":"propose(bytes,uint256)","bade777c":"Marked(address,address,address,address,uint256,uint256,bytes32)","badec5b4":"HK168coin()","badf3de9":"durationForBetAmount(uint256)","badf8b37":"TwoFactorAuth(string,string)","badfa573":"setAllowTransferTimestamp(uint256)","badfedf2":"genEthsRec(uint256,uint256)","bae07416":"canBeValidated(uint256)","bae0c536":"addSaleAgent(address)","bae118f4":"setHouseInfo(bytes32,uint256,string,bytes32)","bae18880":"getReceipt(address,uint256)","bae18ac3":"setUpgradeFee(uint256)","bae1c1ac":"doSendWithSignature(address,uint256,uint256,bytes,uint256,bytes,bool)","bae1cc74":"multiSubWithdraw(address[])","bae2718f":"WithNoArgumentConstructor()","bae2ddb5":"XBHX()","bae37857":"getEndTimeOfSession(uint256,uint256[],uint256)","bae3791e":"weisHardCap()","bae3c066":"sendInternally(uint256,uint256)","bae3c27f":"weiLimit()","bae4f466":"roundKeys()","bae5e693":"partnersAllocation()","bae5f9dd":"takerAffiliateFee()","bae61714":"setICOWeek3Bonus(uint256)","bae6c2ad":"queueSize()","bae6d62b":"manualOverride()","bae70892":"setMyPubKey(bytes32,bytes32,bytes32,bytes32,bytes32)","bae72565":"readAddress(address,uint256)","bae728b1":"setUnholdDate(uint256)","bae78d7b":"getEntry(uint256)","bae804a7":"transferFromSender(address,uint256)","bae8d888":"createArtefact(uint256)","bae944ba":"globalUnlockTime()","bae971e4":"getWithdrawEtherAmountValue()","bae99efc":"ICO_MAX_CAP()","baea0431":"getMsgDataAfter()","baea3a21":"addToWhitelistInternal(address)","baeb0718":"checkin()","baeb8cad":"deleteGroup(address,address)","baeb91ae":"invest(uint128)","baebcaf0":"getApp(address,uint256)","baec1ced":"depositPresaleWithBonus(address,uint256,uint256)","baec25ee":"ZYHToken()","baecd693":"sendTokensAfterBuy(address,uint256,uint256)","baed8bb1":"getAddressValues(bytes32)","baee193d":"changeCountryLimit(uint256,uint256)","baeeddfc":"Ublasti(uint256,string,string)","baef73e9":"expiryOf(uint256)","baf00f76":"removeAllSubUsers()","baf03586":"calculateBaseGet(uint256,uint256,bool,uint256)","baf05a87":"hodl_interval()","baf11cab":"isCommitted(uint256,address)","baf1256f":"withdrawToPlayer(address)","baf30051":"token_issued()","baf38352":"buy_for(address)","baf3a4d4":"distDivRate()","baf3d262":"Tickets_Sold(string,uint256)","baf3ef13":"disableNode()","baf44453":"FundAccount(address,address,address)","baf4960d":"createPlanet(uint256,address,uint256,uint256,uint256,uint256,uint256)","baf4ec53":"sumICOStage3()","baf4f6d1":"_endContestIfNeededStalemate()","baf539ee":"changeGasLimit(uint256)","baf5fbff":"PreIcobonusEnds()","baf652fe":"bonusThresholdWei()","baf6f9ca":"saleis(bool)","baf6fd32":"setintertoken(address)","baf73c0f":"holdingsOf_BULL(address)","baf79eb4":"removeDealInternal(bytes16)","baf8809b":"releaseTimeLock(address)","baf8c622":"_SUTokenContract()","baf9b369":"post(bytes)","baf9c5a2":"initialSupplyPrivateSale()","baf9d07b":"addAuthorization(address,address)","baf9d0cf":"getRoundAwardTicketNum(uint256)","bafa090d":"breakup(address,uint256)","bafa9c9d":"FighterUpdated(uint256)","bafb8e83":"marketSupply()","bafc1437":"getPurchased(uint256)","bafc7fe9":"zero_fee_transaction(address,address,uint256,uint256)","bafcea6f":"dataSourceGetYellowCards()","bafd244f":"setAmbassadorAddress(address)","bafdaf5e":"_getTargetBlock(uint256)","bafdebf3":"getServerAddress(string)","bafe648d":"BerithCoin(uint256)","bafedcaa":"lastRewardAmount()","baff4609":"lockTokenForNode(uint256,uint256,uint256)","baffa903":"getStartPrice()","bb004abc":"reserveManager()","bb005d4f":"setPlayerResearch(address,uint256)","bb007db9":"getSalaryTokenCount(address,address)","bb00c8f9":"ownerMintAmount()","bb00faca":"bonus02()","bb00fc55":"bookEarnings()","bb013206":"addNewCertificate(uint256,bytes32,bytes32)","bb0165b1":"setContractAddress(uint256,address)","bb01aa39":"unreserve(uint32)","bb01fb1f":"Issue(uint64,address,uint256)","bb043d53":"MinimalPayValue()","bb053484":"getInitializeFeePerEthInAttoethValue()","bb056781":"purchaseGas(address,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","bb057c5e":"proposedImplementation()","bb05ca52":"JadeCoin()","bb061fb5":"addWhite(uint256,uint256,uint256,bool)","bb07576d":"voteToUpdatePrenup()","bb083c2b":"substractFee(uint256,uint256)","bb08b247":"showAuction(string)","bb08c6c3":"o_desafiante(bytes14)","bb0936f7":"first_bonus_amount()","bb09adbb":"privGoal()","bb0a420a":"user(address,address)","bb0a64b6":"batchTransfer(address[],uint256[],address)","bb0bcbff":"AddPoolMember(address,string)","bb0bef19":"validateFile(address,uint256,bytes,bool,bool)","bb0c08b6":"getDebitNonce(bytes32)","bb0c8298":"minimumAmount()","bb0c8893":"claimUnrelatedTokens(address,address)","bb0ce7d3":"TotalHoldersAmount()","bb0d6fb6":"noCount(uint256)","bb0d7f9a":"listTCC()","bb0db551":"add_32(uint32,uint32)","bb0e01fd":"isError(uint8)","bb102aea":"totalSupplyCap()","bb10b2f1":"PRE_SALE_BONUS_PER_CENT()","bb119f6e":"productInfo(uint256)","bb11ed7e":"rescueTokensInMultiplePolls(uint256[])","bb128575":"StopSell()","bb13245f":"decimalsMultiplier()","bb133331":"trusteeContract()","bb1488d8":"_newAuction(uint256,uint256,uint256,uint256)","bb1583fc":"isBatched()","bb158dd5":"addToTokenLocked(address[])","bb15ac8e":"readBool(bytes32)","bb1630f2":"getAllSigs()","bb169da5":"Diploma_landing_page()","bb1757cf":"claim(address,bytes)","bb17a938":"toRlp(uint256)","bb17c8cc":"round2StartTime()","bb17e050":"Nullify(address,address,address,address)","bb18705c":"_buildSettleId(bytes,bytes)","bb1953fe":"updateSeed()","bb1a473b":"VOLUME_25()","bb1a5aad":"flipFinalizedSwitchTo(bool)","bb1ad687":"gateKey()","bb1adf9b":"DURATION_BEFORE_RESTORE_UNSOLD()","bb1af82b":"Test3()","bb1b21ed":"RefCommission(uint256,uint256)","bb1b99ce":"isCurrentUserAdministrator()","bb1c9351":"redeemNativeToken(bytes32,address)","bb1cc065":"buy_lovelock_withLOV(bytes32,string,string,string,uint256)","bb1d1cf9":"tier_rate_3()","bb1d45fc":"setOtherManager(address,uint8)","bb1d7ffa":"weddingdate()","bb1dfeca":"buildId3(address,uint256)","bb1e54bc":"TokenCrowdsale(address)","bb1eeb59":"totalWeiAmountSale2()","bb1f602e":"FailingDeployment()","bb205c84":"getDownVoteCount(bytes12,bytes12)","bb210372":"getPresale(uint256)","bb221cc8":"Hadescoin(address)","bb221e4b":"FuelToken()","bb22d75c":"PROMOTION_PROGRAM()","bb23e3a9":"arr(uint256,uint256,uint256)","bb23ef74":"setOwnerTestValue(uint8)","bb2408e6":"PERCENT_DELIMITER()","bb245283":"getHatchDurationMultiByGeneration()","bb24f0dc":"operationsLength()","bb2559ca":"initialTokenBalanceFetched()","bb256f68":"VaultCountPerProcess()","bb25b143":"DrawReadyToPayout(uint32,uint8,uint8,uint8,uint8,bytes32)","bb25bd15":"addWin(address,uint256)","bb25fd7f":"SODIUMTOKEN()","bb262080":"JaroSleep(address,uint256)","bb27e19e":"getlen(bytes32,bytes32)","bb280cba":"addBackers(address,uint256,uint256)","bb287679":"mainFabricAddress()","bb28c3f2":"setNonce(string,uint256)","bb29998e":"test(address)","bb2a51d1":"setSecurityGuard(address)","bb2a7d0c":"addVestingSchedule(address,uint256[],uint256[])","bb2aebe3":"createAssetPack(bytes32,string,uint256[],bytes32[],uint256)","bb2bded0":"trinityDataContract()","bb2c5ad7":"hasRandom()","bb2ce2f5":"DeedClosed()","bb2ced1b":"previousFounders()","bb2ced25":"startPoll(address,address,bytes32,bytes32,uint256,uint256)","bb2d713e":"sells(uint256)","bb2dc863":"getChildBlock(uint256)","bb2de15a":"TicketsBought(uint8,address,uint16[])","bb2e6904":"hopeCoin(uint256,string,string)","bb2eb4d2":"ONE_PERCENT()","bb2eb982":"impl_rewardsFactor()","bb2ebf83":"CostChip(address,uint32)","bb2f159b":"read_i32()","bb2f3228":"EOCSToken(uint256,string,string)","bb305ef2":"getBondOwner(uint256)","bb3084db":"ICOStarted(uint256)","bb30d796":"releaseAllocation(address)","bb316f06":"contributeForAddress(address)","bb32b6f8":"receivedCWC(address,uint256)","bb33072f":"refundToInvestor()","bb33d729":"unpauseSale()","bb33e730":"MoveTokens(address,address,uint256,string)","bb340909":"initPecul()","bb34534c":"addressOf(bytes32)","bb34e57c":"ROLE_BURN()","bb35783b":"move(address,address,uint256)","bb35b29c":"MintIND(address,address,uint256)","bb35f7ee":"rocketTravelTimeByResource(uint256,uint256)","bb3611e7":"BonusWhiteListCrowdsale(uint256)","bb36a233":"customtransfer(address,uint256)","bb36e5d0":"returnExternalPayments(address,bool,bool)","bb36ef7b":"addManyToKyc(address[])","bb370bad":"orderWasValid(uint256,uint256,uint256,uint256)","bb371fdd":"setMaxDeposit(uint256)","bb37a162":"payAdvertisers(bytes32)","bb389952":"unlockFounder()","bb38be10":"notifyCharge()","bb397161":"createNonRepeatableVpfFactory(string,bytes32,uint256,int256[])","bb39a960":"trade(address,uint256,address,uint256)","bb39c85f":"getTotalOwedTokenRepaidToLender(bytes32)","bb39ea60":"MIN_ACCEPT_ETHER()","bb3a304f":"setFundingLock(bool,address)","bb3a77ae":"ROLE_ARBITER()","bb3b2a35":"withdraw_4()","bb3b8dca":"getCertificateHash(bytes)","bb3ce7fe":"DepositHolder()","bb3cf577":"AddressListed(address,uint256)","bb3d13c5":"addValidation(address,bytes32)","bb3d5af2":"GetClaimCount()","bb3d9326":"YTC()","bb3e409a":"buyEggs(uint256,address)","bb3e443b":"FDataToken()","bb3e5b0a":"setPI_edit_34(string)","bb3f0390":"min_inv()","bb3f5330":"revertFunds()","bb3f5b7d":"totalTransfer()","bb3ff0bd":"TITSCOIN()","bb41f421":"payerPercent()","bb424892":"minimumCost()","bb42de92":"getSubscriberContentCount()","bb43a11e":"getHashOf(address)","bb440b82":"funComputeRoundPrice()","bb445084":"getRDividends(address)","bb449782":"setCommunityAccount(address)","bb44e08d":"updateOrderNumber(uint256)","bb452ea7":"objectDoublet()","bb4534f1":"addrecruit(address,address,address,address)","bb453d5a":"CBCToken()","bb45d09d":"getCurrGameInfo()","bb471d73":"getRealAmountBonus(uint256,uint256,uint256)","bb472219":"resetGame()","bb472c93":"bet2deltaOf(uint256)","bb476637":"deliverTokensAdmin(address,uint256)","bb48156a":"preSaleRound()","bb4872de":"stoppable()","bb48d190":"upgradeToPremium(bytes32)","bb4b236a":"CSToken(uint256,string,uint8,string)","bb4b7bd0":"listForSale(uint256,bytes32)","bb4c006c":"checkDeletable(address)","bb4c9f0b":"multiSend(address[],uint256[])","bb4cbd0b":"gracePeriodStopBlock()","bb4d0cb5":"FSC3()","bb4d4b2f":"addVestingAccount(address,uint256,uint256)","bb4d7cd1":"tag(uint256,string)","bb4d9e22":"WithBonusPeriods()","bb4e3f4d":"add(uint8,uint8)","bb502bac":"EthbetOraclize(address,address,uint256)","bb502dd9":"checkExchangeSupported(bytes32)","bb504317":"divest(address,uint256)","bb50c67a":"crowdsaleRunning()","bb510a77":"createChannel(address,uint256)","bb5166e7":"getPaymentType(address,uint256)","bb5196d6":"setParams(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bb51de39":"IDEAL()","bb51f32d":"withdrawTeam()","bb52ca2c":"getOrgClaimsCount(address)","bb537ced":"matchesDelay()","bb540231":"totalFartsReceived()","bb542ef0":"setOwnerWallet(address)","bb5530c4":"updateCampaign(uint256,string,string,string,address,address,address,string)","bb56a683":"guaranteedBuyersBought()","bb572896":"consolationRewardsRequiredFaith()","bb57349c":"handleSaleClaimCallback(address,uint256)","bb575333":"sessionEndTime()","bb582db6":"mgmtBodyAddress()","bb584a3a":"EventCancelAuction(uint256,address)","bb59b48c":"payableWeiReceived()","bb59d68c":"DariaRotkoToken()","bb5a1149":"myReferee()","bb5a4f4c":"placeBet(uint256,uint256,uint256,uint8,bytes32,bytes32)","bb5a7ca0":"extendEventStartsTime(bytes32,uint256)","bb5adf14":"setProxyManagementContract(address)","bb5b3edc":"emergencyWithdraw(uint256,bool)","bb5b586b":"usdPerKEther()","bb5b6aa4":"myInner2()","bb5c3821":"total_ICO_supply()","bb5d3bcb":"tokensPromotion()","bb5d40eb":"isValid()","bb5d69a0":"setEns(string,address)","bb5ddb0f":"sendMessage(address,bytes)","bb5e0696":"LongTermReserveMinted(address,address,uint256,uint256)","bb5e3d3b":"doThing(string)","bb5e5875":"InseeCoin()","bb5e78a4":"HasSigningPermission(address)","bb5e9dec":"get30Artworks(uint16)","bb5e9eab":"thirdWeek()","bb5f4629":"orders(address,bytes32)","bb5f95fe":"LSECoin()","bb602e80":"Volkscoin()","bb6198dd":"getOrCacheTargetReporterGasCostsWasCalled()","bb632244":"btcs()","bb642f65":"seedCreatedCount()","bb64c09b":"KIMEX(address,address)","bb64c79e":"SearchTimeBlocknumber(string)","bb64e420":"getTransactionByTransactionId(uint256)","bb6534a9":"AMOUNT_TeamSupport()","bb67be65":"AFUN(address,uint256)","bb68b86f":"maxTokensToDistribute()","bb6954ce":"BourseToken()","bb6996a5":"swapWinner(uint256,bool,uint256)","bb6a0853":"GreedPit()","bb6a0f07":"tasksCount()","bb6a1427":"testThrowRestartEnforceRevisions()","bb6a55bd":"_mintToken(address,uint256)","bb6ad6ef":"withdrawTokenId(uint256)","bb6af3da":"limit9()","bb6af543":"setJackpotPayRate(uint256)","bb6b13a1":"tier1()","bb6b38bb":"setAdminAddressForComissions(address)","bb6b4619":"SendETC(address)","bb6c1178":"RentToken()","bb6c4827":"burnThis(uint256)","bb6d0132":"End_Promotion()","bb6d203c":"spend(address,uint256,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","bb6d8c77":"contractPoweredUp()","bb6e7de9":"endContract()","bb6f0f0f":"fetchAllCandidatesBySnapshotBlock(uint256)","bb6f175f":"SimpleAquaPriceOracle(uint256,uint256)","bb6f6c15":"protectedDenominationOfOrigin()","bb7029a9":"gameCollapse()","bb702c8e":"discard()","bb707059":"approveMany(address[])","bb70abfa":"_computePVPBeneficiaryFee(uint256)","bb718861":"scheduleCall(address[2],bytes4,bytes,uint8,uint16,uint256[6])","bb71a7c3":"makeInvestment(address,address,uint256,uint256,address)","bb72680c":"getHasPermission(address,string,string)","bb72b12d":"oldOwnerProfit()","bb731f98":"Excalibur()","bb73703f":"delRoleForUser(address,string)","bb7436a7":"getUsersDroidsIds()","bb74a5a0":"testValidationOfDoubles()","bb74b4e6":"TOKEN_SUPPLY_OWNER()","bb74dcda":"isRefunded(address,address)","bb750232":"allowReceiver(address)","bb75a2a9":"throwMe()","bb76d8a5":"TimeLock()","bb777028":"PRE_ICO_BONUS_TIME_3()","bb777498":"calculateId(string,string,string)","bb77b136":"planetAuction()","bb77d7d8":"ConunToken(uint256,string,uint8,string)","bb784140":"AragonTokenSaleMock(uint256,uint256,address,address,uint256,uint256,uint8)","bb7859b5":"periodThree()","bb785f0e":"AirDropPayBitsR1(address[])","bb78d159":"approveTokenControlInfo(uint256)","bb79428c":"RateUpdate(string,uint256,string,string)","bb7963e3":"hasArbiterVoted(uint256,address)","bb7a6dba":"vestingHasStarted()","bb7c15ab":"createDog(uint256,uint256)","bb7c62cb":"getReferrerBonusTokens()","bb7cb80b":"dropOffset()","bb7d064f":"automatedReport(uint256[])","bb7d4f65":"ICOFFSHORE()","bb7d715b":"startEthToCentsRateUpdateCycle()","bb7dd72d":"finishMintingStruct()","bb7fa4ac":"sellCeiling()","bb7fb08b":"getContributor(address,uint256)","bb7fde71":"mint(address,uint256,uint256,string)","bb7fe5c9":"LotteryAdmin(address)","bb7ff992":"requestSellforETH(uint256)","bb806dc9":"initial()","bb813a9b":"KkkTokenSale(uint256,address)","bb814746":"ICO_TWO()","bb814e9e":"versionExists(bytes32)","bb818ea6":"advancedNETH(uint256,string,string)","bb81926d":"_applyCommission(uint256)","bb822605":"calculateTokensTier(uint256,uint256)","bb826e50":"maxBlockActions()","bb828f11":"setChallengeRewardsPercent(uint256)","bb83a01f":"MyTALToken()","bb843219":"closingDateFunding()","bb84d362":"splitProfitVIP_only_Dev()","bb850e01":"_transferOwnershipOnBuy(address,uint256,address)","bb85931b":"eSTATERToken(address,address)","bb862588":"getCET6ScoreById(uint32)","bb86d8fe":"CPGPEREGRINE_FTL_SPEED()","bb878f2a":"ProposalAdded(uint256,uint256,string)","bb87b5f8":"getPersonalStatus(address)","bb87c1f2":"getAllowedUsers(address,uint256)","bb889341":"ZiberToken()","bb88c016":"decreaseApproval(uint256,address,uint256)","bb898233":"getAct()","bb8ab48c":"Bluechip()","bb8b2b47":"getUserContribution(address)","bb8bbc90":"ContractEFT()","bb8bcc46":"crowdSaleCap()","bb8be064":"HardwareToken()","bb8bedc9":"setMasternodeCandidate()","bb8c256a":"ecadd(uint256,uint256,uint256,uint256)","bb8c7ce4":"ContributionReceived(address,bool,uint256,uint256,uint256)","bb8c869d":"contestOver()","bb8c9797":"claimReward(string)","bb8d35ce":"medibitToken()","bb8dc735":"getNonceCompareOp()","bb8e8f46":"isExecutionAllowed()","bb8f0dd2":"PonziSeller()","bb8f712f":"generateGame(bytes32,bytes32,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bb90617b":"toUINT112(uint256)","bb90cec2":"setNewRound()","bb911607":"percents(uint256,uint256)","bb912454":"setKNCPerEthRate(uint256)","bb913f41":"_setImplementation(address)","bb91f8ae":"ownerTransferAllEther()","bb925c19":"_selectWinner(uint256)","bb94392e":"getRemainingTokenForArticle(string)","bb945177":"produceTokens(address,uint256,uint256)","bb9453a5":"assetProperties(address)","bb95d992":"blockhashes(uint256)","bb963c8a":"transferLibOwnership(bytes,address)","bb969132":"getLandEstateId(uint256)","bb9694f3":"Eth()","bb971094":"finishAirdrops()","bb979c3d":"getHotelsByManager(address)","bb9932a7":"addressReserveSupply()","bb996043":"returnPtSafeXLarge()","bb99999c":"TokenLinked()","bb99dec1":"MoldCoin(uint256,address)","bb9b02a8":"evLockFund(address,uint256)","bb9b13d8":"getTotalInterestAmount(address)","bb9ba82d":"Florijn(uint256,string,string)","bb9c3f2b":"minWager()","bb9c6c3e":"verify(string)","bb9e1edc":"ethBaseBalance(address)","bb9e3547":"setTokenCost(uint256)","bb9e37ec":"TitleApproved(uint256)","bb9efd5e":"bulk(address[],uint256[])","bb9efdc6":"QUAK()","bb9fc9ed":"transferStmpsToOwnerAccount(address,uint256)","bba02bf8":"LyuTestToken()","bba04dc9":"resetExplicitState(uint32,int64,int256,uint64,int8)","bba231ce":"_isPast(uint256)","bba2e907":"prepaymentFee()","bba33ace":"sellerCut()","bba45738":"setOmegaContract(address)","bba46031":"LOFO()","bba4a876":"setStateDistributing()","bba4b31e":"birthBlock()","bba4c282":"RaiblocksClassic()","bba4e4c0":"AddressForReturn()","bba4e9bd":"getTraitCount()","bba52516":"tokenTimelock()","bba570cb":"getDatURL(string)","bba5ad87":"registNameXid(string,uint256)","bba5b24e":"buyTokens(uint8)","bba65ed1":"isbit(uint256,uint256)","bba7a1ab":"getTokenVolumebasedBonusRateForPhase1(uint256)","bba80923":"msub(uint128,uint128)","bba8a065":"insert(uint8,uint8)","bba8b342":"PresaleMidexToken()","bba90086":"updateAndTransferFrom(address,uint256,string,uint256,uint256)","bba91ea7":"getHomeadvIndex(uint256)","bba9a9f6":"zeroFeesTransfer(address,address,uint256)","bba9cfe1":"soldBeforeUnsoldAllocation()","bba9dc60":"deactivateProvider(address)","bba9ffce":"TransactionFailed(address,address,uint256)","bbaa7345":"changeDivestmentFee(uint16)","bbaa7a57":"getHeroAttributes(uint256)","bbaaa787":"claimable(address,bool)","bbaac1e8":"privateSaleTokensAvailable()","bbab867c":"setSubContractAddresses(address,address)","bbac78a9":"setImmutableOwnership(address)","bbad490f":"phase_3_bonus()","bbad6172":"ICOZ()","bbadb845":"updateProduct(uint256,string,uint256,uint256,uint256)","bbaefe9f":"bytePrice()","bbafb379":"updateBatchStartTime(uint256,uint256)","bbb01c9c":"privateIcoMinimumContribution()","bbb0c054":"foundersVestedPayment()","bbb0d58e":"_createNeighbors(int32,int32)","bbb104cf":"FucksToken9()","bbb1c4c0":"withdrawForFiveYear()","bbb21c4d":"explore(uint256,uint256)","bbb28a65":"contributors_count()","bbb37f60":"purchaseLeader(uint256)","bbb37f76":"registerTier2Users(address[])","bbb44989":"Token2GB(address)","bbb50b78":"vraWallet()","bbb655b6":"_setGasPrice(uint256)","bbb7259c":"CrowdsaleLimit(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bbb73e3e":"GetBuyPrice()","bbb7d310":"getCompte_19()","bbb7eb64":"addInventories(uint256,uint256,uint256,uint16)","bbb896ad":"isCurrentAdmin(address)","bbb906f7":"TomSkin()","bbb92642":"BotTradesToken()","bbba3333":"safer_ecrecover(bytes32,uint8,bytes32,bytes32)","bbbc0f55":"_price_tokn_ICO_first()","bbbc67d0":"getParticipantDestination()","bbbc77dd":"intersubtoken(address,uint256)","bbbd2953":"startNewBattle(uint256,uint256,uint256,uint256)","bbbdef70":"FreezoneToken()","bbbe1390":"getEmployerJobsForFreelancerInvite(address,address,address)","bbbeac89":"MastermindAlliancePublishingGroupToken()","bbbf8fbd":"increaseWeiRaised(uint256)","bbbf9384":"BATTLE_CASUALTIES()","bbbfc4db":"mulsm(uint256,uint256)","bbbff4fb":"updateMinAmountWei(uint256)","bbbff571":"changeKey(string)","bbc001c3":"alloc()","bbc0c1a2":"addOrg(string,string,string)","bbc0ebbf":"soldForFirst()","bbc10d1a":"distributeeBitcoinCashSmall(address[])","bbc2402d":"startCrowdsale(uint256)","bbc2986c":"setPrice(uint16,uint256)","bbc2fcf5":"TOKEN_PER_ETH()","bbc30ad8":"getGalleryData(uint256)","bbc32820":"autoPay()","bbc39ab6":"readCharityAddress()","bbc42b3f":"orderToContractor(uint256)","bbc43d41":"pay(uint128,address,bytes1)","bbc49130":"Milestone_OpenTheIco(string)","bbc53086":"csvConcat(string,string,string,string)","bbc5aa5b":"maxTransferAmount(uint256)","bbc5d3d9":"setQuickConverter(address)","bbc6049d":"etherSpin()","bbc620a8":"setNewWithdrawCommission(uint256)","bbc6351e":"MMMC()","bbc64582":"getVotesCount(address,uint256,bytes32)","bbc6df30":"getRoundInfoByID(uint256)","bbc6eb1f":"getDefaultDonation()","bbc7d0b9":"marketingPool()","bbc7f045":"ZenCoin()","bbc84d1a":"voteWorth()","bbc878c4":"totalSeraphims()","bbc894a1":"GuoCoin()","bbc8e3cb":"disallowTransfers(address[])","bbc94fda":"priceProgression()","bbc9f09a":"payPartners()","bbca0a89":"c_endTime()","bbcac1c3":"vipBrokerFee()","bbcb4e3a":"TokenERC20(uint32,string,string)","bbcbce8e":"MIN_GOLD_TO_UPGRADE()","bbcbe572":"d(address,address)","bbcbefd0":"unset()","bbcc69ef":"withdrawTokensByInvestors()","bbcc8cea":"SaiSaiToken(uint256,string,string)","bbcd0f02":"endorseClaim(string,string,string,address,address,string)","bbcd5bbe":"setTokenContract(address)","bbcdd139":"initExploit()","bbcded7a":"left73(uint256)","bbce2c17":"lastBurn()","bbce3fc2":"getLastBet()","bbce67ca":"lastPlayTime()","bbced0d0":"newTopic(string)","bbcef175":"end_redeem_period()","bbd0c939":"computePrice(uint256,uint256)","bbd1e186":"addModule(string)","bbd1e1fc":"editionActive(uint256)","bbd2e01e":"betsLength()","bbd2e059":"impl_transferMSI(address,address,uint256)","bbd31db3":"openAll()","bbd32de0":"massTransfer(address[],uint256)","bbd3684c":"reservedteamtoken()","bbd37e37":"RICO()","bbd37ef3":"getReportingParticipant(uint256)","bbd39ac0":"coinBalanceOf(address)","bbd3b27c":"loveEvent()","bbd3b2ab":"inrSessions()","bbd418e6":"testConcatStorage4Bytes()","bbd425df":"bestUser()","bbd4271f":"setRateAndStart(uint256,uint256,uint256)","bbd46303":"changeStage(uint8,uint256,uint256,uint256)","bbd4e8c9":"numDeposits()","bbd4edb1":"updateRatingCustomer(string,bool)","bbd4f854":"buyShares(bytes32,uint8,uint256,uint256)","bbd5301a":"_devteam()","bbd53bf7":"fairsale_protectionOFF()","bbd5d174":"LogGame(string,string,string,string)","bbd6dd48":"getUserTokenInfos(uint256)","bbd74748":"Ethraffle_v4b()","bbd8b602":"getOracleOutcomes(bytes,address[])","bbd95c32":"inArray(uint256[],uint256)","bbd974cc":"maxAllowedTakerBetsPerMakerBet()","bbd9a5fa":"grantPermission(address,string)","bbda1e9a":"BicycleToken()","bbda33d9":"getGameName()","bbdaebe2":"transferFromInternal(address,address,uint256)","bbdb31cb":"challenge(uint256,address,bool)","bbdb57c3":"batchTransferORSS(address[],uint256[])","bbdbd31e":"beneficiaryAndBirth(bytes32,int256,bytes32)","bbdc02db":"gameType()","bbdc04d8":"getDealData(bytes32)","bbdc7709":"startDispute()","bbdd366a":"DECIMALS_MULTIPLIER()","bbddaca3":"setReferrer(address,address)","bbdefbbb":"AWMVoucher()","bbdfbfba":"delivered()","bbe00af5":"beneficiars()","bbe18d43":"betClosed()","bbe2b727":"burnWholeBalance()","bbe42771":"closeDeed(uint256)","bbe430de":"available(address,address)","bbe437eb":"endICO_w2()","bbe4fd50":"getNow()","bbe562b0":"multiplication(uint256,uint256)","bbe5d9d4":"addSpace(uint256,uint256,bytes)","bbe61730":"get_sale_arbits_total()","bbe7180b":"envio_dinero()","bbe7221e":"orderbookContract()","bbe86e6a":"sendTokensToOne(address,uint256)","bbe8a9b6":"registerSecretBatch(bytes32[])","bbe93d91":"mul(int256,int256)","bbe9c7d6":"takePromille(uint256,uint256)","bbe9f99d":"isTeamMember(address)","bbeadcad":"invalidateVotingAtIndex(uint256)","bbeb5923":"joinFee_()","bbeb76bc":"setMultipleParticipantWhitelist(address[],bool[],uint256[])","bbec3768":"createOrder(uint128,uint16,uint256,uint8,uint256)","bbec9e1b":"deletePriceCredentialItemId(bytes32)","bbececa9":"left78(uint256)","bbed7177":"getContentTimestamp(uint256)","bbee1ab7":"forgiveIt(address)","bbef83cf":"getContractNameById(bytes32)","bbef86b8":"PayForServiceCHL(uint256)","bbf02b00":"level_8_percent()","bbf0f065":"keepEth()","bbf14d67":"tier3Timestamp()","bbf1e6d0":"SetMiningEnable()","bbf2a9a3":"changeAcct3(address)","bbf2ee4e":"lockAddress(uint256)","bbf3ae00":"ccExchangeRate()","bbf48d6f":"convertReward()","bbf58f4d":"foundersVault()","bbf59a41":"personal_withdraw()","bbf646c2":"ethAddr()","bbf7585c":"getDistributionAt(uint256)","bbf76802":"purchaseApprove(address)","bbf78026":"SetMemberInfo(address,address,bytes32)","bbf89803":"addBuyer(address)","bbf9cd8b":"EACCoin()","bbfa6153":"getRegulatorLevel(address)","bbfad256":"updated(uint256)","bbfb2f7a":"getEndtime()","bbfbaaf8":"getWorkSecondsInProgress()","bbfbe6b6":"discountedMiningDifficulty(address)","bbfcc86b":"getHistEthRate(uint256)","bbfe6b75":"externalCall(address,uint256,bytes,uint256,uint256)","bc0111a8":"initEnsRigistrar()","bc014bb9":"earlyBackers()","bc019eed":"getAffiliate(address)","bc01b767":"freezeTransfersUntil(uint256)","bc02844c":"totalRemaining(uint256)","bc032967":"getRetailerByAddress(address,address)","bc03a31e":"superManager(address)","bc04056a":"LockedDayAdded(address,uint256,uint256)","bc0409bf":"addTokens(bytes32,uint256)","bc04562d":"Reclaimer(bytes32)","bc04cb0f":"FEED1()","bc04d77b":"datasetHub()","bc055227":"ownerOfPiranha(uint256)","bc05529b":"SaleDeadline()","bc058968":"updateThingData(bytes32[],bytes32[],uint88)","bc05d087":"registerProduct(uint256,string)","bc063e1a":"MAX_FEE()","bc064863":"getRequestorAddresses()","bc070e83":"minimumBuyIn()","bc084de9":"CrowdsaleAuthorizer(address,uint256,uint256,uint256,uint256,uint256)","bc08afd9":"WebOfTrustToken(address,uint256)","bc09b5ec":"fundPreIco()","bc0aaff2":"setzBytes32(bytes32)","bc0aca61":"setFeeAccount1(address)","bc0ae61e":"GazeBountyCoin()","bc0b45fa":"OSPN()","bc0c868c":"stocksOf(uint256)","bc0cd8d3":"BOOCOIN()","bc0e7adb":"testThrowsDisownNotOwner()","bc0eaf0a":"calcAmountAt(uint256,uint256)","bc0f920a":"AuthSuspend(bool)","bc0fb9a0":"predictWinner(uint256,uint256,uint256)","bc1013db":"m_totalWorkerPoolCount()","bc101ffe":"twentyPercentWithBonus()","bc104f24":"compareItemSlots(uint256,uint256)","bc10a667":"euroRaisedICO()","bc10ce84":"Test(int256)","bc1123fe":"isUInt256ValidIn64(uint256)","bc112fa3":"ALC_FUNDATION_ADDRESS()","bc11f72c":"DABcoin()","bc120fe7":"whitelisted(address,address)","bc126ba1":"totalCents()","bc1292a0":"BonusChange(uint256)","bc129a98":"accountedTokenSales()","bc12d19d":"maxCapTokenPresale()","bc12e3d7":"getAuction(uint64)","bc1351ba":"has_contract_started()","bc13e3a6":"controller2()","bc14016b":"removeAllOps()","bc148094":"PostAdded(address)","bc1558be":"MANHATTANPROXY3RDAVE()","bc15a2dd":"BEAXY()","bc15be93":"firstRoundCosmosDiscount()","bc15e5fe":"get_next_global_audit_document(bytes32)","bc16272d":"requestRegistration(bytes32)","bc168c90":"_setIPFSHash(bytes32,string)","bc174df3":"ProofOfCryptoNick()","bc17991d":"restoreBalances(address[60],uint256[60],uint256[60])","bc17a0b4":"PAST()","bc17bd7e":"SelfDestructible(address,address)","bc17e669":"exiteJugador(address)","bc186dc9":"unlockBalanceByIndex(uint256)","bc18f727":"galleryFive()","bc197c81":"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)","bc19bcbf":"submitBallotWithPk(bytes32,bytes32)","bc19bce5":"resolveName(string)","bc1a3810":"thelnwaonCoins()","bc1af71d":"_maxTokenSoldPreICO()","bc1c002c":"call_contract(address,address)","bc1c9888":"CoOwnerSet(address)","bc1e9ca3":"USD_CENT_PER_TOKEN()","bc1ea063":"LogContractOwnershipChangeInitiated(address)","bc1f71e1":"depositKncForFee(address,uint256)","bc2010cc":"feesC()","bc2017f3":"adjustPriceOfCountryPlayersAfterWin(uint256)","bc201a9d":"addSupport(address)","bc208057":"enter(uint256,uint256,uint256)","bc215cb6":"BBTokenBox()","bc21ce9d":"Aggregation()","bc22df1a":"buySpaceshipUpgrade(bytes5,uint16,uint8)","bc22f570":"poolsToCreate()","bc231983":"Temp()","bc244c11":"shut(address,bytes32)","bc244fc9":"systemAddress(address)","bc24612c":"claimableAmount(address,bytes4)","bc246a36":"hashState(address,uint256,uint256,uint256)","bc24d886":"setSail(uint256,uint256,uint256,uint256,uint256,uint256)","bc25415c":"produce(uint64)","bc25a810":"lock(address,bytes32)","bc25e2fd":"postProof(string)","bc2622b4":"addKeyValue(string,string,string,uint256)","bc2674b1":"LogExchange(address,address,uint256)","bc27c7bb":"buyZoAssets(bytes32)","bc28cfe4":"getTicketSet(address,uint256,uint256)","bc28d878":"rejectProposal(uint256)","bc294a7c":"setCEOAddress(address)","bc2a4dd6":"doBalanceOf(address)","bc2b6913":"donateSkin(uint128[],address[],bool[],uint256[])","bc2bbad7":"getMyNotes(uint64,uint64)","bc2c3a12":"ValidContractAdded(address,address,uint256)","bc2d10f1":"finishEthGet()","bc2d87f5":"Set(string,string,address)","bc2eb3f8":"removeNode(bytes32,bytes32)","bc2fe07b":"transferCardOwnership(address,uint8)","bc300ed3":"setBounty(address)","bc304e55":"serverTransfer(address,address,uint256)","bc308233":"autoreleaseTime()","bc30e4ac":"abcLotto()","bc30f3f8":"modifyPlatformAddr(address)","bc33f8ef":"commonRebate()","bc345e11":"Updated(address,address,bytes,bool)","bc346090":"DigipayToken()","bc346c9c":"Attack(address)","bc34f204":"getP3DBalance()","bc356eea":"VEN()","bc3574d4":"adjustSupply(uint256)","bc3589bf":"TOKEN_FIRST_PRICE_RATE()","bc358af9":"listItem(uint256,uint256,uint8,address)","bc35c57f":"setMinAmount2Round(uint256)","bc3619dd":"onBlockClose(address)","bc364d7b":"tokenVestingAddress()","bc367377":"setTokenBurnApproveReset(address,address,address,address)","bc376bbe":"unlockFor(address,uint256)","bc378a73":"getProposalsLength()","bc37d7b8":"setVendingFee(uint256,uint256,uint256)","bc389b6d":"callWithdraw(uint256)","bc38a991":"testInsert()","bc39d42f":"sigDestinationTransferFrom()","bc3a72a5":"ETHHToken(uint256,string,string)","bc3abbdb":"etherPerMiner()","bc3b0d31":"STCB()","bc3bc814":"changeTolerance(bytes32,uint256)","bc3c2846":"requestMediator(uint256,uint256,address)","bc3d9390":"printBlockHash()","bc3dde2f":"xxx(address)","bc3f7bcb":"moleculartechnologySupply()","bc3f931f":"getVote(uint256,address)","bc4006f5":"erc721Metadata()","bc4076e9":"accountsReceiveableHeld()","bc408ec4":"ElixirUSD()","bc40b52a":"startPreICO()","bc40bac6":"getCrydrViewAddress(string)","bc41f298":"changeControllerAccess(address,bool)","bc427bc8":"setFreezeForFounding(uint256,address,uint256)","bc428ee2":"getTimeOutAuthentication()","bc431846":"getBetPriceID(uint256)","bc4447ef":"getBlackListStatus(address,address)","bc447a6d":"numDragonTypes()","bc448782":"setCrowdsaleAddress(address,address)","bc44e79d":"getStageWinners(uint8,uint16,uint8)","bc44ea9a":"setBank(address,uint256)","bc451844":"BONUS_DURATION_1()","bc456c42":"changePaymentAddress(address,address)","bc45d789":"setConfigUint(int256,bytes32,uint256)","bc466ab2":"setNewEnd(uint256)","bc467a3e":"ownedContract()","bc48bc22":"erc20TokenCount()","bc48f4be":"getLand(int256,int256,address)","bc499814":"generatePrefixedPreimage(bytes32)","bc4998b9":"eth2MNT(string)","bc4a2030":"getCurrentRate(uint256,uint256,uint256,uint256)","bc4af295":"spawnAssetWithCreator(address,uint256,uint256,uint256,address)","bc4afa67":"MBTCToken(address,uint256)","bc4b3365":"addFunds(address,uint256)","bc4b346d":"confirmQuest()","bc4bbad1":"updateCostETH(uint256)","bc4c594b":"tokenManagerAddress()","bc4d76e5":"EPay()","bc4d9b50":"minerLockedAmount()","bc4e3105":"unlockAddressDuringITO(address,address)","bc4f65a3":"addCity(bytes32,uint256,uint256)","bc4fcc4a":"redeemedAt(bytes32)","bc4fe17e":"addressToUser(address,address)","bc50c09e":"playAnyTriples(uint256)","bc517131":"walletVersion()","bc5213b7":"_setCurrentRate(uint256)","bc523229":"ShopDex()","bc525652":"templates(uint256)","bc52b43b":"buyinAs(address)","bc537bae":"getMeOutOfHereStocks()","bc53a93d":"E4Token()","bc54a168":"buyTokensOnInvestorBehalfBatch(address[],uint256[])","bc54f56f":"getTemplateDetails()","bc562b9e":"loseSponsor(uint32)","bc56a240":"walletEtherPresale()","bc56e749":"acceptProposal(uint256,address)","bc57275b":"EthCnyPrice()","bc579103":"totalPayed()","bc57d5f5":"transferFrom(address,address,uint256,uint256,uint256,uint256)","bc597d9f":"getProposalVotesCount(uint256)","bc59afe6":"scanMany(address[],bytes1[])","bc59d45a":"raisedWei()","bc5b75f4":"EtherWorldCup()","bc5bf5bf":"releaseVestingTokens(address)","bc5c0c67":"setDowntime(uint256)","bc5cfd4f":"lastBonusNumber()","bc5d066e":"changeCompanyWallet(address,address)","bc5d0f65":"beginExecution()","bc5dc168":"balanceOfLocked2Y(address)","bc5dfd7d":"getCompte_23()","bc5e4bb4":"_hasSkillsCheck(uint256)","bc5ff5e1":"oraclize_query(string,string[4],uint256)","bc602ab7":"removeRandomClass(uint32)","bc607f7b":"funcFromC2()","bc60878e":"total_received_amount()","bc60a365":"removeAdminAccount(uint256,address)","bc60ac60":"StefyToken()","bc61394a":"fillOrder(address[5],uint256[6],uint256,bool,uint8,bytes32,bytes32)","bc6171df":"sendETHToMultiSig(uint256)","bc62c89a":"getTrainerEarn(address)","bc62d8d8":"parse(string)","bc632a21":"creationTime(address)","bc634abb":"getDocumentProposals()","bc636707":"_explorationTime(uint8,uint8,uint8)","bc63cc90":"starCountsForOwner(address)","bc64059b":"exchangeEtherForHavvensAtRate(uint256,uint256)","bc643df1":"getIncludes(uint256,uint256)","bc649f4c":"grantProvider(address)","bc6548fb":"etherVault()","bc655f54":"getEndDate1()","bc65c559":"preIcoInvestment(address,uint256,uint256)","bc65d6f6":"getSubscriberContentHashes()","bc65e9e1":"PenCoin()","bc6633f7":"setSaleState(uint16,bool)","bc677b46":"viewOwner()","bc67f832":"setMessageSender(address)","bc68118b":"setDeveryRegistryAddress(address)","bc68fad9":"burnBalance()","bc697319":"minimumGoal()","bc69dc89":"BenefyCashToken(string,string,uint8,uint256)","bc6a49a3":"LaunchRocketEvent(address,uint32,int64,int64)","bc6ac112":"calculateRegionInitialSalePixelPrice(address[16],uint256)","bc6b12b3":"odem()","bc6c06e7":"GoodfieldRetail(uint256,string,string)","bc6c4d0f":"totalVotesForCandidate(uint256)","bc6d68ee":"updateSubscription(address,address,bool,uint256)","bc6d80fa":"getLenderAmountForIncreasePositionAtTime(bytes32,uint256,uint32)","bc6e6604":"TOKENS_PER_ETH()","bc6f1699":"clockpos()","bc6f712a":"Attestation(string,bool,address)","bc6f9021":"maxCapTokens()","bc6fd6d9":"MINIMAL_WEI()","bc70ad19":"IMEXX()","bc713f1d":"AddPoolCoOwner(string,address)","bc71b0a6":"DeCenterToken(address,address,address,uint256,uint256)","bc71cdcb":"BAInvestor()","bc7202d7":"_updateSalePrice(uint256,uint256,address)","bc734f0f":"nextSeason()","bc735d90":"setOperator(address,address,bool)","bc73a7e4":"_preValidatePurchase(address,uint256,uint256)","bc73c971":"TierBasicDividendAddress(address)","bc7411b2":"chargeBonuses()","bc745a0d":"nextBonusStepLimit()","bc752b61":"buyTicket(uint256[],uint256)","bc76dca0":"GoWalletProject()","bc77b919":"_mySymbol()","bc77f476":"EVCChain()","bc78ac81":"setPet(string)","bc7a6e35":"_startAuction(bytes32)","bc7b3f86":"NewHighestBid(address,uint256,string)","bc7b6d62":"setResolver(uint256,address)","bc7b801e":"adminUpdateWorldSnapshot()","bc7c322c":"ratePerWei()","bc7c55ed":"listing()","bc7c72d7":"getmessagefromdovie()","bc7d8cb4":"EURSToken(address)","bc7dbc0d":"yearlyFee()","bc7dce06":"setETHPrice(uint256)","bc7e8d3c":"isDeholdable()","bc7f25e4":"getReferrerOf(address)","bc7f3b50":"getDelegate()","bc7f58b1":"addAgreement(address,bytes32,uint32,uint32)","bc802c83":"userManagerContract()","bc80bee8":"setFeerate(uint256[3])","bc81572c":"createPromoScene(address,string,uint256[],uint256)","bc81786f":"addBonusToClient(address,address,uint256,string)","bc81c97b":"failingRefund(address,uint256)","bc81f147":"set_iconiq_arbits_per_ether(uint256)","bc81f2f5":"eraseMatch(uint256)","bc82f4d3":"verifyEmailAddress(address,string)","bc83a6fb":"ekkoBlock1(uint256,string,uint8,string)","bc83d001":"DividendFacial()","bc8409a4":"investWallet()","bc843509":"toByte()","bc84a7ba":"getsometokenn(address,uint256)","bc851718":"hashLast()","bc855006":"SantaiToken()","bc85c055":"queryEOSTokenBalance(address,address)","bc85e064":"merchantWallet()","bc86a23a":"addPrimaryRecord(string,string,string,string,string,string,string)","bc87103a":"removeFunder(address,address)","bc8711fd":"getWinnersLength()","bc87b70f":"oldestGen()","bc88adc4":"getBuyerBalancesOfCurrentAuctions(address[],address[],address)","bc899015":"CappedCrowdsaleImpl(uint256,uint256,uint256,address,uint256)","bc8aa899":"we_token()","bc8b336d":"Ninecoin()","bc8bde64":"_creator()","bc8caa47":"resetDividendsCalculation()","bc8cb3f9":"destTokensReferals()","bc8d7a51":"gemsOfOwner(address)","bc8e1143":"processTransaction(bytes,uint256,address,bytes20)","bc8e9cde":"createGen0Horse(uint256,uint256,uint256,uint256,uint256,uint256,address)","bc8f3bcb":"ZeroDollarHomePage()","bc8fbbf8":"nuke()","bc903cb8":"getProposalInfo(uint256)","bc912e1a":"WHITELIST_SALE_PRICE()","bc9147a4":"Foundation()","bc916a50":"hasOwner(uint16)","bc921d54":"setImageData(uint256,uint16,uint256[])","bc92bea5":"getRandomItems(address,string)","bc944d9e":"newLowestAsk(uint256,address)","bc950708":"totalRaisedInCents()","bc95f178":"make(bytes32,bytes32)","bc9748a1":"pong()","bc978361":"setrteamVaultAddr(address)","bc97a8ac":"JackpotPayout()","bc97fd06":"updateMultipleUsersReward(address[],uint256[])","bc98b8b0":"getTTTInfo(uint256)","bc9904ec":"updateProfile(address,bytes)","bc99249e":"buy(address,bool)","bc9968a2":"dataController()","bc99c8be":"takerAddressAt(uint256)","bc99cc37":"maxInvestors()","bc99d04c":"YRQ(uint256,string,string)","bc9abe67":"completedFlag(uint16)","bc9aed8b":"TokensIssued(address,uint256,uint256,uint256,bool,uint256)","bc9b717e":"TokenPurchase(address,address,uint256)","bc9c278d":"IcoContract(address,address,uint256,uint256,uint256,uint256)","bc9c58f6":"countOrigins()","bc9cbcc8":"setImbalanceStepFunction(address,int256[],int256[],int256[],int256[])","bc9cc1fb":"getAllbetByGtype(uint8)","bc9d8d6a":"getLastWallet()","bc9da641":"testToUint8()","bc9e080e":"setVerifierManager(address)","bc9e6b0f":"_getClientLastPaidRate(address)","bc9f31e3":"mock_throwIfNotRemoved(address,address)","bc9ff567":"InternetWealth(uint256)","bca19900":"tokenHardcapIssued()","bca19ca0":"TAAS_CONTRACT()","bca1f81c":"lockOpen()","bca2b941":"setTokenPrice(uint256,uint256,uint256)","bca2bbc0":"EtherModifierMoops()","bca36985":"ExposureSettled(bytes32,address,uint256)","bca38dab":"createGuess(uint256,string,string,string,uint8,bytes,uint256,uint256,uint256[],bytes32[])","bca3eb24":"setCAO(address)","bca50515":"transferFromPreSigned(bytes,address,address,uint256,uint256,uint256)","bca51abf":"_detectStage(uint256)","bca53fa0":"AIHTeamLockContract()","bca58da8":"change_block()","bca60cf5":"getAgreement()","bca63e50":"mintTotal()","bca65475":"jugar()","bca6e8ec":"sendToReceiver(address,address,uint256)","bca7093d":"withdrawalPeriod()","bca72b59":"revealVote(string,uint256,uint256)","bca76131":"GoCryptobotCore()","bca77cd6":"YUBToken()","bca7a9e2":"lockToken()","bca7bd85":"getAllLockerInfo()","bca7e96b":"needsFinalization()","bca86986":"testSetup()","bca915c7":"createPromoPlayer(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bca9745c":"display_time(bytes32)","bca9a5c5":"getEmployee(uint256)","bca9adef":"vestedAvailableAmount(address,address)","bca9e546":"testControlCreateWithParentParentNotInUse()","bcaa218e":"myFrontEndTokens()","bcaa85df":"lockAccounts(address,bool)","bcab7ad2":"TimeDecayingTokenBoundary(uint256,uint256,uint256,uint256,address)","bcabb54c":"modifyCommunityInfo(uint256,string,string,string,string)","bcabbfb1":"startDonation()","bcae19f4":"base58Address(bytes)","bcae9d43":"theProxy()","bcaedade":"STANDARD()","bcafe9a9":"setIncreaseRepAvailableForExtraBondPayouts(bool)","bcb02b74":"testFailPushWhenStopped()","bcb0a787":"_setSchellingRoundSupply(uint256)","bcb0c2d7":"removeStakeholder(address)","bcb0c7c0":"nomParticipant(uint256)","bcb0f541":"setEarlyBirdDuration(uint256)","bcb1e4f7":"GetSellingTokenUnitPrice()","bcb32828":"emissionAddress()","bcb39621":"currentSeason()","bcb3b5d2":"getGamblesList(uint256)","bcb593f1":"subOnStage(address,uint256)","bcb60fa9":"blockTx(bool)","bcb638cb":"parseImpressions(uint64,bytes)","bcb7b0d4":"pauseICOs()","bcb7f880":"DTCC_ILOW_2()","bcb83450":"createMarriage()","bcb98ba2":"changeChampsName(uint256,string)","bcba53f4":"_createBlock(uint256,uint256,uint256,string,address)","bcba6939":"transferERC20Token(address,uint256)","bcbb64c4":"softCapInToken()","bcbc1585":"_payRoyalty()","bcbc758a":"SixStandardToken(uint256,string,uint8,string)","bcbc9175":"prefixedHash(bytes32)","bcbd3bcd":"_editPersonalNote(string,uint256)","bcbd82e5":"rateForPreICO()","bcbd9881":"setFriendsFingersRate(uint256)","bcbdbf40":"SaleResumed()","bcbea1ad":"transferCardTo(address,address)","bcbf5b90":"totalSupplyForPresale()","bcbf7229":"resetVoteCount(uint256)","bcbfe43c":"openSaleCompleted()","bcc13d1d":"contributionMin()","bcc1480a":"canTransferBalance(address)","bcc17ca0":"getvalues(uint256)","bcc221d0":"getBonusValue()","bcc30409":"processPurchase(address,uint8,uint256)","bcc37dd4":"approvedAccount(address)","bcc38018":"recycleReward(uint256)","bcc38d59":"proxies()","bcc3af24":"hasVotedOnConstitutionPoll(uint8,address)","bcc44a72":"restoreTokenOwnership()","bcc46e83":"addCollateral(uint256)","bcc4e4ab":"getVesting()","bcc4f0ed":"isValidBuy(uint256,uint256)","bcc5601b":"BaktFactory(address,bytes32,address)","bcc5dce5":"stash(uint256)","bcc6092a":"MyEtherBank()","bcc673bd":"GeneralToken(string,string,uint8)","bcc70902":"create(address,uint256,uint256[],uint256)","bcc74a3b":"isAdminAddressExist(address)","bcc7900c":"SystemTest()","bcc7db5a":"cleanupErrorGame(address,uint256,uint256)","bcc91d61":"sendEther(address[],uint256[])","bcc941b6":"totalWinners()","bcc94309":"calculator(uint8,uint256,uint256)","bcc9ed6f":"MAX_PAYOUT_FRAC_TOP()","bcca1fd3":"changeVotingRules(uint256,uint256,int256)","bccb6157":"RedemptionWalletUpdated(address)","bccb8fc0":"vestTokens(address,uint256,address,uint256,uint256,uint256,bool)","bccc85e6":"receiveTokenLoot(uint256,uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","bccda810":"logicContractAddress()","bcce515d":"bulkMint(uint256[])","bccee504":"m_ETHPriceLifetime()","bccf0972":"egrToken()","bccf5aa4":"issueTokenAndTransfer(address)","bcd0b22a":"getSnapsLength()","bcd0ce28":"BitcoinUniversal()","bcd101a6":"getStartDates()","bcd2780b":"addValidContract(address)","bcd2feff":"biotorBiomassToken()","bcd396d1":"adminTrade(uint256[],address[],uint8[],bytes32[])","bcd3d8ca":"Collector(address,address,uint256)","bcd3ff89":"setGameSponsorInfo(address,uint256)","bcd4144b":"giveGreed()","bcd45a76":"HolderVacated(address)","bcd47934":"hasBiometric()","bcd5078c":"get_king_address()","bcd533ae":"newRefundProposal()","bcd5349f":"getCapacity(uint256)","bcd59261":"getDepositBlock()","bcd59b36":"secondsAfterStart()","bcd60f6c":"winningProposal(uint256)","bcd61c6a":"getGoodPrice(bytes32)","bcd789cc":"submitProposal(bytes32,string,address,address,uint256)","bcd85b6d":"getBackerStatus(address)","bcd88a61":"viewInvestorDividendPool()","bcd9cc60":"rejectCetification(address)","bcda601f":"Panicked(address)","bcdac66f":"Power()","bcdaea36":"setOpGas(uint256,uint256,uint256,uint256,uint256)","bcdb446b":"recoverEth()","bcdd6121":"increaseApproval(address,address,uint256)","bcdda53f":"TokenERC20(address,uint256,address)","bcddd64e":"CHECKPOINT_KEY()","bcde18f1":"fundingStart()","bcde87eb":"totalAmountOfTeatokensCreated()","bcdea6f9":"getStageMinimum(uint8)","bcdf266c":"EphronTestCoin()","bcdf43dc":"add_presale_arbits_sold(address,uint256)","bcdf569b":"finalize(address,address)","bcdfe0d5":"Hello()","bce0e87a":"payoutOnPurchase(address,uint256)","bce0fb22":"takeOwnershipWithIndex(uint256,uint256)","bce1cdc3":"getTotalEtherOfAllRounds()","bce24669":"removeGame(address)","bce2b9a3":"purchaseEgg()","bce2bb42":"setCoinTotalsContract(address)","bce2d16d":"koef()","bce32da4":"AndhraToken()","bce3cc67":"TokensReclaimed(uint256)","bce440d5":"TokensContractAddressSet(address,address)","bce49a90":"KKCToken(address)","bce4d041":"updateCancels(address,uint256)","bce5a209":"owners2tokens(address,uint256)","bce5fc53":"UIOCOIN(uint256,string,uint8,string)","bce6158d":"PTransfer(address,uint256)","bce643aa":"developer_new_symbol(string)","bce70868":"buildingIsPublic(uint256)","bce83d2a":"setWhitelist(address,address,string)","bce94649":"getRangeURI(uint256)","bce9ae3d":"NewDeal(uint256,address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bce9ccb9":"GetCitySnapshot(address,uint256)","bcea363d":"killContract(address)","bcea7ea0":"chargingGas(uint256)","bcead63e":"lender()","bceaf1fd":"CLOUDForGas()","bcec1df3":"ROLE_DISTRIBUTOR()","bcecbc65":"getSendersEth(address)","bceceefe":"startCrowdsale0(address)","bcecf667":"usdToEth(uint256)","bced2c8c":"InteractingTokenA(uint256,uint256)","bced9cfd":"guessSeed(uint256)","bcedb86c":"payQuarterFinalWinner(uint256)","bcee2dd4":"getFeeCollected()","bcee6eb9":"validateProposedThroneRules(uint256,uint256,uint256,uint256)","bceeb243":"getUserSSCeducationDetails(string)","bceee05e":"isSuperuser(address)","bceeeb9a":"SearchIPR(string,address)","bcef393a":"balanceOfVault(uint256,address)","bcef84b1":"getMaxBuy(uint256,uint256)","bcefafab":"changeAccountAddressForSponsee(address)","bcf0dd8e":"marketTransfer(address,address,uint256)","bcf0e1ea":"TerrariumCoin()","bcf175c8":"oraclize_cbAddress()","bcf2e323":"sort(bool)","bcf49c72":"dewhitelistAddress(address,address)","bcf599f1":"toUnixtime(bytes32)","bcf610bc":"UnsetAgenda(string,address)","bcf6558c":"releaseMid()","bcf685ed":"setAgent(address)","bcf68f87":"lockCrowdSale()","bcf6b3cd":"changeBaseValue(uint256,uint256,uint256,uint256)","bcf711b2":"CBXToken()","bcf7b67e":"emitFeesClaimed(address,uint256)","bcf7bd0b":"requireEnoughExpForBreeding(uint256)","bcf83634":"basecost()","bcfa87d2":"getBounsEarnings(address)","bcfaa79d":"mintTokens(address)","bcfb0140":"getTokenOrderDataHash(uint256[],uint256,uint256,address,address)","bcfb4ea1":"Million()","bcfb9b61":"voteProposal(uint256,bool)","bcfbd445":"getTrader(uint256)","bcfc5078":"bountiesKey()","bcfcb03e":"allocateFounderTokens()","bcfde742":"setHardCapCHF(uint256)","bcfe070f":"batchCancel(address[],uint256[])","bcfe8fb4":"ArtTokenBurn()","bcfea3e4":"BLMCH()","bcff702b":"salePause()","bcfffab8":"shopStoreNextId()","bd00b0c2":"changeDedeAddress(address)","bd0100c9":"registerAddress(string,address,address)","bd01c7d5":"buyTicketToDraw(uint256,uint256,address)","bd025a79":"setDoge(address)","bd02942f":"allocateAdvisors(address,uint256)","bd02d0f5":"getUint(bytes32)","bd02e4f6":"calcRandomNumberAndGetPreliminaryGameResult(uint256,uint64)","bd041c4d":"vote(address,bool)","bd042ca6":"GigsToken()","bd04923f":"values(uint256,uint256,uint256)","bd05c055":"timeBetweenGames()","bd05cb4d":"createContractItem(string)","bd06aa84":"WithdrawalContract()","bd06e777":"SCORE_REPORT_START_TIME()","bd075b84":"mint(address[])","bd079484":"getmortiesSinceLastHatch(address)","bd079a18":"YTPAY(uint256,string,string)","bd088724":"mintDone()","bd097e21":"fundContract()","bd09f117":"eidooWallet_()","bd0a0e85":"setLeaderboard(uint256,uint256)","bd0ae405":"voterReward(address,uint256)","bd0af85d":"pay(address,address)","bd0b65e4":"sub_id(string,uint256)","bd0c6307":"contrExit(uint256[])","bd0cac13":"updPool(uint8,uint256)","bd0cc4ee":"reverseSplitTokensAfterDistribution(uint256)","bd0e5d07":"deposit4()","bd0e6a0f":"startICO(bool)","bd0fda3d":"EntityCount()","bd102430":"blacklister()","bd102993":"CurrentStageUpdated(uint256)","bd119967":"add_rating(uint256,uint256)","bd11e933":"wingsTokenRewardsPercent()","bd129b92":"batchFillOrders(uint256[],bytes[])","bd12a007":"InterfaceId_ERC721Metadata()","bd131a78":"firstAuctionsExtendableDuration()","bd149031":"LongToken(uint256,string,string,uint256)","bd14fe3e":"hasOwnerAccess(address)","bd153c64":"emitted()","bd15e9ab":"hasMinBudget(address,uint256,uint256[])","bd1607ed":"HashRush(string,string,uint8,uint256)","bd16deaa":"ownerSetMaxBet(uint256)","bd16f1f3":"unfreezeByIndex(uint256)","bd1723e5":"blackBox()","bd17647f":"changeMilestone(uint8,uint256,uint256)","bd17a9d8":"blockAccess(address,bytes32)","bd17d63a":"TokenStorageContract(address,address,address[],uint256,uint256,string,string,uint8)","bd183430":"ArtIs()","bd185612":"changeCertificateHash(address,bytes32,uint256)","bd187e3b":"changeParticipationFeeForRaz(uint256,uint256)","bd189666":"DetailedERC20Mock(string,string,uint8)","bd19036a":"investmentCapIcoPhaseTwoPounds()","bd1a77a8":"sellNac(uint256,address,uint256)","bd1ad05c":"LogRecoveryChanged(address,address,address)","bd1b324c":"NewMyToken()","bd1b768b":"getApprovedAddressesOfList(address[],address)","bd1baedb":"SignumToken()","bd1bca06":"_getCrabData(uint256)","bd1d3432":"FOUNDER_ADDRESS1()","bd1de900":"totalOffer()","bd1f4b52":"withdrawErc20(address,uint256)","bd1f7d52":"GetBoosterData()","bd1fac00":"TOKEN_COMMUNITY()","bd218493":"tokenLimitPerWallet()","bd21a864":"DigitalTradingCoin(address)","bd21fa47":"accountBalances()","bd22b1cb":"millionDollarTokenReward()","bd22d07f":"getTankByTokenId(uint256)","bd22f1cd":"testSubmitHash()","bd2302fc":"transferProposal()","bd23076f":"LamboToken()","bd23eb39":"tokenFallback()","bd242709":"initBob(uint256,uint256)","bd249ff0":"lockedBoardBonusAddress()","bd24b0d0":"ZHORA()","bd24de29":"blockDuelBegin()","bd24f08a":"isInBalanceLimit(address,uint256)","bd2560a0":"_inverseGetTokenAmount(address,uint256)","bd262a20":"setAuthority()","bd272880":"OnUpdateFee()","bd2850ab":"Freeze(address,address,uint256,uint256,string)","bd285ea8":"ReferedCrowdsale()","bd28d688":"TFOA(uint256,string,string)","bd28f504":"_computePet(uint256,uint256,uint256)","bd290d8b":"isValidLenth(string)","bd295f30":"GoodTronToken(address,address)","bd2b4ab7":"DigitalContentsToken()","bd2b6444":"adminUpdateWhiteList(address,address,bool)","bd2c0ead":"removeHolder(address,uint256)","bd2c245e":"privateIcoFinalized()","bd2cef65":"callback_ForPayout(bytes32,string,bytes)","bd2deecb":"create(bytes32,address,address[],address,bytes32)","bd2fffb3":"FlipNA()","bd3124e0":"addToBank()","bd320dde":"firstSaleDelivery(address,uint256)","bd322b77":"enableApi(address)","bd32aa44":"initiateSelfDestruct()","bd336584":"first_release(uint256)","bd338d85":"yearOneMultiplier()","bd33cc91":"requestRefundContributor()","bd345ed9":"setETH(string,uint256)","bd353ce2":"withrawDev()","bd355f43":"amountOfBags()","bd3566b7":"generateToken(address,uint256,string,string)","bd35d570":"GAS_TO_COMPLETE_EXECUTION()","bd366ddc":"reclaimEthicHubTeamFee()","bd36a5cd":"updateSaleStatus()","bd36c881":"bytesToAddress(bytes,bytes)","bd36cc93":"burnCancel(address,address)","bd37fec9":"Protean()","bd382b45":"getWindowAdjRatioForGameId(uint256,bool)","bd3a2ef4":"updateOdds(string,uint256)","bd3a5208":"getOraclizeRoundGasFee()","bd3a9d3c":"_createAuction(uint256,string,uint256)","bd3b5d07":"m_pending()","bd3bef41":"NewLeader(uint256,address,uint256,uint256)","bd3ccfc9":"getWeeklyTransactionVolumeSending()","bd3ce132":"transferManually(uint256,address)","bd3d0ecb":"newName(string,string)","bd3e19d4":"getCost()","bd3e7401":"setupSale(uint256,address)","bd3f0965":"AiraEtherFunds(string,string)","bd3fe562":"getRadarsIds()","bd4074f9":"tokensForCrowdSale()","bd431462":"BuyBSTtokens()","bd45115c":"PGPToken()","bd457de2":"KAPcoin(uint256,string,string)","bd478fcb":"readFromCart(address,uint256)","bd47c1a2":"getAccountListLenght()","bd47dd7a":"lockSeedInvestors()","bd484606":"techWallet()","bd48fa0e":"unpause_3()","bd499af3":"updateOptionsRegistryAddress(address)","bd49f00f":"ownersTokenList(address,uint256)","bd4a359d":"getLatestVersion(bytes32,bytes32)","bd4b6bbd":"transferScoupons(address,uint256)","bd4bb67e":"transferTokensFromKingWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","bd4c0755":"Test68()","bd4cfadf":"getownerInfo(address)","bd4dc024":"landRegistry()","bd4e0b4d":"REFERRAL_TOKENS()","bd4ed6cc":"sumHardCapPreICO2()","bd5021af":"startRecovery(address)","bd5034ff":"Redeem(address,uint256,uint256,uint256)","bd50b3b4":"transferAndLock(address,uint256)","bd513bea":"getTreasure(bytes32)","bd51525e":"typeOf(address,uint256)","bd51654b":"showMyEtherBalance(address)","bd516e04":"addCombat(uint128,uint128,bytes32)","bd5196cf":"createGame(string,string,uint256,uint256,string,address,uint256,string,bytes32[2],bool,string)","bd51d5d0":"hasBalance(address,uint256)","bd51fa4c":"propose(string,string,string)","bd527527":"setLLV_edit_13(string)","bd52d81a":"_emitRoleRemoved(address,uint8)","bd5304e3":"ContributorBalanceChanged(address,uint256)","bd53cb96":"changeUnitsUserCanBuyLimit(uint256)","bd541ad0":"depositEscapedFunds()","bd545f53":"cancelAllOrders(uint256)","bd54bced":"LogN_fnc(address,bytes32,uint256,string,bytes,uint256,bytes1,uint256)","bd550824":"_setPayTo(address)","bd556252":"PRE_ICO_PERIOD()","bd58118f":"allocateAngelTokens(address,uint256)","bd5821ca":"_refund(address)","bd5821f1":"changeActualTokenValue(uint256)","bd583bff":"registerManager(address,address)","bd59434d":"setGame(uint8,address)","bd59fdde":"ITube()","bd5acbd6":"continueOrder(uint128,uint256)","bd5ae945":"NodeSwapCrowdSale(uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,uint256)","bd5b758d":"ObtainChip(uint32)","bd5b948d":"CCH_ILOW_1()","bd5c4e24":"TIMEOUT_DESTROY()","bd5c5420":"setExchangeRate(address,uint256)","bd5ca3a3":"createProxyImpl(address)","bd5d7b1d":"FEELCOIN()","bd5dec98":"withdraw(address[])","bd5e3a80":"GPPHARMTOKEN(uint256,uint256)","bd60527b":"getEmployerContracts(address,uint256[],uint256[])","bd611c73":"TOTAL_ICO_TOKENS()","bd61ff75":"cmpn(uint256,uint256)","bd6206ec":"initialDayWithdraw(uint256)","bd621042":"setUnownedPriceInExoTokens(uint256,uint32)","bd623d68":"encodeData(uint128,uint256,uint24,uint40,uint32)","bd625f1b":"setend(uint256)","bd62fff3":"Nines()","bd632e10":"batchInvest(address[],uint256)","bd633642":"MeissaChallengeToken()","bd639259":"getOwnerAngelCount(address)","bd63c338":"canRecover(uint256)","bd646356":"calculateCommissionToWithdraw(uint32)","bd6501b1":"isValidator(uint64,address)","bd656daf":"Fomo2D()","bd659784":"addToList(address)","bd65fc4c":"stb()","bd66528a":"claim(bytes32)","bd675c0e":"revealMove(uint256,uint8,string)","bd679ab2":"WithdrawGains()","bd679ad6":"burnDragons(uint256)","bd6812a4":"lastBlock_a0()","bd684865":"getAuthByPhone(string)","bd68817f":"clearRAMAll()","bd68eb34":"_spawnAxie(uint256,address)","bd6a9abb":"hasClearingPrice(address,bytes32)","bd6bbc31":"lastCollection()","bd6bf475":"canUpdateCompany(string,address)","bd6c4661":"fetchCancelledOrdersForPayer(address)","bd6c6756":"cardsCount()","bd6cac4f":"isPriorPack(address)","bd6de5a3":"dNextOffer()","bd6e578a":"getPreSaleFund()","bd6e5e03":"calcICO(uint256,uint256,uint256)","bd6edba5":"getUserBalances()","bd6fd20d":"getDeedTimestamp(string)","bd7084b2":"getNextNonce()","bd7095db":"GetCompetitionFunds(uint32)","bd70c53a":"LYFToken()","bd70fce9":"getApprenticeDistributedRandom(uint256)","bd7162b6":"setPixelPrice(uint16,uint16,uint256)","bd7173dd":"addLuckyblock(uint256)","bd719336":"canDistributeReservedTokens()","bd71e476":"ownerSetMinBetMining(uint256)","bd7243f6":"wipeBlacklistedAccount(address)","bd725f6e":"UBSToken()","bd728083":"ShowPurchased(uint256,address,address,uint256,uint256)","bd733dfb":"getUintsOwnerCount(address,address)","bd739a2f":"existsManagedContract(uint256,address)","bd73a9b4":"setTime4(address,uint256)","bd7427f8":"forceRefund()","bd7474ca":"upgradeDeploymentAdmins(address)","bd74c4e7":"setAttribute(address,address,bytes32,bytes,uint256)","bd74dc9d":"servicePaymentWithCharityPercentage(address,uint256)","bd763f59":"addPlayerData(uint256,uint256,string,uint256,uint64,uint64,uint64)","bd76540a":"buyIn(uint8,uint256)","bd76bf19":"addToBuyList(uint256,uint256)","bd778fde":"CoinNext()","bd77ac2c":"disburse(uint256)","bd780d0d":"getLastAttack(uint256,uint256)","bd788c88":"allocate(address,address,uint256,uint8)","bd792db3":"setIcoAddress(address)","bd797e32":"ChangeEmployeeState(address,uint8,uint8)","bd79a42a":"decimalToPreciseDecimal(uint256)","bd79d692":"depositEtherToVault(uint256)","bd7a9fda":"nameRegistry(address)","bd7afb29":"lastBlock_f17()","bd7b09e4":"totalCitizens()","bd7b7849":"addFace(string,string)","bd7be110":"SaveCoin()","bd7c13c6":"phase1MaxEtherCap()","bd7d3836":"pauseCrowdSale()","bd801ed4":"yishiliToken()","bd80d449":"newOK()","bd812166":"getSeasonInfo(uint32[99])","bd815a10":"RecyclerToken(uint256,string,string)","bd820688":"numOperators()","bd826f2b":"currentnumber()","bd837b2b":"approveToPullOutTokens(address,address,uint256)","bd83ea8d":"createMarriage(string,string,string,string,uint256)","bd84d8f6":"ProgressiveIndividualCappedCrowdsale(uint256,uint256)","bd853960":"assertEq14(bytes14,bytes14,bytes32)","bd858288":"orderMatch(uint256,uint256,int256,uint256,uint256,address,uint8,bytes32,bytes32,int256)","bd85948c":"startNewRound()","bd85b039":"totalSupply(uint256)","bd85e163":"FOURTH_USER_CUT()","bd865d29":"end_auction()","bd8697ab":"makeFailed(bool)","bd88f603":"setImageData(address[16],uint256,uint16,uint256[])","bd897671":"KYRIOSToken()","bd89d806":"y_Title()","bd8a79d5":"getFollowingCandidate()","bd8aa780":"whitelist(address[])","bd8b452e":"eatUnicorns()","bd8c1d33":"checkTransferFromToICAPWithReference(address,bytes32,uint256,string)","bd8c5643":"disableMoving()","bd8caabf":"setVirtualReserveBalance(uint256)","bd8cb6ca":"removePlugin(address,address)","bd8d34f5":"fundForTeam()","bd8d585e":"NCO()","bd8d5c7f":"EtherCartel()","bd8d5ce3":"amountReservedTokens()","bd8d86c4":"getlevel(uint256,uint256)","bd8d92c3":"requestDiplomaEntry(uint256,uint256)","bd8e0905":"weiToToken(uint256)","bd8e4725":"IxiniumFT()","bd8e4a51":"getCAORatio()","bd8e68c9":"PRICE_STAGE_FOUR()","bd8f61d8":"PerfectCoin()","bd8f997c":"getTotalQtyIpfsAddresses()","bd902dad":"approveSingleUser(address)","bd90df70":"targetContract()","bd916452":"claimReferrerBonus()","bd9215f4":"highest_bidder()","bd9335c0":"scheduleHangouts()","bd93f493":"LAUNCH_DATE()","bd945430":"OUTINGRESERVE()","bd94b005":"cancelSale(uint256)","bd94fafc":"PRESALE_CAP()","bd952178":"rejectAllocation(address)","bd95264c":"store(address,address,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","bd957585":"declareCrowdsaleEnd()","bd95d909":"sellTokenPerEther()","bd95f042":"sendRemainsToOwner()","bd963442":"handleRefundRequest(address)","bd968eed":"runeToWeiRatio()","bd96b348":"GeBitToken()","bd97ce3a":"changeReferrer(address)","bd987008":"setAccountIsNotFrozenForReturn(address,bool)","bd991fc5":"setGroupRight(string,string,bool)","bd9934f1":"freezeAddress(address,uint256)","bd993f9e":"COREthExchangeRate()","bd998dc8":"CloseSale()","bd9a0158":"setTimeConstants(uint256,uint256)","bd9a11fd":"finalstate()","bd9a548b":"getPrices()","bd9a5673":"oraclize_query(string,string[5])","bd9b49b7":"goalCompletedBlock()","bd9b6d86":"confirmOwner()","bd9b6e85":"tokenTranslate()","bd9c33bc":"_discount(uint8)","bd9c5688":"distributeFee(uint256,address)","bd9ca422":"AIChain(uint256,string,string)","bd9d6b37":"AddNewPresalePackage(uint16,uint256)","bd9d6d7f":"memeData(uint256)","bd9e6bfc":"makeBuyOffer(uint32)","bd9ead1f":"calculateClaimableReward(address,address)","bd9ebfbb":"marketSellOrdersNoThrow(uint256,bytes[])","bd9ec492":"maximumEther()","bd9ef436":"witnessOf(uint256)","bd9f8917":"finalizeEnableRefunds()","bd9fbe7b":"getDefaultAQL()","bda00866":"getAmountOfUnlockedTokens(address)","bda02782":"b(address)","bda1504b":"currentSize()","bda1f35e":"Fleuth()","bda2aa53":"testUnsyncedRate()","bda2e692":"DinosaurFarmerNew()","bda330f7":"refundingStarttime()","bda393d3":"totaldividends()","bda4cf80":"_pfind(address)","bda4fd89":"totalItem()","bda5c450":"calculateDividendTokens(uint256,uint256)","bda5ea03":"tkwins()","bda6642c":"changeStartingPricesLimits(uint256,uint256,uint256)","bda6c497":"borrowerReturnDate()","bda70d92":"destroyOldCoins(address,uint256,string)","bda77531":"changeAdultDragonStage(uint8)","bda7c3ee":"delegateTransfer(address,address,uint256,uint256)","bda81086":"jsonRead(string,string)","bda8bf45":"getWitnessWeiCost()","bda9a055":"getStepsCount(uint256)","bda9b45c":"whitelistMe(uint128,uint8,bytes32,bytes32)","bdaa80c1":"TronX()","bdaacabd":"buyXname()","bdaacbbe":"calculateAdminFee(uint256)","bdaae1e7":"createGame(uint256,uint256,uint256,uint256)","bdab5fb0":"fishLocation(bytes32)","bdace3de":"ChessClubLiveChessCoin()","bdad3db2":"_mintTo(address,uint8,uint256)","bdad4dc3":"allocate(address[],uint256[])","bdad8112":"hashArguments(address,uint40,uint40,uint128,uint256)","bdaeb0a0":"m_GameHidden()","bdaf2fae":"timeBought(uint256)","bdaf78fb":"refundUser(bytes32,bytes32)","bdafcda9":"logClassic(string,address)","bdb001a7":"mana()","bdb00fb9":"blackjack(uint256,uint256,address)","bdb084b2":"startCrowdsaleY1(address)","bdb10825":"MOOVIN(uint256,string,string)","bdb15209":"getNewPrice(uint256,uint256)","bdb27170":"setLockinManagerAddress(address)","bdb337d1":"gameOver()","bdb4dc6e":"getBrickSize()","bdb4f321":"balanceOfStocksAt()","bdb57edc":"TokenRedeem(address,uint256)","bdb5daf5":"OvisAddress()","bdb66236":"pushDividends()","bdb6bce8":"livingSupply()","bdb81203":"newGrant(address,address,uint256,uint256,uint256,uint256,bool)","bdb9c11f":"transferTokensFrom(address,address,uint256,uint256)","bdb9f28d":"setPresaleAddress(address)","bdbaae63":"mint(int256)","bdbb829d":"haltICO(address)","bdbbf429":"escrowHistory(address,uint256,uint256)","bdbbfcad":"stageAmount()","bdbcd001":"testSetValidProvider()","bdbcd192":"PowerEnabled(address,address,address,address)","bdbed722":"getAllTokenIds()","bdbf40a9":"Certify(address,uint256)","bdbf7d4c":"DELETE_NAME_ROLE()","bdc056c0":"BanknadToken()","bdc06de4":"SGTExchanger(address,address,address)","bdc0ba8e":"disableMaintenance()","bdc0f93c":"node_count(uint256)","bdc2866e":"MasterMindAlliance()","bdc2f1e8":"multivestBuy(address,address,uint8,bytes32,bytes32)","bdc31ce8":"Roto2coin()","bdc33928":"placeIndexToApproved(uint256)","bdc441b2":"getItemCount(uint256)","bdc4843a":"lockAddressAfterITO(address,address)","bdc6d9ab":"schedules(uint256)","bdc742fc":"updAcceptDonate(bool)","bdc74e23":"_processTokensAssgin(address,uint256)","bdc850d6":"ALasser()","bdc8e551":"isICOOver()","bdc95b32":"registerIdentity(string,string,string)","bdc963d8":"getUIntValue(bytes32)","bdc99152":"Token_1_Balance(address,address)","bdcab795":"addBeneficiary(address,uint256,uint256,uint256,uint256,bool)","bdcafc55":"setSaleFee(uint256)","bdcbd9d1":"howMuchCanXContributeNow(address)","bdcbda5c":"AccountTransfersThawed(address,bool)","bdcc3439":"add_master(address)","bdcc809a":"setReleaseCompany(uint256,bool)","bdccd1af":"TokenHolder(uint256,address)","bdcd0262":"addRecord(bytes32,bytes32,bool)","bdcd21a1":"spawnRaceManual(uint256,uint256,bool)","bdcd3071":"LogBonusLOTRedemption(address,uint256,uint256)","bdcdc0bc":"updateTotalAvailable(uint256,uint256)","bdce46be":"PriceIncrease(string,uint256,address)","bdced258":"VendCrowdsale(uint256,uint256,uint256,address,uint256)","bdceed0b":"gvToken()","bdcefb62":"FRST_CRWDSALE_RATIO()","bdcfbc37":"ANMInflationVesting()","bdd088e9":"littleMonster()","bdd2ae24":"add(bytes,int256,uint256)","bdd2d286":"drawPlayer(address,address)","bdd30406":"successfulWithdraw()","bdd36562":"getBonusByAddressAndIndex(address,uint256)","bdd3abd9":"MjolnirWebsite()","bdd3fea0":"set_for_sale(uint256)","bdd41d4c":"ParagonCoinToken(address)","bdd50908":"approveWithdrawAddress()","bdd5be2f":"performBuy(address[8],uint256[6],uint256,uint256,uint8,bytes32,bytes32)","bdd5f8da":"weiPerSgd()","bdd62b7b":"defective(bytes32,uint256)","bdd75267":"OPULENCE()","bdd7908b":"getFishParams(uint256,uint256,uint256,address)","bdd7c220":"CryptessaLiquidCoin()","bdd83add":"isAllocated12()","bdd8a366":"g1()","bdd8f051":"SmartOToken()","bdd9f4e7":"batchInnerTransfer(address[],address[],uint256[],uint256)","bddac117":"SetAmount(string,uint256)","bddae40e":"setCommittee(address)","bddba4eb":"grantRole(address,string)","bddbe244":"get_vice_pic(uint8)","bddcfead":"MakeWinner(address,uint256,uint256)","bddd0abd":"ExampleToken(uint256)","bddd1e7e":"WITHDRAWAL_END_TIME()","bddd3202":"_tryTriggerPayout(uint16,uint256)","bddd3a6b":"step7()","bddefc06":"withdrawed(address,uint256,string)","bddf66ff":"claimMigrate()","bde18839":"OHGVientiane()","bde1f585":"endCrowdsalel()","bde236a5":"checkClaimEntitlement()","bde27f4a":"forwardToHotWallet(uint256)","bde2ddf2":"_forwardFunds(address)","bde4e7c2":"tokenAddFee()","bde5c4a2":"_stealCardWithId(uint256)","bde60ac9":"donate(uint64,uint64)","bde66362":"_createNinja(uint256,uint256,uint256,uint256,address)","bde6a5a9":"burnPrice()","bde7ef86":"SynTokenCrowdsale()","bde7fa7d":"removeWhiteListed(uint256)","bde842ac":"getJobStatus(uint256,uint256)","bde86dd1":"tokenExpirationTime(uint256)","bde8a93e":"setBankroll(address)","bde8c509":"mintIdentityTokenDelegated(address,address,uint8,bytes32,bytes32)","bde8cd4d":"icoPool()","bde97455":"SCRefundVault()","bdeb130c":"doPayment(uint256,uint256,address)","bdeb45b8":"expireIfNecessary()","bdeb9fb4":"tokensAvailableForSale()","bdec5cce":"LotteryRoundCompleted(bytes32,uint8,bytes4,uint256)","bdeddb45":"setMyICOContract(address)","bdee21ff":"test_oneValidAssertFalse()","bdef744b":"PriceTwoDisable()","bdf1211e":"getPercentBurn()","bdf1e7cf":"getProviderReward(address,uint256)","bdf27b50":"setPOOL_edit_21(string)","bdf2a0f5":"fundDaoFor(uint256,uint256)","bdf3390e":"checkPwnData()","bdf384a8":"peekUpdated()","bdf391cc":"getPair(uint256)","bdf3c4ae":"stock()","bdf44067":"TCASHx()","bdf499e1":"DappHunt()","bdf4bb73":"DatToDtrcNumerator()","bdf4e7c6":"TaskRegister(address,address,address)","bdf5fba1":"COMMUNITY_POOL_ADDR()","bdf63c15":"RSPLT_F()","bdf692f4":"Propersix()","bdf6fb56":"requestMilestonePayment(uint256)","bdf70087":"getInvestor(bytes32,uint8)","bdf70de1":"SportXToken()","bdf7220f":"getFinalTeams()","bdf75a6a":"PRICE_RATE_FIRST()","bdf7716d":"getNodeHeight(bytes32)","bdf79c9d":"Adapter(address,address,address)","bdf7a8e6":"airdrop(uint256,address[])","bdf7f22f":"puremail()","bdf82b2a":"killFrost()","bdf86a66":"give(address)","bdf88d34":"stopTest()","bdf944b3":"depositAffiliate(uint256)","bdf99bd4":"AntPetTempleToken()","bdf9f646":"disApprove(address)","bdfaa337":"totalAlloc()","bdfb481d":"ABDEL_ALLOCATION()","bdfbab66":"getReferals(address)","bdfc0522":"investBounty(address,uint256)","bdfd582b":"FailClosedVault(address,address,uint256,uint256,address,uint256)","bdfd6257":"settingNameExist(string,address)","bdfdb519":"accept(string,uint256,uint16)","bdfdbf56":"read_u16_array()","bdfe7d47":"addresses(string)","bdff85cf":"ArrAccountIsNotFrozenForReturn(uint256)","bdff9fca":"checkTotalPaid()","bdffd282":"SIZE()","be0043bc":"removeMinterByIndex(uint256)","be007380":"DapdapNiubi()","be01bc87":"carTaxiCrowdsaleAddress()","be02bc3c":"internalTransfer(address,address,uint256,uint256)","be030bd8":"_setToken(address)","be038478":"createPermission(address,address,bytes32,address)","be03c602":"test_get()","be040fb0":"redeem()","be041614":"storedDataInBytes()","be048d04":"getOrganizationalCertAddressByID(string)","be0522e0":"inflation()","be063693":"intermediadorAprovaPagamento(bool)","be0638e4":"WealthShare()","be06ae25":"VirsymCoin()","be06e4e8":"inheritedConstant()","be08728f":"_setRemovalPrice(uint256)","be08d744":"TFcoin(uint256,string,string)","be099e7d":"endICOs()","be0ad4d1":"calculatePayoutVariables()","be0ca01b":"resetChallenge(uint256)","be0d4da4":"produceLottoNumber(uint256,uint256)","be0da251":"CANCELLED_FEE_FLAG()","be0e9d75":"removeWorker(address,address)","be0ecd32":"synthInitiatedExchange(address,bytes4,uint256,bytes4,address)","be0f0a50":"setPriceStep5(uint256)","be0f27cf":"rejectBountyTransfer(address)","be0f6bcb":"End10()","be104849":"AutorizeRefund()","be10862b":"partner()","be10c33d":"LogOperatorRem(address)","be116c3b":"removeProxy(address)","be11ce2f":"minEthContribution()","be1271c4":"setPrice(uint8)","be140381":"firstEntranceToSaleStateUNIX()","be14e5fc":"ETH530on420()","be154a18":"Partial8Transfer()","be160a92":"ERC20token(uint256,string,uint8,string)","be162060":"validCrowdsale()","be163d75":"validPurchase(uint256)","be165566":"setTokenBankrollAddress(uint8,address)","be169856":"getOriginByIndex(uint256)","be16dccd":"tomoDeposit()","be177c6a":"addJoinAirdropQuest(address)","be17a8b1":"doCustomAirdrop(address,address[],uint256[])","be17be5d":"total_minted()","be189035":"modifyIndividualCap(address,uint256)","be18a08b":"finishUpRound(int256,string)","be190032":"timespan()","be19d926":"Britishcoin()","be1abba5":"payoffAmount()","be1b7b4c":"FIRST_UNLOCK()","be1c766b":"getLength()","be1eefbf":"hotStore()","be1ef5c1":"approveWithdraw(address,address)","be1faaaf":"depositCoupon(address[2],uint256[7],uint8,bytes32[2])","be1ff08b":"sbtToken(address)","be20d298":"AxiePresale()","be20f9ac":"getSlotInfo(uint256)","be213c2d":"startBoughtExit(bytes32[],uint256,bytes32[])","be220272":"houseWithdraw()","be22f546":"daiToken()","be22f6aa":"LUYOCrowdsale()","be23d291":"requestPrint(address,uint256)","be241871":"isTxExist(bytes32)","be2430fe":"sendValues()","be25270f":"hash(string,uint256)","be25d0ce":"buyerCapHighEther()","be2671c9":"getUserBonusBalance(address)","be26733c":"Kill()","be268c3f":"batchSubmit(address[])","be275680":"submissionOpen(uint256)","be27b22c":"claim(bytes,bytes)","be28f5db":"makeTokens()","be29184f":"mint(address,uint128)","be292552":"setMintAddress(address,address)","be297530":"Coinname()","be29d81f":"BRL_Omnidollar()","be2a2ff2":"getAccountBlockedFunds(address)","be2b1047":"hodlerTimeStart()","be2b5996":"designateAdmin(address,address)","be2d8b2d":"PowerToken()","be2dbe21":"Raffle()","be2dcd6c":"buyMFCoins(address,uint256)","be2eaad4":"expectedFunds(uint256,bool)","be2ef9f0":"secondWalletPercent()","be2f3059":"RcdGet()","be2fd146":"addMultiRequest(address,uint256,uint256,address)","be2ff4a9":"withdrawBank(uint256)","be30eda8":"transferAndLock(address,address,uint256)","be30f0a6":"setPurchaseLimits(uint256,uint256)","be317e7e":"ICOReserveLockUp()","be31b600":"CART()","be31ffed":"AOSToken()","be32cf8d":"mix()","be32eeba":"getFishIdByPos(uint256)","be3400b8":"CharityCashCoin()","be34dab3":"addBrick(string,string,uint256,string,bytes32[])","be354949":"setReservesForExchangeTokensWallet(address)","be35525d":"setPlayerAffID(uint256,uint256)","be357616":"withdrawFee(uint256)","be361f60":"retrieveChange()","be363e36":"sendMoneyBack()","be36e676":"Set(bytes32,bytes32)","be38e241":"activations()","be3912fa":"registerProduct(uint256,uint256,uint256,bytes,bytes)","be3945e4":"getFee(address,address,uint256)","be395cd5":"setPoliticsForJackpotParticipantsList(bool)","be3c33f4":"ZeroXCoin()","be3c8488":"previousStageIsFinalized()","be3c92a6":"setLimitTokenPurchase(uint256,uint256)","be3ca849":"getFunding(address,uint256)","be3cbb04":"iWantXJade(uint256)","be3daf55":"shouldLiquidate(bytes32,address,address,address,address,uint256,uint256,uint256,uint256)","be3dd131":"migrateFunds(address[])","be3dedae":"changeOwnership(string,uint256,uint256,address,address)","be3e33d5":"play(bytes1)","be3e41b1":"bonusFirstTwoDays()","be3eac25":"WithdrawEnabled()","be3ee935":"addClient(string,string,string,string,uint256,uint256,uint8,uint8)","be3f3471":"total_trades()","be3f34a1":"collectIncome(address)","be400cad":"KudosToken(string,string,string,uint8,address)","be4054b9":"commitReading(address,uint256,uint256,string)","be40887d":"sumDepth(uint128)","be408a5f":"winner_percentage()","be410448":"getERC20Id(uint256,address)","be427b1c":"setFinderFee(uint256)","be4299a6":"Maxsupply()","be4413fc":"Donator3()","be4474b4":"processFee(uint256)","be44e2d6":"getdeptreqscount()","be457017":"validateRefundSignature(uint8,bytes,address)","be45a26f":"variables()","be45af43":"InnovateToken()","be45cdb8":"crowdsaleTokenBalance()","be45d47e":"whitehatRecover()","be45fd62":"transfer(address,uint256,bytes)","be46203e":"Claim_TRAC_900()","be4663a1":"vestContract()","be46b94c":"ROLE_KNOWN_ORIGIN()","be46bffb":"verifyLottery(uint8,bytes32,bytes)","be46e9ca":"starting()","be46ee5f":"postNewAnswer(bytes32,bytes32)","be471027":"limitedSale()","be47dca1":"getNumberOfClients()","be482cc2":"getCurrentLotteryJoiners()","be48acc4":"MAX_PERSIANS()","be48d81e":"team_accounts(uint256)","be490a04":"Banned(address,bool)","be494573":"pureBalanceOf(address)","be4951e4":"setBroker(address,address)","be4a0910":"sendTokensSale(address,uint256)","be4a0b11":"preAssign(address)","be4a471c":"memoryFactor()","be4a6bad":"newOrder(address,uint256,uint256)","be4a7160":"closeDistribution(bool)","be4a90eb":"GoramCoin(uint256,string,uint8,string)","be4aba09":"tokenR6()","be4b1772":"withdrawToken(uint256,address)","be4bb31a":"WAmlingCoin()","be4c3a0c":"getContractOwner(string)","be4c45d5":"changeBuyingPrice(uint256)","be4c9e96":"TRONIC()","be4cbafd":"RichGoldToken()","be4cc281":"ManagerUpdate(address,address)","be4ce05c":"JULY()","be4d06cc":"setLLV_edit_16(string)","be4dbb5e":"getInvestorByValue(address)","be4dbe26":"getBlocklancerContractHolder()","be4ea54d":"setDeveloper(string,uint256)","be4eb0e9":"getUserFromId(uint256)","be4ebda3":"BOUNTY_SHARE()","be4f4fdf":"restrictedShare()","be50af2e":"tokenWithdraw(address,uint256)","be519862":"percDown(uint256)","be51bc0a":"FuncToken()","be523c23":"dungeonPreparationTime()","be5308ea":"BitplusToken(uint256,uint256)","be53874f":"emergencyFundReleased()","be53f968":"getPreSaleStart()","be54c568":"starting(uint256)","be54f214":"monthWithdraw()","be5638ff":"investor_contains(address)","be5648c3":"getResoType()","be571e2e":"BigbomToken(uint256,uint256,address,address,address,address,address,address,address)","be571e8f":"getTokens(address,bytes32,uint256)","be572d52":"addItem(uint256,string)","be576364":"synthInitiatedFeePayment(address,bytes4,uint256)","be592488":"validateName(bytes)","be597faa":"_finishTge()","be59b4b1":"mostRecentCaller()","be5affd1":"address3a()","be5b9c74":"MultiSigWalletMock(address[],uint256)","be5babc2":"CryptoGems()","be5c2423":"failedVerificationSlashAmount()","be5df6cb":"findLover(address)","be5e72e0":"updateBasePrice(uint256,uint256,uint256,uint256)","be5ea335":"betERC20(address,bool,uint256)","be5eb443":"getScriptAction(bytes,uint256)","be5eeb2d":"getSociety(uint256)","be5f3d12":"allocateTokensForAdvisor()","be600276":"move(uint16)","be6002c2":"exec(address,bytes)","be6010f9":"calcHash(uint32,uint8,uint256,uint256,int256,bytes32,bytes32,uint256)","be60988e":"getLotteryByID(uint32)","be60989d":"addCard(string,uint8,string,string,string)","be60be76":"TokenMigration()","be60e771":"ZAMZA()","be616e83":"processAP()","be621764":"TradeRegister()","be62e98e":"MIN_PRICE_SALE()","be6307c8":"getDraw(uint256)","be6340b8":"mintedDirectly()","be63c8ca":"Retire()","be63f7b1":"TobkaCoin()","be640921":"regInitAccount(string,string,string)","be65d234":"Owner_Changed(address)","be65d27a":"vaultDeposit()","be66399f":"setOuverture_effective(uint256)","be676ac6":"transfer_balances(address[])","be67f4fd":"ActualShareManager()","be6872af":"totalTokensForSold()","be6896c3":"PropellerheadSupport()","be692cd3":"erase_data()","be6ad6d2":"ForceEther()","be6b6ba6":"getVestingStageAttributes(uint8)","be6c03ff":"stakedForProposal(address,address,bytes32,bytes32)","be6c554f":"firstCheckpointPrice()","be6c61f5":"unsetIdentity(address,address)","be6c87ad":"item(address,address,uint256,bool,bytes)","be6cef0a":"msgExaminer()","be6d055a":"proxy(address,bytes)","be6d91e6":"getBalanceOfSender()","be6fc181":"getFeeParams()","be71021f":"_crownFreeze(uint256)","be7118a7":"Dilution(address,uint256)","be71248a":"payWinner()","be737f72":"toSmallestShareUnit(uint256)","be7385e3":"getPlayerSpaceships(address)","be73983a":"reservePR()","be73d879":"joinBytes(bytes,bytes)","be74264d":"getFeePercent()","be74381f":"calculatePercents(address)","be743ccb":"MCCPP()","be754ba4":"buy20Price()","be760488":"assign(address,uint256)","be782f58":"setBreedTimeout(uint32)","be78632e":"nstDeposit()","be788e70":"getWithdrawableBalance()","be78bb7a":"transferCallGas()","be78e656":"buyXaddr()","be79ca77":"preSaleBonus3Amount()","be7a1540":"setlvlNfee(uint256)","be7a3164":"getNextAuditRequest()","be7aa7be":"SportStarToken()","be7b4858":"isOpenDistributionClosed()","be7c06ba":"iniOwner()","be7c29c1":"getNewDAOAddress(uint256)","be7ccd7e":"setupMiniGame(uint256,uint256)","be7cddf8":"TwoD()","be7e2848":"SkillChainContributions()","be7edebe":"setURIBase(string)","be7f5d23":"addressesReserving(uint256)","be7fdab1":"returnMoney(address)","be80073a":"SentTo(address,address)","be802f05":"getIcoTokensSold()","be80dcfd":"floatEconony()","be81d5bf":"CROWD_WEEK3_PERIOD()","be82f56b":"drainToken(address,address)","be82fffe":"allPolls()","be8360c5":"_maint_EndPromo()","be83a6b4":"ShitCloneslordReq()","be83b3c6":"LogFinishICO(address,address,address,address)","be83ff83":"vipRate()","be854def":"robPantryT(address,uint256)","be85bf3b":"PaymentWithdrawn(uint256,address,uint256)","be85e4ef":"initEngineer()","be86d5a7":"makerTransferEther(address,uint256)","be86d996":"SINGLE_SALE_MULTIPLIER()","be87662b":"inviteProfit(address)","be87bcfc":"getReport(uint256,uint256)","be87c1ab":"returnBalance(address[2],uint256[7],uint8,bytes32[2])","be882d91":"setQuestionFee(address,uint256)","be888bd7":"devteamReserve()","be89900b":"PIOE()","be8a4737":"withdrawalT4T()","be8a550d":"ICO(address,address)","be8acd3f":"ordersLength()","be8b4f45":"HussyToken()","be8bd3df":"IlumXToken()","be8c1bcc":"batchDrop(address[],uint256[])","be8cd7b8":"participatePresaleNow()","be8db3cf":"deadlineBlockNumber()","be8dd49a":"getTokenUserCounter()","be8ecef3":"requestAddOwner(address,string)","be8eef8e":"hasOpened()","be8f316a":"testmsg()","be90be7f":"clearPoolsDone()","be9117cc":"curryChickenToken()","be912a0a":"getAyantDroitEconomique_Compte_7()","be913b6f":"ETH_FUND(address)","be916531":"test_OverSixtyPercent()","be91de53":"frozenBalanceOf(address)","be91ebe5":"tgrSettingsChangeRequest(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","be92ccfd":"setDisableBet(uint256)","be92f334":"astrSold()","be9413a7":"_cancelRole(address,address)","be95e01a":"payout(uint256,address)","be96031e":"playerinfo(address)","be96bb92":"_isFullOrNull(uint256,uint256)","be96faf7":"AWYManKeepChain()","be975f57":"CreateSTR(address,uint256)","be981ff4":"transferOwnershipForVanityURL(address)","be986420":"quarters()","be987c11":"PriceDecrease(string,uint256,address)","be988dbc":"BroCoin()","be999705":"addFunds(uint256)","be99a797":"setNewRegister(int256,string,string,uint256)","be99a980":"setAddress(bytes32,address,bool)","be99c50f":"purchaseInternal(uint256,address)","be99ed6f":"getCompte_41()","be9a6555":"start()","be9a9a28":"getRequestStatus(uint256,uint256)","be9aa8ac":"setSaleContracts(address,address,address)","be9b076d":"Initialized(uint256)","be9b3282":"cookUpFee()","be9b3e8a":"reclaimEth(uint256)","be9ba97f":"maxContributionPerAddress()","be9c1add":"heldBalanceOf(address)","be9d89c5":"createTokenToMarket()","be9ddfed":"getSanTimeLastMove(uint256)","be9e1080":"_escrowPaymentEarning(address,bytes32,uint256,uint256,address,address,bool)","be9e3774":"deathData_f18()","be9e4697":"getDiscountTrancheDiscount(uint8)","be9f2dc0":"hourPotHighscore()","be9f7a20":"setInsertCar(bytes32,uint256,uint256,uint256,uint16,uint8,uint8,uint8,uint8,uint8)","be9fa8dc":"Ethex(address,address,uint256,uint256,address,uint256)","bea046a1":"cashOutShip(uint32)","bea05440":"CurrentStatus(uint8)","bea10370":"hasRecentPrice(address)","bea124a6":"query(bytes,bytes,int256)","bea1dcf8":"taxCollector()","bea24735":"create_a_new_market(address,uint256,uint256,uint256)","bea28a30":"undoTransferOwner()","bea31228":"ObirumIssued()","bea3c8b3":"PardusNetwork()","bea40bad":"composeJingle(address,uint32[5],uint32[5],string,string,uint8[20])","bea412fa":"RedBUX()","bea433a9":"TriumHolding()","bea4ae88":"saleDue()","bea4c4ee":"setIBalance4(uint256,uint256,uint256)","bea50ae3":"setConfirmationPeriod(uint256)","bea51ec2":"SunnyX()","bea51f81":"addToKYCList(address)","bea5f9cd":"newPokemon(uint256,uint256,uint256)","bea677dd":"MCS()","bea69bb9":"Bal()","bea70578":"getPOOL_edit_16()","bea72c0a":"dsAdd(uint256,uint256)","bea76c3c":"disputeBlockNos(uint256)","bea7c13a":"gasPriceForCompensationAtHomeSide()","bea8bd27":"updateVettingTime(uint256)","bea948c8":"GetGift()","beaa4765":"setComplete(bool)","beab0638":"TokenAllocate(address,uint256)","beab3537":"isClaimed(bytes32,string)","beab9848":"SelfllerySaleFoundation(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint8)","beabacc8":"transfer(address,address,uint256)","beabb2c2":"proxyEnableRefunds()","beabdb7b":"isPermitted(bytes32)","beac4bc3":"pauseUET()","beacf74f":"test_insert_findWithHintPrevDecreased()","bead0513":"leaveCommunity(address)","bead21a6":"lockAtTime()","bead45cf":"deposit_amount()","beadd203":"confirmWarranty(string,string,string)","beadf957":"cancelOperation(bytes32)","beae207f":"startAirdrop(uint256)","beaf56a6":"changeInsurer(address)","beafa2dc":"sacToken(uint256,string,string)","beb08ab9":"projectWallet()","beb0a416":"website()","beb1274d":"medianize(uint256[])","beb2b55d":"balanceHaben(address)","beb2bad6":"SHITP()","beb318a0":"updateSelfDropStageState(string,bool)","beb38b43":"set(bytes12,address)","beb3a38f":"capDay1()","beb40d58":"queryShare(address)","beb5f658":"compare(address,address)","beb6422f":"setClue1(string)","beb7de13":"updateCaps(uint256,uint256,uint256,uint256)","beb7fd4e":"_setMany(address,uint256,uint256[],uint256[],bool)","beb92f55":"setCaller(address)","beb9571c":"User_3()","beb96be5":"releaseFor(address,uint256)","beb9716d":"canMint()","beb9c90d":"wavesGW()","beb9d27e":"prepopulate(address)","beb9df86":"fwdToENS(bytes)","beba0b11":"ScallopCrowdsale(uint256,uint256,address,address)","beba285d":"privatePlacementAllocatingToken()","bebaa421":"setTrustAddress(address)","bebb7756":"RecievedDonation(address,uint256,string)","bebb7e60":"kscBurnFrom(address,uint256,string)","bebc3bfb":"requestWithdrawal(address,uint256,string)","bebc9d93":"buyCopyright(uint256,string,string)","bebcc045":"description(bytes32)","bebd284e":"registerCoinData2(address,uint256,address)","bebda5b9":"WhitelistUpdated(uint256,string,address)","bebdd5ca":"GenericCrowdsale(address,uint256,uint256,uint256)","bebe3c88":"advisorsPeriodLength()","bebe4f6d":"Standard_5()","bebeb73f":"createRoom(uint256,uint256,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bebf10d5":"WorkflowState()","bebf8498":"addCardToRegistry(address,bytes32,uint256)","bebfe207":"publishMessage(string)","bec0d799":"removeBook(uint256)","bec10cde":"increaseStake(uint256,uint256)","bec13af1":"doBuyerCancel(bytes16,address,address,uint256,uint16,uint128)","bec17f69":"isPreIco()","bec24a0d":"payJackpot1()","bec272da":"IotaGoldToken(address)","bec3150e":"EthereumBrilliant()","bec3e6f3":"overStage(uint8)","bec3fa17":"transferTokens(address,uint256)","bec507ce":"switchfun()","bec5e7b2":"playerDataRecord(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","bec60bd2":"change_token_price(uint256)","bec6bc67":"adoptionRequests(bytes5)","bec6eb15":"buyGladiatorChest(uint256)","bec77cb1":"getOwnerCards(address)","bec7abfd":"getBounsEarningsInRound(address,uint256)","bec809ec":"tomoConvertRate()","bec81091":"executeEtherDeltaBuy(uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,bytes32,uint256)","bec823c6":"BitcoinGreen()","beca159b":"registerUser(address,string,uint256,uint256,uint256)","beca40df":"PERC_TOKENS_TO_DEV()","beca4a8e":"TeleGrams()","beca7440":"right52(uint256)","becb1f35":"isForking()","becb44da":"token_sale_start_block()","beccdb77":"lastFeesCollected()","beccdd91":"updateSecPerBlock(uint256)","becd0580":"payEtherToWinner(uint256,address)","becd283f":"getPurchaseCount()","becd7027":"withdrawPurchasedTokens()","becda0ea":"tune(uint256)","bece1b22":"GameData(address,bytes32[],bytes32[],int256[])","bece2ea1":"tokenPriceIncremental()","bececd4e":"updateVerificationStatus(address,bool)","becee565":"GodeCoin(address,address)","becf0426":"registerAffiliate()","becf3add":"bonusPercent()","becf917f":"DistribFundsReceiverAddress()","becf9ce1":"removeFromAccountList(address)","becfbf69":"peekLastNonce()","bed03fdb":"winnerSelect(uint256)","bed09038":"updateMember(address,address,uint256)","bed0a8e5":"testRegisterSwarmEth()","bed0d1b9":"validTransfer(address,uint256)","bed18966":"getCompletedFlag(uint16,uint16)","bed1a924":"totalICOSupply()","bed1b8b9":"convertToInt(string)","bed1cfcd":"addToOwnership(address)","bed230d0":"burningMansCount()","bed25542":"onTokenReceived(address,uint256,bytes)","bed289c9":"CPolloToken()","bed315f8":"setRate(uint16)","bed33cae":"getCancelableAt(uint256)","bed34bba":"compareStrings(string,string)","bed36fee":"test_insert_null()","bed411a0":"CheckPrize(address)","bed43ffa":"CoinCrowdToken()","bed47ed8":"sId()","bed50ef8":"emitFeesWithdrawn(address,uint256)","bed531fd":"playersAmounts(uint256)","bed54a24":"ert()","bed6701f":"lastweek_winner2()","bed7437f":"setHydroTokenAddress(address)","bed866f6":"donations(bytes32)","bed9404f":"calculateAccountLiquidity(address)","bed9588b":"getUint256Max()","bed99850":"burnRate()","bed99dec":"replaceSecurityDepositRegistry(address)","bed9d712":"chargeJNT(address,address,uint256)","bed9d861":"withdrawStake()","beda363b":"dynamicReverse(uint256[])","beda86b9":"removeContributors(uint256[])","bedaa624":"setBZRxToken(address)","bedb86fb":"setPause(bool)","bedbb1a5":"saucePoolTotal()","bedc17ea":"testFailSetName()","bedc7796":"ownerCountOfCard(address,address)","bedca054":"Crowdsale(address,address,uint256)","bedcb4fc":"EthlanceContract(address)","bedcf003":"ownerBalance()","bedd12a5":"depository()","bedda13f":"setData_1(string)","bedddbc4":"darkcoin()","beddf557":"NOLLYCOIN(address)","bede2cac":"joinedCrowdsales(uint256)","bede4bd8":"lockupOf(uint256)","bedecc06":"seatsCount()","bedefffe":"getOwnerName(address)","bedf0f4a":"Stop()","bedf8e75":"Netyul(uint256,string,string)","bee03488":"getAllSSP()","bee066a8":"blocksUntilWin()","bee11672":"allowBundlingMultitoken(uint256)","bee1351e":"_getJYPCBonus()","bee14b3d":"getDevBalance()","bee16cae":"getCodeToken(uint256)","bee200cb":"underLimit(address,uint256)","bee2135e":"prefixedHash(string)","bee23c42":"contain(address[],address)","bee28042":"LVX()","bee2e134":"ethCollected()","bee36f37":"disableMiniSwapLock()","bee40aa4":"setCallType(uint256,uint256)","bee47606":"originalPricesBySpinner(uint256)","bee4bbeb":"unsetIsBuyByAtom(uint256)","bee4cc6b":"getBAB(bytes32,address)","bee588e9":"registerCert(bytes32,bytes,uint256)","bee5cdca":"getProjectById(uint256)","bee5ea6d":"PurgeCoin()","bee604ea":"addGame(address,string,uint256)","bee6348a":"presaleOpen()","bee712da":"buyZone(uint256)","bee96d9f":"updateGoldReferrer(address)","bee98dff":"get(string,int256)","beea7bfb":"newSubdomain(string,string,string,address,address)","beea887c":"totalVCCoin()","beeae9a6":"Ather(uint256,string,string)","beeb0578":"processFundingFailedFinished()","beeb0a82":"SeaCoin()","beeb1b5d":"amountRaisedIsc()","beeb6d87":"withdrawCoin(bytes4,bytes32,uint256)","beebeff7":"tokenForAdvisor()","beec1caa":"issueCertificate(string,string,string)","beee5852":"opponentAmount()","beee9a34":"TIER4()","bef17ed0":"totalTeamContributorIds()","bef19a8b":"narcosByDistrict(uint8)","bef23131":"_createBurnLot(address,uint256)","bef28736":"UpgradedController(address)","bef2e0d8":"Variant()","bef35ccb":"requestClose(uint64)","bef39963":"releasedTokens()","bef3a083":"deadLine()","bef44f18":"transferChild(uint256,address,address,uint256)","bef4876b":"finished()","bef4f95d":"alarms(uint256)","bef5223f":"withdrawTokenToFounder()","bef55ef3":"readData()","bef566ef":"requestForMigration(address)","bef5bb45":"checkHash(address,string)","bef72fa2":"controllerLookupName()","bef7a2f0":"Fee()","bef7c258":"tierStartTime(uint256)","bef80387":"KYCCrowdsale(address)","bef8f7a5":"userAddressAdded(address)","bef90b94":"GetShipsByOwner(address)","bef973e4":"getUnclaimedFunds()","bef97c87":"transfersEnabled()","bef9e4ce":"getPreviousProfit(uint256)","befa1e2f":"totalBets()","befa7d5a":"addressFundDevelopers()","befaed75":"Sell_Offer(uint256,uint256,uint256)","befb6e56":"calCandidate(address)","befbae04":"completeIcoPart2()","befc3e2b":"getInvested()","befc5c32":"getOwnersItemList(address)","befcc34d":"updateSignedDealsCount(address,uint256)","befda2ff":"postIcoPhaseCountdown()","befe0e79":"infinity()","befe6299":"buySPIKE()","befed472":"SKToken(uint256,string,string)","beff6dbf":"getInsurancesCount(bytes32)","beff778e":"CoinBazarCap()","beff90dc":"isVersionContractOrLogic()","beffc416":"set_address2(address,address)","befff6af":"setUseDELEGATECALL(bool)","bf02dbcf":"randNums()","bf03e092":"join_address_pay(uint256,address)","bf03ef7d":"setDailyTokenLimit(uint256)","bf04820b":"totalLosses()","bf050334":"resolveDisputeBuyer(string,address)","bf052a8a":"countConfirmations(uint256)","bf059dc2":"_nonce1()","bf05cbe6":"hasFourStepWithdraw()","bf05d653":"endVesting(address)","bf06444b":"BrokenContract()","bf07aae7":"CQT(uint256,string,uint8,string)","bf082e38":"GICT()","bf084408":"submitProof(bytes32)","bf0872ef":"totalDiscount(uint256,uint256,string)","bf08778c":"seeAllNumbers()","bf09466f":"addEntryIn4WeekPeriods(address,uint256,bool,uint256)","bf0a07bd":"getHardCap()","bf0a53f5":"Notarize(bytes32)","bf0aaaf5":"OWN_ChangeState_locked(bool)","bf0b0c52":"PaisaToken()","bf0b47ce":"getWinLoseAmountByBettingOwnerInGamblingParty(uint256,address)","bf0b88aa":"CanYaDao()","bf0bb225":"recoverAddressFromSignature(bytes32,uint256,address,address,uint256,address,address,uint256,bytes32,bytes32,bytes)","bf0c4343":"dividends_by_type(address,bool)","bf0ce059":"isRootAuthority(address)","bf0d44d5":"testControlCreateWithParentsForeignNotInUse()","bf0d4f03":"EventLevelUp(uint32,uint32,uint32)","bf0d51be":"COINLAW()","bf0dc1c0":"IICToken(uint256,string,string)","bf0df0c1":"Start3()","bf0e4900":"randomWithNonce(uint256)","bf0e63d7":"FastGrowthToken()","bf0e9d61":"getProof(string,string)","bf0f5495":"volunteerWrite()","bf0f88ae":"Google()","bf101b32":"isTransferAuthorized(address,address)","bf1031d9":"proposeTemplate(address,address)","bf10bde1":"calculatePrize(address,uint256,uint256)","bf1152db":"preTransfer(address,address,uint256)","bf11f412":"buyCreditsAndSpendAndRecover(string,uint256,uint8,address,uint256,address)","bf120ae5":"freeze(address,bool)","bf12165e":"fillUpSlot(uint256,uint256)","bf125c49":"balanceIsZero(address,string)","bf12bf4f":"transformContract()","bf13633c":"setvalues(string,string,string,string,string,string)","bf137795":"canSpawnAs(uint32,int256,address)","bf1482fa":"getDonators()","bf14c119":"fund(bytes32)","bf14dcbf":"collectStakingBonusTokens()","bf152765":"userBalance()","bf15a645":"add_numbers(uint256)","bf15d827":"issueTDETokens(address,uint256)","bf15e42a":"CoinClaim(string,string,uint8)","bf15ea76":"transferrableTime()","bf16e9e8":"PccToken()","bf16ec99":"_computeCut(uint128)","bf176c34":"profitAddr()","bf1792b3":"toHex(uint256)","bf187478":"shift_left(uint64,uint256)","bf18dfbe":"PhantomToken()","bf190c8e":"GACToken()","bf1a2e52":"NucleusVisionTokensMinted(address,uint256)","bf1b31c2":"ThirdPartyPlatformAddr()","bf1b5f19":"withdrawRequest(int256,int256)","bf1bb055":"getCCH_edit_14()","bf1c30f5":"applicationNameTaken(string)","bf1c8016":"closedSaleWallet()","bf1cd416":"GrowthPool_Released()","bf1d4c66":"lastPurchaseTimestamp()","bf1dfb8a":"totalBattles()","bf1e799b":"getTimelock(address)","bf1e8497":"preCrowdMinContribution()","bf1fe420":"setGasPrice(uint256)","bf205ebc":"luckyNumber()","bf208e00":"setMinAcceptedAmountInPresale(uint256)","bf2095a4":"sellManually(address,uint256)","bf212637":"getMatronId(uint256)","bf21e45d":"changeCrowdSaleDates(uint8,uint256)","bf22c457":"getJob(uint256)","bf22d670":"boolCallWithArray(bool[4])","bf22f63d":"PasswordChallenge(bytes20,bytes32)","bf23b411":"eosPRIVATE(uint256,uint256)","bf24a794":"getMostVotedOptions()","bf24aad0":"set_maxDETsPerReturnLessThan(uint256)","bf24de3d":"transferTo(address[])","bf251bc6":"foundersPercentOfTotal()","bf251e7f":"TOTAL_CROWDSALE_FUND()","bf254915":"set_Gas(uint256)","bf255974":"GoldRegistry(address)","bf25bf2e":"ethToTokenRest(uint256,uint256)","bf25c597":"VernamToken(uint256)","bf260037":"addressFutureInvest()","bf2699e7":"initValidator(address,address,address)","bf26bf58":"MartinKoTokenHolder()","bf277962":"beneficiary(bytes32,int256)","bf27f585":"totalFundsReceived()","bf27fa7c":"OCoin()","bf2805e3":"getVestingAllocation(address,uint256)","bf2860a4":"allocateProofTokens()","bf28d7ee":"_setOutcome(int256)","bf29a854":"aboutFactoryWorkers(uint256)","bf29b90a":"changeAssociation(address)","bf2b7524":"updatePoolAddressCapTier2(uint256)","bf2c1cc8":"setDailyDepositLimit(uint256)","bf2c3dad":"TransferSellAgentSiteReg(address,uint256)","bf2c7cbe":"rateT4T()","bf2d9e0b":"totalRevenue()","bf2e694f":"getPreviousRequest(address,address)","bf2e727b":"BONUS_LEVEL_1()","bf303d14":"convertCountryIndexToBytes(uint256[])","bf30d943":"changefirst24Percent(uint256)","bf31196f":"offerPunkForSaleToAddress(uint256,uint256,address)","bf314640":"newResolution(string,string)","bf31d573":"send_to_darshil()","bf31fc58":"VestingMasterContract(address,bool)","bf326254":"unlockedCustomer(address)","bf32a4b6":"withdrawOwner2(uint256)","bf32bf97":"FailGuyTax()","bf33589b":"createImageTest()","bf33be97":"balanceOfOrder()","bf34040d":"_depositEthereum(uint256)","bf347404":"engravedToken()","bf34ea7d":"makeBatchPayment(address[],uint256[])","bf354389":"Eplay()","bf35588b":"setDepositRate(uint256)","bf35af36":"vestingOwing()","bf35d5de":"FighterCreated(address,uint256,uint256)","bf35d96b":"Lock(uint256,address,address,uint256,uint256)","bf363b18":"transferFee(address,uint256)","bf368399":"leaderboard(uint256)","bf36c5b0":"offerPieceForSale(uint256)","bf36dd16":"icoStartTimestamp()","bf3724af":"f2(uint256)","bf375fb5":"signFork(uint256,bytes32)","bf37689c":"showArrayLength()","bf37b8f1":"devOwed()","bf381f93":"changeVestingAddress(address,address)","bf385c00":"hasSufficientPaymentInternal(address,uint256)","bf390355":"initCasino()","bf391545":"getBAUU(bytes32,address,uint256)","bf395d3d":"getShipProduct(uint32)","bf3986ba":"TrustlessTransactions_TransactionHeight()","bf39ba48":"PRIVATESALE_SUPPLY()","bf3b1101":"transferWalletOwnership(address)","bf3b397b":"tokensToEthereum_(uint256)","bf3b9e38":"a(uint256,uint256,uint256)","bf3bcc41":"isMod()","bf3c1120":"setBytesValue(string,bytes)","bf3c685f":"TOTAL_VALUE()","bf3d6141":"setParams(uint256[],uint8[],uint256[],uint256[])","bf3d9995":"officialWebsite()","bf3da865":"scannedGoldCaps()","bf3e394e":"withdrawInvestment()","bf3e4a79":"CoreTeamAndFoundersWallet()","bf3e67eb":"Sk8coin()","bf3eea48":"privateFundEnabled()","bf3f493c":"AdminAdded(address,address)","bf40b904":"getIssuedBlock(bytes32)","bf40fac1":"getAddress(string)","bf417b9f":"MINING_SUPPLY()","bf419975":"MBLToken()","bf41e16f":"TOTAL_SHARE()","bf428c17":"addTrustedContractAddress(address)","bf4386a0":"maxMembers()","bf439e80":"mintForEarlyInvestors(address[],uint256[])","bf43e91c":"withdrawAffVault(uint256)","bf43ed4d":"dateInit()","bf43fffb":"getFirstEncounterIdFromDay(uint256)","bf44aa70":"setSellCommission(uint256)","bf44eb03":"liquidityReserveWallet()","bf45db19":"ArtGallery()","bf463341":"GetInitData()","bf4637e5":"jackpotPercent()","bf464090":"getManagerCut(uint256,uint256)","bf466c06":"getIntValueByKey(string,string)","bf46ad1d":"approveSponsorableJob(address,uint256,address,address[])","bf46d3df":"canSwap(uint256,address)","bf474766":"joinGame(bytes32)","bf485e95":"getElementLocation(address)","bf487801":"getContractBalanceOf()","bf48d8b5":"setCurrenseeFoundationAddress(address)","bf49649b":"Galatasaray()","bf49d120":"addReview(string,uint256,address)","bf4a185b":"ClientOrderEvent(address,uint8,uint128)","bf4a5485":"extLockBot(uint256,uint16)","bf4a63f8":"withdrawSOC(uint256)","bf4a79e6":"TimeChain()","bf4aaf86":"DefaultActionDelayed()","bf4aeff2":"payoutPeriodEnd()","bf4b72e3":"metaTransferHash(address,uint256,uint256,uint256)","bf4c06a1":"changeLogOwner(address)","bf4d0abe":"NatoExchangeToken()","bf4d5af4":"failures(uint256)","bf4d89b5":"parseInt(string,uint256)","bf4e9615":"calcPriceFromFactor(uint256)","bf4f7cc0":"onlyStores()","bf503a6e":"crowdSalePercentage()","bf506b47":"registerTXS(uint256,address)","bf5103a1":"AUTH_CANMINT()","bf5124d0":"displayCard(uint256)","bf52439b":"BezantERC20Base(string)","bf530969":"setLabel(string)","bf53253b":"NATIVE_ASSET()","bf5371e3":"sendOnRequest()","bf538b68":"BOXToken()","bf538f6f":"mintingCompleted()","bf539711":"buyTokensPresale(address)","bf53dd15":"HBToken(uint256,string,string,uint256)","bf53e3ba":"harvestQuorumPercent()","bf53fa61":"PRIVATESALE_END_DATE()","bf547894":"transferBatch(address)","bf54bb60":"Bitscor()","bf552230":"_changeAttributes(uint256,uint256)","bf5522da":"bounties(bytes32)","bf55486b":"Tanya()","bf559d11":"startTournament()","bf566599":"changeMyName(string)","bf5671fd":"changeSecOwner(address)","bf568a4c":"endIcoByCap()","bf56ac81":"withdrawAffiliateBalance(address)","bf56cc08":"emergencyClawbackEther(uint256)","bf5772b9":"escape(uint32,uint32)","bf583903":"remainingTokens()","bf58aad8":"privatePreSale()","bf59cdff":"getH3Amount()","bf5a451b":"foreverBlockBattleAddressUpdate()","bf5a4dd3":"unlist(uint256)","bf5a79ee":"_getSchellingRoundDetails(uint256)","bf5abfe3":"SimpleConsent(string,address,address)","bf5b2e5d":"MIND_FOUNDATION_AMOUNT()","bf5b4c0c":"getPendingExploreData(address)","bf5b6016":"addContract(string,address)","bf5b6234":"fillSellOrder(address,address,uint256,uint256,uint256)","bf5bb323":"donationMap()","bf5c7f9b":"emissionProvidersCount()","bf5c844b":"oneweek()","bf5cf791":"AIRDROP_TOKENS_NUMS()","bf5e54d2":"updateTokenImprint(uint256,bytes32,int256)","bf5f0169":"deliverTeamTokens(address)","bf5f2b67":"tradingBalanceOf(address,address)","bf5f4edf":"addMonsterClassExtend(uint32,uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint8)","bf5f93e7":"twoHightestBidsDifference(string)","bf5fc2ee":"setStartsAt(uint256)","bf604019":"coinTradeStart()","bf606d14":"sendOneEtherToHome()","bf611c78":"OmniDex()","bf61b517":"FEE_SILO()","bf61e4b2":"AsuRaimu()","bf620a45":"lockAccount(address,uint256)","bf6211d9":"StripToken(address)","bf624273":"expiryBlock()","bf6311c2":"_progressAdPrice(uint256)","bf632e67":"stateController()","bf6537a0":"crowdsaleBeneficiary()","bf654aac":"maxFeePercentage()","bf656791":"getMinContrib()","bf65d492":"FileName()","bf65dd32":"_checkAndCallApprove(address,uint256,bytes)","bf664892":"PARSECS_PER_ETHER_BASE()","bf66a5f9":"indSaleDeposit()","bf6713f6":"getGift(uint256)","bf671782":"handleReferrals(address,uint256,uint256)","bf686453":"PAN()","bf6888c8":"VESTED_PERCENT()","bf6896eb":"signAgreement(bytes32)","bf69d707":"punkBids()","bf6a10d7":"validateContributor(address,uint256,uint8,bytes32,bytes32)","bf6a1413":"hasSigned(address)","bf6ad320":"winnerPrice()","bf6ad32b":"getgbyte()","bf6afbaf":"FeePaid(address,address,uint256)","bf6b43a1":"upgradeCrystalMine()","bf6b6536":"SampleContractOther()","bf6c277a":"getTotalAccessorySeries()","bf6c4de9":"newPLCRWithToken(uint256,string,uint8,string)","bf6ca138":"issuedExternallyTokens()","bf6d91be":"addClient(address,uint256,uint256,uint256)","bf6d9abd":"unlockTransfer()","bf6deda4":"createLotto(bytes,bytes,bytes10,bytes10,bytes)","bf6eac2f":"stake(address,address,uint256)","bf6eb070":"MAX_ALLOWED_STAGE_2()","bf6ec777":"takeFee(uint256,address)","bf6edbd9":"mintFrozen(address,uint256)","bf6f7755":"transferBaseOwnership()","bf7035c3":"getSaleContractDepositEtherMin(address)","bf70a985":"PRESALE_ETH_IN_WEI_FUND_MAX()","bf70bd75":"stopPreIco_step2()","bf716708":"TOKEN_SUPPLY_SEED_PRESALE_LIMIT()","bf730997":"modifyGuess(uint256,uint256,uint256)","bf733e29":"oraclize_newRandomDSQuery(uint256,bytes,uint256)","bf735b13":"createSale(bytes32,uint256)","bf737c87":"JackpotWon(address,uint256)","bf7408de":"TAJ()","bf742d56":"canExecuteArbitraryCode()","bf748655":"isPaymentRegistered(bytes32)","bf748e47":"get_pre_kyc_iconiq_bonus_numerator(address)","bf7540d2":"getMoneyCount()","bf754558":"conversionsEnabled()","bf75553a":"sacarWEA()","bf75fdb5":"CreateShortAlias(bytes32)","bf77aa1f":"updateListing(uint256,bytes32,uint256)","bf77afdb":"TokensReserved(uint256)","bf7929a6":"refundeadline()","bf7abee6":"SetAuth(address)","bf7b69ee":"payDebt(address)","bf7ba12a":"LupeShares(address,address)","bf7c734e":"setMinSell(address,uint256)","bf7c775e":"RESERVED_RESERVE_UNLOCK_AT()","bf7e214f":"authority()","bf7e4026":"pizza_machine(uint256,uint256,uint256)","bf7e7f62":"MaxCouponsPaymentUSD()","bf7ea21c":"addWhitelistMember(address[],uint256[])","bf7f10fe":"isTransferShipment()","bf7f3cfe":"getVotesPerProposal()","bf7f8b89":"EthernetCash()","bf7ff81e":"bitwordsWithdrawlAddress()","bf815059":"updateUnidentifiedSaleLimit(uint256)","bf81765c":"adminAddressForComissions()","bf83735c":"changelp19(address)","bf843aed":"BuckyCoin()","bf8554ff":"fireOnOfferingChanged(uint256,bytes32,uint256[])","bf85cc27":"settleCfd(uint128)","bf85e628":"startVesting(uint256,uint256)","bf86d690":"isShutdown()","bf86e013":"createPromoBot(uint256,address)","bf872aee":"revokeConfirmation(uint256,bytes)","bf8783e0":"callAndGetReturn(address,bytes,uint256)","bf884cf5":"exitThisIcoForHalfOfTokenPrice()","bf8853c6":"getUserInterest(address)","bf8869b5":"GetBal()","bf88a6ff":"reward_contract()","bf88fc09":"revokeOwners(address)","bf892eaa":"removeTrustedContract(address)","bf89662d":"refundable()","bf8981c0":"left36(uint256)","bf8af541":"setLockRatio(uint256,uint256)","bf8b6466":"anOfferWeCantRefuse()","bf8b7ec2":"OpenGift()","bf8ba305":"getCodeStorage(uint256)","bf8bcee4":"setMaxLimit(uint256)","bf8bdac1":"setService(address)","bf8bf85e":"latestReleaseChecksum()","bf8c50ff":"scheduleTransaction()","bf8c6b63":"is_diagonal(int8)","bf8ce97f":"_take0xTrade(address,uint256,address[5][],uint256[6][],bytes)","bf8d5df8":"setTickerSymbol(string)","bf8dde4d":"calculatedReward()","bf8e0ea4":"logGive(address,string)","bf8eae55":"ChangeGasReuired(uint256)","bf8ecf9c":"authProposals()","bf8edd85":"setPriceInEth(uint256,uint256)","bf8f09cb":"cancelOrder(address,uint32)","bf8faa9c":"AMLToken(string,string,uint256,uint256,bool)","bf8fc670":"sendToAggregation(uint256)","bf9005ec":"Test6J()","bf907def":"buyGold(bytes32,string,string,string,string,string)","bf90c4e7":"PYRToEth()","bf913c5e":"getFamedStarByMass(uint256)","bf91cbb5":"mineIsBigger()","bf91ef18":"mergeBoostData(uint256)","bf9222d0":"DNT()","bf93a8be":"changeOwnership(address,address)","bf947852":"blockInvestor(address)","bf94de12":"createPoll(address,bytes32,uint256)","bf955038":"Judgement(uint256,uint256,uint256)","bf962302":"addIntTag(bytes32,int32)","bf96ae63":"signUp()","bf981995":"getCountryInfo(uint256)","bf983772":"BaseExchangeRateChanged(uint256)","bf98976e":"test_curatorDoesVeto()","bf989b6e":"setContracts(address,address,address,address)","bf98a50d":"GasReceipt(address)","bf99669d":"DevPromotionsMarketingSupply()","bf99cce1":"buyTokens(address,uint256,bytes32[])","bf9a5fde":"setConfiguration(uint256[],uint256[])","bf9a6958":"createVoterOnElection(uint256,address,address,string,string,string)","bf9ab00c":"getTeamPerfit(uint256)","bf9b8b38":"CrypviserToken(address)","bf9bbe71":"TRE()","bf9befb1":"totalStakes()","bf9c0d44":"RandomLedgerService()","bf9c3949":"createFaucet()","bf9c5001":"authors(address)","bf9d3d39":"setLineUpEnable(uint256)","bf9e6b0e":"TokenSwap(address,uint256)","bf9e7b75":"DeliveredBTC(address,uint256)","bf9f01f8":"buyMasterNodes(uint256,uint256)","bf9fc4e2":"balanceOfRobots(address)","bfa0b133":"salt()","bfa0fc93":"getVoteResult(uint256)","bfa190f3":"mTransfer(address,address,uint256)","bfa1bd62":"stakeAirdropWhileLocked(address,address,uint256,bytes)","bfa3c1e6":"MySale(uint256,uint256,uint256,uint256,uint256,uint256,address,bytes32,address,uint256)","bfa51df9":"isAirdropped(address)","bfa535c7":"apply(string,uint256)","bfa54b3f":"BLB()","bfa5f1f7":"getLandmark(uint256)","bfa814b5":"func()","bfa87e80":"tellPreviousContract(address)","bfa8ad36":"createProof(bytes32,bytes32)","bfaa1763":"FATA()","bfaad84b":"getLastStarOfAssetId(uint32)","bfab3db9":"withdrawContractBalance()","bfab41c9":"getTargetBlock()","bfab4f8b":"isMonsterAuction()","bfabd754":"increaseFrozen(address,uint256)","bfabe6c4":"ShakaliosToken()","bfac0046":"getPlayerWallet(uint256)","bfad16f4":"new_offer(uint256,uint256)","bfae2f0e":"addrAdmin()","bfae8867":"getLockTimestamp(string)","bfaec04e":"publish(string,bytes32)","bfafa8e6":"auditText(uint8,string)","bfafb91c":"changeMaxCoefPlayerForEmission(uint256)","bfafe92f":"_buyCallToOpen(uint256,uint256,uint256,uint256,address)","bfb01f72":"buyWithCustomerId(string)","bfb04c60":"proposeAcceptanceAsMember(uint256)","bfb05e0b":"declineFightApproval(uint256)","bfb0d82e":"__callback(bytes32,address[])","bfb1fcf5":"dmlwallet()","bfb2fad7":"totalDepositTokenAll()","bfb42682":"addPresaleOrder(address,uint256)","bfb460e9":"receiverSetAmountRequired(uint256)","bfb47e72":"CryptoSurprise()","bfb4d66f":"SudjuKoin()","bfb4ebcf":"Foo()","bfb51ac9":"startGame(uint256,bytes32)","bfb65777":"allContacts(address)","bfb68141":"disableTokensTransfer()","bfb77030":"BRM()","bfb7896d":"OQToken()","bfb790b4":"weeklyRate(uint256)","bfb7c227":"Developeo(uint256,string,string,address,address,address,address,address,bool)","bfb7d9f6":"stringandbytes()","bfb80547":"unfreezeAddress(address)","bfb8a319":"withdrawal(bytes32,address)","bfb8c63e":"confirmDeal(bytes16)","bfb909ce":"applyFeeToAddress(address,address)","bfb9f088":"addInvestorList(address[])","bfba1e8d":"gamePlayed()","bfba5dd6":"equal(address,address,string)","bfba9029":"hashBetMax()","bfbaa54d":"MithrilMace()","bfbad8b9":"preSaleEtherRaised()","bfbb6a23":"winEth(address,uint256)","bfbbd489":"setMonsterAuctionAddress(address)","bfbbfb1d":"getWinNumberBySlot(uint256,uint256)","bfbc37f7":"KOSHER()","bfbc793c":"computeNameFuzzyHash(string)","bfbc944c":"oldTokenReward()","bfbccfae":"currentCoinsCreated18Decimals()","bfbcf293":"setChampEC(address,address)","bfbd5074":"getVillain(uint256)","bfbf95cf":"participateICO(address,uint256)","bfbfa8e4":"kBalance()","bfc0a342":"owner_loadFunds()","bfc0cc5c":"sendEcosysSupplyToken(address,uint256)","bfc0e849":"startNextEra(bytes32,uint256,int256)","bfc1f48c":"isCapFree(address)","bfc2a675":"CreateCredo(address,uint256)","bfc2aa2a":"claimedSupply()","bfc303fa":"updatePublicData(uint256,string)","bfc38592":"cancelItemSale(uint256)","bfc3aef0":"setActiveStar(uint256)","bfc3cd2f":"testFailChargeMoreThanApproved()","bfc3d84b":"CT()","bfc47aa0":"tokensCrowdsale()","bfc4d11c":"subJobSponsorshipsBalance(address,uint256,uint256)","bfc54822":"bet(uint256,uint256,uint256)","bfc5624a":"newBadAPM(bytes32,bytes32,address,bool)","bfc6cdd1":"DukevsKansas()","bfc708a0":"reportMalicious(address)","bfc7952f":"outstandingPayouts()","bfc83af4":"setBountyTokenWallet(address)","bfc84528":"juicyBonus()","bfc8bfce":"executeTransaction(uint256,address,bytes,bytes)","bfc99f5b":"unsafeWriteAddress(uint256,address)","bfca33f7":"Court(address[],uint256[])","bfcabcbf":"changeFeeAmountThreshold(uint256)","bfcae563":"dateSaleEnded()","bfcc4ab2":"change_time_stamp(uint256,uint256)","bfcc8b6d":"ownerOfPlayer(uint256)","bfcdbae9":"preICOStartTime()","bfcdca48":"CastVote(bool)","bfce0b7f":"mainSaleEtherCap()","bfce477f":"forwardTransaction(uint256,bytes)","bfce8cbf":"redeemAdoptedAxies(address,uint256,uint256,uint256)","bfcf04cf":"updateId()","bfcf0baf":"testSliceToString()","bfcf63b0":"claimEther(address,uint256)","bfcf73e7":"blocksToLive()","bfd07c38":"LowJackpotHolder()","bfd0a553":"specWallet()","bfd1084f":"BitNauticWhitelist(uint256)","bfd13217":"ethReceivedPresaleOne()","bfd17831":"RECEIVER_ADDRESS()","bfd201f5":"setTransferFees(uint256,uint256,uint256)","bfd2385e":"allowanceOf(address)","bfd24821":"BonusCrowdsale(uint256,uint256)","bfd2ed01":"bountyPercent()","bfd3c5fa":"refundTransactionAfterExpiry(uint256)","bfd3fa6a":"becomeFairymaster()","bfd431d1":"RefundToBuyers()","bfd45540":"BlocHipo()","bfd4d720":"investors_number(uint256)","bfd4dce9":"WhatIsTheBestFoodInTheWorld()","bfd525b3":"stopTimeLength()","bfd6ef3e":"explore(uint256,uint256,uint256)","bfd74534":"getRequest(address,address)","bfd7534f":"developer_address_for_D(address)","bfd75da4":"TrueUSD()","bfd812ec":"suspend(bool)","bfd8222a":"checkReward(uint256,uint256)","bfd8300d":"setBonusInterval(uint256)","bfd85808":"frozenTokens(address)","bfd8a06e":"getFinalWinningReportingToken()","bfd8fc93":"getOwnersLength(bytes32)","bfd90435":"addDataset(address,address)","bfd94c8c":"transferIsAllowed(address)","bfd9726d":"getMntTokenBalance(address)","bfda3b1a":"setSharedStorage(address)","bfdad9a4":"SignedContractVault(string)","bfdadc19":"change_price(uint256)","bfdb8796":"getPoolNameByID(uint256)","bfdc35f2":"onBalance()","bfdcc9a2":"numBuckets()","bfdcd480":"test_invalidProposalDuration()","bfdcdbf5":"subkey(address,uint256)","bfdd1a20":"getPOOL_edit_17()","bfde4f62":"withdrawAllEthToOwner()","bfdecf8c":"purchaseTokenInPresale()","bfdeddaa":"AllowedContributionCheck(uint256,uint8)","bfdf5e80":"communityPot_()","bfe0c27e":"getCurrencyAddress()","bfe10928":"distributor()","bfe1292a":"distributeLenderBot(address[],uint256,uint256)","bfe36f58":"HashCoinToken()","bfe370d9":"bytesToBytes32(bytes)","bfe38df5":"getTotalBet()","bfe3a664":"createCrowdsale(address,uint256[8])","bfe3c39d":"JYKToken()","bfe3e03a":"midGradeHold()","bfe44c4b":"getUserValue(bytes20,uint256)","bfe484de":"judge(uint256,bool,bytes32)","bfe4ed8e":"Razoom(address)","bfe53e5c":"holdersWithdrowsOf(address)","bfe597fe":"genesisBlockCount()","bfe689cf":"lockedValuesAndTime(address,uint256,uint256,uint256)","bfe6b1ac":"acceptOffer(uint16,uint256)","bfe6c0c7":"viewa1(address)","bfe70251":"_checkCertificate(bytes,uint256,bytes4)","bfe713e3":"truecoin()","bfe7e2eb":"BCBCYCoin()","bfe86bbe":"publicGetElement(uint256,uint256,uint256)","bfe8936c":"getAssetDetailsURI(uint256)","bfe8c107":"betOnDozen(bool,bool,bool)","bfe9b7df":"pubkeys1()","bfe9e7f4":"pack(address,bytes)","bfe9f204":"dividendCycleTime()","bfea267a":"getBalanceToMint(address)","bfea8790":"enableScheduler()","bfead4b9":"maxWithoutWhitelistPerUser()","bfeb049c":"IndexOfCurrentDraw()","bfebb947":"unblacklist(bytes32)","bfec83d6":"RoleAdded(address,string)","bfec8b01":"insertSection(bytes32)","bfee3569":"setTokenControlInfo(address,uint256,uint256,uint256)","bfef9627":"set(bytes4,uint8,uint8)","bff04d6f":"testPostpone()","bff05aef":"adminRefundTokens(address,uint256,uint256)","bff0fbb8":"calculateMeat(uint256)","bff10815":"deleteOffer(uint16)","bff179c4":"setJadeCoinZero(address)","bff18c78":"deployFactory()","bff1f9e1":"totalUsers()","bff2c413":"ChangeFoundersWalletAddress(uint256,address)","bff35618":"setTransferLock(bool)","bff41e36":"WEI_RAISED_CAP()","bff44f0d":"confirmAddressChange(address,address)","bff49180":"updateVendorValid(uint256,bool)","bff5e021":"PumpToken()","bff5fb64":"appNickname()","bff5fccd":"myWishes()","bff65668":"isPresaleHolder(address)","bff7df7c":"refundDeadLine()","bff7e179":"multiPurchase(uint32[],uint8[],uint8[],uint8[],string)","bff8314f":"SetMaxPosXblock(uint256)","bff8a36d":"decreaseReserve(uint256)","bff974e8":"getContentReplies(uint256)","bff99c6c":"tokenWallet()","bff9e842":"getSamplesForOwner(address)","bffa02d5":"sendP3D(address,uint256)","bffa4e41":"getMintAmountApproval(address,address)","bffa55d5":"claimRefund(address)","bffa9258":"assetCount(address)","bffb10de":"add_creature(address,string)","bffbe61c":"node(address)","bffc235a":"mintedList(uint256)","bffcd758":"nasdaqo(uint256,string,string)","bffd952a":"transferMaintainer(address)","bffdf3f1":"Test4()","bffeadd6":"move(uint8,uint256,bytes,uint8,bytes32,bytes32)","bffee609":"setSkills(address,uint256,uint256,uint256)","bfff23f2":"CaptainKitty()","bfff374d":"DepositReturned(uint256,address)","bfffe670":"window1StartTime()","c00007b0":"getReward(address)","c0001786":"ownerBurn(address,uint256)","c0012077":"TeamContract()","c002c4d6":"getTicket()","c003598a":"XEN()","c0036137":"ownerProfitPercent()","c003b082":"getMyPlayerID()","c003f540":"sco(uint256,address,uint256)","c00465ab":"CrowdsaleToken(uint256,uint8,address,bool,address)","c004a877":"shiftSalePurchase()","c0056b7b":"updateAccount(uint8,bytes32,bool,bytes32)","c005c686":"validateCompoundContract(uint256)","c005dc7b":"hon2backup()","c00710fa":"userContractsPred(address,uint256[],uint256[],uint256)","c0075772":"setPromoTokenController(address)","c0086b19":"BCP(uint256,string,uint8,string)","c00941d9":"Dominator()","c009b451":"setEventActive(bool,string)","c00ade41":"receiveTransferOwnership()","c00b060c":"getArrBoolField3()","c00c176c":"GoGO()","c00c2ceb":"isRedeemAllowed()","c00c4e9e":"batch(address[],uint256[])","c00ca383":"getByOwner(address,uint256)","c00d5305":"oraclize_setNetwork()","c00d8f3d":"processLotteryReward()","c00daefe":"etherFund(bytes32,string)","c00e4306":"getCurrentTokenAmountForOneEth()","c00ea6ef":"Polaris()","c0112678":"arcToken()","c0116c3c":"doAirdrop(address[],uint256[])","c011cd1c":"getClixToken()","c012e179":"mintDepositAccount()","c0130adb":"addadjacencies(uint16[],uint16[],uint16[])","c0140fd1":"bid(bytes32,address,uint256)","c014464e":"checkFeePeriodRollover()","c014875f":"mint(bytes32,address,uint256,bytes)","c01569f9":"buyPiece()","c01685d4":"FTKTToken()","c01706dd":"getContentByRank(address,uint256,uint256)","c0171112":"timestamp(uint64)","c018d0e6":"getFeeAmount(int256,int256)","c018fe0d":"sub_sessione(string,uint256)","c01a1c5f":"totalSellPrice(uint256,uint256)","c01a8c84":"confirmTransaction(uint256)","c01ae5d3":"drop(address[],uint256[])","c01b3aa4":"STARTING_SNAKE()","c01bc982":"isRestricted(address)","c01c1ca3":"claimRemaining()","c01ca43f":"getPlayerState(address)","c01d1c60":"getTokenExchangeRate()","c01d8280":"get_balance(address,string)","c01de45c":"storeBet(uint256,uint256,uint256)","c01e38e6":"addPlayer(address,uint256,uint256)","c01e3985":"StupidityToken()","c01e8b6a":"Zigit()","c01f475f":"_setClearingPrice(bytes32,uint256)","c01f56d0":"OfferToDisciple(uint256,uint256)","c01f9e37":"proposalDeadline(uint256)","c0204bab":"EasyOsmiumCrowdsale()","c020df48":"updateGas(uint256)","c022215c":"getTotalDeposit()","c0227bd3":"_toTaxes(uint256)","c022abbe":"GetAuction(uint32)","c022ef43":"getTimeLeftToNextLocalBountyCollect(uint16)","c023a231":"BitSTDView(address)","c02515a9":"maxTokenForHold()","c0263163":"ATT(address)","c026327a":"removeBankToken(uint256)","c02738da":"generateTargetTokens(address,uint256,uint256)","c02898a0":"potatoOwner()","c028c674":"right82(uint256)","c028df06":"offer()","c028e3c9":"cordX(uint256)","c0297bc8":"DreamX()","c02aaea1":"totalTokensForSaleDuringPreICO()","c02b04d8":"rescueLostProperty(uint256,address)","c02b5395":"NAMO()","c02bf40c":"FundsDeposited(address,uint256,uint256,uint256,uint256)","c02c89fe":"PreicoClose()","c02cc957":"firstDigit(string)","c02d0140":"buyCard(uint8,string,string,string)","c02d1e02":"a_document(uint256)","c02e580e":"roundEnd()","c02f081a":"shiftBits(bytes,int256)","c02fd500":"E4Lava()","c0309697":"challengeContract(address)","c030d8b8":"setCardContract(address)","c030f3e2":"increaseSaleLimit(uint256)","c031a180":"getBytes(bytes32)","c031a78b":"maxMedalsBurned()","c0324c77":"setParams(uint256,uint256)","c032846b":"getContractStatus()","c0329a3e":"startAirdropFrom(address,address[],uint256)","c032dc30":"execute(uint256,address)","c0338a0c":"transferTileFromOwner(uint16[],address)","c0343b09":"setDisputeInterface(address)","c035340c":"withdraw_1()","c035e492":"onholdBalances(address)","c0362523":"setUpgradedOwner(address,address,address)","c036c100":"NextGenHype()","c03785c3":"MyRefundVault(address)","c03795ba":"departmentrequest(address,string,bool)","c037ae58":"VESTED_AMOUNT_TOTAL()","c037d9ce":"getElementsFromIndex(uint32,uint32)","c038a38e":"totals()","c038f541":"setProperty(string,string,uint256,int256,string)","c03951f7":"FaceWalletToken()","c0395bb5":"isCurrentOrPastAdmin(address)","c039b88c":"_makeSpecialId(address,address,bytes32)","c039bd87":"withdrawTokenFromPkt(address,uint256)","c039d6db":"PutEther()","c039daf6":"tokenCreationMin()","c03a4018":"getGuessInfo(string)","c03aac7a":"setSellDividendPercentageFee(uint8)","c03b70d5":"getTurnover(address)","c03ba041":"BNC(address)","c03bdbae":"setRdFee(uint256,uint256)","c03c3003":"increment(int256)","c03c72aa":"isBattleDecider()","c03ce1d8":"BondingManager(address)","c03ce796":"crowdSaleStage()","c03cf137":"getMyLocker()","c03d00f3":"a_viewCoinSupplyAndFunding(bool)","c03d1b1d":"verifyCertWithID(bytes32,bytes32,bytes32,address)","c03d848c":"convertEthToCents(uint256)","c03e2cbf":"Whitelisted(address,bool,uint256,uint256)","c03e382f":"calculateShare()","c040188f":"preSaleLockEndTime()","c0406226":"run()","c040e6b8":"stage()","c040ebec":"getUserSize()","c04123fb":"checkProposalCode(uint256,address,uint256,uint256,bytes)","c041652d":"getVendorApplicationStatusTrackCount(string)","c04198f3":"getEndDate(string)","c042575f":"ETHmultiplier()","c0435e29":"setDefaultFriendsFingersRate(uint256)","c043c0d9":"changeMaximumPlayers(uint32)","c043df8c":"verifyWithdrawSignature(address,bytes)","c04484fd":"resetInternal(uint256)","c045732c":"addPreIcoMembers(address[])","c0459899":"approvePreSigned(address,uint256,uint256,uint256,uint8,bytes)","c04605b8":"softEndDate()","c0462ec3":"withdrawAllTokensToExchange(address,address,uint256)","c0463711":"lastUpdate()","c0463810":"PalmToken()","c0465f3a":"dateSisterWins()","c046c691":"setMoveProductToWhom(address,uint256,address)","c046d9b5":"borrow(address,uint256,address,bytes)","c0472889":"currentIDnumber()","c047c1d8":"transactionsStatusUpdate(bool)","c0489af5":"foundersTimelock1()","c048dfb8":"postpone(uint256)","c0496e57":"setNotarisationFee(uint256)","c049813a":"preIcoStagePeriod(uint256)","c04a5414":"developmentWallet()","c04aa9b8":"rpow(uint128,uint64)","c04bb954":"rejectionRatio()","c04c5947":"getGames()","c04c68eb":"changeAllowTransferState()","c04c8e43":"SNSCOIN()","c04ca3f5":"_removeAgent(address)","c04cc86b":"collecttaxes(uint256)","c04d90d0":"ownerByIndex(uint256)","c04de318":"slashAddressLikeUsername(string)","c04ecdb8":"promoTokenController()","c04f01fc":"power(uint256,uint256)","c04fcad8":"INITIAL_TOTAL_SUPPLY()","c0506782":"_createArtwork(string,string,uint32,address)","c050f6dc":"admitUser(address)","c0517c5a":"XferMoneyMarketing()","c051f75f":"setSchemaRegistry(address)","c05283ff":"logQuery(bytes32,address)","c0533b5d":"appVersionList(bytes32,address)","c05374f7":"AirChn()","c05390f6":"PRIZE()","c053dc6b":"EtherBags()","c053ebf5":"setProviderClosed(uint256,uint256)","c0567656":"subtractFee(uint256)","c0576b73":"monsters(uint256)","c057b40d":"SpainvsRussia()","c0584e68":"ContributorsSupply()","c0597a55":"freedWosPoolForThirdStage()","c05a30b9":"_processFunds(uint256,uint256)","c05a8e81":"getPosition(uint8[176],uint256)","c05b7cf6":"setCreationProfit(uint256)","c05b8066":"setCompte_18(string)","c05ce08f":"calculatePoints(uint256,uint256)","c05d1f0e":"PRESALE_JOINTTOKENS()","c05dd5d2":"MatchAborted(uint256)","c05e5776":"giveRightToVote(address,address)","c05f486e":"DEV_SUPPLY()","c060ac53":"bytes20ToString(bytes20)","c0615f09":"CPGPEREGRINE_EXTRACTION_BASE()","c0619c70":"setPrimaryManager(address)","c06265d3":"createContractState(string)","c062dc5f":"releaseAmount()","c062ef86":"_random_empty_location()","c062f578":"updateStage()","c0631b12":"moneyWallet()","c0645011":"getPastRound(uint256)","c06474e0":"removeShare(address,uint256)","c06508dc":"QBTCoin(address)","c0652cf9":"EdelRostenCoin()","c0659108":"beneficiariesLength()","c065ecc2":"queryChildLength()","c065fcf1":"RESERVED_PARTNERS_SIDE()","c066bd1a":"addItem(uint256,uint256,address)","c06702dd":"changeStage()","c0670d2c":"calculateDistributionPeriods()","c0675b78":"addBuyTokensRequest(string,uint256)","c0677fb6":"SetIdentifiedContract(address,address)","c0689e2d":"newCrowdFundingCampaign(address,uint256)","c068eae0":"player_collect_winnings(uint256)","c06a22f4":"dollarsForEther()","c06b0d21":"BondToken(address,address,address)","c06b5281":"buyXnameQR(address,bytes32,uint256)","c06c4474":"get_burned(bytes32)","c06c66ca":"bountyFund()","c06d1272":"startPreIco()","c06d1490":"oppositeAnnouncement(uint256)","c06d7744":"getAllSignersCount()","c06dabf8":"_escrowHostPaymentEarning(address,bytes32,uint256,uint256,address,bool,uint256)","c06f146b":"setNumInvalidMarkets(uint256)","c06f1bc4":"updateVoterTimes(address,uint256)","c06f4c1d":"newCampaign(bytes32,bytes32,bytes32,address,uint256,uint256,uint256,address)","c06f8340":"cancelAuctionByAdmin(uint256)","c06fad06":"items()","c06fff76":"proposePauseChange(bool)","c0702d9c":"_mint()","c07097a6":"coindropsLockEndingAt()","c0715d1d":"assertSafe(bool)","c071f3bf":"deliverPurchasedTokens()","c072422d":"buyTokens(bytes32,uint256,uint8,bytes32,bytes32)","c072497a":"claimPlotMultipleWithData(uint256[],uint256,string,string,string,string)","c072dcf3":"ExampleContract()","c073af55":"GetJackpotMin()","c07401f0":"addToPool()","c0740c16":"numElementsOdd()","c0741c53":"test_assetRegistration()","c0743044":"partAllocations(uint256)","c074313f":"pricePerStake()","c074a27e":"proposeTransaction(address,uint256,bytes,string)","c07653af":"Gavinhereum(uint256,string,string)","c076c847":"NorthPoleAF()","c0774df3":"canForward(address,bytes)","c0777545":"balanceAD()","c077b0f9":"getARSchedule()","c079418b":"setTranchWei(uint256[])","c0797ae1":"stakerIncomeShare(bytes32)","c079c318":"adjustFee(uint256)","c07a1f0c":"changeHouseFeeAddress(address)","c07a32c4":"dateIsLegal(uint256)","c07a5537":"MintableTokenWithMinters()","c07b18ca":"PullPaymentMock()","c07b2586":"SAFCOIN(uint256,string,uint8,string)","c07bcfdc":"updateLimitPerDay(bytes32,uint256)","c07dc59c":"withdrawPot(string)","c07dc890":"selfRegisterDINs(uint256)","c07dd842":"buyFactor()","c07e3391":"setMonethaAddress(address,bool)","c07f47d4":"latestVersion()","c07f773a":"totalTokensAllocated()","c080f08f":"complexReturnType(int256,string,bool,string)","c0819961":"Invest()","c081efc1":"hasSellerBeenAccepted(address)","c083455f":"ownerPutInterest(uint256)","c0835106":"isVotable(bytes32)","c08415b1":"ORDER_PLACE(address,address,bool,uint256,uint256,uint256)","c0845e8a":"catchMonster(address,uint32,string)","c0846957":"EtherDeltaTokenBalance(address)","c0851e09":"getEarlyPurchase(uint256)","c0864877":"tokensForOwner()","c088003d":"getMinThresholdOfVoters(uint256)","c0887991":"getOperation(address)","c088df47":"SECRET_BONUS_FACTOR()","c08a86b1":"endGame(bool,uint256)","c08cc02d":"getProposalCount()","c08d1fe5":"timeLimit()","c08dd1dc":"IOU(string,string,uint8)","c08e05aa":"icoRuleCancel(uint256)","c08eea14":"cloneAccount(uint256)","c0905fef":"getStackholders()","c090b4df":"createRecord(string,string)","c090b86d":"createKingdom(string,address,address,address,uint256,uint256,uint256,uint256,uint256)","c090da1e":"Zhennong(address)","c0910475":"PaymentStatusTimeStamp(address,address)","c0916437":"modifyChoice(uint256)","c091c435":"refund(address[],uint256[])","c091e45a":"redenominate()","c0926d40":"HBOToken()","c0929385":"confirmInit(address,address,string,bytes32,uint256)","c092ecf4":"blocksToVest()","c0934c45":"getNextRules()","c0938c1a":"setMintAgent(int256,address,bool)","c0942dfd":"registerNameXIDFromDapp(address,bytes32,uint256,bool)","c0946d54":"AtomCoin()","c094c73e":"VeritaseumToken()","c094df20":"shift(address,uint256)","c0956fd9":"getRealTokenAmount(uint256)","c0963d97":"getTokensAmount(uint256,address)","c0966693":"RoomNonceAdd(uint8)","c096aa81":"fuint8(uint8)","c097d629":"setPI_edit_30(string)","c0981285":"buyComissionUnits()","c098201f":"updateEtherAndtokenAmount(uint256,uint256)","c0997654":"destIndex(address)","c09a4ef4":"latestEthTxRequest()","c09a898d":"SPTS()","c09b2a2c":"weiMinSale(uint256)","c09bdd06":"_escrow(address,address,uint256)","c09d81be":"calculatePoundsTimesEther(uint256)","c09f32e8":"closeQuestion(uint256)","c09fed25":"transferFromBalance(uint256,address)","c0a06ecb":"infoWithdraw4()","c0a0b5fa":"getKilledArray(uint256)","c0a14da4":"isTeamLockInPeriodOverIfTeamAddress(address,address)","c0a150b3":"RovaZoneBToken()","c0a1a949":"x15()","c0a1b72a":"totalSupplyWithOutBonus()","c0a1e525":"createDaoPOLSKAtokens(address)","c0a2203e":"insert(address,address)","c0a239e3":"valuePerShare()","c0a28014":"setTreeStructure(address,address)","c0a2d9b3":"EssentiaToken()","c0a35d62":"burnReturn(address,uint256)","c0a35e8b":"getTokensMintedAt(uint256)","c0a36345":"getTokenOwnerRewardPercent()","c0a39fb0":"blockTransfer(uint256)","c0a41466":"etherSender(address,uint256)","c0a42d91":"SignatureInvalidity()","c0a5bcbd":"DefaultCents()","c0a7639e":"checkIfAddressIsWhiteListed(address)","c0a7f894":"MAVCash(uint256,string,uint8,string)","c0a843a1":"getCurrentUserRefBonus()","c0a8694d":"NamableAddressList(string,bool)","c0a899f2":"transferAsChild(address,uint256,address,uint256,uint256,bytes)","c0a8fb73":"FlightDelayController()","c0a9066b":"LogValentineRequestCreated(string,string,string,address,address)","c0a9581d":"sendFee(uint256)","c0a963c9":"notifyWinner(address,uint256)","c0a99a83":"oneTokenInUsdWei()","c0aa18e7":"History()","c0aa3b21":"ownerTokens()","c0aa7e2e":"cancelInvoice(bytes32)","c0aace0b":"totalKitties()","c0ab5704":"setVesting(address,uint256,uint256,uint256)","c0ab86bd":"SBSolutions()","c0abf829":"tokenCreationMinMile2()","c0ac3d1c":"PRE_ICO_BONUS_RATE()","c0ac9983":"tokenURIPrefix()","c0ad7427":"saleTokenSupply()","c0adb725":"AuthCancel(address,address)","c0adc465":"getCurrentBonusRate()","c0ae6a3a":"ultimateOutcomes(bytes)","c0aee5ba":"THAW_CYCLE_USER()","c0b14de7":"setLandLimit()","c0b204a6":"TeamWalletAmount()","c0b241d7":"icoRate()","c0b332c1":"moveCharge()","c0b3569d":"setAssetProxy(address)","c0b3870a":"withdrawJackpot()","c0b39e68":"unfinalize()","c0b3aff3":"INCREASE_RATE()","c0b3dab3":"Devilsbest()","c0b4d404":"setGrowingControlStartAt(uint256)","c0b4e657":"HongkongerCoin()","c0b4fa6d":"_reward(address[])","c0b6762c":"SILVER_AMOUNT_XPER()","c0b6f0c2":"NextRoundAndEvents()","c0b6f561":"initiateOwnershipTransfer(address)","c0b75b7d":"setMinContributionAmount(uint256)","c0b7eba4":"game_allocation()","c0b82515":"gzeUsd()","c0b84bfe":"setFee(uint256,uint8)","c0b8a80d":"CVAlejandro()","c0b92612":"changePig(address)","c0b9b36a":"bountyTokensBatch(address[],uint256[],string)","c0b9b8ce":"releaseToAdvisor(address,uint256)","c0b9ecc8":"getNames(address,uint256,uint256)","c0ba6adf":"gemDefenseConversion()","c0bac1a8":"isMigrated(string,string)","c0bb20a6":"setBonusSale(uint256,uint256,uint256)","c0bb6c27":"setTotalPersistLimit(uint256)","c0bb8466":"WithdrawFees()","c0bd3f40":"dumpData(uint256,uint256)","c0bd8351":"getGameId()","c0be3e9a":"removeOffChainAddresses(address[])","c0be4b51":"genWeeklySecondPrizeKey(uint8[4])","c0be7ad3":"freezeAccountDirect(address,bool)","c0c116d5":"getStringValue(uint256)","c0c133a8":"DATE_ICO_END()","c0c19d29":"mock_length()","c0c1b107":"changeOraclizeGasPrice(uint256)","c0c1b18e":"getDepositSize(address)","c0c1cf55":"executeAction(uint256)","c0c1eebc":"addToken(address,bytes32)","c0c2c087":"getOrdersInfo()","c0c3da9c":"totalSupplyLocked1Y()","c0c4440a":"totalAmountOfCrowdsalePurchases()","c0c47e12":"getDeal(bytes16)","c0c4d8a8":"Fundraiser(address,address,uint256,uint256,address,uint256,bytes32,uint256,uint256,uint256,uint256,uint256)","c0c53b8b":"initialize(address,address,address)","c0c602d9":"tokenAssigned()","c0c620d2":"DroneToken(uint256,string,string)","c0c6a430":"BadTronToken(address,address)","c0c6a68a":"setMockedBlockNumber(uint256)","c0c76940":"StopperCoin()","c0c77236":"resetHolder(bool)","c0c77b71":"changeRegistrationStatusForGoldWhiteList(address,bool)","c0c81969":"tokenSupplies(uint256)","c0c83c0d":"getDebtById(uint256)","c0c8821a":"icoRuleUpdate(uint256,uint256,uint256,uint256,uint256)","c0c8b567":"registerCertificateHash(address,bytes32)","c0c8ccb3":"PreHELIX()","c0c91e6d":"getMinPriceSale()","c0c95917":"BrinkzSupply()","c0c98d6f":"setProof(uint256,bytes32)","c0cab256":"ZZWHToken()","c0cad302":"setNetworkName(string)","c0cc365d":"setExpirationTime(uint256)","c0cc6eb1":"rejectPayment(bytes8)","c0ccc863":"NacContract(uint256,uint256,uint256,address,uint256,uint256)","c0cd1ec1":"recordLog(uint256,address,uint256,uint256,uint8,uint8)","c0cd2e32":"chargeWeeklyRate(bytes32,address)","c0cd54c6":"GetGameType(address)","c0cf067b":"deathData_v7()","c0cf22e9":"setSendGiftPrice(uint256)","c0cfa7e5":"startDispute(uint256)","c0d061f4":"execute(address,uint256,bytes32)","c0d0aa69":"daoMultisig()","c0d129d4":"BallotPreferential()","c0d13a6d":"MIN_BUY_ETHER()","c0d26946":"randomNumber(address,uint256)","c0d2834b":"DataSource()","c0d3f378":"specialManagerListMap(uint256)","c0d470a6":"setCCH_edit_23(string)","c0d4fa0c":"emitFeePeriodDurationUpdated(uint256)","c0d6568d":"FEATURE_TRANSFERS()","c0d6ce63":"punksRemainingToAssign()","c0d75442":"TOKEN_SALE()","c0d84ce5":"TransferFrom(address,address,uint256)","c0d8b0b8":"setPetAuras(uint64,uint8,uint8,uint8)","c0d910cd":"getTankOwner(uint256)","c0d9f997":"transperrun()","c0dab516":"adminPercent()","c0db4dd7":"TRANSACTION_MIN_IN_ETH()","c0db8dd8":"allowToLock(address,address)","c0dcf63a":"isLastRaceFinsihed()","c0de3d71":"TransactionCancelledICAP(bytes32,uint256,string,address)","c0df77d0":"getRefName(uint256)","c0e06ca3":"whitelistAddressPresale(address,uint256)","c0e093f1":"AirdropMultiple(address[],uint256)","c0e17c61":"TenStepTestCoin()","c0e18579":"ONETIMESOLD(uint256)","c0e19314":"divideFractional(uint256,uint256,uint256)","c0e1e272":"buyToken(uint32,uint32,uint32,address)","c0e22f31":"frozenStatusOf(address)","c0e31001":"avatar(address,uint256,bytes)","c0e3153c":"balanceSub(address,address,uint256)","c0e317fb":"addToBalance()","c0e33275":"perTokenAmountMax()","c0e37b15":"transferData(address,uint256,bytes)","c0e59e4d":"lastRateUpdateTimeForCurrency(bytes4)","c0e5fbb6":"unlockBalanceOf(address)","c0e71f54":"toKeyValue(string,string)","c0e738ef":"summAdvisors()","c0e789cc":"friendsFingersWallet()","c0e793c2":"transferOwnership(string,address)","c0e79a11":"setAllowed(address)","c0e8ad51":"LydianCoin()","c0e9118e":"killAllXAITActivity()","c0e91320":"finishPVEBatch(uint256[])","c0e91569":"GRCToken()","c0ea09d7":"rest()","c0ea537b":"amountOfTokensPoolD()","c0ea6ff5":"test3_search()","c0eaded2":"makeDeal(uint256,uint256,uint256,uint256,uint256,string,address,string,address,uint256,uint256)","c0eb2325":"scheduleTransaction(address,bytes,uint256)","c0ebc67a":"SimpleStateChannel()","c0ebdba1":"InvestedOtherCrypto(address,uint256,uint256)","c0ec55a5":"buyPokemon(address,uint256)","c0ed969a":"updateBackend(address)","c0edec55":"CroatiavsDenmark()","c0ee0b8a":"tokenFallback(address,uint256,bytes)","c0ee57a5":"giveReserveTo(address,uint256)","c0ee6db8":"_lockToken(address,uint256)","c0efa161":"getDeveloperReservedBalanceLimit()","c0f0c21c":"updateMaxTokenLimit(uint256)","c0f0e925":"getPercent3(address)","c0f11a1b":"addressArrayContains(address[],address)","c0f16fab":"checkAllowedContribution(address,address,uint256,uint8)","c0f17d13":"ChessCash()","c0f3622c":"updateRates(uint256,uint256,uint256)","c0f3ab76":"B2BCoinContract()","c0f40163":"issueFTT(address,uint256)","c0f496ac":"ecosystemAllocation()","c0f4bfa4":"nbSellers()","c0f4d29b":"setLocation(uint256,uint256)","c0f4f41e":"changeRefresherFee(uint256)","c0f57529":"eth_seed_amount()","c0f5a9cb":"deleteThing(bytes32[])","c0f5b5f7":"setSecondRoundPricing(uint256)","c0f5dc97":"totalSupplyUnlocked()","c0f64f43":"attachAsset(uint256)","c0f65734":"SignedDigitalAsset(string)","c0f68859":"getMinimumGracePeriod()","c0f6a3f9":"reserveVaultAddr()","c0f6c0da":"getTokensFromEth(uint256)","c0f6c7b8":"getIdArray(address,uint256,string,string)","c0f70d5a":"IOUSupply()","c0f7c498":"create_planet()","c0f8275e":"detailsOf(uint256)","c0f8940c":"decode()","c0f8de32":"shouldThrowOnAttemptToTransferToNullAddress()","c0f96105":"Enabled()","c0fd43b4":"lastNonce(address)","c0fdba2d":"YCBIToken()","c0fe6c92":"isClientAddedBefore(address,address)","c0feb62d":"fundRaisedDuringPublicSale()","c0feee42":"Error(bytes32)","c0ff3ebc":"ILFManager()","c1009f1b":"testInitialLedgerBalance()","c1013658":"createAsset(uint256,bytes32,uint256)","c1021099":"DBDVToken()","c1039215":"PresaleExtended(uint256)","c10435cc":"lastEruptionTimestamp()","c1061561":"shut_down()","c1072279":"unicornBreeding()","c1075329":"withdrawFunds(address,uint256)","c10796df":"_performTransferToICAPWithReference(bytes32,uint256,string,address)","c107aa6f":"addAssociatedAddress(address,address,address,uint8,bytes32,bytes32,uint256)","c107b9b8":"CTCB()","c107e109":"addFactory(string,address)","c1082c00":"YBananaCoin()","c108adab":"setChangeFee(uint256)","c108d542":"distributionFinished()","c1098e2e":"preSaleFirstCap()","c109e024":"blockdif()","c10a0840":"CryptoChallenge()","c10b30c0":"unlockPurchasedTokensClaim()","c10b9358":"saleEnd()","c10be521":"gapFactor()","c10bef22":"ConditionsAdded(address,uint256)","c10c0bd3":"logMatchdayResults(int16,string)","c10c3463":"addProduct(string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","c10c3546":"setEscrow(address)","c10ce2b0":"calculateDiffPercent(uint256,uint256)","c10d0f11":"didChangeCollateral(bytes32,address,uint256)","c10dd4c6":"getEvents(bytes32[],address)","c10e5fe7":"GemCoin()","c10e7dfe":"bonusInited()","c10e9ba0":"isClientIdentRejectedOf(address)","c10eb14d":"_withdraw()","c10efd2f":"compareResults()","c10f1a75":"proxyFactory()","c10f5075":"KudosPoll(string,string,uint8,uint256,uint256,uint256)","c10fa635":"channelParticipantCount(uint64)","c10fa789":"withdrawalsVotes(address,uint256)","c10fbf0e":"reDraw()","c110afe2":"Percent(uint256,uint256)","c110e6a0":"HealthCoin()","c111368b":"vestingsRemainBalance(address)","c112411e":"_clarifyPVPSchedule()","c112601c":"transferLibOwnership(bytes32,address)","c1127f90":"PresalePool(address,uint256,uint256)","c112a083":"finalizeChangeName()","c112dfa3":"changeDecimals(uint8)","c11301d4":"getSaleContractTargetEtherMax(address)","c113d195":"XECToken(string,string,uint8,uint256)","c11403fc":"maxListingSeconds()","c114301c":"icoPlatformWithdraw(uint256)","c115b06c":"CYFToken()","c11645af":"test_threeInvalidAssertFalse()","c116574c":"__update_oraclize(address)","c1165781":"totalSupplyOnIco()","c11737c7":"getFirstBuyer(address)","c11741a9":"submitReview(uint256,bool)","c117cfe2":"TwoDimensions()","c11808da":"getFloor()","c1184537":"changeContracts(address,address,address,address)","c118a9de":"getDiscountOf(uint256)","c119167b":"numberOfExchInEstateNasBob(address,uint256)","c119d019":"collectPayment(address,uint256)","c11a4b47":"Origin()","c11b2252":"equipContract()","c11bd455":"timeOfLastHalving()","c11bf4e3":"execute(uint256,address[],uint256[],uint8[],bytes32[],bytes32[])","c11bf8d6":"CLXToken(uint256,string,string)","c11c0cc1":"getSecondPoints()","c11d9d9f":"minEtherContrib()","c11dde0d":"setManufacturer(address)","c11e1ff3":"getMe()","c11efcdc":"getRaisedForCurrentStage()","c11f49e3":"ETHERNETSUPPLY()","c11fb13e":"trustedProposals(uint256)","c1204caa":"trade(uint256[11],address[4],uint8[2],bytes32[4])","c12076f1":"holderGroupNumber()","c120d1a4":"outingreserveBalance()","c121be4d":"removeAddressManual(address)","c122759f":"issuerDistributedUnits()","c1232366":"gameCloneFee()","c1238940":"bmy(uint256,string,uint8,string)","c123a658":"boostCloneMarket(uint256)","c1243528":"airdropRecord(address)","c1246d39":"simulatePathwayFromBeneficiary()","c124e2ea":"checkBetDozen(uint8)","c1257bad":"testPassingAProposal()","c1258f69":"txCount(address)","c1263215":"calculateObtainedJOY(uint256)","c1266227":"pow2Bounds(int256)","c12692dc":"tokenRaise(address,uint256)","c12719a7":"EthPriceDependent(address[],uint256,bool)","c1273676":"fundingUnlockTime()","c1273ba0":"likeCelebrity(uint256,uint256)","c127ae41":"getSignatureHash()","c127c247":"addMember(address,string)","c127ee20":"SearchUserPurchase(string,string)","c128c9e7":"GetBuildingData(address,uint256)","c1292cc3":"lastId()","c1294224":"payoff(address)","c12954fa":"restartMinting()","c129827b":"_setSpecialityValue21(uint256)","c12a0fd7":"removeReverseRate(address[])","c12ae5e9":"blocksInFirstCapPeriod()","c12af1ce":"fipsRegister(uint256,bytes)","c12b2513":"assignSubBroker(uint256,address)","c12c202c":"getGrapesSinceLastHarvest(address)","c12c2eb3":"abstractENS()","c12c31d6":"listAllAdmins()","c12d7b01":"Error(uint16)","c12d97de":"DevGiveBlockReward()","c12dec39":"_fetchOrdersForMerchant(address)","c12e760e":"agreeFromDrone()","c12eb191":"updateEarlyParticipantWhitelist(address,uint256)","c12edde6":"EURValue()","c12f48e3":"AssetRegistered(address,string,string,string,uint256)","c12fac40":"oneHundredThousand()","c13026b0":"changePresaleCap(uint256)","c13051d7":"getCellsInfo()","c1309aea":"getOfferor(uint256)","c1310951":"createNewDepositContract(uint256)","c131acdf":"GetBestTokenCount(uint8)","c1321111":"setSaleLength(uint256,uint256,uint256,uint256)","c132bc18":"balanceWosPoolForThirdStage()","c132dd4f":"authorizedCreateTokensToPrivate(address,uint256)","c1331bc3":"setBlacklistSpender(address)","c1333a9c":"setPurchaseRequirements(uint8,address[],uint256[])","c134bc92":"hell()","c13517e1":"createDispute(uint256,bytes)","c135a2d8":"getBackgroundValue(uint256)","c135c040":"gzePerEth()","c1374d5a":"EtherUSDPriceFactor()","c138195c":"icoEtherMinCap()","c1381ea3":"DutchExchangeProxy(address)","c13862ea":"setBoardRating(uint256,uint8)","c13982ee":"checkCap()","c13992b4":"Metadium()","c13a135a":"getWinnerOfEvent(bytes32)","c13ab0fe":"WOLF4()","c13afa91":"object_locations(uint256)","c13b22ef":"setTokenTransferFeeAbs(address,address,uint256)","c13b37c7":"updateIsRevertedEndTimeReached()","c13b3895":"getHype(uint256)","c13b72a8":"registerCDP(uint256)","c13c6813":"_addTimelock(address,uint256)","c13ca374":"SimpleSale()","c13e285d":"maxTrialDrops()","c13f4af7":"claim(address,uint128)","c13fb08b":"breedOnAuction(uint256,bool,uint256,bool,string,string)","c140635b":"audit(bytes32)","c1408cda":"getDataFromAddress(address)","c141e6da":"ERC721ReceiverMock(bytes4,bool)","c141ed74":"calculateCrowdAmount(uint256)","c14248a2":"lrcSent()","c1429c11":"ChainStarToken()","c143a372":"TokenTransferFrom(address,address,uint256)","c143ab2c":"crowdSaleStop()","c143f701":"getRequestFundInfo(uint256)","c1440167":"Voterplayer()","c1441172":"setBlackFlagRequest(uint256,uint256)","c144734c":"getUploadTypes(uint256)","c1448284":"approved(address,uint256)","c144a510":"ADDR_WITHDRAWAL2()","c144a5db":"Bytelending(uint256,string,string)","c144d7dc":"buyMine(uint8)","c14634cf":"KudosTokenSale(address,uint256,address)","c1468587":"mainwallet()","c146eb02":"UNOPEN(string,string,uint256,uint256,bool)","c148002c":"latestUnlockStage()","c148e20e":"FCCToken(string,string,uint256,uint256,bool)","c14958cb":"giveUp(address,address)","c1499199":"_uncreditUser(address,uint256)","c14a2455":"balDailyLotto()","c14a3b8c":"mintTimelocked(address,uint256,uint256)","c14a6046":"payerContract()","c14a932f":"signedTransferFromSig()","c14a9f05":"challenge(address,uint256,uint256)","c14ab7a1":"PredictTheFutureCaller(address,uint8)","c14bafb1":"lastPurchaseTime()","c14bfd29":"hasAlreadyVoted(uint256,address)","c14c1ce3":"requestUpdate(uint256)","c14c5574":"Gold(address,address,int256,address)","c14c7bd7":"performRead1()","c14d2358":"init(address,uint256[],uint256,uint8,uint256,bool)","c14d3abe":"enableSuperUser(address,bool)","c14e50ce":"setValidater(address)","c14e61ba":"overdraftTotal()","c14e6cd0":"changeTransferLock(bool)","c14e7a3f":"setCooldown(uint16,uint32)","c14e9f58":"submitBlockHeader(bytes)","c14edad2":"teamDistribute()","c14f42fd":"mLoadAndReturn(bytes32)","c14fbd64":"satoshiMood()","c15185f5":"getAuditPrice(uint256)","c151ac55":"_createMovie(string,address,uint256)","c151c5ad":"getSignerTable()","c15294a1":"creatGameBet(uint256,bytes32)","c152d3eb":"setKYCTeam(address)","c1531ecc":"changeIssuer(address,bool)","c1551fc8":"QuadCoreChain()","c1554658":"changeDepositorLimit(uint256)","c155836d":"LuCyToken(address,string,uint8,string,string)","c155cfde":"_preAllocateTokens(address,uint256)","c1560a14":"hardCapInUSD()","c1562547":"checkUser()","c156ef6b":"_createPainting(address,uint256,uint256,uint8,uint8,uint256,uint256)","c157b869":"totalUsdValueOfAllTokens()","c157d72c":"itemInfo(address,uint256,bytes)","c1596534":"addReserve(address,uint8,bool)","c1598f6a":"newWage(uint16)","c1599011":"conversionRateOfState(uint256)","c1599bd9":"X()","c15a6791":"oneShotTokenRepartition(uint256)","c15ae376":"_shareToDistribution(uint256,address,uint256,uint256)","c15aec44":"totalGasUtilizing()","c15c09b5":"admin_set_exchange_rate(uint256)","c15d0b10":"getLoanValue(bool)","c15d15da":"_isValidSignatureAndData(address,address,bytes)","c15d7bca":"setEthToTokenConversion(uint256)","c15e47c4":"getFirstBatch(address,address)","c15e61c0":"Authorization()","c15f05fb":"changePrimaryArbitrator(address)","c15f618a":"purchasePokemon(uint256)","c15f68f0":"Retired()","c15f817d":"_import_island(bytes32,address[3],uint256[7],uint256[8])","c15f8779":"get_previous_item_in_state_from_item(bytes32,bytes32)","c1614981":"allocateLocked(address,uint256)","c1615945":"setAffiliateContract(address)","c1615c87":"DEFROST_PERIOD()","c161d506":"CollabCoinToken()","c162ba2f":"walletId()","c162bc03":"clearProposal(address)","c163bba7":"publish(string,string)","c163edf7":"OutcomeEvent(string,uint256)","c163fb0e":"ownedHouses(address)","c1640913":"RETAINED_TOKENS()","c166311f":"freeLotterySeconds()","c166c458":"getUserRequestCount(address)","c166ee38":"sweepAccount()","c1670257":"redeemContractSentTokens(address,uint256)","c1674b74":"assertReadyToClose(uint256)","c167d1cd":"getAvailableSupply()","c1684711":"migrateTokens(address)","c16849c0":"tokenSC()","c1687877":"buyTokens(uint256,uint256,address)","c168e037":"getCustomerPremium(uint256)","c1691fc3":"add_bonus(uint256)","c1694bd4":"TransferDetails(string,uint256,string,uint256,uint256,address[])","c16959b2":"_unpackRaceFinishData(uint256)","c1699a99":"stakePeriod()","c1699bf6":"setPrimaryAccount(address)","c169ec0d":"setBuzzCafe(address)","c16ac06f":"CM()","c16ae3ce":"_receiveFrom(address,uint256)","c16b451f":"_checkedTransfer(address,address,uint256)","c16b9374":"regularEndGame(address,uint32,uint8,uint16,uint256,int256,uint256,address)","c16bca13":"MIN_AUDIT_TIME()","c16c0851":"miningOneSelf()","c16d1377":"IS_CND_CONTRACT_MAGIC_NUMBER()","c16d3344":"setMinimumOfferPrice(uint256)","c16d515a":"_createCenturion(address)","c16e50ef":"validate(bytes)","c16f402c":"getEpisodes()","c16fe907":"getTransfer(uint256)","c1707f66":"stateSetOpen(uint32)","c170fd54":"bid(uint40)","c171747b":"convertEthToMet(uint256)","c1717f80":"BC2Token()","c171cfa6":"getBetValueByGamble(uint8,uint8)","c171fb91":"referrerLevel1Percent()","c172085e":"initialization()","c17281d0":"refundPartial(address,uint256,uint256,uint256)","c172aae5":"getIdentifier(uint256)","c172f9c9":"receiveApproval(address,uint256,address,bytes32)","c1733712":"authorizePayment(address,uint256,uint256)","c1733f68":"getToken(string)","c173508b":"removeConnection(address,address,bytes32)","c1736222":"tokenForSPSold()","c1739b69":"InfraOfOwner(address)","c1747585":"testEvent2()","c1751903":"lockBreak()","c1756a2c":"sendEther(address,uint256)","c1758fee":"vest2mlDevelopers(address,address)","c1766657":"addBonusForMultipleHolders(address[],uint256[])","c176b1d8":"deletePriceIdv(bytes32)","c176d42a":"NavGlobalTourCoin()","c176e639":"payout(address[],uint256[])","c176e73b":"pkt()","c177c20f":"CliToken()","c177e804":"WEETtoken()","c177f22e":"findKingdomCalled(string)","c1784a4e":"safekey(uint256)","c1786ab2":"pre(address,bytes32,bytes32)","c178a2d4":"CreationContract()","c178fc87":"setTokenRate(uint256,string)","c1790561":"_getPetBonus2(uint256)","c179186e":"collectWinnings(uint256,uint256,uint256)","c179520c":"ManageAccount()","c17a099b":"presaleBonusTokensDistributed()","c17a893e":"transferAUTOtoken1(address[])","c17b5a93":"ProfitExchange()","c17b9770":"log2Floor(int256)","c17c0456":"ownerCEO()","c17c3521":"setHourlyRate(uint256)","c17ccc6c":"withdrawUnlockedTokens()","c17d8720":"checkBank(string,address)","c17de343":"isStarOwner(uint256,address)","c17e2aa1":"burnAllTokens()","c17e6817":"sendSafe(address,uint256)","c17e92b6":"unregisterFromBlacklist(address)","c17ed7bd":"purchaseSilver()","c17f23e8":"getRoundID()","c17f8891":"setEtherFeeMin(uint256)","c17ffac6":"unsetRegionForSale(uint256,uint256)","c180e1d0":"GCPToken()","c1811783":"FreezableToken()","c1812b15":"reorganizeOwners()","c1826d78":"Collect()","c1829a14":"testFailTooFewConfirms()","c182f531":"GetFreeEther()","c183660c":"cancelJobContract(uint256,string)","c18378a0":"sellTokensFrom(address,uint256)","c18384ec":"setRestricted(address)","c1838e92":"proposeTokenOwner(address)","c1839258":"LogTokenPurchase(uint256,uint256)","c1840b39":"_generateRandom(bytes32)","c1857bf7":"withdrawFoundation(address,uint256)","c185d772":"emissionStages(uint256)","c185e492":"preSaleThirdPrice()","c186dcbf":"getStaticArraySum()","c18715f8":"prolongationPermitted()","c1873e26":"releaseCoreTeamAccount()","c1889ff2":"payAccTax(uint256)","c188f44b":"addproduct(string,string,uint256,string)","c1891ac6":"multiplePing(address[])","c1899ca7":"request_dividend(address)","c18a40c7":"multiowned(uint256,address[])","c18b4136":"AAC()","c18b5279":"KFHToken()","c18b8db4":"listings(bytes32)","c18b9760":"test_insert_findWithHintPrevDecreased(int256)","c18bca5f":"setCollectionAddress(address,address)","c18ca54c":"testEvent(int256,int256,uint256,uint256,string,string)","c18d767a":"weiMinSalePreIco()","c18e8903":"totalWeiRaisedDuringICO4()","c18e94b4":"Keizer()","c18edde1":"saleopeningTime()","c18f4831":"burnFeeDenominator()","c1908360":"createEntry(string,string)","c190b129":"holderState()","c1912433":"acceptAndPay(bytes32,uint256[],uint256[],int256)","c1918e90":"accountAddressForSponsee()","c191cbd7":"TeamTokensAllocated(uint256)","c191d37d":"Escapable(address,address,address)","c1927292":"TIER1_BONUS()","c1929d8c":"ADVISOR_THREE()","c192ca98":"isCS(address)","c1932833":"maxAirdropParticipants()","c19358bb":"setPropertyLastUpdater(uint16,address)","c193fbf8":"pushArray(bytes32,address)","c19455c8":"signedTransferCheck(address,address,uint256,uint256,uint256,bytes32,address)","c1955e62":"spend(uint256,bytes32)","c195dc41":"getStageEndDate()","c19678d5":"canLotteryBeExecuted()","c196b54f":"bound(uint256,uint256)","c1971240":"dailyGrowthUpdated_date()","c197a7b1":"getLastStoragePayDate()","c197cdee":"preSaleTokenLeft()","c1989276":"MaxItems()","c1991040":"getCurrentVotingDescription()","c19a8095":"deleteUser(address,address)","c19bbf50":"getLockStatus(address,address)","c19c9a21":"CCTHCoin()","c19d7808":"MamaBearToken()","c19d93fb":"state()","c19da6b2":"canBuy(address,address)","c19dccd8":"KantrotechCoin1(string,string,uint256,uint256)","c19dd320":"cancel2(uint256)","c19e33ce":"COIN_SUPPLY_ICO_PHASE_0()","c19e7b00":"WeiCapChanged(uint256)","c1a06de3":"Valens()","c1a12d66":"crowdsaleOpen(bool)","c1a21bf3":"sellerBalances(address,address,uint256,address)","c1a2a8f4":"boards()","c1a2babc":"getMemberSince(address)","c1a38768":"STARTUP()","c1a3bb06":"total_bet_withdrawn()","c1a3bda5":"randomQueryID()","c1a6ec6a":"ADVISORY_TEAM_PORTION()","c1a7db7b":"MtcDailyLimitChange(uint256)","c1a82cdb":"reissueCertWithID(bytes32,bytes,bytes32,uint256,bytes32,bytes,bytes32,uint256,bytes32)","c1a85e16":"test_insert_findWithHintNextUpdateTail()","c1a9953f":"checkRokTeam()","c1aa049d":"getIsPurchased(address)","c1aa104e":"OpenRetailContract(uint16,bytes32,string,string)","c1aa5d98":"getGameIdByAddress(address)","c1aa721d":"lockAfterManuallyMint()","c1aaa717":"_bountySupply()","c1ab1b54":"RebateCoin()","c1abbf6a":"addjoinlist_even(address,uint256)","c1ac7902":"playJackpot()","c1ad5bea":"isdeposit()","c1ad7925":"finalizeFunding(address)","c1adb83e":"NecashTokenBase()","c1ae36d0":"carsOf(address)","c1ae4044":"checkBetColor(uint8)","c1af5785":"enterLottery()","c1afdd48":"belowSevenBets()","c1b0510a":"GlobalBusinessSystem()","c1b0561d":"PDTToken()","c1b056b0":"getNodeLeftChild(bytes)","c1b06513":"registerEvent(bytes32[])","c1b07b1a":"receiverOne()","c1b082b6":"issueOfTokens()","c1b0dc2f":"LogPolyClaimed(address,uint8,uint256,uint256,uint256)","c1b15e44":"_setAllowance(uint256)","c1b16cb0":"ownerAddAsset(string)","c1b2dfc1":"gameGiftMaxAmount()","c1b36489":"QuickUnionPayChain()","c1b3e6ab":"blockedSum()","c1b43a17":"secondHighestBidder()","c1b43af8":"IPchainStandardToken(uint256,string,uint8,string)","c1b466d6":"calculate0xbtcReceived(uint256)","c1b4aa51":"burnContractCoins(uint256)","c1b58f6c":"unlockAllAllocationAddresses()","c1b664de":"setStageCount(uint256)","c1b668a9":"getBoardInfo(address,address)","c1b68a7c":"DebitClientOnce(address)","c1b73010":"removePauser_(address)","c1b74ad8":"propose(uint256,bytes32,address)","c1b7a892":"AsiaCoin()","c1b8847b":"setMaxFeeWithdrawal(uint256)","c1b8b704":"updateGlobalMax(uint256)","c1b90c7b":"_sendTokens(uint256,address)","c1b99811":"transferPrimordialToken(address,uint256)","c1b9f177":"bountyReserve()","c1ba93e1":"dbkDeposit()","c1bb95d0":"TransferConfirmed(address,uint256,uint256)","c1bbcbef":"MICKTOKEN(uint256,string,string)","c1bc2664":"ClearView()","c1bd1e85":"killFeed()","c1bd3685":"proposeSolve(uint256,uint256)","c1bd762b":"wantMyEther()","c1bd8186":"crowdsalepricing(address,uint256)","c1bd8ecb":"initializeCrowdsale(address,uint256)","c1bd9b12":"getShareAddressFromId(uint256)","c1bdff26":"onNewLoan(uint256,address)","c1be4031":"XaurumProxyERC20()","c1beb1e1":"MusereumToken()","c1bf1dcf":"setRegistrar(address,bool)","c1bf22a9":"XAUToken()","c1c02a46":"Atlas()","c1c03094":"EventBattleOver()","c1c0e046":"rescueAccount()","c1c0e9c4":"exec()","c1c1066b":"getCommentsCount()","c1c11c96":"getSender(address,uint256,address,uint256,uint256,uint256)","c1c1d218":"BOND()","c1c28d7d":"calNewTokens(uint256)","c1c379ac":"tokenTwitter()","c1c3eccf":"vestingPeriodInMonths()","c1c43648":"addAction(uint256,uint256,uint8[6],uint8[6],uint16[6],uint8[6],uint256,uint256)","c1c4676e":"updateGameCost(uint256)","c1c5897e":"AOMcoinERC20()","c1c5a3b6":"CaptainSell()","c1c5de4a":"tryDeposit()","c1c64ecf":"mintPriceBuffer()","c1c6c749":"changeWhitelistPrivateStatus(address,bool)","c1c6d4e8":"addLoanProduct(uint32,uint32,uint32,uint256,uint32,bool)","c1c723f4":"validateProposedMonarchName(bytes)","c1c74dde":"_setFunds(address,uint256)","c1c7bc68":"addFreeMineralMulti(address[],uint32[])","c1c8277f":"reclaimOwnership()","c1c8b89d":"Recash(uint256,string,string)","c1cbbca7":"contribute(uint256)","c1cbbe6c":"getRoundAvailableToken(uint256)","c1cbdff3":"moreThanSoftLimit()","c1cc0046":"returnOffer(uint64)","c1cc0775":"calculateFeeDynamic(uint256,uint256)","c1cc6958":"leekStealGo()","c1ccaed3":"pageBuyRecordByAccount(address,uint256,uint256)","c1cd1759":"SpicePayroll(address)","c1cda902":"setTradeable()","c1cdaae8":"generate(address,address,address,uint256,uint256)","c1ce53fc":"reflect(string)","c1ce56eb":"addAccount(address,uint256)","c1ce6647":"minAmountToGetBonus()","c1cfb99a":"get_balance()","c1d038b2":"getSkillIdByIndexAndLevel(uint8,uint8)","c1d11037":"updateAddresses(address,address)","c1d1f5c0":"BirdToken()","c1d1faf3":"createAuction(uint40,uint128,uint128,uint40,address)","c1d22403":"_subFromValueHeld(address,uint256,bool)","c1d25c3d":"insert(int256,int256)","c1d298ab":"emitFeesDonated(address,uint256)","c1d32ad5":"Distribute(address,uint256)","c1d34b89":"transferFromAndCall(address,address,uint256,bytes)","c1d357bc":"getMinAllowedBid(uint256)","c1d4691a":"withdrawalTo()","c1d47a21":"submitPayment(bytes8,uint32)","c1d4bc64":"originalsCount()","c1d4f708":"getMwLength()","c1d55af8":"buy(uint256,address,uint256,bool)","c1d5725f":"buyToken(address,address,uint256)","c1d5e84f":"addNewUser(address)","c1d6036b":"contractExchangeRate(address)","c1d63ce6":"deleteArrayBytes32(bytes32,uint256)","c1d66482":"Postman()","c1d6ab37":"setIsContainerForShareToken(bool)","c1d6cbd8":"getPlayerPoint(uint32)","c1d75bea":"IBM()","c1d9e273":"nextFreeCount()","c1da3923":"ICOstartTime()","c1dbbfb3":"withdrawAllFromRoot()","c1dbd9b2":"authorize(address,uint256)","c1dbf5ef":"changePTSBAddress(address)","c1de0842":"quarterThird()","c1de93df":"Forwarded(address,uint256,bytes)","c1de9ef8":"getPositionHeldToken(bytes32)","c1dfacb2":"getQualifiersPoints(uint160)","c1e0e604":"updateUsdPerMEth(uint256)","c1e10f65":"distributeeBitcoinCashMedium(address[])","c1e1955e":"getaddressfocuscardid2(address,address)","c1e1b327":"adminCollectPastShopFund()","c1e31eab":"SERVER_TIMEOUT()","c1e3bd3e":"getParticipants(uint256)","c1e41f38":"COMPANY_TOKENS()","c1e457c8":"experienceDelay()","c1e472be":"returnNotes(uint256)","c1e4884d":"setSecondStageStartsAt(uint256)","c1e4dfda":"setPriceWei(uint256)","c1e50f3c":"internalAddManager(address)","c1e5202a":"isUserMakerFeeEnabled(address,uint256)","c1e52775":"addDenomination(bytes8,address)","c1e5304a":"CreateNewDraw(uint256,bytes)","c1e59a50":"Example4(string)","c1e6102b":"LunyrToken(address,address,uint256,uint256)","c1e65cb9":"BTRS()","c1e68672":"totalWhitelistedFunding()","c1e68e4b":"developer_string_D(string)","c1e6c506":"TokenPriceInWei(uint256,uint256)","c1e70e63":"startManualPeriod(uint256)","c1e71903":"getResults(uint256,string)","c1e7310a":"signEA(uint32)","c1e74d71":"minPresaleContributionEther()","c1e99a0e":"isInitialInvestor(address)","c1e9c53e":"Lottery(uint8,uint256)","c1ea8b93":"preCrowdsaleTokens()","c1eac693":"ArisaCoin()","c1eb1840":"canBurn()","c1eb3534":"batchMintToPool(uint128[],uint256[],uint128[])","c1eb354a":"setlockall(uint256)","c1eb50a7":"LinaAllocation(address,uint256)","c1eb5ddd":"DEV()","c1eb8c89":"wihtdraw()","c1ec10f4":"RigoBlock()","c1ec4a2a":"RegisterContract()","c1ed41fa":"appliedPresale()","c1ed54a1":"isBetValid(uint256,uint256,bytes)","c1ee22dd":"EMISSION_FOR_SALESTAGE5()","c1ee3375":"autoTransferApproved(uint256,uint256)","c1ef098b":"storeHarvestOperationByRegulator(string,string,string,uint32,uint16,uint16,string)","c1f04f3c":"allWeights()","c1f06e89":"changeYUMOAddress(address)","c1f0dac1":"test_largeDeviationNotPermitted()","c1f0e2c3":"createGameRound(uint256)","c1f10663":"withdrawAccumulatedFees(address)","c1f16bdc":"getWeiBalance(address)","c1f18e38":"isExpired(bytes)","c1f19220":"summFounders1()","c1f1d116":"internalVote(bytes32,address,uint256,uint256)","c1f307c9":"_isTime()","c1f45e80":"sendForPreICO(address,uint256)","c1f52604":"winningPrice()","c1f573ca":"bidInAuction(uint256,uint256,uint256)","c1f62946":"getSecretRevealBlockHeight(bytes32)","c1f64cb0":"supportedRoleList(uint256)","c1f77309":"assignedPayoutAddress()","c1f7c539":"initPricer()","c1f8056b":"createAvatar(address,string,uint256)","c1f979ab":"add_recent(uint256)","c1fa1ed0":"assertEq(bytes32,bytes32,string)","c1fae25b":"receiveAirDrop()","c1fb7c34":"hmin(uint128,uint128)","c1fb9b9e":"developer_How_To(string)","c1fcf863":"getSoftwareExecRecord(uint32)","c1fd2580":"spendable_supply()","c1fd4339":"createMarket(bytes32,uint256,uint256,address)","c1fe5281":"minPurchaseNum()","c1ff808d":"changeBonus(uint256)","c1ffc0a5":"MinimumEthereumInvestmentUpdated(uint256,uint256)","c2006a18":"set_fixedFeeInCWC(uint256)","c201293b":"setCollateralPoolContractAddress(address)","c20155df":"ethRate2()","c201df97":"UnLockAddress(address)","c2021d1b":"maxTeamBonusBps()","c203367a":"EnddatePresale()","c2038560":"setOutcome(bytes,bytes)","c203d77f":"setSaleFinishTime(uint256)","c204505a":"testFailRetractLatestRevisionDoesntHaveAdditionalRevisions()","c204642c":"airdrop(address[],uint256)","c204b288":"InvestorChanged(address,address)","c204f9f1":"_transferFromToICAP(address,bytes32,uint256)","c2052403":"payOut()","c20547b3":"getGameAmount(uint256)","c205afd4":"deferredTotalTokens()","c205e64c":"revokeInsertAgentAuthorization(address)","c20615ed":"ownerWithdrawn()","c20652fe":"setApiAddress(address)","c2083f55":"lacksFunds()","c2091d0e":"getPatron(uint256)","c209fbe9":"change_notice(string)","c20a20d6":"setBlipTokenAddress(address)","c20a6ae9":"EDMToken(address,uint256)","c20c0f3a":"betsForLevel(uint256)","c20c1d9b":"newWithdrawCommission(uint256)","c20e346f":"unFrozenToken(address,uint256)","c20ec5dc":"numberOfFriends()","c20f966b":"Utcoin()","c2108a92":"calculateBalance(uint256,uint256)","c210c623":"getKeys(uint32)","c21191ae":"GechainCoin()","c2127e03":"getMyShrimp()","c212bad5":"dropModule(string,bool)","c212cffa":"NUGOLD()","c215290a":"frozenUntil(address)","c215e800":"currentSubRound()","c2161c31":"getStringHash(string)","c2168ecd":"removeMintContract(address)","c216c0d3":"addCredits(address)","c217a724":"spendWithGasAndData(address,uint256,uint256,bytes)","c217c0e1":"ClickGemTokenERC20()","c2190c94":"registerSettlement(uint64,address,address)","c219c28c":"votingTokenAddress()","c219d326":"getData_14()","c21aa2e4":"PoHarj()","c21abf05":"tatalEthFromBuyer()","c21afa55":"MintingManagerRevoked(address)","c21afe12":"schedulePriceUpdatesRolling(uint256,uint256,uint256)","c21bbe56":"SetupDone()","c21c45e3":"iconRate()","c21c5ee1":"fixSpecications(bool)","c21c9c21":"validEvent()","c21d0204":"SetEvaluate(bytes32[],uint8,uint64[])","c21d5ab7":"setNode(address)","c21db033":"removeSupplier(address,address)","c21de274":"transferReverseProxyThirdParty(address[],uint256[],uint8[],bytes32[],bytes32[])","c21e5712":"makeLiquidCor()","c21ea693":"retraitStandard_3()","c21ec92c":"getAssetIpfs(uint256)","c21ed112":"genesisVirus()","c21fb125":"SpecificApproval(address,address,uint256)","c21fcffb":"DIYTubeCoin()","c2205ee1":"_authority()","c2222b80":"claimSubscriptionDeposit(uint256)","c222ef6d":"periods(bytes32)","c2234f67":"CONVERSION_DENOMINATOR()","c2235e74":"getTotalAmountOfChatMessages()","c2236b26":"setICO3Phase()","c2239daa":"setselfdropamount(uint256)","c223f557":"stopRedeeming()","c2248877":"getBarCodeDataCount(bytes32)","c2248c22":"changeOldTokenReward(address)","c2250a99":"transferStoreOwnership(address)","c225752c":"OneChanceCoin(string,string,uint8,address,address)","c22598d2":"BitClemm()","c225bf03":"resetContractDeploymentDate()","c226d279":"setMiniPoolEdit_7(string)","c226d9ee":"doTest()","c2276090":"settleBet(bool)","c227cee0":"shutThatShitDown()","c2289576":"AddTitle(uint256,string,string,string,uint256)","c228bcc6":"getFillVolumes(bool,bytes,uint256,uint256)","c2299e33":"shutdownMarket(bytes32)","c22a146c":"Unlock(address,string,bytes32)","c22a933c":"setBaseDeposit(uint256)","c22ab4e0":"reservedWallet()","c22af7ff":"ComputeBuy(uint256)","c22c4f43":"services(uint256)","c22d6c3c":"setArenaInterface(address)","c22f0ee2":"transferManagers(address)","c22f1c54":"_initializeAccount(address,address,uint256,uint256)","c22f8250":"updateStandard(bytes4,bytes4)","c22fc384":"exitScam()","c2304c4a":"addExplicitPosition(uint32,int64)","c2314be4":"CONFIG_FEES_DIV()","c231bace":"setMigrationTarget(address)","c232209e":"_verify(address,string)","c2328516":"disablePrivateFund()","c2329e5f":"_isNotOnSale(uint256)","c233e870":"isLatestPatchTree(bytes32,bytes32)","c2353918":"getCount(uint256)","c2356d23":"mintChest(address,uint16,uint24,uint24,uint8,uint8)","c235a5c7":"getGameStart(uint256)","c235e858":"VendorInterface(address)","c2362dd5":"lastEpochBlock()","c23693e0":"multiAccessRequired()","c23697a8":"check(address)","c236cc66":"GeneralUpdate(uint256,uint256)","c2370a62":"openGameResult(uint256,string)","c237898d":"getOwnerBalanceInMilliTokens()","c2381296":"beginPwn()","c2385fa6":"right78(uint256)","c238999b":"dislikeTrack(address,bytes32)","c239dfe0":"PermissionAdded(address)","c23a25ba":"getRoundBetOrigin(uint256,uint256)","c23a7427":"createMultipleWikiPages(string[])","c23b4b5b":"bountyShare()","c23c87d5":"play(bool)","c23da3a9":"initialSaleEndDate()","c23de962":"DefaultActionCalled()","c23e1cea":"SaleTokens()","c23ec301":"KSScidTOKEN()","c23f001f":"balances(address,address)","c23fed45":"setEscapeRequest(uint32,int256,uint32)","c2407089":"CursedToken()","c2410a69":"lockCostPerHour()","c2412676":"Token()","c2427f76":"getBidID(address,bytes32,uint256,uint256,uint256,uint256)","c242afaf":"bet(uint256,uint256,uint256[],uint256,address,bytes32)","c243431e":"AnalyticProxy()","c24366f0":"setKYCProvider(address)","c243bdee":"isHolderOwnAddress(bytes32,address,address)","c24504b7":"internalBuyTokens(address,address,uint256)","c245c1bc":"ownerBurnToken()","c2473378":"consortiumPlaceholder()","c247620d":"getArtistInfo(address)","c2490a67":"removeCardOwner(uint64)","c24924d6":"setQueryFee(uint256)","c2494dbf":"transferOnWallet()","c24977cf":"testPrivate()","c2498be6":"conjureAirdrop()","c24a0f8b":"endDate()","c24a8908":"token_airdrop_cnt_max()","c24a9674":"finalizeLastRound()","c24ad463":"Refundpot()","c24becf3":"getLastTier()","c24c153d":"addRound(uint256,uint256,uint256,uint256,uint256,bytes32)","c24d316e":"UNITDummyPaymentGateway(address)","c24de0e4":"halvingSubsidy(uint256)","c24dec82":"TOKEN_BUSINESS()","c24e1fc1":"issuedSupplyRatio()","c24fe21b":"transferLockup()","c2502d34":"claim_price_money()","c2506eee":"setO3(address)","c2507ac1":"getTokenAmount(uint256)","c2507ef7":"_createPanda(uint256,uint256,uint256,uint256[2],address)","c250a312":"active_withdrawable()","c250ef46":"refSystem(uint256,address)","c25193ad":"lcm(int256,int256)","c251a4e9":"G2Ufund()","c252ca75":"getBonusPercent(address)","c252d844":"rest_time()","c253400b":"RPS(address)","c2535bf0":"COOLCOIN()","c254e4db":"SFT()","c2552497":"impl_mining(address,bytes)","c255343e":"targetUser()","c255fa40":"updateTotal()","c255fb17":"getRefBalance(address)","c25615c0":"joinOneLottery()","c256d578":"getLastAuctionWinsDate()","c256ea58":"get_receiverCryptobank(uint256)","c2571a0a":"percUp(uint256)","c2572c51":"advisorsAndPreICO()","c257c851":"calculateEtherReceived(uint256)","c257eabb":"etherPaid()","c257f3ab":"getNumberOfShipsByOwner()","c258ff74":"List()","c2596b1e":"getDragonPrice(uint256,uint256)","c25a796e":"setHardcupFalse()","c25ab8b0":"iOSCoin()","c25acada":"Bithereum()","c25ae09f":"EthealNormalSale(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","c25b345a":"VivekRohitVibhayToken()","c25c22ee":"stageTokenMul(uint256)","c25cf1d0":"changeLockPeriod(uint256)","c25d0ac1":"tgeSettingsPartInvestor()","c25e6908":"ultimateOutcomes(bytes32)","c25f1901":"addThing(bytes32,string,string,string)","c25f1afe":"SponsorAdded(address)","c25f75fc":"pantry()","c25fe1a4":"changeHoldingTax(uint256)","c2606d99":"BITTECHToken()","c2608314":"getJntBeneficiary()","c260f681":"IsBoilerValid(uint256)","c2610cda":"SecretNumber()","c26181e0":"censorUser(address,bool)","c2619a5a":"AdministratorAdded(address,address,bool)","c26298a7":"getBalanceOfResidualBcoupons()","c262a33b":"preSaleCloseTime()","c262b912":"createCampaign(string,uint256[3],uint256[],uint256,uint256,uint256,uint256,string,int256)","c262df45":"isKnownRequest(address,address)","c26317d1":"RoundRevealStarted(uint256,uint256)","c26381f2":"limitETH()","c264786f":"pauseBlockNumber()","c264a063":"withdrawExcess()","c264a77c":"setSettleTimeout(uint256)","c2656473":"CROWDSALE_LIMIT()","c265a6c0":"KRCPreSaleContract(uint256,address,address)","c26613d5":"LogRebalance(address,bytes32,string,uint256,uint256,uint256)","c2664609":"submitStackholderTransaction(address,bool)","c2674780":"freecommunitycoin()","c2676e39":"VAToken()","c267e4b8":"previousWeiBalance()","c26875a4":"calculateCellBuySimple(uint256)","c268e777":"setDailyHourLimit(uint8)","c269014b":"getMemberId(address)","c2695a25":"Rivercoin()","c2699b1d":"getFirstBuyLimit(bytes32)","c269f263":"PRETDESupplyRemaining()","c26a331d":"bonusProvider()","c26aa3c9":"lockUnicorn(uint256)","c26b41e7":"totalUETsSold()","c26b7ce9":"CashTelexToken()","c26bacd1":"removeDriver(address)","c26c12eb":"getQuorum()","c26c7472":"addTimeToExpiry(uint256)","c26c84ec":"setBI(bytes32,int256)","c26d0412":"ethRate1()","c26d0c2c":"emitWorkPaused(uint256,uint256)","c26d69e1":"OnePercentGift()","c26dd189":"jade(uint256)","c26fe7ce":"releaseVestedTokensFor(address)","c270cbeb":"BtcThumb(uint256,string,uint8,string)","c270ce28":"rdCollectorAddress()","c270d7cb":"getPlayerRoundWinningInfo(uint256,address)","c2710949":"calcValuePerShare(uint256,uint256)","c2714a97":"addBRA(address)","c271ca90":"numMomentsOf(uint256)","c2722ecc":"getStore()","c2723d2e":"token_transfer(address,address,uint256,bytes)","c272f73e":"burnSignature(bytes,address,address,address,uint256,uint256,uint256,uint256,bytes)","c27382d9":"buyAndPlayGame(uint256,uint256,address)","c273b05f":"spentParsecs()","c27509cf":"investDirect()","c27549d9":"setRemainders(uint256,uint256)","c276086f":"createProducer(bytes32,uint256,bytes32)","c2761031":"k(uint256,uint256)","c2765b77":"setLegalToken(address)","c276963f":"tabsOneEthCanBuyICO()","c2775347":"haltsTrades()","c2777ce3":"currentEtherRateInCents()","c277f1ac":"fromId(uint256)","c277fe56":"pause(bool,string)","c2783ee5":"viewCrowdSaleLive(bool,bool)","c2784966":"TkoWhitelist(address)","c279d042":"product4_sell()","c27a65c1":"changeEthPriceQueryDelay(uint256)","c27a74d0":"catOwners(uint256)","c27b2c2d":"collectEarnings()","c27bc67c":"configureKeys(uint32,int256,bytes32,bytes32,uint32,bool)","c27bc7b2":"fortifyClaims(address,uint16[],uint256,bool)","c27c327e":"changeNewRubesUntilPayout(uint256)","c27d1580":"getNorsefirePrice()","c27d607b":"lastEvidence()","c27d7721":"create(uint256[101][])","c27e7398":"getLockedTimeUserInfo(address,address)","c27fc305":"f1()","c280541c":"buy(uint256,address,bytes32)","c2808d1a":"MinSum()","c2812f74":"triggerMinCap()","c281309e":"feeTake()","c28196b1":"addImmigration(address)","c281a013":"FinalizableCrowdsale(uint32,uint32,uint256,address)","c281d19e":"cbAddress()","c283226d":"reclaimTokens(string,string)","c2832430":"withdrawForfeited(address,uint8,address)","c2843a14":"addInviterValue(uint256,uint256,address,address)","c2844c60":"emitJobRatingGiven(address,address,uint256,uint8)","c2845184":"SUPPLY_FOR_REFERAL()","c284ab55":"eLYQD()","c284cdc5":"GetDescript(string)","c2852f38":"pauseContract(uint256)","c2856ca9":"presoldMax()","c285a245":"preferredSaleTLYperETH()","c285daf9":"Xoflife()","c286f3d9":"SetLockAddress(address)","c287820a":"kittensSold()","c287fa72":"calcDiviDistribution(uint256,uint256)","c288ab9d":"getUserCurrentMartialId()","c288eeee":"nowPeriod()","c2897b10":"stand()","c289adfa":"getAssetPrice(uint128,uint128)","c289dbe8":"first_withdrawal(uint256)","c28a56f1":"checkReceiptProof(bytes32,bytes,uint256[],bytes,bytes)","c28a9157":"bullsmasterReq()","c28aafb1":"addWallet(address,string)","c28b4369":"giftCard(uint256,address)","c28b4577":"setPermissionById(uint8,bytes32)","c28bfe5a":"testFailCreateSameIpfsHashAndNonce()","c28c770a":"getLockedTokensPerUser(address)","c28cedf3":"DEMO()","c28d38a8":"STARTING_SEEDS()","c28d5644":"LogMinSell(address,uint256)","c28db642":"tocancel(uint256)","c28dbc38":"grantAccessForToken()","c28de2cd":"upgraded()","c28e5022":"collectAndUpdate(address[])","c28e6e39":"ReducingSupplyCoin()","c28eab85":"setMinimumTokenSell(uint16)","c28ec9d7":"respondToChallenge(uint256[9],bytes,bytes32[],bytes,bytes32[],bytes,bytes32[],bytes,bytes,bytes32[])","c28f57ca":"ICOSaleStart()","c28f812c":"getPaycarnita()","c28f8e09":"icoFunded()","c28f9df1":"requestVestingTrusteeOwnershipTransfer(address)","c290367f":"playDiceCombinations(uint256,uint256,uint256)","c290d691":"pay(uint256)","c291ad27":"Notify_Number(string,uint256)","c291bf6d":"AuthDapps(address,bool,int256,bool,bool)","c291df56":"affPercent_()","c29224ea":"roundFailedToStart()","c292aae3":"McrForGasFailed(address,uint256)","c2930f91":"baseUnit()","c29338cf":"cozyTime(uint256,uint256,address)","c293fc0a":"SetBankerPrincipal(uint8,uint256)","c29402f1":"relistGenesisSales(bytes32,uint256)","c2944f69":"_multiSendOwner()","c2944f7a":"registHolderStep(address,uint8,address)","c294c93b":"getSANOwner(uint256)","c2954ff4":"Sent(address,uint256,bytes)","c2955bdf":"setUserBlacklistedStatus(bool)","c296302a":"transferRoot(address)","c296f721":"_buyLandForCandy(address,uint256)","c29721e0":"sendArena(address[],uint256[],uint64)","c297fa0f":"DEFAULT_DURATION()","c2985578":"foo()","c2992300":"setCreatePrice(uint256)","c29988db":"distributeEbyte(address[],uint256)","c299a394":"getNextRank(address)","c29a6fda":"setERC20(address)","c29d350f":"startTimeOf(address)","c29d9d74":"startMultipass(string,string,string,string,string,uint256,address)","c29e8863":"setImplementation(bytes32,bytes32,address,bytes32)","c2a029f0":"setID_control(uint256)","c2a15dbb":"_currentIcoPhaseBonus()","c2a15e7e":"votingEndsInHHMM()","c2a24b33":"Post(address,string,string)","c2a2747b":"p1()","c2a33485":"setReg3(uint256)","c2a394cb":"AuctionSuccessful(uint256,uint256,address,address,uint256)","c2a48c70":"revokeUserRole(bytes32,string,address)","c2a49237":"memberSellToken(uint256)","c2a5e5c2":"setTwitter(string)","c2a63e3b":"getEmployeeCount()","c2a88340":"Deactivate()","c2a8ec80":"betStats()","c2a95cc9":"updateTrustSettings(address,uint256)","c2a960a1":"signSendFlower(bytes32,string,string,address,string,bytes16,uint256)","c2a96ce5":"EscrowVault(address)","c2a98b41":"mymethod(uint256,string)","c2aaf9c4":"receiveEth(uint256)","c2ab66dd":"hasAttribute1ButNotAttribute2(address,bytes32,bytes32)","c2ac0b4a":"intMax(int256)","c2ac3aff":"addEth()","c2ac481c":"disaToken()","c2acc5cf":"mintTokens(address[],uint256[])","c2add678":"getLockerInfo(address)","c2adf34a":"bonusWeiAmount()","c2ae1a53":"sendTransaction(bytes32,uint256,int256)","c2ae7e14":"approvePaillier(address,string)","c2aeb355":"GRAMATON()","c2b06664":"setDS(address)","c2b0c743":"payETHToProvider(address,address,uint256)","c2b12a73":"setBytes32(bytes32)","c2b2fb5e":"editionExists(uint256)","c2b373a7":"seedHash()","c2b4470c":"FINLAB_PRESALE()","c2b477a7":"mintLimitByTemplate(uint256)","c2b4ab4d":"getCountBonus(uint256)","c2b4ddde":"setFundingEnabled(bool)","c2b6b58c":"isClosed()","c2b70850":"QuantiModoToken()","c2b7be16":"addSupportedToken(address,address)","c2b8fd12":"MYRN()","c2b98295":"balanceOfNonKYC(address)","c2ba4744":"canMint(address)","c2ba5b40":"getPackageData(string)","c2ba857e":"setJobAccepted()","c2baa882":"tokensPerCHF()","c2bc2efc":"get(address)","c2bdb862":"verifyProofOfTransitionAgreement(address,uint64,uint256,bytes32,uint256[2],bool,bytes32,bytes32,uint8)","c2bf17b0":"recover(bytes32,uint8,bytes32,bytes32)","c2bf1af7":"freezingStatus()","c2c06f20":"OldRopeToken()","c2c13a70":"LOCKUP_WALLET()","c2c3bd6a":"_v()","c2c4a328":"getInitPrice(bytes32,uint8)","c2c4abe6":"ASSPToken()","c2c4c5c1":"checkpoint()","c2c5143f":"bobMakesEthDeposit(bytes32,address,bytes20)","c2c52055":"ChampionGameStarted(uint256,uint256)","c2c546b8":"sumICOStage6USD()","c2c5b9f1":"setInt(string,int256)","c2c5ec41":"isValidProof(bytes32,string)","c2c5f89f":"BonusAwareCalculator(address,address)","c2c61d01":"agreeToTrade(address)","c2c62562":"setCrowdsaleData(uint256,uint256,uint256)","c2c68ee1":"unlockTrading()","c2c7ca1d":"extraTokensMintedDuringPresale()","c2c7ff0a":"ToperCoin()","c2c8fd40":"increaseWorldLimit(uint256,uint256,uint256)","c2ca058d":"clearBlacklistMapping()","c2cb88bd":"giftMessage()","c2cb9927":"reward(address,uint256,uint256,string)","c2cba306":"TokenAddress()","c2cbb299":"airdrop_auto(address,address)","c2cca62c":"TransferMinersReward()","c2ccb8a8":"isCurrentAccountMinter(address)","c2cd0e01":"issueNewCoins(address,uint256,string)","c2cd7632":"isEmployee(address,address)","c2cdaf24":"start1BonusPeriod1()","c2cdbf01":"SyloToken()","c2cf7326":"hasConfirmed(bytes32,address)","c2cf9bbb":"PotPotato()","c2d0916f":"moveMetadata(address,address)","c2d15d21":"totalIssuanceLastAverageBalance()","c2d23e41":"continuousBacking()","c2d25167":"closeIcoOne()","c2d37428":"withdrawForWinner(uint256)","c2d415e2":"Chicken()","c2d42ef2":"removeAccount(uint256)","c2d4423f":"excludeWhale(address)","c2d4489f":"provider2()","c2d4f851":"calculatePrice(uint256,address)","c2d526aa":"_rank(uint256)","c2d53eb4":"initOwner()","c2d560ab":"stopOraclize()","c2d5baf9":"JJL()","c2d83718":"randomTeam()","c2d83e61":"UserPool(address,address)","c2d86376":"NewDonor(address,uint256,uint256)","c2d8de54":"promisor()","c2d936d9":"MINATOKU()","c2d9c196":"preico_startdate()","c2da621b":"setMeterPoint(address,int256)","c2dab162":"mineit(address,uint256)","c2db0482":"getUnionIdByAddress(address,address)","c2db26fc":"unverifyAccount(address)","c2db2c42":"purchaseToken(uint256)","c2db5890":"breedAxies(uint256,uint256,uint256)","c2db8676":"BloodToken()","c2db9e25":"getMinerHalvingHashRate()","c2dc0470":"KilledTillNow()","c2dc9af4":"hardCapHash()","c2dcdfb4":"preferredSaleTokensLeftForSale()","c2dced85":"numberDecimal18()","c2de2909":"drawRandomWinner()","c2de89b7":"getCleide()","c2def3b9":"getOrganizer()","c2df8815":"Adnity()","c2e0af44":"doMove(address,address,uint256)","c2e12f21":"setDefaultTranches(bytes32[])","c2e171d7":"Save()","c2e28dd1":"setTitulaire_Compte_8(uint256)","c2e2a338":"withdrawRejected()","c2e2a33e":"setPermanentLimitForType(uint32,uint256)","c2e3460d":"Anxxia()","c2e4601a":"getAffiliateRate(uint256)","c2e46379":"transferBountyTokens(address[],uint256[])","c2e4b8fb":"TokensUpgradedFrom(address,uint256)","c2e52206":"getPlayerCount()","c2e55da3":"product3_pot()","c2e5d950":"finalizedRefund()","c2e5ec04":"setTradingEnabled(bool)","c2e5feb5":"KeyReplaced(address,address)","c2e62675":"COTToken()","c2e78f12":"deVerify(address)","c2e800ed":"isContractProxy(address)","c2e88185":"CyberMusicToken()","c2e9fab3":"SubUser()","c2ea2f9c":"halfCentury(address)","c2ea5c9e":"getInvArray()","c2eaaeb3":"computeTxFee(uint256)","c2eac875":"secure(uint256,string)","c2eb10a2":"makeBundle(uint256)","c2ecdf8e":"ownerCMIT()","c2ed2b05":"documents(uint256)","c2eddfd2":"kyberMultiSigWallet()","c2edec0b":"setCharityDonation(uint256)","c2ee0a57":"getBlockList()","c2ee3a08":"ONE()","c2eef08e":"stopLandEthSale()","c2f02b33":"Crowdsale7(address,uint256,uint256,uint256,address,address)","c2f0bb29":"getCardDetails(uint16,uint8,uint256)","c2f0c083":"angelOnLeaderboard(uint64)","c2f0d93f":"icoAbandoned()","c2f0dbe2":"claimPremium(address[2],uint256[7],uint8,bytes32[2])","c2f137f1":"swapAddr()","c2f3ce10":"ADDRESS_LIMIT()","c2f3d788":"read_total_number_of_purchases()","c2f415b5":"CTBoatGame(address,address,uint256)","c2f490e9":"caller_()","c2f4976f":"setRoundFinalScore(uint16,bytes32)","c2f4faf4":"TestOrder(address)","c2f61a9f":"setOraclizeQueryType(string)","c2f666a3":"PriceIncrease()","c2f7c50a":"FindID(address)","c2fa6697":"fundraiserCallData()","c2fa8b2d":"PoetToken()","c2faa691":"Constructor(uint256,string,string)","c2fb538e":"updateFactoryContract(address)","c2fb8f36":"TinyHuman(address,address,address)","c2fbe7bc":"transferFees()","c2fc048a":"transferOwnerToProxy()","c2fcbf37":"isValidateParameter(string,uint256)","c2fce718":"getPartsOfOwnerWithinRange(address,uint256,uint256)","c2fd0263":"isTripleNumber(uint256)","c2fe2022":"getFollowers(address)","c2fe3321":"PRE_ICO_ON()","c2febe49":"QuantorToken()","c2febef5":"removeCountry(uint256)","c2ff0f15":"NewShare(string,bool,string)","c2ff3334":"jump(uint256)","c2ff7a38":"adjustBalanceCheckpoints(address)","c2ffc7bb":"slates(bytes32,uint256)","c2fffd6b":"setCancelFee(uint256)","c30096ef":"calculationTeamsRewards(uint256[])","c3017200":"removeAssociatedAddress(uint256,address,address)","c3027525":"getOwned()","c302a45b":"crowdsaleStopped()","c302f747":"poolPresale()","c30354cb":"VUP_TOKEN_SUPPLY_TIER3()","c30381b9":"setSellCourse(uint256)","c303c3d5":"returnEtherToInvestors()","c303c53a":"withdrawForTwoStep()","c304b368":"updatedRandom(string)","c304ffc4":"CreateICE(address,uint256)","c3059c63":"buyUpgradeCard(uint256)","c306834e":"PRIVATE_SALE_LIMIT()","c306cb90":"sendDevTokens()","c30715d1":"setNumRewardsUsedForAddress(uint256,address,address)","c30718e8":"testIntParser()","c3077c10":"settxpct(uint256)","c307f6ba":"withdrawWbtToken(address,uint256)","c3082e95":"playerOutputAtNow(address)","c308f55b":"fallback(uint256,address,uint256)","c30a990a":"createPaymentChannel(address,uint256,uint256)","c30b06e8":"allMultitokens()","c30b182e":"sendVNET(address,uint256)","c30b8867":"maxPercentPerPlayer()","c30bc5ef":"breedWith(uint40,uint40)","c30bf4d8":"CodeEligible()","c30c0c0c":"checkUsers(address,address)","c30d0ee4":"phiRate()","c30dafd8":"_setTittyForSale(bool,uint256)","c30df14c":"logPurchase(address,uint256)","c30df586":"ZAI()","c30ed0a4":"Getwsic(uint256)","c30f4a5a":"updateURI(string)","c31028dc":"hasFirstUnionIds(bytes32,bytes32)","c31051fe":"teamPeriodLength()","c31053f7":"NNT()","c310b9df":"ProposalAdded(uint256,uint256,string,bytes32)","c311d049":"withdrawEth(uint256)","c312d468":"sendPToken(address,uint256)","c312ffed":"Contributed(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","c31422ac":"calculateTokens(address,uint256)","c3143fe5":"setUserCap(address,uint256)","c31453a7":"_unpackAttackParams(uint256)","c3146814":"pegETHUSD(uint256)","c3153834":"prefixedRecover(uint8,bytes32,bytes32,address)","c315432a":"isGameStarted()","c3155201":"XulCrowdsale(uint256,uint256,uint256,address)","c31592af":"getY(bytes)","c315a082":"KRT()","c3169ef2":"respond(uint256,uint256[4])","c316c98b":"updateCollector(address)","c3173774":"balanceThreshold()","c317464d":"CryptoHearthStone()","c31752c0":"getEmployerJobs(address,uint8)","c3182360":"getTimeBonus(uint256)","c3191f31":"readWelfareAddress(uint256)","c3192c82":"getcurrNumOfUpgrades()","c319618f":"getAllMyPackageIds()","c31989ed":"TronGold()","c319a02c":"right98(uint256)","c319e412":"allowContribution()","c31a0972":"OrpheusRoyalSiamRailways()","c31ad7dc":"voteYes(string)","c31b29ce":"GAME_DURATION()","c31bb2fb":"XEPToken()","c31bb8d6":"percentToTakeAsRake()","c31c0b62":"isSaleComplete()","c31c5221":"approveSetTokenControlInfo()","c31c6855":"presaleBonusTokensClaimed()","c31ce93e":"getExchangeGroups()","c31ceb2a":"numberOfAttendees()","c31d0031":"CrowdFundDAO(string,uint8,string)","c31d309a":"addRequestorAddress(address)","c31d3a6d":"payInvestors()","c31d3e8e":"maxPublicSale()","c31e0547":"quickConverter()","c31e6ee0":"sendTokensToService(address)","c31f3537":"removeBotAddress(address)","c31f586d":"cancelSaleAuction(uint256)","c31fa083":"setIpfs(string)","c32011f0":"unfreezeTeamRecepientBlock()","c3204954":"confirmTransactionByMediatorFee(uint256)","c320c727":"setRegistrationFee(uint256)","c3210eb7":"proposeCount()","c3218f50":"startPreICO(address)","c321dc18":"showParticipantWei(address)","c32221cf":"_newRepo(string,address)","c32377df":"recevoirApprobation(address,uint256,address)","c3237ff4":"emitFeePeriodClosed(uint256)","c32426c9":"ProvideToken()","c324606a":"confirmStakeholderTransaction(uint256)","c324a669":"purchaseSoldiers(uint256,uint256)","c325ae4e":"belongsToUser(address)","c3262dfd":"setUserID(bytes32)","c3283d83":"getStrandContract(uint256)","c32863a7":"every15()","c32935d7":"getBuyPriceTimesByTime(uint256)","c329e4a5":"BoardAddressChanged(address,address,address)","c32a4369":"getAllSamplesForOwner(address)","c32a4c7e":"returnCoke(uint256)","c32a50f9":"setSeed(uint256)","c32a6f6d":"toUint(string)","c32a88ae":"recoveryPaymentDigest(bytes32,uint256)","c32a8edf":"someMethod1(uint256,uint256,uint256,uint256)","c32a9b00":"do_grant_tokens(address,uint256)","c32aaa86":"getNameWriterId(bytes32)","c32b8683":"creatorRequestFundTransfer(uint256,address,uint256)","c32c1e65":"setOperations(address)","c32cc6d5":"investFor12Months(address,uint256,uint256)","c32ceb14":"setQueryIdForAddress(bytes32,address)","c32d88bb":"changeDepositAmount(uint256)","c32d946d":"performTransfer(address,address,uint256,bytes)","c32dee3a":"second_bonus_amount()","c32e16e7":"REQUEST_CANCELED_BY_LENDER_STATUS()","c32e2b42":"SalesAgentRemoved(address)","c32ee591":"isTransferAllowed(address,address,address,address,uint256)","c32f6945":"MiningLevelup(address,uint256,uint256)","c32fb5ea":"getNewAllowancePeriod()","c32ff491":"ServerManager()","c3310517":"reservedTokensDestinationsLen()","c3315b4b":"EasyInvest25()","c3328816":"TeamAdvisorsWallet()","c3332621":"shippingDate()","c3332732":"setNextGame(uint256,uint256,uint256,uint256)","c3336c0f":"transferMultipleSame(address[],uint256)","c3340892":"LogStateChange(uint8)","c334447b":"bytes32ToTokenId(bytes32)","c334e875":"payByErc20(uint256)","c334ea8f":"setMateAdvertisementRate(uint256)","c3354632":"_premoveByIndex(uint256)","c335f0a4":"RKGToken()","c336937d":"Revoked(address,address)","c3369b0d":"issueTokens(uint256,uint256,uint256)","c336e7fb":"NobelToken()","c3380b72":"getDefense(bytes32,bytes32,uint256)","c33818fd":"Controller_Address2()","c338287f":"getUSDPrice()","c33890ff":"StartNewIteration()","c3392f25":"PRCT100_R_TEAM()","c33a4cc8":"PresaleUpdated(uint256,uint256)","c33a5bb6":"RLCPerETH()","c33a66e0":"updatePriceEDEX(uint256)","c33a800b":"createHeldCoins()","c33aa7fe":"submitBid(string)","c33af352":"_getFunc(uint256,uint256,uint256,uint256)","c33b76c6":"rakeAddress()","c33bbe47":"LAM()","c33cfe36":"KolkhaToken(uint256)","c33db789":"_triggerFinishTournament()","c33df4ba":"getNumOfRickHolders()","c33e1844":"BTMC()","c33e40a3":"setBasePoints(uint256)","c33e4942":"definition(bytes32)","c33fb877":"process()","c3403ddf":"endVoting()","c34052e0":"contains(uint256)","c341031a":"Testereum()","c341b9f6":"freezeAccounts(address[],bool)","c3430bce":"validWhiteListedPurchase(address)","c3434883":"buy(uint256,uint256,bool)","c3437e06":"approvedBuyer(address)","c3440022":"WhitelistedAddress()","c34492a7":"buyTokensByOptions(address,uint256,string)","c344bc47":"HonestisNetworkTokenWire3()","c344bc4a":"REALCrowdsale()","c344cdd2":"offerOptionsConversion(address)","c34588ba":"countOfDeeds()","c3458d18":"callRecipient(address,address,address,uint256,bytes,bytes,bool)","c345b571":"_subDai(uint256,address)","c345c54b":"doSafeSend(address,uint256)","c3462818":"PFC(address)","c34764cf":"makerWithdrawERC20Token(address,uint256)","c347fe1f":"addCET4(uint32,uint32,uint32)","c3492908":"BASE_TIME_TO_COOK()","c34a253a":"cardFacevalue(uint8)","c34b6ae0":"setFreeTransferAllowed(bool)","c34ba3e9":"createPromise(address,uint256,uint256)","c34c08e5":"executor()","c34c27ad":"SendOwner()","c34c4417":"registerData(bytes)","c34c6b93":"getDateInfo(uint256)","c34d2732":"MAX_COMMIT_DURATION_IN_SECONDS()","c34da17c":"isBurned()","c34db131":"CSCPreSaleManager()","c34dd141":"percent_reduction()","c34de22d":"genKeysRec(uint256,uint256)","c34debc7":"updatePlayerWin(address,uint256)","c34e6e1b":"OnlyWhiteListedAddresses(address)","c34ef9af":"second_bonus_duration()","c34f1fea":"UnfreezeAmount(address,uint256,uint256)","c34f6b0d":"getPrize()","c34f783d":"allocateToken(address[],uint256[],uint256[])","c34f869b":"Voted(uint256,bool,address,string)","c34fb5ca":"canonizedParameterizer()","c3500745":"refundLockDate()","c3501ff6":"redeemToken(uint256,address)","c3502510":"UsdPerEthChanged(uint256,uint256)","c3508d58":"refundByOwner(address)","c350bbb6":"RoscaERC20(uint256,string,string)","c3513132":"accessTokenFee(uint256)","c351fd77":"setGasPricePctOfBetValue(uint256)","c351fdfd":"setBatchNumber(address[],uint256[])","c3521b1a":"wolkFund()","c352dae2":"getWalletInfo()","c352fbda":"grantMarketingCoins(address,uint256)","c353a89e":"changeMember(address,address)","c353c2de":"unPauseTokenSale()","c353dbb1":"EtherPluscoin()","c3542cad":"SaleStageUp(int256,uint256)","c3548647":"setActivationFee(uint256)","c35506c0":"upgradingEnabled()","c355b107":"cNiceGuy()","c355eaf0":"setEthlanceSponsorWalletContract(address)","c35740f9":"partner2_name()","c3576b41":"setOwnersCommission(uint256)","c35774a1":"setApproval(address,uint256[],bool)","c35789cc":"Close()","c3584d88":"getMaxEtherToInvest()","c358ced0":"isRevealPhase()","c359a2a4":"increaseContribution(address,uint256)","c35a4d46":"DubaiGreenBlockChain()","c35c08bd":"getCrowdsourcer(bytes32)","c35c3265":"novumAddress()","c35cabf4":"littClientId()","c35d1e01":"RESERVE_TOKENS()","c35dcf90":"getWhitelists()","c35e1b33":"MSERToken(uint256,string,string)","c35ef892":"getWriteTimestamp(bytes32)","c35f4bbb":"calculatePrimordialMultiplier(uint256,uint256,uint256,uint256,uint256)","c3602ee5":"delayedRequest(string,uint256)","c36086f0":"initTransaction(address,uint256)","c360c616":"TittyPurchase(address,address)","c3615e39":"set_address(address,address)","c36360f2":"limit8()","c36433e2":"createPromoDrug(bytes32,address,uint256,uint256)","c3645759":"increaseDistrictWeed(uint256,uint256)","c364a25d":"setHash(uint16,bytes32)","c3650a21":"danserviceTeamAddress()","c36572d6":"hasEnded(uint256)","c3657f96":"setBoxCount(uint16,uint16)","c365a646":"_setRiskParameters(uint256,uint256)","c365d4f0":"initWidth()","c36604ed":"secretNumber()","c3662528":"isApproved(bytes32,uint256,bytes)","c3663271":"Icoends()","c366b1d3":"BulkToken()","c3676a02":"mangeWhileList(address,bool)","c367ec17":"rewardAuditor(uint256,address,uint256)","c36800eb":"IdentityCreated(address,address,address,address)","c368109c":"monster_hp(uint256)","c3681e3d":"change_p3(uint256)","c3682ace":"time_end_sale()","c36851bc":"bidOnWonder()","c3685e89":"addMessage(address,string,string)","c3689f01":"testControlSetNotRetractableNotOwner()","c368b160":"disbursement()","c36981f4":"withdrawNacNetfReController(uint256,address)","c369c0c6":"addValidationPreSigned(address,bytes32,uint8,bytes32,bytes32,bytes32)","c36a7b45":"getUserTotalEthVolumeSaldo(address)","c36ad8a6":"deleteStar(uint256)","c36af460":"getLatest()","c36c0155":"get_planet_info(uint256)","c36c09e2":"setTrustedSender(address)","c36ccedc":"approve(address[16],address,uint256)","c36de353":"Ethereumt()","c36de531":"smallestUnitName()","c36e6fe5":"XclusiveCoin()","c36e9546":"SVL()","c36ff164":"claimFoundationToken()","c36fff2d":"availableOptions(uint256)","c37067fa":"donate(bytes32)","c370b0b5":"BbeCoin()","c370c86d":"setTokenName(address,string)","c370d8fe":"ExpandandHarvest(uint256)","c3720290":"giveSignOff()","c37210f4":"getDocumentSign(uint256,uint256)","c3722b1f":"AutoSell()","c3736dfa":"_shiftRight(bytes32,uint256)","c3737054":"changeManagerQuorum()","c373c0ef":"setStartDate(uint32)","c3751729":"mGenerateTokens(address,uint256)","c375ba8a":"getLavaPacketTypehash()","c375c2ef":"removeContract(address)","c3762904":"ethraised()","c37792b5":"generateSecurityToken(string,string,string,bool)","c3787865":"balanceFromToken(uint256)","c378a83b":"EarthToken()","c378ea76":"getFrom(uint256)","c378f1af":"RemoveAll()","c37981b3":"maxFixedSupply()","c37991e3":"ProposalEnd(uint256,string)","c37a676c":"acceptMins(uint256)","c37a6e8d":"signer1_proposal()","c37a832d":"getRoundUserBalance(uint256,address)","c37b0aa7":"modifyPriceCountry(uint256,uint256)","c37bcb1e":"unlockDate1()","c37cb1ae":"airdropsTokens(address[],uint256[])","c37cdcfe":"doDisputeMemoryRead(uint256,bytes32,uint256)","c37d1c8b":"tokensToMint(uint256)","c37d8a7e":"indexReplies()","c37d9044":"create(uint8)","c37db253":"isNotZero(bytes32,string)","c37dfc5b":"fillOrder(uint256,uint256)","c37e7379":"distributePresale(address)","c37e74c7":"getRet()","c37e8cb2":"testExportAuthorized()","c37f7f7f":"doTransferIn(address,address,uint256)","c37ff3d9":"sha(uint256,uint256)","c3800257":"Addmember(string,address,address,uint256,bool,uint256,bool)","c3800fdc":"CurrentToken(address)","c3801938":"getStateRoot(uint256)","c3830618":"reduceStake(uint256)","c3834d89":"setPromo(address,uint256,uint256)","c383b1bb":"summon10SkinAppearance(uint256,uint128)","c383e020":"endContract(address)","c384521f":"tokenCapPhaseTwo()","c384b170":"teamWallet2()","c3858e82":"unregisttIcoAddress(address)","c38672a0":"confirmTokenTransaction(uint256)","c38678c3":"addBuildingToServer(uint256,uint8[10],uint8[10],uint8[10],bytes32[10],uint8)","c386ff7d":"checkFunction(bytes32,uint256)","c38789ba":"example(uint256,address)","c387b2a7":"BatchTransferContract(address)","c3886f61":"checkWithdrawal(address,address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","c3888bce":"transferTokenToMultiple(address[],uint256)","c388c167":"setNameAndTicker(string,string)","c388cca6":"testBitAndFailIndexOOB()","c38a0306":"devFeeHandle(uint256)","c38a0fcb":"MGLTOKEN()","c38a8afd":"minimumBet()","c38ad273":"priceETH()","c38ad65b":"getHeroPostAddres()","c38bb537":"setPauseStatus(bool)","c38c0fa7":"getParentPayoutDistributionHash()","c38c5813":"registerAdmin(address)","c38c9800":"innerContract(string)","c38caab5":"setPost(string)","c38e52c0":"deletePeerReview(address)","c38e650f":"changeRoundManager(address)","c38f0741":"snapshotDailyGooResearchFunding()","c38f1abf":"waitTokensPeriod()","c391c1b5":"updateOwner(address,address,uint256)","c391d581":"getXPROMO_MULTIPLIER()","c392079f":"removeCoin(string)","c392cf41":"reveal(address)","c392f118":"getSellingStatus(uint256)","c392f5a0":"getAllPackageReleaseHashes(string)","c39387ad":"checkAndUpdateStage()","c3946909":"setTheKingsQuote(string)","c394f6cb":"unclaimedTokens()","c39513af":"setDeprecated(string,address)","c395546c":"authorizedToSpend()","c395a16b":"leaderBid()","c395f336":"processPurchase(uint256,uint256)","c3964372":"startRound(uint256,uint256)","c397ae1b":"holosForWei(uint256)","c39804ac":"generatePreimage(uint256,uint256,uint8)","c39899c1":"isDeadline(uint256)","c398a925":"supportsERC165(address)","c398f030":"expire(uint256,uint8,bytes,bytes,bytes)","c399330d":"getBonusByTime()","c399d7c5":"getAccountTokenStats(address)","c399ec88":"getDeposit()","c39a9d97":"crowdSaleType()","c39afb0b":"BitcoinEther()","c39b79d4":"_contains_(address)","c39cb03f":"ERC827Token(uint256,string,string)","c39cbef1":"changeName(uint256,string)","c39ce8b6":"FranklinFrank()","c39cf53d":"nextrafflenumber()","c39e7394":"addAuctionReward()","c39ffc65":"GVFX()","c3a07df6":"getPermissions()","c3a0ba73":"BlockFilesManagement()","c3a11c51":"etherPriceInUsd()","c3a151de":"getPlayedGamePlayers()","c3a18dec":"PRIVATE_SUPPLY_ADDRESS()","c3a1e7cc":"totalWEIInvested()","c3a25c4c":"computeCntrAmountUsingPacked(uint256,uint16)","c3a267b7":"createEthGlobalDelegation(address,address)","c3a2a665":"retrieve(address,uint256)","c3a2a93a":"getContracts()","c3a2c0c3":"scheduleCall()","c3a35825":"getUint(bytes32,string)","c3a39544":"initialCompanysTokenAllocation()","c3a3ee80":"setPartsToSell(uint256,uint256)","c3a48741":"distributeTKLN(address[],uint256)","c3a4ebf5":"_roundOver()","c3a4f8b5":"hibit(uint256)","c3a5fc4d":"IconFoundation()","c3a62a68":"getDate(bytes10)","c3a69a75":"dividendsDistributor()","c3a6e2a7":"disableToken(bool)","c3a74e6a":"placeSellFciOrder(uint256)","c3a83aab":"getTokensAvailableToMe(address)","c3a869e6":"goldenTicketPrice(uint256)","c3a8da5f":"EthereumMark()","c3a8f536":"rsub(uint128,uint128)","c3a9b1c5":"sayHello(string)","c3a9bd8b":"maximumTokens()","c3a9be6b":"setLimitGame(uint256,string)","c3a9c930":"Gift(uint256,address,address)","c3aa0fe6":"setItemLimitHolding(uint256,uint256)","c3abe888":"sendBatch(address[])","c3ac93df":"QCOToken(address,address,address,address,address,address)","c3ad5ecb":"getTweet(uint256)","c3ae43a0":"buy100tickets()","c3aeacdf":"changeRules(address)","c3aebdd1":"s5(bytes1)","c3aedd92":"updateIsVerifiedInBulk(address[],bool[])","c3af38fa":"changeInfoUrl(uint256,string)","c3af702e":"totalfv()","c3b0f915":"KickToken()","c3b1037b":"ownerSetGasPrice(uint256)","c3b18fb6":"updateSplit(uint256,uint256)","c3b18ff2":"totalSupplyICO()","c3b1d52b":"recipientToGiftIds(address,uint256)","c3b1ff93":"acceptGame(address,uint256,bytes32)","c3b24be0":"Leg()","c3b2556d":"lookup(bytes)","c3b2d337":"_initialSupply()","c3b3271d":"updateStar(uint256,string,string)","c3b35a7e":"withdrawTo(address,address,uint256)","c3b3c656":"kickOutGroup(address,uint256)","c3b4db25":"setSeller(uint256)","c3b55635":"log(string,bool)","c3b57af8":"getStageAmount(uint256,address,address)","c3b66bed":"getProposalVotersCount(uint256)","c3b6f939":"mToken()","c3b7572c":"updateCommission(string,uint8,uint8)","c3b75b8f":"setLockProductActiveState(uint32,bool)","c3b7e378":"startTimeStage2()","c3b8bfe5":"transferIfNoHF(address)","c3b91d15":"AiBank()","c3b9741b":"ModifiedCrowdsale(uint256,uint256,uint256,address)","c3b9e2ed":"powerWithModulus(uint256,uint256,uint256)","c3b9f21e":"p4()","c3ba2368":"transferERC721(address,string)","c3ba65e7":"totalChicken()","c3ba7574":"mintForFund(address)","c3ba938d":"JPY_Omnidollar()","c3bb68cf":"weisPerEther()","c3bb8feb":"releaseSell(uint256)","c3bcb586":"soldKeys()","c3bd0bae":"CapLevelPrice()","c3bdc16f":"setUserRole(address,bytes32,address,uint8)","c3be259f":"ConnectiusToken(uint256)","c3be3c24":"_updateTopUpAvailable()","c3be6e8d":"SetStartTimeTLP1(uint256)","c3be8df3":"addAff(uint256,bytes32)","c3bea9af":"createGen0Auction(uint256)","c3bf32e3":"numberOfHeroClasses()","c3bf504a":"extractEth(uint256)","c3c0198c":"getAssesByOwner(address)","c3c0befb":"dumpPrize()","c3c132b2":"_indexProofId(string)","c3c1d4c7":"withdrawTokensTo(address)","c3c2686c":"preSaleWallets(uint256)","c3c2f066":"block(bytes32)","c3c357f9":"tokenSaleCompleted()","c3c5026c":"depositWEI()","c3c503b7":"becomeBankermaster()","c3c51aca":"cancelSellTokenOrder(uint64)","c3c563f4":"validateAmount(uint256)","c3c59aa9":"walletTimeOf(address)","c3c5a547":"isRegistered(address)","c3c5b40e":"setSaleAddr(address)","c3c63edc":"mintBadge(uint256)","c3c6e202":"indexLastThreads()","c3c6f0c9":"getCustomerTxTimestampPaymentKWh(address,bytes32)","c3c735cb":"BITDRIVE()","c3c74c45":"applyForCertification(string,string,address,string,string,uint256)","c3c75e5c":"setEditionPackSize(uint8,uint8)","c3c88a1d":"disableTransfer(uint256)","c3c8c12b":"setVipInfo(address,uint256)","c3c90e64":"checkReward(address)","c3c95c7b":"getMarket(bytes32)","c3ca3c6a":"SingularityTest3()","c3cad5e7":"senderMIT(address)","c3cb4159":"getICOBonus()","c3cb50ed":"setTileType(uint16,bytes32)","c3cb8c14":"finalizeVault()","c3cbc2c9":"offerSacrifice()","c3cbd341":"create(address,uint256,address,address)","c3cd9996":"CLASS_AQUATIC()","c3ceb939":"view58()","c3cfe00f":"EEB(uint256,string,uint8,string)","c3d014d6":"setContent(bytes32,bytes32)","c3d08f06":"setPermissionByAddress(uint8,address)","c3d0a20a":"NewToken(address,string,string)","c3d0a564":"getAccountBalance(bytes)","c3d23e10":"checkBet()","c3d2c355":"setKey(bytes32)","c3d32e56":"PixelCore()","c3d345c4":"getHangoutAddress()","c3d38586":"newCookie()","c3d4d75a":"getCommitHash(bytes32,address)","c3d54c9a":"paiementConfirmation(bytes32,bytes32)","c3d55adc":"calculateBuyGoldFee(uint256,uint256)","c3d58d95":"runICO()","c3d59369":"setIcoDiscountPercentages(uint8,uint8,uint8,uint8)","c3d5fd39":"getAdminInfo()","c3d68a85":"temporaryKill(address)","c3d69d03":"NatureX()","c3d7ad74":"sendPurchasedTokens(address,uint256)","c3d7e350":"removeAccount(uint256,address)","c3d8c099":"endICOStage5()","c3d97a27":"carsCount()","c3d9820d":"RefillOraclize()","c3d9c4b4":"share(uint256)","c3da42b8":"c()","c3da5153":"getEthartArtReward()","c3daab96":"withdrawBond(uint256)","c3dac9a1":"time_bought()","c3db397f":"unstakePartialContent(bytes32,uint256,uint256,bytes8,uint256)","c3db5ead":"Uruntest()","c3dc0083":"finishDeal(uint256,uint256)","c3dc1040":"orderInternal(uint256,bytes32)","c3dd2395":"maxCapEur()","c3de1ab9":"gamePaused()","c3de7cbf":"checkRedemptionWindow(uint256,uint256)","c3dee67f":"updateAllHoldersShareInfo()","c3defb70":"changePause()","c3df99b6":"upvoteComment(bytes32,bytes32,bytes32)","c3dfb938":"countFortunes()","c3dfbeea":"migratePresaleBalances(address,address,address[])","c3dfdae6":"gameToken()","c3e017c2":"dNextStage(uint32)","c3e053ac":"percentBuyBackTypeTwo()","c3e06be9":"changeReceiveWallet(address)","c3e0ae67":"future_round_percentage()","c3e0bbad":"getContentByName(string)","c3e1d25c":"percentsOfProjectComplete()","c3e2087c":"setManagementCompany(string)","c3e27948":"setTrueUsdFastPause(address)","c3e2f26e":"icoedAmount()","c3e38ae9":"setSEKU(uint256)","c3e3908c":"get_pre_kyc_bonus_numerator(address)","c3e3c7bc":"teamTokens()","c3e50027":"dealConfirm(uint256)","c3e58eec":"blackListSectorExists(uint8[])","c3e6ea31":"BONUS1()","c3e8fb40":"smartToken()","c3e92f9e":"DrawLottery(string,uint256)","c3e93fa3":"depositHelpe(uint256)","c3ea0fca":"promoEthCommission()","c3ea901d":"uint2ToStr(uint256[2])","c3eb0723":"LogNewSecurityToken(string,address,address,address,uint256,uint8)","c3edb4c2":"finalizeChangeInsuranceFees()","c3ee6311":"lockAndCall(string)","c3ef473c":"ShareHolderVoted(address,uint256,bool)","c3ef586a":"Gambit()","c3ef83fc":"executionTimeOf(uint256)","c3f010f7":"numGames()","c3f03fb8":"querySpecialRateForAddress(address,address)","c3f07ba7":"addTokenAddresses(address[])","c3f0dad9":"isGenerator()","c3f17ae8":"getAmountToIssue(uint256)","c3f1a710":"getInvestment()","c3f1b0ea":"changeRequest(bytes32,bytes32,bytes32,string,bytes32,bytes32,uint256)","c3f3310b":"tokensOfFounder(address)","c3f34a50":"Dao(address,uint256,uint256,uint256,uint256,uint256,uint256)","c3f3b854":"maxNumBets()","c3f44c0a":"relayMetaTx(uint8,bytes32,bytes32,address,bytes,address)","c3f51fca":"initMintable(address,address,uint256,uint256)","c3f53e94":"ownerClaimTokensAndRefundForUser(address)","c3f59687":"transferMastership(address)","c3f6263f":"charityCutOf(uint256)","c3f67cde":"withdrawSecond()","c3f6e09c":"sendOnlyHash(string)","c3f7ec97":"addLog(bytes)","c3f7f169":"safeSend(uint256)","c3f843d7":"minVeriAmount()","c3f84c05":"retribution(uint256,address)","c3f90202":"f4()","c3f909d4":"getConfig()","c3f9409f":"signBitcoin(bytes32,uint8,bytes32,bytes32)","c3fa4f27":"sendPowerToken()","c3fa5f93":"BlockScheduler(address,address)","c3fb31a4":"coolDungeon()","c3fb5e5f":"createVestFundFor(address,uint256,uint256,uint256)","c3fbc632":"ICORunning()","c3fc4787":"finalizeFork()","c3fdbef8":"totalInSharedPool()","c3fe3e28":"game()","c3ff05d1":"getBoxCountZIndex(uint8)","c3ff3878":"checkForValidChallenge(address,uint256)","c401a2a3":"destroyforproduction(uint256)","c401d6b0":"totalTokensToSupply()","c4021c13":"topupEnergyByToken(address,uint256,uint256)","c4026d7b":"removeDev(address)","c402e446":"Express_Satisfaction_MediatedTransaction(uint256)","c403adc8":"changeInSale(bytes32,bytes32,uint256)","c403cf6d":"RESERVED_TOTAL_AMOUNT()","c403f90f":"airdropTime()","c4041bc5":"viewauction(uint256)","c4043465":"MYEXCTOKEN()","c404b3f6":"currentTranche()","c4052559":"haraKiri()","c4052a78":"airLiftPrice()","c4057e61":"getData_4()","c40580de":"removeOwners2()","c405b1f0":"addJob(address,uint256,uint256)","c405d30e":"send2marketing(address,address)","c405e11b":"_addAnswerToHistory(bytes32,bytes32,address,uint256,bool)","c4069caf":"getPlayersByTrackId(uint256)","c406d4af":"getPixelToken(uint24)","c407670f":"donorCount()","c4076876":"pay(address,uint256)","c407c6d8":"chop(string)","c4085bf6":"_sell(address,uint256,bytes)","c4086893":"getLockedBalance(address)","c408efba":"isMigrationPhaseOpen()","c40940f4":"pricePerUnicorn()","c409ad08":"exec(bytes,bytes,address[])","c40af29f":"tokenTeamSupporter()","c40b276b":"hasString(string[],string)","c40b4c4d":"minSumPreICOUSD()","c40b716c":"setLLV_edit_14(string)","c40b8868":"changePresale(address,uint256[])","c40b8dcf":"usdToHavPrice()","c40bdc05":"_requestLoans(address,uint256)","c40cf4eb":"memberContract()","c40d19a5":"getAddressSize()","c40d4163":"ArthToken(uint256)","c40d62fe":"OrpheusBlockChainCitySiam()","c40dc8ec":"deadline(uint256)","c40fdc94":"Delisted(uint256)","c40fec3a":"forceOffsetExecuteFeeRate()","c4109843":"OrdersMatched(bytes32,bytes32,address,address,uint256,bytes32)","c4109d48":"baseTokensAllocated()","c411e4d4":"canCancel(uint256)","c4128b6d":"upgradeCount()","c4130ae0":"registerEvent()","c413af2e":"setPreICOPhase()","c413fdf3":"testPayout()","c414dede":"tablets(address,uint256)","c41518f2":"luckyYouToken()","c41559bb":"ETHbalanceOf(address)","c415b95c":"feeCollector()","c4163518":"isMining(address)","c4164365":"investBalanceMax()","c4166ea8":"OBGAllocation(address)","c416a0d7":"emergencySetBBFarm(uint8,address)","c41728a7":"sectorOwnerCut()","c4173548":"preSaleRaised()","c417becd":"RCToken()","c4184def":"BCBToken()","c418c8c9":"TradeToken(address,string,string,uint256,uint256)","c418c93e":"addOnStage(address,uint256,uint256)","c4198161":"setParameters(address,uint256)","c41a360a":"getOwner(uint256)","c41a9892":"bet2()","c41a9dfe":"has_joined()","c41addb5":"newModerator()","c41b0ae7":"getNumberOneArg(address,bytes4,address)","c41c19dc":"trackContributions(address,uint256)","c41c33af":"submitChallengeOrder(bytes,uint64,uint64,uint256,uint256,uint256)","c41c3bde":"setBuyingTime(uint256,uint256)","c41c9a61":"transferERC20Tokens(address,address,uint256)","c41e1d4f":"MAX_NUM_NAVITOKENS()","c41efe08":"getBestSale(bytes32)","c41f48a3":"DinosaurFarmer2()","c41f4cc0":"takerStatus(address)","c41f9482":"getDateTime(uint256)","c41fbbb5":"addFounder(address,uint256,uint256)","c420928d":"EncryptoTelToken()","c420f7fe":"getPlayerShipModelById(uint64)","c421249a":"sui()","c4215398":"publicSaleAddress()","c4218d33":"oraclizeBalance()","c421fa8e":"updateCrowdfundState(uint256,address,uint256)","c421fc6b":"currentStageData(uint8)","c422293b":"finishIssuance()","c422d09b":"ConfirmOwner()","c422ed19":"addFreeBet(address,uint256)","c4236cdc":"catchStarters()","c4254c7b":"CoreWallet()","c4259e2e":"changeOwnerInfo(uint256,uint256,string,string,string,string)","c4264738":"refundSafe()","c426b1e5":"showDepositEther(address)","c426c3e2":"getExtendedAttributesForPlayer(uint256)","c426fbb6":"setCrowdsaleStartBlock(uint256)","c4270574":"userRollDice(uint256,address)","c42791ae":"setBountyOwner(address)","c427a68b":"ExtremeSetupToken()","c427af9b":"outcomeAmounts(address,int256)","c427e699":"getContractsOf()","c42882e3":"getEarlyAccessKitsRemaining()","c42890b6":"setCastleContract(address)","c4290b76":"getAmountWithdrawal(address,bytes32)","c42956d3":"nextExchangeRateIndex()","c4298f89":"ACL(address)","c429e4a3":"TEAM_ALLOWANCE()","c42a0716":"erc20(string,string,uint256,uint256)","c42b5fe1":"registerExternal()","c42bb1e4":"contract_eth_value()","c42bd05a":"newToken()","c42c237a":"CortexCoin()","c42c9905":"register(bytes20,uint32,int24[4],int24[4],uint32[4],bytes32[])","c42cb819":"goldBoxAmountForSale()","c42cce7e":"total_tickets()","c42cd8cf":"etherSplit(address,address)","c42cf535":"setGovernor(address)","c42e04c0":"etherOne()","c42e1ace":"TKP()","c42ed894":"getRoundTargetBlock(uint32)","c42edd61":"payFeesToggle()","c42edf88":"leveRage()","c42f61d3":"RhodoToken(address)","c42fd368":"RateChanged(address,uint256,uint256)","c4305a55":"windowBonusMin()","c430bcda":"whitelistInvestor(address)","c43147c1":"InitializeManifesto(string,string,uint256,bool,bool)","c43148ca":"makeProposal(string,uint256,uint256,uint256,uint256,address,address)","c4319bd8":"AgreementHashEn()","c431f885":"addToContribution()","c4321adb":"investInTheSystem(uint256)","c4329ae5":"totalChangedPixels()","c433793d":"removeWhiteListedAddress(address)","c433e8ca":"remainMintTokenAmount()","c4342252":"latestScheduledUpdate()","c434650c":"_checkOrder(address)","c4359c1b":"marketSeeds()","c435ae0c":"setMaxGoal(uint256)","c435d26f":"GREMToken()","c435d2ac":"publishedTokenOfOwnerByIndex(address,uint256)","c435d68e":"numberOfContracts()","c4366149":"optionBalance(bytes32,address)","c4373c05":"tickRequiredLog(uint256,address,uint256)","c43782e0":"ZipToken()","c437b951":"BytechTechnology()","c43821aa":"issuanceCurrentBalanceSum(address)","c43823e1":"jsonKeyExists(string,string)","c4387936":"edgePigmentB()","c439af4f":"WAVEliteToken()","c43a6a79":"returnsTwoNamed(uint256,uint256)","c43aa319":"startTime_()","c43ae983":"GROWTH_BUMP()","c43b7934":"stagePrice(uint256)","c43bb538":"requestOwnershipTransfer(address,bytes32)","c43c633b":"traderBalances(address,address)","c43c9e12":"addTokenAdmin(address,address)","c43d0575":"scheduleCall(bytes4,uint256)","c43d56bb":"changelp4(address)","c43d9ac9":"TCETest()","c43e0e72":"_withdraw(address,address)","c43e9462":"getRoundNumber(uint256,uint256)","c43eb0e0":"getAvatar(bytes32)","c43ed2c8":"update(bytes)","c43f22c4":"isInvestorAllowed(address)","c440008e":"foundersFund()","c4400ed4":"getProfit(uint8,uint256)","c4405fa7":"_getMaxRarityChance()","c44088fd":"rewardUnitsRatePerYear()","c440e875":"dedeNetworkAddress()","c44193c3":"offerPunkForSale(uint256,uint256)","c44237dc":"EventUpgradeShip(address,uint32,uint8)","c4426a88":"arbitrate(address,address,bytes32,bool)","c44299c7":"preAlphaPrice()","c4432f31":"P3DAddress()","c443a99a":"MicoinNetworkToken(uint256,string,string)","c44412e3":"revokeBonusCreditOf(address,uint256)","c4453bd0":"getPlayerMinions(uint32,uint8)","c4454980":"fundManually(address,uint256)","c4457e47":"load(uint8[],uint256,uint256,uint256,bool)","c445e2ef":"RedPillToken()","c4468f69":"setNewPotWinner()","c4477a11":"Banknote(address,uint256)","c4479812":"batchMultipleAmount(address[],uint256[])","c44828be":"totalAllowance(address,address)","c4489110":"BUYOUT_PRICE()","c448fa85":"isExtraDistribution()","c44a2a10":"ownerCredited()","c44b0290":"setLockPostion1(address,uint256,uint8,uint256,uint8,uint256,uint8,uint256,uint8,uint256,uint8)","c44b10d9":"payoutOdds()","c44c2efd":"burnPLUTUSTOKEN(uint256)","c44cb8fc":"viewTotalPayoutToPlayer(address)","c44cd4df":"sendReaction(address,int8,string)","c44ced7e":"ozr()","c44d36ee":"protectedTransfer(address,uint256,bytes32)","c44d6f87":"PAPER()","c44e6640":"getAuctionCount()","c44e787f":"sideBetPay(bytes32)","c44f7864":"getRemainingTimeInSecond()","c450a08a":"queryLockedTokens(address)","c450a25f":"unfreeze_contract()","c450d98b":"getCommunityReputation(address)","c4522c92":"removeStaff(address)","c45250c8":"icoRound3()","c45330b4":"remainingTotalBonuses()","c453cdd4":"getMyVines()","c4543386":"TUIToken()","c4545e6d":"_replaceModule(address)","c4552791":"proxies(address)","c4561d61":"finishICO()","c456354e":"setEndTimeStamp(uint256)","c4569504":"getKudosOf(address)","c456d394":"getPixelPrice(uint256)","c4576525":"WEC()","c457fb37":"getTokenPrice(uint256)","c45849c2":"doDistribution(uint256,address,uint256)","c458e5f3":"CrowdForceTestToken()","c4590d3f":"setLimits(uint256,uint256)","c4596419":"mintSoldTokens(address,uint256)","c45982b9":"madd(uint128,uint128)","c459b003":"ATTR_PERMANENT()","c459b9e3":"MaxStarIndexAvailable()","c45a0155":"factory()","c45a4047":"batchTrasfer(address[],uint256,uint256)","c45a6f98":"unlockMultiple(address[])","c45aa04c":"queryShareholders(bytes,uint256)","c45ad06a":"etherSince50()","c45b415e":"createRequest(address[4],address,uint256[11],uint256,bytes)","c45c4f58":"balance1()","c45cda5a":"init_fund()","c45d19db":"tokensToBeReturned(address)","c45d32cf":"getRemainingBytesLeadingZs(uint8,bytes)","c45d3d92":"conversionWhitelist()","c45d5fcb":"TwoStageCrowdsale(uint256,uint256,address)","c45d8af4":"getWinIndexFromHash(address,bytes32)","c45d8c8b":"Gryphon()","c45ddd87":"targetDiscountValue4()","c45df8e5":"COSIGN_MAX_TIME()","c45e4a7b":"SwiftDex()","c45ec88c":"Put(bytes32)","c45ef547":"offlineDiscipleSold(uint256,address,uint256)","c46073f7":"LUCYD()","c46093de":"_0xMonacoinToken()","c46180a7":"setBalanceOfActiveToken(address,uint256)","c461889e":"OkLive(uint256,string,string)","c4618978":"MIN_INVEST_ACTIVE()","c4620549":"quaker(address)","c4626ea7":"PumpHodl()","c4628520":"cashoutEOSBetStakeTokens(uint256)","c462a408":"maxParticipantCount()","c462bd11":"setupRules()","c46362fd":"set_merge_mint_threshold(uint256)","c463a1af":"CapitalMatchToken()","c463b008":"triggerTransferEvent(address,address,uint256)","c464fe65":"sellTokens(address,uint256)","c465e742":"UpdatedTokenInformation(bytes32,bytes32)","c466313c":"GetMainSale()","c4664649":"FIXEDREWARD_MM()","c467706d":"startEarlyAdopters()","c467a317":"freezeTeam()","c467b0ff":"_play(uint256,uint256,uint256,uint256,uint256)","c4694ec6":"ecoSupply()","c4697667":"BONUS_WL()","c469eb99":"deleteFromWhiteList(address,address)","c46a23a2":"signedAverage(int256,int256)","c46a2925":"setMinApprovalCount(uint256)","c46a3a0d":"icoPhase1EndTime()","c46a6262":"playEtherOf()","c46aaf38":"PharmaGenome()","c46b2d9d":"denyBundling()","c46b644b":"NewTicketEvent(address,uint8,uint8,uint8)","c46c3c68":"RuffToken()","c46cacae":"initial_time()","c46ce53e":"getOneTotalFeesCollected(uint256)","c46d2235":"serverEndGameConflictImpl(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,bytes32,bytes32,uint256,address)","c46d4cf1":"thawAccountTransfers(address)","c46df008":"walletData(address)","c46e3e85":"unitGooProduction(uint256)","c46e614a":"isCMCT()","c46ed45a":"fee_percentage()","c46f3e25":"lastChanceEnabled()","c4701037":"aaa(bytes)","c47028c1":"TOKEN_RATE_CROWDSALE()","c47031ab":"getKarma()","c4716d0f":"contributedCap(address)","c4725577":"getPrice(uint256,uint256,uint256,uint256)","c472c7e6":"setTotalWithdraw(address,uint256,address,bytes,bytes)","c4735121":"thirdRoundTime()","c4740a95":"removeAccount(address)","c4749079":"_roundDivision(uint256,uint256,uint256)","c4749bbd":"showInvestBalance()","c474e70a":"returnFundsForMultiple(address[])","c4752773":"priceStep3()","c475abff":"renew(uint256,uint256)","c475cdf5":"issueNew(uint256)","c476dd40":"reportMalicious(address,uint256,bytes)","c477d234":"checkIfAlreadyOrderedForDay(uint256,address)","c4784fd4":"setMsg(string)","c4788efe":"resetTotalVotes()","c478b52f":"PLATINUM_AMOUNT_TPT()","c478fc37":"EtherWheel(uint256,uint256,uint8)","c4791421":"changeCooldownEndTime(uint40,uint40)","c47958e2":"ERC20(string)","c479ace6":"updateOwners(uint256,address,address[],uint256,uint8[],bytes32[],bytes32[])","c47af5cf":"ChangeCost(uint256)","c47af732":"setReserved(address,bool)","c47bc007":"add_funds()","c47c4cc7":"getInitialBalanceByAddress(address,address)","c47cf5de":"getAddress(bytes)","c47d5bb8":"unitsUserCanBuyLimitEth()","c47e7bcb":"softcap3Reached()","c47e951f":"adjust_eth(uint256)","c47e9fea":"ContributionRefund(uint256,address)","c47ef875":"activeTokens()","c47f0027":"setName(string)","c47f0f90":"getPurchases()","c47fae76":"autoPlayBot()","c47fc244":"grantInvestorsTokens(address[])","c48029d4":"AddTokensToMember(address,int256)","c4806df4":"createTokenOwner()","c480e583":"revertTransfer(address,uint256)","c4811a0e":"maxICOThirdSupply()","c4813b2c":"StgOnebonusEnds()","c4815c96":"teamAdvTokens()","c4818ae1":"joinPillar(uint256,uint8,uint256)","c4818cdc":"_balanceOf(address,address)","c482299f":"transferAUTOtokens10(address[])","c482ceaf":"reinit()","c4834c30":"teamTotalSupply()","c483b71c":"Map(address)","c483befa":"setParameters(address,string,string,string,address,uint256,uint256)","c4841369":"paymentsByPurchaser(uint128)","c4843365":"getRarity(uint32,uint256)","c48513a4":"getStringConstant()","c485297b":"HelloSystem()","c48590e9":"PARTNER_SUPPLY()","c485ac95":"setWalletForTokens(bytes32,address)","c486301b":"AcceptsExchange(address)","c4864f45":"changeAcceptExchange(bool)","c4868452":"preIcoActive()","c486d133":"round1InitialBonus()","c4871039":"totalWeiRaisedDuringPhase2()","c4882e44":"disableRound0()","c488d6f2":"stopOffering()","c489744b":"getTokenBalance(address,address)","c489a649":"updateAirdrop(address)","c48a0dc0":"OptionToken()","c48a3cbf":"setStackPtr(uint256)","c48a66e0":"transferTimelocked(address,uint256,uint256)","c48a7560":"sellScams(uint256)","c48b1cf0":"test_5_accessRestriction_addMember_shouldThrow()","c48c68ee":"addressFounders4()","c48d5a4a":"_buy(uint256,uint256,uint256,address,uint256)","c48d93d8":"JuraToken(uint256,string,string)","c48d99ca":"DataDumped(address,string,bytes32)","c48db366":"Africacoin()","c48dc5fb":"JackpotAwarded(uint256,address,uint256)","c48e1c4d":"importAddresses(address[],address[])","c48e5ec4":"getPurchaseDetail(uint256,uint256)","c48e819c":"test_openRegistry()","c48eabc0":"getContributionPool()","c48ef17c":"floorId()","c4909a70":"addConfig(bytes32,bytes32)","c490a266":"toUInt(bytes)","c490dfa6":"isVerifiedAddress(address,address)","c491fd18":"FlexibleTokenSale(address,address,uint256,address)","c493afcf":"closeRefund()","c494a080":"totalPlayer()","c494c3f7":"teleportKnight(uint32)","c494f71a":"LedgerFund(uint32,uint32,uint64,uint64)","c49589bb":"rateUSDcETH()","c4969b8f":"setSellerAndAmt(address,uint256)","c4977807":"getFrozenAccount(address)","c4983c65":"updatePoints(address)","c498fcfd":"getUnitDefenseIncreases(address,address,uint256)","c49a1ede":"updateShareValue(address,uint256)","c49a3b04":"OraclizeVerifier(address,string,uint256,uint256)","c49a8fc9":"secureUpdateOrderFunds(address,bool,uint128,uint128,uint128,uint128)","c49b94e9":"getTokenTxn(uint256)","c49c3635":"getEventOutcomeIsSet(uint256,uint256)","c49d3b9f":"memberData()","c49d9ff8":"chatMessages(uint256)","c49ee5b4":"finalUnpause()","c49f91d3":"EIP712DOMAIN_TYPEHASH()","c49fea77":"setVariables(uint8,uint8,uint8,uint8,uint256)","c49fef66":"maxAnimals()","c4a06710":"isKYCPassed(address,address)","c4a0dada":"getOtherName()","c4a13f23":"affiliateBonusPercent()","c4a1ee37":"gasLimitWithdrawConfirm()","c4a1fedf":"increaseWeeklyTransactionVolumeReceiving(uint256)","c4a2c6b4":"Partial23Send()","c4a2d664":"setTransferFeeMax(uint256)","c4a2e641":"confirmTransaction(uint256,bytes)","c4a2fe12":"setversion(uint256)","c4a31557":"packSaleAddress()","c4a381b8":"setTokenRate(uint32)","c4a4cb4e":"countMilk()","c4a4e267":"weaponToApproved(uint256)","c4a4f265":"minimalContribution()","c4a50433":"unprocessedProfits()","c4a5350d":"createNewContract(string,string)","c4a5b138":"approved(address,uint256,address,bytes)","c4a796c1":"setReferee(address)","c4a8158c":"getMyTurtle()","c4a8598e":"BANCOR_X()","c4a85bc1":"allowAccess(address)","c4a89e9e":"lengthOf(uint256,uint256)","c4a8a670":"getEvent(string,uint256)","c4a8b570":"setdteamVaultAddr3(address)","c4a942cb":"chunkSize()","c4a96758":"getByteFromByte32(bytes32,uint8)","c4aa94a6":"withdraw(address,uint256,address[],uint256[])","c4ad32be":"generateTrees(uint256)","c4adb406":"validDestinations(uint256)","c4ae16a8":"getPlayerId(address)","c4ae3168":"togglePause()","c4b05f49":"addThing(string,string,string,string)","c4b06c19":"SeedSale(address)","c4b14e0b":"getSignature(bytes32)","c4b195ab":"r2(address)","c4b24a46":"checkReward()","c4b2841c":"_doTradeWithEth(address,uint256,address)","c4b293db":"getBuyRatio()","c4b296a7":"getInvestorIndex()","c4b2a668":"GlavCryptPoint()","c4b2eccb":"maxAmountAddresses(address)","c4b35f3d":"DIV()","c4b379f7":"earningsOfPlayer()","c4b3a516":"setPercentageAvailableToSell(uint256)","c4b40fb7":"tkcAddress()","c4b4dff1":"PayChain()","c4b54551":"MAX_SPARTANS()","c4b5cde2":"EventBuyShip(address,uint16,uint64)","c4b5f891":"LTBToken()","c4b62bbb":"updateAddressSetting(uint256,address,address,string,string)","c4b67e8a":"generateReport2(int8[],uint32[])","c4b6b5fd":"initChallenge()","c4b6c2f3":"btcPriceProvider()","c4b6fec9":"sendVal()","c4b71cec":"ICO_LEVEL_1()","c4b781a8":"setPercentAllocationFee(uint256,uint256)","c4b7c4cf":"communityVote(bytes32,bool)","c4b80f6e":"incPlayerOwed(address,uint256)","c4b9223f":"setVestingSchedule(address,address,uint256,uint256,uint256,uint256,bool)","c4b9897b":"IagonToken()","c4baa573":"process2(bytes32,uint256[],bytes)","c4baf4a4":"IQT_FUNDATION_ADDRESS()","c4bb0173":"hash_sha3(string,uint256)","c4bc5da5":"resumeContract()","c4bc7b70":"setGlobal(uint64,bool)","c4bd8ebc":"num_monsters()","c4bde5e1":"totalLotteryNumber()","c4bebd69":"pauseLastStart()","c4bff124":"addBlacklistItem(address)","c4c0698d":"withdrawInEmergency()","c4c1b39a":"tokenPriceInitial_()","c4c1c94f":"add(address[])","c4c1d835":"DataAuction(address,address)","c4c22e98":"blockInterval()","c4c24249":"turnLast()","c4c2e702":"execute(uint32)","c4c308be":"getBeneficiaryCash()","c4c3718b":"satoshi_bth_decimals()","c4c39ba7":"SWAP_CAP()","c4c49380":"setCap()","c4c4a89b":"buyNewDrone(uint256)","c4c4d00b":"CRBTTokenLive()","c4c4e3c0":"GOLD_AMOUNT_SKL()","c4c4e438":"oraclize_query(uint256,string,bytes[3])","c4c50acf":"giftTokens(address,uint256)","c4c59c77":"ethIN()","c4c5f3de":"forecastingClosed()","c4c6710d":"buyTicket(uint256,uint256,uint256)","c4c676cf":"TRBToken()","c4c68b44":"getTotalSupplyForType(uint256)","c4c745b6":"getBonusFactor(address,uint256)","c4c842f7":"_emitJobBinded(uint256,uint256,bool)","c4c90d70":"withdrawHouseFee()","c4c90f4c":"tokenUsersSave(address)","c4cae886":"setManualTradingAllowed(bool)","c4cb291e":"unpaid()","c4cbb591":"compot()","c4cbd65b":"isTourUnfreezed(uint256)","c4cbfa44":"isConstructor()","c4cc161b":"SellSnail(uint256)","c4cc5616":"addStory(uint256,string)","c4cc6e53":"TgeOtherReleasingScheduleContract(uint256,uint256)","c4ccf6ea":"getAmountBonus(uint256)","c4cf8a40":"createTradeContract(address,address,uint256,uint256,uint256,bool,bool)","c4cf9385":"MetaMorph()","c4cfc5be":"PGE01NY()","c4d01481":"getPreRemainCoins()","c4d18b18":"calculatePoohBuy(uint256,uint256)","c4d252f5":"cancel(bytes32)","c4d259ad":"setIsAdmin(address,bool)","c4d2783c":"GTTAirdrop(address,address)","c4d2bac9":"HelloToken()","c4d3926a":"currentTokenIdNumber()","c4d42292":"ResidualShare(uint256,string,string)","c4d4fdc0":"getBonusRateForTimeBased()","c4d66de8":"initialize(address)","c4d77090":"nodeAddresses(uint256)","c4d7b98f":"erc20ContractSwitch(address,address,uint256)","c4d8aa44":"VenaCoin()","c4d9102f":"setNextID(uint256,int256)","c4d97470":"PeriodReset(uint256,uint256,uint256,uint256)","c4daa2a6":"roundFees(uint256)","c4dbf622":"buyPrice(uint256)","c4dc1556":"finalizeProposal()","c4dcad1d":"mining(address,uint256)","c4dd3b33":"checkUserSignature(address,string,uint32,string,string,bytes32,bytes32,uint8)","c4dd5acc":"isLastBadgeEle(uint256,uint256)","c4dddedd":"addressVerified(string)","c4ded499":"getActiveBetsAmount(address)","c4df310a":"isWithinTokenAllocLimit(uint256)","c4e11c91":"updateStats(uint256,uint256)","c4e12e1d":"updateMinVotedTokens(uint256)","c4e16b7d":"whitelistToken(address,uint256)","c4e1793f":"_onOverTimeBall(uint8,uint8,uint8,uint8,uint8[3][3][31])","c4e29e66":"getOrderHash(address,uint256,address,uint256,uint256,uint256,address)","c4e34d46":"lockBonusTokens(uint256,address,uint256)","c4e37095":"setSaleState(bool)","c4e3a63b":"firstPeriod()","c4e41b22":"getTotalSupply()","c4e5b7f2":"createAcceptAndPayFromBytes(bytes,address[],uint256[],uint256[])","c4e5fd83":"_safeTransferFromInternal(address,address,uint256,bytes)","c4e627c2":"maxTokenCount()","c4e6aaa6":"setLocationId(uint32)","c4e6c604":"otherAddress()","c4e7099f":"mockTime(uint32)","c4e71adc":"firstReleaseTime()","c4e7d14c":"MultiSender(uint256)","c4e85b63":"flushTokens()","c4e9311b":"bindJobWithBoard(uint256,uint256)","c4e98398":"SimpleRegistrar(bytes32,uint256)","c4e9e80b":"setAutoSell(uint256)","c4eaa978":"_price_token_ICO4()","c4eb2b3c":"putSaveData(address,address,string)","c4eb8ec2":"transfer_ether(address,uint256)","c4ecfbbe":"MonsterChampionship(address)","c4eeeeb9":"isReissuable(bytes32)","c4ef18fc":"setRentAuctionContractAddress(address)","c4ef92d3":"OmiseGOGold()","c4efa665":"decimalPrecision()","c4f06ba9":"makerOf(uint256)","c4f07cff":"getWithdrawTransactionIds(uint256,uint256,bool,bool)","c4f0a043":"BTCPrice()","c4f1215c":"maxGoalReachedAt()","c4f141ff":"setWeiPerCHF(uint256)","c4f14c9c":"restrict(address,address)","c4f1ce79":"clearCurPrize(address,uint256)","c4f2a64f":"blockWait()","c4f2a7af":"GeneScience(address)","c4f35d6c":"WithdrawalToken(uint256)","c4f363bf":"getVersionByte(uint256)","c4f3c097":"setBasicRate(uint256)","c4f54568":"blocktubeTag(string)","c4f5cd82":"firstAllocation()","c4f62031":"setPlayerPrice(uint256,uint256)","c4f7f1e2":"scaledRewardPerToken()","c4f8210e":"_safeTransfer(address,uint256)","c4f8adc7":"consul_nme()","c4f8b9fb":"testAdd(uint256,uint256,uint256)","c4f8f339":"getPercent4(address)","c4f95105":"showUnpayedPercent(address)","c4f987a5":"removeWorker(address)","c4f99aa5":"publicReservedAddress()","c4fa9c6b":"getReservedTokenDestinationList(address,bytes32)","c4faa950":"BrinkToken(uint256,string,uint8,string)","c4fbdaff":"gibLambos(uint256)","c4fc3a3b":"presaleTokenSupply()","c4fc89e1":"bubbled()","c4fce59a":"fourthExtendedBonusSalesEnds()","c4fd262a":"CrowdsaleStarted(uint256,uint256,uint256,uint256)","c4fda23e":"sellTokensIcoWithReferal(address)","c4fdc6b8":"pauseIco()","c4fe2675":"getProtoIdByTokenId(uint256)","c4fed7fb":"addHouseCredits(address,uint256)","c4ff3614":"Wallet(address[],uint256,uint256)","c5007227":"DTToken()","c500ea36":"userPendingCrateNumber(address)","c501024b":"setMinCutValue(uint256)","c5015018":"TEAM_MONTHLY()","c501b87f":"setCreditMcAddress(address)","c503101e":"setCanClaim(bool)","c503772d":"returnUint8(uint8)","c503a868":"getTeamFee(address)","c5043343":"tempSetWinner(uint256,address)","c5044b62":"isDescriptionFinalized()","c50497ae":"SUPPLY()","c50499db":"developer_string_contract_verified(string)","c504bfb8":"ColorsMain()","c50508de":"initialAuctionDuration()","c505c82c":"zxcSold()","c505ebce":"endRate()","c506adae":"migrateInvestorsFromHost(uint256)","c5072172":"justThrow()","c50853f5":"getNumPublications()","c50886ae":"test_ConsensysNotReached()","c508d8f2":"reederemPeriods(uint256)","c5096a69":"feeFor(address,address,uint256)","c509c262":"TokenManager()","c509db3b":"getverifytime(address)","c50aea06":"claimShares(uint256,uint256)","c50bb446":"getNeutralMutation(uint32)","c50bd2e4":"trancheDenominator()","c50be063":"myPlanetList(address,uint256)","c50be16c":"setPublicRelease(uint256)","c50c44cf":"getAuctionSeller(uint256)","c50c97d0":"changeStorage(address)","c50cb9ae":"transferComplex(address,uint256,uint256)","c50d725c":"DACToken()","c50d847e":"POSC()","c50ec10a":"repoAppId()","c50f197b":"charitySplitPercent()","c50f8274":"IWasFirstServiceToken()","c50ff563":"canSubAllocation(address,uint256)","c510187e":"vpfHash(bytes32,uint256,uint256)","c5104c3d":"minPurchaseAmt()","c5105bb5":"TotalEDUSupply()","c510c906":"getEventOutcomeNumeric(uint256,uint256)","c510da62":"getsell(uint256)","c510db20":"userCanStillBuyEth(address)","c510dfeb":"convertAddressFormat(address[8])","c510f746":"createElection(bytes32,bytes32[])","c51131fb":"canBeSet(bytes32)","c511a362":"TransferTargetToken(address,uint256)","c511b016":"SingularDTVToken(address,address,string,string,uint256)","c511ed5e":"closeMarket()","c51215df":"preSaleListTime()","c51226b3":"secondStageMintingDate()","c5129348":"See_price()","c512d1d1":"testCalculateItemId()","c5132a5c":"getCreateMarketDesignatedReporterAddressValue()","c5133802":"mintFraCoins(address,uint256)","c5135ba0":"fuckynum()","c513cde2":"KD1Token()","c513d596":"BountyAdded(bytes32,string)","c513f66e":"EMPTY_PARAM_HASH()","c51450ca":"getTokenIdAtIndex(uint256)","c514ff3f":"EasticoinToken(uint256,string,string)","c515205d":"getValue2()","c515627e":"depositEther(address,uint256,uint256,uint256)","c5160187":"mintStart4()","c5162e1a":"vendre(uint256)","c516358f":"bountyAddress()","c5179027":"team0Points()","c518123a":"financingPeriod()","c519099d":"teamAndFounders()","c519500e":"potSplit_(uint256)","c51a29e0":"getContractType()","c51be90f":"query_withGasLimit(uint256,string,string,uint256)","c51bf934":"CEILING()","c51cc592":"setTransferAllowance(bool)","c51cd5d6":"StarWarsRTscore()","c51cd6ad":"getLockAccount(address,uint256)","c51ce17b":"TelegaOut(address)","c51cf179":"calcBaseFeeForShares(uint256)","c51d16b6":"totalCollectedWei()","c51dc993":"expiryCheck(string)","c52046de":"isDeployed()","c5210e89":"ERC20Standard(uint256,string,uint256,string,bool)","c52141da":"checkSign(address)","c52164c6":"reputation()","c52173de":"xConvert(address[],uint256,uint256,bytes32,bytes32,uint256)","c5231563":"addAddress(uint256,address)","c523d5dd":"setBlockPart(uint64,uint64,uint64,bytes32,bytes)","c523ef11":"VNDCash(uint256,string,uint8,string)","c5241e29":"removeWhitelisted()","c5242acb":"setWithdrawOwner(address)","c524645b":"getTimeBonusAmount(uint256)","c527018b":"jdalevsystemscoin()","c527326e":"PFOffer(address,address,bytes32,uint256,uint256,uint128)","c5277ddd":"isPublisherRegistered(address)","c5282f7a":"generateTokensForPresaleAccounts(address[])","c528fee7":"DRCToken()","c5292c67":"getStart()","c5292ed9":"calculateEggSell(uint256,uint256)","c52987cf":"strikePrice()","c529b80b":"transferWithData(address,uint256,bytes32)","c52ab778":"execute(address,uint256,uint256)","c52adfda":"BobsNVag()","c52bd836":"setDappOwner(bytes32,address)","c52c936c":"removeByIdx(uint256[],uint256)","c52cb003":"OwnerDistribSupply_()","c52cde58":"getRedeemableTokensVoter(bytes32,address)","c52e40d0":"totalWeiExpected()","c52f02ce":"BLS_PRE_ICO()","c52f9fa6":"PartialOwnershipCrowdsale(uint256)","c5312191":"WeiController(address,address,address,uint256,bool)","c531c245":"exists(int256)","c531d52b":"STRUTToken()","c5337992":"setBossHPDefault(uint256)","c5337ed4":"random2()","c5339132":"lastPlayed()","c533fc68":"getLockAccInfo(address)","c5340dcd":"received_wei_with_bonus()","c53467cf":"releasePublicPresaleBonusTokens(address[],uint256)","c5346fb1":"approve_coin(string,bool)","c534ba4b":"destroyBlacklistedTokens(address,uint256)","c5350345":"Magexbit()","c535165f":"revealAndPayout(bytes,bytes)","c5364bc3":"GetChallengeWeightedVolumes(uint256)","c536c952":"getDsitribute(address,uint256)","c536ed5f":"buyDmlCoin(address)","c537a210":"principalOutstanding()","c537f954":"adjustDeployRange(uint256,uint256,uint256)","c53833fe":"getLastContract()","c539607c":"get_internal_block_number()","c53a0292":"increaseNonce()","c53abe29":"tokenOnlyDeploymentCost()","c53ad76f":"Kardashian()","c53adaff":"SingularDTVWorkshop()","c53b12f9":"myEthBalanceOf()","c53b9c04":"maxTimeRemain()","c53bafbb":"setPriceOf(string,string,address)","c53c2556":"getTokenIdFrombBPhash(string)","c53c614d":"canBeWhitelisted(string)","c53ce034":"totalDraw()","c53d6ce1":"getAllBalances(address)","c53d8483":"getActualTotalTokens()","c53dbf82":"disclosureAdded(uint256,bytes32,bytes32,bytes32,bytes16,bytes1,bytes16,bytes32,bytes32)","c53df200":"getArrUintField1()","c53df937":"unshareService(bytes32,address)","c53e4387":"IHODLToken()","c53ee3a5":"_setInitialCardPrice(uint128)","c53f926b":"setByuoutActive(bool)","c53fc65f":"tokensDevelopers()","c53ffe66":"KillerWhale()","c5401559":"setQuantityAdminOnly(uint256,uint256)","c5405f17":"registerUserBonus(address,address,address)","c540f903":"DeployRelay()","c540fb66":"updateBuyNum(bytes32,uint8)","c54110d6":"AcceptsNASDAQ(address)","c54117ac":"REDGILL()","c541783c":"getLockedBalanceOf(address,address)","c541a5bd":"revertAML(address)","c5426124":"getStar(uint256)","c542675e":"fus(uint256)","c54397a4":"changeAffiliate(address,uint256)","c543ae53":"evaluateArea(address,uint8,uint256)","c543b427":"IntegrationOfCredit()","c543c922":"devWithdraw(uint256)","c54421ae":"teamTokensNotDistributed()","c5442f7d":"getRandom(uint16,uint8,address)","c5444ff9":"buyTokens(address,uint128,uint256)","c544682b":"rewardForBurn(uint256)","c544f8d9":"EventRemoveFromBattle(address,uint64)","c5454d11":"Finalize()","c545c09d":"calculatePrice(uint256,uint256,uint256,address)","c5460e71":"getReleasableAmount(uint256,address)","c5465a23":"votingstage()","c546a92e":"testTransferTokensUsingRawCall()","c54704e6":"setLockStartTime(uint256)","c547092b":"setMilestone(uint256)","c547af82":"_totalVouchersSupply()","c547d8f1":"totalWeiAmountSale3()","c547e14d":"setHatchDurationByTimes(uint32[])","c54837a4":"extinguish()","c5487661":"proxyTransferToICAPWithReference(bytes32,uint256,string)","c5494b82":"SCH()","c5498e4e":"setTeamAndAdvisorAndAirdropAddresses(address,address,address)","c54996b7":"refundBond(uint256,address)","c549e4e9":"sellPriceAt(uint256)","c549e6b9":"DAYS()","c549e7a0":"ManualTokenMintRequiresRefund(address,uint256)","c54a068c":"getCurrentRateInternal()","c54a0980":"Total_Entries()","c54b25b0":"claimCancelled(uint16,address)","c54b5658":"toAddress(bytes,bytes,uint256)","c54c80eb":"RxPharma()","c54cd39c":"getSandwichInfoCaloriesPrice(uint256)","c54d59a1":"snt_claimed(address)","c54d8609":"setCoOwner2(address)","c54e73e3":"setPresale(bool)","c54e91c6":"currentPart(address,address)","c54f050c":"_createOrder(address,address,uint256,address,uint256,uint256,uint256)","c54f3409":"getGameEnd(address,uint256)","c54f5344":"OfficialWalletAddr()","c5503e89":"allocateTokensInternally(uint256)","c5505235":"toEther(uint256,uint256,uint256)","c5526d16":"setCrowdsaleWallet(address)","c5530077":"wildcards(uint16)","c55374d0":"oraclizeDelay()","c55425e6":"TotalOwnerSupply()","c5543b22":"powerDayPerPersonCapInWei()","c5546ecd":"transferTokensToParticipants(uint256,uint256,uint256,uint256,address)","c5549cc0":"minDeadline()","c554a600":"initTokenPorter(address,address)","c5566dac":"getNumberOfCourse()","c5575ef0":"checkTransferFrom(address,address,uint256)","c557b985":"icon()","c557d29c":"ByteLocker()","c557e552":"_getWager(address)","c558ae6b":"Airdrop(address[],uint256[])","c5590033":"setStatus(string,string)","c5592be2":"addContract(string,address,address)","c559743a":"included(address)","c559c395":"bitwordsCutOutof100()","c55a02a0":"SNT()","c55b6bb7":"setAdmin(address,address)","c55c1cb6":"queryN_withGasLimit(uint256,string,bytes,uint256)","c55c4115":"FEE_CHARGER_DENOMINATOR()","c55c4f47":"isCrowdsaleSuccessful()","c55d0f56":"getCurrentPrice(uint256)","c55d34d4":"airdropGW()","c55dae63":"baseToken()","c55dd86a":"isLegalPlayer(bytes32,address,address)","c55e0eaa":"bonusPeriodDurationInHours()","c55e4645":"LETOCoins()","c55ed894":"withdraw_to_owner()","c55ee28c":"nextSession()","c55f1f42":"timeLockSend(address,address,uint256,bytes)","c55f3b4c":"GetInventory(address,uint256)","c55f60dc":"checkAndUpdateLimit(uint256)","c55fb39f":"SAFE_PERIOD()","c5620ded":"LogBuy(address,uint256,uint256,uint256)","c56351cd":"createCrowdsale(address,uint32,uint256,address,uint8,address,address)","c5639ed2":"SUB(uint256,uint256)","c56551b6":"pos()","c56597ba":"_v2()","c565eba6":"isRoundTwoSalePeriod(uint256)","c566d43c":"registerPlayer(address,bytes32)","c5671148":"mul64()","c567cd26":"updateStudent(string,bytes32,string)","c567e43a":"show_me_the_money()","c567f304":"approveAddReserveData(uint256)","c5682244":"changeTickPrice(uint256)","c56893fb":"getLockerCount()","c5689e7d":"deWhiteListContract(address)","c56935e2":"showJackpotNextRd()","c5699ac2":"canRestoreUnsoldTokens()","c5699d68":"_compare(int256,bytes,int256)","c569bae0":"right93(uint256)","c569fb36":"setDepositPool(address)","c56a0ffe":"summDevelopers()","c56a3e88":"isManager()","c56af732":"CannabanC()","c56b2dc2":"upgradePony(uint256,uint256,bytes)","c56b4294":"_initialMint()","c56bbda4":"isTransferApprove(uint256)","c56bea64":"setBlacklistedUser(address)","c56c89a2":"ChendeWorld()","c56cf2b2":"getAllSaleAnimals()","c56d0d67":"tokensSoldWhitelist()","c56e3849":"Versioned(string)","c56e610e":"getEscrowBalance()","c56ecdfa":"_isOne(address)","c56ef049":"execBuyBack(uint256)","c56f1578":"UzairToken()","c56fc9c1":"PreSaleDistributed()","c570e952":"CustomPOAToken(string,string,address,address,uint256,uint256,uint256)","c5715483":"bonusMinContribution()","c571627b":"ChangeMainWallet(address)","c572652b":"distributeWithLockup(address,uint256,uint256,uint256,uint256)","c572ca10":"TokenProcurement(address,address,uint256,uint256)","c572dcc3":"getFreeMiner()","c572e9cb":"_decodeBuyData(bytes)","c57380a2":"getControllerAddress()","c573902d":"getInfoPanel()","c573e6bd":"distributeIfNeeded(address,uint256)","c57443fa":"ZRX_EXCHANGE_ADDR()","c574a53c":"addJurisdiction(bytes32[],bool[])","c574d156":"getGameBalance()","c575200d":"setPropertyBecomePublicEarnUntil(uint16,uint256,uint256)","c575c238":"sendToken(address)","c57679fc":"recipientMIT()","c5774a3f":"seedAmount()","c5787fa3":"picops_identity(address,uint256)","c578b2f4":"getTransformTarget_default()","c578f2c8":"SetCityName(address,bytes32)","c5793979":"sendCheck(address,uint256,bytes32)","c57949e2":"AllowanceLedger(address,address)","c57981b5":"FEE()","c57a050e":"fairandeasy()","c57a4a4d":"TOKEN_PUBLIC_SALE_CAP()","c57a8825":"updateRegistryAddress(address)","c57a99e5":"testFailRetractLatestRevisionEnforceRevisions()","c57c3bbd":"addLockProduct(uint32,uint32,uint32,bool)","c57c5f60":"initMultiowned(address[],uint256)","c57c7b62":"mktIssue(address,uint256)","c57d3fb7":"setReFundAddress(address)","c57d5fe9":"addToBalance(address,address,uint256)","c57dead7":"betsLost()","c57fbf90":"tokenRate(address)","c58068d8":"getIdFromStr(string)","c5809312":"setLLV_edit_28(string)","c58156e0":"removeAllocation(address)","c58343ef":"getRequest(uint256)","c5837713":"a_empresa(bytes5)","c583bb53":"RYNO()","c5854113":"MilestonesFactory(address)","c58580aa":"icoAddress1()","c585bb93":"registerAssetProxy(address)","c585de64":"Rate3()","c58684ab":"setPauseEmergence()","c5868754":"is_signed()","c587e3d6":"totalRised()","c587f93e":"softCapCountDownTimer()","c588415e":"phase4EndBlock()","c588953e":"enddate()","c588ba1b":"getLowestGameWithoutQuorum()","c588cabd":"firstBonusPercent()","c5893a8e":"OnPreSaleBuyerCompensated(address,uint256)","c589f1f3":"transferEthersToDao(uint256)","c58a3321":"setAccessControl(address,address,uint8,bool)","c58a34cc":"setTimeout(uint256)","c58a6ce8":"sendPayment(uint256,address)","c58aaae6":"selfDestructBeneficiary()","c58b54ef":"getAssetAttributes(uint256)","c58cc060":"firstBuyers()","c58ce220":"setDeveloper(string)","c58d0be0":"getCompetitionStatusOfRegistrants()","c58d96a5":"whiteListERC223(address)","c58f2f49":"hashTypes(uint8)","c58f520f":"sharingPool()","c5907a34":"Kanicoin()","c590c994":"unfreezeCount()","c5917695":"KevCoin()","c591b3ca":"itemCanVote(address,uint256)","c591c8a3":"getAllJinglesOnSale()","c59255dc":"changeMilestone(uint8,uint256,uint256,uint256)","c592c3ba":"addAmountBoughtAsMember(address,uint256)","c5933658":"registerEmailAddress(address,string)","c59361b9":"getInsurance(address,uint256)","c593dfbf":"queryDataFromId(address,uint256)","c5944f30":"Token(address,uint256)","c5947cd6":"getReportingState()","c594a12d":"areadjacent(uint16,uint16)","c59513a4":"updateMyTimeMintBalance()","c5958bda":"removeFile(bytes)","c595fee6":"adminWithdrawEther()","c5960c29":"buyKeyByAddr(address)","c59671a7":"set_dni(uint256)","c5980b07":"getDRSCoinDividend(uint256)","c5981892":"buyTokensCrowdsale(address)","c59981cd":"edit(uint256,uint256,uint8,uint8,uint8,uint8,string)","c599b77f":"setUserGroup(address,address)","c599d58f":"MAX_NUM_PAYOUT_ATTEMPTS()","c59a9428":"transferTreasurership(address)","c59acae4":"lrcWithdrawn()","c59b2e20":"NEVA()","c59b5562":"buyICO()","c59c1144":"setDefaultKey(address,address,uint8,bytes32,bytes32)","c59d278e":"vehicleDatesByCity(bytes32)","c59d4847":"getStats()","c59d55ad":"releaseTransfer(bytes32,uint8,bytes32,bytes32)","c59d5633":"getPurchasePrice(uint256)","c59d6abe":"getAngelClaims(uint64)","c59e0b87":"setSecondWalletPercent(uint256)","c59e5729":"upAd(uint256)","c59ea269":"snowflakeBalance(string)","c59ee1dc":"raisedAmount()","c59f3a7c":"getConditionsState()","c59f6983":"editMaxItems(uint8)","c59f83cf":"_getNftContract(address)","c5a0a555":"setImageRegionId(uint256,uint256)","c5a0ca8f":"init(address[],uint256[],uint256,address)","c5a0d1c7":"percentageQuarter1()","c5a104d9":"ln_fixed3(uint256,uint256)","c5a1d7f0":"metadataHash()","c5a2d352":"publish(uint256,bytes32)","c5a369b4":"addAddressDescription(string)","c5a46ee6":"value(uint256)","c5a4eb35":"initialPricePaid(uint256)","c5a55152":"distributeRewards(address[])","c5a60ddb":"payout(bytes32,uint256,uint256)","c5a6732b":"_isChallengerAttackFirst(uint256,uint256)","c5a796ac":"set_address_Arina(address,address)","c5a83c2b":"countAssets()","c5a88559":"getWithdrawNum()","c5a8a2ab":"changeStatus(uint256,uint8)","c5a8d421":"RocketFuelToken()","c5a9833e":"trusteeVaultAddr()","c5a988c9":"extendPreSalesPeriodWith(uint256)","c5aa0f17":"setNewJackpot(uint256,uint256,address)","c5aad3be":"getStackPtr()","c5ab4602":"updateBalance(address,address,uint256,bool)","c5ac124d":"cashToEth()","c5ac8a4d":"leftSharePrice()","c5aca3b2":"NYXDecentralizedIdentificationRequest(string,string)","c5ace443":"priceFeedSource()","c5ad94a9":"addressSharesCount(address)","c5ae6e0e":"Kernal()","c5ae7570":"getSaleFinancialData()","c5af3808":"setJntBeneficiary(address)","c5af9000":"Convert()","c5afc0a5":"BonusAllocation(address,string,uint256)","c5afce8b":"ensureInAccountList(address)","c5b045eb":"secondRoundPercent()","c5b05616":"TokenAuction()","c5b15057":"updateSettlementStatus(bool)","c5b15caf":"CIBOS()","c5b1a53c":"deposit(bytes16[],uint64)","c5b1d9aa":"newRound()","c5b1e789":"Unset(string,address)","c5b2333c":"set_status_user(address,address,bool,bool)","c5b2429d":"periodPreITO_tokenPriceUSD()","c5b35556":"bixToken()","c5b3a429":"PresaleStartTimeChanged(uint256)","c5b417ec":"buyPlot(uint256,uint256)","c5b43c39":"CypherX()","c5b53a34":"_setAuthorizedPower(uint256)","c5b748c0":"redemptionPrice()","c5b7589c":"startMiniGame()","c5b7be81":"TruckingCoin()","c5b7c51b":"participateEvent(address)","c5b7f5bf":"presale_eth_fund()","c5b85eb8":"UBSI()","c5b8d7a1":"cyclesStartFrom()","c5b8f772":"isOwnerOf(address,uint256)","c5b930f9":"singletonHash(bytes32)","c5b9cdf8":"SMARTCCCoin()","c5bac421":"pruneInvestors(uint256,uint256)","c5bafbc4":"eosDACToken()","c5bb8af4":"IMDEXsetInactivityReleasePeriod(uint256)","c5bcc4f1":"parentSnapShotBlock()","c5bd8456":"TakeOffWorldWide()","c5bd9089":"redeemCoupons(uint256)","c5bdbd70":"multDenominator()","c5be7a77":"_shareDevCut(uint256)","c5bef690":"_escrowIndex()","c5bef74e":"getHash1(address,uint256,address,uint256,uint256,uint256)","c5bf2249":"wallet(bytes)","c5bf339c":"getLastNonPublished()","c5bfa9d9":"getUserBalanceOnEther(address)","c5bfd5dd":"TokenDrop()","c5bfef39":"initCountry(uint256,uint256)","c5c00ac6":"needVerified()","c5c01169":"checkFrozenAccounts(address)","c5c03af3":"_mode()","c5c09b20":"TestRecover(uint256,uint256,uint8,bytes32,bytes32)","c5c0b859":"pauseMaster()","c5c0db08":"whom()","c5c187f5":"LogApproval(address,address,uint256)","c5c2f6e0":"getTopPlayerScores(uint256)","c5c4412d":"CleanBankerRound(uint8)","c5c4744c":"totalRaised()","c5c5135c":"crystalPrice()","c5c56740":"ROBIET()","c5c593e1":"openGameResultAndNewGame(uint256,uint256,uint256,string,bytes32)","c5c680f3":"testUser()","c5c6b12a":"isInvestorInWhitelist(address)","c5c715e4":"approveBatch(address[],uint256[])","c5c72bf4":"sayAnything(string)","c5c7681f":"Main(address)","c5c78258":"YoloTokenPresaleRound2(uint256,uint256,uint256,uint256,address,address)","c5c80103":"listFaceToFaceAttendants()","c5c8015b":"isNotContract(address)","c5c872ae":"transferFromRobot(address,address,uint256)","c5c87db4":"reinvestReturns(uint256,address)","c5c8a08a":"getExpirationTimeFromAddress(address)","c5c925e2":"StoreRegistry()","c5c93bdc":"Birth(uint256,uint256,uint256)","c5c95c55":"QuantityUnit()","c5c9e3be":"setPreparationPeriodTrainingFeeMultiplier(uint256)","c5c9f617":"walletE()","c5cac386":"Questions()","c5cc52fc":"Indemnisation_5()","c5ccebd3":"smallerPriceComparator(uint256,uint256)","c5cd3bec":"getRevisionTimestamp(bytes20,uint256)","c5cd88db":"missingFundsToEndAuction()","c5ce3911":"productId()","c5cf8c7e":"getCurrentHighscore()","c5d03fc0":"OftenChainToken()","c5d0c68b":"addMaster(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint64,uint64)","c5d14955":"phase_2_token_price()","c5d22e94":"MAX_TOTAL_AMOUNT_TO_RECEIVE_ETH()","c5d2577c":"newTransfer(bool,address,address,uint256,uint256,uint256)","c5d290d0":"RUNtoken(uint256,string,string)","c5d39a33":"isEating(address)","c5d456d6":"moves(address,uint256,uint256)","c5d46dfc":"computeScore(address)","c5d51586":"loser(address)","c5d5997c":"changeSubUser(address,address)","c5d61ad0":"newGame(uint256,bool,uint256)","c5d65d1a":"approveSponsorableJob(uint256)","c5d6a7f1":"GreatcoinERC20Token()","c5d6c75d":"PunchClock()","c5d7802e":"z()","c5d7dd0a":"Blockcash(string,string,uint256,uint256)","c5d81804":"mintSBIToken(address,uint256)","c5d83794":"setDesign(uint256,string)","c5d8adcb":"EventProduct(uint32,string,uint32,uint32,uint32,uint32,uint32,uint256,uint256,uint256)","c5d953a3":"setCurrentMarketRate(uint256)","c5d9ada3":"IANToken()","c5d9c762":"set_pre_kyc_iconiq_bonus_denominator(address,uint256)","c5dacf68":"getOwnerEth()","c5db22da":"lastBlock(uint64)","c5dba811":"doRandom(address[],address,uint256)","c5dc6b55":"getAccountBonus(address,address)","c5dce83d":"changeAPTController(address)","c5ddb614":"BlockFundIncubatorToken()","c5ddba02":"startDate1()","c5decd37":"ico3Raise()","c5df27ef":"ETHcap()","c5e08ba9":"get_oo_of(address)","c5e12813":"burnAllInvestorTokens(address)","c5e290cd":"_editInfoImpl(string)","c5e2a7db":"updateMetadata(address)","c5e2f418":"disableChanges()","c5e35f42":"Gentingchain(uint256,string,string)","c5e36b7e":"lockMana(uint256)","c5e3adf5":"nFund()","c5e3b1a6":"reclaimOwnership(string,string,bytes32)","c5e3e3f3":"s21(bytes1)","c5e412e5":"createSaleContract(address,uint256,uint256,bool)","c5e42338":"getIncreaseTotalStakeCalled()","c5e4594f":"multiline(uint256,uint256,uint256,bytes32)","c5e634e4":"transferAuditTokens(address,uint256)","c5e7b4fe":"setupPreIco(uint256,uint256)","c5e8b864":"hasEnoughBST(address,address,address)","c5e951a4":"agentOrdersOf(uint256,uint256)","c5e974ed":"transferToken(bytes32,address,address,uint256)","c5e98a4c":"updateIncentiveTokenLimit(uint256)","c5e991a8":"ThirdEtherLimit()","c5ea01c9":"testF2(uint256)","c5ea0b4a":"buySquare(uint8,uint256,address)","c5ea3c65":"maxId()","c5ea6256":"enableSecureMode()","c5ea8e1d":"RefUpdate(string,uint256,uint256,uint256)","c5eab684":"calculateDividends(uint256,uint256)","c5eaccfd":"whitelistAddrAndBuyTokens(address,uint256)","c5ebeaec":"borrow(uint256)","c5ec05fd":"scheduleSale(uint256,uint256)","c5ec365f":"guideInvestmentAttractedShareToPay()","c5ecfc61":"getEscrowDeposit(string)","c5ed7162":"firstPresaleStart()","c5ed8c99":"canCollect(uint256)","c5edd450":"payFor(uint256)","c5ee5688":"setCompte_25(string)","c5ef4c3e":"set(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","c5efaa11":"calculateValue(int256,uint64)","c5efaae8":"buyCredits(address,uint256)","c5efea68":"getAdminStatus(address)","c5f0d3d6":"geneKind()","c5f310c0":"register(bytes12)","c5f39cd7":"rateSecondTier()","c5f40edd":"discountedDealAmount()","c5f4b3da":"RewardPoolAmount()","c5f4c98b":"changeDiscountStep(uint256)","c5f5ce21":"advisorTokenWallet()","c5f60620":"expectedTokens(uint256,bool)","c5f70682":"setByuoutCount(uint256)","c5f713cf":"push(uint256,bool)","c5f7ed63":"NeckCoin()","c5f913fe":"callExitFromUnknownContract(address)","c5f956af":"treasuryAddress()","c5f98a3f":"mega()","c5fa1924":"MMS()","c5fbe723":"result_payto()","c5fc43cb":"Newera()","c5fc98c9":"TOKEN_THIRD_DISCOUNT_MULTIPLIER()","c5feaf60":"PRE_SALE_START_1()","c5fee757":"executeOrder2(uint256)","c5ff2069":"MooTokenSale()","c5ff2222":"playNo()","c600e1dc":"getProfit(address)","c6011633":"setRateFees(uint256,uint256)","c6017a25":"playerRoll(uint256,address)","c601b7f8":"icoPhase1Start()","c60211ee":"MineFinished()","c6028cf3":"nextSaleStage()","c6029e7b":"sendBPESOTokenToMultiAddr(address[],uint256[])","c603a4e3":"getTotalHP(uint256,uint256,uint256,int256)","c603ae14":"jockeyFS(uint256)","c603bd7d":"_executeOrder(address,uint256,uint256,bytes,int256)","c603c97b":"NewPiedPiperCoin(string,string,uint8,uint256)","c6041333":"calculateKnowledgeBuySimple(uint256)","c6046f77":"mintAndTransfer(address,uint256,bytes)","c6049946":"saleExchangeRate1()","c604bec9":"hasExtension(address)","c604e967":"delFilter(uint256)","c605f76c":"helloWorld()","c6062bc3":"sellerRefund(uint256,address)","c60778cf":"RefundRequest(uint256,address,uint256)","c6080b3f":"KiDhon()","c60880e0":"Aster()","c609ab26":"setImageCurrentRegionId(uint256,uint256)","c60aa10d":"newForgeCon(address)","c60b099f":"removeRate(uint256,uint256)","c60b7784":"queryEOSCrowdsaleKey(address,address)","c60bdc7f":"setUsersContract(address)","c60c13a3":"blockAccountFunds(address,uint256)","c60c3aca":"callFor(address,uint256,uint256,bytes)","c60cae29":"changePeriodTime(uint256,uint256)","c60ccb0e":"takerBuyAsset()","c60ce271":"findNextMinute(uint256,bytes)","c60ced1b":"LetsGoChain(string,string,uint256,uint256,uint256,uint256,uint256,uint256)","c60f56b2":"totalAcorns()","c60f6462":"resetRick()","c610bb07":"tranfer(address,uint256)","c6113205":"getTokenByIndex(bytes32,string,uint256)","c6114aaf":"updateIPOPrice(uint256)","c6117d37":"xactionFeeShare()","c611ded7":"reserveTokensAddress()","c6129a5a":"GetVersion()","c612cc4e":"compareDatesWithoutTime(uint256,uint256)","c613089f":"getBetsEvenAndODD(uint256)","c6132eb3":"timeBetweenRewards()","c6137977":"eliminateSmartContractByteCode()","c614b522":"getAllInvestmentPackageIds()","c614da67":"free(bytes12)","c615365f":"EthBetter()","c6159a35":"icoTransfer(address,uint256)","c6169e1f":"maxTournamentContenders()","c616f412":"totalQuantity()","c6178a65":"soldTokensSale()","c617fe6e":"_setAllowance(address,address,uint256)","c6180d27":"silverBoxPrice()","c618210a":"crowdsalepricing(address,uint256,uint256)","c618a1e4":"volume()","c618d15f":"ConvertNumbers(bytes5)","c6195d03":"ONE_DECIMAL_QUANTUM_ABC_TOKEN_PRICE()","c6195d36":"setConfig(address,uint256)","c6199b6d":"getCustomerServiceAddress()","c619bbd3":"GetPower()","c61b06ae":"collectibleIndexToOwner(uint256)","c61b8a44":"rewardGenerationComplete()","c61c3c4b":"buyPackWithETH(bool)","c61e42ae":"mint(uint256,int256)","c61e5be6":"cardSetsInCirculation(uint256)","c61ea7a3":"CrowdfundableToken(uint256,string,string,uint8)","c61efde6":"MsgEngine(uint8)","c61f1103":"foundersTimelock2()","c61f13a1":"setWitdrawGas(uint256)","c61f3a2c":"drpToken()","c61fb3f1":"Moon()","c62072d2":"nfo_transaction(uint256,uint256,address,address,bytes32)","c620b5fe":"isDaySecond()","c620ecc7":"KYCTeam()","c62122eb":"AmberToken()","c621f96e":"deleteDIDHolder(address)","c6220fbd":"dividendDistributionStartTime()","c6221878":"projectCompleted()","c6224757":"issueTreasury(address,address,address)","c622afb0":"getInsertPointForNumTokens(address,uint256)","c6235f8d":"delMarketMaker(address,address)","c623674f":"ipfsHash()","c6236a5c":"scheduleCall(bytes,uint256,uint256,uint8,uint256)","c6240303":"SetAuxOwner(address)","c6253f14":"XXXXXXXX08(uint256)","c625bd27":"transferFromBRXPay(address,address,uint256)","c625e9b1":"buyTokens(uint256,address)","c62631a5":"LicensingToken()","c62662f2":"setTotalCapitalization(uint256)","c6266693":"setCoreContract(address)","c626c52e":"isGame(address)","c6279ab1":"voteClose()","c627d0f8":"setCampaign(uint256,uint256)","c628ddc3":"TAIL()","c629061d":"external_oraclize_randomDS_proofVerify(bytes,bytes32,bytes,string)","c6291223":"fundTransferWithin(address,address,uint256)","c629cdf4":"collectPayout()","c629e770":"donorList()","c62aa67d":"getNodeId(bytes32)","c62c5fda":"setIcoFirstWeekRate(uint256)","c62cfa1d":"getMyNote(uint64)","c62d7407":"frozenOf()","c62dcd5b":"getSentTransactions()","c62dee76":"HumanBlockToken()","c62eac5c":"create(address,uint256,bytes32,int256)","c62fae5d":"getValueInfo(address)","c63012a1":"setHashPiture(uint256,bytes32)","c630f92b":"canEnterPool()","c630f96b":"ZToken(uint256,string,uint8,string)","c6314bf9":"companyAllocation()","c6317f37":"Token_Saled()","c631b292":"closeVoting()","c631e758":"clearRole(address)","c6321979":"buyTokenPack(uint256)","c632e654":"_takeRdFee(uint256)","c633084f":"sendGreeting(address,string)","c6335b26":"startInvasion(uint256,uint256[])","c633eb24":"generateReserve()","c63445f3":"setFeePool(uint256)","c634d032":"mintToken(uint256)","c634fd83":"adminSetDefaultFee(uint256,uint256)","c63545e9":"developer_edit_text_fees(string)","c6354bc0":"addCountries()","c6357b54":"impl_forging(address,uint256,uint256)","c635a9f2":"MinimumDeposit()","c635bf38":"keyGt(bytes32,bytes32)","c635d65e":"StandardToken(address,string,string,uint8,uint256,bool)","c6361267":"mintOneWeek()","c6366ce9":"TOTAL_ICO_CAP()","c636813e":"disapproveSingleUser(address)","c63755e1":"transferPresale(address,uint256)","c6381649":"getChats()","c6384071":"voteCount()","c638529f":"SetProvider()","c6388e6f":"_AtlantisToken()","c6393e62":"migrationSetBoard(bytes32,bytes32,string,uint8,address)","c63998ed":"updateUnitsOneEthCanBuy(uint256)","c6399fc7":"_setItemNotForSale(uint256)","c63a4e05":"getCartLength()","c63c1a27":"calcFight(uint64,uint64,uint256,uint256)","c63ccb3b":"Discount()","c63d04df":"BonusReferred(address,address,uint256,uint256)","c63d99db":"auctionName()","c63e2ebc":"setRoundStart(uint256,uint256)","c63e529b":"buy(string,string)","c63ebcbb":"claimedUnits()","c63f49ab":"LuckyDice()","c63fdcc7":"claimPayment(uint256)","c63ff8dd":"claim(bytes)","c64012a6":"CoinSent(uint256,address,string)","c640487d":"_changeLogicContractAddress(address)","c640752d":"update(address,address)","c641aaca":"addPrivateSaleEndDate(uint256)","c6427474":"submitTransaction(address,uint256,bytes)","c642b103":"treasuryTimelockAddress()","c642f094":"MOT()","c6430e29":"get_firstbytes(address)","c6434660":"isTakePermitted(uint256,uint256,uint256,address,address,uint256,uint256,address)","c643872e":"paymentTo(uint256,bytes,address)","c6440b3e":"sub(uint32,uint32)","c64572b8":"minimalPriceUSD()","c645ecc4":"handleReturnBytes32()","c6461625":"setIV_R4(uint256)","c64743d5":"BlockMined()","c6476fe9":"isMinimumInEther()","c647b20e":"setTaxes(uint256,uint256)","c647c3d9":"t_1st_StageEnd()","c648843a":"current_week()","c6490835":"total_tokens()","c64a2358":"_targetBlock()","c64a3239":"updateExec(address)","c64aace0":"airdropConjured()","c64bf22d":"SummerGreen()","c64bf32f":"distribute_token()","c64d73c6":"JCoin()","c64e03a2":"FAPcoin()","c64e08a0":"CampaignPausd(uint256)","c64e8bc0":"executeN(uint256)","c64f28c8":"createImage(address,uint256,uint16,uint16,uint16,uint16)","c64f9490":"updateAccessoryLock(uint64,bool)","c64fa2e4":"totalDividendShares()","c64fbbce":"_calcRemainingRoundTime()","c65025f8":"isSmartSharingEnded(bytes32)","c6502da8":"basePayment()","c6512a33":"CNC(uint256,string,uint8,string)","c6544e5c":"icoSpecConfirmed()","c6548076":"isUserBlacklisted(address,address)","c65538ec":"afterSTEDistributed()","c655d7aa":"recoverAddress(bytes32,bytes)","c655fd2c":"setSlowDump(uint256)","c6560856":"currentJackpotInWei()","c6567835":"changeVaultWallet(address)","c6570e67":"contractorTransfer_Scoupon(address,uint256)","c65799a4":"ReturnRequested(address,address)","c6580352":"HeroTrained(uint256,address,uint256,uint256,uint256,uint256,uint256,bool,uint256)","c65808b9":"getSpell(uint32)","c6585a27":"updateNotaireAddress(address)","c659ce2b":"setBountyAddress(address)","c659d443":"url(bytes32)","c659dceb":"is_verified()","c65a0fdf":"updatePixelIndex(uint16,uint16)","c65a4068":"_multisig(bytes32,uint256)","c65ac542":"saleUnpause()","c65ad85c":"isReadyToStart(bytes32)","c65b125f":"setContestContractAddress(address,address)","c65b490e":"getBabyMakinPrice(uint256)","c65c6eae":"getReadableContribution()","c65c9567":"gameResult(uint256,uint256)","c65ccc07":"setLtdParams(uint256,uint256,uint256)","c65cec32":"refundTokenToCustomer(address,address,uint256,address)","c65d15b9":"reference()","c65daea0":"allocated6Months()","c65fb380":"isSet()","c6601270":"getMyIceDragon()","c660477b":"GetData(uint256)","c6610dec":"owner_share()","c661deb4":"issueHardcapToken(address,address,uint256)","c661ee4d":"proofAddr()","c661fed3":"isAdvisor(address)","c6620580":"presale_tokens()","c6634ef5":"certify(uint256)","c6638df9":"LogTemplateCreated(address,address,string)","c66485b2":"setDefaultResolver(address)","c6653041":"ParticipantRegistry()","c666c798":"setExtendedTokenCap(uint256)","c6677519":"executeSettingsChange(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","c667ab20":"setFundsRegistry(address)","c6685617":"record(address,uint256)","c6688445":"stringToSignExample()","c668dfd7":"doAirdrop(address,address[],uint256)","c668ee3d":"operatingFundAddress()","c668f71b":"exchFee()","c6699ba8":"addPayTable(uint16,uint16,uint16,uint16,uint16,uint16,uint16,uint16,uint16)","c669c955":"incentivesIn(address[],uint256[])","c66a431d":"addContract(bytes32,bytes32,bytes32,bytes32,address,bytes32)","c66aaf0f":"sucessor()","c66bd6aa":"updateEthICOThresholds(uint256,uint256,uint256,uint256,uint256)","c66c2536":"doTransferOut(address,address,uint256)","c66c67e9":"setReservedTokensPercent(uint256)","c66e4095":"icoContract()","c66e9260":"ESCCrowdsale()","c66ed8f7":"lockGenesisImports()","c6702187":"CLAIM_SIGNER_KEY()","c6705a00":"signupUsersManually(address)","c6711049":"withdrawTokenManually(uint256)","c67117f5":"InvEnterpriseAddr()","c67146a5":"check_bet(uint256,address,uint8)","c6715f81":"left44(uint256)","c6716590":"DovieBarMitzvah()","c67410fb":"getOwnersLoan(address)","c67415f3":"mineCrystals(uint256)","c674e0c9":"setSmartContractStatus(uint8)","c67685a9":"turnOffCanUpdateDeveloperMiningPower()","c67747a5":"bitGuildAddress()","c6776239":"BitPropertyToken()","c677b207":"addElectedMember(address,string)","c6786e5a":"destroy(address[])","c678ca19":"comfirmIsses(uint256)","c678e618":"sendDividend()","c679580e":"isModuleHandler(address)","c6795b45":"bonusPatterns(uint256)","c67979a5":"PakistanRupee()","c6798033":"dedicatedProxyAddress()","c67acceb":"firstStageEndsAt()","c67b099f":"createWildcard(string,uint256,uint16)","c67b599a":"presaleMinPurchase()","c67bbc24":"getVolume()","c67c6eab":"stopCrowdSale()","c67ce6f5":"FlightDelayNewPolicy(address)","c67d376d":"getClosedCandidates()","c67e43c1":"setExpectedEnd(uint256)","c67f3ba3":"GanLiXia()","c67f3e1f":"totalDistributedinWei()","c67f7df5":"getDepositsCount(address)","c6803622":"wasCalled()","c68098d9":"personalCapEndAt()","c6814aa2":"copyPaper(address,uint256)","c681d68d":"badgeBalanceOf(address)","c68218d1":"setStrF1F2F3(string,string,string)","c6822356":"_createAss(string,uint32,string,uint256,uint256,uint256)","c682a10d":"createRoot(string,string)","c682d0bb":"authorized_updateSaleInfo(uint256,uint256)","c68309a7":"buyICloudSecsAgainstEther()","c683630d":"isWhitelist(address)","c6837a87":"getDepositeTime(address,uint256)","c683d8e4":"enableSale()","c6842868":"registerBroker(address)","c6851889":"Sale(address,uint256)","c68581ea":"addFile(uint256,string,uint256,string,string)","c686554e":"getInfo(address,address)","c687857c":"updateAsset(uint256,string,string,string,uint256)","c687ce9d":"setInitialOwner(address,uint256,uint256)","c6888fa1":"multiply(uint256)","c68890c7":"AcceptGuardianOffer(uint256)","c6891018":"take(uint256,bytes32[])","c68a3c1e":"setShares()","c68a536d":"GetLuckyRewards()","c68ad0a8":"Hold(address,address,uint256,uint8)","c68ae617":"authenticate(address,uint256,uint256,uint256)","c68b82c9":"ethLastUpdate()","c68bf3ea":"eDeposit()","c68cd47e":"COIN_SUPPLY_ICO_TIER_1()","c68cee04":"addArtistToRegistry(bytes32,address,uint256,uint256)","c68deb7e":"saleEndTimestamp()","c68e35b0":"verifyHash(bytes32,uint8,bytes32,bytes32)","c68e52d9":"setTimeStamp(string,uint256)","c68ee9cd":"search(uint256,uint256)","c68eebe3":"getCurrentTokenPriceInCents()","c68f2ada":"getDoc(string,string)","c68f7dfc":"test_hasClaimableShares_zeroClaimableStake()","c68fd307":"minimumContributionPresalePhase1()","c68fe0c1":"WeClosedInto()","c69034ab":"test_21_assertGasUsage50Boards()","c690c9a5":"Apollo()","c6912a39":"confirmRedbullQuest(address)","c692c049":"pushData()","c692d9de":"LogNeumarksIssued(address,uint256,uint256)","c692f4cf":"renounceAgent()","c69493a0":"subSale()","c69500fd":"rewardPay(address,uint256)","c695ff11":"randomAPI_url()","c6960d4c":"winnerid()","c6967c17":"DeviseToken(uint256)","c6969604":"emitBoardCreated(uint256,bytes32,bytes32,address,uint256,uint256,uint256,bool)","c69768dd":"createInkeTrade(bool,uint256,uint256)","c6979c0a":"WhitelistContract()","c697cbec":"_startNextRound()","c6998dc2":"updatePartner1_vows(string)","c69a00be":"setPeggedToken(address,address,address,uint256)","c69a8e13":"erc20BalanceForAddress(address)","c69b3936":"getNumSigs(bytes32)","c69b5df2":"prev_hash()","c69b5dfb":"verifyInvestors(address[])","c69b761f":"admin_set_deposit(address)","c69c7069":"mintPaper(string,string)","c69cd09d":"breedingFee()","c69e06db":"transactionsActive()","c69ed5f2":"executeTransaction(bytes32)","c69f4481":"setBlacklist(uint32,bool)","c69f8623":"convertSignalToMinimal(uint256)","c69fa8a9":"setAuthorizerAddress(address)","c69fbf48":"bountyProgram()","c6a00369":"LRCFoundationIceboxContract(address,address)","c6a05c06":"payOut(uint8,uint256)","c6a09d95":"grantAccess(address,address)","c6a0b13f":"cancelOnSaleCrab(uint256)","c6a0eb24":"test_threeInvalidEqBytes32Message()","c6a118d4":"impl_transferMS(address,address,uint256)","c6a17d2b":"pow10(uint256,uint8)","c6a22681":"getParticipantIndex(uint64,address)","c6a2573d":"oneTokenInEurWei()","c6a2afa7":"TokenECCAC(uint256,string,uint8,string)","c6a470e2":"getDisputeState(uint256)","c6a496bf":"Artwork(bytes32,uint256,string,string,string,uint256,address)","c6a4d345":"setMaxEscrow(uint256)","c6a4f4af":"getCurrentPotInfo()","c6a52959":"gba()","c6a5d5da":"updateBlocksPerDay(uint256)","c6a69931":"verifyCommit(address,uint40,uint256,uint8,bytes32,bytes32)","c6a71577":"WEKUToken(address)","c6a725d8":"confirmTransaction(uint256,bool)","c6a7d3af":"setTokenExcange(address,uint256)","c6a81857":"existsCountsById(uint256)","c6a898c5":"u()","c6a97c60":"SolusToken()","c6a98543":"ICONIC_NIC(uint256,string,string)","c6ab4514":"sendRobust(address,uint256,uint256)","c6ab5429":"KotET2()","c6ab5cdc":"closeBuy()","c6ab5d90":"withdraw(uint8)","c6ab848a":"referralInstance()","c6abc298":"getBetAt(address,uint256)","c6ac53fd":"submitTransaction(address,uint256,bool,bytes)","c6ad1191":"MyOwnCoin()","c6ad5d7c":"expireBid(address)","c6ae3b57":"dEthereumlotteryNet(address,address)","c6ae67ad":"fundcruToken()","c6af3166":"checkDouble(address)","c6af43f9":"updateThresholdNewAuction(uint256)","c6af477c":"get(bytes32,string)","c6afd98a":"requestConversion(uint256)","c6b0263e":"setPublicCapability(address,bytes4,bool)","c6b0a1fa":"checkPricePair(uint256,uint256)","c6b0de7e":"removeFromWhiteList(address,address)","c6b0ffd0":"is_success()","c6b20dc2":"Invacio()","c6b2a5dd":"updateCurrentSupply()","c6b3a7cf":"wplus(uint256,uint256)","c6b3ad7b":"setTWhitelist(address[],uint256[])","c6b4ad80":"ctu_owner()","c6b547e6":"getDocumentName(uint256)","c6b59e9e":"changeParameters(uint256,uint8,uint256)","c6b6005b":"TMSYToken(address,address,address,address,address)","c6b6b1e8":"ICOReserveSupply()","c6b6bc3c":"burnPurchase(uint256)","c6b85d2b":"AtomicX()","c6bbb6ef":"sendTokensTo7(address,address,address,address,address,address,address,uint256)","c6bc8dee":"testInitial2of3()","c6bcd5f7":"INTEGROToken()","c6bcefe5":"otherPoolTotal()","c6bd541f":"supportTeam(uint256,uint256,uint256)","c6bd5a13":"dividendsPaidPerShare(address)","c6bd62f5":"get_CountAllHolderForProfit()","c6bd9187":"closeEvent(bytes32)","c6bec93a":"startLottery(uint256)","c6befedf":"createPoll(bytes32)","c6bf03dd":"changeReleaseAccount(address,address)","c6bf7489":"sendLudumToMany(address[],uint256[])","c6c09252":"_generateCode()","c6c18e31":"PCToken()","c6c1e248":"ProductFactory()","c6c20a75":"getTotalCardValue()","c6c25d04":"artUrlList()","c6c27c71":"_slrByrLmtChk(address,uint256,uint256,address)","c6c2966d":"setFundingEnv(uint256,uint256,uint256)","c6c332f2":"getUserEthVolumeSaldo(address,address)","c6c39bda":"unitsOneEthCanBuyafter()","c6c3bbe6":"mint(address,address,uint256)","c6c3f3f9":"setKyberProxy(address)","c6c4676c":"currentResult()","c6c4bf44":"issueFor(bytes32,address)","c6c55773":"Topplay()","c6c599c1":"changeApprover(address)","c6c65136":"spiderReq()","c6c68eb7":"getAyantDroitEconomique_Compte_2()","c6c6b3ed":"Sale(uint256,uint256,address)","c6c7d143":"cancelRedemptionRequest(uint256)","c6c7f5aa":"impl_amountOfOrderQueue()","c6c85ca5":"updateTokenRate(uint256)","c6c8823c":"getActionPrice(string)","c6c8cdc7":"LogFundTransfer(address,uint256,bool)","c6c99744":"t01_setKey(bytes32)","c6caa959":"sellRock(uint256,uint256)","c6cb7a96":"orderMatchTest(uint256,uint256,int256,uint256,uint256,address,address,uint256,int256)","c6cb7ab8":"getBytesValues(bytes32)","c6cbc52a":"revokeCertificate(bytes32)","c6cbd5f0":"abandonedIcoBalances(address)","c6cc68b9":"BuyStockRocket(uint16,address)","c6cce2e7":"len(address)","c6cd15aa":"frozenVaults()","c6cd712d":"delegatedTransferAndNotify(address,address,uint256,uint256,uint256,bytes32,bytes,uint256)","c6cdbe5e":"categories(uint256)","c6cdc6f6":"fastICO(uint256)","c6cdf77e":"upgradeWeth(address)","c6ce2664":"setBancorRegistry(address)","c6ce81f0":"manualSendTokens(address,address,uint256)","c6ceafef":"setFeedAddress(address)","c6ceb50b":"Decimals()","c6cebebd":"get_info(uint256)","c6ced32b":"getWorkersCount()","c6cf1c7f":"generateRandomPerformance()","c6cf452b":"testInitialA()","c6cf4dd9":"upgradeOnePointZeroBalances()","c6d04634":"BasicCrowdsale(address,address)","c6d0be63":"emergencyCease()","c6d0ffda":"failedTemperaturesLength()","c6d1d23d":"totalPledgedFeesAt(uint256)","c6d2cb6a":"getLavaTypedDataHash(address,address,address,uint256,uint256,uint256,uint256)","c6d32838":"deathData_f3()","c6d3ab9d":"changeTokenSymbol(string)","c6d417de":"NewName(address,string)","c6d44ecc":"_getTokenCountToBuyFromSeller(uint256)","c6d456ec":"Winning_Entry()","c6d48e0d":"getVersionsCount()","c6d69a30":"setTaxRate(uint256)","c6d761d4":"cancelEscape(uint32)","c6d779e6":"getAmountOrdersForDay(uint256)","c6d784cc":"Statustelega(address)","c6d81547":"DecisionTokenSale(uint256,address)","c6d8a203":"setConversionRateAddress(address)","c6d8be5a":"setPricingStrategy()","c6d8f0c4":"getLocks(uint256)","c6d90e70":"AcceptsDailyRoi(address)","c6d9112a":"MAX_DAILY_TOKEN_COSIGN_SPEND()","c6d95512":"ExchangeTokenPushed(address,uint256)","c6dad082":"make()","c6daeeaa":"TIME_TO_HATCH_1SNAIL()","c6dbdf61":"primary()","c6dc3640":"AirDropPayBitsR2(address[])","c6dc437b":"bids_ignored_count()","c6dca1d2":"proposeAsset(string,uint256,uint256)","c6dd5098":"DateCoinCrowdsale(uint256,uint256,uint256,address,address,address,address)","c6dd5db5":"validateOrder(address,uint256,address,address,uint256,address,uint256,uint256)","c6dd8018":"Cygnal()","c6ddcfe8":"publicSellToken()","c6ddd889":"ForeignBridge(uint256,address[])","c6de150b":"soldIdeaWei()","c6de5709":"calc_partnerPercent(address)","c6deeb9d":"contributionAccepted()","c6df66a7":"firstPlay(bytes32,uint8,bytes32)","c6e000b5":"mntpToken()","c6e0329f":"LaoHuiHui(uint256,string,string)","c6e04590":"rateHard()","c6e08ba9":"EligmaCrowdsaleContract()","c6e0c908":"checkTransferFromWithReference(address,address,uint256,string)","c6e0dc6e":"ChangeTransferStatus()","c6e1c178":"TheLuckyOne(bytes)","c6e3a9b3":"_total_sold()","c6e3d1b4":"promotionsOfHost(address)","c6e3e8fd":"getManualByAddress(address,address)","c6e3ffc3":"determinePID()","c6e416b5":"addressGains(address)","c6e5546c":"distributeTokens(uint256,uint256)","c6e68059":"DeAuthorized(address)","c6e68ea6":"createTournament(bytes32,uint256,uint256)","c6e6ab03":"allocateCandyToken(address[],uint256[])","c6e6b803":"grantAt()","c6e715e1":"rechargeDeposit()","c6e81b07":"remainingAuctionable()","c6e8b4f3":"createProxyAndCall(address,address,bytes)","c6e946df":"ComputePharaohReq()","c6e994d7":"shareWithdraw()","c6e9ce11":"NZD_CLEAR()","c6e9ff54":"changeBonusDistributionAddress(address)","c6ea3037":"_createSale(uint256,uint256,uint256,uint256,address)","c6ead8af":"tokensBurnt()","c6eae0c5":"limitEth()","c6eb8a65":"stage2BeginTime()","c6ed3418":"TokenMintPoD()","c6ed8990":"addTokens(uint256)","c6ed8e1b":"getApprovedProxys()","c6eda379":"totalZTKCheckAmounts()","c6ee701e":"getInts()","c6ee7a2c":"Linkable(address,address)","c6eeeb04":"increaseTimeBy()","c6f017e1":"addOrgan(address)","c6f03aaa":"getRegister(string,string)","c6f0557f":"insertarMensaje(uint256,string,string)","c6f067d1":"MVPToken()","c6f3a895":"endFirstPeriodTimestamp()","c6f47486":"getHistoricalPrice(uint256)","c6f482aa":"largeCapDelay()","c6f48866":"isGameOver(bytes32)","c6f4ebb3":"o_minerador(uint256)","c6f54e62":"order(address[2],uint256[4])","c6f5b0e0":"getContributor(uint256)","c6f5d91f":"getAddressWhiteList()","c6f6122d":"transferredManually()","c6f664af":"totalInsuranceFlows()","c6f6d9d9":"lotteryCount()","c6f6f216":"setMaxPerTx(uint256)","c6f70370":"generateRoomNightToken(uint256,uint256,uint256,uint256,uint256,bytes32)","c6f88b0a":"_hasCorrectTreasury(address)","c6f981d7":"setTrap(uint256)","c6f9defe":"futureExpanstion()","c6fadeb3":"fechAllSumNumForEncourage(uint256)","c6faf736":"updatePromoBonus(uint256)","c6fc2bae":"ACEEquityToken(uint256,string,string,uint8)","c6fd2103":"recordImbalance(address,int256,uint256,uint256)","c6fdee56":"isAddress(address,address)","c6fe317f":"changeVanityURL(string)","c6fe7296":"resetPhases(uint256,uint256,bool,uint256,bool)","c6ff3ae3":"EthMark()","c6ff4081":"tokenProcess(address)","c7005f04":"distributeInternal(uint256,uint256,uint256,uint256)","c701672f":"_recordPresalePurchase(address,uint256)","c7021c9e":"submitPresetTransfer(address)","c7024b98":"deleteHybridization(uint256)","c7027329":"isBossWannaCryContract()","c7028f96":"burnAllLeftTokens()","c702d3b4":"Unregistered(address,address,uint256,uint256,uint256,uint256)","c7033721":"genesisRoot()","c70383a5":"takeOwnerShip(uint256)","c7046117":"sendAsGift(address,uint256)","c7047fa7":"metadataUrlPrefix()","c704e04a":"recordingResultsOfBet(bytes16,bytes16[],uint8[])","c704f7ed":"lockName()","c705a1a8":"getMerchandise(uint256)","c705e1a3":"allowToken(address,address,uint256,bool,bool,address)","c7071c3e":"MiningRewardChanged(uint256)","c707936a":"Serpent()","c707bae5":"getTopNames()","c708ed9c":"getPI_edit_15()","c7091c5e":"INITIAL_STAGE()","c70978da":"UnicornBreeding(address)","c7097f62":"linkAddress(address)","c7098e91":"decodeOrderTokenAndIsBuy(uint256)","c709c7b8":"priceStep7()","c70a24af":"ROLE_NEED_LOCK_UP()","c70a3f1a":"whiteHat()","c70a9246":"GetConsentData(uint256)","c70ad05b":"identity_storage()","c70bbc13":"emitRevoke(bytes32,uint256,address)","c70cc560":"storePassword(string)","c70cdad8":"hashBacktestPositions(uint32,int64[])","c70cef3a":"WalamaCoin()","c70d169d":"answerRequest(uint256,bytes)","c70dd8b3":"procureTokens(address)","c70e8640":"amountFundTeam()","c70ef908":"setPI_edit_33(string)","c70f5eaa":"buyCard(uint256)","c70faf90":"EndMinting(uint256)","c70fe6bd":"migrateAuction(uint256,address)","c71029e1":"getBankRequests(string,uint256)","c7102df7":"__stopBlock()","c710a2aa":"marketplace_controller()","c7110035":"multiSigWithdrawal(address,uint256)","c7120bad":"linkAccount(uint8,string,string)","c7120d77":"sendFunds(address,uint256,uint256,uint256,uint256,uint256)","c712f3b3":"TradeId()","c7133f53":"setAccountS(address)","c713a67b":"momentNonceOf(uint256,uint256)","c713aa94":"setEndBlock(uint256)","c713b10f":"isSameSign(int256,int256)","c713bd70":"getMarketerRate()","c7143c41":"notSameSeed(string,string)","c7144269":"changeSettings_only_Dev(uint256,uint256,uint256,uint256,uint16,uint256,uint256,uint256,uint8,uint8)","c7153816":"lowerSupply(uint256)","c715533e":"allFrozenTime()","c71692b6":"capPreICO()","c716b616":"adopt(uint32,uint32)","c7172710":"pouseCrowdsale()","c7178230":"isDeprecated()","c717e9eb":"voidOrRevert(uint256)","c718b272":"Floor(uint32,address)","c718b2bb":"YunToken(address)","c718d0e0":"_setFreezedBalance(address,uint256,uint256)","c7192cda":"EventUpdateWasReset()","c7192e44":"setPaid(address)","c719348b":"safeCheck(uint256)","c71a7aea":"distributedReservedTokensDestinationsLen()","c71ad84d":"vehrespond(uint256,uint256,address,bool)","c71b583b":"closeRequest()","c71ba100":"revokeBalance(address,address,address)","c71bee4c":"OMITokenLock(address,address)","c71bf8ba":"multiplierOfPrice()","c71c0b40":"fundRaised()","c71c3f05":"blackListCompanies()","c71c890a":"weekFourStart()","c71cb0b4":"buildTile(uint16,uint16,uint8,uint16)","c71cbcf3":"recoverAccount(address,address)","c71daccb":"checkBalance()","c71ddb9f":"releaseContract()","c71e48d6":"setOutcome(bytes32,bytes32[])","c71e876b":"VESTING_DURATION_2Y()","c71eef58":"applyForTokenOneDay()","c71f2bae":"AddOpenOrder(uint32)","c71f311c":"setFABAcompanyTokensWallet(address)","c71f4253":"getNumberOfVotes(uint256)","c7216a44":"_generate_special_horsey(address,address,address,bytes32)","c721b34b":"setBattleAddress(address)","c721b6bd":"grantVestedTokens(address,uint256,uint256,uint256,uint256,bool,bool,bool)","c721cfe2":"reClaimBalance()","c721f08d":"activateSale()","c722328d":"withdrawToMultisig()","c722e113":"_transferDivs(uint256,uint256,uint256)","c722e462":"CoinX()","c7238af7":"escapeDestination()","c724772c":"turnOnIco()","c72486d2":"Unexpended()","c724acb7":"calcDifficulty()","c7258d7f":"isUserWhitelisted(address,address)","c726c2b9":"getPI_edit_24()","c726dea8":"memberArray(uint256)","c7277115":"ManagedToken(string,string,uint8)","c727980a":"payDeposit(uint256,address,uint256)","c7280315":"UnauthorizeToTransfer(address)","c7286a21":"removeContribution(address)","c7291b7e":"descriptionHashHistory(uint256)","c729a567":"withdrawFundToAddress(address)","c72a2328":"tier_rate_1()","c72a480e":"DGameController(address[])","c72b5176":"getGroups()","c72b5e4f":"persentRate()","c72be838":"gasForDCN()","c72c1133":"Log(string,uint256,uint256)","c72c757e":"delete_allowedAddress(address,address)","c72e1576":"addAddressInWhitelist(address)","c72e57c7":"lockedTill()","c72e6d03":"p_setRefPercent(uint256,uint256)","c72e8baf":"PRICE_3()","c72e9e45":"setEgeregAddress(address)","c72f0dd9":"Player_HitOrStand(uint256,bool)","c7303c61":"createPost(string)","c7304f37":"changePool(uint88)","c730bbd8":"rateWaiting()","c730dfbb":"WemarkToken()","c731c504":"restoreFunds(address,address,uint256)","c731e124":"rewardslength()","c73202ff":"jpPercentageDivisor()","c732d201":"currentCount()","c7330bf6":"getDepositesCount(address)","c7343754":"getLendingItemLength(address)","c7347832":"asyncTransfer(address,address,uint256)","c734f917":"onTokenTransfer(address,uint256)","c73659be":"RexToken(uint256,address)","c736e118":"bgxWallet()","c7377d80":"Bourneereum(uint256,string,string)","c737b7c6":"getTotalTickets(address)","c7381593":"Multimember(address[],uint256)","c7385f2e":"proofIds(uint256)","c738a836":"changeEnabledAddressStatus(address,bool)","c7395151":"updateMaxAcceptedDeposits(uint256)","c7398dd4":"getCustomValue()","c73992e4":"hasApproved(address)","c73997b1":"changeBaseValue(uint256,uint256,uint256)","c739d31c":"setPrivateSaleAgent(address,bool)","c73a2d60":"disperseToken(address,address[],uint256[])","c73aae86":"get_Release()","c73b187d":"oraclizeMinCallbackGas()","c73b302e":"projectsCount()","c73c27bc":"getNodeId(uint256)","c73c2a45":"WriteBible(uint16,uint16,uint16,uint16,string)","c73c933d":"ChangeBurnBoundsOperationEvent(uint256,uint256,uint256)","c73d3b30":"getAbilities()","c73defce":"ETCHaddress()","c73ea367":"setNickName(string)","c73ec2eb":"minCompositionFee()","c73f0c11":"burnGlobFoneCoin(uint256)","c73f20e3":"issueamount()","c73fcee2":"CLNTotalSupply()","c74073a1":"close(address)","c740bc9f":"setLongtermMinter(address,uint256)","c7410070":"publicbattlestart()","c7411eb4":"calculateAntBuy(uint256,uint256)","c741764c":"oldE4()","c741d70d":"retrieveFounds()","c741e85a":"set_parameter(string,uint256)","c741f0f3":"buyBILL()","c7420a9f":"store(bytes,address,address,uint256,uint8,uint8)","c7423803":"finishRecovery()","c7423f26":"strFundDeposit()","c74266b3":"HanYinToken()","c742bab1":"VUP_TOKEN_SUPPLY_TIER1()","c743092e":"Buy(uint256,address,uint256,uint256,uint256,uint256)","c7430e28":"Trillionix(address,address)","c7431f5c":"changeETXAddress(address)","c74352af":"FileServerManager()","c74370db":"Transfer(address,address,uint48,bytes)","c74442e6":"withdrawNexiums(address)","c7445c22":"getPassportId(address,address)","c7446565":"startAt()","c74590e3":"LogInvestment(address,uint256)","c745ca9a":"transferBack(uint256,address,address)","c745dab9":"MakerDepositedEther(uint256)","c7464e8a":"showRandomWinners()","c746a52d":"showme(uint256,uint256,uint256)","c746b299":"PSCToken()","c746c8f4":"addAllowedSender(address)","c747ef76":"AbieFund(address[])","c747f120":"totalIssuerCollateralisation()","c74803de":"_isContained(bytes32,bytes,bytes32)","c7489441":"closeMarketMaker(uint256)","c748b54b":"PeerWalletsERC20Token()","c74a2449":"canUserAnswerQuestion(address,uint256)","c74a690c":"price_in_wei()","c74a827c":"setMonsterCreatorAddress(address,address)","c74a96eb":"setHGT(address)","c74abe43":"getMyTokensValue()","c74b1e01":"startPresaleTime()","c74b5a3e":"open5Chest()","c74c251f":"addSafely(uint256,uint256)","c74c851a":"isValidInvestment(address,uint256)","c74ca049":"unshareKey(bytes32,address)","c74ce765":"TESTTESTToken(address)","c74e907b":"commit(address,uint256,uint256)","c74fc077":"guards(uint256)","c74fda29":"_distributeAdvisorsToken(uint256)","c7506049":"_processSalePurchase(address,uint256)","c7508ec7":"removeClaim(address,address,bytes32)","c750938e":"shiftcashToken()","c750c3b1":"allocateEndTime()","c750cb79":"getHighestBidder(uint256)","c750df73":"submitContract(bytes32)","c7516da7":"CITY_INCREASE_RATE()","c751e027":"PoolTeam()","c752746e":"tokenHoldersClaimed(address)","c752a999":"MoneyTokenPromo(uint256,string,uint8,string)","c752ff62":"totalUpgraded()","c75363b6":"BEGIN_TIME()","c7542f1d":"GCCToken()","c754fc08":"addGroup(uint256,uint256,uint256)","c75514e8":"executeOptions(address,uint256,string)","c7559da4":"uint256ToBytes(uint256)","c7573e82":"registerStudent(address)","c7574839":"communityWallet()","c7576e8f":"TOBToken()","c7576ed4":"finalizeMigration(address,address)","c75782be":"startup(uint256,address)","c7586cde":"THIRD_USER_CUT()","c758b813":"ausGroupAllocation()","c75902cf":"iwtfundtokens()","c7591d35":"checkGuess()","c7593f01":"SKLAuction()","c75abf24":"setup(uint256,uint256,uint256)","c75bc4fb":"setMaintenanceLock(bool)","c75bc6f8":"UniverseShieldToken(address,address)","c75d9d29":"unlockPurchase()","c75e8d55":"setRecipientString(string)","c75fb740":"Error(bytes)","c75fc22f":"freeEther()","c7600cde":"getInitialReporterAddress()","c7602316":"deploy(string)","c7614487":"MAX_CROWD_FUNDING_ETH()","c761a2f5":"revertFeeCalculatedFlag(bool)","c762547d":"contractCreatedCount()","c762c463":"mUsers(address)","c762d3ea":"calculateReferralBonus(uint256,uint256)","c762d5f7":"setBorrower(address)","c763400e":"endpreIco(bool)","c763e5a1":"chain()","c764427c":"addAllowedContract(address,address)","c764d4c4":"withdrawCountriesToken()","c764ee57":"VIWOZ()","c7656f6e":"startProject()","c765defd":"setBeneficiary(address,bytes32)","c76668cf":"transferCheck(address,address,uint256)","c7669337":"fundMinting(address,uint256)","c766ce02":"addFactProviderToWhitelist(address,address)","c768051a":"gla()","c768a4cd":"upgradeSword(address)","c768ac01":"totalWithdrew()","c76a4bfb":"relayReceiveApproval(address,address,uint256,bytes)","c76a74df":"Bitscoin()","c76b838c":"bulkSell(uint8[],bytes6[],uint32[],uint32[])","c76c1ba5":"placeBet(uint256,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","c76c68d0":"CalcToc(uint256,uint256,uint256)","c76c9269":"ethVest()","c76d0754":"fiatSend(address,uint256,uint256)","c76de3e9":"Start(string,string)","c76df481":"getArmyOwner(uint256)","c76e7f32":"addressToPersonId(address)","c76f0d13":"COSTToken()","c76f80c8":"_createCaptainToken(address,uint256,uint32,uint32,uint32,uint32,uint32,uint32)","c772173a":"ProsperToken()","c7725426":"setAuthorizeMintToken(uint256)","c772af39":"boss()","c7736abf":"windowOpenTime()","c77547f7":"maxTimeIntervalHB()","c7760b11":"getlevel(address)","c77636fc":"PauseOwnerAdmin(bool)","c77684f9":"ClipperCoin(uint256,string,string)","c776cc42":"FREEDOMCoin()","c7775011":"setSlaveWallet(address)","c77810a4":"Pot()","c778427b":"migrationInitiated(address)","c7786275":"Bitansuo()","c778a46b":"doPresaleMinting(address,uint256,int256)","c7798891":"TokensReleased(address,uint256)","c77a0de6":"xfer(uint256)","c77a16ed":"resumeTransfers()","c77ae9bf":"resetRaz(uint256,address,uint256)","c77bd8cc":"acceptAdminToo()","c77bdfce":"bindToken(address,address)","c77c00f8":"openNewBet(address,uint256,uint256)","c77dff62":"shrimpyramid()","c77e7614":"getTotalWithdrawAmount()","c77ef9b8":"setAccessProvider(address)","c77f58c8":"transferMinusComission(address,uint256,uint256)","c77fe4d6":"incentivisingSupply()","c781d7b0":"calculateAntSell(uint256)","c781f97b":"getCurrentCrabPrice()","c7825c3f":"Pruebalillo()","c782fc60":"getExtraBalance(address)","c783dc9e":"pullEther(uint256)","c783fb10":"validBalanceOf(address)","c784648d":"addIdArrayItem(address,uint256,string,string,uint256)","c7847d19":"createAnnoTrade(bool,uint256,uint256)","c7857d27":"setMyName(string)","c786a66f":"_createSchedule(address,uint256,uint256,uint256,uint256)","c786ebd1":"LogPrepareToStart(string,uint256,uint256,address,address)","c7876ea4":"basePrice()","c7878fa0":"setHumanityFund(address)","c7888a07":"claimSuperDragonEggs()","c7891514":"forthWeekMainICOBonusEstimate()","c78974de":"get_test_data_length()","c78982d5":"getIntervalCoefficient(bytes2,uint256)","c789ea87":"acceptFoundation(string)","c78a33e1":"DestroyEvent(address,uint256)","c78a4c98":"icoRaised()","c78a8dfe":"Kardanor()","c78ad77f":"percentage()","c78af2f7":"contributeByProxyContract(address,uint256)","c78b200c":"transferableFromBlock()","c78b616c":"totalListings()","c78bd060":"makeInvestment()","c78c0138":"timestamp_contract_start()","c78c3a83":"getPredictions()","c78cdf66":"mintTimelocked(address,uint256,uint32)","c78d7380":"COINECTToken()","c78d846d":"PTCToken()","c78dc603":"alt_buyCollectible(uint256,uint256,int256)","c78e139a":"setUpgradedContractAddress(address)","c78f3e18":"starteth()","c78fc487":"indexedByOwner(address,uint256)","c791316e":"minFundingAmount()","c791bd21":"AngelToken()","c791cc39":"BOECoin(uint256,string,uint8,string)","c791e16b":"platPriceOracleContract()","c792024a":"tierRates(uint256)","c79343e5":"isSYNVault()","c7939f34":"oddsTotal(uint256,uint256)","c79403f5":"moveFurnaceData(address[],uint16[],uint256[],bool[],uint256[])","c7941a09":"setDelegadoDeEscuela(bytes32,bytes32,uint8,uint8)","c794549e":"setDesignatedReport(bool)","c7946842":"URLOf(uint256)","c794ef10":"purchaseCostEther(uint256)","c794f575":"makeAnnualInvest(uint256)","c7956846":"get_solved(address)","c795dd24":"availableTokenBalance(uint256,uint8)","c7963ae8":"Tabo()","c7968135":"totalNumberOfFunders()","c798b5cf":"CommunityToken()","c7990f70":"SetDevFee(uint16)","c7995a4e":"_registerTrade(uint32,uint256)","c79a68cf":"setPrices(uint256,uint256,string,string)","c79ba27d":"kscTransferFrom(address,address,uint256,string)","c79bb895":"SGACrowdsale()","c79bdb46":"setRewardPercent(uint256,uint256)","c79c9105":"countOfPublicKey(bytes32)","c79eaa22":"sub(uint96,uint96)","c79f5321":"update_data()","c79f7cef":"_postValidatePurchase(address,uint256)","c79f8b62":"error()","c79fc609":"addressC()","c7a02061":"totalEtherCollected()","c7a08487":"_generateRandomDna()","c7a16847":"SetRewardMulti(uint256)","c7a16965":"testUint(uint256)","c7a1865b":"play(bytes32)","c7a1f221":"tokenPriceInCents()","c7a1fb36":"PRE_SALE_CAP()","c7a24403":"Illuminatus()","c7a28247":"stopBuyingTokens()","c7a2a663":"getCodeAtAddress(address)","c7a323fe":"ACTION_INITIAL_BIDDING()","c7a32726":"StartCrowdsale()","c7a37657":"getCfd(uint128)","c7a3778f":"testControlRetractLatestRevisionNotUpdatable()","c7a4af15":"setPrice(uint8,uint128)","c7a4cf8d":"checkOverMaxcap(uint256)","c7a4e4bc":"VIPCHAINToken()","c7a5d285":"extract(address)","c7a6c454":"confirmTransaction()","c7a6c6d4":"_creditTokens(address,uint256)","c7a86dd2":"updateEnergy(uint32,uint32,uint256)","c7a86e33":"signedApproveCheck(address,address,uint256,uint256,uint256,bytes,address)","c7a96920":"stopICO_20_March()","c7a9a64b":"depositNetfRevenue(uint256)","c7a9d6de":"startICO(address)","c7aa278e":"poolInvestors()","c7aaa83f":"Bounty0xToken()","c7abc42a":"getgamecard(uint256)","c7ac0909":"AddedName(address,string,uint256,address,uint256)","c7ac14b1":"dividendCutPercentage()","c7acae2e":"getServerAddress()","c7ad31b0":"LogHodlStartSet(address,uint256)","c7adb61f":"initializeTreeCoinProject(address,uint256,uint256,address,address)","c7adef28":"getCitationRecord(bytes32,uint256)","c7ae3ad5":"fillBuyOrder(uint256,uint256,uint256)","c7ae7451":"addEvent(address)","c7ae9632":"xfer(address,address,uint256)","c7af18f1":"SedPoSToken()","c7af3dd1":"updateCost()","c7afe9f2":"setTokenAddress(address,address)","c7aff0d7":"manuallyProcessTransaction(address,uint256)","c7b0235b":"DPPCrowdsale()","c7b0f0ca":"lockTokensPercent()","c7b0fc5e":"usedItem(uint256)","c7b11fca":"mainMaxContribution()","c7b160db":"getTotalNumberOfAddressesReceivedAirDrop()","c7b1fd00":"usdPerEthLogSize()","c7b23ec6":"initalizeOrgan()","c7b27a25":"IOReceipts()","c7b31ed0":"store(address,address,uint256,uint8,uint8,bytes)","c7b3b0d4":"getCompanyInfo(bytes32)","c7b41aa9":"getSmartCoins()","c7b43f02":"expressBuyNums(uint256,uint256[])","c7b5716d":"createSellOrder(address,uint256,uint256,uint256,uint256)","c7b6084c":"backendOperator()","c7b6ccae":"opetToken()","c7b6fd6a":"subDays(uint256,uint256)","c7b799ae":"addressFunc(address,address)","c7b7d6ca":"sendResearchAndDevelopment()","c7b81f4f":"isEpochDataSet(uint256)","c7b850dd":"whitelistedContributors(address)","c7b87d74":"setOldTokenAddress(address)","c7b97288":"addTokenEmission(uint256,uint256,uint256)","c7b98dec":"right1(uint256)","c7b9bc9e":"Token(uint256,string,uint8,string,string)","c7b9c355":"setSecondBonusPercent(uint256)","c7ba24bc":"claimAndConvert(address[],uint256,uint256)","c7ba9264":"KAL4Token()","c7bb38e7":"setAmount(bytes32,uint256)","c7bb42f7":"TEAM0()","c7bc747d":"retrieveTokenByContract(address,uint256)","c7bce243":"Menu05()","c7bdbb95":"allowTransferOwnership(bool)","c7bdcde9":"IYAKIN()","c7be44fa":"banReferrer(address)","c7be7ae3":"frozenSupply()","c7bec318":"removeAccountAddress(address)","c7c049fc":"saleGoal()","c7c0c5bf":"modifyMarking(bytes32,uint256)","c7c16353":"weiToRaise()","c7c2aa25":"WarriorsBackToHome(address,address,uint256)","c7c2aee3":"personalCap()","c7c3268b":"setBaseUrl(string)","c7c36959":"GubbermentOverthrown(address,address)","c7c3b1c1":"canTerminate()","c7c3b2dd":"setMockedTotalCollected(uint256)","c7c40fbb":"addPassportLogic(string,address)","c7c4ff46":"depositor()","c7c54e4d":"theEBCC(uint256,string,uint8,string)","c7c5f59d":"forBounty()","c7c625ee":"rand(address)","c7c6939c":"LongPlace(address[2],uint256[8],uint8,bytes32[2],uint256)","c7c7322b":"testCantInitiateIncorrectSale()","c7c7e9ea":"getAllowed(address,address)","c7c806cb":"ambassadorAddress()","c7c80f02":"teamLockUp()","c7c83804":"setFinancingsAdd(address)","c7c8b07b":"KillSwitch()","c7c8c424":"ownersEth()","c7c8ff35":"getNeutralMutationCost(uint8)","c7ca07bb":"QuantityAvailable()","c7cb94e3":"GenPlayerRatio(address,uint256)","c7cbb9c8":"_createArea()","c7cc3743":"addContractAddr()","c7cc4ee9":"later()","c7cc63aa":"getBetTitle()","c7ccc559":"upgrade_cap()","c7cd31d5":"setLLV_edit_23(string)","c7ce060b":"publicDeductDeposit(address,uint256)","c7ceac99":"calculateBattleBoost(uint16,address,address)","c7cec7f8":"versions(bytes32)","c7cefbf1":"IDH()","c7cf28fe":"canClaimTimeout()","c7cf6a2a":"LJSToken()","c7cf8075":"getAvailableDevFund()","c7d044be":"AutoChainToken()","c7d128d1":"readTotalNumberOfUserPurchases(address)","c7d20f82":"addMeterpoint(address,int256)","c7d22929":"betOpen(uint256,string,string,string,string)","c7d26e90":"getAccessoryClaims(uint64)","c7d4f68e":"getRobotForUserByIndex(address,uint256)","c7d586c9":"provideProofOfWork(uint256)","c7d5b6f1":"cancelSellOffer()","c7d5c0af":"XVOTOKEN()","c7d5d171":"costRecharge(uint256)","c7d5dd36":"Factory(address,address)","c7d6e988":"fundOwnerWallet()","c7d6faf1":"easyPropose(address,uint256)","c7d77970":"registerNameXaddrFromDapp(address,bytes32,address)","c7d7b5a6":"fillOrder(address[5],uint256[6],uint8,bytes32,bytes32)","c7d96304":"canMateWithViaAuction(uint256,uint256)","c7d9f4d1":"transferableBalanceOf(address)","c7da93b7":"specialTransfer(address,uint256,uint256,uint256)","c7daae0a":"firstFreeAddressIndex()","c7dab436":"vestingTime()","c7daceb1":"acceptBuyNowOffer(uint256)","c7db04d7":"SelfDestructManager()","c7dbbc47":"nextTicket()","c7dbc2be":"minimumPodSize()","c7dd4b4f":"gameID()","c7dddf0f":"itemHistoryOf(uint256)","c7de2d13":"WithdrawToken(address,uint256,address)","c7dea777":"areOldMiningKeysVoted(uint256,address)","c7deda22":"Doug()","c7df0a90":"all_eth()","c7df9054":"getBuyUnitsInformations()","c7dfabcc":"Buy(uint8,string)","c7e04670":"publicSaleTokenPrice()","c7e0635d":"AGENT_STATUS(bytes32,address)","c7e09d9c":"getSides(uint256)","c7e12723":"Erc20Test(string,string,uint8)","c7e210c3":"optionPoolMembersLockTotalOf(address)","c7e22ac4":"setOracleGas(uint256)","c7e284b8":"getTimeLeft()","c7e293d9":"allocateFunds(address,address,uint256)","c7e35a5c":"LOCK_START()","c7e3b6e8":"airdropAndVault()","c7e3ff4b":"pregnantMonsters()","c7e40b3a":"StatXCoin()","c7e416c5":"LOG_SuccessfulSend(address,uint256)","c7e4f453":"TokenFactoryImpl(address)","c7e50dc9":"isLOC(address)","c7e52480":"convertYourTokens()","c7e56740":"_getIndex(address,address)","c7e58644":"getSharesCount()","c7e59334":"toggleAttachedEnforcement(bool)","c7e5fc3b":"GlobalTechToken()","c7e67360":"GAS_BUFFER()","c7e6926e":"_airdropTotal()","c7e6d04f":"ownerConfig(address,uint256,uint256)","c7e73adf":"getParticipantSource()","c7e83451":"matchMultipleOrders(uint64[],uint64[])","c7e92738":"MicroBTC()","c7e975b8":"partner2_voted_update_marriage_status()","c7e9aaaf":"_isSiringPermitted(uint256,uint256)","c7ea07bb":"SealTokenSale(address,address,address,uint256,uint256,uint256,uint256)","c7ea8a68":"EOSToken()","c7ebc8fe":"getWinnings(address,uint256,uint256)","c7ed1e86":"getNoOfMsgs(address)","c7ed4555":"DepositSlot(address)","c7ed4d8c":"distributeVM(address[],uint256,uint256)","c7edaf33":"TheGoDgital()","c7edf88c":"DOW_SAT()","c7ee005e":"prime()","c7ee1c4e":"getPreviousSeed()","c7ee98c2":"trustedBurnTokens(uint256)","c7ef47d7":"isKill()","c7efa689":"getSaleDay(uint256)","c7efb162":"setup(address,address,address,uint256,uint256)","c7efb8ab":"ledger(address,bytes32)","c7f04e65":"purchase(uint32)","c7f132d5":"QuarterCoin()","c7f18d5b":"updateData(uint256,uint256,uint256,uint256,uint256,bytes,bytes)","c7f24b11":"getCCH_edit_8()","c7f2c3d9":"EasyInvest10()","c7f2e6af":"Contribute(bytes20)","c7f300ed":"CrowdSale_ModifyEndDate(uint256)","c7f3166d":"getBetInfo(uint256,uint256)","c7f31f1c":"HandWins(address)","c7f36010":"setupClaim(uint256)","c7f423c7":"setLeaf(uint256,bytes32)","c7f42c64":"battleFee()","c7f43b57":"TIER2_CAP()","c7f46dea":"testRewardBS(bytes32)","c7f5f1e8":"DistributeNextNTokens(uint256)","c7f6f40c":"updateKYCStatus(uint256)","c7f6fa60":"EIDTokenERC20()","c7f71103":"futrMiner()","c7f7475c":"AdminGroup(string)","c7f758a8":"getProposal(uint256)","c7f7be5c":"setGxCoinContract(address)","c7f84605":"___upgradeTo(address)","c7f86c37":"withdrawFundsRP()","c7f8fe65":"getBalanceReleased()","c7fa1d47":"Hedge()","c7fa52de":"setRegistryAddr(address)","c7faa88d":"collectProfit()","c7fb9aab":"displaymultisig()","c7fbad27":"revealStart()","c7fc9ace":"WorldNode()","c7fccd3f":"isAuthorizedForToken(address,address,address)","c7fde81f":"changePOI(address)","c7fe11d4":"_createCaptainToken(address,uint256,uint32,uint32,uint32,uint32,uint32,uint256)","c7fee63e":"updateRate()","c7ff1584":"isHalted()","c7ff1b60":"maxCapReached()","c7ff2086":"getPropertyColorsOfRow(uint16,uint8)","c8004293":"lastKnownPropertyAddress()","c80094b3":"testEquals()","c8016c85":"MAIN_SALE_BONUS_PERCENTAGE_PHASE1()","c8027210":"Malaysia370()","c8028bee":"auditorRegistry()","c803486b":"getAvailableFunds(address)","c803ae2a":"kycComplete()","c803f981":"care(uint256)","c8045941":"changeDescription(string,string)","c8046827":"registerBurn(uint256)","c804a58e":"toggleRefunding()","c8051885":"isWithinContributionRange()","c805801c":"VoipTken()","c805914a":"setRespectRequiredToRecruit(uint256)","c805b6bc":"PRESALE_TOKEN_HARD_CAP()","c805f68b":"setRelay(address)","c806286d":"setFreeze(uint256,bool)","c80667e3":"appendUintToString(string,uint256)","c80675de":"sendDiamond(address,bytes32,string,bytes16,uint256)","c806a91d":"TOKEN_TOTAL_CAP()","c80743c5":"maximumTokenAmount()","c807be58":"endTimeSale2()","c807cb02":"Uninjected(address)","c807e645":"JECKAirdrop()","c8081bd2":"requestMutualJobCancellation(bytes16,address,address,uint256,uint256)","c8088830":"_canPayOraclize(uint256)","c808cf86":"exchangeHelenium(uint256,address)","c80944e5":"buildRight(address,uint256)","c80a589b":"withdrawTokenBalance(uint256,address)","c80bbb17":"ReserveFund()","c80becb6":"enablePreSale()","c80c14a5":"getBankBalanceWEIInfo()","c80c28a2":"getNumberOfParticipants()","c80d3694":"saleWeiCap()","c80db88c":"getSchellingExpansion(uint256)","c80e0ddd":"saveCode(uint256,string)","c80e3e1e":"SingularityTest23()","c80ec522":"withdrawn()","c80f9a4f":"transferPokemon(address,address,uint256)","c81050e6":"checkBranchInEpisode(uint256,uint256)","c8117b5b":"extractBalanceOfLength()","c81196da":"numberOfMilestones()","c8135ba1":"bids_decrypted_count()","c813c30e":"testThrowSomething()","c813e02e":"_isLeapYear(uint16)","c814324c":"timeBought(address)","c81450a0":"RaffleResult(uint256,uint256,address,uint256,uint256,bytes32)","c814864c":"CreateChips(uint256,uint256,uint256,uint256,bool)","c8149cbc":"setMigrationLock(bool)","c8159d70":"Seriality()","c815c9ef":"TerraEcoToken()","c8162068":"setTeamAddr(address)","c8162497":"BETX()","c8166a8a":"Question()","c817d75d":"Transfer(address,address,uint256,uint256,uint256)","c817e84d":"addWhitelisted(address,bool)","c8187cf1":"determineReward(uint256)","c818acf7":"createCloneToken(address,uint256,string,uint8,string,bool,address)","c818faec":"updatedAt(uint256)","c8193841":"addSoftwareVersionRecord(bytes32,bytes32,uint256)","c8199231":"createContractTot(string,uint256)","c8199826":"buyTickets()","c819f6e9":"levToken()","c81a5455":"Milestone_CloseTheIco(string)","c81a7d10":"CurryCoin()","c81bd106":"approveNewOwner()","c81c590d":"getEtherAmount(uint256)","c81caae7":"acceptMember(address,string,string)","c81cbc5c":"MIST()","c81cf764":"getAmountFromBuyer(address,address)","c81d1d5b":"getPunk(uint256)","c81e05ad":"KODO()","c81ede67":"pollBurnQty()","c81f49cb":"getTotalPaid(address,uint256)","c8216f33":"getLineUpEnable_default()","c8226e61":"withdrawEgereg(uint256)","c822bd3d":"transferCost(bytes16,uint256)","c822d7f0":"isRegistered(string)","c8234ac8":"createTokenUri(uint256)","c82467c9":"ComputeTokenPrice()","c8248f8d":"PreICO(address,address,address,address,address)","c824a222":"auctionsOf(address)","c82531a3":"createAuction(uint256,address,uint256,uint256,uint256,address)","c825a939":"fundingRatePredictionBonusPoolInIBC()","c827a7bb":"testExternal(uint256[20])","c82829e0":"setSoftHardCaps(uint256,uint256)","c828371e":"getStartTime()","c828e6ee":"getCurrentlyClaimableAmount(address)","c8290efd":"zen()","c8291dbd":"increment(address,address)","c829958c":"isImported(address,address)","c8299b10":"gotransfer()","c8299ed8":"afterClaim(uint256,uint256,uint256,uint256,uint256)","c829b0e3":"MAX_LAYERS()","c82aac47":"searchByTag(bytes32)","c82b8ec5":"EtherDaruma(address,address,address,uint256,uint256,uint256)","c82bb37b":"PotSplit(uint256,address,bool)","c82bd265":"ContributionAccepted(address,uint256,uint256)","c82c73c1":"isAddressSet(address)","c82cd8e6":"ControllerRetired(address)","c82d81dd":"GICAToken()","c82db402":"ownerSetOraclizeGas(uint256,uint256)","c82f2418":"decodeTokenOrderTokenAndIsBuy(uint256)","c82f8d9e":"distributeToken(address,address,uint256)","c83068eb":"setPre(uint256,uint256,uint256,uint256,uint256)","c8306c89":"set_arbits(address,address,uint256)","c830b89d":"ReleaseDateChanged(address,uint256)","c830c656":"increasePermillage()","c83126ed":"generateVoteForDelegationSchemaHash(uint16,address,bytes32,address)","c831306e":"icoTimeBonusPhase2End()","c831391d":"getPoolOverlapSize()","c83261bd":"claimTokenFor(address)","c83281e9":"UserAccount(bytes32,bytes32,bytes32,bytes32,bytes32)","c832b00d":"limitDateCrowdWeek3()","c8335143":"AlekseiZaitcevPrivateSale(uint256,uint256,uint256,address)","c8335ba0":"setInitSize(uint256)","c833d7b1":"BigbomContributorWhiteList()","c834d03d":"verifyTx(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[3])","c83507a8":"removeAdv(address)","c836292b":"teamMembers(address)","c836efcb":"_permitted()","c83780a2":"crowdsaleCounter()","c838ccb6":"getDelegates()","c839008e":"setPixelPropertyContract(address)","c8391142":"j1Timeout()","c83923c5":"getMetadataChannel(string)","c83927a0":"pdo()","c8393ba9":"initiateWithdrawal(address,uint256)","c8398947":"currentStateActive()","c839c0de":"CreateVersion(bytes,string)","c83a7e94":"AEToken()","c83a9472":"deathData_a11()","c83a981c":"openPool(uint8)","c83abb40":"registerNotary(address,string,string,string)","c83ac557":"ChangeCommunityHolder(address,address)","c83be888":"single_move(uint256,uint8,uint8)","c83cb16c":"_not(bool)","c83ea900":"soldDET(address,uint256,bytes32)","c8401567":"betbucketTwo()","c840b187":"goodsNotReceived(uint256)","c841df4f":"getMonsterStats(uint256)","c8420d2f":"CollectibleIndex5()","c8422c2d":"boostrapParty(address,address)","c8435ba2":"levelOneTokenNum()","c843c0c8":"getMyAlien()","c8443fad":"revokeExchanger(address)","c8449b65":"Gold()","c84640f5":"addtotalCardValue(uint256,uint256)","c846690b":"initialiseToken()","c847259c":"changeClub(address)","c84748f9":"returnFrozenFreeFunds()","c848a0bc":"notifySellToken(uint256,address)","c848fab7":"SeeleToken(address,address,uint256)","c84920cb":"Ubisoft()","c84a6140":"BackdoorBurner(uint256,string,uint8,string)","c84a8766":"setRegionImageDataCloud(uint256,uint256,uint256,string)","c84aba9b":"demurrageBalance(address,address)","c84b0555":"token(address,string,string)","c84b1ce7":"PUBLIC_RESOLVER_LABEL()","c84b470f":"SALE_PERCENTAGE()","c84ba84a":"finishedPurchase()","c84c009b":"Operated(address)","c84c5963":"setPauseCutoffTime(uint256)","c84c692a":"isTradableFciInSession()","c84c9ef5":"LastName()","c84ca867":"getCurrentPriceAttoTokensPerWei()","c84cda0f":"setRate(string,uint256)","c84d56e0":"setRealmSale(uint256,uint256)","c84eb9e5":"invest(address,bytes)","c84f5d6f":"RowanCoin()","c850029e":"returnTokenOwnership()","c85147c5":"mediumCount()","c8517b48":"CNDTTokenDeposit()","c851b643":"legendsToken()","c851ed7c":"startNewVote(uint256,string)","c8520131":"Withdrawable()","c85234c7":"startPreICOStage3()","c853c03d":"newDraw(uint256,uint8[3],uint256,uint256,uint256,uint256)","c8544e81":"addGenesisPairs()","c854db91":"vault_refund(address)","c85501bb":"minThreshold()","c855d689":"returnLongAddress(bytes32,uint8,bytes32[2])","c855e7bb":"tokenForTeamGranted()","c8578967":"setNewChecker(address,address)","c857a88c":"createDataRequest(address,address,uint256,uint256)","c8582572":"affiliateCommission(address)","c8583ad6":"UnregisteredPrefix(string,address)","c8583e69":"getEthUsdRate()","c858c017":"testMsgSenderInVoters()","c859c482":"holdBalanceOf(address)","c85aff48":"tokenNAVMicroUSD()","c85b7941":"totalEthBankrollReceived()","c85bb02a":"isParticipating(uint256,address)","c85bb1f7":"_doMapAuto(address,string)","c85bc22d":"getDefrostFactor()","c85c11eb":"TOKEN_SECOND_PRICE_RATE()","c85c75b2":"completeCodeUpdate()","c85dba67":"getPrefix(uint32,int256)","c85e07b9":"stamp()","c85e0be2":"setHost(address)","c85e1f73":"totalRecalled()","c85ee477":"FileCoinCash()","c85f6a80":"emission(address)","c85fd4f8":"deployToken(string,string,uint8,string,address,bool,address)","c86039da":"redeemedSupply()","c8612b2f":"TOKENS_FOR_SALE()","c861f243":"_getBonus(uint256)","c861f3a0":"houseStake()","c86283c8":"withdrawTo(uint256,address)","c862a134":"feePercent_()","c8643bc2":"MintOperationEvent(address,uint256,uint256,uint256)","c864e760":"recordCommissionEarned(uint256)","c865164b":"StakingPriceFeed(address,address,address)","c865c29b":"HopiumCoin()","c865cadb":"setActiveValueBonus(bool)","c86662a3":"addOwner_(address)","c86779a4":"lastBlock_v14()","c867cccb":"Contribution(address,address,address,address)","c867ea63":"GoldConnect()","c867fa29":"BookERC20EthV1p1Factory()","c86813a8":"PassContractorCreator()","c8685f21":"validUsername(string)","c868a569":"canBreed(uint40,uint256,uint40,uint256)","c8690233":"pubkey(bytes32)","c8691b2a":"getHistory(uint256)","c8695e59":"RPS(bytes32,address)","c86a90fe":"sendCoin(uint256,address)","c86a9dea":"isKickoffEnabled(uint256)","c86b7001":"randomOrgAPIKey()","c86c50f7":"changeAllowInvestment(bool)","c86d0251":"_getTeamSupportAmount(uint256,uint256)","c86dca5a":"isExploring(uint256)","c86e25d7":"tokenCreateContract()","c87022d3":"startMonarchyGame(uint256)","c8705544":"payAmount()","c870ef78":"MINING_POOL_HOLDER()","c8713608":"HELIX()","c87158fa":"_addBlockProducer(uint256,address)","c87235fd":"burnRemaining(address)","c872da3c":"KIND()","c8738351":"uintFloor(uint256,uint256)","c8744434":"lastTransferQueueIndex()","c8750d8a":"testHitSoftCapPresale()","c8756f12":"getTotalSponsorship()","c875b1fb":"distributeBonuses()","c875d16f":"ArthurStandardToken(uint256,string,uint8,string)","c8765ff2":"rateICO()","c87744d9":"_approvedForTransfer(address,address,uint256)","c8781368":"freezedMoment()","c8788134":"discountedPrice()","c878851d":"setCreate(bool)","c878dad9":"multiFreeze(address[],bool[])","c8796572":"collectFees()","c87a31cd":"fillOrder(bytes32,address[5],uint256[6],uint8,bytes32,bytes32)","c87b36ed":"disableBetting()","c87b56dd":"tokenURI(uint256)","c87be1af":"recoverHashSigner(bytes32,bytes)","c87c07de":"deprecateMeleeSubtype(uint8)","c87cfe63":"setData(uint256[])","c87e5613":"setMaxTokenBuyin(uint256)","c87e8bd0":"icoRound6()","c87f9386":"setAllItemActive(address,address,bool)","c8804b7b":"DSC()","c88098f2":"setParticipationFee(uint256)","c880fab1":"dragonTreasureToken()","c8813ffd":"addToVIPList(address[])","c881b3c0":"AllowedGasPriceUpdated(uint256)","c88215e7":"calculateExcessBalance()","c882acc8":"deleteMemberOfGroup(address,uint256)","c882ee8c":"testUint(int256,uint256)","c882ef92":"GameOpened(uint256)","c8830ddf":"ECryptoToken()","c883346e":"_getProviderIsForRent(uint256)","c8833f56":"setTiersInfo(uint8,uint256[],uint256[],uint256[],uint256[],uint8[2])","c883d3fa":"addMappingForPlayerIDs(uint256,uint256,uint256)","c88449a1":"_getTransferFeeAmount(address,uint256)","c8852b5b":"getBirthCut(uint256)","c8857dcd":"setOperateMode()","c885bc58":"withdrawReward()","c885e92d":"contlength()","c8860f41":"getWinningChoice(uint256,uint256)","c886594d":"getNodeEnabledStatus(address)","c8865c0e":"allocated24Months()","c886ec0d":"getTreasureProbabilityType(bytes32)","c888fafd":"bankerDepositPer()","c888fcc3":"getPollResult(uint256)","c8894a0c":"WMToken(address,uint256)","c88961da":"createKingdom(string,address,address,address)","c88996d6":"MessageCallTransaction(bytes,uint256,uint256,address,uint256,uint8,uint256,uint256)","c889e0de":"finishAirdropBy0Eth()","c88b675b":"setMaxAvailableSpot(uint256)","c88b77e0":"grantTeamAdvisorToken(address)","c88b7c8e":"setConversionFee(uint256)","c88bf75a":"applyRaises(uint256[])","c88c5101":"investor_bonus()","c88cc6ac":"getCertification(address)","c88e662e":"externalSales(address,uint256)","c88fd3ec":"changeIcoRate(uint256)","c88fe1fa":"maxCapMintTransfer()","c890635a":"ownerSale(address,uint256)","c890f27e":"GenChipByWeight(uint256,uint8,uint256[])","c891a29d":"setEpochData(uint256,uint256,uint256,uint256[],uint256,uint256)","c8922057":"MAXUM_SUPPLY()","c89231b3":"mintForInvestor(address,uint256,uint256)","c892693b":"setMotAddress(address)","c892cfdf":"amountRised()","c8931355":"setONTExchangeRate(uint256)","c893ae0b":"ptToPtwo()","c894e1e5":"setTransferFeeRate(uint256)","c895304b":"newDaoRulesProposal(uint256,uint256,uint256,uint256,uint256,bool,address,uint256,uint256)","c89547f9":"adminSetTxFeeInviteGame(uint256)","c89550a8":"BMICoin(address,address)","c89605a2":"DEALERWIN()","c8961644":"unBan(address)","c89924da":"totalTokensForSaleDuringICO2()","c8997121":"forwardFunds(uint256)","c899fa77":"hodlerTotalValue3M()","c89a32ab":"releaseTargetToken(uint256)","c89acc86":"send(address,bytes)","c89b50c7":"credit(address[],uint256[])","c89b7d8c":"buyCommonTTWByETH(uint256,address)","c89b989e":"lckTokenAddress()","c89baff5":"GoldenGate()","c89cea99":"getMyAnts()","c89d6063":"claim(bytes32,uint256,address,uint8,bytes32,bytes32,bytes32[])","c89dcfce":"mint(address,bytes32,uint256)","c89e4361":"delegate()","c89e528e":"receiveCreateAuctionFromArray(address,address,uint256[],uint256,uint256)","c89ec68a":"startRecovery(address,address)","c89f2ce4":"funds()","c89f51ef":"createPromoRabbit(uint256,address)","c89f8f08":"testGetController()","c89faa72":"confirmTransferItem(address,address,string)","c89fb5f0":"ethunpause()","c89fcf58":"setNoviceDungeonId(uint256)","c8a1becb":"_monthToNumber(string)","c8a1e1c7":"sendInternally(address,uint256)","c8a2c880":"setCallStack(uint256,uint256)","c8a2cc03":"strikersMetadata()","c8a2e0bc":"addCustomerReqACC(address,address,address,address)","c8a45c44":"tokenMaturityPeriod()","c8a48d71":"removeStep(bytes16)","c8a4ac9c":"mul(uint256,uint256)","c8a4c767":"kickCommitteeVote(address)","c8a4ddc3":"resetBatches(address,address)","c8a4e001":"EarlyPurchaseAmended(uint256)","c8a5e6d7":"transferFundAndEndGame()","c8a635b7":"setWeiRate(uint256)","c8a6dab7":"test_tokenFreeze()","c8a71e14":"bonusCalculationFactor()","c8a73eca":"transferOpen()","c8a7432f":"getPreIcoPurchase(address)","c8a76494":"Bet()","c8a808d6":"avatar(address,address,uint256,uint256,bytes)","c8a814b8":"firstSend(bytes32)","c8a830ba":"max(uint256)","c8a83384":"allowBurns()","c8a90f76":"handlePresaleToken(address,uint256)","c8a9e841":"addCustomerFromKYC(address)","c8aafbc3":"NodeHash()","c8ac7014":"updateMerchantByAdmin(address,string,string)","c8ad27e6":"finishPre()","c8ad9645":"InactivityHolderResetBalance(address)","c8aded5d":"setDiscounts(uint256[],uint256[])","c8ae8774":"_startMegabox(uint256)","c8aef513":"preSendTTC()","c8aeff39":"isMarket()","c8af1538":"fallbackPayout()","c8af46b4":"canAnyoneBurn()","c8b08125":"tokensRemaining()","c8b0e68d":"getCEO()","c8b18b5b":"oneMonth()","c8b19fa8":"ioxToken()","c8b1a635":"pricePerCoin()","c8b21f18":"distributionuserFinished()","c8b26773":"startEnrollment()","c8b2ccba":"addStrand(uint256,address,bytes32,string)","c8b32089":"TokenLiquidityMarket(address,uint256,uint256,uint256)","c8b342ab":"getBid(address)","c8b35c7a":"BANANA()","c8b39eb5":"setEdCoreContract(address)","c8b413ad":"initialize(address[5],address,uint256[12],uint256,bytes)","c8b43c10":"isPausedCrowdsale()","c8b4c5b8":"MarketToken(uint256,uint256)","c8b4eb6e":"withdrawPresale(address)","c8b52bfb":"ChangeCost(uint256,uint256)","c8b56bda":"unregister_contract(bytes32)","c8b5da66":"pressButton()","c8b6a463":"ASUT()","c8b70559":"_endContestIfNeeded()","c8b7c3ee":"MITCoin()","c8b7e8c3":"testMakeBet()","c8b82220":"registerNameIP(string,string)","c8b91531":"MINOR_VERSION()","c8bb73ef":"testGetBitsFailIndexOOB()","c8bb7d51":"unitRareGrowth()","c8bc2452":"LuJiaZuiToken()","c8bc429a":"removeDividendPathway(address,uint256)","c8bc6fa0":"maxCapEth()","c8bd14ef":"totalInvSupply()","c8bd1d13":"VERIME(address)","c8bd3782":"OsherCurrentICOPrice()","c8bdbfb6":"withdrawUnsoldTokens()","c8bdc0c7":"RevokeDOT(bytes32,bytes)","c8bf3388":"totalIRCAllocated()","c8bffa93":"tier1End()","c8c01a55":"request(address,uint256)","c8c08a89":"_isOfficialApps(address)","c8c0b288":"bountyFundManager()","c8c0cbbb":"setLockedAccountThresholdUsd(uint256)","c8c1a400":"infoAboveSpot()","c8c21594":"releaseByStage(address)","c8c2ed54":"tokenAssignmentControl()","c8c2fe6c":"acceptManagement()","c8c365fc":"nowday()","c8c388eb":"RegBase(address,bytes32,address)","c8c3b926":"changeDragoDao(address)","c8c5139d":"setUserDisplay(address,string)","c8c67ca1":"transferValuebyAddr(address)","c8c719d2":"MangachainToken(address,address,address,address,address)","c8c72bb4":"TEAM_RESERVE_FTX()","c8c749ec":"preTgeManager()","c8c75647":"setVerified(address)","c8c79643":"addBurningMan(address,uint256)","c8c89fa5":"secretBids(address)","c8c9b1f8":"shouldVerifySegment(uint256,uint256[2],uint256,bytes32,uint64)","c8c9d745":"userLookup(uint256)","c8ca645f":"getName(string,string,address)","c8cada78":"oraclize_query(uint256,string,bytes[2])","c8cb60bb":"cancelBid(bytes32,uint8,int32,bool)","c8cb7d04":"Kristina()","c8cb8677":"WithdrawMyTokens()","c8cb8a75":"setCreator(address,uint256)","c8cb985a":"callDividend()","c8cc5cd8":"distributeYield(uint256)","c8cc9cc2":"getElement(address)","c8ccaebc":"extendedTimeLock()","c8cd09ae":"TransferredPreBuyersReward(address,uint256)","c8cd65e5":"processDeposit(address,uint256)","c8cddd61":"test_validShouldBe3_increaseTimeBy30000()","c8ce122b":"checkJackpot(address)","c8ce2fec":"lifetimeDeposits()","c8ce30b0":"blocksForWei(uint256)","c8ceaa95":"mint(bytes32,int256,address,uint256)","c8ceae12":"tavernContract()","c8cf4722":"getRequestsLength()","c8cf67a1":"buySmartSpeed()","c8cfb032":"getPlayerByAddr(address)","c8cfd490":"UNLOCK_TEAM()","c8d0ec0a":"reduceAllowance(address,address,uint256)","c8d172d6":"getTokenInfoNonce()","c8d1c017":"addUIntValue(bytes32,uint256)","c8d1cf4a":"tokenPriceForMainICO()","c8d3db82":"getPresaleMaxValue()","c8d47f16":"replaceLogic(address)","c8d4b389":"approveAndCallPreSigned(bytes,address,uint256,bytes,uint256,uint256)","c8d508fa":"test_insert_findNoHintUpdateTail(int256)","c8d50d7c":"nextBackWindowAdjustmentRatio()","c8d52ee3":"refundTransfer(address,uint256)","c8d61985":"setCryptoAgent(address)","c8d689b1":"addAllowedLock(uint256)","c8d840fa":"EventEmergencyContinue()","c8d86e35":"bullToken()","c8d88829":"oslikiFoundation()","c8d8cf88":"appIndex()","c8d942b5":"Travelerscoin()","c8d9c042":"AuctionCreated(uint256,uint256,uint256,uint256,bool)","c8d9ebc4":"getTomato(uint8)","c8db6a42":"functionCalling(address)","c8db6af9":"getCompte_14()","c8dc60ca":"vehiclesByCity(bytes32)","c8dc7e19":"setReconciliationDate(uint256)","c8dd64ea":"daVinciAddress()","c8dd6ce7":"getPlayerDetails(address)","c8dda301":"VOTING_START_BLOCKNR()","c8dda71c":"HistoryUpdated(string,uint256[])","c8ddf66f":"MMChainToken()","c8df5da0":"BOSHICoin()","c8e0f101":"userPlay()","c8e11521":"TripBitToken()","c8e13bb4":"fit()","c8e1fe3f":"getCountriesOfCampaign(bytes32)","c8e2190d":"_cancelOperation(bytes32,address)","c8e2fca0":"use(address,address,uint256,uint256,uint256,uint256,uint256,string)","c8e32074":"returnFrom(address,uint256)","c8e49707":"activateExportFee(address)","c8e4acef":"playerByAddress(address)","c8e55708":"oraclize_query(string,string[1])","c8e566c6":"betInputToBytes(uint40,uint40,uint40,uint40,uint40)","c8e569a8":"stopICO()","c8e56acb":"FAPFundDeposit1()","c8e5f54f":"ArcanaToken()","c8e626f8":"checkDivsBalance()","c8e6b2a8":"logTimestampSet(uint256)","c8e6ba4d":"verifyTx(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[])","c8e6c7d9":"imin(int256,int256)","c8e706e2":"contractWallet()","c8e71424":"MotherDNAShare()","c8e788c1":"RELEASE_EPOCH()","c8e7ca2e":"getMsgData()","c8e7e5ef":"TOTAL_NUM_TOKENS()","c8e8ce63":"outsourceConfirmNode(uint256)","c8e8d6d6":"TheTokenE()","c8e8f487":"missedVerificationSlash(uint256,uint256,uint256)","c8e9fc8b":"testgas()","c8ea0cfa":"CoinmakeToken()","c8ea1f7f":"updateEntity(uint256,bytes32,uint256,bytes32,uint256)","c8ea429e":"closeCdp(uint256,uint256,uint256)","c8eab537":"randomJackpot(uint32,bytes32,uint32)","c8eb747a":"B42Token()","c8ec2eb8":"MUBEX()","c8ec57ed":"revokeConfirm(bytes32)","c8ed6253":"ManagedToken()","c8ede712":"makersAverageRating(address)","c8edf65e":"GetAndReduceFeesByFraction(uint256)","c8ee0c6b":"withdrawBySubscription(address,uint256,bytes32,string)","c8ee2da8":"setReputationIRNNodeShare(uint256)","c8ef8b00":"window2TotalSupply()","c8efd7af":"getResolverFee()","c8f07770":"funcThatReverts()","c8f09634":"visaOfferingsLength(uint256)","c8f099cb":"upgradeEvilMorty(address,address)","c8f0d741":"AlienFarmer()","c8f21d22":"TagadaTsoinTsoinCoin()","c8f2835f":"transferBack(address,uint256)","c8f288ad":"getPoo(uint256)","c8f3a9e1":"getLastRollOutput(address)","c8f3e5f0":"getParameterByTitle(bytes32)","c8f41706":"pausePhase()","c8f478e1":"SetChangePlatformFlag(bool)","c8f490c8":"numOfBalloonsTypes()","c8f5c3f9":"LNCHSale(uint256,uint128,uint256,uint256,uint128,string,uint128,string,uint128,string,uint128,string,uint128,string)","c8f5d8b0":"total_coins()","c8f803f8":"setUnitJadeStealingMultiplier(address,address,uint256,uint256,bool)","c8f87d36":"_register(uint256,address)","c8f88076":"emissionMasOneType(address[],uint256[],bytes32[],uint256)","c8f8d75d":"Config(uint8,address)","c8f98db8":"getWinningFaction()","c8fbbdda":"getGPSStartTime()","c8fca35e":"getBidHash(uint256,uint256,address,address,uint256,uint256)","c8fd39f7":"GetEthShop()","c8fd6ed0":"unstake(uint256,bytes)","c8fdc891":"numberOfMonarchs()","c8fddb80":"updateLemonCoinsRemainingToDrop()","c8fdf67d":"holdTransaction(uint256,uint256,uint256)","c8fe2065":"getSingleBetItemCount(uint256)","c8fea2fb":"collect(address,address,uint256)","c8fed3f6":"withdrawCashReserveFund()","c8ff80a1":"setMonsterClass(uint32,uint256,uint256,bool)","c9000726":"nextStep()","c90109fa":"removeSomeCWCsFrom(address,uint256)","c90189e4":"fechAllVoteResultPreStageByBlock(uint256)","c902c3ae":"bets(bytes32)","c902d1b6":"_checkClientSign(address,bytes32,bytes)","c902ee36":"tokensAvailable(address)","c9030ea0":"addMember(address,bool)","c904a2ee":"minAllowedReservingPercentage()","c906a5aa":"testDeleteVoter()","c906baa3":"GACFund()","c906c873":"limitCrowdsale()","c906cd68":"ForceCoinTransfer(address,address,uint256)","c90755e2":"secretaryGeneral()","c90763f0":"subAllocation(address)","c9079673":"last_payment_timestamp()","c90797ea":"suicideContract(address)","c907d53b":"getTakeOwnershipFee(uint256)","c9085820":"set_owner(bytes12,address)","c908f302":"searchPursesByAddress(address)","c9090c7f":"levelFourTokenNum()","c9099385":"addApplication(string,string,string,string)","c909b929":"closingTimePeriodTwo()","c90a6a8e":"MAIN_SALE_BONUS_PERCENTAGE_PHASE4()","c90c205b":"CLAIM_AMOUNT_ETH()","c90c589a":"OAR()","c90c949b":"checkForBonuses(uint256,uint256)","c90cfb0b":"newFact(string,string)","c90d080a":"registerEvent(bytes)","c90d1431":"MYLASTTOKEN()","c90d2cd9":"createBallot(uint256,address,string,string)","c90de215":"ClockAuction(address,address,uint256,uint256)","c90f34f0":"Bitstarti(uint256,string,string)","c90f793e":"currentAgreement()","c90fc8ee":"allTotalSupply()","c90fda80":"countRC(address)","c9100bcb":"getClaim(bytes32)","c9101f6c":"increaseApproval(uint256,address,uint256)","c9102029":"_getTokens()","c9116b69":"myBalance()","c9116e4a":"yearThreeClaimed()","c911b56e":"isController(address,address)","c913b552":"getVersions(bytes)","c913f364":"addMoonPrizePool(uint256,uint256)","c914ef54":"SetAllow(address)","c91540f6":"getCurrentCompetitionValues(string)","c915fc93":"proposeUpgrade(address)","c91610cd":"transferDelegator(address)","c91752b2":"girlIdToAuction(uint256)","c91813ca":"testToBool(bytes)","c919992d":"changeBrokerImp(address)","c91b0149":"setWhitelister(address,bool)","c91b46c6":"claimHero()","c91bc856":"withdrawCAT()","c91c6fa5":"completeSupply()","c91ca6c7":"calculatePeerTokens()","c91cd9d0":"minimumNumber()","c91d7e9c":"getFee(bytes32[])","c91d956c":"setMinBalance(uint256)","c91e4cc8":"getItemsByTypeAndOwner(string,address)","c91fc619":"getTotalOut(address)","c92015f6":"getAccountUnlockTime(address)","c9206ddf":"setSalvageable(address,bool)","c9219a7a":"verifyProof(uint256[2],uint256[2][2],uint256[2],uint256[8])","c921f647":"GiftSend(uint256,address,address,bytes32,string,bytes16,uint8,bytes24,uint16,uint16,uint256)","c92261b5":"set(bytes32,int256)","c922f446":"emergencyWd()","c9230c5d":"assetName()","c9247058":"MasternodeRewardAddedToRewardPool(uint256)","c924c524":"secondSend(bytes32)","c924d441":"EnableTokenWithdrawals()","c92501b7":"setStopTime(uint256)","c926435c":"bonusInfo()","c926aae6":"kscSell(address,address,uint256,string)","c9270652":"returnLoanLength(uint256)","c92728a1":"_ballotIdToNamespace(uint256)","c9295bc6":"getOrgInfo(address)","c9296d14":"scheduleTransaction(address,uint256,uint256,uint256,bytes)","c929bdac":"notaioAccounts(address)","c929ccf3":"setTokenId(uint256)","c929d55e":"overrideTokenHolders(address[],uint256[])","c92a1ad8":"bonusPriceDeltaPerHour()","c92a1e26":"setting(bytes)","c92aecc4":"chi()","c92ba8b2":"add(address,uint32,uint128,uint128)","c92babd1":"SITMock(address)","c92cd4d3":"getNewTokenBalanceOf(address)","c92d2385":"transferPreSignedHashingWithPrefix(address,address,uint256,uint256,uint256,uint256)","c92d3ea9":"Amazon()","c92db04d":"VanMinhCoin(uint256,string,uint8,string)","c92e365f":"placeBid(address,uint256,uint256,uint256,bytes,int256)","c92f3a0c":"GameICO()","c92f8954":"withdraw(address,uint256[3])","c932c71e":"USDsToken()","c932ca62":"setBuildersAddress(address)","c9330bfb":"ethToTokenConversion()","c9334051":"decodeAssets(bytes32[])","c9335f58":"worldwidegiftcode()","c9351571":"WorldCupToken()","c93685b8":"getQuorumPercent()","c937b0a9":"platinum()","c937da12":"addToPublicWhitelist(address)","c937e091":"SearchUserID(string)","c9380d3e":"DeciserToken()","c938acc8":"checkExistsOwnedPet(uint64)","c9393c62":"NewState(uint8)","c939625b":"LuckCashCrowdsale(uint256,uint256,uint256,address,address)","c939fd50":"remainingIssuableNomins(address)","c93a6c84":"setDefaultFee(uint256)","c93aac88":"setReleasingSchedule(address)","c93ab4c3":"checkTreesWatered(uint256[])","c93b9755":"mintAgents(int256,address)","c93c266e":"updateWalletAddress(address)","c93ce90f":"chefOwnerWithdrawal()","c93ceec8":"collectDividends(address)","c93cff84":"test_validContractBalance()","c93dd31a":"Blammascoin()","c93e253d":"balanceOfBasic(address)","c93e718b":"removeAddressesFromOperators(address[])","c93e8862":"_checkCap(address)","c93e8b15":"getActiveBuyOrders(uint256)","c9406e86":"crowdsaleEnds()","c940c1b7":"addCustomerHash(bytes32,bytes32)","c9410b76":"ClockAuction(address,uint256)","c942940c":"Sukaya()","c944a38e":"CharlyLifeLog(string,int256)","c9456530":"isRespectTimeFrame()","c945b53f":"lottoIdentifier()","c946f3af":"Standard_3()","c94727f0":"getWinChoice(uint256,uint256)","c947db81":"earlyWithdrawalFeePct()","c9498266":"hash_passcode(bytes32)","c949ba9b":"TokenBase()","c949c0c9":"_houseOf(address)","c94a18ba":"kpyGoalReached()","c94a5841":"BITVesting()","c94b0ac1":"CryptoTwitch()","c94b56e3":"isMinCapReached()","c94b5c3d":"cabbageToken()","c94bfdb1":"setTokenDescription(address,uint256,string)","c94c6787":"specialSend(uint256,address)","c94c79dd":"EtherTots()","c94d0eee":"oddEven(uint256,address)","c94dc71e":"Satochi()","c94e643c":"grantTokens(address,uint256)","c94e6567":"fetchBlocks(address)","c94e7b5c":"icoTokenSupply()","c94f2d69":"ILOTContract()","c94f7983":"StillToGo(uint256)","c94fbd4b":"Reek()","c9511b59":"setAddressToken(address,address)","c95292c4":"EthlanceDB()","c95320db":"migrationPhase()","c9537838":"getExpectedBalance(address)","c9553010":"testDistributing()","c955457e":"getRandomArbiter()","c955b514":"addCancelled(bytes32,uint256)","c9567bf9":"openTrading()","c956d497":"helpWithdrawal(address)","c956db57":"WOLF3()","c957012e":"caps(bytes32)","c9580804":"setAccessManager(address)","c9584008":"registerTicker(address,string,string,bytes32)","c959467b":"setInterestDB(address,uint256)","c959ec57":"GetRocketStock(uint16)","c95acadd":"ethAuction()","c95ae083":"isMethodAllowed(bytes4)","c95bd3aa":"closePreSignedHashing(address,bytes32)","c95c0efd":"setBonusUnlockAt(uint256)","c95c0f7b":"getTransactionIds(uint256)","c95c16af":"imported(address)","c95c67dc":"ADVISORS_SUPPLY_LIMIT()","c95c9a83":"ThinkCoin(uint256)","c95d8e40":"clientSign()","c95e0909":"resetPlayer(address)","c95e81cb":"MyBet(uint8,address)","c95f79ba":"closeLeaderboard(uint16)","c95f8b91":"TransferFunds(address,uint256)","c95f95bb":"ComputedGainsRate(address,uint256)","c96027b3":"ethpaused()","c9613733":"startNextEra(bytes32,uint256,int256,uint256,int256,uint256,int256)","c961df66":"contract_period()","c9620770":"doVote(address,uint256,uint256)","c96266e8":"getDragonFight(uint256)","c96304e8":"balancesAddressDescriptionUpdate(string)","c9634f32":"randomContestant(uint256,uint256)","c9644b77":"retireAxie(uint256,bool)","c96492c4":"SspManagerContract(address,address)","c964e493":"getSpaceship(uint256)","c9651729":"firstLineWrong()","c9653bea":"MainExchange()","c96593a0":"The10ETHPyramid()","c965e1d3":"constructAPIParam()","c965ed7b":"OwnerReward()","c9660d07":"ownerSetEdgeRangeAndPayout(uint256,uint256,uint256)","c966865e":"notRandom(uint256)","c9679537":"HafizToken()","c968907f":"grantVestedTokens(address,uint256,uint256,uint256,uint256,uint256,bool)","c968aab3":"makeUntradable(uint8)","c968ac68":"getWin(uint64)","c9693411":"deliverPresaleFuelBalances(address[],uint256[])","c96adb01":"getUserBet(address)","c96c54a7":"airdrop(address[],uint256,uint8)","c96c8a1d":"ownerListMap(uint256)","c96cd46f":"suicide()","c96cea70":"updateUsername(string)","c96d2dfa":"getStateAndProof(bytes,uint256)","c96e5627":"numRegistered()","c96e785f":"setWhitelisted(address,address)","c96e83db":"firstContributorId()","c96e8fee":"Bury(address,uint256)","c96f3238":"getWithdrawAmount(uint256,uint256)","c96f5041":"addHash(string,uint256)","c971442c":"getDBs()","c971aade":"FINALSTSTEST()","c971b12b":"_onRandom(uint256,bytes32)","c9734ebd":"WatchLastPayout()","c97358df":"GGPCToken()","c973851d":"kMaxStake()","c97399d0":"_isOwner(address,uint256)","c973c2e3":"collectorAddress()","c9744029":"getPremium()","c974631b":"platformWithdrawalProposed()","c974947d":"unlockAddress(address[])","c975653d":"StartCity()","c9762f8f":"TooBigPriceDiff(uint256,uint256)","c976b4f9":"slowDump()","c976bbbb":"_compare(int256,bytes2,int256)","c976ce9c":"privateSaleLimit()","c977a7a7":"setUsdToEtherExchangeRate(uint256)","c9788631":"beneficiaryWallet()","c978a7bc":"inviteRate()","c978c45d":"setNewMessage2(string)","c978ee59":"fourthStageMintingDate()","c979113c":"nextStageEmission()","c9791e0d":"confirmBobIndirectPay(uint256)","c97a06ce":"isHardcapReached()","c97aae82":"NulsStandardToken(uint256,string,uint8,string)","c97ab7ca":"isICOClosed()","c97b5278":"XYZSecurities()","c97b6d1f":"updateBatch(int128[],uint128[],uint8[],bytes32[],bytes32[],bool)","c97be180":"lock(address,uint256,uint256,uint256)","c97c1505":"readRate(string)","c97c6353":"testHello()","c97ca645":"updateWeiPerWholeToken(uint256)","c97cc71e":"getTransferRawAddress(bytes)","c97cef81":"Shelter(string,string)","c97dc17b":"DatareumToken()","c97e8480":"delegatedTransfer(address,uint256,uint256,uint256,uint8,bytes32,bytes32)","c97ec033":"changeOverERC228(address,address,uint256,address)","c97f8363":"setBonusAddress(address)","c9801b50":"f_public()","c98031be":"hintURL(int256,bytes32,string)","c980c626":"setImage(uint256,string)","c98165b6":"createTarget()","c98166c0":"ethAmount()","c9818728":"candyCap()","c9819d1e":"GuardaRegistro(bytes32)","c982e353":"getCurrentPrice(uint256,uint8)","c9838930":"setReferralTokenContract(address)","c985c221":"get_all_levels()","c986cf7c":"defrostAdvisorsTokens()","c987a78a":"AISI()","c987c5a1":"userAdd(address)","c988d70f":"getDailyWithdrawLimit()","c9891384":"PendinglinesToLines()","c9894b5c":"taxValue()","c98a79fb":"getBallotLogN(address)","c98b7027":"bgb_per_Keos()","c98bd7da":"isWinner(uint256,uint256)","c98bdd2f":"year5LockAddress()","c98c3083":"OutcomeToken()","c98c6e08":"payAmountForLoanAtIndex(uint256,uint256)","c98cf6e3":"COBToken()","c98d3457":"alliance(address,address)","c98d9b83":"getTokensContractAddress()","c98e4149":"setKingdomFactory(address)","c98f0ad9":"getUnlockedBalanceLimit(address)","c98fc4d9":"adminSetConfig(address,address,address)","c98fefed":"convertFor(address[],uint256,uint256,address)","c99051dc":"getWildcardsRemaining(uint16)","c9912255":"gago()","c99252d3":"joinGame(uint256,uint8,uint8)","c99380c9":"getAttoTokensBoughtInICO()","c994fe31":"setCompanyManager(address)","c995623e":"revealMove(bytes32,uint256)","c9956b05":"FMCToken()","c99749a8":"prepareWithdrawProposalGivenSplitProposalId()","c997c1e2":"mul18(uint256,uint256)","c99842f9":"startPreIco(uint256,uint256,uint256)","c998e9dd":"changeUserKeyFromRecovery(address)","c9991176":"addAdministrator(address)","c99a975d":"optInFcnMinGas()","c99ae8a7":"setFechaTax(uint256)","c99b1f28":"icoWeek4Bonus()","c99b27ad":"updateFirstWallet(address)","c99c3c62":"getCarProductCount()","c99d89fc":"PriceOneEnable()","c99d9ef7":"startIcoDate()","c99db1ba":"_calculateLockedPercentage(uint8)","c99dccf9":"getInvestor(uint256)","c99f3357":"DRAIN_DELAY()","c99ff644":"dilute(uint256)","c9a04e55":"getDailyEthProfit(address)","c9a0e252":"ICOParticipants(address)","c9a1d88b":"placeBet(uint16,uint16,bool)","c9a2ab19":"aragonDevMultisig()","c9a30482":"BurnableCrowdsaleToken(string,string,uint256)","c9a365a7":"foundationlock()","c9a3f228":"SCLCrowdsale(address,address,address,uint256)","c9a43b2b":"m_software(uint256)","c9a4faa6":"AdexContract(address,address,address,uint256,uint256,uint256)","c9a5003c":"lastHello()","c9a52d2c":"setBytesValue(bytes32,bytes)","c9a56efd":"getBetterBettingInfo2(address)","c9a6964a":"initializeOwnable(address)","c9a6b2a8":"addAuction(uint256,uint256,uint256,uint256,address)","c9a6e480":"tokenSupplyFromCheck()","c9a75d90":"setPI_edit_20(string)","c9a7623a":"buyingPrice(bool)","c9a77e3d":"totaleMsg()","c9a815bd":"setSpendingLimit(address,uint256)","c9a82aa8":"markCrowdsaleEnding()","c9a8baae":"myFirstLoop()","c9aa013b":"Start5()","c9aa4cf8":"testHasTokens()","c9aa71b8":"getFlyingUnicorns(bytes32,uint64)","c9ab521f":"AddBook(uint256,string,address)","c9ac836d":"transferPet(address,address,uint64)","c9acab84":"left59(uint256)","c9ad51b5":"TOKEN_AMOUNT_ICO_STAGE1_PRE_SALE3()","c9ae5594":"countHand(uint8[])","c9af089f":"getOrCreateChildUniverse(bytes32)","c9af2418":"checkUp(address,bytes32)","c9b06a4b":"AECloudToken()","c9b0d97b":"canCollect()","c9b0eef4":"oracleItQuery(uint256,string,string,string,uint256,uint256)","c9b110cb":"getAmountOfWithdrawals(address,address)","c9b1a517":"Show_Doctor(uint256)","c9b1b2ae":"etherKing(uint256)","c9b25f0f":"transferEther()","c9b2a580":"UTTotalSupply()","c9b2e522":"getSymbol(address)","c9b31d4b":"getCurrentSecret()","c9b3e736":"getTokenSellPrice()","c9b44821":"FIRETRADES()","c9b46bbb":"test0_adding()","c9b4cb94":"BIBToken(uint256,string,uint8,string)","c9b4ddb2":"receiveLockedAmount(address,uint256)","c9b5e555":"founderAddr()","c9b67627":"NonActivationWithdrawal(address[2],uint256[8],uint8,bytes32[2],uint256)","c9b7ab8b":"getPostLink(uint256)","c9b8020d":"starbaseToken()","c9b86d43":"manualState()","c9b94eb9":"liabilityFinalized(uint256)","c9ba0d4d":"r9kAddress()","c9ba32f4":"COPPER_AMOUNT_NDC()","c9ba73a3":"getmypost(uint256)","c9ba93be":"getIndexFromAddress(uint256,address)","c9bba27b":"manualEmissionEnabled()","c9bbc8c0":"donkeyName(address)","c9bc0883":"transferFromForcibly(address,address,uint256)","c9bc2bf5":"updateSnipCoinToEtherExchangeRate(uint256)","c9bc5dbd":"requestCeilingRaise(uint256)","c9bd2893":"fines()","c9bebd90":"ownerAlias()","c9c08bb7":"tickerAddress()","c9c09ac8":"denyBundlingMultitoken(uint256)","c9c0c77a":"deposit(uint16)","c9c0f25e":"getAllWorkers()","c9c1db4a":"launchFund(uint256)","c9c1ed93":"testControlRegisterContractIdAgain()","c9c1eded":"EPYCOIN()","c9c22deb":"getStarDistanceInLyThousandths(uint8)","c9c286c6":"getUnitRafflePlayers(uint256)","c9c347b9":"EthereumOneToken(string,uint8,string)","c9c4405b":"CariNetPrivilege(uint256,string,string)","c9c447e0":"getGamePrize(address,uint256)","c9c4797d":"ParticipantAuthority()","c9c51578":"buyBronze(uint256,uint256,uint8,bytes32,bytes32)","c9c53232":"totalStakedAt(uint256)","c9c538aa":"to_binary(uint256)","c9c5b5b4":"migrate(string)","c9c6176c":"BidSubmission(address,uint256,uint256)","c9c666aa":"changeCardboardUnicornTokenAddress(address)","c9c798b3":"addToFreelancerAvgRating(address,address,uint8)","c9c7cb74":"_burnTokens(address,uint256)","c9c7ef25":"withdrawtime()","c9c80a56":"adminshipLevel(address,uint8)","c9c8580c":"makeOffer(uint256,bytes32,uint256,address,uint256,uint256,address,address,uint256)","c9c85ec6":"currentGameCost()","c9c8ffd2":"test_increaseBlockNumber30211()","c9c92c12":"transferWineFromVineyardCellar()","c9c92dc5":"getProposal(bytes32,string)","c9ca080d":"Indecoin()","c9cb0043":"supportTokenAmount()","c9cb0e9b":"emitNewSmartToken(address)","c9cb6f47":"distributeDifferentAmountOfTokens(address[],uint256[])","c9cb7204":"unsold()","c9cbc222":"PicAdded(address,uint256,address,bytes32)","c9cbf8c9":"saleExchangeRate3()","c9cc0498":"buyComission()","c9cc0ed5":"setGuardianSale(uint256,uint256)","c9cc1a05":"transferTokensToContributor(uint256)","c9cd40a2":"vestingEntries(address)","c9cda91f":"changeTokenAddress(address)","c9ce1c23":"KUEKeNParty(string)","c9ce624f":"buyBackFund()","c9cf03ce":"refundMoneyForUser(bytes32)","c9cf2d4e":"vault_deposited(address)","c9cfa6ba":"setAllocation(address,address,uint256,uint256[],uint256[])","c9cfac55":"refundCurrency(address,uint256,uint256)","c9cfe755":"sendUnsold(address,uint256)","c9d00764":"TokenPurchased(string,uint256,uint256,uint256)","c9d07650":"NetkingToken(uint256,string,uint8,string)","c9d12d11":"RC(address,uint256,uint256,uint256,uint256)","c9d2373b":"marketKnowledge()","c9d256ae":"tokenSaleLeft()","c9d27afe":"vote(uint256,bool)","c9d27bcf":"doDisputeMemoryAccessSequence(uint256,bytes32)","c9d2d217":"TokenState(address,address)","c9d34622":"diffDays(uint256,uint256)","c9d4623f":"engine()","c9d57328":"managePlayer(uint256)","c9d66690":"RedeemEvent(address,uint256)","c9d68389":"airdropper()","c9d7d862":"drawFundsAfterTransfer(uint64)","c9d82560":"RewardBonusTimePeriod()","c9d82c96":"ICO_DURATION()","c9d96393":"updateGenVault(uint256,uint256)","c9d9c2b4":"deathData_a0()","c9dab438":"Subrosa()","c9dac221":"Bussines_Card(string,uint256,string,address)","c9db1bbf":"setPreICOStartDate(uint256)","c9db2bbd":"addPendingContribution(address,uint256,uint256)","c9dbc259":"ExchangeSwitch(bool)","c9dca9ba":"changeTokenMinter(address)","c9dd3a56":"annualInterestUpdateToken()","c9dd915f":"checkPremium(address)","c9ddd118":"checkPersonalRemaining(address)","c9ddd12f":"getTimestampOfDayEnd(uint256)","c9de31c7":"EOToken()","c9deb567":"collectionsAvailable()","c9dfa731":"lost(uint256,uint256)","c9e01787":"registerAffiliate(address[],uint256[],string)","c9e075c6":"showLockState(address,uint256)","c9e077e6":"bride()","c9e20791":"_setName(bytes32,string)","c9e25251":"buy(bool)","c9e3af7e":"currentBetLimit()","c9e3e66c":"secondCheckpointPrice()","c9e40106":"getConsolationPrizeTokenId(uint256,address)","c9e43221":"MIN_WTH()","c9e4d8bb":"isService(address,address)","c9e525df":"N()","c9e55b4e":"adminFixMaxSupply(uint256)","c9e6bef4":"_endsAt()","c9e7fd4b":"SovTokenCrowdsale()","c9e84346":"bonusLevels(uint256)","c9e904be":"totalEthRaised()","c9e9f4dc":"donateToLottery()","c9e9ff2c":"CPBWallet()","c9ea7c7c":"setMinimumFundingGoal(uint256)","c9ebb5e8":"freeMem()","c9ebeba6":"setIPFSParameter(string,string)","c9ec6cf6":"setOpenCloseHour(uint8,bool)","c9ecc566":"PurchasingAllowed(bool)","c9eda121":"setArrayIndexValue(bytes32,uint256,string)","c9ee21fa":"GUNS()","c9eea77c":"_updatePrice()","c9ef5569":"getVolumeBonusPercent(uint256)","c9efa392":"bonusMilestones()","c9efda2c":"canStartAuction()","c9f09090":"populateTrancheTokens()","c9f0a02d":"burnAuction()","c9f166f8":"ctz32(uint32)","c9f1b7f0":"TeamToken()","c9f21fec":"setAuditTimeout(uint256)","c9f316dc":"getReferenceCodesOfAddress(address)","c9f3d62e":"getCarProductEarning(uint32)","c9f68025":"AMToken()","c9f73464":"maxCandidateId(uint256)","c9f84e1a":"unlockSecondPrivate()","c9f88f27":"invokeContracts(bytes)","c9f8cf20":"getCanvasesWithSellOffer(bool)","c9fa11df":"EventChain()","c9fa595b":"paused_3()","c9fa8f2d":"houseFeeHoldover()","c9faa7c5":"isActivated(address)","c9fb975c":"UnicornsSold(address,uint256,uint256,uint256)","c9fbdc36":"referral_fee()","c9fbe626":"TweetRegistry()","c9fca8a5":"rivetzRegister(uint256,uint256,uint256,address,address)","c9fd1955":"getVestingWalletLength()","c9fd83e2":"lastFeePeriodStartTime()","c9ff34ec":"privateTime()","c9ffb6e3":"claimPocketMoney()","ca001903":"AntarctiCoin()","ca00aad3":"closeLottery(uint256,string)","ca0157cd":"getGameIds(address)","ca01b37c":"DASToken()","ca01ba39":"generateTokens(uint256)","ca02dbe3":"Requestprofit()","ca0370f7":"calculateCompoundContract(uint256,uint256)","ca03dab5":"withdrawSubdivsAmount(uint256)","ca03fdcd":"ShowADV()","ca04d26f":"transferReadable(address,uint256)","ca04e076":"getOwnerPixelCount(address)","ca051844":"withdrawBalance(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","ca056aed":"addTokens(address,uint256,uint256)","ca06226d":"Ecopackcoin()","ca07218c":"setIt(address)","ca077f72":"allocate4ProjectToken()","ca0781a1":"getRateAndCheckCap()","ca079c52":"Upd(uint256,string,address,uint256,uint256)","ca087b96":"FlexFitRewards()","ca093888":"gameIsSundown()","ca0941b4":"findIdByHostPort(string,uint256)","ca0a992e":"IvyKoinContract()","ca0a9c2d":"makeUser(address,string,string)","ca0b1878":"addValue(address,uint256)","ca0b49ae":"getMyCarsIdx()","ca0c0a49":"gameActiveStrRef(string)","ca0c1e62":"computeMerkle(int256,int256,int256[],int256,int256,int256[])","ca0c2024":"minCapPre()","ca0c601c":"maxGoalInICO()","ca0c74be":"buyForInvestor(address,uint256)","ca0c9b5c":"storeTransactionData(address,address,uint256,uint256)","ca0cd7c0":"setUnlockLater(uint256)","ca0d01a6":"_yearTwoSupply()","ca0d0d82":"getMilestoneInfo(uint8)","ca0d6e48":"Mariton()","ca0d9564":"removeAdminList(address[])","ca0dcf16":"mintRate()","ca0e5c27":"ViewProjects()","ca0f1215":"initialSaleDuration()","ca0fe62a":"CryptoMemes()","ca0fe751":"switchRankings(uint8,uint64,uint64,uint64,uint64,uint64,uint64)","ca1149d1":"getUserEntryStatuses()","ca1314af":"getMax(uint256[])","ca13b818":"setWinningTeam()","ca13fb0f":"minInvestCents()","ca154008":"AssetContract()","ca15fb65":"getCardPower(uint256,uint256)","ca1637f5":"getGDemocsN()","ca169e66":"Voodka()","ca17cad1":"getBoxPrice(uint256,uint256)","ca185022":"foundersFundAddress()","ca1861aa":"stockCancelBuyOrder(uint256,uint256,uint256)","ca18da3f":"setGender(uint8,string)","ca18ebbf":"preICOPrice()","ca1929aa":"LogBeerRedeemed(address,bytes32,uint256)","ca1938e5":"houseCutPercentage()","ca1a2eb4":"localPaiementConfirmation(bytes32,bytes32)","ca1a3086":"transferChickenFrom(address,address,uint256)","ca1a4942":"CountExecs()","ca1a9433":"addZiekenhuis(address)","ca1aa5bb":"distributeReservedTokens()","ca1ab2ef":"divideByZero(uint256)","ca1ac5cb":"_createWhale(string,address,uint256)","ca1ad32c":"setPartnerPercent(address,uint16)","ca1b06b2":"ActionAuctionPlat(address,address)","ca1b5aa7":"allowUpgrading(bool)","ca1bf69f":"froze(address,uint256)","ca1c3bb3":"testNonExistingVoteWeight()","ca1c8895":"setPriceOfToken(uint256)","ca1d209d":"fund(uint256)","ca1d6f73":"doTeamMinting(address)","ca1e5bb7":"mintTokensByETHExternal(address,uint256)","ca1e9738":"getPricePerToken()","ca1ea20e":"dataMigration(address,address,address[])","ca1eb8be":"marketaWallet()","ca209c8b":"Bullexi()","ca2145a7":"CoinHot()","ca215005":"getIndividualPrice(address,uint256)","ca2156bd":"redenominate(uint256)","ca2177ef":"NSPFallback(address,uint256,uint256)","ca219b16":"XsearchToken()","ca2317dd":"changeReserveTeamRecepient(address)","ca2322c2":"mashToken()","ca2392f8":"sell(uint8,bytes6,uint32,uint32)","ca24034b":"deathData_v17()","ca2527e5":"batchTransfer2(address[])","ca256771":"weiPerUSDinTGE()","ca2571af":"lockedEarningsOf(address)","ca25bf6f":"IncubatorGlobalGas()","ca25e9c5":"setPurchaseRatios(address[],uint256[])","ca263a49":"registerDomain(bytes8,string)","ca265c0f":"getCurrentSpend(address)","ca267f28":"getRecordCount()","ca2748bd":"transferAndFreeze(address,uint256,uint256,uint256,uint256,uint256)","ca276c07":"updateTierMinimum(uint256,uint256)","ca2785bf":"flushHouseFees()","ca278feb":"VanityURL()","ca27b214":"LucksToken()","ca27eb1c":"createListing(bytes32,uint256,address)","ca281fd9":"renounceControl()","ca28d2ae":"SEKCapitalToken()","ca292622":"getCompany(bytes32)","ca29cae8":"bufferWallet()","ca2a2f99":"_inMoney(uint256)","ca2acfff":"_getTokenAmountWithoutBonus(uint256)","ca2bf047":"predictPacks(uint256)","ca2c139c":"getCurrentQuickPromoBonus()","ca2cd9d3":"marketactive()","ca2cef51":"MiningWarContract()","ca2d553a":"setAccessControl(address,address,uint8)","ca2dfd0a":"removeVerifier(address)","ca2dfff1":"notforked()","ca2e2f49":"firstVestedLockUpAmount()","ca2e8cc5":"markRedeemed(address)","ca2f281b":"FMC(uint256,string,string)","ca2f5a07":"PubRejected(address,string)","ca2f5cb4":"_addPauser(address)","ca2f6487":"Zettabyte()","ca2fd584":"getCommanderPot()","ca30597d":"BoomstarterPreICO(address[],address,address,uint256,bool)","ca30a279":"setTgeAsSaleAgent()","ca313539":"EMISSION_FOR_SALESTAGE2()","ca315ca6":"slashStake(uint256,address)","ca3181e0":"mint(address,uint32,uint256)","ca31879d":"claimToken(address,address)","ca3228d7":"_updatePlayersMilk(address)","ca325469":"destinationAddress()","ca3261c6":"giveAuthorization(address)","ca330563":"isRedeemed(address)","ca33a817":"_guardianVendPrice(uint256,uint256)","ca343d2b":"getICOBonusAmount(uint256,uint256)","ca34a0e3":"iterate_next(uint256)","ca34e1d6":"WineMarket(address)","ca35271c":"numDebtors(address)","ca35bff2":"setCaps(uint256,uint256,uint256,uint256,uint256)","ca36226d":"removeCrowdsaleContract(address,address)","ca3654e7":"requestBonus()","ca36695c":"setUsdPerEth(uint256)","ca368538":"randN()","ca37a9eb":"setWeiPerCent(uint256)","ca37dfad":"crossBalance()","ca37f7d9":"reserverWallet()","ca386496":"setPassword(string,string)","ca392c49":"setPreITO(address)","ca39e5ef":"fight(uint256,uint256)","ca3a3f0d":"_payTicketByEarnings(uint256,address)","ca3aa607":"LendToken()","ca3b5c91":"hasRelation(bytes,bytes,address)","ca3c7519":"getReffName(address)","ca3c8e11":"BRONZE_AMOUNT_NDC()","ca3c9147":"ownerHistoryEntry(uint256,uint256)","ca3dd175":"approveAuthority(address)","ca3e1176":"DaoRulesProposals(uint256)","ca3e1733":"ico1Tokens()","ca3e5333":"isFundManager()","ca3fc092":"CheckPrivilegeAccomplishment(uint256)","ca4028da":"BabyBorn(string,uint256)","ca414006":"setData_11(string)","ca41d16f":"SMTfundAfterPreICO()","ca4223ad":"LATIME()","ca42afda":"getGErc20ToDemocs(address)","ca43801a":"SelfDesctructionContract()","ca4398e3":"StellarToken(uint256,string,uint8,string)","ca43b191":"armySatelitesCount(uint256)","ca4401f1":"investor_addRefBonus(address,uint256)","ca441b85":"randomBlockStart(uint256)","ca446dd9":"setAddress(bytes32,address)","ca448a88":"revokeAsset(bytes32,uint256)","ca44c8e4":"testMemoryIntegrityCheck4Bytes()","ca46e41f":"CROSAIR_VOUCHER_LIMIT()","ca4742f1":"getRN(uint256)","ca482264":"GetApplicant(uint32)","ca482849":"_finalSupply()","ca4858af":"evacuateTokens(address)","ca48b0be":"setupToken(address,address,address)","ca4938fb":"totalFreezed()","ca495022":"weiFromExchange()","ca4a0298":"maxAirDrop()","ca4a2bf7":"NewTokensSold(uint256,address,uint256)","ca4a3df3":"winlose()","ca4b208b":"developer()","ca4b4fd6":"remove(bytes32[],bytes32)","ca4bc6ae":"getBurritoData(uint256)","ca4bd513":"FundsRefunded(uint256)","ca4c8fc6":"OneTestCoin()","ca4cbf67":"getUint(address,string)","ca4d1435":"GWGF(uint256,string,string)","ca4e02d0":"Jump(address,uint256,uint256)","ca4e4863":"VECTORZILLA_RESERVE()","ca4f0911":"preICOPush(address,uint256)","ca4ff630":"priceForStage(uint8)","ca5271a1":"funcWithoutArguments()","ca52cc86":"CollectibleOffered(uint256,uint256,uint256,address,uint256)","ca53135a":"min_bet()","ca5397c7":"cancelSellOffer(uint32)","ca5450ce":"any_customer_payments_yet()","ca5454db":"createTransferAgreement(uint256,uint256,address)","ca54ea4e":"pointOf(uint256)","ca5541c1":"nextRoundReserve()","ca555f2c":"setInitLockedAccount()","ca558b25":"DataContacts(address)","ca55954c":"getTokenHolder(uint256)","ca56106c":"testCopy()","ca561d4d":"KiemTraNamNhuan(uint16)","ca579642":"GroupBuy(address)","ca585774":"RewardForum(uint256)","ca588f14":"delAdmin(address,address)","ca58a06c":"managerKey()","ca58d2b4":"FUNDS()","ca58da1a":"changeReserve(address)","ca59f45b":"transferRecord(bytes32,address,uint256)","ca59fa8d":"_distributedTo(address,uint16)","ca5a3b4a":"isAllowedWhitelist(uint256,uint256)","ca5a3f38":"getDaysPassedSinceLastRefundBallot()","ca5a899c":"totalStashedPayouts()","ca5adadc":"processEthPulicFunding(address)","ca5b4207":"log8(uint8)","ca5b428f":"Police_2()","ca5b8a52":"REGULAR_CATEGORY()","ca5c058d":"founderTokensLockedUntil()","ca5c1547":"preSaleFirstPrice()","ca5c7a34":"getLand(int256,int256)","ca5c7b91":"lockedSupply()","ca5d0880":"airDrop()","ca5eb5e1":"setDelegate(address)","ca5f4282":"amountWanted()","ca607c4e":"transfer_other(address,address,uint256)","ca60f409":"CurrentIcePrice()","ca61295b":"removeFRA(address)","ca615662":"testFailCreateWithForeignParentNotInUse()","ca6158cb":"itemId()","ca61cdac":"testSub()","ca61e9b3":"verifyHashWithPrefix(bytes32,uint8,bytes32,bytes32)","ca621ac3":"DEVELOPER_RESERVED()","ca626232":"exchangeAdapterManager()","ca628c78":"withdrawToken()","ca632cc5":"bountyPaid()","ca639025":"getNujaRegistry()","ca63a55b":"getHotelsLength()","ca63b5b8":"freezingCount(address)","ca63f057":"DISCOUNT_STAGE_ONE()","ca6490cf":"elementFunction()","ca64a02d":"withdrawBalances(address)","ca64a095":"viewNextRelease(address)","ca64ad89":"getNotPayableTime(uint256)","ca64cd34":"marketCapRed()","ca6528cc":"increaseBalanceOrWithdraw(address,address,uint256,uint256)","ca6649c5":"joinGame(uint256,uint8)","ca668eb2":"MyERC20Token(string,string,uint256,uint256)","ca66a9c7":"blocktubeCoin(uint256,string,uint8,uint256,string,string)","ca67065f":"tokensAreFrozen()","ca67628f":"presaleFemaleEnd()","ca68968e":"ConversionRates(address)","ca68a45d":"createLastWill(address,string,string,string,uint256,uint256)","ca698873":"countWhitelists()","ca699de1":"StagedRefundVault(address)","ca69e323":"maxToken()","ca6ad198":"oraclizeMinCallbackGasPrice()","ca6ad1e4":"setCustomGasPrice(uint256)","ca6b72fd":"XtracoinToken()","ca6c7400":"getBuyerSignature(string)","ca6cf796":"startWinery(string,string,string,uint256)","ca6cfd95":"_createToken(string)","ca6d56dc":"addMember(address)","ca6d5d0c":"getLockedTokensInGroup_(address,uint256)","ca6f8295":"RDOToken()","ca7044c3":"RelentlessConscience2Token()","ca708230":"funnel()","ca709a25":"getFeeToken()","ca710013":"hasAllowanceToRecieveTokens(address,address)","ca7140ad":"playerForceGameEnd(uint8,uint256,uint256,int256,uint256,uint256)","ca722cdc":"settleBet(uint256,bytes32)","ca7230e9":"transferFromRegister(address,uint256)","ca7275cc":"SpiceHours(address)","ca733c32":"commandAddress()","ca73419e":"addAddressesToBlacklist(address[])","ca7390ab":"mulDivCeil(uint256,uint256,uint256)","ca740c8b":"IncreaseFunding(uint256,uint256)","ca74124c":"addUser(uint256,uint256,uint256,string,string)","ca7430ea":"transferunlock()","ca758f42":"stcMaxBonus(uint256)","ca75b954":"PRESALE_HOLDER()","ca75cbfe":"submitTransaction(address,uint256,address)","ca75d770":"m_Owner()","ca760021":"withdrawChamp(uint256,address)","ca761365":"getDebris(bytes32,uint8)","ca76e548":"updateRest()","ca76ecce":"gettotalBondDivs(uint256)","ca7729f7":"_parseIntScientificWei(string)","ca77a6e8":"handleALU(uint256,int256,uint256,uint256,uint256,uint256)","ca77ab65":"calculate()","ca77ab8a":"getNextFile(bytes)","ca77ba31":"totalIssuanceCurrentBalanceSum()","ca77ea25":"createTokenByAtes(address,uint256,string)","ca78e65b":"disableManuallyMintTokens()","ca790380":"AstatosToken(address)","ca792754":"_assign(address,uint256)","ca79e2f2":"mintLongTermTokens(address,uint256)","ca79f967":"abortInactiveFight(uint256)","ca7a08ef":"compensate(address)","ca7b15da":"tokenRate5()","ca7bfc5d":"FinanceChain(uint256,string,string)","ca7c4dba":"getEtherPrice()","ca7c4e35":"OmenoToken()","ca7c8d07":"Medcash(address,address)","ca7c9296":"calculateFundedValueTokenToken(address,address,uint256,uint256,address,uint256)","ca7c95f2":"PRE_SALE_20_BONUS_MIN()","ca7ca5b4":"removeMember(address,bytes32)","ca7d18fe":"CORPayCoin()","ca7dc5b1":"getNumberOfTweets()","ca7e321f":"startBuyBackDate()","ca7e88ba":"setOutcome(bytes32,uint8)","ca80b489":"setGenes(uint256,uint256)","ca8127d4":"tradingFeeModifiers(address,address)","ca819d35":"getUserIDByWallet(address)","ca82a7c8":"rentModified(uint256)","ca82b5aa":"playBps(uint8)","ca84c176":"bonusAfterPresale()","ca84d17d":"payLeaderAndDev()","ca855a57":"SecureEgg()","ca85dbfc":"quickSetStarterClasses()","ca862298":"BitcoinWorld()","ca8695a4":"resetNewTokens()","ca8786c9":"bacancyToken()","ca879753":"burnMe()","ca87cb2a":"MRASToken()","ca87e67e":"setSaleTime(uint256,uint256)","ca87eb50":"Seo(address,uint256)","ca8836d2":"isPending(uint256)","ca88552d":"stock(address)","ca887dc4":"getAllGameStatistic()","ca88a7b0":"_shareToReferer(address,uint256,uint256)","ca88b3b2":"destructAll()","ca88bd5b":"isAccountBlocked(address)","ca88c5bd":"_getChallengeSuccess(uint256,uint256,uint256)","ca8a2c08":"createEstate(int256[],int256[],address)","ca8ab933":"countInstructors()","ca8b39c8":"setRegionBlockUpdatedAt(uint256,uint256)","ca8b42e4":"max_index()","ca8ee75a":"read_u8_array()","ca8f8ff3":"isExist(uint256)","ca8f9651":"voterVotingTime(address)","ca922078":"fundingStage(bytes32)","ca929e12":"transform(uint8,uint8)","ca92a136":"result_hash()","ca940bba":"getPastBet(uint256)","ca94452d":"setCrowdsaleTransfer(address,uint256)","ca94692d":"abiSignature()","ca949a1d":"blackjackValue(uint8)","ca94a927":"UnicornManagement(address)","ca95402d":"ExpRegistrar()","ca965c3f":"transferCEO(address)","ca96d7fc":"claim(bytes32,bytes32,uint8)","ca970bac":"donateDivs()","ca972cd4":"registerNewAccount()","ca97a248":"MoveRerolled(uint256,uint256,uint256)","ca97d274":"updateTokens3PerEth(uint256)","ca990859":"getPlayedInfo(address)","ca997200":"getForecastData(bytes32,bytes32,bytes12,uint8)","ca9a06df":"calcReservedTokens(uint256,uint256)","ca9a9386":"getNickname(address,address)","ca9c2862":"getCrydrController()","ca9c4b33":"hatchEgg()","ca9ccd3d":"secondRoundTime()","ca9d07ba":"refill(uint256)","ca9d0f8d":"process2(uint256,address)","ca9defb7":"ownerTransferZTH(address,uint256)","ca9e1993":"_transfer()","ca9ec138":"toEthSignedMessageHashBytes(bytes)","ca9efc73":"left81(uint256)","ca9f0803":"reservedInvestors(address)","ca9fa49e":"halfyearteam_trade_date()","caa02e08":"winnerCount()","caa035d6":"getTokenSaleType()","caa03a3e":"getPlayerId(string)","caa0f0af":"devAllocateTokenInMinutes(address,uint256,uint256)","caa0f92a":"getNextTokenId()","caa14e36":"setGiveBirthType(bool)","caa25756":"registerProductContract(address,address)","caa3b6e4":"TicTacToe()","caa3d559":"TRCExchangeRate()","caa4041e":"getAccountLimit(address)","caa4c5d0":"assumeControl()","caa5aba2":"ConfigurableParameters(uint256,uint256)","caa648b4":"getTotalValue()","caa67873":"CreateKDT(address,uint256)","caa6fea4":"emergency()","caa7590d":"MIN_INVEST_BOARD()","caa774ed":"petOnLeaderboards(uint64)","caa7b4b8":"ABToken(uint256,string,uint8,string)","caa7be13":"ClientPaymentEvent(address,uint8,uint8,int256)","caa7fd06":"cancelBid(uint256,uint256,bool)","caa82ab2":"TokenSendFail(uint256)","caa872ae":"_takeAll(address,address,uint256)","caa877e7":"buyFor(address,address)","caa8e084":"div(uint32,uint32)","caaa2045":"addressToNumTowns(address)","caaacb12":"totalForMining()","caab0acc":"testThrowCreateRetracted()","caab21d2":"Ore()","caabe889":"inAllocationLockPeriod()","caac87d0":"airdropPlays()","caad5b18":"withDrawEther(uint256)","caade55b":"AddrPartnerPocket()","caaed302":"rejectMilestone(uint256)","caaee91c":"setProxyOwner(address)","caaf2dd7":"getInitialAnswerResult(uint256)","caaf6d21":"numLoveItems()","caafa055":"ROUND_7_PRESALE_BONUS()","caafc163":"process2(uint256,address,address)","cab0198f":"emitTokensToOtherWallet(address,uint256,uint256)","cab067c0":"initialiseCrowdsale(uint256,uint256,address,address)","cab09273":"getUsedPaymentSupply()","cab0f632":"changeSponseeAddress(address)","cab17220":"VotesNecessary()","cab36e92":"addHash(uint256,string)","cab37586":"partnerWithdrawed(address)","cab39db9":"_updatePhase(bool)","cab3ad2c":"BONUS_ICO_WEEK_ONE()","cab47da7":"RATE_FOR_WEEK2()","cab54df1":"testHitPresaleCapPreDistribute()","cab5c0f1":"_incrementState()","cab60267":"getGameCalculatedStats(uint256)","cab63661":"setPublisher(address)","cab6eade":"_destroyDeed()","cab7e3d9":"purchaseCars(uint256,uint256,bool)","cab7f0cc":"test_insert_findWithHintNextRemoved(int256)","cab7f521":"invoke()","cab896dc":"gameCost()","cab925a3":"BurnReceipt(address,uint256)","cab9c32a":"sellLimit(uint256,uint256)","caba203d":"Loyalty()","cabb3a3a":"isAlphaNumeric(string)","cabc0f43":"isLotteryOpen()","cabc737c":"_addMaster(address)","cabcaaa0":"associateWithFile(bytes32)","cabd27de":"Motion(address)","cabd734f":"reject(bytes32)","cabe0452":"getCampaign(bytes32)","cabe2c0a":"levelEndDate()","cabf72e5":"WSBCCoin()","cabf8493":"balancesImporter4()","cabfb934":"replace(address)","cabfd1bf":"allocateTokens(address)","cac07bbf":"distributeTeamCut(bool,uint256)","cac12d2d":"tokenGenerationCap()","cac35112":"tokenRelease()","cac37f93":"totalTokensWithdrawn()","cac3e64a":"checkToken()","cac3f6c9":"percOf(uint256,uint256,uint256)","cac625e6":"transferTokenOwnership(address,address,uint16)","cac6d78f":"ToexCoin()","cac6edd8":"rightLottery()","cac77df7":"__transferFromToICAPWithReference(address,bytes32,uint256,string)","cac7db8a":"addUserToList(address)","cac7fc71":"allBalances(address,address,address[])","cac8d538":"setERC20Contract(address)","cac92fe1":"Aeroneum(address,address)","cac952ae":"isValidCustomerTxPaymentForMCW(address,bytes32)","cac98d6d":"getCCH_edit_24()","cac9a94e":"changeWalletOwnerAddress(address)","cac9ffbd":"fillIndexedBid(uint256)","cac9ffee":"unWhitelistAddress(address)","caca66bd":"transferPlatformship(address)","cacb27f4":"_D_sendToTeamEthContract()","cacc24eb":"transferFromViaProxy(address,address,address,uint256)","cacca238":"getBaseAmount(uint256)","cacca4a0":"approveTransfer(uint256)","caccd7f7":"developerAddress()","caccd805":"daoPOLSKAtokens()","cacd7a66":"creatUserID(string)","cace467e":"cancelSell(uint256,uint256,uint256,uint256)","cace7bd3":"claimRewardK(uint256)","cace8f37":"dragonGirlLotteryNumber()","cacf1e0e":"getPaymentsCount()","cacf5a33":"calculateVestedAmount()","cacf66ab":"genesisTimestamp()","cacfa24a":"_isBuilt(uint256)","cacfb535":"unpackAll(uint256)","cacfd8e9":"playTypes(uint256)","cad079ed":"investedUSD()","cad0899b":"sum(uint256,uint256)","cad1c663":"getChildOperation(bytes32,uint8,uint8)","cad1d39b":"getPersonalAirdropUnlockTimestamp(address,address)","cad2042f":"O2OToken(uint256,string,string)","cad27ae1":"random(uint64,uint8)","cad283a0":"EtherBetIO(address)","cad3d24d":"calculateBoatFee(uint256)","cad41357":"darknodeBond(address)","cad461ea":"setWeiPerUSD(uint256)","cad4ae37":"_addToBlacklist(address)","cad60d17":"freezeTokens(uint256,uint256)","cad66781":"NumOfStudentsRequests()","cad6dd1f":"sumPreICOUSD()","cad7214d":"supplyRound4()","cad80024":"left58(uint256)","cad916ec":"DEVELOP_CAP()","cad93688":"Test2(uint256)","cad9639d":"DEXK()","cad9642b":"getReportCount()","cad987f5":"updateAppreciationStep()","cadaacbf":"g(address)","cadb1166":"modifyWhiteList(address[],bool)","cadb3031":"timeoutY()","cadb48d9":"contractCreationBlockTime()","cadb5236":"vestToAddressEx(address,uint128,uint8,uint32)","cadbead4":"Pentacoin()","cadc958f":"VoteOnTransferStarted(address)","cadca796":"setShareHolders(bool,uint256,uint256)","cadcbce4":"PartComplete()","cadd888b":"getRewardToken(uint256,uint256)","cade3a5d":"_createPixel(uint24,uint32,address)","cade4f31":"collected_crowd_vitas()","cade77fa":"readAddress(address)","cadec1b2":"Registrar(address)","caded61f":"saleRatio()","caded711":"subOpenRoomCount(address)","cadf338f":"valueOf(uint256)","cadf74e2":"_unclaimedChickenOf(address)","cae039eb":"getWishTime(uint256)","cae07d2a":"TOKEN_SCALE()","cae15051":"tokenReceived(address,uint256)","cae20b59":"getAnimalIdsWithPendingCostume()","cae21530":"fightZeroMonster()","cae270b6":"sell(address,address,uint256)","cae342f6":"dontShowMeInTrace()","cae3c254":"publicFundingWhiteList(address)","cae3d482":"vehicles()","cae44e83":"EthereumCoin()","cae4d676":"sendRefund(address)","cae523c1":"testOwnedTryAuthUnauthorized()","cae57913":"addTwo(uint256)","cae5c8c3":"APP_STORE()","cae6047f":"INVERSE_BASIS_POINT()","cae61d2e":"offer(string,uint256,uint256,address)","cae6b9c5":"tapPoll()","cae6ff18":"SKPT()","cae774b3":"maxInterval()","cae8e284":"newProposal(address,uint256,string,bytes32)","cae8eb2f":"ctrtToken()","cae96610":"WorldWifi()","cae96926":"is_creator(address)","cae98d4f":"r1(address)","cae9a07d":"changeManager()","cae9ca51":"approveAndCall(address,uint256,bytes)","caeafe6a":"stageStartTime()","caeb2539":"PreSaleBuy(address)","caeb2e2c":"_emitSkillAreasSet(address,uint256)","caeb30e9":"Configurator()","caebb256":"channelManagerByAsset(address,address)","caec390e":"getinfolaff(address)","caec3c79":"getBatchTransfer(address,address)","caecc5aa":"turnrefund()","caed4f9f":"DataService()","caed80df":"registries(address)","caee04b5":"AddGameCategory(string)","caee1daf":"creationRateOnTime()","caee262c":"sharesRec(uint256,uint256)","caee3305":"firstVestStartsAt()","caee4e18":"CommunityVotes(uint256)","caee7c78":"grantsCreated()","caef2181":"GetTimeMultiplier(uint256)","caef5dec":"getSubPayeesCount(bytes32)","caef6a84":"ETHMONEY()","caefb79e":"setCaps(uint256,uint256,uint256)","caefc5d5":"SemfaxToken()","caefdbe9":"FWDaddrETH()","caf05ce3":"isStopPlay()","caf0887d":"split(uint256,uint256,uint256)","caf19e5a":"toText(bool)","caf1bb7c":"repoBase()","caf29765":"PERCENTAGE_DIVISOR()","caf306c2":"ratePerWeiInMainICO()","caf439cb":"angelBurn(address,uint256)","caf44683":"test2(uint256)","caf597f3":"INVEToken(address)","caf66171":"bigRoundMaxRoundNum()","caf6cb3f":"marketDefaultFeeHigh()","caf6e1c9":"setClosedManually(bool)","caf6fe1a":"randomGenes()","caf71743":"createSellOrder(address,uint256,uint256,uint8[],address[5][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[])","caf798d7":"transferRegion(uint16,address)","caf7caf1":"_multiplyDecimalRound(uint256,uint256,uint256)","caf807a1":"closeEth()","caf91b30":"airdrop(uint8,bytes32,bytes32,uint256)","caf9bf58":"getContributionsCount(address)","cafa1cde":"PajCoin223()","cafa22d7":"setLeftICOTokens(uint256)","cafab7e1":"viewPetitionShareholderWithAddress(address)","cafaed51":"deadlineParticipation()","cafb2202":"invested()","cafbc49d":"createProduct(bytes32,string,address,uint256,uint8,uint256)","cafbcc8a":"inInnerScope(uint256,uint256)","cafc0fbd":"isRegulated(address)","cafd3d52":"setUpCrowdsale()","cafe0e90":"setFee(string,uint256)","cafe2f19":"setReachCapped()","caff4b03":"Response(bytes32,uint256)","cb009d2c":"KellerWilliams(uint256,uint256)","cb00e7f8":"MCTContractToken(uint256,address)","cb0177a0":"disableAllocationModificationsForEver()","cb0195ee":"changeDeveloperTemplateAmountLimit(uint256)","cb01a9bf":"payRent(bytes32,string)","cb01c70c":"episodesNum()","cb01cd02":"masscreate(uint256,uint256)","cb01f15c":"GetLogMessageWarning()","cb01f431":"maxTokensToSaleInClosedPreSale()","cb0210a0":"updateReputation()","cb029785":"Aphrodite()","cb02ba28":"multiSend(uint256,address[])","cb03e43b":"AnimalFoodToken()","cb040e0b":"createTemplate(string,bytes32,bool,address,bytes32,uint256,uint256,uint8,uint256)","cb05b93e":"getEth()","cb07b94b":"getLastRegionId()","cb09abc2":"resolveProp(uint256)","cb09b0d0":"ownerAPI()","cb0a2d95":"HashtagToken(uint256)","cb0a3889":"setPreIcoStart(uint256)","cb0ab425":"getIPFSHash(address)","cb0b6161":"_calcRelease()","cb0b7b03":"setContributionMinimum(uint256)","cb0cedb8":"getFineLevelOfAddress(address)","cb0d3133":"setEscrowedProjectBalances(uint256,uint256)","cb0d3981":"getMintForReportingParticipantTargetValue()","cb0ef7d0":"hgtRates(uint256)","cb0f86ab":"cards_black(uint256)","cb0fb059":"getNumberTwoArgs(address,bytes4,address,address)","cb10e0c5":"getLastDuel1()","cb10fa76":"safeToMul(uint256,uint256)","cb11526d":"moving()","cb117f0c":"approveAndCallAsContract(address,uint256,bytes)","cb122a09":"setFee(uint8)","cb12b48f":"me()","cb12be81":"prometheusShipMinted()","cb12fc1d":"LAMDEN_DECIMALS()","cb1374a2":"claimTokens(address[],uint256[])","cb146814":"baseETHBalance()","cb149b09":"unlockWorker(address,address)","cb14a5cf":"treeDetails(uint256)","cb14b170":"SubscriptionModuleImpl()","cb14d93b":"getHash(bytes,address,uint256)","cb1579ec":"checkOrderBatch(uint256[48])","cb15d07b":"getOfferAmount(uint256)","cb161f8a":"AddDiv()","cb16415f":"fundsToOwner(uint256)","cb1650b4":"createThread(string,string)","cb16d4a2":"sendEther(uint256,address)","cb16e6d0":"earlyParticipantWhitelist(address)","cb170735":"createBools(bytes32[],bool[])","cb19bf53":"Testtoken5()","cb1a32a4":"aotLength()","cb1a7b1d":"tokenDelta(address,address,address,uint256,uint256,uint256)","cb1aaa31":"distributed_bounty()","cb1ab340":"setFinancialAdmin(address)","cb1b82b7":"getuserbalance(address,address)","cb1ba60f":"voteOnElection(address,address,address,address,uint256)","cb1be21a":"configureWallet(address)","cb1c2b5c":"MIN_STAKE()","cb1c8b6a":"purchaseDefense()","cb1d8418":"getForkingMarket()","cb1d9d63":"setENGCommunityAddress(address)","cb1de087":"transferFromFST(address,address,uint256)","cb1e4389":"isMajorityConfirmed(bytes)","cb1fa715":"setSingleWithdraw(uint256)","cb1faac1":"leftVotes()","cb1fc276":"createPassportByOwner(address)","cb1fc7bc":"totalSzaboInBids()","cb207166":"LifeFactor_iv()","cb227cae":"getPOOL_edit_18()","cb22c0aa":"setBudget(address,string)","cb22d392":"windowFinalBlock(uint256)","cb22d41b":"numBeneficiaries()","cb22fd59":"setFeeCharge(uint64)","cb238ffa":"returnHashLong(address,uint256[3])","cb2410b9":"changeContentData(uint256,uint256,bytes32)","cb244f65":"koreanCitizen()","cb24e8f1":"Foorp()","cb25d9a2":"JFDToken()","cb27bdc1":"revealDeadline(bytes32)","cb27f28a":"endCrowdFund()","cb282253":"totalEthContributed()","cb28ba6a":"AIToken(uint256)","cb28c716":"createKycData(address,string,string,uint256,uint256,string,string,string,string,int256,uint256)","cb293e7a":"rentRentable(bytes32,address)","cb294dc5":"ULTRONEUM()","cb2971b1":"eosTokenAddress()","cb297ef0":"_performRenewal(uint256,uint256)","cb29881c":"createEggScheme(uint256,uint256,uint256,uint256,uint256,uint256,bool,bool)","cb29eee0":"medsupply()","cb2b34d6":"setSalary(uint256)","cb2b5668":"EVBChain()","cb2b9031":"addressToBytes(address,address)","cb2bea55":"setEmergencySecrets(uint256,uint256)","cb2c05dc":"viewInitialPricePerShare()","cb2c8723":"addUtilityHolder(address)","cb2e0814":"iii(address)","cb2e1d10":"icoRound4()","cb2e46f3":"endTimer()","cb2ec895":"deposit(bytes32,address,uint256,bool)","cb2f7b87":"update(uint32,uint128,uint128)","cb2f7c49":"hashDifficulty(bytes32)","cb2fe520":"remainingTokenBurnt()","cb31b6cd":"multiTransferFrom(address,address[],uint256[])","cb3204a8":"getKycHash(uint256)","cb338436":"doSendProfits(address)","cb33e7fa":"doTrade(address,address,uint256)","cb35ef2c":"demotest()","cb3687df":"core(uint256,uint256,uint256,uint256)","cb3694ba":"getManualInvestorsCount()","cb379765":"tsauction(uint256)","cb381b61":"teamETHUnlock1()","cb381c3c":"setGas4Token(uint256)","cb388b9b":"test_callIt()","cb38c7b4":"getWithdrawalList(address)","cb393ecb":"Dice5()","cb3993be":"decreaseApprovalAndCall(address,uint256,bytes)","cb39aafb":"validateRequest(bytes32[8],bytes,bytes,bytes)","cb3a11f9":"withdrawUserSpecifiedFunds(string,uint256,uint8)","cb3ab271":"WYQToken(uint256,string,string)","cb3ae150":"Playforbulktoken()","cb3b0c79":"LotToken()","cb3bc227":"LogBeerBought(uint256,address)","cb3c28c7":"trade(address,uint256,address,address,uint256,uint256,address)","cb3cb085":"validateTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address)","cb3ce26e":"m_owners()","cb3cf99a":"decode(bytes,uint256,uint256,uint256,uint256,uint256,uint256)","cb3d6b5f":"devTeamWithdraw()","cb3e394d":"transferFromWithFee(address,address,uint256,uint256)","cb3e64fd":"unhalt()","cb3ebec2":"ownerDividend()","cb3eecc9":"getNewInstance()","cb3eef2c":"allWorkers()","cb3fcb56":"setGrowthTokensPercent(uint256)","cb4153e9":"destroyNinja(uint256)","cb421a21":"denemekontrat()","cb424c24":"HZRToken(address)","cb42a77b":"stringTobytes32(string)","cb43269d":"getRegistryImplementation()","cb4360d9":"allocateToken(address,uint256,uint256)","cb43e079":"drain_block()","cb44211e":"addApproval(address)","cb44b53d":"ResolutionProposals()","cb457d47":"unlimited()","cb45a294":"getSecondTokens()","cb4717b2":"SetProperty(bytes32,uint256,uint256,uint256)","cb4735f2":"estimatedFundingAmount(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","cb4799f2":"getMetadata(uint256,string)","cb47a8ce":"MultiChampion()","cb47abc7":"getTotalNumberOfTransactions()","cb48e1a5":"assignShareTokens(uint256)","cb4a15c5":"checkStringLength(string,uint256,uint256)","cb4b0105":"Unhold(address,uint256)","cb4b3710":"setStopSelling()","cb4b9db1":"EchoChainToken()","cb4bc2e9":"tryauthenticate(bytes)","cb4bd883":"updateRef(bytes32,string)","cb4be0bb":"getTurtlemasterReq()","cb4c86b7":"funding()","cb4c88ae":"MediatedTransferStatusModified(uint256,bool)","cb4c8ee4":"isRSPScience()","cb4d3d67":"AddedTokenHolder(address,uint256)","cb4de968":"ICO_BASE_PRICE_IN_WEI()","cb4e75bb":"smbl()","cb4e7fdc":"icoIsRunning()","cb4f1d85":"getPolicyHolder(bytes)","cb50301a":"unsoldAddr()","cb510e97":"isStaff(address)","cb51c418":"_toString(address)","cb51f777":"TOKEN_PRICE_NUM()","cb526229":"RefundChequeByHash(uint256)","cb52926a":"getBoughtAssetPacks(address,address)","cb52c25e":"updateAmountRemainingForSale(uint256)","cb553ac9":"sweepWizardCommission(uint256)","cb55adfb":"getStrategyTokenAndWeightByIndex(uint256,uint256)","cb560ac4":"winningMultiplier()","cb562fb3":"Uniond()","cb56d626":"testFailBlobStoreNotRegistered()","cb56dd79":"getFinalState(uint256)","cb56e40b":"getTrader(uint8)","cb574b8c":"buyUpgrade()","cb577480":"prepare(uint256)","cb5829ab":"Revision()","cb5853a8":"claimTaxex(uint256,uint256)","cb58594e":"airDropShadowMoney()","cb586251":"MintableMultiownedToken(address[],uint256,address)","cb5b6bef":"setPriceStep8(uint256)","cb5bf9b8":"EthersRaised()","cb5cf43f":"supplyReady()","cb5d0646":"Presale2Sold()","cb5e4805":"NvcFundCoin()","cb5e7d2d":"newMember(address,bytes20,uint64)","cb5e891f":"_setActiveSupply(uint256)","cb5f18db":"get_ads()","cb5fa63f":"getRoundEth(uint256)","cb5fd01f":"TestToken(address,address,address,address)","cb5fe36e":"VESTING_2_DATE()","cb60f8b4":"sellStartTime()","cb6142c9":"freezeAllAccountInEmergency(bool)","cb61522d":"MILLIODS()","cb61b42d":"updateShares(uint256,uint256,uint256)","cb61b49e":"_setRate(address,address,uint256)","cb6291cb":"ownerSendTokens(address,uint8,uint256)","cb6308f1":"approveVersion(address)","cb6367d1":"verifySignatures(bytes32,uint8[],bytes32[],bytes32[])","cb637d85":"changeAccountService(address)","cb639322":"realReserve()","cb63da4e":"ALLOC_RES()","cb63ddb6":"makeProposal(uint8,uint256)","cb642180":"_updateNodeHeight(bytes32)","cb645ae2":"addOneRequest(address)","cb64a37b":"createSeratioStake()","cb64d74d":"etherFeePercent()","cb656a13":"adviserSold()","cb65ad66":"MobileAppSupply()","cb65c0f5":"withdraw_excess_tokens(uint256)","cb662fe1":"claimedList(uint256)","cb67f20f":"SaleClosed(uint256)","cb67f948":"unlockTokens(address)","cb68780f":"GetICOData(uint256)","cb6890d9":"setAccount(address,uint256)","cb6ad855":"log10Ceiling(int256)","cb6af4cb":"createChannel(string)","cb6b1f05":"cf2Wallet2Pct()","cb6b25f3":"votePassed(uint256)","cb6b8699":"getPI_edit_5()","cb6bfa03":"BNIToken()","cb6bfd23":"CyTestCoin(uint256,string,uint8,string)","cb6c1655":"tokensFor1EthP1()","cb6cec4b":"getIpfsAfterTitle(bytes32)","cb6d0c5f":"minimumDurationInBlocks()","cb6da9da":"takerCount()","cb6e3fa9":"shouldUpdateFunder(address)","cb70d9a7":"changeUserCertificate(bytes32)","cb712535":"_transferFrom(address,address,uint256)","cb7129a3":"resolvePriorBets()","cb724422":"testPayTokens()","cb739476":"MAGExCoin()","cb739c0f":"changeRateLoss(uint256)","cb740c61":"grant(address,uint256,uint256,uint256)","cb742358":"virtualBalanceOf(address)","cb752679":"buyTokensWithPoly(uint256)","cb757e92":"REGO()","cb758a89":"addDataPoint(uint256,bytes32)","cb76937c":"getUserBetsTimeStampInARazInstance(uint256,uint256)","cb7729d3":"shiny()","cb774d47":"startingIndex()","cb775d5a":"consumePower(uint256)","cb77ed34":"_getProviderSupply(uint256)","cb78bebc":"USER_BUY_LIMIT()","cb78c9f0":"flips()","cb795a64":"allowedBuy()","cb79d573":"maxCompanyValue()","cb79e31b":"votingRightsOf(address)","cb7a0a6f":"getPlayerSpaceshipBattleModeById(uint256)","cb7aac1e":"transferTokensFromProjectFundAddress(address,uint256)","cb7acdd9":"hola()","cb7b3f0a":"readPaymentChannels()","cb7b3fb9":"KinguinIco()","cb7b4ad4":"canCPCreateInFactory(address,address)","cb7b8673":"setTokenExchangeRate(uint256)","cb7bba39":"lockaddress(address)","cb7bba61":"prove(string,string)","cb7c05e7":"verify_fund()","cb7c225e":"Send_TrustlessTransaction(address,uint256)","cb7c30f2":"m_D_n()","cb7d38ac":"changeStartPreSale(uint256)","cb7d8ef2":"spark()","cb7e70fa":"buyTokensOnInvestorBehalf(address,uint256)","cb7e9057":"dispatcher()","cb7e9bf1":"rewardHistoryMapOf(address,uint256)","cb7ef63d":"Coinage(uint256,uint256,uint256,uint256,uint256,uint256)","cb7fd9db":"checkVeracity(string)","cb802c8b":"getInvoice(bytes32)","cb80bd60":"LogRefundFailed(address,uint256)","cb810ea9":"sendTokensSingleValue(address,address,address[],uint256)","cb81fecf":"lockRequestCount()","cb821f03":"calculateClaimByIndex(address,uint256)","cb82d5df":"canMakeNoFeeTransfer(address,address)","cb84e69e":"setMessageMaxCharacters(uint256)","cb8523c6":"addAllowed(address)","cb856252":"getFreezeList()","cb859c09":"getGameRules()","cb85f175":"WhiteListedInvestorAdded(address,string)","cb86df95":"moveStartDate(uint256)","cb8820ef":"setWriterId(address,bytes32,bytes32)","cb884207":"deathData_f5()","cb885a36":"Crowdsale(address,uint256,uint256,uint256,address,address,uint256)","cb89558d":"AgreementHashRu()","cb899024":"defrostToken()","cb8a67ed":"ownersForChange()","cb8b4b83":"CollectERC20(address)","cb8b99b2":"_addCryptantFragments(address,uint256)","cb8c2982":"getMyKebabers()","cb8c478a":"activeTime()","cb8cb4a3":"getGoals(address)","cb8cd7cb":"transferFee_()","cb8d0f46":"tstop()","cb8ff46f":"koinconekt()","cb908d78":"_updateEthereumPrice()","cb912ffb":"tokenCountSet()","cb918634":"setDrawP(uint256)","cb91a6ba":"setGemPerMiner(uint256)","cb91aec7":"getFreelancerContracts(address,address)","cb91f1c2":"periodPreITO_endTime()","cb92042c":"removeShare(address)","cb923813":"saled()","cb92bfa1":"_computeCurrentPrice(uint256,uint256,uint256,uint256)","cb92c28d":"rewardEvery1000Draw7(uint256)","cb92cb52":"BuyBackStart(uint256,uint256,uint256)","cb930934":"KopihitamToken()","cb93abb2":"BUYER_STEP_1(bytes32)","cb93e347":"CryptoGamesMarket()","cb93f7ef":"withdrawDevFee()","cb944e24":"saleCapUsd()","cb945312":"testEqual()","cb949213":"addressToPurchasedTokens(address)","cb949e51":"getCustomer(address)","cb950c37":"updateValidMCAmount(uint256)","cb9580e0":"TotalPaid()","cb95a6f6":"Bounty(address)","cb96012e":"hashTo256(bytes32)","cb965ae9":"allKeys()","cb96b0d6":"MAX_EXCHANGE_FEE_PERCENTAGE()","cb96f11d":"Oversight()","cb9756ad":"buyClimateCoinsAgainstEther()","cb9854a2":"confirmSwap()","cb985708":"investorWalletAddress()","cb985dd1":"MARKET_SHARE()","cb990457":"holdersByIndices(uint256,uint256,bool)","cb99cbac":"startServer(uint256)","cb9a20d0":"MINI_GAME_ADD_TIME_DEFAULT()","cb9a3251":"finalizeMany(uint64[])","cb9a32a5":"promoMasterpiecesCreatedCount()","cb9a5edd":"availableLand()","cb9aac64":"usesLibrary()","cb9ae707":"latestDifficultyPeriodStarted()","cb9b3a3c":"getCCH_edit_4()","cb9bdf45":"tokenSoftcapIssued()","cb9c8505":"throwIfStartPastBlocktime()","cb9d6176":"LogDelete(address,uint256)","cb9d86e2":"BlockRefunded(address)","cb9dd1a0":"setMoving()","cb9e2755":"deleteEntity(uint256)","cba01a49":"LunarLink()","cba0e996":"isExcluded(address)","cba1fa10":"set_iconiq_presale_open(address,bool)","cba25e79":"presaleHardcap()","cba2c735":"createPurse(string)","cba456df":"casinoProxy(address,address,address)","cba4bc94":"_setHowManyOwnersDecide(uint256)","cba4f643":"changePreIcoRate(uint256)","cba50fd1":"generateUserRelation(address,uint256)","cba58ab6":"disableService()","cba59827":"Reject()","cba5b465":"endContract(address,uint256)","cba6582e":"Ellomiun()","cba66250":"FTV(address,address,address,address)","cba66e14":"sliceBytes20(bytes,uint256)","cba6a3a2":"setTransferAuthorized(address,address,uint256)","cba74da1":"getResource(bytes32,uint256,bytes32)","cba88872":"countdown()","cba8901b":"getPayoutKeys()","cba8be1c":"setServerAdmin(address)","cba91a35":"roundTwoTime()","cba9a794":"handleReturnBool()","cba9c0e0":"presale_start_block()","cbaa0b25":"playerAttack(uint256,uint256)","cbaa0bec":"amendSingleResult(int16,string)","cbaba70f":"EADC()","cbac21b8":"periodPreITO_mainCapInUSD()","cbac8816":"tokenRate20()","cbaca250":"RewardSplit(uint256)","cbacb269":"stopBonusCompaign()","cbacffe4":"addToPayeeBalance(address,uint256)","cbad3779":"getPublisherRegistry()","cbad60b6":"spread(uint8)","cbad7bf6":"cg(address,uint256,uint256,uint256)","cbaddbaa":"BurnMe()","cbae0163":"readPosition(uint256,int256)","cbae0978":"NewResolver(uint256,address)","cbae1467":"deleteAllAvatars()","cbaeadb4":"getRewardHistory(address)","cbaedd3c":"slashUsername(bytes)","cbaf4742":"OPERATE_SUPPLY()","cbaf5104":"_isClosed(bytes)","cbaf566d":"updateRentInfo(uint256,uint256,uint256)","cbafee8a":"tokensToMint()","cbb01884":"setDefault(uint8,address)","cbb04cbd":"debtPaid()","cbb05527":"totalCapInWei()","cbb0c95a":"getPlayerWithdrawEarning(uint256)","cbb105d6":"NewWorld()","cbb1d761":"confirmBySigner(bytes32,address)","cbb2fd5d":"TRTToken()","cbb31da9":"maker(address)","cbb433ea":"DeepToken()","cbb45120":"TOTAL_WINS()","cbb45444":"test_transfer_to_contract_without_fallback()","cbb50d30":"teamAllocationTokenSend(address,uint256)","cbb6e5c9":"transferTopLevelDomainOwnership(bytes32,address)","cbb70c92":"addLOC(address)","cbb8b158":"TESTH()","cbb9818c":"turn_flag_ON()","cbb9dbb9":"depositCoupon(address[2],uint256[8],uint8,bytes32[2])","cbba3f4b":"DCSToken()","cbbacd48":"cliffs(address)","cbbaed1b":"incentiveDistributionMaxRounds()","cbbb2698":"checkBlackAccount(address)","cbbc1bf3":"setCosignerAddressForUser(address)","cbbc8504":"GnosisTalk()","cbbc8a51":"setForeignDailyLimit(uint256)","cbbcdf77":"addCurrency(uint256)","cbbd809c":"approvedAddressInLUT(uint256)","cbbda00e":"Ptest()","cbbdca36":"Upgradable(address)","cbbe2199":"ActualTokenManager()","cbbe2569":"Bogocoin()","cbbe300b":"FooMintToken()","cbbe974b":"unlockUnixTime(address)","cbbea348":"getModeratorAtIndex(uint256)","cbbf879c":"getNumParentOperation(bytes32,uint8)","cbbf9420":"distributeVES(address[],uint256,uint256)","cbbfe168":"getOrder(uint256,address)","cbc066ab":"_transferOrderMoney(uint256,address)","cbc12d13":"maxRingSize()","cbc1cfd2":"emergency_withdraw()","cbc24224":"MuskToken()","cbc264f2":"nestedFirstAllToAll(uint256)","cbc265ac":"revealSeckey(bytes32)","cbc3b73e":"delegateHasValidSignature()","cbc3fb0d":"blind_sha256(string,address)","cbc44835":"PlateMate()","cbc469de":"STRToken()","cbc52ee4":"EtherIslands()","cbc598c5":"isAmountAllowed(address,uint256)","cbc61daf":"mintForMarket(address,uint256)","cbc69c8d":"SocialMediaToken()","cbc6c267":"ejenfwdToken()","cbc7755c":"registerNameXnameFromDapp(address,bytes32,bytes32,bool,uint8)","cbc7854e":"setTokens(address,address)","cbc846d9":"setBoosters(address)","cbc85c97":"getAllCardsClaimContender()","cbc8ae5f":"TOKEN_SUPPLY_ICO()","cbc9023c":"forceRoll()","cbc91e98":"sendTokensAfterBuyExp(address,uint256,uint256)","cbc9c89c":"Claim_TRAC_3800()","cbca02d3":"trasnferFromOwner(address,uint256)","cbcaacab":"checkTransferWithReference(address,uint256,string)","cbcabc13":"changeMdtTeamAddress(address)","cbcb3171":"tokenReserve()","cbcc65eb":"ACL_APP_ID()","cbccf9d6":"Simpletoken()","cbcd5dfe":"MintableMasterToken()","cbcdc2e4":"transferBalanceToOwner(uint256)","cbce2fcf":"setAmountBasedBonus(uint256[],uint256[],uint256[])","cbcf4d25":"icoAccounts(address)","cbcf8ece":"setAccountBonus(address,address,uint256)","cbcf98e6":"changeSecondaryWallet(address)","cbcffd2f":"ShowInfo(uint256,string)","cbd076f8":"depositForUser(address,uint256)","cbd07fd8":"paidDividends(address,uint32)","cbd08c8c":"config(uint256,uint256,uint256,uint256)","cbd1b782":"test_claimShare_notTranscoder()","cbd21f00":"JBartContract()","cbd243b4":"SetWhy(uint32)","cbd2ac68":"confirmWhitelistRemoval(bytes32)","cbd2bdfd":"getAllAuctions()","cbd2c73b":"signUserKeyChange(address)","cbd2ecd2":"transferAllowance(address,address,uint256)","cbd3b403":"getLuck(address)","cbd3faef":"amountOwedForApiForBuyer(uint256,address)","cbd49462":"_sender()","cbd5131b":"sponsoredBonusAmount()","cbd57134":"KTCToken()","cbd5bb2b":"setRound(uint8)","cbd6cc67":"SendDataToken(uint256,string,uint8,string)","cbd85c76":"bytesToBytes4(bytes,uint256)","cbd8877e":"stakeMinAge()","cbd8e690":"setTokenAmountPerHeritor(address,address,uint256)","cbd8ff79":"ContributionToPrizeFund()","cbd9597d":"GenChipLevel_Special(uint256,uint256,uint256)","cbd9d2e0":"InvalidCaller(address)","cbda1d85":"fundingGoalHardCap()","cbdb2469":"_getPetBonus1(uint256)","cbdb4f72":"GetClientBalance()","cbdc5aa4":"tokensTradeable()","cbdd3268":"genesisImportsComplete()","cbdd69b5":"tokensPerEth()","cbde2ff0":"isUnfreezed(uint256)","cbdf02fb":"rejectCertificate(address,address)","cbdf3878":"goldLevelBonusIsUsed()","cbdf8692":"Lockup()","cbe0a1aa":"totalEthCharityCollected()","cbe0e49a":"presaleGranteesMapKeys(uint256)","cbe211ec":"adPriceWeek()","cbe230c3":"isAllowedToken(address)","cbe239ed":"setIcoPaymentStatus(bool)","cbe23b94":"cards_start_total()","cbe29f34":"advisorsSupply()","cbe2e97e":"setGameStatus(bool)","cbe324d8":"_setSuggestedAdPrice(uint256,uint256)","cbe335c1":"verifyDocument(bytes32,bytes,uint16)","cbe37e25":"BYBToken()","cbe3a072":"add(uint32)","cbe3be97":"KeplerCoin()","cbe40622":"setup(address,address,uint256)","cbe432b0":"ico3Tokens()","cbe44fa2":"setWhitelisted(address,uint16)","cbe5404f":"setAccountFrozen(address,bool)","cbe56377":"amendLock(uint256,uint256)","cbe566de":"deleteCascade(uint256)","cbe7a150":"getCryptoMatch(uint256)","cbe7b838":"YunKaiCoin()","cbe8047e":"testValidation()","cbe8623f":"divUp(uint256,uint256)","cbe9ef39":"BasicCoin(uint256,address)","cbea4412":"getItemHolders(uint256)","cbeb5749":"ShoreCoin(uint256,string,uint8,string)","cbebc563":"computeTraitScore(uint256,uint256,uint256)","cbec09a7":"bonus01()","cbec455f":"continueCrowdsale()","cbec72f3":"ownerHasClaimedTokens()","cbec78b9":"requestPrice(string,string,int256)","cbed1568":"addAdminWhitelist(address)","cbedbf5a":"sendMoney()","cbeea68c":"permit(address,address,bytes32)","cbefe55c":"calcTokenRate()","cbf09802":"rateOf(address)","cbf0b0c0":"kill(address)","cbf0fa2d":"totalWageredForAddress(address)","cbf1304d":"balances(address,uint256)","cbf1382f":"founderStorageVault()","cbf1591d":"setDenyContract(bool)","cbf21837":"isSelling()","cbf26c0b":"DeviceOwner()","cbf2ad23":"confirmedBy()","cbf2b203":"Crowdsale(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool)","cbf346cc":"_sellCrowd(uint256,address)","cbf4531d":"dividendsAmount(address)","cbf66a02":"withdrawRune()","cbf6fff9":"SALE_SUPPLY()","cbf7c9a7":"isUserKyc(address)","cbf7cc2e":"deployFinished()","cbf7f009":"FAPFounder()","cbf89ed8":"DividendDeposited(address,uint256,uint256,uint256,uint256)","cbf9051c":"setPublisherRewardPool(bytes32,uint256)","cbf93c9b":"_claimExploreItemUsingEMont(uint256,uint256)","cbf97572":"HipsterFarmer()","cbf9a125":"queryChibiAdd(uint256)","cbf9b6dd":"getRecorderAddress(uint32)","cbfa18ea":"contractRefundFinished()","cbfa3c9c":"scaling()","cbfba0e1":"withdrawFee(bytes8)","cbfc12ba":"Soniq()","cbfd14a2":"publicSaleSupply()","cbfd79e2":"AirdropFan()","cbfe6d41":"documentExists(bytes32)","cbfebb34":"setETHRate(uint256,uint256)","cbff17fa":"_setMinted(uint256,address)","cbff2cfc":"_getValueEther(uint256,uint256)","cbff69db":"contributionAt(uint256,uint256)","cbffb1ae":"updateConflictResolution(address)","cc00814d":"setPublicOfferLimit(uint256,uint256)","cc00ce12":"set_arbits_sale_open(bool)","cc01e39f":"availableAmountToCollect(uint256)","cc0238be":"getsumdata2(bytes32)","cc027cc9":"register(address,uint256,address,address)","cc02d73f":"setColorContract(address)","cc03477d":"nMsgsWaiting()","cc03c342":"setPlatformAddress(address)","cc05d836":"executeOrder(bool,address[3],uint256[4],uint256,uint8,bytes32,bytes32)","cc062b58":"enableSelling()","cc06c359":"maxLevel()","cc06f5ea":"getPeriodReceivedBalanceFor(uint256,address)","cc071051":"purchaseWolk()","cc075fa7":"stopTeamTrade()","cc07a94d":"_createMobster(string,address,uint256,uint256)","cc07dc37":"userReferralsWei(address,address)","cc08ebf6":"CryptoSportZ()","cc09c6b3":"OXO(uint256,string,string)","cc0a26d1":"CurrentMined()","cc0b2c9f":"tokenToOwner(uint256)","cc0b5a5f":"cancel(uint256,address,address)","cc0b94b7":"getChannelStatus(bytes32)","cc0b9dff":"addExitToQueue(uint256,address,address,uint256,uint256)","cc0bb8e5":"proof_of_public_key2()","cc0d0c90":"BlueTitaniumClassic()","cc0e13e2":"enableMaintenance()","cc0e1f66":"startOver()","cc0e24e1":"CheckDOT(bytes32)","cc0e97c9":"logicContract()","cc0f1786":"feeDecimals()","cc0f65f7":"GetMinerData(address)","cc10145f":"ownerWithdrawRune()","cc1027ea":"_validateReferrer(address)","cc105441":"MMOcoin()","cc10d53d":"IsPatient(address)","cc10e401":"create(string,bool)","cc11298e":"getRewards(uint256,uint256)","cc121ac1":"unsoldTokensVault()","cc129f4d":"radd(uint128,uint128)","cc130482":"SUNX()","cc131be1":"CreateNewDraw(uint256)","cc135555":"currentGene()","cc1423bf":"releaseBubToken()","cc143ce9":"NewXRateProvider(address,uint16,address)","cc147334":"payAllRewards()","cc148bf4":"awardBalanceOf(address,uint8)","cc14a7a3":"paidAddress()","cc151c82":"tokensToSellOnce()","cc15bee7":"isPurchasingPaused()","cc15c26c":"buyTokensReserve()","cc15d080":"getEmployeeInformation(uint256)","cc1602df":"lotteryCore()","cc16e6e1":"TOTAL_RESERVE_FUND()","cc16f5db":"Burn(address,uint256)","cc17aa28":"numAdoptedAxies(address,uint8,bool)","cc181ca8":"king()","cc189d00":"Vault(address,uint256)","cc198380":"totalSoldSlogns()","cc1b63d5":"setStakeStartTime(uint256)","cc1b8de6":"freedWosPoolToTeam()","cc1bc747":"deallocate(address,address)","cc1c0937":"NeuralToken()","cc1d050d":"startBlockProfit()","cc1d1e18":"_getCurrentTokenPrice()","cc1d4c02":"certified(address)","cc1ef080":"startPreSTOSale()","cc204cc2":"amountsWithdrew(address)","cc20d075":"getChannelId(address,address,uint8)","cc212a48":"disburseFunds(uint256)","cc21a9a2":"_weekFor(uint256)","cc21e972":"US_INSTITUTIONAL()","cc234ee1":"setICORunning(bool)","cc23a690":"releaseValue2()","cc23b75b":"HARD_CAP_IN_TOKEN()","cc242f40":"CardsRead()","cc24f571":"releaseTenPercent()","cc255b38":"testBazMethodId()","cc25decd":"SampleOffer(address,bytes,uint256,uint256,uint256,uint256,uint256)","cc268393":"setDescendant(address)","cc2761a4":"test_me(int256)","cc27f97b":"LSYP()","cc289fa9":"getPartnerAddressStatus(address)","cc293aea":"setRenewalsCreditAffiliatesFor(uint256)","cc2942da":"SetAElfCommunityMultisig(address,address)","cc29a0e6":"transferTTProduction(address,address,uint256)","cc2a9192":"LogWinnerPaid(address)","cc2aa2c7":"NAMINORI()","cc2b20ff":"refferBonusFunction(uint256)","cc2c2058":"addSpinner(string,uint256,address,uint256,uint8,uint8,uint8)","cc2c2bcf":"MotionFactory(string,string,string)","cc2c5453":"add_sword(uint16)","cc2dcd7e":"removeSideService(address,uint256)","cc2e08ea":"getRecTransactionData(uint256)","cc2e15cc":"getSponsorableJobs(address)","cc2eacb1":"setReferralPercent(uint16)","cc2f5029":"updateNoteMetadata(uint64,uint16)","cc2f5186":"Balances(address,address,address)","cc2fd120":"unofficialUserSignUp(string)","cc304924":"DocumentAdded(uint256,string,uint256)","cc305ae6":"userAssignElement(uint256,uint256,address)","cc308a54":"whitelistStartBlock()","cc3154f8":"attendeesList()","cc326e1c":"currentPhaseRate()","cc328f2f":"b531647b()","cc32f8ad":"transferMoneyForTaskSolutions(string,uint256)","cc33ad3d":"DSP(uint256,string,string)","cc33c875":"tokenInfo(uint256)","cc341430":"coordinatorAgreeForEmission(address)","cc342eba":"RoseToken()","cc3451d6":"MultiverseToken()","cc3471af":"maxClaimBlock()","cc348429":"Ethmall(address,address,address,uint256,uint256,uint256)","cc34a247":"icoEndTimestampStage1()","cc34f810":"AllstocksToken()","cc361cc4":"getTotalBonusPerShare()","cc364f48":"getRange(uint256)","cc36809f":"fee_msg()","cc36a328":"team0Query()","cc36f8eb":"ArtCoin()","cc373d79":"withdrawCommissions(uint256)","cc38639f":"newTuneOption(uint32,uint32,uint256,bool,bool,uint128,uint64)","cc38c8a0":"insuranceAccount()","cc3938f9":"chkLockedA(address,uint256)","cc397ed3":"getCurrentFor(address)","cc3a0c8d":"customerExchangeEther(uint256,address,string)","cc3ad9a1":"unPackParams(uint256)","cc3b8806":"getCertificateMetaDataCount(bytes32,bytes32,bytes32)","cc3bb31a":"crowdsaleStart()","cc3bde3d":"TOTAL_SUPPLY_LIMIT()","cc3bf9e9":"redeem(bytes32,address)","cc3c2c01":"getValidityBondFloor()","cc3c59cc":"Paymec()","cc3c7098":"createTokenToMarket2021()","cc3c74a1":"proposalNonce()","cc3ccf57":"previous_owner()","cc3d2721":"minWithdraw()","cc3d574b":"ElectedBoardController(address,address[],uint256,address)","cc3d967b":"getUserDetails(address)","cc3df01f":"issueToken(uint256)","cc3e378e":"hasEnoughFundsToStart()","cc3eacbb":"getOraclizeFee()","cc3efd6b":"PUKCoin()","cc3f44bf":"getGoldStatusMinted(address)","cc3f51d0":"hitPotProcess(string,bool,uint256)","cc3fa0fd":"NobleAssetsCoin(uint256,string,string)","cc3fdd4c":"buyFeePercent()","cc41a396":"rateStage3()","cc41d3b2":"refundPreIco()","cc422cc2":"coeRemainingAtCurrentRate()","cc423c28":"setSchellingExpansion(uint256,uint256)","cc42e83a":"withdrawWinnings()","cc436196":"initialFundsReleaseDenominator()","cc436e42":"memberIsActive(uint8)","cc442c3f":"ICO_PRICE4()","cc445611":"purchase(bytes32)","cc44b15b":"setCode(address,bytes32,uint256)","cc44fd2b":"changeManagement(address)","cc451581":"getCurrentBigPromoBonus()","cc4580c8":"getBetsLength()","cc459696":"contentCount()","cc466256":"_roll(address,uint256,uint256,bytes32,bytes32,bytes,bytes32,uint256)","cc4720c7":"calculateRewardTokens(uint256,uint8)","cc47a40b":"reserve(address,uint256)","cc47de73":"ExpandT()","cc490e64":"getSplitCount()","cc494291":"setJobController(address)","cc4999ea":"getTradingInfo(uint256)","cc49ede7":"getVesting(address)","cc4aa005":"getDestroySharesOwnerValue()","cc4aa204":"ERC20()","cc4b998a":"titleIds()","cc4bf6a3":"miningTen()","cc4c1c05":"SwytchToken()","cc4cc05f":"collectToken()","cc4d233c":"Reclaimed()","cc4d819c":"tokensPurchased()","cc4da8f4":"EventWinReward(address,uint256)","cc4e0008":"Ticket(address)","cc4fa81b":"exchangeCalculator(uint256,uint256,uint256)","cc4fbc43":"acceptTokenPayment(address,uint256,address,uint256)","cc5061da":"voteForUser(uint16,address)","cc50dacb":"buyCar(uint32)","cc50fc28":"mintInternal(int256,address,uint256)","cc537821":"buyNextRank()","cc539eb1":"replaceAccount(address,address)","cc552c8e":"setHardCapUSD(uint256)","cc5530eb":"endPreSaleStage()","cc577f38":"addPresaleAmount(address,uint256)","cc57e4f8":"increasePregnantCounter()","cc58bcf8":"getCurrentLevel(uint256,uint256,uint256)","cc5a7051":"_setMinDailyPerUser(uint256)","cc5a7804":"payoutTokens(address,uint256,uint256)","cc5aba27":"ConstructorTest(uint256,uint256,string,string)","cc5b13a0":"PAYOUT_DELAY_INTERVAL()","cc5b2292":"DepositForDividends(uint256)","cc5b542e":"toBeDistributed()","cc5c095c":"mintableSupply()","cc5c4224":"setFreezingManager(address)","cc5c4a6b":"attachPresale(address,address)","cc5cab33":"userRewarders(address,uint32)","cc5cee0a":"calculateEthereumReceived(uint256,uint256)","cc5f09fb":"getNbCitizensLocation(string)","cc5fc0d7":"updateInvestBalance()","cc603ed5":"collectRate(address)","cc61d0cb":"changeMinWithdraw(uint256)","cc620704":"joinToTrack(bytes32)","cc6266a1":"getHashFromData(bytes32,bytes32)","cc6305ed":"getNumTicketsPurchased(uint256,address,address)","cc634dac":"get_kek()","cc63604a":"canExecute(uint256)","cc638e03":"rublaJEPoken()","cc63996e":"getHairValue(uint256)","cc63a3c9":"set_token(address)","cc642cc2":"numHolders()","cc64cfcb":"getDeployedMarriages()","cc64e2d5":"depositEthers(address)","cc657697":"GetMatchLength()","cc657e62":"sendToken(uint256,uint256)","cc668524":"verifyPosition(uint8,uint64,uint64,uint64)","cc66d3c7":"buyEngineer(uint256[8])","cc66ec47":"TerraformReserve(address)","cc677679":"setEMAPeriods(uint256)","cc679ffc":"TUPC()","cc67b1bf":"getTransferPerc()","cc69084f":"PHASE_CLOSED()","cc691763":"draw(uint32,uint8,bytes32)","cc6c010d":"ATMGold(uint256,string,uint8,string)","cc6c8e31":"NFXCoinToken()","cc6ca7b7":"specialBaseLayer(uint256)","cc6cf340":"BERTCLUBCOIN()","cc6d7850":"burnILF(address,uint256)","cc6d8ba6":"inheritInvestorPosition(uint256)","cc6da375":"recipientVIP(address)","cc6db55f":"setJackpotModulo(uint256)","cc6e15e5":"setDelayedTokenAllocator(address)","cc6e6f25":"Withdraw_5()","cc6e70e8":"MSTCOIN()","cc6e8593":"lawSupportProfitAddress()","cc6ec39a":"switchToGame(string)","cc6eced7":"priceOfTeam(uint256)","cc6f0ed0":"BirthdayCandy()","cc70993d":"earlyTimeLock()","cc70bb1a":"publish(string,string,string,address)","cc70decb":"showBonus(address)","cc7188a5":"unLinkFromMasterWallet(address)","cc724b27":"isTesting()","cc72c918":"queryOwnerAddr()","cc72ecb0":"purchaseStartBlock()","cc741c9c":"getDidClaimBooty(address,uint256)","cc743a86":"ICO_PROMO_REWARDS()","cc74e2ca":"min_refund_block()","cc750395":"setMonthOpen(uint256,uint256,uint8,uint256,uint256)","cc754a28":"ICOStartTimeChanged(uint256)","cc755b70":"releaseFrozenBalance()","cc759458":"unconfirm(address)","cc759f88":"removeBools(bytes32[])","cc75ac19":"_withdrawAffVault(uint256)","cc75c4b1":"abc(uint256)","cc75cc9b":"SendmoneyCall(uint256)","cc764986":"updateEmaDailyYield(uint256)","cc774681":"mapCompletionNumberForWithdraw(address)","cc77b82d":"BEEFYToken()","cc783c5e":"setBankrollerContractOnce(address)","cc78cc98":"multisigPreICO()","cc7949ae":"round_count()","cc797d8e":"setMaxAttackPrizePercent(uint256)","cc798890":"queryAccounts()","cc79aa04":"getProposal(bytes32,bytes32)","cc79eaf0":"getColors(uint32)","cc7a060f":"ethersCollecteds()","cc7a2049":"permissionManager()","cc7b2ee7":"initAirdropAndEarlyAlloc()","cc7b41ec":"changeRollUnder(uint256)","cc7b60fe":"_emitWorkFinished(uint256,uint256)","cc7c4c39":"gotWinner()","cc7cd9f8":"fundingEthGoal()","cc7cddb8":"dive3(address)","cc7d1a0f":"currentHighestBid()","cc7e1b9a":"setRedemptionAddress(address)","cc7e2208":"Order()","cc7e492e":"refillInstantMintPool()","cc7e930c":"commitmentsOf(address,address)","cc7f365c":"VLADALINA()","cc7f593c":"setRequiredMajority(uint256)","cc7f608d":"setSaleType(uint8,uint8,uint32,uint256,uint256)","cc7f8266":"read_i8_array()","cc7fa928":"nbMonthsPay()","cc7fe38c":"addPresaleInvestor(address,uint256,uint256)","cc80f6f3":"show()","cc80f9e8":"ownerOfID(uint256)","cc81dbb5":"DEFROST_FACTOR_TEAMANDADV()","cc822f54":"changeYDistAddress(address)","cc826160":"ownershipDistributed()","cc82e72e":"SetPlatformInformation(string)","cc833e69":"Cryptonationz(string,string,uint8,address,address,address,address,address)","cc851cac":"SecuritiesVaultBank()","cc863948":"withdrawTokenShare()","cc86566c":"tempMngr()","cc8658b3":"chkStaff(address,address)","cc865b71":"withdrawRoundController(uint256,address)","cc872b66":"issue(uint256)","cc876ded":"born(uint256,uint256)","cc87ed82":"checkNumCards(uint256,uint8,uint8,bytes32,bytes32)","cc8818f6":"setReservefund(uint256)","cc88be52":"NuoBaoChainToken(uint256,string,uint8,string)","cc891023":"depositLock(address)","cc896494":"_setGameOver()","cc89698c":"getTopicCount()","cc897e40":"END_SKO1_UNITS()","cc89d596":"getCryptantFragments(address)","cc89e8bc":"ecosystemTokens()","cc8a86a0":"Y2_release()","cc8af0fe":"bytesToUInt(bytes,bytes)","cc8b34ab":"CrowdCoin()","cc8b96e5":"prepare(uint256,address,address)","cc8baf63":"m_tokenDistributor()","cc8bd060":"setUnitsOneEthCanBuy(uint256)","cc8c0f9f":"transferLocked(address,uint256,uint8)","cc8c3c45":"getTokenIdsLength()","cc8c49aa":"sc(uint256,uint256,uint256,uint256,uint256)","cc8cd5c5":"withdrawDragonsFilm()","cc8ce27e":"CryptoChamps()","cc8ce862":"allowedGasPrice()","cc8e4bc2":"LOCKAMOUNT3()","cc8eb425":"newuser(address,address)","cc8f0b48":"withdraw(bytes32,address,uint8,bytes32,bytes32)","cc90050e":"GetCurrentRoomAndRound(address)","cc9062f9":"finalizeTransferChildrenOwnership()","cc90da29":"bonusNum()","cc90e725":"addProject(string,address)","cc91e91c":"Freezable()","cc925957":"logAccess(string,string,uint256)","cc92bad4":"updateParkingRate(uint256)","cc92ebad":"createCrowdsale(uint256,uint256,uint256,uint256,address,address,address)","cc937ccd":"Doves()","cc93ee70":"forwardCoins(uint256)","cc93f66e":"endTournament(uint256,uint256)","cc9415d0":"commitOn(uint256)","cc9425b7":"OCTACryptoToken()","cc949797":"balanceAffiliateOf(address)","cc94d923":"createTransaction(address,uint256,bytes32,address,address,address)","cc94e4a2":"set_sale_address(address,address)","cc954820":"changeFallbackDeposit(uint256)","cc95d8d1":"s36(bytes1)","cc96019f":"referralTokenWallet()","cc96b943":"offerOptionsToEmployee(address,uint32,uint32,uint32,bool)","cc976620":"usdPerEthCoinmarketcapRate()","cc97b38f":"BANCOR_X_UPGRADER()","cc97edbf":"bmi()","cc98c893":"developer_Transfer_ownership(address)","cc98ff20":"purchaseVillage(uint256)","cc991d8a":"BTestToken(uint256,string,uint8,string)","cc996d1b":"bids()","cc9a31a7":"isRepresentor(address)","cc9a88c9":"canSend(uint32,uint32,int256)","cc9ab267":"voteForCandidate(bytes32)","cc9ac376":"addLock(address,uint256,uint256)","cc9ae3f6":"getMyReward()","cc9b31c9":"exchangeFeeIncurred(uint256)","cc9b714c":"ClearAuth(address)","cc9b71c2":"TaskCoin()","cc9b7826":"setGuaranteedAddress(address,uint256)","cc9ba6b2":"buyRef()","cc9c0936":"startedWorkTS()","cc9c437c":"get_orderAddress(address,uint256,uint256,uint256,uint256)","cc9d7519":"getTierInfo(uint256)","cc9d858d":"FundsRegistryTestHelper(address[],uint256,address)","cc9de25d":"bytesToUint256(bytes)","cc9e735f":"decrementDate()","cc9f28ea":"getDeletedTeams()","cc9fd9d9":"onSetCredit(address,uint256)","cca07f44":"setSpecialLimits(address,uint256,uint256)","cca08d55":"updatesolsforhire()","cca0feb6":"updateTax(uint256)","cca10ba5":"getMultiSigBalance()","cca213a1":"setTranchTime(uint256[])","cca2194c":"getInvestorContribution(address)","cca26917":"getRoundBalance(address,address,uint256)","cca3e832":"_balanceOf(address)","cca40111":"_recharge(address,uint256)","cca41651":"addressPrivateSale()","cca470d2":"roundInvestorInfoByAddress(uint32,uint32,address)","cca4f3c5":"winthdraw(address,address,uint256)","cca5020b":"totalLBSold_PRIVATE()","cca5dcb6":"isTransferEnabled()","cca63f4f":"buyXname(uint256,uint256,string)","cca6ae0b":"getGPSMinEth()","cca746df":"getAnnualFee()","cca78d53":"getActiveListLength()","cca794da":"setGzeBonusOnList(uint256)","cca91579":"PlaceHolder(address)","cca97025":"_performTransferFromWithReference(address,address,uint256,string,address)","cca9943c":"wei25()","ccaa5135":"LIFECOIN()","ccaa5c65":"LomeliToken()","ccaab1ca":"companyPercent()","ccaaef45":"purchaseCompanyAdv(uint256,string,string)","ccab1be7":"SubmissionAccepted(address)","ccab841b":"divf(int256,int256,uint256)","ccabcfca":"XMLYBadge()","ccac77f5":"GooLaunchPromotion()","ccad19e4":"sendEtherFromAddContract(address)","ccadd6b1":"bet1Of(uint256)","ccadef15":"_setOCPTokenContract(address)","ccae794a":"showFPCount()","ccaee929":"JihoyContract()","ccaf4b03":"setIreg(uint256)","ccb00344":"changeEtsAddress(address)","ccb07cef":"crowdsaleClosed()","ccb0893d":"isUIntPrivate()","ccb13cbd":"_acceptAnchorAdmin()","ccb1c0a1":"getQuestion(string)","ccb1cbbc":"testFailBurnNoAuth()","ccb20e8e":"StormBrewCoin()","ccb22e37":"description3()","ccb2e9a4":"insertAccount(bytes32,string,uint256,string,string)","ccb3449e":"NewPresaleAllocation(address,uint256)","ccb50a29":"SIGMA_MAX_CARGO()","ccb53365":"startICOPhase()","ccb60e39":"rentOutMultiple(address,uint256,uint256[])","ccb61dad":"MICRO_DOLLARS_PER_BNTY_MAINSALE()","ccb64997":"isBCDCToken()","ccb6cbe8":"icoBottomIntegerPrice()","ccb767ae":"transferTo(address,uint32)","ccb783a9":"setGPSStartTime(uint16,uint8,uint8,uint8,uint8,uint8)","ccb98ffc":"setEndTime(uint256)","ccbac9f5":"randomNumber()","ccbae5f6":"createEscrow(address,address,uint256,uint256)","ccbb41d0":"TOC()","ccbb52f5":"getGroupRates(uint256)","ccbba441":"setMigrateStage()","ccbd5152":"bankrollBeneficiaryAmount()","ccbd8d25":"setDropAmount(uint256)","ccbd8d29":"tokenAvatar()","ccbda1af":"getChannelByName(string)","ccbde432":"delete_candidate(uint8)","ccbe2a68":"kill(uint8[176],uint8)","ccbe4968":"Withdawal(address,uint256)","ccbfc6ed":"revokeSignature(bytes)","ccc08913":"Restricted()","ccc08974":"setGameActive(bool)","ccc108d7":"reopen()","ccc11f11":"hasAssetRights(address,bytes32)","ccc13814":"max(int256[])","ccc39b5d":"DonationClaimed(address[2],uint256[8],uint8,bytes32[2],uint256,uint256)","ccc51afb":"lookupFillingRing(address,uint256)","ccc54d69":"LOCKUP_3M_ICO_TIMESTAMP()","ccc55189":"Nation(address,address)","ccc5d05f":"testNoTokensNoCalls()","ccc61bef":"REWARD_WIN_MULTIPLE_PER()","ccc62bbe":"assertEq2(bytes2,bytes2,bytes32)","ccc643d7":"updateSaleTime(uint256,uint256)","ccc6ddf3":"createPromoPow(address,string,uint256,uint256,uint256,uint256)","ccc72302":"AUDITED_AND_REJECTED()","ccc8b33c":"buyXnameQR(address)","ccc924ef":"TokensUndelegated(address,uint256,address)","ccc9735d":"ERCSpammer(uint256,uint256,string,string)","ccc98790":"w(uint256)","ccca123b":"waitTime()","ccca237c":"foundationAsset()","cccb987f":"withdrawTwice()","cccc020f":"changeInsuranceFeesOperation()","cccc8f91":"getDappId()","ccccc36b":"createAcceptAndAdditionalsFromBytes(bytes,bytes,bytes,uint256[])","cccd2ea8":"getProductData(address)","ccce413b":"symbols(uint256)","ccce6458":"createKingdom(string,string,uint256,bool)","ccceee48":"lastBlock_v1Hash_uint256()","cccf3a94":"gasForCLOUD()","cccf7a8e":"has(uint256)","ccd15921":"addTransferAndCallWhitelist(address)","ccd1a621":"addguess(uint256)","ccd30a62":"getWhitelistedAddresses(uint256)","ccd331bf":"bountyAmount()","ccd385f5":"staff_3()","ccd3948b":"removeRestaurant(address)","ccd39537":"dilute(address,uint256)","ccd4020c":"PassTokenReborn(address)","ccd46ae4":"BuyTicketUseVault(uint256,uint256)","ccd65296":"initialize(uint256,uint256,uint256,uint256,address)","ccd6559b":"newRandom(string)","ccd65c0a":"activateMainSale()","ccd68f3b":"stamps(uint256)","ccd6aca4":"preSaleSecondCap()","ccd71e8c":"armySubmarinesCount(uint256)","ccd75361":"setFooInt(uint256)","ccd89ecd":"calculateManyHash(address,address[],uint256[],uint256,uint256)","ccd8ad0c":"setGenTime(uint256)","ccd8c186":"DebitCoinTokenGenesis(address)","ccd8e2cf":"AnmiToken()","ccd8ead7":"addToCategorie2(address,address)","ccd93998":"getRequiredSignatures()","ccd95a50":"sendTokenToMultiAddr(address[],uint256[])","ccd96ab0":"cite(bytes32,string)","ccd9aa68":"passedKYC(address)","ccd9d08f":"MLIOU()","ccda4b99":"getMethodValue(string)","ccda696b":"ownersTransfer(address,uint256)","ccdaeab0":"getTechBonus3(uint256)","ccdb05d4":"NokuCustomERC20(string,string,uint8,address,address)","ccdb3f45":"newAddress()","ccdbbff5":"securityTokensWallet()","ccdc535e":"placeBetV1(uint256,uint256,uint256)","ccdd1979":"multisend(address,address[],uint256)","ccdd49f2":"StyToken(address,address)","ccdd95d6":"releaseEnjinTeamTokens()","ccdf68f3":"isOutcomeSet()","ccdfcfa4":"returnFundsForAll()","cce0244d":"setSafeContract(address,bool)","cce0a1ca":"isPresaleSetup()","cce0c0fa":"addOneGame(string,uint256)","cce0cd0c":"blockVersion()","cce106f8":"AmountToLittle()","cce1dfd2":"minimum_token_sell()","cce21eda":"DividendsWithdrawal(uint256,address,uint256,uint256,uint256,uint256)","cce2270a":"isSecondStageFinalized()","cce2771e":"redeemUTXO(bytes32,uint8,uint256,bytes,bytes,bool,uint8,bytes32,bytes32)","cce29ea7":"preSaleEndTime()","cce2f8e3":"checkAddressMisused(address)","cce356b5":"getHodlers()","cce3906b":"hasWithdrawnRake()","cce48e65":"GeeTestCoin()","cce4bd52":"reclaimFunds()","cce7db58":"swipe(address)","cce7ec13":"buy(address,uint256)","cce81927":"EtherDice(address,address)","cce91957":"take(bytes)","cce93ae1":"PeriodChanged(uint256,uint256)","cceb6368":"receiveTicket(address)","cceb9214":"setAuctionStatus(bytes32,uint8)","ccebca11":"Foo(address,bytes32,address)","ccec1461":"bulkEtherSender(address[],uint256[])","ccecc71f":"getPlayerPoints(bytes32)","cced2bb6":"LogOwnerRemoved(address)","cced9b63":"setBestMatch(uint256,uint256,address)","cceda56c":"CAPPED_SUPPLY()","ccedf3d2":"getChainCode(string)","ccee31e8":"setNbKingdomsType(uint256,address,bool)","ccee8047":"settleCall(uint256,uint256,address)","ccef6d63":"_isClientPaidUp(address)","ccf053ba":"TOTAL_TOKEN_SUPPLY()","ccf06abf":"canCompose(string,uint256[],address)","ccf0768a":"transferDividends(address)","ccf12304":"set_mint(uint256)","ccf1454a":"addressOf(string)","ccf1ab9b":"usurpation()","ccf1e80b":"JUNE()","ccf20872":"ChainKey(uint256,string,string)","ccf24838":"updateOwner(uint256,address,address)","ccf27a4e":"setPrice2(uint256)","ccf2b87b":"sendWithFreeze(address,address,uint256,uint256)","ccf41499":"TokenFactory(uint256,string,uint8,string)","ccf4a941":"getVendorApplication(string)","ccf4b70a":"RATE1()","ccf4f413":"setSubRegistrar(string,address)","ccf53a84":"getFile(uint8)","ccf5401e":"checkQuest(address)","ccf5c5cf":"registerConsumer(address,uint32)","ccf64316":"playerRollDiceSingle(uint256)","ccf670f8":"setLevelUpFee(uint256)","ccf69e9b":"randomContract()","ccf6b8b3":"CCCoinToken(string,string,uint256,uint256,address,address,address,address,uint256)","ccf7ba0f":"recoverPrice(address,address)","ccf7d0d4":"sendTokensAfterCrowdsale()","ccf7fe56":"JustinCoin()","ccf82afd":"WataexToken()","ccf8bcf3":"transferOVISBookedTokens()","ccf8e5d0":"CLITOKEN()","ccf8ef24":"undelegateVote()","ccf9f35f":"awardsCount()","ccfa8e71":"addBank(string,address,string)","ccfaa72f":"setRentalPricePerHour(uint256)","ccfbdb9e":"CrowdSaleDapCar()","ccfc0053":"withdrawMILs(uint256)","ccfc1e4e":"preSaleWeiCap()","ccfc811b":"registerParticipant()","ccfc8729":"registerWithToken(address,uint256,address)","ccfc9556":"USDChain(uint256,string,uint8,string)","ccfcbdbe":"canMakerTerminate(bytes32)","ccfdca9a":"setMinPaymentAmount(uint256)","ccfe4691":"CtfToken()","ccfed305":"CMDToken()","ccff361f":"AibitbankToken()","ccff42b2":"isValidAdapter(address)","cd008f1a":"getMine()","cd00ee0d":"startToken()","cd027be5":"getAllowAmount(address)","cd034234":"refundRequest()","cd0389fd":"metadataToken()","cd03b093":"getSupportersForTopic(string)","cd041ae9":"removeCooldown()","cd048de6":"setWord(string)","cd04ccfc":"newProposalEthUSDOracle()","cd05c214":"TOKEN_FOURTH_PRICE_RATE()","cd05d1eb":"shopPants()","cd062734":"getCallABISignature(bytes32)","cd0643ee":"takeInvestments()","cd066fd6":"computeInitialPrice(uint256)","cd0699e9":"OysterPrePearl()","cd06a7bf":"rewardsupply()","cd076620":"mint(address,uint256,int16,int16,int16,int16,int16,int16,uint256)","cd0845fd":"bool2str(bool)","cd09039b":"PayForFlag(string)","cd09263f":"rate_toCap()","cd0a314b":"walletBalance()","cd0c5896":"etherBalance(address)","cd0c870d":"XAP()","cd0e761d":"getCurrentContextAddress()","cd0e8900":"DEFACTO()","cd0ee59b":"_payByErc20(uint256)","cd0f26c6":"setRedemptionContract(address,address)","cd0f5abd":"DTCC()","cd0fdc24":"getPaintingArtistId(uint256)","cd0ffdba":"NukTestToken()","cd103b4d":"RateToken(uint256)","cd11731d":"setPlayerBookAddress(address)","cd11c85d":"timeTillNextAttack()","cd12efc8":"getsecond(uint256[])","cd132aad":"addPrivateSale(uint256)","cd133c8f":"buyXid(uint256)","cd13592a":"claimTokensByUser()","cd152c0a":"getPreAuthorizedAmount(address)","cd154c59":"mainSaleExchangeRate()","cd15c6ab":"MANACrowdsale(uint256,uint256,uint256,uint256,uint256,address)","cd15fc71":"ContractFeatures()","cd16ecbf":"setNum(uint256)","cd17c4b6":"numOfTokens()","cd180fdc":"transferTokensFromAdvisorsAddress(address,uint256)","cd1814d7":"selfDestroyTime()","cd187043":"_price_token_ICO1()","cd18c168":"TakeEth(address,uint256)","cd18d5a4":"airDrop(address)","cd197ff6":"fechVoteInfoForVoter(address)","cd1a4e4d":"setHyperDisbursementAddress(address)","cd1a5cad":"PricingStrategy(uint256,uint256,uint256,uint256,uint256,uint256)","cd1a8ad7":"EGGS_TO_HATCH_1SNAKE()","cd1b9311":"challenge(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[])","cd1ce6d5":"setAdvisorFee(uint256)","cd1dc527":"isTokenAddressAlreadyInList(address)","cd1e0355":"totalRefundedAmount()","cd1e0717":"getRequester()","cd1e484b":"reserveStarsForOwner(uint256)","cd1f63dc":"getMinBuy(uint256,uint256)","cd1f8393":"logsCount()","cd1f9a57":"totalContractHolders()","cd1fca94":"BETNetworkTeamAddress()","cd1fdc14":"_claimReward20(address,string)","cd2057d0":"fail(bytes)","cd20b24b":"saosao5()","cd22ccea":"GameRoll(address,uint256,uint8,uint8,uint256)","cd22f418":"_getAllRevisionTimestamps(bytes32)","cd22f536":"addProductByRegulator(string,uint256,string,string,string,string)","cd230ebd":"tokensClaimableAfter()","cd233e25":"oraclize_gaslimit()","cd257213":"RemoveTickets(uint256)","cd25f56e":"OptionExercise(address,uint256)","cd26e1a8":"SECURITY_ETHER_CAP()","cd271488":"newSaleProjects(string,string,string,uint256)","cd277e6c":"addSolution(bytes32,address,uint32)","cd27d1a0":"setMaxRaiseAmount(uint256)","cd27f1d9":"cappedTokenSupply()","cd29c71a":"metadataUrl()","cd2a0c29":"purchase_with_eth(uint256,address,uint256,uint256,uint256,address,bytes)","cd2a11be":"EnableTrade(bool)","cd2a68e5":"withdrawBillionsCoins()","cd2a7a61":"broadcastState(bytes)","cd2ab49e":"setupBankrollInterface(address)","cd2b5a82":"weiToDistribute()","cd2cdd5b":"claimOwnershi()","cd2cde48":"authorizeIcoBurn()","cd2d5291":"walletAdvisor()","cd2d8a2d":"historyId()","cd2ec3fe":"runAnnualInflation()","cd2f0710":"getItemById(uint256)","cd2f5f2b":"clearFooArray()","cd2f7357":"tokenTransfer(address,uint256,uint256)","cd2f7c1a":"Census()","cd306137":"initialiseGlobals()","cd31037c":"BlockScheduler(address,address,address)","cd313ad9":"listOfFunds(uint256)","cd31f391":"SixtyPercentRules(address)","cd3265a3":"setUpgradeTarget(address)","cd327398":"addExceptions(address[])","cd3293de":"reserve()","cd336707":"reopenContributions()","cd342917":"Lesson(address,uint256)","cd35c5e9":"Eurotrad()","cd3651a7":"setLevelBonusJPYC(uint256,uint256,uint256,uint256)","cd367936":"fundICO(address)","cd37dcb8":"peCap()","cd3882d5":"stage4()","cd38aa87":"chooseWinner()","cd394a41":"ETH10K()","cd395a96":"_transferAndLock(address,address,uint256,uint256)","cd3a1dde":"MaxAirDropXblock()","cd3a376a":"changeSeller(address)","cd3a7531":"loadVotesForParticipantVerify(bytes32,bytes32,uint8)","cd3b0309":"CTokenCoin()","cd3c3011":"getPublishTime(bytes32)","cd3ce306":"redeemEther(bytes32,address)","cd3de8d5":"payToController()","cd3e0155":"BucketDestroyed(bytes32,uint256)","cd3e45c5":"getTop10Messages()","cd3f7a50":"DepositMTU(uint256)","cd3fe21d":"getTotalNumberPlayed(uint256,uint256)","cd40137f":"resetTimeSeal()","cd402189":"list_files()","cd402c8e":"payoutSize(address)","cd40a48d":"send1Mil(address)","cd41ada1":"addressDividendReserve()","cd4217c1":"freezeOf(address)","cd423c99":"getDistributedOreBalances(address)","cd42693d":"victorieumToken()","cd43def3":"updateServiceTokensPerCredit(address,uint32,uint256)","cd43ebf9":"totalSpankStaked()","cd43ee99":"isAffiliateProgram()","cd45376c":"sellWine(uint256)","cd45e561":"CHSToken()","cd45fcdb":"Fxxk2Token()","cd46abe4":"ecosystemPercentOfTotal()","cd46d7e5":"approveByIndex(uint256)","cd474b04":"chainStartBlockNumber()","cd47c0e1":"cooRemoveReviewer(address)","cd47f390":"rescueLostKydy(uint256,address)","cd482d9f":"getLLV_edit_2()","cd48578f":"MaxEth()","cd495391":"setNonlistedUser(address)","cd496e35":"votePositionOf(uint256,uint256)","cd497999":"isHardCapGoalReached()","cd499523":"userList(address,uint256)","cd4aed30":"errorWithMessage()","cd4b3c57":"newSubdomain(string,string,address,address)","cd4b6914":"getRandom(uint256)","cd4c04c6":"Appoint(uint256,address)","cd4c4c0c":"getCurrentBucket()","cd4d0570":"getbuynode(address)","cd4d1664":"EconomyRebated(string,string,string,string,string)","cd4d4b46":"BONUS_CAP()","cd4d6895":"verifyEIP20(address)","cd4e28b5":"setNextBidExpireBlockLength(uint256)","cd4e396b":"USER_ACQUISITION()","cd4f5e90":"MTToken()","cd4fb3be":"newBurnableOpenPayment(address,string,uint256,uint8,uint256)","cd501bf7":"SignalsCrowdsale(address,address,address,address)","cd503c0b":"claimFees(bytes4)","cd50d44f":"CheckRepresentment()","cd51bcae":"setBuyRequestLimit(uint256)","cd51f084":"owner_freeze_term()","cd5286d0":"getAsset(string)","cd53a3b7":"makerWithdrawAsset(uint256)","cd53ac45":"MANHATTANPROXYFDR()","cd53e455":"receivedEther()","cd5406e4":"getBalanceAtSnapshot(address)","cd54c54e":"setCirculationCap(address,uint256)","cd550cc8":"XferMoneyTeamAddress()","cd55205b":"KotET()","cd559561":"getPeers()","cd55cda2":"determineFinalOutcome(uint256)","cd56028f":"ArjToken()","cd560862":"EZ25COIN()","cd5617b6":"STCDR()","cd5655da":"setPixelBlock(uint256[],uint256[],uint256[],uint256[])","cd565bc5":"determineAffID(uint256,uint256)","cd5681d5":"mintRefs(bytes32)","cd568d0f":"submit(string,int8,int8,int16,string)","cd56f019":"getDefaultClaim(address)","cd572a07":"BOF()","cd575c32":"mintGem(uint256,string,uint256,bool,uint256)","cd576dd0":"IPAC()","cd5777e2":"allocateTokensToInvestors(address,uint256)","cd57a448":"SwapContract(address,uint256)","cd57a650":"BasilNetwork()","cd584045":"enableApproval()","cd586a50":"OnliCoinToken()","cd58a867":"internalAssignTokens(address,uint256,uint256,uint256,uint256)","cd58e75b":"newBurnableOpenPayment(address,uint256,uint8,uint256,string)","cd591822":"CanaryV7Fast()","cd59bf5b":"getNowFromOwner()","cd5a489d":"killContract(bool)","cd5a57cb":"registerOpinion(uint256,string)","cd5a9bf3":"isCurrentOrPastAccountMinter(address)","cd5ab612":"buyEmptyPixelArea(uint256,uint256,uint256,uint256)","cd5acd4d":"setKey(bytes32,bytes32,bytes)","cd5b4ae0":"zHQPreSale()","cd5b8837":"distributeGREEN(address[],uint256,uint256)","cd5ba752":"firstPlacePot()","cd5ba978":"presale_end_block()","cd5bfb63":"tokenIdOf(bytes32)","cd5bfbe4":"initialVestAmount()","cd5c222f":"msgMap(uint256)","cd5c4c70":"deleteOwner(address)","cd5d6c2b":"betInfoIsLocked()","cd5d950f":"TaxiToken()","cd5dba1e":"WhiteElephant()","cd5dd1d0":"showMsgSender()","cd5e2038":"t_ImmlaTokenDepository2()","cd5e3c5d":"roll()","cd5ebd93":"calculateTimeout()","cd5ecd60":"theWinnernumber()","cd5f49d5":"transferRewards(address,uint256,uint256)","cd5f5c4a":"tryGet(bytes12)","cd60aa75":"TokenPurchase(address,uint256,uint256)","cd60fe35":"MAX_TOTAL()","cd619681":"count_nodes()","cd61a95a":"sellOrder(uint256,uint256)","cd61cb3a":"setTokenUpgrader(address)","cd62b382":"Sunset(bool)","cd634920":"buyLeader(uint256,uint256)","cd635b71":"ownerShipTransfer(address)","cd639e6c":"EthFundTransfer(uint256)","cd639e8c":"transferByInternal(address,address,uint256)","cd63acf9":"buyChest()","cd63d930":"distributionCap()","cd64b135":"_depositToken(address,uint256)","cd64d952":"buildConnection(address,address,address,int256,uint256,uint256)","cd6566b0":"battle(bytes8,bytes5,bytes8,bytes5)","cd65908e":"changeIPFS(string)","cd65bb67":"ViewToken()","cd67571c":"accept(address,uint256)","cd679413":"ASHLEY_ALLOCATION()","cd67e55e":"LSTRatePerWEI()","cd67f3bc":"LimingCoin()","cd68100c":"lastAddress()","cd69859e":"vestedAdvisors()","cd69a7f1":"weightsApportionDecimals()","cd6a7ca7":"allowance(address,address,address,address)","cd6c4bb0":"startSettlementPreparation()","cd6c8343":"getAttributeValue(address,uint256)","cd6d7f81":"PRICE_FACTOR()","cd6dc687":"initialize(address,uint256)","cd6dca9e":"SaleFinalised(address,address,uint256)","cd6e05e2":"totalPotAwayTeam()","cd6e4dad":"LBCToken(address,address)","cd6e8855":"setMedications(bool)","cd6ebff6":"betAmountAtNow()","cd6ee0c2":"WISDOM()","cd6f4e0d":"dragoCount()","cd6f7c50":"GeneNuggetsToken()","cd6f7fdb":"applyKarmaDiff(address,uint256[2])","cd6fafa2":"XXXXXXXX04()","cd6fc2d1":"addMiningWarPrizePool(uint256)","cd704cb4":"getGeneralRelation(uint32)","cd71a397":"contract6function1()","cd71a471":"withdrawMkt(address,uint256)","cd72250d":"multiTransfer(address[],address[],uint256[])","cd728815":"setSubContractAddresses(address)","cd7292a0":"ChessLottery()","cd729a91":"unlockedTeamAllocationTokens()","cd72ab69":"etherRaised()","cd73d26c":"blocksPerDeal()","cd73df78":"getAllUsers(bool)","cd74096a":"getDataHoldersRefBonus(address)","cd755b41":"subs(address,address)","cd761b9c":"Grass()","cd762827":"joinGame(address,uint256)","cd76635b":"_setAddr(address)","cd76aa16":"getTotalCollected(uint64,address)","cd76faf5":"listActiveEggs()","cd7724c3":"getEthToTokenInputPrice(uint256)","cd77521a":"setFSTAddress(address)","cd77a0c8":"purchaseToken(address)","cd7805bc":"pinged(address,uint256,uint256,uint256)","cd781bf3":"pullEntry(uint256)","cd784d1b":"isSuperUser(address)","cd78a3b7":"processVote(bool)","cd79f86d":"submitPkgHash(string,string)","cd7a2c3b":"ResumeICO()","cd7b6744":"lockGlobalToken()","cd7ba8fd":"currentBlockHashCst()","cd7c92e3":"requestPrice(uint256)","cd7d5b92":"STARTING_SWORD()","cd7da845":"throwsWhenFinalizingWithIncorrectCap()","cd7da914":"renounceArbiter(address)","cd7dfa31":"setStarDeleted(uint256)","cd7e3184":"getValueBonus(uint256)","cd7e9fa6":"RefondCoin(uint256,string,string)","cd7eac3a":"house_fee_pct()","cd7ec171":"developer_string_C(string)","cd7ecda0":"grantPromoPack(address,uint8)","cd7f85fa":"budgetMultiSigWithdraw(uint256)","cd7fa74b":"setPendingReview()","cd7fb38c":"isValidMatingPair(uint256,uint256)","cd7ff921":"stringIndexOf(string,string)","cd80da82":"tokenShare(address)","cd819bdd":"setaddrFWD(address)","cd82a778":"_allowTimelock(address,address)","cd836e15":"SHARDING_REWARD()","cd838f0f":"getNames()","cd83b57c":"TacoCoin()","cd84cff4":"wwwithdrawww(uint256)","cd852330":"buyFromTrusterDealer(address,uint256,uint256)","cd854072":"affiliatThreshold1()","cd8550b8":"setBonus(bool)","cd85e945":"EtalonToken()","cd863e25":"startOffering(uint256)","cd866ee1":"MaximCoin()","cd868648":"setEndBlockNumber(uint256)","cd86eee2":"tokenCreationMinMile1()","cd871b16":"matchBytes32Prefix(bytes32,bytes,uint256,bytes)","cd875247":"OffGridParadise(string,string)","cd880b1e":"kcck256stradd(string,address)","cd881742":"teamTokensReleased()","cd88333e":"coldStore(uint256)","cd887739":"getExpertiseId(uint256)","cd88bac4":"teamTokensLockAddress()","cd897b75":"withdrawSubRound(uint256)","cd8aa272":"Icarus()","cd8b02c8":"Revoce()","cd8b0a77":"getProjectJudge(uint256)","cd8c063b":"isTransferAllowed()","cd8cc844":"lotteryStart()","cd8cdccd":"XiiPay()","cd8d3918":"calcLuckyCoinBenefit(uint256)","cd8d8da0":"tokenFallbackExchange(address,uint256,uint256)","cd8db998":"isDepositBlock(uint256)","cd8df8ec":"activateLastSale()","cd8e250a":"frozenBalancesOf(address)","cd8ed6f6":"addMarking(bytes32,bytes32,int256)","cd8f8b3c":"updateMintingAgent(address,bool)","cd8fce49":"Consents()","cd905dff":"isOperational()","cd9063f6":"replaceToken(address)","cd906676":"changelp1(address)","cd90b99d":"spawnInstance(address,uint256,uint256,uint256)","cd91672d":"firstStageDatetime()","cd91866a":"_startGameRound()","cd9217f7":"eventListener()","cd928f69":"updateAllowedTransfers(address,bool)","cd92dec0":"WaterMeterAcorn(address)","cd92eba9":"debtLedgerLength()","cd932c9c":"parseTimestampParts(uint256)","cd93307a":"EthereumSmart(uint256,string,string)","cd9354e4":"successesOf(address)","cd9380d5":"testSetBalanceSetsSupplyCumulatively()","cd93f6f3":"SetPoolEntryFee(string,uint256)","cd943e54":"transferToLock(address,uint256,uint256)","cd944e3b":"EXPERTS_POOL_TOKENS()","cd94a2a4":"owlToken()","cd953744":"getZTKCheck(address,address)","cd9548ce":"CompanyURL(string,string)","cd955faa":"hasSantaCoins(address)","cd9679dd":"issuePRETDETokens(address)","cd9745f2":"voteForTransaction(uint256)","cd9847bc":"testAccessControl()","cd98b214":"getMarketCreatorSettlementFeeInAttoethPerEth()","cd997aa3":"getData_31()","cd9a1b63":"devBalance()","cd9a1fa6":"countOfOwners()","cd9a27ba":"defaultRegionTax()","cd9a3c98":"any(bool[7])","cd9a7a56":"revokeOperatorByTranche(bytes32,address)","cd9b2f05":"addContributors(address[],bytes32[])","cd9c8d80":"VerifiedInfoHash(bytes32)","cd9d12f2":"icoStartUnix()","cd9d27ed":"setDelegadoDeDistritoVerify(bytes32,bytes32,uint8)","cd9ea342":"testMode()","cd9f05b8":"balanceEtherAddress(address)","cda0574e":"emitNominUpdated(address)","cda0eeaa":"gameMinBetAmount()","cda113ed":"globalBet()","cda2695a":"sponsor(address,uint256,uint256,uint256)","cda35494":"bonusMintingAgent()","cda368c3":"teamV()","cda3c001":"getUnsoldPeriod()","cda4351b":"ViewBetByID(uint256)","cda43ec5":"returnHrt(address,string)","cda4beef":"createAuction(uint256,uint256,uint256)","cda68e5d":"LogDecreaseCap(uint256)","cda6e92a":"sendTransaction(address,uint256,uint256,string,bytes)","cda78dea":"DTransport()","cda8300e":"Transfer_data_enabled()","cda87e33":"getConfigBoolz(bytes)","cda95d80":"Reserve()","cdab73b5":"blackList()","cdab9b5b":"setProviderName(uint256,string)","cdaba786":"addBet(uint256)","cdad5f94":"sendState(bytes,uint256,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","cdad6576":"changeBountyArbiter(uint256,address)","cdadb0fa":"right58(uint256)","cdaeb47d":"removeAddressFromMaster(address)","cdaf4028":"getMigrationCount()","cdb0ec6b":"getLinkedWallets(address)","cdb0fed9":"Livetest()","cdb230be":"DHAMAR()","cdb23c2d":"getMonarchyFactory()","cdb2867b":"canVote(uint256,address)","cdb294a2":"startDeal(bytes32,address)","cdb30482":"setBalancesUSD(address,address,uint256)","cdb3344a":"createGravatar(string,string)","cdb38f4f":"preICOTokenIssuedTotal()","cdb532b9":"deleteCharity(uint256)","cdb58e21":"DUBI()","cdb616b2":"ForkDelta(address,address,uint256,uint256,address)","cdb627b2":"showRecastConfigs()","cdb62c16":"getCashOutAmount(uint256)","cdb6753b":"setNav(uint32)","cdb75f2b":"NemoXXToken()","cdb7699a":"manualTransferTokensToWithBonus(address,uint256,uint256,uint256)","cdb78a2a":"giveNxc(address,uint256)","cdb7ef81":"getMinAuditPriceMax()","cdb80c51":"_service()","cdb88ad1":"setPauseState(bool)","cdb986cc":"getExperience()","cdb99909":"fstPrivateSalePortionNumerator()","cdbaed5a":"_isValidDepositCountry(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","cdbb02af":"getAddressCount()","cdbccf50":"unfreeze_end_date()","cdbce03d":"checkOwner()","cdbcff6d":"getQuotas()","cdbd0f0e":"getRatioOf(address)","cdbd1031":"craftTwoCards(uint256,uint256)","cdbd3fc9":"bax()","cdbd7516":"allowUsers(address,address[])","cdbdc7a4":"DeveciToken()","cdbdd569":"SetLastRoomAndRound(address,uint8,uint256,bool)","cdbdf391":"left34(uint256)","cdbf9c42":"multiply13(uint256)","cdbfd448":"memberLog()","cdc04961":"setStates(address[],uint8[],uint8[])","cdc0563a":"presaleTokenRate()","cdc06bdd":"CrypviserICO(address[],uint256)","cdc07bbc":"_destroy(address,uint256)","cdc18424":"withdrawer()","cdc25845":"setBuyPrices(uint256)","cdc26dcb":"dorcasToken()","cdc2895c":"getOffer()","cdc39f4a":"addCardSet(uint256,uint256,uint256,bytes32,string,address,uint8)","cdc3e046":"balanceMaxSupply()","cdc57fd3":"modifyTokenPrice(uint256)","cdc5c7cd":"updateLinkHash(uint256,bytes32)","cdc62c03":"getFeeToTokenConversion(uint256)","cdc62d39":"ballotDetails(uint32)","cdc68b85":"create_all()","cdc7076d":"getMilk()","cdc81bc2":"totalInVaults()","cdc86ec4":"tokenCreationMinPayment()","cdc89404":"round5StartTime()","cdcb3cdb":"crowdsaleSupply()","cdcb7c8f":"chase()","cdcb8788":"nextRoundFee()","cdcbac0d":"phase3StartingAt()","cdcc599b":"YunnimToken()","cdcc5d3e":"getTokenHolderTribunal()","cdcd77c0":"baz(uint32,bool)","cdcda9a8":"DogeCash(uint256,string,string)","cdcdb463":"getRiskParameters(bytes32)","cdce240c":"WillCoin(string,uint256,string,uint8)","cdce5206":"getUserNum()","cdcf0c4a":"dispute(string,address)","cdcf4b9b":"priceDenominator()","cdcf5794":"checkCooldown(address,address)","cdd11b83":"roundTotalWinnings()","cdd13589":"batchDistributeWithAmount(address[],uint256[])","cdd13673":"rewardReductionRate()","cdd13701":"getEventHashes(uint256[256])","cdd1b539":"getSequenceNumber(uint256,address)","cdd2067e":"getVendingAmountSold(uint256)","cdd247a9":"offerAd(uint256,uint256)","cdd2ef0c":"starBuy()","cdd3574a":"crowdsaleStartBlock()","cdd3ab58":"addDistributionSources(address[])","cdd432d0":"rewardNumerator()","cdd63344":"moveTo(uint256)","cdd6d079":"_tokensForEth(uint256,uint256)","cdd72253":"getVoters()","cdd739f6":"tokenCapForPreICO()","cdd7b1fd":"init(uint256,uint256,uint256,address)","cdd8750e":"getDueTime(bytes32)","cdd8b2b2":"registerBeneficiary(address)","cdd8cc49":"debug_string(string)","cdd8d4e8":"mgmtRewardPercentage()","cdd90fbb":"firstRoundWMDiscount()","cdd93332":"getTradingStart()","cdd977e0":"addrService()","cdda62ad":"FutureBlockCall(address,uint256,uint8,address,bytes4,bytes,uint256,uint256,uint16,uint256,uint256)","cdda96cf":"TokenPriceETH()","cddaf241":"distributeReservedTokens(uint256)","cddb4e44":"getDataAddress()","cddb523b":"changeTeamWallet(address,address)","cddb8e94":"buyProduct(address,uint256)","cddbe729":"game(uint256)","cddbff7c":"CRYPTODUBAI()","cddc028b":"IndexEmpireToken()","cddc37c1":"withdrawForTwoYear()","cddce877":"TOKEN_SHARE_OF_LEGALS()","cdde5413":"updateTileTimeStamp(uint16)","cdde76f7":"hasAnyAttrs(uint256,bytes2)","cdde9294":"avgTokenWinValue()","cddeaba0":"setTokenPrice(uint256,uint256,uint256,uint256)","cddfbaaf":"AirDropAFTKSeven()","cde02b25":"totaldivineTokensIssued()","cde0a4f8":"setRegulator(address)","cde180a9":"listContractByModuleId(string)","cde1d97a":"ChangeTokenVaultAddress(address)","cde25f8a":"getWineOwner(address)","cde2c35a":"rewardBobaBase(uint256)","cde2d72a":"receiveBTC(address,string,address,uint256,string)","cde2e8d7":"A2ACrowdsalePartner()","cde4018e":"AgriChainData()","cde40bc8":"bonusFirstWeek()","cde43f28":"mintTokens(uint256,int256,address,uint256)","cde4efa9":"flip()","cde596b2":"Pay(address)","cde5f58f":"RELEASE_INTERVAL()","cde68041":"hasPermission(address,address)","cde74e51":"licenses(bytes32)","cde7da75":"claimActingPlayerOutOfTime(uint256)","cde7f980":"save(string,address,uint256)","cde93eec":"NewIssue(address,uint256)","cde99727":"calculateROI()","cde9f2ea":"startdate()","cdea76d6":"buyLong(address[2],uint256[2],uint8,bytes32[3])","cdeb1485":"massTransfer(address[],uint256[],bytes32)","cdeb7bac":"MaiToken2()","cdebf885":"Rent(address,uint256,uint256,uint256)","cdecd1d7":"FUN()","cded6986":"_getBridgeTokenFee(uint256)","cded6fa5":"JesusCrowdsale()","cdeda055":"_assert(bool)","cdee2112":"CyberToken()","cdee2b92":"saleclosingTime()","cdee5c4a":"raceRegistration(uint256,address)","cdee8973":"Swapped(address,uint256)","cdef3911":"assignTokenOperator(address)","cdef9423":"create(address,address,address,address,address,address,address,uint8,string)","cdef9fb6":"SimpleStore(uint256)","cdefa007":"FondoNetwork(uint256,string,string)","cdefa4de":"ParaD2Test()","cdefe704":"getLOCbyID(uint256)","cdf016ca":"minimumBounty()","cdf05ab5":"voteTime(uint256)","cdf20e1e":"currentSyndicateValue()","cdf32cab":"totalInvestedWei()","cdf3bc6f":"revise()","cdf3bdab":"GetMyAcorn()","cdf45c03":"FourLeafClover()","cdf46344":"mint(address,string,string,uint256,uint64,uint64,uint64)","cdf4d6b4":"registerKYC(address[])","cdf574f1":"purchase(uint256,bytes7)","cdf6ddb4":"activeCrowdsalePhase1(uint256)","cdf744b2":"setFounderPercent(uint256)","cdf90e02":"Roles2LibraryAndERC20LibraryAdapter(address,address)","cdf93c0f":"EtherBlock()","cdf99413":"CrowdsaleToken(string,string,uint256,uint256,bool)","cdf9b77e":"getCurrency(uint256)","cdfb0a21":"PRVTSToken()","cdfb2b4e":"enableWhitelist()","cdfb5832":"setClaimer(address)","cdfbc437":"setMaxBetAmount(uint256,uint256)","cdfbc8f1":"MINIMAL_PURCHASE()","cdfbe22c":"isAnExchanger(address)","cdfc20aa":"addHashType(uint8,string)","cdfd293b":"BOUTSPRO_AMOUNT()","cdfd72e8":"calcTeamEarnings(uint256,uint256)","cdfd7474":"SONICToken(string,uint8,string)","cdfdb7d6":"increaseAllowance(address,uint256,address)","cdfe2815":"createVip(address,uint256,uint256,uint256)","cdff1be4":"pauseWithdrawal(address,address)","cdff5857":"updateUint256s(bytes32[],uint256[])","ce00d49c":"_transferWithRate(address,address,uint256)","ce017242":"updateICOPrice()","ce01e1ec":"set2(uint256)","ce021384":"numberOfReferralCodes(address)","ce0457fe":"NewOwner(bytes32,bytes32,address)","ce04a8c5":"isDAppReady()","ce04c10e":"highContributionAward(address)","ce05264f":"createInterceptorFromVault()","ce05369b":"releaseTokenHolder()","ce058d0d":"ChangeLEXTokenAddress(address)","ce0617ec":"lockedUntil()","ce072163":"collectPayments()","ce07d2b4":"proxyTransfer(address,address,uint256,bytes)","ce098093":"createtoken(string,string,string,address)","ce0a191a":"setLotteryTokensPercent(uint256)","ce0b5bd5":"cancelWhitelistRemoval(bytes32)","ce0bb9c4":"looksCoin()","ce0bd51f":"bancorConverterFactory()","ce0befcf":"remainTokens()","ce0d5f78":"addAddressToBlacklist(address,address)","ce0df06b":"FreezeAccount(address)","ce0e19ba":"appendString(string)","ce0f802d":"MaazBTC()","ce0f92b7":"hashOrder(bytes,uint64,uint64,uint256,uint256,uint256)","ce0ff8d8":"CSStoken(uint256,string,string)","ce10814c":"wmax(uint128,uint128)","ce109195":"internalDoesEventExist(bytes32)","ce10cf88":"getAddressByIndex(uint256)","ce11f2bb":"vote(uint256[])","ce120afb":"_safeTransferPaymnt(address,uint256)","ce139296":"icoPhaseDiscountPercentage1()","ce13bfb7":"cancelLoanOffering(address[9],uint256[7],uint32[4],uint256)","ce144eb9":"spiceUp(string)","ce146d3d":"getTotalWins()","ce148564":"TIER3END()","ce148c1f":"tempTokensPeriodOf()","ce14a46e":"totalPeriod()","ce14d404":"PieTokenBase()","ce14eeb8":"BASE_HARD_CAP_PER_ROUND()","ce14f10b":"disabled(uint256)","ce15647a":"getTeam(uint8)","ce158ba2":"approveCompanyAllocation(address)","ce160edd":"searchAndBid(uint256,uint256)","ce1619f8":"_lockPaymentTokens(address,uint256,uint256)","ce161b57":"AngelTestToken()","ce165894":"updateExpectedAmount(bytes32,uint8,int256)","ce17f01e":"Hostblock()","ce18eb0b":"stage1Deadline()","ce19419b":"testThrowsSetNotUpdatableNotOwner()","ce1a70a3":"SimplePreTGEContract()","ce1aafc0":"VinaexToken()","ce1afbe1":"_transferToken(address,address,uint256)","ce1b088a":"withdrawDonations()","ce1bd789":"DestroyTransferFeeCoin()","ce1c1538":"getCardByOwner(address)","ce1c93af":"abandon(string)","ce1cf229":"SimpleMultiSigWallet()","ce1d6ea0":"testAppendTranch()","ce1ed182":"getLastMilestoneStartsAt()","ce1ed2bb":"BecomeSquirrelDuke()","ce1f561c":"holdingTaxDecimals()","ce1ffcd9":"setTransferEnable(bool)","ce203b83":"officialUserSignUp(string,address)","ce204b78":"defrozen(address)","ce204bf1":"TOKEN_LOCKING_PERIOD()","ce20fd84":"query(bytes2,int256)","ce21abf3":"sendUnsoldPRETDETokensToTDE()","ce21fbf4":"GolemToken()","ce220ecf":"testAddBalanceFailsAboveOverflow()","ce2293ca":"EIB(string,string,uint8,uint256)","ce230030":"unlockSupervisedFunds(address)","ce233452":"limitPurchasing(uint256,uint256)","ce23e8bc":"LIQUIDATION_TOKENS_PER_ETH()","ce23f2b2":"newLoan(bytes32,address,uint256,uint256,uint256,uint256,uint256,uint256)","ce241d7c":"LogSetOwner(address)","ce248843":"removeOne(address)","ce255bba":"setsafekey(uint256)","ce266af8":"tom()","ce267b55":"ecdsaVerify(address,bytes,uint8,bytes32,bytes32)","ce2777a3":"BigchatToken(uint256,string,uint8,string)","ce27a21a":"setLogoPrice(uint256)","ce289284":"Result(bytes1)","ce2a9f62":"totalEthCollected()","ce2c6ad5":"getChainFeeArray()","ce2ce3fc":"getLocation()","ce2d173f":"setSelfOff()","ce2d3fa1":"returnKVTToOwner()","ce2dfd00":"createFootballerStar(uint256,uint256,uint256,uint256)","ce2fc873":"setArticleHash(uint256,string)","ce2fc8b1":"RequestC(bytes32,bytes32)","ce2fce38":"getTransferInfo(address,uint256)","ce3099fa":"testNBool()","ce3174ca":"revokeSubmission(address,address)","ce329570":"byzantineCloseChannel(bytes32)","ce347a65":"fund(uint16)","ce3498b8":"DelegatedIdentity(address)","ce356e3a":"addTeam2(uint64,uint64,uint64,uint16)","ce371431":"queryFunds(address)","ce373b95":"heroOfThePit()","ce376aa3":"buy_king()","ce3800e1":"moonLevel()","ce383ec7":"view68()","ce389e53":"getTokenAddHold()","ce394696":"calculateCost(uint256,uint256)","ce39952a":"disableSecureMode()","ce39976d":"getUrlAtIndexOf(address,address,uint256)","ce3a7076":"Cancelot(address,address)","ce3b0475":"changePriceDecraseTime2Action(uint256)","ce3be6bb":"withdrawWallet1()","ce3cc3aa":"changeTolerance(address,bytes32,uint256)","ce3ccfd0":"shouldReturnDefault(bytes32)","ce3cd997":"setStage(uint8)","ce3cef0d":"stopTakeToken()","ce3d9237":"mintMarginTokens(bytes32,address[7],uint256[8],uint32[2],bool,bytes,bytes)","ce3e82a4":"KorkToken()","ce3f865f":"collect(uint256)","ce3fff35":"ONTTotalSupply()","ce4150eb":"migrateMarketInFromSibling()","ce419871":"openKYC()","ce41d75d":"NewIntelTechMedia(address)","ce4254ce":"terminationTime()","ce429429":"generateOrderByMerchant(address,uint256,string,string,string)","ce42bb11":"getLockedDevFundAmount()","ce42fa88":"Telcoin(address)","ce435f4b":"SetParticipantAgrHash(address,address,bytes32)","ce43b0c0":"creditorAddresses(uint256)","ce43c032":"getUsername(address)","ce43c097":"CradTimeLock(address)","ce44573a":"GenChipByRandomWeight(uint256,uint8,uint256[])","ce45a260":"CryptoDime()","ce45f981":"MooAdvToken(uint256,string,string)","ce468922":"transferCat(bytes5,address,address,uint256)","ce46e046":"isPayable()","ce471aee":"kompitechToken()","ce47befd":"checkoutCart(string)","ce47e604":"sendAliceBlue(address,uint16,uint256)","ce483c42":"statusI()","ce483e88":"incrementOpenInterest(uint256)","ce48a54d":"getHeroLevel(address,address)","ce49735a":"distributeAlliniTokens()","ce4a6f09":"offerCanvasForSaleToAddress(uint32,uint256,address)","ce4a9206":"minPayInterval()","ce4ae74a":"setRewardMinter(address,uint256)","ce4c4a74":"TrueFlipToken(address)","ce4cf4c8":"advisorTotal()","ce4d01a3":"validate(uint256)","ce4d66b9":"roundBonus(uint256)","ce4d6fdf":"maritalStatus()","ce4dbdff":"securityTokenRegistry()","ce4ddabd":"updateTimeRC(address,uint256,uint256)","ce4e42d2":"BountyManager(address)","ce4e5aa4":"findBestMatch()","ce4e84a3":"STARTING_CHICKEN()","ce4e8c1a":"createNextPremiumSale(uint8,uint256)","ce4eb657":"updateXDRRate(uint256)","ce4ef577":"tokensAllocatedForAs(address,address,address,address,address,address,address,address,address)","ce4efe62":"insert(uint256,bytes32,bytes32)","ce507401":"oraclizeGasPrice()","ce50f72d":"getAvailableBalanceOf(address,address)","ce50f926":"getMinLimit()","ce510d46":"neededAmountTotal()","ce513b6f":"withdrawable(address)","ce52242e":"gotchinfo(address)","ce522f22":"updateWeiCap(uint256)","ce52c4ef":"createDelegation(address,uint256)","ce52cf84":"encoding_format()","ce53ee2d":"voteNoLockByAdmin(address,address,uint256)","ce5478a4":"lockedCapitalOf(address)","ce5494bb":"migrate(address)","ce5566c5":"cash(uint256,uint256)","ce557031":"purchaseTokens(address)","ce5570ec":"isWallet(address)","ce563036":"BaseContract()","ce5659bc":"changePartner2(address)","ce56c454":"withdrawEther(uint256,address)","ce56f3fb":"moneybuy(address,uint256)","ce5774c6":"Proposal(string)","ce578cd6":"managementContractAddress()","ce57d8d5":"getSingleInvestor(address)","ce5910f3":"unfreez()","ce592586":"setThresold(uint256,uint256)","ce5968da":"onMint(int256,address,uint256)","ce597164":"normalDemurrageAmount(uint256)","ce5a5df7":"createUnicorn(address)","ce5a63ff":"purchaseBlock(uint256,uint256)","ce5ac32d":"Firmament()","ce5c073d":"setMintMaster(address)","ce5c2c33":"performTransaction(uint256)","ce5c4fd8":"finalizeSale(uint256,uint256)","ce5c5201":"cryptogsAddress()","ce5d80e6":"stealCardWithId(uint256)","ce5e13aa":"getPlayerProfit(address)","ce5e4190":"set_tokens_per_ether(uint256)","ce5e6393":"tgrSetFinished()","ce5e84a3":"activate(bool)","ce5e9ffb":"CORRECTION()","ce5f9454":"numerator()","ce5fa1e9":"secondExchangeRatePeriod()","ce5fd7f3":"OfferContract()","ce606ee0":"contractOwner()","ce60f78d":"createMarriage(bytes,bytes,uint256,bytes,bytes)","ce622ec5":"announceWinner(string)","ce6236ca":"getRoundLength()","ce627bd9":"mineblocksAddr()","ce629a6b":"_computeTournamentBooty(uint256,uint256,uint256)","ce63066f":"test_6_basicTransfer_increaseBlocksBy1000()","ce6342f3":"getAbiVersion()","ce63cc89":"postTask(string,string,uint256,uint256)","ce649b39":"setEthereumRate(uint256)","ce655952":"_cancelSale(uint256)","ce665dd8":"OFFSET()","ce67bda6":"testNop(int256,int256,uint256)","ce686e40":"IcoToken(string,string,uint256,string)","ce686e62":"BurnableOpenPayment(address,uint256,bool,uint256,string)","ce691294":"kRate()","ce6933d5":"fetchPaidOrdersForPayer()","ce695d7f":"_addArea(address,uint256)","ce699a41":"releaseVestedTokens(address)","ce69cd20":"MIN_BID()","ce6a9bd6":"proofType_Ledger()","ce6b3467":"withdrawExcessToken(address)","ce6c0b64":"_getTokenNumberWithBonus(uint256)","ce6c2589":"_emitOracleRemoved(address)","ce6c9a89":"changeMinimalWei(uint256)","ce6d35d1":"migrateToken(address,address)","ce6d41de":"getMessage()","ce6eaef5":"startSecondSale()","ce6eaff9":"YOU_BET_MINE_DOCUMENT_SHA512()","ce6efb07":"AmountLimitCrowdsale(uint256,uint256)","ce6f149c":"WEEKS_26()","ce6f899d":"EventLogin(address,string)","ce709c9b":"proposalCreateTime(uint256)","ce70faec":"createUltimateOracle(address,address,uint8,uint256,uint256,uint256)","ce71b83c":"TianqibaoTokenERC20(uint256,string,string)","ce71caee":"juryOperator()","ce72a696":"ICO_PERCENTAGE_1()","ce73a61d":"setWhitelistExpiration(uint256)","ce73b41a":"addBuyTokensRequest(address,string,uint256,uint256)","ce742222":"SCARABToken2()","ce744ba5":"SellOffer(address,address,uint256,uint256,uint256,uint256)","ce746024":"recover()","ce7462e9":"setStarSellPrice(uint256,uint256)","ce749c29":"defund()","ce774030":"raiseCoinsAdded(address,uint32,uint256)","ce77cf42":"Rafflecoin()","ce782e08":"floorLog2Test(uint256)","ce784216":"scrapCount()","ce7842f5":"referralBonus()","ce784564":"findPositionInMaxExpArray(uint256)","ce78b752":"ActivatedEvent(bool)","ce7917d7":"GEOCOIN()","ce794294":"multisignature()","ce799b0a":"changeStakeRate(bytes32,uint256)","ce79add1":"givableBalanceOf(address)","ce79d17d":"Storesumdata(bytes32,bytes32,uint64)","ce7a0697":"_internalTgeSetLive()","ce7a2b02":"processPayment(address,address)","ce7a60ab":"unlockBalance(address)","ce7a94eb":"SliceByte32(bytes,uint32)","ce7aa79f":"PXMCToken(uint256,string,uint8,string)","ce7ab6a7":"set_refunded(bool)","ce7ba916":"_initBadges(address,uint256,uint256,uint256)","ce7c2ac2":"shares(address)","ce7c5d7f":"transferEthToOwner(uint256)","ce7ca615":"FoundationAddress()","ce7ca665":"medalBoost()","ce7cdbb7":"getIndexRoot(bytes32)","ce7d3539":"AVMDisputeProcess()","ce7e23a0":"UnityToken(address,uint256,uint256)","ce7e51e3":"uint256ToString(uint256)","ce7f6e82":"CoinPulseToken()","ce7fc203":"accForTeam()","ce803a70":"noOfSeats()","ce806176":"setPurchasing(bool)","ce809e4e":"ETH_DECIMALS_FACTOR()","ce813d8f":"addTurretParts(uint8[])","ce816706":"X4BToken()","ce818ed5":"SiringClockAuction(address,uint256)","ce82eb33":"ico4Bonus()","ce830f5b":"_unlockToken(address)","ce845d1d":"currentBalance()","ce85e801":"MAX_PRICE_SALE()","ce85fbe2":"joojinta()","ce860a62":"getShipIdsByOwner()","ce869a64":"fails()","ce8721b2":"daoAccounts(address)","ce873a67":"processReferer(address)","ce8775a4":"win(uint256,uint256,uint256,bytes,uint256)","ce87f626":"replaceWizardRP(address)","ce8804c9":"setAdvertAddr(address)","ce8883af":"potFee(uint256)","ce88a9ce":"setProduction()","ce88b145":"getAccount(uint256)","ce89a2a2":"changeSettings(uint256,uint8)","ce89b5de":"buy100()","ce89c80c":"calcKeysReceived(uint256,uint256)","ce8ac033":"getAvatar(address)","ce8ae9f3":"giveReward(address,uint256)","ce8b5b60":"setLockAfterManuallyMint(bool,int256)","ce8b7151":"isHF()","ce8b7be4":"consultantsAllocation()","ce8bbe4b":"bobMakesErc20Deposit(bytes32,uint256,address,bytes20,address)","ce8bcae3":"allFundsCanBeUnlocked()","ce8d054e":"_setupNoCallback()","ce8d096d":"redeemVestableToken(address)","ce8d1910":"claimFromSeveral(uint256,address[])","ce8d388d":"disableWithdraw()","ce8d73de":"o_labirinto(uint256)","ce8dc388":"TOTAL_ROUNDS()","ce8e120a":"thawTransfers()","ce8e2fd8":"SaintArnouldToken(address,uint256,uint256)","ce8e5170":"burnedAfterSaleCount()","ce8e95d4":"updateRegion(uint256,uint256,uint256[],bool,bool,uint8[128],bool,address)","ce8ebfc8":"makeSchoolToken()","ce8ff29b":"TicTacToeAdjudicator(address,address,address,address,uint256)","ce90203c":"computeSellPrice()","ce906c6a":"listPrycto5()","ce909980":"checkTimeout(address)","ce90bafa":"topUpERC20(address,uint32,uint192)","ce912692":"createNew(address,address,address,uint256,uint256,uint256)","ce916d85":"icoTokensReceived(address)","ce91e4b3":"freezeaccount(address,bool)","ce923728":"setDealMembers(address,address,address,uint256)","ce92dced":"newBid(bytes32)","ce93b0e4":"returnAdvisorTokens(address,uint256)","ce952345":"icoAssignReservedBounty(address,uint256)","ce95aad2":"isOnCraftingAuction(uint256)","ce95b475":"getBalanceByAdress(address,address)","ce96c8e4":"set_deposit_manager(address)","ce96ec6b":"setRefer(address)","ce972050":"token_orderSheet(address,uint32)","ce972f33":"Menu01(address,uint256)","ce97f61a":"submitTally(uint256,uint256,uint256)","ce9822c7":"Magic10(uint256,address)","ce99151e":"p_wallet()","ce9a3b0f":"special()","ce9a6ac8":"putOn(uint256,uint256,address)","ce9ae667":"PharmaWit()","ce9ae91c":"getARed(uint256,uint256)","ce9af2b9":"isReserved(string,address,string,bytes32)","ce9b4321":"calculateCommission(uint256)","ce9c39c9":"stepTwoStartTime()","ce9e673b":"forceOffsetBasicFeeRate()","ce9e6bb7":"setEndTimeIcoStage2(uint256)","ce9f24dc":"SilentNotaryCrowdsale(address,address,address,uint256)","ce9fb088":"TransferSellAgentBounty(address,uint256)","cea024d9":"tokenPriceNum()","cea08621":"changeDailyLimit(uint256)","cea10af7":"hardFundingGoal()","cea15706":"DarkrenlandCoin()","cea16c83":"endFinalStage2()","cea198c8":"LogBidCanceled(bytes32)","cea22b51":"ico_stage()","cea289db":"debugInt(uint256)","cea2ed48":"CreatedPet(uint64)","cea4b687":"updateListingWithSender(address,uint256,bytes32,uint256)","cea5033c":"_requestTokens(address,uint256)","cea5b151":"getLabelHash(string)","cea5d64b":"shift_right(uint256,uint256)","cea63361":"transactionFeeRateM()","cea65e97":"addressIsOwner(address)","cea67184":"getHydroId(address,address)","cea7555b":"distributedFundariaStakes()","cea81ab1":"generateContestForDelegationSchemaHash(address,uint256,bytes32)","cea876ba":"EthMatch(uint256)","cea943ee":"getSaleConfig()","cea9707a":"getMyTicketList(bool,uint256,uint256)","cea99275":"hasInitMartial()","cea9b7af":"ICO_EOS_AIRDROP()","cea9d26f":"rescueTokens(address,address,uint256)","cea9f621":"setVars(address,address)","ceaa50d4":"getLastPayoutAmountAndReset()","ceaae25d":"massChangeRegistrationStatusForGoldWhiteList(address[],bool)","ceaafb67":"AnonymousDeposit(address,uint256)","ceab09d8":"set_participant(address,uint256,uint256,uint256,bool,uint8)","ceab4ea7":"VOODOO()","ceac2aed":"submit_payment(uint256,uint256,bytes32,bytes32,uint256,address,bytes32)","ceacc749":"calcCurrentMinBid()","cead2c29":"get_ptc_balance(address)","cead4620":"putBtoWithSto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","ceadd9c8":"donateAsWithChecksum(address,bytes4)","ceae3424":"balanceSoll(address)","ceae7f64":"thirdStageMinting()","ceaf0bfb":"admAccount(address,bool)","ceaf1e94":"_transferToAddress(address,uint256)","ceaf9519":"needToGetFree()","ceafb18d":"getCard(address)","ceb0884d":"getSolution(address,uint32)","ceb10f1c":"preIcoCap()","ceb21433":"Activate(address,address,address,address)","ceb22fa0":"meteredEarn(uint256)","ceb24797":"getKycLevel(address)","ceb2731a":"purchaseCrate()","ceb35b0f":"addAddress(string,address)","ceb408b4":"_set5()","ceb41385":"getHashLeftPad()","ceb44d04":"checkSplitEnd(uint256)","ceb51f0a":"setApproved(address,uint256)","ceb60654":"getGroup(uint256)","ceb6dbc3":"time_of_token_swap_end()","ceb791d9":"priceRate()","ceb7bc87":"tokenTransferFrom(address,address,uint256,address[])","ceb7e43c":"getAddOnComplete(uint16)","ceb88ff4":"setContribution(address,uint256)","ceb8ee8b":"durationInMinutes()","ceb98dc7":"unbuy()","ceb9a5fd":"getGameCurrentRoundId(uint256)","ceba1794":"MAX_LOAN_AMOUNT()","ceba30b5":"scheduleTransaction(address,bytes,uint256[4],uint256)","ceba5029":"MOBTokenIssue(address)","cebac2f2":"LRCLongTermHoldingContract(address,address)","cebae575":"GLAU()","cebb8bb0":"testControlRestartEnforceRevisions()","cebbbce5":"ClaimAirdrop(address,uint256)","cebc141a":"devCount()","cebc9a82":"getDelay()","cebce72d":"token(uint64)","cebd31bc":"getStartingPrice()","cebe09c9":"quota()","cebf3bb7":"minRaise()","cebfa61e":"month18companyUnlock()","cec0213e":"HealthDataChain(uint256,string,string)","cec0f734":"setTransferToken(uint256)","cec10c11":"setFees(uint256,uint256,uint256)","cec1365a":"ShortLimit(uint256)","cec17a12":"ChrisBell(uint256,string,uint8,string)","cec33f4e":"getPatentFee(address,uint16[5],uint256)","cec3638d":"VotingChallenge()","cec36cb4":"refundPoweredUp()","cec4a1cc":"pauseRefund(bool)","cec4ab9c":"whitelistEnable()","cec63cea":"NamoToken()","cec68824":"registerFull()","cec7260b":"move_monster(uint16,uint16)","cec77ad5":"ALLOC_ADVISOR()","cec7b4e8":"Deposit(uint256,address,uint256,string)","cec8d277":"decrypt(address,bytes,string)","cec95aa1":"getReleaseHashForPackage(string,uint256)","cec9b4ef":"_executeTransaction(uint256)","cec9df89":"getAddressBetsForEvent(bytes32,address,string,string)","ceca122d":"activate(bool,bool,bool)","ceca7e8e":"fundLock(address,uint256)","cecaf395":"buildBlocks(int32,int32,bytes16)","cecb06d0":"mintOwner()","cecc33e7":"issueTickets(address,uint256,uint256)","ceccc10e":"getHoldersNameAddr()","cecd0264":"executePayment(string)","cecd0ab5":"_processFundsOverflow(address,uint256)","cecd9dd4":"_isNeededNewLottery()","cecdc6aa":"TEAM()","ced095d6":"getContest(string)","ced0a3a5":"setHookOperatorContract(address)","ced0bcc3":"MangaCoin()","ced0c0c2":"subscriptionRate()","ced0d31d":"setFeeRate(uint256,uint256,uint256,uint256,uint256,uint256)","ced11e40":"addMemory(string,bytes)","ced1a60b":"pooja()","ced29978":"LogFrozenAccount(address,bool)","ced32b0c":"setSender(address)","ced39558":"buyLand(uint256)","ced3fb9c":"isAddressAuthorized(address)","ced444bf":"offerStarForSaleToAddress(uint256,uint256,address)","ced4c064":"withdrawTo(string,address)","ced4f4b8":"sellEther()","ced659b6":"burnMktCoins()","ced72f87":"getFee()","ced78ed1":"getImageData(uint256,uint16)","ced7d018":"reFundByOther(address)","ced80aca":"updateMultipleReservedTokens(address[],uint256[],uint256[],uint256[])","ced84a71":"addInvestor(address,uint256,uint256)","ced92670":"changeMultiplier(uint256)","ced9f7c0":"mokenNoName(uint256)","ceda4a03":"NovioCoin_TEST()","cedadaca":"SingularityTest6()","cedbbeee":"createTokens(address)","cedc01ae":"getActivator(address)","cedc2ce1":"setMaxTransfers(uint256)","cedc7277":"getBuyPrice(address)","cedcbd99":"ACTION_BUY_OFFER_ACCEPTED()","cedcd770":"foundationWithdraw(uint256)","cedd90f6":"purchase(bool,bool)","ceddd07d":"balanceOfUnlocked(address)","cedf222e":"congressMemberThreshold()","cee024dc":"getNumberOfVotes()","cee02a86":"SOFTCAP_ETH_LIMIT()","cee0b4fe":"CRTSTAL_MINING_PERIOD()","cee13e28":"Conversion(address,address,address,uint256,uint256,int256,uint256,uint256)","cee24e31":"gambler1()","cee26ed5":"sellers(uint256)","cee2a9cf":"isInvestor(address)","cee401ef":"enableICO()","cee594c8":"addStage(uint256,uint256,uint256,uint64,uint64,uint256)","cee6b0d9":"AcceptsSunny2(address)","cee6b53c":"updateLastActivity()","cee6ee38":"aEthereumlotteryNet()","cee6f794":"SEKEM()","cee6f93c":"getResultOfLastFlip()","cee73630":"buyTPT(uint256,uint256,uint8,bytes32,bytes32)","cee749bc":"withdrawTokenRefund(uint256,address)","cee80356":"min4payout()","cee829ea":"refundMany(address[])","cee8fa1f":"Funding_Setting_cashback_time_end()","cee93e23":"isActive(uint32,int256)","cee96f49":"setissuedSupplyRatio(uint256)","ceea3914":"lookupUserDonationHistoryByCampaignID(address)","ceead4b6":"setCompte_10(string)","ceeafd9d":"withdrawFundsAdvancedRP(address,uint256,uint256)","ceeb7066":"setJoinFee(uint256)","ceebe28d":"repoInterfaceVersion()","ceec8f8f":"removeProduct(string,string)","ceee4119":"getUsersRadarsIds()","ceee9658":"rotate_right(uint256,uint256)","ceeea0ea":"completeAttack(bytes32)","ceef3800":"calculateBonusTierQuotient()","ceef3d93":"changelp7(address)","ceef644c":"LIFEINVIDER()","ceefbbd6":"prePreIcoEndAt()","cef037fd":"setContinueSelling()","cef062fc":"reserveVault()","cef0e9e2":"getFalconmasterReq()","cef24cac":"AmountToFund(uint256)","cef29521":"PRICE_MULTIPLIER_ICO4()","cef2e559":"marketplace_storage()","cef42254":"getContribution(uint256)","cef4be3c":"partialClaim(address,uint256)","cef55ae1":"newComp(uint8)","cef5ed69":"changeServiceAgent(address)","cef6a39a":"createMinerAuction()","cef6cfb2":"addToWhiteList(string,address)","cef75d9f":"myCardDividends()","cef7a4d0":"LogTemplateSet(address,address,address)","cef7e760":"initialCaps()","cef887b0":"storeBlockWithFee(bytes,int256)","cef8d343":"buyShare(uint256,bool)","cef94360":"updatefundingEndTime(uint256)","cef9601f":"timeTillNextSteal()","cef9ca6b":"ThreeDLPrivate()","cef9db6d":"TOKEN_SUPPLY_TOTAL()","cefa624b":"getPlayerAirdropGameData(address)","cefa80fc":"foundersTeam()","cefaba7f":"prc(uint256)","cefad386":"_accountOkayChecks(bytes32,uint64)","cefb09b6":"getBrokerInfo(uint256)","cefb3605":"vaultToWallet()","cefce1f2":"GameOver(string)","cefd2239":"unlocktoken(address,address,address)","cefddda9":"isGenesisValidator(address)","cefdfcf3":"testControlRetractNotRetractable()","cefe23dd":"HarjCoin()","cefeb6f7":"MeshPointManager(int256)","cefed526":"Atlantide(uint256,string,string)","ceff149b":"getRoundLuckyPot(uint256)","ceff6fe6":"cancelApproveForAddress(uint256)","ceffbaf1":"isReleaseApproved()","cf0023ec":"pvt_plmt_max_in_Wei()","cf007460":"nextClaim(address)","cf00c197":"stageOneEnd()","cf00cba0":"BlocksquareSeriesA()","cf00d4b9":"prizePoolPercent()","cf011b26":"excludedAddresses(address)","cf02ba9d":"optionsPerShare()","cf034b1d":"transferFromTrustedContract(address,uint256)","cf03e589":"Registered(address,string,address)","cf03f5f4":"activateMasterKey(address)","cf04dd7e":"DAPSTOKEN()","cf04fb94":"changeVerifier(address)","cf054fb2":"hardCapAmount()","cf0682bc":"warning()","cf06b141":"assertEq17(bytes17,bytes17,bytes32)","cf06b3ba":"KOIOSToken(string,string,uint256,uint256)","cf071005":"showLastPoolAddress(address)","cf07fbb6":"HUToken()","cf082176":"ETHERION()","cf083591":"listAllAttendants()","cf086765":"getPatronsCount()","cf094497":"betCount()","cf09c6dd":"lastBlock_f10Hash_uint256()","cf09e0d0":"createdAt()","cf09e6e1":"SetBigContract(address)","cf09e820":"getPropertyOwnerSalePrice(uint16)","cf0a07b2":"Choon(address,address,address)","cf0a50d3":"DopeToken()","cf0aed0e":"setMinimumBuyValue(uint256)","cf0cb613":"finalUnlockTransfer()","cf0dbc27":"getH2Bidder()","cf0e4076":"findAddress(address,address[])","cf0e4be5":"eggsInTimeSlot(uint8)","cf0e80fe":"getClaimedBalance(address)","cf0f0593":"shl8(uint8,uint8)","cf0f34c4":"setMaxDuration(uint256)","cf0f864e":"battleCardIdRange()","cf0fc7d5":"_fetchOrderByIdWithMerchant(string,address)","cf0fdacb":"getRarityBonusValue(uint256)","cf100287":"payToManager(uint256)","cf112453":"canUpdateNextGameInitalMinBetSize()","cf124ba3":"tokenSaleIsFinished()","cf1259d8":"badge_obj()","cf12789a":"percOf(uint256,uint256)","cf12b725":"releaseTokenPrivate()","cf12d99f":"xorexs()","cf12e870":"giveAccess(address)","cf134a06":"totalLicensePurchases()","cf136426":"IagonTestToken()","cf1405fe":"firstDay()","cf14b191":"recoverAddressOfSigner(address,address,uint256,uint8,bytes32,bytes32)","cf14cecc":"whitelistMaxTok(uint256,address)","cf1578dc":"getOwnerFunds()","cf157942":"endsigning()","cf158fe9":"scheduleTransaction(uint256,uint256,uint256)","cf15b87d":"IcoCompleted()","cf160cf2":"addModerator(address,string)","cf16b4a2":"_packPlayerData(address,uint256)","cf16cc83":"getRoundStart(uint256)","cf16e955":"buyOnBehalf(address)","cf187228":"_createChar(string,address,uint256)","cf187df1":"addFrozenBalances(address,uint256)","cf18811f":"getTrusteeIndex()","cf1893de":"TimeBasedContract()","cf191540":"retraitStandard_5()","cf19463d":"newPokemonMaster(address)","cf195101":"Zchain()","cf195e34":"issuedToDate()","cf1a6243":"MIOTCrowdsales(address,address)","cf1b037c":"registerCallback(address)","cf1b11e8":"tokensPerWeiPlusBonus(uint256)","cf1b3f08":"withdrawTop(uint256)","cf1b45c3":"User(address,address)","cf1c13ce":"setBonusRate()","cf1c316a":"addAuthorized(address)","cf1c9f52":"pauseDET()","cf1cd249":"secureSend(address)","cf1d21c0":"ETHER_ADDRESS()","cf1d567f":"cosmicDice()","cf1d8294":"setPresaleParticipantWhitelist(address[],bool)","cf1e3bcb":"projectReserve()","cf1eba78":"promoMap(bytes32)","cf1ec58d":"usdPerEthLog(uint256)","cf1edfea":"checkIfLockCanBeRemoved(address)","cf1ee6f9":"OVISRESERVED_TOKENS()","cf1eef50":"UpdateRateAgent(address)","cf1f335e":"sendLiquidityFund(address,uint256)","cf1f3dd7":"ledgerName()","cf200e9f":"getBalancesSeller(uint256)","cf202727":"myfirsttoken()","cf20ac40":"citadelBalance()","cf210e16":"restrictedAcct()","cf216207":"tokensToTransfer(address,address,address,uint256,bytes,bytes)","cf21977c":"mint(address,uint256,uint256,uint256,uint256,string)","cf225109":"getSellAgents(uint256)","cf22c803":"Election(bytes32[],uint256,uint256,uint256)","cf2317d5":"nBallots(bytes32)","cf235743":"whitelist(address[],uint256[])","cf23616e":"enableTimelock(uint256)","cf25e4e8":"getActiveBusinessesPerType(uint256)","cf26ac9b":"getLinkOwner(address)","cf27539e":"LBL(uint256,string,string)","cf278430":"split(address,bytes32,uint8,uint256)","cf279ff1":"inserirOuvidoriaNoCadastro(address,bytes32,uint8,bytes32,bytes32,int256)","cf27d016":"isInGracePeriod()","cf282878":"_createNode()","cf2887e5":"transferTo(address,address[],uint256)","cf28b18e":"p_update_tokensRewardsAllocated(uint256)","cf295a5c":"mintbuy(address,uint256)","cf299d04":"joinPre()","cf2a8612":"two(uint256)","cf2affca":"changeRequiredAdmin(uint256,bool,bytes)","cf2b16d9":"Game(address)","cf2b3b47":"createRoomQuick()","cf2b8c05":"getRealisation_effective()","cf2c52cb":"deposit(address,bytes)","cf2d03ae":"minJump()","cf2d31fb":"register(bytes32,string)","cf2d5d66":"TestSelfDropToken()","cf2d5eb4":"ICO_TRIGGER()","cf2d923f":"ADVISORS_AND_CONTRIBUTORS_ADDRESS()","cf2e011e":"link(string)","cf2e161c":"DOWN_winBets()","cf2e3efc":"GetBankAccountBalance()","cf2e80cc":"_setSentReveal(uint256,address,bool)","cf2f856e":"gracePeriodMinTran()","cf2f9a4a":"transferTokenContractOwnership(address,address)","cf2fb7ca":"setDIDTokenAddress(address)","cf3006a1":"setEthPriceInDollar(uint256)","cf309012":"locked()","cf310642":"Police_1()","cf314b6a":"verifyAccount(address,bool)","cf317b7e":"getSellerInfo(address)","cf31e9fe":"getOutputHash()","cf31ff86":"isAddressValid(address)","cf32b062":"deadlines()","cf32b957":"LockInventory()","cf33babc":"VotingStarted(uint256)","cf351c1d":"setFeeTokenAddress(address)","cf35238a":"googleSupply()","cf356f83":"parcelGzeWithBonusOnList()","cf357364":"getOrderType(bytes32)","cf35bdd0":"assets(uint256)","cf35f275":"transferFromStakedisbursementfund(address,uint256)","cf3630b4":"setNextStartTime(uint256)","cf36fe8e":"bobMakesEthPayment(bytes32,address,bytes20)","cf3743c6":"DuxToken()","cf38b609":"priceChibi()","cf397201":"addLockedTokeA(address,uint8,uint256)","cf39bff5":"accoutToSummonNum(address)","cf3b1967":"TOKEN_DECIMALS_UINT8()","cf3b70e6":"CreatedIAM(address,uint256)","cf3c6fd3":"distributeFounderTokens(address,uint256)","cf3ca0fa":"blockDotGasLimit()","cf3cb33f":"exchangeToken(address,uint256)","cf3d1e3c":"sellOffline(address,uint256)","cf3d29ea":"SNTMock(address)","cf3d3849":"getNumInvalidMarkets()","cf3d82e5":"setMaxStage1AllocationPerInvestor(uint256)","cf3e172b":"getTokenInfo(address,bytes32)","cf3e194d":"calculateMultiplierAfterConversion(address,uint256)","cf3e52b8":"ValidateWorldSnapshotInternal(uint256)","cf3e52d9":"topWizard()","cf3e9519":"lrcUnlockPerMonth()","cf40bb58":"currentTimeIndex()","cf40f290":"EventLuckyNumberUpdated(uint256,uint256,uint8)","cf4186cb":"rejectMint(uint256,uint256)","cf41d6f8":"getPaid()","cf4228ea":"isSignedByAll()","cf4246a6":"ethereum2USDprice()","cf424b16":"releaseForSeed(address,uint256)","cf427d1b":"currentPenalty(address)","cf4315bb":"MINBET_perROLL()","cf43f4aa":"TrustedhealthToken()","cf44f5f7":"updateKeyMasks(uint256,uint256,uint256,uint256)","cf456865":"createCompany(bytes32,bytes32,uint256)","cf45f83b":"MADToken()","cf460fa5":"right16(uint256)","cf462616":"isVestingSet(address)","cf464997":"safeAssert(bool)","cf46827e":"getStakingMetrics(address,bytes32)","cf46bd24":"TransferContractOwnership(address,address)","cf46db5b":"isAllowed(uint8,address)","cf46dca7":"setProducer(address,bool)","cf47810c":"deleteAvatar(uint256)","cf478921":"addSpecialFeeTake(address,uint256,uint256)","cf47c326":"generateCryptsyToken()","cf488329":"BITCASH(string,string,uint8,uint256)","cf48d1a6":"setVox(address)","cf4a1612":"scheduleTransaction(uint256,address,bytes,uint256)","cf4baa4b":"kemnagToken()","cf4c3eac":"reservedWeis()","cf4cc8fb":"BitBallCoin()","cf4cea67":"dateBonus(uint256,uint256,uint256)","cf4d3a88":"PeopleSeedCapitalCoin()","cf4d6c0b":"AcceptsHyperDivs(address)","cf4e593a":"getPlayedGameJackpot()","cf4e964a":"cardStructs(uint8)","cf4e9ec3":"endCallRequestDate(address)","cf4fab1f":"PERFORMANCE_FEE_RATE()","cf504d48":"projectActive(uint256)","cf509b9d":"gracePeriodAmount()","cf51ee7a":"removeValueBonus(uint8)","cf51f582":"NucleusVisionAirDrop()","cf52a7b2":"whiteListAddress(address)","cf52ab0b":"New(address,uint256,uint256)","cf5303cf":"checker()","cf530bc3":"LOG_NewBet(address,uint256,uint256,bytes32)","cf53951d":"test_registrationInformationAccurate()","cf53d630":"getBetInfoByID(uint256)","cf54aaa0":"getDecimals(address)","cf561cea":"TestKToken()","cf564ab5":"getVehicleByAddress(address)","cf5713b6":"whatsMyName()","cf58802f":"getOverview(uint256,uint256)","cf58a045":"memberBuyToken()","cf58fbeb":"test_insert_findWithHintNextRemovedUpdateTail()","cf5ae516":"PauseICO()","cf5b5a77":"medalUnFreeze()","cf5b8018":"summSupporters()","cf5b90f0":"sendToken(address[])","cf5ba53f":"create(bytes)","cf5bd8e6":"EthBlockExplorer()","cf5c1b52":"setForSale(uint256,bool,uint256)","cf5c2ac7":"usdCentsBalance()","cf5c8b99":"CuratorRules(address,address[])","cf5cb132":"getRegisteredAssets()","cf5d4e4d":"BarterCoin()","cf5d57db":"changeReward(uint256)","cf5e36df":"getWeiContributed(uint16,address)","cf5f2201":"unMinedPop()","cf5f87d0":"updateConsumable(uint256,uint256,uint8)","cf6036fd":"length(bytes1)","cf62277c":"ThePiContract()","cf62d4e3":"changeMaxBetDoubleDice(uint256)","cf6304d4":"endPreTokensale()","cf6346cb":"presaleMinValue()","cf63bb83":"neymarHasMinted(uint256)","cf63edea":"tokenIdExist(uint256)","cf64c42f":"endCrowdsalePhase1Date()","cf64da7f":"HOVERCRAFT_TYPE()","cf652d1d":"setDefaultBoxNumber(uint256)","cf654886":"getHeroLevel(uint256)","cf65952c":"deactivateDevice(address)","cf662b5e":"JGCoinOld()","cf665443":"nextMint()","cf6661fb":"getNativeAsset()","cf67805c":"MumsTheWord()","cf682b3c":"VMVToken()","cf69318a":"left60(uint256)","cf693418":"_teamJackpot(uint256)","cf69443c":"getCurrentUserTotalReward()","cf69df28":"getDataRequestLength()","cf6a8722":"removeBytes32(bytes32)","cf6ad876":"cancelAgreement()","cf6b1081":"proxyGetRefund()","cf6b3822":"WatchCollectedFeesInSzabo()","cf6b70cf":"many_payments()","cf6b8bbf":"XYT()","cf6bd8b9":"view62()","cf6d06a1":"transferFree(address,uint256)","cf6e4488":"custodianChangeReqs(bytes32)","cf6efb49":"getCdRate()","cf6f3fe4":"distance_driven()","cf6fbb9d":"Mint(address,uint256,uint256,bytes32)","cf6fbeea":"takeAway(address,address)","cf6fcbb0":"calculateAveragePixelPrice(uint256,uint256)","cf7018d4":"setAdURI(uint256,string)","cf70ba36":"tokenZNT()","cf710b34":"showTeam()","cf710b73":"test_setMaxSize_update()","cf72085f":"deliverTokensBatch(address[],uint256[])","cf7209c5":"KyberHandler(address)","cf724096":"transferEthers(address,address,uint256)","cf72b511":"get_refund_deposit_addr_amount(uint256)","cf7315c6":"retract(bytes20)","cf731bd7":"Temgean()","cf73a1bc":"managerAddress()","cf756935":"determineLuckyVoters()","cf763d1c":"periodLimit()","cf76a3b9":"TokenState(uint256,uint8)","cf76cb7d":"simInstallments(bytes)","cf76ebf9":"carsGifted()","cf7730f1":"reserveFundSupply()","cf775255":"configureDomainFor(string,uint256,uint256,address,address)","cf77c8db":"setAffiliateContract(address,address)","cf78044d":"setMaxIndex(uint256)","cf783d8a":"allAccounts()","cf78a450":"unlockBBK(uint256)","cf78cf0d":"ContractCreated(address)","cf7956ab":"SIEToken(address,address)","cf79d8b4":"completeRemainingTokens()","cf7a8965":"steal()","cf7aebea":"transferAntique(address,bytes32)","cf7b38a2":"resumeCollectToken()","cf7b8c5f":"player_count()","cf7bb192":"canStakeExisting(address,bool,uint256,uint256,uint256,uint256,bytes8,uint256)","cf7c2985":"setAuctionPriceLimit(uint256)","cf7c2b31":"paymentOf(address)","cf7d0304":"MintableLazyCoderToken()","cf7d23a3":"Withdrawn(uint256,address,uint256)","cf7dcc15":"distributeEth(uint256,uint256)","cf7e01ba":"ICO1Period()","cf7e06cb":"setCapForParticipants(address[],uint256[])","cf7e69f8":"changeCooldownIndex(uint40,uint16)","cf7e9242":"getAgreements()","cf7efb4c":"SketchMarket()","cf7f12ea":"getBidCountForSketchesWithHolder(address)","cf808000":"iWantXKeys(uint256)","cf81377d":"eosDASH(uint256,uint256)","cf813e3f":"getLockTime(uint8)","cf81978b":"recipientMIT(address)","cf81f24d":"iWannaLiveForever()","cf820461":"txFee()","cf82601b":"removeInstitutionAsset(string,string)","cf82731f":"getPic(uint256)","cf832ce2":"ownerRefundPlayer(bytes32,address,uint256,uint256)","cf837fad":"contractLock()","cf8407c9":"registerFund()","cf854969":"rate1()","cf866d6f":"LastProposalCanDiscard()","cf86a95a":"transferMintership(address)","cf876b72":"setAccountUrl(string)","cf879e83":"isRevoke(address,address)","cf881ad9":"fUseAmount()","cf88eebe":"enableBuyBackMode(address)","cf8951d1":"CollateralTransfered(uint256)","cf89744f":"MaxBetUpdate(uint256)","cf89956e":"Base(uint256,string,uint8,string)","cf8a24de":"emulatePurchase(address,address,uint256,uint256,uint256)","cf8bc918":"getCrowdsalesLength()","cf8c9cc8":"submitTransaction(address,address,uint256,uint256,bytes)","cf8d652c":"tokenCreationRate()","cf8d8ca0":"walletName()","cf8e9996":"MuellerFiredby51()","cf8eb597":"AccountIsFrozen(address)","cf8eeb7e":"subBalance(address,uint256)","cf8f4d4f":"getParticipantRegistry()","cf8f8f12":"finishICOInternal()","cf8fee11":"getBasicRate(address,bool)","cf904e7d":"delCertAdmin(address)","cf9057f7":"findNextYear(uint256,bytes4)","cf905858":"hasIdentity(address,address)","cf90bfc9":"DatPayToken()","cf90e741":"Presale(uint256,uint256,address)","cf910b37":"_getRandom(bytes32[4],uint8)","cf913ae7":"setKoikeToken(uint256,address)","cf914a87":"ownerSetOverride(address,bool)","cf91e331":"TransferGenesis(address)","cf92e19b":"maxPlayableGameId()","cf934d67":"newIndex(bytes32,uint256)","cf934fb8":"sendToBeneficiaryContract()","cf94e395":"set_hosp(uint256,string)","cf951c9f":"initAsset(uint256,string,string,string)","cf9530d0":"totalSupplyOf(address)","cf957ce0":"ROSCA(uint16,uint128,uint256,address[],uint16)","cf9676c1":"setMintRequestUintMap(uint256,int256,string,uint256)","cf96ce03":"setHouseEdgePercent(uint256)","cf9779cd":"accountFor(address,bool)","cf984f16":"testFailRestartEnforceRevisions()","cf98e120":"calculateStagePrice()","cf991259":"BRANDS_ADDR()","cf99a4d9":"buybackTypeTwo()","cf99cd2e":"iterateThroughSwarm(address,uint256)","cf99d935":"finalizeIfNecessary()","cf9a60d4":"ETH_USD_EXCHANGE_RATE_IN_CENTS()","cf9ac727":"logPrice(address,address,uint256)","cf9ac928":"bbd36484()","cf9b62d9":"OwnerOf(uint256)","cf9b9e0a":"FDCToken()","cf9d33d8":"GeniusInvest()","cf9df5eb":"insert(address,address,address,address,uint256,address,bytes32,uint256)","cf9f3db2":"PresaleTimeRangeChanged(address,uint256,uint256)","cf9f5ef6":"MANW()","cf9faf1d":"ownerSetRate(uint256)","cfa0136f":"setPresaleEndTime(uint256)","cfa01baf":"prepareForEarlyFinalization()","cfa059ee":"getIssuanceIds(bool,bool,bool,bool,uint256,uint256)","cfa06700":"_emitAccessBlocked(address,bytes32)","cfa084b0":"setTransferOwnership(address)","cfa12510":"returnHash(address[2],uint256[7])","cfa24ee3":"setFighterCoreAddress(address)","cfa3bfce":"_validateLockupStages()","cfa3c132":"parentOf(uint256)","cfa446ec":"Standard_2()","cfa46990":"getSellUnicornFullPrice(uint256)","cfa4a6a6":"getPools(bytes32)","cfa4f3e8":"setRelease(uint256)","cfa517df":"getOwnerByAnimalId(uint256)","cfa5cfd3":"balanceInSpecificTier(uint256)","cfa5d53b":"blocktubeTransfer(address,uint256)","cfa5df4b":"swapAbleToken()","cfa5f02a":"exchangeETH()","cfa675cc":"_revealBid(bytes32,address,uint256,address,address,address,uint256,uint256)","cfa7074b":"BuyRateChanged(uint256,uint256)","cfa75d43":"developer_add_string_B(string)","cfa83079":"minHpDeducted()","cfa86845":"RedeemingTimeLimit()","cfa9fa85":"percentageHumanityFund()","cfaa234c":"_isNotMixing(uint256,uint256)","cfaa759d":"privateIcoStartTime()","cfaaa266":"TransferOwnership(address)","cfaaff4c":"ADZbuzzCommunityToken()","cfab3056":"guesses(int256)","cfab472f":"isUserEnabledForContract(address,address)","cfab6554":"sumElements(uint16[])","cfab8862":"pfcController()","cfabe67b":"acceptVestingTrusteeOwnership()","cfac2280":"uniqueJingles(bytes32)","cfad5277":"totalAddresses()","cfae2c65":"dispenseTokensToInvestorAddressesByValue(address[],uint256[])","cfae3217":"greet()","cfae52e1":"createFirstDay()","cfaed1e2":"minAllowedBetInEth()","cfaf7315":"BuyEggs()","cfaf8a33":"sellTile(uint256)","cfb009cf":"Obredis()","cfb079d3":"DX()","cfb27084":"switchAirDrop(bool)","cfb3647b":"tokenMinter()","cfb3a493":"getMyBounty(uint256)","cfb3b886":"jack_nonce()","cfb45e3c":"_cancelOperation(bytes32,uint256)","cfb51928":"stringToBytes32(string)","cfb5a5f8":"getShare(uint256)","cfb64dfc":"addCustomerFromProviderAdmin(address)","cfb6e9af":"LogBet(address,uint256,uint256)","cfb75c92":"slavenAdress()","cfb7b9e9":"PROM()","cfb9147d":"exploreFastenETHFee()","cfb9e26f":"getStateOfPlan()","cfba0279":"hasSkill(address,uint256,uint256,uint256)","cfba24ac":"isSenderBiometricLocked()","cfba4fe0":"findBalance(address)","cfba99dc":"getQuoteAsset()","cfbb2047":"currentSmartSpeedNumber()","cfbb4b24":"Invent()","cfbb7d36":"teamWithdraw()","cfbb9f37":"DOW_THU()","cfbbbd9e":"PASS()","cfbbd902":"calcWinNumbers(string)","cfbbda3d":"seekApproval()","cfbd4885":"revokeMinter(address)","cfbe2cb3":"walletDeposit(address,uint256,uint256)","cfbed755":"getCard(uint64)","cfbef67d":"extract(bytes,uint256)","cfbf92a9":"getNodeStake(address)","cfbf9a36":"getBetRecord(uint256)","cfc05b56":"setTokensSoldGoal(uint256)","cfc0cc34":"getStrategy(uint256)","cfc19710":"closeMtr()","cfc220b6":"SpermLabs()","cfc2a93e":"dividendRoundsBeforeFoundersStakeUnlock()","cfc2aad2":"generateBonusForGene(uint256)","cfc41c91":"reb()","cfc450af":"maxInvestmentInWei()","cfc45610":"Makindo()","cfc4af05":"blt()","cfc4af55":"tau()","cfc4d0ec":"getOrderHash(address[5],uint256[6])","cfc54848":"sendEth(uint256)","cfc5a969":"bytesToUint(bytes32)","cfc5e7c8":"getSellCount(address)","cfc72007":"selfdestruct(address)","cfc7e2da":"getMinAmount()","cfc9cb7f":"ForestingToken(address)","cfca375c":"NooCrowdsale()","cfcb2b7e":"createController(address,address,address,uint256,uint256,uint256,uint256,uint256)","cfcb69d1":"TelegramTON()","cfcba2f8":"firstRefundRoundFinishTimestamp()","cfcc09a9":"simpleICO(string,string,uint8,address,uint256[],uint256[],int256)","cfcc57ad":"maxFundsThatCanBeWithdrawnByOwners()","cfcc7720":"rechargeRobot(uint256)","cfcccb32":"escrowList(address)","cfcd84a9":"collectibleIndexToPrice(uint256)","cfcd8c2d":"init(address,uint256,uint256,uint256,uint256,uint256,uint256,bool,address,bool)","cfcdde19":"PRICE_PREBUY_BONUS()","cfd00530":"isContractSignedBySigner(string,address)","cfd0a970":"TierClassicDividendAddress(address)","cfd129f8":"stageSoftcap(uint8)","cfd28966":"getMigrateOutDestinationValue()","cfd2eb49":"StoreComission(address,uint256)","cfd32aa0":"removeFunder()","cfd32ef7":"isMember(address,bytes32)","cfd3c17d":"currentLuckyStoneNumber()","cfd447d7":"startSale(uint256,bool)","cfd4ca6b":"contract_md5()","cfd4edcf":"ProofOf()","cfd550a3":"ICO_ENABLERS_CAP()","cfd56a13":"_sell(address,uint256,uint256)","cfd5cb77":"userAttackMonsterCDSeconds()","cfd65fdb":"assertEq19(bytes19,bytes19)","cfd6eea2":"QDCoin()","cfd7ab91":"STARTTIME()","cfd7be04":"backNewHopeOwner()","cfd7f1fb":"_chkBuyerLmtsAndFinl(address,uint256,uint256)","cfd8a175":"betPrice()","cfd8d6c0":"setProvider(address)","cfd938df":"Channel(string)","cfd94b01":"votersLen()","cfd9e0ea":"getStateForTime(uint256)","cfda7175":"getArbiterFeeAmount(uint256,uint8,uint256,address)","cfdac910":"getSketchesWithAuthor(address)","cfdacb58":"SetCryptoPrice(uint256,uint256)","cfdafde4":"saleIsFinished()","cfdb2eb7":"freeClaimAllowanceOf(address)","cfdb35ed":"setLKCExchangeRate(uint256)","cfdba320":"getRemainLockedOf(address)","cfdbf254":"MAX_BATCH_SIZE()","cfdd4520":"showCurrentBidValue()","cfdd7557":"CountOfAlastayaToken()","cfdd7e8a":"createFirstCommonsForum()","cfdf35b6":"removeLog(string)","cfe01e23":"anyAuditRequestMatchesPrice(uint256)","cfe0a5dc":"tokenKoef()","cfe0d487":"backup_finishIcoVars()","cfe0eeb7":"startSale(uint32,uint64,uint64)","cfe186b2":"finishGame(uint256)","cfe1887b":"delListReq(string,uint256,uint256)","cfe2b37a":"setIntF1ArrBoolF2AddressF1(int256,bool[],address)","cfe2f4e2":"Nicks()","cfe30939":"houseEarnings()","cfe3b8fb":"sTks(address,uint256)","cfe3d16d":"_register(address,address)","cfe3e683":"GWBCoin()","cfe4fb8e":"VECTORZILLA_RESERVE_VZT()","cfe52bdd":"sendFunds(address)","cfe5344a":"updateNovaAddress(address)","cfe60c87":"LookRevToken()","cfe643ac":"getRightAndRoles()","cfe67587":"getWeeklySellVolume()","cfe6f220":"CertificateAddresses(bytes32)","cfe7b770":"getBetInfo()","cfe7e7a0":"createLamboSale(uint256,uint256)","cfe8c535":"giveAnimals(uint8,address)","cfe9a7b8":"getPackageName(uint256)","cfea3bb6":"swapTokenInfo(address)","cfea751f":"getIsAllTransfersLocked()","cfeaa5ea":"setBonusList(address)","cfeaaca1":"newCampaign(string,uint256,uint256,address)","cfeb93a8":"delABaddress(uint256,address,address)","cfeb9a97":"setSubFreezingTime(uint64)","cfeb9ec0":"BSmartValueCirculateAssets()","cfebb88b":"recallVoteToFreezeFund()","cfebc813":"changeExplain(string)","cfebf24d":"optionOf(address)","cfec22f8":"minSum()","cfec6ca3":"calculateProfitGameType1(uint256,uint256)","cfec8d83":"GetUserPELOAmount(address)","cfec934a":"runCrowdsale()","cfecd73d":"EtherIncPrivate()","cfed9199":"timePassed(uint256)","cfedc04a":"neverdieToken()","cfee88db":"closeClaims()","cfefaa8b":"Executed(string,uint256)","cfefb3d5":"payout(bytes32)","cfefcfb0":"VotedForProposal(uint256,address)","cfefe48b":"transferableTokensNow(address)","cfefe5a2":"isContribPeriodRunning()","cfefeb60":"airDropTime()","cff068a3":"random(uint256,uint256,address,uint8)","cff07771":"getEvaluationCount()","cff0ab96":"params()","cff12797":"setIcoPhase3(uint256,uint256)","cff13efb":"newCar(string,bytes17)","cff1b6ef":"updateAdminFee(uint256)","cff29dfd":"bidders(uint256)","cff2fa42":"_returnFee(address,uint256)","cff382ae":"AICrypto()","cff3d4d8":"stage1()","cff410b4":"Exit()","cff4d6cd":"payoutTotal()","cff5b28e":"FLUX()","cff61fb6":"batchExchange(address[])","cff72e67":"changeDevelopersRecipient(address)","cff76d67":"totalEthBankrollRecieved()","cff82e22":"getTicketCount(address)","cff9293a":"vote(uint32,uint32)","cff941fc":"Configured(address,address)","cffa4346":"DIETCoin()","cffc9997":"SetBuildingData(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","cffdc976":"WithdrawOwnerFunds(uint256)","cffe02cf":"setCrowdsaleRate(uint256)","cffe764c":"Insure()","cffee328":"successfulDeals()","cfff25bb":"getNumReserves()","cfff63ca":"assignMediator(address)","cfff8974":"mintToInfluencer(address,uint256,string)","cfffa030":"lanch_atak()","d0005aa4":"salesStart()","d0008a6d":"addNewMember(address,uint256)","d000a404":"PT(uint256,string,string)","d001425a":"bank2()","d0015500":"ownerSecondary()","d002462b":"setDeploymentFee(uint256)","d002a41c":"getUnReportedMatches()","d00408b7":"StandardToken(address)","d0044f9a":"_getLuckyList(uint256,uint8)","d0045341":"totalMintAmount()","d0047acf":"mint(address,uint256,uint32)","d004f0f7":"swap(address,uint256)","d004f38b":"setRates(uint256,uint256,uint256)","d0064c00":"maxDebt()","d0068f80":"getClient(uint256)","d0072e59":"forceReturn(address)","d007c644":"payInterest(address)","d007ff4b":"showJackpotBalance()","d0089141":"ovedclaimBountyairdrop(address,uint256)","d008d7a2":"BosToken()","d00910a3":"yearlyTeamTokensPaid(uint256)","d0095cc6":"genNumber()","d00a9058":"getOwnTokens()","d00cce41":"roleExists(string)","d00d20f4":"getTokensCrowdsaled()","d00eef6a":"TokenGranted(address,uint256,string)","d00ef880":"setShareTokenAddress(address,address)","d01296d9":"addmember(uint256,address)","d0130009":"Subtraction(uint256,uint256)","d013a182":"getServerBuildingWeapon(uint256,uint8,uint8)","d0142c47":"ImperialCreditToken()","d014c01f":"enter(address)","d014d667":"XCDT()","d0158b87":"fetchCancelledOrdersForMerchantByAdmin(address)","d015d86f":"getRoundStats()","d015f6dd":"NorthPoleAddress()","d01678f0":"raiseDay2()","d0169c1e":"lockAsset(bytes32)","d0169f4c":"start_POSTICO()","d016ec40":"vipBrokerNum()","d017c2b4":"returnTokensToWallet()","d017cdcf":"acquireFame(uint256)","d017e20d":"processing(address,uint256,uint256,uint256)","d017f49b":"JustOneToken2()","d01860d0":"isFinishedSuccessfully()","d018a00f":"redeemBeer(bytes32)","d018db3e":"attack(address)","d0198c33":"getFunctionIdentifier(string)","d019d2c4":"MRT()","d01a69c9":"totalBeneficiaries()","d01a9453":"BitAirToken(address,string,string,uint256,uint256)","d01ab2e6":"_cancelOrder(address,address,uint256,address,uint256,uint256,uint256)","d01ab31a":"ICOStart()","d01b555d":"setSalePause(bool)","d01bbdc9":"setOracleCallbackGasLimit(uint256)","d01c0904":"FujintoToken(uint256,string,uint8,string)","d01d0175":"StorageConsumer(address)","d01d6b86":"amountOfRegisters()","d01e2df9":"testContains()","d01ec886":"importPresaleContribution(address)","d01f4c9f":"hoursSinceTimestamp(uint256)","d01f4ffe":"stopSecondSale()","d01f63f5":"getWhitelist()","d02041f3":"advisorsPeriodAmount()","d02042a3":"relief()","d020ae40":"gameTotalGen()","d020dc3b":"rejectMessage(uint256,string)","d02143ed":"getRefToLength(address,address)","d0216dce":"XXXXXXXX07(address)","d021d8da":"Coinbase()","d0220b1c":"setCreateChampFee(uint256)","d0225e9e":"MAX_LRC_DEPOSIT_PER_ADDRESS()","d0237ab8":"EtherLiteSupply()","d023d2bd":"getGladiatorChestPrice()","d023d32c":"setEndAfterSecond(uint256)","d024768f":"computePropertyHash(string,string)","d024cd02":"startAuctionDirect(uint256,uint256,uint256,uint64,address)","d02528e6":"GetGameIndexesToProcess()","d02721cb":"withdrawProvider()","d0280037":"buyin(uint8,bytes32,bytes32)","d0286ab2":"setEmissionTime(uint256)","d028754b":"Withdraw_1()","d028a625":"deathData_v11()","d028c246":"Compaq()","d028f571":"getTokenForTeam(address)","d0297bc6":"changeMaximumContribution(uint256)","d02982cf":"isMember()","d029a530":"buyUnicornWithCandy(uint256)","d02a4f84":"bcn()","d02a6db7":"TokenLongExercised(address[2],uint256[7],uint8,bytes32[2],uint256,uint256)","d02a9889":"getDateOfFirstPayment()","d02b1653":"enablePrivateFund()","d02b97aa":"withdrawPromoter()","d02bf162":"spinTheWheel()","d02bf828":"lotteryTokensWallet()","d02c438a":"enableTokenSupport(bool)","d02c8cdf":"cancelMatch(uint256)","d02cc69f":"playWar(uint256)","d02d08b2":"hasCrowdsaleFinished()","d02d1382":"getPlayerCard(uint8)","d02d3892":"ApolloSeptemBaseCrowdsale(address,address)","d02d4554":"createUser(address,address)","d02d518d":"setArtEvt(string,string)","d02dade4":"getProviderCounter()","d02ddc12":"insert(bytes1,bytes1)","d02e140a":"finalizePrivatesale()","d02e5cfb":"mtcDailySpent()","d02e8f70":"MONUMENT_CITY_FEE()","d02ea39e":"DuckToken()","d02ecbb5":"ObitanChainxToken()","d02f5463":"pillarTokenFactory()","d02f8b98":"getApplications(address,bytes32,address)","d02fcad9":"wdiv(uint128,uint128)","d0302051":"rewardPercent()","d031370b":"reserveTokens(uint256)","d0315658":"getShareDistributionWithTimestamp(bytes)","d031babf":"LikeCrowdsale(address,uint256,uint256,uint256)","d031d8c4":"_transferLand(uint256,uint256,address)","d032ae76":"doAirDrop(address[])","d033c456":"addAddress(address,string)","d033d277":"OwnerNamed()","d033e6ee":"preAllocate(address,uint256,uint256)","d033f913":"getRoundSeedHash(uint32)","d034536e":"logFileClosing(string,uint256,string,string)","d0356fa8":"createVestingGrants()","d035bed4":"validContract(address,uint32)","d035e45f":"token_escape(address)","d0360e59":"drainContract()","d036261f":"amountBonuses(uint256)","d036bce2":"_calculateTokens(uint256)","d0376283":"onlyApprovedOrOwnerOfToken(uint256,address,bool)","d0378d07":"decreaseReserve(uint256,uint256)","d038906a":"FloraFicToken()","d0399bb8":"endGame(uint256)","d03b41a9":"bountyBalance()","d03bf119":"RANGESTART_11()","d03c8e34":"addAngel(address)","d03cff97":"devMiningRewardPerETHBlock()","d03d5231":"raffleDraw()","d03d9604":"maskIt(address,uint256)","d03e1021":"ORACLIZE_GASPRICE_GWEY()","d03e3059":"someMethod3(uint256,uint256,uint256)","d03e6817":"Volkstest()","d03e9bcc":"LogReceiveFunds(address,uint8,uint256)","d03e9fff":"plusTourFreezingTime(uint256)","d03ffefb":"createDeposit()","d04148d6":"m_account()","d04206f3":"CROSS_RESERVE()","d042a795":"multiSendA(uint256,uint256)","d042ce2c":"currentStageTokensBoughtByAddress()","d04301f2":"Annexe_SO_DIVA_SAS_5()","d0431cf5":"_openBox(uint256)","d0435cb0":"MonsterTokenCrowdsale(uint256,address,address,uint256,uint256)","d043d028":"toBytes4(bytes,bytes,uint256)","d045e1ff":"_inverse()","d046065e":"addBet(uint256,uint256,address,uint256)","d0471ee1":"Leverages(address[])","d04737bd":"Yuzhuralzoloto_2()","d0479abc":"burnUnsoldTokens(uint256)","d047a0d0":"getEmergencyTransferSigner(address,uint256)","d04807e9":"Heronium()","d0481f82":"hasLicenseTerms(bytes32,bytes32)","d048bc87":"inAngelPeriod()","d048db37":"getOfferCount()","d04a419b":"getDegree(bytes32)","d04a46b0":"sendFutureExpanstionBalance(address,uint256)","d04b019e":"getWalletResourceBalance(address)","d04bfc9c":"buyer_pay()","d04c9115":"getLoyaltyPoints(address)","d04cb43f":"withdraw_all_token(address,address)","d04d26fe":"updateStrength(uint256,uint8)","d04d2ca3":"BlacklistParticipant(address)","d04d8667":"authorized_recordPlatformFee()","d04dbdea":"Testtoken4()","d04e5586":"MEAManager()","d04f0535":"PisticciCash()","d04fe107":"getActiveAds()","d050498e":"assertEq24(bytes24,bytes24,bytes32)","d050557d":"bulkRegisterPoA(bytes32,bytes32,bytes,uint256)","d05144c8":"getMakeCount()","d0516650":"frozen(address)","d0516b82":"maxPresaleAmount()","d051dfd3":"prizes(uint256,address)","d052fbf6":"getHistory(string,uint256)","d05391d2":"admin_transferFrom(address,address,uint256)","d05407d4":"SetStepFunctionWrapper(address,address)","d054261e":"_generateRandomHash(string)","d05461a6":"mintForReportingParticipant(int256,address,uint256)","d0549602":"scheduleTransaction(address,uint256,uint256,uint256)","d054cd87":"badBoardSent(bytes10,uint256,uint8,bytes32,bytes32,bytes10,uint256,uint8,bytes32,bytes32)","d0569bc8":"getWinResults(uint256)","d056cc69":"stateCode(uint256)","d0578df9":"SMGC()","d0587032":"tablet_length()","d0590bad":"generateMessageToSign(address,uint256)","d05b7ca4":"uintToChar(uint8,uint256)","d05ba4da":"addPokemonToSellingList(address,uint256)","d05c78da":"safeMul(uint256,uint256)","d05c9342":"_getATxToken()","d05c9ad6":"setNumRewardsAvailableForAddress(uint256,address,address)","d05cb545":"registry(address,uint256)","d05d996f":"TXDELAY()","d05ec6c5":"getBonus4(uint256)","d05ee727":"teamAccount()","d05efd40":"directorA()","d0600560":"AD()","d060a2a5":"doSmallDrop(uint256,uint256,uint256,uint256)","d0610ac9":"interpolate(uint256,uint256,uint256,uint256,uint256)","d0617f2f":"OMICrowdsale(uint256,address,address,address)","d062c7ab":"CleanBankerCandidate(uint8)","d06301d3":"__resolve(uint256)","d063f55f":"toLittleEndian(uint64)","d06426d5":"convertUsdToEther(uint256)","d0647f30":"_createDebt(bytes,bytes,uint256)","d06544d0":"getCoinAddress(string)","d0658850":"ListingDB(uint64,uint64,address)","d066c841":"GenesisBuyPriceHistory(address,uint256)","d06760da":"isPartOfOrg()","d0676647":"ProposalClosed(uint256,uint256,uint256,uint256,bool,uint256)","d06798f2":"fourweeks()","d0679d34":"send(address,uint256)","d0683428":"executeRulingA(uint256)","d0692775":"gamesLeft(address)","d06980f1":"LogHodlClaimed(address,address,uint256)","d06982b2":"setDemurrageAmount(uint256)","d0699c98":"calcFees(uint256,uint256,uint256)","d06a0f5b":"setDynamicCeilingAddress(address)","d06a57b0":"pauseAllTokens(bool,string)","d06a89a4":"maxLength()","d06b3ea0":"whackingPool()","d06b44a6":"YKCToken(uint256,string,string,uint256)","d06b6f7e":"setMinTokensToSale(uint256)","d06ba559":"WrestleCoin()","d06c54fb":"acceptNextOwner()","d06c7b5b":"signalToken()","d06c91e4":"multisigEther()","d06ca26c":"managedWallets()","d06cdc73":"LuckyNumberService()","d06d4612":"jak()","d06f887b":"destroyMyToken(uint256)","d06f9734":"setTreasurer(address,bool)","d0707c61":"PerformingDrop(uint256)","d0708e31":"DocumentCertoChainContract(string,string,string,string)","d071f7b1":"recover(bytes32)","d073c531":"IMOSToken()","d073ca3d":"SUCCESS_FLAG()","d074443f":"DeathFactor_i()","d0747a9c":"getGoldmintFeeAccount()","d074a38d":"biddingTime()","d074de8c":"Testico()","d074f215":"PHASE_1_PRICE()","d075c11c":"viewNoncsallocations(address)","d0774f74":"GENSIS_TOTAL_COUNT()","d077814b":"divBase()","d0785dd7":"getNumberOfPlayersInCurrentGame()","d07866d2":"sizeOf(uint256)","d0799bee":"setRole(string,string)","d07a8bd7":"RisingToken()","d07ac4c4":"oraclize_query(uint256,string,bytes[4],uint256)","d07adab3":"getOutAmount()","d07bff0c":"getVoter(uint256)","d07c53b6":"thinkMode()","d07e7d7c":"setTTCTokenAddress(address)","d07e9f90":"getJobsCount()","d07f29e5":"addFounderAccounts(address,uint256)","d07f2ff6":"GreenWorldFarm()","d07f3a8f":"RobBanker(uint8,uint256,uint256,uint8)","d07f8181":"decreasePaymentsBalance(address,uint256)","d07fdfb0":"October12_2017()","d081b681":"vows()","d081b9f5":"networkState()","d081f2b8":"BOUNTY()","d0821b0e":"bet(uint8)","d08275f1":"WolframAlpha()","d08279b0":"unpauseTournament()","d082ea8c":"setExchangeAddress(address)","d083955c":"adjustMintRates()","d084f670":"getLocked(bytes16)","d085835a":"timeLock()","d085b82f":"TIMECOIN(address)","d085c8b8":"StartDistribution()","d085e66e":"GetPart(bytes32,uint256)","d0863580":"blocksRemaining()","d0868223":"returnATXChanges()","d086a201":"main_ico(address,uint256)","d087d288":"getNonce()","d088070a":"checkWhitelist(address,uint256)","d088f50d":"getNumeroCeldas()","d0894297":"EARLY_INVESTOR_WALLET()","d0897347":"engrave(bytes32,string,string,bytes32)","d089e11a":"accountRegistry()","d08a787c":"bytes32ToString(bytes32,bytes)","d08b89f3":"disableStopping()","d08bc007":"logRef(address,uint256)","d08bfe26":"CrowdsaleClose(uint256,bool)","d08c6803":"deletePerson(uint256)","d08d66ec":"setBonusState(uint256)","d08d6753":"mdtRewardAmount()","d08e2354":"goldPercentage()","d08f2c67":"getHistoryAt(uint256)","d0900033":"COLONERToken()","d09119b4":"mortgage(address)","d0914c8d":"RelestToken()","d091b550":"newOwnerCandidate()","d0937598":"getLuckyblockBase(bytes32)","d09398ee":"transferCDP(address,uint256)","d093e04b":"payJackpot(uint256)","d0940a5d":"best()","d0946d00":"subFreeMineral(address)","d0949f99":"UINT256_MAX()","d094dd21":"getLLV_edit_14()","d095761f":"withdrawNetIncome()","d095d499":"profit3eggs()","d095edb2":"initializeModuleAddresses(address[])","d09677df":"TankSellMaster()","d09685b0":"getEntriesCount()","d096b8f0":"setupRaffle()","d0973af8":"transferTokensFromContract(address,uint256)","d09812e1":"settlementRegistry()","d0982feb":"tokenLockDuration()","d0983f4b":"tokenRatios()","d0988149":"MANHATTANPROXYMADISONAVE()","d0995198":"returnMinGoal(uint256)","d0995b33":"refundBalances(address[])","d09a6a62":"transferUnlock()","d09b0ae4":"RealEstate()","d09cb807":"isCurrentAdmin(address,address)","d09de08a":"increment()","d09e21ee":"ignore(bytes4,bool)","d09e3526":"setStatusI(address)","d09eae58":"SCAMToken()","d09edf31":"authorizer()","d09ef241":"getOrder(uint256)","d09f85ca":"Eventine()","d09f872a":"VenusToken(uint256,string,string)","d09f8b8b":"addXY(uint256,uint256,uint256,uint256)","d09fb45e":"setApprovedContracts(address,bool)","d09fbcee":"HumanTokenAllocator(address,address,address,address,address)","d0a05fea":"setI_S(uint256)","d0a06fb9":"cloneCard(address,uint256)","d0a1adf4":"contains(bytes1,bytes1)","d0a27473":"teamUnlock1()","d0a2da8e":"give(address,uint256,string,string)","d0a2f2c4":"getAllInvestors()","d0a45f84":"getVersionImplementation(address,bytes32,address,bytes32,bytes32)","d0a4a81b":"setTellerModerator(address)","d0a56299":"GetAssetTypeAverageSalePrice(uint256)","d0a579fb":"releaseForEarlyInit(address[],uint256)","d0a5eb4e":"setMainWallet(address)","d0a61995":"sell_(address,uint256)","d0a62566":"approveIndexed(address,uint256)","d0a63663":"incrementLimitBranch()","d0a6f018":"LogBalanceChange(address,uint256,uint256)","d0a6fa54":"getPriceById(bytes32)","d0a7b467":"setAragonDevMultisig(address)","d0a826f3":"setWildcardList(address,address,bool)","d0a835e3":"buyShip(uint32)","d0a8c801":"fshare()","d0aa0313":"setCompte_38(string)","d0aa407f":"withdrawEther(bytes32,uint256,uint256,uint256[])","d0aac5cf":"teamProfile(uint256)","d0ab0066":"calcFlexibleReward(uint256)","d0ab48e9":"toB32(bytes,uint256,bytes,address)","d0ab8432":"whitelistRegisteredAmount(address)","d0ac01ac":"setOfferExpiry(uint256)","d0ac2252":"getShipEarning(uint32)","d0ad7fb8":"buyTicket(uint256[],address)","d0ade72d":"assertEquals(uint256,uint256)","d0ae4356":"getRequestStatus(address,address)","d0ae9aec":"setMinInvest(uint256)","d0aff67d":"setNeverdieContractAddress(address)","d0b01e68":"__setBeneficiary(address)","d0b02abc":"createProductionUnit3()","d0b06f5d":"lastUpdated()","d0b0c0d5":"unlockDevTokenSupply()","d0b18fbf":"transferByForce(address,address,uint256)","d0b1b910":"FXSToken()","d0b2b579":"seedFund()","d0b368a0":"addToApproveList(address)","d0b3da99":"join(uint256,bool)","d0b4755c":"RATE_SALESTAGE1()","d0b52156":"getIpfsHash(address,address)","d0b5981f":"closePreICOPublic()","d0b68efb":"yoobaTokenAddress()","d0b6ba2a":"moveFunds()","d0b74806":"claimA()","d0b753f3":"sendPreSaleBonus(address,address)","d0b7ca57":"mintToken(address,uint256,bytes,bytes)","d0b83db9":"insertUser(address,bytes32)","d0b86d15":"FaradEscrow()","d0b91ca7":"showBurnedCoins(address)","d0b94ffe":"web3ViewRoll(bytes32,bytes32,uint256,uint256,uint256)","d0b99ee2":"_distributeLandholderTax(uint256)","d0b9e58b":"SspContract(address,address,address,uint256,string)","d0b9e792":"returnBorrowedEth()","d0bb1d40":"airdropsCount()","d0bc1a88":"addMoney(uint256)","d0bc97d0":"isCrowdsaleFull(uint256,uint256)","d0bcebc8":"collectBack3()","d0bcfc0c":"Bankroll()","d0bec975":"countBid(uint8)","d0bf4d95":"SmokeExchangeCoin(uint256,address,address,uint256,uint256,uint256)","d0bf9502":"btcLastUpdate()","d0bff051":"testSetBalanceDb()","d0c03f35":"multisigVault()","d0c0c39c":"countTokens(uint256,address)","d0c1c844":"getLimitedBalanceOf(address)","d0c1d117":"editAddressDescription(address,string,address)","d0c24e93":"setNotUpdatable(bytes20)","d0c3033c":"generalBounty()","d0c32dd3":"otcPurchase(uint256,address)","d0c32ea9":"SearchALLFileLength()","d0c39f14":"Lottery(address)","d0c412ec":"ENDOairdrop()","d0c426e6":"burnAllRemainingIBC()","d0c475e5":"addRecordStrict(uint256)","d0c5c585":"getBurnAmount()","d0c5c946":"refundBpToken(address)","d0c75ea2":"verifyCommonTransaction(bytes32,uint256,address,address,uint256,address,address,uint256,bytes,bytes)","d0c7b012":"placeGame(uint24,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32)","d0c7c635":"mintToTeamAndAdvisors()","d0c8a7a5":"randgen()","d0c9bb92":"releaseTCLRinTeamTokens()","d0ca12ba":"ICO_START()","d0ca1982":"getCrowdsaleInfo(address,bytes32)","d0ca4dd7":"ownerWithdrawTokens(address,address,uint256)","d0ca5e7a":"createTokenToMarket2020()","d0ca7379":"mintReferralShare(uint256,address,uint256)","d0cac952":"HouseManaged()","d0cb874a":"getTokenByMineID()","d0ccf4bc":"createInstance(bytes32,bytes32,address,bytes,bytes32,bytes32,address,bytes,bytes32,uint256,uint256,bytes)","d0ce659f":"SwitzerlandvsCostaRica()","d0ce7360":"closeContract(uint256)","d0cf49e9":"zoLastRefreshTime()","d0d0ed05":"withdrawVault()","d0d13e87":"smartContractIsForSale(uint256)","d0d1ea70":"setTrustee(address)","d0d2e745":"manualExchange(address,uint256)","d0d38b65":"setFirstRankForFree(bool)","d0d390bf":"HubToken(address)","d0d3b9df":"IfModuleRegist(address)","d0d3f5ba":"removeNode()","d0d44cca":"setPOOL_edit_34(string)","d0d511f9":"getGoalsCount()","d0d529a7":"openWindow()","d0d552dd":"setAsset(address)","d0d68241":"betALenght()","d0d832ad":"fundraiseType()","d0d89ce3":"cummulativeTokensSold()","d0d968c0":"burnFromReserve(uint256)","d0d98276":"revokeOffer(address)","d0d9e21d":"emitCapabilityAdded(address,bytes4,uint8)","d0d9fcf7":"RANGE_STAT_MAX()","d0da3e86":"getNextAntiReplayTag(uint256)","d0dad7e1":"maxCapMain()","d0db5083":"hatch()","d0dc0a04":"all_creatures_for_species(uint256)","d0dc5c65":"updateTotalSupply()","d0dd38ad":"setDepositGasCost(uint8)","d0de7b29":"MetadiumVesting(address,uint256,uint256,uint256,bool)","d0def521":"mint(address,string)","d0e075c7":"BitcoinPurple()","d0e0813a":"promote(address)","d0e0ba95":"setId(uint256)","d0e0e8f6":"isLockedConfig()","d0e2bef0":"initFactorReward(uint256,uint256,uint256,uint256)","d0e2dc64":"playAway()","d0e30db0":"deposit()","d0e33b1b":"testGetResults()","d0e3cbbe":"getCurrentTotalEther()","d0e3f734":"setPubkey(string)","d0e4567e":"activeGroups()","d0e46235":"buyCardsAndSendGift(uint8,address)","d0e4713d":"CEC()","d0e55727":"changeOfferTime(uint256,uint256)","d0e6cfec":"bountyTokenWallet()","d0e709b6":"initialTransfer(address,uint256,uint256)","d0e7a5cb":"editPrice(uint256,uint256)","d0e95ded":"MithrilOre()","d0e9f00f":"BNTBalance()","d0ebdbe7":"setManager(address)","d0ec057e":"getFeeAmount(uint256,bool)","d0ec1607":"cancelPoll(uint256)","d0ed5c2f":"walletContract()","d0edf912":"createTransaction(address,uint256,uint256,uint256,uint256)","d0ee32c4":"getSymbolFromAddress(address)","d0ef1048":"_getRand()","d0ef368d":"setAllocation(address,address,uint256,uint256,uint256)","d0eff891":"weiToEther(uint256)","d0f040c4":"checkOwnerAllowance(address)","d0f0efcb":"buyPredictXname(bytes32,uint8)","d0f13638":"minimumPrepaidClaimedPercent()","d0f15e9e":"WalletWithEmergencyTransfer()","d0f17d41":"contributionMaximum()","d0f2019c":"hasToken(address,address)","d0f3235d":"_transferAirdrop(address[],uint256,bytes)","d0f3aa80":"allowSale()","d0f46c0b":"getUsersContract()","d0f4f99c":"solvePuzzle(uint256)","d0f5f4cd":"getPixelColor(uint16,uint16)","d0f6fc40":"QuantityFactorSet(uint256,uint256,address)","d0f76bb8":"End3()","d0f7a601":"etherRate()","d0f817db":"getOrgCertificatesCount(address)","d0f86c9d":"getUser(int256)","d0f86ea8":"getMemoryRead(uint256,uint256)","d0f86fec":"ENKToken()","d0f87ce7":"periodPreITO_mainCapInWei()","d0f89c6d":"setWhiteBackersByList(address[],bool[])","d0f8c714":"add(bytes32,uint256,bytes,bytes8)","d0f8e6a4":"DelegationTransferred(address,address)","d0f96983":"composite(uint256,uint256,uint8)","d0f96f6b":"DigitalPadlock(string)","d0fa968a":"s14(bytes1)","d0fab480":"meg()","d0fb8909":"activations(address)","d0fbe7fe":"buyTickets(uint256[])","d0fc1e7d":"getFrequency(bytes32)","d0fc2782":"multisigs(uint256)","d0fc35cf":"StandardFormula()","d0fc899a":"presaleInvestorsETH(address)","d0fca0ca":"gogo(bytes,bytes,address[])","d0fe3e85":"releaseTokensTo(address)","d0febda9":"getModerator(address)","d0febe4c":"buyTokens()","d0fef78f":"Visor()","d0ffecaa":"setWhaleMax(uint256)","d10032dc":"getTokeRate()","d1013fec":"endTimeSale1()","d101d3b2":"timelock(address,uint256,uint256,uint256,bool)","d1026aa8":"YESToken()","d10271a1":"OxProtocol()","d103449c":"addURL(string)","d1037a11":"swap(uint256,address,address,address,address,uint256,uint256,bytes,bytes,bytes)","d1042e31":"getUserReward(address,address,bool,bool,bool)","d1047434":"getFactoryCount()","d1048bc9":"reserveVanityURLByOwner(address,string)","d104a136":"getBase()","d104bca2":"getUnitsAttack(address,uint256,uint256)","d1051a68":"DynamicToken()","d10523b7":"GoldenLightChainToken(uint256,string,uint8,string)","d105350b":"getLockedBalance(address,uint8)","d10541ab":"changeIdentityEthAddress(address)","d1058e59":"claimAll()","d1073bdb":"setBitwordsCut(uint256)","d107a5cc":"freezeAllowance(address,uint256)","d108177a":"removeEmployee(address)","d10865a7":"endSecondWeek()","d108b7d4":"KyberContributorWhitelist()","d108ffc0":"tokenToWei(uint256)","d1092be8":"transferAllowedDelete(address)","d1096155":"requireOnce()","d10a5e1d":"lockBalance(uint256,bool)","d10ac7eb":"balanceOfComisionDone(address)","d10adfe3":"setPricing()","d10aee9c":"mainPlayer()","d10bc924":"seeCurrentParticipants()","d10c3d1d":"removeFromInitialSupply(uint256)","d10c504f":"has_voted(address)","d10ceb47":"setConsolationRewardsPercent(uint256)","d10d42eb":"Dividend(address)","d10da303":"_createLinglongCatWithTime(uint256,uint256,uint256,uint256,address,uint256,uint256)","d10db2e1":"addCar(address,uint8,uint16)","d10e10b3":"testCanFinalizeEndedSale()","d10e23c8":"ClothingCoin()","d10e73ab":"createIdentity(address,address)","d10e99fe":"mint(int256,bytes32)","d10f6de9":"_requestSignature(bytes32[8],bytes)","d1100691":"BookCafe()","d1104bd3":"SLRC()","d110f0e6":"LEGAL()","d1110c5f":"buyMicroKeysWithHandle(string,string)","d11127c0":"lastBlock_f18()","d1120db0":"size2()","d112cf30":"PCNCoin()","d114751e":"getWeightRange(uint256,uint256,uint256)","d1153f25":"bugFund()","d1159747":"PREICOstart()","d115cac6":"joinTournament(uint256)","d115f02d":"updateMinReward(uint256)","d116c8c4":"releasePayment()","d11711a2":"participate()","d1180c98":"Lotoblock()","d11831c3":"generateHash()","d1190b7f":"changeTransferStepLock(bool)","d1195c48":"transferNashOut(address,uint256)","d119db4c":"addScore(address,uint256)","d11bd1a6":"sendContingencyFunds()","d11bee0f":"STSTEST6()","d11cd4c6":"changeStartPrice(uint256)","d11db83f":"getPendingTransactions()","d11e77e4":"REIToken()","d11f13df":"numberOfParticipantsWaitingForPayout()","d11f5b9f":"VictorieumNewICOToken()","d11ffc55":"referralSupply()","d1206a29":"unlockRewardTokenMany(address[])","d120a284":"getBytesFromNumbers(uint8[3])","d120a4f2":"setUnderCollaterizedPosition()","d1211a71":"Solarex()","d1226567":"bulletAmount(address)","d1237220":"LogId(address,uint48)","d1239730":"mintEnabled()","d123b6e2":"ensureRegulated(address)","d1241e67":"getProductIdAt(uint256)","d125a7e2":"partialRefund(uint256)","d1260edd":"userDeposit(address)","d126ae0c":"TRLCOIN_DECIMALS()","d126dac4":"cashout(address,address,uint256)","d1279ea8":"AddTrust(address,uint256)","d127bb9d":"currentElement()","d12892e4":"setGiftMode(bool)","d128f2de":"cancelOwner()","d128fc20":"allocateTokensForFounder()","d1295eca":"ENDRoot()","d1295f13":"DTRACK()","d129ee38":"MediatedTransaction_Protection_Seconds()","d12a0a2e":"icoClosed()","d12a6049":"setWeiLockSeconds()","d12a7b42":"whitelistResolver(address)","d12b51c0":"changeUserEduExp(bytes32)","d12b88a6":"SelimToken()","d12c08bf":"EGGS_TO_HATCH_1BULLS()","d12c1e28":"badgesOf(address)","d12c7b52":"WarToken()","d12d5c47":"ReferredBonusTokensEmitted(address,uint256)","d12d9510":"DFTBToken()","d12e0b2a":"MultiOwnable()","d12f6938":"crowdSaleStatus()","d12f7029":"STARTING_PRICE()","d1301074":"grantTokenOwnership(address)","d13091ed":"newGoal(bytes)","d1314ee0":"getBroker()","d1315ea3":"ISRA()","d131a803":"FetchlastHacker()","d131ab1e":"UpdatedTokenInformation(string,string)","d131af30":"precisionMinimum()","d131dfb8":"setFirstStageStartsAt(uint256)","d13209f9":"unhold()","d132391a":"setSaleEndTime(uint256)","d132a8f4":"totalBuyTokens()","d132eb02":"ProposalPassed(address,address,uint256)","d13319c4":"getHash()","d1342958":"refuseKyc(address)","d134474c":"winnings()","d134f4aa":"challengeCanBeResolved(string)","d1351e94":"getRoundPlayerKeys(uint256)","d1354f64":"ReceiveTips(address,uint256)","d135ae6e":"isSignedByToly()","d135cc4b":"withdrawLocked()","d135df42":"CONEGTY()","d1366f17":"sellerRequestCancel(uint16,address,address)","d136a579":"claimEarlyIncomebyAddressRound(address,uint256)","d1375f76":"COIN_SUPPLY_ICO_TOTAL()","d1376daa":"getClosingLine()","d13782a7":"addStage(uint256,uint256,uint256)","d137874b":"getDiscount()","d1382092":"getNumTokens(address,uint256)","d1384eb6":"institution()","d13936fe":"connectOrderPrice(address,address,uint256,uint256)","d1397162":"icoOverview()","d13a3386":"withdrawSale2()","d13a64d3":"getYanCoefficient(uint256,uint32)","d13a73c4":"numberOfStages()","d13b54b7":"getGameAmount(address,uint256)","d13bf769":"foundersFundTimelock2Address()","d13c9c1e":"allocatePresaleTokens(address,uint256,uint256,uint256)","d13cb1fb":"fundings(uint256)","d13d1ace":"scheduleCall(bytes,bytes,uint16,uint8,uint256,uint256,uint256,uint256,uint256)","d13daa79":"TestTokenERC20()","d13e0808":"nextCommonTTMTokenId8()","d13e2a6a":"Wei_Remaining_To_ICO_Cap()","d13e5846":"tokenHolderCount()","d13e79ec":"getUSDRaised()","d13ea9ca":"setMinesPrice()","d13f092e":"setRaffleLimit(uint256)","d13f90b4":"initialize(address,address,uint256,uint256,uint256)","d13f9d55":"newIteration(uint256,string,bytes32,bytes32,bytes32,string,uint256,uint256)","d1407bec":"TraceCrowdsale()","d141138e":"getServerMoneyBag(uint256)","d14192ba":"numParameters()","d141b610":"MembershipPaid(address,uint8,uint256)","d1428e7a":"ratioFor(uint256,uint256,uint256)","d142bc5c":"individualWeiCollected(address)","d143dad0":"getLineSum(uint256)","d1442e93":"getStrField2()","d1472046":"CollectChips(address,uint256)","d14779c4":"signDigitalContract(string)","d1477f7b":"setInitialTokenValue(uint64)","d1479575":"creditcoinLimitInFrac()","d1482791":"updateInterest()","d148288f":"setHoldingPeriod(uint256)","d14ac7c4":"crowdSaleAllowance()","d14b2f9b":"addBonusToken(address,uint256)","d14b691d":"_resetReleaseTime(address)","d14cd233":"tokenSpread()","d14e1784":"paymentForWeek(uint256)","d14e62b8":"setCount(uint256)","d14ebab3":"NXE_Coin()","d14f17f7":"airdrop(address[],address)","d14f56f1":"moveUnsold()","d14f9219":"ham()","d150f835":"currentDonation()","d150fbe6":"convertToInd()","d151ec28":"getMadeTXFund(uint256)","d152865b":"getLastDIVDPeriod()","d15334a5":"firstVestAmount()","d15376a7":"lastBlock_f14()","d15392b2":"forceRelease(uint256)","d153ab40":"addMultipleTier1Members(address[])","d153b60c":"proposedOwner()","d153d118":"MyDice()","d1541264":"getManagerForCount(address)","d1555f1f":"approveCommitmentTransfer(address)","d1558b7c":"referrersCount()","d155908b":"addone()","d155feec":"EdisonCoin()","d156549f":"setExpiredAndWithdraw()","d1571996":"multisigOwner()","d1572e4c":"setResource(string,string,address)","d1577656":"purchaseTo(address)","d157e816":"MiningExtended(uint256,uint256,uint256)","d157f27d":"sendAdvisorsSupplyToken(address)","d157f645":"setPaymentInterval(uint256)","d1594403":"manualTransferTokensTo(address,uint256,uint256,uint256)","d15b506b":"TokenROC()","d15b95b4":"delegateDklBidAuction(uint256,uint256,bytes,uint256,uint16)","d15b9614":"GetLogMessageError()","d15c11e5":"providerRegistry(address)","d15c82e3":"reserveManyTokens(uint256[],uint256,address)","d15cfa25":"ChronoMint(int256,address,address,address)","d15d2745":"CLE_Beta_Pictoris()","d15d62a7":"getLibrary(uint256)","d15db5fb":"_computeBackground(uint256)","d15e06a0":"registerCrowdsales(address,uint256,uint256)","d15e1014":"marketingTokensPercent()","d15e9459":"stopAddressesTotal()","d15ecbc2":"simulatedBlockNumber()","d15ee9ff":"setUsersCanTrade(bool)","d15fc954":"wallet_Address()","d16058df":"getPayOrderKey(uint256)","d1613036":"releaseTokenTransfer(bool)","d1613731":"adminGetBalance()","d1614df3":"individualMinCap()","d1615300":"startWeekTwo()","d161b56a":"tokensMintedDuringICO()","d1631361":"ms0()","d1632f67":"assignFundReceiver(address,uint256)","d16352af":"getProtocol()","d163b764":"row(uint32)","d163fcab":"getCurrentHero()","d1650f7f":"test_oneValidEqStringNoLog()","d1651786":"donateUnicorns(uint256)","d165288e":"setAllowMining(bool)","d165d7cd":"registerNameXnameFromDapp(address,bytes32,bytes32)","d1660f99":"safeTransfer(address,address,uint256)","d166539b":"_migrate(uint256)","d16712ed":"maxGoalReached()","d16782f6":"testMetered()","d1682600":"StandardToken(uint256,string,uint8,string)","d16856ca":"addAdmin(address,string)","d16865a3":"PRIORITY_ADDRESS_LIST()","d168f699":"Glv(uint256,string,uint8,string)","d1698430":"revokeAllTokenGrants(address)","d169a020":"evMgmtIssueBountyToken(address,uint256,address,uint256,bool)","d169c869":"endOfPreSale()","d16a7a4b":"FreezeAccount(address,bool)","d16a8fe7":"kickMember(address)","d16a9624":"winBidEth(address,address,uint256,uint256)","d16b04cf":"myCoinAge()","d16b6473":"getOnTokenTransferToValue()","d16be71b":"teamTokensDelivered()","d16c4cf5":"FOUNDER1()","d16e1ded":"requestTransferItem(address,address,string)","d16e443a":"previousDelegates()","d16e92db":"createCrowdsale(uint256,uint256,address,address,address,address,uint256,uint256,bool)","d16edc15":"chargeFeePool()","d16f8669":"crowdsaleClose()","d16ff4c8":"nextCandidateId()","d1701397":"Flip1Token()","d17222dc":"CATContract()","d1724881":"getBroker(address)","d17291bd":"icoRunning()","d1729a4a":"sendTokensManually(address,uint256)","d172d6fc":"playFast()","d1734eac":"isInNextGeneration(address)","d173707d":"hasPhysicalAddress(address)","d1738b72":"wroomWroom()","d173d531":"Amalgam()","d173e578":"setInitialAllocationLock(address)","d173fc82":"setTokenAdmin(address,address,address,address)","d1746107":"teamTokenRatio()","d174c388":"tokensaleToOtherCoinUser(address,uint256)","d1759141":"massEthFund()","d175958f":"cancelApproveForAll(uint256)","d175d38d":"calculateBonus(uint32)","d176be98":"DonorCrowdsale(uint256,uint256,uint256,address,uint256)","d1776731":"userToRobots(address,uint256)","d1778ed7":"UltrixCoin()","d177e6a6":"fillOrder(address,address,uint256,uint256)","d1786610":"getTokenRemaining()","d1789176":"AMOUNT()","d179eb71":"clonedFrom()","d17a1b5b":"SetAccessType(uint32)","d17a79c1":"totalNormalEtherCollected()","d17aa842":"GetDivPerCoinLarge()","d17ab3c6":"free2Of(uint256)","d17be133":"getAllHousing()","d17cf29f":"retrieveWarriors(address,address,uint8)","d17d0d29":"SITExchangerMock(address,address,address)","d17d25de":"marketingTokenAddress()","d17e45fb":"s23(bytes1)","d17e4889":"decodeProps(uint256)","d17f5d9d":"indice_vincitore()","d17f7142":"isLocked(uint256,uint256,address,address)","d17fd539":"_newInterest(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d1802d79":"mintEGAS()","d18063cd":"registerParticipantAgent(address)","d1809fe8":"depositLiquidateThePool()","d180be1d":"isMemberOf(address,address,string)","d180d0bc":"_deliverTokens(address)","d180ebca":"FinishIco()","d1812be7":"newCustomFutureLottery(uint256,uint256,address,uint256)","d18165f6":"OEN()","d1818aed":"setPresidenteDeMesa(bytes32,uint256,uint256,uint256)","d181c37e":"NecroToken()","d182b4ff":"CurrencyHedge()","d182d253":"ICO_PHASE1_LIMIT()","d183434d":"accountsBalances(uint256,address)","d1835b8c":"left21(uint256)","d184194b":"Smw()","d184935d":"getDebug()","d184adf6":"distributeToAddressesAndAmounts(address[],uint256[])","d184b88e":"AddedPrepaidTokensEvent(address,uint256,uint256,uint256)","d185c583":"ownerWithdrawFees()","d185f378":"_owns(bytes32,uint256)","d18611d6":"reactivate()","d1866019":"GetReferredCount()","d186659d":"setRateIcoMainSale(uint256)","d186899a":"issueAndLock(address,uint256)","d18746ed":"BonusChanged(string,uint256)","d188f550":"setPlayerGeneralLv(uint64,uint8)","d1893d23":"oldusesr(address,address)","d189b98d":"firstPrivateReleaseTime()","d189c1b0":"createUserByEmail(bytes32,bytes32,uint256)","d18a5563":"depositsStack(uint256)","d18ad4de":"getPlayerAff(address)","d18b07b2":"calculateCommission(uint256,uint256)","d18b93e6":"_owns(address,uint256,uint256)","d18c5da7":"FrogDaruma(address,address,address,uint256,uint256,uint256)","d18d944b":"setHardCap(uint256)","d18df96c":"vault_enableRefunds()","d18dfdc9":"parrot(uint256)","d18e031e":"verifyDeed(string)","d18e142d":"Announcements(uint256)","d18e81b3":"currentTime()","d18ffb8d":"inversorIsKyc(address)","d19003e5":"_endOfPreICO()","d1900a04":"TRCTotalSupply()","d191b336":"AdjustBetAmounts(uint256)","d191d7f4":"OPERATIONS_SHARE()","d191e11d":"rateSystem(address,uint256)","d192367b":"randomA()","d1925b80":"YACHT()","d1933a1b":"goalManagment(bool)","d19370bb":"resetKYC(address)","d193a0ca":"splitsSingle(uint256,uint256)","d1940a16":"announce(uint256)","d195bbd5":"AywakeToken(address,address)","d195ef83":"mintAdminApproval()","d195fd28":"RESERVED_BOUNTY_SIDE()","d1976a6f":"completeGame(uint256,uint256,string,address)","d19853c7":"exchangeBounty(address,uint256)","d1987a28":"setTradeRobot(address)","d1988b6a":"getGameHash(uint256)","d199168d":"claimedTokens(address,uint256)","d199c81d":"TokenSale(uint256,uint256,uint256,uint256,address,uint256,uint256,address)","d19b8d87":"refundManagerContractAddress()","d19b99b5":"turnMigrateOff()","d19c395f":"capPreICOTrasferred()","d19d1912":"getSelfGroupsContributedTo()","d19d8e1a":"Ethereumbonus()","d19e09ce":"setDefaultAccountingPeriodSettings(bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,bytes2)","d19e1ad4":"_calculateNewPrice(uint256)","d19e2364":"addDonateTokenAddress(address)","d19e6cf0":"ChangeDeadLine(uint256,uint256,uint256,string,uint256)","d1a0cc5c":"processPayment(address,address,uint256)","d1a0e8c8":"setFeeRebatePercent(address,uint8)","d1a132f9":"enableNodeRegistration()","d1a1beb4":"mint(address,uint256,bool)","d1a1f5ba":"addSongData(string,string,string,string)","d1a2749c":"Crowdsale(address,uint256,uint256,address,address,uint256,uint256,uint256,uint256)","d1a2bfaf":"Wallet_Initial_Supply()","d1a2dfd2":"isExistingDataIdentifier(bytes32)","d1a3d3ad":"assertEq9(bytes9,bytes9)","d1a3fb20":"updateUserRatio(uint256,address)","d1a40ce1":"_rewardVote(address,address,uint256)","d1a4a98c":"BeBitcoin(uint256,string,uint8,string)","d1a61025":"tradeBookOf(address)","d1a634e6":"OVC()","d1a69455":"get_enode_by_row(uint256)","d1a75e0d":"VOTE_FOR()","d1a75fea":"createTreatyRequest(uint8,string,uint256)","d1a7d1a8":"MyPinerTokenTest2()","d1a8d447":"get_all_bet_values()","d1a94e58":"TXOtoken()","d1a9eb19":"withdrawToContractOwner(uint256)","d1a9f5be":"createFileWithContents(string,uint256,bytes32[],uint256)","d1aadb6a":"setColour(uint8,uint8,uint8)","d1ab0457":"AddSoftware(string,string,bytes32,bytes32,bytes32)","d1abdab8":"divideDecimal(uint256,uint256)","d1acb464":"CreatedLoan(uint256,address,address)","d1ae0488":"transferBecauseOfAggregate(address,uint256,address,uint32,uint256[],uint256[])","d1ae956f":"isPayed(uint256)","d1ae9607":"LFSTYLToken()","d1aea543":"forwardFunds(address)","d1af8a5a":"LinkerExample()","d1afaf1f":"addusertime(address)","d1afdb86":"buyAllowed()","d1b12b4e":"extCreateBot(uint256,uint256,uint256,uint256,address)","d1b1a22b":"set(string,uint256[],uint256[],uint256[],bool[],uint256[])","d1b1b65a":"rangeETHAmount()","d1b31a63":"cryptobank(bytes32,bytes32)","d1b33094":"addAccessor(address,uint8)","d1b33afa":"_calculateDayPass()","d1b39ae5":"decimalOffset()","d1b4ff7e":"multiAccessRevokeD(bytes32,address)","d1b5e2be":"testFailRegisterContractIdAgain()","d1b648cd":"contractSendGas()","d1b6a51f":"finishEthGetToken()","d1b6dd30":"airdropClaimed(address)","d1b7cb9b":"transferBatch(address[])","d1b878e9":"getresult(uint256)","d1b9c430":"OPEN()","d1ba656b":"minimumTransferInWei()","d1ba8257":"SIX()","d1baaf58":"communityRoundStartDate()","d1bab4cc":"batchApprove(address,uint256[],uint256[],uint256[])","d1baceac":"DepositBank(address,uint256)","d1bb0433":"preSaleTokensPurchased()","d1bb5cf1":"marketplaceContract()","d1bb7b59":"tokensPerWeiBonus111()","d1bb8688":"ICO_SHARE()","d1bba64f":"Investment()","d1bc2cc4":"transferGift(address,address)","d1bc4157":"KanZhang()","d1bc5c8e":"KryptoroToken()","d1bc62de":"EARLY_FOUNDERS_USD()","d1bc76a1":"recipients(uint256)","d1bcbf6c":"_isReady()","d1bd328b":"bonusFirstIco()","d1bd56c1":"TripleT()","d1bdf639":"cards_black_check(address)","d1be7cc4":"serverPortUpdate()","d1bf942a":"rok()","d1bf9aba":"nextRune()","d1c01b26":"Crowdsale(address,address,uint256,uint256)","d1c06b2f":"availablePositions()","d1c1132f":"lockInTreasury()","d1c13abd":"returnRental()","d1c15acf":"OWNERS_AND_PARTNERS_SUPPLY()","d1c19fbc":"Withdrawn(address,address,uint256)","d1c1f19f":"NewPlay(address,uint256,bool)","d1c2babb":"merge(uint256,uint256)","d1c31f10":"tokenLockUp(bool)","d1c332c7":"preDistriToAcquiantancesStartTime()","d1c43558":"TheExtraordinarySpacemen()","d1c46916":"releaseLock(address)","d1c484f6":"proposedRecoveryKeyPendingUntil()","d1c4c206":"setRoute(string,address,bool)","d1c5e119":"getMyAnotherDragon()","d1c673e9":"transferAndCall(address,uint256,uint256,bytes)","d1c693f8":"TOTAL_TOKENS_FOR_PRICE()","d1c699aa":"exerciseFee()","d1c6b0ca":"setBonusAmount(uint256)","d1c6f448":"updateInitialRate(uint256)","d1c72c89":"isInRoundTwoState()","d1c73322":"tokenHardcapReached()","d1c7a6ac":"ActivationWithdrawal(address[2],uint256[8],uint256,uint256)","d1c7be4d":"_pushLuckyInfo(uint256,uint8,address,uint256)","d1c85478":"GGRocketToken(address,string,string,uint256,uint256)","d1c8e7e6":"charityDonation()","d1ca0218":"issueToken(uint256,uint256,uint256)","d1cb0f0f":"getAllTombs()","d1cb923c":"HUNDREDTIMES(uint256)","d1cb993d":"grantAllowance(address,uint256)","d1cbfc66":"getOneTotalFeesDistributed(uint256)","d1cbfe65":"setRefferal(address)","d1cc9976":"isTerminated()","d1cd19cf":"advisorCut()","d1cd7bfa":"setSUTokenContract(address)","d1cdcf71":"PRICE_STAGE_FOUR_BONUS()","d1cdfe84":"Bonus_PoolTransfer(address,uint256)","d1ce017c":"getABIHashForMod(bytes32)","d1ce36aa":"unLockIdx()","d1ce65ab":"isCryptoRomeLandComposableNFT()","d1cec3ac":"CrowdSaleTest()","d1cf113e":"multiAccessSetRecipient(address)","d1cfe644":"EventCashOutTank(address,uint256)","d1d115ac":"test_fourInvalidEqUint(int256)","d1d1c8ae":"ConvertNumbers(bytes)","d1d1f264":"setSubscriptionStatus(bool,bytes32)","d1d2bd55":"calculateRangeLength()","d1d3a898":"_createElement(uint256,string,address,uint256,uint256)","d1d3bb92":"testSetPkg()","d1d3d8a6":"MintLog(address,uint256)","d1d422f6":"roundEvent(address[6],bytes32[6])","d1d46d2b":"setChestPrice(uint16,uint256)","d1d4c4c6":"safeDiv(int256,int256)","d1d5190c":"changeStart(uint256)","d1d53493":"setMaximalInvestmentTimeTreshold(uint256)","d1d566cf":"allocateExtraTokens(address)","d1d5824d":"maxBetThresholdPct()","d1d58b25":"claimable(uint256)","d1d675e4":"setMaximumCoinsPerAddress(uint256)","d1d6d639":"EstimateGas()","d1d6e44a":"paintGraffiti(uint256,string,string)","d1d80fdf":"setAddr(address)","d1d8fd65":"TransferCoins(address,uint8)","d1d93318":"createAvatar(string,uint256)","d1da09ee":"extractImportFeeChargeLength()","d1da8436":"setAdData(uint256,string,string)","d1db1cc4":"LogRefundingOpened(uint256)","d1db99b6":"INR_Omnidollar()","d1dbcd70":"isNodeTLDOfRegistrar()","d1dc3706":"LogReceivedETH(address,uint256)","d1dc72a0":"METAHASHCOIN()","d1dd2794":"buy_end_time()","d1ddb24e":"recordResult(address,address,address)","d1de5011":"getAccount(bytes32)","d1de592a":"add(bytes32,bytes32)","d1defff2":"_educatedToken()","d1df1252":"ringBell()","d1df306c":"burnToken(address,uint256)","d1df81df":"getPlayerInfo()","d1dfdc07":"patentSaleTimeDelay()","d1e0363d":"_createLock(uint32,address,uint256)","d1e040ec":"ConvertColouredBkp(address)","d1e07bcb":"onlyCapperMock()","d1e15045":"sendBack()","d1e191a4":"withdrawEverything()","d1e19ab2":"distributeAllTokensToContributor()","d1e2eb5e":"countInvestor()","d1e34733":"GCOXACMToken(string,string,uint8,uint256)","d1e400f4":"ecoSystemAddress()","d1e4b8da":"importBalance(address)","d1e58e0f":"preIcoRate()","d1e692eb":"lastLottoTime()","d1e6a64f":"leftForSale()","d1e7e81f":"selfLock()","d1e83b8b":"ChangeInterest(uint256,uint256,uint256,uint256,bool)","d1e8acb4":"ABC(uint256,string,uint8,string)","d1e9822c":"RESERVE_WALLET()","d1e99563":"BACKLEAF()","d1e9ab13":"Swift()","d1e9dcbf":"serverForceGameEnd(address,uint256)","d1e9f75b":"testHitSoftCap()","d1ea2786":"offerSketchForSale(uint256,uint256)","d1ea8b89":"QNTUsdRate()","d1eabc94":"CardToken(uint256,string,string,string,string)","d1eb6404":"donationsFrom(address)","d1eba9c9":"getDeployedAuctions()","d1ec32ed":"secondsToHold()","d1eca85e":"startIcoPreICO()","d1ecdec6":"m_OwnerFees()","d1ed3dad":"getIndex(address,address)","d1ed74ad":"retrieve(bytes32)","d1ee2bf9":"icoDiscountTime()","d1ee32c3":"issueTokensForICO(uint256)","d1ef4e91":"vestTokens(address,uint256,uint256)","d1ef752d":"Post(address,address,address,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","d1efb5cd":"_getChamp(uint256)","d1efd30d":"secret()","d1f0bb2d":"populateAllowedFreeExchanges()","d1f1ef34":"setPrivateSale()","d1f1fff8":"minBalanceForTxFee()","d1f276d3":"releaseAgent()","d1f2a7e2":"isUserPolicyAccepted()","d1f2efd5":"isMainSale()","d1f2f971":"calculateDivi()","d1f34b14":"__uintToBytes(uint256)","d1f38097":"CTGToken()","d1f461d5":"getUsernameFromAddress(address)","d1f4df47":"grantBountyTokens(address)","d1f55764":"shareContract()","d1f59db9":"isLatestMinorTree(bytes32,bytes32)","d1f61c44":"Totalizeum()","d1f61ed5":"dropRoute(uint32)","d1f6424f":"configurationCrowdsale(address,uint256,uint256,address,uint256[],uint256,uint256,uint8,uint256)","d1f69902":"getHeroClassId(uint256)","d1f6d676":"ExchangeContract(address,address,uint256,uint256)","d1f70760":"setAdditionalTokensFromCommonPoolWallet(address)","d1f7a4e4":"createCertificate(bytes)","d1f8a208":"removeOrganisation(address)","d1f92cab":"timereumDelta()","d1f95204":"propertyIndexToOwner(uint256)","d1f9c24d":"gameState()","d1f9f3a0":"bitdncToken()","d1fa338d":"TokenStorage(address)","d1fa74d2":"SimpleEscrow()","d1fa94d0":"setLockStatus(bool)","d1fa9cad":"Partners()","d1fae327":"CofounderSwitchedEvent(address)","d1fb386a":"_recordStashedPayout(uint256,uint256)","d1fb5646":"releaseTo(address)","d1fc0ddf":"prevOracle()","d1fc8cf3":"endDispute()","d1fccf9e":"bonusedPurchases()","d1fd260e":"getLotteriesByOwner(address)","d1fd3b12":"_rotateCauldron(uint8)","d1fe43ba":"migrateDueToNoReports()","d1fea3d5":"setReleased(bool)","d1feb5ee":"deleteArrayBytes32()","d1feca67":"addSpendingRequest(address)","d1ff535e":"PURCHASER_MAX_TOKEN_CAP()","d1ff8151":"getNumTanks()","d1ff9605":"setAdminFeePercent(uint256)","d1ffb796":"_ListingRemoved(bytes32)","d2004f8c":"getChance(uint256,uint256)","d20058af":"ESCBAirdropper(uint256,address)","d2008118":"logPromiseConfirmed(uint256)","d202158d":"keyHasPurpose(bytes32,uint256)","d2038d4d":"finalize4()","d2051f8e":"updatePassword(uint256,string,string,string)","d205ad7d":"proposeDissolve(bytes)","d205bcb0":"isPendingOracle(address)","d205f1e6":"testFail_set_price_without_token()","d2064e2f":"getStamp(uint256)","d2077782":"changeRequestCount()","d2079c0f":"playersLength()","d207e757":"ownerSetOraclizeSafeGas(uint32)","d2080ccd":"pauseWhitelist()","d20838f4":"setRegistryContractAddress(address)","d208fd60":"getMessageSender(uint256)","d209a566":"BP_PERSIAN()","d20ae2b5":"getMyWorks(bytes32,bytes32)","d20c34de":"TaylorToken()","d20cd8e5":"Solved(address,string,string)","d20d6119":"createTokenUri(uint8,uint8,uint8,uint8,uint8)","d20db416":"_approvePurchaser(address,uint256)","d20de0bc":"nextParticipantIndex()","d20e54a8":"startBet(uint256)","d20f5029":"advisorsTokensAddress()","d21077f3":"areFundsReleasedToBeneficiary()","d211483f":"RoleRemoved(address,string)","d211fd18":"capital()","d211fe86":"icoEndtime()","d21220a7":"token1()","d212a69a":"_fees()","d2134b26":"expTx(uint256,uint256,uint256)","d2135356":"isValidRelease(uint256)","d213ed96":"manageApprovedMintingModule(address,bool)","d213f109":"calcAmtReclaimable(address)","d21407fa":"crowdSalesCompleted()","d214326f":"GetWinners()","d214becb":"charactersCountOf(address)","d2161687":"reflectSwitch()","d2164302":"forgeWeaponPureDamage(uint256,uint256,uint256,uint256)","d216995b":"determineBonus(uint256,uint256)","d2169d2f":"getMonsterLevel(uint64)","d2169dfd":"RETURN_DATE()","d216a47d":"decreaseApproveAndCall(address,uint256,bytes)","d216a86c":"publicEventActive()","d216d55d":"etherandomExec(bytes32,bytes32,uint256)","d21705ff":"admin_proportion()","d2178b08":"get2()","d217b149":"managerUnset()","d218e144":"calculateRanking()","d218f92d":"checkinter()","d219f103":"collectedEtherFrom(address)","d21ad1ed":"calculateWinnerCut(uint256,uint256)","d21b84ac":"createNewDAO(address)","d21b93df":"Hypes()","d21b96ab":"ringhashRegistryAddress()","d21bdee4":"Bitforce()","d21c39a1":"acceptPayment(address,uint256,address,uint256,uint256)","d21c700f":"stopToken()","d21cacdf":"referrerOf(address)","d21cbffc":"getIfVoted(uint256,address)","d21ceba0":"RemainingTokensReceiverAddress()","d21cf24f":"setSingleWithdrawMax(uint256)","d21d2cd1":"lifePoints()","d21d7950":"changeGasLimitOfSafeSend(uint256)","d21e17a6":"_payEthereum(uint256)","d21efc35":"endPhase()","d21fa4e1":"contract_alive_until_this_block()","d2201c3b":"CreateLUNETS(address,uint256,uint256)","d22057a9":"register(bytes32,address)","d220b727":"ProposalTallied(uint256,int256,uint256,bool)","d2225635":"getBetterNumOfWinnings(address)","d22290a4":"feeBips()","d222dc04":"requiredSignedAddress()","d2231919":"TransactionRefundedByMediator(uint256,uint256)","d22341a9":"withdrawDeveloperPot(address)","d2234b37":"withdrawal2()","d2235998":"_cancelAuction(address,uint256,address)","d223926f":"buyBooster(uint256)","d224118f":"PrepareDraw()","d224c3e0":"gen0Step()","d224f1ed":"proxiesCount(address)","d2254db0":"DDEToken()","d22591c8":"addBook(string,address)","d226d11f":"foundEvidence()","d226ff1b":"User(string)","d2273f37":"_changeTuneOption(uint32,uint32,uint256,bool,bool,uint128,bool,uint64,uint256)","d2282dc5":"setUint256(uint256)","d228cfc5":"claimHodlRewardFor(address)","d229a94a":"lockTokensForTradingMarketContract(address,uint256)","d22a1180":"finanReserveAllocation()","d22ac06f":"_approveEscrow(bytes32,uint256)","d22b1a0f":"secondVestStartsAt()","d22b32e9":"hivePerEther()","d22b3c8b":"ownerArmyCount(address)","d22b3de6":"setTitulaire_Compte_10(uint256)","d22b64a2":"getDonationByAddress(address,address)","d22b9177":"getImageRegionId(uint256)","d22bdce2":"_getNextStage()","d22c391a":"validateProposedThroneRules(uint256,uint256,uint256,uint256,uint256)","d22c78f8":"getPlanetDetails(uint256,uint256)","d22d9c6d":"tokensInUse()","d22dee48":"claimProfit(uint256)","d22e7b69":"validatePublisher(address,bool,string)","d2305f07":"getCloneArray(uint256[])","d230e875":"MaxValue()","d232790d":"setLastWinner(address,uint256,uint256,uint256)","d232a8f5":"firstStageCap()","d23376ec":"getPOOL_edit_14()","d233e5c0":"oxen(address)","d233fc0b":"changeRecovery()","d23628f1":"CyberRailNET()","d2368f64":"Billing(uint256,uint256)","d237a427":"TT()","d237b43f":"reclaimResourceDeposits(address)","d237bc74":"paymentSizeC()","d238cd1b":"redeemVoucherSingle(uint256,address,address,uint256)","d238ec90":"HWGLToken()","d2395dcd":"buyTokens(address,uint256,uint256)","d239ea8b":"getSchemasLenght()","d23ad39d":"setCommons(address)","d23b8f5c":"drawDailyWinner()","d23dcee0":"_generateTokenURI(bytes32[],uint256)","d23df2d1":"RENEX_SETTLEMENT_ID()","d23e09f5":"trioContract()","d23e8489":"transferOwnership(uint256)","d23ea159":"eGoldchainStart()","d23ef360":"setExchangeRegulatorWallet(address)","d23f0abb":"issueTokensForPresale(uint256)","d23f1bba":"noBets()","d23f4450":"scoreDown(address)","d24155c1":"getAmountBonusRate()","d2415852":"TheDivine()","d241ead8":"testMinReturn0WithReturn()","d242448c":"transferredCrowdsale()","d24257c0":"betAmount()","d2427db5":"checkTotalPayout(address)","d242b051":"reserveWaveLockup()","d243ec26":"payDev()","d244059a":"whiteListLimit()","d245a084":"TransactionRefundedAfterDispute(uint256,uint256)","d245aa92":"endBlockBonus3()","d245da28":"updateEarlyParicipantWhitelist(address,address,uint256)","d2467e31":"GetSellingTokenDecimals()","d246a8c9":"lastNegativeVoting()","d246b379":"calculateRevenue(uint256,uint256,uint256)","d246d411":"burnAddr()","d247160a":"ethertoteDevelopmentTransferComplete()","d24876b7":"sellCMTAgainstEther(uint256)","d248cf1f":"DASHABI(uint256,string,string)","d24987fc":"getNewTokenPrice(uint256)","d24999ca":"getkillerPriceConversionFee()","d249a52e":"update(bytes,uint256[],uint256[])","d24ac764":"getRejectionCount(uint256)","d24b06b7":"registryRequestCustodian()","d24b08cc":"callstoredaddress()","d24b62a8":"lotteryReset()","d24b7090":"_payEtherAndDistribute(uint256)","d24b7e7a":"setEthPrice(uint128)","d24bcb15":"usechainWallet()","d24bcf54":"getEarlyIncomeByAddressRound(address,uint256)","d24c8fe4":"_getCurrentStage()","d24d11ad":"BattleProvider(address,uint256,uint256,uint256,uint256,uint256)","d24ddcfe":"buyKissBTC()","d24ecc10":"initializeSale(uint256,uint256,uint256,uint256,address)","d24ef4f3":"PLATFORM_DEVELOPMENT()","d24f8a17":"convertShortedTokensToLiquidationToken(uint256)","d2500033":"RISE()","d25090ff":"withdrawContribution(uint256)","d25119c7":"getMsgHash(address,string,string)","d2521034":"marriageStatus()","d2526418":"getFeePercent(address)","d2531590":"CANCEL_EXTRA_GAS()","d2536893":"setDividendWinners(uint256[],uint256[],uint8[],uint256)","d2548393":"team2019TokenCreated()","d255494a":"removeInventory(bytes32)","d25570f2":"AliceToken(uint256)","d2558fca":"Token3D()","d2559533":"WinancesToken()","d256451c":"setRates(uint256,bytes32[],uint256[])","d256c7a5":"setTokensPerEther(uint256,uint256)","d2571062":"setAllContracts()","d2577fec":"_getRoleSignature(address,bytes32,address)","d258d7b6":"test_4_generateTokensAccrossBlocksAfterDestroy_increaseBlocksBy1000()","d258f2f4":"TeTeToken()","d2591068":"TLCMarketCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","d259224a":"ssstt()","d2598c4c":"removeTrader(uint8)","d2599312":"initShareRule4Publicity()","d259d761":"changeAdminContract(address)","d25a1212":"revokeAttributeSigned(address,uint8,bytes32,bytes32,string,bytes)","d25a13b4":"roundTwoBlock()","d25a5be9":"airdropTotalSupply()","d25b3ee1":"AcademiCon()","d25b4f2a":"CrowdsaleRC()","d25c0767":"isSaleAuction()","d25d19e2":"SetThrdOwner(address)","d25d603c":"cancelOrder(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32,string)","d25dc056":"transferToWinner(address,address,uint256)","d25e3443":"ISLToken(uint256,string,string)","d25f08b1":"adminAddICO(uint256,uint256,uint256,uint256,uint256,uint256[],uint256[],bool)","d25f1c35":"CPGPEREGRINE_MAX_CARGO()","d25f82a0":"getAirdrop()","d25ff342":"MNXToken()","d2602930":"RockPaperScissors()","d26031ab":"phase2EndingAt()","d261de38":"NVCTToken()","d261fbed":"addressCallWithArray(address[3])","d2620e2d":"holdOf(bytes32)","d2625fce":"pendingOracleB()","d2631e42":"changeRewardManager(address)","d263b7eb":"ownerkill()","d263be48":"myWallets()","d263d2a4":"setWildCardToken(uint256)","d264a878":"getOraclizeWinnerTimeOffset()","d264cfdc":"lockAccountOf(address)","d264e05e":"forward()","d2650fe5":"RedeemEvent(address,uint256,uint256,uint256,uint256)","d2651855":"changeERC20(address)","d2654219":"getCurrencyDenominated()","d2656069":"SmartContract_Allowed(address)","d26574ac":"setCardPerkText(uint256,string)","d266e83b":"isActive(address,uint256)","d2670025":"REQ()","d2676711":"getCommentAccountsLength()","d2689abc":"ecdsaverify(uint256,uint256,uint256,uint256,uint256)","d269ae55":"MAX_ALLOWED_TOTAL()","d26c8a8a":"coinBalance()","d26cbe1e":"Contributed(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool)","d26cfeae":"setMinAmount4Round(uint256)","d26da39e":"isRequestFromOwnerOrMeterKey(address)","d26dbd2a":"preSaleTokensDisbursed()","d26ee061":"getAvailableFundsForTheTeam()","d26f9cd7":"backofficeRedeem(uint256)","d26ff86e":"submit(bytes32,bytes32)","d270085e":"addNoFeeAddress(address[],address[])","d270b8e8":"tokenDistributionEndTime()","d270cbaf":"buyAAC()","d270e7ab":"mainContract()","d271011d":"transferEthers()","d2715a6b":"getEmblemOwner()","d2718fbe":"setOwnerFlag(uint256,uint8)","d271900d":"linkContract(address)","d2719d22":"btcRate()","d271b067":"ln(int128)","d2727e6c":"_oneTokenInWei()","d2728f90":"Bought(uint256,address,uint256)","d273285b":"createdWallets()","d27399b5":"countAddressesSet()","d27416ec":"verify(bytes32,uint8[5],bytes32)","d27482a4":"claimOwner(address)","d274b230":"registerFor(address,address,uint256,uint256,uint256)","d274fa91":"amendRetention(uint256,uint256)","d2756e11":"finalizeNumber(uint256)","d2758538":"createOneDrink(string)","d2760b64":"_isBuying()","d27626fd":"pushToken(address[],uint256,uint256)","d2769df1":"isValidComposition(uint256[],uint256)","d276a3e1":"auctionedEth()","d2789aa5":"getPrivilegeState(string)","d279830c":"addMilestone(uint256,uint256,uint256)","d279c191":"claimReward(address)","d27a43f6":"_checkWin(uint256,address)","d27a6f28":"ZyPPACrowdsale(uint256,uint256,uint256)","d27aa18e":"Secure()","d27bf2e3":"getCurrentLocation()","d27d1bc4":"proposalsNumber()","d27d3e88":"bulkSend(address[],uint256[])","d27f41cd":"CharityInProgressWallet()","d27fcf96":"gmtFundAddress()","d27ffef1":"OLIFEToken()","d282866a":"whichTick(uint256)","d282db01":"_withdrawal(address)","d2835c58":"P4P()","d283833d":"toekensForTeam()","d283859d":"removeBlack(address)","d2840362":"addAdvisors(address,uint256,uint256)","d28442ef":"ownerProfit()","d2846c7b":"isProxyContract()","d285b7b4":"loan()","d286dbf2":"internalNewRound(uint256,uint256)","d2871105":"tokensIssuedBySTO()","d2874e49":"withdraw(address,address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","d2879f47":"_getContractTokenBalance()","d2886ebc":"getUserSkills(address)","d288c878":"blackListERC20(address)","d289ade2":"payFee(uint256)","d289eb82":"buyMultipleItems(uint8)","d289f187":"_addBonus(address,uint256)","d28a4f9e":"setKyberContractAddress(address)","d28ae9ef":"calcMiningSharesAmount(uint256,uint256)","d28b5317":"setCampaign(bytes32,uint256,uint256,uint256,uint256,bool,address,string,int256)","d28be797":"getShitClonelordReq()","d28c25d4":"changeGreeting(string)","d28c2aaa":"fix_parents(uint256,bool)","d28cb7b5":"availableWallet(address)","d28cbded":"ERC20Token(uint256,string,uint8,string)","d28d4e0c":"queryAllAccounts()","d28d8852":"_name()","d28dcdea":"haltPurchase()","d28e4355":"updateClaimable(uint256)","d28e88bd":"freezeDateOf(address)","d28f95ba":"withdrawalEth()","d28fa960":"withdraw_all_funds()","d28fdde8":"updatePrice(uint256[])","d2901c47":"RATE_SOFT()","d290ee06":"revokeTokenTimelock(address,uint256)","d291fa81":"GetMinerAt(uint256)","d29208d4":"MasterCoin()","d292515d":"totalMintNums()","d292b920":"CryptaurMigrations()","d292e6cb":"_sendPriceUpdate(address,uint256)","d294cb0f":"accountBalance(address)","d294f093":"claimFees()","d2953f84":"assetByIndex(address,uint256)","d29543af":"FolioNinjaToken(address,address,uint256,uint256)","d296853a":"whitelistPreSaleAddress(address,bool)","d2970120":"getSettlingTimeoutBlock(bytes32)","d29709fb":"returnDeposit(address,uint256)","d2973f93":"setUserType(address,uint256)","d2983dfd":"LoadedRefund(address,uint256)","d299dac0":"blake2b(bytes,bytes,uint64)","d29b5d2f":"mintReputation(uint256,address,bytes32)","d29c8c96":"createdBlockOnCommitsPhase(uint256,address)","d29cafe1":"ZilliqaToken(address,uint256)","d29cbd60":"getMonsterBaseStats(uint64)","d29d44ee":"_transferOwnership(address)","d29d503c":"addHolder(address,uint256,uint8,uint256)","d29d91ca":"getNarcoHomeLocation(uint256)","d29db7e4":"_processPurchase(address,uint256)","d29dd76d":"whitelistAdmins(address)","d29e2746":"place_buy_order(uint16,string,address,string,string)","d29e319c":"TOKEN_ICO3_LIMIT()","d29e6803":"secretHash()","d29ebd2e":"privateOfferingSupply()","d29f541d":"getPosition(uint256,address)","d2a09b96":"_updateReferrals(uint256,uint256)","d2a17959":"transferTokensFromVault(address,uint256)","d2a1e045":"FuBi()","d2a2feaa":"STRI()","d2a32c12":"bonus_amount()","d2a3899c":"payOrder(uint256,uint256,uint256)","d2a3b190":"SAToken()","d2a569c3":"startAirdrop()","d2a6629c":"playerActiveGames(address,uint256)","d2a6cf5e":"internalTrade(uint256,uint256,uint256,uint256,uint256,uint256,bool,address,address,bytes32)","d2a718ec":"isRefundLocked()","d2a753e4":"cancelBid(address,bytes32,int32,bool)","d2a764d1":"contributeInBNB()","d2a79e57":"tixPresaleDeposit()","d2a7d38a":"MIN_FUNDING_AMOUNT()","d2a7ea17":"setSelfAsPureShareholder(string)","d2a86985":"_ORAK()","d2a9b6ed":"getVotingFor(address)","d2aa24b6":"getControlInfoMaxPerBlockImbalanceList()","d2ab6be1":"start(uint8)","d2ab78b7":"getGameName(address)","d2ac0f59":"setHeroContract(address)","d2ac1c8e":"addApprovedAddress(address)","d2ac2d8a":"heldOf(address)","d2acbc0d":"card_metal_minamount()","d2accad3":"_changeText(uint256,string)","d2ace0cc":"_newVoting(bytes,string)","d2ae5f65":"earlyInvestorTokenRaised()","d2ae8eaa":"getGenesForSale()","d2aeb90f":"removePoweruser(address)","d2aee00b":"getCanAttackMonsterIds()","d2afa8c1":"isERC721()","d2afeeeb":"createBoard(bytes32,bytes32,uint256,uint256,uint256)","d2b001fb":"PREMIUM_TYPE_COUNT()","d2b022d5":"pendingWithdrawalsBalance()","d2b0d554":"getDisclaimer()","d2b10b75":"AirDropContract(address,address)","d2b1569e":"redeemRewardedAxies(address,uint256)","d2b3fe93":"updateRoundLimits(uint256)","d2b420ce":"isOfferSorted(uint256)","d2b4a460":"getJackpotFee(uint256)","d2b50743":"DOW_FRI()","d2b5c227":"AsideTokensHaveBeenAllocated(address,uint256)","d2b5d9e1":"refferalFee()","d2b73cea":"getActiveContractAddress(uint256)","d2b74f70":"CryptoFamousStorage()","d2b75b70":"_upsert(address,uint256,bool,bool,uint256)","d2b77264":"pollMap(bytes32)","d2b78529":"getContractNetBalance()","d2b7d957":"executeDelegatecall(address,uint256,bytes)","d2b8035a":"draw(uint256,uint256)","d2b8915c":"offerPosition(uint256,uint32,uint256)","d2b8b867":"doPayment(uint256)","d2b93303":"EternalToken()","d2b962f2":"createLiability(bytes,bytes)","d2b9da84":"Office(string,string,uint256)","d2ba499c":"IS_SIGNATURER(address)","d2ba5537":"numberOfClaimants()","d2ba8073":"minbid()","d2bafbe6":"setMaxCoordinate(uint256)","d2bb6fd5":"timeTier2()","d2bbda29":"registerName(string,address,string)","d2bbf6df":"getIndexId(address,bytes32)","d2bd3dd9":"YAP()","d2bec28c":"startCraftingAuction(uint256,uint256,uint256,uint256)","d2bf779f":"getKingdomInformations(string)","d2bfd24b":"setgamecard(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d2c03c01":"auto_withdraw(address)","d2c0e032":"set(address,string,string)","d2c18e0b":"api()","d2c18f59":"emergencyManager()","d2c33eb2":"claimRaisedWei(address,address)","d2c37621":"getUserLocalTokenBalance(address)","d2c3a1ec":"updateStageInfo(uint256,uint256)","d2c411d3":"closeBatch(uint256)","d2c49b7f":"getTimeUntilEnd(uint256)","d2c51c72":"withhold()","d2c5c368":"testFailRestartNotUpdatable()","d2c5ce31":"dateTimeAddr()","d2c73093":"createTokens(uint256,address)","d2c731d9":"TermsOfUse()","d2c877f8":"setDollarRate(uint256)","d2c87b02":"MB(address,address,address,address,address)","d2c936ff":"currentBonusLevel()","d2c94ec5":"C4FToken()","d2ca159a":"listUnconferences()","d2ca2115":"periodLength()","d2cad255":"BankDeposit(address,uint256)","d2cad6da":"bonusCalculate(uint256)","d2caeea8":"aomucoin()","d2cafe2d":"allAssetsOf(address)","d2cbcea6":"getSSP(address)","d2cc7015":"placeMove(uint8)","d2cc718f":"accumulatedInput()","d2cced90":"getAnnualInterest(uint256)","d2cd9673":"totalMining()","d2cd96bd":"changeQuorum(uint256)","d2cdf580":"setKYCpassed(address)","d2ce89e5":"logoURL()","d2cf7704":"BanAttempt(address,address,uint256)","d2cfe5a7":"posscoin()","d2d0ded1":"referrerBonusPercent()","d2d0e066":"deposit(address,uint256,uint16)","d2d10162":"initialize(address,address,uint256,uint256,address,address)","d2d10be8":"TGEToken(string,string)","d2d153a4":"Grand_Solar_Minimum()","d2d26edc":"Cloudcoin()","d2d3b8e0":"multiAllowance(address,address[],address[])","d2d42074":"getExchangeContractAddress()","d2d44955":"Cindicator()","d2d4bd72":"getCrossRate(bytes,bytes)","d2d5a55c":"ownerValidator()","d2d7231f":"calculateReward(uint256)","d2d791c0":"payBatch(bytes32[],uint256[],address,address,bytes)","d2d85cf2":"rootsMatch(address,address)","d2d8cb67":"TOKEN_PRICE()","d2d8fd0a":"settleFrom(address,address,uint256)","d2d92f24":"getWhitelistEntry(uint256)","d2d93f90":"ethRate()","d2d976da":"webpage()","d2d97d9f":"coldStorage()","d2d9b8c6":"setCompte_24(string)","d2d9d44e":"awardTitanium(address,address,address)","d2da29c7":"hostAddress()","d2db29af":"claimFutureUse()","d2dc0869":"add(string,uint256,string,string,address)","d2dcd933":"totalSupplyAtTime(uint256)","d2dd8d2a":"authorized_updateCardClaimerAddress(uint256,address)","d2dd9f79":"transferVault(address)","d2ddf1ae":"TradingForest(address)","d2de6cca":"getArrayValueByKey(string,string)","d2de6ec5":"distribute(uint256,uint256,uint256)","d2de9989":"stopPreIoc()","d2df254c":"weiToUSD(uint256)","d2df9222":"recoverStockKey(bytes12)","d2df9cc1":"startTimeSaleNoBonus()","d2e013d9":"Execution(string,string,string,string,string,string)","d2e01b2f":"getLockPosition(address)","d2e0637b":"createContractTot(string)","d2e10879":"getReceiptRoot(uint256)","d2e1d201":"setstring(string,string)","d2e2acf5":"_proxyTransferEvent(uint256,uint256,uint256,bytes32)","d2e3646c":"optionsConverter()","d2e474b3":"PROMOTORS_POOL()","d2e73d78":"withdrawDepositorFunds(address,uint256)","d2e78ace":"DestructionContract()","d2e80494":"setConversionRate(uint256)","d2e81bf9":"initPlayer(address)","d2e8309e":"test_messageSenderEq()","d2e90d0f":"startTimeICO()","d2e91b85":"getset()","d2e9236b":"sendEthValue(address,bytes,uint256)","d2e9953a":"setAdmin(address,address,bool)","d2ea7f7f":"CreditDAOfund(address)","d2eb6483":"EVMDB()","d2ecb4f9":"initialAllocation()","d2ed2d30":"setWorst(uint8)","d2eda057":"checkBool(bool[])","d2eeead7":"PatrickTestCoin()","d2ef0669":"denyAccess(address,address)","d2ef3b0d":"getCreateShareTokenMarketValue()","d2ef7398":"challenge()","d2efeef3":"TradableTokens()","d2f03bf6":"registerWithETH(address)","d2f0be99":"getRefund(uint256)","d2f1f189":"ICOAddress()","d2f1f712":"getVoters(uint128)","d2f27cf4":"setCelebrityPrice(uint256,uint256)","d2f28141":"calculateBonus(uint256,address)","d2f2d549":"CLPTestNetToken()","d2f32d94":"get_card()","d2f343c7":"timeWindow()","d2f3b963":"dateICOEnded()","d2f3ea43":"getPurchaseAmount(uint256)","d2f40cab":"getFunctioName()","d2f4a50a":"wallets()","d2f65fbc":"setMockBytes32(bytes4,bytes32)","d2f6f67d":"mintingContract()","d2f7265a":"exchange()","d2f7c5db":"GetDetail(address)","d2f7f377":"testRegisterNickWalletEth()","d2f80c15":"addDivisionJurisdiction(bytes32[],bool[])","d2f82026":"quickSortBids()","d2f8dd45":"Owned(address)","d2fa1f8b":"proxyPurchases(bytes32)","d2fa635e":"setMaxGasPrice(uint256)","d2fa9a67":"RESERVED_TOKENS_FOR_FURTHER_TECH_DEVELOPMENT()","d2fabaec":"VITToken()","d2faf216":"withdrawBuyer(address[2],uint256[7],uint8,bytes32[2])","d2fafb19":"setAmount(address,uint256)","d2fb32c2":"getGen0ObjInfo(uint64)","d2fb8787":"recordExists(bytes)","d2fbbc51":"ADVISORS_TOKENS_PERCENT()","d2fbd0ed":"payOrder(uint256,uint256)","d2ff5d4f":"allWETHbalances(address,address[])","d2ff8fd8":"ICOtokensSold()","d2ffca2d":"currentTotalExcess()","d2ffd541":"mintAdminCancel(address,address)","d30047bc":"firstPreSaleEndDate()","d3006dea":"ValueFinalized(bytes8)","d300746f":"pullTokensBack()","d300a034":"oraclize_query(string,bytes[])","d300a968":"isSecurityToken(address)","d3017193":"addUser(address,uint256)","d301c85f":"ownerAllocateTokensForList(address[],uint256[],uint256[])","d30272b8":"signAgency(uint256)","d302af4a":"isAirdropContract()","d302b0dc":"unFreeze(uint256)","d303b750":"Coupon(address,uint256,uint256)","d303e3b2":"checkMidiNoteValue(uint8)","d3050195":"_ownsRobot(address,uint256)","d305399d":"addToWhitelist(address,uint16,uint256)","d305577e":"GSSingle(uint256)","d305671a":"Dario(uint256,int256,uint256)","d3057859":"trade(uint8[2],bytes32[4],uint256[8],address[6])","d30592c6":"_trim(uint256[],uint256)","d3059c91":"maxTokensForCommand()","d305a45d":"requestDivident()","d3062b24":"getIndicesWithClaimableTokensForBuyers(address,address,address,uint256)","d3066879":"withdrawVestings(address)","d306967b":"TokenCreated(uint256,string,uint256,address)","d30792d4":"bonusesMapPos(bytes32)","d30796a2":"OwnerTransfer(address,address,uint256)","d307cd53":"_b4(string,uint256)","d3087ff5":"startOpenPpTime()","d3088b52":"transferWithMessageAndRequestAddress(address,uint256,address,bytes)","d3088b5f":"CesaireToken()","d30895e4":"player1()","d308cbe2":"withdrawMoneyByAdmin(uint256,address)","d30920c1":"contractTotalInvested()","d3098883":"memberFee()","d30a119b":"calculateBonusTokens(uint256)","d30a1325":"checkProposalExistence(string)","d30a512e":"betOnColumnOrDozen(bool,bool,bool)","d30a969a":"RemiCoin(uint256,string,string,uint8)","d30b5386":"payFee(bytes32,uint256,address)","d30bbde8":"checkWorkingInfra(uint256,uint256)","d30beffa":"unholdGold(address,uint256)","d30bf323":"setTaskRewardPaid(bytes32)","d30cad77":"nextRoundDuration()","d30e2004":"setRegionUrl(uint256,uint8[128])","d30e268b":"saleTokensPerUnit()","d30e9302":"distributionTokens()","d30f945a":"setNewManager(address)","d30fa946":"fulfillDeliverable(bytes32)","d30fbd0d":"safeSubtract(uint256,uint256)","d30fc8a1":"FundsAdded(uint256)","d3100538":"YOLOCASH()","d3109af3":"drainWei()","d310bc32":"releaseName(string)","d3111d3f":"_getLockedAmount(address,address)","d3115524":"_bptc(uint256,uint256,uint256,uint256,address)","d3118a5a":"addDoc(string,string)","d3119dc0":"minEtherForAccounts()","d311b44d":"everyBidFee()","d312846b":"uniqueContributors()","d313f235":"terminateTokenSale()","d3140a65":"createOpenLockAndDraw(address,address,uint256)","d3146a46":"Claim_TRAC_9600()","d316e912":"deleteGrantee(address)","d3183864":"calculateMultiplierAfterBurn(address,uint256)","d3195184":"_canNowTransfer()","d3195c82":"refundTransactionAfterDisputeFee(uint256)","d319ab75":"getProposalContractor(uint16,uint16)","d31a8be1":"setCentsPerEther(uint256)","d31af484":"updateTokenUri(uint256,string)","d31b3320":"getUserTokenInfo(address)","d31c153c":"AllocateAgentChanged(address,bool)","d31cfed6":"initialMonthWithdraw(uint256)","d31d7b0a":"MoonCatRescue()","d31efc7e":"createHero(string,uint16,uint16,uint16)","d31f0f38":"RamenCoin()","d31fdffd":"setHammer(address)","d31feea1":"OpenLongevity()","d31ff13c":"changeContractOwner(address,string)","d320ac9a":"DonationDeposited4Matching(address,uint256)","d321fe29":"getAmount()","d3220144":"newPriceDecreaseRate(uint256,uint256)","d3226425":"DuMangoCoin()","d324191c":"Codexstandard()","d3251aa2":"setHelpCoinAddress(address)","d3257034":"AgriChainCultivation()","d3258b9e":"DevDorothyCoin()","d325c2e8":"revertPurchase(address)","d3261592":"dripRate()","d32632fd":"migrationGate()","d327523a":"getTotalNumberOfBoards()","d329ce51":"developer_cycle(address,uint256)","d32a7ee0":"updateLand(uint256,uint256,uint256,uint256)","d32a9cd9":"settle(bytes32,bytes32)","d32ab21d":"voteFor(uint8,uint8,uint8)","d32aba42":"getPresaleBonusAmount(uint256)","d32b607c":"sumElements(uint32[])","d32b8575":"_startAuction(uint256)","d32c943a":"resolveChallenge(bytes32)","d32cb0fe":"exercise()","d32cbabb":"Ast()","d32e245b":"getContributorRemainingCap(uint256)","d32e29de":"setApproveFee(uint256)","d32e48c0":"LockOpen(address)","d32ef1e5":"RhodonToken(address)","d3309a7e":"productTribe(string)","d3313802":"EtheraffleDisbursal(address)","d331aeb3":"getAllFiatTransactionsCount()","d331b696":"computeNameFuzzyHashET(string)","d33219b4":"timelock()","d333d7cf":"destroyShares(address,uint256)","d333ec79":"changeServiceAccount(address)","d334d75b":"expireLoan()","d3363dd7":"icoThresholdBonus3()","d3364687":"PRESALE_START()","d33656e0":"primaryOperator()","d336ac80":"getPersonInfo(uint256)","d337616e":"resetLottery()","d337b9c9":"myWeapons()","d337ce86":"addProject(uint256,string,address,uint256,uint256)","d337e72e":"EtherToken2()","d3382a55":"whitelistRate()","d3392545":"spawnItem(uint256,uint256,address)","d33abd33":"t_2nd_StageEnd()","d33b79d9":"addBallotAndVoterNoPk(bytes32)","d33c0a4d":"getMyCells()","d33c449f":"gesamtGuthaben()","d33ca02b":"externalCall(address,uint256,uint256,bytes)","d33cf9fa":"MultiSigMint(address)","d33d1aac":"getWeeklyTokensForWebsitesAmount()","d33d5f3e":"CLOSE_TIME()","d33d6732":"totalSupplyMintTransfer()","d33d6f65":"Delivery(address,uint256,uint256,int256,int256,int256,int256,address)","d33e1a48":"genRNGContractAddress()","d33ecfee":"setResume()","d3400a1d":"etherRatioForOwner()","d34047b6":"mint(address,string,bytes32)","d340ab41":"addInvestorBonusInTokens(address,uint256)","d340dd8a":"getCCH_edit_13()","d340e8f8":"setDistributionPercentage(uint256,uint256,uint256)","d341281a":"ALH()","d3418fb7":"capOfTotalSupply()","d3419bf3":"prices()","d3419d4e":"TokenAiContribution(address,address,address,address,address,address,address)","d341e052":"JoyGameDemo(address,address)","d342275e":"setProgress(uint256)","d342c598":"Bou(address)","d342e4f4":"runInOneDay()","d3437bd3":"ProofOfStableClone()","d3437fe0":"assertFact(uint256,bytes)","d3446856":"tournamentPaused()","d344e01b":"stopTransferToken()","d3451379":"updatePower(uint256)","d3456121":"amountInContract()","d3462259":"howManyTokens(uint256,address)","d346feb8":"changeCertBot(address)","d3471035":"KarmaToken()","d347c205":"transferableTokens(address,uint64)","d347de03":"setPlayerGeneralCd(uint64,uint32)","d3481bd0":"buyBlock(uint256,uint256)","d3484c1c":"TOKEN_SUPPLY_MAINSALE_LIMIT()","d348b409":"calculatePrice()","d348ee9a":"correctResult(int16)","d349f8b4":"MobileGoToken()","d34a280a":"setPreAmounts(uint256,uint256)","d34a412c":"switchRankings(uint16,uint8,uint64,uint64,uint64,uint64,uint64,uint64)","d34acd12":"functionCalls(uint256)","d34b1537":"minFundingReached()","d34b1aef":"returnUnsoldSafeLarge()","d34b2451":"BurritoPurchased(uint256,address,uint256)","d34b6cd3":"BBDToken(uint256,uint256,uint256,uint256)","d34b7e25":"checkWin(uint256[])","d34bb772":"EndsAtChanged(uint256)","d34be5be":"startVotingPrepare(address)","d34cc179":"updateDaoContract(address,string)","d34d8e43":"oracleItQuery(string,string,uint256,uint256)","d34dd1f0":"safeWithdrawal(address,uint256)","d34e4b20":"getWinnerHistory(uint256)","d34ed095":"getSoilTempException(bytes32)","d35066e6":"rsrvToSale(uint256)","d3511f82":"getRoundBetNumber(uint256,uint256,uint256)","d3516b7e":"setVote(uint256,bool)","d3525adf":"setMetadata(bytes32,bytes32)","d35262ef":"getInt256Min()","d3528d9b":"createBetAcrossDeposit(bytes16,bytes16,bytes16,bytes16,uint256,uint256)","d352a862":"ownerOfTwitterId(uint256)","d3535452":"buyPosition(address)","d353a1cb":"finish(uint256)","d3554dd5":"NieShichaoToken()","d35590c2":"sponsors(address)","d355f139":"requestBatchLoans(uint256)","d3565934":"YANG()","d3568560":"calcDates(uint256,uint256)","d356a28b":"addSERAPHIM(address)","d356a879":"removeAddressByIndex(uint256)","d357aa15":"raise2ndAppeal()","d357f0ce":"_checkPixelLeft(uint256)","d357ff87":"sweepRoundsActive(bool)","d359b0c7":"XeniaToken()","d359be70":"distributeExternal(uint256)","d359f82c":"updateExpiry(uint256)","d35ada32":"addParticipant(address,address)","d35b9d83":"codeAt(address)","d35bcf88":"addCET4(uint32,uint64,uint64,uint64,uint16,uint16,uint8,uint8,uint8)","d35c7372":"theCeiling(uint256,uint256)","d35c9a07":"withdrawProfit(address,uint256)","d35cf913":"mint_tokens(address,uint256)","d35d031e":"SellerChanged(address,address)","d35d90ba":"MPKToken()","d35e29d7":"mint(address,uint32)","d35e48e6":"PLBToken()","d35e6537":"IONIATOKEN()","d35e656b":"userNameTaken(string)","d35f4a99":"mint(int256,address,uint256)","d35fbbfb":"range(uint256,uint256,uint256)","d3604bc9":"yesContract()","d3614854":"getAdministratorETH()","d3617e7a":"MyToken(address)","d361ab64":"sendFreeTokens(address,uint256)","d3626d09":"getyestoday()","d3631e00":"refundUnconfirmed()","d3637c27":"icoArray(uint256)","d3650fb8":"approvers(uint256)","d365a08e":"masterAddress()","d366f83b":"allSidesPledgedAmount()","d366fbab":"startLottery(bytes32,uint256,uint256,uint256,uint256,bool)","d3670cb4":"BitcoinBlackToken()","d3671166":"PurchaseSuccessful(address,uint256)","d367a398":"NVTAddr()","d3695161":"deleteUser(string)","d369a744":"CCtestToken(address)","d36a1fa8":"ALKACOIN()","d36a35c9":"strikersBaseContract()","d36a8026":"Phoenix()","d36ae26b":"commBallotPriceWei()","d36afad5":"hasKey(address)","d36b96a9":"controllerFailed()","d36b9e64":"contributorsPeriodsElapsed()","d36bed21":"getGameAddressById(uint256)","d36bf8a1":"increaseWithdrawalChunk()","d36d9b19":"request_callback(uint8)","d36dbc0c":"addWineryOperation(string,string,string,uint256,uint16,string)","d36e0f39":"EIP20Token()","d36e9ac3":"burnUnused()","d36e9b2a":"RentalAgreement()","d36ef2cc":"PolicyPalNetworkCrowdsale(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d36f0e9c":"etherForCharity()","d36f5c87":"stitch(int256,int256,bool)","d36f69eb":"getEthInCents()","d3701ff2":"TongToken()","d3707129":"_removeShareFromLastOwner(address,uint256,uint256)","d3708487":"setInfoAboveSpot(uint256)","d37194f5":"getTotalDepositsAmountLeft()","d371d551":"addAddressToCappedAddresses(address)","d372e3a0":"isCrydrViewAddress(address)","d3732642":"FastRealisticPyramid()","d373507b":"setAllowSell(bool)","d37360a0":"efw()","d3749a15":"user_contract()","d375b921":"orderUsable(address[8],uint256[6])","d3775371":"has_reading()","d377bc5f":"lockedMoney(bytes16)","d377dedd":"currentNiceGuy()","d378f4e0":"NOOR()","d37990ce":"setGenerationSeasonController(uint256)","d379be23":"claimer()","d37a9bb0":"restrictTransfers()","d37aff82":"changeStatus(uint8,bytes32)","d37b34d7":"blacklistAccount(address)","d37b8a96":"deploy(string,string,uint8,string,address)","d37cd1d9":"TalentCoin(address,uint256,string,uint256,string,uint256)","d37d753f":"spin(address,uint256)","d37fe6cb":"balanceOfWithoutUpdate(address)","d3807fa5":"NameChange(string)","d380e036":"marketDefaultFeeLow()","d3811c0f":"setMetadataBase(string)","d38159b8":"testPass()","d38185d3":"_buyXid(uint256,uint256,bytes32)","d381ba7c":"setRootUser(address,bool)","d381c67e":"isRentAuction()","d383f646":"issue()","d384077d":"_closeProvider(address)","d384af87":"checkpopa()","d384d177":"haveCommonPrefixUntilZero(bytes32,bytes32)","d385293d":"confirmTokenTransferToBooking(bytes32,string,bytes32,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d38537cf":"TimerAuction(string,uint256)","d385fac9":"bwin()","d38609f9":"unhaltFX()","d386130c":"Encrypt(uint256)","d38685ee":"unlockGlobalToken()","d3872d57":"getLandRevenue(uint256)","d387978d":"cancelled(address,bytes32)","d387c4c1":"getOwnedTokens(address,address)","d3884c3f":"removeService(bytes32)","d38875ec":"addDeal(uint256,uint256,string,string,uint256,string,bytes32)","d388e416":"getAccountReferalsStats(address)","d3890a43":"DaoCasinoToken(uint256,uint256,uint256,address)","d3895c91":"changeConversionRate(uint256)","d38ac5ac":"WayBackToken()","d38bd9f0":"newTokenOwner()","d38bee56":"PlaceSell(address,address,uint256,uint256,uint256)","d38c3253":"ownerSelfDestruct()","d38c4cca":"removeFromTokenTransferDisallowedAddresses(address)","d38cba4b":"paymentRewardTokensPriority(uint256,uint256)","d38d0f28":"updateSplit(uint256)","d38e5ab7":"TransferDisable()","d38eb9d3":"escrowFrom(address,uint256)","d38f3b68":"getMedications()","d38fe43f":"setMembershipContract(address)","d390021d":"getLastTimeUpdated()","d390e819":"disableDonationContract()","d391014b":"ROLE_ADMIN()","d391a970":"removeFromOwnedTokens(address,uint256)","d391ce7a":"CrowdsaleContract()","d3927c15":"reimburse()","d392c5a2":"getNumOptionChains()","d3933154":"MYL(uint256,string,string)","d393c871":"register(string,address,uint256)","d393cde5":"wholeLineWrong()","d393f628":"changeDemurringFeeOwner(address)","d3943976":"getSGCUsers(address)","d3943ab4":"setIntArr(uint256,uint256)","d3943c83":"numberOfWithdrawls()","d3946ea4":"manuallyEndAuction()","d394a12e":"secondPresaleStart()","d39502bb":"AIBITTECH()","d3953822":"getThisAddress()","d395ee0f":"setQuickBuyPath(address[])","d3964ca1":"operationsEthWallet()","d397e9e4":"getDisputeCrowdsourcer()","d397f861":"TRAC_Tokens_left()","d3980d87":"ReferenceToken(string,string,uint256,address[],address)","d398806d":"updateMinJump(uint256)","d399354b":"KYC_USD_LMT()","d39aa15c":"_getTransferFeeAmount(address,address,uint256)","d39b0cbb":"Start10()","d39b1d48":"setDistributeAmount(uint256)","d39b7e4f":"setBPAddress(address)","d39bbf06":"MAX_INVESTOR()","d39c7880":"setAddressOfERC20Token(address)","d39c9afd":"OwnerKill()","d39cb111":"getShortId(bytes32)","d39cce1c":"calculateSaleReturn(uint256,uint256,uint16,uint256)","d39ce83a":"paymentMixed(uint256,uint256,uint256)","d39cee11":"benchTransfer(address[],uint256[])","d39d8fce":"presaleStart_6_December()","d39de6e9":"getAuthorizedAddresses()","d39e4607":"LogIcoCompleted()","d39eb301":"getStatus(uint8,uint8)","d39ebe2c":"setup(uint8,uint8)","d39ec1fe":"currentTethers(address,uint256)","d39f4149":"fxpMul(uint256,uint256,uint256)","d39f532d":"SafeGift(uint256,string,string)","d3a057c8":"isConfigured()","d3a05872":"AutoFareCalculator()","d3a0d0ab":"RTokenBase(uint256,string,string,uint8,bool)","d3a2d050":"addData(uint256[])","d3a3086e":"ActorCoin()","d3a39686":"getAddress(bytes32,bytes32)","d3a516d3":"viewSuperOwner()","d3a56ec3":"processRequest(uint256,uint256,uint256)","d3a5768b":"RoundWinner(address,uint256)","d3a57b9f":"showRdWonNum(uint256)","d3a5dcb0":"EQUITRADER()","d3a60bd5":"Exchange(address,uint256,uint256,uint256,address,address)","d3a61150":"setDatabaseDownloadUrl(string)","d3a699cd":"PePaDe()","d3a6be66":"donotXXXDappToken()","d3a6c234":"benWallet()","d3a70dba":"getReaderId(bytes32)","d3a73d12":"modifyLevelCaps(uint256[])","d3a85394":"currentPeriodTokenCollected()","d3a86386":"minimumBid()","d3a871e9":"REELToken()","d3a9187e":"mintTemplate(uint256,int256,uint256,uint256,uint256,string)","d3a99388":"JcashUpgradeableToken(address)","d3aa22c7":"transferTLA(string,address)","d3aa831f":"testOwnedTryAuth()","d3aceae2":"_balance(address)","d3ae2814":"LogTokensFrozen(bool)","d3aefeeb":"pauseUnpauseICO()","d3af4dc7":"processRequest(uint256,uint256)","d3b0d9eb":"refundFunds(address)","d3b15dd6":"Millet()","d3b19ee1":"dislike_trackable(address)","d3b234fc":"getAttoTokensToBeFounder()","d3b246d0":"upgradeEvilMorty()","d3b25696":"tradeIntentOf()","d3b302e7":"applyForMembership(string)","d3b3809c":"EscrowGoods(address,uint256,uint256,uint256,uint16,uint256)","d3b3eccb":"isARTDistributed()","d3b4be21":"Obtener_Reputacion(address)","d3b5305c":"setAgriChainDistribution(address)","d3b5695c":"setOraclizeCallbackGasLimit(uint256)","d3b58024":"RepeatCustomerToken()","d3b5c016":"submitSolution(uint256,string)","d3b5dc3b":"precision()","d3b6486a":"setLeastFund(uint256)","d3b6664a":"purchaseTrophy(uint256)","d3b6ac97":"defenceElementBySubtypeIndex(uint256)","d3b6fbc2":"MOVIECREDITS()","d3b7576c":"update(uint256,bytes32)","d3b7bcf1":"preAllocation()","d3b7bfb4":"fundingAddress()","d3b7ef5e":"SCE(uint256,string,string)","d3ba95ce":"throwsWhenFinalizingIfNotMultisig()","d3bac6e3":"coordinatorAccountCount()","d3bbb2c8":"b13ToBytes(bytes13)","d3bc89b7":"GetGuestTokenNo()","d3bc9aca":"addCourse(uint256,string,uint256,uint256,string,string)","d3bca884":"addBalance(address,address,uint256)","d3bced2c":"withdrawBotFee(uint256)","d3bd5a4b":"resetUserPromoBonus(address)","d3bd6e23":"newUpdater(address,address)","d3bd7713":"setCapAtDuration(uint256)","d3bdbd8f":"editMilestone(uint256,uint256,uint256,uint256,uint256,string)","d3bdd242":"isMovingEnable()","d3bf0ce6":"AAP()","d3bfe76a":"revokeApproval(address,address)","d3c0715b":"vote(uint256,bool,string)","d3c13c25":"GCOXAPLToken(string,string,uint8,uint256)","d3c18378":"getPlayersBalance(address)","d3c1c838":"batchTransfer(address[])","d3c33c52":"ipc()","d3c4055d":"VITE()","d3c41dae":"FindCourseBaseOnIdStudent(uint256)","d3c564ad":"tokenZLT()","d3c567c1":"cancelVoteForCandidateByStage(address,uint256,uint256)","d3c5ea45":"ICO_PHASE3_PERIOD()","d3c62676":"MiamiToken()","d3c65384":"ContributedAmount()","d3c65737":"sumICOStage4USD()","d3c683e5":"LOG_FailedDraw(address,uint256)","d3c6a6d6":"getWitnessCount()","d3c764f2":"buyPixelBlock(uint256,uint256,uint256,bytes32)","d3c78097":"startDistribuion()","d3c7adf9":"JimatCoin()","d3c7c2c7":"getSupportedTokens()","d3c7ca2f":"Allinone()","d3c8dd69":"Parent()","d3c8e99e":"_shareDiscountPrice(uint256,address)","d3c9ad17":"REBALANCE()","d3c9cc26":"getTokens(uint256)","d3caee1b":"currencyToToken(address,bytes16,uint256,bytes)","d3cc8d1c":"claimTokensFromSeveralAuctionsAsBuyer(address[],address[],uint256[],address)","d3cce1d2":"setOldContractData(address)","d3cd6052":"getProposalCount(bytes32)","d3cdb97b":"partIndexToOwner(uint256)","d3cde1a5":"updateReferral(address,uint256)","d3cde1c0":"getIndexAndCheckIfAllowedToPublish(uint256,uint256)","d3cdf6c5":"calculateTokenAmount(uint256,uint8)","d3ce71df":"buyCozy(uint256,uint256,bool,address)","d3ce77fe":"destroyTokens(address,uint256)","d3cea787":"setContractServerBlackWhiteListType(string,uint256)","d3cecc4d":"checkVestingCondition(address)","d3cedfee":"sspCount()","d3d10d87":"OwnerChanged(bytes32,address)","d3d18836":"publicLock(address,uint256)","d3d19965":"deleteCroupier(address)","d3d2172e":"total_reward()","d3d37a31":"setSaleCap(uint256)","d3d3b01c":"ToRent(uint256,uint256,uint256,address)","d3d3d412":"getGateAddress(address)","d3d43efa":"returnLoanStatus(uint256)","d3d44e8b":"getBlockCount(uint256,uint256,bytes32)","d3d54129":"setPCAddress(address)","d3d55493":"calculateRefundAmount(uint256,uint256)","d3d6a975":"testThrowsTransferNotEnabled()","d3d70c3c":"setPrivelegedWallet(address)","d3d77f98":"setCoeff(uint8,uint128,uint8,bytes32,bytes32)","d3d864f5":"isFundingOpen()","d3d8aa55":"IG()","d3d8acf8":"checkMyVestingPeriod()","d3d9e741":"SuperCoin()","d3da927f":"isRegistered(address,address)","d3daa8aa":"EtheremonPayment(address,address,address,address,address)","d3db2371":"DHCSToken()","d3dbc861":"Initiate()","d3dc9794":"pendingTxs()","d3dcc175":"devTeam()","d3dccb03":"ERC20Token(string,string,uint8,uint256,address,uint256,address[],uint256[])","d3dcd55a":"calcTokensFromEth(uint256)","d3dd9a18":"addManyAuthorizeToWhitelist(address[])","d3ddebce":"STATE_BET_DISABLED()","d3de5834":"disableFeesForUser(address,uint256)","d3deedfd":"MANHATTANPROXY2NDST()","d3df2d01":"maxUsdFundingReached()","d3e00f4b":"stampBirth(uint256,address)","d3e0996a":"checkProductGenuine(address,address,uint256)","d3e141e0":"left5(uint256)","d3e15747":"setLock(uint256)","d3e212c5":"bidExchange(uint256,uint256)","d3e242c2":"_confirmTransaction(uint256,address)","d3e2846a":"LINKFund()","d3e3623b":"earlyBackersAmountLeft()","d3e65414":"contributedToken(address)","d3e65b6c":"buyTicketByOther(uint256,bytes32,bytes32,bytes32)","d3e66a9e":"startCompetition()","d3e6dda7":"removeFound(address)","d3e6f49f":"isReadyToBreed(uint256)","d3e73312":"allocatedFounders()","d3e7d44d":"tokensBurnedTotal()","d3e82be8":"getMinPrivateSaleBuy()","d3e837cb":"setChecksOn(bool)","d3e848f1":"systemAddress()","d3e89483":"policies(uint256)","d3e8b207":"distributeWithLockup(address,uint256,uint256,uint256)","d3e91a98":"destroyAllTokens(address)","d3ea3322":"testBuildTokenSystemCost()","d3eb11d6":"payoutsWallet()","d3eb667e":"BigBoobsToken()","d3eb6f61":"isGoalReached()","d3ebd2dc":"transferFron(address,address,uint256)","d3ebf454":"LotteryRoundDraw(address,bytes4)","d3ecb95f":"wc()","d3ed0ea2":"setAuthor(uint256,string)","d3edcb0a":"_wholeToken(address)","d3edcb5b":"getCreditorAddresses()","d3ee86e7":"mmax(uint128,uint128)","d3eee5ad":"lockForDays(uint256,uint256)","d3efa856":"CreditBIT()","d3efbd7f":"freezeContract(bool,uint256,uint8[],bytes32[],bytes32[])","d3f01fbd":"calcToken()","d3f045d2":"Player(address,uint32,uint32,uint32,uint32,uint256,uint256)","d3f06def":"uploadFile(uint256,uint256,bytes32,bytes32[],bytes32[],uint256)","d3f16925":"setDevLimit(uint256)","d3f189bd":"COMMUNITY_ADDRESS()","d3f1a78c":"updateDelayTime(uint256)","d3f1fbd7":"updateLastMiningTime(uint256)","d3f233af":"burnOf(address,uint256)","d3f297d6":"claimLiquidityReward()","d3f2b996":"PTH(uint256,string,uint8,string)","d3f2e7cf":"runningRound()","d3f3bea2":"distributionRealized()","d3f40a02":"denyAccess(uint256,uint256)","d3f4fcd9":"claimInitialAllotment(string,string)","d3f60667":"trackBuyBack(uint256,uint256)","d3f60d9c":"startTimeRound2()","d3f6a157":"setWallets(address,address)","d3f6be9f":"LogDeposit(address)","d3f6c328":"AMOCoin(address)","d3f6dc52":"oracleItQuery(string,string,string)","d3f71ecc":"checkIsOnSale(uint256)","d3f73bd4":"getOwnerCEO()","d3f8868b":"getFrequency(uint256)","d3f8cc95":"exhaustAfterFusion(uint256,uint256,uint256)","d3f92288":"WhiteList()","d3f9ba69":"processOneCombat(uint32,uint32)","d3f9fc33":"ownerRecoverTokens(address,uint256)","d3faaeca":"softCapInTokens()","d3fbf39d":"mintNFTNotForSale(uint256,string)","d3fc310a":"_addExtraReceiver(address)","d3fc9864":"mint(address,uint256,string)","d3fd311e":"trading_deactivated()","d3fd9eba":"transferAuction(address,address,uint256)","d3fe1ae1":"updateMember(address,uint256,uint256,uint256)","d3ff09a5":"setTotalTaskEscrow(uint256)","d40027ec":"lockoutPeriod()","d401defe":"getBasicInfo(address)","d40224ec":"triggerSale(bool)","d402be57":"calcMode()","d402f87c":"setTotalProfit(address,uint256)","d4030114":"tableSize()","d40394be":"batchAddWhitelistedTransfer(address[])","d404d6c2":"pushEther()","d404ea23":"hashKey()","d405a069":"grantInitialAllocations()","d405d6f4":"Chally()","d40619b8":"getUsersScannersIds()","d4065763":"returnRemainingMoney()","d406e403":"test_startBlock()","d407d212":"claimJ()","d408746a":"GetContractAddr()","d4088e33":"setPrice(uint256,uint256,uint64)","d4092dd2":"getPOOL_edit_29()","d409a12c":"Kcoin()","d409ddda":"EtherizationUtils()","d40a71fb":"step1()","d40b9d9a":"OwnerHeartbeated(address)","d40c0a58":"saveTeamSpent(address,uint256)","d40c3084":"fundValues()","d40d4d76":"etherToSendBankRoll()","d40dc870":"MAX_AMOUNT()","d40e35da":"Interest_Rate()","d40e985d":"decompose(uint256)","d40e9b9c":"rakeEventPlaceholderAddress()","d40fa8bf":"ZRX()","d40fd402":"salarySent()","d41097e3":"disbandTo(address)","d4112c56":"changeUtilityAccount(address)","d41212c8":"_insertTokenMetadata(uint256,string)","d41376e1":"withdrawl(address,address,bytes32)","d4138673":"IkuraTransferToken(address,address,uint256)","d413bd66":"OfflineMultiSig(address,address,address[],uint256)","d414da2a":"addPatternUserIndex(address,bytes32)","d41584ab":"LogCertifierRemoved(address)","d416c997":"_stringsEqual(string)","d416d1a6":"lastInvestorPaidOut(uint256)","d416d4f3":"Balance(address,address)","d416efdb":"donationTo(address)","d417f18d":"getTopicNameAndVotesAt(uint256)","d4186ba4":"test_oneValidEqInt3()","d41977cd":"contractFee()","d419ef9f":"WinToken(address)","d41b6853":"enter(address,uint256,uint8,uint8,uint8,uint32[11])","d41bcb81":"phaseEndTime(uint256)","d41bdea7":"unlock(bytes32,bytes32,bytes32)","d41be98d":"createDebtToken(string,string,uint256,uint256,uint256,uint256,uint256,uint256,address)","d41c85fa":"__redeem()","d41cc314":"EventUpgradeTank(address,uint32,uint8)","d41e3281":"DocumentManager()","d4200f94":"setCreditBitContract(address)","d4203561":"transferFee(uint256)","d420e4e0":"BCaaS()","d420e527":"BuyLimitsCrowdsale(uint256,uint256)","d4212e93":"storeInitialClaim(address,uint16[],uint256,bool)","d4214d1b":"releaseUnclaimedBounty(address)","d42151b0":"FFCTToken()","d4229b1a":"appBase(bytes32)","d422cf58":"numLocks()","d422e4e0":"takeFee(address,uint256,string)","d422e810":"exchange_commission_wallet()","d423740b":"setter(uint256)","d423754b":"removeFactProviderFromWhitelist(address,address)","d4245e5b":"transferringETH(address)","d424f628":"fundingGoalReached()","d4269986":"getPuzzle(uint8)","d426b04e":"largeContribThreshold()","d426bb47":"allocateForPrivateSale(uint256)","d42706bd":"Batix()","d4270d60":"recall()","d427ccbf":"getEventAddress()","d427ce74":"getBylawsProjectDevelopmentStart()","d428bf3b":"SetdivForPrice(uint256)","d4291e0c":"num_hosts()","d429bfae":"currentTokenOffered()","d42a5011":"setPackLimit(uint16)","d42a9dd5":"ICO_PHASE1_PERIOD()","d42aa2f6":"getHealth(uint8[176],uint8)","d42ad6ea":"getMinAuditPriceMin()","d42b31b9":"_DeclineInsurance()","d42bd8a4":"receivedUETreturn(address,uint256)","d42bf301":"doTriggerTryAuth()","d42c334e":"DepositMasterContract(address)","d42cc0d1":"Planetagro_Exchange(address)","d42cda15":"getOnMintTargetValue(int256)","d42cfc41":"transferFeeDenominator()","d42d24fc":"auditContract()","d42d4c10":"PASSToken()","d42d8eed":"tag(address,uint256)","d42db190":"versionAddresses(bytes32,bytes32,address)","d42dca55":"getAuditors(uint256)","d42e26f5":"initializePresaleFundraiser(uint256,uint256,uint256,uint256)","d42e87ed":"callOnSignUp()","d42ed758":"MixManager()","d42eeb4f":"EtherDrugs()","d4300225":"publicGetBalance(address)","d430381b":"mayorCutPercentage()","d4313945":"setProviderInvitedUser(uint256,address,bool)","d431b1ac":"setPause()","d431ba8e":"lastBlock_v8()","d432a885":"withdrawedFoundationCounter()","d4331c21":"setSubTourFreezingTime(uint64)","d4332f50":"changeBPaddress(address)","d4335bd2":"getSevenCount()","d433ea6a":"CueCrypto()","d4346010":"verifiedTransferFrom(address,address,uint256,uint256,uint256,uint256)","d43503ab":"Sunset()","d4357107":"address_to_tokens_prev_week1(address)","d43582c8":"removeNOSPackage(uint256)","d4365b4b":"Weaver()","d436b6e2":"EtherAdvance()","d4371968":"MAX_IMMORTALS()","d4384156":"UbexToken(uint256)","d438fdbd":"offlineSales(uint256,uint256)","d439390c":"MIN_PURCHASE()","d43948ee":"transferGainedEther()","d439ef55":"distributionMinimum()","d43a0b4c":"hodlerTotalValue9M()","d43a7c16":"finalizePrivateIco()","d43c3bb9":"getData_30()","d43c45b8":"withdrawSurprisePot(address)","d43c5a4a":"setTeamVault(address,address,uint64)","d43ea9e1":"levelTwoTokenNum()","d43ef6b9":"__mulmod(bytes,bytes,bytes)","d43f24b0":"removeApprovedContractAddress(address)","d4403495":"OWN_mintToken(uint256)","d440c6f3":"getWorkerAffectation(address)","d441ea62":"CleanBankerProfit(uint8)","d4430bc7":"tokenSaleOngoing()","d443173d":"requestUnFreezeAccount(address,string)","d4434387":"PolyCompliance()","d443f64a":"Start_Resume_PreICO()","d443fc85":"acceptGuardianVend(uint256)","d4440991":"callTransfer(address,uint256)","d44512e3":"changePrestige(address)","d445afdc":"week1Price()","d445cc78":"unfreezeTransfer()","d44750f5":"bonus_price()","d448273c":"mineForMany(address[],bytes32[])","d4483263":"secondRoundMayStart()","d4492c57":"addInvestorGrant(address,uint256,uint256,uint256)","d449844d":"XbitfwdToken()","d449a832":"decimals(address)","d449ce7c":"Administered()","d44a2863":"changeBooking(string,uint256[],uint256,address,bytes32)","d44aadf7":"initROS()","d44aecb0":"ico1_startdate()","d44b01ec":"safeWithdrawERC721(address,uint256,address,address)","d44bc088":"getTaskId(uint256)","d44cf3dc":"_setPriceFactor(uint256,uint256)","d44d3394":"WIDTH()","d44dbbaf":"addStringComparison(bytes32,bytes32,bytes1)","d44dd681":"beginLiquidation()","d44f2d3d":"getInitialWithdrawalDone()","d45036c7":"viewTeamTokens()","d4508698":"driveCar()","d4524c72":"manualEtherWithdraw()","d45294f5":"charityAmtToCharity()","d45318b9":"scoringDuration()","d4538051":"_emitHolderAddressAdded(bytes32,address,uint256)","d454f92e":"mNumVoters()","d4550efd":"addEngineerQuest(address)","d455b973":"changeStageBlock()","d4565916":"activateproduct(uint256)","d45769b8":"N2Contract()","d4582b56":"Token(string,uint8,string)","d4589835":"sellMorties()","d458c522":"participantCapTier1()","d459197b":"distributeALCTokenBatch(uint256)","d4595aaa":"blockExpiration()","d459654a":"techSupport()","d45973f4":"turretElementBySubtypeIndex(uint256)","d4597aa1":"tokenFrozenUntilTime()","d45a717e":"topGoodsId()","d45b1ae4":"StandardGasPriceLimit(uint256)","d45b5f71":"getIcoStep(uint256)","d45baeab":"Deposit(uint8)","d45bcac1":"listAddresses(address[],uint256[],uint256[])","d45c1b06":"Bank(string)","d45c241c":"minBonus()","d45c4435":"getTimestamp(bytes32)","d45e09c1":"canTransfer(address,uint256)","d45efad5":"getAccessControl(address,address,uint8)","d4607048":"buyForEverybody()","d461518c":"p_setGameDuration(uint256)","d4616967":"deployCode(bytes)","d4620041":"getFirstRoundReleaseTime()","d4625a3a":"equals()","d4629ae7":"ddftFund()","d46300fd":"getA()","d4631019":"_startCounter()","d4638401":"oneImpInWei()","d4638fea":"operatorRedeemByTranche(bytes32,address,uint256,bytes,bytes)","d463ca18":"findSsp(address)","d463eeb3":"numLoans()","d464520c":"PowX()","d4649fde":"expire(uint256,uint8,bytes32,bytes32,bytes32)","d4653a3b":"EXToken()","d465abca":"notInArray(address)","d466a03f":"citizensAmounts(uint256)","d466a046":"LogBidExpired(bytes32)","d466ab6b":"ROLE_BOUNCER()","d467cc00":"calculateRate(uint256,uint256)","d467cc64":"DoubleOrNothingImpl()","d4683f6d":"ArticCoin(uint256,string,string)","d4686534":"LYNIA()","d46a005a":"addWhiteListUser(address,uint256,uint256)","d46a5d7e":"vote(uint256,bool,uint256)","d46aa610":"buyInMarket(uint256)","d46b2987":"Luvtoken()","d46b9b84":"lifeN(uint256)","d46ba0c9":"etherRaisedPerWallet(address)","d46c0f40":"finishPrivatePlacement()","d46cddd4":"capPresale()","d46d0393":"getNextRegionId()","d46d0a22":"setV_S(uint256)","d46d79bb":"withdrawAllEth(address)","d46dbca1":"developerTemplateAmountLimit()","d46dd5bb":"showCurrentWinner()","d46ea4a4":"EXP_18()","d46eb119":"wrap()","d46f8eb1":"getSource(string,string,string,string)","d46ff2f1":"getTweetsDiff(uint256)","d470097c":"lastLargestHODLER()","d4701c35":"activate_kill_switch(string)","d4702576":"calculateTokens(uint256,uint256,uint256)","d4724a57":"TokenTransferForFounder(address,uint256,address,address)","d472d6bf":"get_token_balance(address)","d472fa26":"lockTokenToDate(address,uint256,uint256)","d472fe7e":"totalTokensICO1()","d4735d92":"Transfer(bytes32,address)","d4737d11":"setSampleRegistry(address)","d47380e0":"_mintToken(address,uint256,uint256,string)","d4740b78":"getAmountWeekly(uint32)","d4747f0a":"IQC()","d474a352":"submitBlockHeader(bytes,uint256)","d47510c0":"UNICORN_ID()","d475526f":"numActiveGames()","d475b1ab":"phase5Price()","d475bfa8":"proxyClaimTokens(address,address)","d47637f7":"getLittafiContent(bytes32,uint256)","d476620b":"winnerKey()","d476758f":"extractablePercentage()","d4768994":"soldIdeaWeiPostIco()","d477e3d4":"checkAddERC20(address)","d477f05f":"setDev(address)","d47875d0":"getScore(address)","d4788cc3":"HGT_Reserve()","d478f533":"allowFreezing(address)","d4793a9b":"getNextGuessId()","d4798327":"getPendingBattleRewardsCount(address)","d47a2010":"bnbRaised()","d47b44c3":"Fool()","d47bb75c":"TOKENERC20(uint256,string,string)","d47c0fb0":"onIncome()","d47c9e11":"eastadsCREDITS()","d47cc085":"sameNum()","d47cc9d7":"start_the_race()","d47cf598":"setDayThird()","d47d3202":"releaseINATokenToTeam()","d47d5cfe":"swarmTree()","d47d996e":"addCrowdSale(uint256)","d47dbde2":"buyerFundRelease(uint256,address)","d47e813d":"SteveCoin()","d47e81eb":"blockSettlement(uint64,uint64)","d47eb8ee":"validCall(uint256,bytes)","d47eca0a":"checkDiv()","d47ee6c1":"numberOfLeaderboardPlayers()","d47f269e":"getHand(uint256)","d4807fb2":"initializeRound()","d4810b61":"PRE_ICO_START()","d48210bc":"perValue()","d4821432":"endICOStage8()","d4849a8b":"newEthBackedLoan(uint32)","d484a285":"PRE_ICO_SLGN_LESS()","d48599e3":"setdrawadm(address)","d4859dbc":"UniversalFunctionSecure(uint8,bytes32,bytes32,bytes32,bytes32,bytes32)","d4859dc5":"disableManager(address)","d48675f3":"minGoal()","d4867694":"updateship(uint256,uint256)","d48684d8":"changeLimit(uint256,uint256)","d4868c32":"tokenReserved3Deposit()","d486d129":"releaseVesting(address)","d4871517":"BTCLotto(address,uint256)","d487758a":"forgive(uint16,uint32)","d4878cac":"_transferChild(address,address,uint256)","d487b21a":"assets_controller()","d4884b56":"getEventEnd()","d4897729":"getCET4InfoById(uint32)","d489a018":"adminAddWorldBalance()","d489b701":"starEthRate()","d489b83f":"teamOneShares()","d489c0bf":"getBuyCount(address)","d489e180":"getPendingPartCrateLength()","d489fc8b":"_useOraclize()","d48a1f6e":"returnPurchasedEther()","d48a9340":"SaveCryptoToken()","d48b2e92":"Identify()","d48b55e5":"calculateTokenOnlySellPrice(uint256)","d48b7a9d":"CryptoMyWord()","d48bb321":"next(bytes2,bytes2,bytes2,bytes2,bytes2,bytes2,bytes4,uint256)","d48bfca7":"addToken(address)","d48c4193":"addWhitelistedTransfer(address,address)","d48d02f6":"withinLimits(uint256)","d48e638a":"getCreator(uint256)","d48e6a1b":"TEAM_TOKENS_PERCENT()","d48e9cd5":"OMG()","d48ea599":"getBeneficiaryByTime(address,uint256)","d48f08e5":"disableRegulator(address)","d48f7196":"numHodlers()","d48fb85c":"FIVE_YEAR_KEEPING()","d48fe280":"OK()","d4912ab1":"SNTPlaceHolderMock(address,address,address,address)","d491461a":"Gnosis()","d492283f":"switchLock(bool)","d4923d4e":"getUserVote(address)","d493b9ac":"transferAnyERC20Token(address,address,uint256)","d494c388":"setMinBuyAmount(uint256)","d49620ec":"RoundFinalized(uint256)","d49636c2":"san()","d496a4f1":"cashBackVotes()","d496bde4":"mainSaleTime()","d496f9d2":"PlayReferred(uint8,uint8,uint8,uint8,address)","d4971613":"HashBounty()","d49758d6":"use_bounty_token(address,uint256)","d4975d71":"changeVoter(address,address,string)","d4981928":"WorkOrder(uint256,address,address,address,address,uint256,string,address,address)","d499555b":"getFirstActiveDuel()","d49982cc":"sendPreSaleBonusMany(address[])","d499b2c3":"pks(uint256)","d49ab244":"ICOWhitelisted(address)","d49ad161":"addTokenDetails(uint256,address[],uint256[],uint256[],uint256[])","d49c51b7":"claimedMK(address)","d49ce78d":"WiggaToken()","d49d1836":"openegg(uint256,uint256)","d49d1bac":"transferERC223(uint256,address,address,uint256,bytes)","d49d5181":"MAX()","d49dbb5c":"minBalanceToSell()","d49dd9a8":"getStateofContract()","d49dd9e4":"SonnetCoin()","d49edbd8":"lastPrizeGiven()","d4a03f60":"acceptAdoptionRequest(bytes5)","d4a04ff4":"importFromOld(address,address,address,address,address[],uint256[])","d4a226c3":"bountyManagerDistributionContract()","d4a2498d":"addData(string)","d4a24f06":"checkPermissions()","d4a28823":"EOSSale(uint256,uint128,uint256,uint256,uint128,string)","d4a2f3ca":"getShipAuctionEntity(uint32)","d4a34564":"start3BonusPeriod3()","d4a34a9e":"tokenDecimalsLeft()","d4a3e9d7":"capture()","d4a436cc":"_countBits(uint256)","d4a4513e":"fpct_packet_size()","d4a61d61":"OnlineCasinoCoin()","d4a631ab":"ContractLogEvent(int256,int256,uint256,string,string)","d4a67930":"openBuy()","d4a6fd3e":"has_presale_started()","d4a8d9ba":"Inbox(string)","d4a9991f":"requestDividends()","d4a99d61":"finishDelivery()","d4aa6b59":"Button(uint64,uint64,uint64,uint64,uint64,address)","d4aa7394":"GameStatusUpdate(bool)","d4aa7d38":"City(uint256,string,string)","d4aae0c4":"kernel()","d4ab4a89":"_migrateRobot(string)","d4ac6af5":"MAX_REFERRAL_TOKENS()","d4acaf6c":"ecrecoverFromSig(bytes32,bytes)","d4acfa01":"tokenFrozenSinceBlock()","d4ad678e":"addItem(bytes16,uint16,uint16,bool)","d4ae1061":"getPurseDetails(uint256)","d4afc8b6":"retrieveERC(address)","d4b03d34":"changeValueBonus(uint8,uint256,uint256)","d4b088f9":"ICO_PHASE2_AMOUNT()","d4b0a23b":"addWhitelists(address[],uint256[])","d4b0c6e5":"stringToBytes10(string)","d4b0e966":"changeSaleStart(uint256,uint256)","d4b15ee0":"LogRefund(address,uint256,uint256)","d4b175d4":"mineTokens(address,uint256)","d4b182d4":"block(address,bytes32)","d4b1a462":"LogBought(uint256)","d4b1cdcc":"isResolverFor(uint256,address)","d4b1d19f":"testThrowsTransferDisabled()","d4b2931c":"tokenSEEDcap()","d4b2d5f0":"SQR_TOKEN()","d4b3f5b6":"tokenWithdraw(address,uint256,uint256)","d4b572be":"RESERVE_TOKENS_SUPPLY()","d4b64f35":"getBalanceOfModifiedWeth()","d4b71aa9":"maxPresaleWei()","d4b795c0":"getCurrentRoundEntry()","d4b83992":"target()","d4b8a6f1":"setFeeSchedule(uint256,uint256,uint256,uint256)","d4b9e410":"coiner()","d4ba15ad":"earlyPariticipantWeiPrice()","d4ba769c":"getLatestComponent(string)","d4badfad":"totumAllocation()","d4bb02e4":"changeRatePreSale(uint256)","d4bb1f28":"FCOIN1346Token(uint256,string,string,uint256)","d4bc0942":"withdrawOracleFunds()","d4bc87d9":"currentPriceChangeNumber()","d4bcffe4":"AbxyjoyCoin()","d4bd5a0d":"addCollaborator(uint256,address)","d4bdb879":"tokenSaleHasFinished()","d4bdc45f":"downvote(uint256,int256)","d4bde313":"ownBalance()","d4bdfe00":"ETCTransfer(address,address,uint256)","d4be5f68":"ATL_PER_ATP()","d4be6356":"authentication(bytes8)","d4be7714":"bornFamedStar(uint256)","d4bffa5a":"STATE_INITIAL_BIDDING()","d4c0cbce":"NovaCoinTransfer(address,uint256)","d4c1089b":"WorldRecord(string,bytes32,address)","d4c24db7":"StarterTokenSale()","d4c2b6b1":"scheduleTransaction(address,bytes,uint256[5],uint256)","d4c30ceb":"getFeeBalance()","d4c3eea0":"totalValue()","d4c46fa6":"setDeploymentPriceYear(uint256)","d4c49094":"WithrawDevToken()","d4c50f00":"coinPerEth()","d4c55f56":"wkaToken()","d4c6d9ad":"getbetresult(bytes32)","d4c72e7f":"etherollBeneficiary()","d4c76e8b":"MaxToken()","d4c80edf":"amountWagered()","d4c8fdae":"saleEtherRaised()","d4c9b1f2":"setMainAddress(address,address)","d4ca68ea":"replacePolicyTo(address,uint8)","d4cab39b":"AddedPrecommitment(address,uint256)","d4cae6e2":"getMetadataURL(bytes,uint256)","d4caf2a4":"setCodeSize(uint256)","d4cd5509":"CulturalCoinCrowdsale(uint256,uint256,uint32,uint32,address,address,address,uint256,uint256,uint256,uint256,uint256)","d4cdeb3c":"isInPresale()","d4ce1415":"detectTransferRestriction(address,address,uint256)","d4ce545a":"random(bytes32)","d4cf02ef":"getStringToSignWithKey(string,int256)","d4d0aced":"transferPartOfUnsoldTokens(address,uint256)","d4d0d6e6":"addTrusted(address)","d4d0e931":"resetAllVotes()","d4d1b7da":"approveTokensFromAnyWithSignature(address,address,address,uint256,uint256,uint256,uint256,bytes)","d4d227de":"PBToken()","d4d2af8d":"sellCoin(uint16)","d4d2e23c":"LogRandom(uint64)","d4d30bd9":"GreenX(address,address,address)","d4d33ece":"isRebirthAllowed(uint256,uint256)","d4d37883":"sendSurplusTokens()","d4d42658":"getTokenRateEther()","d4d42c91":"SetupML(uint256,uint256,uint256,uint256)","d4d5d32a":"collectFee()","d4d64f2b":"getRevokeHash(bytes,uint256)","d4d6adc0":"SiliconXCoin()","d4d6cdc4":"getStageTotal()","d4d6d366":"metadataUrlSuffix()","d4d6f5ee":"deleteChannel(address,address,address)","d4d70128":"totalContributions(uint256)","d4d728fe":"IsClaimed(bytes32)","d4d7b19a":"isHolder(address)","d4d81a13":"ClownCore()","d4d82dae":"MCFitCrowdsale(uint256,uint256,uint256,address)","d4d84da5":"addTokenShop(address,uint256)","d4d90bd5":"MINIMUM_PURCHASE_AMOUNT_IN_WEI()","d4d91bdd":"_createOpinion(string,address,uint256)","d4d92b14":"mintInternal(address,uint256)","d4d96ac5":"flag(string)","d4d9748d":"NeoToken()","d4d9bdcd":"approveHash(bytes32)","d4d9f559":"addWhiteListAddSetAuctionObj(address,uint256,uint256)","d4db3791":"processTransferResult(address,address,uint256,bool)","d4dc8e83":"walletCreateSnap(uint256,uint256)","d4dca69b":"thisAddress()","d4dcbc60":"declineApproval(uint256)","d4dd1594":"updateLandData(int256,int256,string)","d4dd26fb":"initKYCUser(uint256)","d4dd5d99":"LiteXTokenVesting(address,uint256,uint256,uint256,uint256,bool)","d4dd707f":"upgrade_node(address,address,string)","d4dd92a9":"TeamAllocation()","d4def0ba":"escrowedTokens()","d4df0c6d":"setSaleAuctionAddress(address,address)","d4df1be8":"getETHNeedPay(uint256,uint256)","d4df6152":"getInvestorByIndex(uint256,uint256)","d4df89e2":"messageBoard1(string)","d4dfadbf":"getMarket(address)","d4dfc4b9":"MinimalManuscript(bytes32,string)","d4e12f2e":"approve(address,int256)","d4e17e6d":"closeBuy(bool)","d4e19bd1":"HART_NETWORK_ID()","d4e30489":"NewYorkCoin()","d4e32938":"subuser(address,uint256)","d4e4716f":"_setWhitelistedUser(address)","d4e4841d":"tokenToEthTransferOutput(uint256,uint256,uint256,address)","d4e678b8":"refundTransaction(uint256)","d4e75363":"NextDistribution(uint256)","d4e77133":"SendCoin(uint32,uint32,uint32,address)","d4e78272":"Draw()","d4e7b9cf":"amountAvailableToCashout()","d4e823a3":"createVendingItem(uint256,uint256,uint256,uint256,uint256)","d4e8b749":"periodITO_weiPerToken()","d4e8e063":"startGrantAuthentication(address)","d4e90e24":"CCTC()","d4e93292":"withdrawal()","d4ea7b08":"_emitPublicCapabilityRemoved(address,bytes4)","d4eaa9fd":"approveAndCall(uint256,bytes)","d4eb139d":"migrateSet()","d4eb21ff":"PonderAirdropToken()","d4eb4186":"setB0xAddresses(address,address,address,address)","d4eb4540":"BLOCKTIMEOUT()","d4eb487e":"getProtectHourglass(bytes32,uint8)","d4eba667":"updateNovaContractAddress(address)","d4ebc5ff":"voteUp(uint256)","d4ed0b46":"setCRaddress(address)","d4ed2cf5":"candidateTillExchange()","d4ed8990":"updatePoolAddressCapTier1(uint256)","d4ee025f":"resetRequest()","d4ee1d90":"newOwner()","d4ee4041":"removeBlock(address)","d4ee9415":"addPurchased(uint256,uint256)","d4ee9fba":"existPublicKey(bytes32,address)","d4eec5a6":"optOut()","d4efcfe4":"getAccountInformation(uint256)","d4f04289":"ownerSellArmy(uint256,uint256)","d4f06298":"UpdatedMainAccount(address)","d4f0ca3f":"onlyTestSetTimestamp(uint256)","d4f0ebe6":"getWeaponNb(uint8[176],uint8)","d4f114a6":"numOfBoundaries()","d4f11ab2":"updateCompanyWallet(address)","d4f2e67c":"ico(address,uint256)","d4f2f1da":"EthereumNano()","d4f397b5":"getLootClaimed(uint256,address)","d4f3d6b8":"updateEditionType(uint256,uint256)","d4f3dd84":"_generation()","d4f50f98":"getVoter(address)","d4f639ea":"run2()","d4f6aa98":"getLargePaymentBonus(uint256)","d4f7329e":"minttoken(uint256)","d4f74bf4":"curatorAccount()","d4f77b1c":"joinGame()","d4f96a09":"giveawayAddr()","d4fa83c3":"setWhitelistTx(address)","d4fa9021":"DeductABS(uint256,uint256)","d4fac45d":"getBalance(address,address)","d4fb0bc1":"payOut(uint256,uint256)","d4fb0d23":"totalGuess()","d4fb9a01":"tradingStatus()","d4fbe1e0":"devAllocation(address,uint256)","d4fbeb19":"registerToken(address,string)","d4fc5822":"userWeiSpent(address)","d4fdbcff":"ViewDividendPoolEnds()","d4fef717":"APC(uint256,string,string)","d4ff60cb":"URB()","d4ff88d5":"TokenSent(address,uint256)","d4ffd1bd":"updateStrategy(uint256,string,string,string,address[],uint256[],bytes32)","d5002f2e":"getTotalShares()","d50030ad":"getMyDividends()","d5005c35":"COINVR()","d5009584":"getManager()","d500ca00":"assignReward(address,uint256)","d500dd6a":"challengeTimeout(uint256,bool,address)","d500f861":"buyFromWallet(uint256,bytes32)","d501953d":"poolTokenAmount()","d5020ce8":"daysMinutesTilExpiryTime()","d5025625":"terms()","d502db97":"getAddr(string)","d5034f2f":"changeRegistrationStatuses(address[],uint256[])","d503d33f":"MyPoolBalance()","d503e948":"developer_edit_text_minimum_period(string)","d503ef95":"getCategoryEvaluation(address,uint256,uint256,address)","d50495f4":"addTransaction(bytes)","d504cb65":"currentBet()","d504ea1d":"getArray()","d5050493":"tokenOf(address,address)","d505c1cf":"currJackpotBetID()","d506355c":"getRentInfo()","d5064037":"BitcoinVision()","d5065090":"setVendingStartPrice(uint256,uint256)","d5072607":"auditTimeout()","d5089396":"Token(string,string,uint8,uint256)","d509b16c":"testWithdraw()","d509b1f9":"like(address,address,uint256,string,address)","d50a04f4":"dataPerUsd()","d50a3d2c":"privateSale(address,uint256)","d50b3065":"addTokenBalance(address,uint256)","d50b65d7":"startBlockjack()","d50b7123":"testLockTokensForTrading()","d50bb794":"getComponent(uint256,uint256,uint256,uint256)","d50cb88b":"priceMultiplier()","d50d4822":"revokeParticipation(address)","d50e38c6":"IbkToken()","d50e829e":"setStopped(bool)","d50f6bf0":"transferETH(address)","d50f6d3a":"getPartner(address)","d50f7c73":"lastBlock_v10()","d5102704":"testRenameStore()","d51033db":"getTuple()","d5119402":"PUBLIC_SALES_3_PERIOD_END()","d511beec":"WithdrawICOEarnings()","d511cc49":"DAILY_PURCHASE_LIMIT()","d511f6c0":"startBuyingTokens(bool,uint256,uint256)","d5144eca":"updateUserBio(string,string)","d515b1ce":"Team(address)","d515be39":"getTokenName(address,uint256)","d5167b26":"partialTrade(uint256)","d5170fcc":"BonusFinalizeAgent(uint256,address)","d5171523":"euroteambet()","d517bc6f":"calcPointShamir(uint256,uint256,uint256,uint256)","d5182b70":"blocked(uint256)","d5185115":"forwardTokens(address,address,uint256)","d51902cf":"fallbackAccount()","d5193235":"mintUserAdoptionTokens()","d519bdcb":"distributeSML(address[],uint256)","d519fdc5":"alterGiveKarmaFee(uint256)","d51abbd9":"updateMaxTxGas(uint256)","d51c2454":"stepOne(int256)","d51c86e7":"setData_12(string)","d51d4fa8":"Securities_3()","d51e1737":"creedex(address,address,address,uint256,uint256,uint256)","d51eda9a":"AMC()","d51f5abd":"BEXMToken(uint256,string,string)","d52230c4":"totalContributionsBySender(address)","d5235a04":"contractEnable()","d5246eba":"queryRandom()","d5250364":"checkWrapperBalance()","d52550a4":"TokenPool(address,address,address)","d525aa32":"conditionalTransitions()","d5260eea":"getChannelAddress(string)","d526b9bd":"_allow()","d526c08e":"uv()","d526c40c":"_denyPublishSecret()","d526d332":"getLogic(uint256)","d526eaeb":"getMaximumReadsPerStep()","d5280c28":"AuthorizedCreate(address,uint256)","d529a072":"buyAddress(address,bytes8,uint256)","d529debb":"subOnHold(uint256)","d52a3524":"addAction(bytes32,bytes32,string,uint256,bool,uint256,uint256)","d52a5fc4":"decomission()","d52a7cbf":"setWallet1(address)","d52a7e86":"totalRewardedAxies(bool)","d52b38cd":"updateVendorApplicationStatus(string,string,string,string,string,string)","d52b5cb4":"_addLegitRace(address)","d52b79bd":"XTT()","d52b8a0e":"addVineyardEndorsement(string,uint256,bool,string,string)","d52b9e40":"activateTokenSwitch()","d52c6c08":"approCertificate(uint256)","d52e4633":"futureRoundTokensRelease()","d52f7122":"myCredit()","d52f916f":"setAddressCrowdsale(address,address)","d530040a":"createAddressHash(address,bytes32)","d5307b0c":"weiContributed(address)","d53087b2":"JANUS()","d531eeaa":"icoBonus1()","d5320300":"getWithdrawableAmountANPES(address)","d532968f":"_chkSellerLmts(address,uint256)","d532df3c":"setCraftAuctionAddress(address)","d532e481":"activateFrozenAccount(address)","d533d0db":"changeUserLangAbility(bytes32)","d534831c":"sumOfWeights()","d5349606":"removeDeadTurns(uint16)","d535268d":"BUZZ()","d5353792":"setWithdrawGasCost(uint8)","d5356b7d":"TOKENS_PER_USD()","d5356fe1":"tokenFallback(address,address,uint256)","d53590a7":"durationPreSale()","d5364231":"forcedRedeem(address,uint256)","d536c3ae":"beginPhaseTwo(uint256)","d5370904":"getAvailableTokenCount()","d5375a5c":"getHigherInstance()","d537c3e3":"blockLockActive()","d537df3c":"claimTwitterIdIfNeededThenStealCardWithTwitterId(uint256,address,uint8,bytes32,bytes32,uint256)","d537e131":"calculateMatchPrice_(address[14],uint256[18],uint8[8],bytes,bytes,bytes,bytes,bytes,bytes)","d538359e":"Copeland()","d5387acb":"buy4(address[],address[],uint256[],bytes,bytes,bytes,bytes)","d539a014":"SSDTokenSwap()","d539a226":"assertEq10(bytes10,bytes10,bytes32)","d53a9b85":"tokensPerCents()","d53aaec2":"cPT()","d53abe1b":"stopRound(bool)","d53b2679":"activated_()","d53b4ab4":"communityAllocation()","d53b932a":"percentLeft()","d53bb6ac":"EthBita()","d53bc605":"testMultitransfer1()","d53beee4":"isOk(bytes1)","d53c61bf":"slasherAddress()","d53ca3c7":"setDiscountMember(address,address,string,bool)","d53ce956":"setOperationAddress(address)","d53dbe8e":"publishier()","d53e963b":"buyCore(uint256,uint256)","d53f1cbd":"getBidFee(uint256)","d53f8208":"fundaria()","d541ca5d":"BONUS_PCT_IN_ICONIQ_SALE()","d5420df4":"drawToHand(uint256,uint32,uint256)","d5425571":"gasonBuffPercentage()","d543f9d6":"setTeamPerfitAddress(address)","d544361e":"increaseShares(uint256,address)","d544e010":"removeAuthority(address)","d5456bc6":"lastBlock_a14Hash_uint256()","d545782e":"updateTokenRate(address,uint256,uint256)","d545ee2d":"CustomToken(string,string)","d54604ae":"min_fundingGoal()","d54656d5":"startTrade(address,address,uint256,uint256,uint256)","d546c975":"getCharacterServer(uint256)","d5472a5e":"userRewardAccountBalance(address,address)","d5472fcb":"removeWhiteLister(address,address)","d5477d37":"getColdWalletAddress()","d54839bf":"FEE_DEV()","d54a6bfb":"setHmcAddress(address)","d54ac04d":"get_master(bytes32)","d54ad2a1":"totalClaimed()","d54ad593":"getgamecardintro(uint256)","d54b02ec":"weiToCollectByInvestor(address)","d54b066f":"calcAmount(uint256)","d54c03a9":"NOORToken()","d54c2a63":"improveCard(uint256,uint256,uint256)","d54c4726":"usageCost()","d54c7099":"TVContract()","d54c7b4f":"_triggerCooldown(uint256)","d54c8c87":"emitApprove(address,address,bytes32,uint256)","d54ced9c":"canContributeAmount(address,uint256)","d54cefc1":"transferTokens(address,address[],uint256[])","d54dc5eb":"REGISTRATION_COST()","d54dd8f9":"slice4(bytes,uint256)","d54e583a":"transferFrom(address,address,uint256[],uint256[])","d54f4dd6":"TestVeryCoin3()","d550172a":"verifySig(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address,bytes,address,address)","d5503d5f":"payBalance()","d550668d":"setContract(bytes32,uint256,address,address)","d550f044":"setAllowLocalBuy(bool)","d55108be":"JOLDEAME()","d5518feb":"RequestCollectInterface(address)","d551f601":"_auth_mode()","d552844b":"signTrueloveByCOO(bytes32,string,string)","d55321db":"newGame(address,string,string,uint256,uint256,uint8,uint8,uint8,uint256)","d5537c0d":"setUsersCap(uint256)","d553adf0":"frozenFunds(address)","d5544f94":"getFundsAndAvailable(address)","d5547587":"ReviewToken(uint256,string,uint8,string,address)","d554ba86":"round_b_begin_date()","d554f8b4":"changeDeDeStorageAddress(address)","d5551518":"CapitalMiningToken(string,uint8,string,string,uint256,uint256,uint256,uint256,uint256,uint256)","d5556544":"offset()","d5562901":"getFeeSchedule()","d5563f31":"createAuction(uint256)","d556c8f5":"getHashID(address,bytes32)","d5572bd6":"closeCrowd()","d5582205":"getCertifiedStudentAtIndex(uint256)","d5582965":"stopMint()","d55a772d":"getCurrentOwner(string)","d55ac94c":"WhiteBullsToken()","d55b7703":"privateIcoCap()","d55b9f4d":"DISCOUNT_PRIVATE_PRESALE()","d55bc06a":"LDEX()","d55bdc5f":"getCampaignPriceById(bytes32)","d55c4af8":"_p3dSellPercentage(uint256)","d55c980f":"submitEntry(bytes,string)","d55c9c84":"confirmWinner()","d55cc3e2":"JSONpath_raw(string,string)","d55d1fed":"EGGS_TO_HATCH_1Dragon()","d55e62a0":"removeTrusted(address)","d55e725b":"initialFunds()","d55ec654":"wash_list(uint128)","d55ec697":"upgrade()","d55edcfd":"freezeChangesToVesting(address)","d55fe582":"isAssociated(address)","d560f696":"releaseRoto(address,bytes32)","d561be54":"createVestingContractWithConstantPercent(address,uint256,uint256,address,uint256)","d561ef2b":"setMinBuyableAmount(uint256)","d562a121":"calcTokens(uint256)","d562de0b":"investor_insert(address,uint256)","d562deef":"getAffiliateFee()","d5630f71":"AlpenCash()","d5635444":"getCoupon(string)","d5656ccf":"getWager()","d5666b5f":"versionBase(bytes32,bytes32,address)","d5667d8a":"updateUSDWEI(uint256)","d5668a92":"_checkTransactions(address)","d5670f59":"VisualChainToken()","d567c0e1":"cashBackWeight(address)","d5687efd":"WhitelistSetDay(address,uint8,uint256)","d5698726":"LogSetPicosPerEther(uint256)","d56a0a88":"bipedaljoe()","d56a4555":"setLink(uint256[2])","d56a62cf":"getPurchases(address,uint256)","d56a9314":"transfer_m(address,uint256,string)","d56b2889":"finish()","d56b7577":"BM_ICO()","d56b7746":"mintTokenCollection(string)","d56bd142":"getPayments()","d56cd796":"addNewCourse(int128,string,string,string,string)","d56d229d":"nftContract()","d56de6ed":"adminAllowance()","d56e3068":"getTotalDonated()","d56ea1b0":"pausePending()","d56efabf":"LockableToken()","d56f279f":"resignOwnMembership()","d5708d5a":"setMinAmount(address,uint256)","d571829e":"mintTokensToEralyInvestors()","d571a9a9":"Hawaii()","d571dbac":"getHeadInfo()","d571e645":"validStoreBuff()","d571edb0":"getExchangeGroupsLength()","d572056e":"testItem(bytes)","d5722518":"setUintsOwnerCount(address,address,uint256,bool)","d5723bf7":"finishGame(uint256,uint256)","d572fd99":"getPlayerCardsNumber()","d574bcdf":"reLoadXname(uint256,bytes32)","d575af74":"getSubscriptionServiceId(bytes32)","d575f332":"updateCampaign(address)","d5762230":"overStakeAgeBurn()","d5767fb6":"_emitCapabilityAdded(address,bytes4,uint8)","d576dc58":"TOKEN_SALE_LIMIT()","d5775f5c":"getCurrentSellPrice()","d5778d37":"preIcoTokens()","d5778efa":"STASHToken()","d5778f07":"transferAdvocatedTAOLogos(address,address,address)","d5779b7f":"imageUploadComplete(address[16],uint256)","d577ab70":"authorizeEscrowService(address)","d577d785":"setJPYC(address)","d57869d4":"findTrustedContract(address,address)","d578ec6c":"uploadData(bytes32[100])","d578f434":"BONUS_PCT_IN_VREO_SALE_PHASE_2()","d579f9e8":"changeBinary(uint256)","d579fd44":"approveNextOwner(address)","d57a0577":"TEAM_BONUS_PER_CENT()","d57a12f5":"testCheckSigs()","d57a9e4f":"LATER_AUCTIONS_INITIAL_PERCENTAGE()","d57ad588":"hashToSign_(bytes32)","d57b8932":"leaseBlock(uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32)","d57bde79":"highestBid()","d57c00de":"PayForServiceETH()","d57c1ea2":"addIssue(uint256)","d57c25f8":"UnderratedToken()","d57f62ff":"getPeriodLockedBalanceFor(uint256,address)","d5812ae1":"positionPrice()","d5813323":"traded(bytes32)","d583644b":"upgradeStrength(uint256)","d5838ca7":"addPublicKey(address)","d5847d33":"conversionRatesContract()","d585b852":"DAOToken()","d586bd4e":"donateP3D()","d586d2e4":"cancelRequest(uint256,uint256)","d586e30f":"calcNextReward()","d587dbf9":"change_specific_addy(address,uint256)","d588acc4":"claimMiningReward()","d588b892":"testCount(uint256)","d588d4d8":"hasHash(bytes10,uint8)","d5893bb2":"tradeEventEnabled()","d58b8282":"roundFiveTime()","d58b82bb":"getCampaignDailyPrice(address)","d58bf09a":"redeem(bytes32,address,bool[4])","d58c4b85":"siteAccount()","d58d1566":"subsidyHalvingInterval()","d58e1758":"totalConvertLotsByAddress(address)","d59070f8":"mintCopieExecutoire(bytes32)","d5909149":"CerberusNetwork()","d590bf49":"deleteCase(uint256)","d590df4a":"setFirstPeriodCap(uint256)","d591221f":"testTransfer()","d59138ef":"markReleased()","d59167f6":"claimComputation(bytes,bytes32)","d591d777":"finanVestingStages()","d592c243":"Issuance(address,uint256,uint256,uint256)","d592f5fd":"reserveFullMintAllowance()","d593c953":"revenueShareIdentifierList(address)","d5949bf3":"RegistroBlockchain()","d595c331":"burnSupply(uint256)","d5969f2b":"grantEnable()","d596c862":"toggleRedeemActive()","d59768a3":"updateAddress()","d597b634":"ETC()","d597b8c8":"getOffer(bytes32)","d597c6bb":"_generateSpaceship(uint16,address)","d598aef8":"TESTToken()","d598b2c5":"getTopCompanyStartBlock()","d598cae5":"ACTIVE_LOAN_CANCELED_BY_LENDER_STATUS()","d598d2ab":"Reward(address,address,uint256,string,uint256)","d598d4c9":"service()","d5992ef5":"isSuited(uint8,uint8)","d5996502":"TheMLMDemo()","d59aec08":"notesOf(address)","d59b5d4e":"getDocumentIdWithContentHash(string)","d59ba0df":"setDistributor(address,bool)","d59cf17f":"WeAPOWH()","d59e31ed":"totalETHSold()","d59e6461":"addRoot(bytes32)","d59f1844":"content_intro()","d59f1f3f":"proposalsByShareholder(address,uint256)","d59f2827":"isTokenOwner(uint256,address)","d59f37e0":"verifyCanRemoveOrderById(uint32)","d59f4e68":"setPaintingArtist(uint256,string)","d59f5c6e":"OmegaNode()","d59f9cc7":"getFullAddressList()","d59fde06":"CredoIco(address,uint256,uint256)","d5a056d8":"AddOrigin(address)","d5a18e4c":"setMany(address,uint256,uint256[],uint256[])","d5a2040e":"AKM()","d5a31956":"commissionArt(uint256,uint256)","d5a34dfb":"VPC0x()","d5a3b734":"dataSourceAddress()","d5a41695":"fetchVoteNumForCandidateBySnapshotBlock(address,uint256)","d5a4726b":"sumICO2()","d5a4a3c6":"findRecentBet(address)","d5a506d0":"regionExists(uint16)","d5a53dec":"ACTION_SELL_OFFER_ACCEPTED()","d5a5825d":"currentEtherBalance()","d5a632b5":"addPartnerSaleWallet(address)","d5a683c0":"addDividends(uint256)","d5a6c97a":"setWhitelistModerator(address,uint8)","d5a73fdd":"getVestedAmount(address)","d5a7b500":"softCapTriggered()","d5a81428":"sellPriceInWei()","d5a841f9":"setFaucetThresholdSecs(uint256)","d5a8487f":"getSquareWins(uint256,uint256)","d5a849e9":"getRewardBalance(address)","d5a8c0d9":"Ghcwchain(uint256,string,string)","d5a9f356":"testTemp3()","d5aa1a26":"getRouteSize()","d5aa1aca":"setmmVaultAddr(address)","d5aa7803":"isGuessesOpen()","d5aaadd1":"finishMintingRequestSetup()","d5ab7f30":"crowdsaleSuccessful()","d5abaa27":"JoinTheFray(address)","d5abeb01":"maxSupply()","d5acdeb2":"allocateCorporateToken(address,uint256)","d5aceaac":"closeBattleboard(uint16)","d5ad2e00":"m_wcStored()","d5ad3ad0":"setServiceController(address)","d5ae1085":"updateNextOrderPrice(address,address,uint256,uint256)","d5af8f24":"createAndSellAllAmountBuyEth(address,address,address,uint256,address,uint256)","d5afd6bc":"startOperation()","d5b014f8":"MoonTrail()","d5b01c99":"existIdAtCurrentVersion(bytes32)","d5b0c0d5":"numberOf(bytes16)","d5b1402c":"ViralTokenSale()","d5b235d0":"test_claimShares_emptyRewardPool_isTranscoder()","d5b2a01a":"ownerFee()","d5b2c102":"sendCoin(bytes32,bytes32,uint256)","d5b36845":"stage3Bonus()","d5b36eeb":"TEHToken()","d5b3b317":"minutestotal()","d5b40406":"signUpForAirdrops()","d5b42496":"enableShowValue(bool)","d5b4ea20":"USDcRaised()","d5b5dc49":"companyReserve()","d5b61da0":"PRE_SALE_MIN_ETHER()","d5b74699":"library1function()","d5b85b2d":"setBAAU(bytes32,address,address,uint256)","d5b89bc8":"Issuance(address,uint256,uint256)","d5b8a884":"ASStokenICO(address)","d5b9df87":"LEADER_FEE()","d5ba4d21":"changeHold(address,uint256,uint8,uint256,bool)","d5ba5f82":"getBattleCard(address)","d5bab53d":"xtestTransferToken()","d5bb7f67":"updateFeatures(uint256)","d5bc0a07":"LYBTToken(uint256,string,uint8,string)","d5bcecab":"setLeagueRosterAndSaleAndTeamContractAddress(address,address,address)","d5bcf8ef":"setGameRunning(bool)","d5bd3443":"newOption(address,uint256,bool)","d5bd57a1":"getCardsDetails()","d5bde837":"registerPoA(string,bytes32,uint64[],uint64[],address,address,string,bytes2)","d5be4153":"buyAd(uint256)","d5bec84e":"weiPixelPrice()","d5bee9f5":"randomAddress()","d5bf158a":"affiliateName(address)","d5bf2dbe":"setFeeParameters(uint256,uint256,uint256,uint256)","d5bf4da1":"eTicket()","d5bf5fc3":"sendBountySupplyToken(address)","d5c06d30":"icoEnabled()","d5c14391":"getAvailableAmount(uint256)","d5c166d5":"getExchgComisnMulByThousand()","d5c21c4f":"setMinAuditPrice(address,uint256)","d5c2d2b6":"TEAM_INCENTIVES_AMOUNT()","d5c2e3ca":"destroyContract(string)","d5c2ee21":"hasLanguage(address,uint256,uint256)","d5c34755":"LogAuthCreate(address,uint256)","d5c4098d":"enableRenounceOwnership()","d5c44898":"updateLastPrice(uint256)","d5c469f8":"isP2SH(bytes,uint256,uint256)","d5c53c44":"DETEX()","d5c5d8e1":"yetAnotherFunction()","d5c60c97":"ShowInfoBool(bool)","d5c61301":"say(string)","d5c61881":"enableWithdrawl()","d5c655c9":"lastTaskIndex()","d5c7aece":"CertAdminDeleted(address)","d5c7bcc8":"coinIssuedEtc()","d5c80423":"lockDeposit(bytes32,string)","d5c813dc":"sellerfee()","d5c96b36":"gettotalCardValue()","d5c9712f":"getBytesLE(bytes,uint256,uint256)","d5c98db1":"setPropertyOwner(uint16,address)","d5c999f8":"getBanque()","d5c9b239":"getAllShops()","d5c9c144":"SetGasFeeReimbursed(uint256)","d5ca35bc":"withdraw(address,uint256,uint256,address,uint8,bytes32,bytes32)","d5cb4a04":"getParticipantTransactions(address,address)","d5cc1d49":"upload(bytes32,bytes32,bytes32,bytes32)","d5cc8813":"startingPriceOf()","d5cce45a":"showbuyPrice()","d5cd3243":"addUser(bytes32,bytes32,uint256)","d5cdd2c7":"tokenToPoint(uint256,address,uint256)","d5ce3389":"from()","d5ce44c1":"totalEthReceivedinWei()","d5ce6719":"AC(uint256,string,string,address)","d5ce6a34":"LogAddressTokenCapCalculated(uint256,uint256,string)","d5ce91fd":"isRegistered(address,bool)","d5ceecea":"ERC777DemoToken(string,string,uint256,uint256)","d5cef133":"requestRefund()","d5cf5c72":"setSoftCap(uint256)","d5cfa94e":"claimAdmin(string)","d5cfad68":"getUserCertificationDetails(string)","d5cfc01b":"lockAddressByKYC(address,address)","d5cfee3e":"playerIsRegistered(address)","d5d067b0":"createRequestAsPayerAction(address[],int256[],address,uint256[],uint256[],string)","d5d09021":"isCrowdsaleFull()","d5d0da83":"KingsToken(uint256)","d5d1b95a":"convertRegularToRewardTokens(address,uint256)","d5d1e770":"confirmOwnership()","d5d21e18":"createTokenContract()","d5d2f528":"setTokenCounts(uint256,uint256)","d5d434c9":"SocialXBounty()","d5d4dfad":"balanceHistoryLength(address)","d5d55931":"ETXCrowdsale()","d5d55c8a":"PurchaseConfirmed()","d5d5913c":"getCCH_edit_2()","d5d5cefa":"cancelOptionOrder(address[3],uint256[3],uint256[2],bool)","d5d5f469":"getDocumentIdWithIPFSdirectoryHash(string)","d5d66031":"Wp()","d5d75cad":"_changeWallet(address)","d5d8a751":"Gallery_MuYi_No3()","d5da9e82":"teamLockTransferFrom(address,address,uint256)","d5db3fe2":"LogTrade(address,address,uint256,uint256,uint8,uint8,uint256,int256,uint256,int256)","d5db72eb":"isRegistrar(address)","d5db9366":"cancelCollateralTransfer(uint256)","d5db9410":"ChangeProtectionTime(uint256,uint128)","d5dbb1ad":"solveBet(address,uint8,bool,uint8,bytes32,bytes32)","d5dbe634":"incrementTotalSupply(uint256)","d5dc7139":"Scratch()","d5dcc638":"StrongHands()","d5dcf127":"setAge(uint256)","d5dd5127":"managerNotSetInApp()","d5de30e0":"evMgmtInvestProject(address,uint256,address,uint256,bool)","d5de78bc":"getGrantBalanceOf(address)","d5df7559":"removeDocument(uint256)","d5df7bcc":"newFootballMatch(uint256)","d5e05c89":"isSpaceshipUpgradeAllowed(bytes5,uint16,uint8)","d5e0b616":"getAnyElementByIndex(uint256)","d5e0d8fc":"setCompositionPrice(uint256,uint256)","d5e0e131":"totalAdvisorsSupply()","d5e38f60":"lpFeeBp()","d5e3fbb2":"payfee()","d5e45a83":"positionFrom(address,address,uint256)","d5e4a36e":"isPreSaleRunning()","d5e4b342":"trexdevshopWaited1Years()","d5e5e6e6":"preciseUnit()","d5e83d9c":"RisikoCoin()","d5e99dac":"rateLoss()","d5e9abfd":"mustKyc(address)","d5e9eb9c":"IPM()","d5ea36f9":"offMaintenance()","d5eb0cbf":"isContractPermanent(string)","d5ec40af":"buyToken(uint32,uint32,address)","d5ec7e1d":"left22(uint256)","d5ec8d82":"_estIntegerSqrt(uint64,uint64,int256)","d5ecc1bd":"papu()","d5ed289d":"getClaimRate(uint256)","d5ed9cba":"setLandRegistry(address)","d5edca54":"Games(uint256,uint256)","d5ee739d":"tokenRateWei()","d5f0400e":"validClaim(bytes32,string,string,address,bytes32,bytes32,uint8)","d5f07396":"checkIfReferee(address)","d5f12812":"setSpend(address,uint256)","d5f17df2":"selectFight2DeathContract()","d5f1e8d8":"hardCapEther()","d5f24708":"gotake()","d5f37f95":"sign(uint256,uint256,address)","d5f39488":"deployer()","d5f404c7":"update_power()","d5f47a51":"Ethraffle_v3b()","d5f48e76":"cancelSynthesizingAuction(uint256)","d5f4f0b3":"addTokens()","d5f52d51":"withDrawMyBalance()","d5f5b788":"maxCapUSD()","d5f5df2a":"checkFiscal(bytes32)","d5f6b538":"getClaimsCountForStory(bytes12)","d5f72b2e":"addMany(address,uint256,uint256[],uint256[])","d5f7b144":"_burnToken(address,uint256)","d5f827e2":"TBrate()","d5f868b7":"removeReverseRate(address)","d5f87242":"assertInvalidState()","d5f9ac43":"transferFromTangibleAssetfund(address,uint256)","d5f9bdf1":"TokenCreated(address,address)","d5f9e6c7":"ProjectName()","d5fa2b00":"setAddr(bytes32,address)","d5fa2da5":"newEscrow(uint256)","d5fb1a1c":"ByteLockerShares()","d5fbe080":"_getEnd(int256)","d5fcc7b6":"setPresale(address)","d5fd5351":"WithdrawAddressApproved(address,address,bool)","d5fdb334":"getOpenGameIds()","d5fdfdbc":"setResult(string,string,string)","d5fe6062":"claimTusdProxyOwnership()","d5fec406":"abdicate(uint64,address)","d5ff0e7b":"transferToContract(address,address,uint256,bytes)","d5ff38ae":"migrateBasicData(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d5ff56f8":"allowChange()","d600630c":"registerInstitution(string,address,address)","d6006e88":"send(address[],uint256[],uint256)","d6006e8e":"preSaleSuccess(address,uint256,uint256,uint256)","d600c846":"JingzhiContract()","d60207c7":"getLowestUnitPriceIdxFromBuy()","d6026ac1":"getPRewardedSumByRound(uint256,address)","d6030d57":"BOUNTY_CAMPAIGN_SHARE()","d6039a41":"totalsigs()","d603f872":"buyPreICO()","d603fd28":"sendToAddressWithTime(address,uint256,uint256)","d6046836":"setAllowBuy(bool)","d604d6a8":"getSkillRating(address,uint256,uint256,uint256,uint256)","d604d8d1":"checkHash(bytes32)","d605787b":"rng()","d6063225":"Ktx(uint256,string,uint8,string)","d606f34b":"century(address)","d60743b1":"read_total_number_of_user_purchases(address)","d6077912":"RRRToken()","d608b3b2":"totalCharity()","d609ea93":"stakingEpochDuration()","d609fe59":"OEO(uint256,string,string)","d60bf518":"Test3(address)","d60d7044":"_char(bytes1)","d60dcb5d":"Switch()","d60df5be":"xmr()","d60e1447":"supplyBezNolei()","d60f0e5a":"BonusWhiteList(address,address,uint256,uint256)","d60f2eae":"buyPBTTAgainstEther()","d60f6cd9":"sendNumber(uint16,address,address)","d60fa784":"Voicecoin()","d60fd1be":"Hopecoin()","d6103b26":"_newPepe(uint256[2],uint64,uint64,uint64,address)","d6106696":"withdrawal_last_voter()","d6106b3e":"buys(uint256)","d611225b":"addContract(string)","d61191bd":"distributeValidityBond()","d612be77":"dpToken()","d612cff5":"permissionHash(address,address,bytes32)","d613ac91":"buybackTypeOne()","d613be0a":"forceChangeContractOwnership(address)","d6142c5b":"createProvider(bool,string,string,string,string,uint8,bool,address)","d615950d":"mintUpdateToken(uint256)","d61647f2":"developer_string_golos(string)","d617ad7d":"getPatentFee(address,uint16[5])","d618996b":"orderEnd()","d6192c6c":"hodlerStakes(address)","d619d216":"retrieveEth()","d619f6b3":"sendIndividualAmount(address[],uint256[])","d61a4524":"setdissolveaddress(address)","d61bd8fb":"getAvlShares(bool)","d61ca7eb":"RYH()","d61ccf84":"RABAToken()","d61e7201":"updateStatus(uint256)","d61e9274":"SetRate(uint32)","d61f92a3":"getJoinAddr(uint256)","d61fb0bf":"dateIT()","d620c7c8":"LogNewContractProposal(address,address,address,uint256)","d620caaa":"walletFromTeam()","d621b83f":"_createKydy(uint256,uint256,uint256,uint256,address)","d621c878":"improvementContract()","d621e813":"tradeEnabled()","d6223305":"ReleaseableToken(uint256,uint256,address)","d6224a6b":"getPixelText(uint256)","d6233491":"getPaid(string,address)","d6236ad0":"MetisCoin()","d62457f6":"callValue()","d624fdb6":"approveUser(address)","d625a7a6":"BetAdded(uint256,address,uint256,uint256,uint256)","d625c654":"migrateLosingTokenRepToWinningToken()","d6264b75":"transferBack(uint256,address)","d626db79":"setPublicWhitelistAbility(bool)","d6271727":"processUpgrade(address,uint256)","d628e0a6":"WatchBalance()","d628ecd7":"multiValueAirDrop(address[],uint256[])","d6291f6f":"VitalKey()","d629bc12":"iNf4mation()","d62a13ac":"ExhaustionCoin()","d62a7127":"getlastid()","d62ac58c":"AdvisorsPartners()","d62b255b":"setOwner(address,string)","d62b6f7e":"Main()","d62c6523":"cancelReservedTokens(address,uint256)","d62d3115":"testCreate()","d62f0f22":"getMyRice()","d62f146b":"updateSkill(uint256,uint256,uint16)","d6300201":"getPercent(address)","d630bd53":"pledgeApprove(uint256)","d630d100":"releaseAdmPercent()","d630efbc":"getAllTotalPrize()","d63124d7":"checkMidiNotesValue(uint8[])","d631eed7":"withdrawEthForUser(uint256)","d631f6d4":"DeleteProject(string)","d63241a6":"EtherCheque()","d63249ee":"_placeBet(uint256,address,bytes)","d632f639":"_privateSale()","d632fd1d":"PIP()","d6349dd6":"referralDividendsOf(address)","d634ba22":"baseNumber()","d6351433":"getRichToken(uint256)","d635357e":"TestContract(int256,string)","d63547e6":"GetFreeCnt()","d63581de":"setPricePoints(uint64[])","d63587a2":"randomNum(uint256)","d635b69f":"preValidatePurchase(uint256)","d635fc63":"getReveralSupply()","d6362e97":"getMin()","d6370149":"_errorAndRefund(string,uint256,uint8)","d6380f37":"complete(uint256,uint256)","d6387a3e":"getMinersAt(uint32,uint32)","d638d981":"SingularityTest24()","d63900d5":"getTileLocation(uint16,uint16,address,address)","d6391a01":"Total_TokenSupply()","d639bf80":"Bitstocksmarket()","d63a1389":"mintFeeFlat()","d63a6ccd":"usd()","d63a8e11":"allowed(address)","d63bed4c":"_setPermissionManager(address,address,bytes32)","d63d4af0":"getOwnerTokens(address)","d63e6ce7":"increasePeriod()","d63e7cc1":"priceICO()","d63ebe92":"StepVesting(address,uint256,uint256,uint256,uint256,uint256,uint256,bool)","d63eea42":"MAX_NUMBER_BETTERS()","d63fe1c7":"TARGET_TOTAL_SUPPLY()","d64196f8":"minInvestedLimit()","d641f3e4":"playGame(uint256,uint256,uint256,bytes32)","d64232c0":"option10name()","d6424ea7":"calculateAmount(string,uint64)","d6427c24":"randomPlayer()","d6449e15":"cancelTXwithCode(bytes32)","d644af34":"withdrawAndSend()","d644c46f":"wuxiaMasterPrice()","d644e356":"index(uint256,address,uint256,uint256)","d645ddf6":"mint(string,string,string)","d64637c7":"distributeDivident(uint256)","d6464b7c":"getSellerOfToken(uint256)","d6475c3a":"returnTokensForDay(uint256,uint256)","d647bb22":"Customcoin()","d647e2da":"test_set_get_RiskParameters()","d6481502":"setFreezingPercentage(uint8)","d648a647":"fundingStartBlock()","d648d7fd":"post(address,uint256)","d6495676":"emitPaymentReleased(uint256)","d64b12cf":"MAX_UNICORNS_TO_GIFT()","d64bcc1a":"releaseIcoTokens()","d64c2018":"setNextImagePart(uint256,uint16,uint16,uint16,uint256[])","d64c34fc":"getLockAmount()","d64d136d":"wnFromGas(uint256)","d64d6968":"isReferrer(address)","d64dc79f":"bidDkl(uint256,uint256,uint256,bytes,uint256)","d64e4e1b":"PKTToken()","d64ee8d2":"unBlockContract()","d64f5135":"In(address)","d64f86c0":"nextTransferFeeProp(uint256)","d64fe5ea":"getLockedWalletReleased(address)","d650cb2e":"forgiveMe()","d652818d":"ZYMToken()","d6528231":"FACTOR_3()","d6545ede":"hbtoken()","d6555687":"migrateUserData()","d655c786":"cancelOrderInternal(uint80,bool,bool)","d656a794":"stopForce()","d657ae0c":"actualTotalSupply()","d6582d0d":"isWeekDay(uint256)","d658d2e9":"hashes(bytes32)","d658d3ed":"setLedgerValue(string,address,address,uint256)","d65995ed":"attemptBeginLoanAtIndex(uint256)","d659afb6":"_isCooldownReady(address)","d659d968":"is_open()","d65a16c0":"isOneToken()","d65a4184":"tokenSaleActive()","d65aabc1":"t_Slava2()","d65ab5f2":"startGame()","d65b476c":"Governable()","d65b48fd":"ReceivedTokens(address,uint256,address,bytes)","d65c0035":"removeAddressFromWhitelist(uint256,address)","d65c8c6c":"claimDiamond(uint64,uint64)","d65f86f2":"setLeed(string)","d6604881":"whitelistBonusLockPeriod()","d660521c":"depositStake(uint256,bytes)","d660c897":"theRichest()","d660ea36":"lastBlock_v1()","d661952a":"removePrivilegeAddress(address)","d6619ffb":"funds_address()","d661d206":"INITIAL_FOUNDER_SUPPLY()","d661dd31":"MULTIPLIER_DIVISOR()","d661f244":"getRoomName()","d6636307":"stateSetOver()","d66495cd":"getSpaceshipProductTotalSoldByModel(uint16)","d6649861":"tokenTransfertoACC(address,uint256)","d664cd89":"askMembership()","d6661999":"securityTokenOffering(address,uint256,uint256)","d6664653":"landmarkToOwner(uint256)","d667dcd7":"houseEdge()","d6680a69":"getAllIntel()","d6682007":"getGameNumSides(uint256)","d66847df":"distributeARTToken()","d668a461":"escapeHatch(bool)","d668e654":"LogTokenReceiver(address,uint256)","d669133f":"PotSplit(uint256)","d669899c":"sendLudumToSingle(address[],uint256)","d6699f48":"addPolicy(uint8,uint256,uint8)","d669e1d4":"MAX_CAP()","d66b0b51":"komission()","d66b2207":"escrowTransferInfo(address,uint256)","d66bd524":"reserves(address)","d66c7faa":"ICO_PHASE3_LIMIT()","d66c9cc2":"transferSenderPaysFee(address,uint256)","d66cac2b":"invest(uint32,uint32,uint64,uint16)","d66cb9e1":"renewbeginnerprotection(uint256)","d66d9e19":"leave()","d66e5726":"getWriter()","d66f146d":"refundPoll()","d66f3afa":"addEmployee(address,string,uint256[3],uint256)","d66fd10d":"LogVote(address)","d6714924":"calculateBoardScore(uint256)","d6721000":"addCommissionToPendingWithdrawals(uint32)","d6728d51":"developer_EKN()","d673c93b":"split(address,uint256,uint256,uint256)","d6740de5":"mint_for_testing()","d674d6a1":"RimuoviNegoziante(address)","d6755434":"remainingCapInWei()","d6757f39":"_existPlatform(bytes32)","d675ecbd":"addPrivateInvestor(address,uint256)","d67601ac":"starsRemainingToAssign()","d67772d3":"PennyEther()","d6779b01":"winningsClaimable(address)","d6779d6f":"isWarrantyValid(string)","d678724f":"getGameNumberOfEntries(uint256)","d6787711":"betHash()","d678ba48":"depositLRC()","d679677a":"currentTier()","d6798645":"set_cooldown(uint256)","d679c4f2":"claimDividendPercentage()","d67a073f":"Drain()","d67a10e3":"etherDelta()","d67a1140":"getMultiBalances(address)","d67a12d4":"getStrategyHiddenState(bytes32)","d67a1694":"getBountyChance(uint256)","d67a7e5f":"updateSignedDealsCountInBulk(address[],uint256[])","d67ae54d":"EUR(uint256)","d67b534e":"socialIdentityToCardId(uint256,uint256)","d67b9a89":"ONLY600Coin()","d67bf1ad":"coinBurnMkt()","d67bf379":"getByUser(address)","d67c1a7a":"finishCrowdSale()","d67c4497":"_approveTransfer(uint256,address,address)","d67c7f35":"p_update_mResaleMultipler(uint256)","d67c9961":"pass(uint256)","d67cbec9":"release(uint32,uint32,uint32,bytes20)","d67d0bb9":"tokenCreationMaxCap()","d67d3af8":"cancelRequest(address,address)","d67d73e0":"removeAllowedContract(address,address)","d67d78cd":"addCard(uint32,uint32,uint32,uint32,uint32,uint256)","d67f4d1b":"TittyFarmer()","d67fd89e":"setout(bool)","d6805f49":"novaTransfer(address,uint256)","d680914d":"SLABToken()","d6816cc1":"fixSpecications(uint256,bool)","d68199dc":"gameStats()","d681ffa7":"getDefinition(uint256)","d6820709":"beginTimeTS()","d6823455":"minQuanValues()","d682b601":"auditContract(address,bytes32,bytes,bool)","d6830af3":"setSettingTAOId(address)","d68314ea":"setReserveWeight(uint32)","d68352d2":"BeatTokenIcoPhase1Started()","d683d1a2":"markRedemptionFulfilled(bytes32)","d6847cd8":"getWithdrawalCoolingPeriod()","d68526c8":"withdrawGemmyMusic(address,uint256)","d68561a3":"_isOwnerOf(address,address,uint256)","d6858850":"AlphabetConvert(address)","d6872352":"sendEtherManually(address,address,uint256,uint256)","d6875520":"reclaimUnwantedGift()","d687a9b3":"_deleteAddress(bytes32)","d687b57e":"interSend(address,uint256)","d689cfe1":"_setClientPaidUpTo(address,uint256)","d68a9fb8":"getFreeTokensAmountOfUser(address)","d68c967f":"addAddressToBackEnd(address)","d68d961a":"ROLE_MINT()","d68e0ff7":"DestroyCoin(address,uint256)","d68e462c":"withhold(address,uint256)","d68e9b1e":"createGen0Token(uint8)","d68f30a7":"recordMoment(address,uint256,uint256)","d68f65f8":"SHAToken(uint256,string,string)","d68f6aac":"salers(uint256)","d68f93df":"changeBonuses(uint256[],uint256[])","d68fac6d":"knuckReward()","d68fbe5c":"testCannotGetTokensInNotInitiatedSale()","d6906295":"withdrawCloneTokens(address)","d691092a":"predictExploreReward(uint256)","d6914217":"getServerUserIndex(address,uint256)","d6916c34":"airDrop(address,uint256[],address[])","d6938c18":"StagebleCrowdsale()","d693dca2":"setAllowCnsContract(address,bytes32,address,bytes32,bool)","d693e17f":"internalSend(uint8,address,uint256)","d6940c8c":"_RemovedFromGeneration(address,uint256)","d69450d5":"setUUID4Bytes(bytes)","d6948c47":"winningTeamId()","d69570e2":"durationOfState(uint256)","d6960697":"confirmPurchase()","d6965ff7":"shops()","d696888a":"EpietherCrowdsale()","d697a9f1":"CooCoinToken(uint256,string,string)","d69932a3":"getLpBidPrice()","d699c00e":"transferWeiToWallet(uint256)","d699fe3d":"setPhase(uint256,uint256,uint256,uint256)","d69a0d2f":"getMostExpensiveCryptoGamer()","d69a1a5f":"getNextPayoutEstimation()","d69b6cf4":"IdolToken()","d69c3d30":"nextNonce()","d69c9275":"extraDistributionPart()","d69d895e":"NUM_RESERVED_COIN()","d69dbf63":"getIssuanceBlockTimestamp(bytes32)","d69dc9a5":"balance_(address)","d69dd156":"setInt256(int256,int256)","d6a02bc2":"getSignedSubscribers()","d6a039f0":"Qbase()","d6a0810f":"ContractPurchased()","d6a0dec5":"buyTicketByOther(uint256,bytes32,bytes32,bytes32,bytes32)","d6a15231":"getIcedInfos(address)","d6a1f6a7":"breakIdUniqueness(uint256,uint256,address)","d6a2a596":"CrowdSale(address,uint256,uint256)","d6a30fb4":"start_quiz_quest(string,string)","d6a39db0":"lockUp(bool)","d6a3b623":"HONORABLE_LOSS_BONUS()","d6a3bc16":"finalReserveWallet()","d6a3f374":"dividendRate()","d6a43a3e":"setPermissionById(uint8,bytes32,bool)","d6a45623":"setAuctionsEnabled(bool)","d6a527eb":"share1()","d6a55e10":"sub_arbits(address,address,uint256)","d6a595ac":"payto2()","d6a5e546":"emergencyRefundContract()","d6a619e3":"transferIfPuritanical(address)","d6a62445":"confirmReturnToken(bytes32,string,bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)","d6a6a520":"undoUpgrade()","d6a6da3e":"angelInvestorsTokens()","d6a75d82":"winningsClaimable()","d6a78004":"burnRemaining()","d6a83613":"bytes20ToString(bytes20,bytes20)","d6a90bcf":"tokenMultisigWallet()","d6a9c807":"_createDog(uint256,uint256,uint256,uint256,address,uint8,uint256,bool)","d6a9de51":"getSeller(uint256)","d6a9e9d1":"teamPercentage()","d6aab015":"getBonusPool()","d6abe110":"tokenDetails()","d6ac2394":"payoutInvestor(uint256)","d6ad00a9":"DOJC()","d6ad5e5e":"MIN_ACCEPTED_VALUE()","d6ae5f29":"getUsedReserveSupply()","d6aefb61":"setBatchTransfer(address,address,bool)","d6af9411":"Rouleth()","d6afc9b1":"getProfile()","d6b0f363":"OpusToken(address)","d6b0f484":"disableWhitelist()","d6b1deac":"KTOCrowdsale()","d6b1e4a9":"buyMinersWithEther(uint64)","d6b224f2":"getNextActiveBuyDetails(bytes32,uint64)","d6b2b242":"Realize(uint256)","d6b2e2ba":"PARSEC_CREDITS_PER_ETHER()","d6b33f59":"getNextActiveSellDetails(bytes32,uint64)","d6b44859":"scheduleUndoIt(uint256)","d6b4ec12":"getDailyWithdrawalLimit()","d6b52d9a":"partnerETHRewardsPercent()","d6b53175":"UpdatePoolState(uint8)","d6b5983d":"checkAmount(address,uint256)","d6b5abc9":"weiToPonzi(uint256,uint256)","d6b645bc":"react(address)","d6b6f9f1":"secondXRChangeBlock()","d6b74865":"watcher()","d6b7c81d":"BountyIssued(address,uint256)","d6b867e6":"exchange(uint256,address,uint256)","d6b8ae26":"jexp(uint256,uint256,uint256)","d6b8ec66":"presaleEth()","d6b92187":"_syncLockedDepositsAmount(bytes32)","d6b93d43":"fillBuy(address[8],uint256[6],uint8,bytes32,bytes32)","d6b94aba":"TTT(string,string,uint8,uint256)","d6bacb0e":"getTxRoot(bytes32)","d6bafa0c":"ECommercePaymentSystem()","d6bb0ad5":"CrowdsaleGummy(address,address)","d6bb358e":"LuckyBaby()","d6bb9eff":"getMartialCardTypeIdList(uint256)","d6bc1b39":"setPrices(bool,uint256)","d6bc1e57":"fromWei(address,address,uint256)","d6bd603c":"getBalance(address,address,address)","d6bd64fc":"test_get_expired()","d6bd8727":"getUrl()","d6be178d":"rateStage2()","d6be6bd5":"birth(bytes32)","d6bea5fd":"rangeToProposalID(uint256)","d6bec803":"setExpiredAndWithdraw(address)","d6beebf7":"buyTokens_ETH(address,uint256,uint256,bytes8)","d6bf28e4":"_sendMonsterPrize(uint256,address)","d6bf7530":"getEthDepositAddress()","d6bfc2d4":"oykooshi()","d6c0ceab":"changeBountyDeadline(uint256,uint256)","d6c12f88":"pricingPlan()","d6c1869b":"s33(bytes1)","d6c19fe0":"build(bytes,uint256,uint256,address)","d6c1be92":"gameEarnings()","d6c242d6":"approveViewer(uint256,address)","d6c2479a":"donationsAddress()","d6c3453c":"addTrancheRateAndTokens(uint256,uint256,uint256)","d6c54bf7":"destroyTokens(address,address,uint256)","d6c5a41e":"tier3End()","d6c5d823":"getScientificData(uint256)","d6c6f48e":"mintAgents()","d6c75abf":"RiskPrices(address[],uint128[])","d6c7b4ad":"receiver1()","d6c7b65b":"addInfo(address,address,uint256,string)","d6c8976b":"changeTokenController(address)","d6c8f93c":"getCooldownIndex(uint256)","d6c9d27a":"addCountry(uint256,uint256)","d6ca8ccb":"disown(bytes20)","d6cb56e6":"FishCoin()","d6cb9ec2":"viewContractState()","d6ccb332":"FED(uint256,string,uint8,string)","d6ccf7a7":"addTokenTime(uint256,uint256)","d6cd4a02":"listAgents()","d6cf18e7":"createPiranhaTokens()","d6cf5297":"oracleItSetNetwork()","d6cfece1":"preBonus()","d6d02c51":"whois(string)","d6d13ac0":"Split(bytes32,uint8)","d6d14171":"initialTimestamp()","d6d1b8bb":"TCLRToken()","d6d1f369":"Test4(uint256)","d6d1fc2a":"SoSoCoin()","d6d21dfd":"who()","d6d22fa4":"MetaCoin()","d6d25008":"coldStoreLast()","d6d30a51":"increaseJackpot(uint256)","d6d3286c":"geProposalInfo(uint256)","d6d329b9":"ships(uint64)","d6d34c7c":"coOwner()","d6d3e19c":"DigitalKeyCoinKO()","d6d4136a":"checkPos()","d6d5c8d5":"DEFROST_MONTHS()","d6d65f3d":"getCurrentMilestoneIndex()","d6d6945e":"doPurchase(address,uint256,uint256)","d6d707a6":"BaseStoreToken()","d6d76ed5":"status(address,bytes32)","d6d76fb7":"ArtCertificate(address,bytes32,string,string,string,string,string,address)","d6d7d525":"get(bytes)","d6d80f0b":"withdrawal_party_a_gets()","d6d86646":"UpdatePolicyState(address,string,string,uint8)","d6d902c4":"claimThroneFor(bytes,address)","d6d9266a":"setNewUseIndex()","d6d98ffc":"CosmicExperiencePoints()","d6da0805":"registerName(bytes32)","d6dad4cb":"BCFLeague(address,uint256,uint256,uint256,uint256)","d6db71e9":"allowRefund(address)","d6db85af":"fracExp(uint256,uint256,uint256,uint256)","d6db8ab6":"dividendPayouts(uint256)","d6dbf1c2":"getPOOL_edit_9()","d6dd1f0f":"ConnectLeaf(uint256,uint256)","d6dda33d":"isPremine()","d6ddbd2d":"purchaseAdv(uint256,uint256,string,string)","d6ddd21b":"vestingStartTimestamp()","d6de8dc4":"getPlayBlockNumber()","d6dfb77a":"getIndexToken(uint256,uint256)","d6e0bf29":"OwnerDeposit()","d6e0d73c":"mintA()","d6e20a56":"confirmKYC(address)","d6e2bcb5":"SwordMaster()","d6e325ae":"joinClub()","d6e38114":"addBet(address)","d6e3bb94":"addAudit(address,address)","d6e3dd77":"balancesImporter3()","d6e4ddc5":"ownerOf(address[16],uint256)","d6e5fe98":"setStakeRequirements(uint128,uint128)","d6e67215":"newCajutel()","d6e78eb0":"setGasMin(uint256)","d6e871ff":"loser(address,uint256)","d6e898ad":"vest2team(address,address)","d6e89cf0":"setTransferStatus(uint256)","d6e8a0b0":"incrementBid(uint256)","d6e95f77":"isSellable()","d6e9b019":"getDisputeData()","d6ea53b1":"changePayer(address)","d6ea5a0e":"distributionEntryCount()","d6ea8c90":"decimalOddsForOutcome(uint8)","d6eab9f2":"setHostFee(uint256)","d6eac4cd":"initTokenGrants()","d6eafd08":"scheduleCall(address,bytes,bytes,uint8,uint256[4])","d6eb1bbf":"authorised(address)","d6eb748c":"setRelation(address,address)","d6ec0065":"CHN()","d6ecb38a":"firstAddressFromDeployer(address)","d6ecff50":"Identified()","d6ed8f52":"addAirdropList(address,uint256)","d6edb047":"addAllocationPartOne(uint256,uint256)","d6ef25d5":"addVersion(uint64[3],address,bytes)","d6ef3de2":"Stocks()","d6ef7af0":"withdrawRewards(address,uint256)","d6efb030":"sendEthToContract(address)","d6efc8eb":"marketBuyOrders(uint256,bytes[])","d6effa2b":"ICOwei()","d6f0b484":"serverEndGame(uint32,uint8,uint16,uint256,int256,bytes32,bytes32,uint256,address,address,bytes)","d6f12a6a":"refundT4T()","d6f15469":"setBuyEnabled(bool)","d6f22e69":"getChecksumPairCount()","d6f327cc":"swapCardForReward(address,uint8)","d6f35eb4":"setMinAmountSale(uint256)","d6f3c45f":"tokenCrowdsaleCap()","d6f42038":"PhoneToAddress()","d6f4472d":"BTCS_PORTION_MAX()","d6f4c235":"setInstructor(string,uint256,string)","d6f4e56e":"allTokensSold()","d6f50ed6":"registrarApp(bytes32,address,bytes32[])","d6f5792d":"isCurrentAccountReader(address)","d6f5c939":"tie()","d6f6b6e7":"closeFailedVotingAndWithdraw()","d6f7ddf9":"topUp(address,uint256)","d6f8307f":"requesters(address)","d6f8560d":"withdraw_eth()","d6f8ecae":"time2()","d6fa3efa":"requiredTimeBetweenDraws()","d6fb1678":"mineableSupply()","d6fb69b9":"_sendWinnerJackpot(address)","d6fbf202":"startingPrice()","d6fc2e62":"rateProjectSecondParty(bytes32,uint8)","d6fd1fe9":"saleAction()","d6fd8822":"threeTimes(address,uint256)","d6fe3d6d":"afterForkRescueContractBalance()","d6fea306":"weiICOMaximum()","d6febde8":"buy(uint256,uint256)","d6feecde":"ret_len()","d700071a":"minorPartnerAddress()","d7003222":"unitCost()","d700ed39":"isStarterClaimed(address)","d70108a6":"getCmd_control()","d702087f":"setSecretSigner(address)","d7020b0c":"setarg_3(uint256)","d7020d2a":"approveEscrow(bytes16,address,address,uint256)","d702b63d":"for_longterm()","d702db81":"UserRetireHodl(uint256)","d702e364":"setPreICOSoldAmount(uint256,uint256)","d7052e17":"GotTokens(address,uint256,uint256)","d705d6d7":"MainSale(address,uint256,uint256,uint256)","d70657ac":"getBalanceHolder()","d7067dc5":"crowdSalePaused()","d70695bb":"swarmRedistribution(address,uint256)","d706df8c":"BioStem()","d7074aaf":"GetCard(uint32)","d70754ec":"node()","d7079ee7":"startPublicsale(uint256,uint256)","d707d466":"allocToMember(address,uint256)","d7081e03":"transferAmount(address,uint256)","d7085e05":"SafeSend(address)","d70907b0":"freezeWithTimestamp(address,uint256)","d70925b4":"teamEthTransferComplete()","d70948b5":"_create_drug(bytes32,address,uint256,uint256)","d7098154":"claimPrize(uint256)","d70afa96":"FEE_ADMIN()","d70b6342":"minInvEth()","d70cf105":"moveBalance(address,address,uint256)","d70d2e26":"DetherTx()","d70d37e6":"OptedIn(address,address)","d70d532b":"provideAccess(address,uint8)","d70d9254":"isBetClosed()","d70d9604":"Sales()","d70dbf7d":"Aequitas()","d70e0f90":"disableAuto()","d70e62eb":"lowLimit()","d70ed38a":"withdraw(bytes32,uint256,address,address,uint256,uint256,bytes32,bytes,bytes,bytes32)","d70efa86":"_inRateFallEffectLimit(uint256,uint256)","d70fe207":"cancelOrdersOnOption(uint256,uint256)","d710999d":"SiliconValleyCoin()","d7109dda":"getCurrentSaleDay()","d710e2f0":"sendAllToOwner(address)","d710eaac":"NewWallet(address,address,address)","d71186b9":"Fund_Contract()","d7121f4b":"HolikopterToken()","d7123dff":"_createBuilding(uint256,uint256,uint256,uint256,uint256,uint256,address,bool)","d712800f":"setLockValue(address,uint256,string)","d712d06d":"tokenDestroyed(address,uint256,string)","d712eb4a":"voteWeight()","d7130651":"getCity(uint256)","d7131e5f":"createToken(uint256,address,string,string)","d71331c2":"getCountPlayerByTrackId(bytes32)","d715c8b2":"ownerHistoryCount(uint256)","d716222c":"is_owner(uint256,address)","d716e9ca":"getTotalInvoices()","d71710e0":"countAttributeTypes()","d717b05e":"exchangeLimit()","d71801d4":"gallerySix()","d7182850":"ownerTokensAllocated()","d7186f2b":"KNTTToken()","d718e763":"FinalizableCrowdsale(address,address)","d719213e":"preBuyPrice1()","d719843f":"getVendingStepPrice(uint256)","d71a0d7c":"HolahopxToken()","d71c14aa":"_isAOContentUsageType(bytes32)","d71c4028":"DRPCrowdsale(address,address,uint256)","d71cdd78":"BONUS_HI_QTY()","d71cf1e4":"getFee(uint256,address,address,address,address)","d71d3b3c":"CrowdSalePreICO()","d71d6cc5":"blendbacktest(uint32[],bytes32[],bytes32[],uint64[],bytes32)","d71d9e8a":"buyFlower(uint256)","d71db8aa":"getBonusPerShare(address)","d71df760":"oraclize_newRandomDSQuery(uint256,uint256,uint256)","d71e58f8":"admin_set_exchange_rate(uint256[])","d71e8296":"canIWithdraw()","d71e930c":"teamAddressTwo()","d71eb6ab":"recursive_store(uint32,uint256)","d71f1bd6":"LottesyAddress()","d71fcbe6":"BaseBountyContract(address)","d7203294":"ZeroXEth()","d7206124":"setInvestorLock(bool)","d721b0af":"batchExchange(address[],uint256[])","d721c760":"IssueAssigneeLoaded(bytes32,string)","d7228bb5":"doSucceedingTransferFrom()","d7237e45":"invitedByReferalBonus()","d723879c":"icoOver2()","d723bb73":"fetchVoteInfoForVoterBySnapshotBlock(address,uint256)","d72473f3":"Added(uint256,string,address,uint256,bool)","d72503ba":"buyCat(uint256)","d725a9f0":"crowdSaleaddress()","d725f10d":"curse(address,address)","d7260cba":"refundGame(uint256)","d726755b":"moveFloor(uint256)","d726f7c7":"mainCoinSentToEther()","d7276479":"battlesOwner()","d727d64b":"disputeSettledTerminate(bytes32,address,uint8,address,uint8,bool,address)","d7289cb4":"FundsReturned(address,uint256)","d728b6db":"getCatOfferPrices()","d728cc72":"novaCoinAddress()","d7290181":"emptyWrongToken(address)","d7299009":"isCustomerHasACCfromWL(address)","d7299ef7":"pausePresale(bool)","d72ad259":"unlockFunds(address)","d72ad623":"getReferrerReward()","d72b11bd":"reserveWallet()","d72b6d3b":"CREATION_LIMIT()","d72bdc53":"initialize(address,string,string,uint8,uint256)","d72c83c0":"SmokeExchangeCoinCrowdsale(uint256,uint256,address,uint256,uint256,uint256,address)","d72c9391":"confirmTransactionSig()","d72d04db":"addGame(address)","d72d8dd6":"numRegistries()","d72dec33":"changeVaccinHistory(address)","d72e2b78":"soldTokensWithoutBonus()","d72e3de1":"createCustomReservation(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d72e4167":"getCompte_38()","d72eabb8":"minimalToken()","d72f7958":"fortune_break_current()","d73019e9":"icoStartDate()","d7303eaf":"nicole()","d7304b09":"cleanupOdd()","d730bfe2":"RabbitCoin()","d7311963":"m_controller()","d7315d60":"totaldeposited()","d731a779":"removeTRA(address)","d732a3fa":"newRound(uint256,bytes32)","d732d30e":"getGamblingPartyInfo(uint256)","d732d955":"decrease()","d73478f8":"userToNumTowns(bytes32)","d735140d":"fourthTokenExchangeRate()","d7353371":"PeerLicensing()","d7354b49":"getBirthDay()","d735875d":"Start_quiz_g(string,string)","d735dc92":"multiAirdrop(address[],uint256[])","d735fa25":"wholeSaleValueLeft()","d7365f9b":"_purchaseMake(uint256)","d737035d":"holdersBonus(uint8)","d73792a9":"FEE_DENOMINATOR()","d7379999":"permissionAt(uint8,int256)","d737c2b0":"setContractInfo(bytes32,address,bytes20)","d737d0c7":"msgSender()","d7385abd":"placeBet(int8,int8,uint32,uint256)","d7397a72":"setUrl(address,uint256,string)","d739aaf8":"getGameInfoById(uint256)","d73a24fc":"canBeWithdrawn()","d73a2901":"setManagedVote(uint256,uint152,bool)","d73b0cf2":"buyerFundRelease(uint256)","d73b1dc9":"decreaseAllowance(address,address,uint256)","d73b3a67":"withdrawal_Eth(uint256)","d73c277c":"storageName()","d73cbc6b":"testLen()","d73cbcba":"daCall()","d73cedd4":"SPECTRUMZ()","d73dd623":"increaseApproval(address,uint256)","d73e0c89":"getBookCount()","d73f0b25":"lookupCampaignPart1(uint256)","d73f3408":"SimpleMultiSig(uint256,address[])","d73fe0aa":"getShares()","d73ff0db":"preSaleBfPlatform()","d740547e":"mintBonusTokensForGames(uint256)","d740766e":"testNoTokenTransferIfNotApproved()","d741e2f9":"pip()","d743015a":"createAssetPack(bytes32,uint256[],bytes32[],uint256,string)","d743ca38":"newWinner(uint256,address,uint256,uint256,uint256)","d7441753":"getTypicalItemById(string,uint256)","d744f2a3":"wantMyToken(uint256)","d744f330":"IdClaveChain(address)","d744f47c":"validateMessage(string,bytes32,uint8,bytes32,bytes32)","d744fcb8":"ClaimFeesFromSharesBought(uint256)","d74543f0":"communityusersCap()","d7463573":"getOpeningTime()","d746a38b":"getMicroModuleByIdPart1(uint256)","d7471ad2":"nemocoin()","d7480aa4":"AuctusEtherVesting(address,uint256,uint256,uint256)","d748d1f6":"revokeEditorRights(address)","d74a960e":"BGFTToken(uint256,string,string)","d74a99d4":"create(uint256,string,uint8,string)","d74ae98e":"redeemShip(uint256)","d74afaa1":"newowner()","d74b2722":"setRefunder(address)","d74be848":"maskSender(address)","d74c894e":"setSecurityWallet(address)","d74d763e":"setUCCoinPerEther(uint256)","d74d7e79":"calculateRewardAt(uint256)","d74e0d9e":"SetBanker(uint8,address)","d74ea11e":"addMockPendingWinner(address,uint256)","d74f8e9a":"getLastPayments(uint256)","d74f8edd":"MAX_OWNER_COUNT()","d7504385":"validateToAddress(address)","d7508a55":"prepareAuctionForNonOGChain()","d7517caa":"getPresaleStatus()","d751b8de":"Request(uint16[],string,address,uint32[],uint256)","d7520298":"SetfirstTTaxAmount(uint256)","d7522582":"isCurrentTierCapReached()","d752dd8e":"AFSBToken()","d75318f8":"SecretCoin()","d75320b1":"_subtractFromMintPool(uint256)","d7533595":"keccak_f(uint256[25])","d7533751":"UnvestedSkyeCrypto(uint256,string,string)","d75352e1":"marginCall()","d75446fe":"etherGet()","d7546da7":"Commitment(address,address,address)","d754a6bc":"adminResetEmail(address,address,string)","d754f0ac":"LOCKOUT_PERIOD()","d754f3d5":"currentEraIndex()","d75528a5":"addSpecial(uint256,uint256,uint256)","d7554a68":"addUser(address,string,string)","d7557f18":"closeCampaign()","d755cc4a":"buyGOP(address,string,uint256,uint256,uint256)","d755e021":"getPlayerShipBattleById(uint64)","d7560f2b":"numRewardsUsed(address)","d7575592":"addr_teamPartToken()","d757579e":"XxxTokenSale()","d7578295":"Cashpayz()","d75b2b18":"takeCollateral(address)","d75b363f":"userRewardCount(address,address)","d75b5d9d":"RAFEND()","d75b80cc":"a_incognita(uint256)","d75d93f6":"registerMeOnToken(address,uint256,string)","d75de4ab":"isAddressInWhitelist(address,address)","d75e30cf":"drawFee()","d75e662f":"OverpayRefund(address,uint256)","d75e7afd":"calDivs(address,uint256)","d75e87ef":"PersonalInfoAdded(address,string,string,string,string,string,string,string)","d75ebde2":"joinGameFromBalance(uint256)","d75f0dd6":"SixtusToken()","d75fabb0":"RewardOffer(address,address,bytes32,uint256,uint256,uint128,uint256)","d7625c88":"hasMigrated(address)","d762755d":"minimumContributionWeiByOneInvestor()","d7638b73":"phase2Cap()","d763f92d":"FintechChain()","d7642ae2":"COIN_COST_ICO_TIER_3()","d7643e18":"protoCount()","d7651471":"Notes()","d7655b98":"OmixToken(uint256)","d7669119":"NewPrice(uint256,string)","d767aee0":"bbb()","d767ee4d":"updateLogic(uint256)","d7682701":"_cancelPermissions(address,address[])","d768729d":"getRecentDiary()","d7688d31":"destEthFoundationDev()","d7689460":"CryptoRex()","d768d95b":"finaliseContract()","d768d95e":"fetchVoteMainInfoForVoterBySnapshotBlock(address,uint256)","d768dd4b":"Stage3Allocation()","d769ae1b":"SLCAdvancedToken(uint256,string,string)","d769f32a":"mulXY(uint256,uint256,uint256)","d76a0cb8":"HybridBlock()","d76a130a":"TokenCDCQ(uint256,string,string)","d76a69e2":"Fund(address,address,address,address,address,address,address,address,address[])","d76b6095":"phase1Rate()","d76bce7c":"dropEth(address[],uint256[])","d76d6ee0":"query(bytes32,bytes2,int256)","d76dc2eb":"LOCKAMOUNT1()","d76dc656":"GDCAcc02()","d76dddd3":"unfreezeTime()","d76e5765":"getUserIpfsFromId(uint256)","d76f288f":"metaBurnHash(address,uint256,uint256,uint256)","d76f94aa":"toAlphabet(uint8[])","d7717750":"tokenLogic()","d7723231":"getIcoPurchase(address)","d772ddc0":"setProcessorAddress(address)","d7730236":"maxEthRaised()","d7734855":"getDiff(uint256,uint256)","d77371e0":"GoodDayToken()","d774c038":"multisend(address[],address)","d775db2a":"testThrowsSaleWalletIncorrectMultisig()","d7760500":"partnersRelease()","d7768c47":"prepare(bytes)","d77727de":"seeOwner(uint256)","d7777c29":"startPreICOStage1()","d77844f6":"isLimitationPeriodActive()","d77849c7":"tokenTakeback(address,uint256)","d7787f33":"setUpgradeContract(address,address)","d7789a9f":"unsetEndorsement(address,uint256)","d778c911":"price3()","d7790c11":"waipaytoken()","d7796915":"checkWithdrawValueFX(uint256)","d779ca24":"payoutBonusesToHolders()","d77a39c9":"addPresaleTokens(address[],uint256[],uint256)","d77a80a8":"lastFunder()","d77a86a0":"sendTo(address,uint64)","d77ac32d":"discountSum(uint256)","d77b0ff7":"keyAtIndexHasNext(uint256)","d77bd1ae":"ProposalAdded(uint256,address,string)","d77bf0cf":"CONFIG_PRICE()","d77c96f8":"mainICOThirdWeekEndTime()","d77d0012":"getBankPercent()","d77d3f79":"KoaStandardToken(uint256,string,uint8,string)","d77da4f4":"withdrawToTeam(uint256)","d77e2f55":"pendingEtherForCroupier()","d77e8986":"isExistsEscrow(bytes16,address,address,uint256)","d77ec4a4":"executeWithdrawTransaction(uint256)","d77fc50f":"checkZeroValue(uint256)","d77ff9ea":"eventCardRangeMin()","d7800fa2":"PurchaseRegistered(bytes32,address,uint256)","d7815ba4":"shareholdersHolding1y()","d7816f45":"transferlocked()","d781be46":"endDatetime()","d781d0f4":"YaoToken(uint256,string,string)","d781f3f4":"FootScoutCrowdsale()","d781fbf9":"removeERC223(uint256,address,uint256)","d78235cf":"setconfigurationEtherPrice(uint256)","d78276c6":"withdrawERC20(uint256)","d782cc54":"setNewBonusLevel(uint256,uint256)","d782d647":"createdTokens(uint256)","d7837ec9":"withdrawNonTop(uint256)","d783aacf":"ItalyToken()","d783b53b":"addSupporter(address)","d784601a":"myEthBalanceOfNoFee()","d784d426":"setImplementation(address)","d78506ce":"RoyaltysOwing(address)","d785c19c":"worldCupResultPart1()","d785e5c9":"m_isCirculating()","d78724d6":"getUserContractCount(address)","d7872745":"GumToken()","d788a945":"_isLongitude(int256)","d7892b6a":"changePeaceRelayAddr(address)","d789479d":"celtic_cross()","d78996d8":"getUtilizationAndAnnualBorrowRate(uint256,uint256)","d789b4c1":"uintMax(uint256)","d78b16a1":"emitTokens(uint256)","d78c15d9":"isPromoted()","d78c20ff":"voteApprove(uint256)","d78cb1b2":"buyXgoldTokens(address)","d78d610b":"getRecipients()","d78db648":"multStore(int256)","d78e1bb1":"teamPot_()","d78ed508":"getShipProductStartPriceByModel(uint16)","d78efa67":"addrecruit(uint256,uint256)","d7901260":"closePreICOPrivate()","d7901645":"GetDappinfo(string)","d790dce7":"endOfSaleFullWithdrawal()","d79185d7":"StartGuess_wis(string,string)","d791de63":"unlock(address[])","d791ed7a":"BaoBaoToken(uint256,string,string)","d792b356":"teamTokenAllocation(uint256)","d793f7a9":"preICOamountBonusMultipierInPercent(uint256)","d7942050":"Setuppresale(uint256,uint256)","d79521e8":"getPokemonDetails(uint256)","d7955eaf":"Santal()","d7959cf9":"ipfs()","d7963f94":"changeOwners(address)","d7982a6c":"unlockEscrow()","d7984cff":"CappedAndBurnableToken(uint256)","d79875eb":"sell(uint256,uint256)","d7988c98":"makeGrant(address,uint256,uint256,uint256,uint8)","d7989a93":"advancedTokensPerEth()","d79941d8":"getQueryRandomCallbackGas()","d79964c3":"addDeprecation(uint256,address,address,address,uint256,address)","d79b5bc6":"DonationSentButNotMatched(address,uint256)","d79bd499":"retrieveBalance()","d79c1f7f":"batchReclaimExpiredSwaps(bytes32,bytes32[])","d79cb6fd":"buyScams()","d79d5c7a":"COMPANY_TOKENS_PERCENT()","d79d63be":"getCardPrice()","d79d8e6c":"set(bytes32,address,bytes32)","d79e1e7d":"sumElements(uint64[])","d79e3755":"totalPromo()","d79e5de8":"HeliumToken()","d79e7894":"isAfterICO()","d79f5678":"DazzioCoin()","d7a084e0":"isWhiteListGame(address)","d7a08641":"checkCanRelease(bool,uint256,uint256)","d7a10acb":"balances2(uint256)","d7a1192d":"STAGE3_TIME_END()","d7a14a05":"totalAmountOfEarlyPurchases()","d7a15951":"winnerReward(address,uint256)","d7a17187":"ico2Raise()","d7a1cfe1":"addFriend(address)","d7a23fd4":"getActivityCount(uint256)","d7a42b54":"isEntity(uint256)","d7a4a09d":"detectJanuary(uint8)","d7a58658":"changeHouseedge(uint8)","d7a5afcf":"holderPartnershipsTokens()","d7a5f278":"slashInvalidUsername(bytes,uint256)","d7a5fdee":"DGPTokenOldContract()","d7a66ebe":"readContent()","d7a71868":"setManualPrice(uint256)","d7a78db8":"freeze(uint256)","d7a8560f":"invoicesStackCount()","d7aa6d74":"ShitCloneFarmer()","d7aa8273":"getTransactionInfo(uint256)","d7aae0e6":"executeProposal(uint256,address)","d7ab2770":"fetchGiven(address,bytes32)","d7ac79ba":"deleteHeir(address)","d7ad28ec":"GSMulti(uint256,uint256)","d7ad4931":"buyNow(bytes32)","d7ae339b":"ForecastChainToken()","d7ae76b6":"DING()","d7af26f8":"getPlayersBalances()","d7b03000":"resetCards()","d7b0a358":"shiggidyToken()","d7b0ca65":"last50plusblokhack()","d7b0e692":"set_new_admin(address)","d7b11125":"pwr(uint64,uint64)","d7b12454":"checkContract(address)","d7b12f38":"PRICE_STAGE_TWO_BONUS()","d7b15a88":"getLockedFundsLastSpending()","d7b1b9c4":"foundationTokensAllocated()","d7b1bb22":"cadastrar(bytes32,uint8,bytes32,bytes32,int256)","d7b2aae6":"setContactInfo(string)","d7b2f360":"getEncounterDetails()","d7b32f5f":"GetPrivateSale()","d7b33f66":"updatePercentToTakeAsSeed(uint256)","d7b33f94":"PRE_ICO_AMOUNT()","d7b40107":"auctionByAssetId(uint256)","d7b4750c":"getFunder(uint256)","d7b4a7f6":"MinerOneCrowdsale(address)","d7b4c9b1":"lookupKittyDetails1(uint256)","d7b53081":"closeSaleAnyway()","d7b5507d":"blockchaincertified()","d7b701b6":"SarahCoin()","d7b7024d":"approvedWithdrawAddresses(bytes32)","d7b7913b":"f3(uint256)","d7b7961c":"getPairHash(address,address)","d7b84f68":"moveDataContractBalanceToWorld()","d7b8cdf4":"MinimumContributionChanged(uint256)","d7b8de00":"setMaxCollectable(uint256)","d7b91bcc":"buyTokensICO()","d7b96d4e":"locker()","d7b97db1":"setDistributionTime(uint256)","d7ba30b2":"rateAirDrop()","d7ba42fc":"addActionAccount(address)","d7ba95ca":"share2()","d7baa041":"PublicLayer()","d7bb913f":"accountTokensPurchased(address)","d7bb99ba":"contribute()","d7bbce2a":"setOrCacheDesignatedReportStake(uint256)","d7bc23af":"newParameters(int256,uint256,uint256,uint256)","d7bd6d0d":"addExchangeAccounts(address,address)","d7bd8987":"testTransfering()","d7bdaaa6":"WLMWallet()","d7bdc3fa":"addVolumeDiscount(uint256,uint8)","d7be503f":"_tokePerEth()","d7be708c":"BoulePreSale(address,uint256,uint256,uint256,address)","d7be8ceb":"performFetch()","d7bea56a":"totalExcessEth()","d7bfc8c5":"BabyDragon()","d7c01c3e":"SetTakePot(uint256)","d7c0302e":"numOfCitizensWhoReceivedDrops()","d7c06439":"AriumToken()","d7c06919":"getAuctions()","d7c0d42d":"ControlledToken(uint256,string,uint8,string)","d7c0f72b":"getTitulaire_Compte_5()","d7c23572":"historyTimesPlayed(address)","d7c23578":"addSig(bytes32,bytes32,bytes32,uint8)","d7c26adb":"oraclize_setProof(bytes1)","d7c2a887":"MANAGEMENT_FEE_RATE()","d7c35657":"EthsqrGate()","d7c39cc6":"totalSellingItem()","d7c482ef":"Defroze(address,bool)","d7c48e2b":"preseller()","d7c4e7ac":"HarlleriumCoin()","d7c4f9d3":"SignatureAdded(string,string,uint256)","d7c5b986":"LogContribution(uint8,address,uint256)","d7c61e7b":"CreateSaleAvgPrice(uint256,uint256,uint256,uint256,uint64,address)","d7c7159c":"buyWithKYCData(bytes,uint8,bytes32,bytes32)","d7c74279":"deployChildren(address)","d7c8112d":"WithdrawAllFunds(uint256)","d7c81b55":"gameId()","d7c81fdc":"MSCCStandardToken(uint256,string,uint8,string)","d7c8843b":"getEggsSinceLastHatch(address)","d7c8e90c":"voteAmendment(uint256)","d7c8f959":"CreateEmployee(address,uint32,uint32,uint16)","d7c94efd":"teamFee()","d7c97fb4":"erc721Contract()","d7c9a0e3":"getMyMoney()","d7ca01b5":"confirm(address,uint256)","d7ca3a90":"CelebrityMarket(address)","d7ca7cc5":"changeLockingPeriod(uint256)","d7ca9949":"totalSoldTokens()","d7cb55a2":"AToken()","d7cbac05":"BONUS_ICO_STAGE1_PRE_SALE1()","d7cbbb73":"getAllCardsAddress()","d7cc43bf":"aSetStart(uint256)","d7cc8362":"isLatestMajorTree(bytes32,bytes32)","d7ccc2c3":"getLastPayment()","d7cd6c13":"burnFundAccount(address,uint256)","d7cd7209":"newGroup(address,bytes32,address[])","d7ce330b":"Deco()","d7cea877":"monthStr(uint256)","d7cee31e":"houseAddress()","d7cf1d20":"HDT_Token()","d7cf61d7":"assertSignedByBoth(uint256,bytes32,uint8,bytes32,bytes32)","d7cf7bcb":"purchaseSafe(uint256,uint256)","d7cff986":"submitAnswerCommitment(bytes32,bytes32,uint256,address)","d7d0afa4":"_fetchCreatedOrdersForMerchant(address)","d7d12297":"taskTotalBalance()","d7d15059":"functionName()","d7d1b48c":"_setWingsValue12(uint256)","d7d1bdbd":"getUnsoldOwner()","d7d23155":"owner_linkage()","d7d29315":"drawReuslt(uint256,address[],address[],uint256,uint256,uint256)","d7d319e4":"CWCreturnQuery()","d7d3c4d5":"pvpContenderRemoved(uint256)","d7d40523":"HardwareWallet()","d7d43b41":"MoedaToken()","d7d49532":"lastBlock_a9()","d7d5878d":"revokeSchedule(address,address)","d7d7442f":"updateThreshold(uint256)","d7d7be34":"oraclize_query(string,bytes[1])","d7d88043":"endSaleDate()","d7d8cdd5":"addTRA(address)","d7d90fb1":"ClearCLevelSignature()","d7d96a12":"StarToken()","d7d9fef0":"scheduleTimelock(address,uint256,uint256)","d7dae83c":"active_withdraw(address)","d7dbb88b":"getn2Exception(bytes32)","d7dbdbe3":"setVicepresidenteDeMesa(bytes32,uint256,bytes32)","d7dc6203":"calculateInterest(address,uint256)","d7dcaa19":"BuToken()","d7dccb1e":"EthSplit(address[],address)","d7dd2ae3":"ValidateCitySnapshotInternal(address,uint256)","d7dd8652":"refundCrowdsale()","d7dde189":"StartupToken()","d7de57c6":"challengeWithFutureCustody(address,uint256,bytes32[],uint256[],bytes32[])","d7de9c6e":"setOracleQueryString(string)","d7df7ef9":"_createWonder(address)","d7dfa0dd":"logic()","d7e07d5f":"destTokensReserve()","d7e0b6e3":"registerUser(address,bytes32)","d7e0d83d":"setPrvd(address)","d7e0e776":"getBalanceOfInstance()","d7e11e9d":"AddTicket(bytes)","d7e25c36":"isCapReached()","d7e2f000":"preallocationsWhitelist()","d7e30832":"TankTransfer(address)","d7e31d67":"setRewardChance(uint256)","d7e3aab2":"VestedMultisigWallet(address[],uint256,uint256)","d7e4e1f7":"setSail(uint16,uint16,bool)","d7e5c07d":"allocateTokens(uint256,uint256,address)","d7e64c00":"investorCount()","d7e7088a":"setUpgradeAgent(address)","d7e751ff":"tokenWithdraw(uint256)","d7e8015a":"FuckToken(uint256,string,uint8,string)","d7e84fbf":"builder()","d7e8553a":"_deleteValidator(address)","d7e9ec6e":"RemovedBlackList(address)","d7ea39c6":"referralDone()","d7ea977b":"V1ChainToken()","d7ea97e2":"setBTHFoundationWallet(address)","d7ead1de":"right74(uint256)","d7eae6db":"setUnPauseEmergence()","d7eaef90":"LGTToken()","d7ebf53d":"countActiveCastle()","d7ec1fac":"CrowdSaleTokenSoldout()","d7ecb5e3":"MINI_GAME_BETWEEN_TIME()","d7ecba0c":"numBarriersPerBoard()","d7ecc129":"supplyTo(address,uint256)","d7ed3fb1":"get_participant_topl_address(address)","d7ed7453":"redeemWinnings(uint256)","d7edddb2":"withdrawAdministratorMoney(uint256)","d7edf88c":"replenishEth()","d7ef1356":"best_adjustment(bool)","d7ef4a04":"CreateCredoIco(address,uint256)","d7efbf34":"transition()","d7f08eed":"unlistSubName(bytes32)","d7f0d86b":"attackUnit(uint256,uint256)","d7f0df73":"Betcash(uint256,string,uint8,string)","d7f0f01b":"fund(uint8,uint8,uint8)","d7f31eb9":"forward(address,uint256,bytes)","d7f3c770":"Mesut()","d7f42ee2":"getBBLibVersion()","d7f56ef7":"partnershipsTokenAddress()","d7f59fd0":"tgeSettingsBlocksPerStage()","d7f6f81c":"getProviderBadge(address)","d7f746ce":"tickingBomb()","d7f7582c":"totalCapitalization()","d7f7f3aa":"markTransferTokens(address,uint256)","d7f8a053":"TokenRate(uint256)","d7f9d655":"Divies()","d7fa1007":"setHash(bytes32,bytes32)","d7fa445e":"claimBidReward(uint256)","d7fb4f1d":"endTime_()","d7fb5ef5":"angelSupply()","d7fb7427":"transferNewCoin(address,uint256)","d7fb8dc0":"messageForReason(uint8)","d7fc1b9b":"register(string,string,bool)","d7fc23a2":"createNewAsset(string,string,uint256)","d7fc98c3":"subscribeIndividual(bool)","d7fd00b0":"TEAMS_PER_ENTRY()","d7fd0e77":"requestTime()","d7fe270e":"multipleTokensSend(address[],uint256[])","d7febcb9":"TestUserBitFlag(address,uint256)","d7ff4d7a":"WODECESHIBI(uint256,string,uint8,string)","d7ffbbaa":"setInformation(string)","d8013c4e":"addNote(bytes32,bytes20,string,string)","d80162fc":"setRecommendStatus(bool)","d8018c42":"getReleaseTimes(address)","d801aa84":"isWalletFromUser(string)","d8020a18":"marketingPercent()","d80326a9":"VentanaToken()","d80364ba":"LogRegister(address,string)","d8047a07":"RobotChain()","d80528ae":"stats()","d8055812":"votesDecline()","d8058712":"UnicornAccessControl(address)","d8063ea6":"addDelegate(address,address,string,address,uint256)","d8070c40":"IcoPrice()","d807a688":"wper(uint256,uint256)","d8085306":"mintTokensForSecondStage()","d8085f78":"ownerCanClaimCard(address,address,address[3],uint256)","d8085fee":"multiMerge(address[])","d80866da":"isValidZ(uint16)","d8090cbf":"resetReclaim()","d809d248":"startNextGame()","d80a5c3b":"MyContribution()","d80ad1ed":"getSponsorshipProportionalAmount(address,uint256,uint256)","d80aea31":"_setCreatedBlockOnRevealsPhase(uint256,address,bool)","d80b1a68":"createAndEndowC1(uint256,uint256)","d80b2056":"emptyWrongEther()","d80cc340":"retainBalance()","d80d3025":"changeBonusSystem(uint256[],uint256[])","d80d9c55":"changeSecondsInBlock(uint256)","d80e821c":"reevaluateICO(uint256)","d80e8700":"CurrentTime()","d80ffb20":"drawNumber()","d8104e19":"GetMyEarning()","d810f298":"computeSettlementAmount()","d81111ab":"BuyTokens()","d8112523":"sendIncentive()","d811b100":"getHouseAddressOne()","d811b7ca":"transferToOtherBucketContract(address)","d811f09e":"ownershipTransferAllowed()","d811fcf0":"farmer()","d81230c8":"shareactive()","d812d961":"getSanName(uint256)","d812f2b0":"setDelegadoDeEscuela(bytes32,uint256,uint256)","d8132807":"_getMinAuctionStartPrice()","d8134a23":"removeAcceptedToken(address)","d813b4b9":"setArtIdt(string,string)","d8145062":"squirrelmasterReq()","d8148166":"DistributionMint(address,uint256)","d81494ba":"blacklist_addys(address[])","d8149fe7":"dive1(address)","d814ebed":"TruUpgradeableToken(address)","d8152cbc":"createBalanceSnapshot()","d816187f":"PreIcoWallet()","d8162db7":"lockedUntilBlock()","d8174150":"MAX_PRESALES_EXTENSION()","d8175101":"ownerHasCardSimple(address,address)","d81849b8":"additionalTokenRate()","d818eb63":"Fundraiser(address,address,uint256,uint256,uint256)","d818ecee":"setDisputed(address,string)","d81a91e9":"get_party2()","d81ab0c1":"invoke(uint256,address,address,bytes)","d81ad101":"IMPACT_REGISTRY_ADDRESS()","d81b1020":"setForceContract(address)","d81c2232":"icoPhase2TimeBonusInPercentage()","d81c6741":"removeAddressFromBonuslist(address)","d81d5062":"relayBuyerCancel(bytes16,address,address,uint256,uint16,uint128,uint8,bytes32,bytes32)","d81d8f89":"getSalaryTokensTotalValue(address)","d81dd9f7":"destroyGame(uint256)","d81dfe30":"LOCKED_TIME()","d81e8423":"get(address,address)","d81efdc4":"euroCentsInOneEther()","d81f53fd":"EtherId()","d81f84b7":"getAddr(uint256)","d81f9830":"BONUS_WINDOW_2_END_TIME()","d8207301":"MyWishCrowdsale(uint256,uint256,uint256)","d820ab95":"secondStageReserve()","d8211b0d":"BENZCoin()","d821b9f9":"initialAllocations(address)","d82277cc":"createInvestment(address,uint256)","d823eec9":"TEAM_TOKEN_CAP()","d825b510":"addDisagree(bytes32)","d825ebc3":"calculateMinting(uint256)","d826505d":"isEthNoEnc(uint16)","d8267fef":"letItRain(address[],uint256[])","d826853e":"sellKeys(uint256,uint256,string)","d826f88f":"reset()","d826fdf1":"checkRefundExistanceByOwner()","d8270dce":"creationTime()","d82745c8":"withdrawCooldown(address)","d828435d":"getNonce(address,address)","d8291e97":"CHELSCOIN()","d8294ede":"minimumTimeout()","d82974f8":"moveUnsoldTokensToFoundation()","d829f1e0":"blendWithOthers(address,uint256,uint256,uint256)","d82a6d56":"isOBR()","d82b394f":"createShip(uint256)","d82beb9e":"sender_enode()","d82c6df4":"inactivate()","d82ce857":"getPI_edit_26()","d82e3962":"calculateReward(address)","d82ed7eb":"unwhitelistAddressPresale(address)","d82f6a3f":"maxWeiInvestment()","d82f94a3":"deleteMinter(address)","d82fa3f1":"doInvest(address)","d831a158":"ownerCtuContract()","d831b714":"withdrawDeklaBalance(address,bytes)","d832d0c8":"isFoundation(address)","d833590f":"totalSupplyPretty()","d833c736":"tripleRoomMax()","d833dbe9":"preSaleRate()","d834e619":"min(uint256[])","d834f1e8":"setConfiguration(string,string,uint256)","d8353b75":"vestingDateEnd()","d83616b2":"TokenSaleLockTransfer(uint256,uint256,uint256)","d83623dd":"startDistribution()","d83678ac":"tradeToken()","d8367d41":"startIncomeDistribution()","d836b12d":"getInvestorTokenPercentage(address,uint256)","d836f06a":"VestingKYCSetted(address,uint256)","d836f794":"sellKebabs()","d836fbe8":"changeHatchEscapeCaller(address)","d8381df0":"createCastle(uint256,string,uint64,uint64,uint64,uint64,uint64,uint64)","d8389dc5":"hash(bytes32)","d8392c92":"WithCoin()","d83a223a":"changeFounderWalletAddress(address)","d83a7f67":"getDepositAddress(address)","d83a8d11":"testProposing()","d83aabbe":"getWagerCount()","d83c68b9":"Pilendthereum(uint256,string,string)","d83cb681":"getMixer(bytes32,uint256)","d83d2afc":"leftoverWeiAmount(address)","d83edd70":"refundEth(address)","d83f24a2":"multiMerge(address[],uint256[])","d83fcfa3":"TMN()","d8412808":"HazzaTokenInterface()","d84201bf":"buy5()","d8420e3a":"_isValidWithCompositions(uint256[],uint256)","d8436663":"destroyIBTCToken(address,uint256)","d8439165":"upgradePonyResult(uint8,uint256)","d843dcbb":"ELF()","d843e40a":"getRoundNum()","d843e721":"convertToATK(uint256)","d844a0fa":"TierionNetworkToken()","d845a4b3":"request(uint256)","d8460e8c":"Menu09()","d8464746":"getEyesValue(uint256)","d847e48f":"BlingTokenSale()","d8485ed6":"FCOIN1519Token(uint256,string,string)","d84891da":"EM122()","d8489a81":"MaxDistribPublicSupply_()","d848dee7":"setDeprecated(bool)","d8493983":"GroverBucks()","d849eeba":"gotResult()","d84acf20":"restoreAllTempTokens(uint256)","d84bd737":"xcc()","d84cb6ad":"ETH_Rate_Factor()","d84d2a47":"spreadMultiplier()","d84d95ba":"confirmMultipleTransactions(uint256,uint256)","d84dbdc3":"verifyInvestor(address)","d84f93cb":"priceOfOfficalCardSold()","d84fdbed":"getSponsorships(address,address,bool)","d850288b":"etherlist_top()","d8507a8d":"unfrezee()","d851eb5d":"betPlaced(address,uint256)","d8523fc2":"askForMatch(uint256)","d8526677":"MintMasterTransferred(address,address)","d852748c":"totalPoolOptions()","d8528af0":"allowedSpenders(address)","d85349f7":"cliffDuration()","d8542d51":"oldTokenAddress()","d8550112":"putServerAddress(string,address,uint256)","d855c059":"setExtraConfig(uint256,uint256,uint256,uint256,uint256)","d85633ec":"releaseOwnership()","d8567213":"chargeAll(uint256)","d856cbae":"ICOMinTresholdReached(uint256,string)","d8574e16":"addressD()","d857561d":"enableWithdrawal()","d8578d14":"showPlayerSafeById(uint256,uint256)","d857eba6":"getTagAt(uint256)","d8583895":"getNumberOfDeposits()","d85874b9":"badgerAmount()","d8589be3":"CoinFlipper()","d858b5c8":"order_sell(uint256,uint256)","d858ebf4":"createVisaOffering(uint256,bytes32,bytes32,uint256,uint256,bytes32)","d8590f93":"clearingPrice(address,bytes32)","d8592d79":"closeWormhole()","d85a82f6":"processDIVD()","d85b07e0":"stopIcoAndBurn()","d85b228e":"testCreateGame(string,string,bool)","d85b559f":"startSelection()","d85ba798":"getCutieId(bytes)","d85bd526":"running()","d85c8966":"ownerTransfer(address,uint256)","d85d3d27":"mint(string)","d85d656f":"getSMPTokensAmountPerWei(uint256)","d85d6d41":"finishLocking()","d85e5486":"privateCap()","d85e88db":"item(address,uint256,bool,bytes)","d85edab6":"m_investors(uint256)","d85f4450":"numberOfWins()","d860ced1":"TIER1END()","d86123e1":"setMany(address[])","d8615e5b":"transferAndPay(address,uint256,bytes)","d86202cb":"getUserProductAtIndex(bytes32,uint256)","d8627542":"intialSupply()","d862b611":"extraMint()","d8632388":"allPlayCount()","d8632ae3":"sign(uint8,bytes32,bytes32)","d863f7f4":"DigiPeso()","d86491fc":"testReentracy()","d864c322":"changeAccountStorage(address)","d864e740":"committee()","d8650f49":"tokenGenerationLock()","d865897c":"_getHashKey(address,uint256)","d865a374":"instruct_1()","d865ae9b":"hasRole(address,bytes32,bytes32)","d865dc4f":"tokensSoldCount()","d8674554":"tokenTransfertoKYC(address,uint256)","d867bb25":"getONG(bytes32)","d8682e69":"returnTimeLeft()","d86892a7":"setSellerGuarantee(uint256)","d868c718":"scheduleFight()","d8690c22":"isAvailableLockSlot(address,uint256)","d8692f17":"calcMerkleDefault(bytes32[],uint256,uint256,bytes32)","d869c681":"issuedTokenBalance()","d869d86d":"getAmountsForChangeWeight(address,address,uint256)","d86afbbb":"giveItem(address,uint256)","d86b2982":"numbersCount()","d86b3721":"getblock()","d86b8739":"redeemedTokens()","d86bc1b0":"cancelByAdmin(uint256[])","d86c31e5":"BOXSToken(address,address,int256)","d86c5bf7":"angelWheelFinanceSupply()","d86df333":"deleteAccounts(address,address,address[])","d86e1850":"AuditBalances()","d86e762d":"getTotalAmountRaised()","d86e79c3":"createFixedPeriodVpfFactory(string,bytes32,uint256,uint256,int256[],uint256,uint256,uint256)","d86eb3b7":"reservedTokensAddress()","d86ec25a":"setNotaryParcel(uint256)","d86f26f2":"BigBucksToken()","d86f8ccd":"getAccountLockState(address)","d86fb89d":"updateRoundsInformation(uint256)","d871e94b":"tokenClaimWaitingPeriod()","d8730ef2":"getMaxCommunityTokens()","d8737d8a":"buyEthUnit(uint256,uint256)","d873f0d6":"tokenSaleMin()","d874082a":"fundtransfer()","d8743fad":"weiMinContribution()","d87522ae":"pauseEnd()","d8754716":"createNewTankHull()","d87574e0":"airDropPot_()","d87624ba":"buyGrimReapersAgainstEther()","d87692d9":"transferAllAndCall(address,bytes)","d876c9c0":"SECOND_AUCTIONS_INITIAL_PERCENTAGE()","d8772e79":"get_transaction_count()","d8774d99":"restrict(bool)","d8783b04":"PRICE_MULTIPLIER_ICO6()","d8787fde":"nextContract()","d8788e68":"getTokensForSaleCap()","d879380d":"timeoutRegistration()","d879914a":"getBidsLength()","d879e911":"JORDAN()","d87a253b":"registerNameXnameFromDapp(address,bytes32,bool)","d87adaa0":"registerPubKey(address,bytes)","d87b5c29":"getSpawnCount(uint32,int256)","d87bc4cd":"WEGC()","d87bca3f":"VictorieumToken()","d87be21b":"lastBlock_a4Hash_uint256()","d87c3df5":"applyBonus(uint256)","d87c5df6":"assignTokensWallet(address,address,uint256)","d87c5fb9":"balanceOfBuyer(address)","d87c9478":"getStageAverageBonus(uint8)","d87ce037":"round1Cap()","d87d2a66":"ETH_CRWDTOKEN()","d87d2b8d":"BuyMOYTokens()","d87d9a66":"get_account_balance_eth(address)","d87ddccc":"WithdrawEvent(string)","d87e568a":"setHWCDeposit(address,uint256)","d87f8da5":"cancelAuction(uint256,bytes)","d880285e":"sPeriodEndDate()","d880610c":"appendKeyValue(string,address)","d88080ed":"ERC20Standard(uint256,string,string,uint256)","d880b0b0":"LogChangePCWallet(address)","d8819e0a":"maxTrainerLevel()","d8822727":"CarDeregistered(uint256)","d882ad5e":"Valeriumcoin()","d883e789":"PayWins(address)","d8844241":"getTotalCategories()","d884a322":"betMaxAmount()","d886daa2":"revokeAccessDeposit(address,address)","d8879dd8":"isValidString(string,string,uint256)","d8879fdc":"deleteBio(bytes3)","d887ac35":"mUpgradeCostFactor()","d8887efc":"withdrawForTrexdevshop()","d88905fa":"sanMint(string,string)","d8894bb5":"fraction()","d88a3af9":"register(address,string,string,uint256,string,string,bytes32,address,address)","d88ae250":"setProjectsContractAddress(address)","d88b0815":"numberOfCrySolObjects()","d88b2da2":"_registerReferral(string,address)","d88b8676":"addTrustedAccount(address)","d88b9732":"BUXCOIN()","d88bfbad":"ContractDisabledBlock()","d88c271e":"isWhitelistedUser(address)","d88c5237":"VenusCoin()","d88cdbd6":"setMe(uint256)","d88dc1c6":"winner_announced(address,uint256)","d88e92a7":"OmegaProtocol()","d8909e74":"withdrawMyDeposit(uint256)","d8910b70":"getTransferProxy(uint32,int256)","d89135cd":"totalBurned()","d8915fc5":"DCAssetBackend(bytes32,bytes32)","d8916bb9":"etherToWei(uint256)","d89397b1":"btcsBuyRecipient(address)","d893b9f1":"soldTokensPreSale()","d894e937":"setSomeValue(string)","d894f861":"costFunds()","d895530c":"getCurrentCandidateForPrize()","d8959512":"getConnectorBalance(address)","d8966ad3":"getTombByOwner(address)","d896dd64":"setStatus(uint256,uint8)","d89739b1":"Marketplace(address)","d897833e":"setSaleStatus(bool)","d898e1b9":"_depositEther()","d899299e":"realUnicornAddress()","d899d312":"Testimony()","d899e112":"target3()","d89ab6d3":"YouCollectCoins()","d89b465c":"getUnitAttackIncreases(address,address,uint256)","d89b8057":"setOscar(address)","d89b908d":"checkFundingCap()","d89bcaaa":"BATsPerEth()","d89cca38":"assignLawyer(string)","d89d4404":"_payEther(uint256)","d89dc0ad":"MarketOpen(address)","d89ea0f5":"setClearingPriceComponent(address)","d89edecf":"returnAmountPlusInterest(uint256)","d89ef018":"addUsersWhitelistA(address[])","d89f9719":"getOrderOtherArguments()","d89fb919":"episodePurchase(uint256,address,uint256)","d89fda34":"Fish()","d89fec58":"aboutCurrentPack()","d8a0aa6c":"getPositionById(address)","d8a119b9":"ownerSetVisible(string,string)","d8a140f9":"peony()","d8a1e70a":"widthrawDev()","d8a2848d":"setPaymentEscrow(address)","d8a351de":"_getDefaultPartitions(address)","d8a3daa0":"createEntry(uint256,uint256[])","d8a3f0bf":"getFactoryPrice()","d8a489d9":"pauseTournament()","d8a506f3":"thirdStageDiscountPriceOfTokenInWei()","d8a52178":"ContractManager()","d8a54360":"totalRemaining()","d8a5cca1":"Finalised(address,uint256)","d8a6021c":"transferTreasury(address)","d8a7233e":"addBook(string,string)","d8a74c7c":"getGamblingPartySummarizeInfo(uint256)","d8a74f3b":"ThrowError()","d8a79d87":"wolf3Balance()","d8a865f6":"getElementAt(uint256)","d8a8e03a":"move(uint256,address)","d8a9e45e":"getProductContractUser(address)","d8aa9f85":"totalForOutcome(uint8)","d8ab8274":"getStates()","d8ab9208":"addressByIndex(uint256)","d8aba1c6":"partFees()","d8ac1bb3":"buyTokensReferral(address,string)","d8ac26c0":"ForksTestContract()","d8ac289f":"frozenWallet4y()","d8ac5b4e":"tokensPerCents_gte5kUsd()","d8ad1c5c":"getCapAmount()","d8ae6139":"WavesPay()","d8aeedf5":"freezingBalanceOf(address)","d8afc2fe":"getAdminVariables()","d8afd392":"advisorySupply()","d8b0403a":"Bithemoth(address,address)","d8b0b499":"country()","d8b11d54":"AddItemExtra(uint32,uint16,uint256,uint16,uint16,string,address)","d8b120c1":"getMeshPointByName(int256,string)","d8b163d0":"eventsAdmin()","d8b29324":"unlockAmount(string,uint8)","d8b3315f":"public_withdraw(uint256)","d8b3a2eb":"isOdd(uint256)","d8b3ad77":"setDateTimeLib(address)","d8b3d69a":"getVendorApplicationScoringTrack(string,uint256)","d8b3e417":"USD20TestToken()","d8b4e580":"uploadBalances(address[],uint256[])","d8b50a63":"addAction(string,uint256)","d8b5cf43":"beneficiary_modify(address)","d8b66ae1":"sendTokens(address[],uint256[])","d8b79543":"FxxkToken()","d8b86753":"getOrderCount(address)","d8b964e6":"approved(address)","d8b98118":"CRLperEther()","d8b98fca":"AirDrop(address)","d8b9a2a0":"addContract(address,address,uint256)","d8b9a7e8":"CLC(uint256,string,string)","d8ba6de2":"Endorsements()","d8ba8ce3":"setNextDiscountTTMTokenId6(uint64)","d8baa905":"getAreaEvaluation(address,uint256,address)","d8bad5bd":"userLoans(address,uint256)","d8bbae03":"getTransferValueFor(address)","d8bd4761":"createCurrency(string,string,uint8,uint256)","d8be2838":"unSuspend(address)","d8be30fc":"getUserMessage(address)","d8bea898":"addReferredInvestor(string,address)","d8bf0568":"level1Bonus()","d8bf0ef8":"finishBurning()","d8bf1773":"calculatePoohBuySimple(uint256)","d8bf63b7":"START_BLOCK_NUMBER()","d8c02572":"Gallery_MuYi_No2()","d8c1c3c2":"getNumberOfTx(uint256)","d8c1fad1":"StakeIt()","d8c251b5":"isNotRegistered(address)","d8c2c1c1":"getcoeffcient(address,uint256)","d8c2c878":"PlexCoin(uint256,string,uint8,string)","d8c30700":"getCurrentCap()","d8c34127":"isKnownSignature(string)","d8c35273":"getHumanNumber()","d8c37ecd":"calculateMarketPixelPrice(address[16],uint256)","d8c3c1ed":"finalizeIto(uint256,uint256,uint256)","d8c42e42":"doublePrice(uint256)","d8c4661c":"getNID()","d8c4c34e":"KaraOmToken()","d8c4cd7d":"saveStudent(uint256,string,string,address,address)","d8c57892":"getDecision(bytes32)","d8c5c6f8":"disapproveInternal()","d8c65cbb":"_setEyesValue4(uint256)","d8c6bd6f":"checkMine(uint256)","d8c90762":"addTrustedIssuer(address,string)","d8c929a8":"getCurrentRoundRewards()","d8c9334b":"TextChanged(bytes32,string,string)","d8c94cd5":"_addToken(address,uint256)","d8c97f34":"transferFromVest(uint256)","d8ca713a":"getStringMember()","d8ca8a55":"distributeIQTTokenBatch(uint256)","d8cb2d4a":"STOCoin()","d8cb4aa3":"bonus(address)","d8cb52d3":"getFreeRabbit(uint32,uint256,uint8,bytes32,bytes32)","d8cba0ba":"transferWallet(address)","d8cba7a2":"phase3Cap()","d8cbce53":"calculateDividendsFor(address)","d8ccd0f3":"free(uint256)","d8cdac0d":"window0StartTime()","d8cecc7b":"MdedicalChainCoin()","d8cf9184":"getServerCreationFee()","d8cfd15a":"LogB(bytes32)","d8cff716":"NBAT101(address,address,address,address,address)","d8d07637":"poll(uint32)","d8d0819f":"CoinVilla()","d8d1d507":"whiteListContracts(address)","d8d1efea":"releaseTimeSecond()","d8d34c89":"ManualTransfer(address,uint256)","d8d3b1a4":"TIER1()","d8d40cee":"gameNumber()","d8d45d13":"setShipping(string)","d8d4a75e":"AUD_Omnidollar()","d8d4ec02":"checkVesting(address)","d8d5740c":"XMLYToken()","d8d5a200":"payBountyManager()","d8d736c5":"_makeDepositForPeriod(bytes32,uint256,uint256)","d8d777f2":"_attack(uint32,uint8,uint64)","d8d8e2f2":"test_23_assertGasUsage200Boards()","d8d9159d":"pr0coinAddress()","d8da3bc0":"getCurrentPotSize()","d8da708f":"preico_enddate()","d8db583f":"getFreelancerSkills(address,address)","d8dbb475":"JSONpath_string(string,string)","d8dbb712":"OfferCancel_internal(uint8,bool)","d8dbe4c9":"setContractManager(address)","d8dd2b79":"emitTransferFeeRateUpdated(uint256)","d8de5a41":"splTransferFrom(address,address,uint256,uint256,uint256)","d8df44fd":"maxTimeBonus()","d8df5dc1":"lockAmount()","d8df9aad":"setDayWithdrawCount(uint256)","d8e09dac":"setTrustee(address,bool)","d8e1b9ba":"explore2(uint256,address,bool)","d8e20e2c":"brickPrice()","d8e223b5":"issueMedal(address)","d8e2e392":"admin_set_isRequireData(bool)","d8e30740":"ETH_RECEIVED_CAP()","d8e3c1c8":"buyPlatinum(uint256,uint256,uint8,bytes32,bytes32)","d8e3c33f":"gridToIndex(uint256,uint256)","d8e476ab":"icoPhaseDiscountPercentage2()","d8e4ab0d":"isOmegaContract()","d8e4f9d9":"teamTwo()","d8e5ae6a":"Etheramid()","d8e5c048":"scheduleCall(address,uint256,uint256)","d8e5c797":"concat(string,string,string,string)","d8e5e64e":"getAsAddressOrZero(bytes32)","d8e60616":"OFNOG()","d8e6b249":"findPossibleDelegatorsOf(address)","d8e71b35":"ico3receivedTotal()","d8e74ed7":"monsterStrength()","d8e86854":"setPrices(uint256,uint256,uint256,uint256)","d8e8752a":"resetUsedToday(uint8,uint8)","d8e8b177":"interestOf(address)","d8e9602b":"tierCap(uint256)","d8e963b3":"PRE_ICO_END_TIME()","d8e97a56":"averageTimestamp()","d8eb3a98":"withdrawAuctionBalance()","d8eb6af3":"redeemEthers(address,uint256)","d8ebfe5a":"interaddmoney(address,uint256,uint256)","d8ec55ed":"meh()","d8ec696f":"__address1__()","d8edbd79":"ZTToken()","d8ee2ff4":"_buys(uint256,uint256)","d8ee796f":"founderAllocatedTime()","d8eea572":"getMinInt64()","d8eebd8d":"spentBalance()","d8eef28b":"ordersFor(uint256,uint256)","d8f012c6":"StatelessFactory(string,string,string)","d8f06b52":"closeAfterWhitelisted(address)","d8f0b9c4":"amountToBeneficiary()","d8f0c358":"getSetupParametersCount()","d8f163ab":"totalTokensDistributed()","d8f248b8":"getForge(uint256)","d8f2cd12":"onceSetOwners()","d8f2f09f":"china()","d8f306a1":"setAvailableToken(uint256)","d8f342be":"getBTCETH(uint256)","d8f3790f":"ethBalance(address)","d8f42fca":"SzeToken(address,address)","d8f45fdb":"LICToken()","d8f5d098":"privateUnlock(address)","d8f6d596":"getSale(uint256)","d8f6dcf2":"getTaskById(bytes32)","d8f71809":"MAX_COMMISION()","d8f9659b":"withdrawnTokens(address[],address)","d8f9d144":"changeOwner(string,address)","d8f9e51b":"EkoBeerCoin()","d8fa191b":"setProviderDetailFields(uint256,bool,bool,uint256)","d8faefc9":"fixDistribution(uint8,uint256)","d8fbbf31":"removeContractFromWhiteList(address,uint256)","d8fbe994":"transferFromAndCall(address,address,uint256)","d8fbff9f":"createDroneFromVault()","d8fce0d4":"pinchVillain(uint256,uint256)","d8fcfd6b":"convertRealTo256(int128)","d8fd1ed9":"creatorReward()","d8fd2043":"getSkullyById(uint256)","d8fd7ae3":"subtractAllowed(address,address,uint256)","d8fe1558":"BaseICOTokenWithBonus(uint256)","d8fe511f":"tithes()","d8fed39e":"tokenSoftcap()","d90025d1":"DIVIDEND_FUND_FRAC_TOP()","d900a6ae":"hgtSold()","d901402b":"getCommitHash(address,uint256)","d9019530":"request(address,uint32)","d901b98c":"test_1_generationAcrossBlocks_increaseBlocksBy100()","d902ac2e":"insert_data()","d9037441":"setEthFundDeposit(address)","d9037522":"removeVoter(address,string)","d903c5ae":"minimumTDEContributionInWei()","d904094e":"ownerCancelArmyMarketplace(uint256)","d9057007":"supportsInterface(address,bytes4)","d9067fbd":"initCongress(address)","d9076129":"secondBonusPercent()","d907e02e":"_cancelBet(uint256)","d9082962":"totalRefunded()","d9089b11":"_processDividends(uint256)","d9099f67":"endPreICOStage3()","d90a8224":"getNumberOfSuccessfulDeals()","d90a88cd":"getContentReplies(uint256,uint256)","d90b02aa":"left80(uint256)","d90b4958":"completeProject(bytes32)","d90c1759":"dayFor(uint256)","d90c2861":"Albertheijn()","d90cdfb4":"getCanvasInfo(uint32)","d90d5b58":"copyright(address)","d90d870b":"adminSetPercent(uint256)","d9106264":"clearAuth(string)","d910c805":"MAX_POWERBALL_NUMBER()","d9114476":"addAudit(bytes32,uint256,bytes32)","d912d248":"transfertOwnership(address)","d912ebb2":"tokensIssuedIco()","d9134c46":"isGlobalConstraintRegistered(int256,address,int256,address)","d9135493":"AdPotato()","d913dea2":"UsdRateSet(uint256)","d9144448":"upgradeProposal(address,address,address,uint256)","d9144712":"numberClaimToken()","d914cd4b":"addPool(address)","d915562b":"isControlled()","d9159f60":"sealedBy()","d915cdbd":"investBalances(address)","d916d8fd":"getPlayersCountByGame(uint256)","d916ec32":"getEmissionProviders()","d917863e":"addExchangeTestAccounts(address,address)","d9178993":"maxPeriodDuration()","d917deb5":"Donate()","d91921ed":"addBalance(uint256)","d9194d2c":"toggleTransferable(bool)","d9194fcb":"setCEO(address,bytes)","d91aee02":"getTotalGamesParticipated()","d91c98d3":"startingBlock()","d91ca13e":"EquinoxCoin()","d91d81c6":"preIcoEndAt()","d91dc952":"timeLock(address,uint256)","d91e1c63":"totalGambles()","d91e24c2":"TIMEToken(address,uint256)","d91f3f33":"BookERC20EthV1Dec()","d91f68a2":"currentMessageNumber()","d92126fc":"NewFees(uint256,uint256,uint256)","d9214848":"CONFIGURE(bytes32,bytes32)","d921eb78":"isRefund()","d922aa30":"core(uint256,address,uint256)","d922b6ab":"stage_1_tokens_scaled()","d922cd12":"InsightChainToken()","d922d5c8":"TimeLockedController(address)","d922f603":"Purpose()","d923a0be":"setLoyaltyWallet(address)","d923c99e":"getRecordByRow(uint256)","d9244bf9":"maximumHodlDuration()","d9246bec":"activateICO(uint256)","d9249e7e":"PuppiesCore()","d924c660":"shift_right(uint32,uint32)","d9269cb4":"at_permille(uint256)","d92782ac":"sumICOStage5()","d927b5ad":"addDistributionPeriod()","d928a3d8":"_getSchellingRoundSupply()","d928e32e":"ERC20Basic(string,string,uint8,uint256)","d9296e45":"totalWeiFunded()","d92c4f7c":"AirContactToken(uint256,string,uint8,string)","d92ca5b4":"tokensTeam()","d92d5bb3":"ADSToken()","d92d7056":"option20name()","d92da722":"processBuyRequestFiat(string,uint256,address,uint256,uint256)","d92da8f8":"bountySupplyRemaining()","d92dc325":"MintAndTransferToken(address,uint256,bytes32)","d92ebe46":"createDAO(address,uint256,uint256,uint256,string,string,uint8)","d92ec71b":"addDeal(uint256,string,string,uint256,bytes32,string)","d92ed48d":"rebalanceBuckets()","d92fb5e9":"newClaimer()","d9300e30":"checkIfAllALCDistributed()","d9305ba7":"LOG_OwnerDeposit(uint256)","d930a90b":"testFailMoveBalanceDueToInsufficientFunds()","d93112e3":"totalEarlyStage()","d9326337":"PiaoPiaoToken()","d932b248":"AssetISR()","d932ed92":"MarriageCertificates()","d933b5f2":"SLABSToken()","d933c1fb":"XYOracleBonus()","d933dac7":"view26()","d9359419":"payoutERC20(string)","d935bac3":"test1Vote()","d935c8b4":"totalEthSales()","d935e0a7":"BBCC(uint256,string,uint8,string)","d936547e":"whitelisted(address)","d9368ba2":"getUserOptState(address,address)","d93761fb":"transferSKM()","d937ed44":"grantVestedEDEXContract()","d9386789":"coreTeamMemberTwo()","d9386c9f":"cofounderVUPDestination()","d939727d":"setMaxTokenNumbers()","d939c960":"fundRecipient()","d93a0a8e":"newClassPlayer(uint256,uint256,uint32,uint32,uint32,uint32,uint32,uint32,uint32)","d93a64a2":"updateDebris(bytes32,uint8,bytes32,address)","d93b4451":"Authorise(bytes16,address,address)","d93d6ad0":"isKeyHolder(address)","d93da7f0":"ROUND_5_PRESALE_BONUS()","d93dbeff":"calculateLevel(bytes8,bytes5)","d93debd5":"registerDappAddress(address)","d93e5aeb":"count_next_address(address,uint256)","d93e7573":"disown(bytes32)","d93eeb5c":"safeTransferManyFrom(address,address,uint256[],bytes)","d93ef85f":"Photos()","d93fabfa":"addSeller(address)","d94073d4":"PT()","d94085cc":"FindMyFish_EnterBarcode(bytes32)","d9409bc5":"WFCC()","d940c3ee":"processPayroll(address,uint256)","d94123b8":"channel_api()","d94178c2":"getvalue(string)","d9417b6a":"balanceWosPoolToWosSystem()","d9417d69":"wikiRemoveTokenFrom(address,uint256)","d941c4ad":"prepare(bytes32)","d94288de":"totalFeatures()","d94389bd":"__char(bytes1)","d94395e2":"lastCitizenPaid()","d943c8b6":"oldHolders(address)","d9441f14":"playerMsgs(uint256)","d944534a":"generate(uint256,address,string)","d944c749":"ADVISOR_FOUR()","d945799f":"removeLockFund(address)","d94585bd":"proveAndClaim(bytes,bytes,bytes)","d9468475":"findRecentInterest(address)","d946af8f":"addNodeAddress(uint256,address)","d9474ad7":"unlockedProvider(address)","d9479692":"contract_name()","d947c8d1":"transferSketch(address,uint256)","d947e234":"offerGuardianVend(uint256,uint256)","d948d468":"forward(bytes)","d94929fe":"setTokenSaleRounds(uint256[5],uint256[5],uint256[5],uint256[5],uint256[5],uint256[5])","d94a0a7d":"findNextwaitPairBetIDs(uint256,uint256)","d94a75bc":"MELON_CONTRACT()","d94acc0a":"distributeVSN(address[],uint256)","d94b9843":"toContractAddr()","d94c7c29":"updateTokPerLockRate(uint256)","d94ca0f9":"approvePrimordialTokenAndCall(address,uint256,bytes)","d94d0316":"timeIncrease()","d94d0787":"EthlyteToken()","d94fd026":"applyPixelChange(uint256,uint256,uint256,uint256,uint256[])","d94fe832":"idOf(address)","d95030cb":"ticketTransfers(uint256,uint256)","d9506c5f":"startSettle(bytes,uint8[2],bytes32[2],bytes32[2])","d950aec6":"splitWinnings(uint256)","d950c432":"multiFreezeWithTimestamp(address[],uint256[])","d950cc3c":"getUserCap()","d9510215":"withdraws()","d9515238":"forward_funds(uint256)","d951d39a":"tokensIssuedForBonusRangeThree()","d951e357":"bonusFourthWeek()","d9520c9a":"allTokenOwnerOnStart()","d9527fa7":"buyShares()","d95374ce":"pendingJackpotForHouse()","d95402e7":"Redeem()","d95405f2":"lockTokenDays(address,uint256,uint256)","d95425e6":"TXwithCode(bytes32)","d95431cd":"lookupFeaturedSprites(uint256)","d9548e53":"isExpired(uint256)","d954a949":"setDeal(address,bool,uint256,uint256,uint256)","d954af09":"revealBid(bytes32,uint256,address,address,address,uint256,uint256)","d954bd4a":"ICO_TIER_LAST()","d954cbcb":"amountInvested()","d95514a8":"Regulator()","d955ec17":"setMiniumInputEther(uint256)","d95660be":"timeNow()","d956634f":"claimTokensAndRefund()","d9573c1a":"taxEth(uint256,address)","d9575ec5":"registerNameXID(string,uint256,bool,uint8)","d95808f0":"lastBlock_f3()","d9583497":"acceptFulfillment(uint256,uint256)","d9592676":"packKey(uint8,uint128)","d9597016":"multisetCustomGasPrice(uint256[],address[])","d95983c3":"Destroy(address,address,uint256)","d959868a":"total_no_of_CTD()","d959cbd2":"fMul(uint256,uint256)","d959e244":"left25(uint256)","d95a0aa5":"setDirectMintLimit(uint256)","d95a2d42":"lendGovernmentMoney(address)","d95a820f":"LogStartPreICO()","d95ab72d":"getMemberWallet(address)","d95ace6f":"checkSigned(bytes32,uint8,bytes32,bytes32)","d95b6371":"isOperatorFor(address,address)","d95c6092":"StartreasureToken(uint256,string,uint8,string)","d95efb98":"genesisAddress(address)","d95ffc08":"myEthBalance()","d9606ca1":"WINE(uint256,string,string)","d96073cf":"swap(uint256,uint256)","d960924d":"dtAddEthBalance(address,uint256)","d960ede1":"sectionPrice(uint256)","d96152c3":"executeRuling(uint256,uint256)","d961de44":"domainConnector(bytes32)","d9629e06":"casinoGames(uint256)","d962a68b":"buyTokensByUSD(address,uint256)","d962c51e":"redeemByTranche(bytes32,uint256,bytes)","d962dd99":"setCompte_43(string)","d9637826":"safe_sub(uint256,uint256)","d964f28a":"TokenAiNetworkToken(address,address)","d9652cb1":"startTimestampOfBonusPeriod()","d965ea00":"getMemberLength()","d9663f6a":"START_PREICO_TIMESTAMP()","d966cfc3":"totalAllocatedToAdvisors()","d967f752":"rentMachine(address,uint256,uint256,uint256)","d968595f":"isValidProposal(uint256)","d968dab1":"chipBalanceOf(address,address)","d9696054":"readInfoList(address,uint256,uint256)","d969b919":"Etherplanet()","d969ead4":"countpro(uint256)","d96a094a":"buy(uint256)","d96a22b8":"windowBonusStep1()","d96a8687":"XMPToken()","d96aee49":"MultipleConstructorTest()","d96bcd8f":"randomTargetAssign()","d96bfbb3":"resetUser(uint256,address)","d96c0991":"quitFromAirdrops()","d96c26c9":"submitTransaction(address,uint256,bytes,bytes,bytes)","d96c30a4":"checkTime(address,uint256)","d96c550a":"_preValidatePurchase(address,uint256,uint8)","d96cb018":"icoCap()","d96cc905":"toB32(uint256,uint256,bytes,address)","d96d7ea2":"PRE_EXECUTION_GAS()","d96db2ec":"OfferToRealm(uint256,uint256)","d96de4ce":"AdminDrawError()","d96e1f76":"icoStatus()","d96e5565":"testThrowsRetractNotRetractable()","d96ed505":"minGasPrice()","d97036c2":"ARM1Token()","d9703dac":"getResoMethod()","d97049bb":"regs(uint256)","d97095f3":"AST()","d970c19b":"raiseCoinsSeeded(address,uint32,uint256,uint256)","d9710278":"TwoFucksToken()","d9719e56":"CROWDSALE_SHARE()","d971da94":"priceUSDcETH()","d972bc59":"setICO_Contract(address)","d972e8ad":"getTranche(uint256)","d972ea3e":"dragon()","d9740383":"SAWJewelleryChain()","d9741bd9":"PinMoToken()","d975767b":"eLitecoin()","d975f3b7":"withdr(uint256)","d977076e":"getExtraBets()","d9779fbe":"currentTokenSupply()","d977a59c":"getCurrentRateByStage()","d9784223":"getEscrowAndHash(bytes16,address,address,uint256,uint16)","d9785451":"timerMax()","d978a0d3":"setFinancialOfficer(address)","d9795f66":"usersNTD()","d9797076":"CoinBroSupply()","d979e906":"getXNKPurchased()","d979f5aa":"setHolder(address)","d97a9c39":"resetContent(string,address,string,string,string,uint256,uint256)","d97b0a6e":"Workcoin()","d97b14f0":"sendAdvisory(address,uint256)","d97c5be5":"losePooling()","d97cec3f":"transferMultiSameValue(address[],uint256)","d97cf075":"onlyBouncerExecuteCall(address,uint256,uint256,bytes)","d97d4f52":"FOUNDERS_LOCK_DATES(uint256)","d97dec19":"transferAll(address,address,uint256,address,uint256,uint256,address)","d97e38d6":"getApprovedBuyerForIndex(address,uint256)","d97fc929":"CommitSolutionHash(bytes32)","d9803cb2":"addOfficer(address)","d9823996":"withdraw(uint152,address,uint256)","d982466d":"getPlayerAwardByRndNo(uint256,address)","d98299a0":"RedBlue()","d9829cbc":"getRewardAndPrepareWithdraw()","d982a84e":"citadelAddress()","d9844e25":"hexAddress(bytes32)","d9852ca9":"nbDispute()","d985f122":"RelayToolsTest()","d9875c93":"stageNow()","d988a0f9":"Payoutnextrefund()","d989f5f2":"productOwners(address,uint256)","d98a977d":"TestWorldSnapshotInternal(uint256)","d98ae811":"transferDay(uint16,address)","d98b094c":"communityPeriodsNumber()","d98b2fbf":"getOverviewsCounter(uint256)","d98b43f7":"removeOracleAddress()","d98b9bb5":"placeBid(address,uint256)","d98bce37":"batchBurnAssets(uint256[])","d98bf529":"LimitTop()","d98c08b5":"CryptaurDepositoryTest()","d98c1524":"getPortfolio(bytes32,address)","d98d011d":"getCandidateKey(bytes,bytes,bytes,bytes)","d98de8a5":"isCrydrViewRegistered(string)","d98e14bd":"STAT_COUNT()","d98e2997":"addMiningToken(address,uint256)","d98f47fe":"recieveEscrowTransfer(address,uint256)","d98f4ea2":"sumICOStage7USD()","d98f6088":"blockDelay()","d9901ce4":"DappToken(uint256)","d991c58f":"mintMaster()","d9923a16":"Account_timePayout(address)","d992aa70":"createBounty(string,uint256[])","d992bd5b":"testResultNotZero()","d9934a8c":"holdAddress4()","d993693c":"LOTTYcoin()","d9946793":"shareHolderBalanceOfAtTime(address,uint256)","d9946a79":"PERSONAL_CAP()","d9948af7":"sumICOStage1USD()","d9964d92":"getResourceName(uint16)","d9969061":"prove(bytes32,uint256)","d9971e92":"reject(uint64,string)","d99727cc":"removeBonus(uint8)","d9972b96":"isAuthorized(address,bytes4)","d997598b":"HoChiMinh()","d997933f":"canBreedWith(uint40,uint40)","d997a153":"transferBatchIdempotent(address[],uint256[],bool)","d997ccb3":"payMe()","d9987c07":"ReturnToOwner(address,uint256)","d998d0d5":"chunkNr()","d99929db":"getAssetIdTypeSequenceId(uint256)","d99969df":"DUNE_BUGGY()","d999741e":"grantFoundationToken()","d999b17e":"CROWDSALE_PHASE_3_START()","d999f132":"optionDescription(uint256)","d99a8dc3":"submit(string)","d99a9d20":"_setTransferFeeProp(uint256)","d99bb9f7":"removeOwnership()","d99c6c76":"_invest(address)","d99d83e3":"txsPerHour(uint256)","d99dbdbe":"changeBookState(uint256,uint256)","d99dd314":"companyTimeLock()","d99f8bd8":"VarnixToken()","d99fe20d":"dexTestApprove(address,address,uint256)","d9a0b299":"deactivateClaim()","d9a18f6d":"totalTokensForSaleDuringICO1()","d9a19a7a":"MMOTOKEN()","d9a2a083":"TeamWalletUpdated(address,address)","d9a2fff5":"airDropPercent()","d9a3988d":"LogPollApproved(bytes32)","d9a3c199":"testSaleToken()","d9a457fe":"endRound(address)","d9a4ad8b":"shouldHadBalance(address)","d9a4cc33":"_finalizeSale(bool)","d9a50120":"SaniCoin()","d9a52ab3":"getForkMigrationPercentageBonusDivisor()","d9a569f5":"OfferPlay(address,uint8,uint8)","d9a57382":"propertyIdToEscrow(uint256)","d9a5b0a7":"testHighestTranchNotExact()","d9a6c6db":"FactbarDeed()","d9a6cf81":"transferableUntil()","d9a6e2de":"VST(string,string,uint8,uint256)","d9a7556f":"indexThreads()","d9a8748c":"fundAccount()","d9a8e212":"GOLDQ()","d9a96c92":"LegalToken()","d9a96f9b":"saleManagerAddress()","d9aa1881":"tokenDestroyed()","d9aa5543":"newDoc(bytes32,uint256,string)","d9ab1ec9":"smallCount()","d9aba9ce":"getProduct(address)","d9abedb4":"take_fees_eth_dev()","d9ac03a6":"getCurrentCertificateNonce(address,address)","d9ac9a88":"getAuctionTotal()","d9aea707":"modifyCeo(address)","d9af3691":"verifyCertificate(address,uint256)","d9afa38b":"payDividends(address,uint256)","d9b02ddf":"setGeneral(uint32,uint8,uint8,uint16,uint16,uint16,uint16,uint32[4],uint32[4],uint8)","d9b058bd":"setOraclizeGasprice(uint256)","d9b158b1":"angelInvestorsWallet()","d9b238ea":"test_insert_findWithHintNotTightBound(int256)","d9b25a24":"proxyBuyTokens(address)","d9b36043":"TJFucks()","d9b4abf5":"marketplace_controller_v2()","d9b5134c":"getTotalExchanged(address)","d9b5618c":"TimeBroker()","d9b596c7":"generateRand()","d9b5b5ca":"exponential(uint256,uint256)","d9b5c4a5":"nodeRegistry()","d9b627dd":"CancelledByBuyer(bytes32)","d9b6aec4":"allInvestments()","d9b6b197":"tempAdvisorsTeam()","d9b7d154":"applyForTask(uint256)","d9b7d41b":"createFootballer()","d9ba32fc":"getWhitelistStatus(address)","d9ba8ea4":"finishLastRound()","d9bb57c6":"removeGameManually(address,address)","d9bb6102":"HealthCashMock()","d9bc9873":"getCanvasPaintedPixelsCount(uint32)","d9bcc65b":"setSeedContract(address)","d9bccfd6":"getWarrantyPrice(address,uint256,uint256,uint256)","d9bd0799":"clearPeriods()","d9bd2468":"getToken(uint256,address)","d9bdc10c":"getPlayerHasGetFree(address,address)","d9bdd6fa":"createCDPLeveragedAllDai()","d9be976c":"GainmersTOKEN(uint256,uint256,address)","d9bf3187":"setOutcome(int256,uint8,bytes32,bytes32)","d9bf8238":"setWinery(address,bool)","d9bfa73e":"orderEpoch(address,address)","d9c01911":"mintIdentityToken()","d9c090a0":"updateRoleName(address,bytes32)","d9c1a344":"balanceTotalOf(address)","d9c1ac25":"transferAllERC20Token(address,uint256)","d9c24acb":"_unlockedAmount(uint256)","d9c263f8":"purchaseWithEth(uint256,uint256,uint256,address,bytes)","d9c27cc6":"setPep(address)","d9c3193d":"setSpaceshipPrice(uint16,uint256)","d9c397f6":"gmtFund()","d9c39fca":"setSilverContractAddress(address)","d9c3d3c9":"checkReturn()","d9c4870e":"beneficiaryAddress()","d9c522ec":"daiRate()","d9c52d27":"getDiscountTrancheEnd(uint8)","d9c55ce1":"fill()","d9c57bcc":"importExchangeSale(uint256,address,uint256)","d9c67404":"getMerkleRoot(bytes)","d9c682a7":"borrowerReturnFiatPerEthRate()","d9c6925e":"AccountIsNotFrozenForReturn(address)","d9c693cb":"emergencyLock()","d9c7041b":"ownbalance()","d9c76d61":"coolHero()","d9c779ce":"_buyP3D(uint256)","d9c7ddfa":"_updateBurnRate()","d9c850f4":"getItemKindCount()","d9c88e14":"ownerWithdraw(address,uint256)","d9c97699":"__callback(bytes32,string,uint256)","d9ca0b7f":"transferRoutingCode(bytes32,address)","d9caa3d2":"submit(bytes32)","d9caaada":"minPreContribution()","d9caed12":"withdraw(address,address,uint256)","d9cba1a1":"MulTraToken()","d9ccf695":"strayToken()","d9cd6046":"BuyTicketSeed()","d9cd98b0":"withdrawDevFees(address)","d9ce2451":"setLeaf2(uint256,uint256)","d9cea519":"getDealInfo(uint32,uint64,uint64,uint64)","d9cfc182":"getHighestPriceAt(uint256)","d9cff93a":"last_result(address,address)","d9d0b091":"AddMarking(bytes32,bytes32,int256,uint256)","d9d14d37":"numOfMiningTimes()","d9d1ceaa":"draw(uint256,bytes32[])","d9d1d4bb":"getCompte_28()","d9d1e0e5":"createBlock(uint256,uint256,bytes32,bytes32,bytes32,bytes32)","d9d1f5d9":"removePendingExplore(uint256,uint256)","d9d210b8":"changeHelper(address,bool)","d9d2d058":"Splitter()","d9d34ce1":"isForkingMarketFinalized()","d9d3cc78":"seriesByName()","d9d578e5":"airDropSetup(address,uint32,uint256)","d9d60b52":"getGameState(address)","d9d61655":"getOwnedTokens(address)","d9d61a10":"GetUserSafesLength(address)","d9d73887":"Diana()","d9d770bb":"_triggerPVEStart(uint256)","d9d84531":"getRemainingKingdoms()","d9d8b2ee":"creationInvestmenting()","d9d958ec":"setUint8(uint8,uint8)","d9da0142":"cancelEscrow(bytes20)","d9da2738":"changeOfficialAddressIfNecessary(address)","d9da486a":"initialEcologyAccount(uint8)","d9da76de":"DailyMint()","d9daa497":"getStageTargetAmount(uint256)","d9daae78":"CCH_Seaport_1()","d9dac92c":"acceptDiscipleVend(uint256)","d9dad80d":"ownerOf(uint256,uint256)","d9db1f55":"deprecate(string,string,string)","d9db9d89":"globalSupplyAfterPercentageLogic()","d9dbd382":"FUTX()","d9dc7fcd":"EVM()","d9ddafb3":"exchangeTransfer(address,uint256)","d9de1e98":"HuuumanStandardToken(uint256,string,uint8,string)","d9def89a":"buyShitClones()","d9df2878":"CryptoCollectorContract()","d9e0dc59":"getLocation(address)","d9e19a91":"setAccountValue(uint16,uint8,uint8,int64)","d9e34038":"ODCToken()","d9e39e50":"getTransferDetails(address)","d9e4fa6a":"setUsdPerKEther(uint256)","d9e50186":"setWeiMin(uint256)","d9e55f7a":"getAllowedToMine(address)","d9e5a50b":"getSnakemasterReq()","d9e68b44":"left100(uint256)","d9e73095":"MiracleToken()","d9e79c72":"admin_dividend(uint256)","d9e7c8ca":"createRace(uint256,uint256,uint256)","d9e7ee1c":"new_game(uint256,uint256)","d9e8843f":"payRent(uint256)","d9e947f3":"kickOutMember(address)","d9e95a98":"addVoter(address,string)","d9ea1b47":"Raffle_Finished()","d9ea372b":"myfichain()","d9ea9bfa":"createBtcAddressHex(uint256,int256,uint256,int256)","d9eac337":"MegaWattContract()","d9ead22b":"accountForClose(uint256)","d9eb547b":"extractCLNfromMarketMaker(address,uint256)","d9eb5947":"flatFee()","d9ec0508":"testThrowTransferNotEnabled()","d9ec3018":"submitSpendLimit(uint256)","d9ece4c7":"changeMaximumContributionForPrivatePhase(uint256)","d9ee369a":"withdrawDifferentToken(address,bool)","d9ef1ee3":"insert(string,uint256)","d9ef58a5":"thisAddr()","d9f00023":"SBGToken()","d9f01878":"centralMinter()","d9f02210":"StarbaseMarketingCampaign()","d9f0354d":"buildMilestone(uint256,uint256,uint256)","d9f035aa":"cardList(uint256)","d9f0cf04":"createAuctionWhenPaused(address,address,uint256,uint256,uint256,uint256)","d9f165dc":"updateFactory(address)","d9f1a1a9":"PublicBallot(address,string,string)","d9f2ac8a":"decr()","d9f300ce":"referedRateBonus()","d9f38388":"RequirementChanged(uint256,bytes32)","d9f3afff":"addCurrency(string,uint8)","d9f47e41":"totalDevelopmentFundBalance()","d9f4ecbb":"lastProfit()","d9f4f56e":"_ethRefund()","d9f58923":"GlobalConstraintRegistrar()","d9f69e4e":"addUserWhoBuy(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","d9f754a3":"LogSetWithdrawLimit(address,uint256)","d9f7e285":"returnExcedent(uint256,address)","d9f7eacf":"removeGains(address,uint256)","d9f80c65":"setMinInvesment(uint256)","d9f81b83":"timeWithoutUpdate()","d9f861b1":"getFreelancerInvoices(address,uint8)","d9f884bf":"BIONICCOIN()","d9f8a3c3":"lastTransactionReceivedInWei()","d9f8a4e2":"calcCurrentTokenPrice()","d9fa1e78":"PractiParlezCrowdSale()","d9fa8c54":"unClaimedToken(address)","d9fa9335":"houseKeeping()","d9facbe0":"isObserver(address)","d9facc80":"MerchantWallet(address,string,address)","d9fb6963":"stateSetLocked()","d9fb7413":"lockTimeLeft()","d9fc4b61":"safeTransferFrom(address,address,address,uint256)","d9fc8026":"getPubKeyArr(bytes32,uint256,uint256[])","d9fca769":"setWinner(address)","d9fcb31f":"comm_channel()","d9fdd155":"isLegendaryPart(uint256,uint256)","d9fe0137":"_transfer_byProxy(address,address,uint256,bytes)","d9fe1045":"MidasDiscountToken()","d9fe60f3":"DTHPool(address,address,uint256,string,string,string)","d9feb8ce":"loserTwo()","d9feeeb6":"fillMyOrder(uint256)","d9fefb93":"getData_34()","d9fefbf8":"addData(uint256,uint256,bytes32)","d9fefd6c":"bountyTokenTimelock()","d9ff4ad8":"burnFrom(address,uint256,bytes)","d9ff8e9d":"setWalletOut2(address)","d9ff8ffc":"BetAnB()","d9ff94b7":"setRegionPurchasedAt(uint256,uint256)","da00586b":"houseKeep()","da00a1f4":"setGetFree(bool)","da0225db":"belongsTo(address,uint256)","da0239a6":"remainingSupply()","da025051":"freelancePlayer(address)","da02b6cf":"computeWinner(address,uint256,uint256,address,uint256,uint256,uint256)","da02f5f3":"updateIsVerified(address,bool)","da0321cd":"addresses()","da037fd1":"confirmPerfectReception()","da040c0f":"purchasingAllowed()","da04197e":"Duration(uint256)","da04f82b":"addUserManager(address)","da05277e":"ImpactRegistry(address)","da05f535":"RefundCrowdsaleFactory(address)","da062d68":"ExCToken11()","da06d96c":"_tokensToEthereum(uint256)","da074874":"getRemainingEthAvailable()","da0774ad":"getCallFeeScalar(uint256,uint256)","da081204":"littAdmins()","da08c5a3":"setTransferWhitelist(address)","da09118e":"addTokenGrant(address,uint256,uint128,uint16,uint16)","da09c72c":"devAddr()","da0a599e":"EjariRules()","da0a5fe0":"TestToken(string,string,uint256)","da0b0682":"beginGame()","da0b0c36":"getNumDesignatedReportNoShows()","da0bba7b":"changeOraclizeConfig(bytes32)","da0bba90":"sendPrize(address[],uint256[],uint64)","da0d76f8":"betContractDOWN()","da0e1451":"distributionForRefers(uint256,uint256,uint256)","da0ef68b":"ICO_END_DATE()","da0f039d":"MaxTotalSupply()","da0f3877":"postFreezeDevCATDestination()","da0f57d0":"confirmWithdraw(uint256)","da0fab61":"BlockContract()","da1070da":"newEscrow(address,address,bytes32)","da11f709":"bank1()","da122e02":"Fishbank(address,address,address)","da128527":"finalizeUpdateState()","da12e9ef":"TokenHolder(address,uint256)","da13610c":"rewarding(address)","da1441cd":"KudosBank(uint256)","da147d32":"tradeTracker()","da14c723":"setCustomBuyer(address,uint256)","da14e3b2":"transferAndFreezeTokens(address,uint256)","da16241b":"Platopay()","da17835f":"FermionToken()","da178cb0":"plot()","da17c21b":"BlockchainMoneyEngine(uint256,string,string)","da18bcef":"getMin(uint256[])","da1919b3":"mintFor(address,uint256)","da1a13ce":"fitsTokensForSaleCap(uint256)","da1aaa59":"_withdraw(address)","da1b2d9d":"comDrop(uint256,uint256,uint256,uint256)","da1b4359":"uploadFinish()","da1b620b":"getTarget(string)","da1b95a6":"DAO(address,address,bytes32,bytes32,address,address,address)","da1bd8ab":"setupTrustedAccounts()","da1d7711":"createHive()","da1eb542":"ceil1(int256,int256)","da1edb38":"shareLastTen(uint256,uint256)","da1ee417":"MoveChain(uint256,string,uint8,string)","da1f149c":"SECURRO()","da1f6433":"AtomUX()","da1fe7d5":"configureDomain(string,uint256,uint256)","da1ff555":"cliffTeamTokensRelease()","da2216ef":"getContractCreatedTimeById(bytes32)","da2242b8":"createActivity(uint256,string,uint256,uint256)","da228f9c":"bountyTokensCreated()","da22ec07":"storing()","da233128":"getCrowdsaleContract()","da23c057":"editAd(uint256,string,string,string,string,bool,bytes32,bytes2,uint8,bytes4)","da23d18b":"updateOnSaleSupply(uint256)","da2424ae":"setPI_edit_22(string)","da24b08c":"UsdPerKEtherUpdated(uint256,uint256)","da257cb4":"setMinRevenue(uint256)","da25c0cd":"ThisExternalAssembly()","da25de3c":"remainingBalance()","da262f58":"setTokenInfo(string,string)","da26358a":"unregisterVendor()","da26663a":"getPrice(uint32)","da26c241":"approvePauseChange(bool)","da26d0b9":"addAuction(uint256,address,uint128,uint128,uint64,uint64)","da26ebc2":"getPayeeCount()","da26f7f6":"CIFR()","da274488":"getMotd()","da27ab1f":"getFreeShitClone()","da27cb0f":"Lottery(string,uint256,uint256)","da280fe5":"resetHasAutoVote()","da284dcc":"expirationTime()","da28c81a":"updateKYClist(address[])","da293136":"TestCrowdsaleController(uint256,address,uint256)","da2a97d8":"GetCurrentNumbers()","da2aa615":"addRandomFight2Death(address,uint256)","da2b2589":"GenExtWeightList(uint8)","da2b7416":"testBitsAndFailIndexOOB()","da2bbfc7":"setTokenURIBase(string)","da2c0460":"gameGiftOnceAmount()","da2d7b70":"userSubscriptionsLength(address)","da2d8720":"payJackpot2()","da2d8c88":"updateRestrictedStockSendTime(address,uint256)","da2dcea6":"returnTokenMulti(address[])","da302fc3":"lighthouseLib()","da306946":"ShareDATA(string)","da30d418":"cancelDist()","da311588":"getCoin(uint256)","da31cf2a":"getStageEtherRaised()","da323c94":"getSketch(uint256)","da328377":"ownerSetStakeCommence(uint256)","da333ca6":"payOut(uint256)","da337465":"getPenguinsByOwner(address)","da34b7f3":"_transfer(uint256)","da35762a":"getPI_edit_16()","da359dc8":"setBytes(bytes)","da35d581":"DaoHubAccount()","da3678df":"transferTokenByContract(uint256,address)","da36d217":"lockupTok(address,uint256)","da36fd03":"FundingAccepted(address,uint256,uint256)","da374157":"changePopulous(address)","da38abb3":"randomGen(address)","da38daba":"getLeftCoordinate(bytes1)","da38f805":"TaskToken()","da38fe31":"ConsentDirectory()","da392f06":"availableNow()","da397985":"CBOToken()","da3986e4":"getTAOIds(uint256,uint256)","da3b6b35":"totalHashRate()","da3c300d":"currentFee()","da3cbf96":"getShipClass(uint32)","da3cd674":"GetDChainDOTHash(bytes32,uint8)","da3d18e8":"PlusUltra()","da3d23a9":"GetEnd()","da3d7d7f":"reconfigure(uint256,uint256)","da3e0fd1":"getAuctionsById(uint32[])","da3e3397":"approveToken(address,address,uint256)","da3f8c38":"Amethycoin()","da3fb6f7":"mainSaleRateP2()","da4077b9":"finishHim()","da421df5":"pageFiles(uint256,uint256)","da42eea5":"setRedeemWallet(address)","da440a1d":"wallcoinToken()","da446958":"totalTokensCap()","da4493f6":"activationTime()","da44d275":"viewWinners()","da44e034":"maximumTokensForForth()","da46098c":"setAllowance(address,address,uint256)","da465d3f":"saleSharesAvail()","da46a73c":"setGameOperator(address)","da46e48e":"setGLA(uint32)","da46e6c4":"transferFeeIncurred(uint256)","da46eda1":"setBlockDotDifficulty(uint256)","da46fe62":"ethereumToTokens(uint256,uint256)","da4751c0":"setMinPrivateSaleCompanyBuy(uint256)","da4778c2":"delayHours()","da4793ac":"setMaxSecurityGuardDelay(uint256)","da47d856":"getService(bytes32)","da481ce0":"DemeterCrowdsale(uint256,uint256,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256)","da489997":"addAsset(address,address)","da49613c":"ownedfunction()","da498084":"addTokenHolder(address)","da499f6f":"SupportAddOn(uint256,address,uint256)","da49cdb5":"getLostTokens(address)","da4a22dc":"MXN_Omnidollar()","da4a76c0":"becomeGameSponsor()","da4a77aa":"isRatifier(address)","da4a8ef6":"SettingsSet(address,uint256,uint256)","da4b5e29":"contains()","da4d0756":"vehicleExist(address,string)","da4d2615":"Gomblot()","da4f2899":"isUserInGroup(bytes32,address)","da5136b8":"setWhitelistAddress(address,address)","da5140fc":"lockTokensForAddress(address,uint256,uint256)","da5196e0":"getmemreqdetails(uint256,uint256)","da51bbd9":"luckyPendingIndex()","da51f168":"GetDayReward()","da5269a6":"getListOfConsents()","da5341a8":"issueMaxNomins()","da53462c":"initialize(address,address,uint256,uint256,uint256,uint256,address,address,uint256)","da535758":"lockUp(address,uint256,uint256,uint256)","da547dcf":"preIcoHardcap()","da548e29":"priceExpirationBlockNumber()","da5520cd":"HeroNodeToken()","da57736f":"stageThree()","da5950a4":"tokenBought(uint256,uint256)","da5a9366":"getAppBase(bytes32)","da5abf5d":"payment_returned(uint256)","da5b1f5c":"buy50()","da5c0a7c":"testDisown()","da5c7ec2":"WNCT()","da5da3b9":"initializeTokenSaleWithToken(uint256,uint256,uint256,uint256,address,address)","da5db748":"firstRelease()","da5e4489":"resetListing(string)","da5e9c62":"whitelistDayMaxStake(uint8)","da5ea40c":"computeMerkle(bytes32,uint256,bytes32[])","da5f3ac1":"GAME_END()","da5f838d":"weisRaised()","da60278a":"receivable(address)","da60d7e8":"BOARD_2()","da62a246":"rewardsTokenSupply()","da640668":"checkNameOccupied(bytes32)","da6443ad":"addAddressToWhitelist(address,address)","da649c63":"startSalePhase(uint256,uint256)","da652b4a":"summBilborough()","da6585ff":"calcSrcQty(uint256,uint256,uint256,uint256)","da658f22":"birthPerHundred()","da66cb3e":"secondRoundICOTokensLimit()","da67ac42":"MIPCoinToken()","da682aeb":"onApprove(address,address,uint256)","da6838ff":"getIfBonus()","da683c63":"Token(string,bytes32)","da68d47d":"licenseNFT()","da69f1c8":"arrayTest(address[])","da6aabbe":"set_sale_address(address,string)","da6b31b9":"testErrorTransferToNullAuthority()","da6babca":"setNextPrice(uint256,uint256)","da6c5832":"CROSAIR_MAX_PRICE()","da6d8ca4":"LotteryRecharge()","da6dfea7":"setRate(address[],address[],uint256[],uint256[],bool)","da6e11a5":"approveFactoryContract(address,bool)","da6efb01":"winAddressOf()","da6f76b5":"updateEpisode(string,uint256)","da70db17":"HireGoToken()","da710422":"getTokenAmountForWei(uint256)","da7150b9":"Qwidex(address,address,address,uint256,uint256,uint256)","da721672":"checkFloatingSupply(address,uint256,bool,uint256)","da72c1e8":"adminTransfer(address,address,uint256)","da7360df":"paymentInternal(bytes32,uint256[],uint256)","da73630e":"addTeam(address,string)","da73f0f9":"conversion_rate()","da748b10":"pausedUntil()","da74c5a1":"citiesSold()","da74ce27":"tokenCapForFourthMainStage()","da7545d0":"titleCount()","da756ba7":"BEAT()","da75b901":"deployStepTwo()","da76d5cd":"withdrawBalance(uint256)","da7855a3":"reclaimLocalNodeFee()","da78d655":"owner1OK()","da7911e1":"getOrderListLengthFactor()","da79a9fc":"setTxAsSpent(bytes32,bytes32,uint256)","da7bd3e9":"getVestingScheduleEntry(address,uint256)","da7c0ad4":"SaleScheduled(uint256,uint256)","da7c6a42":"registrations(bytes32)","da7ccce9":"test_oneValidEqInt1()","da7d0082":"isCertification(address,bytes32)","da7d249f":"UnsetBlockForSale(uint256,uint256,address)","da7d57f9":"startRareRaffle(uint256,uint256)","da7d7827":"getSubscriptions(address,string)","da7d86fd":"softDelete(bytes32)","da7e019e":"AlterContactName(address,bytes32)","da7e6fdf":"TokenDrop(address[],uint256[])","da7eadd4":"totalAffiliateDDT()","da7fc24f":"setBackend(address)","da7fc7c5":"payoutCompleted()","da7fd1f0":"gemmyMusicSupply()","da7ffbd4":"generateRandomSpell(uint8[14],uint32)","da801f20":"approveAndCall(address,uint256,address,address,bytes32,uint256,uint256,uint256)","da81b09b":"lastPeriodStarDate()","da8267e3":"hasDirectorAccess(address)","da82a035":"sweepCommission()","da8300d2":"initialEnemyCombination()","da832237":"SMALLEST_TOKEN()","da834ac4":"getPayoutNumerator(uint256)","da83a649":"onlyAdmin(bool)","da850601":"MKYCToken()","da8567cb":"AldiyoCoin()","da857f2c":"reduceLastWeekStake(address,uint256)","da85868e":"fifthExchangeRate()","da883e6a":"addItems(uint256[],uint256[],address)","da88a831":"updateBaseTokensPerEther(uint256)","da89970b":"hasntStarted()","da8a01a5":"CROWD_WEEK2_BONUS()","da8a46e0":"listUserRecastsFrom(address,bytes32,uint256,bool)","da8ad6b6":"getTAO(address)","da8c229e":"controllers(address)","da8d2f35":"ChannelDeleted(address,address)","da8e2890":"payNihilum()","da8e44d8":"registerColor(string,uint256)","da8ee786":"transferFromContract(uint256)","da8f410a":"ApprovedToken()","da8f54d8":"testVali(address,uint256)","da8f9fe5":"DetailedERC20(uint256,string,string,uint8)","da8fb7cd":"ASSToken(uint256,string,uint8,string)","da8fbf2a":"pauseMinting()","da909b09":"setExchanger(address)","da91254c":"whoAmI()","da918f76":"placeBlock(uint16,uint16)","da9287d1":"acceptHybridization(uint256,uint256)","da9332bb":"addCompanyURL(string,string)","da93d0d1":"setPrice()","da93dfcf":"give(address,bytes32,address)","da93f938":"maxAppeals()","da942ab3":"issueTokensExternal(address,uint256)","da94e770":"YBVToken()","da9534b4":"Stex()","da9590cb":"addPublicSaleWallet(address)","da95ebf7":"requestWithdrawal(address,uint256)","da96bbcd":"publicEventTokens()","da977038":"volumeBasedBonus(uint256)","da979b8d":"SpecialRate(address,address,uint256,uint256)","da98655e":"getNullAddress()","da9893dd":"Resource(address,string,string,string)","da9ab565":"changeId(string)","da9ad094":"changeParameter(uint32,uint32)","da9b3cb4":"getGameBid(uint256,uint256)","da9b90c4":"TOKEN_FIRST_DISCOUNT_MULTIPLIER()","da9bca21":"numActiveMembers()","da9bdbfc":"CKCoin()","da9bf54c":"icoPhaseDiscountPercentage4()","da9c273d":"cancelInvoice(uint256)","da9c6a46":"getReplyCount(uint256)","da9c87fa":"changePayRate(uint256)","da9d0f6b":"withdrawCustom(uint256,address)","da9d56d7":"getBidIds()","da9d95bc":"commonWithdraw(address,uint256)","da9da572":"tryAirdrop()","da9dd8bf":"isAddressVerified(address)","da9e13aa":"getProviderSales(address)","da9eadac":"remit(address,uint256,bytes)","da9eeaeb":"PetroNetworkToken()","da9f40b8":"setAssetFileLink(string)","da9f4875":"freezeTokens()","da9f6918":"MultiSigWallet(address[],uint256,uint256)","da9f7550":"requestRandom()","da9f84a6":"rerollValue(uint256)","daa0ab0e":"majorityForTeam()","daa0f79f":"LEGAL_EXPENSES_ADDR_1()","daa147f3":"redeemLevAndFeeByStaker()","daa170ca":"difficultyBalance()","daa17f49":"marketplaceAddress()","daa1d7d4":"maximumPercentageOfDaysSupply()","daa21e0e":"testBitSetSuccess()","daa232ac":"_bonusRatio1()","daa283c8":"__callback(bytes,string)","daa3a163":"isUpgradeable()","daa44bf8":"getInStreamOf(address)","daa45281":"_addTo(address,uint256)","daa4cf88":"getCurrentStageIndex()","daa50ee0":"DSTMultisig()","daa5f48b":"findbit(uint256)","daa69c9e":"killDividentContract(uint256)","daa6f417":"howMuchTokensAvailableForExchangeFromStock()","daa7370f":"onFailure()","daa86216":"getAllowedContractsCount()","daa89fef":"issueNewHeldCoins(address,uint256)","daa94ab1":"frozenAccountProfit(address)","daa9604d":"byPonzi(address)","daaa50c9":"transferWithCustomReservingNet(address,uint256,uint256)","daaa6b5d":"setReleasedAddress(address,address)","daaadd8e":"arr(address,address)","daab88a6":"createEngine(uint256)","daac1f64":"reqfee()","daac518a":"playerTokenAddress()","daacb24f":"right42(uint256)","daad98f4":"socibit()","daae717c":"setIndividualMinCap(uint256)","daae7e98":"setCompte_20(string)","daaf3d2e":"attack(uint256,uint256,address)","daafe0a5":"setPrice(uint32)","dab0537b":"change_p2(uint256)","dab09999":"returnMyEthBalance(address)","dab122de":"dInit(address,address,bool)","dab12beb":"SmartSweep()","dab23f7c":"__callback(bytes32)","dab306b1":"votingFee()","dab30ccc":"addBonusPeriod(uint64,uint64,uint256,uint8,uint256,uint8)","dab41935":"TootyrToken()","dab43e6d":"PreSale3DAPP(address)","dab46553":"removeOracle()","dab4c65e":"totalDowSold()","dab4cb87":"gameValue()","dab4d1c1":"PixelPrice(uint16,uint16,address,uint256)","dab5cec2":"setExtraTokensPercent(uint256)","dab5f340":"setRoot(bytes32)","dab5fdc4":"DOWN_totalBets()","dab680dc":"getGlobalInfo()","dab78820":"ERC20Rescue(address,uint256)","dab80075":"Signature(address,string,string)","dab80d6f":"addSponsor(address)","dab8263a":"weiPerToken()","dab83b9a":"selltokens0()","dab88ad7":"VI6()","dab8a18b":"specialTransfer(address,uint256,uint256)","dab8c01a":"Zorro01Token()","dab8ef38":"addRooms(string,uint256)","dab8fa73":"setPackage(string,uint64[3])","dab91e87":"linkToMasterWallet(address)","dab93a93":"PolarisDEX(address,address,address,uint256,uint256,uint256)","dab951ba":"arrayFunc(int256[10])","dab9938e":"setIcoBeginDate(uint256)","dab9afa4":"Test12Address()","dabb0531":"getCharacter(uint256)","dabb37d4":"Lakshmi(uint256,string,string)","dabb624b":"rate_ETHUSD()","dabb6360":"percentage_of_three()","dabb6778":"vestingTeamWallet()","dabbbd0b":"sharesChainToken()","dabbd2bd":"removePlayerFromServer(uint256)","dabbd670":"team2Token()","dabc0c37":"isPassOwner(bytes32,address)","dabc706e":"getProposalCost()","dabd2719":"setDiscount(uint256)","dabd2eb2":"changePrice(bytes32,uint256)","dabd5d65":"addDays(uint256)","dabdc1f2":"ChangeActiveDigger(address)","dabecd8d":"_newBid(bytes32)","dabf7dc8":"PayoutDividendEarly(uint256,bool)","dabf7ec4":"helper(uint256)","dabf8246":"EventAuction(address,uint256,uint256,uint256,uint256,uint256)","dac00420":"maxHalvings()","dac05adc":"test_1_ensureVoteWorks_increaseBlocksBy100()","dac1182e":"signBBODocument(bytes,bytes)","dac17430":"lastVoteTime()","dac194f1":"setAutoInvest()","dac1e5e5":"_computePVPReward(uint256,uint256)","dac32ba9":"modifyPolicyTo(address,uint8,uint8)","dac34674":"setNextGameSettings(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","dac3ab88":"getCurrencyHash(uint256)","dac3f6d2":"queryFusionData_ext(uint256)","dac47a71":"SetGiftTime(uint256)","dac4fcdb":"getNewCustomPrice(address,address)","dac54daa":"OPLTest()","dac5b8ae":"TokenSale(address,uint256,uint256,uint256)","dac645bd":"getBUI(bytes32,uint256)","dac649c8":"NEWC()","dac6af5e":"SWIFTH(address,address[],address)","dac796bb":"getInvestorBalance(address,address)","dac7c858":"TOKEN_TRANSFER_PROXY_ADDR()","dac84ee4":"moveToReceiver(address,address,uint256)","dac8df25":"DEVELOPER_CUT()","dac90466":"_error(bytes32)","dac9555d":"allocate_slot(address)","dac9882a":"offChainAddresesValidCount()","daca5ce0":"bonusTokensPercent()","dacaeb07":"pledge(bool,uint256)","dacc8e11":"getTPrice(uint256)","dacd06fc":"KongQiCoin()","dacd4472":"PixoArenaFounderToken()","dacdbb93":"removeAccountSearch(address)","dace4557":"setUnlockTime(uint256)","dacef51b":"payincount()","dacf18c7":"getDeathCoin()","dacf9483":"getUIntValueConverted(bytes32,uint8,uint256)","dacfa06f":"manualDraw()","dad0128d":"calculateAdjustedFiguresForBattle(address[3],address[3])","dad03cb0":"returnError()","dad13822":"setMonsterClassSiteSet(uint256,uint256)","dad22781":"AdvancedArtificialIntelligenceSafetyDefense()","dad24541":"PresaleToken()","dad2771d":"signReceipt(uint256,int256)","dad30cfc":"test_transfer_to_contract_with_fallback()","dad38294":"PowTokenHashedBase()","dad39151":"multiApprove(address,address[],uint256[])","dad52c72":"_itemCancelMarkets(uint256)","dad59f35":"raisedEthers()","dad5c2e3":"validAstroCount()","dad5c3ee":"chainyShortLink(uint256,string)","dad5fda3":"vester()","dad6b482":"userHasPositveBalance(address)","dad72332":"claimUnsold()","dad7ad9e":"aix()","dad7c095":"transferWithAllowance(address,address,address,uint256)","dad7e4d2":"Aaa()","dad86b45":"teamETHUnlock3()","dad90035":"withdrawalRequests()","dad901be":"callWithdraw()","dad950f4":"InvestorPart()","dad98b52":"MonsterBitToken()","dad99119":"ddf()","dad99989":"burnCoins(address)","dad9a423":"setDuesIn(uint256)","dada85c3":"setAirdropOn(uint8)","dadad8fe":"addNewStreetName(string)","dadb20be":"ChangeTokenName(address)","dadc89eb":"setPreIcoDates(uint256,uint256)","dadcb460":"bumpPointer()","dadce8b0":"setExpiration(uint64)","dadd9e8e":"withdraw_some_amount(address,uint256)","daddff33":"claimController()","daded88e":"addMessageRequest(address,address[],string)","dae072d9":"GameWon(address,uint256)","dae1bd84":"AddChip(address,uint32)","dae1ddd2":"check_period(address,address)","dae1f17a":"getShopOwner(string)","dae21454":"toEthereumSignedMessage(string)","dae37abc":"cancelParticipation()","dae37fac":"spendAvailable()","dae392ee":"softFundingGoal()","dae3f7e2":"Gralaxious()","dae595e5":"getAuctionStart(address,address)","dae611c4":"lockUnlockMatchGPForBetting(uint256,bool)","dae6f081":"setScrapMinStartPrice(uint256)","dae79483":"getMemsize()","dae7e05d":"_bonusAll(uint256)","dae8865c":"ETHERCToken()","dae89f18":"coordinatorAccountIndex(uint256)","dae8af77":"getFeeWindowId(uint256)","dae9c31b":"ProofPresale()","dae9e379":"getFundBalance()","daea85c5":"approve(address)","daeab905":"issueReceipts(address,uint256)","daeb1c98":"PlusToken()","daeb860d":"versionAddresses(bytes32,bytes32)","daec4582":"AuctionEnded(address,uint256)","daec75f3":"buyXwithdraw(bytes32,uint256)","daec8128":"mintTokensForFounders()","daecc910":"getCKOwner(uint256)","daed6726":"ETHCollected()","daee4dd6":"readCheck(address,uint256)","daee9e35":"level2Bonus()","daeed3a6":"rateFinalStage2()","daef0e92":"stopCurrentGame(uint256)","daef4df8":"addCar(string,address,uint256,uint256,uint256)","daef569f":"insChainTokenLedger()","daf017a9":"GetRocket(uint32)","daf059c6":"createGuess(uint16,uint64,uint64,uint16)","daf13a47":"reserveLockup()","daf161e2":"getThirdAdmin()","daf1af19":"Current_balance()","daf1db09":"readyForFinish()","daf22f4d":"identify(bytes32)","daf32370":"getPurchaseAddress(uint256)","daf47ba3":"incGenLabFace(uint256)","daf488b1":"setReferrerPercent(uint256)","daf49451":"BINGToken()","daf4f66e":"isLimitEnabled()","daf64aa5":"getCompanyDetails(uint256)","daf69093":"BLOCKCHAIN_DEPOSIT_BETA_1M()","daf6ca30":"saleContract()","daf6e5ae":"DeepBrain()","daf760d0":"getData_6()","daf7f103":"_error(uint256)","daf8f438":"startRedeeming()","daf9812f":"updateBincentiveErrand(address)","daf9a535":"getData_20()","dafa1d2d":"burn(string)","dafa55a1":"creatureIndexToOwner(uint256)","dafae408":"checkThreshold(uint256)","dafba12f":"setMAGContractAddress(address)","dafc5608":"TransferFeeRateConfirmed(uint256,address,uint256)","dafc64c4":"ERC223MintableTokenFactory(address)","dafd54a6":"ExaEUR()","dafd70c9":"RESERVED_UTILITY_GROUP()","dafea207":"smax256(int256,int256)","daff0093":"setReference(address,address,bytes32)","db006a75":"redeem(uint256)","db00758a":"getSGNTokenManager()","db00b848":"_performGeneric(bytes,address)","db00d1a9":"_preValidateCancellation()","db0251e9":"contributeMsgValue()","db035918":"deployForeignBridge(address)","db041965":"fightBetaMonster()","db0436c2":"RUNEToken()","db04aef4":"getHoldersLength()","db051653":"setEtherFeePercent(uint256)","db054134":"mintForReportingParticipant(uint256)","db059dfb":"createSsp(address,uint256,string)","db05ccfc":"setValue(address,uint256,uint256,uint256)","db060e1a":"RESERVED_TOKENS_FOR_FINANCIAL_INSTITUTION()","db068e0e":"setExchangeRate(uint256)","db06f0c2":"doPresaleMinting(address,uint256,uint256)","db078f08":"toggleKey(address,bool)","db0827e9":"ashcashToken()","db0834cf":"lockedAllocation()","db08444a":"toUint(int256,string)","db087ad5":"getCurrentPricePerWei()","db08ccec":"enjinTeamAddress()","db0a087c":"getTypeName()","db0aa668":"Bittwatt()","db0ad29c":"SocialMediaMarketToken(uint256)","db0c154a":"hitCharacter(uint16,uint16,uint8)","db0c9a02":"marketSell(uint256)","db0d5175":"getTransfer(address)","db0d7ce5":"LotteryRoundCreated(address,string)","db0db014":"dividendsForAmountAndTime(uint256,uint256)","db0dd71e":"addAbility(string,bool,uint8,uint8,uint8,uint256,uint256)","db0e127a":"openDoor()","db0e16f1":"emergencyERC20Drain(address,uint256)","db0ec968":"transfer(address,uint16[])","db0edd08":"PubKeyHashAdded(bytes20,uint8)","db0fb107":"updateSafeSender(address)","db107371":"DecentrEx(address,address,address,uint256,uint256,uint256)","db11040f":"LogRegError(address,string)","db112977":"Project_Info(uint256)","db11ead1":"markContribution()","db1227da":"initGameReferred(address,uint8)","db122ad4":"committeeJoinVotes(address)","db123b1a":"ZRX_ASSET_DATA()","db12630a":"fundariaCap()","db12999b":"airdropTokens(address,address[],bool)","db1366bf":"buyExchangeRate()","db136b1e":"createAsset(address,uint256)","db15520d":"TPTContributors()","db15b72d":"getDInfo(bytes32)","db165a76":"createLand(address,uint256)","db16d0fe":"optionExist(uint256,uint256)","db171211":"returnToSender()","db171754":"vestedAddress()","db180b2b":"LOCKAMOUNT2()","db18c972":"play4(address,uint256)","db18f962":"updateSplitandSend()","db192761":"Clockpay()","db1a71ae":"trackable_likes(address)","db1b569f":"previousSender()","db1bdd1d":"TheTokenG()","db1c45f9":"getAllGames()","db1c53e2":"isTransferedUser(address)","db1d0fd5":"alpha()","db1d68b5":"countryWinnerID()","db1eeb51":"MizeCoin()","db1f6689":"authorContentByIndex(uint256)","db201648":"AppicsFund()","db21fc9c":"gettimeback()","db22032f":"rentalTimeRemaining()","db2307b6":"changeRecvEthStatus(bool)","db230b52":"viewScore(address)","db239951":"cbAddresses(address)","db23c5d7":"icoRuleAdd(uint256,uint256,uint256,uint256)","db23f7e3":"veztUserArrayIdentifier(address)","db246fda":"withdrawalTimeOf(address)","db248091":"assignBonus(address,uint256)","db25b407":"listActive()","db25c328":"joinToProvider(uint256,address)","db25e637":"Strikes(address[])","db264a36":"s10(bytes1)","db27b8dd":"vestingManager()","db299492":"IGFC(uint256,string,uint8,string)","db29fd6e":"increaseDistrictCoke(uint256,uint256)","db29fe12":"addShareholder(address)","db2a0cb7":"HumanStandardTokenFactory()","db2ac8d8":"WINTOKENADDRESS()","db2becb0":"getWalletFeeSignatures()","db2c4e2d":"complexScaleObsTest(address)","db2d10a5":"PreICOTokenPushed(address,uint256)","db2d5841":"batchRelease(address[])","db2e21bc":"emergencyWithdraw()","db2ea20e":"arrayTestMulti(address[],address[],uint256[])","db2ea5c0":"_callERC165SupportsInterface(address,bytes4)","db2f1d83":"TalkCrypto()","db3119bb":"manageLink(uint256,uint256)","db318833":"_ecAdd(uint256,uint256,uint256,uint256,uint256,uint256)","db31dd17":"removeAddressFromWhitelist(address,string)","db31fb03":"excessEth(address)","db3268d8":"getBU(bytes32)","db32be98":"refundICO()","db330794":"addToVestMap(address,uint256,uint256,uint256,uint256)","db3359f0":"makeNonFungible(uint256,address)","db35132c":"WithdrawEther(address,uint256)","db3543f5":"setFoundation(address)","db35a03d":"allowedSpenders()","db36c2e5":"destroyOldCoins(address,uint256)","db37ceec":"maxEthContribution()","db37e42f":"multisetProofType(uint256[],address[])","db383bf2":"MyNewToken()","db38b877":"testRsplit()","db395d2e":"bonusPercentForWeiAmount(uint256)","db39a8e8":"getTokenTransferInsByAddress(address,address,uint256)","db39ceac":"MyBalance2(address,address)","db3b73db":"getPlatformName()","db3c1b94":"EtmPerBtc()","db3d8421":"getTotalAngelCardSeries()","db3e7f4f":"forgeTokens(address,uint256)","db3fd0b8":"usedReserveSupply()","db403747":"mintForYear(address,uint256)","db40e896":"stopExchange()","db40ed24":"WeGoldToken()","db412f39":"preSaleDelivery(address,uint256)","db420fe3":"serverAddress()","db422e0b":"sendTokensAndRefund(address)","db447c04":"getPurchaseDetail(uint256,uint256,address)","db45479b":"closeChannel(uint256,address,bytes32,uint256,bytes32,bytes)","db456f77":"extraReceiverByIndex(uint256)","db45a30f":"buyPlanet(uint256)","db475044":"SHITcoin()","db478d08":"levelTwoBonus()","db47b9c9":"isTokenSupported(address,address)","db480704":"HCTToken()","db4844f3":"setRequestFailed(uint256)","db491d49":"ContributionReward()","db491de9":"daysToUnfreeze(address,address)","db491e80":"getNote(uint256,uint256)","db4ad99f":"constructUserIdentity(address,string,uint32,string,string,bytes32,bytes32,uint8)","db4bb866":"bitskiToken()","db4bd421":"trackable_record(address,uint256)","db4c528b":"increasePositionOnBehalfOf(address,bytes32,uint256)","db4cacec":"Other()","db4ce763":"DTRExpensiveWallet(uint256)","db4cf8e6":"getAccountAddress(uint256)","db4d1296":"confirmAdminTx(uint256)","db4e1df5":"setBTTSToken(address)","db4ecbc1":"CONTRACT_ADDRESS()","db518db2":"withdrawFor(address,uint256)","db51d62b":"OpenTime()","db52e130":"saveString(string)","db530222":"nextEndTime()","db536d2f":"getDefaultKey(address)","db5370c3":"EEAcoin(address)","db543fdc":"adviserAndBounty()","db5517b0":"snapshots(address,uint256)","db5549d8":"TokenBurn(address,uint256,bool)","db55bd2d":"authoriseNextAction()","db56702b":"firstWeekEndTime()","db56c29d":"Billionstrader()","db56d26c":"ChangeFiliate(address)","db57c429":"createPromoGameItem(address,string,uint256,uint256)","db5861ed":"ULA(uint256,string,string)","db589907":"setCosts(uint256,uint256)","db589bbe":"getInternalDrawings(uint256)","db59190d":"C1(uint256)","db5a2778":"adminAddCountry(string)","db5ad407":"setData(bytes32,uint256,uint256,uint256,uint8[])","db5b4183":"oracleOutcomes(bytes,address)","db5b5799":"setClientSupply(address,uint256)","db5b7635":"TokenMacroansyPower()","db5c9442":"TRIAL()","db5cf9de":"getSpaceshipProductClassByModel(uint16)","db5d855b":"getReceiptId(address,address,uint256)","db5df447":"redemptionPriceCalculate(uint256)","db5eef61":"PredictionMarket()","db5f2f31":"calcExchangeRate()","db5f5d7c":"usedAPI()","db606931":"pointRootNode(address)","db618c08":"TestAuditor()","db623bd5":"ErrorSendingETH(address,uint256)","db624887":"W()","db62df0e":"likeTrack(address,bytes32)","db6380ec":"tokenCapForMainICO()","db638e51":"resetUserRefBalance(address,address)","db63e149":"EmployeeWallet(string)","db641ab4":"Game_balance_in_Ethers()","db642bce":"GoddessToken()","db6648c0":"collateralisation(address)","db66ef59":"getPublicKeyN()","db6727c1":"myBitFoundationPercentage()","db680e3d":"getMeterInfoByMonth(uint8,uint256)","db681e1d":"GameScored(bytes32,int256,int256,uint256)","db681e54":"getGenerationForCall(bytes32)","db681e9f":"sendRefund(uint256)","db6997ae":"getCitiesData(uint256[])","db6a3652":"addOrder(address,uint256)","db6aef35":"amountOfWorkpointQueue()","db6bb289":"Zygoma()","db6bbeb2":"abx_token()","db6be534":"end_ts()","db6be871":"getAmountByCoupon(bytes32)","db6bed22":"addPresaleWallets(address[],uint256[])","db6c1831":"bonusSystem(bytes5,uint256)","db6c709c":"updateExchangeRates(uint256,uint256)","db6c71d6":"rspContract(address,uint256)","db6c7286":"CTokenGB()","db6c9416":"AgoraToken()","db6f1e74":"getUser(uint32)","db6f7537":"getPOOL_edit_22()","db6f9deb":"rewarded(uint256,address)","db6fcf01":"is_destroyed(uint256)","db7057fb":"rngId()","db714efe":"getBlocks(uint256,uint256)","db71c776":"setRateIcoPreICO(uint256)","db71d8b6":"FEE_SELECT_LRC()","db723e73":"personalMincap()","db72496f":"cancelSubscription(uint256,uint256)","db737c78":"getToken(uint256,bool)","db73bfce":"gameInfo()","db7400a5":"createAppInstance(bytes32,bytes)","db747f21":"setOraGasLimit(uint256)","db74847d":"distributeTratok(address[],uint256[])","db74c27a":"backRedPillTokenOwner()","db75dd5f":"AQBToken()","db76790f":"setAdvisorWallet(address)","db76e9c2":"setMemberLevel(address)","db77032d":"RATE_SALESTAGE4()","db775041":"donation(bytes32,uint256)","db775410":"setTypedJackpotWinner(address,uint256)","db7757cf":"valueRaised()","db78d0ce":"getAirdropAtSnapshot(address)","db78f5ef":"withdrawOnBehalf(uint256,string,uint256,uint8,bytes32,bytes32)","db79a65f":"resetUserWhiteListAmount()","db79e673":"getTradeOfferRecipientItems(uint256)","db7a0855":"MZToken()","db7a2f42":"projectAgent()","db7a4605":"getWallets()","db7a80f8":"getContributionUSD(address)","db7b87ff":"init(address,uint256,bytes32,uint256,uint256,uint256,bool,bool,address)","db7bc073":"refundWhenNotClosed(address)","db7ca38a":"XaurmProxyContract()","db7d2665":"FundTransfer(address,uint256,address)","db7d9065":"assignedAmountToCooperativePartner()","db7ed9e7":"addAssessorToPool(address)","db7ef562":"_2_nation()","db7ef7c6":"verifyEscrowVendor(uint256,address)","db7f1e6b":"getInitialEnemyCombination()","db7fea95":"WALLET_T8EX_RESERVED()","db803a86":"post(string,address[])","db80813f":"set(bytes32)","db80a787":"emitCourtUpdated(address)","db80fbc9":"balanceOfLockup()","db82967c":"createUsingProxy(address,bytes)","db8298f3":"_commissionTarget()","db833e3a":"sellShares(bytes32,uint8,uint256,uint256)","db83694c":"getSaleInfo()","db8374ee":"buyOracleFor(bytes,address,address)","db83d02f":"VREO_SALE_CLOSING_TIME()","db84252c":"tokenCreator()","db852ee7":"pieceSold(address,address,uint256)","db856759":"depositOldTokensFor(address,uint256,address)","db856f28":"_updateCard(address,uint256)","db85bd78":"registerTraderAccount(address)","db86d850":"transferGoo(address,uint256)","db87cbcc":"GetPermissionsList(address,address)","db88176f":"getQuestion(uint256)","db8850bc":"_merge(uint256,uint256)","db886f23":"Marketing()","db89c044":"reputationOf(address)","db89edb2":"BitDailyBot()","db8a61d4":"APP_BASES_NAMESPACE()","db8b6ccf":"addSubjectMatter(string)","db8b7fae":"transform(address)","db8bcec4":"MAX_TIME_RANGE_COUNT()","db8cee5e":"_generateRandomDna(uint256)","db8cfa5a":"HAVtoUSD(uint256)","db8d55f1":"getFees()","db8d7c39":"disableRestriction()","db8e9043":"SetOutRate(uint256)","db8ecf34":"registerFreelancer(string,string,bytes32,uint256,uint256,uint256[],string,string,bool,string,uint256,uint8,uint256[],uint256[],string)","db8ed8a7":"withdraw_a_bit(uint256)","db8ee692":"_price_tokn_ICO()","db8f0301":"getAEth(uint256,uint256)","db8f2f75":"EthStorageContract(address,address,address[],uint256,uint256,string,string,uint8)","db8f5a35":"feesAndBountySupplyRemaining()","db8f7fb5":"preDiscountPercentage()","db9078b4":"CheckGenChip(uint32)","db9090a7":"devTokenWithdraw(uint256)","db91095e":"LVXToken()","db91774c":"setMinValue(uint256)","db9254a5":"_buy(address,uint256,uint256)","db9311c2":"getBlocksToNextRound()","db93f375":"startTokenVotes(address[],uint256,uint256,uint256,address[])","db946a11":"PlayStationChain()","db958f18":"FootCoin(uint256,string,string)","db95937d":"orderContractorProposal(uint256)","db967d05":"endOfPhase3()","db97c24d":"uzziToken()","db98abd8":"testThrowCancelSellOrderTwice()","db98d73f":"setRecordAddress(address)","db99800c":"fetchCreatedOrdersForMerchant(address)","db9a21bb":"CreateRZM(address,uint256)","db9abbd4":"arr(bytes32,bytes32)","db9b6775":"testMintThis(int256)","db9cc410":"createAsset(string,uint256)","db9cc99d":"AuctionCancelled(uint256,uint256)","db9cd8d3":"tab()","db9d28d5":"numDigits(uint256)","db9d5d31":"AdminRemoved(address,address)","db9dfb35":"newTeamOnEnd(uint16,uint64,uint64,uint64)","db9f16a8":"takeOffItem(uint256,uint8)","dba01cfe":"distributePENT(address[],uint256,uint256)","dba07858":"_removeFromList(address[],address)","dba0e9bb":"ethertoteDevelopmentWallet()","dba1a5f9":"allocateFunds()","dba1ac3d":"getEnforceRevisions(bytes20)","dba21586":"ProofOfTrevonJames()","dba21657":"askForEther(uint256)","dba22cb0":"transferPlanet(address,uint256,uint256,uint256)","dba232e3":"POPToken()","dba2a570":"_tune(uint256,uint256)","dba2d875":"forcedRefund()","dba31911":"bookSpaVisit(uint256)","dba33c03":"saleTokensCents()","dba3e704":"setMinimumContribution(uint256)","dba4c85c":"GetWithdrawBalance(address)","dba56cb8":"buyTokensFromContract(address,uint256)","dba5e917":"SelfDestruct()","dba6f7be":"verifyCreateSig(address,uint256,uint256,bytes32,bytes)","dba72a4e":"ICONIQ_SALE_OPENING_TIME()","dba7ef7d":"Bookie(address,address)","dba86ab6":"claimCardboard(uint64)","dba8be6e":"chickenTokenDelegator()","dba989ca":"_bonusTime2()","dba9a8a2":"setTrCut(uint256)","dba9daab":"pickBigWinner()","dbaaa2dd":"MIN_CONTRIBUTION_PRESALE()","dbaab3e1":"setMarketingAdmin(address)","dbaad1e5":"ownerDied()","dbab2f97":"merge(address[],bytes32,bytes32,int256,int256)","dbab7f1b":"UserInfoContract()","dbac248b":"MannaCoin()","dbac4cbf":"GetContractStateTerminatedSecDep()","dbac7806":"milestone()","dbacc237":"holderOf(uint256)","dbad21af":"tickets1kprice()","dbaea636":"UVPToken()","dbaec0fd":"createPattern(bytes32,string,address,string)","dbaf023d":"LogoVote()","dbaf2145":"requestWithdrawal()","dbaf5ce7":"changeRatesToken(uint8,uint256)","dbaf7247":"getValueByIndex(uint256)","dbafd0f2":"getTotalSeconds()","dbafdbb6":"setBalanceLimit(address,uint256)","dbb094ef":"Crowdsale(address,uint256,address,address)","dbb173d9":"test_updateKey_decreaseNoHint(int256)","dbb183c2":"setAuthorizedLogicContractAddress(address)","dbb24554":"updatePriceDenominator(uint256)","dbb3cef3":"developer_update_Terms_of_service(string)","dbb47d77":"claimPlayerWinnings()","dbb57a4b":"transferOne(address,uint256)","dbb61238":"maxDelay(uint256)","dbb62f24":"setDataMining(address)","dbb633f1":"ownerWithdrawalDate()","dbb72f67":"nullify(address)","dbb80e42":"allTokensLength()","dbb82429":"_randByRange(uint256,uint256)","dbb833df":"investWithoutId()","dbb8a305":"getBetName(uint256)","dbb98cae":"limit7()","dbb9deda":"goNext()","dbbabdfe":"getnum(uint256)","dbbb119c":"addMaster(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint32,uint32)","dbbb206f":"buy(address,address,address,address,address)","dbbbe8df":"transferByCrowdsale(address,uint256)","dbbc6fcc":"isPayableEnabled()","dbbc853b":"tokenURISuffix()","dbbd3a71":"addClaim(address,bytes32,string,string,address,uint256)","dbbd4865":"isEarlyBirdsStage()","dbbd78da":"getAccountNickname(address)","dbbd7934":"findItem(address[],address)","dbbd9a04":"ALLOC_MAX_PRE()","dbbdad8c":"generateReleaseTokensSchemaHash(address,address,uint256,bytes32)","dbbdae63":"updateSeller(address)","dbbdf083":"register(uint256,address)","dbbe2ff9":"setCirculationShares(string)","dbbf01b2":"setAddUsers(address,address,string,string,uint256)","dbbfcd7c":"getCOR()","dbc02821":"XTVNetworkContractAddress()","dbc0c085":"teamMultisig()","dbc139be":"LogMigration(address,uint256)","dbc1f226":"suicide(address)","dbc27799":"pendingNewRound()","dbc2783d":"DoNotDeployThisGetTheRightOneCosParityPutsThisOnTop()","dbc2d042":"consumerAddress()","dbc2ef49":"getNotUsedToken_()","dbc38940":"executeTxn(uint256)","dbc45228":"newProposal(address,uint256,bytes,bytes)","dbc488e2":"ESlotsCrowdsale(address)","dbc53c07":"read(uint16,uint16)","dbc56297":"claim(address,bytes32,bytes32,uint8,bytes32,bytes32)","dbc57971":"getIcoStatus()","dbc5d002":"sendQuery(string,uint256,uint256)","dbc65f85":"preBuyPrice2()","dbc69521":"totContribution()","dbc837c5":"insurer()","dbc8817d":"GOLDENRATIO()","dbc91396":"cancelOrder(uint128)","dbc91ed1":"subset(string,uint256,uint256)","dbc933bc":"p_withdrawDevHoldings()","dbc9ef42":"_removeAuction(uint40)","dbca1207":"getLastSeed()","dbcbaca4":"investorInfo(address)","dbcbb362":"setTransperRun(uint256)","dbcc4658":"getSmartContractByPosition(uint256)","dbcc6caf":"second_release(uint256)","dbccb926":"CreatedToken(address,uint256)","dbcd258d":"blocksPerHour()","dbce1ff7":"referralRateInviter()","dbceb005":"split(uint256)","dbcf0531":"ContractFullfilled(address,int256)","dbcf194a":"GetInventoryCount(address)","dbd01de1":"cluster()","dbd05767":"RBA()","dbd0e1b6":"getSeller()","dbd16774":"IGMathsContract()","dbd19619":"round_earnings(uint256)","dbd1be77":"getDrone(uint256)","dbd1df92":"setTitulaire_Compte_1(uint256)","dbd229ff":"totalSupplyMarket()","dbd2ac60":"distributeCallback(uint256,uint256)","dbd3100e":"getBuilding()","dbd3313e":"PizzaPoll()","dbd3c372":"safeMulticastTransfer(address[],uint256[],uint256[],bytes)","dbd3cd62":"withdrawPayment(uint256)","dbd3d021":"findNextSecond(uint256,bytes2)","dbd42da5":"ranked()","dbd4a422":"synthetixState()","dbd4a8ea":"setBase(address,uint64,bool)","dbd54b62":"setMasterAuth(address)","dbd55fb3":"ACTION()","dbd594bb":"FoundsTransferd(address,uint256)","dbd5ef6d":"setFeeConfig(uint256,uint256,uint256,uint256)","dbd64ae9":"closeSale3()","dbd6da8c":"isUidSet(string)","dbd6f5c1":"allocationAddress()","dbd760ca":"PriceThreeDisable()","dbd7fd13":"saleMilk()","dbd84659":"receiveTokenByClientAccount(string,uint256,address)","dbd848e3":"ICO_Ended()","dbd8987c":"contractFeePercentage()","dbd8c25f":"BasicTokenImpl()","dbd91792":"multiowned()","dbd9a4d4":"setAllowances()","dbdb8b56":"eosGAS()","dbdb96c2":"updated_policy_payload()","dbdc275d":"createB()","dbdd5ae6":"actOnBehalf(bytes,uint256,uint8,bytes32,bytes32)","dbdd5d74":"swapsFor(address)","dbddcdb7":"getScouponBalances(address)","dbde1988":"transferFromWithoutReward(address,address,uint256)","dbdef054":"setFinalizeAgent()","dbdf7fce":"resetCounter()","dbdf8538":"_emitWorkStarted(uint256,uint256)","dbdff2c1":"getRandomNumber()","dbe01790":"getAllHpbNodes()","dbe1053d":"sendEthBackToUsers()","dbe201c7":"getAllBidsByAdslot(uint256)","dbe2bc84":"_suspendMarket(address)","dbe2c85b":"checkFiscalVerify(bytes32)","dbe2e296":"pushToPot()","dbe3010c":"WINNER_SHARE()","dbe3071a":"Kitchen()","dbe3117a":"tier2Timestamp()","dbe35007":"getAuctionsLength()","dbe3e92f":"provenanceOf(address)","dbe54524":"set_CWC_Address(address)","dbe55e56":"platformAddress()","dbe587b9":"CashPokerProPreICO()","dbe5bab5":"getOpenOrders()","dbe5ca78":"POAP()","dbe5fe9d":"setMaxCoinSides(uint8)","dbe6c02f":"isOwnerOrOperator(address,address)","dbe705ea":"fetchCreatedOrdersForMerchantByAdmin(address)","dbe992af":"updateEntry(uint256,address,uint256)","dbe9eebf":"getPricePointsLength()","dbea52d8":"lotteryPrice()","dbeab275":"createRoutingCode(bytes32)","dbeabd21":"getPplsAddr(uint32)","dbecc372":"Example(uint256)","dbecfb25":"koth_v1b()","dbed1e88":"getUnlockTime(address)","dbed3a30":"GamePoolAddress()","dbedf9e4":"TB01()","dbee0dea":"releaseTimeLock()","dbeea819":"tokenGrantees(uint256)","dbef0790":"returnUnsoldTokens(address)","dbefe789":"NUM_OF_PHASE()","dbf14295":"claimSilver(uint64,uint64,uint64,uint64,uint64,uint64)","dbf14dd9":"buyfloaksAgainstEther()","dbf1b00b":"claimBeer()","dbf1bfee":"ballotFee()","dbf1ede3":"_getLogTokenContract(uint256)","dbf1f780":"_hasEntryForCompetition(address,uint256)","dbf1fe48":"calculateTokensFromWei(uint256,uint256)","dbf27e0c":"updateConstitutionPoll(address)","dbf2c9da":"isValidAuthority(address)","dbf2f3c2":"get_reward(address)","dbf323dd":"DEDToken()","dbf35430":"ownedOwnershipTransferred()","dbf44530":"isWhite(address,address)","dbf45aa3":"EthBank()","dbf4c54c":"batchTransfer(address[],address[],uint256)","dbf502c0":"getCentsPerETH()","dbf517a2":"_connectModule()","dbf53a0e":"StandardTokenMock(address,uint256)","dbf552aa":"LOG_InvestorEntrance(address,uint256,uint256)","dbf5b91b":"setSafeGas(uint256)","dbf5eb1c":"closeTokenSale(address)","dbf63340":"availableSynthCount()","dbf675c9":"bonusAddresses(address)","dbf724c7":"setReceiver2(address)","dbf76c03":"bountyOfflineWallet()","dbf79dcd":"StatusCow(address,uint256)","dbf7dc0c":"getEntityList(bytes32[],uint8[])","dbf81cc6":"foundersTokensAddress()","dbf8d2fa":"sendTips()","dbf98f6a":"totalSupplyBonds()","dbfa5863":"_endDate()","dbfa6226":"interfaceInstances(uint256)","dbfa980b":"Slogan(string)","dbfab65b":"AvalonToken()","dbfb129e":"ChecksumDatabase(string,string,string)","dbfb18e7":"GoblinChainToken()","dbfc74cb":"ORACLIZEGASPRICE()","dbfccd16":"ethersplay(uint8)","dbfdb6e5":"getIcoTokensAmount(uint256,uint256,address)","dbfdef01":"TechnoEng()","dbfe791b":"confirmed(bytes32)","dbfeb17f":"eth_cap()","dbfec8b7":"CHEXToken(address,uint256,uint256)","dbfef710":"getDefaultRequiredGas()","dbff4182":"seedCoins(address,uint32,string,uint256)","dc00adef":"buyLand(bytes32,int256[],int256[],address)","dc00b602":"EllipseMarketMaker(address,address,address)","dc00e43b":"BananaBasket()","dc012626":"ballotOf(address)","dc015851":"minimumContributionPhase4()","dc01bd0c":"calculateAmountForDAI(uint256)","dc021628":"setFund()","dc02511e":"addPermittedContracts(address[])","dc02f456":"decodeTransfer(bytes)","dc042405":"getNames(address[],address)","dc048cf2":"withdraw(uint256,string)","dc0527de":"NDEX()","dc06269f":"showWhaleAddr()","dc06b859":"numMarketMakers()","dc06d8f8":"lnTest(uint256,uint256)","dc06e754":"_setRspTokenAddress(address)","dc070657":"changeBeneficiary(address)","dc08a80b":"safeToAdd(int256,int256)","dc08b611":"EXAC()","dc08e2c5":"getVIPOwner(uint256)","dc08e5ff":"getStockCount()","dc09426c":"GetGameInfo()","dc09996c":"escrowDatabase(address,uint256)","dc09d8fd":"showInvestorsComission()","dc0b3564":"players()","dc0b48c1":"startPubTrade()","dc0ba228":"change(bytes,uint256[])","dc0bd011":"collectDonations()","dc0bd38e":"appendDecryptedBids(uint256[],uint256[],uint256[],address[],address,uint256[],uint256[],uint256[])","dc0bd75f":"arr(address,uint256,uint256)","dc0c1a27":"numberOfMajorEvents()","dc0c7735":"isPreSaleTokenSet()","dc0d3dff":"funders(uint256)","dc0d4cb6":"merculetContract()","dc0eb1a3":"PredictTheFutureChallenge()","dc0f5ffc":"get_candidate_pic(uint8)","dc11a496":"changeAdmin(address,bool)","dc11b386":"getDailyTarget(uint256,uint256)","dc11be24":"smallSize()","dc126e63":"unlockVestedTokens(address)","dc1279d4":"getPureFromGene(uint256[2])","dc129870":"Loom()","dc12a805":"right57(uint256)","dc12abb5":"setPresaleDates(uint256,uint256)","dc132be8":"getAmountofTotalParticipants()","dc13352a":"TeamSupply()","dc13f85f":"getMaxPriceSale()","dc14af38":"setIncrEth(uint256)","dc1542aa":"testSafeAdd()","dc154918":"_computeTournamentContenderCut(uint256)","dc154a19":"buyAndSetDivPercentage(uint256,address,uint8,string)","dc15c635":"getdeptinfo(uint256,address)","dc165652":"bountyTokensVault()","dc1790e3":"getdeptreqdetails(uint256,address)","dc17c9ca":"getTokenOwner(address)","dc17e808":"getPaidOrderByIndex(uint256)","dc183d64":"setBridgeValidatorsImplementation(address)","dc184e70":"reserveAccount()","dc190074":"setsafemode(uint256)","dc19266f":"Total_of_Players()","dc199335":"checkIdentifier(string)","dc1abb6e":"MAX_AUDIT_TIME()","dc1b93cb":"COREXCoin()","dc1bba17":"getTxAmountMCW(bytes32)","dc1bebe6":"creditExecutedFundsLessFees(uint128,uint256,uint256)","dc1c1389":"acceptOfferForCity(uint256,uint16,uint256)","dc1cb47b":"priceTLP2()","dc1d672d":"mQueue(uint256)","dc1d70c3":"presaleBonusLock()","dc1d83b3":"changeTelephone(address)","dc1df3f6":"myTokens(address)","dc1eab83":"standardSale()","dc1fb5a5":"community()","dc1fca7e":"dateSaleStarted()","dc1fdff0":"commissionSum()","dc201838":"QuickPrice()","dc206e5f":"oraclize_query(uint256,string,string[])","dc20d6e7":"updateRandomNumber(uint256)","dc20f957":"assetIncome(bytes32)","dc21b3de":"preIcoBonus(uint256,uint256)","dc22aca5":"GalaxiumCoin()","dc22cb6a":"series(uint256)","dc22eba6":"register(uint256,uint256,uint256,uint256,uint256)","dc2424fc":"setPositionPrice(uint256)","dc242e38":"calTotalSupply(uint256)","dc2811cd":"KDOU()","dc2816b7":"AddNewChip(uint32,uint8,uint8,uint8)","dc28d0c9":"tokenToValue(address,uint256)","dc298682":"createCategory(string)","dc29a89e":"concatBytes(bytes,bytes,bytes,bytes,bytes,bytes,bytes)","dc29da22":"getNodeHash(address)","dc29ec37":"tokenReserve(address,uint256)","dc29f1de":"topUp()","dc2a3056":"setTripleRoomMax(uint256)","dc2a60f6":"isReadOnly()","dc2af3de":"getCEOAddress()","dc2b32e6":"getWeiInvested(address)","dc2ba357":"SetupQDA(string,string,uint256,uint256,uint256,address,address,uint256)","dc2c928a":"pausePlayerContracts(uint256,uint256)","dc2cf3f5":"timeElapsed()","dc2d46f8":"getWeiAmount()","dc2df955":"get_project_information(uint256)","dc2e47c8":"save4(address,bytes,string)","dc2e7b33":"cal(uint256,uint256)","dc2ebcbc":"whitelistMainSaleAddressMany(address[],bool)","dc2f56cf":"transferAgreement(bytes32,address)","dc2f7867":"setMaxLength(uint256)","dc2f8744":"bounties(uint256)","dc2f8a38":"setResult(uint256,uint8,int8)","dc30685e":"gas4Token()","dc3080f2":"spentAllowance(address,address)","dc30e253":"doFinalizeSale(uint256,uint256)","dc30f912":"addTokenization(string,string,uint8)","dc3134ae":"getIslandBattleStats(uint256)","dc31adee":"releaseMarketingTokens()","dc31e06c":"NEKOCOIN()","dc31e473":"opmAddress()","dc322802":"stage2Bonus()","dc32c72f":"secondReserveTimeLock()","dc3496d7":"allHashTypes(uint256)","dc35213f":"change(address,uint256[])","dc35a6bd":"LOWER_PRICE_RESET_PERCENTAGE()","dc35a900":"createOffer(uint256,uint256,uint256)","dc35ea16":"bonusInPhase1()","dc371e54":"deleteName(bytes32)","dc376392":"ETCCoin()","dc3774b3":"availableBalances(address)","dc382cbf":"sumAcceptedContrib()","dc391176":"delayedPayments()","dc39537a":"AVAILABLE_BONUS2_SUPPLY()","dc39d06d":"transferAnyERC20Token(address,uint256)","dc39e5fe":"removeOperationType(uint32)","dc3a1cad":"setIBalances2(uint256[],uint256[])","dc3a8372":"controllerApproval(address,uint256)","dc3a9433":"lockedFundsPercent()","dc3ab866":"checkEarnings(address)","dc3acebe":"getApp(address)","dc3c39aa":"TCDC()","dc3ccfdd":"transfer_tokens_from_contract(address,uint256)","dc3d1a2a":"addNewEmployeeWallet(address,address)","dc3d2b5c":"MiniMeIrrVesDivToken(address,address,uint256,string,uint8,string,bool)","dc3d4203":"createPatient(bytes32,bytes32,uint256,uint256,uint256,bytes32,uint256)","dc3d6305":"_transferFromAllArgs(address,address,uint256,address)","dc3da6e9":"IcoAddressSet(address)","dc3ecbb4":"debug_wei()","dc3ef685":"feePromille()","dc3f65d3":"createdByMe()","dc3f7536":"AdamToken()","dc40af1f":"oneTimeTickets(address)","dc414448":"_addToParticipants(address)","dc415804":"setFiscal(bytes32,uint256,uint256,uint256)","dc419fd8":"cancelOrder(bool,uint256)","dc41e726":"IndoJek()","dc420fd2":"withdrawPayoutFromBet(uint256)","dc4243f1":"setSalaryToken(address,address,address,uint256)","dc441754":"addDocument(bytes32,string,string,uint256,uint256)","dc44bb1c":"createEscrowFrom(address,address,uint256,uint256)","dc454c13":"EDROP()","dc45b93a":"contributorsCompleteCount()","dc45bfb3":"buyPack(uint256)","dc45d08e":"getEtherBalance(address)","dc45e27f":"getBonusBalanceByType(uint256,uint256,bytes1)","dc460933":"assignRole(address,bytes32,address)","dc46a76d":"getIdeasSinceLastDeploy(address)","dc46c813":"TwoExRush()","dc46d984":"numGamesCanceled()","dc47b3c1":"numberOfTokenIds()","dc47e5b7":"approveAndCall(address,address,address,uint256,uint256,uint256,uint256,bytes,bytes)","dc489c9b":"setAirdropper(address)","dc493790":"advisoryWallet()","dc4a307c":"createCommonAuction(uint256,string)","dc4b3115":"thirdPriceTime()","dc4baedd":"checkVerify(address)","dc4bc06e":"getUserCategory(address)","dc4c4005":"RemoveUser(address,address)","dc4d2ccd":"DiscountPercentToken(uint256,string,string)","dc4ece27":"BONUS_3_DAYS()","dc4ee13f":"overallTakenEther()","dc4f63cc":"cap_max()","dc502d64":"ethToBeDistributed()","dc50af26":"against()","dc51fba8":"SetherFinalized()","dc52696f":"tokenSupplyChanged()","dc52c514":"batchCreateDrawings()","dc533342":"reconciliationDateSet()","dc53903b":"fundsReceived(uint256)","dc540979":"POFOMO()","dc5418b1":"view32()","dc541eb7":"SelfllerySale()","dc542a79":"isMaximumGoalReached()","dc542c0f":"ALIToken()","dc547301":"setCurrentSupply(uint256)","dc54d919":"long_tokens(uint256)","dc555090":"updateTime()","dc555766":"createWithdraw(address,uint256)","dc566787":"topdownAndCashout(address,uint256)","dc570aad":"setPermission(address,string,bool)","dc57726f":"TokenGenerationEnabled()","dc57c1ef":"CopyrightToken(uint256,string,string)","dc57c323":"nextInputProfit()","dc57d553":"epochLast()","dc583801":"doubleyour5()","dc585713":"EtherFundMeIssueTokensCrowdfunding(string,string,string,uint256,uint256,uint256,address,address,string,string,uint256,uint256,uint256,uint256)","dc5936f0":"addCountry(bytes2)","dc596304":"NineLTDevToken()","dc597b47":"getAnimals(uint8)","dc5a2199":"ICO_WALLET()","dc5aa474":"lastBlock_f2Hash_uint256()","dc5acb90":"getOrThrow(string)","dc5b041b":"validationPassed(address)","dc5b0662":"getIndexByShip(uint256)","dc5b87cf":"getPartnerAllocation(uint256)","dc5bc461":"RadToken()","dc5bcafb":"UnicornToken(address)","dc5bf961":"totalTokensLocked()","dc5c3e06":"setFundraiseLimits(uint256,uint256)","dc5c9677":"changeSellerProposedValue(uint256)","dc5d184f":"setID(uint256)","dc5d9bfe":"migrationStep(uint256)","dc5df3fd":"ExperimentalPreICO(address,uint256,uint256,uint256,uint256,uint256,address)","dc5dff36":"LottoComplete(address,uint256,uint256)","dc5fced4":"totalRake()","dc5fe025":"forward(address,bytes,uint256)","dc5fe349":"releaseManyStakes(uint256[],address[],address[],uint256[])","dc602df2":"tokenValueMultiplier()","dc6037d1":"setbaseconfig(uint256,uint256,uint256,uint256,uint256)","dc60457c":"publicIssue(address,uint256)","dc6055dd":"BOUNTY_WALLET()","dc61164d":"getMySperm()","dc61456c":"cooAddCro(address)","dc622bcc":"setTokensAllocation(address,uint256,address[],uint256[])","dc62da61":"checkGameListed(address)","dc63a62c":"getFileListHead()","dc63f0be":"getSatOwed(address)","dc646367":"endSale(bool)","dc64752d":"collectsAccountDividends(address)","dc659907":"useModule(address)","dc661aaa":"mainICOFirstWeekEndTime()","dc6668db":"make_anonymous_withdraw(uint256)","dc667d0c":"getCountriesCount()","dc669dd4":"EndorToken()","dc689d3c":"getBaseDenomination()","dc693ca7":"totalWeiAmountSale1()","dc69a2d6":"tearDown(uint256)","dc69aa23":"SudanGoldCoinCrowdsale(uint256,uint256,uint256,address)","dc6b1cbd":"setUser(address,address,uint256,uint256)","dc6b7fb4":"LockedAccountThresholdUsdUpdated(uint256,uint256)","dc6b9b29":"notesLength()","dc6bbdf5":"totalContributionInWei()","dc6bc372":"TokenChangerBNT(address,address)","dc6bfbb5":"nextBallotId()","dc6c0cdd":"Share()","dc6c3ee4":"setMaxTokenCap(uint256)","dc6dd152":"playerRollDice(uint256)","dc6e7262":"refundTransactionByMediatorFee(uint256)","dc6e9cf9":"_MINIMUM_TARGET()","dc6f39a3":"TriggerCooldown()","dc6ff38e":"MAIN_MAX_CAP()","dc7049bf":"annualManagementFee()","dc706a3a":"VictusToken()","dc70ab02":"setTotalExecutedPerDay(uint256,uint256)","dc718791":"changeRules(uint256,uint256,uint256,uint256,uint256)","dc71db43":"worldCupResultPart2()","dc720528":"AgriChainProduction()","dc726205":"rates(bytes32)","dc730c50":"initialSingleWithdraw(uint256)","dc73e49c":"swapToken()","dc7454dd":"amountReleased()","dc74665e":"totalLeaderboards()","dc75f2db":"multiowned(address[],uint256)","dc760edf":"hardCapCrowdSale()","dc76dc8d":"applyForCertification(string,string,string,uint256)","dc76fabc":"getSpotPrice()","dc77e5e1":"serviceTokensBurn(address)","dc787bba":"getCountTempHolders()","dc799f88":"BaseCertoChainContract()","dc79b176":"getUserGroup(address)","dc79c2ef":"addUser(bytes32,bytes32,bytes32,bytes32,bytes32)","dc79d069":"investorSupply()","dc7abeb3":"OPENSOURCE_TOKENS()","dc7ac1ba":"lendVault()","dc7b808e":"callLibSet(uint256)","dc7bbd72":"hasThreeStepWithdraw()","dc7cbfab":"priceCounter()","dc7df9d8":"testToUint(int256,bytes)","dc7e5762":"goNextPeriod()","dc7e88e8":"amountOfBooked(address)","dc7fc898":"bankermasterReq()","dc80035d":"setFoo(uint256)","dc801db6":"MyYLCToken(uint256,string,uint8,string)","dc80aaee":"DeltaToken()","dc81e2b8":"DarenHui()","dc82697c":"getContractValue()","dc835df5":"Sense()","dc8369ce":"myStakesOnCountry(uint256)","dc8452cd":"required()","dc845934":"getPlayerBetResult(uint256)","dc846d95":"Own()","dc84e79e":"raisedPreSaleUSD()","dc851b02":"itcERC20()","dc85561b":"firstRoomAvailable(string,uint256[])","dc85b996":"window1EndTime()","dc86e6f0":"baseUnit(bytes32)","dc87cfbf":"executeTransaction(uint256,bytes)","dc885527":"burnUnmintedTokens(uint256)","dc88e838":"getOAR()","dc8a0f65":"change_game_dice(string)","dc8b0203":"clearApprovalAndTransfer(address,address,uint256)","dc8bc70d":"finalizeSale(address)","dc8c06d8":"addEmployerFeedback(address,uint256,address,string,uint8)","dc8d1095":"simpleSubmit(uint256)","dc8d2696":"inboxSize(address)","dc8d26ad":"changeICODates(uint8,uint256,uint256)","dc8ee41e":"coldWallet1()","dc8f2ae0":"addExplicitPosition(uint32,int64[2])","dc8fbb44":"deathData_f12()","dc903eb7":"addChunk5ToWhiteList()","dc904e69":"waveCap3()","dc90e42f":"restrictedStockOf(address)","dc91868f":"backTo(address)","dc91b634":"Ticketh()","dc91ea68":"PayerStringUpdated(string)","dc92beec":"setManyWhitelist(address[])","dc93f7c9":"feePayedPerReserve(address)","dc94b4a4":"doPay(bytes32,uint256,uint256)","dc94e45d":"setDistrito(uint256)","dc9513c1":"JustifyClaimWithWitness(uint8)","dc951fdc":"totalOverthrows()","dc9564d5":"buy(uint256,string,address,address,address,address)","dc9590f0":"_START_TARGET()","dc965479":"FooContractCall(address)","dc97a4f9":"getTotalUnPayedDividendsAmount()","dc97d962":"getInt(bytes32)","dc97e366":"stageIndex()","dc9861db":"updateMeDao(address)","dc988b40":"allowWorkerToContribute(address,address,address)","dc992aa0":"minUSD()","dc998901":"SaveData()","dc9a1535":"isPublic()","dc9a190e":"isAllowedTrade(address)","dc9a1df3":"SafecontractsTREXToken()","dc9ac994":"iconiqSaleOngoing()","dc9ae17d":"burn(bytes,address,uint256)","dc9b6d68":"getTimeSinceLastEvent(address)","dc9bb7db":"noKing()","dc9c6e15":"_myinitialSupply()","dc9d625b":"setMaintainance(bool)","dc9deea3":"amountPurchasedWithDecimals()","dc9deeff":"setPresellPrice(uint256)","dc9e7a87":"TransferedERC20(address,address,uint256)","dc9e9ba0":"allowStart()","dc9eb903":"Tbond1()","dc9ebff7":"getTotalInvestedEther()","dc9f0622":"transferManual(address,uint256,string)","dca0b866":"TwoPersonContract(address,address,bytes32)","dca27d5e":"setV_R4(uint256)","dca44b39":"setPerOneEther(uint256)","dca5f188":"AddressBook()","dca60034":"isMapped(string)","dca6058c":"canSetTransferable()","dca67e5d":"_createResident(string,string)","dca6f378":"withdrawTokensFromPool(uint96)","dca703d0":"LogSetQuestionFee(address,uint256)","dca73e6b":"getMyStores()","dca7bcbe":"getWords()","dca80bc6":"EtheremonRankBattle(address,address,address)","dca92eb5":"terminateLiquidation()","dca95419":"recoverSigner(bytes32,string)","dca9fd5b":"editStatus(uint256,string,uint256,uint256,int8)","dcaa5620":"findNextWeekday(uint256,bytes)","dcaabed7":"getLastDeedByAddress(string)","dcabf93f":"refundstate()","dcac652e":"setOwnerShare(address,uint256)","dcac69c3":"inheritedPure(uint256,uint256)","dcace702":"getClientLastPaidRate(address)","dcacf19a":"finalizeAndRestart(address)","dcae2cb4":"getWinningPrize(uint256)","dcaee066":"setStakeDisbursementAddress(address)","dcaeea15":"setadmin()","dcaf391e":"totalAirDropToken()","dcafa43e":"SaxoToken()","dcafaec2":"setCostToCreateGame(uint256)","dcafee05":"killBalance()","dcb01759":"salesEth(address)","dcb032ce":"addNodeGroup(string)","dcb04503":"testConcatStorage33Bytes()","dcb12421":"isSoftcapOn()","dcb1c012":"ChowSale()","dcb27883":"CallAborted(address,bytes32)","dcb31b82":"isConfig()","dcb35d06":"getTransactionApproveCount(uint256)","dcb36063":"crowdsaleMinter()","dcb3ff58":"updateDividendBalance(uint256,address,address,uint256)","dcb46e38":"setWorstCaseRateFactor(uint256)","dcb4775e":"tokenPartner()","dcb4876f":"removeAddresses(bytes32[])","dcb5930a":"ratingContractAddress()","dcb6af48":"calcAverageICOPhaseKeyPrice(uint256)","dcb7e083":"teamTokensInitial()","dcb7f86f":"getWinningPayoutDistributionHashFromFork()","dcb814ef":"presaleWhitelistDiscount()","dcb951de":"pushDividends(address)","dcb9528e":"getBiddingInfo(address)","dcb9d457":"updateClientOfContractorManagers(uint256,uint256)","dcba03da":"MINEA()","dcbac60c":"winPrizes(uint256)","dcbad97b":"setEndIcoMainICO(uint256)","dcbc1288":"m_SMR()","dcbc1c05":"Deposit(address,address,uint256,uint256)","dcbc84ab":"coinsIssuedMkt()","dcbda04c":"setCrowdsaleInterface(address)","dcbe7cf1":"addInsuranceProduct(uint256,uint256,uint256,string,string,bytes32)","dcbf16d4":"Normal(uint8)","dcbfa4b7":"addSkills(bytes32[])","dcbfe3d5":"clearRequests(bytes32)","dcc0ccf3":"Dao(address)","dcc0e622":"setTokensForCrowdSale(uint256)","dcc1fd02":"angelSaled()","dcc23730":"setCurrency(uint256)","dcc279c8":"setHalted(bool)","dcc33e0b":"updateOperationalAddress(address)","dcc42e9b":"cards_blue_total()","dcc439cf":"updatePlayersGooFromPurchase(address,uint256)","dcc5237b":"FlatPricing(uint256)","dcc53305":"getMail(uint256)","dcc60128":"getProjects()","dcc6131c":"checkBalance(uint256[],address)","dcc66b4b":"addRelationshipBindingWineryOperation(bytes32,uint256,bytes32,int256)","dcc66cc2":"getDelegate(uint256)","dcc6762c":"withdrawalInitiate()","dcc6e7ad":"refundEth(uint256)","dcc71ed4":"AdvisorsAndFounders(address,uint256)","dcc76a92":"Ranking()","dcc7f6b0":"Ethen(address)","dcc819c8":"computeCntrAmountUsingUnpacked(uint256,uint16,int8)","dcc8592c":"KOCMOCToken()","dcc8a508":"partnerBonus(uint8)","dcc9a58c":"testCreateGame(string,string,bool,string,address,string)","dccb0c89":"test_1_someTest()","dccb37f1":"initialTokenBalance()","dccb5afb":"_emitTimeAdded(uint256,uint256)","dccb70a7":"setEnableAllTransfers(bool)","dccb98da":"SparkToken()","dccbb14b":"payInterests()","dccbfa2a":"minInvestedCap()","dccc6c94":"fireCloseProposalEvent(address,uint256)","dcccb41d":"setTransferAddress(string,address)","dccd4315":"startingAt()","dccdc893":"setNewWhiteList(address)","dcceaaa8":"sendShipmentTo(address,uint256)","dccee5b2":"posibleDividendsOf(address)","dccf77ce":"setCurrentBlock()","dccfbb62":"overthrow(bytes23)","dcd0fa9e":"get_arbits_min_contribution(address)","dcd1e670":"checkAmount(uint256)","dcd320a0":"bouncyCoinToken()","dcd3c2e5":"QLALA()","dcd4090b":"getStage3Start()","dcd4eb14":"addNewTicket(uint256,bytes32,uint256,uint256,uint256,bytes32,string)","dcd58e2f":"FUTURE_ME_ADDRESS()","dcd65479":"numPeriods()","dcd6561d":"currentSaleSold()","dcd7dd2e":"setKYCLevel(address,uint8)","dcd8023c":"TokenBranch(uint256,uint8)","dcd93691":"retrieveOnFail()","dcd9c289":"getBAA(bytes32,address)","dcda0c8f":"requestDiplomaByNr(uint256)","dcda2385":"TransferSellAgentCreators(address,uint256)","dcda4554":"dazoToken()","dcda4bf3":"mOwner()","dcdaa35b":"mintAmount2()","dcdb622b":"MessageSet(string,uint256,uint256,address)","dcdbbe37":"lockTransferFor(address,uint256)","dcdc055a":"doBuy(address,uint256)","dcdc7254":"admin_set_shopStorePrice(uint256)","dcdc7dd0":"mint(address,uint256,bytes,bytes)","dcdd6d38":"getHolderAddresses(bytes32)","dcdd9af2":"DEX(address,address,address,uint256,uint256,uint256)","dcdda6d7":"teamUnfreeze()","dcde0019":"disapprove()","dcde835e":"NewSale(uint256,uint256,uint256,uint256)","dce0b4e4":"creationFee()","dce11375":"emitter()","dce1d3c6":"addTokenPendingToken()","dce23e97":"getPriceValue(bytes32)","dce293a7":"minLength(uint256)","dce2b4c1":"getMarkup(uint256)","dce2f2dd":"Vouched(address,bytes32)","dce388b6":"payeePartsToSell()","dce4a447":"at(address)","dce4ae87":"DigixConfiguration()","dce4b34e":"submitAnswerByArbitrator(address,bytes32,bytes32,address)","dce4fa38":"IcoTokens()","dce57755":"getBlockLength()","dce579d1":"extendIco(uint256)","dce59311":"didOwnerEndCrowdsale()","dce59c00":"addPayee(address)","dce5c5a9":"norsefirePrice()","dce5c757":"cool()","dce5f277":"investorsAddress(uint256)","dce6417d":"DebitCoinToken(string,string,uint8)","dce722dd":"getJobSkills(uint256)","dce77d84":"getCurrentRate(address)","dce85216":"moveUnsoldTokens()","dce98784":"NiewGold()","dce9f6c3":"SuperConductToken()","dcea0a64":"ADX()","dcea7113":"buyOutPrice()","dcea80a5":"exchangeIEO()","dceacb93":"_createNewBadge(address,uint256)","dceaf74c":"youAre(address)","dceb3e7d":"getConfirmations(bytes32,address)","dcebb122":"extendSale(uint56)","dcec5ecc":"calcNewEmployeePoolOptions(uint256)","dcec7204":"EtherNeo()","dced2f1a":"currentCharId()","dceda27b":"getRegularCarSupply(uint256)","dcede2c3":"testIsSameSign()","dcedeeed":"claimIfNeededThenSteal(uint256,uint256,address,uint8,bytes32,bytes32,uint256,uint256)","dceeeae8":"ServiceController(address,address,address,address)","dcef8165":"CoinBirdDEX()","dcefa538":"buyTokens(address,address,uint256)","dcefcb8e":"extractCallData(bytes)","dcf00b6e":"getAccreditationActive(bytes32,bytes32)","dcf1579c":"thirdBonusPercent()","dcf1a9ef":"commissionBalance()","dcf1df05":"showValue(address,address)","dcf219f2":"setLootboxFee(uint256)","dcf34a91":"SpendingUnblockedEvent(address)","dcf3fb2a":"revoke(address,address)","dcf537b1":"multiply7(int256)","dcf63591":"course()","dcf6a592":"isGreaterThan(uint256,uint256)","dcf72c10":"buyTo(address)","dcf73856":"generateGroups()","dcf7bb5c":"changeTarget(address)","dcf7c0d0":"TokenTrader(address,uint256,address,uint256,uint256,uint256,bool,bool)","dcf7c2f9":"asset(uint8,string,bytes)","dcf8045e":"tiersInitialized()","dcf8113e":"campaignEndedSuccessfully()","dcf86587":"_transferWallet(address)","dcf8f13a":"getCurrentItemPrice(uint256)","dcf90793":"IcoWallet()","dcf91ea9":"MoftakToken()","dcf946c2":"getAllParentIds(bytes32)","dcf97439":"revealX(uint256,uint256)","dcf988d6":"GetFeeBalance(uint256)","dcf9bbec":"hasVerifiedAttributeIndex(address,uint256)","dcf9e836":"setProviderLimits(address,uint256,uint256)","dcfa6ac4":"buyChamp(uint256,address)","dcfa9222":"transferAccessTo(address,address)","dcfa9cc0":"testProxyCall()","dcfac095":"CPX(uint256,string,string,address)","dcfc3b46":"getAdIdByUser(address,uint256)","dcfc4430":"groomAddr()","dcfcda2b":"changeEscrow(address)","dcfda779":"allowCrowdsaleAddress(address)","dcfe63a9":"finishPrivateSale()","dcfe64e9":"SHA256()","dcfe8eb4":"SetIPR(string,string,address,string,string,uint256,string,string)","dcff2f76":"createAndJoinCDP()","dcff5581":"NewFeeAddress(address)","dcfff171":"setDelegadoDeDistrito(bytes32)","dd001254":"nameToTokenId(string)","dd00182b":"dogeAddress()","dd004ca8":"_endEdit()","dd009f48":"recursiveCeil(uint256,uint256,uint256)","dd00a9dc":"close(uint256,uint256,bytes)","dd00b605":"normalCheck()","dd012a15":"setIt(uint256)","dd01f781":"goToWork(uint256)","dd01f9e4":"LogNeededBalance(uint256)","dd022727":"getGameByIndex(uint256,bool)","dd029560":"CoreLayer()","dd02e30d":"isValidTxPaymentForKWh(bytes32)","dd03447f":"DiamondCash()","dd052519":"withdrawAllPlayers()","dd05db9a":"amountPerRelease()","dd0669d4":"getZCount(uint8,uint8)","dd0702d6":"changeTeamPoolForFrozenTokens(address)","dd083f20":"teamPart()","dd0860a8":"IsOwner(address)","dd08b5c9":"disableRedemption()","dd090981":"setName(uint256,uint256,bytes32)","dd09de33":"soldTokensOnIco()","dd09e13c":"totalRegistrationBonusAmount()","dd0a1019":"isReserveGenerated()","dd0ac8ac":"HoldCrowdsale(uint256,uint256,uint256,uint256,uint256,address,uint256,uint256,uint256,uint256,address)","dd0b1af5":"setMythexTokenAddress(address)","dd0b281e":"start(address)","dd0b7ffe":"setBuyNowPrice(uint256)","dd0c189c":"updateFirstExhangeRate(uint256)","dd0c42ab":"updateRequiredEntries(uint16)","dd0cf15d":"sendFund()","dd0cf7d4":"stopGuess(uint32,bool)","dd0d74ff":"IssueBank(address)","dd0e2373":"voterAddresses(uint256)","dd0e3902":"setData_6(string)","dd0e7832":"transferWithChange(uint256,address,address,address,uint256,uint256,bytes,bytes,bytes)","dd0f0808":"genEvent()","dd0f5a9a":"presalePiEnd()","dd0fa641":"winning_bets_total()","dd100efa":"getIcoEnded()","dd10d97e":"getPlayerWaiting()","dd11247e":"totalTickets()","dd114c22":"publish(address,uint256,address,uint256)","dd1219fd":"powerSwitch(bool)","dd12b51f":"getPermissionCheck()","dd137b5d":"toBase58(uint256,uint8)","dd13e20a":"forgeWeaponRarity(uint256,uint256,uint256,uint256)","dd13fd5f":"_acceptContribution(address,uint256,uint8)","dd14ab79":"updateTimestamp(bytes32,uint256)","dd151d1e":"pushAddressArray(bytes32,address)","dd155f3f":"removeAddress(uint256,address[])","dd15b66c":"MyWill(address,string,string,string,address,uint256,uint256)","dd15f993":"depositUSD(address,uint256)","dd16d981":"isCampaignValid(bytes32)","dd16fe09":"getCashBackObject(uint256)","dd17e151":"sendabr(uint256)","dd17eaec":"setMultipleRates(bytes32[],uint256[])","dd18b250":"getIdArray(address,address,string,string)","dd192de7":"affiliatesAddress()","dd193e7b":"addPerSell(uint16,uint256,bool)","dd1956b0":"InfiniviToken()","dd1a293a":"burnTokensFrom(address,uint256,uint256)","dd1a56a7":"WellnessToken()","dd1a5f0d":"_grandPVPLoserReward(uint256)","dd1a68c1":"report(uint16,uint16,uint8)","dd1aa549":"PARTNERS_WALLET()","dd1b1928":"getInputSize(uint256)","dd1b6137":"push(uint256,uint256)","dd1b7a0f":"nonFungibleContract()","dd1b89c6":"freezeExists(uint256)","dd1b9c4a":"POOL_FEE()","dd1bb3d1":"confiscateBalance(address)","dd1bb6f5":"TokenICOGAT()","dd1c35bc":"recycle(uint256)","dd1cdf84":"keybasePubURL(string)","dd1d5e64":"incGenLabFight(uint256)","dd1dbc3a":"calcUnMaskedEarnings(uint256)","dd1dc0ad":"RequestSale()","dd1dffb7":"getFundsCollected()","dd1e2651":"getUserKey(uint256)","dd1e4e11":"_getRandom(uint256)","dd1ee3d7":"whaleAddress()","dd1eee44":"couponTokenSaleAddr()","dd1f969b":"PURCHASE_AMOUNT_RATE_REFERENCE()","dd1fc642":"_approvedFor(address,address,uint256)","dd20a53e":"createTournament(uint256)","dd215410":"getWinnersIndex(uint256)","dd217ce1":"getAddusers()","dd218ff2":"addPreIcoPurchaseInfo(uint256,uint256)","dd21f395":"t_3rd_StageEnd()","dd22148f":"investedSumOnPreIco()","dd228801":"setAffiliateRate(uint256,uint256)","dd234dc7":"PixelBought(uint256,bytes32,uint256,address,address)","dd23795f":"bobMakesEthDeposit(bytes32,address,bytes20,uint64)","dd238603":"unsetWhitelist(address)","dd2407d3":"sendOnlyHash(bytes32)","dd242fa4":"staff_4()","dd253cd0":"setTransferMinimumFee(uint8)","dd2594af":"changeTokenApproves(uint256)","dd27efa0":"_packPVPData()","dd27fcad":"EternalCoin(uint256,string,string)","dd280c7a":"requestDetachmentOnPause(uint256)","dd288173":"doStore(uint256,uint256,bytes32)","dd28d12b":"ZILINGGOSupply()","dd28d14d":"getMembersInGroup(uint256)","dd294142":"institutionTimeLock()","dd2a07a0":"LCS()","dd2ac276":"genToLuck(uint256,uint256)","dd2ad311":"scheduleCall(bytes,uint256)","dd2bcae0":"DeviceIsDeactivated(address)","dd2c4d3d":"AdoptionRequestCancelled(bytes5)","dd2c888e":"balanceHistory(address,uint256)","dd2d2a12":"minimum(uint256,uint256)","dd2d4ea0":"tokensMain()","dd2e0ac0":"unlockToken(uint256)","dd2f4ebd":"getNumberOfGames()","dd300c6d":"getSettingChangeConfirmationCount(uint256)","dd301057":"noOfTiers()","dd3032bc":"RoundCHardCap()","dd30651f":"activateUser(address,uint256)","dd3129a9":"calculateAllBuyBackSum()","dd31f462":"clearDebt()","dd321018":"levelItemClass()","dd324fe7":"PieceStandardToken(uint256,string,uint8,string)","dd3260fc":"checkOpenTimer()","dd32858e":"withdrawWinner()","dd34abd3":"transferDirectorA(address)","dd34c9a3":"capFlex()","dd34dab8":"startTimeOfSaleLot4()","dd34e129":"PriceTest()","dd34e7be":"Vault(address,uint256,uint256)","dd365b8b":"pwn()","dd36b59c":"getPlanetOwner(uint256)","dd36e18b":"ContractStatus()","dd37be12":"mod(uint32,uint32)","dd3840ef":"PRIVATEPLACEMENT()","dd386239":"manuallySetNumRewardsAvailableForChildAddress(address,uint256)","dd397e03":"preIcoTarget()","dd3b014c":"getLatestVersion(bytes32)","dd3bd008":"getReadyTime()","dd3c407f":"_set7()","dd3ccd84":"percentForHelpCoin()","dd3d0bee":"changelp18(address)","dd3e5f47":"_sharesValid(uint256,uint256)","dd3ef6a6":"deathData_v12()","dd3f2893":"_processTokensPurchase(address,uint256)","dd3f8608":"FloatGameToken(bytes32,address)","dd3f9526":"_controller()","dd3fa136":"ship(string)","dd3ff4f6":"sendFeeToWallet(address,address)","dd413da0":"Vendi(uint256)","dd4198f4":"getScore(uint8,bytes32)","dd41cc2f":"getQuestionCount()","dd41e1c7":"redeemFrom(address,uint256,string)","dd420fc5":"auditorComment()","dd4253f7":"MeosunToken()","dd42c228":"totalLockedFund()","dd42faf7":"window3TokenExchangeRate()","dd4314b2":"unique_players()","dd443c7b":"cancelMarkets(uint256)","dd449a83":"allower()","dd44a15c":"allocateTokensForContributor(address)","dd450d4e":"transferFromBankToAccount(bytes32,uint256)","dd457c7f":"balancesSet()","dd45e247":"getUserListSize()","dd462e2d":"withdrawAmountHashing(uint256,uint256)","dd467064":"lock(uint256)","dd473d2b":"withdraw_all()","dd47fe15":"sendToTarget(address,address,address,address,uint256)","dd48087f":"balanceOfContract(address)","dd486c35":"ownerWantMyEther()","dd489e44":"setSystemStartingPriceMin(uint256)","dd48d911":"totalSellOrders()","dd49756e":"depositTokens(uint256)","dd49f1c8":"BooMToken()","dd4a055b":"buySale(uint8,address)","dd4a8361":"setWhitelistEntries(address[],bool)","dd4a8f61":"contractorManager()","dd4aac73":"SELLER_STEP_2_GET_PASS()","dd4aeb92":"manageMinting(bool)","dd4bc101":"weightOf(address)","dd4bd4b7":"getProjectMilestoneStartWindow(bytes32)","dd4c97a0":"approveNode(address)","dd4dfb62":"kUnit()","dd4e6993":"leerGat()","dd4e8823":"poiLockup()","dd4f1f2a":"multipleHomocide()","dd4f5f0f":"withdrawBBO()","dd4f8f74":"roundStartTime()","dd506e09":"changeRound()","dd50e9d4":"clearSummonNum()","dd510361":"setTransformTarget_pool(address,uint256)","dd5108d1":"addressToTotalDonationAmount(address)","dd510e98":"newLockUpAddress(address)","dd515cdb":"checkVotingForStartPayment()","dd51faa2":"setGas(uint256)","dd523559":"devuelveAddressUsuario(bytes32)","dd5244b4":"testTryProxyCallWithValue()","dd53c301":"mintContract(address,address,uint256)","dd54291b":"tokenCap()","dd54a62f":"content(string)","dd54cc0c":"advBtyWallet()","dd550958":"getOwnerAddress(uint256)","dd55f11b":"deleteCitizen(uint256)","dd55fba0":"createSecondPromoCollectible(uint256,address,uint256,address)","dd563726":"GoingGems(uint256,address)","dd57d5c5":"setTrust(address)","dd585e7b":"newincomelog(uint256,string)","dd5891b3":"join(address,string,string)","dd58f5d9":"isIcoFinish()","dd592a32":"topUpAmount()","dd595328":"untransform(uint16)","dd59c954":"mintBatch(bytes32,bytes32,bytes32,bytes32,bytes32,address)","dd5a4efd":"GameRefunded(uint256,uint256,uint256)","dd5a7f40":"getContractCreationTxGasprice()","dd5ac448":"payoutReferrer()","dd5b23df":"transferBond(address,uint256)","dd5b29b7":"toB32(uint256,bytes)","dd5c2678":"KappyKoin()","dd5ca673":"setMintRequestStringMap(uint256,int256,string,string)","dd5cba71":"CHXTokenSale()","dd5dcd52":"findActiveRange(address)","dd5dd552":"_cancelOrder(address)","dd5dd8f2":"timeGap()","dd5ddfe8":"setPermission(address,uint8)","dd5df59c":"nonEtherBuy(address,uint256)","dd5e403c":"IcoFund()","dd5e8410":"jackpotMedium()","dd5ea752":"burnAndConvertToQUA(uint256)","dd5f63fd":"niceguy3()","dd5f9a22":"STSTEST5()","dd604fcb":"EgyptianPound()","dd60b394":"giveFreezePermission(address[],bool)","dd60c898":"participantsCount()","dd611e8d":"Setter(uint256)","dd616a45":"ZeroCap()","dd62b1a0":"LalaToken()","dd62ed3e":"allowance(address,address)","dd62f6f3":"getPayoutDistributionHash()","dd63133a":"onPurchase(uint16,uint16,uint8,address,uint256)","dd63f7d0":"functionReturningValue(bytes32)","dd644f72":"basisPointsRate()","dd66111d":"gameRoundEnd()","dd67a360":"OrderLifeCycle()","dd681e51":"ecosystemGrantsReserveWallet()","dd68b386":"TransactionRefundedAfterExpiry(uint256,uint256)","dd6996a3":"LOL3()","dd6ad764":"withdraw(uint8,address)","dd6afdfe":"Chou(uint8)","dd6b2fc6":"isBarCodeData(bytes32)","dd6b996d":"endDividendPool()","dd6c1394":"GazeCoinCrowdsaleWhitelist()","dd6e66d0":"tokenHoldersTotal(address)","dd6e8e6a":"_markRedemptionFulfilled(bytes32)","dd6ed59a":"initSubPayees(bytes32,address[],int256[])","dd6f0f19":"ApplicationIsInDevelopment()","dd719d2c":"airDrop(address,address,address[],uint256[])","dd722127":"adminRemove(address,string)","dd7221e8":"LogPause(bool)","dd727ea6":"runJackpot()","dd729530":"add_shield(uint16)","dd72ae4e":"availableICO_w1()","dd73d17b":"getComment(address,address)","dd751310":"isRegisteredPublicKey(uint256)","dd75e7ff":"getENow()","dd75ecce":"getVestingAmount(address,uint256)","dd76d2fa":"setIdArray(address,uint256,string,string,address[])","dd787875":"setupSale(uint256,uint256,address)","dd791ce5":"tokenDec()","dd796b07":"indexOfCardAddress(address)","dd79cc6a":"secretBidCount()","dd79e33e":"splitIdentifiers(string)","dd7a1722":"accountLocked()","dd7aabc8":"_transferHelper(address,uint256)","dd7b3e97":"buyoutsEnabledFromTimestamp()","dd7b3f26":"bytes32ToBytes(bytes32,bytes32)","dd7bff82":"removeCandidates()","dd7d168a":"getEthBullet(string)","dd7d6bb0":"getLpAskPrice()","dd7db870":"addFreeVineyard(address)","dd7dde04":"maxTeamSize()","dd7e11be":"InternationalPaymentToken()","dd7eba7a":"ValentineRegistry()","dd7f2225":"MiCarsICO()","dd7f88ee":"date_start()","dd80f2a6":"Vibrancier()","dd817963":"lastBlock_f0Hash_uint256()","dd819721":"setNFTbyTokenId(uint256,string,bool)","dd838808":"endMigrationPeriod()","dd83a303":"cancelMortgage(uint256)","dd83c825":"backersAddresses()","dd8432fe":"getRemainingTokensForSale()","dd847dfe":"get_contract_money()","dd84acaa":"addressesAllowed(address)","dd859739":"SetBeneficiary(string,string,string,string,string,string,string,string,string,string,address,string)","dd85b1dd":"setServiceProvider(address)","dd85b82e":"EthealWhitelist(address)","dd8617ca":"payether(address,uint256)","dd86210a":"medalSymbol()","dd864883":"changeApprovalCore(address,uint256,uint256)","dd86f719":"COMMUNITY_BOUNTY_HOLDER()","dd87c9f0":"exeStatus()","dd897767":"isRealWorldPlayerMintingEnabled(uint128)","dd898fa2":"MinterStorePoolCrowdsale()","dd89daa5":"getBBFarmID(bytes4)","dd8a0c56":"vacate(address)","dd8ad12a":"executeAppReturn(bytes32)","dd8b0ff6":"rmax(uint128,uint128)","dd8bd8cb":"Patient(address)","dd8bf1f5":"setDistrict0xNetworkToken(address)","dd8c8855":"addWarehouse(uint256,uint256,bytes32)","dd8d11e2":"isValidSubscription(bytes32)","dd8d149d":"tokenCrowdsaleRate()","dd8d1cef":"totalUserCampaigns(address)","dd8d4c40":"getCallers()","dd8e668c":"FUND_FRAC_BOT()","dd8ee602":"log(bytes,uint256)","dd8ef66b":"cancelTrade(address)","dd8f3195":"HyperChipsToken()","dd8fee14":"regulator()","dd905097":"organisationWallet()","dd90c403":"getAccountFeed(address,uint256,uint256)","dd9180ea":"tokenReservationAllocated()","dd91f1f5":"toggleAuthorization(address,address,bytes32)","dd924594":"distributeAirdrop(address[],uint256[])","dd92a8b0":"confirmSell(uint256)","dd932c5b":"voteEnd(uint256)","dd93890b":"setMeta(uint256,bytes32,bytes32)","dd93c74a":"setInactivityReleasePeriod(uint256)","dd946033":"right81(uint256)","dd952089":"getTaxDataSignatures()","dd9546b1":"minInvestments()","dd9555f1":"withdrawBidForCollectible(uint256,uint256,int256)","dd955c44":"sellEth(address,uint256)","dd955d4c":"rawTransfer(address,bytes32)","dd9568b0":"messageInfo(uint256)","dd96440e":"DDD()","dd967b0b":"refundLoan()","dd9815a2":"claimPlayerProfit()","dd982bdf":"FaceBookCoin()","dd999ade":"cleanUpRounding()","dd9a76ff":"pay(address,address,uint256,uint256)","dd9a9e2c":"CORReserveAccount()","dd9bc47e":"finish(address,address)","dd9bf998":"authorizeTradingAccounts(uint256)","dd9bfb04":"bakanceOfBeer(address)","dd9cfc4b":"tokenSalesByAsset(address,uint256)","dd9d687e":"namehash(bytes32)","dd9dd688":"calcStopPrice()","dd9e3848":"NewHolder(address)","dd9e4094":"makeMemChange1(uint256,uint256,uint256,int256)","dd9e7b1b":"max_raised_amount()","dd9ea299":"getLastDepositId()","dda0268d":"queryBetUnit()","dda0c1d6":"adminAmendBallot(uint32,string,uint256,uint256)","dda0e4ba":"finishAllGames()","dda0f1bb":"sendToTicker()","dda13903":"GoldOwner()","dda2d923":"setIcoAddress(address,address)","dda3342b":"ReplicatorFactory()","dda342bb":"list(address,uint256,uint256)","dda38380":"CFTRAD()","dda3baff":"showlevel(address)","dda44b10":"buyRecipient(address,uint8,bytes32,bytes32)","dda477fd":"walletTransfer(address)","dda4fa8f":"setReserveWallet(address)","dda5062c":"userIds()","dda51424":"right80(uint256)","dda55b18":"GxTraders(address)","dda5d5cb":"saosao2()","dda5d799":"PRT()","dda6020b":"freezeMintUntil()","dda61c00":"getIsSecurityWalletReg(address)","dda63359":"setSellToContract(bool)","dda69410":"add(address,uint16,uint8,uint8)","dda6abb8":"sendToVestingContract()","dda6c3ce":"checkWinning(uint256)","dda72292":"BONUS_TIER_6_LIMIT()","dda81c15":"TIER_4_BUYIN()","dda89912":"setExchangeDetails(bytes32,bytes32)","dda943d6":"maxSet()","dda9939c":"Store(address[])","dda9f1a3":"HODLRegistration()","ddaa26ad":"START_TIME()","ddaa4c48":"granularPreallocate(address,uint256,uint256)","ddaa7e02":"GetTickSize3(uint256)","ddaaff27":"generateSection()","ddac6654":"validUntil()","ddad2ffe":"newNode(address)","ddad3ca1":"tokenMaxCap()","ddae2e26":"__save128(uint256[])","ddafaf4d":"reclaimNtvuEther(uint8)","ddb12a35":"countPayOrder()","ddb141c2":"execute_transfer(uint256)","ddb1bdc8":"credit(address,uint256,uint256)","ddb1ede9":"canceledBookingfc(uint256)","ddb22537":"withdrawDeadBids()","ddb25d71":"GBPproxy()","ddb31cea":"TEAM_TOKENS_LOCK_PERIOD()","ddb4897a":"NitroCoins()","ddb49f98":"SpiceNinja()","ddb5b3ac":"SellTokens()","ddb62333":"readTaskState(string)","ddb6af4c":"setTimeStamp(uint256,uint256)","ddb6e116":"vote(uint16)","ddb72188":"chAirDropLimit(uint256)","ddb792a0":"admin_from_To_transfer(address,address,uint256)","ddb863be":"multiPartySend(address[],uint256[],bytes)","ddb8b099":"itemNameOf(uint256)","ddb8f090":"GlobalTransfersUnlocked(bool)","ddb9341b":"SetBuildingDataArray(uint256[])","ddb9769c":"_settingsApplied()","ddba8c45":"verifyEscrow(uint256,address,address)","ddbb4ab4":"_bytes32ArrayToString(bytes32[])","ddbbc35c":"searchByName(string)","ddbcb5cb":"registerAs(address,bytes32,address)","ddbcb5fa":"MIN_AMOUNT()","ddbcf3a1":"ensNode()","ddbdf242":"traders()","ddbe7c41":"NeverEndingApp()","ddbe8f09":"voteEnd()","ddbe92d3":"setBondFundAddress(address)","ddbf5856":"completeLottery()","ddbf5c8f":"checkFee(uint256,uint256)","ddbfbdbf":"ETHERKUN()","ddbfd63e":"AddGoods(uint32,uint32,uint256,uint32,uint32,uint32,uint32,uint8,uint8,uint8)","ddc002e8":"TokenSold(address,uint256,uint256,bool,bool)","ddc0db14":"AmountBonusPricing(uint256[])","ddc12019":"_triggerCooldown()","ddc23059":"SchemeRegistrar()","ddc23ddd":"erc165InterfaceSupported_NoCache(address,bytes4)","ddc33450":"MNLTGUNE()","ddc35950":"setOwner(uint32,address)","ddc3e344":"_sellPutToClose(uint256,uint256,uint256,uint256,address)","ddc4aacf":"token4Gas()","ddc53c2c":"lastFreeBlock()","ddc541dd":"publisher(address)","ddc63262":"harvest(uint256)","ddc645f8":"CollateralReturned(uint256)","ddc6a171":"allowance(address,uint256)","ddc6f83e":"setIdent(string)","ddc6ffaa":"SecuredLedgerToken()","ddc86af6":"extractById(int128)","ddc8bb54":"PriceOf1000TokensInUSD()","ddc8d7a6":"_removePauser(address)","ddc983f2":"bonusEnds50()","ddca15de":"ServiceContract()","ddca337e":"SetMaxChequeValue(uint256)","ddca3f43":"fee()","ddcb1a94":"serviceBurn(uint256)","ddcbf794":"addScore(uint256,uint256)","ddcd3681":"getRemainingTrialDrops(address,address)","ddcd7ee9":"lastJson()","ddcd8763":"requestBuywithETH()","ddcd887b":"testMiddleTranchNotExact()","ddceafa9":"recovery()","ddcfa217":"newRecurringBillingContract(address)","ddd1002e":"LogStart()","ddd113f4":"numMarriages()","ddd1527b":"transferFromOwner(uint256)","ddd1b67e":"getCurrentMonth()","ddd35de8":"tokensPerBTC()","ddd41ef6":"transferDirector(address)","ddd505f6":"addTransaction(address,uint256,uint256,string,uint256,bytes)","ddd53cc5":"setupICOPrices(uint256,uint256,uint256,uint256)","ddd57872":"setTimeStamp(string)","ddd5e1b2":"claim(uint256,address)","ddd5e68b":"transferEthersToOwner(uint256)","ddd641b0":"tierName(uint256)","ddd6d79a":"remainingWithdraw()","ddd7c879":"claimWei(uint256)","ddd81f82":"registerProxy()","ddd83259":"_normalDistribution(uint256,uint256)","ddd9537d":"getUsdEthExchangeRate()","ddda66db":"setMerchantWallet(address)","dddac167":"VotingFinished(uint256,uint256)","dddaf901":"wcapToken()","dddb983b":"testFailCreateWithParentsForeignNotInUse1()","dddbb753":"getAdsCount()","dddd3594":"ConsentDirective(address,uint256)","dddd3de8":"getvalid()","dddf31f1":"lastClaims(address)","dddf33cc":"offerCatForSale(uint256,uint256)","dddfb2f2":"buyEIT()","dddff84c":"StandardCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","dde0523f":"changeVisitCosts(uint256,uint256,uint256,uint256,uint256,uint256)","dde05a67":"TinaCoin()","dde070e8":"getClaimAmount(address)","dde0d085":"mathTransfer(address[],uint256)","dde107c2":"stampIndextotransactions(uint256)","dde1589c":"icoTokensPrice()","dde26ec9":"createGrant(address,uint256,uint256)","dde27e29":"distributeTokens2(address[],uint256[])","dde2b332":"setTransferFrozen(bool)","dde2fc22":"DLCToken()","dde37357":"MultiOwner(address[],uint256)","dde3ae6d":"changeAssetOwner(address)","dde41aa9":"canonizedRegistry()","dde42067":"paidTokensOf(address)","dde43cba":"REVISION()","dde49979":"unlockFor(address)","dde4a70b":"getSell(uint256)","dde4dc8e":"Show_Patient(uint256,uint256)","dde4f41a":"releaseMultiWithStage(address[],address[])","dde5a65d":"purchase(address,address)","dde68e2e":"refundETHToCustomer(address,uint256)","dde6b340":"calculateLoanerInterest(uint256)","dde6e256":"getCarProduct(uint32)","dde6f449":"GlobfoneCoin()","dde6f484":"setMainAccount(uint256,address)","dde7af32":"warriorGold()","dde82c2d":"coinsRemaining()","dde8535f":"getMemberStatus(address)","dde8c8d6":"getUserVote(uint256,uint160,bool)","dde8dab2":"BEERCOIN()","dde9394c":"returnOwners()","ddea6df3":"isHumanToken(address)","ddeae033":"claimFor(address)","ddeae8ca":"markDone(uint16)","ddeb5094":"pause(bool,bool)","ddeb63b5":"setEscrowAddress(address)","ddec280e":"fetchAssetPrice(address)","ddec60d9":"Parents()","ddecc5d9":"getTradingTime()","dded49cb":"setadmin(address)","dded5dd8":"isAdminForGame(uint256,address)","ddedfc19":"TheLightToken()","ddeed1a4":"projectFailed(uint16)","ddef6421":"adventureContract()","ddef880f":"getDeepInfo(uint256)","ddef8f29":"HOTTO()","ddefdb90":"fillOrKill(address[5],uint256[6],uint256,uint8,bytes32,bytes32)","ddf0432f":"startPresale(address,uint256)","ddf063c8":"collectedEth()","ddf08ebc":"checkCaptain(address,uint32)","ddf09e89":"NelsonChenTestToken()","ddf0c070":"addBalances(address[],uint256[])","ddf187b0":"dogFight()","ddf1be5f":"setIII_R1(uint256)","ddf252ad":"Transfer(address,address,uint256)","ddf25ce9":"renExBalancesContract()","ddf27259":"LogCertificationDbUnRegistered(address)","ddf29872":"teamvalue()","ddf2d8cd":"setDesignatedReportReceivedTime(uint256)","ddf31394":"lockToken(address,uint16)","ddf33cc7":"TEAM_TOKENS1()","ddf34ab0":"getAgreedCompletionDate(bytes16,address,address,uint256,uint256)","ddf41bf4":"migrateHolders(uint256)","ddf4a032":"changeSettings(uint256,uint64,uint8,uint8,uint8,uint8)","ddf4b011":"TIME_UPDATE(bytes32)","ddf5cc29":"ActivationWithdrawal(address[2],uint256[8],uint256)","ddf6e5a0":"GEN_0_LIMIT()","ddf7e1a7":"tokenToTokenSwapInput(uint256,uint256,uint256,uint256,address)","ddf9d613":"getCustomBuyerLimit(address,address)","ddfa3a60":"getCrystalWeights()","ddfa53e4":"hardcapInWei()","ddfafa96":"getRates(address,uint256)","ddfb8b9b":"Start_quiz_qz(string,string)","ddfc50df":"setByte(bytes1,bytes8,bytes32)","ddfd72f8":"setHashByWriter(bytes32,address,bytes32)","de002aa6":"pushWork(uint256)","de0099a3":"heldTokens(address)","de009e7f":"offerToChannel(address,uint256)","de00a094":"controlled()","de0123bf":"AddMultipleAddresseseToWhitelist(address[])","de01ec28":"setStateMigrated()","de024515":"DEMT()","de02ae96":"bytes32ToBytes(bytes32[],bytes32)","de02f1fc":"PER_ACCOUNT_ADDITIONAL_TOKENS()","de0498d3":"Date_Started()","de05905b":"doSetName(bytes32)","de06b7f4":"doTakerPayment()","de06ef49":"whaleStartTime()","de07a886":"DEFROST_MONTH_IN_MINUTES()","de080401":"SethTokenPurchase(address,address,uint256,uint256)","de089aee":"userMaximumPurchaseAmountNg(address)","de08a6d8":"metaTransfer(address,uint256,bytes,uint256,uint256)","de08c364":"removeAdminister(address)","de08f188":"storageStep()","de090b25":"LockInExpiry()","de0a1c5d":"changeVuePayETHDestinationAddress(address)","de0a7cc6":"purchasedTicket(address)","de0b18f2":"getAssetAttachment(uint256)","de0b5af2":"BONUS_COEFF()","de0bffc2":"GlobaLiquids()","de0cf58b":"callerAllocationStartBlock()","de0d0802":"getWeightAndUpdate(address)","de0d50e4":"incGen0PresaleCount()","de0d7083":"Alter_MediatedTransaction(uint256,bool)","de0e9a3e":"unwrap(uint256)","de0f2b49":"setCertifierStatus(address,bool)","de0f725d":"removeContract(address,address)","de0fe922":"addHashType(string)","de0ff7c5":"getEther()","de1079b3":"vestFromTime()","de10f04b":"eraseNode(bytes32[])","de117fb1":"buyDirector(uint256)","de11823a":"GoldAllocation(uint256,uint256)","de11892b":"isAuthorized(address,bytes32)","de11c94a":"factoryContract()","de121554":"addLike(uint256,bool)","de12b52c":"getTopBlock()","de12b839":"GetPie()","de13bec6":"getApiByName(string)","de1446e8":"view54()","de14bbf7":"randomGen(uint256,uint256)","de14c818":"approvePayment(uint256)","de14d323":"confirmAlice(uint256)","de14e54d":"setActivity(address,bool)","de150d5d":"throwSlammer(bytes32,bytes32,bytes32)","de154352":"getBlocksTillMattew()","de154761":"upgradeManager()","de1565fe":"MainnetProtocol()","de1682a5":"PTLC()","de170570":"getTiers()","de176643":"_advisorsSupply()","de179108":"allSaleCompleted()","de17dfa9":"setCryptaurToken(address)","de1881a8":"processingFee()","de18af92":"getEmployerInvoices(address,uint8)","de18bec6":"BeneficiaryChange(address)","de18dd18":"refuseSale(address[])","de192a20":"ARChain(uint256,string,string)","de1955df":"reclaimByReceiver(address,bytes32)","de1ac2fd":"checkOperator(address)","de1b0486":"withdrawFrom(address)","de1b27f5":"SALE_ALLOCATION()","de1bee1b":"dogexSupply()","de1c237f":"getarg_2_input()","de1c78fb":"batch_send(address[],uint256)","de1c7f70":"getEns(address)","de1c977a":"testPreDistribute()","de1e46e6":"placeBet(uint256,uint256,uint8,int256)","de1e8de8":"MINIMAL_INVESTMENT()","de1eb2d0":"withdrawQuantity()","de1f892a":"adjust_ERC223Transfer(bool)","de1ff163":"isCurrentOrPastAccountReader(address,address)","de2037a7":"createSensor(uint256,uint256,uint256)","de20555f":"getGoldStatusCustodianverify(address)","de20bc92":"Stake()","de2111e2":"got()","de217625":"setAssets(address[])","de2184bf":"voting(address,uint256,string)","de21cd78":"allItems(uint256,uint256)","de21dc6f":"fundit(address)","de2237d3":"getVotersLength()","de223f63":"transferPauseOperator(address)","de242ff4":"allowance()","de24d3ba":"WEBCOIN()","de255778":"relocationActive()","de26bbb2":"percentage(uint256,uint8)","de271ee0":"depositAngelInvestmentEth()","de272835":"advisorIssue(address,uint256)","de2831f2":"getRemainingBonus()","de283b21":"current_transferred()","de28431c":"priceLastUpdate()","de287359":"acl()","de28ba54":"MorpheusTokenFAKE()","de28fc1d":"icoSender()","de2904de":"CapUpdated(uint256,bytes32,uint256)","de292789":"getResult()","de2994c4":"unfreezingTimestamp()","de2a4a43":"RLLToken(uint256,string,string,address)","de2a9778":"createProxy(address,address,uint256,uint256,uint256,uint256,uint256,address,uint256,string,uint8,string,bool)","de2b2cd2":"changeDonor(address)","de2b4473":"setSaleDepositsAllowed(bool)","de2c1d09":"SendERC20ToDex(address)","de2c1e85":"_packWarriorCommonData(uint256,uint256)","de2e6136":"sendGift(address)","de2ed893":"totalDonations()","de2f827e":"saveChickenOf(address)","de301e8c":"getRTEBonusTokenVaultBalance()","de306341":"createMineForToken(uint256,uint256,uint256,uint256,uint256)","de31482a":"tokenHasDistributed()","de318242":"Mani()","de326c1e":"movePatentData(uint16[],address[],uint256[],bool[],uint256[],uint256[],uint256[])","de329396":"ownerSetMaxProfit(uint256)","de33d8d8":"Print(string,address)","de341661":"unpause_2()","de346a40":"whiteListERC20(address)","de34bacd":"cardPrice()","de35a696":"Child(string,address)","de35be81":"submitSellOrder(bytes32,uint256,uint256)","de377015":"maxIcoTokensSold()","de37ca12":"MyFirstSmartContract()","de37e977":"thisTokenBalance()","de38460b":"nextSaleAgent()","de3849be":"owner_AirdropUpdateToken(address[],uint256)","de385438":"calculateEmission(uint256,uint256)","de38a5f4":"verifyKYC(bytes32,bytes32,bytes32,bytes32,bytes32)","de38c771":"setFundingAmount(uint256)","de38eb3a":"MAX_TIMEOUT()","de3989f5":"CalledA()","de39acea":"get32(bytes,uint256)","de3a8511":"teamKeepingSupply()","de3ab731":"evaluateAfterQuery(bool,uint256)","de3b5061":"updateBuyType(address,address,int256)","de3b653a":"IsReleaseToken()","de3bcb97":"takeAll()","de3bec59":"baseowner()","de3d0290":"gwtoken(uint256,string,uint8,string)","de3dac84":"freezeAccount(uint256)","de3ea04a":"SAGAToken()","de3f18e2":"winningTeam()","de3f26eb":"oracleRegistryContract()","de3fbdee":"addRate(uint256,uint256)","de400629":"createListingWithSender(address,bytes32,uint256,address)","de4125b0":"addWineryOperationEndorsement(string,uint256,bool,string,string)","de4138de":"getCurrentStateId()","de41e1a1":"assignOwner(address[],uint256,address)","de42dcc9":"LuckCashToken(uint256)","de42f045":"auditTimeoutInBlocks()","de43844b":"fixedExp(int256)","de44a17e":"setNewModifier(address)","de44bf01":"getCreateUniverseParentUniverseValue()","de459c9b":"RATE_SALESTAGE6()","de469071":"hashBetSum()","de47864c":"testSafeAdd(uint256,uint256)","de47e0bf":"withdrawBaseETH()","de48ff52":"updateState(int128,uint128,uint8,bytes32,bytes32,bool)","de494190":"getCommentIdByAd(uint256,uint256)","de49bd54":"BurnTokensAndSetAmountForNewBlockchain(address)","de4b3262":"setBasePrice(uint256)","de4b3a73":"defaultText()","de4b4073":"devSend()","de4b45fa":"finalizeReclaim()","de4c0574":"migrateAllowancesFromLegacyRep(address[],address[])","de4cd094":"convertToDecimal(uint256)","de4d51a5":"setSaleType_Airdrop(uint8,uint8,uint32,uint8,int256,uint256,int256)","de4f4d2b":"totalEthHandled()","de4f9383":"transferEtherFrom(address,address,uint256)","de5007ff":"sweepMsg()","de50f2fe":"KycClaveChain(address)","de5101af":"timestampToDate(uint256)","de51f57e":"setValueStep3(uint256)","de52ccbe":"NGX()","de530bbb":"EMISSION_FOR_SALESTAGE4()","de534744":"tokenDistribution(address,uint256)","de563b89":"removeRatio()","de56a245":"editionOptionalCommission(uint256)","de571e48":"getCollectedAmount()","de575a02":"dismissRoom(uint256)","de576c8a":"CREATED_STAR5()","de5785d5":"feesAvailableForWithdraw()","de578a90":"ApodTokenContract()","de57e8b4":"releaseEscrow(bytes16,address,address,uint256)","de583ed3":"_improveCard(uint256,uint256,uint256)","de5866f9":"s19(bytes1)","de589fa9":"TokenLongExercised(address[2],uint256[8],uint8,bytes32[2],uint256,uint256)","de58d156":"createAsset(string,string,string)","de5990ca":"INTREPID_VOUCHER_LIMIT()","de59a5cb":"SaleClockAuction(address,address,address,uint256,uint256)","de5ac86d":"createWager(bytes32)","de5b71f7":"distributeReward(address,uint256,uint256)","de5b9987":"getUnitDefenseMultiplier(address,address,uint256)","de5b9e4f":"BitMEDSmartToken()","de5bb5a2":"nEdits()","de5c995e":"Y2_lockedTokenReleaseTime()","de5cb7ed":"DutchAuctionPoD()","de5cf247":"giveTokens(address,address,uint256,string)","de5d953a":"logSingleIndex(bytes,bytes,uint256)","de5da0cf":"nextGiftId()","de5dc6c8":"tokenCapped()","de5dead6":"reduceInventories(uint256,uint256,uint256,uint16)","de5e21df":"timerStart()","de5e7ac4":"getOutcome(address)","de5eaa83":"donate(uint8,bytes32,bytes32)","de5eeb6e":"preICOAddress()","de5f3ec6":"buy10Price()","de5f5517":"lad(bytes32)","de5f72fd":"faucet()","de5f9866":"getTokensLeft()","de605ecc":"changeSettings(uint256,uint256,uint32)","de60a67d":"maxCapIco()","de620676":"_sellprice()","de622de4":"tgeStarted()","de62319c":"IQT_CONTRACT_ADDRESS()","de625d1f":"totalReceivedWei()","de628e3b":"tokensCalculator(uint256,uint256,uint256,uint256)","de629235":"getCertificationDocumentAtIndex(address,uint256)","de637901":"poptxs(address,uint256)","de63dc35":"setPartnerFromPreICOAffiliate(address[],bytes32[],uint256[])","de640e19":"Investment(uint256)","de642b5a":"cbdc(uint256,string,string)","de644ebd":"firstMintRound0For(address[],uint256[],uint8[])","de648b87":"setSKLContractAddress(address)","de656b71":"BecomeSnailmaster()","de658979":"_updateCompany(bytes32,bytes32)","de6595b2":"WhitelistedUpdated(uint256,bool)","de65da20":"purchaseGame()","de661217":"left75(uint256)","de667e70":"setBuyer(uint256,address)","de66b5f7":"unidentifiedSaleLimit()","de66ed0d":"getTargetReporterGasCosts()","de6746a5":"founders(address)","de6764ba":"Swanroll()","de67fd05":"deleteLayer(uint256)","de683a7d":"change(address,uint256,address)","de68c43f":"noFee(address,address,uint256)","de6a1b19":"landmarkPoolTotal()","de6a9d83":"CheckResultCalled(bytes32,address)","de6ab39c":"INITIALSUPPLY()","de6b8a2e":"getOrderLength(address)","de6b978d":"POA20(string,string,uint8)","de6baccb":"transferWithLock(address,uint256,uint256)","de6bd0e8":"redistributeEthForAddresses(uint256,address[])","de6c4f4b":"reset(address,address,address,address,address,address,address)","de6ca3f0":"_setCommit(uint256,address,bytes32)","de6cdd2e":"getExchangeInfo(bytes32)","de6eb4be":"NBAONLINE()","de6ed7dc":"GoldIssueBurnFee(string)","de6ef007":"amountTokensPerEth()","de6f24bb":"sendMessage(address,string)","de7086f6":"TemplateToken()","de70b36c":"RevokeViewingPrivelege(address)","de718e3f":"initialWeiRais(uint256)","de71c467":"presentObject(bytes,bytes32)","de71d56b":"getStandartComponent(uint256,uint256)","de72a01d":"Agt()","de72b83d":"totalBountyAmount()","de72cab0":"finishBonusPeriod()","de733397":"allowClaiming()","de7337a1":"changeFloor(uint256)","de7383e0":"handleTokensReceived()","de742c2d":"getFreeAlien()","de74880c":"platformUnfreeze()","de74e57b":"listings(uint256)","de750f6f":"getNine(uint256)","de758458":"IPFSProxy(address[],uint256,uint256)","de75c36e":"addressMasterNodes()","de763a40":"getEtherFeeForPriceInCandy()","de77229f":"MinterOwnershipTransferred(address,address)","de77743d":"needsbeneficiary(uint256)","de7874f3":"plyr_(uint256)","de78be15":"onSoftCapReached(uint256)","de78e78a":"tokenLaunched()","de78ed85":"actual_balance(address)","de795edd":"prova()","de79fb92":"UKTTokenVoting(uint256,bytes32[],address[],uint256[])","de7a5956":"getWinnerTeam()","de7ae335":"WithdrawDividendsAndCouponsTo(address)","de7b1a77":"finalizeTokenSaleManager()","de7b24b8":"ICOFailed(uint256,uint256,string)","de7b89bd":"GetUserExtraData1(address)","de7bea74":"getThreshold(uint8)","de7c2ed2":"TEAM_VESTING_DURATION()","de7c99c3":"releasePrivateBonusTokens(address[],uint256[])","de7cb327":"Proof()","de7d4fc4":"getGameNumber()","de7dd576":"etherPriceInPoundPences()","de7fe3e7":"getItemInfo(uint256)","de803198":"setFunderSmartToken(address)","de80344d":"startStage(uint256,uint256,uint256,uint256)","de80b0a5":"promo()","de812733":"createBaby(uint256,uint256,uint256,uint256)","de81333e":"claimHeldBalance()","de815e61":"FourArt(address,address,address,address,address,address,address,address,address,address,address)","de81aaaa":"hardCapUSD()","de821a35":"_updateGenerationSeasonFlag(uint256,uint8)","de8248fb":"FEE_PERMILLE()","de824f93":"TimeLeft()","de82b54d":"cancelSellToConsumer(address)","de82efb4":"gimme()","de831ee7":"changeMinTransfer(uint256)","de840f11":"NassauToken()","de850c71":"dequeueAlternately()","de852afe":"revokeAccessDeploy(address)","de854065":"Portfolio(address)","de85a4a9":"tokenIssuedMkt()","de866db1":"buyContract()","de86ba28":"_addMintedTotallyByBridge(uint256,address)","de874962":"EOS_Silver()","de8801e5":"presaleStart()","de887bba":"getSecretBet(address)","de889d50":"refundWallet(address)","de88a342":"payDividends()","de894d3a":"_transferDividends(address,address,uint256)","de8a1c2e":"OMIToken()","de8a6fa2":"baseEthCapPerAddress()","de8b1d5c":"createCustomPresale(uint256,uint256,uint256,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","de8b888e":"freezeTokenTransfers()","de8ba6d1":"getAndDel(bytes32)","de8bb64f":"TEFC()","de8bf3b6":"noRoundMiniGame()","de8c85ea":"operationToken()","de8f50a1":"verify(bytes,bytes,bytes)","de8f55af":"dailyDistribution()","de8fa431":"getSize()","de901104":"setLLV_edit_15(string)","de9122f7":"wipeAttributes(string,bytes32[])","de917978":"SafecontractsTREXFund()","de91af7b":"totalPoolCap()","de91bb10":"CardManger()","de92af4b":"LongBought(address[2],uint256[3],uint256)","de931662":"callToken()","de934416":"balancePrivate(address)","de934d86":"BOT_ELEMENT_1()","de9364f4":"testFailBurnGuyWithoutTrust()","de940c29":"renounceOwnershipForever(uint8)","de942e62":"getLLV_edit_6()","de944520":"getBurnAmountApproval(address,address)","de9476dd":"addNewAirdrop(string,uint256,uint256,address,uint256)","de94b800":"backToken(address,uint256)","de957cf4":"setChunkSize(uint256)","de9652b1":"getcoinSortinglength()","de96587e":"removeAmbassador(address)","de96e823":"StarbaseCrowdsale(address)","de981f1b":"getContract(uint8)","de98bc4f":"LogMintingStopped()","de990bda":"etherMaximum()","de995b90":"sendOwnershipFrom(address,address,uint256)","de998dd0":"_affiliateProgramIsActive()","de9a1bdb":"MyToken(string,string,uint8,uint256)","de9b33f9":"getWithdrawNonce(bytes32)","de9b9364":"max_investment_eth()","de9d0e85":"_setPendingAnchor(address,uint256)","de9daf91":"setEmissionLimit(uint256)","de9db5d3":"projectShare()","de9eade3":"totalInitialAddresses()","de9ee13e":"calculateMaximumPayment(address,address)","de9f28e4":"getJobTotalSkills(uint256)","de9f4248":"identities()","de9f57f5":"LogBroker(address)","dea011f5":"updateService(address,address)","dea01b3e":"removeOneSecret(bytes32)","dea06188":"NumberOfBlockAlreadyMined()","dea09ef3":"takeFee(address,address,address,uint256,uint256)","dea0a837":"SetParticipantURL(address,address,string)","dea0cbd7":"viewMaxGasPrice()","dea1bd69":"setValidity(uint256)","dea216af":"nestedSecond(uint256)","dea2356c":"setInvestorGain(uint256)","dea37fb0":"Force()","dea3ce27":"setEligibleForReimburse(bool)","dea4267b":"addCourse(string,string,string,string,string)","dea5408f":"paymentSizeB()","dea5de80":"phase_4_Time()","dea6aec7":"getTargetSupply()","dea7b768":"submitBallotNoPk(bytes32)","dea89056":"holdMax()","dea8d6b6":"testCannotSetPresaleTokensAfterSaleStarts()","dea90acf":"getEmergencyTransferSignersCount(address)","dea95ff8":"setRoundNum(uint256)","dea97078":"getPendingTransactionsSellerAddresses()","dea9b464":"depositCollateral(bytes32,uint256)","dea9c72b":"getLatestPreReleaseTree(bytes32,uint32,uint32,uint32)","dea9ecd6":"DeanCoin(uint256,string,uint8,string)","deaa0d0a":"withdrawal1()","deaa59df":"setWallet(address)","deab5a78":"TEGTY()","deac4659":"inArray(address)","deaca58e":"settlvlement(address,uint256,address,string,string)","dead98f6":"part_to_vehicle(uint256,string,uint256)","dead9f93":"setParams(uint256,uint256,address,address)","deadc3dc":"currentStepIndexByDate()","deae5d4d":"networkPlaceholder()","deaf5a5e":"transferDocument(bytes32,address)","deb06c3a":"gameActive(uint256)","deb077b9":"nextSaleId()","deb081df":"getIslands()","deb0e09b":"getVotingDuration()","deb209f6":"isProviderValid(uint256)","deb2432b":"zecId()","deb2e0b9":"MedNet()","deb36e32":"startVesting()","deb41f8d":"setTuple(uint256,uint256,bytes32)","deb43874":"Heritable(uint256)","deb52738":"finaliseFirstPhase()","deb53ab4":"BeneficiaryStake(uint256)","deb5d6c2":"inviterReg()","deb60627":"MhpCoin()","deb6930c":"PriceTicker()","deb77083":"stage2Bounty()","deb775a7":"tokenEmission(uint256,uint256)","deb80111":"transfer_asset(address,uint256)","deb80d66":"ProvidencePresale()","deb83bcc":"crowdsaleEndLockTime()","deb931a2":"getOwner(bytes32)","deb93b5b":"balanceOfOn()","deb979ac":"mktValueupdated(uint256)","deba5e95":"addCandidate(address,bytes32,string)","debad25e":"TeslaTest()","debad27f":"getProducts(uint256)","debaeb0e":"bonusLevel1PercentModifier()","debbc6eb":"btcRelay()","debc74f6":"buyRateZeroQuantity(uint256)","debc94ff":"Buckcoin()","debcbdcf":"preSaleStartdate()","debd122e":"setUp(uint256)","debe1c69":"setAccountingParams(uint256,uint256,uint256)","debe9768":"mintTokensLockedMultiple(uint256,int256,address[],uint256[],uint256[])","debf5b9f":"phase_4_rate()","dec0257d":"deleteContract(bytes32)","dec04b9b":"testNow()","dec10357":"currentCandyTotalSupply()","dec18b46":"second_withdrawal(uint256)","dec22b07":"forceExecuteRandomQuery()","dec24118":"lastCallBlock()","dec26d55":"LifeSet_003()","dec32ae8":"byTokens()","dec4b436":"subAttack(uint256,uint256)","dec57e94":"QTUM()","dec5cf53":"Exile()","dec6bc91":"EthernautsPreSale()","dec6c2d8":"updatedDistributee(address,uint256)","dec74ae9":"eurId()","dec7542f":"changePermission(address,address,bytes32,bool)","dec7ee57":"convert2Platinum(uint256)","dec7fa11":"minimumTokenAmount()","dec8f52e":"getVested(address)","dec96e7b":"setTitulaire_Compte_3(uint256)","dec9ba44":"createBet()","deca15db":"calcQueryCost(uint256,uint256)","deca6e76":"adminsInitialized()","decadbcc":"mainstreetCrowdfund()","decb3a90":"winAmount()","decb4803":"Tipcoin()","decbd169":"createPet(uint8,string)","decd8785":"addPartnerAddress(address)","decd8a25":"MINI_GAME_PRIZE_CRYSTAL()","decde7c0":"GetCert(uint32)","decdffbb":"_emitJobRatingGiven(address,address,uint256,uint8)","dece296f":"RET_DIV()","dece2e67":"releaseFundsSeller()","dece3355":"MinePoS(address,uint256)","decebbce":"getFunds(address)","decf1e64":"minimumPledgeAmount()","decfe0d4":"destroyEnabled()","ded04fe9":"testFailCreateNewRevisionNotOwner()","ded05da5":"changeIcoAddress(address)","ded1588c":"OwnerWithdrawTokens(address,address,uint256)","ded1c11b":"startFinalStage1()","ded1d0b8":"createMiniTicket(address,uint256)","ded1e438":"checkRatio(uint256,uint256)","ded1e4de":"DisputeResolver(address[],address)","ded1e7e3":"innerGreet()","ded1f580":"Unregister(address,bool)","ded24016":"getDynamicArrayElement(uint256)","ded2d0f4":"awardToken(address,uint256)","ded30375":"setectoken(address)","ded317a8":"minCapUSD()","ded37745":"maybeAnotherTime(uint256)","ded4980f":"withdrawInvestmentsBeneficiary(address,address)","ded54a4c":"stitch(uint256,uint256,bool)","ded5bc6c":"getBdpImageStorage(address[16])","ded5bd14":"setApp(string,uint256,address)","ded78d3d":"trade(address,uint256,address,uint256,uint256,address,uint8,bytes32,bytes32,uint256)","ded8454a":"addressToBytes(address)","ded8f76d":"_sort(uint256,uint256)","ded94688":"showOwner()","ded9b075":"getAllDepositesCount()","deda0b5a":"mockSetResult(string)","deda20de":"doPurchaseFor(address)","deda2f9d":"triggerStealManually(uint32)","dedb7e25":"_ifEvenThenOddTooFlags(uint256)","dedc440f":"getEscuela(uint256,uint256)","deddab12":"withdrawalToken(uint256)","dede12a4":"startWeekOne()","dedeb3ca":"referralRateInvitee()","dedf141e":"setDates(uint256,uint256)","dedfb567":"multiFreezeAccount(address[],uint256)","dee023e2":"transferAllArgsNoAllowance(address,address,uint256)","dee1bfbe":"totalLendingFiatAmount()","dee1cfd8":"icoStartTimestampStage()","dee1f2af":"addToken(address,uint256,uint256)","dee2596b":"changeBonusTokenAddress(address)","dee2b058":"setCapacity(uint256,uint256)","dee3a226":"finalizeSto()","dee3efb2":"getWorkerPoolByIndex(uint256)","dee4b246":"buyTokens(uint64,uint256,uint8,bytes32,bytes32)","dee5216e":"applyRuntimeUpdate(address,address,uint64,uint64)","dee54b68":"WalletAddressUpdated(address,address)","dee555bf":"discountRateIco()","dee5a9e7":"PRICE_STAGE_THREE_BONUS()","dee6e5a4":"toggleKYC(address,bool)","dee73dbb":"AcceptedOwnership(address)","dee751ce":"createHoldToken(address,uint256)","dee7e59b":"LogWithdrawTokens(address,uint256)","dee81a13":"Local()","dee846c5":"updateJoinedCrowdsales(address)","dee8575c":"getNumBits(uint256)","dee86dfb":"marketIdeas()","dee8bd51":"ReleaseICO()","dee9f53f":"idOf(uint256)","deeb7124":"MDAToken()","deebeac9":"transferToken(address)","deec4c20":"getCardsInfo(uint256)","deecb187":"KyberNetworkProxy(address)","deed18e2":"isReadyToFinalize()","deed2be0":"getDailyPlayers()","deed4b80":"isFirstLockTimeEnd()","deee9adb":"setPOOL_edit_10(string)","deef6c99":"ZigguratToken(uint256,string,uint8,string)","def04570":"TheFrozenDeadShitCoin()","def0defa":"getOwnerHistoryCountOf(bytes32)","def18101":"currentBid()","def1a2da":"vc3Wallet4Pct()","def2489b":"convert(address)","def2be48":"getBAAAU(bytes32,address,address,address)","def4ba32":"utrTestToken()","def51dc2":"CIC()","def59575":"manualyAddReferral(address,uint256)","def59ea5":"addMember(address,address,uint256)","def5bbd0":"strConcats(string,string,string,string,string)","def7eb44":"maxChangeFee()","def843ef":"createOfAthleteCard(string,address,uint256,uint256,uint256)","def86cbb":"modifyWhitelist(address[],address[])","def871ef":"AirDrop(uint256)","def9176c":"team1Balance()","def92c69":"MAX_BALANCE()","def98a72":"recipientExtraMIT()","def9c7e2":"_escrowStakeOwnerPaymentEarning(address,bytes32,uint256,uint256,address,bool)","defa92ee":"depositDividends()","defaa5f2":"_transferEthereum(uint256,uint256,uint256)","defafa37":"setRefundTimelock(uint256)","defb9584":"PROMO_CREATION_LIMIT()","defbc073":"weiUnlocked()","defc876e":"removeAddressFromCaller(address)","defc8ae9":"BuyOffer(address,address,uint256,uint256,uint256,uint256)","defce6d8":"FlagAddress(address)","defe2883":"totalSupplyByAsset(bytes32)","defe2c47":"_checkRecommend(bool,uint256)","defefe96":"payCompoundTerm(uint256,uint8,uint8)","deff30c6":"sellTokens(address)","deff3a37":"purchaseReject(address)","deff41c1":"m_owner()","deff5757":"setPartnersRelease(uint256)","deff71b8":"setAllFlagPairs(bool[2][])","deff7f2f":"CrowdFundings()","deffbaee":"addOwnershipChest(address,uint256)","df000ff7":"acceptParityOwnership()","df013fab":"setDelegadoDeEscuela(bytes32,bytes32,uint256,uint256)","df018dbd":"process(address,address,address,string,string)","df022cbc":"hello1()","df034586":"lockCount(address)","df034cd0":"updater()","df034db8":"aCASATest()","df037443":"timeoutX()","df0441cc":"_checkUnlock(address)","df054797":"securityAudit()","df0584af":"ClimateCoinAddress()","df065d78":"TEST_PLAYER()","df06c1d8":"plotsOwned(address,uint256)","df06f906":"numBets()","df0795aa":"setKycProvider(address)","df08ce62":"give(address[],uint256[])","df09176b":"ActualizePrice(uint256,uint256,uint256,uint256)","df0969dc":"clearPlayerPrize(address)","df09921f":"institutionAllocation()","df0a2bda":"refundIgnoredBids(uint256)","df0a8589":"dealAmount()","df0ad3de":"upgradeabilityAdmin()","df0b1344":"SchmeckleTokenSale()","df0b52c8":"keyAddress()","df0bcf4d":"setAvatar(uint256)","df0c428c":"releaseAdvisorsTeamTokens()","df0c7a55":"nextPrice(uint16)","df0cd37b":"Etheremojis()","df0d05d9":"EmporioExchage()","df0d1078":"volumeType1()","df0da20e":"BONUS_WINDOW_1_END_TIME()","df0efbf5":"rateForSale(uint256)","df0f093b":"purchasePeriod()","df0f26f9":"getBalanceAddr(uint256)","df0f3227":"DurationAltered(uint256)","df0f3c19":"getGameCountdown()","df0f3e1c":"isFalse(bool,string)","df109ee1":"AuctionManager()","df10dd6e":"checkSubAvailability(bytes32)","df117c47":"updateSuperPrivilegeParams(uint256,uint256)","df11d258":"witness(bytes32,bytes32,bytes32,bytes32,uint8,bytes32,bytes32)","df12b94e":"investBalance()","df133cf9":"minesPrice(uint256)","df1340a0":"QTR_Token()","df13569d":"FACTOR_6()","df13994e":"callback(bytes32)","df143fb7":"HackerGold(address)","df148cdb":"setPonziAddress(address)","df155488":"startLockTime()","df15c37e":"getWinners()","df15f87e":"FiatRaisedUpdated(address,uint256)","df1614cf":"setLendFee(uint256)","df1673e9":"CHINESE_EXCHANGE_4()","df175e9b":"newCampaign(address,uint256,uint256)","df17c4b1":"delegateTransferAndCall(uint256,uint256,address,uint256,bytes,uint8,bytes32,bytes32)","df181831":"staff_1()","df1836ca":"referrerAndOwnerPercent()","df18e215":"updateTokenStore(address)","df190048":"getAdPrice(uint256)","df19b71c":"digitToNumber(uint8)","df19df5d":"ownerOperationsLength(address)","df1a5aab":"reservedTokensClaimStage()","df1abf83":"revertTokensByKYC(address)","df1b817e":"setupCutie(uint40,uint16)","df1c455c":"unallocated()","df1cd2b5":"volumeBonusesTokens(address)","df1cf293":"addAuction(uint32,uint256,uint256,uint256)","df1d4559":"setFOUNDATION_POOL_ADDR(address)","df1dbbc9":"ShareToken()","df1dd826":"trade(uint256)","df1e36c6":"unlockDeposit(string,address)","df1ead82":"disinvest()","df1ec3ea":"BesideERC20(uint256,string,string)","df1f4a6e":"getTimestring(uint256)","df1fc781":"KickicoCrowdsale(address,address,address,address,address,address,address,address,address)","df201a46":"simple()","df203ff7":"depositGasCost()","df20b119":"balanceEthCrowd(address)","df20c021":"addNewChannelAndRankofuser(address,string,int256)","df20d738":"BokkyPooBahsEtherRefundablePrize()","df221223":"setWeiExchangeRate(uint256)","df22bf83":"canUseTokens(address,uint256)","df23128f":"adjustTranche(uint256)","df234815":"tokensAvailableAtTierInternal(uint8,uint256,uint256)","df2436b3":"isExistByBytes(bytes32)","df247c5d":"CareerXonToken(uint256,uint256,uint256,uint256)","df25322d":"getFundReceiver()","df25ecf8":"DSTContract(string,string)","df25ee23":"getIndexId(address,bytes)","df25f3f0":"minPerTx()","df26ca08":"emitError(uint256)","df28aef7":"withdrawLiquidatePool(uint256)","df28d6fa":"Dex2(address)","df294588":"get_Gains(address,address)","df294cad":"allocateNominalToken(address,uint256)","df295080":"changeAbstractStorage(address)","df29b982":"emergencyWithdrawERC20(address,uint256)","df29dfc4":"get_start_time()","df2a201b":"setSystemOraGasLimit(uint256)","df2a2753":"LDGToken()","df2a29da":"getDenominationToken()","df2a6e4f":"kscBatchSellByOtherCoin(address,address[],uint256[],uint256,uint256[],string)","df2b1cf8":"toBytes(uint256,uint256)","df2bf12b":"totalBatchOf(bytes32)","df2c05a9":"UbermenschPrefundToken(address)","df2c7fc1":"AuctionFinished(address,uint256,uint256,uint256,uint64,uint256,address)","df2cdbed":"_setBidState(bytes32,uint8)","df2d33d5":"isBreakingCap(uint256)","df2d44af":"EthLongExercised(address[2],uint256[7],uint8,bytes32[2],uint256,uint256)","df2df29a":"CEO_Signature()","df2dfb20":"canIBuy()","df2e5c0f":"changePricePerUnicorn(uint256)","df2f0a4a":"getDecisionBlockNumber(uint256,uint256)","df2fbae6":"totalAvaliableSupply()","df300b46":"getThing(bytes32[])","df305680":"clearProposalLocked(address)","df30e592":"isValidContributorId(uint256)","df31566e":"setUInt(string,uint256)","df3164c6":"Release()","df31b589":"bonusForPreICO()","df320b29":"refundBet(bytes32)","df32754b":"owned()","df32dc5c":"withdrawEarning(uint256)","df331545":"reservedOperationalExpenses()","df334093":"acceptingDeposits()","df36318a":"exchangeStart()","df3864d5":"ticketsSold(uint256)","df390d63":"encodeData(uint128,uint256,uint24,uint40)","df3959f5":"setInitializeUniverseValue()","df3a4fa1":"maxSubdivisions()","df3a635a":"removeDeed(address,uint256)","df3a6b10":"testMemberAddedEvent()","df3aa1fc":"FTXToken(address)","df3b75f0":"test_standardCampaignDeploymentAndUse()","df3be668":"productLimits(bytes32)","df3be9e8":"ERCFW()","df3c211b":"calculateVestedTokens(uint256,uint256,uint256,uint256,uint256)","df3c3a30":"mintLocked()","df3c5a42":"supplyICOContract(address)","df3c8620":"num_challenges()","df3cc390":"setUsdRate(uint256)","df3e0a1d":"completeEscrow(uint256)","df3f5974":"readPublicRecord(bytes32,bytes32)","df3fb59e":"DSPRegistryReplaced(address,address)","df40503c":"getRemainCoins()","df40a089":"setDrawAddress(address,address)","df41765e":"circulatingTokensFromSale()","df418fbf":"returnBytes1(bytes)","df41d979":"ico_distribution(address,uint256)","df426401":"founderTokenUnlockPhase2()","df428e3b":"createChildUniverse(uint256[],bool)","df42dfa9":"initialARXSupplyInWei()","df42e80e":"Asset()","df43b699":"setInvoiceCancelled(address,address,uint256)","df43b830":"absolutCBD()","df444df1":"createEscrowBySeller(address,uint256)","df462098":"setNextCommonTTMTokenId7(uint64)","df463ed3":"buyService(uint64,uint64)","df47a924":"DiaToken()","df482ad5":"privateFundSupply()","df483622":"addLotteryParticipant(address,uint256)","df487962":"FibokenCreated(uint8,address,uint256)","df48a2b0":"setReinvestmentAddress(address)","df49804a":"mtv()","df49dfe3":"updateTransferMinimumFee(uint8)","df4a2ecc":"hasNext()","df4aaf04":"COIN_SUPPLY_ICO_TIER_2()","df4adb94":"getOutcomeByIndex(uint256)","df4b2970":"getRabbitMother(uint32)","df4b3351":"collectEtherBack(address)","df4bcf58":"isMigrationAgent()","df4bd18d":"setPriceAndRate(uint256,uint256)","df4bef32":"searchInList(address)","df4c2164":"mintableAddress()","df4c98b5":"createRentAuction(uint256,uint256,uint256,uint256,uint256)","df4cbb96":"commitProposal(bytes32,string)","df4d17dc":"initToken(address)","df4dfa7f":"PRE_ICO_TOKENS_AMOUNT()","df4e79fa":"VESTED_TOKENS()","df4ebd9d":"buyWanCoin(address)","df4ec249":"step3()","df4f0088":"guardVillain(uint256,uint256)","df4f011c":"licenseIds(uint256)","df4f5a72":"refunder()","df4fc373":"SetIPR(string,string,address,string,string,uint256,address)","df4fcf8e":"newFeePercentageIsSet(uint256)","df5055e6":"adminVer()","df506768":"payTeam(address)","df506801":"preSaleThirdCap()","df50a8c1":"updateFundraiser(address,bool)","df50afa4":"setAllowTransfers(bool)","df51d46b":"setUnlockEarlier(uint256)","df520efc":"pricePerTokenInWei()","df52f321":"CinociCoin(uint256,string,string)","df53623f":"_unlockContract()","df5483ad":"setImageWidth(uint256,uint16)","df54c659":"TransferredFoundersTokens(address,uint256)","df55b41a":"owner(string)","df55f529":"UNLOCK_TEN_PERCENT_PERIOD()","df565ca2":"rateRatioCVSThreshold()","df571e33":"postSoftRate()","df57904a":"GoodfieldNewRetail(uint256,string,string)","df57a6ec":"_generateRandomDna(string)","df57b742":"getReverse(bytes32)","df58471d":"increaseFundingGoal(uint256)","df58d236":"WipedAccount(address,uint256)","df590d89":"KnowHowChain()","df591e82":"goForward()","df59cbeb":"OwnedUpgradeabilityProxy()","df5a1417":"PLAYERWIN()","df5b588c":"PublishWinnersScoreThres(uint16)","df5cc291":"get4(bytes,uint256)","df5cf723":"delegation()","df5d3e89":"subBuy(bytes32,bytes32,address)","df5d3ec7":"setSaleEnd(uint32)","df5dd1a5":"addOracle(address)","df5dd98f":"refFeeVal()","df5e3569":"hasBet(uint256)","df5f0603":"retrieveEth(uint256)","df5f53f1":"checkWithdrawal(address,address,address,uint8,bytes32,bytes32,uint8,bytes32,bytes32)","df603769":"reconcile(uint256,address[],int256[],uint8[],bytes32[],bytes32[])","df61f51b":"TokensIssued(address,uint256,uint256,uint256)","df6378e9":"getAuctionAddress(uint256)","df63d908":"testYBool()","df63e659":"deleteAllMessages()","df642cad":"setCost(uint8,uint256,uint32)","df65d1ef":"getLuckBoyAddrList()","df66fc14":"sendTokenTeamAdvisor(address)","df67184a":"getRequiredBalance(uint256)","df673d35":"SISA_token()","df67ae3d":"GetStuffList(address)","df67d82d":"minETH()","df68a516":"viable_print(int256,uint256,uint256,uint64)","df68c1a2":"canTransfer()","df68fd99":"popElementWithPos(uint256)","df6a000d":"safe_withdraw(uint256)","df6a6002":"fourthMonthEnd()","df6a6b38":"redeemed(address,uint256)","df6ab3d5":"masssend(address[],uint256[])","df6abd34":"icoHardcap()","df6adc2a":"JackpotWinner()","df6af7d1":"getUnclaimedBuyerFunds(address,address,address,uint256)","df6afed9":"replaceArtwork(uint16)","df6b1ebb":"analyzeCondition(uint8)","df6c13c3":"getMinFunding()","df6c7cf4":"changeAssembly(uint256,uint64[],uint64[])","df6cf923":"IXTPayment()","df6d3afa":"setAngelHolder(address)","df6d4843":"getMaxLimit()","df6da6f9":"tokenSellData(address)","df6e1331":"drawGame(uint256,string)","df6e7a5f":"setTokenDelegation(address,address)","df6ee5f2":"lend(bytes32,bytes,address,uint256,bytes)","df6ee6b7":"addStage(uint256,uint256,uint256,uint256,uint256,uint256)","df6f023d":"reLoadCore(uint256,uint256,uint256,uint256)","df700074":"setadmin(address,address)","df706f77":"JTrex()","df708f01":"setMainContract(address,address)","df70ab71":"increasePositionOnBehalfOfRecurse(address,address,bytes32,uint256)","df70f3b5":"Jumanji()","df713abd":"get_time_locked_contract_size(address)","df7447dd":"createTicker(uint256)","df7458cd":"addReply(bytes32,string,uint256,address)","df745d28":"releaseBatch(address[])","df752519":"MANHATTANPROXY1STST()","df75574a":"buyItem3()","df755a98":"prPercent()","df75f3fb":"setPreSaleDurance(uint256)","df761fff":"TokensClaimedEvent(address,uint256,uint256,uint256)","df76d18d":"RegisterIP(bytes32,string)","df775a93":"skipInitBecauseIAmNotOg(address,address,uint256,uint256,uint256,uint256,bytes8,uint256)","df776689":"BasicIterator()","df77a290":"OddsAndEvens()","df77e074":"GetBetInfo(uint8,uint256,address)","df77eb1e":"transferHomeViaRelay(address,uint256)","df78c1dd":"payIn(uint256)","df79d8fa":"initialInvestorAccount(uint8)","df7ae3d8":"debugVal()","df7b70ab":"writesExercised(bytes32,address)","df7be446":"_removeNFToken(address,uint256)","df7bf704":"matchResult()","df7c5fca":"checkPeriodic()","df7cc70d":"ethUnPause()","df7cec28":"cancelBid(bytes32)","df7dbd70":"prTokens()","df7dfef7":"deleteAction(uint256)","df7efed8":"WeiinEth()","df8011b2":"HOWL()","df8089ef":"setAdministrator(address)","df811d7d":"numberOfPlayersInCurrentRound()","df816206":"getGiftIdsByRecipient(address)","df817e54":"checkPreIcoStatus()","df821cf7":"BIDCOIN()","df833a1a":"createGato(uint256)","df8344fe":"allAllowancesForManyAccounts(address[],address,address[])","df84807a":"templateIdOf(uint256)","df851f03":"calcNextPrice(uint256)","df8713ed":"addPot(uint256)","df88126f":"lockedInBets()","df8812c7":"addStageAmount(uint256)","df88401c":"KillahyToken()","df885536":"nxtAddr()","df888f4e":"AO()","df88f5b8":"setNotConstant()","df88fb44":"exchangeByPet(uint256,uint256,address)","df8b7771":"initialiseValues()","df8bb140":"cancelCampaign(bytes32)","df8d66e4":"addPlatform(bytes32)","df8dc370":"Reservation(address,address[])","df8de3e7":"claimTokens(address)","df8e03b1":"BasicWhitelist()","df8e739d":"bitzToken()","df8e9261":"_testItem()","df8f4376":"calcSTQAmount(uint256)","df8f4eb7":"originalTotalSupply()","df8f7971":"ProfileOwner()","df8f8a81":"setETCLockingAddr(address)","df90061b":"onSaleTokens()","df90c98d":"whiteListEndTime()","df90f719":"mln()","df91f2ab":"SggCoin()","df9204b6":"powerStatus()","df922744":"ScamSeal()","df922f3a":"changeCommission(uint256)","df93c9aa":"testrevert()","df957b04":"_couldWithdrawFromHolder(address,uint256)","df958553":"burnForGateway(address,string,uint64,uint64)","df9669e0":"setCrowdsaleEndDate(uint32)","df969bc0":"ADVISOR_TWO()","df96a336":"Bitkeun()","df979b92":"setIncreaseTotalWinningStake(bool)","df98ba00":"m_opNum()","df98ef33":"getResource(bytes,uint256,bytes)","df990c33":"becomeOwlmaster()","df9933e5":"SetPwd(bytes32)","df998f59":"checkSertificate(address,address)","df99f8bf":"TradeToken()","df9a4f56":"registerAuditor(address)","df9abaa0":"smallUintFunc(uint8,uint256)","df9b0774":"SwapResumed(uint256)","df9b2931":"FANBASE()","df9b3bae":"ZperToken(address,uint256,uint256)","df9b5fe9":"ALH3()","df9d3580":"accountBuyLimit()","df9e33e8":"getForeverRose()","df9f3139":"out4Done()","df9f92fb":"Scan(address[],uint256[])","dfa0ca14":"swapProject(uint256)","dfa13498":"LeasedBlock(uint256,uint256,uint256,uint256,bytes32,bytes32,bytes32,bytes32,address)","dfa15809":"databaseAddress()","dfa15b58":"RESERVED_OTHERS_SIDE()","dfa22fed":"buyFromOwner(string)","dfa24e8e":"sendEther(address,uint256,uint256)","dfa38fea":"NANI(address)","dfa4591c":"removeLogicVersion(uint256)","dfa54594":"getStandartRobot(uint256)","dfa5a25d":"purchaseCoffee()","dfa6bc72":"LoggedPhaseICO(uint256,uint256,uint256,string,string,uint8,bool,bool)","dfa72237":"innerPlayerFlight(uint256,uint16,uint256)","dfa78bf5":"savior()","dfa8be5f":"hackEducated(address)","dfa93d64":"relayContractAddress()","dfa9b440":"addAddressToWhiteList(address[])","dfaa3136":"addToMap(uint256[])","dfadb43c":"candyLandSaleAddress()","dfae7dc1":"vestingWhitelister()","dfaeaf67":"ThrowProxy(address)","dfaf3658":"closeCdp(address,uint256,uint256)","dfaf734a":"lastReleaseTime()","dfafaa72":"sendTo(address,uint256,address)","dfafb31d":"QUANTH()","dfafcf7e":"isMinion(address)","dfafe10f":"addParticipant(address)","dfb01c8f":"BCC()","dfb03cf7":"put(address,address)","dfb06d85":"AgentContract(address,address,address,uint256,uint256)","dfb0fb28":"ANGEL_ADDRESS()","dfb1913d":"withdrawFor(address[],uint256[])","dfb1abc0":"distributeReservedTokens(address,uint256)","dfb1c0e5":"buyToKen(uint256)","dfb259de":"SmartPoolToken(uint256,address)","dfb2866d":"priceFactor()","dfb29935":"sendHash(string)","dfb30c14":"getPlayerSpaceshipModelById(uint256)","dfb3557b":"BNB_MIN_CONTRIB()","dfb36b0b":"villagePrice()","dfb41e7c":"getForecast(bytes32,uint8,uint256)","dfb4a12e":"updateCandidateInfo(address)","dfb4ae3a":"WHOM()","dfb4b2f0":"deadline_status()","dfb59249":"EthRental()","dfb5a995":"countStureq()","dfb5f420":"Crowdsale(address,uint256,uint256,uint256)","dfb685cb":"BIT()","dfb69cb2":"colors(uint8)","dfb873fb":"getPrizeByToken(uint256)","dfb87be1":"setEndRate(uint256)","dfb8a38d":"getTokenPackPrice()","dfb8c6c2":"battleContractAddressCanBeUpdated()","dfb9560c":"right24(uint256)","dfb9bdca":"exchange(address,address[],uint256[],uint256)","dfba3be1":"pvpFinished(uint256[],uint256)","dfba9570":"removeStaff(string)","dfba9798":"withdrawMytoken(uint256)","dfbb3036":"currentRoundInformation()","dfbb4021":"checkGrid(uint8)","dfbb70c9":"timeOfLastIncrease()","dfbc3de1":"applyMember()","dfbcb8d9":"transferCard(address,address,address)","dfbd5c69":"EggsRedeemed(address,uint256)","dfbd6150":"subowner()","dfbd9973":"pageByAccount(address,uint256,uint256,uint256)","dfbde5a7":"FedCoup()","dfbe0587":"sellPorftolio(uint256,uint256)","dfbebd07":"licenseExpirationTime(uint256)","dfbec00e":"requestTopic(string)","dfbed623":"updateCaller(address,bool)","dfbef8de":"AllowExchanger(address)","dfbf53ae":"winner()","dfc027ef":"replayAnser(uint256,uint256[])","dfc0bedb":"setCode(uint256)","dfc10ea8":"callerAllocationEndBlock()","dfc119b0":"testRfind()","dfc28653":"NucleusVisionTokenUnlocked()","dfc2a146":"ORACON(uint256,uint256)","dfc366e8":"tenthousandths()","dfc3a987":"cntMembers()","dfc42f7c":"OmegaContract()","dfc4a516":"doApprove(address,address,uint256)","dfc6fbaa":"presaleBalanceOf(address)","dfc6ffc6":"CharlieCoin()","dfc74cb4":"testPlaceBet()","dfc75b9c":"sendJigouByOwner(address,uint256)","dfc765dc":"getMatchers_by_index(uint256)","dfc78bdc":"ProposalTallied(uint256,bool,uint256)","dfc7d488":"getTransactionFee(uint256)","dfc86d56":"UsdToEtherConvert(uint256)","dfc89632":"PresidentElections()","dfc8bff1":"updateLock(uint256)","dfca2f53":"LookAtPrizes()","dfca685a":"unlockPrivate()","dfca8fd2":"contributeForMakers(address)","dfcb4157":"saleAfterRefundPeriod()","dfcb737f":"allocateMarket_CommunitTokens()","dfcbb794":"TrustFund(address,uint256,address)","dfcbc298":"CancelBuyOrder(bytes32,address,uint256,uint256,address)","dfcc4b86":"ConcludeChallenge(uint256)","dfcc525d":"info_SeeTINAmotleyLine(uint256)","dfccdef5":"collectedETH()","dfcdc7f2":"regReferrer(address)","dfcdde5e":"calcAmount()","dfce5a7a":"changeGrantsController(address)","dfce791a":"counterWagerAndDeposit(uint256)","dfce8ac3":"fipsLegacyRegister(bytes20,address,bytes)","dfceb5ba":"refund_and_die()","dfcefd7e":"indexOf(uint64[],uint64,bool)","dfd024c1":"allocateInvestors()","dfd0c510":"ICOReward()","dfd142c1":"IncreaseWithdrawalAmount(uint256)","dfd17111":"ConstructZCashClue(bytes32)","dfd17f2b":"buyInBatch(uint256,uint256,uint256[],uint256)","dfd1be58":"platformFundingPerEpoch()","dfd200c5":"setRunning(bool)","dfd2ddec":"setForeignBridgeProxyOwner(address)","dfd4715e":"setDAdmin(bytes32,address)","dfd4e0f6":"setPrivateSaleHalt(bool)","dfd50f52":"contestants(uint256)","dfd52b74":"_getIcoAddr()","dfd5d3b0":"creditMcAddress()","dfd5dd6b":"ranksCount()","dfd6e6c5":"getIcoPhaseOneThreeDayIndex(uint256)","dfd80665":"whitelistAgent()","dfd84c13":"sendGain()","dfd8d516":"IsThisInternal()","dfd92f8a":"registerProduct()","dfd94849":"addNewSpinner(uint256)","dfd9e184":"droneIndexToApproved(uint256)","dfdadcb9":"isValidPurchase()","dfdadec6":"AlphaCarToken()","dfdb27da":"FoundGameCoin()","dfdb5f17":"doBurn(address,uint256)","dfdc349d":"getLestCommonMul(uint256,uint256)","dfdc99c7":"setKpopCelebContractAddress(address,address)","dfdce77b":"setScrapPercent(uint8)","dfdd3997":"maxETHAutoContributions()","dfde567f":"processAR(uint256)","dfdfb261":"addEsgoTX(address,uint256,uint256,uint256,uint256)","dfe0f0ca":"transferWithSender(address,address,uint256)","dfe1304c":"HumanStandardToken123(uint256,string,uint8,string)","dfe1b17e":"dequeueOrder()","dfe1dcf6":"adminSendEthtoAddContract()","dfe1f357":"checkHash(address,uint256,address,uint256,uint256,uint256)","dfe2de30":"boughtTime(address)","dfe333bd":"copiesSold(uint256)","dfe33748":"TokensAreFrozen()","dfe346d0":"NicksTastyToken()","dfe3a52b":"CUTOFF_PRESALE_TWO()","dfe3e746":"setMasterNode(address)","dfe4858a":"constuctor()","dfe4c261":"approveTransaction(uint256,uint256,string)","dfe525a2":"addHandler(address,address,string,string)","dfe5ef48":"issue(address,uint256,uint256)","dfe699b1":"SetApplicant(string,string,string,int256,string)","dfe6af85":"testThrow_testablePayoutCaseShouldBeFailure()","dfe6d366":"gamblers()","dfe71183":"createCDPLeveraged()","dfe71486":"displayuserdetails(address)","dfe81a26":"GnarlyTimes()","dfe921cb":"lifeReserveTimeLock()","dfea6ec2":"placeBetWithInviter(uint256,uint256,uint256,uint8,bytes32,bytes32,address)","dfea8483":"Countout()","dfeade00":"AceEquityToken(uint256,string,string,uint8)","dfeb1719":"getNotaire()","dfeb1fd3":"getUserVotes(address,string,string)","dfeb34b6":"stakeFailOverRestrictionLifted()","dfeb3c49":"getNonces(address,address)","dfebb4ee":"viewMostRelevantClauses()","dfec375e":"calcCurPointsForAcct(address)","dfedff20":"getTwit(address,uint256)","dfee01d8":"mUpgradeSpeedup()","dfee2bad":"phaseReleaseAmount()","dfee6348":"COMMUNITY_PLUS_PRIORITY_SALE_CAP_ETH()","dfef54a3":"TihoToken(uint256,string,uint8,string)","dfef58a6":"registration(bytes32,uint256,address)","dfef5f69":"mintingStartTime()","dfefaf3f":"secureUnapprove(address)","dff0259f":"donationSum()","dff05de4":"pctDIDOwned(address,address)","dff114dd":"investedCrowdsaleTokenOf(address)","dff18fe0":"provideTeamHolderToken(address)","dff1ab15":"checkProposalCode(uint256,address)","dff2db71":"binaryAddress()","dff3f3b9":"ownerWithdrawal(uint256)","dff3f83e":"resolveRawDelegation(bytes32,uint256)","dff44b2f":"divorce()","dff4a5e8":"getRestaurant(address)","dff53231":"love()","dff538e6":"_currentDay()","dff5f5cb":"updateStartPhase(uint256)","dff649dc":"NameChanged(address,uint256,string,string,uint256)","dff675c2":"getDelivery()","dff79905":"LogTokenRemover(address,uint256)","dff90b5b":"sendFees()","dffa771f":"_setWeaponValue9(uint256)","dffb0bd1":"getPlayerTotalDividend(address)","dffbbef5":"stopDistribution()","dffbd9de":"TokenAdded(address,address)","dffcf9a7":"transferableHavvens(address)","dffd5e57":"buyToken(bytes32)","dffd6054":"changeGameAddress(address)","dffd722f":"totalEarn()","dffd9b8e":"CEO_TEAM_SHARE()","dffdc75d":"forward(address,bytes,uint256,bool)","dffe0a63":"getStatGames()","dffeadd0":"main()","dfff2f79":"autoReinvestFor(address)","dfffcbdb":"triggered(uint256)","e0004f43":"batchTransferTokenS(address,address[],uint256[])","e000eec3":"createPixel(uint24,uint32)","e0018f2f":"showPlayerSeasonScores(address,int8)","e001ddf1":"teamTokensCurrent()","e0020f1a":"tokensPerEthPublicSale()","e0024ae3":"_mine(uint256,address)","e002a486":"changeForwardTo(address)","e002f2ee":"cpCap()","e0031b1d":"GetDOTDelegatedRevoker(bytes32,uint8)","e003604e":"close(address,uint32,uint192,bytes)","e0036d1d":"verifyPosition(uint16,uint8,uint64)","e0041396":"slice(bytes,uint256,uint256)","e004b76f":"PermissionRemoved(address)","e004fe97":"CarRegistry(string)","e004feb0":"testFailMintGuyWhenStopped(int256)","e0056019":"setLand(uint8,uint8,uint8,bool,uint8[])","e0063224":"vouchers(bytes32,uint256)","e0068052":"division(uint256,uint256)","e00686e4":"rewardPerBlockPerAddress()","e006997c":"authenticate(string,bytes)","e007b330":"sterilize(uint256[])","e0081b8c":"approve(bytes32,bytes32,uint256)","e00824bb":"payCreator()","e0089ce7":"UCtestCoin(uint256,string,uint8,string)","e008cdf3":"SBSCoin()","e00a7fc5":"transferFromOwn(address,uint256)","e00ab6dd":"private_setminBet(uint256)","e00ac9a3":"thirdTime()","e00bc0f4":"setIsContainerForMarket(bool)","e00bc7fb":"vota_un_candidato(address)","e00be2a9":"getErc20Rate(string)","e00cb0bc":"etherReceivedPrivate()","e00d0aed":"TalosToken()","e00d7e5c":"ExampleToken()","e00dd161":"currentId()","e00f882c":"numberOfExchInEstateNasAlice(address,uint256)","e00fe2eb":"getText()","e01060f8":"transferOwnership(uint8[],bytes32[],bytes32[],uint256,address[])","e010c686":"newProposal(uint256,uint256,bytes32)","e011171d":"setDOwner(bytes32,address)","e0117441":"setRegistrationPrice(uint256)","e011ac87":"amountLeft()","e01330bb":"testMul(uint256,uint256,uint256)","e014a39f":"weiRaisedIncludingFiatCurrencyRaised()","e014a83f":"takeToken(address,uint256,string)","e01546a8":"fromFraction(int256,int256)","e01567cf":"ethBioxRate1()","e015c62a":"calculatePrice(uint256,uint256,uint256)","e015d863":"variation()","e016603f":"createMultipleShows(uint256[])","e0179e6c":"etherValue(uint256)","e0180115":"culcurateBonusRate()","e0182436":"cancelEscrow(uint256)","e0187d18":"third_partner_address()","e018c36c":"buyFirstPackFromReferral(address,bool)","e0192072":"Rescue(address,address,uint256)","e0195a53":"maxRandom(uint256,address,uint256)","e01964d0":"sterile(uint256)","e019ac29":"setKycCertifier(address)","e01a38c6":"ecrecoverSigner(bytes32,bytes,uint256)","e01ac5a4":"giveReward(bytes32,address,uint8)","e01b1b10":"ICODays()","e01bb918":"_withdrawAll(uint256,address)","e01bc60b":"totalCustomBuyersMapping()","e01c6d4e":"cashin()","e01c979a":"GuneToken()","e01cd37a":"cancelSellingToken(address)","e01cdfaa":"getEmployeeInfoById(uint256)","e01cff84":"getTransferringForCount(address)","e01d1f3d":"MultiSigWallet(address[],uint256,uint256,string)","e01dd67b":"AMBASSADOR_THREE()","e01e0618":"feeDiv(uint256,uint256)","e01e92d2":"abs(int128)","e01ea00c":"getDarknodesFromEpochs(address,uint256,bool)","e01ef1f8":"addInventory(bytes32,string,string,string,string,uint256,uint256)","e01fff13":"familyContract()","e0201e07":"Eclipse()","e0204585":"get_bet(address,address)","e020b8a3":"contract_date()","e02163e7":"etherContributionOf(address)","e021b8cb":"useWeapon(uint8,uint8,uint8,uint8,uint8[176])","e021deff":"meta(address)","e02243ee":"buyInternal(address,uint256)","e023094f":"createDroid(uint256,string,uint256,uint256,uint256)","e023f90e":"getCity(uint16)","e02426c1":"getSignatureHash(bytes4,uint256)","e024ec5a":"getFmmsDetail(bytes32)","e0256835":"balancesCrowd(address)","e02584bf":"listPairForReserve(address,address,bool,bool,bool)","e025a666":"rewardPercentageDivisor()","e027034d":"isWithinIEO()","e028222f":"CreateABet(address,uint256)","e028ff3b":"lotteryGiveHuntMinimalNumber()","e0299621":"GBIToken(uint256,string,string)","e02b8b29":"HardcapToken()","e02ba030":"excess_token()","e02bc1c6":"bidDeposit(bytes32)","e02bcd3e":"getLendTokenBalance()","e02c3b5d":"getAllLeftLeg()","e02c7e1f":"timelockAllocationAddress(address,uint32)","e02c85a4":"_checklottery(uint32,uint32)","e02cec51":"refund(address[])","e02d1c0e":"tradeStarttime(uint256)","e02d306f":"getUNTSQM()","e02df495":"MAX_ETHER_24H()","e02f8d33":"PRICE_STAGE_THREE()","e02f9027":"iTime()","e02fab06":"anubisToken()","e0300fc4":"unregisterFor(address,bytes32,address,uint256,uint256,uint256)","e0303a2e":"getFirstTwoOutputs(bytes)","e0304542":"oddEven(uint8)","e0307e94":"gcsp(uint256)","e030bbd5":"tokenToPointByMetaMask(uint256,uint256)","e030dfb9":"emergency(bytes32,bytes1)","e03179b4":"LogContribution(uint256,uint256)","e031d6f0":"isICOFinished()","e0328c5f":"setRecovery()","e0328c80":"hasRedeemed(address,address,uint256)","e033192c":"gettransferableStartTime()","e03335b4":"_calculatePricePerPixel(uint256)","e0340a05":"Maya_Preferred()","e035e1ac":"thirdBonusEnds()","e03652c2":"isTransactionPending()","e0376e74":"LOG_EmergencyWithdrawalSucceeded(address,uint256)","e037a71c":"withdrawLimit(address,uint8)","e03827d2":"left70(uint256)","e0389a47":"removeAccountMilestone(address)","e038c75a":"circulating_supply()","e0391b6f":"trackable_dislikes(address)","e03992fd":"nextForkUrl()","e039967c":"migrateTransfer(address,address,uint256,uint256)","e039e4a1":"getOwner(uint8,uint8)","e039f224":"isFork()","e03b3044":"setAyantDroitEconomique_Compte_7(uint256)","e03bc7e1":"_registerDevice(address,bytes32,bytes32,bytes32)","e03c151e":"LogSetSTOContract(address,address,address,uint256,uint256)","e03c1c4b":"setLineStartTime(uint256,uint256)","e03c639c":"addPreSaleWallet(address)","e03cca4d":"setChallengeFormulaContract(address)","e03d890b":"_addTokenToAllTokensEnumeration(uint256)","e03e09a8":"_createAuction(address,address,uint256,uint256,uint256)","e03ec01d":"getTargetWallet(address)","e0401918":"SMRToken()","e0402d26":"validDoHash(bytes32)","e04093d6":"updateOracleWithENS()","e040c164":"createT513(uint256,uint256,address)","e040f3e1":"_humanSender(address)","e0412a54":"setBonusRound2(uint256)","e0429b6c":"ShinySquirrels()","e042ad58":"operationWallet()","e0443e92":"LogCreate(address,address,uint256,uint256)","e044c2de":"newLoan(bytes,address,uint256,uint256,uint256,uint256,uint256,uint256)","e044c47f":"playerRollDice()","e0453376":"hasFourYearWithdraw()","e0457049":"trustedInput()","e0457884":"betResolution(uint8,uint8,uint8,bool)","e0462547":"setEndPreSale(uint256)","e0462d0a":"coreTeamMemberOne()","e046c4dc":"Delete()","e046f06f":"deathData_a1()","e0470e02":"matureDragon(uint256)","e0472e36":"swapProposal(uint256)","e0475e27":"holderMarketingTokens()","e048d0fc":"voteCancelCurrent()","e0495a64":"getNormalBuyers()","e04a1942":"test_fourValidEqUint()","e04a2525":"NoahDividend(address)","e04a8c08":"Sold()","e04ac09e":"BountyIssued(uint256)","e04c130b":"token_transferFrom(address,address,address,uint256)","e04c1830":"findNextHour(uint256,bytes2)","e04cd07c":"BOLTH(address,address[],address)","e04d5105":"calculateSeedBuySimple(uint256)","e04f31e9":"forward(address,uint256,bytes,bool)","e04fac0c":"aVideoCost()","e0504910":"buyWithTokens(address)","e050674c":"_deliverWhitelistBonus(address)","e0522012":"getAdjustedPotAsFixedPointForGameId(uint256,bool)","e052a587":"isNotExpired(uint256,uint256)","e052f0c8":"setParams(string,string,string,string,uint256,address,uint256)","e053178a":"XCPlugin()","e0539225":"preicoPrice()","e054057d":"LogBuy(uint256,address,uint256)","e0540d85":"CDreamingICO()","e054c029":"changejp2(address)","e055bba4":"turnId()","e056989a":"OfferUpdated(uint256,bytes,uint256,address)","e056c1eb":"isGlobalPause()","e056f2ff":"takerFeeRateE4()","e0576665":"addLen(string)","e0585ce8":"BetcoinICO()","e058cc59":"setMemeTemplate(string)","e0591ddc":"gizerItemsContract()","e059c868":"private_UpdateGameBarLimit(uint256,uint256)","e05a48cd":"unregisterVendor(address,address)","e05b4c5f":"GetReferredAt(uint256)","e05b5456":"ChenToken(address,address)","e05bac82":"amountReceivedFromExchange(uint256)","e05c5a83":"sellerOf(uint256)","e05cb6f4":"Mitrav()","e05d769e":"expirationSeconds()","e05e3028":"getCommunityManagement(uint256)","e05e91e0":"returnUint64(uint64)","e05ea744":"frost()","e05ee7a4":"RATEotu()","e05f149e":"getTotalRuns()","e05f7d67":"setPCoinContractAddress(address,address)","e05fad90":"decode(bytes,uint256,uint256)","e0607290":"confirmChangeOracle()","e06174e4":"settings()","e0619859":"At(uint256,bytes32)","e061ddca":"getSensorAddress()","e0623632":"UNSOLD_ADDRESS()","e062aff8":"startTimeNumber()","e06309bb":"ValueOwners()","e06375c8":"_fDist()","e063a439":"_computeFee(uint128)","e06452d0":"Completed()","e064bc82":"setFoundersTokensWalletSlave(address)","e064c1ec":"denyChanges()","e065029e":"PokemonPow()","e0655fe5":"changeBuyFee(uint256)","e065914c":"isPersonalLock(address)","e065e388":"NewBOP(address)","e067ea46":"Etherep(address,uint256,address,uint256)","e067f631":"intervalUpdate()","e06868e2":"numberOfBet()","e06902fa":"ito()","e06a09ec":"calculateInterestIndex(uint256,uint256,uint256,uint256)","e06a60ff":"HumanityCard()","e06aa145":"TokenBurned(address,uint256,uint256,uint256)","e06af204":"BetlyCoin()","e06b5837":"getCanSellUnit(address,address,uint256)","e06b7e39":"getInitOrInput()","e06b850c":"testIntParserTwoDecimal()","e06c0fd2":"SatoshiToken()","e06c5808":"burnFromAddress(uint256)","e06d8de9":"acquisitionsLockEndingAt()","e06e0051":"withdrowETH()","e06e0e43":"overLimit()","e06e3873":"encrypt(uint256[])","e06e6b20":"Like(bytes32,bytes32,uint256)","e06e82b2":"teamNIMFAAddress()","e06e9d22":"addCustomerTokenAmount(address,uint256)","e06ec0bb":"isListing()","e06f3d38":"ownerA()","e06fa13d":"ETCL()","e06fa68e":"updateAfter(uint256)","e06fc6d4":"mainsaleRemaining()","e0709589":"blink_block()","e0715a86":"unlocksCount()","e071681d":"setManyAccountsVerified(address[])","e071c0ca":"transferVaultOwnership(address)","e072830c":"FUNDING_ETH_HARD_CAP()","e0728801":"ANV()","e072bd10":"getPlayerInventory(address)","e073ef69":"pubKeyToBitcoinAddress(bytes,bool)","e0741187":"createBreedingAuction(uint256,uint256,uint256,uint256)","e074278d":"setOwnerAddr(address)","e074b027":"hasExecuted(uint256)","e074bb47":"removePermission(address)","e074ee55":"getPeriodsToPay(bytes32,address,uint256)","e0755792":"Permission(bytes32,address[],bytes4[])","e0755b35":"WePOW()","e076c0ae":"queryNow()","e0772f6a":"CROWDSALE_TOKEN_IN_WEI()","e0775be1":"create(address,address,address,address,address,address,address)","e0778211":"_releasableAmount(address,uint256)","e077ca97":"fx()","e078c549":"getNumberOfTokensToIssue(uint256)","e07959bd":"setGainsRate(uint256)","e079e334":"getNewCoinFee()","e079e7e5":"addStock(string,uint256,uint256,uint256,uint8)","e07a2671":"migrationSetPlayer(bytes32,uint256,bytes32,address,uint256,uint256,uint256)","e07a31c7":"getWinningCount(uint256,uint256)","e07a5d29":"CLRCoin()","e07be247":"createSellENS(string,uint256)","e07c80fb":"getKindAddress()","e07ccdeb":"totalPartnerWithdrawSupply()","e07cd936":"ArtcoinPlaceholder(address,address)","e07d4f6b":"saveCarDataTransaction(address,address)","e07f0b66":"SendMessage(uint256,string,address)","e07f0f13":"ZhangPeiPei(uint256,string,uint8,string)","e07f0f5e":"transferToken(address[],uint256[])","e07f3dd6":"go(uint8)","e07fa3c1":"withdrawFund()","e080241c":"setNFTDetached(uint256)","e080b60c":"apiCallsContractAddress()","e0812c75":"migrateInvestorFromHost(address,address)","e0813e25":"getRandomInt(uint256)","e0813e5e":"updateTokensPerEthOnce(uint256)","e08155dd":"ICO_PERCENTAGE_4()","e0815ca9":"findNextMinute(uint256,bytes2)","e0818669":"lps()","e081b569":"DiceOnline()","e081fdfe":"availableBalanceOf(uint256,uint256)","e082707c":"_uintToString(uint256)","e0832cf6":"getWinCount(address)","e0834ea4":"WatchBalanceInEther()","e083a1b5":"_createEstate(int256[],int256[],address,string)","e083d4c8":"dividendBalanceOf(address)","e084a819":"prepareCrowdsale()","e08503ec":"calculateNextPrice(uint256)","e085448f":"FIRST_USER_CUT()","e085942a":"getSubjectMattersSize()","e085c539":"getPlayerScore(address)","e085f82b":"rejectCertificate(address)","e086141d":"Assigned(address,uint256)","e0862fd7":"getNumBadBets(uint256)","e086e5ec":"withdrawETH()","e0873c06":"reissueAsset(bytes32,uint256)","e08761f5":"dtValidateCitySnapshot(address,uint256)","e087cd55":"withdrawIncentives()","e0882af8":"airDrop(address,address[],uint256[])","e0886f90":"at(uint256)","e088747b":"withdraw(address,uint256,string)","e088a96b":"claimerUnset()","e08a5f9e":"startPresaleDate()","e08ac014":"unlockPeriodNum()","e08b63ad":"getAddTokenNonce()","e08bc3fe":"parseInt(bytes)","e08d28d3":"maxInvestmentICO()","e08d8497":"ICO_LEVEL_2()","e08e433a":"transferTime()","e08ed5f9":"withdrawBid(int256,int256,int256)","e090318c":"setFacts()","e090ebab":"VUO()","e0911183":"devTeamAutoBuy(uint256,uint256)","e091de56":"MDA()","e091f453":"setDividend(uint256)","e0929b95":"claimFreeFirstCard(address)","e093a157":"abs(uint256,uint256)","e09413ba":"totalDistributedAirdrop()","e0945a80":"wbcoin()","e0950ddf":"getBet(uint256,address)","e095f814":"etherToToken(uint256)","e0963ced":"LinkEyeStandardToken(uint256,string,uint8,string)","e09678fd":"setIcoContract(address)","e097e7b9":"sendTokensBack()","e098161b":"getRareCoinAddress()","e09874c0":"setPlayConfigs(uint256,uint256,uint256)","e0987873":"BurnedAllRemainedTokens()","e098c76d":"optionPoolTotalMax()","e09adc70":"ethToTokenRate()","e09ca60c":"secureApprove(bytes32,uint256)","e09ceada":"_newAuction(uint256,uint256,uint256)","e09cffcf":"SingularityTest18()","e09d0b75":"compareLeaf(uint256,uint256,uint256,uint256)","e09dbfa4":"checkPatternExistance(bytes32)","e09dd024":"FNCTToken()","e09ded57":"lengthOfCommonPrefix3232(bytes32,bytes32)","e09e9490":"releasePendingTransfer()","e09ea701":"BaseMonoretoCrowdsale(uint256,uint256,uint256)","e09ee57f":"feePercentageMax()","e09ef83e":"promoCutieCreatedCount()","e09f0020":"subCreditScore(uint256,string)","e09f310a":"get_iconiq_presale_open(address)","e09f6f49":"successAtBlock()","e0a09c1f":"Crowdsale(address,address)","e0a0f50d":"setSlaveWalletPercent(uint256)","e0a1a292":"addressAdvisors()","e0a1be53":"updateTargetedMoneyReached()","e0a1ca6e":"winningChance()","e0a1fdad":"unset(bytes12)","e0a21739":"setBlackFundsWallet(address)","e0a27b2c":"withdrawWinnings(uint256,uint256)","e0a29e23":"owner_freeze_start()","e0a3bff7":"RollCount()","e0a3e7ec":"computeDeferBlock()","e0a49f14":"setMatchOutcome(uint256,string)","e0a4aacb":"ExacoreContract(uint256,string,string)","e0a53397":"createSingle(uint256)","e0a550fc":"closeMainSaleICO()","e0a60ea3":"BITTOToken()","e0a62339":"getSha256_UInt(uint256,uint256)","e0a668b4":"setVesting(address,uint256,uint256)","e0a70811":"restart(bytes20,bytes)","e0a73a93":"premium()","e0a7527d":"updateCABoxToken(address)","e0a7b2c3":"startChallenge()","e0a802ba":"scanInputs(bytes,uint256,uint256)","e0a827c6":"RxI()","e0a8299f":"galleryTwo()","e0a82ea8":"setMinBetPerRoll(uint256)","e0a8aa72":"channelOpened(uint64)","e0a8f6f5":"cancelProposal(uint256)","e0aa5654":"getCountReadyPlayerByTrackId(bytes32)","e0abdf66":"setBlockTimestamp(uint256)","e0ac2b72":"HaHaChainToken()","e0ac50cb":"isTreasureBox(address)","e0ac61bb":"changeOwnerSharePerThousandForMating(uint256)","e0acac7f":"withdrawSum()","e0ad411d":"assets(bytes)","e0ae751f":"setAuthorizedContract(string,address,bool)","e0ae96e9":"din()","e0b1cccb":"updateBalance(address,uint256)","e0b1cecd":"DataToken()","e0b30178":"OVCLockAllocation(uint256,address,address,address)","e0b3198c":"serverPort()","e0b3c49c":"acceptTermsAndJoinDXF()","e0b3cc90":"priceOf(uint32)","e0b438ef":"removeNameByOwner(string)","e0b45487":"_setValidator(address)","e0b490f7":"getAccountId(address)","e0b4cf0a":"setMinMaxBet(uint256,uint256)","e0b6cddd":"LLV_311_EDIT_2()","e0b78225":"RemoveTrustedContractAddress(address,address)","e0b86c53":"decreaseLock(uint256,uint256,address)","e0b999a1":"getAmount(address,uint256)","e0b9e83d":"update(address,address,address,uint256,uint256,address)","e0bab523":"for_rewards()","e0bb933b":"getDragon(uint256)","e0bc6c44":"claimInsurance(bytes32)","e0bc6dea":"removeTransferableAddress(address)","e0bd3015":"getClaimableBalance()","e0bd53be":"sellTokensForZec(string,address,uint256,uint256)","e0bd7d15":"addContributor(address,uint256)","e0bede59":"firstPeriodSupply()","e0bfa1f7":"removeUtilityHolder(address)","e0bfe9ad":"MAX_TOKENS_RESERVE()","e0c012ff":"modifyairdrop(uint256,uint256)","e0c104ad":"DONC()","e0c2bc77":"CDEos(uint256,string,uint8,string)","e0c2dcbd":"last_win_wei()","e0c4cea8":"GrowToken()","e0c5f3a0":"add256(uint256,uint256)","e0c6046c":"donateToProject(uint16)","e0c6190d":"checkTime()","e0c63902":"Ok()","e0c67b9c":"ROKToken()","e0c68db0":"shr(uint32,uint8)","e0c6d1ed":"migrateForInvestor()","e0c78337":"XITOToken(address)","e0c7c117":"Randao()","e0c82651":"RWToken()","e0cb3aa0":"buyWithLimit(uint256,uint256)","e0cbbde7":"makeCode(uint256,string)","e0cbf845":"testAddLocked()","e0cc4e1b":"LifCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address,address)","e0cd34f6":"getBlockBuildFee(uint256)","e0cd6eff":"board_size()","e0ce0b79":"processSeason(uint32)","e0ce72cb":"_fConfig()","e0ceb25b":"fairsaleProtection()","e0cec919":"setDailySupply(uint256)","e0cee23f":"SuccessfullyTransferedFromCompanyInventory(address,uint256,bytes32)","e0cf1316":"_transferPlayer(address,address,uint256)","e0cf17a5":"totalStoredDDT()","e0cf1e4c":"removeMembers(bytes32,address[])","e0cf715d":"EtherTrend()","e0cf72e1":"ERC20Token(uint256,string,string)","e0cfc05c":"testThrowsRetractLatestRevisionDoesntHaveAdditionalRevisions()","e0cfde22":"setRestrictedParticipationCap(address[],uint256)","e0d05c51":"MemoireClement()","e0d1ba52":"Rate_Eth()","e0d2771d":"MINIMUMINVESTMENTPRESALE()","e0d29d38":"STARTING_POOH()","e0d3558e":"GetBoosterData(uint256)","e0d370ac":"site()","e0d4ea37":"getSeed(uint256)","e0d4ea7e":"addDestructionProposal(string)","e0d54970":"getInstructions()","e0d5af94":"ownerWithdrawAll()","e0d669d8":"tradesLock(address)","e0d6d530":"setContracts()","e0d751da":"returnBets()","e0d77ff6":"hasBeenBooted(uint32)","e0d79d38":"addcertifieddata(string,string,string)","e0d872b7":"getSideServices()","e0d9bc7b":"sybmol()","e0da260c":"widthdraw(uint256)","e0da4abd":"getDefaultExchangeRate()","e0db6781":"offerDraw(bytes32)","e0db874d":"moneyBack(address)","e0dba60f":"setController(address,bool)","e0dbbea2":"search(uint256,bytes32)","e0dc892c":"GiftHasBeenSent()","e0dcf2d8":"processInitialDistribution()","e0dd31da":"MDCSToken(uint256,string,uint8,string)","e0dda563":"GetContractStagePreMoveIn()","e0ddaa0e":"MAX_TOKEN_BUYIN()","e0dec0c0":"contractValue()","e0df51bb":"test_oneValidAndInvalidEqAddress()","e0df53b9":"LotteryRoundStarted(bytes32,bytes32,uint256,string)","e0df5b6f":"setTokenURI(string)","e0dfd0a6":"GIFTCOIN()","e0e04685":"setOldContract(address)","e0e081d7":"marketStatus()","e0e0e2d3":"random(uint8)","e0e1104d":"tierWhitelist(uint256)","e0e11a14":"newVowIdFlag(address,uint256,uint256)","e0e1593c":"decayedPriceFrom(uint256,uint256)","e0e16f91":"TestContract(address,uint256)","e0e1a7f0":"testSHA3()","e0e267e5":"minimumWei()","e0e29ac1":"SLMICO(address)","e0e32504":"isDaySixtyChecked()","e0e34e06":"getGlobalConstraintParameters(address,int256,address)","e0e3671c":"checkOwner(address)","e0e3b9d7":"ImmutableShares()","e0e3ba5a":"getLosesShare(address)","e0e3feae":"skimALittleOffTheTop(uint256)","e0e40349":"name(address,bytes32)","e0e4704e":"RequestDetachmentOnPause(uint256)","e0e4731a":"TokenGoalReached()","e0e4c438":"sendInternally(address,uint256,uint256)","e0e58009":"BookingPoC(address,address,uint256)","e0e5fffd":"preSale4()","e0e69937":"setDefaultVestingParameters(uint256,uint256,uint256,uint256,bool)","e0e6d6cb":"requireValidIndex(uint256,uint256)","e0e7127a":"getContractOwnerAddress()","e0e722b7":"MAX_ALLOWED_STAGE_3()","e0e81ccb":"getCurrentSchellingRoundID()","e0e848c0":"checkDone()","e0e84e81":"changeCompanyWalletAddress(address)","e0e85fe8":"StatEventA(string,address)","e0e8823c":"withdrawDai(uint256,address)","e0e8a555":"KAL3Token()","e0e9b349":"getReportRegistrationFee()","e0ea129e":"militaryToken()","e0eb3035":"registerAudits(bytes32[],bytes,bool)","e0eb60b2":"initialSpinners(uint256)","e0eb6613":"PresalePool(address,uint256[],uint256)","e0eb9449":"mateAnimal(uint256,uint256,string,string)","e0ebd259":"discountValue()","e0ebdbff":"getAuditRequestor(uint256)","e0ec289a":"creditsExchanged()","e0ed78d1":"setRouletteRules(address)","e0ee74e9":"changeActualQueue(address)","e0ee94e9":"PocketCoin()","e0eef0b9":"BOOKIE_POOL_COMMISSION()","e0efdaf9":"softCapTokensAmount()","e0f0497d":"currentTokenSaleId()","e0f06352":"testIsContractAddress()","e0f20a65":"etherLock()","e0f31fae":"isDoneReporting(address)","e0f32198":"runSweepStake()","e0f3691d":"thisEther()","e0f426fa":"numMCApplied()","e0f47580":"withdrawCommisionToAddress(address,uint256)","e0f4a1a2":"minimumPRETDEContributionInWei()","e0f4ed01":"parcelEth()","e0f50bac":"senderWithdrawal(uint256)","e0f609d4":"unsafeIsEncrypted()","e0f6cc07":"isChain(string)","e0f74cde":"BONUS_TIMES_VALUES(uint256)","e0f771c9":"Bithumb(uint256,string,string)","e0f7b44d":"PreTgeExperty()","e0f898e4":"totalTokenLossValue()","e0f8c670":"getFirstPaymentAmount()","e0f8da97":"sponsoredBonusToken()","e0f9210b":"batchDistributeReward(address[],uint256[],uint256)","e0faf0a8":"getOnSaleIds()","e0fb8459":"recevedEthFromExchange(address,uint256)","e0fce922":"deliver(address,uint256,uint256)","e0fd59bf":"disableAdminForever()","e0fddf81":"setemployee(address,string,uint256)","e0fdf336":"finalReserveTimeLock()","e0fe01f4":"makePrediction(int8,string)","e0fe075e":"payoutReady()","e0fe42be":"existsPriceOnAssetPair(address,address)","e0fe4a84":"updateStrategyCategory(bytes15,uint256)","e0fe6d07":"SideBridge(uint256,address[])","e0fe9ccf":"WaltonTokenLocker()","e0ff5b8b":"getBook(uint256)","e0ff5d2f":"setMaxRacers(uint8)","e0ffa0da":"lastBlock_f13()","e0ffe8e3":"newOrder(string,string,uint256,uint256,string,string,string)","e1005556":"allowTransferWhitelist()","e1017332":"sellPaused()","e1021b53":"getLuckyRecordSize()","e10289b8":"addContributor(uint256,address,uint256)","e102baab":"setTokenController(address)","e102d950":"getNameHash()","e1036f86":"tax_distributed()","e1041d86":"__throw()","e106fae9":"lottoLowestNumber()","e106fb4b":"stringToBytes(string)","e1082335":"to(bytes32,address)","e1089240":"Csts()","e108d2d6":"setMintAdminApproval(address,address,address)","e1094ff6":"DGZTokensSold(address,uint256)","e1097249":"initStage()","e109ef24":"setTokenOperatorApprovals(address,address,bool,bool)","e10a70b7":"LogRedeemVIBE(address,uint256,uint256,uint256)","e10aa985":"Elyxr()","e10b650b":"winnerWithdraw()","e10bcc2a":"startMilestone(bytes32,uint256,address,uint32)","e10be707":"changeGoodBye(string)","e10c7bb5":"EventStore()","e10d29ee":"queue()","e10d416f":"enablePurchasing(bool)","e10d4c0b":"isSaler(address)","e10e274a":"CrazyEarning()","e10e5dce":"_build(bytes)","e10e66e6":"changeWeiPerToken(uint256)","e10e8ffe":"doOraclize()","e10e95c9":"fundingEnabled()","e10eda7a":"IOCFundIndex()","e10f1b06":"isTournament(address)","e10fb98f":"testMul()","e1103422":"retractRewards()","e11074cb":"initFund()","e1108706":"rfind()","e1112648":"record(bytes)","e1115aa5":"addUserRewards(uint256,uint256,address)","e1134799":"claimDaoStakeSupply(address)","e11398e8":"burnLeftovers()","e113c6fd":"ICO_SINCE()","e11443cb":"UWNToken(uint256,string,string,address)","e1152343":"payout(uint256)","e11527d4":"linkedContract()","e11583b7":"TokenOPSSaleAddress()","e116b17e":"getKudosLeftForProject(address,address)","e1175a79":"getMyTickets(string,address)","e117e6f9":"MyToken(uint256,string,uint8,string,uint256,uint8,uint256,string,string,string,string,string,string,string)","e1181c73":"faucetLif()","e1187e2e":"getCollectibleWithMeta(uint256)","e118eda4":"featuredSpritesLength()","e118fba2":"redeemPurchases()","e119f8bb":"migrateMarketInFromNibling()","e11a5a4f":"allocateStartBlock()","e11aa56d":"getDeedTimestampByAddress(string,uint256)","e11b09e0":"softCapCompleted()","e11b53af":"getContributionsCount()","e11dba54":"messagesLength()","e11df80d":"batchVipWithLock(address[],uint256[],bool)","e11e1b0c":"escrowBalance()","e11efa06":"getProgress(uint256)","e11f493e":"reentrancy()","e11f6398":"MAXIMUM_PERCENT()","e11fe9ec":"hasItem(uint256,uint256)","e12073a0":"getAllDetails(address)","e12097b7":"getCurrSale()","e121c102":"incentives(uint256)","e1221400":"getCoinInfo(string)","e1226164":"getFamilyById(address)","e122c028":"totalLBSold_GENERAL_2()","e122f1b2":"GoldenCurrencyToken()","e123182b":"purchase(bytes32,uint256)","e1248d52":"DYLC_ERC20Token()","e124e37b":"add_allowedAddress(address,address)","e124f899":"toPool()","e1252b9b":"make_anonymous_registration(uint256,uint256)","e1254fba":"getDeposit(address)","e125501f":"refundParticipants(uint256)","e125f88b":"aoccoin()","e1266042":"setTakeOwnershipFeePercents(uint256)","e126eb7d":"referralCodeFromAddress(address)","e1270b6e":"approval(address,address)","e1281280":"setAddressUIntMapping(address,uint256)","e12849b2":"getMineGenesis()","e1287520":"getBets(uint256,uint256)","e128f0d6":"getTogetherDate()","e12925a9":"setUnownedNickname(uint256,string)","e129330b":"factorContributed()","e129c99d":"notaryBookSize()","e129f783":"NameRegistered(address,bytes32)","e12a3bbe":"icoAllocation(uint256)","e12a894e":"CbdStandardToken(uint256,string,uint8,string)","e12badcf":"PlatformInformation()","e12bcd68":"relayerName()","e12bceeb":"performEqual(address,address[],uint256)","e12cbb3c":"SIGNAL_DELAY()","e12cbb9e":"updateOrderBatch(bool[],uint32[],uint128[],uint128[],uint32[],int256)","e12ed13c":"currentBlock()","e12ee8d7":"totalAmountRaked()","e12f3a61":"getClaimableAmount(address)","e12f670f":"DiscourzeToken()","e13044fb":"changeEth_to_usd(uint256)","e13062c2":"getInvoices(address,uint256[])","e1313dfb":"additionalInfo(uint256)","e13245b1":"getCommunityBallotsEnabled()","e13251b9":"listAssetsFrom(uint256,bytes32,uint256,bool)","e132db41":"checkRate()","e1332ab9":"setParameter(string,string)","e13380e9":"EmClassic()","e133ad53":"extendCost(uint256)","e1345b02":"SMARTGold()","e134c9ff":"shutdownMarket(address,bytes32)","e134e33d":"reason()","e1351c05":"pay_coin()","e1370365":"makeLogFill(address,address,address,address,address,uint256,uint256,uint256,uint256,uint256)","e137047b":"RESELLING_LOCK_UP_PERIOD()","e1376da2":"updateFirstActiveGamble(uint256)","e137cdd9":"totalTokenCreationCap()","e138efb2":"setAllowStart(bool)","e139e569":"getPriceAndTime()","e13a7716":"testReturn()","e13aba48":"testBurn()","e13bd03c":"delCashier(address,address)","e13da09f":"HARJToken(string,uint8,string)","e13dc28b":"testValidTransfers()","e13e2ecf":"dev_issueTo(address,uint256)","e13ec1fa":"RoundChanged(uint256)","e13efb79":"getReferenceHash(bytes32)","e13fafdb":"marketCoins()","e13fe91c":"REALPlaceHolderMock(address,address,address)","e1404b41":"setNewMembers(address,address,uint256,uint256)","e1419546":"makeLiquid()","e1421a45":"makeIntString(string,uint256,string)","e142967e":"addClaim(uint32,int256,string,string,bytes)","e1437b00":"calculateCurrentMarketPixelPrice(address[16])","e143b3a1":"createNewEscrow(address,address,address)","e1444721":"minGoalReached(uint256,string)","e1472d88":"increaseBalance(address)","e1479d07":"megoAddress()","e1479ebe":"is_registered(bytes32)","e1482188":"showCollectedFee()","e1486ea8":"getContest(uint32)","e1489191":"commission()","e148bae9":"assignClientIfNotAssigned(address)","e148fe28":"transferTokensFromReserveAddress(address,uint256)","e1496d16":"TEAM_NAMES(uint256)","e149fbfa":"ShapeshiftBotSolo(string)","e14a147e":"addPokemon(string,address,uint256)","e14acc04":"getCanLoanAmount()","e14b238a":"EITToken()","e14b7571":"stage_3_price()","e14b983e":"LevelToken()","e14c4675":"rateForMainICO()","e14c5e17":"setcreatorAddr(address)","e14ca10e":"oraclizeCallbackGasLimit()","e14df8b7":"subDepotEth(address,uint256)","e14e1ba7":"_getTokenAmountWithReferal(uint256,uint8)","e14e5ca4":"BETHER()","e14ed045":"getContributionOf(address)","e14f680f":"sendAll()","e151fb62":"_updateMetadata(uint256,string)","e153591c":"FairyFarmer()","e1538b32":"gasPayback()","e1539c53":"claim(bytes32,string,string)","e153b74e":"tokenFallback(address,uint48,bytes)","e154179e":"addToTrusted(string)","e1541b7d":"testDiacritcs()","e1541bc3":"setTdeIssuer(address)","e154d17d":"heldTokens(address,uint256)","e155999e":"getFreeCrocs()","e155b66c":"ConvnertToSecret(uint8,string)","e15618b9":"founderWithdrawablePhase4()","e1567997":"kscBatchTransferToBounty(address,address[],uint256[],uint256,uint256[],string)","e1568024":"totalAmountOfCrowdsalePurchasesWithoutBonus()","e1569f6b":"testThrowsSetNotRetractableNotOwner()","e15746af":"TJCUToken(uint256,string,uint8,string)","e157819a":"distributeCOMIKETCOIN(address[],uint256)","e1587aae":"maxFinneyPerSaleLessThan()","e158a24e":"ethTransfertoACC(uint256)","e1590ed7":"mainEtherReceived()","e15a307c":"killAndRefund()","e15cba26":"_pay(bytes32,address,uint256,uint256,uint256)","e15d051f":"adminUnsigned(address)","e15e9d47":"depositFlag(address,uint256,uint256)","e15f3ec2":"Sent(address,address,int256)","e1606013":"issueCert(uint256,bytes)","e160a1d6":"manaPerEth()","e160e146":"createContractToken(string)","e161c3bf":"getPercentage(uint256)","e1621b04":"getDatePosted(uint256)","e163698a":"setTokenForPublicSale(uint256)","e16385fc":"destroyTokens(uint256,address)","e163b75b":"settleBet(bytes20,bytes20,bytes32)","e164483f":"numberOfBlocksToStartGame()","e164ac50":"teamPercent()","e1654fad":"roundIn(uint256,string)","e1661eff":"getClaim(address,address,bytes32)","e1661ff2":"Later(address)","e1662aa6":"saveMsgByUser(string,string)","e166b756":"ownerMethod()","e166bebd":"BINOToken()","e1674588":"getTokenURIs(uint256,bool)","e1675421":"changeFsTKAuthority(address)","e167dbca":"exchangeTokens()","e168a31a":"getOwnedArea(address)","e168ae8a":"_isPreICO()","e168c3ec":"votes()","e16b924d":"sellBonds(uint256,bool)","e16ba8c6":"privateSale1Hardcap()","e16bd3b7":"getSales(address)","e16c7d5e":"signedApprove(address,address,address,uint256,uint256,uint256,bytes,address)","e16c7d98":"getContract(bytes32)","e16c8053":"setTransfer(uint256,uint256)","e16c8d4b":"viewMyShares(bool)","e16c93e5":"Swarm(address,address,uint256)","e16dbb2f":"Multiplication(uint256,uint256)","e16dd936":"getVestingSchedule(address,address)","e16e2843":"setdividendFee(uint8)","e16e9340":"getAddressArrayIndex(bytes32,uint256)","e16e93aa":"DU30Token(string,uint8,string)","e16f374c":"getHarborLocation(uint16,uint16)","e16f5fe9":"DeathFactor_iv()","e16fb2f9":"recordInvestment(address,uint256,uint256)","e16fe580":"CalcHash(bytes)","e1703521":"setPriceMoreThanOneETH(bool)","e170dd81":"MintingSale(address)","e1725c92":"decimalPlaces()","e1726faa":"pushDividendPayment(uint256,uint256,uint256)","e1727807":"splitPot()","e1727fc6":"contractDeployedTime()","e172a57e":"updateGenerationStopTime(uint256,uint8)","e172dac8":"ethOdinRate1()","e173b0d0":"reserveAll()","e17463c2":"changelp5(address)","e174f106":"ManualMigration(address)","e1757a3c":"TIMEOUTBLOCKS()","e1758bd8":"nativeToken()","e175c86a":"getInviteInfo()","e1765073":"getPath(uint256)","e17682eb":"StablePrice(uint8)","e177246e":"setDelay(uint256)","e17755c4":"zrxTokenContract()","e177573c":"setHatchTime(uint64,uint256)","e177644a":"TimeStamp()","e177b18b":"minCoordinatorCount()","e177b707":"Valdela()","e177bb9b":"registerCode(string)","e17928ba":"BOBOTOKEN()","e17a3ccf":"paused_4()","e17a5894":"yoobaTeamAddress()","e17a7c70":"stage3_start()","e17b25af":"setMetadataAddress(address)","e17b3054":"creatorOwner(address)","e17b35ed":"isMint(address)","e17bf87a":"testRewardBB(bytes32)","e17cb777":"rewardRetweet(address)","e17e1274":"testTransferToRejectAuthority()","e17e1a86":"SetupWWC(string,string,uint256,uint256,uint256,address,address,uint256)","e17e7a20":"setTotalStaked(uint256)","e17fc704":"canMintFoundation(uint256)","e17fe6a0":"getCreatorReward()","e17fec26":"Unregistered(bytes32)","e180819e":"setBuyTime(uint256)","e18099e1":"ethTokenRate()","e180dbbd":"isEarlyBird(address,address)","e180e23b":"Annexe_CPS_6()","e182e27a":"fastHatchingPrice()","e182fd01":"tokensBankPartners()","e184c9be":"expiry()","e1851b83":"getMaximumFundsInEuroCents()","e1859169":"communityContributionQuota()","e185a890":"widthdrawRefunds(address)","e185b24c":"emptyIndex(address[])","e1863b19":"MultisigWalletMock(address[],uint256,uint256)","e186fb27":"checkcitizendetails(uint256,string,string,string,string)","e1878925":"isDeregisterable(address)","e187a550":"logCall(uint256,uint256)","e187eaf7":"addMoreTime(uint256,uint16)","e1883433":"withdrawEther(uint64)","e189dba1":"sellIssuerTokens(uint256)","e18a9134":"getLockProducts(uint256)","e18af2b8":"PHPCoin(uint256,string,string)","e18b170e":"tune(uint256,uint256,uint256,uint256,uint256)","e18b7fcf":"receiveFee()","e18c52ae":"testControlTransferNotTransferable()","e18c8cf9":"etherInWei()","e18d38ce":"getPlayerName(address)","e18dc0f6":"pricingStrategyAddress()","e18e34d5":"setPayoutFee(uint256)","e18ed57b":"_calculateTax(uint256)","e18f1355":"TestERC20Token(uint256,string,uint8,string)","e18fb814":"setFixPrice(uint256)","e18fe709":"AirRewardTotalSupply()","e190264f":"newCampaignAccount(uint256)","e1909035":"GetCompetitionResults(uint32,bool)","e190d1b5":"claimFreeCrab()","e1911d70":"METADATA_URL()","e19136a4":"urbitAdminAddress()","e191548d":"AnimecardCore()","e192c4e0":"investor_Refund()","e1938b14":"oraclizeSetWinner()","e193b735":"tokensDonated()","e1948e44":"ethRateExpiration()","e194e369":"getFamedStarByName(string)","e19593e5":"cashout(uint256,address,address,address,uint256,bytes,bytes)","e195d096":"tokenReserved()","e195f2ec":"howManyFees()","e1980d15":"setBuyAuctionAddress(address)","e199b7e4":"getMasterAdress()","e199c8a8":"SafiraToken()","e19a7bc8":"stopMigration()","e19ab767":"totalDistrictSupply()","e19aca85":"takeDividends(address)","e19bb964":"priceIncreasingRatio()","e19bc813":"bonusesCount()","e19bc8e5":"initPrivateIco(uint256,uint256,uint256,uint256,uint256)","e19d36ff":"removeAsset(bytes32,address)","e19eaf79":"blocknumber(address)","e19f1c55":"EstatePurchased(uint256,address,uint256)","e19fb933":"MentalHealthLifeToken(uint256)","e19fd3c5":"determinePurchase()","e1a05087":"getImpactUnmatchedValue(string)","e1a05344":"createSaddle6(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","e1a1cd8d":"crowdfundEndDate()","e1a27ad3":"needsAdministration()","e1a283d6":"mintingPaused()","e1a29a3f":"setVariationAddress(address,address)","e1a2c446":"lockRewardTokenMany(address[])","e1a382f4":"ZTHToken(uint256,string,string,uint8)","e1a3e55c":"buy(string,address)","e1a44749":"setOptions(uint256)","e1a566f4":"challengeExists(string)","e1a57611":"tokenReceivers(uint32)","e1a58a74":"flowerContract()","e1a63c14":"PixelMap()","e1a67cd3":"overrideTokenHolder(address,uint256)","e1a69d88":"level_1_amount()","e1a6ddcd":"isValidContribution()","e1a6df9e":"FLIGHT_NUMBER()","e1a6e625":"TradingStart(uint256)","e1a6f014":"offer(uint256,address,uint256,address,uint256,bool)","e1a7739c":"getExercisePeriodDeadline()","e1a8af8a":"getWinnerPrize(uint256)","e1a9109d":"setSeedPrice(uint256)","e1a9a2b1":"endRound(uint256,uint256)","e1a9f9b9":"_buyCallToClose(uint256,uint256,uint256,uint256,address)","e1aa1098":"GuardaRegistro(string)","e1aa1bcc":"refundDeadline()","e1aa60dc":"lastBlock_v3()","e1aa7e95":"createNewUser(bytes32,bytes,address)","e1ab5860":"declarePublicOfferingPlan(uint256,uint256)","e1ab690e":"ANRToken()","e1ab7cda":"OnetVN()","e1aba68e":"newProposal(address,string)","e1abf819":"GetWinner(bytes32,address,bytes32,address)","e1ac48ad":"saleableTokens()","e1aca6fb":"quickSort(uint256,uint256)","e1ad1162":"transfer(address,uint256,bool)","e1ad7699":"setPayload(string)","e1ad84a0":"GetFixedPrice(uint256)","e1addfbb":"priceOfreservations(address)","e1ae91b3":"TestToken(address,uint256,uint256)","e1af0121":"associationOf(address)","e1af915d":"changeGenes(uint40,uint256)","e1afb08c":"unlock(bytes16)","e1b0d4b2":"setTransactionsAllowed(bool)","e1b27e6b":"COO()","e1b3f338":"undoPending(address)","e1b40a76":"ipfsAddress()","e1b41513":"LIVEToken()","e1b4d6cb":"HOTCRYPTO()","e1b5265a":"PutForExchange(address,uint256)","e1b53078":"makerAffiliateFee()","e1b54285":"endDateOfVipPlacement()","e1b5989d":"FastLoan()","e1b5ce0f":"buy(uint256,string,string)","e1b7535f":"getDepositor()","e1b7abda":"HOST_SHARE()","e1b8347b":"testFundsAreTransferrableAfterSale()","e1b84ac3":"_storeSettingCreation(address,uint8,string,address,address,string)","e1b8708f":"OwnerChanged(address,address,bytes32)","e1b92b21":"LogOmegaEggSale(address,uint256)","e1b9dc08":"setCallbackGasLimit(uint256,uint256)","e1b9dea4":"Globglogabgalab()","e1b9ed9d":"_buyTokens(address,uint256,uint16)","e1ba84a9":"testFallbackThenAdd()","e1baa2a0":"ownerAngelTransfer(address,uint64)","e1baa9cb":"CNT_Common()","e1baed1a":"hireBountyHunter(uint256)","e1bc048e":"clones_to_create_one_idea()","e1bc3003":"reveal(bytes,string)","e1bccc7f":"FccToken()","e1bd5af9":"contractHolderAddress()","e1bdc3c9":"addAddressMappingProposal(address,address)","e1be7467":"bounties()","e1bedf2a":"AlarmTester(address)","e1bf34e9":"transferToKnownContract(address,uint256,bytes32[])","e1bf4f50":"upgradeM5Logic(address)","e1bf50c8":"_transferChamp(address,address,uint256)","e1bfc31e":"acceptOp()","e1c0669d":"getJobSponsorshipId(address,address,uint256)","e1c093da":"getMinerBlock()","e1c1451a":"tokensIssuedMkt()","e1c18c42":"setEarned_money(uint256)","e1c1b939":"verifyTransaction(bytes32,uint256,address,address,uint256,address,address,uint256,bytes,bytes)","e1c33523":"xpaFundDeposit()","e1c3aedc":"updateRewardVaultContract(address)","e1c3bac6":"stakeMaxAge()","e1c3fb91":"_hasClosed()","e1c49dde":"previousRounds()","e1c4a6a6":"getIsRemoved(bytes32)","e1c4c9fe":"remainingReward()","e1c52dc6":"Confirmation(address,bytes32)","e1c5d838":"createOrgan(string)","e1c621c0":"_rewardTokens(address,uint256)","e1c66292":"Create(uint32,address)","e1c68f31":"findFloorKey(uint256)","e1c6b14b":"addToOtherMap(uint256,uint256)","e1c70b29":"_createPow(string,address,uint256,uint256,uint256)","e1c7392a":"init()","e1c7f06a":"AddSharedAccount(bytes32,bytes32,bytes32,address)","e1c80391":"setArtcoin(address,address,address)","e1c941b0":"batchSendWebGiftToken(address[],uint256)","e1c95bb9":"updateThresholdNewTokenPair(uint256)","e1c9ccaa":"ShopalToken()","e1ca1b7d":"FilmoljupciCoin()","e1ca6f6f":"distribute_100_tokens_to_many(address[])","e1ca8b57":"setNewPriceFuncAddress(address)","e1caa0c7":"createAndCall(string,bytes)","e1cb0e52":"getVal()","e1cb5515":"newArticle(string,string,string,address)","e1cba8d2":"TUBECOINcontract()","e1cd5fc0":"PROJECTOPERATION_SUPPLY()","e1cda468":"createRequestFromBytes(bytes)","e1ce95c8":"summon10SkinAppearance(uint256)","e1cf0b3b":"refundAllPlayers()","e1d001eb":"mintAllowance(int256)","e1d03d11":"setUnlockedAddress(address)","e1d07058":"_modifySpendLimit(uint256)","e1d10d85":"getMyTickets()","e1d10f79":"calluseraddress(address)","e1d1e8ef":"getCurrentUnitPrice()","e1d2d3e4":"SocialMedia()","e1d2f649":"restartAuction(uint256,uint256,uint256)","e1d30979":"wolkInc()","e1d35155":"ProudofYourCoin()","e1d4efc4":"YHT()","e1d5988e":"discount(uint256,uint256,uint256,uint256,uint256)","e1d5e8eb":"rollDices(uint256)","e1d5ec4c":"seedShare()","e1d6aceb":"transferWithComment(address,uint256,string)","e1d6e166":"getContracts(address,uint256)","e1d76c8e":"getBlocksByOwnerDesc(uint256,uint256,address)","e1d7ce2c":"EthCentsUpdated(uint256)","e1d7fadc":"disqualifyHopeful(uint256)","e1d81736":"addUser(uint256)","e1d94d94":"ownerChangeSlogan(string)","e1d9627f":"ReputationChanged(address,int32,int32)","e1da4135":"bountyFundAddress()","e1da4f85":"setStartStage2(uint256)","e1da5637":"setPercentWeiJackpot(uint256)","e1dace1a":"rewiewToken()","e1db206c":"limitTier1()","e1db8e7e":"getCreatedPayoutNumerators()","e1db8ff2":"mineForMany(address[],address[],uint8[],bytes32[],bytes32[])","e1dbc281":"changeBank(uint256)","e1dc7792":"OptedOut(address,address)","e1dcafa3":"setDefaultReputationReward(uint256)","e1dcf3de":"NewBooking(address,uint256,uint8,uint256)","e1de02f3":"_exit(address)","e1de373f":"addPlayerName(string)","e1df4517":"WealthChainToken()","e1df507c":"calculateAmounts(uint256)","e1df7f60":"startstopICO(bool)","e1e073b6":"amountTokenIssued()","e1e09299":"addUserRole(address,uint8)","e1e158a5":"MIN_DEPOSIT()","e1e1f977":"parseTx(address[4],uint256[3],uint32[4])","e1e29558":"completeTask(uint256)","e1e2ccd2":"sellDrugs()","e1e3f915":"parameterizer()","e1e46351":"mvpLaunchedAt()","e1e46f24":"tokenRate2()","e1e471eb":"BankingPayToken()","e1e4d737":"setTokenFront(address)","e1e5c093":"controlSum()","e1e7c320":"getGamesPlayerBids(uint256,address)","e1e85c4b":"splitProfit(uint256)","e1e867e5":"getFees(uint256,uint256,address)","e1e87c28":"refundToBuyers()","e1e87f40":"LogDividend(address,uint256,uint256)","e1e87f60":"_getBid(address,uint256,uint256)","e1e902af":"transferToLock(address,uint256,string)","e1e93604":"atomicMatch_(address[14],uint256[14],uint8[6],bytes,bytes,bytes,bytes,bytes,bytes,uint8[2],bytes32[5])","e1e9e249":"encodeAddress(address,address)","e1ea0a57":"TOKKA()","e1ea5e05":"token_fallback(address,address,uint256,bytes)","e1eb5f87":"NewPrice()","e1ebdb6d":"setWhitelistA(address,address)","e1ec12c7":"TopPlayerToken()","e1ed7fcb":"setBagMultiplier(uint256,uint256)","e1eddc6d":"_rand(uint256)","e1ee9284":"getOwnCard(address)","e1ee9a3d":"isPreIcoDate()","e1ef42b1":"Total_Investors()","e1efda6d":"airaSend(address,address,uint256)","e1f0ae1b":"NexoToken()","e1f0c376":"gameDuration()","e1f11822":"carnumOf(address)","e1f16616":"invcoinSentToEther()","e1f21c67":"approve(address,address,uint256)","e1f4895a":"getCostToken()","e1f4a9b1":"set_pre_kyc_bonus_denominator(uint256)","e1f51aca":"listTokenByRank()","e1f5760b":"horsesRemaining(uint256)","e1f57846":"com_fee_transaction(address,address,address,uint256,uint256)","e1f5eb3f":"convertTokens(uint256,address)","e1f5ebc5":"_projectAddNew(address,uint256)","e1f6452e":"AggiungiNegoziante(address,bool)","e1f69952":"voteSvp02(bool)","e1f7d0e1":"PRE_SALE_END()","e1f7ec5a":"getStored()","e1f82d60":"publicReservedToken()","e1f86887":"getPortfolioTable()","e1f87904":"getNextDouble(address)","e1f8922e":"transferName(address,string)","e1f8926b":"depositEthPool(uint256)","e1fa70ef":"endCloseSale()","e1fa7638":"attack(uint256,uint256)","e1fa78e9":"AgriChainLabelInt()","e1fa82d0":"transferFromFlower(address,address,uint256)","e1fa8b02":"distribute(uint256,address)","e1fa8e84":"register(bytes32)","e1fb070e":"MtTaborToken()","e1fbeaed":"CUCUX()","e1fcad6a":"_equipUpOne(address,uint256)","e1fcb86d":"YouTube()","e1fd3d4e":"emergencySetDOwner(bytes32,address)","e1fd632f":"EDU_KYC_BONUS()","e1fdb4b4":"refundBet(uint256)","e1ff98f2":"getTotalCounter()","e1ffdecb":"tokensPerTranche()","e20056e6":"replaceOwner(address,address)","e200cee8":"setBossWannaCryInterface(address)","e201be98":"airDropToken()","e201d466":"MultiToken(uint256,string,uint256,string,string,uint256)","e2021f66":"getAttack(bytes32,bytes32,uint256)","e2022d3a":"storeNewVesting(address,address,address,string,uint256)","e202e1eb":"contractPartOne(uint256)","e20314ed":"trade(uint256[10],address[4],uint256[6],bytes32[4])","e2034834":"RemoveRocketForSale(uint32)","e203f335":"leafPrice()","e2045452":"setUsername(address,string)","e2045b5e":"getBadgeInfo(uint256)","e2047589":"assertEq(address,address,bytes32)","e204ce12":"transferExtra(address,uint256,uint256)","e2056c46":"ExtraBalToken()","e2059fdf":"showIssueDetail(address,bytes32)","e2069734":"destroyRemainingTokens()","e2087a44":"receiveApprovalTest(address,uint256,address,bytes)","e209bf22":"addMeme(string,string)","e20a4bcd":"recoverAddressFromCooperativeSettleSignature(bytes32,address,uint256,address,uint256,bytes)","e20a5ac2":"bonusFourthWeekPeriod()","e20a9ae9":"Tesoro()","e20acc79":"changeInterval()","e20b7d3c":"checkPoolAddressTierCap(uint8,uint256)","e20bbd8d":"RecoveryWithTenant()","e20bc67b":"autoUnlock(address)","e20bce0a":"lowTimeBonusValue()","e20c6d3d":"getMessageData()","e20ccec3":"pending()","e20cfc4a":"payedDividendsUSD()","e20d35ad":"CellBlocksToken()","e20dc05b":"globalOperator()","e20de6eb":"addrLockedFunds()","e20e1dc3":"createProxy(address[],uint256)","e20e36a0":"ExchangeAdapterBase(address,address)","e20e54a5":"getMHTHoldersNumber()","e20ff6f7":"fetchCurrentSatoshiState()","e2101509":"getSketchesWithHolder(address)","e211003d":"processOffChainPurchase(address,uint256)","e2119c80":"computeRealCap(uint256,uint256)","e2121de1":"withdrawAny()","e2130d1e":"unlockTeamTokens()","e21316ea":"mortal(address)","e213beb7":"transferCoOwnership(address)","e213e10a":"_createMeme(uint256,string,address,uint256)","e2153231":"SahilToken()","e2155c14":"galleassMint(address,uint256)","e21608be":"ReserveToken()","e2164700":"currentRewardNum()","e216bf4d":"SetBlockForSale(uint256,uint256,uint256,address)","e2172000":"left63(uint256)","e2179b8e":"g()","e21827a1":"unmintedTokens()","e218519c":"getref()","e2187e6e":"endTimeLockedTokensTeam()","e2188190":"CROWD_WAVE3_PERIOD()","e219aa11":"GetEscrowETHBalance()","e219b9e1":"rebateOneFenmu_()","e21a430b":"publicRelease()","e21aaa0f":"_getShipPrice(uint256,uint256)","e21ac8a1":"AvatechToken()","e21b0b95":"updateGlobalMinContribution(uint256)","e21b63b2":"setNewMint()","e21b9d08":"m_changeable()","e21be4f4":"CBMTToken()","e21c4783":"isPermitted(address,bytes32)","e21e221b":"ContributionRegistration(address)","e21f37ce":"message()","e21f44f4":"PoolCreated(uint8,uint256,uint256)","e21f8e56":"get_game_fees()","e21fd9fc":"_owns(address,uint256)","e2202a4d":"jester()","e2211592":"TWO_DAYS()","e2217114":"forwardEther(uint256)","e2217d5c":"payeth()","e2219773":"webGiftOnceMaxAmount()","e221d5d5":"getDukeNickName(string)","e222b00c":"blocksPerPayPeriod()","e22325ad":"transferBase(bytes32,address)","e2233ada":"smartDoor(address[])","e223b547":"calcFixedReward(uint256)","e223cb37":"AddBill(uint256,uint256,uint256,bool)","e223ed87":"getPetValue(uint256)","e223facb":"USER_GAME_WITH_TOKEN(uint256)","e224179e":"icoOverride()","e22497e4":"removeFromPublicSaleWhitelist(address[])","e225c56b":"KudosToken()","e225e588":"TNCN()","e226a1b6":"getAddressStatus(address)","e226cdec":"sellOffline(address,address,uint256)","e226ed22":"balanceOfERC20(uint256,address)","e227b5d1":"ETHContributed(address)","e228647f":"olty_6()","e228a6f4":"withdraw(uint256,uint8,uint16)","e228d627":"nextTokenAddress()","e228ecb4":"lockBalance()","e22938bd":"ShareManager()","e22955c6":"MultiplyContract(address,uint256,uint256,uint256,uint256,uint256)","e2298591":"xIPFSPublicKey()","e22a3af8":"canClaimTokens()","e22a6231":"addCandidate(address,string,string)","e22a9877":"getHWCAddress(address)","e22aa47a":"lockTokensForCs(address,address,address)","e22ad518":"startNextPremiumSale()","e22ae31d":"FrameCoin()","e22b0c46":"verify(uint256,uint256,uint8,bytes,bytes)","e22b3fb4":"changeOwner(bytes)","e22b94e8":"ForceCryptoInvestmentCoin()","e22baa56":"nonZero(uint256)","e22bda35":"eventVenue()","e22c6128":"getIncome(address)","e22d1581":"saleEnd2()","e22e8046":"getLunckyIndex()","e22ed995":"createStudent(string,string,string,uint32,bytes1)","e22f8dc9":"buy_lovelock(string,string,string,uint256)","e22fb860":"CJXToken()","e22fcd08":"useItems(uint32,uint256,address,uint256)","e23000a0":"buyBackPrice()","e2301d02":"subApproval(address,uint256)","e2306253":"o1Address()","e230dfbd":"setETHUSD(uint256)","e230e246":"cutFor(address,uint256,uint256,uint256)","e2311a78":"Payperblock()","e2313d1f":"ClaimOrichalcum()","e231bff0":"redeemed()","e2322c73":"firstPeriodWindows()","e2326909":"addCourse(string,string,string,uint256,uint8,uint8,uint16,uint8,uint8)","e2331332":"AortaToken()","e2332120":"secondUnlockTime()","e233ee0d":"publicFillOrder(bytes32,uint256,bytes32)","e2356efd":"holdTokensOnStage()","e235847a":"addSourceForTimeline(uint256,uint256,string,bool)","e235ca59":"revealsCount(uint256)","e236de22":"distributorWallet()","e2376be1":"sendMon(address,address,uint64)","e2387bb6":"AuctionHouse()","e238c7ed":"setAllowanceAdmin(address,address,uint256)","e238def9":"getReleasedBalance()","e23941bc":"testDepositWithdraw()","e239421d":"Lotthereum(uint256,uint256,uint256,uint256,bytes32)","e239ccba":"Disco()","e23a15b5":"logSigned(string,bytes16)","e23a4916":"getMainLockup()","e23a7785":"approveAndBuy(uint256,address,uint256,bool)","e23a845a":"getExpirationTime()","e23c5063":"getAttributeValue(address,bytes32)","e23caa06":"getLotteryDetailsA(int256)","e23cbad1":"getArkData(uint256)","e23d0996":"getDBallotID(bytes32,uint256)","e23d0b23":"week2Price()","e23da75a":"setTokenApproval(uint256,address)","e23e231f":"TOKENS_NOT_FOR_SALE()","e23e3229":"investorIndex()","e23eaae6":"SmogToken()","e23eb0c5":"_calculateFEE2Distribute()","e23f5e49":"checkLucky(address,uint256,uint256)","e23f61f6":"isCurrentOrPastAdmin(address,address)","e23fc908":"_setBurnFeeAbs(uint256)","e2418c15":"throwsWhenNetworkPlaceholderIsBad()","e241c1d9":"deriveKey(uint256,uint256,uint256)","e241e9c5":"_getUt(address)","e2420bd2":"setTwitterBot(address)","e242df57":"MiracleTeleToken(uint256)","e242fbbb":"addHuman(string,uint8)","e244054a":"trade(bool,bytes,uint256,uint256)","e2442441":"VpaxContract()","e24459ce":"rakugoPresaleAddress()","e2449c13":"createSqr(uint256,address,uint256,uint256)","e244fe89":"addToCommunitySaleWhitelist(address[])","e2454522":"verify(uint8,bytes32,bytes32)","e2457f50":"changeZS(address,address,uint256,uint256)","e24613ea":"getNexOrdertUser(address,address,uint256,address)","e2466cb6":"invalidateAnnouncement(uint256)","e24670eb":"EthToCentsUpdated(uint256)","e246ddba":"icoFinishTime()","e246f71a":"EventAddManager(address,address)","e247a2e2":"updateVolume(uint256)","e248b435":"setCCH_edit_15(string)","e2496d5b":"tokensWeiRaised()","e2499b98":"stakedContentById(bytes32)","e249a575":"setTermsNumber(uint256)","e24a1d1e":"deauthoriseMaker(address)","e24a5042":"transmuted(uint256)","e24b4403":"_emitDeposited(address,uint256,address)","e24b7721":"addressLeskiw()","e24c36d0":"flushEra()","e24cddd6":"getCartLength(address)","e24cf226":"closeEscrow(uint256)","e24f8313":"addReputation(address,uint256)","e24fe110":"Decentralized()","e24fed00":"assertEq(bytes,bytes,string)","e2506eab":"setEMAValue(uint256)","e250ecfe":"Cogenero(uint256,uint256,uint256,address)","e251e358":"preIcoSoftCap()","e25209b6":"roundOneLimit()","e253c21d":"ZBCToken()","e253dd6b":"setBonusRound4(uint256)","e2542f03":"updatePurchasePossible(bool)","e2550156":"smallBlind()","e25520a7":"LocklistAddressdisable(address)","e2558086":"calculateLandmarkPrice(uint256)","e255d5ad":"maxBuyRateInPrecision()","e25665da":"earlyBackersPoolAddress()","e256888f":"PERCENTAGE_PRECISION()","e2573266":"withdrawRC()","e2575e48":"_isMultiple(uint256)","e2576998":"changeMaxCoefPartnerForEmission(uint256)","e2583070":"balanceImportsComplete()","e25876d3":"weiToFinney(uint256)","e258a0f0":"createItem(string,uint256,uint256,uint256[6])","e258aa02":"createPromoRegion(address,string,uint256)","e258be32":"removeBookSigner(bytes16,address)","e259501e":"contributorsWallet()","e2595235":"addPack(uint8,uint128,uint256)","e259d074":"endauctionother(uint256)","e25a2a99":"updateTier(uint256,uint256,uint256)","e25a51b6":"setCompositeReputation(string,uint32)","e25ade5f":"issueTokens(address,uint256,uint256,bool)","e25b5cbd":"STAKE_APR()","e25bc771":"_transferCard(address,uint256,uint256)","e25bd409":"receivePositionOwnership(address,bytes32)","e25c80d0":"_currentIcoPhaseMinimum()","e25c9c33":"getBadgeLevel(bytes32,uint256)","e25d4dac":"mintFund(address,uint256)","e25f0a98":"requestedForMigrationAt()","e25fe175":"step()","e2616387":"MPY(uint256,uint256)","e26176d9":"FundRanking(address)","e261fc63":"UserRank(address)","e2621a66":"HPBToken(address)","e26259a4":"updateMyHns(string,address)","e264172c":"drainETH()","e26422fe":"DaysToDestroy()","e2646a9f":"getICOStage()","e2649caf":"voteToFreezeFund()","e264a2f4":"KIN_PER_USD()","e264fc07":"_buyFillet(address,uint256,bytes)","e2651539":"priceCreatingChannel()","e26534bf":"whaleExchangeRate()","e2659324":"require_email(bool)","e265c5e2":"getTotalTokenWithdrawByAddress(address)","e2664254":"priceDivisor(uint256,uint256)","e26659da":"getAllBaller()","e26693ac":"stakeDice()","e266e5ad":"Mystical()","e267761f":"unmintedGBT()","e267dd9b":"addAgent(uint256,uint256,uint256,address)","e26814d8":"withdrawCoins(address,uint256)","e26835ce":"giveToken(address)","e2684f08":"_isPaused()","e268ea6b":"SOFT_CAP_T()","e269053a":"getNumberOfAssets()","e2693180":"DHANACOIN()","e269f929":"recoverRevokeHash(bytes,bytes,uint256)","e26a687f":"BP_IMMORTAL()","e26ba086":"getTargetInvalidMarketsDivisor()","e26bc039":"numRegisteredModules()","e26c2da9":"TerraToken()","e26c551e":"publishConditions(string)","e26c8434":"AdminStartDraw(string,bytes)","e26dee0e":"IcoExt()","e26e7b50":"calculateCritMassRewards(uint256)","e26e8d84":"FillSellOrder(address,address,uint256,uint256,uint256,uint256,uint256)","e26f0342":"ArrayTypesTest(uint256[10])","e26f21bf":"setHoldPercentage(uint256)","e26fdc12":"equipDown(uint256)","e27008c2":"_createRareCard(address,uint256,uint256,uint256,uint256)","e270398a":"emitJobPosted(uint256,address,uint256,uint256,uint256,bytes32,bool)","e270bc81":"resumeICO(address)","e270f88c":"_getFreezeTime(uint256)","e27131f9":"MintCoin()","e2725161":"calculateOdds(uint8)","e2726e94":"minSumICOStage4USD()","e272b892":"pauseContract(bool)","e2734c93":"getPlayerBalance(address)","e273f117":"SetServiceProviderFee(address,uint256)","e2749799":"GBank(uint256)","e274a3e7":"Papergold()","e274fa4e":"BitcoinXL()","e274fd24":"eventContract()","e2757a50":"PepFarmer()","e275a016":"check_data(string)","e275f296":"transferFromMulti(address[],address[],uint256[])","e27671ff":"hillpayout()","e276729d":"getPeriodStarted(uint256)","e276c799":"getx()","e2775da5":"getMartialOwner()","e2776ab8":"CryptoPhoenixes(address)","e2786d65":"refundSplitMembers()","e278c0f2":"setInvestorsFee(uint256)","e278d283":"getLineUpEnable_pool(address)","e278fe6f":"closeRound()","e2790853":"OX()","e27929b6":"addRecord(bytes32,string,string)","e27a8aca":"addWhiteListedInvestor(address,string)","e27a9c74":"setOwnerName(uint256,string)","e27b73f0":"issueWithExternalFoundation(address,uint256,bytes32)","e27c5b17":"testSlice()","e27da9c6":"current_tier()","e27e3fd3":"CancelGame()","e27ecfcc":"LogStartDate(uint256,uint256)","e27f0236":"agingBalanceOf(address,uint256)","e27f1692":"Bitsonatoken()","e27f3853":"timeFreezeTeamTokens()","e27fe50f":"startAuctions(bytes32[])","e280b58f":"tokenIssuedLockUp()","e280d66b":"updateWonNums(uint256,uint256)","e2812256":"Monarch()","e281d7e4":"CryptoSlotsGame()","e282348c":"w_Founders()","e282726b":"reserveAddr()","e282938d":"founderLockEndTime()","e282969e":"getPerson(uint256,bool)","e282cda6":"calculateBucketId(bytes32[])","e283d1ec":"registerEscrow(string,string)","e2842d79":"getAllUsers()","e28435c4":"ownerETHCashout(address)","e284cbfa":"getAllAdIdsByCat(uint256)","e2861c8d":"cashOutProfit()","e2865b4d":"growCost()","e2868c54":"Airdrop2(uint256)","e2869853":"RefID(string,string)","e2869f70":"setCrowdsaleAndVesting(address,address,address)","e2877e04":"transferFactoryResourceAmount(uint16,address,uint256)","e287adf4":"addSig(address,bytes32)","e2889c82":"setTimeLimit(uint256)","e2894a8a":"OwnerAnnounce(string)","e2896598":"leaderTimestamp()","e289fcb6":"contractActive()","e28a5e63":"sellDeadline1()","e28ab336":"MAX_INVEST_SHARE()","e28b0d9a":"updateFundingEndBlock(uint256)","e28b2b76":"ipoPlatform()","e28b7555":"CapiterContract()","e28d717b":"transferETH()","e28d8c4b":"claimBonusTokens()","e28deda5":"sweepTokenAmount(address,uint256)","e28e6b3a":"masterTotalEarning()","e28fa27d":"setHardcap(uint256)","e28fed1e":"userRescues(address)","e29121de":"ADVISOR_TOKENS()","e2912367":"_getValuePartByPercent(uint256,uint256)","e292c740":"setLargeInvestorWei(uint256)","e2935edb":"getUpgradeCardList(address)","e2948c21":"marketingTeamTokens()","e29532c1":"getDataFromCode(string)","e2954a14":"purchaseSeconds()","e29581aa":"getNodes()","e2958974":"read_transfer_config()","e295c9d6":"getActiveBanners()","e297273a":"getBlockHashOrZero(uint256)","e298287f":"senderAddressIsSecretContract(address)","e2982c21":"payments(address)","e2985596":"angelCardDataContract()","e298d85c":"discountBlock()","e2996879":"HuoNiu()","e299beb3":"SimpleIndex()","e29a2e89":"publishMessage(string,string,string)","e29a82d3":"BigFishRoll()","e29bfe13":"submitWithdrawTransaction(address,uint256)","e29c6a7b":"addYearToken()","e29caee2":"currentStageTokensRate()","e29e1345":"amountPerDay()","e29e1864":"PresaleCapChanged(address,uint256)","e29e3a4c":"artistsArtworkCount()","e29e436a":"setWorldCupTeamDesc(uint256,string)","e29eb836":"totalCollected()","e29f5182":"byte32ToString(bytes32)","e29f610d":"end1Timestamp()","e29f99f0":"tokenAdd()","e29f9da6":"_getrand09()","e29fa4b4":"setOriginalOwner(uint256,address,address)","e29fb547":"scheduleCall(bytes4,uint256,uint256,uint8,uint256)","e2a034dd":"participantsFirst(uint256)","e2a0d56d":"FundsBurned(uint256)","e2a27ca8":"_setBorderValue14(uint256)","e2a288c0":"placeCoin(uint16,uint16)","e2a2adc2":"divisionRoundedUp(uint256,uint256)","e2a3382f":"holdedOf(address)","e2a376ec":"addContributor(address,uint256,uint256,uint256,uint256)","e2a38a4b":"removeTokens(address,address,uint256)","e2a4853a":"setUint(bytes32,uint256)","e2a51b8f":"amountOfParticipants()","e2a5c39f":"revealPeriodStartedTimestamp(bytes32)","e2a71f12":"accountDelete()","e2a8215b":"purchaseTokens(address,uint256,address)","e2a9ba05":"getBoosterDuration(uint256)","e2a9bb53":"CreateBattleCards(uint256,uint256,uint256,uint256,uint256,uint256,uint256,bool)","e2a9ca4c":"disableTokenTransfer()","e2aa2dcf":"CryptoPeopleName()","e2aa6003":"gameResult(uint256,uint256,uint256,bool,uint256,uint256)","e2aa6c66":"createPasswordChallenge(bytes20,bytes32)","e2aa99ab":"startCrowdsaleY2(address)","e2ab691d":"lock(address,uint256,uint256)","e2acf75d":"auctionCancel(bytes32)","e2ad0699":"addCertification(address,bytes32,bytes,bytes32)","e2ae0c79":"setParentID(uint256,uint16)","e2ae9de0":"deleteArrayUint(bytes32,uint256)","e2b05077":"getSaleDate(bytes,uint256)","e2b0caef":"when()","e2b13fa0":"ManagerPermissionRevokedEvent(address,string)","e2b178a0":"getAuthority()","e2b202bf":"deleteUint(bytes32)","e2b20a72":"SecretToken()","e2b2579b":"isClean(address)","e2b26323":"proceedToNewStage(int256)","e2b375a9":"transferOwnership2(address)","e2b43e23":"setDepositInterface(address)","e2b4b30d":"getvaluejoinlist_odd(uint256)","e2b4f4b5":"lockedTeamUFT()","e2b770b4":"updateUSDMonthlySalaries(address,uint256,uint256)","e2b7713f":"Midel()","e2b863cf":"calculatePayout(bytes32,uint256)","e2b8766c":"testFailTransferNotTransferable()","e2b91318":"createOptionAndUnderwrite(bool,address,uint128,uint128,address,uint64,uint256)","e2b9e186":"name_()","e2b9e322":"bondsOutstanding(address)","e2ba53f0":"winnerName()","e2ba600e":"starting_giveaway()","e2ba6ce8":"m_KYCProvider()","e2bbb158":"deposit(uint256,uint256)","e2bc1971":"getGamblerGameIds(address)","e2bca77e":"calculatePrizeAmount(uint256,uint256,uint256)","e2bd505b":"setTitulaire_Compte_2(uint256)","e2bd8e43":"CodysToken()","e2c03ace":"itemsCount()","e2c14bdd":"getMapping(bytes32)","e2c1f02c":"buySuperDragon()","e2c1f7d7":"firstCapEndingBlock()","e2c20836":"updateAndGetHodlTotalValue()","e2c2ae5a":"isBuyPrice(uint16)","e2c2d72c":"setChallengeScienceContract(address)","e2c31be6":"icssale(address)","e2c345e2":"originalContract()","e2c38eaf":"findProductIndexById(uint256)","e2c3941a":"DOG_Token()","e2c3f9a8":"RATE_PUBLIC_SALE()","e2c41dbc":"depositFunds()","e2c516be":"icoReceivedWei()","e2c518fa":"lastMovement(address)","e2c5449e":"chanceNo()","e2c61114":"setImportFee(address,uint256)","e2c6d41c":"council()","e2c718d8":"right20(uint256)","e2c76bb0":"SpeculateCoin()","e2c7f7ae":"majorOwnerShares()","e2c86092":"ifoodCommunity()","e2c8a8ad":"contributorPoolMintQuota()","e2c8dd34":"dividendsWallet()","e2c8e54a":"senderIsPosition(address,address)","e2c8f7c8":"ARIWallet()","e2c92a52":"distribute(address,uint256,uint256)","e2c9b07d":"ChangeBillLeasingInfo(uint256,uint256,uint256,bool)","e2c9bc9e":"GenesisTransfersCount()","e2ca01f0":"addNewOrUpdateHolder(uint256,bytes32,bytes32,bytes32)","e2ca481c":"swaps(address,bytes20)","e2cbb9b7":"evCreatedToken(address,uint256,address,uint256)","e2cc20bd":"dealerHit()","e2cc7a51":"signingPrefix()","e2cdd42a":"vote(uint256,address,bool)","e2ce7e67":"read_i16_array()","e2cf8b0d":"createBundle()","e2d07a33":"QYKToken()","e2d0d519":"sendOwnership(address,uint256)","e2d17ab1":"checkGoals()","e2d1da31":"createBuildingOmni(uint32,uint8,uint8,uint8,uint8,uint8,address,bool)","e2d2a868":"autoRefundCrowdsaleContributor(address)","e2d2dcca":"removeMemberAcct(address)","e2d2e219":"dividendsPerShare()","e2d31df4":"getTeamPerfitAmuont()","e2d45f7b":"transferMultipleDelegated(address,address[],uint256[],uint256,uint256,uint256,bytes)","e2d56060":"balanceInWei()","e2d5d11b":"revealCap(uint256,uint256)","e2d6eddc":"get_row_col(uint256,uint256,uint256)","e2d7a7c0":"setAttrCustom(uint256,uint256,uint256,uint256)","e2d7c64c":"darknodeRegisteredAt(address)","e2d84e23":"getLink()","e2daeb9c":"NICTO()","e2dbbf62":"changeIcoDiscountLevels(uint256,uint256)","e2dc35e0":"transferFund(address,uint256)","e2dc5da5":"finishMintingTokens()","e2dc7763":"freeze(address[],bool)","e2dc9aa1":"addTransaction(string,uint64,string)","e2dea715":"getMinerId(address)","e2deaa81":"set_reference(uint256,uint256,uint256)","e2deb962":"signUp(uint256,bytes32)","e2dede94":"getNode(uint256,uint256)","e2df0463":"changeTrancheAdmin(address)","e2df15d6":"setRewardClosed(uint256)","e2df20d1":"setAvailable(bool)","e2df2472":"Aurum()","e2df6c6f":"getBonus3(uint256)","e2e0c049":"UpdateSellAgent(address)","e2e15f2e":"Reward()","e2e1ff4d":"getBallotsNum(address)","e2e267fc":"SintToken(uint256)","e2e29ffe":"assertThat(bool)","e2e2e5cf":"UpdateMinBalance(uint256)","e2e39498":"_verifySignature(bytes,bytes,bytes)","e2e51348":"LogContractCreated(address,uint256)","e2e54288":"getCertificationList(bytes32,bytes32)","e2e5bd42":"setBetBasic(uint256)","e2e5fade":"presaleSales()","e2e616bb":"whiteListEnabled()","e2e68372":"IAM_PER_ETH_PRE_SALE_RATE()","e2e686d0":"safeAdd32(uint32,uint32)","e2e71098":"_FCTOKEN(uint256,string,uint8,string)","e2e794c3":"setPremiumMultiplier(uint8)","e2e79a02":"level2(address,address)","e2e7ab3a":"setEthlanceInvoiceContract(address)","e2e831cf":"genders(uint8)","e2e8b978":"sizeOfUint(uint16)","e2e9e6e8":"updateMaxMinComparables(uint256,uint256,uint256)","e2eb3336":"_performPurchase(uint256,uint256,address,uint256,address)","e2eb91cc":"removeAddressFromOwners(address)","e2ec6ec3":"addAddressesToWhitelist(address[])","e2ecb311":"createEscrow(address,uint256,uint256)","e2ecef03":"boleno()","e2edfc20":"collectAirDropTokenBack(uint256)","e2ee2e89":"isPlayerInRound(uint256,address)","e2ee9941":"tap(bytes20)","e2ef9241":"FawnCoin()","e2f0a05a":"TokenCLC(uint256,string,uint8,string)","e2f1d298":"_addGroupToMember(address,bytes32)","e2f23224":"isEnableBuySell()","e2f273bd":"updateAdmin(address)","e2f2eb27":"NUMBER_OF_BOOSTERS()","e2f31829":"updateStatus(uint256,uint256)","e2f35f17":"teamAccountAddress()","e2f36034":"calculateRevenueAtBlock(uint256)","e2f45eba":"PrettyGirl(uint256,string,string)","e2f60706":"specialPurchase()","e2f60c26":"getMintAuditApproval(address,address)","e2f779f3":"withdrawTokensFromCustody(address,uint256,address,address)","e2f77ae2":"setPriceInExoTokens(uint256,uint32)","e2f8a017":"payInstallment(uint256)","e2f8b790":"buyBlueStarEgg(uint256,uint16)","e2f8fa16":"getPendingTaxData()","e2f8feb2":"internal_tester(int256)","e2f90632":"notTooLongSinceUpdated()","e2fa5398":"pack(uint16,uint64,uint64)","e2fa5fb1":"secondDiscountCap()","e2fa6f90":"_removeTokenFromOwnersList(address,uint256)","e2fa9ee0":"openShop(uint256)","e2faf044":"createDAO(address,uint256,uint256,uint256)","e2fb3d4a":"setReferralSmartContract(address)","e2fc2691":"upvotePost(bytes32)","e2fc421d":"crowdsaleStartTime()","e2fc5d19":"setConfirmations(bytes32,bool,bool)","e2fc6f68":"beneficiaryBalance()","e2fd38e9":"startEvent()","e2fd3c08":"OmVPNToken()","e2fdcc17":"escrow()","e2fdf807":"purchasableTokens()","e2fecdf3":"copy(bytes,uint256,uint256,uint256)","e2ffe3f3":"storageToUint(string)","e3004b57":"depositToken(address,bytes)","e30081a0":"setAddress(address)","e3038aaf":"calcOrderToMsAmount(uint256)","e303a92b":"drawLottery(uint256)","e303cccd":"sellKun(uint256)","e303e81e":"authorizeForTier(uint256,address[])","e30443bc":"setBalance(address,uint256)","e3049b6f":"getFighters(uint32)","e3049ded":"AllyNetworkToken()","e305044f":"disableServiceMode()","e3059cef":"recover(uint8,bytes32,bytes32,address)","e305c210":"getPositionFromBattleboard(uint16,uint8)","e30637d6":"REFF_TOKENS()","e30651b4":"COMMUNITY_CAPPED_VALUE()","e3069e4d":"HTX()","e306f779":"EIP712_DOMAIN_HASH()","e308262a":"kycPassed(address,address)","e3083fb5":"removeFromContribution(uint256)","e308700f":"thresholdEtherLimitForSeedRound()","e308c213":"getBag(uint256)","e30922fc":"isGameLocked(address)","e309396b":"addSchema(string,string)","e3098986":"totalSold_()","e309aa15":"RefundSent(address,uint256)","e309d1b5":"tierTwoRate()","e309f318":"spermlordAddress()","e30addb4":"set_property_layout(uint256,string,string,string)","e30b407e":"payWinningGladiator(uint256,uint256)","e30bd740":"reverse(address)","e30c36f1":"bubbleSort(uint256[])","e30c3978":"pendingOwner()","e30c7b0a":"TronXtended(uint256,uint256)","e30ca7cb":"getBalanceOfContractInSzabo()","e30cfa40":"isExecuted(uint256,uint256)","e30dd27a":"EpsBonus()","e30dfb94":"callAndFailWithoutReason()","e30e3334":"BonusTokens()","e30f4e2b":"addMultipleAddressesToWhitelist(address[])","e30f4f84":"addWhiteBacker(address)","e30f7c8b":"startAirdrop(address[],uint256)","e30fe37a":"setQueryAddress(address)","e310c2ca":"emissionPay(uint256)","e312e00f":"approve(address,uint256,bytes,string)","e3140c51":"PCHAIN()","e31418be":"rateMap(uint256)","e31430c0":"acceptEscrow(address,address,uint256)","e314d852":"mintWithMemo(string,address,uint256)","e3153827":"reading_card_reversed_at(uint8)","e316bd56":"hashMsg(bytes32,address,bytes32,address,uint256,bytes32,string)","e316e9c0":"Issue(uint256,address,uint256,uint256)","e31743d7":"setTransferBlocked(bool)","e31870dc":"mlDevelopers()","e318a74c":"RACEFORETH()","e318b52b":"swapOwner(address,address,address)","e318de73":"getString(address,bytes32)","e3199044":"setGoalsPlayed(uint256,uint256,uint256,bool)","e319b0e2":"advisorsUnlockedAfterCliff()","e31a0292":"getostToken()","e31a7c01":"triggerTransfer(address,address,uint256)","e31a8116":"getMinPrice()","e31a9d92":"lastID()","e31b1aae":"ChangeInterest(uint256,uint256,uint256,bool)","e31bfa00":"next_id()","e31c60e3":"Request(address,uint256)","e31c71c4":"safeToSub(uint256,uint256)","e31d3460":"addused(uint256)","e31d3938":"MINT_INTERVAL_SEC()","e31e0c46":"set_end_block(uint256)","e31e2d6d":"func_0A93()","e31e450d":"checkBoard(uint256)","e31f28ef":"getTransferInfoTime(address,uint256)","e31f3e0c":"startUpgradePoll(address)","e31f4263":"theCamp()","e31ff6c2":"recordOffChainContribute(uint256,address,uint256)","e3206975":"bet_MAX()","e321045a":"_storeSettingDeprecation(uint256,address,address,address,uint256,address)","e321192b":"addTransaction(address,uint256,uint256,string,bytes)","e3218219":"DungeonTokenAuction(uint256)","e321adb3":"_canTransfer(uint256,address)","e3224ac3":"piecesOwned(address)","e32381b6":"kscMintTo(address,uint256,string)","e32497c4":"getArtefactsIds()","e3252a76":"oraclize_randomDS_proofVerify__sessionKeyValidity(bytes,uint256)","e32540b4":"OptionTransfer(address,address,uint256,uint256)","e3256429":"COMPANY_RESERVE_FOR()","e325fb4b":"bonusCap()","e326acbf":"uintFloor(uint256,uint256,uint256)","e326e6ad":"DEFAULT_PRESALES_DURATION()","e32754a0":"MyFreeCoin112(uint256,string,uint8,string)","e327a46f":"breakdown(uint256)","e3280126":"addOrder(string,bool)","e328cc5c":"getActiveArbiters()","e328ef67":"INDInflationVesting()","e3296684":"transferToPie(uint256)","e329e871":"endTime1()","e32a29bb":"burnClosedTokenMultiple(bytes32[])","e32aa56a":"acceptLastMilestone(bytes32)","e32ae93b":"getQueueOpening()","e32af410":"CSClosed(bool)","e32b349a":"JCB()","e32b6325":"releaseForIco(address,uint256)","e32c5f01":"managePID(uint256,uint256)","e32c65f2":"tokensPerWei15()","e32cb7fc":"decimalPlace()","e32d264e":"addDefaultOperatorByTranche(bytes32,address)","e32d5cf8":"setApprovals(address,address,uint256)","e32d76de":"validBeneficiary(address)","e32e68ec":"isNewSchool(uint256)","e32e9f22":"setDeploymentReward(uint256)","e32ecd18":"LEXT()","e32ef3c5":"refereesCount(address)","e33051dd":"setGasPriceLimit(address)","e3306a6f":"CurrentStatus()","e330a737":"setCrowdsaleCloseTimerFor(uint256)","e332dfe9":"Token0901(uint256,string,string)","e3343501":"_playRealOdds(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","e3349637":"addshop(uint256,string,string,string)","e334cd92":"getAstrosLength()","e334f32e":"encodeString(string)","e3350d7c":"setValidKYC()","e3353f3e":"increaseBlockTarget()","e335b5e9":"allocateSupply()","e335e1f8":"LogFundsLocked(address,uint256,uint256)","e33607da":"saleMarket()","e336e01d":"saleQuantity()","e33734fd":"changeProposalDeposit(uint256)","e337db6e":"NANJCOIN()","e337dd35":"SendingBounty(bytes32,uint256)","e337eca6":"TalkBounty(bytes32)","e3380b7e":"joinPillarCore(uint256,uint256,uint8)","e3386a98":"trustedToken()","e338a490":"DEVELOPER_FEE_FRAC_BOT()","e3393a6d":"voting(string)","e3396d2f":"updatePlayersCoin(address)","e339886c":"ADDR_WITHDRAWAL1()","e3399538":"ArithValue()","e33a9ab7":"createOffer(uint16,uint256)","e33b7de3":"totalReleased()","e33b8707":"append(uint256)","e33ba574":"hashSecret(bool,bytes32)","e33bb62a":"BRDCoin()","e33c7ae2":"scheduleTransaction(uint256,uint256,bytes)","e33c9755":"getActionIds(bool,bool,bool)","e33d27e4":"complete_sell_exchange(uint256)","e33d28d7":"vestBalanceOf(address)","e33dafbf":"emitters(bytes4)","e33e59d8":"getInsuranceContracts()","e33e5c5e":"getAddressUInt8(bytes32,bytes32)","e33f6aaf":"getOnBurnAmountValue()","e3407276":"bigModExp(uint256[6])","e340c2fb":"bidETHIncrement()","e340d0d6":"renewDec(uint256,uint256)","e3419202":"redits()","e342c2e6":"investorWhiteList()","e343fea6":"contractPays()","e344606b":"hashtagCommission()","e34486f8":"isActivePoll()","e344ce6b":"updateWhiteLists(address[],bool[])","e3450e13":"lastPlayer()","e34514ba":"getVirtualBalance(address)","e345514c":"CreateTokenToTax(address,uint256)","e345f098":"showLastBidder()","e34639cb":"AllocatedCappedCrowdsale(uint256,address,address,uint256,uint256,uint256,uint256,address,address,address,address,uint256)","e3464b1b":"Drop()","e346b380":"totalPreSale()","e346f79e":"submitTokens(address)","e3470882":"markFirstSaleComplete()","e347a773":"shares(bytes32,bytes32)","e3489a4f":"setII_R1(uint256)","e3495569":"MAX_DISCOUNT()","e3499381":"checkPlayerPayout(address)","e349c313":"addPlayerToBoard(bytes32,bytes32)","e349c7df":"settleUncle(bytes32,bytes32)","e349cb12":"change_name(string)","e349f108":"jokerAddress()","e34a90a7":"distributeBounty()","e34ac873":"avatarTransferState()","e34ad653":"EmissiveToken(address,string,uint8,string,string)","e34b7983":"doPremine()","e34c3896":"FundUpdated(uint256)","e34c8dbf":"distributionDate()","e34da795":"claimTokens4mBTC(address,uint256)","e34dd755":"CrowdsaleAddress()","e34e1700":"StarlightToken()","e34e32c0":"assignOwnership(address)","e34e5786":"test_testableStandardCampaignPayoutToBeneficiary()","e34e7889":"unlistDomain(string)","e34e7cda":"maxRoundDelta()","e34f2a9e":"fundingStartTimestamp()","e34f7137":"_performApprove(address,uint256,address)","e34f947d":"repairCar(bytes17,string,string,uint256)","e34f9dcc":"GCOXPACToken(string,string,uint8,uint256)","e34ffcb8":"changeMinAmount(uint256)","e3500b48":"setResolver()","e35060d9":"RequestEthereumCollect(address)","e350b490":"gameToWinner(uint256)","e3524d36":"getCurrentDiscountPercent()","e3528455":"burnPrimordialTokenFrom(address,uint256)","e3530e9c":"spendFromMultisig(bytes32,uint256,address)","e3539dcc":"LogReceivedETH(address,uint256,uint256)","e3546ac5":"isRatio()","e354a3f2":"freezeAccount(address,bool,string)","e35501be":"activate_admin_commission()","e3552808":"RoboToken(uint256)","e35568cb":"getAvailableTokens()","e355cd4a":"SharkPool()","e35694c0":"callFunction(address,address,uint256,bytes32)","e3577e71":"setPaymentSettings(string,string)","e3579ea5":"publish(string,string,address,uint256)","e3583870":"replaceDecomissioned(address)","e358b0e1":"withdrawPreICOEth()","e358d75a":"getFairymasterReq()","e3599c21":"updateGame(uint8,uint8[],uint32,uint8,uint8)","e359cbbb":"hasEnoughBalance(address,uint256)","e35b37fe":"TRANSFER_COST()","e35b8717":"GolixTokenDistribution(uint256,uint256,uint256,address,address,address)","e35b9699":"Namek()","e35c606b":"JiggsR()","e35c96d4":"NextToken(address)","e35ca326":"cancelOrder(uint80,bool)","e35d3590":"AddSocialAccount(bytes32,bytes32,bytes32)","e35d75a9":"tokensToEthereum_3(uint256,uint256)","e35e6078":"tokenPerUsdDenominator()","e35e6e0c":"setPrice(uint16,uint16,uint8,bytes32,uint256)","e35f0254":"numberOfProposals(string)","e35f4db3":"developer_edit_text_amount(string)","e3602077":"withdrawInWei(address,uint256)","e360736e":"getHistory(string)","e360a49e":"latestUpdate()","e361112a":"isPaying()","e3611578":"testFooKill()","e36255e2":"_checkGeneralRequirements(uint256,uint8,uint8)","e3625dee":"REFERPAYToken()","e362bc9a":"confiscateDeposit()","e362efdc":"getTotalPayout()","e362f168":"CoinAdvisorPreIco(address,address,uint256,uint256)","e362fcaa":"Creditors(address)","e3637435":"supportAccount()","e3643106":"getLatest(uint256,uint256)","e364bd01":"KEOS()","e3650781":"setGasForGR(uint256)","e3651ef3":"fetchRecentSubmittals()","e3659e69":"CNIFCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","e365fd7f":"setMiniPoolEdit_8(string)","e3661586":"confirmManager()","e3669d7c":"Ballot(string,bytes32[])","e3677664":"transferPiece(uint256,address)","e3685ef7":"PocketMoneyContract()","e3686b49":"PopeCoin(uint256,string,uint8,string,address)","e3688d7a":"maxNumMC()","e3692473":"setMockedDate(uint256)","e3699763":"_addAddress(address)","e36a0e6e":"hasPermissionFrom(address)","e36af50d":"betsKeys()","e36b0b37":"stopSale()","e36ba174":"updateMaxCapEthOnce(uint256)","e36c2072":"countCourses()","e36c3f70":"BENEFITToken(uint256,uint256,uint256,uint256,uint256)","e36d036c":"mintPresale(uint256,address)","e36d3844":"CardCreated(address,uint256,uint256,uint256)","e36d392c":"DeliverInfo(uint64,uint256,uint256,uint256,uint256,bytes32,uint64,bytes32)","e36d3a43":"SENDING_BLOCK()","e36db785":"creditor()","e36dd1f9":"withdrawalMoneyBack()","e36e1051":"setcardsalemoney(uint256,uint256)","e36e5d18":"showTopsPlayer()","e36f3177":"maxIssuingSupply()","e36f3e7c":"getAddressDescription(address)","e3710599":"SendTokens(string)","e371817e":"calculateTokenAmount(uint256,address)","e371c0e6":"transferPermissions(address,uint256)","e371cdd4":"luke(uint256,string,string)","e371dfdb":"allFamily(uint256,address)","e372d0eb":"ownersOfArea(uint256,uint256,uint256,uint256)","e37362ab":"NRB_Main()","e37426d4":"StopCrowdsale()","e374e8d4":"isMyWalletLocked_Receive()","e375dfed":"StarbaseCrowdsale(address,address)","e377ac31":"legal()","e3787c61":"TestContract(string)","e378f045":"window0TokenCreationCap()","e37a7fff":"newPlayer(uint256,uint256)","e37aa618":"distributeValue()","e37aca99":"BOXICOIN()","e37b346d":"redistribution()","e37b71ce":"getFundTX(address,uint256)","e37bddc3":"changeEnd(uint256)","e37c6cf8":"redeemDisavowedTokens(address)","e37c8613":"balanceOfPendingToken(address)","e37ccac7":"getSuperseded(address)","e37cd202":"getBonusRate(uint256)","e37d46bd":"myDivs()","e37d4fed":"withdrawToFounders(uint256)","e37d883a":"NumbersToken()","e37e26cc":"_buyFromMarket(uint256,bool,uint256)","e37e60d1":"testControlRetractNotOwner()","e37e7d1a":"init(address,uint256[],uint256,uint8)","e380575a":"presaleFundsRaisedInWei()","e380ae96":"setNow(uint256)","e380b7bd":"balanceOfToken(address,uint256)","e38138a2":"startPurchaseTokens()","e38180ec":"addToPayeeBalance(address,address,uint256)","e381a8d9":"StegoCoin()","e38296e4":"changeDelegate(address)","e382b854":"_setPackedTimestamp(bytes20,uint256)","e382c3e6":"getPeriodBonus()","e382fe45":"deathData_v4()","e383da38":"totalAffiliateTokensSent()","e3843f6e":"myLoseShare()","e3844a61":"isBetPossible(bool)","e3848e5b":"thing(string,string,string)","e385b43a":"DistributionNextPos()","e385f7d2":"SendResult(uint64,bytes18,bytes32,bytes11)","e3877391":"DDJETHToken()","e3877acd":"frozenDaysForAdvisor()","e38787aa":"internalBurnTokens(address,uint256)","e387d31a":"estateRegistry()","e388cbb9":"swpFundDeposit()","e389b63f":"transfer(address,uint256,bytes,string,uint256)","e38bc1f0":"timeThatFinishGuaranteedPeriod()","e38c35b6":"getLockedUserBalance(bytes32)","e38c4585":"JointICOContractAddress()","e38c9825":"maxgame()","e38cc06b":"testDiv()","e38d0fbd":"FirstTradingEcosystem()","e38d6b5c":"maxPrice()","e38d7e99":"_next_id()","e38da1a1":"storeDoi(bytes32,bytes32)","e38e2cfb":"step(uint16)","e38f4861":"initLock()","e38fbdf6":"addBoundary(address)","e38ff5dc":"updateInvestor()","e39062f5":"MDTKAirdrop(address,address)","e3906b3d":"mintNextCard()","e390e263":"disableWhiteListForever()","e3914699":"dEthereumlotteryNetWinners(address)","e391a7c4":"revokeSignaturePreSigned(bytes,bytes,uint256)","e391b3d1":"ssword(string)","e391bda5":"transferImpl(address,address,uint256)","e39253e6":"SampleToken(uint256,string,uint8,string)","e392a521":"indexPrice(uint8)","e3945eba":"planetLife(uint256,uint256,uint256)","e395983a":"bountyTokensBatch(address[],uint256[])","e39608af":"ETUToken(string,string,uint256,uint256)","e3961174":"tokensCreationCap()","e3964b8c":"ERC20Token(string,string,uint8,uint256,address)","e3967d6a":"currentTimeBonus()","e3967eed":"totalUserNumber()","e396bd60":"LogEscrowWeiReq(uint256)","e396da73":"checkProof(bytes32,bytes32[],uint256)","e3973b5a":"NiteshToken()","e397dfd1":"updatetoken(uint256,string,string,uint256)","e39898d1":"checkSaleValid()","e399331b":"coinAllocation()","e3994993":"addDiary(string)","e399cb0d":"initializeCappedFundraiser(uint256)","e399daab":"zoomraffleFee()","e39a686c":"ChainBackedOption()","e39b2284":"ZEONPrivateSale(address,address,address,uint256,uint256)","e39b40d8":"_createCard(string,uint256,address,address,bool)","e39bbf68":"dividedBy(uint256,uint256)","e39bdfab":"getCutie(uint40)","e39c6d80":"batchTransfer(address,uint256[],uint256[])","e39c742a":"_caluLocktime(uint8)","e39cbe80":"senderAdminAndSaleNotFinal()","e39d2a98":"nextCommonTTMTokenId2()","e39dcc21":"blah()","e39ebde9":"FOLIToken()","e39fa059":"queryRandomCallback(bytes32,string,bytes)","e39fbd88":"tokensDispensed()","e39fff72":"Divs()","e3a0a148":"giveOwnership(address)","e3a0de36":"admin(string,string,string,string)","e3a12480":"getBalance(uint8)","e3a135b9":"_bid(uint256,uint256,uint256,uint256,address)","e3a199d6":"testThrowCreateNewRevisionNotUpdatable()","e3a2a327":"SmartCityCrowdsale(address,address,address,uint256)","e3a37ea2":"newIndex(bytes32)","e3a47b00":"standing()","e3a531a3":"setSaleAuctionContractAddress(address)","e3a70ec1":"max_goal_amount()","e3a71e32":"deliverBonusTokens(address[])","e3a75485":"TORUE()","e3a797f1":"getCandidateMemberInfo(uint256)","e3a79840":"finishPresale(uint256,uint256)","e3a7f45a":"ecrecoverWrapper(bytes32,uint8,bytes32,bytes32)","e3a83290":"SALE_address()","e3a861a4":"setCrydrView(address,string)","e3a87f8b":"secondPrivateReleaseTime()","e3a8b13a":"core(uint256,uint256,address,uint256,string,uint256)","e3a8b345":"emptyContract()","e3a8e29c":"addBorrower(address)","e3a8e50b":"Subscription(bytes,address,bytes)","e3a94e9f":"addPacksToStandardSale(uint32[])","e3a9744b":"mintTokens(int256,uint256,address,bool)","e3a97893":"secondPresaleEnd()","e3a99d2b":"updata(uint256,uint256)","e3a9b508":"EnableDisableTokenProxy()","e3a9db1a":"depositsOf(address)","e3aa018e":"setRank(address,uint256)","e3aa3c6e":"initialBonuslistTokens()","e3aa3fbb":"startEscrow(string,uint256,uint64)","e3aa62b1":"responsavel()","e3aae11b":"isStartGame()","e3ab8492":"requestGWAPrice(string)","e3abeaf3":"setAllowedTransferTo(address,bool)","e3ac3880":"backupfarmItems(address[],uint256[])","e3ac5d26":"prize()","e3ac8e16":"setFinalizationTime(uint256)","e3acc49a":"catIndexToPriceException(uint256)","e3adf4ea":"ChangeICOEnd(uint256)","e3ae1667":"commRate()","e3ae85f0":"winReward()","e3aec30c":"ballotStarted()","e3aeedc4":"lastMintedTokens()","e3aef2bd":"checkUnlockedTokensData()","e3af2ed9":"TWToken()","e3b08f56":"concatYearMonth(uint16,uint8)","e3b09a85":"HungrCoin()","e3b10447":"GITToken()","e3b2594f":"fundingCap()","e3b26a8c":"SocialNetwork()","e3b3847c":"SubmitProofOfOwnership(bytes32)","e3b3932a":"bookKeeper()","e3b45ab7":"MIN_TOKEN_AMOUNT()","e3b460c9":"hookOperator()","e3b49a03":"rollSystem(uint256)","e3b55276":"AdminBuyForSomeone(uint16,address)","e3b5a153":"lastEpochTX()","e3b6040e":"amountSlicesCount()","e3b61135":"reinvestProfit()","e3b62158":"TokenVault(address)","e3b71ded":"setMaxContributionCrowdsaleAddress(address)","e3b7b668":"_setMaxDailyPerUser(uint256)","e3ba3398":"importTokens(address)","e3ba80d0":"purchaseImpl(uint16,uint64,address)","e3bb01ac":"viewCancelledList(address)","e3bb3445":"releaseSupply(uint256,uint256)","e3bbab85":"test_smallDeviationPermitted()","e3bbb4f1":"MAX_GAS_PRICE()","e3bc2bb5":"newPassword(string,uint256)","e3bd9638":"getContract(address,address,uint256)","e3bea282":"callnotchecked()","e3bfdcfe":"pollBurnInc()","e3c04c32":"getNota(uint256)","e3c08adf":"getPlayerLAff(uint256)","e3c10714":"setMinContrib(uint256)","e3c2e4b9":"_setCreatedBlockOnCommitsPhase(uint256,address,bool)","e3c33a9b":"hasRole(string)","e3c3ec92":"BONUS_REWARD()","e3c3f180":"_setPurchasePremiumRate(uint128)","e3c4b1ae":"minSumICOStage2USD()","e3c517a9":"lockFlag()","e3c5862b":"setCAO(uint256,uint256,uint256,uint256,uint256,uint256)","e3c5a852":"buyTickets(uint256[],uint256,uint256)","e3c5d11a":"MIN_BUY_TOKENS()","e3c6e66d":"discountedIcoStartBlock()","e3c73d32":"minimumPriceCount()","e3c79a20":"enterOnBehalfOf(uint256[],uint256,address)","e3c82106":"becomeDuke(string,string)","e3ca12c6":"sendtoB(uint256)","e3cafbb0":"TOKEN_EARLYSUPPORTERS()","e3cb0cf0":"maxTransferPerTimeframe()","e3cb49f9":"setBlockingState(address,uint256,uint256)","e3cb8563":"playToken()","e3cbe744":"updatePlayersCoinByOut(address)","e3cc3570":"mintMigrationTokens(int256,address,uint256)","e3cc65e2":"getInvestorsLength()","e3cc83cf":"withdrawWhenFinished(address)","e3ccb809":"voteOnProposal(bool)","e3cd30f6":"getBuilding(uint8[176],uint8,uint8)","e3cd7c03":"getPass(address)","e3ce9714":"proxyWithdraw(address,uint256,uint8,bytes32,bytes32)","e3ceb06d":"YesNo(bytes32,address,string,address,uint256)","e3cf1ad3":"changeRegistrationStatus(address,uint256)","e3cf6644":"sendKmPards()","e3cfef60":"timeRemaining()","e3cff634":"test(uint32)","e3d021d5":"purchaseTicket(uint16[])","e3d0252b":"defaultTriggerTime()","e3d0799c":"PLATFORM_FEE_PER_10000()","e3d0be5c":"EARLY_INV_BONUS()","e3d1072c":"Giveafuck()","e3d13592":"newTechSupport()","e3d1e6d6":"hasProof(bytes32)","e3d2a98c":"setCurrentFundingGoal(uint256)","e3d2c1bf":"presaleTokensPerDollar()","e3d33fc9":"transferCount()","e3d3f4cd":"bidGift(uint256,address)","e3d4187f":"Buy(address,uint256)","e3d5d88b":"getServerBuildingName(uint256,uint8,uint8)","e3d5e6a3":"year2Unlock()","e3d670d7":"balance(address)","e3d6ce2b":"addFiatTransaction(string,int256)","e3d6e4a3":"setFundsCreditBitContract(address)","e3d74457":"releaseTimeFirst()","e3d7f159":"FIRST_TIER_DISCOUNT()","e3d86998":"declareNewerVersion()","e3d91ebf":"bonusPoolsOf(address)","e3d9e8ea":"drawnArbiter(address,uint256)","e3da41b5":"sortWinningNumbers(uint8[5])","e3da5399":"left90(uint256)","e3da9f8f":"tranchesOf(address)","e3dac959":"makeTapTop()","e3db17b8":"updateContract(address)","e3db6670":"isHardCapTokensReached()","e3dbaff1":"tokensSpent()","e3dbda67":"setArtistsControlAddress(uint256,address,address)","e3dcd2c8":"maxPaymentInEther()","e3dd164e":"setNewTokenImporter(address)","e3de18b2":"withdrawMyClosedDeposits()","e3dea4b7":"setMcrAmountForGas(uint256)","e3debbbe":"getSubscriptionServiceID(bytes32)","e3e06c45":"PayPayCoin()","e3e10762":"calculateIdeaBuySimple(uint256)","e3e1dcb3":"getRouteNameByIndex(uint256)","e3e2342f":"callTokenHolderTribunal(string)","e3e28bab":"setTimes(uint256[],uint256[])","e3e2b1ba":"add_number(uint256)","e3e4001b":"buyWithReward(address)","e3e42b0c":"ZenAD()","e3e4a1b4":"burnUserTokens(uint256)","e3e4b9fb":"claimJob(uint256)","e3e5075c":"depositBattleValue(address)","e3e5439c":"specDWallet()","e3e54ac2":"CarDeregistrationFaled(uint256)","e3e5c9c1":"WhiteListBonusTokensEmitted(address,uint256)","e3e7399e":"addWinner(address,bytes4,uint256)","e3e7519c":"getTokenPriceforDapp()","e3e77055":"MultipleTokenVesting(uint256,uint256,uint256,address,uint256)","e3e7903f":"updateScore(address)","e3e7b439":"cryptoWillToken()","e3e7c665":"makeMoney()","e3e7d4f4":"leaderboardEntries(uint256)","e3e88734":"SigUser(address)","e3e9800d":"_cancelSellOfferInternal(uint32,bool)","e3e98cad":"COSSToken()","e3e9bc3f":"becomeSponsor()","e3e9cb4c":"Birth(address,uint256)","e3ea6496":"newCarProductID()","e3ea67d4":"STARTING_TURTLES()","e3eba060":"allowedToSpend(address,address)","e3ec0251":"subtraction()","e3ec0666":"clearJackpotParticipants()","e3ec5046":"DECIMALCOUNT()","e3ec7584":"showTokensUnfreezeDate(address)","e3ecbd7e":"isEditionEnabled(uint256)","e3ed14db":"getDiamond(uint256)","e3ed48a4":"getTokenScope(uint256)","e3edbfd3":"getAmountDue(address)","e3f037d8":"FlightDelayUnderwrite(address)","e3f0920a":"coinMaster()","e3f0b761":"walletF()","e3f0dd48":"getMult(bytes32,bytes32,uint256)","e3f10188":"updateFlagCount(address,address,uint256)","e3f16a61":"GRPlaceholder(address,address)","e3f25f01":"_delegateforward(address)","e3f2e4a4":"ante()","e3f310c7":"priceToSpend(uint256)","e3f38dd6":"GetSignVersion(string,address,uint256)","e3f4937f":"outOverRoundId()","e3f4ffdc":"GeezerToken()","e3f5009f":"payWithMileagePoint(uint256)","e3f508f5":"setLeaf(uint256,uint256)","e3f52c99":"warrior()","e3f563f6":"generateCompoundTerms(uint256)","e3f596a4":"ownerPrice()","e3f61948":"getStartIndex(uint64)","e3f688d3":"ThingschainToken(address)","e3f6b544":"member()","e3f7faaf":"calculatePrice(uint256,uint16)","e3f954be":"buyICOTokens()","e3f96400":"getTotalOwnerAccounts()","e3f9ba0e":"returnEth()","e3f9cd17":"lockTokenForExchange(address)","e3fa5882":"tryWithdraw(uint256)","e3fc03a8":"Guess(address,uint256,int256,int256,uint256)","e3fc43b2":"ended(bool)","e3fcbac1":"getSharesPercentage(address)","e3fcf122":"_sctc(uint256,uint256,uint256,uint256,address)","e3fe0317":"_setAllocationFee(bytes32,uint256)","e3fe48a1":"loadWhiteList(address[],bytes32[])","e3fe6a9e":"sehrRaised()","e3fe9740":"icoThresholdReached()","e3ff2f05":"weiExchangeRate()","e3ff9ac2":"MACHToken()","e3ffc9a3":"sendEtherToOwner()","e3ffcb84":"loserOf(uint256,uint256)","e3ffefe3":"ZeroReturnProfit()","e4002b30":"commitEuro()","e4007949":"buyRegistration()","e4019e07":"BOB()","e40205d6":"roundEndTime()","e4020804":"isHealthy()","e4024194":"returnedData()","e4027126":"mSumRawSpeed()","e40418a0":"trustedContractAddr()","e4043b37":"updateProduct(uint256,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","e4048049":"createBool(bytes32,bool)","e4062df5":"SkychainToken()","e4063140":"getAllActivity(uint256)","e40652e3":"creatUserPurchase(address,string)","e4065c4c":"Alias()","e406bb4b":"minedTokenCount()","e407ccb9":"Repayment(uint256)","e40819af":"lastTokenCreated()","e4083daf":"create_game_invite(bytes32,address,uint32,uint32,uint8,uint16,uint8,address,uint256)","e408de80":"buyInWithAllBalanced()","e40906ed":"getBorrowBasicInfo(uint256)","e4098655":"getCallCalledAtBlock(bytes32)","e409edf1":"chooseWinnerDeadline()","e40a72d4":"_internalToken()","e40a7545":"collectBuyFee(uint256,address)","e40a955c":"grantTeamTokens(address)","e40b4523":"activateVault(address,uint256,uint256,uint256,uint256)","e40c231e":"StoneToken()","e40d3692":"contributedAmountOf(address)","e40d835e":"getPositionIdFromNonce(uint256)","e40d8fc3":"addICOEndDate(uint256)","e40dd35b":"isGameApproved(address)","e40e56d3":"regular_coins()","e40e8457":"requestBurnerContract()","e4105ed5":"setToken(uint8,address)","e410a0c6":"setup(address,uint16)","e4115a8c":"ApcrdaZebichain()","e4120220":"getTokenTrust(address)","e412828a":"Shark()","e412c526":"set_pre_kyc_bonus_numerator(address,uint256)","e415f4ee":"_addDai(uint256,address)","e4160e48":"admin_active_withdrawable()","e4165e15":"ownerDeactivateToken()","e416d173":"PreICO(uint256,uint256,address,address,uint256)","e416f6b4":"_startRound()","e416faa0":"getBetNum()","e4171746":"major_partner_address()","e417291b":"undelegateDAOTokens(uint256)","e41765de":"addBotAddress(address)","e417c38c":"Reward(address,uint256,uint256,uint256)","e417c62c":"ProofFund(address)","e4187d02":"multiplyDecimal(uint256,uint256)","e418f592":"receiveToken(address,uint256,bytes)","e419f189":"multiAccessIsOwner(address)","e41adb25":"PoolPreICO()","e41b1d28":"noAccountedWithdraw()","e41c02c9":"determineFirstPeriodOutcome(uint256)","e41cc093":"getItemStore(bytes12)","e41d0944":"acceptDonate()","e41d65e0":"payWinnerManually()","e41eaa41":"fakeNow()","e41ee46a":"MAX_QUANTITY()","e41f7dc1":"ethPriceProvider()","e41fb842":"comunityMintedTokens()","e420264a":"g(uint256)","e420a904":"FirstToken()","e420dcc5":"tokenDrian()","e4218416":"redemptionPayouts(uint256)","e422d6b8":"createRareCard(uint256,uint256,uint256)","e422ebe9":"getBot()","e422f311":"secondWeekEndTime()","e422f699":"toBE(uint256)","e4232069":"MAX_INPUT_USERS_COUNT()","e4246ad2":"canContractExchange(address)","e4246ba0":"setPaymentContract(uint8,address)","e4251361":"getTodayInvestment()","e4254585":"MFNToken()","e4274453":"PUBLIC_CROWDSALE_SOFT_CAP()","e4277f78":"backToOldOwner()","e427a197":"previousMinters(address)","e428ad8a":"ReferralReward(uint256)","e428fd5f":"takeBackMoney()","e42996d1":"redeemCoinsToICO(uint256)","e429bd8b":"getUsableAmount(address,address)","e429cef1":"addAuditor(address)","e42a4556":"KKTokenNew()","e42a8bc9":"dAddBallot(bytes32,uint256,uint256)","e42a9156":"AppleproToken()","e42a96e7":"escrowContract()","e42b0193":"test_insert_findWithHintNextIncreased(int256)","e42bb93f":"StarUniteChain(uint256,string,uint8,string)","e42bff66":"mintBadge(address,uint256)","e42c04f4":"Cryptshopper()","e42c08f2":"tokenBalanceOf(address)","e42c1337":"getSalary(string)","e42c1b76":"BountyActivated(uint256,address)","e42cb9f3":"statement()","e42d5be0":"getPaymentOf(address)","e42d674d":"refundIco()","e42d6efa":"unregisterUsers(address[])","e42d70ba":"safeAddCheck(uint256,uint256)","e42def21":"CryptoHill()","e42f4cc0":"addPersonalInfo(address,string,string,string,string,string,string,string)","e4309307":"fortifyClaims(uint16[],uint256,bool)","e430bb5b":"getFreeCoins()","e4310205":"addMastercardUser(address)","e431af36":"_addMember(address,uint256)","e431d241":"validateAndRegisterClaim(address,bytes32,uint8,bytes32,bytes32)","e4322464":"MatchBettingFactory(address)","e43252d7":"addToWhitelist(address)","e432f0e5":"queryOracle(string)","e4330545":"dump()","e433bb3a":"HAVY()","e4340e6a":"Wallet5()","e435f2c9":"takeOwnershipMultiple(uint256[])","e4360fc8":"getFileListElement(bytes)","e43650b6":"changeILFManager(address,bytes32)","e436a3f7":"getRoot2_16(uint256)","e436bdf3":"Draws(uint256)","e4372d0f":"setRestrictedAcct(address,uint256)","e437d1a7":"unRedeem(uint256)","e437d815":"getDsitributeMulti(address[],uint256[])","e438ff55":"changeINAWallet(address)","e43926fb":"refundTokenToCustomer(address,uint256)","e439501e":"AntmineToken()","e4397db1":"getBetsState()","e43a0bb2":"pullFunds()","e43a8897":"DonatedBanner()","e43aa5ff":"Medban()","e43ac447":"DirectConnectionFactory()","e43ae642":"deleteDIDHolderWhenBalanceZero(address)","e43b72b4":"discountedInvestors(address)","e43ba0bd":"isStrategy(bytes15)","e43bb0f6":"link(uint256,address,address)","e43bc1e9":"functionName3(bytes32)","e43c74a4":"BRoyalCoin()","e43cd900":"PoolBounty()","e43d68ce":"GetBanker(uint8)","e43dfebf":"burningTokens()","e43f696e":"setWhiteList(address[],bool)","e43f8424":"burnGoldTokens(address,uint256)","e4403507":"tokenContractBalance()","e44171b1":"Arina_amount_judgment(uint8,uint256)","e4424c9e":"createNew(bytes32,address)","e443253a":"DataFromSetting(uint8)","e443348e":"ONE_TOKEN()","e4440a86":"marketWallet()","e4444feb":"removeAllowedAddress(address,address)","e444504c":"nextClaim()","e44451ba":"removeAddressFromAdminlist(address)","e444a2e1":"_birthPerson(string,string,uint64,bool,bool)","e44501c4":"inactive_dividend(address)","e4454fdc":"GetMaxStageEthAmount()","e44591f0":"isNonFungible(uint256)","e4480dd8":"withdrawl(uint256)","e448ee26":"joinChallenge(uint256)","e4492fcd":"TokensPerETH()","e4495b15":"confirmSetIssuer()","e449c52a":"getStr(string)","e449de9f":"prevContract()","e44a94d3":"minContributionPresale()","e44ac1e4":"addLock(address[])","e44b974f":"placeBet(uint8,uint256,uint256,uint8,bytes32,bytes32)","e44bc43f":"stepOneRate()","e44c333a":"DreamTeam()","e44c96c9":"addInitialOwners(address[])","e44caea6":"balances3(uint256)","e44d3084":"testFailure()","e44d311b":"ticketPrices(uint256)","e44d6f04":"beatTeamWallet()","e44dbb75":"addAddressListItem(uint256,address)","e44de421":"buyTokenFrom(address,address,uint256)","e44f777c":"returnETHforUnqualifiedBuyers(uint256,uint256)","e450056c":"tokenPartition(uint256)","e4503da4":"startPhaseMaximumcontribution()","e4504f62":"dogCore()","e451197a":"OrdoCoin()","e451ecfa":"swapTokenValueForCredits(address,address,uint256,address,string,uint256,uint8,address)","e45285cf":"setAIRDROPBounce(uint256)","e4536316":"removeARA(address)","e4536b84":"BalanceReader()","e453877e":"_approveTransfer(uint256)","e4538c6c":"addUndergraduateTo(address,string,string,string,uint8,uint8,uint8,uint8,uint8,uint8,uint32,uint32)","e454158c":"futureSaleAllocation()","e4543410":"setIncrementPercentage(uint256)","e4547443":"releaseTimeLock(address,uint256)","e4547f98":"documentExists(bytes)","e45499c1":"updatePriceOfToken(uint256)","e4556f2d":"MaturityPrice(uint256,uint32,bool,bool,bool)","e455d26c":"getCurrentNeedsCount()","e455fce7":"extractOversightAddressesIndexLength()","e4560388":"endTimeMain()","e45648ac":"exchangeOldVersion()","e4564a4a":"returnAddressBonuses()","e4569c4e":"eeeeeeeeeeee()","e4578590":"SplitPaymentMock(address[],uint256[])","e457e1e5":"charge(uint256)","e458c754":"whitelists(uint8,address)","e45a4fb4":"isMultipleOf(uint256,uint256)","e45a93cc":"GIT()","e45aa608":"tokensForfortis()","e45ab391":"Technology5G(address)","e45b1d1b":"openClosedToken()","e45b7388":"subscribers_TO_HATCH_1CraigGrant()","e45b8134":"transfersFrozen()","e45bc0ae":"dollcoin()","e45be8eb":"minPrice()","e45bf7a6":"forwardTo()","e45c1879":"getAuctionsCount()","e45c210c":"LogFunderInitialized(address,string,uint256)","e45c47b9":"SetPermissionsList(address,address,uint8)","e45ce7e3":"refillTxFeeMinimum()","e45ceec1":"getUnreadMessages(address)","e45d0550":"getAddressArray(address,string,string)","e45d4717":"withdrawLogic(bytes32,uint256,uint256,uint256[])","e45da0be":"freezeAddress()","e45dbabd":"addAddressesToWhitelist(uint256,address[])","e45ebe93":"checkVoteStatus()","e45ef4ad":"bobClaimsPayment(bytes32,uint256,address,address,bytes20)","e45fc71f":"getPeriodCycle(uint256)","e460382c":"importBalanceBatch(address[])","e4614066":"MelonToken(address,address,uint256,uint256)","e46164c5":"waitingForPayout()","e4626c8f":"like(address,uint256)","e462c888":"createEscrowByBuyer(address,uint256)","e463b659":"EtownCoinTest(uint256,string,uint8,string)","e463fa6b":"AddWhitelist(address)","e464dcc8":"userHasLuckyStone(address)","e4651465":"addEthTeller(address,uint256)","e46523f2":"_isNeighbor(uint8,uint8)","e46537ba":"JJCOIN()","e465c465":"like(address)","e46617b6":"releaseMultiAccounts(address[],address)","e4662939":"CLBToken()","e46638e6":"canTransfer(address,address,uint256)","e46694e8":"lastStakePriceUSCents()","e46751e3":"exp(int256)","e467f7e0":"mint(address[],uint256[])","e4682f00":"cancelSpendLimit(uint256)","e4683a79":"refund(bytes32,bytes32)","e4684d8f":"AXNETToken()","e468688e":"addTotalSupply(uint256)","e46871f1":"governingLaw()","e468cb72":"FUTM()","e468dc16":"Testokenmaking()","e4690a0b":"popRequest()","e469185a":"updateReserveRatio(uint8)","e4693e98":"endFundingTime()","e4698ee7":"start5Phase2020()","e46a5c21":"getArmyBattles(uint256)","e46c2cc4":"bytarr28(bytes28[])","e46d1939":"napoleonXAdministrator()","e46d6cb1":"canChangeRecoveryAddress(uint256)","e46da1b9":"MeiJiuToken(uint256,string,uint8,string)","e46dcfeb":"initWallet(address[],uint256,uint256)","e46dea92":"BlockChainPay()","e46f20dc":"getTransferHash(address,uint256,address,address,uint256,uint256)","e46f9ecf":"enableCodeExport()","e46fbe76":"burnSomeEther()","e46feb2c":"orgy1f(string,string)","e4706e3a":"TokenRateChange(uint256)","e470ddf8":"totalKittiesBurned()","e47112bd":"sendTokens()","e471a5b9":"putIntoPackage(uint256,uint256,address)","e471d770":"StopTheFakesPromo()","e472311b":"handleHTLCUpdateTx(address,bytes32,bytes32)","e4723828":"TestMath()","e4725ba1":"accept(bytes32)","e4745970":"transfer(uint256,address,string)","e474777e":"applyForCertification(string,string,bool,string,address,string,string)","e474f97a":"setPreicoAddress(address,uint256)","e4752159":"DigitusToken()","e475222e":"activeGames()","e476137b":"windUp()","e476af5c":"revokeAttributeSigned(address,uint8,bytes32,bytes32,bytes32,bytes)","e476cb86":"_mintTokens(address,uint256)","e4772ae3":"getDailyCount(address)","e4779d73":"register_user(address)","e4788384":"CancelAuction(address,uint256,uint256,uint256,uint64,uint256,address)","e478b578":"ProofofConcept()","e47a192e":"FactomIssued()","e47a6a9f":"disbursementPeriod()","e47bc32b":"ShanHuCoin()","e47c0c20":"GetCityData(address)","e47c5902":"ecverify(bytes32,bytes)","e47ca4eb":"LogNewAnswer(bytes32,bytes32,bytes32,address,uint256,uint256,bool)","e47cb18f":"PointToken(uint256,string,string,uint256)","e47d8085":"isCurrentUser(address)","e47d914a":"fechVoteInfoForVoter()","e47da59e":"consumeTicket(address,string,uint256)","e47dace5":"totalLenderBalance()","e47dea1d":"setWithdraw(address)","e47e1c0b":"getAssetIds()","e47e7e66":"ask(uint256)","e47ea649":"isICOfinalized()","e47f0d64":"list_products()","e47f18d0":"CryptoTorchToken()","e47ffb64":"setSoft_Cap(uint256)","e480ba6a":"isDailySettlementOnGoing()","e4818a5d":"totalUnreleasedTokens()","e4818e4b":"secondPeriod()","e481c884":"ACFWallet()","e481ebf0":"getOwnedActiveEntry(uint256)","e48225ce":"startStakingAt(uint256)","e4828367":"buyEther(uint256)","e48341db":"getUpdateCount(bytes32)","e4845c2f":"Sperm()","e4849b32":"sell(uint256)","e4852b9b":"transferAccount(address)","e4860339":"tokens(address)","e486387a":"ReferenceToken(string,string,uint256)","e486869b":"setstoredaddress(address,address)","e487624b":"EarnedGNS(address,uint256)","e487c88b":"CROWDSALE_UNVERIFIED_USER_CAP()","e487e87b":"activateICOStatus()","e487eb58":"getOwner(bytes20)","e487fdb6":"participant1SentTokensCount()","e4881813":"cat()","e489c5ff":"haltIco()","e489d510":"MAX_TOKEN_SUPPLY()","e489fc68":"NdexSupply()","e48a1d60":"assertPaymentIndexInRange(uint256)","e48a4a29":"mayjaKill()","e48c09fe":"getFiltersLength()","e48c3c5c":"lockInDays()","e48cf65f":"_setClassViewValue2(uint256)","e48d81a8":"multisigwallet()","e48db5d4":"ProofVote(address)","e48e0d69":"ownerRetrieveTokenDetails()","e48e603f":"right54(uint256)","e49013b3":"jigoutuihuan(address,uint256)","e490c513":"getEntityState(bytes32)","e49168f3":"whichEpoch(uint256)","e4917fd2":"provenAddresseList(address[],bool)","e491936f":"getDisputeTX(uint256)","e49280cb":"close(address,uint256)","e4928550":"daylimit()","e4929aa4":"FCC(address)","e4932abe":"INC()","e493ef8c":"Q()","e4942930":"SetMinLot(uint256)","e4952ddb":"transferDataOwnership(address)","e495f08e":"getHouseInfo(bytes32)","e495faf4":"bonusesPayed()","e496f510":"oraclize_query(uint256,string,bytes[3],uint256)","e4983e27":"HEOContract()","e498922f":"getExp(uint256)","e498b98f":"setRedeemRequestLimit(uint256)","e498f5de":"FrozenFunds(address,bool,uint256)","e4995a1d":"ProdTokensale()","e4997dc5":"removeBlackList(address)","e4998173":"blockHalving(uint256)","e499f542":"distribute_reward(uint256,uint256)","e49b4c64":"ownerModAdmin(address,bool)","e49b606c":"claimWinnings(bytes32)","e49c9529":"underwrite(uint256,uint256[6],bytes)","e49cc6a9":"getUserBalancesLastBet()","e49dcee9":"fixTokens()","e49f6e91":"editContact(address,string)","e49fdaa8":"setClaimLimit(address,address,uint256)","e4a008a0":"cancelEthOffer()","e4a05c1f":"_nibblesToTraverse(bytes,bytes,uint256)","e4a0c124":"QCSTToken()","e4a0d386":"ethToBeClaimed()","e4a13fa4":"getICOAddress(uint8)","e4a1d868":"deposit_token(address,uint256)","e4a27ba0":"_play()","e4a2a8af":"getOwnerClientDetails()","e4a2ac62":"getCompactData(address)","e4a2c6d6":"loadProfit()","e4a30116":"initialize(uint256,uint256)","e4a30200":"BRV(uint256,string,string)","e4a358d7":"getPrefix(uint32)","e4a36a77":"getBondRemainingToBePaidOut()","e4a41c7f":"becomeFriendsWithMe()","e4a46a99":"howManyEthersToBecomeOwner()","e4a682d8":"InvestorToken()","e4a6e85a":"CoinStorage()","e4a72b13":"bZxContractAddress()","e4a77d29":"setInitialVaribles(uint256,uint256,uint256,address,address,address)","e4a7f363":"NewSymbol(string,uint8)","e4a8de44":"quater1()","e4a9b286":"getVestingDuration(address,address)","e4aa0741":"AmericoTokenToken()","e4aa2436":"SouthAfricanRandsToken()","e4aa533e":"guess(bytes32)","e4aa6c5c":"MHCBC()","e4aa8140":"MAX_WEI()","e4aa82d7":"test_addAndGetVersion()","e4aa8da9":"checkReceiptProof(bytes,uint256,bytes,bytes)","e4abae32":"respond(uint256,address,address,bool,bool)","e4abf00e":"UnFrozenAddress(address)","e4ac3206":"withdrawIQT(uint256)","e4acecf3":"SALE0_END()","e4ad9a18":"takeTokens(address,uint256)","e4ada9fa":"setFeeForFirstArtWorkChangeRequest(uint256)","e4adc325":"UBS()","e4adc4f0":"ownerTransferWeiThirdWallet(uint256)","e4ae2e88":"enableEdition(uint256)","e4ae7d77":"getResolver(string)","e4af29fc":"accountCount()","e4af5f30":"getMinMaxBet()","e4af8331":"func_02E5()","e4b0a97b":"test_doubleVotingAgainst()","e4b1443b":"KIK_ADDRESS()","e4b19e98":"amountRefunded()","e4b1e977":"hadd(uint128,uint128)","e4b1f93a":"isValidPurchase(uint256,uint256)","e4b1fe54":"totalGas()","e4b203ef":"sealed()","e4b34274":"round4StartTime()","e4b3c517":"crowdsaleContinue()","e4b42498":"AfrFballCoinXToken()","e4b503ec":"MinAmountByBetChanged(uint256)","e4b50cb8":"getToken(uint256)","e4b50ee8":"setRaiseRatio(uint256)","e4b541f3":"currentDevFees()","e4b5553c":"AddPromoter(address)","e4b5762a":"setPriceFeed(uint256,uint256,uint256,uint256,uint8,bytes32,bytes32)","e4b5ddeb":"addInvestorAtID(uint8)","e4b5e557":"CPWAToken()","e4b64da9":"sellOrders(address)","e4b6ac4c":"bonus2StartETH()","e4b6f799":"withdrawDai()","e4b6fbe2":"getApproveSpenderValue()","e4b73ac9":"foundersWallet3()","e4b74590":"distance(uint256,uint256,uint256)","e4b7b1b0":"Payroll(address,address)","e4b7fb73":"getRemainingSupply()","e4b8ebb7":"powercoin()","e4b90ed2":"reclaimInternal(address)","e4ba3969":"supportRecord(uint256)","e4bb7160":"adjustInflationRate()","e4bbb4b0":"POLY()","e4bc01b4":"FooMintableToken()","e4bd6695":"create(string,string,uint8,address,uint256)","e4bd9ebd":"calcId(uint256)","e4bdaa61":"buy(uint16,address)","e4be5159":"queryChild()","e4be782a":"createSecurityToken(string,string,uint256,uint8,address,uint256,address,uint256,uint8,uint256,uint8)","e4bf56b8":"getPastGamesLength()","e4bf6195":"changeGroupInfo(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","e4bff515":"_pointToResolverAndResolve(int256,bytes32,address)","e4c01bbb":"LogSetSymbol(string)","e4c05a7d":"checkEngineerQuest(address)","e4c14a34":"Tx(address,address,uint256,string)","e4c19408":"startPreIco(uint256,uint256)","e4c21cf2":"CheckSoftCap()","e4c28308":"buyPortfolio(address,uint256,uint256)","e4c2db06":"getPreviousFile(bytes)","e4c487c9":"Betsicbo()","e4c53f04":"setCreationCurator(address)","e4c5ff46":"manualMint(address,uint256)","e4c60492":"RANGESTART_8()","e4c82881":"change_tokenReward(uint256)","e4c92731":"FAST()","e4cb30ad":"getCharacter(address,uint256)","e4cc1161":"seedWithGasLimit(uint256)","e4cc18be":"finishMint()","e4cc98a5":"dividendPeriod()","e4cd7d96":"OX_ORG()","e4cdf3cc":"takeBack(uint256,uint256,bytes32,uint8,bytes32,bytes32)","e4ce25ac":"roundEthShares()","e4ce6ccf":"deed(bytes32)","e4cecd32":"cf_request(uint256,uint256)","e4cf77bb":"GoodBoyPoints(uint256,string,string)","e4cfcbf7":"setChainNext(address)","e4cfe9eb":"callerAllocationPeriod()","e4cff610":"process_merge_mint_ious(address)","e4d0f41d":"setAuthorized(address,address,bool)","e4d13625":"pauseActivity(uint16)","e4d1b2cc":"allocatedToken()","e4d2fecf":"isListening(address,address)","e4d433e8":"startDealForUser(bytes32,address,address,uint256,uint256,bool)","e4d534cb":"feewallet()","e4d5a558":"updateAndSafeTransferFrom(address,uint256,string,bytes)","e4d609cc":"addRequester(address)","e4d74f2e":"BCBcyCoin()","e4d75c9d":"setVestingAddress(address)","e4d76d3b":"ATN(uint256)","e4d7a3d4":"getAllClients()","e4d8dead":"setChild(uint256,string)","e4d91372":"setlevel(address)","e4d9d212":"isPVPListener()","e4d9de94":"getInfo(uint8)","e4d9e130":"CrowdsaleToken()","e4da3860":"XfinityAsset()","e4db2230":"addCard(uint256,uint256,address)","e4db2ceb":"auth(string)","e4db4dc1":"CheckEligibility(address,string,string)","e4db6062":"GivethBridge(address,address,uint256,uint256,address,uint256)","e4db915e":"citadelBuy(uint256,address)","e4dbc385":"assertEq12(bytes12,bytes12)","e4dbf719":"FlightDelayLedger(address)","e4dc2aa4":"totalSupply(address)","e4dc3d8b":"raisedSale1USD()","e4dcb06b":"open(string)","e4dd7794":"fundingPaused()","e4deb007":"setNextSaleAgent(address)","e4dec825":"setAllowContributionFlag(bool)","e4dedc7f":"DeleteContract()","e4df2531":"topBalance()","e4e075cc":"_getPlayerInfoByAddress(address)","e4e0bd1f":"PointPowerCoin()","e4e0c030":"makePayment(bytes32,uint8,bytes32,bytes32,uint256,uint8,uint256,bool)","e4e103dc":"rewardUser(address,uint256)","e4e1aae6":"BlockChainShopCoin()","e4e1bd53":"DisableTransfers(address)","e4e1f29b":"discountStep()","e4e1f6c5":"compare(address)","e4e1f7af":"mintTokensMultiple(uint256,int256,address[],uint256[])","e4e299f7":"zero_out(uint256)","e4e2bfe4":"canFinalize(uint256)","e4e2ca59":"supportsEIP20Interface(bytes4)","e4e2d2ae":"changeScore(uint256,uint256)","e4e3466a":"AIToken()","e4e4c8c0":"eMTV()","e4e57b9e":"sellTokens(address,uint256,uint256)","e4e609de":"LogBuyCoins(address,uint256,string)","e4e663a9":"getStatLotteries()","e4e6de18":"setPaoContactAddress(address)","e4e713e0":"DTCC_ILOW_6()","e4e76c16":"setCryptoSoulContract(address)","e4e790b8":"withdraw_GIC(uint256)","e4e80c49":"SpudToRotator(uint256)","e4e85963":"tokenRemainPreSale()","e4e985a8":"getKycProvider()","e4e9bcca":"setEthPriceProvider(address)","e4ea58a5":"withdrawInviteRewardToOrder()","e4eab468":"getWarrantyPrice(address,string,uint256,uint256,uint256)","e4eacd70":"curentBallotId()","e4eaee4c":"setBool(bool,bool)","e4eba2ef":"supplylimit()","e4ec3762":"onChain(address)","e4ec404c":"AG()","e4edf852":"transferManagement(address)","e4ee07b7":"UtlToken(address,address,address,address,address,address)","e4ef2cef":"link(address,string)","e4ef3eaa":"SetEvaluate(address,uint8,uint8)","e4f02750":"listGlobalAuditDocumentsFrom(bytes32,uint256,bool)","e4f06100":"adminSetDiv(uint256)","e4f20fb2":"mintPresale(address,uint256)","e4f2487a":"salePhase()","e4f26633":"betStage(uint256,uint256[])","e4f37374":"pixels(uint32)","e4f3f47f":"BuyCurrentTypeOfAsset(uint256)","e4f4c554":"AddressDefault()","e4f627fe":"keysCount()","e4f6973f":"BIPOOH_DAO_32()","e4f7a076":"set3RoundTime(uint256)","e4f7de93":"isIcoComplete()","e4f84173":"defValue()","e4f843f9":"deprecateTurretSubtype(uint8)","e4f896e8":"proclaimAllInactive()","e4f8b908":"_payout(address)","e4f8c6fb":"YettaCrowdSale()","e4f95226":"getLastInvestors()","e4fa8fc3":"hash_of(address)","e4fab06f":"delegatedFwd(address,bytes)","e4fae421":"ALLOC_ECOSYSTEM()","e4fc6b6d":"distribute()","e4fcf329":"setBonusRate(uint256)","e4fe8eb1":"getUserBigPromoBonus(address)","e4ff0f18":"rocketshipReachedDestination()","e4fffb3a":"updateMaxTokensToDistribute(uint256)","e50007b9":"TerminateEmployee(address,address,uint32,uint8)","e5002347":"setLimitMaxCrowdsale(uint256,string)","e5002a05":"whitelistAddress()","e5027880":"fortyEndTime()","e50278a6":"sellAllAmountPayEth(address,address,address,uint256)","e5033268":"endPreICOTimestamp()","e5033ee4":"maxBridgeHeight()","e503f70d":"newArticle(string,string,string)","e5042271":"setNick(string,string)","e5043632":"ElectronicHealthRecordToken(uint256,string,uint8,string)","e5045002":"setSecurityWalletAddr(address)","e504862b":"assertEq30(bytes30,bytes30)","e5065522":"updatePermissions(address,uint256)","e506b9b7":"joule()","e5071b8e":"incrementCount()","e5075f4f":"ezpzToken()","e507d6dd":"getPlanActiveTime()","e507e7a4":"brandAccountsLength()","e508202d":"triggerLibraryEvent()","e5098e85":"eliminarEntidades(uint256)","e509b9a0":"initiateTransfer(string,string,uint256,uint256)","e509cac5":"_changeTokenAddress(address)","e50a32a9":"PriorityQueue()","e50a3bb1":"oraclize_query(string,string[],uint256)","e50ab759":"contractIndex(bytes32)","e50beffb":"voteStart(uint256)","e50d0473":"SetRank(uint8,address,uint16)","e50d2da1":"setSuperInvestor(address)","e50d8a8a":"deauthorizeMintRequester(address)","e50dce71":"testControllerApproveSetsAllowance()","e50dd26a":"contractTokenWithdraw(uint256,address)","e50dd478":"isFiscal()","e50e2f65":"EARLYADOPTERS()","e50ff8e9":"TestSportsG()","e5104307":"IsPlayer(address)","e5106ae9":"isValidNodalblockJson(string)","e51073f4":"withDrawInWei(uint256)","e510989a":"setNewDepositCommission(uint256)","e5113280":"RecipientStringUpdated(string)","e515a4d1":"gen0Limit()","e515cd38":"deliver(address)","e516f4dd":"LogOwnerChange(address,address)","e5173942":"PRE_SALE_SOFT_CAP()","e517fd54":"getBonusPercents(uint256)","e5189e2a":"minSumICOStage3USD()","e5193c48":"withdrawGalacticTokens(address)","e51949fb":"getMinAuditPriceSum()","e51a3b40":"mul(uint8,uint8)","e51a7826":"buyCore(uint256,uint256,uint256,bytes32)","e51ace16":"record(string)","e51bfd9a":"selfHybridizationPrice()","e51c3257":"isTokenRateCalculated()","e51d2093":"getSaleFee()","e51d5c33":"Bitstraq_Token()","e51dc14a":"setMinBidDifferenceInSzabo(uint256)","e51dfd90":"cancelSellOrder(uint256,uint256)","e51e3c61":"transferReserveFundTokens(address,uint256)","e51e88bd":"MintingManagerApproved(address)","e51f2c68":"change(address,uint256)","e51f95cc":"init_crowdsale(address)","e51fcfa2":"LLV_311_EDIT_4()","e51ff1fc":"iterateOverThings()","e520f09e":"tokensToMintInHold()","e520fc7e":"treasure()","e5212deb":"_buyIcoToken(uint256)","e521357c":"LocalsValidation()","e521889c":"distributePrizes(uint256,uint8)","e5225381":"collect()","e52269c2":"Ooredoo()","e523757e":"Cashback(address,uint256)","e524d618":"UBetCoin()","e5254036":"changeNameOperation()","e5258557":"setMigrateFeesDueToFork(bool)","e525af22":"TOAB()","e525c3d8":"dTRIGGER_NEXTWEEK_TIMESTAMP()","e5260958":"Defraycoin()","e5269bbf":"limitDefaultType()","e526d7a0":"getTeamAddress(bytes32)","e527217b":"Object(string,string)","e52858c6":"token_b()","e5286c80":"token1stContract()","e5291ac5":"getVMParameters(uint256)","e52b6a56":"getAmountBonus(uint256,uint256)","e52c0f24":"changeICOStartBlock(uint256)","e52c17a8":"test_increaseTimeBy800000_timecheck()","e52c66c1":"getTotalLosses()","e52c9da1":"giveaway(address,uint256,uint8)","e52d0404":"addressOfIndex(uint32)","e52d0659":"setPriceForBasePart(uint256)","e52e9f15":"isAddressLocked(address)","e52eb288":"buyFuel(address)","e52eb764":"updateVIPBoard()","e52efbf1":"getCompte_4()","e52f64ce":"releaseMany(address[])","e530db1c":"pool_percentage()","e531a9b8":"numOfUntransferableEcTokens(address)","e53229c7":"zasxzasxqa()","e5333b5e":"close_next_bucket()","e534155d":"holder()","e534a34b":"addThing(uint256,uint256,uint256,uint256,bytes32)","e534c676":"getRefillPercFor(string)","e5357b02":"ReturnCode(uint8)","e535ed35":"closeChannel(bytes,bytes,bytes)","e5362206":"hdiv(uint128,uint128)","e5362667":"getTotalTokenCount()","e5363ab8":"initialise(address,uint256,uint256,uint256,uint256,uint256,string,uint8,string)","e536a41f":"USD20Crowdsale()","e536c723":"lowestContribution()","e536f869":"pai_add(string,string)","e53767bd":"denied(address,address)","e537a195":"getSeatAvatarUrl(uint256)","e53831ed":"setSomeValue(uint256)","e5390e05":"thirdPeriodOfICO()","e53910a2":"TestNetReputationToken()","e5393f25":"GetSoftwareCount()","e53a22ac":"addSubMilestone(uint16,string,string,uint64,bool)","e53a8a5f":"GRAPE()","e53a8cf4":"getTokensLeft(string)","e53ae072":"PUCOINToken(address,uint256)","e53b373e":"TimeBankChain()","e53c4548":"transferOwner(address,uint256)","e53c9a5f":"cf_confirm(uint256,uint256)","e53cacba":"listOutEmployees()","e53cfed9":"setupMiniGame()","e53d4988":"WLLToken()","e53e04a5":"refillGas()","e53eb53d":"amountToSeedNextRound(uint256,uint256)","e53ecb79":"allocatedBalance()","e5408eae":"TEAM_RESERVE()","e5411525":"crowdsaleStartTimestamp()","e54135ac":"updateExchangeRates(uint256)","e542e7a3":"updateEtherCost(uint256)","e542e7c5":"newIdAuctionEntity()","e54384f9":"removeEntryManual(uint256,address)","e5438f5e":"FLiK(uint256,string,string,uint256,uint256)","e5449600":"unFreezeUser(address)","e544b52c":"setNextRules(uint256,uint256,uint256,uint256)","e545f941":"releaseToken(address)","e546299b":"activatePass(bytes32)","e5463032":"getWLAddress()","e546bb0c":"apiAddress()","e546d9c4":"removeTeam(address)","e548799c":"registerCrowdsale(address,address,uint256[8])","e548cf13":"betOnColumn(bool,bool,bool)","e548f086":"ETHOfCrySolObjects()","e549053f":"AnotherStorage(address)","e549114b":"stageOneCap()","e54919e6":"hasInitCard2()","e5494be1":"unlock2Y()","e5499e55":"LWFToken()","e549ec26":"safeDrain()","e54a29bb":"getRegisteredUser(address)","e54a9646":"netAddress()","e54aae13":"getMarketTopLevels()","e54c495a":"majorityReward()","e54c4f98":"getRefundValue(address)","e54d4051":"receiveInteger(bytes,uint256,uint16)","e54d62e9":"simDuration(bytes)","e54d8ccb":"Mappings()","e54ebe61":"updateBalance(uint256,bool)","e5514c9d":"MAX_PRESALE_TOKENS_SOLD()","e55156b5":"setFee(address,uint256)","e5515b55":"updateAssignedAudits(uint256)","e55186a1":"getUnit()","e551bff0":"PokerPayoutValue()","e55219c6":"Chromium()","e5522a5b":"getClassMintCount(uint32)","e5533790":"setBiddingComponent(address)","e554482e":"arrayLength()","e554a5ff":"closeBid(address,uint256)","e554af57":"BAJIDOR(uint256,string,uint8,string)","e5553b33":"GenChip(uint32)","e555c1a3":"sellMyTokens()","e556a08c":"validateToken(address,bool)","e557498b":"reFund(address,uint256)","e5575e61":"getTheLengthOfUserFreeze(address)","e557a18e":"activateHedge(address,uint256)","e557bb4e":"places(uint256)","e55834cb":"write(string,uint256)","e5583c59":"executeTxn(address,uint256,uint256)","e5589756":"Debug(string,address,uint256)","e5593b4d":"allocateTeamAndPartnerTokens(address,address)","e559afd9":"addToWhitelist(address,address[])","e559c724":"TEAM_VESTING_PERIOD()","e55a07b6":"setTiers(bytes32[],uint256[],uint256[],uint256[],uint256[],uint256[],bool[],bool[])","e55a07c2":"tokenSaleClosed()","e55a6ef6":"votingPeriodStartTime()","e55a7afb":"Gemmes()","e55ae4e8":"getPlayer(uint256)","e55b4aa8":"getBalloonCosts()","e55b55ce":"getPreSaleTokensAvailable()","e55b69b3":"startPostIco(uint256)","e55b8b62":"getPeerTokens(address)","e55c6d07":"getStartDateOfCampaign(bytes32)","e55db48e":"roundId_()","e55ed42e":"_phxToken(address)","e55f98f3":"Log1(uint128,string)","e55fae77":"setUpdatePeriod(uint256)","e56044c8":"incMemberBadRep(address,uint256)","e5604559":"UserUpgraded(address,uint256,uint256,uint256,uint256)","e560bf2e":"setOraclizeGasCost(uint256)","e5612b3b":"finishDistribute()","e5612d0e":"transferPaillier(string,address)","e561f28a":"cityIndexToApproved(uint256)","e562dfd9":"openRound()","e562f0ec":"setKYCRequiredToSendTokens(bool)","e5637956":"MIN_INVESTED_ETH()","e563d541":"delFrException(address)","e564bd4d":"accFoundation()","e564f88e":"tokensToIssue()","e564fd25":"setNotary(address,bool)","e56556a9":"getPlayerID(address)","e5656f9c":"updateMsgSenderBonusDrops(uint256)","e565b387":"FOUNDATION_POOL_ADDR_VEST()","e565beeb":"softMtcTransfer(address,uint256)","e565fd1b":"SetStorage(address,address)","e56646ae":"SmartPonzi()","e5664f65":"prePreSalePeriod()","e5665b57":"_softcap()","e566be4e":"EthRelief(address)","e566dfc6":"_handleFunds(uint256,uint256,address,uint256)","e567756f":"setDevelopmentAuditPromotionWallet(address)","e56860c3":"fundingLock()","e5689afa":"updateStorage(uint256,uint256)","e56988dd":"latestBidTime()","e569c1d4":"getMintOwner()","e56a9973":"marketCells()","e56adb5f":"IsWhite(address)","e56b3e68":"mediate(uint256)","e56b9dce":"GetPrize(uint256)","e56bb194":"calculateMyPercents()","e56c10a0":"ONTExchangeRate()","e56c174b":"getRate(address,address,uint256)","e56c8155":"initialiseMultisig(address,uint256)","e56c8552":"spinTheWheel(address)","e56d3fea":"developer_add_address_for_B(address)","e56e4776":"avgSalesToCount()","e56e56b2":"sellCard(address,uint256,uint256,uint256,uint256)","e56e60f6":"SingularityTest12()","e56ee3c1":"cityPrice()","e56f3815":"isKnownOnly()","e5700ddf":"jack_winner()","e5702701":"minSellRateInPrecision()","e57053cd":"airdropWinTime()","e5707fa2":"teamContact()","e570be18":"DVIPBackend(address,address)","e5714ea3":"insertCLNtoMarketMaker(address,uint256)","e571c35e":"ReverseRegistrar(address,bytes32)","e571fd2d":"addPrescription(uint256,string)","e5720f2d":"getCredibilityScoreOfClaim(bytes12,bytes12)","e572dee5":"bountyTokens(address,uint256)","e5731b77":"UnpackRevocation(bytes)","e5734c57":"setPhase1DurationInHours(uint256)","e574015c":"auditSupply()","e57405e2":"EMISSION_FOR_TEAM()","e575c5cb":"assertOnlyTo(uint256)","e575df72":"getUserStatus(uint256,address)","e576038f":"addNewSampleType(string,uint256)","e5760520":"bountyWallet()","e5766e84":"initPayoutTable()","e5769ab9":"getLastPresser()","e5775515":"getUserWallet(string)","e577d2c2":"updateEthToTokenOrderWHint(uint32,uint128,uint128,uint32,int256)","e5781b71":"SatFix(int256,int256,int256)","e5782fd5":"setFeeStructure(uint256,uint256,uint256)","e5789f5f":"getTotalLevelValue()","e5791c3e":"mustHoldFor()","e5796716":"restrictTransfert()","e579ebeb":"chAirDropFshare(uint256)","e57a68da":"StephenHawking()","e57ac748":"resolveDisputeSeller(string,address)","e57b921d":"_createNumber(string,uint256)","e57bc079":"DrawAddr()","e57c09bc":"contentById(bytes32)","e57c78ec":"unregisterPresale(address)","e57c8d1b":"dummyAgent()","e57d4adb":"approvedOrders(bytes32)","e57d880a":"externalPurchase(address,string,uint256,uint256,uint256)","e57e31fa":"approveSubmission(address,address)","e57e5741":"onXon()","e57e6593":"createClaim(string,string,address,uint256,string)","e57ea16d":"checkValueSent(bytes,bytes20,uint256)","e57ebc0f":"FRPToken()","e57f5a1d":"removeFromStud(uint256)","e58018c5":"openSaleEndTime()","e5807e06":"unfreezeBoughtTokens(address)","e580b2b0":"presaleEnded()","e580f47b":"lotteryId()","e580f6ab":"createGame(uint8)","e581002e":"strategybacktest(uint32[],bytes32[],bytes32[],uint64[],bytes32)","e5815b33":"JohanNygren()","e58172b1":"cardCost()","e5820af7":"pushtx(address,uint256)","e582645e":"isTokenSaleRunning()","e582b7e0":"lastBidAmount()","e582dd31":"stored()","e58306f9":"adminMint(address,uint256)","e5834b4d":"setShareactive(bool)","e5839836":"isFrozen(address)","e585f69f":"TokenResolver()","e587fb71":"setTreasureBox(address,bool)","e588a2bb":"ChannelWithdraw(address,address,uint32,uint192)","e5893cbe":"Register(address,bool)","e58a6509":"SMTfund()","e58ae45b":"migratePhraseData(uint256,uint256,uint256,uint256,uint256)","e58b0eb1":"WinkelERC20()","e58b5ab2":"setFinishedTx()","e58b69f2":"getCompte_6()","e58ba9e4":"stealCardWithSocialIdentity(uint256,uint256)","e58c68bc":"MAX_GEN0_GIRLS()","e58c8c5c":"checkParticipantStatus(address)","e58ca07e":"IntegratedMoney()","e58cd3cb":"setTokenCapInUnits(uint256)","e58d116b":"addConfirmation(bytes32)","e58d478e":"btcAddrPubKeyUncompr(bytes32,int256,bytes32,int256)","e58dd55a":"endThirdBonus()","e58dede7":"_tokenAllocator()","e58eda1b":"ARTWORK_AUCTION_DURATION()","e58ef8a8":"executeTransfer(address,address,uint256)","e58f0289":"MANGGAHTOKEN()","e58f2623":"getLotteryData()","e58fc54c":"withdrawForeignTokens(address)","e58fdd04":"isFeed(address)","e5910f04":"setCourceSale(uint256)","e591253c":"refundPreICO()","e59160e3":"nomin()","e591fa26":"getProjectFeedbackWindow(bytes32)","e5920ab5":"getNoVotes()","e592172e":"test_twoInvalidEqString()","e5926ddc":"getSaleLength()","e592f95a":"getRewardWinnings(address,uint256)","e593428f":"PURCHASE(bytes32,uint256)","e5949b5d":"channels(uint256)","e594ad35":"assignCore()","e5962195":"blocked(address)","e596d811":"approveBatchTransfer(address)","e597a27f":"getNumberOfBlocksRemainingToWin()","e597f402":"create(bytes1,bytes32,bytes)","e59843ec":"allowAutoInvest(address)","e5994905":"transferTokenFrom(address,address,address,uint256)","e59997c9":"getFmmsDetail(uint256)","e599a767":"GGG()","e59a29a6":"getStakePerDraw()","e59af25b":"buy_spice_melange()","e59b0e14":"testIsNull(bytes)","e59bcf52":"subLockValue(address,uint256)","e59c4fa3":"smallUintFunc(int256,uint8,uint256)","e59c5e56":"Filled(address,uint256,address,address,uint256,address,uint256,uint256)","e59c9ada":"getBonuses(uint256)","e59cef17":"RaisedFunds()","e59cf926":"FOUNDER_ADDRESS3()","e59d2b7f":"unfreezeTeamWalletBlock()","e59d4912":"setOracleInterval(uint256)","e59d843a":"Replicator(bytes,uint256,uint256,address)","e59de295":"setItemPerPage(uint16)","e59de3a5":"drawToken(address)","e59e1ca6":"getBrickBuilders(uint256)","e59eee2e":"PRE_ICO_MIN_DEPOSIT()","e59f611f":"InputLimit(uint256)","e59ff828":"createOrder(uint32,uint32,uint256,bool)","e5a01e69":"getWeaponNumber()","e5a07419":"sellDividendPercentEth()","e5a078a7":"cancelRegistration()","e5a17818":"cancelSeller(bytes32,uint256)","e5a1eac2":"setSellDividendPercentageFee(uint8,uint256,uint256)","e5a23e7e":"changeBirthSettings(uint256,uint8,uint8)","e5a252b1":"playerTempReward()","e5a27038":"Pluton(uint256,string,uint8,string)","e5a284f8":"roundFourBlock()","e5a31c5d":"canGrantVestedTokens(address,address)","e5a3363c":"luckyVoters(uint256)","e5a34f97":"getFullround()","e5a3c0ad":"addPrivateSaleTokens(address,uint256)","e5a3c771":"expiredLockPeriod()","e5a4bed3":"getInterest()","e5a5fbc8":"crowdsaleInProgress()","e5a62ffc":"Tile()","e5a6b10f":"currency()","e5a6fadd":"ReinsureSeveralDeaths(bool)","e5a70ef7":"feeMultiplier()","e5a71eb6":"Itterator9000Ultra()","e5a749e8":"needSurvive(bytes32)","e5a7b51f":"parentChange(address,uint256)","e5a82fe7":"REXEN(address)","e5a85478":"getUserTXCount()","e5a912c7":"xdest()","e5a93dd8":"inCirculation()","e5a9d6b0":"get_registrant(bytes32)","e5aa3d58":"i()","e5ab8be0":"isCollaboratorOrOwner(address,uint256)","e5ac7291":"lockAccounts(address[],uint256)","e5ac808e":"checkProof(bytes32,bytes32,bytes32[],uint256)","e5aceac5":"getWorlCupByID(uint256)","e5ae7721":"submitPayment(bytes32,bytes32[],uint256,uint256,uint8)","e5af0e89":"setNewTokenURI(string)","e5af18c5":"score(bytes32)","e5af350e":"reloadWhiteByName(uint256)","e5af3a35":"throwsSaleWalletIncorrectMultisig()","e5af48d8":"isApproved(address,address,uint256)","e5af8d92":"iiinoTokenAddress()","e5afe3e6":"tokenPrices(uint256)","e5b02393":"addSaler(address)","e5b02447":"findTopNValues(uint256[],uint256)","e5b0ee4d":"changeVestingPeriod(uint256)","e5b2169f":"Registry(string)","e5b28c07":"weeksFromEndPlusMonth()","e5b2a58d":"SinoeCoin()","e5b4003b":"grantPoolRole(address)","e5b5019a":"MAX_UINT()","e5b598d9":"hasChampSomethingOn(uint256,uint8)","e5b5a527":"giveStellarReward()","e5b5fe72":"Put(address)","e5b6b4fb":"Securities_5()","e5b6eac4":"teamUnlock2()","e5b73e08":"payer(address)","e5b754fb":"Redeem(address,uint256,uint256)","e5b7ec88":"setVoteCut(uint256)","e5b82bba":"dayTokenFees()","e5b8d6e0":"withdrawTokenRefund(uint256)","e5b9a74c":"submit(address,string,string,string)","e5ba08e5":"_baseDebt(uint256,uint256,uint256,uint256)","e5ba0b8a":"sellOffer(uint256,uint256,address,bytes32)","e5bb6575":"blockUser(address,address)","e5bb9fb9":"cancelTx(uint8)","e5bc7be0":"replaceModuleHandler(address)","e5bcb303":"getAccessorPurpose(address)","e5bf1b75":"getElectionId(string)","e5bf93b9":"balanceEther(uint256)","e5c0de3e":"Labereon()","e5c0fa69":"torchDividendsOf(address)","e5c19b2d":"set(int256)","e5c2205e":"_calculateTokens(uint256,uint8,uint256)","e5c31ddc":"rejectTransfer(uint256,uint256)","e5c361b0":"totalTokensICO4()","e5c389cd":"setConfig(uint256,uint256,uint256,uint256)","e5c42fd1":"addStakeholder(address)","e5c46869":"refPercentage()","e5c46944":"MultiSigWallet(address[],uint256)","e5c5dabb":"CSCResourceFactory()","e5c60091":"highest_bid()","e5c60d0b":"INVESTMENT_FUND_TOKENS_SUPPLY()","e5c6258d":"withdrawCrowdsaleTokens(address,uint256)","e5c774de":"houseEdgeDivisor()","e5c7bc6c":"treesOnSale(uint256)","e5c7e509":"testThrowTransferDisableNotEnabled()","e5c8b03d":"renounceSigner()","e5c8eb2f":"mytesttokenToken()","e5c91047":"addMeByRC(address)","e5c92020":"freezeFrom(address,uint256,uint256,uint256)","e5c98b86":"RoundSet(uint64,address)","e5c9c2ed":"_initialize(address,address)","e5ce8200":"withdrawForMkt(address)","e5cf2297":"amountOwed(address)","e5cf45b0":"FruitionToken()","e5cfd1bc":"player3Timestamp()","e5d00bee":"initiateCrabPartData()","e5d00f1f":"checkDepositQuest(address)","e5d02cd0":"PriceReturn(uint256,uint128)","e5d0713b":"maxGamesPerBlock()","e5d0c1bd":"LATToken()","e5d17171":"skl()","e5d2ce2f":"setCategory(uint256)","e5d3d9d7":"getBuyArray(address)","e5d4610f":"generatorTransfer(address,uint256)","e5d5c898":"isSuperior(bytes32[],bytes32[])","e5d607f3":"SocialLendingToken(uint256,string,string,uint256)","e5d71cfe":"rewardLottery(bool)","e5d787f2":"moreTokenPerEtherForPresaleRound()","e5d8011f":"getCurrentTokenAmountForOneBtc()","e5d8103e":"setTotalBonuses(uint256)","e5d824a7":"addData(uint256)","e5d8f1ca":"removeAmount()","e5d90d94":"LuckchemyToken()","e5d9dac4":"assetTransfer(address,uint256)","e5da2717":"BOBToken()","e5dada63":"_pushRoomNight(address,uint256,bool)","e5db1a68":"bytes32Func(bytes32)","e5db2612":"addPrivatePurchaser(address,uint256,uint256,uint256)","e5db7a20":"mainnetAccountDict(address)","e5db9b49":"getJobInvoices(uint256,uint8)","e5dc476f":"getVideoGameCurrentPrice(uint256)","e5dc67d6":"setGameCloneFee(uint256)","e5dcc824":"getInfo1(address,address)","e5dd05ab":"primaryLedgerCount(string)","e5dd90a5":"HumanStandardToken(uint256,string,uint8,string)","e5ddb19d":"_applyLevelBonus(int256,uint256)","e5de0b89":"EGGS_TO_HATCH_1FALCON()","e5de2925":"endPreSales()","e5df3dd0":"unfrozen(address,uint256)","e5df669f":"recoverAddr(bytes32,uint8,bytes32,bytes32)","e5df7b10":"getBoughtTokens()","e5dfbe78":"setCreateDividendPercent(uint256)","e5e04a33":"SendResult(uint64,uint64)","e5e123f1":"funeral(bytes32,int256)","e5e1a202":"endTimeOne()","e5e231dd":"pauseTokens()","e5e288e5":"sendTransaction(address,uint256,bytes)","e5e2fd7b":"balanceTreasury()","e5e38fc7":"test_twoTrueAndFalseAssert()","e5e3ac4f":"removeAssociatedAddressDelegated(address,address,uint8,bytes32,bytes32,uint256)","e5e41a63":"publishOption(uint256,uint256)","e5e45b16":"notifyTempBreach(int256)","e5e4807f":"setPriceToPreSale()","e5e51bd7":"getOrderTokenCompletedAmount(uint256,address)","e5e53493":"requestKinTokenOwnershipTransfer(address)","e5e5cfac":"Altcoin()","e5e5dff1":"cancelBounty(uint256)","e5e5e5d6":"emitGenericProposal(string)","e5e6a0aa":"ticketTransfereesAmount(address)","e5e75fee":"fountainContractAddress()","e5e792de":"_pro(address,uint256)","e5e7a136":"CEO_SHARE()","e5e7b82b":"ethEurRate()","e5e7c276":"isData()","e5e7fa53":"div(uint96,uint96)","e5e88590":"unholdSubscription(uint256)","e5e9a9bb":"registerUsers(address[])","e5ea1201":"changeTicketType(uint256,string,uint256)","e5eabf14":"playInternal(address,uint256,uint256,address,uint256)","e5eb9d7a":"SilverMoon()","e5ec8df3":"calcTimedQuotaByPower(uint256,uint256,uint256,uint256)","e5ed1d59":"startGame(uint256)","e5ed31cb":"updateBytes32(bytes32,bytes32)","e5ed44c2":"Koplak()","e5ed78bb":"setDateStart(uint256)","e5ee8dae":"publicGetElementOffer(uint256,uint256,uint256)","e5eee9be":"longJudge(uint256,address)","e5ef0b95":"BitRRToken()","e5f06556":"fillRequest(bytes32,string,uint256)","e5f171d6":"BLOCKCHAIN_DEPOSIT_BETA()","e5f2806a":"createPlayer(uint32[7],uint256,address)","e5f363f8":"FTTtoken()","e5f3b2dc":"advisorsTokensWallet()","e5f3e7b5":"placeBet(uint256,uint256,uint256,uint256,uint256,bytes32,bytes32)","e5f3fcb1":"alias_price()","e5f4906a":"moveTokenICO(address,uint256)","e5f59e7c":"setIsChargingManagementFee(bool)","e5f5d05b":"tokensRaisedRound()","e5f6186d":"maxContributionWei()","e5f643cf":"InvestorWhiteList()","e5f65c71":"initialBlockCount()","e5f6a908":"AddrCommunityDistribute()","e5f6b137":"getOutCar(string,uint256)","e5f6d376":"updateStatusViaTokens()","e5f6f252":"getUserNumEntries(address,uint256)","e5f6f716":"thirdChainETH()","e5f796fd":"CONTRIBUTION_END()","e5f79bee":"PRE_SALE()","e5f8ce92":"setPercent2(address,uint256)","e5f92973":"conclude()","e5f952d7":"rewardMathGeniuses(uint256,uint256)","e5f9a40f":"TRHToken(address,string,string,uint256,uint256)","e5f9ec29":"left51(uint256)","e5f9f510":"BetMe(address,uint256)","e5fb08c0":"tokenExchangeRateMile2()","e5fb9211":"constructLeaf(uint256,address,uint256)","e5fd6364":"unregisterPublicKey(uint256)","e5fdac45":"presentMissingChunk(bytes)","e5fe3d7a":"aprovaPagamento(bool)","e5fe4f31":"buy(uint8,bytes32,bytes32)","e5fe7870":"vote(string,uint128,uint256)","e5ff2e8a":"mintTeamTokens()","e5ff7674":"restartPresale()","e5ffea8e":"testCalculateNeededCollateral()","e5ffeaf6":"fixAddress(address,bytes32)","e600c817":"verifyUser(string)","e6025572":"ShadowBox()","e602af06":"confirmChangeOwnership()","e604cf9f":"get_all_squares()","e6072d5a":"BONUS_MID_QTY()","e607a638":"DataController(address,address)","e608433b":"weiForRefundPreICO(address)","e608ca67":"calculateSubscore(address,int16,int16)","e608d3e5":"marketingCap()","e609120a":"intercrypto_convert(uint256,string,string)","e609348a":"upgradeOwner(address)","e60a33aa":"userEndGame(uint32,int256,bytes32,bytes32,uint256,address,bytes)","e60a72bc":"ReferalsTokenHolder(address)","e60a955d":"setActive(uint256,bool)","e60aafab":"setIcoStatus(uint256)","e60b0cad":"endPreICOStage1()","e60b1424":"bytes32ToUint(bytes32)","e60b2c9a":"SALE_2WEEK_BONUS()","e60b7ff7":"batchTransferToken(address,address[],uint256)","e60c11a0":"subContractBalance(uint256,uint256)","e60d3caf":"updatePowerDayRate(uint256)","e60dbaae":"Jump()","e60f1ff1":"getExit(uint256)","e60fb021":"publishOwner()","e60fd342":"getCreateSharesFxpValue()","e6107cbb":"isBurnApproved()","e6108fc9":"increaseLockBalance(address,uint256)","e61109fd":"setFiscalVerify(uint256,uint256,uint256,bytes32)","e611ad32":"CourseBaseOnIdStudentFunct(uint256)","e6120842":"warningERASEcontract()","e612a4b6":"get_order(string,uint256)","e612c0ad":"team2()","e6131706":"updateTransaction(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","e6131a64":"UpdateBeneficiary(address)","e6135ffe":"_removeIndex(uint256)","e6136d84":"icoBegintime()","e61387e0":"knc()","e6138b37":"TESTBRB()","e613d3b2":"getParentUser(address)","e6153d1b":"mint(string,bytes16,uint256,uint32,address)","e615ed91":"AragonTokenSaleTokenMock(address,uint256)","e61604cf":"liquidateBorrow(address,address,address,uint256)","e616c975":"GetAccountIsFrozenCount()","e6175794":"MaPToken()","e617f204":"setWhiteListAdmin(address,address)","e618f558":"TempTokensSend(address,uint256,uint256,uint256)","e6197f41":"setTokenSaleFinished()","e61a3c73":"GuDuFengCoin(uint256,string,uint8,string)","e61ab6c9":"accountPubPreSale()","e61b6557":"reserveOwner()","e61b762b":"cancelAllSellOrders(address,uint256,uint256)","e61b959e":"dev_outStream()","e61c51ca":"topUpGas(uint256)","e61c6320":"_recoverAddressFromSignature(bytes,bytes32)","e61ca819":"indexToAddress(uint256)","e61d5d50":"raisedOBR()","e61fde91":"BiciDevuelta()","e6206711":"SendEthOn()","e6207611":"setChests(address)","e6213127":"deprecate(bool,address)","e621350d":"getDiscountAndSupply()","e621b149":"softCapUSD()","e621b5df":"redeemEther()","e6229c14":"_createBid(address,uint256,address,address,bytes32,uint256,uint256)","e622abf8":"LOCK_END(uint256)","e6232ba1":"updateEndDate(uint256,uint256)","e6234260":"depositCollateralOnBehalfOf(address,bytes32,uint256)","e623a1a6":"kcck256straddadd(string,address,address)","e623a93b":"votesForAnswer()","e623c4ac":"addressInSwap(address,address)","e6240deb":"activityCount()","e62420d9":"getChild(address,uint256)","e62444e1":"submitJRH(uint256,uint256,bytes32,uint256,bytes32[],uint256,bytes32[])","e624b02a":"changeHold(address,uint256,uint256)","e624d199":"partnerSaleWallets(uint256)","e625215c":"withdrawStake(uint256,bytes)","e6256509":"SPNToken()","e62580cb":"MYToken(uint256,string,uint8,string)","e6259f53":"timeArrayOf(uint256)","e6281254":"FundsMoved(uint256)","e628dbf9":"changeTiming(uint256,uint256,uint256,uint256,uint256,uint256)","e6293e23":"burnerAddress()","e629837c":"updateAndSafeTransferFrom(address,uint256,string)","e62a4ac9":"setBUI(bytes32,uint256,int256)","e62af875":"isContractOwnerLocked()","e62b795c":"addCourse(string,string,string,string,uint8,uint8)","e62bd899":"mintStart1()","e62c04bb":"OwnershipTransferred(address[],address[])","e62c2f9c":"get_location()","e62c9df9":"participantToEtherSpent(address)","e62cc611":"ETHER_HARD_CAP()","e62cd55c":"test_oneInvalidFalseEq()","e62d64f6":"withdrawableBalance()","e62d809d":"subdividendsOwing(address)","e62d909f":"TargetCreated(address)","e62e3c07":"getTransactionDetails(bytes)","e62eea47":"startSettling(bytes32)","e631b536":"fields(address,uint256)","e631e9b3":"solveIO(uint256,bytes32,bytes32,bytes32,bytes32)","e63227b0":"freezeGlobalTansfers()","e6324270":"profilParticipant(uint256)","e632c2f3":"totalPurchased()","e633cefe":"itemInfo(address,address,uint256,bytes)","e6346867":"imaxChainToken()","e63697c8":"withdraw(uint256,address,uint256)","e6369e41":"Timestamp()","e636bc3c":"addRoyLuxList(string,string,uint256,uint256)","e6378d3a":"joinGame(bytes32,string)","e637f824":"GetPlayerDataAt(address)","e638d76d":"migrateDomain(bytes32,uint256)","e638f372":"getDIVDPayoutPercent()","e639481a":"getUpperBoundBlocksTillGameEnd()","e63988bd":"getContributorInformation(address)","e63a6788":"miningOnePlat()","e63b029d":"finishSalvage(address)","e63b681e":"redeemExternalToken(bytes32,address)","e63b6b87":"DipTokensale()","e63c83c1":"getTotalWithdrawn(uint64,address)","e63d38ed":"disperseEther(address[],uint256[])","e63d4957":"totalLimitUSDWEI()","e63da5f7":"bootstrap2()","e63da84c":"getBattleRandom(uint256,uint256)","e63df4a7":"createJobEscrow(bytes16,address,address,uint256,uint256,uint32,uint32)","e63edfef":"Learn()","e63fb7d2":"getAdText(uint256)","e6400bbe":"suspend()","e64044c0":"payoutKeys(uint256)","e640663a":"removeFromOwnershipAuctionTokenIDs(address,uint256)","e640d5a8":"PubAccepted(address)","e6416f4e":"sendFoo(address,uint256,bytes)","e641bde1":"addInvestor(address)","e642b7b6":"isWhitelistOnlyStatus()","e642b900":"Bugcoin()","e642b9be":"MTP_PER_ETH_PRE_SALE()","e643197b":"TRY_Omnidollar()","e643d63c":"_setProposal(uint256,string,bytes32,bytes32,bytes32,string,uint256,uint256)","e6441201":"set_foo(string)","e644d886":"ico3total()","e644f60b":"isFresh(string)","e6452f64":"TGEDeployer(uint256,uint256,uint256,uint256,uint256,uint256,address,address)","e6456a30":"HARDCAP_ETH_LIMIT()","e646350d":"getTokensAvailableForSale()","e6468b9f":"mCoinPerBlock()","e6470fbe":"updateDefaultPayment()","e6471555":"remForSalesBeforeStageLast()","e64853c4":"polls()","e648ce75":"setSelfClaim(bytes32,bytes)","e64906a4":"setTokenForPreSale(uint256)","e64a4e27":"updateDealConditions(uint256,uint32,uint32,bool,uint256)","e64acfa4":"getRealValueToReturn(uint256)","e64e3241":"mint(bytes32,bytes,uint256[],bytes,bytes)","e64f15a2":"deleteTask(bytes32)","e650672b":"setGreenToken(address)","e6506873":"bookingMetadataForKey(bytes32)","e650ca40":"firstWeekBonusInWeek()","e6511ce2":"createCodeContract(string)","e6512ea2":"fundBounty()","e6514de2":"PreSaleLimit()","e6519a35":"getCreationTime()","e6527376":"OneWorldCryptoCoin()","e65284f1":"getRealPriceSpeed()","e652ca86":"LowcarbonToken()","e652f4cc":"getVoteCount(address)","e6530b97":"addArbiter(address,uint256)","e653d52d":"approveProxy(address,address,uint256,uint8,bytes32,bytes32,string)","e653d5d3":"GlobalStorageMultiId()","e653ec6a":"unsubscribeFromPool()","e6544b87":"ICORatio()","e65500e9":"startincreaseWithdrawalTeam()","e6560c94":"_saveBonus(address,uint256)","e6562fe1":"approveForwardedAccount(address,address,string)","e6569b1e":"getConID()","e657807b":"endIco()","e658d221":"claimPlotMultipleWithData(uint256[],string,string,string,string)","e6591f4e":"setNSFW(uint8,bool)","e65a0117":"earn(uint256)","e65a2e7f":"forceEmpty(bytes32)","e65af219":"PlusCoin()","e65b00b6":"Confirmation(address,bytes32,bool)","e65b1fd0":"getConsecutiveDeaths()","e65b490d":"_rewardWinners()","e65b743e":"dispatchGains()","e65b782f":"getCurrentTranche()","e65b96a7":"MyDanaToken()","e65b99c6":"uservalue()","e65bbceb":"makeAdoptionRequest(bytes5)","e65c1244":"holderEthers(address)","e65ca2fe":"Crowdsale(uint256,uint256,uint256,uint256,uint256,address)","e65d1522":"fromWei(uint256)","e65d19ca":"createInactiveEdition(uint256,bytes32,uint256,uint256,uint256,address,uint256,uint256,string,uint256)","e65d6b49":"getCommission()","e65d9717":"pushVendor(string,address,bool)","e65da9a2":"PROMOTION_ACCOUNT()","e65de3ca":"removeTitleTransfer(string)","e65dea55":"validate(uint256,uint256,uint256,string,string,string)","e65e63ed":"secondsaleclosingTime()","e65e73e2":"oneavl()","e65e95a8":"token_address(address)","e65f0246":"updateCountryHoldersCount(uint256,uint256)","e65f1d98":"bigLoop(uint256)","e65f2a7e":"enroll()","e65f5ea4":"distribute10MT(address[])","e6601fb4":"viewFunds(address)","e660c7aa":"PresaleAddress()","e660dd54":"compWallet()","e661a98f":"ecosystemtoken()","e661b3d5":"returnStatus(uint256)","e662bd25":"doTransfer(address)","e662e9af":"getPersonalStakes(address,address)","e662ff97":"sellMyTokensStocks()","e6634e41":"tokensPerEthAtRegularPrice()","e664214a":"releaseUnlocked(address,address,uint256,uint256)","e6642528":"BitcoinIndigo()","e664725b":"bn128_add(uint256[4])","e664755b":"withdrawAttacker()","e664d8e8":"showhospital(uint256)","e664e1e0":"getAddressTwo(address)","e6657008":"TicketsInGame()","e665dba0":"addAuthorizedExternal(address,address)","e66623ad":"ETbankWord()","e6662e2b":"UrbitToken(address,address)","e666767b":"getPlayerBetForCurrentPlayRound(address)","e6678f33":"updateReferralBonusRate(uint256)","e66825c3":"pricePerUnit()","e668a547":"SingularityTest8()","e668a7af":"buyFrom(address,uint256)","e668e1f3":"noContestTime()","e6690fb1":"nextAuction(uint256)","e6691249":"getCompte_5()","e66a5e6b":"waveCap1()","e66a6b22":"isSigned()","e66aa720":"pureBalance(address)","e66bf416":"DLK()","e66c4175":"LargeCapStartTimeChanged(uint256)","e66c66d9":"setMonsterCreatorAddress(address)","e66caeb4":"payFortune(uint256)","e66d1b84":"countHoldAmount(address)","e66d4694":"gymContract()","e66d9874":"REQUEST_REJECTED_BY_HOST()","e66dda4e":"wallocked()","e66dde38":"startRound(bool)","e66e00f8":"getAdminDashboard()","e66f51fd":"AxieERC721Metadata()","e66f53b7":"curator()","e66f6e75":"getIsAttack()","e66f7bba":"oracleItQuery(uint256,string,string)","e670f7cd":"checkHash(string)","e6714f63":"eth_min()","e6717d3f":"setPresidenteDeMesa(bytes32,uint256,bytes32)","e671ac23":"getMonthClaimed(address)","e671f510":"onEtherandomExec(bytes32,bytes32,uint256)","e6722531":"checkBoosterQuest(address)","e672eb49":"GetBetInformation(uint256)","e673f646":"setContributor(address,address,bool,uint8,uint8,address)","e6744035":"booleanToUInt()","e6748da9":"setBytes(bytes32)","e674a0bd":"unlock(address,address)","e67524a3":"mintTokens(address,uint256,string)","e6758649":"revokeStakeholderConfirmation(uint256)","e676d53f":"GRAD()","e6774e1e":"setCapTab(uint256,uint256)","e677d67d":"decode(bytes,uint256)","e679366f":"setExchangeTime(uint16,uint8,uint8,uint8,uint8,uint8)","e67ad254":"airBegintime()","e67bcfb6":"viewPreSaleCancelledList(address)","e67c4f96":"_createItem(string,address,uint256)","e67cdfb7":"moveOldUser(uint256)","e67d35c6":"UmeTravelNet()","e67d5b16":"SpeedJump()","e67e04f9":"startAcceptingDonation()","e67e3d56":"ethTaxRate()","e67e8aaf":"cliffPercent()","e67eed44":"getTicketOwner(int256,uint256)","e67f3cde":"about(address)","e67fcd10":"createSale(string,uint256,uint256,uint256,uint256)","e6807ca9":"checkBlacklist(address)","e68122e2":"createConsent(address,string,string)","e681e906":"_disableModule(bool)","e681f989":"saveMetaData(address,bytes32,bytes32)","e6821bf5":"videos(uint256)","e6824b0d":"REAPER_INTREPID()","e682c9ea":"rescindVote(bytes32)","e682e290":"getWhitelistStatus(address,address)","e682e2b2":"PingToken()","e6838ffa":"CbDataStandardToken(uint256,string,uint8,string)","e684aa5c":"amountAlreadyPaidBack()","e684d75d":"from_Initialisation_to_Lifecycle()","e685f2fe":"SilcCrowdsale(uint256,uint256,uint256,address,uint256,uint256)","e686b89a":"stage_2_price()","e6885aad":"Notary()","e688aab4":"changeOperative(address)","e688d097":"activekey(address)","e688f89d":"getMax(uint256)","e6890105":"addRefundTransaction(uint256,uint88)","e6891995":"KStarCoin()","e6891a55":"underwritePriceOf(uint256)","e6898a7d":"getSex(uint256[2])","e689928e":"seventyeight()","e689aa66":"isAllocated9()","e68a471d":"getLatestTokenPayday(address,address,address)","e68a555d":"UpdateUserPELOAmount(address,uint256)","e68a655c":"setEtherDeltaFees()","e68a7c3b":"getAccounts(uint256,uint256)","e68a9610":"releaseTokensTo(address,address)","e68c32b3":"cgadmin(address)","e68d3ae3":"escrow(uint256,string,address,uint256)","e68e64cb":"getCurrentUserReward(bool,bool)","e68f05fe":"SetCrowdsaleAddress()","e68f08a0":"MatchGetted(uint256,bool,uint256,uint256,uint256)","e68fb207":"makeOrder(address,address,uint256,uint256)","e690833a":"getPropertyRatingTuple()","e690d9bf":"Rollercoaster()","e6917e67":"tierOnePurchase()","e691bed4":"get_arbits(address,address)","e693e4d1":"neironixProfitAddress()","e69405fd":"_endDutchAuction(uint256,uint256)","e69432c8":"getMyNormalDragons()","e694d107":"getlastDividendPoints()","e694f694":"distributeLRNX(address[],uint256)","e69506aa":"Tokens_Per_Dollar_Denominator()","e6955d7c":"XYCC()","e6957514":"mergedMinerValidatorAddress()","e695c00c":"assertEq29(bytes29,bytes29,bytes32)","e696d10d":"processPurchase(address,address,uint256)","e696fb9a":"_6_friends()","e696fd64":"change_ico_finish(uint256)","e6972dbb":"readEventFromDatabase(uint64)","e6979b90":"multiAdd(address[],uint256[])","e697b5d8":"referrals(address,uint256)","e69852d0":"getUserNameOf(address)","e698816f":"getTokenIdOfCR(string)","e69932e5":"getFreeSeeds()","e6997f6d":"rootUTXOMerkleTreeHash()","e699e8c3":"removeDefaultOperator(address)","e69a2d9a":"Lent(uint256,address)","e69b414b":"issuedTokensAmount()","e69b9b65":"exchangeableTokensFromSale()","e69d09cf":"releasedForTransfer()","e69d27a8":"lifeFactor_v()","e69d849d":"donate(address,uint256)","e69e04b3":"defaultPrice()","e69e4640":"calculateBalance(uint256,uint256,uint256)","e69e9337":"PERSONAToken()","e69fde41":"KentraToken(uint256,uint256)","e69ffce8":"changeRegulator(bool)","e6a0525f":"getStudentID(bytes)","e6a1e811":"newBet(uint8)","e6a27cf2":"getUserEarningsInfo()","e6a33268":"secondRate()","e6a3afe8":"sendTreasuryTokens()","e6a43d63":"crowdsaleSoftCap()","e6a45026":"fetchStageIndexBySnapshotBlock(uint256)","e6a50d84":"getAddressFromIndex(uint256,uint8)","e6a5d78d":"_getMerkleRoot(bytes32,bytes32[])","e6a605df":"PreTgeEnable()","e6a6d4c8":"getExecutedTransactions()","e6a7638c":"eucledianDistance(uint256,uint256,uint256,uint256)","e6a8fe04":"evHarvest(address,uint256)","e6a9026b":"submitTransaction(address,uint256,string,bytes)","e6a9627c":"setAgentAddress(address,address)","e6a9b2d8":"createTAO(string,string,string,string,bytes32,address,uint256)","e6aa216c":"getExchangeRate()","e6aa96a5":"CRS()","e6aaae81":"tokensSoftCap()","e6aac98f":"currentDayTS()","e6ab96ed":"unstakeContent(bytes32)","e6abaaba":"tier_cap_2()","e6ac17a1":"tokens_total()","e6acca00":"_finishBet(address)","e6acf0c1":"determineOutcome(bytes32,uint8[],uint8[])","e6ad204e":"vestingAccounts(address,uint256)","e6ad5bc7":"getFrozenTimestamp(address)","e6adde32":"setIsHiddenMessages(bool)","e6ae0536":"UpdateBackedAmount(uint256)","e6ae1a97":"getTokenAmount(address)","e6ae89b4":"getPlayerInfoInRound(uint256)","e6ae92b0":"getItem(address,address)","e6ae967b":"updateOrder(bool,uint32,uint128,uint128,uint32,int256)","e6af2d5d":"TRICToken()","e6af35f0":"calculateFee()","e6b09e92":"setAd(string,string)","e6b1602f":"buyOneRabbit(uint256)","e6b18f52":"LongTermProjectTokensAddress()","e6b1c48d":"Amal()","e6b1e71c":"jackpot(uint256,uint256)","e6b35875":"getAllbetByGtype(int8)","e6b55ff3":"TokenEmissionEvent(address,uint256,bool)","e6b6f9d5":"baseDiscounts(uint256,uint256,string)","e6b71e45":"changeIncrease(address[],uint256[])","e6b827a6":"becomeSpermlord()","e6b950f3":"_computeCooldownRemainingTime(uint256)","e6b96447":"updateMaxNum(uint32)","e6b96fe3":"setupFund(bytes32,address,uint256,uint256,address,address,address[],address[],uint8,bytes32,bytes32)","e6b972f5":"userName(address)","e6ba54c1":"specialInfo(uint256)","e6bb64b4":"generateChampionTokens(address,uint256,uint256)","e6bb88b3":"setMinEscrow(uint256)","e6bbe9dd":"getMinThreshold()","e6bc2cc9":"Marcela_Birthday(string,string,string,string)","e6bc5269":"CrypexToken()","e6bc7d2a":"FairDistributionToken()","e6bcbc65":"mostSignificantBit(uint256)","e6bcc297":"STARTING_BANKER()","e6bd0eca":"newUser(address,string,uint256)","e6bd11b2":"availableBuyInShares()","e6bf3fdc":"removeFarmer(address)","e6bf6ca2":"check_deadline()","e6bf70e2":"register(bytes20,uint96,uint32,bytes32[],uint16)","e6c01488":"addComment(bytes32,bytes32,string)","e6c0459a":"right79(uint256)","e6c0e6d5":"discountRate()","e6c0e9e1":"randomDS_sessionPubKeysHash(uint256)","e6c160dc":"RateSetter()","e6c1beb4":"prepend(address)","e6c1d7fc":"getHedgeIndices(address)","e6c21c24":"isCertified(uint256,uint256)","e6c22a11":"district0xNetworkToken()","e6c25aa1":"totalPhase2Donations()","e6c28db4":"getPlayerSpaceshipCount(address)","e6c2dee8":"Vish()","e6c2f4fe":"SendmoneySend(uint256)","e6c3329d":"EthaToken()","e6c35a91":"batchAirDrop(address[],uint256[])","e6c3b4ab":"testBalanceAuth()","e6c4498b":"LOCKING_UNLOCK_TIME()","e6c4a46a":"_addRecord(bytes32,address,string,string)","e6c4c2c7":"admin_tokenAdd(uint256)","e6c50020":"callAllFromMew(uint256,address)","e6c52016":"setToken(address,uint256,address)","e6c54139":"BitmassXToken()","e6c57a08":"timeIncreasePerTx()","e6c5e94c":"setinterval(uint256,uint256)","e6c63912":"lastBlock_a17Hash_uint256()","e6c721e4":"senderDelegates(address,address)","e6c75c6b":"triggerEvent(string)","e6c7c456":"balanceOfContract()","e6c88b31":"auditor(uint256,bytes32)","e6c89d4a":"makeOfferForCityForSomeone(uint16,uint256,address)","e6c8fcf1":"getExpirationRequest(uint256)","e6c9f6ee":"shelf(string,address)","e6ca00b5":"_abortAllRounds()","e6ca0f47":"setStages()","e6cb9013":"safeAdd(uint256,uint256)","e6cbcba9":"PlusOnePonzi()","e6cbd74c":"TokenSold(uint256,uint256,uint256,uint256)","e6cbe351":"saleAuction()","e6cda5ff":"countDays()","e6ce1622":"ProcessMarkings(bytes32,uint256,uint256,uint256)","e6d04d5e":"whitelistedParticipants(uint256)","e6d09529":"getTTTCount()","e6d0a37d":"RemovePoolMember(address,string)","e6d0dfda":"setDiscountTime(uint256)","e6d1092d":"vestedTeam(uint256)","e6d17238":"specialWallet()","e6d17cfc":"_updateToken(uint256,uint256)","e6d18a7a":"nihilumBalanceOf(address)","e6d20a23":"king_of_returning_shirts()","e6d26bc6":"setTeamContractAddress(address,address)","e6d2ceab":"set_pool_percentage(uint8)","e6d30bf2":"finishMinting(bool,bool)","e6d343a5":"getTransContractLocked()","e6d3b85b":"getOwnershipForCloning(uint256)","e6d3f673":"distributeGeneratedPower(uint256)","e6d41b39":"isApprovedTransferer(address,uint64)","e6d44122":"limitPreSale()","e6d4d217":"addAddressToWhitelist(address,string)","e6d54815":"delSpecialPrice(address)","e6d55f3a":"buy10ktickets()","e6d61f70":"resetInactivityTimer()","e6d660dc":"UBT(uint256,string,uint8,string)","e6d66ac8":"sendTokens(address,address,uint256)","e6d76a76":"withdrawSynthetix(uint256)","e6d78add":"tokensPerWei5()","e6d7fd33":"TokenERC20(uint256)","e6d8a47a":"MIN_INVEST_BUY()","e6d8d435":"AMBASSADOR_ONE()","e6d944a7":"computeCurrentPrice(uint16)","e6d95eb8":"DSAuthorized()","e6d970aa":"registry(address,address,bytes32)","e6d9bb0f":"secondsUntilEnd()","e6da89cd":"addVestingForBeneficiary(address,uint256)","e6dab965":"startTrack(bytes32,uint256)","e6dad824":"withdrawFrom(uint256)","e6db38c7":"purchaseFromTime(uint256)","e6dba7e8":"EX()","e6dbf486":"setCLC(address)","e6dc3655":"_validateUrl(string)","e6dc85a3":"weiTotal()","e6dc992d":"buySquareAtAuction(uint8,uint256,address)","e6dd672c":"enterMainSale()","e6dd9a8d":"endBookings()","e6deb223":"addPlayerMapping(string,string,uint256,uint256)","e6deefa9":"deposit(address,uint16)","e6dff3b4":"whitelistInvestor(address,bool)","e6e05562":"getIslandPreviousOwners(uint256)","e6e08ba4":"openPreICOPrivate()","e6e13795":"_addEntry(bytes32)","e6e261b2":"getFundAllTx(uint256)","e6e2c041":"_removeDiscount(uint256)","e6e2e1cd":"VestFFTokens(uint256,uint256)","e6e35407":"startCoinFlip(bytes32,bytes32,bytes32)","e6e45ea2":"MyHumanStandardToken(uint256,string,uint8,string)","e6e46238":"idCount()","e6e5b492":"AirwayBill()","e6e623d5":"setTokenSymbol(address,bytes32)","e6e68cb3":"map(uint256,uint8)","e6e7237f":"claim_time_victory(uint256)","e6e84bf8":"Suren3Token()","e6e88593":"_contractStatus()","e6e8c692":"computeResponseFirstHalf(uint256,uint16)","e6e91cfc":"voidFailedPayment(uint256)","e6e93b14":"setbetEnd()","e6eb00ce":"drawingNo()","e6eb6867":"updateKey(bytes)","e6ecc9c1":"getReservedAmount(address)","e6ecf8a0":"CONTENT_FUND()","e6ed4746":"setBonus(uint8)","e6ed51b7":"createToken(uint256,address,address)","e6ed6c74":"getRabbit(uint256)","e6ee78bd":"approveRemoveOwnerRequest()","e6effbe9":"createAuction(address,uint256,uint256,uint256,uint256,address)","e6f02bf9":"computeBonuses(uint256)","e6f041c1":"testLessThan()","e6f0823c":"deleteNota(uint256)","e6f091f9":"isAccepted(address)","e6f0b6cf":"individualCapInWei()","e6f0beeb":"sort(uint8[4])","e6f1a189":"isCustomToken()","e6f3ae3c":"neighbor(uint256,uint8)","e6f46410":"RBC()","e6f47613":"multiSubWithdrawFor(address[],address[])","e6f4c4a7":"setOtherSettingOwner(address)","e6f602ff":"benTook()","e6f6266a":"numMinters()","e6f67ef2":"payOrganizer()","e6f6b789":"setInterfaceImplementation(string,address)","e6f6e19f":"emissionStage()","e6f7bf89":"GetOwnerAddress()","e6f7ec75":"populateTierRates()","e6f8263e":"JackpotPeriods()","e6f8298c":"cancelActiveLoanAtIndex(uint256)","e6f82ca3":"_clearBridgeTokenFee(uint256)","e6f859e7":"descriptions(uint256)","e6f9476a":"getContribPeriod()","e6f9f265":"areNoncesValid(bytes,uint64[],uint64[])","e6fafef0":"ContributionMinimumUpdated(uint256)","e6fb5c4a":"CHLToken()","e6fbf441":"transferFromSenderPaysFee(address,address,uint256)","e6fd2982":"initialReserve()","e6fd42ee":"currentHalving()","e6fd48bc":"startTimestamp()","e6fd604c":"cut()","e6febc9b":"investorWithdraw(uint256)","e6ff0853":"advisorsTokenWallet()","e6ffd50d":"OXGOLD()","e6fff409":"TetherGBP()","e7001b84":"setOwnedCount(address,uint256,uint256,bool)","e700d63a":"FeesConverted(uint256,uint256,uint256)","e700efc4":"MaxSupply(address,uint256,bool)","e701900c":"refundTransaction(bool)","e701a6d3":"handlePresaleTokenMany(address[],uint256[])","e701d051":"setMarketerRate(uint256)","e70265a5":"FRACTION_ETHER()","e7031501":"jackpotWinPercent()","e703e9c3":"CheckActivate()","e704430d":"numberOfTreasuryOfficials()","e70468b1":"cancelOpenBids()","e7046bf0":"setFx(address)","e704f151":"burnContributorTokens(address)","e7058e15":"Rollback()","e705a519":"SALE_1WEEK_BONUS()","e7062263":"checkEndorsementExists(bytes32,bytes32)","e706918c":"testToggleBitSuccess()","e7073a4c":"MarketplaceV2(address)","e7074de2":"FOUNDATION_TOKENS()","e7084b7e":"closeTimeout()","e7092b41":"getAllowance(address,address,address)","e7095e97":"mintTo(address,string,uint256,uint256)","e70990d7":"summon10()","e7099763":"client_wallet()","e70addec":"right87(uint256)","e70b11df":"revokeAllocation(address)","e70b5259":"mapHeight()","e70b793a":"blankbreedingdata(uint256,bool)","e70c052a":"ethFundDepositAddress()","e70c3276":"HyipProfitTokenTeamAddress()","e70cd5ec":"destroyItemsStorage()","e70e690a":"set_gas_price_max(uint256)","e70e6ece":"BOURSETOKEN()","e70eb392":"claimReward(uint256,address)","e70f5d95":"setIV_R3(uint256)","e70fe5e3":"GenesisToken(address,uint256)","e7105795":"_raceOpened(uint256)","e710efc6":"regSpot(uint16,bytes32)","e711da27":"writeToStorage()","e71264fa":"addNewTokens(uint256)","e7127e29":"addressToTrainer(address)","e712bbad":"enterArena(uint256[4],address)","e71346f4":"removeAnimalIdFromCountry(uint256,uint256)","e7137dbf":"withdrawETH(address,address,uint256)","e713cda8":"returnUint32(uint32)","e714a028":"cancelWithdrawalRequest()","e7151828":"deathData_v1()","e7152a5c":"transferStar(address,uint256)","e715920f":"doBuy(address)","e717db5c":"CheetahCoin()","e717dc3d":"tax_fund()","e717ea61":"getCurrentAddress()","e718234d":"tokenLock()","e71897cd":"alfatokenteam()","e718ad01":"ReclaimPeriodChanged(uint256,uint256)","e7199f82":"transferCentralBanking(address)","e71a02e1":"DELAY_PERIOD()","e71a402e":"mul_float_power(uint256,uint8,uint8,uint8)","e71a5577":"getNumPullRequests()","e71a7811":"completeOwnershipTransfer()","e71b49ad":"ADDR_TKG_ORG()","e71b7913":"expireTransfer(address)","e71b8b93":"bye()","e71bbf48":"TokenSyndicateFactory()","e71bdf41":"addDelegate(address)","e71c3b38":"LogSetRBInformationStoreAddress(address)","e71c9697":"placeBet(uint256,uint256,uint256)","e71d3ae2":"CYFR()","e71d77a7":"PRICE_CHANGE_TIME_STEP()","e71d7bf0":"testControlTransferNotEnabled()","e71df6d6":"acceptMembership(address,uint8,uint256)","e71e592b":"replaceDelegates(address[],address[])","e71ecf6e":"revenueShareCurrency(address)","e71efd18":"Mytoken(uint32,string,uint8,string,address)","e7201d7d":"masterOwner()","e720b4a7":"DEEM()","e720e1b3":"marmoOf(address)","e7211134":"createDAO(uint256,string,bytes32)","e7212728":"getFreeChicken()","e7225175":"timeoutSEC()","e722a522":"createContractPeriodicTable(string)","e7233ce7":"getAdIds()","e7239ed2":"getTimebasedBonusRate()","e723a8f9":"setFundraising(address)","e724529c":"freezeAccount(address,bool)","e7255ef9":"desiredOutcome()","e7271c34":"removeArts(address)","e7278231":"DesToken()","e727de55":"setEggPrice(uint128)","e7299675":"DroplexToken()","e729b416":"lockIndexes(uint256)","e729ebe8":"getSignatureParts(bytes)","e72b0e23":"CreateTUBE(address,uint256)","e72b6091":"extendSaleTime()","e72c40dc":"CoreTeamMinted(address,address,uint256,uint256)","e72c81cf":"demo1(address,uint256,bytes,string)","e72cba6e":"ICO_PHASE1_AMOUNT()","e72e46fd":"ImmlaIco(address,address,uint256,uint256,uint256)","e72eb439":"DogTestToken()","e72f4f2a":"s38(bytes1)","e72f5f63":"maxRandom()","e72f7a78":"finishCurrentGame()","e72f99ac":"deathData_a18()","e72fd4e1":"developerCut()","e72fee5d":"massTeamMsgHash()","e7302541":"convertOldToken(address)","e730e87a":"stageOneSupply()","e73140c1":"setPublicOfferingDate(uint256,uint256,uint256)","e7316a95":"_set10()","e731b034":"HawalaKickoffTime()","e731bb09":"cpn(uint256)","e7320f9e":"getGameMaxNumberOfBets(uint256)","e7326806":"transferOracle(address)","e7328000":"userTokenBalances(address)","e7329e71":"scheduleCall(bytes,bytes,uint256,uint256,uint8,uint256)","e732a7e1":"preAllocationsPending()","e7334156":"processNextDeposit(address)","e73471fa":"_mintNativeCoinsByErcToNativeBridge()","e735b48a":"updateDescription(string)","e735f667":"destroyChildren(uint256)","e7368a1f":"isOnSale(uint16,uint64)","e736f03c":"actived()","e7377ccb":"vestingMembers(address)","e7383c91":"ICOStarted(uint256,string)","e73886b0":"addLocked(address,uint256)","e738a7a5":"createDungeon(uint256,uint256,uint256,uint256,address)","e738cb69":"EventLogged(string,uint8,uint256,address)","e738d2b3":"claimingFee()","e7398fa3":"setTokenRate(address,uint256)","e73995cd":"setSale(uint256,uint256,uint256,address)","e739a4fe":"initialSeed()","e73a914c":"setDAO(address)","e73b7d77":"testControlCreateNewRevisionNotUpdatable()","e73b9e2f":"bridgeAmount(address)","e73c032b":"PRESALE_TOKENCAP()","e73c3c53":"pingOracle(uint256)","e73c6353":"Payroll(address,uint256,uint256)","e73c99a0":"METADOLLAR()","e73cba34":"getTicketRound(uint256)","e73cc2eb":"walletPeriodOf(address)","e73cf000":"EMIToken()","e73de430":"releaseAccount(uint8,address)","e73e5063":"setRewardManagerLimit(uint256)","e73fc0c3":"getTokenByName(string)","e740ce26":"DSToken()","e740f4fc":"card_start_first()","e7416f01":"lastBlock_a18Hash_uint256()","e7422d29":"sendBalance()","e742b943":"ispackagesaleSetup()","e742db66":"tokenTaxRate()","e742f18a":"Task(bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32,bytes32)","e743892b":"escrowExpiration(bytes32)","e744052b":"FalconFarmer()","e745656b":"removeImmigration(address)","e7463688":"MasharibTestCoin()","e7477f1c":"WithdrawDeposit(uint256)","e74799b4":"TOKEN_MIN()","e747f31c":"debit(uint256,uint256)","e74803db":"putSaleRequest(uint256,uint256)","e74915d0":"distribute(address,uint256,address)","e74997a8":"transferInternal(string,address,string,address,string,uint256,uint256)","e74a19fa":"AirdropTokensHolder(address,address,address)","e74a48be":"reservedTokens(address,uint256)","e74a5847":"getGladiatorCooldown(address)","e74a84ea":"issueToken(address,uint256)","e74ab046":"increasePrice_20_January()","e74ac94a":"RetailLoyaltySystemToken()","e74b981b":"setFeeRecipient(address)","e74b9d11":"safeToSubtract(uint256,uint256)","e74ba7b3":"getMntTokensPerEth(uint256)","e74baeef":"Upgrade(address,bytes)","e74cd692":"testNextRune()","e74ceb77":"EGGS_TO_HATCH_1CHICKEN()","e74d6d1b":"getLeader(address)","e74e66d7":"toB32(uint256)","e74e6e9e":"GBMToken()","e74f3fbb":"claimVestedTokens()","e74f8eff":"firstDayTokenLimit()","e74ffbd5":"getPart(bytes32,uint256)","e750b5c0":"getProjectAddress(string)","e7514287":"IsGenesisAddress(address,address)","e7519ac0":"_setTokenName(address,uint256,string)","e751f271":"execute(bytes32)","e75235b8":"getThreshold()","e75303a5":"recentWinners()","e7530cfc":"_batch3_icosaleStartTimestamp()","e7542782":"Recovery(address)","e754a4e5":"presale2_startdate()","e75528cc":"buyBuilding(uint256,uint256)","e75539e7":"Schrodinger()","e7556704":"GPSToken()","e755aaaf":"takePoint(uint32,int256,bool)","e755e077":"MKToken()","e75623d8":"setDeploymentAdminsContract(address)","e75705c7":"submitFakeHeader()","e7572230":"getPrice(uint256)","e7574128":"abcToken()","e757835e":"Yotra()","e7579c24":"totalBuyerSupply()","e757c17d":"preSalePrice()","e75864e4":"StarsICO(uint256,uint256,uint256,address,address,address,address,uint256)","e758d445":"getCurrentTierInfo(address,bytes32)","e759dfb8":"investorsBatchSize()","e75a0747":"Staker()","e75afb65":"endCrowdfund(address)","e75b4642":"_decreaseAllowance(address,uint256)","e75bd44a":"currentPrize(address)","e75bf79b":"ESEVENTYSEVEN()","e75bf820":"extraTokensHolder()","e75cdd7b":"isAddressInServer(uint256,address)","e75d1721":"vevcoin()","e75dcb19":"partnerSaleTokenPrice()","e75e69d6":"TryCoin()","e75ea9da":"preICOEndDate()","e75ef9b2":"trackSpend(uint256)","e75f02e3":"UraniumPlus()","e75f1634":"pearlSend(address)","e75f6e21":"totalMfr()","e7609c16":"getFarmer(address)","e760a11a":"attachContracts(address,address,address,address,address)","e760d284":"BOOKIES(uint256)","e760da9d":"createCP(address,string,string)","e760fb06":"groveAddress()","e7619fad":"allTokenIds()","e761eec6":"RecordTransfer(address,address,uint256)","e76240a4":"calcZWCAmountByToken(address,address,uint256)","e76261fb":"GetContractStateCancelledByLandlord()","e7637b5b":"deleteInfo(uint256,bytes32)","e7638445":"getRaffleTimeLeft()","e7651d7a":"normalProcess()","e7657e15":"ids()","e765bc5a":"thirdStageEnd()","e765c69a":"betOnDozen(uint256)","e765cb44":"auctionMinPrice()","e7663079":"owner_()","e766d79e":"CrowdsaleEndChanged(uint256,uint256)","e767b578":"createPlayerAndAssign(uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint8,bytes,string,address)","e76895bf":"OwnerAdded(address,bytes32)","e7694493":"is_white_listed(address,uint256,bytes)","e7696a29":"updateWeedTotal(uint256,bool,uint16)","e769dfbd":"buyTransferFee()","e769f61f":"private_withdrawAll(address)","e76abcb9":"presaleBonusTier2()","e76b8126":"finish(address,address,address,address)","e76cc0d3":"failWithoutReason()","e76dd3ef":"returnBet(uint64)","e76e337d":"Honolulu()","e76e5ecf":"__DEBUG_BAL()","e76e9286":"depositPresale(address,uint256,uint256)","e76eabe5":"finishPreIcoAndStartIco()","e76ece01":"setInvestStart(uint256)","e76ed0e3":"DividendToken()","e76f0836":"getcurrNumOfCards()","e76f3d5a":"REFERRED_BONUS_PERMILLE()","e76f62cd":"Reissue(uint256)","e770390d":"deleteMultitoken(uint256)","e771066f":"marriageProof(bytes)","e7712a94":"MDTCrowdsale(address)","e7718594":"totalAccessories()","e771e193":"GetCountryCode(uint16)","e7722f9b":"isAddressInvited(address)","e773c82f":"bonusEnds2()","e773ffd5":"queryPlayerUnAwakeSkillIds(uint32[11])","e7740cf9":"revealPaper(string)","e7751e48":"ownershipAuctionCount(address)","e775781b":"getPopularity(bytes32)","e775f01f":"CAPToken()","e776a5b5":"wallet_address()","e776fa22":"AlphaconCrowdsale(bytes32[5])","e77772fe":"tokenFactory()","e777b97b":"LogRegisteredInterval(uint64,uint64)","e777d060":"removeProviderAdmin(address)","e7781f3c":"ToppedUp()","e77900e9":"projectMemberAddress()","e779a8cf":"airLimitCount()","e77a6daa":"tokenCalculate(uint256)","e77a912f":"prefilled()","e77aaee2":"enterRecoveryMode()","e77b077f":"canExchange(address)","e77b8d94":"ipow(int128,int64)","e77ba2c9":"checkIfMegaJackpotWinner()","e77c646d":"redeem(uint256,bytes)","e77cfa1c":"weiPending()","e77db232":"isKYCApproved(address)","e77dd5b3":"setSoftCapUSD(uint256)","e77df041":"LykkeTokenBase(address,string,uint8,string,string)","e77e02d3":"giveAdvisorsTokens(address,uint256)","e77ef21f":"drawdown()","e77f9906":"gameListOf(address)","e77ff2f6":"centralAuthority()","e77ff818":"privateSaleEndTime()","e780377e":"liquidityPoolAllocation()","e7804444":"allowMigrate()","e780f6c9":"setDestructionAddress(address)","e7810318":"updateInitialBonus(uint256)","e781d8c5":"getPC()","e7827e85":"unfreezeTokens(uint256)","e7829152":"prometh(address)","e782b172":"transferWithLockBatch(address[],uint256[],uint256[],uint256[])","e783bfb1":"totalAllocatedToTeam()","e7843949":"STATE_PAYOUT()","e784a923":"thisweek()","e7850f2d":"Sunny()","e78562c0":"dividendRecentBuyersPercentageDecreaseFactor()","e785bab2":"withdrawAdminRevenue()","e785daaf":"setUnownedPurchaseableMode(uint256,bool)","e786140e":"setBio(bytes3,bytes)","e78631fb":"changePhaseToICOweek2()","e78686eb":"reclaimContribution(address)","e78721af":"getSmartSharingByID(uint256)","e7873b58":"tokensBurned()","e787418a":"isSubmitted(uint256)","e787654c":"_forumIdToAddr(string)","e787887b":"initialRewardFraction()","e787b523":"CLKToken(address)","e788b5eb":"emitAreaSet(uint256,bytes32)","e78bfee0":"allocate(address,uint256,uint128,uint256)","e78c1136":"CreateLCD(address,uint256)","e78c219b":"takeBuy(address,uint256,uint256,address)","e78c3462":"betsOff(uint256)","e78ce8db":"getCarEarning(uint32)","e78ce986":"KOK()","e78cea92":"bridge()","e78d6306":"getBountyTransfers(uint256)","e78dd6f1":"mainSaleTokenLocked()","e78e3ab1":"ESOPOpened(address)","e78f5412":"_whichCourse(uint256)","e78fd9a8":"submitMint(address,uint256)","e78ff581":"getProposalPayloadHash(bytes32,uint256)","e790aa9e":"joinMountain(bytes32,address)","e791b66c":"Wemark()","e79206e6":"finishElections(uint256)","e7921023":"getHolderLink(address)","e79248ea":"setRelationFrom(uint8,address)","e7930d21":"DeliverToken()","e7933601":"getOverBalanceWEIInfo()","e7933d58":"setIcoPhaseAddress(address)","e7938b82":"minAllowedStakeInPercentage()","e79487da":"checkInvariant()","e7950ede":"logs(bytes)","e795c149":"FinalToken(uint256)","e79609e2":"getOrCacheDesignatedReportStake()","e7964b49":"sendeth(uint256)","e796570b":"isClearingPriceValidator(address)","e796818e":"AEFTOKEN()","e79695da":"WhitelistUpdate(address,bool)","e796a6eb":"refund(uint256,address,uint256)","e796c43c":"_cancelActiveAuction(uint40,address)","e797398f":"IsMultiFreeze(address,address[])","e797496b":"sigDestinationApproveAndCall()","e7977701":"setLotteryOptions(uint8,uint256,uint16,uint256)","e7979efa":"LOG_BetWon(address,uint256,uint256,bytes32)","e797ec1b":"enableMinting()","e7984a3b":"updateRewardForContributor(address,uint256,string)","e7986466":"setSupportedToken(address,bool)","e798f4eb":"webpud()","e7990596":"getAddressAndBalance(address)","e7992845":"pendingInstallments()","e7996f07":"removeAttribute(bytes32)","e799f374":"fundingMaxInWei()","e79a198f":"unregister()","e79ab547":"bulkTokenSender(address[],address[],uint256[])","e79b4388":"LogBidExpired(uint256)","e79d0860":"partnerCount()","e79e0a22":"getEthers(uint256)","e79e2bd3":"updateArea(uint256)","e79e770f":"EmergencySafe()","e79faa58":"unpause(string)","e79fb53c":"setUSDEtherPrice(uint256)","e79ffa11":"_dev()","e79ffa99":"getpurchasersLength()","e7a01215":"right2(uint256)","e7a01352":"adjustHardCap(uint256)","e7a02352":"MintDarioToken(address,int256,uint256)","e7a0459a":"setCatalogPlayersAddress(address)","e7a05f08":"isTokenSaleToken(address)","e7a17d83":"emitTaskCreated(uint256,uint256)","e7a25bfc":"JustEscrowTestCoin()","e7a2e28e":"fishbank()","e7a33822":"seal(address,uint256)","e7a35405":"managerAddressNumberMap(address)","e7a3c218":"testFail_mint_without_add_authority_to_controller()","e7a4581a":"getCirculationSupply()","e7a49c2b":"trustedTransferTokens(address,uint256)","e7a4d9d3":"LIQUID_TOKENS()","e7a60a9c":"getValidatorAtIndex(uint256)","e7a6e75c":"ETH_USD_rate()","e7a7043d":"addPrecommitmentAdjustment(address,uint256)","e7a83c74":"AT()","e7a8a5cb":"setTier(uint256)","e7a95a7f":"WHOLESALE_THRESHOLD()","e7aa3afc":"getProjectStatus()","e7aa8ed5":"CrowdsaleMCS()","e7aab290":"set_s(string)","e7ab4f1c":"getShareholderArray()","e7ac4df8":"launchInvestment(uint256)","e7ac81e5":"productSold(uint64,uint32,string)","e7acaa1e":"createJob(bytes32,address,address,uint256)","e7acb2b4":"ZitronSupply()","e7acdcd0":"deleteInvest(uint32,uint32)","e7aef169":"refreshInvestor(address,address,uint256)","e7aefd01":"allowTransfersEnabled(bool)","e7af4540":"ChiyouCulturalAcchain(uint256,string,uint8,string)","e7afae52":"WayCellToken()","e7b0f666":"totalPaid()","e7b172ed":"GAS_PRICE_LIMIT()","e7b1983e":"giveReward(uint256[4],uint32,uint8,bool,uint32[4])","e7b1a7ae":"collect_fee(string)","e7b1d43c":"withdrawVotingRights(uint256)","e7b1d6dd":"setServerStatus(string,uint256)","e7b2d7e5":"deprecateAndUpgrade(address)","e7b3387c":"getVoteCount()","e7b379c6":"TokensUnlocked(address,uint256)","e7b43c44":"changePuzzle(uint8,uint8,uint8,uint8,uint8)","e7b48d98":"getBurningMans()","e7b48f74":"get(int256,address)","e7b4e5ab":"entrants(uint256)","e7b512ec":"setAddress(bytes32,bytes32,address,bool)","e7b6135d":"getClown(uint256)","e7b6805b":"OriginalMyIdRepository()","e7b686a7":"UnpackEntity(bytes)","e7b69e74":"interest(uint256)","e7b6ff08":"beerAndHookersCap()","e7b70b38":"getPurchaseInfo(uint256,uint256,uint256,bool,uint256,uint256)","e7b7aea5":"changesp2(address)","e7b7c2a6":"setup(uint256,uint256,uint256,address,uint256,uint256,string,address,address)","e7b808ea":"getAccountFeeModifiers(address)","e7b83730":"tokenAmount(uint256,uint256)","e7b89977":"setFeeAccount2(address)","e7b8d977":"editionsOfType(uint256)","e7b94df4":"donationWallet()","e7b9aaef":"FIRST_VOLUME_BONUS()","e7b9db8d":"confirmBurning(uint256)","e7ba1012":"supplyController()","e7ba2cc8":"BelottoCrowdsale(uint256,uint256,uint256,uint256,uint256,address,address,address,address,address,address)","e7ba6c46":"resetReservations(address,bool)","e7bb22cd":"getValidClassId(uint64,address)","e7bb5233":"crowdsaleState()","e7bbda11":"heroCore()","e7bd85ca":"PFGC(uint256,string,string,bool)","e7be5617":"setOracleReference(address,address)","e7bf5352":"_withdraw(uint128,address,uint256,uint128)","e7bf7b08":"GroupCreated(uint32,uint256)","e7bf7dfc":"getProductPrice(uint256)","e7bfcf57":"HighCoin()","e7bfdc93":"clearLevels()","e7c0bd15":"SeedLog(address,bytes32,uint256)","e7c0dad5":"checkApprovalRatio()","e7c0e558":"BoomerangLiquidity(uint256,address)","e7c12837":"getPOOL_edit_24()","e7c158c6":"_setStrengthValue18(uint256)","e7c17972":"btcToTokens_(uint256)","e7c4118a":"certIssued()","e7c5c27f":"saleOpen(address)","e7c5d907":"Broker(bool)","e7c6229a":"publicOfferingHolder()","e7c6978e":"RSCCoinCrowdsale(address,address)","e7c77c80":"getAmountDailybyNum(uint32,uint8[4])","e7c8d171":"getTotalWidth(uint16,uint16)","e7c8dd6d":"GemsToken()","e7c8f61e":"enableAura(uint256,uint256)","e7c957c0":"MultiTransact(address,bytes32,uint256,address,bytes)","e7ca1343":"setReserveForCompany(address)","e7ca438d":"getUserDisplay(address)","e7cc62bd":"total_users()","e7cc862b":"storehouseIndex(uint256)","e7cc8ded":"generateLockupTokensDelegationSchemaHash(address,uint256,bytes32)","e7cd4a04":"addWhiteList(address)","e7ceaeab":"getTrackOwner(bytes32)","e7cf0171":"enableTokenClaiming(bool)","e7cf514d":"setMinOrderEthAmount(uint256)","e7cf548c":"getBurnCount()","e7cf6fcb":"changeEtherTxLimit(uint256)","e7cf7b34":"ICO_PRICE3()","e7cfafce":"getBirthMonth()","e7d00518":"FinishTokensale()","e7d0242b":"totalWeiCollected()","e7d03e93":"setMaxiumInputEther(uint256)","e7d0c552":"getRoyaltyPartners()","e7d0c7e7":"timeStampOfCrowdSaleStart()","e7d11a44":"getFutureTransByIdx(uint256)","e7d137ec":"balancesAddressDescription(address)","e7d1a024":"NewOne(address,uint256,uint256)","e7d2340f":"playervanity(address)","e7d29d8b":"withdrawExtraToken(address)","e7d29e38":"addHolderAddress(bytes32,address)","e7d2c590":"showCompany(uint256)","e7d2f315":"totalSupplys(address[])","e7d3fe6b":"mint(uint256,uint256,address)","e7d4761b":"unhalt_15day()","e7d47c2e":"selflleryManagerWallet()","e7d48741":"allOldUsers(uint256)","e7d4fd91":"getTokenControlInfo(address)","e7d50e5c":"FarmShare()","e7d53fcb":"privateSale(address)","e7d5a62b":"testNot()","e7d80c70":"getOrderCreator(bytes32)","e7d854af":"setWithdrawABIHash(bytes32)","e7d86204":"registerTeamScores(uint256[])","e7d87cda":"arbTokenExists(uint256)","e7d8c7db":"MicroToken()","e7da257f":"highestBidderCC()","e7daaa5a":"OwnerManager()","e7dac983":"submitClaim(uint256,uint256,uint256,uint256,uint256)","e7dafdb6":"transfer_token(address,address,uint256)","e7db6770":"startWork(uint256,bytes32,bytes32,address)","e7dde9a3":"_setDailyLimit(uint256)","e7de559c":"contrDividends(uint256[])","e7de72a4":"createFlag(uint16,uint256)","e7dee968":"KittyCore()","e7df2f3e":"disburseAddr()","e7e00d1d":"assignTestAddresses(bool)","e7e024ce":"janwin(uint256,uint256)","e7e0ca7b":"tariffIndexForAmount(uint256)","e7e10490":"cancelSale()","e7e1e69f":"commitBid(bytes32,string)","e7e2aa0e":"buyer_cancel()","e7e31d52":"setNinjaKindCount(uint8)","e7e31e7a":"addSpender(address)","e7e3411d":"fechBalanceByAddress(address[])","e7e3e167":"rate(address,int256)","e7e481c5":"BP_SPARTAN()","e7e52369":"firstMembershipPurchase()","e7e6aed1":"test_testableStandardCampaignContribution()","e7e766ca":"CSCRarePreSaleManager()","e7e7e3e8":"ETHEREMON_PROCESSOR()","e7e8116e":"forceTransferTokenOwnership()","e7e96a43":"getPOOL_edit_2()","e7e9e106":"rewardVote(address,address,uint256)","e7e9f385":"notarise(bytes32)","e7ea3d2d":"usernames(bytes16)","e7ea4406":"Civiq()","e7ea8065":"setNameRefer(string,address)","e7ea8122":"isStateInitializing()","e7eaaa05":"totalAvailableForSale()","e7eb285f":"stepEtherValue()","e7ebc348":"nonActivationWithdrawal(address[2],uint256[8],uint8,bytes32[2])","e7ec8182":"issueTeamTokens()","e7edab45":"_cancelParticipation()","e7ee6ad6":"rate(uint256)","e7ee85a5":"quickBuyPath(uint256)","e7eed1f7":"getCurrentPot()","e7efcfc2":"totalPayoutAmount()","e7f034c1":"getUri(address,uint256)","e7f0a865":"transfertokenContract(address)","e7f1111e":"initializeHolding(address)","e7f18249":"insertShareholder(address)","e7f1c468":"UserSold(address,uint256,uint256,uint256,uint256)","e7f23cb1":"getCallStack(uint256)","e7f35484":"NewAquarium(address)","e7f4037a":"demintTokens(address,uint8)","e7f40d35":"IntervalBytecodes()","e7f44523":"ReceivedLTC(address,uint256,string)","e7f4767c":"delimiter()","e7f56111":"ClaimPayout(uint8[],bytes32[],bytes32[],bytes)","e7f578e1":"createDoc(string,string,string)","e7f6edbd":"holdingTax()","e7f9e408":"stopTransfer()","e7fa443e":"unlockCashpledge(bytes32)","e7fa6883":"investFor24Months(address,uint256,uint256)","e7fa7969":"assertEq25(bytes25,bytes25)","e7fac728":"friendsFingersRatePerMille()","e7faecec":"testFailInsufficientFundsTransfers()","e7fb5388":"exit(string)","e7fb74c7":"buyItem(uint256)","e7fbee28":"checkIfCustodiesServedBBD(address[])","e7fc4b64":"ricardianVoucher(uint256,string,uint8,string,string,string,uint8,uint8)","e7fcde9b":"setFeeType(uint256,uint256,uint256)","e7fcf520":"signToResetTokenControlInfo()","e7fd9a13":"addEmployee(address,uint256)","e7fdc514":"buyFromVault(uint256,uint256,uint256)","e7fde97a":"_withdrawDividends(address)","e7ff0e38":"bountyDistributed()","e7ff8901":"transferWine(address,bytes32)","e80080d0":"cancelBurnRequest(uint256,string)","e80160ab":"order(bytes32)","e8017bb7":"getHTLCSpendingHash(int256,bytes32)","e801a361":"tileTimeoutTimestamp(uint256,address)","e8022dc9":"PLAgreements(address,address)","e8024468":"getHeroRequiredGoldForLevelUp(uint256)","e8024d75":"eNomCoin()","e8025d77":"changeStatus(uint256)","e8038e25":"TokenSale(uint256,uint256,address)","e803b708":"setDetails(string,uint256)","e803bcc6":"SetPriceIncrease(uint16)","e8046759":"decimals_multiplier()","e8055e9c":"burnExcess(uint256)","e8069e84":"verify(bytes32,bytes,address,address)","e806c603":"robottradingToken()","e8071f30":"exponential_decay(uint256,uint256)","e8078d94":"addLiquidity()","e8083863":"finalizeAuction(uint256)","e8088ca2":"GetEvaluate(bytes32,uint8)","e808aef7":"isIcoSuccess()","e808d671":"crowdsaleTokenMint()","e809046f":"NumeraireBackend(address[],uint256,uint256)","e80919d5":"mintUnderCap(uint256,uint256)","e80a4df7":"NotusNetwork()","e80b128f":"tournamentsAddr()","e80b7ab6":"clearArray()","e80bd3e5":"addCertificationDocumentToSelf(bytes32)","e80c4182":"ShresterToken()","e80d2ef8":"calculatesubscribersell(uint256)","e80d47dd":"USDSTEMPRICE()","e80d60b8":"CryptohomaToken()","e80db5db":"coreContract()","e80f23aa":"tokenApprovalWithSignature(address,address,address,uint256,uint256,uint256,bytes32,bytes)","e80fd970":"etherToSendDev()","e810267a":"dateEcoRelease6()","e8107ed4":"ElectriumToken(uint256,string,uint8,string)","e81140a8":"setPreICOStartTime(uint256)","e811f50a":"collectedFee()","e8125eb9":"updateContractTokenBalance()","e814018d":"getCrowdsaleHardCap()","e8141f93":"logUint(int256,uint256)","e8144c42":"advisorsTokensLock()","e8147a25":"changeMinBet(uint256)","e814c941":"removeParticipant(address[])","e815b60d":"SencToken()","e8168177":"lastBlock_a2()","e816a515":"takeFlight()","e816f76f":"Association(address,uint256,uint256)","e8171f37":"valueOfScheme(uint256)","e81766e8":"AgriChainDataContract()","e8179abf":"getStar(uint256,string,string)","e819172a":"TestCoin2()","e8197a4b":"totalSuppliedAfterLock()","e81a6c58":"issueRefundIfNecessary(uint256)","e81b34af":"_deployContract()","e81b3c88":"CardCount()","e81b53d0":"computeCost(address,bytes32,bool)","e81ba080":"updateMaxCap(uint256)","e81c17a1":"setOwnerAt(uint16,uint16,uint8,address)","e81c2fec":"reDistribution()","e81ca129":"consumeTicket(address,uint256)","e81cf24c":"replace(uint256,uint256)","e81d53cf":"arr()","e81d6c6f":"reserveY2()","e81dd181":"callSoftCap()","e81e0a09":"Win(address,uint8,uint256)","e81e1ccc":"withdrawDonation()","e81e935a":"summPrivateSale()","e81ecb4c":"received(uint64)","e81f0154":"pipeIndex()","e81f02b6":"withdrawFrom(address,address)","e81f35fd":"setLastTokenId(uint256)","e81fdd77":"restCandy()","e8203e38":"emitWithdrawn(address,uint256,address)","e820a32f":"vetoPayout(uint256,uint256)","e820ce4a":"setCTime(uint256)","e8223468":"sha3clone(bytes)","e8227611":"setRealisation_effective(uint256)","e8238688":"setTokenVestingFactory(address)","e823b9bf":"toInt256Safe(uint256)","e823da03":"VKBToken()","e823fa20":"checkDragonStatus(uint256,uint8)","e824b9c7":"moftakToken()","e827653c":"referalCount(address)","e827b3e2":"latestPost(address)","e827f7f3":"request(bytes32,string,uint256)","e827ff89":"HDToken99(uint256,address)","e82898b3":"loser()","e828a293":"TestyToken()","e82906b3":"ISCoin(address)","e82935da":"like(uint256)","e8294aad":"bonus1Ends()","e8297da2":"defaultLockInDuration()","e829945a":"buyProperty(uint16,uint256)","e829a171":"MIN_GET_AMOUNT_FINNEY()","e829d86d":"releaseAgents(address)","e82a7d8d":"submitAnswer(address,uint256)","e82aa31f":"createTeam(uint256[])","e82b7cb2":"proxySetCosignerAddress(address,bytes32)","e82bef29":"fundAddress()","e82c6e7b":"totalTokenSales()","e82c6e8a":"mintFirstTokens(address,uint256,uint256[])","e82cc47f":"getFundInfo(bytes32,string,address,address)","e82d777c":"FHCContract()","e82db7a0":"Batman(uint256,string,string)","e82ed40c":"communityContributionWithdraw(uint256)","e82f7dd4":"testThrowsRetractLatestRevisionNotUpdatable()","e83029bb":"checkbalance(address)","e8303659":"ETHER_CAP()","e8307d00":"setMinPurchase(uint256)","e8315742":"maxTokens()","e831884e":"getPhaseAtTime(uint256)","e832b482":"channelConfiguration(uint64)","e832fda3":"select_at(uint256)","e833bb53":"FLKDForGas()","e833cc12":"getNamespace(uint256)","e83400f6":"getBudgetOfCampaign(bytes32)","e83447d0":"breakLink()","e834a834":"claimed()","e834e89c":"FlexCoin()","e8350fae":"proclaimInactive(uint8)","e8358025":"isCrowdSaleFinalized()","e835852b":"LogQueryFeeSet(uint256,uint256)","e835dd27":"STAKE_MIN_AGE()","e837ab59":"getParticipantByAddress(address)","e8380983":"BChain(uint256,string,uint8,string)","e8387af8":"_mint(int256,address,uint256)","e839554e":"getBasicCentsPricePer30Days()","e839e65e":"query2(string,string,string)","e83b2adf":"PTestYankeeCoin(uint256,string,string)","e83ba1fe":"stageFundGoalReached(uint8)","e83c0bba":"setEmployeeTokenAllocation(address,address,address[],uint256[])","e83c272c":"setTime2(address,uint256)","e83c460d":"TimeWeekOne()","e83c78d4":"toggleContractStopped()","e83ce1f9":"addAddressAlias(address,address)","e83cf468":"sendBattleTokens(address,uint256)","e83d1c5e":"LatestRechargeTime()","e83d589b":"getLLV_edit_24()","e83ded8e":"balanceOfLockTime(address)","e83dfe5a":"ConcludeChallenge(uint256,string)","e83e0359":"dividendsRightsFixUpdate_(address,uint256)","e83e34b1":"maxFees()","e83e92ac":"setSalesFee(uint256)","e83f682a":"beginContinuousSale()","e8400be5":"startBetting(uint32,uint32)","e840c116":"SocialNote()","e8421b94":"PlayToken()","e84221ef":"playBigOrSmall(uint256,uint256)","e8425467":"USDDecimals()","e8429510":"TokenForInvestor(uint256,uint256,uint256)","e8436936":"StatsMinted()","e8436ca5":"setMainCampaignStatus(bool)","e8443708":"PaygineHasDeployed(uint256)","e844ca34":"withdrawTokensToAdvisors()","e844cb18":"batatacoin()","e844d097":"addCandidate(uint256)","e845105c":"countriesLockEndingAt()","e846e7c0":"drawPeriod()","e846f1f4":"collectPercent(uint256)","e846f997":"contributionWallet()","e8474230":"getHybridizationFullPrice(uint256)","e8477bda":"setBuyMaxLimit(uint256)","e847ca9c":"BAXI()","e84818bc":"largeContribPercentage()","e8489626":"setProxy(address,address,bytes32)","e848aba2":"addWhiteListUsers(address[],uint256[],uint256[])","e849ec8c":"ChangeTokenContractOwner(address)","e84a481b":"adddotchtooffer(uint256,uint256)","e84b53bd":"addItemTo(address,uint256,uint256,uint256,uint256)","e84b69e4":"editTimer(uint8,uint256)","e84c9d5c":"removeWhitelister(address,address)","e84d2abf":"inMainSalePeriod()","e84d90c0":"checkDisabledStatus()","e84d92e8":"_getBridgeNativeFee(uint256)","e84f7054":"refundMyIcoInvestment()","e84f82f0":"emitBegin()","e85034a2":"walletTrade(address,uint256,address,address,uint256,uint256,bool,bytes32)","e85061ca":"playerAction(uint256,uint8)","e850899a":"StartPreSale()","e850a8ef":"payTo(address[])","e850e4c4":"GetContractStateEarlyTerminatedByLandlord()","e850efaf":"setRegionTax(uint16,uint8)","e850f3ae":"getGenerationIdForCall(bytes32)","e851808e":"CHARITYSEACOIN()","e8518341":"transferOwnershipWithHowMany(address[],uint256)","e8518be0":"requestReplaceOwner(address,address,string)","e8518dc6":"rateWithBonus()","e85230e9":"minETHin()","e85353e1":"admin_set_withdraw(address,bool)","e85365d5":"firstblock()","e8539244":"SetPayrollLocked(bool)","e85393d7":"WithdrawEmergency()","e853cda3":"checkKncArbitrageRate(uint256)","e853ce64":"joinTeam(uint256,uint256)","e854d135":"executeWill(address)","e854dfb4":"Order(address,uint256,uint256)","e854eeb3":"fciDecimals()","e85501d8":"revokeRequest()","e8554e8b":"getRaceBaseStats(uint256)","e855aee5":"_mint(uint256,address)","e8561d36":"cashBackFromProject(address,address)","e856528a":"mul(uint128,uint128)","e8580dd4":"Survey(address,uint256,string,bytes32[])","e85ac5b0":"ownerSetAuditor(address)","e85b26c0":"createClaim(address,uint256)","e85ca2a4":"bitcoin_multisig_vault()","e85dcfe8":"ScheduleTransaction(string,uint256,uint256)","e85de8e7":"valueInUSD()","e85e0bd7":"addToken(uint256,uint256,uint256)","e85e3d92":"LongClosed(address,uint256)","e85efc50":"assertEq(uint256,uint256,bytes32)","e85f3be6":"TOSPrivateHoldingContract()","e85f3fb0":"setAuthorizedSpender(address)","e86142b5":"orderOnSaleAuction(uint256)","e861c4f1":"dividendEndTime()","e861e34d":"minInvestInWei()","e861f077":"HaltStatus(bool)","e8625060":"testDisputedInvalidSequenceWrongWriteValue()","e863051c":"SmartForestCoin()","e86310eb":"exp(address,address,uint256)","e863a122":"getPercentageCW()","e863d8cc":"repeatedPayment(address,uint256,uint256,uint256)","e863f0d3":"acknowledgeOrder(uint256)","e8641652":"strCompare(string,string)","e86434ef":"startRefundPayment(uint256,uint256)","e864f2b6":"exchange(address,uint128)","e864fd27":"checkCap(uint256)","e8665638":"bonusVestingPeriod()","e866d302":"setJackpotWinCount(uint256)","e86701e0":"playerFlight(uint256,uint16)","e8672de9":"removeRatePlan(uint256)","e8679512":"getTransformInfo(uint32)","e867ecda":"setPricing(uint256)","e8685ba1":"getNumOfCandidates()","e8689bf8":"_emitUserRatingGiven(address,address,uint256)","e868b55e":"createReaderWriter(bytes32,address,address,bytes32)","e868cd17":"ManUnitedSC()","e86994ea":"getPropertyColors(uint16)","e869d45f":"registerScheme(address,bytes32,bytes4,address)","e86a3b8b":"WSIPrivateEquityShare()","e86a9b1e":"Custodian(address[],uint256,uint256,address)","e86afde0":"description(uint64)","e86ba262":"getTimeLimitForReplyOnProposal()","e86bf267":"takeCfd(uint128,address)","e86c6431":"isTransferManager(address)","e86c87d3":"func_0778()","e86cf04b":"TinyProxy(address,uint256)","e86d24ca":"getSmartSharingByHash(bytes32)","e86d86ea":"totalTransferWhitelistMapping()","e86dad29":"assetArray(uint256)","e86dea4a":"feeNumerator()","e86e3f2a":"setArrIntF1StrF2(int256[],string)","e86f2c75":"mainSaleSecondBonus()","e86f6699":"isWhitelistedAddress(bytes32,uint8,bytes32,bytes32)","e870a88e":"setnumMax(uint16)","e870bec1":"logging(uint256)","e871614a":"getResponseUint(uint256,bytes32)","e871f35f":"addCourse(string,uint256,uint256,string,string)","e872a05e":"addrMine()","e873d02d":"cap2(address)","e8742b55":"setComment(string)","e87508be":"investorDeposit()","e8755d00":"setServiceFee(uint256,uint256)","e8756037":"finishExchange()","e8757d19":"donations()","e875bfbc":"getMinimumFunds()","e8763023":"ProofOfAwareness()","e876bdef":"getEtherRaised()","e876c273":"TotalSupplySet(uint256)","e876e3f1":"investorsFee()","e87752f4":"icsToken()","e8777158":"grantVested(address,address)","e877e541":"bankuToken()","e877f910":"sendToContract(address,uint256,bytes)","e8787040":"ElevenElevenToken()","e8789d88":"getEndTimeOfStage(address,uint256)","e878d65f":"QIUToken()","e879790a":"HHRFallback(address,uint256,uint256)","e87a0a59":"EIB()","e87a9d84":"phase1AccountTokensMax()","e87aa769":"_getShinyPurity(uint16,uint16)","e87b0242":"ADVISORS_LOCK_DATES(uint256)","e87bbdbb":"spawn(bytes32,address,address)","e87c05c6":"restSupply()","e87c0ee6":"getGameCount()","e87c1463":"bidTicket(uint256)","e87da468":"addChild(bytes32,bytes32)","e87df70e":"fivetimes()","e87e77fe":"switchAirdrop()","e87ea055":"checkCurrentStage()","e87ed8b5":"RTB2()","e87f41bb":"deleteInvestorTokens(address[],uint256[])","e87ff056":"getTeamByPosition(uint8)","e8801360":"soldTokensCounter()","e8814606":"CryptosisToken(uint256,string,string)","e882f844":"DINAR()","e883429a":"isTransferAllowedteam()","e8836183":"blockLock()","e88390aa":"coinSendDifferentValue(address,address[],uint256[])","e883d157":"outstandingPower()","e88499a9":"claimPayout()","e8850978":"reportMissingChunk(bytes32,uint256,uint8,bytes32,bytes32)","e8853e32":"getData_28()","e8854cfd":"getPointer(uint256)","e885910f":"trackCrowdsale(address)","e885b81f":"Bonuslist(address)","e8862924":"decodedLocksroot()","e886dade":"bulkTransfer(address,address[],uint256[])","e887841e":"to(uint256)","e8878b11":"wakeUpProxy()","e88810ff":"presalePiDiscount()","e8884aee":"_useFromDailyLimit(uint256)","e88885fa":"price1Of(uint256)","e888e445":"CatalogoOuvidorias(bytes32,uint8,bytes32,bytes32,int256)","e88a728f":"getAssetIdOwnerAndOIndex(uint256)","e88ab341":"contributorsVestTokenAllocation()","e88b0067":"mintInvestment(string,string,uint256,address,uint256)","e88b8ac6":"confirmAndCheck(bytes)","e88b9436":"MYR_Omnidollar()","e88bc2ba":"Variation(address,address)","e88c6a8a":"moveToken(address)","e88d27eb":"registerProperty(string,string,string,string,string)","e88d9567":"changeDepositFee(uint256)","e88eff06":"setUserRoles(address[],bytes32[],address[],uint8[])","e88f3a86":"addBonusToBlock(uint256,uint256,uint256)","e88f4510":"LigerToken(address,address,address,address,address)","e88f4c6f":"usedCoreSupply()","e88f97bd":"query2_fnc(uint256,string,string,string,uint256)","e8903656":"executeSubscription(uint256)","e8906a2d":"addSigners(address[])","e89152ac":"ItemReceived()","e8916af9":"addLicenseTerms(bytes32,bytes32,bool,uint256,bool,uint256)","e891c9db":"validateWithdrawalSignature(address,uint256,address,address,bool,uint256,uint8,bytes32,bytes32)","e8927fbc":"increase()","e8928f7a":"setMaxWei(uint256)","e8930efd":"Investors(address)","e8932ea1":"burnClosedTokenInternal(bytes32)","e8936b29":"liveSince()","e894000b":"authorizedPower()","e89401a1":"multihash(bytes32)","e894326c":"addDepositCreator(address)","e8944564":"test_insert_findWithHintPrevRemoved()","e894f117":"TokenTimelock(address,address,uint64)","e8959b94":"addUser(int256)","e8974832":"levelTwoBonus(uint256)","e89826ac":"addGame(string)","e89876d6":"POSController(address,uint256,uint256,uint256,uint256)","e89927ef":"voteForCandidate(string)","e8992d40":"additionalTotalSupply(uint256)","e8997dbd":"setFeesController(address)","e899e848":"Fastmarketnetwork()","e89a49e2":"setPrivateName(bytes32)","e89a4e92":"getFeeRatioForJS(address)","e89ac5dd":"OrganizeFunds()","e89aeaca":"redeemLand(address)","e89b0e1e":"addAccount(address)","e89b2564":"Rate5()","e89b3ecb":"withdrawPUB()","e89b5d4b":"incrementInventory(uint256,uint256)","e89b727c":"myTotalStakeAmount()","e89b9ff6":"errCounter()","e89bc86b":"getBooleanMapCount(string)","e89c9b5d":"doThrow(string)","e89cdff5":"setTeamName(uint256,string)","e89d0d17":"getTeamLeaders()","e89d7f23":"payDividend(uint256,uint256)","e89df228":"shippingService()","e89f0f40":"DTR()","e89f3477":"grip()","e89f38d4":"BonusToken()","e89f5329":"createDebt(uint256,address,uint256)","e89f7672":"fight(bytes32,bytes32,bytes32)","e89f98a2":"TokenContractChanged(address)","e8a01f11":"BagSold(uint256,uint256,uint256,uint256,address,address)","e8a0aed3":"createToken(string,string,uint8)","e8a0cf44":"getScannersIds()","e8a0d312":"issueIndividualTokens(address,uint256)","e8a0e3c9":"BigbomPrivateSaleList()","e8a12479":"CBCT()","e8a1c08f":"nibbleToChar(uint256)","e8a207ad":"freeTokensAvailable()","e8a21157":"setNonEtherController(address)","e8a21382":"calculateInstantBonusAmount(uint256,address)","e8a2a5ba":"Resolved(address,uint256,uint256,bool)","e8a43960":"elixor()","e8a478ad":"round0Bonus()","e8a481bd":"edit(address,bytes32,bytes32,bytes32,bytes10,bytes32,bytes32,bytes32)","e8a4b797":"isTokenApproved(address,uint256)","e8a5282d":"setConfig(bytes32)","e8a55471":"_transfer(address,uint40)","e8a61357":"testInternal(uint256)","e8a61cc8":"refundBuyer()","e8a62235":"storeAction(address)","e8a6d7dc":"START_RATE()","e8a71012":"switchCrowdSaleStage()","e8a7228b":"hasEnoughValidSignatures(bytes,uint8[],bytes32[],bytes32[])","e8a748e7":"whitelistOneAddress(address)","e8a7be57":"MRVToken(address,address)","e8a7e256":"ownerTopUp()","e8a9594f":"rateOfEmissionPerYear()","e8a96b46":"getHolder(uint256)","e8a97ea8":"StateChanged(uint8,uint8)","e8aa1f5e":"makeOwnerBitmapBit(address)","e8aa377b":"storeHarvestOperation(string,string,uint32,uint16,uint16,string)","e8aa58ce":"vaultToWallet(address,uint256)","e8aa6b6f":"TeamtokenRelease4()","e8aabf9c":"ownerTransferWeiSecondWallet(uint256)","e8aada0c":"ViewBet(address)","e8aadc3f":"locationId()","e8ab245b":"WarriorsAssignedToBattlefield(address,address,uint256)","e8ac0e76":"getPropose(address)","e8ac764b":"twoMillionFourHundredThousand()","e8aca46a":"addReferral(address)","e8aca672":"getNodalblockURL()","e8acee9e":"fundPreSale()","e8ad1015":"__FindProjects(string)","e8ad2369":"getCaseAtIndex(uint256)","e8ad6912":"setGasForCLOUD(uint256)","e8ad7bcc":"secondTTax()","e8adf589":"getRateScale()","e8ae7dd2":"getCCH_edit_22()","e8ae8c6e":"DescriptionInt()","e8af214a":"fundingRemainingAvailableInEth()","e8afedd9":"setCommissionTarget(address)","e8b0a262":"ICO2Period()","e8b13c44":"getChainyTimestamp(string)","e8b1d0f3":"relayCall(address,bytes4,bytes)","e8b23632":"playerRefundAll()","e8b3891e":"userTransferUser(address)","e8b3ed65":"addDoc(string,string,string,string)","e8b49df2":"payWithEth(uint256,address)","e8b4c9d7":"OPEN_PACKAGE_PRICE()","e8b50802":"PRESALE_END()","e8b5e51f":"invest()","e8b611d6":"dailySupply()","e8b69081":"checkActionIsAuthorisedAndReset()","e8b6bbe4":"feeToSeconds(uint256)","e8b6fa80":"claim(int256,int256,int256,int256)","e8b9d536":"SingularityNetToken()","e8ba2fc9":"FundWallet(address,address)","e8ba854f":"updateWallets(address,address)","e8ba8f8b":"fixPlayerSurname(uint256,string)","e8bba4f6":"getDepositedOf(address)","e8bc0d40":"activateNextRound()","e8bccab3":"Neglect(address,uint256,uint256,int256)","e8bd09ff":"GetPlayerNumber(uint8)","e8bd5cc4":"NTRYPerEther()","e8be2e8e":"NewsContractEntity()","e8be3853":"setOffchainPayment(address,bool)","e8be73dc":"BenkiICO(address)","e8beef5b":"fireEventLog3Anonym()","e8befc0d":"getDividends(bool,address)","e8bfe5b8":"landmarkPriceStepNumerator()","e8bfebec":"ISSUE_METHOD()","e8c0485f":"profile(string)","e8c09c0d":"verificationHoldersValueMap(address)","e8c0a0df":"totalDepositBalance()","e8c23649":"referralName(string)","e8c28358":"calculateDispensedTokensForGasPrice(uint256)","e8c2cb16":"equal(string,string,string)","e8c32d13":"DoacaoEvento()","e8c3a65f":"save1(address,bytes,string)","e8c3e34d":"GetProperty(bytes32,uint256,uint256)","e8c494f1":"calcPresaleTokenSupply()","e8c4d328":"airDropNumber()","e8c4fa04":"coinIssuedGemmyMusic()","e8c5ff96":"jackpotLarge()","e8c61c4e":"actionB(uint256)","e8c66cac":"fundingReserve()","e8c67216":"getRateLimit()","e8c6ed14":"niceGuy()","e8c78934":"disableReservePurchases(address,bool)","e8c7df8a":"admin_token_add(uint256)","e8c80880":"VestingAddressChanged(address,address)","e8c8a52a":"reinvestDivs(uint256)","e8c8bb52":"_getRegistry()","e8c93aa9":"createProductionUnit7()","e8c96256":"Lesson_2(address,uint256)","e8c9a3e5":"withdrawnTokens(address)","e8c9f9de":"LocalToken(uint256,uint256,string,string,string,address,address,address)","e8ca1609":"startNewPayoutPeriod()","e8ca3bbb":"auctionsContract()","e8cb635b":"checkRequestSignature(bytes,bytes,uint256,bytes)","e8cc00ad":"withdrawOwner()","e8cf0aca":"depositEthersFor(address)","e8cf56a9":"C2L()","e8cf86ff":"MyTestCoin()","e8cf958e":"setBwMarketValidCaller(address)","e8cfc40d":"EtherPrice(uint256,uint8)","e8d03e91":"deployBoard()","e8d07525":"getLockerAddr(uint256)","e8d0affb":"addOwner(address,bool,bytes)","e8d0ed31":"sendInvestor(address,uint256)","e8d11d9c":"DavidCoin()","e8d1891b":"removeOracle(address,uint256)","e8d199ec":"BetterBitcoin()","e8d1e961":"lockAccount(uint256)","e8d320e6":"coinBalanceOf(address,uint8)","e8d3280f":"decrement(address)","e8d34f5d":"ensureCollateralBalance(uint256)","e8d375fe":"week_in_blocs()","e8d3a5a9":"joinboard(string)","e8d3cad5":"getDepositsLength(address)","e8d47923":"fAdd(uint256,uint256)","e8d50403":"ChangeDates(uint256,uint256,uint256,uint256)","e8d59fae":"PROMO_TOKEN_AMOUNT()","e8d663a4":"requalify(address)","e8d6b5aa":"TORCToken()","e8d6f62d":"p1Of(uint256)","e8d70569":"setGameAddress(uint8,address)","e8d83383":"whitelistMaxContribAmount()","e8d88bd4":"Race()","e8d8c3a7":"decreaseApprovalAllArgs(address,uint256,address)","e8d9d76a":"WCMY()","e8dc800c":"setReadings(bytes32,uint256,bool)","e8dca673":"throwsWhenSaleIsNotTokenController()","e8dcd15f":"NeuralProtocol()","e8ddb731":"myshowindex(address)","e8ddf15a":"withdrawEthBalance()","e8de636c":"add(bytes20,address)","e8df0ca1":"checkRefundPollDate()","e8dfa50d":"addPigment(address,uint256,uint256,uint256,uint256)","e8e03280":"window0EndTime()","e8e09563":"PresaleToken(address,address)","e8e0d5bf":"getConversionInfo(string)","e8e44248":"transferMiner(address,uint256)","e8e5882e":"SmartpoolVersion(address[3])","e8e7426e":"Presale(address)","e8e7c73d":"useMonthlyAccess()","e8e81fe4":"setTelegram(string)","e8e9eeae":"getPremiumCentsPricePer30Days()","e8ea0675":"redeemedEscrow(bytes32)","e8eb2284":"amountOf(uint256)","e8ebf3c5":"iii()","e8ecea05":"getSpecialNum()","e8ed024e":"LoopringToken(address)","e8ed1cdd":"getAccountQuantity()","e8edb2ff":"geneticallyEngineer(string)","e8edc816":"spender()","e8ee8b44":"MIS()","e8ee8c75":"deleteCandidateBySnapshotBlock(address,uint256)","e8eecf4c":"maxTxValue()","e8eed374":"hashTerms(string,string)","e8ef51db":"getCCH_edit_15()","e8efc1a0":"updatedValue(bytes32)","e8efe846":"blocksOwners(uint256)","e8f00990":"calcPlayerDivs(uint256)","e8f04e84":"disableLotteryGiveHunt()","e8f09e24":"getDisableBet(uint256)","e8f1736c":"TakeMoney()","e8f1bd8c":"getNeighbourhoodOf(uint256)","e8f1dc9a":"_unpackMakeData(uint256)","e8f35f2c":"updateUSeqvol()","e8f3cd59":"getFunderContributionClaimed(address)","e8f4bc12":"InitUpgradeCard()","e8f54364":"JJ(uint256,string,string)","e8f5cf36":"changeWCT2Controller(address)","e8f62764":"feesController()","e8f62f46":"someMethod2(uint256,uint256,uint256)","e8f64680":"purchaseFor(address,bytes32,uint256)","e8f6bc2e":"changeAccountLevelsAddr(address)","e8f72850":"interactWithXYZ()","e8f88890":"dev_inStream()","e8f8a1d2":"buyBuyerTokens()","e8f95666":"transferPreSigned(address,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","e8fa1d51":"handleCloseChannel(address,bytes32,uint256,address,uint256,address,uint256)","e8fac4cd":"transfer(address,address,address,address[],uint256,uint256)","e8faf89c":"ETHER_MAX_CONTRIB_USA()","e8fb02d2":"sellFeeMilliPercent()","e8fbc67d":"MultisigWallet(address[],uint256,uint256)","e8fc0780":"_malloc(uint256)","e8fc451a":"init(uint256,uint256,address,uint256,uint256,uint256,uint256)","e8fc9273":"verify(address,string)","e8fc9c10":"UnicornContract(address,address,address)","e8fcda45":"_set8()","e8fe6b66":"getCode(bytes32)","e8fe9473":"test_threeInvalidEqUint(int256)","e8ff269e":"setMaxAvatarNumber(uint8)","e900604d":"claimTokenOwnership(address)","e9007d4e":"settleGame(uint256,uint256,string,uint256)","e9013cf7":"getFreelancerInvoicesByStatus(address,address,uint8)","e9024691":"recoverPreSignedHash(address,bytes4,address,uint256,uint256,uint256)","e9024ff5":"modifyMessage(string)","e90352eb":"_transferCheck(address,address,uint256)","e90389bd":"setWaitingTimeBuffer(uint256)","e90459f8":"emitError(bytes32)","e906c804":"_distributeBridgeFee(uint256,bool,bool)","e906e664":"getx2Policy(address,uint256,uint256,uint256)","e90799d2":"unlock4Circulate(uint256)","e9083a41":"drainMe()","e9084739":"economyBoost(uint16,uint16)","e9085957":"RANGESTART_1()","e9087eb7":"canMove(address)","e908a6d6":"Initialize_PlayUnit(uint256,uint256,uint256)","e9092bca":"weeOneEthCanBuy()","e90956cf":"setCurator(address)","e909ebfa":"addDelegate(address,address)","e909f2cc":"updateCancelDistFlag()","e90a3cf2":"addressCashwolf()","e90ab7fe":"lunetReserve()","e90acd53":"bidder(bytes32)","e90bcb32":"senderToProxy(address)","e90cb9b9":"setBurnAddress(address,address)","e90d2120":"etcWallet()","e90dae86":"TokenAUC(uint256,string,uint8,string)","e90dd9e2":"tokenState()","e90e5453":"rand(uint256,uint256,uint256)","e90ecfce":"EvoToken(address)","e90f84bd":"getETHFromTokens(uint256)","e9105cf1":"unblockTokens()","e9108538":"mintSilcToken(address,uint256)","e91208ad":"galleryFour()","e9121758":"token_holders_array(uint256)","e9121b12":"transferAndApply(address,uint256)","e9126154":"returnLoan(uint256)","e912ae4f":"getLastPaidTransaction()","e9130d4a":"test_twoInvalidEqBytes()","e9140274":"stakeTAOContent(uint256,uint256,bytes8,uint256,string,string,string,string,uint256,address)","e914575b":"endPublicIcoForTesing()","e9149e34":"investedWei()","e914d828":"TimeMoneyToken()","e9156cfe":"getMutation(uint32)","e916d0f0":"doBalance(address)","e916d29e":"matchBytes32Prefix(bytes32,bytes)","e91710aa":"DogCoinCrowdsale(uint256,uint256,uint256,uint256,address)","e9171abb":"airdropRecipientCount()","e91723b2":"aggiungi_candidato(string)","e9177f1b":"HTCToken()","e917b027":"setProjectManager(address)","e917f82d":"OxyCoin()","e918268b":"changeDrawer(address)","e9187ef4":"refundAction(bytes32,uint256)","e9198076":"fillBuyOrderPartially(uint256,uint256,uint256)","e919ca10":"getMyDiscount()","e91a08a2":"grantedParsecCredits()","e91a68bf":"getAllRightLeg()","e91b3ac5":"getMutalbeInfo()","e91b6987":"addNewObj(address,uint32)","e91bb26e":"redeemEgg(address)","e91c3a3e":"getStatusInfo()","e91cc17c":"withdrawFunder(address)","e91ccdc0":"allFundingProcessed()","e91cd09d":"thisbalanceETH()","e91d1ea0":"downtime()","e91dcba1":"MDL()","e91df414":"Nurucoin()","e91df8da":"AuctionSoldOut(uint256)","e91e10af":"allocationFinished()","e91e13a9":"CHUNK_SIZE()","e91f9d96":"getNftsByOwner(address)","e91ff7ca":"STORAGE_WALLET()","e921528e":"evTransfer(address,uint256,address,address,uint256)","e921b4f8":"buyByAddress(address)","e922248e":"MinterFunc(address,uint256)","e92254ba":"finaliseFunding()","e922ee6f":"removeParent(address)","e9233a65":"getNameIds(uint256,uint256)","e92340b5":"ICO_BONUS_TIME_2()","e923c3d6":"_setUint(bytes4,uint256)","e923e707":"hardCapWei()","e9253156":"force_deduct_fees()","e9262dae":"changeMinApproval(uint8)","e9263f9d":"ifcoinToken()","e9266fca":"collectRobot(uint256,uint256,uint256,uint256,uint256)","e92704e8":"setGason(uint32,bool)","e927a8c0":"changeContracts(address,address,address)","e927ca04":"addVesting(address,address,address,string,uint256)","e927da3f":"buyPackWithKitty(uint256)","e927ea7a":"ballotVoteCount(uint32,uint32)","e927f1f9":"getLeaderBoardData(address)","e927fc5c":"creatorAddress()","e9288d72":"pushToBank(address)","e928ad47":"createEthBidAuction(uint256,uint256,uint16)","e9298b97":"changePermissions(address,uint8)","e92a5d74":"createTimeDecayingToken(uint256,uint256,uint256,uint256,uint256,string,uint8,string,uint8)","e92b6818":"CONTRIB_PERIOD1_STAKE()","e92b7f4b":"AddVoters(string)","e92ba335":"airdropCountLimit1()","e92bb686":"_CallAborted(address,bytes32,bytes18)","e92bf2a8":"saveData(uint256,bytes32,uint8,bytes32,bytes32,bytes32,address,address)","e92c02cf":"startOpenWindow(uint256,uint256)","e92d5178":"bankerBeginTime()","e92dfb23":"LimitBalance(uint256)","e92e4505":"test_9b_testGoodTransfer_thenInvalid()","e92e4d63":"setReservingStep(uint256)","e92e5c34":"getVoterCount(uint256)","e92e5f03":"PRESALE_TOKEN_SUPPLY_LIMIT()","e92f2904":"Compra()","e92f7447":"isDayThird()","e92f8cfc":"MIN_BUYBACK_VALUE()","e92f9c1d":"getWarriorsFromIndex(uint256,uint256)","e92fdeaa":"ethRec(uint256,uint256,uint256)","e930f06f":"setToSaleWallet(address)","e930f3a6":"ethContractBalance()","e93119d9":"balanceOf(address,address,uint256)","e931f1ba":"secondRoundMayEnd()","e931fa0c":"setMonsterGene(uint64,uint256)","e93239d3":"outputWalletAddress()","e9324444":"preSaleState()","e93314ab":"getS()","e9333fab":"set_admin(address)","e9339de5":"Moneda(address,address,address)","e933cfb0":"mintCard(uint256,address)","e933e6eb":"checkPriceCrowdsale(uint256,uint256)","e9347e31":"_sellKeys(uint256,uint256,bytes32)","e9348532":"kncRateBlocksTrade()","e934ab0c":"ActualCommitteeRoom()","e9353cb7":"createProductionUnit3Beta()","e9358b01":"newENS(address)","e9360096":"cancelCompetition(uint256)","e9361d34":"ethartRevenueReward()","e93680d5":"_my_transfer(address,address,uint8)","e936e878":"disburser()","e9377aca":"mtEndTime()","e937f689":"_getElement(string,uint256)","e9391db9":"getBenificiary()","e9395679":"uintToString(uint256)","e93a1906":"buyFeeMilliPercent()","e93ab977":"bids_ignored_refunded()","e93b9c89":"stepVestingPercent()","e93ba042":"distributePrices(uint256)","e93ba06f":"getWhitelistAt(uint256)","e93c5973":"UpdateRequiredSignatures(uint256)","e93c980d":"tokenUnit()","e93d3e5f":"setNextRoundFee(uint256)","e93e25fe":"zilleriumToken()","e93e40db":"offerCollectibleForSale(uint256,uint256,uint256)","e93e7b26":"Stage3Deadline()","e93f29bd":"_setPartitionControllers(bytes32,address[])","e93f3f8d":"setBuyPrice(uint256,uint256)","e93f57b9":"capAmount()","e94087d6":"joinAsBroker()","e941fa78":"withdrawFee()","e94200f1":"burnAllOwnerTokens()","e94233f6":"oraclizeGasCost()","e942b516":"set(string,string)","e942c564":"getWei(uint256)","e9433ab6":"endDonations()","e943cc01":"powerDayEndTime()","e944267c":"FourArt()","e9445d5a":"createAudit(uint256,uint256,uint256)","e94479a9":"MinterRemoved(address)","e944a6d7":"claimSpecialResource(uint256)","e944f52d":"addressToBytes(address,address,address)","e94559b1":"ETToken()","e945c391":"setEndTime(uint64)","e945e26c":"CCH_OLI_1()","e946115b":"flushVault(uint256,address)","e946ad4a":"getUpgradesOwned(address,uint256)","e947962b":"pushRefIncome(address)","e9482aa6":"UsingANormalStruct()","e9485982":"canBePurchasedByETH(uint16)","e949fba1":"_getPurchaseToken(address,uint256)","e94a4db1":"isSuitableGen(uint256,uint256)","e94acf0e":"TinyRouter(address)","e94aea8a":"lastStealBlockNumber()","e94b6aef":"getLayEggInfo(uint32)","e94c8dc0":"NXX()","e94d7af6":"getCountAllBuildings(uint256,bool)","e94dc568":"freeBalancesOf(address)","e94e4bf1":"maxDailyCap()","e94e80fa":"playerIndexToApproved(uint256)","e94e83d8":"Answer(string)","e94f1dc6":"setWhitelistInternal(address,address,uint256)","e95015b9":"spawnMonster(uint256,address)","e9506c73":"_investAsBonusProgram(address,uint256)","e9519a6b":"FirexToken()","e951c35b":"NewAppleToken()","e9523c97":"getAllAdmins()","e952f74f":"airdropCount()","e9540395":"getRewardDivisor()","e9546d08":"increaseK()","e95502fb":"lockedShares()","e9556430":"SECONDS_PER_MINUTE()","e9559803":"getShipById(uint256)","e955ee03":"revertNoncsallocation(address)","e9560b3b":"getParticipantBalance(address)","e95626c5":"Lizun()","e95715cb":"jackpotSend()","e9577a11":"getHistBtcRate(uint256)","e95823ad":"safe(bytes32)","e958d15f":"partnerMessagesCount(address,address)","e958d1ae":"TreeContract()","e9592a9f":"AuctionStarted(uint64,uint64,address)","e9596db3":"betInfo(bytes32)","e95a644f":"checkIn(uint256)","e95ac9f7":"LBToken(address,uint256)","e95af01b":"identify(address,address)","e95b2bb8":"Ethraffle_v2b()","e95b4aa8":"nameOf(address,address)","e95bcfb1":"UVDICO()","e95bd5f2":"testToData(bytes)","e95bee59":"checkFormat(string)","e95d0a59":"MarbleEarth(address,address)","e95d716c":"FEE_SELECT_MARGIN_SPLIT()","e95d74e0":"set_coin_minimum_trade(string,uint256)","e95db6f9":"buyKey()","e95f206e":"MIN_WEI_AMOUNT()","e95f2c7d":"getMaxLoanAmount(uint256)","e95f6414":"dayPotExpiration()","e95f72e3":"ROD()","e95fa798":"SellerCancelDisabled(bytes32)","e9600f12":"release(bytes16,address,address,uint256,uint16)","e960127e":"set2RoundTime(uint256)","e960b940":"DoubleSixToken()","e960bb48":"balanceOfLocked(address)","e9616fb0":"changeFreezingAgent(address,bool)","e962867d":"BillionsToken()","e9629d7f":"phase1Cap()","e96309e7":"gatherOldBalanceOf(address)","e9639c80":"releaseTheOriginal(uint256)","e963f3e8":"MAX_BUYIN_GAS_PRICE()","e9653482":"hasValidProfile(address)","e966668c":"advisorset()","e9668128":"isTransactionsAllowed()","e9677b6b":"safeExecuteOrder(address,uint256,uint256,bytes,int256)","e967a9b7":"dataSourceCallbackExtras(uint256,uint16)","e967bb18":"refundAllMoney()","e967e60c":"placeBid(string)","e968ab95":"enableTokenTransferability()","e968d087":"shrink128(uint256)","e968e1ec":"setPLATPrice(uint256)","e9698f62":"setBurnAmountApproval(address,address,uint256)","e969c871":"swapTokens(address[],uint256[])","e96a6b38":"getSignerFlagFor(address)","e96b462a":"isOwner(address,bytes32)","e96b5e13":"SERENITY()","e96b8aa6":"bitwordsWithdrawalAddress()","e96bf86d":"lastHour()","e96cd01c":"SoraToken()","e96d01d4":"setPlayerOverrideId(uint256,uint256)","e96d36ac":"communityAllocating()","e96d6e4f":"publicKeys()","e96da99e":"reply(bytes32,uint256)","e96e5950":"getEventHash()","e96fefec":"resetTransferToValues()","e9703701":"byteToUint(bytes1)","e970754b":"getTxs(uint256,uint256)","e970e86d":"testBlockNumber()","e9715de9":"referralBonusPercent()","e97193a6":"removeAuthor(address)","e971c252":"issue(address[],uint256[])","e972261d":"calculateProfit(uint256,uint256)","e9734172":"createWagerAndDeposit(bytes32)","e9739db7":"getTokenRate(uint256)","e973b7ba":"node_height(uint256)","e973f2c4":"reinvest_color(uint256,uint256,uint256)","e9742d23":"createGun(uint256)","e9748e58":"renewalsCreditAffiliatesFor()","e974c000":"checkIsOnlyOwner(bytes32)","e97758a2":"thirdRewardPeriodEndBlock()","e977992d":"Doubler()","e9779b76":"depositOldTokens(address,uint256)","e977a11c":"wavesAssetId()","e977fa76":"_forceTransfer(address,address,uint256)","e9794dc1":"CreateHash(uint8,string)","e9799993":"Wafflecoin()","e979af97":"pushArray(bytes32,string)","e979bac1":"getCustomerBankRating(string)","e979fed6":"ownerstake()","e97a4779":"evaluateProposalPreCondition(uint256)","e97b2190":"add_wall(uint16)","e97b7689":"getTotalBuyers()","e97b97fe":"neumark()","e97cf883":"calculate(uint256,uint256,uint256)","e97cfab4":"withdrawDivs(uint256)","e97d87d5":"releaseStartTime()","e97db66e":"setJackpot()","e97dcb62":"enter()","e97e490c":"canuse(address)","e97e6dca":"applyPresale()","e97ed99c":"TurtleFarmer()","e97f6313":"token_airdrop_amount_each()","e97fe114":"tradeModifiers(address,address)","e98096fc":"numberOfNames()","e980c2e0":"littafiContentCommit(bytes32,string,string,string,string,bool)","e9813f9c":"_distinctOwners(address,address)","e981c803":"rejectPauseChange(bool)","e982d5a9":"transferOwnership1(address)","e9835ee1":"LogAgreementAmended(address,string)","e9841bd8":"certifyTradeAsCounterparty(bytes32,address)","e98444e8":"BIMI_DAO_31_a()","e984d794":"setRarity(uint256,uint256)","e984dd74":"ZenixSupply()","e985e367":"saleToken()","e985e9c5":"isApprovedForAll(address,address)","e9874106":"pricePerTicket()","e98799e0":"Mejasa()","e987cc45":"getfrom(address)","e9884b44":"depositClient()","e9886064":"_sendPrimordialTokenAndRewardDev(uint256,address)","e988998a":"refreeze()","e9892821":"isSpendableFrozenCell(address,uint256)","e9893c67":"awardAmount()","e98a0de7":"setGitHub(string)","e98a1439":"priceOfMultiple(uint256[])","e98ae339":"cancelMarginCall(bytes32)","e98b1679":"set_pre_kyc_bonus_denominator(address,uint256)","e98b7f4d":"getKitty(uint256)","e98bf38e":"test_insert_zeroKey()","e98c365b":"totalMigratedOut()","e98c7608":"mod9710(bytes)","e98cab50":"burnIndexed(uint256)","e98cf987":"turnOnSale()","e98d3112":"OwnableWithDAO()","e98dcba2":"approveExchange(address,address,uint256)","e98e130c":"GetCandidatePrincipal(uint8)","e98e8a64":"getKeccak(bytes32)","e98ebdd5":"numResponses()","e98f402c":"getClassCheckOwner(uint64,address)","e98f5708":"Dgp(address)","e98fe5ce":"AgriChainType()","e9900714":"sendIBTCToken(address,uint256)","e991ae55":"valid_weights(int256[],uint256,uint256,uint256[])","e9922f12":"getCoinInfoFromId(uint16)","e992ae5a":"INCXToken()","e992d8d8":"KNC()","e992f6cd":"pos(address[],uint256)","e99358a5":"TeamtokenRelease2()","e9938919":"EnterBetsForRaz(uint256,uint256[])","e9938e11":"getPricePerCoin(uint80)","e99392c0":"localsAvatar(bytes32,address,bytes32)","e993a9c0":"change_flag_hash(bytes32)","e993c056":"SaloniToken()","e9947583":"addAuditorToMultiRequestAssignment(uint256,address)","e995064e":"changeEmployee2(address)","e995194f":"transfer(address,uint256,uint256,int256)","e99543aa":"Trash(uint256)","e9958314":"getRequest(uint32)","e9959105":"setMintHelper(address,int256)","e99667ad":"OwnershipTransfer(string,address,address)","e99671ad":"movePermission(address)","e9970b6c":"isLessThan(uint256,uint256)","e99718d8":"addressOf(address,bytes32)","e9986f90":"activeStarGenome(address)","e9989220":"viewShareholderListing(uint256)","e998d2fa":"revokeVerification(address)","e998db2a":"directMessage(uint8,string)","e99a7a72":"createCeleb(string,uint256,address,uint256[6],uint256[6])","e99a7dca":"lastCampaignID()","e99b9ab7":"getProposalCreatedOn(address,uint256)","e99d2866":"setSeller(address)","e99d2db4":"universalToken()","e99d7333":"BlitzCrypto()","e99ebee2":"dist_multiple_airdrop(address[],uint256)","e99ed199":"getAddressLiquidatePool()","e9a0dd77":"cancelBid(bytes32,int32,bool)","e9a158a6":"currentETHPrice()","e9a1e689":"PreICO(uint256,uint256,uint256,uint256,address,address)","e9a241cc":"checkRoundsNumberToRun()","e9a24e24":"userlength()","e9a3773c":"setBotContract(address)","e9a3f454":"setAgriChainSeal(string)","e9a51c0d":"call1(uint256)","e9a5605d":"WheelOfFortune(uint256)","e9a58c40":"fun(uint256,uint256)","e9a59b32":"participantRoundAmount(address,address,uint256)","e9a5c776":"THETOKEN()","e9a62ba6":"MEGAMALLCOIN()","e9a6cce4":"getClaimKeysCount()","e9a6fdc3":"addressAt(bytes,uint256)","e9a765eb":"checkICOStatus()","e9a76ff7":"getInputName(uint256,uint256)","e9a78a1e":"decodedNonce()","e9a909a2":"setOraclizeAddrResolverI(address)","e9a9c1b4":"get_party1_balance()","e9a9c50c":"redeemTokens()","e9aa80b1":"contributorsAddress()","e9ab04a8":"hatchEgg(uint256,string)","e9ab1bd7":"True()","e9ab77e5":"getTimes()","e9ac31f2":"msgdata()","e9ac5918":"whatDidJasonSay()","e9ad1b38":"findAddressByEndpoint(string,int256)","e9ad72d7":"_canLotteryFree(address)","e9aeb932":"dUpgradeToPremium(bytes32)","e9afa7a1":"signedApprove(address,address,uint256,uint256,uint256,bytes,address)","e9afad38":"getTotalVesting()","e9b00581":"LogStartWeek(string)","e9b04e69":"addSourceForBudget(uint256,uint256,string,bool)","e9b07bbf":"transfer(address,uint256,bytes,bytes)","e9b0c0e1":"adminContractSecurity(address,bool,bool,bool)","e9b18084":"Diary(address,bytes)","e9b1f1ce":"updateRandomSource(uint256)","e9b23b8b":"updateLeaderboard(address,address)","e9b29a9d":"setAPI(address)","e9b2f0ad":"unfreezeTokens(address,uint256)","e9b32a3f":"HOUSE_EDGE_DIVISOR()","e9b3fd39":"TradeBox()","e9b48288":"insertMessage(string,bool)","e9b4a028":"payAirdrop(address[],uint256)","e9b54840":"viewReferral(address,uint256)","e9b58225":"extDestroyBot(uint256)","e9b5a2f7":"firstWithdraw()","e9b62f13":"lastBlock_f4()","e9b6953b":"team1Token()","e9b85cf4":"SimpleOwnedStorage(string)","e9b93569":"OwnerGetFee()","e9b991cc":"refundPct()","e9ba267e":"distributeETHP(address[])","e9ba2e9b":"Storage(uint256)","e9ba77fb":"receiveToken()","e9ba8698":"TheBillionCoinCash()","e9bacc1a":"freeBalances(address)","e9bb4aac":"WaltonTokenLocker(string,address,address,uint256)","e9bb84c2":"transferEth(address,uint256)","e9bbc19e":"Example3(string)","e9bc13b8":"_createCanvasInternal(address)","e9bc63f7":"getSellInfo(uint256)","e9bc9598":"totaltransactions()","e9bce432":"yetAnotherTransferTo(address,uint256)","e9bd48b8":"VLTToken()","e9bd97dc":"getData_24()","e9bdab6a":"tips(address,bytes32)","e9bec833":"setCrowdsalePause(bool)","e9c003d2":"indexOf(bytes32[],bytes32)","e9c1a9c4":"ProcessGame(address,address,bool,uint256)","e9c24166":"executeRequest(bytes32)","e9c26893":"setValidDurationData(uint256)","e9c2fbd5":"Banned(string)","e9c31315":"checkBetParity(uint8,address,bytes32,bytes32)","e9c33249":"ReceivedBTC(address,string,uint256,string)","e9c33dfe":"getHouseEdgeFee(uint256,uint256)","e9c35ea8":"universalCall(string)","e9c4a3ac":"dispatch()","e9c54384":"doesContractImplementInterface(address,bytes4)","e9c63b9c":"requestPeerBalance()","e9c64ad7":"evRecord(address,uint256,string)","e9c6c176":"addBlock(uint256,uint256,bytes32)","e9c6ed11":"withdrawNomins(uint256)","e9c714f2":"_acceptAdmin()","e9c771f2":"KBItoken()","e9c801e1":"refundInternal(uint256)","e9c9262e":"_productExists(uint256)","e9c93ce7":"cbtFundDeposit()","e9c9db5c":"ICOcontroller()","e9c9f4e0":"_finalizeFailure(uint32,string)","e9ca9b2a":"phase1StartingAt()","e9cac389":"onlyWhitelistedCanDoThis()","e9cafac2":"deleteArray()","e9cb364f":"lastTip(address,bytes32)","e9cbd678":"_resetBalanceDivis(address)","e9cddb1d":"EARLY_BET_INCENTIVE_COMMISSION()","e9ceef50":"createCanvas()","e9cf287a":"sellerGuaranteeEther()","e9cfa745":"calculateNetworkTokenBonusAmount(uint256,uint256,uint256,uint256,uint256)","e9cfb399":"SoupToken(string,string)","e9d16224":"maxFundedValue()","e9d1c598":"isEligibleForAirdrop(address)","e9d1d700":"assertFunction()","e9d1e422":"JZCoin()","e9d36c56":"transferredAmountToReceive(uint256)","e9d41d48":"getAuthorizationDataSource()","e9d56d2e":"releaseDividendsRightsForce(address,uint256)","e9d5d43b":"getWinnerByDrawBlockNumber(uint256)","e9d724e5":"changePreIcoEndDate(uint256)","e9d7d79a":"SRNT_per_ETH()","e9d7f309":"addRemainingTokens()","e9d862b0":"_updateTokensAvailable(uint256)","e9d8d3d7":"MAX_CONTRIBUTION_DURATION()","e9d8dbfd":"isService(address)","e9d979dd":"CioCoinERC21Token(uint256,string,string,uint256)","e9d9c4a9":"devTokenTimelock()","e9d9d5ec":"releaseBBT(address,uint256)","e9da12ab":"ATRToken()","e9db5d79":"Steak()","e9db5f5a":"addSpecialAccount(address)","e9db787b":"cancelStack(bytes32)","e9dc0614":"vote(bytes)","e9dc2e49":"createItem(uint256,uint256,uint256,uint256,uint32)","e9dc438e":"confirmAllSells()","e9dd7b6c":"getUID(uint256)","e9de432f":"testGasPrice()","e9de5c0f":"gen(bytes32,uint256)","e9de78fd":"TestRobotarCrowdsale()","e9deb98c":"presaleConcluded()","e9dff847":"withdrawMatingRequest(uint256)","e9e04195":"GEEKSID()","e9e041f3":"getTotalWeightedContribution()","e9e22362":"setWinPercent(uint256[])","e9e2990e":"bankManager()","e9e2c786":"returnMessage(uint256)","e9e30746":"withdrawBankroll(address,uint256)","e9e32bfb":"firstLevelPrice()","e9e3b1cf":"checkAuthenticity(string)","e9e43eef":"getLLV_edit_10()","e9e44349":"hashLicenseTerms(bytes32,bytes32)","e9e48842":"token_unlock_time()","e9e48880":"BOUNTY_AMOUNT()","e9e55c71":"PRESALE_LEVEL_1()","e9e69a48":"getCurrentPageSize()","e9e7a667":"get_stake(bytes32)","e9e7e908":"BlockOfLifeToken(uint256,string,string)","e9e972d9":"fileLink()","e9e98e76":"WSKYCoin()","e9e99d81":"getChannelFeed(address,uint256,uint256,uint256)","e9e9b5bc":"setIntF1F2(int256,int256)","e9ea666b":"test_remove_singleNode()","e9eaa69b":"sweepToOwner()","e9ebeafe":"greet(bytes32)","e9ec9e8b":"renounceBurner()","e9ecc0cf":"getInvestorsTokens(address)","e9ecd32b":"RajTest()","e9ed8281":"getDiniRequest(uint256)","e9ed8667":"balanceLocks(address)","e9ed9b64":"setProposer(address,bool)","e9edd759":"CCoinToken()","e9edf4cd":"hardwareWallet()","e9ee6eeb":"transferAdmin(address,address)","e9ef5318":"_isValidLandID(uint8)","e9efdd6b":"getByFrom(uint256,uint256)","e9f0509f":"Commit(uint256,address,bytes32)","e9f0ee56":"addPrice(uint256)","e9f12ed3":"itemsByName(string)","e9f1c4c3":"f2(uint256,uint256)","e9f21537":"setUint(bytes32,bytes32,uint256,bool)","e9f29b7b":"setTokenUriPref(string)","e9f2dbfb":"makeCommitment(uint256,bytes32,address,address)","e9f3b9ee":"triggerSteal(uint32,uint256)","e9f4043f":"buyTokens(address,uint8)","e9f50b02":"_transferHelper(address,address,uint256)","e9f58a52":"rotate_left(uint256,uint256)","e9f6af47":"getZethrTokenBankroll(uint256)","e9f6bd0b":"numberOfDays()","e9f702f2":"createDiamond(string,address,string,string,string,string)","e9f84c5b":"ClearToken()","e9f88ca5":"ICHAINToken()","e9f89121":"getWeeklyJackpot(uint32)","e9f8cd70":"addTokenPair(address,address,uint256,uint256,uint256,uint256)","e9f90fe6":"listPokemons(address)","e9f998ce":"checkInventory(uint256)","e9f9d8e2":"unidentifyParticipant(address)","e9fa6277":"updateMasks(uint256,uint256,uint256,uint256)","e9fa65aa":"updateNextStealTime(uint32)","e9fad716":"itemPrice(address,address,uint256,uint256)","e9fad8ee":"exit()","e9fb078e":"setFreeTime(uint256,uint256)","e9fca283":"buy(uint256,bytes32)","e9fcc787":"buyCoinsAtICO()","e9fd3434":"Cedex()","e9fd4e1f":"setAllowCnsContract(bytes32,address,bytes32,bool)","e9fd74dc":"create(string,string,uint8,uint256,address,string,address)","e9fe799e":"registrantRemove(address)","e9fee16f":"refundAll(uint256)","e9ffd6de":"allBlockCoordinates(uint256)","e9ffdf28":"Erc20Dist()","ea00a289":"getStateofContractString()","ea00cdb2":"DrazenToken()","ea00fad4":"callSender(address,bytes4)","ea011db4":"isCustomerHasKYCfromWL(address)","ea014645":"PTYC(uint256,string,string)","ea020f7b":"WindToken()","ea0217cf":"setVotingPeriod(uint256)","ea02db0f":"communityPoolAddress()","ea03918c":"AGC(uint256,string,string)","ea03c115":"getFunctionType()","ea045f34":"CROSS_RESERVE_FTX()","ea048256":"PROCOIN()","ea049958":"stakeScale(address,uint256)","ea05667a":"maximumPurchaseFraction()","ea0570e0":"convertToBytes32(uint256)","ea0599c7":"buyIt()","ea05cd01":"addCarProduct(string,uint32,uint32,uint32,uint32,uint32,uint256,uint256)","ea061e77":"changeNeat(address)","ea06ad02":"postBuyTokens()","ea071ac0":"depositShares()","ea083b86":"contract_enabled()","ea08bb89":"creatureCosts(uint8)","ea08ec2c":"accountModifiers(address)","ea0930f2":"_currentTime()","ea0a5237":"announce(string)","ea0a73d2":"TokenGMCT(uint256,string,string)","ea0a93e2":"miningLeader()","ea0aee14":"BuyStockRocketEvent(address,uint32,uint32,address)","ea0d0015":"_bill_all_participants()","ea0d1027":"calculateSumToWithdraw()","ea0d1702":"verifyEscrowCustomer(uint256,address)","ea0d18b0":"CurrenXToken()","ea0d5dcd":"getUserStatus(address)","ea0d6ad2":"setErrorROFR(bytes)","ea0d8da4":"amountReserved()","ea0d98aa":"changeParticipants(uint256)","ea0f5449":"Transaction(bytes32,address,address,uint256,uint256)","ea107240":"deleteRegionData(uint256)","ea10b18f":"withdrawMainDivi()","ea10d246":"get_orders_sell_amount(address)","ea110eda":"setOraclizeGasLimit(uint256,uint256)","ea112b6c":"updateCrowdsaleAddress(address)","ea116243":"_setCampaign(bytes32,uint256,uint256,uint256,uint256,bool,address)","ea118590":"vote_proposed_address(string)","ea11e00e":"LogMatchingEnabled(bool)","ea1325be":"createTokenUri(uint8,uint8,uint64,uint64)","ea135eeb":"computeSha3(uint256[16],uint256[8])","ea14457e":"emitRecovery(address,address,address)","ea149ab5":"bank2Val()","ea14bc11":"box1Star5()","ea15f262":"ETHEREAL()","ea1642f8":"getManyBalances(address[])","ea16c148":"isIcoAgent(address)","ea16cee5":"migratestate()","ea177073":"nextMaxPlay()","ea18e3d5":"getFreeSword()","ea19efb5":"startVoting(bytes32)","ea1a20d5":"shareholdersWallet()","ea1a9537":"IOBSTestToken()","ea1b28e0":"maxStake()","ea1bbe35":"getIndex(string)","ea1bf386":"getNextSellerBOTdata(uint256)","ea1c0379":"maximumAllocationPerParticipant()","ea1c1690":"timestampToDateTime(uint256)","ea1c41be":"RxEALSaleContract()","ea1cf495":"ImagodeiToken()","ea1d64b8":"startPostIco()","ea1da8b9":"updatePresaleMinWei(uint256)","ea1df439":"timestampFirst()","ea1e4c2d":"Transaction2()","ea1e572b":"addOrderBasicFields(uint256,address,uint256,uint256,bytes32)","ea1e74ef":"withdrawEtherToIfPossible(address,uint256)","ea1eaecb":"buyMinersWithGem(uint64)","ea1ecff4":"sendByTranches(bytes32[],address,uint256[],bytes)","ea1f2954":"transferSnowflakeBalance(string,uint256)","ea1f4082":"RGXToken(string,string,uint256,uint256,uint8)","ea1f9b3e":"NoxonInit()","ea2028b7":"changeSaleHardcap(uint256)","ea212b1e":"withdrawRequest(address,bytes32)","ea217d4d":"logSaleStart(uint256,uint256)","ea21c6be":"find_and_or_register_user(address,address)","ea21d12d":"deleteUncompletableRequest(bytes32)","ea222fde":"getAmbientLightControlLimits(bytes32)","ea22ee15":"LOG_EmergencyWithdrawalVote(address,bool)","ea23c473":"scheduleUpgrade(address,string,string,bytes32,uint256)","ea2470ab":"priceLocked()","ea251c2f":"owner_BurnUpdateTokenFrom(address,uint256)","ea25415a":"getAcceptedGames()","ea25f24a":"TokenCreation(uint256,uint256,address)","ea26b575":"Eth_Collected()","ea273277":"setAyantDroitEconomique_Compte_8(uint256)","ea274a6b":"processBuy(address,uint256)","ea27a881":"getMinimumEndowment(uint256,uint256,uint256,uint256)","ea28baee":"getRealWorldPlayerRosterIndex(uint128)","ea295ec2":"calcRevenue(address)","ea29a210":"TokenVesting(address,uint256,uint256,uint256)","ea2a31fc":"NMK()","ea2a33fc":"getInitialREPSupply()","ea2a9599":"callThisToStart()","ea2bc862":"optionDescription(uint256,uint256)","ea2c23da":"createAccounts(uint256)","ea2c2f36":"doubleBonus(address)","ea2c4357":"newTokenUnlockPercent(uint256)","ea2c69d1":"Marijuaneum()","ea2ce651":"isTokenUpgrader()","ea2d4cf8":"__DeployerFunctions(address,address,uint256)","ea2da598":"NLToken()","ea2e34f2":"isTransformAgent()","ea2ea847":"testChallengeFinalize()","ea2f28d3":"countWeeks()","ea2f43c3":"currentIncreaseWithdrawalTeamBallot()","ea2f9ebe":"retrievePoolFee(uint256)","ea2fe1a2":"nay()","ea3015b8":"burnUnusedTokens()","ea304511":"changeParameters(uint256[],uint256[],uint256[],uint256[])","ea30e2e6":"XiaoMuMuToken()","ea316027":"creditWalletUserLMNO(address,uint256)","ea317f6d":"setdissolveprice(uint256)","ea31b291":"getCreatorByTrackId(uint256)","ea31c53c":"_openGameLoop()","ea31ccb6":"rICO(address,address,address)","ea31d56b":"mintTrusted(address,uint256)","ea326431":"Neulaut()","ea32a8f4":"addshares(uint256,address)","ea32c95e":"EMPTY_PUBLIC_KEY_ID()","ea3367ae":"divMasterAmt()","ea337cdb":"batchChangeHoldPeriod(uint256)","ea33dd24":"developer_increase_prices(uint256,uint256)","ea341309":"catsRemainingToAssign()","ea348da6":"FuckERsToken33()","ea352634":"closeChannel(bytes32,uint256,address,uint256,address,uint256,bytes,bytes)","ea359082":"End4()","ea35df16":"unlockBlock()","ea35e805":"calculateWinner()","ea364a9a":"addSingleApprovedAddress(address,address,uint8)","ea36ad91":"transferERCXTokenInitiation(string,address,address,uint256)","ea383176":"month30Allocated()","ea391420":"endIcoRound()","ea3b3a91":"recoverAddress(bytes32,uint256[3])","ea3b9ba1":"enter(uint256,address)","ea3bd5df":"purchase(uint256,uint256,address)","ea3c281a":"removePartner(address)","ea3d2827":"selectWinner(string)","ea3d4109":"rateIsStale(bytes4)","ea3d508a":"selector()","ea3d7e2c":"getOraclizeGas()","ea3d895f":"vestingBonusMultiplier()","ea3ebae6":"getConfigBool(bytes32)","ea3f190e":"devFee2(uint256)","ea3f6ce0":"joinGroupAndInvest(uint32,address)","ea4061cc":"calculateToFund(address,uint256)","ea4099e4":"QuantumPigBlockchain()","ea40c9e7":"ARCHETYPALXToken()","ea414b28":"setTaxWallet(address)","ea41bca5":"doStake(address,uint256,uint256,address,address)","ea42418b":"settlementContract()","ea428bad":"ACLYDcidTOKEN()","ea4354dc":"totalDividendWinners()","ea43671d":"watchPercent()","ea439e10":"transactionRawToBytes(uint256,address,address,uint256,bool,bool)","ea43b069":"PRIVATE_SALE_TOTAL()","ea43b79f":"unhaltDirectTrade()","ea448370":"setUserEmail(string)","ea454da8":"WonderDogToken(uint256,string,uint8,string)","ea46193e":"getEtherBalance()","ea46336b":"ShiversToken(uint256,string,uint8,string)","ea4634a7":"MarginlessCrowdsale(address)","ea46d7b9":"TACOS()","ea470d33":"voteForAnswer(uint256,address,bool)","ea4796b9":"revertIfReturnLessThanMinAndDie()","ea47cb24":"ownerAccount()","ea486cb1":"moderList()","ea490b84":"ethereumForkArbiter()","ea49ac03":"allScamsForSale()","ea4a294f":"addCard(uint256,uint256)","ea4a6aad":"LogQuantity(uint256,string)","ea4af029":"ConferenceCertification()","ea4afc54":"reserves(address,address)","ea4b466b":"admin_deposit(int256,int256)","ea4b9dce":"getLastBetNumber()","ea4ba8eb":"getOutcome(bytes)","ea4c4388":"createCredit(uint256,address,uint256)","ea4cc26d":"CryptoPayment()","ea4cc7eb":"divvy(uint256,address,uint256)","ea4ce239":"totalSale()","ea4dfce9":"benAddress()","ea4e6ded":"getListOfSupportedTokens()","ea4ef51f":"relockPart(address,uint256,uint256,uint256,int256)","ea4efa5d":"ganeshrajToken()","ea4f0882":"clearVolumeDiscounts()","ea503429":"privateSaleWallet()","ea5136a1":"adminUpdateSettings(address,address)","ea515c98":"pgoUnlockedLiquidityWallet()","ea51c343":"verifyLoanOffering(address[9],uint256[7],uint32[4],bytes32,bytes)","ea520b18":"totalDrop()","ea5366c1":"set_contract2address(address,address)","ea56a44d":"changeUpgradeMaster(address)","ea57712a":"SetFreeMKI(uint256)","ea57d818":"EmilToken()","ea5815f5":"getDatesForUser(address)","ea584ee6":"changeFreeZombiewCount(uint16)","ea58c644":"EUSD()","ea58c955":"powerDayRate()","ea58ca03":"DATE_01_JUN_2018()","ea593025":"giveKarma(uint256,string,string)","ea595672":"_transfer(address,address,uint32)","ea596a34":"EBIT()","ea598cb0":"wrap(uint256)","ea599cb3":"totalAward()","ea59a4e8":"GetPlayer_FromAddr(address,uint8)","ea5a13aa":"coindropsTokens()","ea5a22eb":"mintax()","ea5b2ae2":"checkIsWinner(uint256)","ea5b561f":"guardian1Vote()","ea5c204b":"MecStandardToken(uint256,string,uint8,string)","ea5c3204":"foundersAmount()","ea5ea470":"payFunding(uint256)","ea60e4ab":"Yusuf()","ea60e79b":"preICOLimit()","ea612545":"setBorrowAgreement(uint256,uint256,string)","ea62f24c":"unlockTeamAdvisorsPartnersTokens()","ea636aca":"setNinjaContract(address)","ea63ceb6":"allowAccount(address,bool)","ea64ad37":"totalUserTransfered()","ea64aee5":"GameBidAccepted(address,uint256,uint256,uint256,bytes,bool)","ea64faca":"init(string,string,address,uint256,uint256,address,uint256,address)","ea650378":"getTokenIDRelateWithTx(bytes32)","ea650c7d":"tokenToExchangeSwapOutput(uint256,uint256,uint256,uint256,address)","ea663631":"openTimerElapsed()","ea66543f":"isEmployee(address)","ea669a8a":"setTusdRegistry(address)","ea6723cd":"usdMnr()","ea680080":"firstAuctionsReferrer()","ea681932":"weiWantedOf()","ea6825aa":"VieToken()","ea6955e5":"ownerWithdrawUnspentCredits()","ea6a49ea":"setBetPrices(uint256[])","ea6b1377":"MAXTOKENSOLD()","ea6be96f":"estimateTokens(uint256)","ea6c1258":"setFSTKCentral(address)","ea6c9750":"transferToInvester()","ea6ca182":"addAgingTimesForPool(address,uint256)","ea6cc6e9":"delayedTokenAllocator()","ea6dee80":"addKey(address,address)","ea6ef2fe":"teamShare()","ea6f0725":"initCompoundContract(address,uint256,uint256,uint256)","ea6f1c4a":"sponsorLevel()","ea6f67e1":"SingularityTes26()","ea6f7f3e":"addAllValidShaHashes()","ea7000d6":"buyTokens(bytes32)","ea70b4af":"pendingCount()","ea70bdad":"attackTileForExistingUser(uint16,uint256,bool,bool)","ea726acb":"getReferrerAddr(address)","ea727ba2":"changeInterest(uint256[])","ea72d9de":"SENS_PER_ETH_BASE_RATE()","ea737b54":"getCompte_42()","ea74329c":"tokensRemainingPreCrowd()","ea74838a":"setControllers(address[])","ea7553f0":"vault_wallet()","ea75d311":"isBuyOrder(bytes32)","ea760a6b":"kkICOTest80()","ea760df8":"partner1_vows()","ea769e97":"changeTradeState(bool)","ea76a36f":"Mahjongcoin()","ea770a4c":"getNewCoinsIssued(uint256,uint256,uint256)","ea773d9e":"blink()","ea77d01a":"buyWarriorChest(uint256)","ea780bf2":"overloadedMethod(address,uint256,string)","ea782500":"curr_number()","ea7858f5":"player_cancelGame(uint256)","ea7873db":"addCompany()","ea794ef4":"constructWeaponTokenIdForWinner(uint256,uint256)","ea79dd79":"equal(bytes32,bytes32,string)","ea79f33d":"uniquenessIndex()","ea7a0142":"setRemark1(string)","ea7a7184":"testGetBalanceDb()","ea7b5df3":"pecunioTokenBalance()","ea7c2115":"lookupKittyDetails2(uint256)","ea7cabdd":"checkAllOwner(uint256[],address)","ea7ceaf7":"stopRefunds()","ea7f4d27":"right13(uint256)","ea7f537a":"percentOfGoal()","ea7f7a59":"finalizeLottery(uint256)","ea7f9244":"getRank08()","ea801802":"AviaC01n()","ea8037d6":"batchEscrowToTeamContract(address,uint32[])","ea8118ba":"Trustcoin(address)","ea8269f4":"balanceAddress(address,address)","ea82fa2a":"VestingScheduleConfirmed(address,address,uint256,uint256,uint256,uint256)","ea83add4":"DoTrade(address,address,uint256,address,uint256,address)","ea842e65":"deleteTeam(uint256)","ea8466dc":"LBQ(uint256,string,string)","ea84a6cd":"memberShare(uint256)","ea84bfee":"update(address,bool)","ea851885":"buyStake(bool)","ea85b367":"create(address,int256,address,address)","ea85b581":"Deadpool2RottenorFresh()","ea85c7ac":"getOriginalSpinnerPrice(uint256)","ea863e62":"JorgeToken()","ea87003c":"setRenamingCosts(uint256)","ea871246":"LOW_RANGE_RATE()","ea87152b":"register(string,uint256)","ea879634":"getCode()","ea87a0aa":"updateItemsPrices(uint256[],uint256[])","ea88246d":"Transction()","ea885b55":"UNDERWAY_STATUS()","ea89c6bc":"TrackChain()","ea8a0a23":"PlotTerrainUpdate(uint256,uint256,address,uint256,bytes32)","ea8a1af0":"cancel()","ea8a4305":"Zigicoin()","ea8a66c7":"absoluteMinTimeLock()","ea8ab096":"XEV()","ea8acb67":"_transferToContract(address,address,uint256)","ea8af87d":"sumPreICO1()","ea8b03c2":"innerGuess(uint256,uint256,uint256,address)","ea8b3e9f":"setFlag(string,uint256)","ea8b4627":"playerLastScoredGame(address)","ea8b5ca3":"isContractExpired()","ea8b73df":"createEthCommunityTokenAndMint(string,uint8,string,uint8,uint256)","ea8c1516":"isBlockedAccount(address)","ea8d103f":"transferFundToAccount(address)","ea8dc8d0":"buyTicket(uint256,uint8)","ea8e84a1":"RecoveryEvent(string,address)","ea8eb4be":"blockingDuration()","ea8eee87":"updatePrivateExhangeRate(uint256)","ea8ef515":"airdropSameAmount(address[],uint256)","ea8ef6be":"getBranch()","ea8f6691":"mintSpecificCard(address,uint8,uint256)","ea903c78":"setEndStage3(uint256)","ea905308":"LogSaleCapReached(uint256)","ea90ad7e":"FAUT()","ea91ec69":"TokensReleased(uint256,uint256,uint256)","ea91f8c7":"showMyTokenBalance()","ea920b2b":"betSummary()","ea92dd1d":"withdaw(uint256)","ea932954":"withdraw_token(address,uint256)","ea9362de":"maxMintingTime()","ea93a324":"getCreateShareTokenCounter()","ea941538":"TradeExecute(address,address,uint256,address,uint256,address)","ea94c696":"distributeAmount(address[],uint256)","ea94eaa2":"CreateTokenByAtes(address,uint256,string)","ea95e4d8":"BreezeCoinICO()","ea961d78":"decreaseTokensMulti(address[],address,uint256[])","ea963a21":"ReconCongress(uint256,uint256,int256)","ea9707a3":"getCaptainIndexToCount(uint32)","ea9746a2":"FNTCrowdsale(uint256,uint256,uint256,uint256,uint256,uint256,address,uint256,address,address)","ea983f7f":"Alfacoin()","ea985057":"BountiesMinted(address,address,uint256,uint256)","ea98847b":"withdraw2()","ea988ebd":"mine1000(uint256)","ea98de9f":"runDividendPayment()","ea98e540":"proxyTransferFromToICAPWithReference(address,bytes32,uint256,string)","ea98fcf9":"tokenForBounty()","ea9960d8":"participate(bytes32[],bytes32[])","ea996c9c":"approvedRewardSources(address)","ea99e689":"withdrawFeeRate()","ea9a3eb5":"AFWToken()","ea9ac537":"emitExchangeFeeUpdated(uint256)","ea9ae72e":"setPosTokens(uint256)","ea9b4be5":"Rearden()","ea9b6025":"burnTimeChange()","ea9c2859":"CurrentGoldPercentIncrease()","ea9c3bb3":"ico2_startdate()","ea9c8e63":"addSmartContracts(address[])","ea9ce8fd":"redeemToken(bytes)","ea9e107a":"acceptRegistrarTransfer(bytes32,address,uint256)","ea9e372f":"withdrawImpl(address,address)","ea9eb855":"setWLMTPrice(uint256)","ea9f0c4c":"Partial20Send()","ea9f4968":"withinLimit(uint256)","ea9fa768":"newWeiController(address,address,uint256,bool)","eaa0e760":"automaticWithdrawLoop(uint256,uint256)","eaa1f9fe":"reqisterListening(address)","eaa26f0f":"withdrawal_delay()","eaa2b2f6":"kill(string)","eaa2f447":"BelottoCoin(address)","eaa37394":"create(bytes,bytes32,bool,bool,bool,bool,bool)","eaa382c2":"isMintingManager(address)","eaa40283":"getNewsContractAddress()","eaa4077a":"SetICOPhase(address,uint256,uint256,uint256,uint256,uint256)","eaa42a15":"_setSnapshotStakeAmount(uint256,address,address,uint256)","eaa47de2":"RickAndMortyShrimper()","eaa59c74":"rejectShipping(uint256,string)","eaa61dc2":"changeLicenseTerms(bytes32,bytes32,bool,uint256,bool,uint256)","eaa61e91":"BagpackicoToken()","eaa643d5":"StandingOrder(address,address,uint256,uint256,uint256,string)","eaa8e6d8":"LifeFactor_iii()","eaa968cc":"closeBet()","eaa9b9a7":"timestamp_ack()","eaaad8e9":"masterKeys(address)","eaabd05e":"setTokenSwarmHash(address,bytes32)","eaac77a7":"priceTokenWeiPreICO()","eaac77ea":"supply_cap()","eaacc753":"verifyHolder(address,string)","eaae46e5":"clearClaims(uint32)","eaaf2489":"_registerContributors(uint256,address)","eaaf88c1":"setTeleportContractAddress(address)","eaaff394":"getListing(uint64)","eab07d42":"GetDayCount(uint256)","eab15085":"setData_9(string)","eab184b8":"JLCToken()","eab228b9":"PRE_ICO_TIER_LAST()","eab23779":"validateAndGetTransferFee(address,address,address,uint256)","eab27a7c":"getMigrateInReporterValue()","eab2d378":"setPauseMode(bool)","eab4fb18":"THIRD_PARTY_LOCKUP()","eab5cd84":"createHONtokens(address)","eab65fb2":"EmpAgreements(address)","eab88624":"lockMoney(address,uint256,uint256)","eab8d67b":"GetPlayerAt(uint256)","eab9eb2d":"sellGrapes()","eabbcb4b":"startIco(uint256,uint256,uint256,uint256)","eabc8b8e":"canBeBidden(uint256)","eabd11af":"RandomNumGenerated(uint64)","eabd5dd6":"superman()","eabd94ba":"tryUnlock()","eabd9e60":"BlackNWhite()","eabdd572":"withdrawDAI(address,uint256)","eabe09ad":"addr1()","eabf1ce3":"Approved(address,address,uint256,string)","eabf4240":"mintableTokenAddress()","eabffab6":"VestingScheduleRegistered(address,address,uint256,uint256,uint256,uint256)","eac037b2":"tierBudget()","eac046ce":"AFFBToken()","eac116c4":"createKingdom(string,address,address,address,address)","eac12cae":"stage1Tokens()","eac1e58f":"PRICE_BTCS()","eac24932":"setEarlyParicipantWhitelist(address,bool)","eac257dc":"StandardTokenImpl()","eac2f8d9":"MultiOwnable(address)","eac34569":"redeemLottery(uint256)","eac38f75":"_rotateRight(bytes32)","eac3e799":"target1()","eac449d9":"revoke(address,uint256)","eac471a0":"cycleLength()","eac472bf":"p_setDevPercent(uint256,uint256)","eac48278":"mintToFounders()","eac50c47":"setOnSale(uint256,bool,uint256)","eac533e1":"privateSell2Token()","eac5426f":"setOwnTheDayContract(address)","eac58572":"transferDuringIntialOffer(address,uint256)","eac5a89d":"checkWhitelisted(bytes32,bytes)","eac5ab43":"verifyModule(address,bool)","eac60b27":"AddTag(address,string)","eac66cd8":"getNumberContracts()","eac80b2d":"changeVariables(uint256,uint256)","eac8221e":"previousRoundsCount()","eac8f5b8":"getAsset(uint256)","eac9d94c":"averageGen0SalePrice()","eaca7a0f":"setBaseTokens(address,address)","eacb05d8":"Total_ICOSupply()","eacb6c08":"addressToSubscriberCount(address)","eacba6c7":"setFounderUser(address)","eacbc236":"emitTransferToICAP(address,address,bytes32,uint256,string)","eacbe9ca":"removeDeal(bytes16)","eacc25e7":"Team_Wallet()","eacc501a":"setTransferFeeReceiver(address,address)","eacc5b3b":"safeSend(address,uint256,uint256)","eaccb2e8":"transferOperationsFunction(address)","eacccaf0":"setReward(address,uint256)","eacd2141":"ReasignTokens(int256,int256)","eacd2ff3":"addCar(string,address,uint256,uint256,uint256,bool)","eacde2cb":"tokenIdByIndex(uint256)","eace4827":"player_make_bet(uint8)","eaced5b7":"setSoldTokens(uint256)","eacf7d8a":"MAX_EXPIRE_DELAY()","eacfb78a":"getServerName(uint256)","eacfc0ae":"Authorized()","ead0327d":"getNickName(address)","ead04e44":"addressIsSplitter(address)","ead0f75a":"capFinalized()","ead17f58":"bonusWindow3EndTime()","ead1ed5b":"registerPayment(address,uint256,uint256)","ead2a439":"getUniqueAddressByIndex(uint256,address)","ead2bfdc":"getGamePrize(uint256)","ead2fba4":"setApprove(address,address,address,address,uint256)","ead3a1de":"QYQ(uint256,string,string,address)","ead3c2cf":"multiMint(int256,address[],uint256[])","ead490ad":"recoverLeftoversICO()","ead491ac":"getMarketDataByTokenIdx(uint256)","ead4c32c":"dividendCalculation(uint256)","ead4faaf":"Starmid(uint256,string,string,uint8)","ead50da3":"frequency()","ead5d359":"withdraw(address,uint256,bool)","ead710c4":"greet(string)","ead81e86":"addCourse(uint256,uint256,string,string,string)","ead956c1":"_orderTokens(address,uint256,uint256)","eadb2481":"TransfersEnabled()","eadb6e84":"startRitual()","eadb6fa9":"deleteAccountsInBulk(address[])","eadb80b8":"ownerOfChild(address,uint256)","eadc56d2":"betting(uint256)","eadcbf39":"MFTcreator()","eadd2f91":"distributionTwo(address)","eadd94ec":"usdRaised()","eadd9c8d":"CabChain()","eadddb3c":"getRoomCount()","eaddf568":"WhitelistAddressRemoved(address,address)","eaddf7b9":"getNextImageId()","eadf1f39":"lastBlockRewarded()","eadf4672":"checkScope(address,address)","eadf9760":"setUint(bytes32,string,uint256)","eae00565":"getVotesResult()","eae19df4":"tokenReceived()","eae3d479":"createItem(uint256,uint256,uint256,uint256)","eae445ed":"masternodeInfo(uint256)","eae45561":"setWhitelistedBatch(address[])","eae4c19f":"deployedAt()","eae4e5ce":"getPersonalAirdropAmount(address,address)","eae5a62d":"getProposedOwner()","eae6754a":"totalEthDeposited()","eae70d5e":"setprize(address,uint256)","eae7236f":"transferBack(uint256)","eae81c37":"getDeployedGames()","eae8675d":"getCompanyToken(uint256)","eae8a3d6":"setMigrate(address)","eae8cf88":"Zitron()","eae903e3":"CreatePayroll(address)","eae9dbec":"RESERVED_BUSINESS_GROUP()","eaea25ec":"blockSubsidy(uint256)","eaeb83a2":"User_4()","eaec3fc8":"addCantonEmployee(address)","eaec75aa":"finalizeBuyback()","eaecfca7":"changeBackend(address)","eaed2210":"TransactionCancelled(address,uint256,string,address)","eaefea72":"addStringTag(bytes32,bytes32)","eaf03fc5":"withdrawFromFeeBalance()","eaf0ded9":"presale_price_in_wei()","eaf16303":"DYC(uint256,string,string)","eaf18c45":"setTTMTokenAddress(address)","eaf214ea":"changeTxnTax(uint256)","eaf2402d":"_getStartIndex(uint64)","eaf2a5ef":"itemNum()","eaf39a14":"setCustomBonus(uint256)","eaf4170c":"implementsSaleClockAuctionListener()","eaf4181a":"stopPortalGunAndRick()","eaf4438f":"SuperEdge()","eaf44931":"TokenReturned(address,uint256)","eaf49a82":"numAnimalsXType()","eaf4b6df":"allocate3ProjectToken()","eaf5815a":"recoverAddr(bytes32,bytes)","eaf59375":"returnUnsoldSafe()","eaf626c2":"Set(bytes32,address,address,uint256)","eaf6d212":"getCertificateSince()","eaf7e325":"getNumItems()","eaf82213":"getContributionsForAddress(address)","eaf8294b":"fundTransfer(uint256)","eaf86db3":"isSellingState()","eaf8b774":"getAllbetByNum(int8,int8)","eaf97475":"disableAutoReinvest()","eaf98d23":"FEE_PERCENT()","eaf994b2":"mintReputation(uint256,address,address)","eaf9d194":"updateNameAndSymbol(string,string)","eafac339":"ICOendtime()","eafb2b7a":"setMembershipType(address,uint256)","eafb704f":"majorEventFunc(uint256,bytes32,bytes32)","eafc99a7":"frenzyContract()","eafde28c":"unwrapEth()","eafe5eec":"joinGameWithBalance(uint256)","eaff4b37":"FundsWithdrawn(address,uint256)","eaffb3f9":"rebond(uint256)","eaffd429":"getOrganisations()","eb0030b3":"Paydata(address,uint256,bytes,uint256)","eb009642":"mapInvestors(address)","eb00f20e":"utilityAccount()","eb0166d9":"AccountBalance(string,string,uint256,string,string,uint256,uint256)","eb01d83b":"getBidAmount()","eb01f42d":"KOIOSTokenPreSale(address,uint256,uint256,uint256,uint256,address)","eb0207e3":"hPayMultiSig()","eb02c301":"getPosition(uint256)","eb03085b":"set_bonus_received()","eb0331d5":"destroyAccount()","eb03791b":"BastetToken()","eb03db73":"suicideFunds(address)","eb03e351":"purchased_snt(address)","eb03fb71":"winningValue()","eb045789":"ChannelSeries(address)","eb04c36c":"fundingRaised()","eb04df1d":"setRNGCallbackGasConfig(uint256,uint256)","eb053fad":"calc(bytes4,bytes32,uint256,address,bytes24)","eb05920e":"func_2(string)","eb05bfc0":"disableSaleOwner(address)","eb0616e5":"gimmePizza()","eb068fe5":"F0001Token()","eb06980f":"userAtIndex(uint256)","eb06e65e":"allowanceFromProxy(address,address,address)","eb06ec32":"rewardTaskCompletion(uint256,address)","eb08aa3b":"preSaleAddress()","eb08b304":"changeMeatProvider(address)","eb08dbfc":"emitBurned(address,uint256)","eb09ad46":"EthernautsExplore()","eb09b5bc":"FUNCToken(uint256,string,string)","eb0a70c1":"hasVersion(string)","eb0bfa38":"setRegionPrice(uint16,uint256)","eb0c9e5a":"verifySignature(address,uint256,uint8,bytes32,bytes32)","eb0db6ac":"setChemistryAddress(address)","eb0e9240":"checkNumber(uint256)","eb0eea61":"Securities_4()","eb0f2100":"sweep(uint256,address,uint256,uint8[],bytes32[],bytes32[])","eb0f46cc":"revokeAccessMint(address,address)","eb0f4b33":"numOwnershipStatuses()","eb0f5186":"_determineDefence(uint256)","eb0fb0a3":"setTokenToOwner(uint256,address,bool)","eb1098b8":"packLimit()","eb10b4bd":"getSettingDeprecation(uint256)","eb11dd7b":"squirrelReq()","eb121e2f":"update(uint256,uint256[101][])","eb1257c5":"create(int256,int256)","eb12d61e":"addSigner(address)","eb12fd82":"setRates(address[],address,uint256[])","eb12fef5":"nAddressLog()","eb1301a2":"addAddressToUncappedAddresses(address)","eb142e36":"_setUserInfo(address,uint64,uint256,address)","eb14367d":"layEgg(uint64)","eb14b353":"setGenesis(address)","eb14f53e":"batchTransferEther(address[],uint256[])","eb15d21b":"QiToken()","eb1635ed":"getMintingPrice(uint256)","eb18747a":"getGoldStatusCode(address)","eb18ebdf":"product4()","eb18fbe7":"setPreIcoEnd(uint256)","eb195635":"IQT_DECIMALS()","eb1ab91b":"AtomicSwap(address,uint256,bytes32,uint256)","eb1bb9d9":"hybridizationListSize()","eb1cae39":"EvNewPrice(uint256,uint256)","eb1cfa82":"setMaxDrops(uint256)","eb1d380e":"callContractFunctionByAddress(address,string,address,address,uint256,uint256,bool,string,bytes32)","eb1d74c8":"UpdatedBonusAccount(address)","eb1de3e5":"ICDStopTime()","eb1e2cd9":"getPlayerAccountBalance(address)","eb1ea5be":"clearTracks()","eb1ebd93":"BLS_TOTAL_CAP()","eb1edd61":"FEE_ADDRESS()","eb1f9c78":"HasDelegateAuthority()","eb1fa690":"queryVestingRemain(uint256,uint256)","eb1ff845":"changeId(uint256,uint256,uint256)","eb222098":"ProGenTech()","eb229f1e":"totalSupplyFromInventory()","eb230b2d":"bobClaimsDeposit(bytes32,uint256,bytes32,bytes20,address,address)","eb239d9a":"timeAdjustNeg()","eb245d91":"custodianTransfer(address,address)","eb24ffdd":"getCountriesData(uint256[])","eb26df0a":"updateDiscounts(uint256[],uint256[])","eb28615e":"createCommunityToken(string,uint8,string,uint8)","eb28d249":"setMissions(uint256,uint16)","eb28ddcf":"_isTAOSignatureAddressValid(address,address,address,uint256)","eb290e12":"Mimicoin(uint256,string,string)","eb295b27":"getChannelId(address)","eb29d9ea":"transferWithEther(address,uint256)","eb2a783e":"canBuyExistentToken(uint256)","eb2a7c4a":"freeLottery(uint256)","eb2b381a":"toDecimals(uint256)","eb2b6e95":"PUNDI()","eb2bab77":"increasePot()","eb2bdbab":"getBUU(bytes32,uint256)","eb2bef47":"BetterAuction(address,address,address,uint256,uint256)","eb2c0223":"upgradeContract(address)","eb2c118a":"ExtTokenPurchase(address,address,uint256,uint256,uint256)","eb2c6a19":"setInvestorWhitelist(address,bool)","eb2c87a4":"partner2_vows()","eb2cf098":"get_data_item()","eb2f3038":"buyout(address,uint256)","eb2f4817":"requestAccess()","eb2f8696":"_getCurrentSecret()","eb2ff2d2":"softCapPreSale()","eb3087bf":"buyFci(address,uint256)","eb30db7b":"trade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,string)","eb30f57d":"maxEthToRaise()","eb31f3d0":"Zoltan()","eb321173":"claimStake()","eb32cf9b":"saleExchangeRate2()","eb338f4e":"raiseMaxNumInterests(uint256)","eb343301":"registerCertWithID(bytes32,bytes,bytes32,uint256,bytes32)","eb34967a":"gameGeneration()","eb34c173":"firstAuctionsStartDate()","eb34fa12":"CurrentTLSNProof(address,string)","eb357e99":"payment_time()","eb35a849":"getSignerby()","eb36622d":"readBytes32(bytes32)","eb36d549":"WINR()","eb36f8e8":"stringToBytes64(string)","eb3721be":"getMarketOrder(uint256)","eb37df4f":"getGiftsByTemplateId(uint256)","eb381429":"mint(int256,uint256,bytes32)","eb38615b":"setLiveTx(address)","eb39bc90":"setPropertyColors(uint16,uint256[5])","eb39f443":"startMintingDate()","eb3a2345":"setFunding(bool)","eb3a733f":"responseOptions(uint256)","eb3a867b":"LogVote(bytes32,bool,address)","eb3a88dc":"lockupTokens(address,uint256)","eb3b0ab3":"setFeeLocked(bool)","eb3b41be":"OrderFulfilled(uint256,uint256)","eb3b6891":"throwsWhenTransferingDuringSale()","eb3beb29":"silo()","eb3c8d7d":"changeMaximumValueWithoutProofOfAddress(uint256)","eb3cd55c":"setEveryBidFee(uint256)","eb3d032d":"FAPFundDeposit4()","eb3de344":"whitelistInvestor(address,string,string)","eb3f1b61":"allocateAngelWheelFinanceToken(address[],uint256[])","eb3f2427":"plainPay()","eb3fa926":"manager_()","eb3fee82":"setCompte_16(string)","eb40a9c8":"setRecommenderAllow()","eb41fbca":"changeTargets(uint256,uint256)","eb42b0cb":"payBeneficiaries()","eb4435a3":"Github()","eb4439fb":"enableVoting()","eb446ad8":"WHITELIST_SUPPLIER()","eb4475a1":"reducerunmoney(address,uint256)","eb44bb04":"frozenPool()","eb44dd5d":"preSale5Finished()","eb44fdd3":"getMarket(uint256)","eb455dc6":"sendBitcoin(string,uint256)","eb464316":"TOKENSALE_BLACKLIST()","eb46a11a":"setInvestorId(address,bytes32)","eb470ebf":"getTimeStamp(address)","eb473fc7":"alreadyAvailedOffer(address,address)","eb49168f":"getIntervals(bytes32,uint256)","eb496a80":"exploitMe(bytes8)","eb4999f4":"ticket1price()","eb4a2935":"getScribes()","eb4b41b2":"disableAmbassadorMode()","eb4b8091":"payWinners(address[20],uint256[20])","eb4be616":"CanBaoToken()","eb4c5593":"FREEZE_END()","eb4c5ab9":"createShapeShiftConversionPost(string,string)","eb4c9ae7":"claimUpdateToken()","eb4d0e32":"redemptionFund()","eb4dd8f2":"confirm(address)","eb4defcb":"returnCoupon(address[2],uint256[7],uint8,bytes32[2])","eb4df824":"getOwnItemCount(address)","eb4e64d6":"amendAgreement(string)","eb4eecec":"altarFund()","eb4f16b5":"addStake(uint256)","eb4f17e7":"saleProceedsEtherAllowStale(uint256)","eb4f54b2":"TokenRUSD(uint256,string,uint8,string)","eb4fe500":"logoVote()","eb502d45":"transferProxy(address,address,uint256,uint256,uint8,bytes32,bytes32)","eb5068f2":"exitWallet()","eb50849e":"setCanAcceptTokens(address,address,bool)","eb508932":"lastPayouts(uint256)","eb51e2e4":"_popularitySetting(uint256,uint8)","eb51e575":"getNextPrizePool()","eb5230d7":"ETHERFUNDME_FEE()","eb52835b":"nextShareTime()","eb52e404":"adminTrade(uint256[8],address[4],uint8[2],bytes32[4])","eb531996":"getConversation(address,address,uint32)","eb53367a":"delABaddress(string)","eb533750":"extLockNinja(uint256,uint16)","eb5392ff":"Leonardo()","eb53a9a3":"getInitializeNumTicksValue()","eb53d273":"getServerNb()","eb55b2a3":"replaySweep(address[],address)","eb56105d":"marketSize()","eb5625d9":"safeApprove(address,address,uint256)","eb5653d7":"tokenIdToApproved(uint256)","eb570b05":"currentSalePriceInWei()","eb57d309":"TenantTerminateMisrep(string)","eb581c8f":"ScudoCoin()","eb58705b":"_performTransferFromToICAPWithReference(address,bytes32,uint256,string,address)","eb5904c0":"setProfitDistributionContract(address)","eb59ec82":"setLastMint(address,uint256)","eb5a458e":"unregisterByList(address[])","eb5a662e":"getAllowance(address)","eb5a7033":"getPrefixedHash(address)","eb5b135b":"tFinalized()","eb5b62b4":"BOPToken(address,uint256)","eb5ba3b4":"polyTokenAddress()","eb5ba56e":"creator_tablets_count(address)","eb5baebf":"MAX_SUPPLY_DECIMAL()","eb5bbef8":"withdrawInternal(uint256,bool)","eb5bdda0":"allocateAdvisorTokens(address,uint256,uint64,uint64)","eb5ce181":"Sample()","eb5dd1e3":"shouldPass()","eb5dd94f":"updateController(bytes32,address)","eb5ea1c0":"RemovePoolCoOwner(string,address)","eb5edde3":"bonusPreICO()","eb5f2cf8":"InsertCard(uint32,uint32,uint8,uint16,uint16,uint16,uint16,uint32[])","eb60082b":"profitsSendable()","eb601c70":"Vogeldubastardtoken()","eb605e9f":"hasPlayerWagered(address)","eb60764f":"getDayCount()","eb60c5d7":"DadsToken()","eb60e2c7":"setCountPlayersInPosition(uint256)","eb614fc7":"locked_allocation()","eb6157f7":"Abloxx()","eb6192a9":"getMTUBal(address)","eb62a013":"Offer(address,address,bytes32,uint256,uint256,uint128,uint256)","eb62df61":"acceptOffer()","eb639fd0":"luckyPot()","eb63e140":"getBuyPriceAfterTax()","eb63eadd":"setValue(uint256,uint256,uint256)","eb6443a3":"getIntelsByProvider(address)","eb64922b":"sendTeamTokens(address)","eb64d3e0":"TokenDrain(address,address,uint256)","eb64d5ce":"getUnitsStealingCapacity(address,uint256,uint256)","eb65a2c7":"crownDecimals()","eb663cf2":"LOOMIA_REMAINDER()","eb665994":"_0xBitcoinToken()","eb6779d4":"test_oneFalseAssert()","eb67cee8":"contractSize(address)","eb680744":"nextCheckpoint()","eb6855e3":"BossToken()","eb685867":"withdrawForFourYear()","eb685c47":"setTokenPrice(uint256,uint256)","eb68ce95":"processRegisterUser(address,address,address)","eb6a145b":"extractPartsFromGene(uint256)","eb6b192f":"ownerByAddress(address)","eb6bbd78":"getUserImages(address)","eb6c4bc8":"monsterIdToGeneration(uint256)","eb6d509e":"Test(uint8)","eb6d9fb5":"constructOwned()","eb6dc7c4":"processBurn(address,uint256)","eb6ecc03":"triggerTokenFallbackIfNeeded(address,address,uint256)","eb6ed29a":"setCanGetMoneyBack(bool)","eb6f80f1":"setPreferredSaleTLYperETH(uint256)","eb700331":"getLockTokenSupply()","eb70095d":"showVault()","eb7085cb":"teamReserveTokens()","eb70bc86":"BountyFulfilled(uint256,address,uint256)","eb70e13e":"_unpackStrengthValue(uint256)","eb70e498":"observer()","eb712a48":"etherTransfer(uint256,address[])","eb71b7e4":"prepayProposal(address)","eb727714":"trustNet()","eb73900b":"Whitelist(address)","eb7402f5":"multiAccessHasConfirmed(bytes32,address)","eb7492d1":"testTotalSupply()","eb74fa0b":"BCAClubCoin(uint256,string,string)","eb7550d8":"manualFinishGame(uint256)","eb75c410":"getOffer(address)","eb75dc03":"TOKEN_PRESALE_CAP()","eb76607d":"creationCap()","eb7698e2":"RaffleBitcoinBook(string,uint256)","eb770d0c":"setEntryFee(uint256)","eb780d3c":"SMILO_FOUNDATION_AMOUNT()","eb782d8c":"ContentSeries(address)","eb78a26d":"blackFundsWallet()","eb78a2af":"checkrespond(uint256,address)","eb794dd7":"addBlack(address)","eb795549":"safeTransfer(address,uint256,bytes)","eb799177":"gasOraclize()","eb79ec7c":"withdrawStocks()","eb7a10b1":"test_36_assertGasUsage2000Boards()","eb7a6471":"getPersonalAirdrop(address,address)","eb7a7241":"last_mint()","eb7b7006":"getRefundInfo(address)","eb7bb9fb":"CrowdsaleHardCapReached(uint256)","eb7bdc37":"withdrawSfowns(address)","eb7c244d":"amount5kUsdInCents()","eb7c6525":"ZbzStandardToken(uint256,string,uint8,string)","eb7c6f72":"step6()","eb7cdb56":"rankDown(uint256,uint256)","eb7db21b":"flip32(bytes32)","eb7ea41b":"showLastGlobalAuditTime()","eb7f3905":"tradeWithTips(uint256[10],address[4],uint256[10],bytes32[4])","eb7f4c0d":"CrowdsalePorto(address,address)","eb7fabd7":"getMax(uint64[])","eb800846":"setLLV_edit_18(string)","eb807339":"getRiskId(uint256)","eb80b3d1":"raceDistCon()","eb810864":"addTokensMulti(address[],address,uint256[])","eb8136f3":"stockTokens()","eb81e95a":"controllerBurn(address,bytes32,uint256)","eb8222eb":"spendMoney()","eb823572":"ProfitContainerAdapter(address,address,address)","eb8266b5":"addNumberToDynamicBytes(uint256)","eb829aef":"MPTToken(address,address,uint256,string,uint8,string)","eb83e2b5":"receiveApproval(address,uint32,address,bytes)","eb83f015":"castleContract()","eb845c17":"gen0AuctionDuration()","eb854131":"mbtcToUsd(uint256)","eb8571c8":"trans(address,address,uint256)","eb85c61e":"GUIDEToken()","eb85d999":"IVE()","eb869b8b":"Scheduled(uint256,uint256)","eb87073a":"verifyImages(bytes32,uint256,uint8,uint256,bool)","eb87ec01":"newStatus(address)","eb880380":"checkCooSeed(uint32)","eb886568":"signatureCheckerFreezed()","eb88d688":"createCommitment(uint256)","eb88e84d":"LatiumSeller()","eb89022e":"endDate1()","eb8ac921":"test(uint256,uint256)","eb8b12d4":"PLATFORM_WALLET()","eb8ba66c":"insertStage(uint8,uint256,uint256)","eb8bbd28":"getTotalFunds()","eb8cad45":"doMarriage()","eb8cb983":"LogPauseICO()","eb8d2444":"saleIsActive()","eb8d3321":"start_PRIVATESALE()","eb8e1660":"getPlayerOption()","eb8eea15":"totalMainSaleTokenIssued()","eb8fa486":"contributionInCauldron(uint8,address)","eb8fb32c":"setPercentageToKill(uint8)","eb8fb3ec":"getConstraint(bytes32,address,address)","eb90450f":"getFirstBuyerAddress(uint256)","eb907398":"changeSoftCap(uint256,uint256)","eb90fff8":"blockContract()","eb91385a":"UnauthorizedAccess(address,bytes4)","eb91b5ac":"ALUXToken(uint256,string,string)","eb91d37e":"getCurrentPrice()","eb9220ab":"updateRent(uint256)","eb9253c0":"seize(address,uint256)","eb931024":"passKYC(address)","eb935e70":"bigbrother()","eb93c515":"burnUpdateToken(uint256)","eb944e4c":"revokeTokenGrant(address,uint256)","eb947f19":"ExampleResourcePool()","eb94eecb":"isContributionAllowed()","eb95264c":"consolationRewardsPercent()","eb95b7d5":"Bounty(address,address)","eb95d4e6":"purchaseTokens(uint256,address,address)","eb95f0bf":"getCurRoundId()","eb965c5e":"Orientation(bytes32[])","eb967a2a":"refundsClaimed()","eb968ac7":"change(address,int256)","eb96ada7":"gameUnpause()","eb975390":"lockedTokenTransfer(address[],uint256[])","eb9763ed":"transferby(address,address,uint256)","eb981fea":"withdrawFromToken(uint256)","eb987ca7":"placeBet(address,uint256,string)","eb98c8d6":"getGoldsSinceLastCollect(address)","eb990c59":"initialize(address,address,uint256,uint256)","eb9969a8":"getAllBalance()","eb9a5211":"DonationMatched(address,address,uint256)","eb9aec0a":"oraclizeIds(uint32)","eb9af834":"removePolicy(uint8,uint256)","eb9bc6ff":"partyCount(address)","eb9c9708":"SisterToken(uint256,string,string)","eb9df7db":"updateContractOwner(address)","eb9e0398":"mint(int256,uint256,address)","eba0184f":"issuable()","eba052e7":"RefreshChipUnableList(uint8)","eba068ce":"addBountyForHunter(address,uint256)","eba2a91b":"superMintBulk(address[],uint256[])","eba36dbd":"setAddr(uint256,address)","eba37aff":"nrMeasurements()","eba37dbd":"getAllReportersDisputeBondToken()","eba38402":"finishEvent(address,uint256)","eba3cdfe":"bundle(address,uint256)","eba4ae3b":"NewDungeonFloor(uint256,uint256,uint32,uint128,uint256)","eba56302":"tier1Total()","eba60632":"drawNow()","eba66dc9":"JOTUNSupply()","eba6a307":"getQuotePrice()","eba74c0b":"updateCodeWeight(string,uint256)","eba898a0":"_authenticate(string,uint256)","eba9a4a8":"DiamondBond()","ebaa32f3":"submission_stage_block_size()","ebaa4470":"getOwnerAuctions(address)","ebaac771":"write(string)","ebab43e4":"isPreSaleTime()","ebabfb0b":"volumeType6()","ebad6612":"m_ETHPriceInCents()","ebaddea7":"unlockAccounts(address[])","ebadfd3d":"checkGivenAway()","ebae35a6":"DAOTokenCreationProxyTransferer(address,address)","ebae46be":"finishFunding()","ebae743b":"addCET6To(address,uint32,uint32)","ebae7bf1":"addHpbNode(address,bytes32,bytes32,bytes32)","ebaf0e74":"dInit(address,bool)","ebaf7f2f":"returnReward(uint256)","ebafefb1":"makeInitAccount()","ebb045fa":"PublicResolver(address)","ebb05f9c":"setItemApproveForAll(uint256,bool)","ebb0a856":"leastSwap()","ebb0e631":"dtGetCityData(address)","ebb11c93":"_build(address,uint256,bytes)","ebb1b7ed":"apiAuthorized()","ebb1dc21":"ERC20ByteCode()","ebb240ef":"ExampleUpgradeable23Token(address,uint256,bytes32,bytes32,uint256)","ebb31418":"disableTicker()","ebb32c65":"FooAbi(address)","ebb332be":"getFunStr()","ebb3fd8d":"kingdomName()","ebb44389":"bulkMintVested(uint256,address[],uint256[])","ebb4ac3c":"ForwarderFactory(address,bytes32,address)","ebb4f484":"ROLE_SUPERUSER()","ebb5a996":"setUsdLockAccountThreshold(uint256)","ebb5f11c":"explore(uint256,address,bool)","ebb689a1":"clearAll()","ebb6b338":"certifiedPartner()","ebb6c59f":"right72(uint256)","ebb6dc3a":"returnEther()","ebb71194":"withdrawFees(bytes32)","ebb741cb":"getChannelSize(uint256)","ebb75afc":"debugLog(string,uint256)","ebb85502":"GAME_START_TIME()","ebb88b97":"getABaddressByName(string)","ebb8c22c":"Win(address,uint256,uint256,uint256,uint256)","ebb940e6":"BuyBackContract()","ebb9ab25":"moveState(uint256,uint256)","ebb9b466":"phase_5_Time()","ebb9ba80":"calculateRewardForLevel(uint8,uint256)","ebba1400":"setIntegerValue(uint256)","ebba5184":"WuZeFoundation()","ebbaa1fc":"AdvancedToken()","ebbb76c8":"LongTermProjectTokens()","ebbbe00b":"testNopUnroll16(int256,int256,uint256)","ebbc4965":"acceptOwner()","ebbc9543":"_getPersonalAirdropUnlockTimestamp(address,address)","ebbe05d0":"setMinWeiAmount(uint256)","ebbf2f6a":"PixelColor(uint16,uint16,address,uint24)","ebbfb637":"Registered(bytes32,uint256,address)","ebbfb994":"startTokenSale(uint256,uint256)","ebbfcfef":"tomoDepositAddress()","ebc04649":"ChangeDatabase(address)","ebc16c5c":"getDrugsSinceLastCollect(address)","ebc1b4f1":"ForexCoin()","ebc20426":"minCapWei()","ebc26c95":"ToniToken()","ebc33c51":"minContrib()","ebc46fdb":"detachControllerForever()","ebc56c33":"_hardRequire(bool,bytes32)","ebc56eec":"set_allow_refunds(bool)","ebc58f62":"MSXAdvanced()","ebc59f32":"configPerShares()","ebc66bac":"Payreum()","ebc697d1":"testControlRestartNotOwner()","ebc6a661":"endICOStage2()","ebc6e332":"AuctionCreated(address,uint256,uint256,uint256,uint256,address)","ebc73e65":"setWaitingTime(uint256)","ebc824a2":"killItWithFire()","ebc8b934":"add_player(bytes32)","ebc97c36":"advisorsPeriodsNumber()","ebc98117":"getUserId(uint256)","ebcbee16":"totalRaisedInWei()","ebcc0de1":"closingPrices(address,address,uint256)","ebcc8eb6":"ETHCONEarlyBirdDonation(address)","ebcc9a31":"ICOweek2End()","ebccb566":"Halo3DPotPotato(address)","ebcd8d8a":"setStarInitialPrice(uint256)","ebce79ff":"enableBlacklist(address[])","ebcfd89e":"AGCoin()","ebcfd922":"playerEther()","ebd03c55":"changePlatPrice(uint32,uint256)","ebd057fa":"owner_withdrawal(uint256)","ebd062de":"removeOwnerAddress(address)","ebd0f599":"asktoken()","ebd3d58a":"InitPeculiumAdress(address)","ebd46d64":"encodeTokenId(uint256,uint256)","ebd4d009":"TotalFloatingInt()","ebd56581":"bitservice()","ebd58975":"sub2(uint256,uint256)","ebd66a9c":"MAX_ALLOWED_PRE_SALE()","ebd7cda4":"cTime()","ebd83378":"get_blocks_for(uint256)","ebd863ac":"DccbtcToken()","ebd8d7a0":"getRefReservedTokens()","ebd8fde3":"calculatePriceIncrease(uint256)","ebd9954c":"tgrStageBlockLeft()","ebda6686":"referrerLevel3Percent()","ebdac090":"depositFees(uint256)","ebdb6063":"lastIssuance()","ebdb730d":"weiPerFee()","ebdbc7d6":"CurrentTokenOwner()","ebdbd65e":"update_private_room(bytes32)","ebdcc8ac":"testrc(bytes32,uint8,bytes32,bytes32)","ebdd3f77":"triggerRecoveryAddressChange(uint256,address,bool)","ebde0bce":"MultiUser()","ebde609b":"LykkeTokenErc223Base(address,string,uint8,string,string,uint256)","ebdf0d5d":"endianConvert32bit(uint256)","ebdf86ca":"add(string,string)","ebdfa455":"joinedCrowdsalesLen()","ebdfd722":"whitelistEndTime()","ebdfe5ad":"picops_is_verified(bool)","ebe010b8":"_setStakeHolder(address)","ebe02377":"submissionPool()","ebe09a93":"getGoldTransaction(string,uint256)","ebe14170":"EdgelessToken()","ebe1df4f":"LLV_v31_4()","ebe22b12":"unsale()","ebe24dfd":"deployCtorContract()","ebe25056":"isWarlordChest(uint256)","ebe29383":"initializeSomeAddress(address,address,address)","ebe347d1":"lastTimeWithdrawal()","ebe36cb0":"read_price_floor()","ebe41b73":"deposit(uint8)","ebe4c0d1":"dividendsSumForUser(address)","ebe4c597":"VestingRevoked(address,uint256,uint256)","ebe599aa":"updateAppExec(bytes32,address)","ebe5a4b2":"toB32(bytes,address)","ebe64f97":"draw_random_card(uint8,uint8[])","ebe65f60":"withdrawOffer(uint256,uint256,bytes32)","ebe6ba07":"deprecateInterface()","ebe6f3cc":"setDappTokenContractAddr(address)","ebe749d3":"tokenLockTime()","ebe74b21":"PRE_SALE_30_ETH()","ebe771da":"setPercent5(address,uint256)","ebe7e852":"calculateResult(uint256,uint256,uint256)","ebe87ca4":"between(address)","ebe89597":"validate(uint256,bytes32,address,bytes32,bytes32)","ebe955fe":"simFrequency(bytes)","ebea3815":"setDays(uint256)","ebea3d30":"setFixedRate()","ebeac0c8":"marketCapBlue()","ebeac2b5":"reactivate(address)","ebead05f":"getOrderSharesEscrowed(bytes32)","ebeb0838":"delFromWhiteList(address)","ebeb0f48":"lockTotalSupply()","ebeb1b5e":"transferTokenToMultisig(address,address)","ebeb76bb":"assignMeta(string,uint256)","ebec7352":"numVideos()","ebed561b":"engineRunning()","ebed7a95":"mineral2Shares(uint256)","ebedef1a":"approvalFallback(address,uint256,bytes)","ebef28aa":"BID_DELAY_TIME()","ebf04917":"tranches()","ebf056e3":"revoke(bytes32,address,bool)","ebf06bcb":"spawnSite(uint256,uint256,address)","ebf0c717":"root()","ebf0da65":"erc223()","ebf0e5f1":"SimplePriceFeed(address,address,address)","ebf1356e":"minMineSize()","ebf1a495":"sendEthTweet(uint256,bool,string,bool,string,uint256)","ebf31253":"getMoneyness()","ebf469dc":"issue(address,uint256,string)","ebf5128c":"mintUnICOLeftToken(address,address,address)","ebf522b8":"_newJockey(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","ebf53e0e":"countAllCliDrm()","ebf5cdfd":"jackpotGuard(uint256)","ebf652cc":"lockInTime1()","ebf6e91d":"hit(uint256)","ebf70010":"ChangeWhiteList(address,bool)","ebf701e0":"getAccountBalance(bytes32)","ebf76522":"selfDestroy(address,address)","ebf81d30":"_Withdrawal(bytes32,uint256,uint256)","ebf88de4":"removeHeir()","ebf89fa9":"withdrawPonzi(uint256)","ebf95043":"balanceOfMorty(address)","ebfa3c1b":"maxRandomRound()","ebfaacce":"uncappedBuyerList(address)","ebfb3630":"vernamCrowdsaleToken()","ebfd288a":"getVerifiedReceipt(bytes,bytes,bytes)","ebfda085":"LOOT()","ebfdc657":"foundersAddress()","ebfe0f39":"makeCoin(uint256)","ebfed9f2":"motionVoting(uint256)","ebff2602":"Withdraw(address,address,uint256,uint256,uint256)","ebff410d":"bonusAccountBalances(address)","ebffd7e3":"getStage1Cap()","ec000bb5":"getPrizes()","ec003704":"getVestingStart(address,address)","ec005255":"boolToInt(bool,bool)","ec00d2a4":"frozenRecordsCount()","ec017820":"TransferToBTCoE(address,uint256)","ec01f75f":"initOperated(address)","ec0274ed":"CreateBatch(uint256,string)","ec0317ff":"AidCoin()","ec034bed":"donationAddress()","ec035393":"_getAllRevisionBlockNumbers(bytes20)","ec035aac":"bonusOver3ETH()","ec0373c6":"adminGetPlayerCount()","ec041a24":"getOrModifyBlocked(address)","ec0484ef":"roiEscrow(bytes32)","ec049219":"AtmanToken()","ec0493f7":"_populateTokenData(uint256,bytes16,uint256,uint32)","ec062ac0":"getMaxProfit()","ec066a4c":"ALLYToken()","ec0904f7":"releaseFor(address)","ec096f8d":"addTransaction(address,uint256,bytes)","ec0a0b50":"TOKENS_SUPPLY()","ec0a12d3":"JKToken()","ec0b3d21":"testThrowsIfPlaceholderIsBad()","ec0b3de4":"deletePetition(uint256)","ec0b4153":"getMoneyness(int256,uint256,uint256)","ec0b4207":"initCountTokens()","ec0b529f":"lockMinSiteTipPercentage()","ec0ba006":"countEgg(uint64)","ec0be13d":"Location()","ec0c6a72":"issue(bytes32,int256,string,bytes,uint256)","ec0cfd0b":"getProperties()","ec0d69e3":"train(uint256,bool,uint8)","ec0da0cd":"registerOptionPair(address,uint256,address,uint256,uint256)","ec0da330":"testSafeSub(uint256,uint256)","ec0de26e":"foundationTimelock()","ec0ea816":"breed(uint256,bool,uint256,bool,string,string)","ec0f1025":"testBitsOrSuccess()","ec0f60d9":"ICOcontributors()","ec1024d1":"censoredChatMessages(uint256)","ec10286d":"PointlessCoin(uint256,string,uint8,string,address)","ec109249":"RefundableAllocatedCappedCrowdsale(uint256,address,address,uint256,uint256,uint256,uint256,address,address,address,address,uint256)","ec112460":"_updateDistribution()","ec1182c2":"freezePrice()","ec11d0cf":"DeltaBalances()","ec12f1ef":"increaseMaxAvailableTokens(uint256,string,uint256)","ec132ce3":"unconfirm(uint256)","ec13cc7b":"freeze(bytes32)","ec13df6b":"setExecutiveOfficer(address)","ec140a1f":"BTSJToken()","ec149de9":"Ethereumwhocoin()","ec14f974":"MAX_CARS()","ec1553d1":"mintCoin(address,uint256)","ec15afe1":"filmpaid()","ec15c6ba":"substring(string,uint256,uint256,uint256,uint256)","ec164625":"_clearTotalBonusTokensByAddress(address)","ec176dee":"weiToTokenFactor()","ec17a7a3":"addressSCICO()","ec17b20e":"setStartingBlock(uint256)","ec1847b6":"getWorkerIndex(address)","ec1893b4":"getProps()","ec18ca9c":"lastPresser()","ec1938a8":"AddNewSegment(address,address,uint256,uint256,uint256,string)","ec1ad474":"removeFromWallet(address,uint256)","ec1b375a":"spardosenName()","ec1d9bf4":"isGoldRegistry(address)","ec1e4861":"assignWinnings(uint256)","ec1e6a4f":"tearDown()","ec1e74a7":"commitThreshold()","ec204f87":"_getTokenAmount(uint256,uint8)","ec20b457":"addInvestor(address,uint256)","ec20fc35":"populationIncrease()","ec216c34":"checkOwnerIndex(uint256)","ec21a913":"setUint256(int256,uint256)","ec22f94f":"getRedeemableReputationVoter(bytes32,address)","ec23ba66":"Kapitalexote()","ec24aa01":"startPrivateSaleStage()","ec25adf4":"addtokens()","ec271be2":"charityWalletAddress()","ec277ce7":"Resilience()","ec27bdd3":"challengingInput()","ec27f6d8":"LegacyRepContract()","ec280bf6":"moreMinFunds(uint256)","ec28118e":"nextDiscountTTMTokenId1()","ec2929fb":"divbonus()","ec29781e":"deliveryId()","ec29ff7c":"getMaxiumInputEther()","ec2a4062":"setOpenBlock(uint256)","ec2ac54e":"deposit(address,uint256,bytes32,uint256)","ec2af44d":"test_oneValidEqBool()","ec2b189c":"GetURL(address,uint256)","ec2b50bf":"setUserLibrary(address)","ec2bb963":"openPrize()","ec2bcd22":"addressCanContribute(address)","ec2c28b4":"checkBuy(uint256)","ec2c8fec":"getEggsOff(address)","ec2c9016":"getMarkets()","ec2cdb87":"initialSaleComplete()","ec2ec781":"testFailGetUnsetToken()","ec2efe40":"MinPayment()","ec2f39b4":"isICOStarted()","ec2f81ac":"createGroup(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","ec300fcc":"MediChainToken(uint256)","ec309038":"canStart()","ec30ad95":"EthsqrCore()","ec30c4e3":"getPointsToSpend()","ec3178f9":"getMemesByOwner(address)","ec322a88":"tokenlenth()","ec32d68f":"xrateProviders(uint256)","ec32e4e8":"admin_inactive_withdrawable()","ec332488":"openForPublicTrade()","ec342ad0":"BASE()","ec343a97":"Rate4()","ec35576e":"GetProfitFunds()","ec3575ec":"soccer()","ec357c64":"getIsCoinReg(string)","ec36196e":"toSpread()","ec3743f1":"setTeamFund()","ec38027e":"MadToken()","ec384a3e":"tokenToExchangeTransferInput(uint256,uint256,uint256,uint256,address,address)","ec38e855":"mintOperations(uint256)","ec3a0489":"PAYToken()","ec3a6d64":"getGoodDecision(bytes32)","ec3a6f73":"numRegistrants()","ec3adf65":"editUser(bytes32,bytes32,bytes32,bytes10,bytes32,bytes32,bytes32)","ec3af4a9":"getProjectKudos(address)","ec3bb11a":"maximumRaised()","ec3c155e":"ERC20TokenMock(uint256,string,uint8,string)","ec3d21e1":"kycPass(address)","ec3d45e8":"setMinParticipants(uint256)","ec3d5ffb":"stillAllowedReadable()","ec3f3636":"firstStage()","ec3f5d62":"withdrawRestOfBalance()","ec3fdf1d":"getExpiredAddressIndexes(address)","ec40c43d":"SmartPool(uint256,uint256,uint256)","ec40db16":"HedgeContract1(uint256,address,address)","ec412e00":"targetDiscountValue2()","ec42f82f":"finishIco()","ec439d67":"countAllUsers()","ec43eeb6":"getAddressOfId(uint256)","ec443813":"BytesToAddress(bytes)","ec449e67":"currentPriceInfoOf(uint256,uint256)","ec44acf2":"trading()","ec46009d":"EstateX()","ec4673d1":"approveWithdraw(uint256)","ec46bf8f":"emergency_withdraw(uint256)","ec47297e":"_CallCancelled(bytes32)","ec4754c6":"endetoken()","ec47a795":"getLockedStages(address)","ec47e7ed":"EtherWithdraw(uint256,address)","ec480557":"readTotalNumberOfPurchases()","ec486c23":"NewBToken()","ec4a79cf":"unlockaddress(address)","ec4aca2a":"bancorTradingContract()","ec4b48ad":"testCanDeposit(address)","ec4baa83":"StaticEthAvailable()","ec4bfdd4":"calculateOptionsComponents(uint256[9],uint32,uint32,bool)","ec4c76bb":"setInitialBuyoutPrice(uint256,uint256)","ec4cd0cf":"isSuccessful()","ec4d88d7":"usernames(bytes32)","ec4e530d":"_decodePriceData(bytes)","ec4eb442":"author(uint256)","ec4fb7a0":"totalTokensPresale()","ec4fd09d":"getEtherDog(uint256)","ec503611":"profitsSent()","ec505f58":"INDOCASH()","ec5134ca":"processStep()","ec51431f":"Unvault(uint256,uint256)","ec530de6":"countAddresses()","ec5325c1":"getDarknodes(address,uint256)","ec53589d":"FhnwCoin()","ec54a36a":"updateTimer(uint256)","ec54fa5e":"listCOFI()","ec556889":"proxy()","ec559176":"setEthBalance(address,uint256)","ec560828":"monarchyEndReward()","ec56a373":"contracts(bytes32)","ec56c6b0":"contracteventcount()","ec56eb93":"getComponentCount(uint256)","ec57e25b":"Magzia()","ec582a00":"IkuraStorage()","ec58b996":"encodeMessage(uint256,uint256,uint16[])","ec58f4b8":"addSolver(address)","ec591b20":"cancelSellCard(uint8)","ec59565f":"BinaryOptionV2(address,address,address)","ec597128":"addition()","ec5975c6":"getTokensReserve()","ec5a25e0":"WalletLibrary()","ec5aceab":"createOrder(address,address[3],uint256[5],int256)","ec5c71b3":"getChildIds(address,uint256,uint256)","ec5c9036":"Crowdsale(address,uint256,uint256)","ec5d9cc8":"balanceAvailableTokens(address)","ec5d9e58":"organisationName()","ec5dfaa2":"initHolders(address[],uint96[])","ec5dfb84":"bbBalance()","ec5ffac2":"minimumStake()","ec607f7d":"nextPeriod()","ec60bcf3":"burnFrom(address,address,uint256)","ec61c430":"YudiToken(uint256,string,string)","ec620eb3":"setClaimBlocks(uint256,uint256)","ec622892":"disableInvestment(address[])","ec62558d":"adminBurnToken(uint256)","ec62b216":"PRE_ICO_BONUS_PERCENTAGE()","ec647d42":"JESToken()","ec64f52f":"brag()","ec6507d7":"debug_transfer(address,address,uint256)","ec651551":"PVP(uint256,uint256,uint256)","ec653833":"totalAuctionItems()","ec654389":"tokenBountyAllocated()","ec654e38":"accident()","ec65b7a0":"FINALIZE(bytes32)","ec664694":"GooToken(uint256)","ec672cf6":"setAddressArray(bytes32,address[])","ec67abe4":"MOMCoin()","ec67e37a":"assignRevenueContract()","ec68197b":"setGameAddrt(address,bool)","ec688e8f":"walletNotLocked(address)","ec68a73d":"totalSpecies()","ec698a28":"__transferFromWithReference(address,address,uint256,string,address)","ec6a4487":"setMoneyWallet(address,address)","ec6acb33":"reputationClear(address,string)","ec6afc22":"oraclize_query(uint256,string,string[3])","ec6b16ca":"pMinInFp()","ec6b1d1e":"findAddress(bytes32)","ec6b393d":"subWeiRaised(uint256)","ec6be06e":"setBeneficiaryAddress(address)","ec6c18fc":"TOKEN_DECIMALS_MULTIPLIER()","ec6c32cd":"amendArticleItem(uint256,uint256,bytes)","ec6e43ae":"PRICE_CHANGE_ENDING_TIME()","ec6e5d09":"SellerHistory(address,address,uint256,uint256)","ec6e7bbf":"getTargetSite(address,uint256,uint256,uint256)","ec6eb411":"adjustBalance(address)","ec6f3a8c":"originalTokenHolder()","ec6f509e":"IcoStartTime()","ec6f772d":"addVirus(address,uint256)","ec704095":"getMyCrocs()","ec714926":"setTargetDiscountValue8(uint256)","ec715a31":"releaseToken()","ec7219a1":"growthReserveTokenSend(address,uint256)","ec727000":"getApprovalDB()","ec736b67":"validPerc(uint256)","ec737576":"finalizeMintUtility(address,uint256)","ec7380d9":"transferManually(uint256,address,address)","ec747b09":"getPaymentById(uint256,uint256)","ec74b818":"rbInformationStore()","ec756ee5":"getOrCacheValidityBondWallCalled()","ec759b80":"getOwners(uint8)","ec76312a":"sendInvestorIndex()","ec76bd65":"volumeType5()","ec77537b":"finalizeDispute()","ec77809f":"removeAssetPartOwner(bytes32,address)","ec77a89f":"GoldTokenLedger()","ec78626f":"setPOOL_edit_11(string)","ec788712":"toAddress(bytes,uint8)","ec789ef3":"sellpr0coinsAgainstEther(uint256)","ec796908":"tokensArray(uint256)","ec79efa8":"candidateETHAssets()","ec79f9bd":"setDisputeThresholdForFork(uint256)","ec7a3ab6":"calcBurnFee(uint256)","ec7b2843":"kvcMul(uint256,uint256)","ec7b8c40":"deleteFrozenAddresses(address)","ec7b9655":"spiritual_guidance()","ec7bb2ac":"setGen0Limit()","ec7bbcd2":"TradeAdsCoin()","ec7bf78d":"SetWorldSnapshot(uint256,bool,uint256,uint256,uint256)","ec7c06be":"doMigrate()","ec7c2ef7":"withdraw_excess_tokens()","ec7c637d":"getBalanceLimit(address)","ec7dd7bb":"getOrderDetails(uint256)","ec7de1e9":"masterOfCeremonyPending()","ec7df86e":"hasSDCC(address,address,uint256)","ec7dfb4d":"weiGoal()","ec7ecec5":"getPlayerState(uint256)","ec7f2ae7":"LogTransactionComplete(bytes32,address,uint256,bytes)","ec7f9906":"changeFreeAnimalsLimit(uint256)","ec7fea7b":"BiXuTo()","ec7fec8b":"defineWinner()","ec7ff617":"getMatchIdx()","ec801286":"BITHELPTOKEN()","ec810684":"registrationVote(address,uint256)","ec8120c9":"totalItemsForSale()","ec814f4e":"doDevelopFunds(uint256)","ec81aadb":"deployedTokens(uint256)","ec81b483":"CAP()","ec81e22e":"returnmoneycreator(uint8,uint256)","ec824ca9":"hashNumber(uint8)","ec82bf91":"_pay_token_commission(uint256)","ec82cf4e":"setDepositPpm(uint32)","ec841fe0":"LogTokensPerEthUpdated(uint256)","ec845dd8":"totalSubscription()","ec847fe8":"divholder()","ec854a04":"DogToken()","ec85d2f2":"regulatorStatus()","ec85d464":"returnAmountRaisedSoFar(uint256)","ec866d28":"isApproveOnly()","ec867b27":"isTokenVerified(address)","ec86e1d7":"getReleaseType(address)","ec86fdbd":"getOrCacheMarketCreationCost()","ec87543b":"lockedCZRMap(address,uint256)","ec875f98":"addCourses(string,address[])","ec881472":"Validator(string)","ec8861e7":"switchDelegate(bool)","ec88abc8":"SOVv11Token()","ec8909c0":"setShort(address)","ec89c8f0":"MicheleToken(uint256,string,string)","ec8a2c88":"investments()","ec8ac4d8":"buyTokens(address)","ec8b283c":"give(address,address,uint256)","ec8b8f4e":"addMinerTokens(uint64,address[],uint64[])","ec8be5b9":"canClaim(bytes32,uint256,address,bytes)","ec8cae23":"changeHolderCount(uint256)","ec8cb281":"openDate()","ec8d82f8":"oraclize_query(string,bytes[],uint256)","ec8e1afa":"interfaceInstanceCount()","ec8edf7a":"changeWalletAddress(address)","ec8f3fa5":"getWithdrawalAddress()","ec8f4d04":"onApprove(address,address,uint256,uint256)","ec8f850b":"withdrew()","ec8fb8ef":"withdrawOldTokens(address,uint256)","ec8fe065":"buyItem(address,uint8,uint256)","ec901017":"mintTokensWithTimeBasedVesting(address,uint256,uint256,uint256,uint256)","ec902779":"scribes(address)","ec9029a3":"minerToken(address,uint256)","ec90a79a":"recv_from_side_chain(uint256,bytes)","ec912d61":"markCredit(address,uint256)","ec91b550":"miningThree()","ec92b98d":"bancorErc20Eth()","ec933789":"ParticipantAgent(string,address)","ec93a081":"HelperSearchToken()","ec93b3f8":"GetCardType(uint8,uint8,uint8)","ec93cfae":"FountainOfWealth()","ec941ef8":"BXZToken()","ec94ce4b":"enabledMintTokens(bool)","ec9723ad":"setSalePeriod(uint256,uint256,uint256)","ec972a07":"lastBlock_f15()","ec972fb0":"timeOfLastDistribution()","ec973642":"enable(address,bool)","ec979082":"marketCount()","ec97cff7":"addCertificationDocument(address,bytes32)","ec985c99":"minfinney()","ec98618e":"getDial1Type(uint8)","ec98eefc":"createTokenContract(address,uint256)","ec993f3d":"changeDiscount(uint8)","ec9974eb":"getTotalWEIEther()","ec99bfe9":"setPreSaleParams(uint256,uint256,uint256,uint256)","ec99c60c":"getMatchFromList(uint256)","ec9a6e87":"setDefaultPartitions(bytes32[])","ec9b5cb2":"publicSaleEnd()","ec9be5fe":"setPotatoOwner(address)","ec9c677d":"checkDeck(uint256,uint8[],bytes32)","ec9d35aa":"transferWithCommission(address,uint256)","ec9d7fd2":"getAccumulatedServiceFee()","ec9da59e":"setMainContractAddress(address)","ec9e7971":"kycAdmin()","ec9edfc2":"addSmallInvestor(address,uint256,uint256)","eca001dd":"checkWhitelisted(address,uint256,uint256,uint8,bytes32,bytes32)","eca0290b":"rawSetAttribute(bytes32,bytes32,bytes)","eca058cc":"tokensForWei(uint256)","eca0be47":"TEAM_GROUP_WALLET()","eca10286":"loseNum()","eca1ada7":"getPlayersCount(uint256)","eca25f42":"TARGET_ADDRESS()","eca28cb7":"AleaPrivateSale(uint256,uint256,uint256,address,uint256,address)","eca2e604":"makeWorkStage(uint256,uint256)","eca38e0c":"ethSent()","eca3ee2c":"currentFundingAmount()","eca4742a":"getApprovedAddress(uint256)","eca49641":"TurnBasedGame(bool)","eca5339d":"mintExtraTokens(uint256)","eca5c793":"testErrorUnauthorizedNameRegister()","eca6e42d":"set_minimum_trade(uint256)","eca73f64":"currentBonus()","eca85419":"_getAllChildIds(bytes32)","eca90ffc":"LogGetEther(address,uint256,string)","eca95377":"generateRandom(string,uint256,uint256)","ecaa0e45":"OXGOLDSupply()","ecaaf6c8":"newIdTankHull()","ecab1a06":"_getExpProportion(int256)","ecabaf24":"NewHighestBid(uint256,address)","ecac7f4b":"symbolsCount()","ecacb3e0":"BitcoinSinhalaToken()","ecad17c1":"HurtleCoin()","ecad78a2":"paydCouponsETH(address)","ecaeacf6":"RESERVED_TOKENS_FOR_CYNOTRUST()","ecaeb904":"getDeltaMonth(uint256,uint256)","ecaf76b8":"minReferAmount()","ecb0116a":"getExitFee()","ecb0256b":"relayTx(bytes,int256,int256[],int256,int256,bytes,int256,int256[],int256,int256)","ecb071cf":"mainSaleStartdate()","ecb0b862":"payContract()","ecb14519":"payToken(address,address)","ecb15644":"GasFiles()","ecb1b31c":"TRONIC1()","ecb20de7":"takeBuyTokenOrder(address[3],uint256[3],uint256,uint8,bytes32,bytes32)","ecb389e0":"mmVaultAddr()","ecb39cba":"developer_edit_stake_reward_rate(string)","ecb3dc88":"depositCounter()","ecb4136e":"NotAnotherPonzi()","ecb42795":"MANA()","ecb42914":"STAGE_1_MAXCAP()","ecb46858":"buyGolds()","ecb58c74":"ownerAllocate(address,uint256)","ecb5fff6":"DELTA()","ecb62e49":"defaultParameters(uint256)","ecb63011":"receiveApproval(address,uint256,address,uint8)","ecb6af21":"accountB()","ecb6b50c":"RAVI_ADDRESS()","ecb6c47a":"allStop()","ecb70a98":"tokensByDashTx(string)","ecb70fb7":"hasEnded()","ecb75089":"jackpotRoundNumber(uint256)","ecb828ea":"lastTokensIssued()","ecb87dc4":"cjTeamWallet()","ecb98714":"random_damage(uint256)","ecb9d6a3":"_cancelTknOffer(address)","ecba18c0":"closeCrowdsale(bool)","ecbb06c9":"setPlayerGeneralAttr(uint64,uint32,uint32,uint32,uint32)","ecbb596a":"DecentralizedCrowdFunding(address,uint256,string,uint256,uint256)","ecbbcdda":"processFundsIfAny()","ecbbd1ca":"calculateMaximumBurnAmount(address)","ecbc1481":"calcVIPBenefit(uint256,uint256)","ecbc3177":"shitFundAddress()","ecbc328d":"totalCardValue(uint256)","ecbc8fa7":"adjustBalance(address,int256)","ecbca55d":"setConversionFee(uint32)","ecbd15fd":"alterTokenGrant(address,uint256)","ecbdb633":"getDataHolders(address)","ecbdbb32":"balanceETH()","ecbdee9b":"setWeiPerSatoshi(uint256)","ecbee997":"getPlayerBetInfo(address)","ecbf171c":"setSiteRewards(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","ecbfc077":"startClaim()","ecc06c76":"setFormula(address)","ecc0ee18":"fortune_setimgnme(uint256,bytes32[144],bytes32)","ecc137db":"getRandomAdversary(uint256,uint8)","ecc18582":"exitContest(uint32)","ecc1caef":"founderReward()","ecc1cfaf":"withdrawALC(uint256)","ecc21830":"setBuyoutFeePercentage(uint256)","ecc258dd":"removeSecondAdvisorLock(address)","ecc2c47c":"outSdcForUser(uint256)","ecc2e57d":"classVariants(uint256)","ecc310ae":"kittyActions(uint256,uint256)","ecc38a1f":"REFERER_PERCENT()","ecc4029b":"getSpentAmount(address,address)","ecc46d1b":"DEBATE_PERIOD_MINUTES()","ecc4a6c2":"getSelled(uint256)","ecc54067":"TopTokenBase()","ecc55e4b":"setBool2(bool)","ecc57df4":"_fetchOrderByIdWithPayer(string,address)","ecc5aaaa":"startMint(uint256,bool,int256,uint256)","ecc7296b":"rebalanceMargin()","ecc72b0f":"getSentTrade(address,uint256)","ecc73f48":"collectedSum()","ecc7e7bc":"TestTokenToken()","ecc91c28":"addEtherBroAuction(uint256,uint128)","ecc9665b":"maxWithoutWhitelist()","ecc98ce4":"ERC721_RECEIVED()","ecc99af0":"getNegID()","ecca031f":"hasVoted(uint256)","ecca9c2e":"getPrizeAmount()","eccaa8b5":"getSpellAbility(uint32)","eccb15bc":"SatPosition(int256,int256)","eccb6bd0":"addTicket(uint256,address)","eccbc596":"maxAttackPrizePercent()","eccbf4cc":"getTokenCountFor(address)","eccc32f2":"DD()","eccd162e":"Fortune(string)","eccd1a8d":"NEWT()","eccd8e0d":"getExchangeRate(uint256,uint256,uint256)","ecce7e63":"setWinningTeam(uint256)","eccf1b29":"CrystalDoubler()","eccf93c0":"updateCrowdsale(uint256,uint256,uint256,uint256)","ecd08bc3":"rap()","ecd0c0c3":"_token()","ecd13b89":"discountDivisor()","ecd1a83a":"getUserCoolDown(address)","ecd1c4a5":"availableZLT()","ecd22328":"weiCrowded()","ecd27189":"freeToUseTokens()","ecd370bd":"withdrawCoinToOwner(address,uint256)","ecd4eb74":"sendFees(uint256)","ecd57ec1":"setMinMaxDays(uint8,uint8)","ecd59d9b":"OTHERCRUISER()","ecd63757":"makePresale(string,address,uint256,uint256,string,string)","ecd747de":"getFishByPos(uint256)","ecd75c59":"FourWaySplit(address,address,address,address,address,address,address,address)","ecd79066":"getRedeemableReputationProposer(bytes32)","ecd7df06":"ICOweek4End()","ecd9297d":"withdrawAffBonus()","ecd9442e":"setMaxWeiAllowed(uint256)","ecd9c155":"transferDistributorship(address)","ecda10f5":"deploymentTime()","ecda249b":"UIWishSale(address,uint256,uint256,uint256,uint256,uint256,uint256,address,address)","ecda3055":"start_ICO1(uint256)","ecda58c2":"withdraw_3Completed()","ecda5fb6":"prizeFundFactor()","ecda6635":"owner_MIN_LIMIT()","ecdb065b":"bitNot(bytes32)","ecdb620d":"offlineRealmSold(uint256,address,uint256)","ecdc7135":"GoldeaBonusCalculator(uint256,uint256)","ecdd9549":"bonusOver10ETH()","ecdd9632":"generateOrder(address,address,address,uint256,string,string,string)","ecdf419a":"doCoinage()","ecdf5459":"awardReferralBonus(address,address,uint256)","ecdf6fed":"shareDividends()","ecdfca06":"tokensPreSale()","ecdfdc27":"ROLE_ADMINISTRATOR()","ece02921":"queryGameHistory(uint256)","ece0d561":"CashSaved(uint256)","ece11912":"getBetValue(uint256,uint256,uint256)","ece1d6e5":"maxRate()","ece1de44":"appeal(bytes32)","ece2064c":"setCurrentRewardTokens()","ece20f36":"nullify()","ece2ea40":"nextCapTime()","ece35d01":"sessionDuration()","ece44b81":"numCollected()","ece4f10d":"LULUCOIN()","ece5ca56":"getData_33()","ece62017":"sTCBonus(uint256,uint256)","ece66346":"CryptoSagaHero(address)","ece67270":"countdownIsUp()","ece7c397":"SurveyTokenSale()","ece7fa5d":"registerToken(address,string,string,uint256,uint256)","ece84fd5":"crowdsaleFinished()","ece866b9":"l()","ece8a1d9":"baby()","ece8a29d":"addCourse(string,string,string,string,string,string)","ece9aed4":"crearJuegosPublico()","eceadfd1":"ONEX()","eceae9bf":"setRequiredGoldIncreaseFactor(uint256)","eceb2945":"checkProposalCode(uint256,address,uint256,bytes)","eceb9eef":"SweetTokenLogic(address,address,address,address[],uint256[])","eceba876":"getChildUniverse(bytes32)","ececa529":"mainFundPrecent()","eced0280":"getPhase()","eced2967":"calculateAndRegisterEarlyBonuses(uint256)","eced5526":"SCALE()","eced6c57":"extraTokensPerUnit()","ecedafcb":"SampleCrowdsale(uint256,uint256,uint256,uint256,uint256,address)","ecedf7b2":"initialisation(address,address)","ecee4eb1":"calculateNoOfTokensToSend(uint256)","eceebc3f":"setAllowTrading(bool)","ecef0e54":"DigixbotUsers(address)","ecef615b":"sellTransferFee()","ecf0848f":"MIN_PRESALE()","ecf12669":"FinToken()","ecf1e0fd":"addManyUsers(address[],uint256[])","ecf1fca0":"tradeProfileImplementation()","ecf1fdea":"setper(uint256,uint8,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","ecf24ec0":"Contribution(address,address,address,uint256)","ecf41c8c":"createOption(uint256,bytes32)","ecf42e5a":"ETHRLINK(address,address)","ecf477d5":"CrowdsaleStarted(address)","ecf56d82":"etherToTokens_(uint256)","ecf59b83":"ico3Min()","ecf6512f":"modify_Presale2StartDate(uint256)","ecf68eb8":"TokenTransferAllowed(uint256,address)","ecf6eb22":"setConfigAddress(bytes,address)","ecf6f108":"bigToken()","ecf6f2f8":"Bitgram()","ecf7105e":"etherBounty(address,uint256)","ecf7b873":"_airdropUnlocked(address)","ecf82c91":"setPixelDistributor(address)","ecf836ba":"updateInstance(bytes32,bytes32,bytes32)","ecf862cc":"stopSweepStake()","ecf88111":"setConfig(address,uint256,uint256,uint256)","ecf90824":"testegy(uint256,string,string)","ecf9d3e9":"getDesignatedReportPayoutHash()","ecf9ea1d":"expanded()","ecfa3292":"Forwarder(address,bytes32,address)","ecfb49a3":"totalPool()","ecfb5d17":"deleteFromWhitelist(address)","ecfbe70c":"withdrawERC20Token(address,address)","ecfc5964":"incTotalSupply(uint256)","ecfc7ecc":"placeBid()","ecfce7b4":"addProductEndorsement(string,uint256,int256,bool,string,string)","ecfd0a56":"account1()","ecfd8928":"contributorCount()","ecfef21a":"Mojito()","ecff39af":"START_WEEK_1()","ecff537f":"getGen0COnfig(uint32)","ecff58df":"countProjects()","ecff7531":"BankerFarmer()","ecffc18a":"RussianCash()","ed007cb6":"AggiungiMiner(address)","ed00b73f":"EbolaToken()","ed016620":"EtherToken1()","ed01bf29":"budget()","ed02a732":"doBountyairdrop(address,uint256)","ed02ad37":"numberOfGuesses()","ed02ada4":"TransferCoinsFrom(address,address,uint8)","ed02dded":"lossToCharity(uint256,address)","ed032ad2":"lastCharNoZero(string)","ed03a5b3":"cloneArray(uint256[],uint256)","ed03d0da":"withdrawShares(address)","ed045a3c":"doRefund(uint256,uint256,uint256)","ed047efd":"assignAnotherOwner1(address)","ed04d9f2":"getBuyingAmountRanges()","ed05084e":"setWinner()","ed05582b":"getHash(address,uint256)","ed05ae78":"getDepositBalance(address)","ed060ac1":"batchMount(address,uint256[],uint256)","ed0668fb":"getMyTurtles()","ed06a62c":"confirmBobDirectPay(uint256)","ed06d4dc":"KiwiTestToken()","ed06fb91":"PART_REWARD_CHANCE()","ed07e7b6":"arbifi(uint256,bool)","ed081329":"vote(address[])","ed09d19a":"get3(uint256)","ed0ad321":"releasedOf(address)","ed0b01cf":"MINERS_STAKE()","ed0b1cb3":"LLV_311_EDIT_1()","ed0bce14":"Cryptolotto1Day(address,address,address,address)","ed0c4123":"tokensPaid(address)","ed0c7091":"resignOwnership()","ed0cc2e1":"balancesUploaded()","ed0cdfdb":"MonsterAuction(address,uint256)","ed0e4665":"AVAILABLE_ADVISOR_SUPPLY()","ed0e92e5":"removeControllerContract(address)","ed0f22d5":"Start6()","ed1062ba":"CallExecuted(address,bytes32)","ed10e33c":"unLock()","ed11a690":"STARTING_TURTLE()","ed11d089":"Fortecoin()","ed129c2d":"printMarket()","ed12e8ef":"getVaultBalance()","ed1426e6":"purchasePixel(uint256,uint256,uint256)","ed148ea7":"testEnsFail()","ed149514":"setPartners(address,address)","ed14b6a5":"takeOver()","ed14d17e":"collectRevenue()","ed156449":"HeroCoin(address,address,address,address)","ed15863a":"bookWeekVisit(uint256)","ed15c31d":"Token10xAmin()","ed15c5e6":"targetDiscountValue6()","ed15dafd":"LBToken()","ed1627e9":"closeThisTurn()","ed17dab7":"tokensDistributedPresale()","ed17faa8":"setPlayerDayEthInLimit(uint256)","ed180443":"getUint256(int256)","ed185562":"presaleDeadline()","ed18838c":"setAutoBuy()","ed188f33":"cSale()","ed18bc3f":"Slot(address)","ed18ecae":"scan(address,bytes1)","ed18f0a7":"blue()","ed190746":"testSplit()","ed1923ee":"mediumRate()","ed1a9ca1":"returnsOneUnnamed(uint256,uint256)","ed1b71ea":"registerUser(address,address,address)","ed1ba837":"PensionFundRelease(address[],address,address,uint8,uint256,uint256,uint8,address)","ed1d4870":"changeReceiver(uint256,address)","ed1d840d":"getPriceForAssetAmount(address,uint256)","ed1ece04":"mineCard()","ed1eee68":"getFee(string)","ed1f1656":"totalaccumulated()","ed1f2229":"distributeForBountiesAndAdvisors()","ed1f9991":"getParticipantIndexAddress(uint256)","ed20f370":"debundleAndWithdraw(uint256)","ed21187a":"getInvestorsCount()","ed21248c":"Deposit()","ed214fff":"getParticipantList()","ed21a7e7":"Airsavecoin()","ed225a8a":"equipmentTrainingFeeMultiplier()","ed22671d":"set(bytes32,bytes32,bytes32,bytes)","ed22c02f":"SGEPreICO()","ed23378b":"getMarketCreatorMailbox()","ed234e20":"addCompany(address,string)","ed23e5b7":"requestObjectRoot(bytes32,uint256,uint8,bytes32,bytes32)","ed244fcd":"getAccountValues(uint16,uint8)","ed24e3e0":"CryptoABS()","ed25ba8c":"blinc_block()","ed25e6c2":"expand(uint32[4],uint32[26])","ed2648d3":"setCCH_edit_14(string)","ed26cae8":"contains(address,address)","ed26e60d":"GetReserveAmount(address)","ed26fc86":"SnowBall()","ed287795":"transferFromAndLock(address,address,uint256,uint256,uint256)","ed28d37f":"TokenOne()","ed28ef51":"addManyUsers(address[])","ed29c12b":"MFI()","ed2a2d64":"nonceOf(address)","ed2b5a3c":"getBorrowRate(address,uint256,uint256)","ed2b8e0b":"getPoolRotationDelay()","ed2c92b1":"finalizeLastCampaign()","ed2cbf06":"_deliverTokens(address,uint256)","ed2d1d9e":"goodNightSweetPrince()","ed2d4a1b":"process_game()","ed2ddeae":"claimAllSupporterTokensByOwner(address)","ed2de952":"setInvestorsStorage(address)","ed2df26d":"getGameResult(uint256)","ed2e3f7e":"ChainBankToken(uint256)","ed2e5a97":"read(uint256)","ed2eb843":"withdrawEther(address,address,uint256)","ed2f2369":"activeStakes()","ed2f5b1a":"getRestoredTransactionStatus(uint256)","ed2fbf96":"timesno()","ed3058e0":"transferRight(address,bytes)","ed30ec8f":"_validFee(uint256,uint256)","ed319520":"_validateTokensLimits(uint256)","ed3375f5":"RSPLT_I()","ed338ff1":"saleEndTime()","ed3390ea":"findBest(uint256,uint256)","ed33e00c":"participantClaimCredits()","ed33fba7":"PitisCoin()","ed3411dc":"register(bytes20,uint24,uint32,bytes32[],uint16)","ed3437f8":"scalingFactor()","ed343f65":"totalDropPerUnlockedToken()","ed34ca2e":"ThePlat()","ed355b0b":"getBestInvestor()","ed361694":"failSafeMode()","ed361c17":"burningCapableAccount(address[])","ed3643d6":"checkSignersByName(bytes32,uint256,uint256,uint256)","ed36a874":"getOracleAddressByName(string)","ed3788c9":"futureDevelopmentPoolAddress()","ed39eab3":"HGT()","ed3a2164":"PrincelyGoldenDollar()","ed3a865e":"raceId()","ed3ad43e":"finalizeDeprecation(uint256,address)","ed3b4eca":"setMinAmount1Round(uint256)","ed3d4dc1":"POWM()","ed3e3e0b":"update_counts(uint256)","ed3e46ae":"tipHash()","ed3f1c87":"allowAccess(address,address)","ed3f443f":"getMyBetRecordCount()","ed3fd0d7":"EVMScriptRegistryFactory()","ed40175d":"testFailOnFailedCall()","ed4080b1":"getPreminerAllocation(address,uint256)","ed40a8c8":"getWord()","ed4127df":"CANVAS_HEIGHT()","ed429d1b":"_amountCourse()","ed43191d":"DataRecordStructs(bytes32)","ed442e14":"getDividends()","ed45747f":"editCell(address,uint256)","ed45c9be":"getAllTheThings()","ed45e578":"getAttoTokensLeftForICO()","ed46eb52":"deleteCaller(uint256)","ed47ca94":"debug_verifySharesTreeSubmission(uint256[],uint256[],uint256,uint256,uint256,uint256)","ed49196b":"auctionleader()","ed498fa8":"userTokens(address)","ed49d2f8":"maxDelay()","ed4ae6b5":"isValidVoting(address)","ed4b1d0d":"scheduleTransaction(uint256)","ed4c1cdd":"xauToEur()","ed4c1d97":"syncToken()","ed4c87ac":"startProject(string,address,address,address,bytes,uint8,uint8,uint8,bool)","ed4dd2ab":"SECOND_TIER_DISCOUNT()","ed4e65fb":"noStoreIsActive()","ed4e73da":"signedTransferFrom(address,address,address,address,uint256,uint256,uint256,bytes,address)","ed4f114d":"ConversionRateChange(uint256)","ed4f2b33":"setup(uint8,bytes32[])","ed4f415e":"Holahop()","ed505d3e":"totalAmountOfPresalePurchasesWithoutBonus()","ed50dd4e":"ChiSale(address,uint256[],uint256[])","ed52068c":"revokeBurnDelegate(address)","ed526601":"greenOnFanChun()","ed54746e":"lastAuction()","ed550443":"proxyContract()","ed561fe5":"receiveSecurityDeposit(address)","ed56531a":"pause(bytes32)","ed5667b4":"transferOfPower(address)","ed5677f6":"tierThreeMin()","ed56de8c":"withdrawZRX(uint256)","ed5850b9":"register(address,uint8,bytes32[5],address)","ed5863f6":"agaisnt_votes()","ed58bad8":"setAuthorizedMinter(address,bool)","ed58c840":"transferGu(address,uint256)","ed58d5ec":"setLendingContract(address)","ed59313a":"setUsername(string)","ed598be7":"TenantMoveIn(string)","ed59eda1":"_addSuperInvestor(address)","ed5bc87b":"fundedProxy()","ed5c58f3":"set0xTokenProxy(address)","ed5d2289":"latchFciUser(uint256)","ed5d3f1a":"pow_10(uint256)","ed5d6fbc":"completion()","ed5da4f9":"computeReturnBonus(uint256)","ed5dc952":"getIsRoundOver(uint256)","ed5e68f9":"closeAnnualInvest()","ed5e7691":"CrowdCoinPreICO(address,address,address)","ed5e8437":"locks(bytes32)","ed5eafa2":"ClinicalTrial(address,address,uint256,uint256,uint256,bytes32,bytes)","ed5ec919":"voidTransaction(uint256)","ed60ade6":"bidOnSiringAuction(uint256,uint256)","ed611895":"ManualChangeUnholdDate(uint256,uint256)","ed6183bf":"isWinner(uint8,uint8[5],uint8[5])","ed621591":"KaratBankCoin()","ed621ae1":"PriceWeekFour()","ed621df6":"GuessNumber()","ed621e9a":"addWhitelistUsers(address[],uint256[])","ed621f0f":"YUN(uint256,string,uint8,string)","ed62543d":"bttsToken()","ed62986b":"_getBattleResult(int256,int256,int256,int256,uint256)","ed62cf1f":"setCanCall(address,address,bytes,bool)","ed62f501":"maxPendingPayouts()","ed6302be":"left98(uint256)","ed63455c":"stringContains(string,string)","ed644025":"X5Coins(uint256,string,string)","ed64b36b":"left15(uint256)","ed64bea4":"JamCoin()","ed64c08c":"clearBudget(address)","ed653164":"releaseEscrow(uint256)","ed666e96":"artsCreatedCount()","ed67bca3":"_finalize()","ed684cc6":"trigger(uint256)","ed68ece1":"newFeed(string)","ed68ff2c":"setRequireSignedAddress(bool,address)","ed6a2bc9":"LLToken(uint256,uint256,address)","ed6a2d35":"Blincoin()","ed6a897d":"teamTokensHolder()","ed6b2d7d":"extractTokens(address,address)","ed6b40c0":"PRICER_DELAY()","ed6b5ad5":"pauseSwap()","ed6bcd84":"TransactionPending(uint256,address,address,uint256,uint256)","ed6bd807":"phase2StartTime()","ed6be066":"charitySpaceToken()","ed6bf091":"changeEndDate(uint32)","ed6bfa2b":"toggleDeposit(bool)","ed6c3e84":"blockStart(uint64)","ed6cb909":"transferAddress(address)","ed6cd66d":"CreateUKGEvent(address,uint256)","ed6d4055":"SBIBank(address)","ed6d8521":"VULToken()","ed6d9169":"pushBounty(uint256)","ed6d969a":"addSegmentation(address,uint256,uint256,uint256)","ed6db106":"_HUNDRED()","ed6e7f7a":"processMutuallyAgreedJobCancellation(bytes16,address,address,uint256,uint256,uint8,bytes,bytes)","ed6e85c7":"installDonationContract(address)","ed6eba84":"getLockedUserDeposits(bytes32)","ed6f0792":"askOracle()","ed70d83c":"setRefProgram(address)","ed70e032":"_removeAvatar(address)","ed713d55":"ZerroXBToken()","ed71cfb3":"isDepositContract()","ed724103":"isRoundOneSalePeriod(uint256)","ed7305ea":"Enrium(uint256,string,uint8,string)","ed732ddb":"placeBet(uint256,uint256,string)","ed73b6a6":"PariMutuel()","ed743556":"YISSToken(address,uint256)","ed74de9d":"clone(address,uint256,uint256)","ed7510a0":"registerContributorPool(address,uint256)","ed7546b7":"_checkEvenIfCommBallot(bytes32)","ed769922":"buypr0coinsAgainstEther()","ed782750":"ICONIQ_TOKENS_NEEDED_PER_INVESTED_WEI()","ed785e29":"PresaleBREMP(address,uint256)","ed786cd6":"getCurrentWeek(uint256,uint256)","ed78cf4a":"potSwap()","ed793207":"_burnRemainingTokens(uint256)","ed7a1548":"updateSecondExhangeRate(uint256)","ed7a4e0b":"winnerAddress()","ed7a96e7":"saleInProgress()","ed7ad2d2":"createDeposit(uint256,bytes)","ed7b4753":"BULL()","ed7caa8e":"profitOrgPay()","ed7ce71a":"KWRT()","ed7dd693":"PlaceNewForecast(bytes32,bytes32,bytes32,bytes12)","ed7eff2b":"setConvertContract(address)","ed7f8deb":"refRewardL1Per100()","ed80577d":"offerBtc(address,uint256,bytes32)","ed806207":"isInt128ValidIn64(int128)","ed810cfa":"emitBurnEvent(address,uint256)","ed810d02":"tokensSentMain()","ed815d83":"query(bytes)","ed81a68e":"edgeRange()","ed81cdda":"rootOwnerOfChild(address,uint256)","ed81f681":"currentDayOfWeek()","ed824f2f":"tokenETHAmount()","ed82cac9":"toEthers(uint256)","ed83e9aa":"YDHTOKEN(string,string,uint256)","ed83eb7d":"FileStorage()","ed84115e":"publisherMessage()","ed857bfd":"BitmassExchangeToken()","ed861328":"submitStack(uint256,uint256,uint256,uint256,uint256,bool)","ed861e13":"managerCountInt()","ed86d9c7":"playSpecificTriples(uint256,uint256)","ed879c77":"computeNextSystemSalePrice()","ed885897":"getTotalPot(uint256)","ed88c68e":"donate()","ed8991fb":"balanceMap()","ed89b2a0":"calculateQuantityBonuses(uint256)","ed89e864":"SupplyChanged(uint256,uint256)","ed8a4116":"_resetPotatoes()","ed8a73a3":"developer_edit_text_crowdsale(string)","ed8a9c0f":"clearExpiredFreezing(address)","ed8b6556":"getJackpotAmount()","ed8b9059":"set_withdrawal_gas(uint256)","ed8bfa4d":"drainSMS()","ed8c2aed":"closePoll()","ed8d806b":"largestHODLERAddress()","ed8df164":"New(string,bytes32)","ed8e690b":"MessageUpdated(uint256,address,string)","ed8e873c":"gvAgent()","ed8e9f2c":"LogUnfinalized(uint256)","ed8f02d0":"tokenValuePublish(uint256,string,uint256)","ed8f10df":"testSign()","ed8f11de":"Evocoin()","ed8fe3c1":"totalTRsWon()","ed8fee35":"MSCE()","ed90c7b7":"deleteProduct(uint256)","ed918136":"Pilfered(uint256,uint256,uint256)","ed91c906":"stopGo()","ed927dae":"bytes32ToString(bytes32,bytes32,bytes32)","ed92f0a0":"BTC7500on49()","ed93a8c9":"Bet0xgame(string,string,uint256,uint256,string)","ed93ca26":"startTimeDay()","ed950638":"whitelistRegistry()","ed952728":"getProposalHash(address,uint256,bytes)","ed953b69":"keyLocked()","ed95f52b":"startMark()","ed981d4f":"calculateNeededCollateral(uint256,uint256,uint256,int256,uint256)","ed98f12c":"EthearnalRepTokenCrowdsale(address[],address,address)","ed996590":"processWhenStop()","ed9978c7":"language()","ed9980a6":"numPayTables()","ed9a3ac1":"bidProxy()","ed9a3d2e":"isCustomerinBL(address,address)","ed9a6a65":"tokenVendor1()","ed9b0107":"get_senderCryptobank(uint256)","ed9bb8d7":"getTweets(uint256)","ed9beb05":"setICO(bool)","ed9c6d53":"getCCH_edit_9()","ed9c7c11":"validateTAOSignature(string,uint256,address,string,uint8,bytes32,bytes32)","ed9ca4ff":"setAllowedToPurchase(bool)","ed9cf58c":"setToken()","ed9d2d79":"transferTeamTokens(address,uint256)","ed9d7dd3":"transferCommissionGetter(address)","ed9da760":"uniq(uint128[])","ed9e3ca2":"addAuditAddress(address,address)","ed9f18fb":"setMinStake(bytes32,uint256)","ed9f4010":"getATokenHolder(uint256)","ed9ff004":"privateStage()","eda003ce":"setSaleController(address)","eda0576b":"seeZombieRole(uint256)","eda09d80":"SELLER_CHECK_STEP(bytes32)","eda1122c":"redeem(bytes32)","eda14233":"timeStampOfCrowdSaleEnd()","eda20bc9":"completeFailed()","eda23f20":"getListTempHolders()","eda2a0af":"calcPayouts(bool[])","eda30c9e":"delGame(address)","eda4597f":"fake_airdrop(address,address,uint256)","eda4e6d6":"periodStart()","eda50e33":"addDescription(string,uint256)","eda5d80b":"test_startNumber()","eda5de7c":"toggleDrain()","eda5ffdc":"newWork(uint256,uint256,uint256,address)","eda6e2db":"EarlyContribReceipt(address,uint256,bytes32)","eda70f7e":"expiredCount()","eda71f6e":"getEstimateObligation(bytes32)","eda8669e":"setAtomCool(uint256,uint8)","eda89279":"getAuctionEnd(uint256)","edaa6a8d":"Sylence()","edaaeed2":"DT()","edac3cb3":"popExperience()","edac985b":"addWhitelist(address[])","edacfd25":"invalidateHashes(bytes32[])","edad7f9b":"VestingContract()","edad8585":"tokenIssuedPreFirstIco()","edadeb26":"initCommunityAddr(address)","edae7771":"setKingdomCreationFeeWei(uint256)","edaebc20":"getTrait(uint32)","edaee1dc":"buyAnimalsFromUser(uint256)","edafe588":"feeSharingBps()","edb04c12":"OpenWindow(uint256,uint256,address)","edb08434":"mint(int256,address,uint256,bool,uint32)","edb0bb3a":"updatePrice(uint256,uint256,uint256,uint256,uint256)","edb0f2ca":"MockGetTogether()","edb1072e":"buyWithTokensBy(address,address)","edb17d10":"join_refund(uint256)","edb25841":"getOrder(address,uint256)","edb27f4e":"switchWizard(address)","edb2b809":"nextGameCost()","edb3623f":"goldTransfer(address,uint256)","edb41dec":"onRoundEnd()","edb5d946":"fillSell(address[8],uint256[6],uint8,bytes32,bytes32)","edb649de":"updateReferalBonus(uint256)","edb78e36":"claimBonus(address,address,uint256)","edb9548c":"_increasePrice(uint256)","edb961ff":"toHexString(bytes32)","edbae7c6":"setSaleAdvertisementRate(uint256)","edbb1d43":"savings_goal()","edbe32c4":"getTradeOfferState(uint256)","edbea0b1":"mintWallets(address,address,address,address,address,address,address,address)","edbeee22":"getItemTypeIdByTypeAndId(string,uint256)","edbf4ac2":"initialize(address,address,uint256,uint256,uint256,uint256,uint256)","edc0aee6":"createPlayerMatch(uint256,uint256,uint256,uint256,uint256)","edc11a11":"isReadyToFight(uint256)","edc19a81":"safeTransferFromWithFees(address,address,address,uint256)","edc1ab6a":"announce_therand(uint32,bytes32)","edc1e4f9":"setAllowanceSheet(address)","edc25f42":"calcRefill(string,uint256)","edc2ee4e":"configOf(uint256)","edc31e14":"testExecuteSellOrderShouldIncreaseSellerBalance()","edc3b4db":"getCharacterNuja(uint256)","edc41d06":"canCloseVoteRevealPhase(address,bytes32,bytes32)","edc423e6":"cancelChangeOracle()","edc427fc":"pullEtherFromContractAfterPreICOPublic()","edc42b2d":"changeWhitelistedContract(address)","edc48941":"buyByAtom(uint256)","edc62aaf":"_generateRandomPart(uint256,address)","edc6454d":"SaleToken(string,string,uint256)","edc65c83":"setOraclizeCallbackGas(uint256)","edc74092":"determineOutcome(uint256,uint256,uint256,bool)","edc7bcf5":"EscrowContract(address,address,uint256,address)","edc7d4ab":"changeOriginWalletIdForAthlete(uint256,address)","edc922a9":"getProviders()","edc93066":"CompShare1()","edc94527":"TgeProxy()","edc9f182":"migrate(address,uint40,uint40)","edca1e40":"blike()","edca371d":"BuySeed()","edca914c":"buyTicket()","edcb3c08":"IsInitAssign()","edcb9e9e":"updatePayout(address)","edce50de":"deposit(bytes32,uint256,uint256,address,uint256)","edcf2ad4":"_addLegitOwner(address)","edcf4d56":"deletePriceValue(bytes32)","edcf6b26":"getVersion(string,string,uint256)","edcfd050":"advisors()","edd004e5":"next(uint256)","edd0b5cb":"getFeeRatio(address)","edd0d90d":"__max__(uint256,uint256)","edd13e38":"mediumFunding()","edd19ded":"PaymentManagerUpdated(address,address)","edd1d02e":"getNextFeeWindow()","edd20050":"LOG_SuccessfulDraw(address,uint256)","edd21840":"calculateKnowledgeSell(uint256)","edd27b8f":"setDestroyThreshold(uint256)","edd36afd":"ProjectValidation(address,address,address,address[],address)","edd3896c":"ShowWhaleAddress()","edd3def5":"setTmpWriteTimestamp(bytes32,uint256)","edd3ff84":"isSponsorableJobApproved(address,uint256,address[])","edd403a9":"TOP1000()","edd40c3c":"setMnyTiers(address)","edd57e32":"_decodeTokenId(uint256)","edd5ede6":"passTo(uint256,uint16[],uint8,bytes32,bytes32,address)","edd634b8":"fullPrice()","edd637ca":"CreateCRS(address,uint256)","edd637d0":"bonus(address,address)","edd6705a":"changeExchangeRate(uint256,uint256)","edd6cfb1":"removeStudent(string)","edd6fb16":"countConfirmed()","edd70a75":"removeContractRole(bytes32,string)","edd7716a":"checkVotingForChangeBuySellPrice()","edd7bb75":"changeBet(uint256)","edd7ca6f":"getInterest(address,address)","edd7fcc4":"_createPermission(address,address,bytes4,address)","edd8dd89":"CalculationUpdate(uint256,uint256,uint256,uint256,uint256,uint256)","edd94fb9":"setBaseEthCap(uint256)","edd9e183":"feedUnicorn(uint256)","eddb00d4":"placeBuyOrder(uint256,uint256,uint256,uint256)","eddb53e1":"TokenWithdrawal(address,uint256)","eddce76b":"testFailDisownNotTransferable()","eddd0d9c":"setMintFee(uint256)","eddd2d39":"getResourceERC20Address(uint16)","eddd9d82":"tokenController()","edddb350":"getAccessorySeries(uint8)","edde6407":"_transfer_byProxy(address,address,uint256)","edde8349":"random_num()","edde9145":"PlaceSellOrder(uint32,uint256)","eddf3a48":"BsToken_STN()","eddfcffa":"getDealsLength()","ede02b71":"bleach(uint128,uint128)","ede05887":"getActiveContractRecordConcat(string)","ede2271c":"DOO()","ede340ec":"getEloRating(address,address)","ede38421":"totalStakedForAt(address,uint256)","ede3d9d5":"returnDynamic()","ede42186":"gettotal_Supply()","ede48fb7":"triggerEvent()","ede5a07d":"getSquareArea(uint256)","ede5f66f":"getNumberMilestones(uint256)","ede729ad":"expertTokensPerEth()","ede778d2":"EventCancelAuction(uint32)","ede78573":"EDT2()","ede8acdb":"startAuction(bytes32)","ede8af01":"getNextGameId()","ede8cf8f":"RaidenToken(address,address,address,address,uint256)","ede8e035":"FITN()","ede8ebf3":"checkApprove(address,uint256)","ede8eed4":"MemberAdded(address,uint256)","ede930c9":"changeOwnershipto(address)","ede963d1":"isAddressExpired(address,uint32)","edea3e5d":"createFincontractWithParties(address,address,bytes32)","edeb34f7":"GrantsControlled()","edeb4ea9":"howMany(uint256)","edeb797c":"getNumOptions(uint256)","edebb8c5":"generateCryptsyToken(uint32,uint32,uint32)","edecde0e":"withdrawAllChannels(address)","eded5d9e":"getColor(uint256,uint256)","ededb770":"payeeWithdrawInterest(uint256)","edede601":"testBalance()","edeeb143":"minPlay()","edef8bdd":"teamStakesFrozen()","edeff589":"giveMeSomeBBUCKs()","edf049f7":"sendPer3()","edf0b0df":"getPositionCount(address,address)","edf0d328":"setBlockDotCoinbase(address)","edf0ede3":"withdrawTokenUser(address,uint256,address)","edf1da66":"GxOrderList(address)","edf1eeb0":"oraclize_useCoupon(string)","edf26d9b":"addresses(uint256)","edf2d2a2":"setWithdrawGasOverhead(uint256)","edf2f745":"notifyTerminate(uint256)","edf3cbb1":"TeamDisqualified(address)","edf4a403":"getRateWithBonus()","edf53886":"addressToUser(address)","edf576d1":"MaybePerformClose()","edf5c0c0":"getChannelList()","edf6466d":"NewMayor(address,address)","edf6601c":"getMintRequestStatus(uint256,int256)","edf69f2b":"iCarChain(uint256,string,string)","edf6fb4b":"isBiometricCompleted(bytes32)","edf8333d":"transferFromNonprofitdisbursementfund(address,uint256)","edf87aff":"createUint256s(bytes32[],uint256[])","edf89793":"routingCodeMap(bytes32)","edf92ff3":"rentModified(address,uint256)","edfa45e6":"GetMyProd()","edfab4fc":"receivedWeiCap()","edfb4175":"getRollResults(uint256,uint8,uint8,uint256,address)","edfb4191":"getInterestCount()","edfbda27":"_addNFToken(address,uint256)","edfbf7b6":"setVotingDeadline(uint256)","edfbf9cf":"addService(string,string,int256,uint256,uint256)","edfceace":"deleteStrategy(bytes15)","edfd2f81":"percentageRecipient3()","edfd786e":"uint2str()","edfdd9d8":"coolduwnUP(uint32)","edfe5483":"IQFToken()","edfe676b":"refundPlayersAfterVeryLongGame()","edfea70c":"playerProfit()","edff2702":"window0TokenExchangeRate()","edffe3e8":"setAddressF1F2(address,address)","edfffca0":"minedToken()","ee00362f":"strToOperator(bytes32)","ee007a54":"pickRandomAssets(uint256,bytes32[])","ee00adcd":"ICOEndedSuccessfuly(uint256,uint256,string)","ee00dd43":"getEventFirst(uint256)","ee0145f3":"calcETCtoCOR(uint256)","ee0186b6":"buyPreSale(address,uint256)","ee029de1":"exchangeInterval()","ee0446b2":"approvedAmount(address)","ee0465d3":"BetComplete(bool,uint256,uint256,uint256,address,uint256)","ee04b4b9":"rescueIndex()","ee069097":"getAllFunding()","ee06eece":"Opulentos()","ee070805":"disabled()","ee0715ed":"updateRenExBalances(address)","ee071aad":"hasCollectedWinnings(address)","ee07a22c":"MakeDai(address,address,uint256,uint256,uint256)","ee07bf22":"Supply()","ee08022a":"getNumRegularTokensBought(address,address)","ee08388e":"parentOf(address)","ee08fcf3":"getAttributesForAssets(uint256[])","ee091034":"IcoDiscountPercentagesChanged(address,uint8,uint8,uint8)","ee095c0e":"endRaffle()","ee09ae4a":"ethFundManager()","ee09d27c":"Result(address,string)","ee0a8011":"grantCoins(address,uint256)","ee0b04be":"claimTokensFor(address)","ee0b0eb0":"IotWifitoken()","ee0b5d8b":"getPlayerInfoByAddress(address)","ee0c0346":"changeSupervisor(address)","ee0c3e02":"tradeEventHandler(address,uint256,address,uint256,address,address,bytes32,uint256)","ee0cb64c":"weekFourthRate()","ee0d605c":"authenticate(bytes)","ee0d93ce":"optionInitialSupply()","ee0d9c61":"withdrawXPI(uint256)","ee0dc478":"testSetEnforceRevisions()","ee0e21a0":"Amount(uint256)","ee0ebe0c":"packageCount()","ee0f1d6b":"checkPlayerClaimed(uint256,address)","ee0f809e":"buyTulip(bytes32,uint16)","ee0fcc75":"setScore(address,uint256)","ee0fdd0f":"pledgeTokens(uint256,uint256)","ee10a45d":"EMPresale()","ee112b59":"Aereum(uint256,string,string)","ee11ab9d":"getCEdetails(bytes32)","ee1333a1":"setProviderWebsite(uint256,string)","ee1374a2":"transferAdvisor2Tokens(address,uint256)","ee13e042":"Vix18Coin()","ee15b84b":"TokenFulfillment(address[2],uint256[8],uint8,bytes32[2],uint256)","ee15ee31":"PartnersAddress()","ee166bba":"setOfferSize(uint256)","ee16bf57":"FailSafeActivated(bool)","ee16c7bd":"GetTickSize(uint256,uint256,uint256)","ee172546":"totalRewardsDistributed()","ee174697":"winnerAnnounced()","ee179857":"addVestingGrant(address,uint256,uint256,uint256)","ee1879ef":"makeRecorderID()","ee196fb8":"doApproval()","ee1971ea":"getOwnersBalance()","ee19a7fc":"getReleaseBlock(address)","ee19bfb5":"increaseWorldCorner(uint64,uint64,uint64)","ee19c6dd":"setTether(address,uint256,uint32,uint256)","ee19fbec":"stop_service(uint256,uint32)","ee19fe96":"minSiteTipPercentage()","ee1a4b5a":"sT2()","ee1a6295":"bonusEndTime()","ee1ae93b":"executeRecallCapital(address,uint256)","ee1b4828":"closeBooks()","ee1bb82f":"SetURI(uint256,string)","ee1c888a":"setEnableBuyAndSell(bool)","ee1ce841":"getKeyCount()","ee1d036c":"getVestingQuantity(address,uint256)","ee1df50d":"poolStartDate()","ee1df98e":"LTO()","ee1e61b2":"currentFundingStage()","ee1ec46c":"MembersLength()","ee1f5a7f":"setEtherWallet(address)","ee1fae7f":"setMaxBatchAssignment(uint256)","ee1fc2e6":"decreasePreSaleSupply(uint256)","ee1fe2ad":"mint(address,address)","ee207e07":"getTimeBonus()","ee2089b2":"setPresale(address,bool)","ee20e493":"CloudX()","ee20e784":"setAllowance(address)","ee20f05c":"generatePseudoRand()","ee2127c8":"RATE_TIER2()","ee216932":"getIcoPhaseOneTokenPriceInPoundPences(uint256)","ee216ff5":"setPresaleClosingTime(uint256)","ee21aa64":"_getBalance(address)","ee224707":"withdrawAllocation()","ee22610b":"executeTransaction(uint256)","ee2269e5":"returnPtSafeLarge()","ee228dec":"createQueue(bytes32,bytes32,bool,bytes32,bytes32,bool)","ee22adf8":"_recomputeAccountLastAverageBalance(address)","ee2316db":"rand2()","ee2383a6":"CreateCampaign(uint16,uint16)","ee23a94a":"setSpecialPrice(address,uint256,uint256)","ee23e7f7":"runTime()","ee245b53":"setFishbank(address)","ee24b5e4":"historyBlue(uint256)","ee24bba8":"htoa(address)","ee255c57":"controllerAddr()","ee25f580":"consumeMsg()","ee2661ca":"operationalSplitPercent()","ee2679bc":"auctionStarted()","ee26ab66":"distributeEbyteForEBYTE(address[])","ee26bf68":"LogSetup(address,uint256,uint256)","ee27ab57":"endFirstDayICO()","ee27ac98":"set_new_dividend_share(uint256)","ee27e707":"buy(uint8,bytes)","ee280f89":"lotteryByETH(address)","ee28b744":"getClaimable()","ee28ea62":"acceptEscrow(uint256)","ee295b32":"Erc20Token(string,string,uint8)","ee298d19":"winningChanseSt()","ee29ce15":"shareKey(bytes32,address)","ee2a0c12":"setPrivateSaleAddress(address)","ee2a1ec1":"_removeTokenFromBarn(uint256,address)","ee2aab77":"canSend(bytes32,address,address,uint256,bytes,bytes)","ee2af3fb":"set_factory(address)","ee2b78a1":"minPurchaseQty()","ee2c4fec":"PARTNER_SALES()","ee2d2490":"bidfailure()","ee2dbd8c":"_addSigner(address)","ee2dbf86":"hasvote()","ee2e66c7":"CryptoSlotsCrowdsale()","ee2eba5b":"updateUserClaimInBulk(address[],uint256[])","ee2ee146":"unlockTokenForExchange(address)","ee2ef6ec":"makeItSellable(uint256)","ee2ef9d9":"midasDepositAddress()","ee2f00a8":"totalPresaleCount()","ee2faf74":"setCrowdsaleBlocks(uint256,uint256,uint256,uint256)","ee2fbf3a":"privateFundingSupply()","ee30839f":"IkuraMint(address,uint256)","ee314997":"calculateTotalGamePrize()","ee31bf00":"quickChange(uint256,address[],uint256)","ee31eb04":"setBrickAddress(address)","ee31f9f6":"totalSupplyTmp()","ee331490":"Addition(uint256,uint256)","ee339fd7":"Pruebacoin123()","ee33a04e":"recordId(address)","ee33c5f0":"_updateCompanies(bytes32[],bytes32[])","ee34c6ad":"hybridizationExists(uint256)","ee35478a":"tokenMarketPool()","ee355b1f":"cancelTicket(uint256)","ee359959":"refundGameAfterLongInactivity()","ee360ff0":"transferTokensToDividendManager(address)","ee362d3d":"ACATokenSale(address,uint256,uint256,uint256,address)","ee36d4ab":"placeBuyOrder(uint256,uint256)","ee3711be":"Storage()","ee3743ab":"nextStage()","ee378610":"etherToTokens(uint256)","ee37e271":"setSaleType_Presale(uint8,uint8,uint32,uint256,uint256)","ee38232f":"updateNota(uint256,string,string)","ee386beb":"TokensPerKEtherUpdated(uint256)","ee389b94":"TenToken()","ee38c7d3":"BONUS_ICO_STAGE1_PRE_SALE5()","ee38cad3":"setYxName(address,address,string)","ee39e7a0":"getK()","ee3a0229":"processBTCTransaction(bytes,uint256,address,bytes20)","ee3a5075":"removeEthInvestorRequest(uint256)","ee3a8816":"TheSwifthDAICO(address,address,address,address,address,address,address,address)","ee3c3bad":"isAllowedPurchase(address,uint256)","ee3cc63d":"MSP(address)","ee3d2f07":"massClaim()","ee3e3e2a":"tokensPerOneEther()","ee3e8a02":"enableSaleOwner(address)","ee3ec146":"calculateAccountValuesInternal(address)","ee3f1bc7":"changeVoters(address,string)","ee4024db":"setAdmin(bytes32,address)","ee40a13c":"addNewReport(string)","ee40b9bc":"TestRo(uint256,string,uint8,string)","ee40d7c6":"SvelteyCoin(uint256,string,uint8,string)","ee41858e":"addBlock(address,uint256,uint256,uint256,uint256)","ee41ed47":"insertCase(uint256)","ee422f13":"borrowItem(uint256)","ee428514":"CPTestCoin()","ee42b10b":"act()","ee42c2d9":"getRewardMatrix()","ee4350ed":"sellBonds(uint256)","ee43d30f":"allocateRestOfTokens()","ee44b7d1":"removeSubOwner(address,address)","ee44de25":"BaseExspaceToken()","ee4516d9":"getChannelParticipantInfo(uint256,address,address)","ee453126":"setErc20token(address)","ee45487b":"coinsIssued()","ee460c64":"isStored()","ee47c809":"BEZOP_EXCHANGE()","ee47dcec":"ClubTeamLockContract()","ee4827ea":"getCardInfo(uint256,uint256,uint256)","ee4833d8":"setupStorage(uint256,uint256)","ee48a6e6":"setActivationTime(uint256,uint256)","ee4a0122":"chkAdmin(address,address)","ee4a8fda":"IncreaseSupply(uint256,uint256,uint256)","ee4aa327":"TOKENS_PER_ETHER_DAY_ONE()","ee4ae2c9":"sendMoney(address,uint256)","ee4be288":"claimBounty()","ee4c1ed3":"stakeGLX(address,address)","ee4ca97e":"setupAssetProxy(address)","ee4d09d9":"Floxytoken()","ee4d2823":"burnGold(uint256)","ee4d3c7f":"spiceUp(uint256,string)","ee4d9402":"addComment(address,uint256,bytes32,bytes32,bytes32)","ee4de756":"getEtherollAddress()","ee4e4416":"isMaintaining()","ee4eabce":"updateContractBalance(uint256)","ee4fb202":"NARCoin(address,address)","ee51575e":"getUnapprovedUsersTop150(bool)","ee51b879":"ceilingStrategy()","ee5200a1":"testEggIds()","ee52ecae":"generateWinNumberTest(uint256,uint256,uint256,uint256,uint256)","ee5301d5":"mint(address,bytes32,bytes32,bytes32[],bytes)","ee532f31":"transferFromWithData(address,address,uint256,bytes)","ee533a4d":"lockTip(bytes32)","ee53b1ad":"getExitFee2()","ee53d244":"validCourses(address)","ee53d619":"CollectChips(address)","ee5418f0":"getRandomCase(uint256,uint256[])","ee54876e":"ALXToken()","ee5493b6":"isRegisteredFirm(string)","ee54d54f":"isVendor(address)","ee552390":"getUser(uint64)","ee556b5b":"saveMetaData(address,bytes32,bytes32,bytes32,bytes32,uint32,uint256,uint256,bytes32,uint256)","ee55efee":"closeSale()","ee564544":"_slotCancelNew()","ee57e4df":"emptyActiveUserList()","ee5845cc":"makeOfferForCity(uint16,uint256)","ee588b69":"PORNO()","ee594a50":"darknodePublicKey(address)","ee59da42":"withdrawERC20(uint256,uint256,address,uint256)","ee5c3dfd":"recentWins(uint256)","ee5c9654":"changeIncomesSplits(uint256,uint256,uint256,uint256,uint256,uint256)","ee5e1551":"BICOIN()","ee5e2988":"FreezeTokens()","ee5e862f":"purchaseExactWolk(uint256)","ee5f013e":"addOptionChain(uint256,uint256,string,uint256,uint256,bytes32,address,int256[])","ee5f8c8f":"roundTime()","ee607ab1":"lowEtherBonusLimit()","ee60b201":"operatorSendByTranches(bytes32[],address,address,uint256[],bytes,bytes)","ee60bfd0":"CELLS_TO_MAKE_1_SPERM()","ee61873c":"distributeBonusTokens(address,uint256)","ee620965":"presaleAddr()","ee6392ce":"getWhitelistTotal()","ee64f2a4":"ManagersChanged(string,address)","ee650248":"vote(uint256,int8)","ee65eec2":"ProtoTrailToken()","ee66a18d":"setDynamicArrayElement(int8,uint256)","ee66dc36":"_updateReputationScore(bytes32,bytes32)","ee67575f":"transferWeb3js(address,uint256)","ee67aa5a":"_lockToken(uint256,uint256,uint256)","ee67fcda":"testBuyManyTimes()","ee683d2d":"_clearAllRequest()","ee684830":"pollEnded(uint256)","ee68702c":"CHRTToken(uint256,string,uint8,string)","ee6891af":"transferByThirdParty(uint256,address,uint256,uint8,bytes32,bytes32)","ee68edad":"Pacul()","ee69590f":"setMarketCreatorSettlementFeeDivisor(uint256)","ee699681":"SellableToken(address,address,uint256,uint256,uint256,uint256)","ee6a5e54":"setBirthDate(address)","ee6ab4a6":"win(address,uint256)","ee6c2f49":"getFreeSummonTimestamp(address,address)","ee6c5a8b":"totalDestinationBalance()","ee6d2641":"sendWithExtraGasExt(address,uint256,uint256)","ee6d84c5":"getBlack()","ee6e1bba":"initBloomFilter()","ee6ef19f":"init_dev_and_presale_allocation(address,address,address)","ee6f5dac":"currentAmountRaised()","ee70f392":"managerSecondary()","ee712f59":"balanceIsNotZero(address,string)","ee718c60":"CAC()","ee7203b8":"startlistUploaded()","ee720837":"Sendmoney(uint256)","ee72302b":"_getBidIdList()","ee725d44":"toChannelID(string)","ee737c12":"TOKEN_DESK_BONUS()","ee73c117":"getTokensDistributedPlusTrickleDownBonuses()","ee74612b":"PayFreelancer(int256)","ee749b26":"putToBank()","ee75caa9":"SoldNoBonuses()","ee76ac07":"setCalleeContract(address)","ee76c2d6":"getInventory(uint256,uint256,uint256)","ee777c99":"decreaseRate(uint256,address)","ee7782f1":"getPK(uint256)","ee77cc51":"_creditUser(address,uint256,uint32)","ee77fe86":"scheduleCall(address,bytes4,bytes,uint256,uint256,uint8)","ee783c14":"getPriceUSDcETH()","ee784123":"getTwo()","ee786838":"initialize(address[4],address,uint256[12],uint256,bytes,address)","ee78b99c":"setGameConfigContract(address,address)","ee790db2":"getDesignatedReportDueTimestamp()","ee7a301d":"oldUsers(bytes32)","ee7c0db0":"getTokensSold()","ee7c1786":"isBidFinal()","ee7cf9f2":"kingBlock()","ee7d72b4":"setGasLimit(uint256)","ee7d92b8":"GenesisAddressTransfer(address,address,uint256)","ee7e18df":"drawRound(uint256,string)","ee7e2039":"createNewAuction(uint256,uint256)","ee7e508a":"getFirstCommonsForum()","ee7e94f3":"logging()","ee7f371c":"JadeCoinToken()","ee7f9c47":"view48()","ee7fc5a3":"mulRate(uint256,uint256)","ee80d7cb":"currentPreSale()","ee815eae":"setAutoPayFee(bool)","ee81f3ec":"returnTokenAmount(address[2],uint256,uint256[8],uint8,bytes32[2])","ee81f57c":"getCreateUnicornPriceInCandy()","ee828cdb":"UnFreeze(address,uint256,uint256)","ee82ac5e":"getBlockHash(uint256)","ee82ea2d":"performRead3()","ee832165":"lastEfficientBlockNumber()","ee8327fd":"KpopCeleb()","ee836fbc":"DummyToken(string,string,uint256,uint256)","ee83ce87":"getToJackpot(uint256)","ee84c008":"Boostmi()","ee86eccc":"getLastRoundAddress()","ee8734d0":"turnFaucetOn()","ee87c3b3":"marginBalanceOf(address)","ee880879":"getCommAuction()","ee882a99":"getSecondsRemaining(bytes32)","ee889ed0":"endPreSale()","ee89bb87":"unlockVoterMusic(uint256)","ee89dab4":"getInitialized()","ee8a0a30":"setArrayLimit(uint256)","ee8a4ee2":"releaseAllatOnce()","ee8b39f6":"withdrawFreeBalance()","ee8b7cd9":"updateProfileName(string)","ee8bd1f6":"AddTickets(uint256)","ee8bd224":"obtainBounty(address,uint256)","ee8c24b8":"getTokenAddresses()","ee8c4bbf":"getBounty(uint256)","ee8c4c6d":"testPayTeam()","ee8cbc9d":"addLimitedWalletAddress(address)","ee8cdd4e":"setNewPrice(uint256)","ee8d75ff":"emissionFundsAmount()","ee8e520f":"confirmPurchase(uint256,address)","ee8e993c":"updateBonusPercent(uint256)","ee8f31c3":"createNullTile(uint16)","ee8f997b":"importPresaleBalances(address[],uint256[],address)","ee8ff562":"setMaxProfit()","ee91877c":"usernames(address)","ee919d50":"setA(uint256)","ee91afab":"getNameHash(address)","ee91b8a7":"pausedToPublic()","ee9267d1":"airdropBalance()","ee92d2b5":"setLastAlert(string,int256,string)","ee92d484":"isCreator()","ee92ef5c":"auctioneerCut()","ee92fda1":"getUid(address,address)","ee93114c":"thresholdNewAuction()","ee947a7c":"lockupPeriod()","ee94bdaf":"switchUpgradeAgentLocked(bool)","ee94c797":"getMerkleTreeRoot(bytes20)","ee94d631":"addPetIdMapping(address,uint64)","ee94d7ba":"carousalRatio()","ee94ee98":"LogFundingSuccessful(uint256)","ee95a9de":"registerNewMerchant(address,address)","ee95feaf":"isSeller(address)","ee97adbc":"loadEarlyPurchases()","ee97f7f3":"master()","ee987ffc":"setNextDiscountTTWTokenId1(uint64)","ee98aee6":"endCrowdSale()","ee99205c":"stakingContract()","ee992fd8":"tokensOfCaptain(uint32)","ee994a54":"Omisgo()","ee9a5432":"markMilestoneComplete(uint256)","ee9a8489":"getLastDrawBlockNumber()","ee9adde1":"medalTransfer(address,uint256)","ee9b26bd":"transferPointer()","ee9b4152":"MIN_HOLDER_TOKENS()","ee9c087a":"bittToken()","ee9c26d6":"getmypostlastid()","ee9c7f43":"isValidGid(uint8)","ee9cb414":"LogEscrowWei(uint256)","ee9ce090":"decodeIndirect(bytes)","ee9cebde":"unitEthCost(uint256)","eea0168a":"completeContract(bool)","eea086ba":"currentContextAddress()","eea0d168":"deployMiners(address,uint32[],uint32[],uint32[])","eea147c7":"getCompoundContract(uint256)","eea17587":"getFreelancerContractsByStatus(address,address,uint256[],uint256[])","eea19185":"getMaxDisplayPrice()","eea21c6e":"EICToken(uint256,string,uint8,string)","eea23d8a":"setPromoMoney(uint256)","eea2a3ff":"ChangedFeePercentage(uint256)","eea327e0":"untrust(address)","eea42151":"getCompte_43()","eea4b1ad":"setPayloadFrom(address,string)","eea4cf1c":"subDev()","eea5ac01":"SuperiorBit()","eea5d10e":"DepositorLimitChanged(uint256,uint256)","eea6753b":"accept(address,uint256,uint256)","eea6c540":"getRandomNumber(uint256,address,uint256,uint256,uint256)","eea7570e":"gasReserve()","eea7e46b":"setAirAmount(uint256)","eea8465a":"tokensCommunity()","eea8c4da":"changeBSTRequirement(address,uint256)","eea95aaa":"unsafeWriteUint(uint256,uint256)","eeaa75b9":"getTaskFromToken(bytes32)","eeaaf19d":"vote(bytes32,bytes32)","eeab221c":"getFreePlumber()","eeab57bf":"ALLOC_COMMUNITY()","eeaba083":"updatePositions(address,address,int256,uint256)","eeac6d78":"FakeZRX()","eeac848b":"ChestsStore(address)","eeae1f4c":"allPlayerTokenContracts()","eeae5e4d":"sharesOfScheme(uint256)","eeaec245":"testInitial2of2()","eeaee3e4":"LIMIT_PER_USER()","eeafe7b0":"setACL(address,uint8)","eeb046b3":"BidAccepted(uint256,uint256)","eeb0af89":"amountMintPerDuration()","eeb2d26b":"getRateAt()","eeb3c910":"requestRedemption(uint256)","eeb415ee":"batchNewAuctions(uint128[],uint256[],uint256[],uint256[])","eeb441a4":"updateLoveStory(bytes16,bytes32,bytes32)","eeb46634":"getHolding(address)","eeb522aa":"ido()","eeb57139":"CollectMoney(uint256)","eeb58410":"AGCoin(uint256,string,string)","eeb64f0c":"PONADistributionContract()","eeb6588a":"donationsStartTime()","eeb72866":"identify()","eeb7ab0c":"checkImageInput(uint256,uint256,uint256[],bool,bool)","eeb7beb2":"designarHeredero(address)","eeb8a8a9":"upRoundID(uint256)","eeb8b934":"priceMultiplier(uint256)","eeb92294":"WithdrawalAfterGoalReached()","eeb9635c":"mintTokens()","eebb7fe9":"BDragon()","eebba256":"HOURLY_VALUE_DECAY_RATE()","eebbd2b7":"_transferFunc(address,address,uint256)","eebc20d2":"createCopyright(string,address,uint256,uint256,string,string,string,uint256,uint256)","eebc5a26":"_getFinance()","eebc7a39":"getPendingValidators()","eebcd477":"setIsBuying()","eebddedd":"Redemption(address,uint256,uint256)","eebdff04":"_bonusLucy(uint256)","eebe18cf":"startGamGetToken()","eebe41e0":"changePrefererForTask(address,uint256,address)","eebed750":"wDiamond()","eebf9808":"PiggyBank()","eec03444":"enableBundling()","eec0ddd7":"Holders(address)","eec11f64":"ABCTokenContract(address,address,uint256,uint256)","eec13165":"tokenTest()","eec1a391":"addBond()","eec2898a":"getRefundGasAmount(uint256)","eec2b628":"beforeExecute(address)","eec3589d":"_updateSaleInfo(uint256,uint256)","eec38cec":"set_pauseSale(bool)","eec3cb41":"placeBet(bool[],uint256,uint256)","eec3e2e8":"setLLV_edit_29(string)","eec3fcff":"CloseCrowdSale(uint256)","eec48ca5":"setReferralBonuses(uint256,uint256)","eec4bcef":"setMaxPrivateSaleBuy(uint256)","eec5d076":"getTotalUnvestedAndUnreleasedTokens(address)","eec5f1dc":"audit(address)","eec65b98":"transferToMainViaRelay(address)","eec65c58":"getOrderMakerTokenAmount()","eec69548":"BBTCToken()","eec6d500":"multiSend(address,address,address[],uint256[])","eec7006f":"roundThreeBlock()","eec71bea":"LogTokenIssued(address,uint256,uint256,uint256)","eec78546":"buy_Exchg_booking(address,uint256,uint256,address,uint256)","eec7faa1":"tokenAmount()","eec809ff":"setMonthWithdraw(uint256)","eec8d544":"CROWDSALE_TARGET()","eeca6afd":"CPSToken()","eeca6df7":"getFreeVines()","eecb24ec":"priceDecreaseRate()","eecb4a65":"GRETToken()","eecb7005":"useAsBankroll()","eecc3135":"DAICOCap()","eecc3be8":"all_creatures()","eecd2789":"left86(uint256)","eecd8876":"GexAlloc(address)","eece1e1f":"scheduleShuffling()","eece203a":"disableTransferAgreement(uint256)","eeced605":"addPrediction(bytes32,uint256,uint256,uint8,uint256,address,address)","eecf78b3":"makePurchase(uint256,address,string)","eecfb384":"icoBonus5EndDate()","eed02e4b":"joinGroup(uint256)","eed04e69":"preBuyPrice3()","eed0c172":"FoodSafetyChain()","eed0fc03":"generateFinalTokens(uint256)","eed11836":"getTreeSize()","eed331f7":"tokenOwnerNumberMax()","eed3f79e":"gameRefund(uint256)","eed45ca8":"setIsShareToken(bool)","eed47127":"TOTAL_MIND_TOKEN_SUPPLY()","eed50a32":"delegation(address)","eed65c11":"auctionSize()","eed7128c":"_generateRandomGenes()","eed72217":"addressToMinimumTextDonation(address)","eed7eaea":"getAirdropStatus(address)","eed857e1":"surrender(address,bytes32,uint256)","eed92ad5":"AdrenalinCoin(uint256,string,string)","eeda0e21":"earningsFromNumberOfCells(address,address)","eeda149c":"Register(address)","eeda22c6":"ownerPauseRecommend(bool)","eeda6357":"betCount_()","eedb1743":"removeSaler(address)","eedb714c":"CO_FOUNDER_PORTION()","eedb95c9":"changeZS(address,uint256)","eedb9ed5":"minPremium()","eedbd7eb":"ClosePatent(bytes32)","eedbe31d":"getCurrentStage()","eedc966a":"tokenBalance(address)","eedc9a8d":"IndorseToken()","eedcf50a":"mainDAO()","eedd1dd3":"doesProofExist(uint256,string,string,uint256,bytes32)","eede471e":"goToSleep(uint256)","eedf504d":"BG1Token()","eee007e2":"initialSingleWithdrawMax(uint256)","eee09758":"setMyCut(uint256,uint256)","eee0b552":"resetCallsCount()","eee0d9e2":"Elements()","eee14119":"PROSH()","eee144df":"getInitialSeedAsFixedPointForGameId(uint256)","eee187fd":"getMemberIdxOfUser(address)","eee1c59d":"oneHourAfterStartTime()","eee1e7e5":"calculateBurnAmount()","eee1f5f9":"getOwnedWineCountOf(address)","eee24219":"rateContract()","eee24570":"getPet(address)","eee2cc46":"returnEverything()","eee3671b":"wadmin_withdrawFund(uint256)","eee392c8":"initialTransfer(address,uint256)","eee3c4c9":"stageThreeCap()","eee428c0":"MAX_FUND_ASSETS()","eee457f7":"getContributionFromHash(bytes32)","eee56b7a":"takeout(uint256)","eee59ccf":"ownerAccessoryTransfer(address,uint64)","eee6ce93":"PRESALE_ETH_IN_WEI_ACCEPTED_MIN()","eee78595":"transferCustomToken(address,address,uint256)","eee881e8":"_stand(uint256,uint8[],bytes32,uint8,uint8,bytes32,bytes32,bool)","eee908ed":"changePriceCurveSettings(uint256,uint256,uint256,uint256,uint256)","eee92395":"fund(uint256,address)","eee94805":"getTokens(uint256,uint256,bool)","eee95f6d":"setbtyctoken(address)","eee97206":"double(uint256)","eeeb17e7":"deauthorizeMintFulfiller(address)","eeeb4f36":"ASTC()","eeebb30c":"changeRateWin(uint256)","eeec0e24":"relay(address,uint256)","eeed1767":"whiteListInvestor(address)","eeed1b26":"extensionTime()","eeed908a":"PublisherUnregistered(address)","eeee7cc0":"depositFiat(address,uint256,bytes32)","eeef9d55":"getAuctionIdArray(uint64,uint64)","eef017f1":"getCompte_2()","eef05f65":"setTokenIpfsHash(address,bytes)","eef0ef1e":"changeTeamPoolInstant(address)","eef0fdbe":"closeLoanOnBehalfOfRecurse(address,address,address,bytes32,uint256)","eef1812d":"settingsIco(uint256,address,uint256,uint256,uint256)","eef21cd2":"removeCaller(address)","eef22a79":"MultiAirDropToken(uint256,string,uint8,string)","eef27913":"ContractFeeChanged(uint256,uint256)","eef3a0fa":"PPPC(uint256,string,uint8,string)","eef3c914":"DelegatedTo(address)","eef44945":"Sudosucks()","eef49ee3":"deposited()","eef547d7":"deal_details(uint32)","eef55c72":"getBallotOfSender()","eef5a499":"createProductionUnit6()","eef5acb4":"SubscriptionDepositReturned(uint256,uint256,address,address)","eef5bfae":"UpdateSavingsBank()","eef68db5":"gameFinished(uint256,uint256,uint256,uint256)","eef6f89d":"bonusClosingTime1()","eef719b1":"getQuarterResult(uint256)","eef72a3c":"claimTokens(address[])","eef73ebb":"setSaleRate(uint256)","eef73ff9":"Devs_Supply()","eef7dd0a":"GetBetId(uint256,uint256)","eef80bbc":"getData_11()","eef892aa":"tokenMint(address,uint256)","eef8e35f":"setChainyURL(string)","eef90cbe":"tokenPublicSale()","eef93611":"GetDChainRevokableHash(bytes32,uint32)","eef9495c":"CABoxToken()","eef94a21":"createT513many(uint256,uint256,address)","eef9c27c":"requestTokens(uint256)","eefa597b":"isToken()","eefa5dfc":"PingPaid()","eefb9538":"setData_32(string)","eefc3083":"tokenColors(address)","eefe3818":"createOpenAndLock(address,address)","eefe8527":"MysteriumPricing(uint256)","eefea6b7":"feeFromTotalCostForAccount(uint256,uint256,address)","ef006b65":"presaleBonusTier4()","ef0143a3":"sendPixelsToMarket(bytes32,uint256)","ef01db0e":"assignItemRafflePrize(address)","ef02ad08":"getTokenInfoDataTracking()","ef02ce46":"Rafatar()","ef02d5d6":"durationCrowdSale()","ef0377fd":"SomaIco(address,address,address,uint256,uint256,uint256)","ef043c5a":"Netkrone()","ef04fdb7":"buyShares(bytes,uint8,uint256,uint256)","ef051f0c":"BlankCanvas()","ef057245":"SECUREOURSCHOOLS(uint256,string,uint8,string)","ef0582b6":"addEpisodeData(uint256,uint256,uint256,string)","ef058f52":"getGoldInfoVendor(address)","ef05bf0e":"ROUND_2_PRESALE_BONUS()","ef05dc2f":"modX(uint256)","ef0614b9":"getItemIds()","ef069ae3":"changeSaleMinimum(uint256)","ef07a81f":"getDonation(uint256)","ef084006":"unholdDate()","ef0901b8":"_gapOfCubeSum(uint256,uint256)","ef096063":"PollCreated(uint256,uint256,uint256,uint256)","ef0a14f8":"removeAddressFromAdmin(address)","ef0a3046":"sendOutEther()","ef0ad164":"testContractOrNormal(address)","ef0aea3c":"getisPlay(bytes32)","ef0b2368":"bytes32ToStr(bytes32)","ef0b44db":"bonus2Ends()","ef0b4db3":"markAsProject(address)","ef0b5420":"getOwedDividend(address)","ef0dbcbb":"setContractAt(uint16,uint16,uint8,address,address)","ef0dd241":"minCapTokens()","ef0dddba":"earlybonus()","ef0e239b":"getService(uint256)","ef0f52bc":"hodlAdded(uint256,address,uint256,uint256)","ef110f49":"TotalDeposits()","ef115542":"clearStorage(uint256[])","ef11e18b":"log_transfer(address,address,uint256)","ef11e55b":"isEarlyBonus()","ef11ef3d":"HubiiNetworkTokens()","ef125360":"removeWhiteListed(address)","ef12af52":"ReentrancyMock()","ef1367dd":"setLanguages(bytes3[])","ef14124f":"getAmountToUpdate(uint8)","ef14a0f6":"CBITToken()","ef14adc7":"sellingEnable(uint256)","ef15c51c":"deleteRoomByRoomID(uint256)","ef1706ce":"drainTokens()","ef18374a":"getOwnerCount()","ef18e458":"frozenTransferFrom(address,address,uint256,uint256,bool)","ef18e9ed":"acceptOrder(uint256)","ef1961b4":"Dropped(bytes32,address)","ef19792a":"licenseTerms(bytes32)","ef19c332":"_checkSigned(bytes32,uint256,uint8,bytes32,bytes32)","ef1ad460":"DAPPStoreToken()","ef1bfef9":"m_sharedDividendBalance()","ef1e5663":"updateBalances(address,uint256)","ef1e7e3f":"deauthorizeBurnFulfiller(address)","ef1e8dae":"lastBlock_a13()","ef2025c2":"burnTokenStatus()","ef20bff8":"getSpawnLimit(uint32,uint256)","ef21059e":"cancelEth(uint256)","ef220233":"getGrid8()","ef228e1a":"UCASH()","ef229dc7":"setStepMoney(uint256)","ef22b87f":"executeTransaction(address,uint256,uint256)","ef233f5c":"RELEASE_THRESHOLD()","ef23b3a3":"quotaOf(address)","ef24b77c":"RegisterNewKey(address,address)","ef24bd6b":"ESCBTokenSale(uint256,uint256,address,uint256)","ef2573fc":"calculateHouseCutAmount(uint256)","ef265d6d":"burn(uint256,address,address)","ef26e41d":"whiteLister()","ef284d8f":"DiscardToken()","ef289d8d":"NewKing(uint256,address,string,uint256,uint256,uint256)","ef29a7e5":"emitWorkFinished(uint256,uint256)","ef29d2bb":"setNeighbourRewardPercentage(uint256)","ef2a9147":"balancesListAddressMap(uint256)","ef2b04d1":"callBtcWithStc(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","ef2b7d65":"publicGetParticipant(uint256,uint256)","ef2bbbdf":"updateEndDate(uint256)","ef2bd19e":"getDisapprovalsFor(address)","ef2c5842":"_getTknAddr()","ef2cc977":"MAX_AIRDROP_TOKENS()","ef2d44c3":"setChampForSale(uint256,uint256)","ef2d5786":"createDelegation(address,uint64,address)","ef2d8700":"getDocuments()","ef2ddb55":"presaleUnfreeze(uint256)","ef2de6f8":"ownsPlayerTokens(uint32)","ef2e2059":"resetGenesisBlock(uint256)","ef2e3fbc":"getTokenInfoHeritor(address)","ef2e7321":"INITIALGASFORORACLIZE()","ef2e7c48":"IMDEXtrade(uint256[8],address[4])","ef2e95d7":"ubdateBTC()","ef2f2750":"request_payout_users()","ef2f92ad":"forfeitShares(uint256)","ef2fa169":"setServiceFee(address,uint256)","ef2fd54d":"viewVotes()","ef303553":"athleteCanClaimPercent()","ef3088d1":"AirDropRedeemAFTK2()","ef31bfd1":"isValidSignatureAndMethod(address,address,bytes)","ef3229db":"addTokenFunds()","ef323d85":"getPlotPrice()","ef326c6d":"isOps(address)","ef3336f5":"paymentsByBenefactor(address)","ef3377ca":"devWalletLocked()","ef338b88":"seekOdd(uint256,uint256)","ef339fc4":"getTokenProxyAddress()","ef33f8f0":"bet1000_001eth()","ef343588":"trade(uint256[8],address[4],uint8[2],bytes32[4])","ef34ded2":"lottoLength()","ef35b59d":"_withdrawTokensToWallet()","ef35cdbb":"getLLV_edit_30()","ef35d902":"preIcoEnds()","ef35fc16":"HIGH_RANGE_RATE()","ef3613c3":"allEth()","ef36a883":"termsAndConditionsAreSigned(address,uint8,bytes32,bytes32)","ef36fa39":"fpart(int256)","ef37052d":"isArrAccountIsNotFrozen(address)","ef37cfe9":"getBetsCountAndValue()","ef37f061":"IPOcoinHotelShares()","ef387a50":"rateIco()","ef38a306":"genWallet()","ef38d089":"UpdateSellAgent(address,address)","ef394e1b":"getFastest(uint16,uint8,uint8)","ef39fe35":"updateSaleStageManually(uint256)","ef3a6031":"testBaseToken()","ef3aaf54":"setHouseAddress(address)","ef3adfb3":"XPAAssets()","ef3b70bc":"setMultiRequestRegistrar(uint256,address)","ef3bec3d":"endow(address,uint256)","ef3c0531":"contentHostById(bytes32)","ef3c64a8":"IcoTokenMock()","ef3cbc39":"minOrderEthAmount_()","ef3cdb2f":"upgradeM5Token(address)","ef3d622b":"EOSBetBankroll(address,address)","ef3e8869":"claimStarter(string,uint256)","ef3f7c55":"TokenSold(uint256,string,uint256,uint256,address,address)","ef406d01":"TokenEBU(uint256,string,string)","ef4080bd":"init_pre_ico(address)","ef40c3e6":"tokenSwapLock()","ef416aec":"firstMonthEnd()","ef41e06f":"testThrowSetEnforceRevisionsNotOwner()","ef41ea7e":"feePerc()","ef41f95a":"newProposal(string,address,uint256,address,uint256,bytes)","ef427776":"internalCalculateBonus(uint256,uint256,uint256)","ef42b5da":"withdrawFunds(address[])","ef430aa6":"category()","ef431437":"lastDayPaid()","ef43a2b8":"ChangeEmissionRateCoefficient(uint256)","ef449888":"allowsNewGames()","ef4592fb":"getResult(bytes)","ef464e19":"internalRelease(uint256)","ef46e0ca":"executeOrder(uint256,uint256)","ef474056":"changeOpenString(string)","ef47492b":"summFoundersShare()","ef4787a1":"getIsLimited()","ef47ff4b":"balance(uint8)","ef4886ef":"retrieveVanityForWallet(address,address)","ef48eee6":"pay(uint256,uint256)","ef49567e":"E_Bid(address,uint256)","ef49b414":"isGladiatorChest(uint256)","ef4a0c61":"ico_starting_supply()","ef4b31d8":"proxySetup()","ef4b6831":"callModifiedDeposit(uint256)","ef4b91c0":"ProxySender(address)","ef4ba598":"offerPriceEth(uint256)","ef4bdfdd":"Set_your_game_number_between_1_15(string)","ef4c8685":"LogNewWallet(address)","ef4d6149":"investedAmoun(address)","ef4e679b":"totalNtsSold()","ef4ec047":"addFounder(address)","ef4ef103":"bankrollExternalUpdateTokens(uint256,uint256)","ef4f0c5f":"changeExtraBets(uint256)","ef4f6e9c":"calcUnMaskedEarnings(uint256,uint256)","ef4fac01":"calcTotalTokens(uint256,uint256)","ef4ffee2":"Honestgamble()","ef5121b3":"appreciationRateWei()","ef520aba":"getall_horsesCount()","ef52ad21":"MintMade(uint256,uint256,uint256)","ef52b0dc":"RuneToken()","ef532a47":"addBagAndGift(uint256,address)","ef538593":"NeptaToken()","ef54801b":"getGrantBeneficiaries()","ef548aaf":"PLAYER_TURN_SINGLE_PERIOD()","ef54af8b":"TieToken(address)","ef551b38":"PaymentAddress(address,bytes4)","ef556029":"testFallbackIsCalledOnTransfer()","ef5793c2":"LOG_OwnerWithdraw(address,uint256)","ef57cbec":"BARToken()","ef5850c7":"stakersForPoll(bytes32)","ef589693":"getSMPTokensBoughtInICO()","ef599ba5":"getCoinBalance(bytes4,bytes32)","ef59f8c8":"setRaffleAddress(address,address)","ef5a3a88":"dividendsIndex()","ef5a625b":"disqualify(address)","ef5a80af":"ProductAdded(address,address,address,string,bool)","ef5a8fb5":"sellLand()","ef5ba9ed":"ALLOC_AIRDROP()","ef5c2010":"SelfPayPreSale(uint256,uint256,uint256,uint256,uint256,address,address)","ef5d5331":"isHashValid(bytes32)","ef5daf01":"_dumpToCompany()","ef5f937c":"OpportyToken()","ef5fad95":"DaWeiToken(uint256,string,string)","ef5fb05b":"sayHello()","ef5fbdb2":"stopPlaying()","ef5fd51b":"getKeys(uint32,int256)","ef61041c":"_approveAllArgs(address,uint256,address)","ef616584":"getPurchaseETHNum()","ef6506db":"credit(address,uint256)","ef660169":"withdrawRest()","ef660ab8":"deliverCandidate(uint256,uint256)","ef674e66":"isWhiteListed()","ef67caa0":"reservedTokensFounders()","ef685294":"addCascade(address,uint256)","ef688df5":"addFundraiser(address)","ef68913c":"dronesDeployed()","ef69f408":"protectedTransfer(address,address,uint256)","ef69f7d9":"ManagerRemoved(address)","ef6a676d":"allowTransferToken()","ef6a6bcc":"LogAddressCapExceeded(address,uint256,string)","ef6a88de":"AbstractQuintessenceToken(uint256,uint256)","ef6ac0f0":"run(bytes32)","ef6b141a":"setStarted(bool)","ef6b329a":"close_down()","ef6c4b93":"addLimitAddress(address)","ef6d1cc8":"QZToken(string,string,uint8,uint256)","ef6d7b3b":"emitCancelled(address,uint256,uint256)","ef6da43c":"setIsWeiAccepted(bool,uint256)","ef6f1f36":"setData_25(string)","ef6f8e92":"Creative()","ef6face6":"privateContribution()","ef706adf":"cancelOffer(uint256)","ef70aebf":"endMinting()","ef71a1f2":"BCREWARDS(uint256,string,string)","ef7293d7":"SELLER_STEP_4_ACCEPT(bytes32)","ef739d0f":"changeCountry(uint256,bytes2)","ef7507c8":"testWinner(uint256)","ef765af8":"erc20ApproveChecking()","ef76c060":"HPQToken(address)","ef778d30":"createProject(address,string,string,bytes32)","ef77b601":"SHAREFIDENCE()","ef77ed99":"isFundingState()","ef78a5b2":"singleUserSignUp(address,address)","ef78d4fd":"period()","ef79a35f":"getNumberOfLocks(address)","ef7a4a32":"logoId()","ef7a5956":"BRONZE_AMOUNT_SKL()","ef7a5a2a":"getIudexScoreAll(address,bytes32)","ef7ac0e5":"enableTransfer(bool)","ef7c7797":"getSaleContractDepositAddressVerified(address)","ef7c9ecd":"preIcoTotalSupply()","ef7d47a5":"setMinBlockPurchaseInOneGo(uint256)","ef7dbc54":"listCompetitors()","ef7dd831":"SUPPLY_FOR_ADVISORSL()","ef7e1e89":"pow()","ef7f23a6":"numberOfBlocksBetweenSupplies()","ef7f2e1c":"addHashrate(address,uint256)","ef7f3834":"grantInitialAuthentication(address)","ef80027e":"Members_info(address)","ef802e62":"tokensRemainingStage2()","ef804ead":"testInequalityBytes()","ef80c53a":"earlyReserveBeginTime()","ef80f1ab":"LitmusCrowdsale()","ef80ff18":"tokenExchangeAddress()","ef816fd9":"isState(uint256,uint8)","ef817f2a":"EtherZaarFactory()","ef81eb57":"removeLastSaleOnlyNotActivated()","ef82c8a8":"geProposalCount()","ef82f95c":"setFront(address)","ef8322fd":"queryRoles(address)","ef84e27f":"getWorkpointSupportCancel()","ef8594be":"setPriceStep6(uint256)","ef85fdad":"IRC_PER_ETH_SALE()","ef869443":"investWithCustomerId(address,uint128)","ef8700e5":"tokensForDevelopment()","ef885772":"GCCERC20(uint256,string,string)","ef890cc8":"isGameFinished()","ef898355":"revealHiddenPosition(uint32,int64[2],bytes16)","ef89d6e3":"getArmorValue(uint256)","ef8a22ac":"mineableTokens()","ef8a9235":"currentStatus()","ef8a9c8f":"allocatedStage()","ef8b0e15":"processContribution(address,uint256,uint256)","ef8c1d86":"ownerWithdrawParsecs(uint256)","ef8c2c58":"openModifyCountdown()","ef8c8944":"setPlayerId(uint256)","ef8d4a49":"getAssetIDForTypeSequenceID(uint256,uint256)","ef8dcc2e":"LogTransactionConfirmed(bytes32,address,uint256)","ef8dd09b":"deleteEntry(bytes32)","ef8e8069":"smallPrice()","ef8ea3d0":"NewRegistration(uint256,address)","ef8f1229":"EMISSION_FOR_SALESTAGE3()","ef8fdfd8":"Bonus()","ef902a0c":"ShowBool(bool)","ef9089d6":"nextPrice()","ef90aa46":"givenBountyTokens()","ef9124e1":"TrinityToken()","ef9130b9":"getBetItemCount()","ef921826":"setMaxDuration(uint32)","ef922305":"DACCToken()","ef92742e":"ICOmint()","ef92b384":"saveGenCode(address,uint256)","ef940837":"payday(uint256,address,uint256)","ef941dca":"issueTokens(uint256,string)","ef943909":"PublisherAddress()","ef94ce1e":"addMenu(string)","ef9521ea":"GruffinzContact()","ef95aa5d":"getManifest(address,bytes32,uint256)","ef961367":"registerForCompetition(address,uint8,bytes32,bytes32)","ef982eba":"settournamentPrizeAddress(address)","ef984923":"transferTenuousTokenOwnership(address)","ef98dea3":"getAuctionManagerAddress()","ef99c9ef":"DACVest()","ef9b0214":"read_i32_array()","ef9b559a":"CLX()","ef9bfe1a":"returnInvestors()","ef9c3512":"falconmasterReq()","ef9c4446":"cancelProposeTo()","ef9c52ea":"maxIco()","ef9c79da":"getFileNum()","ef9cb474":"changeWorkerPoolPolicy(uint256,uint256,uint256,uint256)","ef9da13d":"getPeriodOwnerLockedBalance(uint256)","ef9e7f95":"self_readyTime()","ef9f6023":"PUBLICSALE_SUPPLY()","ef9fc1de":"DelegateChanged(address,address)","ef9fc50b":"addNumbers(uint256,uint256)","ef9fe3ac":"setCompte_8(string)","efa08854":"companyShare()","efa0a1ef":"SettankImposedMax(uint256)","efa0e659":"EthX()","efa1c34c":"destroyChannel(address)","efa227ca":"finish(uint16)","efa25196":"getDevidends()","efa390f6":"createNewEvent(bytes32,string,uint256,uint256,string,string)","efa3d586":"add(address,uint8,uint256)","efa3dccd":"totalDividendsPerCoin()","efa408de":"setReservedTokensListMultiple(address[],uint256[],uint256[],uint256[],bool[])","efa40c2a":"engine(string,string,address)","efa4f94d":"computeDeadline()","efa52fb3":"iterateGet(uint256)","efa56a1e":"use_OEM_Parts(bytes32,uint256,uint256)","efa6fd63":"perTransactionRate()","efa726e8":"setEggLimit(uint16,uint16)","efa74f1f":"getTokenBySymbol(string)","efa7e56b":"GameEnds()","efa85335":"Registrar_Oraculo(address)","efa8d998":"GetEtherSpent(address)","efa94e47":"createToken(bytes32,string,string)","efa99ecf":"SubModuleSuspended(uint256)","efaa55a0":"joinGame(uint256)","efaa86b1":"claimTeamTokens(address)","efab1e50":"getInvestorDetails(address)","efab4b91":"_unpackIntelligenceValue(uint256)","efabaa89":"sortTrusted()","efac0fd0":"PowerEvent(address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address[],uint256[])","efac4db4":"add(address[],uint256)","efacd73b":"_createRocHunting(uint256,uint256)","efad6df3":"cycleLimit()","efada80b":"getRunDetails(uint256)","efada94b":"setParentPayoutDistributionHash(bytes32)","efae0f2f":"AIR_1()","efaf8e22":"isSenderRegisteredAgent(address)","efaf90c8":"DAYS_31()","efb0cdd9":"MeTooToken()","efb109d4":"privlocatum(string,string,uint8,uint256)","efb173d4":"addCompany(uint256,string)","efb1900d":"deleteThisContract()","efb20f6a":"Worldcoin1()","efb23d73":"getFirstHexByte(bytes1)","efb2bfd3":"signatureChecker()","efb369c7":"transferFundsByOwner(address,address)","efb588e4":"presaleMaxValue()","efb610bc":"isExternalBuyer(address)","efb7601d":"getExchangeRate(address)","efb7e8b3":"mistakenTokens()","efb7fa77":"unLinkFromMasterWallet(address,address)","efb8b6b1":"after10Seconds()","efb95ced":"masterRewardsPercent()","efb98bcf":"getRemainingTime()","efba9bd2":"recoverLeftovers()","efbb5f17":"retrait_2()","efbb6108":"transferStbToOwner(uint256)","efbbbd65":"getLambo(uint256)","efbbe160":"abiDecodeRegister(bytes)","efbc0075":"transferOwnerShipToPendingOwner()","efbc5469":"addTransaction(address,uint256,uint256)","efbcae98":"deleteMemberOfCommunity(address,uint256)","efbcebe5":"ObsToken()","efbd4bff":"priceForRect(uint256,uint256,uint256,uint256)","efbd863e":"setRealTokenPrice(int128)","efbd8a92":"setPriceFactor(uint256)","efbd9ec2":"changeList(address,bool)","efbe1c1c":"end()","efbe31d5":"removeHoldByAddressIndex(address,uint256)","efbe3894":"MakePatient()","efbe4262":"_removeSuperInvestor(address)","efbe584d":"isDEditor(bytes32,address)","efbe62e8":"validate(uint256,bytes)","efbe8fd1":"createToken(string,string,string,uint256)","efbec487":"payBoss(uint256)","efbee9b3":"_stake(address,bytes32,uint256)","efbf7d83":"GrowGuildToken()","efc018cc":"coupDetat(address)","efc0712c":"activateGladiator(address)","efc139cd":"SmartBooking()","efc1ba92":"FakeMembershipRegistry(address)","efc1c0ab":"SimpleNameRegistry()","efc2fd2a":"getRefillStatFor(string)","efc3323c":"createEvent(bytes16,bytes16[],bytes16[],uint256[])","efc3d252":"GetLuckyLandIds()","efc4cbdd":"Fiocoin()","efc4f1dc":"switchSaleState()","efc58aea":"spawnAsset(address,uint256,uint256,uint256)","efc5c693":"executeSell()","efc63bd3":"_rawGetGlobalDelegation(address)","efc65b3a":"CindicatorIssued()","efc7285c":"mintPresaleWithBlock(address,uint256,uint256,uint256,uint256)","efc7652e":"getBAU2(bytes32,address,uint256)","efc77f3f":"LTHToken()","efc78401":"isSenderAllowed(address)","efc81a8c":"create()","efc82381":"FirstTimeTransfer()","efc8d3c6":"amountReservedRefsTokens()","efc927b9":"ShowEmissionRate(uint256)","efca0214":"HotPotToken()","efca2eed":"totalDistributed()","efca9f09":"minimumPurchaseLimit()","efcb6cde":"changeOwner(bytes32,bytes32,bytes32,address,string,bytes32,bytes32)","efcc3c7f":"getMiniPoolEdit_3()","efcceaae":"getGamePaused()","efcd1cd9":"signatureSplit(bytes)","efcd2ddd":"changeOracleAdd(address)","efcd853f":"DogezerPreICOCrowdsale(address,address,address,address)","efce0688":"createPrometh(address)","efce079e":"doQuest(uint256)","efce1d66":"BitEyeEx(address)","efce6e78":"PinkyToken()","efce828e":"skinCreatedNum()","efcee869":"vote(bool,string)","efcefb40":"withdrawAllFor(address[])","efcf095c":"viewNumberOfMemories()","efcf2479":"trim(string,string)","efcf2730":"_premint(address,uint256)","efcf4f41":"getPixel(uint16)","efcf6d68":"finanReserveTimeLock()","efd0c851":"getPayoutReadyState()","efd0f455":"getChStatus()","efd12624":"startPostICO()","efd2abec":"calculateAntBuySimple(uint256)","efd2fb9b":"DeltaToken1()","efd46e1d":"E4RowEscrow()","efd4d0a6":"finishedloading()","efd6479a":"publicGetUserInfo(address)","efd64af9":"getReportingWindow()","efd71eb0":"updateVaultWallet(address)","efd7313d":"setExists(bytes32,bool)","efd73adc":"MigrationFund()","efd76499":"_cancelOrder(address,uint256)","efd8871a":"revoke(bytes32,address)","efd8c379":"userXRTBalance(address)","efd979cb":"setMinimumEtherToAccept(uint256)","efd9d7e0":"KoosAlbertsToken()","efdc4d01":"extraReceiversLength()","efdc5b77":"change_nodelist(address)","efdcb506":"getMsgGasBefore()","efdcc0f8":"getTeamTokens(uint256)","efdcd974":"setFeeReceiver(address)","efde6dcf":"Rejected()","efde9d6e":"InitChallengeAddress(address[10],address,uint256[10])","efdea046":"test_3_someTest()","efdecd9b":"check_withdrawdao()","efdee94f":"deployerAddress()","efdff7bb":"getContractAddressById(bytes32)","efe08a7d":"changeAddress(address,address)","efe0e495":"calculateVestedTokensNumber(uint256,uint256,uint256,uint256,uint256)","efe1525e":"viewFeaturedLength()","efe213a9":"_getCurrentPeriod()","efe2c8a4":"setConsumerAddress(address)","efe37d6f":"ELTTokenImpl()","efe3f4f4":"determineInterfaceImplementationStatus(address,bytes4)","efe43338":"determineWinner(uint256)","efe4e0a1":"iterateThroughSwarm(address,uint256,uint256)","efe51cca":"state2()","efe6bfa3":"sellOrders(bytes32)","efe6c772":"MAX_PLAYERS_PER_STAGE()","efe79268":"PRICE_STANDARD()","efe7a504":"END()","efe7c791":"RANGESTART_5()","efe86dd5":"batchPunchOut(address[],uint64[])","efe89d5a":"tokens2owners(address)","efe8c94f":"_safeSub(uint256,uint256)","efe93036":"getListTeamByPlayType(uint256)","efe998b9":"ethDividendAmount()","efe9b08d":"dissolve(address)","efe9e86b":"MyPinerTokenTest3()","efea0172":"startIco(bool)","efea835a":"devfeesoutstanding()","efeb4ad7":"onMoneySent()","efeb5e58":"beneficiaries(uint256)","efeb5f1f":"addWallet(address)","efeb941d":"ICOstart()","efebc720":"swapEndTime()","efecab8a":"addSale(address,uint256)","efed160f":"func_0431()","efed7b0a":"fondPlatform()","efedf429":"admin_member_isWithdraw(address,bool)","efeecb51":"getNumberOfTokens()","efef39a1":"purchase(uint256)","efef445b":"transferDataFrom(address,address,uint256,bytes)","eff02ec5":"returnBorroweedEth()","eff134ee":"withdrawTokenOwnerReward()","eff14c78":"submitValue(bytes8)","eff24744":"getTaskAddress(bytes32)","eff26a3b":"checkExist(address)","eff35f75":"setTickTime(uint256)","eff38f92":"getQuestion()","eff3c4e7":"openForPublic()","eff413ad":"setGoldMigrated(address,bool,string)","eff5c266":"addToMemeList(string)","eff60f56":"LRXCOIN()","eff631cf":"setNewPeriod(uint256)","eff6be2f":"changeBaseFee(uint256)","eff6e83d":"getIndexOrder(uint256)","eff7ed65":"setExchangeRateETHToUSD(uint256,uint256)","eff841d1":"setReserveWeight(uint256)","eff867e5":"CruzeiroToken()","eff877e2":"calcTokenPriceInWei()","eff883bd":"takerSellAsset(uint256)","eff8e748":"discountRate(address)","eff91c7e":"getLatestId()","effa00a6":"isIQTDistributed()","effb8415":"set_recivers(address,uint256)","effbbf92":"enableDisableTokenProxy()","effc4c1f":"throwIfLocked()","effcd413":"wallstreet2()","effd88b7":"ethToWei()","effda074":"addFactoryToCP(address,address)","effe031e":"payBankRoll()","efff1fb9":"_collect(address,uint32,uint32,uint32)","efff718d":"BITBIX()","efff78a5":"setRule(uint16,uint256,uint256,uint256,uint256)","effff82f":"valueToken()","f0004ab4":"PRIVATESALE_TOKENCAP()","f0006707":"setWriteTimestamp(bytes32,uint256)","f000999e":"upgrade(address,address,address)","f0024677":"deleteTellerMods(address)","f0032567":"computeFare(uint16)","f00388f7":"give(address,uint256)","f003a487":"unpauseCrowdsale(address)","f004073a":"performAction(uint256)","f00423ac":"XXXcoin()","f0044924":"BitGemPlayToken(address,address)","f004b12b":"CrowdFund(uint256,uint256,address)","f0061866":"deleteCourse(address)","f006228c":"guardian3()","f00648b8":"withdrawCoreTeamTokens()","f0072795":"itemsRange(uint256,uint256)","f007557f":"IPXTokenBase()","f0075829":"isValidPubKey(bytes)","f0083250":"canImplementInterfaceForAddress(address,bytes32)","f0086703":"setNextMilestone(uint256,uint256)","f008be46":"currentTierDiscountPercentage()","f009347d":"KudosProxy(address)","f00989a8":"FOUNDING_TEAM()","f00aac7f":"ArrayRR()","f00ac1da":"Login()","f00acc47":"prepareRoll(uint256,uint256)","f00c67fc":"Bounty0xEscrow()","f00c7669":"lastBlock_v2()","f00c9e67":"testStoresChallengeOwner()","f00d2823":"TokenMinted(uint256)","f00d4b5d":"changeOwner(address,address)","f00d7326":"isSenderInvestor(address,address[])","f00db260":"underwriter()","f00e4129":"EmergencyFundingReleaseApproved()","f00e6a2a":"getTarget()","f00e6f0a":"getResultData(uint8)","f00e8651":"createRequest(address[2],address,uint256[11],uint256,bytes)","f00f087f":"operationsPercent()","f00f7b33":"loseOdd()","f00f9b4d":"transferForMining(address)","f00ff174":"verifyWithdraw(bytes32,bytes32)","f0109f84":"valueAirDrop()","f010b6e5":"wipeBlackListedTrueUSD(address)","f011a7af":"claimProfit()","f011e270":"_payoutWinner(uint256,uint256,uint256,uint256)","f0123bc2":"dtStart()","f0137edf":"tokensFor1EthP3()","f013e0e1":"setWhitelist(address[],uint256[])","f0141d84":"getDecimals()","f0144a91":"dataset_md5checksum()","f0149751":"getTotal(bytes32)","f0149b9d":"ZenswapNetwork()","f01551f6":"difficultyAdjustmentPeriod()","f015bc93":"PRESALE_ADDRESS()","f0163621":"changeDomain(uint256,uint256,address)","f0163a82":"getNobleBalance()","f0173703":"ROLE_ORACLE()","f0174a25":"initMetadataDisable()","f018f741":"isPresidenteDeMesa(bytes32)","f019bd5e":"_generateOrder(address,address,address,uint256,string,string,string)","f019c267":"decreaseApproval(address,address,uint256)","f019c5da":"expReward()","f019c941":"SLAV()","f01b896f":"ambi2()","f01cc531":"setMonarchyRewards(uint256,uint256)","f01dbd03":"rewardAddressesSet()","f01de8c3":"getNextBattleTime(uint64)","f01e0648":"Voted(address,address,bool)","f01e341b":"addPostOnUser(address,address)","f01e66ec":"getAvgPrice()","f01eddda":"claimMyApis()","f01ee2cf":"sendERC20Tweet(uint256,string,string,string,string)","f01f20df":"burnPercentage()","f01fe692":"create(uint256,address)","f020044f":"gameActive()","f02011a8":"StatusContributionMock()","f0204007":"allocateTokens(uint256)","f0206a0d":"DayToken(string,string,uint256,uint8,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","f0207fb1":"_commission()","f020bfe1":"McCringleToken()","f020d093":"applyInsurance(bytes32)","f020f279":"balanceWinPoolForSecondStage()","f02137c8":"updateTicketPrice(uint256)","f02152ab":"sponsorOpinion(uint256,uint8,bool)","f02175c7":"checkNewOwnerArgs(uint256,uint256,uint256)","f0217c32":"changeSaleBlocks(uint256,uint256,uint256)","f0217ce5":"permit(bytes32,bytes32,bytes32)","f02286c1":"topUpLuck(uint256)","f022a694":"ToxbtcToken()","f022a867":"unholdMntp(address,uint256)","f022d9f6":"setContractProtection(bool)","f023d600":"purchase_address()","f0247f78":"maxQtyInFp()","f02694f6":"SetStartVesting(uint256)","f027c7e0":"initOptionProgram()","f027d1f0":"setC4FContractOwner(address,address)","f0285b96":"_ownerSupply()","f02895e4":"ICO_ADDRESS()","f0296bfa":"setRefBonus(uint256,uint256)","f029e102":"SandwichShop()","f02a306e":"timeoutXEnabled()","f02a4463":"SkyExchange()","f02d7ef0":"issued(address)","f02dd53f":"getLand(uint256)","f02e0b3c":"SALE_IN_PROGRESS()","f02f1b6f":"getDailyLotteryParticipants(uint256)","f02f3a89":"oem_share()","f02f85c5":"timeOfLastBlock()","f02fc78f":"batchRegularTransfers(bytes32[],bytes32[])","f02fff9d":"Fcoin()","f0303452":"approveAll(address,uint256[])","f0314df0":"addTrustedContract(address)","f031a4d2":"TasksHandler(address,uint256,uint256,uint256,uint256)","f0330d54":"claimTwitterBonus()","f03342ad":"initiatedBy(address)","f0342179":"setPriceUnits(uint256)","f0349d5f":"setupStages()","f0350c04":"transfer_ownership(address)","f03529c3":"setMasterFeeContract(address)","f0356a36":"balanceOfContractFeeEth()","f036417f":"setTokenSymbol(address,string)","f0366c45":"imageExists(uint256)","f0369550":"getStage0Cap()","f036b592":"getBonusFactor(uint256,uint256)","f036ed56":"addResources(address,address[],bytes4[])","f0375c55":"SudanGoldCoinToken()","f038a969":"createScanner(uint256,string,uint256,uint256,uint256)","f038e106":"CKAOTToken()","f039218a":"Robycoin_test1()","f039d9d5":"totalPicks()","f03a1bc6":"addBet(address,uint256)","f03a5687":"reinvestDividend()","f03a6872":"bitmask_add(address,uint256)","f03aa262":"noContributors()","f03b0c0b":"setMultiSigWallet(address)","f03b7c70":"addComment(string,address,bool,uint256)","f03b8bf5":"UoBAMZNToken()","f03bcc7f":"submitAudit(address,bytes32,bool)","f03c0e8f":"D3JDemo(uint256,string,uint8,string)","f03c58ca":"test_feePoolShare_isTranscoder()","f03c7c6e":"pit()","f03c867a":"ownerDisablePayee(address)","f03d43ed":"updateTokenTicketPrice(uint256)","f03d7d2f":"transferReferralFee(address,uint256)","f03dc3d3":"getUsedReveralSupply()","f03dc4e4":"private_setMinGamePlayAmount(uint256)","f03dc5ef":"publicKeys(bytes32)","f03dd010":"WithdrawalETH(uint256)","f03de5fe":"buyHLPMT()","f03e5de5":"isDisputeActive()","f03e786a":"approveAndCall(bytes,address,address,address,uint256,uint256,uint256,uint256,bytes)","f03fbf2f":"CheckChangePlatformFlagAndAddAccountsInfo(address,address,uint256)","f03fed22":"nwmToken()","f040d973":"ERC20Token(string,string,uint8,uint256,address,address)","f0413191":"badge(uint8,string,bytes)","f04182d8":"insertProposal(address,uint256,address)","f0419588":"reply(uint256,uint8)","f0425fe1":"swappedTokens()","f04303e3":"setSealableProperty(address,uint256,bytes32,bytes32)","f0437a36":"getMyCommitmentHash(uint256)","f0439e0f":"removeExpiredName(string)","f044632f":"loikikdid()","f0446e02":"testFailMintNoAuth(int256)","f0456691":"PrevOwner()","f0459440":"readPermissions(address,uint256)","f046395a":"subscriptions(address)","f04646fe":"roll(bytes)","f04686aa":"LogOrderCreated(address,address,address)","f046cdec":"private_setHouseEdge(uint256)","f0474350":"proposalWeight(uint256)","f0479392":"poolAdd(uint256)","f047a528":"isRoundingErrorCeil(uint256,uint256,uint256)","f047d077":"cancelBuyNowOffer(uint256)","f0485328":"setAccessory(uint8,address)","f04893c2":"modCFOAddress(address)","f048b97f":"userPurchaseNumMap(address)","f04961ba":"getEther(uint256)","f04991f0":"deposit(int256)","f04aa255":"_transferAvailable(address,address,address)","f04be582":"tokentBalance(address,address)","f04bf0c5":"updateTrustScoreInBulk(address[],uint256[],uint256[])","f04cb80c":"setInvestorDataAndIssueNewToken(address,uint256,uint256,uint256)","f04d4d55":"deactivateLineItem()","f04da65b":"getShares(address)","f04e2b45":"_init(address)","f04e42cd":"allocateCoins(address[],uint256[])","f04e7476":"BSBCoin()","f04e8c6f":"payoutPeriodStart()","f04ed952":"typeSize(uint256)","f0502ff7":"tokensRequiredForAllWins()","f05168e6":"getAddTokenResetSignatures()","f052a76b":"setSpecialOffer(uint256,uint256,uint256,uint256,uint256)","f052d65a":"getCreature(uint256)","f0534e0a":"addWalletBonus(address,string)","f05396ac":"currentOperation()","f05492e0":"_getMaker(bytes32,uint8,bytes32,bytes32)","f054d139":"decimalsFactor()","f055d324":"walletBountyProgram()","f0560ea0":"approvedRatio(uint256,uint256,uint256,uint256)","f056a5c7":"declareRF(string)","f0575008":"Locked(bytes32,bytes32,bytes32)","f05764a0":"Currenttask()","f05834d6":"setReservedTokensListMultiple(address[],uint256[],uint256[],uint256[])","f05854ba":"SealToken()","f0586f0d":"doThrow(bool)","f058e6d1":"TXOsale()","f0591308":"getMem()","f0594d38":"PrizeAwarded(uint256,address,uint256)","f059bb6d":"buyTokensPreHook(address,uint256)","f059cf2b":"spentToday()","f05a2818":"changeMinimumBetAmount(uint256)","f05a64bc":"potTime()","f05a781d":"acceptNewOwner()","f05aa334":"cofounderA()","f05ad9f3":"communityTotal()","f05b854f":"LogSquareWinsUpdated(uint256,uint256,uint256)","f05ccd75":"onDecreaseApproval(address,address,uint256)","f05d16f7":"setTxFee(uint256)","f05d5547":"named(string)","f05d68c1":"_newIncomingTransaction(address,address,uint256,string)","f05d85d6":"atmToken()","f05dd6d5":"LogWinner(address,uint256)","f05dda57":"XeinToken()","f05f3e77":"developer_voting_info(string)","f05f45b1":"authoriseEntrants(address[])","f05fae68":"getStoreBalance()","f06067ac":"transferByLock(address,uint256,uint256,uint256)","f060ccb5":"escFundAddress()","f060f617":"setCursedContract(address)","f0611c44":"lockAfterMinting(uint256,uint256)","f06186c7":"testReality()","f0624097":"checkBlockEmpty(uint256,uint256)","f062e26b":"check_darkdao()","f0640355":"AddTeamAccount(address,address)","f0646a3c":"DART()","f064b971":"tryToCloseProject()","f065c36e":"MonopolyBank(uint256,string,uint8,string,address)","f0664a4f":"ownerOne()","f0666fba":"burnedBitcoin(address,uint256)","f066719f":"arbTrade(address[],uint256[],uint8[],bytes32[])","f066844e":"_emitAreaEvaluated(address,address,uint8,uint256)","f066cb83":"treeBuild(address,address)","f0685bf0":"TestFund()","f068a3a6":"setNextSmartContract(address)","f068dc81":"authorizeRequestorAddress(address)","f069629c":"generalSaleStartDate()","f06a1e13":"QUOTE_ASSET()","f06b0901":"interRefreshLock()","f06b53e9":"saveDividends()","f06b9ca6":"avgTokenBetValue()","f06bbf75":"EXTERNAL_QUERY_GAS_LIMIT()","f06c5610":"constructionTime()","f06d335e":"_recoverAccount(address,address)","f06d56ae":"ICO3Period()","f06ea69c":"toUint16(bytes,bytes,uint256)","f06ebc38":"setKv(uint256,uint256)","f06ef632":"fundOrderInternal(address,address,uint256)","f06fc103":"sendTokens(address,uint256,uint256)","f0704f02":"week3Price()","f0705249":"updateSspAbi(string)","f07065b3":"writeToDiary(uint256,bool)","f0715594":"_addAdminAccount(uint256,address)","f071b5fb":"LogEscrowReq(uint256)","f071cacb":"_setClientSupply(address,uint256,uint256)","f071db5a":"feesCollected()","f071ecc5":"AFTER_MAX_GOAL_DURATION()","f07227dc":"release(address[],address,uint256[])","f07255e3":"nextBoundaryAmount()","f073b277":"euroRaisedRc()","f07494a0":"bla()","f0757a91":"TOKEN_PRICE_THOUSANDTH()","f075f253":"QRRial()","f07629f8":"eventsHistory()","f076ba9c":"ethercrowdfund()","f077ae0f":"removeSample(address,uint256)","f07819a3":"setMesa(uint256)","f0782640":"getCompanyCount()","f0793782":"modifyHorseyDna(uint256,bytes32)","f0794ca6":"getRocOwnerItem(uint256)","f07a019d":"ownerRecoverTokens(address,address)","f07b454c":"divMultiplier()","f07b4608":"destruirContrato()","f07b9a04":"certAuthIssuesCerticate(address,address,uint256,string,string,string,string,uint256)","f07b9f20":"MapleCoin()","f07c0b21":"AgriChainLabel()","f07c44c2":"appropriate(uint256)","f07d0c49":"Logs(address,uint256,string)","f07edbf4":"maximumAdminBalance()","f0803358":"TSpaceCoin()","f080f860":"MAYA()","f081d9bd":"HaraKiri()","f081fc2e":"MAX_TOTAL_AMOUNT_GET_ETH()","f082650b":"setStarData(uint256,uint16,uint16,uint32,uint32,uint32,uint64,uint64)","f0829c37":"VeraCoin()","f083156c":"LYBToken(string,uint8,string)","f083e8f2":"addressFundFounder()","f0843ba9":"quickConvert(address[],uint256,uint256)","f085b2a1":"clearTokenLock(address)","f0863c08":"maxPowerUserAddress()","f0869641":"normal_trade_date()","f086965e":"changeOwner(bytes32)","f08697a3":"QuyDau()","f0876747":"KocoCoin()","f087d2ec":"STREAMING()","f088d547":"buy(address)","f0893de2":"maxTradingStartTime()","f089b7dd":"hashtag()","f089d566":"AdmineTeamTokens()","f089e2ed":"getProject(string,uint256)","f089e972":"currentNetfRound()","f08a5faa":"getSmartHash(string)","f08b82e6":"getTotalTokens()","f08c9e2e":"deathData_f2()","f08ccd02":"allocatePresaleTokens(address,uint256,uint64,uint64,bool,bool)","f08d5a25":"initialLockedValues(address,address,address,address,address,address,address,address)","f08e362f":"transferFunds(uint256,address)","f08ea4cc":"_startContract(uint256)","f08fa322":"investors_deliveryDate(address)","f090cee8":"addInvestor()","f091e5a2":"CoinMeet()","f0920a41":"wminus(uint256,uint256)","f0921b80":"habichnet1()","f09304b5":"setIntervalSchedulePresale(uint256,uint256,uint256)","f0932bd7":"setNextRoundLength(uint256)","f0933ab9":"isInActiveStage()","f093fd0a":"_bidEth(uint256,uint256)","f0942d35":"gameStatus(bytes32)","f0947680":"lockstatus()","f095ed3c":"cancelAndEndEvent(bytes32)","f09649ed":"getStateLength()","f0965328":"transferFor(address,uint256)","f0970566":"createDklAuction(uint256,address,uint256)","f097e106":"maxBuyingDate()","f098efb3":"ICOActive()","f098f8e4":"finalWindowTime()","f09915d4":"assign(uint256,uint256)","f0995961":"notarize(bytes32,uint256)","f099ce67":"getGladiatorDistributedRandom(uint256)","f099fbbd":"callBurnTokens(uint256)","f09a1f87":"hashOrderTyped(uint8,address,uint256,uint256,uint256,uint256)","f09a4016":"init(address,address)","f09a58f8":"internalSellTokenFromAdmin(address,uint256,bool)","f09a9b3c":"addGoal()","f09bea14":"totalCities()","f09bfcc2":"distributeFixed(address[],uint256)","f09c25e6":"playerCheckProvablyFair(uint256,bytes)","f09c3152":"NerdShitCoin()","f09c5829":"swaps(uint256)","f09cac98":"receiveApproval(address,uint8)","f09d3103":"royaltyTracking(address)","f09dd7c6":"withdrawAffiliateCommision()","f09dd844":"revealPurchaseOrder(bytes32,uint256,uint256,bytes32,address)","f09e34f0":"addReleaseAgent(address)","f09e65f1":"setAtomFath(uint256,uint64)","f09ea2a6":"offer(uint256,address,uint256,address)","f09ecf10":"Contract_Owner()","f0a03aa3":"ITE()","f0a0a299":"VIPFee()","f0a15f10":"TIER2_RATE()","f0a233d4":"SharesChainToken(address)","f0a279ae":"phase1EndingAt()","f0a2bea2":"testCheckRokBalance()","f0a2c430":"inGameRewardAddress()","f0a32e7b":"maxRefundStageDuration()","f0a3563c":"userClaims(address)","f0a3ce5d":"distributeDivs(uint256,uint256)","f0a3d4fd":"freezeAPI(uint256,string)","f0a3dfa4":"isStartTimeCorrect(uint256,uint256[])","f0a42aa0":"_upgradeLevel(uint256,uint16,uint16,uint16,uint16,uint16,uint16,uint16)","f0a43714":"whitelistSize()","f0a45cff":"report_death(uint256,uint256)","f0a71ef6":"getPrevBlock(bytes)","f0a78538":"scheduleTransaction(uint256,bytes)","f0a7975f":"setDayQualitys(address)","f0aadcda":"AIMcoin()","f0aaf4ec":"getOptionsForModel(uint64)","f0abb382":"isHotWallet(address,address)","f0acc83a":"QCSCToken()","f0acfea2":"piranhasTotalSupply()","f0ad243e":"getCoefficient(bytes2,uint256)","f0adcedb":"executeWinningProposal()","f0adda7d":"setNextVersionAddress(address)","f0ae03be":"robotCoin()","f0af0844":"addTimeUnequalledDefence(address,uint256)","f0af50c9":"stoppedSale()","f0af7e65":"cancelAgon(uint64)","f0afbf84":"newFutureLottery(uint256,uint256,uint256)","f0afd95a":"_2_education()","f0b01d56":"VINEYARD_ADDRESS()","f0b05bfd":"getGamesOfPlayer(address)","f0b070ca":"createAppeal(uint256)","f0b087c5":"getConfigUint(bytes)","f0b0cfa3":"readSoftwareInformation(address,address,uint256)","f0b1adbe":"registerEarnings(uint256)","f0b1b42e":"createContractPow(string,uint256,uint256,uint256)","f0b24181":"totalSupplySale2()","f0b25186":"shopKnife()","f0b30f69":"saveLockedERC20Tokens(address,address,uint256)","f0b32c69":"test_threeValidEqBytes32()","f0b37c04":"unauthorize(address)","f0b3a7ba":"hardCapToken()","f0b3adee":"updateRewardRate(address,uint256)","f0b5165f":"delayOfPreICO()","f0b53256":"SoftCap()","f0b534cb":"getApprovedVotes()","f0b620a2":"isPaymentCompleted(address)","f0b6e707":"ORDER_CANCEL(address,address,uint256)","f0b7e532":"withdrawTaker(address,uint256)","f0b80000":"PRESALE_START_DATE()","f0b85b19":"setDefaultLockInDuration(uint256)","f0b9e5ba":"onERC721Received(address,uint256,bytes)","f0ba23e6":"minterChangeable()","f0ba958c":"Error(uint8)","f0ba96ff":"performPayouts()","f0bae2c5":"doIssueDividend()","f0bae787":"_receiveBuyRank(address,uint256)","f0bbab3b":"HSHToken()","f0bbe08b":"phasePublicSale2_To()","f0bbe877":"Deployed(address,uint256,string)","f0bc6cfb":"isReferred(address)","f0bc9cc5":"receivedDETreturn(address,uint256)","f0bcaf75":"UsingDB(address)","f0bd9ab5":"pushToken(address,bool)","f0bf1aea":"Paint(uint256,bytes3)","f0bf4df4":"setMinEnterFee(uint256)","f0bf611b":"transferDao(address)","f0bfd737":"Testtoken(uint256,string,string)","f0c001df":"proofType_Android()","f0c0546c":"closedRound()","f0c06aa5":"distrust(address)","f0c1d1c7":"setContributionPool(address)","f0c295fd":"seeZombieColor(uint256)","f0c388c7":"convertMainchain(string,string)","f0c413dd":"balanceOfContract(address,address,address)","f0c41bb2":"getChampsByOwner(address)","f0c45472":"modifiyEndFundingTime(uint256)","f0c4c04e":"extractFunds()","f0c4c339":"getFreezeSinceDetails()","f0c4fcc5":"mustToSellCourses()","f0c4fd0c":"isAttributesValid(uint256)","f0c5a46b":"periodPreITO_period()","f0c5a77b":"updateBurnableStatus(bool)","f0c69e8d":"calculateWithdrawable()","f0c71318":"zenOSCrowdsale()","f0c87852":"moveData(uint128[],address[],bool[],uint256[])","f0c95bc1":"setAdminVariables(uint256,uint256,uint256,uint256,uint256)","f0c99750":"endICOStage4()","f0ca618e":"Indemnisation_3()","f0caea2b":"SmartRoulette()","f0cafe0e":"tokenGNO()","f0cb556c":"updateLatestRevision(bytes32,bytes)","f0cb740a":"isJobStart(bytes)","f0cb8e77":"savedAddresses(address)","f0cbe059":"proxyTransferFromWithReference(address,address,uint256,bytes32,string)","f0ccc21a":"chunk5IsAdded()","f0cd58b7":"AuthAddr(address)","f0cd5c17":"cancelTx()","f0cd8057":"OACC()","f0ce6231":"XIAOZHI4()","f0cecafc":"privateSale2Hardcap()","f0cf198a":"RemoveSubscriber(address)","f0cfcaa8":"_getNewEstateId()","f0d02ce9":"AVG_BLOCKS_02W()","f0d07014":"allItemsForSale()","f0d0dd3f":"subDomainOwner(string,string)","f0d1c8ce":"hasTrade()","f0d1d021":"set_stoptransfer(bool)","f0d1eaaf":"getChannelById(bytes32)","f0d22ade":"isRepeated(int256)","f0d30786":"getPositionCallTimeLimit(bytes32)","f0d3a9df":"getBuyersCount()","f0d474f9":"underdogCount()","f0d4753e":"TOKEN_OFFERING_ALLOWANCE()","f0d4c92d":"setTimeBonus(uint256)","f0d4d1a6":"lotteryParticipants()","f0d504eb":"lookupKitty(uint256)","f0d5511c":"isArrAccountIsFrozenByDate(address)","f0d655f8":"_calculateTokenAmountAndRemainderBudget(uint256)","f0d6cc70":"endFullBonusTime()","f0d6ff48":"MeetOneTokenBase()","f0d7c9ff":"setPreviousSurplus(address[],uint256[])","f0d7f3eb":"auctionPause()","f0d85c89":"setRecovery(address)","f0d89e67":"LogRedeemTicket(uint256,address,string)","f0d8d4af":"sendTest()","f0d8e968":"getLastLease(uint8)","f0d90937":"usdAmount()","f0d97469":"setTokenExchange(address)","f0d9bb20":"yesToken()","f0da84f8":"getTransferable(bytes32)","f0daa286":"doubleXY(uint256,uint256)","f0daba01":"merchantIdHash()","f0dc4171":"collectTokens(address[],uint256[])","f0dd7a5d":"borrowBook(uint256,address,address)","f0dda65c":"mintTokens(address,uint256)","f0ddc0c6":"InjurymapCoin()","f0df232f":"buyMessage()","f0df6929":"RequireHuman()","f0e02bd6":"WEI_MAXIMUM_EARLYPURCHASE()","f0e10c0d":"play(address,uint256)","f0e1354c":"removeFromEggPhase(uint256)","f0e1691a":"addEvent(string,uint256)","f0e1ba2c":"priceLimit()","f0e1f84d":"setVotingProxy(uint32,int256,address)","f0e231b5":"Datenow()","f0e26f80":"getBattleDetails(uint256)","f0e3d1ba":"setEnd(bool)","f0e3fff8":"totalWon(address)","f0e40662":"getTotalAmount(uint256)","f0e42a1f":"getDividendTransactionLeft()","f0e4c4fe":"setGatewayI(address)","f0e53489":"integrity()","f0e5eeac":"ico2total()","f0e61771":"tokenFreezing(address,bool)","f0e6c2dc":"CASToken()","f0e769dc":"resumeSwap()","f0e7cf13":"adminClaimAirdropMultiple(address[])","f0e86f93":"ICOBlacklisted(address)","f0e959f9":"TokenSales(address)","f0ea0294":"setStage2Start(uint256)","f0ea433a":"sendQualifiedPartnerCommissionFee(address,uint256)","f0ea4bfc":"raised()","f0eb29fb":"_communitySupply()","f0eb737a":"getCurrentDiscount()","f0ebce5a":"getEnum()","f0ec03ae":"tokenWeiSold()","f0ec747e":"VETRA()","f0ec94cf":"edgePerPosition()","f0ecadaf":"comprueba(address,bytes32)","f0ecadcc":"voteSvp03(bool)","f0ed029e":"DebugUint(uint256)","f0ed14e0":"right95(uint256)","f0edb7cf":"admin_set_Apply_Store_Id_Fee(address)","f0ee7df2":"setMaxWin(uint256)","f0ef7621":"FishOne()","f0f0fe10":"ownerSetRecommendProportion(uint256)","f0f21344":"right27(uint256)","f0f2805f":"isOnSale(uint256)","f0f3f2c8":"getProject(uint256)","f0f44260":"setTreasury(address)","f0f46302":"shopHelmet()","f0f53ee4":"setBool(bytes32,bytes32,bool)","f0f5af8b":"calculateObtainedAMIS(uint256)","f0f7bd31":"LibertyToken()","f0f87e98":"TokenWithoutStart(string,string,uint8)","f0f8aff9":"getPriceForAssetAmountMulCollatRatio(address,uint256)","f0f8b7a5":"betX5()","f0f967e8":"canCall(address,address,bytes)","f0f9a729":"dividendsOf()","f0fa55a9":"setSlippage(uint256)","f0fb4372":"RatingStore(address,address)","f0fb8efd":"allowDefaultToken(address,bool)","f0fbc8ac":"indInflationDeposit()","f0fbe2e4":"addressAirdrop()","f0fbfd3a":"targetDiscountValue5()","f0fc1438":"tradeComplete(address,uint256,address,uint256,address,address,uint256,uint256)","f0fc6bca":"claimDividend()","f0fcc6bb":"pay(address,uint256,address)","f0fdb32f":"canStartWork()","f0fdc689":"setInv2(address)","f0fdf834":"a(uint256)","f0fe3d68":"metaBurnCarbonDollar(address,uint256,bytes,uint256,uint256)","f0fee1f7":"LogMigrate(address,address,uint256)","f0feef96":"closeChannel(bytes,uint256,uint8,bytes32,bytes32)","f0ff4840":"LuckchemyCrowdsale(address)","f0ff6ac4":"withdrawal(uint256,address,uint128)","f1001f8c":"getTotalLockedBalance(address)","f10143e1":"TokenToppedUp(address,uint256,uint256)","f101618a":"getMiniPoolEdit_8()","f1018c6f":"boughtNum()","f101b269":"appstore_share()","f103b433":"updateMaxSupply(uint256)","f104c836":"setAssetTransferGas(address,uint256)","f1052af5":"isRegisteredContract(address)","f105c981":"get_contrib_arbits_min()","f105e23b":"PVE_COMPENSATION()","f1068454":"pid()","f10700c2":"shouldCompleteDay()","f1076703":"getVerificationId(address,bytes,bytes)","f107941b":"buyTest(address,uint256)","f107b5e7":"getMaximumLimit()","f108a7d2":"withdraw(uint256,address,string)","f109517c":"delegatedTxHashesUsed(bytes32)","f10968ea":"assertEq(bool,bool,bytes32)","f10a4f0a":"WALLET_PARTNER()","f10a7798":"setAuth(address,address)","f10a9848":"currentNumberOfUpgrades()","f10ae2ab":"__dig_then_proxy(uint256,address,bytes)","f10ca95a":"close(bytes32,bytes32)","f10cb3da":"ObjectToken(uint256,string,uint8,string)","f10cb5dc":"DomainChanged(address,uint256,uint256)","f10ce7c4":"registration(address,string)","f10d1de1":"setUnbondingPeriod(uint64)","f10e5ceb":"getNumAdd(uint8)","f10ecc65":"chainlinkToken()","f10fae62":"setLLV_edit_21(string)","f10fdf5c":"getContribution()","f11079cf":"createType(address)","f110bbdf":"SetupAccounts()","f1112e70":"payYearlyJackpot(address)","f1115c7e":"transferMSI(address,uint256)","f112ddc0":"GJMI()","f113c854":"icoThresholdBonus1()","f113f700":"advisoryReserveTokens()","f113fccd":"trueGods()","f1144ce0":"HCoinToken()","f1145727":"buyStarterPack()","f1147bae":"withdrawRoyalty()","f1156cdf":"getCurrentVoting()","f115f06a":"WhiteListSet(address,bool)","f1160dc2":"ParticipantAuthority(string,address)","f116260f":"CryptoTreasure()","f1167e0d":"createPlayerIfNeeded(address)","f1168e11":"_createMobster(string,address,uint256,uint256,uint256,string)","f1173928":"RemovedFromGeneration(address,uint256)","f11745df":"totalHolder()","f117c924":"totalInvestedInWei()","f1183e21":"assertEq0(bytes,bytes,bytes32)","f118e465":"LogCreateVIBEX(address,uint256)","f118f7d6":"setDestinationMultisigWallet(address)","f119a48d":"toUnixtime(uint32,uint8,uint8,uint8,uint8,uint8)","f119ada4":"addTeam(string)","f119fcaa":"isMintableNFT()","f11a8911":"accountTxs(uint256)","f11a97ef":"MinerToken()","f11af32a":"EuroToken()","f11b9b46":"FRPTOKEN()","f11b9fc8":"emitTokens(address,uint256)","f11bdfa4":"_isValidHeight(uint8)","f11be7c1":"getTrustedContracts()","f11c2cec":"changeOwner(address,address,address)","f11c4482":"approveFromProxy(address,address,uint256)","f11c46f4":"How_to_interact_with_Smartcontract()","f11c8de8":"ZENT()","f11cfc56":"Vicky()","f11d5039":"place_holder()","f11d5b33":"reward(address,bytes32,uint256)","f11dd6ac":"viewGiveKarmaFee()","f11eb099":"preIcoAllocation()","f11ef5cf":"reserve(uint8)","f11f7d2d":"maximumBidAllowed()","f12001ae":"Testereumx()","f1204db6":"maximumJackpot()","f1208af8":"drawWeeklyWinner()","f120974e":"CHENDE()","f1215d25":"deposit(uint256,string)","f122ed60":"send_message(address,string)","f1233b79":"updateTimeBetweenGames(uint256)","f12479ac":"getPhase(uint8)","f124a300":"setPayable(bool)","f124eab5":"ETD()","f125561d":"notifyReceiver(address,address,uint256,bytes)","f12585f5":"getStageVolumeBoundaries(uint256)","f12611f1":"XID(address)","f1261fce":"permitTransfers()","f1272f35":"ICOBlaster()","f127328a":"totalTokenCollected()","f12782b2":"EPXAirDrop()","f127e53c":"LunchMoney()","f1280c23":"getCCH_edit_32()","f1287aef":"Ethmoji()","f129c5d7":"getGeneScienceAddress()","f12a1580":"withdrawDevReward()","f12a15b1":"heapify(int128[])","f12acca2":"upgradePonyHashing(uint256,uint256)","f12b3d3c":"SentFeeToPlatform(uint256)","f12b60f2":"TEAM_POOL_INIT()","f12c095b":"developer_string_A(string)","f12c87eb":"planetIndexToOwner(uint256)","f12d15c3":"transwerFunds(uint256)","f12d394f":"execute(uint8[],bytes32[],bytes32[],address,uint256,bytes)","f12ddd2b":"sendTokensToOwner(uint256)","f12e5eaa":"withdrawPartial(bytes32,address,uint256)","f12f5409":"accrueInvestorsTokens(address,address,uint256)","f12f6925":"NokuFlatPlan(uint256,uint256,address,address)","f13016d5":"internalPresale(address,uint256)","f1309dc0":"transferTokens(address,uint256,uint256,uint256)","f130da53":"GreenXToken()","f13101e9":"_delegate(address)","f1311a2e":"pgoMonthlyInternalVault()","f1317352":"setVCX(address,address,uint256)","f1317c09":"halt_purchases()","f1319892":"CoinifinexToken()","f131a7ae":"clearGame()","f1320af2":"exempt(address)","f13375bd":"addApprovedWalletAddress(address)","f13397b4":"EmeraldToken(string,string,uint256)","f133a7c6":"_update(uint256,uint256)","f133c38c":"testIntParserOneDecimal()","f1348138":"DoAirDrop(address,uint256)","f13497d6":"notifyCollateralNotTransfered(uint256)","f1349955":"externalTxs(uint256,bytes32)","f136a874":"approvedAddresses(address)","f137005f":"EOCHToken()","f13707b3":"adminGetPlayer(uint256)","f1378efa":"QuanYToken()","f137c236":"DSNCOIN()","f137d1a3":"getVestedAmount(uint256,uint256)","f13837f6":"ALPToken()","f1388f14":"mtrx()","f138fca5":"resetKoth()","f1395f3f":"tokensForDevteam()","f1398db1":"MbbToken()","f13a38a6":"getConstant()","f13ab647":"doMakerPayment(address)","f13ad3bf":"RemoveAllHeaders()","f13b68e8":"getPurchaseableMode(uint256)","f13b8d66":"removePerformer(address)","f13ba6a9":"_calcPhase()","f13c310c":"_createPlayer(string,uint256)","f13c7f57":"returnAllBalance()","f13c8fef":"weiTokensRaised()","f13c9b2b":"gcFundAmount()","f13ca4b8":"setEtherAmount()","f13cc606":"buyNOS(uint256)","f13d111f":"reverse(uint8[])","f13d22c1":"getModuleByName(string)","f13dc2e2":"watermark()","f13fc23b":"FINX()","f14053ad":"minVal()","f140b8ea":"getSentTransfer(uint256)","f141d076":"DURATION_DECREASE_PER_ETHER()","f14210a6":"withdrawETH(uint256)","f1437bd0":"setFrom(address)","f143e6db":"clearRequest(uint256)","f143ffe9":"ProfToken()","f14467fb":"ViewMyPrivateKeys(string)","f1448e10":"requestExecution(bytes)","f1455328":"CappedCrowdsale(uint256,uint256)","f145761c":"StartedGame(uint256,uint256)","f145cae9":"updateStoreFee(uint256)","f145ff23":"getDistributedTokens()","f1469382":"updateRates(uint256,uint256)","f147decc":"buscarAssinatura(string)","f147df3b":"get_king_address(address)","f1496070":"getAuctionArray(uint64,uint64)","f14ae17d":"isPresalePurchase(address)","f14b1c01":"upgradeFactory(uint256)","f14bd85d":"resignFromGroup()","f14be97f":"setTgeAddr(address)","f14ca7d7":"getVestingReleaseInterval(address,uint256)","f14ca885":"preICOcontributors()","f14d147f":"tokenSaleWeiMax()","f14dc176":"setDestructionCurator(address)","f14e96f1":"getBestBid(uint256)","f14eb30d":"SaleClockAuction()","f14f58f1":"removeAsset(uint256)","f14faf6f":"donate(uint256)","f14fcbc8":"commit(bytes32)","f14ff5cf":"getSeatMessageUrl(uint256)","f1508105":"Ohni(uint256,string,uint8,string)","f1518627":"anotherOwner()","f151e4ae":"devuelveToken()","f1522d53":"redeemablevilsinfo(address)","f1533936":"BNTPrice()","f153d3ad":"BurnupHoldingAccessControl()","f15467c4":"WelCoinICO(uint256,uint256,address,address)","f15627a1":"mintArray(address[],uint256[])","f156deb2":"miningTokensOf(address)","f1572e7d":"getQuoteKey()","f15732b8":"REAL()","f157c54b":"operatorRedeemByTranche(bytes32,address,uint256,bytes)","f157ea0b":"forkAddress()","f158458c":"getMinimumEndowment(uint256,uint256)","f15886db":"addressToReceiverToAllowedSprite(address,address,uint256)","f1588d66":"getPurchaseAmount(address,uint256)","f158e478":"destroyCampaign(bytes32)","f159eb84":"KVCToken()","f159f38f":"getTracks2()","f15a1b59":"tokenForTeam()","f15a691d":"validPurchase()","f15a9ae8":"maxPVPContenders()","f15ae568":"addEntry(address)","f15afa50":"fpMulI(int256,int256)","f15b2bda":"approveMintLocked(address,uint256)","f15beecf":"payNode(bytes32,uint32)","f15bf739":"getShareholderArrayLength()","f15caaa9":"insertDate(uint256)","f15cfe33":"KRWT_Token()","f15d775d":"changeMedianier(address)","f15e3af1":"getMatchAtRoundIdAtIndex(uint256,uint256)","f15f14c5":"Dividends()","f15f2bf0":"blockEndICO()","f15f56a7":"calcBingo()","f1608682":"updateUserDetailsInBulk(address[],uint256[],uint256[],uint256[],bool[])","f1610120":"next_giveaway()","f1625534":"deactivateRound(uint256)","f16270c3":"VITTokenSale(address,uint256,uint256,uint256,uint256,address[20])","f162c5a1":"totalScaleStaked()","f1637630":"withdrawBatch(bytes32[],address)","f1644b6c":"getFaucets()","f16638ec":"UselessReserveBank()","f1665a48":"NewVestedToken(address,address,uint256,uint256)","f166dc27":"Bid(address,string,uint256)","f1671b56":"getWeightRange()","f16787bc":"readFromCards(uint256,uint256)","f1679095":"getTransferAddressUser(address)","f167d695":"sacarDoacoes()","f1684237":"Ownable(address)","f1686296":"Hodor(string)","f1687a8d":"tokenSellCost()","f1694b3d":"updateResearch(address,uint256)","f16b6482":"gameCountdown(address)","f16b9422":"_recordFailedOldOwnerTransfer(address,uint256)","f16bdb9c":"validate(bytes20,uint96,uint32,bytes32[],uint16)","f16bdba9":"isCustomerinBLFromWL(address,address)","f16c5e8d":"issuerGuiveToken(address,uint256)","f16d9aca":"khabibToken()","f16dfbe9":"verifyAccount(address)","f16e74ac":"minDividendEtherAmount()","f16f9b53":"signedApproveAndCall(address,address,uint256,bytes,uint256,uint256,bytes,address)","f16fa66a":"updateLotteryData(address)","f16fa954":"debug_resizeRealPrefix(uint256,uint256)","f1700f94":"getInfoF1(address)","f1703d24":"addEntity(address)","f170c83c":"famedStarAddress()","f1714e97":"preserveTokens(address,uint256)","f1714fcc":"AddCommitteeToMapAndArrayEvent(address)","f171a730":"transferEvent_(address,uint256,bool)","f171ba5d":"verdictExecuted(address,bool)","f172f58f":"getPositionOwner(bytes32)","f172f84f":"jockeyLevel(address)","f17313e6":"unFrozenAddress(address)","f1736d86":"m_dailyLimit()","f17382ae":"SUPPLY_FOR_RESERVE()","f1739cae":"transferProxyOwnership(address)","f17401de":"init_multiowned(address[],uint256)","f17454b0":"UserAdded(bytes20)","f174683a":"VTrust()","f174b333":"buscarDocumentoPorId(uint256)","f1751688":"showReportForDevice(uint16)","f17520e5":"changeWhitelistAdmin(address)","f1753550":"supportsInterface(bytes32)","f175e6a9":"getTwitter()","f1762e5d":"bnbRefundEnabled()","f1765b22":"acceptSale(address[])","f1771cf0":"BURNABLE_UP_TO()","f177e837":"to62Encoding(uint256)","f177fc4f":"PornSceneToken()","f1781c72":"removeLockedTime(address,uint256)","f179a86e":"setEtherToTokenAllowed(bool)","f179c6ef":"confirmBatch(address[])","f179f9f1":"parsecCreditContract()","f17a1ff5":"BAG_TRANSFER_FEE()","f17a3c4b":"FTST()","f17b1d63":"BacCara()","f17b5bb0":"assertMatchingBalance(uint256,uint256)","f17b6d9b":"relayCMCT(address,uint256,bytes32)","f17ba16b":"approveByAddress(address,address,uint256)","f17cc54b":"TestLib()","f17ccd73":"DNMC()","f17d186c":"withdrawAllFundsFromContract()","f17e48ec":"adminTransfer(address,uint256)","f17f29d0":"getGoldDataSerial()","f17f3ca3":"AUCTION_WHEN_PERCENTAGE_LOGIC_STARTS()","f17f6f8a":"escapeCaller()","f1806a21":"getUnapprovedUsers()","f180743a":"tokensForFounder()","f1807e35":"removePermission(uint8)","f18166c2":"TRADE_REWARD()","f181b388":"setTotalWithdraw(uint256,address,uint256,bytes,bytes)","f181f396":"unspentAmounts(uint256)","f182dd3b":"releaseTokens4Sender(uint256)","f183452c":"releaseTokenByOwner(address)","f1835db7":"verify(bytes32,uint8,bytes32,bytes32)","f1838a15":"burnFeatureDeactivation()","f1838fe4":"getExpectedRates(address,address[],address[],uint256[])","f1850af8":"getTokenSymbol()","f1860118":"tradeExecuted(address,uint256)","f1861749":"nextDiscountTTMTokenId6()","f18697cf":"IdolCoin()","f186a625":"transferContentOwnership(bytes32,address,address,string)","f186bb79":"getPixelPrice(uint16,uint16)","f186c67f":"permit(address,bool)","f186d77e":"setStarContract(address)","f1870e0c":"contractFinalized()","f187650d":"DeskBellPresale()","f18771de":"NujaRegistry()","f1880128":"getSTMPDecimals()","f1880b24":"checkToken(address)","f189348a":"teleportCharacter(uint32)","f1895e08":"__issueTokens(address,uint256)","f1898fda":"TOKEN_CONTROLLER_INTERFACE()","f18ab544":"pendingList(address)","f18ad6fb":"getRecord()","f18b7bde":"SplitDividendsAmongstOwners(uint256)","f18ba98c":"handleSaleCompletionCallback(uint256)","f18cbe08":"_byteToString(bytes32)","f18d03cc":"transfer(address,address,address,uint256)","f18d20be":"adminWithdraw()","f18d4dbb":"addTokenSupply(uint256)","f18d5a93":"TokensSent(address,uint256)","f18dd512":"PERSONAL_FIRST_HOUR_CAP()","f18df6bb":"increaseAllowanceToken(address,uint256)","f18e120b":"setMaxTokensPerAccount(uint256)","f18ecf80":"OfferToken(uint256,string,string)","f190a793":"companyTokenWallet()","f190ac5f":"mintToAddresses(address[],uint256)","f190b4d3":"newUserRewardPool()","f1914dc5":"StaticEthAvailable(uint128,uint128)","f191c26d":"CPT()","f192866a":"sellTicket(uint256)","f192e91c":"forfeit(bytes32)","f1931b9e":"LAFIN()","f193a3f7":"changeBank(address,address)","f19414d5":"admin_inactive_dividend(address)","f194c23f":"_getCurrentAltarRecordId()","f1952473":"AcoraidaMonicaWantsToKnowTheNewQuestion(string)","f195995c":"isValidGeneration(uint8)","f195f0f9":"slice2(bytes,uint256,uint256)","f19674f6":"PatronThreeWithdrawal()","f19798ab":"numRolls()","f1979de8":"setPixelAreaColor(uint256,uint256,uint256,uint256,uint32[])","f197bbdd":"deadlineOne()","f1991a27":"saleStartTokenCreationRate()","f199265f":"internalExecuteCall(address,uint256,uint256,bytes)","f199f56d":"roundReward()","f19a5810":"changeBaseTokenPrice(uint256)","f19ab230":"Bcoin()","f19ac52d":"newDepositCommission(uint256)","f19be31b":"btcAddrPubKeyCompr(bytes32,bytes32)","f19be5d5":"JackpotCore(uint256,uint256,uint256,uint256)","f19c020d":"returnTokensAll(address)","f19c78b5":"contributorsKeys()","f19cfeff":"RepossessionBounty(address,uint256)","f19d2bcd":"EOS_address()","f19d736e":"Prosper()","f19dd75b":"lspToken()","f19e3c9f":"LogSnapshotCreated(uint256)","f19e75d4":"ownerMint(uint256)","f19e774e":"isValidBet(uint256)","f19eb731":"TKT_TokenERC20(uint256,string,string)","f19ee2a9":"_getAsset()","f19efc43":"getRoundInProgress()","f19f3246":"rejectOwnership()","f19fb157":"withdrawnow()","f19fc6ab":"gonIIToken()","f19fe69b":"withdrawTokenTo(address,address)","f19fefbc":"Hodling(address,address,uint256)","f1a00a53":"unregisterListening(address)","f1a0a85c":"div(uint64,uint64)","f1a138f4":"Airdropsamount()","f1a252b8":"getMoneyBack()","f1a3de09":"register_minting(address)","f1a5158b":"Contest()","f1a570b8":"DividendRecycled(uint256,address,uint256,uint256,uint256)","f1a5fc99":"bytesToInt(bytes)","f1a63733":"createBountyToken(address,uint256)","f1a6ed46":"ORIGIN_ETH_BRT_RATIO()","f1a9af89":"startPrice()","f1a9d749":"LRCCcoin(uint256,string,string)","f1aaea1c":"updateLabAddress(address)","f1ab36b4":"getSaleInformation()","f1ace1a1":"ART_DECIMALS()","f1ad3334":"storeETH()","f1ade50c":"VelesCoin()","f1ae5437":"changeTakeFee(uint256)","f1ae72a5":"minAcceptedEthAmount()","f1ae8c55":"startRaffle(uint256)","f1afc4f6":"ShareHolderController(address,address[],uint256[],address,uint256,uint256,uint256,uint256,uint256,uint256)","f1b0202e":"TalkToExpertPayment(address)","f1b07f96":"deblacklistAddress(address,address)","f1b12493":"IcoContract(address,address,uint256,uint256,uint256,uint256,uint256)","f1b234ad":"setWallet(address,address)","f1b2b03c":"start_ts()","f1b2d6a3":"getListings()","f1b3ea6f":"asyncDebit(address,uint256)","f1b3f968":"getRaceEndBlock()","f1b3fd80":"momentTimeOf(uint256,uint256)","f1b46bc8":"generateRandomCard(uint32)","f1b4d548":"isValidTeam(uint256[])","f1b50c1d":"enableTransfer()","f1b541c2":"startPublicSaleStage()","f1b5bc17":"mintAmount4()","f1b5c777":"contributeWasCalled()","f1b5d7de":"pre_prices(uint256)","f1b6315e":"StartRoulette(uint8)","f1b676a4":"ico3Ended()","f1b6cee5":"winPot(uint256[])","f1b74348":"addExisitingContributors(address[],address,uint256[])","f1b75173":"getLegacy(uint256)","f1b8a5bf":"commitPhaseMinVotes()","f1b9ee24":"setInactive()","f1bab09c":"setExtraBonus(uint256)","f1bab410":"manualSale(address,uint256)","f1bba50a":"GoldBlocksTickets()","f1bba6f9":"account(string)","f1bbc663":"tokenSaleClosedTime()","f1bca30f":"removeManyAdmins(address[])","f1bca7a4":"doCall(uint256)","f1bcb6e5":"createContractor(address,address,bool,address,string,string)","f1bd4c04":"getJackPot()","f1bd5978":"__address3__()","f1be1679":"getMarket()","f1be42f1":"numCharacters()","f1bf18db":"availableZNT()","f1bfb9cd":"listSingleCard()","f1c05831":"authoriseSale(uint256,uint256,address,uint256)","f1c10c24":"infoTokens(address)","f1c16deb":"validPurchase(address,uint256,uint256,uint256,uint256,uint256)","f1c21077":"PROBABILITY_DIVISOR()","f1c22a05":"setNewPixelPrice(uint256)","f1c30ec0":"reclaim(bytes)","f1c36ce0":"burnFromAddress(address)","f1c3dd3e":"fuckTest()","f1c41b68":"setConsensusRules(uint256[6])","f1c461c7":"mesasCreatedVerify()","f1c4d6b0":"DOG_Crowdsale()","f1c4ecb4":"maxCapWei()","f1c53a3a":"UpdateUserExtraData1(address,bytes32)","f1c55931":"reserveFunds(address)","f1c5d07b":"totalLoveBlocks()","f1c61958":"DIGITALCASH()","f1c6aeb7":"SetApplicant(string,uint32,uint256,int256,string)","f1c6c520":"runningauctions(uint256)","f1c760ae":"fixBalanceInternal(address)","f1c7689e":"CandyRate()","f1c94b45":"lastBlock_a7Hash_uint256()","f1c9cc11":"lockMin()","f1ca9410":"gen0CreatedCount()","f1cca8aa":"setTakerFee(uint256)","f1ce37d9":"eachUserWeight()","f1ce9595":"TIME_PERIOD_IN_SEC()","f1cea858":"TCLRToken(address,address,address,address,address,address)","f1cf5b38":"setWethContractAddress(address)","f1cfb100":"remainingEscrow(bytes32)","f1cff4b5":"testBitsNotSetSuccess()","f1d02a8c":"MiningToken(string,string)","f1d08bfa":"setOpenForSale(bool)","f1d15f1f":"setLandPrice(uint256,uint256)","f1d1768c":"updatePresaleListMapping(address[],address,bool)","f1d18a42":"safediv(uint256,uint256)","f1d20d4d":"provider(bool,address,address,address)","f1d2165f":"SaleActive()","f1d22be0":"freezeAll(address)","f1d2b3c2":"Owner1()","f1d2b8ab":"seePurchase(uint256)","f1d308d5":"SingularityTest17()","f1d35260":"setGovernor(uint8,address)","f1d3a853":"PalliumCrowdsale(uint256,address)","f1d588c5":"setRoleManager(address)","f1d59443":"getUSETTotalSupply()","f1d61850":"confirmationPeriodOver()","f1d61f23":"timeLockAdvisor(address)","f1d71b73":"betBlueCoin()","f1d73540":"Quiz(string,string)","f1d841f1":"minAcceptedAmount()","f1d89857":"RequestFactory(address,address)","f1d91942":"setInfoUrlPrefix(string)","f1da588a":"PrivateCoin()","f1da7e63":"getMortgageRate(address)","f1daa1f0":"writeDefinitions(uint256,string)","f1daa5ba":"calculateAmountForETH(uint256)","f1db23dc":"totalProceeds()","f1dbd547":"FINAL_AML_DAYS()","f1dbd647":"receiveDividends(uint256,uint256)","f1dc24ae":"getMeshPointByCreator()","f1dd08b4":"transferCommissionReceiver(address)","f1dd6147":"buyTokensIco(address)","f1de75e3":"getPrefixOwner(string)","f1dfcddb":"testTransferGasIssue()","f1dffed7":"setIntValue(int256)","f1e02620":"setFirstTime(uint256)","f1e03d67":"createEscrow(bytes16,address,address,uint256,uint16,uint32,uint32,uint8,bytes32,bytes32)","f1e253dd":"brickIds()","f1e298c3":"addFee(address,uint256,address,uint256)","f1e2ac12":"evalParam(bytes32,uint32,address,address,bytes32,uint256[])","f1e2e921":"_Owned()","f1e328f9":"left68(uint256)","f1e4a540":"unsetCoordinator()","f1e50ce9":"saveMe()","f1e69009":"registerDsp(address,uint8,bytes32[5])","f1e6bb1c":"getVoteOptions(uint256)","f1e6f4cd":"right40(uint256)","f1e7ae1f":"modifyMemberLimits(address,uint256,uint256)","f1e8ace7":"decodeBillingMetadata(uint256)","f1e954d8":"increaseTokenSaleAllocation()","f1e9951f":"getActionCount(bool,bool,bool)","f1e9a514":"VREO_SALE_PHASE_2_END_TIME()","f1ea43e7":"TCSCCoin()","f1ea6cbd":"creationMinCap()","f1ead3d6":"getAuctionsFor(address)","f1eae25c":"mortal()","f1eae64a":"openSell()","f1eb0ed9":"newInitialPlayerOffering(string,string,uint256,uint256,address,uint256,uint8)","f1ebe451":"ChooseB()","f1ecff08":"BastoneToken()","f1ed9923":"isEcoAllocated6()","f1eeec2e":"insureClient(address,uint64)","f1ef9881":"hashSecret()","f1ef9a08":"preicoAddresses(address)","f1efb76a":"getPayTo()","f1f05a3f":"getAttr(bytes32,uint256)","f1f0b290":"lockToken(bool)","f1f1e30f":"ethForKey(uint256)","f1f201e8":"getArtworkInfo(uint256)","f1f33565":"ENG()","f1f339ef":"doCheck()","f1f3ae31":"novaContractAddress()","f1f49033":"deductDeposit(address,uint256)","f1f4e25d":"OctaBlock()","f1f62f10":"isWalletLocked_Send(address)","f1f6d945":"webAddress()","f1f732cb":"BONUS_TOKENS_RESERVED()","f1f76438":"checkNumber(address)","f1f87fc9":"BitMix()","f1f9539f":"KittyRace(address)","f1fa1744":"sellpause()","f1fa906c":"getProjectName(uint256)","f1fb3ace":"minEth()","f1fb5219":"_calculateContribution(uint32,uint8,uint64)","f1fbf2a3":"calculateObtainedSBT(uint256)","f1fc4db4":"updateCutoff(uint24)","f1fd9614":"getNumData(uint256)","f1fe42b8":"TransactionRequest(address[3],address,uint256[11],uint256,bytes)","f1fea32a":"setPOOL_edit_7(string)","f1fec2b8":"nodePrice()","f1ff3d4b":"totalNumberMinted()","f1ff4a67":"releaseWithheldTokens(address,bool)","f1ff732b":"setBanker(address)","f1ffde45":"BasicBallot(address,string,string)","f20001b0":"Menu08()","f2016a4f":"updateMinEthPerNotification(uint256)","f201da0d":"newChannel(address,address,uint256,uint256,uint256,address)","f2020275":"users()","f2021550":"QBankChain()","f2022905":"toldYouItWouldWork()","f20341a8":"getRemainingTarget()","f203af26":"registerImport(bytes8,bytes8,uint256)","f203c19d":"usersAddress()","f203c857":"getSpeaker(address)","f20431c8":"MyTotalNTD()","f2057179":"changeInstitutionOwner(string,address,address)","f20652a1":"nxcSold()","f2068bfc":"addUniqueSpinner(string,uint256,address,uint256,uint8,uint8,uint8)","f206cf74":"MINIMUM_ETH_SOFT_CAP()","f206e7c9":"fechAllVoteResultBySnapshotBlock(uint256)","f20717e9":"getNbTrade()","f207564e":"register(uint256)","f2080ba6":"Pong(int8)","f2083220":"activeTranscoderTotalStake(address,uint256)","f2091083":"dollaryDanToken()","f2097550":"bucketExists(bytes32)","f2097b9b":"doesAddressOwnSpinner(address,uint256)","f209fc1f":"purchaserWhiteList(address)","f20b4368":"AllocateMainSale(address,uint256)","f20b93ea":"getInvoiceAmountPaid(bytes32)","f20d5385":"endCrowdsalePhase2Date()","f20d5943":"s0(bytes1)","f20d5e57":"distributeToReferreal(uint256,address)","f20dde7b":"updateCostETH()","f20de9d6":"openGameLoop()","f20e5e35":"getAuctionDetails(uint256)","f20e5f51":"PeriodChanged(uint8)","f20eaeb8":"output()","f20f24ec":"pauseTokenSale()","f2102390":"SOFTCAP_RATE()","f2107f83":"getStakingInfoPayload(bytes)","f2108aa8":"FraCoin()","f2114752":"viewSecondLotOfContractState()","f21153d2":"withdrawSettle(bytes32,uint256,address,address,uint256,uint256,bytes32,bytes,bytes,bytes32)","f211c9ed":"releaseMultiByStage(address[])","f2125f40":"SEELE()","f212c216":"setSystemAuctionDuration(uint256)","f213159c":"depositTo(address,address,uint256)","f2139abf":"getBigPromoBlockInterval()","f213aad2":"dayWithdrawCount()","f2141ab9":"lossToCharity(uint256)","f21439b5":"envokeTokenAllocation()","f2147f7b":"currentPeriodPrice()","f21502e5":"ZTHTKNADDR()","f2153fae":"BNKCToken()","f215bc3e":"genEstKeyBlockNr(uint256)","f21632e1":"icoEtherReceived()","f2166ab1":"xpanda(uint256,string,string)","f216b203":"TokenSyndicate(address,uint256,uint256,uint256,uint256)","f216bfd6":"updateUportInfo(string)","f216f45d":"nextStageBonus()","f21711f3":"currentRating()","f217d6a3":"standardDailyLimit()","f217f15c":"doCreate(uint256,bytes)","f2180c61":"versionCode()","f2181e23":"initializeGasPriceLimitFundraiser(uint256)","f219fa66":"depositERC20(address,address,uint256,uint256)","f21a1468":"getOutcomeTokens()","f21aaee6":"MinerChain()","f21aefd2":"isDebug()","f21af007":"unWhitelist(address)","f21b422a":"unregisterCustodian(address,address)","f21b64ad":"DepositETH(uint256)","f21b9379":"setRoundAvailableToken(uint256,uint256)","f21baec7":"withdrawPreIcoFounds()","f21c27a7":"CTAMToken()","f21cdf6f":"defrost()","f21d5dea":"withrawAll()","f21ddc7a":"teamBalanceOf(address)","f21f537d":"startedAt()","f21f80d0":"setGenome(uint256,uint256)","f21f8236":"getRefTo(address,address)","f2204d35":"getWalletsFromUser()","f220cbe0":"GetIsPaused()","f2218819":"getAddressAndSharePriceOfFunds()","f221abef":"isReachedThreshold()","f221b25b":"addSponsorshipsTotalRefunded(address,uint256,uint256)","f221b75a":"addCET4(uint32,string,uint32,uint32,uint32,uint32)","f221fda0":"totalRooms(string)","f2225500":"FHCoin()","f222d0b9":"getNumberOfBets()","f223446c":"start_game(bytes32,uint8,uint32,uint16,address,uint256,uint8)","f2234f6e":"confirmAdmin()","f223885a":"deposit(uint256[],uint256[])","f225138b":"littCapsuleGet(bytes32)","f22513a7":"withdrawLatium(uint256)","f225415a":"getFrozenBalanceByAddress(address,address)","f2260031":"lockAddress(address,bool)","f2263e12":"refundedFunding()","f2269c8e":"_createFootballerStar(uint256,uint256,uint256,uint256)","f2269dba":"airdropCooldownEnd()","f2274abb":"getReservedIsVested(address)","f227b198":"CreateWEE(address,uint256)","f229abbd":"enableBurn(bool)","f22a0b31":"getDays(uint256)","f22a598f":"changePriceUpdateTimeline(uint256)","f22aa38b":"getSDCCSupply()","f22aae52":"_memcpy(uint256,uint256,uint256)","f22b0c94":"setBonusOff()","f22b258a":"trustedMarketTransfer(address,address,uint256)","f22b683e":"delKycVerifiedInvestor(address)","f22c0f7d":"isValidTxPaymentForMCW(bytes32)","f22c10d7":"setShareHolders(uint256,address,uint256,bool)","f22c618e":"isItemStopped()","f22c6a7c":"STE(string,string)","f22c71e5":"finalizeLottery(uint16,bytes32,uint256)","f22c8f63":"FINANCE_CAP()","f22d022b":"burnIcoCoins()","f22dbfe6":"forLoyalty()","f22f264d":"setMinBalance()","f22ffd1d":"TLN_TOKEN_DECIMALS()","f23008ca":"CarBonCash()","f2309723":"setUserApproval(address,address,string)","f2316472":"transferMyTokens()","f2325244":"VULCAN_PROMETHEUS_MAX_CARGO()","f232880d":"reserveWaveTokens()","f232a84d":"getAmountAttempted(address)","f232e351":"initializeBalances()","f23342d8":"checkHashExists(bytes32)","f2335e9d":"setAvgGas(uint8,uint16)","f2342bba":"getBagDetails(uint256)","f2342cd5":"Contributor(string,address,address)","f234bac5":"tokenCreationCapUpdate(uint256)","f235bdfd":"getRetailerTotalBalances(address)","f235bfa4":"addAccount(address,string,uint256)","f236e2fb":"UTCT()","f2371fb3":"grantGiveableKudos(address,uint256)","f2371fd1":"newEmployer(bytes32)","f238683f":"lastKing()","f238dbea":"minimum_payment()","f2393d55":"getKebabsSincelastKebab(address)","f239c5dd":"crowdsaleMinted()","f239e528":"sendOneEtherHome()","f23a6e61":"onERC1155Received(address,address,uint256,uint256,bytes)","f23a8155":"internalInvest(address,uint256,uint256)","f23a8aa6":"getOwnerLink(address)","f23b55c3":"BB8Token()","f23b6fa2":"emitApprovalEvent(address,address,uint256)","f23b872e":"tvc()","f23ba8e6":"hire(address,uint256)","f23bc4f8":"acceptOffer(uint64)","f23c51cd":"setReceiverContractAddress(address)","f23ca012":"becomeNorsefire()","f23e22a7":"rescheduleTransaction(uint256,uint256)","f23f16e6":"appealCost(uint256,bytes)","f23f2cbe":"withdrawWithFee(address,uint256,uint256,bool)","f2405395":"STAGE_THREE_ETHRaised()","f2408d6b":"PIN(uint256,string,string,uint256,uint256,uint256)","f2409d65":"getMileagePoint(address,address)","f240d0f5":"feesWithdrawn()","f240f7c3":"dispute()","f24113c6":"updateProfile(bytes32,bytes32)","f241335d":"calculatePrice(string,uint88)","f2414cbd":"YASToken()","f24150ae":"VoxelDestroyed(uint8,uint8,uint8)","f2415183":"Tithe()","f2416f64":"oracleItCallbackAddress()","f242432a":"safeTransferFrom(address,address,uint256,uint256,bytes)","f2429b1c":"buyCryptopinions(address)","f2430fe5":"Plumix()","f243c170":"buyTokens2(address)","f243c2a7":"tokenIssuer()","f244815e":"setBuyUnfreezePeriodSeconds(uint256)","f245036e":"setPools(address)","f2451a43":"addOwnerNotations(string)","f2455807":"setDesignatedReporter(address)","f24570e0":"approvedFactories()","f245b9e4":"DVIP(address)","f245d8c6":"NewHero(address)","f2460172":"_removeAssetFrom(address,uint256)","f246080a":"addvehicles(address,string,string,string,string,string,string)","f246317c":"SafeTimeLock()","f247016c":"isVoteOngoing()","f2477f7c":"BLOCKREWARD()","f24818cb":"unholdTime()","f2491377":"MAX_SINGLE_ISSUED_FROM_OTHER_CURRENCIES()","f249cf19":"get_all_challenges()","f24a0faa":"balance3()","f24a534e":"Oracle()","f24a6997":"maxGasRefund()","f24ae640":"countAccounts()","f24b5779":"removeTrustedIssuer(address,string)","f24b6782":"updateCrowdsaleTimeline(uint256,uint256)","f24d2532":"changeRegistrationStatus(address,bool)","f24e4a15":"Purge()","f24e7fd9":"activateKillSwitch()","f24edfd6":"setWhitelistedAddressPre(address[],bool)","f24f9abe":"grantBonusTokens(address,uint256)","f24ff92c":"withdrawal(uint256,address,uint256)","f2505211":"oracleItQuery(uint256,string,string,string)","f2513ee9":"cancelMarketsWhenPaused(uint256)","f2518983":"reinvestEther()","f251bc8c":"addPack(address[],uint16)","f251fc8c":"totalContributors()","f25214e4":"CRYPTODOL()","f2523e7a":"setUseRegistry(bool)","f2529e55":"Fidget(address,address,uint256,uint256,uint256,uint256)","f2530d1d":"claimableDividend()","f2534e47":"changeCertifier(address)","f253e6ae":"Daric()","f2540e39":"_unfollow(address,address)","f2556289":"endDutchAuction(uint256,uint256)","f255c21f":"Offer(address,string,uint256,uint256)","f2561a43":"voteSuicide(address)","f25633dd":"year1Unlock()","f256b130":"marketingFund()","f256b48e":"getBalanceOfDist(bytes32)","f257bf3b":"getAuthorityIndex(address)","f2582ef5":"UserStatus(string,address,uint256)","f258a4ea":"investorAccounts(uint256)","f2590315":"ClockAuction(address,address,uint256)","f25a7815":"MockSale(address,bool,uint256,uint256,uint256,uint256,uint256,uint256[])","f25acb35":"acceptDeal(bytes16)","f25aed54":"accountWithUpdatePermissions()","f25b278b":"fetchHash(uint256)","f25b3f99":"blocks(uint256)","f25c130a":"createOnRound(uint256)","f25c870a":"MyERC223(string,string,uint8,uint256)","f25dafd1":"drainAUC(uint256)","f25e34a9":"checkJuryVoted(address)","f25e7bb4":"getState(bytes20)","f25e9ed2":"getMaster(address)","f25eb5c1":"removeReverse()","f25ebdad":"isProxyManager(address)","f25ee28d":"MySecondToken()","f25efc49":"frozenRecords(uint256)","f25f4b56":"feeWallet()","f25fbe6f":"MetaGold()","f260ad05":"titanToken()","f260bd94":"validateRequestParams(address[3],address,uint256[12],uint256,bytes,uint256)","f261a8c0":"withdrawbymanager()","f2624067":"LogIncreaseCap(uint256)","f2624b5d":"whitelistCount()","f262521f":"PHASE_5_PRICE()","f262de8c":"add_staircase(uint16)","f2634485":"setGameRules(uint256,uint256,uint256,uint256)","f26377ed":"kittyGym()","f2642d0f":"decayedTransfer(address,uint256,address)","f2653966":"createReleaseAuction(uint256,uint256,uint256,uint256,uint256)","f26557d8":"AdeelaTestCoin()","f2659bd1":"GetCityLandNums()","f265d351":"rateSetter()","f2663a03":"TERSERAH()","f267035f":"BOARD_1()","f267215a":"_getProviderClosed(uint256)","f267ded5":"TokenStarted(address)","f268225c":"setBountyWalletAddress(address)","f26835d4":"tokensRemainingInHolding(address)","f26a058d":"U21Y()","f26b9834":"ENOM()","f26baecc":"_capLevelEth()","f26bb53d":"setCityPlan(address,uint256)","f26bbde8":"WHOMCrowdsale(address)","f26c159f":"freezeAccount(address)","f26c6aed":"newChannel(address,uint256)","f26cbe9a":"raiseDollarsDeducted(address,uint160,int160)","f26df083":"finalIntervalForTokenGen()","f26e5e85":"GetUpgradeCost(uint256,uint256)","f26e787e":"sendDelayedTransactions()","f26f336e":"MINING_RESERVE()","f26f4f61":"threshold(bytes32,address)","f26f6334":"setCraftingAddress(address)","f26fb705":"getPayoutRoundId()","f270bcda":"getClosingBlockNumber(uint256)","f2711812":"milion()","f27197ab":"getIsAvailable()","f272404d":"_approve(address,uint256,address)","f2729497":"numberOfFarmers()","f2729d8a":"getMinutes(address)","f272a60c":"addBagDelayed(uint256,uint256)","f272fe18":"Campaign(uint256,uint256,uint256,address)","f273515c":"Cyberminer(uint256,string,string)","f273fbbc":"perform_withdraw()","f27402e9":"bchRaised()","f274a828":"icoPhase3Start()","f274d00c":"LAWCoin(uint256,string,string,address)","f2759ee2":"transferDomainBackToSeller(string)","f2760d9c":"shareHoldersWallet()","f2761444":"MathUtil()","f2766051":"lastFinish()","f276e1c7":"voteResultPublish(address[],uint256[])","f276f36b":"getGameDataByIndex(uint256)","f276fdde":"onTaxTransfer(address,uint256)","f277010d":"percentFeeTimes100()","f27715b4":"updateMultiSig(address)","f2787d33":"feeAccountToken()","f278bd02":"newBooleanValue()","f279648b":"setConstraint(int256,bytes32,bool,bool)","f279fac5":"internaltransfer(address,address,uint256)","f27a4188":"icoSucceed()","f27a73ca":"frozenCell(address,uint256)","f27a8a99":"updateEmployeeInfo(uint256,string)","f27ac4d9":"decrease(address,uint256)","f27ae77d":"DGDIssued()","f27b6d8f":"Message(string,address,uint256)","f27b8084":"walletWebydo()","f27b9341":"getTeamPlayersNum()","f27c24ed":"startCloseSale()","f27c3bf6":"oneYear()","f27c85bc":"getQuickPromoPercent()","f27d0afe":"deleteArbitrator(address)","f27d3977":"NEOBleu()","f27db8c9":"getWinnerPayout()","f27e2ef6":"nextMineEvent()","f27e4b1e":"SwitchTokenTransactionsOn()","f27ee76c":"lastPot()","f27eede0":"getTotalBid(address,uint256)","f27f974b":"Margaret()","f2801fe7":"getUserInfo(address,address)","f28063ce":"getMemeHolders()","f28075af":"get_player_address(uint256)","f280efaf":"addressToBytes1(address)","f28109d1":"ConsentTemplate(string,string,uint256,string,string,string)","f281c386":"_percent(uint256,uint256,uint256)","f282f551":"setCrowdsaleTokenExtv1(address)","f2836e1c":"contributorStatement(uint256,string)","f28386bf":"Nexium()","f2853292":"ChangeOwner(address)","f2856a2a":"getTeamPlayers(uint256)","f285d98e":"unlockSecret()","f285f25c":"tokenMetadataHash(uint256)","f286c1c5":"addtoOwners(address,address)","f287900d":"LogContribution(address,address,uint256,uint256,uint256,uint256)","f288753d":"centsPerEth()","f2888dbb":"unstake(address)","f2891b3d":"assetRegistrant(bytes32)","f28a2f75":"_allocateUnspentRefTokens()","f28a7912":"quick2()","f28ac86a":"token(string,string,uint256)","f28adc4d":"Attack()","f28afb1e":"pushAngelInvestmentData(address,uint256)","f28b325d":"admin_set_shopStoreRegister(address)","f28b7a9c":"disbursementAmount()","f28b824e":"MAT_TOTAL_SUPPLY_LIMIT()","f28c0716":"approveDeal(bytes32)","f28ce253":"is_min_goal_reached()","f28d253d":"getDividents()","f28e59c9":"get_sale_owner(address)","f28ee00c":"permittedSender()","f28f0f6a":"bulkCreateLambo(uint256,address,uint64,uint256,uint256)","f29143ad":"Project_ChangeOwner(uint256,address)","f2928eea":"CaptainPreSell()","f2934817":"HalalPenny()","f293bab5":"numberofnews()","f294aa26":"EndoSHARD()","f295206f":"_unsafeSend(address,uint256)","f295587e":"giveITup()","f29617da":"registrationDeposit(address)","f2965a2c":"BurnupGameCore(address)","f296c1f2":"buyTokens(address,uint256,uint256,string)","f297109d":"RESERVED_TEAM_LOCKED_SIDE()","f2977c97":"approve(address,bytes32,bool)","f298083b":"setLottery(address)","f2980eb2":"getPRewardLength(address)","f29a72ff":"_addTokenToPartition(address,bytes32,uint256)","f29b2040":"export(address,bytes8,address,address,uint256,uint256,bytes)","f29c1bc2":"setIsChargingTokenTransferFee(bool)","f29c7870":"setRefineCost(uint256)","f29d2f28":"setTokenHolder(address)","f29f1fa2":"RecievedEth(address,uint256,uint256)","f29f4d0b":"lastBuyTime()","f29f7b1b":"remove_coin(uint256)","f29fdb8a":"createSeason(uint32,uint64,uint64,address[8],uint256[8],uint16[8],address[8])","f29fe77e":"testMintGuy(int256)","f2a0928d":"preICOduration()","f2a0a987":"GCNYToken()","f2a16d5a":"GetNonce(uint8)","f2a38dac":"setKYCAdmin(address,address)","f2a4a82e":"item()","f2a5630a":"BallotUp()","f2a5c79c":"getViewDatas()","f2a6517f":"updateTokenContractAddr(address)","f2a69417":"cancelFoundationTransfer()","f2a6e605":"evenDistThresh()","f2a724b1":"SnoqualmieCoin(uint256,string,string)","f2a75fe4":"empty()","f2a7e624":"approvedWallet()","f2a9a8c7":"allowance(bytes32,bytes32)","f2ab3e60":"incomeOf10k()","f2ab59d9":"contributionTarget_()","f2ab9384":"sumElements(uint256[])","f2abd01d":"initialBeating()","f2ac9427":"pricesToCommit(address[])","f2adc939":"removeBoundary(uint256)","f2af0e2f":"getProviderCurrentSupply(address)","f2af59bf":"fourthStage()","f2afe985":"LEBRON()","f2b0318e":"_getNibbleArray(bytes)","f2b05c15":"getTopicCount(address)","f2b0a55d":"getPlotData(uint256)","f2b175c0":"sendTokenTeam(address,uint256)","f2b1be45":"setAquariumCost(uint256)","f2b265ca":"playGame(uint256,string,string,string)","f2b26d8f":"nextEtherForSale()","f2b29993":"getMineral(uint256)","f2b2f40c":"allowPurchase(uint256)","f2b2ff1b":"platformReferral()","f2b3ddfa":"getCET4ByAddr(address)","f2b40209":"RATE3()","f2b445ad":"rowround(uint256,uint256)","f2b45ac1":"startCrowdSale()","f2b45ec5":"DonQuixoteToken()","f2b47d52":"geneScience()","f2b4c1b9":"isValidDataHash(bytes32,bytes)","f2b559ac":"printQuotation(int256)","f2b6e8b6":"emitSynthetixUpdated(address)","f2b7a54b":"destTokensAirdrop()","f2b841c0":"isPlayerIdle(address,uint256)","f2b85515":"addNewGame(address)","f2b904c3":"checkBetColumn(uint8,address,bytes32,bytes32)","f2b9541f":"createEthCommunityToken(string,uint8,string,uint8)","f2b9b40f":"enableRegistration()","f2b9f903":"_getParticipantRoles(address,address)","f2b9fdb8":"supply(address,uint256)","f2ba18ed":"calculateVotes()","f2ba31ea":"Marine()","f2ba478d":"EtherCashPay(address,address,address,uint256,uint256,uint256)","f2ba810e":"PRE_SALE_30_BONUS_MIN()","f2baaa07":"createBet(uint32,uint256)","f2bb5ce1":"maxMintProofOfStake()","f2bbca67":"checkVotingForChangeBuySellLimits()","f2bbdab4":"N2C()","f2bcd022":"withdrawalAddress()","f2bddf66":"redemptionInfo(address,uint64)","f2be600d":"getNumTanksType(uint256)","f2bea1fc":"MANAGER_SUPPLY()","f2bee03d":"set_sale_address(address)","f2bf7e7a":"TokenGAC(uint256,string,string)","f2bff63b":"ico_tokens()","f2c00979":"_emitTransferred(address,address,uint256,address)","f2c0cdbe":"dividendsPercent()","f2c0d168":"newOwner(address,address)","f2c1d74e":"FansToken()","f2c298be":"register(string)","f2c2dff2":"testFailSetNotRetractableNotOwner()","f2c340f2":"chfCentsPerToken()","f2c3e6d9":"requireTokenFuel()","f2c402b6":"todayReserved()","f2c44e77":"UpgradeEnabled(address)","f2c4c45d":"makeInvestment(address,uint256,address,address,uint256,uint256,address)","f2c51f9d":"DNAc()","f2c5925d":"setNext(bytes12)","f2c6bab0":"doCallNumber()","f2c70bda":"addInvestorIfNotExists(address)","f2c7d331":"receiveDividends(uint256)","f2c80435":"addToUnminted(uint256)","f2c816ae":"addAddressToBlacklist(address)","f2c8257e":"getcapname()","f2c8a87b":"SYC2ndEarlyPurchase()","f2c8b676":"FACTOR_8()","f2c8d247":"convertibleToken(uint16)","f2c9e0ed":"SkrumbleToken()","f2c9ecd8":"getNumber()","f2cba6a6":"REPUTATION_DECIMALS()","f2ccaed5":"getSaleContractEndBlock(address)","f2cd84d5":"tokenHoldersToClaim(address)","f2cedaa0":"destroyCoins(address,address,uint256)","f2cee589":"TIER1_PERCENT()","f2cf687a":"MAXPERWEI()","f2cfe267":"setEpochData(uint128[],uint64[],uint64[],uint256[])","f2d05f2b":"playerIndexToOwner(uint256)","f2d06540":"setBitpaintingStorage(address,address)","f2d15c48":"setLicenceTellerPrice(bytes2,uint256)","f2d213c8":"BONUSED_PURCHASES_LIMIT()","f2d2e1a7":"QSHU()","f2d2fa91":"privateSaleMaxContrAmount()","f2d386b9":"getjournalists()","f2d439d8":"PokerPayout()","f2d50151":"verifyRs1Hash(bytes,bytes32)","f2d578dc":"RHToken()","f2d57adf":"setClaimInterval(uint256)","f2d5866d":"ATTR_EXPLORABLE()","f2d5d56b":"pull(address,uint256)","f2d68ee0":"withdrawCollateralFromPool(address,uint256)","f2d6cd26":"CEO_Trader()","f2d6e0ab":"__process(bytes,address)","f2d701a7":"giveaway(uint256,uint256,uint256,bool,address)","f2d73dc6":"VoteZoneToken()","f2d7f637":"closePosition(bytes32,uint256,address,address,bool,bytes)","f2d805d5":"firstStageRaisedInWei()","f2d906cc":"addressFounders2()","f2d93fb0":"setRushTimeFloorCount(uint256)","f2d9f46e":"flipPayingDoublrs(bool)","f2da1f0a":"imageAddress(address)","f2da67db":"setMany(uint256,int256,uint256,bytes20,address,bytes)","f2da877d":"dataOfSell(address,uint256)","f2dabd26":"multipleMint(address[],uint256[])","f2dadd3d":"FundRequestPrivateSeed(uint256,address)","f2db5493":"VGS()","f2dbe0f8":"options(bytes32,address,address)","f2dc8878":"setTokenSaleAmount(address,uint256)","f2dd4be8":"publish(string,bytes32,uint256)","f2dd6585":"garanteSystemDepositInAllFunds()","f2ddc772":"confirm(bytes)","f2dddd95":"BLDAToken(uint256,string,uint8,string)","f2de12fc":"getFxUSDAmount(string,uint256)","f2dfa136":"STATUS_DEAL_WAIT_CONFIRMATION()","f2dfd7f5":"cancelWarranty(string,string,address)","f2e03ad0":"openProvider(address,bool,string,string,uint256,string,uint8,bool,address)","f2e09c7a":"activatePoint(uint32,int256)","f2e0d636":"registerSponsor(uint32,int256,bool,uint32)","f2e1192a":"wolkSale()","f2e12a39":"setRole(uint8,address)","f2e1b1cc":"getWinSlot(uint256)","f2e1be50":"GDPOracle()","f2e22ae0":"messageBoard(string)","f2e253ec":"FUTURE_ME_TOKENS()","f2e27b33":"signedTransferHash(address,address,address,uint256,uint256,uint256)","f2e28e16":"BrianexToken()","f2e2e5ea":"trustedAddressInLUT(uint256)","f2e34909":"PRICE_CUTOFF()","f2e4ff30":"isValidAuction(uint256)","f2e552a5":"verifyUpdateTransaction(bytes32,uint256,address,uint256,address,uint256)","f2e55ac1":"getDestinationByIndex(uint256)","f2e62772":"admin_address()","f2e650ff":"PerpetualTestCoin()","f2e6e170":"addressesImported(address,uint256,uint256)","f2e6fecd":"Ethernational()","f2e7514c":"buyByName(string)","f2e79ab7":"ETHealth()","f2e84f24":"_byrne(uint256)","f2e998df":"ownerRevealOverride(uint256)","f2ea83e6":"executeRecursive(address,address,bytes32,int256)","f2eae773":"getLockedWalletAmount(address)","f2eaee02":"applyWait()","f2eb32fb":"addOffChainContribution(address,uint256,uint256,string)","f2eb3e34":"init1()","f2eb5dd3":"tokenUSDRate()","f2ebde57":"tryExec(address,bytes)","f2ec602c":"feeWithdrawn()","f2ec6264":"ownerAddressLUT(uint256)","f2ecebea":"ratePreIco()","f2ed2148":"newGateway()","f2edb7c7":"purchaseWonder(uint256)","f2ee8be9":"setSubmissionOpen(uint256)","f2eea5c1":"setupAccreditedAddress(address,uint256)","f2eec570":"transferredAmount(address)","f2eec69b":"CTOAddress()","f2f03877":"commit(uint256,bytes32)","f2f0967b":"setLifToken(address)","f2f18af2":"Withdraws(address,uint256)","f2f254c7":"getLatestMinorTree(bytes32,uint32)","f2f2a043":"setUserCommissionRate(uint256)","f2f3384e":"_getGen0Address(uint256)","f2f3a1d2":"Erc20Token(string,string,uint8,uint256)","f2f3c773":"vestInterval()","f2f48e20":"Update_START_PRESALE_TIMESTAMP(uint256)","f2f4eb26":"core()","f2f56ffe":"getCommit(uint256,address)","f2f62ac7":"TOSPrivateIncentiveContract()","f2f65960":"setGracePeriod(uint256)","f2f6861b":"WinbitTest()","f2f6ccda":"getBalanceFromOwner()","f2f6ff15":"COLOR_BLACK()","f2f70594":"disableMintForever()","f2f8569f":"buyAndTransfer(address,address,bytes)","f2f85fce":"GRAND()","f2f921e6":"snapshotDailyGooDepositFunding()","f2f977a7":"getBetsByCategory(string)","f2fa8f69":"TokenPolicy(address)","f2fc6deb":"weiToTokensBono(uint256)","f2fc9100":"init(address,string,string,uint8,uint256,bool)","f2fd2a49":"galleryThree()","f2fdddf4":"setEncryptContract(address)","f2fde38b":"transferOwnership(address)","f2fdfe34":"createSpecies(uint256,string,address)","f2fe1a1d":"geSoftwareVersionRecordsLength()","f2fec913":"collectMKR(uint256)","f2ff0912":"getHolderAtIndex(uint256)","f2ffb4fc":"stopLive()","f30000f9":"NewCloneToken(address)","f300cf1d":"addUserToMeta(address,uint256)","f301ac65":"hashBid(address,uint256,address,address,bytes32,uint256,uint256)","f3022de8":"setNewContractAddress(address)","f3025556":"newDeveloper(address,uint64,bool)","f3025f10":"dataOfBuy(address)","f302be42":"startTokenRaffle(uint256,address,uint256)","f3036c24":"UTORN()","f30398ef":"Wishcoin()","f30416ca":"setSaleAuctionContractAddress(address,address)","f30431b5":"addAdminAccount(uint256,address)","f3052d26":"getCategory(uint256)","f30562b6":"updateRecord(string,string,string)","f3072020":"partner_1_name()","f3074b58":"withdrawSDTfromcontract()","f307946d":"hardCapMainSale()","f3083c44":"GetMyEarnings()","f308846f":"registeredCallbacks(address)","f3095511":"GetTokenPriceCents()","f309782b":"LescovexAddr()","f309caca":"icoEndOfStageB()","f309e3c5":"allocateUnsold()","f30a4a70":"getSoldToken()","f30a7166":"multiTransferFrom(address,address[],address[],uint256[])","f30ba854":"tokensPerEther_numerator()","f30bb8af":"GoalReached()","f30c0ee6":"getRank05()","f30d3ad4":"crowdSaleAmountRaised()","f30d4d3f":"signedTransferFromCheck(address,address,address,uint256,uint256,uint256,bytes,address)","f30df155":"calculateBorrowAmountWithFee(uint256)","f30f8508":"setReservedTokensList(address,uint256,uint256)","f30faff6":"SetExtra(uint256)","f31011ac":"ANTS_TO_COLLECT_1ANTHILL()","f310348e":"_removeFrom(address,uint256)","f3106780":"DoDividend(uint256,uint256,uint256)","f3107c48":"nestedFirstAnyToAny2(uint256)","f310a19d":"getPlayerVaultsHelper(uint256,uint256)","f31174ee":"inactivityReleasePeriod()","f3125a1f":"deposit(address,uint256,bytes,uint256)","f31294a4":"announcementURI()","f3130ba5":"setTokensSoldInPresale(uint256)","f3147b00":"totalICOAmount()","f314bf46":"setReleaseDb(address)","f314e2c0":"CoinExchangeToken(uint256,string,uint8,string)","f314e976":"parcelGzeWithoutBonus()","f315e81d":"getStage1End()","f31604c7":"setData()","f3161022":"convertToEther(uint256)","f3164eb6":"transferAndFrozen(address,uint256)","f31660e9":"getOrganisationsSize()","f3169506":"readPurchaseAtIndex(uint256)","f316ea78":"buyOrderTotal()","f317b85b":"ownerAddressNumberMap(address)","f3181001":"founderAndTeamSent()","f3182d6c":"setFeeRate(address,uint256,uint256)","f31887e6":"tokenTransferByAdmin(address,uint256)","f318c75f":"dvipAddress()","f318cc4a":"invite(uint256,uint256,uint256)","f3191443":"toggleMigrationStatus()","f3199e98":"setMinWeiForDInit(uint256)","f319a899":"NameProvider(address)","f31a044d":"test_bytes(bytes,bytes)","f31a18a5":"endICOStage7()","f31b4e89":"updateEpisode(uint256,string,uint256)","f31bac4d":"SwitchLoanOwner(address,uint256)","f31bebaf":"BugBountyOneBreaker()","f31df3f8":"AddItem(uint32,uint16,uint256,uint16,uint16,string)","f31e3e84":"AML()","f31e731e":"attack(address,bytes32,uint256)","f31ed9e6":"DescartesToken()","f31fe982":"endGround(uint256)","f3200a1c":"change_symbol(string)","f3201424":"register(address,address,address)","f3203dc0":"MultisigsChanged(address,address)","f3205c93":"isUserBanned()","f320d963":"assertEq(string,string)","f32106f0":"TemplateToken(uint256,string,uint8,string)","f32113d5":"setBgxWalletAddress(address)","f3214652":"NHSToken()","f321653a":"setCommunityBallotStatus(bool)","f3217345":"getShowText()","f32188a5":"reinvest(address,bool)","f3221c7f":"hasHash(address,bytes32)","f322770c":"LogWhitelistAdd(address,uint256,address)","f3227dc4":"cancelDeal(string)","f322a1cf":"BlueChainToken()","f322c755":"daoManager()","f32306d2":"registerNameXID(string,uint256)","f3236460":"closeUp()","f323a061":"lottoQueue()","f3269716":"year()","f326be05":"Centaure()","f3278191":"BuyFST(address,uint256,uint256,uint256)","f32784cd":"getGratitudeOf(address,uint256)","f327b7fc":"isNotZero(address,string)","f3283fba":"setMultisig(address)","f32a547c":"getBuy(uint256)","f32a72eb":"airDropMembers(address)","f32a9f77":"ReceiveEther(address,uint256)","f32b85e8":"timeScale()","f32d61eb":"setDevTokensPercent(uint256)","f32e8038":"setPercentIncrease(uint256,uint256,uint256)","f32eca11":"revokeAccessDeposit(address)","f32efd3c":"recoverUser(address,address,uint256,uint8,bytes32,bytes32)","f32f6a23":"olympus()","f32fc856":"Wanchain()","f32fe995":"left96(uint256)","f3302a4d":"ChangeTransferStatus(bool)","f3305ae2":"setName(bytes32,address)","f331020c":"GAMEPAUSED()","f3310628":"allocateTokensInternal(address)","f33146af":"test_twoTrueAsserts()","f3316ef5":"countStudentRequest()","f3318fed":"ThrowsInConstructor(bool)","f3319243":"decimalFraction(uint256,uint256)","f331de4c":"addShare(address,uint256,uint256,uint256)","f332511f":"getTxcode(uint256)","f33261ac":"stageCount()","f33280b2":"etherLimit()","f332a245":"unbanToken(address)","f3332d1c":"burnTokensExp(uint256,uint256)","f3333e7f":"etherProceedsAccount()","f33376c6":"createNext(address,string)","f333fe08":"getCertificate(bytes32)","f3358ac4":"getNum(uint256)","f33670aa":"sharesAddress()","f336bc7e":"maxDecreasePct()","f336e80a":"setMaximumVotingWindow(uint256)","f3372898":"dtrade(address,uint8,uint8,uint256[],address[],bytes32[])","f337616c":"PETER()","f337a0bb":"getLLV_edit_4()","f337c2e1":"calculateNextEtherValue(uint256)","f33801e0":"setCoachPrice(uint256,uint256)","f3382694":"isCamp()","f3388e75":"timelockController()","f338c984":"initialBountyAmount()","f3391998":"hasHash(uint256)","f339292f":"mintingStopped()","f3396905":"lockedNowBalanceOf(address)","f339c504":"lockBalance(uint256)","f33aa95d":"setIsTransferEnabled(bool)","f33ae7fd":"auctionOf(uint256)","f33b1ea5":"rewardUsers(uint256,address[],uint256[])","f33d0f3a":"requiredBet()","f33d9a52":"get_data_benefited(address,string)","f33dc1fa":"founderTokensAllocated()","f33f8f26":"setpubprize(uint256)","f33f9522":"readCoin(uint256)","f33ffc16":"addSpecialBonusConditions(address,uint256,uint256)","f34080b3":"MIN_INVESTMENT_ICO_PHASE_TWO_POUNDS()","f3408110":"transferWithFee(address,address,uint256)","f340fa01":"deposit(address)","f3412942":"accountLevelsAddr()","f34186c8":"endEthGet()","f341cae8":"setEmergencyAccount(bytes32,bytes32)","f341d3ba":"bandwidthFactor()","f3433ff2":"callbackTime()","f3436873":"totalAxiesRewarded()","f3436c85":"TKXToken()","f343ccbd":"CrystalSkull()","f3444701":"newTankType()","f344f4fa":"HARDCAPPED_SUPPLY()","f345d06b":"getTileHp(uint16,uint8)","f3463272":"signupFee()","f3465181":"preSeedAllocation()","f3466b47":"setTotalCollected(uint256)","f346fd74":"TraceChain()","f34839d1":"C50()","f3492915":"confirmSpendLimit(uint256)","f34969d1":"minimumFundingCHF()","f349e3e3":"own(address)","f34a5e85":"MercuryToken()","f34b95b3":"register(string,address,bytes32)","f34c7010":"commitSecurity(address,uint256,uint256)","f34d22d0":"getQuickPromoRemainingBlocks()","f34df94e":"Version(string,address,address,bool)","f34e2699":"isPresaleFinalized()","f34e3723":"release(string)","f34e4c60":"currNumOfBattleCards()","f34ed4e6":"RanDAOPlus(address)","f34f43f6":"getRepTokenAddress()","f34f5f45":"Election(string)","f3512ce0":"multiLock(address[])","f351d166":"_depositEscrow(uint256)","f3522656":"getRejections(uint256)","f353108b":"fechVoteResultForCandidate(address,uint256)","f353ae48":"goodluck()","f354040c":"SpreadToken()","f3541901":"execute(address,bytes,uint256,uint256)","f3548cd3":"getBagCount()","f354e2c3":"_getSeason()","f355b92d":"BuyTokens(address)","f356d6cc":"getPI_edit_18()","f356e8de":"placeNewSurvey(bytes32,uint256,uint32,uint256)","f3574a20":"TokenTransacted(address,address,bytes32,address,uint256,address)","f3576220":"withdrawls()","f3582373":"getTokenAddressesLength()","f3586fb9":"_isAuthorized(address,uint256)","f35898bd":"PreviousPayout()","f358b3de":"REKTMultiSigWallet()","f359671c":"withdrawWithReference(address,uint256,string)","f359b03c":"recalcBonuses()","f359d66d":"driverCount()","f35a8796":"removeHouseHold(uint256)","f35b3b51":"Bullioncoin()","f35b6068":"selectWinningNumber()","f35ba5d3":"acceptCeoOwnership()","f35c172e":"getSecondHexByte(bytes1)","f35d606c":"ETFToken(address[],uint256[],uint256)","f35dad40":"totalRedeemed()","f35e3945":"SRHCoin(uint256,string,string)","f35e4a6e":"setStartBlock(uint256)","f360234c":"compare(uint256,uint256)","f3604e54":"advisorsKey()","f36089ec":"getConversionRate()","f3608b57":"_getEthToUsdPrice(uint256)","f360c183":"setNonce(uint256)","f360e22f":"celebrityCount()","f3611719":"confirmFriendship(string)","f3616a90":"UpdateHOLDer(address,address)","f362b9af":"StartNewMiner()","f362d78f":"testBitNotEqualSuccess()","f3634033":"token_b_amount()","f363441f":"getCreatorDotBalance()","f363449f":"reservationSupply()","f3635a02":"vc2Wallet4Pct()","f3637d51":"setPayLock(bool)","f3647597":"setGrantVestedEDEXContract(address)","f364e7f4":"_investAsEarlybird(address,uint256)","f36631e7":"createHero(uint16,address)","f3667517":"getMinter()","f3669ec9":"hopefuls(uint256)","f36706cb":"SENSToken(address,address,uint256,uint256)","f3678cd3":"updateOffChainTokens(uint256)","f36a1fd9":"_allowBuyDirect()","f36a4bd3":"ReceivingContractTokenFallbackFailed(address,address,uint256)","f36b135d":"PRICE_EXPONENT()","f36c0810":"RANDOM_BYTES_COUNT()","f36c83f0":"getPuppy(uint256)","f36d1b8e":"SignStopDividend()","f36d1e4e":"setRewards(uint256,uint256,uint256)","f36d29e7":"triggerTansferEvent(address,address,uint256)","f36db900":"gameStarterDividendPercentage()","f36e20db":"getStage1Start()","f36e8dea":"MedicalCannabis()","f36f235d":"getLedger()","f36fd108":"editTitle(uint256,string)","f370031e":"BetOnATeam(address,uint256,uint256)","f3701da2":"build(address)","f3702b82":"setBonusPattern(uint256[],uint256[])","f3703a69":"LogGrantCreated(bytes32,uint256)","f3706bb7":"killTransaction(bytes32,bytes32,string,string)","f370ff51":"LogTokenPurchase(address,address,uint256,uint256)","f371475a":"initialiGnSupply()","f371ec49":"pausedB()","f3737ffd":"setDiscount(uint256[],uint256[])","f3746947":"giveBirth(uint256,uint256[2],uint256[2])","f3746ff7":"advisorReserve()","f375bcaa":"failedTimestampSeconds()","f37633f9":"Internet()","f376daa8":"MMX(uint256,string,string)","f3773466":"endIcoRoundManually()","f377f5b7":"setAirdropTotalSupply(uint256)","f3781697":"HubiiCrowdsale(address,uint256,uint256)","f3784dec":"withdrawFailed(address)","f378ff76":"random(uint32,uint32)","f3791477":"OLD_TOKEN()","f3794914":"mintParticularPart(uint8[4],address)","f37a7d4d":"boosters()","f37a9c1c":"ALLOW_BETA()","f37b0427":"CryptrustToken()","f37b437b":"scheduleCall(address,bytes,uint256,uint256,uint8,uint256,uint256)","f37b74ca":"authorizePayment(string,bytes32,address,address,uint256,uint256)","f37b916a":"tokenCreateUtcTimeInSec()","f37bdaac":"transferSig(bytes32,uint256,address)","f37bf1be":"getParticipateName(uint256)","f37cc477":"calcOutput(uint256,uint256)","f37d11cc":"canTransferFrom(address,address,uint256)","f37e592d":"shopStoreId(address)","f37e741e":"projectWeight(uint256)","f37f8345":"getTokenRates(address,address[])","f37fda1b":"setUser(address,address,bool)","f37fdaf5":"calculateProfitPercent(uint256)","f37ff01b":"getLLV_edit_13()","f380729d":"claimB2()","f3813163":"proxyTakeEtherBack(address)","f3817b23":"getWizzPandaCountOf(uint256)","f381a3e2":"FuelingToDate(uint256)","f381f2a5":"minimumCap()","f38323bb":"bountyDurationInBlocks()","f383c7b3":"setCrowdsaleStart(uint256)","f383d6b9":"OwnerValidatorImpl()","f384632c":"updateContestTeam(uint32,uint32,uint8[],uint32[])","f384764c":"oraclize_query(string,bytes[2])","f3850fda":"receiveTokens(uint256,uint256)","f385d890":"cnt_registrations()","f3868555":"orderEthOf(address)","f386b8fd":"TestToken2()","f3873e7b":"PublicBattle()","f38780e2":"winnerPaid()","f388b046":"currentTask()","f388ef80":"updateXPLPerEther(uint256)","f389057f":"_setMouthValue5(uint256)","f3898a97":"convert(address[],uint256,uint256)","f38a6163":"IncMainSupply(uint256)","f38a8262":"grantPermission(address,bytes32)","f38afbf7":"setModuleEnable(string,uint256)","f38b0585":"withdrawAdvisorFunds()","f38b0600":"fireEventLog3()","f38b2ef0":"testTheFirstMultiplier()","f38d5cb9":"_getHash(address,address,address,address)","f38db3d8":"setRunningInternal(bool)","f38e5ca2":"getBlobStoreFromFullBlobId(bytes32)","f38fb65b":"revertCall()","f3905b82":"ibaMultisig()","f390cae4":"ADDR_TKG_TECH_FUND()","f390e4b4":"getResidentNumber()","f3913e69":"tokenTransferFrom(address,address,address,uint256)","f391f074":"accountIdForAddress(address,address)","f3922cde":"addExceptAddress(address)","f39259d0":"_batch2_icosaleStartTimestamp()","f393b3b0":"_DataRegistered(bytes32)","f393f022":"icoStartP5()","f3942753":"addTxToCustomerRegistry(address,bytes32,uint256,uint256)","f3945ca0":"addEndorsement(bytes32,bytes32)","f39460c4":"setCheckMinContribution(bool)","f3956a71":"isMEH()","f396282d":"signupVerify(bytes32,bytes32)","f396cd66":"weiAmountShare()","f396e81b":"SALES_DURATION()","f397884b":"preIcoOpeningTime()","f3983e44":"createAmountFromTmedForAddress(uint256,address,address)","f398dc28":"aprovarUsuario(address,uint256)","f398faaa":"getRank09()","f3993d11":"batchTransferFrom(address,address,uint256[])","f39981e1":"burnStake(address)","f3998918":"getPreSaleTokenAmount(uint256)","f39992e4":"Blackwood()","f399c7e6":"startGame(address,uint256)","f39afaba":"GCV()","f39b1e74":"CQMVValueCirculateAssets()","f39b5b9b":"ethToTokenSwapInput(uint256,uint256)","f39b7fb1":"get_dati_articolo(bytes,bytes,bytes10)","f39bfb52":"giveBountyTokens(address,uint256)","f39c2197":"numberOfPartners()","f39cce01":"convertLotIdsByAddress(address)","f39d359b":"initDemoc(string)","f39d9f19":"CSES1()","f39e6e1e":"OwnerAddition(address)","f39e9fa6":"setERC223Activated(bool)","f39ec1f7":"lookup(bytes32)","f39f421e":"FIBKAD()","f3a04af4":"PUBLIC_TOKENS()","f3a133a9":"setStartAt(uint256)","f3a16c3e":"tokenCreationCapWithOutBonus()","f3a1b4b2":"setCrowdsaleStartandDuration(uint256,uint256)","f3a1d297":"addToken(address,string,string,uint8,string)","f3a1f828":"EventRandomLedgerRequested(address,uint256,uint256,uint8,address)","f3a247cb":"ZooToken(uint256)","f3a27963":"unpauseMints()","f3a3abc6":"setWhitelistTransfer(address,address,bool)","f3a3bef4":"innerScope()","f3a3de38":"EMACCrowdsale(uint256,uint256,uint256,address)","f3a44fe1":"withdrawForWorkshop()","f3a49f90":"sendOwner()","f3a504f2":"funded()","f3a53cd8":"ICOWIZARD(string,string,uint8,uint256)","f3a5626b":"addPurchased(bytes32,uint256)","f3a5644d":"crowdsaleEndedTime()","f3a5950e":"testHighestTranch()","f3a5f262":"setMemberTier(address,uint256)","f3a60cb4":"unLockAddrOwner(address)","f3a670cd":"Redeemed(address,uint256,uint256)","f3a67ad2":"subAccountBalance(address,uint256)","f3a8041f":"Crowdsale(address,uint256,uint256,uint256,uint256,uint256)","f3a87492":"AntiFakeLabelToken(address,uint256)","f3a8bcaa":"_logGameGiftInfo(address)","f3a9bf03":"verifyImage(address,string)","f3aa4420":"_grandTournamentBooty(uint256,uint256,uint256,uint256)","f3aa67ad":"buyTokensOraclePayIn(address,uint256)","f3ab7ea9":"seeker()","f3ac2732":"confirmed(uint256)","f3ac3df5":"prizeFund()","f3ac9ee4":"parseOpenTx(address[11],uint256[10],uint32[4],bool,bytes)","f3acc06b":"retrait_1()","f3acc477":"addTotalEtherValue()","f3ad0dd8":"multiTransferToken(address[],uint256[])","f3adcc46":"getMinerHashRateCurrentHalving()","f3ae2415":"isManager(address)","f3ae5acd":"LastExtractTime()","f3aee9f9":"tokensUnlockPeriod()","f3afe129":"hourPotExpiration()","f3aff181":"collectBagHolderFund(uint256)","f3b07bb1":"maxEthPerTransaction()","f3b15ffd":"test_insert_containsId()","f3b16265":"onDraw()","f3b303cd":"AdvanceToken()","f3b35100":"voteOf(address)","f3b3a9fa":"maxReserve()","f3b423d5":"updateReloadAmount(uint256)","f3b42c40":"isOnSaleAny3(uint256,uint256,uint256)","f3b4735e":"lotteryAddresses(uint256)","f3b4eccb":"ChallengeFund()","f3b50c04":"rescind()","f3b55007":"TDx(uint256,string,uint8,string)","f3b5678f":"ETHER_MAX_CONTRIB()","f3b585cc":"nSteps()","f3b5a5af":"bonusForEveryone()","f3b600ec":"_allocateTokens(address,uint256,uint256)","f3b6a748":"unpauseFrom(uint256)","f3b75ee3":"totalCommunityFundMinted()","f3b77f30":"close(bytes,bytes)","f3b849d6":"_allocateReferralTokens(address,uint256)","f3b8b2a9":"weiBuysHowManySeconds(uint256)","f3b978c1":"checkProof(bytes32[],bytes32[])","f3ba138e":"MineLevel(uint256)","f3baa092":"RemoveRequestEvent(address,address)","f3bb9741":"commitmentCampaign(uint256,bytes32)","f3bbc84c":"tierNum()","f3bd27a4":"secondStageMinting()","f3bda50a":"getSetNewTerrainPrice(uint256,uint256,bytes32)","f3bdc228":"destroyBlackFunds(address)","f3bdea04":"burnICACOIN(uint256)","f3be07eb":"getDefaultTranches(address)","f3be1e35":"VIVAToken(uint256)","f3becb59":"C(address)","f3bf6b73":"proposalChecked(address,uint256,uint256)","f3bf78e7":"setBAAAU(bytes32,address,address,address,uint256)","f3bf93a0":"forceReleaseAdmin(bytes32)","f3bfddb7":"getById(string)","f3bfe75e":"BeatTokenIcoFinalized()","f3c0efe9":"tokenToTokenTransferOutput(uint256,uint256,uint256,uint256,address,address)","f3c156f3":"purchaseDigitalArtSellingItem(uint256)","f3c15f49":"getLiability()","f3c16e54":"Resolve(bytes32)","f3c1c7c0":"LogCoinsEmited(address,uint256)","f3c20de0":"tokens(uint16)","f3c274a6":"isPut()","f3c37bd5":"Verifier(address,uint256,uint8)","f3c505c2":"updateInventories(uint256,uint256,uint256,uint16)","f3c50ce0":"CobeFriendCore()","f3c51c84":"_EnvoisTokens(uint256,uint256)","f3c537c5":"fint8(int8)","f3c64850":"amendedEarlyPurchaseIndexes(uint256)","f3c6a223":"Bifrost1Token()","f3c74496":"logWorkerStatement(string)","f3c78091":"AcceptingDepositsChanged(bool)","f3c7d275":"prenup(string,string,string,string,string,address,address)","f3c7e538":"set_successful_verifier(address)","f3c85eba":"compound(uint256,uint256,uint256)","f3c8f3ef":"startListing()","f3c8ffaa":"endPreICOStage()","f3c957f2":"haltCommitPeriod(address,bytes32,bytes32)","f3c95c60":"isValidUser(address)","f3c9a5cc":"CrowdsaleController(uint256,address,address,bytes32)","f3ca29b1":"ownerDailyWithdrawal()","f3ca2b54":"test_twoValidEqString()","f3ca5679":"Fund(address,string,address,uint256,uint256,address,address,address,address,address[],address[])","f3ca7425":"exercisePriceOf(uint256)","f3ca824c":"setStartCloseSale(uint256)","f3caad03":"isCitizen(address)","f3cb1805":"bidOnBreedingAuction(uint40,uint40)","f3cb8c31":"addEmployee(address)","f3cbc040":"checkVerify(bytes32,uint256,uint256,uint256)","f3cbe7b5":"exchangeableTokensFromStock()","f3cc2436":"maxPoolTotal()","f3cc6860":"setHash(bytes32,uint256,bytes32)","f3cca49a":"restoreUnsoldTokens(address)","f3cca5b4":"crowdSaleSoldAmount()","f3cca85a":"getInputAddress()","f3ccaac0":"image()","f3ccb401":"DistributeAirdropMultiple(address[],uint256)","f3ccc2f2":"buscarDocumentoPorQM(string)","f3cd1c28":"setTransfersAllowed(bool)","f3cd543f":"sendBoughtTokens(address,uint256)","f3ce2bc6":"_updateSaleAvgHistory(uint256,uint256)","f3ce40eb":"setSchellingRoundSupply(uint256)","f3ce782e":"LongBought(address[2],uint256[5],uint256)","f3cee129":"getOwnerServer()","f3cee64d":"setCmd(uint256)","f3d2f17b":"getData_22()","f3d2f824":"setXQU(string)","f3d305b4":"getBoostedProposalsCount(address)","f3d3402a":"changeBountyData(uint256,string)","f3d38a7b":"setBTBAddress(string)","f3d3d448":"setControllerAddress(address)","f3d3fce7":"settleLend(bytes,bytes,address,uint256,bytes,bytes,bytes,bytes)","f3d448d2":"countryInfo(uint256)","f3d47d1b":"transferAllFrom(address,uint256[])","f3d490db":"transferByPartition(bytes32,address,uint256,bytes)","f3d4b942":"emergencyFreeze()","f3d544d2":"FRTToken(uint256,string,string)","f3d6b54e":"setAirdropPrize(uint256,uint256)","f3d6cb29":"setLLV_edit_34(string)","f3d791ea":"submitTrade(address,uint256,address,bytes)","f3d79244":"frozenProfitDate(address)","f3d7bf1d":"privateStageTokensSold()","f3d7c6f7":"claimPrivateTokens(address[],uint256[])","f3d7e464":"EARLY_CONTRIBUTOR_VESTING_PERIOD()","f3d838a0":"Copyright()","f3d89c49":"setAutoCreationFee(uint256)","f3d91708":"isEligibleForUpgrade(address)","f3d97a25":"cancelTrade(address,address,uint256,uint256,uint256)","f3d9bc65":"sendBountyTokens(address,uint256)","f3d9eeec":"CourseChanged(uint256,uint256)","f3db09b8":"invoice(bytes32,address,address,uint256,uint256,uint256,uint64,uint64)","f3db4f2b":"retrievePieceFromEscrow(uint256)","f3dbaf0d":"removeVestingAdmin(address)","f3dd3d8a":"newCurrency(string,string,uint8)","f3ddb946":"bets_total()","f3de56de":"createNewSociety(string)","f3df0bbe":"startNewBallot(bytes32,bool,bytes32[])","f3df29b6":"periodITO_endTime()","f3e1cb63":"rsVerifyPublic(bytes32,uint256[2],uint256[],uint256[],uint256[],uint256[])","f3e1efbf":"validation_inviter(address)","f3e238d2":"StrongKek()","f3e2aa83":"requestReclaimEther()","f3e3c629":"testBalanceOfStartsAtZero()","f3e41a99":"addRound()","f3e4877c":"distribution(address[],uint256)","f3e4cac4":"_getTokenPrice()","f3e5c15e":"screenstate()","f3e62640":"buyToken(uint256,address,uint256)","f3e664c9":"setSaasApiProfitAddress(address)","f3e68264":"getSignerOfBalanceHash(address,uint8,uint256,bytes)","f3e71756":"checkTickets()","f3e84c4c":"FundingClosed()","f3e84cf3":"createNewRevision(bytes32,bytes)","f3e94596":"LogReferral(address,address,uint256)","f3ea1241":"releaseFirst()","f3ea4c68":"set_symbol(string)","f3eac094":"defaultAuctionPrice()","f3eb2445":"SimpleToken(string,string,uint256,address)","f3ec3f4a":"whitelistPreSaleAddressMany(address[],bool)","f3ecda21":"ITSM()","f3ece9f4":"addBlockList(address)","f3ed064a":"bonus01End()","f3edf112":"changeHelper(address)","f3ee6305":"removeCertificationDocument(address,bytes32)","f3eeb84b":"lastBlock_f9Hash_uint256()","f3eef981":"_init(uint40,uint40)","f3f10da7":"Balance(string,uint256,address)","f3f11048":"ethAddressPublicKey(bytes32,int256,bytes32,int256)","f3f16a15":"voted(address,bool)","f3f18615":"verifyTrustedSender(uint256,address,uint256,uint8,bytes32,bytes32)","f3f1b5a7":"CongressOwned()","f3f1d909":"redeemCoin(uint256,address,bool)","f3f1e4ea":"MenglaToken(address)","f3f2e656":"setAttributeSigned(address,uint8,bytes32,bytes32,string,bytes,uint256)","f3f2f0bc":"beneficiary2()","f3f31853":"getPayTable(uint16)","f3f43703":"pendingWithdrawals(address)","f3f458f8":"cycleCount_()","f3f480d9":"challengePeriod()","f3f4aef3":"getUserIDAndInviterEarnings()","f3f52865":"getPersonalStakeAmounts(address,address)","f3f6f0d7":"lastIndex()","f3f70674":"oracle_call(uint256)","f3f7650d":"fetchOrdersForMerchant(address)","f3f79a97":"setDebtIncreasingFactor(uint256)","f3f9240b":"investAs(address)","f3f969a0":"setRegisteredAuthority(string,address,bool)","f3f9c004":"reffalPool()","f3fa1e7b":"bulkApproveTransfers(uint256[])","f3fa2c37":"getUpdateHash(uint256,uint256,uint256,uint256)","f3fac412":"_calcEndTime(uint256)","f3fb9a02":"setInfo(uint256,uint256)","f3fbabb5":"setDedicatedProxy(address)","f3fbfc60":"SFTSEV()","f3fc536d":"revokeConfirmation(bytes32)","f3fc7fb2":"Ordient()","f3fce3b5":"setC4FContractProviderCompleted(address,bool)","f3fd826f":"transferFromTokens(address,address,address[],uint256[])","f3fde261":"onTransition(bytes32)","f3fe12c9":"claim(string)","f3fe5bc2":"totalWitdrowedToken()","f3fef3a3":"withdraw(address,uint256)","f3ff10bf":"UseQuantity(int32)","f4009d99":"changeMainStartTime(uint256)","f400a3d7":"finishDate()","f400d37b":"yesVoteSum()","f400fde4":"amount1()","f4010db0":"deleteTile(uint16)","f4016ac3":"setInitialState(address)","f4016b17":"destroyBPESOToken(address,uint256)","f4025568":"approveCertificate(uint256)","f4029e92":"getMonsterReturn(uint64)","f40314f4":"tokenCurrentStage()","f4044697":"xrateProviders()","f404d1e2":"transferAndCall(address,uint256,bytes,string)","f404df8e":"_getExpectedRate(address,address,uint256)","f405311b":"Made(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)","f405a275":"EventJoinedBattle(address,uint256)","f4064471":"messagePreSignedHashing(bytes8,address,address,uint256,uint256,uint256,uint8)","f4071928":"mintAuditApproval(address,address,uint256)","f407c81d":"tokenNoByAddress(address)","f408ebe9":"dev_reset()","f409a609":"internalMintToken(uint256)","f409ab66":"getDepositedCount()","f409e633":"SetENGDevAddress(address,address)","f40a049d":"triple(uint256)","f40a9112":"whaleIncreaseLimit()","f40c0843":"subscribe(address,uint8,bytes32)","f40d71f1":"releaseTokens(address,uint256)","f40d8d8f":"updateAllowance()","f40e0b6e":"coinsToSell()","f40e28f2":"createGen0Auction(uint256,uint256,uint256,uint256,address)","f40e8d8b":"retryWinner(uint256)","f40ea5cb":"setReservePricing(uint256)","f40ebcf3":"setBalanceOfValueFor(address,uint256)","f40ef739":"preIcoEndsAt()","f41017fc":"finalize(uint24)","f410a26b":"receive(address,uint8,uint32[])","f410aa39":"_issueByPartition(bytes32,address,address,uint256,bytes,bytes)","f4116381":"setFiscal(bytes32)","f411fb21":"freezeWithdraw(address,uint256,bool)","f41293c7":"getIndexForTeamId(uint32,uint32)","f412af91":"getOuvidoriaEndpoint(address)","f41377ca":"setFoundationAddress(address)","f41440d9":"setCreator(address,address)","f414cccb":"removeFreezableAddresses(address[])","f4156757":"TeamPoolAddress()","f415ed14":"slash(bytes32)","f4162530":"nodeFee()","f4163340":"isFailed()","f416d2cb":"emitTokensSince()","f417614a":"validateAndReturnContribution()","f418b153":"replaceMarketingToken(uint256,uint256,uint128)","f418cf4e":"recordSenderIfNecessary()","f4199bb8":"initializeWhitelist(address[])","f419c69d":"_createPony(uint256,uint256,uint256,uint256,address)","f41a12c8":"_takeOwnership(address,uint256)","f41b536e":"getRecipientString()","f41bfa9e":"mint(int256,uint256,string)","f41c1c93":"setAnswerFee(uint256)","f41c639e":"sendMsg()","f41d0b0c":"getInfluencer(string)","f41d1a82":"partner1_name()","f41d97fc":"getPriceOfTokenInLastAuction(address)","f41db329":"addAuction(uint40,uint40,uint128,uint40)","f41dc25f":"totalWeiLose()","f41e3494":"hasFailed(uint256)","f41e60c5":"enableTransfers(bool)","f41e8fc8":"periodAmount()","f41f4b10":"retrieveHouseTake()","f41fa999":"TTest()","f4201c3c":"isVIP(address)","f4206706":"withdrawEthers(uint256)","f420977d":"noOfTokenAlocatedForSeedRound()","f420c5b1":"getCloneWallets(uint8)","f420d9d2":"setNumRewardsAvailableForAddress(address,address)","f4217648":"setWhitelist(address[])","f421e02b":"testCantFinalizeWithIncorrectCap()","f42206d1":"HouseEdgeUpdate(uint256)","f422878a":"addressIsStakeDiceGameContract(address)","f42355a4":"isSaleInitialized()","f4239eec":"affiliatePercent()","f4246be4":"addToBundle(bytes32,bytes32)","f4250f75":"AgriChainPrevData()","f42541be":"promoToonsMinted()","f42598f0":"get_mintable()","f4268e46":"g17token()","f426ceee":"award(bytes32,uint256,address,bool,uint256)","f426d8ac":"withinHomeLimit(uint256)","f426f03a":"setFrequency(uint256)","f427211c":"getTime2(address)","f4279d1f":"updateEthUSDOracle()","f42a2c42":"removeAssetListing(uint256)","f42aa287":"getBlobStore(bytes12)","f42ac1de":"minQuorum(uint256)","f42b1ae0":"unPauseGame()","f42b9999":"icoMinInvest()","f42c051e":"submitTokenToEthOrderWHint(uint128,uint128,uint32,int256)","f42c0f02":"MARKETING_SHARE()","f42c56c2":"cbrt(uint256)","f42ca2ee":"sub_32(uint32,uint32)","f42d1d30":"creditorAmounts(uint256)","f42eb765":"getAgreement(bytes32)","f42ef9ec":"emitWithrawalRequestEvent(address,address)","f42f0c7d":"lengthOfCommonPrefix32(bytes32,bytes)","f430511a":"setMaxAddresses(int32)","f43098af":"resetTokenOwnership()","f4320f00":"getProjectUnusedTokens()","f4325417":"App(address,string,uint256,string)","f4325d67":"reserveToken()","f43313b6":"assertEq31(bytes31,bytes31,bytes32)","f433262f":"updateFromRegistry()","f4338e89":"getAllTeamCosts()","f433e12e":"marketingTokenWallet()","f4347267":"getX(bytes)","f434e028":"PreICOProxyBuyer(address,uint256,uint256,uint256)","f4351908":"InitialRateChange(uint256,uint256)","f4351e15":"addAndMintPlayers(uint128[],bool[],uint256,uint256,uint256)","f43532ac":"changeWaveVoteContract(address,string)","f435d012":"setUnitJadeStealingIncreases(address,address,uint256,uint256,bool)","f435f5a7":"lock(address)","f436de14":"setAllowanceValue(uint256)","f437bc59":"host()","f437d6bc":"objectShield()","f4381136":"DeferredPresaleTokenPurchase(address,address,uint256,uint256)","f4385912":"getPlayerId(uint256)","f4385eaf":"KPISToken()","f4387d86":"arbitrateApproveMilestone(uint256)","f4395dbc":"bitmcoinToken()","f4399f2d":"MDIToken()","f43a72b0":"setactive(bool)","f43abdf3":"getCrowdsaleUserCap()","f43acb52":"checkLottery(uint256)","f43b1620":"addUserAuto()","f43b4808":"viewPassword(uint256)","f43b7a76":"AdmineAdvisorTokens()","f43bac53":"poolFeeIncurred(uint256)","f43e34b2":"unFreezeAll(address)","f43e3918":"MELON()","f43e98c7":"refunding()","f43f523a":"mod(uint256,uint256)","f43fd7e0":"_handleTrainingFailure(uint256,uint256,uint256)","f4412803":"currentTotalAirDrop()","f44191f0":"getAccessoryByIndex(address,uint256)","f441b1c8":"currentAmount()","f4424cac":"getNumberOfLogEntries()","f44349dd":"angelTokenSupply()","f44376a2":"preFixed(address,uint256)","f443ea83":"MindHacker()","f444c136":"createDklAuction(uint256,address,uint16,uint256)","f444ea30":"allowBack()","f4451628":"buyHSShop(uint256)","f44544b3":"fundPos()","f4462d04":"periodicity()","f44637ba":"addBurner(address)","f4463fb7":"emergencySelfDestruct()","f446c1d0":"A()","f449619e":"collectPrize(uint256)","f449958d":"deliverManagementTokens(address)","f449c3cb":"_presaleSupply()","f449ffe4":"setPresaleRate(uint256)","f44a06b9":"endIcoSaleRound1()","f44a6ca9":"addProduct(address)","f44b43f8":"approveAmount(uint256,address,uint256)","f44b54ca":"functionName1(bytes32)","f44b79b3":"withdrawalAll()","f44bd811":"TRCERC20(uint256,string,string)","f44dc562":"_addKey(address,uint256)","f44e1351":"setEpisodeManager(address)","f44f13d8":"assert2()","f44f8be9":"sendNegReq(uint256,uint256,uint256,string)","f44ff712":"blockHeight()","f450096f":"updateOraclizeGas(uint256,uint256)","f4500eb5":"ETHERCFeeModifiers()","f4508082":"_price_token()","f4509fc2":"LOCKED_1Y_DATE()","f450b574":"_mixer()","f450cfee":"disablePrivileged()","f450d53a":"allFinalised()","f450e5f8":"TOKENS_SOLD_LIMIT()","f4510455":"STQPreICO2TestHelper(address,address[])","f4514ca6":"buySome(uint256,uint256,uint256,uint256,uint256)","f4519035":"betOdd()","f452b69c":"getCommandTokens()","f452f32d":"getByTo(uint256,uint256)","f45346dc":"deposit(address,uint256,address)","f45392fb":"getReportingWindowByMarketEndTime(uint256,bool)","f453c827":"getAddressField3()","f4544255":"refer(address,address)","f454c32c":"teamReserveTokensDistributed()","f4559619":"newOwnerTemp()","f4560403":"Zero()","f456106d":"ProdCToken()","f4572664":"changeMinimumPurchaseAmount(uint256)","f457361a":"paidversion()","f457547a":"spreadPercent()","f457688d":"can_i_jump()","f4577298":"EthGet()","f457ee5a":"donation(address)","f45811bd":"Voyager()","f4586cba":"setVestingRevokeDate(address,address,uint256)","f4591074":"finishInvite()","f45934b6":"cards_gold_total()","f45984fd":"TOKEN_UNIT_RATIO()","f459eb61":"generateKeccak256(bytes)","f459f517":"dividendsPoolAddress()","f45a729c":"getEtherValue(uint256)","f45b106a":"increaseMonthlyTransactionVolumeReceiving(uint256)","f45b4fba":"setPersonalBonus(address,uint256,address,uint256)","f45b96a0":"financePeriodsCount()","f45c85e5":"currentOwnerFeePercent()","f45ce8d7":"setAddressKYC(address,bool)","f45dae6e":"parseLoanOfferRates(uint256[7],uint32[4])","f45e29bb":"hashCoin()","f45e8dc4":"buyWarlordChest(uint256)","f45eb5b4":"_generateRandomhashNumber(string)","f45ef033":"nextReduceSupply()","f45efe88":"stage1Bounty()","f45f74f8":"VerityToken()","f460473e":"fillArray()","f460590b":"updateSigner(address,bool)","f460c5e4":"listItem(uint256,uint256,uint8)","f460e5d0":"setRamenContract(address)","f461847c":"DatGirl()","f4619e71":"NokuCustomERC20Service(address)","f461db0e":"teamAllocatedTime()","f4623e0b":"addBalance(address,address,uint256,uint256)","f462671e":"isAuthDisabled(uint256,uint256)","f46332e0":"test_claimShare_emptyFeeAndRewardPools()","f4635674":"countryOwnersOf()","f4637003":"transferChildren(address)","f463be37":"setSecondAddressBalance(address)","f463edd1":"createDocument(uint256)","f464e64e":"premiumPacks(uint256)","f464e7db":"sellToken(address,uint256)","f4656219":"PRICE_RATE_FOURTH()","f4660ff5":"timeVault()","f4662f71":"canUnshelf(string,address)","f466f106":"addHouseHold(uint256,uint256,uint256)","f4674b89":"withdrawByAdmin(address,uint256,address)","f4686b42":"GxAdminOperations(address)","f468e9b3":"inICO()","f469707f":"addToGoldList(address)","f46b5321":"calculatePoolAmount(uint256)","f46b986a":"secondExtendedBonusSalesEnds()","f46bbc09":"thirdStageTokenRate()","f46c0f29":"compensate(uint256)","f46c50dc":"doFail()","f46c858a":"addAdvisor(address)","f46d1982":"setup(address,uint256)","f46d91f4":"TokenBurn(uint256)","f46da084":"createName(string,string,string,string,bytes32)","f46de44a":"Etherumchain()","f46eccc4":"minters(address)","f46f16c2":"MARKET()","f46ff44f":"dollarToEtherRatio()","f4700d3e":"lpMaxVolume()","f4703d26":"numbersCountMax()","f47073f4":"setTotalIncomeFeePercent(uint256)","f470fd5e":"BLU()","f47125f5":"StableICO()","f471e626":"disapproveByC(uint256,string)","f47279d2":"capRemaining()","f47289e1":"_ecDouble(uint256,uint256,uint256)","f472d615":"enableIco()","f472e136":"fraction(int64,int64)","f4734818":"_random(uint256,uint256,uint256,uint256,uint256)","f4736429":"changeUnicornRanchAddress(address)","f473c484":"BatchDetachAssets(uint256[10])","f4749624":"dist_list_set(address[],uint256[])","f474b6b2":"aboutWorker(address)","f4752806":"convert2PeonyToken(uint256)","f4757a49":"HighestBidIncreased(address,uint256)","f47599db":"WLMTBounce()","f4773d26":"AESSignatum(uint256,string,string)","f47760ac":"forceGame(uint256,uint256)","f47795f3":"CommonTokensale(address,address,address)","f477a6b7":"depositEthers()","f477c2b9":"setColdWalletAddress(address)","f4784b37":"placeCube(uint256,uint256,uint256,uint256,uint256)","f478cef1":"leader_2()","f47a6e84":"getReleased()","f47aa124":"AutoSplitCurator(address)","f47b7740":"information()","f47c84c5":"MAX_TOKENS()","f47cd133":"AMBASSADOR_FOUR()","f47ce310":"getRoomCurrentSet(uint256)","f47efbca":"getMemberLinks(address)","f47f5921":"exerciseOption(address[3],uint256[3])","f4807a4d":"downTickTest(address,uint256)","f4812eb9":"tokenIdToPrice(uint256)","f4814444":"_withdrawBalance()","f481d2d0":"BaseFareCalculator()","f4833360":"getTeamInfoByID(uint256)","f48339e4":"MintingEnded()","f4835aea":"postHardRate()","f4838452":"loseWager(address,uint256,uint256,bool,uint256)","f484e827":"slashSmallUsername(bytes)","f48513ed":"setFundOnContract(bool)","f4869726":"buyWithSignedAddress(uint128,uint8,bytes32,bytes32)","f487404f":"oldOwner()","f487c403":"DataStore(string)","f487e4b6":"SendERC20ToAsset(address)","f4880b22":"transferStatus()","f489faf9":"addAddressToBonuslist(address)","f48a3f2b":"PlazaToken(uint256,string,string)","f48aa044":"upgradeEthCost(uint256)","f48b4391":"SBToken(address,address)","f48be22b":"initialiseAllocations()","f48c157d":"createGame(string,bytes32[])","f48c2afa":"PVCCrowdsale(uint256,address,address)","f48c3054":"proxyPayment(address)","f48c4633":"disableRefunds()","f48d11af":"removeFromVIPList(address[])","f48d371c":"create(uint256,uint256,int256,address,address)","f48d60ca":"hasOwner(uint256)","f48e20f2":"getCreateFeeWindowUniverseValue()","f48e5f27":"infoWithdraw1()","f48e9c33":"ETPotatoPresale(address,uint256,uint256)","f48edf0c":"partner(address,address)","f48f3ced":"HFCoin(string,string)","f4903ca0":"newContract(string,address[],string,bytes32,uint256)","f4914919":"incrementContinuityNumber(uint32)","f4915f5f":"BHM()","f4916f05":"VoteSvp002(address,uint256,uint256)","f49259b7":"UpgradeableToken(address)","f49296ae":"WasHere()","f4929cc5":"initPair(address)","f492a72f":"signUp(address[],uint256[],string)","f493c848":"transferMultiply(address[],uint256[])","f49501f3":"soldOnCurrentSale()","f4954387":"setHalt(bool)","f49627be":"Technology4G()","f4970e71":"approveWithdrawal(address,uint256)","f49727bd":"getSkillEvaluation(address,uint256,uint256,uint256,address)","f497463a":"setVariables(uint256,uint256,uint256,uint256)","f49808ea":"addEthForPayment()","f4993bbd":"executeEmergencyWithdrawal()","f499a349":"NewPrefixPrice(uint256,uint256)","f49a5504":"permittedInvestors(address)","f49a616c":"updateFeePayoutAddress(address,address)","f49a66fd":"_pushLandId(uint256,uint256)","f49b728e":"setAllResourceERC20Addresses(address)","f49b8e10":"BelezaNetwork()","f49bb5a8":"numberPlateExist(address,string)","f49bbb23":"getUserClientsCount(address)","f49bff7b":"getBounty()","f49d1d19":"viewSellOffersAtExchangeMacroansy(address,bool)","f49dec70":"buyPepeAffiliated(uint256,address)","f49e8135":"calculateTokenBuySimple(uint256)","f49eee20":"priceFactorB()","f49f0974":"proxyList()","f4a011be":"transferWithReserving(address,uint256)","f4a05f8f":"_transferAsset(uint256,address,bool)","f4a1585b":"setNextCycle()","f4a222e9":"icoRaisedETH()","f4a32ef8":"bonusTokensSold()","f4a43448":"getEstateSize(uint256)","f4a475cb":"t_ImmlaTokenDepository()","f4a4b8c7":"OfferUnHold(uint256,bytes,bool,address)","f4a67395":"showAddresses()","f4a6ef99":"logBytes(bytes32)","f4a81d08":"getKudosGiven(address)","f4a8619a":"prep(address,uint8)","f4a8a699":"_mint_with_uri(address,uint256,string)","f4a8cbc0":"tokensToWei(uint256,uint256)","f4a92020":"rawApprove(address,bytes32)","f4a972de":"softEthTransfer(address,uint256)","f4a9c919":"startThinking()","f4a9df62":"annul(address)","f4aa1291":"withdrawFundsAdvanced(address,uint256,uint256)","f4aa956c":"preIcoIsRunning()","f4aac034":"charityFraction()","f4ab2928":"isContractPaused()","f4ab2b19":"releaseAllOldBalanceOf(address[])","f4ab4d1d":"_getPetAura(uint256)","f4ab9adf":"addVoter(address)","f4ac6560":"batchVipWtihLock(address[],uint256[],bool)","f4acc2ed":"setContractAdmin(address,bool)","f4accda5":"order(uint256,uint256,address)","f4ace1a5":"processContribution(address,uint256)","f4ad2212":"EthereumEmerald()","f4ad8e37":"listings(uint64)","f4ae0d2f":"getTechBonus1(uint256)","f4ae2164":"EDToken()","f4ae67a1":"setTargetDiscountValue9(uint256)","f4af9146":"setDefaultTranche(bytes32[])","f4afbdca":"assets_explorer_controller()","f4b0ce03":"NewIssue(address,uint256,bytes)","f4b103d4":"SimpleStorage(uint256)","f4b186a7":"setProfitOwner(address)","f4b272db":"licenseAttributes(uint256)","f4b28747":"CaptainToken()","f4b2dfea":"Matching_Finneys()","f4b2f5b6":"maxTokenSupplyICO1()","f4b43268":"phrase()","f4b432b8":"validUser(string)","f4b489e7":"upgraded(address)","f4b4d77e":"cutOf(uint256)","f4b5cbc4":"setCrowdSale(address)","f4b74ae9":"updateBestInvestor(address,uint256)","f4b79379":"generalRate()","f4b86c48":"isMarketplace()","f4b95676":"IsReady()","f4b96570":"greet_omar(uint256)","f4b97c4c":"insertNode(bytes32,bytes32,bytes32)","f4b9fa75":"dai()","f4ba89f9":"escrow_fee_numerator()","f4bbd5d4":"getDealByNumber(uint256)","f4bbfd6a":"scheduleCall(bytes,bytes)","f4bd0bcf":"isConditionMet()","f4bd0eb2":"getSplit(uint256,uint256,uint256,uint256)","f4bd65a7":"_updatePhaseTimes()","f4bd9429":"unassignOwner(address,address)","f4bead6e":"percentageToToteLiquidatorWallet()","f4bebac2":"winner_bids()","f4bffad6":"bonusForMainICO()","f4c06c8e":"removeConfirm(bytes)","f4c140b2":"setArtistFees(uint256)","f4c28ea3":"lowerLimitForToday()","f4c2ebdd":"createLandAndAuction(address,uint256,address,uint256,uint256)","f4c38aa1":"initLending(address,uint256,uint256)","f4c3f3f7":"fetchAllDataForCustomer(address)","f4c52644":"requestRefundDonator()","f4c5ab7c":"validateCallGas(uint256,uint256)","f4c679db":"Gidnist(address)","f4c6f423":"requestWarranty(string,address,uint256,uint256)","f4c7f92c":"newRubesUntilPayout()","f4c84d19":"update(string,string)","f4c91807":"calculateCurrentPrice_(address[7],uint256[7],uint8,uint8,uint8,bytes,bytes,bytes)","f4c97199":"updateNextGamePotSplit(uint256)","f4c99177":"setBlocksPerPayPeriod(uint256)","f4c9b1fd":"campaignState()","f4caee88":"isParticipating(address)","f4cb09cf":"setAmbassadors(address,bool)","f4cb4ae3":"tokenCreationMaxPrivateSale()","f4ccbc4f":"getWithdrawals(address,address)","f4ce66e0":"extractUint(bytes,uint256,uint256)","f4ce7c1c":"purchaseWithEther(uint256)","f4ce7d4a":"ChannelContractAddressChanged(address,address)","f4cebdc2":"HeroCore()","f4cee3b5":"jasontestToken()","f4d0b2a5":"RefundInvestorsBallot(address)","f4d0b67f":"SetTime(uint256)","f4d176e1":"mapMaster()","f4d21515":"submitQuery(uint256)","f4d218f9":"lastBlockClaimed()","f4d22b02":"transferMoreETH(address,uint256)","f4d24fea":"setItem(uint8,uint8,uint256)","f4d26fec":"upgradable()","f4d28ab0":"Update_START_PREICO_TIMESTAMP(uint256)","f4d2cac3":"setBonusSale(uint256)","f4d3e94f":"weiRaisedInPresale()","f4d44b72":"getBoardsCount()","f4d48c0d":"channelParticipant(uint64,uint64)","f4d56a51":"isIdValid(bytes16)","f4d5d6ce":"seriesBSupply()","f4d64745":"HgcToken()","f4d76b60":"postValidatePurchase(address,uint256)","f4d7b725":"GasPrice()","f4d87f8a":"WW3Token()","f4d92886":"test_shutDownVersion()","f4d94699":"EndowmentRetriever()","f4d957a5":"test_validProxyFundTransfer()","f4da6a54":"AUTHORSIGHASH()","f4da834c":"cancelAuctionToBuy(uint256)","f4daa98c":"BitcoinFuture()","f4dadc61":"locks(uint256)","f4dae266":"total_wei_given()","f4dafe71":"update_hash(bytes32)","f4db9ad1":"bountyOnlineTokens()","f4dba182":"take(uint256,uint256[])","f4dbeb9d":"getCredRanksByContents(address,uint256[])","f4dc2d21":"Deed(uint256)","f4dd0fe9":"ico1Max()","f4ddca3c":"shortenBonusPreIco(uint256)","f4ddff1c":"_teamID()","f4de8dfe":"generateUID(uint256,uint256,uint256,uint32)","f4def44b":"getStaff(uint256)","f4df1fb2":"themedSpinners(uint256)","f4df80ee":"subUserTokens(address,uint256)","f4e0f412":"exec(address,uint256)","f4e1358a":"transfer_enabled()","f4e2d68b":"ltcBalance()","f4e340ac":"RedFoo()","f4e36afd":"findThroneByNameHash(uint256)","f4e3be2d":"getSpawnProxy(uint32)","f4e42844":"ResetTransferState()","f4e50a4d":"getSupportedTokenByIndex(uint256)","f4e62c34":"OrigoToken()","f4e68486":"weiICOMinimum()","f4e6a70d":"addAnimalType(uint128,uint8)","f4e6d3f9":"calculateLockedPercentage(uint8)","f4e733c3":"lifeTime()","f4e75b79":"OwnershipTransferProposed(address,address)","f4e76a46":"getBalanace(bytes32,address)","f4e83593":"Volunteertimedollartocken()","f4e96093":"IntimateShoppe(uint256,uint256,uint256,address,address,address,address,uint256,uint8)","f4e9c944":"PRE_ICO_START_TIME()","f4ea7263":"Take_share_team_AES()","f4ea77f3":"coinPool()","f4ea95b9":"validateReleaseVersion(uint32[3])","f4eb20da":"SNC()","f4eb6889":"description1()","f4ebed78":"currentReward(uint64)","f4ec186d":"MoonCoin()","f4ec593d":"ICOCrowdsale(uint256,uint256,address,address)","f4ed0f46":"editionSize()","f4ed216c":"removeExchangePartnerTargetAddress(address)","f4ed660f":"testIfElse()","f4eda76a":"traitIdxToName(uint256)","f4edb15b":"narcosByOwner(address)","f4ee82ee":"TOKEN_SECOND_DISCOUNT_MULTIPLIER()","f4ee9efe":"mintPartOfEmission(address,uint256,uint256)","f4eef932":"deptcheckapproval(string)","f4efa24c":"getConsensusDetails(address)","f4f0b6e5":"investorDate(address)","f4f0dafd":"T0XToken()","f4f0fc21":"raiseCap(uint256,uint256)","f4f22662":"setPersonalBonus(address,uint8)","f4f27042":"open(address,address,uint256)","f4f3122e":"startSale(uint256,uint256)","f4f3b97c":"updateSubjectMatter(uint256,string)","f4f3bdc1":"minus(uint256,uint256)","f4f3c8a4":"comment()","f4f42246":"percentageCut()","f4f4d237":"getById(uint256)","f4f572ae":"CMO_Signature()","f4f59992":"m_analytics()","f4f5b30f":"unitTestGetAvailableReward(uint256,uint256)","f4f5e1c1":"SHARE_BOUNTY()","f4f61563":"setInviteeCount(address,uint256)","f4f6d6fe":"weiMinSale()","f4f724b3":"getEmployerJobsByStatus(address,address,uint8)","f4f7c6c2":"disagreeWithdraw(uint256)","f4f864f0":"STARBITToken(address)","f4f87730":"create_token(uint256)","f4f94a40":"ownerSetRandomGenerateMethod(uint256)","f4f96d29":"smartWallet()","f4f98ad5":"commit(uint256)","f4f996d5":"WandtChain(uint256,string,uint8,string)","f4fa6c1d":"blockheight()","f4fa8603":"fabricTokenSafe()","f4fab748":"end2Timestamp()","f4fb6789":"tknfwdToken()","f4fb7d4e":"m_nonEtherController()","f4fba1bc":"executeProof(bytes32[],uint256)","f4fc3570":"disableController(address)","f4fc5d13":"RevealBet(string)","f4fd326c":"SuperCarbonCoinToken()","f4fde3b6":"sendMoneyOwner()","f4feccbb":"LogUserUnRegistered(address)","f4ff56f4":"ProposalCloned(uint256,uint256,uint256,string,bytes32)","f4ff78bf":"changeMaster(address)","f4ffa7a9":"getMountTokenIds(uint256,address)","f50059b6":"reconcileDividend(address)","f500a0a3":"VeritasToken()","f5012d4b":"sendOtherTokens(address,uint256)","f5015000":"setMaxCharacters(uint16)","f5018d1c":"IronHands2()","f501af70":"OpenLongevityPresale()","f501d8b8":"transferFromICO(address,uint256)","f5023de9":"founder2Wallet()","f50249fc":"totalSupplyMax()","f502cdc0":"distributeNIM(address[],uint256,uint256)","f5037b2a":"addressLength(address,address)","f503a994":"leaveTeam(uint256,uint256)","f5042801":"setAsRefunded(address,uint256,uint256)","f504b089":"memberKeys(uint256)","f504e0da":"load_level(uint16)","f504efa7":"popHatch()","f50522ca":"setNote(uint256,bytes32,string,string)","f5059560":"makeProject(string,uint256,uint256)","f505a299":"getLLV_edit_32()","f505a92d":"reserveFor(address,uint256)","f505eb6e":"WolkDestroyed(address,uint256)","f505f5f7":"quicksort_core(uint256[],uint256,uint256)","f506d7e5":"getCompte_31()","f506fc54":"acceptValentineRequest(address)","f5074f41":"destroyAndSend(address)","f5088730":"copy(uint256,uint256,uint256)","f509078f":"isForAuction(uint256)","f5093ab4":"UpdateState(uint8,uint8)","f509b627":"confirm(address,uint224,uint32,address)","f509c554":"PIPSCHAIN()","f50a2644":"canCompleteContribution(address)","f50aac53":"register(address,string,uint8,string)","f50ab247":"StopGame()","f50ab7b0":"updateCoupleImageIPFShash(bytes)","f50acfa0":"transferToParent(address,address,uint256,uint256,bytes)","f50b486d":"getTokenIdsIndex(uint256)","f50b5308":"PRICE_MULTIPLIER_ICO1()","f50b769e":"lastEditionOf(uint256)","f50bab3f":"distributeCRTM(address[],uint256,uint256)","f50ca46a":"hasICOFinished()","f50d3914":"resetFoundationtList()","f50ebd21":"OHGLuangPrabang()","f50ecf0b":"basicIncomeLimit()","f50f1ba9":"_getRevisionTimestamp(bytes32,uint256)","f50fc02e":"flipsLost()","f510371a":"deleteOperation(bytes32)","f510c329":"EmitTransactionDetails(address,uint256,uint256,uint256,string,string,string)","f510ccd3":"CancelAuction()","f51119db":"checkAuditor()","f5112373":"testFloatArray()","f5112f87":"welcomeBonus()","f512106a":"testStringKeyValue()","f5122232":"LogAccess(address,bytes32,address,bytes4,bool)","f513a671":"soldItems()","f5143b1c":"HNContract()","f514e92c":"TARGET_DURATION_BETTING_BLOCK()","f514f0f9":"STAGE_THREE_TIME_END()","f5156fba":"CECToken(uint256,string,string)","f5166eea":"reservedTokensLockedPeriod()","f516e9ec":"ethDeltaDepositAddress()","f5173120":"TOKEN_FIFTH_PRICE_RATE()","f518e66d":"_addStakeholder(address)","f5194ae2":"MainToken()","f5195b62":"c_dateTo()","f5196002":"getBOPCount()","f519618f":"addMultipleTier2Members(address[])","f51b793a":"get_appuration(uint8)","f51c2907":"affiliatThreshold2()","f51c755b":"testConcatMemory33Bytes()","f51cbc72":"Level()","f51d0c6f":"_awardForRecommender(bool,uint256,uint256)","f51d1399":"reduceBalance(address,address,uint256)","f51d401f":"getStageStartTime(int256)","f51d4cb1":"getCurrentVUPRate()","f51d61ff":"Thanatos()","f51d7d5f":"getTitle(address)","f51dcaa7":"AVGONE()","f51e181a":"scale()","f51f4738":"setCompleted(bool)","f51f5e78":"addPlayer(bytes32,bytes32,bytes6)","f51f96dd":"salePrice()","f51fb6a1":"leftInTier()","f5207c31":"businessPlannedPeriodDuration()","f5218ec2":"increaseRepAvailableForExtraBondPayouts(uint256)","f522ec0e":"_refundTokens(address)","f52343f4":"flipExecutionSwitchTo(bool)","f5235a46":"withdrawFoundersTeamAndAdvisors()","f5238546":"stopInvest()","f5238660":"totalMarketingFundMinted()","f524613f":"freeze(address,uint256,uint8)","f5251269":"ETHDividends()","f5254af8":"startPriceForHLPMT()","f5258aee":"ContractAdded(address,uint256)","f525cb68":"poolCount()","f525dcf1":"setLockFund(address,uint256)","f52706c9":"setMinResalePercentage(uint256)","f527c856":"TOKENS_PER_KETHER()","f527dd6c":"_emitSkillSet(uint256,uint256,uint256,bytes32)","f5292748":"_stakeContent(address,bytes32,uint256,uint256,bytes8,uint256,uint256)","f5298aca":"burn(address,uint256,uint256)","f529d448":"changeBalance(address,uint256)","f52a41f3":"mintOWL(address,uint256)","f52ad690":"badgeUnFreeze()","f52ae24b":"transmute(address,uint256)","f52b8d1f":"tokenReserved1Deposit()","f52bbc2d":"withdraw(address,address,uint256,uint256,address)","f52bd7cb":"addSwap(bytes5,bytes5,bytes32,bytes32,bytes12,bytes32,bytes32,bytes12)","f52c456f":"_createClown(uint256,uint256,uint256,uint256,address)","f52f2526":"exerciseOption(uint256)","f52f77b2":"createEntity(address,address)","f52fa89b":"evolveGeneration(uint16)","f52ff1da":"SDT(address)","f530259e":"isBlacklistDestroyer(address)","f5308c7d":"removeTransferLock()","f5318389":"setEmbassyCtrl(address)","f531aff2":"THINK_TANK_FUND_TOKENS()","f531cc63":"LogCreateEVN(address,uint256)","f531dbbf":"TOKEN_SWAP_DURATION_HOURS()","f5323da4":"phase_5_bonus()","f532e888":"getBookForUser(uint256)","f5336737":"BFTcoin()","f5341b4e":"UserTipped(address,bytes32,uint256,bytes32,bool)","f5343752":"exchangeEnabled()","f534b022":"burnleftToken()","f534d187":"girlBasicToken()","f536c61a":"deleteAllChildren()","f5370884":"WithdrawalVotedEvent(uint256,address,uint256,uint256)","f5376e49":"TestingToken(uint256)","f53773dc":"withdrawBattleValue(uint256)","f5383f3a":"getFoundationStatus(address)","f5385345":"acceptOwnershipOffer()","f53995ff":"setIncludeAuctions(bool)","f53a93f8":"MyFinalizableCrowdsale(address)","f53b0b3a":"_regularDonationsTotal()","f53b396b":"SimpleTokenCoin()","f53b8ded":"mintPreSaleTokens(address[],uint256[],uint256[])","f53bc835":"setMaxBuy(uint256)","f53bde25":"RATE_PRIVATE()","f53c5c87":"setTileContract(uint16,uint16,uint8,address)","f53d0a8e":"administrator()","f53d9d58":"AddLiquidity(uint256)","f53da97e":"currentSalePhase()","f53f43d9":"setcapname(string)","f53fb0cb":"isCollectionAllowedAt(bytes8,bytes8,uint256)","f53fbaf6":"send_ETH_from_contract(address)","f53fd201":"_modifyPixelColor(uint24,uint32,address)","f54011f5":"blockExternalTransfer()","f54095a7":"standart()","f5414023":"claimReward(bytes32)","f5419108":"view46()","f543d3c6":"Stockfinex(uint256,string,uint8,string)","f544cf4f":"decayedPriceOfCard(uint256)","f545118b":"subdividendsOf(address)","f54575d6":"addAdvisor(address,uint256)","f54580cc":"card_blue_minamount()","f5459d6b":"INVESTOR1()","f5462105":"isFundedMax()","f546232d":"ComputeMyEggs(address)","f5465992":"totalTokenBalance(address)","f5470d7b":"itemType()","f5486860":"nextPrizeTime()","f548a578":"removeBurnupGame(address)","f549dd0e":"Vitamin()","f54a2ddc":"setRefundable(address,uint256)","f54b384d":"withdrawBuildingTokens(address)","f54cc2d0":"mintTokensForServices()","f54d28ae":"OPSPoolAddress()","f54d41db":"updateInventories(uint256,uint256[],uint16)","f54da8ee":"addWasteType(string)","f54dbf4c":"Emission(address,uint256)","f54dd191":"Flag()","f54dd974":"setResourceERC20Address(uint16,address)","f54e3977":"BTML()","f54e7a40":"offlineTransaction(address,uint256)","f550cb45":"rank(address,uint256)","f551924c":"testpidgeon()","f5519e8d":"WanChainToken()","f55206a5":"validatePurchase(address)","f5521bf1":"loanDuration()","f5529d3f":"ESIT()","f552b2ba":"threads(uint256)","f552d91b":"tokenToTokenTransferInput(uint256,uint256,uint256,uint256,address,address)","f5537ede":"transferToken(address,address,uint256)","f5539407":"getInvestorInforAddr(uint16)","f554567f":"getTeller(address)","f554e8cc":"officialHold()","f554e934":"TOKEN_COMPANY_OWNED()","f55523e7":"fiat_contract()","f5552b42":"wotDay(uint256)","f5556d78":"Vegas()","f555b815":"rate2()","f5562753":"getClaimAmountForBlock(uint256)","f5582870":"CENTS()","f559417c":"finalizebackup()","f559468c":"initiallyLockedAmount(address)","f5596659":"HoloWhitelist()","f5597e21":"addProperty(string,string,uint64,uint64,uint64)","f55ab987":"penalizeInactiveJuror(address,uint256,uint256[])","f55b23c0":"externalLeave()","f55b39a3":"PetCore()","f55b8fc9":"setraisedAmount(uint256)","f55bddcc":"NFTAuctionBase()","f55befee":"TOURNAMENT_TOKENS_PERCENT()","f55c9f60":"developerReserve()","f55ecf06":"setExchangeRate(uint256,uint256)","f55f41f9":"Version(string,address,address,address,address,address)","f560783d":"getLastProfit()","f560aa57":"setTokenPrices(uint256[],uint256[])","f560d415":"privateSalePrice()","f5610668":"currNumOfCards()","f56142b3":"burnPrivate(uint256,uint256,uint256)","f561e2f9":"refundTransactionFee(uint256)","f5620ed6":"addItemTo(address,uint256,uint256,uint256,string)","f562db76":"wct1()","f56311d7":"getMntpMigration(uint256)","f5632ab4":"receivedEth()","f563424e":"fetchBilateral(address,bytes32)","f564bb8c":"getNodeIdx(string)","f564dca9":"setUrls(string,string)","f564ea7e":"get_bank_data(address)","f5653a79":"_presentValue(uint256)","f56585de":"transferOtherTokens(address)","f56589d5":"PupToken()","f56613e4":"lockBetInfo()","f5663819":"minContributionETH()","f566c1b5":"_normalizeDecimals(uint256,uint256)","f5672f92":"garbageCollect()","f567a72a":"listMultipleItems(uint256[],uint256[],uint256,address)","f568006f":"generateBalanceHash(address,uint8,uint256)","f5681f9d":"Deposited(address,address,uint256,uint256)","f5685061":"startPreICOnow()","f56898fe":"getCompte_40()","f5689a80":"TOKEN_CREATED_MIN()","f5691b07":"_bidDkl(uint256,uint256)","f569626d":"sanTTTCost()","f569a2fc":"withdraw1(address)","f56a5176":"getMostRecentAuctionStart()","f56b8a46":"TEAM_BONUS_PERCENT()","f56c66b1":"parseInt128(string)","f56d7abe":"PaceCoin()","f56e0609":"WorldCup(bytes32,bytes32,bytes32)","f56e4cb1":"blockTokens()","f56e8421":"currentSquirrelOwner()","f56eba15":"SGEToken()","f5710cc5":"setInitialBalance(uint256)","f5716958":"updateSplits(uint256,uint256,uint256,uint256)","f571da7f":"confirmAssessor()","f5720769":"setDrawer(address)","f57213d8":"subsafe(uint256,uint256)","f57271cd":"LogEnded(bool)","f5727f5c":"chainLedger()","f572ae2e":"toggleInPlayJoining()","f573864f":"PrandexBountyToken()","f5738bcd":"setInstructions(string)","f5743c4c":"incrementNonce(address)","f574c691":"KCoinToken()","f5751524":"unfixTokenPriceInWei()","f575c810":"finishPrivateSaleAndStartPreSale(address,uint256,uint256,uint256)","f57688b6":"communityVesting4Years()","f576f722":"getCurrentTierInfo()","f577990d":"passoverEndTime()","f577a5d0":"publicTokens()","f578fd7c":"applyForToken()","f578fd85":"assertEq0(bytes,bytes)","f57a1ccc":"f4(uint256,uint256)","f57ac2df":"World2()","f57ad503":"resetRole(address)","f57ad6ea":"deposit_token(uint256)","f57ae7b9":"buildId2(address,address,address,uint256,bytes)","f57be85d":"ownerActivateToken()","f57d74d8":"blaze()","f57d76d5":"RestrictedShares(string,string,uint256,uint256)","f57db6e1":"signLoan(address)","f57e2368":"bonusAvailable()","f57e63e2":"eventEnded()","f57ee77b":"getRoundId()","f57fc26a":"lccxTeamTokensVesting()","f5804c35":"test_someTest()","f5811447":"createAuction()","f5812687":"distributeTokenFunds(address,address,uint256)","f5813085":"getTotalTokensByAddress(address)","f5818d94":"EtherModifierPandee()","f581ec95":"FIRST_VOLUME_EXTRA_BONUS()","f581f1ef":"setPicopsCertifier(address)","f5823b0b":"parseOrder(bytes,address,address)","f582d293":"buyEnabled()","f582fe70":"PundiXToken()","f58339c1":"_generateGuardianSale(uint256,uint256,uint256,uint256,uint256)","f5836761":"DGBLY()","f58431fd":"Citizen(address)","f584bf09":"Softcap()","f58589ff":"setAirdrop(uint256,uint256,uint256,uint256,uint256)","f58590e9":"ReturnChametz(address,uint256,uint256)","f5866066":"setStringValue(bytes32,string)","f5868e49":"Administrable(address)","f586c6d9":"getPoolAddress()","f586df65":"checkMembership(bytes32,bytes32,uint64,bytes)","f5877bdb":"maintaining()","f5878d40":"maxSCount()","f587c53f":"_generateGene(uint64,uint64,uint256,uint256)","f58951d1":"approve_reject_deleteCertificate(uint256)","f589cbbe":"addPick(uint256)","f58a1adb":"setup(uint256,uint256,uint256,address,uint256,uint256,bytes,address,address)","f58a535f":"phasePublicSale2_From()","f58adfe5":"CharityReservesSupply()","f58b4554":"userPayout()","f58bb0c9":"dealInitialCards()","f58c251c":"sentinel()","f58d3321":"usersCanUnFreeze(bool)","f58e2327":"foundationTokenHolder()","f58edbca":"ISBParentsCoin()","f58fc2f2":"LimorToken()","f58fef8e":"Destroy()","f590aacc":"preBuy()","f5923a6e":"withdrawEth(address,address,uint256)","f5933f66":"changeFlagArraySize(uint256)","f5938baf":"getRemainingBlocks()","f593efec":"briqcoin()","f594ba7b":"assignManagement(address)","f594f13f":"votedFor(address)","f595f1cc":"pendingFees(address,uint256)","f5963aa5":"isJson(string)","f5965d55":"windowOf(uint256)","f5967a2f":"holdPeriod()","f596d10a":"parseSignature(bytes)","f597a499":"UserDatabase(uint256)","f597d097":"streamerContractMaxAmount()","f597f97d":"fractionalBits(int256)","f59823cf":"Congress(uint256,uint256,int256)","f598e201":"finishDividend()","f5991a05":"sellCoins()","f59ae82c":"getTokenPurchase(address)","f59da238":"MBDCToken(uint256,string,string,uint8)","f59db647":"precommitmentAdjusted()","f59dfdfb":"feed(uint256)","f59e0894":"sendSecond(address,uint256)","f59e38b7":"balanceOfToken(address,address)","f59e754c":"setAuctionFee(uint256)","f59ed863":"privateSaleDate()","f59f5e65":"createWheelBetHash(uint256,uint256,uint256)","f59f99ee":"createNextGeneration()","f59faf9e":"GrainToken()","f5a0ea6c":"createMatch(uint256,uint256)","f5a1c96d":"nextFeesPerMillion()","f5a1f5b4":"setNewOwner(address)","f5a23083":"listMOT()","f5a23af0":"myColorIs()","f5a2d3c7":"DomainSale(address)","f5a30cee":"individualMaxCap()","f5a332f6":"endICO(uint256)","f5a486f3":"issueResolved(bytes32,string)","f5a5438e":"dist_airdrop(address,uint256)","f5a647aa":"sendTokensToSevenAddresses(address,address,address,address,address,address,address,uint256)","f5a79767":"getAmount(address)","f5a7ffeb":"dontPanic()","f5a8ea09":"viewClaimedThisPool()","f5a908f0":"getOraclePrice(string)","f5a91ef7":"getEmailAddressOwner(string)","f5a956d8":"swap(uint256[],uint256,uint256)","f5a98558":"restrictionRemoved()","f5a9e21f":"canUpdateCompanyPreferences(string,address)","f5aa0200":"makeClaim()","f5aa19b7":"reclaimUnclaimed()","f5aab219":"currentIcoRate()","f5ab16cc":"rewardTokens(address)","f5ab4c62":"participationEndTimestamp()","f5ab69c8":"thirdPlacePot()","f5ab865a":"tokensAirdrop()","f5ac0b6b":"BasketFactory(address,address,uint256)","f5ac481d":"leaveTeam(uint256,address,uint256,uint256)","f5ac6319":"_raised()","f5ac9db6":"tradeable()","f5ad9034":"TokenTranchePricing(uint256[])","f5adad57":"BdpControllerHelper(bytes8)","f5aec88c":"getUserTokenBalance(address)","f5af374b":"withdrawEth(address,uint256[],uint256[])","f5af4035":"sellTokensForEth(address,uint256)","f5af6289":"EAI_TokenERC20(uint256,string,string)","f5af6621":"getEscapeRequest(uint32)","f5af6de6":"firstStageEnd()","f5affc60":"claimHash(bytes32)","f5b01fd7":"TruCrowdSale(uint256,uint256,address,address,uint256,uint256)","f5b0f72d":"Ethername()","f5b12540":"STATE_NOT_STARTED()","f5b33d0a":"MicroDex()","f5b3beba":"OverAllPerSell()","f5b41aaa":"set_iconiq_token_amount(address,uint256)","f5b45714":"currentKing()","f5b490d5":"roundLockAmount()","f5b4f3c1":"WFC(string,string,uint8,uint256)","f5b53e17":"getInt256()","f5b53fc1":"checkMonsterAttack(uint16,uint8,uint8)","f5b56c56":"highestBindingBid()","f5b57a8d":"transferFeeDenum()","f5b5af16":"closePlayerGame(bytes32)","f5b5bfb9":"provideDividend(uint256)","f5b61230":"escapeHatchDestination()","f5b85ad8":"RoundToken()","f5b944eb":"ROLE_MANAGER()","f5b9644c":"PRE_ICO_RATE()","f5babff2":"convertBytesToBytes32(bytes)","f5bade66":"setDeposit(uint256)","f5bae6b6":"equal(int256,int256,string)","f5bb02b2":"ICODepositContract()","f5bb5aac":"TokenStore(uint256,address)","f5bbc6d5":"isArbiter(address)","f5bd48c4":"totalLotsByAddress(address)","f5bd4931":"transferFlower(address,uint256)","f5bd8f5f":"_isTrue(address)","f5bdeca1":"SetGasLimit(uint256)","f5be3193":"totalIssued()","f5bea782":"userWithdrawPendingTransactions()","f5bee4e6":"priceTokenToCoin()","f5bf6d63":"totalIssuerSupply()","f5bf7413":"close(address,address,uint256)","f5bf7e3d":"registerDINs(address,uint256)","f5c15237":"isPlatformManager(address)","f5c217da":"lastSaleTimestamp()","f5c233f1":"transferAndLock(address,uint256,uint256,uint256)","f5c256ca":"sendPrepaidERC20Tweet(uint256,string,string,uint256)","f5c3f206":"setApprovers(string,string,address[])","f5c454ca":"ProjectDescriptionUpdated(address,string,bytes32)","f5c476f9":"totalLockedTokens()","f5c4ceda":"SimpleConstructorArray(uint256[3],uint256[3])","f5c57382":"nameOf(address)","f5c5ad83":"decrementCounter()","f5c60309":"YuChainToken()","f5c6ca08":"sendTokens(uint256)","f5c6cd0a":"GlobexSciICO()","f5c6cf05":"changeTokenForSale(uint256)","f5c758c4":"getKycApproved(uint256)","f5c86d2a":"ledgerTransfer(address,address,uint256)","f5c87d20":"setAdminPayout(uint8)","f5c89f83":"StartMiningByIdArray(uint256[])","f5c8d71b":"forceMove(address,address,uint256)","f5c901db":"ck()","f5c91f5a":"init(address,uint256,uint256,uint256,uint256,uint256)","f5c972ac":"setUserInfo(address,uint256,uint256)","f5c98aff":"GreeterB(bytes)","f5c9d5f1":"refundPart(address)","f5ca6cd4":"TOKEN_SALE_ALLOCATION()","f5caccad":"gatherCollateral()","f5cb0daa":"queryWaitingTimeBuffer()","f5cb3dff":"getAddressFromData(bytes)","f5cb911d":"divideByNumber(uint256)","f5cbf6cc":"construtor(uint256)","f5cc4056":"BSMinting()","f5cce54d":"preSaleCoinCap()","f5ce0d5b":"onRemoval(string,uint256)","f5cf673b":"setClaimer(address,address)","f5d00ccf":"NewPatent(bytes32)","f5d05f7e":"foundationVestedPayment()","f5d09857":"createDungeon(uint256,uint256,uint256,uint256,uint256,address)","f5d09ff7":"bancorETHToken()","f5d17f10":"get_term_deposit_end_date()","f5d1d299":"setProviderTitle(bytes32)","f5d241d3":"update(uint80,address,uint32,uint32,uint32,uint256)","f5d36a57":"quorumVersion()","f5d3c79a":"setReinvest(bool)","f5d50f86":"balanceAsSupporter()","f5d5edc4":"deployService(bytes32,address)","f5d60a51":"accessPolicy()","f5d60acd":"EtherTakeAfterSoftcap()","f5d67a20":"currentCrowdsale()","f5d6fa14":"whichPrice(uint256)","f5d72a28":"setTakeRewardsPeriod(uint256)","f5d73261":"transferAnyTokens(address,uint256)","f5d78625":"getPersonalInfo(address)","f5d82b6b":"add(address,uint256)","f5d9356e":"newKrakenPriceTicker(string)","f5d97789":"changeBinaryAddress(address)","f5d9d3fd":"formated_data_url()","f5da16e9":"RECHToken()","f5da210c":"getClientData(address)","f5dabc58":"transferDistributePxl(address,uint256,bool,string)","f5db370f":"setSanityRates(address[],uint256[])","f5db8bc7":"depositedETH(address)","f5db9820":"firstTarget()","f5dd7650":"_computeTournamentBeneficiaryFee(uint256)","f5ddff92":"getReputationUpdateLogEntry(uint256)","f5df1d10":"getCollectibleTypeBalance(address,uint256,uint256)","f5df1f1d":"PresalePool(uint256,uint256,uint256,address[])","f5df6618":"newUser(string,string,string)","f5e1713e":"sale_state()","f5e27f5f":"emperor()","f5e3394f":"getUnicornGenByte(uint256,uint256,bytes1)","f5e33a9d":"createPot(string)","f5e3542b":"lookup()","f5e37d57":"_doTradeForEth(address,uint256,address,uint256)","f5e47f96":"getTicketsByAddress(address)","f5e493aa":"getCrowdsaleTierList(address,bytes32)","f5e53f2b":"register(bytes7)","f5e736ed":"tacoPoolTotal()","f5e7b8e3":"setScoringThreshold(uint256)","f5e7ce99":"canPerform(address,address,bytes4)","f5e7ef7a":"getCountCities()","f5e82554":"executeFill(address,address[5],uint256[8],uint256,uint8,bytes32,bytes32)","f5e8e8a9":"NASRToken()","f5e998f7":"FuckCoin()","f5ea15d3":"setContracts(address[16])","f5ea25f0":"setTokenAcceptanceRate(address,uint256)","f5eacece":"create2()","f5eb2313":"UrlHint()","f5eb42d1":"ExecLog(address,bytes32,uint256,bytes32,bytes32,uint256)","f5eb8890":"balanceUser(address)","f5ec2eed":"companyName()","f5ec8685":"claimAfter45days()","f5ece00a":"cryptoChallenge()","f5edc92f":"subwooferUSBToken()","f5ee3348":"setLive(bool)","f5eeaea3":"openChannel(address,uint256,uint8)","f5eed98d":"publisherCount()","f5ef98ea":"setDeathBlock(uint256)","f5efbd2d":"addModule(address,bytes,uint256,uint256)","f5f06acc":"airDropTokens()","f5f0f1e9":"firstBuyPrice()","f5f23b52":"makeTradable(uint8)","f5f2669b":"isAddressNotEmpty(address)","f5f2b62f":"nextSale()","f5f2de34":"ethReceived()","f5f3e58f":"preSale1()","f5f4123f":"_createAvatar(address,string,uint256)","f5f5ba72":"getContractName()","f5f5bb3b":"hashBid(address,uint256,address,bytes32,bytes32,uint256,uint256)","f5f5c622":"setDErc20(bytes32,address)","f5f5f123":"changeMaximumContributionForPublicPhase(uint256)","f5f6ea26":"EthOne()","f5f83a61":"transferManyLandToEstate(int256[],int256[],uint256)","f5fb17f2":"offerPieceForSaleByAddress(address,uint256)","f5fb1b74":"buyname(string)","f5fb22ca":"claimMobsterFunds()","f5fb9137":"donate_step()","f5fc20c6":"canUse(uint256)","f5fc32c8":"getAllot(bytes32,uint8)","f5fc3d47":"giftToken(address,address,uint256)","f5fc58c4":"totalLosts()","f5fd118e":"coordinatorSetAgreeForEmission(uint256)","f5fd1936":"countZTKChecks()","f5fd2108":"ethToBeDistributedSet()","f5fd9343":"Reco()","f5fda5da":"test_35_assertGasUsage1400Boards()","f5fda8cd":"testPublic()","f5ff3dc7":"setOraclizeWinnerTimeOffset(uint8)","f5ff5c76":"agent()","f5ff8977":"renameArtwork(uint256,string)","f60203c6":"createUser(uint256,uint64,uint64)","f602467e":"FundWithdrawal(address,uint256,bool)","f602c312":"erc20Store()","f602e325":"reserveAdress()","f6030aeb":"mint(address,uint256,int256)","f60381a1":"stra2cbor(string[])","f603fa92":"toggleAttachedEnforement(bool)","f60436cd":"reduceTime()","f604498a":"getClientSupply(address,uint256,uint256)","f604620a":"getTicketsAtAdress(address)","f604e6a6":"withdrawXNK(address)","f6054027":"IFLTSidechain()","f605ef93":"LongBought(address[2],uint256[5],uint8,bytes32[3],uint256)","f606b648":"transferTokensFromSpecialAddress(address,address,uint256)","f60744d5":"verifySignature(bytes32,uint256,uint256,uint8,bytes32,bytes32)","f607e88a":"_tokenPurchase()","f60957c0":"HowLongIsDisputeStillRunning(uint256)","f609a1a1":"extraMintArray(address[])","f609bad6":"newDaoRulesProposal(uint256,uint256,uint256,uint256,uint256,bool,address,uint256)","f609bf42":"getSecondsTimeLocked(bytes4)","f60a696d":"migrateUsers(address[10])","f60b0714":"EscrowContract(address,address,uint256,uint256)","f60b9406":"vestingStartUnixTimestamp()","f60ba338":"setOpenTime(uint256)","f60bb720":"receiveFees()","f60ca60d":"project()","f60ca6b6":"distory()","f60cdcf6":"totalPlayers()","f60daa71":"dutchAuctionToCraft()","f60e28f7":"checkUserAndInitIfNecessary(address,address)","f60edb0e":"proposedController()","f60f1ccb":"useregister(address,string)","f60f49bb":"PayToken()","f6105254":"CryptoSagaArenaVer1(address,address,address,address,address,address,uint32,uint256,uint32,uint256,bool)","f610e52a":"acceptInvite(bytes)","f612a62d":"getSaleContractIsFinalised(address)","f613f7a0":"mintUsingSignature(uint256,uint8,bytes32,bytes32)","f6142990":"altDeposited(address)","f614fd72":"assertEq24(bytes24,bytes24)","f6150d17":"payedAmount()","f6151ff6":"transferTokenTo()","f6153ccd":"totalDeposit()","f615e369":"selectDeliverer(uint256)","f615ed54":"subSeconds(uint256,uint256)","f616b7b7":"report(string)","f616ce3c":"candy()","f616f29f":"transferEthFeeAndRefund(uint256,uint256,uint256,address)","f6174b90":"transferCheques(address,address,uint256,uint256)","f617642b":"getlevellen(uint256)","f617a0e9":"BoSenCoin_Test(uint256,string,uint8,string)","f6187006":"crowdSaleIsRunning()","f618c39f":"PartiallyForgived(address,address,uint256)","f619304a":"getSellOrdersBlackMarket()","f61a3e2b":"roundWithdraw(uint256)","f61a7f6f":"fixSaleCompleted()","f61ac3a4":"checkForReceivedTokens()","f61adfdd":"UnitedfansToken(address)","f61b7483":"M5Logic()","f61b9aed":"transferFrom(address,address,uint256,bool,uint256)","f61c266b":"getExpiry()","f61c6c4b":"LobsterFarm()","f61ca773":"transferWithPurpose(address,uint256,bytes)","f61ca87a":"setUserValue(bytes20,uint256,uint256)","f61cd7de":"callerTokenAmountAtBlock(uint256)","f61d9afc":"Errors()","f61ed985":"Kill(uint256)","f61f019d":"GitBitToken()","f61f35dd":"FOG()","f61f54c2":"SendEtherToFund(uint256)","f61ff377":"AccountFilledWithBonus(address,uint256,int256)","f6205042":"storeClaimSeed()","f622a105":"createDApp(bytes32,uint32)","f622cc82":"declareWinningOutcome(uint8)","f6232556":"Security_GetNumberOfAttemptsToConnectBankAccountToANewOwnerAddress()","f6233016":"DomenoToken()","f623d7a7":"TrustlessTransactions_Log(uint256)","f625ee28":"startMasterCopyCountdown(address)","f625f472":"MultiownedControlled(address[],uint256,address)","f6261a0f":"_isValidWithdrawLimits(uint256,uint256,uint256)","f62732b8":"index(address,address[])","f627fe6c":"returnSomething()","f6281a9b":"getTierWhitelist(uint256)","f62847f4":"TerrionFund()","f6288422":"commission_system()","f628e8e8":"startDonations()","f62a92fa":"testRevertTx()","f62bc2dc":"ICTA()","f62cce34":"_clearRecordHierarchy(uint256,bytes32[],bytes32)","f62cec27":"setStartPreICO(uint256)","f62de0c3":"weiPerUSD()","f62e037c":"BETTING_CLOSES()","f62eded9":"buyStar(uint256,uint256)","f62ee1af":"burnFrom(address,uint32)","f62eec09":"rejectLastDeliverable(bytes32)","f62f47ab":"UDF_PORTION()","f62f9dbb":"tokenRatios(uint256)","f63051ff":"FXTOKEN(address,uint256)","f630a468":"setAtomIsRent(uint256,uint128)","f630e0f5":"submitTransaction(address,uint256,bytes,bytes,bytes,uint256)","f6310813":"transferDoc(uint256,address,address)","f631345b":"setlargeBonusStopTime(uint256)","f6326fb3":"depositETH()","f633adc1":"getRegister(int256,string)","f6340be4":"updateProvision(address,uint32,uint256,uint256)","f634bd29":"sec_addr()","f635052f":"colorPrice()","f635d160":"setPOOL_edit_20(string)","f635f50c":"minedTokenStartTime()","f6360d37":"requestDiploma(uint256)","f6366b9f":"OwnerTokensAllocated(uint256)","f6368f8a":"transfer(address,uint256,bytes,string)","f636931e":"PineapplePoints()","f6373296":"applySettings(uint256,uint256,uint256,uint256)","f637b7da":"collectedWei()","f637d950":"getAssetInfo(uint256)","f63841e4":"featurePrice()","f6384cb8":"sendReferallFundBalance(address,uint256)","f63850d0":"GanaTokenPublicSale(address,address,address,uint256,uint256)","f639365d":"testSetGet()","f63a43c0":"TokensPurchased(address,uint16,uint256,uint256,uint256,uint256,uint256)","f63a5d22":"divideDecimalRoundPrecise(uint256,uint256)","f63b1f7c":"GoldenLightCoin(uint256,string,uint8,string)","f63c2659":"PriceCalculator(uint256)","f63c533c":"Cost()","f63c5532":"incrementStat(uint256,uint256)","f63cb8a3":"requireTokenFuel(address[])","f63da25b":"Emailer()","f63df2e9":"createStandardToken(address,uint256)","f63ef744":"sendCharityETH(bytes)","f63f0e62":"turnOffCanUpdateNextGameInitalMinBetSize()","f640b81e":"test_oneInvalidEqBytes32Message()","f640d508":"transferToken(address,uint256,address)","f6413e46":"getFaucetAmountValue()","f6418b0b":"buyLandForEth()","f641d753":"changeElementName(uint256,string)","f6420e15":"tc()","f6432b8c":"publishLawyersInAttendance(string)","f6436a7c":"BONUS_ICO_PERIOD_TWO()","f643cf3d":"NEToken(address,uint256,uint256,uint256)","f64402c4":"setVicepresidenteDeMesa(bytes32)","f6444bcc":"isDeploying()","f6446614":"withDrawToPoolOwner(uint256)","f6448391":"getAllERC20(uint256)","f644c926":"SarmayehaaToken()","f6454620":"add_certifications(string,string)","f645496e":"giveawayFee()","f645835b":"beneficiaryAddresses(address)","f6458c6a":"toZ1(uint256[3],uint256)","f6460964":"teamKeepingPerEpoch()","f64623f1":"getBalanceB(bytes)","f646286b":"getPlayerShipOwnerById(uint64)","f6469342":"_setPackedBlockNumber(bytes32,uint256)","f64820f9":"addAttendant(string)","f6486cad":"burnReserveFees(address)","f6487e4e":"rejectCampaign(address,string)","f648f20b":"agencyWallet()","f64ab21a":"getOnMintAmountValue(int256)","f64b5c16":"distDay()","f64bfaba":"getBuyers()","f64c08b1":"onThrone()","f64ccca6":"payToken(address,address,uint256,uint256)","f64cd26b":"gcmp(uint256,uint256)","f64e167e":"getTextCount()","f64efacb":"icoHardCapInWei()","f64fca2e":"getNodeId(bytes)","f64fe563":"asyncSend(address,uint256,uint256)","f64ffde4":"getAccountPendingValue(address)","f6503662":"safeApprove(address,uint256,uint256)","f65045df":"totalClosedBID()","f6508be6":"tokensPerWei(uint256)","f651bf44":"move_to(uint16)","f652076b":"_getTokensAmount(uint256,uint256)","f652badb":"bitSSAToken()","f653279c":"TOKENS_FOUNDERS()","f653d286":"toggleTokenSaleOnHold()","f6560449":"evaluateProposalMetricEnd(uint256)","f65625ae":"changeWinnerPrizeMoneyForRaz(uint256,uint256)","f6577774":"BonusCrowdsaleImpl(uint256,uint256,uint256,address)","f6585116":"bytesFunc(bytes)","f658b1d5":"calculateContribution(uint256)","f659a45f":"airdropTokens(address,uint256)","f65bed0d":"initNewGame(uint8[16])","f65bffc3":"checkDividend(address)","f65c4d42":"Participate(uint256)","f65d1488":"setMarketingProfitAddress(address)","f65d226f":"getTotalBetAmount(bytes32,bytes32)","f65d6d4f":"MAX_MINT_NUMBER()","f65e2761":"RandomNumberGuessed(uint256,address)","f65e8d4d":"potMembers()","f65f5eeb":"choose(bytes32,bool)","f6618bab":"getBuyRequestsLength()","f661b886":"testCanTransfer()","f661e767":"villainIndexToApproved(uint256)","f6621121":"setSlammerTime(address)","f6623552":"getWalletBonuses(address)","f6626856":"LTT()","f662a12a":"oraclize_randomDS_proofVerify__returnCode(bytes32,string,bytes)","f662b881":"commitmentOf(address)","f662f291":"getInit(address,address)","f66302a2":"releaseMe(uint256)","f6631c64":"PPBC_Ether_Claim()","f6644c5a":"STARTING_FAIRY()","f6648d4c":"publishMixerType(bytes32)","f66597c2":"listTrophy(uint256,uint256,uint256,uint256)","f665a541":"coinsAdded(address)","f6660246":"fundOrderInternal(address,uint256)","f666323e":"UUIDProvider()","f669052a":"maxTokensToMint()","f66a79a0":"secondaryWallet()","f66afcac":"isTheAO(address,address,address)","f66b48da":"getHorseData(uint256)","f66bf229":"minBuyAmount()","f66c3af1":"getAddTokenApproveSignatures()","f66c6691":"shortTimeLock()","f66c75e5":"refund(bytes20,address)","f66cce0e":"adjustKPIs(uint256,uint256)","f66d0076":"getNumberOfCE()","f66d1f65":"releaseToEarlyInvestors(address,uint256)","f66d278e":"AgriChainDescriptionInt()","f66e86bb":"withdrawGasPayback()","f66f0bd9":"MingYuanToken(uint256,string,uint8,string)","f66f2449":"THANKSTEST4()","f66f640e":"pregnantZodiacs()","f66f83f6":"latestSeriesForUser()","f67028be":"trade(uint256,uint256,bool,bool)","f67187ac":"lookup(string)","f671cae4":"setIcoThirdWeekRate(uint256)","f671f5b3":"deleteEntireGlofile()","f6724a55":"totalAmountInvested()","f6729bf2":"canChangeLocked()","f672c1aa":"totalBountyCount()","f672e4d8":"changeAdminUser(address)","f6731d62":"intCallWithArray(int256,uint8[4])","f673745a":"edoPerWei_()","f674cfe5":"VOLUME_60()","f674d799":"removeManyFromWhitelist(address[])","f67501f7":"changePet(uint256,uint256,uint256,uint256)","f6757cff":"getEmployeeInfo(uint256)","f6761151":"Withdraw(address)","f676d539":"get_dati_lotto(bytes)","f6774660":"calculateNumDIDToIssue(uint256,uint256)","f677cf0d":"isDistributed()","f678142a":"ethLandSaleOpen()","f6783518":"KYCToken()","f678462f":"termsAndConditions()","f6785de7":"newPayOutPercentageIsSet(uint256)","f678cf02":"setRelation(uint8,address)","f6791858":"tgeStartTime()","f679791d":"playerRoll(uint256,uint256,address)","f67a1d37":"BlockChainChallenge()","f67a7782":"periodOne()","f67a81ea":"Bigba()","f67abd87":"entryDetails(uint256)","f67b3047":"setItemActive(address,address,string,bool)","f67d5a8d":"sendDividendsWithRefBonus(address,uint256,uint256)","f67e3d0d":"howManyShips()","f67e8db2":"getEthToTokenOrderList()","f67f83a8":"updateFileds(uint256,uint256)","f67ff0af":"_llTransferFrom(address,address,address,uint256)","f68009b9":"getRoundBetAmount(uint256,uint256,uint256)","f68016b7":"gasLimit()","f68036f0":"FaucetManager()","f6806074":"withdrawBonds(uint256)","f680b106":"RateEth()","f6814165":"castToInt(uint256)","f681f6e7":"capitalRaised()","f68297f3":"emergy_withdraw(address)","f6832c4a":"DO()","f683b247":"openSecret(bytes32,bytes32,string)","f68445dd":"myContract2()","f685e618":"_crownUnFreeze(uint256)","f685f942":"ZNCoin()","f685f9ad":"Moac()","f6860955":"emitAborted()","f686640b":"getCrabsOfOwner(address)","f686f019":"getCompte_9()","f686fa10":"verifyBBODocument(bytes,bytes)","f6879623":"addBountyReward(uint256)","f688bb2b":"setAirDrop(uint256,uint256,uint256,uint256)","f68975a9":"Total_Savers()","f68abb25":"approveToFight(uint256,uint256)","f68c021b":"EtherXeum()","f68c5b6a":"equalBytes32ToBytes(bytes32,bytes)","f68ce40b":"turtlemasterReq()","f68da9a0":"AthenaLabsICO(uint256,uint256[7],uint256,address,address[3])","f68dcd2b":"MHTHolders(uint256)","f68e63e3":"PRICE_MUL()","f68f1a0c":"recoverETH_SendbyMistake()","f68f8e42":"dataSourceGetGroupResult(uint256)","f6903c9c":"processEndOfYear(uint256)","f691b30b":"lockReleaseDate6Month()","f691e362":"EtherDOGEICO()","f692715c":"getGameResult(uint64)","f6928070":"numberOfGames()","f6933c7d":"isICOActive()","f694211c":"Composed(uint256,address,uint256[5],uint256[5],string,string)","f6946940":"jack_pot()","f694b761":"createPool(string,address,uint256,uint256,uint256,uint256,uint256,uint256)","f694c4be":"NSEToken()","f6950d5f":"LIFEWORLD()","f6951038":"testCreateWithParentsForeign1()","f696c4ed":"fightAgon(uint64,uint64,uint256,uint256)","f6973532":"setAddOwnerRequest(address)","f6978685":"HashnodeTestCoin_new()","f697a0ed":"ppb(uint256,uint256)","f697ddb2":"firstAddress()","f69871e9":"WithConstructorArguments(uint256,bytes32)","f6988b79":"getDeveloperReservedLockInfo(uint256)","f698bceb":"getMintable()","f698da25":"domainSeparator()","f698e626":"WrapReadTokenData()","f699ad94":"setupFundingInfo(uint256,uint256)","f69a3c7b":"termsAndConditionsAreSigned(uint8,bytes32,bytes32)","f69a6982":"getVirtualTradesSummed(bytes32,uint256)","f69adce6":"dinoToken()","f69b9dd8":"safeWithdrawalTokens(uint256)","f69ba02c":"toB32(address,uint256)","f69bbf16":"setContributions(address,uint256,bool)","f69bf03b":"issuePartnerTokens(uint256)","f69c3b24":"registerEarlyContrib(address,uint256,bytes32)","f69d03c9":"ETCWalletCreated(address)","f69d5f0e":"icoPhases(uint256)","f69da37e":"toRefer()","f69e672e":"modifyContactManual(uint256,address,string)","f69e739e":"voteForCandidate(uint256,address,address)","f69e8384":"ceoRemoveCoo(address)","f69e98d7":"bite(uint256,uint256)","f69f1027":"PRESALE_WEI_GOAL()","f69f18a6":"timesIsOver(address)","f69f190c":"getWorkerStatus(address)","f69f64f7":"setInfo(uint256)","f69f7cab":"createTokenVault(uint32)","f69f8a5c":"approvedBuyerForIndex(uint256)","f6a01234":"TokenStorage(uint256,address)","f6a03ebf":"setStart(uint256)","f6a08ced":"OracleBitfinex()","f6a0be88":"NCRCoin()","f6a0e8a4":"DTCC_ILOW_7()","f6a10249":"TransferedEth(address,uint256)","f6a12b48":"MatchmakerPrevails(address,address,uint256,uint256,uint256)","f6a14bf7":"getNumberOfTokensForTheTeam()","f6a176ae":"fpMul(uint256,uint256)","f6a25127":"test_set_label()","f6a29b81":"EntropyTxDetails(address,string,uint256)","f6a30e3e":"minTicket()","f6a31715":"Revocation(address,uint256)","f6a31b9c":"transferManagerContract()","f6a33253":"changeRatio(uint256)","f6a3b1dd":"totalHardcap()","f6a3d24e":"exists(address)","f6a3e8c8":"lockInfo(address,uint64)","f6a46c2e":"settleBaseDeliveries()","f6a47e9a":"MongoliaNationalToken()","f6a5546a":"testBilibirdaToken()","f6a56bcf":"TianLianCoin(uint256,uint256)","f6a58558":"withdrawRemainingRtc()","f6a5b13e":"m_beneficiary()","f6a5fa30":"subShares(uint256)","f6a60d89":"resumeCrowdsale()","f6a74ed7":"removeController(address)","f6a84013":"totalMEATonsSupply()","f6a8aea7":"financialStrategy()","f6a92de9":"mycontracts(uint32,address)","f6a94ecb":"notifyOfArbitrationRequest(bytes32,address,uint256)","f6ab4243":"buyCastle(uint256,uint256,uint256)","f6ac54dd":"checkRegPeriod(bytes32)","f6ac6684":"getStringZero(uint256,uint256)","f6ad660b":"f3(uint256,uint256)","f6ada1ad":"rewardDaysLeft()","f6adab61":"delayOfICO1()","f6af18f5":"montly_pay()","f6af2718":"Quantastic()","f6afad47":"getDatabase(uint256)","f6afe805":"PRE_SALE_GMRP_TOKEN_CAP()","f6b09195":"preicoTokensPerEth()","f6b098f8":"nextAttackTimestamp()","f6b10854":"safeWithdrawAll()","f6b12f28":"gameOwner()","f6b15fe6":"getProfit(uint256,uint256)","f6b19c74":"drain(uint256)","f6b2b334":"upgradeTo(address,uint256)","f6b2c3b6":"VendTitle(uint256)","f6b39b3c":"ContractTotalMined()","f6b3e080":"roundOneRate()","f6b44d03":"validFactories()","f6b4c691":"getPendingCratesForUser(address)","f6b4dfb4":"contractAddress()","f6b5460f":"withdrawTrackOf(string)","f6b55a93":"hotWalletAddress()","f6b69697":"importPreviousWinners(uint256[],address[],uint256[])","f6b6daf1":"supportedTokens(uint256,uint256)","f6b70702":"LightComplexAirdrop()","f6b781a1":"Bolton()","f6b87500":"internalCalc(int256,int256)","f6b911bc":"burn(address,address,uint256)","f6b91944":"walletLists()","f6b924f8":"EventAuction(address,uint32,uint256,uint256,uint256,uint256)","f6b94cb4":"negotiate(uint32)","f6b9571a":"remove_owner(address)","f6b97131":"redemptionCount(address)","f6b9d05d":"bountyAllocation()","f6b9fd79":"STARTING_VINES()","f6ba13a5":"lastBlockNumberInRound()","f6ba3b6c":"addThing(string,string,bytes32,string)","f6bb3cc4":"deleteString(bytes32)","f6bd5893":"getGas(uint256)","f6be4776":"CannabizToken()","f6be71d1":"setDuration(uint256)","f6bea5dd":"LOCKEDiN()","f6bed059":"mixer()","f6bf0edd":"removecantonEmployee(address)","f6bffff8":"_createTombWithData(address,string)","f6c05625":"isValidNumber(uint8)","f6c0736b":"register_token(address,string)","f6c0d6a3":"_getChainLength(uint256)","f6c1acdf":"proofFor(string)","f6c1db4c":"GetChequeInfoByHash(uint256)","f6c28241":"BuyForFriend(address,address,uint256,uint256,uint256)","f6c3f6cd":"readUserPurchaseAtIndex(address,uint256)","f6c42713":"changeExpiredLimit(uint256)","f6c50d8b":"_ownersTokens()","f6c536a0":"sendBonusMany(address[],uint256[])","f6c5c80d":"cleanUp()","f6c6b731":"activeFirstRound()","f6c7430e":"JAPACHELOR()","f6c8f62e":"TransferBack(address,uint256,uint256)","f6c976d2":"test_1_assertGasUsage50Boards()","f6c98dd7":"WikiToken()","f6c99dad":"SETUP()","f6c9e930":"approveSender(address,address,bool,uint256,uint256)","f6ca75d8":"AkonCoin()","f6cabaa0":"burnedToDate()","f6cb86db":"whitelistTransferPrimordialTokenFrom(address,address,uint256)","f6cbcab0":"mintParts(int256,uint16,address)","f6cbea50":"ErrorReturningEth(address,uint256)","f6cc7d60":"setUnitDefenseIncreases(address,address,uint256,uint256,bool)","f6cdf281":"returnPtSafeMedium()","f6ceecc4":"TokenAdminContract(address,address[],uint256,uint256)","f6cf3a7d":"setDeveloperCut(uint256)","f6cf4570":"BoughtBlock(uint256,uint256,uint256,address,bytes32,bytes32,bytes32,bytes32)","f6cf5411":"startTimePreIco()","f6d0bf2f":"GetContractBalance()","f6d2eb65":"_validateQualityConsensus(bytes32,bytes32)","f6d2ff9d":"setFreelancer(address,address,bool,string,uint256,uint8,uint256[],uint256[],string)","f6d339e4":"setAddress(bytes32,string,address)","f6d361cc":"ENTRY_FEE()","f6d3d52d":"RatesChanged(address,uint32,uint32)","f6d3df65":"ownerStartsCrowdsale(uint256)","f6d4a265":"addLacks(uint16[],int64[],uint16[],int256,int64[],int256,int64[],uint8[])","f6d51638":"getRocIdToTokenId(uint256)","f6d5959b":"getActionStatus(uint256)","f6d68fca":"balanceWinPoolForThirdStage()","f6d6d5aa":"claimableToken()","f6d72acd":"setVoter(uint256,address,uint256)","f6d860d1":"approveUserKYCAndSetReferrer(address,address)","f6d89563":"airdropTotalCurrent()","f6d956df":"buy(uint8,uint256,uint256)","f6da1c0a":"getPriceSMPTokensPerWei()","f6dab356":"getGPSEndTime()","f6db2bac":"LOG_BetLost(address,uint256)","f6db6e50":"ponziToWei(uint256,uint256)","f6dbc252":"MOREToken()","f6dcb32c":"sendRewardTokens()","f6dd0187":"getSubject(uint256)","f6ddac74":"updateLocation(string,string)","f6ddcee5":"_generate_seed(uint256)","f6df0d50":"setFrozenAccountICO(bool)","f6df26d2":"kickOutCommunity(address,uint256)","f6dfafe1":"getShareHolder(uint256)","f6dfcff7":"getCooldownEndTime(uint40)","f6e158b9":"getPickedAssetsAndFinalSeed(bytes32[],uint256[],uint256,uint256)","f6e212ea":"addCrystal(address,uint256)","f6e4641f":"purchaseFor(address)","f6e4a3dd":"tradeBalances(address,uint256,address,uint256,address,address,uint256)","f6e5c6a4":"totalWeiDonated()","f6e5e112":"startingEtherValue()","f6e5e298":"setScientificData(uint256,string)","f6e66c17":"totalAwards()","f6e681a9":"IkuraApproval(address,address,uint256)","f6e72981":"mintManyTo(address,string,uint256[],uint256[])","f6e7b785":"tdeStarted()","f6e7f69d":"test_insert_findWithHintPrevRemoved(int256)","f6e87f81":"SkillChainToken()","f6e898b0":"getIcedAddresses()","f6e9b85c":"doSetCanCreateGrants(address,bool)","f6ea1a3f":"CryptoSpin(address)","f6ea6252":"MINER_END_PRICE()","f6eb1337":"TokenBought(address,uint256,uint256,uint256,uint256)","f6eb13b3":"VietnamToken(uint256,string,uint8,string)","f6eb58de":"TransferManagerRevoked(address)","f6ebe41a":"defaultURIStart()","f6ec91d5":"developerAccount()","f6ecb9ee":"getprizemoney(address)","f6ecd724":"init(address,uint256,bytes32,uint256,uint256,uint256,uint256,bool,bool,address)","f6ecebf2":"LeagueAdministrator()","f6ed4b71":"getBasketDetails(address)","f6ed5342":"updateEscrow(uint64,uint256)","f6ed8fe7":"grantsUnlock()","f6ee2d8d":"developersTokensWallet()","f6ee439f":"registerAssetComment(int256,string,string,uint256)","f6ee87b8":"_0xEtherToken()","f6ee8c59":"FirstBonus()","f6eeb89c":"addBid(string,string,uint256,address)","f6eeff1e":"punkNoLongerForSale(uint256)","f6ef97ff":"transferEthToWallet(uint256)","f6efcb7a":"setKeyData(bytes32,bytes32,bytes32)","f6f0fa8d":"teamReleased()","f6f10a26":"topUpWithEtherAndTokensForHolders(address,uint256)","f6f15ec9":"Larbaoui()","f6f17bba":"distributePreSoldShares()","f6f1995d":"onlyOwnerSetBountyWallet(address)","f6f3144d":"GetEthBalance(address)","f6f32cc4":"CICToken(string,string)","f6f36641":"setV_R5(uint256)","f6f3973f":"fundIco()","f6f494c9":"getTermsContract(bytes32)","f6f505c4":"RaffleResult(uint256,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,address,address,bytes32)","f6f54833":"HighEndTreasureChain()","f6f55ada":"TokenDistributed(address,uint256)","f6f5eb59":"transferableStartTime()","f6f5f567":"SMPAcquired(address,uint256,uint256)","f6f65f1a":"ASTRN_TOKEN()","f6f6edd4":"issuerDecimals()","f6f6fc74":"holderTeamTokens()","f6f7301e":"getById(int128)","f6f82ecb":"massChangeRegistrationStatusForSilverWhiteList(address[],bool)","f6f844e4":"setOp(bytes32)","f6f8ca07":"burnPXL(address,uint256)","f6f91737":"MAX_FREE_REFERRAL_PACKS()","f6f94a85":"ScaleFactor()","f6f94b47":"MiningPayout(address,uint256,uint256)","f6f96d91":"rateOfEther()","f6f98e34":"calcReleaseToken(address,uint256,uint256)","f6fb2c72":"buyGuardian(uint256,uint256,uint256)","f6fb4c9a":"_createFilm(string,address,uint256)","f6fb6ecf":"buildHouse()","f6fbc06a":"getWeiInvested(address,address)","f6fc8160":"addSeed(uint256)","f6fc96ad":"mainsale()","f6fcbee1":"getArrayUint(bytes32)","f6fcc14e":"agTechWallet()","f6fe3a01":"getUint256Min(int256)","f6fee732":"getAccountNote(address)","f7008156":"_haveEveryoneDeposited()","f700abf1":"addBudget(uint256,uint256)","f700ead9":"withdrawTokenMulti(address[],uint256[])","f702dd8a":"hkchain(uint256,string,string)","f703601e":"safe_add(uint256,uint256)","f703e773":"changeLifeExpectancy(uint256)","f7044bae":"getShareHolderCount()","f7048161":"checkRefundSignature(uint8,bytes,address)","f704b57a":"Bitconnect()","f704cb98":"addInvitation(address,address,uint256,address,string)","f70532fe":"getContractsOf(address,uint256)","f705fb87":"preICOend()","f7066121":"lastJackpotRound()","f706b476":"set_pauseUET(bool)","f706b814":"PARSEC_CREDIT_DECIMALS()","f7073490":"buyLink()","f7074919":"seenHereA()","f70794ea":"acceptHelp(uint256)","f707a308":"tierTwoMin()","f7086dd1":"SmigesToken()","f70904b4":"sale1Accepting()","f7095d9d":"updateTentativeWinningChildUniverse(bytes32)","f709dd51":"getTrademark()","f70ad595":"team_release_epoch()","f70b0a07":"setTrustedLateCloser(address,bool)","f70b13c5":"vestedTokens(uint64)","f70bbb9a":"getProposalExternalToken(bytes32,address)","f70bbdaf":"create(string,string,uint32,int256,string,address)","f70bdba7":"AdidasCoin()","f70c92de":"GOSHUIN()","f70ccc6e":"MaptPricing()","f70d7629":"_verifyOwnershipOfTokens(uint256,address,uint256)","f70dbb77":"isPresalePeriod()","f70dd1fe":"isAllocated6()","f70eabff":"addTeamAndAdvisorsAllocation(address,uint256)","f70f1821":"weeksFromEnd()","f70fa221":"getInitializeCashValue()","f71143ca":"isSaleLive()","f712d7ff":"testFailControllerTransferFromWithoutApproval()","f712f3e8":"implementsERC165Interface(address,bytes4)","f7138eaf":"createArtworkAuction(string,string,uint32)","f71441a5":"maxGoal()","f7146269":"testGetRandomDragon(uint256)","f7149220":"RNG()","f714a96e":"myCompany()","f714bf3d":"overflowOwner()","f714de9c":"MultiAccess()","f7160766":"getCompte_13()","f716171c":"createTrade(uint16,address,address,uint256,uint16,uint32)","f7164029":"upgradePrefixPreSignedFirst(uint8,bytes)","f716c400":"getCrowdsaleUniqueBuyers()","f716fe43":"s37(bytes1)","f717442a":"previousPriceOf(uint256)","f717c310":"freezeTransfersSince(uint256,string)","f71868da":"Ethereumcapital()","f719254d":"cancelEthToTokenOrder(uint32)","f719e111":"useOraclize()","f719edfb":"firstPublish()","f71ad40e":"icoCapInWei()","f71b041c":"refundUser(bytes32,uint8,uint256,uint256)","f71b382c":"PIEXTREAM()","f71be837":"sign(address)","f71c60bd":"AMBASSADOR_FIVE()","f71cc3a5":"setUserStatus(address,uint256)","f71db383":"setArbitrationContractAddress(address)","f71dcb10":"CreatedMTP(address,uint256)","f71f7a25":"set(bytes32,bytes32)","f71f9c38":"SupplyChanged(uint256)","f72047ff":"_enableRefunds(address)","f72084b2":"foundationShare()","f720a453":"senderStake()","f720d563":"endAttack(address,bool,uint256,uint256,uint256,uint256,uint256,uint256[])","f720ef08":"setTokenAiNetworkToken(address)","f720f3d2":"tokensToEther(uint256,uint256)","f720f80b":"isMaster(address)","f7213db6":"orderFills(bytes32)","f72457af":"CertifierDb()","f7253071":"lastBlock_f0()","f725839f":"multiGenerate(address,address[],bytes)","f7260d3e":"receiver()","f7265042":"getUsersShipsIds()","f726af40":"MilestoneAmountRaised()","f726f715":"distributeFunds(uint256)","f727550e":"determineOutcome(uint256)","f72755fe":"getRequest(int256)","f72758e7":"getBracketDataMiddleTeamIds(uint8)","f72860ca":"modifyCustomer(string,string)","f7286888":"getPhaseNumber()","f72918ef":"addVoterVote(address)","f729688e":"_hasFlags(uint256,uint256)","f729b216":"moreTokenPerEtherForSeedRound()","f729cf0d":"getJob(bytes32)","f72a244d":"handleAllowance(string,uint256)","f72ae72c":"remainingTokenForSale()","f72b7ab9":"SbloccaConto(address)","f72c436f":"isHuman(address)","f72c75a5":"delegateVestingContractOwner(address)","f72d2c22":"BONUS_HI()","f72d3b15":"LamboPresale(uint256,uint256,uint256,address)","f72d50a9":"getPOOL_edit_4()","f72d53ba":"getNumMatches()","f72db5a3":"getLLV_edit_8()","f72e460a":"getBUUU(bytes32,uint256,uint256)","f72e695b":"setPoolCut(uint256)","f72f30e1":"Vesting(address)","f72f34db":"getDCountedBasicBallotsN(bytes32)","f72f6826":"ChangeEnd(uint256)","f72fc599":"_isThereAnOnGoingTapProposal()","f73052e8":"totalSoldCount()","f73079a6":"Auto(address,string)","f73089b9":"sale2Stopped()","f7309f29":"testLedgerUnderPayback()","f731c3bd":"lotteries(uint32)","f731d33c":"ApzCoin()","f7326286":"getARInvIndexTable()","f73294b8":"isValidatorAlreadyVoted(address,address)","f732eb66":"getPayoutDenominator()","f7342cd3":"SGF()","f7362152":"testThrow_testableContributionCaseExpectFailure()","f73770e7":"is_contract_paused()","f737f274":"getBuyDemand(uint256)","f73857cc":"deauthorizeAddress(address)","f738e5ca":"ownerTakeProfit()","f739a501":"snapShot(uint256,address)","f739ba2f":"picops_withdraw_excess()","f739c261":"legendary()","f739ed4c":"id_for_user_version(uint256,uint256)","f73a590c":"distributed_team()","f73b5541":"bulkWhitelist(address[])","f73baf62":"proxy_initialization()","f73c30e3":"getESOP()","f73c8dfd":"pvpQueueSize()","f73cc97c":"AddDOT(bytes)","f73d05db":"getSha()","f73d594c":"ERC20Base()","f73e05dd":"RetrieveCommissions()","f73f4ebc":"processBuyRequest(string,address,uint256,uint256,bool)","f74034df":"purchaseGen0Token(uint256)","f7407178":"get_banlance(address)","f740fbc9":"test_validPerc()","f74100e3":"getBits(bytes)","f741b602":"denyInvestor(address)","f742048b":"NlvToken(uint256,string,string)","f7426b62":"unlock(bytes32,bytes,uint256[],bytes,bytes,bytes,uint256[],bytes,bytes)","f74279b0":"totalEarning()","f7434ea9":"arbitrationCost(bytes)","f743d334":"BancorBuy()","f744538d":"submitClearingPrice(address,bytes32,uint256)","f7448a31":"transferERC20(address,uint256)","f745630f":"update(uint256,string)","f746e28d":"fundSchool(uint256)","f746f365":"icoSoldCap()","f746fcdb":"presaleMade(string,uint256)","f74715cb":"ApproveERC20(address)","f7474d00":"payEther()","f74758ef":"safeSendCard(uint256,address)","f7477435":"TokensWorldCoin()","f747a5eb":"auctionBid(bytes32)","f747b744":"investFromWallet(uint256)","f749013e":"dateStartContract()","f7493c6a":"UpdatePremiumLimit(uint256,uint256)","f749bdc1":"BUYER_CHECK_STEP(bytes32)","f749d980":"LastExecuted()","f74a4e63":"transferToMint(uint256)","f74b766a":"createBet(uint256,uint256,uint256,bool,string)","f74c67b3":"getAddressKYCState(address)","f74c753f":"dontReturn()","f74d73ec":"issueSertificate(address,address)","f74deae3":"MultiSigWallet(address,string,uint256,uint256,string)","f74e8655":"setWhitelistAgent(address,bool)","f74e9bde":"pwr(uint256,uint256)","f74f4702":"changeRequiredMajor(uint256,bool,bytes)","f74fbb47":"StateChanged(bool)","f74fc598":"listSharesForSale(uint256,uint256)","f750aaa6":"withdrawEverything(address)","f75165c6":"right22(uint256)","f751758b":"getCurrentTokenPrice()","f751b26a":"unclaimedRoyalty()","f751c2f5":"MAC()","f751cd8f":"drop()","f752644c":"aelfCommunityMultisig()","f752fdc3":"wdivide(uint256,uint256)","f75316b4":"CobinhoodToken()","f754f766":"setBonus(uint8,uint8,uint8,uint8)","f7553098":"voteForOutcome(int256,uint256)","f755a76e":"createBoard(bytes32)","f755a98b":"setCrowdsaleEndBlock(uint256)","f75640b3":"crowdsaleCanceled()","f7566b49":"getBet(address)","f756b574":"getDropAmount()","f7572cf3":"newCampaign(address,uint256)","f757342c":"setRewardWasSent(address)","f758ff59":"SentDeveloperFee(uint256,uint256)","f759e298":"getNumberOfBlocksPerKick()","f75a275b":"reservedLPT()","f75b8d3c":"getExpiredCratesForUser(address)","f75beacf":"HuaTuo()","f75ccbf0":"checkErrors(bytes32)","f75cf7d5":"IndecoinBounty()","f75d34bb":"ICOChanged(address)","f75e5d85":"selfDestruct(uint8,bytes32,bytes32)","f75eb240":"removeCallSpenderWhitelist(address)","f75ec528":"getSpaceInfo(uint256)","f75fa5e1":"xorReduce(bytes32[],uint256)","f75fb878":"preICOwei()","f75fdcaa":"cancelMilestone(uint256)","f760d2a2":"_incrementBlockStats(bytes16,uint8)","f761720a":"isEquiped(address,uint256)","f7618a40":"LIMIT_PROMO()","f7620435":"inquire_length(uint256)","f7627da2":"startUnlimitedSale(uint256)","f7628949":"B2ANDcoin()","f762e147":"addAsset(uint256,uint256,bytes)","f7637bec":"AccountReaderRemoved(address,address)","f764531d":"saleStartAtBlock()","f7647f36":"acceptPurchase(uint256,uint256)","f764e8a0":"partPos()","f764eb93":"LogDepositForDividend(uint256,uint256)","f765088f":"UpdateClientAddress(address)","f7654176":"split()","f76543e9":"hasOpening()","f7658e0f":"bonusDecreaseDay()","f765b6b1":"getEventInfo(bytes32)","f765e6e4":"return_pause()","f765ec6f":"lastBlock_a11Hash_uint256()","f766658d":"finalizePreIcoDate()","f76692a6":"dtTestCitySnapshot(address,uint256)","f766cd3e":"minInvestorCap()","f766eca7":"EtherDeltaApproveToken(address,uint256)","f7670b0c":"updateAuth(address,address,bool)","f7678fda":"setNewRegister(string,string,uint256)","f767fdcf":"KRYPT()","f767fe97":"MarketingAddr()","f7682aa5":"CURVE_CUTOFF_DURATION()","f7683b37":"ETTCE()","f768402a":"addProduct(address,string,string,uint256,string)","f768923a":"ignite()","f76a24e6":"isTesting(uint16)","f76aae2f":"addVerifiedAddress(address)","f76b8c5e":"destinationOf(uint256)","f76bd7d1":"disableIssuance()","f76bf292":"StormToken(address)","f76bf757":"registerPage(bytes8,string,bytes32,string)","f76c0f4e":"updateFlipTokenRewardAmount(uint256)","f76c1ea5":"setReceiptLiablity(address,address)","f76c84eb":"manualChangeMonth(uint256)","f76c906b":"mCurrentSnapshotId()","f76ce123":"ERC20Template()","f76cf4bf":"BiToro()","f76d270e":"_setTokenBudget(address,uint256)","f76d3569":"auditorDelegate()","f76e8d29":"createSplitAgreement(address,address,address)","f76e9183":"VitalSkin()","f76f8d78":"SYMBOL()","f76f950e":"uint2str(uint256)","f76ffe7a":"startMintingData()","f77014da":"setGVE(uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32,uint32)","f7701b47":"downloadPriceInWei()","f7701ce8":"batchDistribute(address[],uint256)","f770a865":"FaradCryptoken()","f770c96f":"TDESupply()","f771bc6b":"minerSaleCount()","f772547b":"addressToSubscriptions(address,uint256)","f77267ea":"sendTokensToWorkers(uint8,uint8)","f77282ab":"finalizeAuction()","f773a3fb":"maxAssignedRequests()","f773ab80":"isPVPProvider()","f773c770":"TMSYToken(address,address)","f77404e5":"totalCommonWithdrawSupply()","f7745f88":"BudCoin()","f7746e36":"cars(uint256)","f7749e32":"rocketTimeUntilMoon(uint256)","f7750bd5":"startEthGetToken()","f7759c84":"maxTokenSupplyPreICO()","f7768580":"EventTransferAction(address,address,uint32,uint8)","f7770906":"buy_energy_core(address,uint32,uint32,uint64,uint32,uint64)","f778f32b":"addAlgo(uint256)","f7791010":"approveWriter(uint256,address)","f779a68d":"_deposit(address,address,uint256,bytes)","f779abf7":"DaoUpgraded(address)","f77a0923":"BitcoinProcessor(address)","f77a490d":"setMinPurchaseInWei(uint256)","f77aa0ad":"changeRedTeamAddress(address)","f77abd74":"getMatchPointsGroups(uint256,uint192)","f77b1856":"getAddTokenData()","f77b6f61":"getCRhashOfCRTokenId(address,uint256)","f77c1dc6":"unknownInvestors(uint256)","f77c4791":"controller()","f77c4ff9":"_firstRoundFight()","f77ca208":"managerIsPaused()","f77d62f0":"roundNumber_()","f77da6d5":"claimImmediateTokens(address)","f77dc854":"setHookableTokenAddress(address)","f77dff06":"joinPillarWithEarnings(uint256,uint8,uint256)","f77e4d8b":"test_YayIsNotOverSixtyPercent()","f77e8b83":"addPlayer(string)","f77f29b1":"getFeeWindow()","f77f2f2e":"setRewardStatus(address,bool)","f7800e69":"fundVault()","f780259e":"totalPrayers()","f780d867":"add_coin(string,string,address,uint8)","f7815fae":"getIntField2()","f782b2ea":"_confirm(address)","f784cae5":"Fetish()","f784dd61":"RealeaseTime()","f78525a1":"getFaucetByName(string)","f785ef72":"decimals_()","f785f03d":"setMigrating(bool)","f7860bb1":"addToBounty()","f7862ec2":"feeWindowBurn(address,uint256)","f7868884":"FOUNDERS_REWARD()","f786bb62":"Hiken(uint256,string,uint8,string)","f786becd":"MAJOR_VERSION()","f786cb82":"updateLemontokensRemainingToDrop()","f7870c5b":"Unlock(address,uint256,uint256)","f7888aec":"balanceOf(address,address)","f7892887":"phase_1_Time()","f7899d9e":"_buyCommonTTM(uint256,uint256,address,address)","f78a706a":"extraEmission(uint256)","f78a7a55":"createBurnRequest(address,uint256,string)","f78c6b54":"donations(bytes32,uint256)","f78cc9cf":"getTokenNextPrice(uint256)","f78d1c6a":"managePID(uint256)","f78d5494":"approveNewMintRequest()","f78dd0c1":"MovieCoin(uint256,uint256)","f78e4210":"test_oneValidEqAddress()","f78ed322":"regNameWOwner(string,address,address)","f78fa141":"_uintToSPDStr(uint256)","f78fadc6":"HXC()","f78fe0e9":"stand(uint8[],bytes32,uint8[])","f7903871":"RevTokens()","f7908f00":"verifyTransaction()","f79098f4":"getEditionLimits(uint256)","f793595a":"ThreeAT()","f7935969":"getRank(address,uint256)","f793fb64":"valInt()","f79480f8":"lastBlock_f19Hash_uint256()","f794e7f2":"addDefenceParts(uint8[])","f794eb58":"getBonusRate()","f7963e8a":"testNewCounterValueIszero()","f7966eef":"changeReputation(address,int32)","f7969147":"currentBurned()","f796e06f":"calculateAndRegisterBonuses(uint256)","f79710fd":"extraTokens(address,address,uint256)","f797ac0e":"addSellingItem(uint256,uint256,uint256)","f797b617":"buyInvestorPack(uint256)","f797f7b6":"ETH_SIGN_TYPED_DATA_ARGHASH()","f7981bdd":"indSeed()","f7982243":"addRecipient(address,uint256)","f7987a03":"applySetMaxFeeWithdrawal()","f798abce":"teamLockAddr()","f79915ce":"kkTestICO91()","f7992d85":"eta()","f7996163":"joinSinceOf(uint256)","f79a2b84":"setFirstMile(address,address)","f79a3c25":"voteForDisable()","f79a97fc":"isSpentTxPaymentForMCW(bytes32)","f79acad3":"approveInvestorsInBulk(address[])","f79b22e0":"betOnATeam(uint256)","f79cfaea":"STLToken(string,string,uint8,uint256)","f79d0a8b":"callSomeFunctionViaInner1()","f79d6687":"removeTokenTime(uint256)","f79dcf8d":"earliest_buy_time()","f79e2b32":"inListAsOf(address,uint256)","f79ea94d":"VoipToken()","f79ebd7f":"tokenPriceDenom()","f79ed94b":"reserveAddress()","f79f528b":"getMinAuctionValue()","f79fc70d":"testBaseStoreTokenUsingDeployedContract()","f7a01b93":"StateMachine()","f7a06a88":"setSellerGuarantee(bool,uint256)","f7a0715f":"DoneToken()","f7a084c0":"AIRDROP_START_AT()","f7a0b2da":"updatePeloExtenstionContract(address)","f7a0ee1c":"maxtokens()","f7a0fa0a":"getShareDistribution(bytes)","f7a268c4":"freezeAccount(address,bool,bool)","f7a33598":"round(uint256[4])","f7a34573":"setAction(string,uint256)","f7a40e99":"moveERC721Tokens(address,address,uint256)","f7a4c45c":"calculateSaleReturn(uint256,uint256,uint8,uint256)","f7a6a046":"backOrenCoinOwner()","f7a7408b":"BuyLevel()","f7a7ec12":"fund_color(address,address,uint256,uint256,uint256)","f7a80784":"addProduct(string,uint8)","f7a8b34d":"planetName(uint256,uint256,uint256)","f7a919be":"createRegion(address[16],address,uint256,uint256,uint256,uint256)","f7a9a152":"count_users()","f7aa4e0e":"MithrilArrows()","f7aad9ed":"amendBalances(address[])","f7ab6ec6":"getOfferingByProposal(address,uint8)","f7abab9e":"tokenTotalSupply()","f7ac5611":"pushStatus(string,uint256,uint256,int8)","f7ac9c2e":"approvePreSignedHashing(address,address,uint256,uint256,uint256)","f7ad7d8f":"getAllowedAmountByTeam()","f7ad906f":"contractTransfer(address,address,uint256)","f7adc48f":"test3(uint256)","f7ae24ae":"FundWithdrawal(address,uint256)","f7ae9421":"checkInvestorBalance(address)","f7aeea14":"removeGlobalConstraint(address,int256,address)","f7af21c9":"cancelCrowdsale()","f7af630b":"GetBindTokensAccountEvent(address,string)","f7b09d33":"giveReserveFund(address,uint256)","f7b14066":"setup(uint256,uint256,uint256,uint256,uint256,uint8,uint256,uint256,uint256,uint256)","f7b188a5":"unPause()","f7b22fa2":"getCurrentBeneficiaryCap()","f7b28073":"moleculartechnology()","f7b2a7be":"rewardAmount()","f7b42d08":"set_price_and_sell(uint256,uint256)","f7b43abf":"PRESALE_ICO_PORTION()","f7b47870":"setPublicOfferingHolder(address)","f7b4b087":"purchaseFirstTokens(uint256)","f7b4feec":"FaucetsToken()","f7b53431":"feesTaken()","f7b54065":"getInvestmentCurrentValue(address)","f7b578ee":"LiveCoin()","f7b6302e":"getInvestorTokensPurchase(address,uint256)","f7b75258":"withdrawlsEnabled()","f7b77a21":"MasternodeRegistered(address,uint256)","f7b822db":"setDEditor(bytes32,address,bool)","f7b89a3e":"getTotalCosts()","f7b8a600":"payAltCoin(bytes32,uint256,bytes)","f7b8eeb7":"getWhale(uint256)","f7b92f34":"CandidToken()","f7b95d35":"setRNGCallbackGas(uint256)","f7ba8896":"random(uint256,uint256,address)","f7bada53":"randomChoiceFromticketPool()","f7bbd1c1":"setMinAcceptEther(uint256)","f7bc2003":"releaseApprove(bytes32,uint8,bytes32,bytes32)","f7bc39bf":"owns(address)","f7bd2361":"LookAtBalance()","f7c0085b":"changeRandomOrgAPIKey(string)","f7c00e2f":"presaleWeiRaised()","f7c07442":"getReferrals(address[])","f7c0f4c6":"calculateRates()","f7c0fa4a":"requireCorrectReceipt(uint256)","f7c2b38c":"seconds_left()","f7c360e0":"fee_claimer()","f7c38052":"createBuyOrder(address,uint256,uint8[],address[5][],uint256[6][],uint256[],uint8[],bytes32[],bytes32[])","f7c3b210":"ENCKToken(uint256,string,uint8,string)","f7c3ee7a":"immortality()","f7c42ac8":"onChainIdentities(address)","f7c46a73":"totalhospital()","f7c58b62":"weiPerEther()","f7c5f4b6":"getPreICOBonus()","f7c618c1":"rewardToken()","f7c68ffb":"isReleasedOnce()","f7c824f1":"CombineCard(uint32)","f7c8a091":"forPresale()","f7c8af48":"destroyItem(uint256)","f7c8d634":"tab(bytes32)","f7c9a7be":"drawTertiaryCWinners(uint256)","f7c9afa2":"onlyOwnerGetAdvWallet()","f7c9f1da":"setPonziPriceinWei(uint256)","f7c9f74a":"insert_contribution(address,uint256)","f7cab847":"getRule(bytes32)","f7cb5709":"CoinsLimitUnalterableInteger()","f7cb789a":"roundDuration()","f7cb8e66":"testIt()","f7cbcb8f":"withdrawCrowdsaleOsherCoins()","f7cc8c13":"MobSquads2()","f7cc8f40":"nbBackerWithMoreOrEqualTen()","f7cdf47c":"ETHEREUM()","f7ce25bb":"cardAndChecklistIdsForOwner(address)","f7ce4479":"setCommunityAddress(address)","f7cf0aa1":"updateMinBet(uint256)","f7cf9a1c":"Create(address,uint256,address,string)","f7cfd902":"removalBlackList(address)","f7d08eae":"distributeReserveSupply(uint256,address)","f7d0e04b":"setReputation(address)","f7d4c7e3":"getBracketDataFinals()","f7d518b5":"StartNewGame(string,string,string)","f7d5e485":"airdropToken(address[],uint256)","f7d6dbe5":"UpgradeProposals()","f7d7477b":"sumAmounts(uint256[])","f7d8417d":"MYRED(uint256,string,uint8,string)","f7d871df":"NucleusVisionAirDropTokensMinted(address,uint256)","f7d8c883":"breedWithAuto(uint256,uint256)","f7d9078e":"mintToSpecialFund(address)","f7d91cd4":"allocateReserveCompanyTokens()","f7d97577":"setPrice(uint256,uint256)","f7d978a2":"changeEntryFee(uint256)","f7d9a5ae":"BtcToken()","f7dadf7d":"setBurnFormula(address)","f7daef72":"getIndexBatchByUsername(bytes20[])","f7db7348":"preapprove(address,uint256,uint256,uint16)","f7dba1dc":"nullifyProduct(bytes32)","f7dc0455":"transferInitialAllocation(address,uint256)","f7dc909b":"createNewEvent(bytes32,string,string,uint256,string,string)","f7dd2e28":"BAG_TRANSFER_MINIMUM_AMOUNT_OF_BUYS()","f7ddfb4b":"meltingContract()","f7decfd1":"blacklistSwitch()","f7defe8c":"pickTheWinner()","f7df8f87":"vestingFounderAddress()","f7e0bc92":"COLOR_CUSTOM()","f7e0e743":"removeFirstAdvisorLock(address)","f7e23677":"catAttributes(uint256,uint256)","f7e23778":"PresaleEnd(uint256)","f7e28f8b":"weiRaisedAfterDiscountRounds()","f7e2ed66":"mOnTransfer(address,address,uint256)","f7e2ff00":"userWithdrawalStartTime()","f7e3c068":"PrestigeUp()","f7e3f00e":"PUBLIC_SALES_2_RATE()","f7e42647":"updateTrustRank(uint256)","f7e498f6":"verifyProof(bytes32,bytes,bytes,uint256,bytes32[])","f7e4a4a9":"hardCapPreSale()","f7e502cb":"HALToken()","f7e5951e":"_calcRemainReward()","f7e6af80":"_getOwner()","f7e74e65":"updateEmployee(uint256,uint256,string)","f7e77e44":"releaseMyVestedTokens()","f7e78e78":"verifyDeal(bytes32,bytes)","f7e7d6d8":"Noscam()","f7e80582":"enableAutoReinvest(uint256)","f7e83aee":"verify(bytes,bytes)","f7e95364":"updateGuMasks(uint256,uint256,uint256)","f7e98d15":"YELLOWLAMBO()","f7ea7a3d":"setTotalSupply(uint256)","f7ead092":"totalWinAmount()","f7eaec4f":"removeAgent(address,uint256)","f7eb4017":"findAddressByEndpoint(int256,string)","f7ebc39a":"isTransferAllowed(address,address,uint256)","f7ec221e":"authorizedToDraw()","f7ec2f35":"isContract()","f7ec7b51":"create_new_deal(uint32,uint256,uint32)","f7ecc428":"mintForInvestor(address,uint256)","f7ed6031":"getRoundDividendShare()","f7ed71d0":"left40(uint256)","f7edbbe6":"nextLapId()","f7ee503e":"editTicketPrice(uint256)","f7efd150":"create(address,address,string,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)","f7efd408":"votesIter(uint256)","f7f03516":"EasyHashingCoin()","f7f15304":"ARCD_FUND()","f7f1962e":"firstAuctionsInitialDuration()","f7f2210c":"openBetIndex()","f7f2741c":"AFTCoin()","f7f32916":"computeTokenWithBonus(uint256)","f7f33c54":"CriptaliaRewards()","f7f3815c":"setOperation(address)","f7f3ad16":"FixBet51()","f7f3da3b":"TestContractOne()","f7f4b9d4":"saleEnd1()","f7f50faa":"chunksAlreadyVested()","f7f5886e":"initializeS4FE(address)","f7f59411":"purchaseExistent(uint256)","f7f59b0f":"LogCustomerVerified(address,address,uint8)","f7f6d4da":"GreenEarthEconomyFund()","f7f74b56":"closeVoring()","f7f7915d":"setNextRoundFee(uint32)","f7f8303b":"product1_sell()","f7f87361":"DepositProxy(address,address)","f7f8aae9":"SudoEnabled(bool)","f7f9cb1c":"wrappedContract()","f7fad9fc":"UpdateState(uint256)","f7fb07b0":"getCurrentRate()","f7fb4801":"firstRoundWMEnd()","f7fc1bd6":"PROMETHEUS_SHIP_PRICE()","f7fc7783":"SanityPricing(address)","f7fc8a91":"haveShelf(string)","f7fca4f4":"setFeeFormula(address)","f7fca8d3":"ratePublicSale()","f7fce4da":"raffle_addr()","f7fd2e19":"TCoin()","f7fd3d01":"releaseCarbonDollar(uint256)","f7fe2e32":"newBurnableOpenPayment(address,uint256,uint256,string,string)","f7fe3477":"assertEq(bool,bool)","f7fe6f39":"fibo()","f7feeb31":"amendEntry(uint256,bytes32,bytes32,bytes32,bytes16,bytes1,bytes16,bytes32,bytes32)","f7ff50e2":"transaction_count()","f7ffaa5b":"ExTokeA()","f7ffbd85":"amountRemaining()","f7ffc366":"executeRulingB(uint256)","f80176ab":"GetEthereum(address,uint256)","f8018a79":"prepend(address,address)","f801fae9":"_fCancelDist()","f802075f":"requiredEndowment()","f8024d10":"getMemberAtIndex(uint256)","f80334ae":"selfDestruction()","f803bef0":"forceUpdateWinners(address[])","f803f97e":"transferAUTOtokens5(address[])","f8058bdf":"_CROWDSALE_PAUSED()","f805b300":"SALE_4WEEK_BONUS()","f8065ed6":"setStopMatchBetting()","f8083bab":"simulatedWithdrawal(address,address)","f8085c58":"updateStakerRanking(address)","f80979d6":"isPreSalePeriod(uint256)","f809c826":"managerToFunds(address)","f80af907":"roundThreeAmount()","f80b3564":"returnAddress(bytes32,uint8,bytes32[2])","f80b3cfa":"checkBetLowhigh(uint8)","f80bb2a7":"activateSubRound(uint256)","f80bbedc":"ethToToken(uint256,uint256)","f80d6e90":"GPHToken()","f80d9e58":"PVE_BATTLE()","f80db825":"AffiliateCoinMultiSigWallet()","f80dfdc2":"getTmpWriteTimestamp(bytes32)","f80e77d2":"updateETHNZD(uint256)","f80ea517":"getDealerInfo(string)","f80eba7c":"getTrapid(uint256,uint8)","f80f44f3":"right97(uint256)","f80f4ea8":"mintAdminApproval(address,address,uint256)","f80f5d4a":"EightteenToken()","f80f5dd5":"addWhitelist(address)","f80f96f6":"returnGanaBeforeSale(address)","f80fb7ae":"addCET4To(address,uint32,uint32)","f81126a7":"periodICOStage3()","f8115814":"TOKToken()","f8115891":"getSatTokensOwed(address)","f8125093":"set_devcon_map()","f8129cd2":"send(address,address[],uint256[])","f812f423":"advanceEndTime(uint256)","f8132b66":"lockCycle()","f813f027":"requestedTokens()","f813fcfa":"changeFooIntArrayDynamicSize(uint256)","f8140a7e":"standardFee()","f814530b":"_allocateETH(uint8,bool)","f81501f8":"smartContractPriceIsSet(uint256)","f815e6ab":"kdtFundDeposit()","f816f0aa":"gameCancelled(uint256)","f8185a13":"getBatches(address)","f818d723":"transferPower(address)","f8193547":"transferAndExecute(address,uint256,string,string)","f81a1860":"killOnUnsupportedFork()","f81a95db":"setReferrerFee(uint256)","f81b1998":"StopTransferGuard(address[])","f81bfa3f":"killThisContract()","f81d0292":"setParentAddress(address,address)","f81d087d":"prepareLottery()","f81d29df":"GambangCoin()","f81dc03f":"QuizwinToken()","f81de228":"getInvestorPacksAvailable()","f81dee03":"set_koef(uint256)","f81e8775":"resolveAddress(address)","f81ed6ae":"updateStart(uint256)","f81f8101":"initializedTime()","f81f8bf6":"burnReputation(uint256,address,bytes32)","f81ff8e7":"CurrentCoinPrice()","f8201a32":"requestLoan(uint128,address,address,address,uint256,uint64,bytes)","f821a17c":"getVotingNetworkDetails()","f821c423":"sendAirdrops(address[],uint256[])","f822372e":"Lab51TestToken()","f8225a05":"_setTransferFeeAbs(uint256)","f8226dbf":"TC(uint256,string,string)","f822841e":"PropertySet(address,bytes32,bytes32)","f8228f14":"assignSpartansToBattle(uint256)","f8229eba":"addAuthByCode(string,string,string)","f8241d7e":"updateAddresses(bytes32[],address[])","f8242c32":"addChallenge(address)","f824384a":"addInvestorAtID(uint256)","f8247299":"getIudexScoreAll(address,address)","f8256121":"publicResolver()","f8264772":"getTokenss()","f828500d":"isValidMessageLength(string)","f828c3fa":"scheduleCall(address,bytes4,bytes32,uint256)","f829d1a0":"walletSplitPercentage()","f82a4707":"secondsBetweenMints()","f82a7496":"giveMeCDP(uint256)","f82ab2ec":"PRIVATE_SALE_PRICE()","f82b2c31":"confirmByC(uint256,string)","f82bffa0":"get_merkle_proof(uint256)","f82c09a3":"PresentToCEO()","f82c2301":"resignFromCommunity()","f82c50f1":"log(uint256)","f82de7b0":"mineBlocks(uint256)","f82e4a4f":"Cointum(address,address,address,uint256,uint256,uint256)","f82ec3e6":"Norm()","f82edc1b":"unSign(address,address)","f82f396f":"sha(string,string)","f82f7a4b":"startDepositExit(uint256,address,uint256)","f82fb363":"icoController(address)","f82fe152":"PLAYER_METADATA()","f83064c7":"transferMintship(address)","f830c325":"updateToken(string,string)","f830d489":"depositExit(uint256,bytes32,bytes,bytes)","f83186f5":"HoryouToken()","f831aee6":"kingdomCreationFeeInFinney()","f831e962":"getWebStats()","f831ebab":"freezeTokens(address,uint256,uint256)","f831fe32":"updateApp(string,address,uint256,bool)","f833061b":"RESELLING_LOCKUP_PERIOD()","f8333e0e":"Aramco()","f8339005":"getSaddle(uint256)","f833f984":"OSEToken()","f8341fca":"BezantToken(string)","f8347242":"betsNum()","f834db41":"getBeneficiaryManage()","f834e212":"setGamePrize(uint256,uint256)","f8351daf":"winningCard()","f8354a82":"nextArenaTime()","f835a686":"setSaleEnd()","f835eb1b":"New(string,uint256,uint256,string,string)","f83629e0":"EBLCreation(uint256,string,string)","f83761e5":"setBAU2(bytes32,address,uint256,uint256)","f837e7c1":"battleAdd(uint256)","f838b0e9":"get_allowance_expires(address,address)","f838ea1a":"setDefaultMaxJump()","f838f6dd":"AssignBurnFees(address,uint256)","f8392303":"changeTicketMag(uint256)","f839407b":"setRateRoundSeed(uint256)","f83944ab":"LogEggAcquisition(address,uint256)","f839686d":"STSTEST7()","f839dc62":"pauseWork(uint256)","f839eb1a":"Referral(uint256,address,address,address)","f83a4c8a":"claimBet(uint8,uint8)","f83a768d":"addDiceRoll(uint256,uint256)","f83b5dce":"ec()","f83c4f82":"enableCirculation()","f83c6f64":"MIATOKEN()","f83ce05d":"deauthorizeBurnRequester(address)","f83d08ba":"lock()","f83d14e6":"buySketch(uint256)","f83d69db":"intMin(int256)","f83d96c1":"InsuranceAgent()","f83e3f5a":"SetProjectName(string)","f83e5793":"caged()","f83e9a20":"lock_period()","f83eb5dc":"forcedRefund(address)","f83fcdea":"setPrice(uint256,uint256,address)","f84038b1":"getMinimumContribution()","f8407634":"checkFunderAccount(address,address)","f8408a8d":"Funding_Setting_cashback_time_start()","f843545c":"active_payable()","f843b1b6":"singleWithdraw()","f843d4ec":"setEthereumBalance(uint256,bool)","f843dad6":"phaseTwoEnd()","f843ea4d":"updatePhaseSupplyAndBalance(uint256)","f844a9f4":"requestArbitration(bytes32,uint256,address,address)","f84501e0":"prosperaTokenAddress()","f84564f6":"RGTOKEN()","f845862f":"newUser(bytes32)","f8469646":"slice(address[],uint256,uint256)","f847b16d":"INAToken()","f848091a":"claimERC20(address,address,uint256)","f8482ca5":"Payroll()","f848d541":"withdrawLimit()","f84907d7":"tokens_backed(address)","f849acb8":"overrideLock(bool)","f84a0e74":"BSWCValueCirculateAssets()","f84a6519":"requiredDownPayment()","f84ad0fb":"ProvideWorkOrder(address,address,address,address,address,uint128)","f84af7f3":"isAssetIdOwnerOrApproved(address,uint256)","f84b2f51":"disqualified()","f84b624e":"ProjectCoin()","f84b903e":"distributed()","f84bcb11":"setEtherReceivers(address,address[])","f84ce165":"setEndStage1(uint256)","f84dcb1e":"CFToken()","f84ddf0b":"lastTokenId()","f84f30c4":"_isCorrectBuyin(uint256)","f84f420b":"getRandomNumber(address,uint256)","f84fce56":"isDraw()","f850a136":"get_lose_coefs()","f850a7a4":"_addUser(address,address)","f850b7f8":"ERC20YSLToken()","f851019a":"BONUS_50_100()","f8515cfc":"destroyFactory()","f8515eca":"Operable(address[])","f8516c6c":"groupPolicyInstance()","f851a440":"admin()","f8524236":"DeleteImage(uint256)","f852b976":"_updateState()","f853343d":"addStakeAD(uint256,address)","f8536b94":"participated(uint256,address)","f8538662":"signup(bytes32,bytes32)","f853ee49":"rateUSD()","f8542f5e":"getCopaCoreAddress()","f8548bea":"quarterFirst()","f8548e36":"transfer(uint256,address,uint256)","f854d74c":"withdrawCommunityTokens(address,uint256)","f856d605":"tokensPerEther()","f8570b01":"_newEpoch(uint256)","f85771b2":"removeManager(address,address)","f8579af8":"test_percPoints()","f8588593":"isSuperContract(address,address)","f85905ac":"testEqualityUint(int256)","f85a253f":"setTEx(address)","f85a3dea":"totalAmountOfEarlyPurchasesWithBonus()","f85aefba":"testBitsSetFailIndexOOB()","f85b2160":"recoverFailedLock()","f85c6b3b":"_safeGasCall(address,bytes)","f85cb0b5":"Start2()","f85cd33e":"timelockTokens()","f85d9cc7":"setReviveFee(uint256)","f85daa38":"authorityContractAddress()","f85e4854":"tokenIssuedPreSecondIco()","f85ef43b":"modifyPolicyAttribute(uint8,uint256,uint8)","f85f0972":"FoxicoPool(uint256,uint256,address)","f85f3b7f":"defaultIcoDeadline()","f85f8a3a":"BiTianToken()","f8605230":"getNewTeamPositionAndCheck(uint16,uint8,uint64)","f860a6d8":"withdrawlBalance()","f860e64a":"Lottery(uint256,uint256,uint256)","f8615d24":"getBio(address,bytes3)","f861d2bf":"MIRC()","f86282da":"doStateChanges()","f862d780":"addIn(address)","f862f6f4":"cap_nuru()","f86325ed":"BASE_PRICE()","f8635ece":"openSession()","f86418e5":"_privateSaleTransferFromOwner(address,uint256)","f864bc65":"lastBlock_a5Hash_uint256()","f864ca14":"withdrawToWallet(uint256)","f864e729":"getAvailableTokenForUser(address)","f8651d56":"Prether()","f868061e":"setICOExchangeRate(uint256)","f8688ddd":"setTargetFeePeriodDuration(uint256)","f869b11a":"declareVictor(uint256,uint256)","f869b3ff":"AdvisorsFund()","f86a3529":"totalStages()","f86a3eeb":"MyGaoguans()","f86a6334":"setCampaignStartDateById(bytes32,uint256)","f86abfd9":"mainSaleRateP4()","f86ae8b2":"TokenSaleStop()","f86b0669":"burner_addr()","f86b5ebc":"DANSSold()","f86c4354":"GovcTechnicalGases()","f86c8ed3":"blocksUntilNewPotentialWinner()","f86ccd41":"amountDeposited()","f86cd33d":"noThrowCall(address,bytes4)","f86da6ed":"checkTotalBets()","f86db133":"forwardWithRevert(address,uint256,bytes)","f86e898c":"hasMinCreatedOn(address,uint256,uint256)","f8702fe1":"calcFees(uint256,string,uint256)","f870849d":"GetBankerPrincipal(uint8)","f871cca9":"_check(uint8)","f871e0e1":"DutchAuction(address,address,address)","f8721a4e":"calcReturnValue(uint256,uint256)","f8721f1e":"nAlarms()","f8725493":"GCA1()","f872bec0":"sn()","f872c9dd":"Vote(address,string,uint256)","f8732d3e":"goodLuck(address,uint256)","f8737bc0":"nextUnlockTime()","f87394d6":"DonateEther()","f873d7e6":"initializeTrueUSD(uint256)","f8742a14":"hivePerUSD()","f87482e1":"changeMigrate(address)","f875c421":"delegateReferalTokens(address,uint88)","f876101c":"setConstantsContract(address)","f876250a":"getNumClonesInWild(uint256)","f876fe1a":"availableHavvens(address)","f8779524":"addNewGame(string,int8)","f87876c5":"resignFromMatch(uint256)","f8788382":"payService(uint256,uint32,string,uint64,uint64,uint64,uint64,uint64,uint64)","f8789e1a":"_createUnitHelper(uint256,address)","f878fcc2":"migrationAllowed()","f87aa82f":"_setBuyPrice(uint256)","f87aad3e":"SetAllLock(bool)","f87aba30":"placeBet(uint256,uint256,uint256,bool)","f87c77c0":"getVirtualChannel(bytes32)","f87d7236":"addCapFreeAddress(address)","f87e7446":"Houton()","f87eac7f":"lastBlock_v15()","f87f31c3":"mintMiniICOTokens(address,uint256)","f87f44b9":"setWebsite(string)","f87ffb74":"gameIdCntr()","f88001d4":"reopenSale()","f8801631":"getTotalDonateWEIInfo()","f8806544":"getBioLanguages(address)","f880f920":"calcMax()","f8811c36":"registerNewAccount(address)","f88218e0":"claimPheonix(address)","f8823353":"_isListed(address,address)","f88339a5":"CBOPToken(address)","f8833efd":"probabilities(uint256)","f88351d9":"getDividendsBalance(address)","f88371e8":"balancesLocked1Y()","f883dfb5":"initializeLevel()","f8840c38":"TopforceCoin(uint256,string,uint8,string)","f88489a6":"getBidIdsByToken(address)","f884e54a":"giveCat(bytes5,address)","f88573c8":"Administration()","f885eaf2":"returnAllowedTime()","f88607e4":"ICO_PRICE2()","f88649a1":"getLastWinner()","f8868778":"change(uint256[])","f886cbda":"reado()","f886e9b6":"removeRelation(address)","f8887cd3":"TransferToken(address,address,address,address,uint256)","f8895cc8":"schema()","f8896ea6":"Interim()","f8897945":"min()","f889ac54":"JP_sum()","f88a067f":"registerHotel(string)","f88a742b":"insertStage(uint8,uint256,uint256,uint256)","f88b07a3":"SoldToken()","f88b1f38":"balances6(uint256)","f88bf15a":"removeLiquidity(uint256,uint256,uint256,uint256)","f88bfe3e":"getCountStages()","f88cc87c":"decline(bytes32,bytes32)","f88cf827":"getVendorProducts(address,uint256,uint256,uint256,uint256,uint256,bool)","f88d2047":"cancelOrder(uint256,bool)","f88d6732":"dice(uint256)","f88e0b09":"getTransferValueValue()","f88e9fbf":"divide(uint256,uint256)","f88edaf2":"mMultiSigWallet()","f89005e7":"depositWithReference(string)","f8900ddd":"godAddress()","f89037a9":"TureTreasureChain()","f8907491":"isCollectionAllowed(bytes8,bytes8)","f890e286":"oracleOf(address)","f8910119":"AuctionStarted(uint256,uint256)","f8910241":"_getTokenAmountForBuyer(uint256,bool)","f892ee05":"subDevTwo()","f894d957":"signedApproveCheck(address,address,uint256,uint256,uint256,bytes32,address)","f895436a":"setLotteryParameters(uint256,uint256,uint256,uint256,bool)","f8956a67":"getBonus(address,address,uint256)","f896503a":"getConfigAddress(bytes32)","f896680c":"testInitialEtherBalanceShouldBeZero()","f8975cd9":"ZanteCoin()","f8976385":"RokToken()","f897ae8c":"numEmptyIndexes()","f897c998":"lastSaleTime()","f897ebbc":"setDelegatedFromOperation()","f8981789":"setCompliance(address)","f8984677":"_calculateMinimumprice()","f898e574":"incentiveDistributionDate()","f898f8ab":"Escapable(address,address)","f8995981":"ABAS()","f899b607":"FxdCoin()","f899e9f3":"annihilateShares(address,uint256)","f89a053b":"setAccountFeeModifiers(address,uint256,uint256)","f89a5100":"RGP()","f89a77b1":"removeValidator(address,bool)","f89be593":"softcap()","f89ca001":"revealMove(bytes32,uint256,bytes32)","f89e4df3":"saleMilk(uint256,uint256)","f89e6512":"CMDCrowdsale()","f89ea906":"_refundExcess(address,uint256)","f89eae17":"testStop()","f89f2a65":"addExchanger(address)","f89f3834":"getAccountChartDetailsByEntityId(address)","f89f74bf":"MATCHES_PER_ROUND()","f89f7cb3":"updateDrawPeriod(uint256)","f89fdabc":"TokenTransferContract(address,address)","f8a09cd0":"settlementDetails(uint64)","f8a0cdee":"addUserRewardPayouts(address,uint256)","f8a17d7f":"League(address,uint256)","f8a21631":"PrivateCoinSupply()","f8a321e1":"checkInvestorContribution(address)","f8a34b26":"presale(address,uint256)","f8a35b35":"maximumSubscription()","f8a39a6e":"test_twoTrueAssertNoMessage()","f8a3ce82":"resetSession()","f8a40b7d":"requestSetWithdrawalLimit(address,uint256,string)","f8a46568":"HashnodeProCoin()","f8a47213":"VnixNetwork()","f8a4cc33":"withdrawPoly(uint256)","f8a4e608":"verifiedKYCAddresses(address)","f8a5399a":"settleExtraToken(address)","f8a56efd":"balanceOfRaws(address)","f8a5a8dd":"getTranchesLength()","f8a6172e":"receiveToken(address,uint256,address,bytes)","f8a6c595":"constructor(address)","f8a6fca8":"confirmImperfectReception(uint256)","f8a777f5":"batchCreateInternalDrawings()","f8a8fd6d":"test()","f8a9972a":"selectWinner20()","f8a9c6ae":"golix()","f8aa0a59":"updatebalance()","f8aa836b":"THRESHOLD2()","f8aabbd9":"makeTJs(address)","f8ab02dd":"isRefAvailable(address)","f8ab745e":"validTransfer(uint256)","f8abb93d":"hasVotedOnUpgradePoll(uint8,address)","f8abe7f2":"testSandwichOrder(uint256,address)","f8ac6570":"tokensBoughtInEarlybird()","f8ad69a8":"HetherToken()","f8adb686":"earlyBackerSupplyRemaining()","f8adccdb":"doPartnerShares(uint256)","f8aed03a":"btcsPortionTotal()","f8af2514":"IsItConstantinople()","f8af56b7":"_finish()","f8af9e6f":"setAdv(uint256,string,string)","f8b096bb":"setupRegion(uint256,uint256,uint256[],bool,uint8[128])","f8b0c0b6":"getTransferStat()","f8b10464":"pause_PRIVATESALE()","f8b11853":"getGenerationStartAt(uint256)","f8b14500":"EmissionProvider(address,address,address,uint256,uint256,uint256,uint256)","f8b1db8f":"donationBoxes(bytes32)","f8b28c26":"getSecretByHash(bytes32)","f8b2cb4f":"getBalance(address)","f8b2e259":"lowCapWei()","f8b332ad":"onpayInstallment(uint256,address,uint256)","f8b367c1":"categoryCap(uint256)","f8b3d3b1":"receiveInitialFunds()","f8b45b06":"totalsData()","f8b4ab7a":"updateTotalSupply(uint256,uint256)","f8b4cfc6":"lock(uint8,uint256)","f8b4e080":"changeRateOfToken(uint256)","f8b542c8":"_0xPeriheliaToken()","f8b608a1":"addTournamentContender(address,uint256[])","f8b71c64":"rewardTo(address,uint256)","f8b746dd":"BdpEntryPoint(address[16],bytes8)","f8b89dfb":"setStep(uint8)","f8b991e8":"firstRewardPeriodEndBlock()","f8ba7317":"sealManualMigration()","f8ba8e6a":"getAllowanceAmount(address)","f8bb201c":"setCroupier(address)","f8bb9160":"TIGER()","f8bbca99":"multivestBuy(address,uint256,uint256)","f8bc0505":"left76(uint256)","f8bc8548":"getPOOL_edit_31()","f8bd4498":"AMOUNT_BASETEAM()","f8bd526e":"setCoinageContract(address)","f8bd71c7":"unstop()","f8bdbb60":"assertEq10(bytes10,bytes10)","f8bdc9dd":"get_shares()","f8bf77ae":"managedContracts(uint256,address)","f8bfb34c":"getBorderValue(uint256)","f8c1c186":"isSale()","f8c206b0":"killFaucet(address,address,string,address)","f8c25c48":"changeCreatorBalance(uint256)","f8c28ce0":"releaseOperation()","f8c32ccb":"APG()","f8c34050":"priceIncrease()","f8c3a293":"ADVISORS_AND_PARTNERS_PER_CENT()","f8c439dc":"ETH_EUR()","f8c46eff":"FinalizableToken(string,string,uint8,uint256)","f8c4892f":"transferProxy(address,address,uint256,uint256,uint8,bytes32,bytes32,string)","f8c4ab92":"getNewCumulativeAllowance()","f8c52125":"deriveMarketCreatorFeeAmount(uint256)","f8c587ac":"paper()","f8c5e217":"getSellRatio()","f8c64800":"signTwo()","f8c65bae":"Bgc(uint256,string,string)","f8c75351":"transferViaProxy(address,address,address,uint256)","f8c80d26":"privateCreation()","f8c8282b":"transfer_storage_ownership(address)","f8c8765e":"initialize(address,address,address,address)","f8c8de10":"stringToUint8(string)","f8c95160":"tokenEmission5(address,uint256,address,uint256,address,uint256,address,uint256,address,uint256)","f8ca3e22":"CustomCrowdsale(uint256,uint256,uint256,uint256,address,address)","f8ca9442":"getBalance_in_token()","f8cbd580":"freezeIndex(uint256)","f8cc1055":"transferCallership(address,uint256)","f8ccb027":"AdminTransferred(address,address)","f8ccbd38":"validPurchaseForManual()","f8ce3164":"accumulatedFee()","f8ce5894":"updatePrizePool(address)","f8cf0e1c":"unlockAddr(address)","f8d09593":"Kikicoin(uint256,string,string)","f8d1f5f0":"setProvider(uint8,address)","f8d29219":"fundingStartUnixTimestamp()","f8d29f8a":"hasProfilePicture(address,address)","f8d3277d":"removeFromWhitelist(address,address)","f8d3a26a":"QuasaCoinExchanger()","f8d3afa4":"numberOfTransactions()","f8d3e256":"publicLockEnd()","f8d420a1":"cancelGame(uint32)","f8d50542":"addToWhitelist(address[],uint256[])","f8d506e1":"TCNYCoin()","f8d578f0":"registerContribution(bytes32,address,uint256)","f8d599eb":"appendContribution(address,uint256)","f8d609b2":"assert_ex(bool)","f8d67506":"Shop(uint256,address)","f8d6b70a":"setAyantDroitEconomique_Compte_5(uint256)","f8d7f790":"COMMUNITY()","f8d86bbc":"setNewEndtime(address,uint256,uint256,uint256)","f8d93136":"Savings(uint256,uint256)","f8d95520":"extUnlockNinja(uint256,uint16)","f8d970b6":"checkTemplateRequirements(bytes32,bytes32,bool,uint8)","f8d988d6":"toExchange(address)","f8daa0ee":"transferGroupCommune(uint256,address)","f8dad3db":"MAXIMUMINVESTMENTSALLOWED()","f8db188b":"MeetToken()","f8db5d07":"unlockKyc(address)","f8db71b5":"getStatusContract(address)","f8dc11cc":"soldTokenInPublicsale()","f8dc5dd9":"removeOwner(address,address,uint256)","f8dcbddb":"setStep(uint256)","f8dcc3e0":"getLinkStatus(bytes32,address)","f8dcc9a9":"potato()","f8dd1764":"ClearToken(address,address,address,address,address)","f8ddd288":"s31(bytes1)","f8de2dfd":"destroyCoins(address,uint256)","f8dea17f":"startraffle()","f8df084d":"ZUR()","f8dfaa1e":"ret_img(uint256)","f8e0cc1c":"getPI_edit_32()","f8e1badd":"getCrowdsalePrice()","f8e1ec40":"CTOcoin()","f8e217c4":"getDivBalance(address)","f8e29885":"get_game_balance()","f8e2d041":"maxNumberMembers()","f8e2dc6a":"rangeOfBets(uint256,uint256)","f8e39177":"intrepidShipMinted()","f8e3aa92":"sendNugget(address,uint256)","f8e43382":"icoRunningStatus()","f8e4500a":"getTokenIssued(address)","f8e48488":"returnDevelopersCut(uint256)","f8e4ed5f":"escrowDecision(uint256,uint256,address)","f8e5521a":"getBlockHashOddOrEven(uint256)","f8e58024":"colors()","f8e65295":"storeIt(string)","f8e6a8cf":"payETH(address)","f8e6b331":"jtest()","f8e7577d":"FIBToken()","f8e76cc0":"_exists(uint256)","f8e8b93d":"setTrueUSD(address)","f8e8e035":"COSHACNYToken(address)","f8ea5daf":"withdrawalEnabled()","f8eac151":"Multiply(uint256,uint256)","f8ead7cf":"getUserAverageDividendRate(address)","f8eb5fc5":"getSalePrice(uint256)","f8ebabcd":"_setPixelBlockPrice(uint256,uint256,uint256)","f8ebf282":"changeHSShopPrice(uint256,uint256)","f8ec4bf2":"setAllowTransactions(bool)","f8ec4cd5":"withdrawBidForCollectible(uint256,uint256)","f8ec6911":"buyback()","f8ec7e83":"test_updateKey_zeroNewKey()","f8ecb558":"getFishByAddress(address)","f8eee5d6":"returnPaidBackBlock(uint256)","f8ef13f4":"EthbetToken()","f8ef9a3d":"getPaymentLog(uint256)","f8efaf2b":"partner_2_name()","f8eff67c":"takeInvest()","f8f079bb":"reserveAllocation()","f8f122ba":"numCompletedRequests()","f8f1939d":"PRESALE_TOKEN_CAP()","f8f1d927":"multiERC20TransferTightlyPacked(address,bytes32[])","f8f1f151":"testToAddress(bytes)","f8f2d5e4":"preIcoTokensCount()","f8f32de6":"revealAssertion(uint128,uint256,uint256,uint256,string)","f8f46b5f":"getCurrentMinerAddress()","f8f53ce7":"nestedSecondAnyToAny(uint256)","f8f5cefd":"updateNextMemberPayment(address,uint256,uint256)","f8f63375":"YXLToken()","f8f6773b":"calculatePurchaseBonus(uint256)","f8f6882e":"LavaWallet()","f8f6e080":"UnclaimedDividendTransfer(uint256,uint256)","f8f7312d":"ChangeBurnBoundsEvent(uint256,uint256)","f8f73808":"create(address[],uint256)","f8f8a912":"GetBalance()","f8f9271c":"changeRegistrationStatusForSilverWhiteList(address,bool)","f8f9456c":"CrowdsaleFactory(address)","f8f96a55":"lastBlock_v6Hash_uint256()","f8f9be36":"settlementRegistration(uint64)","f8fb1d0f":"countUsers()","f8fb1f07":"sponsorsOf(uint256)","f8fb3366":"stopPreSale()","f8fb491f":"setSaleAddress(address)","f8fb4ab7":"NBAT001(address,address,address,address,address)","f8fbdbb6":"getChkLockedTokens(address,uint256)","f8fc16ef":"minWeiToAccept()","f8fc6fcd":"QNBAI()","f8fc94aa":"refundTransactionAfterExpiryFee(uint256)","f8fd72ac":"getCompte_44()","f8fdebd3":"weiMaxCap()","f8fe2f9d":"KyberGenesisToken(address)","f8fe63b0":"getERC721Id(uint256,address)","f8ff612e":"WithdrawToHolder(address,uint256)","f8ffe42a":"SetCoefRew(uint256)","f900592a":"ToggleTransferAllowance(bool)","f900b5d6":"getUserTotalPaid(address,address)","f9010d19":"joinEvent()","f901a18f":"setSale(uint256,uint256)","f9020e33":"saleStatus()","f9039f33":"update_current_rate(uint256,string)","f904b9ff":"GXDHRPToken()","f9059832":"isSaleEnded()","f906a440":"getInvoice(string)","f9079685":"SPCoin()","f9081ba2":"safeContract()","f908326b":"payRewardForAddress(address,address)","f9084729":"pvt_plmt_token_generated()","f9094303":"finishVoting()","f909640c":"InitialPriceDisable()","f909d60d":"getMinimumGasLimit()","f90a2f30":"usedNonce(address,uint256)","f90b2bfe":"dissolve(uint256)","f90b2e74":"setInitialTime()","f90c3f27":"FUNDING_PERIOD()","f90ce548":"SmartDeposit()","f90cf0a4":"Land(address)","f90ddee2":"tokenBurners(address)","f90e292c":"stage3Start()","f90f11b7":"withdrawNVTfromGame(uint256,uint256)","f90f3278":"resetUsername(string)","f90f4560":"placeBet()","f90f4a30":"Matthew()","f90fa5dd":"sendTokensToAdvisorsLock(address)","f910feaa":"safeTransfer()","f912e58c":"setPreCrowdsaleAddress(address)","f912ed00":"lockMe()","f913a879":"getBidsNum(address)","f913b919":"setAssetLevel(uint16,uint256)","f9146b2f":"newRefPayStation(address)","f9153fbc":"changeHouse(address)","f9154476":"__redeemAmount(address)","f915cf42":"MINIMUM_BET_VALUE()","f9163e64":"lockUpAmountStrOf(address,address)","f9172266":"setOldSeelToken(address)","f9174551":"cooperativeSettle(address,address,uint256,address,address,uint256,bytes,bytes)","f9177aad":"CreateFBL(address,uint256)","f9190fcc":"smartSponsor(address)","f9191b18":"revealVotes(address,bytes32,bytes32,address[],uint256[],uint256[])","f9195a30":"doFunding(bytes32,string,address,uint256,address)","f91a545b":"getLossTokenAmount()","f91a792e":"decryptHand(string,uint256,uint256,uint256)","f91b853b":"upgradeFrom2To3()","f91bcd76":"getMintForReportingParticipantAmountValue()","f91c022b":"secondTokenCap()","f91c26a5":"dLogN()","f91c339e":"calculateTxHash(address,address[],uint256[])","f91cb3d6":"proposalAvatar(bytes32)","f91d4db7":"TokenTracker(uint256)","f91e89db":"maxMonsterHit()","f91f681f":"targetFromBits(uint32)","f91f87f2":"tokenDistributionDuration()","f9215676":"paymentsByCustomer(uint128)","f921991c":"transferTokensWithOffsetAndLimit(uint256,uint256)","f922501a":"CRYPTOBULL()","f9226daf":"LogWithdrawal(address,uint256,uint256)","f922da7e":"addTokensToCampaign(bytes32,uint256)","f922f216":"disableERC20()","f923058c":"get_total_supply()","f923b8aa":"setBCY(uint256)","f9244a9b":"sendToMinter(uint256)","f9249fbf":"initiateTeamVesting(address)","f924c276":"fechStageIndexBySnapshotBlock(uint256)","f92561f3":"lambosBuildCount()","f9261d3f":"setProviderDetails(address,string,string,string,uint8,address)","f9268170":"setEdgePerPosition(uint256)","f926ac20":"totalInWei()","f9271fd3":"changeFundAddress(address)","f928655b":"transferA2B(address,address)","f92883a2":"mint(address,uint256,uint256,uint256,uint256)","f9297a40":"getPrice(bytes,int256)","f92a373b":"payForOption(address,address,address,uint256)","f92a69ec":"createPolicy(address,uint256,uint8,bytes32,bytes32)","f92a73d7":"ICONIQ_SALE_CLOSING_TIME()","f92a7595":"fxpMul(int256,int256,int256)","f92a79ff":"getExecutor(bytes)","f92a9de5":"developmentFunds()","f92abed9":"GetEvaluate(uint32,uint8)","f92ad219":"initialize(address,uint256,uint256,uint256,uint256)","f92b359a":"instrumentManifest()","f92b9dc7":"TVThreshold()","f92bb8c9":"getConfigUint(bytes32)","f92c33f7":"EventLuckyNumberRevealed(address,uint256,uint256,address)","f92c45b7":"reservedAmount()","f92c6bb6":"getGuessStatus(uint256,uint256)","f92c9b47":"TOKENS_FUTURE()","f92caf3a":"UploadIMG()","f92cd2b2":"airdropTokensBatch(address[],uint256[])","f92ec991":"preEtherReceived()","f92fff12":"requestEtherToUSD(bool,uint256,uint256)","f9307837":"setMaxcap(uint256)","f930a3d2":"presaleMint(address,uint256,uint256)","f9319a88":"SECOND_TIER_RATE()","f931eaef":"untokenizeProperty(string)","f931edb4":"ClaimedTokens(address,address,uint256)","f93231ba":"GetAskingTokenMutiplier()","f932380e":"RoyalPanties(uint256,string,string)","f9323a32":"_selling()","f9324c5f":"EarlyBird(bool)","f9327b9f":"preSaleDeadline()","f933b844":"_addToVesting(address,address,uint256,uint256)","f9355dca":"functionFour()","f93589ce":"didWin(bytes)","f935ae8b":"requestExchangeRate(string,string)","f935fd94":"WeiTransfer(address,uint256)","f937a6eb":"setLockup_investors(address,uint256,uint256)","f938075c":"weiToRecoverPreICO(address)","f9391d24":"AllPayAuction()","f939499d":"backupfarmSingle(address,address,uint256)","f9394c10":"getCarrotCredits()","f93a2109":"ADT()","f93a8d96":"EtheeraCrowdsale(uint256,address)","f93acbe9":"SubBankerProfit(uint8,uint256)","f93af357":"updateSigners(address,bool)","f93b4466":"LudumToken(address,address,address,address)","f93ca568":"ActualQueue()","f93d029a":"sendICOByOwner(address,uint256)","f93de2c3":"updateMinimumQuota(uint256)","f93e2d31":"adminEditCity(uint16,string,uint256,address)","f93e6715":"freeUntilDate()","f93ee24c":"addMinerTokens(uint32,address[],uint32[])","f93f1391":"getPokemonBetTimes(uint256)","f93f1b02":"incByTwo()","f93f7ab5":"saleRateFirstDay()","f93f9a76":"WhitelistUpdated(address,bool)","f93fc97b":"test_updateKey_increaseNoHint(int256)","f940e385":"withdraw(address,address)","f9419088":"mintNonFungible(uint256,address[])","f941c01a":"getOwnerToken()","f942be1c":"endDayOneTime()","f9432517":"transferLimit()","f94497fe":"testCreateWithParentsForeign0()","f944f4c7":"removeUser()","f9454f3f":"register(address,uint256,uint256)","f9455301":"setHoldTime(uint256)","f945b274":"jackpotTokenEthRate()","f945ba2d":"avatarFee()","f945e8b2":"getCurrentRound(uint256,uint256)","f946372c":"TOKENS_SALE_HARD_CAP()","f946d61c":"logReputationTokensTransferredCalled()","f94789bf":"KungfuToken()","f948d276":"changeShare(address,uint256)","f948e51a":"implementation2()","f949116d":"ICDCap()","f94a3223":"submitCro(bytes32,bytes32)","f94a360d":"MAXIMUM_BET_SIZE()","f94aa8bf":"BliBliToken(address,uint256)","f94b97c9":"IntoQueue(address,address)","f94c12cb":"cancelPendingChange()","f94c81c3":"RobotTradingToken(address)","f94c9e13":"getChannelInfo(address,address)","f94d2d44":"formatNumber(uint24,uint256)","f94d71a0":"unregisterObserver(address)","f94d7a10":"setTransferFromWhiteList(address,bool)","f94df54f":"importersBanksLetterOfCredit()","f94df678":"getAuthorizedEditAgents()","f94df97f":"Lotery(uint256,uint256,uint256,uint256,address,uint256)","f94e08d0":"queryWaitingTime()","f94e45de":"Scaltinof()","f94f04e4":"sendPresaleTokens(address,uint256)","f94f1e9a":"LifePasswordAI()","f94f6910":"POINTS_TO_LEVEL()","f9500927":"eth_amount_judgment(uint8)","f950db2b":"unfreezeUpgrade()","f951410d":"setBcouponTransferCost(uint256)","f9514ec9":"ApprovedBy(address)","f9515f1b":"addGroup(address)","f951f856":"getPeriodTotalReceived(uint256)","f952279e":"cancelOffer(bytes32)","f952f938":"CreateCreature(uint256,address)","f953927e":"openRoom(uint256,uint256,address)","f95440ba":"decimalPoints(bytes32)","f954501f":"validRouletteBetData(bytes,uint256)","f95547fa":"getGameFees(uint256)","f9565aec":"NewTokenGrant(address,address,uint256,uint256)","f9566392":"WeightedSubmission()","f956a1b5":"EthereumPinkToken()","f956c139":"getMatchIndex(uint256)","f956ecde":"invalidatePurchase(uint256)","f956fc52":"didWithdrawCollateral(bytes32,address,uint256)","f957417e":"activateToken()","f957ddba":"withdrawAllFrom(address)","f958530f":"bountyTransferToken(address[],uint256[])","f9586eaa":"setScouponAllocationFactor(uint256)","f9587219":"SetPetCardDataContact(address)","f9589eb3":"onceOuttime()","f95918eb":"indexOfUserInfo(uint256)","f959300b":"calculateSetupAllowedUntil(uint256)","f959fe4b":"admin_set_dividend(address,bool)","f95a5504":"buyandearn(uint256)","f95a77e5":"MALCoin(uint256,string,string)","f95a78fd":"milestone(uint64)","f95af64c":"freezeUpdateTokenAccount(address,bool)","f95af865":"selfWithdrawBalance()","f95afe2c":"getPortion(uint256)","f95b4309":"get_selected_player()","f95b5a58":"getInitialAnswer(uint256)","f95b5e0d":"mintTokensWithReferal(address,address,uint256)","f95bbc9c":"activeValueBonus()","f95c1a73":"allocationForESCBbyStage()","f95e0a54":"update(uint256,string,string)","f95e6306":"processInterval()","f95fbf67":"registerBarcode(bytes32,string,string,string,string,string,string)","f95fe2e7":"AddNewChallenge(uint256,uint256,uint256,uint256,bool)","f9609f08":"deposit(address,address)","f9614ac5":"content(string,address,uint256)","f9616bfa":"AidEvaCoin()","f9618364":"DGDb_Auction(address,address,address,address,uint256)","f9619147":"InbestDistribution(uint256,address)","f9639d80":"getCanAcceptAmount(address)","f963aac6":"CONFIG_MAX_PLAYERS()","f96512cc":"createPerDay()","f9654378":"TokenWithValidityPeriod(string,string,uint8,uint256,address,string,address)","f965e32e":"changeValue(uint256)","f9660347":"fetchAllBlocks()","f9662c8f":"returnInterest(uint256)","f9672443":"getMyEntityParents(uint256)","f9672820":"distributeARTTokenBatch(uint256)","f9676db4":"purchaseWithDai(uint256,uint256,uint256,uint256,address,bytes)","f96777d4":"payJackpotToWinner(address,uint256)","f9677e22":"computeSecret(uint256,address,address)","f96803d3":"getJobInvoicesByStatus(address,uint256,uint8)","f9683828":"coinback(uint256)","f968adbe":"maxPerTx()","f968f493":"unlockTokens()","f96a181e":"getContact(address)","f96abf0c":"deleteCrowdsaleContract(address)","f96b636d":"GILLIONTOKEN()","f96c166c":"isInPresalePhase()","f96cecc1":"returnAmount(address,uint256,bytes32)","f96d1c94":"closeStage()","f96ddf7a":"getSigner(bytes32,uint8,bytes32,bytes32)","f96eb003":"migrateManual(address)","f96f143e":"RELEASE_GAS_FEES()","f96f2fa1":"Shareable(address[],uint256)","f9706844":"recommendFundToPlayer(uint256,address,uint256)","f970bbfc":"removeDiscountStruct(uint256)","f97110a3":"getDeployedBlogs()","f9715458":"minActivatedToken()","f9718fc8":"returnTokens()","f971b054":"StoxSmartToken()","f972e2bf":"dateTransferable()","f974a1a2":"PURCHASE_AMOUNT_UNIT()","f974ae3c":"PrivateSaleExchangeRate(uint256)","f975a024":"openNonceId()","f975f3a2":"INITIAL_TOKEN_SUPPLY()","f976104f":"revokeDelegate(address,address,bytes32,address)","f976c371":"ZLHToken()","f9778d0d":"fixPlayerCountryId(uint256,uint256)","f9781eae":"test_curators()","f9782191":"fifth()","f978e842":"_addAdmin(address)","f97944e0":"CREATE_AMOUNT()","f9794660":"finneyToWei(uint256)","f9795a95":"minSlippageFactorInBps()","f979764d":"blockDotNumber()","f97a02fa":"inActive()","f97a9d38":"bonusSubscription()","f97b392a":"unregisterEmployee(address)","f97b65da":"closeShortPosition()","f97b7390":"getCurrentDiscountTrancheIndex()","f97bf9e4":"close(address,uint256,uint256,bytes)","f97c72b1":"_onBall(uint8,uint8,uint8,uint8,uint8[3][3][31])","f97cebed":"BellaStandardToken(uint256,string,uint8,string)","f97d0591":"parseTimestamp(uint256)","f97d8aee":"WriteBond(uint256,address,address)","f97e17d9":"payRate()","f97ea6fc":"getIndicesWithClaimableTokensForSellers(address,address,address,uint256)","f97f8e17":"takeOrder(address,address[5],uint256[8],bytes32,uint8,bytes32,bytes32)","f97fa1bd":"FrozenTokenEvent(address,uint256)","f98038ee":"howManyDicks()","f980a012":"mainSaleRateP1()","f980e52d":"clam()","f98139be":"getCensuredByCount(uint16)","f98157bd":"GetDeadline()","f9819884":"toggleDeathConfirmationByProxy()","f981aaca":"addDeal(uint256,string,string,uint256,string,bytes32)","f981f0c0":"_getAddress(address,bytes32)","f9820cc1":"Nothing()","f983c0fa":"run1()","f98456d2":"unenableTransfers()","f9854bfc":"creditsBalanceOf(address)","f985779c":"sin(uint16)","f985f5fc":"authorized_createCard(uint256,uint256,address,address)","f9869165":"ELIPSToken()","f9870705":"getProject(address)","f98765b2":"BotRemoved(address)","f988279c":"isAce(uint8)","f9888687":"raiseethamount()","f9889f78":"batchTransferFixedAmount(address,address[],uint256)","f988da4a":"TopsToken(uint256,string,uint8,string)","f9892c28":"ProofOfStableCoin()","f98a4eca":"executeVote(uint256)","f98b19f4":"publishBatch(uint16,uint16,string,string,bytes3)","f98b26a9":"submitProposal(address,uint256,uint256)","f98bbc60":"commit(address,bytes32,bytes,bytes32,uint8,bytes32,bytes32)","f98c48c1":"setData_18(string)","f98cbf76":"closeEXORImports()","f98d28bb":"priorityWallet()","f98d7c75":"SALE_STAKE()","f98e09a6":"listResources()","f98e17a7":"PerSellOver(uint16[])","f98e87ba":"hashedParameters()","f98eaa9c":"ClaimTokens(address,address,uint256)","f98f5b92":"setWhitelister(address)","f99031a7":"isWhiteList(address)","f9907274":"allTokenAddress()","f9909915":"bulkStoreHeader(bytes,int256,bytes,int256)","f990b73b":"end_crowdsale()","f991a43f":"currentTadpoleOwner()","f992905d":"deployContracts(uint256,address)","f9937c2b":"getCertificateKeys()","f9938192":"reenduser()","f993bef3":"postDeadline()","f993d955":"BTC_SUISSE_TIER_3()","f9943133":"MeltingContract()","f99450b9":"getEOSIO_USERNAME(uint256)","f994789a":"proposeRewardsWithdrawal(address)","f994bffa":"addCard(string,string,uint8,string,string)","f99514e2":"noInputReturn()","f9952ecf":"changeBoat(address)","f9953de5":"addOrg(string)","f9956289":"PRESALE_OPENING_TIME()","f99638a5":"bTest()","f9965dbf":"giveBounty(address[],uint256)","f996c697":"THRESHOLD1()","f9974d9d":"calculateWineSellSimple(uint256)","f9977329":"CROWDSALE_AMOUNT()","f997e136":"safeAdd(int256,int256)","f997f0c1":"_minHouseEdge()","f997f7eb":"ojiletoken()","f998393c":"Icostart()","f9983a12":"GetMyInvestmentBalance()","f9991f33":"AddProject(uint256,address)","f999ad04":"CreatePCC(address,uint256)","f999eead":"donateToDivs()","f99b7f0b":"getAllMatches(uint256)","f99ca1ee":"productionOf(address)","f99ca808":"totalDonationsWithBonuses()","f99cc96e":"tokenMaxSupply()","f99d18eb":"VIUREFoundersTokenSale(uint256,uint256,address)","f99d948f":"gameExpirationTime()","f99e574b":"BCEK(uint256,string,string)","f99ebb71":"testFailUpdateLatestRevisionEnforceRevisions()","f99ec32c":"lastFreezeSeq(uint8)","f99ee846":"KEACoin(uint256,uint256)","f99f128c":"make_initial_deposit(uint256)","f99f977c":"bountyPercentOfTotal()","f99fc046":"dEthereumlotteryNet()","f99fddae":"isValidUser(address,uint256)","f99ff180":"readMail(uint256,bytes16)","f99ff4df":"paged(uint256,uint256)","f9a01e94":"mintReward(address,uint256,uint256,uint256,uint256,uint256)","f9a075dc":"releaseETH(uint256)","f9a0fcc7":"RequestEthereum(address,address)","f9a191c8":"giveDirectoryTokenAllowance(uint256,address,uint256)","f9a2916f":"getInitiated()","f9a2cbd5":"INTREPID_SHIP_LIMIT()","f9a32246":"_transferFromToICAPWithReference(address,bytes32,uint256,string,address)","f9a329a6":"toVault()","f9a381e2":"CurrentToken()","f9a3e07d":"getObjInfoWithBp(uint64)","f9a42b8b":"_updateSpaceshipPrice(uint256)","f9a56fd8":"GamersCoin1()","f9a57ae4":"notDistributedAmount()","f9a596dd":"validatePrograms(uint256[])","f9a6da0c":"pks()","f9a794ad":"EtherLovers()","f9a7a2ef":"named(bytes)","f9a7c906":"setBonusTokenRateLevelTwo(uint256)","f9a86856":"maxWeiSMSVerified()","f9a87d4f":"buyAllAmountBuyEth(address,address,uint256,address,uint256)","f9a8b0ba":"latchTotalFci(uint256)","f9a8b611":"moveUnsold(address)","f9a8c5b9":"teamSum()","f9a8e898":"slashReservedUsername(bytes,bytes32[])","f9a8f797":"setLatestContract(address)","f9a94d43":"finalisePreSale()","f9a94ecd":"SellTokenToRaj()","f9ab21e2":"indexOf(uint32[],uint32,bool)","f9ac71bf":"allowNorthPoleMinting()","f9add1b9":"ourLastWinner()","f9ae77ff":"supportNewPurge(address,address,uint256)","f9aef74e":"PureGold()","f9b04f72":"reinvestByProxy(address)","f9b07b9b":"TeikhosBounty()","f9b16430":"HonestisNetworkETHpreICO()","f9b18e72":"RentableProvider(string,string)","f9b207f6":"Teepee()","f9b290b6":"PDPCointoken()","f9b2b19a":"getCns()","f9b2d1ee":"buyForFriend(address)","f9b2ec8e":"MinStarIndexAvailable()","f9b35ca3":"seed_traded_token()","f9b3e7f0":"hashAccountId(string)","f9b41139":"getBoxCount(uint16)","f9b4257d":"newXcat(bytes32,address,string,uint256,string,uint256,uint256)","f9b4d63a":"ownerOff(address)","f9b5c633":"ICONClassicToken()","f9b6b0c4":"create(address,uint256,uint256,uint256,uint256)","f9b71e73":"tankImposedMax()","f9b7fb56":"MarketboardListingBuyback(address,uint256)","f9b83323":"getNumberOfChecks()","f9b8659f":"detach(uint32,int256)","f9b87d40":"setKeys(uint32,bytes32,bytes32,uint32)","f9b8d639":"getMemberBonus(address)","f9b9a626":"getTotalWithdraws()","f9ba134d":"subtractAmount(address,uint256,uint256)","f9baa6ec":"freezingAgent(address)","f9bacc1c":"totalBonuses()","f9bb656b":"crowdSaleState()","f9bb84f5":"areWeekdaysOpen(uint256[],uint256[],uint256,uint256)","f9bbcc6d":"setMinVoteWeightK(uint256)","f9bcb4b1":"symbolLocked()","f9bd9338":"onFrozenAccount(address,bool)","f9be029f":"disableWhitelistAddress(address)","f9be437a":"UpdateTokenAddress(address)","f9befdef":"ownerSetGasLimit(uint256)","f9bfc71b":"mulUIntValue(bytes32,uint256)","f9bffc0f":"phID_()","f9c113cb":"ReadContent(string)","f9c12dda":"collectAll(uint8)","f9c1437e":"test5_searchAcrossNodes()","f9c1a197":"TransferEthToAddr(address,uint256)","f9c29e66":"hashOrder_(address[7],uint256[7],uint8,uint8,uint8,bytes,bytes,bytes)","f9c38ebf":"APTest1()","f9c397f8":"VoteInOrganizationScheme()","f9c3a68e":"setminimumAmount(uint256)","f9c447a9":"PurchasedTokens(address,uint256)","f9c58926":"_emitJobOfferPosted(uint256,address,uint256,uint256,uint256)","f9c5e0aa":"updateAttribute(bytes32,bytes32)","f9c6046a":"setForDutchSale(uint256,uint256,uint256)","f9c638ea":"globalMin()","f9c71f79":"isEquipedAny3(address,uint256,uint256,uint256)","f9c78097":"betToken(address)","f9c809fe":"addTip(address,bytes32,uint256)","f9c811f1":"regWL(address,uint256)","f9c8dec3":"KYC_ROLE()","f9c926c1":"has(address,address)","f9c935cf":"discountValue5()","f9c9b9de":"ExperimentalToken()","f9cb1b48":"getTotalInvestment()","f9cb6d7a":"reservedTokensAreDistributed()","f9cbcef0":"setStages(uint32[],uint8[],uint32[])","f9cbec43":"transferLandToEstate(int256,int256,uint256)","f9cc0605":"getAvailable()","f9cc2e66":"setPlatformFeePer10000(uint256)","f9cc6fce":"TestIOTACoin()","f9cd3ceb":"oracleFee()","f9cdbc4e":"paySmartContract(bytes32,uint256[])","f9ce67dd":"compareToIgnoreCase(string,string)","f9ce733b":"Pets()","f9ce7813":"transfer(address,address,uint256,address)","f9cee7b5":"totalScammedQuantity()","f9d09126":"updateTopicAssetClass(bytes15,bytes15)","f9d0fed4":"allowanceProvider()","f9d13bf0":"validate(address[4],address,uint256[12],uint256,uint256)","f9d176b4":"setManualWithdraw(bool)","f9d20590":"distributeFinancialAward(bytes12,int256,bytes12)","f9d38868":"exy()","f9d3b4e9":"obol()","f9d429ee":"NO_BATTLE_LOG()","f9d49797":"whitelistMaxWei(address)","f9d53ac8":"addPaper(address)","f9d593c8":"setNAVAdmin(address,address)","f9d5b4bb":"LogContribution(address,uint256,uint256,uint8,uint8)","f9d5e08b":"adminUsrCount()","f9d630a1":"TUI_ALLOCATION()","f9d6de48":"WALLET_LB_COMMUNITY()","f9d70200":"buyCrystal(uint256,uint256)","f9d75f25":"editDailyLimit(uint256)","f9d7f0fc":"CSES2()","f9d80dcd":"getInstanceImplementation(bytes32)","f9d8241c":"renterExists(address)","f9dbe5e9":"_updateStage(uint256,uint256)","f9dc0793":"getCustomerBankName(string)","f9dc5d43":"getAllPayment(uint256)","f9dca989":"becomeOwner()","f9dcef27":"cityPoolCutPercentage()","f9df65eb":"nullified()","f9df6c33":"calculateTokensAmount(uint256,bool)","f9df816a":"changeWhitelistPrivateStatuses(address[],bool)","f9dfa4a3":"setMaximumEtherToAccept(uint256)","f9dfb361":"preSaleStartBlock()","f9dfcfcc":"transferContract(address,address,address)","f9dfd0a5":"Token(address,string,string,uint8,uint256)","f9dfea54":"relockGroup(uint256)","f9dfecb9":"preICOTokens(uint256,uint256)","f9e0093d":"multiWithdraw(address[])","f9e05ed9":"sha(uint128)","f9e13de4":"doMigration(uint256,uint256)","f9e19fa5":"resetState()","f9e1ceda":"getBalancePercentRate()","f9e24dc2":"balanceOfMineral()","f9e27106":"investmentEntryCost()","f9e37733":"_createUnicorn(address)","f9e3c1e9":"setNextAddr(address)","f9e40a21":"allWon()","f9e4fb34":"fundTransferIn(address,address,uint256)","f9e51b1d":"withdraw(uint128,string,uint32)","f9e54282":"dropUsername(bytes32)","f9e68952":"createDrone()","f9e73764":"airdropExecute(address,address[],uint256)","f9e84395":"unexempt(address)","f9e856ae":"oldE4RecycleBin()","f9e8ad7c":"isPreIcoStage()","f9e9d34a":"getUserRefBalance(address,address)","f9ea3a18":"getHTLCSpendingData(uint256,int256,bytes32)","f9ea8839":"AlphaMarketCoinExchanger(address[],address)","f9eab09f":"setChickenHunt(address)","f9eb4ee2":"APPROVAL(address,address)","f9eba935":"debit(string,uint256)","f9ebdc8b":"isConfirmed(bytes32,address,address)","f9ec2edb":"startNewBoss()","f9eec610":"next(string,string,string,string,string,string)","f9eee901":"setClaimTreshold(uint256)","f9ef04be":"free(address,bytes32,uint256)","f9ef2c7d":"HTC()","f9ef33ff":"walletOEM()","f9ef66f5":"getRoundWinnings(address,uint256)","f9f03556":"ERC20(uint256,string,string)","f9f0507f":"timeLockedStart()","f9f14f6a":"library14function()","f9f16ef2":"numberOfTokens()","f9f20540":"setInvestTokenLimit(uint256)","f9f22d6c":"createNamespace(string,address)","f9f286f9":"setMultisigMain(address)","f9f2c161":"setGod(address)","f9f2c93c":"santaClaus()","f9f2ecb6":"getExtendAddr(address)","f9f39a9c":"initialize_bannable(address)","f9f411d8":"userTokens(address,uint256)","f9f447eb":"getCallDataHash(bytes32)","f9f53be0":"ChangeAmountPrice(uint256)","f9f5e8c8":"changeToCoin(address,address,uint256)","f9f71423":"increasePlayersGooProduction(uint256)","f9f73135":"get_heap(uint256)","f9f7d9de":"TOTAL_PERCRENTS()","f9f81a73":"setAccountCoords(string)","f9f86baf":"airdrop(address[],uint256[],uint8)","f9f8b586":"JMToken()","f9f8bdb7":"currentRate()","f9f8f895":"switchOn()","f9f90a60":"durationInBlocks()","f9f92be4":"blacklist(address)","f9f94bc6":"bioUnlock(bytes32,uint8,bytes32,bytes32)","f9fae4f7":"TOKEN_CREATION_CAP()","f9fafb59":"LogBidFinal(address,uint256,uint256,uint256)","f9fb12ad":"TestXRPCoin()","f9fb3c95":"transferBonus(address,uint256)","f9fb452f":"productID()","f9fbd554":"test(string)","f9fc0d07":"processRewards()","f9fc4816":"withdrawAmountETH(uint256)","f9fd41d8":"setRevolution(address)","f9fd5250":"DOW_MON()","f9fef3b3":"withMod(uint256)","f9ff1378":"solicitaDevolucao()","f9ffabca":"NewAdmin(address,address)","fa003b2e":"SCCAIToken(address,address)","fa006d87":"newPlaySeed(address)","fa009e36":"xxx7Coin()","fa0196eb":"OsherCoinAward(uint256)","fa01dc06":"revoked(address)","fa01dd3c":"BRTToken()","fa02955f":"registerMeOnEther(string)","fa02c4b7":"approveTransfer(address,uint256)","fa02dcc1":"TankWithdrawAll()","fa030ef1":"baba()","fa03446c":"tokensFromEther()","fa036370":"Athereum()","fa043b0f":"checkSig(bytes32,bytes32,uint8,bytes32,bytes32,address)","fa044862":"requireOk(bytes1)","fa048a18":"addHpbNode(address,bytes32,bytes32)","fa05064e":"setBountyDistributionContract(address)","fa058795":"logAdr(address)","fa061d48":"isReadyToSynthesize(uint256)","fa066fbd":"AccountGasLimitReached()","fa097028":"_burnRemainingTokens()","fa09cb30":"PatCoin()","fa09e630":"withdrawAll(address)","fa0a6cfe":"AFEBToken()","fa0a8f26":"calculateNextPrice(uint256,uint8)","fa0b5e55":"registerUser(address,uint256)","fa0b6211":"hasRoundEnded()","fa0bad28":"onholdBalance()","fa0bc8e1":"ownerOfSocialIdentity(uint256,uint256)","fa0c3034":"GenoPay()","fa0c498e":"refundJobSponsorships(uint256,uint256)","fa0c76c5":"calcUserDivsAvailable(address)","fa0cdc81":"getManifestById(bytes32)","fa0d5b52":"BerryLakeCoin()","fa0d80fc":"icoDenominatorPrice()","fa1026dd":"getCommitment(address)","fa107a41":"Cajutel(uint256,string,string,address,address,address,uint256,uint256)","fa113488":"setCMTForGas(uint256)","fa113773":"BlackSeaCoin()","fa1152f3":"MoregainCoin(uint256,string,string)","fa11c471":"holdsValidLicense(address)","fa12d782":"openGame()","fa130b68":"developer_edit_text_price(string)","fa133fdb":"massTransferTokens(address[],uint256)","fa13af97":"InServiceToken()","fa140e3d":"MitToken()","fa1456a9":"transferKROContractOwnership(address,string)","fa147e5e":"remainingTokensAndCost()","fa14df6b":"getChangeRecipientFee()","fa169ec8":"getHashDigest(string)","fa16ab6c":"Platform()","fa16c53b":"DiscrashCredit()","fa17a19d":"forceStand()","fa188644":"whitelist5Addresses(address[5])","fa188df2":"addMinter(address,address)","fa1896f4":"getOneTokenInWei()","fa18dd2b":"isSetupMode()","fa193a6e":"Voter()","fa198656":"roundingPercent(uint256,uint256,uint256)","fa1a5f59":"soldAmount()","fa1acb5c":"_startTime()","fa1ad09e":"fundTransferOut(address,address,uint256)","fa1b3eb8":"gamesOf(address)","fa1ba1e1":"burn(uint256,bool,uint256,uint256)","fa1bde89":"test_set_get_OraclizeCallback()","fa1c594e":"disableRegistryUpdate(bool)","fa1ca37e":"_transferCeo(address)","fa1cee57":"approveKNCRateRange(uint256)","fa1d9cf8":"getZoneTeller(bytes2,bytes16)","fa1db1e7":"SendResult(uint64,bytes32,bytes32)","fa1e4fcb":"holdoverBalance()","fa1eae3c":"newSchellingRound(bool)","fa1f919f":"pre_enddate()","fa2073ad":"getAnswerCounts()","fa208cc5":"KickTheCoin()","fa20e77d":"burntTokens()","fa2299ee":"soldSupply()","fa23023b":"lockSales()","fa233620":"RENTALTOKEN(uint256,string,string)","fa24e7a0":"xyjtoken(uint256,string,string)","fa255179":"getCheckResultMessage()","fa25fd57":"settleOrder(uint256,uint256)","fa26db7e":"setMinAllowedReservingPercentage(uint256)","fa26fe32":"delivery(string)","fa27e070":"removeProxyForSender(address,address)","fa28a6b6":"checkTrainingPrice(uint256,bool)","fa28ba0d":"validateReleaseLockfileURI(string)","fa29141b":"minSellAmount()","fa292c44":"BitcoinPower()","fa2a68d2":"QToken()","fa2a8997":"isReleased()","fa2a9be6":"createPoll(bytes,uint16,uint256,uint256)","fa2acd87":"G(uint64[16],uint256,uint256,uint256,uint256,uint64,uint64)","fa2af9da":"platformWallet()","fa2b579d":"at_percentile(uint256)","fa2b76e2":"tokenReserved2()","fa2c7f9b":"getLender(uint256)","fa2cac28":"rejectEthTransactionRequest()","fa2cc19e":"calculate_price(uint256,uint256)","fa2d7efa":"AdlasToken()","fa2d84b6":"addBlacklistAddress(address,address)","fa2dedec":"SATS_TO_TOKENS()","fa2e9db8":"sunsetWithdrawDate()","fa2f29b6":"claimEOSclassicFor(address)","fa2f3e9a":"numAccountsInfo()","fa2f7a8f":"renounceContract()","fa307fcb":"sendMultipleMessages(address[],string,string,uint256)","fa309571":"delegateGetTokens(address,uint256)","fa30b251":"buyTicket(string)","fa314c67":"newAtomFee()","fa31b371":"deletePublicKey(bytes32,address)","fa31e684":"releaseTokensSaleCount()","fa3276bc":"isModifiedInRound(address,address,uint64)","fa332152":"giftSendIndex()","fa33bcf3":"isInList(address)","fa34b345":"walletsDelegate()","fa34b37b":"bonusPreviousOwner(uint256,uint256,uint256)","fa34da5e":"getTarget(bytes32,bytes4)","fa352dec":"tokensToEthereum_(uint256,uint256)","fa3559f7":"attestToContract(uint256,bool,string)","fa355d1c":"_distributeFloatWalletToken(uint256)","fa358c24":"refundPaused()","fa35a310":"Contributed(address,uint256,uint256)","fa35aa94":"deathData_f10()","fa36316e":"setFiatPerEthRate(uint256)","fa368e6d":"isWMSale()","fa369e66":"batchTransfer(bytes32[])","fa3754ca":"getCurrentDiscountRate()","fa37668f":"createContract(bytes32,bytes20,bytes20,uint256,uint256,uint256)","fa391c64":"isCompleted()","fa3a0f78":"getCreateMarketController()","fa3a3a7e":"DemoPreSale(uint256,uint256,address,address,address,uint256,uint256,uint256)","fa3b8f2c":"AdvertisementPayout(uint256)","fa3c6320":"intercrypto_recover()","fa3c8251":"TimeDecayingTokenEnvironment(uint256)","fa3c9bbc":"getHostRoomLists(address,address)","fa3e9b45":"setCreditDao(address)","fa3ed04d":"getDArbitraryData(bytes32,bytes)","fa3f1e99":"testBlobStoreRegistered()","fa3f5acf":"sendMsg(string,string)","fa3f998c":"redeem_deposit(uint256)","fa3fa196":"transferCreator(address)","fa404e34":"revokePoolRole(address)","fa407c19":"NRCToken()","fa40ce34":"addAllowedContracts(address[])","fa4125f7":"activateNextRound(uint256)","fa41fd32":"lastCallstopPreICO()","fa42f3e5":"map_address(string)","fa448f7a":"_handleAffiliate(address,uint256,uint256,uint256)","fa45858e":"changeSellPOPPrice(uint256,uint256)","fa45aa00":"executeWithdrawal()","fa461f33":"setValueStep2(uint256)","fa462e95":"mintStepPrice()","fa46b8b4":"SellRateChanged(uint256,uint256)","fa472bad":"SkillCoinTest()","fa47c564":"confirmERC20(bytes32)","fa48b4bf":"mintEtherBro()","fa48dfcd":"setLockup_jiedians(address,uint256,uint256)","fa49841d":"ownerAdmin()","fa49a13a":"Vulgus()","fa4a2e36":"ShyneTokens(uint256,string,string)","fa4a80f1":"Matrioska()","fa4ac15d":"withdrawAffVault(uint256,string)","fa4bb165":"setRoundNumber(uint256)","fa4c4271":"reClaimIFS(address)","fa4c5dc0":"addMessage(string,uint8,uint8,uint8)","fa4d0c3c":"lockDeadline()","fa4d300d":"ICOSplit()","fa4d3698":"setOwners(address[])","fa4de094":"KPOP_ARENA_CONTRACT_ADDRESS()","fa4e5e5a":"notify(uint8,string,string)","fa4f34a0":"GetChallengeTimings(uint256)","fa4f5511":"campaignUrl()","fa4f96c4":"ActivatedEvent(bool,bool)","fa4fb369":"addPreSaleTokens(address,uint256)","fa4feb65":"icoTokens()","fa502cf7":"addBidToStack()","fa5064be":"submitProposal(uint256,uint256,uint256,uint8,uint64,string)","fa5083fe":"getMaximumBetRate()","fa508d3e":"dnnToken()","fa509eda":"nextonetogetpaid()","fa509ff7":"collected_eth()","fa50b335":"IS_TIER_CONTRACT_MAGIC_NUMBER()","fa518054":"_addToWhitelist(address)","fa51a2bf":"setSupplyLock(bool)","fa51ae86":"RATE_CORNERSTONE()","fa5201e1":"LuckToken(uint256,string,string)","fa5252e4":"pbWinner()","fa52bcb3":"ICSTCrowSale()","fa52c7d8":"validators(address)","fa52caf6":"HECoin(address)","fa53bb1b":"setauctionother(uint256)","fa544161":"getOwner(address)","fa550659":"approvalForAll()","fa552d8e":"withdrawSale1()","fa556996":"TimeClock(string,uint256,uint256,uint256,uint256)","fa55afe2":"setABIHashForMod(bytes32,bytes)","fa55f4d4":"modifyEligibility(uint256)","fa566ddd":"doAllowance(address,address)","fa56780d":"getPurseContributions(uint256,uint256)","fa57e2ab":"resolved(bytes32,bytes32,uint256)","fa57ff82":"ownerSetJackpotToken(address,uint256,uint256,uint256)","fa58f510":"getFeeMake(uint256)","fa5919a8":"DAOSecurity(address,address,bytes32,uint256,uint256,uint128)","fa59d199":"removeHash(string)","fa5a1db6":"save(uint256,uint256,uint256)","fa5b344e":"assignSubMember(address,uint256)","fa5ba0f9":"stepPrice()","fa5bbcd2":"crowdsaleCreators(address)","fa5bc660":"offerDiscipleVend(uint256,uint256)","fa5be8f8":"setBonus(uint256,uint256,uint256)","fa5bfc1e":"claimedRewardHook(uint256,address,address,uint256)","fa5c0c70":"getSaleOrder(uint256)","fa5cd179":"join_address(uint256)","fa5cdc2b":"OLTestSynatax()","fa5da441":"incrementedIndexOfName(string)","fa5e288c":"ABBC()","fa5ed321":"_pointToResolverAndResolve(bytes32,address)","fa5ef276":"getVotedData(address,uint256,address)","fa5f090b":"SmartIdeaTokenERC20(uint256,string,string)","fa5f2d80":"AOG(address,address,address,address,address,address,address)","fa607442":"timeOneSession()","fa608890":"withdrawRemainingRewards(uint256)","fa60a16e":"serviceAddressOf(address,uint256)","fa60fb0b":"getTxRoot(uint256)","fa6140dd":"weekPotLeader()","fa6171e4":"superMint(address,uint256)","fa62a1ff":"revokeAdminStatus(address)","fa640427":"setPermissionsProvider(address)","fa64dffa":"getDestQty(address,address,uint256,uint256)","fa65d336":"hasFreePlaces()","fa6669b7":"updateAccountData(uint256,uint16,bytes32,uint256,uint16,bytes32)","fa667907":"changeOwnerSharePerThousandForBuying(uint256)","fa66be4e":"countryLengthOf()","fa66e143":"employeeSignsToESOP()","fa671e5f":"deathData_v19()","fa671f6b":"validPurchaseIco(uint256)","fa6799f2":"revokeVesting(address,uint256)","fa67ae5a":"setBlockDelay(uint256)","fa67ba6f":"getSecondsTimeLockedByTx(uint256)","fa6878a7":"setBAB(bytes32,address,bytes)","fa68829a":"UnKoin()","fa68b4ce":"lookupISO3116_1_alpha_3(bytes)","fa691a26":"totalRoundsPassed()","fa695dd7":"createItem(string,uint256,uint256,bool,bool,string,uint256)","fa696d98":"ART_FOUNDATION_ADDRESS()","fa69ede9":"setNewRatesBase(uint256)","fa6a0712":"setOwnerPrice(uint128)","fa6ab63b":"getTokenSum()","fa6ac98e":"test_0_testBasicTxProposal()","fa6ad04c":"PRCT_BOUNTY()","fa6b129d":"tokenGenerationEvent(address)","fa6b535d":"deleteContact(bytes32,address)","fa6bdbf8":"_transfer(address,address,uint256,bytes)","fa6d373c":"LeaderHash()","fa6d8f1f":"callAndReward_1(string,string,uint256)","fa6e01a2":"ARTCToken()","fa6e5776":"haveExtension(string)","fa6ec547":"registeredAddress(address,bool)","fa6f3522":"EthimalFounderEggs()","fa6f3936":"isModerator(address)","fa6fc037":"prepareToBreed(uint256,bool,uint256,bool,uint256)","fa6fcc50":"_startBetBlock()","fa70466e":"getMonsters(uint16)","fa70f6da":"STRATToken()","fa712f71":"isBattleboardLive(uint16)","fa713023":"IEICrowdsale(uint256,uint256,uint256)","fa725ea3":"requireValidAddress(address)","fa7299f7":"getOwnerVirusLength(address)","fa729b5b":"CNY_Omnidollar()","fa72c53e":"providerFeePerEth()","fa73af0b":"GRANT_BATCH_SIZE()","fa73cb37":"ptxToken()","fa73f074":"useAddr()","fa76b253":"getAddressForAccount(string)","fa779bd6":"checkBalanceTier(address)","fa77c074":"shaThree(string)","fa785263":"checkRemoveOwnerArgs(uint256,uint256,uint256)","fa785928":"_revealBid(bytes32,address,uint256,address,bytes32,bytes32,uint256,uint256)","fa7860da":"etherHardCap()","fa78b172":"drawSecondaryWinners()","fa796124":"BitLumensCrowdsale(address,address)","fa796fa1":"CryptoZoo(address,address,address)","fa7a6cd3":"developer_string_symbol(string)","fa7ae620":"cryptaurReserveFund()","fa7af6fe":"investInternal(address,address)","fa7c31af":"withdrawCommunity(uint256)","fa7ca492":"preICOStats()","fa7d68f1":"getAccountInfo(uint256,uint256)","fa7e4eaa":"BELIBELA()","fa7e8f7c":"EtradeMarketsCoin()","fa7f6b96":"tokensLocked(address,uint256)","fa80918b":"computeNodeId(bytes,bytes)","fa81b200":"masterOfCeremony()","fa825185":"getChargers()","fa82e9fc":"organizer1()","fa83c01b":"setStopSendWebGift(bool)","fa848fb0":"startDayOneTime()","fa849243":"targetDiscountValue1()","fa85d33e":"istransferAllowed()","fa878e8f":"TOKEN_RATE_10_PERCENT_BONUS()","fa885329":"setTableSize(uint256)","fa885868":"addPreminer(address,address,uint256,uint256)","fa888c74":"callIt(uint256)","fa89401a":"refund(address)","fa894c08":"balanceWosPoolForSecondStage()","fa8a3c1c":"rateC()","fa8a975d":"forcedTransferAll(address,address)","fa8ad6b9":"unsetIsRentByAtom(uint256)","fa8b72ff":"setBountyTokensWallet(address)","fa8dc33a":"checkRecordExists(bytes)","fa8ec0b2":"_transfer(address,address,uint256,string,uint256)","fa8edab6":"checkBalance(address,address,uint256,uint256)","fa8fc08d":"GxCoin(address)","fa8fd2b5":"LockRequestable()","fa90693b":"isBlockRedeemed(uint256)","fa912743":"feesStrategy()","fa922e66":"pickaxe()","fa923d10":"FutureCoin()","fa92fb6e":"IssueRejected(uint256)","fa93019c":"getBlocks(uint8,uint8)","fa93185f":"LockedDayRemoved(address,uint256,uint256)","fa93f883":"getMinute(uint256)","fa967415":"nextUpgradeMaster()","fa968eea":"minBetAmount()","fa96a49e":"totalSupplyUpgraded()","fa9768c9":"getOnMintAmountValue()","fa9789cf":"trainKitty(uint256)","fa984da8":"SujiToken()","fa985a2f":"p_update_mNewPlotDevPercent(uint256)","fa9907ad":"pay500Winners(uint256)","fa99d7ae":"enterDungeon(uint256[4],uint32)","fa9a4c35":"getPOOL_edit_21()","fa9acb05":"addressInArray(address,address)","fa9aecfb":"isUnowned(uint256)","fa9af30f":"getGoldXchgRate()","fa9b44b7":"PendingETHs(address[])","fa9ba8b4":"FunFaceToken()","fa9ce7e7":"moveTokensFromStockToExchange(uint256)","fa9d2352":"hasRequiredStateChanges()","fa9df423":"setShp(address)","fa9e6f11":"Exafire()","fa9e82cf":"uploadStartlist(uint256[])","fa9f117f":"setNextRoundMaxDonors(uint256)","fa9f245c":"CappedToken(uint256)","fa9fd8b2":"incremental(uint256,uint256)","faa06c06":"GetCityName(address)","faa0a264":"burnToken()","faa10f43":"require(bool)","faa1a8ff":"getOwnedBot(address,uint256)","faa3981a":"boolMemoryArray(bool)","faa458f4":"submittedHashes(bytes32,uint256,uint256)","faa51485":"isValidTraderAddress(address)","faa5369d":"getBorrowingItem(uint256)","faa5c564":"register(uint256,uint256,uint256)","faa5ca93":"erc20Buy(address,uint256,string,string)","faa5d0ea":"updAmountBonusEnabled(bool)","faa5e124":"ref_percent()","faa5e74a":"TokenPurchaseWithGuarantee(address,address,uint256,uint256)","faa62d3f":"setPercentageToLock(uint256)","faa679bf":"TraceToken()","faa7fc61":"bustRange()","faaa4d22":"distributePCY(address[],uint256,uint256)","faaa58da":"RemovePauser(address)","faaad90f":"getBlocksUntilNextRound()","faaad91d":"convertToPrimordial(uint256)","faab806f":"emergencyStopSale(address)","faab9d39":"setRegistrar(address)","faabc195":"updateContract(uint256,address,uint256)","faac90ec":"StorageFactory()","faacf0fd":"toChar(bytes1)","faad4a49":"setDividends(uint256,uint256)","faad6eb5":"updateAgent(address,bool)","faadb14a":"getCustomerTxPaymentKWh(address,bytes32)","faae4c17":"usernamesToAddresses(bytes32)","faaebd29":"Fight_Results(uint256,address,address,uint128,uint128,uint32,uint256,uint32,uint256,uint8)","faaf027b":"getAddressTokenSaleId(address,address)","faaf1921":"updateEthToCentsRateCycleStarted()","faaf71e6":"checkSoftCapOk()","faafa08f":"CatICO(address)","fab0568c":"GIFTToken(uint256,string,uint8,string)","fab14b36":"saleBalance()","fab18075":"numLots()","fab2c469":"getSlots()","fab2cb36":"totalSharesIssued()","fab2e425":"GAMESPLAYED()","fab2f86b":"stopVoting()","fab37154":"setMintAddress(address)","fab3be9a":"WETCToken()","fab3ebb1":"NULL_ENCRYPTION_ALGORITHM_DESCRIPTION_URI_SET_ID()","fab4087a":"parse(bytes)","fab425e7":"external_to_internal_block_number(uint256)","fab43cb1":"getPongAddress()","fab4969f":"amountRaisedPhase()","fab4cb39":"getWarrantyPrice(string,uint256,uint256,uint256)","fab55a49":"addr_forge()","fab57a21":"truebitAddress()","fab5ccb1":"submitBlock(bytes32,bytes)","fab67bb6":"hasNotEnded()","fab825c6":"setCanvasName(uint32,string)","fab88d39":"STS(uint256,string,uint8,string)","fab8cbe4":"splitTokensBeforeDistribution(uint256)","fab93805":"ballotLog(bytes32[2])","fab9b243":"isUpgradable(address,address,string)","fab9caaf":"JungleScratch(address)","fab9f0c4":"DigiWillToken()","faba1f16":"_createPow(string,address,uint256,uint256,uint256,uint256)","fabacf0d":"Yetxkd1601()","fabae696":"updatefxFee(uint256)","fabb25fa":"x_constructor(address)","fabb7952":"setPaintingName(uint256,string)","fabbdc5b":"COIN_COST_ICO_TIER_2()","fabc1cbc":"unpause(uint256)","fabcc880":"update(uint256,int256[2],uint256[2],int256,bytes32,address,uint256,uint256,uint256[3])","fabde80c":"coinBalance(address)","fabe1416":"canClaimToken()","fabec44a":"getCurrentVersion()","fabee62d":"taxTo(address)","fabf00c3":"NewGrant(address,address,uint256)","fabf5ea5":"maxInvestedLimit()","fabf657a":"approveAddress(address)","fabfbefb":"lastPayoutIndex()","fac08874":"BPTestCoin()","fac20ab8":"getGameWinner(uint256)","fac2548b":"updateMember(address,uint256,bool,string)","fac28349":"setInvite(address,uint256,uint256)","fac2b5f8":"setEplay(address)","fac333ac":"ids(uint256)","fac34ff6":"throwFoo()","fac3a4db":"changeWithdrawableNetfRe(uint256)","fac3c1f4":"setOracleName(address,string)","fac416ab":"PriceThreeEnable()","fac50e4c":"StgTwobonusEnds()","fac5235b":"teamTokensAllocated()","fac52bfd":"my_name()","fac57fc9":"hasUpgraded(address)","fac5bb92":"getPreRelease(bytes32)","fac5fbc7":"ContractDisabled(uint256)","fac647cc":"testLongerJson()","fac65256":"wavesTokens()","fac66f01":"getConditions(uint256,uint256)","fac67cf6":"updateVIPRank(address)","fac6a8a2":"withdrawExchangesToken()","fac6fe0c":"level_6_percent()","fac78d83":"tierModifiable(uint256)","fac7abe3":"latestAuctionIndices(address,address)","fac7b20a":"maxCapTokenTotal()","fac8a800":"isTeller(address)","fac952c5":"getLastWithdraw()","fac97122":"ownerSetJackpotAddress(address)","fac9d2c7":"Blockkonnect()","faca7cfa":"prevBalance()","facaa838":"IsEscrowActive()","facb2195":"setIntF1(int256)","facbf93b":"totalBlocks()","facc7905":"unLockTime()","facce5bb":"wingsTokenRewards()","facd0934":"BONUS_250_500()","facd743b":"isValidator(address)","face030b":"SpinTheWheel(address)","face873f":"getAllActiveSales()","face9e8e":"hash_sha256(string,uint256)","facef32a":"IGI()","facf55e6":"getMyClones()","fad09ab3":"closeProvider(address)","fad15673":"UmkaToken(string,string,uint8,uint256)","fad18e7b":"registerNameXaddrFromDapp(address,bytes32,address,bool,uint8)","fad239ac":"PermTokenTest()","fad356f8":"testTransferFromSelf()","fad35818":"calcInviterBenefit(uint256)","fad3f8f7":"maxPreSale()","fad4b99a":"updateChannelMinimum(address,uint256)","fad4e1f2":"getIDMapping(uint256,uint256)","fad5a2af":"isClosedAndValid()","fad6049b":"_transferFrom(uint256,address,uint256)","fad60615":"roundProfitByAddr(address,uint256)","fad774ee":"BONUS_LEVEL_2()","fad7ed8c":"_A_tokenSaleCompleted()","fad8200e":"userToNumCelebs(address)","fad88be7":"VOISE()","fad8b32a":"revokeOperator(address)","fad9100c":"FOMOed()","fad992ea":"claimINRDividends()","fad9aba3":"dust()","fad9bf9e":"storeBlockWithFeeAndRecipient(bytes,int256,int256,bytes,int256,int256)","fada2c18":"transferBond(uint256)","fada4b76":"quater3()","fada5da1":"collectEth()","fadc0700":"InitiateMakes()","fadc51cf":"isAlpha(bytes1)","fadc554b":"updateNonClosingBalanceProof(uint256,address,address,bytes32,uint256,bytes32,bytes,bytes)","fadcd861":"createMarriage(string,string,string,string)","fadcf13c":"startBounty()","fadd3235":"gameEndBlock()","fadda208":"getMemberAdresse(uint256)","fadeb59c":"getListingDB(uint8)","fadf4cb2":"batchAssignTokens(address[],uint256[],bool[])","fadf4f3b":"GECToken(address,uint256)","fadf617b":"reveal(int128,string)","fadf87b1":"testGetBitsSuccess()","fae14192":"changeFeePercentage(uint256)","fae17e21":"createBid(uint256,address,address,address,uint256,uint256)","fae21f0a":"initBank()","fae24454":"removeFromManagementWhitelist(address)","fae25444":"getNumberOfOffers()","fae29ee8":"setWebInfo(string,string)","fae2dd4b":"myName()","fae429af":"NinjaCoinNC()","fae4a213":"buyWithAddressAndFunction(address,bytes4)","fae53222":"addPlayerGeneral(address,uint32,uint32,uint8)","fae59753":"transferOwnershipMessage(address)","fae6edcf":"getI2()","fae72303":"totalWeiRaisedDuringPhase3()","fae73549":"Burnt_Token()","fae8529a":"maxprice()","fae860db":"transferToLockedBalance(address,uint256,uint256,uint256,uint256,uint256,uint256)","fae8c29e":"setPromoPause()","fae8f9a2":"setInitialParent(int256,int256,int256,int256,int256,int256)","fae92612":"setMarketAddress(address)","fae95a71":"participationPresaleHistory(address)","fae9c6b3":"preICOTokenRemaining()","fae9d06d":"calculateTxFee(uint256,address)","faea1878":"cooRemoveCro(address)","faea624c":"VestTokens(address,uint256,uint256,uint256,bool,string,uint256)","faea9129":"Syndicate()","faed08a9":"reLoadXname(uint256)","faed1922":"purchaseWhaleCard()","faed77ab":"wipeAndFree(address,bytes32,uint256,uint256)","faed86ab":"strConcats(string,string,string,string)","faede6a1":"Y2_lockedTokenAmount()","faee13b9":"set(int8)","faee4402":"donateToWhale(uint256)","faee4a10":"initialBankroll()","faef2ad2":"getCategoryHash(address)","faeff650":"phase1TokenPriceInEth()","faf0952b":"testThrowRestartNotOwner()","faf21148":"ValoremICO()","faf236c7":"emitTokensFor(address,uint256,uint256,uint256)","faf27bca":"greeter(string)","faf3d174":"upgradeStart(address)","faf42125":"setTokenURIAffixes(string,string)","faf5115f":"setBank(address,address)","faf81ba5":"applyBonus(uint256,uint256)","faf87b8a":"payoutEF()","faf880ad":"SoftcapReached(address,uint256)","faf924cf":"proof()","faf95e3d":"PayForServiceETHEvent(address,uint256)","faf9859c":"NIU(uint256,string,uint8,string)","faf9b5cf":"mintSendTokens()","faf9f330":"accrueTeamTokens(address,address,uint256)","fafa4c82":"defaultTransferGas()","fafa8e1a":"removeDat(string)","fafaacfa":"hasConfirmed(bytes32,address,uint256)","fafb2330":"setPayout(uint256,uint256)","fafb3c7a":"giftCar(address,uint256,bool)","fafb76dd":"getOffsetIndex()","fafb9334":"roll_normal(address,uint256,uint256,bytes32,bytes32,bytes,bytes32,uint256)","fafbb62b":"create(string,string,uint8,uint256,address,string,address,address)","fafbb9a3":"getNextPayoutTime()","fafbcc08":"IBNZDEVELOPERSERC20_Crowdsale()","fafc56d9":"setStepTwoRate(uint256)","fafcdc34":"dist(address)","fafd2efb":"cashoutable(address,address)","fafd4bba":"RESERVED_TOKENS_FOR_CRYPTO_EXCHANGES()","fafd6bcb":"isConfirmedBy(bytes,address)","fafdb3af":"PlayerBalance(uint8,uint256,uint256)","fafe029f":"getWtotalTransCnt(uint8)","fafe0902":"gift_ClaimTINAmotleyLine(uint256)","fafe805e":"BLOCK_PER_PHASE()","fafe8845":"StateChanged(uint256,uint8)","faff50a8":"rootNode()","faff660e":"isPrivate()","fb007107":"CanMint(bool)","fb00cc67":"search_winner_bid_address(uint8)","fb00fec6":"getStatusForRootHash(bytes32)","fb0101c4":"getUserSpaceIds(uint256)","fb01badd":"companyShares()","fb01f4b1":"developerPrizeClaim()","fb02191c":"addRepo(bytes32,string)","fb03735e":"contractTokenReward()","fb03eaea":"getDisputeThresholdForFork()","fb048705":"itemOf(uint256)","fb04f22c":"secondReleaseDone()","fb054439":"canBearWith(uint256,uint256)","fb05594f":"STARTING_SHRIMP()","fb062a84":"offerOptionsToEmployeeOnlyExtra(address,uint32,uint32,uint32)","fb064161":"advisorsAllocation()","fb06603c":"modifyToken(address,uint256,string,string,string,string,bool)","fb070d0d":"CatFarmer()","fb0720dc":"icoStartP1()","fb072d2a":"random(uint256,uint8)","fb07ac86":"realPriceOracle()","fb083fdc":"EtherDelta()","fb088558":"contributeWithoutVesting()","fb08937c":"tokenTransfer(address,address,address,uint256)","fb08f3a1":"whitelistRequired()","fb08fdaa":"replaceContract(address)","fb099c84":"newInvestor()","fb09b1ac":"testBalanceOfReflectsTransfer()","fb09c964":"getXQU()","fb09db11":"setActiveWhitelist()","fb0a0344":"mockBuy()","fb0a2e3c":"buyerDecimals()","fb0a3867":"updateClientAddress()","fb0a8c62":"addGenerator()","fb0b0220":"outFromPool(uint256)","fb0b02cd":"destroyBucket(bytes32)","fb0b6b6d":"confirmTransactionByMediator(uint256)","fb0c0782":"buy2(uint256)","fb0c1faa":"LearnX()","fb0cf7ab":"getStagePrice(uint8)","fb0d7e43":"initialBonus()","fb0f6f42":"s1(bytes1)","fb0f9363":"getAuctions(address)","fb0f97a8":"depositToken(address,address,uint256)","fb0fcd8c":"triggerRselfdestructRefund()","fb101581":"transferToCharity(address)","fb10b0d3":"currentMaximumSalePercentage()","fb114f57":"oraclize_query(uint256,string,string[3],uint256)","fb11613e":"getGamesByDay(uint256)","fb1161f1":"bountyCap()","fb1291c3":"getPixels(bytes32)","fb12ee85":"amountOfOpenRFQs()","fb13a707":"changeVestingWhitelister(address)","fb13bfae":"getFreezeInfo(address)","fb1478e5":"changeSaleEndBlock(uint256)","fb14cbca":"check(bytes32,uint256,address,uint32,uint32,bytes32[])","fb14f058":"addVestingAdmin(address)","fb15e737":"boolToBytes32(bool,bool)","fb1641d6":"rejectGame(address,uint256)","fb1669ca":"setBalance(uint256)","fb1684f9":"lockTextKey(string,uint256)","fb173712":"SetRate(address,address,uint256,uint256)","fb176b69":"paleyer1show(uint8,uint8,uint8,uint8,uint8)","fb17905f":"DemolishByCredits(uint256,uint256)","fb18962d":"setSoftwareTokensPercent(uint256)","fb1ace34":"notarize(bytes)","fb1ae783":"getWinnerTeam(uint256)","fb1c3461":"_calculatePercent(uint256,uint256)","fb1ce13a":"TestEOSCoin()","fb1ce2ea":"NotifyMe(address,uint256)","fb1d8201":"addClaim(uint32,string,string,bytes)","fb1d9eea":"transferFundsTokens(address,address,uint256)","fb1db11f":"updateEarlyParticipantWhitelist(address,address,uint256)","fb1de995":"solveTask(uint256,uint256,uint256,int256,uint256,int256)","fb1e3804":"FULL_TOKEN_AMOUNT()","fb1e61ca":"getRequest(bytes32)","fb1f41f9":"info_OwnerTINAmotleyLine(uint256)","fb1fad50":"halt(uint256)","fb1fdc2e":"lengthNotEqual(address[],uint256,string)","fb2004f2":"BCOExtendedToken(address,string,string,uint256,uint256)","fb20b70d":"setBonusDate2(uint256)","fb20d071":"registerVestingSchedule(address,address,uint256,uint256,uint256,uint256,uint256)","fb20d98f":"deleteEditor(address)","fb20dc80":"setPriceForVerification(uint256)","fb213549":"confirmApplication(address)","fb21364b":"allocate2ProjectToken()","fb214f4c":"presetGymTrainer()","fb218f5f":"storeData(string)","fb21eefd":"fwdData(address,bytes)","fb222d48":"extractVaultTokens(address,address)","fb236bba":"_deleteOffer(uint256)","fb237eb2":"isUserWhitelisted(address)","fb23bbb1":"BONUS_WINDOW_3_END_TIME()","fb241406":"RedPen()","fb25b62c":"LineToken()","fb2643c0":"DragonKing(address,address,uint8,uint8,uint8,uint16[],uint16[])","fb26c00f":"Treasury(address)","fb26c3f8":"minimumPresaleWeiDeposit()","fb26e2d8":"tgrStartBlock()","fb274654":"offerCollectibleForSaleToAddress(uint256,uint256,int256,uint256,address)","fb277a24":"testMintInvalid(int256)","fb27961c":"softCapAmount()","fb279ef3":"tip(uint256,address,uint256)","fb282a17":"distributeCallback(uint256,address[])","fb282f92":"solveGame(uint256,uint256)","fb283111":"setRunSwitch(bool)","fb2861ff":"MINTTIME()","fb2898e4":"startSaleDepo(uint256)","fb28be72":"SetupQPY(string,string,uint256,uint256,uint256,address,address,uint256)","fb293a34":"backGamePlayerCoinOwner()","fb29aa97":"getNumLoveItems()","fb2c95b6":"PlayX3()","fb2cb34e":"transferPaused()","fb2dfa45":"getKitties()","fb2e0078":"withdrawalFunds(bool)","fb2e3240":"setDOwnerFromClaim(bytes32,address)","fb2ee901":"getBattleFee()","fb2eff20":"PhoenixFund()","fb2f3a8a":"MAX_BOUNTY_SUPPLY()","fb2f5064":"getPendingTokens(address)","fb2fbf49":"registerEOSAddress(string)","fb305569":"UbiqIssued()","fb30d070":"setNewAge(int256)","fb31a6cc":"executeOffer(address)","fb31b262":"VuePayTokenSale()","fb31ff37":"getFullRecord(bytes32)","fb3220fe":"addNodalblockData(string)","fb32ade3":"releaseLockedTokensFor(address)","fb32aedb":"voteB()","fb32f4f5":"ARK_FLAGGER_1_00()","fb3458d1":"extractElementsFromGene(uint256)","fb346eab":"totalSpent()","fb34d075":"channelCloseTimeout(uint64)","fb34fc6f":"WatchNextBlockReward()","fb350502":"calculateWalletTokens()","fb35370b":"transferDari(address,address,uint256)","fb3551ff":"getAgent(address)","fb357f74":"EBLLToken(address,uint256)","fb35a4ba":"KKToken(uint256,string,uint8,string)","fb35b4e4":"totalDeployments()","fb35d545":"unlockDate4()","fb3650c2":"grab(address[],uint256[])","fb368e8f":"getServiceName(bytes32)","fb36eba1":"createCard(address,uint16,uint16)","fb36fae4":"setJpycContactAddress(address)","fb37baa1":"whitelistUserForTransfers(address)","fb386216":"getSeatAddress(uint256)","fb38ec94":"founder3()","fb3918d7":"fillReserve()","fb3979f0":"updateAccountChartAgainstExistingEntity(address,uint256,uint256,uint256)","fb3a1fb2":"getReleaseDb()","fb3a3ff3":"HODLERAddress(address)","fb3ab12b":"setEndSale(uint256)","fb3b11af":"CWCCToken()","fb3ba9b3":"LogNewBlacklistedAddress(address,address)","fb3bc400":"myProfitsReceived()","fb3c0d70":"transferFromToken(address,address,address,uint256)","fb3d8b6e":"SiringClockAuction(address,address,uint256,uint256)","fb3dc0b3":"Leader(string,address,bytes32)","fb3ea59b":"acceptBatched(address[],bool)","fb3ed5c7":"airdropSupply()","fb3f1fd6":"nextroundblocksbeforenewpay()","fb3f4d29":"tokenApprove(address,address,uint256)","fb3f71c8":"addContract(address,uint256,string)","fb3fd6a1":"m_bIsLock()","fb402c26":"BuyTokensWithTokens(address,address,uint256,uint256)","fb40340d":"totalNormalTokenGenerated()","fb40c22a":"getAllCases()","fb4101c0":"reward(address,bytes32)","fb43b2a2":"approveBreeding(address,uint40)","fb4460dd":"getVoterStakes(address,uint256)","fb45d080":"pieBalanceOf(address)","fb468340":"getTotalMember()","fb46d4c5":"tweet(string)","fb46f492":"emissionMas(address[],uint256[],bytes32[],uint256[])","fb470a92":"FlukeCoins()","fb471ce5":"ERC223Transfer_enabled()","fb47a067":"_getRevisionBlockNumber(bytes20,uint256)","fb486c7b":"setGivenName(uint256,string)","fb48ca1d":"NewSuggestion(address,string,uint256)","fb48cf0e":"getVoter(uint256,uint32)","fb490695":"griefCost()","fb497ad2":"stage_1_TokensSold()","fb49dc4a":"AEFFTOKEN()","fb4a18a2":"setCrowdfundPayout(address,uint256)","fb4a6cde":"StarbaseEarlyPurchase()","fb4a86bc":"amountToBeRaised(bytes32)","fb4aa0a1":"fundReceiver()","fb4b7693":"sendSeedAndHash(string)","fb4cd8e2":"numBidders()","fb4ce0a9":"addAssetsOwner(address)","fb4da5b7":"pay(address,string)","fb4fbcd8":"getClaimTradingProceedsWaitTime()","fb4fd984":"requestPrize(bytes32,uint8,bytes32,bytes32)","fb50aec5":"getVendorApplicationStatus(string)","fb51a1ea":"read_total_purchased_today(address)","fb5209bf":"trickleUp(address)","fb524c32":"GetMaximumBet()","fb54047c":"getCustomExtraData(bytes32,uint256,bytes32)","fb557c8c":"PrideToken()","fb5589b4":"memCopy(uint256,uint256,uint256)","fb55d09d":"EtherGames()","fb55ed2a":"transferBlocToUser(address)","fb58674d":"Npole()","fb598f87":"createPost(uint256,uint256)","fb5a3282":"restFinish(address)","fb5b82d0":"setCollector(address)","fb5bd32b":"withdrawDevBalance()","fb5d5729":"getPongvalTransactional()","fb5d5999":"getDepositary_function_control()","fb5d7376":"step4()","fb5f39dd":"offlineSell(address,uint256)","fb5f8a13":"changeAddressKnight(address)","fb5fef42":"distributeALCToken()","fb6021ae":"ICO(string,string,uint8,uint256)","fb60938f":"getSumAmountOfSuccessfulDeals()","fb6139b5":"setServerFee(string,uint256)","fb6168ac":"BUY_ME()","fb621f14":"getSecurityTokenAddress(string)","fb6287d2":"setWalletAddresses(address,address,address)","fb62e083":"addWhiteListed(address)","fb632ef9":"transferrableBalanceOf(address)","fb63c4fc":"MESSAGE_PRICE()","fb63e4b1":"CEZA(uint256,string,string)","fb640453":"_getTotalBmcDaysAmount(uint256,uint256)","fb644a14":"Force(address)","fb64e072":"recordTransfer(address,address,uint256,uint256)","fb64e6b1":"icoAddr()","fb656067":"genesisCallerAddress()","fb659c3a":"addArticleItem(uint256,bytes)","fb65a1a3":"teamdistr(address,uint256)","fb65a3cb":"createCampaign(bytes32,uint256,address)","fb65e4b1":"Contribution()","fb674cf4":"emissionEnabled()","fb67983c":"fuckingClaim1(bytes,bytes)","fb687c24":"refundMethodABI()","fb68aa89":"hasInitCard1()","fb690dcc":"donated(address)","fb6a53d2":"multiBurn(uint256[])","fb6aeb42":"PRE_PUBLIC_LOCKUP_PERIOD()","fb6b18c0":"totalAirDrop()","fb6b4afd":"getWeaponModel(uint256)","fb6bbbce":"Crowdsale()","fb6c2b6f":"stopMarket(uint32)","fb6cae8e":"NetkillerToken(uint256,string,string,uint256)","fb6d0e8f":"pullShares(address)","fb6e155f":"availableVolume(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)","fb6e6558":"holderNumber(address)","fb6f6875":"deleteHotel(address)","fb6f71a3":"setCharity(address)","fb6f93a4":"setEthUsdRate(uint256)","fb6f9579":"Increase()","fb702ed1":"multiDistribute(uint256[])","fb7043ea":"isRefundPossible()","fb709d2e":"charities(uint256)","fb70f765":"foundationTokenSupply()","fb70ff96":"increasePieceCount(uint256)","fb71807f":"setUser(string,string,bytes32,uint256,uint256,uint256[],string,string)","fb719113":"deathData_f17()","fb7248cb":"playerGuess(address,int16)","fb72d24e":"shift_right(uint64,uint256)","fb72fdfe":"setTotalAllowed(address,uint256)","fb73a593":"modifyAllLevelCaps(uint256[],uint256)","fb741504":"IndividualCapCrowdsale(uint256,uint256)","fb7450be":"setBtcToken(address)","fb74da7e":"setTentativeWinningPayoutDistributionHash(bytes32)","fb74e6f7":"ADVISOR_STAKE_FOUR()","fb756f97":"Tokenomicx()","fb75b2c7":"rewardWallet()","fb77269e":"periodITO_period()","fb77378a":"SCOOP()","fb775b46":"giver()","fb77eae2":"startTimeSaleWithBonus()","fb78eb53":"Oncology()","fb78f85c":"mgrCount()","fb791b0b":"withdrawOrder(uint256)","fb794281":"gas_amount()","fb79e70f":"superNovaSupply()","fb7a2c1f":"addQuestion(string,uint256,uint256,string)","fb7a5f4f":"getEndBlock()","fb7a809c":"buyStageDataRecord(uint256,uint256,uint256,uint256,uint256,uint256)","fb7ae31e":"getCurrentRoundLeft()","fb7baf70":"initRegistMatch(uint8,uint8,uint8,uint256)","fb7c0a3f":"doBuy(uint256)","fb7cb850":"setMaxMerge(uint8)","fb7cf694":"buyPriceInWei()","fb7e54eb":"vcx()","fb7e7456":"endOfLockProjectToken()","fb7f21eb":"logo()","fb80d66f":"SQR_TOKEN_MULTIPLIER()","fb80fe9e":"test(uint256,address)","fb81299b":"setAllMarketsFinalized(bool)","fb815503":"withdrawWin()","fb81563b":"SpaceImpulseERC20()","fb84da41":"createSketch(string,string)","fb850fab":"newCampaign(uint32,uint256)","fb8621df":"push(bytes32,string,bytes)","fb8632b8":"availableEmission()","fb867165":"getSaveData(address)","fb86a404":"hardCap()","fb87bf7b":"LLX()","fb87d5ea":"TransactionRequest(address[4],address,uint256[11],uint256,bytes)","fb87eb0b":"setRefundsActive(bool)","fb88e7c1":"updateBestPromouter(address,uint256)","fb890a17":"YUPToken(address,address,address,address,address)","fb89fb28":"yield7Day()","fb8a5bf8":"H2OC()","fb8a5f1c":"createTransaction(address,uint256,bytes32,address,address)","fb8b0197":"claimReceivables(address[])","fb8bc297":"getInvestorPackPrice()","fb8c7420":"GetRandomNumber()","fb8dd3bb":"createEvent(bytes32,bytes32[],address,uint256,uint256,uint256,uint256)","fb8e4f1a":"BountyChanged(uint256)","fb8e7870":"buyKebabs()","fb8e82b4":"min(uint32,uint32)","fb9073eb":"reLoadXname(bytes32,uint256)","fb913d14":"sendByTranche(bytes32,address,uint256,bytes)","fb920ad1":"reclaimAndBurn(address,uint256)","fb92488b":"ChangePrice(uint256)","fb92507d":"daytime(uint256)","fb92e4fb":"_isGoodAddress(address)","fb932108":"distribute(address,uint256)","fb950559":"getAffiliation(address)","fb950a7f":"addGrantableAllocation(address,uint256,bool)","fb95adeb":"testFailBlockhashInsuffiecientFee()","fb95d9e7":"addConfigEntryAddr(bytes32,address)","fb961571":"ICOStartBlockChanged(uint256)","fb969b0a":"bootstrap()","fb9734fc":"confirmProposal(address,bytes32,uint256)","fb979ba2":"ROUND_1_PRESALE_BONUS()","fb97b61f":"lpAskVolume()","fb98a409":"skinContract()","fb990288":"_newInterest(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","fb9a2ce2":"getSellPosition(bytes32,uint256)","fb9a4595":"GitHubBounty()","fb9ab10b":"EpsToken()","fb9b4ab8":"createrAddress()","fb9ba033":"checkAllowedAddressForMinting(address,address)","fb9ba7bc":"removeAccreditedInvestor(address)","fb9bbeaf":"RaiSed()","fb9c7303":"completeInvestment()","fb9ca16b":"MarianaKey(uint256,string,uint8,string)","fb9cb15d":"numChipsMinted()","fb9dd851":"getGameInfoByIndex(uint256)","fb9ded46":"totalWeiRaisedDuringICO3()","fb9e1270":"investmentIdLastAttemptedToSettle()","fb9ec0a8":"assignPersiansToBattle(uint256)","fb9efcf0":"setCustodianForeign(address)","fba06849":"fipsPublishDataMulti(bytes20[],bytes)","fba07791":"fiatCost()","fba0aa5b":"txFeeSentInWei()","fba0ce5e":"setLinkedIn(string)","fba12c17":"minerLockAddress()","fba13bd0":"depositBalanceOf(address)","fba17fc9":"Flye()","fba246de":"DepositETH()","fba26207":"setUint64(int64,uint64)","fba2a2d2":"setPeriod(uint16)","fba2b18b":"_getplayersurplus()","fba2fb66":"newPolicy(bytes32,bytes32,uint256,uint256,uint8,bytes32)","fba36b31":"payWithRef(address)","fba4734f":"withdrawEthereum(uint256)","fba4abb2":"payoutBalanceCheck(address,uint256)","fba52ff1":"getInvestorClaimedTokens(address)","fba5de1c":"cancelGetTogether()","fba5ee24":"getSinistre_effectif()","fba5f1f6":"weaponModels(uint256)","fba6651c":"getCommunityTaxes(uint256)","fba6748c":"getMaxPrivateSaleBuy()","fba6e51b":"_getFinalAddress(uint256[],address[],uint256)","fba70381":"adventureByToken(address,uint256,uint256,uint256,uint64,uint64)","fba71fe9":"periodICOStage6()","fba74490":"PoseidonQuark()","fba779f6":"armyHelicoptersCount(uint256)","fba79777":"test1cash()","fba7c1ab":"addMake(string,address,uint256,uint256)","fba7cc79":"getIsActive()","fba84b2a":"LjwStandardToken()","fba90629":"totalSupplyPrivateSale()","fba906c5":"HiroyukiCoin()","fba939f8":"_goal()","fba9ce40":"donateToDev()","fba9cea9":"someAction(address)","fba9dbbb":"chnageSpecialFeeTake(uint256,address,uint256,uint256)","fba9ecac":"getFreeBanker()","fbaa0ece":"weekTwoRate()","fbaa89d3":"LogBidRemoved(address,uint256)","fbabc444":"PeaceChainToken(uint256,string,string)","fbabdb06":"disapprove(address,uint256)","fbac3951":"isBlocked(address)","fbac7d1d":"setCampaign(bytes32,uint256,uint256,uint256,uint256,bool,address)","fbac89f6":"unlock(bool)","fbacc43f":"getBases()","fbad8983":"sendyum(address)","fbae5e7d":"Investors(uint256)","fbaeac89":"newOwnerAPI()","fbaf094a":"provider(address)","fbaf12a7":"_removeBlacklistedUser(address)","fbb0eb8b":"mintingNonce()","fbb11f29":"setTokenGbi(address)","fbb1c5c4":"XBCOMMUNITY()","fbb26d00":"releaseBasicAccount()","fbb39f6e":"offerTrade(uint256,uint256)","fbb4d51b":"OverseasReturneesUnion()","fbb4dc6b":"secondMonthEnd()","fbb4f0e3":"NuToken()","fbb58c5c":"STARTING_FALCON()","fbb5d52d":"sellCoinsToICO(uint256)","fbb5f682":"KUNTEStandardToken(uint256,string,uint8,string)","fbb6272d":"tokens(uint32)","fbb65708":"freedWinPoolForSecondStage()","fbb78719":"private_setmaxBet(uint256)","fbb8932a":"getSeatMessage(uint256)","fbbb75c5":"getClaimedOwners()","fbbc3448":"getWrefundIndex(uint8)","fbbcb4de":"GointoMigration(address)","fbbd6545":"pushHatch(address,uint32,uint16,uint16)","fbbdb68c":"hiddenOwner()","fbbdbf22":"_setTimes()","fbbe20a9":"breeding(uint256,uint256)","fbbe7887":"NewBOP(address,address,uint256,uint8,uint256,string)","fbbedf5c":"ERC20Token(string,string,uint8,uint256)","fbbf119b":"BTCCCoin()","fbbf93a0":"getDetails()","fbbfa45e":"destory(address)","fbbfe830":"refundTokenHolder()","fbc00b4a":"GACC()","fbc032ab":"GCFcoinF(uint256,string,string)","fbc09b26":"m_totalDatasetCount()","fbc34d1c":"artistsArtworkCount(address)","fbc3d0ef":"frozenReserveTeamWallet()","fbc402fc":"updateDarknodeBond(address,uint256)","fbc44458":"setTransferAuthorizations(address)","fbc449a7":"FirstContract()","fbc47e56":"tokenListContract()","fbc4f981":"ReceivedBTC(address,uint256,string)","fbc53c8e":"Arascacoin(uint256,string,string)","fbc5db95":"lowestAskTime()","fbc6c0f0":"firstChipBonus()","fbc6d0ff":"confirmTransactionWithSignatures(bytes32,uint8[],bytes32[])","fbc7ad3e":"finishedLoading()","fbc805ee":"changeMaximumContributionForAllPhases(uint256)","fbc80af6":"FakeNewsToken()","fbc94bd1":"icoFinishInternal(uint256)","fbc94f24":"changeTokenPrice(uint256)","fbc990d0":"_removeMember(address)","fbc9c601":"requestAccess(address,int256,address)","fbca6ba6":"maintenance(uint256)","fbcbc0f1":"getAccount(address)","fbcc3775":"isMyWalletLocked_Send()","fbccc2b1":"setBoolF1UintF1StrF2Intf3(bool,uint256,string,int256)","fbcebd02":"delegatedRefund(address)","fbcece85":"freeTokens(address,uint256)","fbceff0e":"WangWangCoin(uint256,string,uint8,string)","fbcf1594":"UNLOCK_TEAM_2()","fbcfa0d7":"createCard(string,uint256,address,address,bool)","fbd06cb6":"s42(bytes1)","fbd0c5d7":"SaleClockAuction(address,address,uint256)","fbd0e7df":"Reimburse()","fbd15163":"lengthMessages()","fbd1df54":"TotalCount()","fbd1eb7b":"deployAgentWallet()","fbd22407":"EscrowRaj()","fbd275f8":"randomGen(address,uint8)","fbd2dbad":"previousDelegates(uint256)","fbd395f8":"pauseToken(uint256)","fbd3c51a":"left83(uint256)","fbd3d51b":"setMasterAddress(address,address)","fbd4200c":"base_token_is_seeded()","fbd42e0f":"releaseLockedTokens()","fbd4e0f0":"chkdrawadm(address)","fbd54a63":"sendAmount(address[],uint256)","fbd59425":"ETLToken()","fbd668a9":"setMaxProfit(uint256)","fbd6d77e":"addCoordinator(address)","fbd6fdde":"reLoadCore(uint256,uint256)","fbd70768":"___setProxyOwner(address)","fbd7b853":"setTokenSupplyLimit(uint256)","fbd7c5f1":"priceT3()","fbd7d081":"TOKEN_HODL_3M()","fbd81564":"logger(string)","fbd902f2":"_distributeTokenToPurchaser(address,address,uint256)","fbd95a39":"sendToAddress(address,address,uint256)","fbd9c625":"changeAddressPaladin(address)","fbd9c902":"vendi()","fbda68e2":"numberOfMessages()","fbdafaf9":"getInvestorAtIndex(uint256)","fbdb70fb":"KRWT()","fbdbad3c":"lastCompletedMigration()","fbdc03fe":"nettingContractsByAddress(address,address)","fbdc562a":"setCanChange(bool)","fbdd3982":"s17(bytes1)","fbdd7852":"Ownership()","fbdd8508":"PriceAccepted(uint256,uint256)","fbdda15a":"isTrustedContractAddress(address)","fbde47f6":"FEE_RANGE()","fbde5b64":"gameLength()","fbde8ad4":"pStartBlock()","fbde8d75":"manualWithdrawTokens(uint256)","fbdeecab":"endTimePreIco()","fbdf0378":"getAllChildren(bytes32)","fbdf45c8":"ZoosCoinToken()","fbe00e8e":"receiveEtherFromGameAddress()","fbe04e1c":"boolFunc(bool,bool,bool)","fbe0508c":"toggleActive(bool)","fbe093dc":"targetFeePeriodDurationSeconds()","fbe2e125":"addBet(uint256,uint8,uint256,bool)","fbe334f8":"getNumFulfillments(uint256)","fbe3462c":"minBuyRateInPrecision()","fbe3549c":"addWeight()","fbe38ffb":"canEscapeTo(uint32,int256,uint32)","fbe3bb40":"TSTOraclzAPI()","fbe3e1a2":"_setCap(uint256,string)","fbe413e4":"createMember(address,bytes20,uint64)","fbe45b48":"unitPLATCost(uint256)","fbe5ce0a":"removeOwner(address,address)","fbe5d87e":"getTotalCollected()","fbe6529f":"findOldest()","fbe6a9b2":"winners_count()","fbe7913f":"Accept_Payment()","fbe89965":"GoldenCoinToken()","fbe8dab9":"getProfitForDay(uint256,uint256)","fbe9bb6d":"_isValidDepositCountry(uint256,uint256,uint256)","fbeaa807":"RefundSent(uint256,address,uint256)","fbeaaed2":"VersionedAgreementControll()","fbeac9c9":"setRefBonus(address,uint256)","fbeaebc6":"murder()","fbeb89dd":"tournamentContract()","fbebc9af":"getPixelAuthor(uint32,uint32)","fbec4769":"MatchpoolAdministrator()","fbec51bc":"requestRedemption(address)","fbec6f21":"gold()","fbec9121":"maxRandom(uint256)","fbece99f":"abortive(uint256,uint256)","fbee7b58":"giftIsFrom()","fbeecb47":"safeTransferByContract(address,address,uint256)","fbeee7e4":"isPeriodClosed(uint256)","fbef0195":"_calcDelta(uint256,uint256,uint256,uint256)","fbef957b":"ada()","fbf05e69":"GasLog(string,uint256,uint256)","fbf0ade1":"setOwnerFee(uint256)","fbf0f7da":"buildOutAddress()","fbf184c6":"getBankermasterReq()","fbf1a44b":"holyBountyFundDeposit()","fbf1f78a":"unapprove(address)","fbf22dea":"issueSoftcapToken(address,address,uint256)","fbf2360c":"isMessageEnabled()","fbf2dd6a":"depositTokensForAccount(address,address,address,uint256)","fbf350e2":"TokenBBBasic()","fbf3c88d":"getSignedPublicEncKey(address)","fbf405b0":"pinakion()","fbf42072":"CashPoints1()","fbf44a1b":"setOraclizeGas(uint256)","fbf552db":"hint()","fbf561fe":"developer_add_address_for_A(address)","fbf58b3e":"transfer(string,address)","fbf69367":"FuleexToken()","fbf788d6":"cash(address,uint256,uint8,bytes32,bytes32)","fbf7980f":"setChainsAddresses(address,int256)","fbf7ba65":"claimExploreItem(uint256)","fbf7e985":"ExaUSD()","fbf80773":"isUserRoot(address)","fbf82d31":"WorldWideCoin()","fbf9180e":"getLastAuditTime(address)","fbf94ce1":"GlaidexToken()","fbf9dab7":"getBetters()","fbf9dc12":"GoldBank()","fbfa49a8":"icoWithdraw()","fbfa4b7f":"requestsCount()","fbfa77cf":"vault()","fbfb76c4":"GUAEX(uint256,string,string)","fbfb77d7":"setArquivo(bytes)","fbfb7e70":"market_WithdrawForSale(uint256)","fbfb8b02":"createMintRequest()","fbfbb62e":"BASE_CLB_TO_ETH_RATE()","fbfc1653":"XBLToken()","fbfd1da4":"getKeccak256Uint(uint256,uint256)","fbfd45f5":"PRE_SALE_START_2()","fbfd90cb":"finishBurningByCreator()","fbff728f":"HodboCrowdsale()","fbffb355":"testBitsEqualFailIndexOOB()","fc00234e":"icoStage()","fc006216":"MODICOIN()","fc01157c":"firstCrowdSaleEndDate()","fc017495":"EmployeeOptionsExercised(address,address,uint32,bool)","fc018c05":"makePublic()","fc01987b":"setLockAccount(address)","fc01abbe":"stringToBytes32(string,string)","fc01ce83":"increaseClaimsBalance(address,address,uint256)","fc01dfbb":"mintUpto(address,uint256)","fc0262e0":"CpublicGold()","fc02c1df":"assertExpectations()","fc03441c":"allDecimals()","fc034bd8":"getPoolOwners()","fc036d7c":"SECURITY()","fc037776":"assertEq31(bytes31,bytes31)","fc03c7ec":"setLockend1(uint256)","fc03fb11":"MacBookOracle()","fc043830":"getNetworkFee()","fc043cad":"setPullPaymode()","fc04771a":"RT()","fc04a2ec":"_getOriginAddressHash(address,address,string)","fc04c0c4":"partnerTransfer(uint256,bytes32,address,uint256)","fc04c62e":"offerAsSacrificeFromVault(address)","fc05a6fc":"getPeopleBeforeMe(address,address)","fc06013a":"updateTokenEmission(uint256,uint256,uint256,uint256)","fc0656c9":"candyTokenAddress()","fc06a877":"createApp(string,uint256,string)","fc06d2a6":"sunrise()","fc078bd4":"GDCAcc05()","fc0808e5":"bet_MIN()","fc091b71":"MitCoin()","fc09ff9e":"submitTransaction(address,string,string,uint8[],bytes32[],bytes32[])","fc0a39b7":"isJackpot(bytes32,uint256)","fc0c3460":"CryptoSoft()","fc0c38a7":"Dsocial()","fc0c50fe":"getCallPtr()","fc0c546a":"token()","fc0d0117":"masterWallet()","fc0dce74":"ATL(address)","fc0e3d90":"getStake()","fc0e4262":"___AllBalance()","fc0e64de":"setInitialGasForOraclize(uint256)","fc0e74d1":"shutdown()","fc0ea853":"processWithITG(address,uint256)","fc0f392d":"activateSafeMode()","fc100eb2":"inxToken()","fc10655e":"actual_feedin()","fc10881a":"CXCoin()","fc108f70":"GamblerPerAddress(address)","fc10d4d5":"getFeeRecipientById(uint256)","fc11f71c":"setInstructor(address,address,uint256,bytes16,bytes16)","fc122892":"deleteOpenAction(string,address,string)","fc12c7da":"blocknumbersOf(uint256)","fc12dfc7":"weiDelivered()","fc13440c":"HealthCharityToken(uint256,string,uint8,string)","fc136941":"EmergencyWithdrawalProposed()","fc13a76a":"testFailAddForeignChildNotInUse()","fc14230f":"wei2euroCents(uint256)","fc143f2b":"defrostOwner()","fc14a47c":"CTBToken()","fc14ed71":"updateForSale(uint256)","fc157b13":"getOrganFunction(uint256)","fc15dcef":"resAmount()","fc1711f2":"setWeight(uint256)","fc176c4c":"getAdsCountByUser(address)","fc177bd6":"resetArray()","fc178f2a":"MoonTokenERC20(uint256,string,string)","fc17ce26":"Panthercoin()","fc17d2ac":"setFunctionEightPrice(uint256)","fc184fff":"addPhenomenon(string,string,string,uint8)","fc190261":"getIntervalsForWindow(uint256,uint256,uint256,uint256,int256)","fc190d6e":"newUpdate(string,bool)","fc192fb0":"setMinimumWithdrawal(uint256)","fc196cf3":"getNoInvestor()","fc1a1110":"currentLiquidInDeal()","fc1a142d":"adPriceHour()","fc1a3f0a":"decreaseTokenLock(address,uint256)","fc1adfdf":"invest(address,uint256,uint256,uint256)","fc1b8a7e":"richestPlayer()","fc1b9286":"rewardActivityEnd()","fc1c01b2":"setCrowdsaleParams(uint256,uint256,uint256)","fc1c2180":"setHotWalletAddress(address)","fc1c32fa":"fundariaBonusFundAddress()","fc1c5218":"RemoveOpenOrder(uint32)","fc1c9620":"depositOrWithdraw(address)","fc1da46a":"parcipateCrowdsaleAll()","fc1dfdf1":"extraData1FromHash(string)","fc1e1a32":"NetfBalance()","fc1e2ce9":"getGameAmounts(uint256)","fc1eb4d1":"withdrawPoly()","fc1ed437":"initialAmount()","fc1f2a70":"Add(uint256,string,string)","fc1f2d46":"setAllowTransferWhitelist(bool)","fc1f5c9c":"personalSegmentHash(string,uint256,bytes32)","fc1f5e53":"resetTimeLockValue(address)","fc1f7652":"_isBoardMember(address)","fc200a55":"mintWithTimeLock(address,uint256,uint256)","fc201122":"_setOwner(address)","fc204334":"sendAwardToLastOne()","fc207c8f":"periodAt(uint256)","fc21fa40":"getAmountByCurrency(uint256)","fc223410":"doBet(uint256[],uint256[],uint256[],uint256)","fc22545c":"getPreICOFundersCount()","fc22a9f8":"initialIssuance()","fc22d0e5":"migrate(address,uint256,uint256)","fc23466d":"search_data()","fc235fb8":"timeWaitApply4Redeem(address)","fc236188":"setData_7(string)","fc23f5b1":"getAddressByID(uint256)","fc248fd6":"RegisterNode(bytes32)","fc24e589":"badgeTotalSupply()","fc2525ab":"get(address,string)","fc252b94":"_getBuyPrice()","fc257baa":"traderWithdrawalSignals(address,address)","fc2584a2":"fillOrMarket(address)","fc26088e":"K_INITIAL_SUPPLY()","fc2615d5":"getRemainTime()","fc2634b7":"callURL(string,string,string)","fc26d522":"tip_total()","fc26fe01":"setairDropManagerLimit(uint256)","fc27ea83":"defaultAmount()","fc281217":"TokenInformation(address)","fc284d07":"earlyBackers(uint256)","fc28bc8f":"staffContract()","fc2b8b7b":"initTokenSupply(uint256)","fc2b8cc3":"quit()","fc2bd7ae":"sendtoMultiWallets(address[],uint256[])","fc2c1ddb":"setItemAvailable(uint256,bool)","fc2c3e08":"getIteration()","fc2d2b69":"SmartBondsToken()","fc2d64e3":"getProviderData(address)","fc2df281":"withdrawICOEth()","fc2e5bf2":"OfferOnHold(uint256,bool,address)","fc2ea8a5":"airdropAmount()","fc2f5e67":"recoveryAllowed()","fc300522":"getCallFee(bytes32)","fc303ef1":"destroyBottle()","fc3087f8":"withdrawAll2()","fc317cbe":"mainSaleDate()","fc322d73":"challengers(bytes32)","fc324642":"__createNewToken(address,string,uint256,uint256,uint256,uint256)","fc325efd":"getItemByIndex(uint256)","fc3280c2":"getDegreeAtIndex(uint256)","fc32f09c":"MyShareToken()","fc331ebb":"transfererc20(address,address,uint256)","fc334e8c":"reveal(bytes32,bytes32)","fc335bb5":"OrmeCash()","fc337f5a":"getFreeCat()","fc342947":"renewFeatured(uint256)","fc34b908":"TOTAL_BONUS_SUPPLY_ETH()","fc366a2a":"RETZE()","fc36cc9d":"setCoolHero(uint32)","fc36e15b":"vote(string)","fc37987b":"buyRate()","fc380d96":"addBonusTokens(uint256,uint256)","fc384b7c":"executeStackholderTransaction(uint256)","fc385d51":"changeRelease6m(address)","fc3880ae":"priceWithBonus()","fc38ce19":"validPurchaseTokens(uint256)","fc38d4a4":"upgradeAgility(uint256,uint256)","fc395c90":"AddBillModerator(address)","fc3b7379":"lastBlock_a18()","fc3c28af":"devPercent()","fc3c8561":"testDistribute(uint256,address[],uint8[])","fc3d9f9f":"calcUnMaskedKeyEarnings(uint256,uint256)","fc3daf81":"_CalcDiv()","fc3f162b":"unregisterAuditor(address)","fc3fc168":"DIVIDEND()","fc3fc4ed":"getAuctionInfo(uint256)","fc4116bb":"p_update_mResalePlotTaxPercent(uint256)","fc416159":"coreERC()","fc42b58f":"getTransferFee(address,uint256)","fc4333cd":"clean()","fc434891":"unWhitelistAddresses(address[])","fc43bbfb":"setWhitelistAddress(address,uint256)","fc442ec3":"getFlavor()","fc44e41b":"RANDOMFACTToken()","fc44fd28":"payBalanceToReturnWallet()","fc450ae6":"MummyAccountWithdraw()","fc45c822":"getDividends(address,address)","fc470105":"TestcoinToken()","fc47b9d2":"brulerDe(address,uint256)","fc47fcf5":"total_devidend()","fc48b653":"authorizedTransfer(address,address,uint256)","fc49926f":"getCountdowns()","fc4a089c":"newPermission(bytes32,address[],bytes4[])","fc4a4a1e":"StartTime()","fc4b01ff":"addTicketsToDraw(uint256,uint8,uint8)","fc4b2473":"ALC_CONTRACT_ADDRESS()","fc4bd9d7":"throwIfSetPresaleTokensAfterSaleStarts()","fc4c0daa":"_agent()","fc4d20f5":"addMonsterObj(uint32,address,string)","fc4d705b":"COLOR_GOLD()","fc4db64e":"SendAmount(address,address,uint256)","fc504655":"getPriceInWei()","fc512b92":"postCrowdsaleWithdraw(uint256)","fc515d93":"approvedAddressSize()","fc51b9c5":"cancelOrder(address[3],uint256[5],int256,int256)","fc51daef":"getCurrentRoundWinner()","fc523f7a":"settte(uint256,address)","fc525c75":"Ammbr(string,string,uint8)","fc52be0a":"getLatestTokenAllocation(address,address)","fc52cc1d":"incPreSell(address,uint256)","fc52f2eb":"DogRacingToken()","fc5378bb":"getEmployeeInfoById(address)","fc539a4a":"getInstances(bytes32)","fc53c821":"getMembersLength()","fc53f958":"ADMIN_ALLOWANCE()","fc53fe51":"_authorizePayment(address,uint128)","fc548f08":"changeArbitrator(address)","fc55c8d6":"buyPixel(uint256,bytes32)","fc55ea9d":"removeCustomer(string)","fc56200e":"JCFv1(uint256,string,string,uint8)","fc563658":"getNumber(uint256)","fc578323":"getProposalProposedBy(bytes32,bytes32)","fc57fadf":"IsValidAddress(address)","fc58452e":"castVote(bytes32,uint16)","fc58edea":"FoundationAddressFreezeTime()","fc58fc49":"setUser(address,address,string,uint256)","fc59116d":"setTokenTypes(uint16,uint16,uint16)","fc5a0152":"div256(uint256,uint256)","fc5ab1c6":"_unlockOther(address)","fc5b57a6":"removeStackholder(address)","fc5b652a":"LogNeumarksBurned(address,uint256,uint256)","fc5be8ec":"bonuscalico(uint256)","fc5c0cde":"allTimeDiscount(uint256)","fc5d9244":"totalBonusTokens()","fc5e2cce":"calculatWithdrawForPeriod(uint8,uint256,uint256)","fc5eb846":"currentHunterNumber()","fc5faa82":"ProWalletToken()","fc5fc345":"getPlayerIds()","fc5fc8ae":"preICOEnds()","fc601902":"_isAdmin()","fc608e17":"getAllocatedTokenCount(address,address)","fc60bb36":"_removeGroupFromMember(address,bytes32)","fc60e82c":"calculatePrize(uint256,uint256,uint256,uint256)","fc612a8d":"priceUpdater()","fc623ef8":"hashToSign(bytes32)","fc632647":"MNToken(uint256,string,uint8,string)","fc63977a":"getAddressFromUsername(bytes32)","fc63d4fb":"order(bool,uint32,uint128)","fc63dad6":"getLastBuyer(bytes32,uint8)","fc65169a":"phase4Duration()","fc65b3ac":"all_team_accounts()","fc65ee05":"marginCallOnBehalfOfRecurse(address,address,bytes32,uint256)","fc65f812":"_currentPrice(uint256)","fc6634b9":"setSellPrice(uint256)","fc673c4f":"operatorBurn(address,uint256,bytes,bytes)","fc676652":"Embassy(address,address)","fc67af2d":"withdrawCommunityBalance()","fc68521a":"f(address)","fc687311":"betOn(int8)","fc688e87":"logAccount(address,uint256)","fc6a0ca6":"changeTeamSize(uint8)","fc6a3ff7":"ticketsOwnedByUser(address)","fc6b72b6":"bringCat(uint256)","fc6c403b":"getMySalePrice(bytes32)","fc6d0dd0":"getLightingWithdraw(address,address,bytes32,bytes32,uint256,uint32)","fc6d1892":"setArrUintField1(uint256[])","fc6def15":"decider()","fc6e33ee":"MAX_SALE_DURATION()","fc6ef5a5":"getUserTokenLocalBalance(address)","fc6f46a0":"addTether(address,string,uint256,uint32,string)","fc6f9468":"adminAddress()","fc6fadec":"LoggedReward(uint256,string,uint8,string,bool,bool)","fc700dc0":"createBucketLender(bytes32,address,address,address,uint32[7],address[],address[])","fc70b462":"viewReputation(address)","fc722b2b":"trustedDarknodeRegistry()","fc72c1ef":"ERC20Base(uint256)","fc735e99":"verify()","fc7368fa":"reopenBet(uint256)","fc73c86e":"getInvestments(address)","fc73ec00":"changeDividend(uint256)","fc741c7c":"makerFee()","fc749323":"NTC()","fc74dadd":"delegateProxy(address,bytes)","fc74f55c":"IexecHubAccessor(address)","fc753ce3":"NAME_ARK()","fc756c69":"createship(uint256,address)","fc7596a8":"GoldBoxToken()","fc76501a":"preIco1Raise()","fc76687c":"jinglesOnSale(uint256)","fc77060d":"withdrawEtherHomeExternal()","fc772c8b":"reclaim(address)","fc773166":"GCoin()","fc78b430":"delegateVote(address,address,uint256)","fc792719":"hasBeenClaimed()","fc794183":"timesfucky()","fc79c8eb":"TBCoin()","fc7ae9f5":"presaleMaxContribution(address)","fc7b78b1":"changeVestingAgent(address)","fc7b9c18":"totalDebt()","fc7ba686":"affiliatesCutOutof100()","fc7c1c80":"getParentB(uint256)","fc7c41af":"doDisown()","fc7cb268":"PoSToken()","fc7d07ce":"AllocateFounderTokens()","fc7d2b3a":"EtherOcrend()","fc7d6518":"getLockSdc()","fc7e061f":"convertPresaleTokens(address,uint256,uint256,string)","fc7e4768":"saleMinShares()","fc7f1a88":"increaseBurnApproval(address,uint256)","fc7f7957":"callMeMaybe()","fc7fcae1":"extractFund(uint256)","fc800df4":"getBuyerbyaddress(address,address)","fc818684":"burnFromContract(uint256)","fc8234cb":"_unpause()","fc82d0f7":"currentIterationSupplyLimit()","fc836563":"SendTokens()","fc845834":"GoldenCoin()","fc860e96":"emissionTime()","fc862027":"setNameTAOLookupAddress(address)","fc86a7a5":"getTokenSoldPrice(uint256)","fc87790f":"addToWithoutFee(address)","fc8791c0":"change_p1(uint256)","fc87c766":"addressCap(address)","fc880be0":"SetCommissionValue(uint256)","fc882dff":"ownerHashed()","fc88ee77":"optionExerciseOf(address)","fc891b97":"MosesToken()","fc892cfe":"setup_token()","fc89aff6":"submitVerifiedUsers(address[])","fc89f349":"ORZToken()","fc8aaa76":"disableManualEmission(bytes32)","fc8ad37c":"changeParameters(uint256,uint256,uint256)","fc8b4a90":"checkDuplicateMatchId(address,uint256,uint256)","fc8bbb6d":"AddresstoAsciiString(address)","fc8c2f0d":"AlphaMarketTeamBountyWallet(address[],address)","fc8cddf2":"ARCADIA()","fc8d4f4f":"getShareHoldersInfo(uint256)","fc8dae84":"AllAmericanCoin()","fc8f3a94":"_getPayTo()","fc8f616e":"XXX()","fc8fc6f7":"KittyCoins()","fc906720":"setSiringWithId(uint256,uint32)","fc906897":"StageDistributed(uint8,uint256)","fc909fc7":"EtherGrand()","fc912461":"_setControllers(address[])","fc914949":"ValidContractRemoved(address,address,uint256)","fc91a274":"getAmountByToken(bytes32,string,address)","fc91e03d":"EtherDeltaWithdraw(uint256)","fc94dd18":"verifyHumanStandardToken(address)","fc959d9a":"getMin(uint32[])","fc961664":"setPI_edit_7(string)","fc966d45":"uintToStr(uint256)","fc970859":"PacBall()","fc976827":"TOTAL_TOKEN_AMOUNT()","fc9774c1":"dividendShares(address)","fc98f71e":"developerLock()","fc99342e":"create_table()","fc9937e5":"orders_sell_total()","fc996557":"goldContract()","fc998981":"sendBountyBalance(address[],uint256[])","fc9bfaa6":"externalCallFlag()","fc9c473d":"limitPerHolder()","fc9c8d39":"caller()","fc9dab52":"soldSale()","fc9dc608":"setRoundTime(uint256,uint256)","fc9e53df":"setNextRegistrar(address)","fc9ede65":"getPropertyBecomePublic(uint16)","fc9f8cae":"_isApprovedPack()","fc9ffe02":"getWalletList()","fca062d3":"blockBeforeChange()","fca10682":"randomGen(uint256,uint256,uint256)","fca129a3":"finalizeDescription()","fca16c3b":"getBuyPrice(uint256,uint256,uint256)","fca2452b":"change_b(address)","fca2d9f5":"senttest()","fca2efd5":"DocnotaPresale(address,address)","fca346af":"SetupCrowdSale()","fca3644a":"verifyMessage(uint8,uint256,bytes32[4])","fca3b5aa":"setMinter(address)","fca495f0":"receivePurchase(uint256)","fca5d057":"migrateTokensV1(address,uint256)","fca5d21f":"playSlot()","fca5e61e":"drugs(uint256)","fca64947":"setMetaBet(uint256)","fca69afa":"CYCLE_CAP()","fca6d4e2":"LogAccess(address)","fca76c26":"lockMaxSupply()","fca7c355":"MUSTToken(address,string,string,uint256,uint256)","fca7cdba":"pgoMonthlyPresaleVault()","fca865dd":"aSetProportion(uint16)","fca981f6":"setStepFunctions()","fca9bb5f":"FACTOR_1()","fcaa7664":"getStage()","fcaa96fa":"withdrawForThreeStep()","fcac1c77":"DragonKing(address,address,address,address,uint8,uint8,uint8,uint16[],uint16[])","fcad399f":"TheFlashToken(uint256,string,string)","fcad8cf3":"RentOffice()","fcae08e1":"fundTokens()","fcae4484":"unsubscribe()","fcae8c06":"takeMoney()","fcb0339e":"icoMinCap()","fcb0368c":"BuyToken(uint256)","fcb0a7ad":"getMinAuditPrice(address)","fcb0e55c":"_validGenes(uint256)","fcb163c7":"ExecuteOptions(address,uint256,string,uint8)","fcb1804d":"getRateAndTimeRemaining(uint256,uint256,uint256,uint256)","fcb1b62d":"arbiterAcceptCount()","fcb1cba0":"GetQuota()","fcb2931b":"LockupContract(address,address,address)","fcb2acd5":"_preValidatePurchase(address,uint256)","fcb2cafc":"verifyAddress(address)","fcb300e6":"_activate()","fcb36ce2":"buyCalcAndPayout(address,uint256,uint256,uint256,uint256,bool)","fcb3a3a3":"setCrowdsaleMinter(address)","fcb5bc29":"startPhase2()","fcb5ced3":"saveToCW()","fcb5d44d":"doExchange(uint256)","fcb6323a":"unclaim(address[])","fcb71ea9":"balanceOfHolder(address)","fcb750cf":"REFUND_DIVISION_RATE()","fcb806ac":"ReserveManager()","fcb80d16":"getCurrentFgcCap()","fcb899d7":"LEGAL_EXPENSES_ADDR()","fcb8b1e1":"NewHardCap(uint256)","fcb927aa":"addPublisher(string,bytes,address,address[],uint256[],address,uint32[])","fcb941c9":"setGenomeContractAddress(address,address)","fcb94dbb":"toBytes(address,address)","fcbc1bc4":"Standard23TokenMock(address,uint256)","fcbcf436":"clearSums()","fcbd06aa":"supportersMap(address)","fcbd2731":"transferToProxy(uint256)","fcbe0f5f":"BRD()","fcbeaaa7":"buyTile(uint16,uint16,uint8)","fcbf3131":"private_setBankAddress(address)","fcbf323a":"ScienceToken()","fcc01cce":"getExpectedAmount(bytes32)","fcc101ba":"getCommunityDescription(uint256)","fcc11241":"addOrder(uint256,uint256,uint256,uint256,uint256,uint8)","fcc15c8e":"Strike(uint16,uint32,uint16,uint8)","fcc1cc9b":"removeLockMultiple(address[])","fcc21e56":"withdrawToTeam()","fcc29ae8":"setMaxContributor(uint256)","fcc2a69b":"BankuNetwork()","fcc34e89":"migrateCrowdsale(address)","fcc36c49":"refuseInvestment()","fcc47803":"removeSpecialOffer(address)","fcc4a54c":"getDeedIds()","fcc4dec9":"refound(uint256)","fcc550c6":"CreateCCM(address,uint256)","fcc5b5ad":"investContracts(uint256)","fcc60b6a":"isInited()","fcc648f6":"withdrawEtherToReserveEscrow()","fcc6b5d5":"fillTheirOrder(address)","fcc73637":"updateExchangeRate(uint256,uint256)","fcc8221f":"getfromsun(address,uint256,uint256)","fcc830be":"getMyRickAndMorty()","fcc89710":"LogTokenSaleInitialized(address,address,uint256,uint256,uint256)","fcc9b48c":"isIcoFailed()","fcca4040":"tokenCapReached()","fcca8949":"p_setDevPercent_out(uint256,uint256)","fccc2813":"BURN_ADDRESS()","fcccc68f":"LoveBite()","fcce0492":"AdminTransferredOwnership(address,address)","fcce2622":"challengeAnswer(uint256,bytes)","fcceea26":"communitySupply()","fccf5a68":"SmartBinding()","fccf6e67":"newOrdersContract(address)","fccf82a4":"endDateOfPreSale()","fcd0a747":"RICTToken()","fcd10753":"_getProviderSupply(uint256,uint256,uint256)","fcd13382":"OsherCoinPresaleAward(uint256)","fcd13d65":"setContractRegistry(address)","fcd14456":"teamVestingPeriod()","fcd24400":"lookupCampaignPart2(uint256)","fcd307c4":"processReferral(address,address,uint256)","fcd3533c":"burn(uint256,address)","fcd41502":"requiredMajorityPercent()","fcd41c1f":"officialAddress()","fcd45807":"isTokenRegisteredBySymbol(string)","fcd47e79":"getnowcardcount()","fcd51a4e":"_setIntelligenceValue16(uint256)","fcd58363":"refundCancelledGame(uint32,uint32[])","fcd6e339":"giveBlockReward()","fcd6ec11":"HELLO()","fcd735dd":"transferVesting(address,uint256,uint256,uint256)","fcd778da":"setCardsAddress(address,address)","fcd792f4":"nextAvailableId(uint256)","fcd830c4":"setCCH_edit_28(string)","fcd8c9d4":"_goldTotalSupply()","fcd92992":"resync()","fcd936b1":"Simple()","fcd9da44":"setParameters(uint256,uint256,uint256,uint256)","fcd9f4ce":"withdraw(bytes32,string,string)","fcda4ded":"showBankAmount()","fcdb2c04":"getMyGameInfo()","fcddd056":"payIn()","fcde22fa":"_eachPrize(uint32,uint256,uint8,uint32,uint256)","fcde2ff6":"getPI_edit_23()","fcde6831":"addTokens(address[],bytes32[],uint256[],uint256)","fcde6ebe":"createSalesTierConfigMap()","fcde7b69":"TokenFRT(address)","fcde9925":"proposalOwner(uint256)","fcdf350b":"EGGS_TO_HATCH_1FAIRY()","fcdf9750":"createDispute()","fce14069":"partnerBonusPercent()","fce1cc35":"setInt(int256,int8,int16,int32,int256)","fce1ccca":"voting()","fce1e3e9":"setPatentFees(uint256[9])","fce20190":"_refund(uint256,uint256,uint256,uint256)","fce22c4c":"generatePseudoRand(bytes32)","fce266cb":"artworksFactory(address)","fce33f01":"withdrawLimit(address)","fce3b91e":"IdolToken1()","fce3bbb5":"setSelling(bool)","fce44634":"isValidHashType(uint8)","fce48558":"countryOf(uint256)","fce4c128":"checkInvestmentRequired(uint16,bool)","fce4f84f":"sellToConsumer(address,uint256,uint256)","fce59d0c":"MangoRepo()","fce6d586":"LogClaim(address,uint256)","fce78e5e":"TurtleToken(uint256,string,string)","fce846e8":"getExtraBonus()","fce87fb0":"tokenUriPrefix()","fce897e5":"payBid(address,uint256,bytes)","fce908ad":"whitelistTx(address,address)","fce927f3":"issueReservedTokens(uint256)","fce9fbff":"minWeiPerContributor()","fce9fdd9":"MPYCreation(address,uint256)","fceb9852":"isToOffChainAddresses(address[])","fcec617a":"conflictEndFine()","fcec962e":"adminWithdraw(address,uint256,uint256)","fceca4a0":"VICOXToken(uint256,address)","fcecbb61":"getReceipt(bytes32)","fced4a86":"CryptoHuntIco(uint256,uint256,address,address)","fced5694":"FOUNDER1_STAKE()","fced6ad2":"KARMAtoken()","fcee45f4":"getFee(uint256)","fcef09d6":"BlipCompetition(address)","fcef56a4":"createBar()","fcf07c6b":"foundationAddress()","fcf0f55b":"eventOracles(bytes32,uint256)","fcf23a92":"LogOwnerChanged(address,address)","fcf23d63":"getMatchInfoList03()","fcf2f85f":"requiredDevSignatures()","fcf32769":"adminWithdraw(address[4],uint256[5],uint8,bytes32,bytes32)","fcf3438c":"setSmsCertifier(address)","fcf36918":"doCall(bytes32)","fcf40170":"cleanWallets()","fcf4333a":"updateHashrate(address)","fcf43ce2":"setValidTransferAddress(address)","fcf4b576":"getVaultAccess(address)","fcf516aa":"VuePayToken()","fcf5462e":"SuperUltraUltraCoin()","fcf56577":"setRequesterLock(bool)","fcf7e73d":"addBeneficiary(address,uint256,uint256,uint256,uint256,bool,string)","fcf84962":"InvestAddEvent(address,uint256)","fcf8566e":"unsoldCleanUp()","fcf911e7":"delAddressValue(bytes32)","fcf9c44d":"soldUET(address,uint256,bytes32)","fcfa2bfe":"SALES_START()","fcfa63e3":"getResourceAddress(string)","fcfbc962":"Unset(string,string,address)","fcfc1577":"masterFns(bytes32)","fcfc208e":"unclockAddressDuringITO(address,address)","fcfd3a4c":"PreICO(address)","fcfdaa52":"successfulTime()","fcfdbc23":"perform_withdraw(address)","fcfdcf8a":"removeOpenMakeOrder(address,address)","fcfdeba8":"changeGameEnable(uint256)","fcfdf7c5":"decApprove(address,address,uint256)","fcfe2247":"setContributionDates(uint256,uint256)","fcfe6af1":"transfer(address,uint256,address,address,uint256,uint8,bytes32,bytes32)","fcff1eaf":"increaseGasSpent(bytes32,uint128)","fcff5ed6":"createChannelDelegate(address,address,uint192)","fcffb14e":"getNormalPayout(uint256)","fcfff16f":"open()","fd004f2d":"IRONtoken()","fd01249c":"createGen0Auction(uint256,uint256)","fd01d4a1":"ownerDivRate()","fd0326b4":"m_nextSale()","fd036052":"modPass(uint256,uint256,string,string,string)","fd037bc5":"changeIsPayableEnabled()","fd03846e":"setCreditBondContract(address)","fd03c006":"agreeCount()","fd03d762":"resumeWork(uint256)","fd03e721":"referraltokencontract()","fd049319":"distribute1BTCO(address[])","fd04a902":"totaletherstransacted()","fd05ddfc":"CCCRCoin()","fd062d3b":"handleFees(uint256,address,address)","fd06c6a9":"issuePass(address,bytes32,uint8)","fd070667":"tournamentResult(uint32[3][11][32])","fd074c28":"removeWeapon(uint8[176],uint8,uint8)","fd074e8e":"checkIfMissionCompleted()","fd0801c1":"appendNumToString(string,uint256)","fd080993":"submit(bytes32,bytes32,bytes32)","fd083748":"isGason(uint64)","fd084b16":"etherPartition(uint256)","fd085b41":"minSaleAmount()","fd08921b":"getYear()","fd090e47":"DEPOSIT_PERIOD()","fd0998de":"Totalbalance()","fd09b6f0":"JNDToken()","fd09d013":"CROWDSALE_ALLOCATION()","fd0a7f3e":"grantGrantableAllocations()","fd0aeb34":"EderCoin()","fd0b9dc2":"verifyWithdrawUpdate(bytes32,bytes32,uint256,uint256)","fd0bb752":"getBonusReceived()","fd0c1edb":"_setVault(address)","fd0c2a76":"Crowdsale(uint256,uint256,uint256,address,address)","fd0c78c2":"secondaryOperator()","fd0cdcdb":"withdrawRemaining(address)","fd0cfa91":"baseFeeDivisor()","fd0d1322":"WETCC()","fd0dd4d0":"btnSupply()","fd0e4695":"_canceloffer(address)","fd0edbd6":"refundSeller(address,address,uint256)","fd0f267b":"deathData_v0()","fd0f5a81":"updateWEIAmount(uint256)","fd1075d0":"setTokenRewardRate(uint256)","fd1094a9":"JaiHoToken()","fd12c1cb":"ethFnkRate2()","fd1343f1":"ESOPAndCompanySet(address,address)","fd138223":"remainingBountySupply()","fd13a7ce":"isPurchaseWithinCap(uint256,uint256)","fd14492a":"DinoTokenSale()","fd14ecfe":"balanceOfSPS()","fd15e091":"changeSymbolName(string)","fd17f289":"teamTokenSupply()","fd186de6":"StoToken(address,address)","fd18b484":"VitaToken()","fd19368a":"isEditionAvailable(uint8)","fd1a0a55":"JINGJING()","fd1aaa72":"sendToOwnerBalance(address,uint256)","fd1bd9b0":"getAmountLeft()","fd1c50e0":"sellAtIndex(uint256,uint256)","fd1c66da":"getCertificateIssued()","fd1ccaf3":"HideraNetwork(uint256,string,string)","fd1dc137":"settoken(address,bool)","fd1e582d":"ownertransfer(address,uint256)","fd1e5e7a":"getOrCacheDesignatedReportNoShowBond()","fd1f4ba5":"setAgenda(string)","fd1fb2fa":"rateB()","fd1fc4a0":"airDrop(address[],uint256)","fd203906":"getCarState(string)","fd208ca7":"endprivateIco(bool)","fd214edd":"collect(uint64,address[],address[],address)","fd221031":"tap()","fd221889":"priceFactorA()","fd222745":"melonport()","fd225cfd":"CoCoCoin()","fd228c0b":"isMintAgent(address)","fd22a6cf":"openGames(uint256)","fd23022a":"Orocoin()","fd232b59":"getEscrowPayments(uint256)","fd241e2b":"mintWithLocked(address,uint256,uint256)","fd2457d7":"clearStorage(bytes32[])","fd253492":"leadingHitCount()","fd255683":"getAddressValue(string)","fd260dfc":"getCertificationDbStatus(address)","fd263390":"setBank(address,bool)","fd26c460":"set_game(string,string)","fd275dd5":"TokenFreezerRules(address)","fd277399":"isService(bytes32)","fd27b51e":"getMarketSize()","fd27ce93":"checkRelease(address,uint256)","fd27d1d3":"getBlockPrice(uint256)","fd282afe":"batchSingleAmount(address[],uint256)","fd28392a":"changeSweepAccount(address)","fd289797":"_canSynthesizeWithViaAuction(uint256,uint256)","fd28feb3":"createInitialItems()","fd2994f7":"totalPointsPerToken()","fd2b4f23":"TheTestCompany()","fd2b6b19":"crowdSaleEnded()","fd2b863d":"produceUnitSeconds()","fd2c3abb":"targetDiscountValue8()","fd2c80ae":"updateInterval()","fd2ce18e":"getPayloadFrom(address)","fd2cee78":"pollEnded(bytes32)","fd2cf77a":"COLOR_BLUE()","fd2d39c5":"positionOf(address)","fd2db3f4":"countTotalInvestorsInCrowdsale()","fd2dba2f":"largeRate()","fd2e9caf":"PendingETH()","fd2ecc3f":"_setLastDate(uint256)","fd2edd76":"TOTAL_LOCKS()","fd306ca7":"transferProfitToHouse()","fd30929a":"disable(address[])","fd32649f":"cleanLog()","fd330b26":"Total_Gamblers()","fd338726":"updatePlayerRewards(address,address)","fd339d18":"testAuthorityTryAuthUnauthorized()","fd345fc2":"totalNominees()","fd34e22e":"addrToForumId(address)","fd35c16d":"createLibra(bytes32[],bytes16[],uint256[])","fd35e71b":"entryPayoutDue(uint256)","fd367f7d":"toggleFeatured()","fd36c3f9":"burnFromAdmin(uint256)","fd37f1d0":"setInv1(address)","fd38af55":"testDebugClock()","fd39b40b":"GameScored(bytes32,int256,int256)","fd39ba59":"totalPreICOSupply()","fd3a77db":"acceptManagership()","fd3ab282":"q()","fd3acb5c":"getRoundOfSixteenResult(uint256)","fd3b34e6":"AddEntity(bytes)","fd3bbba5":"openOrCloseSale(bool)","fd3c1391":"flushShareNext()","fd3c1c43":"wolkAddress()","fd3c4277":"BattleDromeICO()","fd3c4cbf":"bidERC20(uint256,uint256)","fd3c88bd":"MultiVault(address,uint256)","fd3c9144":"intervalTime()","fd3cabc0":"_triggerPVEFinish(uint256)","fd3cb5d1":"doCommunityMinting(address,uint256,int256)","fd3d0dbf":"ioxis()","fd3d8cdc":"registerNameXID(string,bool)","fd3e2d86":"EpayToken(uint256,string,string,uint8)","fd3e50a7":"deliver()","fd3e6a0a":"transfers(address,address,uint256)","fd3ecae6":"changeExtendedTime(uint256)","fd3eefe9":"getAvailableAmount(string)","fd3f1a04":"unapprove(uint256)","fd3f2f66":"changePrivateContribution(uint256)","fd408767":"fireEventLog4()","fd40a1e9":"addMarketItem(bytes16,bytes16,bytes16[])","fd413596":"addBulk(address[])","fd41477f":"previligedLock(address,uint256)","fd414a29":"TOKEN_RATE_20_PERCENT_BONUS()","fd425dd5":"initCopper()","fd42657a":"_currentOwner()","fd426e40":"remainingTokensVIPs()","fd4446f3":"ICOSALE_JOINTTOKENS()","fd460302":"internalPresaleVesting(address,uint256,uint256,uint256,uint256,uint256)","fd4649ae":"UpdateUserPELOBonus(address,uint256)","fd46544a":"deleteAllBioTranslations()","fd467473":"setupFundingRate(uint256,uint256)","fd468aaa":"setPeriods(uint8)","fd473852":"TaiChiCoin()","fd475875":"newInversor(address,address)","fd475fa2":"requestAddAdmin(address,string)","fd478ca9":"getNumParticipants()","fd48cc45":"challenge(bytes32,uint256,string)","fd4931a3":"getUintUsername(address,address)","fd4a343d":"extraMint(uint256)","fd4ad523":"recentlyEndedGames(uint256)","fd4b9d4d":"smalobox()","fd4bd17b":"calculateWineBuySimple(uint256)","fd4c5c9f":"MIN_LEADER_FRAC_BOT()","fd4c8c30":"PlayX20()","fd4d603c":"PS_PRICE()","fd4dabef":"solved(uint256,bytes32[])","fd4dbdf2":"T20coin(uint256,string,uint8,string)","fd4e165e":"RiceFarmer()","fd4e4d75":"addressA()","fd4eeb8f":"isOMICrowdsaleContract()","fd4f4125":"totalEtherHasBeenReceived()","fd4faee0":"Chain1()","fd4ff437":"addWhitelistBulk(address[],uint256[])","fd50299a":"addFeedback(address,uint256,address,string,uint8)","fd507f75":"airdropMultiple(address[])","fd50b005":"buyForWhitelisted()","fd52b3cd":"olumla()","fd52bdd5":"TweetherToken()","fd530c17":"Deposit(bytes20,uint256)","fd531e93":"getCertificate(address)","fd535203":"refundEther(uint256)","fd53e7b4":"admin_active_withdraw(address)","fd54fab8":"calculateBonusTokensAmount(uint256,uint256)","fd554229":"getGidOfRarity(uint8,uint8)","fd55714d":"getTotalCampaignsByCountry(string)","fd557d39":"queryCost()","fd56317d":"ANMvesting()","fd56d4c8":"getControlInfoPerToken(uint256)","fd57e9f9":"deleteElement()","fd57ee6d":"timelock(address,uint256,uint256)","fd58e63a":"setBonusMultiplier(uint256)","fd5a6019":"testUser(address)","fd5a60e1":"killDragon(uint256)","fd5c0663":"distributeBalanceToInvestors()","fd5c40ea":"ELIX_ADDRESS()","fd5c6694":"createGennezise(uint32)","fd5cb32c":"ItemBought(address,uint256,uint256,uint256,uint256)","fd5d173b":"MAX_NUM_OZT_TOKENS()","fd5d3e01":"getContractOrigin()","fd5eddf3":"supplyTokens(uint256)","fd5f1e03":"getParticipantLockedAmount(address,address,bytes32)","fd5f7256":"adminRetrieveContractConfig2()","fd5fde65":"mintTimeLockedTokens(address,uint256,uint256)","fd600107":"BONUS_TIER2()","fd600408":"tpe()","fd607594":"min_payment()","fd609b91":"DelVoteMemberCandidate(uint256)","fd60e1a8":"getReferralCounts()","fd6133a6":"updateTokensAvailable()","fd6180cb":"tokenDividendsOf(address)","fd619dce":"sigBountyProgramAddress()","fd61a725":"getMinimumReportingFeeDivisor()","fd626a86":"sellKWHAgainstEther(uint256)","fd6273a3":"ERC20KKToken()","fd6358ce":"setPricingStrategy(uint256,uint256,uint256,uint256,uint256,uint256)","fd636975":"addWeight(address,uint256)","fd637f02":"TEAM2()","fd63f640":"getLLV_edit_5()","fd645193":"RegistrationBonus(address)","fd64eccb":"isForwarder()","fd651d2c":"TransferBy(address,address,uint256)","fd655073":"balancesForWithdraw(address)","fd6673f5":"getNumberOfPlayers()","fd669810":"close(address,address,uint8,uint256)","fd67db81":"getCharity(uint256)","fd68610f":"getEtherBack()","fd6887af":"queenPrestige()","fd68a422":"returnmoneycreator(uint8,uint128)","fd68e463":"FeitebiToken(uint256,uint8,string,string)","fd68f377":"ethyclos()","fd69f3c2":"getMarketCount()","fd6aad25":"indexOf(address)","fd6b7ef8":"safeWithdrawal()","fd6ba459":"mintCard(address,uint8[14])","fd6bb46c":"addWeb(string)","fd6dd889":"marketTokenCreated()","fd6e1b50":"reportBenign(address)","fd6e3bfe":"setNFTAddress(address,address)","fd6ecb7b":"getReceiptDetails(bytes)","fd6efe80":"DiscCoin()","fd6f4137":"getAdvocate(address)","fd6f5270":"CouponDeposit(address[2],uint256[7],uint8,bytes32[2],uint256)","fd6f5430":"setContent(string,bytes32)","fd70813b":"setTermsAndConditions(string)","fd70b40d":"HashToken(address)","fd70f406":"citiesCount()","fd71b579":"LockMechanism(address,uint256)","fd720090":"right86(uint256)","fd7230d6":"create(uint256,bytes)","fd72a11a":"TorusCoin(uint256,address)","fd72e22a":"operationsWallet()","fd735602":"executeN()","fd7394ae":"IndividualityToken()","fd743f2b":"Coke()","fd747c0b":"rsaVerify(bytes,bytes,uint256,bytes)","fd74a151":"ETH_FUND_DEPOSIT()","fd7560ca":"distributeEarningsBasedOnScore(address,address)","fd75b8d4":"calculateGrantClaim(address)","fd7611c7":"withdrawContractTokens(address)","fd764e68":"transfer(uint256,address,address[],uint256[],uint8[],bytes32[],bytes32[])","fd77905c":"setColorMetadata(uint256,string)","fd7801df":"getCitationLength()","fd782de5":"Proxy()","fd7903a0":"getTeamFromLeaderboard(uint16,uint8)","fd790923":"keyImageUsedUpdate(uint256[2])","fd791031":"gamesFund()","fd793c76":"btg()","fd79c2a9":"ContractName()","fd7a1b00":"forbidDeploy(address)","fd7ab1ad":"chiudi_votazioni()","fd7ac203":"TestToken()","fd7af387":"canTransferBetweenUsers()","fd7c074f":"changeReceivingAddress(address)","fd7c460d":"ciberLottery()","fd7caf4d":"loyaltyCap()","fd7d7948":"getTranformedId(uint64)","fd7e1bee":"freezeTime()","fd7f611e":"createCompany(string)","fd7fc0e0":"invest(uint32)","fd7fe115":"grantAccess(address,bool)","fd7feb35":"cancelWonderSale(uint256)","fd7ffdb8":"recordSystemOnSaleToken(uint256)","fd8055d2":"updateBOTBillingInfo(uint256,string,address,string,string,uint256)","fd809759":"getYearIdx()","fd810eb3":"logAccess(bytes32,string)","fd8113e9":"checkprevowner(address)","fd812e7c":"revealHash(uint256,uint256,bytes4)","fd814dbd":"GameXToken()","fd8258bd":"canIssue(address,address,address,uint256)","fd82902d":"MeowCoin()","fd82a59f":"advisorsTokensVault()","fd83915e":"changeOwnership(bytes32,address)","fd83da09":"lastSaleDate(uint256)","fd83f3e3":"QueueUserMayBeDeliveryDroneCotnrol()","fd842125":"ricardianVoucher()","fd854148":"periodDuration(uint256)","fd85b1a7":"openChannel(uint256)","fd8663d2":"setBuyBackFund(address)","fd86e49d":"token_is_active(address)","fd872458":"PK(address,uint8,bytes32)","fd874a7b":"blockedTimeForBountyTokens()","fd87f2cb":"ADXProxy()","fd8828eb":"rawSetPrice(bytes32,uint256)","fd89a9b5":"enableImpairedTokenContract(address,bool)","fd89d17f":"THIRD_SUPPLY()","fd8ac8d0":"capDay2()","fd8acc42":"buyAuction(uint256)","fd8ae24b":"getTimeLeftInQ1()","fd8b09c2":"ENBToken()","fd8bb681":"earlyBackerList(uint256)","fd8bcf6d":"requestCancelationTime()","fd8be237":"CrowdsaleToken(string,string,uint256)","fd8c6fe4":"RexToken(uint256,address,address)","fd8d4bff":"MoyOpenDistribution()","fd902d1e":"setCutoffs(uint256)","fd904207":"OPTCToken()","fd906c0f":"createClone(address,string,string,string,address,uint256)","fd906ec9":"participate(bytes1[64])","fd909594":"icoGoal()","fd90a668":"allowManuallyMintTokens()","fd911997":"make(uint256,address,address,bytes32,bytes32,uint256,uint256)","fd9133f3":"LOCKTokenCOIN()","fd9168a9":"setRef(uint256)","fd9177b5":"LogMoveMade(uint256,uint8,uint8,uint8,uint8)","fd922a42":"server()","fd923a9e":"setCentsExchangeRate(uint256)","fd925795":"pvt_plmt_remaining_in_Wei()","fd9304cd":"minInvestmentValue()","fd93236b":"bankerEndTime()","fd9393c3":"init(uint256,string,string)","fd93bdb1":"changeRestricted(address)","fd94c80b":"priEtherReceived()","fd958695":"isAlphaNumeric(bytes1)","fd97a008":"autoDividendsFor(address)","fd97c61a":"getgamecardcount()","fd97d3c1":"giveCrypto()","fd9923ce":"asmTransfer(address,address,uint256)","fd994513":"executeVote(uint256[])","fd99a746":"transactionsCount()","fd99c012":"USDTUBESupply()","fd99c6a4":"upgradeCar(uint32,uint8)","fd9a4e61":"transferTokens(uint256)","fd9b41ff":"getCurrentFieldBalanceAndTarget()","fd9b8763":"Multiplier()","fd9be522":"withdrawFee(address,uint256)","fd9bf0a4":"_setPermissions(address,address[])","fd9bf3aa":"mint(address,int256)","fd9e2120":"initPara(uint256,uint256,uint256,uint256,address,uint256,uint256)","fd9e5fbf":"setTimeStaked(uint256,address)","fd9e8ff7":"Shard()","fd9f12b0":"isYellow()","fd9f6856":"lastDepositor()","fd9f9b87":"isOption(address)","fda0078f":"AKTestEther1(address,address,address,uint256,uint256,uint256)","fda03476":"luckySevenBets()","fda08958":"isServer(address)","fda0c61d":"setupWhitelist(address)","fda237f8":"genesisToken()","fda263e8":"timeEnd()","fda27af2":"claimSiteToken(uint8,uint256)","fda49eb4":"treasurer()","fda69fae":"getInt(string)","fda76eef":"RewardsGiftToken()","fda78599":"ecoSystemWallet()","fda79925":"complianceAddress()","fda80435":"c_MinInvestment()","fda86c95":"internalRevokeCert(bytes32,bytes,bytes32,bool,uint256)","fda92d3e":"ErrorMsg(string)","fda962d3":"totalGenesisRecipients()","fda9aafe":"WyzonCredit()","fdaa2632":"UploadURL(uint256,string)","fdaa94de":"deleteAddr(address,bytes)","fdaacf1b":"transferOwnerMoney(address)","fdab1b7b":"getCurrentAuctionPrice(address,address,uint256)","fdab5627":"_approveCertificate(uint256,bool)","fdac0025":"cups(bytes32)","fdac3a20":"set_eth(uint256)","fdac9ff7":"setAttributeValue(address,bytes32,uint256)","fdacbecd":"geteths(address)","fdacd576":"setCompleted(uint256)","fdad711d":"setFinalPayoutDistributionHash(bytes32)","fdade29f":"BuyBooster()","fdae3b70":"proofOfSms()","fdae8a4c":"isAddressInBlackList(string,address)","fdaed331":"getTransferedUser(uint256)","fdaed778":"testConcatStorage32Bytes()","fdaf150c":"abc_initNetwork()","fdaf22e8":"minutos()","fdb04023":"closeVirtualChannel(bytes32,bytes32)","fdb31d10":"_createToken(string,bytes5,string,string,string,string,string,address,uint256)","fdb357be":"getVotingForCount(address)","fdb39c40":"userNameHashTaken(bytes32)","fdb406cb":"outstandingTokens(address)","fdb473b1":"unsetMyName()","fdb4dbe0":"totalEgg()","fdb5a03e":"reinvest()","fdb7b065":"marketDataOracle()","fdb7d435":"TEC(uint256,string,string)","fdb837e8":"GetTotalClicks()","fdb89360":"ParkCoin(uint256,string,string)","fdb914e2":"capPreSale()","fdb986cc":"NiobiumToken()","fdbab5f5":"PUBLICSALE_ENDTIMESTAMP()","fdbaf779":"internalBuyTokens(address,address)","fdbb16fd":"setEthPercent(uint256)","fdbb5aee":"ChannelNewBalance(address,address,uint256,uint256)","fdbb9fdb":"UNJUST(string,string,uint256,uint256,bool)","fdbc368a":"_ensureNewUser()","fdbc4006":"getCandidateList()","fdbc6530":"updaterAddress()","fdbc938d":"BlessingChainAlliance()","fdbd2534":"acceptCoinSale()","fdbd8dd8":"investInternal(address,uint256)","fdbd956d":"oraclize_query(uint256,string,bytes[],uint256)","fdbda9a7":"parentChange(address)","fdbdc112":"backersIndex(uint256)","fdbf0765":"hash(bytes20,uint96,uint32,bytes32[],uint16)","fdbf17d0":"computeFinalStake(uint256)","fdc0713b":"getMinAuditPriceCount()","fdc193a4":"test3Fails()","fdc202f1":"Ticket(string,uint256)","fdc24095":"returnMasterNodes(address,uint256)","fdc272fe":"getTokenVolumebasedBonusRateForPhase3(uint256)","fdc292ea":"token(address,address)","fdc35112":"LogBuy(address,uint256,uint256)","fdc37c85":"securityCheckURI()","fdc3d8d7":"nextTaskId()","fdc40466":"maxInterestTime_()","fdc4741b":"addRecToQueue(address,uint256)","fdc487a7":"FundWithdrawl(address,address,uint256)","fdc4b338":"authorizeExtension(uint256,bool,string)","fdc4c3eb":"reservedWithdraw()","fdc5bf2c":"releaseToBuyer()","fdc61dd1":"coinAddress()","fdc63c5c":"aprobarMensaje(uint256,uint8,string)","fdc65c8c":"stakingBonusTokens()","fdc69291":"_adjustSupply(address,uint256)","fdc89f73":"toPowerOfThreeHalves(uint256)","fdc967e5":"jDallyCoin()","fdc98399":"getCurrentBuyerRateInPermilles(bool)","fdc99064":"unregisterNotary(address)","fdc9d0f4":"Telegram()","fdc9e72d":"_ownMint(uint256)","fdcb6068":"accessManager()","fdcb7539":"contruibuteData(bytes)","fdcbd0ec":"_deleteMinion(uint32,uint8,uint64)","fdcbd9b0":"GatewayStatusUpdated(bool)","fdcc6be3":"claimedPreICO(address)","fdccf45e":"computeCurrentPriceImpl(uint16,uint64)","fdcd0a18":"isRefundsEnabled()","fdcd649e":"EthAnte()","fdcd86ab":"addBets(bytes32)","fdce7f5e":"JinglesOpened(address,address,uint256)","fdce8e02":"checkHash1(address,uint256,address,uint256,uint256,uint256)","fdce9565":"determineWinner(uint256[7][],uint256[7][])","fdcea342":"fixPlayerMiddlename(uint256,string)","fdced779":"KozzProjectToken()","fdcf154c":"SODCOIN()","fdcf6f16":"getTopCompanyAtIndex(uint256)","fdd0298e":"PresaleAdded(address,uint256,uint256)","fdd080a4":"activateSaleContract(address)","fdd12c5e":"r(address,address)","fdd1a4e9":"externalCheckSign(bytes32,bytes,address)","fdd245ee":"referralLinkMinimum()","fdd2f2b0":"TIME_MULTIPLIER()","fdd3a879":"quick()","fdd3af8f":"fillTrade(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)","fdd3c1a1":"distributeTimelockedTokens(address,uint256,uint256)","fdd3e3ff":"_removeAuction(uint256)","fdd3ea94":"submitPeerReview()","fdd42e29":"TokenOTBC(uint256,string,uint8,string)","fdd4fd69":"penaltyDisbursalAddress()","fdd5828f":"massPay(address[],uint256)","fdd6a803":"readowners()","fdd6df8c":"mul2Require(uint256)","fdd7d87b":"decline(address,address)","fdd868df":"getTracks(uint256,uint256)","fdd8a733":"TokenCoinExchanger()","fdd8ed02":"BetPlaced(uint256,uint256,address,uint256)","fdd96ae0":"compensateContributors(uint256,uint256)","fdda3d8a":"setVicepresidenteDeMesa(bytes32,uint256,uint256,uint256)","fddaf68a":"getTipperPercentage(uint256,uint256)","fddb4683":"ERC20(string,string,uint256)","fddb7ef0":"mainSaleBonuses(uint256)","fddbcca5":"pause_4()","fddc4686":"getOwnedAssetsLength()","fddc5545":"BitHaus()","fddcbd09":"burnByCreator(address,uint256)","fddcc148":"iterator()","fdddb3ae":"Athena()","fddf0fc0":"ethRaised()","fddf16b7":"INTERFACE_SIGNATURE_ERC721()","fddf4e3b":"_packCombinedParams(int256,int256,int256,int256,int256)","fddfec78":"allowTransfer(address,address)","fde045b9":"HODLaddress()","fde07212":"Betting()","fde074c8":"betAddrsCount_()","fde0a64d":"admin_inactive_payable()","fde1276a":"removeDiscount(address)","fde17733":"demiseCEO(address)","fde1ee44":"addAttestation(string,bool,address)","fde20b6c":"tipPercentageLocked()","fde34dc4":"finalize(uint256,uint256,bytes32)","fde3cbd6":"NucleusVisionCoreToken()","fde440bb":"setPayoutNumeratorsValue(uint256[])","fde45344":"untrustContract(address)","fde46b03":"_set1()","fde4b39d":"updateStages()","fde4d9bf":"setAutoPrice()","fde5ca7d":"calcDevReward(uint256)","fde5e124":"t_Andrey2()","fde63e96":"CreateSpecialPlayer(bytes32,uint8,uint8,uint256,uint256,address)","fde6adb1":"placeBet(uint256,uint256,uint256,uint256)","fde7c834":"increase_bounty(address)","fde83a34":"tokensForTeam()","fde90733":"isRequestingEscapeTo(uint32,uint32)","fde9683d":"ICO_DAYS()","fde99668":"removeOrder(bytes32)","fde9ba41":"transfer(bytes,address,uint256)","fde9cded":"whichAuction(uint256)","fde9e506":"calcDividendsSum(address)","fdea8e0b":"presale()","fdeb49b0":"allocationsLength()","fded813c":"getInvoiceBalance(bytes32)","fdee38a9":"ETH_TLD_NODE()","fdee4ff9":"setExpectedReturn(uint256)","fdee579c":"MINfinney()","fdee5c22":"THAWING_DURATION()","fdee60e9":"peloExtenstion()","fdee69f4":"calResult()","fdef9106":"hasPermission(address,address,bytes32,bytes)","fdf061f0":"adminWithdrawBalance()","fdf0d8e0":"get_account_balance_token(address)","fdf1a434":"updateMinInvestmentForIco(uint256)","fdf1aba0":"check1(uint256,uint256)","fdf31b39":"incrementTasksCompleted(address)","fdf372ad":"niceguy2()","fdf3b97f":"calculateVestedTokens(uint256,uint256,uint256,uint256)","fdf3fa53":"RemoveCategory(uint256)","fdf54c98":"SocialNode()","fdf55523":"numRefCredits(address,bool)","fdf56d57":"voteElection(uint256)","fdf58814":"getLLV_edit_3()","fdf62f05":"createEngine(uint256,string,uint256,uint256,uint256,uint256)","fdf6393c":"removeExistingDiscount(address)","fdf762bb":"TEAM_AND_ANGEL_SUPPLY()","fdf78f70":"unlockStatus(address)","fdf7983a":"safeTransferChild(address,address,uint256,bytes)","fdf8e11c":"getTotalAngels()","fdf97cb2":"trustee()","fdfa571e":"getDrawStatus(uint32)","fdfac8e5":"BMC()","fdfcb425":"activate(address,uint256,uint256,uint256,bool,bool)","fdfd5b43":"determineWinnerScript()","fdfecb0c":"isEcoAllocated12()","fdff31ed":"getPairSellLoyaltyPerc(address,address)","fdff6b30":"testInitialBalanceUsingNewContract()","fdff85b4":"CONFIG_RETURN()","fdff9b4d":"managers(address)","fe0030d9":"IRPToken()","fe00344a":"AuctionCompleted(uint256,uint256,address)","fe006839":"INITIAL_SUPPLLY()","fe00779e":"removeBountyAddresses(address[])","fe007eeb":"SmartRouletteTokenDividend()","fe00b3a3":"kosacafToken()","fe0149a0":"ZQCToken()","fe01ee96":"Clearing(address,uint256)","fe01f1ff":"TokenTester()","fe01ff62":"verifyTx(uint256[2],uint256[2],uint256[2][2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2],uint256[2])","fe02739c":"releaseJackpot()","fe029156":"swap(address,address,uint256,uint256)","fe038093":"createTeams()","fe04a5bc":"senderMIT()","fe04cb1d":"setStatusPrice(uint256)","fe052bc6":"minimumInvestmentInWei()","fe05e8b1":"assertFact(uint256,string)","fe05f7c2":"destroyforeth(uint256)","fe06a915":"totalMTPAllocated()","fe082a21":"SFEscrow()","fe085775":"PresaleAllocation(address,uint256,uint256)","fe08e5fe":"setGalleryTwoPrice(uint256)","fe0904e6":"minerDifficulty()","fe094708":"Map(address,address,uint256,uint256)","fe098371":"findFrozenCell(address,uint128,uint128)","fe0a2c30":"returnArrayBytes1(uint8)","fe0a5ab0":"BLOCKS_BUCKET_SIZE()","fe0ba34e":"placeSellRequest(uint256,uint256,uint256)","fe0c4085":"vestingEnded(address)","fe0d94c1":"execute(uint256)","fe0dadd7":"teamTwoTotalPlayers()","fe0f2fab":"ChangeClaimAddress(address,address)","fe10d836":"setTokensToBeClaimed()","fe110116":"transferToPool()","fe12aeec":"SalesAgentAppointed(address,address)","fe1391ad":"generateFixtures()","fe13a823":"computeResponseFirstHalf(uint16)","fe13b118":"beginDutchAuction(uint256,uint256)","fe13baf7":"_encodeTokenId(int256,int256)","fe1439b4":"setCTO(address)","fe14b085":"walletUserCount()","fe164a5b":"setWhitelistThresholdBalance(uint256)","fe168eef":"_isNoNeedInCountryLimitChange(uint256,uint256,uint256,uint256,uint256,uint256,uint256)","fe16e862":"transactionsOnForHolderUpdate(address,uint256)","fe173b97":"gasPrice()","fe1798a7":"randomAttack()","fe1829b6":"extendPublicSaleDiscountEndTime(uint256)","fe1865cd":"setCompte_26(string)","fe188184":"lastWinner()","fe18d6e6":"convertToEth(uint256)","fe18f82a":"getReceivedFunds(address)","fe192f1e":"parseIntRound(string,uint256)","fe195767":"distributeEPAL(address[])","fe19f495":"VESTING_CLIFF_DURATION()","fe1b0a5c":"setHardCap(address)","fe1b588f":"CoinExchange()","fe1b602a":"getPVPCycles(uint32[])","fe1b6f8f":"getVendorName(address)","fe1bae83":"callforhelp(uint256)","fe1c5aac":"SetParticipantURI(address,address,string)","fe1c91fa":"performWithdrawAccounting(uint256,address)","fe1cdbb8":"Module(address)","fe1ce5d7":"checkOwner(address,address)","fe1d2295":"BankWithdrawal(address,uint256)","fe1d470d":"calculateDiceProfit(uint256,uint256)","fe1da528":"tokensByEurTx(string)","fe1dcbb1":"AuthorizeOperator(address,address,bool)","fe1e079e":"getNumAnimalsXPlayer(address)","fe1ebb04":"augmintReserves()","fe1f06ea":"IQIAN(uint256,string,uint8,string)","fe1f11f1":"getNbits(bytes)","fe1f6a0b":"createGame(bytes32,address)","fe1fd352":"validEmitBuff()","fe211279":"testPrintableToken()","fe213712":"USER_GET_PRIZE()","fe229b61":"_softRequire(bool,bytes32)","fe229f7c":"RecToken()","fe22fcd8":"issuanceLastModified(address)","fe230675":"hasRecord(address)","fe23583d":"fechVoteResultForCandidate(address)","fe23b262":"currentPreICObalance()","fe23baea":"setHashByWriter(address,bytes32,address,bytes32)","fe23c6d1":"BetWon(address,uint256)","fe2450c1":"challengeRewardsPercent()","fe2506a4":"buyFromBal(uint256,uint256,bytes32)","fe2545dc":"purchaseFromVault(uint256)","fe25e00a":"arbiter()","fe26063f":"getTradeAndHash(uint16,address,address)","fe261ab0":"boolToUInt(bool,bool)","fe2622a5":"AgriChainDocuments()","fe2644c6":"creator_fee()","fe26cdeb":"And(bytes32,bytes32)","fe26da0c":"publicGetState()","fe26f16f":"withdrawABIHash()","fe275280":"Silver()","fe277aba":"chAllowAirdrop(bool)","fe280f2b":"roundInfo(uint32,uint32)","fe2830d3":"PausableCrowdsaleImplPaused(uint256,uint256,uint256,address)","fe28d1d8":"CROWD_WAVE2_BONUS()","fe29fc12":"CategoryCapSet(uint256,uint256)","fe2a4e62":"lockAndDistributeTokens(address,uint256,uint256,uint256)","fe2b6246":"updateMaxMinComparables(uint256,uint256,uint256,uint256)","fe2c6198":"price(string)","fe2ca553":"setBalances(uint256,uint256)","fe2cce6f":"PaylessMinisplit()","fe2cec21":"NeobitToken()","fe2d8933":"preIcoInvestors(address)","fe2da970":"getUserByUsername(bytes32)","fe2dac15":"LogNewQuestion(bytes32,address,uint256,string,bytes32,address,uint32,uint32,uint256,uint256)","fe2dc64b":"finalizeProposalVoteResults(bytes32,bytes32)","fe2e306b":"playe2Bid()","fe2e5db4":"SwapyExchange(address,address)","fe2edc1e":"retrieveFinished()","fe2fdf0b":"determineAllocation(address[],uint256[])","fe2ff4cf":"TokenSold(address,uint256)","fe31da3b":"disapproveByB(uint256,string)","fe32a6a7":"pushICO(uint256)","fe32c448":"TokenHolder(address)","fe332a0c":"backDARFtokenOwner()","fe33ada9":"isExistFounder(address)","fe353a5e":"checkWithdrawValueForAddressFX(address,uint256)","fe353d28":"_computeNextGen0Price(uint256)","fe35530c":"setUserWithdrawalAccount(address)","fe35804e":"createLottery(uint256,uint256)","fe37f21a":"changelp17(address)","fe389e09":"removeContract()","fe38ed66":"MarketManager()","fe396c71":"mintEarlySupportersTokens(address,uint256)","fe399121":"referrerEarnings_()","fe3b24b1":"createBBODocument(bytes32,uint256)","fe3c333b":"getActiveJudgmentByParty(address)","fe3c458e":"addContract(bytes32,address,bytes32)","fe3c51df":"getTeamId(string)","fe3c5d80":"becomeSnailmaster()","fe3c6ad4":"addclip(address,string,string,string)","fe3c9b6b":"setIcoEndTime(uint256)","fe3ce632":"lookup(bytes4,bytes)","fe3d002b":"AllocateAngelTokens(address,address,uint256)","fe3d07e4":"decrementInventory(uint256,uint256)","fe3d2236":"Oracle_ChangePeriod()","fe3e0efd":"TestERC20Token(string,string,uint256)","fe3ead72":"interreducemoney(address,uint256)","fe415139":"ProdPublicSale()","fe4170bc":"setDepositLock(bool)","fe417fa5":"claimTokens(address,uint256)","fe41b2da":"setInitialValidators(address[])","fe4215f7":"read_recast_config()","fe4259e3":"isMntpMigrated(address)","fe42cb2d":"setTokenExpectedFee(address,uint256,uint256,address)","fe42da15":"deleted(string,string,address,uint256)","fe435f6b":"getLLV_edit_33()","fe43be3f":"startDestruction()","fe442478":"sendFromContract(address,address,uint256)","fe44a664":"generateWithdrawalHash(string,uint256,address,uint256)","fe44d401":"MoncionToken()","fe4520ad":"_getOwnerTokens(address)","fe45c996":"reVerifiPost(uint256,bool,bool)","fe460201":"getTermsAndConditions()","fe4667e9":"getMaxLossAfterTrade(address,uint256,uint256,int256,int256)","fe47a2ad":"multiRequestAudit(string,uint256,uint256)","fe47a8a7":"totalFunding()","fe47c806":"processFunding(address,uint256,uint256)","fe47d34f":"USC(uint256,string,string)","fe49a9be":"ethGiven(address)","fe49ba1c":"getUnlockIdentifier(uint256,address,address)","fe49dd5f":"halveEntryPrice()","fe49e949":"requestChangeInsuranceFees(uint80,uint80,uint80,uint80,uint256,uint80,uint80,uint256)","fe4a3ac9":"setExecPrice(uint256)","fe4a3e5c":"TokenrateUpd(uint256,uint256)","fe4b84df":"initialize(uint256)","fe4c39fe":"setMaxArenaOneDay(uint256)","fe4c6b08":"_deliverTokens(address,uint256,uint256,uint256)","fe4caa64":"isAborted()","fe4cee66":"numberOfPartitions()","fe4d2a02":"_setupStages()","fe4d62f9":"getMiningKing()","fe4dd8d9":"getTokenApproval(uint256)","fe4e4a84":"exchangeIsRegistered(address)","fe4e6bf9":"queueMint(address,uint256,uint256)","fe4ee216":"transferTips(address,uint256,address,uint256,uint8,bytes32,bytes32)","fe4f7e11":"KangenToken()","fe501c6f":"ChannelSettled(uint256)","fe50cc72":"getGreeting()","fe50ce60":"getBloodlineFromParents(bytes32,bytes32)","fe51717a":"releasePause()","fe51c588":"changeFactoryAdmin(address)","fe52ee70":"setStartingTokensAmount(uint256)","fe530027":"trusteeWithdraw(uint256)","fe536ebe":"setPreferredSaleStartAndEndTime(uint256,uint256)","fe537a82":"upgradeTarget()","fe549815":"pendingTokenBalance()","fe54b5fc":"kyberHash()","fe553250":"adminTransferWorldBalance(uint256)","fe556cf0":"CirculationSupply()","fe55932a":"setName(uint256,string)","fe562ee6":"moveBlockValue(address,uint8,uint8,uint8,uint8,uint256)","fe5675cc":"toNext()","fe56e232":"setManagementFee(uint256)","fe56f5a0":"setEntranceFee(uint256)","fe5709c2":"getSlotWeight(uint256,uint256)","fe5709cd":"createPainting(uint256)","fe575a87":"isBlacklisted(address)","fe5815a6":"hasFinished()","fe58d3a3":"timeLimitEnable()","fe599559":"updateEthToUsdExchangeRate(uint256)","fe5a4e2d":"contractorReleaseFunds(bytes16,address,address,uint256,uint256)","fe5aa8e0":"getUserIndexOnToken(address,address)","fe5ba303":"reservesPerUnitToken()","fe5d5868":"XZBX()","fe5daae6":"_queAmount(uint256)","fe5e1853":"totalBet()","fe5e7e3e":"endICO14()","fe5f1dc4":"PRESALEPLUSCROWDSALE_EVE()","fe5f2e88":"refund(string)","fe5ff154":"recruitHeroFee()","fe602c65":"is_proposal_supported()","fe60d12c":"reserved()","fe60ed81":"changeUserGroup(address,uint256)","fe6129d5":"setPromoBonus(address,uint256)","fe61303b":"createGuardianSale(uint256,uint256,uint256,uint256,uint256,uint256)","fe6214c4":"LDTCrowdsale()","fe62a0a6":"transferFromPretgefund(address,uint256)","fe63300a":"registerExternalBill(uint256,address,address,uint256,uint256,uint256)","fe637e5e":"getScoreChange(int256,int256)","fe63d701":"removeQueueElement(uint256)","fe647394":"setTeamProfitAddress(address)","fe64d6ff":"changeAddress(address)","fe65066e":"setUsdMnr(uint256)","fe65bb65":"cashHistory()","fe669c26":"addPhase(uint256,uint256,uint256,uint256)","fe675deb":"Exchange(address,address,address,address,bytes32,uint256,address)","fe675f13":"toggleFieldActivation(string)","fe67a189":"finalizedTime()","fe67a54b":"endAuction()","fe687b2b":"teamc()","fe68b528":"getExchangeInformation(address)","fe68e285":"toNextStage()","fe68f73b":"getTargetBudget(uint256,uint256)","fe69c926":"onFrozenToken(address,uint256,uint256)","fe69dacd":"validDraws(address,uint256,uint256[])","fe6a0cd6":"hasNextSeedHashB()","fe6ad6c6":"isNotarized(bytes32)","fe6bca8f":"AllTest7()","fe6c19a4":"HelixexToken()","fe6cf9ee":"Krypticion()","fe6d4305":"ALC_DECIMALS()","fe6dcdba":"top()","fe6e0441":"minimalWeiTLP1()","fe6f0d82":"testConstructorEvent()","fe6f1b05":"percentDivider()","fe6f2a60":"matches(bytes32,bytes32)","fe6fef44":"setTokenQuota(uint256)","fe7009f2":"getSupplier(address)","fe704c1f":"RWQToken(uint256)","fe70a123":"KilledTokens(address)","fe70f417":"getNewForkReputationGoal()","fe71aec5":"LittleCactus()","fe71be6e":"monarchToken()","fe72277d":"addHashType(bytes32)","fe7279b1":"setTokenTransferFeeReceiver(address,address,address,address)","fe72ac7f":"newPrice(uint256)","fe72e717":"toDie(bytes)","fe72f3be":"addMember(string,string,string,uint256,string,string,uint256,string)","fe73bf21":"developer_edit_text_Exchanges_links(string)","fe73e3ec":"preliminaryGameResult(uint64)","fe73f74c":"withdrawTokenFromTAR(address,uint256)","fe742c6a":"millionInCents()","fe74f05b":"assertEq(int256,int256)","fe757fb5":"lastClaimPrice()","fe758a1e":"_timelimitCal(address)","fe75dff6":"GcoinProto()","fe75ff54":"runLottery(uint256)","fe76fbe3":"setStageOpeningTime(uint8,uint32)","fe777bcd":"etherForSale()","fe77adda":"reloadTickets(uint256,uint256,uint256)","fe77f5e5":"getCostToNextLevel(uint256)","fe7805f2":"MultiSigWallet()","fe786c5f":"prependUnderscore(string)","fe79bfd0":"giftCode(string,address)","fe7baf8e":"RemoveAuthorityAddress(address)","fe7bf05e":"deathData_v6()","fe7ccb79":"CCN()","fe7cd999":"registerForICO(address[],uint8)","fe7d1587":"canCall(address,address,address,address,bytes4)","fe7d8740":"getFreelancerContracts(address,uint256[],uint256[])","fe7e187f":"add_kycer(address)","fe7eba06":"getCurrencyLength(uint256)","fe7f0d14":"DST_BOUNTY()","fe800489":"totalUnitsLeft()","fe802d7f":"isMHTHolder(address)","fe8190ce":"test_v1()","fe8252f3":"withdrawlEnabled()","fe830334":"initToken(string,string,uint8,address,uint256,bool)","fe8311db":"sendLimitTokensToPartner(uint256)","fe8312c1":"validateWallet(address,bool,string)","fe836931":"freezeAmount()","fe8370bb":"NinjaCoin()","fe84bff5":"getTransferValue(uint256)","fe84c5ec":"fixedExpUnsafe(uint256,uint8)","fe853650":"getRandomHashesLength()","fe856722":"gasPrc()","fe859472":"PractiParlezToken()","fe86338c":"cancelOrderList(bytes32[],uint64[])","fe86de13":"testTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address,bool)","fe8705d5":"throwOnIncompatibleContract()","fe87ee28":"endRC()","fe8806f5":"removeRequest(address,address)","fe882fe2":"getValueAndBox(address)","fe88fc00":"balancsHolder(address)","fe892327":"DML_TOTAL_SUPPLY()","fe8925f4":"interestFeePercent()","fe89a6c1":"MAX_ALLOWED_STAGE_1()","fe8a7458":"_isLowercaseLetter(bytes1)","fe8b2707":"depositedEtherGeneric(address,bytes4,address)","fe8b6642":"setEnforceRevisions(bytes32)","fe8beb71":"getVersionFor(address)","fe8cbe18":"LogBidWithdrawn(address,uint256,uint256)","fe8d640c":"setifoodCommunityAddress(address)","fe8d8c77":"setShouldGateGuard(bool)","fe8e6a63":"quarryCities(uint256)","fe8e992f":"unpackAllocation(bytes32)","fe8f4763":"ROYBOITokenIToken()","fe8f4bbe":"freedWinPoolToWinSystem()","fe8fb49f":"setLastMaxInvestments(uint256)","fe908b7a":"pay(bytes32,address,address,uint256,uint256,bytes)","fe90f3df":"WPAYCoin()","fe91d37f":"semanticVersionHash(uint16[3])","fe92049d":"submitAnswerByArbitrator(bytes32,bytes32,address)","fe925e80":"createLoan(address,address,address,uint256,string,uint256,uint256,uint256,uint256,uint256,uint256)","fe937fa4":"setEndMintDate(uint256)","fe949159":"sendMessageToChannel(string,string)","fe94e504":"setColor(uint8,string)","fe95112c":"faythe()","fe95a5ce":"hat()","fe95cbdd":"getAgentsWithService(uint256)","fe95ec9c":"popcnt32(uint32)","fe968ade":"putStcWithBto(uint256,uint256,bytes32,uint256,uint256,uint256,uint256,bytes32,bytes32,uint8)","fe972054":"create(string,string,uint8,uint256,address,uint256,uint256,uint256)","fe972f11":"_toMill(uint256)","fe97bcf4":"RandomNumberGenerated(uint256,uint8)","fe97e481":"maxCap_MInt()","fe97ee88":"hasPhone(address)","fe98184d":"trustedUniverseTransfer(address,address,uint256)","fe985cb9":"buyin(address)","fe98f1d1":"testCantFinalizeIfNotMultisig()","fe99049a":"transferFrom(address,address,uint256,uint256)","fe992c98":"balanceOfAll(address)","fe996956":"PMET(uint256,string,string)","fe9a3664":"supportList(address)","fe9b7f2f":"maxAmountETH()","fe9bb2da":"setCSCFactoryERC721(address)","fe9bf404":"createManager(address,address)","fe9c3c28":"purchaseHalted()","fe9cc7f4":"VebEX()","fe9ccc1e":"maxBetWei()","fe9d2828":"getPI_edit_11()","fe9d7121":"StorageEther(address,address,address[],uint256,string,string,uint8)","fe9d744d":"buyBulkRegularCar(address,uint256[],address)","fe9d9303":"burn(uint256,bytes)","fe9e1c0f":"buyTokens_Vault(address,uint256,bytes8)","fe9fa16f":"testThrowExecuteSellOrderTwice()","fe9fab4d":"setPrices(string)","fe9fbb80":"isAuthorized(address)","fea1377d":"USD_HARD_CAP()","fea22ae4":"newMinimumTokens(uint256)","fea277dc":"withdrawERC721(address,uint256,address,address)","fea2920e":"createNewDraw()","fea45621":"changeTotsupp(uint256)","fea5d7b1":"mgmtIssueBountyToken(address,uint256)","fea5d9e0":"lengthEqual(uint256[],uint256,string)","fea708f6":"totalPeriods()","fea78df4":"buyGold(uint256,uint256,uint8,bytes32,bytes32)","fea7bcfb":"additional(uint256)","fea8ae97":"MakerWithdrewERC20Token(address,uint256)","fea9b572":"MAX_NUMBER()","feaa29d8":"insertProfitHere()","feaa4cf3":"updateIntention(uint256,string,string,string)","feaaa476":"BurnToken(address[])","feac36d7":"insert(bytes32,bytes32)","feaceab4":"addPayment(string,address,string,uint256,uint256)","fead0097":"setTotalUnvestedAndUnreleasedTokens(address,uint256)","feadce9c":"servicePause()","feadfdbd":"getTimeFromPrize()","feaea586":"recoverToken(address,address)","feaed589":"releasedMarketingTokens()","feaf0872":"getTokenTransferCount()","feaf1fe1":"registerToBlacklist(address)","feaf653d":"sendEth(address[],uint256)","feafb79b":"foundationAddr()","feb03fe1":"_handleProductionIncrease(address,uint256)","feb088ab":"openingTimePeriodTwo()","feb2432a":"addMediator(address)","feb272e4":"noDuplicates(bytes)","feb27ac9":"Proof_of_Tacos()","feb2a20c":"apiAccessDisabled()","feb31939":"attack(address,uint256,uint256[])","feb371cd":"VUP_TOKEN_SUPPLY_TIER2()","feb4ad89":"addEarlyPurchases()","feb4c708":"nextIdentityAccount()","feb50430":"getLevitatingKittens(bytes32,uint64)","feb5d106":"getBPCount()","feb7267b":"deleteMintable(address)","feb7d2fb":"KoniosToken(uint256,string,string)","feb80ee4":"stakeFromTokenContract(address,uint256)","feb99390":"add(uint128,uint128)","feba95fb":"purchaseFor(uint128,address)","febb0f7e":"bar()","febb1315":"gasLimitInWei()","febb5407":"currentLiquidity(address)","febc14b1":"roundCounter()","febc2980":"calculateWinnersCount(uint256)","febc8c39":"feeAffiliate()","febc9dec":"stringEquals(string,string)","febdb9b8":"rewardWinner()","febe4909":"approve(uint256,address)","febe8129":"destrcut()","febec059":"GetCurrentTypeSaleCount(uint256)","febefd61":"startAuctionsAndBid(bytes32[],bytes32)","fec07cb2":"calculateTally(address,uint256)","fec0cc19":"setIcoPhase4(uint256,uint256)","fec1aa12":"codetokenIndexToApproved(uint256)","fec1c41f":"AddNewBooster(uint256,int256,uint256,uint256,uint256,uint256,uint256)","fec2e27b":"acceptManagement(string)","fec320f4":"ListPairsForReserve(address,address,address,bool)","fec35182":"Crowdsale(address,uint256,uint256,uint256,uint256,address,address)","fec3e941":"MintAndTransferIAC(address,uint256,bytes32)","fec3fbe2":"functionTwo(uint256,uint256,uint256,uint256)","fec5438c":"costToCallOraclizeInWei()","fec568d4":"TransactionCompleted(uint128,uint256,uint256,string)","fec5c5f7":"FINX2Token()","fec5d3b0":"BTCRate()","fec69a87":"OneStandardToken(uint256,string,uint8,string)","fec6c66e":"applyFromCertificate(string,string,string,uint256)","fec74d31":"eolBlockNumber()","fec7c0a2":"FRPRUPEES()","fec7fc8e":"isSigned(bytes16,address)","fec84aac":"LogUserAddedToWhiteList(address)","fec8db83":"C3_TokenCreate(uint256,string,string)","fec966df":"countSmartSharingContract()","fec97c03":"finishFundraiser(uint256)","fec9cd77":"allowanceToBurn(address,address)","fec9dc1f":"updateNewToken(address,address)","fecab4bf":"vreoSaleOngoing()","fecadafd":"pushAtom(uint64,uint8,uint8,uint8,uint32,uint64,uint64,uint128,uint128,uint32)","fecc36c0":"fun(int256)","fecca5a5":"checkMyDonation()","fecd3486":"getTulip(uint256)","fecd817c":"cancelBuy()","fece5543":"mock_remove(address,address)","fecf9959":"withdrawTokens(uint256,address,uint256)","fed03118":"getTDETokenExchangeRate(uint256)","fed0827e":"RoseCoin()","fed09b2f":"isFemaleSale()","fed0b877":"distributeAirdropMulti(address[],uint256[])","fed0d2a1":"sellMultiplier()","fed1c977":"blockTransfering()","fed1cec2":"addWinners(uint256)","fed2063c":"mintDataStream(address,uint256,bytes32,bytes32,uint256)","fed23223":"sellFirst(uint256)","fed26772":"zeroFeeTransferByowner(address,address,uint256)","fed39929":"productOwner(string)","fed3a300":"right89(uint256)","fed3b141":"Coinbase(uint256)","fed3f18d":"admin_inactive_withdraw(address)","fed4614b":"funeral(bytes,int256)","fed4de76":"addAuthorizeRole(string,string,string)","fed503cd":"transferCoinInStages(address,address,uint256,uint256)","fed73b54":"getPlayerIdOfIndex(uint256,uint256)","fed7bb07":"getSeedAmountForGameId(uint256)","fed82ef3":"setSanityBounds(uint256)","fed8a53b":"callbackInsertApproveAndDistribute(uint256,address[],uint256[])","fed8b30a":"canSettleOrder(uint256,uint256)","fed8f40f":"invalidateMail(uint256)","fed9981e":"setDemocAdminEmergency(bytes32,address)","fed9d44f":"ARBITRARY_VALUATION_IN_ETH()","feda1045":"slaveWallet()","feda38bc":"setCrowdsaleOpen(bool)","fedabacf":"claimPrepaid(uint256,uint256,uint256,string,uint256)","fedb6dfd":"TACTICALCRUISER_FTL_SPEED()","fedbceba":"getRankLandLimit(uint256)","fedc2a28":"_rewardWinners(string,uint8,address[])","fedce093":"TheNextBlock()","fedda73b":"HC8ICO()","fedda89c":"claimVesting()","feddb41c":"peculOld()","fede04c3":"reject(uint32,int256)","fede5cc6":"issueInternal(address,uint256,bool)","fedeac70":"handleQuickCloseChannel(address,bytes32,address,uint256,address,uint256,uint256)","fedf1ed8":"getCompte_21()","fedfd535":"Config()","fedfe46c":"vote(address,uint256,uint256,uint256)","fedffec0":"currentReferralPercent()","fee01177":"getTopics()","fee0596f":"createContractCompany(string)","fee13823":"ChargeTreasure()","fee1396b":"registerNewRecord(bytes32)","fee160be":"CarFare(uint16,uint16)","fee16841":"showDeposit(address)","fee21471":"getDayIndex_(uint256)","fee24454":"sendNowLastCount()","fee2cb05":"R2()","fee3154c":"setTransferWhitelist(address,address,bool)","fee35ff8":"newInvest(uint256,address,uint256)","fee4f84d":"CryptopusToken()","fee692a3":"getAutomatedReportDisputeDueTimestamp()","fee6d28c":"addSnapshot(string)","fee7e35d":"tokenURISafe(uint256)","fee8775b":"Ping(address)","fee87e3b":"addresstoBytes(address)","fee99898":"getFee(address,address)","fee99e93":"HPAToken(uint256,string,uint8,string)","fee9aa44":"calculateRewardForAddress(address,address)","fee9ca13":"continueSale()","feea01b9":"create(bytes16,uint64,bytes)","feea799b":"rejectTransaction(uint256,bytes)","feec6fc1":"Tegchain(uint256,string,string)","feec756c":"updateRecipient(address)","feec7680":"changeFeesAddress(address)","feed5561":"getContributorsCount()","feed58ff":"setBackgroundColors(bytes3[])","feeda367":"addMarketTo()","feee8139":"setColors(uint32[],uint8[])","feefee1b":"firstExchangeRatePeriod()","fef038e8":"piggyBank(address)","fef10b95":"poolReward()","fef1dc7d":"seekerValue()","fef28cac":"Yudhacoin()","fef2cc97":"getPreAuthorizedAmount(address,address)","fef47e38":"CREATE_NAME_ROLE()","fef4b969":"refundFromSeveral(uint256,address[])","fef5ae43":"enterCurrentRound()","fef5b185":"updateUserEducation(string,uint256,string,uint16)","fef5f1e7":"validateRequestParams(address[4],address,uint256[12],uint256,bytes,uint256)","fef636a8":"stage2Start()","fef64e37":"packedToStartTime(uint256)","fef7d5a8":"findEmptyBenefactorIndex()","fef8383e":"gameOpponent()","fef88502":"hommie()","fef9b5ae":"changeminpublicsale(uint256)","fef9cfe1":"setAvailableAfterStart(uint256)","fefa69a0":"batchCancelOrders()","fefa7d1c":"isLockup(address)","fefa7e41":"countDrugs()","fefa9bb1":"addReferrer(address)","fefaa293":"reservedTokensTeam()","fefaa626":"gameFinishedTime()","fefacee1":"MediatorFees()","fefb130e":"srb(uint256)","fefb8dc3":"publishPost(string,string)","fefb94a5":"PFAToken()","fefba6dd":"transferAnyERC223Token(address,uint256)","fefc38fd":"startActivated()","fefc7089":"AVAILABLE_RESERVE_SUPPLY()","fefc8b41":"test_insert_findWithHintNotTightBound()","fefd336c":"getSettingValues()","fefd41b9":"balanceOfRick(address)","fefd51b2":"getBrick(uint256)","fefd6e9a":"allocateEqual(address[],uint256)","feff0506":"addListing(string,string,uint256,address)","feffd402":"fetchVoteMainInfo()","ff00c592":"setNumRewardsAvailableForAddress(uint256,address)","ff01f11a":"finalUnpaused()","ff01ff08":"setGameVars(uint256,uint256,uint256,uint256,uint256)","ff01ffa8":"refundCrowdsaleContributor()","ff02326f":"MoonDustDividends()","ff025819":"numberOfActiveProposals(bytes32)","ff026158":"setSale(uint256,address)","ff044add":"oldCratesSold()","ff056949":"decreaseBalance(address,uint256)","ff05a9f0":"giftPlot(uint256,uint256,address)","ff05edd8":"inflateSupply(uint256)","ff069b4c":"getPetbyTileId(uint16,uint8)","ff06bb57":"setEthInCents(uint256)","ff07061b":"LUC()","ff08d2b0":"PayMiners()","ff09068f":"SMRTCoin()","ff0935b1":"checkFeeSchedule(address)","ff0938a7":"isPause()","ff097659":"getServerInfo(uint256)","ff09ff99":"purchaseCity(uint256)","ff0a22db":"_shareProfit(uint256,uint256,address)","ff0b3fc5":"intervalLength()","ff0b9c90":"createCheckpoint()","ff0bfc91":"mayGenerateAddr()","ff0c5a4b":"ContributionReceived(bytes32,address,address,uint256,uint256)","ff0cd868":"ShareEstateToken()","ff0ec23e":"setEditionName(uint8,string)","ff0efd6c":"submitDistance(uint256[])","ff0f27de":"setIDChain(address,address)","ff0f2e80":"getNumOrdersByPayee()","ff0f2f71":"setTTCAddress(address)","ff102896":"tokenRedemption(address,string)","ff10dc66":"quickTrade(address,address,uint256)","ff11e1db":"collectEther()","ff12128a":"step(int256,bool)","ff125c8a":"transferAllowed(address,address,uint256)","ff13c6c6":"RefundLoaded(uint256)","ff1401cc":"OdinCoin(address)","ff163aca":"AcquinomToken(address)","ff176844":"ThanosXToken()","ff1780ec":"rescueToken(address[],uint256[])","ff178834":"testApproveWillModifyAllowance()","ff17bc98":"burnOwnerTokens()","ff184b5d":"EthPerToken()","ff18539b":"setDepositCreator(address)","ff186b2e":"ethPrice()","ff190061":"balanceOfActiveToken(address)","ff192bc8":"isFreeze(address)","ff197bc3":"presaleTokenSold()","ff1ad781":"deadbids(address)","ff1ad7fa":"claimRewardBy(address,uint256,string)","ff1b01a6":"bet1000(uint256)","ff1b4341":"easyPropose(address,uint256,uint256)","ff1b636d":"Admin()","ff1c52d8":"Queue(bytes32,bytes32,bool,bytes32,address)","ff1c559e":"ChampionGameFinished(uint256,address,uint256,uint256)","ff1ca005":"supportComponent(uint16,uint256)","ff1d20b5":"getSecondStageWallet()","ff1d2712":"versionIndex()","ff1d83ae":"getTokenGranteesLength()","ff1d91b4":"ccStartTime()","ff1d9dd4":"updatePoolContract(address)","ff1e28a4":"createStamp(address,uint256)","ff1f7046":"requiresAuction(string)","ff1fd974":"getPayAmount(address,address,uint256)","ff2073d7":"fundRaiser()","ff208fa5":"test_insert_findWithHintNextAtPosition(int256)","ff213498":"FlowingHair()","ff21984a":"testMintAuth(int256)","ff21f27f":"issueToken(uint256,uint256,uint256,uint256)","ff22028b":"requireOwnerUnlockedAmount(uint256)","ff2258cb":"diffYears(uint256,uint256)","ff2263b7":"firstRoundStartTimestamp()","ff2311a4":"GetPatient()","ff238839":"showDelegateMsgSender(address)","ff23c7f2":"createArtefact(uint256,string,uint256,uint256,uint256)","ff23e1eb":"ShalloToken()","ff249bb0":"getTokenPacksAvailable()","ff25af24":"migrateAccount(bytes32,bytes32,uint256,uint256,address)","ff25e16d":"getLogErrorArguments()","ff25f859":"KIN_FOUNDATION_ADDRESS()","ff262ea5":"construct(uint256)","ff266d26":"reopen(address)","ff272ad4":"__toDecimals(uint256)","ff27848a":"GoldToken(address)","ff27c476":"shiftBitsRight(bytes,uint256)","ff27cbda":"getPI_edit_4()","ff28bcc2":"increaseReward()","ff28cdaf":"WCT(address)","ff28d625":"releaseEarning(bytes32,bytes32,bytes32,bool,address,address)","ff29507d":"fundingStopBlock()","ff299a63":"BTCUToken(uint256,string,uint8,string)","ff29bc95":"assignBalance(address,uint256,uint256)","ff29c104":"getTotalLeaderboards()","ff2a3776":"claimAllUnsold()","ff2b0571":"doFreeExtension(bytes32)","ff2b247f":"addNewTicket(uint256,bytes32,uint256,uint256,uint256)","ff2b350d":"acceptGiftTokens(address)","ff2d4b71":"addDoctor(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint32,uint32)","ff2eff94":"Cow()","ff2f7a35":"getDeed(bytes32)","ff30feef":"walletTranslate()","ff31e930":"prizePoolAddress()","ff31f9e6":"getSecurityDepositRegistry()","ff332ab7":"getTokenDetails()","ff34ef7d":"PrimaToken()","ff359cb8":"RATE_SALESTAGE2()","ff36cf59":"contributeETH(address)","ff377705":"getNumEntries(address,address,uint256)","ff37839b":"getTxt(uint256)","ff37d31d":"escrowDeed(uint64)","ff394153":"transferEthersToDividendManager(uint256)","ff39ae55":"EthereumExtreme()","ff3a5eea":"isIco()","ff3a91d9":"getOwnerPicture(bytes32)","ff3adc83":"GazeCoinCrowdsale()","ff3af97f":"setBonusToken(address,uint256,uint256,uint256,address,uint256,uint256,uint256)","ff3bf1f4":"sitePercent_()","ff3c1a8f":"getTitle()","ff3c9472":"adduser(string,string,address)","ff3d1be0":"stopPreIco_step1()","ff3d398c":"buyTokensByAtes(address,uint256,string)","ff3e51c8":"ZULICC()","ff3e8ba1":"_transferDirect(uint256,uint256,uint256,bytes32)","ff3ef460":"_userOwnsToken(address,uint256)","ff3f427c":"createMobsterWithOwner(string,address,uint256,uint256,uint256,string)","ff3fb765":"testUpdateCase()","ff40807b":"getAccumulator()","ff40fcf6":"buyBBC(address)","ff41f5cc":"HUT34_RETAIN()","ff423357":"withdrawAmount(uint256,address)","ff429fc8":"getCooldown(uint16)","ff42fd41":"getTotalLockedAmounts(address)","ff4329ee":"receiveCashback(address)","ff4408ee":"stopCrowding()","ff46f210":"isUnfrozenAccount(address)","ff470507":"VaultbankVotingToken()","ff48fd9c":"mintGreen(address,uint256)","ff49b26e":"createEvent(uint256,uint256,uint8,uint32,address,uint256,uint8)","ff49b8ef":"KyberWhiteList(address)","ff4a6638":"followTrader(bytes,address,bytes32,uint256,address,uint256)","ff4a7a7c":"Blin()","ff4ab29c":"setMarketFees(uint256)","ff4b6fea":"_shiftLeft(bytes32,uint256)","ff4bd173":"dealBuyContract(uint256,uint256,string,uint256,uint256,string)","ff4bf170":"TechieCoin()","ff4c9fa5":"getCurrentPriceForToken(uint256)","ff4cfa5e":"onSignUp(string,uint256)","ff4d7404":"sell(uint8,string,uint256,uint256,uint32)","ff4dddc4":"tokensInWeiSold()","ff4ea29e":"migrateTokens(address[])","ff4f03a9":"developeo()","ff507efa":"Consulteth(uint256,uint256)","ff508d76":"renderWeb()","ff50abdc":"totalDeposited()","ff50fcb6":"usedIcoSupply()","ff510ad8":"isOnTrade(uint256)","ff51d18c":"getFlightConnections(uint16)","ff523cb2":"oraclizeQueryGas(uint256)","ff53c5a3":"refundInvestor(address)","ff552482":"GennovaToken()","ff556ecb":"releaseUnicorn(uint256)","ff55da1c":"assertOnlySpecifiedCaller(address,bytes32)","ff55e2ee":"setCasinoAddress(address)","ff5639c4":"optInFromClassic()","ff56b59a":"start6Phase2025()","ff56b65a":"getTxPaymentKWh(bytes32)","ff5732a5":"calculateTokenGet(uint256,uint256,uint256,bool,bytes32)","ff574213":"YeekFormula()","ff584597":"setGameResult(bytes32,int256,int256)","ff585caf":"callback(uint256)","ff592125":"issuedNum()","ff596069":"computeAddressBonus(uint16)","ff597790":"getSold(uint256)","ff598a06":"betTotalGasprice_()","ff59f3cc":"theCyberGatekeeper()","ff5a478b":"finalizeTge()","ff5b98b8":"setAvgReportingGasPrice(uint256)","ff5bc8a7":"getSaleContractTokensLimit(address)","ff5ce378":"_addTokenTo(address,uint256)","ff5d2c39":"to62Encoding(uint256,uint256)","ff5de44b":"getStockBalance(address,address,uint256)","ff5e51b3":"VTOSToken(uint256,string,string)","ff5e7d4d":"lockedFundsSeconds()","ff5f1346":"forSell()","ff5f8b4b":"takeOwnership(uint256,address)","ff5fcf01":"initializeNewSale(uint256,uint256,address,address)","ff5feb3e":"getVoterVotesCount(address)","ff5ff81f":"LastWillContractOraclize(address,address[],uint8[],uint256)","ff600081":"getValuePerMicroKey()","ff60af84":"setNewMinDeposite(uint256)","ff60cdf6":"get1TokenSellPrice()","ff615b87":"SECOND_PHASE_PRICE_FACTOR()","ff61ad09":"getRoomBalance(uint256)","ff62d2cf":"rewardAdjustmentPeriod()","ff630748":"setStepLimits(uint256,uint256)","ff6307f8":"angelFoundationShareDenominator()","ff6387ad":"setconfigurationTokenPrice(uint256)","ff6395a4":"assigned_bids()","ff63ac3b":"_getTime()","ff6417c1":"paidAddress(uint256)","ff6477be":"getScam(uint256)","ff64d469":"weR()","ff65226c":"canBuy()","ff655320":"withdrawFirst()","ff65e44a":"purchaseBronze()","ff668cbe":"donacionTeleton()","ff66a305":"setBountyManager(address)","ff67577a":"Appoint_Mediator(uint256)","ff67c9f5":"getRequirementTime(address)","ff6867c0":"startAndSetStopTime(uint256)","ff69ac36":"currentTokenAmount()","ff69e2bc":"CurrentPrice()","ff69f35e":"CryptoEmojis()","ff6a6df7":"MultiValidator()","ff6c33e6":"TOKEN_OWNER()","ff6c8b87":"MPGame(uint8)","ff6d24b1":"SedPOWToken()","ff6d6f63":"BCTToken(uint256,string,string)","ff6f0d54":"TipSmart()","ff6f2914":"foundersRewardsAccount()","ff7070eb":"_processIncomingEther(address,uint256)","ff70bd9c":"PirateNinjaCoin(string,uint8,string,uint256,uint256)","ff70c4d1":"getBuyerAddress(uint16,uint16)","ff70e8d9":"STAKE_MULTIPLIER()","ff70fa49":"setDeveloper(address)","ff71c6b0":"WALLET_T8EX_COMMUNITY()","ff722b08":"getSkillTypeCnt()","ff72c845":"bat()","ff739e40":"minEnterFee()","ff73d2d8":"getIsRevenuePaid(address,uint256)","ff74927b":"strConcat(string,string)","ff74c0b8":"subTotalInvoiced(address,uint256,uint256)","ff74e915":"NewContent(string)","ff75567b":"participant2SentEtherCount()","ff757d59":"kittenContract()","ff776f55":"regist(address)","ff77898a":"numberOfContractors()","ff7835bf":"SmartCoinCash()","ff78461c":"initSilver()","ff786f2d":"LogTradeError(address,address,uint256,uint256,uint16)","ff7885e8":"withdraw(address,address,address)","ff78d5ed":"mdtComparable()","ff78e48b":"setIsParentOf(bool)","ff79d600":"BATAGOR()","ff7b5730":"getSCF()","ff7c9329":"setMintingCompleted()","ff7c977f":"admin_dividend(int256,int256)","ff7e17b6":"endTimeTLP1()","ff7e5abd":"vestingIsCompleted(address,uint256)","ff7f5f2a":"EtherizationUtils2()","ff8028b3":"megaCandyToken()","ff80b69a":"minPresaleAmount()","ff81c554":"coinMinted()","ff81fb91":"unhint(int256,bytes32)","ff82b174":"getUserBigPromoBonus(address,address)","ff83ce17":"ManagerSet(address,bool)","ff83f562":"acceptOwnership(string)","ff840553":"roundid()","ff8489df":"tokensForFinalize()","ff848eaf":"newDeal(uint256,uint256,uint256,uint256)","ff84990c":"MRDSCoinToken()","ff84d49f":"setMiniPoolEdit_3(string)","ff84ed36":"Identity(address,address)","ff855ac3":"withdrawTokens1(uint256)","ff85bd39":"Free()","ff85fba2":"forceStart()","ff862839":"modifyairdrop(uint256)","ff8872c2":"accountEthAmount(address)","ff895a62":"deActivate()","ff897dbd":"updateMinAmount(uint256)","ff89a720":"ECCToken(uint256,string,string)","ff8bfffc":"sendEthTweet(uint256,bool,string,bool,string,string,string)","ff8cffc1":"returnBorrowerPaidLate(uint256)","ff8ed0f7":"Map(address,uint256)","ff8ee507":"EthernalLoveParent()","ff8f7551":"FINCO()","ff8f9b9f":"LOL10()","ff8f9de7":"BuyRTCtokens()","ff8fa0dd":"transferFromWithData(address,address,uint256,bytes32)","ff8fec7f":"setHashByProvider(bytes32,bytes32)","ff9151dd":"retrait_4()","ff91b949":"nonPublicSupply()","ff91bb45":"castVote(address,uint256)","ff92eb2c":"selleth(uint256)","ff938f4a":"addClientAuthority(address)","ff93a512":"createEvent(uint256,uint256,uint256,uint256,uint256,uint256,address[])","ff947525":"isShutDown()","ff94e502":"getIdByIndex(uint256)","ff950e90":"batchSpawnAsset(address[],uint256[],uint256[],uint256)","ff95a8d2":"grantFounderTeamToken()","ff96b467":"setLockup_contributors(address,uint256,uint256)","ff97278f":"_timeLimit(uint256)","ff981099":"getVotes(uint256)","ff9852bf":"balanceOwed(address)","ff989a0d":"safeDecrement(uint256,uint256)","ff9913e8":"allow(address)","ff992ef5":"addInvestorList(address,uint256)","ff993272":"bonus10end()","ff993a18":"ChangeBuyRate(uint256)","ff9a6773":"DexToken(address,address,address,uint256,uint256,uint256)","ff9b3acf":"house()","ff9c1c5c":"preICODataInitialized()","ff9c8437":"releaseStake(uint256,address,address,uint256)","ff9e1b38":"addUndergraduate(uint32,string,string,string,uint8,uint8,uint8,uint8,uint8,uint16,uint32,uint32)","ff9e3948":"phase_3_remaining_tokens()","ff9e7fe1":"MaxPowerCoin()","ff9f0e5c":"updateToken()","ff9f3055":"generateDna(uint256[])","ff9f633f":"lockedAddresses(address,uint256)","ffa05698":"get_back()","ffa08cb7":"checkPendingWithdrawal()","ffa094fb":"highestBidIsCC()","ffa1ad74":"VERSION()","ffa230b0":"totalCharitySent()","ffa2548a":"LifeSet_008()","ffa2f5c2":"coindropsStatus()","ffa309e4":"currentFiscalYear()","ffa32d1c":"DST_ADVISERS()","ffa34f7c":"isFreezing(address)","ffa39d27":"ElectricCoin()","ffa39d3f":"_isAuthorized(address,bytes4)","ffa40a4c":"pregnantPandas()","ffa49c6a":"expiryEpoch()","ffa61f69":"AllowSuccess(address,address)","ffa640d8":"tradeContract()","ffa651b6":"setEngineerInterface(address)","ffa67f6c":"crowdsaleUnpause()","ffa68839":"initDate()","ffa696d3":"exits(bytes32)","ffa6ae80":"isIdRegistered(bytes16)","ffa72707":"startBuying(uint256)","ffa82f78":"advisorsTokenAmount()","ffa89a00":"permissionToChange(address,address,uint256)","ffa8acde":"StrongHold()","ffa8c44a":"MINSALESCAP()","ffa90f7f":"redeemFrom(address,uint256,bytes,bytes)","ffa97aca":"getInvoice(address,bytes32)","ffaa3608":"voteFor()","ffaa67d4":"deployVesting(address,string,uint256,bool,bool,bool,address)","ffaa9c22":"setAllSupply(uint256)","ffaad6a5":"depositTo(address,uint256)","ffab0959":"backersRedeemed()","ffab3269":"EthRefunded(address,uint256)","ffab7dcd":"setPlayerGeneralDt(uint64,uint32)","ffab984d":"preIcoBuyPrice()","ffacade4":"setFilter(uint256,address)","fface4a3":"rowQuiter()","ffacf300":"doCrowdsaleMinting(address,uint256,int256)","ffad4fc1":"batchLock(address[],uint256)","ffad75eb":"finishICO(bool)","ffae15ba":"e()","ffae2c5b":"getAuthority(uint256)","ffae399e":"shouldRevert(bool)","ffaef25e":"addDataResponse(address,address,string)","ffaf78c2":"_createPiranha(string,address,uint256,uint8,uint256,uint8)","ffaf862f":"getProductWeiRaised(address)","ffb00df1":"TOKENS_LOCKED_2Y_TOTAL()","ffb05c6f":"minRequiredBlockQueueTime()","ffb0885d":"forceTransfer(address,uint256)","ffb171fb":"verifyBalanceProof(address,uint256,bytes)","ffb1a06d":"priceIsStale()","ffb1a6cb":"getWins(address)","ffb24446":"setMaxTicket(uint256)","ffb2c479":"process(uint256)","ffb2d35d":"allowRefund()","ffb308ef":"writeDocument(uint128,uint16,uint256,bytes32[],string,string,string)","ffb31c62":"BetterAuction()","ffb3401d":"SimpleAuction(uint256,address)","ffb38e84":"_setMinter(address,bool)","ffb391fe":"HM(uint256)","ffb40152":"contract_verified()","ffb4c857":"_confirmAndCheck(bytes32)","ffb4e44d":"get_participant(address,address)","ffb54a99":"tradingOpen()","ffb58247":"Ektcoin(uint256,uint256)","ffb5fc2a":"changeDeDeNetwork(address)","ffb747f0":"updateBatches(address,address,uint256)","ffb7bfba":"watchProposal(uint256)","ffb87173":"pixelPrice()","ffb92678":"commFoundAddr()","ffba376c":"unfreezeTokens()","ffbac044":"KickCommitteeFromMapAndArrayEvent(address)","ffbafdfe":"updateState(uint256,uint8)","ffbb62a3":"withdrawCoins()","ffbd26ce":"addReinforcedWhitelist(address[])","ffbd400b":"boolToUInt(bool)","ffbd4dd5":"checkCertificate(string)","ffbd6f72":"splice(uint8[],uint256,uint256)","ffbd73d0":"OSUniEDUSupply()","ffbd8c37":"buyBNNTokens()","ffbfd19e":"accUserReward()","ffbfd38b":"FooStdToken()","ffc0060e":"QingFengCabve(uint256,string,uint8,string)","ffc0483d":"CoreAddress()","ffc0d035":"hgtDecimals()","ffc1b038":"blacklistInvestor(address)","ffc31215":"getStore(string)","ffc3a769":"transfer(address[],uint256[])","ffc3f1f2":"HyperToken()","ffc42904":"MarketContract()","ffc48c61":"buyerAddressTransfer(string,address,address)","ffc4bbb3":"FirstLevelCost()","ffc52a1f":"registerByList(address[],uint256[])","ffc54ea4":"setTokenActive(uint256,bool)","ffc6ff1e":"closeSubmission()","ffc797e4":"setLowerBondPrice(uint256,uint256)","ffc85dc5":"finalizeDeposits()","ffc8bcd7":"getRefToById(address,address,uint256)","ffc8c4cb":"totalConsume()","ffc9152e":"isRefunded(address)","ffc92376":"subEmployerTotalInvoiced(address,address,uint256)","ffc9896b":"getUserData(address)","ffca2968":"ExternalSaleSha3(uint8,bytes32,address,uint256,uint256)","ffcab3e9":"getValidDurationSignatures()","ffcad44e":"getGroupFileCount(string)","ffcb1edb":"getDividendTokenSupply()","ffcb39c2":"tier0(address)","ffcbb5df":"printStats()","ffcc7bbf":"getUserAtIndex(uint256)","ffcc8484":"nextroundERCtradeactive()","ffcce369":"changeIPFSHash(string)","ffcd64e5":"_issueByTranche(bytes32,address,address,uint256,bytes,bytes)","ffcdcb51":"AhooleeTokenPreSale(uint256,uint256,address,address,uint256,uint256,uint256,uint256,uint256)","ffcecf09":"PRE_SALE_START_3()","ffcf1ade":"logPromiseCanceled(uint256)","ffcf21a9":"eventOracles(bytes,uint256)","ffd10e07":"enterPool(address)","ffd19e8c":"isAlreadyProcessed(uint256)","ffd40b56":"allocatorBalance(address)","ffd4185c":"QuantumXICO()","ffd45f16":"calculateTokenCount(uint256,uint256)","ffd479bb":"setBaseInfo(uint256,bool,bool)","ffd48b73":"buyInternal(address,uint256,uint256)","ffd48f40":"setDelegadoDeDistritoVerify(bytes32)","ffd4e0e2":"getTotalIcoTokens()","ffd4e799":"HTJToken()","ffd4f4b2":"withdrawTokensFromContract(uint256)","ffd571ca":"ethersContributed()","ffd68462":"readCheckList(address,uint256,uint256)","ffd6a052":"ChangeAdminWalletAddress(uint256,address)","ffd71e13":"loadCoreAddress(address)","ffd740df":"removeNode(uint256)","ffd7b5e6":"investWithCustomerId(address,string)","ffd85b68":"setControllerDelegate(address)","ffd864d3":"chief()","ffd9ca40":"register(bytes20,uint64,bytes)","ffdaa1b8":"TokenWithdraw(address,uint256,address,uint256)","ffdab909":"removeEntry(uint256)","ffdb0eb3":"getXRateProviderLength()","ffdcf095":"transferWithNarrative(address,uint256,string)","ffdd108b":"addEvent(uint256,string)","ffdd5cf1":"getInfo(address)","ffde0c74":"getGameState(uint256)","ffde8eae":"dismissBunner(address)","ffe0a9f2":"contractSymbolUpdate(string,bool)","ffe0fa66":"CarRegistry()","ffe189ef":"prev(uint80)","ffe280ee":"setWeight(uint256,uint256,bytes)","ffe2d77e":"directorLock()","ffe302d1":"setPlz(string)","ffe34512":"getNumChannels(address)","ffe3acc7":"changeGeneralSaleStartDate(uint256)","ffe3c6fd":"zKill()","ffe45b14":"getHTLCInvalidationTimeoutExtension(uint256,int256,bytes32,bytes32)","ffe48c76":"getBCDTRateForCurrentRound()","ffe4914a":"hdivide(uint256,uint256)","ffe496f2":"setMarginSpend(uint256)","ffe4fe4c":"roundFor(uint256)","ffe55303":"unfreezeCreditScore(uint256,string)","ffe575b1":"Daxther()","ffe57c16":"byuoutActive()","ffe619df":"buyPixelToken(uint24,uint256,uint24)","ffe648d4":"releaseAllOnceLock(address)","ffe6bbd8":"myEarnings()","ffe8ee35":"SetDivTime(uint256)","ffe90ba6":"offsetIndex()","ffe94af0":"burnPass(bytes32,address)","ffe99ca7":"getCitiesStrings(uint256[])","ffea632b":"initialize(address,address,uint8,address)","ffeb7d75":"setUpgradeMaster(address)","ffec34e3":"TokenMintPoD(int256)","ffecf516":"addBot(address)","ffed6ed7":"buyAd(uint8,uint8)","ffeddd49":"addPolicy(bytes32,uint32,uint32,uint256,string)","ffee7c97":"getBookLength()","ffeea273":"withdrawWallet2()","ffeeac82":"info_Name()","ffeecfaa":"Log1(address,bytes32,uint256,string,string,uint256,bytes1)","ffef2b00":"SortCompetitionScores(uint32)","ffef8f88":"Share(uint256)","ffef9b3c":"_checkMaxRoundSupply(uint256)","fff04a87":"test_invalidBalanceNotZero()","fff07241":"playerExist(address)","fff10aba":"getEventsHistory()","fff28137":"reclaimToken()","fff311b1":"ownerSetjackpotContract(address)","fff35670":"icoLaunchTimestamp()","fff3a01b":"transfer(address,string,uint256)","fff3ad33":"getAddTokenDataTracking()","fff3c457":"readMessages(uint256)","fff43b4e":"_setBurnPool(uint256)","fff57ba3":"withdrawSettle(bytes32,bytes32,bytes32)","fff57fe1":"claimableOCDividend(address,address)","fff6a540":"LongBCoin(uint256,string,uint8,string)","fff6fb54":"TTOH()","fff78f9c":"doThrow()","fff7a97e":"addWallet(address,address)","fff83edf":"founderAmounts(uint256)","fff85d49":"addChunk1ToWhiteList()","fff8d42b":"phase2StartingAt()","fff93ec3":"setLandingPage(string)","fff95ce3":"getIsPoop()","fff9627d":"PRESALE_VAULT_START()","fff9d5b9":"confirmProofOfWork(uint256)","fffa932b":"withdrowTo(address)","fffa9d0c":"setGood(bytes32,uint256,uint256)","fffb5183":"initialize(uint256,address,uint256)","fffcde7c":"EOSINT()","fffce84f":"bountyFreeze(address,bool)","fffd52c6":"reading()","fffda870":"lastHorseSex()","fffdbe2c":"frozenTokensSupply()","fffe088d":"saleAddress()","fffeb1ca":"externalCheckSignBool(bytes32,bytes,address)","ffff6b04":"vestingSchedule(address)","ffffce47":"exchangeRateOracle()"} \ No newline at end of file diff --git a/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/abi.go b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/abi.go new file mode 100644 index 00000000..eb531535 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/abi.go @@ -0,0 +1,164 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package fourbyte + +import ( + "bytes" + "encoding/json" + "fmt" + "regexp" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +// decodedCallData is an internal type to represent a method call parsed according +// to an ABI method signature. +type decodedCallData struct { + signature string + name string + inputs []decodedArgument +} + +// decodedArgument is an internal type to represent an argument parsed according +// to an ABI method signature. +type decodedArgument struct { + soltype abi.Argument + value interface{} +} + +// String implements stringer interface, tries to use the underlying value-type +func (arg decodedArgument) String() string { + var value string + switch val := arg.value.(type) { + case fmt.Stringer: + value = val.String() + default: + value = fmt.Sprintf("%v", val) + } + return fmt.Sprintf("%v: %v", arg.soltype.Type.String(), value) +} + +// String implements stringer interface for decodedCallData +func (cd decodedCallData) String() string { + args := make([]string, len(cd.inputs)) + for i, arg := range cd.inputs { + args[i] = arg.String() + } + return fmt.Sprintf("%s(%s)", cd.name, strings.Join(args, ",")) +} + +// verifySelector checks whether the ABI encoded data blob matches the requested +// function signature. +func verifySelector(selector string, calldata []byte) (*decodedCallData, error) { + // Parse the selector into an ABI JSON spec + abidata, err := parseSelector(selector) + if err != nil { + return nil, err + } + // Parse the call data according to the requested selector + return parseCallData(calldata, string(abidata)) +} + +// selectorRegexp is used to validate that a 4byte database selector corresponds +// to a valid ABI function declaration. +// +// Note, although uppercase letters are not part of the ABI spec, this regexp +// still accepts it as the general format is valid. It will be rejected later +// by the type checker. +var selectorRegexp = regexp.MustCompile(`^([^\)]+)\(([A-Za-z0-9,\[\]]*)\)`) + +// parseSelector converts a method selector into an ABI JSON spec. The returned +// data is a valid JSON string which can be consumed by the standard abi package. +func parseSelector(selector string) ([]byte, error) { + // Define a tiny fake ABI struct for JSON marshalling + type fakeArg struct { + Type string `json:"type"` + } + type fakeABI struct { + Name string `json:"name"` + Type string `json:"type"` + Inputs []fakeArg `json:"inputs"` + } + // Validate the selector and extract it's components + groups := selectorRegexp.FindStringSubmatch(selector) + if len(groups) != 3 { + return nil, fmt.Errorf("invalid selector %s (%v matches)", selector, len(groups)) + } + name := groups[1] + args := groups[2] + + // Reassemble the fake ABI and constuct the JSON + arguments := make([]fakeArg, 0) + if len(args) > 0 { + for _, arg := range strings.Split(args, ",") { + arguments = append(arguments, fakeArg{arg}) + } + } + return json.Marshal([]fakeABI{{name, "function", arguments}}) +} + +// parseCallData matches the provided call data against the ABI definition and +// returns a struct containing the actual go-typed values. +func parseCallData(calldata []byte, abidata string) (*decodedCallData, error) { + // Validate the call data that it has the 4byte prefix and the rest divisible by 32 bytes + if len(calldata) < 4 { + return nil, fmt.Errorf("invalid call data, incomplete method signature (%d bytes < 4)", len(calldata)) + } + sigdata := calldata[:4] + + argdata := calldata[4:] + if len(argdata)%32 != 0 { + return nil, fmt.Errorf("invalid call data; length should be a multiple of 32 bytes (was %d)", len(argdata)) + } + // Validate the called method and upack the call data accordingly + abispec, err := abi.JSON(strings.NewReader(abidata)) + if err != nil { + return nil, fmt.Errorf("invalid method signature (%s): %v", abidata, err) + } + method, err := abispec.MethodById(sigdata) + if err != nil { + return nil, err + } + values, err := method.Inputs.UnpackValues(argdata) + if err != nil { + return nil, err + } + // Everything valid, assemble the call infos for the signer + decoded := decodedCallData{signature: method.Sig(), name: method.Name} + for i := 0; i < len(method.Inputs); i++ { + decoded.inputs = append(decoded.inputs, decodedArgument{ + soltype: method.Inputs[i], + value: values[i], + }) + } + // We're finished decoding the data. At this point, we encode the decoded data + // to see if it matches with the original data. If we didn't do that, it would + // be possible to stuff extra data into the arguments, which is not detected + // by merely decoding the data. + encoded, err := method.Inputs.PackValues(values) + if err != nil { + return nil, err + } + if !bytes.Equal(encoded, argdata) { + was := common.Bytes2Hex(encoded) + exp := common.Bytes2Hex(argdata) + return nil, fmt.Errorf("WARNING: Supplied data is stuffed with extra data. \nWant %s\nHave %s\nfor method %v", exp, was, method.Sig()) + } + return &decoded, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/fourbyte.go b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/fourbyte.go new file mode 100644 index 00000000..d1642212 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/fourbyte.go @@ -0,0 +1,143 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:generate go-bindata -nometadata -o 4byte.go -pkg fourbyte 4byte.json +//go:generate gofmt -s -w 4byte.go + +// Package fourbyte contains the 4byte database. +package fourbyte + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "os" +) + +// Database is a 4byte database with the possibility of maintaining an immutable +// set (embedded) into the process and a mutable set (loaded and written to file). +type Database struct { + embedded map[string]string + custom map[string]string + customPath string +} + +// newEmpty exists for testing purposes. +func newEmpty() *Database { + return &Database{ + embedded: make(map[string]string), + custom: make(map[string]string), + } +} + +// New loads the standard signature database embedded in the package. +func New() (*Database, error) { + return NewWithFile("") +} + +// NewFromFile loads signature database from file, and errors if the file is not +// valid JSON. The constructor does no other validation of contents. This method +// does not load the embedded 4byte database. +// +// The provided path will be used to write new values into if they are submitted +// via the API. +func NewFromFile(path string) (*Database, error) { + raw, err := os.Open(path) + if err != nil { + return nil, err + } + defer raw.Close() + + db := newEmpty() + if err := json.NewDecoder(raw).Decode(&db.embedded); err != nil { + return nil, err + } + return db, nil +} + +// NewWithFile loads both the standard signature database (embedded resource +// file) as well as a custom database. The latter will be used to write new +// values into if they are submitted via the API. +func NewWithFile(path string) (*Database, error) { + db := &Database{make(map[string]string), make(map[string]string), path} + db.customPath = path + + blob, err := Asset("4byte.json") + if err != nil { + return nil, err + } + if err := json.Unmarshal(blob, &db.embedded); err != nil { + return nil, err + } + // Custom file may not exist. Will be created during save, if needed. + if _, err := os.Stat(path); err == nil { + if blob, err = ioutil.ReadFile(path); err != nil { + return nil, err + } + if err := json.Unmarshal(blob, &db.custom); err != nil { + return nil, err + } + } + return db, nil +} + +// Size returns the number of 4byte entries in the embedded and custom datasets. +func (db *Database) Size() (int, int) { + return len(db.embedded), len(db.custom) +} + +// Selector checks the given 4byte ID against the known ABI methods. +// +// This method does not validate the match, it's assumed the caller will do. +func (db *Database) Selector(id []byte) (string, error) { + if len(id) < 4 { + return "", fmt.Errorf("expected 4-byte id, got %d", len(id)) + } + sig := hex.EncodeToString(id[:4]) + if selector, exists := db.embedded[sig]; exists { + return selector, nil + } + if selector, exists := db.custom[sig]; exists { + return selector, nil + } + return "", fmt.Errorf("signature %v not found", sig) +} + +// AddSelector inserts a new 4byte entry into the database. If custom database +// saving is enabled, the new dataset is also persisted to disk. +// +// Node, this method does _not_ validate the correctness of the data. It assumes +// the caller has already done so. +func (db *Database) AddSelector(selector string, data []byte) error { + // If the selector is already known, skip duplicating it + if len(data) < 4 { + return nil + } + if _, err := db.Selector(data[:4]); err == nil { + return nil + } + // Inject the custom selector into the database and persist if needed + db.custom[hex.EncodeToString(data[:4])] = selector + if db.customPath == "" { + return nil + } + blob, err := json.Marshal(db.custom) + if err != nil { + return err + } + return ioutil.WriteFile(db.customPath, blob, 0600) +} diff --git a/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/validation.go b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/validation.go new file mode 100644 index 00000000..6b8168cc --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/signer/fourbyte/validation.go @@ -0,0 +1,117 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package fourbyte + +import ( + "bytes" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/signer/core" +) + +// ValidateTransaction does a number of checks on the supplied transaction, and +// returns either a list of warnings, or an error (indicating that the transaction +// should be immediately rejected). +func (db *Database) ValidateTransaction(selector *string, tx *core.SendTxArgs) (*core.ValidationMessages, error) { + messages := new(core.ValidationMessages) + + // Prevent accidental erroneous usage of both 'input' and 'data' (show stopper) + if tx.Data != nil && tx.Input != nil && !bytes.Equal(*tx.Data, *tx.Input) { + return nil, errors.New(`ambiguous request: both "data" and "input" are set and are not identical`) + } + // Place data on 'data', and nil 'input' + var data []byte + if tx.Input != nil { + tx.Data = tx.Input + tx.Input = nil + } + if tx.Data != nil { + data = *tx.Data + } + // Contract creation doesn't validate call data, handle first + if tx.To == nil { + // Contract creation should contain sufficient data to deploy a contract. A + // typical error is omitting sender due to some quirk in the javascript call + // e.g. https://github.com/ethereum/go-ethereum/issues/16106. + if len(data) == 0 { + // Prevent sending ether into black hole (show stopper) + if tx.Value.ToInt().Cmp(big.NewInt(0)) > 0 { + return nil, errors.New("tx will create contract with value but empty code") + } + // No value submitted at least, critically Warn, but don't blow up + messages.Crit("Transaction will create contract with empty code") + } else if len(data) < 40 { // arbitrary heuristic limit + messages.Warn(fmt.Sprintf("Transaction will will create contract, but payload is suspiciously small (%d bytes)", len(data))) + } + // Method selector should be nil for contract creation + if selector != nil { + messages.Warn("Transaction will create contract, but method selector supplied, indicating intent to call a method") + } + return messages, nil + } + // Not a contract creation, validate as a plain transaction + if !tx.To.ValidChecksum() { + messages.Warn("Invalid checksum on recipient address") + } + if bytes.Equal(tx.To.Address().Bytes(), common.Address{}.Bytes()) { + messages.Crit("Transaction recipient is the zero address") + } + // Semantic fields validated, try to make heads or tails of the call data + db.validateCallData(selector, data, messages) + return messages, nil +} + +// validateCallData checks if the ABI call-data + method selector (if given) can +// be parsed and seems to match. +func (db *Database) validateCallData(selector *string, data []byte, messages *core.ValidationMessages) { + // If the data is empty, we have a plain value transfer, nothing more to do + if len(data) == 0 { + return + } + // Validate the call data that it has the 4byte prefix and the rest divisible by 32 bytes + if len(data) < 4 { + messages.Warn("Transaction data is not valid ABI (missing the 4 byte call prefix)") + return + } + if n := len(data) - 4; n%32 != 0 { + messages.Warn(fmt.Sprintf("Transaction data is not valid ABI (length should be a multiple of 32 (was %d))", n)) + } + // If a custom method selector was provided, validate with that + if selector != nil { + if info, err := verifySelector(*selector, data); err != nil { + messages.Warn(fmt.Sprintf("Transaction contains data, but provided ABI signature could not be matched: %v", err)) + } else { + messages.Info(info.String()) + db.AddSelector(*selector, data[:4]) + } + return + } + // No method selector was provided, check the database for embedded ones + embedded, err := db.Selector(data[:4]) + if err != nil { + messages.Warn(fmt.Sprintf("Transaction contains data, but the ABI signature could not be found: %v", err)) + return + } + if info, err := verifySelector(embedded, data); err != nil { + messages.Warn(fmt.Sprintf("Transaction contains data, but provided ABI signature could not be varified: %v", err)) + } else { + messages.Info(info.String()) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/api.go b/vendor/github.com/ethereum/go-ethereum/statediff/api.go new file mode 100644 index 00000000..a05ef551 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/api.go @@ -0,0 +1,91 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +// APIName is the namespace used for the state diffing service API +const APIName = "statediff" + +// APIVersion is the version of the state diffing service API +const APIVersion = "0.0.1" + +// PublicStateDiffAPI provides the a websocket service +// that can be used to stream out state diffs as they +// are produced by a full node +type PublicStateDiffAPI struct { + sds IService +} + +// NewPublicStateDiffAPI create a new state diff websocket streaming service. +func NewPublicStateDiffAPI(sds IService) *PublicStateDiffAPI { + return &PublicStateDiffAPI{ + sds: sds, + } +} + +// Stream is the public method to setup a subscription that fires off state-diff payloads as they are created +func (api *PublicStateDiffAPI) Stream(ctx context.Context) (*rpc.Subscription, error) { + // ensure that the RPC connection supports subscriptions + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // create subscription and start waiting for statediff events + rpcSub := notifier.CreateSubscription() + + go func() { + // subscribe to events from the state diff service + payloadChannel := make(chan Payload, chainEventChanSize) + quitChan := make(chan bool, 1) + api.sds.Subscribe(rpcSub.ID, payloadChannel, quitChan) + // loop and await state diff payloads and relay them to the subscriber with the notifier + for { + select { + case packet := <-payloadChannel: + if notifyErr := notifier.Notify(rpcSub.ID, packet); notifyErr != nil { + log.Error("Failed to send state diff packet; error: " + notifyErr.Error()) + unSubErr := api.sds.Unsubscribe(rpcSub.ID) + if unSubErr != nil { + log.Error("Failed to unsubscribe from the state diff service; error: " + unSubErr.Error()) + } + return + } + case err := <-rpcSub.Err(): + if err != nil { + log.Error("State diff service rpcSub error: " + err.Error()) + err = api.sds.Unsubscribe(rpcSub.ID) + if err != nil { + log.Error("Failed to unsubscribe from the state diff service; error: " + err.Error()) + } + return + } + case <-quitChan: + // don't need to unsubscribe, statediff service does so before sending the quit signal + return + } + } + }() + + return rpcSub, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/builder.go b/vendor/github.com/ethereum/go-ethereum/statediff/builder.go new file mode 100644 index 00000000..765152e8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/builder.go @@ -0,0 +1,332 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains a batch of utility type declarations used by the tests. As the node +// operates on unique types, a lot of them are needed to check various features. + +package statediff + +import ( + "bytes" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" +) + +var nullNode = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") + +// Builder interface exposes the method for building a state diff between two blocks +type Builder interface { + BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (StateDiff, error) +} + +type builder struct { + chainDB ethdb.Database + config Config + blockChain *core.BlockChain + stateCache state.Database +} + +// NewBuilder is used to create a state diff builder +func NewBuilder(db ethdb.Database, blockChain *core.BlockChain, config Config) Builder { + return &builder{ + chainDB: db, + config: config, + blockChain: blockChain, + } +} + +// BuildStateDiff builds a StateDiff object from two blocks +func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (StateDiff, error) { + // Generate tries for old and new states + sdb.stateCache = sdb.blockChain.StateCache() + oldTrie, err := sdb.stateCache.OpenTrie(oldStateRoot) + if err != nil { + return StateDiff{}, fmt.Errorf("error creating trie for oldStateRoot: %v", err) + } + newTrie, err := sdb.stateCache.OpenTrie(newStateRoot) + if err != nil { + return StateDiff{}, fmt.Errorf("error creating trie for newStateRoot: %v", err) + } + + // Find created accounts + oldIt := oldTrie.NodeIterator([]byte{}) + newIt := newTrie.NodeIterator([]byte{}) + creations, err := sdb.collectDiffNodes(oldIt, newIt) + if err != nil { + return StateDiff{}, fmt.Errorf("error collecting creation diff nodes: %v", err) + } + + // Find deleted accounts + oldIt = oldTrie.NodeIterator([]byte{}) + newIt = newTrie.NodeIterator([]byte{}) + deletions, err := sdb.collectDiffNodes(newIt, oldIt) + if err != nil { + return StateDiff{}, fmt.Errorf("error collecting deletion diff nodes: %v", err) + } + + // Find all the diffed keys + createKeys := sortKeys(creations) + deleteKeys := sortKeys(deletions) + updatedKeys := findIntersection(createKeys, deleteKeys) + + // Build and return the statediff + updatedAccounts, err := sdb.buildDiffIncremental(creations, deletions, updatedKeys) + if err != nil { + return StateDiff{}, fmt.Errorf("error building diff for updated accounts: %v", err) + } + createdAccounts, err := sdb.buildDiffEventual(creations) + if err != nil { + return StateDiff{}, fmt.Errorf("error building diff for created accounts: %v", err) + } + deletedAccounts, err := sdb.buildDiffEventual(deletions) + if err != nil { + return StateDiff{}, fmt.Errorf("error building diff for deleted accounts: %v", err) + } + + return StateDiff{ + BlockNumber: blockNumber, + BlockHash: blockHash, + CreatedAccounts: createdAccounts, + DeletedAccounts: deletedAccounts, + UpdatedAccounts: updatedAccounts, + }, nil +} + +func (sdb *builder) isWatchedAddress(hashKey []byte) bool { + // If we aren't watching any addresses, we are watching everything + if len(sdb.config.WatchedAddresses) == 0 { + return true + } + for _, addrStr := range sdb.config.WatchedAddresses { + addr := common.HexToAddress(addrStr) + addrHashKey := crypto.Keccak256(addr[:]) + if bytes.Equal(addrHashKey, hashKey) { + return true + } + } + return false +} + +func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error) { + var diffAccounts = make(AccountsMap) + it, _ := trie.NewDifferenceIterator(a, b) + for { + log.Debug("Current Path and Hash", "path", pathToStr(it), "old hash", it.Hash()) + if it.Leaf() && sdb.isWatchedAddress(it.LeafKey()) { + leafKey := make([]byte, len(it.LeafKey())) + copy(leafKey, it.LeafKey()) + leafKeyHash := common.BytesToHash(leafKey) + leafValue := make([]byte, len(it.LeafBlob())) + copy(leafValue, it.LeafBlob()) + // lookup account state + var account state.Account + if err := rlp.DecodeBytes(leafValue, &account); err != nil { + return nil, fmt.Errorf("error looking up account via address %s\r\nerror: %v", leafKeyHash.Hex(), err) + } + aw := accountWrapper{ + Leaf: true, + Account: &account, + RawKey: leafKey, + RawValue: leafValue, + } + if sdb.config.PathsAndProofs { + leafProof := make([][]byte, len(it.LeafProof())) + copy(leafProof, it.LeafProof()) + leafPath := make([]byte, len(it.Path())) + copy(leafPath, it.Path()) + aw.Proof = leafProof + aw.Path = leafPath + } + // record account to diffs (creation if we are looking at new - old; deletion if old - new) + log.Debug("Account lookup successful", "address", leafKeyHash, "account", account) + diffAccounts[leafKeyHash] = aw + } else if sdb.config.IntermediateNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) { + nodeKey := it.Hash() + node, err := sdb.stateCache.TrieDB().Node(nodeKey) + if err != nil { + return nil, fmt.Errorf("error looking up intermediate state trie node %s\r\nerror: %v", nodeKey.Hex(), err) + } + aw := accountWrapper{ + Leaf: false, + RawKey: nodeKey.Bytes(), + RawValue: node, + } + log.Debug("intermediate state trie node lookup successful", "key", nodeKey.Hex(), "value", node) + diffAccounts[nodeKey] = aw + } + cont := it.Next(true) + if !cont { + break + } + } + + return diffAccounts, nil +} + +func (sdb *builder) buildDiffEventual(accounts AccountsMap) ([]AccountDiff, error) { + accountDiffs := make([]AccountDiff, 0) + var err error + for _, val := range accounts { + // If account is not nil, we need to process storage diffs + var storageDiffs []StorageDiff + if val.Account != nil { + storageDiffs, err = sdb.buildStorageDiffsEventual(val.Account.Root) + if err != nil { + return nil, fmt.Errorf("failed building eventual storage diffs for %s\r\nerror: %v", common.BytesToHash(val.RawKey), err) + } + } + accountDiffs = append(accountDiffs, AccountDiff{ + Leaf: val.Leaf, + Key: val.RawKey, + Value: val.RawValue, + Proof: val.Proof, + Path: val.Path, + Storage: storageDiffs, + }) + } + + return accountDiffs, nil +} + +func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) ([]AccountDiff, error) { + updatedAccounts := make([]AccountDiff, 0) + var err error + for _, val := range updatedKeys { + hashKey := common.HexToHash(val) + createdAcc := creations[hashKey] + deletedAcc := deletions[hashKey] + var storageDiffs []StorageDiff + if deletedAcc.Account != nil && createdAcc.Account != nil { + oldSR := deletedAcc.Account.Root + newSR := createdAcc.Account.Root + storageDiffs, err = sdb.buildStorageDiffsIncremental(oldSR, newSR) + if err != nil { + return nil, fmt.Errorf("failed building incremental storage diffs for %s\r\nerror: %v", hashKey.Hex(), err) + } + } + updatedAccounts = append(updatedAccounts, AccountDiff{ + Leaf: createdAcc.Leaf, + Key: createdAcc.RawKey, + Value: createdAcc.RawValue, + Proof: createdAcc.Proof, + Path: createdAcc.Path, + Storage: storageDiffs, + }) + delete(creations, common.HexToHash(val)) + delete(deletions, common.HexToHash(val)) + } + + return updatedAccounts, nil +} + +func (sdb *builder) buildStorageDiffsEventual(sr common.Hash) ([]StorageDiff, error) { + log.Debug("Storage Root For Eventual Diff", "root", sr.Hex()) + stateCache := sdb.blockChain.StateCache() + sTrie, err := stateCache.OpenTrie(sr) + if err != nil { + log.Info("error in build storage diff eventual", "error", err) + return nil, err + } + it := sTrie.NodeIterator(make([]byte, 0)) + return sdb.buildStorageDiffsFromTrie(it) +} + +func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common.Hash) ([]StorageDiff, error) { + log.Debug("Storage Roots for Incremental Diff", "old", oldSR.Hex(), "new", newSR.Hex()) + stateCache := sdb.blockChain.StateCache() + + oldTrie, err := stateCache.OpenTrie(oldSR) + if err != nil { + return nil, err + } + newTrie, err := stateCache.OpenTrie(newSR) + if err != nil { + return nil, err + } + + oldIt := oldTrie.NodeIterator(make([]byte, 0)) + newIt := newTrie.NodeIterator(make([]byte, 0)) + it, _ := trie.NewDifferenceIterator(oldIt, newIt) + return sdb.buildStorageDiffsFromTrie(it) +} + +func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDiff, error) { + storageDiffs := make([]StorageDiff, 0) + for { + log.Debug("Iterating over state at path ", "path", pathToStr(it)) + if it.Leaf() { + log.Debug("Found leaf in storage", "path", pathToStr(it)) + leafKey := make([]byte, len(it.LeafKey())) + copy(leafKey, it.LeafKey()) + leafValue := make([]byte, len(it.LeafBlob())) + copy(leafValue, it.LeafBlob()) + sd := StorageDiff{ + Leaf: true, + Key: leafKey, + Value: leafValue, + } + if sdb.config.PathsAndProofs { + leafProof := make([][]byte, len(it.LeafProof())) + copy(leafProof, it.LeafProof()) + leafPath := make([]byte, len(it.Path())) + copy(leafPath, it.Path()) + sd.Proof = leafProof + sd.Path = leafPath + } + storageDiffs = append(storageDiffs, sd) + } else if sdb.config.IntermediateNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) { + nodeKey := it.Hash() + node, err := sdb.stateCache.TrieDB().Node(nodeKey) + if err != nil { + return nil, fmt.Errorf("error looking up intermediate storage trie node %s\r\nerror: %v", nodeKey.Hex(), err) + } + storageDiffs = append(storageDiffs, StorageDiff{ + Leaf: false, + Key: nodeKey.Bytes(), + Value: node, + }) + log.Debug("intermediate storage trie node lookup successful", "key", nodeKey.Hex(), "value", node) + } + cont := it.Next(true) + if !cont { + break + } + } + + return storageDiffs, nil +} + +func (sdb *builder) addressByPath(path []byte) (*common.Address, error) { + log.Debug("Looking up address from path", "path", hexutil.Encode(append([]byte("secure-key-"), path...))) + addrBytes, err := sdb.chainDB.Get(append([]byte("secure-key-"), hexToKeyBytes(path)...)) + if err != nil { + log.Error("Error looking up address via path", "path", hexutil.Encode(append([]byte("secure-key-"), path...)), "error", err) + return nil, err + } + addr := common.BytesToAddress(addrBytes) + log.Debug("Address found", "Address", addr) + return &addr, nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/config.go b/vendor/github.com/ethereum/go-ethereum/statediff/config.go new file mode 100644 index 00000000..70f09a74 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/config.go @@ -0,0 +1,25 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +// Config is used to carry in parameters from CLI configuration +type Config struct { + PathsAndProofs bool + IntermediateNodes bool + StreamBlock bool + WatchedAddresses []string +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/doc.go b/vendor/github.com/ethereum/go-ethereum/statediff/doc.go new file mode 100644 index 00000000..c0cbb435 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/doc.go @@ -0,0 +1,40 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +/* +This work is adapted from work by Charles Crain at https://github.com/jpmorganchase/quorum/blob/9b7fd9af8082795eeeb6863d9746f12b82dd5078/statediff/statediff.go + +Package statediff provides an auxiliary service that processes state diff objects from incoming chain events, +relaying the objects to any rpc subscriptions. + +Rpc subscriptions to the service can be created using the rpc.Client.Subscribe() method, +with the "statediff" namespace, a statediff.Payload channel, and the name of the statediff api's rpc method- "stream". + +e.g. + +stateDiffPayloadChan := make(chan statediff.Payload, 20000) +rpcSub, err := Subscribe(context.Background(), "statediff", stateDiffPayloadChan, "stream"}) +for { + select { + case stateDiffPayload := <- stateDiffPayloadChan: + processPayload(stateDiffPayload) + case err := <= rpcSub.Err(): + log.Error(err) + } +} + +*/ +package statediff diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/helpers.go b/vendor/github.com/ethereum/go-ethereum/statediff/helpers.go new file mode 100644 index 00000000..89852b55 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/helpers.go @@ -0,0 +1,118 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains a batch of utility type declarations used by the tests. As the node +// operates on unique types, a lot of them are needed to check various features. + +package statediff + +import ( + "sort" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/trie" +) + +func sortKeys(data AccountsMap) []string { + var keys []string + for key := range data { + keys = append(keys, key.Hex()) + } + sort.Strings(keys) + + return keys +} + +// BytesToNiblePath +func bytesToNiblePath(path []byte) string { + if hasTerm(path) { + path = path[:len(path)-1] + } + nibblePath := "" + for i, v := range common.ToHex(path) { + if i%2 == 0 && i > 1 { + continue + } + nibblePath = nibblePath + string(v) + } + + return nibblePath +} + +func findIntersection(a, b []string) []string { + lenA := len(a) + lenB := len(b) + iOfA, iOfB := 0, 0 + updates := make([]string, 0) + if iOfA >= lenA || iOfB >= lenB { + return updates + } + for { + switch strings.Compare(a[iOfA], b[iOfB]) { + // a[iOfA] < b[iOfB] + case -1: + iOfA++ + if iOfA >= lenA { + return updates + } + // a[iOfA] == b[iOfB] + case 0: + updates = append(updates, a[iOfA]) + iOfA++ + iOfB++ + if iOfA >= lenA || iOfB >= lenB { + return updates + } + // a[iOfA] > b[iOfB] + case 1: + iOfB++ + if iOfB >= lenB { + return updates + } + } + } + +} + +func pathToStr(it trie.NodeIterator) string { + return bytesToNiblePath(it.Path()) +} + +// Duplicated from trie/encoding.go +func hexToKeyBytes(hex []byte) []byte { + if hasTerm(hex) { + hex = hex[:len(hex)-1] + } + if len(hex)&1 != 0 { + panic("can't convert hex key of odd length") + } + key := make([]byte, (len(hex)+1)/2) + decodeNibbles(hex, key) + + return key +} + +func decodeNibbles(nibbles []byte, bytes []byte) { + for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 { + bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1] + } +} + +// hasTerm returns whether a hex key has the terminator flag. +func hasTerm(s []byte) bool { + return len(s) > 0 && s[len(s)-1] == 16 +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/service.go b/vendor/github.com/ethereum/go-ethereum/statediff/service.go new file mode 100644 index 00000000..e978fcb8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/service.go @@ -0,0 +1,267 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +import ( + "bytes" + "fmt" + "sync" + "sync/atomic" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" +) + +const chainEventChanSize = 20000 + +type blockChain interface { + SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + GetBlockByHash(hash common.Hash) *types.Block + AddToStateDiffProcessedCollection(hash common.Hash) +} + +// IService is the state-diffing service interface +type IService interface { + // APIs(), Protocols(), Start() and Stop() + node.Service + // Main event loop for processing state diffs + Loop(chainEventCh chan core.ChainEvent) + // Method to subscribe to receive state diff processing output + Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool) + // Method to unsubscribe from state diff processing + Unsubscribe(id rpc.ID) error +} + +// Service is the underlying struct for the state diffing service +type Service struct { + // Used to sync access to the Subscriptions + sync.Mutex + // Used to build the state diff objects + Builder Builder + // Used to subscribe to chain events (blocks) + BlockChain blockChain + // Used to signal shutdown of the service + QuitChan chan bool + // A mapping of rpc.IDs to their subscription channels + Subscriptions map[rpc.ID]Subscription + // Cache the last block so that we can avoid having to lookup the next block's parent + lastBlock *types.Block + // Whether or not the block data is streamed alongside the state diff data in the subscription payload + streamBlock bool + // Whether or not we have any subscribers; only if we do, do we processes state diffs + subscribers int32 +} + +// NewStateDiffService creates a new StateDiffingService +func NewStateDiffService(db ethdb.Database, blockChain *core.BlockChain, config Config) (*Service, error) { + return &Service{ + Mutex: sync.Mutex{}, + BlockChain: blockChain, + Builder: NewBuilder(db, blockChain, config), + QuitChan: make(chan bool), + Subscriptions: make(map[rpc.ID]Subscription), + streamBlock: config.StreamBlock, + }, nil +} + +// Protocols exports the services p2p protocols, this service has none +func (sds *Service) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +// APIs returns the RPC descriptors the StateDiffingService offers +func (sds *Service) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: APIName, + Version: APIVersion, + Service: NewPublicStateDiffAPI(sds), + Public: true, + }, + } +} + +// Loop is the main processing method +func (sds *Service) Loop(chainEventCh chan core.ChainEvent) { + chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh) + defer chainEventSub.Unsubscribe() + errCh := chainEventSub.Err() + + for { + select { + //Notify chain event channel of events + case chainEvent := <-chainEventCh: + log.Debug("Event received from chainEventCh", "event", chainEvent) + // if we don't have any subscribers, do not process a statediff + if atomic.LoadInt32(&sds.subscribers) == 0 { + log.Debug("Currently no subscribers to the statediffing service; processing is halted") + continue + } + currentBlock := chainEvent.Block + parentHash := currentBlock.ParentHash() + var parentBlock *types.Block + if sds.lastBlock != nil && bytes.Equal(sds.lastBlock.Hash().Bytes(), currentBlock.ParentHash().Bytes()) { + parentBlock = sds.lastBlock + } else { + parentBlock = sds.BlockChain.GetBlockByHash(parentHash) + } + sds.lastBlock = currentBlock + if parentBlock == nil { + log.Error(fmt.Sprintf("Parent block is nil, skipping this block (%d)", currentBlock.Number())) + continue + } + if err := sds.processStateDiff(currentBlock, parentBlock); err != nil { + log.Error(fmt.Sprintf("Error building statediff for block %d; error: ", currentBlock.Number()) + err.Error()) + } + case err := <-errCh: + log.Warn("Error from chain event subscription, breaking loop", "error", err) + sds.close() + return + case <-sds.QuitChan: + log.Info("Quitting the statediffing process") + sds.close() + return + } + } +} + +// processStateDiff method builds the state diff payload from the current and parent block and sends it to listening subscriptions +func (sds *Service) processStateDiff(currentBlock, parentBlock *types.Block) error { + stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number(), currentBlock.Hash()) + if err != nil { + return err + } + stateDiffRlp, err := rlp.EncodeToBytes(stateDiff) + if err != nil { + return err + } + payload := Payload{ + StateDiffRlp: stateDiffRlp, + Err: err, + } + if sds.streamBlock { + rlpBuff := new(bytes.Buffer) + if err = currentBlock.EncodeRLP(rlpBuff); err != nil { + return err + } + payload.BlockRlp = rlpBuff.Bytes() + } + + // If we have any websocket subscriptions listening in, send the data to them + sds.send(payload) + return nil +} + +// Subscribe is used by the API to subscribe to the StateDiffingService loop +func (sds *Service) Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool) { + log.Info("Subscribing to the statediff service") + if atomic.CompareAndSwapInt32(&sds.subscribers, 0, 1) { + log.Info("State diffing subscription received; beginning statediff processing") + } + sds.Lock() + sds.Subscriptions[id] = Subscription{ + PayloadChan: sub, + QuitChan: quitChan, + } + sds.Unlock() +} + +// Unsubscribe is used to unsubscribe to the StateDiffingService loop +func (sds *Service) Unsubscribe(id rpc.ID) error { + log.Info("Unsubscribing from the statediff service") + sds.Lock() + _, ok := sds.Subscriptions[id] + if !ok { + return fmt.Errorf("cannot unsubscribe; subscription for id %s does not exist", id) + } + delete(sds.Subscriptions, id) + if len(sds.Subscriptions) == 0 { + if atomic.CompareAndSwapInt32(&sds.subscribers, 1, 0) { + log.Info("No more subscriptions; halting statediff processing") + } + } + sds.Unlock() + return nil +} + +// Start is used to begin the StateDiffingService +func (sds *Service) Start(*p2p.Server) error { + log.Info("Starting statediff service") + + chainEventCh := make(chan core.ChainEvent, chainEventChanSize) + go sds.Loop(chainEventCh) + + return nil +} + +// Stop is used to close down the StateDiffingService +func (sds *Service) Stop() error { + log.Info("Stopping statediff service") + close(sds.QuitChan) + return nil +} + +// send is used to fan out and serve the statediff payload to all subscriptions +func (sds *Service) send(payload Payload) { + sds.Lock() + for id, sub := range sds.Subscriptions { + select { + case sub.PayloadChan <- payload: + log.Info(fmt.Sprintf("sending state diff payload to subscription %s", id)) + default: + log.Info(fmt.Sprintf("unable to send payload to subscription %s; channel has no receiver", id)) + // in this case, try to close the bad subscription and remove it + select { + case sub.QuitChan <- true: + log.Info(fmt.Sprintf("closing subscription %s", id)) + default: + log.Info(fmt.Sprintf("unable to close subscription %s; channel has no receiver", id)) + } + delete(sds.Subscriptions, id) + } + } + // If after removing all bad subscriptions we have none left, halt processing + if len(sds.Subscriptions) == 0 { + if atomic.CompareAndSwapInt32(&sds.subscribers, 1, 0) { + log.Info("No more subscriptions; halting statediff processing") + } + } + sds.Unlock() +} + +// close is used to close all listening subscriptions +func (sds *Service) close() { + sds.Lock() + for id, sub := range sds.Subscriptions { + select { + case sub.QuitChan <- true: + log.Info(fmt.Sprintf("closing subscription %s", id)) + default: + log.Info(fmt.Sprintf("unable to close subscription %s; channel has no receiver", id)) + } + delete(sds.Subscriptions, id) + } + sds.Unlock() +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/helpers.go b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/helpers.go new file mode 100644 index 00000000..8f52bc8c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/helpers.go @@ -0,0 +1,83 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package testhelpers + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +// MakeChain creates a chain of n blocks starting at and including parent. +// the returned hash chain is ordered head->parent. In addition, every 3rd block +// contains a transaction and every 5th an uncle to allow testing correct block +// reassembly. +func MakeChain(n int, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block, *core.BlockChain) { + blocks, _ := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), Testdb, n, testChainGen) + headers := make([]*types.Header, len(blocks)) + for i, block := range blocks { + headers[i] = block.Header() + } + chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil) + + hashes := make([]common.Hash, n+1) + hashes[len(hashes)-1] = parent.Hash() + blockm := make(map[common.Hash]*types.Block, n+1) + blockm[parent.Hash()] = parent + for i, b := range blocks { + hashes[len(hashes)-i-2] = b.Hash() + blockm[b.Hash()] = b + } + return hashes, blockm, chain +} + +func testChainGen(i int, block *core.BlockGen) { + signer := types.HomesteadSigner{} + switch i { + case 0: + // In block 1, the test bank sends account #1 some ether. + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, TestBankKey) + block.AddTx(tx) + case 1: + // In block 2, the test bank sends some more ether to account #1. + // account1Addr passes it on to account #2. + // account1Addr creates a test contract. + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, TestBankKey) + nonce := block.TxNonce(Account1Addr) + tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, Account1Key) + nonce++ + tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), ContractCode), signer, Account1Key) + ContractAddr = crypto.CreateAddress(Account1Addr, nonce) //0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592 + block.AddTx(tx1) + block.AddTx(tx2) + block.AddTx(tx3) + case 2: + // Block 3 is empty but was mined by account #2. + block.SetCoinbase(Account2Addr) + //get function: 60cd2685 + //put function: c16431b9 + data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey) + block.AddTx(tx) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/api.go b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/api.go new file mode 100644 index 00000000..687a7c77 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/api.go @@ -0,0 +1,188 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "bytes" + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/rlp" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff" +) + +// MockStateDiffService is a mock state diff service +type MockStateDiffService struct { + sync.Mutex + Builder statediff.Builder + ReturnProtocol []p2p.Protocol + ReturnAPIs []rpc.API + BlockChan chan *types.Block + ParentBlockChan chan *types.Block + QuitChan chan bool + Subscriptions map[rpc.ID]statediff.Subscription + streamBlock bool +} + +// Protocols mock method +func (sds *MockStateDiffService) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +// APIs mock method +func (sds *MockStateDiffService) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: statediff.APIName, + Version: statediff.APIVersion, + Service: statediff.NewPublicStateDiffAPI(sds), + Public: true, + }, + } +} + +// Loop mock method +func (sds *MockStateDiffService) Loop(chan core.ChainEvent) { + //loop through chain events until no more + for { + select { + case block := <-sds.BlockChan: + currentBlock := block + parentBlock := <-sds.ParentBlockChan + parentHash := parentBlock.Hash() + if parentBlock == nil { + log.Error("Parent block is nil, skipping this block", + "parent block hash", parentHash.String(), + "current block number", currentBlock.Number()) + continue + } + if err := sds.process(currentBlock, parentBlock); err != nil { + println(err.Error()) + log.Error("Error building statediff", "block number", currentBlock.Number(), "error", err) + } + case <-sds.QuitChan: + log.Debug("Quitting the statediff block channel") + sds.close() + return + } + } +} + +// process method builds the state diff payload from the current and parent block and streams it to listening subscriptions +func (sds *MockStateDiffService) process(currentBlock, parentBlock *types.Block) error { + stateDiff, err := sds.Builder.BuildStateDiff(parentBlock.Root(), currentBlock.Root(), currentBlock.Number(), currentBlock.Hash()) + if err != nil { + return err + } + + stateDiffRlp, err := rlp.EncodeToBytes(stateDiff) + if err != nil { + return err + } + payload := statediff.Payload{ + StateDiffRlp: stateDiffRlp, + Err: err, + } + if sds.streamBlock { + rlpBuff := new(bytes.Buffer) + if err = currentBlock.EncodeRLP(rlpBuff); err != nil { + return err + } + payload.BlockRlp = rlpBuff.Bytes() + } + + // If we have any websocket subscription listening in, send the data to them + sds.send(payload) + return nil +} + +// Subscribe mock method +func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- statediff.Payload, quitChan chan<- bool) { + log.Info("Subscribing to the statediff service") + sds.Lock() + sds.Subscriptions[id] = statediff.Subscription{ + PayloadChan: sub, + QuitChan: quitChan, + } + sds.Unlock() +} + +// Unsubscribe mock method +func (sds *MockStateDiffService) Unsubscribe(id rpc.ID) error { + log.Info("Unsubscribing from the statediff service") + sds.Lock() + _, ok := sds.Subscriptions[id] + if !ok { + return fmt.Errorf("cannot unsubscribe; subscription for id %s does not exist", id) + } + delete(sds.Subscriptions, id) + sds.Unlock() + return nil +} + +func (sds *MockStateDiffService) send(payload statediff.Payload) { + sds.Lock() + for id, sub := range sds.Subscriptions { + select { + case sub.PayloadChan <- payload: + log.Info("sending state diff payload to subscription %s", id) + default: + log.Info("unable to send payload to subscription %s; channel has no receiver", id) + } + } + sds.Unlock() +} + +func (sds *MockStateDiffService) close() { + sds.Lock() + for id, sub := range sds.Subscriptions { + select { + case sub.QuitChan <- true: + delete(sds.Subscriptions, id) + log.Info("closing subscription %s", id) + default: + log.Info("unable to close subscription %s; channel has no receiver", id) + } + } + sds.Unlock() +} + +// Start mock method +func (sds *MockStateDiffService) Start(server *p2p.Server) error { + log.Info("Starting statediff service") + if sds.ParentBlockChan == nil || sds.BlockChan == nil { + return errors.New("mock StateDiffingService requires preconfiguration with a MockParentBlockChan and MockBlockChan") + } + chainEventCh := make(chan core.ChainEvent, 10) + go sds.Loop(chainEventCh) + + return nil +} + +// Stop mock method +func (sds *MockStateDiffService) Stop() error { + log.Info("Stopping statediff service") + close(sds.QuitChan) + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/blockchain.go b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/blockchain.go new file mode 100644 index 00000000..f2c097d3 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/blockchain.go @@ -0,0 +1,86 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "errors" + + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// BlockChain is a mock blockchain for testing +type BlockChain struct { + ParentHashesLookedUp []common.Hash + parentBlocksToReturn []*types.Block + callCount int + ChainEvents []core.ChainEvent +} + +// AddToStateDiffProcessedCollection mock method +func (blockChain *BlockChain) AddToStateDiffProcessedCollection(hash common.Hash) {} + +// SetParentBlocksToReturn mock method +func (blockChain *BlockChain) SetParentBlocksToReturn(blocks []*types.Block) { + blockChain.parentBlocksToReturn = blocks +} + +// GetBlockByHash mock method +func (blockChain *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { + blockChain.ParentHashesLookedUp = append(blockChain.ParentHashesLookedUp, hash) + + var parentBlock *types.Block + if len(blockChain.parentBlocksToReturn) > 0 { + parentBlock = blockChain.parentBlocksToReturn[blockChain.callCount] + } + + blockChain.callCount++ + return parentBlock +} + +// SetChainEvents mock method +func (blockChain *BlockChain) SetChainEvents(chainEvents []core.ChainEvent) { + blockChain.ChainEvents = chainEvents +} + +// SubscribeChainEvent mock method +func (blockChain *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + subErr := errors.New("Subscription Error") + + var eventCounter int + subscription := event.NewSubscription(func(quit <-chan struct{}) error { + for _, chainEvent := range blockChain.ChainEvents { + if eventCounter > 1 { + time.Sleep(250 * time.Millisecond) + return subErr + } + select { + case ch <- chainEvent: + case <-quit: + return nil + } + eventCounter++ + } + return nil + }) + + return subscription +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/builder.go b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/builder.go new file mode 100644 index 00000000..034af041 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/mocks/builder.go @@ -0,0 +1,54 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff" +) + +// Builder is a mock state diff builder +type Builder struct { + OldStateRoot common.Hash + NewStateRoot common.Hash + BlockNumber *big.Int + BlockHash common.Hash + stateDiff statediff.StateDiff + builderError error +} + +// BuildStateDiff mock method +func (builder *Builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, blockNumber *big.Int, blockHash common.Hash) (statediff.StateDiff, error) { + builder.OldStateRoot = oldStateRoot + builder.NewStateRoot = newStateRoot + builder.BlockNumber = blockNumber + builder.BlockHash = blockHash + + return builder.stateDiff, builder.builderError +} + +// SetStateDiffToBuild mock method +func (builder *Builder) SetStateDiffToBuild(stateDiff statediff.StateDiff) { + builder.stateDiff = stateDiff +} + +// SetBuilderError mock method +func (builder *Builder) SetBuilderError(err error) { + builder.builderError = err +} diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/test_data.go b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/test_data.go new file mode 100644 index 00000000..2f6088f8 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/testhelpers/test_data.go @@ -0,0 +1,114 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package testhelpers + +import ( + "math/big" + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff" +) + +// AddressToLeafKey hashes an returns an address +func AddressToLeafKey(address common.Address) common.Hash { + return common.BytesToHash(crypto.Keccak256(address[:])) +} + +// Test variables +var ( + BlockNumber = big.NewInt(rand.Int63()) + BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73" + CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") + NewNonceValue = rand.Uint64() + NewBalanceValue = rand.Int63() + ContractRoot = common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + StoragePath = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes() + StorageKey = common.HexToHash("0000000000000000000000000000000000000000000000000000000000000001").Bytes() + StorageValue = common.Hex2Bytes("0x03") + storage = []statediff.StorageDiff{{ + Key: StorageKey, + Value: StorageValue, + Path: StoragePath, + Proof: [][]byte{}, + }} + emptyStorage = make([]statediff.StorageDiff, 0) + address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592") + ContractLeafKey = AddressToLeafKey(address) + anotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593") + AnotherContractLeafKey = AddressToLeafKey(anotherAddress) + testAccount = state.Account{ + Nonce: NewNonceValue, + Balance: big.NewInt(NewBalanceValue), + Root: ContractRoot, + CodeHash: CodeHash, + } + valueBytes, _ = rlp.EncodeToBytes(testAccount) + CreatedAccountDiffs = []statediff.AccountDiff{ + { + Key: ContractLeafKey.Bytes(), + Value: valueBytes, + Storage: storage, + }, + { + Key: AnotherContractLeafKey.Bytes(), + Value: valueBytes, + Storage: emptyStorage, + }, + } + + UpdatedAccountDiffs = []statediff.AccountDiff{{ + Key: ContractLeafKey.Bytes(), + Value: valueBytes, + Storage: storage, + }} + + DeletedAccountDiffs = []statediff.AccountDiff{{ + Key: ContractLeafKey.Bytes(), + Value: valueBytes, + Storage: storage, + }} + + TestStateDiff = statediff.StateDiff{ + BlockNumber: BlockNumber, + BlockHash: common.HexToHash(BlockHash), + CreatedAccounts: CreatedAccountDiffs, + DeletedAccounts: DeletedAccountDiffs, + UpdatedAccounts: UpdatedAccountDiffs, + } + Testdb = rawdb.NewMemoryDatabase() + + TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7 + BankLeafKey = AddressToLeafKey(TestBankAddress) + TestBankFunds = big.NewInt(100000000) + Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds) + + Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") + Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7 + Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e + Account1LeafKey = AddressToLeafKey(Account1Addr) + Account2LeafKey = AddressToLeafKey(Account2Addr) + ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50602060405190810160405280600160ff16815250600090600161003592919061003b565b506100a5565b826064810192821561006f579160200282015b8281111561006e578251829060ff1690559160200191906001019061004e565b5b50905061007c9190610080565b5090565b6100a291905b8082111561009e576000816000905550600101610086565b5090565b90565b610124806100b46000396000f3fe6080604052348015600f57600080fd5b5060043610604f576000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146054578063c16431b9146093575b600080fd5b607d60048036036020811015606857600080fd5b810190808035906020019092919050505060c8565b6040518082815260200191505060405180910390f35b60c66004803603604081101560a757600080fd5b81019080803590602001909291908035906020019092919050505060e0565b005b6000808260648110151560d757fe5b01549050919050565b8060008360648110151560ef57fe5b0181905550505056fea165627a7a7230582064e918c3140a117bf3aa65865a9b9e83fae21ad1720506e7933b2a9f54bb40260029") + ContractAddr common.Address +) diff --git a/vendor/github.com/ethereum/go-ethereum/statediff/types.go b/vendor/github.com/ethereum/go-ethereum/statediff/types.go new file mode 100644 index 00000000..6df398a1 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/statediff/types.go @@ -0,0 +1,104 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains a batch of utility type declarations used by the tests. As the node +// operates on unique types, a lot of them are needed to check various features. + +package statediff + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/core/state" + + "github.com/ethereum/go-ethereum/common" +) + +// Subscription struct holds our subscription channels +type Subscription struct { + PayloadChan chan<- Payload + QuitChan chan<- bool +} + +// Payload packages the data to send to StateDiffingService subscriptions +type Payload struct { + BlockRlp []byte `json:"blockRlp" gencodec:"required"` + StateDiffRlp []byte `json:"stateDiff" gencodec:"required"` + Err error `json:"error"` +} + +// StateDiff is the final output structure from the builder +type StateDiff struct { + BlockNumber *big.Int `json:"blockNumber" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + CreatedAccounts []AccountDiff `json:"createdAccounts" gencodec:"required"` + DeletedAccounts []AccountDiff `json:"deletedAccounts" gencodec:"required"` + UpdatedAccounts []AccountDiff `json:"updatedAccounts" gencodec:"required"` + + encoded []byte + err error +} + +func (sd *StateDiff) ensureEncoded() { + if sd.encoded == nil && sd.err == nil { + sd.encoded, sd.err = json.Marshal(sd) + } +} + +// Length to implement Encoder interface for StateDiff +func (sd *StateDiff) Length() int { + sd.ensureEncoded() + return len(sd.encoded) +} + +// Encode to implement Encoder interface for StateDiff +func (sd *StateDiff) Encode() ([]byte, error) { + sd.ensureEncoded() + return sd.encoded, sd.err +} + +// AccountDiff holds the data for a single state diff node +type AccountDiff struct { + Leaf bool `json:"leaf" gencodec:"required"` + Key []byte `json:"key" gencodec:"required"` + Value []byte `json:"value" gencodec:"required"` + Proof [][]byte `json:"proof" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + Storage []StorageDiff `json:"storage" gencodec:"required"` +} + +// StorageDiff holds the data for a single storage diff node +type StorageDiff struct { + Leaf bool `json:"leaf" gencodec:"required"` + Key []byte `json:"key" gencodec:"required"` + Value []byte `json:"value" gencodec:"required"` + Proof [][]byte `json:"proof" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` +} + +// AccountsMap is a mapping of keccak256(address) => accountWrapper +type AccountsMap map[common.Hash]accountWrapper + +// AccountWrapper is used to temporary associate the unpacked account with its raw values +type accountWrapper struct { + Account *state.Account + Leaf bool + RawKey []byte + RawValue []byte + Proof [][]byte + Path []byte +} diff --git a/vendor/github.com/ethereum/go-ethereum/swarm/README.md b/vendor/github.com/ethereum/go-ethereum/swarm/README.md new file mode 100644 index 00000000..26588318 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/swarm/README.md @@ -0,0 +1,7 @@ +# Swarm + +https://swarm.ethereum.org + +Swarm is a distributed storage platform and content distribution service, a native base layer service of the ethereum web3 stack. The primary objective of Swarm is to provide a decentralized and redundant store for dapp code and data as well as block chain and state data. Swarm is also set out to provide various base layer services for web3, including node-to-node messaging, media streaming, decentralised database services and scalable state-channel infrastructure for decentralised service economies. + +**Note**: The codebase has been moved to [ethersphere/swarm](https://github.com/ethersphere/swarm) diff --git a/vendor/github.com/ethereum/go-ethereum/tests/block_test_util.go b/vendor/github.com/ethereum/go-ethereum/tests/block_test_util.go new file mode 100644 index 00000000..81dd7b1d --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/tests/block_test_util.go @@ -0,0 +1,304 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package tests implements execution of Ethereum JSON tests. +package tests + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// A BlockTest checks handling of entire blocks. +type BlockTest struct { + json btJSON +} + +// UnmarshalJSON implements json.Unmarshaler interface. +func (t *BlockTest) UnmarshalJSON(in []byte) error { + return json.Unmarshal(in, &t.json) +} + +type btJSON struct { + Blocks []btBlock `json:"blocks"` + Genesis btHeader `json:"genesisBlockHeader"` + Pre core.GenesisAlloc `json:"pre"` + Post core.GenesisAlloc `json:"postState"` + BestBlock common.UnprefixedHash `json:"lastblockhash"` + Network string `json:"network"` + SealEngine string `json:"sealEngine"` +} + +type btBlock struct { + BlockHeader *btHeader + Rlp string + UncleHeaders []*btHeader +} + +//go:generate gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go + +type btHeader struct { + Bloom types.Bloom + Coinbase common.Address + MixHash common.Hash + Nonce types.BlockNonce + Number *big.Int + Hash common.Hash + ParentHash common.Hash + ReceiptTrie common.Hash + StateRoot common.Hash + TransactionsTrie common.Hash + UncleHash common.Hash + ExtraData []byte + Difficulty *big.Int + GasLimit uint64 + GasUsed uint64 + Timestamp uint64 +} + +type btHeaderMarshaling struct { + ExtraData hexutil.Bytes + Number *math.HexOrDecimal256 + Difficulty *math.HexOrDecimal256 + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 +} + +func (t *BlockTest) Run() error { + config, ok := Forks[t.json.Network] + if !ok { + return UnsupportedForkError{t.json.Network} + } + + // import pre accounts & construct test genesis block & state root + db := rawdb.NewMemoryDatabase() + gblock, err := t.genesis(config).Commit(db) + if err != nil { + return err + } + if gblock.Hash() != t.json.Genesis.Hash { + return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6]) + } + if gblock.Root() != t.json.Genesis.StateRoot { + return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes()[:6], t.json.Genesis.StateRoot[:6]) + } + var engine consensus.Engine + if t.json.SealEngine == "NoProof" { + engine = ethash.NewFaker() + } else { + engine = ethash.NewShared() + } + chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanLimit: 0}, config, engine, vm.Config{}, nil) + if err != nil { + return err + } + defer chain.Stop() + + validBlocks, err := t.insertBlocks(chain) + if err != nil { + return err + } + cmlast := chain.CurrentBlock().Hash() + if common.Hash(t.json.BestBlock) != cmlast { + return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast) + } + newDB, err := chain.State() + if err != nil { + return err + } + if err = t.validatePostState(newDB); err != nil { + return fmt.Errorf("post state validation failed: %v", err) + } + return t.validateImportedHeaders(chain, validBlocks) +} + +func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { + return &core.Genesis{ + Config: config, + Nonce: t.json.Genesis.Nonce.Uint64(), + Timestamp: t.json.Genesis.Timestamp, + ParentHash: t.json.Genesis.ParentHash, + ExtraData: t.json.Genesis.ExtraData, + GasLimit: t.json.Genesis.GasLimit, + GasUsed: t.json.Genesis.GasUsed, + Difficulty: t.json.Genesis.Difficulty, + Mixhash: t.json.Genesis.MixHash, + Coinbase: t.json.Genesis.Coinbase, + Alloc: t.json.Pre, + } +} + +/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II + + Whether a block is valid or not is a bit subtle, it's defined by presence of + blockHeader, transactions and uncleHeaders fields. If they are missing, the block is + invalid and we must verify that we do not accept it. + + Since some tests mix valid and invalid blocks we need to check this for every block. + + If a block is invalid it does not necessarily fail the test, if it's invalidness is + expected we are expected to ignore it and continue processing and then validate the + post state. +*/ +func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) { + validBlocks := make([]btBlock, 0) + // insert the test blocks, which will execute all transactions + for _, b := range t.json.Blocks { + cb, err := b.decode() + if err != nil { + if b.BlockHeader == nil { + continue // OK - block is supposed to be invalid, continue with next block + } else { + return nil, fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err) + } + } + // RLP decoding worked, try to insert into chain: + blocks := types.Blocks{cb} + i, err := blockchain.InsertChain(blocks) + if err != nil { + if b.BlockHeader == nil { + continue // OK - block is supposed to be invalid, continue with next block + } else { + return nil, fmt.Errorf("Block #%v insertion into chain failed: %v", blocks[i].Number(), err) + } + } + if b.BlockHeader == nil { + return nil, fmt.Errorf("Block insertion should have failed") + } + + // validate RLP decoding by checking all values against test file JSON + if err = validateHeader(b.BlockHeader, cb.Header()); err != nil { + return nil, fmt.Errorf("Deserialised block header validation failed: %v", err) + } + validBlocks = append(validBlocks, b) + } + return validBlocks, nil +} + +func validateHeader(h *btHeader, h2 *types.Header) error { + if h.Bloom != h2.Bloom { + return fmt.Errorf("Bloom: want: %x have: %x", h.Bloom, h2.Bloom) + } + if h.Coinbase != h2.Coinbase { + return fmt.Errorf("Coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase) + } + if h.MixHash != h2.MixDigest { + return fmt.Errorf("MixHash: want: %x have: %x", h.MixHash, h2.MixDigest) + } + if h.Nonce != h2.Nonce { + return fmt.Errorf("Nonce: want: %x have: %x", h.Nonce, h2.Nonce) + } + if h.Number.Cmp(h2.Number) != 0 { + return fmt.Errorf("Number: want: %v have: %v", h.Number, h2.Number) + } + if h.ParentHash != h2.ParentHash { + return fmt.Errorf("Parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash) + } + if h.ReceiptTrie != h2.ReceiptHash { + return fmt.Errorf("Receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash) + } + if h.TransactionsTrie != h2.TxHash { + return fmt.Errorf("Tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash) + } + if h.StateRoot != h2.Root { + return fmt.Errorf("State hash: want: %x have: %x", h.StateRoot, h2.Root) + } + if h.UncleHash != h2.UncleHash { + return fmt.Errorf("Uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash) + } + if !bytes.Equal(h.ExtraData, h2.Extra) { + return fmt.Errorf("Extra data: want: %x have: %x", h.ExtraData, h2.Extra) + } + if h.Difficulty.Cmp(h2.Difficulty) != 0 { + return fmt.Errorf("Difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty) + } + if h.GasLimit != h2.GasLimit { + return fmt.Errorf("GasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit) + } + if h.GasUsed != h2.GasUsed { + return fmt.Errorf("GasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed) + } + if h.Timestamp != h2.Time { + return fmt.Errorf("Timestamp: want: %v have: %v", h.Timestamp, h2.Time) + } + return nil +} + +func (t *BlockTest) validatePostState(statedb *state.StateDB) error { + // validate post state accounts in test file against what we have in state db + for addr, acct := range t.json.Post { + // address is indirectly verified by the other fields, as it's the db key + code2 := statedb.GetCode(addr) + balance2 := statedb.GetBalance(addr) + nonce2 := statedb.GetNonce(addr) + if !bytes.Equal(code2, acct.Code) { + return fmt.Errorf("account code mismatch for addr: %s want: %v have: %s", addr, acct.Code, hex.EncodeToString(code2)) + } + if balance2.Cmp(acct.Balance) != 0 { + return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addr, acct.Balance, balance2) + } + if nonce2 != acct.Nonce { + return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2) + } + } + return nil +} + +func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []btBlock) error { + // to get constant lookup when verifying block headers by hash (some tests have many blocks) + bmap := make(map[common.Hash]btBlock, len(t.json.Blocks)) + for _, b := range validBlocks { + bmap[b.BlockHeader.Hash] = b + } + // iterate over blocks backwards from HEAD and validate imported + // headers vs test file. some tests have reorgs, and we import + // block-by-block, so we can only validate imported headers after + // all blocks have been processed by BlockChain, as they may not + // be part of the longest chain until last block is imported. + for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlockByHash(b.Header().ParentHash) { + if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil { + return fmt.Errorf("Imported block header validation failed: %v", err) + } + } + return nil +} + +func (bb *btBlock) decode() (*types.Block, error) { + data, err := hexutil.Decode(bb.Rlp) + if err != nil { + return nil, err + } + var b types.Block + err = rlp.DecodeBytes(data, &b) + return &b, err +} diff --git a/vendor/github.com/ethereum/go-ethereum/tests/difficulty_test_util.go b/vendor/github.com/ethereum/go-ethereum/tests/difficulty_test_util.go new file mode 100644 index 00000000..fe6e90b0 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/tests/difficulty_test_util.go @@ -0,0 +1,69 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tests + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +//go:generate gencodec -type DifficultyTest -field-override difficultyTestMarshaling -out gen_difficultytest.go + +type DifficultyTest struct { + ParentTimestamp uint64 `json:"parentTimestamp"` + ParentDifficulty *big.Int `json:"parentDifficulty"` + UncleHash common.Hash `json:"parentUncles"` + CurrentTimestamp uint64 `json:"currentTimestamp"` + CurrentBlockNumber uint64 `json:"currentBlockNumber"` + CurrentDifficulty *big.Int `json:"currentDifficulty"` +} + +type difficultyTestMarshaling struct { + ParentTimestamp math.HexOrDecimal64 + ParentDifficulty *math.HexOrDecimal256 + CurrentTimestamp math.HexOrDecimal64 + CurrentDifficulty *math.HexOrDecimal256 + UncleHash common.Hash + CurrentBlockNumber math.HexOrDecimal64 +} + +func (test *DifficultyTest) Run(config *params.ChainConfig) error { + parentNumber := big.NewInt(int64(test.CurrentBlockNumber - 1)) + parent := &types.Header{ + Difficulty: test.ParentDifficulty, + Time: test.ParentTimestamp, + Number: parentNumber, + UncleHash: test.UncleHash, + } + + actual := ethash.CalcDifficulty(config, test.CurrentTimestamp, parent) + exp := test.CurrentDifficulty + + if actual.Cmp(exp) != 0 { + return fmt.Errorf("parent[time %v diff %v unclehash:%x] child[time %v number %v] diff %v != expected %v", + test.ParentTimestamp, test.ParentDifficulty, test.UncleHash, + test.CurrentTimestamp, test.CurrentBlockNumber, actual, exp) + } + return nil + +} diff --git a/vendor/github.com/ethereum/go-ethereum/tests/gen_btheader.go b/vendor/github.com/ethereum/go-ethereum/tests/gen_btheader.go new file mode 100644 index 00000000..f2e086a7 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/tests/gen_btheader.go @@ -0,0 +1,130 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package tests + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" +) + +var _ = (*btHeaderMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (b btHeader) MarshalJSON() ([]byte, error) { + type btHeader struct { + Bloom types.Bloom + Coinbase common.Address + MixHash common.Hash + Nonce types.BlockNonce + Number *math.HexOrDecimal256 + Hash common.Hash + ParentHash common.Hash + ReceiptTrie common.Hash + StateRoot common.Hash + TransactionsTrie common.Hash + UncleHash common.Hash + ExtraData hexutil.Bytes + Difficulty *math.HexOrDecimal256 + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 + } + var enc btHeader + enc.Bloom = b.Bloom + enc.Coinbase = b.Coinbase + enc.MixHash = b.MixHash + enc.Nonce = b.Nonce + enc.Number = (*math.HexOrDecimal256)(b.Number) + enc.Hash = b.Hash + enc.ParentHash = b.ParentHash + enc.ReceiptTrie = b.ReceiptTrie + enc.StateRoot = b.StateRoot + enc.TransactionsTrie = b.TransactionsTrie + enc.UncleHash = b.UncleHash + enc.ExtraData = b.ExtraData + enc.Difficulty = (*math.HexOrDecimal256)(b.Difficulty) + enc.GasLimit = math.HexOrDecimal64(b.GasLimit) + enc.GasUsed = math.HexOrDecimal64(b.GasUsed) + enc.Timestamp = math.HexOrDecimal64(b.Timestamp) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (b *btHeader) UnmarshalJSON(input []byte) error { + type btHeader struct { + Bloom *types.Bloom + Coinbase *common.Address + MixHash *common.Hash + Nonce *types.BlockNonce + Number *math.HexOrDecimal256 + Hash *common.Hash + ParentHash *common.Hash + ReceiptTrie *common.Hash + StateRoot *common.Hash + TransactionsTrie *common.Hash + UncleHash *common.Hash + ExtraData *hexutil.Bytes + Difficulty *math.HexOrDecimal256 + GasLimit *math.HexOrDecimal64 + GasUsed *math.HexOrDecimal64 + Timestamp *math.HexOrDecimal64 + } + var dec btHeader + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.Bloom != nil { + b.Bloom = *dec.Bloom + } + if dec.Coinbase != nil { + b.Coinbase = *dec.Coinbase + } + if dec.MixHash != nil { + b.MixHash = *dec.MixHash + } + if dec.Nonce != nil { + b.Nonce = *dec.Nonce + } + if dec.Number != nil { + b.Number = (*big.Int)(dec.Number) + } + if dec.Hash != nil { + b.Hash = *dec.Hash + } + if dec.ParentHash != nil { + b.ParentHash = *dec.ParentHash + } + if dec.ReceiptTrie != nil { + b.ReceiptTrie = *dec.ReceiptTrie + } + if dec.StateRoot != nil { + b.StateRoot = *dec.StateRoot + } + if dec.TransactionsTrie != nil { + b.TransactionsTrie = *dec.TransactionsTrie + } + if dec.UncleHash != nil { + b.UncleHash = *dec.UncleHash + } + if dec.ExtraData != nil { + b.ExtraData = *dec.ExtraData + } + if dec.Difficulty != nil { + b.Difficulty = (*big.Int)(dec.Difficulty) + } + if dec.GasLimit != nil { + b.GasLimit = uint64(*dec.GasLimit) + } + if dec.GasUsed != nil { + b.GasUsed = uint64(*dec.GasUsed) + } + if dec.Timestamp != nil { + b.Timestamp = uint64(*dec.Timestamp) + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/tests/gen_difficultytest.go b/vendor/github.com/ethereum/go-ethereum/tests/gen_difficultytest.go new file mode 100644 index 00000000..cd15ae31 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/tests/gen_difficultytest.go @@ -0,0 +1,68 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package tests + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" +) + +var _ = (*difficultyTestMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (d DifficultyTest) MarshalJSON() ([]byte, error) { + type DifficultyTest struct { + ParentTimestamp math.HexOrDecimal64 `json:"parentTimestamp"` + ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` + UncleHash common.Hash `json:"parentUncles"` + CurrentTimestamp math.HexOrDecimal64 `json:"currentTimestamp"` + CurrentBlockNumber math.HexOrDecimal64 `json:"currentBlockNumber"` + CurrentDifficulty *math.HexOrDecimal256 `json:"currentDifficulty"` + } + var enc DifficultyTest + enc.ParentTimestamp = math.HexOrDecimal64(d.ParentTimestamp) + enc.ParentDifficulty = (*math.HexOrDecimal256)(d.ParentDifficulty) + enc.UncleHash = d.UncleHash + enc.CurrentTimestamp = math.HexOrDecimal64(d.CurrentTimestamp) + enc.CurrentBlockNumber = math.HexOrDecimal64(d.CurrentBlockNumber) + enc.CurrentDifficulty = (*math.HexOrDecimal256)(d.CurrentDifficulty) + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (d *DifficultyTest) UnmarshalJSON(input []byte) error { + type DifficultyTest struct { + ParentTimestamp *math.HexOrDecimal64 `json:"parentTimestamp"` + ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"` + UncleHash *common.Hash `json:"parentUncles"` + CurrentTimestamp *math.HexOrDecimal64 `json:"currentTimestamp"` + CurrentBlockNumber *math.HexOrDecimal64 `json:"currentBlockNumber"` + CurrentDifficulty *math.HexOrDecimal256 `json:"currentDifficulty"` + } + var dec DifficultyTest + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ParentTimestamp != nil { + d.ParentTimestamp = uint64(*dec.ParentTimestamp) + } + if dec.ParentDifficulty != nil { + d.ParentDifficulty = (*big.Int)(dec.ParentDifficulty) + } + if dec.UncleHash != nil { + d.UncleHash = *dec.UncleHash + } + if dec.CurrentTimestamp != nil { + d.CurrentTimestamp = uint64(*dec.CurrentTimestamp) + } + if dec.CurrentBlockNumber != nil { + d.CurrentBlockNumber = uint64(*dec.CurrentBlockNumber) + } + if dec.CurrentDifficulty != nil { + d.CurrentDifficulty = (*big.Int)(dec.CurrentDifficulty) + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/tests/transaction_test_util.go b/vendor/github.com/ethereum/go-ethereum/tests/transaction_test_util.go new file mode 100644 index 00000000..12444720 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/tests/transaction_test_util.go @@ -0,0 +1,108 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tests + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// TransactionTest checks RLP decoding and sender derivation of transactions. +type TransactionTest struct { + RLP hexutil.Bytes `json:"rlp"` + Byzantium ttFork + Constantinople ttFork + EIP150 ttFork + EIP158 ttFork + Frontier ttFork + Homestead ttFork +} + +type ttFork struct { + Sender common.UnprefixedAddress `json:"sender"` + Hash common.UnprefixedHash `json:"hash"` +} + +func (tt *TransactionTest) Run(config *params.ChainConfig) error { + + validateTx := func(rlpData hexutil.Bytes, signer types.Signer, isHomestead bool) (*common.Address, *common.Hash, error) { + tx := new(types.Transaction) + if err := rlp.DecodeBytes(rlpData, tx); err != nil { + return nil, nil, err + } + sender, err := types.Sender(signer, tx) + if err != nil { + return nil, nil, err + } + // Intrinsic gas + requiredGas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, isHomestead) + if err != nil { + return nil, nil, err + } + if requiredGas > tx.Gas() { + return nil, nil, fmt.Errorf("insufficient gas ( %d < %d )", tx.Gas(), requiredGas) + } + h := tx.Hash() + return &sender, &h, nil + } + + for _, testcase := range []struct { + name string + signer types.Signer + fork ttFork + isHomestead bool + }{ + {"Frontier", types.FrontierSigner{}, tt.Frontier, false}, + {"Homestead", types.HomesteadSigner{}, tt.Homestead, true}, + {"EIP150", types.HomesteadSigner{}, tt.EIP150, true}, + {"EIP158", types.NewEIP155Signer(config.ChainID), tt.EIP158, true}, + {"Byzantium", types.NewEIP155Signer(config.ChainID), tt.Byzantium, true}, + {"Constantinople", types.NewEIP155Signer(config.ChainID), tt.Constantinople, true}, + } { + sender, txhash, err := validateTx(tt.RLP, testcase.signer, testcase.isHomestead) + + if testcase.fork.Sender == (common.UnprefixedAddress{}) { + if err == nil { + return fmt.Errorf("Expected error, got none (address %v)", sender.String()) + } + continue + } + // Should resolve the right address + if err != nil { + return fmt.Errorf("Got error, expected none: %v", err) + } + if sender == nil { + return fmt.Errorf("sender was nil, should be %x", common.Address(testcase.fork.Sender)) + } + if *sender != common.Address(testcase.fork.Sender) { + return fmt.Errorf("Sender mismatch: got %x, want %x", sender, testcase.fork.Sender) + } + if txhash == nil { + return fmt.Errorf("txhash was nil, should be %x", common.Hash(testcase.fork.Hash)) + } + if *txhash != common.Hash(testcase.fork.Hash) { + return fmt.Errorf("Hash mismatch: got %x, want %x", *txhash, testcase.fork.Hash) + } + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/database.go b/vendor/github.com/ethereum/go-ethereum/trie/database.go new file mode 100644 index 00000000..d8a0fa9c --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/database.go @@ -0,0 +1,901 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "reflect" + "sync" + "time" + + "github.com/allegro/bigcache" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + memcacheCleanHitMeter = metrics.NewRegisteredMeter("trie/memcache/clean/hit", nil) + memcacheCleanMissMeter = metrics.NewRegisteredMeter("trie/memcache/clean/miss", nil) + memcacheCleanReadMeter = metrics.NewRegisteredMeter("trie/memcache/clean/read", nil) + memcacheCleanWriteMeter = metrics.NewRegisteredMeter("trie/memcache/clean/write", nil) + + memcacheFlushTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/flush/time", nil) + memcacheFlushNodesMeter = metrics.NewRegisteredMeter("trie/memcache/flush/nodes", nil) + memcacheFlushSizeMeter = metrics.NewRegisteredMeter("trie/memcache/flush/size", nil) + + memcacheGCTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/gc/time", nil) + memcacheGCNodesMeter = metrics.NewRegisteredMeter("trie/memcache/gc/nodes", nil) + memcacheGCSizeMeter = metrics.NewRegisteredMeter("trie/memcache/gc/size", nil) + + memcacheCommitTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/commit/time", nil) + memcacheCommitNodesMeter = metrics.NewRegisteredMeter("trie/memcache/commit/nodes", nil) + memcacheCommitSizeMeter = metrics.NewRegisteredMeter("trie/memcache/commit/size", nil) +) + +// secureKeyPrefix is the database key prefix used to store trie node preimages. +var secureKeyPrefix = []byte("secure-key-") + +// secureKeyLength is the length of the above prefix + 32byte hash. +const secureKeyLength = 11 + 32 + +// Database is an intermediate write layer between the trie data structures and +// the disk database. The aim is to accumulate trie writes in-memory and only +// periodically flush a couple tries to disk, garbage collecting the remainder. +// +// Note, the trie Database is **not** thread safe in its mutations, but it **is** +// thread safe in providing individual, independent node access. The rationale +// behind this split design is to provide read access to RPC handlers and sync +// servers even while the trie is executing expensive garbage collection. +type Database struct { + diskdb ethdb.KeyValueStore // Persistent storage for matured trie nodes + + cleans *bigcache.BigCache // GC friendly memory cache of clean node RLPs + dirties map[common.Hash]*cachedNode // Data and references relationships of dirty nodes + oldest common.Hash // Oldest tracked node, flush-list head + newest common.Hash // Newest tracked node, flush-list tail + + preimages map[common.Hash][]byte // Preimages of nodes from the secure trie + seckeybuf [secureKeyLength]byte // Ephemeral buffer for calculating preimage keys + + gctime time.Duration // Time spent on garbage collection since last commit + gcnodes uint64 // Nodes garbage collected since last commit + gcsize common.StorageSize // Data storage garbage collected since last commit + + flushtime time.Duration // Time spent on data flushing since last commit + flushnodes uint64 // Nodes flushed since last commit + flushsize common.StorageSize // Data storage flushed since last commit + + dirtiesSize common.StorageSize // Storage size of the dirty node cache (exc. metadata) + childrenSize common.StorageSize // Storage size of the external children tracking + preimagesSize common.StorageSize // Storage size of the preimages cache + + lock sync.RWMutex +} + +// rawNode is a simple binary blob used to differentiate between collapsed trie +// nodes and already encoded RLP binary blobs (while at the same time store them +// in the same cache fields). +type rawNode []byte + +func (n rawNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +func (n rawNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } +func (n rawNode) fstring(ind string) string { panic("this should never end up in a live trie") } + +// rawFullNode represents only the useful data content of a full node, with the +// caches and flags stripped out to minimize its data storage. This type honors +// the same RLP encoding as the original parent. +type rawFullNode [17]node + +func (n rawFullNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +func (n rawFullNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } +func (n rawFullNode) fstring(ind string) string { panic("this should never end up in a live trie") } + +func (n rawFullNode) EncodeRLP(w io.Writer) error { + var nodes [17]node + + for i, child := range n { + if child != nil { + nodes[i] = child + } else { + nodes[i] = nilValueNode + } + } + return rlp.Encode(w, nodes) +} + +// rawShortNode represents only the useful data content of a short node, with the +// caches and flags stripped out to minimize its data storage. This type honors +// the same RLP encoding as the original parent. +type rawShortNode struct { + Key []byte + Val node +} + +func (n rawShortNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +func (n rawShortNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } +func (n rawShortNode) fstring(ind string) string { panic("this should never end up in a live trie") } + +// cachedNode is all the information we know about a single cached node in the +// memory database write layer. +type cachedNode struct { + node node // Cached collapsed trie node, or raw rlp data + size uint16 // Byte size of the useful cached data + + parents uint32 // Number of live nodes referencing this one + children map[common.Hash]uint16 // External children referenced by this node + + flushPrev common.Hash // Previous node in the flush-list + flushNext common.Hash // Next node in the flush-list +} + +// cachedNodeSize is the raw size of a cachedNode data structure without any +// node data included. It's an approximate size, but should be a lot better +// than not counting them. +var cachedNodeSize = int(reflect.TypeOf(cachedNode{}).Size()) + +// cachedNodeChildrenSize is the raw size of an initialized but empty external +// reference map. +const cachedNodeChildrenSize = 48 + +// rlp returns the raw rlp encoded blob of the cached node, either directly from +// the cache, or by regenerating it from the collapsed node. +func (n *cachedNode) rlp() []byte { + if node, ok := n.node.(rawNode); ok { + return node + } + blob, err := rlp.EncodeToBytes(n.node) + if err != nil { + panic(err) + } + return blob +} + +// obj returns the decoded and expanded trie node, either directly from the cache, +// or by regenerating it from the rlp encoded blob. +func (n *cachedNode) obj(hash common.Hash) node { + if node, ok := n.node.(rawNode); ok { + return mustDecodeNode(hash[:], node) + } + return expandNode(hash[:], n.node) +} + +// childs returns all the tracked children of this node, both the implicit ones +// from inside the node as well as the explicit ones from outside the node. +func (n *cachedNode) childs() []common.Hash { + children := make([]common.Hash, 0, 16) + for child := range n.children { + children = append(children, child) + } + if _, ok := n.node.(rawNode); !ok { + gatherChildren(n.node, &children) + } + return children +} + +// gatherChildren traverses the node hierarchy of a collapsed storage node and +// retrieves all the hashnode children. +func gatherChildren(n node, children *[]common.Hash) { + switch n := n.(type) { + case *rawShortNode: + gatherChildren(n.Val, children) + + case rawFullNode: + for i := 0; i < 16; i++ { + gatherChildren(n[i], children) + } + case hashNode: + *children = append(*children, common.BytesToHash(n)) + + case valueNode, nil: + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } +} + +// simplifyNode traverses the hierarchy of an expanded memory node and discards +// all the internal caches, returning a node that only contains the raw data. +func simplifyNode(n node) node { + switch n := n.(type) { + case *shortNode: + // Short nodes discard the flags and cascade + return &rawShortNode{Key: n.Key, Val: simplifyNode(n.Val)} + + case *fullNode: + // Full nodes discard the flags and cascade + node := rawFullNode(n.Children) + for i := 0; i < len(node); i++ { + if node[i] != nil { + node[i] = simplifyNode(node[i]) + } + } + return node + + case valueNode, hashNode, rawNode: + return n + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } +} + +// expandNode traverses the node hierarchy of a collapsed storage node and converts +// all fields and keys into expanded memory form. +func expandNode(hash hashNode, n node) node { + switch n := n.(type) { + case *rawShortNode: + // Short nodes need key and child expansion + return &shortNode{ + Key: compactToHex(n.Key), + Val: expandNode(nil, n.Val), + flags: nodeFlag{ + hash: hash, + }, + } + + case rawFullNode: + // Full nodes need child expansion + node := &fullNode{ + flags: nodeFlag{ + hash: hash, + }, + } + for i := 0; i < len(node.Children); i++ { + if n[i] != nil { + node.Children[i] = expandNode(nil, n[i]) + } + } + return node + + case valueNode, hashNode: + return n + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } +} + +// trienodeHasher is a struct to be used with BigCache, which uses a Hasher to +// determine which shard to place an entry into. It's not a cryptographic hash, +// just to provide a bit of anti-collision (default is FNV64a). +// +// Since trie keys are already hashes, we can just use the key directly to +// map shard id. +type trienodeHasher struct{} + +// Sum64 implements the bigcache.Hasher interface. +func (t trienodeHasher) Sum64(key string) uint64 { + return binary.BigEndian.Uint64([]byte(key)) +} + +// NewDatabase creates a new trie database to store ephemeral trie content before +// its written out to disk or garbage collected. No read cache is created, so all +// data retrievals will hit the underlying disk database. +func NewDatabase(diskdb ethdb.KeyValueStore) *Database { + return NewDatabaseWithCache(diskdb, 0) +} + +// NewDatabaseWithCache creates a new trie database to store ephemeral trie content +// before its written out to disk or garbage collected. It also acts as a read cache +// for nodes loaded from disk. +func NewDatabaseWithCache(diskdb ethdb.KeyValueStore, cache int) *Database { + var cleans *bigcache.BigCache + if cache > 0 { + cleans, _ = bigcache.NewBigCache(bigcache.Config{ + Shards: 1024, + LifeWindow: time.Hour, + MaxEntriesInWindow: cache * 1024, + MaxEntrySize: 512, + HardMaxCacheSize: cache, + Hasher: trienodeHasher{}, + }) + } + return &Database{ + diskdb: diskdb, + cleans: cleans, + dirties: map[common.Hash]*cachedNode{{}: { + children: make(map[common.Hash]uint16), + }}, + preimages: make(map[common.Hash][]byte), + } +} + +// DiskDB retrieves the persistent storage backing the trie database. +func (db *Database) DiskDB() ethdb.KeyValueReader { + return db.diskdb +} + +// InsertBlob writes a new reference tracked blob to the memory database if it's +// yet unknown. This method should only be used for non-trie nodes that require +// reference counting, since trie nodes are garbage collected directly through +// their embedded children. +func (db *Database) InsertBlob(hash common.Hash, blob []byte) { + db.lock.Lock() + defer db.lock.Unlock() + + db.insert(hash, blob, rawNode(blob)) +} + +// insert inserts a collapsed trie node into the memory database. This method is +// a more generic version of InsertBlob, supporting both raw blob insertions as +// well ex trie node insertions. The blob must always be specified to allow proper +// size tracking. +func (db *Database) insert(hash common.Hash, blob []byte, node node) { + // If the node's already cached, skip + if _, ok := db.dirties[hash]; ok { + return + } + // Create the cached entry for this node + entry := &cachedNode{ + node: simplifyNode(node), + size: uint16(len(blob)), + flushPrev: db.newest, + } + for _, child := range entry.childs() { + if c := db.dirties[child]; c != nil { + c.parents++ + } + } + db.dirties[hash] = entry + + // Update the flush-list endpoints + if db.oldest == (common.Hash{}) { + db.oldest, db.newest = hash, hash + } else { + db.dirties[db.newest].flushNext, db.newest = hash, hash + } + db.dirtiesSize += common.StorageSize(common.HashLength + entry.size) +} + +// insertPreimage writes a new trie node pre-image to the memory database if it's +// yet unknown. The method will make a copy of the slice. +// +// Note, this method assumes that the database's lock is held! +func (db *Database) insertPreimage(hash common.Hash, preimage []byte) { + if _, ok := db.preimages[hash]; ok { + return + } + db.preimages[hash] = common.CopyBytes(preimage) + db.preimagesSize += common.StorageSize(common.HashLength + len(preimage)) +} + +// node retrieves a cached trie node from memory, or returns nil if none can be +// found in the memory cache. +func (db *Database) node(hash common.Hash) node { + // Retrieve the node from the clean cache if available + if db.cleans != nil { + if enc, err := db.cleans.Get(string(hash[:])); err == nil && enc != nil { + memcacheCleanHitMeter.Mark(1) + memcacheCleanReadMeter.Mark(int64(len(enc))) + return mustDecodeNode(hash[:], enc) + } + } + // Retrieve the node from the dirty cache if available + db.lock.RLock() + dirty := db.dirties[hash] + db.lock.RUnlock() + + if dirty != nil { + return dirty.obj(hash) + } + // Content unavailable in memory, attempt to retrieve from disk + enc, err := db.diskdb.Get(hash[:]) + if err != nil || enc == nil { + return nil + } + if db.cleans != nil { + db.cleans.Set(string(hash[:]), enc) + memcacheCleanMissMeter.Mark(1) + memcacheCleanWriteMeter.Mark(int64(len(enc))) + } + return mustDecodeNode(hash[:], enc) +} + +// Node retrieves an encoded cached trie node from memory. If it cannot be found +// cached, the method queries the persistent database for the content. +func (db *Database) Node(hash common.Hash) ([]byte, error) { + // It doens't make sense to retrieve the metaroot + if hash == (common.Hash{}) { + return nil, errors.New("not found") + } + // Retrieve the node from the clean cache if available + if db.cleans != nil { + if enc, err := db.cleans.Get(string(hash[:])); err == nil && enc != nil { + memcacheCleanHitMeter.Mark(1) + memcacheCleanReadMeter.Mark(int64(len(enc))) + return enc, nil + } + } + // Retrieve the node from the dirty cache if available + db.lock.RLock() + dirty := db.dirties[hash] + db.lock.RUnlock() + + if dirty != nil { + return dirty.rlp(), nil + } + // Content unavailable in memory, attempt to retrieve from disk + enc, err := db.diskdb.Get(hash[:]) + if err == nil && enc != nil { + if db.cleans != nil { + db.cleans.Set(string(hash[:]), enc) + memcacheCleanMissMeter.Mark(1) + memcacheCleanWriteMeter.Mark(int64(len(enc))) + } + } + return enc, err +} + +// preimage retrieves a cached trie node pre-image from memory. If it cannot be +// found cached, the method queries the persistent database for the content. +func (db *Database) preimage(hash common.Hash) ([]byte, error) { + // Retrieve the node from cache if available + db.lock.RLock() + preimage := db.preimages[hash] + db.lock.RUnlock() + + if preimage != nil { + return preimage, nil + } + // Content unavailable in memory, attempt to retrieve from disk + return db.diskdb.Get(db.secureKey(hash[:])) +} + +// secureKey returns the database key for the preimage of key, as an ephemeral +// buffer. The caller must not hold onto the return value because it will become +// invalid on the next call. +func (db *Database) secureKey(key []byte) []byte { + buf := append(db.seckeybuf[:0], secureKeyPrefix...) + buf = append(buf, key...) + return buf +} + +// Nodes retrieves the hashes of all the nodes cached within the memory database. +// This method is extremely expensive and should only be used to validate internal +// states in test code. +func (db *Database) Nodes() []common.Hash { + db.lock.RLock() + defer db.lock.RUnlock() + + var hashes = make([]common.Hash, 0, len(db.dirties)) + for hash := range db.dirties { + if hash != (common.Hash{}) { // Special case for "root" references/nodes + hashes = append(hashes, hash) + } + } + return hashes +} + +// Reference adds a new reference from a parent node to a child node. +func (db *Database) Reference(child common.Hash, parent common.Hash) { + db.lock.Lock() + defer db.lock.Unlock() + + db.reference(child, parent) +} + +// reference is the private locked version of Reference. +func (db *Database) reference(child common.Hash, parent common.Hash) { + // If the node does not exist, it's a node pulled from disk, skip + node, ok := db.dirties[child] + if !ok { + return + } + // If the reference already exists, only duplicate for roots + if db.dirties[parent].children == nil { + db.dirties[parent].children = make(map[common.Hash]uint16) + db.childrenSize += cachedNodeChildrenSize + } else if _, ok = db.dirties[parent].children[child]; ok && parent != (common.Hash{}) { + return + } + node.parents++ + db.dirties[parent].children[child]++ + if db.dirties[parent].children[child] == 1 { + db.childrenSize += common.HashLength + 2 // uint16 counter + } +} + +// Dereference removes an existing reference from a root node. +func (db *Database) Dereference(root common.Hash) { + // Sanity check to ensure that the meta-root is not removed + if root == (common.Hash{}) { + log.Error("Attempted to dereference the trie cache meta root") + return + } + db.lock.Lock() + defer db.lock.Unlock() + + nodes, storage, start := len(db.dirties), db.dirtiesSize, time.Now() + db.dereference(root, common.Hash{}) + + db.gcnodes += uint64(nodes - len(db.dirties)) + db.gcsize += storage - db.dirtiesSize + db.gctime += time.Since(start) + + memcacheGCTimeTimer.Update(time.Since(start)) + memcacheGCSizeMeter.Mark(int64(storage - db.dirtiesSize)) + memcacheGCNodesMeter.Mark(int64(nodes - len(db.dirties))) + + log.Debug("Dereferenced trie from memory database", "nodes", nodes-len(db.dirties), "size", storage-db.dirtiesSize, "time", time.Since(start), + "gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.dirties), "livesize", db.dirtiesSize) +} + +// dereference is the private locked version of Dereference. +func (db *Database) dereference(child common.Hash, parent common.Hash) { + // Dereference the parent-child + node := db.dirties[parent] + + if node.children != nil && node.children[child] > 0 { + node.children[child]-- + if node.children[child] == 0 { + delete(node.children, child) + db.childrenSize -= (common.HashLength + 2) // uint16 counter + } + } + // If the child does not exist, it's a previously committed node. + node, ok := db.dirties[child] + if !ok { + return + } + // If there are no more references to the child, delete it and cascade + if node.parents > 0 { + // This is a special cornercase where a node loaded from disk (i.e. not in the + // memcache any more) gets reinjected as a new node (short node split into full, + // then reverted into short), causing a cached node to have no parents. That is + // no problem in itself, but don't make maxint parents out of it. + node.parents-- + } + if node.parents == 0 { + // Remove the node from the flush-list + switch child { + case db.oldest: + db.oldest = node.flushNext + db.dirties[node.flushNext].flushPrev = common.Hash{} + case db.newest: + db.newest = node.flushPrev + db.dirties[node.flushPrev].flushNext = common.Hash{} + default: + db.dirties[node.flushPrev].flushNext = node.flushNext + db.dirties[node.flushNext].flushPrev = node.flushPrev + } + // Dereference all children and delete the node + for _, hash := range node.childs() { + db.dereference(hash, child) + } + delete(db.dirties, child) + db.dirtiesSize -= common.StorageSize(common.HashLength + int(node.size)) + if node.children != nil { + db.childrenSize -= cachedNodeChildrenSize + } + } +} + +// Cap iteratively flushes old but still referenced trie nodes until the total +// memory usage goes below the given threshold. +// +// Note, this method is a non-synchronized mutator. It is unsafe to call this +// concurrently with other mutators. +func (db *Database) Cap(limit common.StorageSize) error { + // Create a database batch to flush persistent data out. It is important that + // outside code doesn't see an inconsistent state (referenced data removed from + // memory cache during commit but not yet in persistent storage). This is ensured + // by only uncaching existing data when the database write finalizes. + nodes, storage, start := len(db.dirties), db.dirtiesSize, time.Now() + batch := db.diskdb.NewBatch() + + // db.dirtiesSize only contains the useful data in the cache, but when reporting + // the total memory consumption, the maintenance metadata is also needed to be + // counted. + size := db.dirtiesSize + common.StorageSize((len(db.dirties)-1)*cachedNodeSize) + size += db.childrenSize - common.StorageSize(len(db.dirties[common.Hash{}].children)*(common.HashLength+2)) + + // If the preimage cache got large enough, push to disk. If it's still small + // leave for later to deduplicate writes. + flushPreimages := db.preimagesSize > 4*1024*1024 + if flushPreimages { + for hash, preimage := range db.preimages { + if err := batch.Put(db.secureKey(hash[:]), preimage); err != nil { + log.Error("Failed to commit preimage from trie database", "err", err) + return err + } + if batch.ValueSize() > ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + } + } + } + // Keep committing nodes from the flush-list until we're below allowance + oldest := db.oldest + for size > limit && oldest != (common.Hash{}) { + // Fetch the oldest referenced node and push into the batch + node := db.dirties[oldest] + if err := batch.Put(oldest[:], node.rlp()); err != nil { + return err + } + // If we exceeded the ideal batch size, commit and reset + if batch.ValueSize() >= ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + log.Error("Failed to write flush list to disk", "err", err) + return err + } + batch.Reset() + } + // Iterate to the next flush item, or abort if the size cap was achieved. Size + // is the total size, including the useful cached data (hash -> blob), the + // cache item metadata, as well as external children mappings. + size -= common.StorageSize(common.HashLength + int(node.size) + cachedNodeSize) + if node.children != nil { + size -= common.StorageSize(cachedNodeChildrenSize + len(node.children)*(common.HashLength+2)) + } + oldest = node.flushNext + } + // Flush out any remainder data from the last batch + if err := batch.Write(); err != nil { + log.Error("Failed to write flush list to disk", "err", err) + return err + } + // Write successful, clear out the flushed data + db.lock.Lock() + defer db.lock.Unlock() + + if flushPreimages { + db.preimages = make(map[common.Hash][]byte) + db.preimagesSize = 0 + } + for db.oldest != oldest { + node := db.dirties[db.oldest] + delete(db.dirties, db.oldest) + db.oldest = node.flushNext + + db.dirtiesSize -= common.StorageSize(common.HashLength + int(node.size)) + if node.children != nil { + db.childrenSize -= common.StorageSize(cachedNodeChildrenSize + len(node.children)*(common.HashLength+2)) + } + } + if db.oldest != (common.Hash{}) { + db.dirties[db.oldest].flushPrev = common.Hash{} + } + db.flushnodes += uint64(nodes - len(db.dirties)) + db.flushsize += storage - db.dirtiesSize + db.flushtime += time.Since(start) + + memcacheFlushTimeTimer.Update(time.Since(start)) + memcacheFlushSizeMeter.Mark(int64(storage - db.dirtiesSize)) + memcacheFlushNodesMeter.Mark(int64(nodes - len(db.dirties))) + + log.Debug("Persisted nodes from memory database", "nodes", nodes-len(db.dirties), "size", storage-db.dirtiesSize, "time", time.Since(start), + "flushnodes", db.flushnodes, "flushsize", db.flushsize, "flushtime", db.flushtime, "livenodes", len(db.dirties), "livesize", db.dirtiesSize) + + return nil +} + +// Commit iterates over all the children of a particular node, writes them out +// to disk, forcefully tearing down all references in both directions. As a side +// effect, all pre-images accumulated up to this point are also written. +// +// Note, this method is a non-synchronized mutator. It is unsafe to call this +// concurrently with other mutators. +func (db *Database) Commit(node common.Hash, report bool) error { + // Create a database batch to flush persistent data out. It is important that + // outside code doesn't see an inconsistent state (referenced data removed from + // memory cache during commit but not yet in persistent storage). This is ensured + // by only uncaching existing data when the database write finalizes. + start := time.Now() + batch := db.diskdb.NewBatch() + + // Move all of the accumulated preimages into a write batch + for hash, preimage := range db.preimages { + if err := batch.Put(db.secureKey(hash[:]), preimage); err != nil { + log.Error("Failed to commit preimage from trie database", "err", err) + return err + } + // If the batch is too large, flush to disk + if batch.ValueSize() > ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + } + } + // Since we're going to replay trie node writes into the clean cache, flush out + // any batched pre-images before continuing. + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + + // Move the trie itself into the batch, flushing if enough data is accumulated + nodes, storage := len(db.dirties), db.dirtiesSize + + uncacher := &cleaner{db} + if err := db.commit(node, batch, uncacher); err != nil { + log.Error("Failed to commit trie from trie database", "err", err) + return err + } + // Trie mostly committed to disk, flush any batch leftovers + if err := batch.Write(); err != nil { + log.Error("Failed to write trie to disk", "err", err) + return err + } + // Uncache any leftovers in the last batch + db.lock.Lock() + defer db.lock.Unlock() + + batch.Replay(uncacher) + batch.Reset() + + // Reset the storage counters and bumpd metrics + db.preimages = make(map[common.Hash][]byte) + db.preimagesSize = 0 + + memcacheCommitTimeTimer.Update(time.Since(start)) + memcacheCommitSizeMeter.Mark(int64(storage - db.dirtiesSize)) + memcacheCommitNodesMeter.Mark(int64(nodes - len(db.dirties))) + + logger := log.Info + if !report { + logger = log.Debug + } + logger("Persisted trie from memory database", "nodes", nodes-len(db.dirties)+int(db.flushnodes), "size", storage-db.dirtiesSize+db.flushsize, "time", time.Since(start)+db.flushtime, + "gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.dirties), "livesize", db.dirtiesSize) + + // Reset the garbage collection statistics + db.gcnodes, db.gcsize, db.gctime = 0, 0, 0 + db.flushnodes, db.flushsize, db.flushtime = 0, 0, 0 + + return nil +} + +// commit is the private locked version of Commit. +func (db *Database) commit(hash common.Hash, batch ethdb.Batch, uncacher *cleaner) error { + // If the node does not exist, it's a previously committed node + node, ok := db.dirties[hash] + if !ok { + return nil + } + for _, child := range node.childs() { + if err := db.commit(child, batch, uncacher); err != nil { + return err + } + } + if err := batch.Put(hash[:], node.rlp()); err != nil { + return err + } + // If we've reached an optimal batch size, commit and start over + if batch.ValueSize() >= ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + return err + } + db.lock.Lock() + batch.Replay(uncacher) + batch.Reset() + db.lock.Unlock() + } + return nil +} + +// cleaner is a database batch replayer that takes a batch of write operations +// and cleans up the trie database from anything written to disk. +type cleaner struct { + db *Database +} + +// Put reacts to database writes and implements dirty data uncaching. This is the +// post-processing step of a commit operation where the already persisted trie is +// removed from the dirty cache and moved into the clean cache. The reason behind +// the two-phase commit is to ensure ensure data availability while moving from +// memory to disk. +func (c *cleaner) Put(key []byte, rlp []byte) error { + hash := common.BytesToHash(key) + + // If the node does not exist, we're done on this path + node, ok := c.db.dirties[hash] + if !ok { + return nil + } + // Node still exists, remove it from the flush-list + switch hash { + case c.db.oldest: + c.db.oldest = node.flushNext + c.db.dirties[node.flushNext].flushPrev = common.Hash{} + case c.db.newest: + c.db.newest = node.flushPrev + c.db.dirties[node.flushPrev].flushNext = common.Hash{} + default: + c.db.dirties[node.flushPrev].flushNext = node.flushNext + c.db.dirties[node.flushNext].flushPrev = node.flushPrev + } + // Remove the node from the dirty cache + delete(c.db.dirties, hash) + c.db.dirtiesSize -= common.StorageSize(common.HashLength + int(node.size)) + if node.children != nil { + c.db.dirtiesSize -= common.StorageSize(cachedNodeChildrenSize + len(node.children)*(common.HashLength+2)) + } + // Move the flushed node into the clean cache to prevent insta-reloads + if c.db.cleans != nil { + c.db.cleans.Set(string(hash[:]), rlp) + } + return nil +} + +func (c *cleaner) Delete(key []byte) error { + panic("Not implemented") +} + +// Size returns the current storage size of the memory cache in front of the +// persistent database layer. +func (db *Database) Size() (common.StorageSize, common.StorageSize) { + db.lock.RLock() + defer db.lock.RUnlock() + + // db.dirtiesSize only contains the useful data in the cache, but when reporting + // the total memory consumption, the maintenance metadata is also needed to be + // counted. + var metadataSize = common.StorageSize((len(db.dirties) - 1) * cachedNodeSize) + var metarootRefs = common.StorageSize(len(db.dirties[common.Hash{}].children) * (common.HashLength + 2)) + return db.dirtiesSize + db.childrenSize + metadataSize - metarootRefs, db.preimagesSize +} + +// verifyIntegrity is a debug method to iterate over the entire trie stored in +// memory and check whether every node is reachable from the meta root. The goal +// is to find any errors that might cause memory leaks and or trie nodes to go +// missing. +// +// This method is extremely CPU and memory intensive, only use when must. +func (db *Database) verifyIntegrity() { + // Iterate over all the cached nodes and accumulate them into a set + reachable := map[common.Hash]struct{}{{}: {}} + + for child := range db.dirties[common.Hash{}].children { + db.accumulate(child, reachable) + } + // Find any unreachable but cached nodes + var unreachable []string + for hash, node := range db.dirties { + if _, ok := reachable[hash]; !ok { + unreachable = append(unreachable, fmt.Sprintf("%x: {Node: %v, Parents: %d, Prev: %x, Next: %x}", + hash, node.node, node.parents, node.flushPrev, node.flushNext)) + } + } + if len(unreachable) != 0 { + panic(fmt.Sprintf("trie cache memory leak: %v", unreachable)) + } +} + +// accumulate iterates over the trie defined by hash and accumulates all the +// cached children found in memory. +func (db *Database) accumulate(hash common.Hash, reachable map[common.Hash]struct{}) { + // Mark the node reachable if present in the memory cache + node, ok := db.dirties[hash] + if !ok { + return + } + reachable[hash] = struct{}{} + + // Iterate over all the children and accumulate them too + for _, child := range node.childs() { + db.accumulate(child, reachable) + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/encoding.go b/vendor/github.com/ethereum/go-ethereum/trie/encoding.go new file mode 100644 index 00000000..425326db --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/encoding.go @@ -0,0 +1,116 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +// Trie keys are dealt with in three distinct encodings: +// +// KEYBYTES encoding contains the actual key and nothing else. This encoding is the +// input to most API functions. +// +// HEX encoding contains one byte for each nibble of the key and an optional trailing +// 'terminator' byte of value 0x10 which indicates whether or not the node at the key +// contains a value. Hex key encoding is used for nodes loaded in memory because it's +// convenient to access. +// +// COMPACT encoding is defined by the Ethereum Yellow Paper (it's called "hex prefix +// encoding" there) and contains the bytes of the key and a flag. The high nibble of the +// first byte contains the flag; the lowest bit encoding the oddness of the length and +// the second-lowest encoding whether the node at the key is a value node. The low nibble +// of the first byte is zero in the case of an even number of nibbles and the first nibble +// in the case of an odd number. All remaining nibbles (now an even number) fit properly +// into the remaining bytes. Compact encoding is used for nodes stored on disk. + +func hexToCompact(hex []byte) []byte { + terminator := byte(0) + if hasTerm(hex) { + terminator = 1 + hex = hex[:len(hex)-1] + } + buf := make([]byte, len(hex)/2+1) + buf[0] = terminator << 5 // the flag byte + if len(hex)&1 == 1 { + buf[0] |= 1 << 4 // odd flag + buf[0] |= hex[0] // first nibble is contained in the first byte + hex = hex[1:] + } + decodeNibbles(hex, buf[1:]) + return buf +} + +func compactToHex(compact []byte) []byte { + if len(compact) == 0 { + return compact + } + base := keybytesToHex(compact) + // delete terminator flag + if base[0] < 2 { + base = base[:len(base)-1] + } + // apply odd flag + chop := 2 - base[0]&1 + return base[chop:] +} + +func keybytesToHex(str []byte) []byte { + l := len(str)*2 + 1 + var nibbles = make([]byte, l) + for i, b := range str { + nibbles[i*2] = b / 16 + nibbles[i*2+1] = b % 16 + } + nibbles[l-1] = 16 + return nibbles +} + +// hexToKeyBytes turns hex nibbles into key bytes. +// This can only be used for keys of even length. +func hexToKeyBytes(hex []byte) []byte { + if hasTerm(hex) { + hex = hex[:len(hex)-1] + } + if len(hex)&1 != 0 { + panic("can't convert hex key of odd length") + } + key := make([]byte, len(hex)/2) + decodeNibbles(hex, key) + return key +} + +func decodeNibbles(nibbles []byte, bytes []byte) { + for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 { + bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1] + } +} + +// prefixLen returns the length of the common prefix of a and b. +func prefixLen(a, b []byte) int { + var i, length = 0, len(a) + if len(b) < length { + length = len(b) + } + for ; i < length; i++ { + if a[i] != b[i] { + break + } + } + return i +} + +// hasTerm returns whether a hex key has the terminator flag. +func hasTerm(s []byte) bool { + return len(s) > 0 && s[len(s)-1] == 16 +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/iterator.go b/vendor/github.com/ethereum/go-ethereum/trie/iterator.go new file mode 100644 index 00000000..86cf4409 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/iterator.go @@ -0,0 +1,577 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "bytes" + "container/heap" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +// Iterator is a key-value trie iterator that traverses a Trie. +type Iterator struct { + nodeIt NodeIterator + + Key []byte // Current data key on which the iterator is positioned on + Value []byte // Current data value on which the iterator is positioned on + Err error +} + +// NewIterator creates a new key-value iterator from a node iterator +func NewIterator(it NodeIterator) *Iterator { + return &Iterator{ + nodeIt: it, + } +} + +// Next moves the iterator forward one key-value entry. +func (it *Iterator) Next() bool { + for it.nodeIt.Next(true) { + if it.nodeIt.Leaf() { + it.Key = it.nodeIt.LeafKey() + it.Value = it.nodeIt.LeafBlob() + return true + } + } + it.Key = nil + it.Value = nil + it.Err = it.nodeIt.Error() + return false +} + +// Prove generates the Merkle proof for the leaf node the iterator is currently +// positioned on. +func (it *Iterator) Prove() [][]byte { + return it.nodeIt.LeafProof() +} + +// NodeIterator is an iterator to traverse the trie pre-order. +type NodeIterator interface { + // Next moves the iterator to the next node. If the parameter is false, any child + // nodes will be skipped. + Next(bool) bool + + // Error returns the error status of the iterator. + Error() error + + // Hash returns the hash of the current node. + Hash() common.Hash + + // Parent returns the hash of the parent of the current node. The hash may be the one + // grandparent if the immediate parent is an internal node with no hash. + Parent() common.Hash + + // Path returns the hex-encoded path to the current node. + // Callers must not retain references to the return value after calling Next. + // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. + Path() []byte + + // Leaf returns true iff the current node is a leaf node. + Leaf() bool + + // LeafKey returns the key of the leaf. The method panics if the iterator is not + // positioned at a leaf. Callers must not retain references to the value after + // calling Next. + LeafKey() []byte + + // LeafBlob returns the content of the leaf. The method panics if the iterator + // is not positioned at a leaf. Callers must not retain references to the value + // after calling Next. + LeafBlob() []byte + + // LeafProof returns the Merkle proof of the leaf. The method panics if the + // iterator is not positioned at a leaf. Callers must not retain references + // to the value after calling Next. + LeafProof() [][]byte +} + +// nodeIteratorState represents the iteration state at one particular node of the +// trie, which can be resumed at a later invocation. +type nodeIteratorState struct { + hash common.Hash // Hash of the node being iterated (nil if not standalone) + node node // Trie node being iterated + parent common.Hash // Hash of the first full ancestor node (nil if current is the root) + index int // Child to be processed next + pathlen int // Length of the path to this node +} + +type nodeIterator struct { + trie *Trie // Trie being iterated + stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state + path []byte // Path to the current node + err error // Failure set in case of an internal error in the iterator +} + +// errIteratorEnd is stored in nodeIterator.err when iteration is done. +var errIteratorEnd = errors.New("end of iteration") + +// seekError is stored in nodeIterator.err if the initial seek has failed. +type seekError struct { + key []byte + err error +} + +func (e seekError) Error() string { + return "seek error: " + e.err.Error() +} + +func newNodeIterator(trie *Trie, start []byte) NodeIterator { + if trie.Hash() == emptyState { + return new(nodeIterator) + } + it := &nodeIterator{trie: trie} + it.err = it.seek(start) + return it +} + +func (it *nodeIterator) Hash() common.Hash { + if len(it.stack) == 0 { + return common.Hash{} + } + return it.stack[len(it.stack)-1].hash +} + +func (it *nodeIterator) Parent() common.Hash { + if len(it.stack) == 0 { + return common.Hash{} + } + return it.stack[len(it.stack)-1].parent +} + +func (it *nodeIterator) Leaf() bool { + return hasTerm(it.path) +} + +func (it *nodeIterator) LeafKey() []byte { + if len(it.stack) > 0 { + if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + return hexToKeyBytes(it.path) + } + } + panic("not at leaf") +} + +func (it *nodeIterator) LeafBlob() []byte { + if len(it.stack) > 0 { + if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + return []byte(node) + } + } + panic("not at leaf") +} + +func (it *nodeIterator) LeafProof() [][]byte { + if len(it.stack) > 0 { + if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + hasher := newHasher(nil) + defer returnHasherToPool(hasher) + + proofs := make([][]byte, 0, len(it.stack)) + + for i, item := range it.stack[:len(it.stack)-1] { + // Gather nodes that end up as hash nodes (or the root) + node, _, _ := hasher.hashChildren(item.node, nil) + hashed, _ := hasher.store(node, nil, false) + if _, ok := hashed.(hashNode); ok || i == 0 { + enc, _ := rlp.EncodeToBytes(node) + proofs = append(proofs, enc) + } + } + return proofs + } + } + panic("not at leaf") +} + +func (it *nodeIterator) Path() []byte { + return it.path +} + +func (it *nodeIterator) Error() error { + if it.err == errIteratorEnd { + return nil + } + if seek, ok := it.err.(seekError); ok { + return seek.err + } + return it.err +} + +// Next moves the iterator to the next node, returning whether there are any +// further nodes. In case of an internal error this method returns false and +// sets the Error field to the encountered failure. If `descend` is false, +// skips iterating over any subnodes of the current node. +func (it *nodeIterator) Next(descend bool) bool { + if it.err == errIteratorEnd { + return false + } + if seek, ok := it.err.(seekError); ok { + if it.err = it.seek(seek.key); it.err != nil { + return false + } + } + // Otherwise step forward with the iterator and report any errors. + state, parentIndex, path, err := it.peek(descend) + it.err = err + if it.err != nil { + return false + } + it.push(state, parentIndex, path) + return true +} + +func (it *nodeIterator) seek(prefix []byte) error { + // The path we're looking for is the hex encoded key without terminator. + key := keybytesToHex(prefix) + key = key[:len(key)-1] + // Move forward until we're just before the closest match to key. + for { + state, parentIndex, path, err := it.peek(bytes.HasPrefix(key, it.path)) + if err == errIteratorEnd { + return errIteratorEnd + } else if err != nil { + return seekError{prefix, err} + } else if bytes.Compare(path, key) >= 0 { + return nil + } + it.push(state, parentIndex, path) + } +} + +// peek creates the next state of the iterator. +func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { + if len(it.stack) == 0 { + // Initialize the iterator if we've just started. + root := it.trie.Hash() + state := &nodeIteratorState{node: it.trie.root, index: -1} + if root != emptyRoot { + state.hash = root + } + err := state.resolve(it.trie, nil) + return state, nil, nil, err + } + if !descend { + // If we're skipping children, pop the current node first + it.pop() + } + + // Continue iteration to the next child + for len(it.stack) > 0 { + parent := it.stack[len(it.stack)-1] + ancestor := parent.hash + if (ancestor == common.Hash{}) { + ancestor = parent.parent + } + state, path, ok := it.nextChild(parent, ancestor) + if ok { + if err := state.resolve(it.trie, path); err != nil { + return parent, &parent.index, path, err + } + return state, &parent.index, path, nil + } + // No more child nodes, move back up. + it.pop() + } + return nil, nil, nil, errIteratorEnd +} + +func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error { + if hash, ok := st.node.(hashNode); ok { + resolved, err := tr.resolveHash(hash, path) + if err != nil { + return err + } + st.node = resolved + st.hash = common.BytesToHash(hash) + } + return nil +} + +func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { + switch node := parent.node.(type) { + case *fullNode: + // Full node, move to the first non-nil child. + for i := parent.index + 1; i < len(node.Children); i++ { + child := node.Children[i] + if child != nil { + hash, _ := child.cache() + state := &nodeIteratorState{ + hash: common.BytesToHash(hash), + node: child, + parent: ancestor, + index: -1, + pathlen: len(it.path), + } + path := append(it.path, byte(i)) + parent.index = i - 1 + return state, path, true + } + } + case *shortNode: + // Short node, return the pointer singleton child + if parent.index < 0 { + hash, _ := node.Val.cache() + state := &nodeIteratorState{ + hash: common.BytesToHash(hash), + node: node.Val, + parent: ancestor, + index: -1, + pathlen: len(it.path), + } + path := append(it.path, node.Key...) + return state, path, true + } + } + return parent, it.path, false +} + +func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { + it.path = path + it.stack = append(it.stack, state) + if parentIndex != nil { + *parentIndex++ + } +} + +func (it *nodeIterator) pop() { + parent := it.stack[len(it.stack)-1] + it.path = it.path[:parent.pathlen] + it.stack = it.stack[:len(it.stack)-1] +} + +func compareNodes(a, b NodeIterator) int { + if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { + return cmp + } + if a.Leaf() && !b.Leaf() { + return -1 + } else if b.Leaf() && !a.Leaf() { + return 1 + } + if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { + return cmp + } + if a.Leaf() && b.Leaf() { + return bytes.Compare(a.LeafBlob(), b.LeafBlob()) + } + return 0 +} + +type differenceIterator struct { + a, b NodeIterator // Nodes returned are those in b - a. + eof bool // Indicates a has run out of elements + count int // Number of nodes scanned on either trie +} + +// NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that +// are not in a. Returns the iterator, and a pointer to an integer recording the number +// of nodes seen. +func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { + a.Next(true) + it := &differenceIterator{ + a: a, + b: b, + } + return it, &it.count +} + +func (it *differenceIterator) Hash() common.Hash { + return it.b.Hash() +} + +func (it *differenceIterator) Parent() common.Hash { + return it.b.Parent() +} + +func (it *differenceIterator) Leaf() bool { + return it.b.Leaf() +} + +func (it *differenceIterator) LeafKey() []byte { + return it.b.LeafKey() +} + +func (it *differenceIterator) LeafBlob() []byte { + return it.b.LeafBlob() +} + +func (it *differenceIterator) LeafProof() [][]byte { + return it.b.LeafProof() +} + +func (it *differenceIterator) Path() []byte { + return it.b.Path() +} + +func (it *differenceIterator) Next(bool) bool { + // Invariants: + // - We always advance at least one element in b. + // - At the start of this function, a's path is lexically greater than b's. + if !it.b.Next(true) { + return false + } + it.count++ + + if it.eof { + // a has reached eof, so we just return all elements from b + return true + } + + for { + switch compareNodes(it.a, it.b) { + case -1: + // b jumped past a; advance a + if !it.a.Next(true) { + it.eof = true + return true + } + it.count++ + case 1: + // b is before a + return true + case 0: + // a and b are identical; skip this whole subtree if the nodes have hashes + hasHash := it.a.Hash() == common.Hash{} + if !it.b.Next(hasHash) { + return false + } + it.count++ + if !it.a.Next(hasHash) { + it.eof = true + return true + } + it.count++ + } + } +} + +func (it *differenceIterator) Error() error { + if err := it.a.Error(); err != nil { + return err + } + return it.b.Error() +} + +type nodeIteratorHeap []NodeIterator + +func (h nodeIteratorHeap) Len() int { return len(h) } +func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } +func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } +func (h *nodeIteratorHeap) Pop() interface{} { + n := len(*h) + x := (*h)[n-1] + *h = (*h)[0 : n-1] + return x +} + +type unionIterator struct { + items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators + count int // Number of nodes scanned across all tries +} + +// NewUnionIterator constructs a NodeIterator that iterates over elements in the union +// of the provided NodeIterators. Returns the iterator, and a pointer to an integer +// recording the number of nodes visited. +func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { + h := make(nodeIteratorHeap, len(iters)) + copy(h, iters) + heap.Init(&h) + + ui := &unionIterator{items: &h} + return ui, &ui.count +} + +func (it *unionIterator) Hash() common.Hash { + return (*it.items)[0].Hash() +} + +func (it *unionIterator) Parent() common.Hash { + return (*it.items)[0].Parent() +} + +func (it *unionIterator) Leaf() bool { + return (*it.items)[0].Leaf() +} + +func (it *unionIterator) LeafKey() []byte { + return (*it.items)[0].LeafKey() +} + +func (it *unionIterator) LeafBlob() []byte { + return (*it.items)[0].LeafBlob() +} + +func (it *unionIterator) LeafProof() [][]byte { + return (*it.items)[0].LeafProof() +} + +func (it *unionIterator) Path() []byte { + return (*it.items)[0].Path() +} + +// Next returns the next node in the union of tries being iterated over. +// +// It does this by maintaining a heap of iterators, sorted by the iteration +// order of their next elements, with one entry for each source trie. Each +// time Next() is called, it takes the least element from the heap to return, +// advancing any other iterators that also point to that same element. These +// iterators are called with descend=false, since we know that any nodes under +// these nodes will also be duplicates, found in the currently selected iterator. +// Whenever an iterator is advanced, it is pushed back into the heap if it still +// has elements remaining. +// +// In the case that descend=false - eg, we're asked to ignore all subnodes of the +// current node - we also advance any iterators in the heap that have the current +// path as a prefix. +func (it *unionIterator) Next(descend bool) bool { + if len(*it.items) == 0 { + return false + } + + // Get the next key from the union + least := heap.Pop(it.items).(NodeIterator) + + // Skip over other nodes as long as they're identical, or, if we're not descending, as + // long as they have the same prefix as the current node. + for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { + skipped := heap.Pop(it.items).(NodeIterator) + // Skip the whole subtree if the nodes have hashes; otherwise just skip this node + if skipped.Next(skipped.Hash() == common.Hash{}) { + it.count++ + // If there are more elements, push the iterator back on the heap + heap.Push(it.items, skipped) + } + } + if least.Next(descend) { + it.count++ + heap.Push(it.items, least) + } + return len(*it.items) > 0 +} + +func (it *unionIterator) Error() error { + for i := 0; i < len(*it.items); i++ { + if err := (*it.items)[i].Error(); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/proof.go b/vendor/github.com/ethereum/go-ethereum/trie/proof.go new file mode 100644 index 00000000..9985e730 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/proof.go @@ -0,0 +1,154 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "bytes" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +// Prove constructs a merkle proof for key. The result contains all encoded nodes +// on the path to the value at key. The value itself is also included in the last +// node and can be retrieved by verifying the proof. +// +// If the trie does not contain a value for key, the returned proof contains all +// nodes of the longest existing prefix of the key (at least the root node), ending +// with the node that proves the absence of the key. +func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error { + // Collect all nodes on the path to key. + key = keybytesToHex(key) + var nodes []node + tn := t.root + for len(key) > 0 && tn != nil { + switch n := tn.(type) { + case *shortNode: + if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { + // The trie doesn't contain the key. + tn = nil + } else { + tn = n.Val + key = key[len(n.Key):] + } + nodes = append(nodes, n) + case *fullNode: + tn = n.Children[key[0]] + key = key[1:] + nodes = append(nodes, n) + case hashNode: + var err error + tn, err = t.resolveHash(n, nil) + if err != nil { + log.Error(fmt.Sprintf("Unhandled trie error: %v", err)) + return err + } + default: + panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) + } + } + hasher := newHasher(nil) + defer returnHasherToPool(hasher) + + for i, n := range nodes { + // Don't bother checking for errors here since hasher panics + // if encoding doesn't work and we're not writing to any database. + n, _, _ = hasher.hashChildren(n, nil) + hn, _ := hasher.store(n, nil, false) + if hash, ok := hn.(hashNode); ok || i == 0 { + // If the node's database encoding is a hash (or is the + // root node), it becomes a proof element. + if fromLevel > 0 { + fromLevel-- + } else { + enc, _ := rlp.EncodeToBytes(n) + if !ok { + hash = hasher.makeHashNode(enc) + } + proofDb.Put(hash, enc) + } + } + } + return nil +} + +// Prove constructs a merkle proof for key. The result contains all encoded nodes +// on the path to the value at key. The value itself is also included in the last +// node and can be retrieved by verifying the proof. +// +// If the trie does not contain a value for key, the returned proof contains all +// nodes of the longest existing prefix of the key (at least the root node), ending +// with the node that proves the absence of the key. +func (t *SecureTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error { + return t.trie.Prove(key, fromLevel, proofDb) +} + +// VerifyProof checks merkle proofs. The given proof must contain the value for +// key in a trie with the given root hash. VerifyProof returns an error if the +// proof contains invalid trie nodes or the wrong value. +func VerifyProof(rootHash common.Hash, key []byte, proofDb ethdb.KeyValueReader) (value []byte, nodes int, err error) { + key = keybytesToHex(key) + wantHash := rootHash + for i := 0; ; i++ { + buf, _ := proofDb.Get(wantHash[:]) + if buf == nil { + return nil, i, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash) + } + n, err := decodeNode(wantHash[:], buf) + if err != nil { + return nil, i, fmt.Errorf("bad proof node %d: %v", i, err) + } + keyrest, cld := get(n, key) + switch cld := cld.(type) { + case nil: + // The trie doesn't contain the key. + return nil, i, nil + case hashNode: + key = keyrest + copy(wantHash[:], cld) + case valueNode: + return cld, i + 1, nil + } + } +} + +func get(tn node, key []byte) ([]byte, node) { + for { + switch n := tn.(type) { + case *shortNode: + if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { + return nil, nil + } + tn = n.Val + key = key[len(n.Key):] + case *fullNode: + tn = n.Children[key[0]] + key = key[1:] + case hashNode: + return key, n + case nil: + return key, nil + case valueNode: + return nil, n + default: + panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) + } + } +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/sync.go b/vendor/github.com/ethereum/go-ethereum/trie/sync.go new file mode 100644 index 00000000..6f40b45a --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/sync.go @@ -0,0 +1,347 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/ethdb" +) + +// ErrNotRequested is returned by the trie sync when it's requested to process a +// node it did not request. +var ErrNotRequested = errors.New("not requested") + +// ErrAlreadyProcessed is returned by the trie sync when it's requested to process a +// node it already processed previously. +var ErrAlreadyProcessed = errors.New("already processed") + +// request represents a scheduled or already in-flight state retrieval request. +type request struct { + hash common.Hash // Hash of the node data content to retrieve + data []byte // Data content of the node, cached until all subtrees complete + raw bool // Whether this is a raw entry (code) or a trie node + + parents []*request // Parent state nodes referencing this entry (notify all upon completion) + depth int // Depth level within the trie the node is located to prioritise DFS + deps int // Number of dependencies before allowed to commit this node + + callback LeafCallback // Callback to invoke if a leaf node it reached on this branch +} + +// SyncResult is a simple list to return missing nodes along with their request +// hashes. +type SyncResult struct { + Hash common.Hash // Hash of the originally unknown trie node + Data []byte // Data content of the retrieved node +} + +// syncMemBatch is an in-memory buffer of successfully downloaded but not yet +// persisted data items. +type syncMemBatch struct { + batch map[common.Hash][]byte // In-memory membatch of recently completed items + order []common.Hash // Order of completion to prevent out-of-order data loss +} + +// newSyncMemBatch allocates a new memory-buffer for not-yet persisted trie nodes. +func newSyncMemBatch() *syncMemBatch { + return &syncMemBatch{ + batch: make(map[common.Hash][]byte), + order: make([]common.Hash, 0, 256), + } +} + +// Sync is the main state trie synchronisation scheduler, which provides yet +// unknown trie hashes to retrieve, accepts node data associated with said hashes +// and reconstructs the trie step by step until all is done. +type Sync struct { + database ethdb.KeyValueReader // Persistent database to check for existing entries + membatch *syncMemBatch // Memory buffer to avoid frequent database writes + requests map[common.Hash]*request // Pending requests pertaining to a key hash + queue *prque.Prque // Priority queue with the pending requests + bloom *SyncBloom // Bloom filter for fast node existence checks +} + +// NewSync creates a new trie data download scheduler. +func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallback, bloom *SyncBloom) *Sync { + ts := &Sync{ + database: database, + membatch: newSyncMemBatch(), + requests: make(map[common.Hash]*request), + queue: prque.New(nil), + bloom: bloom, + } + ts.AddSubTrie(root, 0, common.Hash{}, callback) + return ts +} + +// AddSubTrie registers a new trie to the sync code, rooted at the designated parent. +func (s *Sync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callback LeafCallback) { + // Short circuit if the trie is empty or already known + if root == emptyRoot { + return + } + if _, ok := s.membatch.batch[root]; ok { + return + } + if s.bloom.Contains(root[:]) { + // Bloom filter says this might be a duplicate, double check + blob, _ := s.database.Get(root[:]) + if local, err := decodeNode(root[:], blob); local != nil && err == nil { + return + } + // False positive, bump fault meter + bloomFaultMeter.Mark(1) + } + // Assemble the new sub-trie sync request + req := &request{ + hash: root, + depth: depth, + callback: callback, + } + // If this sub-trie has a designated parent, link them together + if parent != (common.Hash{}) { + ancestor := s.requests[parent] + if ancestor == nil { + panic(fmt.Sprintf("sub-trie ancestor not found: %x", parent)) + } + ancestor.deps++ + req.parents = append(req.parents, ancestor) + } + s.schedule(req) +} + +// AddRawEntry schedules the direct retrieval of a state entry that should not be +// interpreted as a trie node, but rather accepted and stored into the database +// as is. This method's goal is to support misc state metadata retrievals (e.g. +// contract code). +func (s *Sync) AddRawEntry(hash common.Hash, depth int, parent common.Hash) { + // Short circuit if the entry is empty or already known + if hash == emptyState { + return + } + if _, ok := s.membatch.batch[hash]; ok { + return + } + if s.bloom.Contains(hash[:]) { + // Bloom filter says this might be a duplicate, double check + if ok, _ := s.database.Has(hash[:]); ok { + return + } + // False positive, bump fault meter + bloomFaultMeter.Mark(1) + } + // Assemble the new sub-trie sync request + req := &request{ + hash: hash, + raw: true, + depth: depth, + } + // If this sub-trie has a designated parent, link them together + if parent != (common.Hash{}) { + ancestor := s.requests[parent] + if ancestor == nil { + panic(fmt.Sprintf("raw-entry ancestor not found: %x", parent)) + } + ancestor.deps++ + req.parents = append(req.parents, ancestor) + } + s.schedule(req) +} + +// Missing retrieves the known missing nodes from the trie for retrieval. +func (s *Sync) Missing(max int) []common.Hash { + var requests []common.Hash + for !s.queue.Empty() && (max == 0 || len(requests) < max) { + requests = append(requests, s.queue.PopItem().(common.Hash)) + } + return requests +} + +// Process injects a batch of retrieved trie nodes data, returning if something +// was committed to the database and also the index of an entry if processing of +// it failed. +func (s *Sync) Process(results []SyncResult) (bool, int, error) { + committed := false + + for i, item := range results { + // If the item was not requested, bail out + request := s.requests[item.Hash] + if request == nil { + return committed, i, ErrNotRequested + } + if request.data != nil { + return committed, i, ErrAlreadyProcessed + } + // If the item is a raw entry request, commit directly + if request.raw { + request.data = item.Data + s.commit(request) + committed = true + continue + } + // Decode the node data content and update the request + node, err := decodeNode(item.Hash[:], item.Data) + if err != nil { + return committed, i, err + } + request.data = item.Data + + // Create and schedule a request for all the children nodes + requests, err := s.children(request, node) + if err != nil { + return committed, i, err + } + if len(requests) == 0 && request.deps == 0 { + s.commit(request) + committed = true + continue + } + request.deps += len(requests) + for _, child := range requests { + s.schedule(child) + } + } + return committed, 0, nil +} + +// Commit flushes the data stored in the internal membatch out to persistent +// storage, returning the number of items written and any occurred error. +func (s *Sync) Commit(dbw ethdb.KeyValueWriter) (int, error) { + // Dump the membatch into a database dbw + for i, key := range s.membatch.order { + if err := dbw.Put(key[:], s.membatch.batch[key]); err != nil { + return i, err + } + s.bloom.Add(key[:]) + } + written := len(s.membatch.order) // TODO(karalabe): could an order change improve write performance? + + // Drop the membatch data and return + s.membatch = newSyncMemBatch() + return written, nil +} + +// Pending returns the number of state entries currently pending for download. +func (s *Sync) Pending() int { + return len(s.requests) +} + +// schedule inserts a new state retrieval request into the fetch queue. If there +// is already a pending request for this node, the new request will be discarded +// and only a parent reference added to the old one. +func (s *Sync) schedule(req *request) { + // If we're already requesting this node, add a new reference and stop + if old, ok := s.requests[req.hash]; ok { + old.parents = append(old.parents, req.parents...) + return + } + // Schedule the request for future retrieval + s.queue.Push(req.hash, int64(req.depth)) + s.requests[req.hash] = req +} + +// children retrieves all the missing children of a state trie entry for future +// retrieval scheduling. +func (s *Sync) children(req *request, object node) ([]*request, error) { + // Gather all the children of the node, irrelevant whether known or not + type child struct { + node node + depth int + } + var children []child + + switch node := (object).(type) { + case *shortNode: + children = []child{{ + node: node.Val, + depth: req.depth + len(node.Key), + }} + case *fullNode: + for i := 0; i < 17; i++ { + if node.Children[i] != nil { + children = append(children, child{ + node: node.Children[i], + depth: req.depth + 1, + }) + } + } + default: + panic(fmt.Sprintf("unknown node: %+v", node)) + } + // Iterate over the children, and request all unknown ones + requests := make([]*request, 0, len(children)) + for _, child := range children { + // Notify any external watcher of a new key/value node + if req.callback != nil { + if node, ok := (child.node).(valueNode); ok { + if err := req.callback(node, req.hash); err != nil { + return nil, err + } + } + } + // If the child references another node, resolve or schedule + if node, ok := (child.node).(hashNode); ok { + // Try to resolve the node from the local database + hash := common.BytesToHash(node) + if _, ok := s.membatch.batch[hash]; ok { + continue + } + if s.bloom.Contains(node) { + // Bloom filter says this might be a duplicate, double check + if ok, _ := s.database.Has(node); ok { + continue + } + // False positive, bump fault meter + bloomFaultMeter.Mark(1) + } + // Locally unknown node, schedule for retrieval + requests = append(requests, &request{ + hash: hash, + parents: []*request{req}, + depth: child.depth, + callback: req.callback, + }) + } + } + return requests, nil +} + +// commit finalizes a retrieval request and stores it into the membatch. If any +// of the referencing parent requests complete due to this commit, they are also +// committed themselves. +func (s *Sync) commit(req *request) (err error) { + // Write the node content to the membatch + s.membatch.batch[req.hash] = req.data + s.membatch.order = append(s.membatch.order, req.hash) + + delete(s.requests, req.hash) + + // Check all parents for completion + for _, parent := range req.parents { + parent.deps-- + if parent.deps == 0 { + if err := s.commit(parent); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/ethereum/go-ethereum/trie/sync_bloom.go b/vendor/github.com/ethereum/go-ethereum/trie/sync_bloom.go new file mode 100644 index 00000000..7b5b7488 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/trie/sync_bloom.go @@ -0,0 +1,207 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "encoding/binary" + "fmt" + "math" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/steakknife/bloomfilter" +) + +var ( + bloomAddMeter = metrics.NewRegisteredMeter("trie/bloom/add", nil) + bloomLoadMeter = metrics.NewRegisteredMeter("trie/bloom/load", nil) + bloomTestMeter = metrics.NewRegisteredMeter("trie/bloom/test", nil) + bloomMissMeter = metrics.NewRegisteredMeter("trie/bloom/miss", nil) + bloomFaultMeter = metrics.NewRegisteredMeter("trie/bloom/fault", nil) + bloomErrorGauge = metrics.NewRegisteredGauge("trie/bloom/error", nil) +) + +// syncBloomHasher is a wrapper around a byte blob to satisfy the interface API +// requirements of the bloom library used. It's used to convert a trie hash into +// a 64 bit mini hash. +type syncBloomHasher []byte + +func (f syncBloomHasher) Write(p []byte) (n int, err error) { panic("not implemented") } +func (f syncBloomHasher) Sum(b []byte) []byte { panic("not implemented") } +func (f syncBloomHasher) Reset() { panic("not implemented") } +func (f syncBloomHasher) BlockSize() int { panic("not implemented") } +func (f syncBloomHasher) Size() int { return 8 } +func (f syncBloomHasher) Sum64() uint64 { return binary.BigEndian.Uint64(f) } + +// SyncBloom is a bloom filter used during fast sync to quickly decide if a trie +// node already exists on disk or not. It self populates from the provided disk +// database on creation in a background thread and will only start returning live +// results once that's finished. +type SyncBloom struct { + bloom *bloomfilter.Filter + inited uint32 + closer sync.Once + closed uint32 + pend sync.WaitGroup +} + +// NewSyncBloom creates a new bloom filter of the given size (in megabytes) and +// initializes it from the database. The bloom is hard coded to use 3 filters. +func NewSyncBloom(memory uint64, database ethdb.Iteratee) *SyncBloom { + // Create the bloom filter to track known trie nodes + bloom, err := bloomfilter.New(memory*1024*1024*8, 3) + if err != nil { + panic(fmt.Sprintf("failed to create bloom: %v", err)) // Can't happen, here for sanity + } + log.Info("Allocated fast sync bloom", "size", common.StorageSize(memory*1024*1024)) + + // Assemble the fast sync bloom and init it from previous sessions + b := &SyncBloom{ + bloom: bloom, + } + b.pend.Add(2) + go func() { + defer b.pend.Done() + b.init(database) + }() + go func() { + defer b.pend.Done() + b.meter() + }() + return b +} + +// init iterates over the database, pushing every trie hash into the bloom filter. +func (b *SyncBloom) init(database ethdb.Iteratee) { + // Iterate over the database, but restart every now and again to avoid holding + // a persistent snapshot since fast sync can push a ton of data concurrently, + // bloating the disk. + // + // Note, this is fine, because everything inserted into leveldb by fast sync is + // also pushed into the bloom directly, so we're not missing anything when the + // iterator is swapped out for a new one. + it := database.NewIterator() + + var ( + start = time.Now() + swap = time.Now() + ) + for it.Next() && atomic.LoadUint32(&b.closed) == 0 { + // If the database entry is a trie node, add it to the bloom + if key := it.Key(); len(key) == common.HashLength { + b.bloom.Add(syncBloomHasher(key)) + bloomLoadMeter.Mark(1) + } + // If enough time elapsed since the last iterator swap, restart + if time.Since(swap) > 8*time.Second { + key := common.CopyBytes(it.Key()) + + it.Release() + it = database.NewIteratorWithStart(key) + + log.Info("Initializing fast sync bloom", "items", b.bloom.N(), "errorrate", b.errorRate(), "elapsed", common.PrettyDuration(time.Since(start))) + swap = time.Now() + } + } + it.Release() + + // Mark the bloom filter inited and return + log.Info("Initialized fast sync bloom", "items", b.bloom.N(), "errorrate", b.errorRate(), "elapsed", common.PrettyDuration(time.Since(start))) + atomic.StoreUint32(&b.inited, 1) +} + +// meter periodically recalculates the false positive error rate of the bloom +// filter and reports it in a metric. +func (b *SyncBloom) meter() { + for { + // Report the current error ration. No floats, lame, scale it up. + bloomErrorGauge.Update(int64(b.errorRate() * 100000)) + + // Wait one second, but check termination more frequently + for i := 0; i < 10; i++ { + if atomic.LoadUint32(&b.closed) == 1 { + return + } + time.Sleep(100 * time.Millisecond) + } + } +} + +// Close terminates any background initializer still running and releases all the +// memory allocated for the bloom. +func (b *SyncBloom) Close() error { + b.closer.Do(func() { + // Ensure the initializer is stopped + atomic.StoreUint32(&b.closed, 1) + b.pend.Wait() + + // Wipe the bloom, but mark it "uninited" just in case someone attempts an access + log.Info("Deallocated fast sync bloom", "items", b.bloom.N(), "errorrate", b.errorRate()) + + atomic.StoreUint32(&b.inited, 0) + b.bloom = nil + }) + return nil +} + +// Add inserts a new trie node hash into the bloom filter. +func (b *SyncBloom) Add(hash []byte) { + if atomic.LoadUint32(&b.closed) == 1 { + return + } + b.bloom.Add(syncBloomHasher(hash)) + bloomAddMeter.Mark(1) +} + +// Contains tests if the bloom filter contains the given hash: +// - false: the bloom definitely does not contain hash +// - true: the bloom maybe contains hash +// +// While the bloom is being initialized, any query will return true. +func (b *SyncBloom) Contains(hash []byte) bool { + bloomTestMeter.Mark(1) + if atomic.LoadUint32(&b.inited) == 0 { + // We didn't load all the trie nodes from the previous run of Geth yet. As + // such, we can't say for sure if a hash is not present for anything. Until + // the init is done, we're faking "possible presence" for everything. + return true + } + // Bloom initialized, check the real one and report any successful misses + maybe := b.bloom.Contains(syncBloomHasher(hash)) + if !maybe { + bloomMissMeter.Mark(1) + } + return maybe +} + +// errorRate calculates the probability of a random containment test returning a +// false positive. +// +// We're calculating it ourselves because the bloom library we used missed a +// parentheses in the formula and calculates it wrong. And it's discontinued... +func (b *SyncBloom) errorRate() float64 { + k := float64(b.bloom.K()) + n := float64(b.bloom.N()) + m := float64(b.bloom.M()) + + return math.Pow(1.0-math.Exp((-k)*(n+0.5)/(m-1)), k) +} diff --git a/vendor/github.com/ethereum/go-ethereum/whisper/whisperv6/api.go b/vendor/github.com/ethereum/go-ethereum/whisper/whisperv6/api.go new file mode 100644 index 00000000..d6d4c8d3 --- /dev/null +++ b/vendor/github.com/ethereum/go-ethereum/whisper/whisperv6/api.go @@ -0,0 +1,593 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package whisperv6 + +import ( + "context" + "crypto/ecdsa" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/rpc" +) + +// List of errors +var ( + ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key") + ErrInvalidSymmetricKey = errors.New("invalid symmetric key") + ErrInvalidPublicKey = errors.New("invalid public key") + ErrInvalidSigningPubKey = errors.New("invalid signing public key") + ErrTooLowPoW = errors.New("message rejected, PoW too low") + ErrNoTopics = errors.New("missing topic(s)") +) + +// PublicWhisperAPI provides the whisper RPC service that can be +// use publicly without security implications. +type PublicWhisperAPI struct { + w *Whisper + + mu sync.Mutex + lastUsed map[string]time.Time // keeps track when a filter was polled for the last time. +} + +// NewPublicWhisperAPI create a new RPC whisper service. +func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI { + api := &PublicWhisperAPI{ + w: w, + lastUsed: make(map[string]time.Time), + } + return api +} + +// Version returns the Whisper sub-protocol version. +func (api *PublicWhisperAPI) Version(ctx context.Context) string { + return ProtocolVersionStr +} + +// Info contains diagnostic information. +type Info struct { + Memory int `json:"memory"` // Memory size of the floating messages in bytes. + Messages int `json:"messages"` // Number of floating messages. + MinPow float64 `json:"minPow"` // Minimal accepted PoW + MaxMessageSize uint32 `json:"maxMessageSize"` // Maximum accepted message size +} + +// Info returns diagnostic information about the whisper node. +func (api *PublicWhisperAPI) Info(ctx context.Context) Info { + stats := api.w.Stats() + return Info{ + Memory: stats.memoryUsed, + Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue), + MinPow: api.w.MinPow(), + MaxMessageSize: api.w.MaxMessageSize(), + } +} + +// SetMaxMessageSize sets the maximum message size that is accepted. +// Upper limit is defined by MaxMessageSize. +func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32) (bool, error) { + return true, api.w.SetMaxMessageSize(size) +} + +// SetMinPoW sets the minimum PoW, and notifies the peers. +func (api *PublicWhisperAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) { + return true, api.w.SetMinimumPoW(pow) +} + +// SetBloomFilter sets the new value of bloom filter, and notifies the peers. +func (api *PublicWhisperAPI) SetBloomFilter(ctx context.Context, bloom hexutil.Bytes) (bool, error) { + return true, api.w.SetBloomFilter(bloom) +} + +// MarkTrustedPeer marks a peer trusted, which will allow it to send historic (expired) messages. +// Note: This function is not adding new nodes, the node needs to exists as a peer. +func (api *PublicWhisperAPI) MarkTrustedPeer(ctx context.Context, url string) (bool, error) { + n, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return false, err + } + return true, api.w.AllowP2PMessagesFromPeer(n.ID().Bytes()) +} + +// NewKeyPair generates a new public and private key pair for message decryption and encryption. +// It returns an ID that can be used to refer to the keypair. +func (api *PublicWhisperAPI) NewKeyPair(ctx context.Context) (string, error) { + return api.w.NewKeyPair() +} + +// AddPrivateKey imports the given private key. +func (api *PublicWhisperAPI) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) { + key, err := crypto.ToECDSA(privateKey) + if err != nil { + return "", err + } + return api.w.AddKeyPair(key) +} + +// DeleteKeyPair removes the key with the given key if it exists. +func (api *PublicWhisperAPI) DeleteKeyPair(ctx context.Context, key string) (bool, error) { + if ok := api.w.DeleteKeyPair(key); ok { + return true, nil + } + return false, fmt.Errorf("key pair %s not found", key) +} + +// HasKeyPair returns an indication if the node has a key pair that is associated with the given id. +func (api *PublicWhisperAPI) HasKeyPair(ctx context.Context, id string) bool { + return api.w.HasKeyPair(id) +} + +// GetPublicKey returns the public key associated with the given key. The key is the hex +// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62. +func (api *PublicWhisperAPI) GetPublicKey(ctx context.Context, id string) (hexutil.Bytes, error) { + key, err := api.w.GetPrivateKey(id) + if err != nil { + return hexutil.Bytes{}, err + } + return crypto.FromECDSAPub(&key.PublicKey), nil +} + +// GetPrivateKey returns the private key associated with the given key. The key is the hex +// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62. +func (api *PublicWhisperAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) { + key, err := api.w.GetPrivateKey(id) + if err != nil { + return hexutil.Bytes{}, err + } + return crypto.FromECDSA(key), nil +} + +// NewSymKey generate a random symmetric key. +// It returns an ID that can be used to refer to the key. +// Can be used encrypting and decrypting messages where the key is known to both parties. +func (api *PublicWhisperAPI) NewSymKey(ctx context.Context) (string, error) { + return api.w.GenerateSymKey() +} + +// AddSymKey import a symmetric key. +// It returns an ID that can be used to refer to the key. +// Can be used encrypting and decrypting messages where the key is known to both parties. +func (api *PublicWhisperAPI) AddSymKey(ctx context.Context, key hexutil.Bytes) (string, error) { + return api.w.AddSymKeyDirect([]byte(key)) +} + +// GenerateSymKeyFromPassword derive a key from the given password, stores it, and returns its ID. +func (api *PublicWhisperAPI) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) { + return api.w.AddSymKeyFromPassword(passwd) +} + +// HasSymKey returns an indication if the node has a symmetric key associated with the given key. +func (api *PublicWhisperAPI) HasSymKey(ctx context.Context, id string) bool { + return api.w.HasSymKey(id) +} + +// GetSymKey returns the symmetric key associated with the given id. +func (api *PublicWhisperAPI) GetSymKey(ctx context.Context, id string) (hexutil.Bytes, error) { + return api.w.GetSymKey(id) +} + +// DeleteSymKey deletes the symmetric key that is associated with the given id. +func (api *PublicWhisperAPI) DeleteSymKey(ctx context.Context, id string) bool { + return api.w.DeleteSymKey(id) +} + +// MakeLightClient turns the node into light client, which does not forward +// any incoming messages, and sends only messages originated in this node. +func (api *PublicWhisperAPI) MakeLightClient(ctx context.Context) bool { + api.w.SetLightClientMode(true) + return api.w.LightClientMode() +} + +// CancelLightClient cancels light client mode. +func (api *PublicWhisperAPI) CancelLightClient(ctx context.Context) bool { + api.w.SetLightClientMode(false) + return !api.w.LightClientMode() +} + +//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go + +// NewMessage represents a new whisper message that is posted through the RPC. +type NewMessage struct { + SymKeyID string `json:"symKeyID"` + PublicKey []byte `json:"pubKey"` + Sig string `json:"sig"` + TTL uint32 `json:"ttl"` + Topic TopicType `json:"topic"` + Payload []byte `json:"payload"` + Padding []byte `json:"padding"` + PowTime uint32 `json:"powTime"` + PowTarget float64 `json:"powTarget"` + TargetPeer string `json:"targetPeer"` +} + +type newMessageOverride struct { + PublicKey hexutil.Bytes + Payload hexutil.Bytes + Padding hexutil.Bytes +} + +// Post posts a message on the Whisper network. +// returns the hash of the message in case of success. +func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.Bytes, error) { + var ( + symKeyGiven = len(req.SymKeyID) > 0 + pubKeyGiven = len(req.PublicKey) > 0 + err error + ) + + // user must specify either a symmetric or an asymmetric key + if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) { + return nil, ErrSymAsym + } + + params := &MessageParams{ + TTL: req.TTL, + Payload: req.Payload, + Padding: req.Padding, + WorkTime: req.PowTime, + PoW: req.PowTarget, + Topic: req.Topic, + } + + // Set key that is used to sign the message + if len(req.Sig) > 0 { + if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil { + return nil, err + } + } + + // Set symmetric key that is used to encrypt the message + if symKeyGiven { + if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption + return nil, ErrNoTopics + } + if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil { + return nil, err + } + if !validateDataIntegrity(params.KeySym, aesKeyLength) { + return nil, ErrInvalidSymmetricKey + } + } + + // Set asymmetric key that is used to encrypt the message + if pubKeyGiven { + if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil { + return nil, ErrInvalidPublicKey + } + } + + // encrypt and sent message + whisperMsg, err := NewSentMessage(params) + if err != nil { + return nil, err + } + + var result []byte + env, err := whisperMsg.Wrap(params) + if err != nil { + return nil, err + } + + // send to specific node (skip PoW check) + if len(req.TargetPeer) > 0 { + n, err := enode.Parse(enode.ValidSchemes, req.TargetPeer) + if err != nil { + return nil, fmt.Errorf("failed to parse target peer: %s", err) + } + err = api.w.SendP2PMessage(n.ID().Bytes(), env) + if err == nil { + hash := env.Hash() + result = hash[:] + } + return result, err + } + + // ensure that the message PoW meets the node's minimum accepted PoW + if req.PowTarget < api.w.MinPow() { + return nil, ErrTooLowPoW + } + + err = api.w.Send(env) + if err == nil { + hash := env.Hash() + result = hash[:] + } + return result, err +} + +//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go + +// Criteria holds various filter options for inbound messages. +type Criteria struct { + SymKeyID string `json:"symKeyID"` + PrivateKeyID string `json:"privateKeyID"` + Sig []byte `json:"sig"` + MinPow float64 `json:"minPow"` + Topics []TopicType `json:"topics"` + AllowP2P bool `json:"allowP2P"` +} + +type criteriaOverride struct { + Sig hexutil.Bytes +} + +// Messages set up a subscription that fires events when messages arrive that match +// the given set of criteria. +func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.Subscription, error) { + var ( + symKeyGiven = len(crit.SymKeyID) > 0 + pubKeyGiven = len(crit.PrivateKeyID) > 0 + err error + ) + + // ensure that the RPC connection supports subscriptions + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // user must specify either a symmetric or an asymmetric key + if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) { + return nil, ErrSymAsym + } + + filter := Filter{ + PoW: crit.MinPow, + Messages: make(map[common.Hash]*ReceivedMessage), + AllowP2P: crit.AllowP2P, + } + + if len(crit.Sig) > 0 { + if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil { + return nil, ErrInvalidSigningPubKey + } + } + + for i, bt := range crit.Topics { + if len(bt) == 0 || len(bt) > 4 { + return nil, fmt.Errorf("subscribe: topic %d has wrong size: %d", i, len(bt)) + } + filter.Topics = append(filter.Topics, bt[:]) + } + + // listen for message that are encrypted with the given symmetric key + if symKeyGiven { + if len(filter.Topics) == 0 { + return nil, ErrNoTopics + } + key, err := api.w.GetSymKey(crit.SymKeyID) + if err != nil { + return nil, err + } + if !validateDataIntegrity(key, aesKeyLength) { + return nil, ErrInvalidSymmetricKey + } + filter.KeySym = key + filter.SymKeyHash = crypto.Keccak256Hash(filter.KeySym) + } + + // listen for messages that are encrypted with the given public key + if pubKeyGiven { + filter.KeyAsym, err = api.w.GetPrivateKey(crit.PrivateKeyID) + if err != nil || filter.KeyAsym == nil { + return nil, ErrInvalidPublicKey + } + } + + id, err := api.w.Subscribe(&filter) + if err != nil { + return nil, err + } + + // create subscription and start waiting for message events + rpcSub := notifier.CreateSubscription() + go func() { + // for now poll internally, refactor whisper internal for channel support + ticker := time.NewTicker(250 * time.Millisecond) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if filter := api.w.GetFilter(id); filter != nil { + for _, rpcMessage := range toMessage(filter.Retrieve()) { + if err := notifier.Notify(rpcSub.ID, rpcMessage); err != nil { + log.Error("Failed to send notification", "err", err) + } + } + } + case <-rpcSub.Err(): + api.w.Unsubscribe(id) + return + case <-notifier.Closed(): + api.w.Unsubscribe(id) + return + } + } + }() + + return rpcSub, nil +} + +//go:generate gencodec -type Message -field-override messageOverride -out gen_message_json.go + +// Message is the RPC representation of a whisper message. +type Message struct { + Sig []byte `json:"sig,omitempty"` + TTL uint32 `json:"ttl"` + Timestamp uint32 `json:"timestamp"` + Topic TopicType `json:"topic"` + Payload []byte `json:"payload"` + Padding []byte `json:"padding"` + PoW float64 `json:"pow"` + Hash []byte `json:"hash"` + Dst []byte `json:"recipientPublicKey,omitempty"` +} + +type messageOverride struct { + Sig hexutil.Bytes + Payload hexutil.Bytes + Padding hexutil.Bytes + Hash hexutil.Bytes + Dst hexutil.Bytes +} + +// ToWhisperMessage converts an internal message into an API version. +func ToWhisperMessage(message *ReceivedMessage) *Message { + msg := Message{ + Payload: message.Payload, + Padding: message.Padding, + Timestamp: message.Sent, + TTL: message.TTL, + PoW: message.PoW, + Hash: message.EnvelopeHash.Bytes(), + Topic: message.Topic, + } + + if message.Dst != nil { + b := crypto.FromECDSAPub(message.Dst) + if b != nil { + msg.Dst = b + } + } + + if isMessageSigned(message.Raw[0]) { + b := crypto.FromECDSAPub(message.SigToPubKey()) + if b != nil { + msg.Sig = b + } + } + + return &msg +} + +// toMessage converts a set of messages to its RPC representation. +func toMessage(messages []*ReceivedMessage) []*Message { + msgs := make([]*Message, len(messages)) + for i, msg := range messages { + msgs[i] = ToWhisperMessage(msg) + } + return msgs +} + +// GetFilterMessages returns the messages that match the filter criteria and +// are received between the last poll and now. +func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) { + api.mu.Lock() + f := api.w.GetFilter(id) + if f == nil { + api.mu.Unlock() + return nil, fmt.Errorf("filter not found") + } + api.lastUsed[id] = time.Now() + api.mu.Unlock() + + receivedMessages := f.Retrieve() + messages := make([]*Message, 0, len(receivedMessages)) + for _, msg := range receivedMessages { + messages = append(messages, ToWhisperMessage(msg)) + } + + return messages, nil +} + +// DeleteMessageFilter deletes a filter. +func (api *PublicWhisperAPI) DeleteMessageFilter(id string) (bool, error) { + api.mu.Lock() + defer api.mu.Unlock() + + delete(api.lastUsed, id) + return true, api.w.Unsubscribe(id) +} + +// NewMessageFilter creates a new filter that can be used to poll for +// (new) messages that satisfy the given criteria. +func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) { + var ( + src *ecdsa.PublicKey + keySym []byte + keyAsym *ecdsa.PrivateKey + topics [][]byte + + symKeyGiven = len(req.SymKeyID) > 0 + asymKeyGiven = len(req.PrivateKeyID) > 0 + + err error + ) + + // user must specify either a symmetric or an asymmetric key + if (symKeyGiven && asymKeyGiven) || (!symKeyGiven && !asymKeyGiven) { + return "", ErrSymAsym + } + + if len(req.Sig) > 0 { + if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil { + return "", ErrInvalidSigningPubKey + } + } + + if symKeyGiven { + if keySym, err = api.w.GetSymKey(req.SymKeyID); err != nil { + return "", err + } + if !validateDataIntegrity(keySym, aesKeyLength) { + return "", ErrInvalidSymmetricKey + } + } + + if asymKeyGiven { + if keyAsym, err = api.w.GetPrivateKey(req.PrivateKeyID); err != nil { + return "", err + } + } + + if len(req.Topics) > 0 { + topics = make([][]byte, len(req.Topics)) + for i, topic := range req.Topics { + topics[i] = make([]byte, TopicLength) + copy(topics[i], topic[:]) + } + } + + f := &Filter{ + Src: src, + KeySym: keySym, + KeyAsym: keyAsym, + PoW: req.MinPow, + AllowP2P: req.AllowP2P, + Topics: topics, + Messages: make(map[common.Hash]*ReceivedMessage), + } + + id, err := api.w.Subscribe(f) + if err != nil { + return "", err + } + + api.mu.Lock() + api.lastUsed[id] = time.Now() + api.mu.Unlock() + + return id, nil +} diff --git a/vendor/github.com/facebookgo/atomicfile/.travis.yml b/vendor/github.com/facebookgo/atomicfile/.travis.yml new file mode 100644 index 00000000..e3632ac5 --- /dev/null +++ b/vendor/github.com/facebookgo/atomicfile/.travis.yml @@ -0,0 +1,20 @@ +language: go + +go: + - 1.4 + +before_install: + - go get -v golang.org/x/tools/cmd/vet + - go get -v golang.org/x/tools/cmd/cover + - go get -v github.com/golang/lint/golint + +install: + - go install -race -v std + - go get -race -t -v ./... + - go install -race -v ./... + +script: + - go vet ./... + - $HOME/gopath/bin/golint . + - go test -cpu=2 -race -v ./... + - go test -cpu=2 -covermode=atomic ./... diff --git a/vendor/github.com/facebookgo/atomicfile/atomicfile.go b/vendor/github.com/facebookgo/atomicfile/atomicfile.go new file mode 100644 index 00000000..9294460d --- /dev/null +++ b/vendor/github.com/facebookgo/atomicfile/atomicfile.go @@ -0,0 +1,59 @@ +// Package atomicfile provides the ability to write a file with an eventual +// rename on Close (using os.Rename). This allows for a file to always be in a +// consistent state and never represent an in-progress write. +// +// NOTE: `os.Rename` may not be atomic on your operating system. +package atomicfile + +import ( + "io/ioutil" + "os" + "path/filepath" +) + +// File behaves like os.File, but does an atomic rename operation at Close. +type File struct { + *os.File + path string +} + +// New creates a new temporary file that will replace the file at the given +// path when Closed. +func New(path string, mode os.FileMode) (*File, error) { + f, err := ioutil.TempFile(filepath.Dir(path), filepath.Base(path)) + if err != nil { + return nil, err + } + if err := os.Chmod(f.Name(), mode); err != nil { + f.Close() + os.Remove(f.Name()) + return nil, err + } + return &File{File: f, path: path}, nil +} + +// Close the file replacing the configured file. +func (f *File) Close() error { + if err := f.File.Close(); err != nil { + os.Remove(f.File.Name()) + return err + } + if err := os.Rename(f.Name(), f.path); err != nil { + return err + } + return nil +} + +// Abort closes the file and removes it instead of replacing the configured +// file. This is useful if after starting to write to the file you decide you +// don't want it anymore. +func (f *File) Abort() error { + if err := f.File.Close(); err != nil { + os.Remove(f.Name()) + return err + } + if err := os.Remove(f.Name()); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/facebookgo/atomicfile/license b/vendor/github.com/facebookgo/atomicfile/license new file mode 100644 index 00000000..d8c91007 --- /dev/null +++ b/vendor/github.com/facebookgo/atomicfile/license @@ -0,0 +1,30 @@ +BSD License + +For atomicfile software + +Copyright (c) 2015, Facebook, Inc. All rights reserved. + +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 Facebook 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 HOLDER 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. diff --git a/vendor/github.com/facebookgo/atomicfile/patents b/vendor/github.com/facebookgo/atomicfile/patents new file mode 100644 index 00000000..50637e6f --- /dev/null +++ b/vendor/github.com/facebookgo/atomicfile/patents @@ -0,0 +1,33 @@ +Additional Grant of Patent Rights Version 2 + +"Software" means the atomicfile software distributed by Facebook, Inc. + +Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software +("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable +(subject to the termination provision below) license under any Necessary +Claims, to make, have made, use, sell, offer to sell, import, and otherwise +transfer the Software. For avoidance of doubt, no license is granted under +Facebook’s rights in any patent claims that are infringed by (i) modifications +to the Software made by you or any third party or (ii) the Software in +combination with any software or other technology. + +The license granted hereunder will terminate, automatically and without notice, +if you (or any of your subsidiaries, corporate affiliates or agents) initiate +directly or indirectly, or take a direct financial interest in, any Patent +Assertion: (i) against Facebook or any of its subsidiaries or corporate +affiliates, (ii) against any party if such Patent Assertion arises in whole or +in part from any software, technology, product or service of Facebook or any of +its subsidiaries or corporate affiliates, or (iii) against any party relating +to the Software. Notwithstanding the foregoing, if Facebook or any of its +subsidiaries or corporate affiliates files a lawsuit alleging patent +infringement against you in the first instance, and you respond by filing a +patent infringement counterclaim in that lawsuit against that party that is +unrelated to the Software, the license granted hereunder will not terminate +under section (i) of this paragraph due to such counterclaim. + +A "Necessary Claim" is a claim of a patent owned by Facebook that is +necessarily infringed by the Software standing alone. + +A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, +or contributory infringement or inducement to infringe any patent, including a +cross-claim or counterclaim. diff --git a/vendor/github.com/facebookgo/atomicfile/readme.md b/vendor/github.com/facebookgo/atomicfile/readme.md new file mode 100644 index 00000000..24a2544d --- /dev/null +++ b/vendor/github.com/facebookgo/atomicfile/readme.md @@ -0,0 +1,9 @@ +atomicfile [![Build Status](https://secure.travis-ci.org/facebookgo/atomicfile.png)](https://travis-ci.org/facebookgo/atomicfile) +========== + +Documentation: https://godoc.org/github.com/facebookgo/atomicfile + +NOTE: This package uses `os.Rename`, which may or may not be atomic on your +operating system. It is known to not be atomic on Windows. +https://github.com/natefinch/atomic provides a similar library that is atomic +on Windows as well and may be worth investigating. diff --git a/vendor/github.com/fjl/memsize/.travis.yml b/vendor/github.com/fjl/memsize/.travis.yml new file mode 100644 index 00000000..bc51dc01 --- /dev/null +++ b/vendor/github.com/fjl/memsize/.travis.yml @@ -0,0 +1,6 @@ +language: go +go: "1.10.x" +env: + - GOARCH=i386 + - GOARCH=amd64 +script: go test -v ./... diff --git a/vendor/github.com/fjl/memsize/LICENSE b/vendor/github.com/fjl/memsize/LICENSE new file mode 100644 index 00000000..8b804564 --- /dev/null +++ b/vendor/github.com/fjl/memsize/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Felix Lange + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/fjl/memsize/bitmap.go b/vendor/github.com/fjl/memsize/bitmap.go new file mode 100644 index 00000000..c3894a24 --- /dev/null +++ b/vendor/github.com/fjl/memsize/bitmap.go @@ -0,0 +1,119 @@ +package memsize + +import ( + "math/bits" +) + +const ( + uintptrBits = 32 << (uint64(^uintptr(0)) >> 63) + uintptrBytes = uintptrBits / 8 + bmBlockRange = 1 * 1024 * 1024 // bytes covered by bmBlock + bmBlockWords = bmBlockRange / uintptrBits +) + +// bitmap is a sparse bitmap. +type bitmap struct { + blocks map[uintptr]*bmBlock +} + +func newBitmap() *bitmap { + return &bitmap{make(map[uintptr]*bmBlock)} +} + +// markRange sets n consecutive bits starting at addr. +func (b *bitmap) markRange(addr, n uintptr) { + for end := addr + n; addr < end; { + block, baddr := b.block(addr) + for i := baddr; i < bmBlockRange && addr < end; i++ { + block.mark(i) + addr++ + } + } +} + +// isMarked returns the value of the bit at the given address. +func (b *bitmap) isMarked(addr uintptr) bool { + block, baddr := b.block(addr) + return block.isMarked(baddr) +} + +// countRange returns the number of set bits in the range [addr, addr+n]. +func (b *bitmap) countRange(addr, n uintptr) uintptr { + c := uintptr(0) + for end := addr + n; addr < end; { + block, baddr := b.block(addr) + bend := uintptr(bmBlockRange - 1) + if baddr+(end-addr) < bmBlockRange { + bend = baddr + (end - addr) + } + c += uintptr(block.count(baddr, bend)) + // Move addr to next block. + addr += bmBlockRange - baddr + } + return c +} + +// block finds the block corresponding to the given memory address. +// It also returns the block's starting address. +func (b *bitmap) block(addr uintptr) (*bmBlock, uintptr) { + index := addr / bmBlockRange + block := b.blocks[index] + if block == nil { + block = new(bmBlock) + b.blocks[index] = block + } + return block, addr % bmBlockRange +} + +// size returns the sum of the byte sizes of all blocks. +func (b *bitmap) size() uintptr { + return uintptr(len(b.blocks)) * bmBlockWords * uintptrBytes +} + +// utilization returns the mean percentage of one bits across all blocks. +func (b *bitmap) utilization() float32 { + var avg float32 + for _, block := range b.blocks { + avg += float32(block.count(0, bmBlockRange-1)) / float32(bmBlockRange) + } + return avg / float32(len(b.blocks)) +} + +// bmBlock is a bitmap block. +type bmBlock [bmBlockWords]uintptr + +// mark sets the i'th bit to one. +func (b *bmBlock) mark(i uintptr) { + b[i/uintptrBits] |= 1 << (i % uintptrBits) +} + +// isMarked returns the value of the i'th bit. +func (b *bmBlock) isMarked(i uintptr) bool { + return (b[i/uintptrBits] & (1 << (i % uintptrBits))) != 0 +} + +// count returns the number of set bits in the range [start, end]. +func (b *bmBlock) count(start, end uintptr) (count int) { + br := b[start/uintptrBits : end/uintptrBits+1] + for i, w := range br { + if i == 0 { + w &= blockmask(start) + } + if i == len(br)-1 { + w &^= blockmask(end) + } + count += onesCountPtr(w) + } + return count +} + +func blockmask(x uintptr) uintptr { + return ^uintptr(0) << (x % uintptrBits) +} + +func onesCountPtr(x uintptr) int { + if uintptrBits == 64 { + return bits.OnesCount64(uint64(x)) + } + return bits.OnesCount32(uint32(x)) +} diff --git a/vendor/github.com/fjl/memsize/doc.go b/vendor/github.com/fjl/memsize/doc.go new file mode 100644 index 00000000..640cfba5 --- /dev/null +++ b/vendor/github.com/fjl/memsize/doc.go @@ -0,0 +1,16 @@ +/* +Package memsize computes the size of your object graph. + +So you made a spiffy algorithm and it works really well, but geez it's using +way too much memory. Where did it all go? memsize to the rescue! + +To get started, find a value that references all your objects and scan it. +This traverses the graph, counting sizes per type. + + sizes := memsize.Scan(myValue) + fmt.Println(sizes.Total) + +memsize can handle cycles just fine and tracks both private and public struct fields. +Unfortunately function closures cannot be inspected in any way. +*/ +package memsize diff --git a/vendor/github.com/fjl/memsize/go.mod b/vendor/github.com/fjl/memsize/go.mod new file mode 100644 index 00000000..094bf037 --- /dev/null +++ b/vendor/github.com/fjl/memsize/go.mod @@ -0,0 +1 @@ +module github.com/fjl/memsize diff --git a/vendor/github.com/fjl/memsize/memsize.go b/vendor/github.com/fjl/memsize/memsize.go new file mode 100644 index 00000000..fcbff1f8 --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsize.go @@ -0,0 +1,246 @@ +package memsize + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" + "text/tabwriter" + "unsafe" +) + +// Scan traverses all objects reachable from v and counts how much memory +// is used per type. The value must be a non-nil pointer to any value. +func Scan(v interface{}) Sizes { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + panic("value to scan must be non-nil pointer") + } + + stopTheWorld("memsize scan") + defer startTheWorld() + + ctx := newContext() + ctx.scan(invalidAddr, rv, false) + ctx.s.BitmapSize = ctx.seen.size() + ctx.s.BitmapUtilization = ctx.seen.utilization() + return *ctx.s +} + +// Sizes is the result of a scan. +type Sizes struct { + Total uintptr + ByType map[reflect.Type]*TypeSize + // Internal stats (for debugging) + BitmapSize uintptr + BitmapUtilization float32 +} + +type TypeSize struct { + Total uintptr + Count uintptr +} + +func newSizes() *Sizes { + return &Sizes{ByType: make(map[reflect.Type]*TypeSize)} +} + +// Report returns a human-readable report. +func (s Sizes) Report() string { + type typLine struct { + name string + count uintptr + total uintptr + } + tab := []typLine{{"ALL", 0, s.Total}} + for _, typ := range s.ByType { + tab[0].count += typ.Count + } + maxname := 0 + for typ, s := range s.ByType { + line := typLine{typ.String(), s.Count, s.Total} + tab = append(tab, line) + if len(line.name) > maxname { + maxname = len(line.name) + } + } + sort.Slice(tab, func(i, j int) bool { return tab[i].total > tab[j].total }) + + buf := new(bytes.Buffer) + w := tabwriter.NewWriter(buf, 0, 0, 0, ' ', tabwriter.AlignRight) + for _, line := range tab { + namespace := strings.Repeat(" ", maxname-len(line.name)) + fmt.Fprintf(w, "%s%s\t %v\t %s\t\n", line.name, namespace, line.count, HumanSize(line.total)) + } + w.Flush() + return buf.String() +} + +// addValue is called during scan and adds the memory of given object. +func (s *Sizes) addValue(v reflect.Value, size uintptr) { + s.Total += size + rs := s.ByType[v.Type()] + if rs == nil { + rs = new(TypeSize) + s.ByType[v.Type()] = rs + } + rs.Total += size + rs.Count++ +} + +type context struct { + // We track previously scanned objects to prevent infinite loops + // when scanning cycles and to prevent counting objects more than once. + seen *bitmap + tc typCache + s *Sizes +} + +func newContext() *context { + return &context{seen: newBitmap(), tc: make(typCache), s: newSizes()} +} + +// scan walks all objects below v, determining their size. It returns the size of the +// previously unscanned parts of the object. +func (c *context) scan(addr address, v reflect.Value, add bool) (extraSize uintptr) { + size := v.Type().Size() + var marked uintptr + if addr.valid() { + marked = c.seen.countRange(uintptr(addr), size) + if marked == size { + return 0 // Skip if we have already seen the whole object. + } + c.seen.markRange(uintptr(addr), size) + } + // fmt.Printf("%v: %v ⮑ (marked %d)\n", addr, v.Type(), marked) + if c.tc.needScan(v.Type()) { + extraSize = c.scanContent(addr, v) + } + size -= marked + size += extraSize + // fmt.Printf("%v: %v %d (add %v, size %d, marked %d, extra %d)\n", addr, v.Type(), size+extraSize, add, v.Type().Size(), marked, extraSize) + if add { + c.s.addValue(v, size) + } + return size +} + +// scanContent and all other scan* functions below return the amount of 'extra' memory +// (e.g. slice data) that is referenced by the object. +func (c *context) scanContent(addr address, v reflect.Value) uintptr { + switch v.Kind() { + case reflect.Array: + return c.scanArray(addr, v) + case reflect.Chan: + return c.scanChan(v) + case reflect.Func: + // can't do anything here + return 0 + case reflect.Interface: + return c.scanInterface(v) + case reflect.Map: + return c.scanMap(v) + case reflect.Ptr: + if !v.IsNil() { + c.scan(address(v.Pointer()), v.Elem(), true) + } + return 0 + case reflect.Slice: + return c.scanSlice(v) + case reflect.String: + return uintptr(v.Len()) + case reflect.Struct: + return c.scanStruct(addr, v) + default: + unhandledKind(v.Kind()) + return 0 + } +} + +func (c *context) scanChan(v reflect.Value) uintptr { + etyp := v.Type().Elem() + extra := uintptr(0) + if c.tc.needScan(etyp) { + // Scan the channel buffer. This is unsafe but doesn't race because + // the world is stopped during scan. + hchan := unsafe.Pointer(v.Pointer()) + for i := uint(0); i < uint(v.Cap()); i++ { + addr := chanbuf(hchan, i) + elem := reflect.NewAt(etyp, addr).Elem() + extra += c.scanContent(address(addr), elem) + } + } + return uintptr(v.Cap())*etyp.Size() + extra +} + +func (c *context) scanStruct(base address, v reflect.Value) uintptr { + extra := uintptr(0) + for i := 0; i < v.NumField(); i++ { + f := v.Type().Field(i) + if c.tc.needScan(f.Type) { + addr := base.addOffset(f.Offset) + extra += c.scanContent(addr, v.Field(i)) + } + } + return extra +} + +func (c *context) scanArray(addr address, v reflect.Value) uintptr { + esize := v.Type().Elem().Size() + extra := uintptr(0) + for i := 0; i < v.Len(); i++ { + extra += c.scanContent(addr, v.Index(i)) + addr = addr.addOffset(esize) + } + return extra +} + +func (c *context) scanSlice(v reflect.Value) uintptr { + slice := v.Slice(0, v.Cap()) + esize := slice.Type().Elem().Size() + base := slice.Pointer() + // Add size of the unscanned portion of the backing array to extra. + blen := uintptr(slice.Len()) * esize + marked := c.seen.countRange(base, blen) + extra := blen - marked + c.seen.markRange(uintptr(base), blen) + if c.tc.needScan(slice.Type().Elem()) { + // Elements may contain pointers, scan them individually. + addr := address(base) + for i := 0; i < slice.Len(); i++ { + extra += c.scanContent(addr, slice.Index(i)) + addr = addr.addOffset(esize) + } + } + return extra +} + +func (c *context) scanMap(v reflect.Value) uintptr { + var ( + typ = v.Type() + len = uintptr(v.Len()) + extra = uintptr(0) + ) + if c.tc.needScan(typ.Key()) || c.tc.needScan(typ.Elem()) { + for _, k := range v.MapKeys() { + extra += c.scan(invalidAddr, k, false) + extra += c.scan(invalidAddr, v.MapIndex(k), false) + } + } else { + extra = len*typ.Key().Size() + len*typ.Elem().Size() + } + return extra +} + +func (c *context) scanInterface(v reflect.Value) uintptr { + elem := v.Elem() + if !elem.IsValid() { + return 0 // nil interface + } + extra := c.scan(invalidAddr, elem, false) + if elem.Type().Kind() == reflect.Ptr { + extra -= uintptrBytes + } + return extra +} diff --git a/vendor/github.com/fjl/memsize/memsizeui/template.go b/vendor/github.com/fjl/memsize/memsizeui/template.go new file mode 100644 index 00000000..b60fe6ba --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsizeui/template.go @@ -0,0 +1,106 @@ +package memsizeui + +import ( + "html/template" + "strconv" + "sync" + + "github.com/fjl/memsize" +) + +var ( + base *template.Template // the "base" template + baseInitOnce sync.Once +) + +func baseInit() { + base = template.Must(template.New("base").Parse(` + + + + memsize + + + + {{template "content" .}} + +`)) + + base.Funcs(template.FuncMap{ + "quote": strconv.Quote, + "humansize": memsize.HumanSize, + }) + + template.Must(base.New("rootbuttons").Parse(` +
Overview +{{- range $root := .Roots -}} +
+ +
+{{- end -}}`)) +} + +func contentTemplate(source string) *template.Template { + baseInitOnce.Do(baseInit) + t := template.Must(base.Clone()) + template.Must(t.New("content").Parse(source)) + return t +} + +var rootTemplate = contentTemplate(` +

Memsize

+{{template "rootbuttons" .}} +
+

Reports

+ +`) + +var notFoundTemplate = contentTemplate(` +

{{.Data}}

+{{template "rootbuttons" .}} +`) + +var reportTemplate = contentTemplate(` +{{- $report := .Data -}} +

Memsize Report {{$report.ID}}

+
+ Overview + +
+
+Root: {{quote $report.RootName}}
+Date: {{$report.Date}}
+Duration: {{$report.Duration}}
+Bitmap Size: {{$report.Sizes.BitmapSize | humansize}}
+Bitmap Utilization: {{$report.Sizes.BitmapUtilization}}
+
+
+
+{{$report.Sizes.Report}}
+
+`) diff --git a/vendor/github.com/fjl/memsize/memsizeui/ui.go b/vendor/github.com/fjl/memsize/memsizeui/ui.go new file mode 100644 index 00000000..c48fc53f --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsizeui/ui.go @@ -0,0 +1,153 @@ +package memsizeui + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "reflect" + "sort" + "strings" + "sync" + "time" + + "github.com/fjl/memsize" +) + +type Handler struct { + init sync.Once + mux http.ServeMux + mu sync.Mutex + reports map[int]Report + roots map[string]interface{} + reportID int +} + +type Report struct { + ID int + Date time.Time + Duration time.Duration + RootName string + Sizes memsize.Sizes +} + +type templateInfo struct { + Roots []string + Reports map[int]Report + PathDepth int + Data interface{} +} + +func (ti *templateInfo) Link(path ...string) string { + prefix := strings.Repeat("../", ti.PathDepth) + return prefix + strings.Join(path, "") +} + +func (h *Handler) Add(name string, v interface{}) { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + panic("root must be non-nil pointer") + } + h.mu.Lock() + if h.roots == nil { + h.roots = make(map[string]interface{}) + } + h.roots[name] = v + h.mu.Unlock() +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.init.Do(func() { + h.reports = make(map[int]Report) + h.mux.HandleFunc("/", h.handleRoot) + h.mux.HandleFunc("/scan", h.handleScan) + h.mux.HandleFunc("/report/", h.handleReport) + }) + h.mux.ServeHTTP(w, r) +} + +func (h *Handler) templateInfo(r *http.Request, data interface{}) *templateInfo { + h.mu.Lock() + roots := make([]string, 0, len(h.roots)) + for name := range h.roots { + roots = append(roots, name) + } + h.mu.Unlock() + sort.Strings(roots) + + return &templateInfo{ + Roots: roots, + Reports: h.reports, + PathDepth: strings.Count(r.URL.Path, "/") - 1, + Data: data, + } +} + +func (h *Handler) handleRoot(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + serveHTML(w, rootTemplate, http.StatusOK, h.templateInfo(r, nil)) +} + +func (h *Handler) handleScan(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "invalid HTTP method, want POST", http.StatusMethodNotAllowed) + return + } + ti := h.templateInfo(r, "Unknown root") + id, ok := h.scan(r.URL.Query().Get("root")) + if !ok { + serveHTML(w, notFoundTemplate, http.StatusNotFound, ti) + return + } + w.Header().Add("Location", ti.Link(fmt.Sprintf("report/%d", id))) + w.WriteHeader(http.StatusSeeOther) +} + +func (h *Handler) handleReport(w http.ResponseWriter, r *http.Request) { + var id int + fmt.Sscan(strings.TrimPrefix(r.URL.Path, "/report/"), &id) + h.mu.Lock() + report, ok := h.reports[id] + h.mu.Unlock() + + if !ok { + serveHTML(w, notFoundTemplate, http.StatusNotFound, h.templateInfo(r, "Report not found")) + } else { + serveHTML(w, reportTemplate, http.StatusOK, h.templateInfo(r, report)) + } +} + +func (h *Handler) scan(root string) (int, bool) { + h.mu.Lock() + defer h.mu.Unlock() + + val, ok := h.roots[root] + if !ok { + return 0, false + } + id := h.reportID + start := time.Now() + sizes := memsize.Scan(val) + h.reports[id] = Report{ + ID: id, + RootName: root, + Date: start.Truncate(1 * time.Second), + Duration: time.Since(start), + Sizes: sizes, + } + h.reportID++ + return id, true +} + +func serveHTML(w http.ResponseWriter, tpl *template.Template, status int, ti *templateInfo) { + w.Header().Set("content-type", "text/html") + var buf bytes.Buffer + if err := tpl.Execute(&buf, ti); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + buf.WriteTo(w) +} diff --git a/vendor/github.com/fjl/memsize/runtimefunc.go b/vendor/github.com/fjl/memsize/runtimefunc.go new file mode 100644 index 00000000..912a3e76 --- /dev/null +++ b/vendor/github.com/fjl/memsize/runtimefunc.go @@ -0,0 +1,14 @@ +package memsize + +import "unsafe" + +var _ = unsafe.Pointer(nil) + +//go:linkname stopTheWorld runtime.stopTheWorld +func stopTheWorld(reason string) + +//go:linkname startTheWorld runtime.startTheWorld +func startTheWorld() + +//go:linkname chanbuf runtime.chanbuf +func chanbuf(ch unsafe.Pointer, i uint) unsafe.Pointer diff --git a/vendor/github.com/fjl/memsize/runtimefunc.s b/vendor/github.com/fjl/memsize/runtimefunc.s new file mode 100644 index 00000000..a091e2fa --- /dev/null +++ b/vendor/github.com/fjl/memsize/runtimefunc.s @@ -0,0 +1 @@ +// This file is required to make stub function declarations work. diff --git a/vendor/github.com/fjl/memsize/type.go b/vendor/github.com/fjl/memsize/type.go new file mode 100644 index 00000000..5d6f59e9 --- /dev/null +++ b/vendor/github.com/fjl/memsize/type.go @@ -0,0 +1,119 @@ +package memsize + +import ( + "fmt" + "reflect" +) + +// address is a memory location. +// +// Code dealing with uintptr is oblivious to the zero address. +// Code dealing with address is not: it treats the zero address +// as invalid. Offsetting an invalid address doesn't do anything. +// +// This distinction is useful because there are objects that we can't +// get the pointer to. +type address uintptr + +const invalidAddr = address(0) + +func (a address) valid() bool { + return a != 0 +} + +func (a address) addOffset(off uintptr) address { + if !a.valid() { + return invalidAddr + } + return a + address(off) +} + +func (a address) String() string { + if uintptrBits == 32 { + return fmt.Sprintf("%#0.8x", uintptr(a)) + } + return fmt.Sprintf("%#0.16x", uintptr(a)) +} + +type typCache map[reflect.Type]typInfo + +type typInfo struct { + isPointer bool + needScan bool +} + +// isPointer returns true for pointer-ish values. The notion of +// pointer includes everything but plain values, i.e. slices, maps +// channels, interfaces are 'pointer', too. +func (tc *typCache) isPointer(typ reflect.Type) bool { + return tc.info(typ).isPointer +} + +// needScan reports whether a value of the type needs to be scanned +// recursively because it may contain pointers. +func (tc *typCache) needScan(typ reflect.Type) bool { + return tc.info(typ).needScan +} + +func (tc *typCache) info(typ reflect.Type) typInfo { + info, found := (*tc)[typ] + switch { + case found: + return info + case isPointer(typ): + info = typInfo{true, true} + default: + info = typInfo{false, tc.checkNeedScan(typ)} + } + (*tc)[typ] = info + return info +} + +func (tc *typCache) checkNeedScan(typ reflect.Type) bool { + switch k := typ.Kind(); k { + case reflect.Struct: + // Structs don't need scan if none of their fields need it. + for i := 0; i < typ.NumField(); i++ { + if tc.needScan(typ.Field(i).Type) { + return true + } + } + case reflect.Array: + // Arrays don't need scan if their element type doesn't. + return tc.needScan(typ.Elem()) + } + return false +} + +func isPointer(typ reflect.Type) bool { + k := typ.Kind() + switch { + case k <= reflect.Complex128: + return false + case k == reflect.Array: + return false + case k >= reflect.Chan && k <= reflect.String: + return true + case k == reflect.Struct || k == reflect.UnsafePointer: + return false + default: + unhandledKind(k) + return false + } +} + +func unhandledKind(k reflect.Kind) { + panic("unhandled kind " + k.String()) +} + +// HumanSize formats the given number of bytes as a readable string. +func HumanSize(bytes uintptr) string { + switch { + case bytes < 1024: + return fmt.Sprintf("%d B", bytes) + case bytes < 1024*1024: + return fmt.Sprintf("%.3f KB", float64(bytes)/1024) + default: + return fmt.Sprintf("%.3f MB", float64(bytes)/1024/1024) + } +} diff --git a/vendor/github.com/gballet/go-libpcsclite/.gitignore b/vendor/github.com/gballet/go-libpcsclite/.gitignore new file mode 100644 index 00000000..f1c181ec --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/vendor/github.com/gballet/go-libpcsclite/LICENSE b/vendor/github.com/gballet/go-libpcsclite/LICENSE new file mode 100644 index 00000000..52d9e62b --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2019, Guillaume Ballet +All rights reserved. + +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 the copyright holder 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 HOLDER 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. diff --git a/vendor/github.com/gballet/go-libpcsclite/README.md b/vendor/github.com/gballet/go-libpcsclite/README.md new file mode 100644 index 00000000..182398e3 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/README.md @@ -0,0 +1,73 @@ +# go-libpcsclite + +A golang implementation of the [libpcpsclite](http://github.com/LudovicRousseau/PCSC) client. It connects to the `pcscd` daemon over sockets. + +## Purpose + +The goal is for major open source projects to distribute a single binary that doesn't depend on `libpcsclite`. It provides an extra function `CheckPCSCDaemon` that will tell the user if `pcscd` is running. + +## Example + +```golang +func main() { + client, err := EstablishContext(2) + if err != nil { + fmt.Printf("Error establishing context: %v\n", err) + os.Exit(1) + } + + _, err = client.ListReaders() + if err != nil { + fmt.Printf("Error getting the list of readers: %v\n", err) + os.Exit(1) + } + + card, err := client.Connect(client.readerStateDescriptors[0].Name, ShareShared, ProtocolT0|ProtocolT1) + if err != nil { + fmt.Printf("Error connecting: %v\n", err) + os.Exit(1) + } + + resp, _, err := card.Transmit([]byte{0, 0xa4, 4, 0, 0xA0, 0, 0, 8, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}) + + card.Disconnect(LeaveCard) +} +``` + +## TODO + + - [x] Finish this README + - [x] Lock context + - [ ] implement missing functions + +## License + +BSD 3-Clause License + +Copyright (c) 2019, Guillaume Ballet +All rights reserved. + +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 the copyright holder 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 HOLDER 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. diff --git a/vendor/github.com/gballet/go-libpcsclite/doc.go b/vendor/github.com/gballet/go-libpcsclite/doc.go new file mode 100644 index 00000000..0f28c0c9 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/doc.go @@ -0,0 +1,95 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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 pcsc + +const ( + AutoAllocate = -1 /* see SCardFreeMemory() */ + ScopeUser = 0x0000 /* Scope in user space */ + ScopeTerminal = 0x0001 /* Scope in terminal */ + ScopeSystem = 0x0002 /* Scope in system */ + ScopeGlobal = 0x0003 /* Scope is global */ + + ProtocolUndefined = 0x0000 /* protocol not set */ + ProtocolUnSet = ProtocolUndefined /* backward compat */ + ProtocolT0 = 0x0001 /* T=0 active protocol. */ + ProtocolT1 = 0x0002 /* T=1 active protocol. */ + ProtocolRaw = 0x0004 /* Raw active protocol. */ + ProtocolT15 = 0x0008 /* T=15 protocol. */ + ProtocolAny = (ProtocolT0 | ProtocolT1) /* IFD determines prot. */ + + ShareExclusive = 0x0001 /* Exclusive mode only */ + ShareShared = 0x0002 /* Shared mode only */ + ShareDirect = 0x0003 /* Raw mode only */ + + LeaveCard = 0x0000 /* Do nothing on close */ + ResetCard = 0x0001 /* Reset on close */ + UnpowerCard = 0x0002 /* Power down on close */ + EjectCard = 0x0003 /* Eject on close */ + + SCardUnknown = 0x0001 /* Unknown state */ + SCardAbsent = 0x0002 /* Card is absent */ + SCardPresent = 0x0004 /* Card is present */ + SCardSwallowed = 0x0008 /* Card not powered */ + SCardPowever = 0x0010 /* Card is powered */ + SCardNegotiable = 0x0020 /* Ready for PTS */ + SCardSpecific = 0x0040 /* PTS has been set */ +) + +// List of commands to send to the daemon +const ( + _ = iota + SCardEstablishContext /* used by SCardEstablishContext() */ + SCardReleaseContext /* used by SCardReleaseContext() */ + SCardListReaders /* used by SCardListReaders() */ + SCardConnect /* used by SCardConnect() */ + SCardReConnect /* used by SCardReconnect() */ + SCardDisConnect /* used by SCardDisconnect() */ + SCardBeginTransaction /* used by SCardBeginTransaction() */ + SCardEndTransaction /* used by SCardEndTransaction() */ + SCardTransmit /* used by SCardTransmit() */ + SCardControl /* used by SCardControl() */ + SCardStatus /* used by SCardStatus() */ + SCardGetStatusChange /* not used */ + SCardCancel /* used by SCardCancel() */ + SCardCancelTransaction /* not used */ + SCardGetAttrib /* used by SCardGetAttrib() */ + SCardSetAttrib /* used by SCardSetAttrib() */ + CommandVersion /* get the client/server protocol version */ + CommandGetReaderState /* get the readers state */ + CommandWaitReaderStateChange /* wait for a reader state change */ + CommandStopWaitingReaderStateChange /* stop waiting for a reader state change */ +) + +// Protocol information +const ( + ProtocolVersionMajor = uint32(4) /* IPC major */ + ProtocolVersionMinor = uint32(3) /* IPC minor */ +) diff --git a/vendor/github.com/gballet/go-libpcsclite/doc_bsd.go b/vendor/github.com/gballet/go-libpcsclite/doc_bsd.go new file mode 100644 index 00000000..672c672e --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/doc_bsd.go @@ -0,0 +1,35 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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. + +// +build dragonfly freebsd netbsd openbsd solaris + +package pcsc + +const PCSCDSockName string = "/var/run/pcscd/pcscd.comm" diff --git a/vendor/github.com/gballet/go-libpcsclite/doc_darwin.go b/vendor/github.com/gballet/go-libpcsclite/doc_darwin.go new file mode 100644 index 00000000..3dec7c79 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/doc_darwin.go @@ -0,0 +1,35 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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. + +// +build darwin + +package pcsc + +const PCSCDSockName string = "" diff --git a/vendor/github.com/gballet/go-libpcsclite/doc_linux.go b/vendor/github.com/gballet/go-libpcsclite/doc_linux.go new file mode 100644 index 00000000..becbf167 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/doc_linux.go @@ -0,0 +1,35 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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. + +// +build linux + +package pcsc + +const PCSCDSockName string = "/run/pcscd/pcscd.comm" \ No newline at end of file diff --git a/vendor/github.com/gballet/go-libpcsclite/doc_windows.go b/vendor/github.com/gballet/go-libpcsclite/doc_windows.go new file mode 100644 index 00000000..9bd6bd33 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/doc_windows.go @@ -0,0 +1,35 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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. + +// +build windows + +package pcsc + +const PCSCDSockName string = "" diff --git a/vendor/github.com/gballet/go-libpcsclite/error.go b/vendor/github.com/gballet/go-libpcsclite/error.go new file mode 100644 index 00000000..4710de5e --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/error.go @@ -0,0 +1,246 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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 pcsc + +import "fmt" + +type ErrorCode uint32 + +const ( + SCardSuccess ErrorCode = 0x00000000 /* No error was encountered. */ + ErrSCardInternal = 0x80100001 /* An internal consistency check failed. */ + ErrSCardCancelled = 0x80100002 /* The action was cancelled by an SCardCancel request. */ + ErrSCardInvalidHandle = 0x80100003 /* The supplied handle was invalid. */ + ErrSCardInvalidParameter = 0x80100004 /* One or more of the supplied parameters could not be properly interpreted. */ + ErrSCardInvalidTarget = 0x80100005 /* Registry startup information is missing or invalid. */ + ErrSCardNoMemory = 0x80100006 /* Not enough memory available to complete this command. */ + ErrSCardWaitedTooLong = 0x80100007 /* An internal consistency timer has expired. */ + ErrSCardInsufficientBuffer = 0x80100008 /* The data buffer to receive returned data is too small for the returned data. */ + ErrScardUnknownReader = 0x80100009 /* The specified reader name is not recognized. */ + ErrSCardTimeout = 0x8010000A /* The user-specified timeout value has expired. */ + ErrSCardSharingViolation = 0x8010000B /* The smart card cannot be accessed because of other connections outstanding. */ + ErrSCardNoSmartCard = 0x8010000C /* The operation requires a Smart Card, but no Smart Card is currently in the device. */ + ErrSCardUnknownCard = 0x8010000D /* The specified smart card name is not recognized. */ + ErrSCardCannotDispose = 0x8010000E /* The system could not dispose of the media in the requested manner. */ + ErrSCardProtoMismatch = 0x8010000F /* The requested protocols are incompatible with the protocol currently in use with the smart card. */ + ErrSCardNotReady = 0x80100010 /* The reader or smart card is not ready to accept commands. */ + ErrSCardInvalidValue = 0x80100011 /* One or more of the supplied parameters values could not be properly interpreted. */ + ErrSCardSystemCancelled = 0x80100012 /* The action was cancelled by the system, presumably to log off or shut down. */ + ErrSCardCommError = 0x80100013 /* An internal communications error has been detected. */ + ErrScardUnknownError = 0x80100014 /* An internal error has been detected, but the source is unknown. */ + ErrSCardInvalidATR = 0x80100015 /* An ATR obtained from the registry is not a valid ATR string. */ + ErrSCardNotTransacted = 0x80100016 /* An attempt was made to end a non-existent transaction. */ + ErrSCardReaderUnavailable = 0x80100017 /* The specified reader is not currently available for use. */ + ErrSCardShutdown = 0x80100018 /* The operation has been aborted to allow the server application to exit. */ + ErrSCardPCITooSmall = 0x80100019 /* The PCI Receive buffer was too small. */ + ErrSCardReaderUnsupported = 0x8010001A /* The reader driver does not meet minimal requirements for support. */ + ErrSCardDuplicateReader = 0x8010001B /* The reader driver did not produce a unique reader name. */ + ErrSCardCardUnsupported = 0x8010001C /* The smart card does not meet minimal requirements for support. */ + ErrScardNoService = 0x8010001D /* The Smart card resource manager is not running. */ + ErrSCardServiceStopped = 0x8010001E /* The Smart card resource manager has shut down. */ + ErrSCardUnexpected = 0x8010001F /* An unexpected card error has occurred. */ + ErrSCardUnsupportedFeature = 0x8010001F /* This smart card does not support the requested feature. */ + ErrSCardICCInstallation = 0x80100020 /* No primary provider can be found for the smart card. */ + ErrSCardICCCreateOrder = 0x80100021 /* The requested order of object creation is not supported. */ + ErrSCardDirNotFound = 0x80100023 /* The identified directory does not exist in the smart card. */ + ErrSCardFileNotFound = 0x80100024 /* The identified file does not exist in the smart card. */ + ErrSCardNoDir = 0x80100025 /* The supplied path does not represent a smart card directory. */ + ErrSCardNoFile = 0x80100026 /* The supplied path does not represent a smart card file. */ + ErrScardNoAccess = 0x80100027 /* Access is denied to this file. */ + ErrSCardWriteTooMany = 0x80100028 /* The smart card does not have enough memory to store the information. */ + ErrSCardBadSeek = 0x80100029 /* There was an error trying to set the smart card file object pointer. */ + ErrSCardInvalidCHV = 0x8010002A /* The supplied PIN is incorrect. */ + ErrSCardUnknownResMNG = 0x8010002B /* An unrecognized error code was returned from a layered component. */ + ErrSCardNoSuchCertificate = 0x8010002C /* The requested certificate does not exist. */ + ErrSCardCertificateUnavailable = 0x8010002D /* The requested certificate could not be obtained. */ + ErrSCardNoReadersAvailable = 0x8010002E /* Cannot find a smart card reader. */ + ErrSCardCommDataLost = 0x8010002F /* A communications error with the smart card has been detected. Retry the operation. */ + ErrScardNoKeyContainer = 0x80100030 /* The requested key container does not exist on the smart card. */ + ErrSCardServerTooBusy = 0x80100031 /* The Smart Card Resource Manager is too busy to complete this operation. */ + ErrSCardUnsupportedCard = 0x80100065 /* The reader cannot communicate with the card, due to ATR string configuration conflicts. */ + ErrSCardUnresponsiveCard = 0x80100066 /* The smart card is not responding to a reset. */ + ErrSCardUnpoweredCard = 0x80100067 /* Power has been removed from the smart card, so that further communication is not possible. */ + ErrSCardResetCard = 0x80100068 /* The smart card has been reset, so any shared state information is invalid. */ + ErrSCardRemovedCard = 0x80100069 /* The smart card has been removed, so further communication is not possible. */ + ErrSCardSecurityViolation = 0x8010006A /* Access was denied because of a security violation. */ + ErrSCardWrongCHV = 0x8010006B /* The card cannot be accessed because the wrong PIN was presented. */ + ErrSCardCHVBlocked = 0x8010006C /* The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */ + ErrSCardEOF = 0x8010006D /* The end of the smart card file has been reached. */ + ErrSCardCancelledByUser = 0x8010006E /* The user pressed "Cancel" on a Smart Card Selection Dialog. */ + ErrSCardCardNotAuthenticated = 0x8010006F /* No PIN was presented to the smart card. */ +) + +// Code returns the error code, with an uint32 type to be used in PutUInt32 +func (code ErrorCode) Code() uint32 { + return uint32(code) +} + +func (code ErrorCode) Error() error { + switch code { + case SCardSuccess: + return fmt.Errorf("Command successful") + + case ErrSCardInternal: + return fmt.Errorf("Internal error") + + case ErrSCardCancelled: + return fmt.Errorf("Command cancelled") + + case ErrSCardInvalidHandle: + return fmt.Errorf("Invalid handle") + + case ErrSCardInvalidParameter: + return fmt.Errorf("Invalid parameter given") + + case ErrSCardInvalidTarget: + return fmt.Errorf("Invalid target given") + + case ErrSCardNoMemory: + return fmt.Errorf("Not enough memory") + + case ErrSCardWaitedTooLong: + return fmt.Errorf("Waited too long") + + case ErrSCardInsufficientBuffer: + return fmt.Errorf("Insufficient buffer") + + case ErrScardUnknownReader: + return fmt.Errorf("Unknown reader specified") + + case ErrSCardTimeout: + return fmt.Errorf("Command timeout") + + case ErrSCardSharingViolation: + return fmt.Errorf("Sharing violation") + + case ErrSCardNoSmartCard: + return fmt.Errorf("No smart card inserted") + + case ErrSCardUnknownCard: + return fmt.Errorf("Unknown card") + + case ErrSCardCannotDispose: + return fmt.Errorf("Cannot dispose handle") + + case ErrSCardProtoMismatch: + return fmt.Errorf("Card protocol mismatch") + + case ErrSCardNotReady: + return fmt.Errorf("Subsystem not ready") + + case ErrSCardInvalidValue: + return fmt.Errorf("Invalid value given") + + case ErrSCardSystemCancelled: + return fmt.Errorf("System cancelled") + + case ErrSCardCommError: + return fmt.Errorf("RPC transport error") + + case ErrScardUnknownError: + return fmt.Errorf("Unknown error") + + case ErrSCardInvalidATR: + return fmt.Errorf("Invalid ATR") + + case ErrSCardNotTransacted: + return fmt.Errorf("Transaction failed") + + case ErrSCardReaderUnavailable: + return fmt.Errorf("Reader is unavailable") + + /* case SCARD_P_SHUTDOWN: */ + case ErrSCardPCITooSmall: + return fmt.Errorf("PCI struct too small") + + case ErrSCardReaderUnsupported: + return fmt.Errorf("Reader is unsupported") + + case ErrSCardDuplicateReader: + return fmt.Errorf("Reader already exists") + + case ErrSCardCardUnsupported: + return fmt.Errorf("Card is unsupported") + + case ErrScardNoService: + return fmt.Errorf("Service not available") + + case ErrSCardServiceStopped: + return fmt.Errorf("Service was stopped") + + /* case SCARD_E_UNEXPECTED: */ + /* case SCARD_E_ICC_CREATEORDER: */ + /* case SCARD_E_UNSUPPORTED_FEATURE: */ + /* case SCARD_E_DIR_NOT_FOUND: */ + /* case SCARD_E_NO_DIR: */ + /* case SCARD_E_NO_FILE: */ + /* case SCARD_E_NO_ACCESS: */ + /* case SCARD_E_WRITE_TOO_MANY: */ + /* case SCARD_E_BAD_SEEK: */ + /* case SCARD_E_INVALID_CHV: */ + /* case SCARD_E_UNKNOWN_RES_MNG: */ + /* case SCARD_E_NO_SUCH_CERTIFICATE: */ + /* case SCARD_E_CERTIFICATE_UNAVAILABLE: */ + case ErrSCardNoReadersAvailable: + return fmt.Errorf("Cannot find a smart card reader") + + /* case SCARD_E_COMM_DATA_LOST: */ + /* case SCARD_E_NO_KEY_CONTAINER: */ + /* case SCARD_E_SERVER_TOO_BUSY: */ + case ErrSCardUnsupportedCard: + return fmt.Errorf("Card is not supported") + + case ErrSCardUnresponsiveCard: + return fmt.Errorf("Card is unresponsive") + + case ErrSCardUnpoweredCard: + return fmt.Errorf("Card is unpowered") + + case ErrSCardResetCard: + return fmt.Errorf("Card was reset") + + case ErrSCardRemovedCard: + return fmt.Errorf("Card was removed") + + /* case SCARD_W_SECURITY_VIOLATION: */ + /* case SCARD_W_WRONG_CHV: */ + /* case SCARD_W_CHV_BLOCKED: */ + /* case SCARD_W_EOF: */ + /* case SCARD_W_CANCELLED_BY_USER: */ + /* case SCARD_W_CARD_NOT_AUTHENTICATED: */ + + case ErrSCardUnsupportedFeature: + return fmt.Errorf("Feature not supported") + + default: + return fmt.Errorf("unknown error: %08x", code) + } +} diff --git a/vendor/github.com/gballet/go-libpcsclite/go.mod b/vendor/github.com/gballet/go-libpcsclite/go.mod new file mode 100644 index 00000000..e97f46b7 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/go.mod @@ -0,0 +1 @@ +module github.com/gballet/go-libpcsclite diff --git a/vendor/github.com/gballet/go-libpcsclite/msg.go b/vendor/github.com/gballet/go-libpcsclite/msg.go new file mode 100644 index 00000000..1377082b --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/msg.go @@ -0,0 +1,82 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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 pcsc + +import ( + "encoding/binary" + "net" +) + +/** + * @brief Wrapper for the MessageSend() function. + * + * Called by clients to send messages to the server. + * The parameters \p command and \p data are set in the \c sharedSegmentMsg + * struct in order to be sent. + * + * @param[in] command Command to be sent. + * @param[in] dwClientID Client socket handle. + * @param[in] size Size of the message (\p data). + * @param[in] data_void Data to be sent. + * + * @return Same error codes as MessageSend(). + */ +func messageSendWithHeader(command uint32, conn net.Conn, data []byte) error { + /* Translate header into bytes */ + msgData := make([]byte, 8+len(data)) + binary.LittleEndian.PutUint32(msgData[4:], command) + binary.LittleEndian.PutUint32(msgData, uint32(len(data))) + + /* Copy payload */ + copy(msgData[8:], data) + + _, err := conn.Write(msgData) + return err +} + +// clientSetupSession prepares a communication channel for the client to talk to the server. +// This is called by the application to create a socket for local IPC with the +// server. The socket is associated to the file \c PCSCLITE_CSOCK_NAME. +/* + * @param[out] pdwClientID Client Connection ID. + * + * @retval 0 Success. + * @retval -1 Can not create the socket. + * @retval -1 The socket can not open a connection. + * @retval -1 Can not set the socket to non-blocking. + */ +func clientSetupSession(daemonPath string) (net.Conn, error) { + path := PCSCDSockName + if len(daemonPath) > 0 { + path = daemonPath + } + return net.Dial("unix", path) +} diff --git a/vendor/github.com/gballet/go-libpcsclite/winscard.go b/vendor/github.com/gballet/go-libpcsclite/winscard.go new file mode 100644 index 00000000..b916db16 --- /dev/null +++ b/vendor/github.com/gballet/go-libpcsclite/winscard.go @@ -0,0 +1,402 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, Guillaume Ballet +// All rights reserved. +// +// 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 the copyright holder 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 HOLDER 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 pcsc + +import ( + "encoding/binary" + "fmt" + "net" + "sync" + "unsafe" +) + +// Client contains all the information needed to establish +// and maintain a connection to the deamon/card. +type Client struct { + conn net.Conn + + minor uint32 + major uint32 + + ctx uint32 + + mutex sync.Mutex + + readerStateDescriptors [MaxReaderStateDescriptors]ReaderState +} + +// EstablishContext asks the PCSC daemon to create a context +// handle for further communication with connected cards and +// readers. +func EstablishContext(path string, scope uint32) (*Client, error) { + client := &Client{} + + conn, err := clientSetupSession(path) + if err != nil { + return nil, err + } + client.conn = conn + + payload := make([]byte, 12) + response := make([]byte, 12) + + var code uint32 + var minor uint32 + for minor = ProtocolVersionMinor; minor <= ProtocolVersionMinor+1; minor++ { + /* Exchange version information */ + binary.LittleEndian.PutUint32(payload, ProtocolVersionMajor) + binary.LittleEndian.PutUint32(payload[4:], minor) + binary.LittleEndian.PutUint32(payload[8:], SCardSuccess.Code()) + err = messageSendWithHeader(CommandVersion, conn, payload) + if err != nil { + return nil, err + } + n, err := conn.Read(response) + if err != nil { + return nil, err + } + if n != len(response) { + return nil, fmt.Errorf("invalid response length: expected %d, got %d", len(response), n) + } + code = binary.LittleEndian.Uint32(response[8:]) + if code != SCardSuccess.Code() { + continue + } + client.major = binary.LittleEndian.Uint32(response) + client.minor = binary.LittleEndian.Uint32(response[4:]) + if client.major != ProtocolVersionMajor || client.minor != minor { + continue + } + break + } + + if code != SCardSuccess.Code() { + return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error()) + } + if client.major != ProtocolVersionMajor || (client.minor != minor && client.minor+1 != minor) { + return nil, fmt.Errorf("invalid version found: expected %d.%d, got %d.%d", ProtocolVersionMajor, ProtocolVersionMinor, client.major, client.minor) + } + + /* Establish the context proper */ + binary.LittleEndian.PutUint32(payload, scope) + binary.LittleEndian.PutUint32(payload[4:], 0) + binary.LittleEndian.PutUint32(payload[8:], SCardSuccess.Code()) + err = messageSendWithHeader(SCardEstablishContext, conn, payload) + if err != nil { + return nil, err + } + response = make([]byte, 12) + n, err := conn.Read(response) + if err != nil { + return nil, err + } + if n != len(response) { + return nil, fmt.Errorf("invalid response length: expected %d, got %d", len(response), n) + } + code = binary.LittleEndian.Uint32(response[8:]) + if code != SCardSuccess.Code() { + return nil, fmt.Errorf("invalid response code: expected %d, got %d (%v)", SCardSuccess, code, ErrorCode(code).Error()) + } + client.ctx = binary.LittleEndian.Uint32(response[4:]) + + return client, nil +} + +// ReleaseContext tells the daemon that the client will no longer +// need the context. +func (client *Client) ReleaseContext() error { + client.mutex.Lock() + defer client.mutex.Unlock() + + data := [8]byte{} + binary.LittleEndian.PutUint32(data[:], client.ctx) + binary.LittleEndian.PutUint32(data[4:], SCardSuccess.Code()) + err := messageSendWithHeader(SCardReleaseContext, client.conn, data[:]) + if err != nil { + return err + } + total := 0 + for total < len(data) { + n, err := client.conn.Read(data[total:]) + if err != nil { + return err + } + total += n + } + code := binary.LittleEndian.Uint32(data[4:]) + if code != SCardSuccess.Code() { + return fmt.Errorf("invalid return code: %x, %v", code, ErrorCode(code).Error()) + } + + return nil +} + +// Constants related to the reader state structure +const ( + ReaderStateNameLength = 128 + ReaderStateMaxAtrSizeLength = 33 + // NOTE: ATR is 32-byte aligned in the C version, which means it's + // actually 36 byte long and not 33. + ReaderStateDescriptorLength = ReaderStateNameLength + ReaderStateMaxAtrSizeLength + 5*4 + 3 + + MaxReaderStateDescriptors = 16 +) + +// ReaderState represent the state of a single reader, as reported +// by the PCSC daemon. +type ReaderState struct { + Name string /* reader name */ + eventCounter uint32 /* number of card events */ + readerState uint32 /* SCARD_* bit field */ + readerSharing uint32 /* PCSCLITE_SHARING_* sharing status */ + + cardAtr [ReaderStateMaxAtrSizeLength]byte /* ATR */ + cardAtrLength uint32 /* ATR length */ + cardProtocol uint32 /* SCARD_PROTOCOL_* value */ +} + +func getReaderState(data []byte) (ReaderState, error) { + ret := ReaderState{} + if len(data) < ReaderStateDescriptorLength { + return ret, fmt.Errorf("could not unmarshall data of length %d < %d", len(data), ReaderStateDescriptorLength) + } + + ret.Name = string(data[:ReaderStateNameLength]) + ret.eventCounter = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.eventCounter):]) + ret.readerState = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.readerState):]) + ret.readerSharing = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.readerSharing):]) + copy(ret.cardAtr[:], data[unsafe.Offsetof(ret.cardAtr):unsafe.Offsetof(ret.cardAtr)+ReaderStateMaxAtrSizeLength]) + ret.cardAtrLength = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.cardAtrLength):]) + ret.cardProtocol = binary.LittleEndian.Uint32(data[unsafe.Offsetof(ret.cardProtocol):]) + + return ret, nil +} + +// ListReaders gets the list of readers from the daemon +func (client *Client) ListReaders() ([]string, error) { + client.mutex.Lock() + defer client.mutex.Unlock() + + err := messageSendWithHeader(CommandGetReaderState, client.conn, []byte{}) + if err != nil { + return nil, err + } + response := make([]byte, ReaderStateDescriptorLength*MaxReaderStateDescriptors) + total := 0 + for total < len(response) { + n, err := client.conn.Read(response[total:]) + if err != nil { + return nil, err + } + total += n + } + + var names []string + for i := range client.readerStateDescriptors { + desc, err := getReaderState(response[i*ReaderStateDescriptorLength:]) + if err != nil { + return nil, err + } + client.readerStateDescriptors[i] = desc + if desc.Name[0] == 0 { + break + } + names = append(names, desc.Name) + } + + return names, nil +} + +// Offsets into the Connect request/response packet +const ( + SCardConnectReaderNameOffset = 4 + SCardConnectShareModeOffset = SCardConnectReaderNameOffset + ReaderStateNameLength + SCardConnectPreferredProtocolOffset = SCardConnectShareModeOffset + 4 + SCardConnectReturnValueOffset = SCardConnectPreferredProtocolOffset + 12 +) + +// Card represents the connection to a card +type Card struct { + handle uint32 + activeProto uint32 + client *Client +} + +// Connect asks the daemon to connect to the card +func (client *Client) Connect(name string, shareMode uint32, preferredProtocol uint32) (*Card, error) { + client.mutex.Lock() + defer client.mutex.Unlock() + + request := make([]byte, ReaderStateNameLength+4*6) + binary.LittleEndian.PutUint32(request, client.ctx) + copy(request[SCardConnectReaderNameOffset:], []byte(name)) + binary.LittleEndian.PutUint32(request[SCardConnectShareModeOffset:], shareMode) + binary.LittleEndian.PutUint32(request[SCardConnectPreferredProtocolOffset:], preferredProtocol) + binary.LittleEndian.PutUint32(request[SCardConnectReturnValueOffset:], SCardSuccess.Code()) + + err := messageSendWithHeader(SCardConnect, client.conn, request) + if err != nil { + return nil, err + } + response := make([]byte, ReaderStateNameLength+4*6) + total := 0 + for total < len(response) { + n, err := client.conn.Read(response[total:]) + if err != nil { + return nil, err + } + // fmt.Println("total, n", total, n, response) + total += n + } + code := binary.LittleEndian.Uint32(response[148:]) + if code != SCardSuccess.Code() { + return nil, fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error()) + } + handle := binary.LittleEndian.Uint32(response[140:]) + active := binary.LittleEndian.Uint32(response[SCardConnectPreferredProtocolOffset:]) + + return &Card{handle: handle, activeProto: active, client: client}, nil +} + +/** +* @brief contained in \ref SCARD_TRANSMIT Messages. +* +* These data are passed throw the field \c sharedSegmentMsg.data. + */ +type transmit struct { + hCard uint32 + ioSendPciProtocol uint32 + ioSendPciLength uint32 + cbSendLength uint32 + ioRecvPciProtocol uint32 + ioRecvPciLength uint32 + pcbRecvLength uint32 + rv uint32 +} + +// SCardIoRequest contains the info needed for performing an IO request +type SCardIoRequest struct { + proto uint32 + length uint32 +} + +const ( + TransmitRequestLength = 32 +) + +// Transmit sends request data to a card and returns the response +func (card *Card) Transmit(adpu []byte) ([]byte, *SCardIoRequest, error) { + card.client.mutex.Lock() + defer card.client.mutex.Unlock() + + request := [TransmitRequestLength]byte{} + binary.LittleEndian.PutUint32(request[:], card.handle) + binary.LittleEndian.PutUint32(request[4:] /*card.activeProto*/, 2) + binary.LittleEndian.PutUint32(request[8:], 8) + binary.LittleEndian.PutUint32(request[12:], uint32(len(adpu))) + binary.LittleEndian.PutUint32(request[16:], 0) + binary.LittleEndian.PutUint32(request[20:], 0) + binary.LittleEndian.PutUint32(request[24:], 0x10000) + binary.LittleEndian.PutUint32(request[28:], SCardSuccess.Code()) + err := messageSendWithHeader(SCardTransmit, card.client.conn, request[:]) + if err != nil { + return nil, nil, err + } + // Add the ADPU payload after the transmit descriptor + n, err := card.client.conn.Write(adpu) + if err != nil { + return nil, nil, err + } + if n != len(adpu) { + return nil, nil, fmt.Errorf("Invalid number of bytes written: expected %d, got %d", len(adpu), n) + } + response := [TransmitRequestLength]byte{} + total := 0 + for total < len(response) { + n, err = card.client.conn.Read(response[total:]) + if err != nil { + return nil, nil, err + } + total += n + } + + code := binary.LittleEndian.Uint32(response[28:]) + if code != SCardSuccess.Code() { + return nil, nil, fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error()) + } + + // Recover the response data + recvProto := binary.LittleEndian.Uint32(response[16:]) + recvLength := binary.LittleEndian.Uint32(response[20:]) + recv := &SCardIoRequest{proto: recvProto, length: recvLength} + recvLength = binary.LittleEndian.Uint32(response[24:]) + recvData := make([]byte, recvLength) + total = 0 + for uint32(total) < recvLength { + n, err := card.client.conn.Read(recvData[total:]) + if err != nil { + return nil, nil, err + } + total += n + } + + return recvData, recv, nil +} + +// Disconnect tells the PCSC daemon that the client is no longer +// interested in communicating with the card. +func (card *Card) Disconnect(disposition uint32) error { + card.client.mutex.Lock() + defer card.client.mutex.Unlock() + + data := [12]byte{} + binary.LittleEndian.PutUint32(data[:], card.handle) + binary.LittleEndian.PutUint32(data[4:], disposition) + binary.LittleEndian.PutUint32(data[8:], SCardSuccess.Code()) + err := messageSendWithHeader(SCardDisConnect, card.client.conn, data[:]) + if err != nil { + return err + } + total := 0 + for total < len(data) { + n, err := card.client.conn.Read(data[total:]) + if err != nil { + return err + } + total += n + } + code := binary.LittleEndian.Uint32(data[8:]) + if code != SCardSuccess.Code() { + return fmt.Errorf("invalid return code: %x (%v)", code, ErrorCode(code).Error()) + } + + return nil +} diff --git a/vendor/github.com/gogo/protobuf/AUTHORS b/vendor/github.com/gogo/protobuf/AUTHORS new file mode 100644 index 00000000..3d97fc7a --- /dev/null +++ b/vendor/github.com/gogo/protobuf/AUTHORS @@ -0,0 +1,15 @@ +# This is the official list of GoGo authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS file, which +# lists people. For example, employees are listed in CONTRIBUTORS, +# but not in AUTHORS, because the employer holds the copyright. + +# Names should be added to this file as one of +# Organization's name +# Individual's name +# Individual's name + +# Please keep the list sorted. + +Sendgrid, Inc +Vastech SA (PTY) LTD +Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/CONTRIBUTORS b/vendor/github.com/gogo/protobuf/CONTRIBUTORS new file mode 100644 index 00000000..1b4f6c20 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/CONTRIBUTORS @@ -0,0 +1,23 @@ +Anton Povarov +Brian Goff +Clayton Coleman +Denis Smirnov +DongYun Kang +Dwayne Schultz +Georg Apitz +Gustav Paul +Johan Brandhorst +John Shahid +John Tuley +Laurent +Patrick Lee +Peter Edge +Roger Johansson +Sam Nguyen +Sergio Arbeo +Stephen J Day +Tamir Duberstein +Todd Eisenberger +Tormod Erevik Lea +Vyacheslav Kim +Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS b/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS new file mode 100644 index 00000000..b368efb7 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS @@ -0,0 +1,5 @@ +The contributors to the Go protobuf repository: + +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. \ No newline at end of file diff --git a/vendor/github.com/gogo/protobuf/LICENSE b/vendor/github.com/gogo/protobuf/LICENSE new file mode 100644 index 00000000..f57de90d --- /dev/null +++ b/vendor/github.com/gogo/protobuf/LICENSE @@ -0,0 +1,35 @@ +Copyright (c) 2013, The GoGo Authors. All rights reserved. + +Protocol Buffers for Go with Gadgets + +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 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. + diff --git a/vendor/github.com/gogo/protobuf/gogoproto/Makefile b/vendor/github.com/gogo/protobuf/gogoproto/Makefile new file mode 100644 index 00000000..0b4659b7 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/Makefile @@ -0,0 +1,37 @@ +# Protocol Buffers for Go with Gadgets +# +# Copyright (c) 2013, The GoGo Authors. All rights reserved. +# http://github.com/gogo/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. +# +# 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. + +regenerate: + go install github.com/gogo/protobuf/protoc-gen-gogo + protoc --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:../../../../ --proto_path=../../../../:../protobuf/:. *.proto + +restore: + cp gogo.pb.golden gogo.pb.go + +preserve: + cp gogo.pb.go gogo.pb.golden diff --git a/vendor/github.com/gogo/protobuf/gogoproto/doc.go b/vendor/github.com/gogo/protobuf/gogoproto/doc.go new file mode 100644 index 00000000..081c86fa --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/doc.go @@ -0,0 +1,169 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 gogoproto provides extensions for protocol buffers to achieve: + + - fast marshalling and unmarshalling. + - peace of mind by optionally generating test and benchmark code. + - more canonical Go structures. + - less typing by optionally generating extra helper code. + - goprotobuf compatibility + +More Canonical Go Structures + +A lot of time working with a goprotobuf struct will lead you to a place where you create another struct that is easier to work with and then have a function to copy the values between the two structs. +You might also find that basic structs that started their life as part of an API need to be sent over the wire. With gob, you could just send it. With goprotobuf, you need to make a parallel struct. +Gogoprotobuf tries to fix these problems with the nullable, embed, customtype and customname field extensions. + + - nullable, if false, a field is generated without a pointer (see warning below). + - embed, if true, the field is generated as an embedded field. + - customtype, It works with the Marshal and Unmarshal methods, to allow you to have your own types in your struct, but marshal to bytes. For example, custom.Uuid or custom.Fixed128 + - customname (beta), Changes the generated fieldname. This is especially useful when generated methods conflict with fieldnames. + - casttype (beta), Changes the generated fieldtype. All generated code assumes that this type is castable to the protocol buffer field type. It does not work for structs or enums. + - castkey (beta), Changes the generated fieldtype for a map key. All generated code assumes that this type is castable to the protocol buffer field type. Only supported on maps. + - castvalue (beta), Changes the generated fieldtype for a map value. All generated code assumes that this type is castable to the protocol buffer field type. Only supported on maps. + +Warning about nullable: According to the Protocol Buffer specification, you should be able to tell whether a field is set or unset. With the option nullable=false this feature is lost, since your non-nullable fields will always be set. It can be seen as a layer on top of Protocol Buffers, where before and after marshalling all non-nullable fields are set and they cannot be unset. + +Let us look at: + + github.com/gogo/protobuf/test/example/example.proto + +for a quicker overview. + +The following message: + + package test; + + import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + + message A { + optional string Description = 1 [(gogoproto.nullable) = false]; + optional int64 Number = 2 [(gogoproto.nullable) = false]; + optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false]; + } + +Will generate a go struct which looks a lot like this: + + type A struct { + Description string + Number int64 + Id github_com_gogo_protobuf_test_custom.Uuid + } + +You will see there are no pointers, since all fields are non-nullable. +You will also see a custom type which marshals to a string. +Be warned it is your responsibility to test your custom types thoroughly. +You should think of every possible empty and nil case for your marshaling, unmarshaling and size methods. + +Next we will embed the message A in message B. + + message B { + optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true]; + repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false]; + } + +See below that A is embedded in B. + + type B struct { + A + G []github_com_gogo_protobuf_test_custom.Uint128 + } + +Also see the repeated custom type. + + type Uint128 [2]uint64 + +Next we will create a custom name for one of our fields. + + message C { + optional int64 size = 1 [(gogoproto.customname) = "MySize"]; + } + +See below that the field's name is MySize and not Size. + + type C struct { + MySize *int64 + } + +The is useful when having a protocol buffer message with a field name which conflicts with a generated method. +As an example, having a field name size and using the sizer plugin to generate a Size method will cause a go compiler error. +Using customname you can fix this error without changing the field name. +This is typically useful when working with a protocol buffer that was designed before these methods and/or the go language were avialable. + +Gogoprotobuf also has some more subtle changes, these could be changed back: + + - the generated package name for imports do not have the extra /filename.pb, + but are actually the imports specified in the .proto file. + +Gogoprotobuf also has lost some features which should be brought back with time: + + - Marshalling and unmarshalling with reflect and without the unsafe package, + this requires work in pointer_reflect.go + +Why does nullable break protocol buffer specifications: + +The protocol buffer specification states, somewhere, that you should be able to tell whether a +field is set or unset. With the option nullable=false this feature is lost, +since your non-nullable fields will always be set. It can be seen as a layer on top of +protocol buffers, where before and after marshalling all non-nullable fields are set +and they cannot be unset. + +Goprotobuf Compatibility: + +Gogoprotobuf is compatible with Goprotobuf, because it is compatible with protocol buffers. +Gogoprotobuf generates the same code as goprotobuf if no extensions are used. +The enumprefix, getters and stringer extensions can be used to remove some of the unnecessary code generated by goprotobuf: + + - gogoproto_import, if false, the generated code imports github.com/golang/protobuf/proto instead of github.com/gogo/protobuf/proto. + - goproto_enum_prefix, if false, generates the enum constant names without the messagetype prefix + - goproto_enum_stringer (experimental), if false, the enum is generated without the default string method, this is useful for rather using enum_stringer, or allowing you to write your own string method. + - goproto_getters, if false, the message is generated without get methods, this is useful when you would rather want to use face + - goproto_stringer, if false, the message is generated without the default string method, this is useful for rather using stringer, or allowing you to write your own string method. + - goproto_extensions_map (beta), if false, the extensions field is generated as type []byte instead of type map[int32]proto.Extension + - goproto_unrecognized (beta), if false, XXX_unrecognized field is not generated. This is useful in conjunction with gogoproto.nullable=false, to generate structures completely devoid of pointers and reduce GC pressure at the cost of losing information about unrecognized fields. + - goproto_registration (beta), if true, the generated files will register all messages and types against both gogo/protobuf and golang/protobuf. This is necessary when using third-party packages which read registrations from golang/protobuf (such as the grpc-gateway). + +Less Typing and Peace of Mind is explained in their specific plugin folders godoc: + + - github.com/gogo/protobuf/plugin/ + +If you do not use any of these extension the code that is generated +will be the same as if goprotobuf has generated it. + +The most complete way to see examples is to look at + + github.com/gogo/protobuf/test/thetest.proto + +Gogoprototest is a seperate project, +because we want to keep gogoprotobuf independent of goprotobuf, +but we still want to test it thoroughly. + +*/ +package gogoproto diff --git a/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go new file mode 100644 index 00000000..e352808b --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go @@ -0,0 +1,874 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: gogo.proto + +package gogoproto + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +var E_GoprotoEnumPrefix = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62001, + Name: "gogoproto.goproto_enum_prefix", + Tag: "varint,62001,opt,name=goproto_enum_prefix", + Filename: "gogo.proto", +} + +var E_GoprotoEnumStringer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62021, + Name: "gogoproto.goproto_enum_stringer", + Tag: "varint,62021,opt,name=goproto_enum_stringer", + Filename: "gogo.proto", +} + +var E_EnumStringer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62022, + Name: "gogoproto.enum_stringer", + Tag: "varint,62022,opt,name=enum_stringer", + Filename: "gogo.proto", +} + +var E_EnumCustomname = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumOptions)(nil), + ExtensionType: (*string)(nil), + Field: 62023, + Name: "gogoproto.enum_customname", + Tag: "bytes,62023,opt,name=enum_customname", + Filename: "gogo.proto", +} + +var E_Enumdecl = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62024, + Name: "gogoproto.enumdecl", + Tag: "varint,62024,opt,name=enumdecl", + Filename: "gogo.proto", +} + +var E_EnumvalueCustomname = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*string)(nil), + Field: 66001, + Name: "gogoproto.enumvalue_customname", + Tag: "bytes,66001,opt,name=enumvalue_customname", + Filename: "gogo.proto", +} + +var E_GoprotoGettersAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63001, + Name: "gogoproto.goproto_getters_all", + Tag: "varint,63001,opt,name=goproto_getters_all", + Filename: "gogo.proto", +} + +var E_GoprotoEnumPrefixAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63002, + Name: "gogoproto.goproto_enum_prefix_all", + Tag: "varint,63002,opt,name=goproto_enum_prefix_all", + Filename: "gogo.proto", +} + +var E_GoprotoStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63003, + Name: "gogoproto.goproto_stringer_all", + Tag: "varint,63003,opt,name=goproto_stringer_all", + Filename: "gogo.proto", +} + +var E_VerboseEqualAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63004, + Name: "gogoproto.verbose_equal_all", + Tag: "varint,63004,opt,name=verbose_equal_all", + Filename: "gogo.proto", +} + +var E_FaceAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63005, + Name: "gogoproto.face_all", + Tag: "varint,63005,opt,name=face_all", + Filename: "gogo.proto", +} + +var E_GostringAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63006, + Name: "gogoproto.gostring_all", + Tag: "varint,63006,opt,name=gostring_all", + Filename: "gogo.proto", +} + +var E_PopulateAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63007, + Name: "gogoproto.populate_all", + Tag: "varint,63007,opt,name=populate_all", + Filename: "gogo.proto", +} + +var E_StringerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63008, + Name: "gogoproto.stringer_all", + Tag: "varint,63008,opt,name=stringer_all", + Filename: "gogo.proto", +} + +var E_OnlyoneAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63009, + Name: "gogoproto.onlyone_all", + Tag: "varint,63009,opt,name=onlyone_all", + Filename: "gogo.proto", +} + +var E_EqualAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63013, + Name: "gogoproto.equal_all", + Tag: "varint,63013,opt,name=equal_all", + Filename: "gogo.proto", +} + +var E_DescriptionAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63014, + Name: "gogoproto.description_all", + Tag: "varint,63014,opt,name=description_all", + Filename: "gogo.proto", +} + +var E_TestgenAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63015, + Name: "gogoproto.testgen_all", + Tag: "varint,63015,opt,name=testgen_all", + Filename: "gogo.proto", +} + +var E_BenchgenAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63016, + Name: "gogoproto.benchgen_all", + Tag: "varint,63016,opt,name=benchgen_all", + Filename: "gogo.proto", +} + +var E_MarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63017, + Name: "gogoproto.marshaler_all", + Tag: "varint,63017,opt,name=marshaler_all", + Filename: "gogo.proto", +} + +var E_UnmarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63018, + Name: "gogoproto.unmarshaler_all", + Tag: "varint,63018,opt,name=unmarshaler_all", + Filename: "gogo.proto", +} + +var E_StableMarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63019, + Name: "gogoproto.stable_marshaler_all", + Tag: "varint,63019,opt,name=stable_marshaler_all", + Filename: "gogo.proto", +} + +var E_SizerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63020, + Name: "gogoproto.sizer_all", + Tag: "varint,63020,opt,name=sizer_all", + Filename: "gogo.proto", +} + +var E_GoprotoEnumStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63021, + Name: "gogoproto.goproto_enum_stringer_all", + Tag: "varint,63021,opt,name=goproto_enum_stringer_all", + Filename: "gogo.proto", +} + +var E_EnumStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63022, + Name: "gogoproto.enum_stringer_all", + Tag: "varint,63022,opt,name=enum_stringer_all", + Filename: "gogo.proto", +} + +var E_UnsafeMarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63023, + Name: "gogoproto.unsafe_marshaler_all", + Tag: "varint,63023,opt,name=unsafe_marshaler_all", + Filename: "gogo.proto", +} + +var E_UnsafeUnmarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63024, + Name: "gogoproto.unsafe_unmarshaler_all", + Tag: "varint,63024,opt,name=unsafe_unmarshaler_all", + Filename: "gogo.proto", +} + +var E_GoprotoExtensionsMapAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63025, + Name: "gogoproto.goproto_extensions_map_all", + Tag: "varint,63025,opt,name=goproto_extensions_map_all", + Filename: "gogo.proto", +} + +var E_GoprotoUnrecognizedAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63026, + Name: "gogoproto.goproto_unrecognized_all", + Tag: "varint,63026,opt,name=goproto_unrecognized_all", + Filename: "gogo.proto", +} + +var E_GogoprotoImport = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63027, + Name: "gogoproto.gogoproto_import", + Tag: "varint,63027,opt,name=gogoproto_import", + Filename: "gogo.proto", +} + +var E_ProtosizerAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63028, + Name: "gogoproto.protosizer_all", + Tag: "varint,63028,opt,name=protosizer_all", + Filename: "gogo.proto", +} + +var E_CompareAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63029, + Name: "gogoproto.compare_all", + Tag: "varint,63029,opt,name=compare_all", + Filename: "gogo.proto", +} + +var E_TypedeclAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63030, + Name: "gogoproto.typedecl_all", + Tag: "varint,63030,opt,name=typedecl_all", + Filename: "gogo.proto", +} + +var E_EnumdeclAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63031, + Name: "gogoproto.enumdecl_all", + Tag: "varint,63031,opt,name=enumdecl_all", + Filename: "gogo.proto", +} + +var E_GoprotoRegistration = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63032, + Name: "gogoproto.goproto_registration", + Tag: "varint,63032,opt,name=goproto_registration", + Filename: "gogo.proto", +} + +var E_MessagenameAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63033, + Name: "gogoproto.messagename_all", + Tag: "varint,63033,opt,name=messagename_all", + Filename: "gogo.proto", +} + +var E_GoprotoSizecacheAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63034, + Name: "gogoproto.goproto_sizecache_all", + Tag: "varint,63034,opt,name=goproto_sizecache_all", + Filename: "gogo.proto", +} + +var E_GoprotoUnkeyedAll = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63035, + Name: "gogoproto.goproto_unkeyed_all", + Tag: "varint,63035,opt,name=goproto_unkeyed_all", + Filename: "gogo.proto", +} + +var E_GoprotoGetters = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64001, + Name: "gogoproto.goproto_getters", + Tag: "varint,64001,opt,name=goproto_getters", + Filename: "gogo.proto", +} + +var E_GoprotoStringer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64003, + Name: "gogoproto.goproto_stringer", + Tag: "varint,64003,opt,name=goproto_stringer", + Filename: "gogo.proto", +} + +var E_VerboseEqual = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64004, + Name: "gogoproto.verbose_equal", + Tag: "varint,64004,opt,name=verbose_equal", + Filename: "gogo.proto", +} + +var E_Face = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64005, + Name: "gogoproto.face", + Tag: "varint,64005,opt,name=face", + Filename: "gogo.proto", +} + +var E_Gostring = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64006, + Name: "gogoproto.gostring", + Tag: "varint,64006,opt,name=gostring", + Filename: "gogo.proto", +} + +var E_Populate = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64007, + Name: "gogoproto.populate", + Tag: "varint,64007,opt,name=populate", + Filename: "gogo.proto", +} + +var E_Stringer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 67008, + Name: "gogoproto.stringer", + Tag: "varint,67008,opt,name=stringer", + Filename: "gogo.proto", +} + +var E_Onlyone = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64009, + Name: "gogoproto.onlyone", + Tag: "varint,64009,opt,name=onlyone", + Filename: "gogo.proto", +} + +var E_Equal = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64013, + Name: "gogoproto.equal", + Tag: "varint,64013,opt,name=equal", + Filename: "gogo.proto", +} + +var E_Description = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64014, + Name: "gogoproto.description", + Tag: "varint,64014,opt,name=description", + Filename: "gogo.proto", +} + +var E_Testgen = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64015, + Name: "gogoproto.testgen", + Tag: "varint,64015,opt,name=testgen", + Filename: "gogo.proto", +} + +var E_Benchgen = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64016, + Name: "gogoproto.benchgen", + Tag: "varint,64016,opt,name=benchgen", + Filename: "gogo.proto", +} + +var E_Marshaler = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64017, + Name: "gogoproto.marshaler", + Tag: "varint,64017,opt,name=marshaler", + Filename: "gogo.proto", +} + +var E_Unmarshaler = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64018, + Name: "gogoproto.unmarshaler", + Tag: "varint,64018,opt,name=unmarshaler", + Filename: "gogo.proto", +} + +var E_StableMarshaler = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64019, + Name: "gogoproto.stable_marshaler", + Tag: "varint,64019,opt,name=stable_marshaler", + Filename: "gogo.proto", +} + +var E_Sizer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64020, + Name: "gogoproto.sizer", + Tag: "varint,64020,opt,name=sizer", + Filename: "gogo.proto", +} + +var E_UnsafeMarshaler = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64023, + Name: "gogoproto.unsafe_marshaler", + Tag: "varint,64023,opt,name=unsafe_marshaler", + Filename: "gogo.proto", +} + +var E_UnsafeUnmarshaler = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64024, + Name: "gogoproto.unsafe_unmarshaler", + Tag: "varint,64024,opt,name=unsafe_unmarshaler", + Filename: "gogo.proto", +} + +var E_GoprotoExtensionsMap = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64025, + Name: "gogoproto.goproto_extensions_map", + Tag: "varint,64025,opt,name=goproto_extensions_map", + Filename: "gogo.proto", +} + +var E_GoprotoUnrecognized = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64026, + Name: "gogoproto.goproto_unrecognized", + Tag: "varint,64026,opt,name=goproto_unrecognized", + Filename: "gogo.proto", +} + +var E_Protosizer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64028, + Name: "gogoproto.protosizer", + Tag: "varint,64028,opt,name=protosizer", + Filename: "gogo.proto", +} + +var E_Compare = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64029, + Name: "gogoproto.compare", + Tag: "varint,64029,opt,name=compare", + Filename: "gogo.proto", +} + +var E_Typedecl = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64030, + Name: "gogoproto.typedecl", + Tag: "varint,64030,opt,name=typedecl", + Filename: "gogo.proto", +} + +var E_Messagename = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64033, + Name: "gogoproto.messagename", + Tag: "varint,64033,opt,name=messagename", + Filename: "gogo.proto", +} + +var E_GoprotoSizecache = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64034, + Name: "gogoproto.goproto_sizecache", + Tag: "varint,64034,opt,name=goproto_sizecache", + Filename: "gogo.proto", +} + +var E_GoprotoUnkeyed = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64035, + Name: "gogoproto.goproto_unkeyed", + Tag: "varint,64035,opt,name=goproto_unkeyed", + Filename: "gogo.proto", +} + +var E_Nullable = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65001, + Name: "gogoproto.nullable", + Tag: "varint,65001,opt,name=nullable", + Filename: "gogo.proto", +} + +var E_Embed = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65002, + Name: "gogoproto.embed", + Tag: "varint,65002,opt,name=embed", + Filename: "gogo.proto", +} + +var E_Customtype = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65003, + Name: "gogoproto.customtype", + Tag: "bytes,65003,opt,name=customtype", + Filename: "gogo.proto", +} + +var E_Customname = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65004, + Name: "gogoproto.customname", + Tag: "bytes,65004,opt,name=customname", + Filename: "gogo.proto", +} + +var E_Jsontag = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65005, + Name: "gogoproto.jsontag", + Tag: "bytes,65005,opt,name=jsontag", + Filename: "gogo.proto", +} + +var E_Moretags = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65006, + Name: "gogoproto.moretags", + Tag: "bytes,65006,opt,name=moretags", + Filename: "gogo.proto", +} + +var E_Casttype = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65007, + Name: "gogoproto.casttype", + Tag: "bytes,65007,opt,name=casttype", + Filename: "gogo.proto", +} + +var E_Castkey = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65008, + Name: "gogoproto.castkey", + Tag: "bytes,65008,opt,name=castkey", + Filename: "gogo.proto", +} + +var E_Castvalue = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65009, + Name: "gogoproto.castvalue", + Tag: "bytes,65009,opt,name=castvalue", + Filename: "gogo.proto", +} + +var E_Stdtime = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65010, + Name: "gogoproto.stdtime", + Tag: "varint,65010,opt,name=stdtime", + Filename: "gogo.proto", +} + +var E_Stdduration = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65011, + Name: "gogoproto.stdduration", + Tag: "varint,65011,opt,name=stdduration", + Filename: "gogo.proto", +} + +var E_Wktpointer = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65012, + Name: "gogoproto.wktpointer", + Tag: "varint,65012,opt,name=wktpointer", + Filename: "gogo.proto", +} + +func init() { + proto.RegisterExtension(E_GoprotoEnumPrefix) + proto.RegisterExtension(E_GoprotoEnumStringer) + proto.RegisterExtension(E_EnumStringer) + proto.RegisterExtension(E_EnumCustomname) + proto.RegisterExtension(E_Enumdecl) + proto.RegisterExtension(E_EnumvalueCustomname) + proto.RegisterExtension(E_GoprotoGettersAll) + proto.RegisterExtension(E_GoprotoEnumPrefixAll) + proto.RegisterExtension(E_GoprotoStringerAll) + proto.RegisterExtension(E_VerboseEqualAll) + proto.RegisterExtension(E_FaceAll) + proto.RegisterExtension(E_GostringAll) + proto.RegisterExtension(E_PopulateAll) + proto.RegisterExtension(E_StringerAll) + proto.RegisterExtension(E_OnlyoneAll) + proto.RegisterExtension(E_EqualAll) + proto.RegisterExtension(E_DescriptionAll) + proto.RegisterExtension(E_TestgenAll) + proto.RegisterExtension(E_BenchgenAll) + proto.RegisterExtension(E_MarshalerAll) + proto.RegisterExtension(E_UnmarshalerAll) + proto.RegisterExtension(E_StableMarshalerAll) + proto.RegisterExtension(E_SizerAll) + proto.RegisterExtension(E_GoprotoEnumStringerAll) + proto.RegisterExtension(E_EnumStringerAll) + proto.RegisterExtension(E_UnsafeMarshalerAll) + proto.RegisterExtension(E_UnsafeUnmarshalerAll) + proto.RegisterExtension(E_GoprotoExtensionsMapAll) + proto.RegisterExtension(E_GoprotoUnrecognizedAll) + proto.RegisterExtension(E_GogoprotoImport) + proto.RegisterExtension(E_ProtosizerAll) + proto.RegisterExtension(E_CompareAll) + proto.RegisterExtension(E_TypedeclAll) + proto.RegisterExtension(E_EnumdeclAll) + proto.RegisterExtension(E_GoprotoRegistration) + proto.RegisterExtension(E_MessagenameAll) + proto.RegisterExtension(E_GoprotoSizecacheAll) + proto.RegisterExtension(E_GoprotoUnkeyedAll) + proto.RegisterExtension(E_GoprotoGetters) + proto.RegisterExtension(E_GoprotoStringer) + proto.RegisterExtension(E_VerboseEqual) + proto.RegisterExtension(E_Face) + proto.RegisterExtension(E_Gostring) + proto.RegisterExtension(E_Populate) + proto.RegisterExtension(E_Stringer) + proto.RegisterExtension(E_Onlyone) + proto.RegisterExtension(E_Equal) + proto.RegisterExtension(E_Description) + proto.RegisterExtension(E_Testgen) + proto.RegisterExtension(E_Benchgen) + proto.RegisterExtension(E_Marshaler) + proto.RegisterExtension(E_Unmarshaler) + proto.RegisterExtension(E_StableMarshaler) + proto.RegisterExtension(E_Sizer) + proto.RegisterExtension(E_UnsafeMarshaler) + proto.RegisterExtension(E_UnsafeUnmarshaler) + proto.RegisterExtension(E_GoprotoExtensionsMap) + proto.RegisterExtension(E_GoprotoUnrecognized) + proto.RegisterExtension(E_Protosizer) + proto.RegisterExtension(E_Compare) + proto.RegisterExtension(E_Typedecl) + proto.RegisterExtension(E_Messagename) + proto.RegisterExtension(E_GoprotoSizecache) + proto.RegisterExtension(E_GoprotoUnkeyed) + proto.RegisterExtension(E_Nullable) + proto.RegisterExtension(E_Embed) + proto.RegisterExtension(E_Customtype) + proto.RegisterExtension(E_Customname) + proto.RegisterExtension(E_Jsontag) + proto.RegisterExtension(E_Moretags) + proto.RegisterExtension(E_Casttype) + proto.RegisterExtension(E_Castkey) + proto.RegisterExtension(E_Castvalue) + proto.RegisterExtension(E_Stdtime) + proto.RegisterExtension(E_Stdduration) + proto.RegisterExtension(E_Wktpointer) +} + +func init() { proto.RegisterFile("gogo.proto", fileDescriptor_592445b5231bc2b9) } + +var fileDescriptor_592445b5231bc2b9 = []byte{ + // 1328 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x49, 0x6f, 0x1c, 0x45, + 0x14, 0x80, 0x85, 0x48, 0x64, 0x4f, 0x79, 0x8b, 0xc7, 0xc6, 0x84, 0x08, 0x44, 0xe0, 0xc4, 0xc9, + 0x3e, 0x45, 0x28, 0x65, 0x45, 0x96, 0x63, 0x39, 0x56, 0x10, 0x0e, 0xc6, 0x89, 0xc3, 0x76, 0x18, + 0xf5, 0xf4, 0x94, 0xdb, 0x8d, 0xbb, 0xbb, 0x9a, 0xee, 0xea, 0x10, 0xe7, 0x86, 0xc2, 0x22, 0x84, + 0xd8, 0x91, 0x20, 0x21, 0x09, 0x04, 0xc4, 0xbe, 0x86, 0x7d, 0xb9, 0x70, 0x61, 0xb9, 0xf2, 0x1f, + 0xb8, 0x00, 0x66, 0xf7, 0xcd, 0x17, 0xf4, 0xba, 0xdf, 0xeb, 0xa9, 0x69, 0x8f, 0x54, 0x35, 0xb7, + 0xf6, 0xb8, 0xbe, 0x6f, 0xaa, 0xdf, 0xeb, 0x7a, 0xef, 0x4d, 0x33, 0xe6, 0x49, 0x4f, 0x4e, 0xc6, + 0x89, 0x54, 0xb2, 0x5e, 0x83, 0xeb, 0xfc, 0x72, 0xdf, 0x7e, 0x4f, 0x4a, 0x2f, 0x10, 0x53, 0xf9, + 0x5f, 0xcd, 0x6c, 0x75, 0xaa, 0x25, 0x52, 0x37, 0xf1, 0x63, 0x25, 0x93, 0x62, 0x31, 0x3f, 0xc6, + 0xc6, 0x70, 0x71, 0x43, 0x44, 0x59, 0xd8, 0x88, 0x13, 0xb1, 0xea, 0x9f, 0xae, 0x5f, 0x3f, 0x59, + 0x90, 0x93, 0x44, 0x4e, 0xce, 0x47, 0x59, 0x78, 0x47, 0xac, 0x7c, 0x19, 0xa5, 0x7b, 0xaf, 0xfc, + 0x72, 0xf5, 0xfe, 0xab, 0x6e, 0xe9, 0x5f, 0x1e, 0x45, 0x14, 0xfe, 0xb7, 0x94, 0x83, 0x7c, 0x99, + 0x5d, 0xd3, 0xe1, 0x4b, 0x55, 0xe2, 0x47, 0x9e, 0x48, 0x0c, 0xc6, 0xef, 0xd1, 0x38, 0xa6, 0x19, + 0x8f, 0x23, 0xca, 0xe7, 0xd8, 0x50, 0x2f, 0xae, 0x1f, 0xd0, 0x35, 0x28, 0x74, 0xc9, 0x02, 0x1b, + 0xc9, 0x25, 0x6e, 0x96, 0x2a, 0x19, 0x46, 0x4e, 0x28, 0x0c, 0x9a, 0x1f, 0x73, 0x4d, 0x6d, 0x79, + 0x18, 0xb0, 0xb9, 0x92, 0xe2, 0x9c, 0xf5, 0xc3, 0x27, 0x2d, 0xe1, 0x06, 0x06, 0xc3, 0x4f, 0xb8, + 0x91, 0x72, 0x3d, 0x3f, 0xc9, 0xc6, 0xe1, 0xfa, 0x94, 0x13, 0x64, 0x42, 0xdf, 0xc9, 0x4d, 0x5d, + 0x3d, 0x27, 0x61, 0x19, 0xc9, 0x7e, 0x3e, 0xbb, 0x2b, 0xdf, 0xce, 0x58, 0x29, 0xd0, 0xf6, 0xa4, + 0x65, 0xd1, 0x13, 0x4a, 0x89, 0x24, 0x6d, 0x38, 0x41, 0xb7, 0xed, 0x1d, 0xf1, 0x83, 0xd2, 0x78, + 0x6e, 0xb3, 0x33, 0x8b, 0x0b, 0x05, 0x39, 0x1b, 0x04, 0x7c, 0x85, 0x5d, 0xdb, 0xe5, 0xa9, 0xb0, + 0x70, 0x9e, 0x47, 0xe7, 0xf8, 0x8e, 0x27, 0x03, 0xb4, 0x4b, 0x8c, 0x3e, 0x2f, 0x73, 0x69, 0xe1, + 0x7c, 0x19, 0x9d, 0x75, 0x64, 0x29, 0xa5, 0x60, 0xbc, 0x8d, 0x8d, 0x9e, 0x12, 0x49, 0x53, 0xa6, + 0xa2, 0x21, 0x1e, 0xc8, 0x9c, 0xc0, 0x42, 0x77, 0x01, 0x75, 0x23, 0x08, 0xce, 0x03, 0x07, 0xae, + 0x83, 0xac, 0x7f, 0xd5, 0x71, 0x85, 0x85, 0xe2, 0x22, 0x2a, 0xfa, 0x60, 0x3d, 0xa0, 0xb3, 0x6c, + 0xd0, 0x93, 0xc5, 0x2d, 0x59, 0xe0, 0x97, 0x10, 0x1f, 0x20, 0x06, 0x15, 0xb1, 0x8c, 0xb3, 0xc0, + 0x51, 0x36, 0x3b, 0x78, 0x85, 0x14, 0xc4, 0xa0, 0xa2, 0x87, 0xb0, 0xbe, 0x4a, 0x8a, 0x54, 0x8b, + 0xe7, 0x0c, 0x1b, 0x90, 0x51, 0xb0, 0x21, 0x23, 0x9b, 0x4d, 0x5c, 0x46, 0x03, 0x43, 0x04, 0x04, + 0xd3, 0xac, 0x66, 0x9b, 0x88, 0x37, 0x36, 0xe9, 0x78, 0x50, 0x06, 0x16, 0xd8, 0x08, 0x15, 0x28, + 0x5f, 0x46, 0x16, 0x8a, 0x37, 0x51, 0x31, 0xac, 0x61, 0x78, 0x1b, 0x4a, 0xa4, 0xca, 0x13, 0x36, + 0x92, 0xb7, 0xe8, 0x36, 0x10, 0xc1, 0x50, 0x36, 0x45, 0xe4, 0xae, 0xd9, 0x19, 0xde, 0xa6, 0x50, + 0x12, 0x03, 0x8a, 0x39, 0x36, 0x14, 0x3a, 0x49, 0xba, 0xe6, 0x04, 0x56, 0xe9, 0x78, 0x07, 0x1d, + 0x83, 0x25, 0x84, 0x11, 0xc9, 0xa2, 0x5e, 0x34, 0xef, 0x52, 0x44, 0x34, 0x0c, 0x8f, 0x5e, 0xaa, + 0x9c, 0x66, 0x20, 0x1a, 0xbd, 0xd8, 0xde, 0xa3, 0xa3, 0x57, 0xb0, 0x8b, 0xba, 0x71, 0x9a, 0xd5, + 0x52, 0xff, 0x8c, 0x95, 0xe6, 0x7d, 0xca, 0x74, 0x0e, 0x00, 0x7c, 0x0f, 0xbb, 0xae, 0x6b, 0x9b, + 0xb0, 0x90, 0x7d, 0x80, 0xb2, 0x89, 0x2e, 0xad, 0x02, 0x4b, 0x42, 0xaf, 0xca, 0x0f, 0xa9, 0x24, + 0x88, 0x8a, 0x6b, 0x89, 0x8d, 0x67, 0x51, 0xea, 0xac, 0xf6, 0x16, 0xb5, 0x8f, 0x28, 0x6a, 0x05, + 0xdb, 0x11, 0xb5, 0x13, 0x6c, 0x02, 0x8d, 0xbd, 0xe5, 0xf5, 0x63, 0x2a, 0xac, 0x05, 0xbd, 0xd2, + 0x99, 0xdd, 0xfb, 0xd8, 0xbe, 0x32, 0x9c, 0xa7, 0x95, 0x88, 0x52, 0x60, 0x1a, 0xa1, 0x13, 0x5b, + 0x98, 0xaf, 0xa0, 0x99, 0x2a, 0xfe, 0x7c, 0x29, 0x58, 0x74, 0x62, 0x90, 0xdf, 0xcd, 0xf6, 0x92, + 0x3c, 0x8b, 0x12, 0xe1, 0x4a, 0x2f, 0xf2, 0xcf, 0x88, 0x96, 0x85, 0xfa, 0x93, 0x4a, 0xaa, 0x56, + 0x34, 0x1c, 0xcc, 0x47, 0xd9, 0x9e, 0x72, 0x56, 0x69, 0xf8, 0x61, 0x2c, 0x13, 0x65, 0x30, 0x7e, + 0x4a, 0x99, 0x2a, 0xb9, 0xa3, 0x39, 0xc6, 0xe7, 0xd9, 0x70, 0xfe, 0xa7, 0xed, 0x23, 0xf9, 0x19, + 0x8a, 0x86, 0xda, 0x14, 0x16, 0x0e, 0x57, 0x86, 0xb1, 0x93, 0xd8, 0xd4, 0xbf, 0xcf, 0xa9, 0x70, + 0x20, 0x82, 0x85, 0x43, 0x6d, 0xc4, 0x02, 0xba, 0xbd, 0x85, 0xe1, 0x0b, 0x2a, 0x1c, 0xc4, 0xa0, + 0x82, 0x06, 0x06, 0x0b, 0xc5, 0x97, 0xa4, 0x20, 0x06, 0x14, 0x77, 0xb6, 0x1b, 0x6d, 0x22, 0x3c, + 0x3f, 0x55, 0x89, 0x03, 0xab, 0x0d, 0xaa, 0xaf, 0x36, 0x3b, 0x87, 0xb0, 0x65, 0x0d, 0x85, 0x4a, + 0x14, 0x8a, 0x34, 0x75, 0x3c, 0x01, 0x13, 0x87, 0xc5, 0xc6, 0xbe, 0xa6, 0x4a, 0xa4, 0x61, 0xb0, + 0x37, 0x6d, 0x42, 0x84, 0xb0, 0xbb, 0x8e, 0xbb, 0x66, 0xa3, 0xfb, 0xa6, 0xb2, 0xb9, 0xe3, 0xc4, + 0x82, 0x53, 0x9b, 0x7f, 0xb2, 0x68, 0x5d, 0x6c, 0x58, 0x3d, 0x9d, 0xdf, 0x56, 0xe6, 0x9f, 0x95, + 0x82, 0x2c, 0x6a, 0xc8, 0x48, 0x65, 0x9e, 0xaa, 0xdf, 0xb8, 0xc3, 0xb5, 0x58, 0xdc, 0x17, 0xe9, + 0x1e, 0xda, 0xc2, 0xfb, 0xed, 0x1c, 0xa7, 0xf8, 0xed, 0xf0, 0x90, 0x77, 0x0e, 0x3d, 0x66, 0xd9, + 0xd9, 0xad, 0xf2, 0x39, 0xef, 0x98, 0x79, 0xf8, 0x11, 0x36, 0xd4, 0x31, 0xf0, 0x98, 0x55, 0x0f, + 0xa3, 0x6a, 0x50, 0x9f, 0x77, 0xf8, 0x01, 0xb6, 0x0b, 0x86, 0x17, 0x33, 0xfe, 0x08, 0xe2, 0xf9, + 0x72, 0x7e, 0x88, 0xf5, 0xd3, 0xd0, 0x62, 0x46, 0x1f, 0x45, 0xb4, 0x44, 0x00, 0xa7, 0x81, 0xc5, + 0x8c, 0x3f, 0x46, 0x38, 0x21, 0x80, 0xdb, 0x87, 0xf0, 0xbb, 0x27, 0x76, 0x61, 0xd3, 0xa1, 0xd8, + 0x4d, 0xb3, 0x3e, 0x9c, 0x54, 0xcc, 0xf4, 0xe3, 0xf8, 0xe5, 0x44, 0xf0, 0x5b, 0xd9, 0x6e, 0xcb, + 0x80, 0x3f, 0x89, 0x68, 0xb1, 0x9e, 0xcf, 0xb1, 0x01, 0x6d, 0x3a, 0x31, 0xe3, 0x4f, 0x21, 0xae, + 0x53, 0xb0, 0x75, 0x9c, 0x4e, 0xcc, 0x82, 0xa7, 0x69, 0xeb, 0x48, 0x40, 0xd8, 0x68, 0x30, 0x31, + 0xd3, 0xcf, 0x50, 0xd4, 0x09, 0xe1, 0x33, 0xac, 0x56, 0x36, 0x1b, 0x33, 0xff, 0x2c, 0xf2, 0x6d, + 0x06, 0x22, 0xa0, 0x35, 0x3b, 0xb3, 0xe2, 0x39, 0x8a, 0x80, 0x46, 0xc1, 0x31, 0xaa, 0x0e, 0x30, + 0x66, 0xd3, 0xf3, 0x74, 0x8c, 0x2a, 0xf3, 0x0b, 0x64, 0x33, 0xaf, 0xf9, 0x66, 0xc5, 0x0b, 0x94, + 0xcd, 0x7c, 0x3d, 0x6c, 0xa3, 0x3a, 0x11, 0x98, 0x1d, 0x2f, 0xd2, 0x36, 0x2a, 0x03, 0x01, 0x5f, + 0x62, 0xf5, 0x9d, 0xd3, 0x80, 0xd9, 0xf7, 0x12, 0xfa, 0x46, 0x77, 0x0c, 0x03, 0xfc, 0x2e, 0x36, + 0xd1, 0x7d, 0x12, 0x30, 0x5b, 0xcf, 0x6d, 0x55, 0x7e, 0xbb, 0xe9, 0x83, 0x00, 0x3f, 0xd1, 0x6e, + 0x29, 0xfa, 0x14, 0x60, 0xd6, 0x9e, 0xdf, 0xea, 0x2c, 0xdc, 0xfa, 0x10, 0xc0, 0x67, 0x19, 0x6b, + 0x37, 0x60, 0xb3, 0xeb, 0x02, 0xba, 0x34, 0x08, 0x8e, 0x06, 0xf6, 0x5f, 0x33, 0x7f, 0x91, 0x8e, + 0x06, 0x12, 0x70, 0x34, 0xa8, 0xf5, 0x9a, 0xe9, 0x4b, 0x74, 0x34, 0x08, 0x81, 0x27, 0x5b, 0xeb, + 0x6e, 0x66, 0xc3, 0x65, 0x7a, 0xb2, 0x35, 0x8a, 0x1f, 0x63, 0xa3, 0x3b, 0x1a, 0xa2, 0x59, 0xf5, + 0x1a, 0xaa, 0xf6, 0x54, 0xfb, 0xa1, 0xde, 0xbc, 0xb0, 0x19, 0x9a, 0x6d, 0xaf, 0x57, 0x9a, 0x17, + 0xf6, 0x42, 0x3e, 0xcd, 0xfa, 0xa3, 0x2c, 0x08, 0xe0, 0xf0, 0xd4, 0x6f, 0xe8, 0xd2, 0x4d, 0x45, + 0xd0, 0x22, 0xc5, 0xaf, 0xdb, 0x18, 0x1d, 0x02, 0xf8, 0x01, 0xb6, 0x5b, 0x84, 0x4d, 0xd1, 0x32, + 0x91, 0xbf, 0x6d, 0x53, 0xc1, 0x84, 0xd5, 0x7c, 0x86, 0xb1, 0xe2, 0xd5, 0x08, 0x84, 0xd9, 0xc4, + 0xfe, 0xbe, 0x5d, 0xbc, 0xa5, 0xd1, 0x90, 0xb6, 0x20, 0x4f, 0x8a, 0x41, 0xb0, 0xd9, 0x29, 0xc8, + 0x33, 0x72, 0x90, 0xf5, 0xdd, 0x9f, 0xca, 0x48, 0x39, 0x9e, 0x89, 0xfe, 0x03, 0x69, 0x5a, 0x0f, + 0x01, 0x0b, 0x65, 0x22, 0x94, 0xe3, 0xa5, 0x26, 0xf6, 0x4f, 0x64, 0x4b, 0x00, 0x60, 0xd7, 0x49, + 0x95, 0xcd, 0x7d, 0xff, 0x45, 0x30, 0x01, 0xb0, 0x69, 0xb8, 0x5e, 0x17, 0x1b, 0x26, 0xf6, 0x6f, + 0xda, 0x34, 0xae, 0xe7, 0x87, 0x58, 0x0d, 0x2e, 0xf3, 0xb7, 0x4a, 0x26, 0xf8, 0x1f, 0x84, 0xdb, + 0x04, 0x7c, 0x73, 0xaa, 0x5a, 0xca, 0x37, 0x07, 0xfb, 0x5f, 0xcc, 0x34, 0xad, 0xe7, 0xb3, 0x6c, + 0x20, 0x55, 0xad, 0x56, 0x86, 0xf3, 0xa9, 0x01, 0xff, 0x6f, 0xbb, 0x7c, 0x65, 0x51, 0x32, 0x90, + 0xed, 0x07, 0xd7, 0x55, 0x2c, 0xfd, 0x48, 0x89, 0xc4, 0x64, 0xd8, 0x42, 0x83, 0x86, 0x1c, 0x9e, + 0x67, 0x63, 0xae, 0x0c, 0xab, 0xdc, 0x61, 0xb6, 0x20, 0x17, 0xe4, 0x52, 0x5e, 0x67, 0xee, 0xbd, + 0xd9, 0xf3, 0xd5, 0x5a, 0xd6, 0x9c, 0x74, 0x65, 0x38, 0x05, 0xbf, 0x3c, 0xda, 0x2f, 0x54, 0xcb, + 0xdf, 0x21, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xaf, 0x70, 0x4e, 0x83, 0x15, 0x00, 0x00, +} diff --git a/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.golden b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.golden new file mode 100644 index 00000000..f6502e4b --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.golden @@ -0,0 +1,45 @@ +// Code generated by protoc-gen-go. +// source: gogo.proto +// DO NOT EDIT! + +package gogoproto + +import proto "github.com/gogo/protobuf/proto" +import json "encoding/json" +import math "math" +import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" + +// Reference proto, json, and math imports to suppress error if they are not otherwise used. +var _ = proto.Marshal +var _ = &json.SyntaxError{} +var _ = math.Inf + +var E_Nullable = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 51235, + Name: "gogoproto.nullable", + Tag: "varint,51235,opt,name=nullable", +} + +var E_Embed = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 51236, + Name: "gogoproto.embed", + Tag: "varint,51236,opt,name=embed", +} + +var E_Customtype = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 51237, + Name: "gogoproto.customtype", + Tag: "bytes,51237,opt,name=customtype", +} + +func init() { + proto.RegisterExtension(E_Nullable) + proto.RegisterExtension(E_Embed) + proto.RegisterExtension(E_Customtype) +} diff --git a/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto b/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto new file mode 100644 index 00000000..b80c8565 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto @@ -0,0 +1,144 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 = "proto2"; +package gogoproto; + +import "google/protobuf/descriptor.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "GoGoProtos"; +option go_package = "github.com/gogo/protobuf/gogoproto"; + +extend google.protobuf.EnumOptions { + optional bool goproto_enum_prefix = 62001; + optional bool goproto_enum_stringer = 62021; + optional bool enum_stringer = 62022; + optional string enum_customname = 62023; + optional bool enumdecl = 62024; +} + +extend google.protobuf.EnumValueOptions { + optional string enumvalue_customname = 66001; +} + +extend google.protobuf.FileOptions { + optional bool goproto_getters_all = 63001; + optional bool goproto_enum_prefix_all = 63002; + optional bool goproto_stringer_all = 63003; + optional bool verbose_equal_all = 63004; + optional bool face_all = 63005; + optional bool gostring_all = 63006; + optional bool populate_all = 63007; + optional bool stringer_all = 63008; + optional bool onlyone_all = 63009; + + optional bool equal_all = 63013; + optional bool description_all = 63014; + optional bool testgen_all = 63015; + optional bool benchgen_all = 63016; + optional bool marshaler_all = 63017; + optional bool unmarshaler_all = 63018; + optional bool stable_marshaler_all = 63019; + + optional bool sizer_all = 63020; + + optional bool goproto_enum_stringer_all = 63021; + optional bool enum_stringer_all = 63022; + + optional bool unsafe_marshaler_all = 63023; + optional bool unsafe_unmarshaler_all = 63024; + + optional bool goproto_extensions_map_all = 63025; + optional bool goproto_unrecognized_all = 63026; + optional bool gogoproto_import = 63027; + optional bool protosizer_all = 63028; + optional bool compare_all = 63029; + optional bool typedecl_all = 63030; + optional bool enumdecl_all = 63031; + + optional bool goproto_registration = 63032; + optional bool messagename_all = 63033; + + optional bool goproto_sizecache_all = 63034; + optional bool goproto_unkeyed_all = 63035; +} + +extend google.protobuf.MessageOptions { + optional bool goproto_getters = 64001; + optional bool goproto_stringer = 64003; + optional bool verbose_equal = 64004; + optional bool face = 64005; + optional bool gostring = 64006; + optional bool populate = 64007; + optional bool stringer = 67008; + optional bool onlyone = 64009; + + optional bool equal = 64013; + optional bool description = 64014; + optional bool testgen = 64015; + optional bool benchgen = 64016; + optional bool marshaler = 64017; + optional bool unmarshaler = 64018; + optional bool stable_marshaler = 64019; + + optional bool sizer = 64020; + + optional bool unsafe_marshaler = 64023; + optional bool unsafe_unmarshaler = 64024; + + optional bool goproto_extensions_map = 64025; + optional bool goproto_unrecognized = 64026; + + optional bool protosizer = 64028; + optional bool compare = 64029; + + optional bool typedecl = 64030; + + optional bool messagename = 64033; + + optional bool goproto_sizecache = 64034; + optional bool goproto_unkeyed = 64035; +} + +extend google.protobuf.FieldOptions { + optional bool nullable = 65001; + optional bool embed = 65002; + optional string customtype = 65003; + optional string customname = 65004; + optional string jsontag = 65005; + optional string moretags = 65006; + optional string casttype = 65007; + optional string castkey = 65008; + optional string castvalue = 65009; + + optional bool stdtime = 65010; + optional bool stdduration = 65011; + optional bool wktpointer = 65012; + +} diff --git a/vendor/github.com/gogo/protobuf/gogoproto/helper.go b/vendor/github.com/gogo/protobuf/gogoproto/helper.go new file mode 100644 index 00000000..390d4e4b --- /dev/null +++ b/vendor/github.com/gogo/protobuf/gogoproto/helper.go @@ -0,0 +1,415 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 gogoproto + +import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" +import proto "github.com/gogo/protobuf/proto" + +func IsEmbed(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Embed, false) +} + +func IsNullable(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Nullable, true) +} + +func IsStdTime(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Stdtime, false) +} + +func IsStdDuration(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Stdduration, false) +} + +func IsStdDouble(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.DoubleValue" +} + +func IsStdFloat(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.FloatValue" +} + +func IsStdInt64(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.Int64Value" +} + +func IsStdUInt64(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.UInt64Value" +} + +func IsStdInt32(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.Int32Value" +} + +func IsStdUInt32(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.UInt32Value" +} + +func IsStdBool(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.BoolValue" +} + +func IsStdString(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.StringValue" +} + +func IsStdBytes(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) && *field.TypeName == ".google.protobuf.BytesValue" +} + +func IsStdType(field *google_protobuf.FieldDescriptorProto) bool { + return (IsStdTime(field) || IsStdDuration(field) || + IsStdDouble(field) || IsStdFloat(field) || + IsStdInt64(field) || IsStdUInt64(field) || + IsStdInt32(field) || IsStdUInt32(field) || + IsStdBool(field) || + IsStdString(field) || IsStdBytes(field)) +} + +func IsWktPtr(field *google_protobuf.FieldDescriptorProto) bool { + return proto.GetBoolExtension(field.Options, E_Wktpointer, false) +} + +func NeedsNilCheck(proto3 bool, field *google_protobuf.FieldDescriptorProto) bool { + nullable := IsNullable(field) + if field.IsMessage() || IsCustomType(field) { + return nullable + } + if proto3 { + return false + } + return nullable || *field.Type == google_protobuf.FieldDescriptorProto_TYPE_BYTES +} + +func IsCustomType(field *google_protobuf.FieldDescriptorProto) bool { + typ := GetCustomType(field) + if len(typ) > 0 { + return true + } + return false +} + +func IsCastType(field *google_protobuf.FieldDescriptorProto) bool { + typ := GetCastType(field) + if len(typ) > 0 { + return true + } + return false +} + +func IsCastKey(field *google_protobuf.FieldDescriptorProto) bool { + typ := GetCastKey(field) + if len(typ) > 0 { + return true + } + return false +} + +func IsCastValue(field *google_protobuf.FieldDescriptorProto) bool { + typ := GetCastValue(field) + if len(typ) > 0 { + return true + } + return false +} + +func HasEnumDecl(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { + return proto.GetBoolExtension(enum.Options, E_Enumdecl, proto.GetBoolExtension(file.Options, E_EnumdeclAll, true)) +} + +func HasTypeDecl(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Typedecl, proto.GetBoolExtension(file.Options, E_TypedeclAll, true)) +} + +func GetCustomType(field *google_protobuf.FieldDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Customtype) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetCastType(field *google_protobuf.FieldDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Casttype) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetCastKey(field *google_protobuf.FieldDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Castkey) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetCastValue(field *google_protobuf.FieldDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Castvalue) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func IsCustomName(field *google_protobuf.FieldDescriptorProto) bool { + name := GetCustomName(field) + if len(name) > 0 { + return true + } + return false +} + +func IsEnumCustomName(field *google_protobuf.EnumDescriptorProto) bool { + name := GetEnumCustomName(field) + if len(name) > 0 { + return true + } + return false +} + +func IsEnumValueCustomName(field *google_protobuf.EnumValueDescriptorProto) bool { + name := GetEnumValueCustomName(field) + if len(name) > 0 { + return true + } + return false +} + +func GetCustomName(field *google_protobuf.FieldDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Customname) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetEnumCustomName(field *google_protobuf.EnumDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_EnumCustomname) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetEnumValueCustomName(field *google_protobuf.EnumValueDescriptorProto) string { + if field == nil { + return "" + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_EnumvalueCustomname) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetJsonTag(field *google_protobuf.FieldDescriptorProto) *string { + if field == nil { + return nil + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Jsontag) + if err == nil && v.(*string) != nil { + return (v.(*string)) + } + } + return nil +} + +func GetMoreTags(field *google_protobuf.FieldDescriptorProto) *string { + if field == nil { + return nil + } + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_Moretags) + if err == nil && v.(*string) != nil { + return (v.(*string)) + } + } + return nil +} + +type EnableFunc func(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool + +func EnabledGoEnumPrefix(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { + return proto.GetBoolExtension(enum.Options, E_GoprotoEnumPrefix, proto.GetBoolExtension(file.Options, E_GoprotoEnumPrefixAll, true)) +} + +func EnabledGoStringer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoStringer, proto.GetBoolExtension(file.Options, E_GoprotoStringerAll, true)) +} + +func HasGoGetters(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoGetters, proto.GetBoolExtension(file.Options, E_GoprotoGettersAll, true)) +} + +func IsUnion(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Onlyone, proto.GetBoolExtension(file.Options, E_OnlyoneAll, false)) +} + +func HasGoString(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Gostring, proto.GetBoolExtension(file.Options, E_GostringAll, false)) +} + +func HasEqual(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Equal, proto.GetBoolExtension(file.Options, E_EqualAll, false)) +} + +func HasVerboseEqual(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_VerboseEqual, proto.GetBoolExtension(file.Options, E_VerboseEqualAll, false)) +} + +func IsStringer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Stringer, proto.GetBoolExtension(file.Options, E_StringerAll, false)) +} + +func IsFace(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Face, proto.GetBoolExtension(file.Options, E_FaceAll, false)) +} + +func HasDescription(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Description, proto.GetBoolExtension(file.Options, E_DescriptionAll, false)) +} + +func HasPopulate(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Populate, proto.GetBoolExtension(file.Options, E_PopulateAll, false)) +} + +func HasTestGen(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Testgen, proto.GetBoolExtension(file.Options, E_TestgenAll, false)) +} + +func HasBenchGen(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Benchgen, proto.GetBoolExtension(file.Options, E_BenchgenAll, false)) +} + +func IsMarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Marshaler, proto.GetBoolExtension(file.Options, E_MarshalerAll, false)) +} + +func IsUnmarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Unmarshaler, proto.GetBoolExtension(file.Options, E_UnmarshalerAll, false)) +} + +func IsStableMarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_StableMarshaler, proto.GetBoolExtension(file.Options, E_StableMarshalerAll, false)) +} + +func IsSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Sizer, proto.GetBoolExtension(file.Options, E_SizerAll, false)) +} + +func IsProtoSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Protosizer, proto.GetBoolExtension(file.Options, E_ProtosizerAll, false)) +} + +func IsGoEnumStringer(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { + return proto.GetBoolExtension(enum.Options, E_GoprotoEnumStringer, proto.GetBoolExtension(file.Options, E_GoprotoEnumStringerAll, true)) +} + +func IsEnumStringer(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { + return proto.GetBoolExtension(enum.Options, E_EnumStringer, proto.GetBoolExtension(file.Options, E_EnumStringerAll, false)) +} + +func IsUnsafeMarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_UnsafeMarshaler, proto.GetBoolExtension(file.Options, E_UnsafeMarshalerAll, false)) +} + +func IsUnsafeUnmarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_UnsafeUnmarshaler, proto.GetBoolExtension(file.Options, E_UnsafeUnmarshalerAll, false)) +} + +func HasExtensionsMap(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoExtensionsMap, proto.GetBoolExtension(file.Options, E_GoprotoExtensionsMapAll, true)) +} + +func HasUnrecognized(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoUnrecognized, proto.GetBoolExtension(file.Options, E_GoprotoUnrecognizedAll, true)) +} + +func IsProto3(file *google_protobuf.FileDescriptorProto) bool { + return file.GetSyntax() == "proto3" +} + +func ImportsGoGoProto(file *google_protobuf.FileDescriptorProto) bool { + return proto.GetBoolExtension(file.Options, E_GogoprotoImport, true) +} + +func HasCompare(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Compare, proto.GetBoolExtension(file.Options, E_CompareAll, false)) +} + +func RegistersGolangProto(file *google_protobuf.FileDescriptorProto) bool { + return proto.GetBoolExtension(file.Options, E_GoprotoRegistration, false) +} + +func HasMessageName(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Messagename, proto.GetBoolExtension(file.Options, E_MessagenameAll, false)) +} + +func HasSizecache(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoSizecache, proto.GetBoolExtension(file.Options, E_GoprotoSizecacheAll, true)) +} + +func HasUnkeyed(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_GoprotoUnkeyed, proto.GetBoolExtension(file.Options, E_GoprotoUnkeyedAll, true)) +} diff --git a/vendor/github.com/gogo/protobuf/io/full.go b/vendor/github.com/gogo/protobuf/io/full.go new file mode 100644 index 00000000..550726a3 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/io/full.go @@ -0,0 +1,102 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 io + +import ( + "github.com/gogo/protobuf/proto" + "io" +) + +func NewFullWriter(w io.Writer) WriteCloser { + return &fullWriter{w, nil} +} + +type fullWriter struct { + w io.Writer + buffer []byte +} + +func (this *fullWriter) WriteMsg(msg proto.Message) (err error) { + var data []byte + if m, ok := msg.(marshaler); ok { + n, ok := getSize(m) + if !ok { + data, err = proto.Marshal(msg) + if err != nil { + return err + } + } + if n >= len(this.buffer) { + this.buffer = make([]byte, n) + } + _, err = m.MarshalTo(this.buffer) + if err != nil { + return err + } + data = this.buffer[:n] + } else { + data, err = proto.Marshal(msg) + if err != nil { + return err + } + } + _, err = this.w.Write(data) + return err +} + +func (this *fullWriter) Close() error { + if closer, ok := this.w.(io.Closer); ok { + return closer.Close() + } + return nil +} + +type fullReader struct { + r io.Reader + buf []byte +} + +func NewFullReader(r io.Reader, maxSize int) ReadCloser { + return &fullReader{r, make([]byte, maxSize)} +} + +func (this *fullReader) ReadMsg(msg proto.Message) error { + length, err := this.r.Read(this.buf) + if err != nil { + return err + } + return proto.Unmarshal(this.buf[:length], msg) +} + +func (this *fullReader) Close() error { + if closer, ok := this.r.(io.Closer); ok { + return closer.Close() + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/io/io.go b/vendor/github.com/gogo/protobuf/io/io.go new file mode 100644 index 00000000..6dca519a --- /dev/null +++ b/vendor/github.com/gogo/protobuf/io/io.go @@ -0,0 +1,70 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 io + +import ( + "github.com/gogo/protobuf/proto" + "io" +) + +type Writer interface { + WriteMsg(proto.Message) error +} + +type WriteCloser interface { + Writer + io.Closer +} + +type Reader interface { + ReadMsg(msg proto.Message) error +} + +type ReadCloser interface { + Reader + io.Closer +} + +type marshaler interface { + MarshalTo(data []byte) (n int, err error) +} + +func getSize(v interface{}) (int, bool) { + if sz, ok := v.(interface { + Size() (n int) + }); ok { + return sz.Size(), true + } else if sz, ok := v.(interface { + ProtoSize() (n int) + }); ok { + return sz.ProtoSize(), true + } else { + return 0, false + } +} diff --git a/vendor/github.com/gogo/protobuf/io/uint32.go b/vendor/github.com/gogo/protobuf/io/uint32.go new file mode 100644 index 00000000..fc43857d --- /dev/null +++ b/vendor/github.com/gogo/protobuf/io/uint32.go @@ -0,0 +1,138 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 io + +import ( + "encoding/binary" + "io" + + "github.com/gogo/protobuf/proto" +) + +const uint32BinaryLen = 4 + +func NewUint32DelimitedWriter(w io.Writer, byteOrder binary.ByteOrder) WriteCloser { + return &uint32Writer{w, byteOrder, nil, make([]byte, uint32BinaryLen)} +} + +func NewSizeUint32DelimitedWriter(w io.Writer, byteOrder binary.ByteOrder, size int) WriteCloser { + return &uint32Writer{w, byteOrder, make([]byte, size), make([]byte, uint32BinaryLen)} +} + +type uint32Writer struct { + w io.Writer + byteOrder binary.ByteOrder + buffer []byte + lenBuf []byte +} + +func (this *uint32Writer) writeFallback(msg proto.Message) error { + data, err := proto.Marshal(msg) + if err != nil { + return err + } + + length := uint32(len(data)) + this.byteOrder.PutUint32(this.lenBuf, length) + if _, err = this.w.Write(this.lenBuf); err != nil { + return err + } + _, err = this.w.Write(data) + return err +} + +func (this *uint32Writer) WriteMsg(msg proto.Message) error { + m, ok := msg.(marshaler) + if !ok { + return this.writeFallback(msg) + } + + n, ok := getSize(m) + if !ok { + return this.writeFallback(msg) + } + + size := n + uint32BinaryLen + if size > len(this.buffer) { + this.buffer = make([]byte, size) + } + + this.byteOrder.PutUint32(this.buffer, uint32(n)) + if _, err := m.MarshalTo(this.buffer[uint32BinaryLen:]); err != nil { + return err + } + + _, err := this.w.Write(this.buffer[:size]) + return err +} + +func (this *uint32Writer) Close() error { + if closer, ok := this.w.(io.Closer); ok { + return closer.Close() + } + return nil +} + +type uint32Reader struct { + r io.Reader + byteOrder binary.ByteOrder + lenBuf []byte + buf []byte + maxSize int +} + +func NewUint32DelimitedReader(r io.Reader, byteOrder binary.ByteOrder, maxSize int) ReadCloser { + return &uint32Reader{r, byteOrder, make([]byte, 4), nil, maxSize} +} + +func (this *uint32Reader) ReadMsg(msg proto.Message) error { + if _, err := io.ReadFull(this.r, this.lenBuf); err != nil { + return err + } + length32 := this.byteOrder.Uint32(this.lenBuf) + length := int(length32) + if length < 0 || length > this.maxSize { + return io.ErrShortBuffer + } + if length >= len(this.buf) { + this.buf = make([]byte, length) + } + _, err := io.ReadFull(this.r, this.buf[:length]) + if err != nil { + return err + } + return proto.Unmarshal(this.buf[:length], msg) +} + +func (this *uint32Reader) Close() error { + if closer, ok := this.r.(io.Closer); ok { + return closer.Close() + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/io/varint.go b/vendor/github.com/gogo/protobuf/io/varint.go new file mode 100644 index 00000000..e81e296e --- /dev/null +++ b/vendor/github.com/gogo/protobuf/io/varint.go @@ -0,0 +1,133 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 io + +import ( + "bufio" + "encoding/binary" + "errors" + "github.com/gogo/protobuf/proto" + "io" +) + +var ( + errSmallBuffer = errors.New("Buffer Too Small") + errLargeValue = errors.New("Value is Larger than 64 bits") +) + +func NewDelimitedWriter(w io.Writer) WriteCloser { + return &varintWriter{w, make([]byte, binary.MaxVarintLen64), nil} +} + +type varintWriter struct { + w io.Writer + lenBuf []byte + buffer []byte +} + +func (this *varintWriter) WriteMsg(msg proto.Message) (err error) { + var data []byte + if m, ok := msg.(marshaler); ok { + n, ok := getSize(m) + if ok { + if n+binary.MaxVarintLen64 >= len(this.buffer) { + this.buffer = make([]byte, n+binary.MaxVarintLen64) + } + lenOff := binary.PutUvarint(this.buffer, uint64(n)) + _, err = m.MarshalTo(this.buffer[lenOff:]) + if err != nil { + return err + } + _, err = this.w.Write(this.buffer[:lenOff+n]) + return err + } + } + + // fallback + data, err = proto.Marshal(msg) + if err != nil { + return err + } + length := uint64(len(data)) + n := binary.PutUvarint(this.lenBuf, length) + _, err = this.w.Write(this.lenBuf[:n]) + if err != nil { + return err + } + _, err = this.w.Write(data) + return err +} + +func (this *varintWriter) Close() error { + if closer, ok := this.w.(io.Closer); ok { + return closer.Close() + } + return nil +} + +func NewDelimitedReader(r io.Reader, maxSize int) ReadCloser { + var closer io.Closer + if c, ok := r.(io.Closer); ok { + closer = c + } + return &varintReader{bufio.NewReader(r), nil, maxSize, closer} +} + +type varintReader struct { + r *bufio.Reader + buf []byte + maxSize int + closer io.Closer +} + +func (this *varintReader) ReadMsg(msg proto.Message) error { + length64, err := binary.ReadUvarint(this.r) + if err != nil { + return err + } + length := int(length64) + if length < 0 || length > this.maxSize { + return io.ErrShortBuffer + } + if len(this.buf) < length { + this.buf = make([]byte, length) + } + buf := this.buf[:length] + if _, err := io.ReadFull(this.r, buf); err != nil { + return err + } + return proto.Unmarshal(buf, msg) +} + +func (this *varintReader) Close() error { + if this.closer != nil { + return this.closer.Close() + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/proto/Makefile b/vendor/github.com/gogo/protobuf/proto/Makefile new file mode 100644 index 00000000..00d65f32 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/Makefile @@ -0,0 +1,43 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 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. + +install: + go install + +test: install generate-test-pbs + go test + + +generate-test-pbs: + make install + make -C test_proto + make -C proto3_proto + make diff --git a/vendor/github.com/gogo/protobuf/proto/clone.go b/vendor/github.com/gogo/protobuf/proto/clone.go new file mode 100644 index 00000000..a26b046d --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/clone.go @@ -0,0 +1,258 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 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. + +// Protocol buffer deep copy and merge. +// TODO: RawMessage. + +package proto + +import ( + "fmt" + "log" + "reflect" + "strings" +) + +// Clone returns a deep copy of a protocol buffer. +func Clone(src Message) Message { + in := reflect.ValueOf(src) + if in.IsNil() { + return src + } + out := reflect.New(in.Type().Elem()) + dst := out.Interface().(Message) + Merge(dst, src) + return dst +} + +// Merger is the interface representing objects that can merge messages of the same type. +type Merger interface { + // Merge merges src into this message. + // Required and optional fields that are set in src will be set to that value in dst. + // Elements of repeated fields will be appended. + // + // Merge may panic if called with a different argument type than the receiver. + Merge(src Message) +} + +// generatedMerger is the custom merge method that generated protos will have. +// We must add this method since a generate Merge method will conflict with +// many existing protos that have a Merge data field already defined. +type generatedMerger interface { + XXX_Merge(src Message) +} + +// Merge merges src into dst. +// Required and optional fields that are set in src will be set to that value in dst. +// Elements of repeated fields will be appended. +// Merge panics if src and dst are not the same type, or if dst is nil. +func Merge(dst, src Message) { + if m, ok := dst.(Merger); ok { + m.Merge(src) + return + } + + in := reflect.ValueOf(src) + out := reflect.ValueOf(dst) + if out.IsNil() { + panic("proto: nil destination") + } + if in.Type() != out.Type() { + panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) + } + if in.IsNil() { + return // Merge from nil src is a noop + } + if m, ok := dst.(generatedMerger); ok { + m.XXX_Merge(src) + return + } + mergeStruct(out.Elem(), in.Elem()) +} + +func mergeStruct(out, in reflect.Value) { + sprop := GetProperties(in.Type()) + for i := 0; i < in.NumField(); i++ { + f := in.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) + } + + if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { + emOut := out.Addr().Interface().(extensionsBytes) + bIn := emIn.GetExtensions() + bOut := emOut.GetExtensions() + *bOut = append(*bOut, *bIn...) + } else if emIn, err := extendable(in.Addr().Interface()); err == nil { + emOut, _ := extendable(out.Addr().Interface()) + mIn, muIn := emIn.extensionsRead() + if mIn != nil { + mOut := emOut.extensionsWrite() + muIn.Lock() + mergeExtension(mOut, mIn) + muIn.Unlock() + } + } + + uf := in.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return + } + uin := uf.Bytes() + if len(uin) > 0 { + out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) + } +} + +// mergeAny performs a merge between two values of the same type. +// viaPtr indicates whether the values were indirected through a pointer (implying proto2). +// prop is set if this is a struct field (it may be nil). +func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { + if in.Type() == protoMessageType { + if !in.IsNil() { + if out.IsNil() { + out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) + } else { + Merge(out.Interface().(Message), in.Interface().(Message)) + } + } + return + } + switch in.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + if !viaPtr && isProto3Zero(in) { + return + } + out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) + case reflect.Map: + if in.Len() == 0 { + return + } + if out.IsNil() { + out.Set(reflect.MakeMap(in.Type())) + } + // For maps with value types of *T or []byte we need to deep copy each value. + elemKind := in.Type().Elem().Kind() + for _, key := range in.MapKeys() { + var val reflect.Value + switch elemKind { + case reflect.Ptr: + val = reflect.New(in.Type().Elem().Elem()) + mergeAny(val, in.MapIndex(key), false, nil) + case reflect.Slice: + val = in.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + default: + val = in.MapIndex(key) + } + out.SetMapIndex(key, val) + } + case reflect.Ptr: + if in.IsNil() { + return + } + if out.IsNil() { + out.Set(reflect.New(in.Elem().Type())) + } + mergeAny(out.Elem(), in.Elem(), true, nil) + case reflect.Slice: + if in.IsNil() { + return + } + if in.Type().Elem().Kind() == reflect.Uint8 { + // []byte is a scalar bytes field, not a repeated field. + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value, and should not + // be merged. + if prop != nil && prop.proto3 && in.Len() == 0 { + return + } + + // Make a deep copy. + // Append to []byte{} instead of []byte(nil) so that we never end up + // with a nil result. + out.SetBytes(append([]byte{}, in.Bytes()...)) + return + } + n := in.Len() + if out.IsNil() { + out.Set(reflect.MakeSlice(in.Type(), 0, n)) + } + switch in.Type().Elem().Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + out.Set(reflect.AppendSlice(out, in)) + default: + for i := 0; i < n; i++ { + x := reflect.Indirect(reflect.New(in.Type().Elem())) + mergeAny(x, in.Index(i), false, nil) + out.Set(reflect.Append(out, x)) + } + } + case reflect.Struct: + mergeStruct(out, in) + default: + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to copy %v", in) + } +} + +func mergeExtension(out, in map[int32]Extension) { + for extNum, eIn := range in { + eOut := Extension{desc: eIn.desc} + if eIn.value != nil { + v := reflect.New(reflect.TypeOf(eIn.value)).Elem() + mergeAny(v, reflect.ValueOf(eIn.value), false, nil) + eOut.value = v.Interface() + } + if eIn.enc != nil { + eOut.enc = make([]byte, len(eIn.enc)) + copy(eOut.enc, eIn.enc) + } + + out[extNum] = eOut + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/custom_gogo.go b/vendor/github.com/gogo/protobuf/proto/custom_gogo.go new file mode 100644 index 00000000..24552483 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/custom_gogo.go @@ -0,0 +1,39 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import "reflect" + +type custom interface { + Marshal() ([]byte, error) + Unmarshal(data []byte) error + Size() int +} + +var customType = reflect.TypeOf((*custom)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go new file mode 100644 index 00000000..63b0f08b --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/decode.go @@ -0,0 +1,427 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Routines for decoding protocol buffer data to construct in-memory representations. + */ + +import ( + "errors" + "fmt" + "io" +) + +// errOverflow is returned when an integer is too large to be represented. +var errOverflow = errors.New("proto: integer overflow") + +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + +// DecodeVarint reads a varint-encoded integer from the slice. +// It returns the integer and the number of bytes consumed, or +// zero if there is not enough. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func DecodeVarint(buf []byte) (x uint64, n int) { + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + +func (p *Buffer) decodeVarintSlow() (x uint64, err error) { + i := p.index + l := len(p.buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + b := p.buf[i] + i++ + x |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + p.index = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + i := p.index + buf := p.buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + p.index++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return p.decodeVarintSlow() + } + + var b uint64 + // we already checked the first byte + x = uint64(buf[i]) - 0x80 + i++ + + b = uint64(buf[i]) + i++ + x += b << 7 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 7 + + b = uint64(buf[i]) + i++ + x += b << 14 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 14 + + b = uint64(buf[i]) + i++ + x += b << 21 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 21 + + b = uint64(buf[i]) + i++ + x += b << 28 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 28 + + b = uint64(buf[i]) + i++ + x += b << 35 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 35 + + b = uint64(buf[i]) + i++ + x += b << 42 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 42 + + b = uint64(buf[i]) + i++ + x += b << 49 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 49 + + b = uint64(buf[i]) + i++ + x += b << 56 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 56 + + b = uint64(buf[i]) + i++ + x += b << 63 + if b&0x80 == 0 { + goto done + } + + return 0, errOverflow + +done: + p.index = i + return x, nil +} + +// DecodeFixed64 reads a 64-bit integer from the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) DecodeFixed64() (x uint64, err error) { + // x, err already 0 + i := p.index + 8 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-8]) + x |= uint64(p.buf[i-7]) << 8 + x |= uint64(p.buf[i-6]) << 16 + x |= uint64(p.buf[i-5]) << 24 + x |= uint64(p.buf[i-4]) << 32 + x |= uint64(p.buf[i-3]) << 40 + x |= uint64(p.buf[i-2]) << 48 + x |= uint64(p.buf[i-1]) << 56 + return +} + +// DecodeFixed32 reads a 32-bit integer from the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) DecodeFixed32() (x uint64, err error) { + // x, err already 0 + i := p.index + 4 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-4]) + x |= uint64(p.buf[i-3]) << 8 + x |= uint64(p.buf[i-2]) << 16 + x |= uint64(p.buf[i-1]) << 24 + return +} + +// DecodeZigzag64 reads a zigzag-encoded 64-bit integer +// from the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) DecodeZigzag64() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) + return +} + +// DecodeZigzag32 reads a zigzag-encoded 32-bit integer +// from the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) DecodeZigzag32() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) + return +} + +// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { + n, err := p.DecodeVarint() + if err != nil { + return nil, err + } + + nb := int(n) + if nb < 0 { + return nil, fmt.Errorf("proto: bad byte length %d", nb) + } + end := p.index + nb + if end < p.index || end > len(p.buf) { + return nil, io.ErrUnexpectedEOF + } + + if !alloc { + // todo: check if can get more uses of alloc=false + buf = p.buf[p.index:end] + p.index += nb + return + } + + buf = make([]byte, nb) + copy(buf, p.buf[p.index:]) + p.index += nb + return +} + +// DecodeStringBytes reads an encoded string from the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) DecodeStringBytes() (s string, err error) { + buf, err := p.DecodeRawBytes(false) + if err != nil { + return + } + return string(buf), nil +} + +// Unmarshaler is the interface representing objects that can +// unmarshal themselves. The argument points to data that may be +// overwritten, so implementations should not keep references to the +// buffer. +// Unmarshal implementations should not clear the receiver. +// Any unmarshaled data should be merged into the receiver. +// Callers of Unmarshal that do not want to retain existing data +// should Reset the receiver before calling Unmarshal. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// newUnmarshaler is the interface representing objects that can +// unmarshal themselves. The semantics are identical to Unmarshaler. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newUnmarshaler interface { + XXX_Unmarshal([]byte) error +} + +// Unmarshal parses the protocol buffer representation in buf and places the +// decoded result in pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// Unmarshal resets pb before starting to unmarshal, so any +// existing data in pb is always removed. Use UnmarshalMerge +// to preserve and append to existing data. +func Unmarshal(buf []byte, pb Message) error { + pb.Reset() + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// UnmarshalMerge parses the protocol buffer representation in buf and +// writes the decoded result to pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// UnmarshalMerge merges into existing data in pb. +// Most code should use Unmarshal instead. +func UnmarshalMerge(buf []byte, pb Message) error { + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +// StartGroup tag is already consumed. This function consumes +// EndGroup tag. +func (p *Buffer) DecodeGroup(pb Message) error { + b := p.buf[p.index:] + x, y := findEndGroup(b) + if x < 0 { + return io.ErrUnexpectedEOF + } + err := Unmarshal(b[:x], pb) + p.index += y + return err +} + +// Unmarshal parses the protocol buffer representation in the +// Buffer and places the decoded result in pb. If the struct +// underlying pb does not match the data in the buffer, the results can be +// unpredictable. +// +// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. +func (p *Buffer) Unmarshal(pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(newUnmarshaler); ok { + err := u.XXX_Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + err := u.Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + + // Slow workaround for messages that aren't Unmarshalers. + // This includes some hand-coded .pb.go files and + // bootstrap protos. + // TODO: fix all of those and then add Unmarshal to + // the Message interface. Then: + // The cast above and code below can be deleted. + // The old unmarshaler can be deleted. + // Clients can call Unmarshal directly (can already do that, actually). + var info InternalMessageInfo + err := info.Unmarshal(pb, p.buf[p.index:]) + p.index = len(p.buf) + return err +} diff --git a/vendor/github.com/gogo/protobuf/proto/deprecated.go b/vendor/github.com/gogo/protobuf/proto/deprecated.go new file mode 100644 index 00000000..35b882c0 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/deprecated.go @@ -0,0 +1,63 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2018 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 proto + +import "errors" + +// Deprecated: do not use. +type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } + +// Deprecated: do not use. +func GetStats() Stats { return Stats{} } + +// Deprecated: do not use. +func MarshalMessageSet(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSet([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func MarshalMessageSetJSON(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSetJSON([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/gogo/protobuf/proto/discard.go b/vendor/github.com/gogo/protobuf/proto/discard.go new file mode 100644 index 00000000..fe1bd7d9 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/discard.go @@ -0,0 +1,350 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2017 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 proto + +import ( + "fmt" + "reflect" + "strings" + "sync" + "sync/atomic" +) + +type generatedDiscarder interface { + XXX_DiscardUnknown() +} + +// DiscardUnknown recursively discards all unknown fields from this message +// and all embedded messages. +// +// When unmarshaling a message with unrecognized fields, the tags and values +// of such fields are preserved in the Message. This allows a later call to +// marshal to be able to produce a message that continues to have those +// unrecognized fields. To avoid this, DiscardUnknown is used to +// explicitly clear the unknown fields after unmarshaling. +// +// For proto2 messages, the unknown fields of message extensions are only +// discarded from messages that have been accessed via GetExtension. +func DiscardUnknown(m Message) { + if m, ok := m.(generatedDiscarder); ok { + m.XXX_DiscardUnknown() + return + } + // TODO: Dynamically populate a InternalMessageInfo for legacy messages, + // but the master branch has no implementation for InternalMessageInfo, + // so it would be more work to replicate that approach. + discardLegacy(m) +} + +// DiscardUnknown recursively discards all unknown fields. +func (a *InternalMessageInfo) DiscardUnknown(m Message) { + di := atomicLoadDiscardInfo(&a.discard) + if di == nil { + di = getDiscardInfo(reflect.TypeOf(m).Elem()) + atomicStoreDiscardInfo(&a.discard, di) + } + di.discard(toPointer(&m)) +} + +type discardInfo struct { + typ reflect.Type + + initialized int32 // 0: only typ is valid, 1: everything is valid + lock sync.Mutex + + fields []discardFieldInfo + unrecognized field +} + +type discardFieldInfo struct { + field field // Offset of field, guaranteed to be valid + discard func(src pointer) +} + +var ( + discardInfoMap = map[reflect.Type]*discardInfo{} + discardInfoLock sync.Mutex +) + +func getDiscardInfo(t reflect.Type) *discardInfo { + discardInfoLock.Lock() + defer discardInfoLock.Unlock() + di := discardInfoMap[t] + if di == nil { + di = &discardInfo{typ: t} + discardInfoMap[t] = di + } + return di +} + +func (di *discardInfo) discard(src pointer) { + if src.isNil() { + return // Nothing to do. + } + + if atomic.LoadInt32(&di.initialized) == 0 { + di.computeDiscardInfo() + } + + for _, fi := range di.fields { + sfp := src.offset(fi.field) + fi.discard(sfp) + } + + // For proto2 messages, only discard unknown fields in message extensions + // that have been accessed via GetExtension. + if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { + // Ignore lock since DiscardUnknown is not concurrency safe. + emm, _ := em.extensionsRead() + for _, mx := range emm { + if m, ok := mx.value.(Message); ok { + DiscardUnknown(m) + } + } + } + + if di.unrecognized.IsValid() { + *src.offset(di.unrecognized).toBytes() = nil + } +} + +func (di *discardInfo) computeDiscardInfo() { + di.lock.Lock() + defer di.lock.Unlock() + if di.initialized != 0 { + return + } + t := di.typ + n := t.NumField() + + for i := 0; i < n; i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + + dfi := discardFieldInfo{field: toField(&f)} + tf := f.Type + + // Unwrap tf to get its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) + } + + switch tf.Kind() { + case reflect.Struct: + switch { + case !isPointer: + panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) + case isSlice: // E.g., []*pb.T + discardInfo := getDiscardInfo(tf) + dfi.discard = func(src pointer) { + sps := src.getPointerSlice() + for _, sp := range sps { + if !sp.isNil() { + discardInfo.discard(sp) + } + } + } + default: // E.g., *pb.T + discardInfo := getDiscardInfo(tf) + dfi.discard = func(src pointer) { + sp := src.getPointer() + if !sp.isNil() { + discardInfo.discard(sp) + } + } + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) + default: // E.g., map[K]V + if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) + dfi.discard = func(src pointer) { + sm := src.asPointerTo(tf).Elem() + if sm.Len() == 0 { + return + } + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + DiscardUnknown(val.Interface().(Message)) + } + } + } else { + dfi.discard = func(pointer) {} // Noop + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) + default: // E.g., interface{} + // TODO: Make this faster? + dfi.discard = func(src pointer) { + su := src.asPointerTo(tf).Elem() + if !su.IsNil() { + sv := su.Elem().Elem().Field(0) + if sv.Kind() == reflect.Ptr && sv.IsNil() { + return + } + switch sv.Type().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + DiscardUnknown(sv.Interface().(Message)) + } + } + } + } + default: + continue + } + di.fields = append(di.fields, dfi) + } + + di.unrecognized = invalidField + if f, ok := t.FieldByName("XXX_unrecognized"); ok { + if f.Type != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + di.unrecognized = toField(&f) + } + + atomic.StoreInt32(&di.initialized, 1) +} + +func discardLegacy(m Message) { + v := reflect.ValueOf(m) + if v.Kind() != reflect.Ptr || v.IsNil() { + return + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return + } + t := v.Type() + + for i := 0; i < v.NumField(); i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + vf := v.Field(i) + tf := f.Type + + // Unwrap tf to get its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) + } + + switch tf.Kind() { + case reflect.Struct: + switch { + case !isPointer: + panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) + case isSlice: // E.g., []*pb.T + for j := 0; j < vf.Len(); j++ { + discardLegacy(vf.Index(j).Interface().(Message)) + } + default: // E.g., *pb.T + discardLegacy(vf.Interface().(Message)) + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) + default: // E.g., map[K]V + tv := vf.Type().Elem() + if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) + for _, key := range vf.MapKeys() { + val := vf.MapIndex(key) + discardLegacy(val.Interface().(Message)) + } + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) + default: // E.g., test_proto.isCommunique_Union interface + if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { + vf = vf.Elem() // E.g., *test_proto.Communique_Msg + if !vf.IsNil() { + vf = vf.Elem() // E.g., test_proto.Communique_Msg + vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value + if vf.Kind() == reflect.Ptr { + discardLegacy(vf.Interface().(Message)) + } + } + } + } + } + } + + if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { + if vf.Type() != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + vf.Set(reflect.ValueOf([]byte(nil))) + } + + // For proto2 messages, only discard unknown fields in message extensions + // that have been accessed via GetExtension. + if em, err := extendable(m); err == nil { + // Ignore lock since discardLegacy is not concurrency safe. + emm, _ := em.extensionsRead() + for _, mx := range emm { + if m, ok := mx.value.(Message); ok { + discardLegacy(m) + } + } + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/duration.go b/vendor/github.com/gogo/protobuf/proto/duration.go new file mode 100644 index 00000000..93464c91 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/duration.go @@ -0,0 +1,100 @@ +// 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 proto + +// This file implements conversions between google.protobuf.Duration +// and time.Duration. + +import ( + "errors" + "fmt" + "time" +) + +const ( + // Range of a 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 Duration is valid according to the +// definition in google/protobuf/duration.proto. A valid Duration +// may still be too large to fit into a time.Duration (the range of Duration +// is about 10,000 years, and the range of time.Duration is about 290). +func validateDuration(d *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 +} + +// DurationFromProto converts a Duration to a time.Duration. DurationFromProto +// returns an error if the Duration is invalid or is too large to be +// represented in a time.Duration. +func durationFromProto(p *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 Duration. +func durationProto(d time.Duration) *duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &duration{ + Seconds: secs, + Nanos: int32(nanos), + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go new file mode 100644 index 00000000..e748e173 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go @@ -0,0 +1,49 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2016, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "reflect" + "time" +) + +var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem() + +type duration struct { + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (m *duration) Reset() { *m = duration{} } +func (*duration) ProtoMessage() {} +func (*duration) String() string { return "duration" } + +func init() { + RegisterType((*duration)(nil), "gogo.protobuf.proto.duration") +} diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go new file mode 100644 index 00000000..3abfed2c --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/encode.go @@ -0,0 +1,203 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "errors" + "reflect" +) + +var ( + // errRepeatedHasNil is the error returned if Marshal is called with + // a struct with a repeated field containing a nil element. + errRepeatedHasNil = errors.New("proto: repeated field has nil element") + + // errOneofHasNil is the error returned if Marshal is called with + // a struct with a oneof field containing a nil element. + errOneofHasNil = errors.New("proto: oneof field has nil value") + + // ErrNil is the error returned if Marshal is called with nil. + ErrNil = errors.New("proto: Marshal called with nil") + + // ErrTooLarge is the error returned if Marshal is called with a + // message that encodes to >2GB. + ErrTooLarge = errors.New("proto: message encodes to over 2 GB") +) + +// The fundamental encoders that put bytes on the wire. +// Those that take integer types all accept uint64 and are +// therefore of type valueEncoder. + +const maxVarintBytes = 10 // maximum length of a varint + +// EncodeVarint returns the varint encoding of x. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +// Not used by the package itself, but helpful to clients +// wishing to use the same encoding. +func EncodeVarint(x uint64) []byte { + var buf [maxVarintBytes]byte + var n int + for n = 0; x > 127; n++ { + buf[n] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + buf[n] = uint8(x) + n++ + return buf[0:n] +} + +// EncodeVarint writes a varint-encoded integer to the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) EncodeVarint(x uint64) error { + for x >= 1<<7 { + p.buf = append(p.buf, uint8(x&0x7f|0x80)) + x >>= 7 + } + p.buf = append(p.buf, uint8(x)) + return nil +} + +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + switch { + case x < 1<<7: + return 1 + case x < 1<<14: + return 2 + case x < 1<<21: + return 3 + case x < 1<<28: + return 4 + case x < 1<<35: + return 5 + case x < 1<<42: + return 6 + case x < 1<<49: + return 7 + case x < 1<<56: + return 8 + case x < 1<<63: + return 9 + } + return 10 +} + +// EncodeFixed64 writes a 64-bit integer to the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) EncodeFixed64(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24), + uint8(x>>32), + uint8(x>>40), + uint8(x>>48), + uint8(x>>56)) + return nil +} + +// EncodeFixed32 writes a 32-bit integer to the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) EncodeFixed32(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24)) + return nil +} + +// EncodeZigzag64 writes a zigzag-encoded 64-bit integer +// to the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) EncodeZigzag64(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +// EncodeZigzag32 writes a zigzag-encoded 32-bit integer +// to the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) EncodeZigzag32(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) EncodeRawBytes(b []byte) error { + p.EncodeVarint(uint64(len(b))) + p.buf = append(p.buf, b...) + return nil +} + +// EncodeStringBytes writes an encoded string to the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) EncodeStringBytes(s string) error { + p.EncodeVarint(uint64(len(s))) + p.buf = append(p.buf, s...) + return nil +} + +// Marshaler is the interface representing objects that can marshal themselves. +type Marshaler interface { + Marshal() ([]byte, error) +} + +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + siz := Size(pb) + p.EncodeVarint(uint64(siz)) + return p.Marshal(pb) +} + +// All protocol buffer fields are nillable, but be careful. +func isNil(v reflect.Value) bool { + switch v.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + return false +} diff --git a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go new file mode 100644 index 00000000..0f5fb173 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go @@ -0,0 +1,33 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +func NewRequiredNotSetError(field string) *RequiredNotSetError { + return &RequiredNotSetError{field} +} diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go new file mode 100644 index 00000000..d4db5a1c --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/equal.go @@ -0,0 +1,300 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 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. + +// Protocol buffer comparison. + +package proto + +import ( + "bytes" + "log" + "reflect" + "strings" +) + +/* +Equal returns true iff protocol buffers a and b are equal. +The arguments must both be pointers to protocol buffer structs. + +Equality is defined in this way: + - Two messages are equal iff they are the same type, + corresponding fields are equal, unknown field sets + are equal, and extensions sets are equal. + - Two set scalar fields are equal iff their values are equal. + If the fields are of a floating-point type, remember that + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). + - Two repeated fields are equal iff their lengths are the same, + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. + - Two unset fields are equal. + - Two unknown field sets are equal if their current + encoded state is equal. + - Two extension sets are equal iff they have corresponding + elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. + - Every other combination of things are not equal. + +The return value is undefined if a and b are not protocol buffers. +*/ +func Equal(a, b Message) bool { + if a == nil || b == nil { + return a == b + } + v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) + if v1.Type() != v2.Type() { + return false + } + if v1.Kind() == reflect.Ptr { + if v1.IsNil() { + return v2.IsNil() + } + if v2.IsNil() { + return false + } + v1, v2 = v1.Elem(), v2.Elem() + } + if v1.Kind() != reflect.Struct { + return false + } + return equalStruct(v1, v2) +} + +// v1 and v2 are known to have the same type. +func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) + for i := 0; i < v1.NumField(); i++ { + f := v1.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + f1, f2 := v1.Field(i), v2.Field(i) + if f.Type.Kind() == reflect.Ptr { + if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { + // both unset + continue + } else if n1 != n2 { + // set/unset mismatch + return false + } + f1, f2 = f1.Elem(), f2.Elem() + } + if !equalAny(f1, f2, sprop.Prop[i]) { + return false + } + } + + if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_InternalExtensions") + if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { + return false + } + } + + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_extensions") + if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + return false + } + } + + uf := v1.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return true + } + + u1 := uf.Bytes() + u2 := v2.FieldByName("XXX_unrecognized").Bytes() + return bytes.Equal(u1, u2) +} + +// v1 and v2 are known to have the same type. +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { + if v1.Type() == protoMessageType { + m1, _ := v1.Interface().(Message) + m2, _ := v2.Interface().(Message) + return Equal(m1, m2) + } + switch v1.Kind() { + case reflect.Bool: + return v1.Bool() == v2.Bool() + case reflect.Float32, reflect.Float64: + return v1.Float() == v2.Float() + case reflect.Int32, reflect.Int64: + return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2, nil) { + return false + } + } + return true + case reflect.Ptr: + // Maps may have nil values in them, so check for nil. + if v1.IsNil() && v2.IsNil() { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return equalAny(v1.Elem(), v2.Elem(), prop) + case reflect.Slice: + if v1.Type().Elem().Kind() == reflect.Uint8 { + // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) + } + + if v1.Len() != v2.Len() { + return false + } + for i := 0; i < v1.Len(); i++ { + if !equalAny(v1.Index(i), v2.Index(i), prop) { + return false + } + } + return true + case reflect.String: + return v1.Interface().(string) == v2.Interface().(string) + case reflect.Struct: + return equalStruct(v1, v2) + case reflect.Uint32, reflect.Uint64: + return v1.Uint() == v2.Uint() + } + + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to compare %v", v1) + return false +} + +// base is the struct type that the extensions are based on. +// x1 and x2 are InternalExtensions. +func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { + em1, _ := x1.extensionsRead() + em2, _ := x2.extensionsRead() + return equalExtMap(base, em1, em2) +} + +func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { + if len(em1) != len(em2) { + return false + } + + for extNum, e1 := range em1 { + e2, ok := em2[extNum] + if !ok { + return false + } + + m1, m2 := e1.value, e2.value + + if m1 == nil && m2 == nil { + // Both have only encoded form. + if bytes.Equal(e1.enc, e2.enc) { + continue + } + // The bytes are different, but the extensions might still be + // equal. We need to decode them to compare. + } + + if m1 != nil && m2 != nil { + // Both are unencoded. + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + continue + } + + // At least one is encoded. To do a semantically correct comparison + // we need to unmarshal them first. + var desc *ExtensionDesc + if m := extensionMaps[base]; m != nil { + desc = m[extNum] + } + if desc == nil { + // If both have only encoded form and the bytes are the same, + // it is handled above. We get here when the bytes are different. + // We don't know how to decode it, so just compare them as byte + // slices. + log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) + return false + } + var err error + if m1 == nil { + m1, err = decodeExtension(e1.enc, desc) + } + if m2 == nil && err == nil { + m2, err = decodeExtension(e2.enc, desc) + } + if err != nil { + // The encoded form is invalid. + log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) + return false + } + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + } + + return true +} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go new file mode 100644 index 00000000..686bd2a0 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/extensions.go @@ -0,0 +1,604 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Types and routines for supporting protocol buffer extensions. + */ + +import ( + "errors" + "fmt" + "io" + "reflect" + "strconv" + "sync" +) + +// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. +var ErrMissingExtension = errors.New("proto: missing extension") + +// ExtensionRange represents a range of message extensions for a protocol buffer. +// Used in code generated by the protocol compiler. +type ExtensionRange struct { + Start, End int32 // both inclusive +} + +// extendableProto is an interface implemented by any protocol buffer generated by the current +// proto compiler that may be extended. +type extendableProto interface { + Message + ExtensionRangeArray() []ExtensionRange + extensionsWrite() map[int32]Extension + extensionsRead() (map[int32]Extension, sync.Locker) +} + +// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous +// version of the proto compiler that may be extended. +type extendableProtoV1 interface { + Message + ExtensionRangeArray() []ExtensionRange + ExtensionMap() map[int32]Extension +} + +// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. +type extensionAdapter struct { + extendableProtoV1 +} + +func (e extensionAdapter) extensionsWrite() map[int32]Extension { + return e.ExtensionMap() +} + +func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { + return e.ExtensionMap(), notLocker{} +} + +// notLocker is a sync.Locker whose Lock and Unlock methods are nops. +type notLocker struct{} + +func (n notLocker) Lock() {} +func (n notLocker) Unlock() {} + +// extendable returns the extendableProto interface for the given generated proto message. +// If the proto message has the old extension format, it returns a wrapper that implements +// the extendableProto interface. +func extendable(p interface{}) (extendableProto, error) { + switch p := p.(type) { + case extendableProto: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return p, nil + case extendableProtoV1: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return extensionAdapter{p}, nil + case extensionsBytes: + return slowExtensionAdapter{p}, nil + } + // Don't allocate a specific error containing %T: + // this is the hot path for Clone and MarshalText. + return nil, errNotExtendable +} + +var errNotExtendable = errors.New("proto: not an extendable proto.Message") + +func isNilPtr(x interface{}) bool { + v := reflect.ValueOf(x) + return v.Kind() == reflect.Ptr && v.IsNil() +} + +// XXX_InternalExtensions is an internal representation of proto extensions. +// +// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, +// thus gaining the unexported 'extensions' method, which can be called only from the proto package. +// +// The methods of XXX_InternalExtensions are not concurrency safe in general, +// but calls to logically read-only methods such as has and get may be executed concurrently. +type XXX_InternalExtensions struct { + // The struct must be indirect so that if a user inadvertently copies a + // generated message and its embedded XXX_InternalExtensions, they + // avoid the mayhem of a copied mutex. + // + // The mutex serializes all logically read-only operations to p.extensionMap. + // It is up to the client to ensure that write operations to p.extensionMap are + // mutually exclusive with other accesses. + p *struct { + mu sync.Mutex + extensionMap map[int32]Extension + } +} + +// extensionsWrite returns the extension map, creating it on first use. +func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { + if e.p == nil { + e.p = new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }) + e.p.extensionMap = make(map[int32]Extension) + } + return e.p.extensionMap +} + +// extensionsRead returns the extensions map for read-only use. It may be nil. +// The caller must hold the returned mutex's lock when accessing Elements within the map. +func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { + if e.p == nil { + return nil, nil + } + return e.p.extensionMap, &e.p.mu +} + +// ExtensionDesc represents an extension specification. +// Used in generated code from the protocol compiler. +type ExtensionDesc struct { + ExtendedType Message // nil pointer to the type that is being extended + ExtensionType interface{} // nil pointer to the extension type + Field int32 // field number + Name string // fully-qualified name of extension, for text formatting + Tag string // protobuf tag style + Filename string // name of the file in which the extension is defined +} + +func (ed *ExtensionDesc) repeated() bool { + t := reflect.TypeOf(ed.ExtensionType) + return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 +} + +// Extension represents an extension in a message. +type Extension struct { + // When an extension is stored in a message using SetExtension + // only desc and value are set. When the message is marshaled + // enc will be set to the encoded form of the message. + // + // When a message is unmarshaled and contains extensions, each + // extension will have only enc set. When such an extension is + // accessed using GetExtension (or GetExtensions) desc and value + // will be set. + desc *ExtensionDesc + value interface{} + enc []byte +} + +// SetRawExtension is for testing only. +func SetRawExtension(base Message, id int32, b []byte) { + if ebase, ok := base.(extensionsBytes); ok { + clearExtension(base, id) + ext := ebase.GetExtensions() + *ext = append(*ext, b...) + return + } + epb, err := extendable(base) + if err != nil { + return + } + extmap := epb.extensionsWrite() + extmap[id] = Extension{enc: b} +} + +// isExtensionField returns true iff the given field number is in an extension range. +func isExtensionField(pb extendableProto, field int32) bool { + for _, er := range pb.ExtensionRangeArray() { + if er.Start <= field && field <= er.End { + return true + } + } + return false +} + +// checkExtensionTypes checks that the given extension is valid for pb. +func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + var pbi interface{} = pb + // Check the extended type. + if ea, ok := pbi.(extensionAdapter); ok { + pbi = ea.extendableProtoV1 + } + if ea, ok := pbi.(slowExtensionAdapter); ok { + pbi = ea.extensionsBytes + } + if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { + return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) + } + // Check the range. + if !isExtensionField(pb, extension.Field) { + return errors.New("proto: bad extension number; not in declared ranges") + } + return nil +} + +// extPropKey is sufficient to uniquely identify an extension. +type extPropKey struct { + base reflect.Type + field int32 +} + +var extProp = struct { + sync.RWMutex + m map[extPropKey]*Properties +}{ + m: make(map[extPropKey]*Properties), +} + +func extensionProperties(ed *ExtensionDesc) *Properties { + key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} + + extProp.RLock() + if prop, ok := extProp.m[key]; ok { + extProp.RUnlock() + return prop + } + extProp.RUnlock() + + extProp.Lock() + defer extProp.Unlock() + // Check again. + if prop, ok := extProp.m[key]; ok { + return prop + } + + prop := new(Properties) + prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) + extProp.m[key] = prop + return prop +} + +// HasExtension returns whether the given extension is present in pb. +func HasExtension(pb Message, extension *ExtensionDesc) bool { + if epb, doki := pb.(extensionsBytes); doki { + ext := epb.GetExtensions() + buf := *ext + o := 0 + for o < len(buf) { + tag, n := DecodeVarint(buf[o:]) + fieldNum := int32(tag >> 3) + if int32(fieldNum) == extension.Field { + return true + } + wireType := int(tag & 0x7) + o += n + l, err := size(buf[o:], wireType) + if err != nil { + return false + } + o += l + } + return false + } + // TODO: Check types, field numbers, etc.? + epb, err := extendable(pb) + if err != nil { + return false + } + extmap, mu := epb.extensionsRead() + if extmap == nil { + return false + } + mu.Lock() + _, ok := extmap[extension.Field] + mu.Unlock() + return ok +} + +// ClearExtension removes the given extension from pb. +func ClearExtension(pb Message, extension *ExtensionDesc) { + clearExtension(pb, extension.Field) +} + +func clearExtension(pb Message, fieldNum int32) { + if epb, ok := pb.(extensionsBytes); ok { + offset := 0 + for offset != -1 { + offset = deleteExtension(epb, fieldNum, offset) + } + return + } + epb, err := extendable(pb) + if err != nil { + return + } + // TODO: Check types, field numbers, etc.? + extmap := epb.extensionsWrite() + delete(extmap, fieldNum) +} + +// GetExtension retrieves a proto2 extended field from pb. +// +// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), +// then GetExtension parses the encoded field and returns a Go value of the specified type. +// If the field is not present, then the default value is returned (if one is specified), +// otherwise ErrMissingExtension is reported. +// +// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), +// then GetExtension returns the raw encoded bytes of the field extension. +func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { + if epb, doki := pb.(extensionsBytes); doki { + ext := epb.GetExtensions() + return decodeExtensionFromBytes(extension, *ext) + } + + epb, err := extendable(pb) + if err != nil { + return nil, err + } + + if extension.ExtendedType != nil { + // can only check type if this is a complete descriptor + if cerr := checkExtensionTypes(epb, extension); cerr != nil { + return nil, cerr + } + } + + emap, mu := epb.extensionsRead() + if emap == nil { + return defaultExtensionValue(extension) + } + mu.Lock() + defer mu.Unlock() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return e.value, nil + } + + if extension.ExtensionType == nil { + // incomplete descriptor + return e.enc, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = v + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return e.value, nil +} + +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + if extension.ExtensionType == nil { + // incomplete descriptor, so no default + return nil, ErrMissingExtension + } + + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + +// decodeExtension decodes an extension encoded in b. +func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + unmarshal := typeUnmarshaler(t, extension.Tag) + + // t is a pointer to a struct, pointer to basic type or a slice. + // Allocate space to store the pointer/slice. + value := reflect.New(t).Elem() + + var err error + for { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + wire := int(x) & 7 + + b, err = unmarshal(b, valToPointer(value.Addr()), wire) + if err != nil { + return nil, err + } + + if len(b) == 0 { + break + } + } + return value.Interface(), nil +} + +// GetExtensions returns a slice of the extensions present in pb that are also listed in es. +// The returned slice has the same length as es; missing extensions will appear as nil elements. +func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + extensions = make([]interface{}, len(es)) + for i, e := range es { + extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } + if err != nil { + return + } + } + return +} + +// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. +// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing +// just the Field field, which defines the extension's field number. +func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + registeredExtensions := RegisteredExtensions(pb) + + emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } + mu.Lock() + defer mu.Unlock() + extensions := make([]*ExtensionDesc, 0, len(emap)) + for extid, e := range emap { + desc := e.desc + if desc == nil { + desc = registeredExtensions[extid] + if desc == nil { + desc = &ExtensionDesc{Field: extid} + } + } + + extensions = append(extensions, desc) + } + return extensions, nil +} + +// SetExtension sets the specified extension of pb to the specified value. +func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { + if epb, ok := pb.(extensionsBytes); ok { + newb, err := encodeExtension(extension, value) + if err != nil { + return err + } + bb := epb.GetExtensions() + *bb = append(*bb, newb...) + return nil + } + epb, err := extendable(pb) + if err != nil { + return err + } + if err := checkExtensionTypes(epb, extension); err != nil { + return err + } + typ := reflect.TypeOf(extension.ExtensionType) + if typ != reflect.TypeOf(value) { + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } + + extmap := epb.extensionsWrite() + extmap[extension.Field] = Extension{desc: extension, value: value} + return nil +} + +// ClearAllExtensions clears all extensions from pb. +func ClearAllExtensions(pb Message) { + if epb, doki := pb.(extensionsBytes); doki { + ext := epb.GetExtensions() + *ext = []byte{} + return + } + epb, err := extendable(pb) + if err != nil { + return + } + m := epb.extensionsWrite() + for k := range m { + delete(m, k) + } +} + +// A global registry of extensions. +// The generated code will register the generated descriptors by calling RegisterExtension. + +var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) + +// RegisterExtension is called from the generated code. +func RegisterExtension(desc *ExtensionDesc) { + st := reflect.TypeOf(desc.ExtendedType).Elem() + m := extensionMaps[st] + if m == nil { + m = make(map[int32]*ExtensionDesc) + extensionMaps[st] = m + } + if _, ok := m[desc.Field]; ok { + panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + } + m[desc.Field] = desc +} + +// RegisteredExtensions returns a map of the registered extensions of a +// protocol buffer struct, indexed by the extension number. +// The argument pb should be a nil pointer to the struct type. +func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { + return extensionMaps[reflect.TypeOf(pb).Elem()] +} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go new file mode 100644 index 00000000..53ebd8cc --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go @@ -0,0 +1,368 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "bytes" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strings" + "sync" +) + +type extensionsBytes interface { + Message + ExtensionRangeArray() []ExtensionRange + GetExtensions() *[]byte +} + +type slowExtensionAdapter struct { + extensionsBytes +} + +func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension { + panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.") +} + +func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { + b := s.GetExtensions() + m, err := BytesToExtensionsMap(*b) + if err != nil { + panic(err) + } + return m, notLocker{} +} + +func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool { + if reflect.ValueOf(pb).IsNil() { + return ifnotset + } + value, err := GetExtension(pb, extension) + if err != nil { + return ifnotset + } + if value == nil { + return ifnotset + } + if value.(*bool) == nil { + return ifnotset + } + return *(value.(*bool)) +} + +func (this *Extension) Equal(that *Extension) bool { + if err := this.Encode(); err != nil { + return false + } + if err := that.Encode(); err != nil { + return false + } + return bytes.Equal(this.enc, that.enc) +} + +func (this *Extension) Compare(that *Extension) int { + if err := this.Encode(); err != nil { + return 1 + } + if err := that.Encode(); err != nil { + return -1 + } + return bytes.Compare(this.enc, that.enc) +} + +func SizeOfInternalExtension(m extendableProto) (n int) { + info := getMarshalInfo(reflect.TypeOf(m)) + return info.sizeV1Extensions(m.extensionsWrite()) +} + +type sortableMapElem struct { + field int32 + ext Extension +} + +func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions { + s := make(sortableExtensions, 0, len(m)) + for k, v := range m { + s = append(s, &sortableMapElem{field: k, ext: v}) + } + return s +} + +type sortableExtensions []*sortableMapElem + +func (this sortableExtensions) Len() int { return len(this) } + +func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] } + +func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field } + +func (this sortableExtensions) String() string { + sort.Sort(this) + ss := make([]string, len(this)) + for i := range this { + ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext) + } + return "map[" + strings.Join(ss, ",") + "]" +} + +func StringFromInternalExtension(m extendableProto) string { + return StringFromExtensionsMap(m.extensionsWrite()) +} + +func StringFromExtensionsMap(m map[int32]Extension) string { + return newSortableExtensionsFromMap(m).String() +} + +func StringFromExtensionsBytes(ext []byte) string { + m, err := BytesToExtensionsMap(ext) + if err != nil { + panic(err) + } + return StringFromExtensionsMap(m) +} + +func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) { + return EncodeExtensionMap(m.extensionsWrite(), data) +} + +func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { + o := 0 + for _, e := range m { + if err := e.Encode(); err != nil { + return 0, err + } + n := copy(data[o:], e.enc) + if n != len(e.enc) { + return 0, io.ErrShortBuffer + } + o += n + } + return o, nil +} + +func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { + e := m[id] + if err := e.Encode(); err != nil { + return nil, err + } + return e.enc, nil +} + +func size(buf []byte, wire int) (int, error) { + switch wire { + case WireVarint: + _, n := DecodeVarint(buf) + return n, nil + case WireFixed64: + return 8, nil + case WireBytes: + v, n := DecodeVarint(buf) + return int(v) + n, nil + case WireFixed32: + return 4, nil + case WireStartGroup: + offset := 0 + for { + u, n := DecodeVarint(buf[offset:]) + fwire := int(u & 0x7) + offset += n + if fwire == WireEndGroup { + return offset, nil + } + s, err := size(buf[offset:], wire) + if err != nil { + return 0, err + } + offset += s + } + } + return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire) +} + +func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) { + m := make(map[int32]Extension) + i := 0 + for i < len(buf) { + tag, n := DecodeVarint(buf[i:]) + if n <= 0 { + return nil, fmt.Errorf("unable to decode varint") + } + fieldNum := int32(tag >> 3) + wireType := int(tag & 0x7) + l, err := size(buf[i+n:], wireType) + if err != nil { + return nil, err + } + end := i + int(l) + n + m[int32(fieldNum)] = Extension{enc: buf[i:end]} + i = end + } + return m, nil +} + +func NewExtension(e []byte) Extension { + ee := Extension{enc: make([]byte, len(e))} + copy(ee.enc, e) + return ee +} + +func AppendExtension(e Message, tag int32, buf []byte) { + if ee, eok := e.(extensionsBytes); eok { + ext := ee.GetExtensions() + *ext = append(*ext, buf...) + return + } + if ee, eok := e.(extendableProto); eok { + m := ee.extensionsWrite() + ext := m[int32(tag)] // may be missing + ext.enc = append(ext.enc, buf...) + m[int32(tag)] = ext + } +} + +func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) { + u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType)) + ei := u.getExtElemInfo(extension) + v := value + p := toAddrPointer(&v, ei.isptr) + siz := ei.sizer(p, SizeVarint(ei.wiretag)) + buf := make([]byte, 0, siz) + return ei.marshaler(buf, p, ei.wiretag, false) +} + +func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) { + o := 0 + for o < len(buf) { + tag, n := DecodeVarint((buf)[o:]) + fieldNum := int32(tag >> 3) + wireType := int(tag & 0x7) + if o+n > len(buf) { + return nil, fmt.Errorf("unable to decode extension") + } + l, err := size((buf)[o+n:], wireType) + if err != nil { + return nil, err + } + if int32(fieldNum) == extension.Field { + if o+n+l > len(buf) { + return nil, fmt.Errorf("unable to decode extension") + } + v, err := decodeExtension((buf)[o:o+n+l], extension) + if err != nil { + return nil, err + } + return v, nil + } + o += n + l + } + return defaultExtensionValue(extension) +} + +func (this *Extension) Encode() error { + if this.enc == nil { + var err error + this.enc, err = encodeExtension(this.desc, this.value) + if err != nil { + return err + } + } + return nil +} + +func (this Extension) GoString() string { + if err := this.Encode(); err != nil { + return fmt.Sprintf("error encoding extension: %v", err) + } + return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) +} + +func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error { + typ := reflect.TypeOf(pb).Elem() + ext, ok := extensionMaps[typ] + if !ok { + return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) + } + desc, ok := ext[fieldNum] + if !ok { + return errors.New("proto: bad extension number; not in declared ranges") + } + return SetExtension(pb, desc, value) +} + +func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) { + typ := reflect.TypeOf(pb).Elem() + ext, ok := extensionMaps[typ] + if !ok { + return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) + } + desc, ok := ext[fieldNum] + if !ok { + return nil, fmt.Errorf("unregistered field number %d", fieldNum) + } + return GetExtension(pb, desc) +} + +func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions { + x := &XXX_InternalExtensions{ + p: new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }), + } + x.p.extensionMap = m + return *x +} + +func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension { + pb := extendable.(extendableProto) + return pb.extensionsWrite() +} + +func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { + ext := pb.GetExtensions() + for offset < len(*ext) { + tag, n1 := DecodeVarint((*ext)[offset:]) + fieldNum := int32(tag >> 3) + wireType := int(tag & 0x7) + n2, err := size((*ext)[offset+n1:], wireType) + if err != nil { + panic(err) + } + newOffset := offset + n1 + n2 + if fieldNum == theFieldNum { + *ext = append((*ext)[:offset], (*ext)[newOffset:]...) + return offset + } + offset = newOffset + } + return -1 +} diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go new file mode 100644 index 00000000..d17f8020 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/lib.go @@ -0,0 +1,967 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Enum types do not get an Enum method. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/gogo/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err + } + *x = FOO(value) + return nil + } + + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" + } + + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type + } + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil + } + + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" + } + + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/gogo/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } + // etc. + } +*/ +package proto + +import ( + "encoding/json" + "fmt" + "log" + "reflect" + "sort" + "strconv" + "sync" +) + +// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. +// Marshal reports this when a required field is not initialized. +// Unmarshal reports this when a required field is missing from the wire data. +type RequiredNotSetError struct{ field string } + +func (e *RequiredNotSetError) Error() string { + if e.field == "" { + return fmt.Sprintf("proto: required field not set") + } + return fmt.Sprintf("proto: required field %q not set", e.field) +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +type invalidUTF8Error struct{ field string } + +func (e *invalidUTF8Error) Error() string { + if e.field == "" { + return "proto: invalid UTF-8 detected" + } + return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) +} +func (e *invalidUTF8Error) InvalidUTF8() bool { + return true +} + +// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. +// This error should not be exposed to the external API as such errors should +// be recreated with the field information. +var errInvalidUTF8 = &invalidUTF8Error{} + +// isNonFatal reports whether the error is either a RequiredNotSet error +// or a InvalidUTF8 error. +func isNonFatal(err error) bool { + if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { + return true + } + if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { + return true + } + return false +} + +type nonFatal struct{ E error } + +// Merge merges err into nf and reports whether it was successful. +// Otherwise it returns false for any fatal non-nil errors. +func (nf *nonFatal) Merge(err error) (ok bool) { + if err == nil { + return true // not an error + } + if !isNonFatal(err) { + return false // fatal error + } + if nf.E == nil { + nf.E = err // store first instance of non-fatal error + } + return true +} + +// Message is implemented by generated protocol buffer messages. +type Message interface { + Reset() + String() string + ProtoMessage() +} + +// A Buffer is a buffer manager for marshaling and unmarshaling +// protocol buffers. It may be reused between invocations to +// reduce memory usage. It is not necessary to use a Buffer; +// the global functions Marshal and Unmarshal create a +// temporary Buffer and are fine for most applications. +type Buffer struct { + buf []byte // encode/decode byte stream + index int // read point + + deterministic bool +} + +// NewBuffer allocates a new Buffer and initializes its internal data to +// the contents of the argument slice. +func NewBuffer(e []byte) *Buffer { + return &Buffer{buf: e} +} + +// Reset resets the Buffer, ready for marshaling a new protocol buffer. +func (p *Buffer) Reset() { + p.buf = p.buf[0:0] // for reading/writing + p.index = 0 // for reading +} + +// SetBuf replaces the internal buffer with the slice, +// ready for unmarshaling the contents of the slice. +func (p *Buffer) SetBuf(s []byte) { + p.buf = s + p.index = 0 +} + +// Bytes returns the contents of the Buffer. +func (p *Buffer) Bytes() []byte { return p.buf } + +// SetDeterministic sets whether to use deterministic serialization. +// +// Deterministic serialization guarantees that for a given binary, equal +// messages will always be serialized to the same bytes. This implies: +// +// - Repeated serialization of a message will return the same bytes. +// - Different processes of the same binary (which may be executing on +// different machines) will serialize equal messages to the same bytes. +// +// Note that the deterministic serialization is NOT canonical across +// languages. It is not guaranteed to remain stable over time. It is unstable +// across different builds with schema changes due to unknown fields. +// Users who need canonical serialization (e.g., persistent storage in a +// canonical form, fingerprinting, etc.) should define their own +// canonicalization specification and implement their own serializer rather +// than relying on this API. +// +// If deterministic serialization is requested, map entries will be sorted +// by keys in lexographical order. This is an implementation detail and +// subject to change. +func (p *Buffer) SetDeterministic(deterministic bool) { + p.deterministic = deterministic +} + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + return &v +} + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { + return &v +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int32 { + p := new(int32) + *p = int32(v) + return p +} + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { + return &v +} + +// Float32 is a helper routine that allocates a new float32 value +// to store v and returns a pointer to it. +func Float32(v float32) *float32 { + return &v +} + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { + return &v +} + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { + return &v +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + return &v +} + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// UnmarshalJSONEnum is a helper function to simplify recovering enum int values +// from their JSON-encoded representation. Given a map from the enum's symbolic +// names to its int values, and a byte buffer containing the JSON-encoded +// value, it returns an int32 that can be cast to the enum type by the caller. +// +// The function can deal with both JSON representations, numeric and symbolic. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// DebugPrint dumps the encoded data in b in a debugging format with a header +// including the string s. Used in testing but made available for general debugging. +func (p *Buffer) DebugPrint(s string, b []byte) { + var u uint64 + + obuf := p.buf + sindex := p.index + p.buf = b + p.index = 0 + depth := 0 + + fmt.Printf("\n--- %s ---\n", s) + +out: + for { + for i := 0; i < depth; i++ { + fmt.Print(" ") + } + + index := p.index + if index == len(p.buf) { + break + } + + op, err := p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: fetching op err %v\n", index, err) + break out + } + tag := op >> 3 + wire := op & 7 + + switch wire { + default: + fmt.Printf("%3d: t=%3d unknown wire=%d\n", + index, tag, wire) + break out + + case WireBytes: + var r []byte + + r, err = p.DecodeRawBytes(false) + if err != nil { + break out + } + fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) + if len(r) <= 6 { + for i := 0; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } else { + for i := 0; i < 3; i++ { + fmt.Printf(" %.2x", r[i]) + } + fmt.Printf(" ..") + for i := len(r) - 3; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } + fmt.Printf("\n") + + case WireFixed32: + u, err = p.DecodeFixed32() + if err != nil { + fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) + + case WireFixed64: + u, err = p.DecodeFixed64() + if err != nil { + fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) + + case WireVarint: + u, err = p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) + + case WireStartGroup: + fmt.Printf("%3d: t=%3d start\n", index, tag) + depth++ + + case WireEndGroup: + depth-- + fmt.Printf("%3d: t=%3d end\n", index, tag) + } + } + + if depth != 0 { + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) + } + fmt.Printf("\n") + + p.buf = obuf + p.index = sindex +} + +// SetDefaults sets unset protocol buffer fields to their default values. +// It only modifies fields that are both unset and have defined defaults. +// It recursively sets default values in any non-nil sub-messages. +func SetDefaults(pb Message) { + setDefaults(reflect.ValueOf(pb), true, false) +} + +// v is a struct. +func setDefaults(v reflect.Value, recur, zeros bool) { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + defaultMu.RLock() + dm, ok := defaults[v.Type()] + defaultMu.RUnlock() + if !ok { + dm = buildDefaultMessage(v.Type()) + defaultMu.Lock() + defaults[v.Type()] = dm + defaultMu.Unlock() + } + + for _, sf := range dm.scalars { + f := v.Field(sf.index) + if !f.IsNil() { + // field already set + continue + } + dv := sf.value + if dv == nil && !zeros { + // no explicit default, and don't want to set zeros + continue + } + fptr := f.Addr().Interface() // **T + // TODO: Consider batching the allocations we do here. + switch sf.kind { + case reflect.Bool: + b := new(bool) + if dv != nil { + *b = dv.(bool) + } + *(fptr.(**bool)) = b + case reflect.Float32: + f := new(float32) + if dv != nil { + *f = dv.(float32) + } + *(fptr.(**float32)) = f + case reflect.Float64: + f := new(float64) + if dv != nil { + *f = dv.(float64) + } + *(fptr.(**float64)) = f + case reflect.Int32: + // might be an enum + if ft := f.Type(); ft != int32PtrType { + // enum + f.Set(reflect.New(ft.Elem())) + if dv != nil { + f.Elem().SetInt(int64(dv.(int32))) + } + } else { + // int32 field + i := new(int32) + if dv != nil { + *i = dv.(int32) + } + *(fptr.(**int32)) = i + } + case reflect.Int64: + i := new(int64) + if dv != nil { + *i = dv.(int64) + } + *(fptr.(**int64)) = i + case reflect.String: + s := new(string) + if dv != nil { + *s = dv.(string) + } + *(fptr.(**string)) = s + case reflect.Uint8: + // exceptional case: []byte + var b []byte + if dv != nil { + db := dv.([]byte) + b = make([]byte, len(db)) + copy(b, db) + } else { + b = []byte{} + } + *(fptr.(*[]byte)) = b + case reflect.Uint32: + u := new(uint32) + if dv != nil { + *u = dv.(uint32) + } + *(fptr.(**uint32)) = u + case reflect.Uint64: + u := new(uint64) + if dv != nil { + *u = dv.(uint64) + } + *(fptr.(**uint64)) = u + default: + log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) + } + } + + for _, ni := range dm.nested { + f := v.Field(ni) + // f is *T or T or []*T or []T + switch f.Kind() { + case reflect.Struct: + setDefaults(f, recur, zeros) + + case reflect.Ptr: + if f.IsNil() { + continue + } + setDefaults(f, recur, zeros) + + case reflect.Slice: + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.Kind() == reflect.Ptr && e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + } + } +} + +var ( + // defaults maps a protocol buffer struct type to a slice of the fields, + // with its scalar fields set to their proto-declared non-zero default values. + defaultMu sync.RWMutex + defaults = make(map[reflect.Type]defaultMessage) + + int32PtrType = reflect.TypeOf((*int32)(nil)) +) + +// defaultMessage represents information about the default values of a message. +type defaultMessage struct { + scalars []scalarField + nested []int // struct field index of nested messages +} + +type scalarField struct { + index int // struct field index + kind reflect.Kind // element type (the T in *T or []T) + value interface{} // the proto-declared default value, or nil +} + +// t is a struct type. +func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { + sprop := GetProperties(t) + for _, prop := range sprop.Prop { + fi, ok := sprop.decoderTags.get(prop.Tag) + if !ok { + // XXX_unrecognized + continue + } + ft := t.Field(fi).Type + + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: + dm.nested = append(dm.nested, fi) + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) + } + } + + return dm +} + +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Struct: + nestedMessage = true // non-nullable + + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr, reflect.Struct: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// mapKeys returns a sort.Interface to be used for sorting the map keys. +// Map fields may have key types of non-float scalars, strings and enums. +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{vs: vs} + + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + case reflect.Bool: + s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true + case reflect.String: + s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } + default: + panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) + } + + return s +} + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +// ProtoPackageIsVersion2 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const GoGoProtoPackageIsVersion2 = true + +// ProtoPackageIsVersion1 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const GoGoProtoPackageIsVersion1 = true + +// InternalMessageInfo is a type used internally by generated .pb.go files. +// This type is not intended to be used by non-generated code. +// This type is not subject to any compatibility guarantee. +type InternalMessageInfo struct { + marshal *marshalInfo + unmarshal *unmarshalInfo + merge *mergeInfo + discard *discardInfo +} diff --git a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go new file mode 100644 index 00000000..b3aa3919 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go @@ -0,0 +1,50 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "encoding/json" + "strconv" +) + +type Sizer interface { + Size() int +} + +type ProtoSizer interface { + ProtoSize() int +} + +func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { + s, ok := m[value] + if !ok { + s = strconv.Itoa(int(value)) + } + return json.Marshal(s) +} diff --git a/vendor/github.com/gogo/protobuf/proto/message_set.go b/vendor/github.com/gogo/protobuf/proto/message_set.go new file mode 100644 index 00000000..f48a7567 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/message_set.go @@ -0,0 +1,181 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Support for message sets. + */ + +import ( + "errors" +) + +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. +// A message type ID is required for storing a protocol buffer in a message set. +var errNoMessageTypeID = errors.New("proto does not have a message type ID") + +// The first two types (_MessageSet_Item and messageSet) +// model what the protocol compiler produces for the following protocol message: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } +// That is the MessageSet wire format. We can't use a proto to generate these +// because that would introduce a circular dependency between it and this package. + +type _MessageSet_Item struct { + TypeId *int32 `protobuf:"varint,2,req,name=type_id"` + Message []byte `protobuf:"bytes,3,req,name=message"` +} + +type messageSet struct { + Item []*_MessageSet_Item `protobuf:"group,1,rep"` + XXX_unrecognized []byte + // TODO: caching? +} + +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) + +// messageTypeIder is an interface satisfied by a protocol buffer type +// that may be stored in a MessageSet. +type messageTypeIder interface { + MessageTypeId() int32 +} + +func (ms *messageSet) find(pb Message) *_MessageSet_Item { + mti, ok := pb.(messageTypeIder) + if !ok { + return nil + } + id := mti.MessageTypeId() + for _, item := range ms.Item { + if *item.TypeId == id { + return item + } + } + return nil +} + +func (ms *messageSet) Has(pb Message) bool { + return ms.find(pb) != nil +} + +func (ms *messageSet) Unmarshal(pb Message) error { + if item := ms.find(pb); item != nil { + return Unmarshal(item.Message, pb) + } + if _, ok := pb.(messageTypeIder); !ok { + return errNoMessageTypeID + } + return nil // TODO: return error instead? +} + +func (ms *messageSet) Marshal(pb Message) error { + msg, err := Marshal(pb) + if err != nil { + return err + } + if item := ms.find(pb); item != nil { + // reuse existing item + item.Message = msg + return nil + } + + mti, ok := pb.(messageTypeIder) + if !ok { + return errNoMessageTypeID + } + + mtid := mti.MessageTypeId() + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: &mtid, + Message: msg, + }) + return nil +} + +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} + +// Support for the message_set_wire_format message option. + +func skipVarint(buf []byte) []byte { + i := 0 + for ; buf[i]&0x80 != 0; i++ { + } + return buf[i+1:] +} + +// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. +func unmarshalMessageSet(buf []byte, exts interface{}) error { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + m = exts.extensionsWrite() + case map[int32]Extension: + m = exts + default: + return errors.New("proto: not an extension map") + } + + ms := new(messageSet) + if err := Unmarshal(buf, ms); err != nil { + return err + } + for _, item := range ms.Item { + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) + + m[id] = Extension{enc: b} + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go new file mode 100644 index 00000000..b6cad908 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go @@ -0,0 +1,357 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 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. + +// +build purego appengine js + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "reflect" + "sync" +) + +const unsafeAllowed = false + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by the sequence of field indices +// passed to reflect's FieldByIndex. +type field []int + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return f.Index +} + +// invalidField is an invalid field identifier. +var invalidField = field(nil) + +// zeroField is a noop when calling pointer.offset. +var zeroField = field([]int{}) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { return f != nil } + +// The pointer type is for the table-driven decoder. +// The implementation here uses a reflect.Value of pointer type to +// create a generic pointer. In pointer_unsafe.go we use unsafe +// instead of reflect to implement the same (but faster) interface. +type pointer struct { + v reflect.Value +} + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + return pointer{v: reflect.ValueOf(*i)} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr bool) pointer { + v := reflect.ValueOf(*i) + u := reflect.New(v.Type()) + u.Elem().Set(v) + return pointer{v: u} +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{v: v} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} +} + +func (p pointer) isNil() bool { + return p.v.IsNil() +} + +// grow updates the slice s in place to make it one element longer. +// s must be addressable. +// Returns the (addressable) new element. +func grow(s reflect.Value) reflect.Value { + n, m := s.Len(), s.Cap() + if n < m { + s.SetLen(n + 1) + } else { + s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) + } + return s.Index(n) +} + +func (p pointer) toInt64() *int64 { + return p.v.Interface().(*int64) +} +func (p pointer) toInt64Ptr() **int64 { + return p.v.Interface().(**int64) +} +func (p pointer) toInt64Slice() *[]int64 { + return p.v.Interface().(*[]int64) +} + +var int32ptr = reflect.TypeOf((*int32)(nil)) + +func (p pointer) toInt32() *int32 { + return p.v.Convert(int32ptr).Interface().(*int32) +} + +// The toInt32Ptr/Slice methods don't work because of enums. +// Instead, we must use set/get methods for the int32ptr/slice case. +/* + func (p pointer) toInt32Ptr() **int32 { + return p.v.Interface().(**int32) +} + func (p pointer) toInt32Slice() *[]int32 { + return p.v.Interface().(*[]int32) +} +*/ +func (p pointer) getInt32Ptr() *int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().(*int32) + } + // an enum + return p.v.Elem().Convert(int32PtrType).Interface().(*int32) +} +func (p pointer) setInt32Ptr(v int32) { + // Allocate value in a *int32. Possibly convert that to a *enum. + // Then assign it to a **int32 or **enum. + // Note: we can convert *int32 to *enum, but we can't convert + // **int32 to **enum! + p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) +} + +// getInt32Slice copies []int32 from p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getInt32Slice() []int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().([]int32) + } + // an enum + // Allocate a []int32, then assign []enum's values into it. + // Note: we can't convert []enum to []int32. + slice := p.v.Elem() + s := make([]int32, slice.Len()) + for i := 0; i < slice.Len(); i++ { + s[i] = int32(slice.Index(i).Int()) + } + return s +} + +// setInt32Slice copies []int32 into p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setInt32Slice(v []int32) { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + p.v.Elem().Set(reflect.ValueOf(v)) + return + } + // an enum + // Allocate a []enum, then assign []int32's values into it. + // Note: we can't convert []enum to []int32. + slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) + for i, x := range v { + slice.Index(i).SetInt(int64(x)) + } + p.v.Elem().Set(slice) +} +func (p pointer) appendInt32Slice(v int32) { + grow(p.v.Elem()).SetInt(int64(v)) +} + +func (p pointer) toUint64() *uint64 { + return p.v.Interface().(*uint64) +} +func (p pointer) toUint64Ptr() **uint64 { + return p.v.Interface().(**uint64) +} +func (p pointer) toUint64Slice() *[]uint64 { + return p.v.Interface().(*[]uint64) +} +func (p pointer) toUint32() *uint32 { + return p.v.Interface().(*uint32) +} +func (p pointer) toUint32Ptr() **uint32 { + return p.v.Interface().(**uint32) +} +func (p pointer) toUint32Slice() *[]uint32 { + return p.v.Interface().(*[]uint32) +} +func (p pointer) toBool() *bool { + return p.v.Interface().(*bool) +} +func (p pointer) toBoolPtr() **bool { + return p.v.Interface().(**bool) +} +func (p pointer) toBoolSlice() *[]bool { + return p.v.Interface().(*[]bool) +} +func (p pointer) toFloat64() *float64 { + return p.v.Interface().(*float64) +} +func (p pointer) toFloat64Ptr() **float64 { + return p.v.Interface().(**float64) +} +func (p pointer) toFloat64Slice() *[]float64 { + return p.v.Interface().(*[]float64) +} +func (p pointer) toFloat32() *float32 { + return p.v.Interface().(*float32) +} +func (p pointer) toFloat32Ptr() **float32 { + return p.v.Interface().(**float32) +} +func (p pointer) toFloat32Slice() *[]float32 { + return p.v.Interface().(*[]float32) +} +func (p pointer) toString() *string { + return p.v.Interface().(*string) +} +func (p pointer) toStringPtr() **string { + return p.v.Interface().(**string) +} +func (p pointer) toStringSlice() *[]string { + return p.v.Interface().(*[]string) +} +func (p pointer) toBytes() *[]byte { + return p.v.Interface().(*[]byte) +} +func (p pointer) toBytesSlice() *[][]byte { + return p.v.Interface().(*[][]byte) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return p.v.Interface().(*XXX_InternalExtensions) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return p.v.Interface().(*map[int32]Extension) +} +func (p pointer) getPointer() pointer { + return pointer{v: p.v.Elem()} +} +func (p pointer) setPointer(q pointer) { + p.v.Elem().Set(q.v) +} +func (p pointer) appendPointer(q pointer) { + grow(p.v.Elem()).Set(q.v) +} + +// getPointerSlice copies []*T from p as a new []pointer. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getPointerSlice() []pointer { + if p.v.IsNil() { + return nil + } + n := p.v.Elem().Len() + s := make([]pointer, n) + for i := 0; i < n; i++ { + s[i] = pointer{v: p.v.Elem().Index(i)} + } + return s +} + +// setPointerSlice copies []pointer into p as a new []*T. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setPointerSlice(v []pointer) { + if v == nil { + p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) + return + } + s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) + for _, p := range v { + s = reflect.Append(s, p.v) + } + p.v.Elem().Set(s) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + if p.v.Elem().IsNil() { + return pointer{v: p.v.Elem()} + } + return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct +} + +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + // TODO: check that p.v.Type().Elem() == t? + return p.v +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} + +var atomicLock sync.Mutex diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go new file mode 100644 index 00000000..7ffd3c29 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go @@ -0,0 +1,59 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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. + +// +build purego appengine js + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "reflect" +) + +// TODO: untested, so probably incorrect. + +func (p pointer) getRef() pointer { + return pointer{v: p.v.Addr()} +} + +func (p pointer) appendRef(v pointer, typ reflect.Type) { + slice := p.getSlice(typ) + elem := v.asPointerTo(typ).Elem() + newSlice := reflect.Append(slice, elem) + slice.Set(newSlice) +} + +func (p pointer) getSlice(typ reflect.Type) reflect.Value { + sliceTyp := reflect.SliceOf(typ) + slice := p.asPointerTo(sliceTyp) + slice = slice.Elem() + return slice +} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go new file mode 100644 index 00000000..d55a335d --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go @@ -0,0 +1,308 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 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. + +// +build !purego,!appengine,!js + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "sync/atomic" + "unsafe" +) + +const unsafeAllowed = true + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by its byte offset from the start of the struct. +type field uintptr + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return field(f.Offset) +} + +// invalidField is an invalid field identifier. +const invalidField = ^field(0) + +// zeroField is a noop when calling pointer.offset. +const zeroField = field(0) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { + return f != invalidField +} + +// The pointer type below is for the new table-driven encoder/decoder. +// The implementation here uses unsafe.Pointer to create a generic pointer. +// In pointer_reflect.go we use reflect instead of unsafe to implement +// the same (but slower) interface. +type pointer struct { + p unsafe.Pointer +} + +// size of pointer +var ptrSize = unsafe.Sizeof(uintptr(0)) + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + // Super-tricky - read pointer out of data word of interface value. + // Saves ~25ns over the equivalent: + // return valToPointer(reflect.ValueOf(*i)) + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr bool) pointer { + // Super-tricky - read or get the address of data word of interface value. + if isptr { + // The interface is of pointer type, thus it is a direct interface. + // The data word is the pointer data itself. We take its address. + return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + } + // The interface is not of pointer type. The data word is the pointer + // to the data. + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{p: unsafe.Pointer(v.Pointer())} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + // For safety, we should panic if !f.IsValid, however calling panic causes + // this to no longer be inlineable, which is a serious performance cost. + /* + if !f.IsValid() { + panic("invalid field") + } + */ + return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} +} + +func (p pointer) isNil() bool { + return p.p == nil +} + +func (p pointer) toInt64() *int64 { + return (*int64)(p.p) +} +func (p pointer) toInt64Ptr() **int64 { + return (**int64)(p.p) +} +func (p pointer) toInt64Slice() *[]int64 { + return (*[]int64)(p.p) +} +func (p pointer) toInt32() *int32 { + return (*int32)(p.p) +} + +// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. +/* + func (p pointer) toInt32Ptr() **int32 { + return (**int32)(p.p) + } + func (p pointer) toInt32Slice() *[]int32 { + return (*[]int32)(p.p) + } +*/ +func (p pointer) getInt32Ptr() *int32 { + return *(**int32)(p.p) +} +func (p pointer) setInt32Ptr(v int32) { + *(**int32)(p.p) = &v +} + +// getInt32Slice loads a []int32 from p. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getInt32Slice() []int32 { + return *(*[]int32)(p.p) +} + +// setInt32Slice stores a []int32 to p. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setInt32Slice(v []int32) { + *(*[]int32)(p.p) = v +} + +// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? +func (p pointer) appendInt32Slice(v int32) { + s := (*[]int32)(p.p) + *s = append(*s, v) +} + +func (p pointer) toUint64() *uint64 { + return (*uint64)(p.p) +} +func (p pointer) toUint64Ptr() **uint64 { + return (**uint64)(p.p) +} +func (p pointer) toUint64Slice() *[]uint64 { + return (*[]uint64)(p.p) +} +func (p pointer) toUint32() *uint32 { + return (*uint32)(p.p) +} +func (p pointer) toUint32Ptr() **uint32 { + return (**uint32)(p.p) +} +func (p pointer) toUint32Slice() *[]uint32 { + return (*[]uint32)(p.p) +} +func (p pointer) toBool() *bool { + return (*bool)(p.p) +} +func (p pointer) toBoolPtr() **bool { + return (**bool)(p.p) +} +func (p pointer) toBoolSlice() *[]bool { + return (*[]bool)(p.p) +} +func (p pointer) toFloat64() *float64 { + return (*float64)(p.p) +} +func (p pointer) toFloat64Ptr() **float64 { + return (**float64)(p.p) +} +func (p pointer) toFloat64Slice() *[]float64 { + return (*[]float64)(p.p) +} +func (p pointer) toFloat32() *float32 { + return (*float32)(p.p) +} +func (p pointer) toFloat32Ptr() **float32 { + return (**float32)(p.p) +} +func (p pointer) toFloat32Slice() *[]float32 { + return (*[]float32)(p.p) +} +func (p pointer) toString() *string { + return (*string)(p.p) +} +func (p pointer) toStringPtr() **string { + return (**string)(p.p) +} +func (p pointer) toStringSlice() *[]string { + return (*[]string)(p.p) +} +func (p pointer) toBytes() *[]byte { + return (*[]byte)(p.p) +} +func (p pointer) toBytesSlice() *[][]byte { + return (*[][]byte)(p.p) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return (*XXX_InternalExtensions)(p.p) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return (*map[int32]Extension)(p.p) +} + +// getPointerSlice loads []*T from p as a []pointer. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getPointerSlice() []pointer { + // Super-tricky - p should point to a []*T where T is a + // message type. We load it as []pointer. + return *(*[]pointer)(p.p) +} + +// setPointerSlice stores []pointer into p as a []*T. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setPointerSlice(v []pointer) { + // Super-tricky - p should point to a []*T where T is a + // message type. We store it as []pointer. + *(*[]pointer)(p.p) = v +} + +// getPointer loads the pointer at p and returns it. +func (p pointer) getPointer() pointer { + return pointer{p: *(*unsafe.Pointer)(p.p)} +} + +// setPointer stores the pointer q at p. +func (p pointer) setPointer(q pointer) { + *(*unsafe.Pointer)(p.p) = q.p +} + +// append q to the slice pointed to by p. +func (p pointer) appendPointer(q pointer) { + s := (*[]unsafe.Pointer)(p.p) + *s = append(*s, q.p) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + // Super-tricky - read pointer out of data word of interface value. + return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} +} + +// asPointerTo returns a reflect.Value that is a pointer to an +// object of type t stored at p. +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + return reflect.NewAt(t, p.p) +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go new file mode 100644 index 00000000..aca8eed0 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go @@ -0,0 +1,56 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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. + +// +build !purego,!appengine,!js + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "unsafe" +) + +func (p pointer) getRef() pointer { + return pointer{p: (unsafe.Pointer)(&p.p)} +} + +func (p pointer) appendRef(v pointer, typ reflect.Type) { + slice := p.getSlice(typ) + elem := v.asPointerTo(typ).Elem() + newSlice := reflect.Append(slice, elem) + slice.Set(newSlice) +} + +func (p pointer) getSlice(typ reflect.Type) reflect.Value { + sliceTyp := reflect.SliceOf(typ) + slice := p.asPointerTo(sliceTyp) + slice = slice.Elem() + return slice +} diff --git a/vendor/github.com/gogo/protobuf/proto/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go new file mode 100644 index 00000000..c9e5fa02 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/properties.go @@ -0,0 +1,599 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" +) + +const debug bool = false + +// Constants that identify the encoding of a value on the wire. +const ( + WireVarint = 0 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 + WireFixed32 = 5 +) + +// tagMap is an optimization over map[int]int for typical protocol buffer +// use-cases. Encoded protocol buffers are often in tag order with small tag +// numbers. +type tagMap struct { + fastTags []int + slowTags map[int]int +} + +// tagMapFastLimit is the upper bound on the tag number that will be stored in +// the tagMap slice rather than its map. +const tagMapFastLimit = 1024 + +func (p *tagMap) get(t int) (int, bool) { + if t > 0 && t < tagMapFastLimit { + if t >= len(p.fastTags) { + return 0, false + } + fi := p.fastTags[t] + return fi, fi >= 0 + } + fi, ok := p.slowTags[t] + return fi, ok +} + +func (p *tagMap) put(t int, fi int) { + if t > 0 && t < tagMapFastLimit { + for len(p.fastTags) < t+1 { + p.fastTags = append(p.fastTags, -1) + } + p.fastTags[t] = fi + return + } + if p.slowTags == nil { + p.slowTags = make(map[int]int) + } + p.slowTags[t] = fi +} + +// StructProperties represents properties for all the fields of a struct. +// decoderTags and decoderOrigNames should only be used by the decoder. +type StructProperties struct { + Prop []*Properties // properties for each field + reqCount int // required count + decoderTags tagMap // map from proto tag to struct field number + decoderOrigNames map[string]int // map from original name to struct field number + order []int // list of struct field numbers in tag order + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties +} + +// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. +// See encode.go, (*Buffer).enc_struct. + +func (sp *StructProperties) Len() int { return len(sp.order) } +func (sp *StructProperties) Less(i, j int) bool { + return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag +} +func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } + +// Properties represents the protocol-specific behavior of a single struct field. +type Properties struct { + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field + oneof bool // whether this is a oneof field + + Default string // default value + HasDefault bool // whether an explicit default was provided + CustomType string + CastType string + StdTime bool + StdDuration bool + WktPointer bool + + stype reflect.Type // set for struct types only + ctype reflect.Type // set for custom types only + sprop *StructProperties // set for struct types only + + mtype reflect.Type // set for map types only + MapKeyProp *Properties // set for map types only + MapValProp *Properties // set for map types only +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s += "," + s += strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName + } + if p.proto3 { + s += ",proto3" + } + if p.oneof { + s += ",oneof" + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(s string) { + // "bytes,49,opt,name=foo,def=hello!" + fields := strings.Split(s, ",") // breaks def=, but handled below. + if len(fields) < 2 { + fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) + return + } + + p.Wire = fields[0] + switch p.Wire { + case "varint": + p.WireType = WireVarint + case "fixed32": + p.WireType = WireFixed32 + case "fixed64": + p.WireType = WireFixed64 + case "zigzag32": + p.WireType = WireVarint + case "zigzag64": + p.WireType = WireVarint + case "bytes", "group": + p.WireType = WireBytes + // no numeric converter for non-numeric types + default: + fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) + return + } + + var err error + p.Tag, err = strconv.Atoi(fields[1]) + if err != nil { + return + } + +outer: + for i := 2; i < len(fields); i++ { + f := fields[i] + switch { + case f == "req": + p.Required = true + case f == "opt": + p.Optional = true + case f == "rep": + p.Repeated = true + case f == "packed": + p.Packed = true + case strings.HasPrefix(f, "name="): + p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] + case strings.HasPrefix(f, "enum="): + p.Enum = f[5:] + case f == "proto3": + p.proto3 = true + case f == "oneof": + p.oneof = true + case strings.HasPrefix(f, "def="): + p.HasDefault = true + p.Default = f[4:] // rest of string + if i+1 < len(fields) { + // Commas aren't escaped, and def is always last. + p.Default += "," + strings.Join(fields[i+1:], ",") + break outer + } + case strings.HasPrefix(f, "embedded="): + p.OrigName = strings.Split(f, "=")[1] + case strings.HasPrefix(f, "customtype="): + p.CustomType = strings.Split(f, "=")[1] + case strings.HasPrefix(f, "casttype="): + p.CastType = strings.Split(f, "=")[1] + case f == "stdtime": + p.StdTime = true + case f == "stdduration": + p.StdDuration = true + case f == "wktptr": + p.WktPointer = true + } + } +} + +var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() + +// setFieldProps initializes the field properties for submessages and maps. +func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { + isMap := typ.Kind() == reflect.Map + if len(p.CustomType) > 0 && !isMap { + p.ctype = typ + p.setTag(lockGetProp) + return + } + if p.StdTime && !isMap { + p.setTag(lockGetProp) + return + } + if p.StdDuration && !isMap { + p.setTag(lockGetProp) + return + } + if p.WktPointer && !isMap { + p.setTag(lockGetProp) + return + } + switch t1 := typ; t1.Kind() { + case reflect.Struct: + p.stype = typ + case reflect.Ptr: + if t1.Elem().Kind() == reflect.Struct { + p.stype = t1.Elem() + } + case reflect.Slice: + switch t2 := t1.Elem(); t2.Kind() { + case reflect.Ptr: + switch t3 := t2.Elem(); t3.Kind() { + case reflect.Struct: + p.stype = t3 + } + case reflect.Struct: + p.stype = t2 + } + + case reflect.Map: + + p.mtype = t1 + p.MapKeyProp = &Properties{} + p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.MapValProp = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + + p.MapValProp.CustomType = p.CustomType + p.MapValProp.StdDuration = p.StdDuration + p.MapValProp.StdTime = p.StdTime + p.MapValProp.WktPointer = p.WktPointer + p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + } + p.setTag(lockGetProp) +} + +func (p *Properties) setTag(lockGetProp bool) { + if p.stype != nil { + if lockGetProp { + p.sprop = GetProperties(p.stype) + } else { + p.sprop = getPropertiesLocked(p.stype) + } + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() +) + +// Init populates the properties from a protocol buffer struct tag. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.init(typ, name, tag, f, true) +} + +func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { + // "bytes,49,opt,def=hello!" + p.Name = name + p.OrigName = name + if tag == "" { + return + } + p.Parse(tag) + p.setFieldProps(typ, f, lockGetProp) +} + +var ( + propertiesMu sync.RWMutex + propertiesMap = make(map[reflect.Type]*StructProperties) +) + +// GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. +func GetProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() + return sprop +} + +// getPropertiesLocked requires that propertiesMu is held. +func getPropertiesLocked(t reflect.Type) *StructProperties { + if prop, ok := propertiesMap[t]; ok { + return prop + } + + prop := new(StructProperties) + // in case of recursive protos, fill this in now. + propertiesMap[t] = prop + + // build properties + prop.Prop = make([]*Properties, t.NumField()) + prop.order = make([]int, t.NumField()) + + isOneofMessage := false + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + p := new(Properties) + name := f.Name + p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + + oneof := f.Tag.Get("protobuf_oneof") // special case + if oneof != "" { + isOneofMessage = true + // Oneof fields don't use the traditional protobuf tag. + p.OrigName = oneof + } + prop.Prop[i] = p + prop.order[i] = i + if debug { + print(i, " ", f.Name, " ", t.String(), " ") + if p.Tag > 0 { + print(p.String()) + } + print("\n") + } + } + + // Re-order prop.order. + sort.Sort(prop) + + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok { + var oots []interface{} + _, _, _, oots = om.XXX_OneofFuncs() + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + + // build required counts + // build tags + reqCount := 0 + prop.decoderOrigNames = make(map[string]int) + for i, p := range prop.Prop { + if strings.HasPrefix(p.Name, "XXX_") { + // Internal fields should not appear in tags/origNames maps. + // They are handled specially when encoding and decoding. + continue + } + if p.Required { + reqCount++ + } + prop.decoderTags.put(p.Tag, i) + prop.decoderOrigNames[p.OrigName] = i + } + prop.reqCount = reqCount + + return prop +} + +// A global registry of enum types. +// The generated code will register the generated maps by calling RegisterEnum. + +var enumValueMaps = make(map[string]map[string]int32) +var enumStringMaps = make(map[string]map[int32]string) + +// RegisterEnum is called from the generated code to install the enum descriptor +// maps into the global table to aid parsing text format protocol buffers. +func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { + if _, ok := enumValueMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumValueMaps[typeName] = valueMap + if _, ok := enumStringMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumStringMaps[typeName] = unusedNameMap +} + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers + protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypedNils[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { + // Generated code always calls RegisterType with nil x. + // This check is just for extra safety. + protoTypedNils[name] = x + } else { + protoTypedNils[name] = reflect.Zero(t).Interface().(Message) + } + revProtoTypes[t] = name +} + +// RegisterMapType is called from generated code and maps from the fully qualified +// proto name to the native map type of the proto map definition. +func RegisterMapType(x interface{}, name string) { + if reflect.TypeOf(x).Kind() != reflect.Map { + panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) + } + if _, ok := protoMapTypes[name]; ok { + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoMapTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} + +// MessageType returns the message type (pointer to struct) for a named message. +// The type is not guaranteed to implement proto.Message if the name refers to a +// map entry. +func MessageType(name string) reflect.Type { + if t, ok := protoTypedNils[name]; ok { + return reflect.TypeOf(t) + } + return protoMapTypes[name] +} + +// A registry of all linked proto files. +var ( + protoFiles = make(map[string][]byte) // file name => fileDescriptor +) + +// RegisterFile is called from generated code and maps from the +// full file name of a .proto file to its compressed FileDescriptorProto. +func RegisterFile(filename string, fileDescriptor []byte) { + protoFiles[filename] = fileDescriptor +} + +// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. +func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go new file mode 100644 index 00000000..40ea3dd9 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go @@ -0,0 +1,36 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "reflect" +) + +var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem() +var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go new file mode 100644 index 00000000..5a5fd93f --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go @@ -0,0 +1,119 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "fmt" + "io" +) + +func Skip(data []byte) (n int, err error) { + l := len(data) + index := 0 + for index < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if index >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[index] + index++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for { + if index >= l { + return 0, io.ErrUnexpectedEOF + } + index++ + if data[index-1] < 0x80 { + break + } + } + return index, nil + case 1: + index += 8 + return index, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if index >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[index] + index++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + index += length + return index, nil + case 3: + for { + var innerWire uint64 + var start int = index + for shift := uint(0); ; shift += 7 { + if index >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[index] + index++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := Skip(data[start:]) + if err != nil { + return 0, err + } + index = start + next + } + return index, nil + case 4: + return index, nil + case 5: + index += 4 + return index, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal.go b/vendor/github.com/gogo/protobuf/proto/table_marshal.go new file mode 100644 index 00000000..9b1538d0 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/table_marshal.go @@ -0,0 +1,3006 @@ +// 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 proto + +import ( + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// a sizer takes a pointer to a field and the size of its tag, computes the size of +// the encoded data. +type sizer func(pointer, int) int + +// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), +// marshals the field to the end of the slice, returns the slice and error (if any). +type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) + +// marshalInfo is the information used for marshaling a message. +type marshalInfo struct { + typ reflect.Type + fields []*marshalFieldInfo + unrecognized field // offset of XXX_unrecognized + extensions field // offset of XXX_InternalExtensions + v1extensions field // offset of XXX_extensions + sizecache field // offset of XXX_sizecache + initialized int32 // 0 -- only typ is set, 1 -- fully initialized + messageset bool // uses message set wire format + hasmarshaler bool // has custom marshaler + sync.RWMutex // protect extElems map, also for initialization + extElems map[int32]*marshalElemInfo // info of extension elements + + hassizer bool // has custom sizer + hasprotosizer bool // has custom protosizer + + bytesExtensions field // offset of XXX_extensions where the field type is []byte +} + +// marshalFieldInfo is the information used for marshaling a field of a message. +type marshalFieldInfo struct { + field field + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isPointer bool + required bool // field is required + name string // name of the field, for error reporting + oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements +} + +// marshalElemInfo is the information used for marshaling an extension or oneof element. +type marshalElemInfo struct { + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) +} + +var ( + marshalInfoMap = map[reflect.Type]*marshalInfo{} + marshalInfoLock sync.Mutex + + uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind() +) + +// getMarshalInfo returns the information to marshal a given type of message. +// The info it returns may not necessarily initialized. +// t is the type of the message (NOT the pointer to it). +func getMarshalInfo(t reflect.Type) *marshalInfo { + marshalInfoLock.Lock() + u, ok := marshalInfoMap[t] + if !ok { + u = &marshalInfo{typ: t} + marshalInfoMap[t] = u + } + marshalInfoLock.Unlock() + return u +} + +// Size is the entry point from generated code, +// and should be ONLY called by generated code. +// It computes the size of encoded data of msg. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Size(msg Message) int { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return 0 + } + return u.size(ptr) +} + +// Marshal is the entry point from generated code, +// and should be ONLY called by generated code. +// It marshals msg to the end of b. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return b, ErrNil + } + return u.marshal(b, ptr, deterministic) +} + +func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { + // u := a.marshal, but atomically. + // We use an atomic here to ensure memory consistency. + u := atomicLoadMarshalInfo(&a.marshal) + if u == nil { + // Get marshal information from type of message. + t := reflect.ValueOf(msg).Type() + if t.Kind() != reflect.Ptr { + panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) + } + u = getMarshalInfo(t.Elem()) + // Store it in the cache for later users. + // a.marshal = u, but atomically. + atomicStoreMarshalInfo(&a.marshal, u) + } + return u +} + +// size is the main function to compute the size of the encoded data of a message. +// ptr is the pointer to the message. +func (u *marshalInfo) size(ptr pointer) int { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + // Uses the message's Size method if available + if u.hassizer { + s := ptr.asPointerTo(u.typ).Interface().(Sizer) + return s.Size() + } + // Uses the message's ProtoSize method if available + if u.hasprotosizer { + s := ptr.asPointerTo(u.typ).Interface().(ProtoSizer) + return s.ProtoSize() + } + + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b, _ := m.Marshal() + return len(b) + } + + n := 0 + for _, f := range u.fields { + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + n += f.sizer(ptr.offset(f.field), f.tagsize) + } + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + n += u.sizeMessageSet(e) + } else { + n += u.sizeExtensions(e) + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + n += u.sizeV1Extensions(m) + } + if u.bytesExtensions.IsValid() { + s := *ptr.offset(u.bytesExtensions).toBytes() + n += len(s) + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + n += len(s) + } + + // cache the result for use in marshal + if u.sizecache.IsValid() { + atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) + } + return n +} + +// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), +// fall back to compute the size. +func (u *marshalInfo) cachedsize(ptr pointer) int { + if u.sizecache.IsValid() { + return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) + } + return u.size(ptr) +} + +// marshal is the main function to marshal a message. It takes a byte slice and appends +// the encoded data to the end of the slice, returns the slice and error (if any). +// ptr is the pointer to the message. +// If deterministic is true, map is marshaled in deterministic order. +func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b1, err := m.Marshal() + b = append(b, b1...) + return b, err + } + + var err, errLater error + // The old marshaler encodes extensions at beginning. + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + b, err = u.appendMessageSet(b, e, deterministic) + } else { + b, err = u.appendExtensions(b, e, deterministic) + } + if err != nil { + return b, err + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + b, err = u.appendV1Extensions(b, m, deterministic) + if err != nil { + return b, err + } + } + if u.bytesExtensions.IsValid() { + s := *ptr.offset(u.bytesExtensions).toBytes() + b = append(b, s...) + } + for _, f := range u.fields { + if f.required { + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // Required field is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name} + } + continue + } + } + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) + if err != nil { + if err1, ok := err.(*RequiredNotSetError); ok { + // Required field in submessage is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name + "." + err1.field} + } + continue + } + if err == errRepeatedHasNil { + err = errors.New("proto: repeated field " + f.name + " has nil element") + } + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return b, err + } + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + b = append(b, s...) + } + return b, errLater +} + +// computeMarshalInfo initializes the marshal info. +func (u *marshalInfo) computeMarshalInfo() { + u.Lock() + defer u.Unlock() + if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock + return + } + + t := u.typ + u.unrecognized = invalidField + u.extensions = invalidField + u.v1extensions = invalidField + u.bytesExtensions = invalidField + u.sizecache = invalidField + isOneofMessage := false + + if reflect.PtrTo(t).Implements(sizerType) { + u.hassizer = true + } + if reflect.PtrTo(t).Implements(protosizerType) { + u.hasprotosizer = true + } + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if reflect.PtrTo(t).Implements(marshalerType) { + u.hasmarshaler = true + atomic.StoreInt32(&u.initialized, 1) + return + } + + n := t.NumField() + + // deal with XXX fields first + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Tag.Get("protobuf_oneof") != "" { + isOneofMessage = true + } + if !strings.HasPrefix(f.Name, "XXX_") { + continue + } + switch f.Name { + case "XXX_sizecache": + u.sizecache = toField(&f) + case "XXX_unrecognized": + u.unrecognized = toField(&f) + case "XXX_InternalExtensions": + u.extensions = toField(&f) + u.messageset = f.Tag.Get("protobuf_messageset") == "1" + case "XXX_extensions": + if f.Type.Kind() == reflect.Map { + u.v1extensions = toField(&f) + } else { + u.bytesExtensions = toField(&f) + } + case "XXX_NoUnkeyedLiteral": + // nothing to do + default: + panic("unknown XXX field: " + f.Name) + } + n-- + } + + // get oneof implementers + var oneofImplementers []interface{} + // gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler + if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok && isOneofMessage { + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + } + + // normal fields + fields := make([]marshalFieldInfo, n) // batch allocation + u.fields = make([]*marshalFieldInfo, 0, n) + for i, j := 0, 0; i < t.NumField(); i++ { + f := t.Field(i) + + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + field := &fields[j] + j++ + field.name = f.Name + u.fields = append(u.fields, field) + if f.Tag.Get("protobuf_oneof") != "" { + field.computeOneofFieldInfo(&f, oneofImplementers) + continue + } + if f.Tag.Get("protobuf") == "" { + // field has no tag (not in generated message), ignore it + u.fields = u.fields[:len(u.fields)-1] + j-- + continue + } + field.computeMarshalFieldInfo(&f) + } + + // fields are marshaled in tag order on the wire. + sort.Sort(byTag(u.fields)) + + atomic.StoreInt32(&u.initialized, 1) +} + +// helper for sorting fields by tag +type byTag []*marshalFieldInfo + +func (a byTag) Len() int { return len(a) } +func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } + +// getExtElemInfo returns the information to marshal an extension element. +// The info it returns is initialized. +func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { + // get from cache first + u.RLock() + e, ok := u.extElems[desc.Field] + u.RUnlock() + if ok { + return e + } + + t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct + tags := strings.Split(desc.Tag, ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + sizr, marshalr := typeMarshaler(t, tags, false, false) + e = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizr, + marshaler: marshalr, + isptr: t.Kind() == reflect.Ptr, + } + + // update cache + u.Lock() + if u.extElems == nil { + u.extElems = make(map[int32]*marshalElemInfo) + } + u.extElems[desc.Field] = e + u.Unlock() + return e +} + +// computeMarshalFieldInfo fills up the information to marshal a field. +func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { + // parse protobuf tag of the field. + // tag has format of "bytes,49,opt,name=foo,def=hello!" + tags := strings.Split(f.Tag.Get("protobuf"), ",") + if tags[0] == "" { + return + } + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + if tags[2] == "req" { + fi.required = true + } + fi.setTag(f, tag, wt) + fi.setMarshaler(f, tags) +} + +func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { + fi.field = toField(f) + fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. + fi.isPointer = true + fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) + fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) + + ityp := f.Type // interface type + for _, o := range oneofImplementers { + t := reflect.TypeOf(o) + if !t.Implements(ityp) { + continue + } + sf := t.Elem().Field(0) // oneof implementer is a struct with a single field + tags := strings.Split(sf.Tag.Get("protobuf"), ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + sizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value + fi.oneofElems[t.Elem()] = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizr, + marshaler: marshalr, + } + } +} + +type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) +} + +// wiretype returns the wire encoding of the type. +func wiretype(encoding string) uint64 { + switch encoding { + case "fixed32": + return WireFixed32 + case "fixed64": + return WireFixed64 + case "varint", "zigzag32", "zigzag64": + return WireVarint + case "bytes": + return WireBytes + case "group": + return WireStartGroup + } + panic("unknown wire type " + encoding) +} + +// setTag fills up the tag (in wire format) and its size in the info of a field. +func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { + fi.field = toField(f) + fi.wiretag = uint64(tag)<<3 | wt + fi.tagsize = SizeVarint(uint64(tag) << 3) +} + +// setMarshaler fills up the sizer and marshaler in the info of a field. +func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { + switch f.Type.Kind() { + case reflect.Map: + // map field + fi.isPointer = true + fi.sizer, fi.marshaler = makeMapMarshaler(f) + return + case reflect.Ptr, reflect.Slice: + fi.isPointer = true + } + fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) +} + +// typeMarshaler returns the sizer and marshaler of a given field. +// t is the type of the field. +// tags is the generated "protobuf" tag of the field. +// If nozero is true, zero value is not marshaled to the wire. +// If oneof is true, it is a oneof field. +func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { + encoding := tags[0] + + pointer := false + slice := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + packed := false + proto3 := false + ctype := false + isTime := false + isDuration := false + isWktPointer := false + validateUTF8 := true + for i := 2; i < len(tags); i++ { + if tags[i] == "packed" { + packed = true + } + if tags[i] == "proto3" { + proto3 = true + } + if strings.HasPrefix(tags[i], "customtype=") { + ctype = true + } + if tags[i] == "stdtime" { + isTime = true + } + if tags[i] == "stdduration" { + isDuration = true + } + if tags[i] == "wktptr" { + isWktPointer = true + } + } + validateUTF8 = validateUTF8 && proto3 + if !proto3 && !pointer && !slice { + nozero = false + } + + if ctype { + if reflect.PtrTo(t).Implements(customType) { + if slice { + return makeMessageRefSliceMarshaler(getMarshalInfo(t)) + } + if pointer { + return makeCustomPtrMarshaler(getMarshalInfo(t)) + } + return makeCustomMarshaler(getMarshalInfo(t)) + } else { + panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) + } + } + + if isTime { + if pointer { + if slice { + return makeTimePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeTimePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeTimeSliceMarshaler(getMarshalInfo(t)) + } + return makeTimeMarshaler(getMarshalInfo(t)) + } + + if isDuration { + if pointer { + if slice { + return makeDurationPtrSliceMarshaler(getMarshalInfo(t)) + } + return makeDurationPtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeDurationSliceMarshaler(getMarshalInfo(t)) + } + return makeDurationMarshaler(getMarshalInfo(t)) + } + + if isWktPointer { + switch t.Kind() { + case reflect.Float64: + if pointer { + if slice { + return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdDoubleValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdDoubleValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdDoubleValueMarshaler(getMarshalInfo(t)) + case reflect.Float32: + if pointer { + if slice { + return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdFloatValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdFloatValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdFloatValueMarshaler(getMarshalInfo(t)) + case reflect.Int64: + if pointer { + if slice { + return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdInt64ValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdInt64ValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdInt64ValueMarshaler(getMarshalInfo(t)) + case reflect.Uint64: + if pointer { + if slice { + return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdUInt64ValueMarshaler(getMarshalInfo(t)) + case reflect.Int32: + if pointer { + if slice { + return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdInt32ValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdInt32ValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdInt32ValueMarshaler(getMarshalInfo(t)) + case reflect.Uint32: + if pointer { + if slice { + return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdUInt32ValueMarshaler(getMarshalInfo(t)) + case reflect.Bool: + if pointer { + if slice { + return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdBoolValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdBoolValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdBoolValueMarshaler(getMarshalInfo(t)) + case reflect.String: + if pointer { + if slice { + return makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdStringValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdStringValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdStringValueMarshaler(getMarshalInfo(t)) + case uint8SliceType: + if pointer { + if slice { + return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t)) + } + return makeStdBytesValuePtrMarshaler(getMarshalInfo(t)) + } + if slice { + return makeStdBytesValueSliceMarshaler(getMarshalInfo(t)) + } + return makeStdBytesValueMarshaler(getMarshalInfo(t)) + default: + panic(fmt.Sprintf("unknown wktpointer type %#v", t)) + } + } + + switch t.Kind() { + case reflect.Bool: + if pointer { + return sizeBoolPtr, appendBoolPtr + } + if slice { + if packed { + return sizeBoolPackedSlice, appendBoolPackedSlice + } + return sizeBoolSlice, appendBoolSlice + } + if nozero { + return sizeBoolValueNoZero, appendBoolValueNoZero + } + return sizeBoolValue, appendBoolValue + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixed32Ptr, appendFixed32Ptr + } + if slice { + if packed { + return sizeFixed32PackedSlice, appendFixed32PackedSlice + } + return sizeFixed32Slice, appendFixed32Slice + } + if nozero { + return sizeFixed32ValueNoZero, appendFixed32ValueNoZero + } + return sizeFixed32Value, appendFixed32Value + case "varint": + if pointer { + return sizeVarint32Ptr, appendVarint32Ptr + } + if slice { + if packed { + return sizeVarint32PackedSlice, appendVarint32PackedSlice + } + return sizeVarint32Slice, appendVarint32Slice + } + if nozero { + return sizeVarint32ValueNoZero, appendVarint32ValueNoZero + } + return sizeVarint32Value, appendVarint32Value + } + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixedS32Ptr, appendFixedS32Ptr + } + if slice { + if packed { + return sizeFixedS32PackedSlice, appendFixedS32PackedSlice + } + return sizeFixedS32Slice, appendFixedS32Slice + } + if nozero { + return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero + } + return sizeFixedS32Value, appendFixedS32Value + case "varint": + if pointer { + return sizeVarintS32Ptr, appendVarintS32Ptr + } + if slice { + if packed { + return sizeVarintS32PackedSlice, appendVarintS32PackedSlice + } + return sizeVarintS32Slice, appendVarintS32Slice + } + if nozero { + return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero + } + return sizeVarintS32Value, appendVarintS32Value + case "zigzag32": + if pointer { + return sizeZigzag32Ptr, appendZigzag32Ptr + } + if slice { + if packed { + return sizeZigzag32PackedSlice, appendZigzag32PackedSlice + } + return sizeZigzag32Slice, appendZigzag32Slice + } + if nozero { + return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero + } + return sizeZigzag32Value, appendZigzag32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixed64Ptr, appendFixed64Ptr + } + if slice { + if packed { + return sizeFixed64PackedSlice, appendFixed64PackedSlice + } + return sizeFixed64Slice, appendFixed64Slice + } + if nozero { + return sizeFixed64ValueNoZero, appendFixed64ValueNoZero + } + return sizeFixed64Value, appendFixed64Value + case "varint": + if pointer { + return sizeVarint64Ptr, appendVarint64Ptr + } + if slice { + if packed { + return sizeVarint64PackedSlice, appendVarint64PackedSlice + } + return sizeVarint64Slice, appendVarint64Slice + } + if nozero { + return sizeVarint64ValueNoZero, appendVarint64ValueNoZero + } + return sizeVarint64Value, appendVarint64Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixedS64Ptr, appendFixedS64Ptr + } + if slice { + if packed { + return sizeFixedS64PackedSlice, appendFixedS64PackedSlice + } + return sizeFixedS64Slice, appendFixedS64Slice + } + if nozero { + return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero + } + return sizeFixedS64Value, appendFixedS64Value + case "varint": + if pointer { + return sizeVarintS64Ptr, appendVarintS64Ptr + } + if slice { + if packed { + return sizeVarintS64PackedSlice, appendVarintS64PackedSlice + } + return sizeVarintS64Slice, appendVarintS64Slice + } + if nozero { + return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero + } + return sizeVarintS64Value, appendVarintS64Value + case "zigzag64": + if pointer { + return sizeZigzag64Ptr, appendZigzag64Ptr + } + if slice { + if packed { + return sizeZigzag64PackedSlice, appendZigzag64PackedSlice + } + return sizeZigzag64Slice, appendZigzag64Slice + } + if nozero { + return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero + } + return sizeZigzag64Value, appendZigzag64Value + } + case reflect.Float32: + if pointer { + return sizeFloat32Ptr, appendFloat32Ptr + } + if slice { + if packed { + return sizeFloat32PackedSlice, appendFloat32PackedSlice + } + return sizeFloat32Slice, appendFloat32Slice + } + if nozero { + return sizeFloat32ValueNoZero, appendFloat32ValueNoZero + } + return sizeFloat32Value, appendFloat32Value + case reflect.Float64: + if pointer { + return sizeFloat64Ptr, appendFloat64Ptr + } + if slice { + if packed { + return sizeFloat64PackedSlice, appendFloat64PackedSlice + } + return sizeFloat64Slice, appendFloat64Slice + } + if nozero { + return sizeFloat64ValueNoZero, appendFloat64ValueNoZero + } + return sizeFloat64Value, appendFloat64Value + case reflect.String: + if validateUTF8 { + if pointer { + return sizeStringPtr, appendUTF8StringPtr + } + if slice { + return sizeStringSlice, appendUTF8StringSlice + } + if nozero { + return sizeStringValueNoZero, appendUTF8StringValueNoZero + } + return sizeStringValue, appendUTF8StringValue + } + if pointer { + return sizeStringPtr, appendStringPtr + } + if slice { + return sizeStringSlice, appendStringSlice + } + if nozero { + return sizeStringValueNoZero, appendStringValueNoZero + } + return sizeStringValue, appendStringValue + case reflect.Slice: + if slice { + return sizeBytesSlice, appendBytesSlice + } + if oneof { + // Oneof bytes field may also have "proto3" tag. + // We want to marshal it as a oneof field. Do this + // check before the proto3 check. + return sizeBytesOneof, appendBytesOneof + } + if proto3 { + return sizeBytes3, appendBytes3 + } + return sizeBytes, appendBytes + case reflect.Struct: + switch encoding { + case "group": + if slice { + return makeGroupSliceMarshaler(getMarshalInfo(t)) + } + return makeGroupMarshaler(getMarshalInfo(t)) + case "bytes": + if pointer { + if slice { + return makeMessageSliceMarshaler(getMarshalInfo(t)) + } + return makeMessageMarshaler(getMarshalInfo(t)) + } else { + if slice { + return makeMessageRefSliceMarshaler(getMarshalInfo(t)) + } + return makeMessageRefMarshaler(getMarshalInfo(t)) + } + } + } + panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) +} + +// Below are functions to size/marshal a specific type of a field. +// They are stored in the field's info, and called by function pointers. +// They have type sizer or marshaler. + +func sizeFixed32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixedS32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFloat32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + return (4 + tagsize) * len(s) +} +func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixed64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFixedS64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFloat64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + return (8 + tagsize) * len(s) +} +func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeVarint32Value(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarint32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarint64Value(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + return SizeVarint(v) + tagsize +} +func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return SizeVarint(v) + tagsize +} +func sizeVarint64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return SizeVarint(*p) + tagsize +} +func sizeVarint64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(v) + tagsize + } + return n +} +func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize + } + return n +} +func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize + } + return n +} +func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeBoolValue(_ pointer, tagsize int) int { + return 1 + tagsize +} +func sizeBoolValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toBool() + if !v { + return 0 + } + return 1 + tagsize +} +func sizeBoolPtr(ptr pointer, tagsize int) int { + p := *ptr.toBoolPtr() + if p == nil { + return 0 + } + return 1 + tagsize +} +func sizeBoolSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + return (1 + tagsize) * len(s) +} +func sizeBoolPackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return 0 + } + return len(s) + SizeVarint(uint64(len(s))) + tagsize +} +func sizeStringValue(ptr pointer, tagsize int) int { + v := *ptr.toString() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toString() + if v == "" { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringPtr(ptr pointer, tagsize int) int { + p := *ptr.toStringPtr() + if p == nil { + return 0 + } + v := *p + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringSlice(ptr pointer, tagsize int) int { + s := *ptr.toStringSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} +func sizeBytes(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if v == nil { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytes3(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if len(v) == 0 { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesOneof(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesSlice(ptr pointer, tagsize int) int { + s := *ptr.toBytesSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} + +// appendFixed32 appends an encoded fixed32 to b. +func appendFixed32(b []byte, v uint32) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24)) + return b +} + +// appendFixed64 appends an encoded fixed64 to b. +func appendFixed64(b []byte, v uint64) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24), + byte(v>>32), + byte(v>>40), + byte(v>>48), + byte(v>>56)) + return b +} + +// appendVarint appends an encoded varint to b. +func appendVarint(b []byte, v uint64) []byte { + // TODO: make 1-byte (maybe 2-byte) case inline-able, once we + // have non-leaf inliner. + switch { + case v < 1<<7: + b = append(b, byte(v)) + case v < 1<<14: + b = append(b, + byte(v&0x7f|0x80), + byte(v>>7)) + case v < 1<<21: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte(v>>14)) + case v < 1<<28: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte(v>>21)) + case v < 1<<35: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte(v>>28)) + case v < 1<<42: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte(v>>35)) + case v < 1<<49: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte(v>>42)) + case v < 1<<56: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte(v>>49)) + case v < 1<<63: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte(v>>56)) + default: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte((v>>56)&0x7f|0x80), + 1) + } + return b +} + +func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, *p) + return b, nil +} +func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(*p)) + return b, nil +} +func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(*p)) + return b, nil +} +func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, *p) + return b, nil +} +func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(*p)) + return b, nil +} +func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(*p)) + return b, nil +} +func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, *p) + return b, nil +} +func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + } + return b, nil +} +func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, v) + } + return b, nil +} +func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + if !v { + return b, nil + } + b = appendVarint(b, wiretag) + b = append(b, 1) + return b, nil +} + +func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toBoolPtr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + if *p { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(len(s))) + for _, v := range s { + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + if v == "" { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toStringSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} +func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if v == "" { + return b, nil + } + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + s := *ptr.toStringSlice() + for _, v := range s { + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if v == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if len(v) == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBytesSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} + +// makeGroupMarshaler returns the sizer and marshaler for a group. +// u is the marshal info of the underlying message. +func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + return u.size(p) + 2*tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + var err error + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, p, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + return b, err + } +} + +// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. +// u is the marshal info of the underlying message. +func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + n += u.size(v) + 2*tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, v, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMessageMarshaler returns the sizer and marshaler for a message field. +// u is the marshal info of the message. +func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.size(p) + return siz + SizeVarint(uint64(siz)) + tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(p) + b = appendVarint(b, uint64(siz)) + return u.marshal(b, p, deterministic) + } +} + +// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. +// u is the marshal info of the message. +func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + siz := u.size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(v) + b = appendVarint(b, uint64(siz)) + b, err = u.marshal(b, v, deterministic) + + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMapMarshaler returns the sizer and marshaler for a map field. +// f is the pointer to the reflect data structure of the field. +func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { + // figure out key and value type + t := f.Type + keyType := t.Key() + valType := t.Elem() + tags := strings.Split(f.Tag.Get("protobuf"), ",") + keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") + valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") + stdOptions := false + for _, t := range tags { + if strings.HasPrefix(t, "customtype=") { + valTags = append(valTags, t) + } + if t == "stdtime" { + valTags = append(valTags, t) + stdOptions = true + } + if t == "stdduration" { + valTags = append(valTags, t) + stdOptions = true + } + if t == "wktptr" { + valTags = append(valTags, t) + } + } + keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map + valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map + keyWireTag := 1<<3 | wiretype(keyTags[0]) + valWireTag := 2<<3 | wiretype(valTags[0]) + + // We create an interface to get the addresses of the map key and value. + // If value is pointer-typed, the interface is a direct interface, the + // idata itself is the value. Otherwise, the idata is the pointer to the + // value. + // Key cannot be pointer-typed. + valIsPtr := valType.Kind() == reflect.Ptr + + // If value is a message with nested maps, calling + // valSizer in marshal may be quadratic. We should use + // cached version in marshal (but not in size). + // If value is not message type, we don't have size cache, + // but it cannot be nested either. Just use valSizer. + valCachedSizer := valSizer + if valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct { + u := getMarshalInfo(valType.Elem()) + valCachedSizer = func(ptr pointer, tagsize int) int { + // Same as message sizer, but use cache. + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.cachedsize(p) + return siz + SizeVarint(uint64(siz)) + tagsize + } + } + return func(ptr pointer, tagsize int) int { + m := ptr.asPointerTo(t).Elem() // the map + n := 0 + for _, k := range m.MapKeys() { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { + m := ptr.asPointerTo(t).Elem() // the map + var err error + keys := m.MapKeys() + if len(keys) > 1 && deterministic { + sort.Sort(mapKeys(keys)) + } + + var nerr nonFatal + for _, k := range keys { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + b = appendVarint(b, tag) + siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + b = appendVarint(b, uint64(siz)) + b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) + if !nerr.Merge(err) { + return b, err + } + b, err = valMarshaler(b, vaddr, valWireTag, deterministic) + if err != ErrNil && !nerr.Merge(err) { // allow nil value in map + return b, err + } + } + return b, nerr.E + } +} + +// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. +// fi is the marshal info of the field. +// f is the pointer to the reflect data structure of the field. +func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { + // Oneof field is an interface. We need to get the actual data type on the fly. + t := f.Type + return func(ptr pointer, _ int) int { + p := ptr.getInterfacePointer() + if p.isNil() { + return 0 + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + e := fi.oneofElems[telem] + return e.sizer(p, e.tagsize) + }, + func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { + p := ptr.getInterfacePointer() + if p.isNil() { + return b, nil + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { + return b, errOneofHasNil + } + e := fi.oneofElems[telem] + return e.marshaler(b, p, e.wiretag, deterministic) + } +} + +// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. +func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, ei.tagsize) + } + mu.Unlock() + return n +} + +// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. +func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + // Not sure this is required, but the old code does it. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// message set format is: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } + +// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field +// in message set format (above). +func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for id, e := range m { + n += 2 // start group, end group. tag = 1 (size=1) + n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + siz := len(msgWithLen) + n += siz + 1 // message, tag = 3 (size=1) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, 1) // message, tag = 3 (size=1) + } + mu.Unlock() + return n +} + +// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) +// to the end of byte slice b. +func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for id, e := range m { + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + if !nerr.Merge(err) { + return b, err + } + b = append(b, 1<<3|WireEndGroup) + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, id := range keys { + e := m[int32(id)] + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + b = append(b, 1<<3|WireEndGroup) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// sizeV1Extensions computes the size of encoded data for a V1-API extension field. +func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { + if m == nil { + return 0 + } + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, ei.tagsize) + } + return n +} + +// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. +func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { + if m == nil { + return b, nil + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + var err error + var nerr nonFatal + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// newMarshaler is the interface representing objects that can marshal themselves. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newMarshaler interface { + XXX_Size() int + XXX_Marshal(b []byte, deterministic bool) ([]byte, error) +} + +// Size returns the encoded size of a protocol buffer message. +// This is the main entry point. +func Size(pb Message) int { + if m, ok := pb.(newMarshaler); ok { + return m.XXX_Size() + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + b, _ := m.Marshal() + return len(b) + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return 0 + } + var info InternalMessageInfo + return info.Size(pb) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, returning the data. +// This is the main entry point. +func Marshal(pb Message) ([]byte, error) { + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + b := make([]byte, 0, siz) + return m.XXX_Marshal(b, false) + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + return m.Marshal() + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return nil, ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + b := make([]byte, 0, siz) + return info.Marshal(b, pb, false) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, writing the result to the +// Buffer. +// This is an alternative entry point. It is not necessary to use +// a Buffer for most applications. +func (p *Buffer) Marshal(pb Message) error { + var err error + if p.deterministic { + if _, ok := pb.(Marshaler); ok { + return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", pb) + } + } + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + p.grow(siz) // make sure buf has enough capacity + p.buf, err = m.XXX_Marshal(p.buf, p.deterministic) + return err + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + var b []byte + b, err = m.Marshal() + p.buf = append(p.buf, b...) + return err + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + p.grow(siz) // make sure buf has enough capacity + p.buf, err = info.Marshal(p.buf, pb, p.deterministic) + return err +} + +// grow grows the buffer's capacity, if necessary, to guarantee space for +// another n bytes. After grow(n), at least n bytes can be written to the +// buffer without another allocation. +func (p *Buffer) grow(n int) { + need := len(p.buf) + n + if need <= cap(p.buf) { + return + } + newCap := len(p.buf) * 2 + if newCap < need { + newCap = need + } + p.buf = append(make([]byte, 0, newCap), p.buf...) +} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go new file mode 100644 index 00000000..997f57c1 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go @@ -0,0 +1,388 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "reflect" + "time" +) + +// makeMessageRefMarshaler differs a bit from makeMessageMarshaler +// It marshal a message T instead of a *T +func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + siz := u.size(ptr) + return siz + SizeVarint(uint64(siz)) + tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + b = appendVarint(b, wiretag) + siz := u.cachedsize(ptr) + b = appendVarint(b, uint64(siz)) + return u.marshal(b, ptr, deterministic) + } +} + +// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler +// It marshals a slice of messages []T instead of []*T +func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + e := elem.Interface() + v := toAddrPointer(&e, false) + siz := u.size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + var err, errreq error + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + e := elem.Interface() + v := toAddrPointer(&e, false) + b = appendVarint(b, wiretag) + siz := u.size(v) + b = appendVarint(b, uint64(siz)) + b, err = u.marshal(b, v, deterministic) + + if err != nil { + if _, ok := err.(*RequiredNotSetError); ok { + // Required field in submessage is not set. + // We record the error but keep going, to give a complete marshaling. + if errreq == nil { + errreq = err + } + continue + } + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + + return b, errreq + } +} + +func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) + siz := m.Size() + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) + siz := m.Size() + buf, err := m.Marshal() + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + return b, nil + } +} + +func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + m := ptr.asPointerTo(u.typ).Interface().(custom) + siz := m.Size() + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + m := ptr.asPointerTo(u.typ).Interface().(custom) + siz := m.Size() + buf, err := m.Marshal() + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + return b, nil + } +} + +func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return 0 + } + siz := Size(ts) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return nil, err + } + buf, err := Marshal(ts) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return 0 + } + siz := Size(ts) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return nil, err + } + buf, err := Marshal(ts) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(time.Time) + ts, err := timestampProto(t) + if err != nil { + return 0 + } + siz := Size(ts) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(time.Time) + ts, err := timestampProto(t) + if err != nil { + return nil, err + } + siz := Size(ts) + buf, err := Marshal(ts) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return 0 + } + siz := Size(ts) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*time.Time) + ts, err := timestampProto(*t) + if err != nil { + return nil, err + } + siz := Size(ts) + buf, err := Marshal(ts) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) + dur := durationProto(*d) + siz := Size(dur) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) + dur := durationProto(*d) + buf, err := Marshal(dur) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) + dur := durationProto(*d) + siz := Size(dur) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) + dur := durationProto(*d) + buf, err := Marshal(dur) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + d := elem.Interface().(time.Duration) + dur := durationProto(d) + siz := Size(dur) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + d := elem.Interface().(time.Duration) + dur := durationProto(d) + siz := Size(dur) + buf, err := Marshal(dur) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + d := elem.Interface().(*time.Duration) + dur := durationProto(*d) + siz := Size(dur) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + d := elem.Interface().(*time.Duration) + dur := durationProto(*d) + siz := Size(dur) + buf, err := Marshal(dur) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/table_merge.go b/vendor/github.com/gogo/protobuf/proto/table_merge.go new file mode 100644 index 00000000..f520106e --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/table_merge.go @@ -0,0 +1,657 @@ +// 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 proto + +import ( + "fmt" + "reflect" + "strings" + "sync" + "sync/atomic" +) + +// Merge merges the src message into dst. +// This assumes that dst and src of the same type and are non-nil. +func (a *InternalMessageInfo) Merge(dst, src Message) { + mi := atomicLoadMergeInfo(&a.merge) + if mi == nil { + mi = getMergeInfo(reflect.TypeOf(dst).Elem()) + atomicStoreMergeInfo(&a.merge, mi) + } + mi.merge(toPointer(&dst), toPointer(&src)) +} + +type mergeInfo struct { + typ reflect.Type + + initialized int32 // 0: only typ is valid, 1: everything is valid + lock sync.Mutex + + fields []mergeFieldInfo + unrecognized field // Offset of XXX_unrecognized +} + +type mergeFieldInfo struct { + field field // Offset of field, guaranteed to be valid + + // isPointer reports whether the value in the field is a pointer. + // This is true for the following situations: + // * Pointer to struct + // * Pointer to basic type (proto2 only) + // * Slice (first value in slice header is a pointer) + // * String (first value in string header is a pointer) + isPointer bool + + // basicWidth reports the width of the field assuming that it is directly + // embedded in the struct (as is the case for basic types in proto3). + // The possible values are: + // 0: invalid + // 1: bool + // 4: int32, uint32, float32 + // 8: int64, uint64, float64 + basicWidth int + + // Where dst and src are pointers to the types being merged. + merge func(dst, src pointer) +} + +var ( + mergeInfoMap = map[reflect.Type]*mergeInfo{} + mergeInfoLock sync.Mutex +) + +func getMergeInfo(t reflect.Type) *mergeInfo { + mergeInfoLock.Lock() + defer mergeInfoLock.Unlock() + mi := mergeInfoMap[t] + if mi == nil { + mi = &mergeInfo{typ: t} + mergeInfoMap[t] = mi + } + return mi +} + +// merge merges src into dst assuming they are both of type *mi.typ. +func (mi *mergeInfo) merge(dst, src pointer) { + if dst.isNil() { + panic("proto: nil destination") + } + if src.isNil() { + return // Nothing to do. + } + + if atomic.LoadInt32(&mi.initialized) == 0 { + mi.computeMergeInfo() + } + + for _, fi := range mi.fields { + sfp := src.offset(fi.field) + + // As an optimization, we can avoid the merge function call cost + // if we know for sure that the source will have no effect + // by checking if it is the zero value. + if unsafeAllowed { + if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string + continue + } + if fi.basicWidth > 0 { + switch { + case fi.basicWidth == 1 && !*sfp.toBool(): + continue + case fi.basicWidth == 4 && *sfp.toUint32() == 0: + continue + case fi.basicWidth == 8 && *sfp.toUint64() == 0: + continue + } + } + } + + dfp := dst.offset(fi.field) + fi.merge(dfp, sfp) + } + + // TODO: Make this faster? + out := dst.asPointerTo(mi.typ).Elem() + in := src.asPointerTo(mi.typ).Elem() + if emIn, err := extendable(in.Addr().Interface()); err == nil { + emOut, _ := extendable(out.Addr().Interface()) + mIn, muIn := emIn.extensionsRead() + if mIn != nil { + mOut := emOut.extensionsWrite() + muIn.Lock() + mergeExtension(mOut, mIn) + muIn.Unlock() + } + } + + if mi.unrecognized.IsValid() { + if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { + *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) + } + } +} + +func (mi *mergeInfo) computeMergeInfo() { + mi.lock.Lock() + defer mi.lock.Unlock() + if mi.initialized != 0 { + return + } + t := mi.typ + n := t.NumField() + + props := GetProperties(t) + for i := 0; i < n; i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + + mfi := mergeFieldInfo{field: toField(&f)} + tf := f.Type + + // As an optimization, we can avoid the merge function call cost + // if we know for sure that the source will have no effect + // by checking if it is the zero value. + if unsafeAllowed { + switch tf.Kind() { + case reflect.Ptr, reflect.Slice, reflect.String: + // As a special case, we assume slices and strings are pointers + // since we know that the first field in the SliceSlice or + // StringHeader is a data pointer. + mfi.isPointer = true + case reflect.Bool: + mfi.basicWidth = 1 + case reflect.Int32, reflect.Uint32, reflect.Float32: + mfi.basicWidth = 4 + case reflect.Int64, reflect.Uint64, reflect.Float64: + mfi.basicWidth = 8 + } + } + + // Unwrap tf to get at its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic("both pointer and slice for basic type in " + tf.Name()) + } + + switch tf.Kind() { + case reflect.Int32: + switch { + case isSlice: // E.g., []int32 + mfi.merge = func(dst, src pointer) { + // NOTE: toInt32Slice is not defined (see pointer_reflect.go). + /* + sfsp := src.toInt32Slice() + if *sfsp != nil { + dfsp := dst.toInt32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []int64{} + } + } + */ + sfs := src.getInt32Slice() + if sfs != nil { + dfs := dst.getInt32Slice() + dfs = append(dfs, sfs...) + if dfs == nil { + dfs = []int32{} + } + dst.setInt32Slice(dfs) + } + } + case isPointer: // E.g., *int32 + mfi.merge = func(dst, src pointer) { + // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). + /* + sfpp := src.toInt32Ptr() + if *sfpp != nil { + dfpp := dst.toInt32Ptr() + if *dfpp == nil { + *dfpp = Int32(**sfpp) + } else { + **dfpp = **sfpp + } + } + */ + sfp := src.getInt32Ptr() + if sfp != nil { + dfp := dst.getInt32Ptr() + if dfp == nil { + dst.setInt32Ptr(*sfp) + } else { + *dfp = *sfp + } + } + } + default: // E.g., int32 + mfi.merge = func(dst, src pointer) { + if v := *src.toInt32(); v != 0 { + *dst.toInt32() = v + } + } + } + case reflect.Int64: + switch { + case isSlice: // E.g., []int64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toInt64Slice() + if *sfsp != nil { + dfsp := dst.toInt64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []int64{} + } + } + } + case isPointer: // E.g., *int64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toInt64Ptr() + if *sfpp != nil { + dfpp := dst.toInt64Ptr() + if *dfpp == nil { + *dfpp = Int64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., int64 + mfi.merge = func(dst, src pointer) { + if v := *src.toInt64(); v != 0 { + *dst.toInt64() = v + } + } + } + case reflect.Uint32: + switch { + case isSlice: // E.g., []uint32 + mfi.merge = func(dst, src pointer) { + sfsp := src.toUint32Slice() + if *sfsp != nil { + dfsp := dst.toUint32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []uint32{} + } + } + } + case isPointer: // E.g., *uint32 + mfi.merge = func(dst, src pointer) { + sfpp := src.toUint32Ptr() + if *sfpp != nil { + dfpp := dst.toUint32Ptr() + if *dfpp == nil { + *dfpp = Uint32(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., uint32 + mfi.merge = func(dst, src pointer) { + if v := *src.toUint32(); v != 0 { + *dst.toUint32() = v + } + } + } + case reflect.Uint64: + switch { + case isSlice: // E.g., []uint64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toUint64Slice() + if *sfsp != nil { + dfsp := dst.toUint64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []uint64{} + } + } + } + case isPointer: // E.g., *uint64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toUint64Ptr() + if *sfpp != nil { + dfpp := dst.toUint64Ptr() + if *dfpp == nil { + *dfpp = Uint64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., uint64 + mfi.merge = func(dst, src pointer) { + if v := *src.toUint64(); v != 0 { + *dst.toUint64() = v + } + } + } + case reflect.Float32: + switch { + case isSlice: // E.g., []float32 + mfi.merge = func(dst, src pointer) { + sfsp := src.toFloat32Slice() + if *sfsp != nil { + dfsp := dst.toFloat32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []float32{} + } + } + } + case isPointer: // E.g., *float32 + mfi.merge = func(dst, src pointer) { + sfpp := src.toFloat32Ptr() + if *sfpp != nil { + dfpp := dst.toFloat32Ptr() + if *dfpp == nil { + *dfpp = Float32(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., float32 + mfi.merge = func(dst, src pointer) { + if v := *src.toFloat32(); v != 0 { + *dst.toFloat32() = v + } + } + } + case reflect.Float64: + switch { + case isSlice: // E.g., []float64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toFloat64Slice() + if *sfsp != nil { + dfsp := dst.toFloat64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []float64{} + } + } + } + case isPointer: // E.g., *float64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toFloat64Ptr() + if *sfpp != nil { + dfpp := dst.toFloat64Ptr() + if *dfpp == nil { + *dfpp = Float64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., float64 + mfi.merge = func(dst, src pointer) { + if v := *src.toFloat64(); v != 0 { + *dst.toFloat64() = v + } + } + } + case reflect.Bool: + switch { + case isSlice: // E.g., []bool + mfi.merge = func(dst, src pointer) { + sfsp := src.toBoolSlice() + if *sfsp != nil { + dfsp := dst.toBoolSlice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []bool{} + } + } + } + case isPointer: // E.g., *bool + mfi.merge = func(dst, src pointer) { + sfpp := src.toBoolPtr() + if *sfpp != nil { + dfpp := dst.toBoolPtr() + if *dfpp == nil { + *dfpp = Bool(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., bool + mfi.merge = func(dst, src pointer) { + if v := *src.toBool(); v { + *dst.toBool() = v + } + } + } + case reflect.String: + switch { + case isSlice: // E.g., []string + mfi.merge = func(dst, src pointer) { + sfsp := src.toStringSlice() + if *sfsp != nil { + dfsp := dst.toStringSlice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []string{} + } + } + } + case isPointer: // E.g., *string + mfi.merge = func(dst, src pointer) { + sfpp := src.toStringPtr() + if *sfpp != nil { + dfpp := dst.toStringPtr() + if *dfpp == nil { + *dfpp = String(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., string + mfi.merge = func(dst, src pointer) { + if v := *src.toString(); v != "" { + *dst.toString() = v + } + } + } + case reflect.Slice: + isProto3 := props.Prop[i].proto3 + switch { + case isPointer: + panic("bad pointer in byte slice case in " + tf.Name()) + case tf.Elem().Kind() != reflect.Uint8: + panic("bad element kind in byte slice case in " + tf.Name()) + case isSlice: // E.g., [][]byte + mfi.merge = func(dst, src pointer) { + sbsp := src.toBytesSlice() + if *sbsp != nil { + dbsp := dst.toBytesSlice() + for _, sb := range *sbsp { + if sb == nil { + *dbsp = append(*dbsp, nil) + } else { + *dbsp = append(*dbsp, append([]byte{}, sb...)) + } + } + if *dbsp == nil { + *dbsp = [][]byte{} + } + } + } + default: // E.g., []byte + mfi.merge = func(dst, src pointer) { + sbp := src.toBytes() + if *sbp != nil { + dbp := dst.toBytes() + if !isProto3 || len(*sbp) > 0 { + *dbp = append([]byte{}, *sbp...) + } + } + } + } + case reflect.Struct: + switch { + case !isPointer: + mergeInfo := getMergeInfo(tf) + mfi.merge = func(dst, src pointer) { + mergeInfo.merge(dst, src) + } + case isSlice: // E.g., []*pb.T + mergeInfo := getMergeInfo(tf) + mfi.merge = func(dst, src pointer) { + sps := src.getPointerSlice() + if sps != nil { + dps := dst.getPointerSlice() + for _, sp := range sps { + var dp pointer + if !sp.isNil() { + dp = valToPointer(reflect.New(tf)) + mergeInfo.merge(dp, sp) + } + dps = append(dps, dp) + } + if dps == nil { + dps = []pointer{} + } + dst.setPointerSlice(dps) + } + } + default: // E.g., *pb.T + mergeInfo := getMergeInfo(tf) + mfi.merge = func(dst, src pointer) { + sp := src.getPointer() + if !sp.isNil() { + dp := dst.getPointer() + if dp.isNil() { + dp = valToPointer(reflect.New(tf)) + dst.setPointer(dp) + } + mergeInfo.merge(dp, sp) + } + } + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic("bad pointer or slice in map case in " + tf.Name()) + default: // E.g., map[K]V + mfi.merge = func(dst, src pointer) { + sm := src.asPointerTo(tf).Elem() + if sm.Len() == 0 { + return + } + dm := dst.asPointerTo(tf).Elem() + if dm.IsNil() { + dm.Set(reflect.MakeMap(tf)) + } + + switch tf.Elem().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + val = reflect.ValueOf(Clone(val.Interface().(Message))) + dm.SetMapIndex(key, val) + } + case reflect.Slice: // E.g. Bytes type (e.g., []byte) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + dm.SetMapIndex(key, val) + } + default: // Basic type (e.g., string) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + dm.SetMapIndex(key, val) + } + } + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic("bad pointer or slice in interface case in " + tf.Name()) + default: // E.g., interface{} + // TODO: Make this faster? + mfi.merge = func(dst, src pointer) { + su := src.asPointerTo(tf).Elem() + if !su.IsNil() { + du := dst.asPointerTo(tf).Elem() + typ := su.Elem().Type() + if du.IsNil() || du.Elem().Type() != typ { + du.Set(reflect.New(typ.Elem())) // Initialize interface if empty + } + sv := su.Elem().Elem().Field(0) + if sv.Kind() == reflect.Ptr && sv.IsNil() { + return + } + dv := du.Elem().Elem().Field(0) + if dv.Kind() == reflect.Ptr && dv.IsNil() { + dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty + } + switch sv.Type().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + Merge(dv.Interface().(Message), sv.Interface().(Message)) + case reflect.Slice: // E.g. Bytes type (e.g., []byte) + dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) + default: // Basic type (e.g., string) + dv.Set(sv) + } + } + } + } + default: + panic(fmt.Sprintf("merger not found for type:%s", tf)) + } + mi.fields = append(mi.fields, mfi) + } + + mi.unrecognized = invalidField + if f, ok := t.FieldByName("XXX_unrecognized"); ok { + if f.Type != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + mi.unrecognized = toField(&f) + } + + atomic.StoreInt32(&mi.initialized, 1) +} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go new file mode 100644 index 00000000..bb2622f2 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go @@ -0,0 +1,2245 @@ +// 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 proto + +import ( + "errors" + "fmt" + "io" + "math" + "reflect" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// Unmarshal is the entry point from the generated .pb.go files. +// This function is not intended to be used by non-generated code. +// This function is not subject to any compatibility guarantee. +// msg contains a pointer to a protocol buffer struct. +// b is the data to be unmarshaled into the protocol buffer. +// a is a pointer to a place to store cached unmarshal information. +func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { + // Load the unmarshal information for this message type. + // The atomic load ensures memory consistency. + u := atomicLoadUnmarshalInfo(&a.unmarshal) + if u == nil { + // Slow path: find unmarshal info for msg, update a with it. + u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) + atomicStoreUnmarshalInfo(&a.unmarshal, u) + } + // Then do the unmarshaling. + err := u.unmarshal(toPointer(&msg), b) + return err +} + +type unmarshalInfo struct { + typ reflect.Type // type of the protobuf struct + + // 0 = only typ field is initialized + // 1 = completely initialized + initialized int32 + lock sync.Mutex // prevents double initialization + dense []unmarshalFieldInfo // fields indexed by tag # + sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # + reqFields []string // names of required fields + reqMask uint64 // 1< 0 { + // Read tag and wire type. + // Special case 1 and 2 byte varints. + var x uint64 + if b[0] < 128 { + x = uint64(b[0]) + b = b[1:] + } else if len(b) >= 2 && b[1] < 128 { + x = uint64(b[0]&0x7f) + uint64(b[1])<<7 + b = b[2:] + } else { + var n int + x, n = decodeVarint(b) + if n == 0 { + return io.ErrUnexpectedEOF + } + b = b[n:] + } + tag := x >> 3 + wire := int(x) & 7 + + // Dispatch on the tag to one of the unmarshal* functions below. + var f unmarshalFieldInfo + if tag < uint64(len(u.dense)) { + f = u.dense[tag] + } else { + f = u.sparse[tag] + } + if fn := f.unmarshal; fn != nil { + var err error + b, err = fn(b, m.offset(f.field), wire) + if err == nil { + reqMask |= f.reqMask + continue + } + if r, ok := err.(*RequiredNotSetError); ok { + // Remember this error, but keep parsing. We need to produce + // a full parse even if a required field is missing. + if errLater == nil { + errLater = r + } + reqMask |= f.reqMask + continue + } + if err != errInternalBadWireType { + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return err + } + // Fragments with bad wire type are treated as unknown fields. + } + + // Unknown tag. + if !u.unrecognized.IsValid() { + // Don't keep unrecognized data; just skip it. + var err error + b, err = skipField(b, wire) + if err != nil { + return err + } + continue + } + // Keep unrecognized data around. + // maybe in extensions, maybe in the unrecognized field. + z := m.offset(u.unrecognized).toBytes() + var emap map[int32]Extension + var e Extension + for _, r := range u.extensionRanges { + if uint64(r.Start) <= tag && tag <= uint64(r.End) { + if u.extensions.IsValid() { + mp := m.offset(u.extensions).toExtensions() + emap = mp.extensionsWrite() + e = emap[int32(tag)] + z = &e.enc + break + } + if u.oldExtensions.IsValid() { + p := m.offset(u.oldExtensions).toOldExtensions() + emap = *p + if emap == nil { + emap = map[int32]Extension{} + *p = emap + } + e = emap[int32(tag)] + z = &e.enc + break + } + if u.bytesExtensions.IsValid() { + z = m.offset(u.bytesExtensions).toBytes() + break + } + panic("no extensions field available") + } + } + // Use wire type to skip data. + var err error + b0 := b + b, err = skipField(b, wire) + if err != nil { + return err + } + *z = encodeVarint(*z, tag<<3|uint64(wire)) + *z = append(*z, b0[:len(b0)-len(b)]...) + + if emap != nil { + emap[int32(tag)] = e + } + } + if reqMask != u.reqMask && errLater == nil { + // A required field of this message is missing. + for _, n := range u.reqFields { + if reqMask&1 == 0 { + errLater = &RequiredNotSetError{n} + } + reqMask >>= 1 + } + } + return errLater +} + +// computeUnmarshalInfo fills in u with information for use +// in unmarshaling protocol buffers of type u.typ. +func (u *unmarshalInfo) computeUnmarshalInfo() { + u.lock.Lock() + defer u.lock.Unlock() + if u.initialized != 0 { + return + } + t := u.typ + n := t.NumField() + + // Set up the "not found" value for the unrecognized byte buffer. + // This is the default for proto3. + u.unrecognized = invalidField + u.extensions = invalidField + u.oldExtensions = invalidField + u.bytesExtensions = invalidField + + // List of the generated type and offset for each oneof field. + type oneofField struct { + ityp reflect.Type // interface type of oneof field + field field // offset in containing message + } + var oneofFields []oneofField + + for i := 0; i < n; i++ { + f := t.Field(i) + if f.Name == "XXX_unrecognized" { + // The byte slice used to hold unrecognized input is special. + if f.Type != reflect.TypeOf(([]byte)(nil)) { + panic("bad type for XXX_unrecognized field: " + f.Type.Name()) + } + u.unrecognized = toField(&f) + continue + } + if f.Name == "XXX_InternalExtensions" { + // Ditto here. + if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { + panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) + } + u.extensions = toField(&f) + if f.Tag.Get("protobuf_messageset") == "1" { + u.isMessageSet = true + } + continue + } + if f.Name == "XXX_extensions" { + // An older form of the extensions field. + if f.Type == reflect.TypeOf((map[int32]Extension)(nil)) { + u.oldExtensions = toField(&f) + continue + } else if f.Type == reflect.TypeOf(([]byte)(nil)) { + u.bytesExtensions = toField(&f) + continue + } + panic("bad type for XXX_extensions field: " + f.Type.Name()) + } + if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { + continue + } + + oneof := f.Tag.Get("protobuf_oneof") + if oneof != "" { + oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) + // The rest of oneof processing happens below. + continue + } + + tags := f.Tag.Get("protobuf") + tagArray := strings.Split(tags, ",") + if len(tagArray) < 2 { + panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) + } + tag, err := strconv.Atoi(tagArray[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tagArray[1]) + } + + name := "" + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + } + + // Extract unmarshaling function from the field (its type and tags). + unmarshal := fieldUnmarshaler(&f) + + // Required field? + var reqMask uint64 + if tagArray[2] == "req" { + bit := len(u.reqFields) + u.reqFields = append(u.reqFields, name) + reqMask = uint64(1) << uint(bit) + // TODO: if we have more than 64 required fields, we end up + // not verifying that all required fields are present. + // Fix this, perhaps using a count of required fields? + } + + // Store the info in the correct slot in the message. + u.setTag(tag, toField(&f), unmarshal, reqMask, name) + } + + // Find any types associated with oneof fields. + // TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? + fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") + // gogo: len(oneofFields) > 0 is needed for embedded oneof messages, without a marshaler and unmarshaler + if fn.IsValid() && len(oneofFields) > 0 { + res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} + for i := res.Len() - 1; i >= 0; i-- { + v := res.Index(i) // interface{} + tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X + typ := tptr.Elem() // Msg_X + + f := typ.Field(0) // oneof implementers have one field + baseUnmarshal := fieldUnmarshaler(&f) + tags := strings.Split(f.Tag.Get("protobuf"), ",") + fieldNum, err := strconv.Atoi(tags[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tags[1]) + } + var name string + for _, tag := range tags { + if strings.HasPrefix(tag, "name=") { + name = strings.TrimPrefix(tag, "name=") + break + } + } + + // Find the oneof field that this struct implements. + // Might take O(n^2) to process all of the oneofs, but who cares. + for _, of := range oneofFields { + if tptr.Implements(of.ityp) { + // We have found the corresponding interface for this struct. + // That lets us know where this struct should be stored + // when we encounter it during unmarshaling. + unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) + u.setTag(fieldNum, of.field, unmarshal, 0, name) + } + } + } + } + + // Get extension ranges, if any. + fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") + if fn.IsValid() { + if !u.extensions.IsValid() && !u.oldExtensions.IsValid() && !u.bytesExtensions.IsValid() { + panic("a message with extensions, but no extensions field in " + t.Name()) + } + u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) + } + + // Explicitly disallow tag 0. This will ensure we flag an error + // when decoding a buffer of all zeros. Without this code, we + // would decode and skip an all-zero buffer of even length. + // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. + u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { + return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) + }, 0, "") + + // Set mask for required field check. + u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? + for len(u.dense) <= tag { + u.dense = append(u.dense, unmarshalFieldInfo{}) + } + u.dense[tag] = i + return + } + if u.sparse == nil { + u.sparse = map[uint64]unmarshalFieldInfo{} + } + u.sparse[uint64(tag)] = i +} + +// fieldUnmarshaler returns an unmarshaler for the given field. +func fieldUnmarshaler(f *reflect.StructField) unmarshaler { + if f.Type.Kind() == reflect.Map { + return makeUnmarshalMap(f) + } + return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) +} + +// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. +func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { + tagArray := strings.Split(tags, ",") + encoding := tagArray[0] + name := "unknown" + ctype := false + isTime := false + isDuration := false + isWktPointer := false + proto3 := false + validateUTF8 := true + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + if tag == "proto3" { + proto3 = true + } + if strings.HasPrefix(tag, "customtype=") { + ctype = true + } + if tag == "stdtime" { + isTime = true + } + if tag == "stdduration" { + isDuration = true + } + if tag == "wktptr" { + isWktPointer = true + } + } + validateUTF8 = validateUTF8 && proto3 + + // Figure out packaging (pointer, slice, or both) + slice := false + pointer := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + if ctype { + if reflect.PtrTo(t).Implements(customType) { + if slice { + return makeUnmarshalCustomSlice(getUnmarshalInfo(t), name) + } + if pointer { + return makeUnmarshalCustomPtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalCustom(getUnmarshalInfo(t), name) + } else { + panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) + } + } + + if isTime { + if pointer { + if slice { + return makeUnmarshalTimePtrSlice(getUnmarshalInfo(t), name) + } + return makeUnmarshalTimePtr(getUnmarshalInfo(t), name) + } + if slice { + return makeUnmarshalTimeSlice(getUnmarshalInfo(t), name) + } + return makeUnmarshalTime(getUnmarshalInfo(t), name) + } + + if isDuration { + if pointer { + if slice { + return makeUnmarshalDurationPtrSlice(getUnmarshalInfo(t), name) + } + return makeUnmarshalDurationPtr(getUnmarshalInfo(t), name) + } + if slice { + return makeUnmarshalDurationSlice(getUnmarshalInfo(t), name) + } + return makeUnmarshalDuration(getUnmarshalInfo(t), name) + } + + if isWktPointer { + switch t.Kind() { + case reflect.Float64: + if pointer { + if slice { + return makeStdDoubleValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdDoubleValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdDoubleValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdDoubleValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Float32: + if pointer { + if slice { + return makeStdFloatValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdFloatValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdFloatValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdFloatValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Int64: + if pointer { + if slice { + return makeStdInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdInt64ValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Uint64: + if pointer { + if slice { + return makeStdUInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdUInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdUInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdUInt64ValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Int32: + if pointer { + if slice { + return makeStdInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdInt32ValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Uint32: + if pointer { + if slice { + return makeStdUInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdUInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdUInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdUInt32ValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.Bool: + if pointer { + if slice { + return makeStdBoolValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdBoolValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdBoolValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdBoolValueUnmarshaler(getUnmarshalInfo(t), name) + case reflect.String: + if pointer { + if slice { + return makeStdStringValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdStringValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdStringValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdStringValueUnmarshaler(getUnmarshalInfo(t), name) + case uint8SliceType: + if pointer { + if slice { + return makeStdBytesValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdBytesValuePtrUnmarshaler(getUnmarshalInfo(t), name) + } + if slice { + return makeStdBytesValueSliceUnmarshaler(getUnmarshalInfo(t), name) + } + return makeStdBytesValueUnmarshaler(getUnmarshalInfo(t), name) + default: + panic(fmt.Sprintf("unknown wktpointer type %#v", t)) + } + } + + // We'll never have both pointer and slice for basic types. + if pointer && slice && t.Kind() != reflect.Struct { + panic("both pointer and slice for basic type in " + t.Name()) + } + + switch t.Kind() { + case reflect.Bool: + if pointer { + return unmarshalBoolPtr + } + if slice { + return unmarshalBoolSlice + } + return unmarshalBoolValue + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixedS32Ptr + } + if slice { + return unmarshalFixedS32Slice + } + return unmarshalFixedS32Value + case "varint": + // this could be int32 or enum + if pointer { + return unmarshalInt32Ptr + } + if slice { + return unmarshalInt32Slice + } + return unmarshalInt32Value + case "zigzag32": + if pointer { + return unmarshalSint32Ptr + } + if slice { + return unmarshalSint32Slice + } + return unmarshalSint32Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixedS64Ptr + } + if slice { + return unmarshalFixedS64Slice + } + return unmarshalFixedS64Value + case "varint": + if pointer { + return unmarshalInt64Ptr + } + if slice { + return unmarshalInt64Slice + } + return unmarshalInt64Value + case "zigzag64": + if pointer { + return unmarshalSint64Ptr + } + if slice { + return unmarshalSint64Slice + } + return unmarshalSint64Value + } + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixed32Ptr + } + if slice { + return unmarshalFixed32Slice + } + return unmarshalFixed32Value + case "varint": + if pointer { + return unmarshalUint32Ptr + } + if slice { + return unmarshalUint32Slice + } + return unmarshalUint32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixed64Ptr + } + if slice { + return unmarshalFixed64Slice + } + return unmarshalFixed64Value + case "varint": + if pointer { + return unmarshalUint64Ptr + } + if slice { + return unmarshalUint64Slice + } + return unmarshalUint64Value + } + case reflect.Float32: + if pointer { + return unmarshalFloat32Ptr + } + if slice { + return unmarshalFloat32Slice + } + return unmarshalFloat32Value + case reflect.Float64: + if pointer { + return unmarshalFloat64Ptr + } + if slice { + return unmarshalFloat64Slice + } + return unmarshalFloat64Value + case reflect.Map: + panic("map type in typeUnmarshaler in " + t.Name()) + case reflect.Slice: + if pointer { + panic("bad pointer in slice case in " + t.Name()) + } + if slice { + return unmarshalBytesSlice + } + return unmarshalBytesValue + case reflect.String: + if validateUTF8 { + if pointer { + return unmarshalUTF8StringPtr + } + if slice { + return unmarshalUTF8StringSlice + } + return unmarshalUTF8StringValue + } + if pointer { + return unmarshalStringPtr + } + if slice { + return unmarshalStringSlice + } + return unmarshalStringValue + case reflect.Struct: + // message or group field + if !pointer { + switch encoding { + case "bytes": + if slice { + return makeUnmarshalMessageSlice(getUnmarshalInfo(t), name) + } + return makeUnmarshalMessage(getUnmarshalInfo(t), name) + } + } + switch encoding { + case "bytes": + if slice { + return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) + case "group": + if slice { + return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) + } + } + panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) +} + +// Below are all the unmarshalers for individual fields of various types. + +func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64() = v + return b, nil +} + +func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64() = v + return b, nil +} + +func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64() = v + return b, nil +} + +func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64Ptr() = &v + return b, nil +} + +func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + *f.toInt32() = v + return b, nil +} + +func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + *f.toInt32() = v + return b, nil +} + +func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32() = v + return b, nil +} + +func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32Ptr() = &v + return b, nil +} + +func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64() = v + return b[8:], nil +} + +func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64() = v + return b[8:], nil +} + +func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32() = v + return b[4:], nil +} + +func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32Ptr() = &v + return b[4:], nil +} + +func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + *f.toInt32() = v + return b[4:], nil +} + +func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.setInt32Ptr(v) + return b[4:], nil +} + +func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + return b[4:], nil +} + +func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + // Note: any length varint is allowed, even though any sane + // encoder will use one byte. + // See https://github.com/golang/protobuf/issues/76 + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + // TODO: check if x>1? Tests seem to indicate no. + v := x != 0 + *f.toBool() = v + return b[n:], nil +} + +func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + *f.toBoolPtr() = &v + return b[n:], nil +} + +func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + b = b[n:] + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + return b[n:], nil +} + +func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64() = v + return b[8:], nil +} + +func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64Ptr() = &v + return b[8:], nil +} + +func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32() = v + return b[4:], nil +} + +func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32Ptr() = &v + return b[4:], nil +} + +func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + return b[x:], nil +} + +func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + return b[x:], nil +} + +func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + return b[x:], nil +} + +func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +var emptyBuf [0]byte + +func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // The use of append here is a trick which avoids the zeroing + // that would be required if we used a make/copy pair. + // We append to emptyBuf instead of nil because we want + // a non-nil result even when the length is 0. + v := append(emptyBuf[:], b[:x]...) + *f.toBytes() = v + return b[x:], nil +} + +func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := append(emptyBuf[:], b[:x]...) + s := f.toBytesSlice() + *s = append(*s, v) + return b[x:], nil +} + +func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // First read the message field to see if something is there. + // The semantics of multiple submessages are weird. Instead of + // the last one winning (as it is for all other fields), multiple + // submessages are merged. + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[x:], err + } +} + +func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[x:], err + } +} + +func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[y:], err + } +} + +func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[y:], err + } +} + +func makeUnmarshalMap(f *reflect.StructField) unmarshaler { + t := f.Type + kt := t.Key() + vt := t.Elem() + tagArray := strings.Split(f.Tag.Get("protobuf"), ",") + valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") + for _, t := range tagArray { + if strings.HasPrefix(t, "customtype=") { + valTags = append(valTags, t) + } + if t == "stdtime" { + valTags = append(valTags, t) + } + if t == "stdduration" { + valTags = append(valTags, t) + } + if t == "wktptr" { + valTags = append(valTags, t) + } + } + unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) + unmarshalVal := typeUnmarshaler(vt, strings.Join(valTags, ",")) + return func(b []byte, f pointer, w int) ([]byte, error) { + // The map entry is a submessage. Figure out how big it is. + if w != WireBytes { + return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + r := b[x:] // unused data to return + b = b[:x] // data for map entry + + // Note: we could use #keys * #values ~= 200 functions + // to do map decoding without reflection. Probably not worth it. + // Maps will be somewhat slow. Oh well. + + // Read key and value from data. + var nerr nonFatal + k := reflect.New(kt) + v := reflect.New(vt) + for len(b) > 0 { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + wire := int(x) & 7 + b = b[n:] + + var err error + switch x >> 3 { + case 1: + b, err = unmarshalKey(b, valToPointer(k), wire) + case 2: + b, err = unmarshalVal(b, valToPointer(v), wire) + default: + err = errInternalBadWireType // skip unknown tag + } + + if nerr.Merge(err) { + continue + } + if err != errInternalBadWireType { + return nil, err + } + + // Skip past unknown fields. + b, err = skipField(b, wire) + if err != nil { + return nil, err + } + } + + // Get map, allocate if needed. + m := f.asPointerTo(t).Elem() // an addressable map[K]T + if m.IsNil() { + m.Set(reflect.MakeMap(t)) + } + + // Insert into map. + m.SetMapIndex(k.Elem(), v.Elem()) + + return r, nerr.E + } +} + +// makeUnmarshalOneof makes an unmarshaler for oneof fields. +// for: +// message Msg { +// oneof F { +// int64 X = 1; +// float64 Y = 2; +// } +// } +// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). +// ityp is the interface type of the oneof field (e.g. isMsg_F). +// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). +// Note that this function will be called once for each case in the oneof. +func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { + sf := typ.Field(0) + field0 := toField(&sf) + return func(b []byte, f pointer, w int) ([]byte, error) { + // Allocate holder for value. + v := reflect.New(typ) + + // Unmarshal data into holder. + // We unmarshal into the first field of the holder object. + var err error + var nerr nonFatal + b, err = unmarshal(b, valToPointer(v).offset(field0), w) + if !nerr.Merge(err) { + return nil, err + } + + // Write pointer to holder into target field. + f.asPointerTo(ityp).Elem().Set(v) + + return b, nerr.E + } +} + +// Error used by decode internally. +var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") + +// skipField skips past a field of type wire and returns the remaining bytes. +func skipField(b []byte, wire int) ([]byte, error) { + switch wire { + case WireVarint: + _, k := decodeVarint(b) + if k == 0 { + return b, io.ErrUnexpectedEOF + } + b = b[k:] + case WireFixed32: + if len(b) < 4 { + return b, io.ErrUnexpectedEOF + } + b = b[4:] + case WireFixed64: + if len(b) < 8 { + return b, io.ErrUnexpectedEOF + } + b = b[8:] + case WireBytes: + m, k := decodeVarint(b) + if k == 0 || uint64(len(b)-k) < m { + return b, io.ErrUnexpectedEOF + } + b = b[uint64(k)+m:] + case WireStartGroup: + _, i := findEndGroup(b) + if i == -1 { + return b, io.ErrUnexpectedEOF + } + b = b[i:] + default: + return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) + } + return b, nil +} + +// findEndGroup finds the index of the next EndGroup tag. +// Groups may be nested, so the "next" EndGroup tag is the first +// unpaired EndGroup. +// findEndGroup returns the indexes of the start and end of the EndGroup tag. +// Returns (-1,-1) if it can't find one. +func findEndGroup(b []byte) (int, int) { + depth := 1 + i := 0 + for { + x, n := decodeVarint(b[i:]) + if n == 0 { + return -1, -1 + } + j := i + i += n + switch x & 7 { + case WireVarint: + _, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + case WireFixed32: + if len(b)-4 < i { + return -1, -1 + } + i += 4 + case WireFixed64: + if len(b)-8 < i { + return -1, -1 + } + i += 8 + case WireBytes: + m, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + if uint64(len(b)-i) < m { + return -1, -1 + } + i += int(m) + case WireStartGroup: + depth++ + case WireEndGroup: + depth-- + if depth == 0 { + return j, i + } + default: + return -1, -1 + } + } +} + +// encodeVarint appends a varint-encoded integer to b and returns the result. +func encodeVarint(b []byte, x uint64) []byte { + for x >= 1<<7 { + b = append(b, byte(x&0x7f|0x80)) + x >>= 7 + } + return append(b, byte(x)) +} + +// decodeVarint reads a varint-encoded integer from b. +// Returns the decoded integer and the number of bytes read. +// If there is an error, it returns 0,0. +func decodeVarint(b []byte) (uint64, int) { + var x, y uint64 + if len(b) == 0 { + goto bad + } + x = uint64(b[0]) + if x < 0x80 { + return x, 1 + } + x -= 0x80 + + if len(b) <= 1 { + goto bad + } + y = uint64(b[1]) + x += y << 7 + if y < 0x80 { + return x, 2 + } + x -= 0x80 << 7 + + if len(b) <= 2 { + goto bad + } + y = uint64(b[2]) + x += y << 14 + if y < 0x80 { + return x, 3 + } + x -= 0x80 << 14 + + if len(b) <= 3 { + goto bad + } + y = uint64(b[3]) + x += y << 21 + if y < 0x80 { + return x, 4 + } + x -= 0x80 << 21 + + if len(b) <= 4 { + goto bad + } + y = uint64(b[4]) + x += y << 28 + if y < 0x80 { + return x, 5 + } + x -= 0x80 << 28 + + if len(b) <= 5 { + goto bad + } + y = uint64(b[5]) + x += y << 35 + if y < 0x80 { + return x, 6 + } + x -= 0x80 << 35 + + if len(b) <= 6 { + goto bad + } + y = uint64(b[6]) + x += y << 42 + if y < 0x80 { + return x, 7 + } + x -= 0x80 << 42 + + if len(b) <= 7 { + goto bad + } + y = uint64(b[7]) + x += y << 49 + if y < 0x80 { + return x, 8 + } + x -= 0x80 << 49 + + if len(b) <= 8 { + goto bad + } + y = uint64(b[8]) + x += y << 56 + if y < 0x80 { + return x, 9 + } + x -= 0x80 << 56 + + if len(b) <= 9 { + goto bad + } + y = uint64(b[9]) + x += y << 63 + if y < 2 { + return x, 10 + } + +bad: + return 0, 0 +} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go new file mode 100644 index 00000000..00d6c7ad --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go @@ -0,0 +1,385 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "io" + "reflect" +) + +func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // First read the message field to see if something is there. + // The semantics of multiple submessages are weird. Instead of + // the last one winning (as it is for all other fields), multiple + // submessages are merged. + v := f // gogo: changed from v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[x:], err + } +} + +func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v) + return b[x:], err + } +} + +func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.New(sub.typ)) + m := s.Interface().(custom) + if err := m.Unmarshal(b[:x]); err != nil { + return nil, err + } + return b[x:], nil + } +} + +func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := reflect.New(sub.typ) + c := m.Interface().(custom) + if err := c.Unmarshal(b[:x]); err != nil { + return nil, err + } + v := valToPointer(m) + f.appendRef(v, sub.typ) + return b[x:], nil + } +} + +func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + + m := f.asPointerTo(sub.typ).Interface().(custom) + if err := m.Unmarshal(b[:x]); err != nil { + return nil, err + } + return b[x:], nil + } +} + +func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := ×tamp{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + t, err := timestampFromProto(m) + if err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(t)) + return b[x:], nil + } +} + +func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := ×tamp{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + t, err := timestampFromProto(m) + if err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&t)) + return b[x:], nil + } +} + +func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := ×tamp{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + t, err := timestampFromProto(m) + if err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&t)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := ×tamp{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + t, err := timestampFromProto(m) + if err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(t)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &duration{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + d, err := durationFromProto(m) + if err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&d)) + return b[x:], nil + } +} + +func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &duration{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + d, err := durationFromProto(m) + if err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(d)) + return b[x:], nil + } +} + +func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &duration{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + d, err := durationFromProto(m) + if err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&d)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &duration{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + d, err := durationFromProto(m) + if err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(d)) + slice.Set(newSlice) + return b[x:], nil + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go new file mode 100644 index 00000000..0407ba85 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/text.go @@ -0,0 +1,928 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +// Functions for writing the text protocol buffer format. + +import ( + "bufio" + "bytes" + "encoding" + "errors" + "fmt" + "io" + "log" + "math" + "reflect" + "sort" + "strings" + "sync" + "time" +) + +var ( + newline = []byte("\n") + spaces = []byte(" ") + endBraceNewline = []byte("}\n") + backslashN = []byte{'\\', 'n'} + backslashR = []byte{'\\', 'r'} + backslashT = []byte{'\\', 't'} + backslashDQ = []byte{'\\', '"'} + backslashBS = []byte{'\\', '\\'} + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +type writer interface { + io.Writer + WriteByte(byte) error +} + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + ind int + complete bool // if the current position is a complete line + compact bool // whether to write out as a one-liner + w writer +} + +func (w *textWriter) WriteString(s string) (n int, err error) { + if !strings.Contains(s, "\n") { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + return io.WriteString(w.w, s) + } + // WriteString is typically called without newlines, so this + // codepath and its copy are rare. We copy to avoid + // duplicating all of Write's logic here. + return w.Write([]byte(s)) +} + +func (w *textWriter) Write(p []byte) (n int, err error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + n, err = w.w.Write(p) + w.complete = false + return n, err + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + if err := w.w.WriteByte(' '); err != nil { + return n, err + } + n++ + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + if i+1 < len(frags) { + if err := w.w.WriteByte('\n'); err != nil { + return n, err + } + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + err := w.w.WriteByte(c) + w.complete = c == '\n' + return err +} + +func (w *textWriter) indent() { w.ind++ } + +func (w *textWriter) unindent() { + if w.ind == 0 { + log.Print("proto: textWriter unindented too far") + return + } + w.ind-- +} + +func writeName(w *textWriter, props *Properties) error { + if _, err := w.WriteString(props.OrigName); err != nil { + return err + } + if props.Wire != "group" { + return w.WriteByte(':') + } + return nil +} + +func requiresQuotes(u string) bool { + // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. + for _, ch := range u { + switch { + case ch == '.' || ch == '/' || ch == '_': + continue + case '0' <= ch && ch <= '9': + continue + case 'A' <= ch && ch <= 'Z': + continue + case 'a' <= ch && ch <= 'z': + continue + default: + return true + } + } + return false +} + +// isAny reports whether sv is a google.protobuf.Any message +func isAny(sv reflect.Value) bool { + type wkt interface { + XXX_WellKnownType() string + } + t, ok := sv.Addr().Interface().(wkt) + return ok && t.XXX_WellKnownType() == "Any" +} + +// writeProto3Any writes an expanded google.protobuf.Any message. +// +// It returns (false, nil) if sv value can't be unmarshaled (e.g. because +// required messages are not linked in). +// +// It returns (true, error) when sv was written in expanded format or an error +// was encountered. +func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { + turl := sv.FieldByName("TypeUrl") + val := sv.FieldByName("Value") + if !turl.IsValid() || !val.IsValid() { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + b, ok := val.Interface().([]byte) + if !ok { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + parts := strings.Split(turl.String(), "/") + mt := MessageType(parts[len(parts)-1]) + if mt == nil { + return false, nil + } + m := reflect.New(mt.Elem()) + if err := Unmarshal(b, m.Interface().(Message)); err != nil { + return false, nil + } + w.Write([]byte("[")) + u := turl.String() + if requiresQuotes(u) { + writeString(w, u) + } else { + w.Write([]byte(u)) + } + if w.compact { + w.Write([]byte("]:<")) + } else { + w.Write([]byte("]: <\n")) + w.ind++ + } + if err := tm.writeStruct(w, m.Elem()); err != nil { + return true, err + } + if w.compact { + w.Write([]byte("> ")) + } else { + w.ind-- + w.Write([]byte(">\n")) + } + return true, nil +} + +func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { + if tm.ExpandAny && isAny(sv) { + if canExpand, err := tm.writeProto3Any(w, sv); canExpand { + return err + } + } + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < sv.NumField(); i++ { + fv := sv.Field(i) + props := sprops.Prop[i] + name := st.Field(i).Name + + if name == "XXX_NoUnkeyedLiteral" { + continue + } + + if strings.HasPrefix(name, "XXX_") { + // There are two XXX_ fields: + // XXX_unrecognized []byte + // XXX_extensions map[int32]proto.Extension + // The first is handled here; + // the second is handled at the bottom of this function. + if name == "XXX_unrecognized" && !fv.IsNil() { + if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Field not filled in. This could be an optional field or + // a required field that wasn't filled in. Either way, there + // isn't anything we can show for it. + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + // Repeated field that is empty, or a bytes field that is unused. + continue + } + + if props.Repeated && fv.Kind() == reflect.Slice { + // Repeated field. + for j := 0; j < fv.Len(); j++ { + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + v := fv.Index(j) + if v.Kind() == reflect.Ptr && v.IsNil() { + // A nil message in a repeated field is not valid, + // but we can handle that more gracefully than panicking. + if _, err := w.Write([]byte("\n")); err != nil { + return err + } + continue + } + if len(props.Enum) > 0 { + if err := tm.writeEnum(w, v, props); err != nil { + return err + } + } else if err := tm.writeAny(w, v, props); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Map { + // Map fields are rendered as a repeated struct with key/value fields. + keys := fv.MapKeys() + sort.Sort(mapKeys(keys)) + for _, key := range keys { + val := fv.MapIndex(key) + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + // open struct + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + // key + if _, err := w.WriteString("key:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + // nil values aren't legal, but we can avoid panicking because of them. + if val.Kind() != reflect.Ptr || !val.IsNil() { + // value + if _, err := w.WriteString("value:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, val, props.MapValProp); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + // close struct + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { + // empty bytes field + continue + } + if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { + // proto3 non-repeated scalar field; skip if zero value + if isProto3Zero(fv) { + continue + } + } + + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { + continue + } + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() + } + } + } + + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + + if len(props.Enum) > 0 { + if err := tm.writeEnum(w, fv, props); err != nil { + return err + } + } else if err := tm.writeAny(w, fv, props); err != nil { + return err + } + + if err := w.WriteByte('\n'); err != nil { + return err + } + } + + // Extensions (the XXX_extensions field). + pv := sv + if pv.CanAddr() { + pv = sv.Addr() + } else { + pv = reflect.New(sv.Type()) + pv.Elem().Set(sv) + } + if _, err := extendable(pv.Interface()); err == nil { + if err := tm.writeExtensions(w, pv); err != nil { + return err + } + } + + return nil +} + +// writeAny writes an arbitrary field. +func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { + v = reflect.Indirect(v) + + if props != nil { + if len(props.CustomType) > 0 { + custom, ok := v.Interface().(Marshaler) + if ok { + data, err := custom.Marshal() + if err != nil { + return err + } + if err := writeString(w, string(data)); err != nil { + return err + } + return nil + } + } else if len(props.CastType) > 0 { + if _, ok := v.Interface().(interface { + String() string + }); ok { + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + _, err := fmt.Fprintf(w, "%d", v.Interface()) + return err + } + } + } else if props.StdTime { + t, ok := v.Interface().(time.Time) + if !ok { + return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface()) + } + tproto, err := timestampProto(t) + if err != nil { + return err + } + propsCopy := *props // Make a copy so that this is goroutine-safe + propsCopy.StdTime = false + err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy) + return err + } else if props.StdDuration { + d, ok := v.Interface().(time.Duration) + if !ok { + return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface()) + } + dproto := durationProto(d) + propsCopy := *props // Make a copy so that this is goroutine-safe + propsCopy.StdDuration = false + err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy) + return err + } + } + + // Floats have special cases. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + x := v.Float() + var b []byte + switch { + case math.IsInf(x, 1): + b = posInf + case math.IsInf(x, -1): + b = negInf + case math.IsNaN(x): + b = nan + } + if b != nil { + _, err := w.Write(b) + return err + } + // Other values are handled below. + } + + // We don't attempt to serialise every possible value type; only those + // that can occur in protocol buffers. + switch v.Kind() { + case reflect.Slice: + // Should only be a []byte; repeated fields are handled in writeStruct. + if err := writeString(w, string(v.Bytes())); err != nil { + return err + } + case reflect.String: + if err := writeString(w, v.String()); err != nil { + return err + } + case reflect.Struct: + // Required/optional group/message. + var bra, ket byte = '<', '>' + if props != nil && props.Wire == "group" { + bra, ket = '{', '}' + } + if err := w.WriteByte(bra); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if v.CanAddr() { + // Calling v.Interface on a struct causes the reflect package to + // copy the entire struct. This is racy with the new Marshaler + // since we atomically update the XXX_sizecache. + // + // Thus, we retrieve a pointer to the struct if possible to avoid + // a race since v.Interface on the pointer doesn't copy the struct. + // + // If v is not addressable, then we are not worried about a race + // since it implies that the binary Marshaler cannot possibly be + // mutating this value. + v = v.Addr() + } + if etm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() + if err != nil { + return err + } + if _, err = w.Write(text); err != nil { + return err + } + } else { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if err := tm.writeStruct(w, v); err != nil { + return err + } + } + w.unindent() + if err := w.WriteByte(ket); err != nil { + return err + } + default: + _, err := fmt.Fprint(w, v.Interface()) + return err + } + return nil +} + +// equivalent to C's isprint. +func isprint(c byte) bool { + return c >= 0x20 && c < 0x7f +} + +// writeString writes a string in the protocol buffer text format. +// It is similar to strconv.Quote except we don't use Go escape sequences, +// we treat the string as a byte sequence, and we use octal escapes. +// These differences are to maintain interoperability with the other +// languages' implementations of the text format. +func writeString(w *textWriter, s string) error { + // use WriteByte here to get any needed indent + if err := w.WriteByte('"'); err != nil { + return err + } + // Loop over the bytes, not the runes. + for i := 0; i < len(s); i++ { + var err error + // Divergence from C++: we don't escape apostrophes. + // There's no need to escape them, and the C++ parser + // copes with a naked apostrophe. + switch c := s[i]; c { + case '\n': + _, err = w.w.Write(backslashN) + case '\r': + _, err = w.w.Write(backslashR) + case '\t': + _, err = w.w.Write(backslashT) + case '"': + _, err = w.w.Write(backslashDQ) + case '\\': + _, err = w.w.Write(backslashBS) + default: + if isprint(c) { + err = w.w.WriteByte(c) + } else { + _, err = fmt.Fprintf(w.w, "\\%03o", c) + } + } + if err != nil { + return err + } + } + return w.WriteByte('"') +} + +func writeUnknownStruct(w *textWriter, data []byte) (err error) { + if !w.compact { + if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { + return err + } + } + b := NewBuffer(data) + for b.index < len(b.buf) { + x, err := b.DecodeVarint() + if err != nil { + _, ferr := fmt.Fprintf(w, "/* %v */\n", err) + return ferr + } + wire, tag := x&7, x>>3 + if wire == WireEndGroup { + w.unindent() + if _, werr := w.Write(endBraceNewline); werr != nil { + return werr + } + continue + } + if _, ferr := fmt.Fprint(w, tag); ferr != nil { + return ferr + } + if wire != WireStartGroup { + if err = w.WriteByte(':'); err != nil { + return err + } + } + if !w.compact || wire == WireStartGroup { + if err = w.WriteByte(' '); err != nil { + return err + } + } + switch wire { + case WireBytes: + buf, e := b.DecodeRawBytes(false) + if e == nil { + _, err = fmt.Fprintf(w, "%q", buf) + } else { + _, err = fmt.Fprintf(w, "/* %v */", e) + } + case WireFixed32: + x, err = b.DecodeFixed32() + err = writeUnknownInt(w, x, err) + case WireFixed64: + x, err = b.DecodeFixed64() + err = writeUnknownInt(w, x, err) + case WireStartGroup: + err = w.WriteByte('{') + w.indent() + case WireVarint: + x, err = b.DecodeVarint() + err = writeUnknownInt(w, x, err) + default: + _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) + } + if err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + return nil +} + +func writeUnknownInt(w *textWriter, x uint64, err error) error { + if err == nil { + _, err = fmt.Fprint(w, x) + } else { + _, err = fmt.Fprintf(w, "/* %v */", err) + } + return err +} + +type int32Slice []int32 + +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// writeExtensions writes all the extensions in pv. +// pv is assumed to be a pointer to a protocol message struct that is extendable. +func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { + emap := extensionMaps[pv.Type().Elem()] + e := pv.Interface().(Message) + + var m map[int32]Extension + var mu sync.Locker + if em, ok := e.(extensionsBytes); ok { + eb := em.GetExtensions() + var err error + m, err = BytesToExtensionsMap(*eb) + if err != nil { + return err + } + mu = notLocker{} + } else if _, ok := e.(extendableProto); ok { + ep, _ := extendable(e) + m, mu = ep.extensionsRead() + if m == nil { + return nil + } + } + + // Order the extensions by ID. + // This isn't strictly necessary, but it will give us + // canonical output, which will also make testing easier. + + mu.Lock() + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + mu.Unlock() + + for _, extNum := range ids { + ext := m[extNum] + var desc *ExtensionDesc + if emap != nil { + desc = emap[extNum] + } + if desc == nil { + // Unknown extension. + if err := writeUnknownStruct(w, ext.enc); err != nil { + return err + } + continue + } + + pb, err := GetExtension(e, desc) + if err != nil { + return fmt.Errorf("failed getting extension: %v", err) + } + + // Repeated extensions will appear as a slice. + if !desc.repeated() { + if err := tm.writeExtension(w, desc.Name, pb); err != nil { + return err + } + } else { + v := reflect.ValueOf(pb) + for i := 0; i < v.Len(); i++ { + if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { + return err + } + } + } + } + return nil +} + +func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { + if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + remain := w.ind * 2 + for remain > 0 { + n := remain + if n > len(spaces) { + n = len(spaces) + } + w.w.Write(spaces[:n]) + remain -= n + } + w.complete = false +} + +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line). + ExpandAny bool // expand google.protobuf.Any messages of known types +} + +// Marshal writes a given protocol buffer in text format. +// The only errors returned are from w. +func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { + val := reflect.ValueOf(pb) + if pb == nil || val.IsNil() { + w.Write([]byte("")) + return nil + } + var bw *bufio.Writer + ww, ok := w.(writer) + if !ok { + bw = bufio.NewWriter(w) + ww = bw + } + aw := &textWriter{ + w: ww, + complete: true, + compact: tm.Compact, + } + + if etm, ok := pb.(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() + if err != nil { + return err + } + if _, err = aw.Write(text); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil + } + // Dereference the received pointer so we don't have outer < and >. + v := reflect.Indirect(val) + if err := tm.writeStruct(aw, v); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil +} + +// Text is the same as Marshal, but returns the string directly. +func (tm *TextMarshaler) Text(pb Message) string { + var buf bytes.Buffer + tm.Marshal(&buf, pb) + return buf.String() +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// TODO: consider removing some of the Marshal functions below. + +// MarshalText writes a given protocol buffer in text format. +// The only errors returned are from w. +func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } + +// MarshalTextString is the same as MarshalText, but returns the string directly. +func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } + +// CompactText writes a given protocol buffer in compact text format (one line). +func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } + +// CompactTextString is the same as CompactText, but returns the string directly. +func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/gogo/protobuf/proto/text_gogo.go b/vendor/github.com/gogo/protobuf/proto/text_gogo.go new file mode 100644 index 00000000..1d6c6aa0 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/text_gogo.go @@ -0,0 +1,57 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "fmt" + "reflect" +) + +func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error { + m, ok := enumStringMaps[props.Enum] + if !ok { + if err := tm.writeAny(w, v, props); err != nil { + return err + } + } + key := int32(0) + if v.Kind() == reflect.Ptr { + key = int32(v.Elem().Int()) + } else { + key = int32(v.Int()) + } + s, ok := m[key] + if !ok { + if err := tm.writeAny(w, v, props); err != nil { + return err + } + } + _, err := fmt.Fprint(w, s) + return err +} diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go new file mode 100644 index 00000000..1ce0be2f --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/text_parser.go @@ -0,0 +1,1018 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +// Functions for parsing the Text protocol buffer format. +// TODO: message sets. + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "time" + "unicode/utf8" +) + +// Error string emitted when deserializing Any and fields are already set +const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" + +type ParseError struct { + Message string + Line int // 1-based line number + Offset int // 0-based byte offset from start of input +} + +func (p *ParseError) Error() string { + if p.Line == 1 { + // show offset only for first line + return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) + } + return fmt.Sprintf("line %d: %v", p.Line, p.Message) +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func (t *token) String() string { + if t.err == nil { + return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) + } + return fmt.Sprintf("parse error: %v", t.err) +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +// Numbers and identifiers are matched by [-+._A-Za-z0-9] +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +var ( + errBadUTF8 = errors.New("proto: bad UTF-8") +) + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + ss := string(r) + s[:2] + s = s[2:] + i, err := strconv.ParseUint(ss, 8, 8) + if err != nil { + return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) + } + return string([]byte{byte(i)}), s, nil + case 'x', 'X', 'u', 'U': + var n int + switch r { + case 'x', 'X': + n = 2 + case 'u': + n = 4 + case 'U': + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) + } + ss := s[:n] + s = s[n:] + i, err := strconv.ParseUint(ss, 16, 64) + if err != nil { + return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) + } + if r == 'x' || r == 'X' { + return string([]byte{byte(i)}), s, nil + } + if i > utf8.MaxRune { + return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) + } + return string(i), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +// Return a RequiredNotSetError indicating which required field was not set. +func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < st.NumField(); i++ { + if !isNil(sv.Field(i)) { + continue + } + + props := sprops.Prop[i] + if props.Required { + return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} + } + } + return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen +} + +// Returns the index in the struct for the named field, as well as the parsed tag properties. +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { + i, ok := sprops.decoderOrigNames[name] + if ok { + return i, sprops.Prop[i], true + } + return -1, nil, false +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + // Colon is optional when the field is a group or message. + needColon := true + switch props.Wire { + case "group": + needColon = false + case "bytes": + // A "bytes" field is either a message, a string, or a repeated field; + // those three become *T, *string and []T respectively, so we can check for + // this field being a pointer to a non-string. + if typ.Kind() == reflect.Ptr { + // *T or *string + if typ.Elem().Kind() == reflect.String { + break + } + } else if typ.Kind() == reflect.Slice { + // []T or []*T + if typ.Elem().Kind() != reflect.Ptr { + break + } + } else if typ.Kind() == reflect.String { + // The proto3 exception is for a string field, + // which requires a colon. + break + } + needColon = false + } + if needColon { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +func (p *textParser) readStruct(sv reflect.Value, terminator string) error { + st := sv.Type() + sprops := GetProperties(st) + reqCount := sprops.reqCount + var reqFieldErr error + fieldSet := make(map[string]bool) + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]" or "[type/url]". + // + // The whole struct can also be an expanded Any message, like: + // [type/url] < ... struct contents ... > + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + // Looks like an extension or an Any. + // + // TODO: Check whether we need to handle + // namespace rooted names (e.g. ".something.Foo"). + extName, err := p.consumeExtName() + if err != nil { + return err + } + + if s := strings.LastIndex(extName, "/"); s >= 0 { + // If it contains a slash, it's an Any type URL. + messageName := extName[s+1:] + mt := MessageType(messageName) + if mt == nil { + return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) + } + tok = p.next() + if tok.err != nil { + return tok.err + } + // consume an optional colon + if tok.value == ":" { + tok = p.next() + if tok.err != nil { + return tok.err + } + } + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + v := reflect.New(mt.Elem()) + if pe := p.readStruct(v.Elem(), terminator); pe != nil { + return pe + } + b, err := Marshal(v.Interface().(Message)) + if err != nil { + return p.errorf("failed to marshal message of type %q: %v", messageName, err) + } + if fieldSet["type_url"] { + return p.errorf(anyRepeatedlyUnpacked, "type_url") + } + if fieldSet["value"] { + return p.errorf(anyRepeatedlyUnpacked, "value") + } + sv.FieldByName("TypeUrl").SetString(extName) + sv.FieldByName("Value").SetBytes(b) + fieldSet["type_url"] = true + fieldSet["value"] = true + continue + } + + var desc *ExtensionDesc + // This could be faster, but it's functional. + // TODO: Do something smarter than a linear scan. + for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { + if d.Name == extName { + desc = d + break + } + } + if desc == nil { + return p.errorf("unrecognized extension %q", extName) + } + + props := &Properties{} + props.Parse(desc.Tag) + + typ := reflect.TypeOf(desc.ExtensionType) + if err := p.checkForColon(props, typ); err != nil { + return err + } + + rep := desc.repeated() + + // Read the extension structure, and set it in + // the value we're constructing. + var ext reflect.Value + if !rep { + ext = reflect.New(typ).Elem() + } else { + ext = reflect.New(typ.Elem()).Elem() + } + if err := p.readAny(ext, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + ep := sv.Addr().Interface().(Message) + if !rep { + SetExtension(ep, desc, ext.Interface()) + } else { + old, err := GetExtension(ep, desc) + var sl reflect.Value + if err == nil { + sl = reflect.ValueOf(old) // existing slice + } else { + sl = reflect.MakeSlice(typ, 0, 1) + } + sl = reflect.Append(sl, ext) + SetExtension(ep, desc, sl.Interface()) + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + field := sv.Field(oop.Field) + if !field.IsNil() { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) + } + field.Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } + + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) + } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // However, implementations may omit key or value, and technically + // we should support them in any order. See b/28924776 for a time + // this went wrong. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + switch tok.value { + case "key": + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.MapKeyProp); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + case "value": + if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.MapValProp); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + default: + p.back() + return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) + } + } + + dst.SetMapIndex(key, val) + continue + } + + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) + } + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + if props.Required { + reqCount-- + } + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + + } + + if reqCount > 0 { + return p.missingRequiredFieldError(sv) + } + return reqFieldErr +} + +// consumeExtName consumes extension name or expanded Any type URL and the +// following ']'. It returns the name or URL consumed. +func (p *textParser) consumeExtName() (string, error) { + tok := p.next() + if tok.err != nil { + return "", tok.err + } + + // If extension name or type url is quoted, it's a single token. + if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { + name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) + if err != nil { + return "", err + } + return name, p.consumeToken("]") + } + + // Consume everything up to "]" + var parts []string + for tok.value != "]" { + parts = append(parts, tok.value) + tok = p.next() + if tok.err != nil { + return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) + } + if p.done && tok.value != "]" { + return "", p.errorf("unclosed type_url or extension name") + } + } + return strings.Join(parts, ""), nil +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) readAny(v reflect.Value, props *Properties) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "" { + return p.errorf("unexpected EOF") + } + if len(props.CustomType) > 0 { + if props.Repeated { + t := reflect.TypeOf(v.Interface()) + if t.Kind() == reflect.Slice { + tc := reflect.TypeOf(new(Marshaler)) + ok := t.Elem().Implements(tc.Elem()) + if ok { + fv := v + flen := fv.Len() + if flen == fv.Cap() { + nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1) + reflect.Copy(nav, fv) + fv.Set(nav) + } + fv.SetLen(flen + 1) + + // Read one. + p.back() + return p.readAny(fv.Index(flen), props) + } + } + } + if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { + custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler) + err := custom.Unmarshal([]byte(tok.unquoted)) + if err != nil { + return p.errorf("%v %v: %v", err, v.Type(), tok.value) + } + v.Set(reflect.ValueOf(custom)) + } else { + custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler) + err := custom.Unmarshal([]byte(tok.unquoted)) + if err != nil { + return p.errorf("%v %v: %v", err, v.Type(), tok.value) + } + v.Set(reflect.Indirect(reflect.ValueOf(custom))) + } + return nil + } + if props.StdTime { + fv := v + p.back() + props.StdTime = false + tproto := ×tamp{} + err := p.readAny(reflect.ValueOf(tproto).Elem(), props) + props.StdTime = true + if err != nil { + return err + } + tim, err := timestampFromProto(tproto) + if err != nil { + return err + } + if props.Repeated { + t := reflect.TypeOf(v.Interface()) + if t.Kind() == reflect.Slice { + if t.Elem().Kind() == reflect.Ptr { + ts := fv.Interface().([]*time.Time) + ts = append(ts, &tim) + fv.Set(reflect.ValueOf(ts)) + return nil + } else { + ts := fv.Interface().([]time.Time) + ts = append(ts, tim) + fv.Set(reflect.ValueOf(ts)) + return nil + } + } + } + if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { + v.Set(reflect.ValueOf(&tim)) + } else { + v.Set(reflect.Indirect(reflect.ValueOf(&tim))) + } + return nil + } + if props.StdDuration { + fv := v + p.back() + props.StdDuration = false + dproto := &duration{} + err := p.readAny(reflect.ValueOf(dproto).Elem(), props) + props.StdDuration = true + if err != nil { + return err + } + dur, err := durationFromProto(dproto) + if err != nil { + return err + } + if props.Repeated { + t := reflect.TypeOf(v.Interface()) + if t.Kind() == reflect.Slice { + if t.Elem().Kind() == reflect.Ptr { + ds := fv.Interface().([]*time.Duration) + ds = append(ds, &dur) + fv.Set(reflect.ValueOf(ds)) + return nil + } else { + ds := fv.Interface().([]time.Duration) + ds = append(ds, dur) + fv.Set(reflect.ValueOf(ds)) + return nil + } + } + } + if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { + v.Set(reflect.ValueOf(&dur)) + } else { + v.Set(reflect.Indirect(reflect.ValueOf(&dur))) + } + return nil + } + switch fv := v; fv.Kind() { + case reflect.Slice: + at := v.Type() + if at.Elem().Kind() == reflect.Uint8 { + // Special case for []byte + if tok.value[0] != '"' && tok.value[0] != '\'' { + // Deliberately written out here, as the error after + // this switch statement would write "invalid []byte: ...", + // which is not as user-friendly. + return p.errorf("invalid string: %v", tok.value) + } + bytes := []byte(tok.unquoted) + fv.Set(reflect.ValueOf(bytes)) + return nil + } + // Repeated field. + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + err := p.readAny(fv.Index(fv.Len()-1), props) + if err != nil { + return err + } + ntok := p.next() + if ntok.err != nil { + return ntok.err + } + if ntok.value == "]" { + break + } + if ntok.value != "," { + return p.errorf("Expected ']' or ',' found %q", ntok.value) + } + } + return nil + } + // One value of the repeated field. + p.back() + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + return p.readAny(fv.Index(fv.Len()-1), props) + case reflect.Bool: + // true/1/t/True or false/f/0/False. + switch tok.value { + case "true", "1", "t", "True": + fv.SetBool(true) + return nil + case "false", "0", "f", "False": + fv.SetBool(false) + return nil + } + case reflect.Float32, reflect.Float64: + v := tok.value + // Ignore 'f' for compatibility with output generated by C++, but don't + // remove 'f' when the value is "-inf" or "inf". + if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { + v = v[:len(v)-1] + } + if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { + fv.SetFloat(f) + return nil + } + case reflect.Int8: + if x, err := strconv.ParseInt(tok.value, 0, 8); err == nil { + fv.SetInt(x) + return nil + } + case reflect.Int16: + if x, err := strconv.ParseInt(tok.value, 0, 16); err == nil { + fv.SetInt(x) + return nil + } + case reflect.Int32: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + fv.SetInt(x) + return nil + } + + if len(props.Enum) == 0 { + break + } + m, ok := enumValueMaps[props.Enum] + if !ok { + break + } + x, ok := m[tok.value] + if !ok { + break + } + fv.SetInt(int64(x)) + return nil + case reflect.Int64: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + fv.SetInt(x) + return nil + } + + case reflect.Ptr: + // A basic field (indirected through pointer), or a repeated message/group + p.back() + fv.Set(reflect.New(fv.Type().Elem())) + return p.readAny(fv.Elem(), props) + case reflect.String: + if tok.value[0] == '"' || tok.value[0] == '\'' { + fv.SetString(tok.unquoted) + return nil + } + case reflect.Struct: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + // TODO: Handle nested messages which implement encoding.TextUnmarshaler. + return p.readStruct(fv, terminator) + case reflect.Uint8: + if x, err := strconv.ParseUint(tok.value, 0, 8); err == nil { + fv.SetUint(x) + return nil + } + case reflect.Uint16: + if x, err := strconv.ParseUint(tok.value, 0, 16); err == nil { + fv.SetUint(x) + return nil + } + case reflect.Uint32: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + fv.SetUint(uint64(x)) + return nil + } + case reflect.Uint64: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + fv.SetUint(x) + return nil + } + } + return p.errorf("invalid %v: %v", v.Type(), tok.value) +} + +// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb +// before starting to unmarshal, so any existing data in pb is always removed. +// If a required field is not set and no other error occurs, +// UnmarshalText returns *RequiredNotSetError. +func UnmarshalText(s string, pb Message) error { + if um, ok := pb.(encoding.TextUnmarshaler); ok { + return um.UnmarshalText([]byte(s)) + } + pb.Reset() + v := reflect.ValueOf(pb) + return newTextParser(s).readStruct(v.Elem(), "") +} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp.go b/vendor/github.com/gogo/protobuf/proto/timestamp.go new file mode 100644 index 00000000..9324f654 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/timestamp.go @@ -0,0 +1,113 @@ +// 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 proto + +// This file implements operations on google.protobuf.Timestamp. + +import ( + "errors" + "fmt" + "time" +) + +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 *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 +} + +// TimestampFromProto 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 timestampFromProto(ts *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) (*timestamp, error) { + seconds := t.Unix() + nanos := int32(t.Sub(time.Unix(seconds, 0))) + ts := ×tamp{ + Seconds: seconds, + Nanos: nanos, + } + if err := validateTimestamp(ts); err != nil { + return nil, err + } + return ts, nil +} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go new file mode 100644 index 00000000..38439fa9 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go @@ -0,0 +1,49 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2016, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "reflect" + "time" +) + +var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() + +type timestamp struct { + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (m *timestamp) Reset() { *m = timestamp{} } +func (*timestamp) ProtoMessage() {} +func (*timestamp) String() string { return "timestamp" } + +func init() { + RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp") +} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers.go b/vendor/github.com/gogo/protobuf/proto/wrappers.go new file mode 100644 index 00000000..b175d1b6 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/wrappers.go @@ -0,0 +1,1888 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +import ( + "io" + "reflect" +) + +func makeStdDoubleValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*float64) + v := &float64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*float64) + v := &float64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdDoubleValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) + v := &float64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) + v := &float64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdDoubleValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(float64) + v := &float64Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(float64) + v := &float64Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdDoubleValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*float64) + v := &float64Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*float64) + v := &float64Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdDoubleValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdDoubleValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdDoubleValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdDoubleValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdFloatValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*float32) + v := &float32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*float32) + v := &float32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdFloatValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) + v := &float32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) + v := &float32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdFloatValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(float32) + v := &float32Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(float32) + v := &float32Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdFloatValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*float32) + v := &float32Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*float32) + v := &float32Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdFloatValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdFloatValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdFloatValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdFloatValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &float32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*int64) + v := &int64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*int64) + v := &int64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) + v := &int64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) + v := &int64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(int64) + v := &int64Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(int64) + v := &int64Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*int64) + v := &int64Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*int64) + v := &int64Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdUInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*uint64) + v := &uint64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*uint64) + v := &uint64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdUInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) + v := &uint64Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) + v := &uint64Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdUInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(uint64) + v := &uint64Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(uint64) + v := &uint64Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdUInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*uint64) + v := &uint64Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*uint64) + v := &uint64Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdUInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdUInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdUInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdUInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint64Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*int32) + v := &int32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*int32) + v := &int32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) + v := &int32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) + v := &int32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(int32) + v := &int32Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(int32) + v := &int32Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*int32) + v := &int32Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*int32) + v := &int32Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &int32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdUInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*uint32) + v := &uint32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*uint32) + v := &uint32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdUInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) + v := &uint32Value{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) + v := &uint32Value{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdUInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(uint32) + v := &uint32Value{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(uint32) + v := &uint32Value{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdUInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*uint32) + v := &uint32Value{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*uint32) + v := &uint32Value{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdUInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdUInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdUInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdUInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &uint32Value{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdBoolValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*bool) + v := &boolValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*bool) + v := &boolValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdBoolValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) + v := &boolValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) + v := &boolValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdBoolValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(bool) + v := &boolValue{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(bool) + v := &boolValue{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdBoolValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*bool) + v := &boolValue{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*bool) + v := &boolValue{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdBoolValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &boolValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdBoolValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &boolValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdBoolValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &boolValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdBoolValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &boolValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdStringValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*string) + v := &stringValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*string) + v := &stringValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdStringValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) + v := &stringValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) + v := &stringValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdStringValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(string) + v := &stringValue{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(string) + v := &stringValue{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdStringValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*string) + v := &stringValue{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*string) + v := &stringValue{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdStringValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &stringValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdStringValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &stringValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdStringValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &stringValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdStringValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &stringValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdBytesValueMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + t := ptr.asPointerTo(u.typ).Interface().(*[]byte) + v := &bytesValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + t := ptr.asPointerTo(u.typ).Interface().(*[]byte) + v := &bytesValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdBytesValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + if ptr.isNil() { + return 0 + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) + v := &bytesValue{*t} + siz := Size(v) + return tagsize + SizeVarint(uint64(siz)) + siz + }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + if ptr.isNil() { + return b, nil + } + t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) + v := &bytesValue{*t} + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(buf))) + b = append(b, buf...) + return b, nil + } +} + +func makeStdBytesValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(u.typ) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().([]byte) + v := &bytesValue{t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(u.typ) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().([]byte) + v := &bytesValue{t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdBytesValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + n := 0 + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*[]byte) + v := &bytesValue{*t} + siz := Size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getSlice(reflect.PtrTo(u.typ)) + for i := 0; i < s.Len(); i++ { + elem := s.Index(i) + t := elem.Interface().(*[]byte) + v := &bytesValue{*t} + siz := Size(v) + buf, err := Marshal(v) + if err != nil { + return nil, err + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(siz)) + b = append(b, buf...) + } + + return b, nil + } +} + +func makeStdBytesValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &bytesValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(sub.typ).Elem() + s.Set(reflect.ValueOf(m.Value)) + return b[x:], nil + } +} + +func makeStdBytesValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &bytesValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() + s.Set(reflect.ValueOf(&m.Value)) + return b[x:], nil + } +} + +func makeStdBytesValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &bytesValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(reflect.PtrTo(sub.typ)) + newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} + +func makeStdBytesValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return nil, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + m := &bytesValue{} + if err := Unmarshal(b[:x], m); err != nil { + return nil, err + } + slice := f.getSlice(sub.typ) + newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) + slice.Set(newSlice) + return b[x:], nil + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go b/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go new file mode 100644 index 00000000..c1cf7bf8 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go @@ -0,0 +1,113 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2018, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 proto + +type float64Value struct { + Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *float64Value) Reset() { *m = float64Value{} } +func (*float64Value) ProtoMessage() {} +func (*float64Value) String() string { return "float64" } + +type float32Value struct { + Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *float32Value) Reset() { *m = float32Value{} } +func (*float32Value) ProtoMessage() {} +func (*float32Value) String() string { return "float32" } + +type int64Value struct { + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *int64Value) Reset() { *m = int64Value{} } +func (*int64Value) ProtoMessage() {} +func (*int64Value) String() string { return "int64" } + +type uint64Value struct { + Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *uint64Value) Reset() { *m = uint64Value{} } +func (*uint64Value) ProtoMessage() {} +func (*uint64Value) String() string { return "uint64" } + +type int32Value struct { + Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *int32Value) Reset() { *m = int32Value{} } +func (*int32Value) ProtoMessage() {} +func (*int32Value) String() string { return "int32" } + +type uint32Value struct { + Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *uint32Value) Reset() { *m = uint32Value{} } +func (*uint32Value) ProtoMessage() {} +func (*uint32Value) String() string { return "uint32" } + +type boolValue struct { + Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *boolValue) Reset() { *m = boolValue{} } +func (*boolValue) ProtoMessage() {} +func (*boolValue) String() string { return "bool" } + +type stringValue struct { + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *stringValue) Reset() { *m = stringValue{} } +func (*stringValue) ProtoMessage() {} +func (*stringValue) String() string { return "string" } + +type bytesValue struct { + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *bytesValue) Reset() { *m = bytesValue{} } +func (*bytesValue) ProtoMessage() {} +func (*bytesValue) String() string { return "[]byte" } + +func init() { + RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue") + RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue") + RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value") + RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value") + RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value") + RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value") + RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue") + RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue") + RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue") +} diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/Makefile b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/Makefile new file mode 100644 index 00000000..3496dc99 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/Makefile @@ -0,0 +1,36 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 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. + +regenerate: + go install github.com/gogo/protobuf/protoc-gen-gogo + go install github.com/gogo/protobuf/protoc-gen-gostring + protoc --gogo_out=. -I=../../protobuf/google/protobuf ../../protobuf/google/protobuf/descriptor.proto + protoc --gostring_out=. -I=../../protobuf/google/protobuf ../../protobuf/google/protobuf/descriptor.proto diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go new file mode 100644 index 00000000..a85bf198 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go @@ -0,0 +1,118 @@ +// 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 descriptor provides functions for obtaining protocol buffer +// descriptors for generated Go types. +// +// These functions cannot go in package proto because they depend on the +// generated protobuf descriptor messages, which themselves depend on proto. +package descriptor + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" + + "github.com/gogo/protobuf/proto" +) + +// extractFile extracts a FileDescriptorProto from a gzip'd buffer. +func extractFile(gz []byte) (*FileDescriptorProto, error) { + r, err := gzip.NewReader(bytes.NewReader(gz)) + if err != nil { + return nil, fmt.Errorf("failed to open gzip reader: %v", err) + } + defer r.Close() + + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, fmt.Errorf("failed to uncompress descriptor: %v", err) + } + + fd := new(FileDescriptorProto) + if err := proto.Unmarshal(b, fd); err != nil { + return nil, fmt.Errorf("malformed FileDescriptorProto: %v", err) + } + + return fd, nil +} + +// Message is a proto.Message with a method to return its descriptor. +// +// Message types generated by the protocol compiler always satisfy +// the Message interface. +type Message interface { + proto.Message + Descriptor() ([]byte, []int) +} + +// ForMessage returns a FileDescriptorProto and a DescriptorProto from within it +// describing the given message. +func ForMessage(msg Message) (fd *FileDescriptorProto, md *DescriptorProto) { + gz, path := msg.Descriptor() + fd, err := extractFile(gz) + if err != nil { + panic(fmt.Sprintf("invalid FileDescriptorProto for %T: %v", msg, err)) + } + + md = fd.MessageType[path[0]] + for _, i := range path[1:] { + md = md.NestedType[i] + } + return fd, md +} + +// Is this field a scalar numeric type? +func (field *FieldDescriptorProto) IsScalar() bool { + if field.Type == nil { + return false + } + switch *field.Type { + case FieldDescriptorProto_TYPE_DOUBLE, + FieldDescriptorProto_TYPE_FLOAT, + FieldDescriptorProto_TYPE_INT64, + FieldDescriptorProto_TYPE_UINT64, + FieldDescriptorProto_TYPE_INT32, + FieldDescriptorProto_TYPE_FIXED64, + FieldDescriptorProto_TYPE_FIXED32, + FieldDescriptorProto_TYPE_BOOL, + FieldDescriptorProto_TYPE_UINT32, + FieldDescriptorProto_TYPE_ENUM, + FieldDescriptorProto_TYPE_SFIXED32, + FieldDescriptorProto_TYPE_SFIXED64, + FieldDescriptorProto_TYPE_SINT32, + FieldDescriptorProto_TYPE_SINT64: + return true + default: + return false + } +} diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go new file mode 100644 index 00000000..cacfa392 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go @@ -0,0 +1,2865 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: descriptor.proto + +package descriptor + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type FieldDescriptorProto_Type int32 + +const ( + // 0 is reserved for errors. + // Order is weird for historical reasons. + FieldDescriptorProto_TYPE_DOUBLE FieldDescriptorProto_Type = 1 + FieldDescriptorProto_TYPE_FLOAT FieldDescriptorProto_Type = 2 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT64 FieldDescriptorProto_Type = 3 + FieldDescriptorProto_TYPE_UINT64 FieldDescriptorProto_Type = 4 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT32 FieldDescriptorProto_Type = 5 + FieldDescriptorProto_TYPE_FIXED64 FieldDescriptorProto_Type = 6 + FieldDescriptorProto_TYPE_FIXED32 FieldDescriptorProto_Type = 7 + FieldDescriptorProto_TYPE_BOOL FieldDescriptorProto_Type = 8 + FieldDescriptorProto_TYPE_STRING FieldDescriptorProto_Type = 9 + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + FieldDescriptorProto_TYPE_GROUP FieldDescriptorProto_Type = 10 + FieldDescriptorProto_TYPE_MESSAGE FieldDescriptorProto_Type = 11 + // New in version 2. + FieldDescriptorProto_TYPE_BYTES FieldDescriptorProto_Type = 12 + FieldDescriptorProto_TYPE_UINT32 FieldDescriptorProto_Type = 13 + FieldDescriptorProto_TYPE_ENUM FieldDescriptorProto_Type = 14 + FieldDescriptorProto_TYPE_SFIXED32 FieldDescriptorProto_Type = 15 + FieldDescriptorProto_TYPE_SFIXED64 FieldDescriptorProto_Type = 16 + FieldDescriptorProto_TYPE_SINT32 FieldDescriptorProto_Type = 17 + FieldDescriptorProto_TYPE_SINT64 FieldDescriptorProto_Type = 18 +) + +var FieldDescriptorProto_Type_name = map[int32]string{ + 1: "TYPE_DOUBLE", + 2: "TYPE_FLOAT", + 3: "TYPE_INT64", + 4: "TYPE_UINT64", + 5: "TYPE_INT32", + 6: "TYPE_FIXED64", + 7: "TYPE_FIXED32", + 8: "TYPE_BOOL", + 9: "TYPE_STRING", + 10: "TYPE_GROUP", + 11: "TYPE_MESSAGE", + 12: "TYPE_BYTES", + 13: "TYPE_UINT32", + 14: "TYPE_ENUM", + 15: "TYPE_SFIXED32", + 16: "TYPE_SFIXED64", + 17: "TYPE_SINT32", + 18: "TYPE_SINT64", +} + +var FieldDescriptorProto_Type_value = map[string]int32{ + "TYPE_DOUBLE": 1, + "TYPE_FLOAT": 2, + "TYPE_INT64": 3, + "TYPE_UINT64": 4, + "TYPE_INT32": 5, + "TYPE_FIXED64": 6, + "TYPE_FIXED32": 7, + "TYPE_BOOL": 8, + "TYPE_STRING": 9, + "TYPE_GROUP": 10, + "TYPE_MESSAGE": 11, + "TYPE_BYTES": 12, + "TYPE_UINT32": 13, + "TYPE_ENUM": 14, + "TYPE_SFIXED32": 15, + "TYPE_SFIXED64": 16, + "TYPE_SINT32": 17, + "TYPE_SINT64": 18, +} + +func (x FieldDescriptorProto_Type) Enum() *FieldDescriptorProto_Type { + p := new(FieldDescriptorProto_Type) + *p = x + return p +} + +func (x FieldDescriptorProto_Type) String() string { + return proto.EnumName(FieldDescriptorProto_Type_name, int32(x)) +} + +func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Type_value, data, "FieldDescriptorProto_Type") + if err != nil { + return err + } + *x = FieldDescriptorProto_Type(value) + return nil +} + +func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{4, 0} +} + +type FieldDescriptorProto_Label int32 + +const ( + // 0 is reserved for errors + FieldDescriptorProto_LABEL_OPTIONAL FieldDescriptorProto_Label = 1 + FieldDescriptorProto_LABEL_REQUIRED FieldDescriptorProto_Label = 2 + FieldDescriptorProto_LABEL_REPEATED FieldDescriptorProto_Label = 3 +) + +var FieldDescriptorProto_Label_name = map[int32]string{ + 1: "LABEL_OPTIONAL", + 2: "LABEL_REQUIRED", + 3: "LABEL_REPEATED", +} + +var FieldDescriptorProto_Label_value = map[string]int32{ + "LABEL_OPTIONAL": 1, + "LABEL_REQUIRED": 2, + "LABEL_REPEATED": 3, +} + +func (x FieldDescriptorProto_Label) Enum() *FieldDescriptorProto_Label { + p := new(FieldDescriptorProto_Label) + *p = x + return p +} + +func (x FieldDescriptorProto_Label) String() string { + return proto.EnumName(FieldDescriptorProto_Label_name, int32(x)) +} + +func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Label_value, data, "FieldDescriptorProto_Label") + if err != nil { + return err + } + *x = FieldDescriptorProto_Label(value) + return nil +} + +func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{4, 1} +} + +// Generated classes can be optimized for speed or code size. +type FileOptions_OptimizeMode int32 + +const ( + FileOptions_SPEED FileOptions_OptimizeMode = 1 + // etc. + FileOptions_CODE_SIZE FileOptions_OptimizeMode = 2 + FileOptions_LITE_RUNTIME FileOptions_OptimizeMode = 3 +) + +var FileOptions_OptimizeMode_name = map[int32]string{ + 1: "SPEED", + 2: "CODE_SIZE", + 3: "LITE_RUNTIME", +} + +var FileOptions_OptimizeMode_value = map[string]int32{ + "SPEED": 1, + "CODE_SIZE": 2, + "LITE_RUNTIME": 3, +} + +func (x FileOptions_OptimizeMode) Enum() *FileOptions_OptimizeMode { + p := new(FileOptions_OptimizeMode) + *p = x + return p +} + +func (x FileOptions_OptimizeMode) String() string { + return proto.EnumName(FileOptions_OptimizeMode_name, int32(x)) +} + +func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FileOptions_OptimizeMode_value, data, "FileOptions_OptimizeMode") + if err != nil { + return err + } + *x = FileOptions_OptimizeMode(value) + return nil +} + +func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{10, 0} +} + +type FieldOptions_CType int32 + +const ( + // Default mode. + FieldOptions_STRING FieldOptions_CType = 0 + FieldOptions_CORD FieldOptions_CType = 1 + FieldOptions_STRING_PIECE FieldOptions_CType = 2 +) + +var FieldOptions_CType_name = map[int32]string{ + 0: "STRING", + 1: "CORD", + 2: "STRING_PIECE", +} + +var FieldOptions_CType_value = map[string]int32{ + "STRING": 0, + "CORD": 1, + "STRING_PIECE": 2, +} + +func (x FieldOptions_CType) Enum() *FieldOptions_CType { + p := new(FieldOptions_CType) + *p = x + return p +} + +func (x FieldOptions_CType) String() string { + return proto.EnumName(FieldOptions_CType_name, int32(x)) +} + +func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_CType_value, data, "FieldOptions_CType") + if err != nil { + return err + } + *x = FieldOptions_CType(value) + return nil +} + +func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{12, 0} +} + +type FieldOptions_JSType int32 + +const ( + // Use the default type. + FieldOptions_JS_NORMAL FieldOptions_JSType = 0 + // Use JavaScript strings. + FieldOptions_JS_STRING FieldOptions_JSType = 1 + // Use JavaScript numbers. + FieldOptions_JS_NUMBER FieldOptions_JSType = 2 +) + +var FieldOptions_JSType_name = map[int32]string{ + 0: "JS_NORMAL", + 1: "JS_STRING", + 2: "JS_NUMBER", +} + +var FieldOptions_JSType_value = map[string]int32{ + "JS_NORMAL": 0, + "JS_STRING": 1, + "JS_NUMBER": 2, +} + +func (x FieldOptions_JSType) Enum() *FieldOptions_JSType { + p := new(FieldOptions_JSType) + *p = x + return p +} + +func (x FieldOptions_JSType) String() string { + return proto.EnumName(FieldOptions_JSType_name, int32(x)) +} + +func (x *FieldOptions_JSType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_JSType_value, data, "FieldOptions_JSType") + if err != nil { + return err + } + *x = FieldOptions_JSType(value) + return nil +} + +func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{12, 1} +} + +// Is this method side-effect-free (or safe in HTTP parlance), or idempotent, +// or neither? HTTP based RPC implementation may choose GET verb for safe +// methods, and PUT verb for idempotent methods instead of the default POST. +type MethodOptions_IdempotencyLevel int32 + +const ( + MethodOptions_IDEMPOTENCY_UNKNOWN MethodOptions_IdempotencyLevel = 0 + MethodOptions_NO_SIDE_EFFECTS MethodOptions_IdempotencyLevel = 1 + MethodOptions_IDEMPOTENT MethodOptions_IdempotencyLevel = 2 +) + +var MethodOptions_IdempotencyLevel_name = map[int32]string{ + 0: "IDEMPOTENCY_UNKNOWN", + 1: "NO_SIDE_EFFECTS", + 2: "IDEMPOTENT", +} + +var MethodOptions_IdempotencyLevel_value = map[string]int32{ + "IDEMPOTENCY_UNKNOWN": 0, + "NO_SIDE_EFFECTS": 1, + "IDEMPOTENT": 2, +} + +func (x MethodOptions_IdempotencyLevel) Enum() *MethodOptions_IdempotencyLevel { + p := new(MethodOptions_IdempotencyLevel) + *p = x + return p +} + +func (x MethodOptions_IdempotencyLevel) String() string { + return proto.EnumName(MethodOptions_IdempotencyLevel_name, int32(x)) +} + +func (x *MethodOptions_IdempotencyLevel) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MethodOptions_IdempotencyLevel_value, data, "MethodOptions_IdempotencyLevel") + if err != nil { + return err + } + *x = MethodOptions_IdempotencyLevel(value) + return nil +} + +func (MethodOptions_IdempotencyLevel) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{17, 0} +} + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +type FileDescriptorSet struct { + File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } +func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorSet) ProtoMessage() {} +func (*FileDescriptorSet) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{0} +} +func (m *FileDescriptorSet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorSet.Unmarshal(m, b) +} +func (m *FileDescriptorSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorSet.Marshal(b, m, deterministic) +} +func (m *FileDescriptorSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorSet.Merge(m, src) +} +func (m *FileDescriptorSet) XXX_Size() int { + return xxx_messageInfo_FileDescriptorSet.Size(m) +} +func (m *FileDescriptorSet) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorSet.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorSet proto.InternalMessageInfo + +func (m *FileDescriptorSet) GetFile() []*FileDescriptorProto { + if m != nil { + return m.File + } + return nil +} + +// Describes a complete .proto file. +type FileDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` + // Names of files imported by this file. + Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` + // Indexes of the public imported files in the dependency list above. + PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency,json=publicDependency" json:"public_dependency,omitempty"` + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"` + // All top-level definitions in this file. + MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + Service []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` + Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info,json=sourceCodeInfo" json:"source_code_info,omitempty"` + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } +func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorProto) ProtoMessage() {} +func (*FileDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{1} +} +func (m *FileDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorProto.Unmarshal(m, b) +} +func (m *FileDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FileDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorProto.Merge(m, src) +} +func (m *FileDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FileDescriptorProto.Size(m) +} +func (m *FileDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorProto proto.InternalMessageInfo + +func (m *FileDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FileDescriptorProto) GetPackage() string { + if m != nil && m.Package != nil { + return *m.Package + } + return "" +} + +func (m *FileDescriptorProto) GetDependency() []string { + if m != nil { + return m.Dependency + } + return nil +} + +func (m *FileDescriptorProto) GetPublicDependency() []int32 { + if m != nil { + return m.PublicDependency + } + return nil +} + +func (m *FileDescriptorProto) GetWeakDependency() []int32 { + if m != nil { + return m.WeakDependency + } + return nil +} + +func (m *FileDescriptorProto) GetMessageType() []*DescriptorProto { + if m != nil { + return m.MessageType + } + return nil +} + +func (m *FileDescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *FileDescriptorProto) GetService() []*ServiceDescriptorProto { + if m != nil { + return m.Service + } + return nil +} + +func (m *FileDescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *FileDescriptorProto) GetOptions() *FileOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *FileDescriptorProto) GetSourceCodeInfo() *SourceCodeInfo { + if m != nil { + return m.SourceCodeInfo + } + return nil +} + +func (m *FileDescriptorProto) GetSyntax() string { + if m != nil && m.Syntax != nil { + return *m.Syntax + } + return "" +} + +// Describes a message type. +type DescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` + NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type,json=nestedType" json:"nested_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range,json=extensionRange" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl,json=oneofDecl" json:"oneof_decl,omitempty"` + Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` + ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } +func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto) ProtoMessage() {} +func (*DescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{2} +} +func (m *DescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto.Unmarshal(m, b) +} +func (m *DescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto.Marshal(b, m, deterministic) +} +func (m *DescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto.Merge(m, src) +} +func (m *DescriptorProto) XXX_Size() int { + return xxx_messageInfo_DescriptorProto.Size(m) +} +func (m *DescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto proto.InternalMessageInfo + +func (m *DescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DescriptorProto) GetField() []*FieldDescriptorProto { + if m != nil { + return m.Field + } + return nil +} + +func (m *DescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *DescriptorProto) GetNestedType() []*DescriptorProto { + if m != nil { + return m.NestedType + } + return nil +} + +func (m *DescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *DescriptorProto) GetExtensionRange() []*DescriptorProto_ExtensionRange { + if m != nil { + return m.ExtensionRange + } + return nil +} + +func (m *DescriptorProto) GetOneofDecl() []*OneofDescriptorProto { + if m != nil { + return m.OneofDecl + } + return nil +} + +func (m *DescriptorProto) GetOptions() *MessageOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *DescriptorProto) GetReservedRange() []*DescriptorProto_ReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *DescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +type DescriptorProto_ExtensionRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} } +func (m *DescriptorProto_ExtensionRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ExtensionRange) ProtoMessage() {} +func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{2, 0} +} +func (m *DescriptorProto_ExtensionRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ExtensionRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ExtensionRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ExtensionRange.Merge(m, src) +} +func (m *DescriptorProto_ExtensionRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Size(m) +} +func (m *DescriptorProto_ExtensionRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ExtensionRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ExtensionRange proto.InternalMessageInfo + +func (m *DescriptorProto_ExtensionRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetOptions() *ExtensionRangeOptions { + if m != nil { + return m.Options + } + return nil +} + +// Range of reserved tag numbers. Reserved tag numbers may not be used by +// fields or extension ranges in the same message. Reserved ranges may +// not overlap. +type DescriptorProto_ReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ReservedRange) Reset() { *m = DescriptorProto_ReservedRange{} } +func (m *DescriptorProto_ReservedRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ReservedRange) ProtoMessage() {} +func (*DescriptorProto_ReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{2, 1} +} +func (m *DescriptorProto_ReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ReservedRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ReservedRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ReservedRange.Merge(m, src) +} +func (m *DescriptorProto_ReservedRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ReservedRange.Size(m) +} +func (m *DescriptorProto_ReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ReservedRange proto.InternalMessageInfo + +func (m *DescriptorProto_ReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +type ExtensionRangeOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExtensionRangeOptions) Reset() { *m = ExtensionRangeOptions{} } +func (m *ExtensionRangeOptions) String() string { return proto.CompactTextString(m) } +func (*ExtensionRangeOptions) ProtoMessage() {} +func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{3} +} + +var extRange_ExtensionRangeOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ExtensionRangeOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ExtensionRangeOptions +} + +func (m *ExtensionRangeOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExtensionRangeOptions.Unmarshal(m, b) +} +func (m *ExtensionRangeOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExtensionRangeOptions.Marshal(b, m, deterministic) +} +func (m *ExtensionRangeOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExtensionRangeOptions.Merge(m, src) +} +func (m *ExtensionRangeOptions) XXX_Size() int { + return xxx_messageInfo_ExtensionRangeOptions.Size(m) +} +func (m *ExtensionRangeOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ExtensionRangeOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ExtensionRangeOptions proto.InternalMessageInfo + +func (m *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// Describes a field within a message. +type FieldDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` + Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"` + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + TypeName *string `protobuf:"bytes,6,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"` + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value,json=defaultValue" json:"default_value,omitempty"` + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index,json=oneofIndex" json:"oneof_index,omitempty"` + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + JsonName *string `protobuf:"bytes,10,opt,name=json_name,json=jsonName" json:"json_name,omitempty"` + Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } +func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FieldDescriptorProto) ProtoMessage() {} +func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{4} +} +func (m *FieldDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldDescriptorProto.Unmarshal(m, b) +} +func (m *FieldDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FieldDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldDescriptorProto.Merge(m, src) +} +func (m *FieldDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FieldDescriptorProto.Size(m) +} +func (m *FieldDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FieldDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldDescriptorProto proto.InternalMessageInfo + +func (m *FieldDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FieldDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *FieldDescriptorProto) GetLabel() FieldDescriptorProto_Label { + if m != nil && m.Label != nil { + return *m.Label + } + return FieldDescriptorProto_LABEL_OPTIONAL +} + +func (m *FieldDescriptorProto) GetType() FieldDescriptorProto_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FieldDescriptorProto_TYPE_DOUBLE +} + +func (m *FieldDescriptorProto) GetTypeName() string { + if m != nil && m.TypeName != nil { + return *m.TypeName + } + return "" +} + +func (m *FieldDescriptorProto) GetExtendee() string { + if m != nil && m.Extendee != nil { + return *m.Extendee + } + return "" +} + +func (m *FieldDescriptorProto) GetDefaultValue() string { + if m != nil && m.DefaultValue != nil { + return *m.DefaultValue + } + return "" +} + +func (m *FieldDescriptorProto) GetOneofIndex() int32 { + if m != nil && m.OneofIndex != nil { + return *m.OneofIndex + } + return 0 +} + +func (m *FieldDescriptorProto) GetJsonName() string { + if m != nil && m.JsonName != nil { + return *m.JsonName + } + return "" +} + +func (m *FieldDescriptorProto) GetOptions() *FieldOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a oneof. +type OneofDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Options *OneofOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} +func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{5} +} +func (m *OneofDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofDescriptorProto.Unmarshal(m, b) +} +func (m *OneofDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofDescriptorProto.Marshal(b, m, deterministic) +} +func (m *OneofDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofDescriptorProto.Merge(m, src) +} +func (m *OneofDescriptorProto) XXX_Size() int { + return xxx_messageInfo_OneofDescriptorProto.Size(m) +} +func (m *OneofDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_OneofDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofDescriptorProto proto.InternalMessageInfo + +func (m *OneofDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *OneofDescriptorProto) GetOptions() *OneofOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes an enum type. +type EnumDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Value []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` + Options *EnumOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } +func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto) ProtoMessage() {} +func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{6} +} +func (m *EnumDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto.Unmarshal(m, b) +} +func (m *EnumDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto.Merge(m, src) +} +func (m *EnumDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto.Size(m) +} +func (m *EnumDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto proto.InternalMessageInfo + +func (m *EnumDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumDescriptorProto) GetValue() []*EnumValueDescriptorProto { + if m != nil { + return m.Value + } + return nil +} + +func (m *EnumDescriptorProto) GetOptions() *EnumOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedRange() []*EnumDescriptorProto_EnumReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +// Range of reserved numeric values. Reserved values may not be used by +// entries in the same enum. Reserved ranges may not overlap. +// +// Note that this is distinct from DescriptorProto.ReservedRange in that it +// is inclusive such that it can appropriately represent the entire int32 +// domain. +type EnumDescriptorProto_EnumReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto_EnumReservedRange) Reset() { *m = EnumDescriptorProto_EnumReservedRange{} } +func (m *EnumDescriptorProto_EnumReservedRange) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto_EnumReservedRange) ProtoMessage() {} +func (*EnumDescriptorProto_EnumReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{6, 0} +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Unmarshal(m, b) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Merge(m, src) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Size(m) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto_EnumReservedRange proto.InternalMessageInfo + +func (m *EnumDescriptorProto_EnumReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *EnumDescriptorProto_EnumReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +// Describes a value within an enum. +type EnumValueDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` + Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} } +func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumValueDescriptorProto) ProtoMessage() {} +func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{7} +} +func (m *EnumValueDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueDescriptorProto.Unmarshal(m, b) +} +func (m *EnumValueDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumValueDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueDescriptorProto.Merge(m, src) +} +func (m *EnumValueDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumValueDescriptorProto.Size(m) +} +func (m *EnumValueDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueDescriptorProto proto.InternalMessageInfo + +func (m *EnumValueDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumValueDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *EnumValueDescriptorProto) GetOptions() *EnumValueOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a service. +type ServiceDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` + Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } +func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*ServiceDescriptorProto) ProtoMessage() {} +func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{8} +} +func (m *ServiceDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceDescriptorProto.Unmarshal(m, b) +} +func (m *ServiceDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceDescriptorProto.Marshal(b, m, deterministic) +} +func (m *ServiceDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceDescriptorProto.Merge(m, src) +} +func (m *ServiceDescriptorProto) XXX_Size() int { + return xxx_messageInfo_ServiceDescriptorProto.Size(m) +} +func (m *ServiceDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceDescriptorProto proto.InternalMessageInfo + +func (m *ServiceDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ServiceDescriptorProto) GetMethod() []*MethodDescriptorProto { + if m != nil { + return m.Method + } + return nil +} + +func (m *ServiceDescriptorProto) GetOptions() *ServiceOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a method of a service. +type MethodDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + InputType *string `protobuf:"bytes,2,opt,name=input_type,json=inputType" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type,json=outputType" json:"output_type,omitempty"` + Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Identifies if client streams multiple client messages + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,json=clientStreaming,def=0" json:"client_streaming,omitempty"` + // Identifies if server streams multiple server messages + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,json=serverStreaming,def=0" json:"server_streaming,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } +func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*MethodDescriptorProto) ProtoMessage() {} +func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{9} +} +func (m *MethodDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodDescriptorProto.Unmarshal(m, b) +} +func (m *MethodDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodDescriptorProto.Marshal(b, m, deterministic) +} +func (m *MethodDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodDescriptorProto.Merge(m, src) +} +func (m *MethodDescriptorProto) XXX_Size() int { + return xxx_messageInfo_MethodDescriptorProto.Size(m) +} +func (m *MethodDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_MethodDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodDescriptorProto proto.InternalMessageInfo + +const Default_MethodDescriptorProto_ClientStreaming bool = false +const Default_MethodDescriptorProto_ServerStreaming bool = false + +func (m *MethodDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MethodDescriptorProto) GetInputType() string { + if m != nil && m.InputType != nil { + return *m.InputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOutputType() string { + if m != nil && m.OutputType != nil { + return *m.OutputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOptions() *MethodOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *MethodDescriptorProto) GetClientStreaming() bool { + if m != nil && m.ClientStreaming != nil { + return *m.ClientStreaming + } + return Default_MethodDescriptorProto_ClientStreaming +} + +func (m *MethodDescriptorProto) GetServerStreaming() bool { + if m != nil && m.ServerStreaming != nil { + return *m.ServerStreaming + } + return Default_MethodDescriptorProto_ServerStreaming +} + +type FileOptions struct { + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + JavaPackage *string `protobuf:"bytes,1,opt,name=java_package,json=javaPackage" json:"java_package,omitempty"` + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname,json=javaOuterClassname" json:"java_outer_classname,omitempty"` + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"` + // This option does nothing. + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash" json:"java_generate_equals_and_hash,omitempty"` // Deprecated: Do not use. + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,json=javaStringCheckUtf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,json=optimizeFor,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + GoPackage *string `protobuf:"bytes,11,opt,name=go_package,json=goPackage" json:"go_package,omitempty"` + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,json=ccGenericServices,def=0" json:"cc_generic_services,omitempty"` + JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,json=javaGenericServices,def=0" json:"java_generic_services,omitempty"` + PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,json=pyGenericServices,def=0" json:"py_generic_services,omitempty"` + PhpGenericServices *bool `protobuf:"varint,42,opt,name=php_generic_services,json=phpGenericServices,def=0" json:"php_generic_services,omitempty"` + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,json=ccEnableArenas,def=0" json:"cc_enable_arenas,omitempty"` + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + ObjcClassPrefix *string `protobuf:"bytes,36,opt,name=objc_class_prefix,json=objcClassPrefix" json:"objc_class_prefix,omitempty"` + // Namespace for generated classes; defaults to the package. + CsharpNamespace *string `protobuf:"bytes,37,opt,name=csharp_namespace,json=csharpNamespace" json:"csharp_namespace,omitempty"` + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + SwiftPrefix *string `protobuf:"bytes,39,opt,name=swift_prefix,json=swiftPrefix" json:"swift_prefix,omitempty"` + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + PhpClassPrefix *string `protobuf:"bytes,40,opt,name=php_class_prefix,json=phpClassPrefix" json:"php_class_prefix,omitempty"` + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + PhpNamespace *string `protobuf:"bytes,41,opt,name=php_namespace,json=phpNamespace" json:"php_namespace,omitempty"` + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be used + // for determining the namespace. + PhpMetadataNamespace *string `protobuf:"bytes,44,opt,name=php_metadata_namespace,json=phpMetadataNamespace" json:"php_metadata_namespace,omitempty"` + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + RubyPackage *string `protobuf:"bytes,45,opt,name=ruby_package,json=rubyPackage" json:"ruby_package,omitempty"` + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileOptions) Reset() { *m = FileOptions{} } +func (m *FileOptions) String() string { return proto.CompactTextString(m) } +func (*FileOptions) ProtoMessage() {} +func (*FileOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{10} +} + +var extRange_FileOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FileOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FileOptions +} + +func (m *FileOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileOptions.Unmarshal(m, b) +} +func (m *FileOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileOptions.Marshal(b, m, deterministic) +} +func (m *FileOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileOptions.Merge(m, src) +} +func (m *FileOptions) XXX_Size() int { + return xxx_messageInfo_FileOptions.Size(m) +} +func (m *FileOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FileOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FileOptions proto.InternalMessageInfo + +const Default_FileOptions_JavaMultipleFiles bool = false +const Default_FileOptions_JavaStringCheckUtf8 bool = false +const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED +const Default_FileOptions_CcGenericServices bool = false +const Default_FileOptions_JavaGenericServices bool = false +const Default_FileOptions_PyGenericServices bool = false +const Default_FileOptions_PhpGenericServices bool = false +const Default_FileOptions_Deprecated bool = false +const Default_FileOptions_CcEnableArenas bool = false + +func (m *FileOptions) GetJavaPackage() string { + if m != nil && m.JavaPackage != nil { + return *m.JavaPackage + } + return "" +} + +func (m *FileOptions) GetJavaOuterClassname() string { + if m != nil && m.JavaOuterClassname != nil { + return *m.JavaOuterClassname + } + return "" +} + +func (m *FileOptions) GetJavaMultipleFiles() bool { + if m != nil && m.JavaMultipleFiles != nil { + return *m.JavaMultipleFiles + } + return Default_FileOptions_JavaMultipleFiles +} + +// Deprecated: Do not use. +func (m *FileOptions) GetJavaGenerateEqualsAndHash() bool { + if m != nil && m.JavaGenerateEqualsAndHash != nil { + return *m.JavaGenerateEqualsAndHash + } + return false +} + +func (m *FileOptions) GetJavaStringCheckUtf8() bool { + if m != nil && m.JavaStringCheckUtf8 != nil { + return *m.JavaStringCheckUtf8 + } + return Default_FileOptions_JavaStringCheckUtf8 +} + +func (m *FileOptions) GetOptimizeFor() FileOptions_OptimizeMode { + if m != nil && m.OptimizeFor != nil { + return *m.OptimizeFor + } + return Default_FileOptions_OptimizeFor +} + +func (m *FileOptions) GetGoPackage() string { + if m != nil && m.GoPackage != nil { + return *m.GoPackage + } + return "" +} + +func (m *FileOptions) GetCcGenericServices() bool { + if m != nil && m.CcGenericServices != nil { + return *m.CcGenericServices + } + return Default_FileOptions_CcGenericServices +} + +func (m *FileOptions) GetJavaGenericServices() bool { + if m != nil && m.JavaGenericServices != nil { + return *m.JavaGenericServices + } + return Default_FileOptions_JavaGenericServices +} + +func (m *FileOptions) GetPyGenericServices() bool { + if m != nil && m.PyGenericServices != nil { + return *m.PyGenericServices + } + return Default_FileOptions_PyGenericServices +} + +func (m *FileOptions) GetPhpGenericServices() bool { + if m != nil && m.PhpGenericServices != nil { + return *m.PhpGenericServices + } + return Default_FileOptions_PhpGenericServices +} + +func (m *FileOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FileOptions_Deprecated +} + +func (m *FileOptions) GetCcEnableArenas() bool { + if m != nil && m.CcEnableArenas != nil { + return *m.CcEnableArenas + } + return Default_FileOptions_CcEnableArenas +} + +func (m *FileOptions) GetObjcClassPrefix() string { + if m != nil && m.ObjcClassPrefix != nil { + return *m.ObjcClassPrefix + } + return "" +} + +func (m *FileOptions) GetCsharpNamespace() string { + if m != nil && m.CsharpNamespace != nil { + return *m.CsharpNamespace + } + return "" +} + +func (m *FileOptions) GetSwiftPrefix() string { + if m != nil && m.SwiftPrefix != nil { + return *m.SwiftPrefix + } + return "" +} + +func (m *FileOptions) GetPhpClassPrefix() string { + if m != nil && m.PhpClassPrefix != nil { + return *m.PhpClassPrefix + } + return "" +} + +func (m *FileOptions) GetPhpNamespace() string { + if m != nil && m.PhpNamespace != nil { + return *m.PhpNamespace + } + return "" +} + +func (m *FileOptions) GetPhpMetadataNamespace() string { + if m != nil && m.PhpMetadataNamespace != nil { + return *m.PhpMetadataNamespace + } + return "" +} + +func (m *FileOptions) GetRubyPackage() string { + if m != nil && m.RubyPackage != nil { + return *m.RubyPackage + } + return "" +} + +func (m *FileOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MessageOptions struct { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,json=messageSetWireFormat,def=0" json:"message_set_wire_format,omitempty"` + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,json=noStandardDescriptorAccessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry,json=mapEntry" json:"map_entry,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageOptions) Reset() { *m = MessageOptions{} } +func (m *MessageOptions) String() string { return proto.CompactTextString(m) } +func (*MessageOptions) ProtoMessage() {} +func (*MessageOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{11} +} + +var extRange_MessageOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MessageOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MessageOptions +} + +func (m *MessageOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageOptions.Unmarshal(m, b) +} +func (m *MessageOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageOptions.Marshal(b, m, deterministic) +} +func (m *MessageOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageOptions.Merge(m, src) +} +func (m *MessageOptions) XXX_Size() int { + return xxx_messageInfo_MessageOptions.Size(m) +} +func (m *MessageOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MessageOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageOptions proto.InternalMessageInfo + +const Default_MessageOptions_MessageSetWireFormat bool = false +const Default_MessageOptions_NoStandardDescriptorAccessor bool = false +const Default_MessageOptions_Deprecated bool = false + +func (m *MessageOptions) GetMessageSetWireFormat() bool { + if m != nil && m.MessageSetWireFormat != nil { + return *m.MessageSetWireFormat + } + return Default_MessageOptions_MessageSetWireFormat +} + +func (m *MessageOptions) GetNoStandardDescriptorAccessor() bool { + if m != nil && m.NoStandardDescriptorAccessor != nil { + return *m.NoStandardDescriptorAccessor + } + return Default_MessageOptions_NoStandardDescriptorAccessor +} + +func (m *MessageOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MessageOptions_Deprecated +} + +func (m *MessageOptions) GetMapEntry() bool { + if m != nil && m.MapEntry != nil { + return *m.MapEntry + } + return false +} + +func (m *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type FieldOptions struct { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"` + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + Jstype *FieldOptions_JSType `protobuf:"varint,6,opt,name=jstype,enum=google.protobuf.FieldOptions_JSType,def=0" json:"jstype,omitempty"` + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"` + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // For Google-internal migration only. Do not use. + Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldOptions) Reset() { *m = FieldOptions{} } +func (m *FieldOptions) String() string { return proto.CompactTextString(m) } +func (*FieldOptions) ProtoMessage() {} +func (*FieldOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{12} +} + +var extRange_FieldOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FieldOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FieldOptions +} + +func (m *FieldOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldOptions.Unmarshal(m, b) +} +func (m *FieldOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldOptions.Marshal(b, m, deterministic) +} +func (m *FieldOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldOptions.Merge(m, src) +} +func (m *FieldOptions) XXX_Size() int { + return xxx_messageInfo_FieldOptions.Size(m) +} +func (m *FieldOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FieldOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldOptions proto.InternalMessageInfo + +const Default_FieldOptions_Ctype FieldOptions_CType = FieldOptions_STRING +const Default_FieldOptions_Jstype FieldOptions_JSType = FieldOptions_JS_NORMAL +const Default_FieldOptions_Lazy bool = false +const Default_FieldOptions_Deprecated bool = false +const Default_FieldOptions_Weak bool = false + +func (m *FieldOptions) GetCtype() FieldOptions_CType { + if m != nil && m.Ctype != nil { + return *m.Ctype + } + return Default_FieldOptions_Ctype +} + +func (m *FieldOptions) GetPacked() bool { + if m != nil && m.Packed != nil { + return *m.Packed + } + return false +} + +func (m *FieldOptions) GetJstype() FieldOptions_JSType { + if m != nil && m.Jstype != nil { + return *m.Jstype + } + return Default_FieldOptions_Jstype +} + +func (m *FieldOptions) GetLazy() bool { + if m != nil && m.Lazy != nil { + return *m.Lazy + } + return Default_FieldOptions_Lazy +} + +func (m *FieldOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FieldOptions_Deprecated +} + +func (m *FieldOptions) GetWeak() bool { + if m != nil && m.Weak != nil { + return *m.Weak + } + return Default_FieldOptions_Weak +} + +func (m *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type OneofOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofOptions) Reset() { *m = OneofOptions{} } +func (m *OneofOptions) String() string { return proto.CompactTextString(m) } +func (*OneofOptions) ProtoMessage() {} +func (*OneofOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{13} +} + +var extRange_OneofOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*OneofOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OneofOptions +} + +func (m *OneofOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofOptions.Unmarshal(m, b) +} +func (m *OneofOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofOptions.Marshal(b, m, deterministic) +} +func (m *OneofOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofOptions.Merge(m, src) +} +func (m *OneofOptions) XXX_Size() int { + return xxx_messageInfo_OneofOptions.Size(m) +} +func (m *OneofOptions) XXX_DiscardUnknown() { + xxx_messageInfo_OneofOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofOptions proto.InternalMessageInfo + +func (m *OneofOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumOptions struct { + // Set this option to true to allow mapping different tag names to the same + // value. + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,json=allowAlias" json:"allow_alias,omitempty"` + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumOptions) Reset() { *m = EnumOptions{} } +func (m *EnumOptions) String() string { return proto.CompactTextString(m) } +func (*EnumOptions) ProtoMessage() {} +func (*EnumOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{14} +} + +var extRange_EnumOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumOptions +} + +func (m *EnumOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumOptions.Unmarshal(m, b) +} +func (m *EnumOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumOptions.Marshal(b, m, deterministic) +} +func (m *EnumOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumOptions.Merge(m, src) +} +func (m *EnumOptions) XXX_Size() int { + return xxx_messageInfo_EnumOptions.Size(m) +} +func (m *EnumOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumOptions proto.InternalMessageInfo + +const Default_EnumOptions_Deprecated bool = false + +func (m *EnumOptions) GetAllowAlias() bool { + if m != nil && m.AllowAlias != nil { + return *m.AllowAlias + } + return false +} + +func (m *EnumOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumOptions_Deprecated +} + +func (m *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumValueOptions struct { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } +func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } +func (*EnumValueOptions) ProtoMessage() {} +func (*EnumValueOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{15} +} + +var extRange_EnumValueOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumValueOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumValueOptions +} + +func (m *EnumValueOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueOptions.Unmarshal(m, b) +} +func (m *EnumValueOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueOptions.Marshal(b, m, deterministic) +} +func (m *EnumValueOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueOptions.Merge(m, src) +} +func (m *EnumValueOptions) XXX_Size() int { + return xxx_messageInfo_EnumValueOptions.Size(m) +} +func (m *EnumValueOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueOptions proto.InternalMessageInfo + +const Default_EnumValueOptions_Deprecated bool = false + +func (m *EnumValueOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumValueOptions_Deprecated +} + +func (m *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type ServiceOptions struct { + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } +func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } +func (*ServiceOptions) ProtoMessage() {} +func (*ServiceOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{16} +} + +var extRange_ServiceOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ServiceOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ServiceOptions +} + +func (m *ServiceOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceOptions.Unmarshal(m, b) +} +func (m *ServiceOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceOptions.Marshal(b, m, deterministic) +} +func (m *ServiceOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceOptions.Merge(m, src) +} +func (m *ServiceOptions) XXX_Size() int { + return xxx_messageInfo_ServiceOptions.Size(m) +} +func (m *ServiceOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceOptions proto.InternalMessageInfo + +const Default_ServiceOptions_Deprecated bool = false + +func (m *ServiceOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_ServiceOptions_Deprecated +} + +func (m *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MethodOptions struct { + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + IdempotencyLevel *MethodOptions_IdempotencyLevel `protobuf:"varint,34,opt,name=idempotency_level,json=idempotencyLevel,enum=google.protobuf.MethodOptions_IdempotencyLevel,def=0" json:"idempotency_level,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodOptions) Reset() { *m = MethodOptions{} } +func (m *MethodOptions) String() string { return proto.CompactTextString(m) } +func (*MethodOptions) ProtoMessage() {} +func (*MethodOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{17} +} + +var extRange_MethodOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MethodOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MethodOptions +} + +func (m *MethodOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodOptions.Unmarshal(m, b) +} +func (m *MethodOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodOptions.Marshal(b, m, deterministic) +} +func (m *MethodOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodOptions.Merge(m, src) +} +func (m *MethodOptions) XXX_Size() int { + return xxx_messageInfo_MethodOptions.Size(m) +} +func (m *MethodOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MethodOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodOptions proto.InternalMessageInfo + +const Default_MethodOptions_Deprecated bool = false +const Default_MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel = MethodOptions_IDEMPOTENCY_UNKNOWN + +func (m *MethodOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MethodOptions_Deprecated +} + +func (m *MethodOptions) GetIdempotencyLevel() MethodOptions_IdempotencyLevel { + if m != nil && m.IdempotencyLevel != nil { + return *m.IdempotencyLevel + } + return Default_MethodOptions_IdempotencyLevel +} + +func (m *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +type UninterpretedOption struct { + Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value,json=identifierValue" json:"identifier_value,omitempty"` + PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value,json=positiveIntValue" json:"positive_int_value,omitempty"` + NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value,json=negativeIntValue" json:"negative_int_value,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` + StringValue []byte `protobuf:"bytes,7,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` + AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value,json=aggregateValue" json:"aggregate_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } +func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption) ProtoMessage() {} +func (*UninterpretedOption) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{18} +} +func (m *UninterpretedOption) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption.Unmarshal(m, b) +} +func (m *UninterpretedOption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption.Merge(m, src) +} +func (m *UninterpretedOption) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption.Size(m) +} +func (m *UninterpretedOption) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption proto.InternalMessageInfo + +func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart { + if m != nil { + return m.Name + } + return nil +} + +func (m *UninterpretedOption) GetIdentifierValue() string { + if m != nil && m.IdentifierValue != nil { + return *m.IdentifierValue + } + return "" +} + +func (m *UninterpretedOption) GetPositiveIntValue() uint64 { + if m != nil && m.PositiveIntValue != nil { + return *m.PositiveIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetNegativeIntValue() int64 { + if m != nil && m.NegativeIntValue != nil { + return *m.NegativeIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetDoubleValue() float64 { + if m != nil && m.DoubleValue != nil { + return *m.DoubleValue + } + return 0 +} + +func (m *UninterpretedOption) GetStringValue() []byte { + if m != nil { + return m.StringValue + } + return nil +} + +func (m *UninterpretedOption) GetAggregateValue() string { + if m != nil && m.AggregateValue != nil { + return *m.AggregateValue + } + return "" +} + +// The name of the uninterpreted option. Each string represents a segment in +// a dot-separated name. is_extension is true iff a segment represents an +// extension (denoted with parentheses in options specs in .proto files). +// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents +// "foo.(bar.baz).qux". +type UninterpretedOption_NamePart struct { + NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOption_NamePart{} } +func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption_NamePart) ProtoMessage() {} +func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{18, 0} +} +func (m *UninterpretedOption_NamePart) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption_NamePart.Unmarshal(m, b) +} +func (m *UninterpretedOption_NamePart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption_NamePart.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption_NamePart) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption_NamePart.Merge(m, src) +} +func (m *UninterpretedOption_NamePart) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption_NamePart.Size(m) +} +func (m *UninterpretedOption_NamePart) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption_NamePart.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption_NamePart proto.InternalMessageInfo + +func (m *UninterpretedOption_NamePart) GetNamePart() string { + if m != nil && m.NamePart != nil { + return *m.NamePart + } + return "" +} + +func (m *UninterpretedOption_NamePart) GetIsExtension() bool { + if m != nil && m.IsExtension != nil { + return *m.IsExtension + } + return false +} + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +type SourceCodeInfo struct { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } +func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo) ProtoMessage() {} +func (*SourceCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{19} +} +func (m *SourceCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo.Unmarshal(m, b) +} +func (m *SourceCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo.Merge(m, src) +} +func (m *SourceCodeInfo) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo.Size(m) +} +func (m *SourceCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo proto.InternalMessageInfo + +func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { + if m != nil { + return m.Location + } + return nil +} + +type SourceCodeInfo_Location struct { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + Span []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"` + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` + TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` + LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} } +func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo_Location) ProtoMessage() {} +func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{19, 0} +} +func (m *SourceCodeInfo_Location) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo_Location.Unmarshal(m, b) +} +func (m *SourceCodeInfo_Location) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo_Location.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo_Location) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo_Location.Merge(m, src) +} +func (m *SourceCodeInfo_Location) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo_Location.Size(m) +} +func (m *SourceCodeInfo_Location) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo_Location.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo_Location proto.InternalMessageInfo + +func (m *SourceCodeInfo_Location) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *SourceCodeInfo_Location) GetSpan() []int32 { + if m != nil { + return m.Span + } + return nil +} + +func (m *SourceCodeInfo_Location) GetLeadingComments() string { + if m != nil && m.LeadingComments != nil { + return *m.LeadingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetTrailingComments() string { + if m != nil && m.TrailingComments != nil { + return *m.TrailingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetLeadingDetachedComments() []string { + if m != nil { + return m.LeadingDetachedComments + } + return nil +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +type GeneratedCodeInfo struct { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + Annotation []*GeneratedCodeInfo_Annotation `protobuf:"bytes,1,rep,name=annotation" json:"annotation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo) Reset() { *m = GeneratedCodeInfo{} } +func (m *GeneratedCodeInfo) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo) ProtoMessage() {} +func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{20} +} +func (m *GeneratedCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo.Merge(m, src) +} +func (m *GeneratedCodeInfo) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo.Size(m) +} +func (m *GeneratedCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo proto.InternalMessageInfo + +func (m *GeneratedCodeInfo) GetAnnotation() []*GeneratedCodeInfo_Annotation { + if m != nil { + return m.Annotation + } + return nil +} + +type GeneratedCodeInfo_Annotation struct { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Identifies the filesystem path to the original source .proto. + SourceFile *string `protobuf:"bytes,2,opt,name=source_file,json=sourceFile" json:"source_file,omitempty"` + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + Begin *int32 `protobuf:"varint,3,opt,name=begin" json:"begin,omitempty"` + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo_Annotation) Reset() { *m = GeneratedCodeInfo_Annotation{} } +func (m *GeneratedCodeInfo_Annotation) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo_Annotation) ProtoMessage() {} +func (*GeneratedCodeInfo_Annotation) Descriptor() ([]byte, []int) { + return fileDescriptor_308767df5ffe18af, []int{20, 0} +} +func (m *GeneratedCodeInfo_Annotation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo_Annotation.Merge(m, src) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Size(m) +} +func (m *GeneratedCodeInfo_Annotation) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo_Annotation.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo_Annotation proto.InternalMessageInfo + +func (m *GeneratedCodeInfo_Annotation) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *GeneratedCodeInfo_Annotation) GetSourceFile() string { + if m != nil && m.SourceFile != nil { + return *m.SourceFile + } + return "" +} + +func (m *GeneratedCodeInfo_Annotation) GetBegin() int32 { + if m != nil && m.Begin != nil { + return *m.Begin + } + return 0 +} + +func (m *GeneratedCodeInfo_Annotation) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func init() { + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Type", FieldDescriptorProto_Type_name, FieldDescriptorProto_Type_value) + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Label", FieldDescriptorProto_Label_name, FieldDescriptorProto_Label_value) + proto.RegisterEnum("google.protobuf.FileOptions_OptimizeMode", FileOptions_OptimizeMode_name, FileOptions_OptimizeMode_value) + proto.RegisterEnum("google.protobuf.FieldOptions_CType", FieldOptions_CType_name, FieldOptions_CType_value) + proto.RegisterEnum("google.protobuf.FieldOptions_JSType", FieldOptions_JSType_name, FieldOptions_JSType_value) + proto.RegisterEnum("google.protobuf.MethodOptions_IdempotencyLevel", MethodOptions_IdempotencyLevel_name, MethodOptions_IdempotencyLevel_value) + proto.RegisterType((*FileDescriptorSet)(nil), "google.protobuf.FileDescriptorSet") + proto.RegisterType((*FileDescriptorProto)(nil), "google.protobuf.FileDescriptorProto") + proto.RegisterType((*DescriptorProto)(nil), "google.protobuf.DescriptorProto") + proto.RegisterType((*DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange") + proto.RegisterType((*DescriptorProto_ReservedRange)(nil), "google.protobuf.DescriptorProto.ReservedRange") + proto.RegisterType((*ExtensionRangeOptions)(nil), "google.protobuf.ExtensionRangeOptions") + proto.RegisterType((*FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto") + proto.RegisterType((*OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto") + proto.RegisterType((*EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto") + proto.RegisterType((*EnumDescriptorProto_EnumReservedRange)(nil), "google.protobuf.EnumDescriptorProto.EnumReservedRange") + proto.RegisterType((*EnumValueDescriptorProto)(nil), "google.protobuf.EnumValueDescriptorProto") + proto.RegisterType((*ServiceDescriptorProto)(nil), "google.protobuf.ServiceDescriptorProto") + proto.RegisterType((*MethodDescriptorProto)(nil), "google.protobuf.MethodDescriptorProto") + proto.RegisterType((*FileOptions)(nil), "google.protobuf.FileOptions") + proto.RegisterType((*MessageOptions)(nil), "google.protobuf.MessageOptions") + proto.RegisterType((*FieldOptions)(nil), "google.protobuf.FieldOptions") + proto.RegisterType((*OneofOptions)(nil), "google.protobuf.OneofOptions") + proto.RegisterType((*EnumOptions)(nil), "google.protobuf.EnumOptions") + proto.RegisterType((*EnumValueOptions)(nil), "google.protobuf.EnumValueOptions") + proto.RegisterType((*ServiceOptions)(nil), "google.protobuf.ServiceOptions") + proto.RegisterType((*MethodOptions)(nil), "google.protobuf.MethodOptions") + proto.RegisterType((*UninterpretedOption)(nil), "google.protobuf.UninterpretedOption") + proto.RegisterType((*UninterpretedOption_NamePart)(nil), "google.protobuf.UninterpretedOption.NamePart") + proto.RegisterType((*SourceCodeInfo)(nil), "google.protobuf.SourceCodeInfo") + proto.RegisterType((*SourceCodeInfo_Location)(nil), "google.protobuf.SourceCodeInfo.Location") + proto.RegisterType((*GeneratedCodeInfo)(nil), "google.protobuf.GeneratedCodeInfo") + proto.RegisterType((*GeneratedCodeInfo_Annotation)(nil), "google.protobuf.GeneratedCodeInfo.Annotation") +} + +func init() { proto.RegisterFile("descriptor.proto", fileDescriptor_308767df5ffe18af) } + +var fileDescriptor_308767df5ffe18af = []byte{ + // 2522 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xcd, 0x6f, 0xdb, 0xc8, + 0x15, 0x5f, 0x7d, 0x5a, 0x7a, 0x92, 0x65, 0x7a, 0xec, 0x75, 0x18, 0xef, 0x47, 0x1c, 0xed, 0x66, + 0xe3, 0x24, 0xbb, 0xca, 0xc2, 0x49, 0x9c, 0xac, 0x53, 0x6c, 0x2b, 0x4b, 0x8c, 0x57, 0xa9, 0xbe, + 0x4a, 0xc9, 0xdd, 0x64, 0x8b, 0x82, 0x18, 0x93, 0x23, 0x89, 0x09, 0x45, 0x72, 0x49, 0x2a, 0x89, + 0x83, 0x1e, 0x02, 0xf4, 0x54, 0xa0, 0x7f, 0x40, 0x51, 0x14, 0x3d, 0xf4, 0xb2, 0x40, 0xff, 0x80, + 0x02, 0xed, 0xbd, 0xd7, 0x02, 0xbd, 0xf7, 0x50, 0xa0, 0x05, 0xda, 0x3f, 0xa1, 0xc7, 0x62, 0x66, + 0x48, 0x8a, 0xd4, 0x47, 0xe2, 0x5d, 0x20, 0xd9, 0x93, 0x3d, 0xef, 0xfd, 0xde, 0x9b, 0x37, 0x8f, + 0xbf, 0x79, 0xf3, 0x66, 0x04, 0x82, 0x46, 0x5c, 0xd5, 0xd1, 0x6d, 0xcf, 0x72, 0x2a, 0xb6, 0x63, + 0x79, 0x16, 0x5a, 0x1b, 0x5a, 0xd6, 0xd0, 0x20, 0x7c, 0x74, 0x32, 0x19, 0x94, 0x5b, 0xb0, 0x7e, + 0x4f, 0x37, 0x48, 0x3d, 0x04, 0xf6, 0x88, 0x87, 0xee, 0x40, 0x7a, 0xa0, 0x1b, 0x44, 0x4c, 0xec, + 0xa4, 0x76, 0x0b, 0x7b, 0x1f, 0x56, 0x66, 0x8c, 0x2a, 0x71, 0x8b, 0x2e, 0x15, 0xcb, 0xcc, 0xa2, + 0xfc, 0xef, 0x34, 0x6c, 0x2c, 0xd0, 0x22, 0x04, 0x69, 0x13, 0x8f, 0xa9, 0xc7, 0xc4, 0x6e, 0x5e, + 0x66, 0xff, 0x23, 0x11, 0x56, 0x6c, 0xac, 0x3e, 0xc6, 0x43, 0x22, 0x26, 0x99, 0x38, 0x18, 0xa2, + 0xf7, 0x01, 0x34, 0x62, 0x13, 0x53, 0x23, 0xa6, 0x7a, 0x2a, 0xa6, 0x76, 0x52, 0xbb, 0x79, 0x39, + 0x22, 0x41, 0xd7, 0x60, 0xdd, 0x9e, 0x9c, 0x18, 0xba, 0xaa, 0x44, 0x60, 0xb0, 0x93, 0xda, 0xcd, + 0xc8, 0x02, 0x57, 0xd4, 0xa7, 0xe0, 0xcb, 0xb0, 0xf6, 0x94, 0xe0, 0xc7, 0x51, 0x68, 0x81, 0x41, + 0x4b, 0x54, 0x1c, 0x01, 0xd6, 0xa0, 0x38, 0x26, 0xae, 0x8b, 0x87, 0x44, 0xf1, 0x4e, 0x6d, 0x22, + 0xa6, 0xd9, 0xea, 0x77, 0xe6, 0x56, 0x3f, 0xbb, 0xf2, 0x82, 0x6f, 0xd5, 0x3f, 0xb5, 0x09, 0xaa, + 0x42, 0x9e, 0x98, 0x93, 0x31, 0xf7, 0x90, 0x59, 0x92, 0x3f, 0xc9, 0x9c, 0x8c, 0x67, 0xbd, 0xe4, + 0xa8, 0x99, 0xef, 0x62, 0xc5, 0x25, 0xce, 0x13, 0x5d, 0x25, 0x62, 0x96, 0x39, 0xb8, 0x3c, 0xe7, + 0xa0, 0xc7, 0xf5, 0xb3, 0x3e, 0x02, 0x3b, 0x54, 0x83, 0x3c, 0x79, 0xe6, 0x11, 0xd3, 0xd5, 0x2d, + 0x53, 0x5c, 0x61, 0x4e, 0x2e, 0x2d, 0xf8, 0x8a, 0xc4, 0xd0, 0x66, 0x5d, 0x4c, 0xed, 0xd0, 0x3e, + 0xac, 0x58, 0xb6, 0xa7, 0x5b, 0xa6, 0x2b, 0xe6, 0x76, 0x12, 0xbb, 0x85, 0xbd, 0x77, 0x17, 0x12, + 0xa1, 0xc3, 0x31, 0x72, 0x00, 0x46, 0x0d, 0x10, 0x5c, 0x6b, 0xe2, 0xa8, 0x44, 0x51, 0x2d, 0x8d, + 0x28, 0xba, 0x39, 0xb0, 0xc4, 0x3c, 0x73, 0x70, 0x61, 0x7e, 0x21, 0x0c, 0x58, 0xb3, 0x34, 0xd2, + 0x30, 0x07, 0x96, 0x5c, 0x72, 0x63, 0x63, 0xb4, 0x05, 0x59, 0xf7, 0xd4, 0xf4, 0xf0, 0x33, 0xb1, + 0xc8, 0x18, 0xe2, 0x8f, 0xca, 0x7f, 0xce, 0xc2, 0xda, 0x59, 0x28, 0x76, 0x17, 0x32, 0x03, 0xba, + 0x4a, 0x31, 0xf9, 0x6d, 0x72, 0xc0, 0x6d, 0xe2, 0x49, 0xcc, 0x7e, 0xc7, 0x24, 0x56, 0xa1, 0x60, + 0x12, 0xd7, 0x23, 0x1a, 0x67, 0x44, 0xea, 0x8c, 0x9c, 0x02, 0x6e, 0x34, 0x4f, 0xa9, 0xf4, 0x77, + 0xa2, 0xd4, 0x03, 0x58, 0x0b, 0x43, 0x52, 0x1c, 0x6c, 0x0e, 0x03, 0x6e, 0x5e, 0x7f, 0x55, 0x24, + 0x15, 0x29, 0xb0, 0x93, 0xa9, 0x99, 0x5c, 0x22, 0xb1, 0x31, 0xaa, 0x03, 0x58, 0x26, 0xb1, 0x06, + 0x8a, 0x46, 0x54, 0x43, 0xcc, 0x2d, 0xc9, 0x52, 0x87, 0x42, 0xe6, 0xb2, 0x64, 0x71, 0xa9, 0x6a, + 0xa0, 0xcf, 0xa6, 0x54, 0x5b, 0x59, 0xc2, 0x94, 0x16, 0xdf, 0x64, 0x73, 0x6c, 0x3b, 0x86, 0x92, + 0x43, 0x28, 0xef, 0x89, 0xe6, 0xaf, 0x2c, 0xcf, 0x82, 0xa8, 0xbc, 0x72, 0x65, 0xb2, 0x6f, 0xc6, + 0x17, 0xb6, 0xea, 0x44, 0x87, 0xe8, 0x03, 0x08, 0x05, 0x0a, 0xa3, 0x15, 0xb0, 0x2a, 0x54, 0x0c, + 0x84, 0x6d, 0x3c, 0x26, 0xdb, 0xcf, 0xa1, 0x14, 0x4f, 0x0f, 0xda, 0x84, 0x8c, 0xeb, 0x61, 0xc7, + 0x63, 0x2c, 0xcc, 0xc8, 0x7c, 0x80, 0x04, 0x48, 0x11, 0x53, 0x63, 0x55, 0x2e, 0x23, 0xd3, 0x7f, + 0xd1, 0x8f, 0xa6, 0x0b, 0x4e, 0xb1, 0x05, 0x7f, 0x34, 0xff, 0x45, 0x63, 0x9e, 0x67, 0xd7, 0xbd, + 0x7d, 0x1b, 0x56, 0x63, 0x0b, 0x38, 0xeb, 0xd4, 0xe5, 0x5f, 0xc0, 0xdb, 0x0b, 0x5d, 0xa3, 0x07, + 0xb0, 0x39, 0x31, 0x75, 0xd3, 0x23, 0x8e, 0xed, 0x10, 0xca, 0x58, 0x3e, 0x95, 0xf8, 0x9f, 0x95, + 0x25, 0x9c, 0x3b, 0x8e, 0xa2, 0xb9, 0x17, 0x79, 0x63, 0x32, 0x2f, 0xbc, 0x9a, 0xcf, 0xfd, 0x77, + 0x45, 0x78, 0xf1, 0xe2, 0xc5, 0x8b, 0x64, 0xf9, 0x37, 0x59, 0xd8, 0x5c, 0xb4, 0x67, 0x16, 0x6e, + 0xdf, 0x2d, 0xc8, 0x9a, 0x93, 0xf1, 0x09, 0x71, 0x58, 0x92, 0x32, 0xb2, 0x3f, 0x42, 0x55, 0xc8, + 0x18, 0xf8, 0x84, 0x18, 0x62, 0x7a, 0x27, 0xb1, 0x5b, 0xda, 0xbb, 0x76, 0xa6, 0x5d, 0x59, 0x69, + 0x52, 0x13, 0x99, 0x5b, 0xa2, 0xcf, 0x21, 0xed, 0x97, 0x68, 0xea, 0xe1, 0xea, 0xd9, 0x3c, 0xd0, + 0xbd, 0x24, 0x33, 0x3b, 0xf4, 0x0e, 0xe4, 0xe9, 0x5f, 0xce, 0x8d, 0x2c, 0x8b, 0x39, 0x47, 0x05, + 0x94, 0x17, 0x68, 0x1b, 0x72, 0x6c, 0x9b, 0x68, 0x24, 0x38, 0xda, 0xc2, 0x31, 0x25, 0x96, 0x46, + 0x06, 0x78, 0x62, 0x78, 0xca, 0x13, 0x6c, 0x4c, 0x08, 0x23, 0x7c, 0x5e, 0x2e, 0xfa, 0xc2, 0x9f, + 0x52, 0x19, 0xba, 0x00, 0x05, 0xbe, 0xab, 0x74, 0x53, 0x23, 0xcf, 0x58, 0xf5, 0xcc, 0xc8, 0x7c, + 0xa3, 0x35, 0xa8, 0x84, 0x4e, 0xff, 0xc8, 0xb5, 0xcc, 0x80, 0x9a, 0x6c, 0x0a, 0x2a, 0x60, 0xd3, + 0xdf, 0x9e, 0x2d, 0xdc, 0xef, 0x2d, 0x5e, 0xde, 0x2c, 0xa7, 0xca, 0x7f, 0x4a, 0x42, 0x9a, 0xd5, + 0x8b, 0x35, 0x28, 0xf4, 0x1f, 0x76, 0x25, 0xa5, 0xde, 0x39, 0x3e, 0x6c, 0x4a, 0x42, 0x02, 0x95, + 0x00, 0x98, 0xe0, 0x5e, 0xb3, 0x53, 0xed, 0x0b, 0xc9, 0x70, 0xdc, 0x68, 0xf7, 0xf7, 0x6f, 0x0a, + 0xa9, 0xd0, 0xe0, 0x98, 0x0b, 0xd2, 0x51, 0xc0, 0x8d, 0x3d, 0x21, 0x83, 0x04, 0x28, 0x72, 0x07, + 0x8d, 0x07, 0x52, 0x7d, 0xff, 0xa6, 0x90, 0x8d, 0x4b, 0x6e, 0xec, 0x09, 0x2b, 0x68, 0x15, 0xf2, + 0x4c, 0x72, 0xd8, 0xe9, 0x34, 0x85, 0x5c, 0xe8, 0xb3, 0xd7, 0x97, 0x1b, 0xed, 0x23, 0x21, 0x1f, + 0xfa, 0x3c, 0x92, 0x3b, 0xc7, 0x5d, 0x01, 0x42, 0x0f, 0x2d, 0xa9, 0xd7, 0xab, 0x1e, 0x49, 0x42, + 0x21, 0x44, 0x1c, 0x3e, 0xec, 0x4b, 0x3d, 0xa1, 0x18, 0x0b, 0xeb, 0xc6, 0x9e, 0xb0, 0x1a, 0x4e, + 0x21, 0xb5, 0x8f, 0x5b, 0x42, 0x09, 0xad, 0xc3, 0x2a, 0x9f, 0x22, 0x08, 0x62, 0x6d, 0x46, 0xb4, + 0x7f, 0x53, 0x10, 0xa6, 0x81, 0x70, 0x2f, 0xeb, 0x31, 0xc1, 0xfe, 0x4d, 0x01, 0x95, 0x6b, 0x90, + 0x61, 0xec, 0x42, 0x08, 0x4a, 0xcd, 0xea, 0xa1, 0xd4, 0x54, 0x3a, 0xdd, 0x7e, 0xa3, 0xd3, 0xae, + 0x36, 0x85, 0xc4, 0x54, 0x26, 0x4b, 0x3f, 0x39, 0x6e, 0xc8, 0x52, 0x5d, 0x48, 0x46, 0x65, 0x5d, + 0xa9, 0xda, 0x97, 0xea, 0x42, 0xaa, 0xac, 0xc2, 0xe6, 0xa2, 0x3a, 0xb9, 0x70, 0x67, 0x44, 0x3e, + 0x71, 0x72, 0xc9, 0x27, 0x66, 0xbe, 0xe6, 0x3e, 0xf1, 0xbf, 0x92, 0xb0, 0xb1, 0xe0, 0xac, 0x58, + 0x38, 0xc9, 0x0f, 0x21, 0xc3, 0x29, 0xca, 0x4f, 0xcf, 0x2b, 0x0b, 0x0f, 0x1d, 0x46, 0xd8, 0xb9, + 0x13, 0x94, 0xd9, 0x45, 0x3b, 0x88, 0xd4, 0x92, 0x0e, 0x82, 0xba, 0x98, 0xab, 0xe9, 0x3f, 0x9f, + 0xab, 0xe9, 0xfc, 0xd8, 0xdb, 0x3f, 0xcb, 0xb1, 0xc7, 0x64, 0xdf, 0xae, 0xb6, 0x67, 0x16, 0xd4, + 0xf6, 0xbb, 0xb0, 0x3e, 0xe7, 0xe8, 0xcc, 0x35, 0xf6, 0x97, 0x09, 0x10, 0x97, 0x25, 0xe7, 0x15, + 0x95, 0x2e, 0x19, 0xab, 0x74, 0x77, 0x67, 0x33, 0x78, 0x71, 0xf9, 0x47, 0x98, 0xfb, 0xd6, 0xdf, + 0x24, 0x60, 0x6b, 0x71, 0xa7, 0xb8, 0x30, 0x86, 0xcf, 0x21, 0x3b, 0x26, 0xde, 0xc8, 0x0a, 0xba, + 0xa5, 0x8f, 0x16, 0x9c, 0xc1, 0x54, 0x3d, 0xfb, 0xb1, 0x7d, 0xab, 0xe8, 0x21, 0x9e, 0x5a, 0xd6, + 0xee, 0xf1, 0x68, 0xe6, 0x22, 0xfd, 0x55, 0x12, 0xde, 0x5e, 0xe8, 0x7c, 0x61, 0xa0, 0xef, 0x01, + 0xe8, 0xa6, 0x3d, 0xf1, 0x78, 0x47, 0xc4, 0x0b, 0x6c, 0x9e, 0x49, 0x58, 0xf1, 0xa2, 0xc5, 0x73, + 0xe2, 0x85, 0xfa, 0x14, 0xd3, 0x03, 0x17, 0x31, 0xc0, 0x9d, 0x69, 0xa0, 0x69, 0x16, 0xe8, 0xfb, + 0x4b, 0x56, 0x3a, 0x47, 0xcc, 0x4f, 0x41, 0x50, 0x0d, 0x9d, 0x98, 0x9e, 0xe2, 0x7a, 0x0e, 0xc1, + 0x63, 0xdd, 0x1c, 0xb2, 0x13, 0x24, 0x77, 0x90, 0x19, 0x60, 0xc3, 0x25, 0xf2, 0x1a, 0x57, 0xf7, + 0x02, 0x2d, 0xb5, 0x60, 0x04, 0x72, 0x22, 0x16, 0xd9, 0x98, 0x05, 0x57, 0x87, 0x16, 0xe5, 0x5f, + 0xe7, 0xa1, 0x10, 0xe9, 0xab, 0xd1, 0x45, 0x28, 0x3e, 0xc2, 0x4f, 0xb0, 0x12, 0xdc, 0x95, 0x78, + 0x26, 0x0a, 0x54, 0xd6, 0xf5, 0xef, 0x4b, 0x9f, 0xc2, 0x26, 0x83, 0x58, 0x13, 0x8f, 0x38, 0x8a, + 0x6a, 0x60, 0xd7, 0x65, 0x49, 0xcb, 0x31, 0x28, 0xa2, 0xba, 0x0e, 0x55, 0xd5, 0x02, 0x0d, 0xba, + 0x05, 0x1b, 0xcc, 0x62, 0x3c, 0x31, 0x3c, 0xdd, 0x36, 0x88, 0x42, 0x6f, 0x6f, 0x2e, 0x3b, 0x49, + 0xc2, 0xc8, 0xd6, 0x29, 0xa2, 0xe5, 0x03, 0x68, 0x44, 0x2e, 0xaa, 0xc3, 0x7b, 0xcc, 0x6c, 0x48, + 0x4c, 0xe2, 0x60, 0x8f, 0x28, 0xe4, 0xeb, 0x09, 0x36, 0x5c, 0x05, 0x9b, 0x9a, 0x32, 0xc2, 0xee, + 0x48, 0xdc, 0xa4, 0x0e, 0x0e, 0x93, 0x62, 0x42, 0x3e, 0x4f, 0x81, 0x47, 0x3e, 0x4e, 0x62, 0xb0, + 0xaa, 0xa9, 0x7d, 0x81, 0xdd, 0x11, 0x3a, 0x80, 0x2d, 0xe6, 0xc5, 0xf5, 0x1c, 0xdd, 0x1c, 0x2a, + 0xea, 0x88, 0xa8, 0x8f, 0x95, 0x89, 0x37, 0xb8, 0x23, 0xbe, 0x13, 0x9d, 0x9f, 0x45, 0xd8, 0x63, + 0x98, 0x1a, 0x85, 0x1c, 0x7b, 0x83, 0x3b, 0xa8, 0x07, 0x45, 0xfa, 0x31, 0xc6, 0xfa, 0x73, 0xa2, + 0x0c, 0x2c, 0x87, 0x1d, 0x8d, 0xa5, 0x05, 0xa5, 0x29, 0x92, 0xc1, 0x4a, 0xc7, 0x37, 0x68, 0x59, + 0x1a, 0x39, 0xc8, 0xf4, 0xba, 0x92, 0x54, 0x97, 0x0b, 0x81, 0x97, 0x7b, 0x96, 0x43, 0x09, 0x35, + 0xb4, 0xc2, 0x04, 0x17, 0x38, 0xa1, 0x86, 0x56, 0x90, 0xde, 0x5b, 0xb0, 0xa1, 0xaa, 0x7c, 0xcd, + 0xba, 0xaa, 0xf8, 0x77, 0x2c, 0x57, 0x14, 0x62, 0xc9, 0x52, 0xd5, 0x23, 0x0e, 0xf0, 0x39, 0xee, + 0xa2, 0xcf, 0xe0, 0xed, 0x69, 0xb2, 0xa2, 0x86, 0xeb, 0x73, 0xab, 0x9c, 0x35, 0xbd, 0x05, 0x1b, + 0xf6, 0xe9, 0xbc, 0x21, 0x8a, 0xcd, 0x68, 0x9f, 0xce, 0x9a, 0xdd, 0x86, 0x4d, 0x7b, 0x64, 0xcf, + 0xdb, 0x5d, 0x8d, 0xda, 0x21, 0x7b, 0x64, 0xcf, 0x1a, 0x5e, 0x62, 0x17, 0x6e, 0x87, 0xa8, 0xd8, + 0x23, 0x9a, 0x78, 0x2e, 0x0a, 0x8f, 0x28, 0xd0, 0x75, 0x10, 0x54, 0x55, 0x21, 0x26, 0x3e, 0x31, + 0x88, 0x82, 0x1d, 0x62, 0x62, 0x57, 0xbc, 0x10, 0x05, 0x97, 0x54, 0x55, 0x62, 0xda, 0x2a, 0x53, + 0xa2, 0xab, 0xb0, 0x6e, 0x9d, 0x3c, 0x52, 0x39, 0x25, 0x15, 0xdb, 0x21, 0x03, 0xfd, 0x99, 0xf8, + 0x21, 0xcb, 0xef, 0x1a, 0x55, 0x30, 0x42, 0x76, 0x99, 0x18, 0x5d, 0x01, 0x41, 0x75, 0x47, 0xd8, + 0xb1, 0x59, 0x4d, 0x76, 0x6d, 0xac, 0x12, 0xf1, 0x12, 0x87, 0x72, 0x79, 0x3b, 0x10, 0xd3, 0x2d, + 0xe1, 0x3e, 0xd5, 0x07, 0x5e, 0xe0, 0xf1, 0x32, 0xdf, 0x12, 0x4c, 0xe6, 0x7b, 0xdb, 0x05, 0x81, + 0xa6, 0x22, 0x36, 0xf1, 0x2e, 0x83, 0x95, 0xec, 0x91, 0x1d, 0x9d, 0xf7, 0x03, 0x58, 0xa5, 0xc8, + 0xe9, 0xa4, 0x57, 0x78, 0x43, 0x66, 0x8f, 0x22, 0x33, 0xde, 0x84, 0x2d, 0x0a, 0x1a, 0x13, 0x0f, + 0x6b, 0xd8, 0xc3, 0x11, 0xf4, 0xc7, 0x0c, 0x4d, 0xf3, 0xde, 0xf2, 0x95, 0xb1, 0x38, 0x9d, 0xc9, + 0xc9, 0x69, 0xc8, 0xac, 0x4f, 0x78, 0x9c, 0x54, 0x16, 0x70, 0xeb, 0xb5, 0x35, 0xdd, 0xe5, 0x03, + 0x28, 0x46, 0x89, 0x8f, 0xf2, 0xc0, 0xa9, 0x2f, 0x24, 0x68, 0x17, 0x54, 0xeb, 0xd4, 0x69, 0xff, + 0xf2, 0x95, 0x24, 0x24, 0x69, 0x1f, 0xd5, 0x6c, 0xf4, 0x25, 0x45, 0x3e, 0x6e, 0xf7, 0x1b, 0x2d, + 0x49, 0x48, 0x45, 0x1b, 0xf6, 0xbf, 0x26, 0xa1, 0x14, 0xbf, 0x7b, 0xa1, 0x1f, 0xc0, 0xb9, 0xe0, + 0xa1, 0xc4, 0x25, 0x9e, 0xf2, 0x54, 0x77, 0xd8, 0x5e, 0x1c, 0x63, 0x7e, 0x2e, 0x86, 0x6c, 0xd8, + 0xf4, 0x51, 0x3d, 0xe2, 0x7d, 0xa9, 0x3b, 0x74, 0xa7, 0x8d, 0xb1, 0x87, 0x9a, 0x70, 0xc1, 0xb4, + 0x14, 0xd7, 0xc3, 0xa6, 0x86, 0x1d, 0x4d, 0x99, 0x3e, 0x51, 0x29, 0x58, 0x55, 0x89, 0xeb, 0x5a, + 0xfc, 0x0c, 0x0c, 0xbd, 0xbc, 0x6b, 0x5a, 0x3d, 0x1f, 0x3c, 0x3d, 0x1c, 0xaa, 0x3e, 0x74, 0x86, + 0xb9, 0xa9, 0x65, 0xcc, 0x7d, 0x07, 0xf2, 0x63, 0x6c, 0x2b, 0xc4, 0xf4, 0x9c, 0x53, 0xd6, 0x71, + 0xe7, 0xe4, 0xdc, 0x18, 0xdb, 0x12, 0x1d, 0xbf, 0x99, 0x8b, 0xcf, 0x3f, 0x52, 0x50, 0x8c, 0x76, + 0xdd, 0xf4, 0x12, 0xa3, 0xb2, 0x03, 0x2a, 0xc1, 0x4a, 0xd8, 0x07, 0x2f, 0xed, 0xd1, 0x2b, 0x35, + 0x7a, 0x72, 0x1d, 0x64, 0x79, 0x2f, 0x2c, 0x73, 0x4b, 0xda, 0x35, 0x50, 0x6a, 0x11, 0xde, 0x7b, + 0xe4, 0x64, 0x7f, 0x84, 0x8e, 0x20, 0xfb, 0xc8, 0x65, 0xbe, 0xb3, 0xcc, 0xf7, 0x87, 0x2f, 0xf7, + 0x7d, 0xbf, 0xc7, 0x9c, 0xe7, 0xef, 0xf7, 0x94, 0x76, 0x47, 0x6e, 0x55, 0x9b, 0xb2, 0x6f, 0x8e, + 0xce, 0x43, 0xda, 0xc0, 0xcf, 0x4f, 0xe3, 0x67, 0x1c, 0x13, 0x9d, 0x35, 0xf1, 0xe7, 0x21, 0xfd, + 0x94, 0xe0, 0xc7, 0xf1, 0x93, 0x85, 0x89, 0x5e, 0x23, 0xf5, 0xaf, 0x43, 0x86, 0xe5, 0x0b, 0x01, + 0xf8, 0x19, 0x13, 0xde, 0x42, 0x39, 0x48, 0xd7, 0x3a, 0x32, 0xa5, 0xbf, 0x00, 0x45, 0x2e, 0x55, + 0xba, 0x0d, 0xa9, 0x26, 0x09, 0xc9, 0xf2, 0x2d, 0xc8, 0xf2, 0x24, 0xd0, 0xad, 0x11, 0xa6, 0x41, + 0x78, 0xcb, 0x1f, 0xfa, 0x3e, 0x12, 0x81, 0xf6, 0xb8, 0x75, 0x28, 0xc9, 0x42, 0x32, 0xfa, 0x79, + 0x5d, 0x28, 0x46, 0x1b, 0xee, 0x37, 0xc3, 0xa9, 0xbf, 0x24, 0xa0, 0x10, 0x69, 0xa0, 0x69, 0xe7, + 0x83, 0x0d, 0xc3, 0x7a, 0xaa, 0x60, 0x43, 0xc7, 0xae, 0x4f, 0x0a, 0x60, 0xa2, 0x2a, 0x95, 0x9c, + 0xf5, 0xa3, 0xbd, 0x91, 0xe0, 0x7f, 0x9f, 0x00, 0x61, 0xb6, 0x77, 0x9d, 0x09, 0x30, 0xf1, 0xbd, + 0x06, 0xf8, 0xbb, 0x04, 0x94, 0xe2, 0x0d, 0xeb, 0x4c, 0x78, 0x17, 0xbf, 0xd7, 0xf0, 0xfe, 0x99, + 0x84, 0xd5, 0x58, 0x9b, 0x7a, 0xd6, 0xe8, 0xbe, 0x86, 0x75, 0x5d, 0x23, 0x63, 0xdb, 0xf2, 0x88, + 0xa9, 0x9e, 0x2a, 0x06, 0x79, 0x42, 0x0c, 0xb1, 0xcc, 0x0a, 0xc5, 0xf5, 0x97, 0x37, 0xc2, 0x95, + 0xc6, 0xd4, 0xae, 0x49, 0xcd, 0x0e, 0x36, 0x1a, 0x75, 0xa9, 0xd5, 0xed, 0xf4, 0xa5, 0x76, 0xed, + 0xa1, 0x72, 0xdc, 0xfe, 0x71, 0xbb, 0xf3, 0x65, 0x5b, 0x16, 0xf4, 0x19, 0xd8, 0x6b, 0xdc, 0xea, + 0x5d, 0x10, 0x66, 0x83, 0x42, 0xe7, 0x60, 0x51, 0x58, 0xc2, 0x5b, 0x68, 0x03, 0xd6, 0xda, 0x1d, + 0xa5, 0xd7, 0xa8, 0x4b, 0x8a, 0x74, 0xef, 0x9e, 0x54, 0xeb, 0xf7, 0xf8, 0xd3, 0x46, 0x88, 0xee, + 0xc7, 0x37, 0xf5, 0x6f, 0x53, 0xb0, 0xb1, 0x20, 0x12, 0x54, 0xf5, 0x2f, 0x25, 0xfc, 0x9e, 0xf4, + 0xc9, 0x59, 0xa2, 0xaf, 0xd0, 0xae, 0xa0, 0x8b, 0x1d, 0xcf, 0xbf, 0xc3, 0x5c, 0x01, 0x9a, 0x25, + 0xd3, 0xd3, 0x07, 0x3a, 0x71, 0xfc, 0x97, 0x20, 0x7e, 0x53, 0x59, 0x9b, 0xca, 0xf9, 0x63, 0xd0, + 0xc7, 0x80, 0x6c, 0xcb, 0xd5, 0x3d, 0xfd, 0x09, 0x51, 0x74, 0x33, 0x78, 0x36, 0xa2, 0x37, 0x97, + 0xb4, 0x2c, 0x04, 0x9a, 0x86, 0xe9, 0x85, 0x68, 0x93, 0x0c, 0xf1, 0x0c, 0x9a, 0x16, 0xf0, 0x94, + 0x2c, 0x04, 0x9a, 0x10, 0x7d, 0x11, 0x8a, 0x9a, 0x35, 0xa1, 0xed, 0x1c, 0xc7, 0xd1, 0xf3, 0x22, + 0x21, 0x17, 0xb8, 0x2c, 0x84, 0xf8, 0x8d, 0xfa, 0xf4, 0xbd, 0xaa, 0x28, 0x17, 0xb8, 0x8c, 0x43, + 0x2e, 0xc3, 0x1a, 0x1e, 0x0e, 0x1d, 0xea, 0x3c, 0x70, 0xc4, 0xaf, 0x1e, 0xa5, 0x50, 0xcc, 0x80, + 0xdb, 0xf7, 0x21, 0x17, 0xe4, 0x81, 0x1e, 0xc9, 0x34, 0x13, 0x8a, 0xcd, 0xef, 0xd3, 0xc9, 0xdd, + 0xbc, 0x9c, 0x33, 0x03, 0xe5, 0x45, 0x28, 0xea, 0xae, 0x32, 0x7d, 0x7e, 0x4f, 0xee, 0x24, 0x77, + 0x73, 0x72, 0x41, 0x77, 0xc3, 0xa7, 0xcb, 0xf2, 0x37, 0x49, 0x28, 0xc5, 0x7f, 0x3e, 0x40, 0x75, + 0xc8, 0x19, 0x96, 0x8a, 0x19, 0xb5, 0xf8, 0x6f, 0x57, 0xbb, 0xaf, 0xf8, 0xc5, 0xa1, 0xd2, 0xf4, + 0xf1, 0x72, 0x68, 0xb9, 0xfd, 0xb7, 0x04, 0xe4, 0x02, 0x31, 0xda, 0x82, 0xb4, 0x8d, 0xbd, 0x11, + 0x73, 0x97, 0x39, 0x4c, 0x0a, 0x09, 0x99, 0x8d, 0xa9, 0xdc, 0xb5, 0xb1, 0xc9, 0x28, 0xe0, 0xcb, + 0xe9, 0x98, 0x7e, 0x57, 0x83, 0x60, 0x8d, 0xdd, 0x6b, 0xac, 0xf1, 0x98, 0x98, 0x9e, 0x1b, 0x7c, + 0x57, 0x5f, 0x5e, 0xf3, 0xc5, 0xe8, 0x1a, 0xac, 0x7b, 0x0e, 0xd6, 0x8d, 0x18, 0x36, 0xcd, 0xb0, + 0x42, 0xa0, 0x08, 0xc1, 0x07, 0x70, 0x3e, 0xf0, 0xab, 0x11, 0x0f, 0xab, 0x23, 0xa2, 0x4d, 0x8d, + 0xb2, 0xec, 0xfd, 0xe2, 0x9c, 0x0f, 0xa8, 0xfb, 0xfa, 0xc0, 0xb6, 0xfc, 0xf7, 0x04, 0xac, 0x07, + 0x37, 0x31, 0x2d, 0x4c, 0x56, 0x0b, 0x00, 0x9b, 0xa6, 0xe5, 0x45, 0xd3, 0x35, 0x4f, 0xe5, 0x39, + 0xbb, 0x4a, 0x35, 0x34, 0x92, 0x23, 0x0e, 0xb6, 0xc7, 0x00, 0x53, 0xcd, 0xd2, 0xb4, 0x5d, 0x80, + 0x82, 0xff, 0xdb, 0x10, 0xfb, 0x81, 0x91, 0xdf, 0xdd, 0x81, 0x8b, 0xe8, 0x95, 0x0d, 0x6d, 0x42, + 0xe6, 0x84, 0x0c, 0x75, 0xd3, 0x7f, 0xf1, 0xe5, 0x83, 0xe0, 0x85, 0x25, 0x1d, 0xbe, 0xb0, 0x1c, + 0xfe, 0x0c, 0x36, 0x54, 0x6b, 0x3c, 0x1b, 0xee, 0xa1, 0x30, 0xf3, 0x7e, 0xe0, 0x7e, 0x91, 0xf8, + 0x0a, 0xa6, 0x2d, 0xe6, 0xff, 0x12, 0x89, 0x3f, 0x24, 0x53, 0x47, 0xdd, 0xc3, 0x3f, 0x26, 0xb7, + 0x8f, 0xb8, 0x69, 0x37, 0x58, 0xa9, 0x4c, 0x06, 0x06, 0x51, 0x69, 0xf4, 0xff, 0x0f, 0x00, 0x00, + 0xff, 0xff, 0x88, 0x17, 0xc1, 0xbe, 0x38, 0x1d, 0x00, 0x00, +} diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go new file mode 100644 index 00000000..165b2110 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go @@ -0,0 +1,752 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: descriptor.proto + +package descriptor + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + math "math" + reflect "reflect" + sort "sort" + strconv "strconv" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func (this *FileDescriptorSet) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&descriptor.FileDescriptorSet{") + if this.File != nil { + s = append(s, "File: "+fmt.Sprintf("%#v", this.File)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *FileDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 16) + s = append(s, "&descriptor.FileDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Package != nil { + s = append(s, "Package: "+valueToGoStringDescriptor(this.Package, "string")+",\n") + } + if this.Dependency != nil { + s = append(s, "Dependency: "+fmt.Sprintf("%#v", this.Dependency)+",\n") + } + if this.PublicDependency != nil { + s = append(s, "PublicDependency: "+fmt.Sprintf("%#v", this.PublicDependency)+",\n") + } + if this.WeakDependency != nil { + s = append(s, "WeakDependency: "+fmt.Sprintf("%#v", this.WeakDependency)+",\n") + } + if this.MessageType != nil { + s = append(s, "MessageType: "+fmt.Sprintf("%#v", this.MessageType)+",\n") + } + if this.EnumType != nil { + s = append(s, "EnumType: "+fmt.Sprintf("%#v", this.EnumType)+",\n") + } + if this.Service != nil { + s = append(s, "Service: "+fmt.Sprintf("%#v", this.Service)+",\n") + } + if this.Extension != nil { + s = append(s, "Extension: "+fmt.Sprintf("%#v", this.Extension)+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.SourceCodeInfo != nil { + s = append(s, "SourceCodeInfo: "+fmt.Sprintf("%#v", this.SourceCodeInfo)+",\n") + } + if this.Syntax != nil { + s = append(s, "Syntax: "+valueToGoStringDescriptor(this.Syntax, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 14) + s = append(s, "&descriptor.DescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Field != nil { + s = append(s, "Field: "+fmt.Sprintf("%#v", this.Field)+",\n") + } + if this.Extension != nil { + s = append(s, "Extension: "+fmt.Sprintf("%#v", this.Extension)+",\n") + } + if this.NestedType != nil { + s = append(s, "NestedType: "+fmt.Sprintf("%#v", this.NestedType)+",\n") + } + if this.EnumType != nil { + s = append(s, "EnumType: "+fmt.Sprintf("%#v", this.EnumType)+",\n") + } + if this.ExtensionRange != nil { + s = append(s, "ExtensionRange: "+fmt.Sprintf("%#v", this.ExtensionRange)+",\n") + } + if this.OneofDecl != nil { + s = append(s, "OneofDecl: "+fmt.Sprintf("%#v", this.OneofDecl)+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.ReservedRange != nil { + s = append(s, "ReservedRange: "+fmt.Sprintf("%#v", this.ReservedRange)+",\n") + } + if this.ReservedName != nil { + s = append(s, "ReservedName: "+fmt.Sprintf("%#v", this.ReservedName)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DescriptorProto_ExtensionRange) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&descriptor.DescriptorProto_ExtensionRange{") + if this.Start != nil { + s = append(s, "Start: "+valueToGoStringDescriptor(this.Start, "int32")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringDescriptor(this.End, "int32")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DescriptorProto_ReservedRange) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.DescriptorProto_ReservedRange{") + if this.Start != nil { + s = append(s, "Start: "+valueToGoStringDescriptor(this.Start, "int32")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringDescriptor(this.End, "int32")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ExtensionRangeOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&descriptor.ExtensionRangeOptions{") + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *FieldDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 14) + s = append(s, "&descriptor.FieldDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Number != nil { + s = append(s, "Number: "+valueToGoStringDescriptor(this.Number, "int32")+",\n") + } + if this.Label != nil { + s = append(s, "Label: "+valueToGoStringDescriptor(this.Label, "FieldDescriptorProto_Label")+",\n") + } + if this.Type != nil { + s = append(s, "Type: "+valueToGoStringDescriptor(this.Type, "FieldDescriptorProto_Type")+",\n") + } + if this.TypeName != nil { + s = append(s, "TypeName: "+valueToGoStringDescriptor(this.TypeName, "string")+",\n") + } + if this.Extendee != nil { + s = append(s, "Extendee: "+valueToGoStringDescriptor(this.Extendee, "string")+",\n") + } + if this.DefaultValue != nil { + s = append(s, "DefaultValue: "+valueToGoStringDescriptor(this.DefaultValue, "string")+",\n") + } + if this.OneofIndex != nil { + s = append(s, "OneofIndex: "+valueToGoStringDescriptor(this.OneofIndex, "int32")+",\n") + } + if this.JsonName != nil { + s = append(s, "JsonName: "+valueToGoStringDescriptor(this.JsonName, "string")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *OneofDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.OneofDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EnumDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 9) + s = append(s, "&descriptor.EnumDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Value != nil { + s = append(s, "Value: "+fmt.Sprintf("%#v", this.Value)+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.ReservedRange != nil { + s = append(s, "ReservedRange: "+fmt.Sprintf("%#v", this.ReservedRange)+",\n") + } + if this.ReservedName != nil { + s = append(s, "ReservedName: "+fmt.Sprintf("%#v", this.ReservedName)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EnumDescriptorProto_EnumReservedRange) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.EnumDescriptorProto_EnumReservedRange{") + if this.Start != nil { + s = append(s, "Start: "+valueToGoStringDescriptor(this.Start, "int32")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringDescriptor(this.End, "int32")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EnumValueDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&descriptor.EnumValueDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Number != nil { + s = append(s, "Number: "+valueToGoStringDescriptor(this.Number, "int32")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ServiceDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&descriptor.ServiceDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.Method != nil { + s = append(s, "Method: "+fmt.Sprintf("%#v", this.Method)+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *MethodDescriptorProto) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 10) + s = append(s, "&descriptor.MethodDescriptorProto{") + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringDescriptor(this.Name, "string")+",\n") + } + if this.InputType != nil { + s = append(s, "InputType: "+valueToGoStringDescriptor(this.InputType, "string")+",\n") + } + if this.OutputType != nil { + s = append(s, "OutputType: "+valueToGoStringDescriptor(this.OutputType, "string")+",\n") + } + if this.Options != nil { + s = append(s, "Options: "+fmt.Sprintf("%#v", this.Options)+",\n") + } + if this.ClientStreaming != nil { + s = append(s, "ClientStreaming: "+valueToGoStringDescriptor(this.ClientStreaming, "bool")+",\n") + } + if this.ServerStreaming != nil { + s = append(s, "ServerStreaming: "+valueToGoStringDescriptor(this.ServerStreaming, "bool")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *FileOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 25) + s = append(s, "&descriptor.FileOptions{") + if this.JavaPackage != nil { + s = append(s, "JavaPackage: "+valueToGoStringDescriptor(this.JavaPackage, "string")+",\n") + } + if this.JavaOuterClassname != nil { + s = append(s, "JavaOuterClassname: "+valueToGoStringDescriptor(this.JavaOuterClassname, "string")+",\n") + } + if this.JavaMultipleFiles != nil { + s = append(s, "JavaMultipleFiles: "+valueToGoStringDescriptor(this.JavaMultipleFiles, "bool")+",\n") + } + if this.JavaGenerateEqualsAndHash != nil { + s = append(s, "JavaGenerateEqualsAndHash: "+valueToGoStringDescriptor(this.JavaGenerateEqualsAndHash, "bool")+",\n") + } + if this.JavaStringCheckUtf8 != nil { + s = append(s, "JavaStringCheckUtf8: "+valueToGoStringDescriptor(this.JavaStringCheckUtf8, "bool")+",\n") + } + if this.OptimizeFor != nil { + s = append(s, "OptimizeFor: "+valueToGoStringDescriptor(this.OptimizeFor, "FileOptions_OptimizeMode")+",\n") + } + if this.GoPackage != nil { + s = append(s, "GoPackage: "+valueToGoStringDescriptor(this.GoPackage, "string")+",\n") + } + if this.CcGenericServices != nil { + s = append(s, "CcGenericServices: "+valueToGoStringDescriptor(this.CcGenericServices, "bool")+",\n") + } + if this.JavaGenericServices != nil { + s = append(s, "JavaGenericServices: "+valueToGoStringDescriptor(this.JavaGenericServices, "bool")+",\n") + } + if this.PyGenericServices != nil { + s = append(s, "PyGenericServices: "+valueToGoStringDescriptor(this.PyGenericServices, "bool")+",\n") + } + if this.PhpGenericServices != nil { + s = append(s, "PhpGenericServices: "+valueToGoStringDescriptor(this.PhpGenericServices, "bool")+",\n") + } + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.CcEnableArenas != nil { + s = append(s, "CcEnableArenas: "+valueToGoStringDescriptor(this.CcEnableArenas, "bool")+",\n") + } + if this.ObjcClassPrefix != nil { + s = append(s, "ObjcClassPrefix: "+valueToGoStringDescriptor(this.ObjcClassPrefix, "string")+",\n") + } + if this.CsharpNamespace != nil { + s = append(s, "CsharpNamespace: "+valueToGoStringDescriptor(this.CsharpNamespace, "string")+",\n") + } + if this.SwiftPrefix != nil { + s = append(s, "SwiftPrefix: "+valueToGoStringDescriptor(this.SwiftPrefix, "string")+",\n") + } + if this.PhpClassPrefix != nil { + s = append(s, "PhpClassPrefix: "+valueToGoStringDescriptor(this.PhpClassPrefix, "string")+",\n") + } + if this.PhpNamespace != nil { + s = append(s, "PhpNamespace: "+valueToGoStringDescriptor(this.PhpNamespace, "string")+",\n") + } + if this.PhpMetadataNamespace != nil { + s = append(s, "PhpMetadataNamespace: "+valueToGoStringDescriptor(this.PhpMetadataNamespace, "string")+",\n") + } + if this.RubyPackage != nil { + s = append(s, "RubyPackage: "+valueToGoStringDescriptor(this.RubyPackage, "string")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *MessageOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 9) + s = append(s, "&descriptor.MessageOptions{") + if this.MessageSetWireFormat != nil { + s = append(s, "MessageSetWireFormat: "+valueToGoStringDescriptor(this.MessageSetWireFormat, "bool")+",\n") + } + if this.NoStandardDescriptorAccessor != nil { + s = append(s, "NoStandardDescriptorAccessor: "+valueToGoStringDescriptor(this.NoStandardDescriptorAccessor, "bool")+",\n") + } + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.MapEntry != nil { + s = append(s, "MapEntry: "+valueToGoStringDescriptor(this.MapEntry, "bool")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *FieldOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 11) + s = append(s, "&descriptor.FieldOptions{") + if this.Ctype != nil { + s = append(s, "Ctype: "+valueToGoStringDescriptor(this.Ctype, "FieldOptions_CType")+",\n") + } + if this.Packed != nil { + s = append(s, "Packed: "+valueToGoStringDescriptor(this.Packed, "bool")+",\n") + } + if this.Jstype != nil { + s = append(s, "Jstype: "+valueToGoStringDescriptor(this.Jstype, "FieldOptions_JSType")+",\n") + } + if this.Lazy != nil { + s = append(s, "Lazy: "+valueToGoStringDescriptor(this.Lazy, "bool")+",\n") + } + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.Weak != nil { + s = append(s, "Weak: "+valueToGoStringDescriptor(this.Weak, "bool")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *OneofOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&descriptor.OneofOptions{") + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EnumOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&descriptor.EnumOptions{") + if this.AllowAlias != nil { + s = append(s, "AllowAlias: "+valueToGoStringDescriptor(this.AllowAlias, "bool")+",\n") + } + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EnumValueOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.EnumValueOptions{") + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *ServiceOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.ServiceOptions{") + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *MethodOptions) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&descriptor.MethodOptions{") + if this.Deprecated != nil { + s = append(s, "Deprecated: "+valueToGoStringDescriptor(this.Deprecated, "bool")+",\n") + } + if this.IdempotencyLevel != nil { + s = append(s, "IdempotencyLevel: "+valueToGoStringDescriptor(this.IdempotencyLevel, "MethodOptions_IdempotencyLevel")+",\n") + } + if this.UninterpretedOption != nil { + s = append(s, "UninterpretedOption: "+fmt.Sprintf("%#v", this.UninterpretedOption)+",\n") + } + s = append(s, "XXX_InternalExtensions: "+extensionToGoStringDescriptor(this)+",\n") + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *UninterpretedOption) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 11) + s = append(s, "&descriptor.UninterpretedOption{") + if this.Name != nil { + s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n") + } + if this.IdentifierValue != nil { + s = append(s, "IdentifierValue: "+valueToGoStringDescriptor(this.IdentifierValue, "string")+",\n") + } + if this.PositiveIntValue != nil { + s = append(s, "PositiveIntValue: "+valueToGoStringDescriptor(this.PositiveIntValue, "uint64")+",\n") + } + if this.NegativeIntValue != nil { + s = append(s, "NegativeIntValue: "+valueToGoStringDescriptor(this.NegativeIntValue, "int64")+",\n") + } + if this.DoubleValue != nil { + s = append(s, "DoubleValue: "+valueToGoStringDescriptor(this.DoubleValue, "float64")+",\n") + } + if this.StringValue != nil { + s = append(s, "StringValue: "+valueToGoStringDescriptor(this.StringValue, "byte")+",\n") + } + if this.AggregateValue != nil { + s = append(s, "AggregateValue: "+valueToGoStringDescriptor(this.AggregateValue, "string")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *UninterpretedOption_NamePart) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&descriptor.UninterpretedOption_NamePart{") + if this.NamePart != nil { + s = append(s, "NamePart: "+valueToGoStringDescriptor(this.NamePart, "string")+",\n") + } + if this.IsExtension != nil { + s = append(s, "IsExtension: "+valueToGoStringDescriptor(this.IsExtension, "bool")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SourceCodeInfo) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&descriptor.SourceCodeInfo{") + if this.Location != nil { + s = append(s, "Location: "+fmt.Sprintf("%#v", this.Location)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SourceCodeInfo_Location) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 9) + s = append(s, "&descriptor.SourceCodeInfo_Location{") + if this.Path != nil { + s = append(s, "Path: "+fmt.Sprintf("%#v", this.Path)+",\n") + } + if this.Span != nil { + s = append(s, "Span: "+fmt.Sprintf("%#v", this.Span)+",\n") + } + if this.LeadingComments != nil { + s = append(s, "LeadingComments: "+valueToGoStringDescriptor(this.LeadingComments, "string")+",\n") + } + if this.TrailingComments != nil { + s = append(s, "TrailingComments: "+valueToGoStringDescriptor(this.TrailingComments, "string")+",\n") + } + if this.LeadingDetachedComments != nil { + s = append(s, "LeadingDetachedComments: "+fmt.Sprintf("%#v", this.LeadingDetachedComments)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *GeneratedCodeInfo) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&descriptor.GeneratedCodeInfo{") + if this.Annotation != nil { + s = append(s, "Annotation: "+fmt.Sprintf("%#v", this.Annotation)+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *GeneratedCodeInfo_Annotation) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&descriptor.GeneratedCodeInfo_Annotation{") + if this.Path != nil { + s = append(s, "Path: "+fmt.Sprintf("%#v", this.Path)+",\n") + } + if this.SourceFile != nil { + s = append(s, "SourceFile: "+valueToGoStringDescriptor(this.SourceFile, "string")+",\n") + } + if this.Begin != nil { + s = append(s, "Begin: "+valueToGoStringDescriptor(this.Begin, "int32")+",\n") + } + if this.End != nil { + s = append(s, "End: "+valueToGoStringDescriptor(this.End, "int32")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringDescriptor(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func extensionToGoStringDescriptor(m github_com_gogo_protobuf_proto.Message) string { + e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m) + if e == nil { + return "nil" + } + s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{" + keys := make([]int, 0, len(e)) + for k := range e { + keys = append(keys, int(k)) + } + sort.Ints(keys) + ss := []string{} + for _, k := range keys { + ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) + } + s += strings.Join(ss, ",") + "})" + return s +} diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go new file mode 100644 index 00000000..e0846a35 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go @@ -0,0 +1,390 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/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. +// +// 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 descriptor + +import ( + "strings" +) + +func (msg *DescriptorProto) GetMapFields() (*FieldDescriptorProto, *FieldDescriptorProto) { + if !msg.GetOptions().GetMapEntry() { + return nil, nil + } + return msg.GetField()[0], msg.GetField()[1] +} + +func dotToUnderscore(r rune) rune { + if r == '.' { + return '_' + } + return r +} + +func (field *FieldDescriptorProto) WireType() (wire int) { + switch *field.Type { + case FieldDescriptorProto_TYPE_DOUBLE: + return 1 + case FieldDescriptorProto_TYPE_FLOAT: + return 5 + case FieldDescriptorProto_TYPE_INT64: + return 0 + case FieldDescriptorProto_TYPE_UINT64: + return 0 + case FieldDescriptorProto_TYPE_INT32: + return 0 + case FieldDescriptorProto_TYPE_UINT32: + return 0 + case FieldDescriptorProto_TYPE_FIXED64: + return 1 + case FieldDescriptorProto_TYPE_FIXED32: + return 5 + case FieldDescriptorProto_TYPE_BOOL: + return 0 + case FieldDescriptorProto_TYPE_STRING: + return 2 + case FieldDescriptorProto_TYPE_GROUP: + return 2 + case FieldDescriptorProto_TYPE_MESSAGE: + return 2 + case FieldDescriptorProto_TYPE_BYTES: + return 2 + case FieldDescriptorProto_TYPE_ENUM: + return 0 + case FieldDescriptorProto_TYPE_SFIXED32: + return 5 + case FieldDescriptorProto_TYPE_SFIXED64: + return 1 + case FieldDescriptorProto_TYPE_SINT32: + return 0 + case FieldDescriptorProto_TYPE_SINT64: + return 0 + } + panic("unreachable") +} + +func (field *FieldDescriptorProto) GetKeyUint64() (x uint64) { + packed := field.IsPacked() + wireType := field.WireType() + fieldNumber := field.GetNumber() + if packed { + wireType = 2 + } + x = uint64(uint32(fieldNumber)<<3 | uint32(wireType)) + return x +} + +func (field *FieldDescriptorProto) GetKey3Uint64() (x uint64) { + packed := field.IsPacked3() + wireType := field.WireType() + fieldNumber := field.GetNumber() + if packed { + wireType = 2 + } + x = uint64(uint32(fieldNumber)<<3 | uint32(wireType)) + return x +} + +func (field *FieldDescriptorProto) GetKey() []byte { + x := field.GetKeyUint64() + i := 0 + keybuf := make([]byte, 0) + for i = 0; x > 127; i++ { + keybuf = append(keybuf, 0x80|uint8(x&0x7F)) + x >>= 7 + } + keybuf = append(keybuf, uint8(x)) + return keybuf +} + +func (field *FieldDescriptorProto) GetKey3() []byte { + x := field.GetKey3Uint64() + i := 0 + keybuf := make([]byte, 0) + for i = 0; x > 127; i++ { + keybuf = append(keybuf, 0x80|uint8(x&0x7F)) + x >>= 7 + } + keybuf = append(keybuf, uint8(x)) + return keybuf +} + +func (desc *FileDescriptorSet) GetField(packageName, messageName, fieldName string) *FieldDescriptorProto { + msg := desc.GetMessage(packageName, messageName) + if msg == nil { + return nil + } + for _, field := range msg.GetField() { + if field.GetName() == fieldName { + return field + } + } + return nil +} + +func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto { + for _, msg := range file.GetMessageType() { + if msg.GetName() == typeName { + return msg + } + nes := file.GetNestedMessage(msg, strings.TrimPrefix(typeName, msg.GetName()+".")) + if nes != nil { + return nes + } + } + return nil +} + +func (file *FileDescriptorProto) GetNestedMessage(msg *DescriptorProto, typeName string) *DescriptorProto { + for _, nes := range msg.GetNestedType() { + if nes.GetName() == typeName { + return nes + } + res := file.GetNestedMessage(nes, strings.TrimPrefix(typeName, nes.GetName()+".")) + if res != nil { + return res + } + } + return nil +} + +func (desc *FileDescriptorSet) GetMessage(packageName string, typeName string) *DescriptorProto { + for _, file := range desc.GetFile() { + if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { + continue + } + for _, msg := range file.GetMessageType() { + if msg.GetName() == typeName { + return msg + } + } + for _, msg := range file.GetMessageType() { + for _, nes := range msg.GetNestedType() { + if nes.GetName() == typeName { + return nes + } + if msg.GetName()+"."+nes.GetName() == typeName { + return nes + } + } + } + } + return nil +} + +func (desc *FileDescriptorSet) IsProto3(packageName string, typeName string) bool { + for _, file := range desc.GetFile() { + if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { + continue + } + for _, msg := range file.GetMessageType() { + if msg.GetName() == typeName { + return file.GetSyntax() == "proto3" + } + } + for _, msg := range file.GetMessageType() { + for _, nes := range msg.GetNestedType() { + if nes.GetName() == typeName { + return file.GetSyntax() == "proto3" + } + if msg.GetName()+"."+nes.GetName() == typeName { + return file.GetSyntax() == "proto3" + } + } + } + } + return false +} + +func (msg *DescriptorProto) IsExtendable() bool { + return len(msg.GetExtensionRange()) > 0 +} + +func (desc *FileDescriptorSet) FindExtension(packageName string, typeName string, fieldName string) (extPackageName string, field *FieldDescriptorProto) { + parent := desc.GetMessage(packageName, typeName) + if parent == nil { + return "", nil + } + if !parent.IsExtendable() { + return "", nil + } + extendee := "." + packageName + "." + typeName + for _, file := range desc.GetFile() { + for _, ext := range file.GetExtension() { + if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) { + if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) { + continue + } + } else { + if ext.GetExtendee() != extendee { + continue + } + } + if ext.GetName() == fieldName { + return file.GetPackage(), ext + } + } + } + return "", nil +} + +func (desc *FileDescriptorSet) FindExtensionByFieldNumber(packageName string, typeName string, fieldNum int32) (extPackageName string, field *FieldDescriptorProto) { + parent := desc.GetMessage(packageName, typeName) + if parent == nil { + return "", nil + } + if !parent.IsExtendable() { + return "", nil + } + extendee := "." + packageName + "." + typeName + for _, file := range desc.GetFile() { + for _, ext := range file.GetExtension() { + if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) { + if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) { + continue + } + } else { + if ext.GetExtendee() != extendee { + continue + } + } + if ext.GetNumber() == fieldNum { + return file.GetPackage(), ext + } + } + } + return "", nil +} + +func (desc *FileDescriptorSet) FindMessage(packageName string, typeName string, fieldName string) (msgPackageName string, msgName string) { + parent := desc.GetMessage(packageName, typeName) + if parent == nil { + return "", "" + } + field := parent.GetFieldDescriptor(fieldName) + if field == nil { + var extPackageName string + extPackageName, field = desc.FindExtension(packageName, typeName, fieldName) + if field == nil { + return "", "" + } + packageName = extPackageName + } + typeNames := strings.Split(field.GetTypeName(), ".") + if len(typeNames) == 1 { + msg := desc.GetMessage(packageName, typeName) + if msg == nil { + return "", "" + } + return packageName, msg.GetName() + } + if len(typeNames) > 2 { + for i := 1; i < len(typeNames)-1; i++ { + packageName = strings.Join(typeNames[1:len(typeNames)-i], ".") + typeName = strings.Join(typeNames[len(typeNames)-i:], ".") + msg := desc.GetMessage(packageName, typeName) + if msg != nil { + typeNames := strings.Split(msg.GetName(), ".") + if len(typeNames) == 1 { + return packageName, msg.GetName() + } + return strings.Join(typeNames[1:len(typeNames)-1], "."), typeNames[len(typeNames)-1] + } + } + } + return "", "" +} + +func (msg *DescriptorProto) GetFieldDescriptor(fieldName string) *FieldDescriptorProto { + for _, field := range msg.GetField() { + if field.GetName() == fieldName { + return field + } + } + return nil +} + +func (desc *FileDescriptorSet) GetEnum(packageName string, typeName string) *EnumDescriptorProto { + for _, file := range desc.GetFile() { + if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) { + continue + } + for _, enum := range file.GetEnumType() { + if enum.GetName() == typeName { + return enum + } + } + } + return nil +} + +func (f *FieldDescriptorProto) IsEnum() bool { + return *f.Type == FieldDescriptorProto_TYPE_ENUM +} + +func (f *FieldDescriptorProto) IsMessage() bool { + return *f.Type == FieldDescriptorProto_TYPE_MESSAGE +} + +func (f *FieldDescriptorProto) IsBytes() bool { + return *f.Type == FieldDescriptorProto_TYPE_BYTES +} + +func (f *FieldDescriptorProto) IsRepeated() bool { + return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REPEATED +} + +func (f *FieldDescriptorProto) IsString() bool { + return *f.Type == FieldDescriptorProto_TYPE_STRING +} + +func (f *FieldDescriptorProto) IsBool() bool { + return *f.Type == FieldDescriptorProto_TYPE_BOOL +} + +func (f *FieldDescriptorProto) IsRequired() bool { + return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED +} + +func (f *FieldDescriptorProto) IsPacked() bool { + return f.Options != nil && f.GetOptions().GetPacked() +} + +func (f *FieldDescriptorProto) IsPacked3() bool { + if f.IsRepeated() && f.IsScalar() { + if f.Options == nil || f.GetOptions().Packed == nil { + return true + } + return f.Options != nil && f.GetOptions().GetPacked() + } + return false +} + +func (m *DescriptorProto) HasExtension() bool { + return len(m.ExtensionRange) > 0 +} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go new file mode 100644 index 00000000..63b0f08b --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -0,0 +1,427 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Routines for decoding protocol buffer data to construct in-memory representations. + */ + +import ( + "errors" + "fmt" + "io" +) + +// errOverflow is returned when an integer is too large to be represented. +var errOverflow = errors.New("proto: integer overflow") + +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + +// DecodeVarint reads a varint-encoded integer from the slice. +// It returns the integer and the number of bytes consumed, or +// zero if there is not enough. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func DecodeVarint(buf []byte) (x uint64, n int) { + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + +func (p *Buffer) decodeVarintSlow() (x uint64, err error) { + i := p.index + l := len(p.buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + b := p.buf[i] + i++ + x |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + p.index = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + i := p.index + buf := p.buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + p.index++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return p.decodeVarintSlow() + } + + var b uint64 + // we already checked the first byte + x = uint64(buf[i]) - 0x80 + i++ + + b = uint64(buf[i]) + i++ + x += b << 7 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 7 + + b = uint64(buf[i]) + i++ + x += b << 14 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 14 + + b = uint64(buf[i]) + i++ + x += b << 21 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 21 + + b = uint64(buf[i]) + i++ + x += b << 28 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 28 + + b = uint64(buf[i]) + i++ + x += b << 35 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 35 + + b = uint64(buf[i]) + i++ + x += b << 42 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 42 + + b = uint64(buf[i]) + i++ + x += b << 49 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 49 + + b = uint64(buf[i]) + i++ + x += b << 56 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 56 + + b = uint64(buf[i]) + i++ + x += b << 63 + if b&0x80 == 0 { + goto done + } + + return 0, errOverflow + +done: + p.index = i + return x, nil +} + +// DecodeFixed64 reads a 64-bit integer from the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) DecodeFixed64() (x uint64, err error) { + // x, err already 0 + i := p.index + 8 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-8]) + x |= uint64(p.buf[i-7]) << 8 + x |= uint64(p.buf[i-6]) << 16 + x |= uint64(p.buf[i-5]) << 24 + x |= uint64(p.buf[i-4]) << 32 + x |= uint64(p.buf[i-3]) << 40 + x |= uint64(p.buf[i-2]) << 48 + x |= uint64(p.buf[i-1]) << 56 + return +} + +// DecodeFixed32 reads a 32-bit integer from the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) DecodeFixed32() (x uint64, err error) { + // x, err already 0 + i := p.index + 4 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-4]) + x |= uint64(p.buf[i-3]) << 8 + x |= uint64(p.buf[i-2]) << 16 + x |= uint64(p.buf[i-1]) << 24 + return +} + +// DecodeZigzag64 reads a zigzag-encoded 64-bit integer +// from the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) DecodeZigzag64() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) + return +} + +// DecodeZigzag32 reads a zigzag-encoded 32-bit integer +// from the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) DecodeZigzag32() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) + return +} + +// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { + n, err := p.DecodeVarint() + if err != nil { + return nil, err + } + + nb := int(n) + if nb < 0 { + return nil, fmt.Errorf("proto: bad byte length %d", nb) + } + end := p.index + nb + if end < p.index || end > len(p.buf) { + return nil, io.ErrUnexpectedEOF + } + + if !alloc { + // todo: check if can get more uses of alloc=false + buf = p.buf[p.index:end] + p.index += nb + return + } + + buf = make([]byte, nb) + copy(buf, p.buf[p.index:]) + p.index += nb + return +} + +// DecodeStringBytes reads an encoded string from the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) DecodeStringBytes() (s string, err error) { + buf, err := p.DecodeRawBytes(false) + if err != nil { + return + } + return string(buf), nil +} + +// Unmarshaler is the interface representing objects that can +// unmarshal themselves. The argument points to data that may be +// overwritten, so implementations should not keep references to the +// buffer. +// Unmarshal implementations should not clear the receiver. +// Any unmarshaled data should be merged into the receiver. +// Callers of Unmarshal that do not want to retain existing data +// should Reset the receiver before calling Unmarshal. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// newUnmarshaler is the interface representing objects that can +// unmarshal themselves. The semantics are identical to Unmarshaler. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newUnmarshaler interface { + XXX_Unmarshal([]byte) error +} + +// Unmarshal parses the protocol buffer representation in buf and places the +// decoded result in pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// Unmarshal resets pb before starting to unmarshal, so any +// existing data in pb is always removed. Use UnmarshalMerge +// to preserve and append to existing data. +func Unmarshal(buf []byte, pb Message) error { + pb.Reset() + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// UnmarshalMerge parses the protocol buffer representation in buf and +// writes the decoded result to pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// UnmarshalMerge merges into existing data in pb. +// Most code should use Unmarshal instead. +func UnmarshalMerge(buf []byte, pb Message) error { + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +// StartGroup tag is already consumed. This function consumes +// EndGroup tag. +func (p *Buffer) DecodeGroup(pb Message) error { + b := p.buf[p.index:] + x, y := findEndGroup(b) + if x < 0 { + return io.ErrUnexpectedEOF + } + err := Unmarshal(b[:x], pb) + p.index += y + return err +} + +// Unmarshal parses the protocol buffer representation in the +// Buffer and places the decoded result in pb. If the struct +// underlying pb does not match the data in the buffer, the results can be +// unpredictable. +// +// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. +func (p *Buffer) Unmarshal(pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(newUnmarshaler); ok { + err := u.XXX_Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + err := u.Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + + // Slow workaround for messages that aren't Unmarshalers. + // This includes some hand-coded .pb.go files and + // bootstrap protos. + // TODO: fix all of those and then add Unmarshal to + // the Message interface. Then: + // The cast above and code below can be deleted. + // The old unmarshaler can be deleted. + // Clients can call Unmarshal directly (can already do that, actually). + var info InternalMessageInfo + err := info.Unmarshal(pb, p.buf[p.index:]) + p.index = len(p.buf) + return err +} diff --git a/vendor/github.com/golang/protobuf/proto/deprecated.go b/vendor/github.com/golang/protobuf/proto/deprecated.go new file mode 100644 index 00000000..35b882c0 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/deprecated.go @@ -0,0 +1,63 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2018 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 proto + +import "errors" + +// Deprecated: do not use. +type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } + +// Deprecated: do not use. +func GetStats() Stats { return Stats{} } + +// Deprecated: do not use. +func MarshalMessageSet(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSet([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func MarshalMessageSetJSON(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSetJSON([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go new file mode 100644 index 00000000..f9b6e41b --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -0,0 +1,301 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 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. + +// Protocol buffer comparison. + +package proto + +import ( + "bytes" + "log" + "reflect" + "strings" +) + +/* +Equal returns true iff protocol buffers a and b are equal. +The arguments must both be pointers to protocol buffer structs. + +Equality is defined in this way: + - Two messages are equal iff they are the same type, + corresponding fields are equal, unknown field sets + are equal, and extensions sets are equal. + - Two set scalar fields are equal iff their values are equal. + If the fields are of a floating-point type, remember that + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). + - Two repeated fields are equal iff their lengths are the same, + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. + - Two unset fields are equal. + - Two unknown field sets are equal if their current + encoded state is equal. + - Two extension sets are equal iff they have corresponding + elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. + - Every other combination of things are not equal. + +The return value is undefined if a and b are not protocol buffers. +*/ +func Equal(a, b Message) bool { + if a == nil || b == nil { + return a == b + } + v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) + if v1.Type() != v2.Type() { + return false + } + if v1.Kind() == reflect.Ptr { + if v1.IsNil() { + return v2.IsNil() + } + if v2.IsNil() { + return false + } + v1, v2 = v1.Elem(), v2.Elem() + } + if v1.Kind() != reflect.Struct { + return false + } + return equalStruct(v1, v2) +} + +// v1 and v2 are known to have the same type. +func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) + for i := 0; i < v1.NumField(); i++ { + f := v1.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + f1, f2 := v1.Field(i), v2.Field(i) + if f.Type.Kind() == reflect.Ptr { + if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { + // both unset + continue + } else if n1 != n2 { + // set/unset mismatch + return false + } + f1, f2 = f1.Elem(), f2.Elem() + } + if !equalAny(f1, f2, sprop.Prop[i]) { + return false + } + } + + if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_InternalExtensions") + if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { + return false + } + } + + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_extensions") + if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + return false + } + } + + uf := v1.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return true + } + + u1 := uf.Bytes() + u2 := v2.FieldByName("XXX_unrecognized").Bytes() + return bytes.Equal(u1, u2) +} + +// v1 and v2 are known to have the same type. +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { + if v1.Type() == protoMessageType { + m1, _ := v1.Interface().(Message) + m2, _ := v2.Interface().(Message) + return Equal(m1, m2) + } + switch v1.Kind() { + case reflect.Bool: + return v1.Bool() == v2.Bool() + case reflect.Float32, reflect.Float64: + return v1.Float() == v2.Float() + case reflect.Int32, reflect.Int64: + return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2, nil) { + return false + } + } + return true + case reflect.Ptr: + // Maps may have nil values in them, so check for nil. + if v1.IsNil() && v2.IsNil() { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return equalAny(v1.Elem(), v2.Elem(), prop) + case reflect.Slice: + if v1.Type().Elem().Kind() == reflect.Uint8 { + // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) + } + + if v1.Len() != v2.Len() { + return false + } + for i := 0; i < v1.Len(); i++ { + if !equalAny(v1.Index(i), v2.Index(i), prop) { + return false + } + } + return true + case reflect.String: + return v1.Interface().(string) == v2.Interface().(string) + case reflect.Struct: + return equalStruct(v1, v2) + case reflect.Uint32, reflect.Uint64: + return v1.Uint() == v2.Uint() + } + + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to compare %v", v1) + return false +} + +// base is the struct type that the extensions are based on. +// x1 and x2 are InternalExtensions. +func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { + em1, _ := x1.extensionsRead() + em2, _ := x2.extensionsRead() + return equalExtMap(base, em1, em2) +} + +func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { + if len(em1) != len(em2) { + return false + } + + for extNum, e1 := range em1 { + e2, ok := em2[extNum] + if !ok { + return false + } + + m1 := extensionAsLegacyType(e1.value) + m2 := extensionAsLegacyType(e2.value) + + if m1 == nil && m2 == nil { + // Both have only encoded form. + if bytes.Equal(e1.enc, e2.enc) { + continue + } + // The bytes are different, but the extensions might still be + // equal. We need to decode them to compare. + } + + if m1 != nil && m2 != nil { + // Both are unencoded. + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + continue + } + + // At least one is encoded. To do a semantically correct comparison + // we need to unmarshal them first. + var desc *ExtensionDesc + if m := extensionMaps[base]; m != nil { + desc = m[extNum] + } + if desc == nil { + // If both have only encoded form and the bytes are the same, + // it is handled above. We get here when the bytes are different. + // We don't know how to decode it, so just compare them as byte + // slices. + log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) + return false + } + var err error + if m1 == nil { + m1, err = decodeExtension(e1.enc, desc) + } + if m2 == nil && err == nil { + m2, err = decodeExtension(e2.enc, desc) + } + if err != nil { + // The encoded form is invalid. + log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) + return false + } + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + } + + return true +} diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go new file mode 100644 index 00000000..fa88add3 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -0,0 +1,607 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Types and routines for supporting protocol buffer extensions. + */ + +import ( + "errors" + "fmt" + "io" + "reflect" + "strconv" + "sync" +) + +// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. +var ErrMissingExtension = errors.New("proto: missing extension") + +// ExtensionRange represents a range of message extensions for a protocol buffer. +// Used in code generated by the protocol compiler. +type ExtensionRange struct { + Start, End int32 // both inclusive +} + +// extendableProto is an interface implemented by any protocol buffer generated by the current +// proto compiler that may be extended. +type extendableProto interface { + Message + ExtensionRangeArray() []ExtensionRange + extensionsWrite() map[int32]Extension + extensionsRead() (map[int32]Extension, sync.Locker) +} + +// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous +// version of the proto compiler that may be extended. +type extendableProtoV1 interface { + Message + ExtensionRangeArray() []ExtensionRange + ExtensionMap() map[int32]Extension +} + +// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. +type extensionAdapter struct { + extendableProtoV1 +} + +func (e extensionAdapter) extensionsWrite() map[int32]Extension { + return e.ExtensionMap() +} + +func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { + return e.ExtensionMap(), notLocker{} +} + +// notLocker is a sync.Locker whose Lock and Unlock methods are nops. +type notLocker struct{} + +func (n notLocker) Lock() {} +func (n notLocker) Unlock() {} + +// extendable returns the extendableProto interface for the given generated proto message. +// If the proto message has the old extension format, it returns a wrapper that implements +// the extendableProto interface. +func extendable(p interface{}) (extendableProto, error) { + switch p := p.(type) { + case extendableProto: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return p, nil + case extendableProtoV1: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return extensionAdapter{p}, nil + } + // Don't allocate a specific error containing %T: + // this is the hot path for Clone and MarshalText. + return nil, errNotExtendable +} + +var errNotExtendable = errors.New("proto: not an extendable proto.Message") + +func isNilPtr(x interface{}) bool { + v := reflect.ValueOf(x) + return v.Kind() == reflect.Ptr && v.IsNil() +} + +// XXX_InternalExtensions is an internal representation of proto extensions. +// +// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, +// thus gaining the unexported 'extensions' method, which can be called only from the proto package. +// +// The methods of XXX_InternalExtensions are not concurrency safe in general, +// but calls to logically read-only methods such as has and get may be executed concurrently. +type XXX_InternalExtensions struct { + // The struct must be indirect so that if a user inadvertently copies a + // generated message and its embedded XXX_InternalExtensions, they + // avoid the mayhem of a copied mutex. + // + // The mutex serializes all logically read-only operations to p.extensionMap. + // It is up to the client to ensure that write operations to p.extensionMap are + // mutually exclusive with other accesses. + p *struct { + mu sync.Mutex + extensionMap map[int32]Extension + } +} + +// extensionsWrite returns the extension map, creating it on first use. +func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { + if e.p == nil { + e.p = new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }) + e.p.extensionMap = make(map[int32]Extension) + } + return e.p.extensionMap +} + +// extensionsRead returns the extensions map for read-only use. It may be nil. +// The caller must hold the returned mutex's lock when accessing Elements within the map. +func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { + if e.p == nil { + return nil, nil + } + return e.p.extensionMap, &e.p.mu +} + +// ExtensionDesc represents an extension specification. +// Used in generated code from the protocol compiler. +type ExtensionDesc struct { + ExtendedType Message // nil pointer to the type that is being extended + ExtensionType interface{} // nil pointer to the extension type + Field int32 // field number + Name string // fully-qualified name of extension, for text formatting + Tag string // protobuf tag style + Filename string // name of the file in which the extension is defined +} + +func (ed *ExtensionDesc) repeated() bool { + t := reflect.TypeOf(ed.ExtensionType) + return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 +} + +// Extension represents an extension in a message. +type Extension struct { + // When an extension is stored in a message using SetExtension + // only desc and value are set. When the message is marshaled + // enc will be set to the encoded form of the message. + // + // When a message is unmarshaled and contains extensions, each + // extension will have only enc set. When such an extension is + // accessed using GetExtension (or GetExtensions) desc and value + // will be set. + desc *ExtensionDesc + + // value is a concrete value for the extension field. Let the type of + // desc.ExtensionType be the "API type" and the type of Extension.value + // be the "storage type". The API type and storage type are the same except: + // * For scalars (except []byte), the API type uses *T, + // while the storage type uses T. + // * For repeated fields, the API type uses []T, while the storage type + // uses *[]T. + // + // The reason for the divergence is so that the storage type more naturally + // matches what is expected of when retrieving the values through the + // protobuf reflection APIs. + // + // The value may only be populated if desc is also populated. + value interface{} + + // enc is the raw bytes for the extension field. + enc []byte +} + +// SetRawExtension is for testing only. +func SetRawExtension(base Message, id int32, b []byte) { + epb, err := extendable(base) + if err != nil { + return + } + extmap := epb.extensionsWrite() + extmap[id] = Extension{enc: b} +} + +// isExtensionField returns true iff the given field number is in an extension range. +func isExtensionField(pb extendableProto, field int32) bool { + for _, er := range pb.ExtensionRangeArray() { + if er.Start <= field && field <= er.End { + return true + } + } + return false +} + +// checkExtensionTypes checks that the given extension is valid for pb. +func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + var pbi interface{} = pb + // Check the extended type. + if ea, ok := pbi.(extensionAdapter); ok { + pbi = ea.extendableProtoV1 + } + if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { + return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) + } + // Check the range. + if !isExtensionField(pb, extension.Field) { + return errors.New("proto: bad extension number; not in declared ranges") + } + return nil +} + +// extPropKey is sufficient to uniquely identify an extension. +type extPropKey struct { + base reflect.Type + field int32 +} + +var extProp = struct { + sync.RWMutex + m map[extPropKey]*Properties +}{ + m: make(map[extPropKey]*Properties), +} + +func extensionProperties(ed *ExtensionDesc) *Properties { + key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} + + extProp.RLock() + if prop, ok := extProp.m[key]; ok { + extProp.RUnlock() + return prop + } + extProp.RUnlock() + + extProp.Lock() + defer extProp.Unlock() + // Check again. + if prop, ok := extProp.m[key]; ok { + return prop + } + + prop := new(Properties) + prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) + extProp.m[key] = prop + return prop +} + +// HasExtension returns whether the given extension is present in pb. +func HasExtension(pb Message, extension *ExtensionDesc) bool { + // TODO: Check types, field numbers, etc.? + epb, err := extendable(pb) + if err != nil { + return false + } + extmap, mu := epb.extensionsRead() + if extmap == nil { + return false + } + mu.Lock() + _, ok := extmap[extension.Field] + mu.Unlock() + return ok +} + +// ClearExtension removes the given extension from pb. +func ClearExtension(pb Message, extension *ExtensionDesc) { + epb, err := extendable(pb) + if err != nil { + return + } + // TODO: Check types, field numbers, etc.? + extmap := epb.extensionsWrite() + delete(extmap, extension.Field) +} + +// GetExtension retrieves a proto2 extended field from pb. +// +// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), +// then GetExtension parses the encoded field and returns a Go value of the specified type. +// If the field is not present, then the default value is returned (if one is specified), +// otherwise ErrMissingExtension is reported. +// +// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), +// then GetExtension returns the raw encoded bytes of the field extension. +func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + + if extension.ExtendedType != nil { + // can only check type if this is a complete descriptor + if err := checkExtensionTypes(epb, extension); err != nil { + return nil, err + } + } + + emap, mu := epb.extensionsRead() + if emap == nil { + return defaultExtensionValue(extension) + } + mu.Lock() + defer mu.Unlock() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return extensionAsLegacyType(e.value), nil + } + + if extension.ExtensionType == nil { + // incomplete descriptor + return e.enc, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = extensionAsStorageType(v) + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return extensionAsLegacyType(e.value), nil +} + +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + if extension.ExtensionType == nil { + // incomplete descriptor, so no default + return nil, ErrMissingExtension + } + + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + +// decodeExtension decodes an extension encoded in b. +func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + unmarshal := typeUnmarshaler(t, extension.Tag) + + // t is a pointer to a struct, pointer to basic type or a slice. + // Allocate space to store the pointer/slice. + value := reflect.New(t).Elem() + + var err error + for { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + wire := int(x) & 7 + + b, err = unmarshal(b, valToPointer(value.Addr()), wire) + if err != nil { + return nil, err + } + + if len(b) == 0 { + break + } + } + return value.Interface(), nil +} + +// GetExtensions returns a slice of the extensions present in pb that are also listed in es. +// The returned slice has the same length as es; missing extensions will appear as nil elements. +func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + extensions = make([]interface{}, len(es)) + for i, e := range es { + extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } + if err != nil { + return + } + } + return +} + +// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. +// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing +// just the Field field, which defines the extension's field number. +func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + registeredExtensions := RegisteredExtensions(pb) + + emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } + mu.Lock() + defer mu.Unlock() + extensions := make([]*ExtensionDesc, 0, len(emap)) + for extid, e := range emap { + desc := e.desc + if desc == nil { + desc = registeredExtensions[extid] + if desc == nil { + desc = &ExtensionDesc{Field: extid} + } + } + + extensions = append(extensions, desc) + } + return extensions, nil +} + +// SetExtension sets the specified extension of pb to the specified value. +func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { + epb, err := extendable(pb) + if err != nil { + return err + } + if err := checkExtensionTypes(epb, extension); err != nil { + return err + } + typ := reflect.TypeOf(extension.ExtensionType) + if typ != reflect.TypeOf(value) { + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } + + extmap := epb.extensionsWrite() + extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)} + return nil +} + +// ClearAllExtensions clears all extensions from pb. +func ClearAllExtensions(pb Message) { + epb, err := extendable(pb) + if err != nil { + return + } + m := epb.extensionsWrite() + for k := range m { + delete(m, k) + } +} + +// A global registry of extensions. +// The generated code will register the generated descriptors by calling RegisterExtension. + +var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) + +// RegisterExtension is called from the generated code. +func RegisterExtension(desc *ExtensionDesc) { + st := reflect.TypeOf(desc.ExtendedType).Elem() + m := extensionMaps[st] + if m == nil { + m = make(map[int32]*ExtensionDesc) + extensionMaps[st] = m + } + if _, ok := m[desc.Field]; ok { + panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + } + m[desc.Field] = desc +} + +// RegisteredExtensions returns a map of the registered extensions of a +// protocol buffer struct, indexed by the extension number. +// The argument pb should be a nil pointer to the struct type. +func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { + return extensionMaps[reflect.TypeOf(pb).Elem()] +} + +// extensionAsLegacyType converts an value in the storage type as the API type. +// See Extension.value. +func extensionAsLegacyType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + // Represent primitive types as a pointer to the value. + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Slice: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + } + return v +} + +// extensionAsStorageType converts an value in the API type as the storage type. +// See Extension.value. +func extensionAsStorageType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + case reflect.Slice: + // Represent slice types as a pointer to the value. + if rv.Type().Elem().Kind() != reflect.Uint8 { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + } + } + return v +} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go new file mode 100644 index 00000000..fdd328bb --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -0,0 +1,965 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Enum types do not get an Enum method. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err + } + *x = FOO(value) + return nil + } + + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" + } + + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type + } + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil + } + + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" + } + + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } + // etc. + } +*/ +package proto + +import ( + "encoding/json" + "fmt" + "log" + "reflect" + "sort" + "strconv" + "sync" +) + +// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. +// Marshal reports this when a required field is not initialized. +// Unmarshal reports this when a required field is missing from the wire data. +type RequiredNotSetError struct{ field string } + +func (e *RequiredNotSetError) Error() string { + if e.field == "" { + return fmt.Sprintf("proto: required field not set") + } + return fmt.Sprintf("proto: required field %q not set", e.field) +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +type invalidUTF8Error struct{ field string } + +func (e *invalidUTF8Error) Error() string { + if e.field == "" { + return "proto: invalid UTF-8 detected" + } + return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) +} +func (e *invalidUTF8Error) InvalidUTF8() bool { + return true +} + +// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. +// This error should not be exposed to the external API as such errors should +// be recreated with the field information. +var errInvalidUTF8 = &invalidUTF8Error{} + +// isNonFatal reports whether the error is either a RequiredNotSet error +// or a InvalidUTF8 error. +func isNonFatal(err error) bool { + if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { + return true + } + if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { + return true + } + return false +} + +type nonFatal struct{ E error } + +// Merge merges err into nf and reports whether it was successful. +// Otherwise it returns false for any fatal non-nil errors. +func (nf *nonFatal) Merge(err error) (ok bool) { + if err == nil { + return true // not an error + } + if !isNonFatal(err) { + return false // fatal error + } + if nf.E == nil { + nf.E = err // store first instance of non-fatal error + } + return true +} + +// Message is implemented by generated protocol buffer messages. +type Message interface { + Reset() + String() string + ProtoMessage() +} + +// A Buffer is a buffer manager for marshaling and unmarshaling +// protocol buffers. It may be reused between invocations to +// reduce memory usage. It is not necessary to use a Buffer; +// the global functions Marshal and Unmarshal create a +// temporary Buffer and are fine for most applications. +type Buffer struct { + buf []byte // encode/decode byte stream + index int // read point + + deterministic bool +} + +// NewBuffer allocates a new Buffer and initializes its internal data to +// the contents of the argument slice. +func NewBuffer(e []byte) *Buffer { + return &Buffer{buf: e} +} + +// Reset resets the Buffer, ready for marshaling a new protocol buffer. +func (p *Buffer) Reset() { + p.buf = p.buf[0:0] // for reading/writing + p.index = 0 // for reading +} + +// SetBuf replaces the internal buffer with the slice, +// ready for unmarshaling the contents of the slice. +func (p *Buffer) SetBuf(s []byte) { + p.buf = s + p.index = 0 +} + +// Bytes returns the contents of the Buffer. +func (p *Buffer) Bytes() []byte { return p.buf } + +// SetDeterministic sets whether to use deterministic serialization. +// +// Deterministic serialization guarantees that for a given binary, equal +// messages will always be serialized to the same bytes. This implies: +// +// - Repeated serialization of a message will return the same bytes. +// - Different processes of the same binary (which may be executing on +// different machines) will serialize equal messages to the same bytes. +// +// Note that the deterministic serialization is NOT canonical across +// languages. It is not guaranteed to remain stable over time. It is unstable +// across different builds with schema changes due to unknown fields. +// Users who need canonical serialization (e.g., persistent storage in a +// canonical form, fingerprinting, etc.) should define their own +// canonicalization specification and implement their own serializer rather +// than relying on this API. +// +// If deterministic serialization is requested, map entries will be sorted +// by keys in lexographical order. This is an implementation detail and +// subject to change. +func (p *Buffer) SetDeterministic(deterministic bool) { + p.deterministic = deterministic +} + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + return &v +} + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { + return &v +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int32 { + p := new(int32) + *p = int32(v) + return p +} + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { + return &v +} + +// Float32 is a helper routine that allocates a new float32 value +// to store v and returns a pointer to it. +func Float32(v float32) *float32 { + return &v +} + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { + return &v +} + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { + return &v +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + return &v +} + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// UnmarshalJSONEnum is a helper function to simplify recovering enum int values +// from their JSON-encoded representation. Given a map from the enum's symbolic +// names to its int values, and a byte buffer containing the JSON-encoded +// value, it returns an int32 that can be cast to the enum type by the caller. +// +// The function can deal with both JSON representations, numeric and symbolic. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// DebugPrint dumps the encoded data in b in a debugging format with a header +// including the string s. Used in testing but made available for general debugging. +func (p *Buffer) DebugPrint(s string, b []byte) { + var u uint64 + + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 + depth := 0 + + fmt.Printf("\n--- %s ---\n", s) + +out: + for { + for i := 0; i < depth; i++ { + fmt.Print(" ") + } + + index := p.index + if index == len(p.buf) { + break + } + + op, err := p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: fetching op err %v\n", index, err) + break out + } + tag := op >> 3 + wire := op & 7 + + switch wire { + default: + fmt.Printf("%3d: t=%3d unknown wire=%d\n", + index, tag, wire) + break out + + case WireBytes: + var r []byte + + r, err = p.DecodeRawBytes(false) + if err != nil { + break out + } + fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) + if len(r) <= 6 { + for i := 0; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } else { + for i := 0; i < 3; i++ { + fmt.Printf(" %.2x", r[i]) + } + fmt.Printf(" ..") + for i := len(r) - 3; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } + fmt.Printf("\n") + + case WireFixed32: + u, err = p.DecodeFixed32() + if err != nil { + fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) + + case WireFixed64: + u, err = p.DecodeFixed64() + if err != nil { + fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) + + case WireVarint: + u, err = p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) + + case WireStartGroup: + fmt.Printf("%3d: t=%3d start\n", index, tag) + depth++ + + case WireEndGroup: + depth-- + fmt.Printf("%3d: t=%3d end\n", index, tag) + } + } + + if depth != 0 { + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) + } + fmt.Printf("\n") + + p.buf = obuf + p.index = index +} + +// SetDefaults sets unset protocol buffer fields to their default values. +// It only modifies fields that are both unset and have defined defaults. +// It recursively sets default values in any non-nil sub-messages. +func SetDefaults(pb Message) { + setDefaults(reflect.ValueOf(pb), true, false) +} + +// v is a pointer to a struct. +func setDefaults(v reflect.Value, recur, zeros bool) { + v = v.Elem() + + defaultMu.RLock() + dm, ok := defaults[v.Type()] + defaultMu.RUnlock() + if !ok { + dm = buildDefaultMessage(v.Type()) + defaultMu.Lock() + defaults[v.Type()] = dm + defaultMu.Unlock() + } + + for _, sf := range dm.scalars { + f := v.Field(sf.index) + if !f.IsNil() { + // field already set + continue + } + dv := sf.value + if dv == nil && !zeros { + // no explicit default, and don't want to set zeros + continue + } + fptr := f.Addr().Interface() // **T + // TODO: Consider batching the allocations we do here. + switch sf.kind { + case reflect.Bool: + b := new(bool) + if dv != nil { + *b = dv.(bool) + } + *(fptr.(**bool)) = b + case reflect.Float32: + f := new(float32) + if dv != nil { + *f = dv.(float32) + } + *(fptr.(**float32)) = f + case reflect.Float64: + f := new(float64) + if dv != nil { + *f = dv.(float64) + } + *(fptr.(**float64)) = f + case reflect.Int32: + // might be an enum + if ft := f.Type(); ft != int32PtrType { + // enum + f.Set(reflect.New(ft.Elem())) + if dv != nil { + f.Elem().SetInt(int64(dv.(int32))) + } + } else { + // int32 field + i := new(int32) + if dv != nil { + *i = dv.(int32) + } + *(fptr.(**int32)) = i + } + case reflect.Int64: + i := new(int64) + if dv != nil { + *i = dv.(int64) + } + *(fptr.(**int64)) = i + case reflect.String: + s := new(string) + if dv != nil { + *s = dv.(string) + } + *(fptr.(**string)) = s + case reflect.Uint8: + // exceptional case: []byte + var b []byte + if dv != nil { + db := dv.([]byte) + b = make([]byte, len(db)) + copy(b, db) + } else { + b = []byte{} + } + *(fptr.(*[]byte)) = b + case reflect.Uint32: + u := new(uint32) + if dv != nil { + *u = dv.(uint32) + } + *(fptr.(**uint32)) = u + case reflect.Uint64: + u := new(uint64) + if dv != nil { + *u = dv.(uint64) + } + *(fptr.(**uint64)) = u + default: + log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) + } + } + + for _, ni := range dm.nested { + f := v.Field(ni) + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } + setDefaults(f, recur, zeros) + + case reflect.Slice: + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + } + } +} + +var ( + // defaults maps a protocol buffer struct type to a slice of the fields, + // with its scalar fields set to their proto-declared non-zero default values. + defaultMu sync.RWMutex + defaults = make(map[reflect.Type]defaultMessage) + + int32PtrType = reflect.TypeOf((*int32)(nil)) +) + +// defaultMessage represents information about the default values of a message. +type defaultMessage struct { + scalars []scalarField + nested []int // struct field index of nested messages +} + +type scalarField struct { + index int // struct field index + kind reflect.Kind // element type (the T in *T or []T) + value interface{} // the proto-declared default value, or nil +} + +// t is a struct type. +func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { + sprop := GetProperties(t) + for _, prop := range sprop.Prop { + fi, ok := sprop.decoderTags.get(prop.Tag) + if !ok { + // XXX_unrecognized + continue + } + ft := t.Field(fi).Type + + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: + dm.nested = append(dm.nested, fi) + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) + } + } + + return dm +} + +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// mapKeys returns a sort.Interface to be used for sorting the map keys. +// Map fields may have key types of non-float scalars, strings and enums. +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{vs: vs} + + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + case reflect.Bool: + s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true + case reflect.String: + s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } + default: + panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) + } + + return s +} + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +const ( + // ProtoPackageIsVersion3 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion3 = true + + // ProtoPackageIsVersion2 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion2 = true + + // ProtoPackageIsVersion1 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion1 = true +) + +// InternalMessageInfo is a type used internally by generated .pb.go files. +// This type is not intended to be used by non-generated code. +// This type is not subject to any compatibility guarantee. +type InternalMessageInfo struct { + marshal *marshalInfo + unmarshal *unmarshalInfo + merge *mergeInfo + discard *discardInfo +} diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go new file mode 100644 index 00000000..f48a7567 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/message_set.go @@ -0,0 +1,181 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Support for message sets. + */ + +import ( + "errors" +) + +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. +// A message type ID is required for storing a protocol buffer in a message set. +var errNoMessageTypeID = errors.New("proto does not have a message type ID") + +// The first two types (_MessageSet_Item and messageSet) +// model what the protocol compiler produces for the following protocol message: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } +// That is the MessageSet wire format. We can't use a proto to generate these +// because that would introduce a circular dependency between it and this package. + +type _MessageSet_Item struct { + TypeId *int32 `protobuf:"varint,2,req,name=type_id"` + Message []byte `protobuf:"bytes,3,req,name=message"` +} + +type messageSet struct { + Item []*_MessageSet_Item `protobuf:"group,1,rep"` + XXX_unrecognized []byte + // TODO: caching? +} + +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) + +// messageTypeIder is an interface satisfied by a protocol buffer type +// that may be stored in a MessageSet. +type messageTypeIder interface { + MessageTypeId() int32 +} + +func (ms *messageSet) find(pb Message) *_MessageSet_Item { + mti, ok := pb.(messageTypeIder) + if !ok { + return nil + } + id := mti.MessageTypeId() + for _, item := range ms.Item { + if *item.TypeId == id { + return item + } + } + return nil +} + +func (ms *messageSet) Has(pb Message) bool { + return ms.find(pb) != nil +} + +func (ms *messageSet) Unmarshal(pb Message) error { + if item := ms.find(pb); item != nil { + return Unmarshal(item.Message, pb) + } + if _, ok := pb.(messageTypeIder); !ok { + return errNoMessageTypeID + } + return nil // TODO: return error instead? +} + +func (ms *messageSet) Marshal(pb Message) error { + msg, err := Marshal(pb) + if err != nil { + return err + } + if item := ms.find(pb); item != nil { + // reuse existing item + item.Message = msg + return nil + } + + mti, ok := pb.(messageTypeIder) + if !ok { + return errNoMessageTypeID + } + + mtid := mti.MessageTypeId() + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: &mtid, + Message: msg, + }) + return nil +} + +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} + +// Support for the message_set_wire_format message option. + +func skipVarint(buf []byte) []byte { + i := 0 + for ; buf[i]&0x80 != 0; i++ { + } + return buf[i+1:] +} + +// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. +func unmarshalMessageSet(buf []byte, exts interface{}) error { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + m = exts.extensionsWrite() + case map[int32]Extension: + m = exts + default: + return errors.New("proto: not an extension map") + } + + ms := new(messageSet) + if err := Unmarshal(buf, ms); err != nil { + return err + } + for _, item := range ms.Item { + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) + + m[id] = Extension{enc: b} + } + return nil +} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go new file mode 100644 index 00000000..94fa9194 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go @@ -0,0 +1,360 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 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. + +// +build purego appengine js + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "reflect" + "sync" +) + +const unsafeAllowed = false + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by the sequence of field indices +// passed to reflect's FieldByIndex. +type field []int + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return f.Index +} + +// invalidField is an invalid field identifier. +var invalidField = field(nil) + +// zeroField is a noop when calling pointer.offset. +var zeroField = field([]int{}) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { return f != nil } + +// The pointer type is for the table-driven decoder. +// The implementation here uses a reflect.Value of pointer type to +// create a generic pointer. In pointer_unsafe.go we use unsafe +// instead of reflect to implement the same (but faster) interface. +type pointer struct { + v reflect.Value +} + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + return pointer{v: reflect.ValueOf(*i)} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr, deref bool) pointer { + v := reflect.ValueOf(*i) + u := reflect.New(v.Type()) + u.Elem().Set(v) + if deref { + u = u.Elem() + } + return pointer{v: u} +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{v: v} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} +} + +func (p pointer) isNil() bool { + return p.v.IsNil() +} + +// grow updates the slice s in place to make it one element longer. +// s must be addressable. +// Returns the (addressable) new element. +func grow(s reflect.Value) reflect.Value { + n, m := s.Len(), s.Cap() + if n < m { + s.SetLen(n + 1) + } else { + s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) + } + return s.Index(n) +} + +func (p pointer) toInt64() *int64 { + return p.v.Interface().(*int64) +} +func (p pointer) toInt64Ptr() **int64 { + return p.v.Interface().(**int64) +} +func (p pointer) toInt64Slice() *[]int64 { + return p.v.Interface().(*[]int64) +} + +var int32ptr = reflect.TypeOf((*int32)(nil)) + +func (p pointer) toInt32() *int32 { + return p.v.Convert(int32ptr).Interface().(*int32) +} + +// The toInt32Ptr/Slice methods don't work because of enums. +// Instead, we must use set/get methods for the int32ptr/slice case. +/* + func (p pointer) toInt32Ptr() **int32 { + return p.v.Interface().(**int32) +} + func (p pointer) toInt32Slice() *[]int32 { + return p.v.Interface().(*[]int32) +} +*/ +func (p pointer) getInt32Ptr() *int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().(*int32) + } + // an enum + return p.v.Elem().Convert(int32PtrType).Interface().(*int32) +} +func (p pointer) setInt32Ptr(v int32) { + // Allocate value in a *int32. Possibly convert that to a *enum. + // Then assign it to a **int32 or **enum. + // Note: we can convert *int32 to *enum, but we can't convert + // **int32 to **enum! + p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) +} + +// getInt32Slice copies []int32 from p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getInt32Slice() []int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().([]int32) + } + // an enum + // Allocate a []int32, then assign []enum's values into it. + // Note: we can't convert []enum to []int32. + slice := p.v.Elem() + s := make([]int32, slice.Len()) + for i := 0; i < slice.Len(); i++ { + s[i] = int32(slice.Index(i).Int()) + } + return s +} + +// setInt32Slice copies []int32 into p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setInt32Slice(v []int32) { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + p.v.Elem().Set(reflect.ValueOf(v)) + return + } + // an enum + // Allocate a []enum, then assign []int32's values into it. + // Note: we can't convert []enum to []int32. + slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) + for i, x := range v { + slice.Index(i).SetInt(int64(x)) + } + p.v.Elem().Set(slice) +} +func (p pointer) appendInt32Slice(v int32) { + grow(p.v.Elem()).SetInt(int64(v)) +} + +func (p pointer) toUint64() *uint64 { + return p.v.Interface().(*uint64) +} +func (p pointer) toUint64Ptr() **uint64 { + return p.v.Interface().(**uint64) +} +func (p pointer) toUint64Slice() *[]uint64 { + return p.v.Interface().(*[]uint64) +} +func (p pointer) toUint32() *uint32 { + return p.v.Interface().(*uint32) +} +func (p pointer) toUint32Ptr() **uint32 { + return p.v.Interface().(**uint32) +} +func (p pointer) toUint32Slice() *[]uint32 { + return p.v.Interface().(*[]uint32) +} +func (p pointer) toBool() *bool { + return p.v.Interface().(*bool) +} +func (p pointer) toBoolPtr() **bool { + return p.v.Interface().(**bool) +} +func (p pointer) toBoolSlice() *[]bool { + return p.v.Interface().(*[]bool) +} +func (p pointer) toFloat64() *float64 { + return p.v.Interface().(*float64) +} +func (p pointer) toFloat64Ptr() **float64 { + return p.v.Interface().(**float64) +} +func (p pointer) toFloat64Slice() *[]float64 { + return p.v.Interface().(*[]float64) +} +func (p pointer) toFloat32() *float32 { + return p.v.Interface().(*float32) +} +func (p pointer) toFloat32Ptr() **float32 { + return p.v.Interface().(**float32) +} +func (p pointer) toFloat32Slice() *[]float32 { + return p.v.Interface().(*[]float32) +} +func (p pointer) toString() *string { + return p.v.Interface().(*string) +} +func (p pointer) toStringPtr() **string { + return p.v.Interface().(**string) +} +func (p pointer) toStringSlice() *[]string { + return p.v.Interface().(*[]string) +} +func (p pointer) toBytes() *[]byte { + return p.v.Interface().(*[]byte) +} +func (p pointer) toBytesSlice() *[][]byte { + return p.v.Interface().(*[][]byte) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return p.v.Interface().(*XXX_InternalExtensions) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return p.v.Interface().(*map[int32]Extension) +} +func (p pointer) getPointer() pointer { + return pointer{v: p.v.Elem()} +} +func (p pointer) setPointer(q pointer) { + p.v.Elem().Set(q.v) +} +func (p pointer) appendPointer(q pointer) { + grow(p.v.Elem()).Set(q.v) +} + +// getPointerSlice copies []*T from p as a new []pointer. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getPointerSlice() []pointer { + if p.v.IsNil() { + return nil + } + n := p.v.Elem().Len() + s := make([]pointer, n) + for i := 0; i < n; i++ { + s[i] = pointer{v: p.v.Elem().Index(i)} + } + return s +} + +// setPointerSlice copies []pointer into p as a new []*T. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setPointerSlice(v []pointer) { + if v == nil { + p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) + return + } + s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) + for _, p := range v { + s = reflect.Append(s, p.v) + } + p.v.Elem().Set(s) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + if p.v.Elem().IsNil() { + return pointer{v: p.v.Elem()} + } + return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct +} + +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + // TODO: check that p.v.Type().Elem() == t? + return p.v +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} + +var atomicLock sync.Mutex diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go new file mode 100644 index 00000000..dbfffe07 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -0,0 +1,313 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 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. + +// +build !purego,!appengine,!js + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "sync/atomic" + "unsafe" +) + +const unsafeAllowed = true + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by its byte offset from the start of the struct. +type field uintptr + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return field(f.Offset) +} + +// invalidField is an invalid field identifier. +const invalidField = ^field(0) + +// zeroField is a noop when calling pointer.offset. +const zeroField = field(0) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { + return f != invalidField +} + +// The pointer type below is for the new table-driven encoder/decoder. +// The implementation here uses unsafe.Pointer to create a generic pointer. +// In pointer_reflect.go we use reflect instead of unsafe to implement +// the same (but slower) interface. +type pointer struct { + p unsafe.Pointer +} + +// size of pointer +var ptrSize = unsafe.Sizeof(uintptr(0)) + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + // Super-tricky - read pointer out of data word of interface value. + // Saves ~25ns over the equivalent: + // return valToPointer(reflect.ValueOf(*i)) + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) { + // Super-tricky - read or get the address of data word of interface value. + if isptr { + // The interface is of pointer type, thus it is a direct interface. + // The data word is the pointer data itself. We take its address. + p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + } else { + // The interface is not of pointer type. The data word is the pointer + // to the data. + p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} + } + if deref { + p.p = *(*unsafe.Pointer)(p.p) + } + return p +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{p: unsafe.Pointer(v.Pointer())} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + // For safety, we should panic if !f.IsValid, however calling panic causes + // this to no longer be inlineable, which is a serious performance cost. + /* + if !f.IsValid() { + panic("invalid field") + } + */ + return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} +} + +func (p pointer) isNil() bool { + return p.p == nil +} + +func (p pointer) toInt64() *int64 { + return (*int64)(p.p) +} +func (p pointer) toInt64Ptr() **int64 { + return (**int64)(p.p) +} +func (p pointer) toInt64Slice() *[]int64 { + return (*[]int64)(p.p) +} +func (p pointer) toInt32() *int32 { + return (*int32)(p.p) +} + +// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. +/* + func (p pointer) toInt32Ptr() **int32 { + return (**int32)(p.p) + } + func (p pointer) toInt32Slice() *[]int32 { + return (*[]int32)(p.p) + } +*/ +func (p pointer) getInt32Ptr() *int32 { + return *(**int32)(p.p) +} +func (p pointer) setInt32Ptr(v int32) { + *(**int32)(p.p) = &v +} + +// getInt32Slice loads a []int32 from p. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getInt32Slice() []int32 { + return *(*[]int32)(p.p) +} + +// setInt32Slice stores a []int32 to p. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setInt32Slice(v []int32) { + *(*[]int32)(p.p) = v +} + +// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? +func (p pointer) appendInt32Slice(v int32) { + s := (*[]int32)(p.p) + *s = append(*s, v) +} + +func (p pointer) toUint64() *uint64 { + return (*uint64)(p.p) +} +func (p pointer) toUint64Ptr() **uint64 { + return (**uint64)(p.p) +} +func (p pointer) toUint64Slice() *[]uint64 { + return (*[]uint64)(p.p) +} +func (p pointer) toUint32() *uint32 { + return (*uint32)(p.p) +} +func (p pointer) toUint32Ptr() **uint32 { + return (**uint32)(p.p) +} +func (p pointer) toUint32Slice() *[]uint32 { + return (*[]uint32)(p.p) +} +func (p pointer) toBool() *bool { + return (*bool)(p.p) +} +func (p pointer) toBoolPtr() **bool { + return (**bool)(p.p) +} +func (p pointer) toBoolSlice() *[]bool { + return (*[]bool)(p.p) +} +func (p pointer) toFloat64() *float64 { + return (*float64)(p.p) +} +func (p pointer) toFloat64Ptr() **float64 { + return (**float64)(p.p) +} +func (p pointer) toFloat64Slice() *[]float64 { + return (*[]float64)(p.p) +} +func (p pointer) toFloat32() *float32 { + return (*float32)(p.p) +} +func (p pointer) toFloat32Ptr() **float32 { + return (**float32)(p.p) +} +func (p pointer) toFloat32Slice() *[]float32 { + return (*[]float32)(p.p) +} +func (p pointer) toString() *string { + return (*string)(p.p) +} +func (p pointer) toStringPtr() **string { + return (**string)(p.p) +} +func (p pointer) toStringSlice() *[]string { + return (*[]string)(p.p) +} +func (p pointer) toBytes() *[]byte { + return (*[]byte)(p.p) +} +func (p pointer) toBytesSlice() *[][]byte { + return (*[][]byte)(p.p) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return (*XXX_InternalExtensions)(p.p) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return (*map[int32]Extension)(p.p) +} + +// getPointerSlice loads []*T from p as a []pointer. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getPointerSlice() []pointer { + // Super-tricky - p should point to a []*T where T is a + // message type. We load it as []pointer. + return *(*[]pointer)(p.p) +} + +// setPointerSlice stores []pointer into p as a []*T. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setPointerSlice(v []pointer) { + // Super-tricky - p should point to a []*T where T is a + // message type. We store it as []pointer. + *(*[]pointer)(p.p) = v +} + +// getPointer loads the pointer at p and returns it. +func (p pointer) getPointer() pointer { + return pointer{p: *(*unsafe.Pointer)(p.p)} +} + +// setPointer stores the pointer q at p. +func (p pointer) setPointer(q pointer) { + *(*unsafe.Pointer)(p.p) = q.p +} + +// append q to the slice pointed to by p. +func (p pointer) appendPointer(q pointer) { + s := (*[]unsafe.Pointer)(p.p) + *s = append(*s, q.p) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + // Super-tricky - read pointer out of data word of interface value. + return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} +} + +// asPointerTo returns a reflect.Value that is a pointer to an +// object of type t stored at p. +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + return reflect.NewAt(t, p.p) +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go new file mode 100644 index 00000000..79668ff5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -0,0 +1,545 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 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 proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" +) + +const debug bool = false + +// Constants that identify the encoding of a value on the wire. +const ( + WireVarint = 0 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 + WireFixed32 = 5 +) + +// tagMap is an optimization over map[int]int for typical protocol buffer +// use-cases. Encoded protocol buffers are often in tag order with small tag +// numbers. +type tagMap struct { + fastTags []int + slowTags map[int]int +} + +// tagMapFastLimit is the upper bound on the tag number that will be stored in +// the tagMap slice rather than its map. +const tagMapFastLimit = 1024 + +func (p *tagMap) get(t int) (int, bool) { + if t > 0 && t < tagMapFastLimit { + if t >= len(p.fastTags) { + return 0, false + } + fi := p.fastTags[t] + return fi, fi >= 0 + } + fi, ok := p.slowTags[t] + return fi, ok +} + +func (p *tagMap) put(t int, fi int) { + if t > 0 && t < tagMapFastLimit { + for len(p.fastTags) < t+1 { + p.fastTags = append(p.fastTags, -1) + } + p.fastTags[t] = fi + return + } + if p.slowTags == nil { + p.slowTags = make(map[int]int) + } + p.slowTags[t] = fi +} + +// StructProperties represents properties for all the fields of a struct. +// decoderTags and decoderOrigNames should only be used by the decoder. +type StructProperties struct { + Prop []*Properties // properties for each field + reqCount int // required count + decoderTags tagMap // map from proto tag to struct field number + decoderOrigNames map[string]int // map from original name to struct field number + order []int // list of struct field numbers in tag order + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties +} + +// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. +// See encode.go, (*Buffer).enc_struct. + +func (sp *StructProperties) Len() int { return len(sp.order) } +func (sp *StructProperties) Less(i, j int) bool { + return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag +} +func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } + +// Properties represents the protocol-specific behavior of a single struct field. +type Properties struct { + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field + oneof bool // whether this is a oneof field + + Default string // default value + HasDefault bool // whether an explicit default was provided + + stype reflect.Type // set for struct types only + sprop *StructProperties // set for struct types only + + mtype reflect.Type // set for map types only + MapKeyProp *Properties // set for map types only + MapValProp *Properties // set for map types only +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s += "," + s += strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName + } + if p.proto3 { + s += ",proto3" + } + if p.oneof { + s += ",oneof" + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(s string) { + // "bytes,49,opt,name=foo,def=hello!" + fields := strings.Split(s, ",") // breaks def=, but handled below. + if len(fields) < 2 { + fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) + return + } + + p.Wire = fields[0] + switch p.Wire { + case "varint": + p.WireType = WireVarint + case "fixed32": + p.WireType = WireFixed32 + case "fixed64": + p.WireType = WireFixed64 + case "zigzag32": + p.WireType = WireVarint + case "zigzag64": + p.WireType = WireVarint + case "bytes", "group": + p.WireType = WireBytes + // no numeric converter for non-numeric types + default: + fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) + return + } + + var err error + p.Tag, err = strconv.Atoi(fields[1]) + if err != nil { + return + } + +outer: + for i := 2; i < len(fields); i++ { + f := fields[i] + switch { + case f == "req": + p.Required = true + case f == "opt": + p.Optional = true + case f == "rep": + p.Repeated = true + case f == "packed": + p.Packed = true + case strings.HasPrefix(f, "name="): + p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] + case strings.HasPrefix(f, "enum="): + p.Enum = f[5:] + case f == "proto3": + p.proto3 = true + case f == "oneof": + p.oneof = true + case strings.HasPrefix(f, "def="): + p.HasDefault = true + p.Default = f[4:] // rest of string + if i+1 < len(fields) { + // Commas aren't escaped, and def is always last. + p.Default += "," + strings.Join(fields[i+1:], ",") + break outer + } + } + } +} + +var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() + +// setFieldProps initializes the field properties for submessages and maps. +func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { + switch t1 := typ; t1.Kind() { + case reflect.Ptr: + if t1.Elem().Kind() == reflect.Struct { + p.stype = t1.Elem() + } + + case reflect.Slice: + if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { + p.stype = t2.Elem() + } + + case reflect.Map: + p.mtype = t1 + p.MapKeyProp = &Properties{} + p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.MapValProp = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + } + + if p.stype != nil { + if lockGetProp { + p.sprop = GetProperties(p.stype) + } else { + p.sprop = getPropertiesLocked(p.stype) + } + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() +) + +// Init populates the properties from a protocol buffer struct tag. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.init(typ, name, tag, f, true) +} + +func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { + // "bytes,49,opt,def=hello!" + p.Name = name + p.OrigName = name + if tag == "" { + return + } + p.Parse(tag) + p.setFieldProps(typ, f, lockGetProp) +} + +var ( + propertiesMu sync.RWMutex + propertiesMap = make(map[reflect.Type]*StructProperties) +) + +// GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. +func GetProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() + return sprop +} + +type ( + oneofFuncsIface interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + oneofWrappersIface interface { + XXX_OneofWrappers() []interface{} + } +) + +// getPropertiesLocked requires that propertiesMu is held. +func getPropertiesLocked(t reflect.Type) *StructProperties { + if prop, ok := propertiesMap[t]; ok { + return prop + } + + prop := new(StructProperties) + // in case of recursive protos, fill this in now. + propertiesMap[t] = prop + + // build properties + prop.Prop = make([]*Properties, t.NumField()) + prop.order = make([]int, t.NumField()) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + p := new(Properties) + name := f.Name + p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + + oneof := f.Tag.Get("protobuf_oneof") // special case + if oneof != "" { + // Oneof fields don't use the traditional protobuf tag. + p.OrigName = oneof + } + prop.Prop[i] = p + prop.order[i] = i + if debug { + print(i, " ", f.Name, " ", t.String(), " ") + if p.Tag > 0 { + print(p.String()) + } + print("\n") + } + } + + // Re-order prop.order. + sort.Sort(prop) + + var oots []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oots = m.XXX_OneofFuncs() + case oneofWrappersIface: + oots = m.XXX_OneofWrappers() + } + if len(oots) > 0 { + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + + // build required counts + // build tags + reqCount := 0 + prop.decoderOrigNames = make(map[string]int) + for i, p := range prop.Prop { + if strings.HasPrefix(p.Name, "XXX_") { + // Internal fields should not appear in tags/origNames maps. + // They are handled specially when encoding and decoding. + continue + } + if p.Required { + reqCount++ + } + prop.decoderTags.put(p.Tag, i) + prop.decoderOrigNames[p.OrigName] = i + } + prop.reqCount = reqCount + + return prop +} + +// A global registry of enum types. +// The generated code will register the generated maps by calling RegisterEnum. + +var enumValueMaps = make(map[string]map[string]int32) + +// RegisterEnum is called from the generated code to install the enum descriptor +// maps into the global table to aid parsing text format protocol buffers. +func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { + if _, ok := enumValueMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumValueMaps[typeName] = valueMap +} + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers + protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypedNils[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { + // Generated code always calls RegisterType with nil x. + // This check is just for extra safety. + protoTypedNils[name] = x + } else { + protoTypedNils[name] = reflect.Zero(t).Interface().(Message) + } + revProtoTypes[t] = name +} + +// RegisterMapType is called from generated code and maps from the fully qualified +// proto name to the native map type of the proto map definition. +func RegisterMapType(x interface{}, name string) { + if reflect.TypeOf(x).Kind() != reflect.Map { + panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) + } + if _, ok := protoMapTypes[name]; ok { + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoMapTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} + +// MessageType returns the message type (pointer to struct) for a named message. +// The type is not guaranteed to implement proto.Message if the name refers to a +// map entry. +func MessageType(name string) reflect.Type { + if t, ok := protoTypedNils[name]; ok { + return reflect.TypeOf(t) + } + return protoMapTypes[name] +} + +// A registry of all linked proto files. +var ( + protoFiles = make(map[string][]byte) // file name => fileDescriptor +) + +// RegisterFile is called from generated code and maps from the +// full file name of a .proto file to its compressed FileDescriptorProto. +func RegisterFile(filename string, fileDescriptor []byte) { + protoFiles[filename] = fileDescriptor +} + +// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. +func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go new file mode 100644 index 00000000..5cb11fa9 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/table_marshal.go @@ -0,0 +1,2776 @@ +// 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 proto + +import ( + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// a sizer takes a pointer to a field and the size of its tag, computes the size of +// the encoded data. +type sizer func(pointer, int) int + +// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), +// marshals the field to the end of the slice, returns the slice and error (if any). +type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) + +// marshalInfo is the information used for marshaling a message. +type marshalInfo struct { + typ reflect.Type + fields []*marshalFieldInfo + unrecognized field // offset of XXX_unrecognized + extensions field // offset of XXX_InternalExtensions + v1extensions field // offset of XXX_extensions + sizecache field // offset of XXX_sizecache + initialized int32 // 0 -- only typ is set, 1 -- fully initialized + messageset bool // uses message set wire format + hasmarshaler bool // has custom marshaler + sync.RWMutex // protect extElems map, also for initialization + extElems map[int32]*marshalElemInfo // info of extension elements +} + +// marshalFieldInfo is the information used for marshaling a field of a message. +type marshalFieldInfo struct { + field field + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isPointer bool + required bool // field is required + name string // name of the field, for error reporting + oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements +} + +// marshalElemInfo is the information used for marshaling an extension or oneof element. +type marshalElemInfo struct { + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) + deref bool // dereference the pointer before operating on it; implies isptr +} + +var ( + marshalInfoMap = map[reflect.Type]*marshalInfo{} + marshalInfoLock sync.Mutex +) + +// getMarshalInfo returns the information to marshal a given type of message. +// The info it returns may not necessarily initialized. +// t is the type of the message (NOT the pointer to it). +func getMarshalInfo(t reflect.Type) *marshalInfo { + marshalInfoLock.Lock() + u, ok := marshalInfoMap[t] + if !ok { + u = &marshalInfo{typ: t} + marshalInfoMap[t] = u + } + marshalInfoLock.Unlock() + return u +} + +// Size is the entry point from generated code, +// and should be ONLY called by generated code. +// It computes the size of encoded data of msg. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Size(msg Message) int { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return 0 + } + return u.size(ptr) +} + +// Marshal is the entry point from generated code, +// and should be ONLY called by generated code. +// It marshals msg to the end of b. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return b, ErrNil + } + return u.marshal(b, ptr, deterministic) +} + +func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { + // u := a.marshal, but atomically. + // We use an atomic here to ensure memory consistency. + u := atomicLoadMarshalInfo(&a.marshal) + if u == nil { + // Get marshal information from type of message. + t := reflect.ValueOf(msg).Type() + if t.Kind() != reflect.Ptr { + panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) + } + u = getMarshalInfo(t.Elem()) + // Store it in the cache for later users. + // a.marshal = u, but atomically. + atomicStoreMarshalInfo(&a.marshal, u) + } + return u +} + +// size is the main function to compute the size of the encoded data of a message. +// ptr is the pointer to the message. +func (u *marshalInfo) size(ptr pointer) int { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b, _ := m.Marshal() + return len(b) + } + + n := 0 + for _, f := range u.fields { + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + n += f.sizer(ptr.offset(f.field), f.tagsize) + } + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + n += u.sizeMessageSet(e) + } else { + n += u.sizeExtensions(e) + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + n += u.sizeV1Extensions(m) + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + n += len(s) + } + // cache the result for use in marshal + if u.sizecache.IsValid() { + atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) + } + return n +} + +// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), +// fall back to compute the size. +func (u *marshalInfo) cachedsize(ptr pointer) int { + if u.sizecache.IsValid() { + return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) + } + return u.size(ptr) +} + +// marshal is the main function to marshal a message. It takes a byte slice and appends +// the encoded data to the end of the slice, returns the slice and error (if any). +// ptr is the pointer to the message. +// If deterministic is true, map is marshaled in deterministic order. +func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b1, err := m.Marshal() + b = append(b, b1...) + return b, err + } + + var err, errLater error + // The old marshaler encodes extensions at beginning. + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + b, err = u.appendMessageSet(b, e, deterministic) + } else { + b, err = u.appendExtensions(b, e, deterministic) + } + if err != nil { + return b, err + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + b, err = u.appendV1Extensions(b, m, deterministic) + if err != nil { + return b, err + } + } + for _, f := range u.fields { + if f.required { + if ptr.offset(f.field).getPointer().isNil() { + // Required field is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name} + } + continue + } + } + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) + if err != nil { + if err1, ok := err.(*RequiredNotSetError); ok { + // Required field in submessage is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name + "." + err1.field} + } + continue + } + if err == errRepeatedHasNil { + err = errors.New("proto: repeated field " + f.name + " has nil element") + } + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return b, err + } + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + b = append(b, s...) + } + return b, errLater +} + +// computeMarshalInfo initializes the marshal info. +func (u *marshalInfo) computeMarshalInfo() { + u.Lock() + defer u.Unlock() + if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock + return + } + + t := u.typ + u.unrecognized = invalidField + u.extensions = invalidField + u.v1extensions = invalidField + u.sizecache = invalidField + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if reflect.PtrTo(t).Implements(marshalerType) { + u.hasmarshaler = true + atomic.StoreInt32(&u.initialized, 1) + return + } + + // get oneof implementers + var oneofImplementers []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() + } + + n := t.NumField() + + // deal with XXX fields first + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if !strings.HasPrefix(f.Name, "XXX_") { + continue + } + switch f.Name { + case "XXX_sizecache": + u.sizecache = toField(&f) + case "XXX_unrecognized": + u.unrecognized = toField(&f) + case "XXX_InternalExtensions": + u.extensions = toField(&f) + u.messageset = f.Tag.Get("protobuf_messageset") == "1" + case "XXX_extensions": + u.v1extensions = toField(&f) + case "XXX_NoUnkeyedLiteral": + // nothing to do + default: + panic("unknown XXX field: " + f.Name) + } + n-- + } + + // normal fields + fields := make([]marshalFieldInfo, n) // batch allocation + u.fields = make([]*marshalFieldInfo, 0, n) + for i, j := 0, 0; i < t.NumField(); i++ { + f := t.Field(i) + + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + field := &fields[j] + j++ + field.name = f.Name + u.fields = append(u.fields, field) + if f.Tag.Get("protobuf_oneof") != "" { + field.computeOneofFieldInfo(&f, oneofImplementers) + continue + } + if f.Tag.Get("protobuf") == "" { + // field has no tag (not in generated message), ignore it + u.fields = u.fields[:len(u.fields)-1] + j-- + continue + } + field.computeMarshalFieldInfo(&f) + } + + // fields are marshaled in tag order on the wire. + sort.Sort(byTag(u.fields)) + + atomic.StoreInt32(&u.initialized, 1) +} + +// helper for sorting fields by tag +type byTag []*marshalFieldInfo + +func (a byTag) Len() int { return len(a) } +func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } + +// getExtElemInfo returns the information to marshal an extension element. +// The info it returns is initialized. +func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { + // get from cache first + u.RLock() + e, ok := u.extElems[desc.Field] + u.RUnlock() + if ok { + return e + } + + t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct + tags := strings.Split(desc.Tag, ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct { + t = t.Elem() + } + sizer, marshaler := typeMarshaler(t, tags, false, false) + var deref bool + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + t = reflect.PtrTo(t) + deref = true + } + e = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizer, + marshaler: marshaler, + isptr: t.Kind() == reflect.Ptr, + deref: deref, + } + + // update cache + u.Lock() + if u.extElems == nil { + u.extElems = make(map[int32]*marshalElemInfo) + } + u.extElems[desc.Field] = e + u.Unlock() + return e +} + +// computeMarshalFieldInfo fills up the information to marshal a field. +func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { + // parse protobuf tag of the field. + // tag has format of "bytes,49,opt,name=foo,def=hello!" + tags := strings.Split(f.Tag.Get("protobuf"), ",") + if tags[0] == "" { + return + } + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + if tags[2] == "req" { + fi.required = true + } + fi.setTag(f, tag, wt) + fi.setMarshaler(f, tags) +} + +func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { + fi.field = toField(f) + fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. + fi.isPointer = true + fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) + fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) + + ityp := f.Type // interface type + for _, o := range oneofImplementers { + t := reflect.TypeOf(o) + if !t.Implements(ityp) { + continue + } + sf := t.Elem().Field(0) // oneof implementer is a struct with a single field + tags := strings.Split(sf.Tag.Get("protobuf"), ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value + fi.oneofElems[t.Elem()] = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizer, + marshaler: marshaler, + } + } +} + +// wiretype returns the wire encoding of the type. +func wiretype(encoding string) uint64 { + switch encoding { + case "fixed32": + return WireFixed32 + case "fixed64": + return WireFixed64 + case "varint", "zigzag32", "zigzag64": + return WireVarint + case "bytes": + return WireBytes + case "group": + return WireStartGroup + } + panic("unknown wire type " + encoding) +} + +// setTag fills up the tag (in wire format) and its size in the info of a field. +func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { + fi.field = toField(f) + fi.wiretag = uint64(tag)<<3 | wt + fi.tagsize = SizeVarint(uint64(tag) << 3) +} + +// setMarshaler fills up the sizer and marshaler in the info of a field. +func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { + switch f.Type.Kind() { + case reflect.Map: + // map field + fi.isPointer = true + fi.sizer, fi.marshaler = makeMapMarshaler(f) + return + case reflect.Ptr, reflect.Slice: + fi.isPointer = true + } + fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) +} + +// typeMarshaler returns the sizer and marshaler of a given field. +// t is the type of the field. +// tags is the generated "protobuf" tag of the field. +// If nozero is true, zero value is not marshaled to the wire. +// If oneof is true, it is a oneof field. +func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { + encoding := tags[0] + + pointer := false + slice := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + packed := false + proto3 := false + validateUTF8 := true + for i := 2; i < len(tags); i++ { + if tags[i] == "packed" { + packed = true + } + if tags[i] == "proto3" { + proto3 = true + } + } + validateUTF8 = validateUTF8 && proto3 + + switch t.Kind() { + case reflect.Bool: + if pointer { + return sizeBoolPtr, appendBoolPtr + } + if slice { + if packed { + return sizeBoolPackedSlice, appendBoolPackedSlice + } + return sizeBoolSlice, appendBoolSlice + } + if nozero { + return sizeBoolValueNoZero, appendBoolValueNoZero + } + return sizeBoolValue, appendBoolValue + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixed32Ptr, appendFixed32Ptr + } + if slice { + if packed { + return sizeFixed32PackedSlice, appendFixed32PackedSlice + } + return sizeFixed32Slice, appendFixed32Slice + } + if nozero { + return sizeFixed32ValueNoZero, appendFixed32ValueNoZero + } + return sizeFixed32Value, appendFixed32Value + case "varint": + if pointer { + return sizeVarint32Ptr, appendVarint32Ptr + } + if slice { + if packed { + return sizeVarint32PackedSlice, appendVarint32PackedSlice + } + return sizeVarint32Slice, appendVarint32Slice + } + if nozero { + return sizeVarint32ValueNoZero, appendVarint32ValueNoZero + } + return sizeVarint32Value, appendVarint32Value + } + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixedS32Ptr, appendFixedS32Ptr + } + if slice { + if packed { + return sizeFixedS32PackedSlice, appendFixedS32PackedSlice + } + return sizeFixedS32Slice, appendFixedS32Slice + } + if nozero { + return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero + } + return sizeFixedS32Value, appendFixedS32Value + case "varint": + if pointer { + return sizeVarintS32Ptr, appendVarintS32Ptr + } + if slice { + if packed { + return sizeVarintS32PackedSlice, appendVarintS32PackedSlice + } + return sizeVarintS32Slice, appendVarintS32Slice + } + if nozero { + return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero + } + return sizeVarintS32Value, appendVarintS32Value + case "zigzag32": + if pointer { + return sizeZigzag32Ptr, appendZigzag32Ptr + } + if slice { + if packed { + return sizeZigzag32PackedSlice, appendZigzag32PackedSlice + } + return sizeZigzag32Slice, appendZigzag32Slice + } + if nozero { + return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero + } + return sizeZigzag32Value, appendZigzag32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixed64Ptr, appendFixed64Ptr + } + if slice { + if packed { + return sizeFixed64PackedSlice, appendFixed64PackedSlice + } + return sizeFixed64Slice, appendFixed64Slice + } + if nozero { + return sizeFixed64ValueNoZero, appendFixed64ValueNoZero + } + return sizeFixed64Value, appendFixed64Value + case "varint": + if pointer { + return sizeVarint64Ptr, appendVarint64Ptr + } + if slice { + if packed { + return sizeVarint64PackedSlice, appendVarint64PackedSlice + } + return sizeVarint64Slice, appendVarint64Slice + } + if nozero { + return sizeVarint64ValueNoZero, appendVarint64ValueNoZero + } + return sizeVarint64Value, appendVarint64Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixedS64Ptr, appendFixedS64Ptr + } + if slice { + if packed { + return sizeFixedS64PackedSlice, appendFixedS64PackedSlice + } + return sizeFixedS64Slice, appendFixedS64Slice + } + if nozero { + return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero + } + return sizeFixedS64Value, appendFixedS64Value + case "varint": + if pointer { + return sizeVarintS64Ptr, appendVarintS64Ptr + } + if slice { + if packed { + return sizeVarintS64PackedSlice, appendVarintS64PackedSlice + } + return sizeVarintS64Slice, appendVarintS64Slice + } + if nozero { + return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero + } + return sizeVarintS64Value, appendVarintS64Value + case "zigzag64": + if pointer { + return sizeZigzag64Ptr, appendZigzag64Ptr + } + if slice { + if packed { + return sizeZigzag64PackedSlice, appendZigzag64PackedSlice + } + return sizeZigzag64Slice, appendZigzag64Slice + } + if nozero { + return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero + } + return sizeZigzag64Value, appendZigzag64Value + } + case reflect.Float32: + if pointer { + return sizeFloat32Ptr, appendFloat32Ptr + } + if slice { + if packed { + return sizeFloat32PackedSlice, appendFloat32PackedSlice + } + return sizeFloat32Slice, appendFloat32Slice + } + if nozero { + return sizeFloat32ValueNoZero, appendFloat32ValueNoZero + } + return sizeFloat32Value, appendFloat32Value + case reflect.Float64: + if pointer { + return sizeFloat64Ptr, appendFloat64Ptr + } + if slice { + if packed { + return sizeFloat64PackedSlice, appendFloat64PackedSlice + } + return sizeFloat64Slice, appendFloat64Slice + } + if nozero { + return sizeFloat64ValueNoZero, appendFloat64ValueNoZero + } + return sizeFloat64Value, appendFloat64Value + case reflect.String: + if validateUTF8 { + if pointer { + return sizeStringPtr, appendUTF8StringPtr + } + if slice { + return sizeStringSlice, appendUTF8StringSlice + } + if nozero { + return sizeStringValueNoZero, appendUTF8StringValueNoZero + } + return sizeStringValue, appendUTF8StringValue + } + if pointer { + return sizeStringPtr, appendStringPtr + } + if slice { + return sizeStringSlice, appendStringSlice + } + if nozero { + return sizeStringValueNoZero, appendStringValueNoZero + } + return sizeStringValue, appendStringValue + case reflect.Slice: + if slice { + return sizeBytesSlice, appendBytesSlice + } + if oneof { + // Oneof bytes field may also have "proto3" tag. + // We want to marshal it as a oneof field. Do this + // check before the proto3 check. + return sizeBytesOneof, appendBytesOneof + } + if proto3 { + return sizeBytes3, appendBytes3 + } + return sizeBytes, appendBytes + case reflect.Struct: + switch encoding { + case "group": + if slice { + return makeGroupSliceMarshaler(getMarshalInfo(t)) + } + return makeGroupMarshaler(getMarshalInfo(t)) + case "bytes": + if slice { + return makeMessageSliceMarshaler(getMarshalInfo(t)) + } + return makeMessageMarshaler(getMarshalInfo(t)) + } + } + panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) +} + +// Below are functions to size/marshal a specific type of a field. +// They are stored in the field's info, and called by function pointers. +// They have type sizer or marshaler. + +func sizeFixed32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixedS32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFloat32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + return (4 + tagsize) * len(s) +} +func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixed64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFixedS64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFloat64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + return (8 + tagsize) * len(s) +} +func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeVarint32Value(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarint32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarint64Value(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + return SizeVarint(v) + tagsize +} +func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return SizeVarint(v) + tagsize +} +func sizeVarint64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return SizeVarint(*p) + tagsize +} +func sizeVarint64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(v) + tagsize + } + return n +} +func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize + } + return n +} +func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize + } + return n +} +func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeBoolValue(_ pointer, tagsize int) int { + return 1 + tagsize +} +func sizeBoolValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toBool() + if !v { + return 0 + } + return 1 + tagsize +} +func sizeBoolPtr(ptr pointer, tagsize int) int { + p := *ptr.toBoolPtr() + if p == nil { + return 0 + } + return 1 + tagsize +} +func sizeBoolSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + return (1 + tagsize) * len(s) +} +func sizeBoolPackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return 0 + } + return len(s) + SizeVarint(uint64(len(s))) + tagsize +} +func sizeStringValue(ptr pointer, tagsize int) int { + v := *ptr.toString() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toString() + if v == "" { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringPtr(ptr pointer, tagsize int) int { + p := *ptr.toStringPtr() + if p == nil { + return 0 + } + v := *p + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringSlice(ptr pointer, tagsize int) int { + s := *ptr.toStringSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} +func sizeBytes(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if v == nil { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytes3(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if len(v) == 0 { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesOneof(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesSlice(ptr pointer, tagsize int) int { + s := *ptr.toBytesSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} + +// appendFixed32 appends an encoded fixed32 to b. +func appendFixed32(b []byte, v uint32) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24)) + return b +} + +// appendFixed64 appends an encoded fixed64 to b. +func appendFixed64(b []byte, v uint64) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24), + byte(v>>32), + byte(v>>40), + byte(v>>48), + byte(v>>56)) + return b +} + +// appendVarint appends an encoded varint to b. +func appendVarint(b []byte, v uint64) []byte { + // TODO: make 1-byte (maybe 2-byte) case inline-able, once we + // have non-leaf inliner. + switch { + case v < 1<<7: + b = append(b, byte(v)) + case v < 1<<14: + b = append(b, + byte(v&0x7f|0x80), + byte(v>>7)) + case v < 1<<21: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte(v>>14)) + case v < 1<<28: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte(v>>21)) + case v < 1<<35: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte(v>>28)) + case v < 1<<42: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte(v>>35)) + case v < 1<<49: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte(v>>42)) + case v < 1<<56: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte(v>>49)) + case v < 1<<63: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte(v>>56)) + default: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte((v>>56)&0x7f|0x80), + 1) + } + return b +} + +func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, *p) + return b, nil +} +func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(*p)) + return b, nil +} +func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(*p)) + return b, nil +} +func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, *p) + return b, nil +} +func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(*p)) + return b, nil +} +func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(*p)) + return b, nil +} +func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, *p) + return b, nil +} +func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + } + return b, nil +} +func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, v) + } + return b, nil +} +func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + if !v { + return b, nil + } + b = appendVarint(b, wiretag) + b = append(b, 1) + return b, nil +} + +func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toBoolPtr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + if *p { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(len(s))) + for _, v := range s { + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + if v == "" { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toStringSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} +func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if v == "" { + return b, nil + } + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + s := *ptr.toStringSlice() + for _, v := range s { + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if v == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if len(v) == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBytesSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} + +// makeGroupMarshaler returns the sizer and marshaler for a group. +// u is the marshal info of the underlying message. +func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + return u.size(p) + 2*tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + var err error + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, p, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + return b, err + } +} + +// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. +// u is the marshal info of the underlying message. +func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + n += u.size(v) + 2*tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, v, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMessageMarshaler returns the sizer and marshaler for a message field. +// u is the marshal info of the message. +func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.size(p) + return siz + SizeVarint(uint64(siz)) + tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(p) + b = appendVarint(b, uint64(siz)) + return u.marshal(b, p, deterministic) + } +} + +// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. +// u is the marshal info of the message. +func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + siz := u.size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(v) + b = appendVarint(b, uint64(siz)) + b, err = u.marshal(b, v, deterministic) + + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMapMarshaler returns the sizer and marshaler for a map field. +// f is the pointer to the reflect data structure of the field. +func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { + // figure out key and value type + t := f.Type + keyType := t.Key() + valType := t.Elem() + keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") + valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") + keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map + valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map + keyWireTag := 1<<3 | wiretype(keyTags[0]) + valWireTag := 2<<3 | wiretype(valTags[0]) + + // We create an interface to get the addresses of the map key and value. + // If value is pointer-typed, the interface is a direct interface, the + // idata itself is the value. Otherwise, the idata is the pointer to the + // value. + // Key cannot be pointer-typed. + valIsPtr := valType.Kind() == reflect.Ptr + + // If value is a message with nested maps, calling + // valSizer in marshal may be quadratic. We should use + // cached version in marshal (but not in size). + // If value is not message type, we don't have size cache, + // but it cannot be nested either. Just use valSizer. + valCachedSizer := valSizer + if valIsPtr && valType.Elem().Kind() == reflect.Struct { + u := getMarshalInfo(valType.Elem()) + valCachedSizer = func(ptr pointer, tagsize int) int { + // Same as message sizer, but use cache. + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.cachedsize(p) + return siz + SizeVarint(uint64(siz)) + tagsize + } + } + return func(ptr pointer, tagsize int) int { + m := ptr.asPointerTo(t).Elem() // the map + n := 0 + for _, k := range m.MapKeys() { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value + siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { + m := ptr.asPointerTo(t).Elem() // the map + var err error + keys := m.MapKeys() + if len(keys) > 1 && deterministic { + sort.Sort(mapKeys(keys)) + } + + var nerr nonFatal + for _, k := range keys { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value + b = appendVarint(b, tag) + siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + b = appendVarint(b, uint64(siz)) + b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) + if !nerr.Merge(err) { + return b, err + } + b, err = valMarshaler(b, vaddr, valWireTag, deterministic) + if err != ErrNil && !nerr.Merge(err) { // allow nil value in map + return b, err + } + } + return b, nerr.E + } +} + +// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. +// fi is the marshal info of the field. +// f is the pointer to the reflect data structure of the field. +func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { + // Oneof field is an interface. We need to get the actual data type on the fly. + t := f.Type + return func(ptr pointer, _ int) int { + p := ptr.getInterfacePointer() + if p.isNil() { + return 0 + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + e := fi.oneofElems[telem] + return e.sizer(p, e.tagsize) + }, + func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { + p := ptr.getInterfacePointer() + if p.isNil() { + return b, nil + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { + return b, errOneofHasNil + } + e := fi.oneofElems[telem] + return e.marshaler(b, p, e.wiretag, deterministic) + } +} + +// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. +func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + n += ei.sizer(p, ei.tagsize) + } + mu.Unlock() + return n +} + +// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. +func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + // Not sure this is required, but the old code does it. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// message set format is: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } + +// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field +// in message set format (above). +func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for id, e := range m { + n += 2 // start group, end group. tag = 1 (size=1) + n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + siz := len(msgWithLen) + n += siz + 1 // message, tag = 3 (size=1) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + n += ei.sizer(p, 1) // message, tag = 3 (size=1) + } + mu.Unlock() + return n +} + +// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) +// to the end of byte slice b. +func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for id, e := range m { + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + if !nerr.Merge(err) { + return b, err + } + b = append(b, 1<<3|WireEndGroup) + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, id := range keys { + e := m[int32(id)] + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + b = append(b, 1<<3|WireEndGroup) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// sizeV1Extensions computes the size of encoded data for a V1-API extension field. +func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { + if m == nil { + return 0 + } + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + n += ei.sizer(p, ei.tagsize) + } + return n +} + +// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. +func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { + if m == nil { + return b, nil + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + var err error + var nerr nonFatal + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr, ei.deref) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// newMarshaler is the interface representing objects that can marshal themselves. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newMarshaler interface { + XXX_Size() int + XXX_Marshal(b []byte, deterministic bool) ([]byte, error) +} + +// Size returns the encoded size of a protocol buffer message. +// This is the main entry point. +func Size(pb Message) int { + if m, ok := pb.(newMarshaler); ok { + return m.XXX_Size() + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + b, _ := m.Marshal() + return len(b) + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return 0 + } + var info InternalMessageInfo + return info.Size(pb) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, returning the data. +// This is the main entry point. +func Marshal(pb Message) ([]byte, error) { + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + b := make([]byte, 0, siz) + return m.XXX_Marshal(b, false) + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + return m.Marshal() + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return nil, ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + b := make([]byte, 0, siz) + return info.Marshal(b, pb, false) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, writing the result to the +// Buffer. +// This is an alternative entry point. It is not necessary to use +// a Buffer for most applications. +func (p *Buffer) Marshal(pb Message) error { + var err error + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + p.grow(siz) // make sure buf has enough capacity + p.buf, err = m.XXX_Marshal(p.buf, p.deterministic) + return err + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + b, err := m.Marshal() + p.buf = append(p.buf, b...) + return err + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + p.grow(siz) // make sure buf has enough capacity + p.buf, err = info.Marshal(p.buf, pb, p.deterministic) + return err +} + +// grow grows the buffer's capacity, if necessary, to guarantee space for +// another n bytes. After grow(n), at least n bytes can be written to the +// buffer without another allocation. +func (p *Buffer) grow(n int) { + need := len(p.buf) + n + if need <= cap(p.buf) { + return + } + newCap := len(p.buf) * 2 + if newCap < need { + newCap = need + } + p.buf = append(make([]byte, 0, newCap), p.buf...) +} diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go new file mode 100644 index 00000000..acee2fc5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go @@ -0,0 +1,2053 @@ +// 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 proto + +import ( + "errors" + "fmt" + "io" + "math" + "reflect" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// Unmarshal is the entry point from the generated .pb.go files. +// This function is not intended to be used by non-generated code. +// This function is not subject to any compatibility guarantee. +// msg contains a pointer to a protocol buffer struct. +// b is the data to be unmarshaled into the protocol buffer. +// a is a pointer to a place to store cached unmarshal information. +func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { + // Load the unmarshal information for this message type. + // The atomic load ensures memory consistency. + u := atomicLoadUnmarshalInfo(&a.unmarshal) + if u == nil { + // Slow path: find unmarshal info for msg, update a with it. + u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) + atomicStoreUnmarshalInfo(&a.unmarshal, u) + } + // Then do the unmarshaling. + err := u.unmarshal(toPointer(&msg), b) + return err +} + +type unmarshalInfo struct { + typ reflect.Type // type of the protobuf struct + + // 0 = only typ field is initialized + // 1 = completely initialized + initialized int32 + lock sync.Mutex // prevents double initialization + dense []unmarshalFieldInfo // fields indexed by tag # + sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # + reqFields []string // names of required fields + reqMask uint64 // 1< 0 { + // Read tag and wire type. + // Special case 1 and 2 byte varints. + var x uint64 + if b[0] < 128 { + x = uint64(b[0]) + b = b[1:] + } else if len(b) >= 2 && b[1] < 128 { + x = uint64(b[0]&0x7f) + uint64(b[1])<<7 + b = b[2:] + } else { + var n int + x, n = decodeVarint(b) + if n == 0 { + return io.ErrUnexpectedEOF + } + b = b[n:] + } + tag := x >> 3 + wire := int(x) & 7 + + // Dispatch on the tag to one of the unmarshal* functions below. + var f unmarshalFieldInfo + if tag < uint64(len(u.dense)) { + f = u.dense[tag] + } else { + f = u.sparse[tag] + } + if fn := f.unmarshal; fn != nil { + var err error + b, err = fn(b, m.offset(f.field), wire) + if err == nil { + reqMask |= f.reqMask + continue + } + if r, ok := err.(*RequiredNotSetError); ok { + // Remember this error, but keep parsing. We need to produce + // a full parse even if a required field is missing. + if errLater == nil { + errLater = r + } + reqMask |= f.reqMask + continue + } + if err != errInternalBadWireType { + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return err + } + // Fragments with bad wire type are treated as unknown fields. + } + + // Unknown tag. + if !u.unrecognized.IsValid() { + // Don't keep unrecognized data; just skip it. + var err error + b, err = skipField(b, wire) + if err != nil { + return err + } + continue + } + // Keep unrecognized data around. + // maybe in extensions, maybe in the unrecognized field. + z := m.offset(u.unrecognized).toBytes() + var emap map[int32]Extension + var e Extension + for _, r := range u.extensionRanges { + if uint64(r.Start) <= tag && tag <= uint64(r.End) { + if u.extensions.IsValid() { + mp := m.offset(u.extensions).toExtensions() + emap = mp.extensionsWrite() + e = emap[int32(tag)] + z = &e.enc + break + } + if u.oldExtensions.IsValid() { + p := m.offset(u.oldExtensions).toOldExtensions() + emap = *p + if emap == nil { + emap = map[int32]Extension{} + *p = emap + } + e = emap[int32(tag)] + z = &e.enc + break + } + panic("no extensions field available") + } + } + + // Use wire type to skip data. + var err error + b0 := b + b, err = skipField(b, wire) + if err != nil { + return err + } + *z = encodeVarint(*z, tag<<3|uint64(wire)) + *z = append(*z, b0[:len(b0)-len(b)]...) + + if emap != nil { + emap[int32(tag)] = e + } + } + if reqMask != u.reqMask && errLater == nil { + // A required field of this message is missing. + for _, n := range u.reqFields { + if reqMask&1 == 0 { + errLater = &RequiredNotSetError{n} + } + reqMask >>= 1 + } + } + return errLater +} + +// computeUnmarshalInfo fills in u with information for use +// in unmarshaling protocol buffers of type u.typ. +func (u *unmarshalInfo) computeUnmarshalInfo() { + u.lock.Lock() + defer u.lock.Unlock() + if u.initialized != 0 { + return + } + t := u.typ + n := t.NumField() + + // Set up the "not found" value for the unrecognized byte buffer. + // This is the default for proto3. + u.unrecognized = invalidField + u.extensions = invalidField + u.oldExtensions = invalidField + + // List of the generated type and offset for each oneof field. + type oneofField struct { + ityp reflect.Type // interface type of oneof field + field field // offset in containing message + } + var oneofFields []oneofField + + for i := 0; i < n; i++ { + f := t.Field(i) + if f.Name == "XXX_unrecognized" { + // The byte slice used to hold unrecognized input is special. + if f.Type != reflect.TypeOf(([]byte)(nil)) { + panic("bad type for XXX_unrecognized field: " + f.Type.Name()) + } + u.unrecognized = toField(&f) + continue + } + if f.Name == "XXX_InternalExtensions" { + // Ditto here. + if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { + panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) + } + u.extensions = toField(&f) + if f.Tag.Get("protobuf_messageset") == "1" { + u.isMessageSet = true + } + continue + } + if f.Name == "XXX_extensions" { + // An older form of the extensions field. + if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) { + panic("bad type for XXX_extensions field: " + f.Type.Name()) + } + u.oldExtensions = toField(&f) + continue + } + if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { + continue + } + + oneof := f.Tag.Get("protobuf_oneof") + if oneof != "" { + oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) + // The rest of oneof processing happens below. + continue + } + + tags := f.Tag.Get("protobuf") + tagArray := strings.Split(tags, ",") + if len(tagArray) < 2 { + panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) + } + tag, err := strconv.Atoi(tagArray[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tagArray[1]) + } + + name := "" + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + } + + // Extract unmarshaling function from the field (its type and tags). + unmarshal := fieldUnmarshaler(&f) + + // Required field? + var reqMask uint64 + if tagArray[2] == "req" { + bit := len(u.reqFields) + u.reqFields = append(u.reqFields, name) + reqMask = uint64(1) << uint(bit) + // TODO: if we have more than 64 required fields, we end up + // not verifying that all required fields are present. + // Fix this, perhaps using a count of required fields? + } + + // Store the info in the correct slot in the message. + u.setTag(tag, toField(&f), unmarshal, reqMask, name) + } + + // Find any types associated with oneof fields. + var oneofImplementers []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() + } + for _, v := range oneofImplementers { + tptr := reflect.TypeOf(v) // *Msg_X + typ := tptr.Elem() // Msg_X + + f := typ.Field(0) // oneof implementers have one field + baseUnmarshal := fieldUnmarshaler(&f) + tags := strings.Split(f.Tag.Get("protobuf"), ",") + fieldNum, err := strconv.Atoi(tags[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tags[1]) + } + var name string + for _, tag := range tags { + if strings.HasPrefix(tag, "name=") { + name = strings.TrimPrefix(tag, "name=") + break + } + } + + // Find the oneof field that this struct implements. + // Might take O(n^2) to process all of the oneofs, but who cares. + for _, of := range oneofFields { + if tptr.Implements(of.ityp) { + // We have found the corresponding interface for this struct. + // That lets us know where this struct should be stored + // when we encounter it during unmarshaling. + unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) + u.setTag(fieldNum, of.field, unmarshal, 0, name) + } + } + + } + + // Get extension ranges, if any. + fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") + if fn.IsValid() { + if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { + panic("a message with extensions, but no extensions field in " + t.Name()) + } + u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) + } + + // Explicitly disallow tag 0. This will ensure we flag an error + // when decoding a buffer of all zeros. Without this code, we + // would decode and skip an all-zero buffer of even length. + // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. + u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { + return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) + }, 0, "") + + // Set mask for required field check. + u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? + for len(u.dense) <= tag { + u.dense = append(u.dense, unmarshalFieldInfo{}) + } + u.dense[tag] = i + return + } + if u.sparse == nil { + u.sparse = map[uint64]unmarshalFieldInfo{} + } + u.sparse[uint64(tag)] = i +} + +// fieldUnmarshaler returns an unmarshaler for the given field. +func fieldUnmarshaler(f *reflect.StructField) unmarshaler { + if f.Type.Kind() == reflect.Map { + return makeUnmarshalMap(f) + } + return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) +} + +// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. +func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { + tagArray := strings.Split(tags, ",") + encoding := tagArray[0] + name := "unknown" + proto3 := false + validateUTF8 := true + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + if tag == "proto3" { + proto3 = true + } + } + validateUTF8 = validateUTF8 && proto3 + + // Figure out packaging (pointer, slice, or both) + slice := false + pointer := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + // We'll never have both pointer and slice for basic types. + if pointer && slice && t.Kind() != reflect.Struct { + panic("both pointer and slice for basic type in " + t.Name()) + } + + switch t.Kind() { + case reflect.Bool: + if pointer { + return unmarshalBoolPtr + } + if slice { + return unmarshalBoolSlice + } + return unmarshalBoolValue + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixedS32Ptr + } + if slice { + return unmarshalFixedS32Slice + } + return unmarshalFixedS32Value + case "varint": + // this could be int32 or enum + if pointer { + return unmarshalInt32Ptr + } + if slice { + return unmarshalInt32Slice + } + return unmarshalInt32Value + case "zigzag32": + if pointer { + return unmarshalSint32Ptr + } + if slice { + return unmarshalSint32Slice + } + return unmarshalSint32Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixedS64Ptr + } + if slice { + return unmarshalFixedS64Slice + } + return unmarshalFixedS64Value + case "varint": + if pointer { + return unmarshalInt64Ptr + } + if slice { + return unmarshalInt64Slice + } + return unmarshalInt64Value + case "zigzag64": + if pointer { + return unmarshalSint64Ptr + } + if slice { + return unmarshalSint64Slice + } + return unmarshalSint64Value + } + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixed32Ptr + } + if slice { + return unmarshalFixed32Slice + } + return unmarshalFixed32Value + case "varint": + if pointer { + return unmarshalUint32Ptr + } + if slice { + return unmarshalUint32Slice + } + return unmarshalUint32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixed64Ptr + } + if slice { + return unmarshalFixed64Slice + } + return unmarshalFixed64Value + case "varint": + if pointer { + return unmarshalUint64Ptr + } + if slice { + return unmarshalUint64Slice + } + return unmarshalUint64Value + } + case reflect.Float32: + if pointer { + return unmarshalFloat32Ptr + } + if slice { + return unmarshalFloat32Slice + } + return unmarshalFloat32Value + case reflect.Float64: + if pointer { + return unmarshalFloat64Ptr + } + if slice { + return unmarshalFloat64Slice + } + return unmarshalFloat64Value + case reflect.Map: + panic("map type in typeUnmarshaler in " + t.Name()) + case reflect.Slice: + if pointer { + panic("bad pointer in slice case in " + t.Name()) + } + if slice { + return unmarshalBytesSlice + } + return unmarshalBytesValue + case reflect.String: + if validateUTF8 { + if pointer { + return unmarshalUTF8StringPtr + } + if slice { + return unmarshalUTF8StringSlice + } + return unmarshalUTF8StringValue + } + if pointer { + return unmarshalStringPtr + } + if slice { + return unmarshalStringSlice + } + return unmarshalStringValue + case reflect.Struct: + // message or group field + if !pointer { + panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding)) + } + switch encoding { + case "bytes": + if slice { + return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) + case "group": + if slice { + return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) + } + } + panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) +} + +// Below are all the unmarshalers for individual fields of various types. + +func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64() = v + return b, nil +} + +func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64() = v + return b, nil +} + +func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64() = v + return b, nil +} + +func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64Ptr() = &v + return b, nil +} + +func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + *f.toInt32() = v + return b, nil +} + +func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + *f.toInt32() = v + return b, nil +} + +func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32() = v + return b, nil +} + +func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32Ptr() = &v + return b, nil +} + +func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64() = v + return b[8:], nil +} + +func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64() = v + return b[8:], nil +} + +func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32() = v + return b[4:], nil +} + +func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32Ptr() = &v + return b[4:], nil +} + +func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + *f.toInt32() = v + return b[4:], nil +} + +func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.setInt32Ptr(v) + return b[4:], nil +} + +func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + return b[4:], nil +} + +func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + // Note: any length varint is allowed, even though any sane + // encoder will use one byte. + // See https://github.com/golang/protobuf/issues/76 + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + // TODO: check if x>1? Tests seem to indicate no. + v := x != 0 + *f.toBool() = v + return b[n:], nil +} + +func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + *f.toBoolPtr() = &v + return b[n:], nil +} + +func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + b = b[n:] + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + return b[n:], nil +} + +func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64() = v + return b[8:], nil +} + +func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64Ptr() = &v + return b[8:], nil +} + +func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32() = v + return b[4:], nil +} + +func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32Ptr() = &v + return b[4:], nil +} + +func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + return b[x:], nil +} + +func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + return b[x:], nil +} + +func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + return b[x:], nil +} + +func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +var emptyBuf [0]byte + +func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // The use of append here is a trick which avoids the zeroing + // that would be required if we used a make/copy pair. + // We append to emptyBuf instead of nil because we want + // a non-nil result even when the length is 0. + v := append(emptyBuf[:], b[:x]...) + *f.toBytes() = v + return b[x:], nil +} + +func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := append(emptyBuf[:], b[:x]...) + s := f.toBytesSlice() + *s = append(*s, v) + return b[x:], nil +} + +func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // First read the message field to see if something is there. + // The semantics of multiple submessages are weird. Instead of + // the last one winning (as it is for all other fields), multiple + // submessages are merged. + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[x:], err + } +} + +func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[x:], err + } +} + +func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[y:], err + } +} + +func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[y:], err + } +} + +func makeUnmarshalMap(f *reflect.StructField) unmarshaler { + t := f.Type + kt := t.Key() + vt := t.Elem() + unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) + unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val")) + return func(b []byte, f pointer, w int) ([]byte, error) { + // The map entry is a submessage. Figure out how big it is. + if w != WireBytes { + return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + r := b[x:] // unused data to return + b = b[:x] // data for map entry + + // Note: we could use #keys * #values ~= 200 functions + // to do map decoding without reflection. Probably not worth it. + // Maps will be somewhat slow. Oh well. + + // Read key and value from data. + var nerr nonFatal + k := reflect.New(kt) + v := reflect.New(vt) + for len(b) > 0 { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + wire := int(x) & 7 + b = b[n:] + + var err error + switch x >> 3 { + case 1: + b, err = unmarshalKey(b, valToPointer(k), wire) + case 2: + b, err = unmarshalVal(b, valToPointer(v), wire) + default: + err = errInternalBadWireType // skip unknown tag + } + + if nerr.Merge(err) { + continue + } + if err != errInternalBadWireType { + return nil, err + } + + // Skip past unknown fields. + b, err = skipField(b, wire) + if err != nil { + return nil, err + } + } + + // Get map, allocate if needed. + m := f.asPointerTo(t).Elem() // an addressable map[K]T + if m.IsNil() { + m.Set(reflect.MakeMap(t)) + } + + // Insert into map. + m.SetMapIndex(k.Elem(), v.Elem()) + + return r, nerr.E + } +} + +// makeUnmarshalOneof makes an unmarshaler for oneof fields. +// for: +// message Msg { +// oneof F { +// int64 X = 1; +// float64 Y = 2; +// } +// } +// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). +// ityp is the interface type of the oneof field (e.g. isMsg_F). +// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). +// Note that this function will be called once for each case in the oneof. +func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { + sf := typ.Field(0) + field0 := toField(&sf) + return func(b []byte, f pointer, w int) ([]byte, error) { + // Allocate holder for value. + v := reflect.New(typ) + + // Unmarshal data into holder. + // We unmarshal into the first field of the holder object. + var err error + var nerr nonFatal + b, err = unmarshal(b, valToPointer(v).offset(field0), w) + if !nerr.Merge(err) { + return nil, err + } + + // Write pointer to holder into target field. + f.asPointerTo(ityp).Elem().Set(v) + + return b, nerr.E + } +} + +// Error used by decode internally. +var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") + +// skipField skips past a field of type wire and returns the remaining bytes. +func skipField(b []byte, wire int) ([]byte, error) { + switch wire { + case WireVarint: + _, k := decodeVarint(b) + if k == 0 { + return b, io.ErrUnexpectedEOF + } + b = b[k:] + case WireFixed32: + if len(b) < 4 { + return b, io.ErrUnexpectedEOF + } + b = b[4:] + case WireFixed64: + if len(b) < 8 { + return b, io.ErrUnexpectedEOF + } + b = b[8:] + case WireBytes: + m, k := decodeVarint(b) + if k == 0 || uint64(len(b)-k) < m { + return b, io.ErrUnexpectedEOF + } + b = b[uint64(k)+m:] + case WireStartGroup: + _, i := findEndGroup(b) + if i == -1 { + return b, io.ErrUnexpectedEOF + } + b = b[i:] + default: + return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) + } + return b, nil +} + +// findEndGroup finds the index of the next EndGroup tag. +// Groups may be nested, so the "next" EndGroup tag is the first +// unpaired EndGroup. +// findEndGroup returns the indexes of the start and end of the EndGroup tag. +// Returns (-1,-1) if it can't find one. +func findEndGroup(b []byte) (int, int) { + depth := 1 + i := 0 + for { + x, n := decodeVarint(b[i:]) + if n == 0 { + return -1, -1 + } + j := i + i += n + switch x & 7 { + case WireVarint: + _, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + case WireFixed32: + if len(b)-4 < i { + return -1, -1 + } + i += 4 + case WireFixed64: + if len(b)-8 < i { + return -1, -1 + } + i += 8 + case WireBytes: + m, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + if uint64(len(b)-i) < m { + return -1, -1 + } + i += int(m) + case WireStartGroup: + depth++ + case WireEndGroup: + depth-- + if depth == 0 { + return j, i + } + default: + return -1, -1 + } + } +} + +// encodeVarint appends a varint-encoded integer to b and returns the result. +func encodeVarint(b []byte, x uint64) []byte { + for x >= 1<<7 { + b = append(b, byte(x&0x7f|0x80)) + x >>= 7 + } + return append(b, byte(x)) +} + +// decodeVarint reads a varint-encoded integer from b. +// Returns the decoded integer and the number of bytes read. +// If there is an error, it returns 0,0. +func decodeVarint(b []byte) (uint64, int) { + var x, y uint64 + if len(b) == 0 { + goto bad + } + x = uint64(b[0]) + if x < 0x80 { + return x, 1 + } + x -= 0x80 + + if len(b) <= 1 { + goto bad + } + y = uint64(b[1]) + x += y << 7 + if y < 0x80 { + return x, 2 + } + x -= 0x80 << 7 + + if len(b) <= 2 { + goto bad + } + y = uint64(b[2]) + x += y << 14 + if y < 0x80 { + return x, 3 + } + x -= 0x80 << 14 + + if len(b) <= 3 { + goto bad + } + y = uint64(b[3]) + x += y << 21 + if y < 0x80 { + return x, 4 + } + x -= 0x80 << 21 + + if len(b) <= 4 { + goto bad + } + y = uint64(b[4]) + x += y << 28 + if y < 0x80 { + return x, 5 + } + x -= 0x80 << 28 + + if len(b) <= 5 { + goto bad + } + y = uint64(b[5]) + x += y << 35 + if y < 0x80 { + return x, 6 + } + x -= 0x80 << 35 + + if len(b) <= 6 { + goto bad + } + y = uint64(b[6]) + x += y << 42 + if y < 0x80 { + return x, 7 + } + x -= 0x80 << 42 + + if len(b) <= 7 { + goto bad + } + y = uint64(b[7]) + x += y << 49 + if y < 0x80 { + return x, 8 + } + x -= 0x80 << 49 + + if len(b) <= 8 { + goto bad + } + y = uint64(b[8]) + x += y << 56 + if y < 0x80 { + return x, 9 + } + x -= 0x80 << 56 + + if len(b) <= 9 { + goto bad + } + y = uint64(b[9]) + x += y << 63 + if y < 2 { + return x, 10 + } + +bad: + return 0, 0 +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go new file mode 100644 index 00000000..1ded05bb --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go @@ -0,0 +1,2887 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/descriptor.proto + +package descriptor + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type FieldDescriptorProto_Type int32 + +const ( + // 0 is reserved for errors. + // Order is weird for historical reasons. + FieldDescriptorProto_TYPE_DOUBLE FieldDescriptorProto_Type = 1 + FieldDescriptorProto_TYPE_FLOAT FieldDescriptorProto_Type = 2 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT64 FieldDescriptorProto_Type = 3 + FieldDescriptorProto_TYPE_UINT64 FieldDescriptorProto_Type = 4 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT32 FieldDescriptorProto_Type = 5 + FieldDescriptorProto_TYPE_FIXED64 FieldDescriptorProto_Type = 6 + FieldDescriptorProto_TYPE_FIXED32 FieldDescriptorProto_Type = 7 + FieldDescriptorProto_TYPE_BOOL FieldDescriptorProto_Type = 8 + FieldDescriptorProto_TYPE_STRING FieldDescriptorProto_Type = 9 + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + FieldDescriptorProto_TYPE_GROUP FieldDescriptorProto_Type = 10 + FieldDescriptorProto_TYPE_MESSAGE FieldDescriptorProto_Type = 11 + // New in version 2. + FieldDescriptorProto_TYPE_BYTES FieldDescriptorProto_Type = 12 + FieldDescriptorProto_TYPE_UINT32 FieldDescriptorProto_Type = 13 + FieldDescriptorProto_TYPE_ENUM FieldDescriptorProto_Type = 14 + FieldDescriptorProto_TYPE_SFIXED32 FieldDescriptorProto_Type = 15 + FieldDescriptorProto_TYPE_SFIXED64 FieldDescriptorProto_Type = 16 + FieldDescriptorProto_TYPE_SINT32 FieldDescriptorProto_Type = 17 + FieldDescriptorProto_TYPE_SINT64 FieldDescriptorProto_Type = 18 +) + +var FieldDescriptorProto_Type_name = map[int32]string{ + 1: "TYPE_DOUBLE", + 2: "TYPE_FLOAT", + 3: "TYPE_INT64", + 4: "TYPE_UINT64", + 5: "TYPE_INT32", + 6: "TYPE_FIXED64", + 7: "TYPE_FIXED32", + 8: "TYPE_BOOL", + 9: "TYPE_STRING", + 10: "TYPE_GROUP", + 11: "TYPE_MESSAGE", + 12: "TYPE_BYTES", + 13: "TYPE_UINT32", + 14: "TYPE_ENUM", + 15: "TYPE_SFIXED32", + 16: "TYPE_SFIXED64", + 17: "TYPE_SINT32", + 18: "TYPE_SINT64", +} + +var FieldDescriptorProto_Type_value = map[string]int32{ + "TYPE_DOUBLE": 1, + "TYPE_FLOAT": 2, + "TYPE_INT64": 3, + "TYPE_UINT64": 4, + "TYPE_INT32": 5, + "TYPE_FIXED64": 6, + "TYPE_FIXED32": 7, + "TYPE_BOOL": 8, + "TYPE_STRING": 9, + "TYPE_GROUP": 10, + "TYPE_MESSAGE": 11, + "TYPE_BYTES": 12, + "TYPE_UINT32": 13, + "TYPE_ENUM": 14, + "TYPE_SFIXED32": 15, + "TYPE_SFIXED64": 16, + "TYPE_SINT32": 17, + "TYPE_SINT64": 18, +} + +func (x FieldDescriptorProto_Type) Enum() *FieldDescriptorProto_Type { + p := new(FieldDescriptorProto_Type) + *p = x + return p +} + +func (x FieldDescriptorProto_Type) String() string { + return proto.EnumName(FieldDescriptorProto_Type_name, int32(x)) +} + +func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Type_value, data, "FieldDescriptorProto_Type") + if err != nil { + return err + } + *x = FieldDescriptorProto_Type(value) + return nil +} + +func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4, 0} +} + +type FieldDescriptorProto_Label int32 + +const ( + // 0 is reserved for errors + FieldDescriptorProto_LABEL_OPTIONAL FieldDescriptorProto_Label = 1 + FieldDescriptorProto_LABEL_REQUIRED FieldDescriptorProto_Label = 2 + FieldDescriptorProto_LABEL_REPEATED FieldDescriptorProto_Label = 3 +) + +var FieldDescriptorProto_Label_name = map[int32]string{ + 1: "LABEL_OPTIONAL", + 2: "LABEL_REQUIRED", + 3: "LABEL_REPEATED", +} + +var FieldDescriptorProto_Label_value = map[string]int32{ + "LABEL_OPTIONAL": 1, + "LABEL_REQUIRED": 2, + "LABEL_REPEATED": 3, +} + +func (x FieldDescriptorProto_Label) Enum() *FieldDescriptorProto_Label { + p := new(FieldDescriptorProto_Label) + *p = x + return p +} + +func (x FieldDescriptorProto_Label) String() string { + return proto.EnumName(FieldDescriptorProto_Label_name, int32(x)) +} + +func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Label_value, data, "FieldDescriptorProto_Label") + if err != nil { + return err + } + *x = FieldDescriptorProto_Label(value) + return nil +} + +func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4, 1} +} + +// Generated classes can be optimized for speed or code size. +type FileOptions_OptimizeMode int32 + +const ( + FileOptions_SPEED FileOptions_OptimizeMode = 1 + // etc. + FileOptions_CODE_SIZE FileOptions_OptimizeMode = 2 + FileOptions_LITE_RUNTIME FileOptions_OptimizeMode = 3 +) + +var FileOptions_OptimizeMode_name = map[int32]string{ + 1: "SPEED", + 2: "CODE_SIZE", + 3: "LITE_RUNTIME", +} + +var FileOptions_OptimizeMode_value = map[string]int32{ + "SPEED": 1, + "CODE_SIZE": 2, + "LITE_RUNTIME": 3, +} + +func (x FileOptions_OptimizeMode) Enum() *FileOptions_OptimizeMode { + p := new(FileOptions_OptimizeMode) + *p = x + return p +} + +func (x FileOptions_OptimizeMode) String() string { + return proto.EnumName(FileOptions_OptimizeMode_name, int32(x)) +} + +func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FileOptions_OptimizeMode_value, data, "FileOptions_OptimizeMode") + if err != nil { + return err + } + *x = FileOptions_OptimizeMode(value) + return nil +} + +func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{10, 0} +} + +type FieldOptions_CType int32 + +const ( + // Default mode. + FieldOptions_STRING FieldOptions_CType = 0 + FieldOptions_CORD FieldOptions_CType = 1 + FieldOptions_STRING_PIECE FieldOptions_CType = 2 +) + +var FieldOptions_CType_name = map[int32]string{ + 0: "STRING", + 1: "CORD", + 2: "STRING_PIECE", +} + +var FieldOptions_CType_value = map[string]int32{ + "STRING": 0, + "CORD": 1, + "STRING_PIECE": 2, +} + +func (x FieldOptions_CType) Enum() *FieldOptions_CType { + p := new(FieldOptions_CType) + *p = x + return p +} + +func (x FieldOptions_CType) String() string { + return proto.EnumName(FieldOptions_CType_name, int32(x)) +} + +func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_CType_value, data, "FieldOptions_CType") + if err != nil { + return err + } + *x = FieldOptions_CType(value) + return nil +} + +func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12, 0} +} + +type FieldOptions_JSType int32 + +const ( + // Use the default type. + FieldOptions_JS_NORMAL FieldOptions_JSType = 0 + // Use JavaScript strings. + FieldOptions_JS_STRING FieldOptions_JSType = 1 + // Use JavaScript numbers. + FieldOptions_JS_NUMBER FieldOptions_JSType = 2 +) + +var FieldOptions_JSType_name = map[int32]string{ + 0: "JS_NORMAL", + 1: "JS_STRING", + 2: "JS_NUMBER", +} + +var FieldOptions_JSType_value = map[string]int32{ + "JS_NORMAL": 0, + "JS_STRING": 1, + "JS_NUMBER": 2, +} + +func (x FieldOptions_JSType) Enum() *FieldOptions_JSType { + p := new(FieldOptions_JSType) + *p = x + return p +} + +func (x FieldOptions_JSType) String() string { + return proto.EnumName(FieldOptions_JSType_name, int32(x)) +} + +func (x *FieldOptions_JSType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_JSType_value, data, "FieldOptions_JSType") + if err != nil { + return err + } + *x = FieldOptions_JSType(value) + return nil +} + +func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12, 1} +} + +// Is this method side-effect-free (or safe in HTTP parlance), or idempotent, +// or neither? HTTP based RPC implementation may choose GET verb for safe +// methods, and PUT verb for idempotent methods instead of the default POST. +type MethodOptions_IdempotencyLevel int32 + +const ( + MethodOptions_IDEMPOTENCY_UNKNOWN MethodOptions_IdempotencyLevel = 0 + MethodOptions_NO_SIDE_EFFECTS MethodOptions_IdempotencyLevel = 1 + MethodOptions_IDEMPOTENT MethodOptions_IdempotencyLevel = 2 +) + +var MethodOptions_IdempotencyLevel_name = map[int32]string{ + 0: "IDEMPOTENCY_UNKNOWN", + 1: "NO_SIDE_EFFECTS", + 2: "IDEMPOTENT", +} + +var MethodOptions_IdempotencyLevel_value = map[string]int32{ + "IDEMPOTENCY_UNKNOWN": 0, + "NO_SIDE_EFFECTS": 1, + "IDEMPOTENT": 2, +} + +func (x MethodOptions_IdempotencyLevel) Enum() *MethodOptions_IdempotencyLevel { + p := new(MethodOptions_IdempotencyLevel) + *p = x + return p +} + +func (x MethodOptions_IdempotencyLevel) String() string { + return proto.EnumName(MethodOptions_IdempotencyLevel_name, int32(x)) +} + +func (x *MethodOptions_IdempotencyLevel) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MethodOptions_IdempotencyLevel_value, data, "MethodOptions_IdempotencyLevel") + if err != nil { + return err + } + *x = MethodOptions_IdempotencyLevel(value) + return nil +} + +func (MethodOptions_IdempotencyLevel) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{17, 0} +} + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +type FileDescriptorSet struct { + File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } +func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorSet) ProtoMessage() {} +func (*FileDescriptorSet) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{0} +} + +func (m *FileDescriptorSet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorSet.Unmarshal(m, b) +} +func (m *FileDescriptorSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorSet.Marshal(b, m, deterministic) +} +func (m *FileDescriptorSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorSet.Merge(m, src) +} +func (m *FileDescriptorSet) XXX_Size() int { + return xxx_messageInfo_FileDescriptorSet.Size(m) +} +func (m *FileDescriptorSet) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorSet.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorSet proto.InternalMessageInfo + +func (m *FileDescriptorSet) GetFile() []*FileDescriptorProto { + if m != nil { + return m.File + } + return nil +} + +// Describes a complete .proto file. +type FileDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` + // Names of files imported by this file. + Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` + // Indexes of the public imported files in the dependency list above. + PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency,json=publicDependency" json:"public_dependency,omitempty"` + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"` + // All top-level definitions in this file. + MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + Service []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` + Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info,json=sourceCodeInfo" json:"source_code_info,omitempty"` + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } +func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorProto) ProtoMessage() {} +func (*FileDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{1} +} + +func (m *FileDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorProto.Unmarshal(m, b) +} +func (m *FileDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FileDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorProto.Merge(m, src) +} +func (m *FileDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FileDescriptorProto.Size(m) +} +func (m *FileDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorProto proto.InternalMessageInfo + +func (m *FileDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FileDescriptorProto) GetPackage() string { + if m != nil && m.Package != nil { + return *m.Package + } + return "" +} + +func (m *FileDescriptorProto) GetDependency() []string { + if m != nil { + return m.Dependency + } + return nil +} + +func (m *FileDescriptorProto) GetPublicDependency() []int32 { + if m != nil { + return m.PublicDependency + } + return nil +} + +func (m *FileDescriptorProto) GetWeakDependency() []int32 { + if m != nil { + return m.WeakDependency + } + return nil +} + +func (m *FileDescriptorProto) GetMessageType() []*DescriptorProto { + if m != nil { + return m.MessageType + } + return nil +} + +func (m *FileDescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *FileDescriptorProto) GetService() []*ServiceDescriptorProto { + if m != nil { + return m.Service + } + return nil +} + +func (m *FileDescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *FileDescriptorProto) GetOptions() *FileOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *FileDescriptorProto) GetSourceCodeInfo() *SourceCodeInfo { + if m != nil { + return m.SourceCodeInfo + } + return nil +} + +func (m *FileDescriptorProto) GetSyntax() string { + if m != nil && m.Syntax != nil { + return *m.Syntax + } + return "" +} + +// Describes a message type. +type DescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` + NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type,json=nestedType" json:"nested_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range,json=extensionRange" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl,json=oneofDecl" json:"oneof_decl,omitempty"` + Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` + ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } +func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto) ProtoMessage() {} +func (*DescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2} +} + +func (m *DescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto.Unmarshal(m, b) +} +func (m *DescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto.Marshal(b, m, deterministic) +} +func (m *DescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto.Merge(m, src) +} +func (m *DescriptorProto) XXX_Size() int { + return xxx_messageInfo_DescriptorProto.Size(m) +} +func (m *DescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto proto.InternalMessageInfo + +func (m *DescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DescriptorProto) GetField() []*FieldDescriptorProto { + if m != nil { + return m.Field + } + return nil +} + +func (m *DescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *DescriptorProto) GetNestedType() []*DescriptorProto { + if m != nil { + return m.NestedType + } + return nil +} + +func (m *DescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *DescriptorProto) GetExtensionRange() []*DescriptorProto_ExtensionRange { + if m != nil { + return m.ExtensionRange + } + return nil +} + +func (m *DescriptorProto) GetOneofDecl() []*OneofDescriptorProto { + if m != nil { + return m.OneofDecl + } + return nil +} + +func (m *DescriptorProto) GetOptions() *MessageOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *DescriptorProto) GetReservedRange() []*DescriptorProto_ReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *DescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +type DescriptorProto_ExtensionRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} } +func (m *DescriptorProto_ExtensionRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ExtensionRange) ProtoMessage() {} +func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2, 0} +} + +func (m *DescriptorProto_ExtensionRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ExtensionRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ExtensionRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ExtensionRange.Merge(m, src) +} +func (m *DescriptorProto_ExtensionRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Size(m) +} +func (m *DescriptorProto_ExtensionRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ExtensionRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ExtensionRange proto.InternalMessageInfo + +func (m *DescriptorProto_ExtensionRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetOptions() *ExtensionRangeOptions { + if m != nil { + return m.Options + } + return nil +} + +// Range of reserved tag numbers. Reserved tag numbers may not be used by +// fields or extension ranges in the same message. Reserved ranges may +// not overlap. +type DescriptorProto_ReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ReservedRange) Reset() { *m = DescriptorProto_ReservedRange{} } +func (m *DescriptorProto_ReservedRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ReservedRange) ProtoMessage() {} +func (*DescriptorProto_ReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2, 1} +} + +func (m *DescriptorProto_ReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ReservedRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ReservedRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ReservedRange.Merge(m, src) +} +func (m *DescriptorProto_ReservedRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ReservedRange.Size(m) +} +func (m *DescriptorProto_ReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ReservedRange proto.InternalMessageInfo + +func (m *DescriptorProto_ReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +type ExtensionRangeOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExtensionRangeOptions) Reset() { *m = ExtensionRangeOptions{} } +func (m *ExtensionRangeOptions) String() string { return proto.CompactTextString(m) } +func (*ExtensionRangeOptions) ProtoMessage() {} +func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{3} +} + +var extRange_ExtensionRangeOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ExtensionRangeOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ExtensionRangeOptions +} + +func (m *ExtensionRangeOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExtensionRangeOptions.Unmarshal(m, b) +} +func (m *ExtensionRangeOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExtensionRangeOptions.Marshal(b, m, deterministic) +} +func (m *ExtensionRangeOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExtensionRangeOptions.Merge(m, src) +} +func (m *ExtensionRangeOptions) XXX_Size() int { + return xxx_messageInfo_ExtensionRangeOptions.Size(m) +} +func (m *ExtensionRangeOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ExtensionRangeOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ExtensionRangeOptions proto.InternalMessageInfo + +func (m *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// Describes a field within a message. +type FieldDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` + Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"` + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + TypeName *string `protobuf:"bytes,6,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"` + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value,json=defaultValue" json:"default_value,omitempty"` + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index,json=oneofIndex" json:"oneof_index,omitempty"` + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + JsonName *string `protobuf:"bytes,10,opt,name=json_name,json=jsonName" json:"json_name,omitempty"` + Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } +func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FieldDescriptorProto) ProtoMessage() {} +func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4} +} + +func (m *FieldDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldDescriptorProto.Unmarshal(m, b) +} +func (m *FieldDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FieldDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldDescriptorProto.Merge(m, src) +} +func (m *FieldDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FieldDescriptorProto.Size(m) +} +func (m *FieldDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FieldDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldDescriptorProto proto.InternalMessageInfo + +func (m *FieldDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FieldDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *FieldDescriptorProto) GetLabel() FieldDescriptorProto_Label { + if m != nil && m.Label != nil { + return *m.Label + } + return FieldDescriptorProto_LABEL_OPTIONAL +} + +func (m *FieldDescriptorProto) GetType() FieldDescriptorProto_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FieldDescriptorProto_TYPE_DOUBLE +} + +func (m *FieldDescriptorProto) GetTypeName() string { + if m != nil && m.TypeName != nil { + return *m.TypeName + } + return "" +} + +func (m *FieldDescriptorProto) GetExtendee() string { + if m != nil && m.Extendee != nil { + return *m.Extendee + } + return "" +} + +func (m *FieldDescriptorProto) GetDefaultValue() string { + if m != nil && m.DefaultValue != nil { + return *m.DefaultValue + } + return "" +} + +func (m *FieldDescriptorProto) GetOneofIndex() int32 { + if m != nil && m.OneofIndex != nil { + return *m.OneofIndex + } + return 0 +} + +func (m *FieldDescriptorProto) GetJsonName() string { + if m != nil && m.JsonName != nil { + return *m.JsonName + } + return "" +} + +func (m *FieldDescriptorProto) GetOptions() *FieldOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a oneof. +type OneofDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Options *OneofOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} +func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{5} +} + +func (m *OneofDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofDescriptorProto.Unmarshal(m, b) +} +func (m *OneofDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofDescriptorProto.Marshal(b, m, deterministic) +} +func (m *OneofDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofDescriptorProto.Merge(m, src) +} +func (m *OneofDescriptorProto) XXX_Size() int { + return xxx_messageInfo_OneofDescriptorProto.Size(m) +} +func (m *OneofDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_OneofDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofDescriptorProto proto.InternalMessageInfo + +func (m *OneofDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *OneofDescriptorProto) GetOptions() *OneofOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes an enum type. +type EnumDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Value []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` + Options *EnumOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } +func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto) ProtoMessage() {} +func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{6} +} + +func (m *EnumDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto.Unmarshal(m, b) +} +func (m *EnumDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto.Merge(m, src) +} +func (m *EnumDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto.Size(m) +} +func (m *EnumDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto proto.InternalMessageInfo + +func (m *EnumDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumDescriptorProto) GetValue() []*EnumValueDescriptorProto { + if m != nil { + return m.Value + } + return nil +} + +func (m *EnumDescriptorProto) GetOptions() *EnumOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedRange() []*EnumDescriptorProto_EnumReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +// Range of reserved numeric values. Reserved values may not be used by +// entries in the same enum. Reserved ranges may not overlap. +// +// Note that this is distinct from DescriptorProto.ReservedRange in that it +// is inclusive such that it can appropriately represent the entire int32 +// domain. +type EnumDescriptorProto_EnumReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto_EnumReservedRange) Reset() { *m = EnumDescriptorProto_EnumReservedRange{} } +func (m *EnumDescriptorProto_EnumReservedRange) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto_EnumReservedRange) ProtoMessage() {} +func (*EnumDescriptorProto_EnumReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{6, 0} +} + +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Unmarshal(m, b) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Merge(m, src) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Size(m) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto_EnumReservedRange proto.InternalMessageInfo + +func (m *EnumDescriptorProto_EnumReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *EnumDescriptorProto_EnumReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +// Describes a value within an enum. +type EnumValueDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` + Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} } +func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumValueDescriptorProto) ProtoMessage() {} +func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{7} +} + +func (m *EnumValueDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueDescriptorProto.Unmarshal(m, b) +} +func (m *EnumValueDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumValueDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueDescriptorProto.Merge(m, src) +} +func (m *EnumValueDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumValueDescriptorProto.Size(m) +} +func (m *EnumValueDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueDescriptorProto proto.InternalMessageInfo + +func (m *EnumValueDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumValueDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *EnumValueDescriptorProto) GetOptions() *EnumValueOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a service. +type ServiceDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` + Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } +func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*ServiceDescriptorProto) ProtoMessage() {} +func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{8} +} + +func (m *ServiceDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceDescriptorProto.Unmarshal(m, b) +} +func (m *ServiceDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceDescriptorProto.Marshal(b, m, deterministic) +} +func (m *ServiceDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceDescriptorProto.Merge(m, src) +} +func (m *ServiceDescriptorProto) XXX_Size() int { + return xxx_messageInfo_ServiceDescriptorProto.Size(m) +} +func (m *ServiceDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceDescriptorProto proto.InternalMessageInfo + +func (m *ServiceDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ServiceDescriptorProto) GetMethod() []*MethodDescriptorProto { + if m != nil { + return m.Method + } + return nil +} + +func (m *ServiceDescriptorProto) GetOptions() *ServiceOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a method of a service. +type MethodDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + InputType *string `protobuf:"bytes,2,opt,name=input_type,json=inputType" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type,json=outputType" json:"output_type,omitempty"` + Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Identifies if client streams multiple client messages + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,json=clientStreaming,def=0" json:"client_streaming,omitempty"` + // Identifies if server streams multiple server messages + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,json=serverStreaming,def=0" json:"server_streaming,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } +func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*MethodDescriptorProto) ProtoMessage() {} +func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{9} +} + +func (m *MethodDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodDescriptorProto.Unmarshal(m, b) +} +func (m *MethodDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodDescriptorProto.Marshal(b, m, deterministic) +} +func (m *MethodDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodDescriptorProto.Merge(m, src) +} +func (m *MethodDescriptorProto) XXX_Size() int { + return xxx_messageInfo_MethodDescriptorProto.Size(m) +} +func (m *MethodDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_MethodDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodDescriptorProto proto.InternalMessageInfo + +const Default_MethodDescriptorProto_ClientStreaming bool = false +const Default_MethodDescriptorProto_ServerStreaming bool = false + +func (m *MethodDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MethodDescriptorProto) GetInputType() string { + if m != nil && m.InputType != nil { + return *m.InputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOutputType() string { + if m != nil && m.OutputType != nil { + return *m.OutputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOptions() *MethodOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *MethodDescriptorProto) GetClientStreaming() bool { + if m != nil && m.ClientStreaming != nil { + return *m.ClientStreaming + } + return Default_MethodDescriptorProto_ClientStreaming +} + +func (m *MethodDescriptorProto) GetServerStreaming() bool { + if m != nil && m.ServerStreaming != nil { + return *m.ServerStreaming + } + return Default_MethodDescriptorProto_ServerStreaming +} + +type FileOptions struct { + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + JavaPackage *string `protobuf:"bytes,1,opt,name=java_package,json=javaPackage" json:"java_package,omitempty"` + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname,json=javaOuterClassname" json:"java_outer_classname,omitempty"` + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"` + // This option does nothing. + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash" json:"java_generate_equals_and_hash,omitempty"` // Deprecated: Do not use. + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,json=javaStringCheckUtf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,json=optimizeFor,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + GoPackage *string `protobuf:"bytes,11,opt,name=go_package,json=goPackage" json:"go_package,omitempty"` + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,json=ccGenericServices,def=0" json:"cc_generic_services,omitempty"` + JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,json=javaGenericServices,def=0" json:"java_generic_services,omitempty"` + PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,json=pyGenericServices,def=0" json:"py_generic_services,omitempty"` + PhpGenericServices *bool `protobuf:"varint,42,opt,name=php_generic_services,json=phpGenericServices,def=0" json:"php_generic_services,omitempty"` + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,json=ccEnableArenas,def=0" json:"cc_enable_arenas,omitempty"` + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + ObjcClassPrefix *string `protobuf:"bytes,36,opt,name=objc_class_prefix,json=objcClassPrefix" json:"objc_class_prefix,omitempty"` + // Namespace for generated classes; defaults to the package. + CsharpNamespace *string `protobuf:"bytes,37,opt,name=csharp_namespace,json=csharpNamespace" json:"csharp_namespace,omitempty"` + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + SwiftPrefix *string `protobuf:"bytes,39,opt,name=swift_prefix,json=swiftPrefix" json:"swift_prefix,omitempty"` + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + PhpClassPrefix *string `protobuf:"bytes,40,opt,name=php_class_prefix,json=phpClassPrefix" json:"php_class_prefix,omitempty"` + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + PhpNamespace *string `protobuf:"bytes,41,opt,name=php_namespace,json=phpNamespace" json:"php_namespace,omitempty"` + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be used + // for determining the namespace. + PhpMetadataNamespace *string `protobuf:"bytes,44,opt,name=php_metadata_namespace,json=phpMetadataNamespace" json:"php_metadata_namespace,omitempty"` + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + RubyPackage *string `protobuf:"bytes,45,opt,name=ruby_package,json=rubyPackage" json:"ruby_package,omitempty"` + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileOptions) Reset() { *m = FileOptions{} } +func (m *FileOptions) String() string { return proto.CompactTextString(m) } +func (*FileOptions) ProtoMessage() {} +func (*FileOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{10} +} + +var extRange_FileOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FileOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FileOptions +} + +func (m *FileOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileOptions.Unmarshal(m, b) +} +func (m *FileOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileOptions.Marshal(b, m, deterministic) +} +func (m *FileOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileOptions.Merge(m, src) +} +func (m *FileOptions) XXX_Size() int { + return xxx_messageInfo_FileOptions.Size(m) +} +func (m *FileOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FileOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FileOptions proto.InternalMessageInfo + +const Default_FileOptions_JavaMultipleFiles bool = false +const Default_FileOptions_JavaStringCheckUtf8 bool = false +const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED +const Default_FileOptions_CcGenericServices bool = false +const Default_FileOptions_JavaGenericServices bool = false +const Default_FileOptions_PyGenericServices bool = false +const Default_FileOptions_PhpGenericServices bool = false +const Default_FileOptions_Deprecated bool = false +const Default_FileOptions_CcEnableArenas bool = false + +func (m *FileOptions) GetJavaPackage() string { + if m != nil && m.JavaPackage != nil { + return *m.JavaPackage + } + return "" +} + +func (m *FileOptions) GetJavaOuterClassname() string { + if m != nil && m.JavaOuterClassname != nil { + return *m.JavaOuterClassname + } + return "" +} + +func (m *FileOptions) GetJavaMultipleFiles() bool { + if m != nil && m.JavaMultipleFiles != nil { + return *m.JavaMultipleFiles + } + return Default_FileOptions_JavaMultipleFiles +} + +// Deprecated: Do not use. +func (m *FileOptions) GetJavaGenerateEqualsAndHash() bool { + if m != nil && m.JavaGenerateEqualsAndHash != nil { + return *m.JavaGenerateEqualsAndHash + } + return false +} + +func (m *FileOptions) GetJavaStringCheckUtf8() bool { + if m != nil && m.JavaStringCheckUtf8 != nil { + return *m.JavaStringCheckUtf8 + } + return Default_FileOptions_JavaStringCheckUtf8 +} + +func (m *FileOptions) GetOptimizeFor() FileOptions_OptimizeMode { + if m != nil && m.OptimizeFor != nil { + return *m.OptimizeFor + } + return Default_FileOptions_OptimizeFor +} + +func (m *FileOptions) GetGoPackage() string { + if m != nil && m.GoPackage != nil { + return *m.GoPackage + } + return "" +} + +func (m *FileOptions) GetCcGenericServices() bool { + if m != nil && m.CcGenericServices != nil { + return *m.CcGenericServices + } + return Default_FileOptions_CcGenericServices +} + +func (m *FileOptions) GetJavaGenericServices() bool { + if m != nil && m.JavaGenericServices != nil { + return *m.JavaGenericServices + } + return Default_FileOptions_JavaGenericServices +} + +func (m *FileOptions) GetPyGenericServices() bool { + if m != nil && m.PyGenericServices != nil { + return *m.PyGenericServices + } + return Default_FileOptions_PyGenericServices +} + +func (m *FileOptions) GetPhpGenericServices() bool { + if m != nil && m.PhpGenericServices != nil { + return *m.PhpGenericServices + } + return Default_FileOptions_PhpGenericServices +} + +func (m *FileOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FileOptions_Deprecated +} + +func (m *FileOptions) GetCcEnableArenas() bool { + if m != nil && m.CcEnableArenas != nil { + return *m.CcEnableArenas + } + return Default_FileOptions_CcEnableArenas +} + +func (m *FileOptions) GetObjcClassPrefix() string { + if m != nil && m.ObjcClassPrefix != nil { + return *m.ObjcClassPrefix + } + return "" +} + +func (m *FileOptions) GetCsharpNamespace() string { + if m != nil && m.CsharpNamespace != nil { + return *m.CsharpNamespace + } + return "" +} + +func (m *FileOptions) GetSwiftPrefix() string { + if m != nil && m.SwiftPrefix != nil { + return *m.SwiftPrefix + } + return "" +} + +func (m *FileOptions) GetPhpClassPrefix() string { + if m != nil && m.PhpClassPrefix != nil { + return *m.PhpClassPrefix + } + return "" +} + +func (m *FileOptions) GetPhpNamespace() string { + if m != nil && m.PhpNamespace != nil { + return *m.PhpNamespace + } + return "" +} + +func (m *FileOptions) GetPhpMetadataNamespace() string { + if m != nil && m.PhpMetadataNamespace != nil { + return *m.PhpMetadataNamespace + } + return "" +} + +func (m *FileOptions) GetRubyPackage() string { + if m != nil && m.RubyPackage != nil { + return *m.RubyPackage + } + return "" +} + +func (m *FileOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MessageOptions struct { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,json=messageSetWireFormat,def=0" json:"message_set_wire_format,omitempty"` + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,json=noStandardDescriptorAccessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry,json=mapEntry" json:"map_entry,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageOptions) Reset() { *m = MessageOptions{} } +func (m *MessageOptions) String() string { return proto.CompactTextString(m) } +func (*MessageOptions) ProtoMessage() {} +func (*MessageOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{11} +} + +var extRange_MessageOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MessageOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MessageOptions +} + +func (m *MessageOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageOptions.Unmarshal(m, b) +} +func (m *MessageOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageOptions.Marshal(b, m, deterministic) +} +func (m *MessageOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageOptions.Merge(m, src) +} +func (m *MessageOptions) XXX_Size() int { + return xxx_messageInfo_MessageOptions.Size(m) +} +func (m *MessageOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MessageOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageOptions proto.InternalMessageInfo + +const Default_MessageOptions_MessageSetWireFormat bool = false +const Default_MessageOptions_NoStandardDescriptorAccessor bool = false +const Default_MessageOptions_Deprecated bool = false + +func (m *MessageOptions) GetMessageSetWireFormat() bool { + if m != nil && m.MessageSetWireFormat != nil { + return *m.MessageSetWireFormat + } + return Default_MessageOptions_MessageSetWireFormat +} + +func (m *MessageOptions) GetNoStandardDescriptorAccessor() bool { + if m != nil && m.NoStandardDescriptorAccessor != nil { + return *m.NoStandardDescriptorAccessor + } + return Default_MessageOptions_NoStandardDescriptorAccessor +} + +func (m *MessageOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MessageOptions_Deprecated +} + +func (m *MessageOptions) GetMapEntry() bool { + if m != nil && m.MapEntry != nil { + return *m.MapEntry + } + return false +} + +func (m *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type FieldOptions struct { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"` + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + Jstype *FieldOptions_JSType `protobuf:"varint,6,opt,name=jstype,enum=google.protobuf.FieldOptions_JSType,def=0" json:"jstype,omitempty"` + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"` + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // For Google-internal migration only. Do not use. + Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldOptions) Reset() { *m = FieldOptions{} } +func (m *FieldOptions) String() string { return proto.CompactTextString(m) } +func (*FieldOptions) ProtoMessage() {} +func (*FieldOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12} +} + +var extRange_FieldOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FieldOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FieldOptions +} + +func (m *FieldOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldOptions.Unmarshal(m, b) +} +func (m *FieldOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldOptions.Marshal(b, m, deterministic) +} +func (m *FieldOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldOptions.Merge(m, src) +} +func (m *FieldOptions) XXX_Size() int { + return xxx_messageInfo_FieldOptions.Size(m) +} +func (m *FieldOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FieldOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldOptions proto.InternalMessageInfo + +const Default_FieldOptions_Ctype FieldOptions_CType = FieldOptions_STRING +const Default_FieldOptions_Jstype FieldOptions_JSType = FieldOptions_JS_NORMAL +const Default_FieldOptions_Lazy bool = false +const Default_FieldOptions_Deprecated bool = false +const Default_FieldOptions_Weak bool = false + +func (m *FieldOptions) GetCtype() FieldOptions_CType { + if m != nil && m.Ctype != nil { + return *m.Ctype + } + return Default_FieldOptions_Ctype +} + +func (m *FieldOptions) GetPacked() bool { + if m != nil && m.Packed != nil { + return *m.Packed + } + return false +} + +func (m *FieldOptions) GetJstype() FieldOptions_JSType { + if m != nil && m.Jstype != nil { + return *m.Jstype + } + return Default_FieldOptions_Jstype +} + +func (m *FieldOptions) GetLazy() bool { + if m != nil && m.Lazy != nil { + return *m.Lazy + } + return Default_FieldOptions_Lazy +} + +func (m *FieldOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FieldOptions_Deprecated +} + +func (m *FieldOptions) GetWeak() bool { + if m != nil && m.Weak != nil { + return *m.Weak + } + return Default_FieldOptions_Weak +} + +func (m *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type OneofOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofOptions) Reset() { *m = OneofOptions{} } +func (m *OneofOptions) String() string { return proto.CompactTextString(m) } +func (*OneofOptions) ProtoMessage() {} +func (*OneofOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{13} +} + +var extRange_OneofOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*OneofOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OneofOptions +} + +func (m *OneofOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofOptions.Unmarshal(m, b) +} +func (m *OneofOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofOptions.Marshal(b, m, deterministic) +} +func (m *OneofOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofOptions.Merge(m, src) +} +func (m *OneofOptions) XXX_Size() int { + return xxx_messageInfo_OneofOptions.Size(m) +} +func (m *OneofOptions) XXX_DiscardUnknown() { + xxx_messageInfo_OneofOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofOptions proto.InternalMessageInfo + +func (m *OneofOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumOptions struct { + // Set this option to true to allow mapping different tag names to the same + // value. + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,json=allowAlias" json:"allow_alias,omitempty"` + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumOptions) Reset() { *m = EnumOptions{} } +func (m *EnumOptions) String() string { return proto.CompactTextString(m) } +func (*EnumOptions) ProtoMessage() {} +func (*EnumOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{14} +} + +var extRange_EnumOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumOptions +} + +func (m *EnumOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumOptions.Unmarshal(m, b) +} +func (m *EnumOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumOptions.Marshal(b, m, deterministic) +} +func (m *EnumOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumOptions.Merge(m, src) +} +func (m *EnumOptions) XXX_Size() int { + return xxx_messageInfo_EnumOptions.Size(m) +} +func (m *EnumOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumOptions proto.InternalMessageInfo + +const Default_EnumOptions_Deprecated bool = false + +func (m *EnumOptions) GetAllowAlias() bool { + if m != nil && m.AllowAlias != nil { + return *m.AllowAlias + } + return false +} + +func (m *EnumOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumOptions_Deprecated +} + +func (m *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumValueOptions struct { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } +func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } +func (*EnumValueOptions) ProtoMessage() {} +func (*EnumValueOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{15} +} + +var extRange_EnumValueOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumValueOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumValueOptions +} + +func (m *EnumValueOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueOptions.Unmarshal(m, b) +} +func (m *EnumValueOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueOptions.Marshal(b, m, deterministic) +} +func (m *EnumValueOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueOptions.Merge(m, src) +} +func (m *EnumValueOptions) XXX_Size() int { + return xxx_messageInfo_EnumValueOptions.Size(m) +} +func (m *EnumValueOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueOptions proto.InternalMessageInfo + +const Default_EnumValueOptions_Deprecated bool = false + +func (m *EnumValueOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumValueOptions_Deprecated +} + +func (m *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type ServiceOptions struct { + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } +func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } +func (*ServiceOptions) ProtoMessage() {} +func (*ServiceOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{16} +} + +var extRange_ServiceOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ServiceOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ServiceOptions +} + +func (m *ServiceOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceOptions.Unmarshal(m, b) +} +func (m *ServiceOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceOptions.Marshal(b, m, deterministic) +} +func (m *ServiceOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceOptions.Merge(m, src) +} +func (m *ServiceOptions) XXX_Size() int { + return xxx_messageInfo_ServiceOptions.Size(m) +} +func (m *ServiceOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceOptions proto.InternalMessageInfo + +const Default_ServiceOptions_Deprecated bool = false + +func (m *ServiceOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_ServiceOptions_Deprecated +} + +func (m *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MethodOptions struct { + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + IdempotencyLevel *MethodOptions_IdempotencyLevel `protobuf:"varint,34,opt,name=idempotency_level,json=idempotencyLevel,enum=google.protobuf.MethodOptions_IdempotencyLevel,def=0" json:"idempotency_level,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodOptions) Reset() { *m = MethodOptions{} } +func (m *MethodOptions) String() string { return proto.CompactTextString(m) } +func (*MethodOptions) ProtoMessage() {} +func (*MethodOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{17} +} + +var extRange_MethodOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MethodOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MethodOptions +} + +func (m *MethodOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodOptions.Unmarshal(m, b) +} +func (m *MethodOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodOptions.Marshal(b, m, deterministic) +} +func (m *MethodOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodOptions.Merge(m, src) +} +func (m *MethodOptions) XXX_Size() int { + return xxx_messageInfo_MethodOptions.Size(m) +} +func (m *MethodOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MethodOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodOptions proto.InternalMessageInfo + +const Default_MethodOptions_Deprecated bool = false +const Default_MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel = MethodOptions_IDEMPOTENCY_UNKNOWN + +func (m *MethodOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MethodOptions_Deprecated +} + +func (m *MethodOptions) GetIdempotencyLevel() MethodOptions_IdempotencyLevel { + if m != nil && m.IdempotencyLevel != nil { + return *m.IdempotencyLevel + } + return Default_MethodOptions_IdempotencyLevel +} + +func (m *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +type UninterpretedOption struct { + Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value,json=identifierValue" json:"identifier_value,omitempty"` + PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value,json=positiveIntValue" json:"positive_int_value,omitempty"` + NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value,json=negativeIntValue" json:"negative_int_value,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` + StringValue []byte `protobuf:"bytes,7,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` + AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value,json=aggregateValue" json:"aggregate_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } +func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption) ProtoMessage() {} +func (*UninterpretedOption) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{18} +} + +func (m *UninterpretedOption) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption.Unmarshal(m, b) +} +func (m *UninterpretedOption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption.Merge(m, src) +} +func (m *UninterpretedOption) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption.Size(m) +} +func (m *UninterpretedOption) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption proto.InternalMessageInfo + +func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart { + if m != nil { + return m.Name + } + return nil +} + +func (m *UninterpretedOption) GetIdentifierValue() string { + if m != nil && m.IdentifierValue != nil { + return *m.IdentifierValue + } + return "" +} + +func (m *UninterpretedOption) GetPositiveIntValue() uint64 { + if m != nil && m.PositiveIntValue != nil { + return *m.PositiveIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetNegativeIntValue() int64 { + if m != nil && m.NegativeIntValue != nil { + return *m.NegativeIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetDoubleValue() float64 { + if m != nil && m.DoubleValue != nil { + return *m.DoubleValue + } + return 0 +} + +func (m *UninterpretedOption) GetStringValue() []byte { + if m != nil { + return m.StringValue + } + return nil +} + +func (m *UninterpretedOption) GetAggregateValue() string { + if m != nil && m.AggregateValue != nil { + return *m.AggregateValue + } + return "" +} + +// The name of the uninterpreted option. Each string represents a segment in +// a dot-separated name. is_extension is true iff a segment represents an +// extension (denoted with parentheses in options specs in .proto files). +// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents +// "foo.(bar.baz).qux". +type UninterpretedOption_NamePart struct { + NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOption_NamePart{} } +func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption_NamePart) ProtoMessage() {} +func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{18, 0} +} + +func (m *UninterpretedOption_NamePart) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption_NamePart.Unmarshal(m, b) +} +func (m *UninterpretedOption_NamePart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption_NamePart.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption_NamePart) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption_NamePart.Merge(m, src) +} +func (m *UninterpretedOption_NamePart) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption_NamePart.Size(m) +} +func (m *UninterpretedOption_NamePart) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption_NamePart.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption_NamePart proto.InternalMessageInfo + +func (m *UninterpretedOption_NamePart) GetNamePart() string { + if m != nil && m.NamePart != nil { + return *m.NamePart + } + return "" +} + +func (m *UninterpretedOption_NamePart) GetIsExtension() bool { + if m != nil && m.IsExtension != nil { + return *m.IsExtension + } + return false +} + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +type SourceCodeInfo struct { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } +func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo) ProtoMessage() {} +func (*SourceCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{19} +} + +func (m *SourceCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo.Unmarshal(m, b) +} +func (m *SourceCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo.Merge(m, src) +} +func (m *SourceCodeInfo) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo.Size(m) +} +func (m *SourceCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo proto.InternalMessageInfo + +func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { + if m != nil { + return m.Location + } + return nil +} + +type SourceCodeInfo_Location struct { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + Span []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"` + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` + TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` + LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} } +func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo_Location) ProtoMessage() {} +func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{19, 0} +} + +func (m *SourceCodeInfo_Location) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo_Location.Unmarshal(m, b) +} +func (m *SourceCodeInfo_Location) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo_Location.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo_Location) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo_Location.Merge(m, src) +} +func (m *SourceCodeInfo_Location) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo_Location.Size(m) +} +func (m *SourceCodeInfo_Location) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo_Location.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo_Location proto.InternalMessageInfo + +func (m *SourceCodeInfo_Location) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *SourceCodeInfo_Location) GetSpan() []int32 { + if m != nil { + return m.Span + } + return nil +} + +func (m *SourceCodeInfo_Location) GetLeadingComments() string { + if m != nil && m.LeadingComments != nil { + return *m.LeadingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetTrailingComments() string { + if m != nil && m.TrailingComments != nil { + return *m.TrailingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetLeadingDetachedComments() []string { + if m != nil { + return m.LeadingDetachedComments + } + return nil +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +type GeneratedCodeInfo struct { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + Annotation []*GeneratedCodeInfo_Annotation `protobuf:"bytes,1,rep,name=annotation" json:"annotation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo) Reset() { *m = GeneratedCodeInfo{} } +func (m *GeneratedCodeInfo) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo) ProtoMessage() {} +func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{20} +} + +func (m *GeneratedCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo.Merge(m, src) +} +func (m *GeneratedCodeInfo) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo.Size(m) +} +func (m *GeneratedCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo proto.InternalMessageInfo + +func (m *GeneratedCodeInfo) GetAnnotation() []*GeneratedCodeInfo_Annotation { + if m != nil { + return m.Annotation + } + return nil +} + +type GeneratedCodeInfo_Annotation struct { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Identifies the filesystem path to the original source .proto. + SourceFile *string `protobuf:"bytes,2,opt,name=source_file,json=sourceFile" json:"source_file,omitempty"` + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + Begin *int32 `protobuf:"varint,3,opt,name=begin" json:"begin,omitempty"` + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo_Annotation) Reset() { *m = GeneratedCodeInfo_Annotation{} } +func (m *GeneratedCodeInfo_Annotation) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo_Annotation) ProtoMessage() {} +func (*GeneratedCodeInfo_Annotation) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{20, 0} +} + +func (m *GeneratedCodeInfo_Annotation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo_Annotation.Merge(m, src) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Size(m) +} +func (m *GeneratedCodeInfo_Annotation) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo_Annotation.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo_Annotation proto.InternalMessageInfo + +func (m *GeneratedCodeInfo_Annotation) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *GeneratedCodeInfo_Annotation) GetSourceFile() string { + if m != nil && m.SourceFile != nil { + return *m.SourceFile + } + return "" +} + +func (m *GeneratedCodeInfo_Annotation) GetBegin() int32 { + if m != nil && m.Begin != nil { + return *m.Begin + } + return 0 +} + +func (m *GeneratedCodeInfo_Annotation) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func init() { + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Type", FieldDescriptorProto_Type_name, FieldDescriptorProto_Type_value) + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Label", FieldDescriptorProto_Label_name, FieldDescriptorProto_Label_value) + proto.RegisterEnum("google.protobuf.FileOptions_OptimizeMode", FileOptions_OptimizeMode_name, FileOptions_OptimizeMode_value) + proto.RegisterEnum("google.protobuf.FieldOptions_CType", FieldOptions_CType_name, FieldOptions_CType_value) + proto.RegisterEnum("google.protobuf.FieldOptions_JSType", FieldOptions_JSType_name, FieldOptions_JSType_value) + proto.RegisterEnum("google.protobuf.MethodOptions_IdempotencyLevel", MethodOptions_IdempotencyLevel_name, MethodOptions_IdempotencyLevel_value) + proto.RegisterType((*FileDescriptorSet)(nil), "google.protobuf.FileDescriptorSet") + proto.RegisterType((*FileDescriptorProto)(nil), "google.protobuf.FileDescriptorProto") + proto.RegisterType((*DescriptorProto)(nil), "google.protobuf.DescriptorProto") + proto.RegisterType((*DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange") + proto.RegisterType((*DescriptorProto_ReservedRange)(nil), "google.protobuf.DescriptorProto.ReservedRange") + proto.RegisterType((*ExtensionRangeOptions)(nil), "google.protobuf.ExtensionRangeOptions") + proto.RegisterType((*FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto") + proto.RegisterType((*OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto") + proto.RegisterType((*EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto") + proto.RegisterType((*EnumDescriptorProto_EnumReservedRange)(nil), "google.protobuf.EnumDescriptorProto.EnumReservedRange") + proto.RegisterType((*EnumValueDescriptorProto)(nil), "google.protobuf.EnumValueDescriptorProto") + proto.RegisterType((*ServiceDescriptorProto)(nil), "google.protobuf.ServiceDescriptorProto") + proto.RegisterType((*MethodDescriptorProto)(nil), "google.protobuf.MethodDescriptorProto") + proto.RegisterType((*FileOptions)(nil), "google.protobuf.FileOptions") + proto.RegisterType((*MessageOptions)(nil), "google.protobuf.MessageOptions") + proto.RegisterType((*FieldOptions)(nil), "google.protobuf.FieldOptions") + proto.RegisterType((*OneofOptions)(nil), "google.protobuf.OneofOptions") + proto.RegisterType((*EnumOptions)(nil), "google.protobuf.EnumOptions") + proto.RegisterType((*EnumValueOptions)(nil), "google.protobuf.EnumValueOptions") + proto.RegisterType((*ServiceOptions)(nil), "google.protobuf.ServiceOptions") + proto.RegisterType((*MethodOptions)(nil), "google.protobuf.MethodOptions") + proto.RegisterType((*UninterpretedOption)(nil), "google.protobuf.UninterpretedOption") + proto.RegisterType((*UninterpretedOption_NamePart)(nil), "google.protobuf.UninterpretedOption.NamePart") + proto.RegisterType((*SourceCodeInfo)(nil), "google.protobuf.SourceCodeInfo") + proto.RegisterType((*SourceCodeInfo_Location)(nil), "google.protobuf.SourceCodeInfo.Location") + proto.RegisterType((*GeneratedCodeInfo)(nil), "google.protobuf.GeneratedCodeInfo") + proto.RegisterType((*GeneratedCodeInfo_Annotation)(nil), "google.protobuf.GeneratedCodeInfo.Annotation") +} + +func init() { proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor_e5baabe45344a177) } + +var fileDescriptor_e5baabe45344a177 = []byte{ + // 2589 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdd, 0x8e, 0xdb, 0xc6, + 0x15, 0x0e, 0xf5, 0xb7, 0xd2, 0x91, 0x56, 0x3b, 0x3b, 0xbb, 0xb1, 0xe9, 0xcd, 0x8f, 0xd7, 0xca, + 0x8f, 0xd7, 0x4e, 0xac, 0x0d, 0x1c, 0xdb, 0x71, 0xd6, 0x45, 0x5a, 0xad, 0x44, 0x6f, 0xe4, 0xee, + 0x4a, 0x2a, 0xa5, 0x6d, 0x7e, 0x80, 0x82, 0x98, 0x25, 0x47, 0x12, 0x6d, 0x8a, 0x64, 0x48, 0xca, + 0xf6, 0x06, 0xbd, 0x30, 0xd0, 0xab, 0x5e, 0x15, 0xe8, 0x55, 0x51, 0x14, 0xbd, 0xe8, 0x4d, 0x80, + 0x3e, 0x40, 0x81, 0xde, 0xf5, 0x09, 0x0a, 0xe4, 0x0d, 0x8a, 0xb6, 0x40, 0xfb, 0x08, 0xbd, 0x2c, + 0x66, 0x86, 0xa4, 0x48, 0x49, 0x1b, 0x6f, 0x02, 0xc4, 0xb9, 0x92, 0xe6, 0x3b, 0xdf, 0x39, 0x73, + 0xe6, 0xcc, 0x99, 0x99, 0x33, 0x43, 0xd8, 0x1e, 0x39, 0xce, 0xc8, 0xa2, 0xbb, 0xae, 0xe7, 0x04, + 0xce, 0xc9, 0x74, 0xb8, 0x6b, 0x50, 0x5f, 0xf7, 0x4c, 0x37, 0x70, 0xbc, 0x3a, 0xc7, 0xf0, 0x9a, + 0x60, 0xd4, 0x23, 0x46, 0xed, 0x08, 0xd6, 0xef, 0x9b, 0x16, 0x6d, 0xc5, 0xc4, 0x3e, 0x0d, 0xf0, + 0x5d, 0xc8, 0x0d, 0x4d, 0x8b, 0xca, 0xd2, 0x76, 0x76, 0xa7, 0x7c, 0xf3, 0xcd, 0xfa, 0x9c, 0x52, + 0x3d, 0xad, 0xd1, 0x63, 0xb0, 0xca, 0x35, 0x6a, 0xff, 0xce, 0xc1, 0xc6, 0x12, 0x29, 0xc6, 0x90, + 0xb3, 0xc9, 0x84, 0x59, 0x94, 0x76, 0x4a, 0x2a, 0xff, 0x8f, 0x65, 0x58, 0x71, 0x89, 0xfe, 0x88, + 0x8c, 0xa8, 0x9c, 0xe1, 0x70, 0xd4, 0xc4, 0xaf, 0x03, 0x18, 0xd4, 0xa5, 0xb6, 0x41, 0x6d, 0xfd, + 0x54, 0xce, 0x6e, 0x67, 0x77, 0x4a, 0x6a, 0x02, 0xc1, 0xef, 0xc0, 0xba, 0x3b, 0x3d, 0xb1, 0x4c, + 0x5d, 0x4b, 0xd0, 0x60, 0x3b, 0xbb, 0x93, 0x57, 0x91, 0x10, 0xb4, 0x66, 0xe4, 0xab, 0xb0, 0xf6, + 0x84, 0x92, 0x47, 0x49, 0x6a, 0x99, 0x53, 0xab, 0x0c, 0x4e, 0x10, 0x9b, 0x50, 0x99, 0x50, 0xdf, + 0x27, 0x23, 0xaa, 0x05, 0xa7, 0x2e, 0x95, 0x73, 0x7c, 0xf4, 0xdb, 0x0b, 0xa3, 0x9f, 0x1f, 0x79, + 0x39, 0xd4, 0x1a, 0x9c, 0xba, 0x14, 0x37, 0xa0, 0x44, 0xed, 0xe9, 0x44, 0x58, 0xc8, 0x9f, 0x11, + 0x3f, 0xc5, 0x9e, 0x4e, 0xe6, 0xad, 0x14, 0x99, 0x5a, 0x68, 0x62, 0xc5, 0xa7, 0xde, 0x63, 0x53, + 0xa7, 0x72, 0x81, 0x1b, 0xb8, 0xba, 0x60, 0xa0, 0x2f, 0xe4, 0xf3, 0x36, 0x22, 0x3d, 0xdc, 0x84, + 0x12, 0x7d, 0x1a, 0x50, 0xdb, 0x37, 0x1d, 0x5b, 0x5e, 0xe1, 0x46, 0xde, 0x5a, 0x32, 0x8b, 0xd4, + 0x32, 0xe6, 0x4d, 0xcc, 0xf4, 0xf0, 0x1d, 0x58, 0x71, 0xdc, 0xc0, 0x74, 0x6c, 0x5f, 0x2e, 0x6e, + 0x4b, 0x3b, 0xe5, 0x9b, 0xaf, 0x2e, 0x4d, 0x84, 0xae, 0xe0, 0xa8, 0x11, 0x19, 0xb7, 0x01, 0xf9, + 0xce, 0xd4, 0xd3, 0xa9, 0xa6, 0x3b, 0x06, 0xd5, 0x4c, 0x7b, 0xe8, 0xc8, 0x25, 0x6e, 0xe0, 0xf2, + 0xe2, 0x40, 0x38, 0xb1, 0xe9, 0x18, 0xb4, 0x6d, 0x0f, 0x1d, 0xb5, 0xea, 0xa7, 0xda, 0xf8, 0x02, + 0x14, 0xfc, 0x53, 0x3b, 0x20, 0x4f, 0xe5, 0x0a, 0xcf, 0x90, 0xb0, 0x55, 0xfb, 0x6b, 0x01, 0xd6, + 0xce, 0x93, 0x62, 0xf7, 0x20, 0x3f, 0x64, 0xa3, 0x94, 0x33, 0xdf, 0x26, 0x06, 0x42, 0x27, 0x1d, + 0xc4, 0xc2, 0x77, 0x0c, 0x62, 0x03, 0xca, 0x36, 0xf5, 0x03, 0x6a, 0x88, 0x8c, 0xc8, 0x9e, 0x33, + 0xa7, 0x40, 0x28, 0x2d, 0xa6, 0x54, 0xee, 0x3b, 0xa5, 0xd4, 0xa7, 0xb0, 0x16, 0xbb, 0xa4, 0x79, + 0xc4, 0x1e, 0x45, 0xb9, 0xb9, 0xfb, 0x3c, 0x4f, 0xea, 0x4a, 0xa4, 0xa7, 0x32, 0x35, 0xb5, 0x4a, + 0x53, 0x6d, 0xdc, 0x02, 0x70, 0x6c, 0xea, 0x0c, 0x35, 0x83, 0xea, 0x96, 0x5c, 0x3c, 0x23, 0x4a, + 0x5d, 0x46, 0x59, 0x88, 0x92, 0x23, 0x50, 0xdd, 0xc2, 0x1f, 0xce, 0x52, 0x6d, 0xe5, 0x8c, 0x4c, + 0x39, 0x12, 0x8b, 0x6c, 0x21, 0xdb, 0x8e, 0xa1, 0xea, 0x51, 0x96, 0xf7, 0xd4, 0x08, 0x47, 0x56, + 0xe2, 0x4e, 0xd4, 0x9f, 0x3b, 0x32, 0x35, 0x54, 0x13, 0x03, 0x5b, 0xf5, 0x92, 0x4d, 0xfc, 0x06, + 0xc4, 0x80, 0xc6, 0xd3, 0x0a, 0xf8, 0x2e, 0x54, 0x89, 0xc0, 0x0e, 0x99, 0xd0, 0xad, 0x2f, 0xa1, + 0x9a, 0x0e, 0x0f, 0xde, 0x84, 0xbc, 0x1f, 0x10, 0x2f, 0xe0, 0x59, 0x98, 0x57, 0x45, 0x03, 0x23, + 0xc8, 0x52, 0xdb, 0xe0, 0xbb, 0x5c, 0x5e, 0x65, 0x7f, 0xf1, 0x4f, 0x66, 0x03, 0xce, 0xf2, 0x01, + 0xbf, 0xbd, 0x38, 0xa3, 0x29, 0xcb, 0xf3, 0xe3, 0xde, 0xfa, 0x00, 0x56, 0x53, 0x03, 0x38, 0x6f, + 0xd7, 0xb5, 0x5f, 0xc2, 0xcb, 0x4b, 0x4d, 0xe3, 0x4f, 0x61, 0x73, 0x6a, 0x9b, 0x76, 0x40, 0x3d, + 0xd7, 0xa3, 0x2c, 0x63, 0x45, 0x57, 0xf2, 0x7f, 0x56, 0xce, 0xc8, 0xb9, 0xe3, 0x24, 0x5b, 0x58, + 0x51, 0x37, 0xa6, 0x8b, 0xe0, 0xf5, 0x52, 0xf1, 0xbf, 0x2b, 0xe8, 0xd9, 0xb3, 0x67, 0xcf, 0x32, + 0xb5, 0xdf, 0x15, 0x60, 0x73, 0xd9, 0x9a, 0x59, 0xba, 0x7c, 0x2f, 0x40, 0xc1, 0x9e, 0x4e, 0x4e, + 0xa8, 0xc7, 0x83, 0x94, 0x57, 0xc3, 0x16, 0x6e, 0x40, 0xde, 0x22, 0x27, 0xd4, 0x92, 0x73, 0xdb, + 0xd2, 0x4e, 0xf5, 0xe6, 0x3b, 0xe7, 0x5a, 0x95, 0xf5, 0x43, 0xa6, 0xa2, 0x0a, 0x4d, 0xfc, 0x11, + 0xe4, 0xc2, 0x2d, 0x9a, 0x59, 0xb8, 0x7e, 0x3e, 0x0b, 0x6c, 0x2d, 0xa9, 0x5c, 0x0f, 0xbf, 0x02, + 0x25, 0xf6, 0x2b, 0x72, 0xa3, 0xc0, 0x7d, 0x2e, 0x32, 0x80, 0xe5, 0x05, 0xde, 0x82, 0x22, 0x5f, + 0x26, 0x06, 0x8d, 0x8e, 0xb6, 0xb8, 0xcd, 0x12, 0xcb, 0xa0, 0x43, 0x32, 0xb5, 0x02, 0xed, 0x31, + 0xb1, 0xa6, 0x94, 0x27, 0x7c, 0x49, 0xad, 0x84, 0xe0, 0xcf, 0x19, 0x86, 0x2f, 0x43, 0x59, 0xac, + 0x2a, 0xd3, 0x36, 0xe8, 0x53, 0xbe, 0x7b, 0xe6, 0x55, 0xb1, 0xd0, 0xda, 0x0c, 0x61, 0xdd, 0x3f, + 0xf4, 0x1d, 0x3b, 0x4a, 0x4d, 0xde, 0x05, 0x03, 0x78, 0xf7, 0x1f, 0xcc, 0x6f, 0xdc, 0xaf, 0x2d, + 0x1f, 0xde, 0x7c, 0x4e, 0xd5, 0xfe, 0x92, 0x81, 0x1c, 0xdf, 0x2f, 0xd6, 0xa0, 0x3c, 0xf8, 0xac, + 0xa7, 0x68, 0xad, 0xee, 0xf1, 0xfe, 0xa1, 0x82, 0x24, 0x5c, 0x05, 0xe0, 0xc0, 0xfd, 0xc3, 0x6e, + 0x63, 0x80, 0x32, 0x71, 0xbb, 0xdd, 0x19, 0xdc, 0xb9, 0x85, 0xb2, 0xb1, 0xc2, 0xb1, 0x00, 0x72, + 0x49, 0xc2, 0xfb, 0x37, 0x51, 0x1e, 0x23, 0xa8, 0x08, 0x03, 0xed, 0x4f, 0x95, 0xd6, 0x9d, 0x5b, + 0xa8, 0x90, 0x46, 0xde, 0xbf, 0x89, 0x56, 0xf0, 0x2a, 0x94, 0x38, 0xb2, 0xdf, 0xed, 0x1e, 0xa2, + 0x62, 0x6c, 0xb3, 0x3f, 0x50, 0xdb, 0x9d, 0x03, 0x54, 0x8a, 0x6d, 0x1e, 0xa8, 0xdd, 0xe3, 0x1e, + 0x82, 0xd8, 0xc2, 0x91, 0xd2, 0xef, 0x37, 0x0e, 0x14, 0x54, 0x8e, 0x19, 0xfb, 0x9f, 0x0d, 0x94, + 0x3e, 0xaa, 0xa4, 0xdc, 0x7a, 0xff, 0x26, 0x5a, 0x8d, 0xbb, 0x50, 0x3a, 0xc7, 0x47, 0xa8, 0x8a, + 0xd7, 0x61, 0x55, 0x74, 0x11, 0x39, 0xb1, 0x36, 0x07, 0xdd, 0xb9, 0x85, 0xd0, 0xcc, 0x11, 0x61, + 0x65, 0x3d, 0x05, 0xdc, 0xb9, 0x85, 0x70, 0xad, 0x09, 0x79, 0x9e, 0x5d, 0x18, 0x43, 0xf5, 0xb0, + 0xb1, 0xaf, 0x1c, 0x6a, 0xdd, 0xde, 0xa0, 0xdd, 0xed, 0x34, 0x0e, 0x91, 0x34, 0xc3, 0x54, 0xe5, + 0x67, 0xc7, 0x6d, 0x55, 0x69, 0xa1, 0x4c, 0x12, 0xeb, 0x29, 0x8d, 0x81, 0xd2, 0x42, 0xd9, 0x9a, + 0x0e, 0x9b, 0xcb, 0xf6, 0xc9, 0xa5, 0x2b, 0x23, 0x31, 0xc5, 0x99, 0x33, 0xa6, 0x98, 0xdb, 0x5a, + 0x98, 0xe2, 0x7f, 0x65, 0x60, 0x63, 0xc9, 0x59, 0xb1, 0xb4, 0x93, 0x1f, 0x43, 0x5e, 0xa4, 0xa8, + 0x38, 0x3d, 0xaf, 0x2d, 0x3d, 0x74, 0x78, 0xc2, 0x2e, 0x9c, 0xa0, 0x5c, 0x2f, 0x59, 0x41, 0x64, + 0xcf, 0xa8, 0x20, 0x98, 0x89, 0x85, 0x3d, 0xfd, 0x17, 0x0b, 0x7b, 0xba, 0x38, 0xf6, 0xee, 0x9c, + 0xe7, 0xd8, 0xe3, 0xd8, 0xb7, 0xdb, 0xdb, 0xf3, 0x4b, 0xf6, 0xf6, 0x7b, 0xb0, 0xbe, 0x60, 0xe8, + 0xdc, 0x7b, 0xec, 0xaf, 0x24, 0x90, 0xcf, 0x0a, 0xce, 0x73, 0x76, 0xba, 0x4c, 0x6a, 0xa7, 0xbb, + 0x37, 0x1f, 0xc1, 0x2b, 0x67, 0x4f, 0xc2, 0xc2, 0x5c, 0x7f, 0x25, 0xc1, 0x85, 0xe5, 0x95, 0xe2, + 0x52, 0x1f, 0x3e, 0x82, 0xc2, 0x84, 0x06, 0x63, 0x27, 0xaa, 0x96, 0xde, 0x5e, 0x72, 0x06, 0x33, + 0xf1, 0xfc, 0x64, 0x87, 0x5a, 0xc9, 0x43, 0x3c, 0x7b, 0x56, 0xb9, 0x27, 0xbc, 0x59, 0xf0, 0xf4, + 0xd7, 0x19, 0x78, 0x79, 0xa9, 0xf1, 0xa5, 0x8e, 0xbe, 0x06, 0x60, 0xda, 0xee, 0x34, 0x10, 0x15, + 0x91, 0xd8, 0x60, 0x4b, 0x1c, 0xe1, 0x9b, 0x17, 0xdb, 0x3c, 0xa7, 0x41, 0x2c, 0xcf, 0x72, 0x39, + 0x08, 0x88, 0x13, 0xee, 0xce, 0x1c, 0xcd, 0x71, 0x47, 0x5f, 0x3f, 0x63, 0xa4, 0x0b, 0x89, 0xf9, + 0x1e, 0x20, 0xdd, 0x32, 0xa9, 0x1d, 0x68, 0x7e, 0xe0, 0x51, 0x32, 0x31, 0xed, 0x11, 0x3f, 0x41, + 0x8a, 0x7b, 0xf9, 0x21, 0xb1, 0x7c, 0xaa, 0xae, 0x09, 0x71, 0x3f, 0x92, 0x32, 0x0d, 0x9e, 0x40, + 0x5e, 0x42, 0xa3, 0x90, 0xd2, 0x10, 0xe2, 0x58, 0xa3, 0xf6, 0xdb, 0x12, 0x94, 0x13, 0x75, 0x35, + 0xbe, 0x02, 0x95, 0x87, 0xe4, 0x31, 0xd1, 0xa2, 0xbb, 0x92, 0x88, 0x44, 0x99, 0x61, 0xbd, 0xf0, + 0xbe, 0xf4, 0x1e, 0x6c, 0x72, 0x8a, 0x33, 0x0d, 0xa8, 0xa7, 0xe9, 0x16, 0xf1, 0x7d, 0x1e, 0xb4, + 0x22, 0xa7, 0x62, 0x26, 0xeb, 0x32, 0x51, 0x33, 0x92, 0xe0, 0xdb, 0xb0, 0xc1, 0x35, 0x26, 0x53, + 0x2b, 0x30, 0x5d, 0x8b, 0x6a, 0xec, 0xf6, 0xe6, 0xf3, 0x93, 0x24, 0xf6, 0x6c, 0x9d, 0x31, 0x8e, + 0x42, 0x02, 0xf3, 0xc8, 0xc7, 0x2d, 0x78, 0x8d, 0xab, 0x8d, 0xa8, 0x4d, 0x3d, 0x12, 0x50, 0x8d, + 0x7e, 0x31, 0x25, 0x96, 0xaf, 0x11, 0xdb, 0xd0, 0xc6, 0xc4, 0x1f, 0xcb, 0x9b, 0xcc, 0xc0, 0x7e, + 0x46, 0x96, 0xd4, 0x4b, 0x8c, 0x78, 0x10, 0xf2, 0x14, 0x4e, 0x6b, 0xd8, 0xc6, 0xc7, 0xc4, 0x1f, + 0xe3, 0x3d, 0xb8, 0xc0, 0xad, 0xf8, 0x81, 0x67, 0xda, 0x23, 0x4d, 0x1f, 0x53, 0xfd, 0x91, 0x36, + 0x0d, 0x86, 0x77, 0xe5, 0x57, 0x92, 0xfd, 0x73, 0x0f, 0xfb, 0x9c, 0xd3, 0x64, 0x94, 0xe3, 0x60, + 0x78, 0x17, 0xf7, 0xa1, 0xc2, 0x26, 0x63, 0x62, 0x7e, 0x49, 0xb5, 0xa1, 0xe3, 0xf1, 0xa3, 0xb1, + 0xba, 0x64, 0x6b, 0x4a, 0x44, 0xb0, 0xde, 0x0d, 0x15, 0x8e, 0x1c, 0x83, 0xee, 0xe5, 0xfb, 0x3d, + 0x45, 0x69, 0xa9, 0xe5, 0xc8, 0xca, 0x7d, 0xc7, 0x63, 0x09, 0x35, 0x72, 0xe2, 0x00, 0x97, 0x45, + 0x42, 0x8d, 0x9c, 0x28, 0xbc, 0xb7, 0x61, 0x43, 0xd7, 0xc5, 0x98, 0x4d, 0x5d, 0x0b, 0xef, 0x58, + 0xbe, 0x8c, 0x52, 0xc1, 0xd2, 0xf5, 0x03, 0x41, 0x08, 0x73, 0xdc, 0xc7, 0x1f, 0xc2, 0xcb, 0xb3, + 0x60, 0x25, 0x15, 0xd7, 0x17, 0x46, 0x39, 0xaf, 0x7a, 0x1b, 0x36, 0xdc, 0xd3, 0x45, 0x45, 0x9c, + 0xea, 0xd1, 0x3d, 0x9d, 0x57, 0xfb, 0x00, 0x36, 0xdd, 0xb1, 0xbb, 0xa8, 0x77, 0x3d, 0xa9, 0x87, + 0xdd, 0xb1, 0x3b, 0xaf, 0xf8, 0x16, 0xbf, 0x70, 0x7b, 0x54, 0x27, 0x01, 0x35, 0xe4, 0x8b, 0x49, + 0x7a, 0x42, 0x80, 0x77, 0x01, 0xe9, 0xba, 0x46, 0x6d, 0x72, 0x62, 0x51, 0x8d, 0x78, 0xd4, 0x26, + 0xbe, 0x7c, 0x39, 0x49, 0xae, 0xea, 0xba, 0xc2, 0xa5, 0x0d, 0x2e, 0xc4, 0xd7, 0x61, 0xdd, 0x39, + 0x79, 0xa8, 0x8b, 0x94, 0xd4, 0x5c, 0x8f, 0x0e, 0xcd, 0xa7, 0xf2, 0x9b, 0x3c, 0xbe, 0x6b, 0x4c, + 0xc0, 0x13, 0xb2, 0xc7, 0x61, 0x7c, 0x0d, 0x90, 0xee, 0x8f, 0x89, 0xe7, 0xf2, 0x3d, 0xd9, 0x77, + 0x89, 0x4e, 0xe5, 0xb7, 0x04, 0x55, 0xe0, 0x9d, 0x08, 0x66, 0x4b, 0xc2, 0x7f, 0x62, 0x0e, 0x83, + 0xc8, 0xe2, 0x55, 0xb1, 0x24, 0x38, 0x16, 0x5a, 0xdb, 0x01, 0xc4, 0x42, 0x91, 0xea, 0x78, 0x87, + 0xd3, 0xaa, 0xee, 0xd8, 0x4d, 0xf6, 0xfb, 0x06, 0xac, 0x32, 0xe6, 0xac, 0xd3, 0x6b, 0xa2, 0x20, + 0x73, 0xc7, 0x89, 0x1e, 0x6f, 0xc1, 0x05, 0x46, 0x9a, 0xd0, 0x80, 0x18, 0x24, 0x20, 0x09, 0xf6, + 0xbb, 0x9c, 0xcd, 0xe2, 0x7e, 0x14, 0x0a, 0x53, 0x7e, 0x7a, 0xd3, 0x93, 0xd3, 0x38, 0xb3, 0x6e, + 0x08, 0x3f, 0x19, 0x16, 0xe5, 0xd6, 0xf7, 0x56, 0x74, 0xd7, 0xf6, 0xa0, 0x92, 0x4c, 0x7c, 0x5c, + 0x02, 0x91, 0xfa, 0x48, 0x62, 0x55, 0x50, 0xb3, 0xdb, 0x62, 0xf5, 0xcb, 0xe7, 0x0a, 0xca, 0xb0, + 0x3a, 0xea, 0xb0, 0x3d, 0x50, 0x34, 0xf5, 0xb8, 0x33, 0x68, 0x1f, 0x29, 0x28, 0x9b, 0x28, 0xd8, + 0x1f, 0xe4, 0x8a, 0x6f, 0xa3, 0xab, 0xb5, 0xaf, 0x33, 0x50, 0x4d, 0xdf, 0xc0, 0xf0, 0x8f, 0xe0, + 0x62, 0xf4, 0x5c, 0xe2, 0xd3, 0x40, 0x7b, 0x62, 0x7a, 0x7c, 0x45, 0x4e, 0x88, 0x38, 0x1d, 0xe3, + 0x9c, 0xd8, 0x0c, 0x59, 0x7d, 0x1a, 0x7c, 0x62, 0x7a, 0x6c, 0xbd, 0x4d, 0x48, 0x80, 0x0f, 0xe1, + 0xb2, 0xed, 0x68, 0x7e, 0x40, 0x6c, 0x83, 0x78, 0x86, 0x36, 0x7b, 0xa8, 0xd2, 0x88, 0xae, 0x53, + 0xdf, 0x77, 0xc4, 0x49, 0x18, 0x5b, 0x79, 0xd5, 0x76, 0xfa, 0x21, 0x79, 0x76, 0x44, 0x34, 0x42, + 0xea, 0x5c, 0xfe, 0x66, 0xcf, 0xca, 0xdf, 0x57, 0xa0, 0x34, 0x21, 0xae, 0x46, 0xed, 0xc0, 0x3b, + 0xe5, 0x75, 0x77, 0x51, 0x2d, 0x4e, 0x88, 0xab, 0xb0, 0xf6, 0x0b, 0xb9, 0xfe, 0x3c, 0xc8, 0x15, + 0x8b, 0xa8, 0xf4, 0x20, 0x57, 0x2c, 0x21, 0xa8, 0xfd, 0x33, 0x0b, 0x95, 0x64, 0x1d, 0xce, 0xae, + 0x35, 0x3a, 0x3f, 0xb2, 0x24, 0xbe, 0xa9, 0xbd, 0xf1, 0x8d, 0x55, 0x7b, 0xbd, 0xc9, 0xce, 0xb2, + 0xbd, 0x82, 0xa8, 0x8e, 0x55, 0xa1, 0xc9, 0xea, 0x08, 0x96, 0x6c, 0x54, 0x54, 0x23, 0x45, 0x35, + 0x6c, 0xe1, 0x03, 0x28, 0x3c, 0xf4, 0xb9, 0xed, 0x02, 0xb7, 0xfd, 0xe6, 0x37, 0xdb, 0x7e, 0xd0, + 0xe7, 0xc6, 0x4b, 0x0f, 0xfa, 0x5a, 0xa7, 0xab, 0x1e, 0x35, 0x0e, 0xd5, 0x50, 0x1d, 0x5f, 0x82, + 0x9c, 0x45, 0xbe, 0x3c, 0x4d, 0x9f, 0x7a, 0x1c, 0x3a, 0xef, 0x24, 0x5c, 0x82, 0xdc, 0x13, 0x4a, + 0x1e, 0xa5, 0xcf, 0x1a, 0x0e, 0x7d, 0x8f, 0x8b, 0x61, 0x17, 0xf2, 0x3c, 0x5e, 0x18, 0x20, 0x8c, + 0x18, 0x7a, 0x09, 0x17, 0x21, 0xd7, 0xec, 0xaa, 0x6c, 0x41, 0x20, 0xa8, 0x08, 0x54, 0xeb, 0xb5, + 0x95, 0xa6, 0x82, 0x32, 0xb5, 0xdb, 0x50, 0x10, 0x41, 0x60, 0x8b, 0x25, 0x0e, 0x03, 0x7a, 0x29, + 0x6c, 0x86, 0x36, 0xa4, 0x48, 0x7a, 0x7c, 0xb4, 0xaf, 0xa8, 0x28, 0x93, 0x9e, 0xea, 0x1c, 0xca, + 0xd7, 0x7c, 0xa8, 0x24, 0x0b, 0xf1, 0x17, 0x73, 0xc9, 0xfe, 0x9b, 0x04, 0xe5, 0x44, 0x61, 0xcd, + 0x2a, 0x22, 0x62, 0x59, 0xce, 0x13, 0x8d, 0x58, 0x26, 0xf1, 0xc3, 0xd4, 0x00, 0x0e, 0x35, 0x18, + 0x72, 0xde, 0xa9, 0x7b, 0x41, 0x4b, 0x24, 0x8f, 0x0a, 0xb5, 0x3f, 0x4a, 0x80, 0xe6, 0x2b, 0xdb, + 0x39, 0x37, 0xa5, 0x1f, 0xd2, 0xcd, 0xda, 0x1f, 0x24, 0xa8, 0xa6, 0xcb, 0xd9, 0x39, 0xf7, 0xae, + 0xfc, 0xa0, 0xee, 0xfd, 0x23, 0x03, 0xab, 0xa9, 0x22, 0xf6, 0xbc, 0xde, 0x7d, 0x01, 0xeb, 0xa6, + 0x41, 0x27, 0xae, 0x13, 0x50, 0x5b, 0x3f, 0xd5, 0x2c, 0xfa, 0x98, 0x5a, 0x72, 0x8d, 0x6f, 0x1a, + 0xbb, 0xdf, 0x5c, 0x26, 0xd7, 0xdb, 0x33, 0xbd, 0x43, 0xa6, 0xb6, 0xb7, 0xd1, 0x6e, 0x29, 0x47, + 0xbd, 0xee, 0x40, 0xe9, 0x34, 0x3f, 0xd3, 0x8e, 0x3b, 0x3f, 0xed, 0x74, 0x3f, 0xe9, 0xa8, 0xc8, + 0x9c, 0xa3, 0x7d, 0x8f, 0xcb, 0xbe, 0x07, 0x68, 0xde, 0x29, 0x7c, 0x11, 0x96, 0xb9, 0x85, 0x5e, + 0xc2, 0x1b, 0xb0, 0xd6, 0xe9, 0x6a, 0xfd, 0x76, 0x4b, 0xd1, 0x94, 0xfb, 0xf7, 0x95, 0xe6, 0xa0, + 0x2f, 0x1e, 0x3e, 0x62, 0xf6, 0x20, 0xb5, 0xc0, 0x6b, 0xbf, 0xcf, 0xc2, 0xc6, 0x12, 0x4f, 0x70, + 0x23, 0xbc, 0xb2, 0x88, 0x5b, 0xd4, 0x8d, 0xf3, 0x78, 0x5f, 0x67, 0x35, 0x43, 0x8f, 0x78, 0x41, + 0x78, 0xc3, 0xb9, 0x06, 0x2c, 0x4a, 0x76, 0x60, 0x0e, 0x4d, 0xea, 0x85, 0xef, 0x44, 0xe2, 0x1e, + 0xb3, 0x36, 0xc3, 0xc5, 0x53, 0xd1, 0xbb, 0x80, 0x5d, 0xc7, 0x37, 0x03, 0xf3, 0x31, 0xd5, 0x4c, + 0x3b, 0x7a, 0x54, 0x62, 0xf7, 0x9a, 0x9c, 0x8a, 0x22, 0x49, 0xdb, 0x0e, 0x62, 0xb6, 0x4d, 0x47, + 0x64, 0x8e, 0xcd, 0x36, 0xf3, 0xac, 0x8a, 0x22, 0x49, 0xcc, 0xbe, 0x02, 0x15, 0xc3, 0x99, 0xb2, + 0x62, 0x4f, 0xf0, 0xd8, 0xd9, 0x21, 0xa9, 0x65, 0x81, 0xc5, 0x94, 0xb0, 0x8c, 0x9f, 0xbd, 0x66, + 0x55, 0xd4, 0xb2, 0xc0, 0x04, 0xe5, 0x2a, 0xac, 0x91, 0xd1, 0xc8, 0x63, 0xc6, 0x23, 0x43, 0xe2, + 0x62, 0x52, 0x8d, 0x61, 0x4e, 0xdc, 0x7a, 0x00, 0xc5, 0x28, 0x0e, 0xec, 0xa8, 0x66, 0x91, 0xd0, + 0x5c, 0x71, 0xdb, 0xce, 0xec, 0x94, 0xd4, 0xa2, 0x1d, 0x09, 0xaf, 0x40, 0xc5, 0xf4, 0xb5, 0xd9, + 0xe3, 0x7c, 0x66, 0x3b, 0xb3, 0x53, 0x54, 0xcb, 0xa6, 0x1f, 0x3f, 0x6c, 0xd6, 0xbe, 0xca, 0x40, + 0x35, 0xfd, 0x71, 0x01, 0xb7, 0xa0, 0x68, 0x39, 0x3a, 0xe1, 0xa9, 0x25, 0xbe, 0x6c, 0xed, 0x3c, + 0xe7, 0x7b, 0x44, 0xfd, 0x30, 0xe4, 0xab, 0xb1, 0xe6, 0xd6, 0xdf, 0x25, 0x28, 0x46, 0x30, 0xbe, + 0x00, 0x39, 0x97, 0x04, 0x63, 0x6e, 0x2e, 0xbf, 0x9f, 0x41, 0x92, 0xca, 0xdb, 0x0c, 0xf7, 0x5d, + 0x62, 0xf3, 0x14, 0x08, 0x71, 0xd6, 0x66, 0xf3, 0x6a, 0x51, 0x62, 0xf0, 0x5b, 0x8f, 0x33, 0x99, + 0x50, 0x3b, 0xf0, 0xa3, 0x79, 0x0d, 0xf1, 0x66, 0x08, 0xe3, 0x77, 0x60, 0x3d, 0xf0, 0x88, 0x69, + 0xa5, 0xb8, 0x39, 0xce, 0x45, 0x91, 0x20, 0x26, 0xef, 0xc1, 0xa5, 0xc8, 0xae, 0x41, 0x03, 0xa2, + 0x8f, 0xa9, 0x31, 0x53, 0x2a, 0xf0, 0xd7, 0x8d, 0x8b, 0x21, 0xa1, 0x15, 0xca, 0x23, 0xdd, 0xda, + 0xd7, 0x12, 0xac, 0x47, 0xf7, 0x34, 0x23, 0x0e, 0xd6, 0x11, 0x00, 0xb1, 0x6d, 0x27, 0x48, 0x86, + 0x6b, 0x31, 0x95, 0x17, 0xf4, 0xea, 0x8d, 0x58, 0x49, 0x4d, 0x18, 0xd8, 0x9a, 0x00, 0xcc, 0x24, + 0x67, 0x86, 0xed, 0x32, 0x94, 0xc3, 0x2f, 0x47, 0xfc, 0xf3, 0xa3, 0xb8, 0xd9, 0x83, 0x80, 0xd8, + 0x85, 0x0e, 0x6f, 0x42, 0xfe, 0x84, 0x8e, 0x4c, 0x3b, 0x7c, 0x0f, 0x16, 0x8d, 0xe8, 0xfd, 0x25, + 0x17, 0xbf, 0xbf, 0xec, 0xff, 0x46, 0x82, 0x0d, 0xdd, 0x99, 0xcc, 0xfb, 0xbb, 0x8f, 0xe6, 0x9e, + 0x17, 0xfc, 0x8f, 0xa5, 0xcf, 0x3f, 0x1a, 0x99, 0xc1, 0x78, 0x7a, 0x52, 0xd7, 0x9d, 0xc9, 0xee, + 0xc8, 0xb1, 0x88, 0x3d, 0x9a, 0x7d, 0x3f, 0xe5, 0x7f, 0xf4, 0x1b, 0x23, 0x6a, 0xdf, 0x18, 0x39, + 0x89, 0xaf, 0xa9, 0xf7, 0x66, 0x7f, 0xff, 0x27, 0x49, 0x7f, 0xca, 0x64, 0x0f, 0x7a, 0xfb, 0x7f, + 0xce, 0x6c, 0x1d, 0x88, 0xee, 0x7a, 0x51, 0x78, 0x54, 0x3a, 0xb4, 0xa8, 0xce, 0x86, 0xfc, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xe8, 0xef, 0xc4, 0x9b, 0x1d, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto new file mode 100644 index 00000000..ed08fcbc --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto @@ -0,0 +1,883 @@ +// 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. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; +option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; + optional int32 end = 2; + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + }; + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + }; + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default=false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default=false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default=false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default=false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default=SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; + optional bool php_generic_services = 42 [default=false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default=false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default=false]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be used + // for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default=false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default=false]; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default=false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default=false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default=false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default=false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default=false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = + 34 [default=IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed=true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/vendor/github.com/golang/snappy/go.mod b/vendor/github.com/golang/snappy/go.mod new file mode 100644 index 00000000..f6406bb2 --- /dev/null +++ b/vendor/github.com/golang/snappy/go.mod @@ -0,0 +1 @@ +module github.com/golang/snappy diff --git a/vendor/github.com/google/uuid/go.mod b/vendor/github.com/google/uuid/go.mod new file mode 100644 index 00000000..fc84cd79 --- /dev/null +++ b/vendor/github.com/google/uuid/go.mod @@ -0,0 +1 @@ +module github.com/google/uuid diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go new file mode 100644 index 00000000..d651a2b0 --- /dev/null +++ b/vendor/github.com/google/uuid/node.go @@ -0,0 +1,90 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "sync" +) + +var ( + nodeMu sync.Mutex + ifname string // name of interface being used + nodeID [6]byte // hardware for version 1 UUIDs + zeroID [6]byte // nodeID with only 0's +) + +// NodeInterface returns the name of the interface from which the NodeID was +// derived. The interface "user" is returned if the NodeID was set by +// SetNodeID. +func NodeInterface() string { + defer nodeMu.Unlock() + nodeMu.Lock() + return ifname +} + +// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. +// If name is "" then the first usable interface found will be used or a random +// Node ID will be generated. If a named interface cannot be found then false +// is returned. +// +// SetNodeInterface never fails when name is "". +func SetNodeInterface(name string) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +func setNodeInterface(name string) bool { + iname, addr := getHardwareInterface(name) // null implementation for js + if iname != "" && addr != nil { + ifname = iname + copy(nodeID[:], addr) + return true + } + + // We found no interfaces with a valid hardware address. If name + // does not specify a specific interface generate a random Node ID + // (section 4.1.6) + if name == "" { + ifname = "random" + randomBits(nodeID[:]) + return true + } + return false +} + +// NodeID returns a slice of a copy of the current Node ID, setting the Node ID +// if not already set. +func NodeID() []byte { + defer nodeMu.Unlock() + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nid := nodeID + return nid[:] +} + +// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes +// of id are used. If id is less than 6 bytes then false is returned and the +// Node ID is not set. +func SetNodeID(id []byte) bool { + if len(id) < 6 { + return false + } + defer nodeMu.Unlock() + nodeMu.Lock() + copy(nodeID[:], id) + ifname = "user" + return true +} + +// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is +// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) NodeID() []byte { + var node [6]byte + copy(node[:], uuid[10:]) + return node[:] +} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go new file mode 100644 index 00000000..524404cc --- /dev/null +++ b/vendor/github.com/google/uuid/uuid.go @@ -0,0 +1,245 @@ +// Copyright 2018 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" +) + +// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC +// 4122. +type UUID [16]byte + +// A Version represents a UUID's version. +type Version byte + +// A Variant represents a UUID's variant. +type Variant byte + +// Constants returned by Variant. +const ( + Invalid = Variant(iota) // Invalid UUID + RFC4122 // The variant specified in RFC4122 + Reserved // Reserved, NCS backward compatibility. + Microsoft // Reserved, Microsoft Corporation backward compatibility. + Future // Reserved for future definition. +) + +var rander = rand.Reader // random function + +// Parse decodes s into a UUID or returns an error. Both the standard UUID +// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the +// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex +// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +func Parse(s string) (UUID, error) { + var uuid UUID + switch len(s) { + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36: + + // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: + if strings.ToLower(s[:9]) != "urn:uuid:" { + return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + case 36 + 2: + s = s[1:] + + // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + case 32: + var ok bool + for i := range uuid { + uuid[i], ok = xtob(s[i*2], s[i*2+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(s[x], s[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// ParseBytes is like Parse, except it parses a byte slice instead of a string. +func ParseBytes(b []byte) (UUID, error) { + var uuid UUID + switch len(b) { + case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) + } + b = b[9:] + case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + b = b[1:] + case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + var ok bool + for i := 0; i < 32; i += 2 { + uuid[i/2], ok = xtob(b[i], b[i+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(b[x], b[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// MustParse is like Parse but panics if the string cannot be parsed. +// It simplifies safe initialization of global variables holding compiled UUIDs. +func MustParse(s string) UUID { + uuid, err := Parse(s) + if err != nil { + panic(`uuid: Parse(` + s + `): ` + err.Error()) + } + return uuid +} + +// FromBytes creates a new UUID from a byte slice. Returns an error if the slice +// does not have a length of 16. The bytes are copied from the slice. +func FromBytes(b []byte) (uuid UUID, err error) { + err = uuid.UnmarshalBinary(b) + return uuid, err +} + +// Must returns uuid if err is nil and panics otherwise. +func Must(uuid UUID, err error) UUID { + if err != nil { + panic(err) + } + return uuid +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// URN returns the RFC 2141 URN form of uuid, +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. +func (uuid UUID) URN() string { + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst, uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[10:]) +} + +// Variant returns the variant encoded in uuid. +func (uuid UUID) Variant() Variant { + switch { + case (uuid[8] & 0xc0) == 0x80: + return RFC4122 + case (uuid[8] & 0xe0) == 0xc0: + return Microsoft + case (uuid[8] & 0xe0) == 0xe0: + return Future + default: + return Reserved + } +} + +// Version returns the version of uuid. +func (uuid UUID) Version() Version { + return Version(uuid[6] >> 4) +} + +func (v Version) String() string { + if v > 15 { + return fmt.Sprintf("BAD_VERSION_%d", v) + } + return fmt.Sprintf("VERSION_%d", v) +} + +func (v Variant) String() string { + switch v { + case RFC4122: + return "RFC4122" + case Reserved: + return "Reserved" + case Microsoft: + return "Microsoft" + case Future: + return "Future" + case Invalid: + return "Invalid" + } + return fmt.Sprintf("BadVariant%d", int(v)) +} + +// SetRand sets the random number generator to r, which implements io.Reader. +// If r.Read returns an error when the package requests random data then +// a panic will be issued. +// +// Calling SetRand with nil sets the random number generator to the default +// generator. +func SetRand(r io.Reader) { + if r == nil { + rander = rand.Reader + return + } + rander = r +} diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore new file mode 100644 index 00000000..cd3fcd1e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe + +.idea/ +*.iml diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml new file mode 100644 index 00000000..a49db51c --- /dev/null +++ b/vendor/github.com/gorilla/websocket/.travis.yml @@ -0,0 +1,19 @@ +language: go +sudo: false + +matrix: + include: + - go: 1.7.x + - go: 1.8.x + - go: 1.9.x + - go: 1.10.x + - go: 1.11.x + - go: tip + allow_failures: + - go: tip + +script: + - go get -t -v ./... + - diff -u <(echo -n) <(gofmt -d .) + - go vet $(go list ./... | grep -v /vendor/) + - go test -v -race ./... diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS new file mode 100644 index 00000000..1931f400 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/AUTHORS @@ -0,0 +1,9 @@ +# This is the official list of Gorilla WebSocket authors for copyright +# purposes. +# +# Please keep the list sorted. + +Gary Burd +Google LLC (https://opensource.google.com/) +Joachim Bauch + diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE new file mode 100644 index 00000000..9171c972 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +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. + +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 HOLDER 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. diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md new file mode 100644 index 00000000..20e391f8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/README.md @@ -0,0 +1,64 @@ +# Gorilla WebSocket + +Gorilla WebSocket is a [Go](http://golang.org/) implementation of the +[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. + +[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket) +[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) + +### Documentation + +* [API Reference](http://godoc.org/github.com/gorilla/websocket) +* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) +* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) +* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) +* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) + +### Status + +The Gorilla WebSocket package provides a complete and tested implementation of +the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The +package API is stable. + +### Installation + + go get github.com/gorilla/websocket + +### Protocol Compliance + +The Gorilla WebSocket package passes the server tests in the [Autobahn Test +Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn +subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). + +### Gorilla WebSocket compared with other packages + + + + + + + + + + + + + + + + + + +
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Compression ExtensionsExperimentalNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
+ +Notes: + +1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). +2. The application can get the type of a received data message by implementing + a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) + function. +3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. + Read returns when the input buffer is full or a frame boundary is + encountered. Each call to Write sends a single frame message. The Gorilla + io.Reader and io.WriteCloser operate on a single WebSocket message. + diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go new file mode 100644 index 00000000..2e32fd50 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client.go @@ -0,0 +1,395 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "context" + "crypto/tls" + "errors" + "io" + "io/ioutil" + "net" + "net/http" + "net/http/httptrace" + "net/url" + "strings" + "time" +) + +// ErrBadHandshake is returned when the server response to opening handshake is +// invalid. +var ErrBadHandshake = errors.New("websocket: bad handshake") + +var errInvalidCompression = errors.New("websocket: invalid compression negotiation") + +// NewClient creates a new client connection using the given net connection. +// The URL u specifies the host and request URI. Use requestHeader to specify +// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies +// (Cookie). Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etc. +// +// Deprecated: Use Dialer instead. +func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { + d := Dialer{ + ReadBufferSize: readBufSize, + WriteBufferSize: writeBufSize, + NetDial: func(net, addr string) (net.Conn, error) { + return netConn, nil + }, + } + return d.Dial(u.String(), requestHeader) +} + +// A Dialer contains options for connecting to WebSocket server. +type Dialer struct { + // NetDial specifies the dial function for creating TCP connections. If + // NetDial is nil, net.Dial is used. + NetDial func(network, addr string) (net.Conn, error) + + // NetDialContext specifies the dial function for creating TCP connections. If + // NetDialContext is nil, net.DialContext is used. + NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) + + // Proxy specifies a function to return a proxy for a given + // Request. If the function returns a non-nil error, the + // request is aborted with the provided error. + // If Proxy is nil or returns a nil *URL, no proxy is used. + Proxy func(*http.Request) (*url.URL, error) + + // TLSClientConfig specifies the TLS configuration to use with tls.Client. + // If nil, the default configuration is used. + TLSClientConfig *tls.Config + + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer + // size is zero, then a useful default size is used. The I/O buffer sizes + // do not limit the size of the messages that can be sent or received. + ReadBufferSize, WriteBufferSize int + + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + + // Subprotocols specifies the client's requested subprotocols. + Subprotocols []string + + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool + + // Jar specifies the cookie jar. + // If Jar is nil, cookies are not sent in requests and ignored + // in responses. + Jar http.CookieJar +} + +// Dial creates a new client connection by calling DialContext with a background context. +func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + return d.DialContext(context.Background(), urlStr, requestHeader) +} + +var errMalformedURL = errors.New("malformed ws or wss URL") + +func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { + hostPort = u.Host + hostNoPort = u.Host + if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { + hostNoPort = hostNoPort[:i] + } else { + switch u.Scheme { + case "wss": + hostPort += ":443" + case "https": + hostPort += ":443" + default: + hostPort += ":80" + } + } + return hostPort, hostNoPort +} + +// DefaultDialer is a dialer with all fields set to the default values. +var DefaultDialer = &Dialer{ + Proxy: http.ProxyFromEnvironment, + HandshakeTimeout: 45 * time.Second, +} + +// nilDialer is dialer to use when receiver is nil. +var nilDialer = *DefaultDialer + +// DialContext creates a new client connection. Use requestHeader to specify the +// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). +// Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// The context will be used in the request and in the Dialer +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etcetera. The response body may not contain the entire response and does not +// need to be closed by the application. +func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + if d == nil { + d = &nilDialer + } + + challengeKey, err := generateChallengeKey() + if err != nil { + return nil, nil, err + } + + u, err := url.Parse(urlStr) + if err != nil { + return nil, nil, err + } + + switch u.Scheme { + case "ws": + u.Scheme = "http" + case "wss": + u.Scheme = "https" + default: + return nil, nil, errMalformedURL + } + + if u.User != nil { + // User name and password are not allowed in websocket URIs. + return nil, nil, errMalformedURL + } + + req := &http.Request{ + Method: "GET", + URL: u, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: u.Host, + } + req = req.WithContext(ctx) + + // Set the cookies present in the cookie jar of the dialer + if d.Jar != nil { + for _, cookie := range d.Jar.Cookies(u) { + req.AddCookie(cookie) + } + } + + // Set the request headers using the capitalization for names and values in + // RFC examples. Although the capitalization shouldn't matter, there are + // servers that depend on it. The Header.Set method is not used because the + // method canonicalizes the header names. + req.Header["Upgrade"] = []string{"websocket"} + req.Header["Connection"] = []string{"Upgrade"} + req.Header["Sec-WebSocket-Key"] = []string{challengeKey} + req.Header["Sec-WebSocket-Version"] = []string{"13"} + if len(d.Subprotocols) > 0 { + req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} + } + for k, vs := range requestHeader { + switch { + case k == "Host": + if len(vs) > 0 { + req.Host = vs[0] + } + case k == "Upgrade" || + k == "Connection" || + k == "Sec-Websocket-Key" || + k == "Sec-Websocket-Version" || + k == "Sec-Websocket-Extensions" || + (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): + return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) + case k == "Sec-Websocket-Protocol": + req.Header["Sec-WebSocket-Protocol"] = vs + default: + req.Header[k] = vs + } + } + + if d.EnableCompression { + req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"} + } + + if d.HandshakeTimeout != 0 { + var cancel func() + ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout) + defer cancel() + } + + // Get network dial function. + var netDial func(network, add string) (net.Conn, error) + + if d.NetDialContext != nil { + netDial = func(network, addr string) (net.Conn, error) { + return d.NetDialContext(ctx, network, addr) + } + } else if d.NetDial != nil { + netDial = d.NetDial + } else { + netDialer := &net.Dialer{} + netDial = func(network, addr string) (net.Conn, error) { + return netDialer.DialContext(ctx, network, addr) + } + } + + // If needed, wrap the dial function to set the connection deadline. + if deadline, ok := ctx.Deadline(); ok { + forwardDial := netDial + netDial = func(network, addr string) (net.Conn, error) { + c, err := forwardDial(network, addr) + if err != nil { + return nil, err + } + err = c.SetDeadline(deadline) + if err != nil { + c.Close() + return nil, err + } + return c, nil + } + } + + // If needed, wrap the dial function to connect through a proxy. + if d.Proxy != nil { + proxyURL, err := d.Proxy(req) + if err != nil { + return nil, nil, err + } + if proxyURL != nil { + dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) + if err != nil { + return nil, nil, err + } + netDial = dialer.Dial + } + } + + hostPort, hostNoPort := hostPortNoPort(u) + trace := httptrace.ContextClientTrace(ctx) + if trace != nil && trace.GetConn != nil { + trace.GetConn(hostPort) + } + + netConn, err := netDial("tcp", hostPort) + if trace != nil && trace.GotConn != nil { + trace.GotConn(httptrace.GotConnInfo{ + Conn: netConn, + }) + } + if err != nil { + return nil, nil, err + } + + defer func() { + if netConn != nil { + netConn.Close() + } + }() + + if u.Scheme == "https" { + cfg := cloneTLSConfig(d.TLSClientConfig) + if cfg.ServerName == "" { + cfg.ServerName = hostNoPort + } + tlsConn := tls.Client(netConn, cfg) + netConn = tlsConn + + var err error + if trace != nil { + err = doHandshakeWithTrace(trace, tlsConn, cfg) + } else { + err = doHandshake(tlsConn, cfg) + } + + if err != nil { + return nil, nil, err + } + } + + conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil) + + if err := req.Write(netConn); err != nil { + return nil, nil, err + } + + if trace != nil && trace.GotFirstResponseByte != nil { + if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 { + trace.GotFirstResponseByte() + } + } + + resp, err := http.ReadResponse(conn.br, req) + if err != nil { + return nil, nil, err + } + + if d.Jar != nil { + if rc := resp.Cookies(); len(rc) > 0 { + d.Jar.SetCookies(u, rc) + } + } + + if resp.StatusCode != 101 || + !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || + !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || + resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { + // Before closing the network connection on return from this + // function, slurp up some of the response to aid application + // debugging. + buf := make([]byte, 1024) + n, _ := io.ReadFull(resp.Body, buf) + resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) + return nil, resp, ErrBadHandshake + } + + for _, ext := range parseExtensions(resp.Header) { + if ext[""] != "permessage-deflate" { + continue + } + _, snct := ext["server_no_context_takeover"] + _, cnct := ext["client_no_context_takeover"] + if !snct || !cnct { + return nil, resp, errInvalidCompression + } + conn.newCompressionWriter = compressNoContextTakeover + conn.newDecompressionReader = decompressNoContextTakeover + break + } + + resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) + conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") + + netConn.SetDeadline(time.Time{}) + netConn = nil // to avoid close in defer. + return conn, resp, nil +} + +func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error { + if err := tlsConn.Handshake(); err != nil { + return err + } + if !cfg.InsecureSkipVerify { + if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go new file mode 100644 index 00000000..4f0d9437 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone.go @@ -0,0 +1,16 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package websocket + +import "crypto/tls" + +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return cfg.Clone() +} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go new file mode 100644 index 00000000..babb007f --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone_legacy.go @@ -0,0 +1,38 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package websocket + +import "crypto/tls" + +// cloneTLSConfig clones all public fields except the fields +// SessionTicketsDisabled and SessionTicketKey. This avoids copying the +// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a +// config in active use. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go new file mode 100644 index 00000000..813ffb1e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -0,0 +1,148 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "compress/flate" + "errors" + "io" + "strings" + "sync" +) + +const ( + minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 + maxCompressionLevel = flate.BestCompression + defaultCompressionLevel = 1 +) + +var ( + flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool + flateReaderPool = sync.Pool{New: func() interface{} { + return flate.NewReader(nil) + }} +) + +func decompressNoContextTakeover(r io.Reader) io.ReadCloser { + const tail = + // Add four bytes as specified in RFC + "\x00\x00\xff\xff" + + // Add final block to squelch unexpected EOF error from flate reader. + "\x01\x00\x00\xff\xff" + + fr, _ := flateReaderPool.Get().(io.ReadCloser) + fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) + return &flateReadWrapper{fr} +} + +func isValidCompressionLevel(level int) bool { + return minCompressionLevel <= level && level <= maxCompressionLevel +} + +func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { + p := &flateWriterPools[level-minCompressionLevel] + tw := &truncWriter{w: w} + fw, _ := p.Get().(*flate.Writer) + if fw == nil { + fw, _ = flate.NewWriter(tw, level) + } else { + fw.Reset(tw) + } + return &flateWriteWrapper{fw: fw, tw: tw, p: p} +} + +// truncWriter is an io.Writer that writes all but the last four bytes of the +// stream to another io.Writer. +type truncWriter struct { + w io.WriteCloser + n int + p [4]byte +} + +func (w *truncWriter) Write(p []byte) (int, error) { + n := 0 + + // fill buffer first for simplicity. + if w.n < len(w.p) { + n = copy(w.p[w.n:], p) + p = p[n:] + w.n += n + if len(p) == 0 { + return n, nil + } + } + + m := len(p) + if m > len(w.p) { + m = len(w.p) + } + + if nn, err := w.w.Write(w.p[:m]); err != nil { + return n + nn, err + } + + copy(w.p[:], w.p[m:]) + copy(w.p[len(w.p)-m:], p[len(p)-m:]) + nn, err := w.w.Write(p[:len(p)-m]) + return n + nn, err +} + +type flateWriteWrapper struct { + fw *flate.Writer + tw *truncWriter + p *sync.Pool +} + +func (w *flateWriteWrapper) Write(p []byte) (int, error) { + if w.fw == nil { + return 0, errWriteClosed + } + return w.fw.Write(p) +} + +func (w *flateWriteWrapper) Close() error { + if w.fw == nil { + return errWriteClosed + } + err1 := w.fw.Flush() + w.p.Put(w.fw) + w.fw = nil + if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { + return errors.New("websocket: internal error, unexpected bytes at end of flate stream") + } + err2 := w.tw.w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +type flateReadWrapper struct { + fr io.ReadCloser +} + +func (r *flateReadWrapper) Read(p []byte) (int, error) { + if r.fr == nil { + return 0, io.ErrClosedPipe + } + n, err := r.fr.Read(p) + if err == io.EOF { + // Preemptively place the reader back in the pool. This helps with + // scenarios where the application does not call NextReader() soon after + // this final read. + r.Close() + } + return n, err +} + +func (r *flateReadWrapper) Close() error { + if r.fr == nil { + return io.ErrClosedPipe + } + err := r.fr.Close() + flateReaderPool.Put(r.fr) + r.fr = nil + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go new file mode 100644 index 00000000..d2a21c14 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -0,0 +1,1165 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "encoding/binary" + "errors" + "io" + "io/ioutil" + "math/rand" + "net" + "strconv" + "sync" + "time" + "unicode/utf8" +) + +const ( + // Frame header byte 0 bits from Section 5.2 of RFC 6455 + finalBit = 1 << 7 + rsv1Bit = 1 << 6 + rsv2Bit = 1 << 5 + rsv3Bit = 1 << 4 + + // Frame header byte 1 bits from Section 5.2 of RFC 6455 + maskBit = 1 << 7 + + maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask + maxControlFramePayloadSize = 125 + + writeWait = time.Second + + defaultReadBufferSize = 4096 + defaultWriteBufferSize = 4096 + + continuationFrame = 0 + noFrame = -1 +) + +// Close codes defined in RFC 6455, section 11.7. +const ( + CloseNormalClosure = 1000 + CloseGoingAway = 1001 + CloseProtocolError = 1002 + CloseUnsupportedData = 1003 + CloseNoStatusReceived = 1005 + CloseAbnormalClosure = 1006 + CloseInvalidFramePayloadData = 1007 + ClosePolicyViolation = 1008 + CloseMessageTooBig = 1009 + CloseMandatoryExtension = 1010 + CloseInternalServerErr = 1011 + CloseServiceRestart = 1012 + CloseTryAgainLater = 1013 + CloseTLSHandshake = 1015 +) + +// The message types are defined in RFC 6455, section 11.8. +const ( + // TextMessage denotes a text data message. The text message payload is + // interpreted as UTF-8 encoded text data. + TextMessage = 1 + + // BinaryMessage denotes a binary data message. + BinaryMessage = 2 + + // CloseMessage denotes a close control message. The optional message + // payload contains a numeric code and text. Use the FormatCloseMessage + // function to format a close message payload. + CloseMessage = 8 + + // PingMessage denotes a ping control message. The optional message payload + // is UTF-8 encoded text. + PingMessage = 9 + + // PongMessage denotes a pong control message. The optional message payload + // is UTF-8 encoded text. + PongMessage = 10 +) + +// ErrCloseSent is returned when the application writes a message to the +// connection after sending a close message. +var ErrCloseSent = errors.New("websocket: close sent") + +// ErrReadLimit is returned when reading a message that is larger than the +// read limit set for the connection. +var ErrReadLimit = errors.New("websocket: read limit exceeded") + +// netError satisfies the net Error interface. +type netError struct { + msg string + temporary bool + timeout bool +} + +func (e *netError) Error() string { return e.msg } +func (e *netError) Temporary() bool { return e.temporary } +func (e *netError) Timeout() bool { return e.timeout } + +// CloseError represents a close message. +type CloseError struct { + // Code is defined in RFC 6455, section 11.7. + Code int + + // Text is the optional text payload. + Text string +} + +func (e *CloseError) Error() string { + s := []byte("websocket: close ") + s = strconv.AppendInt(s, int64(e.Code), 10) + switch e.Code { + case CloseNormalClosure: + s = append(s, " (normal)"...) + case CloseGoingAway: + s = append(s, " (going away)"...) + case CloseProtocolError: + s = append(s, " (protocol error)"...) + case CloseUnsupportedData: + s = append(s, " (unsupported data)"...) + case CloseNoStatusReceived: + s = append(s, " (no status)"...) + case CloseAbnormalClosure: + s = append(s, " (abnormal closure)"...) + case CloseInvalidFramePayloadData: + s = append(s, " (invalid payload data)"...) + case ClosePolicyViolation: + s = append(s, " (policy violation)"...) + case CloseMessageTooBig: + s = append(s, " (message too big)"...) + case CloseMandatoryExtension: + s = append(s, " (mandatory extension missing)"...) + case CloseInternalServerErr: + s = append(s, " (internal server error)"...) + case CloseTLSHandshake: + s = append(s, " (TLS handshake error)"...) + } + if e.Text != "" { + s = append(s, ": "...) + s = append(s, e.Text...) + } + return string(s) +} + +// IsCloseError returns boolean indicating whether the error is a *CloseError +// with one of the specified codes. +func IsCloseError(err error, codes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range codes { + if e.Code == code { + return true + } + } + } + return false +} + +// IsUnexpectedCloseError returns boolean indicating whether the error is a +// *CloseError with a code not in the list of expected codes. +func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range expectedCodes { + if e.Code == code { + return false + } + } + return true + } + return false +} + +var ( + errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} + errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} + errBadWriteOpCode = errors.New("websocket: bad write message type") + errWriteClosed = errors.New("websocket: write closed") + errInvalidControlFrame = errors.New("websocket: invalid control frame") +) + +func newMaskKey() [4]byte { + n := rand.Uint32() + return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +} + +func hideTempErr(err error) error { + if e, ok := err.(net.Error); ok && e.Temporary() { + err = &netError{msg: e.Error(), timeout: e.Timeout()} + } + return err +} + +func isControl(frameType int) bool { + return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage +} + +func isData(frameType int) bool { + return frameType == TextMessage || frameType == BinaryMessage +} + +var validReceivedCloseCodes = map[int]bool{ + // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number + + CloseNormalClosure: true, + CloseGoingAway: true, + CloseProtocolError: true, + CloseUnsupportedData: true, + CloseNoStatusReceived: false, + CloseAbnormalClosure: false, + CloseInvalidFramePayloadData: true, + ClosePolicyViolation: true, + CloseMessageTooBig: true, + CloseMandatoryExtension: true, + CloseInternalServerErr: true, + CloseServiceRestart: true, + CloseTryAgainLater: true, + CloseTLSHandshake: false, +} + +func isValidReceivedCloseCode(code int) bool { + return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) +} + +// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this +// interface. The type of the value stored in a pool is not specified. +type BufferPool interface { + // Get gets a value from the pool or returns nil if the pool is empty. + Get() interface{} + // Put adds a value to the pool. + Put(interface{}) +} + +// writePoolData is the type added to the write buffer pool. This wrapper is +// used to prevent applications from peeking at and depending on the values +// added to the pool. +type writePoolData struct{ buf []byte } + +// The Conn type represents a WebSocket connection. +type Conn struct { + conn net.Conn + isServer bool + subprotocol string + + // Write fields + mu chan bool // used as mutex to protect write to conn + writeBuf []byte // frame is constructed in this buffer. + writePool BufferPool + writeBufSize int + writeDeadline time.Time + writer io.WriteCloser // the current writer returned to the application + isWriting bool // for best-effort concurrent write detection + + writeErrMu sync.Mutex + writeErr error + + enableWriteCompression bool + compressionLevel int + newCompressionWriter func(io.WriteCloser, int) io.WriteCloser + + // Read fields + reader io.ReadCloser // the current reader returned to the application + readErr error + br *bufio.Reader + readRemaining int64 // bytes remaining in current frame. + readFinal bool // true the current message has more frames. + readLength int64 // Message size. + readLimit int64 // Maximum message size. + readMaskPos int + readMaskKey [4]byte + handlePong func(string) error + handlePing func(string) error + handleClose func(int, string) error + readErrCount int + messageReader *messageReader // the current low-level reader + + readDecompress bool // whether last read frame had RSV1 set + newDecompressionReader func(io.Reader) io.ReadCloser +} + +func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn { + + if br == nil { + if readBufferSize == 0 { + readBufferSize = defaultReadBufferSize + } else if readBufferSize < maxControlFramePayloadSize { + // must be large enough for control frame + readBufferSize = maxControlFramePayloadSize + } + br = bufio.NewReaderSize(conn, readBufferSize) + } + + if writeBufferSize <= 0 { + writeBufferSize = defaultWriteBufferSize + } + writeBufferSize += maxFrameHeaderSize + + if writeBuf == nil && writeBufferPool == nil { + writeBuf = make([]byte, writeBufferSize) + } + + mu := make(chan bool, 1) + mu <- true + c := &Conn{ + isServer: isServer, + br: br, + conn: conn, + mu: mu, + readFinal: true, + writeBuf: writeBuf, + writePool: writeBufferPool, + writeBufSize: writeBufferSize, + enableWriteCompression: true, + compressionLevel: defaultCompressionLevel, + } + c.SetCloseHandler(nil) + c.SetPingHandler(nil) + c.SetPongHandler(nil) + return c +} + +// Subprotocol returns the negotiated protocol for the connection. +func (c *Conn) Subprotocol() string { + return c.subprotocol +} + +// Close closes the underlying network connection without sending or waiting +// for a close message. +func (c *Conn) Close() error { + return c.conn.Close() +} + +// LocalAddr returns the local network address. +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +// RemoteAddr returns the remote network address. +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +// Write methods + +func (c *Conn) writeFatal(err error) error { + err = hideTempErr(err) + c.writeErrMu.Lock() + if c.writeErr == nil { + c.writeErr = err + } + c.writeErrMu.Unlock() + return err +} + +func (c *Conn) read(n int) ([]byte, error) { + p, err := c.br.Peek(n) + if err == io.EOF { + err = errUnexpectedEOF + } + c.br.Discard(len(p)) + return p, err +} + +func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error { + <-c.mu + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + if len(buf1) == 0 { + _, err = c.conn.Write(buf0) + } else { + err = c.writeBufs(buf0, buf1) + } + if err != nil { + return c.writeFatal(err) + } + if frameType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return nil +} + +// WriteControl writes a control message with the given deadline. The allowed +// message types are CloseMessage, PingMessage and PongMessage. +func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { + if !isControl(messageType) { + return errBadWriteOpCode + } + if len(data) > maxControlFramePayloadSize { + return errInvalidControlFrame + } + + b0 := byte(messageType) | finalBit + b1 := byte(len(data)) + if !c.isServer { + b1 |= maskBit + } + + buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize) + buf = append(buf, b0, b1) + + if c.isServer { + buf = append(buf, data...) + } else { + key := newMaskKey() + buf = append(buf, key[:]...) + buf = append(buf, data...) + maskBytes(key, 0, buf[6:]) + } + + d := time.Hour * 1000 + if !deadline.IsZero() { + d = deadline.Sub(time.Now()) + if d < 0 { + return errWriteTimeout + } + } + + timer := time.NewTimer(d) + select { + case <-c.mu: + timer.Stop() + case <-timer.C: + return errWriteTimeout + } + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + _, err = c.conn.Write(buf) + if err != nil { + return c.writeFatal(err) + } + if messageType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return err +} + +func (c *Conn) prepWrite(messageType int) error { + // Close previous writer if not already closed by the application. It's + // probably better to return an error in this situation, but we cannot + // change this without breaking existing applications. + if c.writer != nil { + c.writer.Close() + c.writer = nil + } + + if !isControl(messageType) && !isData(messageType) { + return errBadWriteOpCode + } + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + if c.writeBuf == nil { + wpd, ok := c.writePool.Get().(writePoolData) + if ok { + c.writeBuf = wpd.buf + } else { + c.writeBuf = make([]byte, c.writeBufSize) + } + } + return nil +} + +// NextWriter returns a writer for the next message to send. The writer's Close +// method flushes the complete message to the network. +// +// There can be at most one open writer on a connection. NextWriter closes the +// previous writer if the application has not already done so. +// +// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and +// PongMessage) are supported. +func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { + if err := c.prepWrite(messageType); err != nil { + return nil, err + } + + mw := &messageWriter{ + c: c, + frameType: messageType, + pos: maxFrameHeaderSize, + } + c.writer = mw + if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { + w := c.newCompressionWriter(c.writer, c.compressionLevel) + mw.compress = true + c.writer = w + } + return c.writer, nil +} + +type messageWriter struct { + c *Conn + compress bool // whether next call to flushFrame should set RSV1 + pos int // end of data in writeBuf. + frameType int // type of the current frame. + err error +} + +func (w *messageWriter) fatal(err error) error { + if w.err != nil { + w.err = err + w.c.writer = nil + } + return err +} + +// flushFrame writes buffered data and extra as a frame to the network. The +// final argument indicates that this is the last frame in the message. +func (w *messageWriter) flushFrame(final bool, extra []byte) error { + c := w.c + length := w.pos - maxFrameHeaderSize + len(extra) + + // Check for invalid control frames. + if isControl(w.frameType) && + (!final || length > maxControlFramePayloadSize) { + return w.fatal(errInvalidControlFrame) + } + + b0 := byte(w.frameType) + if final { + b0 |= finalBit + } + if w.compress { + b0 |= rsv1Bit + } + w.compress = false + + b1 := byte(0) + if !c.isServer { + b1 |= maskBit + } + + // Assume that the frame starts at beginning of c.writeBuf. + framePos := 0 + if c.isServer { + // Adjust up if mask not included in the header. + framePos = 4 + } + + switch { + case length >= 65536: + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 127 + binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length)) + case length > 125: + framePos += 6 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 126 + binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length)) + default: + framePos += 8 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | byte(length) + } + + if !c.isServer { + key := newMaskKey() + copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) + maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) + if len(extra) > 0 { + return c.writeFatal(errors.New("websocket: internal error, extra used in client mode")) + } + } + + // Write the buffers to the connection with best-effort detection of + // concurrent writes. See the concurrency section in the package + // documentation for more info. + + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + + err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) + + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + + if err != nil { + return w.fatal(err) + } + + if final { + c.writer = nil + if c.writePool != nil { + c.writePool.Put(writePoolData{buf: c.writeBuf}) + c.writeBuf = nil + } + return nil + } + + // Setup for next frame. + w.pos = maxFrameHeaderSize + w.frameType = continuationFrame + return nil +} + +func (w *messageWriter) ncopy(max int) (int, error) { + n := len(w.c.writeBuf) - w.pos + if n <= 0 { + if err := w.flushFrame(false, nil); err != nil { + return 0, err + } + n = len(w.c.writeBuf) - w.pos + } + if n > max { + n = max + } + return n, nil +} + +func (w *messageWriter) Write(p []byte) (int, error) { + if w.err != nil { + return 0, w.err + } + + if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { + // Don't buffer large messages. + err := w.flushFrame(false, p) + if err != nil { + return 0, err + } + return len(p), nil + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) WriteString(p string) (int, error) { + if w.err != nil { + return 0, w.err + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { + if w.err != nil { + return 0, w.err + } + for { + if w.pos == len(w.c.writeBuf) { + err = w.flushFrame(false, nil) + if err != nil { + break + } + } + var n int + n, err = r.Read(w.c.writeBuf[w.pos:]) + w.pos += n + nn += int64(n) + if err != nil { + if err == io.EOF { + err = nil + } + break + } + } + return nn, err +} + +func (w *messageWriter) Close() error { + if w.err != nil { + return w.err + } + if err := w.flushFrame(true, nil); err != nil { + return err + } + w.err = errWriteClosed + return nil +} + +// WritePreparedMessage writes prepared message into connection. +func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { + frameType, frameData, err := pm.frame(prepareKey{ + isServer: c.isServer, + compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), + compressionLevel: c.compressionLevel, + }) + if err != nil { + return err + } + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + err = c.write(frameType, c.writeDeadline, frameData, nil) + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + return err +} + +// WriteMessage is a helper method for getting a writer using NextWriter, +// writing the message and closing the writer. +func (c *Conn) WriteMessage(messageType int, data []byte) error { + + if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { + // Fast path with no allocations and single frame. + + if err := c.prepWrite(messageType); err != nil { + return err + } + mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize} + n := copy(c.writeBuf[mw.pos:], data) + mw.pos += n + data = data[n:] + return mw.flushFrame(true, data) + } + + w, err := c.NextWriter(messageType) + if err != nil { + return err + } + if _, err = w.Write(data); err != nil { + return err + } + return w.Close() +} + +// SetWriteDeadline sets the write deadline on the underlying network +// connection. After a write has timed out, the websocket state is corrupt and +// all future writes will return an error. A zero value for t means writes will +// not time out. +func (c *Conn) SetWriteDeadline(t time.Time) error { + c.writeDeadline = t + return nil +} + +// Read methods + +func (c *Conn) advanceFrame() (int, error) { + // 1. Skip remainder of previous frame. + + if c.readRemaining > 0 { + if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { + return noFrame, err + } + } + + // 2. Read and parse first two bytes of frame header. + + p, err := c.read(2) + if err != nil { + return noFrame, err + } + + final := p[0]&finalBit != 0 + frameType := int(p[0] & 0xf) + mask := p[1]&maskBit != 0 + c.readRemaining = int64(p[1] & 0x7f) + + c.readDecompress = false + if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { + c.readDecompress = true + p[0] &^= rsv1Bit + } + + if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { + return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) + } + + switch frameType { + case CloseMessage, PingMessage, PongMessage: + if c.readRemaining > maxControlFramePayloadSize { + return noFrame, c.handleProtocolError("control frame length > 125") + } + if !final { + return noFrame, c.handleProtocolError("control frame not final") + } + case TextMessage, BinaryMessage: + if !c.readFinal { + return noFrame, c.handleProtocolError("message start before final message frame") + } + c.readFinal = final + case continuationFrame: + if c.readFinal { + return noFrame, c.handleProtocolError("continuation after final message frame") + } + c.readFinal = final + default: + return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) + } + + // 3. Read and parse frame length. + + switch c.readRemaining { + case 126: + p, err := c.read(2) + if err != nil { + return noFrame, err + } + c.readRemaining = int64(binary.BigEndian.Uint16(p)) + case 127: + p, err := c.read(8) + if err != nil { + return noFrame, err + } + c.readRemaining = int64(binary.BigEndian.Uint64(p)) + } + + // 4. Handle frame masking. + + if mask != c.isServer { + return noFrame, c.handleProtocolError("incorrect mask flag") + } + + if mask { + c.readMaskPos = 0 + p, err := c.read(len(c.readMaskKey)) + if err != nil { + return noFrame, err + } + copy(c.readMaskKey[:], p) + } + + // 5. For text and binary messages, enforce read limit and return. + + if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage { + + c.readLength += c.readRemaining + if c.readLimit > 0 && c.readLength > c.readLimit { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) + return noFrame, ErrReadLimit + } + + return frameType, nil + } + + // 6. Read control frame payload. + + var payload []byte + if c.readRemaining > 0 { + payload, err = c.read(int(c.readRemaining)) + c.readRemaining = 0 + if err != nil { + return noFrame, err + } + if c.isServer { + maskBytes(c.readMaskKey, 0, payload) + } + } + + // 7. Process control frame payload. + + switch frameType { + case PongMessage: + if err := c.handlePong(string(payload)); err != nil { + return noFrame, err + } + case PingMessage: + if err := c.handlePing(string(payload)); err != nil { + return noFrame, err + } + case CloseMessage: + closeCode := CloseNoStatusReceived + closeText := "" + if len(payload) >= 2 { + closeCode = int(binary.BigEndian.Uint16(payload)) + if !isValidReceivedCloseCode(closeCode) { + return noFrame, c.handleProtocolError("invalid close code") + } + closeText = string(payload[2:]) + if !utf8.ValidString(closeText) { + return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") + } + } + if err := c.handleClose(closeCode, closeText); err != nil { + return noFrame, err + } + return noFrame, &CloseError{Code: closeCode, Text: closeText} + } + + return frameType, nil +} + +func (c *Conn) handleProtocolError(message string) error { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) + return errors.New("websocket: " + message) +} + +// NextReader returns the next data message received from the peer. The +// returned messageType is either TextMessage or BinaryMessage. +// +// There can be at most one open reader on a connection. NextReader discards +// the previous message if the application has not already consumed it. +// +// Applications must break out of the application's read loop when this method +// returns a non-nil error value. Errors returned from this method are +// permanent. Once this method returns a non-nil error, all subsequent calls to +// this method return the same error. +func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { + // Close previous reader, only relevant for decompression. + if c.reader != nil { + c.reader.Close() + c.reader = nil + } + + c.messageReader = nil + c.readLength = 0 + + for c.readErr == nil { + frameType, err := c.advanceFrame() + if err != nil { + c.readErr = hideTempErr(err) + break + } + if frameType == TextMessage || frameType == BinaryMessage { + c.messageReader = &messageReader{c} + c.reader = c.messageReader + if c.readDecompress { + c.reader = c.newDecompressionReader(c.reader) + } + return frameType, c.reader, nil + } + } + + // Applications that do handle the error returned from this method spin in + // tight loop on connection failure. To help application developers detect + // this error, panic on repeated reads to the failed connection. + c.readErrCount++ + if c.readErrCount >= 1000 { + panic("repeated read on failed websocket connection") + } + + return noFrame, nil, c.readErr +} + +type messageReader struct{ c *Conn } + +func (r *messageReader) Read(b []byte) (int, error) { + c := r.c + if c.messageReader != r { + return 0, io.EOF + } + + for c.readErr == nil { + + if c.readRemaining > 0 { + if int64(len(b)) > c.readRemaining { + b = b[:c.readRemaining] + } + n, err := c.br.Read(b) + c.readErr = hideTempErr(err) + if c.isServer { + c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) + } + c.readRemaining -= int64(n) + if c.readRemaining > 0 && c.readErr == io.EOF { + c.readErr = errUnexpectedEOF + } + return n, c.readErr + } + + if c.readFinal { + c.messageReader = nil + return 0, io.EOF + } + + frameType, err := c.advanceFrame() + switch { + case err != nil: + c.readErr = hideTempErr(err) + case frameType == TextMessage || frameType == BinaryMessage: + c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") + } + } + + err := c.readErr + if err == io.EOF && c.messageReader == r { + err = errUnexpectedEOF + } + return 0, err +} + +func (r *messageReader) Close() error { + return nil +} + +// ReadMessage is a helper method for getting a reader using NextReader and +// reading from that reader to a buffer. +func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { + var r io.Reader + messageType, r, err = c.NextReader() + if err != nil { + return messageType, nil, err + } + p, err = ioutil.ReadAll(r) + return messageType, p, err +} + +// SetReadDeadline sets the read deadline on the underlying network connection. +// After a read has timed out, the websocket connection state is corrupt and +// all future reads will return an error. A zero value for t means reads will +// not time out. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +// SetReadLimit sets the maximum size for a message read from the peer. If a +// message exceeds the limit, the connection sends a close message to the peer +// and returns ErrReadLimit to the application. +func (c *Conn) SetReadLimit(limit int64) { + c.readLimit = limit +} + +// CloseHandler returns the current close handler +func (c *Conn) CloseHandler() func(code int, text string) error { + return c.handleClose +} + +// SetCloseHandler sets the handler for close messages received from the peer. +// The code argument to h is the received close code or CloseNoStatusReceived +// if the close message is empty. The default close handler sends a close +// message back to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// close messages as described in the section on Control Messages above. +// +// The connection read methods return a CloseError when a close message is +// received. Most applications should handle close messages as part of their +// normal error handling. Applications should only set a close handler when the +// application must perform some action before sending a close message back to +// the peer. +func (c *Conn) SetCloseHandler(h func(code int, text string) error) { + if h == nil { + h = func(code int, text string) error { + message := FormatCloseMessage(code, "") + c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) + return nil + } + } + c.handleClose = h +} + +// PingHandler returns the current ping handler +func (c *Conn) PingHandler() func(appData string) error { + return c.handlePing +} + +// SetPingHandler sets the handler for ping messages received from the peer. +// The appData argument to h is the PING message application data. The default +// ping handler sends a pong to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// ping messages as described in the section on Control Messages above. +func (c *Conn) SetPingHandler(h func(appData string) error) { + if h == nil { + h = func(message string) error { + err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) + if err == ErrCloseSent { + return nil + } else if e, ok := err.(net.Error); ok && e.Temporary() { + return nil + } + return err + } + } + c.handlePing = h +} + +// PongHandler returns the current pong handler +func (c *Conn) PongHandler() func(appData string) error { + return c.handlePong +} + +// SetPongHandler sets the handler for pong messages received from the peer. +// The appData argument to h is the PONG message application data. The default +// pong handler does nothing. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// pong messages as described in the section on Control Messages above. +func (c *Conn) SetPongHandler(h func(appData string) error) { + if h == nil { + h = func(string) error { return nil } + } + c.handlePong = h +} + +// UnderlyingConn returns the internal net.Conn. This can be used to further +// modifications to connection specific flags. +func (c *Conn) UnderlyingConn() net.Conn { + return c.conn +} + +// EnableWriteCompression enables and disables write compression of +// subsequent text and binary messages. This function is a noop if +// compression was not negotiated with the peer. +func (c *Conn) EnableWriteCompression(enable bool) { + c.enableWriteCompression = enable +} + +// SetCompressionLevel sets the flate compression level for subsequent text and +// binary messages. This function is a noop if compression was not negotiated +// with the peer. See the compress/flate package for a description of +// compression levels. +func (c *Conn) SetCompressionLevel(level int) error { + if !isValidCompressionLevel(level) { + return errors.New("websocket: invalid compression level") + } + c.compressionLevel = level + return nil +} + +// FormatCloseMessage formats closeCode and text as a WebSocket close message. +// An empty message is returned for code CloseNoStatusReceived. +func FormatCloseMessage(closeCode int, text string) []byte { + if closeCode == CloseNoStatusReceived { + // Return empty message because it's illegal to send + // CloseNoStatusReceived. Return non-nil value in case application + // checks for nil. + return []byte{} + } + buf := make([]byte, 2+len(text)) + binary.BigEndian.PutUint16(buf, uint16(closeCode)) + copy(buf[2:], text) + return buf +} diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go new file mode 100644 index 00000000..a509a21f --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package websocket + +import "net" + +func (c *Conn) writeBufs(bufs ...[]byte) error { + b := net.Buffers(bufs) + _, err := b.WriteTo(c.conn) + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go new file mode 100644 index 00000000..37edaff5 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go @@ -0,0 +1,18 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package websocket + +func (c *Conn) writeBufs(bufs ...[]byte) error { + for _, buf := range bufs { + if len(buf) > 0 { + if _, err := c.conn.Write(buf); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go new file mode 100644 index 00000000..dcce1a63 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -0,0 +1,180 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package websocket implements the WebSocket protocol defined in RFC 6455. +// +// Overview +// +// The Conn type represents a WebSocket connection. A server application calls +// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: +// +// var upgrader = websocket.Upgrader{ +// ReadBufferSize: 1024, +// WriteBufferSize: 1024, +// } +// +// func handler(w http.ResponseWriter, r *http.Request) { +// conn, err := upgrader.Upgrade(w, r, nil) +// if err != nil { +// log.Println(err) +// return +// } +// ... Use conn to send and receive messages. +// } +// +// Call the connection's WriteMessage and ReadMessage methods to send and +// receive messages as a slice of bytes. This snippet of code shows how to echo +// messages using these methods: +// +// for { +// messageType, p, err := conn.ReadMessage() +// if err != nil { +// log.Println(err) +// return +// } +// if err := conn.WriteMessage(messageType, p); err != nil { +// log.Println(err) +// return +// } +// } +// +// In above snippet of code, p is a []byte and messageType is an int with value +// websocket.BinaryMessage or websocket.TextMessage. +// +// An application can also send and receive messages using the io.WriteCloser +// and io.Reader interfaces. To send a message, call the connection NextWriter +// method to get an io.WriteCloser, write the message to the writer and close +// the writer when done. To receive a message, call the connection NextReader +// method to get an io.Reader and read until io.EOF is returned. This snippet +// shows how to echo messages using the NextWriter and NextReader methods: +// +// for { +// messageType, r, err := conn.NextReader() +// if err != nil { +// return +// } +// w, err := conn.NextWriter(messageType) +// if err != nil { +// return err +// } +// if _, err := io.Copy(w, r); err != nil { +// return err +// } +// if err := w.Close(); err != nil { +// return err +// } +// } +// +// Data Messages +// +// The WebSocket protocol distinguishes between text and binary data messages. +// Text messages are interpreted as UTF-8 encoded text. The interpretation of +// binary messages is left to the application. +// +// This package uses the TextMessage and BinaryMessage integer constants to +// identify the two data message types. The ReadMessage and NextReader methods +// return the type of the received message. The messageType argument to the +// WriteMessage and NextWriter methods specifies the type of a sent message. +// +// It is the application's responsibility to ensure that text messages are +// valid UTF-8 encoded text. +// +// Control Messages +// +// The WebSocket protocol defines three types of control messages: close, ping +// and pong. Call the connection WriteControl, WriteMessage or NextWriter +// methods to send a control message to the peer. +// +// Connections handle received close messages by calling the handler function +// set with the SetCloseHandler method and by returning a *CloseError from the +// NextReader, ReadMessage or the message Read method. The default close +// handler sends a close message to the peer. +// +// Connections handle received ping messages by calling the handler function +// set with the SetPingHandler method. The default ping handler sends a pong +// message to the peer. +// +// Connections handle received pong messages by calling the handler function +// set with the SetPongHandler method. The default pong handler does nothing. +// If an application sends ping messages, then the application should set a +// pong handler to receive the corresponding pong. +// +// The control message handler functions are called from the NextReader, +// ReadMessage and message reader Read methods. The default close and ping +// handlers can block these methods for a short time when the handler writes to +// the connection. +// +// The application must read the connection to process close, ping and pong +// messages sent from the peer. If the application is not otherwise interested +// in messages from the peer, then the application should start a goroutine to +// read and discard messages from the peer. A simple example is: +// +// func readLoop(c *websocket.Conn) { +// for { +// if _, _, err := c.NextReader(); err != nil { +// c.Close() +// break +// } +// } +// } +// +// Concurrency +// +// Connections support one concurrent reader and one concurrent writer. +// +// Applications are responsible for ensuring that no more than one goroutine +// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, +// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and +// that no more than one goroutine calls the read methods (NextReader, +// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) +// concurrently. +// +// The Close and WriteControl methods can be called concurrently with all other +// methods. +// +// Origin Considerations +// +// Web browsers allow Javascript applications to open a WebSocket connection to +// any host. It's up to the server to enforce an origin policy using the Origin +// request header sent by the browser. +// +// The Upgrader calls the function specified in the CheckOrigin field to check +// the origin. If the CheckOrigin function returns false, then the Upgrade +// method fails the WebSocket handshake with HTTP status 403. +// +// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail +// the handshake if the Origin request header is present and the Origin host is +// not equal to the Host request header. +// +// The deprecated package-level Upgrade function does not perform origin +// checking. The application is responsible for checking the Origin header +// before calling the Upgrade function. +// +// Compression EXPERIMENTAL +// +// Per message compression extensions (RFC 7692) are experimentally supported +// by this package in a limited capacity. Setting the EnableCompression option +// to true in Dialer or Upgrader will attempt to negotiate per message deflate +// support. +// +// var upgrader = websocket.Upgrader{ +// EnableCompression: true, +// } +// +// If compression was successfully negotiated with the connection's peer, any +// message received in compressed form will be automatically decompressed. +// All Read methods will return uncompressed bytes. +// +// Per message compression of messages written to a connection can be enabled +// or disabled by calling the corresponding Conn method: +// +// conn.EnableWriteCompression(false) +// +// Currently this package does not support compression with "context takeover". +// This means that messages must be compressed and decompressed in isolation, +// without retaining sliding window or dictionary state across messages. For +// more details refer to RFC 7692. +// +// Use of compression is experimental and may result in decreased performance. +package websocket diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go new file mode 100644 index 00000000..dc2c1f64 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/json.go @@ -0,0 +1,60 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "encoding/json" + "io" +) + +// WriteJSON writes the JSON encoding of v as a message. +// +// Deprecated: Use c.WriteJSON instead. +func WriteJSON(c *Conn, v interface{}) error { + return c.WriteJSON(v) +} + +// WriteJSON writes the JSON encoding of v as a message. +// +// See the documentation for encoding/json Marshal for details about the +// conversion of Go values to JSON. +func (c *Conn) WriteJSON(v interface{}) error { + w, err := c.NextWriter(TextMessage) + if err != nil { + return err + } + err1 := json.NewEncoder(w).Encode(v) + err2 := w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// Deprecated: Use c.ReadJSON instead. +func ReadJSON(c *Conn, v interface{}) error { + return c.ReadJSON(v) +} + +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// See the documentation for the encoding/json Unmarshal function for details +// about the conversion of JSON to a Go value. +func (c *Conn) ReadJSON(v interface{}) error { + _, r, err := c.NextReader() + if err != nil { + return err + } + err = json.NewDecoder(r).Decode(v) + if err == io.EOF { + // One value is expected in the message. + err = io.ErrUnexpectedEOF + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go new file mode 100644 index 00000000..577fce9e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +// +build !appengine + +package websocket + +import "unsafe" + +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +func maskBytes(key [4]byte, pos int, b []byte) int { + // Mask one byte at a time for small buffers. + if len(b) < 2*wordSize { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 + } + + // Mask one byte at a time to word boundary. + if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { + n = wordSize - n + for i := range b[:n] { + b[i] ^= key[pos&3] + pos++ + } + b = b[n:] + } + + // Create aligned word size key. + var k [wordSize]byte + for i := range k { + k[i] = key[(pos+i)&3] + } + kw := *(*uintptr)(unsafe.Pointer(&k)) + + // Mask one word at a time. + n := (len(b) / wordSize) * wordSize + for i := 0; i < n; i += wordSize { + *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw + } + + // Mask one byte at a time for remaining bytes. + b = b[n:] + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go new file mode 100644 index 00000000..2aac060e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask_safe.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +// +build appengine + +package websocket + +func maskBytes(key [4]byte, pos int, b []byte) int { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go new file mode 100644 index 00000000..74ec565d --- /dev/null +++ b/vendor/github.com/gorilla/websocket/prepared.go @@ -0,0 +1,102 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "net" + "sync" + "time" +) + +// PreparedMessage caches on the wire representations of a message payload. +// Use PreparedMessage to efficiently send a message payload to multiple +// connections. PreparedMessage is especially useful when compression is used +// because the CPU and memory expensive compression operation can be executed +// once for a given set of compression options. +type PreparedMessage struct { + messageType int + data []byte + mu sync.Mutex + frames map[prepareKey]*preparedFrame +} + +// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. +type prepareKey struct { + isServer bool + compress bool + compressionLevel int +} + +// preparedFrame contains data in wire representation. +type preparedFrame struct { + once sync.Once + data []byte +} + +// NewPreparedMessage returns an initialized PreparedMessage. You can then send +// it to connection using WritePreparedMessage method. Valid wire +// representation will be calculated lazily only once for a set of current +// connection options. +func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { + pm := &PreparedMessage{ + messageType: messageType, + frames: make(map[prepareKey]*preparedFrame), + data: data, + } + + // Prepare a plain server frame. + _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) + if err != nil { + return nil, err + } + + // To protect against caller modifying the data argument, remember the data + // copied to the plain server frame. + pm.data = frameData[len(frameData)-len(data):] + return pm, nil +} + +func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { + pm.mu.Lock() + frame, ok := pm.frames[key] + if !ok { + frame = &preparedFrame{} + pm.frames[key] = frame + } + pm.mu.Unlock() + + var err error + frame.once.Do(func() { + // Prepare a frame using a 'fake' connection. + // TODO: Refactor code in conn.go to allow more direct construction of + // the frame. + mu := make(chan bool, 1) + mu <- true + var nc prepareConn + c := &Conn{ + conn: &nc, + mu: mu, + isServer: key.isServer, + compressionLevel: key.compressionLevel, + enableWriteCompression: true, + writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), + } + if key.compress { + c.newCompressionWriter = compressNoContextTakeover + } + err = c.WriteMessage(pm.messageType, pm.data) + frame.data = nc.buf.Bytes() + }) + return pm.messageType, frame.data, err +} + +type prepareConn struct { + buf bytes.Buffer + net.Conn +} + +func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } +func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go new file mode 100644 index 00000000..bf2478e4 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/proxy.go @@ -0,0 +1,77 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "encoding/base64" + "errors" + "net" + "net/http" + "net/url" + "strings" +) + +type netDialerFunc func(network, addr string) (net.Conn, error) + +func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { + return fn(network, addr) +} + +func init() { + proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { + return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil + }) +} + +type httpProxyDialer struct { + proxyURL *url.URL + fowardDial func(network, addr string) (net.Conn, error) +} + +func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { + hostPort, _ := hostPortNoPort(hpd.proxyURL) + conn, err := hpd.fowardDial(network, hostPort) + if err != nil { + return nil, err + } + + connectHeader := make(http.Header) + if user := hpd.proxyURL.User; user != nil { + proxyUser := user.Username() + if proxyPassword, passwordSet := user.Password(); passwordSet { + credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) + connectHeader.Set("Proxy-Authorization", "Basic "+credential) + } + } + + connectReq := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: addr}, + Host: addr, + Header: connectHeader, + } + + if err := connectReq.Write(conn); err != nil { + conn.Close() + return nil, err + } + + // Read response. It's OK to use and discard buffered reader here becaue + // the remote server does not speak until spoken to. + br := bufio.NewReader(conn) + resp, err := http.ReadResponse(br, connectReq) + if err != nil { + conn.Close() + return nil, err + } + + if resp.StatusCode != 200 { + conn.Close() + f := strings.SplitN(resp.Status, " ", 2) + return nil, errors.New(f[1]) + } + return conn, nil +} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go new file mode 100644 index 00000000..a761824b --- /dev/null +++ b/vendor/github.com/gorilla/websocket/server.go @@ -0,0 +1,363 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "errors" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +// HandshakeError describes an error with the handshake from the peer. +type HandshakeError struct { + message string +} + +func (e HandshakeError) Error() string { return e.message } + +// Upgrader specifies parameters for upgrading an HTTP connection to a +// WebSocket connection. +type Upgrader struct { + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer + // size is zero, then buffers allocated by the HTTP server are used. The + // I/O buffer sizes do not limit the size of the messages that can be sent + // or received. + ReadBufferSize, WriteBufferSize int + + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + + // Subprotocols specifies the server's supported protocols in order of + // preference. If this field is not nil, then the Upgrade method negotiates a + // subprotocol by selecting the first match in this list with a protocol + // requested by the client. If there's no match, then no protocol is + // negotiated (the Sec-Websocket-Protocol header is not included in the + // handshake response). + Subprotocols []string + + // Error specifies the function for generating HTTP error responses. If Error + // is nil, then http.Error is used to generate the HTTP response. + Error func(w http.ResponseWriter, r *http.Request, status int, reason error) + + // CheckOrigin returns true if the request Origin header is acceptable. If + // CheckOrigin is nil, then a safe default is used: return false if the + // Origin request header is present and the origin host is not equal to + // request Host header. + // + // A CheckOrigin function should carefully validate the request origin to + // prevent cross-site request forgery. + CheckOrigin func(r *http.Request) bool + + // EnableCompression specify if the server should attempt to negotiate per + // message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool +} + +func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { + err := HandshakeError{reason} + if u.Error != nil { + u.Error(w, r, status, err) + } else { + w.Header().Set("Sec-Websocket-Version", "13") + http.Error(w, http.StatusText(status), status) + } + return nil, err +} + +// checkSameOrigin returns true if the origin is not set or is equal to the request host. +func checkSameOrigin(r *http.Request) bool { + origin := r.Header["Origin"] + if len(origin) == 0 { + return true + } + u, err := url.Parse(origin[0]) + if err != nil { + return false + } + return equalASCIIFold(u.Host, r.Host) +} + +func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { + if u.Subprotocols != nil { + clientProtocols := Subprotocols(r) + for _, serverProtocol := range u.Subprotocols { + for _, clientProtocol := range clientProtocols { + if clientProtocol == serverProtocol { + return clientProtocol + } + } + } + } else if responseHeader != nil { + return responseHeader.Get("Sec-Websocket-Protocol") + } + return "" +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// application negotiated subprotocol (Sec-WebSocket-Protocol). +// +// If the upgrade fails, then Upgrade replies to the client with an HTTP error +// response. +func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { + const badHandshake = "websocket: the client is not using the websocket protocol: " + + if !tokenListContainsValue(r.Header, "Connection", "upgrade") { + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") + } + + if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") + } + + if r.Method != "GET" { + return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") + } + + if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") + } + + if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") + } + + checkOrigin := u.CheckOrigin + if checkOrigin == nil { + checkOrigin = checkSameOrigin + } + if !checkOrigin(r) { + return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") + } + + challengeKey := r.Header.Get("Sec-Websocket-Key") + if challengeKey == "" { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank") + } + + subprotocol := u.selectSubprotocol(r, responseHeader) + + // Negotiate PMCE + var compress bool + if u.EnableCompression { + for _, ext := range parseExtensions(r.Header) { + if ext[""] != "permessage-deflate" { + continue + } + compress = true + break + } + } + + h, ok := w.(http.Hijacker) + if !ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") + } + var brw *bufio.ReadWriter + netConn, brw, err := h.Hijack() + if err != nil { + return u.returnError(w, r, http.StatusInternalServerError, err.Error()) + } + + if brw.Reader.Buffered() > 0 { + netConn.Close() + return nil, errors.New("websocket: client sent data before handshake is complete") + } + + var br *bufio.Reader + if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { + // Reuse hijacked buffered reader as connection reader. + br = brw.Reader + } + + buf := bufioWriterBuffer(netConn, brw.Writer) + + var writeBuf []byte + if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { + // Reuse hijacked write buffer as connection buffer. + writeBuf = buf + } + + c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf) + c.subprotocol = subprotocol + + if compress { + c.newCompressionWriter = compressNoContextTakeover + c.newDecompressionReader = decompressNoContextTakeover + } + + // Use larger of hijacked buffer and connection write buffer for header. + p := buf + if len(c.writeBuf) > len(p) { + p = c.writeBuf + } + p = p[:0] + + p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) + p = append(p, computeAcceptKey(challengeKey)...) + p = append(p, "\r\n"...) + if c.subprotocol != "" { + p = append(p, "Sec-WebSocket-Protocol: "...) + p = append(p, c.subprotocol...) + p = append(p, "\r\n"...) + } + if compress { + p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) + } + for k, vs := range responseHeader { + if k == "Sec-Websocket-Protocol" { + continue + } + for _, v := range vs { + p = append(p, k...) + p = append(p, ": "...) + for i := 0; i < len(v); i++ { + b := v[i] + if b <= 31 { + // prevent response splitting. + b = ' ' + } + p = append(p, b) + } + p = append(p, "\r\n"...) + } + } + p = append(p, "\r\n"...) + + // Clear deadlines set by HTTP server. + netConn.SetDeadline(time.Time{}) + + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) + } + if _, err = netConn.Write(p); err != nil { + netConn.Close() + return nil, err + } + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Time{}) + } + + return c, nil +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// Deprecated: Use websocket.Upgrader instead. +// +// Upgrade does not perform origin checking. The application is responsible for +// checking the Origin header before calling Upgrade. An example implementation +// of the same origin policy check is: +// +// if req.Header.Get("Origin") != "http://"+req.Host { +// http.Error(w, "Origin not allowed", http.StatusForbidden) +// return +// } +// +// If the endpoint supports subprotocols, then the application is responsible +// for negotiating the protocol used on the connection. Use the Subprotocols() +// function to get the subprotocols requested by the client. Use the +// Sec-Websocket-Protocol response header to specify the subprotocol selected +// by the application. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// negotiated subprotocol (Sec-Websocket-Protocol). +// +// The connection buffers IO to the underlying network connection. The +// readBufSize and writeBufSize parameters specify the size of the buffers to +// use. Messages can be larger than the buffers. +// +// If the request is not a valid WebSocket handshake, then Upgrade returns an +// error of type HandshakeError. Applications should handle this error by +// replying to the client with an HTTP error response. +func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) { + u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize} + u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { + // don't return errors to maintain backwards compatibility + } + u.CheckOrigin = func(r *http.Request) bool { + // allow all connections by default + return true + } + return u.Upgrade(w, r, responseHeader) +} + +// Subprotocols returns the subprotocols requested by the client in the +// Sec-Websocket-Protocol header. +func Subprotocols(r *http.Request) []string { + h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol")) + if h == "" { + return nil + } + protocols := strings.Split(h, ",") + for i := range protocols { + protocols[i] = strings.TrimSpace(protocols[i]) + } + return protocols +} + +// IsWebSocketUpgrade returns true if the client requested upgrade to the +// WebSocket protocol. +func IsWebSocketUpgrade(r *http.Request) bool { + return tokenListContainsValue(r.Header, "Connection", "upgrade") && + tokenListContainsValue(r.Header, "Upgrade", "websocket") +} + +// bufioReaderSize size returns the size of a bufio.Reader. +func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { + // This code assumes that peek on a reset reader returns + // bufio.Reader.buf[:0]. + // TODO: Use bufio.Reader.Size() after Go 1.10 + br.Reset(originalReader) + if p, err := br.Peek(0); err == nil { + return cap(p) + } + return 0 +} + +// writeHook is an io.Writer that records the last slice passed to it vio +// io.Writer.Write. +type writeHook struct { + p []byte +} + +func (wh *writeHook) Write(p []byte) (int, error) { + wh.p = p + return len(p), nil +} + +// bufioWriterBuffer grabs the buffer from a bufio.Writer. +func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { + // This code assumes that bufio.Writer.buf[:1] is passed to the + // bufio.Writer's underlying writer. + var wh writeHook + bw.Reset(&wh) + bw.WriteByte(0) + bw.Flush() + + bw.Reset(originalWriter) + + return wh.p[:cap(wh.p)] +} diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go new file mode 100644 index 00000000..834f122a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace.go @@ -0,0 +1,19 @@ +// +build go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + if trace.TLSHandshakeStart != nil { + trace.TLSHandshakeStart() + } + err := doHandshake(tlsConn, cfg) + if trace.TLSHandshakeDone != nil { + trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go new file mode 100644 index 00000000..77d05a0b --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace_17.go @@ -0,0 +1,12 @@ +// +build !go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + return doHandshake(tlsConn, cfg) +} diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go new file mode 100644 index 00000000..354001e1 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/util.go @@ -0,0 +1,237 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "io" + "net/http" + "strings" + "unicode/utf8" +) + +var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") + +func computeAcceptKey(challengeKey string) string { + h := sha1.New() + h.Write([]byte(challengeKey)) + h.Write(keyGUID) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func generateChallengeKey() (string, error) { + p := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, p); err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(p), nil +} + +// Octet types from RFC 2616. +var octetTypes [256]byte + +const ( + isTokenOctet = 1 << iota + isSpaceOctet +) + +func init() { + // From RFC 2616 + // + // OCTET = + // CHAR = + // CTL = + // CR = + // LF = + // SP = + // HT = + // <"> = + // CRLF = CR LF + // LWS = [CRLF] 1*( SP | HT ) + // TEXT = + // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> + // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT + // token = 1* + // qdtext = > + + for c := 0; c < 256; c++ { + var t byte + isCtl := c <= 31 || c == 127 + isChar := 0 <= c && c <= 127 + isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0 + if strings.IndexRune(" \t\r\n", rune(c)) >= 0 { + t |= isSpaceOctet + } + if isChar && !isCtl && !isSeparator { + t |= isTokenOctet + } + octetTypes[c] = t + } +} + +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isSpaceOctet == 0 { + break + } + } + return s[i:] +} + +func nextToken(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isTokenOctet == 0 { + break + } + } + return s[:i], s[i:] +} + +func nextTokenOrQuoted(s string) (value string, rest string) { + if !strings.HasPrefix(s, "\"") { + return nextToken(s) + } + s = s[1:] + for i := 0; i < len(s); i++ { + switch s[i] { + case '"': + return s[:i], s[i+1:] + case '\\': + p := make([]byte, len(s)-1) + j := copy(p, s[:i]) + escape := true + for i = i + 1; i < len(s); i++ { + b := s[i] + switch { + case escape: + escape = false + p[j] = b + j++ + case b == '\\': + escape = true + case b == '"': + return string(p[:j]), s[i+1:] + default: + p[j] = b + j++ + } + } + return "", "" + } + } + return "", "" +} + +// equalASCIIFold returns true if s is equal to t with ASCII case folding. +func equalASCIIFold(s, t string) bool { + for s != "" && t != "" { + sr, size := utf8.DecodeRuneInString(s) + s = s[size:] + tr, size := utf8.DecodeRuneInString(t) + t = t[size:] + if sr == tr { + continue + } + if 'A' <= sr && sr <= 'Z' { + sr = sr + 'a' - 'A' + } + if 'A' <= tr && tr <= 'Z' { + tr = tr + 'a' - 'A' + } + if sr != tr { + return false + } + } + return s == t +} + +// tokenListContainsValue returns true if the 1#token header with the given +// name contains a token equal to value with ASCII case folding. +func tokenListContainsValue(header http.Header, name string, value string) bool { +headers: + for _, s := range header[name] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + s = skipSpace(s) + if s != "" && s[0] != ',' { + continue headers + } + if equalASCIIFold(t, value) { + return true + } + if s == "" { + continue headers + } + s = s[1:] + } + } + return false +} + +// parseExtensions parses WebSocket extensions from a header. +func parseExtensions(header http.Header) []map[string]string { + // From RFC 6455: + // + // Sec-WebSocket-Extensions = extension-list + // extension-list = 1#extension + // extension = extension-token *( ";" extension-param ) + // extension-token = registered-token + // registered-token = token + // extension-param = token [ "=" (token | quoted-string) ] + // ;When using the quoted-string syntax variant, the value + // ;after quoted-string unescaping MUST conform to the + // ;'token' ABNF. + + var result []map[string]string +headers: + for _, s := range header["Sec-Websocket-Extensions"] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + ext := map[string]string{"": t} + for { + s = skipSpace(s) + if !strings.HasPrefix(s, ";") { + break + } + var k string + k, s = nextToken(skipSpace(s[1:])) + if k == "" { + continue headers + } + s = skipSpace(s) + var v string + if strings.HasPrefix(s, "=") { + v, s = nextTokenOrQuoted(skipSpace(s[1:])) + s = skipSpace(s) + } + if s != "" && s[0] != ',' && s[0] != ';' { + continue headers + } + ext[k] = v + } + if s != "" && s[0] != ',' { + continue headers + } + result = append(result, ext) + if s == "" { + continue headers + } + s = s[1:] + } + } + return result +} diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go new file mode 100644 index 00000000..2e668f6b --- /dev/null +++ b/vendor/github.com/gorilla/websocket/x_net_proxy.go @@ -0,0 +1,473 @@ +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. +//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy + +// Package proxy provides support for a variety of protocols to proxy network +// data. +// + +package websocket + +import ( + "errors" + "io" + "net" + "net/url" + "os" + "strconv" + "strings" + "sync" +) + +type proxy_direct struct{} + +// Direct is a direct proxy: one that makes network connections directly. +var proxy_Direct = proxy_direct{} + +func (proxy_direct) Dial(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} + +// A PerHost directs connections to a default Dialer unless the host name +// requested matches one of a number of exceptions. +type proxy_PerHost struct { + def, bypass proxy_Dialer + + bypassNetworks []*net.IPNet + bypassIPs []net.IP + bypassZones []string + bypassHosts []string +} + +// NewPerHost returns a PerHost Dialer that directs connections to either +// defaultDialer or bypass, depending on whether the connection matches one of +// the configured rules. +func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { + return &proxy_PerHost{ + def: defaultDialer, + bypass: bypass, + } +} + +// Dial connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + return p.dialerForRequest(host).Dial(network, addr) +} + +func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { + if ip := net.ParseIP(host); ip != nil { + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass + } + } + for _, bypassIP := range p.bypassIPs { + if bypassIP.Equal(ip) { + return p.bypass + } + } + return p.def + } + + for _, zone := range p.bypassZones { + if strings.HasSuffix(host, zone) { + return p.bypass + } + if host == zone[1:] { + // For a zone ".example.com", we match "example.com" + // too. + return p.bypass + } + } + for _, bypassHost := range p.bypassHosts { + if bypassHost == host { + return p.bypass + } + } + return p.def +} + +// AddFromString parses a string that contains comma-separated values +// specifying hosts that should use the bypass proxy. Each value is either an +// IP address, a CIDR range, a zone (*.example.com) or a host name +// (localhost). A best effort is made to parse the string and errors are +// ignored. +func (p *proxy_PerHost) AddFromString(s string) { + hosts := strings.Split(s, ",") + for _, host := range hosts { + host = strings.TrimSpace(host) + if len(host) == 0 { + continue + } + if strings.Contains(host, "/") { + // We assume that it's a CIDR address like 127.0.0.0/8 + if _, net, err := net.ParseCIDR(host); err == nil { + p.AddNetwork(net) + } + continue + } + if ip := net.ParseIP(host); ip != nil { + p.AddIP(ip) + continue + } + if strings.HasPrefix(host, "*.") { + p.AddZone(host[1:]) + continue + } + p.AddHost(host) + } +} + +// AddIP specifies an IP address that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match an IP. +func (p *proxy_PerHost) AddIP(ip net.IP) { + p.bypassIPs = append(p.bypassIPs, ip) +} + +// AddNetwork specifies an IP range that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match. +func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { + p.bypassNetworks = append(p.bypassNetworks, net) +} + +// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of +// "example.com" matches "example.com" and all of its subdomains. +func (p *proxy_PerHost) AddZone(zone string) { + if strings.HasSuffix(zone, ".") { + zone = zone[:len(zone)-1] + } + if !strings.HasPrefix(zone, ".") { + zone = "." + zone + } + p.bypassZones = append(p.bypassZones, zone) +} + +// AddHost specifies a host name that will use the bypass proxy. +func (p *proxy_PerHost) AddHost(host string) { + if strings.HasSuffix(host, ".") { + host = host[:len(host)-1] + } + p.bypassHosts = append(p.bypassHosts, host) +} + +// A Dialer is a means to establish a connection. +type proxy_Dialer interface { + // Dial connects to the given address via the proxy. + Dial(network, addr string) (c net.Conn, err error) +} + +// Auth contains authentication parameters that specific Dialers may require. +type proxy_Auth struct { + User, Password string +} + +// FromEnvironment returns the dialer specified by the proxy related variables in +// the environment. +func proxy_FromEnvironment() proxy_Dialer { + allProxy := proxy_allProxyEnv.Get() + if len(allProxy) == 0 { + return proxy_Direct + } + + proxyURL, err := url.Parse(allProxy) + if err != nil { + return proxy_Direct + } + proxy, err := proxy_FromURL(proxyURL, proxy_Direct) + if err != nil { + return proxy_Direct + } + + noProxy := proxy_noProxyEnv.Get() + if len(noProxy) == 0 { + return proxy + } + + perHost := proxy_NewPerHost(proxy, proxy_Direct) + perHost.AddFromString(noProxy) + return perHost +} + +// proxySchemes is a map from URL schemes to a function that creates a Dialer +// from a URL with such a scheme. +var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) + +// RegisterDialerType takes a URL scheme and a function to generate Dialers from +// a URL with that scheme and a forwarding Dialer. Registered schemes are used +// by FromURL. +func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { + if proxy_proxySchemes == nil { + proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) + } + proxy_proxySchemes[scheme] = f +} + +// FromURL returns a Dialer given a URL specification and an underlying +// Dialer for it to make network requests. +func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { + var auth *proxy_Auth + if u.User != nil { + auth = new(proxy_Auth) + auth.User = u.User.Username() + if p, ok := u.User.Password(); ok { + auth.Password = p + } + } + + switch u.Scheme { + case "socks5": + return proxy_SOCKS5("tcp", u.Host, auth, forward) + } + + // If the scheme doesn't match any of the built-in schemes, see if it + // was registered by another package. + if proxy_proxySchemes != nil { + if f, ok := proxy_proxySchemes[u.Scheme]; ok { + return f(u, forward) + } + } + + return nil, errors.New("proxy: unknown scheme: " + u.Scheme) +} + +var ( + proxy_allProxyEnv = &proxy_envOnce{ + names: []string{"ALL_PROXY", "all_proxy"}, + } + proxy_noProxyEnv = &proxy_envOnce{ + names: []string{"NO_PROXY", "no_proxy"}, + } +) + +// envOnce looks up an environment variable (optionally by multiple +// names) once. It mitigates expensive lookups on some platforms +// (e.g. Windows). +// (Borrowed from net/http/transport.go) +type proxy_envOnce struct { + names []string + once sync.Once + val string +} + +func (e *proxy_envOnce) Get() string { + e.once.Do(e.init) + return e.val +} + +func (e *proxy_envOnce) init() { + for _, n := range e.names { + e.val = os.Getenv(n) + if e.val != "" { + return + } + } +} + +// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address +// with an optional username and password. See RFC 1928 and RFC 1929. +func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { + s := &proxy_socks5{ + network: network, + addr: addr, + forward: forward, + } + if auth != nil { + s.user = auth.User + s.password = auth.Password + } + + return s, nil +} + +type proxy_socks5 struct { + user, password string + network, addr string + forward proxy_Dialer +} + +const proxy_socks5Version = 5 + +const ( + proxy_socks5AuthNone = 0 + proxy_socks5AuthPassword = 2 +) + +const proxy_socks5Connect = 1 + +const ( + proxy_socks5IP4 = 1 + proxy_socks5Domain = 3 + proxy_socks5IP6 = 4 +) + +var proxy_socks5Errors = []string{ + "", + "general failure", + "connection forbidden", + "network unreachable", + "host unreachable", + "connection refused", + "TTL expired", + "command not supported", + "address type not supported", +} + +// Dial connects to the address addr on the given network via the SOCKS5 proxy. +func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { + switch network { + case "tcp", "tcp6", "tcp4": + default: + return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) + } + + conn, err := s.forward.Dial(s.network, s.addr) + if err != nil { + return nil, err + } + if err := s.connect(conn, addr); err != nil { + conn.Close() + return nil, err + } + return conn, nil +} + +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *proxy_socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) + if err != nil { + return err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return errors.New("proxy: failed to parse port number: " + portStr) + } + if port < 1 || port > 0xffff { + return errors.New("proxy: port number out of range: " + portStr) + } + + // the size here is just an estimate + buf := make([]byte, 0, 6+len(host)) + + buf = append(buf, proxy_socks5Version) + if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { + buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) + } else { + buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) + } + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + if buf[0] != 5 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + } + if buf[1] == 0xff { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + } + + // See RFC 1929 + if buf[1] == proxy_socks5AuthPassword { + buf = buf[:0] + buf = append(buf, 1 /* password protocol version */) + buf = append(buf, uint8(len(s.user))) + buf = append(buf, s.user...) + buf = append(buf, uint8(len(s.password))) + buf = append(buf, s.password...) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if buf[1] != 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + } + } + + buf = buf[:0] + buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) + + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + buf = append(buf, proxy_socks5IP4) + ip = ip4 + } else { + buf = append(buf, proxy_socks5IP6) + } + buf = append(buf, ip...) + } else { + if len(host) > 255 { + return errors.New("proxy: destination host name too long: " + host) + } + buf = append(buf, proxy_socks5Domain) + buf = append(buf, byte(len(host))) + buf = append(buf, host...) + } + buf = append(buf, byte(port>>8), byte(port)) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:4]); err != nil { + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + failure := "unknown error" + if int(buf[1]) < len(proxy_socks5Errors) { + failure = proxy_socks5Errors[buf[1]] + } + + if len(failure) > 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + } + + bytesToDiscard := 0 + switch buf[3] { + case proxy_socks5IP4: + bytesToDiscard = net.IPv4len + case proxy_socks5IP6: + bytesToDiscard = net.IPv6len + case proxy_socks5Domain: + _, err := io.ReadFull(conn, buf[:1]) + if err != nil { + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + bytesToDiscard = int(buf[0]) + default: + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + } + + if cap(buf) < bytesToDiscard { + buf = make([]byte, bytesToDiscard) + } else { + buf = buf[:bytesToDiscard] + } + if _, err := io.ReadFull(conn, buf); err != nil { + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + // Also need to discard the port number + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/errwrap/LICENSE b/vendor/github.com/hashicorp/errwrap/LICENSE new file mode 100644 index 00000000..c33dcc7c --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/LICENSE @@ -0,0 +1,354 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hashicorp/errwrap/README.md b/vendor/github.com/hashicorp/errwrap/README.md new file mode 100644 index 00000000..444df08f --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/README.md @@ -0,0 +1,89 @@ +# errwrap + +`errwrap` is a package for Go that formalizes the pattern of wrapping errors +and checking if an error contains another error. + +There is a common pattern in Go of taking a returned `error` value and +then wrapping it (such as with `fmt.Errorf`) before returning it. The problem +with this pattern is that you completely lose the original `error` structure. + +Arguably the _correct_ approach is that you should make a custom structure +implementing the `error` interface, and have the original error as a field +on that structure, such [as this example](http://golang.org/pkg/os/#PathError). +This is a good approach, but you have to know the entire chain of possible +rewrapping that happens, when you might just care about one. + +`errwrap` formalizes this pattern (it doesn't matter what approach you use +above) by giving a single interface for wrapping errors, checking if a specific +error is wrapped, and extracting that error. + +## Installation and Docs + +Install using `go get github.com/hashicorp/errwrap`. + +Full documentation is available at +http://godoc.org/github.com/hashicorp/errwrap + +## Usage + +#### Basic Usage + +Below is a very basic example of its usage: + +```go +// A function that always returns an error, but wraps it, like a real +// function might. +func tryOpen() error { + _, err := os.Open("/i/dont/exist") + if err != nil { + return errwrap.Wrapf("Doesn't exist: {{err}}", err) + } + + return nil +} + +func main() { + err := tryOpen() + + // We can use the Contains helpers to check if an error contains + // another error. It is safe to do this with a nil error, or with + // an error that doesn't even use the errwrap package. + if errwrap.Contains(err, "does not exist") { + // Do something + } + if errwrap.ContainsType(err, new(os.PathError)) { + // Do something + } + + // Or we can use the associated `Get` functions to just extract + // a specific error. This would return nil if that specific error doesn't + // exist. + perr := errwrap.GetType(err, new(os.PathError)) +} +``` + +#### Custom Types + +If you're already making custom types that properly wrap errors, then +you can get all the functionality of `errwraps.Contains` and such by +implementing the `Wrapper` interface with just one function. Example: + +```go +type AppError { + Code ErrorCode + Err error +} + +func (e *AppError) WrappedErrors() []error { + return []error{e.Err} +} +``` + +Now this works: + +```go +err := &AppError{Err: fmt.Errorf("an error")} +if errwrap.ContainsType(err, fmt.Errorf("")) { + // This will work! +} +``` diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go new file mode 100644 index 00000000..a733bef1 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/errwrap.go @@ -0,0 +1,169 @@ +// Package errwrap implements methods to formalize error wrapping in Go. +// +// All of the top-level functions that take an `error` are built to be able +// to take any error, not just wrapped errors. This allows you to use errwrap +// without having to type-check and type-cast everywhere. +package errwrap + +import ( + "errors" + "reflect" + "strings" +) + +// WalkFunc is the callback called for Walk. +type WalkFunc func(error) + +// Wrapper is an interface that can be implemented by custom types to +// have all the Contains, Get, etc. functions in errwrap work. +// +// When Walk reaches a Wrapper, it will call the callback for every +// wrapped error in addition to the wrapper itself. Since all the top-level +// functions in errwrap use Walk, this means that all those functions work +// with your custom type. +type Wrapper interface { + WrappedErrors() []error +} + +// Wrap defines that outer wraps inner, returning an error type that +// can be cleanly used with the other methods in this package, such as +// Contains, GetAll, etc. +// +// This function won't modify the error message at all (the outer message +// will be used). +func Wrap(outer, inner error) error { + return &wrappedError{ + Outer: outer, + Inner: inner, + } +} + +// Wrapf wraps an error with a formatting message. This is similar to using +// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap +// errors, you should replace it with this. +// +// format is the format of the error message. The string '{{err}}' will +// be replaced with the original error message. +func Wrapf(format string, err error) error { + outerMsg := "" + if err != nil { + outerMsg = err.Error() + } + + outer := errors.New(strings.Replace( + format, "{{err}}", outerMsg, -1)) + + return Wrap(outer, err) +} + +// Contains checks if the given error contains an error with the +// message msg. If err is not a wrapped error, this will always return +// false unless the error itself happens to match this msg. +func Contains(err error, msg string) bool { + return len(GetAll(err, msg)) > 0 +} + +// ContainsType checks if the given error contains an error with +// the same concrete type as v. If err is not a wrapped error, this will +// check the err itself. +func ContainsType(err error, v interface{}) bool { + return len(GetAllType(err, v)) > 0 +} + +// Get is the same as GetAll but returns the deepest matching error. +func Get(err error, msg string) error { + es := GetAll(err, msg) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetType is the same as GetAllType but returns the deepest matching error. +func GetType(err error, v interface{}) error { + es := GetAllType(err, v) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetAll gets all the errors that might be wrapped in err with the +// given message. The order of the errors is such that the outermost +// matching error (the most recent wrap) is index zero, and so on. +func GetAll(err error, msg string) []error { + var result []error + + Walk(err, func(err error) { + if err.Error() == msg { + result = append(result, err) + } + }) + + return result +} + +// GetAllType gets all the errors that are the same type as v. +// +// The order of the return value is the same as described in GetAll. +func GetAllType(err error, v interface{}) []error { + var result []error + + var search string + if v != nil { + search = reflect.TypeOf(v).String() + } + Walk(err, func(err error) { + var needle string + if err != nil { + needle = reflect.TypeOf(err).String() + } + + if needle == search { + result = append(result, err) + } + }) + + return result +} + +// Walk walks all the wrapped errors in err and calls the callback. If +// err isn't a wrapped error, this will be called once for err. If err +// is a wrapped error, the callback will be called for both the wrapper +// that implements error as well as the wrapped error itself. +func Walk(err error, cb WalkFunc) { + if err == nil { + return + } + + switch e := err.(type) { + case *wrappedError: + cb(e.Outer) + Walk(e.Inner, cb) + case Wrapper: + cb(err) + + for _, err := range e.WrappedErrors() { + Walk(err, cb) + } + default: + cb(err) + } +} + +// wrappedError is an implementation of error that has both the +// outer and inner errors. +type wrappedError struct { + Outer error + Inner error +} + +func (w *wrappedError) Error() string { + return w.Outer.Error() +} + +func (w *wrappedError) WrappedErrors() []error { + return []error{w.Outer, w.Inner} +} diff --git a/vendor/github.com/hashicorp/errwrap/go.mod b/vendor/github.com/hashicorp/errwrap/go.mod new file mode 100644 index 00000000..c9b84022 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/go.mod @@ -0,0 +1 @@ +module github.com/hashicorp/errwrap diff --git a/vendor/github.com/hashicorp/go-multierror/.travis.yml b/vendor/github.com/hashicorp/go-multierror/.travis.yml new file mode 100644 index 00000000..304a8359 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/.travis.yml @@ -0,0 +1,12 @@ +sudo: false + +language: go + +go: + - 1.x + +branches: + only: + - master + +script: make test testrace diff --git a/vendor/github.com/hashicorp/go-multierror/LICENSE b/vendor/github.com/hashicorp/go-multierror/LICENSE new file mode 100644 index 00000000..82b4de97 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/LICENSE @@ -0,0 +1,353 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/go-multierror/Makefile b/vendor/github.com/hashicorp/go-multierror/Makefile new file mode 100644 index 00000000..b97cd6ed --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/Makefile @@ -0,0 +1,31 @@ +TEST?=./... + +default: test + +# test runs the test suite and vets the code. +test: generate + @echo "==> Running tests..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS} + +# testrace runs the race checker +testrace: generate + @echo "==> Running tests (race)..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -race ${TESTARGS} + +# updatedeps installs all the dependencies needed to run and build. +updatedeps: + @sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'" + +# generate runs `go generate` to build the dynamically generated source files. +generate: + @echo "==> Generating..." + @find . -type f -name '.DS_Store' -delete + @go list ./... \ + | grep -v "/vendor/" \ + | xargs -n1 go generate + +.PHONY: default test testrace updatedeps generate diff --git a/vendor/github.com/hashicorp/go-multierror/README.md b/vendor/github.com/hashicorp/go-multierror/README.md new file mode 100644 index 00000000..ead5830f --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/README.md @@ -0,0 +1,97 @@ +# go-multierror + +[![Build Status](http://img.shields.io/travis/hashicorp/go-multierror.svg?style=flat-square)][travis] +[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs] + +[travis]: https://travis-ci.org/hashicorp/go-multierror +[godocs]: https://godoc.org/github.com/hashicorp/go-multierror + +`go-multierror` is a package for Go that provides a mechanism for +representing a list of `error` values as a single `error`. + +This allows a function in Go to return an `error` that might actually +be a list of errors. If the caller knows this, they can unwrap the +list and access the errors. If the caller doesn't know, the error +formats to a nice human-readable format. + +`go-multierror` implements the +[errwrap](https://github.com/hashicorp/errwrap) interface so that it can +be used with that library, as well. + +## Installation and Docs + +Install using `go get github.com/hashicorp/go-multierror`. + +Full documentation is available at +http://godoc.org/github.com/hashicorp/go-multierror + +## Usage + +go-multierror is easy to use and purposely built to be unobtrusive in +existing Go applications/libraries that may not be aware of it. + +**Building a list of errors** + +The `Append` function is used to create a list of errors. This function +behaves a lot like the Go built-in `append` function: it doesn't matter +if the first argument is nil, a `multierror.Error`, or any other `error`, +the function behaves as you would expect. + +```go +var result error + +if err := step1(); err != nil { + result = multierror.Append(result, err) +} +if err := step2(); err != nil { + result = multierror.Append(result, err) +} + +return result +``` + +**Customizing the formatting of the errors** + +By specifying a custom `ErrorFormat`, you can customize the format +of the `Error() string` function: + +```go +var result *multierror.Error + +// ... accumulate errors here, maybe using Append + +if result != nil { + result.ErrorFormat = func([]error) string { + return "errors!" + } +} +``` + +**Accessing the list of errors** + +`multierror.Error` implements `error` so if the caller doesn't know about +multierror, it will work just fine. But if you're aware a multierror might +be returned, you can use type switches to access the list of errors: + +```go +if err := something(); err != nil { + if merr, ok := err.(*multierror.Error); ok { + // Use merr.Errors + } +} +``` + +**Returning a multierror only if there are errors** + +If you build a `multierror.Error`, you can use the `ErrorOrNil` function +to return an `error` implementation only if there are errors to return: + +```go +var result *multierror.Error + +// ... accumulate errors here + +// Return the `error` only if errors were added to the multierror, otherwise +// return nil since there are no errors. +return result.ErrorOrNil() +``` diff --git a/vendor/github.com/hashicorp/go-multierror/append.go b/vendor/github.com/hashicorp/go-multierror/append.go new file mode 100644 index 00000000..775b6e75 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/append.go @@ -0,0 +1,41 @@ +package multierror + +// Append is a helper function that will append more errors +// onto an Error in order to create a larger multi-error. +// +// If err is not a multierror.Error, then it will be turned into +// one. If any of the errs are multierr.Error, they will be flattened +// one level into err. +func Append(err error, errs ...error) *Error { + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Go through each error and flatten + for _, e := range errs { + switch e := e.(type) { + case *Error: + if e != nil { + err.Errors = append(err.Errors, e.Errors...) + } + default: + if e != nil { + err.Errors = append(err.Errors, e) + } + } + } + + return err + default: + newErrs := make([]error, 0, len(errs)+1) + if err != nil { + newErrs = append(newErrs, err) + } + newErrs = append(newErrs, errs...) + + return Append(&Error{}, newErrs...) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/flatten.go b/vendor/github.com/hashicorp/go-multierror/flatten.go new file mode 100644 index 00000000..aab8e9ab --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/flatten.go @@ -0,0 +1,26 @@ +package multierror + +// Flatten flattens the given error, merging any *Errors together into +// a single *Error. +func Flatten(err error) error { + // If it isn't an *Error, just return the error as-is + if _, ok := err.(*Error); !ok { + return err + } + + // Otherwise, make the result and flatten away! + flatErr := new(Error) + flatten(err, flatErr) + return flatErr +} + +func flatten(err error, flatErr *Error) { + switch err := err.(type) { + case *Error: + for _, e := range err.Errors { + flatten(e, flatErr) + } + default: + flatErr.Errors = append(flatErr.Errors, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/format.go b/vendor/github.com/hashicorp/go-multierror/format.go new file mode 100644 index 00000000..47f13c49 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/format.go @@ -0,0 +1,27 @@ +package multierror + +import ( + "fmt" + "strings" +) + +// ErrorFormatFunc is a function callback that is called by Error to +// turn the list of errors into a string. +type ErrorFormatFunc func([]error) string + +// ListFormatFunc is a basic formatter that outputs the number of errors +// that occurred along with a bullet point list of the errors. +func ListFormatFunc(es []error) string { + if len(es) == 1 { + return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0]) + } + + points := make([]string, len(es)) + for i, err := range es { + points[i] = fmt.Sprintf("* %s", err) + } + + return fmt.Sprintf( + "%d errors occurred:\n\t%s\n\n", + len(es), strings.Join(points, "\n\t")) +} diff --git a/vendor/github.com/hashicorp/go-multierror/go.mod b/vendor/github.com/hashicorp/go-multierror/go.mod new file mode 100644 index 00000000..2534331d --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/go.mod @@ -0,0 +1,3 @@ +module github.com/hashicorp/go-multierror + +require github.com/hashicorp/errwrap v1.0.0 diff --git a/vendor/github.com/hashicorp/go-multierror/go.sum b/vendor/github.com/hashicorp/go-multierror/go.sum new file mode 100644 index 00000000..85b1f8ff --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/go.sum @@ -0,0 +1,4 @@ +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w+PflHoszQNLTUh4kaByUcEWM/9uin4= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/vendor/github.com/hashicorp/go-multierror/multierror.go b/vendor/github.com/hashicorp/go-multierror/multierror.go new file mode 100644 index 00000000..89b1422d --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/multierror.go @@ -0,0 +1,51 @@ +package multierror + +import ( + "fmt" +) + +// Error is an error type to track multiple errors. This is used to +// accumulate errors in cases and return them as a single "error". +type Error struct { + Errors []error + ErrorFormat ErrorFormatFunc +} + +func (e *Error) Error() string { + fn := e.ErrorFormat + if fn == nil { + fn = ListFormatFunc + } + + return fn(e.Errors) +} + +// ErrorOrNil returns an error interface if this Error represents +// a list of errors, or returns nil if the list of errors is empty. This +// function is useful at the end of accumulation to make sure that the value +// returned represents the existence of errors. +func (e *Error) ErrorOrNil() error { + if e == nil { + return nil + } + if len(e.Errors) == 0 { + return nil + } + + return e +} + +func (e *Error) GoString() string { + return fmt.Sprintf("*%#v", *e) +} + +// WrappedErrors returns the list of errors that this Error is wrapping. +// It is an implementation of the errwrap.Wrapper interface so that +// multierror.Error can be used with that library. +// +// This method is not safe to be called concurrently and is no different +// than accessing the Errors field directly. It is implemented only to +// satisfy the errwrap.Wrapper interface. +func (e *Error) WrappedErrors() []error { + return e.Errors +} diff --git a/vendor/github.com/hashicorp/go-multierror/prefix.go b/vendor/github.com/hashicorp/go-multierror/prefix.go new file mode 100644 index 00000000..5c477abe --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/prefix.go @@ -0,0 +1,37 @@ +package multierror + +import ( + "fmt" + + "github.com/hashicorp/errwrap" +) + +// Prefix is a helper function that will prefix some text +// to the given error. If the error is a multierror.Error, then +// it will be prefixed to each wrapped error. +// +// This is useful to use when appending multiple multierrors +// together in order to give better scoping. +func Prefix(err error, prefix string) error { + if err == nil { + return nil + } + + format := fmt.Sprintf("%s {{err}}", prefix) + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Wrap each of the errors + for i, e := range err.Errors { + err.Errors[i] = errwrap.Wrapf(format, e) + } + + return err + default: + return errwrap.Wrapf(format, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/sort.go b/vendor/github.com/hashicorp/go-multierror/sort.go new file mode 100644 index 00000000..fecb14e8 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/sort.go @@ -0,0 +1,16 @@ +package multierror + +// Len implements sort.Interface function for length +func (err Error) Len() int { + return len(err.Errors) +} + +// Swap implements sort.Interface function for swapping elements +func (err Error) Swap(i, j int) { + err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i] +} + +// Less implements sort.Interface function for determining order +func (err Error) Less(i, j int) bool { + return err.Errors[i].Error() < err.Errors[j].Error() +} diff --git a/vendor/github.com/hashicorp/golang-lru/go.mod b/vendor/github.com/hashicorp/golang-lru/go.mod new file mode 100644 index 00000000..824cb97e --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/go.mod @@ -0,0 +1 @@ +module github.com/hashicorp/golang-lru diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go new file mode 100644 index 00000000..1cbe04b7 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/lru.go @@ -0,0 +1,116 @@ +package lru + +import ( + "sync" + + "github.com/hashicorp/golang-lru/simplelru" +) + +// Cache is a thread-safe fixed size LRU cache. +type Cache struct { + lru simplelru.LRUCache + lock sync.RWMutex +} + +// New creates an LRU of the given size. +func New(size int) (*Cache, error) { + return NewWithEvict(size, nil) +} + +// NewWithEvict constructs a fixed size cache with the given eviction +// callback. +func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) { + lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted)) + if err != nil { + return nil, err + } + c := &Cache{ + lru: lru, + } + return c, nil +} + +// Purge is used to completely clear the cache. +func (c *Cache) Purge() { + c.lock.Lock() + c.lru.Purge() + c.lock.Unlock() +} + +// Add adds a value to the cache. Returns true if an eviction occurred. +func (c *Cache) Add(key, value interface{}) (evicted bool) { + c.lock.Lock() + evicted = c.lru.Add(key, value) + c.lock.Unlock() + return evicted +} + +// Get looks up a key's value from the cache. +func (c *Cache) Get(key interface{}) (value interface{}, ok bool) { + c.lock.Lock() + value, ok = c.lru.Get(key) + c.lock.Unlock() + return value, ok +} + +// Contains checks if a key is in the cache, without updating the +// recent-ness or deleting it for being stale. +func (c *Cache) Contains(key interface{}) bool { + c.lock.RLock() + containKey := c.lru.Contains(key) + c.lock.RUnlock() + return containKey +} + +// Peek returns the key value (or undefined if not found) without updating +// the "recently used"-ness of the key. +func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) { + c.lock.RLock() + value, ok = c.lru.Peek(key) + c.lock.RUnlock() + return value, ok +} + +// ContainsOrAdd checks if a key is in the cache without updating the +// recent-ness or deleting it for being stale, and if not, adds the value. +// Returns whether found and whether an eviction occurred. +func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { + c.lock.Lock() + defer c.lock.Unlock() + + if c.lru.Contains(key) { + return true, false + } + evicted = c.lru.Add(key, value) + return false, evicted +} + +// Remove removes the provided key from the cache. +func (c *Cache) Remove(key interface{}) { + c.lock.Lock() + c.lru.Remove(key) + c.lock.Unlock() +} + +// RemoveOldest removes the oldest item from the cache. +func (c *Cache) RemoveOldest() { + c.lock.Lock() + c.lru.RemoveOldest() + c.lock.Unlock() +} + +// Keys returns a slice of the keys in the cache, from oldest to newest. +func (c *Cache) Keys() []interface{} { + c.lock.RLock() + keys := c.lru.Keys() + c.lock.RUnlock() + return keys +} + +// Len returns the number of items in the cache. +func (c *Cache) Len() int { + c.lock.RLock() + length := c.lru.Len() + c.lock.RUnlock() + return length +} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go new file mode 100644 index 00000000..74c70774 --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go @@ -0,0 +1,36 @@ +package simplelru + +// LRUCache is the interface for simple LRU cache. +type LRUCache interface { + // Adds a value to the cache, returns true if an eviction occurred and + // updates the "recently used"-ness of the key. + Add(key, value interface{}) bool + + // Returns key's value from the cache and + // updates the "recently used"-ness of the key. #value, isFound + Get(key interface{}) (value interface{}, ok bool) + + // Check if a key exsists in cache without updating the recent-ness. + Contains(key interface{}) (ok bool) + + // Returns key's value without updating the "recently used"-ness of the key. + Peek(key interface{}) (value interface{}, ok bool) + + // Removes a key from the cache. + Remove(key interface{}) bool + + // Removes the oldest entry from cache. + RemoveOldest() (interface{}, interface{}, bool) + + // Returns the oldest entry from the cache. #key, value, isFound + GetOldest() (interface{}, interface{}, bool) + + // Returns a slice of the keys in the cache, from oldest to newest. + Keys() []interface{} + + // Returns the number of items in the cache. + Len() int + + // Clear all cache entries + Purge() +} diff --git a/vendor/github.com/huin/goupnp/.gitignore b/vendor/github.com/huin/goupnp/.gitignore new file mode 100644 index 00000000..7a6e0ebe --- /dev/null +++ b/vendor/github.com/huin/goupnp/.gitignore @@ -0,0 +1,2 @@ +*.zip +*.sublime-workspace \ No newline at end of file diff --git a/vendor/github.com/huin/goupnp/README.md b/vendor/github.com/huin/goupnp/README.md new file mode 100644 index 00000000..7c63903a --- /dev/null +++ b/vendor/github.com/huin/goupnp/README.md @@ -0,0 +1,48 @@ +goupnp is a UPnP client library for Go + +Installation +------------ + +Run `go get -u github.com/huin/goupnp`. + +Documentation +------------- + +Supported DCPs (you probably want to start with one of these): + +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1. +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1. +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2. + +Core components: + +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) (goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs. +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP. +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network. +* [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services. + + +Regenerating dcps generated source code: +---------------------------------------- + +1. Build code generator: + + `go get -u github.com/huin/goupnp/cmd/goupnpdcpgen` + +2. Regenerate the code: + + `go generate ./...` + +Supporting additional UPnP devices and services: +------------------------------------------------ + +Supporting additional services is, in the trivial case, simply a matter of +adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`, +regenerating the source code (see above), and committing that source code. + +However, it would be helpful if anyone needing such a service could test the +service against the service they have, and then reporting any trouble +encountered as an [issue on this +project](https://github.com/huin/goupnp/issues/new). If it just works, then +please report at least minimal working functionality as an issue, and +optionally contribute the metadata upstream. diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway1/gen.go b/vendor/github.com/huin/goupnp/dcps/internetgateway1/gen.go new file mode 100644 index 00000000..2b146a34 --- /dev/null +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway1/gen.go @@ -0,0 +1,2 @@ +//go:generate goupnpdcpgen -dcp_name internetgateway1 +package internetgateway1 diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go b/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go new file mode 100644 index 00000000..752058b4 --- /dev/null +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go @@ -0,0 +1,2 @@ +//go:generate goupnpdcpgen -dcp_name internetgateway2 +package internetgateway2 diff --git a/vendor/github.com/huin/goupnp/go.mod b/vendor/github.com/huin/goupnp/go.mod new file mode 100644 index 00000000..e4a078f6 --- /dev/null +++ b/vendor/github.com/huin/goupnp/go.mod @@ -0,0 +1,7 @@ +module github.com/huin/goupnp + +require ( + github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150 + golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1 + golang.org/x/text v0.3.0 // indirect +) diff --git a/vendor/github.com/huin/goupnp/go.sum b/vendor/github.com/huin/goupnp/go.sum new file mode 100644 index 00000000..3e758699 --- /dev/null +++ b/vendor/github.com/huin/goupnp/go.sum @@ -0,0 +1,6 @@ +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150 h1:vlNjIqmUZ9CMAWsbURYl3a6wZbw7q5RHVvlXTNS/Bs8= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1 h1:Y/KGZSOdz/2r0WJ9Mkmz6NJBusp0kiNx1Cn82lzJQ6w= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/huin/goupnp/goupnp.sublime-project b/vendor/github.com/huin/goupnp/goupnp.sublime-project new file mode 100644 index 00000000..24db3031 --- /dev/null +++ b/vendor/github.com/huin/goupnp/goupnp.sublime-project @@ -0,0 +1,8 @@ +{ + "folders": + [ + { + "path": "." + } + ] +} diff --git a/vendor/github.com/ipfs/bbloom/.gitignore b/vendor/github.com/ipfs/bbloom/.gitignore new file mode 100644 index 00000000..6540f71c --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/.gitignore @@ -0,0 +1 @@ +words.txt diff --git a/vendor/github.com/ipfs/bbloom/.travis.yml b/vendor/github.com/ipfs/bbloom/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/bbloom/README.md b/vendor/github.com/ipfs/bbloom/README.md new file mode 100644 index 00000000..6d77e146 --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/README.md @@ -0,0 +1,129 @@ +## bbloom: a bitset Bloom filter for go/golang +=== + +package implements a fast bloom filter with real 'bitset' and JSONMarshal/JSONUnmarshal to store/reload the Bloom filter. + +NOTE: the package uses unsafe.Pointer to set and read the bits from the bitset. If you're uncomfortable with using the unsafe package, please consider using my bloom filter package at github.com/AndreasBriese/bloom + +=== + +changelog 11/2015: new thread safe methods AddTS(), HasTS(), AddIfNotHasTS() following a suggestion from Srdjan Marinovic (github @a-little-srdjan), who used this to code a bloomfilter cache. + +This bloom filter was developed to strengthen a website-log database and was tested and optimized for this log-entry mask: "2014/%02i/%02i %02i:%02i:%02i /info.html". +Nonetheless bbloom should work with any other form of entries. + +~~Hash function is a modified Berkeley DB sdbm hash (to optimize for smaller strings). sdbm http://www.cse.yorku.ca/~oz/hash.html~~ + +Found sipHash (SipHash-2-4, a fast short-input PRF created by Jean-Philippe Aumasson and Daniel J. Bernstein.) to be about as fast. sipHash had been ported by Dimtry Chestnyk to Go (github.com/dchest/siphash ) + +Minimum hashset size is: 512 ([4]uint64; will be set automatically). + +###install + +```sh +go get github.com/AndreasBriese/bbloom +``` + +###test ++ change to folder ../bbloom ++ create wordlist in file "words.txt" (you might use `python permut.py`) ++ run 'go test -bench=.' within the folder + +```go +go test -bench=. +``` + +~~If you've installed the GOCONVEY TDD-framework http://goconvey.co/ you can run the tests automatically.~~ + +using go's testing framework now (have in mind that the op timing is related to 65536 operations of Add, Has, AddIfNotHas respectively) + +### usage + +after installation add + +```go +import ( + ... + "github.com/AndreasBriese/bbloom" + ... + ) +``` + +at your header. In the program use + +```go +// create a bloom filter for 65536 items and 1 % wrong-positive ratio +bf := bbloom.New(float64(1<<16), float64(0.01)) + +// or +// create a bloom filter with 650000 for 65536 items and 7 locs per hash explicitly +// bf = bbloom.New(float64(650000), float64(7)) +// or +bf = bbloom.New(650000.0, 7.0) + +// add one item +bf.Add([]byte("butter")) + +// Number of elements added is exposed now +// Note: ElemNum will not be included in JSON export (for compatability to older version) +nOfElementsInFilter := bf.ElemNum + +// check if item is in the filter +isIn := bf.Has([]byte("butter")) // should be true +isNotIn := bf.Has([]byte("Butter")) // should be false + +// 'add only if item is new' to the bloomfilter +added := bf.AddIfNotHas([]byte("butter")) // should be false because 'butter' is already in the set +added = bf.AddIfNotHas([]byte("buTTer")) // should be true because 'buTTer' is new + +// thread safe versions for concurrent use: AddTS, HasTS, AddIfNotHasTS +// add one item +bf.AddTS([]byte("peanutbutter")) +// check if item is in the filter +isIn = bf.HasTS([]byte("peanutbutter")) // should be true +isNotIn = bf.HasTS([]byte("peanutButter")) // should be false +// 'add only if item is new' to the bloomfilter +added = bf.AddIfNotHasTS([]byte("butter")) // should be false because 'peanutbutter' is already in the set +added = bf.AddIfNotHasTS([]byte("peanutbuTTer")) // should be true because 'penutbuTTer' is new + +// convert to JSON ([]byte) +Json := bf.JSONMarshal() + +// bloomfilters Mutex is exposed for external un-/locking +// i.e. mutex lock while doing JSON conversion +bf.Mtx.Lock() +Json = bf.JSONMarshal() +bf.Mtx.Unlock() + +// restore a bloom filter from storage +bfNew := bbloom.JSONUnmarshal(Json) + +isInNew := bfNew.Has([]byte("butter")) // should be true +isNotInNew := bfNew.Has([]byte("Butter")) // should be false + +``` + +to work with the bloom filter. + +### why 'fast'? + +It's about 3 times faster than William Fitzgeralds bitset bloom filter https://github.com/willf/bloom . And it is about so fast as my []bool set variant for Boom filters (see https://github.com/AndreasBriese/bloom ) but having a 8times smaller memory footprint: + + + Bloom filter (filter size 524288, 7 hashlocs) + github.com/AndreasBriese/bbloom 'Add' 65536 items (10 repetitions): 6595800 ns (100 ns/op) + github.com/AndreasBriese/bbloom 'Has' 65536 items (10 repetitions): 5986600 ns (91 ns/op) + github.com/AndreasBriese/bloom 'Add' 65536 items (10 repetitions): 6304684 ns (96 ns/op) + github.com/AndreasBriese/bloom 'Has' 65536 items (10 repetitions): 6568663 ns (100 ns/op) + + github.com/willf/bloom 'Add' 65536 items (10 repetitions): 24367224 ns (371 ns/op) + github.com/willf/bloom 'Test' 65536 items (10 repetitions): 21881142 ns (333 ns/op) + github.com/dataence/bloom/standard 'Add' 65536 items (10 repetitions): 23041644 ns (351 ns/op) + github.com/dataence/bloom/standard 'Check' 65536 items (10 repetitions): 19153133 ns (292 ns/op) + github.com/cabello/bloom 'Add' 65536 items (10 repetitions): 131921507 ns (2012 ns/op) + github.com/cabello/bloom 'Contains' 65536 items (10 repetitions): 131108962 ns (2000 ns/op) + +(on MBPro15 OSX10.8.5 i7 4Core 2.4Ghz) + + +With 32bit bloom filters (bloom32) using modified sdbm, bloom32 does hashing with only 2 bit shifts, one xor and one substraction per byte. smdb is about as fast as fnv64a but gives less collisions with the dataset (see mask above). bloom.New(float64(10 * 1<<16),float64(7)) populated with 1<<16 random items from the dataset (see above) and tested against the rest results in less than 0.05% collisions. diff --git a/vendor/github.com/ipfs/bbloom/bbloom.go b/vendor/github.com/ipfs/bbloom/bbloom.go new file mode 100644 index 00000000..2bff5945 --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/bbloom.go @@ -0,0 +1,315 @@ +// The MIT License (MIT) +// Copyright (c) 2014 Andreas Briese, eduToolbox@Bri-C GmbH, Sarstedt + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package bbloom + +import ( + "bytes" + "encoding/json" + "errors" + "math" + "sync" + "unsafe" +) + +// helper +var mask = []uint8{1, 2, 4, 8, 16, 32, 64, 128} + +func getSize(ui64 uint64) (size uint64, exponent uint64) { + if ui64 < uint64(512) { + ui64 = uint64(512) + } + size = uint64(1) + for size < ui64 { + size <<= 1 + exponent++ + } + return size, exponent +} + +func calcSizeByWrongPositives(numEntries, wrongs float64) (uint64, uint64) { + size := -1 * numEntries * math.Log(wrongs) / math.Pow(float64(0.69314718056), 2) + locs := math.Ceil(float64(0.69314718056) * size / numEntries) + return uint64(size), uint64(locs) +} + +var ErrUsage = errors.New("usage: New(float64(number_of_entries), float64(number_of_hashlocations)) i.e. New(float64(1000), float64(3)) or New(float64(number_of_entries), float64(ratio_of_false_positives)) i.e. New(float64(1000), float64(0.03))") +var ErrInvalidParms = errors.New("One of parameters was outside of allowed range") + +// New +// returns a new bloomfilter +func New(params ...float64) (bloomfilter *Bloom, err error) { + var entries, locs uint64 + if len(params) == 2 { + if params[0] < 0 || params[1] < 0 { + return nil, ErrInvalidParms + } + if params[1] < 1 { + entries, locs = calcSizeByWrongPositives(math.Max(params[0], 1), params[1]) + } else { + entries, locs = uint64(params[0]), uint64(params[1]) + } + } else { + return nil, ErrUsage + } + size, exponent := getSize(uint64(entries)) + bloomfilter = &Bloom{ + sizeExp: exponent, + size: size - 1, + setLocs: locs, + shift: 64 - exponent, + bitset: make([]uint64, size>>6), + } + return bloomfilter, nil +} + +// NewWithBoolset +// takes a []byte slice and number of locs per entry +// returns the bloomfilter with a bitset populated according to the input []byte +func NewWithBoolset(bs *[]byte, locs uint64) (bloomfilter *Bloom) { + bloomfilter, err := New(float64(len(*bs)<<3), float64(locs)) + if err != nil { + panic(err) // Should never happen + } + ptr := uintptr(unsafe.Pointer(&bloomfilter.bitset[0])) + for _, b := range *bs { + *(*uint8)(unsafe.Pointer(ptr)) = b + ptr++ + } + return bloomfilter +} + +// bloomJSONImExport +// Im/Export structure used by JSONMarshal / JSONUnmarshal +type bloomJSONImExport struct { + FilterSet []byte + SetLocs uint64 +} + +// +// Bloom filter +type Bloom struct { + Mtx sync.RWMutex + bitset []uint64 + sizeExp uint64 + size uint64 + setLocs uint64 + shift uint64 + + content uint64 +} + +func (bl *Bloom) ElementsAdded() uint64 { + return bl.content +} + +// <--- http://www.cse.yorku.ca/~oz/hash.html +// modified Berkeley DB Hash (32bit) +// hash is casted to l, h = 16bit fragments +// func (bl Bloom) absdbm(b *[]byte) (l, h uint64) { +// hash := uint64(len(*b)) +// for _, c := range *b { +// hash = uint64(c) + (hash << 6) + (hash << bl.sizeExp) - hash +// } +// h = hash >> bl.shift +// l = hash << bl.shift >> bl.shift +// return l, h +// } + +// Update: found sipHash of Jean-Philippe Aumasson & Daniel J. Bernstein to be even faster than absdbm() +// https://131002.net/siphash/ +// siphash was implemented for Go by Dmitry Chestnykh https://github.com/dchest/siphash + +// Add +// set the bit(s) for entry; Adds an entry to the Bloom filter +func (bl *Bloom) Add(entry []byte) { + bl.content++ + l, h := bl.sipHash(entry) + for i := uint64(0); i < (*bl).setLocs; i++ { + bl.set((h + i*l) & (*bl).size) + } +} + +// AddTS +// Thread safe: Mutex.Lock the bloomfilter for the time of processing the entry +func (bl *Bloom) AddTS(entry []byte) { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + bl.Add(entry[:]) +} + +// Has +// check if bit(s) for entry is/are set +// returns true if the entry was added to the Bloom Filter +func (bl *Bloom) Has(entry []byte) bool { + l, h := bl.sipHash(entry) + res := true + for i := uint64(0); i < bl.setLocs; i++ { + res = res && bl.isSet((h+i*l)&bl.size) + // Branching here (early escape) is not worth it + // This is my conclusion from benchmarks + // if !res { + // return false + // } + } + return res +} + +// HasTS +// Thread safe: Mutex.Lock the bloomfilter for the time of processing the entry +func (bl *Bloom) HasTS(entry []byte) bool { + bl.Mtx.RLock() + defer bl.Mtx.RUnlock() + return bl.Has(entry[:]) +} + +// AddIfNotHas +// Only Add entry if it's not present in the bloomfilter +// returns true if entry was added +// returns false if entry was allready registered in the bloomfilter +func (bl *Bloom) AddIfNotHas(entry []byte) (added bool) { + l, h := bl.sipHash(entry) + contained := true + for i := uint64(0); i < bl.setLocs; i++ { + prev := bl.getSet((h + i*l) & bl.size) + contained = contained && prev + } + if !contained { + bl.content++ + } + return !contained +} + +// AddIfNotHasTS +// Tread safe: Only Add entry if it's not present in the bloomfilter +// returns true if entry was added +// returns false if entry was allready registered in the bloomfilter +func (bl *Bloom) AddIfNotHasTS(entry []byte) (added bool) { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + return bl.AddIfNotHas(entry[:]) +} + +// Clear +// resets the Bloom filter +func (bl *Bloom) Clear() { + bl.Mtx.Lock() + defer bl.Mtx.Unlock() + for i, _ := range (*bl).bitset { + bl.bitset[i] = 0 + } + bl.content = 0 +} + +// Set +// set the bit[idx] of bitsit +func (bl *Bloom) set(idx uint64) { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bl.bitset[idx>>6])) + uintptr((idx%64)>>3)) + *(*uint8)(ptr) |= mask[idx%8] +} + +func (bl *Bloom) getSet(idx uint64) bool { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bl.bitset[idx>>6])) + uintptr((idx%64)>>3)) + res := *(*uint8)(ptr)&mask[idx%8] > 0 + *(*uint8)(ptr) |= mask[idx%8] + return res +} + +// IsSet +// check if bit[idx] of bitset is set +// returns true/false +func (bl *Bloom) isSet(idx uint64) bool { + ptr := unsafe.Pointer(uintptr(unsafe.Pointer(&bl.bitset[idx>>6])) + uintptr((idx%64)>>3)) + return *(*uint8)(ptr)&mask[idx%8] > 0 +} + +// JSONMarshal +// returns JSON-object (type bloomJSONImExport) as []byte +func (bl *Bloom) JSONMarshal() ([]byte, error) { + bl.Mtx.RLock() + defer bl.Mtx.RUnlock() + bloomImEx := bloomJSONImExport{} + bloomImEx.SetLocs = uint64(bl.setLocs) + bloomImEx.FilterSet = make([]byte, len(bl.bitset)<<3) + ptr := uintptr(unsafe.Pointer(&bl.bitset[0])) + for i := range bloomImEx.FilterSet { + bloomImEx.FilterSet[i] = *(*byte)(unsafe.Pointer(ptr)) + ptr++ + } + data, err := json.Marshal(bloomImEx) + return data, err +} + +// JSONUnmarshal +// takes JSON-Object (type bloomJSONImExport) as []bytes +// returns bloom32 / bloom64 object +func JSONUnmarshal(dbData []byte) *Bloom { + bloomImEx := bloomJSONImExport{} + json.Unmarshal(dbData, &bloomImEx) + buf := bytes.NewBuffer(bloomImEx.FilterSet) + bs := buf.Bytes() + bf := NewWithBoolset(&bs, bloomImEx.SetLocs) + return bf +} + +func (bl *Bloom) FillRatio() float64 { + count := uint64(0) + for _, b := range bl.bitset { + count += uint64(popcount(b)) + } + return float64(count) / float64(bl.size+1) +} + +func popcount(x uint64) uint { + const ( + m1 = 0x5555555555555555 //binary: 0101... + m2 = 0x3333333333333333 //binary: 00110011.. + m4 = 0x0f0f0f0f0f0f0f0f //binary: 4 zeros, 4 ones ... + h01 = 0x0101010101010101 //the sum of 256 to the power of 0,1,2,3... + ) + x -= (x >> 1) & m1 //put count of each 2 bits into those 2 bits + x = (x & m2) + ((x >> 2) & m2) //put count of each 4 bits into those 4 bits + x = (x + (x >> 4)) & m4 //put count of each 8 bits into those 8 bits + return uint((x * h01) >> 56) +} + +// // alternative hashFn +// func (bl Bloom) fnv64a(b *[]byte) (l, h uint64) { +// h64 := fnv.New64a() +// h64.Write(*b) +// hash := h64.Sum64() +// h = hash >> 32 +// l = hash << 32 >> 32 +// return l, h +// } +// +// // <-- http://partow.net/programming/hashfunctions/index.html +// // citation: An algorithm proposed by Donald E. Knuth in The Art Of Computer Programming Volume 3, +// // under the topic of sorting and search chapter 6.4. +// // modified to fit with boolset-length +// func (bl Bloom) DEKHash(b *[]byte) (l, h uint64) { +// hash := uint64(len(*b)) +// for _, c := range *b { +// hash = ((hash << 5) ^ (hash >> bl.shift)) ^ uint64(c) +// } +// h = hash >> bl.shift +// l = hash << bl.sizeExp >> bl.sizeExp +// return l, h +// } diff --git a/vendor/github.com/ipfs/bbloom/go.mod b/vendor/github.com/ipfs/bbloom/go.mod new file mode 100644 index 00000000..07ae2921 --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/go.mod @@ -0,0 +1 @@ +module github.com/ipfs/bbloom diff --git a/vendor/github.com/ipfs/bbloom/package.json b/vendor/github.com/ipfs/bbloom/package.json new file mode 100644 index 00000000..3d42cf9c --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/package.json @@ -0,0 +1,15 @@ +{ + "author": "AndreasBriese", + "bugs": { + "url": "https://github.com/ipfs/bbloom" + }, + "gx": { + "dvcsimport": "github.com/ipfs/bbloom" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "MIT", + "name": "bbloom", + "version": "0.1.2" +} + diff --git a/vendor/github.com/ipfs/bbloom/sipHash.go b/vendor/github.com/ipfs/bbloom/sipHash.go new file mode 100644 index 00000000..a91d8199 --- /dev/null +++ b/vendor/github.com/ipfs/bbloom/sipHash.go @@ -0,0 +1,225 @@ +// Written in 2012 by Dmitry Chestnykh. +// +// To the extent possible under law, the author have dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// http://creativecommons.org/publicdomain/zero/1.0/ +// +// Package siphash implements SipHash-2-4, a fast short-input PRF +// created by Jean-Philippe Aumasson and Daniel J. Bernstein. + +package bbloom + +// Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit +// parts of 128-bit key: k0 and k1. +func (bl Bloom) sipHash(p []byte) (l, h uint64) { + // Initialization. + v0 := uint64(8317987320269560794) // k0 ^ 0x736f6d6570736575 + v1 := uint64(7237128889637516672) // k1 ^ 0x646f72616e646f6d + v2 := uint64(7816392314733513934) // k0 ^ 0x6c7967656e657261 + v3 := uint64(8387220255325274014) // k1 ^ 0x7465646279746573 + t := uint64(len(p)) << 56 + + // Compression. + for len(p) >= 8 { + + m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | + uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 + + v3 ^= m + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + v0 ^= m + p = p[8:] + } + + // Compress last block. + switch len(p) { + case 7: + t |= uint64(p[6]) << 48 + fallthrough + case 6: + t |= uint64(p[5]) << 40 + fallthrough + case 5: + t |= uint64(p[4]) << 32 + fallthrough + case 4: + t |= uint64(p[3]) << 24 + fallthrough + case 3: + t |= uint64(p[2]) << 16 + fallthrough + case 2: + t |= uint64(p[1]) << 8 + fallthrough + case 1: + t |= uint64(p[0]) + } + + v3 ^= t + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + v0 ^= t + + // Finalization. + v2 ^= 0xff + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 3. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // Round 4. + v0 += v1 + v1 = v1<<13 | v1>>51 + v1 ^= v0 + v0 = v0<<32 | v0>>32 + + v2 += v3 + v3 = v3<<16 | v3>>48 + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>43 + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>47 + v1 ^= v2 + v2 = v2<<32 | v2>>32 + + // return v0 ^ v1 ^ v2 ^ v3 + + hash := v0 ^ v1 ^ v2 ^ v3 + h = hash >> bl.shift + l = hash << bl.shift >> bl.shift + return l, h + +} diff --git a/vendor/github.com/ipfs/go-bitswap/.gitignore b/vendor/github.com/ipfs/go-bitswap/.gitignore new file mode 100644 index 00000000..a9a5aecf --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/.gitignore @@ -0,0 +1 @@ +tmp diff --git a/vendor/github.com/ipfs/go-bitswap/.travis.yml b/vendor/github.com/ipfs/go-bitswap/.travis.yml new file mode 100644 index 00000000..923835bc --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-bitswap/LICENSE b/vendor/github.com/ipfs/go-bitswap/LICENSE new file mode 100644 index 00000000..7d5dcac4 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-bitswap/Makefile b/vendor/github.com/ipfs/go-bitswap/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-bitswap/README.md b/vendor/github.com/ipfs/go-bitswap/README.md new file mode 100644 index 00000000..62bbd9b3 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/README.md @@ -0,0 +1,64 @@ +go-bitswap +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-bitswap/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-bitswap/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-bitswap.svg?branch=master)](https://travis-ci.org/ipfs/go-bitswap) + +> An implementation of the bitswap protocol in go! + + +## Table of Contents + +- [Install](#install) +- [Protocol](#protocol) +- [Implementation](#implementation) +- [Contribute](#contribute) +- [License](#license) + +## Protocol +Bitswap is the data trading module for ipfs, it manages requesting and sending +blocks to and from other peers in the network. Bitswap has two main jobs, the +first is to acquire blocks requested by the client from the network. The second +is to judiciously send blocks in its possession to other peers who want them. + +Bitswap is a message based protocol, as opposed to response-reply. All messages +contain wantlists, or blocks. Upon receiving a wantlist, a node should consider +sending out wanted blocks if they have them. Upon receiving blocks, the node +should send out a notification called a 'Cancel' signifying that they no longer +want the block. At a protocol level, bitswap is very simple. + +## Implementation +Internally, when a message with a wantlist is received, it is sent to the +decision engine to be considered, and blocks that we have that are wanted are +placed into the peer request queue. Any block we possess that is wanted by +another peer has a task in the peer request queue created for it. The peer +request queue is a priority queue that sorts available tasks by some metric, +currently, that metric is very simple and aims to fairly address the tasks +of each other peer. More advanced decision logic will be implemented in the +future. Task workers pull tasks to be done off of the queue, retrieve the block +to be sent, and send it off. The number of task workers is limited by a constant +factor. + +Client requests for new blocks are handled by the want manager, for every new +block (or set of blocks) wanted, the 'WantBlocks' method is invoked. The want +manager then ensures that connected peers are notified of the new block that we +want by sending the new entries to a message queue for each peer. The message +queue will loop while there is work available and do the following: 1) Ensure it +has a connection to its peer, 2) grab the message to be sent, and 3) send it. +If new messages are added while the loop is in steps 1 or 3, the messages are +combined into one to avoid having to keep an actual queue and send multiple +messages. The same process occurs when the client receives a block and sends a +cancel message for it. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-bitswap/bitswap.go b/vendor/github.com/ipfs/go-bitswap/bitswap.go new file mode 100644 index 00000000..ec89982f --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/bitswap.go @@ -0,0 +1,428 @@ +// Package bitswap implements the IPFS exchange interface with the BitSwap +// bilateral exchange protocol. +package bitswap + +import ( + "context" + "errors" + "sync" + "time" + + bssrs "github.com/ipfs/go-bitswap/sessionrequestsplitter" + delay "github.com/ipfs/go-ipfs-delay" + + decision "github.com/ipfs/go-bitswap/decision" + bsgetter "github.com/ipfs/go-bitswap/getter" + bsmsg "github.com/ipfs/go-bitswap/message" + bsmq "github.com/ipfs/go-bitswap/messagequeue" + bsnet "github.com/ipfs/go-bitswap/network" + bspm "github.com/ipfs/go-bitswap/peermanager" + bspqm "github.com/ipfs/go-bitswap/providerquerymanager" + bssession "github.com/ipfs/go-bitswap/session" + bssm "github.com/ipfs/go-bitswap/sessionmanager" + bsspm "github.com/ipfs/go-bitswap/sessionpeermanager" + bswm "github.com/ipfs/go-bitswap/wantmanager" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" + exchange "github.com/ipfs/go-ipfs-exchange-interface" + logging "github.com/ipfs/go-log" + metrics "github.com/ipfs/go-metrics-interface" + process "github.com/jbenet/goprocess" + procctx "github.com/jbenet/goprocess/context" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("bitswap") + +var _ exchange.SessionExchange = (*Bitswap)(nil) + +const ( + // these requests take at _least_ two minutes at the moment. + provideTimeout = time.Minute * 3 + defaultProvSearchDelay = time.Second +) + +var ( + // HasBlockBufferSize is the buffer size of the channel for new blocks + // that need to be provided. They should get pulled over by the + // provideCollector even before they are actually provided. + // TODO: Does this need to be this large givent that? + HasBlockBufferSize = 256 + provideKeysBufferSize = 2048 + provideWorkerMax = 6 + + // the 1<<18+15 is to observe old file chunks that are 1<<18 + 14 in size + metricsBuckets = []float64{1 << 6, 1 << 10, 1 << 14, 1 << 18, 1<<18 + 15, 1 << 22} +) + +// Option defines the functional option type that can be used to configure +// bitswap instances +type Option func(*Bitswap) + +// ProvideEnabled is an option for enabling/disabling provide announcements +func ProvideEnabled(enabled bool) Option { + return func(bs *Bitswap) { + bs.provideEnabled = enabled + } +} + +// ProviderSearchDelay overwrites the global provider search delay +func ProviderSearchDelay(newProvSearchDelay time.Duration) Option { + return func(bs *Bitswap) { + bs.provSearchDelay = newProvSearchDelay + } +} + +// RebroadcastDelay overwrites the global provider rebroadcast delay +func RebroadcastDelay(newRebroadcastDelay delay.D) Option { + return func(bs *Bitswap) { + bs.rebroadcastDelay = newRebroadcastDelay + } +} + +// New initializes a BitSwap instance that communicates over the provided +// BitSwapNetwork. This function registers the returned instance as the network +// delegate. Runs until context is cancelled or bitswap.Close is called. +func New(parent context.Context, network bsnet.BitSwapNetwork, + bstore blockstore.Blockstore, options ...Option) exchange.Interface { + + // important to use provided parent context (since it may include important + // loggable data). It's probably not a good idea to allow bitswap to be + // coupled to the concerns of the ipfs daemon in this way. + // + // FIXME(btc) Now that bitswap manages itself using a process, it probably + // shouldn't accept a context anymore. Clients should probably use Close() + // exclusively. We should probably find another way to share logging data + ctx, cancelFunc := context.WithCancel(parent) + ctx = metrics.CtxSubScope(ctx, "bitswap") + dupHist := metrics.NewCtx(ctx, "recv_dup_blocks_bytes", "Summary of duplicate"+ + " data blocks recived").Histogram(metricsBuckets) + allHist := metrics.NewCtx(ctx, "recv_all_blocks_bytes", "Summary of all"+ + " data blocks recived").Histogram(metricsBuckets) + + sentHistogram := metrics.NewCtx(ctx, "sent_all_blocks_bytes", "Histogram of blocks sent by"+ + " this bitswap").Histogram(metricsBuckets) + + px := process.WithTeardown(func() error { + return nil + }) + + peerQueueFactory := func(ctx context.Context, p peer.ID) bspm.PeerQueue { + return bsmq.New(ctx, p, network) + } + + wm := bswm.New(ctx, bspm.New(ctx, peerQueueFactory)) + pqm := bspqm.New(ctx, network) + + sessionFactory := func(ctx context.Context, id uint64, pm bssession.PeerManager, srs bssession.RequestSplitter, + provSearchDelay time.Duration, + rebroadcastDelay delay.D) bssm.Session { + return bssession.New(ctx, id, wm, pm, srs, provSearchDelay, rebroadcastDelay) + } + sessionPeerManagerFactory := func(ctx context.Context, id uint64) bssession.PeerManager { + return bsspm.New(ctx, id, network.ConnectionManager(), pqm) + } + sessionRequestSplitterFactory := func(ctx context.Context) bssession.RequestSplitter { + return bssrs.New(ctx) + } + + bs := &Bitswap{ + blockstore: bstore, + engine: decision.NewEngine(ctx, bstore, network.ConnectionManager()), // TODO close the engine with Close() method + network: network, + process: px, + newBlocks: make(chan cid.Cid, HasBlockBufferSize), + provideKeys: make(chan cid.Cid, provideKeysBufferSize), + wm: wm, + pqm: pqm, + sm: bssm.New(ctx, sessionFactory, sessionPeerManagerFactory, sessionRequestSplitterFactory), + counters: new(counters), + dupMetric: dupHist, + allMetric: allHist, + sentHistogram: sentHistogram, + provideEnabled: true, + provSearchDelay: defaultProvSearchDelay, + rebroadcastDelay: delay.Fixed(time.Minute), + } + + // apply functional options before starting and running bitswap + for _, option := range options { + option(bs) + } + + bs.wm.Startup() + bs.pqm.Startup() + network.SetDelegate(bs) + + // Start up bitswaps async worker routines + bs.startWorkers(ctx, px) + + // bind the context and process. + // do it over here to avoid closing before all setup is done. + go func() { + <-px.Closing() // process closes first + cancelFunc() + }() + procctx.CloseAfterContext(px, ctx) // parent cancelled first + + return bs +} + +// Bitswap instances implement the bitswap protocol. +type Bitswap struct { + // the wantlist tracks global wants for bitswap + wm *bswm.WantManager + + // the provider query manager manages requests to find providers + pqm *bspqm.ProviderQueryManager + + // the engine is the bit of logic that decides who to send which blocks to + engine *decision.Engine + + // network delivers messages on behalf of the session + network bsnet.BitSwapNetwork + + // blockstore is the local database + // NB: ensure threadsafety + blockstore blockstore.Blockstore + + // newBlocks is a channel for newly added blocks to be provided to the + // network. blocks pushed down this channel get buffered and fed to the + // provideKeys channel later on to avoid too much network activity + newBlocks chan cid.Cid + // provideKeys directly feeds provide workers + provideKeys chan cid.Cid + + process process.Process + + // Counters for various statistics + counterLk sync.Mutex + counters *counters + + // Metrics interface metrics + dupMetric metrics.Histogram + allMetric metrics.Histogram + sentHistogram metrics.Histogram + + // the sessionmanager manages tracking sessions + sm *bssm.SessionManager + + // whether or not to make provide announcements + provideEnabled bool + + // how long to wait before looking for providers in a session + provSearchDelay time.Duration + + // how often to rebroadcast providing requests to find more optimized providers + rebroadcastDelay delay.D +} + +type counters struct { + blocksRecvd uint64 + dupBlocksRecvd uint64 + dupDataRecvd uint64 + blocksSent uint64 + dataSent uint64 + dataRecvd uint64 + messagesRecvd uint64 +} + +// GetBlock attempts to retrieve a particular block from peers within the +// deadline enforced by the context. +func (bs *Bitswap) GetBlock(parent context.Context, k cid.Cid) (blocks.Block, error) { + return bsgetter.SyncGetBlock(parent, k, bs.GetBlocks) +} + +// WantlistForPeer returns the currently understood list of blocks requested by a +// given peer. +func (bs *Bitswap) WantlistForPeer(p peer.ID) []cid.Cid { + var out []cid.Cid + for _, e := range bs.engine.WantlistForPeer(p) { + out = append(out, e.Cid) + } + return out +} + +// LedgerForPeer returns aggregated data about blocks swapped and communication +// with a given peer. +func (bs *Bitswap) LedgerForPeer(p peer.ID) *decision.Receipt { + return bs.engine.LedgerForPeer(p) +} + +// GetBlocks returns a channel where the caller may receive blocks that +// correspond to the provided |keys|. Returns an error if BitSwap is unable to +// begin this request within the deadline enforced by the context. +// +// NB: Your request remains open until the context expires. To conserve +// resources, provide a context with a reasonably short deadline (ie. not one +// that lasts throughout the lifetime of the server) +func (bs *Bitswap) GetBlocks(ctx context.Context, keys []cid.Cid) (<-chan blocks.Block, error) { + session := bs.sm.NewSession(ctx, bs.provSearchDelay, bs.rebroadcastDelay) + return session.GetBlocks(ctx, keys) +} + +// HasBlock announces the existence of a block to this bitswap service. The +// service will potentially notify its peers. +func (bs *Bitswap) HasBlock(blk blocks.Block) error { + return bs.receiveBlockFrom(blk, "") +} + +// TODO: Some of this stuff really only needs to be done when adding a block +// from the user, not when receiving it from the network. +// In case you run `git blame` on this comment, I'll save you some time: ask +// @whyrusleeping, I don't know the answers you seek. +func (bs *Bitswap) receiveBlockFrom(blk blocks.Block, from peer.ID) error { + select { + case <-bs.process.Closing(): + return errors.New("bitswap is closed") + default: + } + + err := bs.blockstore.Put(blk) + if err != nil { + log.Errorf("Error writing block to datastore: %s", err) + return err + } + + // NOTE: There exists the possiblity for a race condition here. If a user + // creates a node, then adds it to the dagservice while another goroutine + // is waiting on a GetBlock for that object, they will receive a reference + // to the same node. We should address this soon, but i'm not going to do + // it now as it requires more thought and isnt causing immediate problems. + + bs.sm.ReceiveBlockFrom(from, blk) + + bs.engine.AddBlock(blk) + + if bs.provideEnabled { + select { + case bs.newBlocks <- blk.Cid(): + // send block off to be reprovided + case <-bs.process.Closing(): + return bs.process.Close() + } + } + return nil +} + +// ReceiveMessage is called by the network interface when a new message is +// received. +func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg.BitSwapMessage) { + bs.counterLk.Lock() + bs.counters.messagesRecvd++ + bs.counterLk.Unlock() + + // This call records changes to wantlists, blocks received, + // and number of bytes transfered. + bs.engine.MessageReceived(p, incoming) + // TODO: this is bad, and could be easily abused. + // Should only track *useful* messages in ledger + + iblocks := incoming.Blocks() + + if len(iblocks) == 0 { + return + } + + wg := sync.WaitGroup{} + for _, block := range iblocks { + + wg.Add(1) + go func(b blocks.Block) { // TODO: this probably doesnt need to be a goroutine... + defer wg.Done() + + bs.updateReceiveCounters(b) + bs.sm.UpdateReceiveCounters(b) + log.Debugf("got block %s from %s", b, p) + + // skip received blocks that are not in the wantlist + if !bs.wm.IsWanted(b.Cid()) { + return + } + + if err := bs.receiveBlockFrom(b, p); err != nil { + log.Warningf("ReceiveMessage recvBlockFrom error: %s", err) + } + log.Event(ctx, "Bitswap.GetBlockRequest.End", b.Cid()) + }(block) + } + wg.Wait() +} + +func (bs *Bitswap) updateReceiveCounters(b blocks.Block) { + blkLen := len(b.RawData()) + has, err := bs.blockstore.Has(b.Cid()) + if err != nil { + log.Infof("blockstore.Has error: %s", err) + return + } + + bs.allMetric.Observe(float64(blkLen)) + if has { + bs.dupMetric.Observe(float64(blkLen)) + } + + bs.counterLk.Lock() + defer bs.counterLk.Unlock() + c := bs.counters + + c.blocksRecvd++ + c.dataRecvd += uint64(len(b.RawData())) + if has { + c.dupBlocksRecvd++ + c.dupDataRecvd += uint64(blkLen) + } +} + +// PeerConnected is called by the network interface +// when a peer initiates a new connection to bitswap. +func (bs *Bitswap) PeerConnected(p peer.ID) { + bs.wm.Connected(p) + bs.engine.PeerConnected(p) +} + +// PeerDisconnected is called by the network interface when a peer +// closes a connection +func (bs *Bitswap) PeerDisconnected(p peer.ID) { + bs.wm.Disconnected(p) + bs.engine.PeerDisconnected(p) +} + +// ReceiveError is called by the network interface when an error happens +// at the network layer. Currently just logs error. +func (bs *Bitswap) ReceiveError(err error) { + log.Infof("Bitswap ReceiveError: %s", err) + // TODO log the network error + // TODO bubble the network error up to the parent context/error logger +} + +// Close is called to shutdown Bitswap +func (bs *Bitswap) Close() error { + return bs.process.Close() +} + +// GetWantlist returns the current local wantlist. +func (bs *Bitswap) GetWantlist() []cid.Cid { + entries := bs.wm.CurrentWants() + out := make([]cid.Cid, 0, len(entries)) + for _, e := range entries { + out = append(out, e.Cid) + } + return out +} + +// IsOnline is needed to match go-ipfs-exchange-interface +func (bs *Bitswap) IsOnline() bool { + return true +} + +// NewSession generates a new Bitswap session. You should use this, rather +// that calling Bitswap.GetBlocks, any time you intend to do several related +// block requests in a row. The session returned will have it's own GetBlocks +// method, but the session will use the fact that the requests are related to +// be more efficient in its requests to peers. If you are using a session +// from go-blockservice, it will create a bitswap session automatically. +func (bs *Bitswap) NewSession(ctx context.Context) exchange.Fetcher { + return bs.sm.NewSession(ctx, bs.provSearchDelay, bs.rebroadcastDelay) +} diff --git a/vendor/github.com/ipfs/go-bitswap/decision/engine.go b/vendor/github.com/ipfs/go-bitswap/decision/engine.go new file mode 100644 index 00000000..61bb4ca1 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/decision/engine.go @@ -0,0 +1,424 @@ +// Package decision implements the decision engine for the bitswap service. +package decision + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/google/uuid" + bsmsg "github.com/ipfs/go-bitswap/message" + wl "github.com/ipfs/go-bitswap/wantlist" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + bstore "github.com/ipfs/go-ipfs-blockstore" + logging "github.com/ipfs/go-log" + "github.com/ipfs/go-peertaskqueue" + "github.com/ipfs/go-peertaskqueue/peertask" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// TODO consider taking responsibility for other types of requests. For +// example, there could be a |cancelQueue| for all of the cancellation +// messages that need to go out. There could also be a |wantlistQueue| for +// the local peer's wantlists. Alternatively, these could all be bundled +// into a single, intelligent global queue that efficiently +// batches/combines and takes all of these into consideration. +// +// Right now, messages go onto the network for four reasons: +// 1. an initial `sendwantlist` message to a provider of the first key in a +// request +// 2. a periodic full sweep of `sendwantlist` messages to all providers +// 3. upon receipt of blocks, a `cancel` message to all peers +// 4. draining the priority queue of `blockrequests` from peers +// +// Presently, only `blockrequests` are handled by the decision engine. +// However, there is an opportunity to give it more responsibility! If the +// decision engine is given responsibility for all of the others, it can +// intelligently decide how to combine requests efficiently. +// +// Some examples of what would be possible: +// +// * when sending out the wantlists, include `cancel` requests +// * when handling `blockrequests`, include `sendwantlist` and `cancel` as +// appropriate +// * when handling `cancel`, if we recently received a wanted block from a +// peer, include a partial wantlist that contains a few other high priority +// blocks +// +// In a sense, if we treat the decision engine as a black box, it could do +// whatever it sees fit to produce desired outcomes (get wanted keys +// quickly, maintain good relationships with peers, etc). + +var log = logging.Logger("engine") + +const ( + // outboxChanBuffer must be 0 to prevent stale messages from being sent + outboxChanBuffer = 0 + // maxMessageSize is the maximum size of the batched payload + maxMessageSize = 512 * 1024 + // tagPrefix is the tag given to peers associated an engine + tagPrefix = "bs-engine-%s" + + // tagWeight is the default weight for peers associated with an engine + tagWeight = 5 +) + +// Envelope contains a message for a Peer. +type Envelope struct { + // Peer is the intended recipient. + Peer peer.ID + + // Message is the payload. + Message bsmsg.BitSwapMessage + + // A callback to notify the decision queue that the task is complete + Sent func() +} + +// PeerTagger covers the methods on the connection manager used by the decision +// engine to tag peers +type PeerTagger interface { + TagPeer(peer.ID, string, int) + UntagPeer(p peer.ID, tag string) +} + +// Engine manages sending requested blocks to peers. +type Engine struct { + // peerRequestQueue is a priority queue of requests received from peers. + // Requests are popped from the queue, packaged up, and placed in the + // outbox. + peerRequestQueue *peertaskqueue.PeerTaskQueue + + // FIXME it's a bit odd for the client and the worker to both share memory + // (both modify the peerRequestQueue) and also to communicate over the + // workSignal channel. consider sending requests over the channel and + // allowing the worker to have exclusive access to the peerRequestQueue. In + // that case, no lock would be required. + workSignal chan struct{} + + // outbox contains outgoing messages to peers. This is owned by the + // taskWorker goroutine + outbox chan (<-chan *Envelope) + + bs bstore.Blockstore + + peerTagger PeerTagger + + tag string + lock sync.Mutex // protects the fields immediatly below + // ledgerMap lists Ledgers by their Partner key. + ledgerMap map[peer.ID]*ledger + + ticker *time.Ticker +} + +// NewEngine creates a new block sending engine for the given block store +func NewEngine(ctx context.Context, bs bstore.Blockstore, peerTagger PeerTagger) *Engine { + e := &Engine{ + ledgerMap: make(map[peer.ID]*ledger), + bs: bs, + peerTagger: peerTagger, + outbox: make(chan (<-chan *Envelope), outboxChanBuffer), + workSignal: make(chan struct{}, 1), + ticker: time.NewTicker(time.Millisecond * 100), + } + e.tag = fmt.Sprintf(tagPrefix, uuid.New().String()) + e.peerRequestQueue = peertaskqueue.New(peertaskqueue.OnPeerAddedHook(e.onPeerAdded), peertaskqueue.OnPeerRemovedHook(e.onPeerRemoved)) + go e.taskWorker(ctx) + return e +} + +func (e *Engine) onPeerAdded(p peer.ID) { + e.peerTagger.TagPeer(p, e.tag, tagWeight) +} + +func (e *Engine) onPeerRemoved(p peer.ID) { + e.peerTagger.UntagPeer(p, e.tag) +} + +// WantlistForPeer returns the currently understood want list for a given peer +func (e *Engine) WantlistForPeer(p peer.ID) (out []wl.Entry) { + partner := e.findOrCreate(p) + partner.lk.Lock() + defer partner.lk.Unlock() + return partner.wantList.SortedEntries() +} + +// LedgerForPeer returns aggregated data about blocks swapped and communication +// with a given peer. +func (e *Engine) LedgerForPeer(p peer.ID) *Receipt { + ledger := e.findOrCreate(p) + + ledger.lk.Lock() + defer ledger.lk.Unlock() + + return &Receipt{ + Peer: ledger.Partner.String(), + Value: ledger.Accounting.Value(), + Sent: ledger.Accounting.BytesSent, + Recv: ledger.Accounting.BytesRecv, + Exchanged: ledger.ExchangeCount(), + } +} + +func (e *Engine) taskWorker(ctx context.Context) { + defer close(e.outbox) // because taskWorker uses the channel exclusively + for { + oneTimeUse := make(chan *Envelope, 1) // buffer to prevent blocking + select { + case <-ctx.Done(): + return + case e.outbox <- oneTimeUse: + } + // receiver is ready for an outoing envelope. let's prepare one. first, + // we must acquire a task from the PQ... + envelope, err := e.nextEnvelope(ctx) + if err != nil { + close(oneTimeUse) + return // ctx cancelled + } + oneTimeUse <- envelope // buffered. won't block + close(oneTimeUse) + } +} + +// nextEnvelope runs in the taskWorker goroutine. Returns an error if the +// context is cancelled before the next Envelope can be created. +func (e *Engine) nextEnvelope(ctx context.Context) (*Envelope, error) { + for { + nextTask := e.peerRequestQueue.PopBlock() + for nextTask == nil { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-e.workSignal: + nextTask = e.peerRequestQueue.PopBlock() + case <-e.ticker.C: + e.peerRequestQueue.ThawRound() + nextTask = e.peerRequestQueue.PopBlock() + } + } + + // with a task in hand, we're ready to prepare the envelope... + msg := bsmsg.New(true) + for _, entry := range nextTask.Tasks { + block, err := e.bs.Get(entry.Identifier.(cid.Cid)) + if err != nil { + log.Errorf("tried to execute a task and errored fetching block: %s", err) + continue + } + msg.AddBlock(block) + } + + if msg.Empty() { + // If we don't have the block, don't hold that against the peer + // make sure to update that the task has been 'completed' + nextTask.Done(nextTask.Tasks) + continue + } + + return &Envelope{ + Peer: nextTask.Target, + Message: msg, + Sent: func() { + nextTask.Done(nextTask.Tasks) + select { + case e.workSignal <- struct{}{}: + // work completing may mean that our queue will provide new + // work to be done. + default: + } + }, + }, nil + } +} + +// Outbox returns a channel of one-time use Envelope channels. +func (e *Engine) Outbox() <-chan (<-chan *Envelope) { + return e.outbox +} + +// Peers returns a slice of Peers with whom the local node has active sessions. +func (e *Engine) Peers() []peer.ID { + e.lock.Lock() + defer e.lock.Unlock() + + response := make([]peer.ID, 0, len(e.ledgerMap)) + + for _, ledger := range e.ledgerMap { + response = append(response, ledger.Partner) + } + return response +} + +// MessageReceived performs book-keeping. Returns error if passed invalid +// arguments. +func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) { + if m.Empty() { + log.Debugf("received empty message from %s", p) + } + + newWorkExists := false + defer func() { + if newWorkExists { + e.signalNewWork() + } + }() + + l := e.findOrCreate(p) + l.lk.Lock() + defer l.lk.Unlock() + if m.Full() { + l.wantList = wl.New() + } + + var msgSize int + var activeEntries []peertask.Task + for _, entry := range m.Wantlist() { + if entry.Cancel { + log.Debugf("%s cancel %s", p, entry.Cid) + l.CancelWant(entry.Cid) + e.peerRequestQueue.Remove(entry.Cid, p) + } else { + log.Debugf("wants %s - %d", entry.Cid, entry.Priority) + l.Wants(entry.Cid, entry.Priority) + blockSize, err := e.bs.GetSize(entry.Cid) + if err != nil { + if err == bstore.ErrNotFound { + continue + } + log.Error(err) + } else { + // we have the block + newWorkExists = true + if msgSize+blockSize > maxMessageSize { + e.peerRequestQueue.PushBlock(p, activeEntries...) + activeEntries = []peertask.Task{} + msgSize = 0 + } + activeEntries = append(activeEntries, peertask.Task{Identifier: entry.Cid, Priority: entry.Priority}) + msgSize += blockSize + } + } + } + if len(activeEntries) > 0 { + e.peerRequestQueue.PushBlock(p, activeEntries...) + } + for _, block := range m.Blocks() { + log.Debugf("got block %s %d bytes", block, len(block.RawData())) + l.ReceivedBytes(len(block.RawData())) + } +} + +func (e *Engine) addBlock(block blocks.Block) { + work := false + + for _, l := range e.ledgerMap { + l.lk.Lock() + if entry, ok := l.WantListContains(block.Cid()); ok { + e.peerRequestQueue.PushBlock(l.Partner, peertask.Task{ + Identifier: entry.Cid, + Priority: entry.Priority, + }) + work = true + } + l.lk.Unlock() + } + + if work { + e.signalNewWork() + } +} + +// AddBlock is called to when a new block is received and added to a block store +// meaning there may be peers who want that block that we should send it to. +func (e *Engine) AddBlock(block blocks.Block) { + e.lock.Lock() + defer e.lock.Unlock() + + e.addBlock(block) +} + +// TODO add contents of m.WantList() to my local wantlist? NB: could introduce +// race conditions where I send a message, but MessageSent gets handled after +// MessageReceived. The information in the local wantlist could become +// inconsistent. Would need to ensure that Sends and acknowledgement of the +// send happen atomically + +// MessageSent is called when a message has successfully been sent out, to record +// changes. +func (e *Engine) MessageSent(p peer.ID, m bsmsg.BitSwapMessage) { + l := e.findOrCreate(p) + l.lk.Lock() + defer l.lk.Unlock() + + for _, block := range m.Blocks() { + l.SentBytes(len(block.RawData())) + l.wantList.Remove(block.Cid()) + e.peerRequestQueue.Remove(block.Cid(), p) + } + +} + +// PeerConnected is called when a new peer connects, meaning we should start +// sending blocks. +func (e *Engine) PeerConnected(p peer.ID) { + e.lock.Lock() + defer e.lock.Unlock() + l, ok := e.ledgerMap[p] + if !ok { + l = newLedger(p) + e.ledgerMap[p] = l + } + l.lk.Lock() + defer l.lk.Unlock() + l.ref++ +} + +// PeerDisconnected is called when a peer disconnects. +func (e *Engine) PeerDisconnected(p peer.ID) { + e.lock.Lock() + defer e.lock.Unlock() + l, ok := e.ledgerMap[p] + if !ok { + return + } + l.lk.Lock() + defer l.lk.Unlock() + l.ref-- + if l.ref <= 0 { + delete(e.ledgerMap, p) + } +} + +func (e *Engine) numBytesSentTo(p peer.ID) uint64 { + // NB not threadsafe + return e.findOrCreate(p).Accounting.BytesSent +} + +func (e *Engine) numBytesReceivedFrom(p peer.ID) uint64 { + // NB not threadsafe + return e.findOrCreate(p).Accounting.BytesRecv +} + +// ledger lazily instantiates a ledger +func (e *Engine) findOrCreate(p peer.ID) *ledger { + e.lock.Lock() + defer e.lock.Unlock() + l, ok := e.ledgerMap[p] + if !ok { + l = newLedger(p) + e.ledgerMap[p] = l + } + return l +} + +func (e *Engine) signalNewWork() { + // Signal task generation to restart (if stopped!) + select { + case e.workSignal <- struct{}{}: + default: + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/decision/ledger.go b/vendor/github.com/ipfs/go-bitswap/decision/ledger.go new file mode 100644 index 00000000..12eca63b --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/decision/ledger.go @@ -0,0 +1,97 @@ +package decision + +import ( + "sync" + "time" + + wl "github.com/ipfs/go-bitswap/wantlist" + + cid "github.com/ipfs/go-cid" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +func newLedger(p peer.ID) *ledger { + return &ledger{ + wantList: wl.New(), + Partner: p, + sentToPeer: make(map[string]time.Time), + } +} + +// ledger stores the data exchange relationship between two peers. +// NOT threadsafe +type ledger struct { + // Partner is the remote Peer. + Partner peer.ID + + // Accounting tracks bytes sent and received. + Accounting debtRatio + + // lastExchange is the time of the last data exchange. + lastExchange time.Time + + // exchangeCount is the number of exchanges with this peer + exchangeCount uint64 + + // wantList is a (bounded, small) set of keys that Partner desires. + wantList *wl.Wantlist + + // sentToPeer is a set of keys to ensure we dont send duplicate blocks + // to a given peer + sentToPeer map[string]time.Time + + // ref is the reference count for this ledger, its used to ensure we + // don't drop the reference to this ledger in multi-connection scenarios + ref int + + lk sync.Mutex +} + +// Receipt is a summary of the ledger for a given peer +// collecting various pieces of aggregated data for external +// reporting purposes. +type Receipt struct { + Peer string + Value float64 + Sent uint64 + Recv uint64 + Exchanged uint64 +} + +type debtRatio struct { + BytesSent uint64 + BytesRecv uint64 +} + +func (dr *debtRatio) Value() float64 { + return float64(dr.BytesSent) / float64(dr.BytesRecv+1) +} + +func (l *ledger) SentBytes(n int) { + l.exchangeCount++ + l.lastExchange = time.Now() + l.Accounting.BytesSent += uint64(n) +} + +func (l *ledger) ReceivedBytes(n int) { + l.exchangeCount++ + l.lastExchange = time.Now() + l.Accounting.BytesRecv += uint64(n) +} + +func (l *ledger) Wants(k cid.Cid, priority int) { + log.Debugf("peer %s wants %s", l.Partner, k) + l.wantList.Add(k, priority) +} + +func (l *ledger) CancelWant(k cid.Cid) { + l.wantList.Remove(k) +} + +func (l *ledger) WantListContains(k cid.Cid) (wl.Entry, bool) { + return l.wantList.Contains(k) +} + +func (l *ledger) ExchangeCount() uint64 { + return l.exchangeCount +} diff --git a/vendor/github.com/ipfs/go-bitswap/getter/getter.go b/vendor/github.com/ipfs/go-bitswap/getter/getter.go new file mode 100644 index 00000000..4f1c29db --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/getter/getter.go @@ -0,0 +1,112 @@ +package getter + +import ( + "context" + "errors" + + notifications "github.com/ipfs/go-bitswap/notifications" + logging "github.com/ipfs/go-log" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" +) + +var log = logging.Logger("bitswap") + +// GetBlocksFunc is any function that can take an array of CIDs and return a +// channel of incoming blocks. +type GetBlocksFunc func(context.Context, []cid.Cid) (<-chan blocks.Block, error) + +// SyncGetBlock takes a block cid and an async function for getting several +// blocks that returns a channel, and uses that function to return the +// block syncronously. +func SyncGetBlock(p context.Context, k cid.Cid, gb GetBlocksFunc) (blocks.Block, error) { + if !k.Defined() { + log.Error("undefined cid in GetBlock") + return nil, blockstore.ErrNotFound + } + + // Any async work initiated by this function must end when this function + // returns. To ensure this, derive a new context. Note that it is okay to + // listen on parent in this scope, but NOT okay to pass |parent| to + // functions called by this one. Otherwise those functions won't return + // when this context's cancel func is executed. This is difficult to + // enforce. May this comment keep you safe. + ctx, cancel := context.WithCancel(p) + defer cancel() + + promise, err := gb(ctx, []cid.Cid{k}) + if err != nil { + return nil, err + } + + select { + case block, ok := <-promise: + if !ok { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + return nil, errors.New("promise channel was closed") + } + } + return block, nil + case <-p.Done(): + return nil, p.Err() + } +} + +// WantFunc is any function that can express a want for set of blocks. +type WantFunc func(context.Context, []cid.Cid) + +// AsyncGetBlocks take a set of block cids, a pubsub channel for incoming +// blocks, a want function, and a close function, +// and returns a channel of incoming blocks. +func AsyncGetBlocks(ctx context.Context, keys []cid.Cid, notif notifications.PubSub, want WantFunc, cwants func([]cid.Cid)) (<-chan blocks.Block, error) { + if len(keys) == 0 { + out := make(chan blocks.Block) + close(out) + return out, nil + } + + remaining := cid.NewSet() + promise := notif.Subscribe(ctx, keys...) + for _, k := range keys { + log.Event(ctx, "Bitswap.GetBlockRequest.Start", k) + remaining.Add(k) + } + + want(ctx, keys) + + out := make(chan blocks.Block) + go handleIncoming(ctx, remaining, promise, out, cwants) + return out, nil +} + +func handleIncoming(ctx context.Context, remaining *cid.Set, in <-chan blocks.Block, out chan blocks.Block, cfun func([]cid.Cid)) { + ctx, cancel := context.WithCancel(ctx) + defer func() { + cancel() + close(out) + // can't just defer this call on its own, arguments are resolved *when* the defer is created + cfun(remaining.Keys()) + }() + for { + select { + case blk, ok := <-in: + if !ok { + return + } + + remaining.Remove(blk.Cid()) + select { + case out <- blk: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/go.mod b/vendor/github.com/ipfs/go-bitswap/go.mod new file mode 100644 index 00000000..9fb78e7f --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/go.mod @@ -0,0 +1,39 @@ +module github.com/ipfs/go-bitswap + +require ( + github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 // indirect + github.com/cskr/pubsub v1.0.2 + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gogo/protobuf v1.2.1 + github.com/golang/protobuf v1.3.1 // indirect + github.com/google/uuid v1.1.1 + github.com/hashicorp/golang-lru v0.5.1 + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-detect-race v0.0.1 + github.com/ipfs/go-ipfs-blockstore v0.0.1 + github.com/ipfs/go-ipfs-blocksutil v0.0.1 + github.com/ipfs/go-ipfs-delay v0.0.1 + github.com/ipfs/go-ipfs-exchange-interface v0.0.1 + github.com/ipfs/go-ipfs-routing v0.1.0 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-metrics-interface v0.0.1 + github.com/ipfs/go-peertaskqueue v0.1.1 + github.com/jbenet/goprocess v0.1.3 + github.com/libp2p/go-libp2p v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.3 + github.com/libp2p/go-libp2p-loggables v0.1.0 + github.com/libp2p/go-libp2p-netutil v0.1.0 + github.com/libp2p/go-libp2p-testing v0.0.4 + github.com/libp2p/go-msgio v0.0.3 // indirect + github.com/mattn/go-colorable v0.1.2 // indirect + github.com/multiformats/go-multiaddr v0.0.4 + github.com/opentracing/opentracing-go v1.1.0 // indirect + golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect + golang.org/x/net v0.0.0-20190611141213-3f473d35a33a // indirect + golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae // indirect + golang.org/x/text v0.3.2 // indirect + gopkg.in/yaml.v2 v2.2.2 // indirect +) diff --git a/vendor/github.com/ipfs/go-bitswap/go.sum b/vendor/github.com/ipfs/go-bitswap/go.sum new file mode 100644 index 00000000..6740d9e1 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/go.sum @@ -0,0 +1,334 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 h1:4i3KsuVA0o0KoBxAC5x+MY7RbteiMK1V7gf/G08NGIQ= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.1.1 h1:+gPjbI+V3NktXZOqJA1kzbms2pYmhjgQQal0MzZrOAY= +github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.1 h1:52sB0TJuDk2nYMcMfHOKaPoaayDZjaYVCq6Vk1ejUTk= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= +github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0 h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2 h1:86uOwW+O6Uc7NbaK4diuLZo2/Ikvqw2rgyV03VcSbLE= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3 h1:+IonUYY0nJZLb5Fdv6a6DOjtGP1L8Bb3faamiI2q5FY= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3 h1:VsOlWispTivSsOMg70e0W77y6oiSBSRCyP6URrWvE04= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-bitswap/message/message.go b/vendor/github.com/ipfs/go-bitswap/message/message.go new file mode 100644 index 00000000..df44d112 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/message/message.go @@ -0,0 +1,251 @@ +package message + +import ( + "fmt" + "io" + + pb "github.com/ipfs/go-bitswap/message/pb" + wantlist "github.com/ipfs/go-bitswap/wantlist" + blocks "github.com/ipfs/go-block-format" + + ggio "github.com/gogo/protobuf/io" + cid "github.com/ipfs/go-cid" + + "github.com/libp2p/go-libp2p-core/network" +) + +// BitSwapMessage is the basic interface for interacting building, encoding, +// and decoding messages sent on the BitSwap protocol. +type BitSwapMessage interface { + // Wantlist returns a slice of unique keys that represent data wanted by + // the sender. + Wantlist() []Entry + + // Blocks returns a slice of unique blocks. + Blocks() []blocks.Block + + // AddEntry adds an entry to the Wantlist. + AddEntry(key cid.Cid, priority int) + + Cancel(key cid.Cid) + + Empty() bool + + // A full wantlist is an authoritative copy, a 'non-full' wantlist is a patch-set + Full() bool + + AddBlock(blocks.Block) + Exportable + + Loggable() map[string]interface{} +} + +// Exportable is an interface for structures than can be +// encoded in a bitswap protobuf. +type Exportable interface { + ToProtoV0() *pb.Message + ToProtoV1() *pb.Message + ToNetV0(w io.Writer) error + ToNetV1(w io.Writer) error +} + +type impl struct { + full bool + wantlist map[cid.Cid]*Entry + blocks map[cid.Cid]blocks.Block +} + +// New returns a new, empty bitswap message +func New(full bool) BitSwapMessage { + return newMsg(full) +} + +func newMsg(full bool) *impl { + return &impl{ + blocks: make(map[cid.Cid]blocks.Block), + wantlist: make(map[cid.Cid]*Entry), + full: full, + } +} + +// Entry is an wantlist entry in a Bitswap message (along with whether it's an +// add or cancel). +type Entry struct { + wantlist.Entry + Cancel bool +} + +func newMessageFromProto(pbm pb.Message) (BitSwapMessage, error) { + m := newMsg(pbm.Wantlist.Full) + for _, e := range pbm.Wantlist.Entries { + c, err := cid.Cast([]byte(e.Block)) + if err != nil { + return nil, fmt.Errorf("incorrectly formatted cid in wantlist: %s", err) + } + m.addEntry(c, int(e.Priority), e.Cancel) + } + + // deprecated + for _, d := range pbm.Blocks { + // CIDv0, sha256, protobuf only + b := blocks.NewBlock(d) + m.AddBlock(b) + } + // + + for _, b := range pbm.GetPayload() { + pref, err := cid.PrefixFromBytes(b.GetPrefix()) + if err != nil { + return nil, err + } + + c, err := pref.Sum(b.GetData()) + if err != nil { + return nil, err + } + + blk, err := blocks.NewBlockWithCid(b.GetData(), c) + if err != nil { + return nil, err + } + + m.AddBlock(blk) + } + + return m, nil +} + +func (m *impl) Full() bool { + return m.full +} + +func (m *impl) Empty() bool { + return len(m.blocks) == 0 && len(m.wantlist) == 0 +} + +func (m *impl) Wantlist() []Entry { + out := make([]Entry, 0, len(m.wantlist)) + for _, e := range m.wantlist { + out = append(out, *e) + } + return out +} + +func (m *impl) Blocks() []blocks.Block { + bs := make([]blocks.Block, 0, len(m.blocks)) + for _, block := range m.blocks { + bs = append(bs, block) + } + return bs +} + +func (m *impl) Cancel(k cid.Cid) { + delete(m.wantlist, k) + m.addEntry(k, 0, true) +} + +func (m *impl) AddEntry(k cid.Cid, priority int) { + m.addEntry(k, priority, false) +} + +func (m *impl) addEntry(c cid.Cid, priority int, cancel bool) { + e, exists := m.wantlist[c] + if exists { + e.Priority = priority + e.Cancel = cancel + } else { + m.wantlist[c] = &Entry{ + Entry: wantlist.Entry{ + Cid: c, + Priority: priority, + }, + Cancel: cancel, + } + } +} + +func (m *impl) AddBlock(b blocks.Block) { + m.blocks[b.Cid()] = b +} + +// FromNet generates a new BitswapMessage from incoming data on an io.Reader. +func FromNet(r io.Reader) (BitSwapMessage, error) { + pbr := ggio.NewDelimitedReader(r, network.MessageSizeMax) + return FromPBReader(pbr) +} + +// FromPBReader generates a new Bitswap message from a gogo-protobuf reader +func FromPBReader(pbr ggio.Reader) (BitSwapMessage, error) { + pb := new(pb.Message) + if err := pbr.ReadMsg(pb); err != nil { + return nil, err + } + + return newMessageFromProto(*pb) +} + +func (m *impl) ToProtoV0() *pb.Message { + pbm := new(pb.Message) + pbm.Wantlist.Entries = make([]pb.Message_Wantlist_Entry, 0, len(m.wantlist)) + for _, e := range m.wantlist { + pbm.Wantlist.Entries = append(pbm.Wantlist.Entries, pb.Message_Wantlist_Entry{ + Block: e.Cid.Bytes(), + Priority: int32(e.Priority), + Cancel: e.Cancel, + }) + } + pbm.Wantlist.Full = m.full + + blocks := m.Blocks() + pbm.Blocks = make([][]byte, 0, len(blocks)) + for _, b := range blocks { + pbm.Blocks = append(pbm.Blocks, b.RawData()) + } + return pbm +} + +func (m *impl) ToProtoV1() *pb.Message { + pbm := new(pb.Message) + pbm.Wantlist.Entries = make([]pb.Message_Wantlist_Entry, 0, len(m.wantlist)) + for _, e := range m.wantlist { + pbm.Wantlist.Entries = append(pbm.Wantlist.Entries, pb.Message_Wantlist_Entry{ + Block: e.Cid.Bytes(), + Priority: int32(e.Priority), + Cancel: e.Cancel, + }) + } + pbm.Wantlist.Full = m.full + + blocks := m.Blocks() + pbm.Payload = make([]pb.Message_Block, 0, len(blocks)) + for _, b := range blocks { + pbm.Payload = append(pbm.Payload, pb.Message_Block{ + Data: b.RawData(), + Prefix: b.Cid().Prefix().Bytes(), + }) + } + return pbm +} + +func (m *impl) ToNetV0(w io.Writer) error { + pbw := ggio.NewDelimitedWriter(w) + + return pbw.WriteMsg(m.ToProtoV0()) +} + +func (m *impl) ToNetV1(w io.Writer) error { + pbw := ggio.NewDelimitedWriter(w) + + return pbw.WriteMsg(m.ToProtoV1()) +} + +func (m *impl) Loggable() map[string]interface{} { + blocks := make([]string, 0, len(m.blocks)) + for _, v := range m.blocks { + blocks = append(blocks, v.Cid().String()) + } + return map[string]interface{}{ + "blocks": blocks, + "wants": m.Wantlist(), + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/message/pb/Makefile b/vendor/github.com/ipfs/go-bitswap/message/pb/Makefile new file mode 100644 index 00000000..df34e54b --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/message/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/ipfs/go-bitswap/message/pb/message.pb.go b/vendor/github.com/ipfs/go-bitswap/message/pb/message.pb.go new file mode 100644 index 00000000..34eacb29 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/message/pb/message.pb.go @@ -0,0 +1,1152 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: message.proto + +package bitswap_message_pb + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Message struct { + Wantlist Message_Wantlist `protobuf:"bytes,1,opt,name=wantlist,proto3" json:"wantlist"` + Blocks [][]byte `protobuf:"bytes,2,rep,name=blocks,proto3" json:"blocks,omitempty"` + Payload []Message_Block `protobuf:"bytes,3,rep,name=payload,proto3" json:"payload"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{0} +} +func (m *Message) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) +} +func (m *Message) XXX_Size() int { + return m.Size() +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetWantlist() Message_Wantlist { + if m != nil { + return m.Wantlist + } + return Message_Wantlist{} +} + +func (m *Message) GetBlocks() [][]byte { + if m != nil { + return m.Blocks + } + return nil +} + +func (m *Message) GetPayload() []Message_Block { + if m != nil { + return m.Payload + } + return nil +} + +type Message_Wantlist struct { + Entries []Message_Wantlist_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"` + Full bool `protobuf:"varint,2,opt,name=full,proto3" json:"full,omitempty"` +} + +func (m *Message_Wantlist) Reset() { *m = Message_Wantlist{} } +func (m *Message_Wantlist) String() string { return proto.CompactTextString(m) } +func (*Message_Wantlist) ProtoMessage() {} +func (*Message_Wantlist) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{0, 0} +} +func (m *Message_Wantlist) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_Wantlist) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_Wantlist.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_Wantlist) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_Wantlist.Merge(m, src) +} +func (m *Message_Wantlist) XXX_Size() int { + return m.Size() +} +func (m *Message_Wantlist) XXX_DiscardUnknown() { + xxx_messageInfo_Message_Wantlist.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_Wantlist proto.InternalMessageInfo + +func (m *Message_Wantlist) GetEntries() []Message_Wantlist_Entry { + if m != nil { + return m.Entries + } + return nil +} + +func (m *Message_Wantlist) GetFull() bool { + if m != nil { + return m.Full + } + return false +} + +type Message_Wantlist_Entry struct { + Block []byte `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"` + Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"` + Cancel bool `protobuf:"varint,3,opt,name=cancel,proto3" json:"cancel,omitempty"` +} + +func (m *Message_Wantlist_Entry) Reset() { *m = Message_Wantlist_Entry{} } +func (m *Message_Wantlist_Entry) String() string { return proto.CompactTextString(m) } +func (*Message_Wantlist_Entry) ProtoMessage() {} +func (*Message_Wantlist_Entry) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{0, 0, 0} +} +func (m *Message_Wantlist_Entry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_Wantlist_Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_Wantlist_Entry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_Wantlist_Entry) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_Wantlist_Entry.Merge(m, src) +} +func (m *Message_Wantlist_Entry) XXX_Size() int { + return m.Size() +} +func (m *Message_Wantlist_Entry) XXX_DiscardUnknown() { + xxx_messageInfo_Message_Wantlist_Entry.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_Wantlist_Entry proto.InternalMessageInfo + +func (m *Message_Wantlist_Entry) GetBlock() []byte { + if m != nil { + return m.Block + } + return nil +} + +func (m *Message_Wantlist_Entry) GetPriority() int32 { + if m != nil { + return m.Priority + } + return 0 +} + +func (m *Message_Wantlist_Entry) GetCancel() bool { + if m != nil { + return m.Cancel + } + return false +} + +type Message_Block struct { + Prefix []byte `protobuf:"bytes,1,opt,name=prefix,proto3" json:"prefix,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *Message_Block) Reset() { *m = Message_Block{} } +func (m *Message_Block) String() string { return proto.CompactTextString(m) } +func (*Message_Block) ProtoMessage() {} +func (*Message_Block) Descriptor() ([]byte, []int) { + return fileDescriptor_33c57e4bae7b9afd, []int{0, 1} +} +func (m *Message_Block) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_Block.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_Block) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_Block.Merge(m, src) +} +func (m *Message_Block) XXX_Size() int { + return m.Size() +} +func (m *Message_Block) XXX_DiscardUnknown() { + xxx_messageInfo_Message_Block.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_Block proto.InternalMessageInfo + +func (m *Message_Block) GetPrefix() []byte { + if m != nil { + return m.Prefix + } + return nil +} + +func (m *Message_Block) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func init() { + proto.RegisterType((*Message)(nil), "bitswap.message.pb.Message") + proto.RegisterType((*Message_Wantlist)(nil), "bitswap.message.pb.Message.Wantlist") + proto.RegisterType((*Message_Wantlist_Entry)(nil), "bitswap.message.pb.Message.Wantlist.Entry") + proto.RegisterType((*Message_Block)(nil), "bitswap.message.pb.Message.Block") +} + +func init() { proto.RegisterFile("message.proto", fileDescriptor_33c57e4bae7b9afd) } + +var fileDescriptor_33c57e4bae7b9afd = []byte{ + // 335 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcf, 0x4a, 0xf3, 0x40, + 0x14, 0xc5, 0x33, 0x4d, 0xd3, 0x86, 0xdb, 0x7e, 0x9b, 0xe1, 0x43, 0x86, 0x2c, 0x62, 0x14, 0x17, + 0x41, 0x70, 0x0a, 0xed, 0x13, 0x58, 0xd0, 0x85, 0xe0, 0xc2, 0x6c, 0x5c, 0x4f, 0xd2, 0x34, 0x0e, + 0xa6, 0x99, 0x90, 0x4c, 0xa9, 0x7d, 0x0b, 0x5f, 0xc1, 0x07, 0x71, 0xdf, 0x65, 0x97, 0xae, 0x44, + 0xda, 0x17, 0x91, 0xdc, 0x4e, 0xb3, 0x11, 0xc4, 0xdd, 0x3d, 0xc3, 0x39, 0xbf, 0xfb, 0x67, 0xe0, + 0xdf, 0x22, 0xad, 0x6b, 0x91, 0xa5, 0xbc, 0xac, 0x94, 0x56, 0x94, 0xc6, 0x52, 0xd7, 0x2b, 0x51, + 0xf2, 0xf6, 0x39, 0xf6, 0xae, 0x32, 0xa9, 0x9f, 0x96, 0x31, 0x4f, 0xd4, 0x62, 0x94, 0xa9, 0x4c, + 0x8d, 0xd0, 0x1a, 0x2f, 0xe7, 0xa8, 0x50, 0x60, 0x75, 0x40, 0x9c, 0xbf, 0xd9, 0xd0, 0xbf, 0x3f, + 0xa4, 0xe9, 0x2d, 0xb8, 0x2b, 0x51, 0xe8, 0x5c, 0xd6, 0x9a, 0x91, 0x80, 0x84, 0x83, 0xf1, 0x05, + 0xff, 0xd9, 0x81, 0x1b, 0x3b, 0x7f, 0x34, 0xde, 0x69, 0x77, 0xf3, 0x79, 0x6a, 0x45, 0x6d, 0x96, + 0x9e, 0x40, 0x2f, 0xce, 0x55, 0xf2, 0x5c, 0xb3, 0x4e, 0x60, 0x87, 0xc3, 0xc8, 0x28, 0x7a, 0x0d, + 0xfd, 0x52, 0xac, 0x73, 0x25, 0x66, 0xcc, 0x0e, 0xec, 0x70, 0x30, 0x3e, 0xfb, 0x0d, 0x3f, 0x6d, + 0x42, 0x86, 0x7d, 0xcc, 0x79, 0xef, 0x04, 0xdc, 0x63, 0x5f, 0x7a, 0x07, 0xfd, 0xb4, 0xd0, 0x95, + 0x4c, 0x6b, 0x46, 0x90, 0x77, 0xf9, 0x97, 0x71, 0xf9, 0x4d, 0xa1, 0xab, 0xf5, 0x11, 0x6c, 0x00, + 0x94, 0x42, 0x77, 0xbe, 0xcc, 0x73, 0xd6, 0x09, 0x48, 0xe8, 0x46, 0x58, 0x7b, 0x0f, 0xe0, 0xa0, + 0x97, 0xfe, 0x07, 0x07, 0x57, 0xc0, 0xab, 0x0c, 0xa3, 0x83, 0xa0, 0x1e, 0xb8, 0x65, 0x25, 0x55, + 0x25, 0xf5, 0x1a, 0x63, 0x4e, 0xd4, 0xea, 0xe6, 0x04, 0x89, 0x28, 0x92, 0x34, 0x67, 0x36, 0x02, + 0x8d, 0xf2, 0x26, 0xe0, 0xe0, 0x5e, 0x8d, 0xa1, 0xac, 0xd2, 0xb9, 0x7c, 0x31, 0x4c, 0xa3, 0x9a, + 0x39, 0x66, 0x42, 0x0b, 0x04, 0x0e, 0x23, 0xac, 0xa7, 0x6c, 0xb3, 0xf3, 0xc9, 0x76, 0xe7, 0x93, + 0xaf, 0x9d, 0x4f, 0x5e, 0xf7, 0xbe, 0xb5, 0xdd, 0xfb, 0xd6, 0xc7, 0xde, 0xb7, 0xe2, 0x1e, 0x7e, + 0xe2, 0xe4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x1d, 0x6e, 0x21, 0x18, 0x02, 0x00, 0x00, +} + +func (m *Message) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintMessage(dAtA, i, uint64(m.Wantlist.Size())) + n1, err := m.Wantlist.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + if len(m.Blocks) > 0 { + for _, b := range m.Blocks { + dAtA[i] = 0x12 + i++ + i = encodeVarintMessage(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if len(m.Payload) > 0 { + for _, msg := range m.Payload { + dAtA[i] = 0x1a + i++ + i = encodeVarintMessage(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *Message_Wantlist) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_Wantlist) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Entries) > 0 { + for _, msg := range m.Entries { + dAtA[i] = 0xa + i++ + i = encodeVarintMessage(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.Full { + dAtA[i] = 0x10 + i++ + if m.Full { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func (m *Message_Wantlist_Entry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_Wantlist_Entry) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Block) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintMessage(dAtA, i, uint64(len(m.Block))) + i += copy(dAtA[i:], m.Block) + } + if m.Priority != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintMessage(dAtA, i, uint64(m.Priority)) + } + if m.Cancel { + dAtA[i] = 0x18 + i++ + if m.Cancel { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func (m *Message_Block) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_Block) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Prefix) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintMessage(dAtA, i, uint64(len(m.Prefix))) + i += copy(dAtA[i:], m.Prefix) + } + if len(m.Data) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintMessage(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + +func encodeVarintMessage(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Message) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Wantlist.Size() + n += 1 + l + sovMessage(uint64(l)) + if len(m.Blocks) > 0 { + for _, b := range m.Blocks { + l = len(b) + n += 1 + l + sovMessage(uint64(l)) + } + } + if len(m.Payload) > 0 { + for _, e := range m.Payload { + l = e.Size() + n += 1 + l + sovMessage(uint64(l)) + } + } + return n +} + +func (m *Message_Wantlist) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovMessage(uint64(l)) + } + } + if m.Full { + n += 2 + } + return n +} + +func (m *Message_Wantlist_Entry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Block) + if l > 0 { + n += 1 + l + sovMessage(uint64(l)) + } + if m.Priority != 0 { + n += 1 + sovMessage(uint64(m.Priority)) + } + if m.Cancel { + n += 2 + } + return n +} + +func (m *Message_Block) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Prefix) + if l > 0 { + n += 1 + l + sovMessage(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovMessage(uint64(l)) + } + return n +} + +func sovMessage(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozMessage(x uint64) (n int) { + return sovMessage(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Message) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Wantlist", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Wantlist.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blocks", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Blocks = append(m.Blocks, make([]byte, postIndex-iNdEx)) + copy(m.Blocks[len(m.Blocks)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload, Message_Block{}) + if err := m.Payload[len(m.Payload)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_Wantlist) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Wantlist: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Wantlist: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, Message_Wantlist_Entry{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Full", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Full = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_Wantlist_Entry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Entry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Block", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Block = append(m.Block[:0], dAtA[iNdEx:postIndex]...) + if m.Block == nil { + m.Block = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + m.Priority = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Priority |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cancel", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Cancel = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_Block) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Block: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Block: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prefix", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prefix = append(m.Prefix[:0], dAtA[iNdEx:postIndex]...) + if m.Prefix == nil { + m.Prefix = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMessage(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthMessage + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthMessage + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipMessage(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthMessage + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthMessage = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMessage = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-bitswap/message/pb/message.proto b/vendor/github.com/ipfs/go-bitswap/message/pb/message.proto new file mode 100644 index 00000000..102b3431 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/message/pb/message.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package bitswap.message.pb; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +message Message { + + message Wantlist { + + message Entry { + bytes block = 1; // the block cid (cidV0 in bitswap 1.0.0, cidV1 in bitswap 1.1.0) + int32 priority = 2; // the priority (normalized). default to 1 + bool cancel = 3; // whether this revokes an entry + } + + repeated Entry entries = 1 [(gogoproto.nullable) = false]; // a list of wantlist entries + bool full = 2; // whether this is the full wantlist. default to false + } + + message Block { + bytes prefix = 1; // CID prefix (cid version, multicodec and multihash prefix (type + length) + bytes data = 2; + } + + Wantlist wantlist = 1 [(gogoproto.nullable) = false]; + repeated bytes blocks = 2; // used to send Blocks in bitswap 1.0.0 + repeated Block payload = 3 [(gogoproto.nullable) = false]; // used to send Blocks in bitswap 1.1.0 +} diff --git a/vendor/github.com/ipfs/go-bitswap/messagequeue/messagequeue.go b/vendor/github.com/ipfs/go-bitswap/messagequeue/messagequeue.go new file mode 100644 index 00000000..9e472424 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/messagequeue/messagequeue.go @@ -0,0 +1,273 @@ +package messagequeue + +import ( + "context" + "sync" + "time" + + bsmsg "github.com/ipfs/go-bitswap/message" + bsnet "github.com/ipfs/go-bitswap/network" + wantlist "github.com/ipfs/go-bitswap/wantlist" + logging "github.com/ipfs/go-log" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("bitswap") + +const ( + defaultRebroadcastInterval = 30 * time.Second + maxRetries = 10 +) + +// MessageNetwork is any network that can connect peers and generate a message +// sender. +type MessageNetwork interface { + ConnectTo(context.Context, peer.ID) error + NewMessageSender(context.Context, peer.ID) (bsnet.MessageSender, error) +} + +// MessageQueue implements queue of want messages to send to peers. +type MessageQueue struct { + ctx context.Context + p peer.ID + network MessageNetwork + + outgoingWork chan struct{} + done chan struct{} + + // do not touch out of run loop + wl *wantlist.SessionTrackedWantlist + nextMessage bsmsg.BitSwapMessage + nextMessageLk sync.RWMutex + sender bsnet.MessageSender + rebroadcastIntervalLk sync.RWMutex + rebroadcastInterval time.Duration + rebroadcastTimer *time.Timer +} + +// New creats a new MessageQueue. +func New(ctx context.Context, p peer.ID, network MessageNetwork) *MessageQueue { + return &MessageQueue{ + ctx: ctx, + wl: wantlist.NewSessionTrackedWantlist(), + network: network, + p: p, + outgoingWork: make(chan struct{}, 1), + done: make(chan struct{}), + rebroadcastInterval: defaultRebroadcastInterval, + } +} + +// AddMessage adds new entries to an outgoing message for a given session. +func (mq *MessageQueue) AddMessage(entries []bsmsg.Entry, ses uint64) { + if !mq.addEntries(entries, ses) { + return + } + select { + case mq.outgoingWork <- struct{}{}: + default: + } +} + +// AddWantlist adds a complete session tracked want list to a message queue +func (mq *MessageQueue) AddWantlist(initialWants *wantlist.SessionTrackedWantlist) { + initialWants.CopyWants(mq.wl) + mq.addWantlist() +} + +// SetRebroadcastInterval sets a new interval on which to rebroadcast the full wantlist +func (mq *MessageQueue) SetRebroadcastInterval(delay time.Duration) { + mq.rebroadcastIntervalLk.Lock() + mq.rebroadcastInterval = delay + if mq.rebroadcastTimer != nil { + mq.rebroadcastTimer.Reset(delay) + } + mq.rebroadcastIntervalLk.Unlock() +} + +// Startup starts the processing of messages, and creates an initial message +// based on the given initial wantlist. +func (mq *MessageQueue) Startup() { + mq.rebroadcastIntervalLk.RLock() + mq.rebroadcastTimer = time.NewTimer(mq.rebroadcastInterval) + mq.rebroadcastIntervalLk.RUnlock() + go mq.runQueue() +} + +// Shutdown stops the processing of messages for a message queue. +func (mq *MessageQueue) Shutdown() { + close(mq.done) +} + +func (mq *MessageQueue) runQueue() { + for { + select { + case <-mq.rebroadcastTimer.C: + mq.rebroadcastWantlist() + case <-mq.outgoingWork: + mq.sendMessage() + case <-mq.done: + if mq.sender != nil { + mq.sender.Close() + } + return + case <-mq.ctx.Done(): + if mq.sender != nil { + mq.sender.Reset() + } + return + } + } +} + +func (mq *MessageQueue) addWantlist() { + + mq.nextMessageLk.Lock() + defer mq.nextMessageLk.Unlock() + + if mq.wl.Len() > 0 { + if mq.nextMessage == nil { + mq.nextMessage = bsmsg.New(false) + } + for _, e := range mq.wl.Entries() { + mq.nextMessage.AddEntry(e.Cid, e.Priority) + } + select { + case mq.outgoingWork <- struct{}{}: + default: + } + } +} + +func (mq *MessageQueue) rebroadcastWantlist() { + mq.rebroadcastIntervalLk.RLock() + mq.rebroadcastTimer.Reset(mq.rebroadcastInterval) + mq.rebroadcastIntervalLk.RUnlock() + + mq.addWantlist() +} + +func (mq *MessageQueue) addEntries(entries []bsmsg.Entry, ses uint64) bool { + var work bool + mq.nextMessageLk.Lock() + defer mq.nextMessageLk.Unlock() + // if we have no message held allocate a new one + if mq.nextMessage == nil { + mq.nextMessage = bsmsg.New(false) + } + + for _, e := range entries { + if e.Cancel { + if mq.wl.Remove(e.Cid, ses) { + work = true + mq.nextMessage.Cancel(e.Cid) + } + } else { + if mq.wl.Add(e.Cid, e.Priority, ses) { + work = true + mq.nextMessage.AddEntry(e.Cid, e.Priority) + } + } + } + return work +} + +func (mq *MessageQueue) extractOutgoingMessage() bsmsg.BitSwapMessage { + // grab outgoing message + mq.nextMessageLk.Lock() + message := mq.nextMessage + mq.nextMessage = nil + mq.nextMessageLk.Unlock() + return message +} + +func (mq *MessageQueue) sendMessage() { + message := mq.extractOutgoingMessage() + if message == nil || message.Empty() { + return + } + + err := mq.initializeSender() + if err != nil { + log.Infof("cant open message sender to peer %s: %s", mq.p, err) + // TODO: cant connect, what now? + return + } + + for i := 0; i < maxRetries; i++ { // try to send this message until we fail. + if mq.attemptSendAndRecovery(message) { + return + } + } +} + +func (mq *MessageQueue) initializeSender() error { + if mq.sender != nil { + return nil + } + nsender, err := openSender(mq.ctx, mq.network, mq.p) + if err != nil { + return err + } + mq.sender = nsender + return nil +} + +func (mq *MessageQueue) attemptSendAndRecovery(message bsmsg.BitSwapMessage) bool { + err := mq.sender.SendMsg(mq.ctx, message) + if err == nil { + return true + } + + log.Infof("bitswap send error: %s", err) + mq.sender.Reset() + mq.sender = nil + + select { + case <-mq.done: + return true + case <-mq.ctx.Done(): + return true + case <-time.After(time.Millisecond * 100): + // wait 100ms in case disconnect notifications are still propogating + log.Warning("SendMsg errored but neither 'done' nor context.Done() were set") + } + + err = mq.initializeSender() + if err != nil { + log.Infof("couldnt open sender again after SendMsg(%s) failed: %s", mq.p, err) + // TODO(why): what do we do now? + // I think the *right* answer is to probably put the message we're + // trying to send back, and then return to waiting for new work or + // a disconnect. + return true + } + + // TODO: Is this the same instance for the remote peer? + // If its not, we should resend our entire wantlist to them + /* + if mq.sender.InstanceID() != mq.lastSeenInstanceID { + wlm = mq.getFullWantlistMessage() + } + */ + return false +} + +func openSender(ctx context.Context, network MessageNetwork, p peer.ID) (bsnet.MessageSender, error) { + // allow ten minutes for connections this includes looking them up in the + // dht dialing them, and handshaking + conctx, cancel := context.WithTimeout(ctx, time.Minute*10) + defer cancel() + + err := network.ConnectTo(conctx, p) + if err != nil { + return nil, err + } + + nsender, err := network.NewMessageSender(ctx, p) + if err != nil { + return nil, err + } + + return nsender, nil +} diff --git a/vendor/github.com/ipfs/go-bitswap/network/interface.go b/vendor/github.com/ipfs/go-bitswap/network/interface.go new file mode 100644 index 00000000..783e29e9 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/network/interface.go @@ -0,0 +1,87 @@ +package network + +import ( + "context" + + bsmsg "github.com/ipfs/go-bitswap/message" + + cid "github.com/ipfs/go-cid" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +var ( + // ProtocolBitswapOne is the prefix for the legacy bitswap protocol + ProtocolBitswapOne protocol.ID = "/ipfs/bitswap/1.0.0" + // ProtocolBitswapNoVers is equivalent to the legacy bitswap protocol + ProtocolBitswapNoVers protocol.ID = "/ipfs/bitswap" + + // ProtocolBitswap is the current version of bitswap protocol, 1.1.0 + ProtocolBitswap protocol.ID = "/ipfs/bitswap/1.1.0" +) + +// BitSwapNetwork provides network connectivity for BitSwap sessions. +type BitSwapNetwork interface { + + // SendMessage sends a BitSwap message to a peer. + SendMessage( + context.Context, + peer.ID, + bsmsg.BitSwapMessage) error + + // SetDelegate registers the Reciver to handle messages received from the + // network. + SetDelegate(Receiver) + + ConnectTo(context.Context, peer.ID) error + + NewMessageSender(context.Context, peer.ID) (MessageSender, error) + + ConnectionManager() connmgr.ConnManager + + Stats() Stats + + Routing +} + +// MessageSender is an interface for sending a series of messages over the bitswap +// network +type MessageSender interface { + SendMsg(context.Context, bsmsg.BitSwapMessage) error + Close() error + Reset() error +} + +// Receiver is an interface that can receive messages from the BitSwapNetwork. +type Receiver interface { + ReceiveMessage( + ctx context.Context, + sender peer.ID, + incoming bsmsg.BitSwapMessage) + + ReceiveError(error) + + // Connected/Disconnected warns bitswap about peer connections. + PeerConnected(peer.ID) + PeerDisconnected(peer.ID) +} + +// Routing is an interface to providing and finding providers on a bitswap +// network. +type Routing interface { + // FindProvidersAsync returns a channel of providers for the given key. + FindProvidersAsync(context.Context, cid.Cid, int) <-chan peer.ID + + // Provide provides the key to the network. + Provide(context.Context, cid.Cid) error +} + +// Stats is a container for statistics about the bitswap network +// the numbers inside are specific to bitswap, and not any other protocols +// using the same underlying network. +type Stats struct { + MessagesSent uint64 + MessagesRecvd uint64 +} diff --git a/vendor/github.com/ipfs/go-bitswap/network/ipfs_impl.go b/vendor/github.com/ipfs/go-bitswap/network/ipfs_impl.go new file mode 100644 index 00000000..2cfbbcbf --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/network/ipfs_impl.go @@ -0,0 +1,229 @@ +package network + +import ( + "context" + "fmt" + "io" + "sync/atomic" + "time" + + bsmsg "github.com/ipfs/go-bitswap/message" + "github.com/libp2p/go-libp2p-core/helpers" + + ggio "github.com/gogo/protobuf/io" + cid "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + peerstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/routing" + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("bitswap_network") + +var sendMessageTimeout = time.Minute * 10 + +// NewFromIpfsHost returns a BitSwapNetwork supported by underlying IPFS host. +func NewFromIpfsHost(host host.Host, r routing.ContentRouting) BitSwapNetwork { + bitswapNetwork := impl{ + host: host, + routing: r, + } + return &bitswapNetwork +} + +// impl transforms the ipfs network interface, which sends and receives +// NetMessage objects, into the bitswap network interface. +type impl struct { + host host.Host + routing routing.ContentRouting + + // inbound messages from the network are forwarded to the receiver + receiver Receiver + + stats Stats +} + +type streamMessageSender struct { + s network.Stream +} + +func (s *streamMessageSender) Close() error { + return helpers.FullClose(s.s) +} + +func (s *streamMessageSender) Reset() error { + return s.s.Reset() +} + +func (s *streamMessageSender) SendMsg(ctx context.Context, msg bsmsg.BitSwapMessage) error { + return msgToStream(ctx, s.s, msg) +} + +func msgToStream(ctx context.Context, s network.Stream, msg bsmsg.BitSwapMessage) error { + deadline := time.Now().Add(sendMessageTimeout) + if dl, ok := ctx.Deadline(); ok { + deadline = dl + } + + if err := s.SetWriteDeadline(deadline); err != nil { + log.Warningf("error setting deadline: %s", err) + } + + switch s.Protocol() { + case ProtocolBitswap: + if err := msg.ToNetV1(s); err != nil { + log.Debugf("error: %s", err) + return err + } + case ProtocolBitswapOne, ProtocolBitswapNoVers: + if err := msg.ToNetV0(s); err != nil { + log.Debugf("error: %s", err) + return err + } + default: + return fmt.Errorf("unrecognized protocol on remote: %s", s.Protocol()) + } + + if err := s.SetWriteDeadline(time.Time{}); err != nil { + log.Warningf("error resetting deadline: %s", err) + } + return nil +} + +func (bsnet *impl) NewMessageSender(ctx context.Context, p peer.ID) (MessageSender, error) { + s, err := bsnet.newStreamToPeer(ctx, p) + if err != nil { + return nil, err + } + + return &streamMessageSender{s: s}, nil +} + +func (bsnet *impl) newStreamToPeer(ctx context.Context, p peer.ID) (network.Stream, error) { + return bsnet.host.NewStream(ctx, p, ProtocolBitswap, ProtocolBitswapOne, ProtocolBitswapNoVers) +} + +func (bsnet *impl) SendMessage( + ctx context.Context, + p peer.ID, + outgoing bsmsg.BitSwapMessage) error { + + s, err := bsnet.newStreamToPeer(ctx, p) + if err != nil { + return err + } + + if err = msgToStream(ctx, s, outgoing); err != nil { + s.Reset() + return err + } + atomic.AddUint64(&bsnet.stats.MessagesSent, 1) + + // TODO(https://github.com/libp2p/go-libp2p-net/issues/28): Avoid this goroutine. + go helpers.AwaitEOF(s) + return s.Close() + +} + +func (bsnet *impl) SetDelegate(r Receiver) { + bsnet.receiver = r + bsnet.host.SetStreamHandler(ProtocolBitswap, bsnet.handleNewStream) + bsnet.host.SetStreamHandler(ProtocolBitswapOne, bsnet.handleNewStream) + bsnet.host.SetStreamHandler(ProtocolBitswapNoVers, bsnet.handleNewStream) + bsnet.host.Network().Notify((*netNotifiee)(bsnet)) + // TODO: StopNotify. + +} + +func (bsnet *impl) ConnectTo(ctx context.Context, p peer.ID) error { + return bsnet.host.Connect(ctx, peer.AddrInfo{ID: p}) +} + +// FindProvidersAsync returns a channel of providers for the given key. +func (bsnet *impl) FindProvidersAsync(ctx context.Context, k cid.Cid, max int) <-chan peer.ID { + out := make(chan peer.ID, max) + go func() { + defer close(out) + providers := bsnet.routing.FindProvidersAsync(ctx, k, max) + for info := range providers { + if info.ID == bsnet.host.ID() { + continue // ignore self as provider + } + bsnet.host.Peerstore().AddAddrs(info.ID, info.Addrs, peerstore.TempAddrTTL) + select { + case <-ctx.Done(): + return + case out <- info.ID: + } + } + }() + return out +} + +// Provide provides the key to the network +func (bsnet *impl) Provide(ctx context.Context, k cid.Cid) error { + return bsnet.routing.Provide(ctx, k, true) +} + +// handleNewStream receives a new stream from the network. +func (bsnet *impl) handleNewStream(s network.Stream) { + defer s.Close() + + if bsnet.receiver == nil { + s.Reset() + return + } + + reader := ggio.NewDelimitedReader(s, network.MessageSizeMax) + for { + received, err := bsmsg.FromPBReader(reader) + if err != nil { + if err != io.EOF { + s.Reset() + go bsnet.receiver.ReceiveError(err) + log.Debugf("bitswap net handleNewStream from %s error: %s", s.Conn().RemotePeer(), err) + } + return + } + + p := s.Conn().RemotePeer() + ctx := context.Background() + log.Debugf("bitswap net handleNewStream from %s", s.Conn().RemotePeer()) + bsnet.receiver.ReceiveMessage(ctx, p, received) + atomic.AddUint64(&bsnet.stats.MessagesRecvd, 1) + } +} + +func (bsnet *impl) ConnectionManager() connmgr.ConnManager { + return bsnet.host.ConnManager() +} + +func (bsnet *impl) Stats() Stats { + return Stats{ + MessagesRecvd: atomic.LoadUint64(&bsnet.stats.MessagesRecvd), + MessagesSent: atomic.LoadUint64(&bsnet.stats.MessagesSent), + } +} + +type netNotifiee impl + +func (nn *netNotifiee) impl() *impl { + return (*impl)(nn) +} + +func (nn *netNotifiee) Connected(n network.Network, v network.Conn) { + nn.impl().receiver.PeerConnected(v.RemotePeer()) +} + +func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) { + nn.impl().receiver.PeerDisconnected(v.RemotePeer()) +} + +func (nn *netNotifiee) OpenedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) ClosedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) Listen(n network.Network, a ma.Multiaddr) {} +func (nn *netNotifiee) ListenClose(n network.Network, a ma.Multiaddr) {} diff --git a/vendor/github.com/ipfs/go-bitswap/notifications/notifications.go b/vendor/github.com/ipfs/go-bitswap/notifications/notifications.go new file mode 100644 index 00000000..0934fa5f --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/notifications/notifications.go @@ -0,0 +1,135 @@ +package notifications + +import ( + "context" + "sync" + + pubsub "github.com/cskr/pubsub" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" +) + +const bufferSize = 16 + +// PubSub is a simple interface for publishing blocks and being able to subscribe +// for cids. It's used internally by bitswap to decouple receiving blocks +// and actually providing them back to the GetBlocks caller. +type PubSub interface { + Publish(block blocks.Block) + Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Block + Shutdown() +} + +// New generates a new PubSub interface. +func New() PubSub { + return &impl{ + wrapped: *pubsub.New(bufferSize), + closed: make(chan struct{}), + } +} + +type impl struct { + lk sync.RWMutex + wrapped pubsub.PubSub + + closed chan struct{} +} + +func (ps *impl) Publish(block blocks.Block) { + ps.lk.RLock() + defer ps.lk.RUnlock() + select { + case <-ps.closed: + return + default: + } + + ps.wrapped.Pub(block, block.Cid().KeyString()) +} + +func (ps *impl) Shutdown() { + ps.lk.Lock() + defer ps.lk.Unlock() + select { + case <-ps.closed: + return + default: + } + close(ps.closed) + ps.wrapped.Shutdown() +} + +// Subscribe returns a channel of blocks for the given |keys|. |blockChannel| +// is closed if the |ctx| times out or is cancelled, or after sending len(keys) +// blocks. +func (ps *impl) Subscribe(ctx context.Context, keys ...cid.Cid) <-chan blocks.Block { + + blocksCh := make(chan blocks.Block, len(keys)) + valuesCh := make(chan interface{}, len(keys)) // provide our own channel to control buffer, prevent blocking + if len(keys) == 0 { + close(blocksCh) + return blocksCh + } + + // prevent shutdown + ps.lk.RLock() + defer ps.lk.RUnlock() + + select { + case <-ps.closed: + close(blocksCh) + return blocksCh + default: + } + + ps.wrapped.AddSubOnceEach(valuesCh, toStrings(keys)...) + go func() { + defer func() { + close(blocksCh) + + ps.lk.RLock() + defer ps.lk.RUnlock() + // Don't touch the pubsub instance if we're + // already closed. + select { + case <-ps.closed: + return + default: + } + + ps.wrapped.Unsub(valuesCh) + }() + + for { + select { + case <-ctx.Done(): + return + case <-ps.closed: + case val, ok := <-valuesCh: + if !ok { + return + } + block, ok := val.(blocks.Block) + if !ok { + return + } + select { + case <-ctx.Done(): + return + case blocksCh <- block: // continue + case <-ps.closed: + } + } + } + }() + + return blocksCh +} + +func toStrings(keys []cid.Cid) []string { + strs := make([]string, 0, len(keys)) + for _, key := range keys { + strs = append(strs, key.KeyString()) + } + return strs +} diff --git a/vendor/github.com/ipfs/go-bitswap/peermanager/peermanager.go b/vendor/github.com/ipfs/go-bitswap/peermanager/peermanager.go new file mode 100644 index 00000000..3aefbbe6 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/peermanager/peermanager.go @@ -0,0 +1,108 @@ +package peermanager + +import ( + "context" + + bsmsg "github.com/ipfs/go-bitswap/message" + wantlist "github.com/ipfs/go-bitswap/wantlist" + + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// PeerQueue provides a queer of messages to be sent for a single peer. +type PeerQueue interface { + AddMessage(entries []bsmsg.Entry, ses uint64) + Startup() + AddWantlist(initialWants *wantlist.SessionTrackedWantlist) + Shutdown() +} + +// PeerQueueFactory provides a function that will create a PeerQueue. +type PeerQueueFactory func(ctx context.Context, p peer.ID) PeerQueue + +type peerQueueInstance struct { + refcnt int + pq PeerQueue +} + +// PeerManager manages a pool of peers and sends messages to peers in the pool. +type PeerManager struct { + // peerQueues -- interact through internal utility functions get/set/remove/iterate + peerQueues map[peer.ID]*peerQueueInstance + + createPeerQueue PeerQueueFactory + ctx context.Context +} + +// New creates a new PeerManager, given a context and a peerQueueFactory. +func New(ctx context.Context, createPeerQueue PeerQueueFactory) *PeerManager { + return &PeerManager{ + peerQueues: make(map[peer.ID]*peerQueueInstance), + createPeerQueue: createPeerQueue, + ctx: ctx, + } +} + +// ConnectedPeers returns a list of peers this PeerManager is managing. +func (pm *PeerManager) ConnectedPeers() []peer.ID { + peers := make([]peer.ID, 0, len(pm.peerQueues)) + for p := range pm.peerQueues { + peers = append(peers, p) + } + return peers +} + +// Connected is called to add a new peer to the pool, and send it an initial set +// of wants. +func (pm *PeerManager) Connected(p peer.ID, initialWants *wantlist.SessionTrackedWantlist) { + pq := pm.getOrCreate(p) + + if pq.refcnt == 0 { + pq.pq.AddWantlist(initialWants) + } + + pq.refcnt++ +} + +// Disconnected is called to remove a peer from the pool. +func (pm *PeerManager) Disconnected(p peer.ID) { + pq, ok := pm.peerQueues[p] + + if !ok { + return + } + + pq.refcnt-- + if pq.refcnt > 0 { + return + } + + delete(pm.peerQueues, p) + pq.pq.Shutdown() +} + +// SendMessage is called to send a message to all or some peers in the pool; +// if targets is nil, it sends to all. +func (pm *PeerManager) SendMessage(entries []bsmsg.Entry, targets []peer.ID, from uint64) { + if len(targets) == 0 { + for _, p := range pm.peerQueues { + p.pq.AddMessage(entries, from) + } + } else { + for _, t := range targets { + pqi := pm.getOrCreate(t) + pqi.pq.AddMessage(entries, from) + } + } +} + +func (pm *PeerManager) getOrCreate(p peer.ID) *peerQueueInstance { + pqi, ok := pm.peerQueues[p] + if !ok { + pq := pm.createPeerQueue(pm.ctx, p) + pq.Startup() + pqi = &peerQueueInstance{0, pq} + pm.peerQueues[p] = pqi + } + return pqi +} diff --git a/vendor/github.com/ipfs/go-bitswap/providerquerymanager/providerquerymanager.go b/vendor/github.com/ipfs/go-bitswap/providerquerymanager/providerquerymanager.go new file mode 100644 index 00000000..e1f77edf --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/providerquerymanager/providerquerymanager.go @@ -0,0 +1,423 @@ +package providerquerymanager + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("bitswap") + +const ( + maxProviders = 10 + maxInProcessRequests = 6 + defaultTimeout = 10 * time.Second +) + +type inProgressRequestStatus struct { + ctx context.Context + cancelFn func() + providersSoFar []peer.ID + listeners map[chan peer.ID]struct{} +} + +type findProviderRequest struct { + k cid.Cid + ctx context.Context +} + +// ProviderQueryNetwork is an interface for finding providers and connecting to +// peers. +type ProviderQueryNetwork interface { + ConnectTo(context.Context, peer.ID) error + FindProvidersAsync(context.Context, cid.Cid, int) <-chan peer.ID +} + +type providerQueryMessage interface { + debugMessage() string + handle(pqm *ProviderQueryManager) +} + +type receivedProviderMessage struct { + k cid.Cid + p peer.ID +} + +type finishedProviderQueryMessage struct { + k cid.Cid +} + +type newProvideQueryMessage struct { + k cid.Cid + inProgressRequestChan chan<- inProgressRequest +} + +type cancelRequestMessage struct { + incomingProviders chan peer.ID + k cid.Cid +} + +// ProviderQueryManager manages requests to find more providers for blocks +// for bitswap sessions. It's main goals are to: +// - rate limit requests -- don't have too many find provider calls running +// simultaneously +// - connect to found peers and filter them if it can't connect +// - ensure two findprovider calls for the same block don't run concurrently +// - manage timeouts +type ProviderQueryManager struct { + ctx context.Context + network ProviderQueryNetwork + providerQueryMessages chan providerQueryMessage + providerRequestsProcessing chan *findProviderRequest + incomingFindProviderRequests chan *findProviderRequest + + findProviderTimeout time.Duration + timeoutMutex sync.RWMutex + + // do not touch outside the run loop + inProgressRequestStatuses map[cid.Cid]*inProgressRequestStatus +} + +// New initializes a new ProviderQueryManager for a given context and a given +// network provider. +func New(ctx context.Context, network ProviderQueryNetwork) *ProviderQueryManager { + return &ProviderQueryManager{ + ctx: ctx, + network: network, + providerQueryMessages: make(chan providerQueryMessage, 16), + providerRequestsProcessing: make(chan *findProviderRequest), + incomingFindProviderRequests: make(chan *findProviderRequest), + inProgressRequestStatuses: make(map[cid.Cid]*inProgressRequestStatus), + findProviderTimeout: defaultTimeout, + } +} + +// Startup starts processing for the ProviderQueryManager. +func (pqm *ProviderQueryManager) Startup() { + go pqm.run() +} + +type inProgressRequest struct { + providersSoFar []peer.ID + incoming chan peer.ID +} + +// SetFindProviderTimeout changes the timeout for finding providers +func (pqm *ProviderQueryManager) SetFindProviderTimeout(findProviderTimeout time.Duration) { + pqm.timeoutMutex.Lock() + pqm.findProviderTimeout = findProviderTimeout + pqm.timeoutMutex.Unlock() +} + +// FindProvidersAsync finds providers for the given block. +func (pqm *ProviderQueryManager) FindProvidersAsync(sessionCtx context.Context, k cid.Cid) <-chan peer.ID { + inProgressRequestChan := make(chan inProgressRequest) + + select { + case pqm.providerQueryMessages <- &newProvideQueryMessage{ + k: k, + inProgressRequestChan: inProgressRequestChan, + }: + case <-pqm.ctx.Done(): + ch := make(chan peer.ID) + close(ch) + return ch + case <-sessionCtx.Done(): + ch := make(chan peer.ID) + close(ch) + return ch + } + + // DO NOT select on sessionCtx. We only want to abort here if we're + // shutting down because we can't actually _cancel_ the request till we + // get to receiveProviders. + var receivedInProgressRequest inProgressRequest + select { + case <-pqm.ctx.Done(): + ch := make(chan peer.ID) + close(ch) + return ch + case receivedInProgressRequest = <-inProgressRequestChan: + } + + return pqm.receiveProviders(sessionCtx, k, receivedInProgressRequest) +} + +func (pqm *ProviderQueryManager) receiveProviders(sessionCtx context.Context, k cid.Cid, receivedInProgressRequest inProgressRequest) <-chan peer.ID { + // maintains an unbuffered queue for incoming providers for given request for a given session + // essentially, as a provider comes in, for a given CID, we want to immediately broadcast to all + // sessions that queried that CID, without worrying about whether the client code is actually + // reading from the returned channel -- so that the broadcast never blocks + // based on: https://medium.com/capital-one-tech/building-an-unbounded-channel-in-go-789e175cd2cd + returnedProviders := make(chan peer.ID) + receivedProviders := append([]peer.ID(nil), receivedInProgressRequest.providersSoFar[0:]...) + incomingProviders := receivedInProgressRequest.incoming + + go func() { + defer close(returnedProviders) + outgoingProviders := func() chan<- peer.ID { + if len(receivedProviders) == 0 { + return nil + } + return returnedProviders + } + nextProvider := func() peer.ID { + if len(receivedProviders) == 0 { + return "" + } + return receivedProviders[0] + } + for len(receivedProviders) > 0 || incomingProviders != nil { + select { + case <-pqm.ctx.Done(): + return + case <-sessionCtx.Done(): + if incomingProviders != nil { + pqm.cancelProviderRequest(k, incomingProviders) + } + return + case provider, ok := <-incomingProviders: + if !ok { + incomingProviders = nil + } else { + receivedProviders = append(receivedProviders, provider) + } + case outgoingProviders() <- nextProvider(): + receivedProviders = receivedProviders[1:] + } + } + }() + return returnedProviders +} + +func (pqm *ProviderQueryManager) cancelProviderRequest(k cid.Cid, incomingProviders chan peer.ID) { + cancelMessageChannel := pqm.providerQueryMessages + for { + select { + case cancelMessageChannel <- &cancelRequestMessage{ + incomingProviders: incomingProviders, + k: k, + }: + cancelMessageChannel = nil + // clear out any remaining providers, in case and "incoming provider" + // messages get processed before our cancel message + case _, ok := <-incomingProviders: + if !ok { + return + } + case <-pqm.ctx.Done(): + return + } + } +} + +func (pqm *ProviderQueryManager) findProviderWorker() { + // findProviderWorker just cycles through incoming provider queries one + // at a time. We have six of these workers running at once + // to let requests go in parallel but keep them rate limited + for { + select { + case fpr, ok := <-pqm.providerRequestsProcessing: + if !ok { + return + } + k := fpr.k + log.Debugf("Beginning Find Provider Request for cid: %s", k.String()) + pqm.timeoutMutex.RLock() + findProviderCtx, cancel := context.WithTimeout(fpr.ctx, pqm.findProviderTimeout) + pqm.timeoutMutex.RUnlock() + providers := pqm.network.FindProvidersAsync(findProviderCtx, k, maxProviders) + wg := &sync.WaitGroup{} + for p := range providers { + wg.Add(1) + go func(p peer.ID) { + defer wg.Done() + err := pqm.network.ConnectTo(findProviderCtx, p) + if err != nil { + log.Debugf("failed to connect to provider %s: %s", p, err) + return + } + select { + case pqm.providerQueryMessages <- &receivedProviderMessage{ + k: k, + p: p, + }: + case <-pqm.ctx.Done(): + return + } + }(p) + } + cancel() + wg.Wait() + select { + case pqm.providerQueryMessages <- &finishedProviderQueryMessage{ + k: k, + }: + case <-pqm.ctx.Done(): + } + case <-pqm.ctx.Done(): + return + } + } +} + +func (pqm *ProviderQueryManager) providerRequestBufferWorker() { + // the provider request buffer worker just maintains an unbounded + // buffer for incoming provider queries and dispatches to the find + // provider workers as they become available + // based on: https://medium.com/capital-one-tech/building-an-unbounded-channel-in-go-789e175cd2cd + var providerQueryRequestBuffer []*findProviderRequest + nextProviderQuery := func() *findProviderRequest { + if len(providerQueryRequestBuffer) == 0 { + return nil + } + return providerQueryRequestBuffer[0] + } + outgoingRequests := func() chan<- *findProviderRequest { + if len(providerQueryRequestBuffer) == 0 { + return nil + } + return pqm.providerRequestsProcessing + } + + for { + select { + case incomingRequest, ok := <-pqm.incomingFindProviderRequests: + if !ok { + return + } + providerQueryRequestBuffer = append(providerQueryRequestBuffer, incomingRequest) + case outgoingRequests() <- nextProviderQuery(): + providerQueryRequestBuffer = providerQueryRequestBuffer[1:] + case <-pqm.ctx.Done(): + return + } + } +} + +func (pqm *ProviderQueryManager) cleanupInProcessRequests() { + for _, requestStatus := range pqm.inProgressRequestStatuses { + for listener := range requestStatus.listeners { + close(listener) + } + requestStatus.cancelFn() + } +} + +func (pqm *ProviderQueryManager) run() { + defer pqm.cleanupInProcessRequests() + + go pqm.providerRequestBufferWorker() + for i := 0; i < maxInProcessRequests; i++ { + go pqm.findProviderWorker() + } + + for { + select { + case nextMessage := <-pqm.providerQueryMessages: + log.Debug(nextMessage.debugMessage()) + nextMessage.handle(pqm) + case <-pqm.ctx.Done(): + return + } + } +} + +func (rpm *receivedProviderMessage) debugMessage() string { + return fmt.Sprintf("Received provider (%s) for cid (%s)", rpm.p.String(), rpm.k.String()) +} + +func (rpm *receivedProviderMessage) handle(pqm *ProviderQueryManager) { + requestStatus, ok := pqm.inProgressRequestStatuses[rpm.k] + if !ok { + log.Errorf("Received provider (%s) for cid (%s) not requested", rpm.p.String(), rpm.k.String()) + return + } + requestStatus.providersSoFar = append(requestStatus.providersSoFar, rpm.p) + for listener := range requestStatus.listeners { + select { + case listener <- rpm.p: + case <-pqm.ctx.Done(): + return + } + } +} + +func (fpqm *finishedProviderQueryMessage) debugMessage() string { + return fmt.Sprintf("Finished Provider Query on cid: %s", fpqm.k.String()) +} + +func (fpqm *finishedProviderQueryMessage) handle(pqm *ProviderQueryManager) { + requestStatus, ok := pqm.inProgressRequestStatuses[fpqm.k] + if !ok { + // we canceled the request as it finished. + return + } + for listener := range requestStatus.listeners { + close(listener) + } + delete(pqm.inProgressRequestStatuses, fpqm.k) + requestStatus.cancelFn() +} + +func (npqm *newProvideQueryMessage) debugMessage() string { + return fmt.Sprintf("New Provider Query on cid: %s", npqm.k.String()) +} + +func (npqm *newProvideQueryMessage) handle(pqm *ProviderQueryManager) { + requestStatus, ok := pqm.inProgressRequestStatuses[npqm.k] + if !ok { + ctx, cancelFn := context.WithCancel(pqm.ctx) + requestStatus = &inProgressRequestStatus{ + listeners: make(map[chan peer.ID]struct{}), + ctx: ctx, + cancelFn: cancelFn, + } + pqm.inProgressRequestStatuses[npqm.k] = requestStatus + select { + case pqm.incomingFindProviderRequests <- &findProviderRequest{ + k: npqm.k, + ctx: ctx, + }: + case <-pqm.ctx.Done(): + return + } + } + inProgressChan := make(chan peer.ID) + requestStatus.listeners[inProgressChan] = struct{}{} + select { + case npqm.inProgressRequestChan <- inProgressRequest{ + providersSoFar: requestStatus.providersSoFar, + incoming: inProgressChan, + }: + case <-pqm.ctx.Done(): + } +} + +func (crm *cancelRequestMessage) debugMessage() string { + return fmt.Sprintf("Cancel provider query on cid: %s", crm.k.String()) +} + +func (crm *cancelRequestMessage) handle(pqm *ProviderQueryManager) { + requestStatus, ok := pqm.inProgressRequestStatuses[crm.k] + if !ok { + // Request finished while queued. + return + } + _, ok = requestStatus.listeners[crm.incomingProviders] + if !ok { + // Request finished and _restarted_ while queued. + return + } + delete(requestStatus.listeners, crm.incomingProviders) + close(crm.incomingProviders) + if len(requestStatus.listeners) == 0 { + delete(pqm.inProgressRequestStatuses, crm.k) + requestStatus.cancelFn() + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/session/cidqueue.go b/vendor/github.com/ipfs/go-bitswap/session/cidqueue.go new file mode 100644 index 00000000..cf461a6c --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/session/cidqueue.go @@ -0,0 +1,46 @@ +package session + +import cid "github.com/ipfs/go-cid" + +type cidQueue struct { + elems []cid.Cid + eset *cid.Set +} + +func newCidQueue() *cidQueue { + return &cidQueue{eset: cid.NewSet()} +} + +func (cq *cidQueue) Pop() cid.Cid { + for { + if len(cq.elems) == 0 { + return cid.Cid{} + } + + out := cq.elems[0] + cq.elems = cq.elems[1:] + + if cq.eset.Has(out) { + cq.eset.Remove(out) + return out + } + } +} + +func (cq *cidQueue) Push(c cid.Cid) { + if cq.eset.Visit(c) { + cq.elems = append(cq.elems, c) + } +} + +func (cq *cidQueue) Remove(c cid.Cid) { + cq.eset.Remove(c) +} + +func (cq *cidQueue) Has(c cid.Cid) bool { + return cq.eset.Has(c) +} + +func (cq *cidQueue) Len() int { + return cq.eset.Len() +} diff --git a/vendor/github.com/ipfs/go-bitswap/session/session.go b/vendor/github.com/ipfs/go-bitswap/session/session.go new file mode 100644 index 00000000..0757ab11 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/session/session.go @@ -0,0 +1,467 @@ +package session + +import ( + "context" + "math/rand" + "time" + + lru "github.com/hashicorp/golang-lru" + bsgetter "github.com/ipfs/go-bitswap/getter" + notifications "github.com/ipfs/go-bitswap/notifications" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + delay "github.com/ipfs/go-ipfs-delay" + logging "github.com/ipfs/go-log" + peer "github.com/libp2p/go-libp2p-core/peer" + loggables "github.com/libp2p/go-libp2p-loggables" + + bssrs "github.com/ipfs/go-bitswap/sessionrequestsplitter" +) + +const ( + broadcastLiveWantsLimit = 4 + targetedLiveWantsLimit = 32 +) + +// WantManager is an interface that can be used to request blocks +// from given peers. +type WantManager interface { + WantBlocks(ctx context.Context, ks []cid.Cid, peers []peer.ID, ses uint64) + CancelWants(ctx context.Context, ks []cid.Cid, peers []peer.ID, ses uint64) +} + +// PeerManager provides an interface for tracking and optimize peers, and +// requesting more when neccesary. +type PeerManager interface { + FindMorePeers(context.Context, cid.Cid) + GetOptimizedPeers() []peer.ID + RecordPeerRequests([]peer.ID, []cid.Cid) + RecordPeerResponse(peer.ID, cid.Cid) +} + +// RequestSplitter provides an interface for splitting +// a request for Cids up among peers. +type RequestSplitter interface { + SplitRequest([]peer.ID, []cid.Cid) []*bssrs.PartialRequest + RecordDuplicateBlock() + RecordUniqueBlock() +} + +type interestReq struct { + c cid.Cid + resp chan bool +} + +type blkRecv struct { + from peer.ID + blk blocks.Block + counterMessage bool +} + +// Session holds state for an individual bitswap transfer operation. +// This allows bitswap to make smarter decisions about who to send wantlist +// info to, and who to request blocks from. +type Session struct { + // dependencies + ctx context.Context + wm WantManager + pm PeerManager + srs RequestSplitter + + // channels + incoming chan blkRecv + newReqs chan []cid.Cid + cancelKeys chan []cid.Cid + interestReqs chan interestReq + latencyReqs chan chan time.Duration + tickDelayReqs chan time.Duration + + // do not touch outside run loop + tofetch *cidQueue + interest *lru.Cache + pastWants *cidQueue + liveWants map[cid.Cid]time.Time + idleTick *time.Timer + periodicSearchTimer *time.Timer + baseTickDelay time.Duration + latTotal time.Duration + fetchcnt int + consecutiveTicks int + initialSearchDelay time.Duration + periodicSearchDelay delay.D + // identifiers + notif notifications.PubSub + uuid logging.Loggable + id uint64 +} + +// New creates a new bitswap session whose lifetime is bounded by the +// given context. +func New(ctx context.Context, + id uint64, + wm WantManager, + pm PeerManager, + srs RequestSplitter, + initialSearchDelay time.Duration, + periodicSearchDelay delay.D) *Session { + s := &Session{ + liveWants: make(map[cid.Cid]time.Time), + newReqs: make(chan []cid.Cid), + cancelKeys: make(chan []cid.Cid), + tofetch: newCidQueue(), + pastWants: newCidQueue(), + interestReqs: make(chan interestReq), + latencyReqs: make(chan chan time.Duration), + tickDelayReqs: make(chan time.Duration), + ctx: ctx, + wm: wm, + pm: pm, + srs: srs, + incoming: make(chan blkRecv), + notif: notifications.New(), + uuid: loggables.Uuid("GetBlockRequest"), + baseTickDelay: time.Millisecond * 500, + id: id, + initialSearchDelay: initialSearchDelay, + periodicSearchDelay: periodicSearchDelay, + } + + cache, _ := lru.New(2048) + s.interest = cache + + go s.run(ctx) + + return s +} + +// ReceiveBlockFrom receives an incoming block from the given peer. +func (s *Session) ReceiveBlockFrom(from peer.ID, blk blocks.Block) { + select { + case s.incoming <- blkRecv{from: from, blk: blk, counterMessage: false}: + case <-s.ctx.Done(): + } + ks := []cid.Cid{blk.Cid()} + s.wm.CancelWants(s.ctx, ks, nil, s.id) + +} + +// UpdateReceiveCounters updates receive counters for a block, +// which may be a duplicate and adjusts the split factor based on that. +func (s *Session) UpdateReceiveCounters(blk blocks.Block) { + select { + case s.incoming <- blkRecv{from: "", blk: blk, counterMessage: true}: + case <-s.ctx.Done(): + } +} + +// InterestedIn returns true if this session is interested in the given Cid. +func (s *Session) InterestedIn(c cid.Cid) bool { + if s.interest.Contains(c) { + return true + } + // TODO: PERF: this is using a channel to guard a map access against race + // conditions. This is definitely much slower than a mutex, though its unclear + // if it will actually induce any noticeable slowness. This is implemented this + // way to avoid adding a more complex set of mutexes around the liveWants map. + // note that in the average case (where this session *is* interested in the + // block we received) this function will not be called, as the cid will likely + // still be in the interest cache. + resp := make(chan bool, 1) + select { + case s.interestReqs <- interestReq{ + c: c, + resp: resp, + }: + case <-s.ctx.Done(): + return false + } + + select { + case want := <-resp: + return want + case <-s.ctx.Done(): + return false + } +} + +// GetBlock fetches a single block. +func (s *Session) GetBlock(parent context.Context, k cid.Cid) (blocks.Block, error) { + return bsgetter.SyncGetBlock(parent, k, s.GetBlocks) +} + +// GetBlocks fetches a set of blocks within the context of this session and +// returns a channel that found blocks will be returned on. No order is +// guaranteed on the returned blocks. +func (s *Session) GetBlocks(ctx context.Context, keys []cid.Cid) (<-chan blocks.Block, error) { + ctx = logging.ContextWithLoggable(ctx, s.uuid) + return bsgetter.AsyncGetBlocks(ctx, keys, s.notif, + func(ctx context.Context, keys []cid.Cid) { + select { + case s.newReqs <- keys: + case <-ctx.Done(): + case <-s.ctx.Done(): + } + }, + func(keys []cid.Cid) { + select { + case s.cancelKeys <- keys: + case <-s.ctx.Done(): + } + }, + ) +} + +// GetAverageLatency returns the average latency for block requests. +func (s *Session) GetAverageLatency() time.Duration { + resp := make(chan time.Duration) + select { + case s.latencyReqs <- resp: + case <-s.ctx.Done(): + return -1 * time.Millisecond + } + + select { + case latency := <-resp: + return latency + case <-s.ctx.Done(): + return -1 * time.Millisecond + } +} + +// SetBaseTickDelay changes the rate at which ticks happen. +func (s *Session) SetBaseTickDelay(baseTickDelay time.Duration) { + select { + case s.tickDelayReqs <- baseTickDelay: + case <-s.ctx.Done(): + } +} + +// Session run loop -- everything function below here should not be called +// of this loop +func (s *Session) run(ctx context.Context) { + s.idleTick = time.NewTimer(s.initialSearchDelay) + s.periodicSearchTimer = time.NewTimer(s.periodicSearchDelay.NextWaitTime()) + for { + select { + case blk := <-s.incoming: + if blk.counterMessage { + s.updateReceiveCounters(ctx, blk) + } else { + s.handleIncomingBlock(ctx, blk) + } + case keys := <-s.newReqs: + s.handleNewRequest(ctx, keys) + case keys := <-s.cancelKeys: + s.handleCancel(keys) + case <-s.idleTick.C: + s.handleIdleTick(ctx) + case <-s.periodicSearchTimer.C: + s.handlePeriodicSearch(ctx) + case lwchk := <-s.interestReqs: + lwchk.resp <- s.cidIsWanted(lwchk.c) + case resp := <-s.latencyReqs: + resp <- s.averageLatency() + case baseTickDelay := <-s.tickDelayReqs: + s.baseTickDelay = baseTickDelay + case <-ctx.Done(): + s.handleShutdown() + return + } + } +} + +func (s *Session) handleIncomingBlock(ctx context.Context, blk blkRecv) { + s.idleTick.Stop() + + if blk.from != "" { + s.pm.RecordPeerResponse(blk.from, blk.blk.Cid()) + } + + s.receiveBlock(ctx, blk.blk) + + s.resetIdleTick() +} + +func (s *Session) handleNewRequest(ctx context.Context, keys []cid.Cid) { + for _, k := range keys { + s.interest.Add(k, nil) + } + if toadd := s.wantBudget(); toadd > 0 { + if toadd > len(keys) { + toadd = len(keys) + } + + now := keys[:toadd] + keys = keys[toadd:] + + s.wantBlocks(ctx, now) + } + for _, k := range keys { + s.tofetch.Push(k) + } +} + +func (s *Session) handleCancel(keys []cid.Cid) { + for _, c := range keys { + s.tofetch.Remove(c) + } +} + +func (s *Session) handleIdleTick(ctx context.Context) { + + live := make([]cid.Cid, 0, len(s.liveWants)) + now := time.Now() + for c := range s.liveWants { + live = append(live, c) + s.liveWants[c] = now + } + + // Broadcast these keys to everyone we're connected to + s.pm.RecordPeerRequests(nil, live) + s.wm.WantBlocks(ctx, live, nil, s.id) + + // do no find providers on consecutive ticks + // -- just rely on periodic search widening + if len(live) > 0 && (s.consecutiveTicks == 0) { + s.pm.FindMorePeers(ctx, live[0]) + } + s.resetIdleTick() + + if len(s.liveWants) > 0 { + s.consecutiveTicks++ + } +} + +func (s *Session) handlePeriodicSearch(ctx context.Context) { + randomWant := s.randomLiveWant() + if !randomWant.Defined() { + return + } + + // TODO: come up with a better strategy for determining when to search + // for new providers for blocks. + s.pm.FindMorePeers(ctx, randomWant) + s.wm.WantBlocks(ctx, []cid.Cid{randomWant}, nil, s.id) + + s.periodicSearchTimer.Reset(s.periodicSearchDelay.NextWaitTime()) +} + +func (s *Session) randomLiveWant() cid.Cid { + if len(s.liveWants) == 0 { + return cid.Cid{} + } + i := rand.Intn(len(s.liveWants)) + // picking a random live want + for k := range s.liveWants { + if i == 0 { + return k + } + i-- + } + return cid.Cid{} +} +func (s *Session) handleShutdown() { + s.idleTick.Stop() + s.notif.Shutdown() + + live := make([]cid.Cid, 0, len(s.liveWants)) + for c := range s.liveWants { + live = append(live, c) + } + s.wm.CancelWants(s.ctx, live, nil, s.id) +} + +func (s *Session) cidIsWanted(c cid.Cid) bool { + _, ok := s.liveWants[c] + if !ok { + ok = s.tofetch.Has(c) + } + return ok +} + +func (s *Session) receiveBlock(ctx context.Context, blk blocks.Block) { + c := blk.Cid() + if s.cidIsWanted(c) { + s.srs.RecordUniqueBlock() + tval, ok := s.liveWants[c] + if ok { + s.latTotal += time.Since(tval) + delete(s.liveWants, c) + } else { + s.tofetch.Remove(c) + } + s.fetchcnt++ + // we've received new wanted blocks, so future ticks are not consecutive + s.consecutiveTicks = 0 + s.notif.Publish(blk) + + toAdd := s.wantBudget() + if toAdd > s.tofetch.Len() { + toAdd = s.tofetch.Len() + } + if toAdd > 0 { + var keys []cid.Cid + for i := 0; i < toAdd; i++ { + keys = append(keys, s.tofetch.Pop()) + } + s.wantBlocks(ctx, keys) + } + + s.pastWants.Push(c) + } +} + +func (s *Session) updateReceiveCounters(ctx context.Context, blk blkRecv) { + ks := blk.blk.Cid() + if s.pastWants.Has(ks) { + s.srs.RecordDuplicateBlock() + } +} + +func (s *Session) wantBlocks(ctx context.Context, ks []cid.Cid) { + now := time.Now() + for _, c := range ks { + s.liveWants[c] = now + } + peers := s.pm.GetOptimizedPeers() + if len(peers) > 0 { + splitRequests := s.srs.SplitRequest(peers, ks) + for _, splitRequest := range splitRequests { + s.pm.RecordPeerRequests(splitRequest.Peers, splitRequest.Keys) + s.wm.WantBlocks(ctx, splitRequest.Keys, splitRequest.Peers, s.id) + } + } else { + s.pm.RecordPeerRequests(nil, ks) + s.wm.WantBlocks(ctx, ks, nil, s.id) + } +} + +func (s *Session) averageLatency() time.Duration { + return s.latTotal / time.Duration(s.fetchcnt) +} + +func (s *Session) resetIdleTick() { + var tickDelay time.Duration + if s.latTotal == 0 { + tickDelay = s.initialSearchDelay + } else { + avLat := s.averageLatency() + tickDelay = s.baseTickDelay + (3 * avLat) + } + tickDelay = tickDelay * time.Duration(1+s.consecutiveTicks) + s.idleTick.Reset(tickDelay) +} + +func (s *Session) wantBudget() int { + live := len(s.liveWants) + var budget int + if len(s.pm.GetOptimizedPeers()) > 0 { + budget = targetedLiveWantsLimit - live + } else { + budget = broadcastLiveWantsLimit - live + } + if budget < 0 { + budget = 0 + } + return budget +} diff --git a/vendor/github.com/ipfs/go-bitswap/sessionmanager/sessionmanager.go b/vendor/github.com/ipfs/go-bitswap/sessionmanager/sessionmanager.go new file mode 100644 index 00000000..a2617073 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/sessionmanager/sessionmanager.go @@ -0,0 +1,138 @@ +package sessionmanager + +import ( + "context" + "sync" + "time" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + delay "github.com/ipfs/go-ipfs-delay" + + bssession "github.com/ipfs/go-bitswap/session" + exchange "github.com/ipfs/go-ipfs-exchange-interface" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// Session is a session that is managed by the session manager +type Session interface { + exchange.Fetcher + InterestedIn(cid.Cid) bool + ReceiveBlockFrom(peer.ID, blocks.Block) + UpdateReceiveCounters(blocks.Block) +} + +type sesTrk struct { + session Session + pm bssession.PeerManager + srs bssession.RequestSplitter +} + +// SessionFactory generates a new session for the SessionManager to track. +type SessionFactory func(ctx context.Context, id uint64, pm bssession.PeerManager, srs bssession.RequestSplitter, provSearchDelay time.Duration, rebroadcastDelay delay.D) Session + +// RequestSplitterFactory generates a new request splitter for a session. +type RequestSplitterFactory func(ctx context.Context) bssession.RequestSplitter + +// PeerManagerFactory generates a new peer manager for a session. +type PeerManagerFactory func(ctx context.Context, id uint64) bssession.PeerManager + +// SessionManager is responsible for creating, managing, and dispatching to +// sessions. +type SessionManager struct { + ctx context.Context + sessionFactory SessionFactory + peerManagerFactory PeerManagerFactory + requestSplitterFactory RequestSplitterFactory + + // Sessions + sessLk sync.Mutex + sessions []sesTrk + + // Session Index + sessIDLk sync.Mutex + sessID uint64 +} + +// New creates a new SessionManager. +func New(ctx context.Context, sessionFactory SessionFactory, peerManagerFactory PeerManagerFactory, requestSplitterFactory RequestSplitterFactory) *SessionManager { + return &SessionManager{ + ctx: ctx, + sessionFactory: sessionFactory, + peerManagerFactory: peerManagerFactory, + requestSplitterFactory: requestSplitterFactory, + } +} + +// NewSession initializes a session with the given context, and adds to the +// session manager. +func (sm *SessionManager) NewSession(ctx context.Context, + provSearchDelay time.Duration, + rebroadcastDelay delay.D) exchange.Fetcher { + id := sm.GetNextSessionID() + sessionctx, cancel := context.WithCancel(ctx) + + pm := sm.peerManagerFactory(sessionctx, id) + srs := sm.requestSplitterFactory(sessionctx) + session := sm.sessionFactory(sessionctx, id, pm, srs, provSearchDelay, rebroadcastDelay) + tracked := sesTrk{session, pm, srs} + sm.sessLk.Lock() + sm.sessions = append(sm.sessions, tracked) + sm.sessLk.Unlock() + go func() { + defer cancel() + select { + case <-sm.ctx.Done(): + sm.removeSession(tracked) + case <-ctx.Done(): + sm.removeSession(tracked) + } + }() + + return session +} + +func (sm *SessionManager) removeSession(session sesTrk) { + sm.sessLk.Lock() + defer sm.sessLk.Unlock() + for i := 0; i < len(sm.sessions); i++ { + if sm.sessions[i] == session { + sm.sessions[i] = sm.sessions[len(sm.sessions)-1] + sm.sessions = sm.sessions[:len(sm.sessions)-1] + return + } + } +} + +// GetNextSessionID returns the next sequentional identifier for a session. +func (sm *SessionManager) GetNextSessionID() uint64 { + sm.sessIDLk.Lock() + defer sm.sessIDLk.Unlock() + sm.sessID++ + return sm.sessID +} + +// ReceiveBlockFrom receives a block from a peer and dispatches to interested +// sessions. +func (sm *SessionManager) ReceiveBlockFrom(from peer.ID, blk blocks.Block) { + sm.sessLk.Lock() + defer sm.sessLk.Unlock() + + k := blk.Cid() + for _, s := range sm.sessions { + if s.session.InterestedIn(k) { + s.session.ReceiveBlockFrom(from, blk) + } + } +} + +// UpdateReceiveCounters records the fact that a block was received, allowing +// sessions to track duplicates +func (sm *SessionManager) UpdateReceiveCounters(blk blocks.Block) { + sm.sessLk.Lock() + defer sm.sessLk.Unlock() + + for _, s := range sm.sessions { + s.session.UpdateReceiveCounters(blk) + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/sessionpeermanager/sessionpeermanager.go b/vendor/github.com/ipfs/go-bitswap/sessionpeermanager/sessionpeermanager.go new file mode 100644 index 00000000..59bfbf49 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/sessionpeermanager/sessionpeermanager.go @@ -0,0 +1,221 @@ +package sessionpeermanager + +import ( + "context" + "fmt" + "math/rand" + + cid "github.com/ipfs/go-cid" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +const ( + maxOptimizedPeers = 32 + reservePeers = 2 + unoptimizedTagValue = 5 // tag value for "unoptimized" session peers. + optimizedTagValue = 10 // tag value for "optimized" session peers. +) + +// PeerTagger is an interface for tagging peers with metadata +type PeerTagger interface { + TagPeer(peer.ID, string, int) + UntagPeer(p peer.ID, tag string) +} + +// PeerProviderFinder is an interface for finding providers +type PeerProviderFinder interface { + FindProvidersAsync(context.Context, cid.Cid) <-chan peer.ID +} + +type peerMessage interface { + handle(spm *SessionPeerManager) +} + +// SessionPeerManager tracks and manages peers for a session, and provides +// the best ones to the session +type SessionPeerManager struct { + ctx context.Context + tagger PeerTagger + providerFinder PeerProviderFinder + tag string + id uint64 + + peerMessages chan peerMessage + + // do not touch outside of run loop + activePeers map[peer.ID]bool + unoptimizedPeersArr []peer.ID + optimizedPeersArr []peer.ID +} + +// New creates a new SessionPeerManager +func New(ctx context.Context, id uint64, tagger PeerTagger, providerFinder PeerProviderFinder) *SessionPeerManager { + spm := &SessionPeerManager{ + id: id, + ctx: ctx, + tagger: tagger, + providerFinder: providerFinder, + peerMessages: make(chan peerMessage, 16), + activePeers: make(map[peer.ID]bool), + } + + spm.tag = fmt.Sprint("bs-ses-", id) + + go spm.run(ctx) + return spm +} + +// RecordPeerResponse records that a peer received a block, and adds to it +// the list of peers if it wasn't already added +func (spm *SessionPeerManager) RecordPeerResponse(p peer.ID, k cid.Cid) { + + // at the moment, we're just adding peers here + // in the future, we'll actually use this to record metrics + select { + case spm.peerMessages <- &peerResponseMessage{p}: + case <-spm.ctx.Done(): + } +} + +// RecordPeerRequests records that a given set of peers requested the given cids +func (spm *SessionPeerManager) RecordPeerRequests(p []peer.ID, ks []cid.Cid) { + // at the moment, we're not doing anything here + // soon we'll use this to track latency by peer +} + +// GetOptimizedPeers returns the best peers available for a session +func (spm *SessionPeerManager) GetOptimizedPeers() []peer.ID { + // right now this just returns all peers, but soon we might return peers + // ordered by optimization, or only a subset + resp := make(chan []peer.ID, 1) + select { + case spm.peerMessages <- &peerReqMessage{resp}: + case <-spm.ctx.Done(): + return nil + } + + select { + case peers := <-resp: + return peers + case <-spm.ctx.Done(): + return nil + } +} + +// FindMorePeers attempts to find more peers for a session by searching for +// providers for the given Cid +func (spm *SessionPeerManager) FindMorePeers(ctx context.Context, c cid.Cid) { + go func(k cid.Cid) { + for p := range spm.providerFinder.FindProvidersAsync(ctx, k) { + + select { + case spm.peerMessages <- &peerFoundMessage{p}: + case <-ctx.Done(): + case <-spm.ctx.Done(): + } + } + }(c) +} + +func (spm *SessionPeerManager) run(ctx context.Context) { + for { + select { + case pm := <-spm.peerMessages: + pm.handle(spm) + case <-ctx.Done(): + spm.handleShutdown() + return + } + } +} + +func (spm *SessionPeerManager) tagPeer(p peer.ID, value int) { + spm.tagger.TagPeer(p, spm.tag, value) +} + +func (spm *SessionPeerManager) insertOptimizedPeer(p peer.ID) { + if len(spm.optimizedPeersArr) >= (maxOptimizedPeers - reservePeers) { + tailPeer := spm.optimizedPeersArr[len(spm.optimizedPeersArr)-1] + spm.optimizedPeersArr = spm.optimizedPeersArr[:len(spm.optimizedPeersArr)-1] + spm.unoptimizedPeersArr = append(spm.unoptimizedPeersArr, tailPeer) + } + + spm.optimizedPeersArr = append([]peer.ID{p}, spm.optimizedPeersArr...) +} + +func (spm *SessionPeerManager) removeOptimizedPeer(p peer.ID) { + for i := 0; i < len(spm.optimizedPeersArr); i++ { + if spm.optimizedPeersArr[i] == p { + spm.optimizedPeersArr = append(spm.optimizedPeersArr[:i], spm.optimizedPeersArr[i+1:]...) + return + } + } +} + +func (spm *SessionPeerManager) removeUnoptimizedPeer(p peer.ID) { + for i := 0; i < len(spm.unoptimizedPeersArr); i++ { + if spm.unoptimizedPeersArr[i] == p { + spm.unoptimizedPeersArr[i] = spm.unoptimizedPeersArr[len(spm.unoptimizedPeersArr)-1] + spm.unoptimizedPeersArr = spm.unoptimizedPeersArr[:len(spm.unoptimizedPeersArr)-1] + return + } + } +} + +type peerFoundMessage struct { + p peer.ID +} + +func (pfm *peerFoundMessage) handle(spm *SessionPeerManager) { + p := pfm.p + if _, ok := spm.activePeers[p]; !ok { + spm.activePeers[p] = false + spm.unoptimizedPeersArr = append(spm.unoptimizedPeersArr, p) + spm.tagPeer(p, unoptimizedTagValue) + } +} + +type peerResponseMessage struct { + p peer.ID +} + +func (prm *peerResponseMessage) handle(spm *SessionPeerManager) { + p := prm.p + isOptimized, ok := spm.activePeers[p] + if isOptimized { + spm.removeOptimizedPeer(p) + } else { + spm.activePeers[p] = true + spm.tagPeer(p, optimizedTagValue) + + // transition from unoptimized. + if ok { + spm.removeUnoptimizedPeer(p) + } + } + spm.insertOptimizedPeer(p) +} + +type peerReqMessage struct { + resp chan<- []peer.ID +} + +func (prm *peerReqMessage) handle(spm *SessionPeerManager) { + randomOrder := rand.Perm(len(spm.unoptimizedPeersArr)) + maxPeers := len(spm.unoptimizedPeersArr) + len(spm.optimizedPeersArr) + if maxPeers > maxOptimizedPeers { + maxPeers = maxOptimizedPeers + } + + extraPeers := make([]peer.ID, maxPeers-len(spm.optimizedPeersArr)) + for i := range extraPeers { + extraPeers[i] = spm.unoptimizedPeersArr[randomOrder[i]] + } + prm.resp <- append(spm.optimizedPeersArr, extraPeers...) +} + +func (spm *SessionPeerManager) handleShutdown() { + for p := range spm.activePeers { + spm.tagger.UntagPeer(p, spm.tag) + } +} diff --git a/vendor/github.com/ipfs/go-bitswap/sessionrequestsplitter/sessionrequestsplitter.go b/vendor/github.com/ipfs/go-bitswap/sessionrequestsplitter/sessionrequestsplitter.go new file mode 100644 index 00000000..5400fe5c --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/sessionrequestsplitter/sessionrequestsplitter.go @@ -0,0 +1,163 @@ +package sessionrequestsplitter + +import ( + "context" + + "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p-core/peer" +) + +const ( + minReceivedToAdjustSplit = 2 + maxSplit = 16 + maxAcceptableDupes = 0.4 + minDuplesToTryLessSplits = 0.2 + initialSplit = 2 +) + +// PartialRequest is represents one slice of an over request split among peers +type PartialRequest struct { + Peers []peer.ID + Keys []cid.Cid +} + +type srsMessage interface { + handle(srs *SessionRequestSplitter) +} + +// SessionRequestSplitter track how many duplicate and unique blocks come in and +// uses that to determine how much to split up each set of wants among peers. +type SessionRequestSplitter struct { + ctx context.Context + messages chan srsMessage + + // data, do not touch outside run loop + receivedCount int + split int + duplicateReceivedCount int +} + +// New returns a new SessionRequestSplitter. +func New(ctx context.Context) *SessionRequestSplitter { + srs := &SessionRequestSplitter{ + ctx: ctx, + messages: make(chan srsMessage, 10), + split: initialSplit, + } + go srs.run() + return srs +} + +// SplitRequest splits a request for the given cids one or more times among the +// given peers. +func (srs *SessionRequestSplitter) SplitRequest(peers []peer.ID, ks []cid.Cid) []*PartialRequest { + resp := make(chan []*PartialRequest, 1) + + select { + case srs.messages <- &splitRequestMessage{peers, ks, resp}: + case <-srs.ctx.Done(): + return nil + } + select { + case splitRequests := <-resp: + return splitRequests + case <-srs.ctx.Done(): + return nil + } + +} + +// RecordDuplicateBlock records the fact that the session received a duplicate +// block and adjusts split factor as neccesary. +func (srs *SessionRequestSplitter) RecordDuplicateBlock() { + select { + case srs.messages <- &recordDuplicateMessage{}: + case <-srs.ctx.Done(): + } +} + +// RecordUniqueBlock records the fact that the session received unique block +// and adjusts the split factor as neccesary. +func (srs *SessionRequestSplitter) RecordUniqueBlock() { + select { + case srs.messages <- &recordUniqueMessage{}: + case <-srs.ctx.Done(): + } +} + +func (srs *SessionRequestSplitter) run() { + for { + select { + case message := <-srs.messages: + message.handle(srs) + case <-srs.ctx.Done(): + return + } + } +} + +func (srs *SessionRequestSplitter) duplicateRatio() float64 { + return float64(srs.duplicateReceivedCount) / float64(srs.receivedCount) +} + +type splitRequestMessage struct { + peers []peer.ID + ks []cid.Cid + resp chan []*PartialRequest +} + +func (s *splitRequestMessage) handle(srs *SessionRequestSplitter) { + split := srs.split + peers := s.peers + ks := s.ks + if len(peers) < split { + split = len(peers) + } + peerSplits := splitPeers(peers, split) + if len(ks) < split { + split = len(ks) + } + keySplits := splitKeys(ks, split) + splitRequests := make([]*PartialRequest, len(keySplits)) + for i := range splitRequests { + splitRequests[i] = &PartialRequest{peerSplits[i], keySplits[i]} + } + s.resp <- splitRequests +} + +type recordDuplicateMessage struct{} + +func (r *recordDuplicateMessage) handle(srs *SessionRequestSplitter) { + srs.receivedCount++ + srs.duplicateReceivedCount++ + if (srs.receivedCount > minReceivedToAdjustSplit) && (srs.duplicateRatio() > maxAcceptableDupes) && (srs.split < maxSplit) { + srs.split++ + } +} + +type recordUniqueMessage struct{} + +func (r *recordUniqueMessage) handle(srs *SessionRequestSplitter) { + srs.receivedCount++ + if (srs.split > 1) && (srs.duplicateRatio() < minDuplesToTryLessSplits) { + srs.split-- + } + +} +func splitKeys(ks []cid.Cid, split int) [][]cid.Cid { + splits := make([][]cid.Cid, split) + for i, c := range ks { + pos := i % split + splits[pos] = append(splits[pos], c) + } + return splits +} + +func splitPeers(peers []peer.ID, split int) [][]peer.ID { + splits := make([][]peer.ID, split) + for i, p := range peers { + pos := i % split + splits[pos] = append(splits[pos], p) + } + return splits +} diff --git a/vendor/github.com/ipfs/go-bitswap/stat.go b/vendor/github.com/ipfs/go-bitswap/stat.go new file mode 100644 index 00000000..af39ecb2 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/stat.go @@ -0,0 +1,48 @@ +package bitswap + +import ( + "sort" + + cid "github.com/ipfs/go-cid" +) + +// Stat is a struct that provides various statistics on bitswap operations +type Stat struct { + ProvideBufLen int + Wantlist []cid.Cid + Peers []string + BlocksReceived uint64 + DataReceived uint64 + BlocksSent uint64 + DataSent uint64 + DupBlksReceived uint64 + DupDataReceived uint64 + MessagesReceived uint64 +} + +// Stat returns aggregated statistics about bitswap operations +func (bs *Bitswap) Stat() (*Stat, error) { + st := new(Stat) + st.ProvideBufLen = len(bs.newBlocks) + st.Wantlist = bs.GetWantlist() + bs.counterLk.Lock() + c := bs.counters + st.BlocksReceived = c.blocksRecvd + st.DupBlksReceived = c.dupBlocksRecvd + st.DupDataReceived = c.dupDataRecvd + st.BlocksSent = c.blocksSent + st.DataSent = c.dataSent + st.DataReceived = c.dataRecvd + st.MessagesReceived = c.messagesRecvd + bs.counterLk.Unlock() + + peers := bs.engine.Peers() + st.Peers = make([]string, 0, len(peers)) + + for _, p := range peers { + st.Peers = append(st.Peers, p.Pretty()) + } + sort.Strings(st.Peers) + + return st, nil +} diff --git a/vendor/github.com/ipfs/go-bitswap/wantlist/wantlist.go b/vendor/github.com/ipfs/go-bitswap/wantlist/wantlist.go new file mode 100644 index 00000000..b5c2a602 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/wantlist/wantlist.go @@ -0,0 +1,216 @@ +// Package wantlist implements an object for bitswap that contains the keys +// that a given peer wants. +package wantlist + +import ( + "sort" + + cid "github.com/ipfs/go-cid" +) + +// SessionTrackedWantlist is a list of wants that also track which bitswap +// sessions have requested them +type SessionTrackedWantlist struct { + set map[cid.Cid]*sessionTrackedEntry +} + +// Wantlist is a raw list of wanted blocks and their priorities +type Wantlist struct { + set map[cid.Cid]Entry +} + +// Entry is an entry in a want list, consisting of a cid and its priority +type Entry struct { + Cid cid.Cid + Priority int +} + +type sessionTrackedEntry struct { + Entry + sesTrk map[uint64]struct{} +} + +// NewRefEntry creates a new reference tracked wantlist entry. +func NewRefEntry(c cid.Cid, p int) Entry { + return Entry{ + Cid: c, + Priority: p, + } +} + +type entrySlice []Entry + +func (es entrySlice) Len() int { return len(es) } +func (es entrySlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] } +func (es entrySlice) Less(i, j int) bool { return es[i].Priority > es[j].Priority } + +// NewSessionTrackedWantlist generates a new SessionTrackedWantList. +func NewSessionTrackedWantlist() *SessionTrackedWantlist { + return &SessionTrackedWantlist{ + set: make(map[cid.Cid]*sessionTrackedEntry), + } +} + +// New generates a new raw Wantlist +func New() *Wantlist { + return &Wantlist{ + set: make(map[cid.Cid]Entry), + } +} + +// Add adds the given cid to the wantlist with the specified priority, governed +// by the session ID 'ses'. if a cid is added under multiple session IDs, then +// it must be removed by each of those sessions before it is no longer 'in the +// wantlist'. Calls to Add are idempotent given the same arguments. Subsequent +// calls with different values for priority will not update the priority. +// TODO: think through priority changes here +// Add returns true if the cid did not exist in the wantlist before this call +// (even if it was under a different session). +func (w *SessionTrackedWantlist) Add(c cid.Cid, priority int, ses uint64) bool { + + if e, ok := w.set[c]; ok { + e.sesTrk[ses] = struct{}{} + return false + } + + w.set[c] = &sessionTrackedEntry{ + Entry: Entry{Cid: c, Priority: priority}, + sesTrk: map[uint64]struct{}{ses: struct{}{}}, + } + + return true +} + +// AddEntry adds given Entry to the wantlist. For more information see Add method. +func (w *SessionTrackedWantlist) AddEntry(e Entry, ses uint64) bool { + if ex, ok := w.set[e.Cid]; ok { + ex.sesTrk[ses] = struct{}{} + return false + } + w.set[e.Cid] = &sessionTrackedEntry{ + Entry: e, + sesTrk: map[uint64]struct{}{ses: struct{}{}}, + } + return true +} + +// Remove removes the given cid from being tracked by the given session. +// 'true' is returned if this call to Remove removed the final session ID +// tracking the cid. (meaning true will be returned iff this call caused the +// value of 'Contains(c)' to change from true to false) +func (w *SessionTrackedWantlist) Remove(c cid.Cid, ses uint64) bool { + e, ok := w.set[c] + if !ok { + return false + } + + delete(e.sesTrk, ses) + if len(e.sesTrk) == 0 { + delete(w.set, c) + return true + } + return false +} + +// Contains returns true if the given cid is in the wantlist tracked by one or +// more sessions. +func (w *SessionTrackedWantlist) Contains(k cid.Cid) (Entry, bool) { + e, ok := w.set[k] + if !ok { + return Entry{}, false + } + return e.Entry, true +} + +// Entries returns all wantlist entries for a given session tracked want list. +func (w *SessionTrackedWantlist) Entries() []Entry { + es := make([]Entry, 0, len(w.set)) + for _, e := range w.set { + es = append(es, e.Entry) + } + return es +} + +// SortedEntries returns wantlist entries ordered by priority. +func (w *SessionTrackedWantlist) SortedEntries() []Entry { + es := w.Entries() + sort.Sort(entrySlice(es)) + return es +} + +// Len returns the number of entries in a wantlist. +func (w *SessionTrackedWantlist) Len() int { + return len(w.set) +} + +// CopyWants copies all wants from one SessionTrackWantlist to another (along with +// the session data) +func (w *SessionTrackedWantlist) CopyWants(to *SessionTrackedWantlist) { + for _, e := range w.set { + for k := range e.sesTrk { + to.AddEntry(e.Entry, k) + } + } +} + +// Len returns the number of entries in a wantlist. +func (w *Wantlist) Len() int { + return len(w.set) +} + +// Add adds an entry in a wantlist from CID & Priority, if not already present. +func (w *Wantlist) Add(c cid.Cid, priority int) bool { + if _, ok := w.set[c]; ok { + return false + } + + w.set[c] = Entry{ + Cid: c, + Priority: priority, + } + + return true +} + +// AddEntry adds an entry to a wantlist if not already present. +func (w *Wantlist) AddEntry(e Entry) bool { + if _, ok := w.set[e.Cid]; ok { + return false + } + w.set[e.Cid] = e + return true +} + +// Remove removes the given cid from the wantlist. +func (w *Wantlist) Remove(c cid.Cid) bool { + _, ok := w.set[c] + if !ok { + return false + } + + delete(w.set, c) + return true +} + +// Contains returns the entry, if present, for the given CID, plus whether it +// was present. +func (w *Wantlist) Contains(c cid.Cid) (Entry, bool) { + e, ok := w.set[c] + return e, ok +} + +// Entries returns all wantlist entries for a want list. +func (w *Wantlist) Entries() []Entry { + es := make([]Entry, 0, len(w.set)) + for _, e := range w.set { + es = append(es, e) + } + return es +} + +// SortedEntries returns wantlist entries ordered by priority. +func (w *Wantlist) SortedEntries() []Entry { + es := w.Entries() + sort.Sort(entrySlice(es)) + return es +} diff --git a/vendor/github.com/ipfs/go-bitswap/wantmanager/wantmanager.go b/vendor/github.com/ipfs/go-bitswap/wantmanager/wantmanager.go new file mode 100644 index 00000000..4203d14f --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/wantmanager/wantmanager.go @@ -0,0 +1,282 @@ +package wantmanager + +import ( + "context" + "math" + + bsmsg "github.com/ipfs/go-bitswap/message" + wantlist "github.com/ipfs/go-bitswap/wantlist" + logging "github.com/ipfs/go-log" + + cid "github.com/ipfs/go-cid" + metrics "github.com/ipfs/go-metrics-interface" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("bitswap") + +const ( + // maxPriority is the max priority as defined by the bitswap protocol + maxPriority = math.MaxInt32 +) + +// PeerHandler sends changes out to the network as they get added to the wantlist +// managed by the WantManager. +type PeerHandler interface { + Disconnected(p peer.ID) + Connected(p peer.ID, initialWants *wantlist.SessionTrackedWantlist) + SendMessage(entries []bsmsg.Entry, targets []peer.ID, from uint64) +} + +type wantMessage interface { + handle(wm *WantManager) +} + +// WantManager manages a global want list. It tracks two seperate want lists - +// one for all wants, and one for wants that are specifically broadcast to the +// internet. +type WantManager struct { + // channel requests to the run loop + // to get predictable behavior while running this in a go routine + // having only one channel is neccesary, so requests are processed serially + wantMessages chan wantMessage + + // synchronized by Run loop, only touch inside there + wl *wantlist.SessionTrackedWantlist + bcwl *wantlist.SessionTrackedWantlist + + ctx context.Context + cancel func() + + peerHandler PeerHandler + wantlistGauge metrics.Gauge +} + +// New initializes a new WantManager for a given context. +func New(ctx context.Context, peerHandler PeerHandler) *WantManager { + ctx, cancel := context.WithCancel(ctx) + wantlistGauge := metrics.NewCtx(ctx, "wantlist_total", + "Number of items in wantlist.").Gauge() + return &WantManager{ + wantMessages: make(chan wantMessage, 10), + wl: wantlist.NewSessionTrackedWantlist(), + bcwl: wantlist.NewSessionTrackedWantlist(), + ctx: ctx, + cancel: cancel, + peerHandler: peerHandler, + wantlistGauge: wantlistGauge, + } +} + +// WantBlocks adds the given cids to the wantlist, tracked by the given session. +func (wm *WantManager) WantBlocks(ctx context.Context, ks []cid.Cid, peers []peer.ID, ses uint64) { + log.Infof("want blocks: %s", ks) + wm.addEntries(ctx, ks, peers, false, ses) +} + +// CancelWants removes the given cids from the wantlist, tracked by the given session. +func (wm *WantManager) CancelWants(ctx context.Context, ks []cid.Cid, peers []peer.ID, ses uint64) { + wm.addEntries(context.Background(), ks, peers, true, ses) +} + +// IsWanted returns whether a CID is currently wanted. +func (wm *WantManager) IsWanted(c cid.Cid) bool { + resp := make(chan bool, 1) + select { + case wm.wantMessages <- &isWantedMessage{c, resp}: + case <-wm.ctx.Done(): + return false + } + select { + case wanted := <-resp: + return wanted + case <-wm.ctx.Done(): + return false + } +} + +// CurrentWants returns the list of current wants. +func (wm *WantManager) CurrentWants() []wantlist.Entry { + resp := make(chan []wantlist.Entry, 1) + select { + case wm.wantMessages <- ¤tWantsMessage{resp}: + case <-wm.ctx.Done(): + return nil + } + select { + case wantlist := <-resp: + return wantlist + case <-wm.ctx.Done(): + return nil + } +} + +// CurrentBroadcastWants returns the current list of wants that are broadcasts. +func (wm *WantManager) CurrentBroadcastWants() []wantlist.Entry { + resp := make(chan []wantlist.Entry, 1) + select { + case wm.wantMessages <- ¤tBroadcastWantsMessage{resp}: + case <-wm.ctx.Done(): + return nil + } + select { + case wl := <-resp: + return wl + case <-wm.ctx.Done(): + return nil + } +} + +// WantCount returns the total count of wants. +func (wm *WantManager) WantCount() int { + resp := make(chan int, 1) + select { + case wm.wantMessages <- &wantCountMessage{resp}: + case <-wm.ctx.Done(): + return 0 + } + select { + case count := <-resp: + return count + case <-wm.ctx.Done(): + return 0 + } +} + +// Connected is called when a new peer is connected +func (wm *WantManager) Connected(p peer.ID) { + select { + case wm.wantMessages <- &connectedMessage{p}: + case <-wm.ctx.Done(): + } +} + +// Disconnected is called when a peer is disconnected +func (wm *WantManager) Disconnected(p peer.ID) { + select { + case wm.wantMessages <- &disconnectedMessage{p}: + case <-wm.ctx.Done(): + } +} + +// Startup starts processing for the WantManager. +func (wm *WantManager) Startup() { + go wm.run() +} + +// Shutdown ends processing for the want manager. +func (wm *WantManager) Shutdown() { + wm.cancel() +} + +func (wm *WantManager) run() { + // NOTE: Do not open any streams or connections from anywhere in this + // event loop. Really, just don't do anything likely to block. + for { + select { + case message := <-wm.wantMessages: + message.handle(wm) + case <-wm.ctx.Done(): + return + } + } +} + +func (wm *WantManager) addEntries(ctx context.Context, ks []cid.Cid, targets []peer.ID, cancel bool, ses uint64) { + entries := make([]bsmsg.Entry, 0, len(ks)) + for i, k := range ks { + entries = append(entries, bsmsg.Entry{ + Cancel: cancel, + Entry: wantlist.NewRefEntry(k, maxPriority-i), + }) + } + select { + case wm.wantMessages <- &wantSet{entries: entries, targets: targets, from: ses}: + case <-wm.ctx.Done(): + case <-ctx.Done(): + } +} + +type wantSet struct { + entries []bsmsg.Entry + targets []peer.ID + from uint64 +} + +func (ws *wantSet) handle(wm *WantManager) { + // is this a broadcast or not? + brdc := len(ws.targets) == 0 + + // add changes to our wantlist + for _, e := range ws.entries { + if e.Cancel { + if brdc { + wm.bcwl.Remove(e.Cid, ws.from) + } + + if wm.wl.Remove(e.Cid, ws.from) { + wm.wantlistGauge.Dec() + } + } else { + if brdc { + wm.bcwl.AddEntry(e.Entry, ws.from) + } + if wm.wl.AddEntry(e.Entry, ws.from) { + wm.wantlistGauge.Inc() + } + } + } + + // broadcast those wantlist changes + wm.peerHandler.SendMessage(ws.entries, ws.targets, ws.from) +} + +type isWantedMessage struct { + c cid.Cid + resp chan<- bool +} + +func (iwm *isWantedMessage) handle(wm *WantManager) { + _, isWanted := wm.wl.Contains(iwm.c) + iwm.resp <- isWanted +} + +type currentWantsMessage struct { + resp chan<- []wantlist.Entry +} + +func (cwm *currentWantsMessage) handle(wm *WantManager) { + cwm.resp <- wm.wl.Entries() +} + +type currentBroadcastWantsMessage struct { + resp chan<- []wantlist.Entry +} + +func (cbcwm *currentBroadcastWantsMessage) handle(wm *WantManager) { + cbcwm.resp <- wm.bcwl.Entries() +} + +type wantCountMessage struct { + resp chan<- int +} + +func (wcm *wantCountMessage) handle(wm *WantManager) { + wcm.resp <- wm.wl.Len() +} + +type connectedMessage struct { + p peer.ID +} + +func (cm *connectedMessage) handle(wm *WantManager) { + wm.peerHandler.Connected(cm.p, wm.bcwl) +} + +type disconnectedMessage struct { + p peer.ID +} + +func (dm *disconnectedMessage) handle(wm *WantManager) { + wm.peerHandler.Disconnected(dm.p) +} diff --git a/vendor/github.com/ipfs/go-bitswap/workers.go b/vendor/github.com/ipfs/go-bitswap/workers.go new file mode 100644 index 00000000..fb3dc019 --- /dev/null +++ b/vendor/github.com/ipfs/go-bitswap/workers.go @@ -0,0 +1,189 @@ +package bitswap + +import ( + "context" + + engine "github.com/ipfs/go-bitswap/decision" + bsmsg "github.com/ipfs/go-bitswap/message" + cid "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log" + process "github.com/jbenet/goprocess" + procctx "github.com/jbenet/goprocess/context" +) + +// TaskWorkerCount is the total number of simultaneous threads sending +// outgoing messages +var TaskWorkerCount = 8 + +func (bs *Bitswap) startWorkers(ctx context.Context, px process.Process) { + + // Start up workers to handle requests from other nodes for the data on this node + for i := 0; i < TaskWorkerCount; i++ { + i := i + px.Go(func(px process.Process) { + bs.taskWorker(ctx, i) + }) + } + + if bs.provideEnabled { + // Start up a worker to manage sending out provides messages + px.Go(func(px process.Process) { + bs.provideCollector(ctx) + }) + + // Spawn up multiple workers to handle incoming blocks + // consider increasing number if providing blocks bottlenecks + // file transfers + px.Go(bs.provideWorker) + } +} + +func (bs *Bitswap) taskWorker(ctx context.Context, id int) { + idmap := logging.LoggableMap{"ID": id} + defer log.Debug("bitswap task worker shutting down...") + for { + log.Event(ctx, "Bitswap.TaskWorker.Loop", idmap) + select { + case nextEnvelope := <-bs.engine.Outbox(): + select { + case envelope, ok := <-nextEnvelope: + if !ok { + continue + } + // update the BS ledger to reflect sent message + // TODO: Should only track *useful* messages in ledger + outgoing := bsmsg.New(false) + for _, block := range envelope.Message.Blocks() { + log.Event(ctx, "Bitswap.TaskWorker.Work", logging.LoggableF(func() map[string]interface{} { + return logging.LoggableMap{ + "ID": id, + "Target": envelope.Peer.Pretty(), + "Block": block.Cid().String(), + } + })) + outgoing.AddBlock(block) + } + bs.engine.MessageSent(envelope.Peer, outgoing) + + bs.sendBlocks(ctx, envelope) + bs.counterLk.Lock() + for _, block := range envelope.Message.Blocks() { + bs.counters.blocksSent++ + bs.counters.dataSent += uint64(len(block.RawData())) + } + bs.counterLk.Unlock() + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } +} + +func (bs *Bitswap) sendBlocks(ctx context.Context, env *engine.Envelope) { + // Blocks need to be sent synchronously to maintain proper backpressure + // throughout the network stack + defer env.Sent() + + msgSize := 0 + msg := bsmsg.New(false) + for _, block := range env.Message.Blocks() { + msgSize += len(block.RawData()) + msg.AddBlock(block) + log.Infof("Sending block %s to %s", block, env.Peer) + } + + bs.sentHistogram.Observe(float64(msgSize)) + err := bs.network.SendMessage(ctx, env.Peer, msg) + if err != nil { + log.Infof("sendblock error: %s", err) + } +} + +func (bs *Bitswap) provideWorker(px process.Process) { + // FIXME: OnClosingContext returns a _custom_ context type. + // Unfortunately, deriving a new cancelable context from this custom + // type fires off a goroutine. To work around this, we create a single + // cancelable context up-front and derive all sub-contexts from that. + // + // See: https://github.com/ipfs/go-ipfs/issues/5810 + ctx := procctx.OnClosingContext(px) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + limit := make(chan struct{}, provideWorkerMax) + + limitedGoProvide := func(k cid.Cid, wid int) { + defer func() { + // replace token when done + <-limit + }() + ev := logging.LoggableMap{"ID": wid} + + defer log.EventBegin(ctx, "Bitswap.ProvideWorker.Work", ev, k).Done() + + ctx, cancel := context.WithTimeout(ctx, provideTimeout) // timeout ctx + defer cancel() + + if err := bs.network.Provide(ctx, k); err != nil { + log.Warning(err) + } + } + + // worker spawner, reads from bs.provideKeys until it closes, spawning a + // _ratelimited_ number of workers to handle each key. + for wid := 2; ; wid++ { + ev := logging.LoggableMap{"ID": 1} + log.Event(ctx, "Bitswap.ProvideWorker.Loop", ev) + + select { + case <-px.Closing(): + return + case k, ok := <-bs.provideKeys: + if !ok { + log.Debug("provideKeys channel closed") + return + } + select { + case <-px.Closing(): + return + case limit <- struct{}{}: + go limitedGoProvide(k, wid) + } + } + } +} + +func (bs *Bitswap) provideCollector(ctx context.Context) { + defer close(bs.provideKeys) + var toProvide []cid.Cid + var nextKey cid.Cid + var keysOut chan cid.Cid + + for { + select { + case blkey, ok := <-bs.newBlocks: + if !ok { + log.Debug("newBlocks channel closed") + return + } + + if keysOut == nil { + nextKey = blkey + keysOut = bs.provideKeys + } else { + toProvide = append(toProvide, blkey) + } + case keysOut <- nextKey: + if len(toProvide) > 0 { + nextKey = toProvide[0] + toProvide = toProvide[1:] + } else { + keysOut = nil + } + case <-ctx.Done(): + return + } + } +} diff --git a/vendor/github.com/ipfs/go-block-format/.travis.yml b/vendor/github.com/ipfs/go-block-format/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-block-format/LICENSE b/vendor/github.com/ipfs/go-block-format/LICENSE new file mode 100644 index 00000000..8001ebee --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2017 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-block-format/Makefile b/vendor/github.com/ipfs/go-block-format/Makefile new file mode 100644 index 00000000..7811c099 --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/Makefile @@ -0,0 +1,15 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +covertools: + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +deps: gx covertools + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-block-format/README.md b/vendor/github.com/ipfs/go-block-format/README.md new file mode 100644 index 00000000..67cd1fcd --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/README.md @@ -0,0 +1,35 @@ +go-block-format +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-block-format/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-block-format/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-block-format.svg?branch=master)](https://travis-ci.org/ipfs/go-block-format) + +> go-block-format is a set of interfaces that a type needs to implement in order to be a CID addressable block of data. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-block-format/blocks.go b/vendor/github.com/ipfs/go-block-format/blocks.go new file mode 100644 index 00000000..3d3894b3 --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/blocks.go @@ -0,0 +1,82 @@ +// Package blocks contains the lowest level of IPLD data structures. +// A block is raw data accompanied by a CID. The CID contains the multihash +// corresponding to the block. +package blocks + +import ( + "errors" + "fmt" + + cid "github.com/ipfs/go-cid" + u "github.com/ipfs/go-ipfs-util" + mh "github.com/multiformats/go-multihash" +) + +// ErrWrongHash is returned when the Cid of a block is not the expected +// according to the contents. It is currently used only when debugging. +var ErrWrongHash = errors.New("data did not match given hash") + +// Block provides abstraction for blocks implementations. +type Block interface { + RawData() []byte + Cid() cid.Cid + String() string + Loggable() map[string]interface{} +} + +// A BasicBlock is a singular block of data in ipfs. It implements the Block +// interface. +type BasicBlock struct { + cid cid.Cid + data []byte +} + +// NewBlock creates a Block object from opaque data. It will hash the data. +func NewBlock(data []byte) *BasicBlock { + // TODO: fix assumptions + return &BasicBlock{data: data, cid: cid.NewCidV0(u.Hash(data))} +} + +// NewBlockWithCid creates a new block when the hash of the data +// is already known, this is used to save time in situations where +// we are able to be confident that the data is correct. +func NewBlockWithCid(data []byte, c cid.Cid) (*BasicBlock, error) { + if u.Debug { + chkc, err := c.Prefix().Sum(data) + if err != nil { + return nil, err + } + + if !chkc.Equals(c) { + return nil, ErrWrongHash + } + } + return &BasicBlock{data: data, cid: c}, nil +} + +// Multihash returns the hash contained in the block CID. +func (b *BasicBlock) Multihash() mh.Multihash { + return b.cid.Hash() +} + +// RawData returns the block raw contents as a byte slice. +func (b *BasicBlock) RawData() []byte { + return b.data +} + +// Cid returns the content identifier of the block. +func (b *BasicBlock) Cid() cid.Cid { + return b.cid +} + +// String provides a human-readable representation of the block CID. +func (b *BasicBlock) String() string { + return fmt.Sprintf("[Block %s]", b.Cid()) +} + +// Loggable returns a go-log loggable item. +func (b *BasicBlock) Loggable() map[string]interface{} { + return map[string]interface{}{ + "block": b.Cid().String(), + } +} diff --git a/vendor/github.com/ipfs/go-block-format/codecov.yml b/vendor/github.com/ipfs/go-block-format/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-block-format/go.mod b/vendor/github.com/ipfs/go-block-format/go.mod new file mode 100644 index 00000000..f6ab8eab --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-block-format + +require ( + github.com/ipfs/go-cid v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-block-format/go.sum b/vendor/github.com/ipfs/go-block-format/go.sum new file mode 100644 index 00000000..3fb22960 --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/go.sum @@ -0,0 +1,24 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-block-format/package.json b/vendor/github.com/ipfs/go-block-format/package.json new file mode 100644 index 00000000..970ac559 --- /dev/null +++ b/vendor/github.com/ipfs/go-block-format/package.json @@ -0,0 +1,36 @@ +{ + "author": "stebalien", + "bugs": { + "url": "https://github.com/ipfs/go-block-format" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-block-format" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + } + ], + "gxVersion": "0.11.0", + "language": "go", + "license": "", + "name": "go-block-format", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.2.2" +} + diff --git a/vendor/github.com/ipfs/go-blockservice/.travis.yml b/vendor/github.com/ipfs/go-blockservice/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-blockservice/LICENSE b/vendor/github.com/ipfs/go-blockservice/LICENSE new file mode 100644 index 00000000..7d5dcac4 --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-blockservice/README.md b/vendor/github.com/ipfs/go-blockservice/README.md new file mode 100644 index 00000000..3df67fde --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/README.md @@ -0,0 +1,33 @@ +go-blockservice +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-block-format/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-block-format/branch/master) +[![Travis CI](https://travis-ci.com/ipfs/go-blockservice.svg?branch=master)](https://travis-ci.com/ipfs/go-blockservice) + +> go-blockservice provides a seamless interface to both local and remote storage backends. + + +## Table of Contents + +- [TODO](#todo) +- [Contribute](#contribute) +- [License](#license) + +## TODO + +The interfaces here really would like to be merged with the blockstore interfaces. +The 'dagservice' constructor currently takes a blockservice, but it would be really nice +if it could just take a blockstore, and have this package implement a blockstore. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-blockservice/blockservice.go b/vendor/github.com/ipfs/go-blockservice/blockservice.go new file mode 100644 index 00000000..ba88d1c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/blockservice.go @@ -0,0 +1,359 @@ +// package blockservice implements a BlockService interface that provides +// a single GetBlock/AddBlock interface that seamlessly retrieves data either +// locally or from a remote peer through the exchange. +package blockservice + +import ( + "context" + "errors" + "io" + "sync" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" + exchange "github.com/ipfs/go-ipfs-exchange-interface" + logging "github.com/ipfs/go-log" + "github.com/ipfs/go-verifcid" +) + +var log = logging.Logger("blockservice") + +var ErrNotFound = errors.New("blockservice: key not found") + +// BlockGetter is the common interface shared between blockservice sessions and +// the blockservice. +type BlockGetter interface { + // GetBlock gets the requested block. + GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, error) + + // GetBlocks does a batch request for the given cids, returning blocks as + // they are found, in no particular order. + // + // It may not be able to find all requested blocks (or the context may + // be canceled). In that case, it will close the channel early. It is up + // to the consumer to detect this situation and keep track which blocks + // it has received and which it hasn't. + GetBlocks(ctx context.Context, ks []cid.Cid) <-chan blocks.Block +} + +// BlockService is a hybrid block datastore. It stores data in a local +// datastore and may retrieve data from a remote Exchange. +// It uses an internal `datastore.Datastore` instance to store values. +type BlockService interface { + io.Closer + BlockGetter + + // Blockstore returns a reference to the underlying blockstore + Blockstore() blockstore.Blockstore + + // Exchange returns a reference to the underlying exchange (usually bitswap) + Exchange() exchange.Interface + + // AddBlock puts a given block to the underlying datastore + AddBlock(o blocks.Block) error + + // AddBlocks adds a slice of blocks at the same time using batching + // capabilities of the underlying datastore whenever possible. + AddBlocks(bs []blocks.Block) error + + // DeleteBlock deletes the given block from the blockservice. + DeleteBlock(o cid.Cid) error +} + +type blockService struct { + blockstore blockstore.Blockstore + exchange exchange.Interface + // If checkFirst is true then first check that a block doesn't + // already exist to avoid republishing the block on the exchange. + checkFirst bool +} + +// NewBlockService creates a BlockService with given datastore instance. +func New(bs blockstore.Blockstore, rem exchange.Interface) BlockService { + if rem == nil { + log.Warning("blockservice running in local (offline) mode.") + } + + return &blockService{ + blockstore: bs, + exchange: rem, + checkFirst: true, + } +} + +// NewWriteThrough ceates a BlockService that guarantees writes will go +// through to the blockstore and are not skipped by cache checks. +func NewWriteThrough(bs blockstore.Blockstore, rem exchange.Interface) BlockService { + if rem == nil { + log.Warning("blockservice running in local (offline) mode.") + } + + return &blockService{ + blockstore: bs, + exchange: rem, + checkFirst: false, + } +} + +// Blockstore returns the blockstore behind this blockservice. +func (s *blockService) Blockstore() blockstore.Blockstore { + return s.blockstore +} + +// Exchange returns the exchange behind this blockservice. +func (s *blockService) Exchange() exchange.Interface { + return s.exchange +} + +// NewSession creates a new session that allows for +// controlled exchange of wantlists to decrease the bandwidth overhead. +// If the current exchange is a SessionExchange, a new exchange +// session will be created. Otherwise, the current exchange will be used +// directly. +func NewSession(ctx context.Context, bs BlockService) *Session { + exch := bs.Exchange() + if sessEx, ok := exch.(exchange.SessionExchange); ok { + return &Session{ + sessCtx: ctx, + ses: nil, + sessEx: sessEx, + bs: bs.Blockstore(), + } + } + return &Session{ + ses: exch, + sessCtx: ctx, + bs: bs.Blockstore(), + } +} + +// AddBlock adds a particular block to the service, Putting it into the datastore. +// TODO pass a context into this if the remote.HasBlock is going to remain here. +func (s *blockService) AddBlock(o blocks.Block) error { + c := o.Cid() + // hash security + err := verifcid.ValidateCid(c) + if err != nil { + return err + } + if s.checkFirst { + if has, err := s.blockstore.Has(c); has || err != nil { + return err + } + } + + if err := s.blockstore.Put(o); err != nil { + return err + } + + log.Event(context.TODO(), "BlockService.BlockAdded", c) + + if err := s.exchange.HasBlock(o); err != nil { + log.Errorf("HasBlock: %s", err.Error()) + } + + return nil +} + +func (s *blockService) AddBlocks(bs []blocks.Block) error { + // hash security + for _, b := range bs { + err := verifcid.ValidateCid(b.Cid()) + if err != nil { + return err + } + } + var toput []blocks.Block + if s.checkFirst { + toput = make([]blocks.Block, 0, len(bs)) + for _, b := range bs { + has, err := s.blockstore.Has(b.Cid()) + if err != nil { + return err + } + if !has { + toput = append(toput, b) + } + } + } else { + toput = bs + } + + if len(toput) == 0 { + return nil + } + + err := s.blockstore.PutMany(toput) + if err != nil { + return err + } + + for _, o := range toput { + log.Event(context.TODO(), "BlockService.BlockAdded", o.Cid()) + if err := s.exchange.HasBlock(o); err != nil { + log.Errorf("HasBlock: %s", err.Error()) + } + } + return nil +} + +// GetBlock retrieves a particular block from the service, +// Getting it from the datastore using the key (hash). +func (s *blockService) GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, error) { + log.Debugf("BlockService GetBlock: '%s'", c) + + var f func() exchange.Fetcher + if s.exchange != nil { + f = s.getExchange + } + + return getBlock(ctx, c, s.blockstore, f) // hash security +} + +func (s *blockService) getExchange() exchange.Fetcher { + return s.exchange +} + +func getBlock(ctx context.Context, c cid.Cid, bs blockstore.Blockstore, fget func() exchange.Fetcher) (blocks.Block, error) { + err := verifcid.ValidateCid(c) // hash security + if err != nil { + return nil, err + } + + block, err := bs.Get(c) + if err == nil { + return block, nil + } + + if err == blockstore.ErrNotFound && fget != nil { + f := fget() // Don't load the exchange until we have to + + // TODO be careful checking ErrNotFound. If the underlying + // implementation changes, this will break. + log.Debug("Blockservice: Searching bitswap") + blk, err := f.GetBlock(ctx, c) + if err != nil { + if err == blockstore.ErrNotFound { + return nil, ErrNotFound + } + return nil, err + } + log.Event(ctx, "BlockService.BlockFetched", c) + return blk, nil + } + + log.Debug("Blockservice GetBlock: Not found") + if err == blockstore.ErrNotFound { + return nil, ErrNotFound + } + + return nil, err +} + +// GetBlocks gets a list of blocks asynchronously and returns through +// the returned channel. +// NB: No guarantees are made about order. +func (s *blockService) GetBlocks(ctx context.Context, ks []cid.Cid) <-chan blocks.Block { + return getBlocks(ctx, ks, s.blockstore, s.getExchange) // hash security +} + +func getBlocks(ctx context.Context, ks []cid.Cid, bs blockstore.Blockstore, fget func() exchange.Fetcher) <-chan blocks.Block { + out := make(chan blocks.Block) + + go func() { + defer close(out) + + k := 0 + for _, c := range ks { + // hash security + if err := verifcid.ValidateCid(c); err == nil { + ks[k] = c + k++ + } else { + log.Errorf("unsafe CID (%s) passed to blockService.GetBlocks: %s", c, err) + } + } + ks = ks[:k] + + var misses []cid.Cid + for _, c := range ks { + hit, err := bs.Get(c) + if err != nil { + misses = append(misses, c) + continue + } + select { + case out <- hit: + case <-ctx.Done(): + return + } + } + + if len(misses) == 0 { + return + } + + f := fget() // don't load exchange unless we have to + rblocks, err := f.GetBlocks(ctx, misses) + if err != nil { + log.Debugf("Error with GetBlocks: %s", err) + return + } + + for b := range rblocks { + log.Event(ctx, "BlockService.BlockFetched", b.Cid()) + select { + case out <- b: + case <-ctx.Done(): + return + } + } + }() + return out +} + +// DeleteBlock deletes a block in the blockservice from the datastore +func (s *blockService) DeleteBlock(c cid.Cid) error { + err := s.blockstore.DeleteBlock(c) + if err == nil { + log.Event(context.TODO(), "BlockService.BlockDeleted", c) + } + return err +} + +func (s *blockService) Close() error { + log.Debug("blockservice is shutting down...") + return s.exchange.Close() +} + +// Session is a helper type to provide higher level access to bitswap sessions +type Session struct { + bs blockstore.Blockstore + ses exchange.Fetcher + sessEx exchange.SessionExchange + sessCtx context.Context + lk sync.Mutex +} + +func (s *Session) getSession() exchange.Fetcher { + s.lk.Lock() + defer s.lk.Unlock() + if s.ses == nil { + s.ses = s.sessEx.NewSession(s.sessCtx) + } + + return s.ses +} + +// GetBlock gets a block in the context of a request session +func (s *Session) GetBlock(ctx context.Context, c cid.Cid) (blocks.Block, error) { + return getBlock(ctx, c, s.bs, s.getSession) // hash security +} + +// GetBlocks gets blocks in the context of a request session +func (s *Session) GetBlocks(ctx context.Context, ks []cid.Cid) <-chan blocks.Block { + return getBlocks(ctx, ks, s.bs, s.getSession) // hash security +} + +var _ BlockGetter = (*Session)(nil) diff --git a/vendor/github.com/ipfs/go-blockservice/go.mod b/vendor/github.com/ipfs/go-blockservice/go.mod new file mode 100644 index 00000000..4644e9fa --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/go.mod @@ -0,0 +1,17 @@ +module github.com/ipfs/go-blockservice + +require ( + github.com/ipfs/go-bitswap v0.1.3 + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs-blockstore v0.0.1 + github.com/ipfs/go-ipfs-blocksutil v0.0.1 + github.com/ipfs/go-ipfs-delay v0.0.1 + github.com/ipfs/go-ipfs-exchange-interface v0.0.1 + github.com/ipfs/go-ipfs-exchange-offline v0.0.1 + github.com/ipfs/go-ipfs-routing v0.1.0 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-verifcid v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-blockservice/go.sum b/vendor/github.com/ipfs/go-blockservice/go.sum new file mode 100644 index 00000000..5cba9762 --- /dev/null +++ b/vendor/github.com/ipfs/go-blockservice/go.sum @@ -0,0 +1,335 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 h1:4i3KsuVA0o0KoBxAC5x+MY7RbteiMK1V7gf/G08NGIQ= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.1.3 h1:jAl9Z/TYObpGeGATUemnOZ7RYb0F/kzNVlhcYZesz+0= +github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.1.1 h1:+gPjbI+V3NktXZOqJA1kzbms2pYmhjgQQal0MzZrOAY= +github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.1 h1:52sB0TJuDk2nYMcMfHOKaPoaayDZjaYVCq6Vk1ejUTk= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2 h1:86uOwW+O6Uc7NbaK4diuLZo2/Ikvqw2rgyV03VcSbLE= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3 h1:+IonUYY0nJZLb5Fdv6a6DOjtGP1L8Bb3faamiI2q5FY= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3 h1:VsOlWispTivSsOMg70e0W77y6oiSBSRCyP6URrWvE04= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-cid/.gitignore b/vendor/github.com/ipfs/go-cid/.gitignore new file mode 100644 index 00000000..aaea8ed0 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/.gitignore @@ -0,0 +1 @@ +cid-fuzz.zip diff --git a/vendor/github.com/ipfs/go-cid/.travis.yml b/vendor/github.com/ipfs/go-cid/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-cid/LICENSE b/vendor/github.com/ipfs/go-cid/LICENSE new file mode 100644 index 00000000..0e323020 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Protocol Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-cid/Makefile b/vendor/github.com/ipfs/go-cid/Makefile new file mode 100644 index 00000000..e6bdd2c9 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/Makefile @@ -0,0 +1,16 @@ +all: deps + +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +covertools: + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +deps: gx covertools + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo diff --git a/vendor/github.com/ipfs/go-cid/README.md b/vendor/github.com/ipfs/go-cid/README.md new file mode 100644 index 00000000..0824d519 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/README.md @@ -0,0 +1,125 @@ +go-cid +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-cid?status.svg)](https://godoc.org/github.com/ipfs/go-cid) +[![Coverage Status](https://coveralls.io/repos/github/ipfs/go-cid/badge.svg?branch=master)](https://coveralls.io/github/ipfs/go-cid?branch=master) +[![Travis CI](https://travis-ci.org/ipfs/go-cid.svg?branch=master)](https://travis-ci.org/ipfs/go-cid) + +> A package to handle content IDs in Go. + +This is an implementation in Go of the [CID spec](https://github.com/ipld/cid). +It is used in `go-ipfs` and related packages to refer to a typed hunk of data. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-cid` is a standard Go module which can be installed with: + +```sh +go get github.com/ipfs/go-cid +``` + +Note that `go-cid` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section). + +## Usage + +### Using Gx and Gx-go + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/ipfs/go-cid +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +### Running tests + +Before running tests, please run: + +```sh +make deps +``` + +This will make sure that dependencies are rewritten to known working versions. + +### Examples + +#### Parsing string input from users + +```go +// Create a cid from a marshaled string +c, err := cid.Decode("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm") +if err != nil {...} + +fmt.Println("Got CID: ", c) +``` + +#### Creating a CID from scratch + +```go +// Create a cid manually by specifying the 'prefix' parameters +pref := cid.Prefix{ + Version: 1, + Codec: cid.Raw, + MhType: mh.SHA2_256, + MhLength: -1, // default length +} + +// And then feed it some data +c, err := pref.Sum([]byte("Hello World!")) +if err != nil {...} + +fmt.Println("Created CID: ", c) +``` + +#### Check if two CIDs match + +```go +// To test if two cid's are equivalent, be sure to use the 'Equals' method: +if c1.Equals(c2) { + fmt.Println("These two refer to the same exact data!") +} +``` + +#### Check if some data matches a given CID + +```go +// To check if some data matches a given cid, +// Get your CIDs prefix, and use that to sum the data in question: +other, err := c.Prefix().Sum(mydata) +if err != nil {...} + +if !c.Equals(other) { + fmt.Println("This data is different.") +} + +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson diff --git a/vendor/github.com/ipfs/go-cid/builder.go b/vendor/github.com/ipfs/go-cid/builder.go new file mode 100644 index 00000000..a1688327 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/builder.go @@ -0,0 +1,74 @@ +package cid + +import ( + mh "github.com/multiformats/go-multihash" +) + +type Builder interface { + Sum(data []byte) (Cid, error) + GetCodec() uint64 + WithCodec(uint64) Builder +} + +type V0Builder struct{} + +type V1Builder struct { + Codec uint64 + MhType uint64 + MhLength int // MhLength <= 0 means the default length +} + +func (p Prefix) GetCodec() uint64 { + return p.Codec +} + +func (p Prefix) WithCodec(c uint64) Builder { + if c == p.Codec { + return p + } + p.Codec = c + if c != DagProtobuf { + p.Version = 1 + } + return p +} + +func (p V0Builder) Sum(data []byte) (Cid, error) { + hash, err := mh.Sum(data, mh.SHA2_256, -1) + if err != nil { + return Undef, err + } + return NewCidV0(hash), nil +} + +func (p V0Builder) GetCodec() uint64 { + return DagProtobuf +} + +func (p V0Builder) WithCodec(c uint64) Builder { + if c == DagProtobuf { + return p + } + return V1Builder{Codec: c, MhType: mh.SHA2_256} +} + +func (p V1Builder) Sum(data []byte) (Cid, error) { + mhLen := p.MhLength + if mhLen <= 0 { + mhLen = -1 + } + hash, err := mh.Sum(data, p.MhType, mhLen) + if err != nil { + return Undef, err + } + return NewCidV1(p.Codec, hash), nil +} + +func (p V1Builder) GetCodec() uint64 { + return p.Codec +} + +func (p V1Builder) WithCodec(c uint64) Builder { + p.Codec = c + return p +} diff --git a/vendor/github.com/ipfs/go-cid/cid.go b/vendor/github.com/ipfs/go-cid/cid.go new file mode 100644 index 00000000..6b62d30d --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/cid.go @@ -0,0 +1,601 @@ +// Package cid implements the Content-IDentifiers specification +// (https://github.com/ipld/cid) in Go. CIDs are +// self-describing content-addressed identifiers useful for +// distributed information systems. CIDs are used in the IPFS +// (https://ipfs.io) project ecosystem. +// +// CIDs have two major versions. A CIDv0 corresponds to a multihash of type +// DagProtobuf, is deprecated and exists for compatibility reasons. Usually, +// CIDv1 should be used. +// +// A CIDv1 has four parts: +// +// ::= +// +// As shown above, the CID implementation relies heavily on Multiformats, +// particularly Multibase +// (https://github.com/multiformats/go-multibase), Multicodec +// (https://github.com/multiformats/multicodec) and Multihash +// implementations (https://github.com/multiformats/go-multihash). +package cid + +import ( + "bytes" + "encoding" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "strings" + + mbase "github.com/multiformats/go-multibase" + mh "github.com/multiformats/go-multihash" +) + +// UnsupportedVersionString just holds an error message +const UnsupportedVersionString = "" + +var ( + // ErrVarintBuffSmall means that a buffer passed to the cid parser was not + // long enough, or did not contain an invalid cid + ErrVarintBuffSmall = errors.New("reading varint: buffer too small") + + // ErrVarintTooBig means that the varint in the given cid was above the + // limit of 2^64 + ErrVarintTooBig = errors.New("reading varint: varint bigger than 64bits" + + " and not supported") + + // ErrCidTooShort means that the cid passed to decode was not long + // enough to be a valid Cid + ErrCidTooShort = errors.New("cid too short") + + // ErrInvalidEncoding means that selected encoding is not supported + // by this Cid version + ErrInvalidEncoding = errors.New("invalid base encoding") +) + +// These are multicodec-packed content types. The should match +// the codes described in the authoritative document: +// https://github.com/multiformats/multicodec/blob/master/table.csv +const ( + Raw = 0x55 + + DagProtobuf = 0x70 + DagCBOR = 0x71 + + GitRaw = 0x78 + + EthBlock = 0x90 + EthBlockList = 0x91 + EthTxTrie = 0x92 + EthTx = 0x93 + EthTxReceiptTrie = 0x94 + EthTxReceipt = 0x95 + EthStateTrie = 0x96 + EthAccountSnapshot = 0x97 + EthStorageTrie = 0x98 + BitcoinBlock = 0xb0 + BitcoinTx = 0xb1 + ZcashBlock = 0xc0 + ZcashTx = 0xc1 + DecredBlock = 0xe0 + DecredTx = 0xe1 + DashBlock = 0xf0 + DashTx = 0xf1 +) + +// Codecs maps the name of a codec to its type +var Codecs = map[string]uint64{ + "v0": DagProtobuf, + "raw": Raw, + "protobuf": DagProtobuf, + "cbor": DagCBOR, + "git-raw": GitRaw, + "eth-block": EthBlock, + "eth-block-list": EthBlockList, + "eth-tx-trie": EthTxTrie, + "eth-tx": EthTx, + "eth-tx-receipt-trie": EthTxReceiptTrie, + "eth-tx-receipt": EthTxReceipt, + "eth-state-trie": EthStateTrie, + "eth-account-snapshot": EthAccountSnapshot, + "eth-storage-trie": EthStorageTrie, + "bitcoin-block": BitcoinBlock, + "bitcoin-tx": BitcoinTx, + "zcash-block": ZcashBlock, + "zcash-tx": ZcashTx, + "decred-block": DecredBlock, + "decred-tx": DecredTx, + "dash-block": DashBlock, + "dash-tx": DashTx, +} + +// CodecToStr maps the numeric codec to its name +var CodecToStr = map[uint64]string{ + Raw: "raw", + DagProtobuf: "protobuf", + DagCBOR: "cbor", + GitRaw: "git-raw", + EthBlock: "eth-block", + EthBlockList: "eth-block-list", + EthTxTrie: "eth-tx-trie", + EthTx: "eth-tx", + EthTxReceiptTrie: "eth-tx-receipt-trie", + EthTxReceipt: "eth-tx-receipt", + EthStateTrie: "eth-state-trie", + EthAccountSnapshot: "eth-account-snapshot", + EthStorageTrie: "eth-storage-trie", + BitcoinBlock: "bitcoin-block", + BitcoinTx: "bitcoin-tx", + ZcashBlock: "zcash-block", + ZcashTx: "zcash-tx", + DecredBlock: "decred-block", + DecredTx: "decred-tx", + DashBlock: "dash-block", + DashTx: "dash-tx", +} + +// NewCidV0 returns a Cid-wrapped multihash. +// They exist to allow IPFS to work with Cids while keeping +// compatibility with the plain-multihash format used used in IPFS. +// NewCidV1 should be used preferentially. +func NewCidV0(mhash mh.Multihash) Cid { + // Need to make sure hash is valid for CidV0 otherwise we will + // incorrectly detect it as CidV1 in the Version() method + dec, err := mh.Decode(mhash) + if err != nil { + panic(err) + } + if dec.Code != mh.SHA2_256 || dec.Length != 32 { + panic("invalid hash for cidv0") + } + return Cid{string(mhash)} +} + +// NewCidV1 returns a new Cid using the given multicodec-packed +// content type. +func NewCidV1(codecType uint64, mhash mh.Multihash) Cid { + hashlen := len(mhash) + // two 8 bytes (max) numbers plus hash + buf := make([]byte, 2*binary.MaxVarintLen64+hashlen) + n := binary.PutUvarint(buf, 1) + n += binary.PutUvarint(buf[n:], codecType) + cn := copy(buf[n:], mhash) + if cn != hashlen { + panic("copy hash length is inconsistent") + } + + return Cid{string(buf[:n+hashlen])} +} + +var _ encoding.BinaryMarshaler = Cid{} +var _ encoding.BinaryUnmarshaler = (*Cid)(nil) +var _ encoding.TextMarshaler = Cid{} +var _ encoding.TextUnmarshaler = (*Cid)(nil) + +// Cid represents a self-describing content addressed +// identifier. It is formed by a Version, a Codec (which indicates +// a multicodec-packed content type) and a Multihash. +type Cid struct{ str string } + +// Undef can be used to represent a nil or undefined Cid, using Cid{} +// directly is also acceptable. +var Undef = Cid{} + +// Defined returns true if a Cid is defined +// Calling any other methods on an undefined Cid will result in +// undefined behavior. +func (c Cid) Defined() bool { + return c.str != "" +} + +// Parse is a short-hand function to perform Decode, Cast etc... on +// a generic interface{} type. +func Parse(v interface{}) (Cid, error) { + switch v2 := v.(type) { + case string: + if strings.Contains(v2, "/ipfs/") { + return Decode(strings.Split(v2, "/ipfs/")[1]) + } + return Decode(v2) + case []byte: + return Cast(v2) + case mh.Multihash: + return NewCidV0(v2), nil + case Cid: + return v2, nil + default: + return Undef, fmt.Errorf("can't parse %+v as Cid", v2) + } +} + +// Decode parses a Cid-encoded string and returns a Cid object. +// For CidV1, a Cid-encoded string is primarily a multibase string: +// +// +// +// The base-encoded string represents a: +// +// +// +// Decode will also detect and parse CidV0 strings. Strings +// starting with "Qm" are considered CidV0 and treated directly +// as B58-encoded multihashes. +func Decode(v string) (Cid, error) { + if len(v) < 2 { + return Undef, ErrCidTooShort + } + + if len(v) == 46 && v[:2] == "Qm" { + hash, err := mh.FromB58String(v) + if err != nil { + return Undef, err + } + + return NewCidV0(hash), nil + } + + _, data, err := mbase.Decode(v) + if err != nil { + return Undef, err + } + + return Cast(data) +} + +// Extract the encoding from a Cid. If Decode on the same string did +// not return an error neither will this function. +func ExtractEncoding(v string) (mbase.Encoding, error) { + if len(v) < 2 { + return -1, ErrCidTooShort + } + + if len(v) == 46 && v[:2] == "Qm" { + return mbase.Base58BTC, nil + } + + encoding := mbase.Encoding(v[0]) + + // check encoding is valid + _, err := mbase.NewEncoder(encoding) + if err != nil { + return -1, err + } + + return encoding, nil +} + +func uvError(read int) error { + switch { + case read == 0: + return ErrVarintBuffSmall + case read < 0: + return ErrVarintTooBig + default: + return nil + } +} + +// Cast takes a Cid data slice, parses it and returns a Cid. +// For CidV1, the data buffer is in the form: +// +// +// +// CidV0 are also supported. In particular, data buffers starting +// with length 34 bytes, which starts with bytes [18,32...] are considered +// binary multihashes. +// +// Please use decode when parsing a regular Cid string, as Cast does not +// expect multibase-encoded data. Cast accepts the output of Cid.Bytes(). +func Cast(data []byte) (Cid, error) { + if len(data) == 34 && data[0] == 18 && data[1] == 32 { + h, err := mh.Cast(data) + if err != nil { + return Undef, err + } + + return NewCidV0(h), nil + } + + vers, n := binary.Uvarint(data) + if err := uvError(n); err != nil { + return Undef, err + } + + if vers != 1 { + return Undef, fmt.Errorf("expected 1 as the cid version number, got: %d", vers) + } + + _, cn := binary.Uvarint(data[n:]) + if err := uvError(cn); err != nil { + return Undef, err + } + + rest := data[n+cn:] + h, err := mh.Cast(rest) + if err != nil { + return Undef, err + } + + return Cid{string(data[0 : n+cn+len(h)])}, nil +} + +// UnmarshalBinary is equivalent to Cast(). It implements the +// encoding.BinaryUnmarshaler interface. +func (c *Cid) UnmarshalBinary(data []byte) error { + casted, err := Cast(data) + if err != nil { + return err + } + c.str = casted.str + return nil +} + +// UnmarshalText is equivalent to Decode(). It implements the +// encoding.TextUnmarshaler interface. +func (c *Cid) UnmarshalText(text []byte) error { + decodedCid, err := Decode(string(text)) + if err != nil { + return err + } + c.str = decodedCid.str + return nil +} + +// Version returns the Cid version. +func (c Cid) Version() uint64 { + if len(c.str) == 34 && c.str[0] == 18 && c.str[1] == 32 { + return 0 + } + return 1 +} + +// Type returns the multicodec-packed content type of a Cid. +func (c Cid) Type() uint64 { + if c.Version() == 0 { + return DagProtobuf + } + _, n := uvarint(c.str) + codec, _ := uvarint(c.str[n:]) + return codec +} + +// String returns the default string representation of a +// Cid. Currently, Base58 is used as the encoding for the +// multibase string. +func (c Cid) String() string { + switch c.Version() { + case 0: + return c.Hash().B58String() + case 1: + mbstr, err := mbase.Encode(mbase.Base32, c.Bytes()) + if err != nil { + panic("should not error with hardcoded mbase: " + err.Error()) + } + + return mbstr + default: + panic("not possible to reach this point") + } +} + +// String returns the string representation of a Cid +// encoded is selected base +func (c Cid) StringOfBase(base mbase.Encoding) (string, error) { + switch c.Version() { + case 0: + if base != mbase.Base58BTC { + return "", ErrInvalidEncoding + } + return c.Hash().B58String(), nil + case 1: + return mbase.Encode(base, c.Bytes()) + default: + panic("not possible to reach this point") + } +} + +// Encode return the string representation of a Cid in a given base +// when applicable. Version 0 Cid's are always in Base58 as they do +// not take a multibase prefix. +func (c Cid) Encode(base mbase.Encoder) string { + switch c.Version() { + case 0: + return c.Hash().B58String() + case 1: + return base.Encode(c.Bytes()) + default: + panic("not possible to reach this point") + } +} + +// Hash returns the multihash contained by a Cid. +func (c Cid) Hash() mh.Multihash { + bytes := c.Bytes() + + if c.Version() == 0 { + return mh.Multihash(bytes) + } + + // skip version length + _, n1 := binary.Uvarint(bytes) + // skip codec length + _, n2 := binary.Uvarint(bytes[n1:]) + + return mh.Multihash(bytes[n1+n2:]) +} + +// Bytes returns the byte representation of a Cid. +// The output of bytes can be parsed back into a Cid +// with Cast(). +func (c Cid) Bytes() []byte { + return []byte(c.str) +} + +// MarshalBinary is equivalent to Bytes(). It implements the +// encoding.BinaryMarshaler interface. +func (c Cid) MarshalBinary() ([]byte, error) { + return c.Bytes(), nil +} + +// MarshalText is equivalent to String(). It implements the +// encoding.TextMarshaler interface. +func (c Cid) MarshalText() ([]byte, error) { + return []byte(c.String()), nil +} + +// Equals checks that two Cids are the same. +// In order for two Cids to be considered equal, the +// Version, the Codec and the Multihash must match. +func (c Cid) Equals(o Cid) bool { + return c == o +} + +// UnmarshalJSON parses the JSON representation of a Cid. +func (c *Cid) UnmarshalJSON(b []byte) error { + if len(b) < 2 { + return fmt.Errorf("invalid cid json blob") + } + obj := struct { + CidTarget string `json:"/"` + }{} + objptr := &obj + err := json.Unmarshal(b, &objptr) + if err != nil { + return err + } + if objptr == nil { + *c = Cid{} + return nil + } + + if obj.CidTarget == "" { + return fmt.Errorf("cid was incorrectly formatted") + } + + out, err := Decode(obj.CidTarget) + if err != nil { + return err + } + + *c = out + + return nil +} + +// MarshalJSON procudes a JSON representation of a Cid, which looks as follows: +// +// { "/": "" } +// +// Note that this formatting comes from the IPLD specification +// (https://github.com/ipld/specs/tree/master/ipld) +func (c Cid) MarshalJSON() ([]byte, error) { + if !c.Defined() { + return []byte("null"), nil + } + return []byte(fmt.Sprintf("{\"/\":\"%s\"}", c.String())), nil +} + +// KeyString returns the binary representation of the Cid as a string +func (c Cid) KeyString() string { + return c.str +} + +// Loggable returns a Loggable (as defined by +// https://godoc.org/github.com/ipfs/go-log). +func (c Cid) Loggable() map[string]interface{} { + return map[string]interface{}{ + "cid": c, + } +} + +// Prefix builds and returns a Prefix out of a Cid. +func (c Cid) Prefix() Prefix { + dec, _ := mh.Decode(c.Hash()) // assuming we got a valid multiaddr, this will not error + return Prefix{ + MhType: dec.Code, + MhLength: dec.Length, + Version: c.Version(), + Codec: c.Type(), + } +} + +// Prefix represents all the metadata of a Cid, +// that is, the Version, the Codec, the Multihash type +// and the Multihash length. It does not contains +// any actual content information. +// NOTE: The use -1 in MhLength to mean default length is deprecated, +// use the V0Builder or V1Builder structures instead +type Prefix struct { + Version uint64 + Codec uint64 + MhType uint64 + MhLength int +} + +// Sum uses the information in a prefix to perform a multihash.Sum() +// and return a newly constructed Cid with the resulting multihash. +func (p Prefix) Sum(data []byte) (Cid, error) { + length := p.MhLength + if p.MhType == mh.ID { + length = -1 + } + + hash, err := mh.Sum(data, p.MhType, length) + if err != nil { + return Undef, err + } + + switch p.Version { + case 0: + return NewCidV0(hash), nil + case 1: + return NewCidV1(p.Codec, hash), nil + default: + return Undef, fmt.Errorf("invalid cid version") + } +} + +// Bytes returns a byte representation of a Prefix. It looks like: +// +// +func (p Prefix) Bytes() []byte { + buf := make([]byte, 4*binary.MaxVarintLen64) + n := binary.PutUvarint(buf, p.Version) + n += binary.PutUvarint(buf[n:], p.Codec) + n += binary.PutUvarint(buf[n:], uint64(p.MhType)) + n += binary.PutUvarint(buf[n:], uint64(p.MhLength)) + return buf[:n] +} + +// PrefixFromBytes parses a Prefix-byte representation onto a +// Prefix. +func PrefixFromBytes(buf []byte) (Prefix, error) { + r := bytes.NewReader(buf) + vers, err := binary.ReadUvarint(r) + if err != nil { + return Prefix{}, err + } + + codec, err := binary.ReadUvarint(r) + if err != nil { + return Prefix{}, err + } + + mhtype, err := binary.ReadUvarint(r) + if err != nil { + return Prefix{}, err + } + + mhlen, err := binary.ReadUvarint(r) + if err != nil { + return Prefix{}, err + } + + return Prefix{ + Version: vers, + Codec: codec, + MhType: mhtype, + MhLength: int(mhlen), + }, nil +} diff --git a/vendor/github.com/ipfs/go-cid/cid_fuzz.go b/vendor/github.com/ipfs/go-cid/cid_fuzz.go new file mode 100644 index 00000000..99842b53 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/cid_fuzz.go @@ -0,0 +1,37 @@ +// +build gofuzz + +package cid + +func Fuzz(data []byte) int { + cid, err := Cast(data) + + if err != nil { + return 0 + } + + _ = cid.Bytes() + _ = cid.String() + p := cid.Prefix() + _ = p.Bytes() + + if !cid.Equals(cid) { + panic("inequality") + } + + // json loop + json, err := cid.MarshalJSON() + if err != nil { + panic(err.Error()) + } + cid2 := Cid{} + err = cid2.UnmarshalJSON(json) + if err != nil { + panic(err.Error()) + } + + if !cid.Equals(cid2) { + panic("json loop not equal") + } + + return 1 +} diff --git a/vendor/github.com/ipfs/go-cid/codecov.yml b/vendor/github.com/ipfs/go-cid/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-cid/deprecated.go b/vendor/github.com/ipfs/go-cid/deprecated.go new file mode 100644 index 00000000..cd889f98 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/deprecated.go @@ -0,0 +1,28 @@ +package cid + +import ( + mh "github.com/multiformats/go-multihash" +) + +// NewPrefixV0 returns a CIDv0 prefix with the specified multihash type. +// DEPRECATED: Use V0Builder +func NewPrefixV0(mhType uint64) Prefix { + return Prefix{ + MhType: mhType, + MhLength: mh.DefaultLengths[mhType], + Version: 0, + Codec: DagProtobuf, + } +} + +// NewPrefixV1 returns a CIDv1 prefix with the specified codec and multihash +// type. +// DEPRECATED: Use V1Builder +func NewPrefixV1(codecType uint64, mhType uint64) Prefix { + return Prefix{ + MhType: mhType, + MhLength: mh.DefaultLengths[mhType], + Version: 1, + Codec: codecType, + } +} diff --git a/vendor/github.com/ipfs/go-cid/go.mod b/vendor/github.com/ipfs/go-cid/go.mod new file mode 100644 index 00000000..8e1b5f47 --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-cid + +require ( + github.com/multiformats/go-multibase v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-cid/go.sum b/vendor/github.com/ipfs/go-cid/go.sum new file mode 100644 index 00000000..d6043b8b --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/go.sum @@ -0,0 +1,20 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-cid/package.json b/vendor/github.com/ipfs/go-cid/package.json new file mode 100644 index 00000000..c98a77ee --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/ipfs/go-cid" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-cid" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "whyrusleeping", + "hash": "QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd", + "name": "go-multibase", + "version": "0.3.0" + } + ], + "gxVersion": "0.8.0", + "language": "go", + "license": "MIT", + "name": "go-cid", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.9.3" +} + diff --git a/vendor/github.com/ipfs/go-cid/set.go b/vendor/github.com/ipfs/go-cid/set.go new file mode 100644 index 00000000..eb3b3f0d --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/set.go @@ -0,0 +1,65 @@ +package cid + +// Set is a implementation of a set of Cids, that is, a structure +// to which holds a single copy of every Cids that is added to it. +type Set struct { + set map[Cid]struct{} +} + +// NewSet initializes and returns a new Set. +func NewSet() *Set { + return &Set{set: make(map[Cid]struct{})} +} + +// Add puts a Cid in the Set. +func (s *Set) Add(c Cid) { + s.set[c] = struct{}{} +} + +// Has returns if the Set contains a given Cid. +func (s *Set) Has(c Cid) bool { + _, ok := s.set[c] + return ok +} + +// Remove deletes a Cid from the Set. +func (s *Set) Remove(c Cid) { + delete(s.set, c) +} + +// Len returns how many elements the Set has. +func (s *Set) Len() int { + return len(s.set) +} + +// Keys returns the Cids in the set. +func (s *Set) Keys() []Cid { + out := make([]Cid, 0, len(s.set)) + for k := range s.set { + out = append(out, k) + } + return out +} + +// Visit adds a Cid to the set only if it is +// not in it already. +func (s *Set) Visit(c Cid) bool { + if !s.Has(c) { + s.Add(c) + return true + } + + return false +} + +// ForEach allows to run a custom function on each +// Cid in the set. +func (s *Set) ForEach(f func(c Cid) error) error { + for c := range s.set { + err := f(c) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-cid/varint.go b/vendor/github.com/ipfs/go-cid/varint.go new file mode 100644 index 00000000..391c1f4d --- /dev/null +++ b/vendor/github.com/ipfs/go-cid/varint.go @@ -0,0 +1,34 @@ +package cid + +// Version of varint function that work with a string rather than +// []byte to avoid unnecessary allocation + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license as given at https://golang.org/LICENSE + +// uvarint decodes a uint64 from buf and returns that value and the +// number of characters read (> 0). If an error occurred, the value is 0 +// and the number of bytes n is <= 0 meaning: +// +// n == 0: buf too small +// n < 0: value larger than 64 bits (overflow) +// and -n is the number of bytes read +// +func uvarint(buf string) (uint64, int) { + var x uint64 + var s uint + // we have a binary string so we can't use a range loope + for i := 0; i < len(buf); i++ { + b := buf[i] + if b < 0x80 { + if i > 9 || i == 9 && b > 1 { + return 0, -(i + 1) // overflow + } + return x | uint64(b)< go-cidutil implements various utilities and helper functions for working with CIDs + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-cidutil/codecov.yml b/vendor/github.com/ipfs/go-cidutil/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-cidutil/format.go b/vendor/github.com/ipfs/go-cidutil/format.go new file mode 100644 index 00000000..21e157df --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/format.go @@ -0,0 +1,197 @@ +package cidutil + +import ( + "bytes" + "fmt" + + c "github.com/ipfs/go-cid" + mb "github.com/multiformats/go-multibase" + mh "github.com/multiformats/go-multihash" +) + +// FormatRef is a string documenting the format string for the Format function +const FormatRef = ` + %% literal % + %b multibase name + %B multibase code + %v version string + %V version number + %c codec name + %C codec code + %h multihash name + %H multihash code + %L hash digest length + %m multihash encoded in base %b (with multibase prefix) + %M multihash encoded in base %b without multibase prefix + %d hash digest encoded in base %b (with multibase prefix) + %D hash digest encoded in base %b without multibase prefix + %s cid string encoded in base %b (1) + %S cid string encoded in base %b without multibase prefix + %P cid prefix: %v-%c-%h-%L + +(1) For CID version 0 the multibase must be base58btc and no prefix is +used. For Cid version 1 the multibase prefix is included. +` + +// Format formats a cid according to the format specificer as +// documented in the FormatRef constant +func Format(fmtStr string, base mb.Encoding, cid c.Cid) (string, error) { + p := cid.Prefix() + var out bytes.Buffer + var err error + encoder, err := mb.NewEncoder(base) + if err != nil { + return "", err + } + for i := 0; i < len(fmtStr); i++ { + if fmtStr[i] != '%' { + out.WriteByte(fmtStr[i]) + continue + } + i++ + if i >= len(fmtStr) { + return "", FormatStringError{"premature end of format string", ""} + } + switch fmtStr[i] { + case '%': + out.WriteByte('%') + case 'b': // base name + out.WriteString(baseToString(base)) + case 'B': // base code + out.WriteByte(byte(base)) + case 'v': // version string + fmt.Fprintf(&out, "cidv%d", p.Version) + case 'V': // version num + fmt.Fprintf(&out, "%d", p.Version) + case 'c': // codec name + out.WriteString(codecToString(p.Codec)) + case 'C': // codec code + fmt.Fprintf(&out, "%d", p.Codec) + case 'h': // hash fun name + out.WriteString(hashToString(p.MhType)) + case 'H': // hash fun code + fmt.Fprintf(&out, "%d", p.MhType) + case 'L': // hash length + fmt.Fprintf(&out, "%d", p.MhLength) + case 'm', 'M': // multihash encoded in base %b + out.WriteString(encode(encoder, cid.Hash(), fmtStr[i] == 'M')) + case 'd', 'D': // hash digest encoded in base %b + dec, err := mh.Decode(cid.Hash()) + if err != nil { + return "", err + } + out.WriteString(encode(encoder, dec.Digest, fmtStr[i] == 'D')) + case 's': // cid string encoded in base %b + str, err := cid.StringOfBase(base) + if err != nil { + return "", err + } + out.WriteString(str) + case 'S': // cid string without base prefix + out.WriteString(encode(encoder, cid.Bytes(), true)) + case 'P': // prefix + fmt.Fprintf(&out, "cidv%d-%s-%s-%d", + p.Version, + codecToString(p.Codec), + hashToString(p.MhType), + p.MhLength, + ) + default: + return "", FormatStringError{"unrecognized specifier in format string", fmtStr[i-1 : i+1]} + } + + } + return out.String(), err +} + +// FormatStringError is the error return from Format when the format +// string is ill formed +type FormatStringError struct { + Message string + Specifier string +} + +func (e FormatStringError) Error() string { + if e.Specifier == "" { + return e.Message + } else { + return fmt.Sprintf("%s: %s", e.Message, e.Specifier) + } +} + +func baseToString(base mb.Encoding) string { + baseStr, ok := mb.EncodingToStr[base] + if !ok { + return fmt.Sprintf("base?%c", base) + } + return baseStr +} + +func codecToString(num uint64) string { + name, ok := c.CodecToStr[num] + if !ok { + return fmt.Sprintf("codec?%d", num) + } + return name +} + +func hashToString(num uint64) string { + name, ok := mh.Codes[num] + if !ok { + return fmt.Sprintf("hash?%d", num) + } + return name +} + +func encode(base mb.Encoder, data []byte, strip bool) string { + str := base.Encode(data) + if strip { + return str[1:] + } + return str +} + +// ScanForCid scans bytes for anything resembling a CID. If one is +// found `i` will point to the begging of the cid and `j` to to the +// end and the cid will be returned, otherwise `i` and `j` will point +// the end of the buffer and the cid will be `Undef`. +func ScanForCid(buf []byte) (i, j int, cid c.Cid, cidStr string) { + i = 0 + for { + i = j + for i < len(buf) && !asciiIsAlpha(buf[i]) { + i++ + } + j = i + if i == len(buf) { + return + } + for j < len(buf) && asciiIsAlpha(buf[j]) { + j++ + } + if j-i <= 1 || j-i > 128 || !supported[buf[i]] { + continue + } + var err error + cidStr = string(buf[i:j]) + cid, err = c.Decode(cidStr) + if err == nil { + return + } + } +} + +var supported = make([]bool, 256) + +func init() { + // for now base64 encoding are not supported as they contain non + // alhphanumeric characters + supportedPrefixes := []byte("QfFbBcCvVtThzZ") + for _, b := range supportedPrefixes { + supported[b] = true + } +} + +func asciiIsAlpha(b byte) bool { + return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') || ('0' <= b && b <= '9') +} diff --git a/vendor/github.com/ipfs/go-cidutil/go.mod b/vendor/github.com/ipfs/go-cidutil/go.mod new file mode 100644 index 00000000..73ce4c91 --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-cidutil + +require ( + github.com/ipfs/go-cid v0.0.2 + github.com/multiformats/go-multibase v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-cidutil/go.sum b/vendor/github.com/ipfs/go-cidutil/go.sum new file mode 100644 index 00000000..7319f155 --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/go.sum @@ -0,0 +1,22 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-cidutil/inline.go b/vendor/github.com/ipfs/go-cidutil/inline.go new file mode 100644 index 00000000..d140e114 --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/inline.go @@ -0,0 +1,26 @@ +package cidutil + +import ( + cid "github.com/ipfs/go-cid" + mhash "github.com/multiformats/go-multihash" +) + +// InlineBuilder is a cid.Builder that will use the id multihash when the +// size of the content is no more than limit +type InlineBuilder struct { + cid.Builder // Parent Builder + Limit int // Limit (inclusive) +} + +// WithCodec implements the cid.Builder interface +func (p InlineBuilder) WithCodec(c uint64) cid.Builder { + return InlineBuilder{p.Builder.WithCodec(c), p.Limit} +} + +// Sum implements the cid.Builder interface +func (p InlineBuilder) Sum(data []byte) (cid.Cid, error) { + if len(data) > p.Limit { + return p.Builder.Sum(data) + } + return cid.V1Builder{Codec: p.GetCodec(), MhType: mhash.ID}.Sum(data) +} diff --git a/vendor/github.com/ipfs/go-cidutil/package.json b/vendor/github.com/ipfs/go-cidutil/package.json new file mode 100644 index 00000000..a286ee0e --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/package.json @@ -0,0 +1,34 @@ +{ + "author": "kevina", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/ipfs/go-cidutil" + }, + "gxDependencies": [ + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "whyrusleeping", + "hash": "QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd", + "name": "go-multibase", + "version": "0.3.0" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-cidutil", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.2.1" +} + diff --git a/vendor/github.com/ipfs/go-cidutil/set.go b/vendor/github.com/ipfs/go-cidutil/set.go new file mode 100644 index 00000000..ea812a13 --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/set.go @@ -0,0 +1,42 @@ +package cidutil + +import ( + "context" + + c "github.com/ipfs/go-cid" +) + +type Set = c.Set + +func NewSet() *Set { return c.NewSet() } + +// StreamingSet is an extension of Set which allows to implement back-pressure +// for the Visit function +type StreamingSet struct { + Set *Set + New chan c.Cid +} + +// NewStreamingSet initializes and returns new Set. +func NewStreamingSet() *StreamingSet { + return &StreamingSet{ + Set: c.NewSet(), + New: make(chan c.Cid), + } +} + +// Visitor creates new visitor which adds a Cids to the set and emits them to +// the set.New channel +func (s *StreamingSet) Visitor(ctx context.Context) func(c c.Cid) bool { + return func(c c.Cid) bool { + if s.Set.Visit(c) { + select { + case s.New <- c: + case <-ctx.Done(): + } + return true + } + + return false + } +} diff --git a/vendor/github.com/ipfs/go-cidutil/slice.go b/vendor/github.com/ipfs/go-cidutil/slice.go new file mode 100644 index 00000000..fa39b64d --- /dev/null +++ b/vendor/github.com/ipfs/go-cidutil/slice.go @@ -0,0 +1,30 @@ +package cidutil + +import ( + "github.com/ipfs/go-cid" + "sort" +) + +// Slice is a convenience type for sorting CIDs +type Slice []cid.Cid + +func (s Slice) Len() int { + return len(s) +} + +func (s Slice) Less(i, j int) bool { + return s[i].KeyString() < s[j].KeyString() +} + +func (s Slice) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s Slice) Sort() { + sort.Sort(s) +} + +// Sort sorts a slice of CIDs +func Sort(s []cid.Cid) { + Slice(s).Sort() +} diff --git a/vendor/github.com/ipfs/go-datastore/.gitignore b/vendor/github.com/ipfs/go-datastore/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/ipfs/go-datastore/.travis.yml b/vendor/github.com/ipfs/go-datastore/.travis.yml new file mode 100644 index 00000000..30dc421c --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race -cpu=5" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-datastore/LICENSE b/vendor/github.com/ipfs/go-datastore/LICENSE new file mode 100644 index 00000000..f2049023 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-datastore/Makefile b/vendor/github.com/ipfs/go-datastore/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/ipfs/go-datastore/README.md b/vendor/github.com/ipfs/go-datastore/README.md new file mode 100644 index 00000000..0f7a3c19 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/README.md @@ -0,0 +1,34 @@ +# go-datastore + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-datastore?status.svg)](https://godoc.org/github.com/ipfs/go-datastore) + +> key-value datastore interfaces + +datastore is a generic layer of abstraction for data store and database access. It is a simple API with the aim to enable application development in a datastore-agnostic way, allowing datastores to be swapped seamlessly without changing application code. Thus, one can leverage different datastores with different strengths without committing the application to one datastore throughout its lifetime. + +In addition, grouped datastores significantly simplify interesting data access patterns (such as caching and sharding). + +Based on [datastore.py](https://github.com/datastore/datastore). + +## Documentation + +https://godoc.org/github.com/ipfs/go-datastore + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-datastore/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + diff --git a/vendor/github.com/ipfs/go-datastore/autobatch/README.md b/vendor/github.com/ipfs/go-datastore/autobatch/README.md new file mode 100644 index 00000000..9b805aba --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/autobatch/README.md @@ -0,0 +1,19 @@ +# autobatch + +Autobatch is an implementation of +[go-datastore](https://github.com/ipfs/go-datastore) that automatically batches +together writes by holding puts in memory until a certain threshold is met. +This can improve disk performance at the cost of memory in certain situations. + +## Usage + +Simply wrap your existing datastore in an autobatching layer like so: + +```go +bds := NewAutoBatching(basedstore, 128) +``` + +And make all future calls to the autobatching object. + +## License +MIT diff --git a/vendor/github.com/ipfs/go-datastore/autobatch/autobatch.go b/vendor/github.com/ipfs/go-datastore/autobatch/autobatch.go new file mode 100644 index 00000000..aeca9a45 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/autobatch/autobatch.go @@ -0,0 +1,143 @@ +// Package autobatch provides a go-datastore implementation that +// automatically batches together writes by holding puts in memory until +// a certain threshold is met. +package autobatch + +import ( + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" +) + +// Datastore implements a go-datatsore. +type Datastore struct { + child ds.Batching + + // TODO: discuss making ds.Batch implement the full ds.Datastore interface + buffer map[ds.Key]op + maxBufferEntries int +} + +type op struct { + delete bool + value []byte +} + +// NewAutoBatching returns a new datastore that automatically +// batches writes using the given Batching datastore. The size +// of the memory pool is given by size. +func NewAutoBatching(d ds.Batching, size int) *Datastore { + return &Datastore{ + child: d, + buffer: make(map[ds.Key]op, size), + maxBufferEntries: size, + } +} + +// Delete deletes a key/value +func (d *Datastore) Delete(k ds.Key) error { + d.buffer[k] = op{delete: true} + if len(d.buffer) > d.maxBufferEntries { + return d.Flush() + } + return nil +} + +// Get retrieves a value given a key. +func (d *Datastore) Get(k ds.Key) ([]byte, error) { + o, ok := d.buffer[k] + if ok { + if o.delete { + return nil, ds.ErrNotFound + } + return o.value, nil + } + + return d.child.Get(k) +} + +// Put stores a key/value. +func (d *Datastore) Put(k ds.Key, val []byte) error { + d.buffer[k] = op{value: val} + if len(d.buffer) > d.maxBufferEntries { + return d.Flush() + } + return nil +} + +// Flush flushes the current batch to the underlying datastore. +func (d *Datastore) Flush() error { + b, err := d.child.Batch() + if err != nil { + return err + } + + for k, o := range d.buffer { + var err error + if o.delete { + err = b.Delete(k) + if err == ds.ErrNotFound { + // Ignore these, let delete be idempotent. + err = nil + } + } else { + err = b.Put(k, o.value) + } + if err != nil { + return err + } + } + // clear out buffer + d.buffer = make(map[ds.Key]op, d.maxBufferEntries) + + return b.Commit() +} + +// Has checks if a key is stored. +func (d *Datastore) Has(k ds.Key) (bool, error) { + o, ok := d.buffer[k] + if ok { + return !o.delete, nil + } + + return d.child.Has(k) +} + +// GetSize implements Datastore.GetSize +func (d *Datastore) GetSize(k ds.Key) (int, error) { + o, ok := d.buffer[k] + if ok { + if o.delete { + return -1, ds.ErrNotFound + } + return len(o.value), nil + } + + return d.child.GetSize(k) +} + +// Query performs a query +func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) { + err := d.Flush() + if err != nil { + return nil, err + } + + return d.child.Query(q) +} + +// DiskUsage implements the PersistentDatastore interface. +func (d *Datastore) DiskUsage() (uint64, error) { + return ds.DiskUsage(d.child) +} + +func (d *Datastore) Close() error { + err1 := d.Flush() + err2 := d.child.Close() + if err1 != nil { + return err1 + } + if err2 != nil { + return err2 + } + return nil +} diff --git a/vendor/github.com/ipfs/go-datastore/basic_ds.go b/vendor/github.com/ipfs/go-datastore/basic_ds.go new file mode 100644 index 00000000..19b74e26 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/basic_ds.go @@ -0,0 +1,274 @@ +package datastore + +import ( + "log" + + dsq "github.com/ipfs/go-datastore/query" +) + +// Here are some basic datastore implementations. + +// MapDatastore uses a standard Go map for internal storage. +type MapDatastore struct { + values map[Key][]byte +} + +// NewMapDatastore constructs a MapDatastore. It is _not_ thread-safe by +// default, wrap using sync.MutexWrap if you need thread safety (the answer here +// is usually yes). +func NewMapDatastore() (d *MapDatastore) { + return &MapDatastore{ + values: make(map[Key][]byte), + } +} + +// Put implements Datastore.Put +func (d *MapDatastore) Put(key Key, value []byte) (err error) { + d.values[key] = value + return nil +} + +// Get implements Datastore.Get +func (d *MapDatastore) Get(key Key) (value []byte, err error) { + val, found := d.values[key] + if !found { + return nil, ErrNotFound + } + return val, nil +} + +// Has implements Datastore.Has +func (d *MapDatastore) Has(key Key) (exists bool, err error) { + _, found := d.values[key] + return found, nil +} + +// GetSize implements Datastore.GetSize +func (d *MapDatastore) GetSize(key Key) (size int, err error) { + if v, found := d.values[key]; found { + return len(v), nil + } + return -1, ErrNotFound +} + +// Delete implements Datastore.Delete +func (d *MapDatastore) Delete(key Key) (err error) { + if _, found := d.values[key]; !found { + return ErrNotFound + } + delete(d.values, key) + return nil +} + +// Query implements Datastore.Query +func (d *MapDatastore) Query(q dsq.Query) (dsq.Results, error) { + re := make([]dsq.Entry, 0, len(d.values)) + for k, v := range d.values { + e := dsq.Entry{Key: k.String()} + if !q.KeysOnly { + e.Value = v + } + re = append(re, e) + } + r := dsq.ResultsWithEntries(q, re) + r = dsq.NaiveQueryApply(q, r) + return r, nil +} + +func (d *MapDatastore) Batch() (Batch, error) { + return NewBasicBatch(d), nil +} + +func (d *MapDatastore) Close() error { + return nil +} + +// NullDatastore stores nothing, but conforms to the API. +// Useful to test with. +type NullDatastore struct { +} + +// NewNullDatastore constructs a null datastoe +func NewNullDatastore() *NullDatastore { + return &NullDatastore{} +} + +// Put implements Datastore.Put +func (d *NullDatastore) Put(key Key, value []byte) (err error) { + return nil +} + +// Get implements Datastore.Get +func (d *NullDatastore) Get(key Key) (value []byte, err error) { + return nil, ErrNotFound +} + +// Has implements Datastore.Has +func (d *NullDatastore) Has(key Key) (exists bool, err error) { + return false, nil +} + +// Has implements Datastore.GetSize +func (d *NullDatastore) GetSize(key Key) (size int, err error) { + return -1, ErrNotFound +} + +// Delete implements Datastore.Delete +func (d *NullDatastore) Delete(key Key) (err error) { + return nil +} + +// Query implements Datastore.Query +func (d *NullDatastore) Query(q dsq.Query) (dsq.Results, error) { + return dsq.ResultsWithEntries(q, nil), nil +} + +func (d *NullDatastore) Batch() (Batch, error) { + return NewBasicBatch(d), nil +} + +func (d *NullDatastore) Close() error { + return nil +} + +// LogDatastore logs all accesses through the datastore. +type LogDatastore struct { + Name string + child Datastore +} + +// Shim is a datastore which has a child. +type Shim interface { + Datastore + + Children() []Datastore +} + +// NewLogDatastore constructs a log datastore. +func NewLogDatastore(ds Datastore, name string) *LogDatastore { + if len(name) < 1 { + name = "LogDatastore" + } + return &LogDatastore{Name: name, child: ds} +} + +// Children implements Shim +func (d *LogDatastore) Children() []Datastore { + return []Datastore{d.child} +} + +// Put implements Datastore.Put +func (d *LogDatastore) Put(key Key, value []byte) (err error) { + log.Printf("%s: Put %s\n", d.Name, key) + // log.Printf("%s: Put %s ```%s```", d.Name, key, value) + return d.child.Put(key, value) +} + +// Get implements Datastore.Get +func (d *LogDatastore) Get(key Key) (value []byte, err error) { + log.Printf("%s: Get %s\n", d.Name, key) + return d.child.Get(key) +} + +// Has implements Datastore.Has +func (d *LogDatastore) Has(key Key) (exists bool, err error) { + log.Printf("%s: Has %s\n", d.Name, key) + return d.child.Has(key) +} + +// GetSize implements Datastore.GetSize +func (d *LogDatastore) GetSize(key Key) (size int, err error) { + log.Printf("%s: GetSize %s\n", d.Name, key) + return d.child.GetSize(key) +} + +// Delete implements Datastore.Delete +func (d *LogDatastore) Delete(key Key) (err error) { + log.Printf("%s: Delete %s\n", d.Name, key) + return d.child.Delete(key) +} + +// DiskUsage implements the PersistentDatastore interface. +func (d *LogDatastore) DiskUsage() (uint64, error) { + log.Printf("%s: DiskUsage\n", d.Name) + return DiskUsage(d.child) +} + +// Query implements Datastore.Query +func (d *LogDatastore) Query(q dsq.Query) (dsq.Results, error) { + log.Printf("%s: Query\n", d.Name) + log.Printf("%s: q.Prefix: %s\n", d.Name, q.Prefix) + log.Printf("%s: q.KeysOnly: %v\n", d.Name, q.KeysOnly) + log.Printf("%s: q.Filters: %d\n", d.Name, len(q.Filters)) + log.Printf("%s: q.Orders: %d\n", d.Name, len(q.Orders)) + log.Printf("%s: q.Offset: %d\n", d.Name, q.Offset) + + return d.child.Query(q) +} + +// LogBatch logs all accesses through the batch. +type LogBatch struct { + Name string + child Batch +} + +func (d *LogDatastore) Batch() (Batch, error) { + log.Printf("%s: Batch\n", d.Name) + if bds, ok := d.child.(Batching); ok { + b, err := bds.Batch() + + if err != nil { + return nil, err + } + return &LogBatch{ + Name: d.Name, + child: b, + }, nil + } + return nil, ErrBatchUnsupported +} + +// Put implements Batch.Put +func (d *LogBatch) Put(key Key, value []byte) (err error) { + log.Printf("%s: BatchPut %s\n", d.Name, key) + // log.Printf("%s: Put %s ```%s```", d.Name, key, value) + return d.child.Put(key, value) +} + +// Delete implements Batch.Delete +func (d *LogBatch) Delete(key Key) (err error) { + log.Printf("%s: BatchDelete %s\n", d.Name, key) + return d.child.Delete(key) +} + +// Commit implements Batch.Commit +func (d *LogBatch) Commit() (err error) { + log.Printf("%s: BatchCommit\n", d.Name) + return d.child.Commit() +} + +func (d *LogDatastore) Close() error { + log.Printf("%s: Close\n", d.Name) + return d.child.Close() +} + +func (d *LogDatastore) Check() error { + if c, ok := d.child.(CheckedDatastore); ok { + return c.Check() + } + return nil +} + +func (d *LogDatastore) Scrub() error { + if c, ok := d.child.(ScrubbedDatastore); ok { + return c.Scrub() + } + return nil +} + +func (d *LogDatastore) CollectGarbage() error { + if c, ok := d.child.(GCDatastore); ok { + return c.CollectGarbage() + } + return nil +} diff --git a/vendor/github.com/ipfs/go-datastore/batch.go b/vendor/github.com/ipfs/go-datastore/batch.go new file mode 100644 index 00000000..57880dd2 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/batch.go @@ -0,0 +1,52 @@ +package datastore + +type op struct { + delete bool + value []byte +} + +// basicBatch implements the transaction interface for datastores who do +// not have any sort of underlying transactional support +type basicBatch struct { + ops map[Key]op + + target Datastore +} + +func NewBasicBatch(ds Datastore) Batch { + return &basicBatch{ + ops: make(map[Key]op), + target: ds, + } +} + +func (bt *basicBatch) Put(key Key, val []byte) error { + bt.ops[key] = op{value: val} + return nil +} + +func (bt *basicBatch) Delete(key Key) error { + bt.ops[key] = op{delete: true} + return nil +} + +func (bt *basicBatch) Commit() error { + var err error + for k, op := range bt.ops { + if op.delete { + err = bt.target.Delete(k) + // We could try to do something smarter but I really + // don't care. Delete should be idempotent anyways. + if err == ErrNotFound { + err = nil + } + } else { + err = bt.target.Put(k, op.value) + } + if err != nil { + break + } + } + + return err +} diff --git a/vendor/github.com/ipfs/go-datastore/datastore.go b/vendor/github.com/ipfs/go-datastore/datastore.go new file mode 100644 index 00000000..eec1932c --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/datastore.go @@ -0,0 +1,239 @@ +package datastore + +import ( + "errors" + "io" + "time" + + query "github.com/ipfs/go-datastore/query" +) + +/* +Datastore represents storage for any key-value pair. + +Datastores are general enough to be backed by all kinds of different storage: +in-memory caches, databases, a remote datastore, flat files on disk, etc. + +The general idea is to wrap a more complicated storage facility in a simple, +uniform interface, keeping the freedom of using the right tools for the job. +In particular, a Datastore can aggregate other datastores in interesting ways, +like sharded (to distribute load) or tiered access (caches before databases). + +While Datastores should be written general enough to accept all sorts of +values, some implementations will undoubtedly have to be specific (e.g. SQL +databases where fields should be decomposed into columns), particularly to +support queries efficiently. Moreover, certain datastores may enforce certain +types of values (e.g. requiring an io.Reader, a specific struct, etc) or +serialization formats (JSON, Protobufs, etc). + +IMPORTANT: No Datastore should ever Panic! This is a cross-module interface, +and thus it should behave predictably and handle exceptional conditions with +proper error reporting. Thus, all Datastore calls may return errors, which +should be checked by callers. +*/ +type Datastore interface { + Read + Write + io.Closer +} + +// Write is the write-side of the Datastore interface. +type Write interface { + // Put stores the object `value` named by `key`. + // + // The generalized Datastore interface does not impose a value type, + // allowing various datastore middleware implementations (which do not + // handle the values directly) to be composed together. + // + // Ultimately, the lowest-level datastore will need to do some value checking + // or risk getting incorrect values. It may also be useful to expose a more + // type-safe interface to your application, and do the checking up-front. + Put(key Key, value []byte) error + + // Delete removes the value for given `key`. + Delete(key Key) error +} + +// Read is the read-side of the Datastore interface. +type Read interface { + // Get retrieves the object `value` named by `key`. + // Get will return ErrNotFound if the key is not mapped to a value. + Get(key Key) (value []byte, err error) + + // Has returns whether the `key` is mapped to a `value`. + // In some contexts, it may be much cheaper only to check for existence of + // a value, rather than retrieving the value itself. (e.g. HTTP HEAD). + // The default implementation is found in `GetBackedHas`. + Has(key Key) (exists bool, err error) + + // GetSize returns the size of the `value` named by `key`. + // In some contexts, it may be much cheaper to only get the size of the + // value rather than retrieving the value itself. + GetSize(key Key) (size int, err error) + + // Query searches the datastore and returns a query result. This function + // may return before the query actually runs. To wait for the query: + // + // result, _ := ds.Query(q) + // + // // use the channel interface; result may come in at different times + // for entry := range result.Next() { ... } + // + // // or wait for the query to be completely done + // entries, _ := result.Rest() + // for entry := range entries { ... } + // + Query(q query.Query) (query.Results, error) +} + +// Batching datastores support deferred, grouped updates to the database. +// `Batch`es do NOT have transactional semantics: updates to the underlying +// datastore are not guaranteed to occur in the same iota of time. Similarly, +// batched updates will not be flushed to the underlying datastore until +// `Commit` has been called. `Txn`s from a `TxnDatastore` have all the +// capabilities of a `Batch`, but the reverse is NOT true. +type Batching interface { + Datastore + + Batch() (Batch, error) +} + +// ErrBatchUnsupported is returned if the by Batch if the Datastore doesn't +// actually support batching. +var ErrBatchUnsupported = errors.New("this datastore does not support batching") + +// CheckedDatastore is an interface that should be implemented by datastores +// which may need checking on-disk data integrity. +type CheckedDatastore interface { + Datastore + + Check() error +} + +// CheckedDatastore is an interface that should be implemented by datastores +// which want to provide a mechanism to check data integrity and/or +// error correction. +type ScrubbedDatastore interface { + Datastore + + Scrub() error +} + +// GCDatastore is an interface that should be implemented by datastores which +// don't free disk space by just removing data from them. +type GCDatastore interface { + Datastore + + CollectGarbage() error +} + +// PersistentDatastore is an interface that should be implemented by datastores +// which can report disk usage. +type PersistentDatastore interface { + Datastore + + // DiskUsage returns the space used by a datastore, in bytes. + DiskUsage() (uint64, error) +} + +// DiskUsage checks if a Datastore is a +// PersistentDatastore and returns its DiskUsage(), +// otherwise returns 0. +func DiskUsage(d Datastore) (uint64, error) { + persDs, ok := d.(PersistentDatastore) + if !ok { + return 0, nil + } + return persDs.DiskUsage() +} + +// TTLDatastore is an interface that should be implemented by datastores that +// support expiring entries. +type TTLDatastore interface { + Datastore + TTL +} + +// TTL encapulates the methods that deal with entries with time-to-live. +type TTL interface { + PutWithTTL(key Key, value []byte, ttl time.Duration) error + SetTTL(key Key, ttl time.Duration) error + GetExpiration(key Key) (time.Time, error) +} + +// Txn extends the Datastore type. Txns allow users to batch queries and +// mutations to the Datastore into atomic groups, or transactions. Actions +// performed on a transaction will not take hold until a successful call to +// Commit has been made. Likewise, transactions can be aborted by calling +// Discard before a successful Commit has been made. +type Txn interface { + Read + Write + + // Commit finalizes a transaction, attempting to commit it to the Datastore. + // May return an error if the transaction has gone stale. The presence of an + // error is an indication that the data was not committed to the Datastore. + Commit() error + // Discard throws away changes recorded in a transaction without committing + // them to the underlying Datastore. Any calls made to Discard after Commit + // has been successfully called will have no effect on the transaction and + // state of the Datastore, making it safe to defer. + Discard() +} + +// TxnDatastore is an interface that should be implemented by datastores that +// support transactions. +type TxnDatastore interface { + Datastore + + NewTransaction(readOnly bool) (Txn, error) +} + +// Errors + +// ErrNotFound is returned by Get, Has, and Delete when a datastore does not +// map the given key to a value. +var ErrNotFound = errors.New("datastore: key not found") + +// ErrInvalidType is returned by Put when a given value is incopatible with +// the type the datastore supports. This means a conversion (or serialization) +// is needed beforehand. +var ErrInvalidType = errors.New("datastore: invalid type error") + +// GetBackedHas provides a default Datastore.Has implementation. +// It exists so Datastore.Has implementations can use it, like so: +// +// func (*d SomeDatastore) Has(key Key) (exists bool, err error) { +// return GetBackedHas(d, key) +// } +func GetBackedHas(ds Read, key Key) (bool, error) { + _, err := ds.Get(key) + switch err { + case nil: + return true, nil + case ErrNotFound: + return false, nil + default: + return false, err + } +} + +// GetBackedSize provides a default Datastore.GetSize implementation. +// It exists so Datastore.GetSize implementations can use it, like so: +// +// func (*d SomeDatastore) GetSize(key Key) (size int, err error) { +// return GetBackedSize(d, key) +// } +func GetBackedSize(ds Read, key Key) (int, error) { + value, err := ds.Get(key) + if err == nil { + return len(value), nil + } + return -1, err +} + +type Batch interface { + Write + + Commit() error +} diff --git a/vendor/github.com/ipfs/go-datastore/go.mod b/vendor/github.com/ipfs/go-datastore/go.mod new file mode 100644 index 00000000..6e22c954 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/go.mod @@ -0,0 +1,10 @@ +module github.com/ipfs/go-datastore + +require ( + github.com/go-check/check v0.0.0-20180628173108-788fd7840127 + github.com/google/uuid v1.1.1 + github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8 + github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 + github.com/kr/pretty v0.1.0 // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect +) diff --git a/vendor/github.com/ipfs/go-datastore/go.sum b/vendor/github.com/ipfs/go-datastore/go.sum new file mode 100644 index 00000000..d7327672 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/go.sum @@ -0,0 +1,15 @@ +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8 h1:NAviDvJ0WXgD+yiL2Rj35AmnfgI11+pHXbdciD917U0= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-datastore/key.go b/vendor/github.com/ipfs/go-datastore/key.go new file mode 100644 index 00000000..161fedff --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/key.go @@ -0,0 +1,302 @@ +package datastore + +import ( + "encoding/json" + "path" + "strings" + + dsq "github.com/ipfs/go-datastore/query" + + "github.com/google/uuid" +) + +/* +A Key represents the unique identifier of an object. +Our Key scheme is inspired by file systems and Google App Engine key model. + +Keys are meant to be unique across a system. Keys are hierarchical, +incorporating more and more specific namespaces. Thus keys can be deemed +'children' or 'ancestors' of other keys:: + + Key("/Comedy") + Key("/Comedy/MontyPython") + +Also, every namespace can be parametrized to embed relevant object +information. For example, the Key `name` (most specific namespace) could +include the object type:: + + Key("/Comedy/MontyPython/Actor:JohnCleese") + Key("/Comedy/MontyPython/Sketch:CheeseShop") + Key("/Comedy/MontyPython/Sketch:CheeseShop/Character:Mousebender") + +*/ +type Key struct { + string +} + +// NewKey constructs a key from string. it will clean the value. +func NewKey(s string) Key { + k := Key{s} + k.Clean() + return k +} + +// RawKey creates a new Key without safety checking the input. Use with care. +func RawKey(s string) Key { + // accept an empty string and fix it to avoid special cases + // elsewhere + if len(s) == 0 { + return Key{"/"} + } + + // perform a quick sanity check that the key is in the correct + // format, if it is not then it is a programmer error and it is + // okay to panic + if len(s) == 0 || s[0] != '/' || (len(s) > 1 && s[len(s)-1] == '/') { + panic("invalid datastore key: " + s) + } + + return Key{s} +} + +// KeyWithNamespaces constructs a key out of a namespace slice. +func KeyWithNamespaces(ns []string) Key { + return NewKey(strings.Join(ns, "/")) +} + +// Clean up a Key, using path.Clean. +func (k *Key) Clean() { + switch { + case len(k.string) == 0: + k.string = "/" + case k.string[0] == '/': + k.string = path.Clean(k.string) + default: + k.string = path.Clean("/" + k.string) + } +} + +// Strings is the string value of Key +func (k Key) String() string { + return k.string +} + +// Bytes returns the string value of Key as a []byte +func (k Key) Bytes() []byte { + return []byte(k.string) +} + +// Equal checks equality of two keys +func (k Key) Equal(k2 Key) bool { + return k.string == k2.string +} + +// Less checks whether this key is sorted lower than another. +func (k Key) Less(k2 Key) bool { + list1 := k.List() + list2 := k2.List() + for i, c1 := range list1 { + if len(list2) < (i + 1) { + return false + } + + c2 := list2[i] + if c1 < c2 { + return true + } else if c1 > c2 { + return false + } + // c1 == c2, continue + } + + // list1 is shorter or exactly the same. + return len(list1) < len(list2) +} + +// List returns the `list` representation of this Key. +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List() +// ["Comedy", "MontyPythong", "Actor:JohnCleese"] +func (k Key) List() []string { + return strings.Split(k.string, "/")[1:] +} + +// Reverse returns the reverse of this Key. +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Reverse() +// NewKey("/Actor:JohnCleese/MontyPython/Comedy") +func (k Key) Reverse() Key { + l := k.List() + r := make([]string, len(l), len(l)) + for i, e := range l { + r[len(l)-i-1] = e + } + return KeyWithNamespaces(r) +} + +// Namespaces returns the `namespaces` making up this Key. +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Namespaces() +// ["Comedy", "MontyPython", "Actor:JohnCleese"] +func (k Key) Namespaces() []string { + return k.List() +} + +// BaseNamespace returns the "base" namespace of this key (path.Base(filename)) +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").BaseNamespace() +// "Actor:JohnCleese" +func (k Key) BaseNamespace() string { + n := k.Namespaces() + return n[len(n)-1] +} + +// Type returns the "type" of this key (value of last namespace). +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Type() +// "Actor" +func (k Key) Type() string { + return NamespaceType(k.BaseNamespace()) +} + +// Name returns the "name" of this key (field of last namespace). +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Name() +// "JohnCleese" +func (k Key) Name() string { + return NamespaceValue(k.BaseNamespace()) +} + +// Instance returns an "instance" of this type key (appends value to namespace). +// NewKey("/Comedy/MontyPython/Actor").Instance("JohnClesse") +// NewKey("/Comedy/MontyPython/Actor:JohnCleese") +func (k Key) Instance(s string) Key { + return NewKey(k.string + ":" + s) +} + +// Path returns the "path" of this key (parent + type). +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Path() +// NewKey("/Comedy/MontyPython/Actor") +func (k Key) Path() Key { + s := k.Parent().string + "/" + NamespaceType(k.BaseNamespace()) + return NewKey(s) +} + +// Parent returns the `parent` Key of this Key. +// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Parent() +// NewKey("/Comedy/MontyPython") +func (k Key) Parent() Key { + n := k.List() + if len(n) == 1 { + return RawKey("/") + } + return NewKey(strings.Join(n[:len(n)-1], "/")) +} + +// Child returns the `child` Key of this Key. +// NewKey("/Comedy/MontyPython").Child(NewKey("Actor:JohnCleese")) +// NewKey("/Comedy/MontyPython/Actor:JohnCleese") +func (k Key) Child(k2 Key) Key { + switch { + case k.string == "/": + return k2 + case k2.string == "/": + return k + default: + return RawKey(k.string + k2.string) + } +} + +// ChildString returns the `child` Key of this Key -- string helper. +// NewKey("/Comedy/MontyPython").ChildString("Actor:JohnCleese") +// NewKey("/Comedy/MontyPython/Actor:JohnCleese") +func (k Key) ChildString(s string) Key { + return NewKey(k.string + "/" + s) +} + +// IsAncestorOf returns whether this key is a prefix of `other` +// NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython") +// true +func (k Key) IsAncestorOf(other Key) bool { + if other.string == k.string { + return false + } + return strings.HasPrefix(other.string, k.string) +} + +// IsDescendantOf returns whether this key contains another as a prefix. +// NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy") +// true +func (k Key) IsDescendantOf(other Key) bool { + if other.string == k.string { + return false + } + return strings.HasPrefix(k.string, other.string) +} + +// IsTopLevel returns whether this key has only one namespace. +func (k Key) IsTopLevel() bool { + return len(k.List()) == 1 +} + +// MarshalJSON implements the json.Marshaler interface, +// keys are represented as JSON strings +func (k Key) MarshalJSON() ([]byte, error) { + return json.Marshal(k.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface, +// keys will parse any value specified as a key to a string +func (k *Key) UnmarshalJSON(data []byte) error { + var key string + if err := json.Unmarshal(data, &key); err != nil { + return err + } + *k = NewKey(key) + return nil +} + +// RandomKey returns a randomly (uuid) generated key. +// RandomKey() +// NewKey("/f98719ea086343f7b71f32ea9d9d521d") +func RandomKey() Key { + return NewKey(strings.Replace(uuid.New().String(), "-", "", -1)) +} + +/* +A Key Namespace is like a path element. +A namespace can optionally include a type (delimited by ':') + + > NamespaceValue("Song:PhilosopherSong") + PhilosopherSong + > NamespaceType("Song:PhilosopherSong") + Song + > NamespaceType("Music:Song:PhilosopherSong") + Music:Song +*/ + +// NamespaceType is the first component of a namespace. `foo` in `foo:bar` +func NamespaceType(namespace string) string { + parts := strings.Split(namespace, ":") + if len(parts) < 2 { + return "" + } + return strings.Join(parts[0:len(parts)-1], ":") +} + +// NamespaceValue returns the last component of a namespace. `baz` in `f:b:baz` +func NamespaceValue(namespace string) string { + parts := strings.Split(namespace, ":") + return parts[len(parts)-1] +} + +// KeySlice attaches the methods of sort.Interface to []Key, +// sorting in increasing order. +type KeySlice []Key + +func (p KeySlice) Len() int { return len(p) } +func (p KeySlice) Less(i, j int) bool { return p[i].Less(p[j]) } +func (p KeySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// EntryKeys +func EntryKeys(e []dsq.Entry) []Key { + ks := make([]Key, len(e)) + for i, e := range e { + ks[i] = NewKey(e.Key) + } + return ks +} diff --git a/vendor/github.com/ipfs/go-datastore/keytransform/doc.go b/vendor/github.com/ipfs/go-datastore/keytransform/doc.go new file mode 100644 index 00000000..b389dcfa --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/keytransform/doc.go @@ -0,0 +1,25 @@ +// Package keytransform introduces a Datastore Shim that transforms keys before +// passing them to its child. It can be used to manipulate what keys look like +// to the user, for example namespacing keys, reversing them, etc. +// +// Use the Wrap function to wrap a datastore with any KeyTransform. +// A KeyTransform is simply an interface with two functions, a conversion and +// its inverse. For example: +// +// import ( +// ktds "github.com/ipfs/go-datastore/keytransform" +// ds "github.com/ipfs/go-datastore" +// ) +// +// func reverseKey(k ds.Key) ds.Key { +// return k.Reverse() +// } +// +// func invertKeys(d ds.Datastore) { +// return ktds.Wrap(d, &ktds.Pair{ +// Convert: reverseKey, +// Invert: reverseKey, // reverse is its own inverse. +// }) +// } +// +package keytransform diff --git a/vendor/github.com/ipfs/go-datastore/keytransform/interface.go b/vendor/github.com/ipfs/go-datastore/keytransform/interface.go new file mode 100644 index 00000000..4f07967a --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/keytransform/interface.go @@ -0,0 +1,13 @@ +package keytransform + +import ds "github.com/ipfs/go-datastore" + +// KeyMapping is a function that maps one key to annother +type KeyMapping func(ds.Key) ds.Key + +// KeyTransform is an object with a pair of functions for (invertibly) +// transforming keys +type KeyTransform interface { + ConvertKey(ds.Key) ds.Key + InvertKey(ds.Key) ds.Key +} diff --git a/vendor/github.com/ipfs/go-datastore/keytransform/keytransform.go b/vendor/github.com/ipfs/go-datastore/keytransform/keytransform.go new file mode 100644 index 00000000..ae029730 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/keytransform/keytransform.go @@ -0,0 +1,255 @@ +package keytransform + +import ( + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" +) + +// Wrap wraps a given datastore with a KeyTransform function. +// The resulting wrapped datastore will use the transform on all Datastore +// operations. +func Wrap(child ds.Datastore, t KeyTransform) *Datastore { + if t == nil { + panic("t (KeyTransform) is nil") + } + + if child == nil { + panic("child (ds.Datastore) is nil") + } + + return &Datastore{child: child, KeyTransform: t} +} + +// Datastore keeps a KeyTransform function +type Datastore struct { + child ds.Datastore + + KeyTransform +} + +// Children implements ds.Shim +func (d *Datastore) Children() []ds.Datastore { + return []ds.Datastore{d.child} +} + +// Put stores the given value, transforming the key first. +func (d *Datastore) Put(key ds.Key, value []byte) (err error) { + return d.child.Put(d.ConvertKey(key), value) +} + +// Get returns the value for given key, transforming the key first. +func (d *Datastore) Get(key ds.Key) (value []byte, err error) { + return d.child.Get(d.ConvertKey(key)) +} + +// Has returns whether the datastore has a value for a given key, transforming +// the key first. +func (d *Datastore) Has(key ds.Key) (exists bool, err error) { + return d.child.Has(d.ConvertKey(key)) +} + +// GetSize returns the size of the value named by the given key, transforming +// the key first. +func (d *Datastore) GetSize(key ds.Key) (size int, err error) { + return d.child.GetSize(d.ConvertKey(key)) +} + +// Delete removes the value for given key +func (d *Datastore) Delete(key ds.Key) (err error) { + return d.child.Delete(d.ConvertKey(key)) +} + +// Query implements Query, inverting keys on the way back out. +func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) { + nq, cq := d.prepareQuery(q) + + cqr, err := d.child.Query(cq) + if err != nil { + return nil, err + } + + qr := dsq.ResultsFromIterator(q, dsq.Iterator{ + Next: func() (dsq.Result, bool) { + r, ok := cqr.NextSync() + if !ok { + return r, false + } + if r.Error == nil { + r.Entry.Key = d.InvertKey(ds.RawKey(r.Entry.Key)).String() + } + return r, true + }, + Close: func() error { + return cqr.Close() + }, + }) + return dsq.NaiveQueryApply(nq, qr), nil +} + +// Split the query into a child query and a naive query. That way, we can make +// the child datastore do as much work as possible. +func (d *Datastore) prepareQuery(q dsq.Query) (naive, child dsq.Query) { + + // First, put everything in the child query. Then, start taking things + // out. + child = q + + // Always let the child handle the key prefix. + child.Prefix = d.ConvertKey(ds.NewKey(child.Prefix)).String() + + // Check if the key transform is order-preserving so we can use the + // child datastore's built-in ordering. + orderPreserving := false + switch d.KeyTransform.(type) { + case PrefixTransform, *PrefixTransform: + orderPreserving = true + } + + // Try to let the child handle ordering. +orders: + for i, o := range child.Orders { + switch o.(type) { + case dsq.OrderByValue, *dsq.OrderByValue, + dsq.OrderByValueDescending, *dsq.OrderByValueDescending: + // Key doesn't matter. + continue + case dsq.OrderByKey, *dsq.OrderByKey, + dsq.OrderByKeyDescending, *dsq.OrderByKeyDescending: + // if the key transform preserves order, we can delegate + // to the child datastore. + if orderPreserving { + // When sorting, we compare with the first + // Order, then, if equal, we compare with the + // second Order, etc. However, keys are _unique_ + // so we'll never apply any additional orders + // after ordering by key. + child.Orders = child.Orders[:i+1] + break orders + } + } + + // Can't handle this order under transform, punt it to a naive + // ordering. + naive.Orders = q.Orders + child.Orders = nil + naive.Offset = q.Offset + child.Offset = 0 + naive.Limit = q.Limit + child.Limit = 0 + break + } + + // Try to let the child handle the filters. + + // don't modify the original filters. + child.Filters = append([]dsq.Filter(nil), child.Filters...) + + for i, f := range child.Filters { + switch f := f.(type) { + case dsq.FilterValueCompare, *dsq.FilterValueCompare: + continue + case dsq.FilterKeyCompare: + child.Filters[i] = dsq.FilterKeyCompare{ + Op: f.Op, + Key: d.ConvertKey(ds.NewKey(f.Key)).String(), + } + continue + case *dsq.FilterKeyCompare: + child.Filters[i] = &dsq.FilterKeyCompare{ + Op: f.Op, + Key: d.ConvertKey(ds.NewKey(f.Key)).String(), + } + continue + case dsq.FilterKeyPrefix: + child.Filters[i] = dsq.FilterKeyPrefix{ + Prefix: d.ConvertKey(ds.NewKey(f.Prefix)).String(), + } + continue + case *dsq.FilterKeyPrefix: + child.Filters[i] = &dsq.FilterKeyPrefix{ + Prefix: d.ConvertKey(ds.NewKey(f.Prefix)).String(), + } + continue + } + + // Not a known filter, defer to the naive implementation. + naive.Filters = q.Filters + child.Filters = nil + naive.Offset = q.Offset + child.Offset = 0 + naive.Limit = q.Limit + child.Limit = 0 + break + } + return +} + +func (d *Datastore) Close() error { + return d.child.Close() +} + +// DiskUsage implements the PersistentDatastore interface. +func (d *Datastore) DiskUsage() (uint64, error) { + return ds.DiskUsage(d.child) +} + +func (d *Datastore) Batch() (ds.Batch, error) { + bds, ok := d.child.(ds.Batching) + if !ok { + return nil, ds.ErrBatchUnsupported + } + + childbatch, err := bds.Batch() + if err != nil { + return nil, err + } + return &transformBatch{ + dst: childbatch, + f: d.ConvertKey, + }, nil +} + +type transformBatch struct { + dst ds.Batch + + f KeyMapping +} + +func (t *transformBatch) Put(key ds.Key, val []byte) error { + return t.dst.Put(t.f(key), val) +} + +func (t *transformBatch) Delete(key ds.Key) error { + return t.dst.Delete(t.f(key)) +} + +func (t *transformBatch) Commit() error { + return t.dst.Commit() +} + +func (d *Datastore) Check() error { + if c, ok := d.child.(ds.CheckedDatastore); ok { + return c.Check() + } + return nil +} + +func (d *Datastore) Scrub() error { + if c, ok := d.child.(ds.ScrubbedDatastore); ok { + return c.Scrub() + } + return nil +} + +func (d *Datastore) CollectGarbage() error { + if c, ok := d.child.(ds.GCDatastore); ok { + return c.CollectGarbage() + } + return nil +} + +var _ ds.Datastore = (*Datastore)(nil) +var _ ds.GCDatastore = (*Datastore)(nil) +var _ ds.Batching = (*Datastore)(nil) +var _ ds.PersistentDatastore = (*Datastore)(nil) +var _ ds.ScrubbedDatastore = (*Datastore)(nil) diff --git a/vendor/github.com/ipfs/go-datastore/keytransform/transforms.go b/vendor/github.com/ipfs/go-datastore/keytransform/transforms.go new file mode 100644 index 00000000..cc39897e --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/keytransform/transforms.go @@ -0,0 +1,49 @@ +package keytransform + +import ds "github.com/ipfs/go-datastore" + +// Pair is a convince struct for constructing a key transform. +type Pair struct { + Convert KeyMapping + Invert KeyMapping +} + +func (t *Pair) ConvertKey(k ds.Key) ds.Key { + return t.Convert(k) +} + +func (t *Pair) InvertKey(k ds.Key) ds.Key { + return t.Invert(k) +} + +var _ KeyTransform = (*Pair)(nil) + +// PrefixTransform constructs a KeyTransform with a pair of functions that +// add or remove the given prefix key. +// +// Warning: will panic if prefix not found when it should be there. This is +// to avoid insidious data inconsistency errors. +type PrefixTransform struct { + Prefix ds.Key +} + +// ConvertKey adds the prefix. +func (p PrefixTransform) ConvertKey(k ds.Key) ds.Key { + return p.Prefix.Child(k) +} + +// InvertKey removes the prefix. panics if prefix not found. +func (p PrefixTransform) InvertKey(k ds.Key) ds.Key { + if p.Prefix.String() == "/" { + return k + } + + if !p.Prefix.IsAncestorOf(k) { + panic("expected prefix not found") + } + + s := k.String()[len(p.Prefix.String()):] + return ds.RawKey(s) +} + +var _ KeyTransform = (*PrefixTransform)(nil) diff --git a/vendor/github.com/ipfs/go-datastore/mount/mount.go b/vendor/github.com/ipfs/go-datastore/mount/mount.go new file mode 100644 index 00000000..326277a6 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/mount/mount.go @@ -0,0 +1,400 @@ +// Package mount provides a Datastore that has other Datastores +// mounted at various key prefixes and is threadsafe +package mount + +import ( + "container/heap" + "errors" + "fmt" + "sort" + "strings" + "sync" + + ds "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" +) + +var ( + ErrNoMount = errors.New("no datastore mounted for this key") +) + +type Mount struct { + Prefix ds.Key + Datastore ds.Datastore +} + +func New(mounts []Mount) *Datastore { + // make a copy so we're sure it doesn't mutate + m := make([]Mount, len(mounts)) + for i, v := range mounts { + m[i] = v + } + sort.Slice(m, func(i, j int) bool { return m[i].Prefix.String() > m[j].Prefix.String() }) + return &Datastore{mounts: m} +} + +type Datastore struct { + mounts []Mount +} + +var _ ds.Datastore = (*Datastore)(nil) + +func (d *Datastore) lookup(key ds.Key) (ds.Datastore, ds.Key, ds.Key) { + for _, m := range d.mounts { + if m.Prefix.Equal(key) || m.Prefix.IsAncestorOf(key) { + s := strings.TrimPrefix(key.String(), m.Prefix.String()) + k := ds.NewKey(s) + return m.Datastore, m.Prefix, k + } + } + return nil, ds.NewKey("/"), key +} + +type queryResults struct { + mount ds.Key + results query.Results + next query.Result +} + +func (qr *queryResults) advance() bool { + if qr.results == nil { + return false + } + + qr.next = query.Result{} + r, more := qr.results.NextSync() + if !more { + err := qr.results.Close() + qr.results = nil + if err != nil { + // One more result, the error. + qr.next = query.Result{Error: err} + return true + } + return false + } + + r.Key = qr.mount.Child(ds.RawKey(r.Key)).String() + qr.next = r + return true +} + +type querySet struct { + query query.Query + heads []*queryResults +} + +func (h *querySet) Len() int { + return len(h.heads) +} + +func (h *querySet) Less(i, j int) bool { + return query.Less(h.query.Orders, h.heads[i].next.Entry, h.heads[j].next.Entry) +} + +func (h *querySet) Swap(i, j int) { + h.heads[i], h.heads[j] = h.heads[j], h.heads[i] +} + +func (h *querySet) Push(x interface{}) { + h.heads = append(h.heads, x.(*queryResults)) +} + +func (h *querySet) Pop() interface{} { + i := len(h.heads) - 1 + last := h.heads[i] + h.heads[i] = nil + h.heads = h.heads[:i] + return last +} + +func (h *querySet) close() error { + var errs []error + for _, qr := range h.heads { + err := qr.results.Close() + if err != nil { + errs = append(errs, err) + } + } + h.heads = nil + if len(errs) > 0 { + return errs[0] + } + return nil +} + +func (h *querySet) addResults(mount ds.Key, results query.Results) { + r := &queryResults{ + results: results, + mount: mount, + } + if r.advance() { + heap.Push(h, r) + } +} + +func (h *querySet) next() (query.Result, bool) { + if len(h.heads) == 0 { + return query.Result{}, false + } + head := h.heads[0] + next := head.next + + if head.advance() { + heap.Fix(h, 0) + } else { + heap.Remove(h, 0) + } + + return next, true +} + +// lookupAll returns all mounts that might contain keys that are descendant of +// +// Matching: /ao/e +// +// / B /ao/e +// /a/ not matching +// /ao/ B /e +// /ao/e/ A / +// /ao/e/uh/ A / +// /aoe/ not matching +func (d *Datastore) lookupAll(key ds.Key) (dst []ds.Datastore, mountpoint, rest []ds.Key) { + for _, m := range d.mounts { + p := m.Prefix.String() + if len(p) > 1 { + p = p + "/" + } + + if strings.HasPrefix(p, key.String()) { + dst = append(dst, m.Datastore) + mountpoint = append(mountpoint, m.Prefix) + rest = append(rest, ds.NewKey("/")) + } else if strings.HasPrefix(key.String(), p) { + r := strings.TrimPrefix(key.String(), m.Prefix.String()) + + dst = append(dst, m.Datastore) + mountpoint = append(mountpoint, m.Prefix) + rest = append(rest, ds.NewKey(r)) + } + } + return dst, mountpoint, rest +} + +func (d *Datastore) Put(key ds.Key, value []byte) error { + cds, _, k := d.lookup(key) + if cds == nil { + return ErrNoMount + } + return cds.Put(k, value) +} + +func (d *Datastore) Get(key ds.Key) (value []byte, err error) { + cds, _, k := d.lookup(key) + if cds == nil { + return nil, ds.ErrNotFound + } + return cds.Get(k) +} + +func (d *Datastore) Has(key ds.Key) (exists bool, err error) { + cds, _, k := d.lookup(key) + if cds == nil { + return false, nil + } + return cds.Has(k) +} + +func (d *Datastore) GetSize(key ds.Key) (size int, err error) { + cds, _, k := d.lookup(key) + if cds == nil { + return -1, ds.ErrNotFound + } + return cds.GetSize(k) +} + +func (d *Datastore) Delete(key ds.Key) error { + cds, _, k := d.lookup(key) + if cds == nil { + return ds.ErrNotFound + } + return cds.Delete(k) +} + +func (d *Datastore) Query(master query.Query) (query.Results, error) { + childQuery := query.Query{ + Prefix: master.Prefix, + Limit: master.Limit, + Orders: master.Orders, + KeysOnly: master.KeysOnly, + ReturnExpirations: master.ReturnExpirations, + } + + prefix := ds.NewKey(childQuery.Prefix) + dses, mounts, rests := d.lookupAll(prefix) + + queries := &querySet{ + query: childQuery, + heads: make([]*queryResults, 0, len(dses)), + } + + for i := range dses { + mount := mounts[i] + dstore := dses[i] + rest := rests[i] + + qi := childQuery + qi.Prefix = rest.String() + results, err := dstore.Query(qi) + + if err != nil { + _ = queries.close() + return nil, err + } + queries.addResults(mount, results) + } + + qr := query.ResultsFromIterator(childQuery, query.Iterator{ + Next: queries.next, + Close: queries.close, + }) + + if len(master.Filters) > 0 { + for _, f := range master.Filters { + qr = query.NaiveFilter(qr, f) + } + } + + if master.Offset > 0 { + qr = query.NaiveOffset(qr, master.Offset) + } + + if childQuery.Limit > 0 { + qr = query.NaiveLimit(qr, childQuery.Limit) + } + + return qr, nil +} + +func (d *Datastore) Close() error { + for _, d := range d.mounts { + err := d.Datastore.Close() + if err != nil { + return err + } + } + return nil +} + +// DiskUsage returns the sum of DiskUsages for the mounted datastores. +// Non PersistentDatastores will not be accounted. +func (d *Datastore) DiskUsage() (uint64, error) { + var duTotal uint64 = 0 + for _, d := range d.mounts { + du, err := ds.DiskUsage(d.Datastore) + duTotal += du + if err != nil { + return duTotal, err + } + } + return duTotal, nil +} + +type mountBatch struct { + mounts map[string]ds.Batch + lk sync.Mutex + + d *Datastore +} + +func (d *Datastore) Batch() (ds.Batch, error) { + return &mountBatch{ + mounts: make(map[string]ds.Batch), + d: d, + }, nil +} + +func (mt *mountBatch) lookupBatch(key ds.Key) (ds.Batch, ds.Key, error) { + mt.lk.Lock() + defer mt.lk.Unlock() + + child, loc, rest := mt.d.lookup(key) + t, ok := mt.mounts[loc.String()] + if !ok { + bds, ok := child.(ds.Batching) + if !ok { + return nil, ds.NewKey(""), ds.ErrBatchUnsupported + } + var err error + t, err = bds.Batch() + if err != nil { + return nil, ds.NewKey(""), err + } + mt.mounts[loc.String()] = t + } + return t, rest, nil +} + +func (mt *mountBatch) Put(key ds.Key, val []byte) error { + t, rest, err := mt.lookupBatch(key) + if err != nil { + return err + } + + return t.Put(rest, val) +} + +func (mt *mountBatch) Delete(key ds.Key) error { + t, rest, err := mt.lookupBatch(key) + if err != nil { + return err + } + + return t.Delete(rest) +} + +func (mt *mountBatch) Commit() error { + mt.lk.Lock() + defer mt.lk.Unlock() + + for _, t := range mt.mounts { + err := t.Commit() + if err != nil { + return err + } + } + return nil +} + +func (d *Datastore) Check() error { + for _, m := range d.mounts { + if c, ok := m.Datastore.(ds.CheckedDatastore); ok { + if err := c.Check(); err != nil { + return fmt.Errorf("checking datastore at %s: %s", m.Prefix.String(), err.Error()) + } + } + } + return nil +} + +func (d *Datastore) Scrub() error { + for _, m := range d.mounts { + if c, ok := m.Datastore.(ds.ScrubbedDatastore); ok { + if err := c.Scrub(); err != nil { + return fmt.Errorf("scrubbing datastore at %s: %s", m.Prefix.String(), err.Error()) + } + } + } + return nil +} + +func (d *Datastore) CollectGarbage() error { + for _, m := range d.mounts { + if c, ok := m.Datastore.(ds.GCDatastore); ok { + if err := c.CollectGarbage(); err != nil { + return fmt.Errorf("gc on datastore at %s: %s", m.Prefix.String(), err.Error()) + } + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-datastore/namespace/doc.go b/vendor/github.com/ipfs/go-datastore/namespace/doc.go new file mode 100644 index 00000000..9ff9a8ca --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/namespace/doc.go @@ -0,0 +1,24 @@ +// Package namespace introduces a namespace Datastore Shim, which basically +// mounts the entire child datastore under a prefix. +// +// Use the Wrap function to wrap a datastore with any Key prefix. For example: +// +// import ( +// "fmt" +// +// ds "github.com/ipfs/go-datastore" +// nsds "github.com/ipfs/go-datastore/namespace" +// ) +// +// func main() { +// mp := ds.NewMapDatastore() +// ns := nsds.Wrap(mp, ds.NewKey("/foo/bar")) +// +// // in the Namespace Datastore: +// ns.Put(ds.NewKey("/beep"), "boop") +// v2, _ := ns.Get(ds.NewKey("/beep")) // v2 == "boop" +// +// // and, in the underlying MapDatastore: +// v3, _ := mp.Get(ds.NewKey("/foo/bar/beep")) // v3 == "boop" +// } +package namespace diff --git a/vendor/github.com/ipfs/go-datastore/namespace/namespace.go b/vendor/github.com/ipfs/go-datastore/namespace/namespace.go new file mode 100644 index 00000000..1913fb79 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/namespace/namespace.go @@ -0,0 +1,26 @@ +package namespace + +import ( + ds "github.com/ipfs/go-datastore" + ktds "github.com/ipfs/go-datastore/keytransform" +) + +// PrefixTransform constructs a KeyTransform with a pair of functions that +// add or remove the given prefix key. +// +// Warning: will panic if prefix not found when it should be there. This is +// to avoid insidious data inconsistency errors. +// +// DEPRECATED: Use ktds.PrefixTransform directly. +func PrefixTransform(prefix ds.Key) ktds.PrefixTransform { + return ktds.PrefixTransform{Prefix: prefix} +} + +// Wrap wraps a given datastore with a key-prefix. +func Wrap(child ds.Datastore, prefix ds.Key) *ktds.Datastore { + if child == nil { + panic("child (ds.Datastore) is nil") + } + + return ktds.Wrap(child, PrefixTransform(prefix)) +} diff --git a/vendor/github.com/ipfs/go-datastore/package.json b/vendor/github.com/ipfs/go-datastore/package.json new file mode 100644 index 00000000..d1d52e6a --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/package.json @@ -0,0 +1,42 @@ +{ + "author": "jbenet", + "bugs": { + "url": "https://github.com/jbenet/go-datastore" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-datastore" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP", + "name": "goprocess", + "version": "1.0.0" + }, + { + "author": "gustavo", + "hash": "QmYBJ8BXPDTMnzLFdv4rS5kbR1fUFASDVDpK7ZbeWMx6hq", + "name": "go-check", + "version": "1.0.0" + }, + { + "author": "hsanjuan", + "hash": "QmUe1WCHkQaz4UeNKiHDUBV2T6i9prc3DniqyHPXyfGaUq", + "name": "go-ipfs-delay", + "version": "0.1.0" + }, + { + "author": "google", + "hash": "QmSSeQqc5QeuefkaM6JFV5tSF9knLUkXKVhW1eYRiqe72W", + "name": "uuid", + "version": "0.1.0" + } + ], + "gxVersion": "0.7.0", + "language": "go", + "license": "MIT", + "name": "go-datastore", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "3.6.1" +} + diff --git a/vendor/github.com/ipfs/go-datastore/query/filter.go b/vendor/github.com/ipfs/go-datastore/query/filter.go new file mode 100644 index 00000000..501414d3 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/query/filter.go @@ -0,0 +1,90 @@ +package query + +import ( + "bytes" + "fmt" + "strings" +) + +// Filter is an object that tests ResultEntries +type Filter interface { + // Filter returns whether an entry passes the filter + Filter(e Entry) bool +} + +// Op is a comparison operator +type Op string + +var ( + Equal = Op("==") + NotEqual = Op("!=") + GreaterThan = Op(">") + GreaterThanOrEqual = Op(">=") + LessThan = Op("<") + LessThanOrEqual = Op("<=") +) + +// FilterValueCompare is used to signal to datastores they +// should apply internal comparisons. unfortunately, there +// is no way to apply comparisons* to interface{} types in +// Go, so if the datastore doesnt have a special way to +// handle these comparisons, you must provided the +// TypedFilter to actually do filtering. +// +// [*] other than == and !=, which use reflect.DeepEqual. +type FilterValueCompare struct { + Op Op + Value []byte +} + +func (f FilterValueCompare) Filter(e Entry) bool { + cmp := bytes.Compare(e.Value, f.Value) + switch f.Op { + case Equal: + return cmp == 0 + case NotEqual: + return cmp != 0 + case LessThan: + return cmp < 0 + case LessThanOrEqual: + return cmp <= 0 + case GreaterThan: + return cmp > 0 + case GreaterThanOrEqual: + return cmp >= 0 + default: + panic(fmt.Errorf("unknown operation: %s", f.Op)) + } +} + +type FilterKeyCompare struct { + Op Op + Key string +} + +func (f FilterKeyCompare) Filter(e Entry) bool { + switch f.Op { + case Equal: + return e.Key == f.Key + case NotEqual: + return e.Key != f.Key + case GreaterThan: + return e.Key > f.Key + case GreaterThanOrEqual: + return e.Key >= f.Key + case LessThan: + return e.Key < f.Key + case LessThanOrEqual: + return e.Key <= f.Key + default: + panic(fmt.Errorf("unknown op '%s'", f.Op)) + } +} + +type FilterKeyPrefix struct { + Prefix string +} + +func (f FilterKeyPrefix) Filter(e Entry) bool { + return strings.HasPrefix(e.Key, f.Prefix) +} diff --git a/vendor/github.com/ipfs/go-datastore/query/order.go b/vendor/github.com/ipfs/go-datastore/query/order.go new file mode 100644 index 00000000..5e0acf1b --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/query/order.go @@ -0,0 +1,74 @@ +package query + +import ( + "bytes" + "sort" + "strings" +) + +// Order is an object used to order objects +type Order interface { + Compare(a, b Entry) int +} + +// OrderByFunction orders the results based on the result of the given function. +type OrderByFunction func(a, b Entry) int + +func (o OrderByFunction) Compare(a, b Entry) int { + return o(a, b) +} + +// OrderByValue is used to signal to datastores they should apply internal +// orderings. +type OrderByValue struct{} + +func (o OrderByValue) Compare(a, b Entry) int { + return bytes.Compare(a.Value, b.Value) +} + +// OrderByValueDescending is used to signal to datastores they +// should apply internal orderings. +type OrderByValueDescending struct{} + +func (o OrderByValueDescending) Compare(a, b Entry) int { + return -bytes.Compare(a.Value, b.Value) +} + +// OrderByKey +type OrderByKey struct{} + +func (o OrderByKey) Compare(a, b Entry) int { + return strings.Compare(a.Key, b.Key) +} + +// OrderByKeyDescending +type OrderByKeyDescending struct{} + +func (o OrderByKeyDescending) Compare(a, b Entry) int { + return -strings.Compare(a.Key, b.Key) +} + +// Less returns true if a comes before b with the requested orderings. +func Less(orders []Order, a, b Entry) bool { + for _, cmp := range orders { + switch cmp.Compare(a, b) { + case 0: + case -1: + return true + case 1: + return false + } + } + + // This gives us a *stable* sort for free. We don't care + // preserving the order from the underlying datastore + // because it's undefined. + return a.Key < b.Key +} + +// Sort sorts the given entries using the given orders. +func Sort(orders []Order, entries []Entry) { + sort.Slice(entries, func(i int, j int) bool { + return Less(orders, entries[i], entries[j]) + }) +} diff --git a/vendor/github.com/ipfs/go-datastore/query/query.go b/vendor/github.com/ipfs/go-datastore/query/query.go new file mode 100644 index 00000000..2540dfc6 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/query/query.go @@ -0,0 +1,386 @@ +package query + +import ( + "time" + + goprocess "github.com/jbenet/goprocess" +) + +/* +Query represents storage for any key-value pair. + +tl;dr: + + queries are supported across datastores. + Cheap on top of relational dbs, and expensive otherwise. + Pick the right tool for the job! + +In addition to the key-value store get and set semantics, datastore +provides an interface to retrieve multiple records at a time through +the use of queries. The datastore Query model gleans a common set of +operations performed when querying. To avoid pasting here years of +database research, let’s summarize the operations datastore supports. + +Query Operations: + + * namespace - scope the query, usually by object type + * filters - select a subset of values by applying constraints + * orders - sort the results by applying sort conditions + * limit - impose a numeric limit on the number of results + * offset - skip a number of results (for efficient pagination) + +datastore combines these operations into a simple Query class that allows +applications to define their constraints in a simple, generic, way without +introducing datastore specific calls, languages, etc. + +Of course, different datastores provide relational query support across a +wide spectrum, from full support in traditional databases to none at all in +most key-value stores. Datastore aims to provide a common, simple interface +for the sake of application evolution over time and keeping large code bases +free of tool-specific code. It would be ridiculous to claim to support high- +performance queries on architectures that obviously do not. Instead, datastore +provides the interface, ideally translating queries to their native form +(e.g. into SQL for MySQL). + +However, on the wrong datastore, queries can potentially incur the high cost +of performing the aforemantioned query operations on the data set directly in +Go. It is the client’s responsibility to select the right tool for the job: +pick a data storage solution that fits the application’s needs now, and wrap +it with a datastore implementation. As the needs change, swap out datastore +implementations to support your new use cases. Some applications, particularly +in early development stages, can afford to incurr the cost of queries on non- +relational databases (e.g. using a FSDatastore and not worry about a database +at all). When it comes time to switch the tool for performance, updating the +application code can be as simple as swapping the datastore in one place, not +all over the application code base. This gain in engineering time, both at +initial development and during later iterations, can significantly offset the +cost of the layer of abstraction. + +*/ +type Query struct { + Prefix string // namespaces the query to results whose keys have Prefix + Filters []Filter // filter results. apply sequentially + Orders []Order // order results. apply hierarchically + Limit int // maximum number of results + Offset int // skip given number of results + KeysOnly bool // return only keys. + ReturnExpirations bool // return expirations (see TTLDatastore) +} + +// Entry is a query result entry. +type Entry struct { + Key string // cant be ds.Key because circular imports ...!!! + Value []byte // Will be nil if KeysOnly has been passed. + Expiration time.Time // Entry expiration timestamp if requested and supported (see TTLDatastore). +} + +// Result is a special entry that includes an error, so that the client +// may be warned about internal errors. If Error is non-nil, Entry must be +// empty. +type Result struct { + Entry + + Error error +} + +// Results is a set of Query results. This is the interface for clients. +// Example: +// +// qr, _ := myds.Query(q) +// for r := range qr.Next() { +// if r.Error != nil { +// // handle. +// break +// } +// +// fmt.Println(r.Entry.Key, r.Entry.Value) +// } +// +// or, wait on all results at once: +// +// qr, _ := myds.Query(q) +// es, _ := qr.Rest() +// for _, e := range es { +// fmt.Println(e.Key, e.Value) +// } +// +type Results interface { + Query() Query // the query these Results correspond to + Next() <-chan Result // returns a channel to wait for the next result + NextSync() (Result, bool) // blocks and waits to return the next result, second paramter returns false when results are exhausted + Rest() ([]Entry, error) // waits till processing finishes, returns all entries at once. + Close() error // client may call Close to signal early exit + + // Process returns a goprocess.Process associated with these results. + // most users will not need this function (Close is all they want), + // but it's here in case you want to connect the results to other + // goprocess-friendly things. + Process() goprocess.Process +} + +// results implements Results +type results struct { + query Query + proc goprocess.Process + res <-chan Result +} + +func (r *results) Next() <-chan Result { + return r.res +} + +func (r *results) NextSync() (Result, bool) { + val, ok := <-r.res + return val, ok +} + +func (r *results) Rest() ([]Entry, error) { + var es []Entry + for e := range r.res { + if e.Error != nil { + return es, e.Error + } + es = append(es, e.Entry) + } + <-r.proc.Closed() // wait till the processing finishes. + return es, nil +} + +func (r *results) Process() goprocess.Process { + return r.proc +} + +func (r *results) Close() error { + return r.proc.Close() +} + +func (r *results) Query() Query { + return r.query +} + +// ResultBuilder is what implementors use to construct results +// Implementors of datastores and their clients must respect the +// Process of the Request: +// +// * clients must call r.Process().Close() on an early exit, so +// implementations can reclaim resources. +// * if the Entries are read to completion (channel closed), Process +// should be closed automatically. +// * datastores must respect <-Process.Closing(), which intermediates +// an early close signal from the client. +// +type ResultBuilder struct { + Query Query + Process goprocess.Process + Output chan Result +} + +// Results returns a Results to to this builder. +func (rb *ResultBuilder) Results() Results { + return &results{ + query: rb.Query, + proc: rb.Process, + res: rb.Output, + } +} + +const NormalBufSize = 1 +const KeysOnlyBufSize = 128 + +func NewResultBuilder(q Query) *ResultBuilder { + bufSize := NormalBufSize + if q.KeysOnly { + bufSize = KeysOnlyBufSize + } + b := &ResultBuilder{ + Query: q, + Output: make(chan Result, bufSize), + } + b.Process = goprocess.WithTeardown(func() error { + close(b.Output) + return nil + }) + return b +} + +// ResultsWithChan returns a Results object from a channel +// of Result entries. +// +// DEPRECATED: This iterator is impossible to cancel correctly. Canceling it +// will leave anything trying to write to the result channel hanging. +func ResultsWithChan(q Query, res <-chan Result) Results { + return ResultsWithProcess(q, func(worker goprocess.Process, out chan<- Result) { + for { + select { + case <-worker.Closing(): // client told us to close early + return + case e, more := <-res: + if !more { + return + } + + select { + case out <- e: + case <-worker.Closing(): // client told us to close early + return + } + } + } + }) +} + +// ResultsWithProcess returns a Results object with the results generated by the +// passed subprocess. +func ResultsWithProcess(q Query, proc func(goprocess.Process, chan<- Result)) Results { + b := NewResultBuilder(q) + + // go consume all the entries and add them to the results. + b.Process.Go(func(worker goprocess.Process) { + proc(worker, b.Output) + }) + + go b.Process.CloseAfterChildren() + return b.Results() +} + +// ResultsWithEntries returns a Results object from a list of entries +func ResultsWithEntries(q Query, res []Entry) Results { + i := 0 + return ResultsFromIterator(q, Iterator{ + Next: func() (Result, bool) { + if i >= len(res) { + return Result{}, false + } + next := res[i] + i++ + return Result{Entry: next}, true + }, + }) +} + +func ResultsReplaceQuery(r Results, q Query) Results { + switch r := r.(type) { + case *results: + // note: not using field names to make sure all fields are copied + return &results{q, r.proc, r.res} + case *resultsIter: + // note: not using field names to make sure all fields are copied + lr := r.legacyResults + if lr != nil { + lr = &results{q, lr.proc, lr.res} + } + return &resultsIter{q, r.next, r.close, lr} + default: + panic("unknown results type") + } +} + +// +// ResultFromIterator provides an alternative way to to construct +// results without the use of channels. +// + +func ResultsFromIterator(q Query, iter Iterator) Results { + if iter.Close == nil { + iter.Close = noopClose + } + return &resultsIter{ + query: q, + next: iter.Next, + close: iter.Close, + } +} + +func noopClose() error { + return nil +} + +type Iterator struct { + Next func() (Result, bool) + Close func() error // note: might be called more than once +} + +type resultsIter struct { + query Query + next func() (Result, bool) + close func() error + legacyResults *results +} + +func (r *resultsIter) Next() <-chan Result { + r.useLegacyResults() + return r.legacyResults.Next() +} + +func (r *resultsIter) NextSync() (Result, bool) { + if r.legacyResults != nil { + return r.legacyResults.NextSync() + } else { + res, ok := r.next() + if !ok { + r.close() + } + return res, ok + } +} + +func (r *resultsIter) Rest() ([]Entry, error) { + var es []Entry + for { + e, ok := r.NextSync() + if !ok { + break + } + if e.Error != nil { + return es, e.Error + } + es = append(es, e.Entry) + } + return es, nil +} + +func (r *resultsIter) Process() goprocess.Process { + r.useLegacyResults() + return r.legacyResults.Process() +} + +func (r *resultsIter) Close() error { + if r.legacyResults != nil { + return r.legacyResults.Close() + } else { + return r.close() + } +} + +func (r *resultsIter) Query() Query { + return r.query +} + +func (r *resultsIter) useLegacyResults() { + if r.legacyResults != nil { + return + } + + b := NewResultBuilder(r.query) + + // go consume all the entries and add them to the results. + b.Process.Go(func(worker goprocess.Process) { + defer r.close() + for { + e, ok := r.next() + if !ok { + break + } + select { + case b.Output <- e: + case <-worker.Closing(): // client told us to close early + return + } + } + return + }) + + go b.Process.CloseAfterChildren() + + r.legacyResults = b.Results().(*results) +} diff --git a/vendor/github.com/ipfs/go-datastore/query/query_impl.go b/vendor/github.com/ipfs/go-datastore/query/query_impl.go new file mode 100644 index 00000000..6c2e422b --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/query/query_impl.go @@ -0,0 +1,142 @@ +package query + +import ( + goprocess "github.com/jbenet/goprocess" +) + +// NaiveFilter applies a filter to the results. +func NaiveFilter(qr Results, filter Filter) Results { + return ResultsFromIterator(qr.Query(), Iterator{ + Next: func() (Result, bool) { + for { + e, ok := qr.NextSync() + if !ok { + return Result{}, false + } + if e.Error != nil || filter.Filter(e.Entry) { + return e, true + } + } + }, + Close: func() error { + return qr.Close() + }, + }) +} + +// NaiveLimit truncates the results to a given int limit +func NaiveLimit(qr Results, limit int) Results { + if limit == 0 { + // 0 means no limit + return qr + } + closed := false + return ResultsFromIterator(qr.Query(), Iterator{ + Next: func() (Result, bool) { + if limit == 0 { + if !closed { + closed = true + err := qr.Close() + if err != nil { + return Result{Error: err}, true + } + } + return Result{}, false + } + limit-- + return qr.NextSync() + }, + Close: func() error { + if closed { + return nil + } + closed = true + return qr.Close() + }, + }) +} + +// NaiveOffset skips a given number of results +func NaiveOffset(qr Results, offset int) Results { + return ResultsFromIterator(qr.Query(), Iterator{ + Next: func() (Result, bool) { + for ; offset > 0; offset-- { + res, ok := qr.NextSync() + if !ok || res.Error != nil { + return res, ok + } + } + return qr.NextSync() + }, + Close: func() error { + return qr.Close() + }, + }) +} + +// NaiveOrder reorders results according to given orders. +// WARNING: this is the only non-stream friendly operation! +func NaiveOrder(qr Results, orders ...Order) Results { + // Short circuit. + if len(orders) == 0 { + return qr + } + + return ResultsWithProcess(qr.Query(), func(worker goprocess.Process, out chan<- Result) { + defer qr.Close() + var entries []Entry + collect: + for { + select { + case <-worker.Closing(): + return + case e, ok := <-qr.Next(): + if !ok { + break collect + } + if e.Error != nil { + out <- e + continue + } + entries = append(entries, e.Entry) + } + } + + Sort(orders, entries) + + for _, e := range entries { + select { + case <-worker.Closing(): + return + case out <- Result{Entry: e}: + } + } + }) +} + +func NaiveQueryApply(q Query, qr Results) Results { + if q.Prefix != "" { + qr = NaiveFilter(qr, FilterKeyPrefix{q.Prefix}) + } + for _, f := range q.Filters { + qr = NaiveFilter(qr, f) + } + if len(q.Orders) > 0 { + qr = NaiveOrder(qr, q.Orders...) + } + if q.Offset != 0 { + qr = NaiveOffset(qr, q.Offset) + } + if q.Limit != 0 { + qr = NaiveLimit(qr, q.Limit) + } + return qr +} + +func ResultEntriesFrom(keys []string, vals [][]byte) []Entry { + re := make([]Entry, len(keys)) + for i, k := range keys { + re[i] = Entry{Key: k, Value: vals[i]} + } + return re +} diff --git a/vendor/github.com/ipfs/go-datastore/retrystore/retrystore.go b/vendor/github.com/ipfs/go-datastore/retrystore/retrystore.go new file mode 100644 index 00000000..a03daa8c --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/retrystore/retrystore.go @@ -0,0 +1,96 @@ +// Package retrystore provides a datastore wrapper which +// allows to retry operations. +package retrystore + +import ( + "fmt" + "time" + + ds "github.com/ipfs/go-datastore" +) + +// Datastore wraps a Batching datastore with a +// user-provided TempErrorFunc -which determines if an error +// is a temporal error and thus, worth retrying-, an amount of Retries +// -which specify how many times to retry an operation after +// a temporal error- and a base Delay, which is multiplied by the +// current retry and performs a pause before attempting the operation again. +type Datastore struct { + TempErrFunc func(error) bool + Retries int + Delay time.Duration + + ds.Batching +} + +var errFmtString = "ran out of retries trying to get past temporary error: %s" + +func (d *Datastore) runOp(op func() error) error { + err := op() + if err == nil || !d.TempErrFunc(err) { + return err + } + + for i := 0; i < d.Retries; i++ { + time.Sleep(time.Duration(i+1) * d.Delay) + + err = op() + if err == nil || !d.TempErrFunc(err) { + return err + } + } + + return fmt.Errorf(errFmtString, err) +} + +// DiskUsage implements the PersistentDatastore interface. +func (d *Datastore) DiskUsage() (uint64, error) { + var size uint64 + err := d.runOp(func() error { + var err error + size, err = ds.DiskUsage(d.Batching) + return err + }) + return size, err +} + +// Get retrieves a value given a key. +func (d *Datastore) Get(k ds.Key) ([]byte, error) { + var val []byte + err := d.runOp(func() error { + var err error + val, err = d.Batching.Get(k) + return err + }) + + return val, err +} + +// Put stores a key/value. +func (d *Datastore) Put(k ds.Key, val []byte) error { + return d.runOp(func() error { + return d.Batching.Put(k, val) + }) +} + +// Has checks if a key is stored. +func (d *Datastore) Has(k ds.Key) (bool, error) { + var has bool + err := d.runOp(func() error { + var err error + has, err = d.Batching.Has(k) + return err + }) + return has, err +} + +// GetSize returns the size of the value in the datastore, if present. +func (d *Datastore) GetSize(k ds.Key) (int, error) { + var size int + err := d.runOp(func() error { + var err error + size, err = d.Batching.GetSize(k) + return err + }) + return size, err +} diff --git a/vendor/github.com/ipfs/go-datastore/sync/sync.go b/vendor/github.com/ipfs/go-datastore/sync/sync.go new file mode 100644 index 00000000..5a4bb0e7 --- /dev/null +++ b/vendor/github.com/ipfs/go-datastore/sync/sync.go @@ -0,0 +1,167 @@ +package sync + +import ( + "sync" + + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" +) + +// MutexDatastore contains a child datastire and a mutex. +// used for coarse sync +type MutexDatastore struct { + sync.RWMutex + + child ds.Datastore +} + +// MutexWrap constructs a datastore with a coarse lock around the entire +// datastore, for every single operation. +func MutexWrap(d ds.Datastore) *MutexDatastore { + return &MutexDatastore{child: d} +} + +// Children implements Shim +func (d *MutexDatastore) Children() []ds.Datastore { + return []ds.Datastore{d.child} +} + +// Put implements Datastore.Put +func (d *MutexDatastore) Put(key ds.Key, value []byte) (err error) { + d.Lock() + defer d.Unlock() + return d.child.Put(key, value) +} + +// Get implements Datastore.Get +func (d *MutexDatastore) Get(key ds.Key) (value []byte, err error) { + d.RLock() + defer d.RUnlock() + return d.child.Get(key) +} + +// Has implements Datastore.Has +func (d *MutexDatastore) Has(key ds.Key) (exists bool, err error) { + d.RLock() + defer d.RUnlock() + return d.child.Has(key) +} + +// GetSize implements Datastore.GetSize +func (d *MutexDatastore) GetSize(key ds.Key) (size int, err error) { + d.RLock() + defer d.RUnlock() + return d.child.GetSize(key) +} + +// Delete implements Datastore.Delete +func (d *MutexDatastore) Delete(key ds.Key) (err error) { + d.Lock() + defer d.Unlock() + return d.child.Delete(key) +} + +// Query implements Datastore.Query +func (d *MutexDatastore) Query(q dsq.Query) (dsq.Results, error) { + d.RLock() + defer d.RUnlock() + + // Apply the entire query while locked. Non-sync datastores may not + // allow concurrent queries. + + results, err := d.child.Query(q) + if err != nil { + return nil, err + } + + entries, err1 := results.Rest() + err2 := results.Close() + switch { + case err1 != nil: + return nil, err1 + case err2 != nil: + return nil, err2 + } + return dsq.ResultsWithEntries(q, entries), nil +} + +func (d *MutexDatastore) Batch() (ds.Batch, error) { + d.RLock() + defer d.RUnlock() + bds, ok := d.child.(ds.Batching) + if !ok { + return nil, ds.ErrBatchUnsupported + } + + b, err := bds.Batch() + if err != nil { + return nil, err + } + return &syncBatch{ + batch: b, + mds: d, + }, nil +} + +func (d *MutexDatastore) Close() error { + d.RWMutex.Lock() + defer d.RWMutex.Unlock() + return d.child.Close() +} + +// DiskUsage implements the PersistentDatastore interface. +func (d *MutexDatastore) DiskUsage() (uint64, error) { + d.RLock() + defer d.RUnlock() + return ds.DiskUsage(d.child) +} + +type syncBatch struct { + batch ds.Batch + mds *MutexDatastore +} + +func (b *syncBatch) Put(key ds.Key, val []byte) error { + b.mds.Lock() + defer b.mds.Unlock() + return b.batch.Put(key, val) +} + +func (b *syncBatch) Delete(key ds.Key) error { + b.mds.Lock() + defer b.mds.Unlock() + return b.batch.Delete(key) +} + +func (b *syncBatch) Commit() error { + b.mds.Lock() + defer b.mds.Unlock() + return b.batch.Commit() +} + +func (d *MutexDatastore) Check() error { + if c, ok := d.child.(ds.CheckedDatastore); ok { + d.RWMutex.Lock() + defer d.RWMutex.Unlock() + return c.Check() + } + return nil +} + +func (d *MutexDatastore) Scrub() error { + if c, ok := d.child.(ds.ScrubbedDatastore); ok { + d.RWMutex.Lock() + defer d.RWMutex.Unlock() + return c.Scrub() + } + return nil +} + +func (d *MutexDatastore) CollectGarbage() error { + if c, ok := d.child.(ds.GCDatastore); ok { + d.RWMutex.Lock() + defer d.RWMutex.Unlock() + return c.CollectGarbage() + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ds-badger/.travis.yml b/vendor/github.com/ipfs/go-ds-badger/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ds-badger/LICENSE b/vendor/github.com/ipfs/go-ds-badger/LICENSE new file mode 100644 index 00000000..1e2cfe14 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 Łukasz Magiera + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/ipfs/go-ds-badger/Makefile b/vendor/github.com/ipfs/go-ds-badger/Makefile new file mode 100644 index 00000000..785abac8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/Makefile @@ -0,0 +1,14 @@ + +test: deps + go test -race -v ./... + +export IPFS_API ?= v04x.ipfs.io + +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + go get -t ./... diff --git a/vendor/github.com/ipfs/go-ds-badger/README.md b/vendor/github.com/ipfs/go-ds-badger/README.md new file mode 100644 index 00000000..b3e55c63 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/README.md @@ -0,0 +1,28 @@ +# go-ds-badger + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ds-badger?status.svg)](https://godoc.org/github.com/ipfs/go-ds-badger) +[![Build Status](https://travis-ci.org/ipfs/go-ds-badger.svg?branch=master)](https://travis-ci.org/ipfs/go-ds-badger) + +> Datastore implementation using [badger](https://github.com/dgraph-io/badger) as backend. + +## Documentation + +https://godoc.org/github.com/ipfs/go-ds-badger + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ds-badger/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT diff --git a/vendor/github.com/ipfs/go-ds-badger/codecov.yml b/vendor/github.com/ipfs/go-ds-badger/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-ds-badger/datastore.go b/vendor/github.com/ipfs/go-ds-badger/datastore.go new file mode 100644 index 00000000..8204e04e --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/datastore.go @@ -0,0 +1,608 @@ +package badger + +import ( + "errors" + "fmt" + "strings" + "sync" + "time" + + badger "github.com/dgraph-io/badger" + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" + logger "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" +) + +var log = logger.Logger("badger") + +var ErrClosed = errors.New("datastore closed") + +type Datastore struct { + DB *badger.DB + + closeLk sync.RWMutex + closed bool + closeOnce sync.Once + closing chan struct{} + + gcDiscardRatio float64 +} + +// Implements the datastore.Txn interface, enabling transaction support for +// the badger Datastore. +type txn struct { + ds *Datastore + txn *badger.Txn + + // Whether this transaction has been implicitly created as a result of a direct Datastore + // method invocation. + implicit bool +} + +// Options are the badger datastore options, reexported here for convenience. +type Options struct { + gcDiscardRatio float64 + + badger.Options +} + +// DefaultOptions are the default options for the badger datastore. +var DefaultOptions Options + +func init() { + DefaultOptions = Options{ + gcDiscardRatio: 0.1, + Options: badger.DefaultOptions, + } + DefaultOptions.Options.CompactL0OnClose = false + DefaultOptions.Options.Truncate = true +} + +var _ ds.Datastore = (*Datastore)(nil) +var _ ds.TxnDatastore = (*Datastore)(nil) +var _ ds.TTLDatastore = (*Datastore)(nil) + +// NewDatastore creates a new badger datastore. +// +// DO NOT set the Dir and/or ValuePath fields of opt, they will be set for you. +func NewDatastore(path string, options *Options) (*Datastore, error) { + // Copy the options because we modify them. + var opt badger.Options + var gcDiscardRatio float64 + if options == nil { + opt = badger.DefaultOptions + gcDiscardRatio = DefaultOptions.gcDiscardRatio + } else { + opt = options.Options + gcDiscardRatio = options.gcDiscardRatio + } + + opt.Dir = path + opt.ValueDir = path + opt.Logger = log + + kv, err := badger.Open(opt) + if err != nil { + if strings.HasPrefix(err.Error(), "manifest has unsupported version:") { + err = fmt.Errorf("unsupported badger version, use github.com/ipfs/badgerds-upgrade to upgrade: %s", err.Error()) + } + return nil, err + } + + return &Datastore{ + DB: kv, + closing: make(chan struct{}), + gcDiscardRatio: gcDiscardRatio, + }, nil +} + +// NewTransaction starts a new transaction. The resulting transaction object +// can be mutated without incurring changes to the underlying Datastore until +// the transaction is Committed. +func (d *Datastore) NewTransaction(readOnly bool) (ds.Txn, error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return nil, ErrClosed + } + + return &txn{d, d.DB.NewTransaction(!readOnly), false}, nil +} + +// newImplicitTransaction creates a transaction marked as 'implicit'. +// Implicit transactions are created by Datastore methods performing single operations. +func (d *Datastore) newImplicitTransaction(readOnly bool) *txn { + return &txn{d, d.DB.NewTransaction(!readOnly), true} +} + +func (d *Datastore) Put(key ds.Key, value []byte) error { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return ErrClosed + } + + txn := d.newImplicitTransaction(false) + defer txn.discard() + + if err := txn.put(key, value); err != nil { + return err + } + + return txn.commit() +} + +func (d *Datastore) PutWithTTL(key ds.Key, value []byte, ttl time.Duration) error { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return ErrClosed + } + + txn := d.newImplicitTransaction(false) + defer txn.discard() + + if err := txn.putWithTTL(key, value, ttl); err != nil { + return err + } + + return txn.commit() +} + +func (d *Datastore) SetTTL(key ds.Key, ttl time.Duration) error { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return ErrClosed + } + + txn := d.newImplicitTransaction(false) + defer txn.discard() + + if err := txn.setTTL(key, ttl); err != nil { + return err + } + + return txn.commit() +} + +func (d *Datastore) GetExpiration(key ds.Key) (time.Time, error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return time.Time{}, ErrClosed + } + + txn := d.newImplicitTransaction(false) + defer txn.discard() + + return txn.getExpiration(key) +} + +func (d *Datastore) Get(key ds.Key) (value []byte, err error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return nil, ErrClosed + } + + txn := d.newImplicitTransaction(true) + defer txn.discard() + + return txn.get(key) +} + +func (d *Datastore) Has(key ds.Key) (bool, error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return false, ErrClosed + } + + txn := d.newImplicitTransaction(true) + defer txn.discard() + + return txn.has(key) +} + +func (d *Datastore) GetSize(key ds.Key) (size int, err error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return -1, ErrClosed + } + + txn := d.newImplicitTransaction(true) + defer txn.discard() + + return txn.getSize(key) +} + +func (d *Datastore) Delete(key ds.Key) error { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + + txn := d.newImplicitTransaction(false) + defer txn.discard() + + err := txn.delete(key) + if err != nil { + return err + } + + return txn.commit() +} + +func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + + txn := d.newImplicitTransaction(true) + // We cannot defer txn.Discard() here, as the txn must remain active while the iterator is open. + // https://github.com/dgraph-io/badger/commit/b1ad1e93e483bbfef123793ceedc9a7e34b09f79 + // The closing logic in the query goprocess takes care of discarding the implicit transaction. + return txn.query(q) +} + +// DiskUsage implements the PersistentDatastore interface. +// It returns the sum of lsm and value log files sizes in bytes. +func (d *Datastore) DiskUsage() (uint64, error) { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return 0, ErrClosed + } + lsm, vlog := d.DB.Size() + return uint64(lsm + vlog), nil +} + +func (d *Datastore) Close() error { + d.closeOnce.Do(func() { + close(d.closing) + }) + d.closeLk.Lock() + defer d.closeLk.Unlock() + if d.closed { + return ErrClosed + } + d.closed = true + return d.DB.Close() +} + +func (d *Datastore) Batch() (ds.Batch, error) { + tx, _ := d.NewTransaction(false) + return tx, nil +} + +func (d *Datastore) CollectGarbage() error { + d.closeLk.RLock() + defer d.closeLk.RUnlock() + if d.closed { + return ErrClosed + } + + err := d.DB.RunValueLogGC(d.gcDiscardRatio) + if err == badger.ErrNoRewrite { + err = nil + } + return err +} + +var _ ds.Datastore = (*txn)(nil) +var _ ds.TTLDatastore = (*txn)(nil) + +func (t *txn) Put(key ds.Key, value []byte) error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + return t.put(key, value) +} + +func (t *txn) put(key ds.Key, value []byte) error { + return t.txn.Set(key.Bytes(), value) +} + +func (t *txn) PutWithTTL(key ds.Key, value []byte, ttl time.Duration) error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + return t.putWithTTL(key, value, ttl) +} + +func (t *txn) putWithTTL(key ds.Key, value []byte, ttl time.Duration) error { + return t.txn.SetWithTTL(key.Bytes(), value, ttl) +} + +func (t *txn) GetExpiration(key ds.Key) (time.Time, error) { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return time.Time{}, ErrClosed + } + + return t.getExpiration(key) +} + +func (t *txn) getExpiration(key ds.Key) (time.Time, error) { + item, err := t.txn.Get(key.Bytes()) + if err == badger.ErrKeyNotFound { + return time.Time{}, ds.ErrNotFound + } else if err != nil { + return time.Time{}, err + } + return time.Unix(int64(item.ExpiresAt()), 0), nil +} + +func (t *txn) SetTTL(key ds.Key, ttl time.Duration) error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + + return t.setTTL(key, ttl) +} + +func (t *txn) setTTL(key ds.Key, ttl time.Duration) error { + item, err := t.txn.Get(key.Bytes()) + if err != nil { + return err + } + return item.Value(func(data []byte) error { + return t.putWithTTL(key, data, ttl) + }) + +} + +func (t *txn) Get(key ds.Key) ([]byte, error) { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return nil, ErrClosed + } + + return t.get(key) +} + +func (t *txn) get(key ds.Key) ([]byte, error) { + item, err := t.txn.Get(key.Bytes()) + if err == badger.ErrKeyNotFound { + err = ds.ErrNotFound + } + if err != nil { + return nil, err + } + + return item.ValueCopy(nil) +} + +func (t *txn) Has(key ds.Key) (bool, error) { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return false, ErrClosed + } + + return t.has(key) +} + +func (t *txn) has(key ds.Key) (bool, error) { + _, err := t.txn.Get(key.Bytes()) + switch err { + case badger.ErrKeyNotFound: + return false, nil + case nil: + return true, nil + default: + return false, err + } +} + +func (t *txn) GetSize(key ds.Key) (int, error) { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return -1, ErrClosed + } + + return t.getSize(key) +} + +func (t *txn) getSize(key ds.Key) (int, error) { + item, err := t.txn.Get(key.Bytes()) + switch err { + case nil: + return int(item.ValueSize()), nil + case badger.ErrKeyNotFound: + return -1, ds.ErrNotFound + default: + return -1, err + } +} + +func (t *txn) Delete(key ds.Key) error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + + return t.delete(key) +} + +func (t *txn) delete(key ds.Key) error { + return t.txn.Delete(key.Bytes()) +} + +func (t *txn) Query(q dsq.Query) (dsq.Results, error) { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return nil, ErrClosed + } + + return t.query(q) +} + +func (t *txn) query(q dsq.Query) (dsq.Results, error) { + prefix := []byte(q.Prefix) + opt := badger.DefaultIteratorOptions + opt.PrefetchValues = !q.KeysOnly + + // Special case order by key. + orders := q.Orders + if len(orders) > 0 { + switch q.Orders[0].(type) { + case dsq.OrderByKey, *dsq.OrderByKey: + // Already ordered by key. + orders = nil + case dsq.OrderByKeyDescending, *dsq.OrderByKeyDescending: + orders = nil + opt.Reverse = true + } + } + + txn := t.txn + + it := txn.NewIterator(opt) + it.Seek(prefix) + + if q.Offset > 0 { + for j := 0; j < q.Offset; j++ { + it.Next() + } + } + + qrb := dsq.NewResultBuilder(q) + + qrb.Process.Go(func(worker goprocess.Process) { + t.ds.closeLk.RLock() + closedEarly := false + defer func() { + t.ds.closeLk.RUnlock() + if closedEarly { + select { + case qrb.Output <- dsq.Result{ + Error: ErrClosed, + }: + case <-qrb.Process.Closing(): + } + } + + }() + if t.ds.closed { + closedEarly = true + return + } + + // this iterator is part of an implicit transaction, so when + // we're done we must discard the transaction. It's safe to + // discard the txn it because it contains the iterator only. + if t.implicit { + defer t.discard() + } + + defer it.Close() + + for sent := 0; it.ValidForPrefix(prefix); sent++ { + if qrb.Query.Limit > 0 && sent >= qrb.Query.Limit { + break + } + + item := it.Item() + + k := string(item.Key()) + e := dsq.Entry{Key: k} + + var result dsq.Result + if !q.KeysOnly { + b, err := item.ValueCopy(nil) + if err != nil { + result = dsq.Result{Error: err} + } else { + e.Value = b + result = dsq.Result{Entry: e} + } + } else { + result = dsq.Result{Entry: e} + } + + if q.ReturnExpirations { + result.Expiration = time.Unix(int64(item.ExpiresAt()), 0) + } + + select { + case qrb.Output <- result: + case <-t.ds.closing: // datastore closing. + closedEarly = true + return + case <-worker.Closing(): // client told us to close early + return + } + + it.Next() + } + + return + }) + + go qrb.Process.CloseAfterChildren() + + // Now, apply remaining things (filters, order) + qr := qrb.Results() + for _, f := range q.Filters { + qr = dsq.NaiveFilter(qr, f) + } + if len(orders) > 0 { + qr = dsq.NaiveOrder(qr, orders...) + } + + return qr, nil +} + +func (t *txn) Commit() error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + + return t.commit() +} + +func (t *txn) commit() error { + return t.txn.Commit() +} + +// Alias to commit +func (t *txn) Close() error { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return ErrClosed + } + return t.close() +} + +func (t *txn) close() error { + return t.txn.Commit() +} + +func (t *txn) Discard() { + t.ds.closeLk.RLock() + defer t.ds.closeLk.RUnlock() + if t.ds.closed { + return + } + + t.discard() +} + +func (t *txn) discard() { + t.txn.Discard() +} diff --git a/vendor/github.com/ipfs/go-ds-badger/go.mod b/vendor/github.com/ipfs/go-ds-badger/go.mod new file mode 100644 index 00000000..b5ce2565 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/go.mod @@ -0,0 +1,13 @@ +module github.com/ipfs/go-ds-badger + +require ( + github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 // indirect + github.com/dgraph-io/badger v2.0.0-rc.2+incompatible + github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/golang/protobuf v1.3.0 // indirect + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 + github.com/pkg/errors v0.8.1 // indirect +) diff --git a/vendor/github.com/ipfs/go-ds-badger/go.sum b/vendor/github.com/ipfs/go-ds-badger/go.sum new file mode 100644 index 00000000..75c9054b --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/go.sum @@ -0,0 +1,62 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.4 h1:gVTrpUTbbr/T24uvoCaqY2KSHfNLVGm0w+hbee2HMeg= +github.com/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f h1:6itBiEUtu+gOzXZWn46bM5/qm8LlV6/byR7Yflx/y6M= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgraph-io/badger v2.0.0-rc.2+incompatible h1:7KPp6xv5+wymkVUbkAnZZXvmDrJlf09m/7u1HG5lAYA= +github.com/dgraph-io/badger v2.0.0-rc.2+incompatible/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f h1:dDxpBYafY/GYpcl+LS4Bn3ziLPuEdGRkRjYAbSlWxSA= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ds-badger/package.json b/vendor/github.com/ipfs/go-ds-badger/package.json new file mode 100644 index 00000000..cca00dee --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-badger/package.json @@ -0,0 +1,41 @@ +{ + "author": "magik6k", + "bugs": { + "url": "https://github.com/ipfs/go-ds-badger" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ds-badger" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP", + "name": "goprocess", + "version": "1.0.0" + }, + { + "author": "jbenet", + "hash": "QmUadX5EcvrBmxAV9sE7wUWtWSqxns5K84qKJBixmcT1w9", + "name": "go-datastore", + "version": "3.6.1" + }, + { + "author": "dgraph-io", + "hash": "QmU4emVTYFKnoJ5yK3pPEN9joyEx6U7y892PDx26ZtNxQd", + "name": "badger", + "version": "2.11.4" + }, + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + } + ], + "gxVersion": "0.8.0", + "language": "go", + "license": "", + "name": "go-ds-badger", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.12.4" +} + diff --git a/vendor/github.com/ipfs/go-ds-flatfs/.gitignore b/vendor/github.com/ipfs/go-ds-flatfs/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/ipfs/go-ds-flatfs/.travis.yml b/vendor/github.com/ipfs/go-ds-flatfs/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ds-flatfs/LICENSE b/vendor/github.com/ipfs/go-ds-flatfs/LICENSE new file mode 100644 index 00000000..f2049023 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ds-flatfs/Makefile b/vendor/github.com/ipfs/go-ds-flatfs/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/ipfs/go-ds-flatfs/README.md b/vendor/github.com/ipfs/go-ds-flatfs/README.md new file mode 100644 index 00000000..9f51bd58 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/README.md @@ -0,0 +1,92 @@ +# go-ds-flatfs + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ds-flatfs?status.svg)](https://godoc.org/github.com/ipfs/go-ds-flatfs) +[![Build Status](https://travis-ci.org/ipfs/go-ds-flatfs.svg?branch=master)](https://travis-ci.org/ipfs/go-ds-flatfs) +[![Coverage Status](https://img.shields.io/codecov/c/github/ipfs/go-ds-flatfs.svg)](https://codecov.io/gh/ipfs/go-ds-flatfs) + + +> A datastore implementation using sharded directories and flat files to store data + +`go-ds-flatfs` is used by `go-ipfs` to store raw block contents on disk. It supports several sharding functions (prefix, suffix, next-to-last/*). + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ds-flatfs` can be used like any Go module: + + +``` +import "github.com/ipfs/go-ds-flatfs" +``` + +`go-ds-flatfs` uses [`Gx`](https://github.com/whyrusleeping/gx) and [`Gx-go`](https://github.com/whyrusleeping/gx-go) to handle dependendencies. Run `make deps` to download and rewrite the imports to their fixed dependencies. + +## Usage + +Check the [GoDoc module documentation](https://godoc.org/github.com/ipfs/go-ds-flatfs) for an overview of this module's +functionality. + +### DiskUsage and Accuracy + +This datastore implements the [`PersistentDatastore`](https://godoc.org/github.com/ipfs/go-datastore#PersistentDatastore) interface. It offers a `DiskUsage()` method which strives to find a balance between accuracy and performance. This implies: + +* The total disk usage of a datastore is calculated when opening the datastore +* The current disk usage is cached frequently in a file in the datastore root (`diskUsage.cache` by default). This file is also +written when the datastore is closed. +* If this file is not present when the datastore is opened: + * The disk usage will be calculated by walking the datastore's directory tree and estimating the size of each folder. + * This may be a very slow operation for huge datastores or datastores with slow disks + * The operation is time-limited (5 minutes by default). + * Upon timeout, the remaining folders will be assumed to have the average of the previously processed ones. +* After opening, the disk usage is updated in every write/delete operation. + +This means that for certain datastores (huge ones, those with very slow disks or special content), the values reported by +`DiskUsage()` might be reduced accuracy and the first startup (without a `diskUsage.cache` file present), might be slow. + +If you need increased accuracy or a fast start from the first time, you can manually create or update the +`diskUsage.cache` file. + +The file `diskUsage.cache` is a JSON file with two fields `diskUsage` and `accuracy`. For example the JSON file for a +small repo might be: + +``` +{"diskUsage":6357,"accuracy":"initial-exact"} +``` + +`diskUsage` is the calculated disk usage and `accuracy` is a note on the accuracy of the initial calculation. If the +initial calculation was accurate the file will contain the value `initial-exact`. If some of the directories have too +many entries and the disk usage for that directory was estimated based on the first 2000 entries, the file will contain +`initial-approximate`. If the calculation took too long and timed out as indicated above, the file will contain +`initial-timed-out`. + +If the initial calculation timed out the JSON file might be: +``` +{"diskUsage":7589482442898,"accuracy":"initial-timed-out"} + +``` + +To fix this with a more accurate value you could do (in the datastore root): + + $ du -sb . + 7536515831332 . + $ echo -n '{"diskUsage":7536515831332,"accuracy":"initial-exact"}' > diskUsage.cache + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ds-flatfs/codecov.yml b/vendor/github.com/ipfs/go-ds-flatfs/codecov.yml new file mode 100644 index 00000000..db247200 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/codecov.yml @@ -0,0 +1 @@ +comment: off diff --git a/vendor/github.com/ipfs/go-ds-flatfs/convert.go b/vendor/github.com/ipfs/go-ds-flatfs/convert.go new file mode 100644 index 00000000..308a03a9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/convert.go @@ -0,0 +1,182 @@ +// Package flatfs is a Datastore implementation that stores all +// objects in a two-level directory structure in the local file +// system, regardless of the hierarchy of the keys. +package flatfs + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" +) + +func UpgradeV0toV1(path string, prefixLen int) error { + fun := Prefix(prefixLen) + err := WriteShardFunc(path, fun) + if err != nil { + return err + } + err = WriteReadme(path, fun) + if err != nil { + return err + } + return nil +} + +func DowngradeV1toV0(path string) error { + fun, err := ReadShardFunc(path) + if err != nil { + return err + } else if fun.funName != "prefix" { + return fmt.Errorf("%s: can only downgrade datastore that use the 'prefix' sharding function", path) + } + + err = os.Remove(filepath.Join(path, SHARDING_FN)) + if err != nil { + return err + } + err = os.Remove(filepath.Join(path, README_FN)) + if err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + +func Move(oldPath string, newPath string, out io.Writer) error { + oldDS, err := Open(oldPath, false) + if err != nil { + return fmt.Errorf("%s: %v", oldPath, err) + } + oldDS.deactivate() + newDS, err := Open(newPath, false) + if err != nil { + return fmt.Errorf("%s: %v", newPath, err) + } + newDS.deactivate() + + res, err := oldDS.Query(query.Query{KeysOnly: true}) + if err != nil { + return err + } + + if out != nil { + fmt.Fprintf(out, "Moving Keys...\n") + } + + // first move the keys + count := 0 + for { + e, ok := res.NextSync() + if !ok { + break + } + if e.Error != nil { + return e.Error + } + + err := moveKey(oldDS, newDS, datastore.RawKey(e.Key)) + if err != nil { + return err + } + + count++ + if out != nil && count%10 == 0 { + fmt.Fprintf(out, "\r%d keys so far", count) + } + } + + if out != nil { + fmt.Fprintf(out, "\nCleaning Up...\n") + } + + // now walk the old top-level directory + dir, err := os.Open(oldDS.path) + if err != nil { + return err + } + defer dir.Close() + names, err := dir.Readdirnames(-1) + if err != nil { + return err + } + for _, fn := range names { + if fn == "." || fn == ".." { + continue + } + oldPath := filepath.Join(oldDS.path, fn) + inf, err := os.Stat(oldPath) + if err != nil { + return err + } + if inf.IsDir() { + indir, err := os.Open(oldPath) + if err != nil { + return err + } + + names, err := indir.Readdirnames(-1) + indir.Close() + if err != nil { + return err + } + + for _, n := range names { + p := filepath.Join(oldPath, n) + // part of unfinished write transaction + // remove it + if strings.HasPrefix(n, "put-") { + err := os.Remove(p) + if err != nil { + return err + } + } else { + return errors.New("unknown file in flatfs: " + p) + } + } + + err = os.Remove(oldPath) + if err != nil { + return err + } + } else if fn == SHARDING_FN || fn == README_FN { + // generated file so just remove it + err := os.Remove(oldPath) + if err != nil { + return err + } + } else { + // else we found something unexpected, so to be safe just move it + log.Warningf("found unexpected file in datastore directory: \"%s\", moving anyway\n", fn) + newPath := filepath.Join(newDS.path, fn) + err := os.Rename(oldPath, newPath) + if err != nil { + return err + } + } + } + + if out != nil { + fmt.Fprintf(out, "All Done.\n") + } + + return nil +} + +func moveKey(oldDS *Datastore, newDS *Datastore, key datastore.Key) error { + _, oldPath := oldDS.encode(key) + dir, newPath := newDS.encode(key) + err := os.Mkdir(dir, 0755) + if err != nil && !os.IsExist(err) { + return err + } + err = os.Rename(oldPath, newPath) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ds-flatfs/flatfs.go b/vendor/github.com/ipfs/go-ds-flatfs/flatfs.go new file mode 100644 index 00000000..4afebabf --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/flatfs.go @@ -0,0 +1,1101 @@ +// Package flatfs is a Datastore implementation that stores all +// objects in a two-level directory structure in the local file +// system, regardless of the hierarchy of the keys. +package flatfs + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "math" + "math/rand" + "os" + "path/filepath" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + "github.com/jbenet/goprocess" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("flatfs") + +const ( + extension = ".data" + diskUsageMessageTimeout = 5 * time.Second + diskUsageCheckpointPercent = 1.0 + diskUsageCheckpointTimeout = 2 * time.Second +) + +var ( + // DiskUsageFile is the name of the file to cache the size of the + // datastore in disk + DiskUsageFile = "diskUsage.cache" + // DiskUsageFilesAverage is the maximum number of files per folder + // to stat in order to calculate the size of the datastore. + // The size of the rest of the files in a folder will be assumed + // to be the average of the values obtained. This includes + // regular files and directories. + DiskUsageFilesAverage = 2000 + // DiskUsageCalcTimeout is the maximum time to spend + // calculating the DiskUsage upon a start when no + // DiskUsageFile is present. + // If this period did not suffice to read the size of the datastore, + // the remaining sizes will be stimated. + DiskUsageCalcTimeout = 5 * time.Minute +) + +const ( + opPut = iota + opDelete + opRename +) + +type initAccuracy string + +const ( + unknownA initAccuracy = "unknown" + exactA initAccuracy = "initial-exact" + approxA initAccuracy = "initial-approximate" + timedoutA initAccuracy = "initial-timed-out" +) + +func combineAccuracy(a, b initAccuracy) initAccuracy { + if a == unknownA || b == unknownA { + return unknownA + } + if a == timedoutA || b == timedoutA { + return timedoutA + } + if a == approxA || b == approxA { + return approxA + } + if a == exactA && b == exactA { + return exactA + } + if a == "" { + return b + } + if b == "" { + return a + } + return unknownA +} + +var _ datastore.Datastore = (*Datastore)(nil) + +var ( + ErrDatastoreExists = errors.New("datastore already exists") + ErrDatastoreDoesNotExist = errors.New("datastore directory does not exist") + ErrShardingFileMissing = fmt.Errorf("%s file not found in datastore", SHARDING_FN) + ErrClosed = errors.New("datastore closed") +) + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + +// Datastore implements the go-datastore Interface. +// Note this datastore cannot guarantee order of concurrent +// write operations to the same key. See the explanation in +// Put(). +type Datastore struct { + // atmoic operations should always be used with diskUsage. + // Must be first in struct to ensure correct alignment + // (see https://golang.org/pkg/sync/atomic/#pkg-note-BUG) + diskUsage int64 + + path string + + shardStr string + getDir ShardFunc + + // sychronize all writes and directory changes for added safety + sync bool + + // these values should only be used during internalization or + // inside the checkpoint loop + dirty bool + storedValue diskUsageValue + + // Used to trigger a checkpoint. + checkpointCh chan struct{} + done chan struct{} + + shutdownLock sync.RWMutex + shutdown bool + + // opMap handles concurrent write operations (put/delete) + // to the same key + opMap *opMap +} + +type diskUsageValue struct { + DiskUsage int64 `json:"diskUsage"` + Accuracy initAccuracy `json:"accuracy"` +} + +type ShardFunc func(string) string + +type opT int + +// op wraps useful arguments of write operations +type op struct { + typ opT // operation type + key datastore.Key // datastore key. Mandatory. + tmp string // temp file path + path string // file path + v []byte // value +} + +type opMap struct { + ops sync.Map +} + +type opResult struct { + mu sync.RWMutex + success bool + + opMap *opMap + name string +} + +// Returns nil if there's nothing to do. +func (m *opMap) Begin(name string) *opResult { + for { + myOp := &opResult{opMap: m, name: name} + myOp.mu.Lock() + opIface, loaded := m.ops.LoadOrStore(name, myOp) + if !loaded { // no one else doing ops with this key + return myOp + } + + op := opIface.(*opResult) + // someone else doing ops with this key, wait for + // the result + op.mu.RLock() + if op.success { + return nil + } + + // if we are here, we will retry the operation + } +} + +func (o *opResult) Finish(ok bool) { + o.success = ok + o.opMap.ops.Delete(o.name) + o.mu.Unlock() +} + +func Create(path string, fun *ShardIdV1) error { + + err := os.Mkdir(path, 0755) + if err != nil && !os.IsExist(err) { + return err + } + + dsFun, err := ReadShardFunc(path) + switch err { + case ErrShardingFileMissing: + isEmpty, err := DirIsEmpty(path) + if err != nil { + return err + } + if !isEmpty { + return fmt.Errorf("directory missing %s file: %s", SHARDING_FN, path) + } + + err = WriteShardFunc(path, fun) + if err != nil { + return err + } + err = WriteReadme(path, fun) + return err + case nil: + if fun.String() != dsFun.String() { + return fmt.Errorf("specified shard func '%s' does not match repo shard func '%s'", + fun.String(), dsFun.String()) + } + return ErrDatastoreExists + default: + return err + } +} + +func Open(path string, syncFiles bool) (*Datastore, error) { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return nil, ErrDatastoreDoesNotExist + } else if err != nil { + return nil, err + } + + shardId, err := ReadShardFunc(path) + if err != nil { + return nil, err + } + + fs := &Datastore{ + path: path, + shardStr: shardId.String(), + getDir: shardId.Func(), + sync: syncFiles, + checkpointCh: make(chan struct{}, 1), + done: make(chan struct{}), + diskUsage: 0, + opMap: new(opMap), + } + + // This sets diskUsage to the correct value + // It might be slow, but allowing it to happen + // while the datastore is usable might + // cause diskUsage to not be accurate. + err = fs.calculateDiskUsage() + if err != nil { + // Cannot stat() all + // elements in the datastore. + return nil, err + } + + go fs.checkpointLoop() + return fs, nil +} + +// convenience method +func CreateOrOpen(path string, fun *ShardIdV1, sync bool) (*Datastore, error) { + err := Create(path, fun) + if err != nil && err != ErrDatastoreExists { + return nil, err + } + return Open(path, sync) +} + +func (fs *Datastore) ShardStr() string { + return fs.shardStr +} + +func (fs *Datastore) encode(key datastore.Key) (dir, file string) { + noslash := key.String()[1:] + dir = filepath.Join(fs.path, fs.getDir(noslash)) + file = filepath.Join(dir, noslash+extension) + return dir, file +} + +func (fs *Datastore) decode(file string) (key datastore.Key, ok bool) { + if filepath.Ext(file) != extension { + return datastore.Key{}, false + } + name := file[:len(file)-len(extension)] + return datastore.NewKey(name), true +} + +func (fs *Datastore) makeDir(dir string) error { + if err := fs.makeDirNoSync(dir); err != nil { + return err + } + + // In theory, if we create a new prefix dir and add a file to + // it, the creation of the prefix dir itself might not be + // durable yet. Sync the root dir after a successful mkdir of + // a prefix dir, just to be paranoid. + if fs.sync { + if err := syncDir(fs.path); err != nil { + return err + } + } + return nil +} + +func (fs *Datastore) makeDirNoSync(dir string) error { + if err := os.Mkdir(dir, 0755); err != nil { + // EEXIST is safe to ignore here, that just means the prefix + // directory already existed. + if !os.IsExist(err) { + return err + } + return nil + } + + // Track DiskUsage of this NEW folder + fs.updateDiskUsage(dir, true) + return nil +} + +// This function always runs under an opLock. Therefore, only one thread is +// touching the affected files. +func (fs *Datastore) renameAndUpdateDiskUsage(tmpPath, path string) error { + fi, err := os.Stat(path) + + // Destination exists, we need to discount it from diskUsage + if fs != nil && err == nil { + atomic.AddInt64(&fs.diskUsage, -fi.Size()) + } else if !os.IsNotExist(err) { + return err + } + + // Rename and add new file's diskUsage. If the rename fails, + // it will either a) Re-add the size of an existing file, which + // was sustracted before b) Add 0 if there is no existing file. + err = os.Rename(tmpPath, path) + fs.updateDiskUsage(path, true) + return err +} + +var putMaxRetries = 6 + +// Put stores a key/value in the datastore. +// +// Note, that we do not guarantee order of write operations (Put or Delete) +// to the same key in this datastore. +// +// For example. i.e. in the case of two concurrent Put, we only guarantee +// that one of them will come through, but cannot assure which one even if +// one arrived slightly later than the other. In the case of a +// concurrent Put and a Delete operation, we cannot guarantee which one +// will win. +func (fs *Datastore) Put(key datastore.Key, value []byte) error { + fs.shutdownLock.RLock() + defer fs.shutdownLock.RUnlock() + if fs.shutdown { + return ErrClosed + } + + var err error + for i := 1; i <= putMaxRetries; i++ { + err = fs.doWriteOp(&op{ + typ: opPut, + key: key, + v: value, + }) + if err == nil { + break + } + + if !strings.Contains(err.Error(), "too many open files") { + break + } + + log.Errorf("too many open files, retrying in %dms", 100*i) + time.Sleep(time.Millisecond * 100 * time.Duration(i)) + } + return err +} + +func (fs *Datastore) doOp(oper *op) error { + switch oper.typ { + case opPut: + return fs.doPut(oper.key, oper.v) + case opDelete: + return fs.doDelete(oper.key) + case opRename: + return fs.renameAndUpdateDiskUsage(oper.tmp, oper.path) + default: + panic("bad operation, this is a bug") + } +} + +// doWrite optmizes out write operations (put/delete) to the same +// key by queueing them and suceeding all queued +// operations if one of them does. In such case, +// we assume that the first suceeding operation +// on that key was the last one to happen after +// all successful others. +func (fs *Datastore) doWriteOp(oper *op) error { + keyStr := oper.key.String() + + opRes := fs.opMap.Begin(keyStr) + if opRes == nil { // nothing to do, a concurrent op succeeded + return nil + } + + // Do the operation + err := fs.doOp(oper) + + // Finish it. If no error, it will signal other operations + // waiting on this result to succeed. Otherwise, they will + // retry. + opRes.Finish(err == nil) + return err +} + +func (fs *Datastore) doPut(key datastore.Key, val []byte) error { + + dir, path := fs.encode(key) + if err := fs.makeDir(dir); err != nil { + return err + } + + tmp, err := ioutil.TempFile(dir, "put-") + if err != nil { + return err + } + closed := false + removed := false + defer func() { + if !closed { + // silence errcheck + _ = tmp.Close() + } + if !removed { + // silence errcheck + _ = os.Remove(tmp.Name()) + } + }() + + if _, err := tmp.Write(val); err != nil { + return err + } + if fs.sync { + if err := syncFile(tmp); err != nil { + return err + } + } + if err := tmp.Close(); err != nil { + return err + } + closed = true + + err = fs.renameAndUpdateDiskUsage(tmp.Name(), path) + if err != nil { + return err + } + removed = true + + if fs.sync { + if err := syncDir(dir); err != nil { + return err + } + } + return nil +} + +func (fs *Datastore) putMany(data map[datastore.Key][]byte) error { + fs.shutdownLock.RLock() + defer fs.shutdownLock.RUnlock() + if fs.shutdown { + return ErrClosed + } + + var dirsToSync []string + + files := make(map[*os.File]*op, len(data)) + ops := make(map[*os.File]int, len(data)) + + defer func() { + for fi := range files { + val, _ := ops[fi] + switch val { + case 0: + _ = fi.Close() + fallthrough + case 1: + _ = os.Remove(fi.Name()) + } + } + }() + + for key, value := range data { + dir, path := fs.encode(key) + if err := fs.makeDirNoSync(dir); err != nil { + return err + } + dirsToSync = append(dirsToSync, dir) + + tmp, err := ioutil.TempFile(dir, "put-") + if err != nil { + return err + } + + if _, err := tmp.Write(value); err != nil { + return err + } + + files[tmp] = &op{ + typ: opRename, + path: path, + tmp: tmp.Name(), + key: key, + } + } + + // Now we sync everything + // sync and close files + for fi := range files { + if fs.sync { + if err := syncFile(fi); err != nil { + return err + } + } + + if err := fi.Close(); err != nil { + return err + } + + // signify closed + ops[fi] = 1 + } + + // move files to their proper places + for fi, op := range files { + err := fs.doWriteOp(op) + if err != nil { + return err + } + // signify removed + ops[fi] = 2 + } + + // now sync the dirs for those files + if fs.sync { + for _, dir := range dirsToSync { + if err := syncDir(dir); err != nil { + return err + } + } + + // sync top flatfs dir + if err := syncDir(fs.path); err != nil { + return err + } + } + + return nil +} + +func (fs *Datastore) Get(key datastore.Key) (value []byte, err error) { + _, path := fs.encode(key) + data, err := ioutil.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return nil, datastore.ErrNotFound + } + // no specific error to return, so just pass it through + return nil, err + } + return data, nil +} + +func (fs *Datastore) Has(key datastore.Key) (exists bool, err error) { + _, path := fs.encode(key) + switch _, err := os.Stat(path); { + case err == nil: + return true, nil + case os.IsNotExist(err): + return false, nil + default: + return false, err + } +} + +func (fs *Datastore) GetSize(key datastore.Key) (size int, err error) { + _, path := fs.encode(key) + switch s, err := os.Stat(path); { + case err == nil: + return int(s.Size()), nil + case os.IsNotExist(err): + return -1, datastore.ErrNotFound + default: + return -1, err + } +} + +// Delete removes a key/value from the Datastore. Please read +// the Put() explanation about the handling of concurrent write +// operations to the same key. +func (fs *Datastore) Delete(key datastore.Key) error { + fs.shutdownLock.RLock() + defer fs.shutdownLock.RUnlock() + if fs.shutdown { + return ErrClosed + } + + return fs.doWriteOp(&op{ + typ: opDelete, + key: key, + v: nil, + }) +} + +// This function always runs within an opLock for the given +// key, and not concurrently. +func (fs *Datastore) doDelete(key datastore.Key) error { + _, path := fs.encode(key) + + fSize := fileSize(path) + + switch err := os.Remove(path); { + case err == nil: + atomic.AddInt64(&fs.diskUsage, -fSize) + fs.checkpointDiskUsage() + return nil + case os.IsNotExist(err): + return datastore.ErrNotFound + default: + return err + } +} + +func (fs *Datastore) Query(q query.Query) (query.Results, error) { + if (q.Prefix != "" && q.Prefix != "/") || + len(q.Filters) > 0 || + len(q.Orders) > 0 || + q.Limit > 0 || + q.Offset > 0 || + !q.KeysOnly { + // TODO this is overly simplistic, but the only caller is + // `ipfs refs local` for now, and this gets us moving. + return nil, errors.New("flatfs only supports listing all keys in random order") + } + + // Replicates the logic in ResultsWithChan but actually respects calls + // to `Close`. + b := query.NewResultBuilder(q) + b.Process.Go(func(p goprocess.Process) { + err := fs.walkTopLevel(fs.path, b) + if err == nil { + return + } + select { + case b.Output <- query.Result{Error: errors.New("walk failed: " + err.Error())}: + case <-p.Closing(): + } + }) + go b.Process.CloseAfterChildren() + + return b.Results(), nil +} + +func (fs *Datastore) walkTopLevel(path string, result *query.ResultBuilder) error { + dir, err := os.Open(path) + if err != nil { + return err + } + defer dir.Close() + names, err := dir.Readdirnames(-1) + if err != nil { + return err + } + for _, dir := range names { + if len(dir) == 0 || dir[0] == '.' { + continue + } + + err = fs.walk(filepath.Join(path, dir), result) + if err != nil { + return err + } + + // Are we closing? + select { + case <-result.Process.Closing(): + return nil + default: + } + } + return nil +} + +// folderSize estimates the diskUsage of a folder by reading +// up to DiskUsageFilesAverage entries in it and assumming any +// other files will have an avereage size. +func folderSize(path string, deadline time.Time) (int64, initAccuracy, error) { + var du int64 + + folder, err := os.Open(path) + if err != nil { + return 0, "", err + } + defer folder.Close() + + stat, err := folder.Stat() + if err != nil { + return 0, "", err + } + + files, err := folder.Readdirnames(-1) + if err != nil { + return 0, "", err + } + + totalFiles := len(files) + i := 0 + filesProcessed := 0 + maxFiles := DiskUsageFilesAverage + if maxFiles <= 0 { + maxFiles = totalFiles + } + + // randomize file order + // https://stackoverflow.com/a/42776696 + for i := len(files) - 1; i > 0; i-- { + j := rand.Intn(i + 1) + files[i], files[j] = files[j], files[i] + } + + accuracy := exactA + for { + // Do not process any files after deadline is over + if time.Now().After(deadline) { + accuracy = timedoutA + break + } + + if i >= totalFiles || filesProcessed >= maxFiles { + if filesProcessed >= maxFiles { + accuracy = approxA + } + break + } + + // Stat the file + fname := files[i] + subpath := filepath.Join(path, fname) + st, err := os.Stat(subpath) + if err != nil { + return 0, "", err + } + + // Find folder size recursively + if st.IsDir() { + du2, acc, err := folderSize(filepath.Join(subpath), deadline) + if err != nil { + return 0, "", err + } + accuracy = combineAccuracy(acc, accuracy) + du += du2 + filesProcessed++ + } else { // in any other case, add the file size + du += st.Size() + filesProcessed++ + } + + i++ + } + + nonProcessed := totalFiles - filesProcessed + + // Avg is total size in this folder up to now / total files processed + // it includes folders ant not folders + avg := 0.0 + if filesProcessed > 0 { + avg = float64(du) / float64(filesProcessed) + } + duEstimation := int64(avg * float64(nonProcessed)) + du += duEstimation + du += stat.Size() + //fmt.Println(path, "total:", totalFiles, "totalStat:", i, "totalFile:", filesProcessed, "left:", nonProcessed, "avg:", int(avg), "est:", int(duEstimation), "du:", du) + return du, accuracy, nil +} + +// calculateDiskUsage tries to read the DiskUsageFile for a cached +// diskUsage value, otherwise walks the datastore files. +// it is only safe to call in Open() +func (fs *Datastore) calculateDiskUsage() error { + // Try to obtain a previously stored value from disk + if persDu := fs.readDiskUsageFile(); persDu > 0 { + fs.diskUsage = persDu + return nil + } + + msgDone := make(chan struct{}, 1) // prevent race condition + msgTimer := time.AfterFunc(diskUsageMessageTimeout, func() { + fmt.Printf("Calculating datastore size. This might take %s at most and will happen only once\n", + DiskUsageCalcTimeout.String()) + msgDone <- struct{}{} + }) + defer msgTimer.Stop() + deadline := time.Now().Add(DiskUsageCalcTimeout) + du, accuracy, err := folderSize(fs.path, deadline) + if err != nil { + return err + } + if !msgTimer.Stop() { + <-msgDone + } + if accuracy == timedoutA { + fmt.Println("WARN: It took to long to calculate the datastore size") + fmt.Printf("WARN: The total size (%d) is an estimation. You can fix errors by\n", du) + fmt.Printf("WARN: replacing the %s file with the right disk usage in bytes and\n", + filepath.Join(fs.path, DiskUsageFile)) + fmt.Println("WARN: re-opening the datastore") + } + + fs.storedValue.Accuracy = accuracy + fs.diskUsage = du + fs.writeDiskUsageFile(du, true) + + return nil +} + +func fileSize(path string) int64 { + fi, err := os.Stat(path) + if err != nil { + return 0 + } + return fi.Size() +} + +// updateDiskUsage reads the size of path and atomically +// increases or decreases the diskUsage variable. +// setting add to false will subtract from disk usage. +func (fs *Datastore) updateDiskUsage(path string, add bool) { + fsize := fileSize(path) + if !add { + fsize = -fsize + } + + if fsize != 0 { + atomic.AddInt64(&fs.diskUsage, fsize) + fs.checkpointDiskUsage() + } +} + +func (fs *Datastore) checkpointDiskUsage() { + select { + case fs.checkpointCh <- struct{}{}: + // msg sent + default: + // checkpoint request already pending + } +} + +func (fs *Datastore) checkpointLoop() { + defer close(fs.done) + + timerActive := true + timer := time.NewTimer(0) + defer timer.Stop() + for { + select { + case _, more := <-fs.checkpointCh: + du := atomic.LoadInt64(&fs.diskUsage) + fs.dirty = true + if !more { // shutting down + fs.writeDiskUsageFile(du, true) + if fs.dirty { + log.Errorf("could not store final value of disk usage to file, future estimates may be inaccurate") + } + return + } + // If the difference between the checkpointed disk usage and + // current one is larger than than `diskUsageCheckpointPercent` + // of the checkpointed: store it. + newDu := float64(du) + lastCheckpointDu := float64(fs.storedValue.DiskUsage) + diff := math.Abs(newDu - lastCheckpointDu) + if lastCheckpointDu*diskUsageCheckpointPercent < diff*100.0 { + fs.writeDiskUsageFile(du, false) + } + // Otherwise insure the value will be written to disk after + // `diskUsageCheckpointTimeout` + if fs.dirty && !timerActive { + timer.Reset(diskUsageCheckpointTimeout) + timerActive = true + } + case <-timer.C: + timerActive = false + if fs.dirty { + du := atomic.LoadInt64(&fs.diskUsage) + fs.writeDiskUsageFile(du, false) + } + } + } +} + +func (fs *Datastore) writeDiskUsageFile(du int64, doSync bool) { + tmp, err := ioutil.TempFile(fs.path, "du-") + if err != nil { + log.Warningf("cound not write disk usage: %v", err) + return + } + + removed := false + defer func() { + if !removed { + // silence errcheck + _ = os.Remove(tmp.Name()) + } + }() + + toWrite := fs.storedValue + toWrite.DiskUsage = du + encoder := json.NewEncoder(tmp) + if err := encoder.Encode(&toWrite); err != nil { + log.Warningf("cound not write disk usage: %v", err) + return + } + + if doSync { + if err := tmp.Sync(); err != nil { + log.Warningf("cound not sync %s: %v", DiskUsageFile, err) + return + } + } + + if err := tmp.Close(); err != nil { + log.Warningf("cound not write disk usage: %v", err) + return + } + + if err := os.Rename(tmp.Name(), filepath.Join(fs.path, DiskUsageFile)); err != nil { + log.Warningf("cound not write disk usage: %v", err) + return + } + removed = true + + fs.storedValue = toWrite + fs.dirty = false +} + +// readDiskUsageFile is only safe to call in Open() +func (fs *Datastore) readDiskUsageFile() int64 { + fpath := filepath.Join(fs.path, DiskUsageFile) + duB, err := ioutil.ReadFile(fpath) + if err != nil { + return 0 + } + err = json.Unmarshal(duB, &fs.storedValue) + if err != nil { + return 0 + } + return fs.storedValue.DiskUsage +} + +// DiskUsage implements the PersistentDatastore interface +// and returns the current disk usage in bytes used by +// this datastore. +// +// The size is approximative and may slightly differ from +// the real disk values. +func (fs *Datastore) DiskUsage() (uint64, error) { + // it may differ from real disk values if + // the filesystem has allocated for blocks + // for a directory because it has many files in it + // we don't account for "resized" directories. + // In a large datastore, the differences should be + // are negligible though. + + du := atomic.LoadInt64(&fs.diskUsage) + return uint64(du), nil +} + +// Accuracy returns a string representing the accuracy of the +// DiskUsage() result, the value returned is implementation defined +// and for informational purposes only +func (fs *Datastore) Accuracy() string { + return string(fs.storedValue.Accuracy) +} + +func (fs *Datastore) walk(path string, result *query.ResultBuilder) error { + dir, err := os.Open(path) + if err != nil { + if os.IsNotExist(err) { + // not an error if the file disappeared + return nil + } + return err + } + defer dir.Close() + + // ignore non-directories + fileInfo, err := dir.Stat() + if err != nil { + return err + } + if !fileInfo.IsDir() { + return nil + } + + names, err := dir.Readdirnames(-1) + if err != nil { + return err + } + for _, fn := range names { + + if len(fn) == 0 || fn[0] == '.' { + continue + } + + key, ok := fs.decode(fn) + if !ok { + log.Warningf("failed to decode flatfs entry: %s", fn) + continue + } + + select { + case result.Output <- query.Result{ + Entry: query.Entry{ + Key: key.String(), + }, + }: + case <-result.Process.Closing(): + return nil + } + } + return nil +} + +// Deactivate closes background maintenance threads, most write +// operations will fail but readonly operations will continue to +// function +func (fs *Datastore) deactivate() error { + fs.shutdownLock.Lock() + defer fs.shutdownLock.Unlock() + if fs.shutdown { + return nil + } + fs.shutdown = true + close(fs.checkpointCh) + <-fs.done + return nil +} + +func (fs *Datastore) Close() error { + return fs.deactivate() +} + +type flatfsBatch struct { + puts map[datastore.Key][]byte + deletes map[datastore.Key]struct{} + + ds *Datastore +} + +func (fs *Datastore) Batch() (datastore.Batch, error) { + return &flatfsBatch{ + puts: make(map[datastore.Key][]byte), + deletes: make(map[datastore.Key]struct{}), + ds: fs, + }, nil +} + +func (bt *flatfsBatch) Put(key datastore.Key, val []byte) error { + bt.puts[key] = val + return nil +} + +func (bt *flatfsBatch) Delete(key datastore.Key) error { + bt.deletes[key] = struct{}{} + return nil +} + +func (bt *flatfsBatch) Commit() error { + if err := bt.ds.putMany(bt.puts); err != nil { + return err + } + + for k, _ := range bt.deletes { + if err := bt.ds.Delete(k); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/ipfs/go-ds-flatfs/go.mod b/vendor/github.com/ipfs/go-ds-flatfs/go.mod new file mode 100644 index 00000000..f2a9e266 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-ds-flatfs + +require ( + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 +) diff --git a/vendor/github.com/ipfs/go-ds-flatfs/go.sum b/vendor/github.com/ipfs/go-ds-flatfs/go.sum new file mode 100644 index 00000000..c5e35f8a --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/go.sum @@ -0,0 +1,42 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ds-flatfs/package.json b/vendor/github.com/ipfs/go-ds-flatfs/package.json new file mode 100644 index 00000000..e8bd0dbd --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/package.json @@ -0,0 +1,35 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/ipfs/go-ds-flatfs" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ds-flatfs" + }, + "gxDependencies": [ + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "jbenet", + "hash": "QmUadX5EcvrBmxAV9sE7wUWtWSqxns5K84qKJBixmcT1w9", + "name": "go-datastore", + "version": "3.6.1" + }, + { + "author": "whyrusleeping", + "hash": "QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP", + "name": "goprocess", + "version": "1.0.0" + } + ], + "gxVersion": "0.8.0", + "language": "go", + "license": "", + "name": "go-ds-flatfs", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.3.7" +} + diff --git a/vendor/github.com/ipfs/go-ds-flatfs/readme.go b/vendor/github.com/ipfs/go-ds-flatfs/readme.go new file mode 100644 index 00000000..9c1065bd --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/readme.go @@ -0,0 +1,33 @@ +package flatfs + +var README_IPFS_DEF_SHARD = `This is a repository of IPLD objects. Each IPLD object is in a single file, +named .data. Where is the +"base32" encoding of the CID (as specified in +https://github.com/multiformats/multibase) without the 'B' prefix. +All the object files are placed in a tree of directories, based on a +function of the CID. This is a form of sharding similar to +the objects directory in git repositories. Previously, we used +prefixes, we now use the next-to-last two charters. + + func NextToLast(base32cid string) { + nextToLastLen := 2 + offset := len(base32cid) - nextToLastLen - 1 + return str[offset : offset+nextToLastLen] + } + +For example, an object with a base58 CIDv1 of + + zb2rhYSxw4ZjuzgCnWSt19Q94ERaeFhu9uSqRgjSdx9bsgM6f + +has a base32 CIDv1 of + + BAFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA + +and will be placed at + + SC/AFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA.data + +with 'SC' being the last-to-next two characters and the 'B' at the +beginning of the CIDv1 string is the multibase prefix that is not +stored in the filename. +` diff --git a/vendor/github.com/ipfs/go-ds-flatfs/shard.go b/vendor/github.com/ipfs/go-ds-flatfs/shard.go new file mode 100644 index 00000000..acfa4505 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/shard.go @@ -0,0 +1,145 @@ +package flatfs + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" +) + +var IPFS_DEF_SHARD = NextToLast(2) +var IPFS_DEF_SHARD_STR = IPFS_DEF_SHARD.String() + +const PREFIX = "/repo/flatfs/shard/" + +const SHARDING_FN = "SHARDING" +const README_FN = "_README" + +type ShardIdV1 struct { + funName string + param int + fun ShardFunc +} + +func (f *ShardIdV1) String() string { + return fmt.Sprintf("%sv1/%s/%d", PREFIX, f.funName, f.param) +} + +func (f *ShardIdV1) Func() ShardFunc { + return f.fun +} + +func Prefix(prefixLen int) *ShardIdV1 { + padding := strings.Repeat("_", prefixLen) + return &ShardIdV1{ + funName: "prefix", + param: prefixLen, + fun: func(noslash string) string { + return (noslash + padding)[:prefixLen] + }, + } +} + +func Suffix(suffixLen int) *ShardIdV1 { + padding := strings.Repeat("_", suffixLen) + return &ShardIdV1{ + funName: "suffix", + param: suffixLen, + fun: func(noslash string) string { + str := padding + noslash + return str[len(str)-suffixLen:] + }, + } +} + +func NextToLast(suffixLen int) *ShardIdV1 { + padding := strings.Repeat("_", suffixLen+1) + return &ShardIdV1{ + funName: "next-to-last", + param: suffixLen, + fun: func(noslash string) string { + str := padding + noslash + offset := len(str) - suffixLen - 1 + return str[offset : offset+suffixLen] + }, + } +} + +func ParseShardFunc(str string) (*ShardIdV1, error) { + str = strings.TrimSpace(str) + + if len(str) == 0 { + return nil, fmt.Errorf("empty shard identifier") + } + + trimmed := strings.TrimPrefix(str, PREFIX) + if str == trimmed { // nothing trimmed + return nil, fmt.Errorf("invalid or no prefix in shard identifier: %s", str) + } + str = trimmed + + parts := strings.Split(str, "/") + if len(parts) != 3 { + return nil, fmt.Errorf("invalid shard identifier: %s", str) + } + + version := parts[0] + if version != "v1" { + return nil, fmt.Errorf("expected 'v1' for version string got: %s\n", version) + } + + funName := parts[1] + + param, err := strconv.Atoi(parts[2]) + if err != nil { + return nil, fmt.Errorf("invalid parameter: %v", err) + } + + switch funName { + case "prefix": + return Prefix(param), nil + case "suffix": + return Suffix(param), nil + case "next-to-last": + return NextToLast(param), nil + default: + return nil, fmt.Errorf("expected 'prefix', 'suffix' or 'next-to-last' got: %s", funName) + } + +} + +func ReadShardFunc(dir string) (*ShardIdV1, error) { + buf, err := ioutil.ReadFile(filepath.Join(dir, SHARDING_FN)) + if os.IsNotExist(err) { + return nil, ErrShardingFileMissing + } else if err != nil { + return nil, err + } + return ParseShardFunc(string(buf)) +} + +func WriteShardFunc(dir string, id *ShardIdV1) error { + file, err := os.OpenFile(filepath.Join(dir, SHARDING_FN), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + return err + } + defer file.Close() + _, err = file.WriteString(id.String()) + if err != nil { + return err + } + _, err = file.WriteString("\n") + return err +} + +func WriteReadme(dir string, id *ShardIdV1) error { + if id.String() == IPFS_DEF_SHARD.String() { + err := ioutil.WriteFile(filepath.Join(dir, README_FN), []byte(README_IPFS_DEF_SHARD), 0444) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ds-flatfs/sync.go b/vendor/github.com/ipfs/go-ds-flatfs/sync.go new file mode 100644 index 00000000..bf38c16f --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/sync.go @@ -0,0 +1,42 @@ +package flatfs + +import ( + "os" + "runtime" +) + +// don't block more than 16 threads on sync opearation +// 16 should be able to sataurate most RAIDs +// in case of two used disks per write (RAID 1, 5) and queue depth of 2, +// 16 concurrent Sync calls should be able to saturate 16 HDDs RAID +//TODO: benchmark it out, maybe provide tweak parmeter +const SyncThreadsMax = 16 + +var syncSemaphore chan struct{} = make(chan struct{}, SyncThreadsMax) + +func syncDir(dir string) error { + if runtime.GOOS == "windows" { + // dir sync on windows doesn't work: https://git.io/vPnCI + return nil + } + + dirF, err := os.Open(dir) + if err != nil { + return err + } + defer dirF.Close() + + syncSemaphore <- struct{}{} + defer func() { <-syncSemaphore }() + + if err := dirF.Sync(); err != nil { + return err + } + return nil +} + +func syncFile(file *os.File) error { + syncSemaphore <- struct{}{} + defer func() { <-syncSemaphore }() + return file.Sync() +} diff --git a/vendor/github.com/ipfs/go-ds-flatfs/util.go b/vendor/github.com/ipfs/go-ds-flatfs/util.go new file mode 100644 index 00000000..31ebde05 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-flatfs/util.go @@ -0,0 +1,21 @@ +package flatfs + +import ( + "io" + "os" +) + +// From: http://stackoverflow.com/questions/30697324/how-to-check-if-directory-on-path-is-empty +func DirIsEmpty(name string) (bool, error) { + f, err := os.Open(name) + if err != nil { + return false, err + } + defer f.Close() + + _, err = f.Readdirnames(1) // Or f.Readdir(1) + if err == io.EOF { + return true, nil + } + return false, err // Either not empty or error, suits both cases +} diff --git a/vendor/github.com/ipfs/go-ds-leveldb/.gitignore b/vendor/github.com/ipfs/go-ds-leveldb/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/ipfs/go-ds-leveldb/.travis.yml b/vendor/github.com/ipfs/go-ds-leveldb/.travis.yml new file mode 100644 index 00000000..b86c124d --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race -cpu=5" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ds-leveldb/LICENSE b/vendor/github.com/ipfs/go-ds-leveldb/LICENSE new file mode 100644 index 00000000..6152c321 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ds-leveldb/Makefile b/vendor/github.com/ipfs/go-ds-leveldb/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/ipfs/go-ds-leveldb/README.md b/vendor/github.com/ipfs/go-ds-leveldb/README.md new file mode 100644 index 00000000..53515c2f --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/README.md @@ -0,0 +1,47 @@ +# go-ds-leveldb + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ds-leveldb?status.svg)](https://godoc.org/github.com/ipfs/go-ds-leveldb) +[![Build Status](https://travis-ci.org/ipfs/go-ds-leveldb.svg?branch=master)](https://travis-ci.org/ipfs/go-ds-leveldb) + +> A go-datastore implementation using LevelDB + +`go-ds-leveldb` implements the [go-datastore](https://github.com/ipfs/go-datastore) interface using a LevelDB backend. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +This module can be installed like a regular go module: + +``` +go get github.com/ipfs/go-ds-leveldb +``` + +It uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make deps` to rewrite imports to the gx-specified versions. + +## Usage + +``` +import "github.com/ipfs/go-ds-leveldb" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ds-leveldb) + + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ds-leveldb/datastore.go b/vendor/github.com/ipfs/go-ds-leveldb/datastore.go new file mode 100644 index 00000000..1b2df122 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/datastore.go @@ -0,0 +1,239 @@ +package leveldb + +import ( + "os" + "path/filepath" + + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/util" +) + +type Datastore struct { + *accessor + DB *leveldb.DB + path string +} + +var _ ds.Datastore = (*Datastore)(nil) +var _ ds.TxnDatastore = (*Datastore)(nil) + +// Options is an alias of syndtr/goleveldb/opt.Options which might be extended +// in the future. +type Options opt.Options + +// NewDatastore returns a new datastore backed by leveldb +// +// for path == "", an in memory bachend will be chosen +func NewDatastore(path string, opts *Options) (*Datastore, error) { + var nopts opt.Options + if opts != nil { + nopts = opt.Options(*opts) + } + + var err error + var db *leveldb.DB + + if path == "" { + db, err = leveldb.Open(storage.NewMemStorage(), &nopts) + } else { + db, err = leveldb.OpenFile(path, &nopts) + if errors.IsCorrupted(err) && !nopts.GetReadOnly() { + db, err = leveldb.RecoverFile(path, &nopts) + } + } + + if err != nil { + return nil, err + } + + return &Datastore{ + accessor: &accessor{ldb: db}, + DB: db, + path: path, + }, nil +} + +// An extraction of the common interface between LevelDB Transactions and the DB itself. +// +// It allows to plug in either inside the `accessor`. +type levelDbOps interface { + Put(key, value []byte, wo *opt.WriteOptions) error + Get(key []byte, ro *opt.ReadOptions) (value []byte, err error) + Has(key []byte, ro *opt.ReadOptions) (ret bool, err error) + Delete(key []byte, wo *opt.WriteOptions) error + NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator +} + +// Datastore operations using either the DB or a transaction as the backend. +type accessor struct { + ldb levelDbOps +} + +func (a *accessor) Put(key ds.Key, value []byte) (err error) { + return a.ldb.Put(key.Bytes(), value, nil) +} + +func (a *accessor) Get(key ds.Key) (value []byte, err error) { + val, err := a.ldb.Get(key.Bytes(), nil) + if err != nil { + if err == leveldb.ErrNotFound { + return nil, ds.ErrNotFound + } + return nil, err + } + return val, nil +} + +func (a *accessor) Has(key ds.Key) (exists bool, err error) { + return a.ldb.Has(key.Bytes(), nil) +} + +func (d *accessor) GetSize(key ds.Key) (size int, err error) { + return ds.GetBackedSize(d, key) +} + +func (a *accessor) Delete(key ds.Key) (err error) { + // leveldb Delete will not return an error if the key doesn't + // exist (see https://github.com/syndtr/goleveldb/issues/109), + // so check that the key exists first and if not return an + // error + exists, err := a.ldb.Has(key.Bytes(), nil) + if !exists { + return ds.ErrNotFound + } else if err != nil { + return err + } + return a.ldb.Delete(key.Bytes(), nil) +} + +func (a *accessor) Query(q dsq.Query) (dsq.Results, error) { + var rnge *util.Range + + // make a copy of the query for the fallback naive query implementation. + // don't modify the original so res.Query() returns the correct results. + qNaive := q + if q.Prefix != "" { + rnge = util.BytesPrefix([]byte(q.Prefix)) + qNaive.Prefix = "" + } + i := a.ldb.NewIterator(rnge, nil) + next := i.Next + if len(q.Orders) > 0 { + switch q.Orders[0].(type) { + case dsq.OrderByKey, *dsq.OrderByKey: + qNaive.Orders = nil + case dsq.OrderByKeyDescending, *dsq.OrderByKeyDescending: + next = func() bool { + next = i.Prev + return i.Last() + } + qNaive.Orders = nil + default: + } + } + r := dsq.ResultsFromIterator(q, dsq.Iterator{ + Next: func() (dsq.Result, bool) { + if !next() { + return dsq.Result{}, false + } + k := string(i.Key()) + e := dsq.Entry{Key: k} + + if !q.KeysOnly { + buf := make([]byte, len(i.Value())) + copy(buf, i.Value()) + e.Value = buf + } + return dsq.Result{Entry: e}, true + }, + Close: func() error { + i.Release() + return nil + }, + }) + return dsq.NaiveQueryApply(qNaive, r), nil +} + +// DiskUsage returns the current disk size used by this levelDB. +// For in-mem datastores, it will return 0. +func (d *Datastore) DiskUsage() (uint64, error) { + if d.path == "" { // in-mem + return 0, nil + } + + var du uint64 + + err := filepath.Walk(d.path, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + du += uint64(info.Size()) + return nil + }) + + if err != nil { + return 0, err + } + + return du, nil +} + +// LevelDB needs to be closed. +func (d *Datastore) Close() (err error) { + return d.DB.Close() +} + +type leveldbBatch struct { + b *leveldb.Batch + db *leveldb.DB +} + +func (d *Datastore) Batch() (ds.Batch, error) { + return &leveldbBatch{ + b: new(leveldb.Batch), + db: d.DB, + }, nil +} + +func (b *leveldbBatch) Put(key ds.Key, value []byte) error { + b.b.Put(key.Bytes(), value) + return nil +} + +func (b *leveldbBatch) Commit() error { + return b.db.Write(b.b, nil) +} + +func (b *leveldbBatch) Delete(key ds.Key) error { + b.b.Delete(key.Bytes()) + return nil +} + +// A leveldb transaction embedding the accessor backed by the transaction. +type transaction struct { + *accessor + tx *leveldb.Transaction +} + +func (t *transaction) Commit() error { + return t.tx.Commit() +} + +func (t *transaction) Discard() { + t.tx.Discard() +} + +func (d *Datastore) NewTransaction(readOnly bool) (ds.Txn, error) { + tx, err := d.DB.OpenTransaction() + if err != nil { + return nil, err + } + accessor := &accessor{tx} + return &transaction{accessor, tx}, nil +} diff --git a/vendor/github.com/ipfs/go-ds-leveldb/go.mod b/vendor/github.com/ipfs/go-ds-leveldb/go.mod new file mode 100644 index 00000000..d26e1c18 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-ds-leveldb + +require ( + github.com/ipfs/go-datastore v0.0.3 + github.com/syndtr/goleveldb v1.0.0 +) diff --git a/vendor/github.com/ipfs/go-ds-leveldb/go.sum b/vendor/github.com/ipfs/go-ds-leveldb/go.sum new file mode 100644 index 00000000..d6ecf9b4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-leveldb/go.sum @@ -0,0 +1,46 @@ +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-datastore v0.0.3 h1:/eP3nMDmLzMJNoWSSYvEkmMTTrm9FFCN+JraP9NdlwU= +github.com/ipfs/go-datastore v0.0.3/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-ds-measure/.gitignore b/vendor/github.com/ipfs/go-ds-measure/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/ipfs/go-ds-measure/.travis.yml b/vendor/github.com/ipfs/go-ds-measure/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ds-measure/LICENSE b/vendor/github.com/ipfs/go-ds-measure/LICENSE new file mode 100644 index 00000000..f2049023 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ds-measure/Makefile b/vendor/github.com/ipfs/go-ds-measure/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/ipfs/go-ds-measure/go.mod b/vendor/github.com/ipfs/go-ds-measure/go.mod new file mode 100644 index 00000000..701ed5c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-ds-measure + +require ( + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-metrics-interface v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ds-measure/go.sum b/vendor/github.com/ipfs/go-ds-measure/go.sum new file mode 100644 index 00000000..fb24202d --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/go.sum @@ -0,0 +1,18 @@ +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ds-measure/measure.go b/vendor/github.com/ipfs/go-ds-measure/measure.go new file mode 100644 index 00000000..c8e83f38 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/measure.go @@ -0,0 +1,332 @@ +// Package measure provides a Datastore wrapper that records metrics +// using github.com/ipfs/go-metrics-interface +package measure + +import ( + "io" + "time" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + "github.com/ipfs/go-metrics-interface" +) + +var ( + // sort latencies in buckets with following upper bounds in seconds + datastoreLatencyBuckets = []float64{1e-4, 1e-3, 1e-2, 1e-1, 1} + + // sort sizes in buckets with following upper bounds in bytes + datastoreSizeBuckets = []float64{1 << 6, 1 << 12, 1 << 18, 1 << 24} +) + +// New wraps the datastore, providing metrics on the operations. The +// metrics are registered with names starting with prefix and a dot. +func New(prefix string, ds datastore.Datastore) *measure { + m := &measure{ + backend: ds, + + putNum: metrics.New(prefix+".put_total", "Total number of Datastore.Put calls").Counter(), + putErr: metrics.New(prefix+".put.errors_total", "Number of errored Datastore.Put calls").Counter(), + putLatency: metrics.New(prefix+".put.latency_seconds", + "Latency distribution of Datastore.Put calls").Histogram(datastoreLatencyBuckets), + putSize: metrics.New(prefix+".put.size_bytes", + "Size distribution of stored byte slices").Histogram(datastoreSizeBuckets), + + getNum: metrics.New(prefix+".get_total", "Total number of Datastore.Get calls").Counter(), + getErr: metrics.New(prefix+".get.errors_total", "Number of errored Datastore.Get calls").Counter(), + getLatency: metrics.New(prefix+".get.latency_seconds", + "Latency distribution of Datastore.Get calls").Histogram(datastoreLatencyBuckets), + getSize: metrics.New(prefix+".get.size_bytes", + "Size distribution of retrieved byte slices").Histogram(datastoreSizeBuckets), + + hasNum: metrics.New(prefix+".has_total", "Total number of Datastore.Has calls").Counter(), + hasErr: metrics.New(prefix+".has.errors_total", "Number of errored Datastore.Has calls").Counter(), + hasLatency: metrics.New(prefix+".has.latency_seconds", + "Latency distribution of Datastore.Has calls").Histogram(datastoreLatencyBuckets), + getsizeNum: metrics.New(prefix+".getsize_total", "Total number of Datastore.GetSize calls").Counter(), + getsizeErr: metrics.New(prefix+".getsize.errors_total", "Number of errored Datastore.GetSize calls").Counter(), + getsizeLatency: metrics.New(prefix+".getsize.latency_seconds", + "Latency distribution of Datastore.GetSize calls").Histogram(datastoreLatencyBuckets), + + deleteNum: metrics.New(prefix+".delete_total", "Total number of Datastore.Delete calls").Counter(), + deleteErr: metrics.New(prefix+".delete.errors_total", "Number of errored Datastore.Delete calls").Counter(), + deleteLatency: metrics.New(prefix+".delete.latency_seconds", + "Latency distribution of Datastore.Delete calls").Histogram(datastoreLatencyBuckets), + + queryNum: metrics.New(prefix+".query_total", "Total number of Datastore.Query calls").Counter(), + queryErr: metrics.New(prefix+".query.errors_total", "Number of errored Datastore.Query calls").Counter(), + queryLatency: metrics.New(prefix+".query.latency_seconds", + "Latency distribution of Datastore.Query calls").Histogram(datastoreLatencyBuckets), + + checkNum: metrics.New(prefix+".check_total", "Total number of Datastore.Check calls").Counter(), + checkErr: metrics.New(prefix+".check.errors_total", "Number of errored Datastore.Check calls").Counter(), + checkLatency: metrics.New(prefix+".check.latency_seconds", + "Latency distribution of Datastore.Check calls").Histogram(datastoreLatencyBuckets), + + scrubNum: metrics.New(prefix+".scrub_total", "Total number of Datastore.Scrub calls").Counter(), + scrubErr: metrics.New(prefix+".scrub.errors_total", "Number of errored Datastore.Scrub calls").Counter(), + scrubLatency: metrics.New(prefix+".scrub.latency_seconds", + "Latency distribution of Datastore.Scrub calls").Histogram(datastoreLatencyBuckets), + + gcNum: metrics.New(prefix+".gc_total", "Total number of Datastore.CollectGarbage calls").Counter(), + gcErr: metrics.New(prefix+".gc.errors_total", "Number of errored Datastore.CollectGarbage calls").Counter(), + gcLatency: metrics.New(prefix+".gc.latency_seconds", + "Latency distribution of Datastore.CollectGarbage calls").Histogram(datastoreLatencyBuckets), + + duNum: metrics.New(prefix+".du_total", "Total number of Datastore.DiskUsage calls").Counter(), + duErr: metrics.New(prefix+".du.errors_total", "Number of errored Datastore.DiskUsage calls").Counter(), + duLatency: metrics.New(prefix+".du.latency_seconds", + "Latency distribution of Datastore.DiskUsage calls").Histogram(datastoreLatencyBuckets), + } + return m +} + +type measure struct { + backend datastore.Datastore + + putNum metrics.Counter + putErr metrics.Counter + putLatency metrics.Histogram + putSize metrics.Histogram + + getNum metrics.Counter + getErr metrics.Counter + getLatency metrics.Histogram + getSize metrics.Histogram + + hasNum metrics.Counter + hasErr metrics.Counter + hasLatency metrics.Histogram + + getsizeNum metrics.Counter + getsizeErr metrics.Counter + getsizeLatency metrics.Histogram + + deleteNum metrics.Counter + deleteErr metrics.Counter + deleteLatency metrics.Histogram + + queryNum metrics.Counter + queryErr metrics.Counter + queryLatency metrics.Histogram + + checkNum metrics.Counter + checkErr metrics.Counter + checkLatency metrics.Histogram + + scrubNum metrics.Counter + scrubErr metrics.Counter + scrubLatency metrics.Histogram + + gcNum metrics.Counter + gcErr metrics.Counter + gcLatency metrics.Histogram + + duNum metrics.Counter + duErr metrics.Counter + duLatency metrics.Histogram +} + +func recordLatency(h metrics.Histogram, start time.Time) { + elapsed := time.Since(start) + h.Observe(elapsed.Seconds()) +} + +func (m *measure) Put(key datastore.Key, value []byte) error { + defer recordLatency(m.putLatency, time.Now()) + m.putNum.Inc() + m.putSize.Observe(float64(len(value))) + err := m.backend.Put(key, value) + if err != nil { + m.putErr.Inc() + } + return err +} + +func (m *measure) Get(key datastore.Key) (value []byte, err error) { + defer recordLatency(m.getLatency, time.Now()) + m.getNum.Inc() + value, err = m.backend.Get(key) + switch err { + case nil: + m.getSize.Observe(float64(len(value))) + case datastore.ErrNotFound: + // Not really an error. + default: + m.getErr.Inc() + } + return value, err +} + +func (m *measure) Has(key datastore.Key) (exists bool, err error) { + defer recordLatency(m.hasLatency, time.Now()) + m.hasNum.Inc() + exists, err = m.backend.Has(key) + if err != nil { + m.hasErr.Inc() + } + return exists, err +} + +func (m *measure) GetSize(key datastore.Key) (size int, err error) { + defer recordLatency(m.getsizeLatency, time.Now()) + m.hasNum.Inc() + size, err = m.backend.GetSize(key) + switch err { + case nil, datastore.ErrNotFound: + default: + m.getsizeErr.Inc() + } + return size, err +} + +func (m *measure) Delete(key datastore.Key) error { + defer recordLatency(m.deleteLatency, time.Now()) + m.deleteNum.Inc() + err := m.backend.Delete(key) + if err != nil { + m.deleteErr.Inc() + } + return err +} + +func (m *measure) Query(q query.Query) (query.Results, error) { + defer recordLatency(m.queryLatency, time.Now()) + m.queryNum.Inc() + res, err := m.backend.Query(q) + if err != nil { + m.queryErr.Inc() + } + return res, err +} + +func (m *measure) Check() error { + defer recordLatency(m.checkLatency, time.Now()) + m.checkNum.Inc() + if c, ok := m.backend.(datastore.CheckedDatastore); ok { + err := c.Check() + if err != nil { + m.checkErr.Inc() + } + return err + } + return nil +} + +func (m *measure) Scrub() error { + defer recordLatency(m.scrubLatency, time.Now()) + m.scrubNum.Inc() + if c, ok := m.backend.(datastore.ScrubbedDatastore); ok { + err := c.Scrub() + if err != nil { + m.scrubErr.Inc() + } + return err + } + return nil +} + +func (m *measure) CollectGarbage() error { + defer recordLatency(m.gcLatency, time.Now()) + m.gcNum.Inc() + if c, ok := m.backend.(datastore.GCDatastore); ok { + err := c.CollectGarbage() + if err != nil { + m.gcErr.Inc() + } + return err + } + return nil +} + +func (m *measure) DiskUsage() (uint64, error) { + defer recordLatency(m.duLatency, time.Now()) + m.duNum.Inc() + size, err := datastore.DiskUsage(m.backend) + if err != nil { + m.duErr.Inc() + } + return size, err +} + +type measuredBatch struct { + puts int + deletes int + + putts datastore.Batch + delts datastore.Batch + + m *measure +} + +func (m *measure) Batch() (datastore.Batch, error) { + bds, ok := m.backend.(datastore.Batching) + if !ok { + return nil, datastore.ErrBatchUnsupported + } + pb, err := bds.Batch() + if err != nil { + return nil, err + } + + db, err := bds.Batch() + if err != nil { + return nil, err + } + + return &measuredBatch{ + putts: pb, + delts: db, + + m: m, + }, nil +} + +func (mt *measuredBatch) Put(key datastore.Key, val []byte) error { + mt.puts++ + mt.m.putSize.Observe(float64(len(val))) + return mt.putts.Put(key, val) +} + +func (mt *measuredBatch) Delete(key datastore.Key) error { + mt.deletes++ + return mt.delts.Delete(key) +} + +func (mt *measuredBatch) Commit() error { + err := logBatchCommit(mt.delts, mt.deletes, mt.m.deleteNum, mt.m.deleteErr, mt.m.deleteLatency) + if err != nil { + return err + } + + err = logBatchCommit(mt.putts, mt.puts, mt.m.putNum, mt.m.putErr, mt.m.putLatency) + if err != nil { + return err + } + + return nil +} + +func logBatchCommit(b datastore.Batch, n int, num, errs metrics.Counter, lat metrics.Histogram) error { + if n > 0 { + before := time.Now() + err := b.Commit() + took := time.Since(before) / time.Duration(n) + num.Add(float64(n)) + for i := 0; i < n; i++ { + lat.Observe(took.Seconds()) + } + if err != nil { + errs.Inc() + return err + } + } + return nil +} + +func (m *measure) Close() error { + if c, ok := m.backend.(io.Closer); ok { + return c.Close() + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ds-measure/package.json b/vendor/github.com/ipfs/go-ds-measure/package.json new file mode 100644 index 00000000..9d31f488 --- /dev/null +++ b/vendor/github.com/ipfs/go-ds-measure/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/ipfs/go-ds-measure" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ds-measure" + }, + "gxDependencies": [ + { + "author": "ipfs", + "hash": "QmekzFM3hPZjTjUFGTABdQkEnQ3PTiMstY198PwSFr5w1Q", + "name": "go-metrics-interface", + "version": "0.2.0" + }, + { + "author": "jbenet", + "hash": "QmUadX5EcvrBmxAV9sE7wUWtWSqxns5K84qKJBixmcT1w9", + "name": "go-datastore", + "version": "3.6.1" + } + ], + "gxVersion": "0.8.0", + "language": "go", + "license": "", + "name": "go-ds-measure", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.4.5" +} + diff --git a/vendor/github.com/ipfs/go-fs-lock/.gitignore b/vendor/github.com/ipfs/go-fs-lock/.gitignore new file mode 100644 index 00000000..fcd2aa0d --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/.gitignore @@ -0,0 +1,6 @@ +*.swp +*.out +*.coverprofile +*.test +*.orig +*~ diff --git a/vendor/github.com/ipfs/go-fs-lock/.travis.yml b/vendor/github.com/ipfs/go-fs-lock/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-fs-lock/LICENSE b/vendor/github.com/ipfs/go-fs-lock/LICENSE new file mode 100644 index 00000000..79bd9c59 --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-fs-lock/README.md b/vendor/github.com/ipfs/go-fs-lock/README.md new file mode 100644 index 00000000..adc6c63f --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/README.md @@ -0,0 +1,66 @@ +# go-fs-lock + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-fs-lock?status.svg)](https://godoc.org/github.com/ipfs/go-fs-lock) +[![Coverage Status](https://coveralls.io/repos/github/ipfs/go-fs-lock/badge.svg?branch=master)](https://coveralls.io/github/ipfs/go-fs-lock?branch=master) +[![Travis CI](https://travis-ci.org/ipfs/go-fs-lock.svg?branch=master)](https://travis-ci.org/ipfs/go-fs-lock) + +> Filesystem based locking + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-fs-lock` is a standard Go module which can be installed with: + +```sh +go get github.com/ipfs/go-fs-lock +``` + +Note that `go-fs-lock` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section). + +## Usage + +### Using Gx and Gx-go + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/ipfs/go-fs-lock +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +### Running tests + +Before running tests, please run: + +```sh +make deps +``` + +This will make sure that dependencies are rewritten to known working versions. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-fs-lock/fslock.go b/vendor/github.com/ipfs/go-fs-lock/fslock.go new file mode 100644 index 00000000..4b33acb5 --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/fslock.go @@ -0,0 +1,76 @@ +package fslock + +import ( + "fmt" + "io" + "os" + "path" + "strings" + "syscall" + + "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" + lock "go4.org/lock" +) + +// log is the fsrepo logger +var log = logging.Logger("lock") + +func errPerm(path string) error { + return fmt.Errorf("failed to take lock at %s: permission denied", path) +} + +// Lock creates the lock. +func Lock(confdir, lockFile string) (io.Closer, error) { + return lock.Lock(path.Join(confdir, lockFile)) +} + +// Locked checks if there is a lock already set. +func Locked(confdir, lockFile string) (bool, error) { + log.Debugf("Checking lock") + if !util.FileExists(path.Join(confdir, lockFile)) { + log.Debugf("File doesn't exist: %s", path.Join(confdir, lockFile)) + return false, nil + } + + lk, err := Lock(confdir, lockFile) + if err != nil { + // EAGAIN == someone else has the lock + if err == syscall.EAGAIN { + log.Debugf("Someone else has the lock: %s", path.Join(confdir, lockFile)) + return true, nil + } + if strings.Contains(err.Error(), "resource temporarily unavailable") { + log.Debugf("Can't lock file: %s.\n reason: %s", path.Join(confdir, lockFile), err.Error()) + return true, nil + } + + // we hold the lock ourselves + if strings.Contains(err.Error(), "already locked") { + log.Debugf("Lock is already held by us: %s", path.Join(confdir, lockFile)) + return true, nil + } + + // lock fails on permissions error + if os.IsPermission(err) { + log.Debugf("Lock fails on permissions error") + return false, errPerm(confdir) + } + if isLockCreatePermFail(err) { + log.Debugf("Lock fails on permissions error") + return false, errPerm(confdir) + } + + // otherwise, we cant guarantee anything, error out + return false, err + } + + log.Debugf("No one has a lock") + lk.Close() + return false, nil +} + +func isLockCreatePermFail(err error) bool { + s := err.Error() + return strings.Contains(s, "Lock Create of") && strings.Contains(s, "permission denied") +} diff --git a/vendor/github.com/ipfs/go-fs-lock/go.mod b/vendor/github.com/ipfs/go-fs-lock/go.mod new file mode 100644 index 00000000..8b3764e9 --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-fs-lock + +require ( + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + go4.org v0.0.0-20190218023631-ce4c26f7be8e +) diff --git a/vendor/github.com/ipfs/go-fs-lock/go.sum b/vendor/github.com/ipfs/go-fs-lock/go.sum new file mode 100644 index 00000000..f08985a5 --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/go.sum @@ -0,0 +1,45 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +go4.org v0.0.0-20190218023631-ce4c26f7be8e h1:m9LfARr2VIOW0vsV19kEKp/sWQvZnGobA8JHui/XJoY= +go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/ipfs/go-fs-lock/package.json b/vendor/github.com/ipfs/go-fs-lock/package.json new file mode 100644 index 00000000..9000978e --- /dev/null +++ b/vendor/github.com/ipfs/go-fs-lock/package.json @@ -0,0 +1,35 @@ +{ + "author": "dignifiedquire", + "bugs": { + "url": "https://github.com/ipfs/go-fs-lock/issues" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-fs-lock" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + }, + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "hsanjuan", + "hash": "QmYDxsntDcWC7CTisDmeorEvDVjkRAjjY9Vr9DJ6HSkXMS", + "name": "go4-lock", + "version": "0.0.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-fs-lock", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.11" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/.travis.yml b/vendor/github.com/ipfs/go-ipfs-blockstore/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/LICENSE b/vendor/github.com/ipfs/go-ipfs-blockstore/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/Makefile b/vendor/github.com/ipfs/go-ipfs-blockstore/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/README.md b/vendor/github.com/ipfs/go-ipfs-blockstore/README.md new file mode 100644 index 00000000..446a95e2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/README.md @@ -0,0 +1,44 @@ +# go-ipfs-blockstore + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-blockstore?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-blockstore) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-blockstore.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-blockstore) + +> go-ipfs-blockstore implements a thin wrapper over a datastore, giving a clean interface for Getting and Putting block objects. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-blockstore` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-blockstore +``` + +## Usage + +``` +import "github.com/ipfs/go-ipfs-blockstore" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-blockstore) + +This module uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies. + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/arc_cache.go b/vendor/github.com/ipfs/go-ipfs-blockstore/arc_cache.go new file mode 100644 index 00000000..231fd855 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/arc_cache.go @@ -0,0 +1,182 @@ +package blockstore + +import ( + "context" + + lru "github.com/hashicorp/golang-lru" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + metrics "github.com/ipfs/go-metrics-interface" +) + +type cacheHave bool +type cacheSize int + +// arccache wraps a BlockStore with an Adaptive Replacement Cache (ARC) for +// block Cids. This provides block access-time improvements, allowing +// to short-cut many searches without query-ing the underlying datastore. +type arccache struct { + arc *lru.ARCCache + blockstore Blockstore + + hits metrics.Counter + total metrics.Counter +} + +func newARCCachedBS(ctx context.Context, bs Blockstore, lruSize int) (*arccache, error) { + arc, err := lru.NewARC(lruSize) + if err != nil { + return nil, err + } + c := &arccache{arc: arc, blockstore: bs} + c.hits = metrics.NewCtx(ctx, "arc.hits_total", "Number of ARC cache hits").Counter() + c.total = metrics.NewCtx(ctx, "arc_total", "Total number of ARC cache requests").Counter() + + return c, nil +} + +func (b *arccache) DeleteBlock(k cid.Cid) error { + if has, _, ok := b.hasCached(k); ok && !has { + return ErrNotFound + } + + b.arc.Remove(k) // Invalidate cache before deleting. + err := b.blockstore.DeleteBlock(k) + switch err { + case nil, ErrNotFound: + b.cacheHave(k, false) + return err + default: + return err + } +} + +// if ok == false has is inconclusive +// if ok == true then has respons to question: is it contained +func (b *arccache) hasCached(k cid.Cid) (has bool, size int, ok bool) { + b.total.Inc() + if !k.Defined() { + log.Error("undefined cid in arccache") + // Return cache invalid so the call to blockstore happens + // in case of invalid key and correct error is created. + return false, -1, false + } + + h, ok := b.arc.Get(k.KeyString()) + if ok { + b.hits.Inc() + switch h := h.(type) { + case cacheHave: + return bool(h), -1, true + case cacheSize: + return true, int(h), true + } + } + return false, -1, false +} + +func (b *arccache) Has(k cid.Cid) (bool, error) { + if has, _, ok := b.hasCached(k); ok { + return has, nil + } + has, err := b.blockstore.Has(k) + if err != nil { + return false, err + } + b.cacheHave(k, has) + return has, nil +} + +func (b *arccache) GetSize(k cid.Cid) (int, error) { + if has, blockSize, ok := b.hasCached(k); ok { + if has { + return blockSize, nil + } + return -1, ErrNotFound + } + blockSize, err := b.blockstore.GetSize(k) + if err == ErrNotFound { + b.cacheHave(k, false) + } else if err == nil { + b.cacheSize(k, blockSize) + } + return blockSize, err +} + +func (b *arccache) Get(k cid.Cid) (blocks.Block, error) { + if !k.Defined() { + log.Error("undefined cid in arc cache") + return nil, ErrNotFound + } + + if has, _, ok := b.hasCached(k); ok && !has { + return nil, ErrNotFound + } + + bl, err := b.blockstore.Get(k) + if bl == nil && err == ErrNotFound { + b.cacheHave(k, false) + } else if bl != nil { + b.cacheSize(k, len(bl.RawData())) + } + return bl, err +} + +func (b *arccache) Put(bl blocks.Block) error { + if has, _, ok := b.hasCached(bl.Cid()); ok && has { + return nil + } + + err := b.blockstore.Put(bl) + if err == nil { + b.cacheSize(bl.Cid(), len(bl.RawData())) + } + return err +} + +func (b *arccache) PutMany(bs []blocks.Block) error { + var good []blocks.Block + for _, block := range bs { + // call put on block if result is inconclusive or we are sure that + // the block isn't in storage + if has, _, ok := b.hasCached(block.Cid()); !ok || (ok && !has) { + good = append(good, block) + } + } + err := b.blockstore.PutMany(good) + if err != nil { + return err + } + for _, block := range good { + b.cacheSize(block.Cid(), len(block.RawData())) + } + return nil +} + +func (b *arccache) HashOnRead(enabled bool) { + b.blockstore.HashOnRead(enabled) +} + +func (b *arccache) cacheHave(c cid.Cid, have bool) { + b.arc.Add(c.KeyString(), cacheHave(have)) +} + +func (b *arccache) cacheSize(c cid.Cid, blockSize int) { + b.arc.Add(c.KeyString(), cacheSize(blockSize)) +} + +func (b *arccache) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + return b.blockstore.AllKeysChan(ctx) +} + +func (b *arccache) GCLock() Unlocker { + return b.blockstore.(GCBlockstore).GCLock() +} + +func (b *arccache) PinLock() Unlocker { + return b.blockstore.(GCBlockstore).PinLock() +} + +func (b *arccache) GCRequested() bool { + return b.blockstore.(GCBlockstore).GCRequested() +} diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/blockstore.go b/vendor/github.com/ipfs/go-ipfs-blockstore/blockstore.go new file mode 100644 index 00000000..f57a90af --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/blockstore.go @@ -0,0 +1,284 @@ +// Package blockstore implements a thin wrapper over a datastore, giving a +// clean interface for Getting and Putting block objects. +package blockstore + +import ( + "context" + "errors" + "sync" + "sync/atomic" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + dsns "github.com/ipfs/go-datastore/namespace" + dsq "github.com/ipfs/go-datastore/query" + dshelp "github.com/ipfs/go-ipfs-ds-help" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("blockstore") + +// BlockPrefix namespaces blockstore datastores +var BlockPrefix = ds.NewKey("blocks") + +// ErrHashMismatch is an error returned when the hash of a block +// is different than expected. +var ErrHashMismatch = errors.New("block in storage has different hash than requested") + +// ErrNotFound is an error returned when a block is not found. +var ErrNotFound = errors.New("blockstore: block not found") + +// Blockstore wraps a Datastore block-centered methods and provides a layer +// of abstraction which allows to add different caching strategies. +type Blockstore interface { + DeleteBlock(cid.Cid) error + Has(cid.Cid) (bool, error) + Get(cid.Cid) (blocks.Block, error) + + // GetSize returns the CIDs mapped BlockSize + GetSize(cid.Cid) (int, error) + + // Put puts a given block to the underlying datastore + Put(blocks.Block) error + + // PutMany puts a slice of blocks at the same time using batching + // capabilities of the underlying datastore whenever possible. + PutMany([]blocks.Block) error + + // AllKeysChan returns a channel from which + // the CIDs in the Blockstore can be read. It should respect + // the given context, closing the channel if it becomes Done. + AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) + + // HashOnRead specifies if every read block should be + // rehashed to make sure it matches its CID. + HashOnRead(enabled bool) +} + +// GCLocker abstract functionality to lock a blockstore when performing +// garbage-collection operations. +type GCLocker interface { + // GCLock locks the blockstore for garbage collection. No operations + // that expect to finish with a pin should ocurr simultaneously. + // Reading during GC is safe, and requires no lock. + GCLock() Unlocker + + // PinLock locks the blockstore for sequences of puts expected to finish + // with a pin (before GC). Multiple put->pin sequences can write through + // at the same time, but no GC should happen simulatenously. + // Reading during Pinning is safe, and requires no lock. + PinLock() Unlocker + + // GcRequested returns true if GCLock has been called and is waiting to + // take the lock + GCRequested() bool +} + +// GCBlockstore is a blockstore that can safely run garbage-collection +// operations. +type GCBlockstore interface { + Blockstore + GCLocker +} + +// NewGCBlockstore returns a default implementation of GCBlockstore +// using the given Blockstore and GCLocker. +func NewGCBlockstore(bs Blockstore, gcl GCLocker) GCBlockstore { + return gcBlockstore{bs, gcl} +} + +type gcBlockstore struct { + Blockstore + GCLocker +} + +// NewBlockstore returns a default Blockstore implementation +// using the provided datastore.Batching backend. +func NewBlockstore(d ds.Batching) Blockstore { + var dsb ds.Batching + dd := dsns.Wrap(d, BlockPrefix) + dsb = dd + return &blockstore{ + datastore: dsb, + } +} + +type blockstore struct { + datastore ds.Batching + + rehash bool +} + +func (bs *blockstore) HashOnRead(enabled bool) { + bs.rehash = enabled +} + +func (bs *blockstore) Get(k cid.Cid) (blocks.Block, error) { + if !k.Defined() { + log.Error("undefined cid in blockstore") + return nil, ErrNotFound + } + + bdata, err := bs.datastore.Get(dshelp.CidToDsKey(k)) + if err == ds.ErrNotFound { + return nil, ErrNotFound + } + if err != nil { + return nil, err + } + if bs.rehash { + rbcid, err := k.Prefix().Sum(bdata) + if err != nil { + return nil, err + } + + if !rbcid.Equals(k) { + return nil, ErrHashMismatch + } + + return blocks.NewBlockWithCid(bdata, rbcid) + } + return blocks.NewBlockWithCid(bdata, k) +} + +func (bs *blockstore) Put(block blocks.Block) error { + k := dshelp.CidToDsKey(block.Cid()) + + // Has is cheaper than Put, so see if we already have it + exists, err := bs.datastore.Has(k) + if err == nil && exists { + return nil // already stored. + } + return bs.datastore.Put(k, block.RawData()) +} + +func (bs *blockstore) PutMany(blocks []blocks.Block) error { + t, err := bs.datastore.Batch() + if err != nil { + return err + } + for _, b := range blocks { + k := dshelp.CidToDsKey(b.Cid()) + exists, err := bs.datastore.Has(k) + if err == nil && exists { + continue + } + + err = t.Put(k, b.RawData()) + if err != nil { + return err + } + } + return t.Commit() +} + +func (bs *blockstore) Has(k cid.Cid) (bool, error) { + return bs.datastore.Has(dshelp.CidToDsKey(k)) +} + +func (bs *blockstore) GetSize(k cid.Cid) (int, error) { + size, err := bs.datastore.GetSize(dshelp.CidToDsKey(k)) + if err == ds.ErrNotFound { + return -1, ErrNotFound + } + return size, err +} + +func (bs *blockstore) DeleteBlock(k cid.Cid) error { + err := bs.datastore.Delete(dshelp.CidToDsKey(k)) + if err == ds.ErrNotFound { + return ErrNotFound + } + return err +} + +// AllKeysChan runs a query for keys from the blockstore. +// this is very simplistic, in the future, take dsq.Query as a param? +// +// AllKeysChan respects context. +func (bs *blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + + // KeysOnly, because that would be _a lot_ of data. + q := dsq.Query{KeysOnly: true} + res, err := bs.datastore.Query(q) + if err != nil { + return nil, err + } + + output := make(chan cid.Cid, dsq.KeysOnlyBufSize) + go func() { + defer func() { + res.Close() // ensure exit (signals early exit, too) + close(output) + }() + + for { + e, ok := res.NextSync() + if !ok { + return + } + if e.Error != nil { + log.Errorf("blockstore.AllKeysChan got err: %s", e.Error) + return + } + + // need to convert to key.Key using key.KeyFromDsKey. + k, err := dshelp.DsKeyToCid(ds.RawKey(e.Key)) + if err != nil { + log.Warningf("error parsing key from DsKey: %s", err) + continue + } + + select { + case <-ctx.Done(): + return + case output <- k: + } + } + }() + + return output, nil +} + +// NewGCLocker returns a default implementation of +// GCLocker using standard [RW] mutexes. +func NewGCLocker() GCLocker { + return &gclocker{} +} + +type gclocker struct { + lk sync.RWMutex + gcreq int32 +} + +// Unlocker represents an object which can Unlock +// something. +type Unlocker interface { + Unlock() +} + +type unlocker struct { + unlock func() +} + +func (u *unlocker) Unlock() { + u.unlock() + u.unlock = nil // ensure its not called twice +} + +func (bs *gclocker) GCLock() Unlocker { + atomic.AddInt32(&bs.gcreq, 1) + bs.lk.Lock() + atomic.AddInt32(&bs.gcreq, -1) + return &unlocker{bs.lk.Unlock} +} + +func (bs *gclocker) PinLock() Unlocker { + bs.lk.RLock() + return &unlocker{bs.lk.RUnlock} +} + +func (bs *gclocker) GCRequested() bool { + return atomic.LoadInt32(&bs.gcreq) > 0 +} diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/bloom_cache.go b/vendor/github.com/ipfs/go-ipfs-blockstore/bloom_cache.go new file mode 100644 index 00000000..3720d20d --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/bloom_cache.go @@ -0,0 +1,204 @@ +package blockstore + +import ( + "context" + "fmt" + "sync/atomic" + "time" + + bloom "github.com/ipfs/bbloom" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + metrics "github.com/ipfs/go-metrics-interface" +) + +// bloomCached returns a Blockstore that caches Has requests using a Bloom +// filter. bloomSize is size of bloom filter in bytes. hashCount specifies the +// number of hashing functions in the bloom filter (usually known as k). +func bloomCached(ctx context.Context, bs Blockstore, bloomSize, hashCount int) (*bloomcache, error) { + bl, err := bloom.New(float64(bloomSize), float64(hashCount)) + if err != nil { + return nil, err + } + bc := &bloomcache{ + blockstore: bs, + bloom: bl, + hits: metrics.NewCtx(ctx, "bloom.hits_total", + "Number of cache hits in bloom cache").Counter(), + total: metrics.NewCtx(ctx, "bloom_total", + "Total number of requests to bloom cache").Counter(), + buildChan: make(chan struct{}), + } + go func() { + err := bc.build(ctx) + if err != nil { + select { + case <-ctx.Done(): + log.Warning("Cache rebuild closed by context finishing: ", err) + default: + log.Error(err) + } + return + } + if metrics.Active() { + fill := metrics.NewCtx(ctx, "bloom_fill_ratio", + "Ratio of bloom filter fullnes, (updated once a minute)").Gauge() + + t := time.NewTicker(1 * time.Minute) + defer t.Stop() + for { + select { + case <-ctx.Done(): + return + case <-t.C: + fill.Set(bc.bloom.FillRatio()) + } + } + } + }() + return bc, nil +} + +type bloomcache struct { + active int32 + + bloom *bloom.Bloom + buildErr error + + buildChan chan struct{} + blockstore Blockstore + + // Statistics + hits metrics.Counter + total metrics.Counter +} + +func (b *bloomcache) BloomActive() bool { + return atomic.LoadInt32(&b.active) != 0 +} + +func (b *bloomcache) Wait(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + case <-b.buildChan: + return b.buildErr + } +} + +func (b *bloomcache) build(ctx context.Context) error { + evt := log.EventBegin(ctx, "bloomcache.build") + defer evt.Done() + defer close(b.buildChan) + + ch, err := b.blockstore.AllKeysChan(ctx) + if err != nil { + b.buildErr = fmt.Errorf("AllKeysChan failed in bloomcache rebuild with: %v", err) + return b.buildErr + } + for { + select { + case key, ok := <-ch: + if !ok { + atomic.StoreInt32(&b.active, 1) + return nil + } + b.bloom.AddTS(key.Bytes()) // Use binary key, the more compact the better + case <-ctx.Done(): + b.buildErr = ctx.Err() + return b.buildErr + } + } +} + +func (b *bloomcache) DeleteBlock(k cid.Cid) error { + if has, ok := b.hasCached(k); ok && !has { + return ErrNotFound + } + + return b.blockstore.DeleteBlock(k) +} + +// if ok == false has is inconclusive +// if ok == true then has respons to question: is it contained +func (b *bloomcache) hasCached(k cid.Cid) (has bool, ok bool) { + b.total.Inc() + if !k.Defined() { + log.Error("undefined in bloom cache") + // Return cache invalid so call to blockstore + // in case of invalid key is forwarded deeper + return false, false + } + if b.BloomActive() { + blr := b.bloom.HasTS(k.Bytes()) + if !blr { // not contained in bloom is only conclusive answer bloom gives + b.hits.Inc() + return false, true + } + } + return false, false +} + +func (b *bloomcache) Has(k cid.Cid) (bool, error) { + if has, ok := b.hasCached(k); ok { + return has, nil + } + + return b.blockstore.Has(k) +} + +func (b *bloomcache) GetSize(k cid.Cid) (int, error) { + return b.blockstore.GetSize(k) +} + +func (b *bloomcache) Get(k cid.Cid) (blocks.Block, error) { + if has, ok := b.hasCached(k); ok && !has { + return nil, ErrNotFound + } + + return b.blockstore.Get(k) +} + +func (b *bloomcache) Put(bl blocks.Block) error { + // See comment in PutMany + err := b.blockstore.Put(bl) + if err == nil { + b.bloom.AddTS(bl.Cid().Bytes()) + } + return err +} + +func (b *bloomcache) PutMany(bs []blocks.Block) error { + // bloom cache gives only conclusive resulty if key is not contained + // to reduce number of puts we need conclusive information if block is contained + // this means that PutMany can't be improved with bloom cache so we just + // just do a passthrough. + err := b.blockstore.PutMany(bs) + if err != nil { + return err + } + for _, bl := range bs { + b.bloom.AddTS(bl.Cid().Bytes()) + } + return nil +} + +func (b *bloomcache) HashOnRead(enabled bool) { + b.blockstore.HashOnRead(enabled) +} + +func (b *bloomcache) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + return b.blockstore.AllKeysChan(ctx) +} + +func (b *bloomcache) GCLock() Unlocker { + return b.blockstore.(GCBlockstore).GCLock() +} + +func (b *bloomcache) PinLock() Unlocker { + return b.blockstore.(GCBlockstore).PinLock() +} + +func (b *bloomcache) GCRequested() bool { + return b.blockstore.(GCBlockstore).GCRequested() +} diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/caching.go b/vendor/github.com/ipfs/go-ipfs-blockstore/caching.go new file mode 100644 index 00000000..798b84ce --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/caching.go @@ -0,0 +1,55 @@ +package blockstore + +import ( + "context" + "errors" + + metrics "github.com/ipfs/go-metrics-interface" +) + +// CacheOpts wraps options for CachedBlockStore(). +// Next to each option is it aproximate memory usage per unit +type CacheOpts struct { + HasBloomFilterSize int // 1 byte + HasBloomFilterHashes int // No size, 7 is usually best, consult bloom papers + HasARCCacheSize int // 32 bytes +} + +// DefaultCacheOpts returns a CacheOpts initialized with default values. +func DefaultCacheOpts() CacheOpts { + return CacheOpts{ + HasBloomFilterSize: 512 << 10, + HasBloomFilterHashes: 7, + HasARCCacheSize: 64 << 10, + } +} + +// CachedBlockstore returns a blockstore wrapped in an ARCCache and +// then in a bloom filter cache, if the options indicate it. +func CachedBlockstore( + ctx context.Context, + bs Blockstore, + opts CacheOpts) (cbs Blockstore, err error) { + cbs = bs + + if opts.HasBloomFilterSize < 0 || opts.HasBloomFilterHashes < 0 || + opts.HasARCCacheSize < 0 { + return nil, errors.New("all options for cache need to be greater than zero") + } + + if opts.HasBloomFilterSize != 0 && opts.HasBloomFilterHashes == 0 { + return nil, errors.New("bloom filter hash count can't be 0 when there is size set") + } + + ctx = metrics.CtxSubScope(ctx, "bs.cache") + + if opts.HasARCCacheSize > 0 { + cbs, err = newARCCachedBS(ctx, cbs, opts.HasARCCacheSize) + } + if opts.HasBloomFilterSize != 0 { + // *8 because of bytes to bits conversion + cbs, err = bloomCached(ctx, cbs, opts.HasBloomFilterSize*8, opts.HasBloomFilterHashes) + } + + return cbs, err +} diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/go.mod b/vendor/github.com/ipfs/go-ipfs-blockstore/go.mod new file mode 100644 index 00000000..6a8f6c7f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/go.mod @@ -0,0 +1,14 @@ +module github.com/ipfs/go-ipfs-blockstore + +require ( + github.com/hashicorp/golang-lru v0.5.1 + github.com/ipfs/bbloom v0.0.1 + github.com/ipfs/go-block-format v0.0.1 + github.com/ipfs/go-cid v0.0.1 + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-ipfs-ds-help v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-metrics-interface v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/go.sum b/vendor/github.com/ipfs/go-ipfs-blockstore/go.sum new file mode 100644 index 00000000..c18ffbbe --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/go.sum @@ -0,0 +1,75 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-block-format v0.0.1 h1:GjLpqsPNn2KbzA2GuG+hsUyxMhQ1xXgffWqWOee9e9o= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/idstore.go b/vendor/github.com/ipfs/go-ipfs-blockstore/idstore.go new file mode 100644 index 00000000..2a5bf841 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/idstore.go @@ -0,0 +1,86 @@ +package blockstore + +import ( + "context" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +// idstore wraps a BlockStore to add support for identity hashes +type idstore struct { + bs Blockstore +} + +func NewIdStore(bs Blockstore) Blockstore { + return &idstore{bs} +} + +func extractContents(k cid.Cid) (bool, []byte) { + dmh, err := mh.Decode(k.Hash()) + if err != nil || dmh.Code != mh.ID { + return false, nil + } + return true, dmh.Digest +} + +func (b *idstore) DeleteBlock(k cid.Cid) error { + isId, _ := extractContents(k) + if isId { + return nil + } + return b.bs.DeleteBlock(k) +} + +func (b *idstore) Has(k cid.Cid) (bool, error) { + isId, _ := extractContents(k) + if isId { + return true, nil + } + return b.bs.Has(k) +} + +func (b *idstore) GetSize(k cid.Cid) (int, error) { + isId, bdata := extractContents(k) + if isId { + return len(bdata), nil + } + return b.bs.GetSize(k) +} + +func (b *idstore) Get(k cid.Cid) (blocks.Block, error) { + isId, bdata := extractContents(k) + if isId { + return blocks.NewBlockWithCid(bdata, k) + } + return b.bs.Get(k) +} + +func (b *idstore) Put(bl blocks.Block) error { + isId, _ := extractContents(bl.Cid()) + if isId { + return nil + } + return b.bs.Put(bl) +} + +func (b *idstore) PutMany(bs []blocks.Block) error { + toPut := make([]blocks.Block, 0, len(bs)) + for _, bl := range bs { + isId, _ := extractContents(bl.Cid()) + if isId { + continue + } + toPut = append(toPut, bl) + } + return b.bs.PutMany(toPut) +} + +func (b *idstore) HashOnRead(enabled bool) { + b.bs.HashOnRead(enabled) +} + +func (b *idstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + return b.bs.AllKeysChan(ctx) +} diff --git a/vendor/github.com/ipfs/go-ipfs-blockstore/package.json b/vendor/github.com/ipfs/go-ipfs-blockstore/package.json new file mode 100644 index 00000000..6a40ca76 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-blockstore/package.json @@ -0,0 +1,65 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-blockstore" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-blockstore" + }, + "gxDependencies": [ + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "jbenet", + "hash": "QmUadX5EcvrBmxAV9sE7wUWtWSqxns5K84qKJBixmcT1w9", + "name": "go-datastore", + "version": "3.6.1" + }, + { + "author": "ipfs", + "hash": "QmekzFM3hPZjTjUFGTABdQkEnQ3PTiMstY198PwSFr5w1Q", + "name": "go-metrics-interface", + "version": "0.2.0" + }, + { + "author": "hashicorp", + "hash": "QmQjMHF8ptRgx4E57UFMiT4YM6kqaJeYxZ1MCDX23aw4rK", + "name": "golang-lru", + "version": "2017.10.18" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "hector", + "hash": "QmXSEqXLCzpCByJU4wqbJ37TcBEj77FKMUWUP1qLh56847", + "name": "go-ipfs-ds-help", + "version": "0.1.7" + }, + { + "author": "kubuxu", + "hash": "QmWaLViWQF8jgyoLLqqcSrnp6dJpHESiJfzor1vrfDyTZf", + "name": "bbloom", + "version": "0.1.2" + }, + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-blockstore", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.8" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/.travis.yml b/vendor/github.com/ipfs/go-ipfs-chunker/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/LICENSE b/vendor/github.com/ipfs/go-ipfs-chunker/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/Makefile b/vendor/github.com/ipfs/go-ipfs-chunker/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/README.md b/vendor/github.com/ipfs/go-ipfs-chunker/README.md new file mode 100644 index 00000000..96faa3de --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/README.md @@ -0,0 +1,48 @@ +# go-ipfs-chunker + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-chunker?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-chunker) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-chunker.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-chunker) + +> go-ipfs-chunker implements data Splitters for go-ipfs. + +`go-ipfs-chunker` provides the `Splitter` interface. IPFS splitters read data from a reader an create "chunks". These chunks are used to build the ipfs DAGs (Merkle Tree) and are the base unit to obtain the sums that ipfs uses to address content. + +The package provides a `SizeSplitter` which creates chunks of equal size and it is used by default in most cases, and a `rabin` fingerprint chunker. This chunker will attempt to split data in a way that the resulting blocks are the same when the data has repetitive patterns, thus optimizing the resulting DAGs. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-chunker` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-chunker +``` + +It uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies. + +## Usage + +``` +import "github.com/ipfs/go-ipfs-chunker" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-chunker) + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/go.mod b/vendor/github.com/ipfs/go-ipfs-chunker/go.mod new file mode 100644 index 00000000..0610d885 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/go.mod @@ -0,0 +1,9 @@ +module github.com/ipfs/go-ipfs-chunker + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.1 + github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f +) diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/go.sum b/vendor/github.com/ipfs/go-ipfs-chunker/go.sum new file mode 100644 index 00000000..a45b1eeb --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/go.sum @@ -0,0 +1,55 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/package.json b/vendor/github.com/ipfs/go-ipfs-chunker/package.json new file mode 100644 index 00000000..d53c0e7b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/package.json @@ -0,0 +1,47 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-chunker" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-chunker" + }, + "gxDependencies": [ + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "whyrusleeping", + "hash": "QmZooytqEoUwQjv7KzH4d3xyJnyvD3AWJaCDMYt5pbCtua", + "name": "chunker", + "version": "0.0.1" + }, + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + }, + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "Stebalien", + "hash": "QmQDvJoB6aJWN3sjr3xsgXqKCXf4jU5zdMXpDMsBkYVNqa", + "name": "go-buffer-pool", + "version": "0.1.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-chunker", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.6" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/parse.go b/vendor/github.com/ipfs/go-ipfs-chunker/parse.go new file mode 100644 index 00000000..af0a31e8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/parse.go @@ -0,0 +1,88 @@ +package chunk + +import ( + "errors" + "fmt" + "io" + "strconv" + "strings" +) + +var ( + ErrRabinMin = errors.New("rabin min must be greater than 16") + ErrSize = errors.New("chunker size muster greater than 0") +) + +// FromString returns a Splitter depending on the given string: +// it supports "default" (""), "size-{size}", "rabin", "rabin-{blocksize}" and +// "rabin-{min}-{avg}-{max}". +func FromString(r io.Reader, chunker string) (Splitter, error) { + switch { + case chunker == "" || chunker == "default": + return DefaultSplitter(r), nil + + case strings.HasPrefix(chunker, "size-"): + sizeStr := strings.Split(chunker, "-")[1] + size, err := strconv.Atoi(sizeStr) + if err != nil { + return nil, err + } else if size <= 0 { + return nil, ErrSize + } + return NewSizeSplitter(r, int64(size)), nil + + case strings.HasPrefix(chunker, "rabin"): + return parseRabinString(r, chunker) + + default: + return nil, fmt.Errorf("unrecognized chunker option: %s", chunker) + } +} + +func parseRabinString(r io.Reader, chunker string) (Splitter, error) { + parts := strings.Split(chunker, "-") + switch len(parts) { + case 1: + return NewRabin(r, uint64(DefaultBlockSize)), nil + case 2: + size, err := strconv.Atoi(parts[1]) + if err != nil { + return nil, err + } + return NewRabin(r, uint64(size)), nil + case 4: + sub := strings.Split(parts[1], ":") + if len(sub) > 1 && sub[0] != "min" { + return nil, errors.New("first label must be min") + } + min, err := strconv.Atoi(sub[len(sub)-1]) + if err != nil { + return nil, err + } + if min < 16 { + return nil, ErrRabinMin + } + sub = strings.Split(parts[2], ":") + if len(sub) > 1 && sub[0] != "avg" { + log.Error("sub == ", sub) + return nil, errors.New("second label must be avg") + } + avg, err := strconv.Atoi(sub[len(sub)-1]) + if err != nil { + return nil, err + } + + sub = strings.Split(parts[3], ":") + if len(sub) > 1 && sub[0] != "max" { + return nil, errors.New("final label must be max") + } + max, err := strconv.Atoi(sub[len(sub)-1]) + if err != nil { + return nil, err + } + + return NewRabinMinMax(r, uint64(min), uint64(avg), uint64(max)), nil + default: + return nil, errors.New("incorrect format (expected 'rabin' 'rabin-[avg]' or 'rabin-[min]-[avg]-[max]'") + } +} diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/rabin.go b/vendor/github.com/ipfs/go-ipfs-chunker/rabin.go new file mode 100644 index 00000000..4247057b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/rabin.go @@ -0,0 +1,54 @@ +package chunk + +import ( + "hash/fnv" + "io" + + "github.com/whyrusleeping/chunker" +) + +// IpfsRabinPoly is the irreducible polynomial of degree 53 used by for Rabin. +var IpfsRabinPoly = chunker.Pol(17437180132763653) + +// Rabin implements the Splitter interface and splits content with Rabin +// fingerprints. +type Rabin struct { + r *chunker.Chunker + reader io.Reader +} + +// NewRabin creates a new Rabin splitter with the given +// average block size. +func NewRabin(r io.Reader, avgBlkSize uint64) *Rabin { + min := avgBlkSize / 3 + max := avgBlkSize + (avgBlkSize / 2) + + return NewRabinMinMax(r, min, avgBlkSize, max) +} + +// NewRabinMinMax returns a new Rabin splitter which uses +// the given min, average and max block sizes. +func NewRabinMinMax(r io.Reader, min, avg, max uint64) *Rabin { + h := fnv.New32a() + ch := chunker.New(r, IpfsRabinPoly, h, avg, min, max) + + return &Rabin{ + r: ch, + reader: r, + } +} + +// NextBytes reads the next bytes from the reader and returns a slice. +func (r *Rabin) NextBytes() ([]byte, error) { + ch, err := r.r.Next() + if err != nil { + return nil, err + } + + return ch.Data, nil +} + +// Reader returns the io.Reader associated to this Splitter. +func (r *Rabin) Reader() io.Reader { + return r.reader +} diff --git a/vendor/github.com/ipfs/go-ipfs-chunker/splitting.go b/vendor/github.com/ipfs/go-ipfs-chunker/splitting.go new file mode 100644 index 00000000..2b237399 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-chunker/splitting.go @@ -0,0 +1,105 @@ +// Package chunk implements streaming block splitters. +// Splitters read data from a reader and provide byte slices (chunks) +// The size and contents of these slices depend on the splitting method +// used. +package chunk + +import ( + "io" + + logging "github.com/ipfs/go-log" + pool "github.com/libp2p/go-buffer-pool" +) + +var log = logging.Logger("chunk") + +// DefaultBlockSize is the chunk size that splitters produce (or aim to). +var DefaultBlockSize int64 = 1024 * 256 + +// A Splitter reads bytes from a Reader and creates "chunks" (byte slices) +// that can be used to build DAG nodes. +type Splitter interface { + Reader() io.Reader + NextBytes() ([]byte, error) +} + +// SplitterGen is a splitter generator, given a reader. +type SplitterGen func(r io.Reader) Splitter + +// DefaultSplitter returns a SizeSplitter with the DefaultBlockSize. +func DefaultSplitter(r io.Reader) Splitter { + return NewSizeSplitter(r, DefaultBlockSize) +} + +// SizeSplitterGen returns a SplitterGen function which will create +// a splitter with the given size when called. +func SizeSplitterGen(size int64) SplitterGen { + return func(r io.Reader) Splitter { + return NewSizeSplitter(r, size) + } +} + +// Chan returns a channel that receives each of the chunks produced +// by a splitter, along with another one for errors. +func Chan(s Splitter) (<-chan []byte, <-chan error) { + out := make(chan []byte) + errs := make(chan error, 1) + go func() { + defer close(out) + defer close(errs) + + // all-chunks loop (keep creating chunks) + for { + b, err := s.NextBytes() + if err != nil { + errs <- err + return + } + + out <- b + } + }() + return out, errs +} + +type sizeSplitterv2 struct { + r io.Reader + size uint32 + err error +} + +// NewSizeSplitter returns a new size-based Splitter with the given block size. +func NewSizeSplitter(r io.Reader, size int64) Splitter { + return &sizeSplitterv2{ + r: r, + size: uint32(size), + } +} + +// NextBytes produces a new chunk. +func (ss *sizeSplitterv2) NextBytes() ([]byte, error) { + if ss.err != nil { + return nil, ss.err + } + + full := pool.Get(int(ss.size)) + n, err := io.ReadFull(ss.r, full) + switch err { + case io.ErrUnexpectedEOF: + ss.err = io.EOF + small := make([]byte, n) + copy(small, full) + pool.Put(full) + return small, nil + case nil: + return full, nil + default: + pool.Put(full) + return nil, err + } +} + +// Reader returns the io.Reader associated to this Splitter. +func (ss *sizeSplitterv2) Reader() io.Reader { + return ss.r +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/.gitignore b/vendor/github.com/ipfs/go-ipfs-config/.gitignore new file mode 100644 index 00000000..9a684b15 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/.gitignore @@ -0,0 +1 @@ +serialize/.ipfsconfig diff --git a/vendor/github.com/ipfs/go-ipfs-config/.travis.yml b/vendor/github.com/ipfs/go-ipfs-config/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-config/LICENSE b/vendor/github.com/ipfs/go-ipfs-config/LICENSE new file mode 100644 index 00000000..833dabb8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-config/addresses.go b/vendor/github.com/ipfs/go-ipfs-config/addresses.go new file mode 100644 index 00000000..2d88468f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/addresses.go @@ -0,0 +1,10 @@ +package config + +// Addresses stores the (string) multiaddr addresses for the node. +type Addresses struct { + Swarm []string // addresses for the swarm to listen on + Announce []string // swarm addresses to announce to the network + NoAnnounce []string // swarm addresses not to announce to the network + API Strings // address for the local API (RPC) + Gateway Strings // address to listen on for IPFS HTTP object gateway +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/api.go b/vendor/github.com/ipfs/go-ipfs-config/api.go new file mode 100644 index 00000000..b36b1080 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/api.go @@ -0,0 +1,5 @@ +package config + +type API struct { + HTTPHeaders map[string][]string // HTTP headers to return with the API. +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/bootstrap_peers.go b/vendor/github.com/ipfs/go-ipfs-config/bootstrap_peers.go new file mode 100644 index 00000000..f4a13dc9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/bootstrap_peers.go @@ -0,0 +1,88 @@ +package config + +import ( + "errors" + "fmt" + + peer "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" + + // Needs to be imported so that users can import this package directly + // and still parse the bootstrap addresses. + _ "github.com/multiformats/go-multiaddr-dns" +) + +// DefaultBootstrapAddresses are the hardcoded bootstrap addresses +// for IPFS. they are nodes run by the IPFS team. docs on these later. +// As with all p2p networks, bootstrap is an important security concern. +// +// NOTE: This is here -- and not inside cmd/ipfs/init.go -- because of an +// import dependency issue. TODO: move this into a config/default/ package. +var DefaultBootstrapAddresses = []string{ + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", + "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io + "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", // pluto.i.ipfs.io + "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn.i.ipfs.io + "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", // venus.i.ipfs.io + "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", // earth.i.ipfs.io + "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", // pluto.i.ipfs.io + "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn.i.ipfs.io + "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", // venus.i.ipfs.io + "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", // earth.i.ipfs.io +} + +// ErrInvalidPeerAddr signals an address is not a valid peer address. +var ErrInvalidPeerAddr = errors.New("invalid peer address") + +func (c *Config) BootstrapPeers() ([]peer.AddrInfo, error) { + return ParseBootstrapPeers(c.Bootstrap) +} + +// DefaultBootstrapPeers returns the (parsed) set of default bootstrap peers. +// if it fails, it returns a meaningful error for the user. +// This is here (and not inside cmd/ipfs/init) because of module dependency problems. +func DefaultBootstrapPeers() ([]peer.AddrInfo, error) { + ps, err := ParseBootstrapPeers(DefaultBootstrapAddresses) + if err != nil { + return nil, fmt.Errorf(`failed to parse hardcoded bootstrap peers: %s +This is a problem with the ipfs codebase. Please report it to the dev team.`, err) + } + return ps, nil +} + +func (c *Config) SetBootstrapPeers(bps []peer.AddrInfo) { + c.Bootstrap = BootstrapPeerStrings(bps) +} + +// ParseBootstrapPeer parses a bootstrap list into a list of AddrInfos. +func ParseBootstrapPeers(addrs []string) ([]peer.AddrInfo, error) { + maddrs := make([]ma.Multiaddr, len(addrs)) + for i, addr := range addrs { + var err error + maddrs[i], err = ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + } + return peer.AddrInfosFromP2pAddrs(maddrs...) +} + +// BootstrapPeerStrings formats a list of AddrInfos as a bootstrap peer list +// suitable for serialization. +func BootstrapPeerStrings(bps []peer.AddrInfo) []string { + bpss := make([]string, 0, len(bps)) + for _, pi := range bps { + addrs, err := peer.AddrInfoToP2pAddrs(&pi) + if err != nil { + // programmer error. + panic(err) + } + for _, addr := range addrs { + bpss = append(bpss, addr.String()) + } + } + return bpss +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/config.go b/vendor/github.com/ipfs/go-ipfs-config/config.go new file mode 100644 index 00000000..dc987547 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/config.go @@ -0,0 +1,128 @@ +// package config implements the ipfs config file datastructures and utilities. +package config + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/mitchellh/go-homedir" +) + +// Config is used to load ipfs config files. +type Config struct { + Identity Identity // local node's peer identity + Datastore Datastore // local node's storage + Addresses Addresses // local node's addresses + Mounts Mounts // local node's mount points + Discovery Discovery // local node's discovery mechanisms + Routing Routing // local node's routing settings + Ipns Ipns // Ipns settings + Bootstrap []string // local nodes's bootstrap peer addresses + Gateway Gateway // local node's gateway server options + API API // local node's API settings + Swarm SwarmConfig + Pubsub PubsubConfig + + Reprovider Reprovider + Experimental Experiments +} + +const ( + // DefaultPathName is the default config dir name + DefaultPathName = ".ipfs" + // DefaultPathRoot is the path to the default config dir location. + DefaultPathRoot = "~/" + DefaultPathName + // DefaultConfigFile is the filename of the configuration file + DefaultConfigFile = "config" + // EnvDir is the environment variable used to change the path root. + EnvDir = "IPFS_PATH" +) + +// PathRoot returns the default configuration root directory +func PathRoot() (string, error) { + dir := os.Getenv(EnvDir) + var err error + if len(dir) == 0 { + dir, err = homedir.Expand(DefaultPathRoot) + } + return dir, err +} + +// Path returns the path `extension` relative to the configuration root. If an +// empty string is provided for `configroot`, the default root is used. +func Path(configroot, extension string) (string, error) { + if len(configroot) == 0 { + dir, err := PathRoot() + if err != nil { + return "", err + } + return filepath.Join(dir, extension), nil + + } + return filepath.Join(configroot, extension), nil +} + +// Filename returns the configuration file path given a configuration root +// directory. If the configuration root directory is empty, use the default one +func Filename(configroot string) (string, error) { + return Path(configroot, DefaultConfigFile) +} + +// HumanOutput gets a config value ready for printing +func HumanOutput(value interface{}) ([]byte, error) { + s, ok := value.(string) + if ok { + return []byte(strings.Trim(s, "\n")), nil + } + return Marshal(value) +} + +// Marshal configuration with JSON +func Marshal(value interface{}) ([]byte, error) { + // need to prettyprint, hence MarshalIndent, instead of Encoder + return json.MarshalIndent(value, "", " ") +} + +func FromMap(v map[string]interface{}) (*Config, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(v); err != nil { + return nil, err + } + var conf Config + if err := json.NewDecoder(buf).Decode(&conf); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + return &conf, nil +} + +func ToMap(conf *Config) (map[string]interface{}, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(conf); err != nil { + return nil, err + } + var m map[string]interface{} + if err := json.NewDecoder(buf).Decode(&m); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + return m, nil +} + +// Clone copies the config. Use when updating. +func (c *Config) Clone() (*Config, error) { + var newConfig Config + var buf bytes.Buffer + + if err := json.NewEncoder(&buf).Encode(c); err != nil { + return nil, fmt.Errorf("failure to encode config: %s", err) + } + + if err := json.NewDecoder(&buf).Decode(&newConfig); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + + return &newConfig, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/datastore.go b/vendor/github.com/ipfs/go-ipfs-config/datastore.go new file mode 100644 index 00000000..2b2bcb51 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/datastore.go @@ -0,0 +1,32 @@ +package config + +import ( + "encoding/json" +) + +// DefaultDataStoreDirectory is the directory to store all the local IPFS data. +const DefaultDataStoreDirectory = "datastore" + +// Datastore tracks the configuration of the datastore. +type Datastore struct { + StorageMax string // in B, kB, kiB, MB, ... + StorageGCWatermark int64 // in percentage to multiply on StorageMax + GCPeriod string // in ns, us, ms, s, m, h + + // deprecated fields, use Spec + Type string `json:",omitempty"` + Path string `json:",omitempty"` + NoSync bool `json:",omitempty"` + Params *json.RawMessage `json:",omitempty"` + + Spec map[string]interface{} + + HashOnRead bool + BloomFilterSize int +} + +// DataStorePath returns the default data store path given a configuration root +// (set an empty string to have the default configuration root) +func DataStorePath(configroot string) (string, error) { + return Path(configroot, DefaultDataStoreDirectory) +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/discovery.go b/vendor/github.com/ipfs/go-ipfs-config/discovery.go new file mode 100644 index 00000000..4fb8508f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/discovery.go @@ -0,0 +1,12 @@ +package config + +type Discovery struct { + MDNS MDNS +} + +type MDNS struct { + Enabled bool + + // Time in seconds between discovery rounds + Interval int +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/experiments.go b/vendor/github.com/ipfs/go-ipfs-config/experiments.go new file mode 100644 index 00000000..6821ed6b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/experiments.go @@ -0,0 +1,12 @@ +package config + +type Experiments struct { + FilestoreEnabled bool + UrlstoreEnabled bool + ShardingEnabled bool + Libp2pStreamMounting bool + P2pHttpProxy bool + QUIC bool + PreferTLS bool + StrategicProviding bool +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/gateway.go b/vendor/github.com/ipfs/go-ipfs-config/gateway.go new file mode 100644 index 00000000..017be9b2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/gateway.go @@ -0,0 +1,11 @@ +package config + +// Gateway contains options for the HTTP gateway server. +type Gateway struct { + HTTPHeaders map[string][]string // HTTP headers to return with the gateway + RootRedirect string + Writable bool + PathPrefixes []string + APICommands []string + NoFetch bool +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/go.mod b/vendor/github.com/ipfs/go-ipfs-config/go.mod new file mode 100644 index 00000000..95b7006b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/go.mod @@ -0,0 +1,10 @@ +module github.com/ipfs/go-ipfs-config + +require ( + github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.3 + github.com/mitchellh/go-homedir v1.1.0 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-dns v0.0.2 +) diff --git a/vendor/github.com/ipfs/go-ipfs-config/go.sum b/vendor/github.com/ipfs/go-ipfs-config/go.sum new file mode 100644 index 00000000..de086052 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/go.sum @@ -0,0 +1,92 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= +github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.3 h1:+IonUYY0nJZLb5Fdv6a6DOjtGP1L8Bb3faamiI2q5FY= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-ipfs-config/identity.go b/vendor/github.com/ipfs/go-ipfs-config/identity.go new file mode 100644 index 00000000..f4e7c872 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/identity.go @@ -0,0 +1,29 @@ +package config + +import ( + "encoding/base64" + + ic "github.com/libp2p/go-libp2p-core/crypto" +) + +const IdentityTag = "Identity" +const PrivKeyTag = "PrivKey" +const PrivKeySelector = IdentityTag + "." + PrivKeyTag + +// Identity tracks the configuration of the local node's identity. +type Identity struct { + PeerID string + PrivKey string `json:",omitempty"` +} + +// DecodePrivateKey is a helper to decode the users PrivateKey +func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) { + pkb, err := base64.StdEncoding.DecodeString(i.PrivKey) + if err != nil { + return nil, err + } + + // currently storing key unencrypted. in the future we need to encrypt it. + // TODO(security) + return ic.UnmarshalPrivateKey(pkb) +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/init.go b/vendor/github.com/ipfs/go-ipfs-config/init.go new file mode 100644 index 00000000..7f11c3a3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/init.go @@ -0,0 +1,181 @@ +package config + +import ( + "encoding/base64" + "errors" + "fmt" + "io" + "time" + + ci "github.com/libp2p/go-libp2p-core/crypto" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { + identity, err := identityConfig(out, nBitsForKeypair) + if err != nil { + return nil, err + } + + bootstrapPeers, err := DefaultBootstrapPeers() + if err != nil { + return nil, err + } + + datastore := DefaultDatastoreConfig() + + conf := &Config{ + API: API{ + HTTPHeaders: map[string][]string{}, + }, + + // setup the node's default addresses. + // NOTE: two swarm listen addrs, one tcp, one utp. + Addresses: addressesConfig(), + + Datastore: datastore, + Bootstrap: BootstrapPeerStrings(bootstrapPeers), + Identity: identity, + Discovery: Discovery{ + MDNS: MDNS{ + Enabled: true, + Interval: 10, + }, + }, + + Routing: Routing{ + Type: "dht", + }, + + // setup the node mount points. + Mounts: Mounts{ + IPFS: "/ipfs", + IPNS: "/ipns", + }, + + Ipns: Ipns{ + ResolveCacheSize: 128, + }, + + Gateway: Gateway{ + RootRedirect: "", + Writable: false, + NoFetch: false, + PathPrefixes: []string{}, + HTTPHeaders: map[string][]string{ + "Access-Control-Allow-Origin": []string{"*"}, + "Access-Control-Allow-Methods": []string{"GET"}, + "Access-Control-Allow-Headers": []string{"X-Requested-With", "Range", "User-Agent"}, + }, + APICommands: []string{}, + }, + Reprovider: Reprovider{ + Interval: "12h", + Strategy: "all", + }, + Swarm: SwarmConfig{ + ConnMgr: ConnMgr{ + LowWater: DefaultConnMgrLowWater, + HighWater: DefaultConnMgrHighWater, + GracePeriod: DefaultConnMgrGracePeriod.String(), + Type: "basic", + }, + }, + } + + return conf, nil +} + +// DefaultConnMgrHighWater is the default value for the connection managers +// 'high water' mark +const DefaultConnMgrHighWater = 900 + +// DefaultConnMgrLowWater is the default value for the connection managers 'low +// water' mark +const DefaultConnMgrLowWater = 600 + +// DefaultConnMgrGracePeriod is the default value for the connection managers +// grace period +const DefaultConnMgrGracePeriod = time.Second * 20 + +func addressesConfig() Addresses { + return Addresses{ + Swarm: []string{ + "/ip4/0.0.0.0/tcp/4001", + // "/ip4/0.0.0.0/udp/4002/utp", // disabled for now. + "/ip6/::/tcp/4001", + }, + Announce: []string{}, + NoAnnounce: []string{}, + API: Strings{"/ip4/127.0.0.1/tcp/5001"}, + Gateway: Strings{"/ip4/127.0.0.1/tcp/8080"}, + } +} + +// DefaultDatastoreConfig is an internal function exported to aid in testing. +func DefaultDatastoreConfig() Datastore { + return Datastore{ + StorageMax: "10GB", + StorageGCWatermark: 90, // 90% + GCPeriod: "1h", + BloomFilterSize: 0, + Spec: map[string]interface{}{ + "type": "mount", + "mounts": []interface{}{ + map[string]interface{}{ + "mountpoint": "/blocks", + "type": "measure", + "prefix": "flatfs.datastore", + "child": map[string]interface{}{ + "type": "flatfs", + "path": "blocks", + "sync": true, + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + }, + }, + map[string]interface{}{ + "mountpoint": "/", + "type": "measure", + "prefix": "leveldb.datastore", + "child": map[string]interface{}{ + "type": "levelds", + "path": "datastore", + "compression": "none", + }, + }, + }, + }, + } +} + +// identityConfig initializes a new identity. +func identityConfig(out io.Writer, nbits int) (Identity, error) { + // TODO guard higher up + ident := Identity{} + if nbits < 1024 { + return ident, errors.New("bitsize less than 1024 is considered unsafe") + } + + fmt.Fprintf(out, "generating %v-bit RSA keypair...", nbits) + sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits) + if err != nil { + return ident, err + } + fmt.Fprintf(out, "done\n") + + // currently storing key unencrypted. in the future we need to encrypt it. + // TODO(security) + skbytes, err := sk.Bytes() + if err != nil { + return ident, err + } + ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes) + + id, err := peer.IDFromPublicKey(pk) + if err != nil { + return ident, err + } + ident.PeerID = id.Pretty() + fmt.Fprintf(out, "peer identity: %s\n", ident.PeerID) + return ident, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/ipns.go b/vendor/github.com/ipfs/go-ipfs-config/ipns.go new file mode 100644 index 00000000..44a95b09 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/ipns.go @@ -0,0 +1,8 @@ +package config + +type Ipns struct { + RepublishPeriod string + RecordLifetime string + + ResolveCacheSize int +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/mounts.go b/vendor/github.com/ipfs/go-ipfs-config/mounts.go new file mode 100644 index 00000000..b23d30b2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/mounts.go @@ -0,0 +1,8 @@ +package config + +// Mounts stores the (string) mount points +type Mounts struct { + IPFS string + IPNS string + FuseAllowOther bool +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/profile.go b/vendor/github.com/ipfs/go-ipfs-config/profile.go new file mode 100644 index 00000000..ac871f3f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/profile.go @@ -0,0 +1,259 @@ +package config + +import ( + "fmt" + "net" + "os" + "time" +) + +// Transformer is a function which takes configuration and applies some filter to it +type Transformer func(c *Config) error + +// Profile contains the profile transformer the description of the profile +type Profile struct { + // Description briefly describes the functionality of the profile + Description string + + // Transform takes ipfs configuration and applies the profile to it + Transform Transformer +} + +// defaultServerFilters has is a list of IPv4 and IPv6 prefixes that are private, local only, or unrouteable. +// according to https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +// and https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml +var defaultServerFilters = []string{ + "/ip4/10.0.0.0/ipcidr/8", + "/ip4/100.64.0.0/ipcidr/10", + "/ip4/169.254.0.0/ipcidr/16", + "/ip4/172.16.0.0/ipcidr/12", + "/ip4/192.0.0.0/ipcidr/24", + "/ip4/192.0.0.0/ipcidr/29", + "/ip4/192.0.0.8/ipcidr/32", + "/ip4/192.0.0.170/ipcidr/32", + "/ip4/192.0.0.171/ipcidr/32", + "/ip4/192.0.2.0/ipcidr/24", + "/ip4/192.168.0.0/ipcidr/16", + "/ip4/198.18.0.0/ipcidr/15", + "/ip4/198.51.100.0/ipcidr/24", + "/ip4/203.0.113.0/ipcidr/24", + "/ip4/240.0.0.0/ipcidr/4", + "/ip6/100::/ipcidr/64", + "/ip6/2001:2::/ipcidr/48", + "/ip6/2001:db8::/ipcidr/32", + "/ip6/fc00::/ipcidr/7", + "/ip6/fe80::/ipcidr/10", +} + +// Profiles is a map holding configuration transformers. Docs are in docs/config.md +var Profiles = map[string]Profile{ + "server": { + Description: `Disables local host discovery, recommended when +running IPFS on machines with public IPv4 addresses.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = appendSingle(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = appendSingle(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = false + c.Swarm.DisableNatPortMap = true + return nil + }, + }, + + "local-discovery": { + Description: `Sets default values to fields affected by the server +profile, enables discovery in local networks.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = deleteEntries(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = deleteEntries(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = true + c.Swarm.DisableNatPortMap = false + return nil + }, + }, + "test": { + Description: `Reduces external interference of IPFS daemon, this +is useful when using the daemon in test environments.`, + + Transform: func(c *Config) error { + c.Addresses.API = Strings{"/ip4/127.0.0.1/tcp/0"} + c.Addresses.Gateway = Strings{"/ip4/127.0.0.1/tcp/0"} + c.Addresses.Swarm = []string{ + "/ip4/127.0.0.1/tcp/0", + } + + c.Swarm.DisableNatPortMap = true + + c.Bootstrap = []string{} + c.Discovery.MDNS.Enabled = false + return nil + }, + }, + "default-networking": { + Description: `Restores default network settings. +Inverse profile of the test profile.`, + + Transform: func(c *Config) error { + c.Addresses = addressesConfig() + + bootstrapPeers, err := DefaultBootstrapPeers() + if err != nil { + return err + } + c.Bootstrap = appendSingle(c.Bootstrap, BootstrapPeerStrings(bootstrapPeers)) + + c.Swarm.DisableNatPortMap = false + c.Discovery.MDNS.Enabled = true + return nil + }, + }, + "badgerds": { + Description: `Replaces default datastore configuration with experimental +badger datastore. + +If you apply this profile after ipfs init, you will need +to convert your datastore to the new configuration. +You can do this using ipfs-ds-convert. + +For more on ipfs-ds-convert see +$ ipfs-ds-convert --help +and +$ ipfs-ds-convert convert --help + +WARNING: badger datastore is experimental. +Make sure to backup your data frequently.`, + + Transform: func(c *Config) error { + c.Datastore.Spec = map[string]interface{}{ + "type": "measure", + "prefix": "badger.datastore", + "child": map[string]interface{}{ + "type": "badgerds", + "path": "badgerds", + "syncWrites": true, + "truncate": true, + }, + } + return nil + }, + }, + "postgresds": { + Description: `Replaces default datastore configuration with experimental +postgres datastore. + +WARNING: postgres datastore is experimental. +Make sure to backup your data frequently.`, + Transform: func(c *Config) error { + c.Datastore.Spec = map[string]interface{}{ + "type": "measure", + "prefix": "postgres.datastore", + "child": map[string]interface{}{ + "type": "postgres", + "host": os.Getenv("IPFS_PGHOST"), + "user": os.Getenv("IPFS_PGUSER"), + "passfile": os.Getenv("IPFS_PGPASSFILE"), + "password": os.Getenv("IPFS_PGPASSWORD"), + "dbname": os.Getenv("IPFS_PGDATABASE"), + "port": os.Getenv("IPFS_PGPORT"), + }, + } + return nil + }, + }, + "default-datastore": { + Description: `Restores default datastore configuration. + +If you apply this profile after ipfs init, you will need +to convert your datastore to the new configuration. +You can do this using ipfs-ds-convert. + +For more on ipfs-ds-convert see +$ ipfs-ds-convert --help +and +$ ipfs-ds-convert convert --help +`, + + Transform: func(c *Config) error { + c.Datastore.Spec = DefaultDatastoreConfig().Spec + return nil + }, + }, + "lowpower": { + Description: `Reduces daemon overhead on the system. May affect node +functionality - performance of content discovery and data +fetching may be degraded. +`, + Transform: func(c *Config) error { + c.Routing.Type = "dhtclient" + c.Reprovider.Interval = "0" + + c.Swarm.ConnMgr.LowWater = 20 + c.Swarm.ConnMgr.HighWater = 40 + c.Swarm.ConnMgr.GracePeriod = time.Minute.String() + return nil + }, + }, + "randomports": { + Description: `Use a random port number for swarm.`, + + Transform: func(c *Config) error { + port, err := getAvailablePort() + if err != nil { + return err + } + c.Addresses.Swarm = []string{ + fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port), + fmt.Sprintf("/ip6/::/tcp/%d", port), + } + return nil + }, + }, +} + +func getAvailablePort() (port int, err error) { + ln, err := net.Listen("tcp", "[::]:0") + if err != nil { + return 0, err + } + defer ln.Close() + port = ln.Addr().(*net.TCPAddr).Port + return port, nil +} + +func appendSingle(a []string, b []string) []string { + out := make([]string, 0, len(a)+len(b)) + m := map[string]bool{} + for _, f := range a { + if !m[f] { + out = append(out, f) + } + m[f] = true + } + for _, f := range b { + if !m[f] { + out = append(out, f) + } + m[f] = true + } + return out +} + +func deleteEntries(arr []string, del []string) []string { + m := map[string]struct{}{} + for _, f := range arr { + m[f] = struct{}{} + } + for _, f := range del { + delete(m, f) + } + return mapKeys(m) +} + +func mapKeys(m map[string]struct{}) []string { + out := make([]string, 0, len(m)) + for f := range m { + out = append(out, f) + } + return out +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/pubsub.go b/vendor/github.com/ipfs/go-ipfs-config/pubsub.go new file mode 100644 index 00000000..94e03e28 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/pubsub.go @@ -0,0 +1,18 @@ +package config + +type PubsubConfig struct { + // Router can be either floodsub (legacy) or gossipsub (new and + // backwards compatible). + Router string + + // DisableSigning disables message signing. Message signing is *enabled* + // by default. + DisableSigning bool + + // StrictSignatureVerification enables strict signature verification. + // When enabled, unsigned messages will be rejected. Eventually, this + // will be made the default and this option will disappear. Once this + // happens, networks will either need to completely disable or + // completely enable message signing. + StrictSignatureVerification bool +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/reprovider.go b/vendor/github.com/ipfs/go-ipfs-config/reprovider.go new file mode 100644 index 00000000..fa029c2f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/reprovider.go @@ -0,0 +1,6 @@ +package config + +type Reprovider struct { + Interval string // Time period to reprovide locally stored objects to the network + Strategy string // Which keys to announce +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/routing.go b/vendor/github.com/ipfs/go-ipfs-config/routing.go new file mode 100644 index 00000000..e601cd5e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/routing.go @@ -0,0 +1,7 @@ +package config + +// Routing defines configuration options for libp2p routing +type Routing struct { + // Type sets default daemon routing mode. + Type string +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/serialize/serialize.go b/vendor/github.com/ipfs/go-ipfs-config/serialize/serialize.go new file mode 100644 index 00000000..eedf7e1a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/serialize/serialize.go @@ -0,0 +1,71 @@ +package fsrepo + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/ipfs/go-ipfs-config" + + "github.com/facebookgo/atomicfile" + "github.com/ipfs/go-ipfs-util" +) + +// ReadConfigFile reads the config from `filename` into `cfg`. +func ReadConfigFile(filename string, cfg interface{}) error { + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + if err := json.NewDecoder(f).Decode(cfg); err != nil { + return fmt.Errorf("failure to decode config: %s", err) + } + return nil +} + +// WriteConfigFile writes the config from `cfg` into `filename`. +func WriteConfigFile(filename string, cfg interface{}) error { + err := os.MkdirAll(filepath.Dir(filename), 0775) + if err != nil { + return err + } + + f, err := atomicfile.New(filename, 0660) + if err != nil { + return err + } + defer f.Close() + + return encode(f, cfg) +} + +// encode configuration with JSON +func encode(w io.Writer, value interface{}) error { + // need to prettyprint, hence MarshalIndent, instead of Encoder + buf, err := config.Marshal(value) + if err != nil { + return err + } + _, err = w.Write(buf) + return err +} + +// Load reads given file and returns the read config, or error. +func Load(filename string) (*config.Config, error) { + // if nothing is there, fail. User must run 'ipfs init' + if !util.FileExists(filename) { + return nil, errors.New("ipfs not initialized, please run 'ipfs init'") + } + + var cfg config.Config + err := ReadConfigFile(filename, &cfg) + if err != nil { + return nil, err + } + + return &cfg, err +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/swarm.go b/vendor/github.com/ipfs/go-ipfs-config/swarm.go new file mode 100644 index 00000000..16dc54d9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/swarm.go @@ -0,0 +1,25 @@ +package config + +type SwarmConfig struct { + AddrFilters []string + DisableBandwidthMetrics bool + DisableNatPortMap bool + DisableRelay bool + EnableRelayHop bool + + // autorelay functionality + // if true, then the libp2p host will be constructed with autorelay functionality. + EnableAutoRelay bool + // if true, then an AutoNATService will be instantiated to facilitate autorelay + EnableAutoNATService bool + + ConnMgr ConnMgr +} + +// ConnMgr defines configuration options for the libp2p connection manager +type ConnMgr struct { + Type string + LowWater int + HighWater int + GracePeriod string +} diff --git a/vendor/github.com/ipfs/go-ipfs-config/types.go b/vendor/github.com/ipfs/go-ipfs-config/types.go new file mode 100644 index 00000000..58451c68 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-config/types.go @@ -0,0 +1,41 @@ +package config + +import ( + "encoding/json" +) + +// Strings is a helper type that (un)marshals a single string to/from a single +// JSON string and a slice of strings to/from a JSON array of strings. +type Strings []string + +// UnmarshalJSON conforms to the json.Unmarshaler interface. +func (o *Strings) UnmarshalJSON(data []byte) error { + if data[0] == '[' { + return json.Unmarshal(data, (*[]string)(o)) + } + var value string + if err := json.Unmarshal(data, &value); err != nil { + return err + } + if len(value) == 0 { + *o = []string{} + } else { + *o = []string{value} + } + return nil +} + +// MarshalJSON conforms to the json.Marshaler interface. +func (o Strings) MarshalJSON() ([]byte, error) { + switch len(o) { + case 0: + return json.Marshal(nil) + case 1: + return json.Marshal(o[0]) + default: + return json.Marshal([]string(o)) + } +} + +var _ json.Unmarshaler = (*Strings)(nil) +var _ json.Marshaler = (*Strings)(nil) diff --git a/vendor/github.com/ipfs/go-ipfs-delay/.travis.yml b/vendor/github.com/ipfs/go-ipfs-delay/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-delay/LICENSE b/vendor/github.com/ipfs/go-ipfs-delay/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-delay/Makefile b/vendor/github.com/ipfs/go-ipfs-delay/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-delay/README.md b/vendor/github.com/ipfs/go-ipfs-delay/README.md new file mode 100644 index 00000000..0f020b1e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/README.md @@ -0,0 +1,42 @@ +# go-ipfs-delay + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-delay?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-delay) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-delay.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-delay) + +> go-ipfs-delay makes it easy to add (threadsafe) configurable delays to other objects. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-delay` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-delay +``` + +## Usage + +``` +import "github.com/ipfs/go-ipfs-delay" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-delay) + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-delay/delay.go b/vendor/github.com/ipfs/go-ipfs-delay/delay.go new file mode 100644 index 00000000..afc08587 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/delay.go @@ -0,0 +1,75 @@ +package delay + +import ( + "math/rand" + "sync" + "time" +) + +// D (Delay) makes it easy to add (threadsafe) configurable delays to other +// objects. +type D interface { + Set(time.Duration) time.Duration + Wait() + NextWaitTime() time.Duration + Get() time.Duration +} + +type delay struct { + l sync.RWMutex + t time.Duration + generator Generator +} + +func (d *delay) Set(t time.Duration) time.Duration { + d.l.Lock() + defer d.l.Unlock() + prev := d.t + d.t = t + return prev +} + +func (d *delay) Wait() { + d.l.RLock() + defer d.l.RUnlock() + time.Sleep(d.generator.NextWaitTime(d.t)) +} + +func (d *delay) NextWaitTime() time.Duration { + d.l.Lock() + defer d.l.Unlock() + return d.generator.NextWaitTime(d.t) +} + +func (d *delay) Get() time.Duration { + d.l.Lock() + defer d.l.Unlock() + return d.t +} + +// Delay generates a generic delay form a t, a sleeper, and a generator +func Delay(t time.Duration, generator Generator) D { + return &delay{ + t: t, + generator: generator, + } +} + +// Fixed returns a delay with fixed latency +func Fixed(t time.Duration) D { + return Delay(t, FixedGenerator()) +} + +// VariableUniform is a delay following a uniform distribution +// Notice that to implement the D interface Set can only change the minimum delay +// the delta is set only at initialization +func VariableUniform(t, d time.Duration, rng *rand.Rand) D { + return Delay(t, VariableUniformGenerator(d, rng)) +} + +// VariableNormal is a delay following a normal distribution +// Notice that to implement the D interface Set can only change the mean delay +// the standard deviation is set only at initialization +func VariableNormal(t, std time.Duration, rng *rand.Rand) D { + return Delay(t, VariableNormalGenerator(std, rng)) +} diff --git a/vendor/github.com/ipfs/go-ipfs-delay/generator.go b/vendor/github.com/ipfs/go-ipfs-delay/generator.go new file mode 100644 index 00000000..122d7c0b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/generator.go @@ -0,0 +1,66 @@ +package delay + +import ( + "math/rand" + "time" +) + +// Generator provides an interface for generating wait times +type Generator interface { + NextWaitTime(time.Duration) time.Duration +} + +var sharedRNG = rand.New(rand.NewSource(time.Now().UnixNano())) + +// VariableNormalGenerator makes delays that following a normal distribution +func VariableNormalGenerator(std time.Duration, rng *rand.Rand) Generator { + if rng == nil { + rng = sharedRNG + } + + return &variableNormal{ + std: std, + rng: rng, + } +} + +type variableNormal struct { + std time.Duration + rng *rand.Rand +} + +func (d *variableNormal) NextWaitTime(t time.Duration) time.Duration { + return time.Duration(d.rng.NormFloat64()*float64(d.std)) + t +} + +// VariableUniformGenerator generates delays following a uniform distribution +func VariableUniformGenerator(d time.Duration, rng *rand.Rand) Generator { + if rng == nil { + rng = sharedRNG + } + + return &variableUniform{ + d: d, + rng: rng, + } +} + +type variableUniform struct { + d time.Duration // max delta + rng *rand.Rand +} + +func (d *variableUniform) NextWaitTime(t time.Duration) time.Duration { + return time.Duration(d.rng.Float64()*float64(d.d)) + t +} + +type fixed struct{} + +// FixedGenerator returns a delay with fixed latency +func FixedGenerator() Generator { + return &fixed{} +} + +func (d *fixed) NextWaitTime(t time.Duration) time.Duration { + return t +} diff --git a/vendor/github.com/ipfs/go-ipfs-delay/go.mod b/vendor/github.com/ipfs/go-ipfs-delay/go.mod new file mode 100644 index 00000000..49cae0fc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/go.mod @@ -0,0 +1 @@ +module github.com/ipfs/go-ipfs-delay diff --git a/vendor/github.com/ipfs/go-ipfs-delay/package.json b/vendor/github.com/ipfs/go-ipfs-delay/package.json new file mode 100644 index 00000000..124b8915 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-delay/package.json @@ -0,0 +1,16 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-delay" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-delay" + }, + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-ipfs-delay", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.0" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/.travis.yml b/vendor/github.com/ipfs/go-ipfs-ds-help/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/LICENSE b/vendor/github.com/ipfs/go-ipfs-ds-help/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/Makefile b/vendor/github.com/ipfs/go-ipfs-ds-help/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/README.md b/vendor/github.com/ipfs/go-ipfs-ds-help/README.md new file mode 100644 index 00000000..2af3bff4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/README.md @@ -0,0 +1,44 @@ +# go-ipfs-ds-help + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-ds-help?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-ds-help) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-ds-help.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-ds-help) + +> go-ipfs-ds-help provides utilities for parsing and creating datastore keys used by go-ipfs. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-ds-help` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-ds-help +``` + +## Usage + +``` +import "github.com/ipfs/go-ipfs-ds-help" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-ds-help) + +This module uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies. + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/go.mod b/vendor/github.com/ipfs/go-ipfs-ds-help/go.mod new file mode 100644 index 00000000..ada36b21 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-ipfs-ds-help + +require ( + github.com/ipfs/go-cid v0.0.1 + github.com/ipfs/go-datastore v0.0.1 + github.com/multiformats/go-base32 v0.0.3 +) diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/go.sum b/vendor/github.com/ipfs/go-ipfs-ds-help/go.sum new file mode 100644 index 00000000..6de64438 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/go.sum @@ -0,0 +1,38 @@ +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/key.go b/vendor/github.com/ipfs/go-ipfs-ds-help/key.go new file mode 100644 index 00000000..1f47023f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/key.go @@ -0,0 +1,36 @@ +// Package dshelp provides utilities for parsing and creating +// datastore keys used by go-ipfs +package dshelp + +import ( + cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + "github.com/multiformats/go-base32" +) + +// NewKeyFromBinary creates a new key from a byte slice. +func NewKeyFromBinary(rawKey []byte) datastore.Key { + buf := make([]byte, 1+base32.RawStdEncoding.EncodedLen(len(rawKey))) + buf[0] = '/' + base32.RawStdEncoding.Encode(buf[1:], rawKey) + return datastore.RawKey(string(buf)) +} + +// BinaryFromDsKey returns the byte slice corresponding to the given Key. +func BinaryFromDsKey(k datastore.Key) ([]byte, error) { + return base32.RawStdEncoding.DecodeString(k.String()[1:]) +} + +// CidToDsKey creates a Key from the given Cid. +func CidToDsKey(k cid.Cid) datastore.Key { + return NewKeyFromBinary(k.Bytes()) +} + +// DsKeyToCid converts the given Key to its corresponding Cid. +func DsKeyToCid(dsKey datastore.Key) (cid.Cid, error) { + kb, err := BinaryFromDsKey(dsKey) + if err != nil { + return cid.Cid{}, err + } + return cid.Cast(kb) +} diff --git a/vendor/github.com/ipfs/go-ipfs-ds-help/package.json b/vendor/github.com/ipfs/go-ipfs-ds-help/package.json new file mode 100644 index 00000000..830616eb --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-ds-help/package.json @@ -0,0 +1,36 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-ds-help" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-ds-help" + }, + "gxDependencies": [ + { + "author": "jbenet", + "hash": "QmUadX5EcvrBmxAV9sE7wUWtWSqxns5K84qKJBixmcT1w9", + "name": "go-datastore", + "version": "3.6.1" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "Golang", + "hash": "QmPbbYin7KBd1Y1BfUe15vHzwJiioyi3wtKQTtXWWf8SC5", + "name": "base32", + "version": "0.0.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-ipfs-ds-help", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.7" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/.travis.yml b/vendor/github.com/ipfs/go-ipfs-exchange-interface/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/LICENSE b/vendor/github.com/ipfs/go-ipfs-exchange-interface/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/Makefile b/vendor/github.com/ipfs/go-ipfs-exchange-interface/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/README.md b/vendor/github.com/ipfs/go-ipfs-exchange-interface/README.md new file mode 100644 index 00000000..8dbcfe1c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/README.md @@ -0,0 +1,42 @@ +# go-ipfs-exchange-interface + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-exchange-interface?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-exchange-interface) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-exchange-interface.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-exchange-interface) + +> go-ipfs-exchange-interface defines the IPFS exchange interface + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-exchange-interface` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-exchange-interface +``` + +## Usage + +``` +import "github.com/ipfs/go-ipfs-exchange-interface" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-exchange-interface) + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.mod b/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.mod new file mode 100644 index 00000000..fade39b9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-ipfs-exchange-interface + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.sum b/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.sum new file mode 100644 index 00000000..aa764c6a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/go.sum @@ -0,0 +1,26 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/interface.go b/vendor/github.com/ipfs/go-ipfs-exchange-interface/interface.go new file mode 100644 index 00000000..c3032b23 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/interface.go @@ -0,0 +1,37 @@ +// Package exchange defines the IPFS exchange interface +package exchange + +import ( + "context" + "io" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" +) + +// Interface defines the functionality of the IPFS block exchange protocol. +type Interface interface { // type Exchanger interface + Fetcher + + // TODO Should callers be concerned with whether the block was made + // available on the network? + HasBlock(blocks.Block) error + + IsOnline() bool + + io.Closer +} + +// Fetcher is an object that can be used to retrieve blocks +type Fetcher interface { + // GetBlock returns the block associated with a given key. + GetBlock(context.Context, cid.Cid) (blocks.Block, error) + GetBlocks(context.Context, []cid.Cid) (<-chan blocks.Block, error) +} + +// SessionExchange is an exchange.Interface which supports +// sessions. +type SessionExchange interface { + Interface + NewSession(context.Context) Fetcher +} diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-interface/package.json b/vendor/github.com/ipfs/go-ipfs-exchange-interface/package.json new file mode 100644 index 00000000..c5f83220 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-interface/package.json @@ -0,0 +1,30 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-exchange-interface" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-exchange-interface" + }, + "gxDependencies": [ + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-exchange-interface", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.3" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/.travis.yml b/vendor/github.com/ipfs/go-ipfs-exchange-offline/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/LICENSE b/vendor/github.com/ipfs/go-ipfs-exchange-offline/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/Makefile b/vendor/github.com/ipfs/go-ipfs-exchange-offline/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/README.md b/vendor/github.com/ipfs/go-ipfs-exchange-offline/README.md new file mode 100644 index 00000000..707099e9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/README.md @@ -0,0 +1,46 @@ +# go-ipfs-exchange-offline + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-exchange-offline?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-exchange-offline) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-exchange-offline.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-exchange-offline) + +> go-ipfs-exchange-offline implements the go-ipfs-exchange-interface + +This is an offline exchange implementation which will not perform any request. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-exchange-offline` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-exchange-offline +``` + +It uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies. + +## Usage + +``` +import "github.com/ipfs/go-ipfs-exchange-offline" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-exchange-offline) + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.mod b/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.mod new file mode 100644 index 00000000..5852ebda --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.mod @@ -0,0 +1,11 @@ +module github.com/ipfs/go-ipfs-exchange-offline + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.1 + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-ipfs-blockstore v0.0.1 + github.com/ipfs/go-ipfs-blocksutil v0.0.1 + github.com/ipfs/go-ipfs-exchange-interface v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.sum b/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.sum new file mode 100644 index 00000000..b52cb59a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/go.sum @@ -0,0 +1,82 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/offline.go b/vendor/github.com/ipfs/go-ipfs-exchange-offline/offline.go new file mode 100644 index 00000000..cb82b8a0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/offline.go @@ -0,0 +1,73 @@ +// package offline implements an object that implements the exchange +// interface but returns nil values to every request. +package offline + +import ( + "context" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" + exchange "github.com/ipfs/go-ipfs-exchange-interface" +) + +func Exchange(bs blockstore.Blockstore) exchange.Interface { + return &offlineExchange{bs: bs} +} + +// offlineExchange implements the Exchange interface but doesn't return blocks. +// For use in offline mode. +type offlineExchange struct { + bs blockstore.Blockstore +} + +// GetBlock returns nil to signal that a block could not be retrieved for the +// given key. +// NB: This function may return before the timeout expires. +func (e *offlineExchange) GetBlock(_ context.Context, k cid.Cid) (blocks.Block, error) { + return e.bs.Get(k) +} + +// HasBlock always returns nil. +func (e *offlineExchange) HasBlock(b blocks.Block) error { + return e.bs.Put(b) +} + +// Close always returns nil. +func (_ *offlineExchange) Close() error { + // NB: exchange doesn't own the blockstore's underlying datastore, so it is + // not responsible for closing it. + return nil +} + +func (e *offlineExchange) GetBlocks(ctx context.Context, ks []cid.Cid) (<-chan blocks.Block, error) { + out := make(chan blocks.Block) + go func() { + defer close(out) + var misses []cid.Cid + for _, k := range ks { + hit, err := e.bs.Get(k) + if err != nil { + misses = append(misses, k) + // a long line of misses should abort when context is cancelled. + select { + // TODO case send misses down channel + case <-ctx.Done(): + return + default: + continue + } + } + select { + case out <- hit: + case <-ctx.Done(): + return + } + } + }() + return out, nil +} + +func (e *offlineExchange) IsOnline() bool { + return false +} diff --git a/vendor/github.com/ipfs/go-ipfs-exchange-offline/package.json b/vendor/github.com/ipfs/go-ipfs-exchange-offline/package.json new file mode 100644 index 00000000..e356dd9f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-exchange-offline/package.json @@ -0,0 +1,48 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-exchange-offline" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-exchange-offline" + }, + "gxDependencies": [ + { + "author": "hsanjuan", + "hash": "QmXjKkjMDTtXAiLBwstVexofB8LeruZmE2eBd85GwGFFLA", + "name": "go-ipfs-blockstore", + "version": "0.1.8" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "hsanjuan", + "hash": "QmWokDcQdSZCxrNxgaRzQDDBofALhActzNBaxRLtiRkUHg", + "name": "go-ipfs-exchange-interface", + "version": "0.1.3" + }, + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "hsanjuan", + "hash": "QmcbQ44AgbtV1rnxZz5RsRVduxdgNYLANxnsuW5wvvu4ts", + "name": "go-ipfs-blocksutil", + "version": "0.1.2" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-exchange-offline", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.7" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-files/.travis.yml b/vendor/github.com/ipfs/go-ipfs-files/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-files/LICENSE b/vendor/github.com/ipfs/go-ipfs-files/LICENSE new file mode 100644 index 00000000..6cccfc2b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-files/README.md b/vendor/github.com/ipfs/go-ipfs-files/README.md new file mode 100644 index 00000000..4f704695 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/README.md @@ -0,0 +1,27 @@ +# go-ipfs-files + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) + +> File interfaces and utils used in IPFS + +## Documentation + +https://godoc.org/github.com/ipfs/go-ipfs-files + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-files/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + diff --git a/vendor/github.com/ipfs/go-ipfs-files/file.go b/vendor/github.com/ipfs/go-ipfs-files/file.go new file mode 100644 index 00000000..4d7ef113 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/file.go @@ -0,0 +1,94 @@ +package files + +import ( + "errors" + "io" + "os" +) + +var ( + ErrNotDirectory = errors.New("file isn't a directory") + ErrNotReader = errors.New("file isn't a regular file") + + ErrNotSupported = errors.New("operation not supported") +) + +// Node is a common interface for files, directories and other special files +type Node interface { + io.Closer + + // Size returns size of this file (if this file is a directory, total size of + // all files stored in the tree should be returned). Some implementations may + // choose not to implement this + Size() (int64, error) +} + +// Node represents a regular Unix file +type File interface { + Node + + io.Reader + io.Seeker +} + +// DirEntry exposes information about a directory entry +type DirEntry interface { + // Name returns base name of this entry, which is the base name of referenced + // file + Name() string + + // Node returns the file referenced by this DirEntry + Node() Node +} + +// DirIterator is a iterator over directory entries. +// See Directory.Entries for more +type DirIterator interface { + // DirEntry holds information about current directory entry. + // Note that after creating new iterator you MUST call Next() at least once + // before accessing these methods. Calling these methods without prior calls + // to Next() and after Next() returned false may result in undefined behavior + DirEntry + + // Next advances iterator to the next file. + Next() bool + + // Err may return an error after previous call to Next() returned `false`. + // If previous call to Next() returned `true`, Err() is guaranteed to + // return nil + Err() error +} + +// Directory is a special file which can link to any number of files. +type Directory interface { + Node + + // Entries returns a stateful iterator over directory entries. + // + // Example usage: + // + // it := dir.Entries() + // for it.Next() { + // name := it.Name() + // file := it.Node() + // [...] + // } + // if it.Err() != nil { + // return err + // } + // + // Note that you can't store the result of it.Node() and use it after + // advancing the iterator + Entries() DirIterator +} + +// FileInfo exposes information on files in local filesystem +type FileInfo interface { + Node + + // AbsPath returns full real file path. + AbsPath() string + + // Stat returns os.Stat of this file, may be nil for some files + Stat() os.FileInfo +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/go.mod b/vendor/github.com/ipfs/go-ipfs-files/go.mod new file mode 100644 index 00000000..1e70e551 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/go.mod @@ -0,0 +1,3 @@ +module github.com/ipfs/go-ipfs-files + +require golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 diff --git a/vendor/github.com/ipfs/go-ipfs-files/go.sum b/vendor/github.com/ipfs/go-ipfs-files/go.sum new file mode 100644 index 00000000..55a8c3a9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipfs-files/is_hidden.go b/vendor/github.com/ipfs/go-ipfs-files/is_hidden.go new file mode 100644 index 00000000..4ebca600 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/is_hidden.go @@ -0,0 +1,18 @@ +// +build !windows + +package files + +import ( + "path/filepath" + "strings" +) + +func IsHidden(name string, f Node) bool { + fName := filepath.Base(name) + + if strings.HasPrefix(fName, ".") && len(fName) > 1 { + return true + } + + return false +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/is_hidden_windows.go b/vendor/github.com/ipfs/go-ipfs-files/is_hidden_windows.go new file mode 100644 index 00000000..7419f932 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/is_hidden_windows.go @@ -0,0 +1,35 @@ +// +build windows + +package files + +import ( + "path/filepath" + "strings" + + windows "golang.org/x/sys/windows" +) + +func IsHidden(name string, f Node) bool { + + fName := filepath.Base(name) + + if strings.HasPrefix(fName, ".") && len(fName) > 1 { + return true + } + + fi, ok := f.(FileInfo) + if !ok { + return false + } + + p, e := windows.UTF16PtrFromString(fi.AbsPath()) + if e != nil { + return false + } + + attrs, e := windows.GetFileAttributes(p) + if e != nil { + return false + } + return attrs&windows.FILE_ATTRIBUTE_HIDDEN != 0 +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/linkfile.go b/vendor/github.com/ipfs/go-ipfs-files/linkfile.go new file mode 100644 index 00000000..409309bc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/linkfile.go @@ -0,0 +1,53 @@ +package files + +import ( + "io" + "os" + "strings" +) + +type Symlink struct { + Target string + stat os.FileInfo + + reader io.Reader +} + +func NewLinkFile(target string, stat os.FileInfo) File { + return &Symlink{ + Target: target, + stat: stat, + reader: strings.NewReader(target), + } +} + +func (lf *Symlink) Close() error { + if c, ok := lf.reader.(io.Closer); ok { + return c.Close() + } + + return nil +} + +func (lf *Symlink) Read(b []byte) (int, error) { + return lf.reader.Read(b) +} + +func (lf *Symlink) Seek(offset int64, whence int) (int64, error) { + if s, ok := lf.reader.(io.Seeker); ok { + return s.Seek(offset, whence) + } + + return 0, ErrNotSupported +} + +func (lf *Symlink) Size() (int64, error) { + return 0, ErrNotSupported +} + +func ToSymlink(n Node) *Symlink { + l, _ := n.(*Symlink) + return l +} + +var _ File = &Symlink{} diff --git a/vendor/github.com/ipfs/go-ipfs-files/multifilereader.go b/vendor/github.com/ipfs/go-ipfs-files/multifilereader.go new file mode 100644 index 00000000..86867f68 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/multifilereader.go @@ -0,0 +1,152 @@ +package files + +import ( + "bytes" + "fmt" + "io" + "mime/multipart" + "net/textproto" + "net/url" + "path" + "sync" +) + +// MultiFileReader reads from a `commands.Node` (which can be a directory of files +// or a regular file) as HTTP multipart encoded data. +type MultiFileReader struct { + io.Reader + + // directory stack for NextFile + files []DirIterator + path []string + + currentFile Node + buf bytes.Buffer + mpWriter *multipart.Writer + closed bool + mutex *sync.Mutex + + // if true, the data will be type 'multipart/form-data' + // if false, the data will be type 'multipart/mixed' + form bool +} + +// NewMultiFileReader constructs a MultiFileReader. `file` can be any `commands.Directory`. +// If `form` is set to true, the multipart data will have a Content-Type of 'multipart/form-data', +// if `form` is false, the Content-Type will be 'multipart/mixed'. +func NewMultiFileReader(file Directory, form bool) *MultiFileReader { + it := file.Entries() + + mfr := &MultiFileReader{ + files: []DirIterator{it}, + path: []string{""}, + form: form, + mutex: &sync.Mutex{}, + } + mfr.mpWriter = multipart.NewWriter(&mfr.buf) + + return mfr +} + +func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { + mfr.mutex.Lock() + defer mfr.mutex.Unlock() + + // if we are closed and the buffer is flushed, end reading + if mfr.closed && mfr.buf.Len() == 0 { + return 0, io.EOF + } + + // if the current file isn't set, advance to the next file + if mfr.currentFile == nil { + var entry DirEntry + + for entry == nil { + if len(mfr.files) == 0 { + mfr.mpWriter.Close() + mfr.closed = true + return mfr.buf.Read(buf) + } + + if !mfr.files[len(mfr.files)-1].Next() { + if mfr.files[len(mfr.files)-1].Err() != nil { + return 0, mfr.files[len(mfr.files)-1].Err() + } + mfr.files = mfr.files[:len(mfr.files)-1] + mfr.path = mfr.path[:len(mfr.path)-1] + continue + } + + entry = mfr.files[len(mfr.files)-1] + } + + // handle starting a new file part + if !mfr.closed { + + mfr.currentFile = entry.Node() + + // write the boundary and headers + header := make(textproto.MIMEHeader) + filename := url.QueryEscape(path.Join(path.Join(mfr.path...), entry.Name())) + dispositionPrefix := "attachment" + if mfr.form { + dispositionPrefix = "form-data; name=\"file\"" + } + + header.Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", dispositionPrefix, filename)) + + var contentType string + + switch f := entry.Node().(type) { + case *Symlink: + contentType = "application/symlink" + case Directory: + newIt := f.Entries() + mfr.files = append(mfr.files, newIt) + mfr.path = append(mfr.path, entry.Name()) + contentType = "application/x-directory" + case File: + // otherwise, use the file as a reader to read its contents + contentType = "application/octet-stream" + default: + return 0, ErrNotSupported + } + + header.Set("Content-Type", contentType) + if rf, ok := entry.Node().(FileInfo); ok { + header.Set("abspath", rf.AbsPath()) + } + + _, err := mfr.mpWriter.CreatePart(header) + if err != nil { + return 0, err + } + } + } + + // if the buffer has something in it, read from it + if mfr.buf.Len() > 0 { + return mfr.buf.Read(buf) + } + + // otherwise, read from file data + switch f := mfr.currentFile.(type) { + case File: + written, err = f.Read(buf) + if err != io.EOF { + return written, err + } + } + + if err := mfr.currentFile.Close(); err != nil { + return written, err + } + + mfr.currentFile = nil + return written, nil +} + +// Boundary returns the boundary string to be used to separate files in the multipart data +func (mfr *MultiFileReader) Boundary() string { + return mfr.mpWriter.Boundary() +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go b/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go new file mode 100644 index 00000000..d4593ad6 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/multipartfile.go @@ -0,0 +1,228 @@ +package files + +import ( + "io" + "io/ioutil" + "mime" + "mime/multipart" + "net/url" + "path" + "strings" +) + +const ( + multipartFormdataType = "multipart/form-data" + multipartMixedType = "multipart/mixed" + + applicationDirectory = "application/x-directory" + applicationSymlink = "application/symlink" + applicationFile = "application/octet-stream" + + contentTypeHeader = "Content-Type" +) + +type multipartDirectory struct { + path string + walker *multipartWalker + + // part is the part describing the directory. It's nil when implicit. + part *multipart.Part +} + +type multipartWalker struct { + part *multipart.Part + reader *multipart.Reader +} + +func (m *multipartWalker) consumePart() { + m.part = nil +} + +func (m *multipartWalker) getPart() (*multipart.Part, error) { + if m.part != nil { + return m.part, nil + } + if m.reader == nil { + return nil, io.EOF + } + + var err error + m.part, err = m.reader.NextPart() + if err == io.EOF { + m.reader = nil + } + return m.part, err +} + +// NewFileFromPartReader creates a Directory from a multipart reader. +func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (Directory, error) { + switch mediatype { + case applicationDirectory, multipartFormdataType: + default: + return nil, ErrNotDirectory + } + + return &multipartDirectory{ + path: "/", + walker: &multipartWalker{ + reader: reader, + }, + }, nil +} + +func (w *multipartWalker) nextFile() (Node, error) { + part, err := w.getPart() + if err != nil { + return nil, err + } + w.consumePart() + + contentType := part.Header.Get(contentTypeHeader) + if contentType != "" { + var err error + contentType, _, err = mime.ParseMediaType(contentType) + if err != nil { + return nil, err + } + } + + switch contentType { + case multipartFormdataType, applicationDirectory: + return &multipartDirectory{ + part: part, + path: fileName(part), + walker: w, + }, nil + case applicationSymlink: + out, err := ioutil.ReadAll(part) + if err != nil { + return nil, err + } + + return NewLinkFile(string(out), nil), nil + default: + return &ReaderFile{ + reader: part, + abspath: part.Header.Get("abspath"), + }, nil + } +} + +// fileName returns a normalized filename from a part. +func fileName(part *multipart.Part) string { + filename := part.FileName() + if escaped, err := url.QueryUnescape(filename); err == nil { + filename = escaped + } // if there is a unescape error, just treat the name as unescaped + + return path.Clean("/" + filename) +} + +// dirName appends a slash to the end of the filename, if not present. +// expects a _cleaned_ path. +func dirName(filename string) string { + if !strings.HasSuffix(filename, "/") { + filename += "/" + } + return filename +} + +// isChild checks if child is a child of parent directory. +// expects a _cleaned_ path. +func isChild(child, parent string) bool { + return strings.HasPrefix(child, dirName(parent)) +} + +// makeRelative makes the child path relative to the parent path. +// expects a _cleaned_ path. +func makeRelative(child, parent string) string { + return strings.TrimPrefix(child, dirName(parent)) +} + +type multipartIterator struct { + f *multipartDirectory + + curFile Node + curName string + err error +} + +func (it *multipartIterator) Name() string { + return it.curName +} + +func (it *multipartIterator) Node() Node { + return it.curFile +} + +func (it *multipartIterator) Next() bool { + if it.f.walker.reader == nil || it.err != nil { + return false + } + var part *multipart.Part + for { + part, it.err = it.f.walker.getPart() + if it.err != nil { + return false + } + + name := fileName(part) + + // Is the file in a different directory? + if !isChild(name, it.f.path) { + return false + } + + // Have we already entered this directory? + if it.curName != "" && isChild(name, path.Join(it.f.path, it.curName)) { + it.f.walker.consumePart() + continue + } + + // Make the path relative to the current directory. + name = makeRelative(name, it.f.path) + + // Check if we need to create a fake directory (more than one + // path component). + if idx := strings.IndexByte(name, '/'); idx >= 0 { + it.curName = name[:idx] + it.curFile = &multipartDirectory{ + path: path.Join(it.f.path, it.curName), + walker: it.f.walker, + } + return true + } + it.curName = name + + // Finally, advance to the next file. + it.curFile, it.err = it.f.walker.nextFile() + + return it.err == nil + } +} + +func (it *multipartIterator) Err() error { + // We use EOF to signal that this iterator is done. That way, we don't + // need to check every time `Next` is called. + if it.err == io.EOF { + return nil + } + return it.err +} + +func (f *multipartDirectory) Entries() DirIterator { + return &multipartIterator{f: f} +} + +func (f *multipartDirectory) Close() error { + if f.part != nil { + return f.part.Close() + } + return nil +} + +func (f *multipartDirectory) Size() (int64, error) { + return 0, ErrNotSupported +} + +var _ Directory = &multipartDirectory{} diff --git a/vendor/github.com/ipfs/go-ipfs-files/package.json b/vendor/github.com/ipfs/go-ipfs-files/package.json new file mode 100644 index 00000000..967f2e79 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/package.json @@ -0,0 +1,24 @@ +{ + "author": "magik6k", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-files" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-files" + }, + "gxDependencies": [ + { + "author": "The Go Authors", + "hash": "QmVGjyM9i2msKvLXwh9VosCTgP4mL91kC7hDmqnwTTx6Hu", + "name": "sys", + "version": "0.2.0" + } + ], + "gxVersion": "0.11.0", + "language": "go", + "license": "", + "name": "go-ipfs-files", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "2.0.7" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-files/readerfile.go b/vendor/github.com/ipfs/go-ipfs-files/readerfile.go new file mode 100644 index 00000000..f98fec48 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/readerfile.go @@ -0,0 +1,82 @@ +package files + +import ( + "bytes" + "io" + "io/ioutil" + "os" + "path/filepath" +) + +// ReaderFile is a implementation of File created from an `io.Reader`. +// ReaderFiles are never directories, and can be read from and closed. +type ReaderFile struct { + abspath string + reader io.ReadCloser + stat os.FileInfo + + fsize int64 +} + +func NewBytesFile(b []byte) File { + return &ReaderFile{"", NewReaderFile(bytes.NewReader(b)), nil, int64(len(b))} +} + +func NewReaderFile(reader io.Reader) File { + return NewReaderStatFile(reader, nil) +} + +func NewReaderStatFile(reader io.Reader, stat os.FileInfo) File { + rc, ok := reader.(io.ReadCloser) + if !ok { + rc = ioutil.NopCloser(reader) + } + + return &ReaderFile{"", rc, stat, -1} +} + +func NewReaderPathFile(path string, reader io.ReadCloser, stat os.FileInfo) (*ReaderFile, error) { + abspath, err := filepath.Abs(path) + if err != nil { + return nil, err + } + + return &ReaderFile{abspath, reader, stat, -1}, nil +} + +func (f *ReaderFile) AbsPath() string { + return f.abspath +} + +func (f *ReaderFile) Read(p []byte) (int, error) { + return f.reader.Read(p) +} + +func (f *ReaderFile) Close() error { + return f.reader.Close() +} + +func (f *ReaderFile) Stat() os.FileInfo { + return f.stat +} + +func (f *ReaderFile) Size() (int64, error) { + if f.stat == nil { + if f.fsize >= 0 { + return f.fsize, nil + } + return 0, ErrNotSupported + } + return f.stat.Size(), nil +} + +func (f *ReaderFile) Seek(offset int64, whence int) (int64, error) { + if s, ok := f.reader.(io.Seeker); ok { + return s.Seek(offset, whence) + } + + return 0, ErrNotSupported +} + +var _ File = &ReaderFile{} +var _ FileInfo = &ReaderFile{} diff --git a/vendor/github.com/ipfs/go-ipfs-files/serialfile.go b/vendor/github.com/ipfs/go-ipfs-files/serialfile.go new file mode 100644 index 00000000..e29752d6 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/serialfile.go @@ -0,0 +1,178 @@ +package files + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" +) + +// serialFile implements Node, and reads from a path on the OS filesystem. +// No more than one file will be opened at a time (directories will advance +// to the next file when NextFile() is called). +type serialFile struct { + path string + files []os.FileInfo + stat os.FileInfo + handleHiddenFiles bool +} + +type serialIterator struct { + files []os.FileInfo + handleHiddenFiles bool + path string + + curName string + curFile Node + + err error +} + +// TODO: test/document limitations +func NewSerialFile(path string, hidden bool, stat os.FileInfo) (Node, error) { + switch mode := stat.Mode(); { + case mode.IsRegular(): + file, err := os.Open(path) + if err != nil { + return nil, err + } + return NewReaderPathFile(path, file, stat) + case mode.IsDir(): + // for directories, stat all of the contents first, so we know what files to + // open when NextFile() is called + contents, err := ioutil.ReadDir(path) + if err != nil { + return nil, err + } + return &serialFile{path, contents, stat, hidden}, nil + case mode&os.ModeSymlink != 0: + target, err := os.Readlink(path) + if err != nil { + return nil, err + } + return NewLinkFile(target, stat), nil + default: + return nil, fmt.Errorf("unrecognized file type for %s: %s", path, mode.String()) + } +} + +func (it *serialIterator) Name() string { + return it.curName +} + +func (it *serialIterator) Node() Node { + return it.curFile +} + +func (it *serialIterator) Next() bool { + // if there aren't any files left in the root directory, we're done + if len(it.files) == 0 { + return false + } + + stat := it.files[0] + it.files = it.files[1:] + for !it.handleHiddenFiles && strings.HasPrefix(stat.Name(), ".") { + if len(it.files) == 0 { + return false + } + + stat = it.files[0] + it.files = it.files[1:] + } + + // open the next file + filePath := filepath.ToSlash(filepath.Join(it.path, stat.Name())) + + // recursively call the constructor on the next file + // if it's a regular file, we will open it as a ReaderFile + // if it's a directory, files in it will be opened serially + sf, err := NewSerialFile(filePath, it.handleHiddenFiles, stat) + if err != nil { + it.err = err + return false + } + + it.curName = stat.Name() + it.curFile = sf + return true +} + +func (it *serialIterator) Err() error { + return it.err +} + +func (f *serialFile) Entries() DirIterator { + return &serialIterator{ + path: f.path, + files: f.files, + handleHiddenFiles: f.handleHiddenFiles, + } +} + +func (f *serialFile) NextFile() (string, Node, error) { + // if there aren't any files left in the root directory, we're done + if len(f.files) == 0 { + return "", nil, io.EOF + } + + stat := f.files[0] + f.files = f.files[1:] + + for !f.handleHiddenFiles && strings.HasPrefix(stat.Name(), ".") { + if len(f.files) == 0 { + return "", nil, io.EOF + } + + stat = f.files[0] + f.files = f.files[1:] + } + + // open the next file + filePath := filepath.ToSlash(filepath.Join(f.path, stat.Name())) + + // recursively call the constructor on the next file + // if it's a regular file, we will open it as a ReaderFile + // if it's a directory, files in it will be opened serially + sf, err := NewSerialFile(filePath, f.handleHiddenFiles, stat) + if err != nil { + return "", nil, err + } + + return stat.Name(), sf, nil +} + +func (f *serialFile) Close() error { + return nil +} + +func (f *serialFile) Stat() os.FileInfo { + return f.stat +} + +func (f *serialFile) Size() (int64, error) { + if !f.stat.IsDir() { + //something went terribly, terribly wrong + return 0, errors.New("serialFile is not a directory") + } + + var du int64 + err := filepath.Walk(f.path, func(p string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + if fi != nil && fi.Mode().IsRegular() { + du += fi.Size() + } + return nil + }) + + return du, err +} + +var _ Directory = &serialFile{} +var _ DirIterator = &serialIterator{} diff --git a/vendor/github.com/ipfs/go-ipfs-files/slicedirectory.go b/vendor/github.com/ipfs/go-ipfs-files/slicedirectory.go new file mode 100644 index 00000000..d1165626 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/slicedirectory.go @@ -0,0 +1,97 @@ +package files + +import "sort" + +type fileEntry struct { + name string + file Node +} + +func (e fileEntry) Name() string { + return e.name +} + +func (e fileEntry) Node() Node { + return e.file +} + +func FileEntry(name string, file Node) DirEntry { + return fileEntry{ + name: name, + file: file, + } +} + +type sliceIterator struct { + files []DirEntry + n int +} + +func (it *sliceIterator) Name() string { + return it.files[it.n].Name() +} + +func (it *sliceIterator) Node() Node { + return it.files[it.n].Node() +} + +func (it *sliceIterator) Next() bool { + it.n++ + return it.n < len(it.files) +} + +func (it *sliceIterator) Err() error { + return nil +} + +// SliceFile implements Node, and provides simple directory handling. +// It contains children files, and is created from a `[]Node`. +// SliceFiles are always directories, and can't be read from or closed. +type SliceFile struct { + files []DirEntry +} + +func NewMapDirectory(f map[string]Node) Directory { + ents := make([]DirEntry, 0, len(f)) + for name, nd := range f { + ents = append(ents, FileEntry(name, nd)) + } + sort.Slice(ents, func(i, j int) bool { + return ents[i].Name() < ents[j].Name() + }) + + return NewSliceDirectory(ents) +} + +func NewSliceDirectory(files []DirEntry) Directory { + return &SliceFile{files} +} + +func (f *SliceFile) Entries() DirIterator { + return &sliceIterator{files: f.files, n: -1} +} + +func (f *SliceFile) Close() error { + return nil +} + +func (f *SliceFile) Length() int { + return len(f.files) +} + +func (f *SliceFile) Size() (int64, error) { + var size int64 + + for _, file := range f.files { + s, err := file.Node().Size() + if err != nil { + return 0, err + } + size += s + } + + return size, nil +} + +var _ Directory = &SliceFile{} +var _ DirEntry = fileEntry{} diff --git a/vendor/github.com/ipfs/go-ipfs-files/tarwriter.go b/vendor/github.com/ipfs/go-ipfs-files/tarwriter.go new file mode 100644 index 00000000..6d062726 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/tarwriter.go @@ -0,0 +1,100 @@ +package files + +import ( + "archive/tar" + "fmt" + "io" + "path" + "time" +) + +type TarWriter struct { + TarW *tar.Writer +} + +// NewTarWriter wraps given io.Writer into a new tar writer +func NewTarWriter(w io.Writer) (*TarWriter, error) { + return &TarWriter{ + TarW: tar.NewWriter(w), + }, nil +} + +func (w *TarWriter) writeDir(f Directory, fpath string) error { + if err := writeDirHeader(w.TarW, fpath); err != nil { + return err + } + + it := f.Entries() + for it.Next() { + if err := w.WriteFile(it.Node(), path.Join(fpath, it.Name())); err != nil { + return err + } + } + return it.Err() +} + +func (w *TarWriter) writeFile(f File, fpath string) error { + size, err := f.Size() + if err != nil { + return err + } + + if err := writeFileHeader(w.TarW, fpath, uint64(size)); err != nil { + return err + } + + if _, err := io.Copy(w.TarW, f); err != nil { + return err + } + w.TarW.Flush() + return nil +} + +// WriteNode adds a node to the archive. +func (w *TarWriter) WriteFile(nd Node, fpath string) error { + switch nd := nd.(type) { + case *Symlink: + return writeSymlinkHeader(w.TarW, nd.Target, fpath) + case File: + return w.writeFile(nd, fpath) + case Directory: + return w.writeDir(nd, fpath) + default: + return fmt.Errorf("file type %T is not supported", nd) + } +} + +// Close closes the tar writer. +func (w *TarWriter) Close() error { + return w.TarW.Close() +} + +func writeDirHeader(w *tar.Writer, fpath string) error { + return w.WriteHeader(&tar.Header{ + Name: fpath, + Typeflag: tar.TypeDir, + Mode: 0777, + ModTime: time.Now(), + // TODO: set mode, dates, etc. when added to unixFS + }) +} + +func writeFileHeader(w *tar.Writer, fpath string, size uint64) error { + return w.WriteHeader(&tar.Header{ + Name: fpath, + Size: int64(size), + Typeflag: tar.TypeReg, + Mode: 0644, + ModTime: time.Now(), + // TODO: set mode, dates, etc. when added to unixFS + }) +} + +func writeSymlinkHeader(w *tar.Writer, target, fpath string) error { + return w.WriteHeader(&tar.Header{ + Name: fpath, + Linkname: target, + Mode: 0777, + Typeflag: tar.TypeSymlink, + }) +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/util.go b/vendor/github.com/ipfs/go-ipfs-files/util.go new file mode 100644 index 00000000..e727e7ae --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/util.go @@ -0,0 +1,25 @@ +package files + +// ToFile is an alias for n.(File). If the file isn't a regular file, nil value +// will be returned +func ToFile(n Node) File { + f, _ := n.(File) + return f +} + +// ToDir is an alias for n.(Directory). If the file isn't directory, a nil value +// will be returned +func ToDir(n Node) Directory { + d, _ := n.(Directory) + return d +} + +// FileFromEntry calls ToFile on Node in the given entry +func FileFromEntry(e DirEntry) File { + return ToFile(e.Node()) +} + +// DirFromEntry calls ToDir on Node in the given entry +func DirFromEntry(e DirEntry) Directory { + return ToDir(e.Node()) +} diff --git a/vendor/github.com/ipfs/go-ipfs-files/webfile.go b/vendor/github.com/ipfs/go-ipfs-files/webfile.go new file mode 100644 index 00000000..594b81c8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-files/webfile.go @@ -0,0 +1,89 @@ +package files + +import ( + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" +) + +// WebFile is an implementation of File which reads it +// from a Web URL (http). A GET request will be performed +// against the source when calling Read(). +type WebFile struct { + body io.ReadCloser + url *url.URL + contentLength int64 +} + +// NewWebFile creates a WebFile with the given URL, which +// will be used to perform the GET request on Read(). +func NewWebFile(url *url.URL) *WebFile { + return &WebFile{ + url: url, + } +} + +func (wf *WebFile) start() error { + if wf.body == nil { + s := wf.url.String() + resp, err := http.Get(s) + if err != nil { + return err + } + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return fmt.Errorf("got non-2XX status code %d: %s", resp.StatusCode, s) + } + wf.body = resp.Body + wf.contentLength = resp.ContentLength + } + return nil +} + +// Read reads the File from it's web location. On the first +// call to Read, a GET request will be performed against the +// WebFile's URL, using Go's default HTTP client. Any further +// reads will keep reading from the HTTP Request body. +func (wf *WebFile) Read(b []byte) (int, error) { + if err := wf.start(); err != nil { + return 0, err + } + return wf.body.Read(b) +} + +// Close closes the WebFile (or the request body). +func (wf *WebFile) Close() error { + if wf.body == nil { + return nil + } + return wf.body.Close() +} + +// TODO: implement +func (wf *WebFile) Seek(offset int64, whence int) (int64, error) { + return 0, ErrNotSupported +} + +func (wf *WebFile) Size() (int64, error) { + if err := wf.start(); err != nil { + return 0, err + } + if wf.contentLength < 0 { + return -1, errors.New("Content-Length hearer was not set") + } + + return wf.contentLength, nil +} + +func (wf *WebFile) AbsPath() string { + return wf.url.String() +} + +func (wf *WebFile) Stat() os.FileInfo { + return nil +} + +var _ File = &WebFile{} +var _ FileInfo = &WebFile{} diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/.gitignore b/vendor/github.com/ipfs/go-ipfs-posinfo/.gitignore new file mode 100644 index 00000000..a1338d68 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/.gitignore @@ -0,0 +1,14 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/.travis.yml b/vendor/github.com/ipfs/go-ipfs-posinfo/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/LICENSE b/vendor/github.com/ipfs/go-ipfs-posinfo/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/Makefile b/vendor/github.com/ipfs/go-ipfs-posinfo/Makefile new file mode 100644 index 00000000..24d71558 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + go test -v -covermode count -coverprofile=coverage.out . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/README.md b/vendor/github.com/ipfs/go-ipfs-posinfo/README.md new file mode 100644 index 00000000..bd509c17 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/README.md @@ -0,0 +1,37 @@ +# go-ipfs-posinfo + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-posinfo?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-posinfo) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-posinfo.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-posinfo) + +> Posinfo wraps offset information for ipfs filestore nodes + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +``` +go get github.com/ipfs/go-ipfs-posinfo +``` + +## Usage + +See the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-posinfo) + + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/go.mod b/vendor/github.com/ipfs/go-ipfs-posinfo/go.mod new file mode 100644 index 00000000..d0064084 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/go.mod @@ -0,0 +1,3 @@ +module github.com/ipfs/go-ipfs-posinfo + +require github.com/ipfs/go-ipld-format v0.0.1 diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/go.sum b/vendor/github.com/ipfs/go-ipfs-posinfo/go.sum new file mode 100644 index 00000000..9e2d1534 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/go.sum @@ -0,0 +1,28 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/package.json b/vendor/github.com/ipfs/go-ipfs-posinfo/package.json new file mode 100644 index 00000000..f1815f58 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/package.json @@ -0,0 +1,24 @@ +{ + "author": "hector", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-posinfo" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-posinfo" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-posinfo", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.5" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-posinfo/posinfo.go b/vendor/github.com/ipfs/go-ipfs-posinfo/posinfo.go new file mode 100644 index 00000000..0b32c89d --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-posinfo/posinfo.go @@ -0,0 +1,23 @@ +// Package posinfo wraps offset information used by ipfs filestore nodes +package posinfo + +import ( + "os" + + ipld "github.com/ipfs/go-ipld-format" +) + +// PosInfo stores information about the file offset, its path and +// stat. +type PosInfo struct { + Offset uint64 + FullPath string + Stat os.FileInfo // can be nil +} + +// FilestoreNode is an ipld.Node which arries PosInfo with it +// allowing to map it directly to a filesystem object. +type FilestoreNode struct { + ipld.Node + PosInfo *PosInfo +} diff --git a/vendor/github.com/ipfs/go-ipfs-pq/.travis.yml b/vendor/github.com/ipfs/go-ipfs-pq/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-pq/LICENSE b/vendor/github.com/ipfs/go-ipfs-pq/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-pq/Makefile b/vendor/github.com/ipfs/go-ipfs-pq/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-ipfs-pq/README.md b/vendor/github.com/ipfs/go-ipfs-pq/README.md new file mode 100644 index 00000000..df2157fc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/README.md @@ -0,0 +1,42 @@ +# go-ipfs-pq + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs-pq?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs-pq) +[![Build Status](https://travis-ci.org/ipfs/go-ipfs-pq.svg?branch=master)](https://travis-ci.org/ipfs/go-ipfs-pq) + +> go-ipfs-pq implements a priority queue. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-ipfs-pq` works like a regular Go module: + +``` +> go get github.com/ipfs/go-ipfs-pq +``` + +## Usage + +``` +import "github.com/ipfs/go-ipfs-pq" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-pq) + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-ipfs-pq/go.mod b/vendor/github.com/ipfs/go-ipfs-pq/go.mod new file mode 100644 index 00000000..28b98ba0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/go.mod @@ -0,0 +1 @@ +module github.com/ipfs/go-ipfs-pq diff --git a/vendor/github.com/ipfs/go-ipfs-pq/package.json b/vendor/github.com/ipfs/go-ipfs-pq/package.json new file mode 100644 index 00000000..329e1c13 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/package.json @@ -0,0 +1,16 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-ipfs-pq" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-pq" + }, + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipfs-pq", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.0.1" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-pq/pq.go b/vendor/github.com/ipfs/go-ipfs-pq/pq.go new file mode 100644 index 00000000..28f40616 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-pq/pq.go @@ -0,0 +1,106 @@ +// Package pq implements a priority queue. +package pq + +import "container/heap" + +// PQ is a basic priority queue. +type PQ interface { + // Push adds the ele + Push(Elem) + // Pop returns the highest priority Elem in PQ. + Pop() Elem + // Len returns the number of elements in the PQ. + Len() int + // Update `fixes` the PQ. + Update(index int) + + // TODO explain why this interface should not be extended + // It does not support Remove. This is because... +} + +// Elem describes elements that can be added to the PQ. Clients must implement +// this interface. +type Elem interface { + // SetIndex stores the int index. + SetIndex(int) + // Index returns the last given by SetIndex(int). + Index() int +} + +// ElemComparator returns true if pri(a) > pri(b) +type ElemComparator func(a, b Elem) bool + +// New creates a PQ with a client-supplied comparator. +func New(cmp ElemComparator) PQ { + q := &wrapper{heapinterface{ + elems: make([]Elem, 0), + cmp: cmp, + }} + heap.Init(&q.heapinterface) + return q +} + +// wrapper exists because we cannot re-define Push. We want to expose +// Push(Elem) but heap.Interface requires Push(interface{}) +type wrapper struct { + heapinterface +} + +var _ PQ = &wrapper{} + +func (w *wrapper) Push(e Elem) { + heap.Push(&w.heapinterface, e) +} + +func (w *wrapper) Pop() Elem { + return heap.Pop(&w.heapinterface).(Elem) +} + +func (w *wrapper) Update(index int) { + heap.Fix(&w.heapinterface, index) +} + +// heapinterface handles dirty low-level details of managing the priority queue. +type heapinterface struct { + elems []Elem + cmp ElemComparator +} + +var _ heap.Interface = &heapinterface{} + +// public interface + +func (q *heapinterface) Len() int { + return len(q.elems) +} + +// Less delegates the decision to the comparator +func (q *heapinterface) Less(i, j int) bool { + return q.cmp(q.elems[i], q.elems[j]) +} + +// Swap swaps the elements with indexes i and j. +func (q *heapinterface) Swap(i, j int) { + q.elems[i], q.elems[j] = q.elems[j], q.elems[i] + q.elems[i].SetIndex(i) + q.elems[j].SetIndex(j) +} + +// Note that Push and Pop in this interface are for package heap's +// implementation to call. To add and remove things from the heap, wrap with +// the pq struct to call heap.Push and heap.Pop. + +func (q *heapinterface) Push(x interface{}) { // where to put the elem? + t := x.(Elem) + t.SetIndex(len(q.elems)) + q.elems = append(q.elems, t) +} + +func (q *heapinterface) Pop() interface{} { + old := q.elems + n := len(old) + elem := old[n-1] // remove the last + elem.SetIndex(-1) // for safety // FIXME why? + q.elems = old[0 : n-1] // shrink + return elem +} diff --git a/vendor/github.com/ipfs/go-ipfs-routing/LICENSE b/vendor/github.com/ipfs/go-ipfs-routing/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-routing/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-routing/none/none_client.go b/vendor/github.com/ipfs/go-ipfs-routing/none/none_client.go new file mode 100644 index 00000000..9604ab07 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-routing/none/none_client.go @@ -0,0 +1,57 @@ +// Package nilrouting implements a routing client that does nothing. +package nilrouting + +import ( + "context" + "errors" + + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + record "github.com/libp2p/go-libp2p-record" +) + +type nilclient struct { +} + +func (c *nilclient) PutValue(_ context.Context, _ string, _ []byte, _ ...routing.Option) error { + return nil +} + +func (c *nilclient) GetValue(_ context.Context, _ string, _ ...routing.Option) ([]byte, error) { + return nil, errors.New("tried GetValue from nil routing") +} + +func (c *nilclient) SearchValue(_ context.Context, _ string, _ ...routing.Option) (<-chan []byte, error) { + return nil, errors.New("tried SearchValue from nil routing") +} + +func (c *nilclient) FindPeer(_ context.Context, _ peer.ID) (peer.AddrInfo, error) { + return peer.AddrInfo{}, nil +} + +func (c *nilclient) FindProvidersAsync(_ context.Context, _ cid.Cid, _ int) <-chan peer.AddrInfo { + out := make(chan peer.AddrInfo) + defer close(out) + return out +} + +func (c *nilclient) Provide(_ context.Context, _ cid.Cid, _ bool) error { + return nil +} + +func (c *nilclient) Bootstrap(_ context.Context) error { + return nil +} + +// ConstructNilRouting creates an Routing client which does nothing. +func ConstructNilRouting(_ context.Context, _ host.Host, _ ds.Batching, _ record.Validator) (routing.Routing, error) { + return &nilclient{}, nil +} + +// ensure nilclient satisfies interface +var _ routing.Routing = &nilclient{} diff --git a/vendor/github.com/ipfs/go-ipfs-routing/offline/offline.go b/vendor/github.com/ipfs/go-ipfs-routing/offline/offline.go new file mode 100644 index 00000000..c76f9209 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-routing/offline/offline.go @@ -0,0 +1,128 @@ +// Package offline implements Routing with a client which +// is only able to perform offline operations. +package offline + +import ( + "bytes" + "context" + "errors" + "time" + + proto "github.com/gogo/protobuf/proto" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + record "github.com/libp2p/go-libp2p-record" + pb "github.com/libp2p/go-libp2p-record/pb" +) + +// ErrOffline is returned when trying to perform operations that +// require connectivity. +var ErrOffline = errors.New("routing system in offline mode") + +// NewOfflineRouter returns an Routing implementation which only performs +// offline operations. It allows to Put and Get signed dht +// records to and from the local datastore. +func NewOfflineRouter(dstore ds.Datastore, validator record.Validator) routing.Routing { + return &offlineRouting{ + datastore: dstore, + validator: validator, + } +} + +// offlineRouting implements the Routing interface, +// but only provides the capability to Put and Get signed dht +// records to and from the local datastore. +type offlineRouting struct { + datastore ds.Datastore + validator record.Validator +} + +func (c *offlineRouting) PutValue(ctx context.Context, key string, val []byte, _ ...routing.Option) error { + if err := c.validator.Validate(key, val); err != nil { + return err + } + if old, err := c.GetValue(ctx, key); err == nil { + // be idempotent to be nice. + if bytes.Equal(old, val) { + return nil + } + // check to see if the older record is better + i, err := c.validator.Select(key, [][]byte{val, old}) + if err != nil { + // this shouldn't happen for validated records. + return err + } + if i != 0 { + return errors.New("can't replace a newer record with an older one") + } + } + rec := record.MakePutRecord(key, val) + data, err := proto.Marshal(rec) + if err != nil { + return err + } + + return c.datastore.Put(dshelp.NewKeyFromBinary([]byte(key)), data) +} + +func (c *offlineRouting) GetValue(ctx context.Context, key string, _ ...routing.Option) ([]byte, error) { + buf, err := c.datastore.Get(dshelp.NewKeyFromBinary([]byte(key))) + if err != nil { + return nil, err + } + + rec := new(pb.Record) + err = proto.Unmarshal(buf, rec) + if err != nil { + return nil, err + } + val := rec.GetValue() + + err = c.validator.Validate(key, val) + if err != nil { + return nil, err + } + return val, nil +} + +func (c *offlineRouting) SearchValue(ctx context.Context, key string, _ ...routing.Option) (<-chan []byte, error) { + out := make(chan []byte, 1) + go func() { + defer close(out) + v, err := c.GetValue(ctx, key) + if err == nil { + out <- v + } + }() + return out, nil +} + +func (c *offlineRouting) FindPeer(ctx context.Context, pid peer.ID) (peer.AddrInfo, error) { + return peer.AddrInfo{}, ErrOffline +} + +func (c *offlineRouting) FindProvidersAsync(ctx context.Context, k cid.Cid, max int) <-chan peer.AddrInfo { + out := make(chan peer.AddrInfo) + close(out) + return out +} + +func (c *offlineRouting) Provide(_ context.Context, k cid.Cid, _ bool) error { + return ErrOffline +} + +func (c *offlineRouting) Ping(ctx context.Context, p peer.ID) (time.Duration, error) { + return 0, ErrOffline +} + +func (c *offlineRouting) Bootstrap(context.Context) error { + return nil +} + +// ensure offlineRouting matches the Routing interface +var _ routing.Routing = &offlineRouting{} diff --git a/vendor/github.com/ipfs/go-ipfs-util/.gitignore b/vendor/github.com/ipfs/go-ipfs-util/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/ipfs/go-ipfs-util/.travis.yml b/vendor/github.com/ipfs/go-ipfs-util/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipfs-util/LICENSE b/vendor/github.com/ipfs/go-ipfs-util/LICENSE new file mode 100644 index 00000000..9ce97444 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs-util/README.md b/vendor/github.com/ipfs/go-ipfs-util/README.md new file mode 100644 index 00000000..33bff12c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/README.md @@ -0,0 +1,45 @@ +# go-ipfs-util + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![](https://img.shields.io/badge/discussion_repo-go_to_issues-brightgreen.svg?style=flat-square)](https://github.com/ipfs/NAME/issues) + +> Common utilities used by go-ipfs and other related go packages + +## Install + +This is a Go module which can be installed with `go get github.com/ipfs/go-ipfs-util`. `go-ipfs-util` is however packaged with Gx, so it is recommended to use Gx to install it (see Usage section). + +## Usage + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). +In order to use it in your own project do: + +``` +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/ipfs/go-ipfs-util +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipfs-util/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT diff --git a/vendor/github.com/ipfs/go-ipfs-util/file.go b/vendor/github.com/ipfs/go-ipfs-util/file.go new file mode 100644 index 00000000..e6e30df4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/file.go @@ -0,0 +1,12 @@ +package util + +import "os" + +// FileExists check if the file with the given path exits. +func FileExists(filename string) bool { + fi, err := os.Lstat(filename) + if fi != nil || (err != nil && !os.IsNotExist(err)) { + return true + } + return false +} diff --git a/vendor/github.com/ipfs/go-ipfs-util/go.mod b/vendor/github.com/ipfs/go-ipfs-util/go.mod new file mode 100644 index 00000000..112c925b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-ipfs-util + +require ( + github.com/mr-tron/base58 v1.1.0 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipfs-util/go.sum b/vendor/github.com/ipfs/go-ipfs-util/go.sum new file mode 100644 index 00000000..25c9723e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/go.sum @@ -0,0 +1,16 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipfs-util/package.json b/vendor/github.com/ipfs/go-ipfs-util/package.json new file mode 100644 index 00000000..3c3ed116 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/package.json @@ -0,0 +1,28 @@ +{ + "author": "whyrusleeping", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipfs-util" + }, + "gxDependencies": [ + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "mr-tron", + "hash": "QmWFAMPqsEyUX7gDUsRVmMWz59FxSpJ1b2v6bJ1yYzo7jY", + "name": "go-base58-fast", + "version": "0.1.1" + } + ], + "gxVersion": "0.9.1", + "language": "go", + "license": "", + "name": "go-ipfs-util", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.2.9" +} + diff --git a/vendor/github.com/ipfs/go-ipfs-util/time.go b/vendor/github.com/ipfs/go-ipfs-util/time.go new file mode 100644 index 00000000..37d720fb --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/time.go @@ -0,0 +1,22 @@ +package util + +import "time" + +// TimeFormatIpfs is the format ipfs uses to represent time in string form. +var TimeFormatIpfs = time.RFC3339Nano + +// ParseRFC3339 parses an RFC3339Nano-formatted time stamp and +// returns the UTC time. +func ParseRFC3339(s string) (time.Time, error) { + t, err := time.Parse(TimeFormatIpfs, s) + if err != nil { + return time.Time{}, err + } + return t.UTC(), nil +} + +// FormatRFC3339 returns the string representation of the +// UTC value of the given time in RFC3339Nano format. +func FormatRFC3339(t time.Time) string { + return t.UTC().Format(TimeFormatIpfs) +} diff --git a/vendor/github.com/ipfs/go-ipfs-util/util.go b/vendor/github.com/ipfs/go-ipfs-util/util.go new file mode 100644 index 00000000..8ebe3c70 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs-util/util.go @@ -0,0 +1,158 @@ +// Package util implements various utility functions used within ipfs +// that do not currently have a better place to live. +package util + +import ( + "errors" + "io" + "math/rand" + "os" + "path/filepath" + "runtime/debug" + "strings" + "time" + + b58 "github.com/mr-tron/base58/base58" + mh "github.com/multiformats/go-multihash" +) + +// DefaultIpfsHash is the current default hash function used by IPFS. +const DefaultIpfsHash = mh.SHA2_256 + +// Debug is a global flag for debugging. +var Debug bool + +// ErrNotImplemented signifies a function has not been implemented yet. +var ErrNotImplemented = errors.New("Error: not implemented yet.") + +// ErrTimeout implies that a timeout has been triggered +var ErrTimeout = errors.New("Error: Call timed out.") + +// ErrSearchIncomplete implies that a search type operation didnt +// find the expected node, but did find 'a' node. +var ErrSearchIncomplete = errors.New("Error: Search Incomplete.") + +// ErrCast is returned when a cast fails AND the program should not panic. +func ErrCast() error { + debug.PrintStack() + return errCast +} + +var errCast = errors.New("cast error") + +// ExpandPathnames takes a set of paths and turns them into absolute paths +func ExpandPathnames(paths []string) ([]string, error) { + var out []string + for _, p := range paths { + abspath, err := filepath.Abs(p) + if err != nil { + return nil, err + } + out = append(out, abspath) + } + return out, nil +} + +type randGen struct { + rand.Rand +} + +// NewTimeSeededRand returns a random bytes reader +// which has been initialized with the current time. +func NewTimeSeededRand() io.Reader { + src := rand.NewSource(time.Now().UnixNano()) + return &randGen{ + Rand: *rand.New(src), + } +} + +// NewSeededRand returns a random bytes reader +// initialized with the given seed. +func NewSeededRand(seed int64) io.Reader { + src := rand.NewSource(seed) + return &randGen{ + Rand: *rand.New(src), + } +} + +func (r *randGen) Read(p []byte) (n int, err error) { + for i := 0; i < len(p); i++ { + p[i] = byte(r.Rand.Intn(255)) + } + return len(p), nil +} + +// GetenvBool is the way to check an env var as a boolean +func GetenvBool(name string) bool { + v := strings.ToLower(os.Getenv(name)) + return v == "true" || v == "t" || v == "1" +} + +// MultiErr is a util to return multiple errors +type MultiErr []error + +func (m MultiErr) Error() string { + if len(m) == 0 { + return "no errors" + } + + s := "Multiple errors: " + for i, e := range m { + if i != 0 { + s += ", " + } + s += e.Error() + } + return s +} + +// Partition splits a subject 3 parts: prefix, separator, suffix. +// The first occurrence of the separator will be matched. +// ie. Partition("Ready, steady, go!", ", ") -> ["Ready", ", ", "steady, go!"] +func Partition(subject string, sep string) (string, string, string) { + if i := strings.Index(subject, sep); i != -1 { + return subject[:i], subject[i : i+len(sep)], subject[i+len(sep):] + } + return subject, "", "" +} + +// RPartition splits a subject 3 parts: prefix, separator, suffix. +// The last occurrence of the separator will be matched. +// ie. RPartition("Ready, steady, go!", ", ") -> ["Ready, steady", ", ", "go!"] +func RPartition(subject string, sep string) (string, string, string) { + if i := strings.LastIndex(subject, sep); i != -1 { + return subject[:i], subject[i : i+len(sep)], subject[i+len(sep):] + } + return subject, "", "" +} + +// Hash is the global IPFS hash function. uses multihash SHA2_256, 256 bits +func Hash(data []byte) mh.Multihash { + h, err := mh.Sum(data, DefaultIpfsHash, -1) + if err != nil { + // this error can be safely ignored (panic) because multihash only fails + // from the selection of hash function. If the fn + length are valid, it + // won't error. + panic("multihash failed to hash using SHA2_256.") + } + return h +} + +// IsValidHash checks whether a given hash is valid (b58 decodable, len > 0) +func IsValidHash(s string) bool { + out, err := b58.Decode(s) + if err != nil { + return false + } + _, err = mh.Cast(out) + return err == nil +} + +// XOR takes two byte slices, XORs them together, returns the resulting slice. +func XOR(a, b []byte) []byte { + c := make([]byte, len(a)) + for i := 0; i < len(a); i++ { + c[i] = a[i] ^ b[i] + } + return c +} diff --git a/vendor/github.com/ipfs/go-ipfs/.codeclimate.yml b/vendor/github.com/ipfs/go-ipfs/.codeclimate.yml new file mode 100644 index 00000000..98f44c20 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/.codeclimate.yml @@ -0,0 +1,46 @@ +ratings: + paths: + - "**/*.go" + +exclude_paths: +- test/ +- Godeps/ +- thirdparty/ +- "**/*.pb.go" + +engines: + fixme: + enabled: true + config: + strings: + - FIXME + - HACK + - XXX + - BUG + golint: + enabled: true + govet: + enabled: true + gofmt: + enabled: true + +version: "2" +checks: + argument-count: + enabled: false + complex-logic: + enabled: false + file-lines: + enabled: false + method-complexity: + enabled: false + method-count: + enabled: false + method-lines: + enabled: false + nested-control-flow: + enabled: false + return-statements: + enabled: false + similar-code: + enabled: false diff --git a/vendor/github.com/ipfs/go-ipfs/.dockerignore b/vendor/github.com/ipfs/go-ipfs/.dockerignore new file mode 100644 index 00000000..10dd5fd8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/.dockerignore @@ -0,0 +1,13 @@ +Dockerfile +Dockerfile.fast +.git/ +!.git/HEAD +!.git/refs/ +!.git/packed-refs +test/sharness/lib/sharness/ + +# The Docker client might not be running on Linux +# so delete any compiled binaries +bin/gx +bin/gx* +bin/tmp diff --git a/vendor/github.com/ipfs/go-ipfs/.gitattributes b/vendor/github.com/ipfs/go-ipfs/.gitattributes new file mode 100644 index 00000000..d6b38c11 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/.gitattributes @@ -0,0 +1,15 @@ +# Default to text +* text eol=lf + +# True text +*.md text eol=auto +LICENSE text eol=auto + +# Known binary types +*.png binary +*.tar binary +*.gz binary + +# Binary assets +assets/init-doc/* binary +core/coreunix/test_data/** binary diff --git a/vendor/github.com/ipfs/go-ipfs/.gitignore b/vendor/github.com/ipfs/go-ipfs/.gitignore new file mode 100644 index 00000000..f96cb84b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/.gitignore @@ -0,0 +1,27 @@ +# ipfs can generate profiling dump files +*.cpuprof +*.memprof + +*.swp +.ipfsconfig +*.out +*.coverprofile +*.test +*.orig +*~ + +coverage.txt +gx-workspace-update.json + +.ipfs +bin/gx +bin/protoc-* +bin/gx* +bin/tmp +bin/gocovmerge +bin/cover + + +vendor +.tarball +go-ipfs-source.tar.gz diff --git a/vendor/github.com/ipfs/go-ipfs/CHANGELOG.md b/vendor/github.com/ipfs/go-ipfs/CHANGELOG.md new file mode 100644 index 00000000..c6f2f085 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/CHANGELOG.md @@ -0,0 +1,4352 @@ +# go-ipfs changelog + +## 0.4.21 2019-05-30 + +We're happy to announce go-ipfs 0.4.21. This release has some critical bug fixes +and a handful of new features so every user should upgrade. + +Key bug fixes: + +* Too many open file descriptors/too many peers + ([#6237](https://github.com/ipfs/go-ipfs/issues/6237)). +* Adding multiple files at the same time doesn't work + ([#6254](https://github.com/ipfs/go-ipfs/pull/6255)). +* CPU utilization spikes and then holds at 100% + ([#5613](https://github.com/ipfs/go-ipfs/issues/5613)). + +Key features: + +* Experimental TLS1.3 support (to eventually replace secio). +* OpenSSL support for SECIO handshakes (performance improvement). + +**IMPORTANT:** This release fixes a bug in our security transport that could +potentially drop data from the channel. Note: This issue affects neither the +privacy nor the integrity of the data with respect to a third-party attacker. +Only the peer sending us data could trigger this bug. + +**ALL USERS MUST UPGRADE.** We intended to introduce a feature this release that, +unfortunately, [reliably triggered this bug][secio-bug]. To avoid partitioning +the network, we've decided to postpone this feature for a release or two. + +Specifically, we're going to provide a minimum _one month_ upgrade period. After +that, we'll start testing the impact of deploying the proposed changes. + +If you're running the mainline go-ipfs, please upgrade ASAP. If you're building +a separate app or working on a forked go-ipfs, make sure to upgrade +github.com/libp2p/go-libp2p-secio to _at least_ v0.0.3. + +[secio-bug]: https://github.com/libp2p/go-libp2p/issues/644 + +### Contributors + +First off, we'd like to give a shout-out to all contributors that participated +in this release (including contributions to ipld, libp2p, and multiformats): + +| Contributor | Commits | Lines ± | Files Changed | +|----------------------------|---------|-------------|---------------| +| Steven Allen | 220 | +6078/-4211 | 520 | +| Łukasz Magiera | 53 | +5039/-4557 | 274 | +| vyzo | 179 | +2929/-1704 | 238 | +| Raúl Kripalani | 44 | +757/-1895 | 134 | +| hannahhoward | 11 | +755/-1005 | 49 | +| Marten Seemann | 16 | +862/-203 | 44 | +| keks | 10 | +359/-110 | 12 | +| Jan Winkelmann | 8 | +368/-26 | 16 | +| Jakub Sztandera | 4 | +361/-8 | 7 | +| Adrian Lanzafame | 1 | +287/-18 | 5 | +| Erik Ingenito | 4 | +247/-28 | 8 | +| Reid 'arrdem' McKenzie | 1 | +220/-20 | 3 | +| Yusef Napora | 26 | +98/-130 | 26 | +| Michael Avila | 3 | +116/-59 | 8 | +| Raghav Gulati | 13 | +145/-26 | 13 | +| tg | 1 | +41/-33 | 1 | +| Matt Joiner | 6 | +41/-30 | 7 | +| Cole Brown | 1 | +37/-25 | 1 | +| Dominic Della Valle | 2 | +12/-40 | 4 | +| Overbool | 1 | +50/-0 | 2 | +| Christopher Buesser | 3 | +29/-16 | 10 | +| myself659 | 1 | +38/-5 | 2 | +| Alex Browne | 3 | +30/-8 | 3 | +| jmank88 | 1 | +27/-4 | 2 | +| Vikram | 1 | +25/-1 | 2 | +| MollyM | 7 | +17/-9 | 7 | +| Marcin Rataj | 1 | +17/-1 | 1 | +| requilence | 1 | +11/-4 | 1 | +| Teran McKinney | 1 | +8/-2 | 1 | +| Oli Evans | 1 | +5/-5 | 1 | +| Masashi Salvador Mitsuzawa | 1 | +5/-1 | 1 | +| chenminjian | 1 | +4/-0 | 1 | +| Edgar Lee | 1 | +3/-1 | 1 | +| Dirk McCormick | 1 | +2/-2 | 2 | +| ia | 1 | +1/-1 | 1 | +| Alan Shaw | 1 | +1/-1 | 1 | + +### Bug Fixes And Enhancements + +This release includes quite a number of critical bug fixes and +performance/reliability enhancements. + +#### Error when adding multiple files + +The last release broke the simple command `ipfs add file1 file2`. It turns out +we simply lacked a test case for this. Both of these issues (the bug and the +lack of a test case) have now been fixed. + +#### SECIO + +As noted above, we've fixed a bug that could cause data to be dropped from a +SECIO connection on read. Specifically, this happens when: + +1. The capacity of the read buffer is greater than the length. +2. The remote peer sent more than the length but less than the capacity in a + single secio "frame". + +In this case, we'd fill the read buffer to it's capacity instead of its length. + +#### Too many open files, too many peers, etc. + +Go-ipfs automatically closes the least useful connections when it accumulates +too many connections. Unfortunately, some relayed connections were blocking in +`Close()`, halting the entire process. + +#### Out of control CPU usage + +Many users noted out of control CPU usage this release. This turned out to be a +long-standing issue with how the DHT handled provider records (records recording +which peers have what content): + +1. It wasn't removing provider records for content until the set of providers + completely emptied. +2. It was loading every provider record into memory whenever we updated the set + of providers. + +Combined, these two issues were trashing the provider record cache, forcing the +DHT to repeatedly load and discard provider records. + +#### More Reliable Connection Management + +Go-ipfs has a subsystem called the "connection manager" to close the +least-useful connections when go-ipfs runs low on resources. + +Unfortunately, other IPFS subsystems may learn about connections _before_ the +connection manager. Previously, if some IPFS subsystem tried to mark a +connection as useful before the connection manager learned about it, the +connection manager would discard this information. We believe this was causing +[#6271](https://github.com/ipfs/go-ipfs/issues/6271). [It no longer does +that](https://github.com/libp2p/go-libp2p-connmgr/pull/39). + +#### Improved Bitswap Connection Management + +Bitswap now uses the connection manager to mark all peers downloading blocks as +important (while downloading). Previously, it only marked peers from which _it_ +was downloading blocks. + +#### Reduced Memory Usage + +The most noticeable memory reduction in this release comes from fixing connection +closing. However, we've made a few additional improvements: + +* Bitswap's "work queue" no longer remembers every peer it has seen + indefinitely. +* The peerstore now interns protocol names. +* The per-peer goroutine count has been reduced. +* The DHT now wastes less memory on idle peers by pooling buffered writers and + returning them to the pool when not actively using them. + +#### Increased File Descriptor Limit + +The default file descriptor limit has been raised to 8192 (from 2048). +Unfortunately, go-ipfs behaves poorly when it runs out of file descriptors and +it uses a _lot_ of file descriptors. + +Luckily, most modern kernels can handle thousands of file descriptors without +any difficulty. + +#### Decreased Connection Handshake Latency + +Libp2p now shaves off a couple of round trips when initiating connections by +beginning the protocol negotiation before the remote peer responds to the +initial handshake message. + +In the optimal case (when the target peer speaks our preferred protocol), this +reduces the number of handshake round-trips from 6 to 4 (including the TCP +handshake). + +### Commands + +This release brings no new commands but does introduce a few changes, bugfixes, +and enhancements. This section is hardly complete but it lists the most +noticeable changes. + +Take note: this release also introduces a few breaking changes. + +#### [DEPRECATION] The URLStore Command Deprecated + +The experimental `ipfs urlstore` command is now deprecated. Please use `ipfs add +--nocopy URL` instead. + +#### [BREAKING] The DHT Command Base64 Encodes Values + +When responding to an `ipfs dht get` command, the daemon now encodes the +returned value using base64. The `ipfs` command will automatically decode this +value before returning it to the user so this change should only affect those +using the HTTP API directly. + +Unfortunately, this change was necessary as DHT records are arbitrary binary +blobs which can't be directly stored in JSON strings. + +#### [BREAKING] Base32 Encoded v1 CIDs By Default + +Both js-ipfs and go-ipfs now encode CIDv1 CIDs using base32 by default, instead +of base58. Unfortunately, base58 is case-sensitive and doesn't play well with +browsers (see [#4143](https://github.com/ipfs/go-ipfs/issues/4143). + +#### Human Readable Numbers + +The `ipfs bitswap stat` and and `ipfs object stat` commands now support a +`--humanize` flag that formats numbers with human-readable units (GiB, MiB, +etc.). + +#### Improved Errors + +This release improves two types of errors: + +1. Commands that take paths/multiaddrs now include the path/multiaddr in the + error message when it fails to parse. +2. `ipfs swarm connect` now returns a detailed error describing which addresses + were tried and why the dial failed. + +#### Ping Improvements + +The ping command has received some small improvements and fixes: + +1. It now exits with a non-zero exit status on failure. +2. It no longer succeeds with zero successful pings if we have a zombie but + non-functional connection to the peer being pinged + ([#6298](https://github.com/ipfs/go-ipfs/issues/6298)). +3. It now prints out the average latency when canceled with `^C` (like the unix + `ping` command). + +#### Improved Help Text + +Go-ipfs now intelligently wraps help text for easier reading. On an 80 character +wide terminal, + +**Before** + +``` +USAGE + ipfs add ... - Add a file or directory to ipfs. + +SYNOPSIS + ipfs add [--recursive | -r] [--dereference-args] [--stdin-name=] [ +--hidden | -H] [--quiet | -q] [--quieter | -Q] [--silent] [--progress | -p] [--t +rickle | -t] [--only-hash | -n] [--wrap-with-directory | -w] [--chunker= | -s] [--pin=false] [--raw-leaves] [--nocopy] [--fscache] [--cid-version=] [--hash=] [--inline] [--inline-limit=] [--] +... + +ARGUMENTS + + ... - The path to a file to be added to ipfs. + +OPTIONS + + -r, --recursive bool - Add directory paths recursive +ly. + --dereference-args bool - Symlinks supplied in argument +s are dereferenced. + --stdin-name string - Assign a name if the file sou +rce is stdin. + -H, --hidden bool - Include files that are hidden +. Only takes effect on recursive add. + -q, --quiet bool - Write minimal output. + -Q, --quieter bool - Write only final hash. + --silent bool - Write no output. + -p, --progress bool - Stream progress data. + -t, --trickle bool - Use trickle-dag format for da +g generation. + -n, --only-hash bool - Only chunk and hash - do not +write to disk. + -w, --wrap-with-directory bool - Wrap files with a directory o +bject. + -s, --chunker string - Chunking algorithm, size-[byt +es] or rabin-[min]-[avg]-[max]. Default: size-262144. + --pin bool - Pin this object when adding. +Default: true. + --raw-leaves bool - Use raw blocks for leaf nodes +. (experimental). + --nocopy bool - Add the file using filestore. + Implies raw-leaves. (experimental). + --fscache bool - Check the filestore for pre-e +xisting blocks. (experimental). + --cid-version int - CID version. Defaults to 0 un +less an option that depends on CIDv1 is passed. (experimental). + --hash string - Hash function to use. Implies + CIDv1 if not sha2-256. (experimental). Default: sha2-256. + --inline bool - Inline small blocks into CIDs +. (experimental). + --inline-limit int - Maximum block size to inline. + (experimental). Default: 32. + +``` + + +**After** + +``` +USAGE + ipfs add ... - Add a file or directory to ipfs. + +SYNOPSIS + ipfs add [--recursive | -r] [--dereference-args] [--stdin-name=] + [--hidden | -H] [--quiet | -q] [--quieter | -Q] [--silent] + [--progress | -p] [--trickle | -t] [--only-hash | -n] + [--wrap-with-directory | -w] [--chunker= | -s] [--pin=false] + [--raw-leaves] [--nocopy] [--fscache] [--cid-version=] + [--hash=] [--inline] [--inline-limit=] [--] + ... + +ARGUMENTS + + ... - The path to a file to be added to ipfs. + +OPTIONS + + -r, --recursive bool - Add directory paths recursively. + --dereference-args bool - Symlinks supplied in arguments are + dereferenced. + --stdin-name string - Assign a name if the file source is stdin. + -H, --hidden bool - Include files that are hidden. Only takes + effect on recursive add. + -q, --quiet bool - Write minimal output. + -Q, --quieter bool - Write only final hash. + --silent bool - Write no output. + -p, --progress bool - Stream progress data. + -t, --trickle bool - Use trickle-dag format for dag generation. + -n, --only-hash bool - Only chunk and hash - do not write to + disk. + -w, --wrap-with-directory bool - Wrap files with a directory object. + -s, --chunker string - Chunking algorithm, size-[bytes] or + rabin-[min]-[avg]-[max]. Default: + size-262144. + --pin bool - Pin this object when adding. Default: + true. + --raw-leaves bool - Use raw blocks for leaf nodes. + (experimental). + --nocopy bool - Add the file using filestore. Implies + raw-leaves. (experimental). + --fscache bool - Check the filestore for pre-existing + blocks. (experimental). + --cid-version int - CID version. Defaults to 0 unless an + option that depends on CIDv1 is passed. + (experimental). + --hash string - Hash function to use. Implies CIDv1 if + not sha2-256. (experimental). Default: + sha2-256. + --inline bool - Inline small blocks into CIDs. + (experimental). + --inline-limit int - Maximum block size to inline. + (experimental). Default: 32. +``` + +### Features + +This release is primarily a bug fix release but it still includes two nice +features from libp2p. + +#### Experimental TLS1.3 support + +Go-ipfs now has experimental TLS1.3 support. Currently, libp2p (IPFS's +networking library) uses a custom TLS-like protocol we call SECIO. However, the +conventional wisdom concerning custom security transports is "just don't" so we +are working on replacing it with TLS1.3 + +To choose this protocol by default, set the `Experimental.PreferTLS` config +variable: + +```bash +> ipfs config --bool Experimental.PreferTLS true +``` + +Why TLS1.3 and not X (noise, etc.)? + +1. Libp2p allows negotiating transports so there's no reason not to add noise + support to libp2p as well. +2. TLS has wide language support which should make implementing libp2p for new + languages significantly simpler. + +#### OpenSSL Support + +Go-ipfs can now (optionally) be built with OpenSSL support for improved +performance when establishing connections. This is primarily useful for nodes +receiving multiple inbound connections per second. + +To enable openssl support, rebuild go-ipfs with: + +```bash +> make build GOFLAGS=-tags=openssl +``` + +### CoreAPI + +The CoreAPI refactor is still underway and we've made significant progress +towards a usable ipfs-as-a-library constructor. Specifically, we've integrated +the [fx](https://go.uber.org/fx) dependency injection system and are +now working on cleaning up our initialization logic. This should make it easier +to inject new services into a go-ipfs process without messing with the core +internals. + +### Build: `GOCC` Environment Variable + +Build system now uses `GOCC` environment variable allowing for use of specific +go versions during builds. + +### Changelog + +- github.com/ipfs/go-ipfs: + - fix: use http.Error for sending errors ([ipfs/go-ipfs#6379](https://github.com/ipfs/go-ipfs/pull/6379)) + - core: call app.Stop once ([ipfs/go-ipfs#6380](https://github.com/ipfs/go-ipfs/pull/6380)) + - explain what dhtclient does ([ipfs/go-ipfs#6375](https://github.com/ipfs/go-ipfs/pull/6375)) + - ci: actually enable golangci-lint ([ipfs/go-ipfs#6362](https://github.com/ipfs/go-ipfs/pull/6362)) + - commands/swarm(fix): handle empty multiaddrs ([ipfs/go-ipfs#6355](https://github.com/ipfs/go-ipfs/pull/6355)) + - feat: improve errors when a path fails to parse ([ipfs/go-ipfs#6346](https://github.com/ipfs/go-ipfs/pull/6346)) + - fix vendoring dependencies when building the source tarball ([ipfs/go-ipfs#6349](https://github.com/ipfs/go-ipfs/pull/6349)) + - core: Use correct default for connmgr lowWater ([ipfs/go-ipfs#6352](https://github.com/ipfs/go-ipfs/pull/6352)) + - doc: remove out of date documentation ([ipfs/go-ipfs#6345](https://github.com/ipfs/go-ipfs/pull/6345)) + - Add generation of dependency changes to mkreleaselog ([ipfs/go-ipfs#6348](https://github.com/ipfs/go-ipfs/pull/6348)) + - readme: remove mention of DCO ([ipfs/go-ipfs#6344](https://github.com/ipfs/go-ipfs/pull/6344)) + - Add golangci-lint ([ipfs/go-ipfs#6321](https://github.com/ipfs/go-ipfs/pull/6321)) + - docs+mk: update guidance for unsupported platforms ([ipfs/go-ipfs#6338](https://github.com/ipfs/go-ipfs/pull/6338)) + - fix formatting in object get ([ipfs/go-ipfs#6340](https://github.com/ipfs/go-ipfs/pull/6340)) + - fail start when loading a plugin fails ([ipfs/go-ipfs#6339](https://github.com/ipfs/go-ipfs/pull/6339)) + - fix a typo in the issue template ([ipfs/go-ipfs#6335](https://github.com/ipfs/go-ipfs/pull/6335)) + - github: turn issue template into a multiple-choice question ([ipfs/go-ipfs#6333](https://github.com/ipfs/go-ipfs/pull/6333)) + - object put: Allow empty objects ([ipfs/go-ipfs#6330](https://github.com/ipfs/go-ipfs/pull/6330)) + - Update fuse.md ([ipfs/go-ipfs#6332](https://github.com/ipfs/go-ipfs/pull/6332)) + - work towards fixing dht commands ([ipfs/go-ipfs#6277](https://github.com/ipfs/go-ipfs/pull/6277)) + - fix setting ulimit ([ipfs/go-ipfs#6319](https://github.com/ipfs/go-ipfs/pull/6319)) + - switch to base32 by default for CIDv1 ([ipfs/go-ipfs#6300](https://github.com/ipfs/go-ipfs/pull/6300)) + - cmdkit -> cmds ([ipfs/go-ipfs#6318](https://github.com/ipfs/go-ipfs/pull/6318)) + - raise default fd limit to 8192 ([ipfs/go-ipfs#6266](https://github.com/ipfs/go-ipfs/pull/6266)) + - pin: don't walk all pinned blocks when removing a non-existent pin ([ipfs/go-ipfs#6311](https://github.com/ipfs/go-ipfs/pull/6311)) + - ping: fix a bunch of issues ([ipfs/go-ipfs#6312](https://github.com/ipfs/go-ipfs/pull/6312)) + - test(coreapi): use a thread-safe datastore everywhere ([ipfs/go-ipfs#6222](https://github.com/ipfs/go-ipfs/pull/6222)) + - fix(Dockerfile): Allow ipfs mount in Docker container ([ipfs/go-ipfs#5560](https://github.com/ipfs/go-ipfs/pull/5560)) + - docs: fix Routing section ([ipfs/go-ipfs#6309](https://github.com/ipfs/go-ipfs/pull/6309)) + - License update to dual MIT and Apache 2 ([ipfs/go-ipfs#6301](https://github.com/ipfs/go-ipfs/pull/6301)) + - Go test fix ([ipfs/go-ipfs#6293](https://github.com/ipfs/go-ipfs/pull/6293)) + - commands(pin update): return resolved CIDs instead of paths ([ipfs/go-ipfs#6275](https://github.com/ipfs/go-ipfs/pull/6275)) + - core: fix autonat construction ([ipfs/go-ipfs#6289](https://github.com/ipfs/go-ipfs/pull/6289)) + - Test and fix GC/pin bug ([ipfs/go-ipfs#6288](https://github.com/ipfs/go-ipfs/pull/6288)) + - GOCC implementation & fix in make & build scripts ([ipfs/go-ipfs#6282](https://github.com/ipfs/go-ipfs/pull/6282)) + - gc: cancel context ([ipfs/go-ipfs#6281](https://github.com/ipfs/go-ipfs/pull/6281)) + - fix: windows friendly daemon help ([ipfs/go-ipfs#6278](https://github.com/ipfs/go-ipfs/pull/6278)) + - Invert constructor config handling ([ipfs/go-ipfs#6276](https://github.com/ipfs/go-ipfs/pull/6276)) + - docs: document environment variables ([ipfs/go-ipfs#6268](https://github.com/ipfs/go-ipfs/pull/6268)) + - add: Return error from iterator ([ipfs/go-ipfs#6272](https://github.com/ipfs/go-ipfs/pull/6272)) + - commands(feat): use the coreapi in the urlstore command ([ipfs/go-ipfs#6259](https://github.com/ipfs/go-ipfs/pull/6259)) + - humanize for ipfs bitswap stat ([ipfs/go-ipfs#6258](https://github.com/ipfs/go-ipfs/pull/6258)) + - Revert "raise default fd limit to 8192" ([ipfs/go-ipfs#6265](https://github.com/ipfs/go-ipfs/pull/6265)) + - raise default fd limit to 8192 ([ipfs/go-ipfs#6261](https://github.com/ipfs/go-ipfs/pull/6261)) + - Fix AutoNAT service for private network ([ipfs/go-ipfs#6251](https://github.com/ipfs/go-ipfs/pull/6251)) + - add: Fix adding multiple files ([ipfs/go-ipfs#6255](https://github.com/ipfs/go-ipfs/pull/6255)) + - reprovider: Use goprocess ([ipfs/go-ipfs#6248](https://github.com/ipfs/go-ipfs/pull/6248)) + - core/corehttp/gateway_handler: pass a request ctx instead of the node ([ipfs/go-ipfs#6244](https://github.com/ipfs/go-ipfs/pull/6244)) + - constructor: cleanup some things ([ipfs/go-ipfs#6246](https://github.com/ipfs/go-ipfs/pull/6246)) + - Support --human flag in cmd/object-stat ([ipfs/go-ipfs#6241](https://github.com/ipfs/go-ipfs/pull/6241)) + - build: fix macos build with fuse ([ipfs/go-ipfs#6235](https://github.com/ipfs/go-ipfs/pull/6235)) + - add an experiment to prefer TLS 1.3 over secio ([ipfs/go-ipfs#6229](https://github.com/ipfs/go-ipfs/pull/6229)) + - fix two small nits in the go-ipfs constructor ([ipfs/go-ipfs#6234](https://github.com/ipfs/go-ipfs/pull/6234)) + - DI-based core.NewNode ([ipfs/go-ipfs#6162](https://github.com/ipfs/go-ipfs/pull/6162)) + - coreapi: Drop error from ParsePath ([ipfs/go-ipfs#6122](https://github.com/ipfs/go-ipfs/pull/6122)) + - fix the wrong path configuration in root redirection ([ipfs/go-ipfs#6215](https://github.com/ipfs/go-ipfs/pull/6215)) +- github.com/ipfs/go-bitswap (v0.0.4 -> v0.0.7): + - feat(engine): tag peers with requests ([ipfs/go-bitswap#128](https://github.com/ipfs/go-bitswap/pull/128)) + - fix(network): add mutex to avoid data race ([ipfs/go-bitswap#127](https://github.com/ipfs/go-bitswap/pull/127)) + - Change bitswap provide toggle to not be static ([ipfs/go-bitswap#124](https://github.com/ipfs/go-bitswap/pull/124)) + - Use shared peer task queue with Graphsync ([ipfs/go-bitswap#119](https://github.com/ipfs/go-bitswap/pull/119)) + - Add missing godoc comments, refactor to avoid confusion ([ipfs/go-bitswap#117](https://github.com/ipfs/go-bitswap/pull/117)) + - fix(decision): cleanup request queues ([ipfs/go-bitswap#116](https://github.com/ipfs/go-bitswap/pull/116)) + - Control provider workers with experiment flag ([ipfs/go-bitswap#110](https://github.com/ipfs/go-bitswap/pull/110)) + - connmgr: give peers more weight when actively participating in a session ([ipfs/go-bitswap#111](https://github.com/ipfs/go-bitswap/pull/111)) + - make the WantlistManager own the PeerHandler ([ipfs/go-bitswap#78](https://github.com/ipfs/go-bitswap/pull/78)) + - remove IPFS_LOW_MEM flag support ([ipfs/go-bitswap#115](https://github.com/ipfs/go-bitswap/pull/115)) +- github.com/ipfs/go-cid (v0.0.1 -> v0.0.2): + - default cidv1 to base32 ([ipfs/go-cid#85](https://github.com/ipfs/go-cid/pull/85)) +- github.com/ipfs/go-cidutil (v0.0.1 -> v0.0.2): + - default cidv1 to base32 ([ipfs/go-cidutil#13](https://github.com/ipfs/go-cidutil/pull/13)) +- github.com/ipfs/go-datastore (v0.0.3 -> v0.0.5): + - MapDatastore: obey KeysOnly ([ipfs/go-datastore#130](https://github.com/ipfs/go-datastore/pull/130)) + - fix the keytransform datastore's query implementation ([ipfs/go-datastore#127](https://github.com/ipfs/go-datastore/pull/127)) + - sync: apply entire query while locked ([ipfs/go-datastore#129](https://github.com/ipfs/go-datastore/pull/129)) + - filter: values are now always bytes ([ipfs/go-datastore#126](https://github.com/ipfs/go-datastore/pull/126)) + - autobatch: batch deletes ([ipfs/go-datastore#128](https://github.com/ipfs/go-datastore/pull/128)) +- github.com/ipfs/go-ipfs-cmds (v0.0.5 -> v0.0.8): + - fix: use golang's http.Error to send errors ([ipfs/go-ipfs-cmds#167](https://github.com/ipfs/go-ipfs-cmds/pull/167)) + - improve help text on narrow terminals ([ipfs/go-ipfs-cmds#140](https://github.com/ipfs/go-ipfs-cmds/pull/140)) + - chore: remove an old hack ([ipfs/go-ipfs-cmds#165](https://github.com/ipfs/go-ipfs-cmds/pull/165)) + - http: use the request context ([ipfs/go-ipfs-cmds#163](https://github.com/ipfs/go-ipfs-cmds/pull/163)) + - merge in go-ipfs-cmdkit ([ipfs/go-ipfs-cmds#164](https://github.com/ipfs/go-ipfs-cmds/pull/164)) + - fix: return the correct error ([ipfs/go-ipfs-cmds#162](https://github.com/ipfs/go-ipfs-cmds/pull/162)) +- github.com/ipfs/go-ipfs-config (v0.0.1 -> v0.0.3): + - Closes: #6284 Add appropriate IPv6 ranges to defaultServerFilters ([ipfs/go-ipfs-config#34](https://github.com/ipfs/go-ipfs-config/pull/34)) + - add an experiment to prefer TLS 1.3 over secio ([ipfs/go-ipfs-config#32](https://github.com/ipfs/go-ipfs-config/pull/32)) +- github.com/ipfs/go-ipfs-files (v0.0.2 -> v0.0.3): + - webfile: make Size() work before Read ([ipfs/go-ipfs-files#18](https://github.com/ipfs/go-ipfs-files/pull/18)) + - check http status code during WebFile reads and return error for non-2XX ([ipfs/go-ipfs-files#17](https://github.com/ipfs/go-ipfs-files/pull/17)) +- github.com/ipfs/go-ipld-cbor (v0.0.1 -> v0.0.2): + - switch to base32 by default ([ipfs/go-ipld-cbor#62](https://github.com/ipfs/go-ipld-cbor/pull/62)) +- github.com/ipfs/go-ipld-git (v0.0.1 -> v0.0.2): + - switch to base32 by default ([ipfs/go-ipld-git#40](https://github.com/ipfs/go-ipld-git/pull/40)) +- github.com/ipfs/go-mfs (v0.0.4 -> v0.0.7): + - Fix directory mv and add tests ([ipfs/go-mfs#76](https://github.com/ipfs/go-mfs/pull/76)) + - fix: not remove file by mistakes ([ipfs/go-mfs#73](https://github.com/ipfs/go-mfs/pull/73)) +- github.com/ipfs/go-path (v0.0.3 -> v0.0.4): + - include the path in path errors ([ipfs/go-path#28](https://github.com/ipfs/go-path/pull/28)) +- github.com/ipfs/go-unixfs (v0.0.4 -> v0.0.6): + - chore: remove URL field ([ipfs/go-unixfs#72](https://github.com/ipfs/go-unixfs/pull/72)) +- github.com/ipfs/interface-go-ipfs-core (v0.0.6 -> v0.0.8): + - switch to base32 cidv1 by default ([ipfs/interface-go-ipfs-core#29](https://github.com/ipfs/interface-go-ipfs-core/pull/29)) + - path: drop error from ParsePath ([ipfs/interface-go-ipfs-core#22](https://github.com/ipfs/interface-go-ipfs-core/pull/22)) + - tests: fix a bunch of small test lints/issues ([ipfs/interface-go-ipfs-core#28](https://github.com/ipfs/interface-go-ipfs-core/pull/28)) + - Update Pin.RmRecursive docs to clarify shared indirect pins are not removed ([ipfs/interface-go-ipfs-core#26](https://github.com/ipfs/interface-go-ipfs-core/pull/26)) +- github.com/libp2p/go-buffer-pool (v0.0.1 -> v0.0.2): + - feat: add buffered writer ([libp2p/go-buffer-pool#9](https://github.com/libp2p/go-buffer-pool/pull/9)) +- github.com/libp2p/go-conn-security-multistream (v0.0.1 -> v0.0.2): + - block while writing ([libp2p/go-conn-security-multistream#10](https://github.com/libp2p/go-conn-security-multistream/pull/10)) +- github.com/libp2p/go-libp2p (v0.0.12 -> v0.0.28): + - Close the connection manager ([libp2p/go-libp2p#639](https://github.com/libp2p/go-libp2p/pull/639)) + - Frequent Relay Advertisements ([libp2p/go-libp2p#637](https://github.com/libp2p/go-libp2p/pull/637)) + - ping: return a stream of results ([libp2p/go-libp2p#626](https://github.com/libp2p/go-libp2p/pull/626)) + - Use cancelable background context in identify ([libp2p/go-libp2p#624](https://github.com/libp2p/go-libp2p/pull/624)) + - avoid intermediate allocation in relayAddrs ([libp2p/go-libp2p#609](https://github.com/libp2p/go-libp2p/pull/609)) + - cache relayAddrs for a short period of time ([libp2p/go-libp2p#608](https://github.com/libp2p/go-libp2p/pull/608)) + - autorelay: break findRelays into multiple functions and avoid the goto ([libp2p/go-libp2p#606](https://github.com/libp2p/go-libp2p/pull/606)) + - autorelay: curtail addrsplosion ([libp2p/go-libp2p#598](https://github.com/libp2p/go-libp2p/pull/598)) + - Periodically schedule identify push if the address set has changed ([libp2p/go-libp2p#597](https://github.com/libp2p/go-libp2p/pull/597)) + - Replace peer addresses in identify ([libp2p/go-libp2p#599](https://github.com/libp2p/go-libp2p/pull/599)) +- github.com/libp2p/go-libp2p-circuit (v0.0.4 -> v0.0.8): + - call Stream.Reset instead of Stream.Close ([libp2p/go-libp2p-circuit#76](https://github.com/libp2p/go-libp2p-circuit/pull/76)) + - Tag the hop relay when creating stop streams ([libp2p/go-libp2p-circuit#77](https://github.com/libp2p/go-libp2p-circuit/pull/77)) + - Tag peers with live hop streams ([libp2p/go-libp2p-circuit#75](https://github.com/libp2p/go-libp2p-circuit/pull/75)) + - Hard Limit the number of hop stream goroutines ([libp2p/go-libp2p-circuit#74](https://github.com/libp2p/go-libp2p-circuit/pull/74)) + - set deadline for stop handshake ([libp2p/go-libp2p-circuit#73](https://github.com/libp2p/go-libp2p-circuit/pull/73)) +- github.com/libp2p/go-libp2p-connmgr (v0.0.1 -> v0.0.6): + - Background trimming ([libp2p/go-libp2p-connmgr#43](https://github.com/libp2p/go-libp2p-connmgr/pull/43)) + - Implement UpsertTag ([libp2p/go-libp2p-connmgr#38](https://github.com/libp2p/go-libp2p-connmgr/pull/38)) + - Add peer protection capability (implementation) ([libp2p/go-libp2p-connmgr#36](https://github.com/libp2p/go-libp2p-connmgr/pull/36)) +- github.com/libp2p/go-libp2p-crypto (v0.0.1 -> v0.0.2): + - add openssl support ([libp2p/go-libp2p-crypto#61](https://github.com/libp2p/go-libp2p-crypto/pull/61)) +- github.com/libp2p/go-libp2p-discovery (v0.0.1 -> v0.0.4): + - More consistent use of options ([libp2p/go-libp2p-discovery#25](https://github.com/libp2p/go-libp2p-discovery/pull/25)) + - Use 3hrs as routing advertisement ttl ([libp2p/go-libp2p-discovery#23](https://github.com/libp2p/go-libp2p-discovery/pull/23)) +- github.com/libp2p/go-libp2p-interface-connmgr (v0.0.1 -> v0.0.5): + - Add Close method to the ConnManager interface ([libp2p/go-libp2p-interface-connmgr#18](https://github.com/libp2p/go-libp2p-interface-connmgr/pull/18)) + - Add UpsertTag to the interface ([libp2p/go-libp2p-interface-connmgr#17](https://github.com/libp2p/go-libp2p-interface-connmgr/pull/17)) + - Fix NullConnMgr to respect ConnManager interface ([libp2p/go-libp2p-interface-connmgr#15](https://github.com/libp2p/go-libp2p-interface-connmgr/pull/15)) + - Add peer protection capability ([libp2p/go-libp2p-interface-connmgr#14](https://github.com/libp2p/go-libp2p-interface-connmgr/pull/14)) +- github.com/libp2p/go-libp2p-kad-dht (v0.0.7 -> v0.0.13): + - fix: reduce memory used by buffered writers ([libp2p/go-libp2p-kad-dht#332](https://github.com/libp2p/go-libp2p-kad-dht/pull/332)) + - query: fix a goroutine leak when the routing table is empty ([libp2p/go-libp2p-kad-dht#329](https://github.com/libp2p/go-libp2p-kad-dht/pull/329)) + - query: fix error "leak" ([libp2p/go-libp2p-kad-dht#328](https://github.com/libp2p/go-libp2p-kad-dht/pull/328)) + - providers: run datastore GC concurrently ([libp2p/go-libp2p-kad-dht#326](https://github.com/libp2p/go-libp2p-kad-dht/pull/326)) + - fix(providers): gc ([libp2p/go-libp2p-kad-dht#325](https://github.com/libp2p/go-libp2p-kad-dht/pull/325)) + - Remove the old protocol from the defaults ([libp2p/go-libp2p-kad-dht#320](https://github.com/libp2p/go-libp2p-kad-dht/pull/320)) + - Fix some provider subsystem performance issues ([libp2p/go-libp2p-kad-dht#319](https://github.com/libp2p/go-libp2p-kad-dht/pull/319)) +- github.com/libp2p/go-libp2p-peerstore (v0.0.2 -> v0.0.6): + - segment the memory peerstore + granular locks ([libp2p/go-libp2p-peerstore#78](https://github.com/libp2p/go-libp2p-peerstore/pull/78)) + - don't delete under the read lock ([libp2p/go-libp2p-peerstore#76](https://github.com/libp2p/go-libp2p-peerstore/pull/76)) + - Read/Write locking ([libp2p/go-libp2p-peerstore#74](https://github.com/libp2p/go-libp2p-peerstore/pull/74)) + - optimize peerstore memory ([libp2p/go-libp2p-peerstore#71](https://github.com/libp2p/go-libp2p-peerstore/pull/71)) + - fix unmarshalling of peer IDs ([libp2p/go-libp2p-peerstore#72](https://github.com/libp2p/go-libp2p-peerstore/pull/72)) + - fix error handling in UpdateAddrs: return on error ([libp2p/go-libp2p-peerstore#70](https://github.com/libp2p/go-libp2p-peerstore/pull/70)) +- github.com/libp2p/go-libp2p-pubsub (v0.0.1 -> v0.0.3): + - rework validator pipeline ([libp2p/go-libp2p-pubsub#176](https://github.com/libp2p/go-libp2p-pubsub/pull/176)) + - Test adversarial signing ([libp2p/go-libp2p-pubsub#181](https://github.com/libp2p/go-libp2p-pubsub/pull/181)) + - Strict message signing by default ([libp2p/go-libp2p-pubsub#180](https://github.com/libp2p/go-libp2p-pubsub/pull/180)) +- github.com/libp2p/go-libp2p-secio (v0.0.1 -> v0.0.3): + - fix buffer size check ([libp2p/go-libp2p-secio#44](https://github.com/libp2p/go-libp2p-secio/pull/44)) +- github.com/libp2p/go-libp2p-swarm (v0.0.2 -> v0.0.6): + - dial: return a nice custom dial error ([libp2p/go-libp2p-swarm#121](https://github.com/libp2p/go-libp2p-swarm/pull/121)) +- github.com/libp2p/go-libp2p-tls (null -> v0.0.1): + - implement the new handshake ([libp2p/go-libp2p-tls#20](https://github.com/libp2p/go-libp2p-tls/pull/20)) + - use a prefix when signing the public key ([libp2p/go-libp2p-tls#26](https://github.com/libp2p/go-libp2p-tls/pull/26)) + - use ChaCha if one of the peers doesn't have AES hardware support ([libp2p/go-libp2p-tls#23](https://github.com/libp2p/go-libp2p-tls/pull/23)) + - improve peer verification ([libp2p/go-libp2p-tls#17](https://github.com/libp2p/go-libp2p-tls/pull/17)) + - add an example (mainly for development) ([libp2p/go-libp2p-tls#14](https://github.com/libp2p/go-libp2p-tls/pull/14)) +- github.com/libp2p/go-libp2p-transport-upgrader (v0.0.1 -> v0.0.4): + - improve correctness of closing connections on failure ([libp2p/go-libp2p-transport-upgrader#19](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/19)) +- github.com/libp2p/go-maddr-filter (v0.0.1 -> v0.0.4): + - fix filter listing ([libp2p/go-maddr-filter#13](https://github.com/libp2p/go-maddr-filter/pull/13)) + - Reinstate deprecated Remove() method to reverse breakage ([libp2p/go-maddr-filter#12](https://github.com/libp2p/go-maddr-filter/pull/12)) + - Implement support for whitelists, default-deny/allow ([libp2p/go-maddr-filter#8](https://github.com/libp2p/go-maddr-filter/pull/8)) +- github.com/libp2p/go-mplex (v0.0.1 -> v0.0.4): + - disable write coalescing ([libp2p/go-mplex#61](https://github.com/libp2p/go-mplex/pull/61)) + - fix SetDeadline error conditions ([libp2p/go-mplex#59](https://github.com/libp2p/go-mplex/pull/59)) + - don't use contexts for deadlines ([libp2p/go-mplex#58](https://github.com/libp2p/go-mplex/pull/58)) + - don't reset on pathologies, just ignore the data ([libp2p/go-mplex#57](https://github.com/libp2p/go-mplex/pull/57)) + - coalesce writes ([libp2p/go-mplex#54](https://github.com/libp2p/go-mplex/pull/54)) + - read as much as we can in one go ([libp2p/go-mplex#53](https://github.com/libp2p/go-mplex/pull/53)) + - use timeouts when sending messages for stream open, close, and reset. ([libp2p/go-mplex#52](https://github.com/libp2p/go-mplex/pull/52)) + - fix: reset a stream even if closed remotely ([libp2p/go-mplex#50](https://github.com/libp2p/go-mplex/pull/50)) + - downgrade Error log to Warning ([libp2p/go-mplex#46](https://github.com/libp2p/go-mplex/pull/46)) + - Fix race condition by adding a mutex for deadline access ([libp2p/go-mplex#41](https://github.com/libp2p/go-mplex/pull/41)) +- github.com/libp2p/go-msgio (v0.0.1 -> v0.0.2): + - fix: never claim to read more than read ([libp2p/go-msgio#12](https://github.com/libp2p/go-msgio/pull/12)) +- github.com/libp2p/go-ws-transport (v0.0.2 -> v0.0.4): + - dep: import go-smux-* into the libp2p org ([libp2p/go-ws-transport#43](https://github.com/libp2p/go-ws-transport/pull/43)) + - replace gx instructions with note about gomod ([libp2p/go-ws-transport#42](https://github.com/libp2p/go-ws-transport/pull/42)) + + +## 0.4.20 2019-04-16 + +We're happy to release go-ipfs 0.4.20. This release includes some critical +performance and stability fixes so all users should upgrade ASAP. + +This is also the first release to use go modules instead of GX. While GX has +been a great way to dogfood an IPFS-based package manager, building and +maintaining a custom package manager is a _lot_ of work and we haven't been able +to dedicate enough time to bring the user experience of gx to an acceptable +level. You can read [#5850](https://github.com/ipfs/go-ipfs/issues/5850) for +some discussion on this matter. + +### Docker + +As of this release, it's now much easier to run arbitrary IPFS commands within +the docker container: + +```bash +> docker run --name my-ipfs ipfs/go-ipfs:v0.4.20 config profile apply server # apply the server profile +> docker start my-ipfs # start the daemon +``` + +This release also [reverts](https://github.com/ipfs/go-ipfs/pull/6040) a change that +caused some significant trouble in 0.4.19. If you've been running into Docker +permission errors in 0.4.19, please upgrade. + +### WebUI + +This release contains a major +[WebUI](https://github.com/ipfs-shipyard/ipfs-webui) release with some +significant improvements to the file browser and new opt-in, privately hosted, +anonymous usage analytics. + +### Commands + +As usual, we've made several changes and improvements to our commands. The most +notable changes are listed in this section. + +#### New: `ipfs version deps` + +This release includes a new command, `ipfs version deps`, to list all +dependencies (with versions) of the current go-ipfs build. This should make it +easy to tell exactly how go-ipfs was built when tracking down issues. + +#### New: `ipfs add URL` + +The `ipfs add` command has gained support for URLs. This means you can: + +1. Add files with `ipfs add URL` instead of downloading the file first. +2. Replace all uses of the `ipfs urlstore` command with a call to `ipfs add + --nocopy`. The `ipfs urlstore` command will be deprecated in a future + release. + + +#### Changed: `ipfs swarm connect` + +The `ipfs swarm connect` command has a few new features: + +It now marks the newly created connection as "important". This should ensure +that the connection manager won't come along later and close the connection if +it doesn't think it's being used. + +It can now resolve `/dnsaddr` addresses that _don't_ end in a peer ID. For +example, you can now run `ipfs swarm connect /dnsaddr/bootstrap.libp2p.io` to +connect to one of the bootstrap peers at random. NOTE: This could connect you to +an _arbitrary_ peer as DNS is not secure (by default). Please do not rely on +this except for testing or unless you know what you're doing. + +Finally, `ipfs swarm connect` now returns _all_ errors on failure. This should +make it much easier to debug connectivity issues. For example, one might see an +error like: + +``` +Error: connect QmYou failure: dial attempt failed: 6 errors occurred: + * --> (/ip4/127.0.0.1/tcp/4001) dial attempt failed: dial tcp4 127.0.0.1:4001: connect: connection refused + * --> (/ip6/::1/tcp/4001) dial attempt failed: dial tcp6 [::1]:4001: connect: connection refused + * --> (/ip6/2604::1/tcp/4001) dial attempt failed: dial tcp6 [2604::1]:4001: connect: network is unreachable + * --> (/ip6/2602::1/tcp/4001) dial attempt failed: dial tcp6 [2602::1]:4001: connect: network is unreachable + * --> (/ip4/150.0.1.2/tcp/4001) dial attempt failed: dial tcp4 0.0.0.0:4001->150.0.1.2:4001: i/o timeout + * --> (/ip4/200.0.1.2/tcp/4001) dial attempt failed: dial tcp4 0.0.0.0:4001->200.0.1.2:4001: i/o timeout +``` + +#### Changed: `ipfs bitswap stat` + +`ipfs bitswap stat` no longer lists bitswap partners unless the `-v` flag is +passed. That is, it will now return: + +``` +> ipfs bitswap stat +bitswap status + provides buffer: 0 / 256 + blocks received: 0 + blocks sent: 79 + data received: 0 + data sent: 672706 + dup blocks received: 0 + dup data received: 0 B + wantlist [0 keys] + partners [197] +``` + +Instead of: + +``` +> ipfs bitswap stat -v +bitswap status + provides buffer: 0 / 256 + blocks received: 0 + blocks sent: 79 + data received: 0 + data sent: 672706 + dup blocks received: 0 + dup data received: 0 B + wantlist [0 keys] + partners [203] + QmNQTTTRCDpCYCiiu6TYWCqEa7ShAUo9jrZJvWngfSu1mL + QmNWaxbqERvdcgoWpqAhDMrbK2gKi3SMGk3LUEvfcqZcf4 + QmNgSVpgZVEd41pBX6DyCaHRof8UmUJLqQ3XH2qNL9xLvN + ... omitting 200 lines ... +``` + +#### Changed: `ipfs repo stat --human` + +The `--human` flag in the `ipfs repo stat` command now intelligently picks a +size unit instead of always using MiB. + +#### Changed: `ipfs resolve` (`ipfs dns`, `ipfs name resolve`) + +All of the resolve commands now: + +1. Resolve _recursively_ (up to 32 steps) by default to better match user + expectations (these commands used to be non-recursive by default). To turn + recursion off, pass `-r false`. +2. When resolving non-recursively, these commands no longer fail when partially + resolving a name. Instead, they simply return the intermediate result. + +#### Changed: `ipfs files flush` + +The `ipfs files flush` command now returns the CID of the flushed file. + +### Performance And Reliability + +This release has the usual collection of performance and reliability +improvements. + +#### Badger Memory Usage + +Those of you using the badger datastore should notice reduced memory usage in +this release due to some upstream changes. Badger still uses significantly more +memory than the default datastore configuration but this will hopefully continue +to improve. + +#### Bitswap + +We fixed some critical CPU utilization regressions in bitswap for this release. +If you've been noticing CPU _regressions_ in go-ipfs 0.4.19, especially when +running a public gateway, upgrading to 0.4.20 will likely fix them. + +#### Relays + +After AutoRelay was introduced in go-ipfs 0.4.19, the number of peers connecting +through relays skyrocketed to over 120K concurrent peers. This highlighted some +performance issues that we've now fixed in this release. Specifically: + +* We've significantly reduced the amount of memory allocated per-peer. +* We've fixed a bug where relays might, in rare cases, try to actively dial a + peer to relay traffic. By default, relays only forward traffic between peers + already connected to the relay. +* We've fixed quite a number of performance issues that only show up when + rapidly forming new connections. This will actually help _all_ nodes but will + especially help relays. + +If you've enabled relay _hop_ (`Swarm.EnableRelayHop`) in go-ipfs 0.4.19 and it +hasn't burned down your machine yet, this release should improve things +significantly. However, relays are still under heavy load so running an open +relay will continue to be resource intensive. + +We're continuing to investigate this issue and have a few more patches on the +way that, unfortunately, won't make it into this release. + +#### Panics + +We've fixed two notable panics in this release: + +* We've fixed a frequent panic in the DHT. +* We've fixed an occasional panic in the experimental QUIC transport. + +### Content Routing + +IPFS announces and finds content by sending and retrieving content routing +("provider") records to and from the DHT. Unfortunately, sending out these +records can be quite resource intensive. + +This release has two changes to alleviate this: a reduced number of initial +provide workers and a persistent provider queue. + +We've reduced the number of parallel initial provide workers (workers that send +out provider records when content is initially added to go-ipfs) from 512 to 6. +Each provide request (currently, due to some issues in our DHT) tries to +establish hundreds of connections, significantly impacting the performance of +go-ipfs and [crashing some +routers](https://github.com/ipfs/go-ipfs/issues/3320). + +We've introduced a new persistent provider queue for files added via `ipfs add` +and `ipfs pin add`. When new directory trees are added to go-ipfs, go-ipfs will +add the root/final CID to this queue. Then, in the background, go-ipfs will walk +the queue, sequentially sending out provider records for each CID. + +This ensures that root CIDs are sent out as soon as possible and are sent even +when files are added when the go-ipfs daemon isn't running. + +By example, let's add a directory tree to go-ipfs: + +```bash +> # We're going to do this in "online" mode first so let's start the daemon. +> ipfs daemon & +... +Daemon is ready +> # Now, we're going to create a directory to add. +> mkdir foo +> for i in {0..1000}; do echo do echo $i > foo/$i; done +> # finally, we're going to add it. +> ipfs add -r foo +added QmUQcSjQx2bg4cSe2rUZyQi6F8QtJFJb74fWL7D784UWf9 foo/0 +... +added QmQac2chFyJ24yfG2Dfuqg1P5gipLcgUDuiuYkQ5ExwGap foo/990 +added QmQWwz9haeQ5T2QmQeXzqspKdowzYELShBCLzLJjVa2DuV foo/991 +added QmQ5D4MtHUN4LTS4n7mgyHyaUukieMMyCfvnzXQAAbgTJm foo/992 +added QmZq4n4KRNq3k1ovzxJ4qdQXZSrarfJjnoLYPR3ztHd7EY foo/993 +added QmdtrsuVf8Nf1s1MaSjLAd54iNqrn1KN9VoFNgKGnLgjbt foo/994 +added QmbstvU9mnW2hsE94WFmw5WbrXdLTu2Sf9kWWSozrSDscL foo/995 +added QmXFd7f35gAnmisjfFmfYKkjA3F3TSpvUYB9SXr6tLsdg8 foo/996 +added QmV5BxS1YQ9V227Np2Cq124cRrFDAyBXNMqHHa6kpJ9cr6 foo/997 +added QmcXsccUtwKeQ1SuYC3YgyFUeYmAR9CXwGGnT3LPeCg5Tx foo/998 +added Qmc4mcQcpaNzyDQxQj5SyxwFg9ZYz5XBEeEZAuH4cQirj9 foo/999 +added QmXpXzUhcS9edmFBuVafV5wFXKjfXkCQcjAUZsTs7qFf3G foo +``` + +In 0.4.19, we would have sent out provider records for files `foo/{0..1000}` +_before_ sending out a provider record for `foo`. If you were ask a friend to +download /ipfs/QmUQcSjQx2bg4cSe2rUZyQi6F8QtJFJb74fWL7D784UWf9, they would +(baring other issues) be able to find it pretty quickly as this is the first CID +you'll have announced to the network. However, if you ask your friend to +download /ipfs/QmXpXzUhcS9edmFBuVafV5wFXKjfXkCQcjAUZsTs7qFf3G/0, they'll have to +wait for you to finish telling the network about every file in `foo` first. + +In 0.4.20, we _immediately_ tell the network about +`QmXpXzUhcS9edmFBuVafV5wFXKjfXkCQcjAUZsTs7qFf3G` (the `foo` directory) as soon +as we finish adding the directory to go-ipfs _without_ waiting to finish +announcing `foo/{0..1000}`. This is especially important in this release +because we've drastically reduced the number of provide workers. + +The second benefit is that this queue is persistent. That means go-ipfs won't +forget to send out this record, even if it was offline when the content was +initially added. NOTE: go-ipfs _does_ continuously _re_-send provider records in +the background twice a day, it just might be a while before it gets around to +sending one out any specific one. + +### Bitswap + +Bitswap now periodically re-sends its wantlist to connected peers. This should +help work around some race conditions we've seen in bitswap where one node wants +a block but the other doesn't know for some reason. + +You can track this issue here: https://github.com/ipfs/go-ipfs/issues/5183. + +### Improved NAT Traversal + +While NATs are still p2p enemy #1, this release includes slightly improved +support for traversing them. + +Specifically, this release now: + +1. Better detects the "gateway" NAT, even when multiple devices on the network + _claim_ to be NATs. +2. Better guesses the external IP address when port mapping, even when the + gateway lies. + +### Reduced AutoRelay Boot Time + +The experimental AutoRelay feature can now detect NATs _much_ faster as we've +reduced initial NAT detection delay to 15 seconds. There's still room for +improvement but this should make nodes that have enabled this feature dialable +earlier on start. + +### Changelogs + +- github.com/ipfs/go-ipfs: + - gitattributes: avoid normalizing known binary files ([ipfs/go-ipfs#6209](https://github.com/ipfs/go-ipfs/pull/6209)) + - gitattributes: default to LF ([ipfs/go-ipfs#6198](https://github.com/ipfs/go-ipfs/pull/6198)) + - Fix level db panic ([ipfs/go-ipfs#6186](https://github.com/ipfs/go-ipfs/pull/6186)) + - Dockerfile: Remove 2 year old deprecation warning ([ipfs/go-ipfs#6188](https://github.com/ipfs/go-ipfs/pull/6188)) + - align output for the command ipfs object stat ([ipfs/go-ipfs#6189](https://github.com/ipfs/go-ipfs/pull/6189)) + - provider queue: don't repeatedly retry the same item if we fail ([ipfs/go-ipfs#6187](https://github.com/ipfs/go-ipfs/pull/6187)) + - test: remove version/deps from ro commands test ([ipfs/go-ipfs#6185](https://github.com/ipfs/go-ipfs/pull/6185)) + - feat: add version deps command [modversion] ([ipfs/go-ipfs#6115](https://github.com/ipfs/go-ipfs/pull/6115)) + - readme: update for go modules ([ipfs/go-ipfs#6180](https://github.com/ipfs/go-ipfs/pull/6180)) + - Switch to Go 1.12 ([ipfs/go-ipfs#6144](https://github.com/ipfs/go-ipfs/pull/6144)) + - ci: avoid interleaving output from different sharness tests ([ipfs/go-ipfs#6175](https://github.com/ipfs/go-ipfs/pull/6175)) + - fix two bugs where the repo may not properly be closed ([ipfs/go-ipfs#6176](https://github.com/ipfs/go-ipfs/pull/6176)) + - fix error check in swarm connect ([ipfs/go-ipfs#6174](https://github.com/ipfs/go-ipfs/pull/6174)) + - feat(coreapi): tag all explicit connect requests in the connection manager ([ipfs/go-ipfs#6171](https://github.com/ipfs/go-ipfs/pull/6171)) + - chore: remove CODEOWNERS ([ipfs/go-ipfs#6172](https://github.com/ipfs/go-ipfs/pull/6172)) + - feat: update to IPFS Web UI 2.4.4 ([ipfs/go-ipfs#6169](https://github.com/ipfs/go-ipfs/pull/6169)) + - fix add error handling ([ipfs/go-ipfs#6156](https://github.com/ipfs/go-ipfs/pull/6156)) + - chore: remove waffle ([ipfs/go-ipfs#6157](https://github.com/ipfs/go-ipfs/pull/6157)) + - chore: fix a bunch of issues caught by golangci-lint ([ipfs/go-ipfs#6140](https://github.com/ipfs/go-ipfs/pull/6140)) + - docs/experimental-features.md: link to ipfs-ds-convert ([ipfs/go-ipfs#6154](https://github.com/ipfs/go-ipfs/pull/6154)) + - interrupt: fix send on closed ([ipfs/go-ipfs#6147](https://github.com/ipfs/go-ipfs/pull/6147)) + - docs: document Gateway.Writable not Gateway.Writeable ([ipfs/go-ipfs#6151](https://github.com/ipfs/go-ipfs/pull/6151)) + - Fuse fixes ([ipfs/go-ipfs#6135](https://github.com/ipfs/go-ipfs/pull/6135)) + - Remove duplicate blockstore from the package list ([ipfs/go-ipfs#6138](https://github.com/ipfs/go-ipfs/pull/6138)) + - Query for provider head/tail ([ipfs/go-ipfs#6125](https://github.com/ipfs/go-ipfs/pull/6125)) + - Remove dead link from ISSUE_TEMPLATE.md ([ipfs/go-ipfs#6128](https://github.com/ipfs/go-ipfs/pull/6128)) + - coreapi: remove Unixfs.Wrap ([ipfs/go-ipfs#6123](https://github.com/ipfs/go-ipfs/pull/6123)) + - coreapi unixfs: change Wrap logic to make more sense ([ipfs/go-ipfs#6019](https://github.com/ipfs/go-ipfs/pull/6019)) + - deps: switch back to jbenet go-is-domain ([ipfs/go-ipfs#6119](https://github.com/ipfs/go-ipfs/pull/6119)) + - command repo stat: add human flag tests to t0080-repo.sh ([ipfs/go-ipfs#6116](https://github.com/ipfs/go-ipfs/pull/6116)) + - gc: fix a potential deadlock ([ipfs/go-ipfs#6112](https://github.com/ipfs/go-ipfs/pull/6112)) + - fix config options in osxfuse error messages ([ipfs/go-ipfs#6105](https://github.com/ipfs/go-ipfs/pull/6105)) + - Command repo stat: improve human flag behavior ([ipfs/go-ipfs#6106](https://github.com/ipfs/go-ipfs/pull/6106)) + - Provide root node immediately on add and pin add ([ipfs/go-ipfs#6068](https://github.com/ipfs/go-ipfs/pull/6068)) + - gomod: Update Dockerfile, remove Dockerfile.fast ([ipfs/go-ipfs#6100](https://github.com/ipfs/go-ipfs/pull/6100)) + - Return CID from 'ipfs files flush' ([ipfs/go-ipfs#6102](https://github.com/ipfs/go-ipfs/pull/6102)) + - resolve: fix recursion ([ipfs/go-ipfs#6087](https://github.com/ipfs/go-ipfs/pull/6087)) + - fix(swarm): add dnsaddr support in swarm connect ([ipfs/go-ipfs#5535](https://github.com/ipfs/go-ipfs/pull/5535)) + - make in-memory datastore thread-safe ([ipfs/go-ipfs#6085](https://github.com/ipfs/go-ipfs/pull/6085)) + - Update package table to remove broken jenkins links ([ipfs/go-ipfs#6084](https://github.com/ipfs/go-ipfs/pull/6084)) + - mk: fix maketarball to work with gomod ([ipfs/go-ipfs#6078](https://github.com/ipfs/go-ipfs/pull/6078)) + - fix ls command to use the new coreinterface types ([ipfs/go-ipfs#6051](https://github.com/ipfs/go-ipfs/pull/6051)) + - mk: remove install_unsupported, leave a note ([ipfs/go-ipfs#6063](https://github.com/ipfs/go-ipfs/pull/6063)) + - mk: change git-hash command to include information about modifications ([ipfs/go-ipfs#6060](https://github.com/ipfs/go-ipfs/pull/6060)) + - mk: fix make install by not setting GOBIN ([ipfs/go-ipfs#6059](https://github.com/ipfs/go-ipfs/pull/6059)) + - go: require Golang 1.11.4 ([ipfs/go-ipfs#6057](https://github.com/ipfs/go-ipfs/pull/6057)) + - yamux: increase yamux window size to 8MiB. ([ipfs/go-ipfs#6049](https://github.com/ipfs/go-ipfs/pull/6049)) + - Introduce go modules [yey] ([ipfs/go-ipfs#6038](https://github.com/ipfs/go-ipfs/pull/6038)) + - cleanup daemon online logic ([ipfs/go-ipfs#6050](https://github.com/ipfs/go-ipfs/pull/6050)) + - ci: test on 32bit os ([ipfs/go-ipfs#5429](https://github.com/ipfs/go-ipfs/pull/5429)) + - feat/cmds: hide peers info default in bitswap stat ([ipfs/go-ipfs#5820](https://github.com/ipfs/go-ipfs/pull/5820)) + - Improve CLI help pages ([ipfs/go-ipfs#6013](https://github.com/ipfs/go-ipfs/pull/6013)) + - Close #6044 ([ipfs/go-ipfs#6045](https://github.com/ipfs/go-ipfs/pull/6045)) + - commands(dht): return final error ([ipfs/go-ipfs#6034](https://github.com/ipfs/go-ipfs/pull/6034)) + - Revert "Really run as non-root user in docker container" ([ipfs/go-ipfs#6040](https://github.com/ipfs/go-ipfs/pull/6040)) +- github.com/ipfs/go-bitswap: + - feat(messagequeue): rebroadcast wantlist ([ipfs/go-bitswap#106](https://github.com/ipfs/go-bitswap/pull/106)) + - reduce provide workers to 6 ([ipfs/go-bitswap#93](https://github.com/ipfs/go-bitswap/pull/93)) + - Reduce memory allocation ([ipfs/go-bitswap#103](https://github.com/ipfs/go-bitswap/pull/103)) + - refactor(messagequeue): remove dead code ([ipfs/go-bitswap#98](https://github.com/ipfs/go-bitswap/pull/98)) + - fix: limit use of custom context type ([ipfs/go-bitswap#89](https://github.com/ipfs/go-bitswap/pull/89)) + - fix: remove non-error log message ([ipfs/go-bitswap#91](https://github.com/ipfs/go-bitswap/pull/91)) + - fix(messagequeue): Remove second run loop ([ipfs/go-bitswap#94](https://github.com/ipfs/go-bitswap/pull/94)) +- github.com/ipfs/go-blockservice: + - Revert "Remove verifcid as it is handled in go-cid" ([ipfs/go-blockservice#25](https://github.com/ipfs/go-blockservice/pull/25)) + - Remove verifcid as it is handled in go-cid ([ipfs/go-blockservice#23](https://github.com/ipfs/go-blockservice/pull/23)) +- github.com/ipfs/go-datastore: + - cleanup and optimize naive query filters ([ipfs/go-datastore#125](https://github.com/ipfs/go-datastore/pull/125)) + - Fix – sorted limited offset mount queries ([ipfs/go-datastore#124](https://github.com/ipfs/go-datastore/pull/124)) + - Fix function comments based on best practices from Effective Go ([ipfs/go-datastore#122](https://github.com/ipfs/go-datastore/pull/122)) + - remove ThreadSafeDatastore ([ipfs/go-datastore#120](https://github.com/ipfs/go-datastore/pull/120)) + - Splinter TTLDatastore interface into TTL + Datastore ([ipfs/go-datastore#118](https://github.com/ipfs/go-datastore/pull/118)) +- github.com/ipfs/go-ds-badger: + - tweak the default options ([ipfs/go-ds-badger#52](https://github.com/ipfs/go-ds-badger/pull/52)) + - remove thread-safe assertion ([ipfs/go-ds-badger#55](https://github.com/ipfs/go-ds-badger/pull/55)) + - make memory-safe against concurrent closure/operations ([ipfs/go-ds-badger#53](https://github.com/ipfs/go-ds-badger/pull/53)) + - make badger use our logging framework ([ipfs/go-ds-badger#50](https://github.com/ipfs/go-ds-badger/pull/50)) +- github.com/ipfs/go-ds-flatfs: + - remove thread-safe assertion ([ipfs/go-ds-flatfs#53](https://github.com/ipfs/go-ds-flatfs/pull/53)) +- github.com/ipfs/go-ds-leveldb: + - Fast reverse query ([ipfs/go-ds-leveldb#28](https://github.com/ipfs/go-ds-leveldb/pull/28)) + - remove thread-safe assertion ([ipfs/go-ds-leveldb#27](https://github.com/ipfs/go-ds-leveldb/pull/27)) +- github.com/ipfs/go-ipfs-cmdkit: + - Extract files package ([ipfs/go-ipfs-cmdkit#31](https://github.com/ipfs/go-ipfs-cmdkit/pull/31)) +- github.com/ipfs/go-ipfs-cmds: + - sync: add yet another sync error ([ipfs/go-ipfs-cmds#161](https://github.com/ipfs/go-ipfs-cmds/pull/161)) + - Removed broken link from readme ([ipfs/go-ipfs-cmds#159](https://github.com/ipfs/go-ipfs-cmds/pull/159)) + - Fix broken link in readme ([ipfs/go-ipfs-cmds#160](https://github.com/ipfs/go-ipfs-cmds/pull/160)) + - set WebFile fpath to URL base ([ipfs/go-ipfs-cmds#158](https://github.com/ipfs/go-ipfs-cmds/pull/158)) + - Handle stdin name in cli/parse ([ipfs/go-ipfs-cmds#157](https://github.com/ipfs/go-ipfs-cmds/pull/157)) + - support url paths as files.WebFile ([ipfs/go-ipfs-cmds#154](https://github.com/ipfs/go-ipfs-cmds/pull/154)) + - typed encoder: improve pointer reflection ([ipfs/go-ipfs-cmds#155](https://github.com/ipfs/go-ipfs-cmds/pull/155)) + - cli: don't sync output to NUL on Windows ([ipfs/go-ipfs-cmds#153](https://github.com/ipfs/go-ipfs-cmds/pull/153)) +- github.com/ipfs/go-ipfs-files: + - return url as AbsPath from WebFile to implement FileInfo ([ipfs/go-ipfs-files#13](https://github.com/ipfs/go-ipfs-files/pull/13)) + - fix the content disposition header ([ipfs/go-ipfs-files#14](https://github.com/ipfs/go-ipfs-files/pull/14)) + - go format ([ipfs/go-ipfs-files#15](https://github.com/ipfs/go-ipfs-files/pull/15)) + - simplify content type checking ([ipfs/go-ipfs-files#9](https://github.com/ipfs/go-ipfs-files/pull/9)) + - remove extra webfile test code ([ipfs/go-ipfs-files#12](https://github.com/ipfs/go-ipfs-files/pull/12)) +- github.com/ipfs/go-merkledag: + - add function to marshal raw nodes to json ([ipfs/go-merkledag#36](https://github.com/ipfs/go-merkledag/pull/36)) + - fix some performance regressions when reading protobuf nodes ([ipfs/go-merkledag#34](https://github.com/ipfs/go-merkledag/pull/34)) +- github.com/ipfs/go-metrics-interface: + - update the counter interface to match prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) +- github.com/ipfs/go-mfs: + - Return node from FlushPath ([ipfs/go-mfs#72](https://github.com/ipfs/go-mfs/pull/72)) + - Wire up context to FlushPath ([ipfs/go-mfs#70](https://github.com/ipfs/go-mfs/pull/70)) +- github.com/ipfs/interface-go-ipfs-core: + - don't close the top-level addr ([ipfs/interface-go-ipfs-core#25](https://github.com/ipfs/interface-go-ipfs-core/pull/25)) + - fix a bunch of small test "bugs" ([ipfs/interface-go-ipfs-core#24](https://github.com/ipfs/interface-go-ipfs-core/pull/24)) + - remove Wrap ([ipfs/interface-go-ipfs-core#21](https://github.com/ipfs/interface-go-ipfs-core/pull/21)) + - Unixfs.Wrap Fixes ([ipfs/interface-go-ipfs-core#10](https://github.com/ipfs/interface-go-ipfs-core/pull/10)) + - tweak the Ls interface ([ipfs/interface-go-ipfs-core#14](https://github.com/ipfs/interface-go-ipfs-core/pull/14)) +- github.com/libp2p/go-buffer-pool: + - Enable tests ([libp2p/go-buffer-pool#6](https://github.com/libp2p/go-buffer-pool/pull/6)) +- github.com/libp2p/go-flow-metrics: + - Just repair spelling mistake ([libp2p/go-flow-metrics#3](https://github.com/libp2p/go-flow-metrics/pull/3)) +- github.com/libp2p/go-libp2p: + - Deprecate gx in readme & link to workspace repo ([libp2p/go-libp2p#591](https://github.com/libp2p/go-libp2p/pull/591)) + - Respect nodial option in routed host ([libp2p/go-libp2p#590](https://github.com/libp2p/go-libp2p/pull/590)) + - fix panic in observed address activation check ([libp2p/go-libp2p#586](https://github.com/libp2p/go-libp2p/pull/586)) + - Improve observed address handling ([libp2p/go-libp2p#585](https://github.com/libp2p/go-libp2p/pull/585)) + - identify: avoid parsing/printing multiaddrs ([libp2p/go-libp2p#583](https://github.com/libp2p/go-libp2p/pull/583)) + - move things outside of the lock in obsaddr ([libp2p/go-libp2p#582](https://github.com/libp2p/go-libp2p/pull/582)) + - identify: be more careful about the addresses we store ([libp2p/go-libp2p#577](https://github.com/libp2p/go-libp2p/pull/577)) + - relay: turn autorelay into a service and always filter out relay addresses ([libp2p/go-libp2p#578](https://github.com/libp2p/go-libp2p/pull/578)) + - chore: fail in the libp2p constructor if we fail to store the key ([libp2p/go-libp2p#576](https://github.com/libp2p/go-libp2p/pull/576)) + - Fix broken link in README.md ([libp2p/go-libp2p#580](https://github.com/libp2p/go-libp2p/pull/580)) + - Link to docs & discuss in readme ([libp2p/go-libp2p#571](https://github.com/libp2p/go-libp2p/pull/571)) + - Reduce autorelay boot delay and correctly handle private->public transition ([libp2p/go-libp2p#570](https://github.com/libp2p/go-libp2p/pull/570)) + - reduce nat error level ([libp2p/go-libp2p#568](https://github.com/libp2p/go-libp2p/pull/568)) + - relay: simplify declaration of multiaddr var ([libp2p/go-libp2p#563](https://github.com/libp2p/go-libp2p/pull/563)) + - Fix UDP listen on a Unspecified Address and Dial from the Unspecified Address ([libp2p/go-libp2p#561](https://github.com/libp2p/go-libp2p/pull/561)) + - Remove jenkins column from package table ([libp2p/go-libp2p#562](https://github.com/libp2p/go-libp2p/pull/562)) + - Fix typos in p2p/net/README.md ([libp2p/go-libp2p#555](https://github.com/libp2p/go-libp2p/pull/555)) + - better nat mapping ([libp2p/go-libp2p#549](https://github.com/libp2p/go-libp2p/pull/549)) +- github.com/libp2p/go-libp2p-autonat: + - fully close the autonat client stream ([libp2p/go-libp2p-autonat#21](https://github.com/libp2p/go-libp2p-autonat/pull/21)) + - parallelize dialbacks ([libp2p/go-libp2p-autonat#20](https://github.com/libp2p/go-libp2p-autonat/pull/20)) + - Pacify the race detector ([libp2p/go-libp2p-autonat#17](https://github.com/libp2p/go-libp2p-autonat/pull/17)) +- github.com/libp2p/go-libp2p-autonat-svc: + - full close the autonat stream ([libp2p/go-libp2p-autonat-svc#20](https://github.com/libp2p/go-libp2p-autonat-svc/pull/20)) + - reduce dialback timeout to 15s ([libp2p/go-libp2p-autonat-svc#17](https://github.com/libp2p/go-libp2p-autonat-svc/pull/17)) +- github.com/libp2p/go-libp2p-circuit: + - use buffer pool in newDelimitedReader ([libp2p/go-libp2p-circuit#71](https://github.com/libp2p/go-libp2p-circuit/pull/71)) + - Use NoDial option when opening hop streams for non-active relays ([libp2p/go-libp2p-circuit#70](https://github.com/libp2p/go-libp2p-circuit/pull/70)) + - use io.CopyBuffer with explicitly allocated buffers ([libp2p/go-libp2p-circuit#69](https://github.com/libp2p/go-libp2p-circuit/pull/69)) + - docs and nits ([libp2p/go-libp2p-circuit#66](https://github.com/libp2p/go-libp2p-circuit/pull/66)) +- github.com/libp2p/go-libp2p-kad-dht: + - dialQueue: start the control loop later ([libp2p/go-libp2p-kad-dht#312](https://github.com/libp2p/go-libp2p-kad-dht/pull/312)) + - make it work in wasm ([libp2p/go-libp2p-kad-dht#310](https://github.com/libp2p/go-libp2p-kad-dht/pull/310)) + - Revert "GoModules: Checksum mismatch:" ([libp2p/go-libp2p-kad-dht#309](https://github.com/libp2p/go-libp2p-kad-dht/pull/309)) + - defer dialqueue action until initial peers have been added ([libp2p/go-libp2p-kad-dht#301](https://github.com/libp2p/go-libp2p-kad-dht/pull/301)) +- github.com/libp2p/go-libp2p-nat: + - switch to libp2p's go-nat fork ([libp2p/go-libp2p-nat#16](https://github.com/libp2p/go-libp2p-nat/pull/16)) + - remove all uses of multiaddrs ([libp2p/go-libp2p-nat#14](https://github.com/libp2p/go-libp2p-nat/pull/14)) +- github.com/libp2p/go-libp2p-net: + - fix WithNoDial to return the context ([libp2p/go-libp2p-net#43](https://github.com/libp2p/go-libp2p-net/pull/43)) + - NoDial context option ([libp2p/go-libp2p-net#42](https://github.com/libp2p/go-libp2p-net/pull/42)) +- github.com/libp2p/go-libp2p-peer: + - Let ID implement encoding.Binary[Un]Marshaler and encoding.Text[Un]Marshaler ([libp2p/go-libp2p-peer#44](https://github.com/libp2p/go-libp2p-peer/pull/44)) +- github.com/libp2p/go-libp2p-peerstore: + - keep temp addresses for 2 minutes ([libp2p/go-libp2p-peerstore#67](https://github.com/libp2p/go-libp2p-peerstore/pull/67)) + - migrate to multiformats/go-base32 ([libp2p/go-libp2p-peerstore#61](https://github.com/libp2p/go-libp2p-peerstore/pull/61)) +- github.com/libp2p/go-libp2p-protocol: + - update readme ([libp2p/go-libp2p-protocol#6](https://github.com/libp2p/go-libp2p-protocol/pull/6)) + - Enable standard Travis CI tests. ([libp2p/go-libp2p-protocol#5](https://github.com/libp2p/go-libp2p-protocol/pull/5)) + - Fix go get address. ([libp2p/go-libp2p-protocol#4](https://github.com/libp2p/go-libp2p-protocol/pull/4)) + - Add MIT license ([libp2p/go-libp2p-protocol#3](https://github.com/libp2p/go-libp2p-protocol/pull/3)) + - Standardized Readme ([libp2p/go-libp2p-protocol#2](https://github.com/libp2p/go-libp2p-protocol/pull/2)) +- github.com/libp2p/go-libp2p-pubsub-router: + - gx publish 0.5.17 ([libp2p/go-libp2p-pubsub-router#26](https://github.com/libp2p/go-libp2p-pubsub-router/pull/26)) +- github.com/libp2p/go-libp2p-quic-transport: + - update quic-go to v0.11.0 ([libp2p/go-libp2p-quic-transport#54](https://github.com/libp2p/go-libp2p-quic-transport/pull/54)) +- github.com/libp2p/go-libp2p-routing-helpers: + - fix(put): fail if any router fails ([libp2p/go-libp2p-routing-helpers#19](https://github.com/libp2p/go-libp2p-routing-helpers/pull/19)) +- github.com/libp2p/go-libp2p-swarm: + - Add context option to disable dialing when opening a new stream ([libp2p/go-libp2p-swarm#116](https://github.com/libp2p/go-libp2p-swarm/pull/116)) + - return all dial errors if dial has failed ([libp2p/go-libp2p-swarm#115](https://github.com/libp2p/go-libp2p-swarm/pull/115)) + - Differentiate no addresses error from no good addresses ([libp2p/go-libp2p-swarm#113](https://github.com/libp2p/go-libp2p-swarm/pull/113)) +- github.com/libp2p/go-libp2p-transport: + - tests: constrain concurrency with race detector. ([libp2p/go-libp2p-transport#47](https://github.com/libp2p/go-libp2p-transport/pull/47)) + - pick test timeout from env var if available. ([libp2p/go-libp2p-transport#46](https://github.com/libp2p/go-libp2p-transport/pull/46)) + - increase test timeout. ([libp2p/go-libp2p-transport#45](https://github.com/libp2p/go-libp2p-transport/pull/45)) +- github.com/libp2p/go-msgio: + - Improve test coverage ([libp2p/go-msgio#10](https://github.com/libp2p/go-msgio/pull/10)) +- github.com/libp2p/go-reuseport: + - fix: add wasm build tag to wasm module ([libp2p/go-reuseport#70](https://github.com/libp2p/go-reuseport/pull/70)) +- github.com/libp2p/go-reuseport-transport: + - don't set linger to 0 ([libp2p/go-reuseport-transport#14](https://github.com/libp2p/go-reuseport-transport/pull/14)) +- github.com/libp2p/go-tcp-transport: + - set linger to 0 for both inbound and outbound connections ([libp2p/go-tcp-transport#36](https://github.com/libp2p/go-tcp-transport/pull/36)) +- github.com/libp2p/go-ws-transport: + - modernize request handling ([libp2p/go-ws-transport#41](https://github.com/libp2p/go-ws-transport/pull/41)) + +## 0.4.19 2019-03-01 + +We're happy to announce go 0.4.19. This release contains a bunch of important +fixes and a slew of new and improved features. Get pumped and upgrade ASAP to benefit from all the new goodies! 🎁 + +### Features + +#### 🔌 Initializing With Random Ports + +Go-ipfs can now be configured to listen on a random but _stable_ port (across +restarts) using the new `randomports` configuration profile. This should be +helpful when testing and/or running multiple go-ipfs instances on a single +machine. + +To initialize a go-ipfs instance with a randomly chosen port, run: + +```bash +> ipfs init --profile=randomports +``` + +#### 👂 Gateway Directory Listing + +IPNS (and/or DNSLink) directory listings on the gateway, e.g. +https://ipfs.io/ipns/dist.ipfs.io/go-ipfs/, will now display the _ipfs_ hash of +the current directory. This way users can more easily create permanent links to +otherwise mutable data. + +#### 📡 AutoRelay and AutoNAT + +This release introduces two new experimental features (courtesy of libp2p): +AutoRelay and AutoNAT. + +AutoRelay is a new service that automatically chooses a public relay when it +detects that the go-ipfs node is behind a NAT. While relaying connections +through a third-party node isn't the most efficient way to route around NATs, +it's a reliable fallback. + +To enable AutoRelay, set the `Swarm.EnableAutoRelay` option in the config. + +AutoNAT is the service AutoRelay uses to detect if the node is behind a NAT. You +don't have to set any special config flags to enable it. + +In this same config section, you may also notice options like `EnableRelayHop`, +`EnableAutoNATService`, etc. You _do not_ need to enable these: + +* `EnableRelayHop` -- Allow _other_ nodes to use _your_ node as a relay + (disabled by default). +* `EnableAutoNATService` -- Help _other_ nodes detect if they're behind a NAT + (disabled by default). + +#### 📵 Offline Operation + +There are two new "offline" features in this release: a global `--offline` flag +and an option to configure the gateway to not fetch files. + +Most go-ipfs commands now support the `--offline` flag. This causes IPFS to avoid +network operations when performing the requested operation. If you've ever used +the `--local` flag, the `--offline` flag is the (almost) universally supported +replacement. + +For example: + +* If the daemon is started with `ipfs daemon --offline`, it won't even _connect_ + to the network. (note: this feature isn't new, just an example). +* `ipfs add --offline some_file` won't send out provider records. +* `ipfs cat --offline Qm...` won't fetch any blocks from the network. +* `ipfs block stat --offline Qm...` is a great way to tell if a block is locally + available. + +Note: It doesn't _yet_ work with the `refs`, `urlstore`, or `tar` commands +([#6002](https://github.com/ipfs/go-ipfs/issues/6002)). + +On to the gateway, there's a new `Gateway.NoFetch` option to configure the +gateway to only serve locally present files. This makes it possible to run an +IPFS node as a gateway to serve content of _your_ choosing without acting like a +public proxy. 🤫 + +#### 📍 Adding And Pinning Content + +There's a new `--pin` flag for both `ipfs block put` and `ipfs urlstore add` to +match the `--pin` flag in `ipfs add`. This allows one to atomically add and pin +content with these APIs. + +**NOTE 1:** For `ipfs urlstore add`, `--pin` has been enabled _by default_ to +match the behavior in `ipfs add`. However, `ipfs block put` _does not_ pin by +default to match the _current_ behavior. + +**NOTE 2:** If you had previously used the urlstore and _weren't_ explicitly +pinning content after adding it, it isn't pinned and running the garbage +collector will delete it. While technically documented in the `ipfs urlstore +add` helptext, this behavior was non-obvious and bears mentioning. + +#### 🗂 File Listing + +The `ipfs ls` command has two significant changes this release: it reports +_file_ sizes instead of _dag_ sizes and has gained a new `--stream` flag. + +First up, `ipfs ls` now reports _file_ sizes instead of _dag_ sizes. Previously, +for historical reasons, `ipfs ls` would report the size of a file/directory as +seen by IPFS _including_ all the filesystem datastructures and metadata. +However, this meant that `ls -l` and `ipfs ls` would print _different_ sizes: + +```bash +> ipfs ls /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv + +QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V 1688 about +QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y 200 contact +QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 322 help +QmejvEPop4D7YUadeGqYWmZxHhLc4JBUCzJJHWMzdcMe2y 12 ping +QmXgqKTbzdh83pQtKFb19SpMCpDDcKR2ujqk3pKph9aCNF 1692 quick-start +QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB 1102 readme +QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm 1173 security-notes + +> ipfs get /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv +Saving file(s) to QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv + 6.39 KiB / 6.39 KiB [================================] 100.00% 0s + +> ls -l QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv +total 28 +-rw------- 1 user group 1677 Feb 14 17:03 about +-rw------- 1 user group 189 Feb 14 17:03 contact +-rw------- 1 user group 311 Feb 14 17:03 help +-rw------- 1 user group 4 Feb 14 17:03 ping +-rw------- 1 user group 1681 Feb 14 17:03 quick-start +-rw------- 1 user group 1091 Feb 14 17:03 readme +-rw------- 1 user group 1162 Feb 14 17:03 security-notes +``` + +This is now no longer the case. `ipfs ls` and `ls -l` now return the _same_ +sizes. 🙌 + +Second up, `ipfs ls` now has a new `--stream` flag. In IPFS, very large +directories (e.g., Wikipedia) are split up into multiple chunks (shards) as +there are too many entries to fit in a single block. Unfortunately, `ipfs ls` +buffers the _entire_ file list in memory and then sorts it. This means that +`ipfs ls /ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki` (wikipedia) +will take a _very_ long time to return anything (it'll also use quite a bit of +memory). + +However, the new `--stream` flag makes it possible to stream a directory listing +as new chunks are fetched from the network. To test this, you can run `ipfs ls +--stream --size=false --resolve-type=false +/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki`. You probably won't +want to wait for that command to finish, Wikipedia has a _lot_ of entries. 😉 + +#### 🔁 HTTP Proxy + +This release sees a new (experimental) feature contributed by our friends at +[Peergos](https://peergos.org): HTTP proxy over libp2p. When enabled, the local +gateway can act as an HTTP proxy and forward HTTP requests to libp2p peers. When +combined with the `ipfs p2p` command, users can use this to expose HTTP services +to other go-ipfs nodes via their gateways. For details, check out the +[documentation](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#p2p-http-proxy). + +### Performance And Reliability + +This release introduces quite a few performance/reliability improvements and, as +usual, fixes several memory leaks. Below is a non-exhaustive list of noticeable changes. + +#### 📞 DHT + +This release includes an important DHT fix that should significantly: + +1. Reduce dialing. +2. Speed up DHT queries. +3. Improve performance of the gateways. + +Basically, in the worst case, a DHT query would turn into a random walk of the +entire IPFS network. Yikes! + +Relevant PR: https://github.com/libp2p/go-libp2p-kad-dht/pull/237 + +#### 🕸 Bitswap + +Bitswap sessions have improved and are now used for _all_ requests. Sessions +allow us to group related content and ask peers most likely to _have_ the +content instead of broadcasting the request to all connected peers. This gives +us two significant benefits: + +1. Less wasted upload bandwidth. Instead of broadcasting which blocks we want to + everyone, we can ask fewer peers thus reducing the number of requests we send + out. +2. Less wasted download bandwidth. Because we _know_ which peers likely have + content, we can ask an individual peer for a block and expect to get an + answer. In the past, we'd ask every peer at the same time to optimize for + latency at the expense of bandwidth (getting the same block from multiple + peers). We had to do this because we had to assume that _most_ peers didn't + have the requested block. + +#### ‼️ Pubsub + +This release includes some significant reliability improvements in pubsub +subscription handling. If you've previously had issues with connected pubsub +peers _not_ seeing each-other's messages, please upgrade ASAP. + +#### ♻️ Reuseport + +In this release, we've rewritten our previously error-prone `go-reuseport` +library to _not_ duplicate a significant portion of Go's low-level networking +code. This was made possible by Go's new `Control` +[`net.Dialer`](https://golang.org/pkg/net/#Dialer) option. + +In the past, our first suggestion to anyone experiencing weird resource or +connectivity issues was to disable `REUSEPORT` (set `IPFS_REUSEPORT` to false). +This should no longer be necessary. + +#### 🐺 Badger Datastore + +[Badger has reached 1.0][badger-release]. This release brings an audit and +numerous reliability fixes. We are now reasonably confident that badger will +become the default datastore in a future release. 👍 + +[badger-release]: https://blog.dgraph.io/post/releasing-v1.0/ + +This release also adds a new `Truncate` configuration option for the badger +datastore (enabled by default for new IPFS nodes). When enabled, badger will +_delete_ any un-synced data on start instead of simply refusing to start. This +should be safe on all filesystems where the `sync` operation is safe and removes +the need for manual intervention when restarting an IPFS node after a crash. + +Assuming you initialized your badger repo with `ipfs init --profile=badgerds`, +you can enable truncate on an existing repo by running: `ipfs config --json +"Datastore.Spec.child.truncate" true`. + +### Refactors and Endeavors + +#### 🕹 Commands Library + +The legacy commands library shim has now been completely removed. This won't +mean much for many users but the go-ipfs team is happy to have this behind them. + +#### 🌐 Base32 CIDs + +This release can now encode CIDs in responses in bases other than base58. This +is primarily useful for web-browser integration as it allows us to (a) encode +CIDs in a lower-case base (e.g., base32) and then use them in the _origin_ part +of URLs. The take away is: this release brings us a step closer to better +browser integration. + +Specifically, this release adds two flags: + +1. `--cid-base`: When specified, the IPFS CLI will encode all CIDv1 CIDs using the + requested base. +2. `--upgrade-cidv0-in-output`: When specified, the IPFS CLI will _upgrade_ CIDv0 + CIDs to CIDv1 CIDs when returning them to the user. This upgrade is necessary + because CIDv0 doesn't support multibase however, it's off by default as it + changes the _binary_ representation of the CIDs (which could have unintended + consequences). + +#### 🎛 CoreAPI + +The work on the CoreAPI refactor ([ipfs/go-ipfs#4498][]) has progressed leaps and +bounds this release. The CoreAPI is a comprehensive programmatic interface +designed to allow go-ipfs be used as a daemon or a library interchangeably. + +As of this release, go-ipfs now has: + +* External interface definitions in [ipfs/interface-go-ipfs-core][]. +* A work-in-progress implementation ([ipfs/go-ipfs-http-client][]) of these + interfaces that uses the IPFS HTTP API. This will replace the + ([ipfs/go-ipfs-api][]) library. +* A new plugin type ["Daemon"][daemon-plugin]. Daemon plugins are started and + stopped along with the go-ipfs daemon and are instantiated with a copy of the + CoreAPI. This allows them to control and extend the go-ipfs daemon from within + the daemon itself. + +The next steps are: + +1. Finishing the remaining API surface area. At the moment, the two key missing + parts are: + 1. Config manipulation. + 2. The `ipfs files` API. +1. Finalizing the [ipfs/go-ipfs-http-client][] implementation. +2. Creating a simple way to construct and initialize a go-ipfs node when using + go-ipfs as a library. + +[ipfs/go-ipfs#4498]: https://github.com/ipfs/go-ipfs/issues/4498 +[ipfs/interface-go-ipfs-core]: https://github.com/ipfs/interface-go-ipfs-core +[ipfs/go-ipfs-http-client]: https://github.com/ipfs/go-ipfs-http-client +[ipfs/go-ipfs-api]: https://github.com/ipfs/go-ipfs-http-client +[daemon-plugin]: https://github.com/ipfs/go-ipfs/blob/master/docs/plugins.md#daemon + +### Changelogs + +- github.com/ipfs/go-ipfs: + - fix: show interactive output from install.sh ([ipfs/go-ipfs#6024](https://github.com/ipfs/go-ipfs/pull/6024)) + - fix: return the shortest, completely resolved path in the resolve command ([ipfs/go-ipfs#5704](https://github.com/ipfs/go-ipfs/pull/5704)) + - fix a few interop test issues ([ipfs/go-ipfs#6004](https://github.com/ipfs/go-ipfs/pull/6004)) + - fix HAMT bookmark ln ([ipfs/go-ipfs#6005](https://github.com/ipfs/go-ipfs/pull/6005)) + - docs: document Gateway.NoFetch ([ipfs/go-ipfs#5999](https://github.com/ipfs/go-ipfs/pull/5999)) + - Improve "name publish" ttl option documentation ([ipfs/go-ipfs#5979](https://github.com/ipfs/go-ipfs/pull/5979)) + - fix(cmd/mv): dst filename error ([ipfs/go-ipfs#5964](https://github.com/ipfs/go-ipfs/pull/5964)) + - coreapi: extract interface ([ipfs/go-ipfs#5978](https://github.com/ipfs/go-ipfs/pull/5978)) + - coreapi: cleanup non-gx references ([ipfs/go-ipfs#5976](https://github.com/ipfs/go-ipfs/pull/5976)) + - coreapi: fix seek test on http impl ([ipfs/go-ipfs#5971](https://github.com/ipfs/go-ipfs/pull/5971)) + - block put --pin ([ipfs/go-ipfs#5969](https://github.com/ipfs/go-ipfs/pull/5969)) + - Port `ipfs ls` to CoreAPI ([ipfs/go-ipfs#5962](https://github.com/ipfs/go-ipfs/pull/5962)) + - docs: duplicate default helptext in `name publish` ([ipfs/go-ipfs#5960](https://github.com/ipfs/go-ipfs/pull/5960)) + - plugin: add a daemon plugin with access to the CoreAPI ([ipfs/go-ipfs#5955](https://github.com/ipfs/go-ipfs/pull/5955)) + - coreapi: add some seeker tests ([ipfs/go-ipfs#5934](https://github.com/ipfs/go-ipfs/pull/5934)) + - Refactor ipfs get to use CoreAPI ([ipfs/go-ipfs#5943](https://github.com/ipfs/go-ipfs/pull/5943)) + - refact(cmd/init): change string option to const ([ipfs/go-ipfs#5949](https://github.com/ipfs/go-ipfs/pull/5949)) + - cmds/pin: use coreapi/pin ([ipfs/go-ipfs#5843](https://github.com/ipfs/go-ipfs/pull/5843)) + - Only perform DNSLink lookups on fully qualified domain names (FQDN) ([ipfs/go-ipfs#5950](https://github.com/ipfs/go-ipfs/pull/5950)) + - Fix DontCheckOSXFUSE config command example ([ipfs/go-ipfs#5951](https://github.com/ipfs/go-ipfs/pull/5951)) + - refact(cmd/config): change string option to const ([ipfs/go-ipfs#5948](https://github.com/ipfs/go-ipfs/pull/5948)) + - clarification the document of --resolve flag in name.publish ([ipfs/go-ipfs#5651](https://github.com/ipfs/go-ipfs/pull/5651)) + - Drop some coreunix code ([ipfs/go-ipfs#5938](https://github.com/ipfs/go-ipfs/pull/5938)) + - commands: fix verbose flag ([ipfs/go-ipfs#5940](https://github.com/ipfs/go-ipfs/pull/5940)) + - Fixes #4558 ([ipfs/go-ipfs#5937](https://github.com/ipfs/go-ipfs/pull/5937)) + - Port dag commansds to CoreAPI ([ipfs/go-ipfs#5939](https://github.com/ipfs/go-ipfs/pull/5939)) + - mfs: make sure to flush after mv and chcid ([ipfs/go-ipfs#5936](https://github.com/ipfs/go-ipfs/pull/5936)) + - docs/code-flow : Add code flow documentation for add cmd. ([ipfs/go-ipfs#5864](https://github.com/ipfs/go-ipfs/pull/5864)) + - coreapi: few more error check fixes ([ipfs/go-ipfs#5935](https://github.com/ipfs/go-ipfs/pull/5935)) + - Fixed and cleaned up TestIpfsStressRead ([ipfs/go-ipfs#5920](https://github.com/ipfs/go-ipfs/pull/5920)) + - Clarify that chunker sizes are in bytes ([ipfs/go-ipfs#5923](https://github.com/ipfs/go-ipfs/pull/5923)) + - refact(cmd/patch): change string to const ([ipfs/go-ipfs#5931](https://github.com/ipfs/go-ipfs/pull/5931)) + - refact(cmd/object): change option string to const ([ipfs/go-ipfs#5932](https://github.com/ipfs/go-ipfs/pull/5932)) + - coreapi: replace coreiface.DagAPI with ipld.DAGService ([ipfs/go-ipfs#5922](https://github.com/ipfs/go-ipfs/pull/5922)) + - Add global option to specify the multibase encoding (server side) ([ipfs/go-ipfs#5789](https://github.com/ipfs/go-ipfs/pull/5789)) + - coreapi: Adjust some tests for go-ipfs-http-api ([ipfs/go-ipfs#5926](https://github.com/ipfs/go-ipfs/pull/5926)) + - chore: update to Web UI v2.3.3 ([ipfs/go-ipfs#5928](https://github.com/ipfs/go-ipfs/pull/5928)) + - ls: Report real file size ([ipfs/go-ipfs#5906](https://github.com/ipfs/go-ipfs/pull/5906)) + - Improve the Filestore document ([ipfs/go-ipfs#5927](https://github.com/ipfs/go-ipfs/pull/5927)) + - [CORS] Bubble go-ipfs-cmds 2.0.10 - Updates CORS library ([ipfs/go-ipfs#5919](https://github.com/ipfs/go-ipfs/pull/5919)) + - reduce verbosity of daemon start ([ipfs/go-ipfs#5904](https://github.com/ipfs/go-ipfs/pull/5904)) + - feat: update to Web UI v2.3.2 ([ipfs/go-ipfs#5899](https://github.com/ipfs/go-ipfs/pull/5899)) + - CoreAPI: Don't panic when testing incomplete implementions ([ipfs/go-ipfs#5900](https://github.com/ipfs/go-ipfs/pull/5900)) + - gateway: fix CORs headers ([ipfs/go-ipfs#5893](https://github.com/ipfs/go-ipfs/pull/5893)) + - Local Gateway option ([ipfs/go-ipfs#5649](https://github.com/ipfs/go-ipfs/pull/5649)) + - Show hash on gateway ([ipfs/go-ipfs#5830](https://github.com/ipfs/go-ipfs/pull/5830)) + - fix: ulimit docs mistake ([ipfs/go-ipfs#5894](https://github.com/ipfs/go-ipfs/pull/5894)) + - Move coreapi tests to the interface ([ipfs/go-ipfs#5865](https://github.com/ipfs/go-ipfs/pull/5865)) + - Move checkHelptextRecursive forward a bit ([ipfs/go-ipfs#5889](https://github.com/ipfs/go-ipfs/pull/5889)) + - coreapi/unixfs: Use path instead of raw hash in AddEvent ([ipfs/go-ipfs#5854](https://github.com/ipfs/go-ipfs/pull/5854)) + - Fix name resolve --offline ([ipfs/go-ipfs#5885](https://github.com/ipfs/go-ipfs/pull/5885)) + - testing: slow down republisher sharness test ([ipfs/go-ipfs#5856](https://github.com/ipfs/go-ipfs/pull/5856)) + - docs: flesh out plugin documentation ([ipfs/go-ipfs#5876](https://github.com/ipfs/go-ipfs/pull/5876)) + - main: move InterruptHandler to util ([ipfs/go-ipfs#5872](https://github.com/ipfs/go-ipfs/pull/5872)) + - make: fix building source tarball on macos ([ipfs/go-ipfs#5860](https://github.com/ipfs/go-ipfs/pull/5860)) + - fix config data race ([ipfs/go-ipfs#5634](https://github.com/ipfs/go-ipfs/pull/5634)) + - CoreAPI: Global offline option ([ipfs/go-ipfs#5825](https://github.com/ipfs/go-ipfs/pull/5825)) + - Update for go-ipfs-files refactor ([ipfs/go-ipfs#5661](https://github.com/ipfs/go-ipfs/pull/5661)) + - feat: update Web UI to v2.3.0 ([ipfs/go-ipfs#5855](https://github.com/ipfs/go-ipfs/pull/5855)) + - Stateful plugin loading ([ipfs/go-ipfs#4806](https://github.com/ipfs/go-ipfs/pull/4806)) + - startup: always load the private key ([ipfs/go-ipfs#5844](https://github.com/ipfs/go-ipfs/pull/5844)) + - add --dereference-args parameter ([ipfs/go-ipfs#5801](https://github.com/ipfs/go-ipfs/pull/5801)) + - config: document the connection manager ([ipfs/go-ipfs#5839](https://github.com/ipfs/go-ipfs/pull/5839)) + - add pinning support to the urlstore ([ipfs/go-ipfs#5834](https://github.com/ipfs/go-ipfs/pull/5834)) + - refact(cmd/cat): remove useless code ([ipfs/go-ipfs#5836](https://github.com/ipfs/go-ipfs/pull/5836)) + - Really run as non-root user in docker container ([ipfs/go-ipfs#5048](https://github.com/ipfs/go-ipfs/pull/5048)) + - README: document guix package ([ipfs/go-ipfs#5832](https://github.com/ipfs/go-ipfs/pull/5832)) + - docs: Improve config documentation ([ipfs/go-ipfs#5829](https://github.com/ipfs/go-ipfs/pull/5829)) + - block: rm extra output ([ipfs/go-ipfs#5751](https://github.com/ipfs/go-ipfs/pull/5751)) + - merge github-issue-guide with the issue template ([ipfs/go-ipfs#4636](https://github.com/ipfs/go-ipfs/pull/4636)) + - docs: fix inconsistent capitalization of "API". ([ipfs/go-ipfs#5824](https://github.com/ipfs/go-ipfs/pull/5824)) + - Update README.md ([ipfs/go-ipfs#5818](https://github.com/ipfs/go-ipfs/pull/5818)) + - CONTRIBUTING.md link ([ipfs/go-ipfs#5811](https://github.com/ipfs/go-ipfs/pull/5811)) + - README: Update required Go version ([ipfs/go-ipfs#5813](https://github.com/ipfs/go-ipfs/pull/5813)) + - p2p: report-peer-id option for listen ([ipfs/go-ipfs#5771](https://github.com/ipfs/go-ipfs/pull/5771)) + - really fix netcat race ([ipfs/go-ipfs#5803](https://github.com/ipfs/go-ipfs/pull/5803)) + - [http_proxy_over_p2p] ([ipfs/go-ipfs#5526](https://github.com/ipfs/go-ipfs/pull/5526)) + - coreapi/pin: Use CID's directly in maps instead of converting to string ([ipfs/go-ipfs#5809](https://github.com/ipfs/go-ipfs/pull/5809)) + - Gx update go-merkledag and related deps. ([ipfs/go-ipfs#5802](https://github.com/ipfs/go-ipfs/pull/5802)) + - cmds: rm old lib ([ipfs/go-ipfs#5786](https://github.com/ipfs/go-ipfs/pull/5786)) + - badger: add truncate flag ([ipfs/go-ipfs#5625](https://github.com/ipfs/go-ipfs/pull/5625)) + - docker: allow IPFS_PROFILE to choose the profile for `ipfs init` ([ipfs/go-ipfs#5473](https://github.com/ipfs/go-ipfs/pull/5473)) + - Add --stream option to `ls` command ([ipfs/go-ipfs#5611](https://github.com/ipfs/go-ipfs/pull/5611)) + - Switch to using request.Context() ([ipfs/go-ipfs#5782](https://github.com/ipfs/go-ipfs/pull/5782)) + - Update go-ipfs-delay and assoc deps ([ipfs/go-ipfs#5762](https://github.com/ipfs/go-ipfs/pull/5762)) + - Suppress bootstrap error ([ipfs/go-ipfs#5769](https://github.com/ipfs/go-ipfs/pull/5769)) + - ISSUE_TEMPLATE: move the support question comment to the very top ([ipfs/go-ipfs#5770](https://github.com/ipfs/go-ipfs/pull/5770)) + - cmds: use MakeTypedEncoder ([ipfs/go-ipfs#5760](https://github.com/ipfs/go-ipfs/pull/5760)) + - cmds/bitswap: sort wantlist ([ipfs/go-ipfs#5759](https://github.com/ipfs/go-ipfs/pull/5759)) + - cmds/update: use new cmds lib ([ipfs/go-ipfs#5730](https://github.com/ipfs/go-ipfs/pull/5730)) + - cmds/file: use new cmds lib ([ipfs/go-ipfs#5756](https://github.com/ipfs/go-ipfs/pull/5756)) + - cmds: remove reduntant func ([ipfs/go-ipfs#5750](https://github.com/ipfs/go-ipfs/pull/5750)) + - commands/refs: use new cmds ([ipfs/go-ipfs#5679](https://github.com/ipfs/go-ipfs/pull/5679)) + - commands/pin: use new cmds lib ([ipfs/go-ipfs#5674](https://github.com/ipfs/go-ipfs/pull/5674)) + - commands/boostrap: use new cmds ([ipfs/go-ipfs#5678](https://github.com/ipfs/go-ipfs/pull/5678)) + - fix(cmd/add): progressbar output error when input is read from stdin ([ipfs/go-ipfs#5743](https://github.com/ipfs/go-ipfs/pull/5743)) + - unexport GOFLAGS ([ipfs/go-ipfs#5747](https://github.com/ipfs/go-ipfs/pull/5747)) + - refactor(cmds): use new cmds ([ipfs/go-ipfs#5659](https://github.com/ipfs/go-ipfs/pull/5659)) + - commands/filestore: use new cmds lib ([ipfs/go-ipfs#5673](https://github.com/ipfs/go-ipfs/pull/5673)) + - Fix broken links ([ipfs/go-ipfs#5721](https://github.com/ipfs/go-ipfs/pull/5721)) + - fix `ipfs help` bug #5557 ([ipfs/go-ipfs#5573](https://github.com/ipfs/go-ipfs/pull/5573)) + - commands/bitswap: use new cmds lib ([ipfs/go-ipfs#5676](https://github.com/ipfs/go-ipfs/pull/5676)) + - refact(cmd/repo): repo's sub cmds uses new cmd lib ([ipfs/go-ipfs#5677](https://github.com/ipfs/go-ipfs/pull/5677)) + - fix the maketarball script ([ipfs/go-ipfs#5718](https://github.com/ipfs/go-ipfs/pull/5718)) + - output link to WebUI on daemon startup ([ipfs/go-ipfs#5729](https://github.com/ipfs/go-ipfs/pull/5729)) + - Move persistent datastores to plugins ([ipfs/go-ipfs#5695](https://github.com/ipfs/go-ipfs/pull/5695)) + - Update IPTB test ([ipfs/go-ipfs#5636](https://github.com/ipfs/go-ipfs/pull/5636)) + - enhance(cmd/verify): add goroutine count to improve verify speed ([ipfs/go-ipfs#5710](https://github.com/ipfs/go-ipfs/pull/5710)) + - Update go-mfs and go-unixfs ([ipfs/go-ipfs#5714](https://github.com/ipfs/go-ipfs/pull/5714)) + - fix(flag/version): flag `all` should have a higher priority ([ipfs/go-ipfs#5719](https://github.com/ipfs/go-ipfs/pull/5719)) + - commands/p2p: use new cmds lib ([ipfs/go-ipfs#5672](https://github.com/ipfs/go-ipfs/pull/5672)) + - commands/dht: use new cmds lib ([ipfs/go-ipfs#5671](https://github.com/ipfs/go-ipfs/pull/5671)) + - commands/object: use new cmds ([ipfs/go-ipfs#5666](https://github.com/ipfs/go-ipfs/pull/5666)) + - commands/files: use new cmds ([ipfs/go-ipfs#5665](https://github.com/ipfs/go-ipfs/pull/5665)) + - cmds/env: add a config path helper ([ipfs/go-ipfs#5712](https://github.com/ipfs/go-ipfs/pull/5712)) +- github.com/ipfs/dir-index-html: + - show hash if given ([ipfs/dir-index-html#21](https://github.com/ipfs/dir-index-html/pull/21)) + - Add "jpeg" as an alias to "jpg". ([ipfs/dir-index-html#16](https://github.com/ipfs/dir-index-html/pull/16)) +- github.com/libp2p/go-addr-util: + - Improve test coverage ([libp2p/go-addr-util#14](https://github.com/libp2p/go-addr-util/pull/14)) +- github.com/ipfs/go-bitswap: + - fix(prq): fix a bunch of goroutine leaks and deadlocks ([ipfs/go-bitswap#87](https://github.com/ipfs/go-bitswap/pull/87)) + - remove allocations round two ([ipfs/go-bitswap#84](https://github.com/ipfs/go-bitswap/pull/84)) + - fix(bitswap): remove CancelWants function ([ipfs/go-bitswap#80](https://github.com/ipfs/go-bitswap/pull/80)) + - Avoid allocating for wantlist entries ([ipfs/go-bitswap#79](https://github.com/ipfs/go-bitswap/pull/79)) + - ci(Jenkins): remove Jenkinsfile ([ipfs/go-bitswap#83](https://github.com/ipfs/go-bitswap/pull/83)) + - More specific wantlists ([ipfs/go-bitswap#74](https://github.com/ipfs/go-bitswap/pull/74)) + - fix(wantlist): remove races on setup ([ipfs/go-bitswap#72](https://github.com/ipfs/go-bitswap/pull/72)) + - fix multiple data races ([ipfs/go-bitswap#76](https://github.com/ipfs/go-bitswap/pull/76)) + - ci: add travis ([ipfs/go-bitswap#75](https://github.com/ipfs/go-bitswap/pull/75)) + - providers: don't add every connected node as a provider ([ipfs/go-bitswap#59](https://github.com/ipfs/go-bitswap/pull/59)) + - refactor(GetBlocks): Merge session/non-session ([ipfs/go-bitswap#64](https://github.com/ipfs/go-bitswap/pull/64)) + - Feat: A more robust provider finder for sessions (for now) and soon for all bitswap ([ipfs/go-bitswap#60](https://github.com/ipfs/go-bitswap/pull/60)) + - fix(tests): stabilize session tests ([ipfs/go-bitswap#63](https://github.com/ipfs/go-bitswap/pull/63)) + - contexts: make sure to abort when a context is canceled ([ipfs/go-bitswap#58](https://github.com/ipfs/go-bitswap/pull/58)) + - fix(sessions): explicitly connect found peers ([ipfs/go-bitswap#56](https://github.com/ipfs/go-bitswap/pull/56)) + - Speed up sessions Round #1 ([ipfs/go-bitswap#27](https://github.com/ipfs/go-bitswap/pull/27)) + - Fix debug log formatting issues ([ipfs/go-bitswap#37](https://github.com/ipfs/go-bitswap/pull/37)) + - Feat/bandwidth limited tests ([ipfs/go-bitswap#42](https://github.com/ipfs/go-bitswap/pull/42)) + - fix(tests): stabilize unreliable session tests ([ipfs/go-bitswap#44](https://github.com/ipfs/go-bitswap/pull/44)) + - Bitswap Refactor #4: Extract session peer manager from sessions ([ipfs/go-bitswap#26](https://github.com/ipfs/go-bitswap/pull/26)) + - Bitswap Refactor #3: Extract sessions to package ([ipfs/go-bitswap#30](https://github.com/ipfs/go-bitswap/pull/30)) + - docs(comments): end comment sentences to have full-stop ([ipfs/go-bitswap#33](https://github.com/ipfs/go-bitswap/pull/33)) + - Bitswap Refactor #2: Extract PeerManager From Want Manager + Unit Test ([ipfs/go-bitswap#29](https://github.com/ipfs/go-bitswap/pull/29)) + - Bitswap Refactor #1: Session Manager & Extract Want Manager ([ipfs/go-bitswap#28](https://github.com/ipfs/go-bitswap/pull/28)) + - fix(Receiver): Ignore unwanted blocks ([ipfs/go-bitswap#24](https://github.com/ipfs/go-bitswap/pull/24)) + - feat(Benchmarks): Add real world dup blocks test ([ipfs/go-bitswap#25](https://github.com/ipfs/go-bitswap/pull/25)) + - Feat/bitswap pr improvements ([ipfs/go-bitswap#19](https://github.com/ipfs/go-bitswap/pull/19)) +- github.com/ipfs/go-blockservice: + - Don't return errors on closed exchange ([ipfs/go-blockservice#15](https://github.com/ipfs/go-blockservice/pull/15)) +- github.com/ipfs/go-cid: + - fix inline CIDs generated by Prefix.Sum ([ipfs/go-cid#84](https://github.com/ipfs/go-cid/pull/84)) + - Let Cid implement Binary[Un]Marshaler and Text[Un]Marshaler interfaces. ([ipfs/go-cid#81](https://github.com/ipfs/go-cid/pull/81)) + - fix typo in comment ([ipfs/go-cid#80](https://github.com/ipfs/go-cid/pull/80)) + - add codecs for Dash blocks, tx ([ipfs/go-cid#78](https://github.com/ipfs/go-cid/pull/78)) +- github.com/ipfs/go-cidutil: + - Fix Travis CI to run all tests. ([ipfs/go-cidutil#11](https://github.com/ipfs/go-cidutil/pull/11)) + - Changes needed for `--cid-base` option in go-ipfs (simplified vesion) ([ipfs/go-cidutil#10](https://github.com/ipfs/go-cidutil/pull/10)) + - add a utility method for sorting CID slices ([ipfs/go-cidutil#5](https://github.com/ipfs/go-cidutil/pull/5)) +- github.com/libp2p/go-conn-security: + - fix link to usage example in README ([libp2p/go-conn-security#4](https://github.com/libp2p/go-conn-security/pull/4)) +- github.com/ipfs/go-datastore: + - interfaces: make GetBacked* take a Read instead of a Datastore ([ipfs/go-datastore#115](https://github.com/ipfs/go-datastore/pull/115)) + - remove closer type assertions ([ipfs/go-datastore#112](https://github.com/ipfs/go-datastore/pull/112)) + - remove io.Closer from the transaction interface ([ipfs/go-datastore#113](https://github.com/ipfs/go-datastore/pull/113)) + - feat(datastore): expose datastore Close() ([ipfs/go-datastore#111](https://github.com/ipfs/go-datastore/pull/111)) + - query: make datastore ordering act like a user would expect ([ipfs/go-datastore#110](https://github.com/ipfs/go-datastore/pull/110)) + - delayed: implement io.Closer and export datastore type. ([ipfs/go-datastore#108](https://github.com/ipfs/go-datastore/pull/108)) + - split the datastore into a read and a write interface ([ipfs/go-datastore#107](https://github.com/ipfs/go-datastore/pull/107)) + - Describe behavior of Batching datastores ([ipfs/go-datastore#105](https://github.com/ipfs/go-datastore/pull/105)) + - handle concurrent puts/deletes in BasicBatch ([ipfs/go-datastore#103](https://github.com/ipfs/go-datastore/pull/103)) + - add a GetSize method ([ipfs/go-datastore#99](https://github.com/ipfs/go-datastore/pull/99)) +- github.com/ipfs/go-ds-badger: + - removed additional/wasteful Prefix conversion ([ipfs/go-ds-badger#45](https://github.com/ipfs/go-ds-badger/pull/45)) + - Enable Jenkins ([ipfs/go-ds-badger#35](https://github.com/ipfs/go-ds-badger/pull/35)) + - fix application or ordering for interface change ([ipfs/go-ds-badger#44](https://github.com/ipfs/go-ds-badger/pull/44)) + - Update badger ([ipfs/go-ds-badger#40](https://github.com/ipfs/go-ds-badger/pull/40)) +- github.com/ipfs/go-ds-flatfs: + - fix a goroutine leak killing the gateways ([ipfs/go-ds-flatfs#51](https://github.com/ipfs/go-ds-flatfs/pull/51)) +- github.com/ipfs/go-ds-leveldb: + - Expose Datastore type ([ipfs/go-ds-leveldb#20](https://github.com/ipfs/go-ds-leveldb/pull/20)) + - fix application or ordering for interface change ([ipfs/go-ds-leveldb#23](https://github.com/ipfs/go-ds-leveldb/pull/23)) +- github.com/ipfs/go-ipfs-cmds: + - fix sync error with go1.12 on darwin ([ipfs/go-ipfs-cmds#147](https://github.com/ipfs/go-ipfs-cmds/pull/147)) + - cli: fix ignoring std{out,err} sync errors on windows ([ipfs/go-ipfs-cmds#146](https://github.com/ipfs/go-ipfs-cmds/pull/146)) + - roundup of cleanup fixes ([ipfs/go-ipfs-cmds#144](https://github.com/ipfs/go-ipfs-cmds/pull/144)) + - Update cors library ([ipfs/go-ipfs-cmds#139](https://github.com/ipfs/go-ipfs-cmds/pull/139)) + - expand on the api error ([ipfs/go-ipfs-cmds#138](https://github.com/ipfs/go-ipfs-cmds/pull/138)) + - set the connection close header if we have a body to read ([ipfs/go-ipfs-cmds#116](https://github.com/ipfs/go-ipfs-cmds/pull/116)) + - print a nicer error on timeout/cancel ([ipfs/go-ipfs-cmds#137](https://github.com/ipfs/go-ipfs-cmds/pull/137)) + - Add link traversal option ([ipfs/go-ipfs-cmds#96](https://github.com/ipfs/go-ipfs-cmds/pull/96)) + - Don't skip stdin test on Windows ([ipfs/go-ipfs-cmds#136](https://github.com/ipfs/go-ipfs-cmds/pull/136)) + - MakeTypedEncoder: accept results by pointer or value ([ipfs/go-ipfs-cmds#134](https://github.com/ipfs/go-ipfs-cmds/pull/134)) +- github.com/ipfs/go-ipfs-config: + - Gateway.NoFetch ([ipfs/go-ipfs-config#19](https://github.com/ipfs/go-ipfs-config/pull/19)) + - add a Clone function ([ipfs/go-ipfs-config#16](https://github.com/ipfs/go-ipfs-config/pull/16)) + - randomports: give user ability to init ipfs using random port for swarm. ([ipfs/go-ipfs-config#17](https://github.com/ipfs/go-ipfs-config/pull/17)) + - Allow the use of the User-Agent header ([ipfs/go-ipfs-config#15](https://github.com/ipfs/go-ipfs-config/pull/15)) + - autorelay options ([ipfs/go-ipfs-config#21](https://github.com/ipfs/go-ipfs-config/pull/21)) + - profile: add badger truncate option ([ipfs/go-ipfs-config#20](https://github.com/ipfs/go-ipfs-config/pull/20)) +- github.com/ipfs/go-ipfs-delay: + - Feat/refactor wait time ([ipfs/go-ipfs-delay#1](https://github.com/ipfs/go-ipfs-delay/pull/1)) +- github.com/ipfs/go-ipfs-files: + - multipart: fix handling of common prefixes ([ipfs/go-ipfs-files#7](https://github.com/ipfs/go-ipfs-files/pull/7)) + - create implicit directories from multipart requests ([ipfs/go-ipfs-files#6](https://github.com/ipfs/go-ipfs-files/pull/6)) + - TarWriter ([ipfs/go-ipfs-files#4](https://github.com/ipfs/go-ipfs-files/pull/4)) + - Refactor filename - file relation ([ipfs/go-ipfs-files#2](https://github.com/ipfs/go-ipfs-files/pull/2)) +- github.com/ipfs/go-ipld-cbor: + - cbor: decode undefined as null ([ipfs/go-ipld-cbor#54](https://github.com/ipfs/go-ipld-cbor/pull/54)) + - error when trying to encode an empty link ([ipfs/go-ipld-cbor#52](https://github.com/ipfs/go-ipld-cbor/pull/52)) + - test for struct with both a cid and a bigint ([ipfs/go-ipld-cbor#51](https://github.com/ipfs/go-ipld-cbor/pull/51)) +- github.com/ipfs/go-ipld-format: + - Add a DAG walker with support for IPLD `Node`s ([ipfs/go-ipld-format#39](https://github.com/ipfs/go-ipld-format/pull/39)) + - Add BufferedDAG wrapping Batch as a DAGService. ([ipfs/go-ipld-format#48](https://github.com/ipfs/go-ipld-format/pull/48)) +- github.com/ipfs/go-ipld-git: + - Fix blob marshalling ([ipfs/go-ipld-git#37](https://github.com/ipfs/go-ipld-git/pull/37)) + - Re-enable assertion on commit size -- it is correct after #31 ([ipfs/go-ipld-git#33](https://github.com/ipfs/go-ipld-git/pull/33)) + - Use OS path separator in testing, fixes #30 ([ipfs/go-ipld-git#34](https://github.com/ipfs/go-ipld-git/pull/34)) + - Use rawdata length for size, fixes #7 ([ipfs/go-ipld-git#31](https://github.com/ipfs/go-ipld-git/pull/31)) + - Cache RawData for Commit, Tag, & Tree, fixes #6 ([ipfs/go-ipld-git#28](https://github.com/ipfs/go-ipld-git/pull/28)) + - Precompute Blob CID, fixes #21 ([ipfs/go-ipld-git#27](https://github.com/ipfs/go-ipld-git/pull/27)) + - Enable Jenkins ([ipfs/go-ipld-git#29](https://github.com/ipfs/go-ipld-git/pull/29)) +- github.com/ipfs/go-ipns: + - fix community/CONTRIBUTING.md link in README.md ([ipfs/go-ipns#20](https://github.com/ipfs/go-ipns/pull/20)) + - fix typo in README.md ([ipfs/go-ipns#21](https://github.com/ipfs/go-ipns/pull/21)) + - testing: disable inline peer ID test ([ipfs/go-ipns#19](https://github.com/ipfs/go-ipns/pull/19)) +- github.com/libp2p/go-libp2p: + - Fixed race conditions in mock package mock_stream and mock_conn ([libp2p/go-libp2p#535](https://github.com/libp2p/go-libp2p/pull/535)) + - increase initial relay advertisement delay to 30s ([libp2p/go-libp2p#534](https://github.com/libp2p/go-libp2p/pull/534)) + - Use PeerRouting in autorelay to find relay peer addresses ([libp2p/go-libp2p#531](https://github.com/libp2p/go-libp2p/pull/531)) + - docs: update broken links in NEWS.md ([libp2p/go-libp2p#517](https://github.com/libp2p/go-libp2p/pull/517)) + - don't advertise the raw public address in autorelay ([libp2p/go-libp2p#511](https://github.com/libp2p/go-libp2p/pull/511)) + - mock: export ratelimiter as RateLimiter ([libp2p/go-libp2p#507](https://github.com/libp2p/go-libp2p/pull/507)) + - readme: remove duplicate repo entries in README and package-list.json ([libp2p/go-libp2p#506](https://github.com/libp2p/go-libp2p/pull/506)) + - explicit option to enable autorelay ([libp2p/go-libp2p#500](https://github.com/libp2p/go-libp2p/pull/500)) + - Add delay in initial relay advertisement to allow the dht time to bootstrap ([libp2p/go-libp2p#495](https://github.com/libp2p/go-libp2p/pull/495)) + - suppressing error msg for NoSecurity option ([libp2p/go-libp2p#498](https://github.com/libp2p/go-libp2p/pull/498)) + - pulling updates ([libp2p/go-libp2p#4](https://github.com/libp2p/go-libp2p/pull/4)) + - fix contributing link in README ([libp2p/go-libp2p#494](https://github.com/libp2p/go-libp2p/pull/494)) + - Fix badges and links on README.md ([libp2p/go-libp2p#485](https://github.com/libp2p/go-libp2p/pull/485)) + - mocknet: fix NewStream and self dials ([libp2p/go-libp2p#480](https://github.com/libp2p/go-libp2p/pull/480)) + - deflake identify test ([libp2p/go-libp2p#479](https://github.com/libp2p/go-libp2p/pull/479)) + - mocknet: use peer ID in peer address ([libp2p/go-libp2p#476](https://github.com/libp2p/go-libp2p/pull/476)) + - autorelay ([libp2p/go-libp2p#454](https://github.com/libp2p/go-libp2p/pull/454)) + - Getting updates ([libp2p/go-libp2p#3](https://github.com/libp2p/go-libp2p/pull/3)) +- github.com/libp2p/go-libp2p-autonat: + - track autonat peer addresses ([libp2p/go-libp2p-autonat#7](https://github.com/libp2p/go-libp2p-autonat/pull/7)) +- github.com/libp2p/go-libp2p-circuit: + - Don't log raw binary ([libp2p/go-libp2p-circuit#53](https://github.com/libp2p/go-libp2p-circuit/pull/53)) +- github.com/libp2p/go-libp2p-connmgr: + - Fix concurrency and silence period not being honoured ([libp2p/go-libp2p-connmgr#26](https://github.com/libp2p/go-libp2p-connmgr/pull/26)) +- github.com/libp2p/go-libp2p-crypto: + - Fix: Remove redundant Ed25519 public key (#36). ([libp2p/go-libp2p-crypto#54](https://github.com/libp2p/go-libp2p-crypto/pull/54)) + - libp2p badges, remove IPFS ([libp2p/go-libp2p-crypto#52](https://github.com/libp2p/go-libp2p-crypto/pull/52)) + - Fix broken contribute link in README ([libp2p/go-libp2p-crypto#46](https://github.com/libp2p/go-libp2p-crypto/pull/46)) + - forbid RSA keys smaller than 512 bits ([libp2p/go-libp2p-crypto#43](https://github.com/libp2p/go-libp2p-crypto/pull/43)) + - Added ECDSA; Added RSA tests; Fixed linting errors; Handling all un-handled errors ([libp2p/go-libp2p-crypto#35](https://github.com/libp2p/go-libp2p-crypto/pull/35)) + - switch to the go-crypto ed25519 implementation ([libp2p/go-libp2p-crypto#38](https://github.com/libp2p/go-libp2p-crypto/pull/38)) + - update gogo protobuf ([libp2p/go-libp2p-crypto#37](https://github.com/libp2p/go-libp2p-crypto/pull/37)) +- github.com/libp2p/go-libp2p-discovery: + - add a timeout to Provide in routing.Advertise ([libp2p/go-libp2p-discovery#12](https://github.com/libp2p/go-libp2p-discovery/pull/12)) + - correctly encode ns to CID ([libp2p/go-libp2p-discovery#11](https://github.com/libp2p/go-libp2p-discovery/pull/11)) + - use 6hrs as ttl for routing based advertisements ([libp2p/go-libp2p-discovery#8](https://github.com/libp2p/go-libp2p-discovery/pull/8)) +- github.com/libp2p/go-libp2p-host: + - Helper to get PeerInfo from Host ([libp2p/go-libp2p-host#20](https://github.com/libp2p/go-libp2p-host/pull/20)) +- github.com/libp2p/go-libp2p-kad-dht: + - fix(dialQueue): account for failed dials ([libp2p/go-libp2p-kad-dht#277](https://github.com/libp2p/go-libp2p-kad-dht/pull/277)) + - Fix Bootstrap sub-queries ([libp2p/go-libp2p-kad-dht#264](https://github.com/libp2p/go-libp2p-kad-dht/pull/264)) + - dial queue: fix possible goroutine leak ([libp2p/go-libp2p-kad-dht#262](https://github.com/libp2p/go-libp2p-kad-dht/pull/262)) + - Alter some logging ([libp2p/go-libp2p-kad-dht#269](https://github.com/libp2p/go-libp2p-kad-dht/pull/269)) + - Revert #236: Test go mod in travis and use major versioning in import paths ([libp2p/go-libp2p-kad-dht#259](https://github.com/libp2p/go-libp2p-kad-dht/pull/259)) + - fix tests on freebsd ([libp2p/go-libp2p-kad-dht#255](https://github.com/libp2p/go-libp2p-kad-dht/pull/255)) + - Fix "no protocol with name dnsaddr" error ([libp2p/go-libp2p-kad-dht#247](https://github.com/libp2p/go-libp2p-kad-dht/pull/247)) + - Fix a race in dial queue ([libp2p/go-libp2p-kad-dht#248](https://github.com/libp2p/go-libp2p-kad-dht/pull/248)) + - Fix races with DialQueue variables ([libp2p/go-libp2p-kad-dht#241](https://github.com/libp2p/go-libp2p-kad-dht/pull/241)) + - Fix CircleCI ([libp2p/go-libp2p-kad-dht#238](https://github.com/libp2p/go-libp2p-kad-dht/pull/238)) + - Adaptive queue for staging dials ([libp2p/go-libp2p-kad-dht#237](https://github.com/libp2p/go-libp2p-kad-dht/pull/237)) + - Add the full libp2p default bootstrap peer list ([libp2p/go-libp2p-kad-dht#226](https://github.com/libp2p/go-libp2p-kad-dht/pull/226)) + - Revert "Tidy up bootstrapping" ([libp2p/go-libp2p-kad-dht#232](https://github.com/libp2p/go-libp2p-kad-dht/pull/232)) + - Tidy up bootstrapping ([libp2p/go-libp2p-kad-dht#225](https://github.com/libp2p/go-libp2p-kad-dht/pull/225)) + - Revert "Remove signal bootstrapping" ([libp2p/go-libp2p-kad-dht#227](https://github.com/libp2p/go-libp2p-kad-dht/pull/227)) + - Remove signal bootstrapping ([libp2p/go-libp2p-kad-dht#224](https://github.com/libp2p/go-libp2p-kad-dht/pull/224)) + - fix a potential DHT query hang ([libp2p/go-libp2p-kad-dht#219](https://github.com/libp2p/go-libp2p-kad-dht/pull/219)) + - docs: duplicate pkg documentation ([libp2p/go-libp2p-kad-dht#218](https://github.com/libp2p/go-libp2p-kad-dht/pull/218)) + - tests: skip key inlining test ([libp2p/go-libp2p-kad-dht#212](https://github.com/libp2p/go-libp2p-kad-dht/pull/212)) + - Rephrase "betterPeersToQuery" method comment to be less cryptic ([libp2p/go-libp2p-kad-dht#206](https://github.com/libp2p/go-libp2p-kad-dht/pull/206)) +- github.com/libp2p/go-libp2p-loggables: + - test: add unit tests ([libp2p/go-libp2p-loggables#21](https://github.com/libp2p/go-libp2p-loggables/pull/21)) +- github.com/libp2p/go-libp2p-netutil: + - Add tests ([libp2p/go-libp2p-netutil#28](https://github.com/libp2p/go-libp2p-netutil/pull/28)) +- github.com/libp2p/go-libp2p-peer: + - fix: re-enable peer ID inlining but make it configurable ([libp2p/go-libp2p-peer#42](https://github.com/libp2p/go-libp2p-peer/pull/42)) + - Protobuf and JSON (un-)marshalling methods for peer.ID ([libp2p/go-libp2p-peer#41](https://github.com/libp2p/go-libp2p-peer/pull/41)) + - disable key inlining ([libp2p/go-libp2p-peer#40](https://github.com/libp2p/go-libp2p-peer/pull/40)) +- github.com/libp2p/go-libp2p-peerstore: + - Add unit test to verify AddAddr doesn't shorten TTL ([libp2p/go-libp2p-peerstore#52](https://github.com/libp2p/go-libp2p-peerstore/pull/52)) + - disable inline-peer id test ([libp2p/go-libp2p-peerstore#49](https://github.com/libp2p/go-libp2p-peerstore/pull/49)) + - README: Update contributing guideline linkrot. ([libp2p/go-libp2p-peerstore#48](https://github.com/libp2p/go-libp2p-peerstore/pull/48)) + - Deterministic benchmark order; Keybook interface benchmarks ([libp2p/go-libp2p-peerstore#43](https://github.com/libp2p/go-libp2p-peerstore/pull/43)) + - PeerInfo UnMarshal Error #393 ([libp2p/go-libp2p-peerstore#45](https://github.com/libp2p/go-libp2p-peerstore/pull/45)) + - fix the inline key test ([libp2p/go-libp2p-peerstore#44](https://github.com/libp2p/go-libp2p-peerstore/pull/44)) +- github.com/libp2p/go-libp2p-pubsub: + - move timecache check/update after validation ([libp2p/go-libp2p-pubsub#156](https://github.com/libp2p/go-libp2p-pubsub/pull/156)) + - fix nonsensical check ([libp2p/go-libp2p-pubsub#154](https://github.com/libp2p/go-libp2p-pubsub/pull/154)) + - Extend validator interface to include message source ([libp2p/go-libp2p-pubsub#151](https://github.com/libp2p/go-libp2p-pubsub/pull/151)) + - Implement peer blacklist ([libp2p/go-libp2p-pubsub#149](https://github.com/libp2p/go-libp2p-pubsub/pull/149)) + - make timecache duration configurable ([libp2p/go-libp2p-pubsub#148](https://github.com/libp2p/go-libp2p-pubsub/pull/148)) + - godoc is not html either ([libp2p/go-libp2p-pubsub#147](https://github.com/libp2p/go-libp2p-pubsub/pull/147)) + - godoc documentation is not markdown ([libp2p/go-libp2p-pubsub#146](https://github.com/libp2p/go-libp2p-pubsub/pull/146)) + - Add documentation for subscribe's non-instanteneous semantics ([libp2p/go-libp2p-pubsub#145](https://github.com/libp2p/go-libp2p-pubsub/pull/145)) + - Some documentation ([libp2p/go-libp2p-pubsub#140](https://github.com/libp2p/go-libp2p-pubsub/pull/140)) + - rework peer tracking logic to handle multiple connections ([libp2p/go-libp2p-pubsub#132](https://github.com/libp2p/go-libp2p-pubsub/pull/132)) +- github.com/libp2p/go-libp2p-pubsub-router: + - encode record-store keys in pubsub ([libp2p/go-libp2p-pubsub-router#17](https://github.com/libp2p/go-libp2p-pubsub-router/pull/17)) +- github.com/libp2p/go-libp2p-quic-transport: + - fix badges in README ([libp2p/go-libp2p-quic-transport#39](https://github.com/libp2p/go-libp2p-quic-transport/pull/39)) + - Fix missing transport parameter in dialed connection ([libp2p/go-libp2p-quic-transport#38](https://github.com/libp2p/go-libp2p-quic-transport/pull/38)) +- github.com/libp2p/go-libp2p-routing: + - Update the comment on IpfsRouting.Bootstrap ([libp2p/go-libp2p-routing#36](https://github.com/libp2p/go-libp2p-routing/pull/36)) +- github.com/libp2p/go-libp2p-swarm: + - Make FD limits configurable by environment property ([libp2p/go-libp2p-swarm#102](https://github.com/libp2p/go-libp2p-swarm/pull/102)) + - Fix logging race ([libp2p/go-libp2p-swarm#100](https://github.com/libp2p/go-libp2p-swarm/pull/100)) + - Add CircleCI config ([libp2p/go-libp2p-swarm#99](https://github.com/libp2p/go-libp2p-swarm/pull/99)) + - Enhance debug logging in dial limiter ([libp2p/go-libp2p-swarm#98](https://github.com/libp2p/go-libp2p-swarm/pull/98)) + - dialer: handle dial cancel and/or completion before trying new addresses ([libp2p/go-libp2p-swarm#96](https://github.com/libp2p/go-libp2p-swarm/pull/96)) + - avoid spawning goroutines for canceled dials ([libp2p/go-libp2p-swarm#95](https://github.com/libp2p/go-libp2p-swarm/pull/95)) + - warn when we encounter a useless transport ([libp2p/go-libp2p-swarm#90](https://github.com/libp2p/go-libp2p-swarm/pull/90)) +- github.com/libp2p/go-libp2p-transport: + - fix transport tests for quic ([libp2p/go-libp2p-transport#39](https://github.com/libp2p/go-libp2p-transport/pull/39)) + - fix: fully close streams before returning ([libp2p/go-libp2p-transport#37](https://github.com/libp2p/go-libp2p-transport/pull/37)) + - fix typo in README ([libp2p/go-libp2p-transport#36](https://github.com/libp2p/go-libp2p-transport/pull/36)) +- github.com/libp2p/go-libp2p-transport-upgrader: + - annotate errors ([libp2p/go-libp2p-transport-upgrader#11](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/11)) +- github.com/ipfs/go-log: + - uglify the (event) logs ([ipfs/go-log#53](https://github.com/ipfs/go-log/pull/53)) + - add environment variable for writing tracing information to a file ([ipfs/go-log#52](https://github.com/ipfs/go-log/pull/52)) + - correctly display the line number when FinishWithErr fails ([ipfs/go-log#51](https://github.com/ipfs/go-log/pull/51)) +- github.com/libp2p/go-maddr-filter: + - test: extend test to improve coverage ([libp2p/go-maddr-filter#7](https://github.com/libp2p/go-maddr-filter/pull/7)) +- github.com/ipfs/go-merkledag: + - Increase FetchGraphConcurrency to 32 ([ipfs/go-merkledag#29](https://github.com/ipfs/go-merkledag/pull/29)) + - Enable CI ([ipfs/go-merkledag#9](https://github.com/ipfs/go-merkledag/pull/9)) + - fix a fetch deadlock on error ([ipfs/go-merkledag#21](https://github.com/ipfs/go-merkledag/pull/21)) + - Wait for all go routines to finish before function returns ([ipfs/go-merkledag#19](https://github.com/ipfs/go-merkledag/pull/19)) +- github.com/ipfs/go-metrics-prometheus: + - use prometheus instead of gxed ([ipfs/go-metrics-prometheus#3](https://github.com/ipfs/go-metrics-prometheus/pull/3)) +- github.com/ipfs/go-mfs: + - fix(mv): dst filename error ([ipfs/go-mfs#62](https://github.com/ipfs/go-mfs/pull/62)) + - fix over-wait in WaitPub ([ipfs/go-mfs#53](https://github.com/ipfs/go-mfs/pull/53)) + - Fix/32/pr ports from go-ipfs to go-mfs ([ipfs/go-mfs#49](https://github.com/ipfs/go-mfs/pull/49)) + - remove the `fullSync` option from `updateChildEntry` ([ipfs/go-mfs#45](https://github.com/ipfs/go-mfs/pull/45)) + - Various refactorings ([ipfs/go-mfs#36](https://github.com/ipfs/go-mfs/pull/36)) + - use RW lock for the `File`'s lock ([ipfs/go-mfs#43](https://github.com/ipfs/go-mfs/pull/43)) + - add documentation links in README ([ipfs/go-mfs#41](https://github.com/ipfs/go-mfs/pull/41)) + - [WIP] documentation notes ([ipfs/go-mfs#27](https://github.com/ipfs/go-mfs/pull/27)) + - feat(inode): add inode struct ([ipfs/go-mfs#12](https://github.com/ipfs/go-mfs/pull/12)) +- github.com/libp2p/go-mplex: + - fix deadlock ([libp2p/go-mplex#39](https://github.com/libp2p/go-mplex/pull/39)) + - When a stream is closed, cancel pending writes ([libp2p/go-mplex#35](https://github.com/libp2p/go-mplex/pull/35)) + - make sure to but the buffer back in the pool ([libp2p/go-mplex#34](https://github.com/libp2p/go-mplex/pull/34)) + - reduce the packet count ([libp2p/go-mplex#29](https://github.com/libp2p/go-mplex/pull/29)) +- github.com/ipfs/go-path: + - fix: no components error ([ipfs/go-path#18](https://github.com/ipfs/go-path/pull/18)) + - nit: validate CIDs in IPLD paths ([ipfs/go-path#16](https://github.com/ipfs/go-path/pull/16)) +- github.com/libp2p/go-reuseport: + - Fix build on wasm ([libp2p/go-reuseport#59](https://github.com/libp2p/go-reuseport/pull/59)) + - Use Go Control API ([libp2p/go-reuseport#56](https://github.com/libp2p/go-reuseport/pull/56)) + - Support WASM ([libp2p/go-reuseport#54](https://github.com/libp2p/go-reuseport/pull/54)) +- github.com/libp2p/go-reuseport-transport: + - Update to go-reuseport 0.2.0 ([libp2p/go-reuseport-transport#6](https://github.com/libp2p/go-reuseport-transport/pull/6)) +- github.com/libp2p/go-stream-muxer: + - add standard reset error ([libp2p/go-stream-muxer#23](https://github.com/libp2p/go-stream-muxer/pull/23)) + - ci: fix ([libp2p/go-stream-muxer#24](https://github.com/libp2p/go-stream-muxer/pull/24)) + - Document Reset versus Close ([libp2p/go-stream-muxer#18](https://github.com/libp2p/go-stream-muxer/pull/18)) + - WIP document Conn.Close ([libp2p/go-stream-muxer#19](https://github.com/libp2p/go-stream-muxer/pull/19)) +- github.com/libp2p/go-tcp-transport: + - Deprecate IPFS_REUSEPORT, use LIBP2P_TCP_REUSEPORT ([libp2p/go-tcp-transport#27](https://github.com/libp2p/go-tcp-transport/pull/27)) +- github.com/ipfs/go-unixfs: + - unixfile: precalc dir size ([ipfs/go-unixfs#61](https://github.com/ipfs/go-unixfs/pull/61)) + - Archive refactor ([ipfs/go-unixfs#59](https://github.com/ipfs/go-unixfs/pull/59)) + - decouple the DAG traversal logic from the DAG reader (local branch) ([ipfs/go-unixfs#60](https://github.com/ipfs/go-unixfs/pull/60)) + - Unixfs: enforce refs on files when using nocopy ([ipfs/go-unixfs#56](https://github.com/ipfs/go-unixfs/pull/56)) + - Fix/handle overflow ([ipfs/go-unixfs#53](https://github.com/ipfs/go-unixfs/pull/53)) + - feat(Directory): Add EnumLinksAsync method ([ipfs/go-unixfs#39](https://github.com/ipfs/go-unixfs/pull/39)) + + + +## 0.4.18 2018-10-26 + +This is probably one of the largest go-ipfs releases in recent history, 3 months +in the making. + +### Features + +The headline features this release are experimental QUIC support, the gossipsub +pubsub routing algorithm, pubsub message signing, and a refactored `ipfs p2p` +command. However, that's just scratching the surface. + +#### QUIC + +First up, on the networking front, this release has also introduced experimental +support for the QUIC protocol. QUIC is a new UDP-based network transport that +solves many of the long standing issues with TCP. + +For us, this means (eventually): + +* **Fewer local resources.** TCP requires a file-descriptor per connection while + QUIC (and most UDP based transports) can share a single file descriptor + between all connections. This should allow us to dial faster and keep more + connections open. +* **Faster connection establishment.** When client authentication is included, + QUIC has a three-way handshake like TCP. However, unlike TCP, this handshake + brings us from all the way from 0 to a fully encrypted, authenticated, and + multiplexed connection. In theory (not yet in practice), this should + significantly reduce the latency of DHT queries. +* **Behaves better on lossy networks.** When multiplexing multiple requests over + a single TCP connection, a single dropped packet will bring the entire + connection to a halt while the packet is re-transmitted. However, because QUIC + handles multiplexing internally, dropping a single packets affects only the + related stream. +* **Better NAT traversal.** TL;DR: NAT hole-punching is significantly easier + and, in many cases, more reliable with UDP than with TCP. + +However, we still have a long way to go. While we encourage users to test this, +the IETF QUIC protocol is still being actively developed and *will* change. You +can find instructions for enabling it +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#QUIC). + +#### Pubsub + +In terms of pubsub, go-ipfs now supports the gossipsub routing algorithm and +message signing. + +The gossipsub routing algorithm is *significantly* more efficient than the +current floodsub routing algorithm. Even better, it's fully backwards compatible +so you can enable it and still talk to nodes using the floodsub algorithm. You +can find instructions to enable gossipsub in go-ipfs +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#gossipsub). + +Messages are now signed by their authors. While signing has now been enabled by +default, strict signature verification has not been and will not be for at least +one release (probably multiple) to avoid breaking existing applications. You can +read about how to configure this feature +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#message-signing). + +#### Commands + +In terms of new toys, this release introduces a new `ipfs cid` subcommand for +working with CIDs, a completely refactored `ipfs p2p` command, streaming name +resolution, and complete inline block support. + +The new `ipfs cid` command allows users to both inspect CIDs and convert them +between various formats and versions. For example: + +```sh +# Print out the CID metadata (prefix) +> ipfs cid format -f %P QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o +cidv0-protobuf-sha2-256-32 + +# Get the hex sha256 hash from the CID. +> ipfs cid format -b base16 -f '0x%D' QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o +0x46d44814b9c5af141c3aaab7c05dc5e844ead5f91f12858b021eba45768b4c0e + +# Convert a base58 v0 CID to a base32 v1 CID. +> ipfs cid base32 QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o +bafybeicg2rebjoofv4kbyovkw7af3rpiitvnl6i7ckcywaq6xjcxnc2mby +``` + +The refactored `ipfs p2p` command allows forwarding TCP streams through two IPFS +nodes from one host to another. It's `ssh -L` but for IPFS. You can find +documentation +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-p2p). +It's still experimental but we don't expect too many breaking changes at this +point (it will very likely be stabilized in the next release). Quick summary of +breaking changes: + +* We don't stop listening for local (forwarded) connections after accepting a + single connection. +* `ipfs p2p stream ls` output now returns more useful output, first address is + always the initiator address. +* `ipfs p2p listener ls` is renamed to `ipfs p2p ls` +* `ipfs p2p listener close` is renamed to `ipfs p2p close` +* Protocol names have to be prefixed with `/x/` and are now just passed to + libp2p as handler name. Previous version did this 'under the hood' and with + `/p2p/` prefix. There is a `--allow-custom-protocol` flag which allows you + to use any libp2p handler name. +* `ipfs p2p listener open` and `ipfs p2p stream dial` got renamed: + * `ipfs p2p listener open p2p-test /ip4/127.0.0.1/tcp/10101` + new becomes `ipfs p2p listen /x/p2p-test /ip4/127.0.0.1/tcp/10101` + * `ipfs p2p stream dial $NODE_A_PEERID p2p-test /ip4/127.0.0.1/tcp/10102` + is now `ipfs p2p forward /x/p2p-test /ip4/127.0.0.1/tcp/10102 /ipfs/$NODE_A_PEERID` + +There is now a new flag for `ipfs name resolve` - `--stream`. When the command +is invoked with the flag set, it will start returning results as soon as they +are discovered in the DHT and other routing mechanisms. This enables certain +applications to start prefetching/displaying data while the discovery is still +running. Note that this command will likely return many outdated records +before it finding and returning the latest. However, it will always return +*valid* records (even if a bit stale). + +Finally, in the previous release, we added support for extracting blocks inlined +into CIDs. In this release, we've added support for creating these CIDs. You can +now run `ipfs add` with the `--inline` flag to inline blocks less than or equal +to 32 bytes in length into a CID, instead of writing an actual block. This +should significantly reduce the size of filesystem trees with many empty +directories and tiny files. + +#### IPNS + +You can now publish and resolve paths with namespaces *other* than `/ipns` and +`/ipfs` through IPNS. Critically, IPNS can now be used with IPLD paths (paths +starting with `/ipld`). + +#### WebUI + +Finally, this release includes the shiny [updated +webui](https://github.com/ipfs-shipyard/ipfs-webui). You can view it by +installing go-ipfs and visiting http://localhost:5001/webui. + +### Performance + +This release includes some significant performance improvements, both in terms +of resource utilization and speed. This section will go into some technical +details so feel free to skip it if you're just looking for shiny new features. + +#### Resource Utilization + +In this release, we've (a) fixed a slow memory leak in libp2p and (b) +significantly reduced the allocation load. Together, these should improve both +memory and CPU usage. + +##### Datastructures + +We've changed two of our most frequently used datastructures, CIDs and +Multiaddrs, to reduce allocation load. + +First, we now store CIDs *encode* as strings, instead of decoded in structs +(behind pointers). In addition to being more compact, our `Cid` type is now a +valid `map` key so we no longer have to encode CIDs every time we want to use +them in a map/set. Allocations when inserting CIDs into maps/sets was showing up +as a significant source of allocations under heavy load so this change should +improve memory usage. + +Second, we've changed many of our multiaddr parsing/processing/formatting +functions to allocate less. Much of our DHT related-work includes processing +multiaddrs so this should reduce CPU utilization when heavily using the DHT. + +##### Streams and Yamux + +Streams have always plagued us in terms of memory utilization. This was +partially solved by introducing the connection manager, keeping our maximum +connection count to a reasonable number but they're still a major memory sink. + +This release sees two improvements on this front: + +1. A memory [leak in identify](https://github.com/libp2p/go-libp2p/issues/419) + has been fixed. This was slowly causing us to leak connections (locking up + the memory used by the connections' streams). +2. Yamux streams now use a buffer-pool backed, auto shrinking read buffer. + Before, this read buffer would grow to its maximum size (a few megabytes) and + never shrink but these buffers now shrink as they're emptied. + +#### Bitswap Performance + +Bitswap will now pack *multiple* small blocks into a single message thanks +[ipfs/go-bitswap#5](https://github.com/ipfs/go-bitswap/pull/5). While this won't +help when transferring large files (with large blocks), this should help when +transferring many tiny files. + +### Refactors and Endeavors + +This release saw yet another commands-library refactor, work towards the +CoreAPI, and the first step towards reliable base32 CID support. + +#### Commands Lib + +We've completely refactored our commands library (again). While it still needs +quite a bit of work, it now requires significantly less boilerplate and should +be significantly more robust. The refactor immediately found two broken tests +and probably fixed quite a few bugs around properly returning and handling +errors. + +#### CoreAPI + +CoreAPI is a new way to interact with IPFS from Go. While it's still not +final, most things you can do via the CLI or HTTP interfaces, can now be done +through the new API. + +Currently there is only one implementation, backed by go-ipfs node, and there are +plans to start http-api backed one soon. We are also looking into creating RPC +interface using this API, which could help performance in some use cases. + +You can track progress in https://github.com/ipfs/go-ipfs/issues/4498 + +#### IPLD paths + +We introduced new path type which introduces distinction between IPLD and +IPFS (unixfs) paths. From now on paths prefixed with `/ipld/` will always +use IPLD link traversal and `/ipfs/` will use unixfs path resolver, which +takes things like shardnig into account. + +Note that this is only initial support and there likely are some bugs in +how the paths are handled internally, so consider this feature +experimental for now. + +#### CIDv1/Base32 Migration + +Currently, IPFS is usually used in browsers by browsing to +`https://SOME_GATEWAY/ipfs/CID/...`. There are two significant drawbacks to this +approach: + +1. From a browser security standpoint, all IPFS "sites" will live under the same + origin (SOME_GATEWAY). +2. From a UX standpoint, this doesn't feel very "native" (even if the gateway is + a local IPFS node). + +To fix the security issue, we intend to switch IPFS gateway links +`https://ipfs.io/ipfs/CID` to to `https://CID.ipfs.dweb.link`. This way, the CID +will be a part of the +["origin"](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) so +each IPFS website will get a separate security origin. + +To fix the UX issue, we've been working on adding support for `ipfs://CID/...` +to web browsers through our +[ipfs-companion](https://github.com/ipfs/ipfs-companion/) add-on and some new, +experimental extension APIs from Mozilla. This has the same effect of putting +the CID in the URL origin but has the added benefit of looking "native". + +Unfortunately, origins must be *case insensitive*. Currently, most CIDs users +see are *CIDv0* CIDs (those starting with `Qm`) which are *always* base58 +encoded and are therefore case-sensitive. + +Fortunately, CIDv1 (the latest CID format) supports arbitrary bases using the +[multibase](https://github.com/multiformats/multibase/) standard. Unfortunately, +IPFS has always treated equivalent CIDv0 and CIDv1 CIDs as distinct. This means +that files added with CIDv0 CIDs (the default) can't be looked up using the +equivalent CIDv1. + +This release makes some significant progress towards solving this issue by +introducing two features: + +(1) The previous mentioned `ipfs cid base32` command for converting CID to a +case intensive encoding required by domain names. This command converts a CID to +version 1 and encodes it using base32. + +(2) A hack to allow locally looking up blocks associated with a CIDv0 CID using +the equivalent CIDv1 CID (or the reverse). This hack will eventually +be replaced with a multihash indexed blockstore, which is agnostic to both the +CID version and multicodec content type. + +### go-ipfs changelog + +Features (i.e., users take heed): + - gossipsub ([ipfs/go-ipfs#5373](https://github.com/ipfs/go-ipfs/pull/5373)) + - support /ipfs/CID in `ipfs dht findprovs` ([ipfs/go-ipfs#5329](https://github.com/ipfs/go-ipfs/pull/5329)) + - return a json object from config show ([ipfs/go-ipfs#5345](https://github.com/ipfs/go-ipfs/pull/5345)) + - Set filename in Content-Disposition if filename=x is passed in URI query ([ipfs/go-ipfs#4177](https://github.com/ipfs/go-ipfs/pull/4177)) + - Allow mfs files.write command to create parent directories ([ipfs/go-ipfs#5359](https://github.com/ipfs/go-ipfs/pull/5359)) + - Run DNS lookup for --api endpoint provided in CLI ([ipfs/go-ipfs#5372](https://github.com/ipfs/go-ipfs/pull/5372)) + - Add support for inlinling blocks into CIDs the id-hash ([ipfs/go-ipfs#5281](https://github.com/ipfs/go-ipfs/pull/5281)) + - depth limited refs -r ([ipfs/go-ipfs#5337](https://github.com/ipfs/go-ipfs/pull/5337)) + - remove bitswap unwant ([ipfs/go-ipfs#5308](https://github.com/ipfs/go-ipfs/pull/5308)) + - add experimental QUIC support ([ipfs/go-ipfs#5350](https://github.com/ipfs/go-ipfs/pull/5350)) + - add a --stdin-name flag for naming files from stdin ([ipfs/go-ipfs#5399](https://github.com/ipfs/go-ipfs/pull/5399)) + - Refactor `ipfs p2p` ([ipfs/go-ipfs#4929](https://github.com/ipfs/go-ipfs/pull/4929)) + - add dns support in`ipfs p2p forward` and refactor code ([ipfs/go-ipfs#5533](https://github.com/ipfs/go-ipfs/pull/5533)) + - feat(command): expose connection direction ([ipfs/go-ipfs#5457](https://github.com/ipfs/go-ipfs/pull/5457)) + - error when publishing ipns records without a running daemon ([ipfs/go-ipfs#5477](https://github.com/ipfs/go-ipfs/pull/5477)) + - feat(daemon): print version on start ([ipfs/go-ipfs#5503](https://github.com/ipfs/go-ipfs/pull/5503)) + - add quieter option to name publish ([ipfs/go-ipfs#5494](https://github.com/ipfs/go-ipfs/pull/5494)) + - Provide new "cid" sub-command. ([ipfs/go-ipfs#5385](https://github.com/ipfs/go-ipfs/pull/5385)) + - feat(command): add force flag for files rm ([ipfs/go-ipfs#5555](https://github.com/ipfs/go-ipfs/pull/5555)) + - Add support for datastore plugins ([ipfs/go-ipfs#5187](https://github.com/ipfs/go-ipfs/pull/5187)) + - files ls: append slash to directory names ([ipfs/go-ipfs#5605](https://github.com/ipfs/go-ipfs/pull/5605)) + - ipfs name resolve --stream ([ipfs/go-ipfs#5404](https://github.com/ipfs/go-ipfs/pull/5404)) + - update webui to 2.1.0 ([ipfs/go-ipfs#5627](https://github.com/ipfs/go-ipfs/pull/5627)) + - feat: add dry-run flag for config profile apply command ([ipfs/go-ipfs#5455](https://github.com/ipfs/go-ipfs/pull/5455)) + - configurable pubsub signing ([ipfs/go-ipfs#5647](https://github.com/ipfs/go-ipfs/pull/5647)) + +Fixes (i.e., users take note): + - pin update fixes ([ipfs/go-ipfs#5265](https://github.com/ipfs/go-ipfs/pull/5265)) + - Fix inability to pin two things at once ([ipfs/go-ipfs#5512](https://github.com/ipfs/go-ipfs/pull/5512)) + - wait for all connections to close before exiting on shutdown. ([ipfs/go-ipfs#5322](https://github.com/ipfs/go-ipfs/pull/5322)) + - Fixed ipns address resolution in fuse unix mount ([ipfs/go-ipfs#5384](https://github.com/ipfs/go-ipfs/pull/5384)) + - core/commands/ls: wrap `NewDirectoryFromNode` error ([ipfs/go-ipfs#5166](https://github.com/ipfs/go-ipfs/pull/5166)) + - fix goroutine leaks in filestore.go ([ipfs/go-ipfs#5427](https://github.com/ipfs/go-ipfs/pull/5427)) + - move VersionOption after GatewayOption to fix #5422 ([ipfs/go-ipfs#5424](https://github.com/ipfs/go-ipfs/pull/5424)) + - fix(commands): fix filestore.go goroutine leak ([ipfs/go-ipfs#5439](https://github.com/ipfs/go-ipfs/pull/5439)) + - fix(commands): goroutine leaks in ping.go ([ipfs/go-ipfs#5444](https://github.com/ipfs/go-ipfs/pull/5444)) + - fix output of object command ([ipfs/go-ipfs#5459](https://github.com/ipfs/go-ipfs/pull/5459)) + - add warning when no bootstrap in config ([ipfs/go-ipfs#5445](https://github.com/ipfs/go-ipfs/pull/5445)) + - fix behaviour of key rename to same name ([ipfs/go-ipfs#5465](https://github.com/ipfs/go-ipfs/pull/5465)) + - fix(object): print object diff error ([ipfs/go-ipfs#5469](https://github.com/ipfs/go-ipfs/pull/5469)) + - fix(pin): goroutine leaks ([ipfs/go-ipfs#5453](https://github.com/ipfs/go-ipfs/pull/5453)) + - fix offline id bug ([ipfs/go-ipfs#5486](https://github.com/ipfs/go-ipfs/pull/5486)) + - files cp: improve flush error message ([ipfs/go-ipfs#5485](https://github.com/ipfs/go-ipfs/pull/5485)) + - resolve: fix unixfs resolution through sharded directories ([ipfs/go-ipfs#5484](https://github.com/ipfs/go-ipfs/pull/5484)) + - Switch name publish/resolve to coreapi ([ipfs/go-ipfs#5563](https://github.com/ipfs/go-ipfs/pull/5563)) + - use CoreAPI resolver everywhere (fixes sharded directory resolution) ([ipfs/go-ipfs#5492](https://github.com/ipfs/go-ipfs/pull/5492)) + - add pin lock in AddallPin function ([ipfs/go-ipfs#5506](https://github.com/ipfs/go-ipfs/pull/5506)) + - take the pinlock when updating pins ([ipfs/go-ipfs#5550](https://github.com/ipfs/go-ipfs/pull/5550)) + - fix(object): add support for raw leaves in object diff ([ipfs/go-ipfs#5472](https://github.com/ipfs/go-ipfs/pull/5472)) + - don't use the domain name as a filename in /ipns/a.com ([ipfs/go-ipfs#5564](https://github.com/ipfs/go-ipfs/pull/5564)) + - refactor(command): modify int to int64 ([ipfs/go-ipfs#5612](https://github.com/ipfs/go-ipfs/pull/5612)) + - fix(core): ipns config RecordLifetime panic ([ipfs/go-ipfs#5648](https://github.com/ipfs/go-ipfs/pull/5648)) + - simplify dag put and correctly take pin lock ([ipfs/go-ipfs#5667](https://github.com/ipfs/go-ipfs/pull/5667)) + - fix prometheus concurrent map write bug ([ipfs/go-ipfs#5706](https://github.com/ipfs/go-ipfs/pull/5706)) + +Regressions Fixes (fixes for bugs introduced since the last release): + - namesys: properly attach path in name.Resolve ([ipfs/go-ipfs#5660](https://github.com/ipfs/go-ipfs/pull/5660)) + - fix(p2p): issue #5523 ([ipfs/go-ipfs#5529](https://github.com/ipfs/go-ipfs/pull/5529)) + - fix infinite loop in `stats bw` ([ipfs/go-ipfs#5598](https://github.com/ipfs/go-ipfs/pull/5598)) + - make warnings on no bootstrap peers less noisy ([ipfs/go-ipfs#5466](https://github.com/ipfs/go-ipfs/pull/5466)) + - fix two transport related bugs ([ipfs/go-ipfs#5417](https://github.com/ipfs/go-ipfs/pull/5417)) + - Fix pin ls output when hash is specified ([ipfs/go-ipfs#5699](https://github.com/ipfs/go-ipfs/pull/5699)) + - ping: switch to the ping service enabled in the libp2p constructor ([ipfs/go-ipfs#5698](https://github.com/ipfs/go-ipfs/pull/5698)) + - commands: fix a bunch of tiny commands-lib issues ([ipfs/go-ipfs#5697](https://github.com/ipfs/go-ipfs/pull/5697)) + - cleanup the ping command ([ipfs/go-ipfs#5680](https://github.com/ipfs/go-ipfs/pull/5680)) + - fix gossipsub goroutine explosion ([ipfs/go-ipfs#5688](https://github.com/ipfs/go-ipfs/pull/5688)) + - fix(cmd/gc): Run func does not return error when Emit func returns error ([ipfs/go-ipfs#5687](https://github.com/ipfs/go-ipfs/pull/5687)) + +Extractions: + - Extract bitswap to go-bitswap ([ipfs/go-ipfs#5294](https://github.com/ipfs/go-ipfs/pull/5294)) + - Extract blockservice and verifcid ([ipfs/go-ipfs#5296](https://github.com/ipfs/go-ipfs/pull/5296)) + - Extract merkledag package, move dagutils to top level ([ipfs/go-ipfs#5298](https://github.com/ipfs/go-ipfs/pull/5298)) + - Extract path and resolver ([ipfs/go-ipfs#5306](https://github.com/ipfs/go-ipfs/pull/5306)) + - Extract config package ([ipfs/go-ipfs#5277](https://github.com/ipfs/go-ipfs/pull/5277)) + - Extract unixfs and importers to go-unixfs ([ipfs/go-ipfs#5316](https://github.com/ipfs/go-ipfs/pull/5316)) + - delete unixfs code... ([ipfs/go-ipfs#5319](https://github.com/ipfs/go-ipfs/pull/5319)) + - Extract /mfs to github.com/ipfs/go-mfs ([ipfs/go-ipfs#5391](https://github.com/ipfs/go-ipfs/pull/5391)) + - re-format log output as ndjson ([ipfs/go-ipfs#5708](https://github.com/ipfs/go-ipfs/pull/5708)) + - error on resolving non-terminal paths ([ipfs/go-ipfs#5705](https://github.com/ipfs/go-ipfs/pull/5705)) + +Documentation: + - document the fact that we now publish releases on GitHub ([ipfs/go-ipfs#5301](https://github.com/ipfs/go-ipfs/pull/5301)) + - docs: add url to dev weekly sync to the README ([ipfs/go-ipfs#5371](https://github.com/ipfs/go-ipfs/pull/5371)) + - docs: README refresh, add cli-http-api-core diagram ([ipfs/go-ipfs#5396](https://github.com/ipfs/go-ipfs/pull/5396)) + - add some basic gateway documentation ([ipfs/go-ipfs#5393](https://github.com/ipfs/go-ipfs/pull/5393)) + - fix the default gateway port ([ipfs/go-ipfs#5419](https://github.com/ipfs/go-ipfs/pull/5419)) + - fix order of events in the release process ([ipfs/go-ipfs#5434](https://github.com/ipfs/go-ipfs/pull/5434)) + - docs: add some minimal read-only API documentation ([ipfs/go-ipfs#5437](https://github.com/ipfs/go-ipfs/pull/5437)) + - feat: use package-table ([ipfs/go-ipfs#5395](https://github.com/ipfs/go-ipfs/pull/5395)) + - link to go-{libp2p,ipld} package tables ([ipfs/go-ipfs#5446](https://github.com/ipfs/go-ipfs/pull/5446)) + - api: fix outdated HTTPHeaders config documentation ([ipfs/go-ipfs#5451](https://github.com/ipfs/go-ipfs/pull/5451)) + - add version, usage, and planning info for urlstore ([ipfs/go-ipfs#5552](https://github.com/ipfs/go-ipfs/pull/5552)) + - debug-guide.md added memory statistics command ([ipfs/go-ipfs#5546](https://github.com/ipfs/go-ipfs/pull/5546)) + - Change to point to combined go contributing guidelines ([ipfs/go-ipfs#5607](https://github.com/ipfs/go-ipfs/pull/5607)) + - docs: Update link format ([ipfs/go-ipfs#5617](https://github.com/ipfs/go-ipfs/pull/5617)) + - Fix link in readme ([ipfs/go-ipfs#5632](https://github.com/ipfs/go-ipfs/pull/5632)) + - docs: add a note for dns command ([ipfs/go-ipfs#5629](https://github.com/ipfs/go-ipfs/pull/5629)) + - Dockerfile: Specifies comments on exposed ports ([ipfs/go-ipfs#5615](https://github.com/ipfs/go-ipfs/pull/5615)) + - document pubsub message signing ([ipfs/go-ipfs#5669](https://github.com/ipfs/go-ipfs/pull/5669)) + +Testing: + - Include cid-fmt binary in test/bin. ([ipfs/go-ipfs#5297](https://github.com/ipfs/go-ipfs/pull/5297)) + - wait for the nodes to fully stop ([ipfs/go-ipfs#5315](https://github.com/ipfs/go-ipfs/pull/5315)) + - apply timeout for build steps after getting node ([ipfs/go-ipfs#5313](https://github.com/ipfs/go-ipfs/pull/5313)) + - ci: check for gx deps dupes ([ipfs/go-ipfs#5338](https://github.com/ipfs/go-ipfs/pull/5338)) + - ci: call cleanWs after each step ([ipfs/go-ipfs#5374](https://github.com/ipfs/go-ipfs/pull/5374)) + - add correct test for GC completeness ([ipfs/go-ipfs#5364](https://github.com/ipfs/go-ipfs/pull/5364)) + - fix the urlstore tests ([ipfs/go-ipfs#5397](https://github.com/ipfs/go-ipfs/pull/5397)) + - improve gateway options test ([ipfs/go-ipfs#5433](https://github.com/ipfs/go-ipfs/pull/5433)) + - coreapi name: Increase test swarm size ([ipfs/go-ipfs#5481](https://github.com/ipfs/go-ipfs/pull/5481)) + - fix fuse unmount test ([ipfs/go-ipfs#5476](https://github.com/ipfs/go-ipfs/pull/5476)) + - test(add): add test for issue \#5456 ([ipfs/go-ipfs#5493](https://github.com/ipfs/go-ipfs/pull/5493)) + - fixed tests of raised fd limits ([ipfs/go-ipfs#5496](https://github.com/ipfs/go-ipfs/pull/5496)) + - pprof: create HTTP endpoint for setting MutexProfileFraction ([ipfs/go-ipfs#5527](https://github.com/ipfs/go-ipfs/pull/5527)) + - fix(command):update `add --chunker` test ([ipfs/go-ipfs#5571](https://github.com/ipfs/go-ipfs/pull/5571)) + - switch to go 1.11 ([ipfs/go-ipfs#5483](https://github.com/ipfs/go-ipfs/pull/5483)) + - fix: sharness race in directory_size if file is removed ([ipfs/go-ipfs#5586](https://github.com/ipfs/go-ipfs/pull/5586)) + - Bump Go versions and use '.x' to always get latest minor versions ([ipfs/go-ipfs#5682](https://github.com/ipfs/go-ipfs/pull/5682)) + - add rabin min error test ([ipfs/go-ipfs#5449](https://github.com/ipfs/go-ipfs/pull/5449)) + - Use CircleCI 2.0 ([ipfs/go-ipfs#5691](https://github.com/ipfs/go-ipfs/pull/5691)) + +Internal: + - Add ability to retrieve blocks even if given using a different CID version ([ipfs/go-ipfs#5285](https://github.com/ipfs/go-ipfs/pull/5285)) + - update gogo-protobuf ([ipfs/go-ipfs#5355](https://github.com/ipfs/go-ipfs/pull/5355)) + - update protobuf files in go-ipfs ([ipfs/go-ipfs#5356](https://github.com/ipfs/go-ipfs/pull/5356)) + - string-backed CIDs ([ipfs/go-ipfs#5441](https://github.com/ipfs/go-ipfs/pull/5441)) + - commands: switch object to CoreAPI ([ipfs/go-ipfs#4643](https://github.com/ipfs/go-ipfs/pull/4643)) + - coreapi: dag: Batching interface ([ipfs/go-ipfs#5340](https://github.com/ipfs/go-ipfs/pull/5340)) + - key cmd: Refactor to use coreapi ([ipfs/go-ipfs#5339](https://github.com/ipfs/go-ipfs/pull/5339)) + - coreapi: DHT API ([ipfs/go-ipfs#4804](https://github.com/ipfs/go-ipfs/pull/4804)) + - block cmd: Use coreapi ([ipfs/go-ipfs#5331](https://github.com/ipfs/go-ipfs/pull/5331)) + - mk: embed CurrentCommit in the right place ([ipfs/go-ipfs#5507](https://github.com/ipfs/go-ipfs/pull/5507)) + - added binary executable files to .dockerignore ([ipfs/go-ipfs#5544](https://github.com/ipfs/go-ipfs/pull/5544)) + - Add sessions when fetching MerkleDAG in LS ([ipfs/go-ipfs#5509](https://github.com/ipfs/go-ipfs/pull/5509)) + - coreapi: Swarm API ([ipfs/go-ipfs#4803](https://github.com/ipfs/go-ipfs/pull/4803)) + - coreapi swarm: unify impl type with other apis ([ipfs/go-ipfs#5551](https://github.com/ipfs/go-ipfs/pull/5551)) + - Refactor UnixFS CoreAPI ([ipfs/go-ipfs#5501](https://github.com/ipfs/go-ipfs/pull/5501)) + - coreapi: PubSub API ([ipfs/go-ipfs#4805](https://github.com/ipfs/go-ipfs/pull/4805)) + - fix: maketarball.sh for OSX ([ipfs/go-ipfs#5575](https://github.com/ipfs/go-ipfs/pull/5575)) + - test the correct return value when checking directory size ([ipfs/go-ipfs#5580](https://github.com/ipfs/go-ipfs/pull/5580)) + - coreapi unixfs: remove Cat ([ipfs/go-ipfs#5574](https://github.com/ipfs/go-ipfs/pull/5574)) + - Explicitally use BufferedDAG after removing Batch from importers ([ipfs/go-ipfs#5626](https://github.com/ipfs/go-ipfs/pull/5626)) + +Cleanup: + - Fix some weird code in core/coreunix/add.go ([ipfs/go-ipfs#5354](https://github.com/ipfs/go-ipfs/pull/5354)) + - name cmd: move subcommands to subdirectory ([ipfs/go-ipfs#5392](https://github.com/ipfs/go-ipfs/pull/5392)) + - directly parse peer IDs as peer IDs ([ipfs/go-ipfs#5409](https://github.com/ipfs/go-ipfs/pull/5409)) + - don't bother caching if we're using a nil repo ([ipfs/go-ipfs#5414](https://github.com/ipfs/go-ipfs/pull/5414)) + - object:refactor data encode error ([ipfs/go-ipfs#5426](https://github.com/ipfs/go-ipfs/pull/5426)) + - remove Godeps ([ipfs/go-ipfs#5440](https://github.com/ipfs/go-ipfs/pull/5440)) + - update for the go-ipfs-cmds refactor ([ipfs/go-ipfs#5035](https://github.com/ipfs/go-ipfs/pull/5035)) + - fix(unixfs): issue #5217 (Avoid use of `pb.Data`) ([ipfs/go-ipfs#5505](https://github.com/ipfs/go-ipfs/pull/5505)) + - fix(unixfs): issue #5055 ([ipfs/go-ipfs#5525](https://github.com/ipfs/go-ipfs/pull/5525)) + - add offline id test #4978 and refactor command code ([ipfs/go-ipfs#5562](https://github.com/ipfs/go-ipfs/pull/5562)) + - refact(command): replace option name with const string ([ipfs/go-ipfs#5642](https://github.com/ipfs/go-ipfs/pull/5642)) + - remove p2p-circuit addr hack in ipfs swarm peers ([ipfs/go-ipfs#5645](https://github.com/ipfs/go-ipfs/pull/5645)) + - refactor(commands/id): use new command ([ipfs/go-ipfs#5646](https://github.com/ipfs/go-ipfs/pull/5646)) + - object patch rm-link: change arg from 'link' to 'name' ([ipfs/go-ipfs#5638](https://github.com/ipfs/go-ipfs/pull/5638)) + - refactor(cmds): use new cmds lib in version, tar and dns ([ipfs/go-ipfs#5650](https://github.com/ipfs/go-ipfs/pull/5650)) + - cmds/dag: use new cmds lib ([ipfs/go-ipfs#5662](https://github.com/ipfs/go-ipfs/pull/5662)) + - commands/ping: use new cmds lib ([ipfs/go-ipfs#5675](https://github.com/ipfs/go-ipfs/pull/5675)) + +### related changelogs + +Changes to sub-packages go-ipfs depends on. This *does not* include libp2p or multiformats. + +github.com/ipfs/go-log + - update gogo protobuf ([ipfs/go-log#39](https://github.com/ipfs/go-log/pull/39)) + - rename the protobuf to loggabletracer ([ipfs/go-log#41](https://github.com/ipfs/go-log/pull/41)) + - protect loggers with rwmutex ([ipfs/go-log#44](https://github.com/ipfs/go-log/pull/44)) + - make logging prettier ([ipfs/go-log#45](https://github.com/ipfs/go-log/pull/45)) + - add env vars for logging to file and syslog ([ipfs/go-log#46](https://github.com/ipfs/go-log/pull/46)) + - remove syslogger ([ipfs/go-log#47](https://github.com/ipfs/go-log/pull/47)) + +github.com/ipfs/go-datastore + - implement DiskUsage for the rest of the datastores ([ipfs/go-datastore#86](https://github.com/ipfs/go-datastore/pull/86)) + - switch to google's uuid library ([ipfs/go-datastore#89](https://github.com/ipfs/go-datastore/pull/89)) + - return ErrNotFound from the NullDatastore instead of nil, nil ([ipfs/go-datastore#92](https://github.com/ipfs/go-datastore/pull/92)) + - Add TTL and Transactional interfaces ([ipfs/go-datastore#91](https://github.com/ipfs/go-datastore/pull/91)) + - improve testing ([ipfs/go-datastore#93](https://github.com/ipfs/go-datastore/pull/93)) + - Add support for querying entry expiration ([ipfs/go-datastore#96](https://github.com/ipfs/go-datastore/pull/96)) + - Allow ds.NewTransaction() to return an error ([ipfs/go-datastore#98](https://github.com/ipfs/go-datastore/pull/98)) + - add a GetSize method ([ipfs/go-datastore#99](https://github.com/ipfs/go-datastore/pull/99)) + +github.com/ipfs/go-cid + - Add tests for Set type ([ipfs/go-cid#63](https://github.com/ipfs/go-cid/pull/63)) + - Create new Builder interface for creating CIDs. ([ipfs/go-cid#53](https://github.com/ipfs/go-cid/pull/53)) + - cid-fmt Enhancments ([ipfs/go-cid#61](https://github.com/ipfs/go-cid/pull/61)) + - add String benchmark ([ipfs/go-cid#44](https://github.com/ipfs/go-cid/pull/44)) + - add a streaming CID set ([ipfs/go-cid#67](https://github.com/ipfs/go-cid/pull/67)) + - Extract non-core functionality from go-cid into go-cidutil ([ipfs/go-cid#69](https://github.com/ipfs/go-cid/pull/69)) + - cid implementation research ([ipfs/go-cid#70](https://github.com/ipfs/go-cid/pull/70)) + - cid implementation variations++ ([ipfs/go-cid#72](https://github.com/ipfs/go-cid/pull/72)) + - Create a new Encode method that is like StringOfBase but never errors ([ipfs/go-cid#60](https://github.com/ipfs/go-cid/pull/60)) + - add codecs for Dash blocks, tx ([ipfs/go-cid#78](https://github.com/ipfs/go-cid/pull/78)) + +github.com/ipfs/go-ds-flatfs + - check error before defer-removing disk usage file ([ipfs/go-ds-flatfs#47](https://github.com/ipfs/go-ds-flatfs/pull/47)) + - add GetSize function ([ipfs/go-ds-flatfs#48](https://github.com/ipfs/go-ds-flatfs/pull/48)) + +github.com/ipfs/go-ds-measure + - ([ipfs/go-ds-measure#](https://github.com/ipfs/go-ds-measure/pull/)) + +github.com/ipfs/go-ds-leveldb + - recover datastore on corruption ([ipfs/go-ds-leveldb#15](https://github.com/ipfs/go-ds-leveldb/pull/15)) + - Add transactional support to leveldb datastore. ([ipfs/go-ds-leveldb#17](https://github.com/ipfs/go-ds-leveldb/pull/17)) + - implement GetSize ([ipfs/go-ds-leveldb#18](https://github.com/ipfs/go-ds-leveldb/pull/18)) + +github.com/ipfs/go-metrics-prometheus + - use an existing metric when it has already been registered ([ipfs/go-metrics-prometheus#1](https://github.com/ipfs/go-metrics-prometheus/pull/1)) + +github.com/ipfs/go-metrics-interface + - update the counter interface to match prometheus ([ipfs/go-metrics-interface#2](https://github.com/ipfs/go-metrics-interface/pull/2)) + +github.com/ipfs/go-ipld-format + - add copy dagservice function ([ipfs/go-ipld-format#41](https://github.com/ipfs/go-ipld-format/pull/41)) + +github.com/ipfs/go-ipld-cbor + - Refactor to refmt ([ipfs/go-ipld-cbor#30](https://github.com/ipfs/go-ipld-cbor/pull/30)) + - import changes from the filecoin branch ([ipfs/go-ipld-cbor#41](https://github.com/ipfs/go-ipld-cbor/pull/41)) + - register the BitIntAtlasEntry for the tests ([ipfs/go-ipld-cbor#43](https://github.com/ipfs/go-ipld-cbor/pull/43)) + - attempt to allocate a bit less ([ipfs/go-ipld-cbor#45](https://github.com/ipfs/go-ipld-cbor/pull/45)) + +github.com/ipfs/go-ipfs-cmds + - check if we can decode an error before trying ([ipfs/go-ipfs-cmds#108](https://github.com/ipfs/go-ipfs-cmds/pull/108)) + - fix(option): print error message for error timeout option ([ipfs/go-ipfs-cmds#118](https://github.com/ipfs/go-ipfs-cmds/pull/118)) + - Create Jenkinsfile ([ipfs/go-ipfs-cmds#89](https://github.com/ipfs/go-ipfs-cmds/pull/89)) + - fix(add): refer to ipfs issue #5456 ([ipfs/go-ipfs-cmds#121](https://github.com/ipfs/go-ipfs-cmds/pull/121)) + - commands refactor 2.0 ([ipfs/go-ipfs-cmds#112](https://github.com/ipfs/go-ipfs-cmds/pull/112)) + - always assign keks to review new PRs ([ipfs/go-ipfs-cmds#123](https://github.com/ipfs/go-ipfs-cmds/pull/123)) + - extract go-ipfs-files ([ipfs/go-ipfs-cmds#125](https://github.com/ipfs/go-ipfs-cmds/pull/125)) + - split the value encoder and the error encoder ([ipfs/go-ipfs-cmds#128](https://github.com/ipfs/go-ipfs-cmds/pull/128)) + +github.com/ipfs/go-ipfs-cmdkit + - all: gofmt ([ipfs/go-ipfs-cmdkit#22](https://github.com/ipfs/go-ipfs-cmdkit/pull/22)) + - add standard ci scripts ([ipfs/go-ipfs-cmdkit#23](https://github.com/ipfs/go-ipfs-cmdkit/pull/23)) + - only count size for regular files ([ipfs/go-ipfs-cmdkit#25](https://github.com/ipfs/go-ipfs-cmdkit/pull/25)) + - Create Jenkinsfile ([ipfs/go-ipfs-cmdkit#16](https://github.com/ipfs/go-ipfs-cmdkit/pull/16)) + - Feat: add WebFile File implementation. ([ipfs/go-ipfs-cmdkit#26](https://github.com/ipfs/go-ipfs-cmdkit/pull/26)) + - feat(type): fix issue #28 ([ipfs/go-ipfs-cmdkit#29](https://github.com/ipfs/go-ipfs-cmdkit/pull/29)) + - Extract files package ([ipfs/go-ipfs-cmdkit#31](https://github.com/ipfs/go-ipfs-cmdkit/pull/31)) + +github.com/ipfs/go-ds-badger + - update protobuf ([ipfs/go-ds-badger#26](https://github.com/ipfs/go-ds-badger/pull/26)) + - exported type datastore => Datastore ([ipfs/go-ds-badger#1](https://github.com/ipfs/go-ds-badger/pull/1)) + - using exported Datastore type ([ipfs/go-ds-badger#2](https://github.com/ipfs/go-ds-badger/pull/2)) + - exported type datastore => Datastore ([ipfs/go-ds-badger#28](https://github.com/ipfs/go-ds-badger/pull/28)) + - Implement new TxDatastore and Txn interfaces ([ipfs/go-ds-badger#27](https://github.com/ipfs/go-ds-badger/pull/27)) + - Avoid discarding transaction too early in queries ([ipfs/go-ds-badger#31](https://github.com/ipfs/go-ds-badger/pull/31)) + - Ability to get entry expirations ([ipfs/go-ds-badger#32](https://github.com/ipfs/go-ds-badger/pull/32)) + - Update badger to 2.8.0 ([ipfs/go-ds-badger#33](https://github.com/ipfs/go-ds-badger/pull/33)) + - ds.NewTransaction() now returns an error parameter ([ipfs/go-ds-badger#36](https://github.com/ipfs/go-ds-badger/pull/36)) + - make has faster ([ipfs/go-ds-badger#37](https://github.com/ipfs/go-ds-badger/pull/37)) + - Implement GetSize and update badger ([ipfs/go-ds-badger#38](https://github.com/ipfs/go-ds-badger/pull/38)) + +github.com/ipfs/go-ipfs-addr + - Remove dependency on libp2p-circuit ([ipfs/go-ipfs-addr#7](https://github.com/ipfs/go-ipfs-addr/pull/7)) + +github.com/ipfs/go-ipfs-chunker + - return err when rabin min less than 16 ([ipfs/go-ipfs-chunker#3](https://github.com/ipfs/go-ipfs-chunker/pull/3)) + - switch to go-buffer-pool ([ipfs/go-ipfs-chunker#8](https://github.com/ipfs/go-ipfs-chunker/pull/8)) + - fix size-0 chunker bug ([ipfs/go-ipfs-chunker#9](https://github.com/ipfs/go-ipfs-chunker/pull/9)) + +github.com/ipfs/go-ipfs-routing + - update protobuf ([ipfs/go-ipfs-routing#8](https://github.com/ipfs/go-ipfs-routing/pull/8)) + - Implement SearchValue ([ipfs/go-ipfs-routing#12](https://github.com/ipfs/go-ipfs-routing/pull/12)) + +github.com/ipfs/go-ipfs-blockstore + - blockstore: Adding Stat method to map from Cid to BlockSize ([ipfs/go-ipfs-blockstore#5](https://github.com/ipfs/go-ipfs-blockstore/pull/5)) + - correctly convert the datastore not found errors ([ipfs/go-ipfs-blockstore#10](https://github.com/ipfs/go-ipfs-blockstore/pull/10)) + - Fix typo: Change 'should not' to 'should' ([ipfs/go-ipfs-blockstore#14](https://github.com/ipfs/go-ipfs-blockstore/pull/14)) + - fix test race condition ([ipfs/go-ipfs-blockstore#9](https://github.com/ipfs/go-ipfs-blockstore/pull/9)) + - make arccache.GetSize return ErrNotFound when not found ([ipfs/go-ipfs-blockstore#16](https://github.com/ipfs/go-ipfs-blockstore/pull/16)) + - use datastore.GetSize ([ipfs/go-ipfs-blockstore#17](https://github.com/ipfs/go-ipfs-blockstore/pull/17)) + +github.com/ipfs/go-ipns + - update gogo protobuf ([ipfs/go-ipns#16](https://github.com/ipfs/go-ipns/pull/16)) + - use new ExtractPublicKey signature ([ipfs/go-ipns#17](https://github.com/ipfs/go-ipns/pull/17)) + +github.com/ipfs/go-bitswap + - update gogo protobuf ([ipfs/go-bitswap#2](https://github.com/ipfs/go-bitswap/pull/2)) + - ci: add jenkins ([ipfs/go-bitswap#9](https://github.com/ipfs/go-bitswap/pull/9)) + - bitswap: Bitswap now sends multiple blocks per message ([ipfs/go-bitswap#5](https://github.com/ipfs/go-bitswap/pull/5)) + - reduce allocations ([ipfs/go-bitswap#12](https://github.com/ipfs/go-bitswap/pull/12)) + - buffer writes ([ipfs/go-bitswap#15](https://github.com/ipfs/go-bitswap/pull/15)) + - delay finding providers ([ipfs/go-bitswap#17](https://github.com/ipfs/go-bitswap/pull/17)) +github.com/ipfs/go-blockservice + - Avoid allocating a session unless we need it ([ipfs/go-blockservice#6](https://github.com/ipfs/go-blockservice/pull/6)) + +github.com/ipfs/go-cidutil + - add a utility method for sorting CID slices ([ipfs/go-cidutil#5](https://github.com/ipfs/go-cidutil/pull/5)) + +github.com/ipfs/go-ipfs-config + - Add pubsub configuration options ([ipfs/go-ipfs-config#3](https://github.com/ipfs/go-ipfs-config/pull/3)) + - add QUIC experiment ([ipfs/go-ipfs-config#4](https://github.com/ipfs/go-ipfs-config/pull/4)) + - Add Gateway.APICommands for /api allowlists ([ipfs/go-ipfs-config#10](https://github.com/ipfs/go-ipfs-config/pull/10)) + - allow multiple API/Gateway addresses ([ipfs/go-ipfs-config#11](https://github.com/ipfs/go-ipfs-config/pull/11)) + - Fix handling of null strings ([ipfs/go-ipfs-config#12](https://github.com/ipfs/go-ipfs-config/pull/12)) + - add experiment for p2p http proxy ([ipfs/go-ipfs-config#13](https://github.com/ipfs/go-ipfs-config/pull/13)) + - add message signing config options ([ipfs/go-ipfs-config#18](https://github.com/ipfs/go-ipfs-config/pull/18)) + +github.com/ipfs/go-merkledag + - Add FetchGraphWithDepthLimit to specify depth-limited graph fetching. ([ipfs/go-merkledag#2](https://github.com/ipfs/go-merkledag/pull/2)) + - update gogo protobuf ([ipfs/go-merkledag#4](https://github.com/ipfs/go-merkledag/pull/4)) + - Update to use new Builder interface for creating CIDs. ([ipfs/go-merkledag#6](https://github.com/ipfs/go-merkledag/pull/6)) + - perf: avoid allocations when filtering nodes ([ipfs/go-merkledag#11](https://github.com/ipfs/go-merkledag/pull/11)) + +github.com/ipfs/go-mfs + - fix(unixfs): issue #6 ([ipfs/go-mfs#7](https://github.com/ipfs/go-mfs/pull/7)) + - fix(type): issue #13 ([ipfs/go-mfs#14](https://github.com/ipfs/go-mfs/pull/14)) + +github.com/ipfs/go-path + - fix: don't dag.Get in ResolveToLastNode when not needed ([ipfs/go-path#1](https://github.com/ipfs/go-path/pull/1)) + +github.com/ipfs/go-unixfs + - update gogo protobuf ([ipfs/go-unixfs#6](https://github.com/ipfs/go-unixfs/pull/6)) + - Update to use new Builder interface for creating CIDs. ([ipfs/go-unixfs#7](https://github.com/ipfs/go-unixfs/pull/7)) + - nit: make dagTruncate a method on DagModifier ([ipfs/go-unixfs#13](https://github.com/ipfs/go-unixfs/pull/13)) + - fix(fsnode): issue #17 ([ipfs/go-unixfs#18](https://github.com/ipfs/go-unixfs/pull/18)) + - Use EnumerateChildrenAsync in for enumerating HAMT links ([ipfs/go-unixfs#19](https://github.com/ipfs/go-unixfs/pull/19)) + +## 0.4.17 2018-07-27 + +Ipfs 0.4.17 is a quick release to fix a major performance regression in bitswap +(mostly affecting go-ipfs -> js-ipfs transfers). However, while motivated by +this fix, this release contains a few other goodies that will excite some users. + +The headline feature in this release is [urlstore][] support. Urlstore is a +generalization of the filestore backend that can fetch file blocks from remote +URLs on-demand instead of storing them in the local datastore. + +Additionally, we've added support for extracting inline blocks from CIDs (blocks +inlined into CIDs using the identity hash function). However, go-ipfs won't yet +*create* such CIDs so you're unlikely to see any in the wild. + +[urlstore]: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-urlstore + +Features: + +* URLStore ([ipfs/go-ipfs#4896](https://github.com/ipfs/go-ipfs/pull/4896)) +* Add trickle-dag support to the urlstore ([ipfs/go-ipfs#5245](https://github.com/ipfs/go-ipfs/pull/5245)). +* Allow specifying how the data field in the `object get` is encoded ([ipfs/go-ipfs#5139](https://github.com/ipfs/go-ipfs/pull/5139)) +* Add a `-U` flag to `files ls` to disable sorting ([ipfs/go-ipfs#5219](https://github.com/ipfs/go-ipfs/pull/5219)) +* Add an efficient `--size-only` flag to the `repo stat` ([ipfs/go-ipfs#5010](https://github.com/ipfs/go-ipfs/pull/5010)) +* Inline blocks in CIDs ([ipfs/go-ipfs#5117](https://github.com/ipfs/go-ipfs/pull/5117)) + +Changes/Fixes: + +* Make `ipfs files ls -l` correctly report the hash and size of files ([ipfs/go-ipfs#5045](https://github.com/ipfs/go-ipfs/pull/5045)) +* Fix sorting of `files ls` ([ipfs/go-ipfs#5219](https://github.com/ipfs/go-ipfs/pull/5219)) +* Improve prefetching in `ipfs cat` and related commands ([ipfs/go-ipfs#5162](https://github.com/ipfs/go-ipfs/pull/5162)) +* Better error message when `ipfs cp` fails ([ipfs/go-ipfs#5218](https://github.com/ipfs/go-ipfs/pull/5218)) +* Don't wait for the peer to close it's end of a bitswap stream before considering the block "sent" ([ipfs/go-ipfs#5258](https://github.com/ipfs/go-ipfs/pull/5258)) +* Fix resolving links in sharded directories via the gateway ([ipfs/go-ipfs#5271](https://github.com/ipfs/go-ipfs/pull/5271)) +* Fix building when there's a space in the current directory ([ipfs/go-ipfs#5261](https://github.com/ipfs/go-ipfs/pull/5261)) + +Documentation: + +* Improve documentation about the bloomfilter config options ([ipfs/go-ipfs#4924](https://github.com/ipfs/go-ipfs/pull/4924)) + +General refactorings and internal bug fixes: + +* Remove the `Offset()` method from the DAGReader ([ipfs/go-ipfs#5190](https://github.com/ipfs/go-ipfs/pull/5190)) +* Fix TestLargeWriteChunks seek behavior ([ipfs/go-ipfs#5276](https://github.com/ipfs/go-ipfs/pull/5276)) +* Add a build tag to disable dynamic plugins ([ipfs/go-ipfs#5274](https://github.com/ipfs/go-ipfs/pull/5274)) +* Use FSNode instead of the Protobuf structure in PBDagReader ([ipfs/go-ipfs#5189](https://github.com/ipfs/go-ipfs/pull/5189)) +* Remove support for non-directory MFS roots ([ipfs/go-ipfs#5170](https://github.com/ipfs/go-ipfs/pull/5170)) +* Remove `UnixfsNode` from the balanced builder ([ipfs/go-ipfs#5118](https://github.com/ipfs/go-ipfs/pull/5118)) +* Fix truncating files (internal) when already at the correct size ([ipfs/go-ipfs#5253](https://github.com/ipfs/go-ipfs/pull/5253)) +* Fix `dagTruncate` (internal) to preserve the node type ([ipfs/go-ipfs#5216](https://github.com/ipfs/go-ipfs/pull/5216)) +* Add an internal interface for unixfs directories ([ipfs/go-ipfs#5160](https://github.com/ipfs/go-ipfs/pull/5160)) +* Refactor the CoreAPI path types and interfaces ([ipfs/go-ipfs#4672](https://github.com/ipfs/go-ipfs/pull/4672)) +* Refactor `precalcNextBuf` in the dag reader ([ipfs/go-ipfs#5237](https://github.com/ipfs/go-ipfs/pull/5237)) +* Update a bunch of dependencies that haven't been updated for a while ([ipfs/go-ipfs#5268](https://github.com/ipfs/go-ipfs/pull/5268)) + +## 0.4.16 2018-07-13 + +Ipfs 0.4.16 is a fairly small release in terms of changes to the ipfs codebase, +but it contains a huge amount of changes and improvements from the libraries we +depend on, notably libp2p. + +This release includes small a repo migration to account for some changes to the +DHT. It should only take a second to run but, depending on your configuration, +you may need to run it manually. + +You can run a migration by either: + +1. Selecting "Yes" when the daemon prompts you to migrate. +2. Running the daemon with the `--migrate=true` flag. +3. Manually [running](https://github.com/ipfs/fs-repo-migrations/blob/master/run.md#running-repo-migrations) the migration. + +### Libp2p + +This version of ipfs contains the changes made in libp2p from v5.0.14 through +v6.0.5. In that time, we have made significant changes to the codebase to allow +for easier integration of future transports and modules along with the usual +performance and reliability improvements. You can find many of these +improvements in the libp2p 6.0 [release blog +post](https://ipfs.io/blog/39-go-libp2p-6-0-0/). + +The primary motivation for this refactor was adding support for network +transports like QUIC that have built-in support for encryption, authentication, +and stream multiplexing. It will also allow us to plug-in new security +transports (like TLS) without hard-coding them. + +For example, our [QUIC +transport](https://github.com/libp2p/go-libp2p-quic-transport) currently works, +and can be plugged into libp2p manually (though note that it is still +experimental, as the upstream spec is still in flux). Further work is needed to +make enabling this inside ipfs easy and not require recompilation. + +On the user-visible side of things, we've improved our dialing logic and +timeouts. We now abort dials to local subnets after 5 seconds and abort all +dials if the TCP handshake takes longer than 5 seconds. This should +significantly improve performance in some cases as we limit the number of +concurrent dials and slow dials to non-responsive peers have been known to clog +the dialer, blocking dials to reachable peers. Importantly, this should improve +DHT performance as it tends to spend a disproportional amount of time connecting +to peers. + +We have also made a few noticeable changes to the DHT: we've significantly +improved the chances of finding a value on the DHT, tightened up some of our +validation logic, and fixed some issues that should reduce traffic to nodes +running in dhtclient mode over time. + +Of these, the first one will likely see the most impact. In the past, when +putting a value (e.g., an IPNS entry) into the DHT, we'd try to put the value to +K peers (where K for us is 20). However, we'd often fail to connect to many of +these peers so we'd end up putting the value to significantly fewer than K +peers. We now try to put the value to the K peers we can actually connect to. + +Finally, we've fixed JavaScript interoperability in go-multiplex, the one stream +muxer that both go-libp2p and js-libp2p implement. This should significantly +improve go-libp2p and js-libp2p interoperability. + +### Multiformats + +We are also changing the way that people write 'ipfs' multiaddrs. Currently, +ipfs multiaddrs look something like +`/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ`. +However, calling them 'ipfs' multiaddrs is a bit misleading, as this is actually +the multiaddr of a libp2p peer that happens to run ipfs. Other protocols built +on libp2p right now still have to use multiaddrs that say 'ipfs', even if they +have nothing to do with ipfs. Therefore, we are renaming them to 'p2p' +multiaddrs. Moving forward, these addresses will be written as: +`/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ`. + +This release adds support for *parsing* both types of addresses (`.../ipfs/...` +and `.../p2p/...`) into the same network format, and the network format is +remaining exactly the same. A future release will have the ipfs daemon switch to +*printing* out addresses this way once a large enough portion of the network +has upgraded. + +N.B., these addresses are *not* related to IPFS *file* names (`/ipfs/Qm...`). +Disambiguating the two was yet another motivation to switch the protocol name to +`/p2p/`. + +### IPFS + +On the ipfs side of things, we've started embedding public keys inside IPNS +records and have enabled the Git plugin by default. + +Embedding public keys inside IPNS records allows lookups to be faster as we only +need to fetch the record itself (and not the public key separately). It also +fixes an issue where DHT peers wouldn't store a record for a peer if they didn't +have their public key already. Combined with some of the DHT and dialing fixes, +this should improve the performance of IPNS (once a majority of the network +updates). + +Second, our public builds now include the Git plugin (in past builds, you could +add it yourself, but doing so was not easy). With this, ipfs can ingest and +operate over Git repositories and commit graphs directly. For more information +on this, see [the go-ipld-git repo](https://github.com/ipfs/go-ipld-git). + +Finally, we've included many smaller bugfixes, refactorings, improved +documentation, and a good bit more. For the full details, see the changelog +below. + +## 0.4.16-rc3 2018-07-09 +- Bugfixes + - Fix dht commands when ipns over pubsub is enabled ([ipfs/go-ipfs#5200](https://github.com/ipfs/go-ipfs/pull/5200)) + - Fix content routing when ipns over pubsub is enabled ([ipfs/go-ipfs#5200](https://github.com/ipfs/go-ipfs/pull/5200)) + - Correctly handle multi-hop dnslink resolution ([ipfs/go-ipfs#5202](https://github.com/ipfs/go-ipfs/pull/5202)) + +## 0.4.16-rc2 2018-07-05 +- Bugfixes + - Fix usage of file name vs path name in adder ([ipfs/go-ipfs#5167](https://github.com/ipfs/go-ipfs/pull/5167)) + - Fix `ipfs update` working with migrations ([ipfs/go-ipfs#5194](https://github.com/ipfs/go-ipfs/pull/5194)) +- Documentation + - Grammar fix in fuse docs ([ipfs/go-ipfs#5164](https://github.com/ipfs/go-ipfs/pull/5164)) + +## 0.4.16-rc1 2018-06-27 +- Features + - Embed public keys inside ipns records, use for validation ([ipfs/go-ipfs#5079](https://github.com/ipfs/go-ipfs/pull/5079)) + - Preload git plugin by default ([ipfs/go-ipfs#4991](https://github.com/ipfs/go-ipfs/pull/4991)) +- Improvements + - Only resolve dnslinks once in the gateway ([ipfs/go-ipfs#4977](https://github.com/ipfs/go-ipfs/pull/4977)) + - Libp2p transport refactor update ([ipfs/go-ipfs#4817](https://github.com/ipfs/go-ipfs/pull/4817)) + - Improve swarm connect/disconnect commands ([ipfs/go-ipfs#5107](https://github.com/ipfs/go-ipfs/pull/5107)) +- Documentation + - Fix typo of sudo install command ([ipfs/go-ipfs#5001](https://github.com/ipfs/go-ipfs/pull/5001)) + - Fix experimental features Table of Contents ([ipfs/go-ipfs#4976](https://github.com/ipfs/go-ipfs/pull/4976)) + - Fix link to systemd init scripts in the README ([ipfs/go-ipfs#4968](https://github.com/ipfs/go-ipfs/pull/4968)) + - Add package overview comments to coreapi ([ipfs/go-ipfs#5108](https://github.com/ipfs/go-ipfs/pull/5108)) + - Add README to docs folder ([ipfs/go-ipfs#5095](https://github.com/ipfs/go-ipfs/pull/5095)) + - Add system requirements to README ([ipfs/go-ipfs#5137](https://github.com/ipfs/go-ipfs/pull/5137)) +- Bugfixes + - Fix goroutine leak in pin verify ([ipfs/go-ipfs#5011](https://github.com/ipfs/go-ipfs/pull/5011)) + - Fix commit string in version ([ipfs/go-ipfs#4982](https://github.com/ipfs/go-ipfs/pull/4982)) + - Fix `key rename` command output error ([ipfs/go-ipfs#4962](https://github.com/ipfs/go-ipfs/pull/4962)) + - Report error source when failing to construct private network ([ipfs/go-ipfs#4952](https://github.com/ipfs/go-ipfs/pull/4952)) + - Fix build on DragonFlyBSD ([ipfs/go-ipfs#5031](https://github.com/ipfs/go-ipfs/pull/5031)) + - Fix goroutine leak in dag put ([ipfs/go-ipfs#5016](https://github.com/ipfs/go-ipfs/pull/5016)) + - Fix goroutine leaks in refs.go ([ipfs/go-ipfs#5018](https://github.com/ipfs/go-ipfs/pull/5018)) + - Fix panic, Don't handle errors with fallthrough ([ipfs/go-ipfs#5072](https://github.com/ipfs/go-ipfs/pull/5072)) + - Fix how filestore is hooked up with caching ([ipfs/go-ipfs#5122](https://github.com/ipfs/go-ipfs/pull/5122)) + - Add record validation to offline routing ([ipfs/go-ipfs#5116](https://github.com/ipfs/go-ipfs/pull/5116)) + - Fix `ipfs update` working with migrations ([ipfs/go-ipfs#5194](https://github.com/ipfs/go-ipfs/pull/5194)) +- General Changes and Refactorings + - Remove leftover bits of dead code ([ipfs/go-ipfs#5022](https://github.com/ipfs/go-ipfs/pull/5022)) + - Remove fuse platform build constraints ([ipfs/go-ipfs#5033](https://github.com/ipfs/go-ipfs/pull/5033)) + - Warning when legacy NoSync setting is set ([ipfs/go-ipfs#5036](https://github.com/ipfs/go-ipfs/pull/5036)) + - Clean up and refactor namesys module ([ipfs/go-ipfs#5007](https://github.com/ipfs/go-ipfs/pull/5007)) + - When raw-leaves are used for empty files use 'Raw' nodes ([ipfs/go-ipfs#4693](https://github.com/ipfs/go-ipfs/pull/4693)) + - Update dist_root in build scripts ([ipfs/go-ipfs#5093](https://github.com/ipfs/go-ipfs/pull/5093)) + - Integrate `pb.Data` into `FSNode` to avoid duplicating fields ([ipfs/go-ipfs#5098](https://github.com/ipfs/go-ipfs/pull/5098)) + - Reduce log level when we can't republish ([ipfs/go-ipfs#5091](https://github.com/ipfs/go-ipfs/pull/5091)) + - Extract ipns record logic to go-ipns ([ipfs/go-ipfs#5124](https://github.com/ipfs/go-ipfs/pull/5124)) +- Testing + - Collect test times for sharness ([ipfs/go-ipfs#4959](https://github.com/ipfs/go-ipfs/pull/4959)) + - Fix sharness iptb connect timeout ([ipfs/go-ipfs#4966](https://github.com/ipfs/go-ipfs/pull/4966)) + - Add more timeouts to the jenkins pipeline ([ipfs/go-ipfs#4958](https://github.com/ipfs/go-ipfs/pull/4958)) + - Use go 1.10 on jenkins ([ipfs/go-ipfs#5009](https://github.com/ipfs/go-ipfs/pull/5009)) + - Speed up multinode sharness test ([ipfs/go-ipfs#4967](https://github.com/ipfs/go-ipfs/pull/4967)) + - Print out iptb logs on iptb test failure (for debugging CI) ([ipfs/go-ipfs#5069](https://github.com/ipfs/go-ipfs/pull/5069)) + - Disable the MacOS tests in jenkins ([ipfs/go-ipfs#5119](https://github.com/ipfs/go-ipfs/pull/5119)) + - Make republisher test robust against timing issues ([ipfs/go-ipfs#5125](https://github.com/ipfs/go-ipfs/pull/5125)) + - Archive sharness trash dirs in jenkins ([ipfs/go-ipfs#5071](https://github.com/ipfs/go-ipfs/pull/5071)) + - Fixup DHT sharness tests ([ipfs/go-ipfs#5114](https://github.com/ipfs/go-ipfs/pull/5114)) +- Dependencies + - Update go-ipld-git to fix mergetag resolving ([ipfs/go-ipfs#4988](https://github.com/ipfs/go-ipfs/pull/4988)) + - Fix duplicate /x/sys imports ([ipfs/go-ipfs#5068](https://github.com/ipfs/go-ipfs/pull/5068)) + - Update stream multiplexers ([ipfs/go-ipfs#5075](https://github.com/ipfs/go-ipfs/pull/5075)) + - Update dependencies: go-log, sys, go-crypto ([ipfs/go-ipfs#5100](https://github.com/ipfs/go-ipfs/pull/5100)) + - Explicitly import go-multiaddr-dns in config/bootstrap_peers ([ipfs/go-ipfs#5144](https://github.com/ipfs/go-ipfs/pull/5144)) + - Gx update with dht and dialing improvements ([ipfs/go-ipfs#5158](https://github.com/ipfs/go-ipfs/pull/5158)) + +## 0.4.15 2018-05-09 + +This release is significantly smaller than the last as much of the work on +improving our datastores, and other libraries libp2p has yet to be merged. +However, it still includes many welcome improvements. + +As with 0.4.12 and 0.4.14 (0.4.13 was a patch), this release has a negative +diff-stat. Unfortunately, much of this code isn't actually going away but at +least it's being moved out into separate repositories. + +Much of the work that made it into this release is under the hood. We've cleaned +up some code, extracted several packages into their own repositories, and made +some long neglected optimizations (e.g., handling of sharded directories). +Additionally, this release includes a bunch of tests for our CLI commands that +should help us avoid some of the issues we've seen in the past few releases. + +More visibly, thanks to @djdv's efforts, this release includes some significant +Windows improvements (with more on the way). Specifically, this release includes +better handling of repo lockfiles (no more `ipfs repo fsck`), stdin command-line +support, and, last but not least, IPFS no longer writes random files with scary +garbage in the drive root. To read more about future windows improvements, take +a look at this [blog post](https://blog.ipfs.io/36-a-look-at-windows/). + +To better support low-power devices, we've added a low-power config profile. +This can be enabled when initializing a repo by running `ipfs init` with the +`--profile=lowpower` flag or later by running `ipfs config profile apply lowpower`. + +Finally, with this release we have begun distributing self-contained source +archives of go-ipfs and its dependencies. This should be a welcome improvement +for both packagers and those living in countries with harmonized internet +access. + +- Features + - Add options for record count and timeout for resolving DHT paths ([ipfs/go-ipfs#4733](https://github.com/ipfs/go-ipfs/pull/4733)) + - Add low power init profile ([ipfs/go-ipfs#4154](https://github.com/ipfs/go-ipfs/pull/4154)) + - Add Opentracing plugin support ([ipfs/go-ipfs#4506](https://github.com/ipfs/go-ipfs/pull/4506)) + - Add make target to build source tarballs ([ipfs/go-ipfs#4920](https://github.com/ipfs/go-ipfs/pull/4920)) + +- Improvements + - Add BlockedFetched/Added/Removed events to Blockservice ([ipfs/go-ipfs#4649](https://github.com/ipfs/go-ipfs/pull/4649)) + - Improve performance of HAMT code ([ipfs/go-ipfs#4889](https://github.com/ipfs/go-ipfs/pull/4889)) + - Avoid unnecessarily resolving child nodes when listing a sharded directory ([ipfs/go-ipfs#4884](https://github.com/ipfs/go-ipfs/pull/4884)) + - Tar writer now supports sharded ipfs directories ([ipfs/go-ipfs#4873](https://github.com/ipfs/go-ipfs/pull/4873)) + - Infer type from CID when possible in `ipfs ls` ([ipfs/go-ipfs#4890](https://github.com/ipfs/go-ipfs/pull/4890)) + - Deduplicate keys in GetMany ([ipfs/go-ipfs#4888](https://github.com/ipfs/go-ipfs/pull/4888)) + +- Documentation + - Fix spelling of retrieval ([ipfs/go-ipfs#4819](https://github.com/ipfs/go-ipfs/pull/4819)) + - Update broken links ([ipfs/go-ipfs#4798](https://github.com/ipfs/go-ipfs/pull/4798)) + - Remove roadmap.md ([ipfs/go-ipfs#4834](https://github.com/ipfs/go-ipfs/pull/4834)) + - Remove link to IPFS paper in contribute.md ([ipfs/go-ipfs#4812](https://github.com/ipfs/go-ipfs/pull/4812)) + - Fix broken todo link in readme.md ([ipfs/go-ipfs#4865](https://github.com/ipfs/go-ipfs/pull/4865)) + - Document ipns pubsub ([ipfs/go-ipfs#4903](https://github.com/ipfs/go-ipfs/pull/4903)) + - Fix missing profile docs ([ipfs/go-ipfs#4846](https://github.com/ipfs/go-ipfs/pull/4846)) + - Fix a few typos ([ipfs/go-ipfs#4835](https://github.com/ipfs/go-ipfs/pull/4835)) + - Fix typo in fsrepo error message ([ipfs/go-ipfs#4933](https://github.com/ipfs/go-ipfs/pull/4933)) + - Remove go-ipfs version from issue template ([ipfs/go-ipfs#4943](https://github.com/ipfs/go-ipfs/pull/4943)) + - Add docs for --profile=lowpower ([ipfs/go-ipfs#4970](https://github.com/ipfs/go-ipfs/pull/4970)) + - Improve Windows build documentation ([ipfs/go-ipfs#4691](https://github.com/ipfs/go-ipfs/pull/4691)) + +- Bugfixes + - Check CIDs in base case when diffing nodes ([ipfs/go-ipfs#4767](https://github.com/ipfs/go-ipfs/pull/4767)) + - Support for CIDv1 with custom mhtype in `ipfs block put` ([ipfs/go-ipfs#4563](https://github.com/ipfs/go-ipfs/pull/4563)) + - Clean path in DagArchive ([ipfs/go-ipfs#4743](https://github.com/ipfs/go-ipfs/pull/4743)) + - Set the prefix for MFS root in `ipfs add --hash-only` ([ipfs/go-ipfs#4755](https://github.com/ipfs/go-ipfs/pull/4755)) + - Fix get output path ([ipfs/go-ipfs#4809](https://github.com/ipfs/go-ipfs/pull/4809)) + - Fix incorrect Read calls ([ipfs/go-ipfs#4792](https://github.com/ipfs/go-ipfs/pull/4792)) + - Use prefix in bootstrapWritePeers ([ipfs/go-ipfs#4832](https://github.com/ipfs/go-ipfs/pull/4832)) + - Fix mfs Directory.Path not working ([ipfs/go-ipfs#4844](https://github.com/ipfs/go-ipfs/pull/4844)) + - Remove header in `ipfs stats bw` if not polling ([ipfs/go-ipfs#4856](https://github.com/ipfs/go-ipfs/pull/4856)) + - Match Go's GOPATH defaults behaviour in build scripts ([ipfs/go-ipfs#4678](https://github.com/ipfs/go-ipfs/pull/4678)) + - Fix default-net profile not reverting bootstrap config ([ipfs/go-ipfs#4845](https://github.com/ipfs/go-ipfs/pull/4845)) + - Fix excess goroutines in bitswap caused by insecure CIDs ([ipfs/go-ipfs#4946](https://github.com/ipfs/go-ipfs/pull/4946)) + +- General Changes and Refactorings + - Refactor trickle DAG builder ([ipfs/go-ipfs#4730](https://github.com/ipfs/go-ipfs/pull/4730)) + - Split the coreapi interface into multiple files ([ipfs/go-ipfs#4802](https://github.com/ipfs/go-ipfs/pull/4802)) + - Make `ipfs init` command use new cmds lib ([ipfs/go-ipfs#4732](https://github.com/ipfs/go-ipfs/pull/4732)) + - Extract thirdparty/tar package ([ipfs/go-ipfs#4857](https://github.com/ipfs/go-ipfs/pull/4857)) + - Reduce log level when for disconnected peers to info ([ipfs/go-ipfs#4811](https://github.com/ipfs/go-ipfs/pull/4811)) + - Only visit nodes in EnumerateChildrenAsync when asked ([ipfs/go-ipfs#4885](https://github.com/ipfs/go-ipfs/pull/4885)) + - Refactor coreapi options ([ipfs/go-ipfs#4807](https://github.com/ipfs/go-ipfs/pull/4807)) + - Fix error style for most errors ([ipfs/go-ipfs#4829](https://github.com/ipfs/go-ipfs/pull/4829)) + - Ensure `--help` always works, even with /dev/null stdin ([ipfs/go-ipfs#4849](https://github.com/ipfs/go-ipfs/pull/4849)) + - Deduplicate AddNodeLinkClean into AddNodeLink ([ipfs/go-ipfs#4940](https://github.com/ipfs/go-ipfs/pull/4940)) + - Remove some dead code ([ipfs/go-ipfs#4833](https://github.com/ipfs/go-ipfs/pull/4833)) + - Remove unused imports ([ipfs/go-ipfs#4955](https://github.com/ipfs/go-ipfs/pull/4955)) + - Fix go vet warnings ([ipfs/go-ipfs#4859](https://github.com/ipfs/go-ipfs/pull/4859)) + +- Testing + - Generate JUnit test reports for sharness tests ([ipfs/go-ipfs#4530](https://github.com/ipfs/go-ipfs/pull/4530)) + - Fix t0063-daemon-init.sh by adding test profile to daemon ([ipfs/go-ipfs#4816](https://github.com/ipfs/go-ipfs/pull/4816)) + - Remove circular dependencies in merkledag package tests ([ipfs/go-ipfs#4704](https://github.com/ipfs/go-ipfs/pull/4704)) + - Check that all the commands fail when passed a bad flag ([ipfs/go-ipfs#4848](https://github.com/ipfs/go-ipfs/pull/4848)) + - Allow for some small margin of code coverage dropping on commit ([ipfs/go-ipfs#4867](https://github.com/ipfs/go-ipfs/pull/4867)) + - Add confirmation to archive-branches script ([ipfs/go-ipfs#4797](https://github.com/ipfs/go-ipfs/pull/4797)) + +- Dependencies + - Update lock package ([ipfs/go-ipfs#4855](https://github.com/ipfs/go-ipfs/pull/4855)) + - Update to latest go-datastore. Remove thirdparty/datastore2 ([ipfs/go-ipfs#4742](https://github.com/ipfs/go-ipfs/pull/4742)) + - Extract fs lock into go-fs-lock ([ipfs/go-ipfs#4631](https://github.com/ipfs/go-ipfs/pull/4631)) + - Extract: exchange/interface.go, blocks/blocksutil, exchange/offline ([ipfs/go-ipfs#4912](https://github.com/ipfs/go-ipfs/pull/4912)) + - Remove unused lock dep ([ipfs/go-ipfs#4971](https://github.com/ipfs/go-ipfs/pull/4971)) + - Update iptb ([ipfs/go-ipfs#4965](https://github.com/ipfs/go-ipfs/pull/4965)) + - Update go-ipfs-cmds to fix stdin on windows ([ipfs/go-ipfs#4975](https://github.com/ipfs/go-ipfs/pull/4975)) + - Update go-ds-flatfs to fix windows corruption issue ([ipfs/go-ipfs#4872](https://github.com/ipfs/go-ipfs/pull/4872)) + +## 0.4.14 2018-03-22 + +Ipfs 0.4.14 is a big release with a large number of improvements and bugfixes. +It is also the first release of 2018, and our first release in over three +months. The release took longer than expected due to our refactoring and +extracting of our commands library. This refactor had two stages. The first +round of the refactor disentangled the commands code from core ipfs code, +allowing us to move it out into a [separate +repository](https://github.com/ipfs/go-ipfs-cmds). The code was previously +very entangled with the go-ipfs codebase and not usable for other projects. +The second round of the refactor had the goal of fixing several major issues +around streaming outputs, progress bars, and error handling. It also paved the +way for us to more easily provide an API over other transports, such as +websockets and unix domain sockets. It took a while to flush out all the kinks +on such a massive change. We're pretty sure we've got most of them, but if you +notice anything weird, please let us know. + +Beyond that, we've added a new experimental way to use IPNS. With the new +pubsub IPNS resolver and publisher, you can subscribe to updates of an IPNS +entry, and the owner can publish out changes in real time. With this, IPNS can +become nearly instantaneous. To make use of this, simply start your ipfs daemon +with the `--enable-namesys-pubsub` option, and all IPNS resolution and +publishing will use pubsub. Note that resolving an IPNS name via pubsub without +someone publishing it via pubsub will result in a fallback to using the DHT. +Please give this a try and let us know how it goes! + +Memory and CPU usage should see a noticeable improvement in this release. We +have spent considerable time fixing excess memory usage throughout the codebase +and down into libp2p. Fixes in peer tracking, bitswap allocation, pinning, and +many other places have brought down both peak and average memory usage. An +upgraded hashing library, base58 encoding library, and improved allocation +patterns all contribute to overall lower CPU usage across the board. See the +full changelist below for more memory and CPU usage improvements. + +This release also brings the beginning of the ipfs 'Core API'. Once finished, +the Core API will be the primary way to interact with go-ipfs using go. Both +embedded nodes and nodes accessed over the http API will have the same +interface. Stay tuned for future updates and documentation. + +These are only a sampling of the changes that made it into this release, the +full list (almost 100 PRs!) is below. + +Finally, I'd like to thank everyone who contributed to this release, whether +you're just contributing a typo fix or driving new features. We are really +grateful to everyone who has spent their their time pushing ipfs forward. + +SECURITY NOTE: + +This release of ipfs disallows the usage of insecure hash functions and +lengths. Ipfs does not create these insecure objects for any purpose, but it +did allow manually creating them and fetching them from other peers. If you +currently have objects using insecure hashes in your local ipfs repo, please +remove them before updating. + +#### Changes from rc2 to rc3 +- Fix bug in stdin argument parsing ([ipfs/go-ipfs#4827](https://github.com/ipfs/go-ipfs/pull/4827)) +- Revert commands back to sending a single response ([ipfs/go-ipfs#4822](https://github.com/ipfs/go-ipfs/pull/4822)) + +#### Changes from rc1 to rc2 +- Fix issue in ipfs get caused by go1.10 changes ([ipfs/go-ipfs#4790](https://github.com/ipfs/go-ipfs/pull/4790)) + +- Features + - Pubsub IPNS Publisher and Resolver (experimental) ([ipfs/go-ipfs#4047](https://github.com/ipfs/go-ipfs/pull/4047)) + - Implement coreapi Dag interface ([ipfs/go-ipfs#4471](https://github.com/ipfs/go-ipfs/pull/4471)) + - Add --offset flag to ipfs cat ([ipfs/go-ipfs#4538](https://github.com/ipfs/go-ipfs/pull/4538)) + - Command to apply config profile after init ([ipfs/go-ipfs#4195](https://github.com/ipfs/go-ipfs/pull/4195)) + - Implement coreapi Name and Key interfaces ([ipfs/go-ipfs#4477](https://github.com/ipfs/go-ipfs/pull/4477)) + - Add --length flag to ipfs cat ([ipfs/go-ipfs#4553](https://github.com/ipfs/go-ipfs/pull/4553)) + - Implement coreapi Object interface ([ipfs/go-ipfs#4492](https://github.com/ipfs/go-ipfs/pull/4492)) + - Implement coreapi Block interface ([ipfs/go-ipfs#4548](https://github.com/ipfs/go-ipfs/pull/4548)) + - Implement coreapi Pin interface ([ipfs/go-ipfs#4575](https://github.com/ipfs/go-ipfs/pull/4575)) + - Add a --with-local flag to ipfs files stat ([ipfs/go-ipfs#4638](https://github.com/ipfs/go-ipfs/pull/4638)) + - Disallow usage of blocks with insecure hashes ([ipfs/go-ipfs#4751](https://github.com/ipfs/go-ipfs/pull/4751)) +- Improvements + - Add uuid to event logs ([ipfs/go-ipfs#4392](https://github.com/ipfs/go-ipfs/pull/4392)) + - Add --quiet flag to object put ([ipfs/go-ipfs#4411](https://github.com/ipfs/go-ipfs/pull/4411)) + - Pinning memory improvements and fixes ([ipfs/go-ipfs#4451](https://github.com/ipfs/go-ipfs/pull/4451)) + - Update WebUI version ([ipfs/go-ipfs#4449](https://github.com/ipfs/go-ipfs/pull/4449)) + - Check strong and weak ETag validator ([ipfs/go-ipfs#3983](https://github.com/ipfs/go-ipfs/pull/3983)) + - Improve and refactor FD limit handling ([ipfs/go-ipfs#3801](https://github.com/ipfs/go-ipfs/pull/3801)) + - Support linking to non-dagpb objects in ipfs object patch ([ipfs/go-ipfs#4460](https://github.com/ipfs/go-ipfs/pull/4460)) + - Improve allocation patterns of slices in bitswap ([ipfs/go-ipfs#4458](https://github.com/ipfs/go-ipfs/pull/4458)) + - Secio handshake now happens synchronously ([libp2p/go-libp2p-secio#25](https://github.com/libp2p/go-libp2p-secio/pull/25)) + - Don't block closing connections on pending writes ([libp2p/go-msgio#7](https://github.com/libp2p/go-msgio/pull/7)) + - Improve memory usage of multiaddr parsing ([multiformats/go-multiaddr#56](https://github.com/multiformats/go-multiaddr/pull/56)) + - Don't lock up 256KiB buffers when adding small files ([ipfs/go-ipfs#4508](https://github.com/ipfs/go-ipfs/pull/4508)) + - Clear out memory after reads from the dagreader ([ipfs/go-ipfs#4525](https://github.com/ipfs/go-ipfs/pull/4525)) + - Improve error handling in ipfs ping ([ipfs/go-ipfs#4546](https://github.com/ipfs/go-ipfs/pull/4546)) + - Allow install.sh to be run without being the script dir ([ipfs/go-ipfs#4547](https://github.com/ipfs/go-ipfs/pull/4547)) + - Much faster base58 encoding ([libp2p/go-libp2p-peer#24](https://github.com/libp2p/go-libp2p-peer/pull/24)) + - Use faster sha256 and blake2b libs ([multiformats/go-multihash#63](https://github.com/multiformats/go-multihash/pull/63)) + - Greatly improve peerstore memory usage ([libp2p/go-libp2p-peerstore#22](https://github.com/libp2p/go-libp2p-peerstore/pull/22)) + - Improve dht memory usage and peer tracking ([libp2p/go-libp2p-kad-dht#111](https://github.com/libp2p/go-libp2p-kad-dht/pull/111)) + - New libp2p metrics lib with lower overhead ([libp2p/go-libp2p-metrics#8](https://github.com/libp2p/go-libp2p-metrics/pull/8)) + - Fix memory leak that occurred when dialing many peers ([libp2p/go-libp2p-swarm#51](https://github.com/libp2p/go-libp2p-swarm/pull/51)) + - Wire up new dag interfaces to make sessions easier ([ipfs/go-ipfs#4641](https://github.com/ipfs/go-ipfs/pull/4641)) +- Documentation + - Correct StorageMax config description ([ipfs/go-ipfs#4388](https://github.com/ipfs/go-ipfs/pull/4388)) + - Add how to download IPFS with IPFS doc ([ipfs/go-ipfs#4390](https://github.com/ipfs/go-ipfs/pull/4390)) + - Document gx release checklist item ([ipfs/go-ipfs#4480](https://github.com/ipfs/go-ipfs/pull/4480)) + - Add some documentation to CoreAPI ([ipfs/go-ipfs#4493](https://github.com/ipfs/go-ipfs/pull/4493)) + - Add interop tests to the release checklist ([ipfs/go-ipfs#4501](https://github.com/ipfs/go-ipfs/pull/4501)) + - Add badgerds to experimental-features ToC ([ipfs/go-ipfs#4537](https://github.com/ipfs/go-ipfs/pull/4537)) + - Fix typos and inconsistencies in commands documentation ([ipfs/go-ipfs#4552](https://github.com/ipfs/go-ipfs/pull/4552)) + - Add a document to help troubleshoot data transfers ([ipfs/go-ipfs#4332](https://github.com/ipfs/go-ipfs/pull/4332)) + - Add a bunch of documentation on public interfaces ([ipfs/go-ipfs#4599](https://github.com/ipfs/go-ipfs/pull/4599)) + - Expand the issue template and remove the severity field ([ipfs/go-ipfs#4624](https://github.com/ipfs/go-ipfs/pull/4624)) + - Add godocs for importers module ([ipfs/go-ipfs#4640](https://github.com/ipfs/go-ipfs/pull/4640)) + - Document make targets ([ipfs/go-ipfs#4653](https://github.com/ipfs/go-ipfs/pull/4653)) + - Add godocs for merkledag module ([ipfs/go-ipfs#4665](https://github.com/ipfs/go-ipfs/pull/4665)) + - Add godocs for unixfs module ([ipfs/go-ipfs#4664](https://github.com/ipfs/go-ipfs/pull/4664)) + - Add sharding to experimental features list ([ipfs/go-ipfs#4569](https://github.com/ipfs/go-ipfs/pull/4569)) + - Add godocs for routing module ([ipfs/go-ipfs#4676](https://github.com/ipfs/go-ipfs/pull/4676)) + - Add godocs for path module ([ipfs/go-ipfs#4689](https://github.com/ipfs/go-ipfs/pull/4689)) + - Add godocs for pin module ([ipfs/go-ipfs#4696](https://github.com/ipfs/go-ipfs/pull/4696)) + - Update link to filestore experimental status ([ipfs/go-ipfs#4557](https://github.com/ipfs/go-ipfs/pull/4557)) +- Bugfixes + - Remove trailing slash in ipfs get paths, fixes #3729 ([ipfs/go-ipfs#4365](https://github.com/ipfs/go-ipfs/pull/4365)) + - fix deadlock in bitswap sessions ([ipfs/go-ipfs#4407](https://github.com/ipfs/go-ipfs/pull/4407)) + - Fix two race conditions (and possibly go routine leaks) in commands ([ipfs/go-ipfs#4406](https://github.com/ipfs/go-ipfs/pull/4406)) + - Fix output delay in ipfs pubsub sub ([ipfs/go-ipfs#4402](https://github.com/ipfs/go-ipfs/pull/4402)) + - Use correct context in AddWithContext ([ipfs/go-ipfs#4433](https://github.com/ipfs/go-ipfs/pull/4433)) + - Fix various IPNS republisher issues ([ipfs/go-ipfs#4440](https://github.com/ipfs/go-ipfs/pull/4440)) + - Fix error handling in commands add and get ([ipfs/go-ipfs#4454](https://github.com/ipfs/go-ipfs/pull/4454)) + - Fix hamt (sharding) delete issue ([ipfs/go-ipfs#4398](https://github.com/ipfs/go-ipfs/pull/4398)) + - More correctly check for reuseport support ([libp2p/go-reuseport#40](https://github.com/libp2p/go-reuseport/pull/40)) + - Fix goroutine leak in websockets transport ([libp2p/go-ws-transport#21](https://github.com/libp2p/go-ws-transport/pull/21)) + - Update badgerds to fix i386 windows build ([ipfs/go-ipfs#4464](https://github.com/ipfs/go-ipfs/pull/4464)) + - Only construct bitswap event loggable if necessary ([ipfs/go-ipfs#4533](https://github.com/ipfs/go-ipfs/pull/4533)) + - Ensure that flush on the mfs root flushes its directory ([ipfs/go-ipfs#4509](https://github.com/ipfs/go-ipfs/pull/4509)) + - Fix deferred unlock of pin lock in AddR ([ipfs/go-ipfs#4562](https://github.com/ipfs/go-ipfs/pull/4562)) + - Fix iOS builds ([ipfs/go-ipfs#4610](https://github.com/ipfs/go-ipfs/pull/4610)) + - Calling repo gc now frees up space with badgerds ([ipfs/go-ipfs#4578](https://github.com/ipfs/go-ipfs/pull/4578)) + - Fix leak in bitswap sessions shutdown ([ipfs/go-ipfs#4658](https://github.com/ipfs/go-ipfs/pull/4658)) + - Fix make on windows ([ipfs/go-ipfs#4682](https://github.com/ipfs/go-ipfs/pull/4682)) + - Ignore invalid key files in keystore directory ([ipfs/go-ipfs#4700](https://github.com/ipfs/go-ipfs/pull/4700)) +- General Changes and Refactorings + - Extract and refactor commands library ([ipfs/go-ipfs#3856](https://github.com/ipfs/go-ipfs/pull/3856)) + - Remove all instances of `Default(false)` ([ipfs/go-ipfs#4042](https://github.com/ipfs/go-ipfs/pull/4042)) + - Build for all supported platforms when testing ([ipfs/go-ipfs#4445](https://github.com/ipfs/go-ipfs/pull/4445)) + - Refine gateway and namesys logging ([ipfs/go-ipfs#4428](https://github.com/ipfs/go-ipfs/pull/4428)) + - Demote bitswap error to an info ([ipfs/go-ipfs#4472](https://github.com/ipfs/go-ipfs/pull/4472)) + - Extract posinfo package to github.com/ipfs/go-ipfs-posinfo ([ipfs/go-ipfs#4669](https://github.com/ipfs/go-ipfs/pull/4669)) + - Move signature verification to ipns validator ([ipfs/go-ipfs#4628](https://github.com/ipfs/go-ipfs/pull/4628)) + - Extract importers/chunk module as go-ipfs-chunker ([ipfs/go-ipfs#4661](https://github.com/ipfs/go-ipfs/pull/4661)) + - Extract go-detect-race from Godeps ([ipfs/go-ipfs#4686](https://github.com/ipfs/go-ipfs/pull/4686)) + - Extract flags, delay, ds-help ([ipfs/go-ipfs#4685](https://github.com/ipfs/go-ipfs/pull/4685)) + - Extract routing package to go-ipfs-routing ([ipfs/go-ipfs#4703](https://github.com/ipfs/go-ipfs/pull/4703)) + - Extract blocks/blockstore package to go-ipfs-blockstore ([ipfs/go-ipfs#4707](https://github.com/ipfs/go-ipfs/pull/4707)) + - Add exchange.SessionExchange interface for exchanges that support sessions ([ipfs/go-ipfs#4709](https://github.com/ipfs/go-ipfs/pull/4709)) + - Extract thirdparty/pq to go-ipfs-pq ([ipfs/go-ipfs#4711](https://github.com/ipfs/go-ipfs/pull/4711)) + - Separate "path" from "path/resolver" ([ipfs/go-ipfs#4713](https://github.com/ipfs/go-ipfs/pull/4713)) +- Testing + - Increase verbosity of t0088-repo-stat-symlink.sh test ([ipfs/go-ipfs#4434](https://github.com/ipfs/go-ipfs/pull/4434)) + - Make repo size test pass deterministically ([ipfs/go-ipfs#4443](https://github.com/ipfs/go-ipfs/pull/4443)) + - Always set IPFS_PATH in test-lib.sh ([ipfs/go-ipfs#4469](https://github.com/ipfs/go-ipfs/pull/4469)) + - Fix sharness docker ([ipfs/go-ipfs#4489](https://github.com/ipfs/go-ipfs/pull/4489)) + - Fix loops in sharness tests to fail the test if the inner command fails ([ipfs/go-ipfs#4482](https://github.com/ipfs/go-ipfs/pull/4482)) + - Improve bitswap tests, fix race conditions ([ipfs/go-ipfs#4499](https://github.com/ipfs/go-ipfs/pull/4499)) + - Fix circleci cache directory list ([ipfs/go-ipfs#4564](https://github.com/ipfs/go-ipfs/pull/4564)) + - Only run the build test on test_go_expensive ([ipfs/go-ipfs#4645](https://github.com/ipfs/go-ipfs/pull/4645)) + - Fix go test on Windows ([ipfs/go-ipfs#4632](https://github.com/ipfs/go-ipfs/pull/4632)) + - Fix some tests on FreeBSD ([ipfs/go-ipfs#4662](https://github.com/ipfs/go-ipfs/pull/4662)) + +## 0.4.13 2017-11-16 + +Ipfs 0.4.13 is a patch release that fixes two high priority issues that were +discovered in the 0.4.12 release. + +Bugfixes: + - Fix periodic bitswap deadlock ([ipfs/go-ipfs#4386](https://github.com/ipfs/go-ipfs/pull/4386)) + - Fix badgerds crash on startup ([ipfs/go-ipfs#4384](https://github.com/ipfs/go-ipfs/pull/4384)) + + +## 0.4.12 2017-11-09 + +Ipfs 0.4.12 brings with it many important fixes for the huge spike in network +size we've seen this past month. These changes include the Connection Manager, +faster batching in `ipfs add`, libp2p fixes that reduce CPU usage, and a bunch +of new documentation. + +The most critical change is the 'Connection Manager': it allows an ipfs node to +maintain a limited set of connections to other peers in the network. By default +(and with no config changes required by the user), ipfs nodes will now try to +maintain between 600 and 900 open connections. These limits are still likely +higher than needed, and future releases may lower the default recommendation, +but for now we want to make changes gradually. The rationale for this selection +of numbers is as follows: + +- The DHT routing table for a large network may rise to around 400 peers +- Bitswap connections tend to be separate from the DHT +- PubSub connections also generally are another distinct set of peers + (including js-ipfs nodes) + +Because of this, we selected 600 as a 'LowWater' number, and 900 as a +'HighWater' number to avoid having to clear out connections too frequently. +You can configure different numbers as you see fit via the `Swarm.ConnMgr` +field in your ipfs config file. See +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#connmgr) for +more details. + +Disk utilization during `ipfs add` has been optimized for large files by doing +batch writes in parallel. Previously, when adding a large file, users might have +noticed that the add progressed by about 8MB at a time, with brief pauses in between. +This was caused by quickly filling up the batch, then blocking while it was +writing to disk. We now write to disk in the background while continuing to add +the remainder of the file. + +Other changes in this release have noticeably reduced memory consumption and CPU +usage. This was done by optimising some frequently called functions in libp2p +that were expensive in terms of both CPU usage and memory allocations. We also +lowered the yamux accept buffer sizes which were raised over a year ago to +combat a separate bug that has since been fixed. + +And finally, thank you to everyone who filed bugs, tested out the release candidates, +filed pull requests, and contributed in any other way to this release! + +- Features + - Implement Connection Manager ([ipfs/go-ipfs#4288](https://github.com/ipfs/go-ipfs/pull/4288)) + - Support multiple files in dag put ([ipfs/go-ipfs#4254](https://github.com/ipfs/go-ipfs/pull/4254)) + - Add 'raw' support to the dag put command ([ipfs/go-ipfs#4285](https://github.com/ipfs/go-ipfs/pull/4285)) +- Improvements + - Parallelize dag batch flushing ([ipfs/go-ipfs#4296](https://github.com/ipfs/go-ipfs/pull/4296)) + - Update go-peerstream to improve CPU usage ([ipfs/go-ipfs#4323](https://github.com/ipfs/go-ipfs/pull/4323)) + - Add full support for CidV1 in Files API and Dag Modifier ([ipfs/go-ipfs#4026](https://github.com/ipfs/go-ipfs/pull/4026)) + - Lower yamux accept buffer size ([ipfs/go-ipfs#4326](https://github.com/ipfs/go-ipfs/pull/4326)) + - Optimise `ipfs pin update` command ([ipfs/go-ipfs#4348](https://github.com/ipfs/go-ipfs/pull/4348)) +- Documentation + - Add some docs on plugins ([ipfs/go-ipfs#4255](https://github.com/ipfs/go-ipfs/pull/4255)) + - Add more info about private network bootstrap ([ipfs/go-ipfs#4270](https://github.com/ipfs/go-ipfs/pull/4270)) + - Add more info about `ipfs add` chunker option ([ipfs/go-ipfs#4306](https://github.com/ipfs/go-ipfs/pull/4306)) + - Remove cruft in readme and mention discourse forum ([ipfs/go-ipfs#4345](https://github.com/ipfs/go-ipfs/pull/4345)) + - Add note about updating before reporting issues ([ipfs/go-ipfs#4361](https://github.com/ipfs/go-ipfs/pull/4361)) +- Bugfixes + - Fix FreeBSD build issues ([ipfs/go-ipfs#4275](https://github.com/ipfs/go-ipfs/pull/4275)) + - Don't crash when Datastore.StorageMax is not defined ([ipfs/go-ipfs#4246](https://github.com/ipfs/go-ipfs/pull/4246)) + - Do not call 'Connect' on NewStream in bitswap ([ipfs/go-ipfs#4317](https://github.com/ipfs/go-ipfs/pull/4317)) + - Filter out "" from active peers in bitswap sessions ([ipfs/go-ipfs#4316](https://github.com/ipfs/go-ipfs/pull/4316)) + - Fix "seeker can't seek" on specific files ([ipfs/go-ipfs#4320](https://github.com/ipfs/go-ipfs/pull/4320)) + - Do not set "gecos" field in Dockerfile ([ipfs/go-ipfs#4331](https://github.com/ipfs/go-ipfs/pull/4331)) + - Handle sym links in when calculating repo size ([ipfs/go-ipfs#4305](https://github.com/ipfs/go-ipfs/pull/4305)) +- General Changes and Refactorings + - Fix indent in sharness tests ([ipfs/go-ipfs#4212](https://github.com/ipfs/go-ipfs/pull/4212)) + - Remove supernode routing ([ipfs/go-ipfs#4302](https://github.com/ipfs/go-ipfs/pull/4302)) + - Extract go-ipfs-addr ([ipfs/go-ipfs#4340](https://github.com/ipfs/go-ipfs/pull/4340)) + - Remove dead code and config files ([ipfs/go-ipfs#4357](https://github.com/ipfs/go-ipfs/pull/4357)) + - Update badgerds to 1.0 ([ipfs/go-ipfs#4327](https://github.com/ipfs/go-ipfs/pull/4327)) + - Wrap help descriptions under 80 chars ([ipfs/go-ipfs#4121](https://github.com/ipfs/go-ipfs/pull/4121)) +- Testing + - Make sharness t0180-p2p less racy ([ipfs/go-ipfs#4310](https://github.com/ipfs/go-ipfs/pull/4310)) + + +### 0.4.11 2017-09-14 + +Ipfs 0.4.11 is a larger release that brings many long-awaited features and +performance improvements. These include new datastore options, more efficient +bitswap transfers, greatly improved resource consumption, circuit relay +support, ipld plugins, and more! Take a look at the full changelog below for a +detailed list of every change. + +The ipfs datastore has, until now, been a combination of leveldb and a custom +git-like storage backend called 'flatfs'. This works well enough for the +average user, but different ipfs usecases demand different backend +configurations. To address this, we have changed the configuration file format +for datastores to be a modular way of specifying exactly how you want the +datastore to be structured. You will now be able to configure ipfs to use +flatfs, leveldb, badger, an in-memory datastore, and more to suit your needs. +See the new [datastore +documentation](https://github.com/ipfs/go-ipfs/blob/master/docs/datastores.md) +for more information. + +Bitswap received some much needed attention during this release cycle. The +concept of 'Bitswap Sessions' allows bitswap to associate requests for +different blocks to the same underlying session, and from that infer better +ways of requesting that data. In more concrete terms, parts of the ipfs +codebase that take advantage of sessions (currently, only `ipfs pin add`) will +cause much less extra traffic than before. This is done by making optimistic +guesses about which nodes might be providing given blocks and not sending +wantlist updates to every connected bitswap partner, as well as searching the +DHT for providers less frequently. In future releases we will migrate over more +ipfs commands to take advantage of bitswap sessions. As nodes update to this +and future versions, expect to see idle bandwidth usage on the ipfs network +go down noticeably. + +The never ending effort to reduce resource consumption had a few important +updates this release. First, the bitswap sessions changes discussed above will +help with improving bandwidth usage. Aside from that there are two important +libp2p updates that improved things significantly. The first was a fix to a bug +in the dial limiter code that was causing it to not limit outgoing dials +correctly. This resulted in ipfs running out of file descriptors very +frequently (as well as incurring a decent amount of excess outgoing bandwidth), +this has now been fixed. Users who previously received "too many open files" +errors should see this much less often in 0.4.11. The second change was a +memory leak in the DHT that was identified and fixed. Streams being tracked in +a map in the DHT weren't being cleaned up after the peer disconnected leading +to the multiplexer session not being cleaned up properly. This issue has been +resolved, and now memory usage appears to be stable over time. There is still a +lot of work to be done improving memory usage, but we feel this is a solid +victory. + +It is often said that NAT traversal is the hardest problem in peer to peer +technology, we tend to agree with this. In an effort to provide a more +ubiquitous p2p mesh, we have implemented a relay mechanism that allows willing +peers to relay traffic for other peers who might not otherwise be able to +communicate with each other. This feature is still pretty early, and currently +users have to manually connect through a relay. The next step in this endeavour +is automatic relaying, and research for this is currently in progress. We +expect that when it lands, it will improve the perceived performance of ipfs by +spending less time attempting connections to hard to reach nodes. A short guide +on using the circuit relay feature can be found +[here](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#circuit-relay). + +The last feature we want to highlight (but by no means the last feature in this +release) is our new plugin system. There are many different workflows and +usecases that ipfs should be able to support, but not everyone wants to be able +to use every feature. We could simply merge in all these features, but that +causes problems for several reasons: first off, the size of the ipfs binary +starts to get very large very quickly. Second, each of these different pieces +needs to be maintained and updated independently, which would cause significant +churn in the codebase. To address this, we have come up with a system that +allows users to install plugins to the vanilla ipfs daemon that augment its +capabilities. The first of these plugins are a [git +plugin](https://github.com/ipfs/go-ipfs/blob/master/plugin/plugins/git/git.go) +that allows ipfs to natively address git objects and an [ethereum +plugin](https://github.com/ipfs/go-ipld-eth) that lets ipfs ingest and operate +on all ethereum blockchain data. Soon to come are plugins for the bitcoin and +zcash data formats. In the future, we will be adding plugins for other things +like datastore backends and specialized libp2p network transports. +You can read more on this topic in [Plugin docs](docs/plugins.md) + +In order to simplify its integration with fs-repo-migrations, we've switched +the ipfs/go-ipfs docker image from a musl base to a glibc base. For most users +this will not be noticeable, but if you've been building your own images based +off this image, you'll have to update your dockerfile. We recommend a +multi-stage dockerfile, where the build stage is based off of a regular Debian or +other glibc-based image, and the assembly stage is based off of the ipfs/go-ipfs +image, and you copy build artifacts from the build stage to the assembly +stage. Note, if you are using the docker image and see a deprecation message, +please update your usage. We will stop supporting the old method of starting +the dockerfile in the next release. + +Finally, I would like to thank all of our contributors, users, supporters, and +friends for helping us along the way. Ipfs would not be where it is without +you. + + +- Features + - Add `--pin` option to `ipfs dag put` ([ipfs/go-ipfs#4004](https://github.com/ipfs/go-ipfs/pull/4004)) + - Add `--pin` option to `ipfs object put` ([ipfs/go-ipfs#4095](https://github.com/ipfs/go-ipfs/pull/4095)) + - Implement `--profile` option on `ipfs init` ([ipfs/go-ipfs#4001](https://github.com/ipfs/go-ipfs/pull/4001)) + - Add CID Codecs to `ipfs block put` ([ipfs/go-ipfs#4022](https://github.com/ipfs/go-ipfs/pull/4022)) + - Bitswap sessions ([ipfs/go-ipfs#3867](https://github.com/ipfs/go-ipfs/pull/3867)) + - Create plugin API and loader, add ipld-git plugin ([ipfs/go-ipfs#4033](https://github.com/ipfs/go-ipfs/pull/4033)) + - Make announced swarm addresses configurable ([ipfs/go-ipfs#3948](https://github.com/ipfs/go-ipfs/pull/3948)) + - Reprovider strategies ([ipfs/go-ipfs#4113](https://github.com/ipfs/go-ipfs/pull/4113)) + - Circuit Relay integration ([ipfs/go-ipfs#4091](https://github.com/ipfs/go-ipfs/pull/4091)) + - More configurable datastore configs ([ipfs/go-ipfs#3575](https://github.com/ipfs/go-ipfs/pull/3575)) + - Add experimental support for badger datastore ([ipfs/go-ipfs#4007](https://github.com/ipfs/go-ipfs/pull/4007)) +- Improvements + - Add better support for Raw Nodes in MFS and elsewhere ([ipfs/go-ipfs#3996](https://github.com/ipfs/go-ipfs/pull/3996)) + - Added file size to response of `ipfs add` command ([ipfs/go-ipfs#4082](https://github.com/ipfs/go-ipfs/pull/4082)) + - Add /dnsaddr bootstrap nodes ([ipfs/go-ipfs#4127](https://github.com/ipfs/go-ipfs/pull/4127)) + - Do not publish public keys extractable from ID ([ipfs/go-ipfs#4020](https://github.com/ipfs/go-ipfs/pull/4020)) +- Documentation + - Adding documentation that PubSub Sub can be encoded. ([ipfs/go-ipfs#3909](https://github.com/ipfs/go-ipfs/pull/3909)) + - Add Comms items from js-ipfs, including blog ([ipfs/go-ipfs#3936](https://github.com/ipfs/go-ipfs/pull/3936)) + - Add Developer Certificate of Origin ([ipfs/go-ipfs#4006](https://github.com/ipfs/go-ipfs/pull/4006)) + - Add `transports.md` document ([ipfs/go-ipfs#4034](https://github.com/ipfs/go-ipfs/pull/4034)) + - Add `experimental-features.md` document ([ipfs/go-ipfs#4036](https://github.com/ipfs/go-ipfs/pull/4036)) + - Update release docs ([ipfs/go-ipfs#4165](https://github.com/ipfs/go-ipfs/pull/4165)) + - Add documentation for datastore configs ([ipfs/go-ipfs#4223](https://github.com/ipfs/go-ipfs/pull/4223)) + - General update and clean-up of docs ([ipfs/go-ipfs#4222](https://github.com/ipfs/go-ipfs/pull/4222)) +- Bugfixes + - Fix shutdown check in t0023 ([ipfs/go-ipfs#3969](https://github.com/ipfs/go-ipfs/pull/3969)) + - Fix pinning of unixfs sharded directories ([ipfs/go-ipfs#3975](https://github.com/ipfs/go-ipfs/pull/3975)) + - Show escaped url in gateway 404 message ([ipfs/go-ipfs#4005](https://github.com/ipfs/go-ipfs/pull/4005)) + - Fix early opening of bitswap message sender ([ipfs/go-ipfs#4069](https://github.com/ipfs/go-ipfs/pull/4069)) + - Fix determination of 'root' node in dag put ([ipfs/go-ipfs#4072](https://github.com/ipfs/go-ipfs/pull/4072)) + - Fix bad multipart message panic in gateway ([ipfs/go-ipfs#4053](https://github.com/ipfs/go-ipfs/pull/4053)) + - Add blocks to the blockstore before returning them from blockservice sessions ([ipfs/go-ipfs#4169](https://github.com/ipfs/go-ipfs/pull/4169)) + - Various fixes for /ipfs fuse code ([ipfs/go-ipfs#4194](https://github.com/ipfs/go-ipfs/pull/4194)) + - Fix memory leak in dht stream tracking ([ipfs/go-ipfs#4251](https://github.com/ipfs/go-ipfs/pull/4251)) +- General Changes and Refactorings + - Require go 1.8 ([ipfs/go-ipfs#4044](https://github.com/ipfs/go-ipfs/pull/4044)) + - Change IPFS to use the new pluggable Block to IPLD decoding framework. ([ipfs/go-ipfs#4060](https://github.com/ipfs/go-ipfs/pull/4060)) + - Remove tour command from ipfs ([ipfs/go-ipfs#4123](https://github.com/ipfs/go-ipfs/pull/4123)) + - Add support for Go 1.9 ([ipfs/go-ipfs#4156](https://github.com/ipfs/go-ipfs/pull/4156)) + - Remove some dead code ([ipfs/go-ipfs#4204](https://github.com/ipfs/go-ipfs/pull/4204)) + - Switch docker image from musl to glibc ([ipfs/go-ipfs#4219](https://github.com/ipfs/go-ipfs/pull/4219)) + +### 0.4.10 - 2017-06-27 + +Ipfs 0.4.10 is a patch release that contains several exciting new features, +bugfixes and general improvements. Including new commands, easier corruption +recovery, and a generally cleaner codebase. + +The `ipfs pin` command has two new subcommands, `verify` and `update`. `ipfs +pin verify` is used to scan the repo for pinned object graphs and check their +integrity. Any issues are reported back with helpful error text to make error +recovery simpler. This subcommand was added to help recover from datastore +corruptions, particularly if using the experimental filestore and accidentally +deleting tracked files. +`ipfs pin update` was added to make the task of keeping a large, frequently +changing object graph pinned. Previously users had to call `ipfs pin rm` on the +old pin, and `ipfs pin add` on the new one. The 'new' `ipfs pin add` call would +be very expensive as it would need to verify the entirety of the graph again. +The `ipfs pin update` command takes shortcuts, portions of the graph that were +covered under the old pin are assumed to be fine, and the command skips +checking them. + +Next up, we have finally implemented an `ipfs shutdown` command so users can +shut down their ipfs daemons via the API. This is especially useful on +platforms that make it difficult to control processes (Android, for example), +and is also useful when needing to shut down a node remotely and you do not +have access to the machine itself. + +`ipfs add` has gained a new flag; the `--hash` flag allows you to select which +hash function to use and we have given it the ability to select `blake2b-256`. +This pushes us one step closer to shifting over to using blake2b as the +default. Blake2b is significantly faster than sha2-256, and also is conjectured +to provide superior security. + +We have also finally implemented a very early (and experimental) `ipfs p2p`. +This command and its subcommands will allow you to open up arbitrary streams to +other ipfs peers through libp2p. The interfaces are a little bit clunky right +now, but shouldn't get in the way of anyone wanting to try building a fully +peer to peer application on top of ipfs and libp2p. For more info on this +command, to ask questions, or to provide feedback, head over to the [feedback +issue](https://github.com/ipfs/go-ipfs/issues/3994) for the command. + +A few other subcommands and flags were added around the API, as well as many +other requested improvements. See below for the full list of changes. + + +- Features + - Add support for specifying the hash function in `ipfs add` ([ipfs/go-ipfs#3919](https://github.com/ipfs/go-ipfs/pull/3919)) + - Implement `ipfs key {rm, rename}` ([ipfs/go-ipfs#3892](https://github.com/ipfs/go-ipfs/pull/3892)) + - Implement `ipfs shutdown` command ([ipfs/go-ipfs#3884](https://github.com/ipfs/go-ipfs/pull/3884)) + - Implement `ipfs pin update` ([ipfs/go-ipfs#3846](https://github.com/ipfs/go-ipfs/pull/3846)) + - Implement `ipfs pin verify` ([ipfs/go-ipfs#3843](https://github.com/ipfs/go-ipfs/pull/3843)) + - Implemented experimental p2p commands ([ipfs/go-ipfs#3943](https://github.com/ipfs/go-ipfs/pull/3943)) +- Improvements + - Add MaxStorage field to output of "repo stat" ([ipfs/go-ipfs#3915](https://github.com/ipfs/go-ipfs/pull/3915)) + - Add Suborigin header to gateway responses ([ipfs/go-ipfs#3914](https://github.com/ipfs/go-ipfs/pull/3914)) + - Add "--file-order" option to "filestore ls" and "verify" ([ipfs/go-ipfs#3938](https://github.com/ipfs/go-ipfs/pull/3938)) + - Allow selecting ipns keys by Peer ID ([ipfs/go-ipfs#3882](https://github.com/ipfs/go-ipfs/pull/3882)) + - Don't redirect to trailing slash in gateway for `go get` ([ipfs/go-ipfs#3963](https://github.com/ipfs/go-ipfs/pull/3963)) + - Add 'ipfs dht findprovs --num-providers' to allow choosing number of providers to find ([ipfs/go-ipfs#3966](https://github.com/ipfs/go-ipfs/pull/3966)) + - Make sure all keystore keys get republished ([ipfs/go-ipfs#3951](https://github.com/ipfs/go-ipfs/pull/3951)) +- Documentation + - Adding documentation on PubSub encodings ([ipfs/go-ipfs#3909](https://github.com/ipfs/go-ipfs/pull/3909)) + - Change 'neccessary' to 'necessary' ([ipfs/go-ipfs#3941](https://github.com/ipfs/go-ipfs/pull/3941)) + - README.md: add Nix to the linux package managers ([ipfs/go-ipfs#3939](https://github.com/ipfs/go-ipfs/pull/3939)) + - More verbose errors in filestore ([ipfs/go-ipfs#3964](https://github.com/ipfs/go-ipfs/pull/3964)) +- Bugfixes + - Fix typo in message when file size check fails ([ipfs/go-ipfs#3895](https://github.com/ipfs/go-ipfs/pull/3895)) + - Clean up bitswap ledgers when disconnecting ([ipfs/go-ipfs#3437](https://github.com/ipfs/go-ipfs/pull/3437)) + - Make odds of 'process added after close' panic less likely ([ipfs/go-ipfs#3940](https://github.com/ipfs/go-ipfs/pull/3940)) +- General Changes and Refactorings + - Remove 'ipfs diag net' from codebase ([ipfs/go-ipfs#3916](https://github.com/ipfs/go-ipfs/pull/3916)) + - Update to dht code with provide announce option ([ipfs/go-ipfs#3928](https://github.com/ipfs/go-ipfs/pull/3928)) + - Apply the megacheck code vetting tool ([ipfs/go-ipfs#3949](https://github.com/ipfs/go-ipfs/pull/3949)) + - Expose port 8081 in docker container for /ws listener ([ipfs/go-ipfs#3954](https://github.com/ipfs/go-ipfs/pull/3954)) + +### 0.4.9 - 2017-04-30 + +Ipfs 0.4.9 is a maintenance release that contains several useful bugfixes and +improvements. Notably, `ipfs add` has gained the ability to select which CID +version will be output. The common ipfs hash that looks like this: +`QmRjNgF2mRLDT8AzCPsQbw1EYF2hDTFgfUmJokJPhCApYP` is a multihash. Multihashes +allow us to specify the hashing algorithm that was used to verify the data, but +it doesn't give us any indication of what format that data might be. To address +that issue, we are adding another couple of bytes to the prefix that will allow us +to indicate the format of the data referenced by the hash. This new format is +called a Content ID, or CID for short. The previous bare multihashes will still +be fully supported throughout the entire application as CID version 0. The new +format with the type information will be CID version 1. To give an example, +the content referenced by the hash above is "Hello Ipfs!". That same content, +in the same format (dag-protobuf) using CIDv1 is +`zb2rhkgXZVkT2xvDiuUsJENPSbWJy7fdYnsboLBzzEjjZMRoG`. + +CIDv1 hashes are supported in ipfs versions back to 0.4.5. Nodes running 0.4.4 +and older will not be able to load content via CIDv1 and we recommend that they +update to a newer version. + +There are many other use cases for CIDs. Plugins can be written to +allow ipfs to natively address content from any other merkletree based system, +such as git, bitcoin, zcash and ethereum -- a few systems we've already started work on. + +Aside from the CID flag, there were many other changes as noted below: + +- Features + - Add support for using CidV1 in 'ipfs add' ([ipfs/go-ipfs#3743](https://github.com/ipfs/go-ipfs/pull/3743)) +- Improvements + - Use CID as an ETag strong validator ([ipfs/go-ipfs#3869](https://github.com/ipfs/go-ipfs/pull/3869)) + - Update go-multihash with keccak and bitcoin hashes ([ipfs/go-ipfs#3833](https://github.com/ipfs/go-ipfs/pull/3833)) + - Update go-is-domain to contain new gTLD ([ipfs/go-ipfs#3873](https://github.com/ipfs/go-ipfs/pull/3873)) + - Periodically flush cached directories during ipfs add ([ipfs/go-ipfs#3888](https://github.com/ipfs/go-ipfs/pull/3888)) + - improved gateway directory listing for sharded nodes ([ipfs/go-ipfs#3897](https://github.com/ipfs/go-ipfs/pull/3897)) +- Documentation + - Change issue template to use Severity instead of Priority ([ipfs/go-ipfs#3834](https://github.com/ipfs/go-ipfs/pull/3834)) + - Fix link to commit hook script in contribute.md ([ipfs/go-ipfs#3863](https://github.com/ipfs/go-ipfs/pull/3863)) + - Fix install_unsupported for openbsd, add docs ([ipfs/go-ipfs#3880](https://github.com/ipfs/go-ipfs/pull/3880)) +- Bugfixes + - Fix wanlist typo in prometheus metric name ([ipfs/go-ipfs#3841](https://github.com/ipfs/go-ipfs/pull/3841)) + - Fix `make install` not using ldflags for git hash ([ipfs/go-ipfs#3838](https://github.com/ipfs/go-ipfs/pull/3838)) + - Fix `make install` not installing dependencies ([ipfs/go-ipfs#3848](https://github.com/ipfs/go-ipfs/pull/3848)) + - Fix erroneous Cache-Control: immutable on dir listings ([ipfs/go-ipfs#3870](https://github.com/ipfs/go-ipfs/pull/3870)) + - Fix bitswap accounting of 'BytesSent' in ledger ([ipfs/go-ipfs#3876](https://github.com/ipfs/go-ipfs/pull/3876)) + - Fix gateway handling of sharded directories ([ipfs/go-ipfs#3889](https://github.com/ipfs/go-ipfs/pull/3889)) + - Fix sharding memory growth, and fix resolver for unixfs paths ([ipfs/go-ipfs#3890](https://github.com/ipfs/go-ipfs/pull/3890)) +- General Changes and Refactorings + - Use ctx var consistently in daemon.go ([ipfs/go-ipfs#3864](https://github.com/ipfs/go-ipfs/pull/3864)) + - Handle 404 correctly in dist_get tool ([ipfs/go-ipfs#3879](https://github.com/ipfs/go-ipfs/pull/3879)) +- Testing + - Fix go fuse tests ([ipfs/go-ipfs#3840](https://github.com/ipfs/go-ipfs/pull/3840)) + +### 0.4.8 - 2017-03-29 + +Ipfs 0.4.8 brings with it several improvements, bugfixes, documentation +improvements, and the long awaited directory sharding code. + +Currently, when too many items are added into a unixfs directory, the object +gets too large and you may experience issues. To pervent this problem, and +generally make working really large directories more efficient, we have +implemented a HAMT structure for unixfs. To enable this feature, run: +``` +ipfs config --json Experimental.ShardingEnabled true +``` + +And restart your daemon if it was running. + +Note: With this setting enabled, the hashes of any newly added directories will +be different than they previously were, as the new code will use the sharded +HAMT structure for all directories. Also, nodes running ipfs 0.4.7 and earlier +will not be able to access directories created with this option. + +That said, please do give it a try, let us know how it goes, and then take a +look at all the other cool things added in 0.4.8 below. + +- Features + - Implement unixfs directory sharding ([ipfs/go-ipfs#3042](https://github.com/ipfs/go-ipfs/pull/3042)) + - Add DisableNatPortMap option ([ipfs/go-ipfs#3798](https://github.com/ipfs/go-ipfs/pull/3798)) + - Basic Filestore utilty commands ([ipfs/go-ipfs#3653](https://github.com/ipfs/go-ipfs/pull/3653)) +- Improvements + - More Robust GC ([ipfs/go-ipfs#3712](https://github.com/ipfs/go-ipfs/pull/3712)) + - Automatically fix permissions for docker volumes ([ipfs/go-ipfs#3744](https://github.com/ipfs/go-ipfs/pull/3744)) + - Core API refinements and efficiency improvements ([ipfs/go-ipfs#3493](https://github.com/ipfs/go-ipfs/pull/3493)) + - Improve IsPinned() lookups for indirect pins ([ipfs/go-ipfs#3809](https://github.com/ipfs/go-ipfs/pull/3809)) +- Documentation + - Improve 'name' and 'key' helptexts ([ipfs/go-ipfs#3806](https://github.com/ipfs/go-ipfs/pull/3806)) + - Update link to paper in dev.md ([ipfs/go-ipfs#3812](https://github.com/ipfs/go-ipfs/pull/3812)) + - Add test to enforce helptext on commands ([ipfs/go-ipfs#2648](https://github.com/ipfs/go-ipfs/pull/2648)) +- Bugfixes + - Remove bloom filter check on Put call in blockstore ([ipfs/go-ipfs#3782](https://github.com/ipfs/go-ipfs/pull/3782)) + - Re-add the GOPATH checking functionality ([ipfs/go-ipfs#3787](https://github.com/ipfs/go-ipfs/pull/3787)) + - Use fsrepo.IsInitialized to test for initialization ([ipfs/go-ipfs#3805](https://github.com/ipfs/go-ipfs/pull/3805)) + - Return 404 Not Found for failed path resolutions ([ipfs/go-ipfs#3777](https://github.com/ipfs/go-ipfs/pull/3777)) + - Fix 'dist\_get' failing without failing ([ipfs/go-ipfs#3818](https://github.com/ipfs/go-ipfs/pull/3818)) + - Update iptb with fix for t0130 hanging issue ([ipfs/go-ipfs#3823](https://github.com/ipfs/go-ipfs/pull/3823)) + - fix hidden file detection on windows ([ipfs/go-ipfs#3829](https://github.com/ipfs/go-ipfs/pull/3829)) +- General Changes and Refactorings + - Fix multiple govet warnings ([ipfs/go-ipfs#3824](https://github.com/ipfs/go-ipfs/pull/3824)) + - Make Golint happy in the blocks submodule ([ipfs/go-ipfs#3827](https://github.com/ipfs/go-ipfs/pull/3827)) +- Testing + - Enable codeclimate for automated linting and vetting ([ipfs/go-ipfs#3821](https://github.com/ipfs/go-ipfs/pull/3821)) + - Fix EOF test failure with Multipart.Read ([ipfs/go-ipfs#3804](https://github.com/ipfs/go-ipfs/pull/3804)) + +### 0.4.7 - 2017-03-15 + +Ipfs 0.4.7 contains several exciting new features! +First off, The long awaited filestore feature has been merged, allowing users +the option to not have ipfs store chunked copies of added files in the +blockstore, pushing to burden of ensuring those files are not changed to the +user. The filestore feature is currently still experimental, and must be +enabled in your config with: +``` +ipfs config --json Experimental.FilestoreEnabled true +``` +before it can be used. Please see [this issue](https://github.com/ipfs/go-ipfs/issues/3397#issuecomment-284337564) for more details. + +Next up, We have merged initial support for ipfs 'Private Networks'. This +feature allows users to run ipfs in a mode that will only connect to other +peers in the private network. This feature, like the filestore is being +released experimentally, but if you're interested please try it out. +Instructions for setting it up can be found +[here](https://github.com/ipfs/go-ipfs/issues/3397#issuecomment-284341649). + +This release also enables support for the 'mplex' stream muxer by default. This +stream multiplexing protocol was available previously via the +`--enable-mplex-experiment` daemon flag, but has now graduated to being 'less +experimental' and no longer requires the flag to use it. + +Aside from those, we have a good number of bugfixes, perf improvements and new +tests. Heres a list of highlights: + +- Features + - Implement basic filestore 'no-copy' functionality ([ipfs/go-ipfs#3629](https://github.com/ipfs/go-ipfs/pull/3629)) + - Add support for private ipfs networks ([ipfs/go-ipfs#3697](https://github.com/ipfs/go-ipfs/pull/3697)) + - Enable 'mplex' stream muxer by default ([ipfs/go-ipfs#3725](https://github.com/ipfs/go-ipfs/pull/3725)) + - Add `--quieter` option to `ipfs add` ([ipfs/go-ipfs#3770](https://github.com/ipfs/go-ipfs/pull/3770)) + - Report progress during `pin add` via `--progress` ([ipfs/go-ipfs#3671](https://github.com/ipfs/go-ipfs/pull/3671)) +- Improvements + - Allow `ipfs get` to handle content added with raw leaves option ([ipfs/go-ipfs#3757](https://github.com/ipfs/go-ipfs/pull/3757)) + - Fix accuracy of progress bar on `ipfs get` ([ipfs/go-ipfs#3758](https://github.com/ipfs/go-ipfs/pull/3758)) + - Limit number of objects in batches to prevent too many fds issue ([ipfs/go-ipfs#3756](https://github.com/ipfs/go-ipfs/pull/3756)) + - Add more info to bitswap stat ([ipfs/go-ipfs#3635](https://github.com/ipfs/go-ipfs/pull/3635)) + - Add multiple performance metrics ([ipfs/go-ipfs#3615](https://github.com/ipfs/go-ipfs/pull/3615)) + - Make `dist_get` fall back to other downloaders if one fails ([ipfs/go-ipfs#3692](https://github.com/ipfs/go-ipfs/pull/3692)) +- Documentation + - Add Arch Linux install instructions to readme ([ipfs/go-ipfs#3742](https://github.com/ipfs/go-ipfs/pull/3742)) + - Improve release checklist document ([ipfs/go-ipfs#3717](https://github.com/ipfs/go-ipfs/pull/3717)) +- Bugfixes + - Fix drive root parsing on windows ([ipfs/go-ipfs#3328](https://github.com/ipfs/go-ipfs/pull/3328)) + - Fix panic in ipfs get when passing no parameters to API ([ipfs/go-ipfs#3768](https://github.com/ipfs/go-ipfs/pull/3768)) + - Fix breakage of `ipfs pin add` api output ([ipfs/go-ipfs#3760](https://github.com/ipfs/go-ipfs/pull/3760)) + - Fix issue in DHT queries that was causing poor record replication ([ipfs/go-ipfs#3748](https://github.com/ipfs/go-ipfs/pull/3748)) + - Fix `ipfs mount` crashing if no name was published before ([ipfs/go-ipfs#3728](https://github.com/ipfs/go-ipfs/pull/3728)) + - Add `self` key to the `ipfs key list` listing ([ipfs/go-ipfs#3734](https://github.com/ipfs/go-ipfs/pull/3734)) + - Fix panic when shutting down `ipfs daemon` pre gateway setup ([ipfs/go-ipfs#3723](https://github.com/ipfs/go-ipfs/pull/3723)) +- General Changes and Refactorings + - Refactor `EnumerateChildren` to avoid need for bestEffort parameter ([ipfs/go-ipfs#3700](https://github.com/ipfs/go-ipfs/pull/3700)) + - Update fuse dependency, fixing several issues ([ipfs/go-ipfs#3727](https://github.com/ipfs/go-ipfs/pull/3727)) + - Add `install_unsupported` makefile target for 'exotic' systems ([ipfs/go-ipfs#3719](https://github.com/ipfs/go-ipfs/pull/3719)) + - Deprecate implicit daemon argument in Dockerfile ([ipfs/go-ipfs#3685](https://github.com/ipfs/go-ipfs/pull/3685)) +- Testing + - Add test to ensure helptext is under 80 columns wide ([ipfs/go-ipfs#3774](https://github.com/ipfs/go-ipfs/pull/3774)) + - Add unit tests for auto migration code ([ipfs/go-ipfs#3618](https://github.com/ipfs/go-ipfs/pull/3618)) + - Fix iptb stop issue in sharness tests ([ipfs/go-ipfs#3714](https://github.com/ipfs/go-ipfs/pull/3714)) + + +### 0.4.6 - 2017-02-21 + +Ipfs 0.4.6 contains several bugfixes related to migrations and also contains a +few other improvements to other parts of the codebase. Notably: + +- The default config will now contain some ipv6 addresses for bootstrap nodes. +- `ipfs pin add` should be faster and consume less memory. +- Pinning thousands of files no longer causes superlinear usage of storage space. + +- Improvements + - Make pinset sharding deterministic ([ipfs/go-ipfs#3640](https://github.com/ipfs/go-ipfs/pull/3640)) + - Update to go-multihash with blake2 ([ipfs/go-ipfs#3649](https://github.com/ipfs/go-ipfs/pull/3649)) + - Pass cids instead of nodes around in EnumerateChildrenAsync ([ipfs/go-ipfs#3598](https://github.com/ipfs/go-ipfs/pull/3598)) + - Add /ip6 bootstrap nodes ([ipfs/go-ipfs#3523](https://github.com/ipfs/go-ipfs/pull/3523)) + - Add sub-object support to `dag get` command ([ipfs/go-ipfs#3687](https://github.com/ipfs/go-ipfs/pull/3687)) + - Add half-closed streams support to multiplex experiment ([ipfs/go-ipfs#3695](https://github.com/ipfs/go-ipfs/pull/3695)) +- Documentation + - Add the snap installation instructions ([ipfs/go-ipfs#3663](https://github.com/ipfs/go-ipfs/pull/3663)) + - Add closed PRs, Issues throughput ([ipfs/go-ipfs#3602](https://github.com/ipfs/go-ipfs/pull/3602)) +- Bugfixes + - Fix auto-migration on docker nodes ([ipfs/go-ipfs#3698](https://github.com/ipfs/go-ipfs/pull/3698)) + - Update flatfs to v1.1.2, fixing directory fd issue ([ipfs/go-ipfs#3711](https://github.com/ipfs/go-ipfs/pull/3711)) +- General Changes and Refactorings + - Remove `FindProviders` from routing mocks ([ipfs/go-ipfs#3617](https://github.com/ipfs/go-ipfs/pull/3617)) + - Use Marshalers instead of PostRun to process `block rm` output ([ipfs/go-ipfs#3708](https://github.com/ipfs/go-ipfs/pull/3708)) +- Testing + - Makefile rework and sharness test coverage ([ipfs/go-ipfs#3504](https://github.com/ipfs/go-ipfs/pull/3504)) + - Print out all daemon stderr files when iptb stop fails ([ipfs/go-ipfs#3701](https://github.com/ipfs/go-ipfs/pull/3701)) + - Add tests for recursively pinning a dag ([ipfs/go-ipfs#3691](https://github.com/ipfs/go-ipfs/pull/3691)) + - Fix lack of commit hash during build ([ipfs/go-ipfs#3705](https://github.com/ipfs/go-ipfs/pull/3705)) + +### 0.4.5 - 2017-02-11 + +#### Changes from rc3 to rc4 +- Update to fixed webui. ([ipfs/go-ipfs#3669](https://github.com/ipfs/go-ipfs/pull/3669)) + +#### Changes from rc2 to rc3 +- Fix handling of null arrays in cbor ipld objects. ([ipfs/go-ipfs#3666](https://github.com/ipfs/go-ipfs/pull/3666)) +- Add env var to enable yamux debug logging. ([ipfs/go-ipfs#3668](https://github.com/ipfs/go-ipfs/pull/3668)) +- Fix libc check during auto-migrations. ([ipfs/go-ipfs#3665](https://github.com/ipfs/go-ipfs/pull/3665)) + +#### Changes from rc1 to rc2 +- Fixed json output of ipld objects in `ipfs dag get` ([ipfs/go-ipfs#3655](https://github.com/ipfs/go-ipfs/pull/3655)) + +#### Changes since 0.4.4 + +- Notable changes + - IPLD and CIDs + - Rework go-ipfs to use Content IDs ([ipfs/go-ipfs#3187](https://github.com/ipfs/go-ipfs/pull/3187)) ([ipfs/go-ipfs#3290](https://github.com/ipfs/go-ipfs/pull/3290)) + - Turn merkledag.Node into an interface ([ipfs/go-ipfs#3301](https://github.com/ipfs/go-ipfs/pull/3301)) + - Implement cbor ipld nodes ([ipfs/go-ipfs#3325](https://github.com/ipfs/go-ipfs/pull/3325)) + - Allow cid format selection in block put command ([ipfs/go-ipfs#3324](https://github.com/ipfs/go-ipfs/pull/3324)) ([ipfs/go-ipfs#3483](https://github.com/ipfs/go-ipfs/pull/3483)) + - Bitswap protocol extension to handle cids ([ipfs/go-ipfs#3297](https://github.com/ipfs/go-ipfs/pull/3297)) + - Add dag get to read-only api ([ipfs/go-ipfs#3499](https://github.com/ipfs/go-ipfs/pull/3499)) + - Raw Nodes + - Implement 'Raw Node' node type for addressing raw data ([ipfs/go-ipfs#3307](https://github.com/ipfs/go-ipfs/pull/3307)) + - Optimize DagService GetLinks for Raw Nodes. ([ipfs/go-ipfs#3351](https://github.com/ipfs/go-ipfs/pull/3351)) + - Experimental PubSub + - Added a very basic pubsub implementation ([ipfs/go-ipfs#3202](https://github.com/ipfs/go-ipfs/pull/3202)) + - Core API + - gateway: use core api for serving GET/HEAD/POST ([ipfs/go-ipfs#3244](https://github.com/ipfs/go-ipfs/pull/3244)) + +- Improvements + - Disable auto-gc check in 'ipfs cat' ([ipfs/go-ipfs#3100](https://github.com/ipfs/go-ipfs/pull/3100)) + - Add `bitswap ledger` command ([ipfs/go-ipfs#2852](https://github.com/ipfs/go-ipfs/pull/2852)) + - Add `ipfs block rm` command. ([ipfs/go-ipfs#2962](https://github.com/ipfs/go-ipfs/pull/2962)) + - Add config option to disable bandwidth metrics ([ipfs/go-ipfs#3381](https://github.com/ipfs/go-ipfs/pull/3381)) + - Add experimental dht 'client mode' flag ([ipfs/go-ipfs#3269](https://github.com/ipfs/go-ipfs/pull/3269)) + - Add config option to set reprovider interval ([ipfs/go-ipfs#3101](https://github.com/ipfs/go-ipfs/pull/3101)) + - Add `ipfs dht provide` command ([ipfs/go-ipfs#3106](https://github.com/ipfs/go-ipfs/pull/3106)) + - Add stream info to `ipfs swarm peers -v` ([ipfs/go-ipfs#3352](https://github.com/ipfs/go-ipfs/pull/3352)) + - Add option to enable go-multiplex experiment ([ipfs/go-ipfs#3447](https://github.com/ipfs/go-ipfs/pull/3447)) + - Basic Keystore implementation ([ipfs/go-ipfs#3472](https://github.com/ipfs/go-ipfs/pull/3472)) + - Make `ipfs add --local` not send providers messages ([ipfs/go-ipfs#3102](https://github.com/ipfs/go-ipfs/pull/3102)) + - Fix bug in `ipfs tar add` that buffered input in memory ([ipfs/go-ipfs#3334](https://github.com/ipfs/go-ipfs/pull/3334)) + - Make blockstore retry operations on temporary errors ([ipfs/go-ipfs#3091](https://github.com/ipfs/go-ipfs/pull/3091)) + - Don't hold the PinLock in adder when not pinning. ([ipfs/go-ipfs#3222](https://github.com/ipfs/go-ipfs/pull/3222)) + - Validate repo/api file and improve error message ([ipfs/go-ipfs#3219](https://github.com/ipfs/go-ipfs/pull/3219)) + - no longer hard code gomaxprocs ([ipfs/go-ipfs#3357](https://github.com/ipfs/go-ipfs/pull/3357)) + - Updated Bash complete script ([ipfs/go-ipfs#3377](https://github.com/ipfs/go-ipfs/pull/3377)) + - Remove expensive debug statement in blockstore AllKeysChan ([ipfs/go-ipfs#3384](https://github.com/ipfs/go-ipfs/pull/3384)) + - Remove GC timeout, fix GC tests ([ipfs/go-ipfs#3494](https://github.com/ipfs/go-ipfs/pull/3494)) + - Fix `ipfs pin add` resource consumption ([ipfs/go-ipfs#3495](https://github.com/ipfs/go-ipfs/pull/3495)) ([ipfs/go-ipfs#3571](https://github.com/ipfs/go-ipfs/pull/3571)) + - Add IPNS entry to DHT cache after publish ([ipfs/go-ipfs#3501](https://github.com/ipfs/go-ipfs/pull/3501)) + - Add in `--routing=none` daemon option ([ipfs/go-ipfs#3605](https://github.com/ipfs/go-ipfs/pull/3605)) + +- Bitswap + - Don't re-provide blocks we've provided very recently ([ipfs/go-ipfs#3105](https://github.com/ipfs/go-ipfs/pull/3105)) + - Add a deadline to sendmsg calls ([ipfs/go-ipfs#3445](https://github.com/ipfs/go-ipfs/pull/3445)) + - cleanup bitswap and handle message send failure slightly better ([ipfs/go-ipfs#3408](https://github.com/ipfs/go-ipfs/pull/3408)) + - Increase wantlist resend delay to one minute ([ipfs/go-ipfs#3448](https://github.com/ipfs/go-ipfs/pull/3448)) + - Fix issue where wantlist fullness wasn't included in messages ([ipfs/go-ipfs#3461](https://github.com/ipfs/go-ipfs/pull/3461)) + - Only pass keys down newBlocks chan in bitswap ([ipfs/go-ipfs#3271](https://github.com/ipfs/go-ipfs/pull/3271)) + +- Bugfixes + - gateway: fix --writable flag ([ipfs/go-ipfs#3206](https://github.com/ipfs/go-ipfs/pull/3206)) + - Fix relative seek in unixfs not expanding file properly ([ipfs/go-ipfs#3095](https://github.com/ipfs/go-ipfs/pull/3095)) + - Update multicodec service names for ipfs services ([ipfs/go-ipfs#3132](https://github.com/ipfs/go-ipfs/pull/3132)) + - dht: add missing protocol ID to newStream call ([ipfs/go-ipfs#3203](https://github.com/ipfs/go-ipfs/pull/3203)) + - Return immediately on namesys error ([ipfs/go-ipfs#3345](https://github.com/ipfs/go-ipfs/pull/3345)) + - Improve osxfuse handling ([ipfs/go-ipfs#3098](https://github.com/ipfs/go-ipfs/pull/3098)) ([ipfs/go-ipfs#3413](https://github.com/ipfs/go-ipfs/pull/3413)) + - commands: fix opt.Description panic when desc was empty ([ipfs/go-ipfs#3521](https://github.com/ipfs/go-ipfs/pull/3521)) + - Fixes #3133: Properly handle release candidates in version comparison ([ipfs/go-ipfs#3136](https://github.com/ipfs/go-ipfs/pull/3136)) + - Don't drop error in readStreamedJson. ([ipfs/go-ipfs#3276](https://github.com/ipfs/go-ipfs/pull/3276)) + - Error out on invalid `--routing` option ([ipfs/go-ipfs#3482](https://github.com/ipfs/go-ipfs/pull/3482)) + - Respect contexts when returning diagnostics responses ([ipfs/go-ipfs#3353](https://github.com/ipfs/go-ipfs/pull/3353)) + - Fix json marshalling of pbnode ([ipfs/go-ipfs#3507](https://github.com/ipfs/go-ipfs/pull/3507)) + +- General changes and refactorings + - Disable Suborigins the spec changed and our impl conflicts ([ipfs/go-ipfs#3519](https://github.com/ipfs/go-ipfs/pull/3519)) + - Avoid sending provide messages for pinsets ([ipfs/go-ipfs#3103](https://github.com/ipfs/go-ipfs/pull/3103)) + - Refactor cli handling to expose argument parsing functionality ([ipfs/go-ipfs#3308](https://github.com/ipfs/go-ipfs/pull/3308)) + - Create a FilestoreNode object to carry PosInfo ([ipfs/go-ipfs#3314](https://github.com/ipfs/go-ipfs/pull/3314)) + - Print 'n/a' instead of zero latency in `ipfs swarm peers` ([ipfs/go-ipfs#3491](https://github.com/ipfs/go-ipfs/pull/3491)) + - Add DAGService.GetLinks() method to optimize traversals. ([ipfs/go-ipfs#3255](https://github.com/ipfs/go-ipfs/pull/3255)) + - Make path resolver no longer require whole IpfsNode for construction ([ipfs/go-ipfs#3321](https://github.com/ipfs/go-ipfs/pull/3321)) + - Distinguish between Offline and Local Modes of daemon operation. ([ipfs/go-ipfs#3259](https://github.com/ipfs/go-ipfs/pull/3259)) + - Separate out the GC Locking from the Blockstore interface. ([ipfs/go-ipfs#3348](https://github.com/ipfs/go-ipfs/pull/3348)) + - Avoid unnecessary allocs in datastore key handling ([ipfs/go-ipfs#3407](https://github.com/ipfs/go-ipfs/pull/3407)) + - Use NextSync method for datastore queries ([ipfs/go-ipfs#3386](https://github.com/ipfs/go-ipfs/pull/3386)) + - Switch unixfs.Metadata.MimeType to optional ([ipfs/go-ipfs#3458](https://github.com/ipfs/go-ipfs/pull/3458)) + - Fix path parsing in `ipfs name publish` ([ipfs/go-ipfs#3592](https://github.com/ipfs/go-ipfs/pull/3592)) + - Fix inconsistent `ipfs stats bw` formatting ([ipfs/go-ipfs#3554](https://github.com/ipfs/go-ipfs/pull/3554)) + - Set the libp2p agent version based on version string ([ipfs/go-ipfs#3569](https://github.com/ipfs/go-ipfs/pull/3569)) + +- Cross Platform Changes + - Fix 'dist_get' script on BSDs. ([ipfs/go-ipfs#3264](https://github.com/ipfs/go-ipfs/pull/3264)) + - ulimit: Tune resource limits on BSDs ([ipfs/go-ipfs#3374](https://github.com/ipfs/go-ipfs/pull/3374)) + +- Metrics + - Introduce go-metrics-interface ([ipfs/go-ipfs#3189](https://github.com/ipfs/go-ipfs/pull/3189)) + - Fix metrics injection ([ipfs/go-ipfs#3315](https://github.com/ipfs/go-ipfs/pull/3315)) + +- Misc + - Bump Go requirement to 1.7 ([ipfs/go-ipfs#3111](https://github.com/ipfs/go-ipfs/pull/3111)) + - Merge 0.4.3 release candidate changes back into master ([ipfs/go-ipfs#3248](https://github.com/ipfs/go-ipfs/pull/3248)) + - Add security@ipfs.io GPG key to assets ([ipfs/go-ipfs#2997](https://github.com/ipfs/go-ipfs/pull/2997)) + - Improve makefiles ([ipfs/go-ipfs#2999](https://github.com/ipfs/go-ipfs/pull/2999)) ([ipfs/go-ipfs#3265](https://github.com/ipfs/go-ipfs/pull/3265)) + - Refactor install.sh script ([ipfs/go-ipfs#3194](https://github.com/ipfs/go-ipfs/pull/3194)) + - Add test check for go code formatting ([ipfs/go-ipfs#3421](https://github.com/ipfs/go-ipfs/pull/3421)) + - bin: dist_get script: prevents get_go_vars() returns same values twice ([ipfs/go-ipfs#3079](https://github.com/ipfs/go-ipfs/pull/3079)) + +- Dependencies + - Update libp2p to have fixed spdystream dep ([ipfs/go-ipfs#3210](https://github.com/ipfs/go-ipfs/pull/3210)) + - Update libp2p and dht packages ([ipfs/go-ipfs#3263](https://github.com/ipfs/go-ipfs/pull/3263)) + - Update to libp2p 4.0.1 and propogate other changes ([ipfs/go-ipfs#3284](https://github.com/ipfs/go-ipfs/pull/3284)) + - Update to libp2p 4.0.4 ([ipfs/go-ipfs#3361](https://github.com/ipfs/go-ipfs/pull/3361)) + - Update go-libp2p across codebase ([ipfs/go-ipfs#3406](https://github.com/ipfs/go-ipfs/pull/3406)) + - Update to go-libp2p 4.1.0 ([ipfs/go-ipfs#3373](https://github.com/ipfs/go-ipfs/pull/3373)) + - Update deps for libp2p 3.4.0 ([ipfs/go-ipfs#3110](https://github.com/ipfs/go-ipfs/pull/3110)) + - Update go-libp2p-swarm with deadlock fixes ([ipfs/go-ipfs#3339](https://github.com/ipfs/go-ipfs/pull/3339)) + - Update to new cid and ipld node packages ([ipfs/go-ipfs#3326](https://github.com/ipfs/go-ipfs/pull/3326)) + - Update to newer ipld node interface with Copy and better Tree ([ipfs/go-ipfs#3391](https://github.com/ipfs/go-ipfs/pull/3391)) + - Update experimental go-multiplex to 0.2.6 ([ipfs/go-ipfs#3475](https://github.com/ipfs/go-ipfs/pull/3475)) + - Rework routing interfaces to make separation easier ([ipfs/go-ipfs#3107](https://github.com/ipfs/go-ipfs/pull/3107)) + - Update to dht code with fixed GetClosestPeers ([ipfs/go-ipfs#3346](https://github.com/ipfs/go-ipfs/pull/3346)) + - Move go-is-domain to gx ([ipfs/go-ipfs#3077](https://github.com/ipfs/go-ipfs/pull/3077)) + - Extract thirdparty/loggables and thirdparty/peerset ([ipfs/go-ipfs#3204](https://github.com/ipfs/go-ipfs/pull/3204)) + - Completely remove go-key dep ([ipfs/go-ipfs#3439](https://github.com/ipfs/go-ipfs/pull/3439)) + - Remove randbo dep, its no longer needed ([ipfs/go-ipfs#3118](https://github.com/ipfs/go-ipfs/pull/3118)) + - Update libp2p for identify configuration updates ([ipfs/go-ipfs#3539](https://github.com/ipfs/go-ipfs/pull/3539)) + - Use newer flatfs sharding scheme ([ipfs/go-ipfs#3608](https://github.com/ipfs/go-ipfs/pull/3608)) + +- Testing + - fix test_fsh arg quoting in ipfs-test-lib ([ipfs/go-ipfs#3085](https://github.com/ipfs/go-ipfs/pull/3085)) + - 100% coverage for blocks/blocksutil ([ipfs/go-ipfs#3090](https://github.com/ipfs/go-ipfs/pull/3090)) + - 100% coverage on blocks/set ([ipfs/go-ipfs#3084](https://github.com/ipfs/go-ipfs/pull/3084)) + - 81% coverage on blockstore ([ipfs/go-ipfs#3074](https://github.com/ipfs/go-ipfs/pull/3074)) + - 80% coverage of unixfs/mod ([ipfs/go-ipfs#3096](https://github.com/ipfs/go-ipfs/pull/3096)) + - 82% coverage on blocks ([ipfs/go-ipfs#3086](https://github.com/ipfs/go-ipfs/pull/3086)) + - 87% coverage on unixfs ([ipfs/go-ipfs#3492](https://github.com/ipfs/go-ipfs/pull/3492)) + - Improve coverage on routing/offline ([ipfs/go-ipfs#3516](https://github.com/ipfs/go-ipfs/pull/3516)) + - Add test for flags package ([ipfs/go-ipfs#3449](https://github.com/ipfs/go-ipfs/pull/3449)) + - improve test coverage on merkledag package ([ipfs/go-ipfs#3113](https://github.com/ipfs/go-ipfs/pull/3113)) + - 80% coverage of unixfs/io ([ipfs/go-ipfs#3097](https://github.com/ipfs/go-ipfs/pull/3097)) + - Accept more than one digit in repo version tests ([ipfs/go-ipfs#3130](https://github.com/ipfs/go-ipfs/pull/3130)) + - Fix typo in hash in t0050 ([ipfs/go-ipfs#3170](https://github.com/ipfs/go-ipfs/pull/3170)) + - fix bug in pinsets and add a stress test for the scenario ([ipfs/go-ipfs#3273](https://github.com/ipfs/go-ipfs/pull/3273)) ([ipfs/go-ipfs#3302](https://github.com/ipfs/go-ipfs/pull/3302)) + - Report coverage to codecov ([ipfs/go-ipfs#3473](https://github.com/ipfs/go-ipfs/pull/3473)) + - Add test for 'ipfs config replace' ([ipfs/go-ipfs#3073](https://github.com/ipfs/go-ipfs/pull/3073)) + - Fix netcat on macOS not closing socket when the stdin sends EOF ([ipfs/go-ipfs#3515](https://github.com/ipfs/go-ipfs/pull/3515)) + +- Documentation + - Update dns help with a correct domain name ([ipfs/go-ipfs#3087](https://github.com/ipfs/go-ipfs/pull/3087)) + - Add period to `ipfs pin rm` ([ipfs/go-ipfs#3088](https://github.com/ipfs/go-ipfs/pull/3088)) + - Make all Taglines use imperative mood ([ipfs/go-ipfs#3041](https://github.com/ipfs/go-ipfs/pull/3041)) + - Document listing commands better ([ipfs/go-ipfs#3083](https://github.com/ipfs/go-ipfs/pull/3083)) + - Add notes to readme on building for uncommon systems ([ipfs/go-ipfs#3051](https://github.com/ipfs/go-ipfs/pull/3051)) + - Add branch naming conventions doc ([ipfs/go-ipfs#3035](https://github.com/ipfs/go-ipfs/pull/3035)) + - Replace keyword with <> ([ipfs/go-ipfs#3129](https://github.com/ipfs/go-ipfs/pull/3129)) + - Fix Add() docs regarding pinning ([ipfs/go-ipfs#3513](https://github.com/ipfs/go-ipfs/pull/3513)) + - Add sudo to install commands. ([ipfs/go-ipfs#3201](https://github.com/ipfs/go-ipfs/pull/3201)) + - Add docs for `"commands".Command.Run` ([ipfs/go-ipfs#3382](https://github.com/ipfs/go-ipfs/pull/3382)) + - Put config keys in proper case ([ipfs/go-ipfs#3365](https://github.com/ipfs/go-ipfs/pull/3365)) + - Fix link in `ipfs stats bw` help message ([ipfs/go-ipfs#3620](https://github.com/ipfs/go-ipfs/pull/3620)) + + +### 0.4.4 - 2016-10-11 + +This release contains an important hotfix for a bug we discovered in how pinning works. +If you had a large number of pins, new pins would overwrite existing pins. +Apart from the hotfix, this release is equal to the previous release 0.4.3. + +- Fix bug in pinsets fanout, and add stress test. (@whyrusleeping, [ipfs/go-ipfs#3273](https://github.com/ipfs/go-ipfs/pull/3273)) + +We published a [detailed account of the bug and fix in a blog post](https://ipfs.io/blog/21-go-ipfs-0-4-4-released/). + +### 0.4.3 - 2016-09-20 + +There have been no changes since the last release candidate 0.4.3-rc4. \o/ + +### 0.4.3-rc4 - 2016-09-09 + +This release candidate fixes issues in Bitswap and the `ipfs add` command, and improves testing. +We plan for this to be the last release candidate before the release of go-ipfs v0.4.3. + +With this release candidate, we're also moving go-ipfs to Go 1.7, which we expect will yield improvements in runtime performance, memory usage, build time and size of the release binaries. + +- Require Go 1.7. (@whyrusleeping, @Kubuxu, @lgierth, [ipfs/go-ipfs#3163](https://github.com/ipfs/go-ipfs/pull/3163)) + - For this purpose, switch Docker image from Alpine 3.4 to Alpine Edge. +- Fix cancellation of Bitswap `wantlist` entries. (@whyrusleeping, [ipfs/go-ipfs#3182](https://github.com/ipfs/go-ipfs/pull/3182)) +- Fix clearing of `active` state of Bitswap provider queries. (@whyrusleeping, [ipfs/go-ipfs#3169](https://github.com/ipfs/go-ipfs/pull/3169)) +- Fix a panic in the DHT code. (@Kubuxu, [ipfs/go-ipfs#3200](https://github.com/ipfs/go-ipfs/pull/3200)) +- Improve handling of `Identity` field in `ipfs config` command. (@Kubuxu, @whyrusleeping, [ipfs/go-ipfs#3141](https://github.com/ipfs/go-ipfs/pull/3141)) +- Fix explicit adding of symlinked files and directories. (@kevina, [ipfs/go-ipfs#3135](https://github.com/ipfs/go-ipfs/pull/3135)) +- Fix bash auto-completion of `ipfs daemon --unrestricted-api` option. (@lgierth, [ipfs/go-ipfs#3159](https://github.com/ipfs/go-ipfs/pull/3159)) +- Introduce a new timeout tool for tests to avoid licensing issues. (@Kubuxu, [ipfs/go-ipfs#3152](https://github.com/ipfs/go-ipfs/pull/3152)) +- Improve output for migrations of fs-repo. (@lgierth, [ipfs/go-ipfs#3158](https://github.com/ipfs/go-ipfs/pull/3158)) +- Fix info notice of commands taking input from stdin. (@Kubuxu, [ipfs/go-ipfs#3134](https://github.com/ipfs/go-ipfs/pull/3134)) +- Bring back a few tests for stdin handling of `ipfs cat` and `ipfs add`. (@Kubuxu, [ipfs/go-ipfs#3144](https://github.com/ipfs/go-ipfs/pull/3144)) +- Improve sharness tests for `ipfs repo verify` command. (@whyrusleeping, [ipfs/go-ipfs#3148](https://github.com/ipfs/go-ipfs/pull/3148)) +- Improve sharness tests for CORS headers on the gateway. (@Kubuxu, [ipfs/go-ipfs#3142](https://github.com/ipfs/go-ipfs/pull/3142)) +- Improve tests for pinning within `ipfs files`. (@kevina, [ipfs/go-ipfs#3151](https://github.com/ipfs/go-ipfs/pull/3151)) +- Improve tests for the automatic raising of file descriptor limits. (@whyrusleeping, [ipfs/go-ipfs#3149](https://github.com/ipfs/go-ipfs/pull/3149)) + +### 0.4.3-rc3 - 2016-08-11 + +This release candidate fixes a panic that occurs when input from stdin was +expected, but none was given: [ipfs/go-ipfs#3050](https://github.com/ipfs/go-ipfs/pull/3050) + +### 0.4.3-rc2 - 2016-08-04 + +This release includes bugfixes and fixes for regressions that were introduced +between 0.4.2 and 0.4.3-rc1. + +- Regressions + - Fix daemon panic when there is no multipart input provided over the HTTP API. + (@whyrusleeping, [ipfs/go-ipfs#2989](https://github.com/ipfs/go-ipfs/pull/2989)) + - Fix `ipfs refs --edges` not printing edges. + (@Kubuxu, [ipfs/go-ipfs#3007](https://github.com/ipfs/go-ipfs/pull/3007)) + - Fix progress option for `ipfs add` defaulting to true on the HTTP API. + (@whyrusleeping, [ipfs/go-ipfs#3025](https://github.com/ipfs/go-ipfs/pull/3025)) + - Fix erroneous printing of stdin reading message. + (@whyrusleeping, [ipfs/go-ipfs#3033](https://github.com/ipfs/go-ipfs/pull/3033)) + - Fix panic caused by passing `--mount` and `--offline` flags to `ipfs daemon`. + (@Kubuxu, [ipfs/go-ipfs#3022](https://github.com/ipfs/go-ipfs/pull/3022)) + - Fix symlink path resolution on windows. + (@Kubuxu, [ipfs/go-ipfs#3023](https://github.com/ipfs/go-ipfs/pull/3023)) + - Add in code to prevent issue 3032 from crashing the daemon. + (@whyrusleeping, [ipfs/go-ipfs#3037](https://github.com/ipfs/go-ipfs/pull/3037)) + + +### 0.4.3-rc1 - 2016-07-23 + +This is a maintenance release which comes with a couple of nice enhancements, and improves the performance of Storage, Bitswap, as well as Content and Peer Routing. It also introduces a handful of new commands and options, and fixes a good bunch of bugs. + +This is the first Release Candidate. Unless there are vulnerabilities or regressions discovered, the final 0.4.3 release will happen about one week from now. + +- Security Vulnerability + + - The `master` branch if go-ipfs suffered from a vulnerability for about 3 weeks. It allowed an attacker to use an iframe to request malicious HTML and JS from the API of a local go-ipfs node. The attacker could then gain unrestricted access to the node's API, and e.g. extract the private key. We fixed this issue by reintroducing restrictions on which particular objects can be loaded through the API (@lgierth, [ipfs/go-ipfs#2949](https://github.com/ipfs/go-ipfs/pull/2949)), and by completely excluding the private key from the API (@Kubuxu, [ipfs/go-ipfs#2957](https://github.com/ipfs/go-ipfs/pull/2957)). We will also work on more hardening of the API in the next release. + - **The previous release 0.4.2 is not vulnerable. That means if you're using official binaries from [dist.ipfs.io](https://dist.ipfs.io) you're not affected.** If you're running go-ipfs built from the `master` branch between June 17th ([ipfs/go-ipfs@1afebc21](https://github.com/ipfs/go-ipfs/commit/1afebc21f324982141ca8a29710da0d6f83ca804)) and July 7th ([ipfs/go-ipfs@39bef0d5](https://github.com/ipfs/go-ipfs/commit/39bef0d5b01f70abf679fca2c4d078a2d55620e2)), please update to v0.4.3-rc1 immediately. + - We are grateful to the group of independent researchers who made us aware of this vulnerability. We wanna use this opportunity to reiterate that we're very happy about any additional review of pull requests and releases. You can contact us any time at security@ipfs.io (GPG [4B9665FB 92636D17 7C7A86D3 50AAE8A9 59B13AF3](https://pgp.mit.edu/pks/lookup?op=get&search=0x50AAE8A959B13AF3)). + +- Notable changes + + - Improve Bitswap performance. (@whyrusleeping, [ipfs/go-ipfs#2727](https://github.com/ipfs/go-ipfs/pull/2727), [ipfs/go-ipfs#2798](https://github.com/ipfs/go-ipfs/pull/2798)) + - Improve Content Routing and Peer Routing performance. (@whyrusleeping, [ipfs/go-ipfs#2817](https://github.com/ipfs/go-ipfs/pull/2817), [ipfs/go-ipfs#2841](https://github.com/ipfs/go-ipfs/pull/2841)) + - Improve datastore, blockstore, and dagstore performance. (@kevina, @Kubuxu, @whyrusleeping [ipfs/go-datastore#43](https://github.com/ipfs/go-datastore/pull/43), [ipfs/go-ipfs#2885](https://github.com/ipfs/go-ipfs/pull/2885), [ipfs/go-ipfs#2961](https://github.com/ipfs/go-ipfs/pull/2961), [ipfs/go-ipfs#2953](https://github.com/ipfs/go-ipfs/pull/2953), [ipfs/go-ipfs#2960](https://github.com/ipfs/go-ipfs/pull/2960)) + - Content Providers are now stored on disk to gain savings on process memory. (@whyrusleeping, [ipfs/go-ipfs#2804](https://github.com/ipfs/go-ipfs/pull/2804), [ipfs/go-ipfs#2860](https://github.com/ipfs/go-ipfs/pull/2860)) + - Migrations of the fs-repo (usually stored at `~/.ipfs`) now run automatically. If there's a TTY available, you'll get prompted when running `ipfs daemon`, and in addition you can use the `--migrate=true` or `--migrate=false` options to avoid the prompt. (@whyrusleeping, @lgierth, [ipfs/go-ipfs#2939](https://github.com/ipfs/go-ipfs/pull/2939)) + - The internal naming of blocks in the blockstore has changed, which requires a migration of the fs-repo, from version 3 to 4. (@whyrusleeping, [ipfs/go-ipfs#2903](https://github.com/ipfs/go-ipfs/pull/2903)) + - We now automatically raise the file descriptor limit to 1024 if neccessary. (@whyrusleeping, [ipfs/go-ipfs#2884](https://github.com/ipfs/go-ipfs/pull/2884), [ipfs/go-ipfs#2891](https://github.com/ipfs/go-ipfs/pull/2891)) + - After a long struggle with deadlocks and hanging connections, we've decided to disable the uTP transport by default for now. (@whyrusleeping, [ipfs/go-ipfs#2840](https://github.com/ipfs/go-ipfs/pull/2840), [ipfs/go-libp2p-transport@88244000](https://github.com/ipfs/go-libp2p-transport/commit/88244000f0ce8851ffcfbac746ebc0794b71d2a4)) + - There is now documentation for the configuration options in `docs/config.md`. (@whyrusleeping, [ipfs/go-ipfs#2974](https://github.com/ipfs/go-ipfs/pull/2974)) + - All commands now sanely handle the combination of stdin and optional flags in certain edge cases. (@lgierth, [ipfs/go-ipfs#2952](https://github.com/ipfs/go-ipfs/pull/2952)) + +- New Features + + - Add `--offline` option to `ipfs daemon` command, which disables all swarm networking. (@Kubuxu, [ipfs/go-ipfs#2696](https://github.com/ipfs/go-ipfs/pull/2696), [ipfs/go-ipfs#2867](https://github.com/ipfs/go-ipfs/pull/2867)) + - Add `Datastore.HashOnRead` option for verifying block hashes on read access. (@Kubuxu, [ipfs/go-ipfs#2904](https://github.com/ipfs/go-ipfs/pull/2904)) + - Add `Datastore.BloomFilterSize` option for tuning the blockstore's new lookup bloom filter. (@Kubuxu, [ipfs/go-ipfs#2973](https://github.com/ipfs/go-ipfs/pull/2973)) + +- Bugfixes + + - Fix publishing of local IPNS entries, and more. (@whyrusleeping, [ipfs/go-ipfs#2943](https://github.com/ipfs/go-ipfs/pull/2943)) + - Fix progress bars in `ipfs add` and `ipfs get`. (@whyrusleeping, [ipfs/go-ipfs#2893](https://github.com/ipfs/go-ipfs/pull/2893), [ipfs/go-ipfs#2948](https://github.com/ipfs/go-ipfs/pull/2948)) + - Make sure files added through `ipfs files` are pinned and don't get GC'd. (@kevina, [ipfs/go-ipfs#2872](https://github.com/ipfs/go-ipfs/pull/2872)) + - Fix copying into directory using `ipfs files cp`. (@whyrusleeping, [ipfs/go-ipfs#2977](https://github.com/ipfs/go-ipfs/pull/2977)) + - Fix `ipfs version --commit` with Docker containers. (@lgierth, [ipfs/go-ipfs#2734](https://github.com/ipfs/go-ipfs/pull/2734)) + - Run `ipfs diag` commands in the daemon instead of the CLI. (@Kubuxu, [ipfs/go-ipfs#2761](https://github.com/ipfs/go-ipfs/pull/2761)) + - Fix protobuf encoding on the API and in commands. (@stebalien, [ipfs/go-ipfs#2516](https://github.com/ipfs/go-ipfs/pull/2516)) + - Fix goroutine leak in `/ipfs/ping` protocol handler. (@whyrusleeping, [ipfs/go-libp2p#58](https://github.com/ipfs/go-libp2p/pull/58)) + - Fix `--flags` option on `ipfs commands`. (@Kubuxu, [ipfs/go-ipfs#2773](https://github.com/ipfs/go-ipfs/pull/2773)) + - Fix the error channels in `namesys`. (@whyrusleeping, [ipfs/go-ipfs#2788](https://github.com/ipfs/go-ipfs/pull/2788)) + - Fix consumptions of observed swarm addresses. (@whyrusleeping, [ipfs/go-libp2p#63](https://github.com/ipfs/go-libp2p/pull/63), [ipfs/go-ipfs#2771](https://github.com/ipfs/go-ipfs/issues/2771)) + - Fix a rare DHT panic. (@whyrusleeping, [ipfs/go-ipfs#2856](https://github.com/ipfs/go-ipfs/pull/2856)) + - Fix go-ipfs/js-ipfs interoperability issues in SPDY. (@whyrusleeping, [whyrusleeping/go-smux-spdystream@fae17783](https://github.com/whyrusleeping/go-smux-spdystream/commit/fae1778302a9e029bb308cf71cf33f857f2d89e8)) + - Fix a logging race condition during shutdown. (@Kubuxu, [ipfs/go-log#3](https://github.com/ipfs/go-log/pull/3)) + - Prevent DHT connection hangs. (@whyrusleeping, [ipfs/go-ipfs#2826](https://github.com/ipfs/go-ipfs/pull/2826), [ipfs/go-ipfs#2863](https://github.com/ipfs/go-ipfs/pull/2863)) + - Fix NDJSON output of `ipfs refs local`. (@Kubuxu, [ipfs/go-ipfs#2812](https://github.com/ipfs/go-ipfs/pull/2812)) + - Fix race condition in NAT detection. (@whyrusleeping, [ipfs/go-libp2p#69](https://github.com/ipfs/go-libp2p/pull/69)) + - Fix error messages. (@whyrusleeping, @Kubuxu, [ipfs/go-ipfs#2905](https://github.com/ipfs/go-ipfs/pull/2905), [ipfs/go-ipfs#2928](https://github.com/ipfs/go-ipfs/pull/2928)) + +- Enhancements + + - Increase maximum object size on `ipfs put` from 1 MiB to 2 MiB. The maximum object size on the wire including all framing is 4 MiB. (@kpcyrd, [ipfs/go-ipfs#2980](https://github.com/ipfs/go-ipfs/pull/2980)) + - Add CORS headers to the Gateway's default config. (@Kubuxu, [ipfs/go-ipfs#2778](https://github.com/ipfs/go-ipfs/pull/2778)) + - Clear the dial backoff for a peer when using `ipfs swarm connect`. (@whyrusleeping, [ipfs/go-ipfs#2941](https://github.com/ipfs/go-ipfs/pull/2941)) + - Allow passing options to daemon in Docker container. (@lgierth, [ipfs/go-ipfs#2955](https://github.com/ipfs/go-ipfs/pull/2955)) + - Add `-v/--verbose` to `ìpfs swarm peers` command. (@csasarak, [ipfs/go-ipfs#2713](https://github.com/ipfs/go-ipfs/pull/2713)) + - Add `--format`, `--hash`, and `--size` options to `ipfs files stat` command. (@Kubuxu, [ipfs/go-ipfs#2706](https://github.com/ipfs/go-ipfs/pull/2706)) + - Add `--all` option to `ipfs version` command. (@Kubuxu, [ipfs/go-ipfs#2790](https://github.com/ipfs/go-ipfs/pull/2790)) + - Add `ipfs repo version` command. (@pfista, [ipfs/go-ipfs#2598](https://github.com/ipfs/go-ipfs/pull/2598)) + - Add `ipfs repo verify` command. (@whyrusleeping, [ipfs/go-ipfs#2924](https://github.com/ipfs/go-ipfs/pull/2924), [ipfs/go-ipfs#2951](https://github.com/ipfs/go-ipfs/pull/2951)) + - Add `ipfs stats repo` and `ipfs stats bitswap` command aliases. (@pfista, [ipfs/go-ipfs#2810](https://github.com/ipfs/go-ipfs/pull/2810)) + - Add success indication to responses of `ipfs ping` command. (@Kubuxu, [ipfs/go-ipfs#2813](https://github.com/ipfs/go-ipfs/pull/2813)) + - Save changes made via `ipfs swarm filter` to the config file. (@yuvallanger, [ipfs/go-ipfs#2880](https://github.com/ipfs/go-ipfs/pull/2880)) + - Expand `ipfs_p2p_peers` metric to include libp2p transport. (@lgierth, [ipfs/go-ipfs#2728](https://github.com/ipfs/go-ipfs/pull/2728)) + - Rework `ipfs files add` internals to avoid caching and prevent memory leaks. (@whyrusleeping, [ipfs/go-ipfs#2795](https://github.com/ipfs/go-ipfs/pull/2795)) + - Support `GOPATH` with multiple path components. (@karalabe, @lgierth, @djdv, [ipfs/go-ipfs#2808](https://github.com/ipfs/go-ipfs/pull/2808), [ipfs/go-ipfs#2862](https://github.com/ipfs/go-ipfs/pull/2862), [ipfs/go-ipfs#2975](https://github.com/ipfs/go-ipfs/pull/2975)) + +- General Codebase + + - Take steps towards the `filestore` datastore. (@kevina, [ipfs/go-ipfs#2792](https://github.com/ipfs/go-ipfs/pull/2792), [ipfs/go-ipfs#2634](https://github.com/ipfs/go-ipfs/pull/2634)) + - Update recommended Golang version to 1.6.2 (@Kubuxu, [ipfs/go-ipfs#2724](https://github.com/ipfs/go-ipfs/pull/2724)) + - Update to Gx 0.8.0 and Gx-Go 1.2.1, which is faster and less noisy. (@whyrusleeping, [ipfs/go-ipfs#2979](https://github.com/ipfs/go-ipfs/pull/2979)) + - Use `go4.org/lock` instead of `camlistore/lock` for locking. (@whyrusleeping, [ipfs/go-ipfs#2887](https://github.com/ipfs/go-ipfs/pull/2887)) + - Manage `go.uuid`, `hamming`, `backoff`, `proquint`, `pb`, `go-context`, `cors`, `go-datastore` packages with Gx. (@Kubuxu, [ipfs/go-ipfs#2733](https://github.com/ipfs/go-ipfs/pull/2733), [ipfs/go-ipfs#2736](https://github.com/ipfs/go-ipfs/pull/2736), [ipfs/go-ipfs#2757](https://github.com/ipfs/go-ipfs/pull/2757), [ipfs/go-ipfs#2825](https://github.com/ipfs/go-ipfs/pull/2825), [ipfs/go-ipfs#2838](https://github.com/ipfs/go-ipfs/pull/2838)) + - Clean up the gateway's surface. (@lgierth, [ipfs/go-ipfs#2874](https://github.com/ipfs/go-ipfs/pull/2874)) + - Simplify the API gateway's access restrictions. (@lgierth, [ipfs/go-ipfs#2949](https://github.com/ipfs/go-ipfs/pull/2949), [ipfs/go-ipfs#2956](https://github.com/ipfs/go-ipfs/pull/2956)) + - Update docker image to Alpine Linux 3.4 and remove Go version constraint. (@lgierth, [ipfs/go-ipfs#2901](https://github.com/ipfs/go-ipfs/pull/2901), [ipfs/go-ipfs#2929](https://github.com/ipfs/go-ipfs/pull/2929)) + - Clarify `Dockerfile` and `Dockerfile.fast`. (@lgierth, [ipfs/go-ipfs#2796](https://github.com/ipfs/go-ipfs/pull/2796)) + - Simplify resolution of Git commit refs in Dockerfiles. (@lgierth, [ipfs/go-ipfs#2754](https://github.com/ipfs/go-ipfs/pull/2754)) + - Consolidate `--verbose` description across commands. (@Kubuxu, [ipfs/go-ipfs#2746](https://github.com/ipfs/go-ipfs/pull/2746)) + - Allow setting position of default values in command option descriptions. (@Kubuxu, [ipfs/go-ipfs#2744](https://github.com/ipfs/go-ipfs/pull/2744)) + - Set explicit default values for boolean command options. (@RichardLitt, [ipfs/go-ipfs#2657](https://github.com/ipfs/go-ipfs/pull/2657)) + - Autogenerate command synopsises. (@Kubuxu, [ipfs/go-ipfs#2785](https://github.com/ipfs/go-ipfs/pull/2785)) + - Fix and improve lots of documentation. (@RichardLitt, [ipfs/go-ipfs#2741](https://github.com/ipfs/go-ipfs/pull/2741), [ipfs/go-ipfs#2781](https://github.com/ipfs/go-ipfs/pull/2781)) + - Improve command descriptions to fit a width of 78 characters. (@RichardLitt, [ipfs/go-ipfs#2779](https://github.com/ipfs/go-ipfs/pull/2779), [ipfs/go-ipfs#2780](https://github.com/ipfs/go-ipfs/pull/2780), [ipfs/go-ipfs#2782](https://github.com/ipfs/go-ipfs/pull/2782)) + - Fix filename conflict in the debugging guide. (@Kubuxu, [ipfs/go-ipfs#2752](https://github.com/ipfs/go-ipfs/pull/2752)) + - Decapitalize log messages, according to Golang style guides. (@RichardLitt, [ipfs/go-ipfs#2853](https://github.com/ipfs/go-ipfs/pull/2853)) + - Add Github Issues HowTo guide. (@RichardLitt, @chriscool, [ipfs/go-ipfs#2889](https://github.com/ipfs/go-ipfs/pull/2889), [ipfs/go-ipfs#2895](https://github.com/ipfs/go-ipfs/pull/2895)) + - Add Github Issue template. (@chriscool, [ipfs/go-ipfs#2786](https://github.com/ipfs/go-ipfs/pull/2786)) + - Apply standard-readme to the README file. (@RichardLitt, [ipfs/go-ipfs#2883](https://github.com/ipfs/go-ipfs/pull/2883)) + - Fix issues pointed out by `govet`. (@Kubuxu, [ipfs/go-ipfs#2854](https://github.com/ipfs/go-ipfs/pull/2854)) + - Clarify `ipfs get` error message. (@whyrusleeping, [ipfs/go-ipfs#2886](https://github.com/ipfs/go-ipfs/pull/2886)) + - Remove dead code. (@whyrusleeping, [ipfs/go-ipfs#2819](https://github.com/ipfs/go-ipfs/pull/2819)) + - Add changelog for v0.4.3. (@lgierth, [ipfs/go-ipfs#2984](https://github.com/ipfs/go-ipfs/pull/2984)) + +- Tests & CI + + - Fix flaky `ipfs mount` sharness test by using the `iptb` tool. (@noffle, [ipfs/go-ipfs#2707](https://github.com/ipfs/go-ipfs/pull/2707)) + - Fix flaky IP port selection in tests. (@Kubuxu, [ipfs/go-ipfs#2855](https://github.com/ipfs/go-ipfs/pull/2855)) + - Fix CLI tests on OSX by resolving /tmp symlink. (@Kubuxu, [ipfs/go-ipfs#2926](https://github.com/ipfs/go-ipfs/pull/2926)) + - Fix flaky GC test by running the daemon in offline mode. (@Kubuxu, [ipfs/go-ipfs#2908](https://github.com/ipfs/go-ipfs/pull/2908)) + - Add tests for `ipfs add` with hidden files. (@Kubuxu, [ipfs/go-ipfs#2756](https://github.com/ipfs/go-ipfs/pull/2756)) + - Add test to make sure the body of HEAD responses is empty. (@Kubuxu, [ipfs/go-ipfs#2775](https://github.com/ipfs/go-ipfs/pull/2775)) + - Add test to catch misdials. (@Kubuxu, [ipfs/go-ipfs#2831](https://github.com/ipfs/go-ipfs/pull/2831)) + - Mark flaky tests for `ipfs dht query` as known failure. (@noffle, [ipfs/go-ipfs#2720](https://github.com/ipfs/go-ipfs/pull/2720)) + - Remove failing blockstore-without-context test. (@Kubuxu, [ipfs/go-ipfs#2857](https://github.com/ipfs/go-ipfs/pull/2857)) + - Fix `--version` tests for versions with a suffix like `-dev` or `-rc1`. (@lgierth, [ipfs/go-ipfs#2937](https://github.com/ipfs/go-ipfs/pull/2937)) + - Make sharness tests work in cases where go-ipfs is symlinked into GOPATH. (@lgierth, [ipfs/go-ipfs#2937](https://github.com/ipfs/go-ipfs/pull/2937)) + - Add variable delays to blockstore mocks. (@rikonor, [ipfs/go-ipfs#2871](https://github.com/ipfs/go-ipfs/pull/2871)) + - Disable Travis CI email notifications. (@Kubuxu, [ipfs/go-ipfs#2896](https://github.com/ipfs/go-ipfs/pull/2896)) + + +### 0.4.2 - 2016-05-17 + +This is a patch release which fixes performance and networking bugs in go-libp2p, +You should see improvements in CPU and RAM usage, as well as speed of object lookups. +There are also a few other nice improvements. + +* Notable Fixes + * Set a deadline for dialing attempts. This prevents a node from accumulating + failed connections. (@whyrusleeping) + * Avoid unnecessary string/byte conversions in go-multihash. (@whyrusleeping) + * Fix a deadlock around the yamux stream muxer. (@whyrusleeping) + * Fix a bug that left channels open, causing hangs. (@whyrusleeping) + * Fix a bug around yamux which caused connection hangs. (@whyrusleeping) + * Fix a crash caused by nil multiaddrs. (@whyrusleeping) + +* Enhancements + * Add NetBSD support. (@erde74) + * Set Cache-Control: immutable on /ipfs responses. (@kpcyrd) + * Have `ipfs init` optionally accept a default configuration from stdin. (@sivachandran) + * Add `ipfs log ls` command for listing logging subsystems. (@hsanjuan) + * Allow bitswap to read multiple messages per stream. (@whyrusleeping) + * Remove `make toolkit_upgrade` step. (@chriscool) + +* Documentation + * Add a debug-guidelines document. (@richardlitt) + * Update the contribute document. (@richardlitt) + * Fix documentation of many `ipfs` commands. (@richardlitt) + * Fall back to ShortDesc if LongDesc is missing. (@Kubuxu) + +* Removals + * Remove -f option from `ipfs init` command. (@whyrusleeping) + +* Bugfixes + * Fix `ipfs object patch` argument handling and validation. (@jbenet) + * Fix `ipfs config edit` command by running it client-side. (@Kubuxu) + * Set default value for `ipfs refs` arguments. (@richardlitt) + * Fix parsing of incorrect command and argument permutations. (@thomas-gardner) + * Update Dockerfile to latest go1.5.4-r0. (@chriscool) + * Allow passing IPFS_LOGGING to Docker image. (@lgierth) + * Fix dot path parsing on Windows. (@djdv) + * Fix formatting of `ipfs log ls` output. (@richardlitt) + +* General Codebase + * Refactor Makefile. (@kevina) + * Wire context into bitswap requests more deeply. (@whyrusleeping) + * Use gx for iptb. (@chriscool) + * Update gx and gx-go. (@chriscool) + * Make blocks.Block an interface. (@kevina) + * Silence check for Docker existance. (@chriscool) + * Add dist_get script for fetching tools from dist.ipfs.io. (@whyrusleeping) + * Add proper defaults to all `ipfs` commands. (@richardlitt) + * Remove dead `count` option from `ipfs pin ls`. (@richardlitt) + * Initialize pin mode strings only once. (@chriscool) + * Add changelog for v0.4.2. (@lgierth) + * Specify a dist.ipfs.io hash for tool downloads instead of trusting DNS. (@lgierth) + +* CI + * Fix t0170-dht sharness test. (@chriscool) + * Increase timeout in t0060-daemon sharness test. (@Kubuxu) + * Have CircleCI use `make deps` instead of `gx` directly. (@whyrusleeping) + + +### 0.4.1 - 2016-04-25 + +This is a patch release that fixes a few bugs, and adds a few small (but not +insignificant) features. The primary reason for this release is the listener +hang bugfix that was shipped in the 0.4.0 release. + +* Features + * implemented ipfs object diff (@whyrusleeping) + * allow promises (used in get, refs) to fail (@whyrusleeping) + +* Tool changes + * Adds 'toolkit_upgrade' to the makefile help target (@achin) + +* General Codebase + * Use extracted go-libp2p-crypto, -secio, -peer packages (@lgierth) + * Update go-libp2p (@lgierth) + * Fix package manifest fields (@lgierth) + * remove incfusever dead-code (@whyrusleeping) + * remove a ton of unused godeps (@whyrusleeping) + * metrics: add prometheus back (@lgierth) + * clean up dead code and config fields (@whyrusleeping) + * Add log events when blocks are added/removed from the blockstore (@michealmure) + * repo: don't create logs directory, not used any longer (@lgierth) + +* Bugfixes + * fixed ipfs name resolve --local multihash error (@pfista) + * ipfs patch commands won't return null links field anymore (@whyrusleeping) + * Make non recursive resolve print the result (@Kubuxu) + * Output dirs on ipfs add -rn (@noffle) + * update libp2p dep to fix hanging listeners problem (@whyrusleeping) + * Fix Swarm.AddrFilters config setting with regard to `/ip6` addresses (@lgierth) + * fix dht command key escaping (@whyrusleeping) + +* Testing + * Adds tests to make sure 'object patch' writes. (@noffle) + * small sharness test for promise failure checking (@whyrusleeping) + * sharness/Makefile: clean all BINS when cleaning (@chriscool) + +* Documentation + * Fix disconnect argument description (@richardlitt) + * Added a note about swarm disconnect (@richardlitt) + * Also fixed syntax for comment (@richardlitt) + * Alphabetized swarm subcmds (@richardlitt) + * Added note to ipfs stats bw interval option (@richardlitt) + * Small syntax changes to repo stat man (@richardlitt) + * update log command help text (@pfista) + * Added a long description to add (@richardlitt) + * Edited object patch set-data doc (@richardlitt) + * add roadmap.md (@Jeromy) + * Adds files api cmd to helptext (@noffle) + + +### 0.4.0 - 2016-04-05 + +This is a major release with plenty of new features and bugfixes. +It also includes breaking changes which make it incompatible with v0.3.x +on the networking layer. + +* Major Changes + * Multistream + * The addition of multistream is a breaking change on the networking layer, + but gives IPFS implementations the ability to mix and match different + stream multiplexers, e.g. yamux, spdystream, or muxado. + This adds a ton of flexibility on one of the lower layers of the protocol, + and will help us avoid further breaking protocol changes in the future. + * Files API + * The new `files` command and API allow a program to interact with IPFS + using familiar filesystem operations, namely: creating directories, + reading, writing, and deleting files, listing out different directories, + and so on. This feature enables any other application that uses a + filesystem-like backend for storage, to use IPFS as its storage driver + without having change the application logic at all. + * Gx + * go-ipfs now uses [gx](https://github.com/whyrusleeping/gx) to manage its + dependencies. This means that under the hood, go-ipfs's dependencies are + backed by IPFS itself! It also means that go-ipfs is no longer installed + using `go get`. Use `make install` instead. +* New Features + * Web UI + * Update to new version which is compatible with 0.4.0. (@dignifiedquire) + * Networking + * Implement uTP transport. (@whyrusleeping) + * Allow multiple addresses per configured bootstrap node. (@whyrusleeping) + * IPNS + * Improve IPNS resolution performance. (@whyrusleeping) + * Have dnslink prefer `TXT _dnslink.example.com`, allows usage of CNAME records. (@Kubuxu) + * Prevent `ipfs name publish` when `/ipns` is mounted. (@noffle) + * Repo + * Improve performance of `ipfs add`. (@whyrusleeping) + * Add `Datastore.NoSync` config option for flatfs. (@rht) + * Implement mark-and-sweep GC. (@whyrusleeping) + * Allow for GC during `ipfs add`. (@whyrusleeping) + * Add `ipfs repo stat` command. (@tmg, @diasdavid) + * General + * Add support for HTTP OPTIONS requests. (@lidel) + * Add `ipfs diag cmds` to view active API requests (@whyrusleeping) + * Add an `IPFS_LOW_MEM` environment variable which relaxes Bitswap's memory usage. (@whyrusleeping) + * The Docker image now lives at `ipfs/go-ipfs` and has been completely reworked. (@lgierth) +* Security fixes + * The gateway path prefix added in v0.3.10 was vulnerable to cross-site + scripting attacks. This release introduces a configurable list of allowed + path prefixes. It's called `Gateway.PathPrefixes` and takes a list of + strings, e.g. `["/blog", "/foo/bar"]`. The v0.3.x line will not receive any + further updates, so please update to v0.4.0 as soon as possible. (@lgierth) +* Incompatible Changes + * Install using `make install` instead of `go get` (@whyrusleeping) + * Rewrite pinning to store pins in IPFS objects. (@tv42) + * Bump fs-repo version to 3. (@whyrusleeping) + * Use multistream muxer (@whyrusleeping) + * The default for `--type` in `ipfs pin ls` is now `all`. (@chriscool) +* Bug Fixes + * Remove msgio double wrap. (@jbenet) + * Buffer msgio. (@whyrusleeping) + * Perform various fixes to the FUSE code. (@tv42) + * Compute `ipfs add` size in background to not stall add operation. (@whyrusleeping) + * Add option to have `ipfs add` include top-level hidden files. (@noffle) + * Fix CORS checks on the API. (@rht) + * Fix `ipfs update` error message. (@tomgg) + * Resolve paths in `ipfs pin rm` without network lookup. (@noffle) + * Detect FUSE unmounts and track mount state. (@noffle) + * Fix go1.6rc2 panic caused by CloseNotify being called from wrong goroutine. (@rwcarlsen) + * Bump DHT kvalue from 10 to 20. (@whyrusleeping) + * Put public key and IPNS entry to DHT in parallel. (@whyrusleeping) + * Fix panic in CLI argument parsing. (@whyrusleeping) + * Fix range error by using larger-than-zero-length buffer. (@noffle) + * Fix yamux hanging issue by increasing AcceptBacklog. (@whyrusleeping) + * Fix double Transport-Encoding header bug. (@whyrusleeping) + * Fix uTP panic and file descriptor leak. (@whyrusleeping) +* Tool Changes + * Add `--pin` option to `ipfs add`, which defaults to `true` and allows `--pin=false`. (@eminence) + * Add arguments to `ipfs pin ls`. (@chriscool) + * Add `dns` and `resolve` commands to read-only API. (@Kubuxu) + * Add option to display headers for `ipfs object links`. (@palkeo) +* General Codebase Changes + * Check Golang version in Makefile. (@chriscool) + * Improve Makefile. (@tomgg) + * Remove dead Jenkins CI code. (@lgierth) + * Add locking interface to blockstore. (@whyrusleeping) + * Add Merkledag FetchGraph and EnumerateChildren. (@whyrusleeping) + * Rename Lock/RLock to GCLock/PinLock. (@jbenet) + * Implement pluggable datastore types. (@tv42) + * Record datastore metrics for non-default datastores. (@tv42) + * Allow multistream to have zero-rtt stream opening. (@whyrusleeping) + * Refactor `ipnsfs` into a more generic and well tested `mfs`. (@whyrusleeping) + * Grab more peers if bucket doesn't contain enough. (@whyrusleeping) + * Use CloseNotify in gateway. (@whyrusleeping) + * Flatten multipart file transfers. (@whyrusleeping) + * Send updated DHT record fixes to peers who sent outdated records. (@whyrusleeping) + * Replace go-psutil with go-sysinfo. (@whyrusleeping) + * Use ServeContent for index.html. (@AtnNn) + * Refactor `object patch` API to not store data in URL. (@whyrusleeping) + * Use mfs for `ipfs add`. (@whyrusleeping) + * Add `Server` header to API responses. (@Kubuxu) + * Wire context directly into HTTP requests. (@rht) + * Wire context directly into GetDAG operations within GC. (@rht) + * Vendor libp2p using gx. (@whyrusleeping) + * Use gx vendored packages instead of Godeps. (@whyrusleeping) + * Simplify merkledag package interface to ease IPLD inclusion. (@mildred) + * Add default option value support to commands lib. (@whyrusleeping) + * Refactor merkledag fetching methods. (@whyrusleeping) + * Use net/url to escape paths within Web UI. (@noffle) + * Deprecated key.Pretty(). (@MichealMure) +* Documentation + * Fix and update help text for **every** `ipfs` command. (@RichardLitt) + * Change sample API origin settings from wildcard (`*`) to `example.com`. (@Kubuxu) + * Improve documentation of installation process in README. (@whyrusleeping) + * Improve windows.md. (@chriscool) + * Clarify instructions for installing from source. (@noffle) + * Make version checking more robust. (@jedahan) + * Assert the source code is located within GOPATH. (@whyrusleeping) + * Remove mentions of `/dns` from `ipfs dns` command docs. (@lgierth) +* Testing + * Refactor iptb tests. (@chriscool) + * Improve t0240 sharness test. (@chriscool) + * Make bitswap tests less flaky. (@whyrusleeping) + * Use TCP port zero for ipfs daemon in sharness tests. (@whyrusleeping) + * Improve sharness tests on AppVeyor. (@chriscool) + * Add a pause to fix timing on t0065. (@whyrusleeping) + * Add support for arbitrary TCP ports to t0060-daemon.sh. (@noffle) + * Make t0060 sharness test use TCP port zero. (@whyrusleeping) + * Randomized ipfs stress testing via randor (@dignifiedquire) + * Stress test pinning and migrations (@whyrusleeping) + +### 0.3.11 - 2016-01-12 + +This is the final ipfs version before the transition to v0.4.0. +It introduces a few stability improvements, bugfixes, and increased +test coverage. + +* Features + * Add 'get' and 'patch' to the allowed gateway commands (@whyrusleeping) + * Updated webui version (@dignifiedquire) + +* BugFixes + * Fix path parsing for add command (@djdv) + * namesys: Make paths with multiple segments work. Fixes #2059 (@Kubuxu) + * Fix up panic catching in http handler funcs (@whyrusleeping) + * Add correct access control headers to the default api config (@dignifiedquire) + * Fix closenotify by not sending empty file set (@whyrusleeping) + +* Tool Changes + * Have install.sh use the full path to ipfs binary if detected (@jedahan) + * Install daemon system-wide if on El Capitan (@jedahan) + * makefile: add -ldflags to install and nofuse tasks (@lgierth) + +* General Codebase + * Clean up http client code (@whyrusleeping) + * Move api version check to header (@rht) + +* Documentation + * Improved release checklist (@jbenet) + * Added quotes around command in long description (@RichardLitt) + * Added a shutdown note to daemon description (@RichardLitt) + +* Testing + * t0080: improve last tests (@chriscool) + * t0080: improve 'ipfs refs --unique' test (@chriscool) + * Fix t.Fatal usage in goroutines (@chriscool) + * Add docker testing support to sharness (@chriscool) + * sharness: add t0300-docker-image.sh (@chriscool) + * Included more namesys tests. (@Kubuxu) + * Add sharness test to verify requests look good (@whyrusleeping) + * Re-enable ipns sharness test now that iptb is fixed (@whyrusleeping) + * Force use of ipv4 in test (@whyrusleeping) + * Travis-CI: use go 1.5.2 (@jbenet) + +### 0.3.10 - 2015-12-07 + +This patch update introduces the 'ipfs update' command which will be used for +future ipfs updates along with a few other bugfixes and documentation +improvements. + + +* Features + * support for 'ipfs update' to call external binary (@whyrusleeping) + * cache ipns entries to speed things up a little (@whyrusleeping) + * add option to version command to print repo version (@whyrusleeping) + * Add in some more notifications to help profile queries (@whyrusleeping) + * gateway: add path prefix for directory listings (@lgierth) + * gateway: add CurrentCommit to /version (@lgierth) + +* BugFixes + * set data and links nil if not present (@whyrusleeping) + * fix log hanging issue, and implement close-notify for commands (@whyrusleeping) + * fix dial backoff (@whyrusleeping) + * proper ndjson implementation (@whyrusleeping) + * seccat: fix secio context (@lgierth) + * Add newline to end of the output for a few commands. (@nham) + * Add fixed period repo GC + test (@rht) + +* Tool Changes + * Allow `ipfs cat` on ipns path (@rht) + +* General Codebase + * rewrite of backoff mechanism (@whyrusleeping) + * refactor net code to use transports, in rough accordance with libp2p (@whyrusleeping) + * disable building fuse stuff on windows (@whyrusleeping) + * repo: remove Log config (@lgierth) + * commands: fix description of --api (@lgierth) + +* Documentation + * --help: Add a note on using IPFS_PATH to the footer of the helptext. (@sahib) + * Moved email juan to ipfs/contribute (@richardlitt) + * Added commit sign off section (@richardlitt) + * Added a security section (@richardlitt) + * Moved TODO doc to issue #1929 (@richardlitt) + +* Testing + * gateway: add tests for /version (@lgierth) + * Add gc auto test (@rht) + * t0020: cleanup dir with bad perms (@chriscool) + +Note: this commit introduces fixed-period repo gc, which will trigger gc +after a fixed period of time. This feature is introduced now, disabled by +default, and can be enabled with `ipfs daemon --enable-gc`. If all goes well, +in the future, it will be enabled by default. + +### 0.3.9 - 2015-10-30 + +This patch update includes a good number of bugfixes, notably, it fixes +builds on windows, and puts newlines between streaming json objects for a +proper ndjson format. + +* Features + * Writable gateway enabled again (@cryptix) + +* Bugfixes + * fix windows builds (@whyrusleeping) + * content type on command responses default to text (@whyrusleeping) + * add check to makefile to ensure windows builds don't fail silently (@whyrusleeping) + * put newlines between streaming json output objects (@whyrusleeping) + * fix streaming output to flush per write (@whyrusleeping) + * purposely fail builds pre go1.5 (@whyrusleeping) + * fix ipfs id (@whyrusleeping) + * fix a few race conditions in mocknet (@whyrusleeping) + * fix makefile failing when not in a git repo (@whyrusleeping) + * fix cli flag orders (long, short) (@rht) + * fix races in http cors (@miolini) + * small webui update (some bugfixes) (@jbenet) + +* Tool Changes + * make swarm connect return an error when it fails (@whyrusleeping) + * Add short flag for `ipfs ls --headers` (v for verbose) (@rht) + +* General Codebase + * bitswap: clean log printf and humanize dup data count (@cryptix) + * config: update pluto's peerID (@lgierth) + * config: update bootstrap list hostname (@lgierth) + +* Documentation + * Pared down contribute to link to new go guidelines (@richardlitt) + +* Testing + * t0010: add tests for 'ipfs commands --flags' (@chriscool) + * ipns_test: fix namesys.NewNameSystem() call (@chriscool) + * t0060: fail if no nc (@chriscool) + +### 0.3.8 - 2015-10-09 + +This patch update includes changes to make ipns more consistent and reliable, +symlink support in unixfs, mild performance improvements, new tooling features, +a plethora of bugfixes, and greatly improved tests. + +NOTICE: Version 0.3.8 also requires golang version 1.5.1 or higher. + +* Bugfixes + * refactor ipns to be more consistent and reliable (@whyrusleeping) + * fix 'ipfs refs' json output (@whyrusleeping) + * fix setting null config maps (@rht) + * fix output of dht commands (@whyrusleeping) + * fix NAT spam dialing (@whyrusleeping) + * fix random panics on 32 bit systems (@whyrusleeping) + * limit total number of network fd's (@whyrusleeping) + * fix http api content type (@WeMeetAgain) + * fix writing of api file for port zero daemons (@whyrusleeping) + * windows connection refused fixes (@mjanczyk) + * use go1.5's built in trailers, no more failures (@whyrusleeping) + * fix random bitswap hangs (@whyrusleeping) + * rate limit fd usage (@whyrusleeping) + * fix panic in bitswap ratelimiting (@whyrusleeping) + +* Tool Changes + * --empty-repo option for init (@prusnak) + * implement symlinks (@whyrusleeping) + * improve cmds lib files processing (@rht) + * properly return errors through commands (@whyrusleeping) + * bitswap unwant command (@whyrusleeping) + * tar add/cat commands (@whyrusleeping) + * fix gzip compression in get (@klauspost) + * bitswap stat logs wasted bytes (@whyrusleeping) + * resolve command now uses core.Resolve (@rht) + * add `--local` flag to 'name resolve' (@whyrusleeping) + * add `ipfs diag sys` command for debugging help (@whyrusleeping) + +* General Codebase + * improvements to dag editor (@whyrusleeping) + * swarm IPv6 in default config (Baptiste Jonglez) + * improve dir listing css (@rht) + * removed elliptic.P224 usage (@prusnak) + * improve bitswap providing speed (@jbenet) + * print panics that occur in cmds lib (@whyrusleeping) + * ipfs api check test fixes (@rht) + * update peerstream and datastore (@whyrusleeping) + * cleaned up tar-reader code (@jbenet) + * write context into coreunix.Cat (@rht) + * move assets to separate repo (@rht) + * fix proc/ctx wiring in bitswap (@jbenet) + * rabin fingerprinting chunker (@whyrusleeping) + * better notification on daemon ready (@rht) + * coreunix cat cleanup (@rht) + * extract logging into go-log (@whyrusleeping) + * blockservice.New no longer errors (@whyrusleeping) + * refactor ipfs get (@rht) + * readonly api on gateway (@rht) + * cleanup context usage all over (@rht) + * add xml decoding to 'object put' (@ForrestWeston) + * replace nodebuilder with NewNode method (@whyrusleeping) + * add metrics to http handlers (@lgierth) + * rm blockservice workers (@whyrusleeping) + * decompose maybeGzWriter (@rht) + * makefile sets git commit sha on build (@CaioAlonso) + +* Documentation + * add contribute file (@RichardLitt) + * add go devel guide to contribute.md (@whyrusleeping) + +* Testing + * fix mock notifs test (@whyrusleeping) + * test utf8 with object cmd (@chriscool) + * make mocknet conn close idempotent (@jbenet) + * fix fuse tests (@pnelson) + * improve sharness test quoting (@chriscool) + * sharness tests for chunker and add-cat (@rht) + * generalize peerid check in sharness (@chriscool) + * test_cmp argument cleanup (@chriscool) + +### 0.3.7 - 2015-08-02 + +This patch update fixes a problem we introduced in 0.3.6 and did not +catch: the webui failed to work with out-of-the-box CORS configs. +This has been fixed and now should work correctly. @jbenet + +### 0.3.6 - 2015-07-30 + +This patch improves the resource consumption of go-ipfs, +introduces a few new options on the CLI, and also +fixes (yet again) windows builds. + +* Resource consumption: + * fixed goprocess memory leak @rht + * implement batching on datastore @whyrusleeping + * Fix bitswap memory leak @whyrusleeping + * let bitswap ignore temporary write errors @whyrusleeping + * remove logging to disk in favor of api endpoint @whyrusleeping + * --only-hash option for add to skip writing to disk @whyrusleeping + +* Tool changes + * improved `ipfs daemon` output with all addresses @jbenet + * improved `ipfs id -f` output, added `` and `\n \t` support @jbenet + * `ipfs swarm addrs local` now shows the local node's addrs @jbenet + * improved config json parsing @rht + * improved Dockerfile to use alpine linux @Luzifer @lgierth + * improved bash completion @MichaelMure + * Improved 404 for gateway @cryptix + * add unixfs ls to list correct filesizes @wking + * ignore hidden files by default @gatesvp + * global --timeout flag @whyrusleeping + * fix random API failures by closing resp bodies @whyrusleeping + * ipfs swarm filters @whyrusleeping + * api returns errors in http trailers @whyrusleeping @jbenet + * `ipfs patch` learned to create intermediate nodes @whyrusleeping + * `ipfs object stat` now shows Hash @whyrusleeping + * `ipfs cat` now clears progressbar on exit @rht + * `ipfs add -w -r ` now wraps directories @jbenet + * `ipfs add -w ` now wraps with one dir @jbenet + * API + Gateway now support arbitrary HTTP Headers from config @jbenet + * API now supports CORS properly from config @jbenet + * **Deprecated:** `API_ORIGIN` env var (use config, see `ipfs daemon --help`) @jbenet + +* General Codebase + * `nofuse` tag for windows @Luzifer + * improved `ipfs add` code @gatesvp + * started requiring license trailers @chriscool @jbenet + * removed CtxCloser for goprocess @rht + * remove deadcode @lgierth @whyrusleeping + * reduced number of logging libs to 2 (soon to be 1) @rht + * dial address filtering @whyrusleeping + * prometheus metrics @lgierth + * new index page for gateway @krl @cryptix + * move ping to separate protocol @whyrusleeping + * add events to bitswap for a dashboard @whyrusleeping + * add latency and bandwidth options to mocknet @heems + * levenshtein distance cmd autosuggest @sbruce + * refactor/cleanup of cmds http handler @whyrusleeping + * cmds http stream reports errors in trailers @whyrusleeping + +* Bugfixes + * fixed path resolution and validation @rht + * fixed `ipfs get -C` output and progress bar @rht + * Fixed install pkg dist bug @jbenet @Luzifer + * Fix `ipfs get` silent failure @whyrusleeping + * `ipfs get` tarx no longer times out @jbenet + * `ipfs refs -r -u` is now correct @gatesvp + * Fix `ipfs add -w -r ` wrapping bugs @jbenet + * Fixed FUSE unmount failures @jbenet + * Fixed `ipfs log tail` command (api + cli) @whyrusleeping + +* Testing + * sharness updates @chriscool + * ability to disable secio for testing @jbenet + * fixed many random test failures, more reliable CI @whyrusleeping + * Fixed racey notifier failures @whyrusleeping + * `ipfs refs -r -u` test cases @jbenet + * Fix failing pinning test @jbenet + * Better CORS + Referer tests @jbenet + * Added reversible gc test @rht + * Fixed bugs in FUSE IPNS tests @whyrusleeping + * Fixed bugs in FUSE IPFS tests @jbenet + * Added `random-files` tool for easier sharness tests @jbenet + +* Documentation + * Add link to init system examples @slang800 + * Add CORS documentation to daemon init @carver (Note: this will change soon) + +### 0.3.5 - 2015-06-11 + +This patch improves overall stability and performance + +* added 'object patch' and 'object new' commands @whyrusleeping +* improved symmetric NAT avoidance @jbenet +* move util.Key to blocks.Key @whyrusleeping +* fix memory leak in provider store @whyrusleeping +* updated webui to 0.2.0 @krl +* improved bitswap performance @whyrusleeping +* update fuse lib @cryptix +* fix path resolution @wking +* implement test_seq() in sharness @chriscool +* improve parsing of stdin for commands @chriscool +* fix 'ipfs refs' failing silently @whyrusleeping +* fix serial dialing bug @jbenet +* improved testing @chriscool @rht @jbenet +* fixed domain resolving @luzifer +* fix parsing of unwanted stdin @lgierth +* added CORS handlers to gateway @NodeGuy +* added `ipfs daemon --unrestricted-api` option @krl +* general cleanup of dependencies + +### 0.3.4 - 2015-05-10 + +* fix ipns append bug @whyrusleeping +* fix out of memory panic @whyrusleeping +* add in expvar metrics @tv42 +* bitswap improvements @whyrusleeping +* fix write-cache in blockstore @tv42 +* vendoring cleanup @cryptix +* added `launchctl` plist for OSX @grncdr +* improved Dockerfile, changed root and mount paths @ehd +* improved `pin ls` output to show types @vitorbaptista + +### 0.3.3 - 2015-04-28 + +This patch update fixes various issues, in particular: +- windows support (0.3.0 had broken it) +- commandline parses spaces correctly. + +* much improved commandline parsing by @AtnNn +* improved dockerfile by @luzifer +* add cmd cleanup by @wking +* fix flatfs windows support by @tv42 and @gatesvp +* test case improvements by @chriscool +* ipns resolution timeout bug fix by @whyrusleeping +* new cluster tests with iptb by @whyrusleeping +* fix log callstack printing bug by @whyrusleeping +* document bash completion by @dylanPowers + +### 0.3.2 - 2015-04-22 + +This patch update implements multicast dns as well as fxing a few test issues. + +* implement mdns peer discovery @whyrusleeping +* fix mounting issues in sharness tests @chriscool + +### 0.3.1 - 2015-04-21 + +This patch update fixes a few bugs: + +* harden shutdown logic by @torarnv +* daemon locking fixes by @travisperson +* don't re-add entire dirs by @whyrusleeping +* tests now wait for graceful shutdown by @jbenet +* default key size is now 2048 by @jbenet + +### 0.3.0 - 2015-04-20 + +We've just released version 0.3.0, which contains many +performance improvements, bugfixes, and new features. +Perhaps the most noticeable change is moving block storage +from leveldb to flat files in the filesystem. + +What to expect: + +* _much faster_ performance + +* Repo format 2 + * moved default location from ~/.go-ipfs -> ~/.ipfs + * renamed lock filename daemon.lock -> repo.lock + * now using a flat-file datastore for local blocks + +* Fixed lots of bugs + * proper ipfs-path in various commands + * fixed two pinning bugs (recursive pins) + * increased yamux streams window (for speed) + * increased bitswap workers (+ env var) + * fixed memory leaks + * ipfs add error returns + * daemon exit bugfix + * set proper UID and GID on fuse mounts + +* Gateway + * Added support for HEAD requests + +* configuration + * env var to turn off SO_REUSEPORT: IPFS_REUSEPORT=false + * env var to increase bitswap workers: IPFS_BITSWAP_TASK_WORKERS=n + +* other + * bash completion is now available + * ipfs stats bw -- bandwidth meetering + +And many more things. + +### 0.2.3 - 2015-03-01 + +* Alpha Release + +### 2015-01-31: + +* bootstrap addresses now have .../ipfs/... in format + config file Bootstrap field changed accordingly. users + can upgrade cleanly with: + + ipfs bootstrap >boostrap_peers + ipfs bootstrap rm --all + + + ipfs bootstrap add + +ENV SRC_DIR /go-ipfs + +# Download packages first so they can be cached. +COPY go.mod go.sum $SRC_DIR/ +RUN cd $SRC_DIR \ + && go mod download + +COPY . $SRC_DIR + +# Build the thing. +# Also: fix getting HEAD commit hash via git rev-parse. +RUN cd $SRC_DIR \ + && mkdir .git/objects \ + && make build + +# Get su-exec, a very minimal tool for dropping privileges, +# and tini, a very minimal init daemon for containers +ENV SUEXEC_VERSION v0.2 +ENV TINI_VERSION v0.16.1 +RUN set -x \ + && cd /tmp \ + && git clone https://github.com/ncopa/su-exec.git \ + && cd su-exec \ + && git checkout -q $SUEXEC_VERSION \ + && make \ + && cd /tmp \ + && wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini \ + && chmod +x tini + +# Get the TLS CA certificates, they're not provided by busybox. +RUN apt-get update && apt-get install -y ca-certificates + +# Install FUSE +RUN apt-get update && apt-get install -y fuse + +# Now comes the actual target image, which aims to be as small as possible. +FROM busybox:1-glibc +MAINTAINER Lars Gierth + +# Get the ipfs binary, entrypoint script, and TLS CAs from the build container. +ENV SRC_DIR /go-ipfs +COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs +COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs +COPY --from=0 /tmp/su-exec/su-exec /sbin/su-exec +COPY --from=0 /tmp/tini /sbin/tini +COPY --from=0 /bin/fusermount /usr/local/bin/fusermount +COPY --from=0 /etc/ssl/certs /etc/ssl/certs + +# Add suid bit on fusermount so it will run properly +RUN chmod 4755 /usr/local/bin/fusermount + +# This shared lib (part of glibc) doesn't seem to be included with busybox. +COPY --from=0 /lib/x86_64-linux-gnu/libdl-2.24.so /lib/libdl.so.2 + +# Swarm TCP; should be exposed to the public +EXPOSE 4001 +# Daemon API; must not be exposed publicly but to client services under you control +EXPOSE 5001 +# Web Gateway; can be exposed publicly with a proxy, e.g. as https://ipfs.example.org +EXPOSE 8080 +# Swarm Websockets; must be exposed publicly when the node is listening using the websocket transport (/ipX/.../tcp/8081/ws). +EXPOSE 8081 + +# Create the fs-repo directory and switch to a non-privileged user. +ENV IPFS_PATH /data/ipfs +RUN mkdir -p $IPFS_PATH \ + && adduser -D -h $IPFS_PATH -u 1000 -G users ipfs \ + && chown ipfs:users $IPFS_PATH + +# Create mount points for `ipfs mount` command +RUN mkdir /ipfs /ipns \ + && chown ipfs:users /ipfs /ipns + +# Expose the fs-repo as a volume. +# start_ipfs initializes an fs-repo if none is mounted. +# Important this happens after the USER directive so permission are correct. +VOLUME $IPFS_PATH + +# The default logging level +ENV IPFS_LOGGING "" + +# This just makes sure that: +# 1. There's an fs-repo, and initializes one if there isn't. +# 2. The API and Gateway are accessible from outside the container. +ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"] + +# Execute the daemon subcommand by default +CMD ["daemon", "--migrate=true"] diff --git a/vendor/github.com/ipfs/go-ipfs/Gopkg.lock b/vendor/github.com/ipfs/go-ipfs/Gopkg.lock new file mode 100644 index 00000000..37044d34 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/Gopkg.lock @@ -0,0 +1,2642 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + digest = "1:2fab77e19256b26d733b70e1f68cd965cb87e38e3a619fa960cf319aef743d53" + name = "bazil.org/fuse" + packages = [ + ".", + "fs", + "fs/fstestutil", + "fuseutil", + ] + pruneopts = "UT" + revision = "65cc252bf6691cb3c7014bcb2c8dc29de91e3a7e" + +[[projects]] + branch = "master" + digest = "1:6716c9fe6333591128e72848f246fc01dc72240e1e64185d8b4e124e7280b35d" + name = "github.com/AndreasBriese/bbloom" + packages = ["."] + pruneopts = "UT" + revision = "e2d15f34fcf99d5dbb871c820ec73f710fca9815" + +[[projects]] + digest = "1:9f3b30d9f8e0d7040f729b82dcbc8f0dead820a133b3147ce355fc451f32d761" + name = "github.com/BurntSushi/toml" + packages = ["."] + pruneopts = "UT" + revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005" + version = "v0.3.1" + +[[projects]] + digest = "1:4a7be34ac4d3c56c039ece7d674236bde2d95f6adc93262cbb21d5b758566b15" + name = "github.com/Kubuxu/go-os-helper" + packages = ["."] + pruneopts = "UT" + revision = "3d3fc2fb493d8d889dddd5a4524283ac2faa4732" + version = "v0.0.1" + +[[projects]] + branch = "master" + digest = "1:c42df949106ee61667006128ed30161bea596cb773a94543bd2d8eec2f88fee5" + name = "github.com/Kubuxu/gocovmerge" + packages = ["."] + pruneopts = "UT" + revision = "7ecaa51963cdbbd985d4d0d8266fda9fab6680ca" + +[[projects]] + branch = "master" + digest = "1:166dc6852cbd78ca17b96e76b18f65853adf97989fcb14a0743f3aa6123f546b" + name = "github.com/OpenPeeDeeP/depguard" + packages = ["."] + pruneopts = "UT" + revision = "1f388ab2d81096755d25043aa729e2fb889f3dae" + +[[projects]] + digest = "1:bf67b338b8ad10f12e81c2f151d0be3246373c96681d06ba1312afe02d4e7fa4" + name = "github.com/Stebalien/go-bitfield" + packages = ["."] + pruneopts = "UT" + revision = "a911218965d225c9b5b8ba5e1a8ea539651ca036" + version = "v0.0.1" + +[[projects]] + digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" + name = "github.com/beorn7/perks" + packages = ["quantile"] + pruneopts = "UT" + revision = "4b2b341e8d7715fae06375aa633dbb6e91b3fb46" + version = "v1.0.0" + +[[projects]] + digest = "1:b6d886569181ec96ca83d529f4d6ba0cbf92ace7bb6f633f90c5f34d9bba7aab" + name = "github.com/blang/semver" + packages = ["."] + pruneopts = "UT" + revision = "ba2c2ddd89069b46a7011d4106f6868f17ee1705" + version = "v3.6.1" + +[[projects]] + branch = "master" + digest = "1:02796fed67c64543bfe3343b26cdc9a221bca2d83e8c7dcf35b5b70f6b5b9c56" + name = "github.com/bren2010/proquint" + packages = ["."] + pruneopts = "UT" + revision = "38337c27106d8f06e9b5cddc6df973ceece1c8ea" + +[[projects]] + branch = "master" + digest = "1:9e7c5138114ff9c51a60731b3a425c319305013c6ea8b3f60fd2435baba1a0db" + name = "github.com/btcsuite/btcd" + packages = ["btcec"] + pruneopts = "UT" + revision = "a0d1e3e36d50f61ee6eaab26d7bd246aae1f9ece" + +[[projects]] + digest = "1:c1100fc71e23b6a32b2c68a5202a848fd13811d5a10b12edb8019c3667d1cd9a" + name = "github.com/cenkalti/backoff" + packages = ["."] + pruneopts = "UT" + revision = "4b4cebaf850ec58f1bb1fec5bdebdf8501c2bc3f" + version = "v3.0.0" + +[[projects]] + digest = "1:f438d91be142877c3ad83157992c91de787ddfbddcc2a7da1ef6ef61606cadc4" + name = "github.com/cheekybits/genny" + packages = ["generic"] + pruneopts = "UT" + revision = "d2cf3cdd35ce0d789056c4bc02a4d6349c947caf" + version = "v1.0.0" + +[[projects]] + digest = "1:05ffeeed3f0f05520de0679f6aa3219ffee69cfd6d9fb6c194879d4c818ad670" + name = "github.com/coreos/go-semver" + packages = ["semver"] + pruneopts = "UT" + revision = "e214231b295a8ea9479f11b70b35d5acf3556d9b" + version = "v0.3.0" + +[[projects]] + digest = "1:5bdd0581421e643e6c3163bb5da785600a2d7d0d73fec58acebaf2e693868e9d" + name = "github.com/cskr/pubsub" + packages = ["."] + pruneopts = "UT" + revision = "65166f5ae403cbf6dcdced31e1f8f8ad95485cb3" + version = "v1.0.2" + +[[projects]] + branch = "master" + digest = "1:ff0db56095c10bcdbf92ce2503f1d0d6e2ee0615184cfb96db2907fcb08d454e" + name = "github.com/davidlazar/go-crypto" + packages = ["salsa20"] + pruneopts = "UT" + revision = "62389b5e4ae0188549f6bb2f4877e7a22a1c420d" + +[[projects]] + digest = "1:98436a9785f711ffee66f06265296dd36afd6e3dc532410c98a9051b5fd4c2f1" + name = "github.com/dgraph-io/badger" + packages = [ + ".", + "options", + "pb", + "skl", + "table", + "y", + ] + pruneopts = "UT" + revision = "0ce1d2e26af1ba8b8a72ea864145a3e1e3b382cd" + +[[projects]] + branch = "master" + digest = "1:6e8109ce247a59ab1eeb5330166c12735f6590de99c9647b6162d11518d32c9a" + name = "github.com/dgryski/go-farm" + packages = ["."] + pruneopts = "UT" + revision = "6a90982ecee230ff6cba02d5bd386acc030be9d3" + +[[projects]] + digest = "1:6f9339c912bbdda81302633ad7e99a28dfa5a639c864061f1929510a9a64aa74" + name = "github.com/dustin/go-humanize" + packages = ["."] + pruneopts = "UT" + revision = "9f541cc9db5d55bce703bd99987c9d5cb8eea45e" + version = "v1.0.0" + +[[projects]] + branch = "master" + digest = "1:fffcae02150ef80950d18c721eaa249e6e80df5e0b9b645731949e586573f685" + name = "github.com/elgris/jsondiff" + packages = ["."] + pruneopts = "UT" + revision = "765b5c24c302e7c7fd032fdb8c69f101918229cb" + +[[projects]] + branch = "master" + digest = "1:c183111eaf02a9e6bb39c213bdfb5472b16f1955dd4c9dab82db83f114c64a63" + name = "github.com/facebookgo/atomicfile" + packages = ["."] + pruneopts = "UT" + revision = "2de1f203e7d5e386a6833233882782932729f27e" + +[[projects]] + digest = "1:938a2672d6ebbb7f7bc63eee3e4b9464c16ffcf77ec8913d3edbf32b4e3984dd" + name = "github.com/fatih/color" + packages = ["."] + pruneopts = "UT" + revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" + version = "v1.5.0" + +[[projects]] + digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" + name = "github.com/fsnotify/fsnotify" + packages = ["."] + pruneopts = "UT" + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" + +[[projects]] + digest = "1:b57b6448d97d626ca173056800c194c7cc7f1f6f6590eafd18fe86dfb434f080" + name = "github.com/go-critic/go-critic" + packages = [ + "checkers", + "checkers/internal/lintutil", + ] + pruneopts = "UT" + revision = "d7b3038bc7a1c35a1d02fdd7cf4094f0f1a12001" + version = "v0.3.4" + +[[projects]] + digest = "1:f12f53369294649f9d5046d1e8a40187ad36584201a9e1a135bf44589df1deb8" + name = "github.com/go-lintpack/lintpack" + packages = [ + ".", + "astwalk", + ] + pruneopts = "UT" + revision = "80adc0715ac409128d0b7212719896ad8d3444b7" + version = "v0.5.2" + +[[projects]] + digest = "1:b9a8d81ce273b216a3ad70ff95d98179ec2f5392523a9a305b3e38c70ca9d361" + name = "github.com/go-toolsmith/astcast" + packages = ["."] + pruneopts = "UT" + revision = "a6cb19f07b66b859a53f3f2be6e4c3bba892db7e" + version = "v1.0.0" + +[[projects]] + digest = "1:bd091673b35859ad8f831a5b3c961805e108be72d0778b9d07fd383e59ab4287" + name = "github.com/go-toolsmith/astcopy" + packages = ["."] + pruneopts = "UT" + revision = "245af3020944a15e09072c8ad3883c1451d1fdef" + version = "v1.0.0" + +[[projects]] + digest = "1:db8123e0896cf805cb30c7bacad0b1a1d562edbbcd2a765ceda1af926c9a99a4" + name = "github.com/go-toolsmith/astequal" + packages = ["."] + pruneopts = "UT" + revision = "dcb477bfacd6e00a13c6d63bfc73db28dd343160" + version = "v1.0.0" + +[[projects]] + digest = "1:1ef70bd4e2d06e76470c3cb43b89020201dcb0b4a409d9a961df77cfaf5ae3a8" + name = "github.com/go-toolsmith/astfmt" + packages = ["."] + pruneopts = "UT" + revision = "0d74c731079884bda287cf8df9ce7b92e688af8c" + version = "v1.0.0" + +[[projects]] + digest = "1:f2def520d33d9ba100161b0d2101f98b2104e62bafd3e45ae5deca271ac84000" + name = "github.com/go-toolsmith/astp" + packages = ["."] + pruneopts = "UT" + revision = "6373270dee65bfb0479f2acd16d4c8e9d5db13f8" + version = "v1.0.0" + +[[projects]] + digest = "1:aba9fa7c6dacad505e95d984ec0b07f6b5a4691ed2f4ff36c7b732b3704627a3" + name = "github.com/go-toolsmith/strparse" + packages = ["."] + pruneopts = "UT" + revision = "830b6daa1241714c12a9b9a4a56849fe2f93aedc" + version = "v1.0.0" + +[[projects]] + digest = "1:a51f9845b0dec6e372e229395e019cab7c032711c6ca3ec1895a58bfdf760962" + name = "github.com/go-toolsmith/typep" + packages = ["."] + pruneopts = "UT" + revision = "cab1745ffd84a567b524317c7f90e96755b18fcf" + version = "v1.0.0" + +[[projects]] + digest = "1:9ae31ce33b4bab257668963e844d98765b44160be4ee98cafc44637a213e530d" + name = "github.com/gobwas/glob" + packages = [ + ".", + "compiler", + "match", + "syntax", + "syntax/ast", + "syntax/lexer", + "util/runes", + "util/strings", + ] + pruneopts = "UT" + revision = "5ccd90ef52e1e632236f7326478d4faa74f99438" + version = "v0.2.3" + +[[projects]] + digest = "1:d0e00c8ccabdfe678667d6be78c9d08a6a4efc36d9fb596f098706728b00ba6b" + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "io", + "proto", + "protoc-gen-gogo/descriptor", + ] + pruneopts = "UT" + revision = "ba06b47c162d49f2af050fb4c75bcbc86a159d5c" + version = "v1.2.1" + +[[projects]] + digest = "1:be408f349cae090a7c17a279633d6e62b00068e64af66a582cae0983de8890ea" + name = "github.com/golang/mock" + packages = ["gomock"] + pruneopts = "UT" + revision = "9fa652df1129bef0e734c9cf9bf6dbae9ef3b9fa" + version = "1.3.1" + +[[projects]] + digest = "1:318f1c959a8a740366fce4b1e1eb2fd914036b4af58fbd0a003349b305f118ad" + name = "github.com/golang/protobuf" + packages = ["proto"] + pruneopts = "UT" + revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30" + version = "v1.3.1" + +[[projects]] + digest = "1:e4f5819333ac698d294fe04dbf640f84719658d5c7ce195b10060cc37292ce79" + name = "github.com/golang/snappy" + packages = ["."] + pruneopts = "UT" + revision = "2a8bb927dd31d8daada140a5d09578521ce5c36a" + version = "v0.0.1" + +[[projects]] + branch = "master" + digest = "1:c173565780edcf5d43c5f983be0e9085266764465422d4ad230355abd2e0d252" + name = "github.com/golangci/check" + packages = [ + "cmd/structcheck", + "cmd/varcheck", + ] + pruneopts = "UT" + revision = "cfe4005ccda277a820149d44d6ededc400cc99a2" + +[[projects]] + branch = "master" + digest = "1:efb8cf3f0c2f47844104d6e879fc77d846649df794e378cae50e749fad1bb1dc" + name = "github.com/golangci/dupl" + packages = [ + ".", + "job", + "printer", + "suffixtree", + "syntax", + "syntax/golang", + ] + pruneopts = "UT" + revision = "3e9179ac440a0386ac7cc9a085fc44397c6b9bbc" + +[[projects]] + branch = "master" + digest = "1:f1761ff12ebf63f70390733f5804434f9b323996816cb9cddbb7041279872bcb" + name = "github.com/golangci/errcheck" + packages = [ + "golangci", + "internal/errcheck", + ] + pruneopts = "UT" + revision = "ef45e06d44b6e018d817c16c762d448990adc5e0" + +[[projects]] + branch = "master" + digest = "1:f63d85b6e551b6c8aa3ed2e42b64db15f5b525bdb01fa36af18288f1de4c859b" + name = "github.com/golangci/go-misc" + packages = ["deadcode"] + pruneopts = "UT" + revision = "927a3d87b613e9f6f0fb7ef8bb8de8b83c30a5a2" + +[[projects]] + branch = "master" + digest = "1:cc3a79e8819804582643d37b0664f3fa501dd0b6be958ebe77677e2f69aaba95" + name = "github.com/golangci/go-tools" + packages = [ + "arg", + "callgraph", + "callgraph/static", + "config", + "deprecated", + "functions", + "internal/sharedcheck", + "lint", + "lint/lintdsl", + "lint/lintutil", + "lint/lintutil/format", + "simple", + "ssa", + "ssa/ssautil", + "ssautil", + "staticcheck", + "staticcheck/vrp", + "stylecheck", + "unused", + "version", + ] + pruneopts = "UT" + revision = "35a9f45a5db090b0227d692d823151104cd695fa" + +[[projects]] + branch = "master" + digest = "1:e1b9fbecb1d985f291dbca59767070fe899f38d1b40f7e9433f9a42b7fb3bd4e" + name = "github.com/golangci/goconst" + packages = ["."] + pruneopts = "UT" + revision = "041c5f2b40f3dd334a4a6ee6a3f84ca3fc70680a" + +[[projects]] + branch = "master" + digest = "1:431fd101ab780d1916262a582e241d01cbcbca10f7d85ebdd4ba339b8485483e" + name = "github.com/golangci/gocyclo" + packages = ["pkg/gocyclo"] + pruneopts = "UT" + revision = "0a533e8fa43d6605069e94f455bf9d79d4b8ea8c" + +[[projects]] + branch = "master" + digest = "1:66fcab6100e2be1bb31ae5494a0eb928690e2a4bf739d44eb2923ac7dd687e03" + name = "github.com/golangci/gofmt" + packages = [ + "gofmt", + "goimports", + ] + pruneopts = "UT" + revision = "0b8337e80d98f7eec18e4504a4557b34423fd039" + +[[projects]] + digest = "1:959d250b56bb86b3a6a6b8a4f97749c90a68187f2bbce59888de884117dce849" + name = "github.com/golangci/golangci-lint" + packages = [ + "cmd/golangci-lint", + "pkg/commands", + "pkg/config", + "pkg/exitcodes", + "pkg/fsutils", + "pkg/golinters", + "pkg/golinters/goanalysis", + "pkg/golinters/goanalysis/checker", + "pkg/golinters/goanalysis/passes/nilness", + "pkg/goutil", + "pkg/lint", + "pkg/lint/astcache", + "pkg/lint/linter", + "pkg/lint/lintersdb", + "pkg/logutils", + "pkg/packages", + "pkg/printers", + "pkg/report", + "pkg/result", + "pkg/result/processors", + "pkg/timeutils", + ] + pruneopts = "UT" + revision = "4ba2155996359eabd8800d1fbf3e3a9777c80490" + version = "v1.17.1" + +[[projects]] + branch = "master" + digest = "1:bf573d0637989470dee90e11a6ea87b5de1ddb7a435334b80656b0df05b0630b" + name = "github.com/golangci/gosec" + packages = [ + ".", + "rules", + ] + pruneopts = "UT" + revision = "8afd9cbb6cfb34a3b4d4d5711bafdc6640ae892f" + +[[projects]] + branch = "master" + digest = "1:3a5ea92f78579dfd319260ce995575c07890c8aff429035637287a00da664647" + name = "github.com/golangci/ineffassign" + packages = ["."] + pruneopts = "UT" + revision = "2ee8f2867dde308c46d401d6d30f6c644094b167" + +[[projects]] + branch = "master" + digest = "1:3919f284dcb91eca214603fb11ba9a9d5b020975b577b2c85c541ac3d40fa114" + name = "github.com/golangci/lint-1" + packages = ["."] + pruneopts = "UT" + revision = "d2cdd8c0821928c61cb0903441f8b35457a98a61" + +[[projects]] + branch = "master" + digest = "1:8665edfb3c5371fbac9820d127fa0d9aed813cc2349a27a7d16064dd89fed146" + name = "github.com/golangci/maligned" + packages = ["."] + pruneopts = "UT" + revision = "b1d89398deca2fd3f8578e5a9551e819bd01ca5f" + +[[projects]] + digest = "1:73dfedbcb6b348638ef0066766a9e7d8f6cfc5cfcb3a8e00ceb631a4bca73cf1" + name = "github.com/golangci/misspell" + packages = ["."] + pruneopts = "UT" + revision = "b90dc15cfd220ecf8bbc9043ecb928cef381f011" + version = "v0.3.4" + +[[projects]] + branch = "master" + digest = "1:6bc38b03a76ac4ce44482b437c6a31ec441e494abd271d63722f99ac2e7e9e80" + name = "github.com/golangci/prealloc" + packages = ["."] + pruneopts = "UT" + revision = "215b22d4de21190b80ce05e7d8466677c1aa3223" + +[[projects]] + branch = "master" + digest = "1:6bea17ec2cee4996145d70cffbee98330adc2bfc24107373953a250abca159ff" + name = "github.com/golangci/revgrep" + packages = ["."] + pruneopts = "UT" + revision = "276a5c0a103935ee65af49afc254a65335bf1fcf" + +[[projects]] + branch = "master" + digest = "1:c553e7c7483f2d6db1e84a27a18df144ed4041792d7556916369f86ccf5409fe" + name = "github.com/golangci/unconvert" + packages = ["."] + pruneopts = "UT" + revision = "28b1c447d1f4a810737ee6ab40ea6c1d0ceae4ad" + +[[projects]] + digest = "1:582b704bebaa06b48c29b0cec224a6058a09c86883aaddabde889cd1a5f73e1b" + name = "github.com/google/uuid" + packages = ["."] + pruneopts = "UT" + revision = "0cd6bf5da1e1c83f8b45653022c74f71af0538a4" + version = "v1.1.1" + +[[projects]] + digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d" + name = "github.com/gorilla/websocket" + packages = ["."] + pruneopts = "UT" + revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d" + version = "v1.4.0" + +[[projects]] + branch = "master" + digest = "1:6c612dcf6342c70b413171db9caa4eb6d64298ac92be7142d5f8757792bd0045" + name = "github.com/gostaticanalysis/analysisutil" + packages = ["."] + pruneopts = "UT" + revision = "56bca42c76353df8b3e08af308c2e3b915bdc4c2" + +[[projects]] + digest = "1:7efe48dea4db6b35dcc15e15394b627247e5b3fb814242de986b746ba8e0abf0" + name = "github.com/gxed/go-shellwords" + packages = ["."] + pruneopts = "UT" + revision = "02e3cf038dcea8290e44424da473dd12be796a8a" + version = "v1.0.3" + +[[projects]] + digest = "1:0ade334594e69404d80d9d323445d2297ff8161637f9b2d347cc6973d2d6f05b" + name = "github.com/hashicorp/errwrap" + packages = ["."] + pruneopts = "UT" + revision = "8a6fb523712970c966eefc6b39ed2c5e74880354" + version = "v1.0.0" + +[[projects]] + digest = "1:f668349b83f7d779567c880550534addeca7ebadfdcf44b0b9c39be61864b4b7" + name = "github.com/hashicorp/go-multierror" + packages = ["."] + pruneopts = "UT" + revision = "886a7fbe3eb1c874d46f623bfa70af45f425b3d1" + version = "v1.0.0" + +[[projects]] + digest = "1:d15ee511aa0f56baacc1eb4c6b922fa1c03b38413b6be18166b996d82a0156ea" + name = "github.com/hashicorp/golang-lru" + packages = [ + ".", + "simplelru", + ] + pruneopts = "UT" + revision = "7087cb70de9f7a8bc0a10c375cb0d2280a8edf9c" + version = "v0.5.1" + +[[projects]] + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/printer", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token", + ] + pruneopts = "UT" + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" + +[[projects]] + digest = "1:541a489631d4084ea2b619e0edd3f8eb7e3858cd8725dd0239a361798863672e" + name = "github.com/hsanjuan/go-libp2p-http" + packages = ["."] + pruneopts = "UT" + revision = "9b0da0751e81069747a272ede6c1248394cbb560" + version = "v0.1.2" + +[[projects]] + digest = "1:c00cc6d95a674b4b923ac069d364445043bc67836e9bd8aeff8440cfbe6a2cc7" + name = "github.com/huin/goupnp" + packages = [ + ".", + "dcps/internetgateway1", + "dcps/internetgateway2", + "httpu", + "scpd", + "soap", + "ssdp", + ] + pruneopts = "UT" + revision = "656e61dfadd241c7cbdd22a023fa81ecb6860ea8" + version = "v1.0.0" + +[[projects]] + digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" + name = "github.com/inconshreveable/mousetrap" + packages = ["."] + pruneopts = "UT" + revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" + version = "v1.0" + +[[projects]] + digest = "1:fe9aa4ac8c8d9bf5eaec1a8dd8c029f2cecd1c4ad91072b7ac99ecb44ff66910" + name = "github.com/ipfs/bbloom" + packages = ["."] + pruneopts = "UT" + revision = "4492942caf937893b9cf1ebba71c297beda904b2" + version = "v0.0.1" + +[[projects]] + digest = "1:014f43937a01f4140d5c32584836c86dd1c6e524bf56e1b402d842a9d78eb652" + name = "github.com/ipfs/dir-index-html" + packages = ["."] + pruneopts = "UT" + revision = "76b6774a477fe6263d445972fe176f3f3b4ea176" + version = "v1.0.3" + +[[projects]] + digest = "1:01c18b3edc5ca147f9136e937ff4095aa1808bc51772e133273666ea069699bc" + name = "github.com/ipfs/go-bitswap" + packages = [ + ".", + "decision", + "getter", + "message", + "message/pb", + "messagequeue", + "network", + "notifications", + "peermanager", + "providerquerymanager", + "session", + "sessionmanager", + "sessionpeermanager", + "sessionrequestsplitter", + "wantlist", + "wantmanager", + ] + pruneopts = "UT" + revision = "1b921d216899ca84abc6a904efd2cbca77a67f65" + version = "v0.1.1" + +[[projects]] + digest = "1:97b7b1549d94c885626167359549d9164bb35a9a584faa7c3a576909be0ea37f" + name = "github.com/ipfs/go-block-format" + packages = ["."] + pruneopts = "UT" + revision = "9e46c0dce5d9a041b8ea1eed8ca924b36355c61b" + version = "v0.0.2" + +[[projects]] + digest = "1:4de47245d5ec315fb9c8f7aa3b0f2d19fb6df0cf33bf1cdb25673c6110fe4d95" + name = "github.com/ipfs/go-blockservice" + packages = ["."] + pruneopts = "UT" + revision = "4815cb7459d447756e8783e26a86dc8e1bfed774" + version = "v0.1.0" + +[[projects]] + digest = "1:664cf1fc1e6ec05988cc6b8f52a61fca914279a92dcd0bc1b8be5507fb3b0c8a" + name = "github.com/ipfs/go-cid" + packages = ["."] + pruneopts = "UT" + revision = "b1cc3e404d48791056147f118ea7e7ea94eb946f" + version = "v0.0.2" + +[[projects]] + digest = "1:b8b8567077bb9d92b85b2411d5e5a9bb79e79ce3a620f094931b909d6845328a" + name = "github.com/ipfs/go-cidutil" + packages = [ + ".", + "cid-fmt", + "cidenc", + ] + pruneopts = "UT" + revision = "fdf58ea0da03b6087e14bcce352303c1c0bad32d" + version = "v0.0.2" + +[[projects]] + digest = "1:079436f26cbece7e60cf4b4b851794a65dd5f360579b2f27a05415c70478dfb4" + name = "github.com/ipfs/go-datastore" + packages = [ + ".", + "autobatch", + "keytransform", + "mount", + "namespace", + "query", + "retrystore", + "sync", + ] + pruneopts = "UT" + revision = "aa9190c18f1576be98e974359fd08c64ca0b5a94" + version = "v0.0.5" + +[[projects]] + digest = "1:77f64288e27bdc74a4937129006037f89ea08ec55a0822531a9a76050f904528" + name = "github.com/ipfs/go-detect-race" + packages = ["."] + pruneopts = "UT" + revision = "52daa73989bc95b2fa97d6c610adf62d04eb7822" + version = "v0.0.1" + +[[projects]] + digest = "1:8270de0224f4c8ef01e23463a6c6f2a5026a2d3ccf3f2e3145ffcd67d7b9a62c" + name = "github.com/ipfs/go-ds-badger" + packages = ["."] + pruneopts = "UT" + revision = "7fe0af0808f565d460fa8d3851a5808d77f72628" + version = "v0.0.3" + +[[projects]] + digest = "1:f896dc92ae70c70f57ac8d47c0aa3e9fe185afcc35ee807975a621766ee6028f" + name = "github.com/ipfs/go-ds-flatfs" + packages = ["."] + pruneopts = "UT" + revision = "d5e3c1fa14d2fcc187a4a996eea3f48de9d7a5cd" + version = "v0.0.2" + +[[projects]] + digest = "1:ab70bd10c780d127a66393a14061ae69ae0145027e7207b7c43db68524f3f64a" + name = "github.com/ipfs/go-ds-leveldb" + packages = ["."] + pruneopts = "UT" + revision = "47a9627082eeb3e52570a75eb4fdfaff8b2f19a9" + version = "v0.0.2" + +[[projects]] + digest = "1:afbc88b3730097cd76ea72695941270547a5b3ed00d870ee0612897ac9943d79" + name = "github.com/ipfs/go-ds-measure" + packages = ["."] + pruneopts = "UT" + revision = "a74729db656decb31c9d0546aef893eaeb4247f7" + version = "v0.0.1" + +[[projects]] + digest = "1:bc3ed1378495622fd5eba7b63c86c10af1e5c4c1ae8642ab85b994ed89cf08bf" + name = "github.com/ipfs/go-fs-lock" + packages = ["."] + pruneopts = "UT" + revision = "66f8794e4aed94004486434cf8bf815e5991a0a4" + version = "v0.0.1" + +[[projects]] + digest = "1:429edc38cba9210059680d94ed67a8552632025635e666e112313986de135d74" + name = "github.com/ipfs/go-ipfs-blockstore" + packages = ["."] + pruneopts = "UT" + revision = "8d6a694a33d2729a94d848208c75d117b77c3492" + version = "v0.0.1" + +[[projects]] + digest = "1:25b55cfa6c762a2623c5b50b76e021c48c293e983cd38890f885e2f8d8a216c6" + name = "github.com/ipfs/go-ipfs-blocksutil" + packages = ["."] + pruneopts = "UT" + revision = "11463846b576c51999afeedd9a0eacda8b5cb2c4" + version = "v0.0.1" + +[[projects]] + digest = "1:cf743f8296553603264f68ae79fbd0ed9ce25636c28deedde111d6760b8b0c7d" + name = "github.com/ipfs/go-ipfs-chunker" + packages = ["."] + pruneopts = "UT" + revision = "ecef6090e78f549c5f48f18d398e7b7f97e8c32d" + version = "v0.0.1" + +[[projects]] + digest = "1:50f399a26a1a675a8d1709f69aafaee8b5a7d51d678902c98285d02197ea829e" + name = "github.com/ipfs/go-ipfs-cmds" + packages = [ + ".", + "cli", + "http", + ] + pruneopts = "UT" + revision = "6069424baf71e64d6075836733f34a6f9afba22d" + version = "v0.0.10" + +[[projects]] + digest = "1:4751a46363a69f324ef4ed1ef60e24a2f8d74c1b4de8672f094b9329a785ef18" + name = "github.com/ipfs/go-ipfs-config" + packages = [ + ".", + "serialize", + ] + pruneopts = "UT" + revision = "4a51393611d9580d17ecbccb0c4aec5eb81f21ce" + source = "github.com/vulcanize/go-ipfs-config" + +[[projects]] + digest = "1:ae1ee4c628ee8ad66d9505bb2685902c93e0cd89089a17b8804463b5cc1b766b" + name = "github.com/ipfs/go-ipfs-delay" + packages = ["."] + pruneopts = "UT" + revision = "6482ad624d0b4f4053563439f8ca0bd619fbc737" + version = "v0.0.1" + +[[projects]] + digest = "1:0fcfbb9a7c8245d19d5a79c13ad702201c1d9cd8ca79619379a22845de723278" + name = "github.com/ipfs/go-ipfs-ds-help" + packages = ["."] + pruneopts = "UT" + revision = "4a69beb72c1b4e6e7ed62c5c5cbc1bd7a3d219b2" + version = "v0.0.1" + +[[projects]] + digest = "1:c8bc4cbd7b94d84784f6f99cca35ebedebb5f9ded2d561e4130d8c67cc5127b0" + name = "github.com/ipfs/go-ipfs-exchange-interface" + packages = ["."] + pruneopts = "UT" + revision = "b6e88260772433e18af18bb3f237d78678e65f0b" + version = "v0.0.1" + +[[projects]] + digest = "1:284cfd2a17692d0e628a263854b8acea34427b9aa2f4f923b91570f07ae65d2e" + name = "github.com/ipfs/go-ipfs-exchange-offline" + packages = ["."] + pruneopts = "UT" + revision = "e3705b31117ceccfa67820f84c1085f74f5e039b" + version = "v0.0.1" + +[[projects]] + digest = "1:2f4c34c23f57eadaea0a620386dcc691e83f44cc52fb8163f53695e7aa3fbae4" + name = "github.com/ipfs/go-ipfs-files" + packages = ["."] + pruneopts = "UT" + revision = "cf8456081cd5fd17ae1716c5fdff7d4cfba1bbb2" + version = "v0.0.3" + +[[projects]] + digest = "1:990c3a92954ef12159a3564533e63edc53feeadcb513930250351b919c6756f5" + name = "github.com/ipfs/go-ipfs-posinfo" + packages = ["."] + pruneopts = "UT" + revision = "19b0f52f6bd140be93fb568203586a165eb1aadf" + version = "v0.0.1" + +[[projects]] + digest = "1:3d6b825f2ac90788f3ac6bb7927d339ded21d02951d08b5bb66bf5326af45ea9" + name = "github.com/ipfs/go-ipfs-pq" + packages = ["."] + pruneopts = "UT" + revision = "63128f5dd36a6c20c0f2d1c65eb4390d2590a273" + version = "v0.0.1" + +[[projects]] + digest = "1:962e8c6b42e9c2d36bbdb2e55a4cc893f7faec22da7de71c634090b96a87a4d6" + name = "github.com/ipfs/go-ipfs-routing" + packages = [ + "mock", + "none", + "offline", + ] + pruneopts = "UT" + revision = "d508458cea98e199ae7b84029b627ceb9e5db660" + version = "v0.1.0" + +[[projects]] + digest = "1:0b4439ae69776549e6489b261f66894a1390140dad53f1c3b1fbfc074478590d" + name = "github.com/ipfs/go-ipfs-util" + packages = ["."] + pruneopts = "UT" + revision = "a4bb5361e49427531f9a716ead2ce4bd9bdd7959" + version = "v0.0.1" + +[[projects]] + digest = "1:b67b5b49a303fbef8d0c30958b41754068898b0084813cf9021cc9ecd7e4c7e4" + name = "github.com/ipfs/go-ipld-cbor" + packages = [ + ".", + "encoding", + ] + pruneopts = "UT" + revision = "c084f45ab421fae38c99d98ce7aca9ca5ae85af3" + version = "v0.0.2" + +[[projects]] + digest = "1:60006152d40763463546fc6db3e21a223d9a1a5dedb6554bbe6d1679ae1bf7b3" + name = "github.com/ipfs/go-ipld-format" + packages = ["."] + pruneopts = "UT" + revision = "c8bb359ca21e831187139329dd4da249abc95602" + version = "v0.0.2" + +[[projects]] + digest = "1:fe257dab08c7455ab2afb1836d9933f09719d53e16c61df9a2e23316798ccfc2" + name = "github.com/ipfs/go-ipld-git" + packages = ["."] + pruneopts = "UT" + revision = "ee620e932c0cf00124e7c1c6f434eb89530caaf8" + version = "v0.0.2" + +[[projects]] + digest = "1:4638b57014e4a204350087e3a2d5631f8aaa197bb6af688ca6e280457a7a46fa" + name = "github.com/ipfs/go-ipns" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "a989b48e3b7d32af1c872cbf2f6e884a08a9b351" + version = "v0.0.1" + +[[projects]] + digest = "1:e8c78569402b8dcf846924dea6eb27b1de135c9a53d7adbd2629250ef66c021a" + name = "github.com/ipfs/go-log" + packages = [ + ".", + "tracer", + "tracer/wire", + "writer", + ] + pruneopts = "UT" + revision = "91b837264c0f35dd4e2be341d711316b91d3573d" + version = "v0.0.1" + +[[projects]] + digest = "1:1347cc59745de60dcec6e00aec552d654d0efa72b119cd3a92967b8a69a6ff47" + name = "github.com/ipfs/go-merkledag" + packages = [ + ".", + "pb", + "test", + ] + pruneopts = "UT" + revision = "e0c97528b5888969361ca8c0826e79944ea40682" + version = "v0.1.0" + +[[projects]] + digest = "1:2de37461901377cb21aae96aab4ca67ebbb6d77e5f140c8f376eb566b7805365" + name = "github.com/ipfs/go-metrics-interface" + packages = ["."] + pruneopts = "UT" + revision = "87aa106f53272f064ca7956a6db83f17a553f254" + version = "v0.0.1" + +[[projects]] + digest = "1:c78afe3d1578551c86f287fdac8fb883ae34b545084fa9b7d8f6cfb7a73e730f" + name = "github.com/ipfs/go-metrics-prometheus" + packages = ["."] + pruneopts = "UT" + revision = "8f6977cb23506737d1177332bd0b91a2352bcb98" + version = "v0.0.2" + +[[projects]] + digest = "1:87b290476fd7fbd45a38d7e2608ac51562d075cb7e709425cb1a060cf71fbf9a" + name = "github.com/ipfs/go-mfs" + packages = ["."] + pruneopts = "UT" + revision = "bb73cf40769a3306b932f156365f7e7662719fd2" + version = "v0.1.0" + +[[projects]] + digest = "1:78c440f94312bb5181ef6fdebf54ed91c7c115f6e79010aa5e513fdc9a7e3ddd" + name = "github.com/ipfs/go-path" + packages = [ + ".", + "resolver", + ] + pruneopts = "UT" + revision = "466e1ce7a7073faa0af3af8cd95c914ff1b1e945" + version = "v0.0.7" + +[[projects]] + digest = "1:d0b359ab95f5abe4d17eae347b5a2270912e728eaaa9826e6371c8a3d5325fff" + name = "github.com/ipfs/go-peertaskqueue" + packages = [ + ".", + "peertask", + "peertracker", + ] + pruneopts = "UT" + revision = "98cd87e43d9738e3409c0fbf44c9613b1f455207" + version = "v0.1.0" + +[[projects]] + digest = "1:5d5961815f8e4f1fbad28f6c7ff5e42fcd9527aa823a5daa19b622b9cc41d1ed" + name = "github.com/ipfs/go-todocounter" + packages = ["."] + pruneopts = "UT" + revision = "bc75efcf13e6e50fbba27679ba5451585d70c954" + version = "v0.0.1" + +[[projects]] + digest = "1:42a537f668fb79eeb79cd951d6459dd3eb8fba72a914ac15eda3a7cb1d5d2548" + name = "github.com/ipfs/go-unixfs" + packages = [ + ".", + "file", + "hamt", + "importer", + "importer/balanced", + "importer/helpers", + "importer/trickle", + "io", + "mod", + "pb", + ] + pruneopts = "UT" + revision = "5fc20dbc340ea48f74d111d139b2d539d8ffa3c0" + version = "v0.0.8" + +[[projects]] + digest = "1:78438260483c355139f9d83830a88ecd69578904f0f288134d3a95786c4f0864" + name = "github.com/ipfs/go-verifcid" + packages = ["."] + pruneopts = "UT" + revision = "34e41ba962e7ce0211a05915f788486c8db755f1" + version = "v0.0.1" + +[[projects]] + digest = "1:67444125b68f4adc123856dec40308ff0ef9b01f4b6c9a935f57dae78f2d3340" + name = "github.com/ipfs/hang-fds" + packages = ["."] + pruneopts = "UT" + revision = "7a8a28f4b275d193ef56fc921f61f68b4e8d64d0" + version = "v0.0.1" + +[[projects]] + digest = "1:49a5b375c716393e801f42bd704a07f2affa1b99e00e6431bbf012e08ef25af4" + name = "github.com/ipfs/interface-go-ipfs-core" + packages = [ + ".", + "options", + "options/namesys", + "path", + "tests", + ] + pruneopts = "UT" + revision = "f77aa7ee2c521ce3361de11b4e257b01f28f8db0" + version = "v0.1.0" + +[[projects]] + digest = "1:da000e612bc16400a8a0c53dda5b78c401fd7851e7b30a977a3087e7d36d80fc" + name = "github.com/ipfs/iptb" + packages = [ + "cli", + "commands", + "testbed", + "testbed/interfaces", + "util", + ] + pruneopts = "UT" + revision = "ae2b4b3d6c9166db00a845c9e88181c0886f585b" + version = "v1.4.0" + +[[projects]] + digest = "1:aefdc6057b4c5135a4eb07aa5e9a38d0364d1a5d28d1865fec17545799819ce3" + name = "github.com/ipfs/iptb-plugins" + packages = [ + ".", + "local", + ] + pruneopts = "UT" + revision = "a1cfafa7cc11f44e35a1ae4f7f1db896b12642e5" + version = "v0.1.0" + +[[projects]] + digest = "1:b352ae8b1a77cc6b48fc8e314e34a522cfc76d6ca3a06c93b29c9cde5de6771e" + name = "github.com/jackpal/gateway" + packages = ["."] + pruneopts = "UT" + revision = "cbcf4e3f3baee7952fc386c8b2534af4d267c875" + version = "v1.0.5" + +[[projects]] + digest = "1:32b82e71cf24f8b78323e0d7903c4b90278486283965aa2a19b1ea13763b8f34" + name = "github.com/jackpal/go-nat-pmp" + packages = ["."] + pruneopts = "UT" + revision = "c9cfead9f2a36ddf3daa40ba269aa7f4bbba6b62" + version = "v1.0.1" + +[[projects]] + digest = "1:30f857b000a0d14f978110222f1b1ba9cb1de8f6cabaca51933f3627ca6578a0" + name = "github.com/jbenet/go-is-domain" + packages = ["."] + pruneopts = "UT" + revision = "009bc9fc8d69261cc21e8eb2aa0925af155d1c11" + version = "v1.0.2" + +[[projects]] + branch = "master" + digest = "1:8cec67047e352e2a6e2c4ee4ce5b9886ac435c8b86df5941a7a10253e96fc0d3" + name = "github.com/jbenet/go-random" + packages = [ + ".", + "random", + ] + pruneopts = "UT" + revision = "123a90aedc0cfa3fbac8e2854d3d3b8219d9d156" + +[[projects]] + branch = "master" + digest = "1:cf7bb5b9d6a9136537450b5af1bc76578e1b6ec9bdbea01931c9917b74c50824" + name = "github.com/jbenet/go-random-files" + packages = [ + ".", + "random-files", + "ringreader", + ] + pruneopts = "UT" + revision = "31b3f20ebded11390a052597f61b9661e6e7c9ff" + +[[projects]] + branch = "master" + digest = "1:8f4aedc183dc8dfef9a7a1f1ba205dc87ecd2675eea350a736bda889e3bcf8ea" + name = "github.com/jbenet/go-temp-err-catcher" + packages = ["."] + pruneopts = "UT" + revision = "aac704a3f4f27190b4ccc05f303a4931fd1241ff" + +[[projects]] + digest = "1:ee4b434dc3622e5c25a611ce314d40dd724495f27968797a2589a4d89eeed7eb" + name = "github.com/jbenet/goprocess" + packages = [ + ".", + "context", + "periodic", + "ratelimit", + ] + pruneopts = "UT" + revision = "7f9d9ed286badffcf2122cfeb383ec37daf92508" + version = "v0.1.3" + +[[projects]] + digest = "1:75ab90ae3f5d876167e60f493beadfe66f0ed861a710f283fb06c86437a09538" + name = "github.com/jonboulle/clockwork" + packages = ["."] + pruneopts = "UT" + revision = "2eee05ed794112d45db504eb05aa693efd2b8b09" + version = "v0.1.0" + +[[projects]] + digest = "1:15ec2166e33ef6c60b344a04d050eec79193517e7f5082b6233b2d09ef0d10b8" + name = "github.com/kisielk/gotool" + packages = [ + ".", + "internal/load", + ] + pruneopts = "UT" + revision = "80517062f582ea3340cd4baf70e86d539ae7d84d" + version = "v1.0.0" + +[[projects]] + digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de" + name = "github.com/konsorten/go-windows-terminal-sequences" + packages = ["."] + pruneopts = "UT" + revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e" + version = "v1.0.2" + +[[projects]] + digest = "1:58ad79834dc097c36a857a8c325d646af0a8bbd73375a6958a639507c5399a61" + name = "github.com/koron/go-ssdp" + packages = ["."] + pruneopts = "UT" + revision = "6d1709049dead37ead37808479f88c9bffa2c4d6" + version = "v0.1" + +[[projects]] + digest = "1:bdd53b87de8185da386bae179c84d4848854c6870bacacf6a154fe63e2e750f7" + name = "github.com/lib/pq" + packages = [ + ".", + "oid", + "scram", + ] + pruneopts = "UT" + revision = "bc6a3c0594130b1e34005880bc600b6d3f49fa7f" + version = "v1.1.1" + +[[projects]] + digest = "1:483fcb9b21a758b47501f8880628b85aa3c4e99e33166867d06fa278965c66b2" + name = "github.com/libp2p/go-addr-util" + packages = ["."] + pruneopts = "UT" + revision = "4cd36c0f325f9e38f1e31ff7a10b9d94d53a11cf" + version = "v0.0.1" + +[[projects]] + digest = "1:b18a269f11ff51135d6f82987dbb53288f4d66098a6639b429f4f494a910155b" + name = "github.com/libp2p/go-buffer-pool" + packages = ["."] + pruneopts = "UT" + revision = "c4a5988a1e475884367015e1a2d0bd5fa4c491f4" + version = "v0.0.2" + +[[projects]] + digest = "1:041a5219e2f0c1fa2af5d25aee6970600ba2ac055ba386c18cfe960d392df3db" + name = "github.com/libp2p/go-conn-security-multistream" + packages = ["."] + pruneopts = "UT" + revision = "09b4134a655b5fc883a5bdd62ea12db6e0a1b095" + version = "v0.1.0" + +[[projects]] + digest = "1:83d3d59c84ff3da342ab63011d79750ccb987bda399eb64db3abd3e2fd32c18f" + name = "github.com/libp2p/go-flow-metrics" + packages = ["."] + pruneopts = "UT" + revision = "1f5b3acc846b2c8ce4c4e713296af74f5c24df55" + version = "v0.0.1" + +[[projects]] + digest = "1:d19d69803c50feab0b448d60dee41a3d9bd36af71f0c4b21d3075cfe5b288441" + name = "github.com/libp2p/go-libp2p" + packages = [ + ".", + "config", + "p2p/discovery", + "p2p/host/basic", + "p2p/host/relay", + "p2p/host/routed", + "p2p/net/mock", + "p2p/protocol/identify", + "p2p/protocol/identify/pb", + "p2p/protocol/ping", + ] + pruneopts = "UT" + revision = "d69c889ad97b02883e04164c6acf77a7381634c2" + version = "v0.1.1" + +[[projects]] + digest = "1:9a8251be38a87690510affa2e2fb04799a066b8ef49edc25a6acd30760d40792" + name = "github.com/libp2p/go-libp2p-autonat" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "3464f9b4f7bfbd7bb008813eacb626c7ab7fb9a3" + version = "v0.1.0" + +[[projects]] + digest = "1:04832a4429ccc5e9d793c6c27a5807c5854a79d44a893c80cb72d0bf8dfc157f" + name = "github.com/libp2p/go-libp2p-autonat-svc" + packages = ["."] + pruneopts = "UT" + revision = "51a8fe550623e6ebae91c9b43755e2ee9c310549" + version = "v0.1.0" + +[[projects]] + digest = "1:3da4ac7b6ea1fd52a22012966d7c744715a5cabfea013be30cb0d595bcfcdd3f" + name = "github.com/libp2p/go-libp2p-circuit" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "e65c36f3bb806cf658db0f0b612879899e2d28dc" + version = "v0.1.0" + +[[projects]] + digest = "1:15ffa5302d331a56efdc24ce2570ddf32bfff89daa4e3b0fed0c453a19b4960c" + name = "github.com/libp2p/go-libp2p-connmgr" + packages = ["."] + pruneopts = "UT" + revision = "152025a671fcc297333095f8e4afc98d90b30df7" + version = "v0.1.0" + +[[projects]] + digest = "1:acd95ce094e21559ddad0985e07709d5a1c9f7f648428681b423a5360cd71c74" + name = "github.com/libp2p/go-libp2p-core" + packages = [ + "connmgr", + "crypto", + "crypto/pb", + "discovery", + "helpers", + "host", + "metrics", + "mux", + "network", + "peer", + "peerstore", + "pnet", + "protocol", + "routing", + "sec", + "sec/insecure", + "test", + "transport", + ] + pruneopts = "UT" + revision = "8f222f4b5a872d9af86f74f2ec0982c7356adce6" + version = "v0.0.3" + +[[projects]] + digest = "1:35caf66f415bddda628d9410a20a6bcd8ac3deebbda33de1220d3f7ee3a14ccd" + name = "github.com/libp2p/go-libp2p-crypto" + packages = ["."] + pruneopts = "UT" + revision = "ddb6d72b5ad0ae81bf1ee77b628eac1d7237536a" + version = "v0.1.0" + +[[projects]] + digest = "1:0333065da4682126d7c1aa07dd11d94accc3b93b48945ebb7f6a921e2f6b0db2" + name = "github.com/libp2p/go-libp2p-discovery" + packages = ["."] + pruneopts = "UT" + revision = "d248d63b0af8c023307da18ad7000a12020e06f0" + version = "v0.1.0" + +[[projects]] + digest = "1:c370faf62c81c21ad23d2a5a30e4fb0347e80460e3abcc10901a48daf0999ddc" + name = "github.com/libp2p/go-libp2p-gostream" + packages = ["."] + pruneopts = "UT" + revision = "7fcf4dd149c1d97388f362aa139db26227d54bd4" + version = "v0.1.1" + +[[projects]] + digest = "1:7811b2a796bfc81952e70d14c5bb99ac550b18b1bbf815359a4d24cfc4329481" + name = "github.com/libp2p/go-libp2p-kad-dht" + packages = [ + ".", + "metrics", + "opts", + "pb", + "providers", + ] + pruneopts = "UT" + revision = "31765355df17ef818381169dc36180c84c119928" + version = "v0.1.0" + +[[projects]] + digest = "1:d750c3b6c1c69bab8ed996ca6c053e0a13db53d2c51937a0debc40174c77bfc1" + name = "github.com/libp2p/go-libp2p-kbucket" + packages = [ + ".", + "keyspace", + ] + pruneopts = "UT" + revision = "3752ea0128fd84b4fef0a66739b8ca95c8a471b6" + version = "v0.2.0" + +[[projects]] + digest = "1:645c5ab1429b06141e0d22852df9561e04b3759380f6657f0b510a30eef83665" + name = "github.com/libp2p/go-libp2p-loggables" + packages = ["."] + pruneopts = "UT" + revision = "814642b01726ff6f9302e8ce9eeeb00d25409520" + version = "v0.1.0" + +[[projects]] + digest = "1:714ce7cff748910cfc250713300d24ece7d4832156ba7a245e7ac5fc810c7319" + name = "github.com/libp2p/go-libp2p-mplex" + packages = ["."] + pruneopts = "UT" + revision = "811729f15f0af13fe3f0d9e410c22f6a4bc5c686" + version = "v0.2.1" + +[[projects]] + digest = "1:4614c7d351b9cc24ef6457107fad9830664615bb7d7de91de10c4a4ab1919545" + name = "github.com/libp2p/go-libp2p-nat" + packages = ["."] + pruneopts = "UT" + revision = "c50c291a61bceccb914366d93eb24f58594e9134" + version = "v0.0.4" + +[[projects]] + digest = "1:2930f937f465b6801ca4a89a701a5131aa215a6a854b0e7c344d6d62960d2563" + name = "github.com/libp2p/go-libp2p-netutil" + packages = ["."] + pruneopts = "UT" + revision = "cd42ce60b36206032242a27faa1121c08ae2829e" + version = "v0.1.0" + +[[projects]] + digest = "1:79d1cf3e88f9ae667c30039cc37a6ad0be8bf0fa9b5359b572253de74b24c644" + name = "github.com/libp2p/go-libp2p-peer" + packages = ["."] + pruneopts = "UT" + revision = "62676d8fb785a8fc279878cbe8e03b878f005910" + version = "v0.2.0" + +[[projects]] + digest = "1:9a42e258de3b7daa00e2a3499bfa34185fb0c94b31cfa12a0f85f9105ebf8072" + name = "github.com/libp2p/go-libp2p-peerstore" + packages = [ + ".", + "addr", + "pstoremem", + "queue", + ] + pruneopts = "UT" + revision = "4353646945045d89f77d0b362cb5e5533cbd117e" + version = "v0.1.0" + +[[projects]] + digest = "1:576fc983d8a7fae4f2d03f8bfcfee6c2b062b70fee73cb10cc6a7531445ba998" + name = "github.com/libp2p/go-libp2p-pnet" + packages = ["."] + pruneopts = "UT" + revision = "f0a2f186a5c972b76b55680d5ef21894491c2f81" + version = "v0.1.0" + +[[projects]] + digest = "1:639e2ee83cffd5445eeffd1cb8ba50b690028dc98464abac24e93a15abca8c8b" + name = "github.com/libp2p/go-libp2p-pubsub" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "49274b0e8aecdf6cad59d768e5702ff00aa48488" + version = "v0.1.0" + +[[projects]] + digest = "1:d1eeaaf0f74ecb34eb30a48fd20347cf5b3df17ca822e3a99e23100922072b31" + name = "github.com/libp2p/go-libp2p-pubsub-router" + packages = ["."] + pruneopts = "UT" + revision = "1b619f8d12950c3a6b91f93c08f29842af38a68c" + version = "v0.1.0" + +[[projects]] + digest = "1:0e004b6b20f295a4e3a0e11e0644b3cb05beb5011c751f52cb088bc6d15ba94c" + name = "github.com/libp2p/go-libp2p-quic-transport" + packages = ["."] + pruneopts = "UT" + revision = "2abd270a64ebf0e3b869ee6bc7a1e5ac8b001fe6" + version = "v0.1.1" + +[[projects]] + digest = "1:524733c74ff3b3fad069dbfda7b21c532c2411125b5bd60a7560f90cdbf82eab" + name = "github.com/libp2p/go-libp2p-record" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "4837430afd8f3864d4805d7a1675521abb1096b4" + version = "v0.1.0" + +[[projects]] + digest = "1:ab8374423f8b7148d55e6d7ec848d248a0707b2af8a8b8a5b3608887d9ec485d" + name = "github.com/libp2p/go-libp2p-routing" + packages = ["notifications"] + pruneopts = "UT" + revision = "f4ece6c1baa8e77ee488b25014fcb1059955ed0f" + version = "v0.1.0" + +[[projects]] + digest = "1:62994932ddbe31d1130589fb009538831afec171c787677a570cc9eba0dd96fe" + name = "github.com/libp2p/go-libp2p-routing-helpers" + packages = ["."] + pruneopts = "UT" + revision = "061228ae05eb858e5d99d80e96920a6de1df497a" + version = "v0.1.0" + +[[projects]] + digest = "1:d0bed92a182074cefb3f2e1beb5d250618ab38b2fb2dbcaf0496c20c77acf8da" + name = "github.com/libp2p/go-libp2p-secio" + packages = [ + ".", + "pb", + ] + pruneopts = "UT" + revision = "a158134b5708e33fa36545d8ba8e27ea1c8ae54e" + version = "v0.1.0" + +[[projects]] + digest = "1:112a23330f359f603c21f42d0917245829807671b8e819ff0397d73966df8195" + name = "github.com/libp2p/go-libp2p-swarm" + packages = [ + ".", + "testing", + ] + pruneopts = "UT" + revision = "99831444e78c8f23c9335c17d8f7c700ba25ca14" + version = "v0.1.0" + +[[projects]] + digest = "1:c639dcba227173d259cfd5e0ceb23df301eeddb1ce944fa1a72b60fd6f37d93d" + name = "github.com/libp2p/go-libp2p-testing" + packages = [ + "ci", + "ci/travis", + "etc", + "net", + ] + pruneopts = "UT" + revision = "6d4ca71943f35271918e28f9a9950002e17b4f16" + version = "v0.0.4" + +[[projects]] + digest = "1:af731b7005639d582a0353c22651e94d08d3970abfdddac742c9fad94b85bfd1" + name = "github.com/libp2p/go-libp2p-tls" + packages = ["."] + pruneopts = "UT" + revision = "d1a46ca5425197316b94a31953df645adaa21f67" + version = "v0.1.0" + +[[projects]] + digest = "1:2fcb80000123d80148ce210a053a226d52dc891419905d7ff076c164825da50d" + name = "github.com/libp2p/go-libp2p-transport-upgrader" + packages = ["."] + pruneopts = "UT" + revision = "07ed92ccf9aba3a2e4b2fddc4c17ced060524922" + version = "v0.1.1" + +[[projects]] + digest = "1:c476d8c20126fdc217055de367da2a8c4d78da52bf0818dedd6c92e87795021c" + name = "github.com/libp2p/go-libp2p-yamux" + packages = ["."] + pruneopts = "UT" + revision = "a61e80cb5770aa0d9b1bafe94da1278f58baa2c5" + version = "v0.2.1" + +[[projects]] + digest = "1:986c0c852c462da2cdc5d584dc2fd884cb898371cbc43cdc250149f40f8cd8fc" + name = "github.com/libp2p/go-maddr-filter" + packages = ["."] + pruneopts = "UT" + revision = "e3cdd802c04babcbec2c4711721d105cfe822cd3" + version = "v0.0.4" + +[[projects]] + digest = "1:fd01fc96631a63d323f17fcbd64161804439855404b9405db14deacba9e1b69c" + name = "github.com/libp2p/go-mplex" + packages = ["."] + pruneopts = "UT" + revision = "62fe9554facaec3f80333b61ea8d694fe615705f" + version = "v0.1.0" + +[[projects]] + digest = "1:fd524b598a7aa769d2bb5f0a6e5de4b95989070cf65ff100b87523fc2be7b9dc" + name = "github.com/libp2p/go-msgio" + packages = ["."] + pruneopts = "UT" + revision = "90cce7933451e8b170cf5d5a3627fd2950d155fd" + version = "v0.0.3" + +[[projects]] + digest = "1:82e0411449d8af0c34e200cd6b90e70689d692d17f836906194fa9fc28692e80" + name = "github.com/libp2p/go-nat" + packages = ["."] + pruneopts = "UT" + revision = "d13fdefb3bbb2fde2c6fc090a7ea992cec8b26df" + version = "v0.0.3" + +[[projects]] + digest = "1:3218d9edf75d814d2994ce4b14fae01c657a3284af84522efcc8dee89806f4ca" + name = "github.com/libp2p/go-reuseport" + packages = ["."] + pruneopts = "UT" + revision = "3e6d618acfdfacbbeff71cb2bd70fc188f897a0f" + version = "v0.0.1" + +[[projects]] + digest = "1:bf12fbd51fb864c9e2cb688581d3c14551a8c3d1c2fa60c9ad405c532e1b9d42" + name = "github.com/libp2p/go-reuseport-transport" + packages = ["."] + pruneopts = "UT" + revision = "c7583c88df654a2ecd621e863f661783d79b64d1" + version = "v0.0.2" + +[[projects]] + digest = "1:58a6c4b9e52e298228703f9bf480d65c40ede7152a9ad17aa1eafe618ed0b43a" + name = "github.com/libp2p/go-stream-muxer-multistream" + packages = ["."] + pruneopts = "UT" + revision = "2439b02deee2de8bb1fe24473d3d8333008a714a" + version = "v0.2.0" + +[[projects]] + digest = "1:ac5ce11098023fcf8164307727a2b99d69e2bb84a3b1f4bc3e1d10fd72f9bdbd" + name = "github.com/libp2p/go-tcp-transport" + packages = ["."] + pruneopts = "UT" + revision = "415627e90148700bf97890e54b193a42125c3b66" + version = "v0.1.0" + +[[projects]] + digest = "1:b1436d41d493ff2d51052838e0415c26366314febead5051f732f5c98e3729f1" + name = "github.com/libp2p/go-ws-transport" + packages = ["."] + pruneopts = "UT" + revision = "6efd965516262a6b6e46ea987b94904ef13e59bc" + version = "v0.1.0" + +[[projects]] + digest = "1:64fdef1e970d17504d960d18412125e85ca620703e495105b3fbffee27acf568" + name = "github.com/libp2p/go-yamux" + packages = ["."] + pruneopts = "UT" + revision = "663972181d409e7263040f0b668462f87c85e1bd" + version = "v1.2.3" + +[[projects]] + digest = "1:95de854fb72e6cd0344b875a04abace9abbef78c304c4f31b451bbedd9023338" + name = "github.com/lucas-clemente/quic-go" + packages = [ + ".", + "internal/ackhandler", + "internal/congestion", + "internal/flowcontrol", + "internal/handshake", + "internal/protocol", + "internal/qerr", + "internal/utils", + "internal/wire", + ] + pruneopts = "UT" + revision = "4355e1a7e961ba3b6005cb035ae17732181c9508" + version = "v0.11.2" + +[[projects]] + digest = "1:5a0ef768465592efca0412f7e838cdc0826712f8447e70e6ccc52eb441e9ab13" + name = "github.com/magiconair/properties" + packages = ["."] + pruneopts = "UT" + revision = "de8848e004dd33dc07a2947b3d76f618a7fc7ef1" + version = "v1.8.1" + +[[projects]] + digest = "1:9d377b8e6748a813a7fb25e99bf54bfaefba62eac5bf5152c2657f95dbe83172" + name = "github.com/marten-seemann/qtls" + packages = ["."] + pruneopts = "UT" + revision = "cd359ef406f82ab779fea7db4c512898eb3007a6" + version = "v0.2.4" + +[[projects]] + digest = "1:7c084e0e780596dd2a7e20d25803909a9a43689c153de953520dfbc0b0e51166" + name = "github.com/mattn/go-colorable" + packages = ["."] + pruneopts = "UT" + revision = "8029fb3788e5a4a9c00e415f586a6d033f5d38b3" + version = "v0.1.2" + +[[projects]] + digest = "1:9b90c7639a41697f3d4ad12d7d67dfacc9a7a4a6e0bbfae4fc72d0da57c28871" + name = "github.com/mattn/go-isatty" + packages = ["."] + pruneopts = "UT" + revision = "1311e847b0cb909da63b5fecfb5370aa66236465" + version = "v0.0.8" + +[[projects]] + digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7" + name = "github.com/mattn/go-runewidth" + packages = ["."] + pruneopts = "UT" + revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3" + version = "v0.0.4" + +[[projects]] + digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + pruneopts = "UT" + revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" + version = "v1.0.1" + +[[projects]] + branch = "master" + digest = "1:2b32af4d2a529083275afc192d1067d8126b578c7a9613b26600e4df9c735155" + name = "github.com/mgutz/ansi" + packages = ["."] + pruneopts = "UT" + revision = "9520e82c474b0a04dd04f8a40959027271bab992" + +[[projects]] + digest = "1:7c572c76f914b3d3f7d75ce752c3a6ac5ba03be1f775e4602a3f18d7b08ddbbb" + name = "github.com/miekg/dns" + packages = ["."] + pruneopts = "UT" + revision = "9cfcfb2209aecb663673bd44b11f71c215186b80" + version = "v1.1.14" + +[[projects]] + branch = "master" + digest = "1:130cefe87d7eeefc824978dcb78e35672d4c49a11f25c153fbf0cfd952756fa3" + name = "github.com/minio/blake2b-simd" + packages = ["."] + pruneopts = "UT" + revision = "3f5f724cb5b182a5c278d6d3d55b40e7f8c2efb4" + +[[projects]] + digest = "1:d69117243f58a0d320c2889872d8c14d323d865277dc49fc85bfcf48b2846b8f" + name = "github.com/minio/sha256-simd" + packages = ["."] + pruneopts = "UT" + revision = "05b4dd3047e5d6e86cb4e0477164b850cd896261" + version = "v0.1.0" + +[[projects]] + digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + pruneopts = "UT" + revision = "af06845cf3004701891bf4fdb884bfe4920b3727" + version = "v1.1.0" + +[[projects]] + digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + pruneopts = "UT" + revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe" + version = "v1.1.2" + +[[projects]] + branch = "master" + digest = "1:ae08d850ba158ea3ba4a7bb90f8372608172d8920644e5a6693b940a1f4e5d01" + name = "github.com/mmcloughlin/avo" + packages = [ + "attr", + "build", + "buildtags", + "gotypes", + "internal/prnt", + "internal/stack", + "ir", + "operand", + "pass", + "printer", + "reg", + "src", + "x86", + ] + pruneopts = "UT" + revision = "83fbad1a6b3cba8ac7711170e57953fd12cdc40a" + +[[projects]] + digest = "1:b6299badabd66eaede0651e2eaede106d8298b25564e4a7f23e335471d3e5a35" + name = "github.com/mr-tron/base58" + packages = ["base58"] + pruneopts = "UT" + revision = "d504ab2e22d97cb9f10b1d146a1e6a063f4a5f43" + version = "v1.1.2" + +[[projects]] + digest = "1:b9fe622bbadbb060338620752b1cb3aa1473855071195ebe83813af5ebb3629b" + name = "github.com/multiformats/go-base32" + packages = ["."] + pruneopts = "UT" + revision = "a9c2755c3d1672dbe6a7e4a5d182169fa30b6a8e" + version = "v0.0.3" + +[[projects]] + digest = "1:c95537699dfc9ecc62c2bb273fd2fdf5810ce23ed50f25529c17f755a052a7c3" + name = "github.com/multiformats/go-multiaddr" + packages = ["."] + pruneopts = "UT" + revision = "5b1de2f51ff2368d5ce94a659f15ef26be273cd0" + version = "v0.0.4" + +[[projects]] + digest = "1:e7b7007612b49b368d5b505b624b399a1de5fe2764271b92145aa9ca0440ab4e" + name = "github.com/multiformats/go-multiaddr-dns" + packages = ["."] + pruneopts = "UT" + revision = "e7c544d7a325c57bdbd7e9ba9c035a6701c5c7d2" + version = "v0.0.2" + +[[projects]] + digest = "1:1275cf8587ba416c439453ee4b194b803270b836831c487b3da3cf9d82f58bb7" + name = "github.com/multiformats/go-multiaddr-fmt" + packages = ["."] + pruneopts = "UT" + revision = "7d8102a98552c80f8a5ccb9c01e670fac17fd6df" + version = "v0.0.1" + +[[projects]] + digest = "1:ccb950e76138c70abe765c3b9c0e6cad0e55fc66ff53318cea8b651df9f892c7" + name = "github.com/multiformats/go-multiaddr-net" + packages = ["."] + pruneopts = "UT" + revision = "bd61b0499a3cfc893a8eb109c5669342b1671881" + version = "v0.0.1" + +[[projects]] + digest = "1:8f2a32f6d211bf2685d5c47ace5d6b59bd4359f69e92b632793d066129a65c4e" + name = "github.com/multiformats/go-multibase" + packages = ["."] + pruneopts = "UT" + revision = "d63641945dc1749baa23686ad0564ad63fef0493" + version = "v0.0.1" + +[[projects]] + digest = "1:5769b15a01346046ca7a66e2205326e0d5efcf7c4e2d116fcd26b6c8910c6872" + name = "github.com/multiformats/go-multihash" + packages = [ + ".", + "multihash", + "opts", + ] + pruneopts = "UT" + revision = "c242156eec223a58ac13b8c114a2b31e87bbf558" + version = "v0.0.5" + +[[projects]] + digest = "1:026ef80e6db7432132c7687d23b465e0c4bdb47a4aed893ee4b7d528a0550059" + name = "github.com/multiformats/go-multistream" + packages = ["."] + pruneopts = "UT" + revision = "039807e4901c4b2041f40a0e4aa32d72939608aa" + version = "v0.1.0" + +[[projects]] + digest = "1:66b0a65aba488ca6c72f77132d5b8d7e2c5baf07d577dee64502b69a2c90c791" + name = "github.com/nbutton23/zxcvbn-go" + packages = [ + ".", + "adjacency", + "data", + "entropy", + "frequency", + "match", + "matching", + "scoring", + "utils/math", + ] + pruneopts = "UT" + revision = "eafdab6b0663b4b528c35975c8b0e78be6e25261" + version = "v0.1" + +[[projects]] + digest = "1:11e62d6050198055e6cd87ed57e5d8c669e84f839c16e16f192374d913d1a70d" + name = "github.com/opentracing/opentracing-go" + packages = [ + ".", + "ext", + "log", + ] + pruneopts = "UT" + revision = "659c90643e714681897ec2521c60567dd21da733" + version = "v1.1.0" + +[[projects]] + digest = "1:93131d8002d7025da13582877c32d1fc302486775a1b06f62241741006428c5e" + name = "github.com/pelletier/go-toml" + packages = ["."] + pruneopts = "UT" + revision = "728039f679cbcd4f6a54e080d2219a4c4928c546" + version = "v1.4.0" + +[[projects]] + digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b" + name = "github.com/pkg/errors" + packages = ["."] + pruneopts = "UT" + revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" + version = "v0.8.1" + +[[projects]] + branch = "master" + digest = "1:13e3ecd0eb9145fd62bebcc8fb8334b20408f31da7be3cacb68b5abcd09a1f42" + name = "github.com/polydawn/refmt" + packages = [ + ".", + "cbor", + "json", + "obj", + "obj/atlas", + "pretty", + "shared", + "tok", + ] + pruneopts = "UT" + revision = "01bf1e26dd14f9b71f26b7005a2b1ef514d5f9a4" + +[[projects]] + digest = "1:e89f2cdede55684adbe44b5566f55838ad2aee1dff348d14b73ccf733607b671" + name = "github.com/prometheus/client_golang" + packages = [ + "prometheus", + "prometheus/internal", + "prometheus/promhttp", + ] + pruneopts = "UT" + revision = "2641b987480bca71fb39738eb8c8b0d577cb1d76" + version = "v0.9.4" + +[[projects]] + branch = "master" + digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4" + name = "github.com/prometheus/client_model" + packages = ["go"] + pruneopts = "UT" + revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8" + +[[projects]] + digest = "1:8dcedf2e8f06c7f94e48267dea0bc0be261fa97b377f3ae3e87843a92a549481" + name = "github.com/prometheus/common" + packages = [ + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model", + ] + pruneopts = "UT" + revision = "17f5ca1748182ddf24fc33a5a7caaaf790a52fcc" + version = "v0.4.1" + +[[projects]] + digest = "1:403b810b43500b5b0a9a24a47347e31dc2783ccae8cf97c891b46f5b0496fa1a" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/fs", + ] + pruneopts = "UT" + revision = "833678b5bb319f2d20a475cb165c6cc59c2cc77c" + version = "v0.0.2" + +[[projects]] + digest = "1:b0c25f00bad20d783d259af2af8666969e2fc343fa0dc9efe52936bbd67fb758" + name = "github.com/rs/cors" + packages = ["."] + pruneopts = "UT" + revision = "9a47f48565a795472d43519dd49aac781f3034fb" + version = "v1.6.0" + +[[projects]] + digest = "1:04457f9f6f3ffc5fea48e71d62f2ca256637dee0a04d710288e27e05c8b41976" + name = "github.com/sirupsen/logrus" + packages = ["."] + pruneopts = "UT" + revision = "839c75faf7f98a33d445d181f3018b5c3409a45e" + version = "v1.4.2" + +[[projects]] + digest = "1:f0be8922b4a34a3e07caef4c8bcb9377713af6edf3b7cb9ded42f095b7994374" + name = "github.com/sourcegraph/go-diff" + packages = ["diff"] + pruneopts = "UT" + revision = "042635e6444e67483d777aaa240274f13691500c" + version = "v0.5.1" + +[[projects]] + branch = "master" + digest = "1:74aa99ef18406ebfdedfb2a07b9a01f9ff2b6d2547b27b33fcdf1007223d75cc" + name = "github.com/spacemonkeygo/openssl" + packages = [ + ".", + "utils", + ] + pruneopts = "UT" + revision = "c2dcc5cca94ac8f7f3f0c20e20050d4cce9d9730" + +[[projects]] + branch = "master" + digest = "1:d6956eb95db39859627c18e1dd425b2ddd1a0d6000b643a4d4ada8fc887c1e09" + name = "github.com/spacemonkeygo/spacelog" + packages = ["."] + pruneopts = "UT" + revision = "2296661a0572a51438413369004fa931c2641923" + +[[projects]] + digest = "1:919bb3aa6d9d0b67648c219fa4925312bc3c2872da19e818fa769e9c97a2b643" + name = "github.com/spaolacci/murmur3" + packages = ["."] + pruneopts = "UT" + revision = "9f5d223c60793748f04a9d5b4b4eacddfc1f755d" + version = "v1.1" + +[[projects]] + digest = "1:bb495ec276ab82d3dd08504bbc0594a65de8c3b22c6f2aaa92d05b73fbf3a82e" + name = "github.com/spf13/afero" + packages = [ + ".", + "mem", + ] + pruneopts = "UT" + revision = "588a75ec4f32903aa5e39a2619ba6a4631e28424" + version = "v1.2.2" + +[[projects]] + digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc" + name = "github.com/spf13/cast" + packages = ["."] + pruneopts = "UT" + revision = "8c9545af88b134710ab1cd196795e7f2388358d7" + version = "v1.3.0" + +[[projects]] + digest = "1:e096613fb7cf34743d49af87d197663cfccd61876e2219853005a57baedfa562" + name = "github.com/spf13/cobra" + packages = ["."] + pruneopts = "UT" + revision = "f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5" + version = "v0.0.5" + +[[projects]] + digest = "1:1b753ec16506f5864d26a28b43703c58831255059644351bbcb019b843950900" + name = "github.com/spf13/jwalterweatherman" + packages = ["."] + pruneopts = "UT" + revision = "94f6ae3ed3bceceafa716478c5fbf8d29ca601a1" + version = "v1.1.0" + +[[projects]] + digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" + name = "github.com/spf13/pflag" + packages = ["."] + pruneopts = "UT" + revision = "298182f68c66c05229eb03ac171abe6e309ee79a" + version = "v1.0.3" + +[[projects]] + digest = "1:11118bd196646c6515fea3d6c43f66162833c6ae4939bfb229b9956d91c6cf17" + name = "github.com/spf13/viper" + packages = ["."] + pruneopts = "UT" + revision = "b5bf975e5823809fb22c7644d008757f78a4259e" + version = "v1.4.0" + +[[projects]] + digest = "1:5b180f17d5bc50b765f4dcf0d126c72979531cbbd7f7929bf3edd87fb801ea2d" + name = "github.com/syndtr/goleveldb" + packages = [ + "leveldb", + "leveldb/cache", + "leveldb/comparer", + "leveldb/errors", + "leveldb/filter", + "leveldb/iterator", + "leveldb/journal", + "leveldb/memdb", + "leveldb/opt", + "leveldb/storage", + "leveldb/table", + "leveldb/util", + ] + pruneopts = "UT" + revision = "9d007e481048296f09f59bd19bb7ae584563cd95" + version = "v1.0.0" + +[[projects]] + branch = "master" + digest = "1:a38c75e7edd595bbaa03334c1ac26163a5e990d81f05cd9ec5fd0edc9c786078" + name = "github.com/texttheater/golang-levenshtein" + packages = ["levenshtein"] + pruneopts = "UT" + revision = "d188e65d659ef53fcdb0691c12f1bba64928b649" + +[[projects]] + branch = "master" + digest = "1:7393233424f587db9c11ea3b74c57e4955b47e4ba1b76ab5ea940b672a1263fb" + name = "github.com/timakin/bodyclose" + packages = ["passes/bodyclose"] + pruneopts = "UT" + revision = "4a873e97b2bb302885fe7592c4b2d5749cc62985" + +[[projects]] + digest = "1:b24d38b282bacf9791408a080f606370efa3d364e4b5fd9ba0f7b87786d3b679" + name = "github.com/urfave/cli" + packages = ["."] + pruneopts = "UT" + revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" + version = "v1.20.0" + +[[projects]] + branch = "master" + digest = "1:98fa13beefbf581ec173561adad6374c460631593b4bdcf03adc29cd18e5d2f5" + name = "github.com/whyrusleeping/base32" + packages = ["."] + pruneopts = "UT" + revision = "c30ac30633ccdabefe87eb12465113f06f1bab75" + +[[projects]] + branch = "master" + digest = "1:3ca7e47848bbb8fc6c17b86c9887117e2e83dd5d68f7c4daf8c8fd30471ea597" + name = "github.com/whyrusleeping/chunker" + packages = ["."] + pruneopts = "UT" + revision = "fe64bd25879f446bb7e8a4adf5d4a68552211bd3" + +[[projects]] + branch = "master" + digest = "1:b33eed6794f2b2d1a7d0b45cb705402f26af0f0ad6521667e144ffa71f52d9d9" + name = "github.com/whyrusleeping/go-keyspace" + packages = ["."] + pruneopts = "UT" + revision = "5b898ac5add1da7178a4a98e69cb7b9205c085ee" + +[[projects]] + branch = "master" + digest = "1:0102dfa2f98777db8ff68c920bef1be3ff8504e90485b6cdd24d61b981b487b6" + name = "github.com/whyrusleeping/go-logging" + packages = ["."] + pruneopts = "UT" + revision = "0457bb6b88fc1973573aaf6b5145d8d3ae972390" + +[[projects]] + branch = "master" + digest = "1:94796f9decedb46b17985693cbe996ce3642a991f0efcf7bf9a6c5197da3eefc" + name = "github.com/whyrusleeping/go-notifier" + packages = ["."] + pruneopts = "UT" + revision = "097c5d47330ff6a823f67e3515faa13566a62c6f" + +[[projects]] + branch = "master" + digest = "1:2fba6c6f47871875d89473514217f2e32380f72373ece98c10c93807981f35db" + name = "github.com/whyrusleeping/go-sysinfo" + packages = ["."] + pruneopts = "UT" + revision = "4a357d4b90b11a6fd867fdb51c21d686645830c2" + +[[projects]] + digest = "1:6c96967502c55c555abfe560f561a124951345e713a8e87cc6e2c214976e6e75" + name = "github.com/whyrusleeping/mafmt" + packages = ["."] + pruneopts = "UT" + revision = "7aa7fad2ede4e7157818e3e7af5061f866a9ae23" + version = "v1.2.8" + +[[projects]] + branch = "master" + digest = "1:0a017705731cb8ad506e72d842840ba89809e5b27b5593954c7eeeb631823735" + name = "github.com/whyrusleeping/mdns" + packages = ["."] + pruneopts = "UT" + revision = "ef14215e6b30606f4ce84174ed7a644a05cb1af3" + +[[projects]] + branch = "master" + digest = "1:94b933c1b26f1da25d25a089937d15987170a0a54109aa521a111345c3e84581" + name = "github.com/whyrusleeping/multiaddr-filter" + packages = ["."] + pruneopts = "UT" + revision = "e903e4adabd70b78bc9293b6ee4f359afb3f9f59" + +[[projects]] + branch = "master" + digest = "1:dc9bda956375dc82dacd2a78f32095aae7c6e40c676b2f971357ccb76cbf46c2" + name = "github.com/whyrusleeping/sql-datastore" + packages = [ + ".", + "postgres", + ] + pruneopts = "UT" + revision = "b24eb8d0ce144e31120c0708b0c987362d63c1a0" + +[[projects]] + branch = "master" + digest = "1:e2599924072678810fe41b00dead8e11e95fa55be2dbc01b5309c4bf04f2209c" + name = "github.com/whyrusleeping/tar-utils" + packages = ["."] + pruneopts = "UT" + revision = "8c6c8ba81d5c71fd69c0f48dbde4b2fb422b6dfc" + +[[projects]] + branch = "master" + digest = "1:1ccd9d66ae1abe6b3b28d8b68e09387533fee345d8bbaa753af2fa16e0505807" + name = "github.com/whyrusleeping/timecache" + packages = ["."] + pruneopts = "UT" + revision = "cfcb2f1abfee846c430233aef0b630a946e0a5a6" + +[[projects]] + digest = "1:0509a2e8721ffedf3c03ebed1ac8eda633b8f4ee812d5edcac5c5d77eaeb7f0d" + name = "go.opencensus.io" + packages = [ + "internal/tagencoding", + "metric/metricdata", + "metric/metricproducer", + "resource", + "stats", + "stats/internal", + "stats/view", + "tag", + ] + pruneopts = "UT" + revision = "9c377598961b706d1542bd2d84d538b5094d596e" + version = "v0.22.0" + +[[projects]] + digest = "1:ff6b126259880858441d0a43e63c3f2f9071601415e1f34a7f053f90cbef8464" + name = "go.uber.org/atomic" + packages = ["."] + pruneopts = "UT" + revision = "3b8db5e93c4c02efbc313e17b2e796b0914a01fb" + version = "v1.1.0" + +[[projects]] + digest = "1:2773e4e922e5af534775962ffef08770b8114e177590f7605886528d37417105" + name = "go.uber.org/dig" + packages = [ + ".", + "internal/digreflect", + "internal/dot", + ] + pruneopts = "UT" + revision = "7ff117f761a3f1b3eb521945c17a1091438eb6de" + version = "v1.7.0" + +[[projects]] + digest = "1:74e59bc785a76b467b9a5c0353193e8befa0c27863413e5fc52e87cf3d24fa4e" + name = "go.uber.org/fx" + packages = [ + ".", + "internal/fxlog", + "internal/fxreflect", + "internal/lifecycle", + ] + pruneopts = "UT" + revision = "3de044da969b90ad0a3e4a7867a74662f645f3f9" + version = "v1.9.0" + +[[projects]] + digest = "1:60bf2a5e347af463c42ed31a493d817f8a72f102543060ed992754e689805d1a" + name = "go.uber.org/multierr" + packages = ["."] + pruneopts = "UT" + revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a" + version = "v1.1.0" + +[[projects]] + branch = "master" + digest = "1:52796c672f9529f506ac63c10bf44072c8156cb2c85c0784a8b8ccb164e94903" + name = "go4.org" + packages = ["lock"] + pruneopts = "UT" + revision = "94abd6928b1da39b1d757b60c93fb2419c409fa1" + +[[projects]] + branch = "master" + digest = "1:b7289611803360021aa5fe4469d9ff38eab6b6fa9898af160fc218d3edbbd1a6" + name = "golang.org/x/crypto" + packages = [ + "blake2s", + "blowfish", + "chacha20poly1305", + "cryptobyte", + "cryptobyte/asn1", + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "hkdf", + "internal/chacha20", + "internal/subtle", + "poly1305", + "salsa20", + "salsa20/salsa", + "sha3", + "ssh/terminal", + ] + pruneopts = "UT" + revision = "5c40567a22f818bd14a1ea7245dad9f8ef0691aa" + +[[projects]] + branch = "master" + digest = "1:c094df8a7b79d5c6ddc9035b13516f5bf1d7516e785d1c57a6f9d6a1d0efe3ff" + name = "golang.org/x/net" + packages = [ + "bpf", + "context", + "html", + "html/atom", + "html/charset", + "internal/iana", + "internal/socket", + "internal/timeseries", + "ipv4", + "ipv6", + "trace", + ] + pruneopts = "UT" + revision = "3f473d35a33aa6fdd203e306dc439b797820e3f1" + +[[projects]] + branch = "master" + digest = "1:8ea0513faaf49c2491a6aa1c4962261295ed140478e3e84b5c699f42af0a3936" + name = "golang.org/x/sys" + packages = [ + "cpu", + "unix", + "windows", + ] + pruneopts = "UT" + revision = "93c9922d18aeb82498a065f07aec7ad7fa60dfb7" + +[[projects]] + digest = "1:a8790d49ff0b71048aa8170d2863918f9d22e74293ca92b90333c05a40514a84" + name = "golang.org/x/text" + packages = [ + "encoding", + "encoding/charmap", + "encoding/htmlindex", + "encoding/internal", + "encoding/internal/identifier", + "encoding/japanese", + "encoding/korean", + "encoding/simplifiedchinese", + "encoding/traditionalchinese", + "encoding/unicode", + "internal/gen", + "internal/language", + "internal/language/compact", + "internal/tag", + "internal/triegen", + "internal/ucd", + "internal/utf8internal", + "language", + "runes", + "transform", + "unicode/cldr", + "unicode/norm", + "width", + ] + pruneopts = "UT" + revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475" + version = "v0.3.2" + +[[projects]] + branch = "master" + digest = "1:319e7521886d58092551020028e8ddb691d5bd756f1ab58baa033e0ff3ff6c30" + name = "golang.org/x/tools" + packages = [ + "cover", + "go/analysis", + "go/analysis/passes/asmdecl", + "go/analysis/passes/assign", + "go/analysis/passes/atomic", + "go/analysis/passes/atomicalign", + "go/analysis/passes/bools", + "go/analysis/passes/buildssa", + "go/analysis/passes/buildtag", + "go/analysis/passes/cgocall", + "go/analysis/passes/composite", + "go/analysis/passes/copylock", + "go/analysis/passes/ctrlflow", + "go/analysis/passes/httpresponse", + "go/analysis/passes/inspect", + "go/analysis/passes/internal/analysisutil", + "go/analysis/passes/loopclosure", + "go/analysis/passes/lostcancel", + "go/analysis/passes/nilfunc", + "go/analysis/passes/printf", + "go/analysis/passes/shadow", + "go/analysis/passes/shift", + "go/analysis/passes/stdmethods", + "go/analysis/passes/structtag", + "go/analysis/passes/tests", + "go/analysis/passes/unmarshal", + "go/analysis/passes/unreachable", + "go/analysis/passes/unsafeptr", + "go/analysis/passes/unusedresult", + "go/ast/astutil", + "go/ast/inspector", + "go/buildutil", + "go/cfg", + "go/gcexportdata", + "go/internal/cgo", + "go/internal/gcimporter", + "go/internal/packagesdriver", + "go/loader", + "go/packages", + "go/ssa", + "go/ssa/ssautil", + "go/types/typeutil", + "imports", + "internal/fastwalk", + "internal/gopathwalk", + "internal/imports", + "internal/module", + "internal/semver", + ] + pruneopts = "UT" + revision = "d73e1c7e250b19f9948138e2df37cea712e8f06f" + +[[projects]] + branch = "master" + digest = "1:c44a77760372a998be8d4656e8d3c865f68735ec4cad1743a245903a58f64249" + name = "golang.org/x/xerrors" + packages = [ + ".", + "internal", + ] + pruneopts = "UT" + revision = "3ee3066db522c6628d440a3a91c4abdd7f5ef22f" + +[[projects]] + digest = "1:d219400f09c151f0ada918bab650ef46f7ebdb1ff4fea923fdcb839481ec7ec1" + name = "gopkg.in/cheggaaa/pb.v1" + packages = ["."] + pruneopts = "UT" + revision = "f907f6f5dd81f77c2bbc1cde92e4c5a04720cb11" + version = "v1.0.28" + +[[projects]] + digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96" + name = "gopkg.in/yaml.v2" + packages = ["."] + pruneopts = "UT" + revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" + version = "v2.2.2" + +[[projects]] + digest = "1:7ee7d5148e71f169ebba5fa35fc04bf6e9224f91a7d054483a97e56f9bda9ea7" + name = "gotest.tools/gotestsum" + packages = [ + ".", + "internal/junitxml", + "testjson", + ] + pruneopts = "UT" + revision = "ab2fe5eb001028c964502a7ddf7ee721c5826b2c" + version = "v0.1" + +[[projects]] + branch = "master" + digest = "1:ef98efcb9462d27d251466fdc89656c5dbc28f4dc6b428a4270c3ba668ea412d" + name = "mvdan.cc/interfacer" + packages = ["check"] + pruneopts = "UT" + revision = "c20040233aedb03da82d460eca6130fcd91c629a" + +[[projects]] + branch = "master" + digest = "1:521f15c98723cb42db85f5b83980ffa5f707ddaff12976a0d366e6a6cdd1f791" + name = "mvdan.cc/lint" + packages = ["."] + pruneopts = "UT" + revision = "adc824a0674b99099789b6188a058d485eaf61c0" + +[[projects]] + branch = "master" + digest = "1:49663f044145c794116bde2cbcc8045164717b068a3194d26ae2243874de5994" + name = "mvdan.cc/unparam" + packages = ["check"] + pruneopts = "UT" + revision = "1b9ccfa71afe53433971717161c9666adfc4d8c5" + +[[projects]] + digest = "1:ffbeee69d5d01b594a4ca53e359861e3416c70bdbca8d423c72b815f470ecc49" + name = "sourcegraph.com/sqs/pbtypes" + packages = ["."] + pruneopts = "UT" + revision = "688c2c2cb411327a50aae0f89119af9f38b0fc03" + version = "v1.0.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "bazil.org/fuse", + "bazil.org/fuse/fs", + "bazil.org/fuse/fs/fstestutil", + "github.com/Kubuxu/go-os-helper", + "github.com/Kubuxu/gocovmerge", + "github.com/blang/semver", + "github.com/bren2010/proquint", + "github.com/cenkalti/backoff", + "github.com/dustin/go-humanize", + "github.com/elgris/jsondiff", + "github.com/fsnotify/fsnotify", + "github.com/gogo/protobuf/proto", + "github.com/golangci/golangci-lint/cmd/golangci-lint", + "github.com/hashicorp/go-multierror", + "github.com/hashicorp/golang-lru", + "github.com/hsanjuan/go-libp2p-http", + "github.com/ipfs/dir-index-html", + "github.com/ipfs/go-bitswap", + "github.com/ipfs/go-bitswap/decision", + "github.com/ipfs/go-bitswap/network", + "github.com/ipfs/go-block-format", + "github.com/ipfs/go-blockservice", + "github.com/ipfs/go-cid", + "github.com/ipfs/go-cidutil", + "github.com/ipfs/go-cidutil/cid-fmt", + "github.com/ipfs/go-cidutil/cidenc", + "github.com/ipfs/go-datastore", + "github.com/ipfs/go-datastore/mount", + "github.com/ipfs/go-datastore/namespace", + "github.com/ipfs/go-datastore/query", + "github.com/ipfs/go-datastore/retrystore", + "github.com/ipfs/go-datastore/sync", + "github.com/ipfs/go-detect-race", + "github.com/ipfs/go-ds-badger", + "github.com/ipfs/go-ds-flatfs", + "github.com/ipfs/go-ds-leveldb", + "github.com/ipfs/go-ds-measure", + "github.com/ipfs/go-fs-lock", + "github.com/ipfs/go-ipfs-blockstore", + "github.com/ipfs/go-ipfs-blocksutil", + "github.com/ipfs/go-ipfs-chunker", + "github.com/ipfs/go-ipfs-cmds", + "github.com/ipfs/go-ipfs-cmds/cli", + "github.com/ipfs/go-ipfs-cmds/http", + "github.com/ipfs/go-ipfs-config", + "github.com/ipfs/go-ipfs-config/serialize", + "github.com/ipfs/go-ipfs-ds-help", + "github.com/ipfs/go-ipfs-exchange-interface", + "github.com/ipfs/go-ipfs-exchange-offline", + "github.com/ipfs/go-ipfs-files", + "github.com/ipfs/go-ipfs-posinfo", + "github.com/ipfs/go-ipfs-routing/mock", + "github.com/ipfs/go-ipfs-routing/none", + "github.com/ipfs/go-ipfs-routing/offline", + "github.com/ipfs/go-ipfs-util", + "github.com/ipfs/go-ipld-cbor", + "github.com/ipfs/go-ipld-format", + "github.com/ipfs/go-ipld-git", + "github.com/ipfs/go-ipns", + "github.com/ipfs/go-ipns/pb", + "github.com/ipfs/go-log", + "github.com/ipfs/go-log/writer", + "github.com/ipfs/go-merkledag", + "github.com/ipfs/go-merkledag/test", + "github.com/ipfs/go-metrics-interface", + "github.com/ipfs/go-metrics-prometheus", + "github.com/ipfs/go-mfs", + "github.com/ipfs/go-path", + "github.com/ipfs/go-path/resolver", + "github.com/ipfs/go-unixfs", + "github.com/ipfs/go-unixfs/file", + "github.com/ipfs/go-unixfs/importer", + "github.com/ipfs/go-unixfs/importer/balanced", + "github.com/ipfs/go-unixfs/importer/helpers", + "github.com/ipfs/go-unixfs/importer/trickle", + "github.com/ipfs/go-unixfs/io", + "github.com/ipfs/go-unixfs/pb", + "github.com/ipfs/go-verifcid", + "github.com/ipfs/hang-fds", + "github.com/ipfs/interface-go-ipfs-core", + "github.com/ipfs/interface-go-ipfs-core/options", + "github.com/ipfs/interface-go-ipfs-core/options/namesys", + "github.com/ipfs/interface-go-ipfs-core/path", + "github.com/ipfs/interface-go-ipfs-core/tests", + "github.com/ipfs/iptb-plugins/local", + "github.com/ipfs/iptb/cli", + "github.com/ipfs/iptb/testbed", + "github.com/jbenet/go-is-domain", + "github.com/jbenet/go-random", + "github.com/jbenet/go-random-files/random-files", + "github.com/jbenet/go-random/random", + "github.com/jbenet/go-temp-err-catcher", + "github.com/jbenet/goprocess", + "github.com/jbenet/goprocess/context", + "github.com/jbenet/goprocess/periodic", + "github.com/jbenet/goprocess/ratelimit", + "github.com/libp2p/go-libp2p", + "github.com/libp2p/go-libp2p-autonat-svc", + "github.com/libp2p/go-libp2p-circuit", + "github.com/libp2p/go-libp2p-connmgr", + "github.com/libp2p/go-libp2p-core/connmgr", + "github.com/libp2p/go-libp2p-core/crypto", + "github.com/libp2p/go-libp2p-core/host", + "github.com/libp2p/go-libp2p-core/metrics", + "github.com/libp2p/go-libp2p-core/mux", + "github.com/libp2p/go-libp2p-core/network", + "github.com/libp2p/go-libp2p-core/peer", + "github.com/libp2p/go-libp2p-core/peerstore", + "github.com/libp2p/go-libp2p-core/protocol", + "github.com/libp2p/go-libp2p-core/routing", + "github.com/libp2p/go-libp2p-core/test", + "github.com/libp2p/go-libp2p-kad-dht", + "github.com/libp2p/go-libp2p-kad-dht/opts", + "github.com/libp2p/go-libp2p-kbucket", + "github.com/libp2p/go-libp2p-loggables", + "github.com/libp2p/go-libp2p-mplex", + "github.com/libp2p/go-libp2p-peerstore/pstoremem", + "github.com/libp2p/go-libp2p-pnet", + "github.com/libp2p/go-libp2p-pubsub", + "github.com/libp2p/go-libp2p-pubsub-router", + "github.com/libp2p/go-libp2p-quic-transport", + "github.com/libp2p/go-libp2p-record", + "github.com/libp2p/go-libp2p-routing-helpers", + "github.com/libp2p/go-libp2p-secio", + "github.com/libp2p/go-libp2p-swarm", + "github.com/libp2p/go-libp2p-swarm/testing", + "github.com/libp2p/go-libp2p-testing/ci", + "github.com/libp2p/go-libp2p-testing/net", + "github.com/libp2p/go-libp2p-tls", + "github.com/libp2p/go-libp2p-yamux", + "github.com/libp2p/go-libp2p/p2p/discovery", + "github.com/libp2p/go-libp2p/p2p/host/basic", + "github.com/libp2p/go-libp2p/p2p/host/routed", + "github.com/libp2p/go-libp2p/p2p/net/mock", + "github.com/libp2p/go-libp2p/p2p/protocol/identify", + "github.com/libp2p/go-libp2p/p2p/protocol/ping", + "github.com/libp2p/go-maddr-filter", + "github.com/mitchellh/go-homedir", + "github.com/mr-tron/base58/base58", + "github.com/multiformats/go-multiaddr", + "github.com/multiformats/go-multiaddr-dns", + "github.com/multiformats/go-multiaddr-net", + "github.com/multiformats/go-multibase", + "github.com/multiformats/go-multihash", + "github.com/multiformats/go-multihash/multihash", + "github.com/opentracing/opentracing-go", + "github.com/pkg/errors", + "github.com/prometheus/client_golang/prometheus", + "github.com/prometheus/client_golang/prometheus/promhttp", + "github.com/syndtr/goleveldb/leveldb/opt", + "github.com/whyrusleeping/base32", + "github.com/whyrusleeping/go-sysinfo", + "github.com/whyrusleeping/multiaddr-filter", + "github.com/whyrusleeping/sql-datastore/postgres", + "github.com/whyrusleeping/tar-utils", + "go.uber.org/fx", + "golang.org/x/sys/unix", + "gopkg.in/cheggaaa/pb.v1", + "gotest.tools/gotestsum", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/ipfs/go-ipfs/Gopkg.toml b/vendor/github.com/ipfs/go-ipfs/Gopkg.toml new file mode 100644 index 00000000..53699ef2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/Gopkg.toml @@ -0,0 +1,443 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + branch = "master" + name = "bazil.org/fuse" + +[[constraint]] + name = "github.com/Kubuxu/go-os-helper" + version = "0.0.1" + +[[constraint]] + branch = "master" + name = "github.com/Kubuxu/gocovmerge" + +[[constraint]] + name = "github.com/blang/semver" + version = "3.6.1" + +[[constraint]] + branch = "master" + name = "github.com/bren2010/proquint" + +[[constraint]] + name = "github.com/cenkalti/backoff" + version = "3.0.0" + +[[constraint]] + name = "github.com/dustin/go-humanize" + version = "1.0.0" + +[[constraint]] + branch = "master" + name = "github.com/elgris/jsondiff" + +[[constraint]] + name = "github.com/fsnotify/fsnotify" + version = "1.4.7" + +[[constraint]] + name = "github.com/gogo/protobuf" + version = "1.2.1" + +[[constraint]] + name = "github.com/golangci/golangci-lint" + version = "1.17.1" + +[[constraint]] + name = "github.com/hashicorp/go-multierror" + version = "1.0.0" + +[[constraint]] + name = "github.com/hashicorp/golang-lru" + version = "0.5.1" + +[[constraint]] + name = "github.com/hsanjuan/go-libp2p-http" + version = "0.1.2" + +[[constraint]] + name = "github.com/ipfs/dir-index-html" + version = "1.0.3" + +[[constraint]] + name = "github.com/ipfs/go-bitswap" + version = "0.1.1" + +[[constraint]] + name = "github.com/ipfs/go-block-format" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-blockservice" + version = "0.1.0" + +[[constraint]] + name = "github.com/ipfs/go-cid" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-cidutil" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-datastore" + version = "0.0.5" + +[[constraint]] + name = "github.com/ipfs/go-detect-race" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ds-badger" + version = "0.0.3" + +[[constraint]] + name = "github.com/ipfs/go-ds-flatfs" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-ds-leveldb" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-ds-measure" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-fs-lock" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-blockstore" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-blocksutil" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-chunker" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-cmds" + version = "0.0.10" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-config" + source = "github.com/vulcanize/go-ipfs-config" + revision = "4a51393611d9580d17ecbccb0c4aec5eb81f21ce" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-ds-help" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-exchange-interface" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-exchange-offline" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-files" + version = "0.0.3" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-posinfo" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-routing" + version = "0.1.0" + +[[constraint]] + name = "github.com/ipfs/go-ipfs-util" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-ipld-cbor" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-ipld-format" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-ipld-git" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-ipns" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-log" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-merkledag" + version = "0.1.0" + +[[constraint]] + name = "github.com/ipfs/go-metrics-interface" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/go-metrics-prometheus" + version = "0.0.2" + +[[constraint]] + name = "github.com/ipfs/go-mfs" + version = "0.1.0" + +[[constraint]] + name = "github.com/ipfs/go-path" + version = "0.0.7" + +[[constraint]] + name = "github.com/ipfs/go-unixfs" + version = "0.0.8" + +[[constraint]] + name = "github.com/ipfs/go-verifcid" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/hang-fds" + version = "0.0.1" + +[[constraint]] + name = "github.com/ipfs/interface-go-ipfs-core" + version = "0.1.0" + +[[constraint]] + name = "github.com/ipfs/iptb" + version = "1.4.0" + +[[constraint]] + name = "github.com/ipfs/iptb-plugins" + version = "0.1.0" + +[[constraint]] + name = "github.com/jbenet/go-is-domain" + version = "1.0.2" + +[[constraint]] + branch = "master" + name = "github.com/jbenet/go-random" + +[[constraint]] + branch = "master" + name = "github.com/jbenet/go-random-files" + +[[constraint]] + branch = "master" + name = "github.com/jbenet/go-temp-err-catcher" + +[[constraint]] + name = "github.com/jbenet/goprocess" + version = "0.1.3" + +[[constraint]] + name = "github.com/libp2p/go-libp2p" + version = "0.1.1" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-autonat-svc" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-circuit" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-connmgr" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-core" + version = "0.0.3" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-kad-dht" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-kbucket" + version = "0.2.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-loggables" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-mplex" + version = "0.2.1" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-peerstore" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-pnet" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-pubsub" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-pubsub-router" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-quic-transport" + version = "0.1.1" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-record" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-routing-helpers" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-secio" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-swarm" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-testing" + version = "0.0.4" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-tls" + version = "0.1.0" + +[[constraint]] + name = "github.com/libp2p/go-libp2p-yamux" + version = "0.2.1" + +[[constraint]] + name = "github.com/libp2p/go-maddr-filter" + version = "0.0.4" + +[[constraint]] + name = "github.com/mitchellh/go-homedir" + version = "1.1.0" + +[[constraint]] + name = "github.com/mr-tron/base58" + version = "1.1.2" + +[[constraint]] + name = "github.com/multiformats/go-multiaddr" + version = "0.0.4" + +[[constraint]] + name = "github.com/multiformats/go-multiaddr-dns" + version = "0.0.2" + +[[constraint]] + name = "github.com/multiformats/go-multiaddr-net" + version = "0.0.1" + +[[constraint]] + name = "github.com/multiformats/go-multibase" + version = "0.0.1" + +[[constraint]] + name = "github.com/multiformats/go-multihash" + version = "0.0.5" + +[[constraint]] + name = "github.com/opentracing/opentracing-go" + version = "1.1.0" + +[[constraint]] + name = "github.com/pkg/errors" + version = "0.8.1" + +[[constraint]] + name = "github.com/prometheus/client_golang" + version = "0.9.4" + +[[constraint]] + name = "github.com/syndtr/goleveldb" + version = "1.0.0" + +[[constraint]] + branch = "master" + name = "github.com/whyrusleeping/base32" + +[[constraint]] + branch = "master" + name = "github.com/whyrusleeping/go-sysinfo" + +[[constraint]] + branch = "master" + name = "github.com/whyrusleeping/multiaddr-filter" + +[[constraint]] + branch = "master" + name = "github.com/whyrusleeping/tar-utils" + +[[constraint]] + name = "go.uber.org/fx" + version = "1.9.0" + +[[constraint]] + branch = "master" + name = "golang.org/x/sys" + +[[constraint]] + name = "gopkg.in/cheggaaa/pb.v1" + version = "1.0.28" + +[[constraint]] + name = "gotest.tools/gotestsum" + version = "0.1.0" + +[[constraint]] + branch = "master" + name = "github.com/whyrusleeping/sql-datastore" + +[[override]] + name = "github.com/dgraph-io/badger" + revision = "0ce1d2e26af1ba8b8a72ea864145a3e1e3b382cd" + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/ipfs/go-ipfs/LICENSE-APACHE b/vendor/github.com/ipfs/go-ipfs/LICENSE-APACHE new file mode 100644 index 00000000..14478a3b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/vendor/github.com/ipfs/go-ipfs/LICENSE-MIT b/vendor/github.com/ipfs/go-ipfs/LICENSE-MIT new file mode 100644 index 00000000..72dc60d8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs/Makefile b/vendor/github.com/ipfs/go-ipfs/Makefile new file mode 100644 index 00000000..4c175dbc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/Makefile @@ -0,0 +1,8 @@ +# General tools + +SHELL=PATH='$(PATH)' /bin/sh + +# enable second expansion +.SECONDEXPANSION: + +include Rules.mk diff --git a/vendor/github.com/ipfs/go-ipfs/README.md b/vendor/github.com/ipfs/go-ipfs/README.md new file mode 100644 index 00000000..a4af02c0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/README.md @@ -0,0 +1,434 @@ +# go-ipfs + +![banner](https://ipfs.io/ipfs/QmVk7srrwahXLNmcDYvyUEJptyoxpndnRa57YJ11L4jV26/ipfs.go.png) + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-ipfs?status.svg)](https://godoc.org/github.com/ipfs/go-ipfs) +[![Build Status](https://travis-ci.com/ipfs/go-ipfs.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs) + +## What is IPFS? + +IPFS is a global, versioned, peer-to-peer filesystem. It combines good ideas from Git, BitTorrent, Kademlia, SFS, and the Web. It is like a single bittorrent swarm, exchanging git objects. IPFS provides an interface as simple as the HTTP web, but with permanence built in. You can also mount the world at /ipfs. + +For more info see: https://github.com/ipfs/ipfs. + +Please put all issues regarding: + - IPFS _design_ in the [ipfs repo issues](https://github.com/ipfs/ipfs/issues). + - Go IPFS _implementation_ in [this repo](https://github.com/ipfs/go-ipfs/issues). + +## Table of Contents + +- [Security Issues](#security-issues) +- [Install](#install) + - [System Requirements](#system-requirements) + - [Install prebuilt packages](#install-prebuilt-packages) + - [From Linux package managers](#from-linux-package-managers) + - [Build from Source](#build-from-source) + - [Install Go](#install-go) + - [Download and Compile IPFS](#download-and-compile-ipfs) + - [Troubleshooting](#troubleshooting) + - [Development Dependencies](#development-dependencies) + - [Updating](#updating-go-ipfs) +- [Usage](#usage) +- [Getting Started](#getting-started) + - [Some things to try](#some-things-to-try) + - [Docker usage](#docker-usage) + - [Troubleshooting](#troubleshooting-1) +- [Packages](#packages) +- [Development](#development) +- [Contributing](#contributing) +- [License](#license) + +## Security Issues + +The IPFS protocol and its implementations are still in heavy development. This means that there may be problems in our protocols, or there may be mistakes in our implementations. And -- though IPFS is not production-ready yet -- many people are already running nodes in their machines. So we take security vulnerabilities very seriously. If you discover a security issue, please bring it to our attention right away! + +If you find a vulnerability that may affect live deployments -- for example, by exposing a remote execution exploit -- please send your report privately to security@ipfs.io. Please DO NOT file a public issue. The GPG key for security@ipfs.io is [4B9665FB 92636D17 7C7A86D3 50AAE8A9 59B13AF3](https://pgp.mit.edu/pks/lookup?op=get&search=0x50AAE8A959B13AF3). + +If the issue is a protocol weakness that cannot be immediately exploited or something not yet deployed, just discuss it openly. + +## Install + +The canonical download instructions for IPFS are over at: https://docs.ipfs.io/introduction/install/. It is **highly suggested** you follow those instructions if you are not interested in working on IPFS development. + +### System Requirements + +IPFS can run on most Linux, macOS, and Windows systems. We recommend running it on a machine with at least 2 GB of RAM (it’ll do fine with only one CPU core), but it should run fine with as little as 1 GB of RAM. On systems with less memory, it may not be completely stable. + +### Install prebuilt packages + +We host prebuilt binaries over at our [distributions page](https://ipfs.io/ipns/dist.ipfs.io#go-ipfs). + +From there: +- Click the blue "Download go-ipfs" on the right side of the page. +- Open/extract the archive. +- Move `ipfs` to your path (`install.sh` can do it for you). + +You can also download go-ipfs from this project's GitHub releases page if you are unable to access ipfs.io. + +### From Linux package managers + +- [Arch Linux](#arch-linux) +- [Nix](#nix) +- [Snap](#snap) + +#### Arch Linux + +In Arch Linux go-ipfs is available as +[go-ipfs](https://www.archlinux.org/packages/community/x86_64/go-ipfs/) package. + +``` +$ sudo pacman -S go-ipfs +``` + +Development version of go-ipfs is also on AUR under +[go-ipfs-git](https://aur.archlinux.org/packages/go-ipfs-git/). +You can install it using your favourite AUR Helper or manually from AUR. + +#### Nix + +For Linux and MacOSX you can use the purely functional package manager [Nix](https://nixos.org/nix/): + +``` +$ nix-env -i ipfs +``` + +You can also install the Package by using it's attribute name, which is also `ipfs`. + +#### Guix + +GNU's functional package manager, [Guix](https://www.gnu.org/software/guix/), also provides a go-ipfs package: + +``` +$ guix package -i go-ipfs +``` + +#### Snap + +With snap, in any of the [supported Linux distributions](https://snapcraft.io/docs/core/install): + +``` +$ sudo snap install ipfs +``` + +### From Windows package managers + +- [Chocolatey](#chocolatey) + +#### Chocolatey + +The package [ipfs](https://chocolatey.org/packages/ipfs) currently points to go-ipfs and is being maintained. + +```Powershell +PS> choco install ipfs +``` + +### Build from Source + +#### Install Go + +The build process for ipfs requires Go 1.11 or higher. If you don't have it: [Download Go 1.11+](https://golang.org/dl/). + +You'll need to add Go's bin directories to your `$PATH` environment variable e.g., by adding these lines to your `/etc/profile` (for a system-wide installation) or `$HOME/.profile`: + +``` +export PATH=$PATH:/usr/local/go/bin +export PATH=$PATH:$GOPATH/bin +``` + +(If you run into trouble, see the [Go install instructions](https://golang.org/doc/install)). + +#### Download and Compile IPFS + +``` +$ git clone https://github.com/ipfs/go-ipfs.git + +$ cd go-ipfs +$ make install +``` + +If you are building on a non-GNU system, use `gmake` in place of `make`. +Unsupported platforms (run `(g)make supported` for a list) will also need to set the `nofuse` gotag during build. +``` +$ GOTAGS=nofuse (g)make install +``` + +#### Troubleshooting + +- Separate [instructions are available for building on Windows](docs/windows.md). +- `git` is required in order for `go get` to fetch all dependencies. +- Package managers often contain out-of-date `golang` packages. + Ensure that `go version` reports at least 1.10. See above for how to install go. +- If you are interested in development, please install the development +dependencies as well. +- _WARNING_: Older versions of OSX FUSE (for Mac OS X) can cause kernel panics when mounting!- + We strongly recommend you use the [latest version of OSX FUSE](http://osxfuse.github.io/). + (See https://github.com/ipfs/go-ipfs/issues/177) +- For more details on setting up FUSE (so that you can mount the filesystem), see the docs folder. +- Shell command completion is available in `misc/completion/ipfs-completion.bash`. Read [docs/command-completion.md](docs/command-completion.md) to learn how to install it. +- See the [init examples](https://github.com/ipfs/website/tree/master/static/docs/examples/init) for how to connect IPFS to systemd or whatever init system your distro uses. + +### Updating go-ipfs + +#### Using ipfs-update + +IPFS has an updating tool that can be accessed through `ipfs update`. The tool is +not installed alongside IPFS in order to keep that logic independent of the main +codebase. To install `ipfs update`, [download it here](https://ipfs.io/ipns/dist.ipfs.io/#ipfs-update). + +#### Downloading IPFS builds using IPFS + +List the available versions of go-ipfs: + +``` +$ ipfs cat /ipns/dist.ipfs.io/go-ipfs/versions +``` + +Then, to view available builds for a version from the previous command ($VERSION): + +``` +$ ipfs ls /ipns/dist.ipfs.io/go-ipfs/$VERSION +``` + +To download a given build of a version: + +``` +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_darwin-386.tar.gz # darwin 32-bit build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_darwin-amd64.tar.gz # darwin 64-bit build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_freebsd-amd64.tar.gz # freebsd 64-bit build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_linux-386.tar.gz # linux 32-bit build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_linux-amd64.tar.gz # linux 64-bit build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_linux-arm.tar.gz # linux arm build +$ ipfs get /ipns/dist.ipfs.io/go-ipfs/$VERSION/go-ipfs_$VERSION_windows-amd64.zip # windows 64-bit build +``` + +## Usage + +``` + ipfs - Global p2p merkle-dag filesystem. + + ipfs [] [] ... + +SUBCOMMANDS + BASIC COMMANDS + init Initialize ipfs local configuration + add Add a file to ipfs + cat Show ipfs object data + get Download ipfs objects + ls List links from an object + refs List hashes of links from an object + + DATA STRUCTURE COMMANDS + block Interact with raw blocks in the datastore + object Interact with raw dag nodes + files Interact with objects as if they were a unix filesystem + + ADVANCED COMMANDS + daemon Start a long-running daemon process + mount Mount an ipfs read-only mountpoint + resolve Resolve any type of name + name Publish or resolve IPNS names + dns Resolve DNS links + pin Pin objects to local storage + repo Manipulate an IPFS repository + + NETWORK COMMANDS + id Show info about ipfs peers + bootstrap Add or remove bootstrap peers + swarm Manage connections to the p2p network + dht Query the DHT for values or peers + ping Measure the latency of a connection + diag Print diagnostics + + TOOL COMMANDS + config Manage configuration + version Show ipfs version information + update Download and apply go-ipfs updates + commands List all available commands + + Use 'ipfs --help' to learn more about each command. + + ipfs uses a repository in the local file system. By default, the repo is located + at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable: + + export IPFS_PATH=/path/to/ipfsrepo +``` + +## Getting Started + +See also: http://ipfs.io/docs/getting-started/ + +To start using IPFS, you must first initialize IPFS's config files on your +system, this is done with `ipfs init`. See `ipfs init --help` for information on +the optional arguments it takes. After initialization is complete, you can use +`ipfs mount`, `ipfs add` and any of the other commands to explore! + +### Some things to try + +Basic proof of 'ipfs working' locally: + + echo "hello world" > hello + ipfs add hello + # This should output a hash string that looks something like: + # QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o + ipfs cat + + +### Docker usage + +An IPFS docker image is hosted at [hub.docker.com/r/ipfs/go-ipfs](https://hub.docker.com/r/ipfs/go-ipfs/). +To make files visible inside the container you need to mount a host directory +with the `-v` option to docker. Choose a directory that you want to use to +import/export files from IPFS. You should also choose a directory to store +IPFS files that will persist when you restart the container. + + export ipfs_staging= + export ipfs_data= + +Start a container running ipfs and expose ports 4001, 5001 and 8080: + + docker run -d --name ipfs_host -v $ipfs_staging:/export -v $ipfs_data:/data/ipfs -p 4001:4001 -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest + +Watch the ipfs log: + + docker logs -f ipfs_host + +Wait for ipfs to start. ipfs is running when you see: + + Gateway (readonly) server + listening on /ip4/0.0.0.0/tcp/8080 + +You can now stop watching the log. + +Run ipfs commands: + + docker exec ipfs_host ipfs + +For example: connect to peers + + docker exec ipfs_host ipfs swarm peers + +Add files: + + cp -r $ipfs_staging + docker exec ipfs_host ipfs add -r /export/ + +Stop the running container: + + docker stop ipfs_host + +When starting a container running ipfs for the first time with an empty data directory, it will call `ipfs init` to initialize configuration files and generate a new keypair. At this time, you can choose which profile to apply using the `IPFS_PROFILE` environment variable: + + docker run -d --name ipfs_host -e IPFS_PROFILE=server -v $ipfs_staging:/export -v $ipfs_data:/data/ipfs -p 4001:4001 -p 127.0.0.1:8080:8080 -p 127.0.0.1:5001:5001 ipfs/go-ipfs:latest + +### Troubleshooting + +If you have previously installed IPFS before and you are running into problems getting a newer version to work, try deleting (or backing up somewhere else) your IPFS config directory (~/.ipfs by default) and rerunning `ipfs init`. This will reinitialize the config file to its defaults and clear out the local datastore of any bad entries. + +Please direct general questions and help requests to our [forum](https://discuss.ipfs.io) or our IRC channel (freenode #ipfs). + +If you believe you've found a bug, check the [issues list](https://github.com/ipfs/go-ipfs/issues) and, if you don't see your problem there, either come talk to us on IRC (freenode #ipfs) or file an issue of your own! + +## Packages + +> This table is generated using the module [`package-table`](https://github.com/ipfs-shipyard/package-table) with `package-table --data=package-list.json`. + +Listing of the main packages used in the IPFS ecosystem. There are also three specifications worth linking here: + +| Name | CI/Travis | Coverage | Description | +| ---------|---------|---------|--------- | +| **Files** | +| [`go-unixfs`](//github.com/ipfs/go-unixfs) | [![Travis CI](https://travis-ci.com/ipfs/go-unixfs.svg?branch=master)](https://travis-ci.com/ipfs/go-unixfs) | [![codecov](https://codecov.io/gh/ipfs/go-unixfs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-unixfs) | the core 'filesystem' logic | +| [`go-mfs`](//github.com/ipfs/go-mfs) | [![Travis CI](https://travis-ci.com/ipfs/go-mfs.svg?branch=master)](https://travis-ci.com/ipfs/go-mfs) | [![codecov](https://codecov.io/gh/ipfs/go-mfs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-mfs) | a mutable filesystem editor for unixfs | +| [`go-ipfs-posinfo`](//github.com/ipfs/go-ipfs-posinfo) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-posinfo.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-posinfo) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-posinfo/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-posinfo) | helper datatypes for the filestore | +| [`go-ipfs-chunker`](//github.com/ipfs/go-ipfs-chunker) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-chunker.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-chunker) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-chunker/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-chunker) | file chunkers | +| **Exchange** | +| [`go-ipfs-exchange-interface`](//github.com/ipfs/go-ipfs-exchange-interface) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-exchange-interface.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-exchange-interface) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-exchange-interface/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-exchange-interface) | exchange service interface | +| [`go-ipfs-exchange-offline`](//github.com/ipfs/go-ipfs-exchange-offline) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-exchange-offline.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-exchange-offline) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-exchange-offline/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-exchange-offline) | (dummy) offline implementation of the exchange service | +| [`go-bitswap`](//github.com/ipfs/go-bitswap) | [![Travis CI](https://travis-ci.com/ipfs/go-bitswap.svg?branch=master)](https://travis-ci.com/ipfs/go-bitswap) | [![codecov](https://codecov.io/gh/ipfs/go-bitswap/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-bitswap) | bitswap protocol implementation | +| [`go-blockservice`](//github.com/ipfs/go-blockservice) | [![Travis CI](https://travis-ci.com/ipfs/go-blockservice.svg?branch=master)](https://travis-ci.com/ipfs/go-blockservice) | [![codecov](https://codecov.io/gh/ipfs/go-blockservice/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-blockservice) | service that plugs a blockstore and an exchange together | +| **Datastores** | +| [`go-datastore`](//github.com/ipfs/go-datastore) | [![Travis CI](https://travis-ci.com/ipfs/go-datastore.svg?branch=master)](https://travis-ci.com/ipfs/go-datastore) | [![codecov](https://codecov.io/gh/ipfs/go-datastore/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-datastore) | datastore interfaces, adapters, and basic implementations | +| [`go-ipfs-ds-help`](//github.com/ipfs/go-ipfs-ds-help) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-ds-help.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-ds-help) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-ds-help/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-ds-help) | datastore utility functions | +| [`go-ds-flatfs`](//github.com/ipfs/go-ds-flatfs) | [![Travis CI](https://travis-ci.com/ipfs/go-ds-flatfs.svg?branch=master)](https://travis-ci.com/ipfs/go-ds-flatfs) | [![codecov](https://codecov.io/gh/ipfs/go-ds-flatfs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ds-flatfs) | a filesystem-based datastore | +| [`go-ds-measure`](//github.com/ipfs/go-ds-measure) | [![Travis CI](https://travis-ci.com/ipfs/go-ds-measure.svg?branch=master)](https://travis-ci.com/ipfs/go-ds-measure) | [![codecov](https://codecov.io/gh/ipfs/go-ds-measure/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ds-measure) | a metric-collecting database adapter | +| [`go-ds-leveldb`](//github.com/ipfs/go-ds-leveldb) | [![Travis CI](https://travis-ci.com/ipfs/go-ds-leveldb.svg?branch=master)](https://travis-ci.com/ipfs/go-ds-leveldb) | [![codecov](https://codecov.io/gh/ipfs/go-ds-leveldb/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ds-leveldb) | a leveldb based datastore | +| [`go-ds-badger`](//github.com/ipfs/go-ds-badger) | [![Travis CI](https://travis-ci.com/ipfs/go-ds-badger.svg?branch=master)](https://travis-ci.com/ipfs/go-ds-badger) | [![codecov](https://codecov.io/gh/ipfs/go-ds-badger/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ds-badger) | a badgerdb based datastore | +| **Namesys** | +| [`go-ipns`](//github.com/ipfs/go-ipns) | [![Travis CI](https://travis-ci.com/ipfs/go-ipns.svg?branch=master)](https://travis-ci.com/ipfs/go-ipns) | [![codecov](https://codecov.io/gh/ipfs/go-ipns/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipns) | IPNS datastructures and validation logic | +| **Repo** | +| [`go-ipfs-config`](//github.com/ipfs/go-ipfs-config) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-config.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-config) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-config/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-config) | go-ipfs config file definitions | +| [`go-fs-lock`](//github.com/ipfs/go-fs-lock) | [![Travis CI](https://travis-ci.com/ipfs/go-fs-lock.svg?branch=master)](https://travis-ci.com/ipfs/go-fs-lock) | [![codecov](https://codecov.io/gh/ipfs/go-fs-lock/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-fs-lock) | lockfile management functions | +| [`fs-repo-migrations`](//github.com/ipfs/fs-repo-migrations) | [![Travis CI](https://travis-ci.com/ipfs/fs-repo-migrations.svg?branch=master)](https://travis-ci.com/ipfs/fs-repo-migrations) | [![codecov](https://codecov.io/gh/ipfs/fs-repo-migrations/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/fs-repo-migrations) | repo migrations | +| **Blocks** | +| [`go-block-format`](//github.com/ipfs/go-block-format) | [![Travis CI](https://travis-ci.com/ipfs/go-block-format.svg?branch=master)](https://travis-ci.com/ipfs/go-block-format) | [![codecov](https://codecov.io/gh/ipfs/go-block-format/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-block-format) | block interfaces and implementations | +| [`go-ipfs-blockstore`](//github.com/ipfs/go-ipfs-blockstore) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-blockstore.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-blockstore) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-blockstore/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-blockstore) | blockstore interfaces and implementations | +| **Commands** | +| [`go-ipfs-cmds`](//github.com/ipfs/go-ipfs-cmds) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-cmds.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-cmds) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-cmds/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-cmds) | CLI & HTTP commands library | +| [`go-ipfs-api`](//github.com/ipfs/go-ipfs-api) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-api.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-api) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-api/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-api) | a shell for the IPFS HTTP API | +| **Metrics & Logging** | +| [`go-metrics-interface`](//github.com/ipfs/go-metrics-interface) | [![Travis CI](https://travis-ci.com/ipfs/go-metrics-interface.svg?branch=master)](https://travis-ci.com/ipfs/go-metrics-interface) | [![codecov](https://codecov.io/gh/ipfs/go-metrics-interface/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-metrics-interface) | metrics collection interfaces | +| [`go-metrics-prometheus`](//github.com/ipfs/go-metrics-prometheus) | [![Travis CI](https://travis-ci.com/ipfs/go-metrics-prometheus.svg?branch=master)](https://travis-ci.com/ipfs/go-metrics-prometheus) | [![codecov](https://codecov.io/gh/ipfs/go-metrics-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-metrics-prometheus) | prometheus-backed metrics collector | +| [`go-log`](//github.com/ipfs/go-log) | [![Travis CI](https://travis-ci.com/ipfs/go-log.svg?branch=master)](https://travis-ci.com/ipfs/go-log) | [![codecov](https://codecov.io/gh/ipfs/go-log/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-log) | logging framework | +| **Generics/Utils** | +| [`go-ipfs-routing`](//github.com/ipfs/go-ipfs-routing) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-routing.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-routing) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-routing) | routing (content, peer, value) helpers | +| [`go-ipfs-util`](//github.com/ipfs/go-ipfs-util) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-util.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-util) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-util/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-util) | the kitchen sink | +| [`go-ipfs-addr`](//github.com/ipfs/go-ipfs-addr) | [![Travis CI](https://travis-ci.com/ipfs/go-ipfs-addr.svg?branch=master)](https://travis-ci.com/ipfs/go-ipfs-addr) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-addr/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipfs-addr) | utility functions for parsing IPFS multiaddrs | + +For brevity, we've omitted go-libp2p and go-ipld packages. These package tables can be found in their respective project's READMEs: + +* [go-libp2p](https://github.com/libp2p/go-libp2p#packages) +* [go-ipld](https://github.com/ipld/go-ipld#packages) + +## Development + +Some places to get you started on the codebase: + +- Main file: [./cmd/ipfs/main.go](https://github.com/ipfs/go-ipfs/blob/master/cmd/ipfs/main.go) +- CLI Commands: [./core/commands/](https://github.com/ipfs/go-ipfs/tree/master/core/commands) +- Bitswap (the data trading engine): [go-bitswap](https://github.com/ipfs/go-bitswap) +- libp2p + - libp2p: https://github.com/libp2p/go-libp2p + - DHT: https://github.com/libp2p/go-libp2p-kad-dht + - PubSub: https://github.com/libp2p/go-libp2p-pubsub +- [IPFS : The `Add` command demystified](https://github.com/ipfs/go-ipfs/tree/master/docs/add-code-flow.md) + +### CLI, HTTP-API, Architecture Diagram + +![](./docs/cli-http-api-core-diagram.png) + +> [Origin](https://github.com/ipfs/pm/pull/678#discussion_r210410924) + +Description: Dotted means "likely going away". The "Legacy" parts are thin wrappers around some commands to translate between the new system and the old system. The grayed-out parts on the "daemon" diagram are there to show that the code is all the same, it's just that we turn some pieces on and some pieces off depending on whether we're running on the client or the server. + +### Testing + +``` +make test +``` + +### Development Dependencies + +If you make changes to the protocol buffers, you will need to install the [protoc compiler](https://github.com/google/protobuf). + +### Developer Notes + +Find more documentation for developers on [docs](./docs) + +## Contributing + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) + +We ❤️ all [our contributors](docs/AUTHORS); this project wouldn’t be what it is without you! If you want to help out, please see [CONTRIBUTING.md](CONTRIBUTING.md). + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +You can contact us on the freenode #ipfs-dev channel or attend one of our +[weekly calls](https://github.com/ipfs/team-mgmt/issues/674). + +## License + +[MIT](./LICENSE) diff --git a/vendor/github.com/ipfs/go-ipfs/Rules.mk b/vendor/github.com/ipfs/go-ipfs/Rules.mk new file mode 100644 index 00000000..d4bdf361 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/Rules.mk @@ -0,0 +1,150 @@ +TGT_BIN := +CLEAN := +COVERAGE := +DISTCLEAN := +TEST := +TEST_SHORT := +GOCC ?= go +PROTOC ?= protoc + +all: help # all has to be first defined target +.PHONY: all + +include mk/git.mk # has to be before tarball.mk +include mk/tarball.mk +include mk/util.mk +include mk/golang.mk + +# -------------------- # +# extra properties # +# -------------------- # + +ifeq ($(TEST_NO_FUSE),1) + GOTAGS += nofuse +endif +export IPFS_REUSEPORT=false + +# -------------------- # +# sub-files # +# -------------------- # +dir := bin +include $(dir)/Rules.mk + +# tests need access to rules from plugin +dir := plugin +include $(dir)/Rules.mk + +dir := test +include $(dir)/Rules.mk + +dir := cmd/ipfs +include $(dir)/Rules.mk + +# include this file only if coverage target is executed +# it is quite expensive +ifneq ($(filter coverage% clean distclean test/unit/gotest.junit.xml,$(MAKECMDGOALS)),) + # has to be after cmd/ipfs due to PATH + dir := coverage + include $(dir)/Rules.mk +endif + +dir := pin/internal/pb +include $(dir)/Rules.mk + +dir := filestore/pb +include $(dir)/Rules.mk + + +# -------------------- # +# universal rules # +# -------------------- # + +%.pb.go: %.proto bin/protoc-gen-gogofaster + $(PROTOC) --gogofaster_out=. --proto_path=.:$(GOPATH)/src:$(dir $@) $< + +# -------------------- # +# core targets # +# -------------------- # + +build: $(TGT_BIN) +.PHONY: build + +clean: + rm -rf $(CLEAN) +.PHONY: clean + +coverage: $(COVERAGE) +.PHONY: coverage + +distclean: clean + rm -rf $(DISTCLEAN) + git clean -ffxd +.PHONY: distclean + +test: $(TEST) +.PHONY: test + +test_short: $(TEST_SHORT) +.PHONY: test_short + +deps: +.PHONY: deps + +nofuse: GOTAGS += nofuse +nofuse: build +.PHONY: nofuse + +install: cmd/ipfs-install +.PHONY: install + +install_unsupported: install + @echo "/=======================================================================\\" + @echo '| |' + @echo '| `make install_unsupported` is deprecated, use `make install` instead. |' + @echo '| |' + @echo "\\=======================================================================/" +.PHONY: install_unsupported + +uninstall: + $(GOCC) clean -i ./cmd/ipfs +.PHONY: uninstall + +supported: + @echo "Currently supported platforms:" + @for p in ${SUPPORTED_PLATFORMS}; do echo $$p; done +.PHONY: supported + +help: + @echo 'DEPENDENCY TARGETS:' + @echo '' + @echo ' deps - Download dependencies using bundled gx' + @echo ' test_sharness_deps - Download and build dependencies for sharness' + @echo '' + @echo 'BUILD TARGETS:' + @echo '' + @echo ' all - print this help message' + @echo ' build - Build binary at ./cmd/ipfs/ipfs' + @echo ' nofuse - Build binary with no fuse support' + @echo ' install - Build binary and install into $$GOPATH/bin' +# @echo ' dist_install - TODO: c.f. ./cmd/ipfs/dist/README.md' + @echo '' + @echo 'CLEANING TARGETS:' + @echo '' + @echo ' clean - Remove files generated by build' + @echo ' distclean - Remove files that are no part of a repository' + @echo ' uninstall - Remove binary from $$GOPATH/bin' + @echo '' + @echo 'TESTING TARGETS:' + @echo '' + @echo ' test - Run all tests' + @echo ' test_short - Run short go tests and short sharness tests' + @echo ' test_go_short - Run short go tests' + @echo ' test_go_test - Run all go tests' + @echo ' test_go_expensive - Run all go tests and compile on all platforms' + @echo ' test_go_race - Run go tests with the race detector enabled' + @echo ' test_go_lint - Run the `golangci-lint` vetting tool' + @echo ' test_sharness_short - Run short sharness tests' + @echo ' test_sharness_expensive - Run all sharness tests' + @echo ' coverage - Collects coverage info from unit tests and sharness' + @echo +.PHONY: help diff --git a/vendor/github.com/ipfs/go-ipfs/appveyor.yml b/vendor/github.com/ipfs/go-ipfs/appveyor.yml new file mode 100644 index 00000000..696102ff --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/appveyor.yml @@ -0,0 +1,49 @@ +# Notes: +# - Minimal appveyor.yml file is an empty file. All sections are optional. +# - Indent each level of configuration with 2 spaces. Do not use tabs! +# - All section names are case-sensitive. +# - Section names should be unique on each level. + +version: "{build}" + +os: Windows Server 2012 R2 + +clone_folder: c:\gopath\src\github.com\ipfs\go-ipfs + +environment: + GOPATH: c:\gopath + TEST_VERBOSE: 1 + #TEST_NO_FUSE: 1 + #TEST_SUITE: test_sharness_expensive + #GOFLAGS: -tags nofuse + global: + BASH: C:\cygwin\bin\bash + matrix: + - GOARCH: amd64 + GOVERSION: 1.5.1 + GOROOT: c:\go + DOWNLOADPLATFORM: "x64" + +install: + # Enable make + #- SET PATH=c:\MinGW\bin;%PATH% + #- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe + - go version + - go env + +# Cygwin build script +# +# NOTES: +# +# The stdin/stdout file descriptor appears not to be valid for the Appveyor +# build which causes failures as certain functions attempt to redirect +# default file handles. Ensure a dummy file descriptor is opened with 'exec'. +# +build_script: + - '%BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0= cfg.MinPeerThreshold { + log.Event(ctx, "bootstrapSkip", id) + log.Debugf("%s core bootstrap skipped -- connected to %d (> %d) nodes", + id, len(connected), cfg.MinPeerThreshold) + return nil + } + numToDial := cfg.MinPeerThreshold - len(connected) + + // filter out bootstrap nodes we are already connected to + var notConnected []peer.AddrInfo + for _, p := range peers { + if host.Network().Connectedness(p.ID) != network.Connected { + notConnected = append(notConnected, p) + } + } + + // if connected to all bootstrap peer candidates, exit + if len(notConnected) < 1 { + log.Debugf("%s no more bootstrap peers to create %d connections", id, numToDial) + return ErrNotEnoughBootstrapPeers + } + + // connect to a random susbset of bootstrap candidates + randSubset := randomSubsetOfPeers(notConnected, numToDial) + + defer log.EventBegin(ctx, "bootstrapStart", id).Done() + log.Debugf("%s bootstrapping to %d nodes: %s", id, numToDial, randSubset) + return bootstrapConnect(ctx, host, randSubset) +} + +func bootstrapConnect(ctx context.Context, ph host.Host, peers []peer.AddrInfo) error { + if len(peers) < 1 { + return ErrNotEnoughBootstrapPeers + } + + errs := make(chan error, len(peers)) + var wg sync.WaitGroup + for _, p := range peers { + + // performed asynchronously because when performed synchronously, if + // one `Connect` call hangs, subsequent calls are more likely to + // fail/abort due to an expiring context. + // Also, performed asynchronously for dial speed. + + wg.Add(1) + go func(p peer.AddrInfo) { + defer wg.Done() + defer log.EventBegin(ctx, "bootstrapDial", ph.ID(), p.ID).Done() + log.Debugf("%s bootstrapping to %s", ph.ID(), p.ID) + + ph.Peerstore().AddAddrs(p.ID, p.Addrs, peerstore.PermanentAddrTTL) + if err := ph.Connect(ctx, p); err != nil { + log.Event(ctx, "bootstrapDialFailed", p.ID) + log.Debugf("failed to bootstrap with %v: %s", p.ID, err) + errs <- err + return + } + log.Event(ctx, "bootstrapDialSuccess", p.ID) + log.Infof("bootstrapped with %v", p.ID) + }(p) + } + wg.Wait() + + // our failure condition is when no connection attempt succeeded. + // So drain the errs channel, counting the results. + close(errs) + count := 0 + var err error + for err = range errs { + if err != nil { + count++ + } + } + if count == len(peers) { + return fmt.Errorf("failed to bootstrap. %s", err) + } + return nil +} + +func randomSubsetOfPeers(in []peer.AddrInfo, max int) []peer.AddrInfo { + if max > len(in) { + max = len(in) + } + + out := make([]peer.AddrInfo, max) + for i, val := range rand.Perm(len(in))[:max] { + out[i] = in[val] + } + return out +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/builder.go b/vendor/github.com/ipfs/go-ipfs/core/builder.go new file mode 100644 index 00000000..ff8fbd32 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/builder.go @@ -0,0 +1,65 @@ +package core + +import ( + "context" + "sync" + + "github.com/ipfs/go-ipfs/core/bootstrap" + "github.com/ipfs/go-ipfs/core/node" + + "github.com/ipfs/go-metrics-interface" + "go.uber.org/fx" +) + +type BuildCfg = node.BuildCfg // Alias for compatibility until we properly refactor the constructor interface + +// NewNode constructs and returns an IpfsNode using the given cfg. +func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { + ctx = metrics.CtxScope(ctx, "ipfs") + + n := &IpfsNode{ + ctx: ctx, + } + + app := fx.New( + node.IPFS(ctx, cfg), + + fx.NopLogger, + fx.Extract(n), + ) + + var once sync.Once + var stopErr error + n.stop = func() error { + once.Do(func() { + stopErr = app.Stop(context.Background()) + }) + return stopErr + } + n.IsOnline = cfg.Online + + go func() { + // Note that some services use contexts to signal shutting down, which is + // very suboptimal. This needs to be here until that's addressed somehow + <-ctx.Done() + err := n.stop() + if err != nil { + log.Error("failure on stop: ", err) + } + }() + + if app.Err() != nil { + return nil, app.Err() + } + + if err := app.Start(ctx); err != nil { + return nil, err + } + + // TODO: How soon will bootstrap move to libp2p? + if !cfg.Online { + return n, nil + } + + return n, n.Bootstrap(bootstrap.DefaultBootstrapConfig) +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/core.go b/vendor/github.com/ipfs/go-ipfs/core/core.go new file mode 100644 index 00000000..24535208 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/core.go @@ -0,0 +1,178 @@ +/* +Package core implements the IpfsNode object and related methods. + +Packages underneath core/ provide a (relatively) stable, low-level API +to carry out most IPFS-related tasks. For more details on the other +interfaces and how core/... fits into the bigger IPFS picture, see: + + $ godoc github.com/ipfs/go-ipfs +*/ +package core + +import ( + "context" + "io" + + version "github.com/ipfs/go-ipfs" + "github.com/ipfs/go-ipfs/core/bootstrap" + "github.com/ipfs/go-ipfs/core/node" + "github.com/ipfs/go-ipfs/core/node/libp2p" + "github.com/ipfs/go-ipfs/filestore" + "github.com/ipfs/go-ipfs/fuse/mount" + "github.com/ipfs/go-ipfs/namesys" + ipnsrp "github.com/ipfs/go-ipfs/namesys/republisher" + "github.com/ipfs/go-ipfs/p2p" + "github.com/ipfs/go-ipfs/pin" + "github.com/ipfs/go-ipfs/provider" + "github.com/ipfs/go-ipfs/repo" + + bserv "github.com/ipfs/go-blockservice" + bstore "github.com/ipfs/go-ipfs-blockstore" + exchange "github.com/ipfs/go-ipfs-exchange-interface" + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" + mfs "github.com/ipfs/go-mfs" + resolver "github.com/ipfs/go-path/resolver" + goprocess "github.com/jbenet/goprocess" + autonat "github.com/libp2p/go-libp2p-autonat-svc" + connmgr "github.com/libp2p/go-libp2p-core/connmgr" + ic "github.com/libp2p/go-libp2p-core/crypto" + p2phost "github.com/libp2p/go-libp2p-core/host" + metrics "github.com/libp2p/go-libp2p-core/metrics" + peer "github.com/libp2p/go-libp2p-core/peer" + pstore "github.com/libp2p/go-libp2p-core/peerstore" + routing "github.com/libp2p/go-libp2p-core/routing" + dht "github.com/libp2p/go-libp2p-kad-dht" + pubsub "github.com/libp2p/go-libp2p-pubsub" + psrouter "github.com/libp2p/go-libp2p-pubsub-router" + record "github.com/libp2p/go-libp2p-record" + "github.com/libp2p/go-libp2p/p2p/discovery" + p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" +) + +var log = logging.Logger("core") + +func init() { + identify.ClientVersion = "go-ipfs/" + version.CurrentVersionNumber + "/" + version.CurrentCommit +} + +// IpfsNode is IPFS Core module. It represents an IPFS instance. +type IpfsNode struct { + + // Self + Identity peer.ID // the local node's identity + + Repo repo.Repo + + // Local node + Pinning pin.Pinner // the pinning manager + Mounts Mounts `optional:"true"` // current mount state, if any. + PrivateKey ic.PrivKey `optional:"true"` // the local node's private Key + PNetFingerprint libp2p.PNetFingerprint `optional:"true"` // fingerprint of private network + + // Services + Peerstore pstore.Peerstore `optional:"true"` // storage for other Peer instances + Blockstore bstore.GCBlockstore // the block store (lower level) + Filestore *filestore.Filestore `optional:"true"` // the filestore blockstore + BaseBlocks node.BaseBlocks // the raw blockstore, no filestore wrapping + GCLocker bstore.GCLocker // the locker used to protect the blockstore during gc + Blocks bserv.BlockService // the block service, get/add blocks. + DAG ipld.DAGService // the merkle dag service, get/add objects. + Resolver *resolver.Resolver // the path resolution system + Reporter metrics.Reporter `optional:"true"` + Discovery discovery.Service `optional:"true"` + FilesRoot *mfs.Root + RecordValidator record.Validator + + // Online + PeerHost p2phost.Host `optional:"true"` // the network host (server+client) + Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper + Routing routing.Routing `optional:"true"` // the routing system. recommend ipfs-dht + Exchange exchange.Interface // the block exchange + strategy (bitswap) + Namesys namesys.NameSystem // the name system, resolves paths to hashes + Provider provider.System // the value provider system + IpnsRepub *ipnsrp.Republisher `optional:"true"` + + AutoNAT *autonat.AutoNATService `optional:"true"` + PubSub *pubsub.PubSub `optional:"true"` + PSRouter *psrouter.PubsubValueStore `optional:"true"` + DHT *dht.IpfsDHT `optional:"true"` + P2P *p2p.P2P `optional:"true"` + + Process goprocess.Process + ctx context.Context + + stop func() error + + // Flags + IsOnline bool `optional:"true"` // Online is set when networking is enabled. + IsDaemon bool `optional:"true"` // Daemon is set when running on a long-running daemon. +} + +// Mounts defines what the node's mount state is. This should +// perhaps be moved to the daemon or mount. It's here because +// it needs to be accessible across daemon requests. +type Mounts struct { + Ipfs mount.Mount + Ipns mount.Mount +} + +// Close calls Close() on the App object +func (n *IpfsNode) Close() error { + return n.stop() +} + +// Context returns the IpfsNode context +func (n *IpfsNode) Context() context.Context { + if n.ctx == nil { + n.ctx = context.TODO() + } + return n.ctx +} + +// Bootstrap will set and call the IpfsNodes bootstrap function. +func (n *IpfsNode) Bootstrap(cfg bootstrap.BootstrapConfig) error { + // TODO what should return value be when in offlineMode? + if n.Routing == nil { + return nil + } + + if n.Bootstrapper != nil { + n.Bootstrapper.Close() // stop previous bootstrap process. + } + + // if the caller did not specify a bootstrap peer function, get the + // freshest bootstrap peers from config. this responds to live changes. + if cfg.BootstrapPeers == nil { + cfg.BootstrapPeers = func() []peer.AddrInfo { + ps, err := n.loadBootstrapPeers() + if err != nil { + log.Warning("failed to parse bootstrap peers from config") + return nil + } + return ps + } + } + + var err error + n.Bootstrapper, err = bootstrap.Bootstrap(n.Identity, n.PeerHost, n.Routing, cfg) + return err +} + +func (n *IpfsNode) loadBootstrapPeers() ([]peer.AddrInfo, error) { + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + return cfg.BootstrapPeers() +} + +type ConstructPeerHostOpts struct { + AddrsFactory p2pbhost.AddrsFactory + DisableNatPortMap bool + DisableRelay bool + EnableRelayHop bool + ConnectionManager connmgr.ConnManager +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/coredag/cbor.go b/vendor/github.com/ipfs/go-ipfs/core/coredag/cbor.go new file mode 100644 index 00000000..b51a7057 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/coredag/cbor.go @@ -0,0 +1,32 @@ +package coredag + +import ( + "io" + "io/ioutil" + + ipldcbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" +) + +func cborJSONParser(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + nd, err := ipldcbor.FromJSON(r, mhType, mhLen) + if err != nil { + return nil, err + } + + return []ipld.Node{nd}, nil +} + +func cborRawParser(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + nd, err := ipldcbor.Decode(data, mhType, mhLen) + if err != nil { + return nil, err + } + + return []ipld.Node{nd}, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/coredag/dagpb.go b/vendor/github.com/ipfs/go-ipfs/core/coredag/dagpb.go new file mode 100644 index 00000000..0350ec5c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/coredag/dagpb.go @@ -0,0 +1,66 @@ +package coredag + +import ( + "io" + "io/ioutil" + "math" + + "github.com/ipfs/go-merkledag" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +func dagpbJSONParser(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + nd := &merkledag.ProtoNode{} + + err = nd.UnmarshalJSON(data) + if err != nil { + return nil, err + } + + nd.SetCidBuilder(cidPrefix(mhType, mhLen)) + + return []ipld.Node{nd}, nil +} + +func dagpbRawParser(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + nd, err := merkledag.DecodeProtobuf(data) + if err != nil { + return nil, err + } + + nd.SetCidBuilder(cidPrefix(mhType, mhLen)) + + return []ipld.Node{nd}, nil +} + +func cidPrefix(mhType uint64, mhLen int) *cid.Prefix { + if mhType == math.MaxUint64 { + mhType = mh.SHA2_256 + } + + prefix := &cid.Prefix{ + MhType: mhType, + MhLength: mhLen, + Version: 1, + Codec: cid.DagProtobuf, + } + + if mhType == mh.SHA2_256 { + prefix.Version = 0 + } + + return prefix +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/coredag/dagtransl.go b/vendor/github.com/ipfs/go-ipfs/core/coredag/dagtransl.go new file mode 100644 index 00000000..67a79246 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/coredag/dagtransl.go @@ -0,0 +1,86 @@ +package coredag + +import ( + "fmt" + "io" + + ipld "github.com/ipfs/go-ipld-format" +) + +// DagParser is function used for parsing stream into Node +type DagParser func(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) + +// FormatParsers is used for mapping format descriptors to DagParsers +type FormatParsers map[string]DagParser + +// InputEncParsers is used for mapping input encodings to FormatParsers +type InputEncParsers map[string]FormatParsers + +// DefaultInputEncParsers is InputEncParser that is used everywhere +var DefaultInputEncParsers = InputEncParsers{ + "json": defaultJSONParsers, + "raw": defaultRawParsers, + "cbor": defaultCborParsers, + "protobuf": defaultProtobufParsers, +} + +var defaultJSONParsers = FormatParsers{ + "cbor": cborJSONParser, + "dag-cbor": cborJSONParser, + + "protobuf": dagpbJSONParser, + "dag-pb": dagpbJSONParser, +} + +var defaultRawParsers = FormatParsers{ + "cbor": cborRawParser, + "dag-cbor": cborRawParser, + + "protobuf": dagpbRawParser, + "dag-pb": dagpbRawParser, + + "raw": rawRawParser, +} + +var defaultCborParsers = FormatParsers{ + "cbor": cborRawParser, + "dag-cbor": cborRawParser, +} + +var defaultProtobufParsers = FormatParsers{ + "protobuf": dagpbRawParser, + "dag-pb": dagpbRawParser, +} + +// ParseInputs uses DefaultInputEncParsers to parse io.Reader described by +// input encoding and format to an instance of ipld Node +func ParseInputs(ienc, format string, r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + return DefaultInputEncParsers.ParseInputs(ienc, format, r, mhType, mhLen) +} + +// AddParser adds DagParser under give input encoding and format +func (iep InputEncParsers) AddParser(ienc, format string, f DagParser) { + m, ok := iep[ienc] + if !ok { + m = make(FormatParsers) + iep[ienc] = m + } + + m[format] = f +} + +// ParseInputs parses io.Reader described by input encoding and format to +// an instance of ipld Node +func (iep InputEncParsers) ParseInputs(ienc, format string, r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + parsers, ok := iep[ienc] + if !ok { + return nil, fmt.Errorf("no input parser for %q", ienc) + } + + parser, ok := parsers[format] + if !ok { + return nil, fmt.Errorf("no parser for format %q using input type %q", format, ienc) + } + + return parser(r, mhType, mhLen) +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/coredag/raw.go b/vendor/github.com/ipfs/go-ipfs/core/coredag/raw.go new file mode 100644 index 00000000..03bbffac --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/coredag/raw.go @@ -0,0 +1,37 @@ +package coredag + +import ( + "io" + "io/ioutil" + "math" + + "github.com/ipfs/go-merkledag" + + block "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +func rawRawParser(r io.Reader, mhType uint64, mhLen int) ([]ipld.Node, error) { + if mhType == math.MaxUint64 { + mhType = mh.SHA2_256 + } + + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + h, err := mh.Sum(data, mhType, mhLen) + if err != nil { + return nil, err + } + c := cid.NewCidV1(cid.Raw, h) + blk, err := block.NewBlockWithCid(data, c) + if err != nil { + return nil, err + } + nd := &merkledag.RawNode{Block: blk} + return []ipld.Node{nd}, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/builder.go b/vendor/github.com/ipfs/go-ipfs/core/node/builder.go new file mode 100644 index 00000000..129ac0a3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/builder.go @@ -0,0 +1,151 @@ +package node + +import ( + "context" + "crypto/rand" + "encoding/base64" + "errors" + + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/core/node/libp2p" + "github.com/ipfs/go-ipfs/repo" + + ds "github.com/ipfs/go-datastore" + dsync "github.com/ipfs/go-datastore/sync" + cfg "github.com/ipfs/go-ipfs-config" + ci "github.com/libp2p/go-libp2p-core/crypto" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +type BuildCfg struct { + // If online is set, the node will have networking enabled + Online bool + + // ExtraOpts is a map of extra options used to configure the ipfs nodes creation + ExtraOpts map[string]bool + + // If permanent then node should run more expensive processes + // that will improve performance in long run + Permanent bool + + // DisableEncryptedConnections disables connection encryption *entirely*. + // DO NOT SET THIS UNLESS YOU'RE TESTING. + DisableEncryptedConnections bool + + // If NilRepo is set, a Repo backed by a nil datastore will be constructed + NilRepo bool + + Routing libp2p.RoutingOption + Host libp2p.HostOption + Repo repo.Repo +} + +func (cfg *BuildCfg) getOpt(key string) bool { + if cfg.ExtraOpts == nil { + return false + } + + return cfg.ExtraOpts[key] +} + +func (cfg *BuildCfg) fillDefaults() error { + if cfg.Repo != nil && cfg.NilRepo { + return errors.New("cannot set a Repo and specify nilrepo at the same time") + } + + if cfg.Repo == nil { + var d ds.Datastore + if cfg.NilRepo { + d = ds.NewNullDatastore() + } else { + d = ds.NewMapDatastore() + } + r, err := defaultRepo(dsync.MutexWrap(d)) + if err != nil { + return err + } + cfg.Repo = r + } + + if cfg.Routing == nil { + cfg.Routing = libp2p.DHTOption + } + + if cfg.Host == nil { + cfg.Host = libp2p.DefaultHostOption + } + + return nil +} + +// options creates fx option group from this build config +func (cfg *BuildCfg) options(ctx context.Context) (fx.Option, *cfg.Config) { + err := cfg.fillDefaults() + if err != nil { + return fx.Error(err), nil + } + + repoOption := fx.Provide(func(lc fx.Lifecycle) repo.Repo { + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return cfg.Repo.Close() + }, + }) + + return cfg.Repo + }) + + metricsCtx := fx.Provide(func() helpers.MetricsCtx { + return helpers.MetricsCtx(ctx) + }) + + hostOption := fx.Provide(func() libp2p.HostOption { + return cfg.Host + }) + + routingOption := fx.Provide(func() libp2p.RoutingOption { + return cfg.Routing + }) + + conf, err := cfg.Repo.Config() + if err != nil { + return fx.Error(err), nil + } + + return fx.Options( + repoOption, + hostOption, + routingOption, + metricsCtx, + ), conf +} + +func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { + c := cfg.Config{} + priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, rand.Reader) + if err != nil { + return nil, err + } + + pid, err := peer.IDFromPublicKey(pub) + if err != nil { + return nil, err + } + + privkeyb, err := priv.Bytes() + if err != nil { + return nil, err + } + + c.Bootstrap = cfg.DefaultBootstrapAddresses + c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001"} + c.Identity.PeerID = pid.Pretty() + c.Identity.PrivKey = base64.StdEncoding.EncodeToString(privkeyb) + + return &repo.Mock{ + D: dstore, + C: c, + }, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/core.go b/vendor/github.com/ipfs/go-ipfs/core/node/core.go new file mode 100644 index 00000000..ddb42aff --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/core.go @@ -0,0 +1,124 @@ +package node + +import ( + "context" + "fmt" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/pin" + "github.com/ipfs/go-ipfs/repo" + + "github.com/ipfs/go-bitswap" + "github.com/ipfs/go-bitswap/network" + "github.com/ipfs/go-blockservice" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-ipfs-blockstore" + "github.com/ipfs/go-ipfs-exchange-interface" + "github.com/ipfs/go-ipfs-exchange-offline" + "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-merkledag" + "github.com/ipfs/go-mfs" + "github.com/ipfs/go-unixfs" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/routing" + "go.uber.org/fx" +) + +// BlockService creates new blockservice which provides an interface to fetch content-addressable blocks +func BlockService(lc fx.Lifecycle, bs blockstore.Blockstore, rem exchange.Interface) blockservice.BlockService { + bsvc := blockservice.New(bs, rem) + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return bsvc.Close() + }, + }) + + return bsvc +} + +// Pinning creates new pinner which tells GC which blocks should be kept +func Pinning(bstore blockstore.Blockstore, ds format.DAGService, repo repo.Repo) (pin.Pinner, error) { + internalDag := merkledag.NewDAGService(blockservice.New(bstore, offline.Exchange(bstore))) + pinning, err := pin.LoadPinner(repo.Datastore(), ds, internalDag) + if err != nil { + // TODO: we should move towards only running 'NewPinner' explicitly on + // node init instead of implicitly here as a result of the pinner keys + // not being found in the datastore. + // this is kinda sketchy and could cause data loss + pinning = pin.NewPinner(repo.Datastore(), ds, internalDag) + } + + return pinning, nil +} + +// Dag creates new DAGService +func Dag(bs blockservice.BlockService) format.DAGService { + return merkledag.NewDAGService(bs) +} + +// OnlineExchange creates new LibP2P backed block exchange (BitSwap) +func OnlineExchange(provide bool) interface{} { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routing.Routing, bs blockstore.GCBlockstore) exchange.Interface { + bitswapNetwork := network.NewFromIpfsHost(host, rt) + exch := bitswap.New(helpers.LifecycleCtx(mctx, lc), bitswapNetwork, bs, bitswap.ProvideEnabled(provide)) + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return exch.Close() + }, + }) + return exch + + } +} + +// Files loads persisted MFS root +func Files(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo, dag format.DAGService) (*mfs.Root, error) { + dsk := datastore.NewKey("/local/filesroot") + pf := func(ctx context.Context, c cid.Cid) error { + return repo.Datastore().Put(dsk, c.Bytes()) + } + + var nd *merkledag.ProtoNode + val, err := repo.Datastore().Get(dsk) + ctx := helpers.LifecycleCtx(mctx, lc) + + switch { + case err == datastore.ErrNotFound || val == nil: + nd = unixfs.EmptyDirNode() + err := dag.Add(ctx, nd) + if err != nil { + return nil, fmt.Errorf("failure writing to dagstore: %s", err) + } + case err == nil: + c, err := cid.Cast(val) + if err != nil { + return nil, err + } + + rnd, err := dag.Get(ctx, c) + if err != nil { + return nil, fmt.Errorf("error loading filesroot from DAG: %s", err) + } + + pbnd, ok := rnd.(*merkledag.ProtoNode) + if !ok { + return nil, merkledag.ErrNotProtobuf + } + + nd = pbnd + default: + return nil, err + } + + root, err := mfs.NewRoot(ctx, dag, nd, pf) + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return root.Close() + }, + }) + + return root, err +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/groups.go b/vendor/github.com/ipfs/go-ipfs/core/node/groups.go new file mode 100644 index 00000000..1e5207b8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/groups.go @@ -0,0 +1,294 @@ +package node + +import ( + "context" + "errors" + "fmt" + "time" + + blockstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/ipfs/go-ipfs-config" + util "github.com/ipfs/go-ipfs-util" + peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-peerstore/pstoremem" + pubsub "github.com/libp2p/go-libp2p-pubsub" + + "github.com/ipfs/go-ipfs/core/node/libp2p" + "github.com/ipfs/go-ipfs/p2p" + + offline "github.com/ipfs/go-ipfs-exchange-offline" + offroute "github.com/ipfs/go-ipfs-routing/offline" + "github.com/ipfs/go-path/resolver" + uio "github.com/ipfs/go-unixfs/io" + "go.uber.org/fx" +) + +var BaseLibP2P = fx.Options( + fx.Provide(libp2p.PNet), + fx.Provide(libp2p.ConnectionManager), + fx.Provide(libp2p.DefaultTransports), + + fx.Provide(libp2p.Host), + + fx.Provide(libp2p.DiscoveryHandler), + + fx.Invoke(libp2p.PNetChecker), +) + +func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { + // parse ConnMgr config + + grace := config.DefaultConnMgrGracePeriod + low := config.DefaultConnMgrLowWater + high := config.DefaultConnMgrHighWater + + connmgr := fx.Options() + + if cfg.Swarm.ConnMgr.Type != "none" { + switch cfg.Swarm.ConnMgr.Type { + case "": + // 'default' value is the basic connection manager + break + case "basic": + var err error + grace, err = time.ParseDuration(cfg.Swarm.ConnMgr.GracePeriod) + if err != nil { + return fx.Error(fmt.Errorf("parsing Swarm.ConnMgr.GracePeriod: %s", err)) + } + + low = cfg.Swarm.ConnMgr.LowWater + high = cfg.Swarm.ConnMgr.HighWater + default: + return fx.Error(fmt.Errorf("unrecognized ConnMgr.Type: %q", cfg.Swarm.ConnMgr.Type)) + } + + connmgr = fx.Provide(libp2p.ConnectionManager(low, high, grace)) + } + + // parse PubSub config + + ps := fx.Options() + if bcfg.getOpt("pubsub") || bcfg.getOpt("ipnsps") { + var pubsubOptions []pubsub.Option + pubsubOptions = append( + pubsubOptions, + pubsub.WithMessageSigning(!cfg.Pubsub.DisableSigning), + pubsub.WithStrictSignatureVerification(cfg.Pubsub.StrictSignatureVerification), + ) + + switch cfg.Pubsub.Router { + case "": + fallthrough + case "floodsub": + ps = fx.Provide(libp2p.FloodSub(pubsubOptions...)) + case "gossipsub": + ps = fx.Provide(libp2p.GossipSub(pubsubOptions...)) + default: + return fx.Error(fmt.Errorf("unknown pubsub router %s", cfg.Pubsub.Router)) + } + } + + // Gather all the options + + opts := fx.Options( + BaseLibP2P, + + fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), + fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.NoAnnounce)), + fx.Provide(libp2p.SmuxTransport(bcfg.getOpt("mplex"))), + fx.Provide(libp2p.Relay(cfg.Swarm.DisableRelay, cfg.Swarm.EnableRelayHop)), + fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)), + fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled, cfg.Discovery.MDNS.Interval)), + + fx.Provide(libp2p.Security(!bcfg.DisableEncryptedConnections, cfg.Experimental.PreferTLS)), + + fx.Provide(libp2p.Routing), + fx.Provide(libp2p.BaseRouting), + maybeProvide(libp2p.PubsubRouter, bcfg.getOpt("ipnsps")), + + maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics), + maybeProvide(libp2p.NatPortMap, !cfg.Swarm.DisableNatPortMap), + maybeProvide(libp2p.AutoRealy, cfg.Swarm.EnableAutoRelay), + maybeProvide(libp2p.QUIC, cfg.Experimental.QUIC), + maybeInvoke(libp2p.AutoNATService(cfg.Experimental.QUIC), cfg.Swarm.EnableAutoNATService), + connmgr, + ps, + ) + + return opts +} + +// Storage groups units which setup datastore based persistence and blockstore layers +func Storage(bcfg *BuildCfg, cfg *config.Config) fx.Option { + cacheOpts := blockstore.DefaultCacheOpts() + cacheOpts.HasBloomFilterSize = cfg.Datastore.BloomFilterSize + if !bcfg.Permanent { + cacheOpts.HasBloomFilterSize = 0 + } + + finalBstore := fx.Provide(GcBlockstoreCtor) + if cfg.Experimental.FilestoreEnabled || cfg.Experimental.UrlstoreEnabled { + finalBstore = fx.Provide(FilestoreBlockstoreCtor) + } + + return fx.Options( + fx.Provide(RepoConfig), + fx.Provide(Datastore), + fx.Provide(BaseBlockstoreCtor(cacheOpts, bcfg.NilRepo, cfg.Datastore.HashOnRead)), + finalBstore, + ) +} + +// Identity groups units providing cryptographic identity +func Identity(cfg *config.Config) fx.Option { + // PeerID + + cid := cfg.Identity.PeerID + if cid == "" { + return fx.Error(errors.New("identity was not set in config (was 'ipfs init' run?)")) + } + if len(cid) == 0 { + return fx.Error(errors.New("no peer ID in config! (was 'ipfs init' run?)")) + } + + id, err := peer.IDB58Decode(cid) + if err != nil { + return fx.Error(fmt.Errorf("peer ID invalid: %s", err)) + } + + // Private Key + + if cfg.Identity.PrivKey == "" { + return fx.Options( // No PK (usually in tests) + fx.Provide(PeerID(id)), + fx.Provide(pstoremem.NewPeerstore), + ) + } + + sk, err := cfg.Identity.DecodePrivateKey("passphrase todo!") + if err != nil { + return fx.Error(err) + } + + return fx.Options( // Full identity + fx.Provide(PeerID(id)), + fx.Provide(PrivateKey(sk)), + fx.Provide(pstoremem.NewPeerstore), + + fx.Invoke(libp2p.PstoreAddSelfKeys), + ) +} + +// IPNS groups namesys related units +var IPNS = fx.Options( + fx.Provide(RecordValidator), +) + +// Online groups online-only units +func Online(bcfg *BuildCfg, cfg *config.Config) fx.Option { + + // Namesys params + + ipnsCacheSize := cfg.Ipns.ResolveCacheSize + if ipnsCacheSize == 0 { + ipnsCacheSize = DefaultIpnsCacheSize + } + if ipnsCacheSize < 0 { + return fx.Error(fmt.Errorf("cannot specify negative resolve cache size")) + } + + // Republisher params + + var repubPeriod, recordLifetime time.Duration + + if cfg.Ipns.RepublishPeriod != "" { + d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod) + if err != nil { + return fx.Error(fmt.Errorf("failure to parse config setting IPNS.RepublishPeriod: %s", err)) + } + + if !util.Debug && (d < time.Minute || d > (time.Hour*24)) { + return fx.Error(fmt.Errorf("config setting IPNS.RepublishPeriod is not between 1min and 1day: %s", d)) + } + + repubPeriod = d + } + + if cfg.Ipns.RecordLifetime != "" { + d, err := time.ParseDuration(cfg.Ipns.RecordLifetime) + if err != nil { + return fx.Error(fmt.Errorf("failure to parse config setting IPNS.RecordLifetime: %s", err)) + } + + recordLifetime = d + } + + /* don't provide from bitswap when the strategic provider service is active */ + shouldBitswapProvide := !cfg.Experimental.StrategicProviding + + return fx.Options( + fx.Provide(OnlineExchange(shouldBitswapProvide)), + fx.Provide(Namesys(ipnsCacheSize)), + + fx.Invoke(IpnsRepublisher(repubPeriod, recordLifetime)), + + fx.Provide(p2p.New), + + LibP2P(bcfg, cfg), + OnlineProviders(cfg.Experimental.StrategicProviding, cfg.Reprovider.Strategy, cfg.Reprovider.Interval), + ) +} + +// Offline groups offline alternatives to Online units +func Offline(cfg *config.Config) fx.Option { + return fx.Options( + fx.Provide(offline.Exchange), + fx.Provide(Namesys(0)), + fx.Provide(offroute.NewOfflineRouter), + OfflineProviders(cfg.Experimental.StrategicProviding, cfg.Reprovider.Strategy, cfg.Reprovider.Interval), + ) +} + +// Core groups basic IPFS services +var Core = fx.Options( + fx.Provide(BlockService), + fx.Provide(Dag), + fx.Provide(resolver.NewBasicResolver), + fx.Provide(Pinning), + fx.Provide(Files), +) + +func Networked(bcfg *BuildCfg, cfg *config.Config) fx.Option { + if bcfg.Online { + return Online(bcfg, cfg) + } + return Offline(cfg) +} + +// IPFS builds a group of fx Options based on the passed BuildCfg +func IPFS(ctx context.Context, bcfg *BuildCfg) fx.Option { + if bcfg == nil { + bcfg = new(BuildCfg) + } + + bcfgOpts, cfg := bcfg.options(ctx) + if cfg == nil { + return bcfgOpts // error + } + + // TEMP: setting global sharding switch here + uio.UseHAMTSharding = cfg.Experimental.ShardingEnabled + + return fx.Options( + bcfgOpts, + + fx.Provide(baseProcess), + + Storage(bcfg, cfg), + Identity(cfg), + IPNS, + Networked(bcfg, cfg), + + Core, + ) +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/helpers.go b/vendor/github.com/ipfs/go-ipfs/core/node/helpers.go new file mode 100644 index 00000000..9ecd8036 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/helpers.go @@ -0,0 +1,62 @@ +package node + +import ( + "context" + + "github.com/jbenet/goprocess" + "github.com/pkg/errors" + "go.uber.org/fx" +) + +type lcProcess struct { + fx.In + + LC fx.Lifecycle + Proc goprocess.Process +} + +// Append wraps ProcessFunc into a goprocess, and appends it to the lifecycle +func (lp *lcProcess) Append(f goprocess.ProcessFunc) { + // Hooks are guaranteed to run in sequence. If a hook fails to start, its + // OnStop won't be executed. + var proc goprocess.Process + + lp.LC.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + proc = lp.Proc.Go(f) + return nil + }, + OnStop: func(ctx context.Context) error { + if proc == nil { // Theoretically this shouldn't ever happen + return errors.New("lcProcess: proc was nil") + } + + return proc.Close() // todo: respect ctx, somehow + }, + }) +} + +func maybeProvide(opt interface{}, enable bool) fx.Option { + if enable { + return fx.Provide(opt) + } + return fx.Options() +} + +func maybeInvoke(opt interface{}, enable bool) fx.Option { + if enable { + return fx.Invoke(opt) + } + return fx.Options() +} + +// baseProcess creates a goprocess which is closed when the lifecycle signals it to stop +func baseProcess(lc fx.Lifecycle) goprocess.Process { + p := goprocess.WithParent(goprocess.Background()) + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + return p.Close() + }, + }) + return p +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/helpers/helpers.go b/vendor/github.com/ipfs/go-ipfs/core/node/helpers/helpers.go new file mode 100644 index 00000000..546c8e97 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/helpers/helpers.go @@ -0,0 +1,23 @@ +package helpers + +import ( + "context" + "go.uber.org/fx" +) + +type MetricsCtx context.Context + +// LifecycleCtx creates a context which will be cancelled when lifecycle stops +// +// This is a hack which we need because most of our services use contexts in a +// wrong way +func LifecycleCtx(mctx MetricsCtx, lc fx.Lifecycle) context.Context { + ctx, cancel := context.WithCancel(mctx) + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + cancel() + return nil + }, + }) + return ctx +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/identity.go b/vendor/github.com/ipfs/go-ipfs/core/node/identity.go new file mode 100644 index 00000000..ad6eb238 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/identity.go @@ -0,0 +1,29 @@ +package node + +import ( + "fmt" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +func PeerID(id peer.ID) func() peer.ID { + return func() peer.ID { + return id + } +} + +// PrivateKey loads the private key from config +func PrivateKey(sk crypto.PrivKey) func(id peer.ID) (crypto.PrivKey, error) { + return func(id peer.ID) (crypto.PrivKey, error) { + id2, err := peer.IDFromPrivateKey(sk) + if err != nil { + return nil, err + } + + if id2 != id { + return nil, fmt.Errorf("private key in config does not match id: %s != %s", id, id2) + } + return sk, nil + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/ipns.go b/vendor/github.com/ipfs/go-ipfs/core/node/ipns.go new file mode 100644 index 00000000..11769d97 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/ipns.go @@ -0,0 +1,56 @@ +package node + +import ( + "fmt" + "time" + + "github.com/ipfs/go-ipfs-util" + "github.com/ipfs/go-ipns" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/routing" + "github.com/libp2p/go-libp2p-record" + + "github.com/ipfs/go-ipfs/namesys" + "github.com/ipfs/go-ipfs/namesys/republisher" + "github.com/ipfs/go-ipfs/repo" +) + +const DefaultIpnsCacheSize = 128 + +// RecordValidator provides namesys compatible routing record validator +func RecordValidator(ps peerstore.Peerstore) record.Validator { + return record.NamespacedValidator{ + "pk": record.PublicKeyValidator{}, + "ipns": ipns.Validator{KeyBook: ps}, + } +} + +// Namesys creates new name system +func Namesys(cacheSize int) func(rt routing.Routing, repo repo.Repo) (namesys.NameSystem, error) { + return func(rt routing.Routing, repo repo.Repo) (namesys.NameSystem, error) { + return namesys.NewNameSystem(rt, repo.Datastore(), cacheSize), nil + } +} + +// IpnsRepublisher runs new IPNS republisher service +func IpnsRepublisher(repubPeriod time.Duration, recordLifetime time.Duration) func(lcProcess, namesys.NameSystem, repo.Repo, crypto.PrivKey) error { + return func(lc lcProcess, namesys namesys.NameSystem, repo repo.Repo, privKey crypto.PrivKey) error { + repub := republisher.NewRepublisher(namesys, repo.Datastore(), privKey, repo.Keystore()) + + if repubPeriod != 0 { + if !util.Debug && (repubPeriod < time.Minute || repubPeriod > (time.Hour*24)) { + return fmt.Errorf("config setting IPNS.RepublishPeriod is not between 1min and 1day: %s", repubPeriod) + } + + repub.Interval = repubPeriod + } + + if recordLifetime != 0 { + repub.RecordLifetime = recordLifetime + } + + lc.Append(repub.Run) + return nil + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/addrs.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/addrs.go new file mode 100644 index 00000000..703a959c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/addrs.go @@ -0,0 +1,117 @@ +package libp2p + +import ( + "fmt" + + "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-core/host" + p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" + mafilter "github.com/libp2p/go-maddr-filter" + ma "github.com/multiformats/go-multiaddr" + mamask "github.com/whyrusleeping/multiaddr-filter" +) + +func AddrFilters(filters []string) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + for _, s := range filters { + f, err := mamask.NewMask(s) + if err != nil { + return opts, fmt.Errorf("incorrectly formatted address filter in config: %s", s) + } + opts.Opts = append(opts.Opts, libp2p.FilterAddresses(f)) + } + return opts, nil + } +} + +func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFactory, error) { + var annAddrs []ma.Multiaddr + for _, addr := range announce { + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + annAddrs = append(annAddrs, maddr) + } + + filters := mafilter.NewFilters() + noAnnAddrs := map[string]bool{} + for _, addr := range noAnnounce { + f, err := mamask.NewMask(addr) + if err == nil { + filters.AddFilter(*f, mafilter.ActionDeny) + continue + } + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + noAnnAddrs[string(maddr.Bytes())] = true + } + + return func(allAddrs []ma.Multiaddr) []ma.Multiaddr { + var addrs []ma.Multiaddr + if len(annAddrs) > 0 { + addrs = annAddrs + } else { + addrs = allAddrs + } + + var out []ma.Multiaddr + for _, maddr := range addrs { + // check for exact matches + ok := noAnnAddrs[string(maddr.Bytes())] + // check for /ipcidr matches + if !ok && !filters.AddrBlocked(maddr) { + out = append(out, maddr) + } + } + return out + }, nil +} + +func AddrsFactory(announce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + addrsFactory, err := makeAddrsFactory(announce, noAnnounce) + if err != nil { + return opts, err + } + opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory)) + return + } +} + +func listenAddresses(addresses []string) ([]ma.Multiaddr, error) { + var listen []ma.Multiaddr + for _, addr := range addresses { + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + return nil, fmt.Errorf("failure to parse config.Addresses.Swarm: %s", addresses) + } + listen = append(listen, maddr) + } + + return listen, nil +} + +func StartListening(addresses []string) func(host host.Host) error { + return func(host host.Host) error { + listenAddrs, err := listenAddresses(addresses) + if err != nil { + return err + } + + // Actually start listening: + if err := host.Network().Listen(listenAddrs...); err != nil { + return err + } + + // list out our addresses + addrs, err := host.Network().InterfaceListenAddresses() + if err != nil { + return err + } + log.Infof("Swarm listening at: %s", addrs) + return nil + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/discovery.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/discovery.go new file mode 100644 index 00000000..7b0c8263 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/discovery.go @@ -0,0 +1,53 @@ +package libp2p + +import ( + "context" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/p2p/discovery" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" +) + +const discoveryConnTimeout = time.Second * 30 + +type discoveryHandler struct { + ctx context.Context + host host.Host +} + +func (dh *discoveryHandler) HandlePeerFound(p peer.AddrInfo) { + log.Warning("trying peer info: ", p) + ctx, cancel := context.WithTimeout(dh.ctx, discoveryConnTimeout) + defer cancel() + if err := dh.host.Connect(ctx, p); err != nil { + log.Warning("Failed to connect to peer found by discovery: ", err) + } +} + +func DiscoveryHandler(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) *discoveryHandler { + return &discoveryHandler{ + ctx: helpers.LifecycleCtx(mctx, lc), + host: host, + } +} + +func SetupDiscovery(mdns bool, mdnsInterval int) func(helpers.MetricsCtx, fx.Lifecycle, host.Host, *discoveryHandler) error { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, handler *discoveryHandler) error { + if mdns { + if mdnsInterval == 0 { + mdnsInterval = 5 + } + service, err := discovery.NewMdnsService(helpers.LifecycleCtx(mctx, lc), host, time.Duration(mdnsInterval)*time.Second, discovery.ServiceTag) + if err != nil { + log.Error("mdns error: ", err) + return nil + } + service.RegisterNotifee(handler) + } + return nil + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/host.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/host.go new file mode 100644 index 00000000..57475316 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/host.go @@ -0,0 +1,76 @@ +package libp2p + +import ( + "context" + + "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" + peerstore "github.com/libp2p/go-libp2p-core/peerstore" + routing "github.com/libp2p/go-libp2p-core/routing" + record "github.com/libp2p/go-libp2p-record" + routedhost "github.com/libp2p/go-libp2p/p2p/host/routed" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/repo" +) + +type P2PHostIn struct { + fx.In + + Repo repo.Repo + Validator record.Validator + HostOption HostOption + RoutingOption RoutingOption + ID peer.ID + Peerstore peerstore.Peerstore + + Opts [][]libp2p.Option `group:"libp2p"` +} + +type P2PHostOut struct { + fx.Out + + Host host.Host + Routing BaseIpfsRouting +} + +func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (out P2PHostOut, err error) { + opts := []libp2p.Option{libp2p.NoListenAddrs} + for _, o := range params.Opts { + opts = append(opts, o...) + } + + ctx := helpers.LifecycleCtx(mctx, lc) + + opts = append(opts, libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { + r, err := params.RoutingOption(ctx, h, params.Repo.Datastore(), params.Validator) + out.Routing = r + return r, err + })) + + out.Host, err = params.HostOption(ctx, params.ID, params.Peerstore, opts...) + if err != nil { + return P2PHostOut{}, err + } + + // this code is necessary just for tests: mock network constructions + // ignore the libp2p constructor options that actually construct the routing! + if out.Routing == nil { + r, err := params.RoutingOption(ctx, out.Host, params.Repo.Datastore(), params.Validator) + if err != nil { + return P2PHostOut{}, err + } + out.Routing = r + out.Host = routedhost.Wrap(out.Host, out.Routing) + } + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return out.Host.Close() + }, + }) + + return out, err +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/hostopt.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/hostopt.go new file mode 100644 index 00000000..26d6cad7 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/hostopt.go @@ -0,0 +1,25 @@ +package libp2p + +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" + peerstore "github.com/libp2p/go-libp2p-core/peerstore" +) + +type HostOption func(ctx context.Context, id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error) + +var DefaultHostOption HostOption = constructPeerHost + +// isolates the complex initialization steps +func constructPeerHost(ctx context.Context, id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error) { + pkey := ps.PrivKey(id) + if pkey == nil { + return nil, fmt.Errorf("missing private key for node ID: %s", id.Pretty()) + } + options = append([]libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(ps)}, options...) + return libp2p.New(ctx, options...) +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/libp2p.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/libp2p.go new file mode 100644 index 00000000..f0c84027 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/libp2p.go @@ -0,0 +1,46 @@ +package libp2p + +import ( + "time" + + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p-connmgr" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "go.uber.org/fx" +) + +var log = logging.Logger("p2pnode") + +type Libp2pOpts struct { + fx.Out + + Opts []libp2p.Option `group:"libp2p"` +} + +// Misc options + +func ConnectionManager(low, high int, grace time.Duration) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + cm := connmgr.NewConnManager(low, high, grace) + opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm)) + return + } +} + +func PstoreAddSelfKeys(id peer.ID, sk crypto.PrivKey, ps peerstore.Peerstore) error { + if err := ps.AddPubKey(id, sk.GetPublic()); err != nil { + return err + } + + return ps.AddPrivKey(id, sk) +} + +func simpleOpt(opt libp2p.Option) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + opts.Opts = append(opts.Opts, opt) + return + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/nat.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/nat.go new file mode 100644 index 00000000..6367d311 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/nat.go @@ -0,0 +1,32 @@ +package libp2p + +import ( + "github.com/libp2p/go-libp2p" + autonat "github.com/libp2p/go-libp2p-autonat-svc" + host "github.com/libp2p/go-libp2p-core/host" + libp2pquic "github.com/libp2p/go-libp2p-quic-transport" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/repo" +) + +var NatPortMap = simpleOpt(libp2p.NATPortMap()) + +func AutoNATService(quic bool) func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error { + return func(repo repo.Repo, mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) error { + // collect private net option in case swarm.key is presented + opts, _, err := PNet(repo) + if err != nil { + // swarm key exists but was failed to decode + return err + } + + if quic { + opts.Opts = append(opts.Opts, libp2p.DefaultTransports, libp2p.Transport(libp2pquic.NewTransport)) + } + + _, err = autonat.NewAutoNATService(helpers.LifecycleCtx(mctx, lc), host, opts.Opts...) + return err + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pnet.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pnet.go new file mode 100644 index 00000000..bf4cc556 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pnet.go @@ -0,0 +1,70 @@ +package libp2p + +import ( + "bytes" + "context" + "fmt" + "time" + + "github.com/libp2p/go-libp2p" + host "github.com/libp2p/go-libp2p-core/host" + pnet "github.com/libp2p/go-libp2p-pnet" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/repo" +) + +type PNetFingerprint []byte + +func PNet(repo repo.Repo) (opts Libp2pOpts, fp PNetFingerprint, err error) { + swarmkey, err := repo.SwarmKey() + if err != nil || swarmkey == nil { + return opts, nil, err + } + + protec, err := pnet.NewProtector(bytes.NewReader(swarmkey)) + if err != nil { + return opts, nil, fmt.Errorf("failed to configure private network: %s", err) + } + fp = protec.Fingerprint() + + opts.Opts = append(opts.Opts, libp2p.PrivateNetwork(protec)) + return opts, fp, nil +} + +func PNetChecker(repo repo.Repo, ph host.Host, lc fx.Lifecycle) error { + // TODO: better check? + swarmkey, err := repo.SwarmKey() + if err != nil || swarmkey == nil { + return err + } + + done := make(chan struct{}) + lc.Append(fx.Hook{ + OnStart: func(_ context.Context) error { + go func() { + t := time.NewTicker(30 * time.Second) + defer t.Stop() + + <-t.C // swallow one tick + for { + select { + case <-t.C: + if len(ph.Network().Peers()) == 0 { + log.Warning("We are in private network and have no peers.") + log.Warning("This might be configuration mistake.") + } + case <-done: + return + } + } + }() + return nil + }, + OnStop: func(_ context.Context) error { + close(done) + return nil + }, + }) + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pubsub.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pubsub.go new file mode 100644 index 00000000..c065cd7e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/pubsub.go @@ -0,0 +1,21 @@ +package libp2p + +import ( + host "github.com/libp2p/go-libp2p-core/host" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" +) + +func FloodSub(pubsubOptions ...pubsub.Option) interface{} { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) { + return pubsub.NewFloodSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...) + } +} + +func GossipSub(pubsubOptions ...pubsub.Option) interface{} { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host) (service *pubsub.PubSub, err error) { + return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, pubsubOptions...) + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/relay.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/relay.go new file mode 100644 index 00000000..b9e8afa4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/relay.go @@ -0,0 +1,24 @@ +package libp2p + +import ( + "github.com/libp2p/go-libp2p" + relay "github.com/libp2p/go-libp2p-circuit" +) + +func Relay(disable, enableHop bool) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + if disable { + // Enabled by default. + opts.Opts = append(opts.Opts, libp2p.DisableRelay()) + } else { + relayOpts := []relay.RelayOpt{relay.OptDiscovery} + if enableHop { + relayOpts = append(relayOpts, relay.OptHop) + } + opts.Opts = append(opts.Opts, libp2p.EnableRelay(relayOpts...)) + } + return + } +} + +var AutoRealy = simpleOpt(libp2p.EnableAutoRelay()) diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routing.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routing.go new file mode 100644 index 00000000..e5ba1de3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routing.go @@ -0,0 +1,106 @@ +package libp2p + +import ( + "context" + "sort" + + host "github.com/libp2p/go-libp2p-core/host" + routing "github.com/libp2p/go-libp2p-core/routing" + dht "github.com/libp2p/go-libp2p-kad-dht" + "github.com/libp2p/go-libp2p-pubsub" + namesys "github.com/libp2p/go-libp2p-pubsub-router" + record "github.com/libp2p/go-libp2p-record" + routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" +) + +type BaseIpfsRouting routing.Routing + +type Router struct { + routing.Routing + + Priority int // less = more important +} + +type p2pRouterOut struct { + fx.Out + + Router Router `group:"routers"` +} + +func BaseRouting(lc fx.Lifecycle, in BaseIpfsRouting) (out p2pRouterOut, dr *dht.IpfsDHT) { + if dht, ok := in.(*dht.IpfsDHT); ok { + dr = dht + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return dr.Close() + }, + }) + } + + return p2pRouterOut{ + Router: Router{ + Priority: 1000, + Routing: in, + }, + }, dr +} + +type p2pOnlineRoutingIn struct { + fx.In + + Routers []Router `group:"routers"` + Validator record.Validator +} + +func Routing(in p2pOnlineRoutingIn) routing.Routing { + routers := in.Routers + + sort.SliceStable(routers, func(i, j int) bool { + return routers[i].Priority < routers[j].Priority + }) + + irouters := make([]routing.Routing, len(routers)) + for i, v := range routers { + irouters[i] = v.Routing + } + + return routinghelpers.Tiered{ + Routers: irouters, + Validator: in.Validator, + } +} + +type p2pPSRoutingIn struct { + fx.In + + BaseIpfsRouting BaseIpfsRouting + Validator record.Validator + Host host.Host + PubSub *pubsub.PubSub `optional:"true"` +} + +func PubsubRouter(mctx helpers.MetricsCtx, lc fx.Lifecycle, in p2pPSRoutingIn) (p2pRouterOut, *namesys.PubsubValueStore) { + psRouter := namesys.NewPubsubValueStore( + helpers.LifecycleCtx(mctx, lc), + in.Host, + in.BaseIpfsRouting, + in.PubSub, + in.Validator, + ) + + return p2pRouterOut{ + Router: Router{ + Routing: &routinghelpers.Compose{ + ValueStore: &routinghelpers.LimitedValueStore{ + ValueStore: psRouter, + Namespaces: []string{"ipns"}, + }, + }, + Priority: 100, + }, + }, psRouter +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routingopt.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routingopt.go new file mode 100644 index 00000000..35389d85 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/routingopt.go @@ -0,0 +1,36 @@ +package libp2p + +import ( + "context" + + "github.com/ipfs/go-datastore" + nilrouting "github.com/ipfs/go-ipfs-routing/none" + host "github.com/libp2p/go-libp2p-core/host" + routing "github.com/libp2p/go-libp2p-core/routing" + dht "github.com/libp2p/go-libp2p-kad-dht" + dhtopts "github.com/libp2p/go-libp2p-kad-dht/opts" + record "github.com/libp2p/go-libp2p-record" +) + +type RoutingOption func(context.Context, host.Host, datastore.Batching, record.Validator) (routing.Routing, error) + +func constructDHTRouting(ctx context.Context, host host.Host, dstore datastore.Batching, validator record.Validator) (routing.Routing, error) { + return dht.New( + ctx, host, + dhtopts.Datastore(dstore), + dhtopts.Validator(validator), + ) +} + +func constructClientDHTRouting(ctx context.Context, host host.Host, dstore datastore.Batching, validator record.Validator) (routing.Routing, error) { + return dht.New( + ctx, host, + dhtopts.Client(true), + dhtopts.Datastore(dstore), + dhtopts.Validator(validator), + ) +} + +var DHTOption RoutingOption = constructDHTRouting +var DHTClientOption RoutingOption = constructClientDHTRouting +var NilRouterOption RoutingOption = nilrouting.ConstructNilRouting diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/smux.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/smux.go new file mode 100644 index 00000000..95e599ec --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/smux.go @@ -0,0 +1,54 @@ +package libp2p + +import ( + "os" + "strings" + + "github.com/libp2p/go-libp2p" + smux "github.com/libp2p/go-libp2p-core/mux" + mplex "github.com/libp2p/go-libp2p-mplex" + yamux "github.com/libp2p/go-libp2p-yamux" +) + +func makeSmuxTransportOption(mplexExp bool) libp2p.Option { + const yamuxID = "/yamux/1.0.0" + const mplexID = "/mplex/6.7.0" + + ymxtpt := *yamux.DefaultTransport + ymxtpt.AcceptBacklog = 512 + + if os.Getenv("YAMUX_DEBUG") != "" { + ymxtpt.LogOutput = os.Stderr + } + + muxers := map[string]smux.Multiplexer{yamuxID: &ymxtpt} + if mplexExp { + muxers[mplexID] = mplex.DefaultTransport + } + + // Allow muxer preference order overriding + order := []string{yamuxID, mplexID} + if prefs := os.Getenv("LIBP2P_MUX_PREFS"); prefs != "" { + order = strings.Fields(prefs) + } + + opts := make([]libp2p.Option, 0, len(order)) + for _, id := range order { + tpt, ok := muxers[id] + if !ok { + log.Warning("unknown or duplicate muxer in LIBP2P_MUX_PREFS: %s", id) + continue + } + delete(muxers, id) + opts = append(opts, libp2p.Muxer(id, tpt)) + } + + return libp2p.ChainOptions(opts...) +} + +func SmuxTransport(mplex bool) func() (opts Libp2pOpts, err error) { + return func() (opts Libp2pOpts, err error) { + opts.Opts = append(opts.Opts, makeSmuxTransportOption(mplex)) + return + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/transport.go b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/transport.go new file mode 100644 index 00000000..526776ab --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/libp2p/transport.go @@ -0,0 +1,38 @@ +package libp2p + +import ( + "github.com/libp2p/go-libp2p" + metrics "github.com/libp2p/go-libp2p-core/metrics" + libp2pquic "github.com/libp2p/go-libp2p-quic-transport" + secio "github.com/libp2p/go-libp2p-secio" + tls "github.com/libp2p/go-libp2p-tls" +) + +var DefaultTransports = simpleOpt(libp2p.DefaultTransports) +var QUIC = simpleOpt(libp2p.Transport(libp2pquic.NewTransport)) + +func Security(enabled, preferTLS bool) interface{} { + if !enabled { + return func() (opts Libp2pOpts) { + // TODO: shouldn't this be Errorf to guarantee visibility? + log.Warningf(`Your IPFS node has been configured to run WITHOUT ENCRYPTED CONNECTIONS. + You will not be able to connect to any nodes configured to use encrypted connections`) + opts.Opts = append(opts.Opts, libp2p.NoSecurity) + return opts + } + } + return func() (opts Libp2pOpts) { + if preferTLS { + opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(tls.ID, tls.New), libp2p.Security(secio.ID, secio.New))) + } else { + opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(secio.ID, secio.New), libp2p.Security(tls.ID, tls.New))) + } + return opts + } +} + +func BandwidthCounter() (opts Libp2pOpts, reporter metrics.Reporter) { + reporter = metrics.NewBandwidthCounter() + opts.Opts = append(opts.Opts, libp2p.BandwidthReporter(reporter)) + return opts, reporter +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/provider.go b/vendor/github.com/ipfs/go-ipfs/core/node/provider.go new file mode 100644 index 00000000..c87e2ac5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/provider.go @@ -0,0 +1,117 @@ +package node + +import ( + "context" + "fmt" + "time" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/provider" + q "github.com/ipfs/go-ipfs/provider/queue" + "github.com/ipfs/go-ipfs/provider/simple" + "github.com/ipfs/go-ipfs/repo" + "github.com/libp2p/go-libp2p-core/routing" + "go.uber.org/fx" +) + +const kReprovideFrequency = time.Hour * 12 + +// SIMPLE + +// ProviderQueue creates new datastore backed provider queue +func ProviderQueue(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (*q.Queue, error) { + return q.NewQueue(helpers.LifecycleCtx(mctx, lc), "provider-v1", repo.Datastore()) +} + +// SimpleProvider creates new record provider +func SimpleProvider(mctx helpers.MetricsCtx, lc fx.Lifecycle, queue *q.Queue, rt routing.Routing) provider.Provider { + return simple.NewProvider(helpers.LifecycleCtx(mctx, lc), queue, rt) +} + +// SimpleReprovider creates new reprovider +func SimpleReprovider(reproviderInterval time.Duration) interface{} { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, rt routing.Routing, keyProvider simple.KeyChanFunc) (provider.Reprovider, error) { + return simple.NewReprovider(helpers.LifecycleCtx(mctx, lc), reproviderInterval, rt, keyProvider), nil + } +} + +// SimpleProviderSys creates new provider system +func SimpleProviderSys(isOnline bool) interface{} { + return func(lc fx.Lifecycle, p provider.Provider, r provider.Reprovider) provider.System { + sys := provider.NewSystem(p, r) + + if isOnline { + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + sys.Run() + return nil + }, + OnStop: func(ctx context.Context) error { + return sys.Close() + }, + }) + } + + return sys + } +} + +// ONLINE/OFFLINE + +// OnlineProviders groups units managing provider routing records online +func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval string) fx.Option { + if useStrategicProviding { + return fx.Provide(provider.NewOfflineProvider) + } + + return fx.Options( + SimpleProviders(reprovideStrategy, reprovideInterval), + fx.Provide(SimpleProviderSys(true)), + ) +} + +// OfflineProviders groups units managing provider routing records offline +func OfflineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval string) fx.Option { + if useStrategicProviding { + return fx.Provide(provider.NewOfflineProvider) + } + + return fx.Options( + SimpleProviders(reprovideStrategy, reprovideInterval), + fx.Provide(SimpleProviderSys(false)), + ) +} + +// SimpleProviders creates the simple provider/reprovider dependencies +func SimpleProviders(reprovideStrategy string, reprovideInterval string) fx.Option { + reproviderInterval := kReprovideFrequency + if reprovideInterval != "" { + dur, err := time.ParseDuration(reprovideInterval) + if err != nil { + return fx.Error(err) + } + + reproviderInterval = dur + } + + var keyProvider fx.Option + switch reprovideStrategy { + case "all": + fallthrough + case "": + keyProvider = fx.Provide(simple.NewBlockstoreProvider) + case "roots": + keyProvider = fx.Provide(simple.NewPinnedProvider(true)) + case "pinned": + keyProvider = fx.Provide(simple.NewPinnedProvider(false)) + default: + return fx.Error(fmt.Errorf("unknown reprovider strategy '%s'", reprovideStrategy)) + } + + return fx.Options( + fx.Provide(ProviderQueue), + fx.Provide(SimpleProvider), + keyProvider, + fx.Provide(SimpleReprovider(reproviderInterval)), + ) +} diff --git a/vendor/github.com/ipfs/go-ipfs/core/node/storage.go b/vendor/github.com/ipfs/go-ipfs/core/node/storage.go new file mode 100644 index 00000000..008b1970 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/core/node/storage.go @@ -0,0 +1,94 @@ +package node + +import ( + "os" + "syscall" + "time" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/retrystore" + blockstore "github.com/ipfs/go-ipfs-blockstore" + config "github.com/ipfs/go-ipfs-config" + "go.uber.org/fx" + + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/filestore" + "github.com/ipfs/go-ipfs/repo" + "github.com/ipfs/go-ipfs/thirdparty/cidv0v1" + "github.com/ipfs/go-ipfs/thirdparty/verifbs" +) + +func isTooManyFDError(err error) bool { + perr, ok := err.(*os.PathError) + if ok && perr.Err == syscall.EMFILE { + return true + } + + return false +} + +// RepoConfig loads configuration from the repo +func RepoConfig(repo repo.Repo) (*config.Config, error) { + return repo.Config() +} + +// Datastore provides the datastore +func Datastore(repo repo.Repo) datastore.Datastore { + return repo.Datastore() +} + +// BaseBlocks is the lower level blockstore without GC or Filestore layers +type BaseBlocks blockstore.Blockstore + +// BaseBlockstoreCtor creates cached blockstore backed by the provided datastore +func BaseBlockstoreCtor(cacheOpts blockstore.CacheOpts, nilRepo bool, hashOnRead bool) func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) { + return func(mctx helpers.MetricsCtx, repo repo.Repo, lc fx.Lifecycle) (bs BaseBlocks, err error) { + rds := &retrystore.Datastore{ + Batching: repo.Datastore(), + Delay: time.Millisecond * 200, + Retries: 6, + TempErrFunc: isTooManyFDError, + } + // hash security + bs = blockstore.NewBlockstore(rds) + bs = &verifbs.VerifBS{Blockstore: bs} + + if !nilRepo { + bs, err = blockstore.CachedBlockstore(helpers.LifecycleCtx(mctx, lc), bs, cacheOpts) + if err != nil { + return nil, err + } + } + + bs = blockstore.NewIdStore(bs) + bs = cidv0v1.NewBlockstore(bs) + + if hashOnRead { // TODO: review: this is how it was done originally, is there a reason we can't just pass this directly? + bs.HashOnRead(true) + } + + return + } +} + +// GcBlockstoreCtor wraps the base blockstore with GC and Filestore layers +func GcBlockstoreCtor(bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore) { + gclocker = blockstore.NewGCLocker() + gcbs = blockstore.NewGCBlockstore(bb, gclocker) + + bs = gcbs + return +} + +// GcBlockstoreCtor wraps GcBlockstore and adds Filestore support +func FilestoreBlockstoreCtor(repo repo.Repo, bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) { + gclocker = blockstore.NewGCLocker() + + // hash security + fstore = filestore.NewFilestore(bb, repo.FileManager()) + gcbs = blockstore.NewGCBlockstore(fstore, gclocker) + gcbs = &verifbs.VerifBSGC{GCBlockstore: gcbs} + + bs = gcbs + return +} diff --git a/vendor/github.com/ipfs/go-ipfs/dagutils/diff.go b/vendor/github.com/ipfs/go-ipfs/dagutils/diff.go new file mode 100644 index 00000000..a43756ff --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/dagutils/diff.go @@ -0,0 +1,211 @@ +package dagutils + +import ( + "context" + "fmt" + "path" + + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + dag "github.com/ipfs/go-merkledag" + coreiface "github.com/ipfs/interface-go-ipfs-core" +) + +// These constants define the changes that can be applied to a DAG. +const ( + Add = iota + Remove + Mod +) + +// Change represents a change to a DAG and contains a reference to the old and +// new CIDs. +type Change struct { + Type coreiface.ChangeType + Path string + Before cid.Cid + After cid.Cid +} + +// String prints a human-friendly line about a change. +func (c *Change) String() string { + switch c.Type { + case Add: + return fmt.Sprintf("Added %s at %s", c.After.String(), c.Path) + case Remove: + return fmt.Sprintf("Removed %s from %s", c.Before.String(), c.Path) + case Mod: + return fmt.Sprintf("Changed %s to %s at %s", c.Before.String(), c.After.String(), c.Path) + default: + panic("nope") + } +} + +// ApplyChange applies the requested changes to the given node in the given dag. +func ApplyChange(ctx context.Context, ds ipld.DAGService, nd *dag.ProtoNode, cs []*Change) (*dag.ProtoNode, error) { + e := NewDagEditor(nd, ds) + for _, c := range cs { + switch c.Type { + case Add: + child, err := ds.Get(ctx, c.After) + if err != nil { + return nil, err + } + + childpb, ok := child.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + err = e.InsertNodeAtPath(ctx, c.Path, childpb, nil) + if err != nil { + return nil, err + } + + case Remove: + err := e.RmLink(ctx, c.Path) + if err != nil { + return nil, err + } + + case Mod: + err := e.RmLink(ctx, c.Path) + if err != nil { + return nil, err + } + child, err := ds.Get(ctx, c.After) + if err != nil { + return nil, err + } + + childpb, ok := child.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + err = e.InsertNodeAtPath(ctx, c.Path, childpb, nil) + if err != nil { + return nil, err + } + } + } + + return e.Finalize(ctx, ds) +} + +// Diff returns a set of changes that transform node 'a' into node 'b'. +// It only traverses links in the following cases: +// 1. two node's links number are greater than 0. +// 2. both of two nodes are ProtoNode. +// Otherwise, it compares the cid and emits a Mod change object. +func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) { + // Base case where both nodes are leaves, just compare + // their CIDs. + if len(a.Links()) == 0 && len(b.Links()) == 0 { + return getChange(a, b) + } + + var out []*Change + cleanA, okA := a.Copy().(*dag.ProtoNode) + cleanB, okB := b.Copy().(*dag.ProtoNode) + if !okA || !okB { + return getChange(a, b) + } + + // strip out unchanged stuff + for _, lnk := range a.Links() { + l, _, err := b.ResolveLink([]string{lnk.Name}) + if err == nil { + if l.Cid.Equals(lnk.Cid) { + // no change... ignore it + } else { + anode, err := lnk.GetNode(ctx, ds) + if err != nil { + return nil, err + } + + bnode, err := l.GetNode(ctx, ds) + if err != nil { + return nil, err + } + + sub, err := Diff(ctx, ds, anode, bnode) + if err != nil { + return nil, err + } + + for _, subc := range sub { + subc.Path = path.Join(lnk.Name, subc.Path) + out = append(out, subc) + } + } + _ = cleanA.RemoveNodeLink(l.Name) + _ = cleanB.RemoveNodeLink(l.Name) + } + } + + for _, lnk := range cleanA.Links() { + out = append(out, &Change{ + Type: Remove, + Path: lnk.Name, + Before: lnk.Cid, + }) + } + for _, lnk := range cleanB.Links() { + out = append(out, &Change{ + Type: Add, + Path: lnk.Name, + After: lnk.Cid, + }) + } + + return out, nil +} + +// Conflict represents two incompatible changes and is returned by MergeDiffs(). +type Conflict struct { + A *Change + B *Change +} + +// MergeDiffs takes two slice of changes and adds them to a single slice. +// When a Change from b happens to the same path of an existing change in a, +// a conflict is created and b is not added to the merged slice. +// A slice of Conflicts is returned and contains pointers to the +// Changes involved (which share the same path). +func MergeDiffs(a, b []*Change) ([]*Change, []Conflict) { + var out []*Change + var conflicts []Conflict + paths := make(map[string]*Change) + for _, c := range a { + paths[c.Path] = c + } + + for _, c := range b { + if ca, ok := paths[c.Path]; ok { + conflicts = append(conflicts, Conflict{ + A: ca, + B: c, + }) + } else { + out = append(out, c) + } + } + for _, c := range paths { + out = append(out, c) + } + return out, conflicts +} + +func getChange(a, b ipld.Node) ([]*Change, error) { + if a.Cid().Equals(b.Cid()) { + return []*Change{}, nil + } + return []*Change{ + { + Type: Mod, + Before: a.Cid(), + After: b.Cid(), + }, + }, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/dagutils/diffenum.go b/vendor/github.com/ipfs/go-ipfs/dagutils/diffenum.go new file mode 100644 index 00000000..4ec74b2d --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/dagutils/diffenum.go @@ -0,0 +1,99 @@ +package dagutils + +import ( + "context" + "fmt" + + mdag "github.com/ipfs/go-merkledag" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// DiffEnumerate fetches every object in the graph pointed to by 'to' that is +// not in 'from'. This can be used to more efficiently fetch a graph if you can +// guarantee you already have the entirety of 'from' +func DiffEnumerate(ctx context.Context, dserv ipld.NodeGetter, from, to cid.Cid) error { + fnd, err := dserv.Get(ctx, from) + if err != nil { + return fmt.Errorf("get %s: %s", from, err) + } + + tnd, err := dserv.Get(ctx, to) + if err != nil { + return fmt.Errorf("get %s: %s", to, err) + } + + diff := getLinkDiff(fnd, tnd) + + sset := cid.NewSet() + for _, c := range diff { + // Since we're already assuming we have everything in the 'from' graph, + // add all those cids to our 'already seen' set to avoid potentially + // enumerating them later + if c.bef.Defined() { + sset.Add(c.bef) + } + } + for _, c := range diff { + if !c.bef.Defined() { + if sset.Has(c.aft) { + continue + } + err := mdag.EnumerateChildrenAsync(ctx, mdag.GetLinksDirect(dserv), c.aft, sset.Visit) + if err != nil { + return err + } + } else { + err := DiffEnumerate(ctx, dserv, c.bef, c.aft) + if err != nil { + return err + } + } + } + + return nil +} + +// if both bef and aft are not nil, then that signifies bef was replaces with aft. +// if bef is nil and aft is not, that means aft was newly added +// if aft is nil and bef is not, that means bef was deleted +type diffpair struct { + bef, aft cid.Cid +} + +// getLinkDiff returns a changeset between nodes 'a' and 'b'. Currently does +// not log deletions as our usecase doesnt call for this. +func getLinkDiff(a, b ipld.Node) []diffpair { + ina := make(map[string]*ipld.Link) + inb := make(map[string]*ipld.Link) + var aonly []cid.Cid + for _, l := range b.Links() { + inb[l.Cid.KeyString()] = l + } + for _, l := range a.Links() { + var key = l.Cid.KeyString() + ina[key] = l + if inb[key] == nil { + aonly = append(aonly, l.Cid) + } + } + + var out []diffpair + var aindex int + + for _, l := range b.Links() { + if ina[l.Cid.KeyString()] != nil { + continue + } + + if aindex < len(aonly) { + out = append(out, diffpair{bef: aonly[aindex], aft: l.Cid}) + aindex++ + } else { + out = append(out, diffpair{aft: l.Cid}) + continue + } + } + return out +} diff --git a/vendor/github.com/ipfs/go-ipfs/dagutils/utils.go b/vendor/github.com/ipfs/go-ipfs/dagutils/utils.go new file mode 100644 index 00000000..3a796a9c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/dagutils/utils.go @@ -0,0 +1,234 @@ +package dagutils + +import ( + "context" + "errors" + + bserv "github.com/ipfs/go-blockservice" + dag "github.com/ipfs/go-merkledag" + path "github.com/ipfs/go-path" + + ds "github.com/ipfs/go-datastore" + syncds "github.com/ipfs/go-datastore/sync" + bstore "github.com/ipfs/go-ipfs-blockstore" + offline "github.com/ipfs/go-ipfs-exchange-offline" + ipld "github.com/ipfs/go-ipld-format" +) + +// Editor represents a ProtoNode tree editor and provides methods to +// modify it. +type Editor struct { + root *dag.ProtoNode + + // tmp is a temporary in memory (for now) dagstore for all of the + // intermediary nodes to be stored in + tmp ipld.DAGService + + // src is the dagstore with *all* of the data on it, it is used to pull + // nodes from for modification (nil is a valid value) + src ipld.DAGService +} + +// NewMemoryDagService returns a new, thread-safe in-memory DAGService. +func NewMemoryDagService() ipld.DAGService { + // build mem-datastore for editor's intermediary nodes + bs := bstore.NewBlockstore(syncds.MutexWrap(ds.NewMapDatastore())) + bsrv := bserv.New(bs, offline.Exchange(bs)) + return dag.NewDAGService(bsrv) +} + +// NewDagEditor returns an ProtoNode editor. +// +// * root is the node to be modified +// * source is the dagstore to pull nodes from (optional) +func NewDagEditor(root *dag.ProtoNode, source ipld.DAGService) *Editor { + return &Editor{ + root: root, + tmp: NewMemoryDagService(), + src: source, + } +} + +// GetNode returns the a copy of the root node being edited. +func (e *Editor) GetNode() *dag.ProtoNode { + return e.root.Copy().(*dag.ProtoNode) +} + +// GetDagService returns the DAGService used by this editor. +func (e *Editor) GetDagService() ipld.DAGService { + return e.tmp +} + +func addLink(ctx context.Context, ds ipld.DAGService, root *dag.ProtoNode, childname string, childnd ipld.Node) (*dag.ProtoNode, error) { + if childname == "" { + return nil, errors.New("cannot create link with no name") + } + + // ensure that the node we are adding is in the dagservice + err := ds.Add(ctx, childnd) + if err != nil { + return nil, err + } + + _ = ds.Remove(ctx, root.Cid()) + + // ensure no link with that name already exists + _ = root.RemoveNodeLink(childname) // ignore error, only option is ErrNotFound + + if err := root.AddNodeLink(childname, childnd); err != nil { + return nil, err + } + + if err := ds.Add(ctx, root); err != nil { + return nil, err + } + return root, nil +} + +// InsertNodeAtPath inserts a new node in the tree and replaces the current root with the new one. +func (e *Editor) InsertNodeAtPath(ctx context.Context, pth string, toinsert ipld.Node, create func() *dag.ProtoNode) error { + splpath := path.SplitList(pth) + nd, err := e.insertNodeAtPath(ctx, e.root, splpath, toinsert, create) + if err != nil { + return err + } + e.root = nd + return nil +} + +func (e *Editor) insertNodeAtPath(ctx context.Context, root *dag.ProtoNode, path []string, toinsert ipld.Node, create func() *dag.ProtoNode) (*dag.ProtoNode, error) { + if len(path) == 1 { + return addLink(ctx, e.tmp, root, path[0], toinsert) + } + + nd, err := root.GetLinkedProtoNode(ctx, e.tmp, path[0]) + if err != nil { + // if 'create' is true, we create directories on the way down as needed + if err == dag.ErrLinkNotFound && create != nil { + nd = create() + err = nil // no longer an error case + } else if err == ipld.ErrNotFound { + // try finding it in our source dagstore + nd, err = root.GetLinkedProtoNode(ctx, e.src, path[0]) + } + + // if we receive an ErrNotFound, then our second 'GetLinkedNode' call + // also fails, we want to error out + if err != nil { + return nil, err + } + } + + ndprime, err := e.insertNodeAtPath(ctx, nd, path[1:], toinsert, create) + if err != nil { + return nil, err + } + + _ = e.tmp.Remove(ctx, root.Cid()) + + _ = root.RemoveNodeLink(path[0]) + err = root.AddNodeLink(path[0], ndprime) + if err != nil { + return nil, err + } + + err = e.tmp.Add(ctx, root) + if err != nil { + return nil, err + } + + return root, nil +} + +// RmLink removes the link with the given name and updates the root node of +// the editor. +func (e *Editor) RmLink(ctx context.Context, pth string) error { + splpath := path.SplitList(pth) + nd, err := e.rmLink(ctx, e.root, splpath) + if err != nil { + return err + } + e.root = nd + return nil +} + +func (e *Editor) rmLink(ctx context.Context, root *dag.ProtoNode, path []string) (*dag.ProtoNode, error) { + if len(path) == 1 { + // base case, remove node in question + err := root.RemoveNodeLink(path[0]) + if err != nil { + return nil, err + } + + err = e.tmp.Add(ctx, root) + if err != nil { + return nil, err + } + + return root, nil + } + + // search for node in both tmp dagstore and source dagstore + nd, err := root.GetLinkedProtoNode(ctx, e.tmp, path[0]) + if err == ipld.ErrNotFound { + nd, err = root.GetLinkedProtoNode(ctx, e.src, path[0]) + } + + if err != nil { + return nil, err + } + + nnode, err := e.rmLink(ctx, nd, path[1:]) + if err != nil { + return nil, err + } + + _ = e.tmp.Remove(ctx, root.Cid()) + + _ = root.RemoveNodeLink(path[0]) + err = root.AddNodeLink(path[0], nnode) + if err != nil { + return nil, err + } + + err = e.tmp.Add(ctx, root) + if err != nil { + return nil, err + } + + return root, nil +} + +// Finalize writes the new DAG to the given DAGService and returns the modified +// root node. +func (e *Editor) Finalize(ctx context.Context, ds ipld.DAGService) (*dag.ProtoNode, error) { + nd := e.GetNode() + err := copyDag(ctx, nd, e.tmp, ds) + return nd, err +} + +func copyDag(ctx context.Context, nd ipld.Node, from, to ipld.DAGService) error { + // TODO(#4609): make this batch. + err := to.Add(ctx, nd) + if err != nil { + return err + } + + for _, lnk := range nd.Links() { + child, err := lnk.GetNode(ctx, from) + if err != nil { + if err == ipld.ErrNotFound { + // not found means we didnt modify it, and it should + // already be in the target datastore + continue + } + return err + } + + err = copyDag(ctx, child, from, to) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/doc.go b/vendor/github.com/ipfs/go-ipfs/doc.go new file mode 100644 index 00000000..1183559a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/doc.go @@ -0,0 +1,4 @@ +/* +IPFS is a global, versioned, peer-to-peer filesystem +*/ +package ipfs diff --git a/vendor/github.com/ipfs/go-ipfs/docs/AUTHORS b/vendor/github.com/ipfs/go-ipfs/docs/AUTHORS new file mode 100644 index 00000000..85a6e160 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/docs/AUTHORS @@ -0,0 +1,112 @@ +# This file lists all individuals having contributed content to the repository. +# For how it is generated, see `docs/generate-authors.sh`. + +Aaron Hill +Adam Gashlin +Adrian Ulrich +Alex +anarcat +Andres Buritica +Andrew Chin +Andy Leap +Artem Andreenko +Baptiste Jonglez +Brendan Benshoof +Brendan Mc +Brian Tiger Chow +Caio Alonso +Carlos Cobo +Cayman Nava +Chas Leichner +Chris Grimmett +Chris P +Chris Sasarak +Christian Couder +Christian Kniep +Christopher Sasarak +David +David Braun +David Dias +David Wagner +dignifiedquire +Dominic Della Valle +Dominic Tarr +drathir +Dylan Powers +Emery Hemingway +epitron +Ethan Buchman +Etienne Laurin +Forrest Weston +Francesco Canessa +gatesvp +Giuseppe Bertone +Harlan T Wood +Hector Sanjuan +Henry +Ho-Sheng Hsiao +Jakub Sztandera +Jason Carver +Jonathan Dahan +Juan Batiz-Benet +Karthik Bala +Kevin Atkinson +Kevin Wallace +klauspost +Knut Ahlers +Konstantin Koroviev +kpcyrd +Kristoffer Ström +Lars Gierth +llSourcell +Marcin Janczyk +Marcin Rataj +Markus Amalthea Magnuson +michael +Michael Lovci +Michael Muré +Michael Pfister +Mildred Ki'Lya +Muneeb Ali +Nick Hamann +palkeo +Patrick Connolly +Pavol Rusnak +Peter Borzov +Philip Nelson +Quinn Slack +ReadmeCritic +rht +Richard Littauer +Robert Carlsen +Roerick Sweeney +Sean Lang +SH +Shanti Bouchez-Mongardé +Shaun Bruce +Simon Kirkby +Siraj Ravel +Siva Chandran +slothbag +sroerick +Stephan Seidt +Stephen Sugden +Stephen Whitmore +Steven Allen +Tarnay Kálmán +theswitch +Thomas Gardner +Tim Groeneveld +Tommi Virtanen +Tonis Tiigi +Tor Arne Vestbø +Travis Person +verokarhu +Vijayee Kulkaa +Vitor Baptista +vitzli +W. Trevor King +Whyrusleeping +wzhd +Yuval Langer +ᴍᴀᴛᴛ ʙᴇʟʟ diff --git a/vendor/github.com/ipfs/go-ipfs/docs/generate-authors.sh b/vendor/github.com/ipfs/go-ipfs/docs/generate-authors.sh new file mode 100755 index 00000000..75b33b7e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/docs/generate-authors.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +# see also ".mailmap" for how email addresses and names are deduplicated + + +cat >AUTHORS <<-'EOF' +# This file lists all individuals having contributed content to the repository. +# For how it is generated, see `docs/generate-authors.sh`. + +EOF +git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf >>AUTHORS diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/filestore.go b/vendor/github.com/ipfs/go-ipfs/filestore/filestore.go new file mode 100644 index 00000000..be4d954b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/filestore.go @@ -0,0 +1,251 @@ +// Package filestore implements a Blockstore which is able to read certain +// blocks of data directly from its original location in the filesystem. +// +// In a Filestore, object leaves are stored as FilestoreNodes. FilestoreNodes +// include a filesystem path and an offset, allowing a Blockstore dealing with +// such blocks to avoid storing the whole contents and reading them from their +// filesystem location instead. +package filestore + +import ( + "context" + "errors" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + dsq "github.com/ipfs/go-datastore/query" + blockstore "github.com/ipfs/go-ipfs-blockstore" + posinfo "github.com/ipfs/go-ipfs-posinfo" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("filestore") + +var ErrFilestoreNotEnabled = errors.New("filestore is not enabled, see https://git.io/vNItf") +var ErrUrlstoreNotEnabled = errors.New("urlstore is not enabled") + +// Filestore implements a Blockstore by combining a standard Blockstore +// to store regular blocks and a special Blockstore called +// FileManager to store blocks which data exists in an external file. +type Filestore struct { + fm *FileManager + bs blockstore.Blockstore +} + +// FileManager returns the FileManager in Filestore. +func (f *Filestore) FileManager() *FileManager { + return f.fm +} + +// MainBlockstore returns the standard Blockstore in the Filestore. +func (f *Filestore) MainBlockstore() blockstore.Blockstore { + return f.bs +} + +// NewFilestore creates one using the given Blockstore and FileManager. +func NewFilestore(bs blockstore.Blockstore, fm *FileManager) *Filestore { + return &Filestore{fm, bs} +} + +// AllKeysChan returns a channel from which to read the keys stored in +// the blockstore. If the given context is cancelled the channel will be closed. +func (f *Filestore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + ctx, cancel := context.WithCancel(ctx) + + a, err := f.bs.AllKeysChan(ctx) + if err != nil { + cancel() + return nil, err + } + + out := make(chan cid.Cid, dsq.KeysOnlyBufSize) + go func() { + defer cancel() + defer close(out) + + var done bool + for !done { + select { + case c, ok := <-a: + if !ok { + done = true + continue + } + select { + case out <- c: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + + // Can't do these at the same time because the abstractions around + // leveldb make us query leveldb for both operations. We apparently + // cant query leveldb concurrently + b, err := f.fm.AllKeysChan(ctx) + if err != nil { + log.Error("error querying filestore: ", err) + return + } + + done = false + for !done { + select { + case c, ok := <-b: + if !ok { + done = true + continue + } + select { + case out <- c: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + return out, nil +} + +// DeleteBlock deletes the block with the given key from the +// blockstore. As expected, in the case of FileManager blocks, only the +// reference is deleted, not its contents. It may return +// ErrNotFound when the block is not stored. +func (f *Filestore) DeleteBlock(c cid.Cid) error { + err1 := f.bs.DeleteBlock(c) + if err1 != nil && err1 != blockstore.ErrNotFound { + return err1 + } + + err2 := f.fm.DeleteBlock(c) + // if we successfully removed something from the blockstore, but the + // filestore didnt have it, return success + + switch err2 { + case nil: + return nil + case blockstore.ErrNotFound: + if err1 == blockstore.ErrNotFound { + return blockstore.ErrNotFound + } + return nil + default: + return err2 + } +} + +// Get retrieves the block with the given Cid. It may return +// ErrNotFound when the block is not stored. +func (f *Filestore) Get(c cid.Cid) (blocks.Block, error) { + blk, err := f.bs.Get(c) + switch err { + case nil: + return blk, nil + case blockstore.ErrNotFound: + return f.fm.Get(c) + default: + return nil, err + } +} + +// GetSize returns the size of the requested block. It may return ErrNotFound +// when the block is not stored. +func (f *Filestore) GetSize(c cid.Cid) (int, error) { + size, err := f.bs.GetSize(c) + switch err { + case nil: + return size, nil + case blockstore.ErrNotFound: + return f.fm.GetSize(c) + default: + return -1, err + } +} + +// Has returns true if the block with the given Cid is +// stored in the Filestore. +func (f *Filestore) Has(c cid.Cid) (bool, error) { + has, err := f.bs.Has(c) + if err != nil { + return false, err + } + + if has { + return true, nil + } + + return f.fm.Has(c) +} + +// Put stores a block in the Filestore. For blocks of +// underlying type FilestoreNode, the operation is +// delegated to the FileManager, while the rest of blocks +// are handled by the regular blockstore. +func (f *Filestore) Put(b blocks.Block) error { + has, err := f.Has(b.Cid()) + if err != nil { + return err + } + + if has { + return nil + } + + switch b := b.(type) { + case *posinfo.FilestoreNode: + return f.fm.Put(b) + default: + return f.bs.Put(b) + } +} + +// PutMany is like Put(), but takes a slice of blocks, allowing +// the underlying blockstore to perform batch transactions. +func (f *Filestore) PutMany(bs []blocks.Block) error { + var normals []blocks.Block + var fstores []*posinfo.FilestoreNode + + for _, b := range bs { + has, err := f.Has(b.Cid()) + if err != nil { + return err + } + + if has { + continue + } + + switch b := b.(type) { + case *posinfo.FilestoreNode: + fstores = append(fstores, b) + default: + normals = append(normals, b) + } + } + + if len(normals) > 0 { + err := f.bs.PutMany(normals) + if err != nil { + return err + } + } + + if len(fstores) > 0 { + err := f.fm.PutMany(fstores) + if err != nil { + return err + } + } + return nil +} + +// HashOnRead calls blockstore.HashOnRead. +func (f *Filestore) HashOnRead(enabled bool) { + f.bs.HashOnRead(enabled) +} + +var _ blockstore.Blockstore = (*Filestore)(nil) diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/fsrefstore.go b/vendor/github.com/ipfs/go-ipfs/filestore/fsrefstore.go new file mode 100644 index 00000000..320ee592 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/fsrefstore.go @@ -0,0 +1,330 @@ +package filestore + +import ( + "context" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + + pb "github.com/ipfs/go-ipfs/filestore/pb" + + proto "github.com/gogo/protobuf/proto" + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + dsns "github.com/ipfs/go-datastore/namespace" + dsq "github.com/ipfs/go-datastore/query" + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + posinfo "github.com/ipfs/go-ipfs-posinfo" +) + +// FilestorePrefix identifies the key prefix for FileManager blocks. +var FilestorePrefix = ds.NewKey("filestore") + +// FileManager is a blockstore implementation which stores special +// blocks FilestoreNode type. These nodes only contain a reference +// to the actual location of the block data in the filesystem +// (a path and an offset). +type FileManager struct { + AllowFiles bool + AllowUrls bool + ds ds.Batching + root string +} + +// CorruptReferenceError implements the error interface. +// It is used to indicate that the block contents pointed +// by the referencing blocks cannot be retrieved (i.e. the +// file is not found, or the data changed as it was being read). +type CorruptReferenceError struct { + Code Status + Err error +} + +// Error() returns the error message in the CorruptReferenceError +// as a string. +func (c CorruptReferenceError) Error() string { + return c.Err.Error() +} + +// NewFileManager initializes a new file manager with the given +// datastore and root. All FilestoreNodes paths are relative to the +// root path given here, which is prepended for any operations. +func NewFileManager(ds ds.Batching, root string) *FileManager { + return &FileManager{ds: dsns.Wrap(ds, FilestorePrefix), root: root} +} + +// AllKeysChan returns a channel from which to read the keys stored in +// the FileManager. If the given context is cancelled the channel will be +// closed. +func (f *FileManager) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) { + q := dsq.Query{KeysOnly: true} + + res, err := f.ds.Query(q) + if err != nil { + return nil, err + } + + out := make(chan cid.Cid, dsq.KeysOnlyBufSize) + go func() { + defer close(out) + for { + v, ok := res.NextSync() + if !ok { + return + } + + k := ds.RawKey(v.Key) + c, err := dshelp.DsKeyToCid(k) + if err != nil { + log.Errorf("decoding cid from filestore: %s", err) + continue + } + + select { + case out <- c: + case <-ctx.Done(): + return + } + } + }() + + return out, nil +} + +// DeleteBlock deletes the reference-block from the underlying +// datastore. It does not touch the referenced data. +func (f *FileManager) DeleteBlock(c cid.Cid) error { + err := f.ds.Delete(dshelp.CidToDsKey(c)) + if err == ds.ErrNotFound { + return blockstore.ErrNotFound + } + return err +} + +// Get reads a block from the datastore. Reading a block +// is done in two steps: the first step retrieves the reference +// block from the datastore. The second step uses the stored +// path and offsets to read the raw block data directly from disk. +func (f *FileManager) Get(c cid.Cid) (blocks.Block, error) { + dobj, err := f.getDataObj(c) + if err != nil { + return nil, err + } + out, err := f.readDataObj(c, dobj) + if err != nil { + return nil, err + } + + return blocks.NewBlockWithCid(out, c) +} + +// GetSize gets the size of the block from the datastore. +// +// This method may successfully return the size even if returning the block +// would fail because the associated file is no longer available. +func (f *FileManager) GetSize(c cid.Cid) (int, error) { + dobj, err := f.getDataObj(c) + if err != nil { + return -1, err + } + return int(dobj.GetSize_()), nil +} + +func (f *FileManager) readDataObj(c cid.Cid, d *pb.DataObj) ([]byte, error) { + if IsURL(d.GetFilePath()) { + return f.readURLDataObj(c, d) + } + return f.readFileDataObj(c, d) +} + +func (f *FileManager) getDataObj(c cid.Cid) (*pb.DataObj, error) { + o, err := f.ds.Get(dshelp.CidToDsKey(c)) + switch err { + case ds.ErrNotFound: + return nil, blockstore.ErrNotFound + default: + return nil, err + case nil: + // + } + + return unmarshalDataObj(o) +} + +func unmarshalDataObj(data []byte) (*pb.DataObj, error) { + var dobj pb.DataObj + if err := proto.Unmarshal(data, &dobj); err != nil { + return nil, err + } + + return &dobj, nil +} + +func (f *FileManager) readFileDataObj(c cid.Cid, d *pb.DataObj) ([]byte, error) { + if !f.AllowFiles { + return nil, ErrFilestoreNotEnabled + } + + p := filepath.FromSlash(d.GetFilePath()) + abspath := filepath.Join(f.root, p) + + fi, err := os.Open(abspath) + if os.IsNotExist(err) { + return nil, &CorruptReferenceError{StatusFileNotFound, err} + } else if err != nil { + return nil, &CorruptReferenceError{StatusFileError, err} + } + defer fi.Close() + + _, err = fi.Seek(int64(d.GetOffset()), io.SeekStart) + if err != nil { + return nil, &CorruptReferenceError{StatusFileError, err} + } + + outbuf := make([]byte, d.GetSize_()) + _, err = io.ReadFull(fi, outbuf) + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil, &CorruptReferenceError{StatusFileChanged, err} + } else if err != nil { + return nil, &CorruptReferenceError{StatusFileError, err} + } + + outcid, err := c.Prefix().Sum(outbuf) + if err != nil { + return nil, err + } + + if !c.Equals(outcid) { + return nil, &CorruptReferenceError{StatusFileChanged, + fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())} + } + + return outbuf, nil +} + +// reads and verifies the block from URL +func (f *FileManager) readURLDataObj(c cid.Cid, d *pb.DataObj) ([]byte, error) { + if !f.AllowUrls { + return nil, ErrUrlstoreNotEnabled + } + + req, err := http.NewRequest("GET", d.GetFilePath(), nil) + if err != nil { + return nil, err + } + + req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", d.GetOffset(), d.GetOffset()+d.GetSize_()-1)) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return nil, &CorruptReferenceError{StatusFileError, err} + } + if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusPartialContent { + return nil, &CorruptReferenceError{StatusFileError, + fmt.Errorf("expected HTTP 200 or 206 got %d", res.StatusCode)} + } + + outbuf := make([]byte, d.GetSize_()) + _, err = io.ReadFull(res.Body, outbuf) + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil, &CorruptReferenceError{StatusFileChanged, err} + } else if err != nil { + return nil, &CorruptReferenceError{StatusFileError, err} + } + res.Body.Close() + + outcid, err := c.Prefix().Sum(outbuf) + if err != nil { + return nil, err + } + + if !c.Equals(outcid) { + return nil, &CorruptReferenceError{StatusFileChanged, + fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())} + } + + return outbuf, nil +} + +// Has returns if the FileManager is storing a block reference. It does not +// validate the data, nor checks if the reference is valid. +func (f *FileManager) Has(c cid.Cid) (bool, error) { + // NOTE: interesting thing to consider. Has doesnt validate the data. + // So the data on disk could be invalid, and we could think we have it. + dsk := dshelp.CidToDsKey(c) + return f.ds.Has(dsk) +} + +type putter interface { + Put(ds.Key, []byte) error +} + +// Put adds a new reference block to the FileManager. It does not check +// that the reference is valid. +func (f *FileManager) Put(b *posinfo.FilestoreNode) error { + return f.putTo(b, f.ds) +} + +func (f *FileManager) putTo(b *posinfo.FilestoreNode, to putter) error { + var dobj pb.DataObj + + if IsURL(b.PosInfo.FullPath) { + if !f.AllowUrls { + return ErrUrlstoreNotEnabled + } + dobj.FilePath = b.PosInfo.FullPath + } else { + if !f.AllowFiles { + return ErrFilestoreNotEnabled + } + if !filepath.HasPrefix(b.PosInfo.FullPath, f.root) { //nolint:staticcheck + return fmt.Errorf("cannot add filestore references outside ipfs root (%s)", f.root) + } + + p, err := filepath.Rel(f.root, b.PosInfo.FullPath) + if err != nil { + return err + } + + dobj.FilePath = filepath.ToSlash(p) + } + dobj.Offset = b.PosInfo.Offset + dobj.Size_ = uint64(len(b.RawData())) + + data, err := proto.Marshal(&dobj) + if err != nil { + return err + } + + return to.Put(dshelp.CidToDsKey(b.Cid()), data) +} + +// PutMany is like Put() but takes a slice of blocks instead, +// allowing it to create a batch transaction. +func (f *FileManager) PutMany(bs []*posinfo.FilestoreNode) error { + batch, err := f.ds.Batch() + if err != nil { + return err + } + + for _, b := range bs { + if err := f.putTo(b, batch); err != nil { + return err + } + } + + return batch.Commit() +} + +// IsURL returns true if the string represents a valid URL that the +// urlstore can handle. More specifically it returns true if a string +// begins with 'http://' or 'https://'. +func IsURL(str string) bool { + return (len(str) > 7 && str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p') && + ((len(str) > 8 && str[4] == 's' && str[5] == ':' && str[6] == '/' && str[7] == '/') || + (str[4] == ':' && str[5] == '/' && str[6] == '/')) +} diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/pb/Rules.mk b/vendor/github.com/ipfs/go-ipfs/filestore/pb/Rules.mk new file mode 100644 index 00000000..505f70e7 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/pb/Rules.mk @@ -0,0 +1,8 @@ +include mk/header.mk + +PB_$(d) = $(wildcard $(d)/*.proto) +TGTS_$(d) = $(PB_$(d):.proto=.pb.go) + +#DEPS_GO += $(TGTS_$(d)) + +include mk/footer.mk diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.pb.go b/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.pb.go new file mode 100644 index 00000000..59650a11 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.pb.go @@ -0,0 +1,399 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: filestore/pb/dataobj.proto + +package datastore_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type DataObj struct { + FilePath string `protobuf:"bytes,1,opt,name=FilePath" json:"FilePath"` + Offset uint64 `protobuf:"varint,2,opt,name=Offset" json:"Offset"` + Size_ uint64 `protobuf:"varint,3,opt,name=Size" json:"Size"` +} + +func (m *DataObj) Reset() { *m = DataObj{} } +func (m *DataObj) String() string { return proto.CompactTextString(m) } +func (*DataObj) ProtoMessage() {} +func (*DataObj) Descriptor() ([]byte, []int) { + return fileDescriptor_86a3613fbaff9a6c, []int{0} +} +func (m *DataObj) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DataObj) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DataObj.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DataObj) XXX_Merge(src proto.Message) { + xxx_messageInfo_DataObj.Merge(m, src) +} +func (m *DataObj) XXX_Size() int { + return m.Size() +} +func (m *DataObj) XXX_DiscardUnknown() { + xxx_messageInfo_DataObj.DiscardUnknown(m) +} + +var xxx_messageInfo_DataObj proto.InternalMessageInfo + +func (m *DataObj) GetFilePath() string { + if m != nil { + return m.FilePath + } + return "" +} + +func (m *DataObj) GetOffset() uint64 { + if m != nil { + return m.Offset + } + return 0 +} + +func (m *DataObj) GetSize_() uint64 { + if m != nil { + return m.Size_ + } + return 0 +} + +func init() { + proto.RegisterType((*DataObj)(nil), "datastore.pb.DataObj") +} + +func init() { proto.RegisterFile("filestore/pb/dataobj.proto", fileDescriptor_86a3613fbaff9a6c) } + +var fileDescriptor_86a3613fbaff9a6c = []byte{ + // 160 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0xcb, 0xcc, 0x49, + 0x2d, 0x2e, 0xc9, 0x2f, 0x4a, 0xd5, 0x2f, 0x48, 0xd2, 0x4f, 0x49, 0x2c, 0x49, 0xcc, 0x4f, 0xca, + 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x01, 0x71, 0xc1, 0x72, 0x7a, 0x05, 0x49, 0x4a, + 0xc9, 0x5c, 0xec, 0x2e, 0x89, 0x25, 0x89, 0xfe, 0x49, 0x59, 0x42, 0x0a, 0x5c, 0x1c, 0x6e, 0x99, + 0x39, 0xa9, 0x01, 0x89, 0x25, 0x19, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x4e, 0x2c, 0x27, 0xee, + 0xc9, 0x33, 0x04, 0xc1, 0x45, 0x85, 0x64, 0xb8, 0xd8, 0xfc, 0xd3, 0xd2, 0x8a, 0x53, 0x4b, 0x24, + 0x98, 0x14, 0x18, 0x35, 0x58, 0xa0, 0xf2, 0x50, 0x31, 0x21, 0x09, 0x2e, 0x96, 0xe0, 0xcc, 0xaa, + 0x54, 0x09, 0x66, 0x24, 0x39, 0xb0, 0x88, 0x93, 0xc4, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, + 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, + 0xcb, 0x31, 0x00, 0x02, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x87, 0xf5, 0x88, 0xa9, 0x00, 0x00, 0x00, +} + +func (m *DataObj) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DataObj) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintDataobj(dAtA, i, uint64(len(m.FilePath))) + i += copy(dAtA[i:], m.FilePath) + dAtA[i] = 0x10 + i++ + i = encodeVarintDataobj(dAtA, i, uint64(m.Offset)) + dAtA[i] = 0x18 + i++ + i = encodeVarintDataobj(dAtA, i, uint64(m.Size_)) + return i, nil +} + +func encodeVarintDataobj(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *DataObj) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FilePath) + n += 1 + l + sovDataobj(uint64(l)) + n += 1 + sovDataobj(uint64(m.Offset)) + n += 1 + sovDataobj(uint64(m.Size_)) + return n +} + +func sovDataobj(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozDataobj(x uint64) (n int) { + return sovDataobj(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *DataObj) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDataobj + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DataObj: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DataObj: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FilePath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDataobj + } + 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 ErrInvalidLengthDataobj + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDataobj + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FilePath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDataobj + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType) + } + m.Size_ = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDataobj + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Size_ |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDataobj(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDataobj + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDataobj + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipDataobj(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDataobj + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDataobj + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDataobj + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthDataobj + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthDataobj + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDataobj + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipDataobj(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthDataobj + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthDataobj = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowDataobj = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.proto b/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.proto new file mode 100644 index 00000000..909d22b7 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/pb/dataobj.proto @@ -0,0 +1,9 @@ +syntax = "proto2"; + +package datastore.pb; + +message DataObj { + optional string FilePath = 1; + optional uint64 Offset = 2; + optional uint64 Size = 3; +} diff --git a/vendor/github.com/ipfs/go-ipfs/filestore/util.go b/vendor/github.com/ipfs/go-ipfs/filestore/util.go new file mode 100644 index 00000000..4f394959 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/filestore/util.go @@ -0,0 +1,287 @@ +package filestore + +import ( + "fmt" + "sort" + + pb "github.com/ipfs/go-ipfs/filestore/pb" + + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" +) + +// Status is used to identify the state of the block data referenced +// by a FilestoreNode. Among other places, it is used by CorruptReferenceError. +type Status int32 + +// These are the supported Status codes. +const ( + StatusOk Status = 0 + StatusFileError Status = 10 // Backing File Error + StatusFileNotFound Status = 11 // Backing File Not Found + StatusFileChanged Status = 12 // Contents of the file changed + StatusOtherError Status = 20 // Internal Error, likely corrupt entry + StatusKeyNotFound Status = 30 +) + +// String provides a human-readable representation for Status codes. +func (s Status) String() string { + switch s { + case StatusOk: + return "ok" + case StatusFileError: + return "error" + case StatusFileNotFound: + return "no-file" + case StatusFileChanged: + return "changed" + case StatusOtherError: + return "ERROR" + case StatusKeyNotFound: + return "missing" + default: + return "???" + } +} + +// Format returns the status formatted as a string +// with leading 0s. +func (s Status) Format() string { + return fmt.Sprintf("%-7s", s.String()) +} + +// ListRes wraps the response of the List*() functions, which +// allows to obtain and verify blocks stored by the FileManager +// of a Filestore. It includes information about the referenced +// block. +type ListRes struct { + Status Status + ErrorMsg string + Key cid.Cid + FilePath string + Offset uint64 + Size uint64 +} + +// FormatLong returns a human readable string for a ListRes object +func (r *ListRes) FormatLong(enc func(cid.Cid) string) string { + if enc == nil { + enc = (cid.Cid).String + } + switch { + case !r.Key.Defined(): + return "" + case r.FilePath == "": + return r.Key.String() + default: + return fmt.Sprintf("%-50s %6d %s %d", enc(r.Key), r.Size, r.FilePath, r.Offset) + } +} + +// List fetches the block with the given key from the Filemanager +// of the given Filestore and returns a ListRes object with the information. +// List does not verify that the reference is valid or whether the +// raw data is accesible. See Verify(). +func List(fs *Filestore, key cid.Cid) *ListRes { + return list(fs, false, key) +} + +// ListAll returns a function as an iterator which, once invoked, returns +// one by one each block in the Filestore's FileManager. +// ListAll does not verify that the references are valid or whether +// the raw data is accessible. See VerifyAll(). +func ListAll(fs *Filestore, fileOrder bool) (func() *ListRes, error) { + if fileOrder { + return listAllFileOrder(fs, false) + } + return listAll(fs, false) +} + +// Verify fetches the block with the given key from the Filemanager +// of the given Filestore and returns a ListRes object with the information. +// Verify makes sure that the reference is valid and the block data can be +// read. +func Verify(fs *Filestore, key cid.Cid) *ListRes { + return list(fs, true, key) +} + +// VerifyAll returns a function as an iterator which, once invoked, +// returns one by one each block in the Filestore's FileManager. +// VerifyAll checks that the reference is valid and that the block data +// can be read. +func VerifyAll(fs *Filestore, fileOrder bool) (func() *ListRes, error) { + if fileOrder { + return listAllFileOrder(fs, true) + } + return listAll(fs, true) +} + +func list(fs *Filestore, verify bool, key cid.Cid) *ListRes { + dobj, err := fs.fm.getDataObj(key) + if err != nil { + return mkListRes(key, nil, err) + } + if verify { + _, err = fs.fm.readDataObj(key, dobj) + } + return mkListRes(key, dobj, err) +} + +func listAll(fs *Filestore, verify bool) (func() *ListRes, error) { + q := dsq.Query{} + qr, err := fs.fm.ds.Query(q) + if err != nil { + return nil, err + } + + return func() *ListRes { + cid, dobj, err := next(qr) + if dobj == nil && err == nil { + return nil + } else if err == nil && verify { + _, err = fs.fm.readDataObj(cid, dobj) + } + return mkListRes(cid, dobj, err) + }, nil +} + +func next(qr dsq.Results) (cid.Cid, *pb.DataObj, error) { + v, ok := qr.NextSync() + if !ok { + return cid.Cid{}, nil, nil + } + + k := ds.RawKey(v.Key) + c, err := dshelp.DsKeyToCid(k) + if err != nil { + return cid.Cid{}, nil, fmt.Errorf("decoding cid from filestore: %s", err) + } + + dobj, err := unmarshalDataObj(v.Value) + if err != nil { + return c, nil, err + } + + return c, dobj, nil +} + +func listAllFileOrder(fs *Filestore, verify bool) (func() *ListRes, error) { + q := dsq.Query{} + qr, err := fs.fm.ds.Query(q) + if err != nil { + return nil, err + } + + var entries listEntries + + for { + v, ok := qr.NextSync() + if !ok { + break + } + dobj, err := unmarshalDataObj(v.Value) + if err != nil { + entries = append(entries, &listEntry{ + dsKey: v.Key, + err: err, + }) + } else { + entries = append(entries, &listEntry{ + dsKey: v.Key, + filePath: dobj.GetFilePath(), + offset: dobj.GetOffset(), + size: dobj.GetSize_(), + }) + } + } + sort.Sort(entries) + + i := 0 + return func() *ListRes { + if i >= len(entries) { + return nil + } + v := entries[i] + i++ + // attempt to convert the datastore key to a CID, + // store the error but don't use it yet + cid, keyErr := dshelp.DsKeyToCid(ds.RawKey(v.dsKey)) + // first if they listRes already had an error return that error + if v.err != nil { + return mkListRes(cid, nil, v.err) + } + // now reconstruct the DataObj + dobj := pb.DataObj{ + FilePath: v.filePath, + Offset: v.offset, + Size_: v.size, + } + // now if we could not convert the datastore key return that + // error + if keyErr != nil { + return mkListRes(cid, &dobj, keyErr) + } + // finally verify the dataobj if requested + var err error + if verify { + _, err = fs.fm.readDataObj(cid, &dobj) + } + return mkListRes(cid, &dobj, err) + }, nil +} + +type listEntry struct { + filePath string + offset uint64 + dsKey string + size uint64 + err error +} + +type listEntries []*listEntry + +func (l listEntries) Len() int { return len(l) } +func (l listEntries) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l listEntries) Less(i, j int) bool { + if l[i].filePath == l[j].filePath { + if l[i].offset == l[j].offset { + return l[i].dsKey < l[j].dsKey + } + return l[i].offset < l[j].offset + } + return l[i].filePath < l[j].filePath +} + +func mkListRes(c cid.Cid, d *pb.DataObj, err error) *ListRes { + status := StatusOk + errorMsg := "" + if err != nil { + if err == ds.ErrNotFound || err == blockstore.ErrNotFound { + status = StatusKeyNotFound + } else if err, ok := err.(*CorruptReferenceError); ok { + status = err.Code + } else { + status = StatusOtherError + } + errorMsg = err.Error() + } + if d == nil { + return &ListRes{ + Status: status, + ErrorMsg: errorMsg, + Key: c, + } + } + + return &ListRes{ + Status: status, + ErrorMsg: errorMsg, + Key: c, + FilePath: d.FilePath, + Size: d.Size_, + Offset: d.Offset, + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/fuse/mount/fuse.go b/vendor/github.com/ipfs/go-ipfs/fuse/mount/fuse.go new file mode 100644 index 00000000..41d14cc3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/fuse/mount/fuse.go @@ -0,0 +1,162 @@ +// +build !nofuse +// +build !windows + +package mount + +import ( + "errors" + "fmt" + "sync" + "time" + + "bazil.org/fuse" + "bazil.org/fuse/fs" + "github.com/jbenet/goprocess" +) + +var ErrNotMounted = errors.New("not mounted") + +// mount implements go-ipfs/fuse/mount +type mount struct { + mpoint string + filesys fs.FS + fuseConn *fuse.Conn + + active bool + activeLock *sync.RWMutex + + proc goprocess.Process +} + +// Mount mounts a fuse fs.FS at a given location, and returns a Mount instance. +// parent is a ContextGroup to bind the mount's ContextGroup to. +func NewMount(p goprocess.Process, fsys fs.FS, mountpoint string, allow_other bool) (Mount, error) { + var conn *fuse.Conn + var err error + + if allow_other { + conn, err = fuse.Mount(mountpoint, fuse.AllowOther()) + } else { + conn, err = fuse.Mount(mountpoint) + } + + if err != nil { + return nil, err + } + + m := &mount{ + mpoint: mountpoint, + fuseConn: conn, + filesys: fsys, + active: false, + activeLock: &sync.RWMutex{}, + proc: goprocess.WithParent(p), // link it to parent. + } + m.proc.SetTeardown(m.unmount) + + // launch the mounting process. + if err := m.mount(); err != nil { + _ = m.Unmount() // just in case. + return nil, err + } + + return m, nil +} + +func (m *mount) mount() error { + log.Infof("Mounting %s", m.MountPoint()) + + errs := make(chan error, 1) + go func() { + // fs.Serve blocks until the filesystem is unmounted. + err := fs.Serve(m.fuseConn, m.filesys) + log.Debugf("%s is unmounted", m.MountPoint()) + if err != nil { + log.Debugf("fs.Serve returned (%s)", err) + errs <- err + } + m.setActive(false) + }() + + // wait for the mount process to be done, or timed out. + select { + case <-time.After(MountTimeout): + return fmt.Errorf("mounting %s timed out", m.MountPoint()) + case err := <-errs: + return err + case <-m.fuseConn.Ready: + } + + // check if the mount process has an error to report + if err := m.fuseConn.MountError; err != nil { + return err + } + + m.setActive(true) + + log.Infof("Mounted %s", m.MountPoint()) + return nil +} + +// umount is called exactly once to unmount this service. +// note that closing the connection will not always unmount +// properly. If that happens, we bring out the big guns +// (mount.ForceUnmountManyTimes, exec unmount). +func (m *mount) unmount() error { + log.Infof("Unmounting %s", m.MountPoint()) + + // try unmounting with fuse lib + err := fuse.Unmount(m.MountPoint()) + if err == nil { + m.setActive(false) + return nil + } + log.Warningf("fuse unmount err: %s", err) + + // try closing the fuseConn + err = m.fuseConn.Close() + if err == nil { + m.setActive(false) + return nil + } + log.Warningf("fuse conn error: %s", err) + + // try mount.ForceUnmountManyTimes + if err := ForceUnmountManyTimes(m, 10); err != nil { + return err + } + + log.Infof("Seemingly unmounted %s", m.MountPoint()) + m.setActive(false) + return nil +} + +func (m *mount) Process() goprocess.Process { + return m.proc +} + +func (m *mount) MountPoint() string { + return m.mpoint +} + +func (m *mount) Unmount() error { + if !m.IsActive() { + return ErrNotMounted + } + + // call Process Close(), which calls unmount() exactly once. + return m.proc.Close() +} + +func (m *mount) IsActive() bool { + m.activeLock.RLock() + defer m.activeLock.RUnlock() + + return m.active +} + +func (m *mount) setActive(a bool) { + m.activeLock.Lock() + m.active = a + m.activeLock.Unlock() +} diff --git a/vendor/github.com/ipfs/go-ipfs/fuse/mount/mount.go b/vendor/github.com/ipfs/go-ipfs/fuse/mount/mount.go new file mode 100644 index 00000000..84df699e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/fuse/mount/mount.go @@ -0,0 +1,107 @@ +// package mount provides a simple abstraction around a mount point +package mount + +import ( + "fmt" + "io" + "os/exec" + "runtime" + "time" + + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" +) + +var log = logging.Logger("mount") + +var MountTimeout = time.Second * 5 + +// Mount represents a filesystem mount +type Mount interface { + // MountPoint is the path at which this mount is mounted + MountPoint() string + + // Unmounts the mount + Unmount() error + + // Checks if the mount is still active. + IsActive() bool + + // Process returns the mount's Process to be able to link it + // to other processes. Unmount upon closing. + Process() goprocess.Process +} + +// ForceUnmount attempts to forcibly unmount a given mount. +// It does so by calling diskutil or fusermount directly. +func ForceUnmount(m Mount) error { + point := m.MountPoint() + log.Warningf("Force-Unmounting %s...", point) + + cmd, err := UnmountCmd(point) + if err != nil { + return err + } + + errc := make(chan error, 1) + go func() { + defer close(errc) + + // try vanilla unmount first. + if err := exec.Command("umount", point).Run(); err == nil { + return + } + + // retry to unmount with the fallback cmd + errc <- cmd.Run() + }() + + select { + case <-time.After(7 * time.Second): + return fmt.Errorf("umount timeout") + case err := <-errc: + return err + } +} + +// UnmountCmd creates an exec.Cmd that is GOOS-specific +// for unmount a FUSE mount +func UnmountCmd(point string) (*exec.Cmd, error) { + switch runtime.GOOS { + case "darwin": + return exec.Command("diskutil", "umount", "force", point), nil + case "linux": + return exec.Command("fusermount", "-u", point), nil + default: + return nil, fmt.Errorf("unmount: unimplemented") + } +} + +// ForceUnmountManyTimes attempts to forcibly unmount a given mount, +// many times. It does so by calling diskutil or fusermount directly. +// Attempts a given number of times. +func ForceUnmountManyTimes(m Mount, attempts int) error { + var err error + for i := 0; i < attempts; i++ { + err = ForceUnmount(m) + if err == nil { + return err + } + + <-time.After(time.Millisecond * 500) + } + return fmt.Errorf("unmount %s failed after 10 seconds of trying", m.MountPoint()) +} + +type closer struct { + M Mount +} + +func (c *closer) Close() error { + log.Warning(" (c *closer) Close(),", c.M.MountPoint()) + return c.M.Unmount() +} + +func Closer(m Mount) io.Closer { + return &closer{m} +} diff --git a/vendor/github.com/ipfs/go-ipfs/keystore/keystore.go b/vendor/github.com/ipfs/go-ipfs/keystore/keystore.go new file mode 100644 index 00000000..237d4b05 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/keystore/keystore.go @@ -0,0 +1,176 @@ +package keystore + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + logging "github.com/ipfs/go-log" + ci "github.com/libp2p/go-libp2p-core/crypto" +) + +var log = logging.Logger("keystore") + +// Keystore provides a key management interface +type Keystore interface { + // Has returns whether or not a key exist in the Keystore + Has(string) (bool, error) + // Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists + Put(string, ci.PrivKey) error + // Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey + // otherwise. + Get(string) (ci.PrivKey, error) + // Delete removes a key from the Keystore + Delete(string) error + // List returns a list of key identifier + List() ([]string, error) +} + +var ErrNoSuchKey = fmt.Errorf("no key by the given name was found") +var ErrKeyExists = fmt.Errorf("key by that name already exists, refusing to overwrite") + +// FSKeystore is a keystore backed by files in a given directory stored on disk. +type FSKeystore struct { + dir string +} + +func validateName(name string) error { + if name == "" { + return fmt.Errorf("key names must be at least one character") + } + + if strings.Contains(name, "/") { + return fmt.Errorf("key names may not contain slashes") + } + + if strings.HasPrefix(name, ".") { + return fmt.Errorf("key names may not begin with a period") + } + + return nil +} + +func NewFSKeystore(dir string) (*FSKeystore, error) { + _, err := os.Stat(dir) + if err != nil { + if !os.IsNotExist(err) { + return nil, err + } + if err := os.Mkdir(dir, 0700); err != nil { + return nil, err + } + } + + return &FSKeystore{dir}, nil +} + +// Has returns whether or not a key exist in the Keystore +func (ks *FSKeystore) Has(name string) (bool, error) { + kp := filepath.Join(ks.dir, name) + + _, err := os.Stat(kp) + + if os.IsNotExist(err) { + return false, nil + } + + if err != nil { + return false, err + } + + if err := validateName(name); err != nil { + return false, err + } + + return true, nil +} + +// Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists +func (ks *FSKeystore) Put(name string, k ci.PrivKey) error { + if err := validateName(name); err != nil { + return err + } + + b, err := k.Bytes() + if err != nil { + return err + } + + kp := filepath.Join(ks.dir, name) + + _, err = os.Stat(kp) + if err == nil { + return ErrKeyExists + } else if !os.IsNotExist(err) { + return err + } + + fi, err := os.Create(kp) + if err != nil { + return err + } + defer fi.Close() + + _, err = fi.Write(b) + + return err +} + +// Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey +// otherwise. +func (ks *FSKeystore) Get(name string) (ci.PrivKey, error) { + if err := validateName(name); err != nil { + return nil, err + } + + kp := filepath.Join(ks.dir, name) + + data, err := ioutil.ReadFile(kp) + if err != nil { + if os.IsNotExist(err) { + return nil, ErrNoSuchKey + } + return nil, err + } + + return ci.UnmarshalPrivateKey(data) +} + +// Delete removes a key from the Keystore +func (ks *FSKeystore) Delete(name string) error { + if err := validateName(name); err != nil { + return err + } + + kp := filepath.Join(ks.dir, name) + + return os.Remove(kp) +} + +// List return a list of key identifier +func (ks *FSKeystore) List() ([]string, error) { + dir, err := os.Open(ks.dir) + if err != nil { + return nil, err + } + + dirs, err := dir.Readdirnames(0) + if err != nil { + return nil, err + } + + list := make([]string, 0, len(dirs)) + + for _, name := range dirs { + err := validateName(name) + if err == nil { + list = append(list, name) + } else { + log.Warningf("Ignoring the invalid keyfile: %s", name) + } + } + + return list, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/keystore/memkeystore.go b/vendor/github.com/ipfs/go-ipfs/keystore/memkeystore.go new file mode 100644 index 00000000..4067bbce --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/keystore/memkeystore.go @@ -0,0 +1,67 @@ +package keystore + +import ci "github.com/libp2p/go-libp2p-core/crypto" + +// MemKeystore is an in memory keystore implementation that is not persisted to +// any backing storage. +type MemKeystore struct { + keys map[string]ci.PrivKey +} + +func NewMemKeystore() *MemKeystore { + return &MemKeystore{make(map[string]ci.PrivKey)} +} + +// Has return whether or not a key exist in the Keystore +func (mk *MemKeystore) Has(name string) (bool, error) { + _, ok := mk.keys[name] + return ok, nil +} + +// Put store a key in the Keystore +func (mk *MemKeystore) Put(name string, k ci.PrivKey) error { + if err := validateName(name); err != nil { + return err + } + + _, ok := mk.keys[name] + if ok { + return ErrKeyExists + } + + mk.keys[name] = k + return nil +} + +// Get retrieve a key from the Keystore +func (mk *MemKeystore) Get(name string) (ci.PrivKey, error) { + if err := validateName(name); err != nil { + return nil, err + } + + k, ok := mk.keys[name] + if !ok { + return nil, ErrNoSuchKey + } + + return k, nil +} + +// Delete remove a key from the Keystore +func (mk *MemKeystore) Delete(name string) error { + if err := validateName(name); err != nil { + return err + } + + delete(mk.keys, name) + return nil +} + +// List return a list of key identifier +func (mk *MemKeystore) List() ([]string, error) { + out := make([]string, 0, len(mk.keys)) + for k := range mk.keys { + out = append(out, k) + } + return out, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/base.go b/vendor/github.com/ipfs/go-ipfs/namesys/base.go new file mode 100644 index 00000000..27cc38f8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/base.go @@ -0,0 +1,120 @@ +package namesys + +import ( + "context" + "strings" + "time" + + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" +) + +type onceResult struct { + value path.Path + ttl time.Duration + err error +} + +type resolver interface { + resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult +} + +// resolve is a helper for implementing Resolver.ResolveN using resolveOnce. +func resolve(ctx context.Context, r resolver, name string, options opts.ResolveOpts) (path.Path, error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + err := ErrResolveFailed + var p path.Path + + resCh := resolveAsync(ctx, r, name, options) + + for res := range resCh { + p, err = res.Path, res.Err + if err != nil { + break + } + } + + return p, err +} + +func resolveAsync(ctx context.Context, r resolver, name string, options opts.ResolveOpts) <-chan Result { + resCh := r.resolveOnceAsync(ctx, name, options) + depth := options.Depth + outCh := make(chan Result, 1) + + go func() { + defer close(outCh) + var subCh <-chan Result + var cancelSub context.CancelFunc + defer func() { + if cancelSub != nil { + cancelSub() + } + }() + + for { + select { + case res, ok := <-resCh: + if !ok { + resCh = nil + break + } + + if res.err != nil { + emitResult(ctx, outCh, Result{Err: res.err}) + return + } + log.Debugf("resolved %s to %s", name, res.value.String()) + if !strings.HasPrefix(res.value.String(), ipnsPrefix) { + emitResult(ctx, outCh, Result{Path: res.value}) + break + } + + if depth == 1 { + emitResult(ctx, outCh, Result{Path: res.value, Err: ErrResolveRecursion}) + break + } + + subopts := options + if subopts.Depth > 1 { + subopts.Depth-- + } + + var subCtx context.Context + if cancelSub != nil { + // Cancel previous recursive resolve since it won't be used anyways + cancelSub() + } + subCtx, cancelSub = context.WithCancel(ctx) + _ = cancelSub + + p := strings.TrimPrefix(res.value.String(), ipnsPrefix) + subCh = resolveAsync(subCtx, r, p, subopts) + case res, ok := <-subCh: + if !ok { + subCh = nil + break + } + + // We don't bother returning here in case of context timeout as there is + // no good reason to do that, and we may still be able to emit a result + emitResult(ctx, outCh, res) + case <-ctx.Done(): + return + } + if resCh == nil && subCh == nil { + return + } + } + }() + return outCh +} + +func emitResult(ctx context.Context, outCh chan<- Result, r Result) { + select { + case outCh <- r: + case <-ctx.Done(): + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/cache.go b/vendor/github.com/ipfs/go-ipfs/namesys/cache.go new file mode 100644 index 00000000..4a5cb511 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/cache.go @@ -0,0 +1,47 @@ +package namesys + +import ( + "time" + + path "github.com/ipfs/go-path" +) + +func (ns *mpns) cacheGet(name string) (path.Path, bool) { + if ns.cache == nil { + return "", false + } + + ientry, ok := ns.cache.Get(name) + if !ok { + return "", false + } + + entry, ok := ientry.(cacheEntry) + if !ok { + // should never happen, purely for sanity + log.Panicf("unexpected type %T in cache for %q.", ientry, name) + } + + if time.Now().Before(entry.eol) { + return entry.val, true + } + + ns.cache.Remove(name) + + return "", false +} + +func (ns *mpns) cacheSet(name string, val path.Path, ttl time.Duration) { + if ns.cache == nil || ttl <= 0 { + return + } + ns.cache.Add(name, cacheEntry{ + val: val, + eol: time.Now().Add(ttl), + }) +} + +type cacheEntry struct { + val path.Path + eol time.Time +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/dns.go b/vendor/github.com/ipfs/go-ipfs/namesys/dns.go new file mode 100644 index 00000000..931edec0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/dns.go @@ -0,0 +1,149 @@ +package namesys + +import ( + "context" + "errors" + "net" + "strings" + + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" + isd "github.com/jbenet/go-is-domain" +) + +type LookupTXTFunc func(name string) (txt []string, err error) + +// DNSResolver implements a Resolver on DNS domains +type DNSResolver struct { + lookupTXT LookupTXTFunc + // TODO: maybe some sort of caching? + // cache would need a timeout +} + +// NewDNSResolver constructs a name resolver using DNS TXT records. +func NewDNSResolver() *DNSResolver { + return &DNSResolver{lookupTXT: net.LookupTXT} +} + +// Resolve implements Resolver. +func (r *DNSResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) { + return resolve(ctx, r, name, opts.ProcessOpts(options)) +} + +// ResolveAsync implements Resolver. +func (r *DNSResolver) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result { + return resolveAsync(ctx, r, name, opts.ProcessOpts(options)) +} + +type lookupRes struct { + path path.Path + error error +} + +// resolveOnce implements resolver. +// TXT records for a given domain name should contain a b58 +// encoded multihash. +func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult { + var fqdn string + out := make(chan onceResult, 1) + segments := strings.SplitN(name, "/", 2) + domain := segments[0] + + if !isd.IsDomain(domain) { + out <- onceResult{err: errors.New("not a valid domain name")} + close(out) + return out + } + log.Debugf("DNSResolver resolving %s", domain) + + if strings.HasSuffix(domain, ".") { + fqdn = domain + } else { + fqdn = domain + "." + } + + rootChan := make(chan lookupRes, 1) + go workDomain(r, fqdn, rootChan) + + subChan := make(chan lookupRes, 1) + go workDomain(r, "_dnslink."+fqdn, subChan) + + appendPath := func(p path.Path) (path.Path, error) { + if len(segments) > 1 { + return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1]) + } + return p, nil + } + + go func() { + defer close(out) + for { + select { + case subRes, ok := <-subChan: + if !ok { + subChan = nil + break + } + if subRes.error == nil { + p, err := appendPath(subRes.path) + emitOnceResult(ctx, out, onceResult{value: p, err: err}) + return + } + case rootRes, ok := <-rootChan: + if !ok { + rootChan = nil + break + } + if rootRes.error == nil { + p, err := appendPath(rootRes.path) + emitOnceResult(ctx, out, onceResult{value: p, err: err}) + } + case <-ctx.Done(): + return + } + if subChan == nil && rootChan == nil { + return + } + } + }() + + return out +} + +func workDomain(r *DNSResolver, name string, res chan lookupRes) { + defer close(res) + + txt, err := r.lookupTXT(name) + if err != nil { + // Error is != nil + res <- lookupRes{"", err} + return + } + + for _, t := range txt { + p, err := parseEntry(t) + if err == nil { + res <- lookupRes{p, nil} + return + } + } + res <- lookupRes{"", ErrResolveFailed} +} + +func parseEntry(txt string) (path.Path, error) { + p, err := path.ParseCidToPath(txt) // bare IPFS multihashes + if err == nil { + return p, nil + } + + return tryParseDnsLink(txt) +} + +func tryParseDnsLink(txt string) (path.Path, error) { + parts := strings.SplitN(txt, "=", 2) + if len(parts) == 2 && parts[0] == "dnslink" { + return path.ParsePath(parts[1]) + } + + return "", errors.New("not a valid dnslink entry") +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/interface.go b/vendor/github.com/ipfs/go-ipfs/namesys/interface.go new file mode 100644 index 00000000..ecd80943 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/interface.go @@ -0,0 +1,106 @@ +/* +Package namesys implements resolvers and publishers for the IPFS +naming system (IPNS). + +The core of IPFS is an immutable, content-addressable Merkle graph. +That works well for many use cases, but doesn't allow you to answer +questions like "what is Alice's current homepage?". The mutable name +system allows Alice to publish information like: + + The current homepage for alice.example.com is + /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj + +or: + + The current homepage for node + QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy + is + /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj + +The mutable name system also allows users to resolve those references +to find the immutable IPFS object currently referenced by a given +mutable name. + +For command-line bindings to this functionality, see: + + ipfs name + ipfs dns + ipfs resolve +*/ +package namesys + +import ( + "errors" + "time" + + context "context" + + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" + ci "github.com/libp2p/go-libp2p-core/crypto" +) + +// ErrResolveFailed signals an error when attempting to resolve. +var ErrResolveFailed = errors.New("could not resolve name") + +// ErrResolveRecursion signals a recursion-depth limit. +var ErrResolveRecursion = errors.New( + "could not resolve name (recursion limit exceeded)") + +// ErrPublishFailed signals an error when attempting to publish. +var ErrPublishFailed = errors.New("could not publish name") + +// Namesys represents a cohesive name publishing and resolving system. +// +// Publishing a name is the process of establishing a mapping, a key-value +// pair, according to naming rules and databases. +// +// Resolving a name is the process of looking up the value associated with the +// key (name). +type NameSystem interface { + Resolver + Publisher +} + +// Result is the return type for Resolver.ResolveAsync. +type Result struct { + Path path.Path + Err error +} + +// Resolver is an object capable of resolving names. +type Resolver interface { + + // Resolve performs a recursive lookup, returning the dereferenced + // path. For example, if ipfs.io has a DNS TXT record pointing to + // /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy + // and there is a DHT IPNS entry for + // QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy + // -> /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj + // then + // Resolve(ctx, "/ipns/ipfs.io") + // will resolve both names, returning + // /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj + // + // There is a default depth-limit to avoid infinite recursion. Most + // users will be fine with this default limit, but if you need to + // adjust the limit you can specify it as an option. + Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (value path.Path, err error) + + // ResolveAsync performs recursive name lookup, like Resolve, but it returns + // entries as they are discovered in the DHT. Each returned result is guaranteed + // to be "better" (which usually means newer) than the previous one. + ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result +} + +// Publisher is an object capable of publishing particular names. +type Publisher interface { + + // Publish establishes a name-value mapping. + // TODO make this not PrivKey specific. + Publish(ctx context.Context, name ci.PrivKey, value path.Path) error + + // TODO: to be replaced by a more generic 'PublishWithValidity' type + // call once the records spec is implemented + PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/namesys.go b/vendor/github.com/ipfs/go-ipfs/namesys/namesys.go new file mode 100644 index 00000000..6d59c62e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/namesys.go @@ -0,0 +1,191 @@ +package namesys + +import ( + "context" + "strings" + "time" + + lru "github.com/hashicorp/golang-lru" + ds "github.com/ipfs/go-datastore" + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" + isd "github.com/jbenet/go-is-domain" + ci "github.com/libp2p/go-libp2p-core/crypto" + peer "github.com/libp2p/go-libp2p-core/peer" + routing "github.com/libp2p/go-libp2p-core/routing" + mh "github.com/multiformats/go-multihash" +) + +// mpns (a multi-protocol NameSystem) implements generic IPFS naming. +// +// Uses several Resolvers: +// (a) IPFS routing naming: SFS-like PKI names. +// (b) dns domains: resolves using links in DNS TXT records +// (c) proquints: interprets string as the raw byte data. +// +// It can only publish to: (a) IPFS routing naming. +// +type mpns struct { + dnsResolver, proquintResolver, ipnsResolver resolver + ipnsPublisher Publisher + + cache *lru.Cache +} + +// NewNameSystem will construct the IPFS naming system based on Routing +func NewNameSystem(r routing.ValueStore, ds ds.Datastore, cachesize int) NameSystem { + var cache *lru.Cache + if cachesize > 0 { + cache, _ = lru.New(cachesize) + } + + return &mpns{ + dnsResolver: NewDNSResolver(), + proquintResolver: new(ProquintResolver), + ipnsResolver: NewIpnsResolver(r), + ipnsPublisher: NewIpnsPublisher(r, ds), + cache: cache, + } +} + +const DefaultResolverCacheTTL = time.Minute + +// Resolve implements Resolver. +func (ns *mpns) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) { + if strings.HasPrefix(name, "/ipfs/") { + return path.ParsePath(name) + } + + if !strings.HasPrefix(name, "/") { + return path.ParsePath("/ipfs/" + name) + } + + return resolve(ctx, ns, name, opts.ProcessOpts(options)) +} + +func (ns *mpns) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result { + res := make(chan Result, 1) + if strings.HasPrefix(name, "/ipfs/") { + p, err := path.ParsePath(name) + res <- Result{p, err} + return res + } + + if !strings.HasPrefix(name, "/") { + p, err := path.ParsePath("/ipfs/" + name) + res <- Result{p, err} + return res + } + + return resolveAsync(ctx, ns, name, opts.ProcessOpts(options)) +} + +// resolveOnce implements resolver. +func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult { + out := make(chan onceResult, 1) + + if !strings.HasPrefix(name, ipnsPrefix) { + name = ipnsPrefix + name + } + segments := strings.SplitN(name, "/", 4) + if len(segments) < 3 || segments[0] != "" { + log.Debugf("invalid name syntax for %s", name) + out <- onceResult{err: ErrResolveFailed} + close(out) + return out + } + + key := segments[2] + + if p, ok := ns.cacheGet(key); ok { + if len(segments) > 3 { + var err error + p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) + if err != nil { + emitOnceResult(ctx, out, onceResult{value: p, err: err}) + } + } + + out <- onceResult{value: p} + close(out) + return out + } + + // Resolver selection: + // 1. if it is a multihash resolve through "ipns". + // 2. if it is a domain name, resolve through "dns" + // 3. otherwise resolve through the "proquint" resolver + + var res resolver + if _, err := mh.FromB58String(key); err == nil { + res = ns.ipnsResolver + } else if isd.IsDomain(key) { + res = ns.dnsResolver + } else { + res = ns.proquintResolver + } + + resCh := res.resolveOnceAsync(ctx, key, options) + var best onceResult + go func() { + defer close(out) + for { + select { + case res, ok := <-resCh: + if !ok { + if best != (onceResult{}) { + ns.cacheSet(key, best.value, best.ttl) + } + return + } + if res.err == nil { + best = res + } + p := res.value + + // Attach rest of the path + if len(segments) > 3 { + var err error + p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) + if err != nil { + emitOnceResult(ctx, out, onceResult{value: p, ttl: res.ttl, err: err}) + } + } + + emitOnceResult(ctx, out, onceResult{value: p, ttl: res.ttl, err: res.err}) + case <-ctx.Done(): + return + } + } + }() + + return out +} + +func emitOnceResult(ctx context.Context, outCh chan<- onceResult, r onceResult) { + select { + case outCh <- r: + case <-ctx.Done(): + } +} + +// Publish implements Publisher +func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error { + return ns.PublishWithEOL(ctx, name, value, time.Now().Add(DefaultRecordEOL)) +} + +func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error { + id, err := peer.IDFromPrivateKey(name) + if err != nil { + return err + } + if err := ns.ipnsPublisher.PublishWithEOL(ctx, name, value, eol); err != nil { + return err + } + ttl := DefaultResolverCacheTTL + if ttEol := time.Until(eol); ttEol < ttl { + ttl = ttEol + } + ns.cacheSet(peer.IDB58Encode(id), value, ttl) + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/proquint.go b/vendor/github.com/ipfs/go-ipfs/namesys/proquint.go new file mode 100644 index 00000000..63cb62a0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/proquint.go @@ -0,0 +1,32 @@ +package namesys + +import ( + "context" + "errors" + + proquint "github.com/bren2010/proquint" + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" +) + +type ProquintResolver struct{} + +// Resolve implements Resolver. +func (r *ProquintResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) { + return resolve(ctx, r, name, opts.ProcessOpts(options)) +} + +// resolveOnce implements resolver. Decodes the proquint string. +func (r *ProquintResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult { + out := make(chan onceResult, 1) + defer close(out) + + ok, err := proquint.IsProquint(name) + if err != nil || !ok { + out <- onceResult{err: errors.New("not a valid proquint string")} + return out + } + // Return a 0 TTL as caching this result is pointless. + out <- onceResult{value: path.FromString(string(proquint.Decode(name)))} + return out +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/publisher.go b/vendor/github.com/ipfs/go-ipfs/namesys/publisher.go new file mode 100644 index 00000000..c06deb79 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/publisher.go @@ -0,0 +1,312 @@ +package namesys + +import ( + "context" + "strings" + "sync" + "time" + + pin "github.com/ipfs/go-ipfs/pin" + + proto "github.com/gogo/protobuf/proto" + ds "github.com/ipfs/go-datastore" + dsquery "github.com/ipfs/go-datastore/query" + ipns "github.com/ipfs/go-ipns" + pb "github.com/ipfs/go-ipns/pb" + path "github.com/ipfs/go-path" + ft "github.com/ipfs/go-unixfs" + ci "github.com/libp2p/go-libp2p-core/crypto" + peer "github.com/libp2p/go-libp2p-core/peer" + routing "github.com/libp2p/go-libp2p-core/routing" + base32 "github.com/whyrusleeping/base32" +) + +const ipnsPrefix = "/ipns/" + +const PublishPutValTimeout = time.Minute +const DefaultRecordEOL = 24 * time.Hour + +// IpnsPublisher is capable of publishing and resolving names to the IPFS +// routing system. +type IpnsPublisher struct { + routing routing.ValueStore + ds ds.Datastore + + // Used to ensure we assign IPNS records *sequential* sequence numbers. + mu sync.Mutex +} + +// NewIpnsPublisher constructs a publisher for the IPFS Routing name system. +func NewIpnsPublisher(route routing.ValueStore, ds ds.Datastore) *IpnsPublisher { + if ds == nil { + panic("nil datastore") + } + return &IpnsPublisher{routing: route, ds: ds} +} + +// Publish implements Publisher. Accepts a keypair and a value, +// and publishes it out to the routing system +func (p *IpnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value path.Path) error { + log.Debugf("Publish %s", value) + return p.PublishWithEOL(ctx, k, value, time.Now().Add(DefaultRecordEOL)) +} + +func IpnsDsKey(id peer.ID) ds.Key { + return ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id))) +} + +// PublishedNames returns the latest IPNS records published by this node and +// their expiration times. +// +// This method will not search the routing system for records published by other +// nodes. +func (p *IpnsPublisher) ListPublished(ctx context.Context) (map[peer.ID]*pb.IpnsEntry, error) { + query, err := p.ds.Query(dsquery.Query{ + Prefix: ipnsPrefix, + }) + if err != nil { + return nil, err + } + defer query.Close() + + records := make(map[peer.ID]*pb.IpnsEntry) + for { + select { + case result, ok := <-query.Next(): + if !ok { + return records, nil + } + if result.Error != nil { + return nil, result.Error + } + e := new(pb.IpnsEntry) + if err := proto.Unmarshal(result.Value, e); err != nil { + // Might as well return what we can. + log.Error("found an invalid IPNS entry:", err) + continue + } + if !strings.HasPrefix(result.Key, ipnsPrefix) { + log.Errorf("datastore query for keys with prefix %s returned a key: %s", ipnsPrefix, result.Key) + continue + } + k := result.Key[len(ipnsPrefix):] + pid, err := base32.RawStdEncoding.DecodeString(k) + if err != nil { + log.Errorf("ipns ds key invalid: %s", result.Key) + continue + } + records[peer.ID(pid)] = e + case <-ctx.Done(): + return nil, ctx.Err() + } + } +} + +// GetPublished returns the record this node has published corresponding to the +// given peer ID. +// +// If `checkRouting` is true and we have no existing record, this method will +// check the routing system for any existing records. +func (p *IpnsPublisher) GetPublished(ctx context.Context, id peer.ID, checkRouting bool) (*pb.IpnsEntry, error) { + ctx, cancel := context.WithTimeout(ctx, time.Second*30) + defer cancel() + + value, err := p.ds.Get(IpnsDsKey(id)) + switch err { + case nil: + case ds.ErrNotFound: + if !checkRouting { + return nil, nil + } + ipnskey := ipns.RecordKey(id) + value, err = p.routing.GetValue(ctx, ipnskey) + if err != nil { + // Not found or other network issue. Can't really do + // anything about this case. + if err != routing.ErrNotFound { + log.Debugf("error when determining the last published IPNS record for %s: %s", id, err) + } + + return nil, nil + } + default: + return nil, err + } + e := new(pb.IpnsEntry) + if err := proto.Unmarshal(value, e); err != nil { + return nil, err + } + return e, nil +} + +func (p *IpnsPublisher) updateRecord(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) (*pb.IpnsEntry, error) { + id, err := peer.IDFromPrivateKey(k) + if err != nil { + return nil, err + } + + p.mu.Lock() + defer p.mu.Unlock() + + // get previous records sequence number + rec, err := p.GetPublished(ctx, id, true) + if err != nil { + return nil, err + } + + seqno := rec.GetSequence() // returns 0 if rec is nil + if rec != nil && value != path.Path(rec.GetValue()) { + // Don't bother incrementing the sequence number unless the + // value changes. + seqno++ + } + + // Create record + entry, err := ipns.Create(k, []byte(value), seqno, eol) + if err != nil { + return nil, err + } + + // Set the TTL + // TODO: Make this less hacky. + ttl, ok := checkCtxTTL(ctx) + if ok { + entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds())) + } + + data, err := proto.Marshal(entry) + if err != nil { + return nil, err + } + + // Put the new record. + if err := p.ds.Put(IpnsDsKey(id), data); err != nil { + return nil, err + } + return entry, nil +} + +// PublishWithEOL is a temporary stand in for the ipns records implementation +// see here for more details: https://github.com/ipfs/specs/tree/master/records +func (p *IpnsPublisher) PublishWithEOL(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) error { + record, err := p.updateRecord(ctx, k, value, eol) + if err != nil { + return err + } + + return PutRecordToRouting(ctx, p.routing, k.GetPublic(), record) +} + +// setting the TTL on published records is an experimental feature. +// as such, i'm using the context to wire it through to avoid changing too +// much code along the way. +func checkCtxTTL(ctx context.Context) (time.Duration, bool) { + v := ctx.Value("ipns-publish-ttl") + if v == nil { + return 0, false + } + + d, ok := v.(time.Duration) + return d, ok +} + +func PutRecordToRouting(ctx context.Context, r routing.ValueStore, k ci.PubKey, entry *pb.IpnsEntry) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + errs := make(chan error, 2) // At most two errors (IPNS, and public key) + + if err := ipns.EmbedPublicKey(k, entry); err != nil { + return err + } + + id, err := peer.IDFromPublicKey(k) + if err != nil { + return err + } + + go func() { + errs <- PublishEntry(ctx, r, ipns.RecordKey(id), entry) + }() + + // Publish the public key if a public key cannot be extracted from the ID + // TODO: once v0.4.16 is widespread enough, we can stop doing this + // and at that point we can even deprecate the /pk/ namespace in the dht + // + // NOTE: This check actually checks if the public key has been embedded + // in the IPNS entry. This check is sufficient because we embed the + // public key in the IPNS entry if it can't be extracted from the ID. + if entry.PubKey != nil { + go func() { + errs <- PublishPublicKey(ctx, r, PkKeyForID(id), k) + }() + + if err := waitOnErrChan(ctx, errs); err != nil { + return err + } + } + + return waitOnErrChan(ctx, errs) +} + +func waitOnErrChan(ctx context.Context, errs chan error) error { + select { + case err := <-errs: + return err + case <-ctx.Done(): + return ctx.Err() + } +} + +func PublishPublicKey(ctx context.Context, r routing.ValueStore, k string, pubk ci.PubKey) error { + log.Debugf("Storing pubkey at: %s", k) + pkbytes, err := pubk.Bytes() + if err != nil { + return err + } + + // Store associated public key + timectx, cancel := context.WithTimeout(ctx, PublishPutValTimeout) + defer cancel() + return r.PutValue(timectx, k, pkbytes) +} + +func PublishEntry(ctx context.Context, r routing.ValueStore, ipnskey string, rec *pb.IpnsEntry) error { + timectx, cancel := context.WithTimeout(ctx, PublishPutValTimeout) + defer cancel() + + data, err := proto.Marshal(rec) + if err != nil { + return err + } + + log.Debugf("Storing ipns entry at: %s", ipnskey) + // Store ipns entry at "/ipns/"+h(pubkey) + return r.PutValue(timectx, ipnskey, data) +} + +// InitializeKeyspace sets the ipns record for the given key to +// point to an empty directory. +// TODO: this doesnt feel like it belongs here +func InitializeKeyspace(ctx context.Context, pub Publisher, pins pin.Pinner, key ci.PrivKey) error { + emptyDir := ft.EmptyDirNode() + + // pin recursively because this might already be pinned + // and doing a direct pin would throw an error in that case + err := pins.Pin(ctx, emptyDir, true) + if err != nil { + return err + } + + err = pins.Flush() + if err != nil { + return err + } + + return pub.Publish(ctx, key, path.FromCid(emptyDir.Cid())) +} + +// PkKeyForID returns the public key routing key for the given peer ID. +func PkKeyForID(id peer.ID) string { + return "/pk/" + string(id) +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/republisher/repub.go b/vendor/github.com/ipfs/go-ipfs/namesys/republisher/repub.go new file mode 100644 index 00000000..9e7272d3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/republisher/repub.go @@ -0,0 +1,158 @@ +package republisher + +import ( + "context" + "errors" + "time" + + keystore "github.com/ipfs/go-ipfs/keystore" + namesys "github.com/ipfs/go-ipfs/namesys" + path "github.com/ipfs/go-path" + + proto "github.com/gogo/protobuf/proto" + ds "github.com/ipfs/go-datastore" + pb "github.com/ipfs/go-ipns/pb" + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" + gpctx "github.com/jbenet/goprocess/context" + ic "github.com/libp2p/go-libp2p-core/crypto" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +var errNoEntry = errors.New("no previous entry") + +var log = logging.Logger("ipns-repub") + +// DefaultRebroadcastInterval is the default interval at which we rebroadcast IPNS records +var DefaultRebroadcastInterval = time.Hour * 4 + +// InitialRebroadcastDelay is the delay before first broadcasting IPNS records on start +var InitialRebroadcastDelay = time.Minute * 1 + +// FailureRetryInterval is the interval at which we retry IPNS records broadcasts (when they fail) +var FailureRetryInterval = time.Minute * 5 + +// DefaultRecordLifetime is the default lifetime for IPNS records +const DefaultRecordLifetime = time.Hour * 24 + +type Republisher struct { + ns namesys.Publisher + ds ds.Datastore + self ic.PrivKey + ks keystore.Keystore + + Interval time.Duration + + // how long records that are republished should be valid for + RecordLifetime time.Duration +} + +// NewRepublisher creates a new Republisher +func NewRepublisher(ns namesys.Publisher, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher { + return &Republisher{ + ns: ns, + ds: ds, + self: self, + ks: ks, + Interval: DefaultRebroadcastInterval, + RecordLifetime: DefaultRecordLifetime, + } +} + +func (rp *Republisher) Run(proc goprocess.Process) { + timer := time.NewTimer(InitialRebroadcastDelay) + defer timer.Stop() + if rp.Interval < InitialRebroadcastDelay { + timer.Reset(rp.Interval) + } + + for { + select { + case <-timer.C: + timer.Reset(rp.Interval) + err := rp.republishEntries(proc) + if err != nil { + log.Info("republisher failed to republish: ", err) + if FailureRetryInterval < rp.Interval { + timer.Reset(FailureRetryInterval) + } + } + case <-proc.Closing(): + return + } + } +} + +func (rp *Republisher) republishEntries(p goprocess.Process) error { + ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p)) + defer cancel() + + // TODO: Use rp.ipns.ListPublished(). We can't currently *do* that + // because: + // 1. There's no way to get keys from the keystore by ID. + // 2. We don't actually have access to the IPNS publisher. + err := rp.republishEntry(ctx, rp.self) + if err != nil { + return err + } + + if rp.ks != nil { + keyNames, err := rp.ks.List() + if err != nil { + return err + } + for _, name := range keyNames { + priv, err := rp.ks.Get(name) + if err != nil { + return err + } + err = rp.republishEntry(ctx, priv) + if err != nil { + return err + } + + } + } + + return nil +} + +func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) error { + id, err := peer.IDFromPrivateKey(priv) + if err != nil { + return err + } + + log.Debugf("republishing ipns entry for %s", id) + + // Look for it locally only + p, err := rp.getLastVal(id) + if err != nil { + if err == errNoEntry { + return nil + } + return err + } + + // update record with same sequence number + eol := time.Now().Add(rp.RecordLifetime) + return rp.ns.PublishWithEOL(ctx, priv, p, eol) +} + +func (rp *Republisher) getLastVal(id peer.ID) (path.Path, error) { + // Look for it locally only + val, err := rp.ds.Get(namesys.IpnsDsKey(id)) + switch err { + case nil: + case ds.ErrNotFound: + return "", errNoEntry + default: + return "", err + } + + e := new(pb.IpnsEntry) + if err := proto.Unmarshal(val, e); err != nil { + return "", err + } + return path.Path(e.Value), nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/namesys/routing.go b/vendor/github.com/ipfs/go-ipfs/namesys/routing.go new file mode 100644 index 00000000..94c12a72 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/namesys/routing.go @@ -0,0 +1,161 @@ +package namesys + +import ( + "context" + "strings" + "time" + + proto "github.com/gogo/protobuf/proto" + cid "github.com/ipfs/go-cid" + ipns "github.com/ipfs/go-ipns" + pb "github.com/ipfs/go-ipns/pb" + logging "github.com/ipfs/go-log" + path "github.com/ipfs/go-path" + opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" + peer "github.com/libp2p/go-libp2p-core/peer" + routing "github.com/libp2p/go-libp2p-core/routing" + dht "github.com/libp2p/go-libp2p-kad-dht" + mh "github.com/multiformats/go-multihash" +) + +var log = logging.Logger("namesys") + +// IpnsResolver implements NSResolver for the main IPFS SFS-like naming +type IpnsResolver struct { + routing routing.ValueStore +} + +// NewIpnsResolver constructs a name resolver using the IPFS Routing system +// to implement SFS-like naming on top. +func NewIpnsResolver(route routing.ValueStore) *IpnsResolver { + if route == nil { + panic("attempt to create resolver with nil routing system") + } + return &IpnsResolver{ + routing: route, + } +} + +// Resolve implements Resolver. +func (r *IpnsResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) { + return resolve(ctx, r, name, opts.ProcessOpts(options)) +} + +// ResolveAsync implements Resolver. +func (r *IpnsResolver) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result { + return resolveAsync(ctx, r, name, opts.ProcessOpts(options)) +} + +// resolveOnce implements resolver. Uses the IPFS routing system to +// resolve SFS-like names. +func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult { + out := make(chan onceResult, 1) + log.Debugf("RoutingResolver resolving %s", name) + cancel := func() {} + + if options.DhtTimeout != 0 { + // Resolution must complete within the timeout + ctx, cancel = context.WithTimeout(ctx, options.DhtTimeout) + } + + name = strings.TrimPrefix(name, "/ipns/") + pid, err := peer.IDB58Decode(name) + if err != nil { + log.Debugf("RoutingResolver: could not convert public key hash %s to peer ID: %s\n", name, err) + out <- onceResult{err: err} + close(out) + cancel() + return out + } + + // Name should be the hash of a public key retrievable from ipfs. + // We retrieve the public key here to make certain that it's in the peer + // store before calling GetValue() on the DHT - the DHT will call the + // ipns validator, which in turn will get the public key from the peer + // store to verify the record signature + _, err = routing.GetPublicKey(r.routing, ctx, pid) + if err != nil { + log.Debugf("RoutingResolver: could not retrieve public key %s: %s\n", name, err) + out <- onceResult{err: err} + close(out) + cancel() + return out + } + + // Use the routing system to get the name. + // Note that the DHT will call the ipns validator when retrieving + // the value, which in turn verifies the ipns record signature + ipnsKey := ipns.RecordKey(pid) + + vals, err := r.routing.SearchValue(ctx, ipnsKey, dht.Quorum(int(options.DhtRecordCount))) + if err != nil { + log.Debugf("RoutingResolver: dht get for name %s failed: %s", name, err) + out <- onceResult{err: err} + close(out) + cancel() + return out + } + + go func() { + defer cancel() + defer close(out) + for { + select { + case val, ok := <-vals: + if !ok { + return + } + + entry := new(pb.IpnsEntry) + err = proto.Unmarshal(val, entry) + if err != nil { + log.Debugf("RoutingResolver: could not unmarshal value for name %s: %s", name, err) + emitOnceResult(ctx, out, onceResult{err: err}) + return + } + + var p path.Path + // check for old style record: + if valh, err := mh.Cast(entry.GetValue()); err == nil { + // Its an old style multihash record + log.Debugf("encountered CIDv0 ipns entry: %s", valh) + p = path.FromCid(cid.NewCidV0(valh)) + } else { + // Not a multihash, probably a new style record + p, err = path.ParsePath(string(entry.GetValue())) + if err != nil { + emitOnceResult(ctx, out, onceResult{err: err}) + return + } + } + + ttl := DefaultResolverCacheTTL + if entry.Ttl != nil { + ttl = time.Duration(*entry.Ttl) + } + switch eol, err := ipns.GetEOL(entry); err { + case ipns.ErrUnrecognizedValidity: + // No EOL. + case nil: + ttEol := time.Until(eol) + if ttEol < 0 { + // It *was* valid when we first resolved it. + ttl = 0 + } else if ttEol < ttl { + ttl = ttEol + } + default: + log.Errorf("encountered error when parsing EOL: %s", err) + emitOnceResult(ctx, out, onceResult{err: err}) + return + } + + emitOnceResult(ctx, out, onceResult{value: p, ttl: ttl}) + case <-ctx.Done(): + return + } + } + }() + + return out +} diff --git a/vendor/github.com/ipfs/go-ipfs/p2p/listener.go b/vendor/github.com/ipfs/go-ipfs/p2p/listener.go new file mode 100644 index 00000000..65fe87c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/p2p/listener.go @@ -0,0 +1,96 @@ +package p2p + +import ( + "errors" + "sync" + + p2phost "github.com/libp2p/go-libp2p-core/host" + net "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/protocol" + ma "github.com/multiformats/go-multiaddr" +) + +// Listener listens for connections and proxies them to a target +type Listener interface { + Protocol() protocol.ID + ListenAddress() ma.Multiaddr + TargetAddress() ma.Multiaddr + + key() string + + // close closes the listener. Does not affect child streams + close() +} + +// Listeners manages a group of Listener implementations, +// checking for conflicts and optionally dispatching connections +type Listeners struct { + sync.RWMutex + + Listeners map[string]Listener +} + +func newListenersLocal() *Listeners { + return &Listeners{ + Listeners: map[string]Listener{}, + } +} + +func newListenersP2P(host p2phost.Host) *Listeners { + reg := &Listeners{ + Listeners: map[string]Listener{}, + } + + host.SetStreamHandlerMatch("/x/", func(p string) bool { + reg.RLock() + defer reg.RUnlock() + + _, ok := reg.Listeners[p] + return ok + }, func(stream net.Stream) { + reg.RLock() + defer reg.RUnlock() + + l := reg.Listeners[string(stream.Protocol())] + if l != nil { + go l.(*remoteListener).handleStream(stream) + } + }) + + return reg +} + +// Register registers listenerInfo into this registry and starts it +func (r *Listeners) Register(l Listener) error { + r.Lock() + defer r.Unlock() + + if _, ok := r.Listeners[l.key()]; ok { + return errors.New("listener already registered") + } + + r.Listeners[l.key()] = l + return nil +} + +func (r *Listeners) Close(matchFunc func(listener Listener) bool) int { + todo := make([]Listener, 0) + r.Lock() + for _, l := range r.Listeners { + if !matchFunc(l) { + continue + } + + if _, ok := r.Listeners[l.key()]; ok { + delete(r.Listeners, l.key()) + todo = append(todo, l) + } + } + r.Unlock() + + for _, l := range todo { + l.close() + } + + return len(todo) +} diff --git a/vendor/github.com/ipfs/go-ipfs/p2p/local.go b/vendor/github.com/ipfs/go-ipfs/p2p/local.go new file mode 100644 index 00000000..bff25e20 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/p2p/local.go @@ -0,0 +1,121 @@ +package p2p + +import ( + "context" + "time" + + tec "github.com/jbenet/go-temp-err-catcher" + net "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + ma "github.com/multiformats/go-multiaddr" + "github.com/multiformats/go-multiaddr-net" +) + +// localListener manet streams and proxies them to libp2p services +type localListener struct { + ctx context.Context + + p2p *P2P + + proto protocol.ID + laddr ma.Multiaddr + peer peer.ID + + listener manet.Listener +} + +// ForwardLocal creates new P2P stream to a remote listener +func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto protocol.ID, bindAddr ma.Multiaddr) (Listener, error) { + listener := &localListener{ + ctx: ctx, + p2p: p2p, + proto: proto, + peer: peer, + } + + maListener, err := manet.Listen(bindAddr) + if err != nil { + return nil, err + } + + listener.listener = maListener + listener.laddr = maListener.Multiaddr() + + if err := p2p.ListenersLocal.Register(listener); err != nil { + return nil, err + } + + go listener.acceptConns() + + return listener, nil +} + +func (l *localListener) dial(ctx context.Context) (net.Stream, error) { + cctx, cancel := context.WithTimeout(ctx, time.Second*30) //TODO: configurable? + defer cancel() + + return l.p2p.peerHost.NewStream(cctx, l.peer, l.proto) +} + +func (l *localListener) acceptConns() { + for { + local, err := l.listener.Accept() + if err != nil { + if tec.ErrIsTemporary(err) { + continue + } + return + } + + go l.setupStream(local) + } +} + +func (l *localListener) setupStream(local manet.Conn) { + remote, err := l.dial(l.ctx) + if err != nil { + local.Close() + log.Warningf("failed to dial to remote %s/%s", l.peer.Pretty(), l.proto) + return + } + + stream := &Stream{ + Protocol: l.proto, + + OriginAddr: local.RemoteMultiaddr(), + TargetAddr: l.TargetAddress(), + peer: l.peer, + + Local: local, + Remote: remote, + + Registry: l.p2p.Streams, + } + + l.p2p.Streams.Register(stream) +} + +func (l *localListener) close() { + l.listener.Close() +} + +func (l *localListener) Protocol() protocol.ID { + return l.proto +} + +func (l *localListener) ListenAddress() ma.Multiaddr { + return l.laddr +} + +func (l *localListener) TargetAddress() ma.Multiaddr { + addr, err := ma.NewMultiaddr(maPrefix + l.peer.Pretty()) + if err != nil { + panic(err) + } + return addr +} + +func (l *localListener) key() string { + return l.ListenAddress().String() +} diff --git a/vendor/github.com/ipfs/go-ipfs/p2p/p2p.go b/vendor/github.com/ipfs/go-ipfs/p2p/p2p.go new file mode 100644 index 00000000..078ba51c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/p2p/p2p.go @@ -0,0 +1,53 @@ +package p2p + +import ( + logging "github.com/ipfs/go-log" + p2phost "github.com/libp2p/go-libp2p-core/host" + peer "github.com/libp2p/go-libp2p-core/peer" + pstore "github.com/libp2p/go-libp2p-core/peerstore" +) + +var log = logging.Logger("p2p-mount") + +// P2P structure holds information on currently running streams/Listeners +type P2P struct { + ListenersLocal *Listeners + ListenersP2P *Listeners + Streams *StreamRegistry + + identity peer.ID + peerHost p2phost.Host + peerstore pstore.Peerstore +} + +// New creates new P2P struct +func New(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P2P { + return &P2P{ + identity: identity, + peerHost: peerHost, + peerstore: peerstore, + + ListenersLocal: newListenersLocal(), + ListenersP2P: newListenersP2P(peerHost), + + Streams: &StreamRegistry{ + Streams: map[uint64]*Stream{}, + ConnManager: peerHost.ConnManager(), + conns: map[peer.ID]int{}, + }, + } +} + +// CheckProtoExists checks whether a proto handler is registered to +// mux handler +func (p2p *P2P) CheckProtoExists(proto string) bool { + protos := p2p.peerHost.Mux().Protocols() + + for _, p := range protos { + if p != proto { + continue + } + return true + } + return false +} diff --git a/vendor/github.com/ipfs/go-ipfs/p2p/remote.go b/vendor/github.com/ipfs/go-ipfs/p2p/remote.go new file mode 100644 index 00000000..a89b2f2f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/p2p/remote.go @@ -0,0 +1,106 @@ +package p2p + +import ( + "context" + "fmt" + + net "github.com/libp2p/go-libp2p-core/network" + protocol "github.com/libp2p/go-libp2p-core/protocol" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +var maPrefix = "/" + ma.ProtocolWithCode(ma.P_IPFS).Name + "/" + +// remoteListener accepts libp2p streams and proxies them to a manet host +type remoteListener struct { + p2p *P2P + + // Application proto identifier. + proto protocol.ID + + // Address to proxy the incoming connections to + addr ma.Multiaddr + + // reportRemote if set to true makes the handler send '\n' + // to target before any data is forwarded + reportRemote bool +} + +// ForwardRemote creates new p2p listener +func (p2p *P2P) ForwardRemote(ctx context.Context, proto protocol.ID, addr ma.Multiaddr, reportRemote bool) (Listener, error) { + listener := &remoteListener{ + p2p: p2p, + + proto: proto, + addr: addr, + + reportRemote: reportRemote, + } + + if err := p2p.ListenersP2P.Register(listener); err != nil { + return nil, err + } + + return listener, nil +} + +func (l *remoteListener) handleStream(remote net.Stream) { + local, err := manet.Dial(l.addr) + if err != nil { + _ = remote.Reset() + return + } + + peer := remote.Conn().RemotePeer() + + if l.reportRemote { + if _, err := fmt.Fprintf(local, "%s\n", peer.Pretty()); err != nil { + _ = remote.Reset() + return + } + } + + peerMa, err := ma.NewMultiaddr(maPrefix + peer.Pretty()) + if err != nil { + _ = remote.Reset() + return + } + + stream := &Stream{ + Protocol: l.proto, + + OriginAddr: peerMa, + TargetAddr: l.addr, + peer: peer, + + Local: local, + Remote: remote, + + Registry: l.p2p.Streams, + } + + l.p2p.Streams.Register(stream) +} + +func (l *remoteListener) Protocol() protocol.ID { + return l.proto +} + +func (l *remoteListener) ListenAddress() ma.Multiaddr { + addr, err := ma.NewMultiaddr(maPrefix + l.p2p.identity.Pretty()) + if err != nil { + panic(err) + } + return addr +} + +func (l *remoteListener) TargetAddress() ma.Multiaddr { + return l.addr +} + +func (l *remoteListener) close() {} + +func (l *remoteListener) key() string { + return string(l.proto) +} diff --git a/vendor/github.com/ipfs/go-ipfs/p2p/stream.go b/vendor/github.com/ipfs/go-ipfs/p2p/stream.go new file mode 100644 index 00000000..137f14c1 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/p2p/stream.go @@ -0,0 +1,120 @@ +package p2p + +import ( + "io" + "sync" + + ifconnmgr "github.com/libp2p/go-libp2p-core/connmgr" + net "github.com/libp2p/go-libp2p-core/network" + peer "github.com/libp2p/go-libp2p-core/peer" + protocol "github.com/libp2p/go-libp2p-core/protocol" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +const cmgrTag = "stream-fwd" + +// Stream holds information on active incoming and outgoing p2p streams. +type Stream struct { + id uint64 + + Protocol protocol.ID + + OriginAddr ma.Multiaddr + TargetAddr ma.Multiaddr + peer peer.ID + + Local manet.Conn + Remote net.Stream + + Registry *StreamRegistry +} + +// close stream endpoints and deregister it +func (s *Stream) close() { + s.Registry.Close(s) +} + +// reset closes stream endpoints and deregisters it +func (s *Stream) reset() { + s.Registry.Reset(s) +} + +func (s *Stream) startStreaming() { + go func() { + _, err := io.Copy(s.Local, s.Remote) + if err != nil { + s.reset() + } else { + s.close() + } + }() + + go func() { + _, err := io.Copy(s.Remote, s.Local) + if err != nil { + s.reset() + } else { + s.close() + } + }() +} + +// StreamRegistry is a collection of active incoming and outgoing proto app streams. +type StreamRegistry struct { + sync.Mutex + + Streams map[uint64]*Stream + conns map[peer.ID]int + nextID uint64 + + ifconnmgr.ConnManager +} + +// Register registers a stream to the registry +func (r *StreamRegistry) Register(streamInfo *Stream) { + r.Lock() + defer r.Unlock() + + r.ConnManager.TagPeer(streamInfo.peer, cmgrTag, 20) + r.conns[streamInfo.peer]++ + + streamInfo.id = r.nextID + r.Streams[r.nextID] = streamInfo + r.nextID++ + + streamInfo.startStreaming() +} + +// Deregister deregisters stream from the registry +func (r *StreamRegistry) Deregister(streamID uint64) { + r.Lock() + defer r.Unlock() + + s, ok := r.Streams[streamID] + if !ok { + return + } + p := s.peer + r.conns[p]-- + if r.conns[p] < 1 { + delete(r.conns, p) + r.ConnManager.UntagPeer(p, cmgrTag) + } + + delete(r.Streams, streamID) +} + +// Close stream endpoints and deregister it +func (r *StreamRegistry) Close(s *Stream) { + _ = s.Local.Close() + _ = s.Remote.Close() + s.Registry.Deregister(s.id) +} + +// Reset closes stream endpoints and deregisters it +func (r *StreamRegistry) Reset(s *Stream) { + _ = s.Local.Close() + _ = s.Remote.Reset() + s.Registry.Deregister(s.id) +} diff --git a/vendor/github.com/ipfs/go-ipfs/package-list.json b/vendor/github.com/ipfs/go-ipfs/package-list.json new file mode 100644 index 00000000..5551193d --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/package-list.json @@ -0,0 +1,55 @@ +{ + "columns": [ + "Name", + "CI/Travis", + "Coverage", + "Description" + ], + "rows": [ + "Files", + ["ipfs/go-unixfs", "go-unixfs", "the core 'filesystem' logic"], + ["ipfs/go-mfs", "go-mfs", "a mutable filesystem editor for unixfs"], + ["ipfs/go-ipfs-posinfo", "go-ipfs-posinfo", "helper datatypes for the filestore"], + ["ipfs/go-ipfs-chunker", "go-ipfs-chunker", "file chunkers"], + + "Exchange", + ["ipfs/go-ipfs-exchange-interface", "go-ipfs-exchange-interface", "exchange service interface"], + ["ipfs/go-ipfs-exchange-offline", "go-ipfs-exchange-offline", "(dummy) offline implementation of the exchange service"], + ["ipfs/go-bitswap", "go-bitswap", "bitswap protocol implementation"], + ["ipfs/go-blockservice", "go-blockservice", "service that plugs a blockstore and an exchange together"], + + "Datastores", + ["ipfs/go-datastore", "go-datastore", "datastore interfaces, adapters, and basic implementations"], + ["ipfs/go-ipfs-ds-help", "go-ipfs-ds-help", "datastore utility functions"], + ["ipfs/go-ds-flatfs", "go-ds-flatfs", "a filesystem-based datastore"], + ["ipfs/go-ds-measure", "go-ds-measure", "a metric-collecting database adapter"], + ["ipfs/go-ds-leveldb", "go-ds-leveldb", "a leveldb based datastore"], + ["ipfs/go-ds-badger", "go-ds-badger", "a badgerdb based datastore"], + + "Namesys", + ["ipfs/go-ipns", "go-ipns", "IPNS datastructures and validation logic"], + + "Repo", + ["ipfs/go-ipfs-config", "go-ipfs-config", "go-ipfs config file definitions"], + ["ipfs/go-fs-lock", "go-fs-lock", "lockfile management functions"], + ["ipfs/fs-repo-migrations", "fs-repo-migrations", "repo migrations"], + + "Blocks", + ["ipfs/go-block-format", "go-block-format", "block interfaces and implementations"], + ["ipfs/go-ipfs-blockstore", "go-ipfs-blockstore", "blockstore interfaces and implementations"], + + "Commands", + ["ipfs/go-ipfs-cmds", "go-ipfs-cmds", "CLI & HTTP commands library"], + ["ipfs/go-ipfs-api", "go-ipfs-api", "a shell for the IPFS HTTP API"], + + "Metrics & Logging", + ["ipfs/go-metrics-interface", "go-metrics-interface", "metrics collection interfaces"], + ["ipfs/go-metrics-prometheus", "go-metrics-prometheus", "prometheus-backed metrics collector"], + ["ipfs/go-log", "go-log", "logging framework"], + + "Generics/Utils", + ["ipfs/go-ipfs-routing", "go-ipfs-routing", "routing (content, peer, value) helpers"], + ["ipfs/go-ipfs-util", "go-ipfs-util", "the kitchen sink"], + ["ipfs/go-ipfs-addr", "go-ipfs-addr", "utility functions for parsing IPFS multiaddrs"] + ] +} diff --git a/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/Rules.mk b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/Rules.mk new file mode 100644 index 00000000..505f70e7 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/Rules.mk @@ -0,0 +1,8 @@ +include mk/header.mk + +PB_$(d) = $(wildcard $(d)/*.proto) +TGTS_$(d) = $(PB_$(d):.proto=.pb.go) + +#DEPS_GO += $(TGTS_$(d)) + +include mk/footer.mk diff --git a/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/doc.go b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/doc.go new file mode 100644 index 00000000..95d4afe6 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/doc.go @@ -0,0 +1,3 @@ +package pb + +//go:generate protoc --gogo_out=. header.proto diff --git a/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.pb.go b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.pb.go new file mode 100644 index 00000000..71196b26 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.pb.go @@ -0,0 +1,381 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pin/internal/pb/header.proto + +package pb + +import ( + encoding_binary "encoding/binary" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Set struct { + // 1 for now, library will refuse to handle entries with an unrecognized version. + Version uint32 `protobuf:"varint,1,opt,name=version" json:"version"` + // how many of the links are subtrees + Fanout uint32 `protobuf:"varint,2,opt,name=fanout" json:"fanout"` + // hash seed for subtree selection, a random number + Seed uint32 `protobuf:"fixed32,3,opt,name=seed" json:"seed"` +} + +func (m *Set) Reset() { *m = Set{} } +func (m *Set) String() string { return proto.CompactTextString(m) } +func (*Set) ProtoMessage() {} +func (*Set) Descriptor() ([]byte, []int) { + return fileDescriptor_cda303a5a3ed87e7, []int{0} +} +func (m *Set) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Set) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Set.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Set) XXX_Merge(src proto.Message) { + xxx_messageInfo_Set.Merge(m, src) +} +func (m *Set) XXX_Size() int { + return m.Size() +} +func (m *Set) XXX_DiscardUnknown() { + xxx_messageInfo_Set.DiscardUnknown(m) +} + +var xxx_messageInfo_Set proto.InternalMessageInfo + +func (m *Set) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *Set) GetFanout() uint32 { + if m != nil { + return m.Fanout + } + return 0 +} + +func (m *Set) GetSeed() uint32 { + if m != nil { + return m.Seed + } + return 0 +} + +func init() { + proto.RegisterType((*Set)(nil), "ipfs.pin.Set") +} + +func init() { proto.RegisterFile("pin/internal/pb/header.proto", fileDescriptor_cda303a5a3ed87e7) } + +var fileDescriptor_cda303a5a3ed87e7 = []byte{ + // 162 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0xc8, 0xcc, 0xd3, + 0xcf, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2f, 0x48, 0xd2, 0xcf, 0x48, 0x4d, 0x4c, + 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xc8, 0x2c, 0x48, 0x2b, 0xd6, 0x2b, + 0xc8, 0xcc, 0x53, 0x8a, 0xe5, 0x62, 0x0e, 0x4e, 0x2d, 0x11, 0x92, 0xe3, 0x62, 0x2f, 0x4b, 0x2d, + 0x2a, 0xce, 0xcc, 0xcf, 0x93, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x75, 0x62, 0x39, 0x71, 0x4f, 0x9e, + 0x21, 0x08, 0x26, 0x28, 0x24, 0xc3, 0xc5, 0x96, 0x96, 0x98, 0x97, 0x5f, 0x5a, 0x22, 0xc1, 0x84, + 0x24, 0x0d, 0x15, 0x13, 0x92, 0xe0, 0x62, 0x29, 0x4e, 0x4d, 0x4d, 0x91, 0x60, 0x56, 0x60, 0xd4, + 0x60, 0x87, 0xca, 0x81, 0x45, 0x9c, 0x64, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, + 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, + 0x21, 0x8a, 0xa9, 0x20, 0x09, 0x10, 0x00, 0x00, 0xff, 0xff, 0x20, 0x85, 0x2f, 0x24, 0xa5, 0x00, + 0x00, 0x00, +} + +func (m *Set) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Set) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0x8 + i++ + i = encodeVarintHeader(dAtA, i, uint64(m.Version)) + dAtA[i] = 0x10 + i++ + i = encodeVarintHeader(dAtA, i, uint64(m.Fanout)) + dAtA[i] = 0x1d + i++ + encoding_binary.LittleEndian.PutUint32(dAtA[i:], uint32(m.Seed)) + i += 4 + return i, nil +} + +func encodeVarintHeader(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Set) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovHeader(uint64(m.Version)) + n += 1 + sovHeader(uint64(m.Fanout)) + n += 5 + return n +} + +func sovHeader(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozHeader(x uint64) (n int) { + return sovHeader(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Set) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHeader + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Set: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Set: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHeader + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Fanout", wireType) + } + m.Fanout = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHeader + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Fanout |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 5 { + return fmt.Errorf("proto: wrong wireType = %d for field Seed", wireType) + } + m.Seed = 0 + if (iNdEx + 4) > l { + return io.ErrUnexpectedEOF + } + m.Seed = uint32(encoding_binary.LittleEndian.Uint32(dAtA[iNdEx:])) + iNdEx += 4 + default: + iNdEx = preIndex + skippy, err := skipHeader(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthHeader + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthHeader + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipHeader(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHeader + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHeader + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHeader + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthHeader + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthHeader + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHeader + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipHeader(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthHeader + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthHeader = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowHeader = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.proto b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.proto new file mode 100644 index 00000000..36b32b36 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/internal/pb/header.proto @@ -0,0 +1,14 @@ +syntax = "proto2"; + +package ipfs.pin; + +option go_package = "pb"; + +message Set { + // 1 for now, library will refuse to handle entries with an unrecognized version. + optional uint32 version = 1; + // how many of the links are subtrees + optional uint32 fanout = 2; + // hash seed for subtree selection, a random number + optional fixed32 seed = 3; +} diff --git a/vendor/github.com/ipfs/go-ipfs/pin/pin.go b/vendor/github.com/ipfs/go-ipfs/pin/pin.go new file mode 100644 index 00000000..48a16f84 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/pin.go @@ -0,0 +1,637 @@ +// Package pin implements structures and methods to keep track of +// which objects a user wants to keep stored locally. +package pin + +import ( + "context" + "fmt" + "os" + "sync" + "time" + + "github.com/ipfs/go-ipfs/dagutils" + mdag "github.com/ipfs/go-merkledag" + + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("pin") + +var pinDatastoreKey = ds.NewKey("/local/pins") + +var emptyKey cid.Cid + +func init() { + e, err := cid.Decode("QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n") + if err != nil { + log.Error("failed to decode empty key constant") + os.Exit(1) + } + emptyKey = e +} + +const ( + linkRecursive = "recursive" + linkDirect = "direct" + linkIndirect = "indirect" + linkInternal = "internal" + linkNotPinned = "not pinned" + linkAny = "any" + linkAll = "all" +) + +// Mode allows to specify different types of pin (recursive, direct etc.). +// See the Pin Modes constants for a full list. +type Mode int + +// Pin Modes +const ( + // Recursive pins pin the target cids along with any reachable children. + Recursive Mode = iota + + // Direct pins pin just the target cid. + Direct + + // Indirect pins are cids who have some ancestor pinned recursively. + Indirect + + // Internal pins are cids used to keep the internal state of the pinner. + Internal + + // NotPinned + NotPinned + + // Any refers to any pinned cid + Any +) + +// ModeToString returns a human-readable name for the Mode. +func ModeToString(mode Mode) (string, bool) { + m := map[Mode]string{ + Recursive: linkRecursive, + Direct: linkDirect, + Indirect: linkIndirect, + Internal: linkInternal, + NotPinned: linkNotPinned, + Any: linkAny, + } + s, ok := m[mode] + return s, ok +} + +// StringToMode parses the result of ModeToString() back to a Mode. +// It returns a boolean which is set to false if the mode is unknown. +func StringToMode(s string) (Mode, bool) { + m := map[string]Mode{ + linkRecursive: Recursive, + linkDirect: Direct, + linkIndirect: Indirect, + linkInternal: Internal, + linkNotPinned: NotPinned, + linkAny: Any, + linkAll: Any, // "all" and "any" means the same thing + } + mode, ok := m[s] + return mode, ok +} + +// A Pinner provides the necessary methods to keep track of Nodes which are +// to be kept locally, according to a pin mode. In practice, a Pinner is in +// in charge of keeping the list of items from the local storage that should +// not be garbage-collected. +type Pinner interface { + // IsPinned returns whether or not the given cid is pinned + // and an explanation of why its pinned + IsPinned(cid.Cid) (string, bool, error) + + // IsPinnedWithType returns whether or not the given cid is pinned with the + // given pin type, as well as returning the type of pin its pinned with. + IsPinnedWithType(cid.Cid, Mode) (string, bool, error) + + // Pin the given node, optionally recursively. + Pin(ctx context.Context, node ipld.Node, recursive bool) error + + // Unpin the given cid. If recursive is true, removes either a recursive or + // a direct pin. If recursive is false, only removes a direct pin. + Unpin(ctx context.Context, cid cid.Cid, recursive bool) error + + // Update updates a recursive pin from one cid to another + // this is more efficient than simply pinning the new one and unpinning the + // old one + Update(ctx context.Context, from, to cid.Cid, unpin bool) error + + // Check if a set of keys are pinned, more efficient than + // calling IsPinned for each key + CheckIfPinned(cids ...cid.Cid) ([]Pinned, error) + + // PinWithMode is for manually editing the pin structure. Use with + // care! If used improperly, garbage collection may not be + // successful. + PinWithMode(cid.Cid, Mode) + + // RemovePinWithMode is for manually editing the pin structure. + // Use with care! If used improperly, garbage collection may not + // be successful. + RemovePinWithMode(cid.Cid, Mode) + + // Flush writes the pin state to the backing datastore + Flush() error + + // DirectKeys returns all directly pinned cids + DirectKeys() []cid.Cid + + // DirectKeys returns all recursively pinned cids + RecursiveKeys() []cid.Cid + + // InternalPins returns all cids kept pinned for the internal state of the + // pinner + InternalPins() []cid.Cid +} + +// Pinned represents CID which has been pinned with a pinning strategy. +// The Via field allows to identify the pinning parent of this CID, in the +// case that the item is not pinned directly (but rather pinned recursively +// by some ascendant). +type Pinned struct { + Key cid.Cid + Mode Mode + Via cid.Cid +} + +// Pinned returns whether or not the given cid is pinned +func (p Pinned) Pinned() bool { + return p.Mode != NotPinned +} + +// String Returns pin status as string +func (p Pinned) String() string { + switch p.Mode { + case NotPinned: + return "not pinned" + case Indirect: + return fmt.Sprintf("pinned via %s", p.Via) + default: + modeStr, _ := ModeToString(p.Mode) + return fmt.Sprintf("pinned: %s", modeStr) + } +} + +// pinner implements the Pinner interface +type pinner struct { + lock sync.RWMutex + recursePin *cid.Set + directPin *cid.Set + + // Track the keys used for storing the pinning state, so gc does + // not delete them. + internalPin *cid.Set + dserv ipld.DAGService + internal ipld.DAGService // dagservice used to store internal objects + dstore ds.Datastore +} + +// NewPinner creates a new pinner using the given datastore as a backend +func NewPinner(dstore ds.Datastore, serv, internal ipld.DAGService) Pinner { + + rcset := cid.NewSet() + dirset := cid.NewSet() + + return &pinner{ + recursePin: rcset, + directPin: dirset, + dserv: serv, + dstore: dstore, + internal: internal, + internalPin: cid.NewSet(), + } +} + +// Pin the given node, optionally recursive +func (p *pinner) Pin(ctx context.Context, node ipld.Node, recurse bool) error { + p.lock.Lock() + defer p.lock.Unlock() + err := p.dserv.Add(ctx, node) + if err != nil { + return err + } + + c := node.Cid() + + if recurse { + if p.recursePin.Has(c) { + return nil + } + + if p.directPin.Has(c) { + p.directPin.Remove(c) + } + p.lock.Unlock() + // fetch entire graph + err := mdag.FetchGraph(ctx, c, p.dserv) + p.lock.Lock() + if err != nil { + return err + } + + if p.recursePin.Has(c) { + return nil + } + + if p.directPin.Has(c) { + p.directPin.Remove(c) + } + + p.recursePin.Add(c) + } else { + p.lock.Unlock() + _, err := p.dserv.Get(ctx, c) + p.lock.Lock() + if err != nil { + return err + } + + if p.recursePin.Has(c) { + return fmt.Errorf("%s already pinned recursively", c.String()) + } + + p.directPin.Add(c) + } + return nil +} + +// ErrNotPinned is returned when trying to unpin items which are not pinned. +var ErrNotPinned = fmt.Errorf("not pinned or pinned indirectly") + +// Unpin a given key +func (p *pinner) Unpin(ctx context.Context, c cid.Cid, recursive bool) error { + p.lock.Lock() + defer p.lock.Unlock() + if p.recursePin.Has(c) { + if !recursive { + return fmt.Errorf("%s is pinned recursively", c) + } + p.recursePin.Remove(c) + return nil + } + if p.directPin.Has(c) { + p.directPin.Remove(c) + return nil + } + return ErrNotPinned +} + +func (p *pinner) isInternalPin(c cid.Cid) bool { + return p.internalPin.Has(c) +} + +// IsPinned returns whether or not the given key is pinned +// and an explanation of why its pinned +func (p *pinner) IsPinned(c cid.Cid) (string, bool, error) { + p.lock.RLock() + defer p.lock.RUnlock() + return p.isPinnedWithType(c, Any) +} + +// IsPinnedWithType returns whether or not the given cid is pinned with the +// given pin type, as well as returning the type of pin its pinned with. +func (p *pinner) IsPinnedWithType(c cid.Cid, mode Mode) (string, bool, error) { + p.lock.RLock() + defer p.lock.RUnlock() + return p.isPinnedWithType(c, mode) +} + +// isPinnedWithType is the implementation of IsPinnedWithType that does not lock. +// intended for use by other pinned methods that already take locks +func (p *pinner) isPinnedWithType(c cid.Cid, mode Mode) (string, bool, error) { + switch mode { + case Any, Direct, Indirect, Recursive, Internal: + default: + err := fmt.Errorf("invalid Pin Mode '%d', must be one of {%d, %d, %d, %d, %d}", + mode, Direct, Indirect, Recursive, Internal, Any) + return "", false, err + } + if (mode == Recursive || mode == Any) && p.recursePin.Has(c) { + return linkRecursive, true, nil + } + if mode == Recursive { + return "", false, nil + } + + if (mode == Direct || mode == Any) && p.directPin.Has(c) { + return linkDirect, true, nil + } + if mode == Direct { + return "", false, nil + } + + if (mode == Internal || mode == Any) && p.isInternalPin(c) { + return linkInternal, true, nil + } + if mode == Internal { + return "", false, nil + } + + // Default is Indirect + visitedSet := cid.NewSet() + for _, rc := range p.recursePin.Keys() { + has, err := hasChild(p.dserv, rc, c, visitedSet.Visit) + if err != nil { + return "", false, err + } + if has { + return rc.String(), true, nil + } + } + return "", false, nil +} + +// CheckIfPinned Checks if a set of keys are pinned, more efficient than +// calling IsPinned for each key, returns the pinned status of cid(s) +func (p *pinner) CheckIfPinned(cids ...cid.Cid) ([]Pinned, error) { + p.lock.RLock() + defer p.lock.RUnlock() + pinned := make([]Pinned, 0, len(cids)) + toCheck := cid.NewSet() + + // First check for non-Indirect pins directly + for _, c := range cids { + if p.recursePin.Has(c) { + pinned = append(pinned, Pinned{Key: c, Mode: Recursive}) + } else if p.directPin.Has(c) { + pinned = append(pinned, Pinned{Key: c, Mode: Direct}) + } else if p.isInternalPin(c) { + pinned = append(pinned, Pinned{Key: c, Mode: Internal}) + } else { + toCheck.Add(c) + } + } + + // Now walk all recursive pins to check for indirect pins + var checkChildren func(cid.Cid, cid.Cid) error + checkChildren = func(rk, parentKey cid.Cid) error { + links, err := ipld.GetLinks(context.TODO(), p.dserv, parentKey) + if err != nil { + return err + } + for _, lnk := range links { + c := lnk.Cid + + if toCheck.Has(c) { + pinned = append(pinned, + Pinned{Key: c, Mode: Indirect, Via: rk}) + toCheck.Remove(c) + } + + err := checkChildren(rk, c) + if err != nil { + return err + } + + if toCheck.Len() == 0 { + return nil + } + } + return nil + } + + for _, rk := range p.recursePin.Keys() { + err := checkChildren(rk, rk) + if err != nil { + return nil, err + } + if toCheck.Len() == 0 { + break + } + } + + // Anything left in toCheck is not pinned + for _, k := range toCheck.Keys() { + pinned = append(pinned, Pinned{Key: k, Mode: NotPinned}) + } + + return pinned, nil +} + +// RemovePinWithMode is for manually editing the pin structure. +// Use with care! If used improperly, garbage collection may not +// be successful. +func (p *pinner) RemovePinWithMode(c cid.Cid, mode Mode) { + p.lock.Lock() + defer p.lock.Unlock() + switch mode { + case Direct: + p.directPin.Remove(c) + case Recursive: + p.recursePin.Remove(c) + default: + // programmer error, panic OK + panic("unrecognized pin type") + } +} + +func cidSetWithValues(cids []cid.Cid) *cid.Set { + out := cid.NewSet() + for _, c := range cids { + out.Add(c) + } + return out +} + +// LoadPinner loads a pinner and its keysets from the given datastore +func LoadPinner(d ds.Datastore, dserv, internal ipld.DAGService) (Pinner, error) { + p := new(pinner) + + rootKey, err := d.Get(pinDatastoreKey) + if err != nil { + return nil, fmt.Errorf("cannot load pin state: %v", err) + } + rootCid, err := cid.Cast(rootKey) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithTimeout(context.TODO(), time.Second*5) + defer cancel() + + root, err := internal.Get(ctx, rootCid) + if err != nil { + return nil, fmt.Errorf("cannot find pinning root object: %v", err) + } + + rootpb, ok := root.(*mdag.ProtoNode) + if !ok { + return nil, mdag.ErrNotProtobuf + } + + internalset := cid.NewSet() + internalset.Add(rootCid) + recordInternal := internalset.Add + + { // load recursive set + recurseKeys, err := loadSet(ctx, internal, rootpb, linkRecursive, recordInternal) + if err != nil { + return nil, fmt.Errorf("cannot load recursive pins: %v", err) + } + p.recursePin = cidSetWithValues(recurseKeys) + } + + { // load direct set + directKeys, err := loadSet(ctx, internal, rootpb, linkDirect, recordInternal) + if err != nil { + return nil, fmt.Errorf("cannot load direct pins: %v", err) + } + p.directPin = cidSetWithValues(directKeys) + } + + p.internalPin = internalset + + // assign services + p.dserv = dserv + p.dstore = d + p.internal = internal + + return p, nil +} + +// DirectKeys returns a slice containing the directly pinned keys +func (p *pinner) DirectKeys() []cid.Cid { + p.lock.RLock() + defer p.lock.RUnlock() + + return p.directPin.Keys() +} + +// RecursiveKeys returns a slice containing the recursively pinned keys +func (p *pinner) RecursiveKeys() []cid.Cid { + p.lock.RLock() + defer p.lock.RUnlock() + + return p.recursePin.Keys() +} + +// Update updates a recursive pin from one cid to another +// this is more efficient than simply pinning the new one and unpinning the +// old one +func (p *pinner) Update(ctx context.Context, from, to cid.Cid, unpin bool) error { + p.lock.Lock() + defer p.lock.Unlock() + + if !p.recursePin.Has(from) { + return fmt.Errorf("'from' cid was not recursively pinned already") + } + + err := dagutils.DiffEnumerate(ctx, p.dserv, from, to) + if err != nil { + return err + } + + p.recursePin.Add(to) + if unpin { + p.recursePin.Remove(from) + } + return nil +} + +// Flush encodes and writes pinner keysets to the datastore +func (p *pinner) Flush() error { + p.lock.Lock() + defer p.lock.Unlock() + + ctx := context.TODO() + + internalset := cid.NewSet() + recordInternal := internalset.Add + + root := &mdag.ProtoNode{} + { + n, err := storeSet(ctx, p.internal, p.directPin.Keys(), recordInternal) + if err != nil { + return err + } + if err := root.AddNodeLink(linkDirect, n); err != nil { + return err + } + } + + { + n, err := storeSet(ctx, p.internal, p.recursePin.Keys(), recordInternal) + if err != nil { + return err + } + if err := root.AddNodeLink(linkRecursive, n); err != nil { + return err + } + } + + // add the empty node, its referenced by the pin sets but never created + err := p.internal.Add(ctx, new(mdag.ProtoNode)) + if err != nil { + return err + } + + err = p.internal.Add(ctx, root) + if err != nil { + return err + } + + k := root.Cid() + + internalset.Add(k) + if err := p.dstore.Put(pinDatastoreKey, k.Bytes()); err != nil { + return fmt.Errorf("cannot store pin state: %v", err) + } + p.internalPin = internalset + return nil +} + +// InternalPins returns all cids kept pinned for the internal state of the +// pinner +func (p *pinner) InternalPins() []cid.Cid { + p.lock.Lock() + defer p.lock.Unlock() + var out []cid.Cid + out = append(out, p.internalPin.Keys()...) + return out +} + +// PinWithMode allows the user to have fine grained control over pin +// counts +func (p *pinner) PinWithMode(c cid.Cid, mode Mode) { + p.lock.Lock() + defer p.lock.Unlock() + switch mode { + case Recursive: + p.recursePin.Add(c) + case Direct: + p.directPin.Add(c) + } +} + +// hasChild recursively looks for a Cid among the children of a root Cid. +// The visit function can be used to shortcut already-visited branches. +func hasChild(ng ipld.NodeGetter, root cid.Cid, child cid.Cid, visit func(cid.Cid) bool) (bool, error) { + links, err := ipld.GetLinks(context.TODO(), ng, root) + if err != nil { + return false, err + } + for _, lnk := range links { + c := lnk.Cid + if lnk.Cid.Equals(child) { + return true, nil + } + if visit(c) { + has, err := hasChild(ng, c, child, visit) + if err != nil { + return false, err + } + + if has { + return has, nil + } + } + } + return false, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/pin/set.go b/vendor/github.com/ipfs/go-ipfs/pin/set.go new file mode 100644 index 00000000..b050c31c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/pin/set.go @@ -0,0 +1,297 @@ +package pin + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "hash/fnv" + "sort" + + "github.com/ipfs/go-ipfs/pin/internal/pb" + "github.com/ipfs/go-merkledag" + + "github.com/gogo/protobuf/proto" + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +const ( + // defaultFanout specifies the default number of fan-out links per layer + defaultFanout = 256 + + // maxItems is the maximum number of items that will fit in a single bucket + maxItems = 8192 +) + +func hash(seed uint32, c cid.Cid) uint32 { + var buf [4]byte + binary.LittleEndian.PutUint32(buf[:], seed) + h := fnv.New32a() + _, _ = h.Write(buf[:]) + _, _ = h.Write(c.Bytes()) + return h.Sum32() +} + +type itemIterator func() (c cid.Cid, ok bool) + +type keyObserver func(cid.Cid) + +type sortByHash struct { + links []*ipld.Link +} + +func (s sortByHash) Len() int { + return len(s.links) +} + +func (s sortByHash) Less(a, b int) bool { + return bytes.Compare(s.links[a].Cid.Bytes(), s.links[b].Cid.Bytes()) == -1 +} + +func (s sortByHash) Swap(a, b int) { + s.links[a], s.links[b] = s.links[b], s.links[a] +} + +func storeItems(ctx context.Context, dag ipld.DAGService, estimatedLen uint64, depth uint32, iter itemIterator, internalKeys keyObserver) (*merkledag.ProtoNode, error) { + links := make([]*ipld.Link, 0, defaultFanout+maxItems) + for i := 0; i < defaultFanout; i++ { + links = append(links, &ipld.Link{Cid: emptyKey}) + } + + // add emptyKey to our set of internal pinset objects + n := &merkledag.ProtoNode{} + n.SetLinks(links) + + internalKeys(emptyKey) + + hdr := &pb.Set{ + Version: 1, + Fanout: defaultFanout, + Seed: depth, + } + if err := writeHdr(n, hdr); err != nil { + return nil, err + } + + if estimatedLen < maxItems { + // it'll probably fit + links := n.Links() + for i := 0; i < maxItems; i++ { + k, ok := iter() + if !ok { + // all done + break + } + + links = append(links, &ipld.Link{Cid: k}) + } + + n.SetLinks(links) + + // sort by hash, also swap item Data + s := sortByHash{ + links: n.Links()[defaultFanout:], + } + sort.Stable(s) + } + + hashed := make([][]cid.Cid, defaultFanout) + for { + // This loop essentially enumerates every single item in the set + // and maps them all into a set of buckets. Each bucket will be recursively + // turned into its own sub-set, and so on down the chain. Each sub-set + // gets added to the dagservice, and put into its place in a set nodes + // links array. + // + // Previously, the bucket was selected by taking an int32 from the hash of + // the input key + seed. This was erroneous as we would later be assigning + // the created sub-sets into an array of length 256 by the modulus of the + // int32 hash value with 256. This resulted in overwriting existing sub-sets + // and losing pins. The fix (a few lines down from this comment), is to + // map the hash value down to the 8 bit keyspace here while creating the + // buckets. This way, we avoid any overlapping later on. + k, ok := iter() + if !ok { + break + } + h := hash(depth, k) % defaultFanout + hashed[h] = append(hashed[h], k) + } + + for h, items := range hashed { + if len(items) == 0 { + // recursion base case + continue + } + + childIter := getCidListIterator(items) + + // recursively create a pinset from the items for this bucket index + child, err := storeItems(ctx, dag, uint64(len(items)), depth+1, childIter, internalKeys) + if err != nil { + return nil, err + } + + size, err := child.Size() + if err != nil { + return nil, err + } + + err = dag.Add(ctx, child) + if err != nil { + return nil, err + } + childKey := child.Cid() + + internalKeys(childKey) + + // overwrite the 'empty key' in the existing links array + n.Links()[h] = &ipld.Link{ + Cid: childKey, + Size: size, + } + } + return n, nil +} + +func readHdr(n *merkledag.ProtoNode) (*pb.Set, error) { + hdrLenRaw, consumed := binary.Uvarint(n.Data()) + if consumed <= 0 { + return nil, errors.New("invalid Set header length") + } + + pbdata := n.Data()[consumed:] + if hdrLenRaw > uint64(len(pbdata)) { + return nil, errors.New("impossibly large Set header length") + } + // as hdrLenRaw was <= an int, we now know it fits in an int + hdrLen := int(hdrLenRaw) + var hdr pb.Set + if err := proto.Unmarshal(pbdata[:hdrLen], &hdr); err != nil { + return nil, err + } + + if v := hdr.GetVersion(); v != 1 { + return nil, fmt.Errorf("unsupported Set version: %d", v) + } + if uint64(hdr.GetFanout()) > uint64(len(n.Links())) { + return nil, errors.New("impossibly large Fanout") + } + return &hdr, nil +} + +func writeHdr(n *merkledag.ProtoNode, hdr *pb.Set) error { + hdrData, err := proto.Marshal(hdr) + if err != nil { + return err + } + + // make enough space for the length prefix and the marshaled header data + data := make([]byte, binary.MaxVarintLen64, binary.MaxVarintLen64+len(hdrData)) + + // write the uvarint length of the header data + uvarlen := binary.PutUvarint(data, uint64(len(hdrData))) + + // append the actual protobuf data *after* the length value we wrote + data = append(data[:uvarlen], hdrData...) + + n.SetData(data) + return nil +} + +type walkerFunc func(idx int, link *ipld.Link) error + +func walkItems(ctx context.Context, dag ipld.DAGService, n *merkledag.ProtoNode, fn walkerFunc, children keyObserver) error { + hdr, err := readHdr(n) + if err != nil { + return err + } + // readHdr guarantees fanout is a safe value + fanout := hdr.GetFanout() + for i, l := range n.Links()[fanout:] { + if err := fn(i, l); err != nil { + return err + } + } + for _, l := range n.Links()[:fanout] { + c := l.Cid + children(c) + if c.Equals(emptyKey) { + continue + } + subtree, err := l.GetNode(ctx, dag) + if err != nil { + return err + } + + stpb, ok := subtree.(*merkledag.ProtoNode) + if !ok { + return merkledag.ErrNotProtobuf + } + + if err := walkItems(ctx, dag, stpb, fn, children); err != nil { + return err + } + } + return nil +} + +func loadSet(ctx context.Context, dag ipld.DAGService, root *merkledag.ProtoNode, name string, internalKeys keyObserver) ([]cid.Cid, error) { + l, err := root.GetNodeLink(name) + if err != nil { + return nil, err + } + + lnkc := l.Cid + internalKeys(lnkc) + + n, err := l.GetNode(ctx, dag) + if err != nil { + return nil, err + } + + pbn, ok := n.(*merkledag.ProtoNode) + if !ok { + return nil, merkledag.ErrNotProtobuf + } + + var res []cid.Cid + walk := func(idx int, link *ipld.Link) error { + res = append(res, link.Cid) + return nil + } + + if err := walkItems(ctx, dag, pbn, walk, internalKeys); err != nil { + return nil, err + } + return res, nil +} + +func getCidListIterator(cids []cid.Cid) itemIterator { + return func() (c cid.Cid, ok bool) { + if len(cids) == 0 { + return cid.Cid{}, false + } + + first := cids[0] + cids = cids[1:] + return first, true + } +} + +func storeSet(ctx context.Context, dag ipld.DAGService, cids []cid.Cid, internalKeys keyObserver) (*merkledag.ProtoNode, error) { + iter := getCidListIterator(cids) + + n, err := storeItems(ctx, dag, uint64(len(cids)), 0, iter, internalKeys) + if err != nil { + return nil, err + } + err = dag.Add(ctx, n) + if err != nil { + return nil, err + } + internalKeys(n.Cid()) + return n, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/Rules.mk b/vendor/github.com/ipfs/go-ipfs/plugin/Rules.mk new file mode 100644 index 00000000..1e26d2a3 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/Rules.mk @@ -0,0 +1,9 @@ +include mk/header.mk + +dir := $(d)/loader +include $(dir)/Rules.mk + +dir := $(d)/plugins +include $(dir)/Rules.mk + +include mk/footer.mk diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/daemon.go b/vendor/github.com/ipfs/go-ipfs/plugin/daemon.go new file mode 100644 index 00000000..8ed86b76 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/daemon.go @@ -0,0 +1,14 @@ +package plugin + +import ( + coreiface "github.com/ipfs/interface-go-ipfs-core" +) + +// PluginDaemon is an interface for daemon plugins. These plugins will be run on +// the daemon and will be given access to an implementation of the CoreAPI. +type PluginDaemon interface { + Plugin + + Start(coreiface.CoreAPI) error + Close() error +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/datastore.go b/vendor/github.com/ipfs/go-ipfs/plugin/datastore.go new file mode 100644 index 00000000..735eedc9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/datastore.go @@ -0,0 +1,14 @@ +package plugin + +import ( + "github.com/ipfs/go-ipfs/repo/fsrepo" +) + +// PluginDatastore is an interface that can be implemented to add handlers for +// for different datastores +type PluginDatastore interface { + Plugin + + DatastoreTypeName() string + DatastoreConfigParser() fsrepo.ConfigFromMap +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/ipld.go b/vendor/github.com/ipfs/go-ipfs/plugin/ipld.go new file mode 100644 index 00000000..5b45e9cd --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/ipld.go @@ -0,0 +1,16 @@ +package plugin + +import ( + "github.com/ipfs/go-ipfs/core/coredag" + + ipld "github.com/ipfs/go-ipld-format" +) + +// PluginIPLD is an interface that can be implemented to add handlers for +// for different IPLD formats +type PluginIPLD interface { + Plugin + + RegisterBlockDecoders(dec ipld.BlockDecoder) error + RegisterInputEncParsers(iec coredag.InputEncParsers) error +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/loader/Rules.mk b/vendor/github.com/ipfs/go-ipfs/plugin/loader/Rules.mk new file mode 100644 index 00000000..01f50e27 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/loader/Rules.mk @@ -0,0 +1,10 @@ +include mk/header.mk + +$(d)/preload.go: d:=$(d) +$(d)/preload.go: $(d)/preload_list $(d)/preload.sh + $(d)/preload.sh > $@ + go fmt $@ >/dev/null + +DEPS_GO += $(d)/preload.go + +include mk/footer.mk diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/loader/load_linux.go b/vendor/github.com/ipfs/go-ipfs/plugin/loader/load_linux.go new file mode 100644 index 00000000..19c1e994 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/loader/load_linux.go @@ -0,0 +1,68 @@ +// +build !noplugin + +package loader + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "plugin" + + iplugin "github.com/ipfs/go-ipfs/plugin" +) + +func init() { + loadPluginsFunc = linuxLoadFunc +} + +func linuxLoadFunc(pluginDir string) ([]iplugin.Plugin, error) { + var plugins []iplugin.Plugin + + err := filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + if fi != pluginDir { + log.Warningf("found directory inside plugins directory: %s", fi) + } + return nil + } + + if info.Mode().Perm()&0111 == 0 { + // file is not executable let's not load it + // this is to prevent loading plugins from for example non-executable + // mounts, some /tmp mounts are marked as such for security + log.Errorf("non-executable file in plugins directory: %s", fi) + return nil + } + + if newPlugins, err := loadPlugin(fi); err == nil { + plugins = append(plugins, newPlugins...) + } else { + return fmt.Errorf("loading plugin %s: %s", fi, err) + } + return nil + }) + + return plugins, err +} + +func loadPlugin(fi string) ([]iplugin.Plugin, error) { + pl, err := plugin.Open(fi) + if err != nil { + return nil, err + } + pls, err := pl.Lookup("Plugins") + if err != nil { + return nil, err + } + + typePls, ok := pls.(*[]iplugin.Plugin) + if !ok { + return nil, errors.New("filed 'Plugins' didn't contain correct type") + } + + return *typePls, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/loader/loader.go b/vendor/github.com/ipfs/go-ipfs/plugin/loader/loader.go new file mode 100644 index 00000000..b5a2d08e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/loader/loader.go @@ -0,0 +1,170 @@ +package loader + +import ( + "fmt" + "os" + "strings" + + coredag "github.com/ipfs/go-ipfs/core/coredag" + plugin "github.com/ipfs/go-ipfs/plugin" + fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" + + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" + coreiface "github.com/ipfs/interface-go-ipfs-core" + opentracing "github.com/opentracing/opentracing-go" +) + +var log = logging.Logger("plugin/loader") + +var loadPluginsFunc = func(string) ([]plugin.Plugin, error) { + return nil, nil +} + +// PluginLoader keeps track of loaded plugins +type PluginLoader struct { + plugins []plugin.Plugin +} + +// NewPluginLoader creates new plugin loader +func NewPluginLoader(pluginDir string) (*PluginLoader, error) { + plMap := make(map[string]plugin.Plugin) + for _, v := range preloadPlugins { + plMap[v.Name()] = v + } + + if pluginDir != "" { + newPls, err := loadDynamicPlugins(pluginDir) + if err != nil { + return nil, err + } + + for _, pl := range newPls { + if ppl, ok := plMap[pl.Name()]; ok { + // plugin is already preloaded + return nil, fmt.Errorf( + "plugin: %s, is duplicated in version: %s, "+ + "while trying to load dynamically: %s", + ppl.Name(), ppl.Version(), pl.Version()) + } + plMap[pl.Name()] = pl + } + } + + loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(plMap))} + + for _, v := range plMap { + loader.plugins = append(loader.plugins, v) + } + + return loader, nil +} + +func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) { + _, err := os.Stat(pluginDir) + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + + return loadPluginsFunc(pluginDir) +} + +// Initialize initializes all loaded plugins +func (loader *PluginLoader) Initialize() error { + for _, p := range loader.plugins { + err := p.Init() + if err != nil { + return err + } + } + + return nil +} + +// Inject hooks all the plugins into the appropriate subsystems. +func (loader *PluginLoader) Inject() error { + for _, pl := range loader.plugins { + if pl, ok := pl.(plugin.PluginIPLD); ok { + err := injectIPLDPlugin(pl) + if err != nil { + return err + } + } + if pl, ok := pl.(plugin.PluginTracer); ok { + err := injectTracerPlugin(pl) + if err != nil { + return err + } + } + if pl, ok := pl.(plugin.PluginDatastore); ok { + err := injectDatastorePlugin(pl) + if err != nil { + return err + } + } + } + return nil +} + +// Start starts all long-running plugins. +func (loader *PluginLoader) Start(iface coreiface.CoreAPI) error { + for i, pl := range loader.plugins { + if pl, ok := pl.(plugin.PluginDaemon); ok { + err := pl.Start(iface) + if err != nil { + _ = closePlugins(loader.plugins[i:]) + return err + } + } + } + return nil +} + +// StopDaemon stops all long-running plugins. +func (loader *PluginLoader) Close() error { + return closePlugins(loader.plugins) +} + +func closePlugins(plugins []plugin.Plugin) error { + var errs []string + for _, pl := range plugins { + if pl, ok := pl.(plugin.PluginDaemon); ok { + err := pl.Close() + if err != nil { + errs = append(errs, fmt.Sprintf( + "error closing plugin %s: %s", + pl.Name(), + err.Error(), + )) + } + } + } + if errs != nil { + return fmt.Errorf(strings.Join(errs, "\n")) + } + return nil +} + +func injectDatastorePlugin(pl plugin.PluginDatastore) error { + return fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser()) +} + +func injectIPLDPlugin(pl plugin.PluginIPLD) error { + err := pl.RegisterBlockDecoders(ipld.DefaultBlockDecoder) + if err != nil { + return err + } + return pl.RegisterInputEncParsers(coredag.DefaultInputEncParsers) +} + +func injectTracerPlugin(pl plugin.PluginTracer) error { + tracer, err := pl.InitTracer() + if err != nil { + return err + } + opentracing.SetGlobalTracer(tracer) + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.go b/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.go new file mode 100644 index 00000000..35c0e4ec --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.go @@ -0,0 +1,23 @@ +package loader + +import ( + "github.com/ipfs/go-ipfs/plugin" + pluginbadgerds "github.com/ipfs/go-ipfs/plugin/plugins/badgerds" + pluginflatfs "github.com/ipfs/go-ipfs/plugin/plugins/flatfs" + pluginipldgit "github.com/ipfs/go-ipfs/plugin/plugins/git" + pluginlevelds "github.com/ipfs/go-ipfs/plugin/plugins/levelds" + pluginpostgresds "github.com/ipfs/go-ipfs/plugin/plugins/postgresds" +) + + +// DO NOT EDIT THIS FILE +// This file is being generated as part of plugin build process +// To change it, modify the plugin/loader/preload.sh + +var preloadPlugins = []plugin.Plugin{ + pluginipldgit.Plugins[0], + pluginbadgerds.Plugins[0], + pluginflatfs.Plugins[0], + pluginlevelds.Plugins[0], + pluginpostgresds.Plugins[0], +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.sh b/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.sh new file mode 100755 index 00000000..5d000d0a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/loader/preload.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +to_preload() { + awk 'NF' "$DIR/preload_list" | sed '/^#/d' +} + +cat <::::", c.passfile) + } + c.host = envVars[0] + c.port = envVars[1] + c.dbname = envVars[2] + c.user = envVars[3] + c.password = envVars[4] + return &c, nil + } + c.host, ok = params["host"].(string) + if !ok { + return nil, fmt.Errorf("'path' field was not a string") + } + c.port, ok = params["port"].(string) + if !ok { + return nil, fmt.Errorf("'port' field was not a string") + } + c.user, ok = params["user"].(string) + if !ok { + return nil, fmt.Errorf("'user' field was not a string") + } + c.dbname, ok = params["dbname"].(string) + if !ok { + return nil, fmt.Errorf("'dbname' field was not a string") + } + c.password, ok = params["password"].(string) + if !ok { + return nil, fmt.Errorf("'password' field was not a string") + } + return &c, nil + } +} + +func (c *datastoreConfig) DiskSpec() fsrepo.DiskSpec { + return map[string]interface{}{ + "type": "postgres", + "user": c.user, + "database": c.dbname, + } +} + +func (c *datastoreConfig) Create(path string) (repo.Datastore, error) { + pg := postgresdb.Options{ + Host: c.host, + User: c.user, + Database: c.dbname, + Password: c.password, + Port: c.port, + } + ds, err := pg.Create() + if err != nil { + fmt.Println("error loading pg: ", err) + return ds, err + } + return ds, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/plugin/tracer.go b/vendor/github.com/ipfs/go-ipfs/plugin/tracer.go new file mode 100644 index 00000000..2f1d8f81 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/plugin/tracer.go @@ -0,0 +1,11 @@ +package plugin + +import ( + "github.com/opentracing/opentracing-go" +) + +// PluginTracer is an interface that can be implemented to add a tracer +type PluginTracer interface { + Plugin + InitTracer() (opentracing.Tracer, error) +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/offline.go b/vendor/github.com/ipfs/go-ipfs/provider/offline.go new file mode 100644 index 00000000..5511364e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/offline.go @@ -0,0 +1,28 @@ +package provider + +import ( + "context" + "github.com/ipfs/go-cid" +) + +type offlineProvider struct{} + +// NewOfflineProvider creates a ProviderSystem that does nothing +func NewOfflineProvider() System { + return &offlineProvider{} +} + +func (op *offlineProvider) Run() { +} + +func (op *offlineProvider) Close() error { + return nil +} + +func (op *offlineProvider) Provide(cid.Cid) error { + return nil +} + +func (op *offlineProvider) Reprovide(context.Context) error { + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/provider.go b/vendor/github.com/ipfs/go-ipfs/provider/provider.go new file mode 100644 index 00000000..7dec4c17 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/provider.go @@ -0,0 +1,26 @@ +package provider + +import ( + "context" + "github.com/ipfs/go-cid" +) + +// Provider announces blocks to the network +type Provider interface { + // Run is used to begin processing the provider work + Run() + // Provide takes a cid and makes an attempt to announce it to the network + Provide(cid.Cid) error + // Close stops the provider + Close() error +} + +// Reprovider reannounces blocks to the network +type Reprovider interface { + // Run is used to begin processing the reprovider work and waiting for reprovide triggers + Run() + // Trigger a reprovide + Trigger(context.Context) error + // Close stops the reprovider + Close() error +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/queue/queue.go b/vendor/github.com/ipfs/go-ipfs/provider/queue/queue.go new file mode 100644 index 00000000..2afbc81e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/queue/queue.go @@ -0,0 +1,211 @@ +package queue + +import ( + "context" + "fmt" + "strconv" + "strings" + + cid "github.com/ipfs/go-cid" + datastore "github.com/ipfs/go-datastore" + namespace "github.com/ipfs/go-datastore/namespace" + query "github.com/ipfs/go-datastore/query" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("provider.queue") + +// Queue provides a durable, FIFO interface to the datastore for storing cids +// +// Durability just means that cids in the process of being provided when a +// crash or shutdown occurs will still be in the queue when the node is +// brought back online. +type Queue struct { + // used to differentiate queues in datastore + // e.g. provider vs reprovider + name string + ctx context.Context + tail uint64 + head uint64 + ds datastore.Datastore // Must be threadsafe + dequeue chan cid.Cid + enqueue chan cid.Cid + close context.CancelFunc + closed chan struct{} +} + +// NewQueue creates a queue for cids +func NewQueue(ctx context.Context, name string, ds datastore.Datastore) (*Queue, error) { + namespaced := namespace.Wrap(ds, datastore.NewKey("/"+name+"/queue/")) + head, tail, err := getQueueHeadTail(ctx, namespaced) + if err != nil { + return nil, err + } + cancelCtx, cancel := context.WithCancel(ctx) + q := &Queue{ + name: name, + ctx: cancelCtx, + head: head, + tail: tail, + ds: namespaced, + dequeue: make(chan cid.Cid), + enqueue: make(chan cid.Cid), + close: cancel, + closed: make(chan struct{}, 1), + } + q.work() + return q, nil +} + +// Close stops the queue +func (q *Queue) Close() error { + q.close() + <-q.closed + return nil +} + +// Enqueue puts a cid in the queue +func (q *Queue) Enqueue(cid cid.Cid) { + select { + case q.enqueue <- cid: + case <-q.ctx.Done(): + } +} + +// Dequeue returns a channel that if listened to will remove entries from the queue +func (q *Queue) Dequeue() <-chan cid.Cid { + return q.dequeue +} + +// Look for next Cid in the queue and return it. Skip over gaps and mangled data +func (q *Queue) nextEntry() (datastore.Key, cid.Cid) { + for { + if q.head >= q.tail { + return datastore.Key{}, cid.Undef + } + + key := q.queueKey(q.head) + value, err := q.ds.Get(key) + + if err != nil { + if err == datastore.ErrNotFound { + log.Warningf("Error missing entry in queue: %s", key) + } else { + log.Errorf("Error fetching from queue: %s", err) + } + q.head++ // move on + continue + } + + c, err := cid.Parse(value) + if err != nil { + log.Warningf("Error marshalling Cid from queue: ", err) + q.head++ + err = q.ds.Delete(key) + if err != nil { + log.Warningf("Provider queue failed to delete: %s", key) + } + continue + } + + return key, c + } +} + +// Run dequeues and enqueues when available. +func (q *Queue) work() { + go func() { + var k datastore.Key = datastore.Key{} + var c cid.Cid = cid.Undef + + defer func() { + close(q.closed) + }() + + for { + if c == cid.Undef { + k, c = q.nextEntry() + } + + // If c != cid.Undef set dequeue and attempt write, otherwise wait for enqueue + var dequeue chan cid.Cid + if c != cid.Undef { + dequeue = q.dequeue + } + + select { + case toQueue := <-q.enqueue: + nextKey := q.queueKey(q.tail) + + if err := q.ds.Put(nextKey, toQueue.Bytes()); err != nil { + log.Errorf("Failed to enqueue cid: %s", err) + continue + } + + q.tail++ + case dequeue <- c: + err := q.ds.Delete(k) + + if err != nil { + log.Errorf("Failed to delete queued cid %s with key %s: %s", c, k, err) + continue + } + c = cid.Undef + q.head++ + case <-q.ctx.Done(): + return + } + } + }() +} + +func (q *Queue) queueKey(id uint64) datastore.Key { + s := fmt.Sprintf("%016X", id) + return datastore.NewKey(s) +} + +func getQueueHeadTail(ctx context.Context, datastore datastore.Datastore) (uint64, uint64, error) { + head, err := getQueueHead(datastore) + if err != nil { + return 0, 0, err + } + tail, err := getQueueTail(datastore) + if err != nil { + return 0, 0, err + } + return head, tail, nil +} + +func getQueueHead(ds datastore.Datastore) (uint64, error) { + return getFirstIDByOrder(ds, query.OrderByKey{}) +} + +func getQueueTail(ds datastore.Datastore) (uint64, error) { + tail, err := getFirstIDByOrder(ds, query.OrderByKeyDescending{}) + if err != nil { + return 0, err + } + if tail > 0 { + tail++ + } + return tail, nil +} + +func getFirstIDByOrder(ds datastore.Datastore, order query.Order) (uint64, error) { + q := query.Query{Orders: []query.Order{order}} + results, err := ds.Query(q) + if err != nil { + return 0, err + } + defer results.Close() + r, ok := results.NextSync() + if !ok { + return 0, nil + } + trimmed := strings.TrimPrefix(r.Key, "/") + id, err := strconv.ParseUint(trimmed, 16, 64) + if err != nil { + return 0, err + } + return id, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/simple/provider.go b/vendor/github.com/ipfs/go-ipfs/provider/simple/provider.go new file mode 100644 index 00000000..abe13ce5 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/simple/provider.go @@ -0,0 +1,72 @@ +// Package simple implements structures and methods to provide blocks, +// keep track of which blocks are provided, and to allow those blocks to +// be reprovided. +package simple + +import ( + "context" + + cid "github.com/ipfs/go-cid" + q "github.com/ipfs/go-ipfs/provider/queue" + logging "github.com/ipfs/go-log" + routing "github.com/libp2p/go-libp2p-core/routing" +) + +var logP = logging.Logger("provider.simple") + +const provideOutgoingWorkerLimit = 8 + +// Provider announces blocks to the network +type Provider struct { + ctx context.Context + // the CIDs for which provide announcements should be made + queue *q.Queue + // used to announce providing to the network + contentRouting routing.ContentRouting +} + +// NewProvider creates a provider that announces blocks to the network using a content router +func NewProvider(ctx context.Context, queue *q.Queue, contentRouting routing.ContentRouting) *Provider { + return &Provider{ + ctx: ctx, + queue: queue, + contentRouting: contentRouting, + } +} + +// Close stops the provider +func (p *Provider) Close() error { + p.queue.Close() + return nil +} + +// Run workers to handle provide requests. +func (p *Provider) Run() { + p.handleAnnouncements() +} + +// Provide the given cid using specified strategy. +func (p *Provider) Provide(root cid.Cid) error { + p.queue.Enqueue(root) + return nil +} + +// Handle all outgoing cids by providing (announcing) them +func (p *Provider) handleAnnouncements() { + for workers := 0; workers < provideOutgoingWorkerLimit; workers++ { + go func() { + for p.ctx.Err() == nil { + select { + case <-p.ctx.Done(): + return + case c := <-p.queue.Dequeue(): + logP.Info("announce - start - ", c) + if err := p.contentRouting.Provide(p.ctx, c, true); err != nil { + logP.Warningf("Unable to provide entry: %s, %s", c, err) + } + logP.Info("announce - end - ", c) + } + } + }() + } +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/simple/reprovide.go b/vendor/github.com/ipfs/go-ipfs/provider/simple/reprovide.go new file mode 100644 index 00000000..ce5c7181 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/simple/reprovide.go @@ -0,0 +1,225 @@ +package simple + +import ( + "context" + "fmt" + "time" + + backoff "github.com/cenkalti/backoff" + cid "github.com/ipfs/go-cid" + cidutil "github.com/ipfs/go-cidutil" + blocks "github.com/ipfs/go-ipfs-blockstore" + pin "github.com/ipfs/go-ipfs/pin" + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" + merkledag "github.com/ipfs/go-merkledag" + verifcid "github.com/ipfs/go-verifcid" + routing "github.com/libp2p/go-libp2p-core/routing" +) + +var logR = logging.Logger("reprovider.simple") + +//KeyChanFunc is function streaming CIDs to pass to content routing +type KeyChanFunc func(context.Context) (<-chan cid.Cid, error) +type doneFunc func(error) + +// Reprovider reannounces blocks to the network +type Reprovider struct { + ctx context.Context + trigger chan doneFunc + + // The routing system to provide values through + rsys routing.ContentRouting + + keyProvider KeyChanFunc + + tick time.Duration +} + +// NewReprovider creates new Reprovider instance. +func NewReprovider(ctx context.Context, reprovideIniterval time.Duration, rsys routing.ContentRouting, keyProvider KeyChanFunc) *Reprovider { + return &Reprovider{ + ctx: ctx, + trigger: make(chan doneFunc), + + rsys: rsys, + keyProvider: keyProvider, + tick: reprovideIniterval, + } +} + +// Close the reprovider +func (rp *Reprovider) Close() error { + return nil +} + +// Run re-provides keys with 'tick' interval or when triggered +func (rp *Reprovider) Run() { + // dont reprovide immediately. + // may have just started the daemon and shutting it down immediately. + // probability( up another minute | uptime ) increases with uptime. + after := time.After(time.Minute) + var done doneFunc + for { + if rp.tick == 0 { + after = make(chan time.Time) + } + + select { + case <-rp.ctx.Done(): + return + case done = <-rp.trigger: + case <-after: + } + + //'mute' the trigger channel so when `ipfs bitswap reprovide` is called + //a 'reprovider is already running' error is returned + unmute := rp.muteTrigger() + + err := rp.Reprovide() + if err != nil { + logR.Debug(err) + } + + if done != nil { + done(err) + } + + unmute() + + after = time.After(rp.tick) + } +} + +// Reprovide registers all keys given by rp.keyProvider to libp2p content routing +func (rp *Reprovider) Reprovide() error { + keychan, err := rp.keyProvider(rp.ctx) + if err != nil { + return fmt.Errorf("failed to get key chan: %s", err) + } + for c := range keychan { + // hash security + if err := verifcid.ValidateCid(c); err != nil { + logR.Errorf("insecure hash in reprovider, %s (%s)", c, err) + continue + } + op := func() error { + err := rp.rsys.Provide(rp.ctx, c, true) + if err != nil { + logR.Debugf("Failed to provide key: %s", err) + } + return err + } + + // TODO: this backoff library does not respect our context, we should + // eventually work contexts into it. low priority. + err := backoff.Retry(op, backoff.NewExponentialBackOff()) + if err != nil { + logR.Debugf("Providing failed after number of retries: %s", err) + return err + } + } + return nil +} + +// Trigger starts reprovision process in rp.Run and waits for it +func (rp *Reprovider) Trigger(ctx context.Context) error { + progressCtx, done := context.WithCancel(ctx) + + var err error + df := func(e error) { + err = e + done() + } + + select { + case <-rp.ctx.Done(): + return context.Canceled + case <-ctx.Done(): + return context.Canceled + case rp.trigger <- df: + <-progressCtx.Done() + return err + } +} + +func (rp *Reprovider) muteTrigger() context.CancelFunc { + ctx, cf := context.WithCancel(rp.ctx) + go func() { + defer cf() + for { + select { + case <-ctx.Done(): + return + case done := <-rp.trigger: + done(fmt.Errorf("reprovider is already running")) + } + } + }() + + return cf +} + +// Strategies + +// NewBlockstoreProvider returns key provider using bstore.AllKeysChan +func NewBlockstoreProvider(bstore blocks.Blockstore) KeyChanFunc { + return func(ctx context.Context) (<-chan cid.Cid, error) { + return bstore.AllKeysChan(ctx) + } +} + +// NewPinnedProvider returns provider supplying pinned keys +func NewPinnedProvider(onlyRoots bool) func(pin.Pinner, ipld.DAGService) KeyChanFunc { + return func(pinning pin.Pinner, dag ipld.DAGService) KeyChanFunc { + return func(ctx context.Context) (<-chan cid.Cid, error) { + set, err := pinSet(ctx, pinning, dag, onlyRoots) + if err != nil { + return nil, err + } + + outCh := make(chan cid.Cid) + go func() { + defer close(outCh) + for c := range set.New { + select { + case <-ctx.Done(): + return + case outCh <- c: + } + } + + }() + + return outCh, nil + } + } +} + +func pinSet(ctx context.Context, pinning pin.Pinner, dag ipld.DAGService, onlyRoots bool) (*cidutil.StreamingSet, error) { + set := cidutil.NewStreamingSet() + + go func() { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + defer close(set.New) + + for _, key := range pinning.DirectKeys() { + set.Visitor(ctx)(key) + } + + for _, key := range pinning.RecursiveKeys() { + set.Visitor(ctx)(key) + + if !onlyRoots { + err := merkledag.EnumerateChildren(ctx, merkledag.GetLinksWithDAG(dag), key, set.Visitor(ctx)) + if err != nil { + logR.Errorf("reprovide indirect pins: %s", err) + return + } + } + } + }() + + return set, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/provider/system.go b/vendor/github.com/ipfs/go-ipfs/provider/system.go new file mode 100644 index 00000000..b3e17ee4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/provider/system.go @@ -0,0 +1,59 @@ +package provider + +import ( + "context" + "github.com/ipfs/go-cid" +) + +// System defines the interface for interacting with the value +// provider system +type System interface { + Run() + Close() error + Provide(cid.Cid) error + Reprovide(context.Context) error +} + +type system struct { + provider Provider + reprovider Reprovider +} + +// NewSystem constructs a new provider system from a provider and reprovider +func NewSystem(provider Provider, reprovider Reprovider) System { + return &system{provider, reprovider} +} + +// Run the provider system by running the provider and reprovider +func (s *system) Run() { + go s.provider.Run() + go s.reprovider.Run() +} + +// Close the provider and reprovider +func (s *system) Close() error { + var errs []error + + if err := s.provider.Close(); err != nil { + errs = append(errs, err) + } + + if err := s.reprovider.Close(); err != nil { + errs = append(errs, err) + } + + if len(errs) > 0 { + return errs[0] + } + return nil +} + +// Provide a value +func (s *system) Provide(cid cid.Cid) error { + return s.provider.Provide(cid) +} + +// Reprovide all the previously provided values +func (s *system) Reprovide(ctx context.Context) error { + return s.reprovider.Trigger(ctx) +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/common/common.go b/vendor/github.com/ipfs/go-ipfs/repo/common/common.go new file mode 100644 index 00000000..dc1e7c50 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/common/common.go @@ -0,0 +1,56 @@ +package common + +import ( + "fmt" + "strings" +) + +func MapGetKV(v map[string]interface{}, key string) (interface{}, error) { + var ok bool + var mcursor map[string]interface{} + var cursor interface{} = v + + parts := strings.Split(key, ".") + for i, part := range parts { + sofar := strings.Join(parts[:i], ".") + + mcursor, ok = cursor.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%s key is not a map", sofar) + } + + cursor, ok = mcursor[part] + if !ok { + return nil, fmt.Errorf("%s key has no attributes", sofar) + } + } + return cursor, nil +} + +func MapSetKV(v map[string]interface{}, key string, value interface{}) error { + var ok bool + var mcursor map[string]interface{} + var cursor interface{} = v + + parts := strings.Split(key, ".") + for i, part := range parts { + mcursor, ok = cursor.(map[string]interface{}) + if !ok { + sofar := strings.Join(parts[:i], ".") + return fmt.Errorf("%s key is not a map", sofar) + } + + // last part? set here + if i == (len(parts) - 1) { + mcursor[part] = value + break + } + + cursor, ok = mcursor[part] + if !ok || cursor == nil { // create map if this is empty or is null + mcursor[part] = map[string]interface{}{} + cursor = mcursor[part] + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/datastores.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/datastores.go new file mode 100644 index 00000000..8cdf25fc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/datastores.go @@ -0,0 +1,248 @@ +package fsrepo + +import ( + "bytes" + "encoding/json" + "fmt" + "sort" + + "github.com/ipfs/go-ipfs/repo" + + ds "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/mount" + dssync "github.com/ipfs/go-datastore/sync" + "github.com/ipfs/go-ds-measure" +) + +// ConfigFromMap creates a new datastore config from a map +type ConfigFromMap func(map[string]interface{}) (DatastoreConfig, error) + +// DatastoreConfig is an abstraction of a datastore config. A "spec" +// is first converted to a DatastoreConfig and then Create() is called +// to instantiate a new datastore +type DatastoreConfig interface { + // DiskSpec returns a minimal configuration of the datastore + // represting what is stored on disk. Run time values are + // excluded. + DiskSpec() DiskSpec + + // Create instantiate a new datastore from this config + Create(path string) (repo.Datastore, error) +} + +// DiskSpec is a minimal representation of the characteristic values of the +// datastore. If two diskspecs are the same, the loader assumes that they refer +// to exactly the same datastore. If they differ at all, it is assumed they are +// completely different datastores and a migration will be performed. Runtime +// values such as cache options or concurrency options should not be added +// here. +type DiskSpec map[string]interface{} + +// Bytes returns a minimal JSON encoding of the DiskSpec +func (spec DiskSpec) Bytes() []byte { + b, err := json.Marshal(spec) + if err != nil { + // should not happen + panic(err) + } + return bytes.TrimSpace(b) +} + +// String returns a minimal JSON encoding of the DiskSpec +func (spec DiskSpec) String() string { + return string(spec.Bytes()) +} + +var datastores map[string]ConfigFromMap + +func init() { + datastores = map[string]ConfigFromMap{ + "mount": MountDatastoreConfig, + "mem": MemDatastoreConfig, + "log": LogDatastoreConfig, + "measure": MeasureDatastoreConfig, + } +} + +func AddDatastoreConfigHandler(name string, dsc ConfigFromMap) error { + _, ok := datastores[name] + if ok { + return fmt.Errorf("already have a datastore named %q", name) + } + + datastores[name] = dsc + return nil +} + +// AnyDatastoreConfig returns a DatastoreConfig from a spec based on +// the "type" parameter +func AnyDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { + which, ok := params["type"].(string) + if !ok { + return nil, fmt.Errorf("'type' field missing or not a string") + } + fun, ok := datastores[which] + if !ok { + return nil, fmt.Errorf("unknown datastore type: %s", which) + } + return fun(params) +} + +type mountDatastoreConfig struct { + mounts []premount +} + +type premount struct { + ds DatastoreConfig + prefix ds.Key +} + +// MountDatastoreConfig returns a mount DatastoreConfig from a spec +func MountDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { + var res mountDatastoreConfig + mounts, ok := params["mounts"].([]interface{}) + if !ok { + return nil, fmt.Errorf("'mounts' field is missing or not an array") + } + for _, iface := range mounts { + cfg, ok := iface.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("expected map for mountpoint") + } + + child, err := AnyDatastoreConfig(cfg) + if err != nil { + return nil, err + } + + prefix, found := cfg["mountpoint"] + if !found { + return nil, fmt.Errorf("no 'mountpoint' on mount") + } + + res.mounts = append(res.mounts, premount{ + ds: child, + prefix: ds.NewKey(prefix.(string)), + }) + } + sort.Slice(res.mounts, + func(i, j int) bool { + return res.mounts[i].prefix.String() > res.mounts[j].prefix.String() + }) + + return &res, nil +} + +func (c *mountDatastoreConfig) DiskSpec() DiskSpec { + cfg := map[string]interface{}{"type": "mount"} + mounts := make([]interface{}, len(c.mounts)) + for i, m := range c.mounts { + c := m.ds.DiskSpec() + if c == nil { + c = make(map[string]interface{}) + } + c["mountpoint"] = m.prefix.String() + mounts[i] = c + } + cfg["mounts"] = mounts + return cfg +} + +func (c *mountDatastoreConfig) Create(path string) (repo.Datastore, error) { + mounts := make([]mount.Mount, len(c.mounts)) + for i, m := range c.mounts { + ds, err := m.ds.Create(path) + if err != nil { + return nil, err + } + mounts[i].Datastore = ds + mounts[i].Prefix = m.prefix + } + return mount.New(mounts), nil +} + +type memDatastoreConfig struct { + cfg map[string]interface{} +} + +// MemDatastoreConfig returns a memory DatastoreConfig from a spec +func MemDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { + return &memDatastoreConfig{params}, nil +} + +func (c *memDatastoreConfig) DiskSpec() DiskSpec { + return nil +} + +func (c *memDatastoreConfig) Create(string) (repo.Datastore, error) { + return dssync.MutexWrap(ds.NewMapDatastore()), nil +} + +type logDatastoreConfig struct { + child DatastoreConfig + name string +} + +// LogDatastoreConfig returns a log DatastoreConfig from a spec +func LogDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { + childField, ok := params["child"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("'child' field is missing or not a map") + } + child, err := AnyDatastoreConfig(childField) + if err != nil { + return nil, err + } + name, ok := params["name"].(string) + if !ok { + return nil, fmt.Errorf("'name' field was missing or not a string") + } + return &logDatastoreConfig{child, name}, nil + +} + +func (c *logDatastoreConfig) Create(path string) (repo.Datastore, error) { + child, err := c.child.Create(path) + if err != nil { + return nil, err + } + return ds.NewLogDatastore(child, c.name), nil +} + +func (c *logDatastoreConfig) DiskSpec() DiskSpec { + return c.child.DiskSpec() +} + +type measureDatastoreConfig struct { + child DatastoreConfig + prefix string +} + +// MeasureDatastoreConfig returns a measure DatastoreConfig from a spec +func MeasureDatastoreConfig(params map[string]interface{}) (DatastoreConfig, error) { + childField, ok := params["child"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("'child' field is missing or not a map") + } + child, err := AnyDatastoreConfig(childField) + if err != nil { + return nil, err + } + prefix, ok := params["prefix"].(string) + if !ok { + return nil, fmt.Errorf("'prefix' field was missing or not a string") + } + return &measureDatastoreConfig{child, prefix}, nil +} + +func (c *measureDatastoreConfig) DiskSpec() DiskSpec { + return c.child.DiskSpec() +} + +func (c measureDatastoreConfig) Create(path string) (repo.Datastore, error) { + child, err := c.child.Create(path) + if err != nil { + return nil, err + } + return measure.New(c.prefix, child), nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/doc.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/doc.go new file mode 100644 index 00000000..50d52855 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/doc.go @@ -0,0 +1,20 @@ +// package fsrepo +// +// TODO explain the package roadmap... +// +// .ipfs/ +// ├── client/ +// | ├── client.lock <------ protects client/ + signals its own pid +// │ ├── ipfs-client.cpuprof +// │ └── ipfs-client.memprof +// ├── config +// ├── daemon/ +// │ ├── daemon.lock <------ protects daemon/ + signals its own address +// │ ├── ipfs-daemon.cpuprof +// │ └── ipfs-daemon.memprof +// ├── datastore/ +// ├── repo.lock <------ protects datastore/ and config +// └── version +package fsrepo + +// TODO prevent multiple daemons from running diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/fsrepo.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/fsrepo.go new file mode 100644 index 00000000..d35c9714 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/fsrepo.go @@ -0,0 +1,720 @@ +package fsrepo + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + + filestore "github.com/ipfs/go-ipfs/filestore" + keystore "github.com/ipfs/go-ipfs/keystore" + repo "github.com/ipfs/go-ipfs/repo" + "github.com/ipfs/go-ipfs/repo/common" + mfsr "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" + dir "github.com/ipfs/go-ipfs/thirdparty/dir" + + ds "github.com/ipfs/go-datastore" + measure "github.com/ipfs/go-ds-measure" + lockfile "github.com/ipfs/go-fs-lock" + config "github.com/ipfs/go-ipfs-config" + serialize "github.com/ipfs/go-ipfs-config/serialize" + util "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" + homedir "github.com/mitchellh/go-homedir" + ma "github.com/multiformats/go-multiaddr" +) + +// LockFile is the filename of the repo lock, relative to config dir +// TODO rename repo lock and hide name +const LockFile = "repo.lock" + +var log = logging.Logger("fsrepo") + +// version number that we are currently expecting to see +var RepoVersion = 7 + +var migrationInstructions = `See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md +Sorry for the inconvenience. In the future, these will run automatically.` + +var programTooLowMessage = `Your programs version (%d) is lower than your repos (%d). +Please update ipfs to a version that supports the existing repo, or run +a migration in reverse. + +See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md for details.` + +var ( + ErrNoVersion = errors.New("no version file found, please run 0-to-1 migration tool.\n" + migrationInstructions) + ErrOldRepo = errors.New("ipfs repo found in old '~/.go-ipfs' location, please run migration tool.\n" + migrationInstructions) + ErrNeedMigration = errors.New("ipfs repo needs migration") +) + +type NoRepoError struct { + Path string +} + +var _ error = NoRepoError{} + +func (err NoRepoError) Error() string { + return fmt.Sprintf("no IPFS repo found in %s.\nplease run: 'ipfs init'", err.Path) +} + +const apiFile = "api" +const swarmKeyFile = "swarm.key" + +const specFn = "datastore_spec" + +var ( + + // packageLock must be held to while performing any operation that modifies an + // FSRepo's state field. This includes Init, Open, Close, and Remove. + packageLock sync.Mutex + + // onlyOne keeps track of open FSRepo instances. + // + // TODO: once command Context / Repo integration is cleaned up, + // this can be removed. Right now, this makes ConfigCmd.Run + // function try to open the repo twice: + // + // $ ipfs daemon & + // $ ipfs config foo + // + // The reason for the above is that in standalone mode without the + // daemon, `ipfs config` tries to save work by not building the + // full IpfsNode, but accessing the Repo directly. + onlyOne repo.OnlyOne +) + +// FSRepo represents an IPFS FileSystem Repo. It is safe for use by multiple +// callers. +type FSRepo struct { + // has Close been called already + closed bool + // path is the file-system path + path string + // lockfile is the file system lock to prevent others from opening + // the same fsrepo path concurrently + lockfile io.Closer + config *config.Config + ds repo.Datastore + keystore keystore.Keystore + filemgr *filestore.FileManager +} + +var _ repo.Repo = (*FSRepo)(nil) + +// Open the FSRepo at path. Returns an error if the repo is not +// initialized. +func Open(repoPath string) (repo.Repo, error) { + fn := func() (repo.Repo, error) { + return open(repoPath) + } + return onlyOne.Open(repoPath, fn) +} + +func open(repoPath string) (repo.Repo, error) { + packageLock.Lock() + defer packageLock.Unlock() + + r, err := newFSRepo(repoPath) + if err != nil { + return nil, err + } + + // Check if its initialized + if err := checkInitialized(r.path); err != nil { + return nil, err + } + + r.lockfile, err = lockfile.Lock(r.path, LockFile) + if err != nil { + return nil, err + } + keepLocked := false + defer func() { + // unlock on error, leave it locked on success + if !keepLocked { + r.lockfile.Close() + } + }() + + // Check version, and error out if not matching + ver, err := mfsr.RepoPath(r.path).Version() + if err != nil { + if os.IsNotExist(err) { + return nil, ErrNoVersion + } + return nil, err + } + + if RepoVersion > ver { + return nil, ErrNeedMigration + } else if ver > RepoVersion { + // program version too low for existing repo + return nil, fmt.Errorf(programTooLowMessage, RepoVersion, ver) + } + + // check repo path, then check all constituent parts. + if err := dir.Writable(r.path); err != nil { + return nil, err + } + + if err := r.openConfig(); err != nil { + return nil, err + } + + if err := r.openDatastore(); err != nil { + return nil, err + } + + if err := r.openKeystore(); err != nil { + return nil, err + } + + if r.config.Experimental.FilestoreEnabled || r.config.Experimental.UrlstoreEnabled { + r.filemgr = filestore.NewFileManager(r.ds, filepath.Dir(r.path)) + r.filemgr.AllowFiles = r.config.Experimental.FilestoreEnabled + r.filemgr.AllowUrls = r.config.Experimental.UrlstoreEnabled + } + + keepLocked = true + return r, nil +} + +func newFSRepo(rpath string) (*FSRepo, error) { + expPath, err := homedir.Expand(filepath.Clean(rpath)) + if err != nil { + return nil, err + } + + return &FSRepo{path: expPath}, nil +} + +func checkInitialized(path string) error { + if !isInitializedUnsynced(path) { + alt := strings.Replace(path, ".ipfs", ".go-ipfs", 1) + if isInitializedUnsynced(alt) { + return ErrOldRepo + } + return NoRepoError{Path: path} + } + return nil +} + +// ConfigAt returns an error if the FSRepo at the given path is not +// initialized. This function allows callers to read the config file even when +// another process is running and holding the lock. +func ConfigAt(repoPath string) (*config.Config, error) { + + // packageLock must be held to ensure that the Read is atomic. + packageLock.Lock() + defer packageLock.Unlock() + + configFilename, err := config.Filename(repoPath) + if err != nil { + return nil, err + } + return serialize.Load(configFilename) +} + +// configIsInitialized returns true if the repo is initialized at +// provided |path|. +func configIsInitialized(path string) bool { + configFilename, err := config.Filename(path) + if err != nil { + return false + } + if !util.FileExists(configFilename) { + return false + } + return true +} + +func initConfig(path string, conf *config.Config) error { + if configIsInitialized(path) { + return nil + } + configFilename, err := config.Filename(path) + if err != nil { + return err + } + // initialization is the one time when it's okay to write to the config + // without reading the config from disk and merging any user-provided keys + // that may exist. + if err := serialize.WriteConfigFile(configFilename, conf); err != nil { + return err + } + + return nil +} + +func initSpec(path string, conf map[string]interface{}) error { + fn, err := config.Path(path, specFn) + if err != nil { + return err + } + + if util.FileExists(fn) { + return nil + } + + dsc, err := AnyDatastoreConfig(conf) + if err != nil { + return err + } + bytes := dsc.DiskSpec().Bytes() + + return ioutil.WriteFile(fn, bytes, 0600) +} + +// Init initializes a new FSRepo at the given path with the provided config. +// TODO add support for custom datastores. +func Init(repoPath string, conf *config.Config) error { + + // packageLock must be held to ensure that the repo is not initialized more + // than once. + packageLock.Lock() + defer packageLock.Unlock() + + if isInitializedUnsynced(repoPath) { + return nil + } + + if err := initConfig(repoPath, conf); err != nil { + return err + } + + if err := initSpec(repoPath, conf.Datastore.Spec); err != nil { + return err + } + + if err := mfsr.RepoPath(repoPath).WriteVersion(RepoVersion); err != nil { + return err + } + + return nil +} + +// LockedByOtherProcess returns true if the FSRepo is locked by another +// process. If true, then the repo cannot be opened by this process. +func LockedByOtherProcess(repoPath string) (bool, error) { + repoPath = filepath.Clean(repoPath) + locked, err := lockfile.Locked(repoPath, LockFile) + if locked { + log.Debugf("(%t)<->Lock is held at %s", locked, repoPath) + } + return locked, err +} + +// APIAddr returns the registered API addr, according to the api file +// in the fsrepo. This is a concurrent operation, meaning that any +// process may read this file. modifying this file, therefore, should +// use "mv" to replace the whole file and avoid interleaved read/writes. +func APIAddr(repoPath string) (ma.Multiaddr, error) { + repoPath = filepath.Clean(repoPath) + apiFilePath := filepath.Join(repoPath, apiFile) + + // if there is no file, assume there is no api addr. + f, err := os.Open(apiFilePath) + if err != nil { + if os.IsNotExist(err) { + return nil, repo.ErrApiNotRunning + } + return nil, err + } + defer f.Close() + + // read up to 2048 bytes. io.ReadAll is a vulnerability, as + // someone could hose the process by putting a massive file there. + // + // NOTE(@stebalien): @jbenet probably wasn't thinking straight when he + // wrote that comment but I'm leaving the limit here in case there was + // some hidden wisdom. However, I'm fixing it such that: + // 1. We don't read too little. + // 2. We don't truncate and succeed. + buf, err := ioutil.ReadAll(io.LimitReader(f, 2048)) + if err != nil { + return nil, err + } + if len(buf) == 2048 { + return nil, fmt.Errorf("API file too large, must be <2048 bytes long: %s", apiFilePath) + } + + s := string(buf) + s = strings.TrimSpace(s) + return ma.NewMultiaddr(s) +} + +func (r *FSRepo) Keystore() keystore.Keystore { + return r.keystore +} + +func (r *FSRepo) Path() string { + return r.path +} + +// SetAPIAddr writes the API Addr to the /api file. +func (r *FSRepo) SetAPIAddr(addr ma.Multiaddr) error { + f, err := os.Create(filepath.Join(r.path, apiFile)) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(addr.String()) + return err +} + +// openConfig returns an error if the config file is not present. +func (r *FSRepo) openConfig() error { + configFilename, err := config.Filename(r.path) + if err != nil { + return err + } + conf, err := serialize.Load(configFilename) + if err != nil { + return err + } + r.config = conf + return nil +} + +func (r *FSRepo) openKeystore() error { + ksp := filepath.Join(r.path, "keystore") + ks, err := keystore.NewFSKeystore(ksp) + if err != nil { + return err + } + + r.keystore = ks + + return nil +} + +// openDatastore returns an error if the config file is not present. +func (r *FSRepo) openDatastore() error { + if r.config.Datastore.Type != "" || r.config.Datastore.Path != "" { + return fmt.Errorf("old style datatstore config detected") + } else if r.config.Datastore.Spec == nil { + return fmt.Errorf("required Datastore.Spec entry missing from config file") + } + if r.config.Datastore.NoSync { + log.Warning("NoSync is now deprecated in favor of datastore specific settings. If you want to disable fsync on flatfs set 'sync' to false. See https://github.com/ipfs/go-ipfs/blob/master/docs/datastores.md#flatfs.") + } + + dsc, err := AnyDatastoreConfig(r.config.Datastore.Spec) + if err != nil { + return err + } + spec := dsc.DiskSpec() + + oldSpec, err := r.readSpec() + if err != nil { + return err + } + if oldSpec != spec.String() { + return fmt.Errorf("datastore configuration of '%s' does not match what is on disk '%s'", + oldSpec, spec.String()) + } + + d, err := dsc.Create(r.path) + if err != nil { + return err + } + r.ds = d + + // Wrap it with metrics gathering + prefix := "ipfs.fsrepo.datastore" + r.ds = measure.New(prefix, r.ds) + + return nil +} + +func (r *FSRepo) readSpec() (string, error) { + fn, err := config.Path(r.path, specFn) + if err != nil { + return "", err + } + b, err := ioutil.ReadFile(fn) + if err != nil { + return "", err + } + return strings.TrimSpace(string(b)), nil +} + +// Close closes the FSRepo, releasing held resources. +func (r *FSRepo) Close() error { + packageLock.Lock() + defer packageLock.Unlock() + + if r.closed { + return errors.New("repo is closed") + } + + err := os.Remove(filepath.Join(r.path, apiFile)) + if err != nil && !os.IsNotExist(err) { + log.Warning("error removing api file: ", err) + } + + if err := r.ds.Close(); err != nil { + return err + } + + // This code existed in the previous versions, but + // EventlogComponent.Close was never called. Preserving here + // pending further discussion. + // + // TODO It isn't part of the current contract, but callers may like for us + // to disable logging once the component is closed. + // logging.Configure(logging.Output(os.Stderr)) + + r.closed = true + return r.lockfile.Close() +} + +// Config the current config. This function DOES NOT copy the config. The caller +// MUST NOT modify it without first calling `Clone`. +// +// Result when not Open is undefined. The method may panic if it pleases. +func (r *FSRepo) Config() (*config.Config, error) { + // It is not necessary to hold the package lock since the repo is in an + // opened state. The package lock is _not_ meant to ensure that the repo is + // thread-safe. The package lock is only meant to guard against removal and + // coordinate the lockfile. However, we provide thread-safety to keep + // things simple. + packageLock.Lock() + defer packageLock.Unlock() + + if r.closed { + return nil, errors.New("cannot access config, repo not open") + } + return r.config, nil +} + +func (r *FSRepo) FileManager() *filestore.FileManager { + return r.filemgr +} + +func (r *FSRepo) BackupConfig(prefix string) (string, error) { + temp, err := ioutil.TempFile(r.path, "config-"+prefix) + if err != nil { + return "", err + } + defer temp.Close() + + configFilename, err := config.Filename(r.path) + if err != nil { + return "", err + } + + orig, err := os.OpenFile(configFilename, os.O_RDONLY, 0600) + if err != nil { + return "", err + } + defer orig.Close() + + _, err = io.Copy(temp, orig) + if err != nil { + return "", err + } + + return orig.Name(), nil +} + +// setConfigUnsynced is for private use. +func (r *FSRepo) setConfigUnsynced(updated *config.Config) error { + configFilename, err := config.Filename(r.path) + if err != nil { + return err + } + // to avoid clobbering user-provided keys, must read the config from disk + // as a map, write the updated struct values to the map and write the map + // to disk. + var mapconf map[string]interface{} + if err := serialize.ReadConfigFile(configFilename, &mapconf); err != nil { + return err + } + m, err := config.ToMap(updated) + if err != nil { + return err + } + for k, v := range m { + mapconf[k] = v + } + if err := serialize.WriteConfigFile(configFilename, mapconf); err != nil { + return err + } + // Do not use `*r.config = ...`. This will modify the *shared* config + // returned by `r.Config`. + r.config = updated + return nil +} + +// SetConfig updates the FSRepo's config. The user must not modify the config +// object after calling this method. +func (r *FSRepo) SetConfig(updated *config.Config) error { + + // packageLock is held to provide thread-safety. + packageLock.Lock() + defer packageLock.Unlock() + + return r.setConfigUnsynced(updated) +} + +// GetConfigKey retrieves only the value of a particular key. +func (r *FSRepo) GetConfigKey(key string) (interface{}, error) { + packageLock.Lock() + defer packageLock.Unlock() + + if r.closed { + return nil, errors.New("repo is closed") + } + + filename, err := config.Filename(r.path) + if err != nil { + return nil, err + } + var cfg map[string]interface{} + if err := serialize.ReadConfigFile(filename, &cfg); err != nil { + return nil, err + } + return common.MapGetKV(cfg, key) +} + +// SetConfigKey writes the value of a particular key. +func (r *FSRepo) SetConfigKey(key string, value interface{}) error { + packageLock.Lock() + defer packageLock.Unlock() + + if r.closed { + return errors.New("repo is closed") + } + + filename, err := config.Filename(r.path) + if err != nil { + return err + } + var mapconf map[string]interface{} + if err := serialize.ReadConfigFile(filename, &mapconf); err != nil { + return err + } + + // Load private key to guard against it being overwritten. + // NOTE: this is a temporary measure to secure this field until we move + // keys out of the config file. + pkval, err := common.MapGetKV(mapconf, config.PrivKeySelector) + if err != nil { + return err + } + + // Get the type of the value associated with the key + oldValue, err := common.MapGetKV(mapconf, key) + ok := true + if err != nil { + // key-value does not exist yet + switch v := value.(type) { + case string: + value, err = strconv.ParseBool(v) + if err != nil { + value, err = strconv.Atoi(v) + if err != nil { + value, err = strconv.ParseFloat(v, 32) + if err != nil { + value = v + } + } + } + default: + } + } else { + switch oldValue.(type) { + case bool: + value, ok = value.(bool) + case int: + value, ok = value.(int) + case float32: + value, ok = value.(float32) + case string: + value, ok = value.(string) + default: + } + if !ok { + return fmt.Errorf("wrong config type, expected %T", oldValue) + } + } + + if err := common.MapSetKV(mapconf, key, value); err != nil { + return err + } + + // replace private key, in case it was overwritten. + if err := common.MapSetKV(mapconf, config.PrivKeySelector, pkval); err != nil { + return err + } + + // This step doubles as to validate the map against the struct + // before serialization + conf, err := config.FromMap(mapconf) + if err != nil { + return err + } + if err := serialize.WriteConfigFile(filename, mapconf); err != nil { + return err + } + return r.setConfigUnsynced(conf) // TODO roll this into this method +} + +// Datastore returns a repo-owned datastore. If FSRepo is Closed, return value +// is undefined. +func (r *FSRepo) Datastore() repo.Datastore { + packageLock.Lock() + d := r.ds + packageLock.Unlock() + return d +} + +// GetStorageUsage computes the storage space taken by the repo in bytes +func (r *FSRepo) GetStorageUsage() (uint64, error) { + return ds.DiskUsage(r.Datastore()) +} + +func (r *FSRepo) SwarmKey() ([]byte, error) { + repoPath := filepath.Clean(r.path) + spath := filepath.Join(repoPath, swarmKeyFile) + + f, err := os.Open(spath) + if err != nil { + if os.IsNotExist(err) { + err = nil + } + return nil, err + } + defer f.Close() + + return ioutil.ReadAll(f) +} + +var _ io.Closer = &FSRepo{} +var _ repo.Repo = &FSRepo{} + +// IsInitialized returns true if the repo is initialized at provided |path|. +func IsInitialized(path string) bool { + // packageLock is held to ensure that another caller doesn't attempt to + // Init or Remove the repo while this call is in progress. + packageLock.Lock() + defer packageLock.Unlock() + + return isInitializedUnsynced(path) +} + +// private methods below this point. NB: packageLock must held by caller. + +// isInitializedUnsynced reports whether the repo is initialized. Caller must +// hold the packageLock. +func isInitializedUnsynced(repoPath string) bool { + return configIsInitialized(repoPath) +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/mfsr.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/mfsr.go new file mode 100644 index 00000000..c0f3b8b4 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/mfsr.go @@ -0,0 +1,55 @@ +package mfsr + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "strconv" + "strings" +) + +const VersionFile = "version" + +type RepoPath string + +func (rp RepoPath) VersionFile() string { + return path.Join(string(rp), VersionFile) +} + +func (rp RepoPath) Version() (int, error) { + if rp == "" { + return 0, fmt.Errorf("invalid repo path \"%s\"", rp) + } + + fn := rp.VersionFile() + if _, err := os.Stat(fn); err != nil { + return 0, err + } + + c, err := ioutil.ReadFile(fn) + if err != nil { + return 0, err + } + + s := strings.TrimSpace(string(c)) + return strconv.Atoi(s) +} + +func (rp RepoPath) CheckVersion(version int) error { + v, err := rp.Version() + if err != nil { + return err + } + + if v != version { + return fmt.Errorf("versions differ (expected: %d, actual:%d)", version, v) + } + + return nil +} + +func (rp RepoPath) WriteVersion(version int) error { + fn := rp.VersionFile() + return ioutil.WriteFile(fn, []byte(fmt.Sprintf("%d\n", version)), 0644) +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/migrations.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/migrations.go new file mode 100644 index 00000000..de71de60 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/migrations.go @@ -0,0 +1,277 @@ +package mfsr + +import ( + "bufio" + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" +) + +var DistPath = "https://ipfs.io/ipfs/QmZLYJBVBK8nqc5JTHp6CZU1v9Ja3MvGrkCe61PfCecc6E" + +func init() { + if dist := os.Getenv("IPFS_DIST_PATH"); dist != "" { + DistPath = dist + } +} + +const migrations = "fs-repo-migrations" + +func migrationsBinName() string { + switch runtime.GOOS { + case "windows": + return migrations + ".exe" + default: + return migrations + } +} + +func RunMigration(newv int) error { + migrateBin := migrationsBinName() + + fmt.Println(" => Looking for suitable fs-repo-migrations binary.") + + var err error + migrateBin, err = exec.LookPath(migrateBin) + if err == nil { + // check to make sure migrations binary supports our target version + err = verifyMigrationSupportsVersion(migrateBin, newv) + } + + if err != nil { + fmt.Println(" => None found, downloading.") + + loc, err := GetMigrations() + if err != nil { + fmt.Println(" => Failed to download fs-repo-migrations.") + return err + } + + err = verifyMigrationSupportsVersion(loc, newv) + if err != nil { + return fmt.Errorf("no fs-repo-migration binary found for version %d: %s", newv, err) + } + + migrateBin = loc + } + + cmd := exec.Command(migrateBin, "-to", fmt.Sprint(newv), "-y") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + fmt.Printf(" => Running: %s -to %d -y\n", migrateBin, newv) + + err = cmd.Run() + if err != nil { + fmt.Printf(" => Failed: %s -to %d -y\n", migrateBin, newv) + return fmt.Errorf("migration failed: %s", err) + } + + fmt.Printf(" => Success: fs-repo has been migrated to version %d.\n", newv) + + return nil +} + +func GetMigrations() (string, error) { + latest, err := GetLatestVersion(DistPath, migrations) + if err != nil { + return "", fmt.Errorf("failed to find latest fs-repo-migrations: %s", err) + } + + dir, err := ioutil.TempDir("", "go-ipfs-migrate") + if err != nil { + return "", fmt.Errorf("failed to create fs-repo-migrations tempdir: %s", err) + } + + out := filepath.Join(dir, migrationsBinName()) + + err = GetBinaryForVersion(migrations, migrations, DistPath, latest, out) + if err != nil { + return "", fmt.Errorf("failed to download latest fs-repo-migrations: %s", err) + } + + err = os.Chmod(out, 0755) + if err != nil { + return "", err + } + + return out, nil +} + +func verifyMigrationSupportsVersion(fsrbin string, vn int) error { + sn, err := migrationsVersion(fsrbin) + if err != nil { + return err + } + + if sn >= vn { + return nil + } + + return fmt.Errorf("migrations binary doesnt support version %d: %s", vn, fsrbin) +} + +func migrationsVersion(bin string) (int, error) { + out, err := exec.Command(bin, "-v").CombinedOutput() + if err != nil { + return 0, fmt.Errorf("failed to check migrations version: %s", err) + } + + vs := strings.Trim(string(out), " \n\t") + vn, err := strconv.Atoi(vs) + if err != nil { + return 0, fmt.Errorf("migrations binary version check did not return a number: %s", err) + } + + return vn, nil +} + +func GetVersions(ipfspath, dist string) ([]string, error) { + rc, err := httpFetch(ipfspath + "/" + dist + "/versions") + if err != nil { + return nil, err + } + defer rc.Close() + + var out []string + scan := bufio.NewScanner(rc) + for scan.Scan() { + out = append(out, scan.Text()) + } + + return out, nil +} + +func GetLatestVersion(ipfspath, dist string) (string, error) { + vs, err := GetVersions(ipfspath, dist) + if err != nil { + return "", err + } + var latest string + for i := len(vs) - 1; i >= 0; i-- { + if !strings.Contains(vs[i], "-dev") { + latest = vs[i] + break + } + } + if latest == "" { + return "", fmt.Errorf("couldnt find a non dev version in the list") + } + return vs[len(vs)-1], nil +} + +func httpGet(url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("http.NewRequest error: %s", err) + } + + req.Header.Set("User-Agent", "go-ipfs") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, fmt.Errorf("http.DefaultClient.Do error: %s", err) + } + + return resp, nil +} + +func httpFetch(url string) (io.ReadCloser, error) { + resp, err := httpGet(url) + if err != nil { + return nil, err + } + + if resp.StatusCode >= 400 { + mes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("error reading error body: %s", err) + } + + return nil, fmt.Errorf("GET %s error: %s: %s", url, resp.Status, string(mes)) + } + + return resp.Body, nil +} + +func GetBinaryForVersion(distname, binnom, root, vers, out string) error { + dir, err := ioutil.TempDir("", "go-ipfs-auto-migrate") + if err != nil { + return err + } + + var archive string + switch runtime.GOOS { + case "windows": + archive = "zip" + binnom += ".exe" + default: + archive = "tar.gz" + } + osv, err := osWithVariant() + if err != nil { + return err + } + finame := fmt.Sprintf("%s_%s_%s-%s.%s", distname, vers, osv, runtime.GOARCH, archive) + distpath := fmt.Sprintf("%s/%s/%s/%s", root, distname, vers, finame) + + data, err := httpFetch(distpath) + if err != nil { + return err + } + + arcpath := filepath.Join(dir, finame) + fi, err := os.Create(arcpath) + if err != nil { + return err + } + + _, err = io.Copy(fi, data) + if err != nil { + return err + } + fi.Close() + + return unpackArchive(distname, binnom, arcpath, out, archive) +} + +// osWithVariant returns the OS name with optional variant. +// Currently returns either runtime.GOOS, or "linux-musl". +func osWithVariant() (string, error) { + if runtime.GOOS != "linux" { + return runtime.GOOS, nil + } + + // ldd outputs the system's kind of libc. + // - on standard ubuntu: ldd (Ubuntu GLIBC 2.23-0ubuntu5) 2.23 + // - on alpine: musl libc (x86_64) + // + // we use the combined stdout+stderr, + // because ldd --version prints differently on different OSes. + // - on standard ubuntu: stdout + // - on alpine: stderr (it probably doesn't know the --version flag) + // + // we suppress non-zero exit codes (see last point about alpine). + out, err := exec.Command("sh", "-c", "ldd --version || true").CombinedOutput() + if err != nil { + return "", err + } + + // now just see if we can find "musl" somewhere in the output + scan := bufio.NewScanner(bytes.NewBuffer(out)) + for scan.Scan() { + if strings.Contains(scan.Text(), "musl") { + return "linux-musl", nil + } + } + + return "linux", nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/unpack.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/unpack.go new file mode 100644 index 00000000..5b563071 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/migrations/unpack.go @@ -0,0 +1,98 @@ +package mfsr + +import ( + "archive/tar" + "archive/zip" + "compress/gzip" + "fmt" + "io" + "os" +) + +func unpackArchive(dist, binnom, path, out, atype string) error { + switch atype { + case "zip": + return unpackZip(dist, binnom, path, out) + case "tar.gz": + return unpackTgz(dist, binnom, path, out) + default: + return fmt.Errorf("unrecognized archive type: %s", atype) + } +} + +func unpackTgz(dist, binnom, path, out string) error { + fi, err := os.Open(path) + if err != nil { + return err + } + defer fi.Close() + + gzr, err := gzip.NewReader(fi) + if err != nil { + return err + } + + defer gzr.Close() + + var bin io.Reader + tarr := tar.NewReader(gzr) + +loop: + for { + th, err := tarr.Next() + switch err { + default: + return err + case io.EOF: + break loop + case nil: + // continue + } + + if th.Name == dist+"/"+binnom { + bin = tarr + break + } + } + + if bin == nil { + return fmt.Errorf("no binary found in downloaded archive") + } + + return writeToPath(bin, out) +} + +func writeToPath(rc io.Reader, out string) error { + binfi, err := os.Create(out) + if err != nil { + return fmt.Errorf("error opening tmp bin path '%s': %s", out, err) + } + defer binfi.Close() + + _, err = io.Copy(binfi, rc) + + return err +} + +func unpackZip(dist, binnom, path, out string) error { + zipr, err := zip.OpenReader(path) + if err != nil { + return fmt.Errorf("error opening zipreader: %s", err) + } + + defer zipr.Close() + + var bin io.ReadCloser + for _, fis := range zipr.File { + if fis.Name == dist+"/"+binnom { + rc, err := fis.Open() + if err != nil { + return fmt.Errorf("error extracting binary from archive: %s", err) + } + + bin = rc + } + } + + return writeToPath(bin, out) +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/misc.go b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/misc.go new file mode 100644 index 00000000..7f0c0164 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/fsrepo/misc.go @@ -0,0 +1,23 @@ +package fsrepo + +import ( + "os" + + config "github.com/ipfs/go-ipfs-config" + homedir "github.com/mitchellh/go-homedir" +) + +// BestKnownPath returns the best known fsrepo path. If the ENV override is +// present, this function returns that value. Otherwise, it returns the default +// repo path. +func BestKnownPath() (string, error) { + ipfsPath := config.DefaultPathRoot + if os.Getenv(config.EnvDir) != "" { + ipfsPath = os.Getenv(config.EnvDir) + } + ipfsPath, err := homedir.Expand(ipfsPath) + if err != nil { + return "", err + } + return ipfsPath, nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/mock.go b/vendor/github.com/ipfs/go-ipfs/repo/mock.go new file mode 100644 index 00000000..78ec9073 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/mock.go @@ -0,0 +1,58 @@ +package repo + +import ( + "errors" + + filestore "github.com/ipfs/go-ipfs/filestore" + keystore "github.com/ipfs/go-ipfs/keystore" + + config "github.com/ipfs/go-ipfs-config" + ma "github.com/multiformats/go-multiaddr" +) + +var errTODO = errors.New("TODO: mock repo") + +// Mock is not thread-safe +type Mock struct { + C config.Config + D Datastore + K keystore.Keystore + F *filestore.FileManager +} + +func (m *Mock) Config() (*config.Config, error) { + return &m.C, nil // FIXME threadsafety +} + +func (m *Mock) SetConfig(updated *config.Config) error { + m.C = *updated // FIXME threadsafety + return nil +} + +func (m *Mock) BackupConfig(prefix string) (string, error) { + return "", errTODO +} + +func (m *Mock) SetConfigKey(key string, value interface{}) error { + return errTODO +} + +func (m *Mock) GetConfigKey(key string) (interface{}, error) { + return nil, errTODO +} + +func (m *Mock) Datastore() Datastore { return m.D } + +func (m *Mock) GetStorageUsage() (uint64, error) { return 0, nil } + +func (m *Mock) Close() error { return errTODO } + +func (m *Mock) SetAPIAddr(addr ma.Multiaddr) error { return errTODO } + +func (m *Mock) Keystore() keystore.Keystore { return m.K } + +func (m *Mock) SwarmKey() ([]byte, error) { + return nil, nil +} + +func (m *Mock) FileManager() *filestore.FileManager { return m.F } diff --git a/vendor/github.com/ipfs/go-ipfs/repo/onlyone.go b/vendor/github.com/ipfs/go-ipfs/repo/onlyone.go new file mode 100644 index 00000000..860c166b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/onlyone.go @@ -0,0 +1,72 @@ +package repo + +import ( + "sync" +) + +// OnlyOne tracks open Repos by arbitrary key and returns the already +// open one. +type OnlyOne struct { + mu sync.Mutex + active map[interface{}]*ref +} + +// Open a Repo identified by key. If Repo is not already open, the +// open function is called, and the result is remember for further +// use. +// +// Key must be comparable, or Open will panic. Make sure to pick keys +// that are unique across different concrete Repo implementations, +// e.g. by creating a local type: +// +// type repoKey string +// r, err := o.Open(repoKey(path), open) +// +// Call Repo.Close when done. +func (o *OnlyOne) Open(key interface{}, open func() (Repo, error)) (Repo, error) { + o.mu.Lock() + defer o.mu.Unlock() + if o.active == nil { + o.active = make(map[interface{}]*ref) + } + + item, found := o.active[key] + if !found { + repo, err := open() + if err != nil { + return nil, err + } + item = &ref{ + parent: o, + key: key, + Repo: repo, + } + o.active[key] = item + } + item.refs++ + return item, nil +} + +type ref struct { + parent *OnlyOne + key interface{} + refs uint32 + Repo +} + +var _ Repo = (*ref)(nil) + +func (r *ref) Close() error { + r.parent.mu.Lock() + defer r.parent.mu.Unlock() + + r.refs-- + if r.refs > 0 { + // others are holding it open + return nil + } + + // last one + delete(r.parent.active, r.key) + return r.Repo.Close() +} diff --git a/vendor/github.com/ipfs/go-ipfs/repo/repo.go b/vendor/github.com/ipfs/go-ipfs/repo/repo.go new file mode 100644 index 00000000..ffb024af --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/repo/repo.go @@ -0,0 +1,63 @@ +package repo + +import ( + "errors" + "io" + + filestore "github.com/ipfs/go-ipfs/filestore" + keystore "github.com/ipfs/go-ipfs/keystore" + + ds "github.com/ipfs/go-datastore" + config "github.com/ipfs/go-ipfs-config" + ma "github.com/multiformats/go-multiaddr" +) + +var ( + ErrApiNotRunning = errors.New("api not running") +) + +// Repo represents all persistent data of a given ipfs node. +type Repo interface { + // Config returns the ipfs configuration file from the repo. Changes made + // to the returned config are not automatically persisted. + Config() (*config.Config, error) + + // BackupConfig creates a backup of the current configuration file using + // the given prefix for naming. + BackupConfig(prefix string) (string, error) + + // SetConfig persists the given configuration struct to storage. + SetConfig(*config.Config) error + + // SetConfigKey sets the given key-value pair within the config and persists it to storage. + SetConfigKey(key string, value interface{}) error + + // GetConfigKey reads the value for the given key from the configuration in storage. + GetConfigKey(key string) (interface{}, error) + + // Datastore returns a reference to the configured data storage backend. + Datastore() Datastore + + // GetStorageUsage returns the number of bytes stored. + GetStorageUsage() (uint64, error) + + // Keystore returns a reference to the key management interface. + Keystore() keystore.Keystore + + // FileManager returns a reference to the filestore file manager. + FileManager() *filestore.FileManager + + // SetAPIAddr sets the API address in the repo. + SetAPIAddr(addr ma.Multiaddr) error + + // SwarmKey returns the configured shared symmetric key for the private networks feature. + SwarmKey() ([]byte, error) + + io.Closer +} + +// Datastore is the interface required from a datastore to be +// acceptable to FSRepo. +type Datastore interface { + ds.Batching // must be thread-safe +} diff --git a/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-sleep/LICENSE b/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-sleep/LICENSE new file mode 100644 index 00000000..7a6cf794 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-sleep/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet +Copyright (c) 2015 Christian Couder + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-timeout/LICENSE b/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-timeout/LICENSE new file mode 100644 index 00000000..5c30e8cc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/test/dependencies/go-timeout/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jakub "Kubuxu" Sztandera + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/github.com/ipfs/go-ipfs/test/dependencies/ma-pipe-unidir/LICENSE b/vendor/github.com/ipfs/go-ipfs/test/dependencies/ma-pipe-unidir/LICENSE new file mode 100644 index 00000000..e1159e5d --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/test/dependencies/ma-pipe-unidir/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2017 Łukasz Magiera + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/github.com/ipfs/go-ipfs/thirdparty/cidv0v1/blockstore.go b/vendor/github.com/ipfs/go-ipfs/thirdparty/cidv0v1/blockstore.go new file mode 100644 index 00000000..2f098dff --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/thirdparty/cidv0v1/blockstore.go @@ -0,0 +1,87 @@ +package cidv0v1 + +import ( + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + bs "github.com/ipfs/go-ipfs-blockstore" + mh "github.com/multiformats/go-multihash" +) + +type blockstore struct { + bs.Blockstore +} + +func NewBlockstore(b bs.Blockstore) bs.Blockstore { + return &blockstore{b} +} + +func (b *blockstore) Has(c cid.Cid) (bool, error) { + have, err := b.Blockstore.Has(c) + if have || err != nil { + return have, err + } + c1 := tryOtherCidVersion(c) + if !c1.Defined() { + return false, nil + } + return b.Blockstore.Has(c1) +} + +func (b *blockstore) Get(c cid.Cid) (blocks.Block, error) { + block, err := b.Blockstore.Get(c) + if err == nil { + return block, nil + } + if err != bs.ErrNotFound { + return nil, err + } + c1 := tryOtherCidVersion(c) + if !c1.Defined() { + return nil, bs.ErrNotFound + } + block, err = b.Blockstore.Get(c1) + if err != nil { + return nil, err + } + // modify block so it has the original CID + block, err = blocks.NewBlockWithCid(block.RawData(), c) + if err != nil { + return nil, err + } + // insert the block with the original CID to avoid problems + // with pinning + err = b.Blockstore.Put(block) + if err != nil { + return nil, err + } + return block, nil +} + +func (b *blockstore) GetSize(c cid.Cid) (int, error) { + size, err := b.Blockstore.GetSize(c) + if err == nil { + return size, nil + } + if err != bs.ErrNotFound { + return -1, err + } + c1 := tryOtherCidVersion(c) + if !c1.Defined() { + return -1, bs.ErrNotFound + } + return b.Blockstore.GetSize(c1) +} + +func tryOtherCidVersion(c cid.Cid) cid.Cid { + prefix := c.Prefix() + if prefix.Codec != cid.DagProtobuf || prefix.MhType != mh.SHA2_256 || prefix.MhLength != 32 { + return cid.Undef + } + var c1 cid.Cid + if prefix.Version == 0 { + c1 = cid.NewCidV1(cid.DagProtobuf, c.Hash()) + } else { + c1 = cid.NewCidV0(c.Hash()) + } + return c1 +} diff --git a/vendor/github.com/ipfs/go-ipfs/thirdparty/dir/dir.go b/vendor/github.com/ipfs/go-ipfs/thirdparty/dir/dir.go new file mode 100644 index 00000000..1549cc80 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/thirdparty/dir/dir.go @@ -0,0 +1,25 @@ +package dir + +// TODO move somewhere generic + +import ( + "errors" + "os" + "path/filepath" +) + +// Writable ensures the directory exists and is writable +func Writable(path string) error { + // Construct the path if missing + if err := os.MkdirAll(path, os.ModePerm); err != nil { + return err + } + // Check the directory is writable + if f, err := os.Create(filepath.Join(path, "._check_writable")); err == nil { + f.Close() + os.Remove(f.Name()) + } else { + return errors.New("'" + path + "' is not writable") + } + return nil +} diff --git a/vendor/github.com/ipfs/go-ipfs/thirdparty/verifbs/verifbs.go b/vendor/github.com/ipfs/go-ipfs/thirdparty/verifbs/verifbs.go new file mode 100644 index 00000000..53b6d13c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/thirdparty/verifbs/verifbs.go @@ -0,0 +1,62 @@ +package verifbs + +import ( + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + bstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/ipfs/go-verifcid" +) + +type VerifBSGC struct { + bstore.GCBlockstore +} + +func (bs *VerifBSGC) Put(b blocks.Block) error { + if err := verifcid.ValidateCid(b.Cid()); err != nil { + return err + } + return bs.GCBlockstore.Put(b) +} + +func (bs *VerifBSGC) PutMany(blks []blocks.Block) error { + for _, b := range blks { + if err := verifcid.ValidateCid(b.Cid()); err != nil { + return err + } + } + return bs.GCBlockstore.PutMany(blks) +} + +func (bs *VerifBSGC) Get(c cid.Cid) (blocks.Block, error) { + if err := verifcid.ValidateCid(c); err != nil { + return nil, err + } + return bs.GCBlockstore.Get(c) +} + +type VerifBS struct { + bstore.Blockstore +} + +func (bs *VerifBS) Put(b blocks.Block) error { + if err := verifcid.ValidateCid(b.Cid()); err != nil { + return err + } + return bs.Blockstore.Put(b) +} + +func (bs *VerifBS) PutMany(blks []blocks.Block) error { + for _, b := range blks { + if err := verifcid.ValidateCid(b.Cid()); err != nil { + return err + } + } + return bs.Blockstore.PutMany(blks) +} + +func (bs *VerifBS) Get(c cid.Cid) (blocks.Block, error) { + if err := verifcid.ValidateCid(c); err != nil { + return nil, err + } + return bs.Blockstore.Get(c) +} diff --git a/vendor/github.com/ipfs/go-ipfs/version.go b/vendor/github.com/ipfs/go-ipfs/version.go new file mode 100644 index 00000000..5257125e --- /dev/null +++ b/vendor/github.com/ipfs/go-ipfs/version.go @@ -0,0 +1,9 @@ +package ipfs + +// CurrentCommit is the current git commit, this is set as a ldflag in the Makefile +var CurrentCommit string + +// CurrentVersionNumber is the current application's version literal +const CurrentVersionNumber = "0.4.22-dev" + +const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" diff --git a/vendor/github.com/ipfs/go-ipld-cbor/.travis.yml b/vendor/github.com/ipfs/go-ipld-cbor/.travis.yml new file mode 100644 index 00000000..923835bc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipld-cbor/LICENSE b/vendor/github.com/ipfs/go-ipld-cbor/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipld-cbor/Makefile b/vendor/github.com/ipfs/go-ipld-cbor/Makefile new file mode 100644 index 00000000..7811c099 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/Makefile @@ -0,0 +1,15 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +covertools: + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +deps: gx covertools + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-ipld-cbor/README.md b/vendor/github.com/ipfs/go-ipld-cbor/README.md new file mode 100644 index 00000000..0cec10cc --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/README.md @@ -0,0 +1,54 @@ +go-ipld-cbor +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/js-libp2p-floodsub/badge.svg?branch=master)](https://coveralls.io/github/libp2p/js-libp2p-floodsub?branch=master) +[![Travis CI](https://travis-ci.org/libp2p/js-libp2p-floodsub.svg?branch=master)](https://travis-ci.org/libp2p/js-libp2p-floodsub) + +> An implementation of a cbor encoded merkledag object. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Usage + +TODO: Right now this package isn't the easiest to use, it will be getting better rapidly, soon. +```go +// Make an object +obj := map[interface{}]interface{}{ + "foo": "bar", + "baz": &Link{ + Target: myCid, + }, +} + +// Parse it into an ipldcbor node +nd, err := WrapMap(obj) + +fmt.Println(nd.Links()) + +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson diff --git a/vendor/github.com/ipfs/go-ipld-cbor/codecov.yml b/vendor/github.com/ipfs/go-ipld-cbor/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-ipld-cbor/encoding/cloner.go b/vendor/github.com/ipfs/go-ipld-cbor/encoding/cloner.go new file mode 100644 index 00000000..0a04a3c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/encoding/cloner.go @@ -0,0 +1,33 @@ +package encoding + +import ( + "sync" + + refmt "github.com/polydawn/refmt" + "github.com/polydawn/refmt/obj/atlas" +) + +// PooledCloner is a thread-safe pooled object cloner. +type PooledCloner struct { + pool sync.Pool +} + +// NewPooledCloner returns a PooledCloner with the given atlas. Do not copy +// after use. +func NewPooledCloner(atl atlas.Atlas) PooledCloner { + return PooledCloner{ + pool: sync.Pool{ + New: func() interface{} { + return refmt.NewCloner(atl) + }, + }, + } +} + +// Clone clones a into b using a cloner from the pool. +func (p *PooledCloner) Clone(a, b interface{}) error { + c := p.pool.Get().(refmt.Cloner) + err := c.Clone(a, b) + p.pool.Put(c) + return err +} diff --git a/vendor/github.com/ipfs/go-ipld-cbor/encoding/marshaller.go b/vendor/github.com/ipfs/go-ipld-cbor/encoding/marshaller.go new file mode 100644 index 00000000..f4fe84be --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/encoding/marshaller.go @@ -0,0 +1,82 @@ +package encoding + +import ( + "bytes" + "io" + "sync" + + cbor "github.com/polydawn/refmt/cbor" + "github.com/polydawn/refmt/obj/atlas" +) + +type proxyWriter struct { + w io.Writer +} + +func (w *proxyWriter) Write(b []byte) (int, error) { + return w.w.Write(b) +} + +// Marshaller is a reusbale CBOR marshaller. +type Marshaller struct { + marshal *cbor.Marshaller + writer proxyWriter +} + +// NewMarshallerAtlased constructs a new cbor Marshaller using the given atlas. +func NewMarshallerAtlased(atl atlas.Atlas) *Marshaller { + m := new(Marshaller) + m.marshal = cbor.NewMarshallerAtlased(&m.writer, atl) + return m +} + +// Encode encodes the given object to the given writer. +func (m *Marshaller) Encode(obj interface{}, w io.Writer) error { + m.writer.w = w + err := m.marshal.Marshal(obj) + m.writer.w = nil + return err +} + +// Marshal marshels the given object to a byte slice. +func (m *Marshaller) Marshal(obj interface{}) ([]byte, error) { + var buf bytes.Buffer + if err := m.Encode(obj, &buf); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// PooledMarshaller is a thread-safe pooled CBOR marshaller. +type PooledMarshaller struct { + pool sync.Pool +} + +// NewPooledMarshaller returns a PooledMarshaller with the given atlas. Do not +// copy after use. +func NewPooledMarshaller(atl atlas.Atlas) PooledMarshaller { + return PooledMarshaller{ + pool: sync.Pool{ + New: func() interface{} { + return NewMarshallerAtlased(atl) + }, + }, + } +} + +// Marshal marshals the passed object using the pool of marshallers. +func (p *PooledMarshaller) Marshal(obj interface{}) ([]byte, error) { + m := p.pool.Get().(*Marshaller) + bts, err := m.Marshal(obj) + p.pool.Put(m) + return bts, err +} + +// Encode encodes the passed object to the given writer using the pool of +// marshallers. +func (p *PooledMarshaller) Encode(obj interface{}, w io.Writer) error { + m := p.pool.Get().(*Marshaller) + err := m.Encode(obj, w) + p.pool.Put(m) + return err +} diff --git a/vendor/github.com/ipfs/go-ipld-cbor/encoding/unmarshaller.go b/vendor/github.com/ipfs/go-ipld-cbor/encoding/unmarshaller.go new file mode 100644 index 00000000..2561dd79 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/encoding/unmarshaller.go @@ -0,0 +1,79 @@ +package encoding + +import ( + "bytes" + "io" + "sync" + + cbor "github.com/polydawn/refmt/cbor" + "github.com/polydawn/refmt/obj/atlas" +) + +type proxyReader struct { + r io.Reader +} + +func (r *proxyReader) Read(b []byte) (int, error) { + return r.r.Read(b) +} + +// Unmarshaller is a reusable CBOR unmarshaller. +type Unmarshaller struct { + unmarshal *cbor.Unmarshaller + reader proxyReader +} + +// NewUnmarshallerAtlased creates a new reusable unmarshaller. +func NewUnmarshallerAtlased(atl atlas.Atlas) *Unmarshaller { + m := new(Unmarshaller) + m.unmarshal = cbor.NewUnmarshallerAtlased(cbor.DecodeOptions{CoerceUndefToNull: true}, &m.reader, atl) + return m +} + +// Decode reads a CBOR object from the given reader and decodes it into the +// given object. +func (m *Unmarshaller) Decode(r io.Reader, obj interface{}) error { + m.reader.r = r + err := m.unmarshal.Unmarshal(obj) + m.reader.r = nil + return err +} + +// Unmarshal unmarshals the given CBOR byte slice into the given object. +func (m *Unmarshaller) Unmarshal(b []byte, obj interface{}) error { + return m.Decode(bytes.NewReader(b), obj) +} + +// PooledUnmarshaller is a thread-safe pooled CBOR unmarshaller. +type PooledUnmarshaller struct { + pool sync.Pool +} + +// NewPooledUnmarshaller returns a PooledUnmarshaller with the given atlas. Do +// not copy after use. +func NewPooledUnmarshaller(atl atlas.Atlas) PooledUnmarshaller { + return PooledUnmarshaller{ + pool: sync.Pool{ + New: func() interface{} { + return NewUnmarshallerAtlased(atl) + }, + }, + } +} + +// Decode decodes an object from the passed reader into the given object using +// the pool of unmarshallers. +func (p *PooledUnmarshaller) Decode(r io.Reader, obj interface{}) error { + u := p.pool.Get().(*Unmarshaller) + err := u.Decode(r, obj) + p.pool.Put(u) + return err +} + +// Unmarshal unmarshals the passed object using the pool of unmarshallers. +func (p *PooledUnmarshaller) Unmarshal(b []byte, obj interface{}) error { + u := p.pool.Get().(*Unmarshaller) + err := u.Unmarshal(b, obj) + p.pool.Put(u) + return err +} diff --git a/vendor/github.com/ipfs/go-ipld-cbor/go.mod b/vendor/github.com/ipfs/go-ipld-cbor/go.mod new file mode 100644 index 00000000..80f8c276 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/go.mod @@ -0,0 +1,12 @@ +module github.com/ipfs/go-ipld-cbor + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-ipld-format v0.0.1 + github.com/multiformats/go-multihash v0.0.1 + github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 + github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect + github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 // indirect +) diff --git a/vendor/github.com/ipfs/go-ipld-cbor/go.sum b/vendor/github.com/ipfs/go-ipld-cbor/go.sum new file mode 100644 index 00000000..94987205 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/go.sum @@ -0,0 +1,42 @@ +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipld-cbor/node.go b/vendor/github.com/ipfs/go-ipld-cbor/node.go new file mode 100644 index 00000000..4a30cc3a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/node.go @@ -0,0 +1,541 @@ +package cbornode + +import ( + "encoding/json" + "errors" + "io" + "math" + "strconv" + "strings" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +// CBORTagLink is the integer used to represent tags in CBOR. +const CBORTagLink = 42 + +// Node represents an IPLD node. +type Node struct { + obj interface{} + tree []string + links []*node.Link + raw []byte + cid cid.Cid +} + +// Compile time check to make sure Node implements the node.Node interface +var _ node.Node = (*Node)(nil) + +var ( + // ErrNoSuchLink is returned when no link with the given name was found. + ErrNoSuchLink = errors.New("no such link found") + ErrNonLink = errors.New("non-link found at given path") + ErrInvalidLink = errors.New("link value should have been bytes") + ErrInvalidKeys = errors.New("map keys must be strings") + ErrArrayOutOfRange = errors.New("array index out of range") + ErrNoLinks = errors.New("tried to resolve through object that had no links") + ErrEmptyLink = errors.New("link value was empty") + ErrInvalidMultibase = errors.New("invalid multibase on IPLD link") + ErrNonStringLink = errors.New("link should have been a string") +) + +// DecodeBlock decodes a CBOR encoded Block into an IPLD Node. +// +// This method *does not* canonicalize and *will* preserve the CID. As a matter +// of fact, it will assume that `block.Cid()` returns the correct CID and will +// make no effort to validate this assumption. +// +// In general, you should not be calling this method directly. Instead, you +// should be calling the `Decode` method from the `go-ipld-format` package. That +// method will pick the right decoder based on the Block's CID. +// +// Note: This function keeps a reference to `block` and assumes that it is +// immutable. +func DecodeBlock(block blocks.Block) (node.Node, error) { + return decodeBlock(block) +} + +func decodeBlock(block blocks.Block) (*Node, error) { + var m interface{} + if err := DecodeInto(block.RawData(), &m); err != nil { + return nil, err + } + return newObject(block, m) +} + +func newObject(block blocks.Block, m interface{}) (*Node, error) { + tree, links, err := compute(m) + if err != nil { + return nil, err + } + + return &Node{ + obj: m, + tree: tree, + links: links, + raw: block.RawData(), + cid: block.Cid(), + }, nil +} + +var _ node.DecodeBlockFunc = DecodeBlock + +// Decode decodes a CBOR object into an IPLD Node. +// +// If passed a non-canonical CBOR node, this function will canonicalize it. +// Therefore, `bytes.Equal(b, Decode(b).RawData())` may not hold. If you already +// have a CID for this data and want to ensure that it doesn't change, you +// should use `DecodeBlock`. +// mhType is multihash code to use for hashing, for example mh.SHA2_256 +// +// Note: This function does not hold onto `b`. You may reuse it. +func Decode(b []byte, mhType uint64, mhLen int) (*Node, error) { + var m interface{} + if err := DecodeInto(b, &m); err != nil { + return nil, err + } + + // We throw away `b` here to ensure that we canonicalize the encoded + // CBOR object. + return WrapObject(m, mhType, mhLen) +} + +// DecodeInto decodes a serialized IPLD cbor object into the given object. +func DecodeInto(b []byte, v interface{}) error { + return unmarshaller.Unmarshal(b, v) +} + +// WrapObject converts an arbitrary object into a Node. +func WrapObject(m interface{}, mhType uint64, mhLen int) (*Node, error) { + data, err := marshaller.Marshal(m) + if err != nil { + return nil, err + } + + var obj interface{} + err = cloner.Clone(m, &obj) + if err != nil { + return nil, err + } + + if mhType == math.MaxUint64 { + mhType = mh.SHA2_256 + } + + hash, err := mh.Sum(data, mhType, mhLen) + if err != nil { + return nil, err + } + c := cid.NewCidV1(cid.DagCBOR, hash) + + block, err := blocks.NewBlockWithCid(data, c) + if err != nil { + // TODO: Shouldn't this just panic? + return nil, err + } + // No need to deserialize. We can just deep copy. + return newObject(block, obj) +} + +// Resolve resolves a given path, and returns the object found at the end, as well +// as the possible tail of the path that was not resolved. +func (n *Node) Resolve(path []string) (interface{}, []string, error) { + var cur interface{} = n.obj + for i, val := range path { + switch curv := cur.(type) { + case map[string]interface{}: + next, ok := curv[val] + if !ok { + return nil, nil, ErrNoSuchLink + } + + cur = next + case map[interface{}]interface{}: + next, ok := curv[val] + if !ok { + return nil, nil, ErrNoSuchLink + } + + cur = next + case []interface{}: + n, err := strconv.Atoi(val) + if err != nil { + return nil, nil, err + } + + if n < 0 || n >= len(curv) { + return nil, nil, ErrArrayOutOfRange + } + + cur = curv[n] + case cid.Cid: + return &node.Link{Cid: curv}, path[i:], nil + default: + return nil, nil, ErrNoLinks + } + } + + lnk, ok := cur.(cid.Cid) + if ok { + return &node.Link{Cid: lnk}, nil, nil + } + + jsonish, err := convertToJSONIsh(cur) + if err != nil { + return nil, nil, err + } + + return jsonish, nil, nil +} + +// Copy creates a copy of the Node. +func (n *Node) Copy() node.Node { + links := make([]*node.Link, len(n.links)) + copy(links, n.links) + + raw := make([]byte, len(n.raw)) + copy(raw, n.raw) + + tree := make([]string, len(n.tree)) + copy(tree, n.tree) + + return &Node{ + obj: copyObj(n.obj), + links: links, + raw: raw, + tree: tree, + cid: n.cid, + } +} + +func copyObj(i interface{}) interface{} { + switch i := i.(type) { + case map[string]interface{}: + out := make(map[string]interface{}) + for k, v := range i { + out[k] = copyObj(v) + } + return out + case map[interface{}]interface{}: + out := make(map[interface{}]interface{}) + for k, v := range i { + out[k] = copyObj(v) + } + return out + case []interface{}: + var out []interface{} + for _, v := range i { + out = append(out, copyObj(v)) + } + return out + default: + // TODO: do not be lazy + // being lazy for now + // use caution + return i + } +} + +// ResolveLink resolves a path and returns the raw Link at the end, as well as +// the possible tail of the path that was not resolved. +func (n *Node) ResolveLink(path []string) (*node.Link, []string, error) { + obj, rest, err := n.Resolve(path) + if err != nil { + return nil, nil, err + } + + lnk, ok := obj.(*node.Link) + if !ok { + return nil, rest, ErrNonLink + } + + return lnk, rest, nil +} + +// Tree returns a flattend array of paths at the given path for the given depth. +func (n *Node) Tree(path string, depth int) []string { + if path == "" && depth == -1 { + return n.tree + } + + var out []string + for _, t := range n.tree { + if !strings.HasPrefix(t, path) { + continue + } + + sub := strings.TrimLeft(t[len(path):], "/") + if sub == "" { + continue + } + + if depth < 0 { + out = append(out, sub) + continue + } + + parts := strings.Split(sub, "/") + if len(parts) <= depth { + out = append(out, sub) + } + } + return out +} + +func compute(obj interface{}) (tree []string, links []*node.Link, err error) { + err = traverse(obj, "", func(name string, val interface{}) error { + if name != "" { + tree = append(tree, name[1:]) + } + if lnk, ok := val.(cid.Cid); ok { + links = append(links, &node.Link{Cid: lnk}) + } + return nil + }) + if err != nil { + return nil, nil, err + } + + return tree, links, nil +} + +// Links lists all known links of the Node. +func (n *Node) Links() []*node.Link { + return n.links +} + +func traverse(obj interface{}, cur string, cb func(string, interface{}) error) error { + if err := cb(cur, obj); err != nil { + return err + } + + switch obj := obj.(type) { + case map[string]interface{}: + for k, v := range obj { + this := cur + "/" + k + if err := traverse(v, this, cb); err != nil { + return err + } + } + return nil + case map[interface{}]interface{}: + for k, v := range obj { + ks, ok := k.(string) + if !ok { + return errors.New("map key was not a string") + } + this := cur + "/" + ks + if err := traverse(v, this, cb); err != nil { + return err + } + } + return nil + case []interface{}: + for i, v := range obj { + this := cur + "/" + strconv.Itoa(i) + if err := traverse(v, this, cb); err != nil { + return err + } + } + return nil + default: + return nil + } +} + +// RawData returns the raw bytes that represent the Node as serialized CBOR. +func (n *Node) RawData() []byte { + return n.raw +} + +// Cid returns the canonical Cid of the NOde. +func (n *Node) Cid() cid.Cid { + return n.cid +} + +// Loggable returns a loggable representation of the Node. +func (n *Node) Loggable() map[string]interface{} { + return map[string]interface{}{ + "node_type": "cbor", + "cid": n.Cid(), + } +} + +// Size returns the size of the binary representation of the Node. +func (n *Node) Size() (uint64, error) { + return uint64(len(n.RawData())), nil +} + +// Stat returns stats about the Node. +// TODO: implement? +func (n *Node) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// String returns the string representation of the CID of the Node. +func (n *Node) String() string { + return n.Cid().String() +} + +// MarshalJSON converts the Node into its JSON representation. +func (n *Node) MarshalJSON() ([]byte, error) { + out, err := convertToJSONIsh(n.obj) + if err != nil { + return nil, err + } + + return json.Marshal(out) +} + +// DumpObject marshals any object into its CBOR serialized byte representation +// TODO: rename +func DumpObject(obj interface{}) (out []byte, err error) { + return marshaller.Marshal(obj) +} + +func toSaneMap(n map[interface{}]interface{}) (interface{}, error) { + if lnk, ok := n["/"]; ok && len(n) == 1 { + lnkb, ok := lnk.([]byte) + if !ok { + return nil, ErrInvalidLink + } + + c, err := cid.Cast(lnkb) + if err != nil { + return nil, err + } + + return map[string]interface{}{"/": c}, nil + } + out := make(map[string]interface{}) + for k, v := range n { + ks, ok := k.(string) + if !ok { + return nil, ErrInvalidKeys + } + + obj, err := convertToJSONIsh(v) + if err != nil { + return nil, err + } + + out[ks] = obj + } + + return out, nil +} + +func convertToJSONIsh(v interface{}) (interface{}, error) { + switch v := v.(type) { + case map[interface{}]interface{}: + return toSaneMap(v) + case []interface{}: + var out []interface{} + if len(v) == 0 && v != nil { + return []interface{}{}, nil + } + for _, i := range v { + obj, err := convertToJSONIsh(i) + if err != nil { + return nil, err + } + + out = append(out, obj) + } + return out, nil + default: + return v, nil + } +} + +// FromJSON converts incoming JSON into a Node. +func FromJSON(r io.Reader, mhType uint64, mhLen int) (*Node, error) { + var m interface{} + err := json.NewDecoder(r).Decode(&m) + if err != nil { + return nil, err + } + + obj, err := convertToCborIshObj(m) + if err != nil { + return nil, err + } + + return WrapObject(obj, mhType, mhLen) +} + +func convertToCborIshObj(i interface{}) (interface{}, error) { + switch v := i.(type) { + case map[string]interface{}: + if len(v) == 0 && v != nil { + return v, nil + } + + if lnk, ok := v["/"]; ok && len(v) == 1 { + // special case for links + vstr, ok := lnk.(string) + if !ok { + return nil, ErrNonStringLink + } + + return cid.Decode(vstr) + } + + for a, b := range v { + val, err := convertToCborIshObj(b) + if err != nil { + return nil, err + } + + v[a] = val + } + return v, nil + case []interface{}: + if len(v) == 0 && v != nil { + return v, nil + } + + var out []interface{} + for _, o := range v { + obj, err := convertToCborIshObj(o) + if err != nil { + return nil, err + } + + out = append(out, obj) + } + + return out, nil + default: + return v, nil + } +} + +func castBytesToCid(x []byte) (cid.Cid, error) { + if len(x) == 0 { + return cid.Cid{}, ErrEmptyLink + } + + // TODO: manually doing multibase checking here since our deps don't + // support binary multibase yet + if x[0] != 0 { + return cid.Cid{}, ErrInvalidMultibase + } + + c, err := cid.Cast(x[1:]) + if err != nil { + return cid.Cid{}, ErrInvalidLink + } + + return c, nil +} + +func castCidToBytes(link cid.Cid) ([]byte, error) { + if !link.Defined() { + return nil, ErrEmptyLink + } + return append([]byte{0}, link.Bytes()...), nil +} diff --git a/vendor/github.com/ipfs/go-ipld-cbor/readable.go b/vendor/github.com/ipfs/go-ipld-cbor/readable.go new file mode 100644 index 00000000..cc9d03fa --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/readable.go @@ -0,0 +1,33 @@ +package cbornode + +import ( + "bufio" + "bytes" + + cbor "github.com/polydawn/refmt/cbor" + "github.com/polydawn/refmt/pretty" + "github.com/polydawn/refmt/shared" +) + +//HumanReadable returns a string representation of a CBOR blob +func HumanReadable(blob []byte) (string, error) { + reader := bytes.NewReader(blob) + + var buf bytes.Buffer + writer := bufio.NewWriter(&buf) + + err := shared.TokenPump{ + TokenSource: cbor.NewDecoder(cbor.DecodeOptions{}, reader), + TokenSink: pretty.NewEncoder(writer), + }.Run() + + if err != nil { + return "", err + } + + if err = writer.Flush(); err != nil { + return "", err + } + + return buf.String(), nil +} diff --git a/vendor/github.com/ipfs/go-ipld-cbor/refmt.go b/vendor/github.com/ipfs/go-ipld-cbor/refmt.go new file mode 100644 index 00000000..e8bd7ded --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-cbor/refmt.go @@ -0,0 +1,72 @@ +package cbornode + +import ( + "math/big" + + cid "github.com/ipfs/go-cid" + + encoding "github.com/ipfs/go-ipld-cbor/encoding" + + "github.com/polydawn/refmt/obj/atlas" +) + +// This atlas describes the CBOR Tag (42) for IPLD links, such that refmt can marshal and unmarshal them +var cidAtlasEntry = atlas.BuildEntry(cid.Cid{}). + UseTag(CBORTagLink). + Transform(). + TransformMarshal(atlas.MakeMarshalTransformFunc( + castCidToBytes, + )). + TransformUnmarshal(atlas.MakeUnmarshalTransformFunc( + castBytesToCid, + )). + Complete() + +// BigIntAtlasEntry gives a reasonable default encoding for big.Int. It is not +// included in the entries by default. +var BigIntAtlasEntry = atlas.BuildEntry(big.Int{}).Transform(). + TransformMarshal(atlas.MakeMarshalTransformFunc( + func(i big.Int) ([]byte, error) { + return i.Bytes(), nil + })). + TransformUnmarshal(atlas.MakeUnmarshalTransformFunc( + func(x []byte) (big.Int, error) { + return *big.NewInt(0).SetBytes(x), nil + })). + Complete() + +// CborAtlas is the refmt.Atlas used by the CBOR IPLD decoder/encoder. +var CborAtlas atlas.Atlas +var cborSortingMode = atlas.KeySortMode_RFC7049 +var atlasEntries = []*atlas.AtlasEntry{cidAtlasEntry} + +var ( + cloner encoding.PooledCloner + unmarshaller encoding.PooledUnmarshaller + marshaller encoding.PooledMarshaller +) + +func init() { + rebuildAtlas() +} + +func rebuildAtlas() { + CborAtlas = atlas.MustBuild(atlasEntries...). + WithMapMorphism(atlas.MapMorphism{KeySortMode: atlas.KeySortMode_RFC7049}) + + marshaller = encoding.NewPooledMarshaller(CborAtlas) + unmarshaller = encoding.NewPooledUnmarshaller(CborAtlas) + cloner = encoding.NewPooledCloner(CborAtlas) +} + +// RegisterCborType allows to register a custom cbor type +func RegisterCborType(i interface{}) { + var entry *atlas.AtlasEntry + if ae, ok := i.(*atlas.AtlasEntry); ok { + entry = ae + } else { + entry = atlas.BuildEntry(i).StructMap().AutogenerateWithSortingScheme(atlas.KeySortMode_RFC7049).Complete() + } + atlasEntries = append(atlasEntries, entry) + rebuildAtlas() +} diff --git a/vendor/github.com/ipfs/go-ipld-format/.travis.yml b/vendor/github.com/ipfs/go-ipld-format/.travis.yml new file mode 100644 index 00000000..ba87d9a8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.12.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipld-format/LICENSE b/vendor/github.com/ipfs/go-ipld-format/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ipld-format/Makefile b/vendor/github.com/ipfs/go-ipld-format/Makefile new file mode 100644 index 00000000..7811c099 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/Makefile @@ -0,0 +1,15 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +covertools: + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +deps: gx covertools + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-ipld-format/README.md b/vendor/github.com/ipfs/go-ipld-format/README.md new file mode 100644 index 00000000..7a2ccffa --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/README.md @@ -0,0 +1,35 @@ +go-ipld-format +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-ipld-format/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipld-format/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-ipld-format.svg?branch=master)](https://travis-ci.org/ipfs/go-ipld-format) + +> go-ipld-format is a set of interfaces that a type needs to implement in order to be a part of the ipld merkle-forest. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson diff --git a/vendor/github.com/ipfs/go-ipld-format/batch.go b/vendor/github.com/ipfs/go-ipld-format/batch.go new file mode 100644 index 00000000..dc879d5f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/batch.go @@ -0,0 +1,295 @@ +package format + +import ( + "context" + "errors" + "runtime" + + cid "github.com/ipfs/go-cid" +) + +// ParallelBatchCommits is the number of batch commits that can be in-flight before blocking. +// TODO(ipfs/go-ipfs#4299): Experiment with multiple datastores, storage +// devices, and CPUs to find the right value/formula. +var ParallelBatchCommits = runtime.NumCPU() * 2 + +// ErrNotCommited is returned when closing a batch that hasn't been successfully +// committed. +var ErrNotCommited = errors.New("error: batch not commited") + +// ErrClosed is returned when operating on a batch that has already been closed. +var ErrClosed = errors.New("error: batch closed") + +// NewBatch returns a node buffer (Batch) that buffers nodes internally and +// commits them to the underlying DAGService in batches. Use this if you intend +// to add or remove a lot of nodes all at once. +// +// If the passed context is canceled, any in-progress commits are aborted. +// +func NewBatch(ctx context.Context, na NodeAdder, opts ...BatchOption) *Batch { + ctx, cancel := context.WithCancel(ctx) + bopts := defaultBatchOptions + for _, o := range opts { + o(&bopts) + } + return &Batch{ + na: na, + ctx: ctx, + cancel: cancel, + commitResults: make(chan error, ParallelBatchCommits), + opts: bopts, + } +} + +// Batch is a buffer for batching adds to a dag. +type Batch struct { + na NodeAdder + + ctx context.Context + cancel func() + + activeCommits int + err error + commitResults chan error + + nodes []Node + size int + + opts batchOptions +} + +func (t *Batch) processResults() { + for t.activeCommits > 0 { + select { + case err := <-t.commitResults: + t.activeCommits-- + if err != nil { + t.setError(err) + return + } + default: + return + } + } +} + +func (t *Batch) asyncCommit() { + numBlocks := len(t.nodes) + if numBlocks == 0 { + return + } + if t.activeCommits >= ParallelBatchCommits { + select { + case err := <-t.commitResults: + t.activeCommits-- + + if err != nil { + t.setError(err) + return + } + case <-t.ctx.Done(): + t.setError(t.ctx.Err()) + return + } + } + go func(ctx context.Context, b []Node, result chan error, na NodeAdder) { + select { + case result <- na.AddMany(ctx, b): + case <-ctx.Done(): + } + }(t.ctx, t.nodes, t.commitResults, t.na) + + t.activeCommits++ + t.nodes = make([]Node, 0, numBlocks) + t.size = 0 + + return +} + +// Add adds a node to the batch and commits the batch if necessary. +func (t *Batch) Add(ctx context.Context, nd Node) error { + return t.AddMany(ctx, []Node{nd}) +} + +// AddMany many calls Add for every given Node, thus batching and +// commiting them as needed. +func (t *Batch) AddMany(ctx context.Context, nodes []Node) error { + if t.err != nil { + return t.err + } + // Not strictly necessary but allows us to catch errors early. + t.processResults() + + if t.err != nil { + return t.err + } + + t.nodes = append(t.nodes, nodes...) + for _, nd := range nodes { + t.size += len(nd.RawData()) + } + + if t.size > t.opts.maxSize || len(t.nodes) > t.opts.maxNodes { + t.asyncCommit() + } + return t.err +} + +// Commit commits batched nodes. +func (t *Batch) Commit() error { + if t.err != nil { + return t.err + } + + t.asyncCommit() + +loop: + for t.activeCommits > 0 { + select { + case err := <-t.commitResults: + t.activeCommits-- + if err != nil { + t.setError(err) + break loop + } + case <-t.ctx.Done(): + t.setError(t.ctx.Err()) + break loop + } + } + + return t.err +} + +func (t *Batch) setError(err error) { + t.err = err + + t.cancel() + + // Drain as much as we can without blocking. +loop: + for { + select { + case <-t.commitResults: + default: + break loop + } + } + + // Be nice and cleanup. These can take a *lot* of memory. + t.commitResults = nil + t.na = nil + t.ctx = nil + t.nodes = nil + t.size = 0 + t.activeCommits = 0 +} + +// BatchOption provides a way of setting internal options of +// a Batch. +// +// See this post about the "functional options" pattern: +// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis +type BatchOption func(o *batchOptions) + +type batchOptions struct { + maxSize int + maxNodes int +} + +var defaultBatchOptions = batchOptions{ + maxSize: 8 << 20, + + // By default, only batch up to 128 nodes at a time. + // The current implementation of flatfs opens this many file + // descriptors at the same time for the optimized batch write. + maxNodes: 128, +} + +// MaxSizeBatchOption sets the maximum size of a Batch. +func MaxSizeBatchOption(size int) BatchOption { + return func(o *batchOptions) { + o.maxSize = size + } +} + +// MaxNodesBatchOption sets the maximum number of nodes in a Batch. +func MaxNodesBatchOption(num int) BatchOption { + return func(o *batchOptions) { + o.maxNodes = num + } +} + +// BufferedDAG implements DAGService using a Batch NodeAdder to wrap add +// operations in the given DAGService. It will trigger Commit() before any +// non-Add operations, but otherwise calling Commit() is left to the user. +type BufferedDAG struct { + ds DAGService + b *Batch +} + +// NewBufferedDAG creates a BufferedDAG using the given DAGService and the +// given options for the Batch NodeAdder. +func NewBufferedDAG(ctx context.Context, ds DAGService, opts ...BatchOption) *BufferedDAG { + return &BufferedDAG{ + ds: ds, + b: NewBatch(ctx, ds, opts...), + } +} + +// Commit calls commit on the Batch. +func (bd *BufferedDAG) Commit() error { + return bd.b.Commit() +} + +// Add adds a new node using Batch. +func (bd *BufferedDAG) Add(ctx context.Context, n Node) error { + return bd.b.Add(ctx, n) +} + +// AddMany adds many nodes using Batch. +func (bd *BufferedDAG) AddMany(ctx context.Context, nds []Node) error { + return bd.b.AddMany(ctx, nds) +} + +// Get commits and gets a node from the DAGService. +func (bd *BufferedDAG) Get(ctx context.Context, c cid.Cid) (Node, error) { + err := bd.b.Commit() + if err != nil { + return nil, err + } + return bd.ds.Get(ctx, c) +} + +// GetMany commits and gets nodes from the DAGService. +func (bd *BufferedDAG) GetMany(ctx context.Context, cs []cid.Cid) <-chan *NodeOption { + err := bd.b.Commit() + if err != nil { + ch := make(chan *NodeOption, 1) + defer close(ch) + ch <- &NodeOption{ + Node: nil, + Err: err, + } + return ch + } + return bd.ds.GetMany(ctx, cs) +} + +// Remove commits and removes a node from the DAGService. +func (bd *BufferedDAG) Remove(ctx context.Context, c cid.Cid) error { + err := bd.b.Commit() + if err != nil { + return err + } + return bd.ds.Remove(ctx, c) +} + +// RemoveMany commits and removes nodes from the DAGService. +func (bd *BufferedDAG) RemoveMany(ctx context.Context, cs []cid.Cid) error { + err := bd.b.Commit() + if err != nil { + return err + } + return bd.ds.RemoveMany(ctx, cs) +} diff --git a/vendor/github.com/ipfs/go-ipld-format/codecov.yml b/vendor/github.com/ipfs/go-ipld-format/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-ipld-format/coding.go b/vendor/github.com/ipfs/go-ipld-format/coding.go new file mode 100644 index 00000000..e202f75a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/coding.go @@ -0,0 +1,62 @@ +package format + +import ( + "fmt" + "sync" + + blocks "github.com/ipfs/go-block-format" +) + +// DecodeBlockFunc functions decode blocks into nodes. +type DecodeBlockFunc func(block blocks.Block) (Node, error) + +type BlockDecoder interface { + Register(codec uint64, decoder DecodeBlockFunc) + Decode(blocks.Block) (Node, error) +} +type safeBlockDecoder struct { + // Can be replaced with an RCU if necessary. + lock sync.RWMutex + decoders map[uint64]DecodeBlockFunc +} + +// Register registers decoder for all blocks with the passed codec. +// +// This will silently replace any existing registered block decoders. +func (d *safeBlockDecoder) Register(codec uint64, decoder DecodeBlockFunc) { + d.lock.Lock() + defer d.lock.Unlock() + d.decoders[codec] = decoder +} + +func (d *safeBlockDecoder) Decode(block blocks.Block) (Node, error) { + // Short-circuit by cast if we already have a Node. + if node, ok := block.(Node); ok { + return node, nil + } + + ty := block.Cid().Type() + + d.lock.RLock() + decoder, ok := d.decoders[ty] + d.lock.RUnlock() + + if ok { + return decoder(block) + } else { + // TODO: get the *long* name for this format + return nil, fmt.Errorf("unrecognized object type: %d", ty) + } +} + +var DefaultBlockDecoder BlockDecoder = &safeBlockDecoder{decoders: make(map[uint64]DecodeBlockFunc)} + +// Decode decodes the given block using the default BlockDecoder. +func Decode(block blocks.Block) (Node, error) { + return DefaultBlockDecoder.Decode(block) +} + +// Register registers block decoders with the default BlockDecoder. +func Register(codec uint64, decoder DecodeBlockFunc) { + DefaultBlockDecoder.Register(codec, decoder) +} diff --git a/vendor/github.com/ipfs/go-ipld-format/daghelpers.go b/vendor/github.com/ipfs/go-ipld-format/daghelpers.go new file mode 100644 index 00000000..70ad0b91 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/daghelpers.go @@ -0,0 +1,118 @@ +package format + +import ( + "context" + + cid "github.com/ipfs/go-cid" +) + +// GetLinks returns the CIDs of the children of the given node. Prefer this +// method over looking up the node itself and calling `Links()` on it as this +// method may be able to use a link cache. +func GetLinks(ctx context.Context, ng NodeGetter, c cid.Cid) ([]*Link, error) { + if c.Type() == cid.Raw { + return nil, nil + } + if gl, ok := ng.(LinkGetter); ok { + return gl.GetLinks(ctx, c) + } + node, err := ng.Get(ctx, c) + if err != nil { + return nil, err + } + return node.Links(), nil +} + +// GetDAG will fill out all of the links of the given Node. +// It returns an array of NodePromise with the linked nodes all in the proper +// order. +func GetDAG(ctx context.Context, ds NodeGetter, root Node) []*NodePromise { + var cids []cid.Cid + for _, lnk := range root.Links() { + cids = append(cids, lnk.Cid) + } + + return GetNodes(ctx, ds, cids) +} + +// GetNodes returns an array of 'FutureNode' promises, with each corresponding +// to the key with the same index as the passed in keys +func GetNodes(ctx context.Context, ds NodeGetter, keys []cid.Cid) []*NodePromise { + + // Early out if no work to do + if len(keys) == 0 { + return nil + } + + promises := make([]*NodePromise, len(keys)) + for i := range keys { + promises[i] = NewNodePromise(ctx) + } + + dedupedKeys := dedupeKeys(keys) + go func() { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + nodechan := ds.GetMany(ctx, dedupedKeys) + + for count := 0; count < len(keys); { + select { + case opt, ok := <-nodechan: + if !ok { + for _, p := range promises { + p.Fail(ErrNotFound) + } + return + } + + if opt.Err != nil { + for _, p := range promises { + p.Fail(opt.Err) + } + return + } + + nd := opt.Node + c := nd.Cid() + for i, lnk_c := range keys { + if c.Equals(lnk_c) { + count++ + promises[i].Send(nd) + } + } + case <-ctx.Done(): + return + } + } + }() + return promises +} + +func Copy(ctx context.Context, from, to DAGService, root cid.Cid) error { + node, err := from.Get(ctx, root) + if err != nil { + return err + } + links := node.Links() + for _, link := range links { + err := Copy(ctx, from, to, link.Cid) + if err != nil { + return err + } + } + err = to.Add(ctx, node) + if err != nil { + return err + } + return nil +} + +// Remove duplicates from a list of keys +func dedupeKeys(cids []cid.Cid) []cid.Cid { + set := cid.NewSet() + for _, c := range cids { + set.Add(c) + } + return set.Keys() +} diff --git a/vendor/github.com/ipfs/go-ipld-format/format.go b/vendor/github.com/ipfs/go-ipld-format/format.go new file mode 100644 index 00000000..990e1ce0 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/format.go @@ -0,0 +1,90 @@ +package format + +import ( + "context" + "fmt" + + blocks "github.com/ipfs/go-block-format" + + cid "github.com/ipfs/go-cid" +) + +type Resolver interface { + // Resolve resolves a path through this node, stopping at any link boundary + // and returning the object found as well as the remaining path to traverse + Resolve(path []string) (interface{}, []string, error) + + // Tree lists all paths within the object under 'path', and up to the given depth. + // To list the entire object (similar to `find .`) pass "" and -1 + Tree(path string, depth int) []string +} + +// Node is the base interface all IPLD nodes must implement. +// +// Nodes are **Immutable** and all methods defined on the interface are +// **Thread Safe**. +type Node interface { + blocks.Block + Resolver + + // ResolveLink is a helper function that calls resolve and asserts the + // output is a link + ResolveLink(path []string) (*Link, []string, error) + + // Copy returns a deep copy of this node + Copy() Node + + // Links is a helper function that returns all links within this object + Links() []*Link + + // TODO: not sure if stat deserves to stay + Stat() (*NodeStat, error) + + // Size returns the size in bytes of the serialized object + Size() (uint64, error) +} + +// Link represents an IPFS Merkle DAG Link between Nodes. +type Link struct { + // utf string name. should be unique per object + Name string // utf8 + + // cumulative size of target object + Size uint64 + + // multihash of the target object + Cid cid.Cid +} + +// NodeStat is a statistics object for a Node. Mostly sizes. +type NodeStat struct { + Hash string + NumLinks int // number of links in link table + BlockSize int // size of the raw, encoded data + LinksSize int // size of the links segment + DataSize int // size of the data segment + CumulativeSize int // cumulative size of object and its references +} + +func (ns NodeStat) String() string { + f := "NodeStat{NumLinks: %d, BlockSize: %d, LinksSize: %d, DataSize: %d, CumulativeSize: %d}" + return fmt.Sprintf(f, ns.NumLinks, ns.BlockSize, ns.LinksSize, ns.DataSize, ns.CumulativeSize) +} + +// MakeLink creates a link to the given node +func MakeLink(n Node) (*Link, error) { + s, err := n.Size() + if err != nil { + return nil, err + } + + return &Link{ + Size: s, + Cid: n.Cid(), + }, nil +} + +// GetNode returns the MDAG Node that this link points to +func (l *Link) GetNode(ctx context.Context, serv NodeGetter) (Node, error) { + return serv.Get(ctx, l.Cid) +} diff --git a/vendor/github.com/ipfs/go-ipld-format/go.mod b/vendor/github.com/ipfs/go-ipld-format/go.mod new file mode 100644 index 00000000..f56c4536 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/go.mod @@ -0,0 +1,7 @@ +module github.com/ipfs/go-ipld-format + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.2 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipld-format/go.sum b/vendor/github.com/ipfs/go-ipld-format/go.sum new file mode 100644 index 00000000..79b1fea1 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/go.sum @@ -0,0 +1,28 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipld-format/merkledag.go b/vendor/github.com/ipfs/go-ipld-format/merkledag.go new file mode 100644 index 00000000..755b90f6 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/merkledag.go @@ -0,0 +1,67 @@ +package format + +import ( + "context" + "fmt" + + cid "github.com/ipfs/go-cid" +) + +var ErrNotFound = fmt.Errorf("merkledag: not found") + +// Either a node or an error. +type NodeOption struct { + Node Node + Err error +} + +// The basic Node resolution service. +type NodeGetter interface { + // Get retrieves nodes by CID. Depending on the NodeGetter + // implementation, this may involve fetching the Node from a remote + // machine; consider setting a deadline in the context. + Get(context.Context, cid.Cid) (Node, error) + + // GetMany returns a channel of NodeOptions given a set of CIDs. + GetMany(context.Context, []cid.Cid) <-chan *NodeOption +} + +// NodeAdder adds nodes to a DAG. +type NodeAdder interface { + // Add adds a node to this DAG. + Add(context.Context, Node) error + + // AddMany adds many nodes to this DAG. + // + // Consider using the Batch NodeAdder (`NewBatch`) if you make + // extensive use of this function. + AddMany(context.Context, []Node) error +} + +// NodeGetters can optionally implement this interface to make finding linked +// objects faster. +type LinkGetter interface { + NodeGetter + + // TODO(ipfs/go-ipld-format#9): This should return []cid.Cid + + // GetLinks returns the children of the node refered to by the given + // CID. + GetLinks(ctx context.Context, nd cid.Cid) ([]*Link, error) +} + +// DAGService is an IPFS Merkle DAG service. +type DAGService interface { + NodeGetter + NodeAdder + + // Remove removes a node from this DAG. + // + // Remove returns no error if the requested node is not present in this DAG. + Remove(context.Context, cid.Cid) error + + // RemoveMany removes many nodes from this DAG. + // + // It returns success even if the nodes were not present in the DAG. + RemoveMany(context.Context, []cid.Cid) error +} diff --git a/vendor/github.com/ipfs/go-ipld-format/navipld.go b/vendor/github.com/ipfs/go-ipld-format/navipld.go new file mode 100644 index 00000000..12986737 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/navipld.go @@ -0,0 +1,149 @@ +package format + +import ( + "context" + + cid "github.com/ipfs/go-cid" +) + +// NavigableIPLDNode implements the `NavigableNode` interface wrapping +// an IPLD `Node` and providing support for node promises. +type NavigableIPLDNode struct { + node Node + + // The CID of each child of the node. + childCIDs []cid.Cid + + // Node promises for child nodes requested. + childPromises []*NodePromise + // TODO: Consider encapsulating it in a single structure alongside `childCIDs`. + + nodeGetter NodeGetter + // TODO: Should this be stored in the `Walker`'s context to avoid passing + // it along to every node? It seems like a structure that doesn't need + // to be replicated (the entire DAG will use the same `NodeGetter`). +} + +// NewNavigableIPLDNode returns a `NavigableIPLDNode` wrapping the provided +// `node`. +func NewNavigableIPLDNode(node Node, nodeGetter NodeGetter) *NavigableIPLDNode { + nn := &NavigableIPLDNode{ + node: node, + nodeGetter: nodeGetter, + } + + nn.childCIDs = getLinkCids(node) + nn.childPromises = make([]*NodePromise, len(nn.childCIDs)) + + return nn +} + +// FetchChild implements the `NavigableNode` interface using node promises +// to preload the following child nodes to `childIndex` leaving them ready +// for subsequent `FetchChild` calls. +func (nn *NavigableIPLDNode) FetchChild(ctx context.Context, childIndex uint) (NavigableNode, error) { + // This function doesn't check that `childIndex` is valid, that's + // the `Walker` responsibility. + + // If we drop to <= preloadSize/2 preloading nodes, preload the next 10. + for i := childIndex; i < childIndex+preloadSize/2 && i < uint(len(nn.childPromises)); i++ { + // TODO: Check if canceled. + if nn.childPromises[i] == nil { + nn.preload(ctx, i) + break + } + } + + child, err := nn.getPromiseValue(ctx, childIndex) + + switch err { + case nil: + case context.DeadlineExceeded, context.Canceled: + if ctx.Err() != nil { + return nil, ctx.Err() + } + + // In this case, the context used to *preload* the node (in a previous + // `FetchChild` call) has been canceled. We need to retry the load with + // the current context and we might as well preload some extra nodes + // while we're at it. + nn.preload(ctx, childIndex) + child, err = nn.getPromiseValue(ctx, childIndex) + if err != nil { + return nil, err + } + default: + return nil, err + } + + return NewNavigableIPLDNode(child, nn.nodeGetter), nil +} + +// Number of nodes to preload every time a child is requested. +// TODO: Give more visibility to this constant, it could be an attribute +// set in the `Walker` context that gets passed in `FetchChild`. +const preloadSize = 10 + +// Preload at most `preloadSize` child nodes from `beg` through promises +// created using this `ctx`. +func (nn *NavigableIPLDNode) preload(ctx context.Context, beg uint) { + end := beg + preloadSize + if end >= uint(len(nn.childCIDs)) { + end = uint(len(nn.childCIDs)) + } + + copy(nn.childPromises[beg:], GetNodes(ctx, nn.nodeGetter, nn.childCIDs[beg:end])) +} + +// Fetch the actual node (this is the blocking part of the mechanism) +// and invalidate the promise. `preload` should always be called first +// for the `childIndex` being fetch. +// +// TODO: Include `preload` into the beginning of this function? +// (And collapse the two calls in `FetchChild`). +func (nn *NavigableIPLDNode) getPromiseValue(ctx context.Context, childIndex uint) (Node, error) { + value, err := nn.childPromises[childIndex].Get(ctx) + nn.childPromises[childIndex] = nil + return value, err +} + +// Get the CID of all the links of this `node`. +func getLinkCids(node Node) []cid.Cid { + links := node.Links() + out := make([]cid.Cid, 0, len(links)) + + for _, l := range links { + out = append(out, l.Cid) + } + return out +} + +// GetIPLDNode returns the IPLD `Node` wrapped into this structure. +func (nn *NavigableIPLDNode) GetIPLDNode() Node { + return nn.node +} + +// ChildTotal implements the `NavigableNode` returning the number +// of links (of child nodes) in this node. +func (nn *NavigableIPLDNode) ChildTotal() uint { + return uint(len(nn.GetIPLDNode().Links())) +} + +// ExtractIPLDNode is a helper function that takes a `NavigableNode` +// and returns the IPLD `Node` wrapped inside. Used in the `Visitor` +// function. +// TODO: Check for errors to avoid a panic? +func ExtractIPLDNode(node NavigableNode) Node { + return node.(*NavigableIPLDNode).GetIPLDNode() +} + +// TODO: `Cleanup` is not supported at the moment in the `Walker`. +// +// Called in `Walker.up()` when the node is not part of the path anymore. +//func (nn *NavigableIPLDNode) Cleanup() { +// // TODO: Ideally this would be the place to issue a context `cancel()` +// // but since the DAG reader uses multiple contexts in the same session +// // (through `Read` and `CtxReadFull`) we would need to store an array +// // with the multiple contexts in `NavigableIPLDNode` with its corresponding +// // cancel functions. +//} diff --git a/vendor/github.com/ipfs/go-ipld-format/promise.go b/vendor/github.com/ipfs/go-ipld-format/promise.go new file mode 100644 index 00000000..02743b03 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/promise.go @@ -0,0 +1,66 @@ +package format + +import ( + "context" +) + +// NodePromise provides a promise like interface for a dag Node +// the first call to Get will block until the Node is received +// from its internal channels, subsequent calls will return the +// cached node. +// +// Thread Safety: This is multiple-consumer/single-producer safe. +func NewNodePromise(ctx context.Context) *NodePromise { + return &NodePromise{ + done: make(chan struct{}), + ctx: ctx, + } +} + +type NodePromise struct { + value Node + err error + done chan struct{} + + ctx context.Context +} + +// Call this function to fail a promise. +// +// Once a promise has been failed or fulfilled, further attempts to fail it will +// be silently dropped. +func (np *NodePromise) Fail(err error) { + if np.err != nil || np.value != nil { + // Already filled. + return + } + np.err = err + close(np.done) +} + +// Fulfill this promise. +// +// Once a promise has been fulfilled or failed, calling this function will +// panic. +func (np *NodePromise) Send(nd Node) { + // if promise has a value, don't fail it + if np.err != nil || np.value != nil { + panic("already filled") + } + np.value = nd + close(np.done) +} + +// Get the value of this promise. +// +// This function is safe to call concurrently from any number of goroutines. +func (np *NodePromise) Get(ctx context.Context) (Node, error) { + select { + case <-np.done: + return np.value, np.err + case <-np.ctx.Done(): + return nil, np.ctx.Err() + case <-ctx.Done(): + return nil, ctx.Err() + } +} diff --git a/vendor/github.com/ipfs/go-ipld-format/walker.go b/vendor/github.com/ipfs/go-ipld-format/walker.go new file mode 100644 index 00000000..81380936 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-format/walker.go @@ -0,0 +1,436 @@ +package format + +import ( + "context" + "errors" +) + +// Walker provides methods to move through a DAG of nodes that implement +// the `NavigableNode` interface. It uses iterative algorithms (instead +// of recursive ones) that expose the `path` of nodes from the root to +// the `ActiveNode` it currently points to. +// +// It provides multiple ways to walk through the DAG (e.g. `Iterate` +// and `Seek`). When using them, you provide a Visitor function that +// will be called for each node the Walker traverses. The Visitor can +// read data from those nodes and, optionally, direct the movement of +// the Walker by calling `Pause` (to stop traversing and return) or +// `NextChild` (to skip a child and its descendants). See the DAG reader +// in `github.com/ipfs/go-unixfs/io/dagreader.go` for a usage example. +// TODO: This example isn't merged yet. +type Walker struct { + + // Sequence of nodes in the DAG from the root to the `ActiveNode`, each + // position in the slice being the parent of the next one. The `ActiveNode` + // resides in the position indexed by `currentDepth` (the slice may contain + // more elements past that point but they should be ignored since the slice + // is not truncated to leverage the already allocated space). + // + // Every time `down` is called the `currentDepth` increases and the child + // of the `ActiveNode` is inserted after it (effectively becoming the new + // `ActiveNode`). + // + // The slice must *always* have a length bigger than zero with the root + // of the DAG at the first position (empty DAGs are not valid). + path []NavigableNode + + // Depth of the `ActiveNode`. It grows downwards, root being 0, its child 1, + // and so on. It controls the effective length of `path` and `childIndex`. + // + // A currentDepth of -1 signals the start case of a new `Walker` that hasn't + // moved yet. Although this state is an invalid index to the slices, it + // allows to centralize all the visit calls in the `down` move (starting at + // zero would require a special visit case inside every walk operation like + // `Iterate()` and `Seek`). This value should never be returned to after + // the first `down` movement, moving up from the root should always return + // `errUpOnRoot`. + currentDepth int + + // This slice has the index of the child each node in `path` is pointing + // to. The child index in the node can be set past all of its child nodes + // (having a value equal to `ChildTotal`) to signal it has visited (or + // skipped) all of them. A leaf node with no children that has its index + // in zero would also comply with this format. + // + // Complement to `path`, not only do we need to know which nodes have been + // traversed to reach the `ActiveNode` but also which child nodes they are + // to correctly have the active path of the DAG. (Reword this paragraph.) + childIndex []uint + + // Flag to signal that a pause in the current walk operation has been + // requested by the user inside `Visitor`. + pauseRequested bool + + // Used to pass information from the central `Walker` structure to the + // distributed `NavigableNode`s (to have a centralized configuration + // structure to control the behavior of all of them), e.g., to tell + // the `NavigableIPLDNode` which context should be used to load node + // promises (but this could later be used in more elaborate ways). + ctx context.Context +} + +// `Walker` implementation details: +// +// The `Iterate` and `Seek` walk operations are implemented through two +// basic move methods `up` and `down`, that change which node is the +// `ActiveNode` (modifying the `path` that leads to it). The `NextChild` +// method allows to change which child the `ActiveNode` is pointing to +// in order to change the direction of the descent. +// +// The `down` method is the analogous of a recursive call and the one in +// charge of visiting (possible new) nodes (through `Visitor`) and performing +// some user-defined logic. A `Pause` method is available to interrupt the +// current walk operation after visiting a node. +// +// Key terms and concepts: +// * Walk operation (e.g., `Iterate`). +// * Move methods: `up` and `down`. +// * Active node. +// * Path to the active node. + +// Function called each time a node is arrived upon in a walk operation +// through the `down` method (not when going back `up`). It is the main +// API to implement DAG functionality (e.g., read and seek a file DAG) +// on top of the `Walker` structure. +// +// Its argument is the current `node` being visited (the `ActiveNode`). +// Any error it returns (apart from the internal `errPauseWalkOperation`) +// will be forwarded to the caller of the walk operation (pausing it). +// +// Any of the exported methods of this API should be allowed to be called +// from within this method, e.g., `NextChild`. +// TODO: Check that. Can `ResetPosition` be called without breaking +// the `Walker` integrity? +type Visitor func(node NavigableNode) error + +// NavigableNode is the interface the nodes of a DAG need to implement in +// order to be traversed by the `Walker`. +type NavigableNode interface { + + // FetchChild returns the child of this node pointed to by `childIndex`. + // A `Context` stored in the `Walker` is passed (`ctx`) that may contain + // configuration attributes stored by the user before initiating the + // walk operation. + FetchChild(ctx context.Context, childIndex uint) (NavigableNode, error) + + // ChildTotal returns the number of children of the `ActiveNode`. + ChildTotal() uint + + // TODO: Evaluate providing the `Cleanup` and `Reset` methods. + + // Cleanup is an optional method that is called by the `Walker` when + // this node leaves the active `path`, i.e., when this node is the + // `ActiveNode` and the `up` movement is called. + //Cleanup() + // Allow this method to return an error? That would imply + // modifying the `Walker` API, `up()` would now return an error + // different than `errUpOnRoot`. + + // Reset is an optional function that is called by the `Walker` when + // `ResetPosition` is called, it is only applied to the root node + // of the DAG. + //Reset() +} + +// NewWalker creates a new `Walker` structure from a `root` +// NavigableNode. +func NewWalker(ctx context.Context, root NavigableNode) *Walker { + return &Walker{ + ctx: ctx, + + path: []NavigableNode{root}, + childIndex: []uint{0}, + + currentDepth: -1, + // Starting position, "on top" of the root node, see `currentDepth`. + } +} + +// ActiveNode returns the `NavigableNode` that `Walker` is pointing +// to at the moment. It changes when `up` or `down` is called. +func (w *Walker) ActiveNode() NavigableNode { + return w.path[w.currentDepth] + // TODO: Add a check for the initial state of `currentDepth` -1? +} + +// ErrDownNoChild signals there is no child at `ActiveChildIndex` in the +// `ActiveNode` to go down to. +var ErrDownNoChild = errors.New("can't go down, the child does not exist") + +// errUpOnRoot signals the end of the DAG after returning to the root. +var errUpOnRoot = errors.New("can't go up, already on root") + +// EndOfDag wraps the `errUpOnRoot` and signals to the user that the +// entire DAG has been iterated. +var EndOfDag = errors.New("end of DAG") + +// ErrNextNoChild signals the end of this parent child nodes. +var ErrNextNoChild = errors.New("can't go to the next child, no more child nodes in this parent") + +// errPauseWalkOperation signals the pause of the walk operation. +var errPauseWalkOperation = errors.New("pause in the current walk operation") + +// ErrNilVisitor signals the lack of a `Visitor` function. +var ErrNilVisitor = errors.New("no Visitor function specified") + +// Iterate the DAG through the DFS pre-order walk algorithm, going down +// as much as possible, then `NextChild` to the other siblings, and then up +// (to go down again). The position is saved throughout iterations (and +// can be previously set in `Seek`) allowing `Iterate` to be called +// repeatedly (after a `Pause`) to continue the iteration. +// +// This function returns the errors received from `down` (generated either +// inside the `Visitor` call or any other errors while fetching the child +// nodes), the rest of the move errors are handled within the function and +// are not returned. +func (w *Walker) Iterate(visitor Visitor) error { + + // Iterate until either: the end of the DAG (`errUpOnRoot`), a `Pause` + // is requested (`errPauseWalkOperation`) or an error happens (while + // going down). + for { + + // First, go down as much as possible. + for { + err := w.down(visitor) + + if err == ErrDownNoChild { + break + // Can't keep going down from this node, try to move Next. + } + + if err == errPauseWalkOperation { + return nil + // Pause requested, `errPauseWalkOperation` is just an internal + // error to signal to pause, don't pass it along. + } + + if err != nil { + return err + // `down` is the only movement that can return *any* error. + } + } + + // Can't move down anymore, turn to the next child in the `ActiveNode` + // to go down a different path. If there are no more child nodes + // available, go back up. + for { + err := w.NextChild() + if err == nil { + break + // No error, it turned to the next child. Try to go down again. + } + + // It can't go Next (`ErrNextNoChild`), try to move up. + err = w.up() + if err != nil { + // Can't move up, on the root again (`errUpOnRoot`). + return EndOfDag + } + + // Moved up, try `NextChild` again. + } + + // Turned to the next child (after potentially many up moves), + // try going down again. + } +} + +// Seek a specific node in a downwards manner. The `Visitor` should be +// used to steer the seek selecting at each node which child will the +// seek continue to (extending the `path` in that direction) or pause it +// (if the desired node has been found). The seek always starts from +// the root. It modifies the position so it shouldn't be used in-between +// `Iterate` calls (it can be used to set the position *before* iterating). +// If the visitor returns any non-`nil` errors the seek will stop. +// +// TODO: The seek could be extended to seek from the current position. +// (Is there something in the logic that would prevent it at the moment?) +func (w *Walker) Seek(visitor Visitor) error { + + if visitor == nil { + return ErrNilVisitor + // Although valid, there is no point in calling `Seek` without + // any extra logic, it would just go down to the leftmost leaf, + // so this would probably be a user error. + } + + // Go down until it the desired node is found (that will be signaled + // pausing the seek with `errPauseWalkOperation`) or a leaf node is + // reached (end of the DAG). + for { + err := w.down(visitor) + + if err == errPauseWalkOperation { + return nil + // Found the node, `errPauseWalkOperation` is just an internal + // error to signal to pause, don't pass it along. + } + + if err == ErrDownNoChild { + return nil + // Can't keep going down from this node, either at a leaf node + // or the `Visitor` has moved the child index past the + // available index (probably because none indicated that the + // target node could be down from there). + } + + if err != nil { + return err + // `down()` is the only movement that can return *any* error. + } + } + // TODO: Copied from the first part of `Iterate()` (although conceptually + // different from it). Could this be encapsulated in a function to avoid + // repeating code? The way the pause signal is handled it wouldn't seem + // very useful: the `errPauseWalkOperation` needs to be processed at this + // depth to return from the function (and pause the seek, returning + // from another function here wouldn't cause it to stop). +} + +// Go down one level in the DAG to the child of the `ActiveNode` +// pointed to by `ActiveChildIndex` and perform some logic on it by +// through the user-specified `visitor`. +// +// This should always be the first move in any walk operation +// (to visit the root node and move the `currentDepth` away +// from the negative value). +func (w *Walker) down(visitor Visitor) error { + child, err := w.fetchChild() + if err != nil { + return err + } + + w.extendPath(child) + + return w.visitActiveNode(visitor) +} + +// Fetch the child from the `ActiveNode` through the `FetchChild` +// method of the `NavigableNode` interface. +func (w *Walker) fetchChild() (NavigableNode, error) { + if w.currentDepth == -1 { + // First time `down()` is called, `currentDepth` is -1, + // return the root node. Don't check available child nodes + // (as the `Walker` is not actually on any node just yet + // and `ActiveChildIndex` is of no use yet). + return w.path[0], nil + } + + // Check if the child to fetch exists. + if w.ActiveChildIndex() >= w.ActiveNode().ChildTotal() { + return nil, ErrDownNoChild + } + + return w.ActiveNode().FetchChild(w.ctx, w.ActiveChildIndex()) + + // TODO: Maybe call `extendPath` here and hide it away + // from `down`. +} + +// Increase the `currentDepth` and extend the `path` to the fetched +// `child` node (which now becomes the new `ActiveNode`) +func (w *Walker) extendPath(child NavigableNode) { + w.currentDepth++ + + // Extend the slices if needed (doubling its capacity). + if w.currentDepth >= len(w.path) { + w.path = append(w.path, make([]NavigableNode, len(w.path))...) + w.childIndex = append(w.childIndex, make([]uint, len(w.childIndex))...) + // TODO: Check the performance of this grow mechanism. + } + + // `child` now becomes the `ActiveNode()`. + w.path[w.currentDepth] = child + w.childIndex[w.currentDepth] = 0 +} + +// Call the `Visitor` on the `ActiveNode`. This function should only be +// called from `down`. This is a wrapper function to `Visitor` to process +// the `Pause` signal and do other minor checks (taking this logic away +// from `down`). +func (w *Walker) visitActiveNode(visitor Visitor) error { + if visitor == nil { + return nil + // No need to check `pauseRequested` as `Pause` should + // only be called from within the `Visitor`. + } + + err := visitor(w.ActiveNode()) + + if w.pauseRequested { + // If a pause was requested make sure an error is returned + // that will cause the current walk operation to return. If + // `Visitor` didn't return an error set an artificial one + // generated by the `Walker`. + if err == nil { + err = errPauseWalkOperation + } + + w.pauseRequested = false + } + + return err +} + +// Go up from the `ActiveNode`. The only possible error this method +// can return is to signal it's already at the root and can't go up. +func (w *Walker) up() error { + if w.currentDepth < 1 { + return errUpOnRoot + } + + w.currentDepth-- + + // w.ActiveNode().Cleanup() + // If `Cleanup` is supported this would be the place to call it. + + return nil +} + +// NextChild increases the child index of the `ActiveNode` to point +// to the next child (which may exist or may be the end of the available +// child nodes). +// +// This method doesn't change the `ActiveNode`, it just changes where +// is it pointing to next, it could be interpreted as "turn to the next +// child". +func (w *Walker) NextChild() error { + w.incrementActiveChildIndex() + + if w.ActiveChildIndex() == w.ActiveNode().ChildTotal() { + return ErrNextNoChild + // At the end of the available children, signal it. + } + + return nil +} + +// incrementActiveChildIndex increments the child index of the `ActiveNode` to +// point to the next child (if it exists) or to the position past all of +// the child nodes (`ChildTotal`) to signal that all of its children have +// been visited/skipped (if already at that last position, do nothing). +func (w *Walker) incrementActiveChildIndex() { + if w.ActiveChildIndex()+1 <= w.ActiveNode().ChildTotal() { + w.childIndex[w.currentDepth]++ + } +} + +// ActiveChildIndex returns the index of the child the `ActiveNode()` +// is pointing to. +func (w *Walker) ActiveChildIndex() uint { + return w.childIndex[w.currentDepth] +} + +// SetContext changes the internal `Walker` (that is provided to the +// `NavigableNode`s when calling `FetchChild`) with the one passed +// as argument. +func (w *Walker) SetContext(ctx context.Context) { + w.ctx = ctx +} + +// Pause the current walk operation. This function must be called from +// within the `Visitor` function. +func (w *Walker) Pause() { + w.pauseRequested = true +} diff --git a/vendor/github.com/ipfs/go-ipld-git/.travis.yml b/vendor/github.com/ipfs/go-ipld-git/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipld-git/README.md b/vendor/github.com/ipfs/go-ipld-git/README.md new file mode 100644 index 00000000..db74e2bf --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/README.md @@ -0,0 +1,99 @@ +Git ipld format +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-ipld-git/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ipld-git/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-ipld-git.svg?branch=master)](https://travis-ci.org/ipfs/go-ipld-git) + +> An ipld codec for git objects allowing path traversals across the git graph! + +Note: This is WIP and may not be an entirely correct parser. + +## Table of Contents + +- [Install](#install) +- [About](#about) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +go get github.com/ipfs/go-ipld-git +``` + +## About +This is an IPLD codec which handles git objects. Objects are transformed +into IPLD graph in the following way: + +* Commit: +```json +{ + "author": { + "date": "1503667703 +0200", + "email": "author@mail", + "name": "Author Name" + }, + "committer": { + "date": "1503667703 +0200", + "email": "author@mail", + "name": "Author Name" + }, + "message": "Commit Message\n", + "parents": [ + , , ... + ], + "tree": +} + +``` + +* Tag: +```json +{ + "message": "message\n", + "object": { + "/": "baf4bcfg3mbz3yj3njqyr3ifdaqyfv3prei6h6bq" + }, + "tag": "tagname", + "tagger": { + "date": "1503667703 +0200", + "email": "author@mail", + "name": "Author Name" + }, + "type": "commit" +} + +``` + +* Tree: +```json +{ + "file.name": { + "mode": "100664", + "hash": + }, + "directoryname": { + "mode": "40000", + "hash": + }, + ... +} +``` + + +* Blob: +```json +"\0'>" +``` +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson diff --git a/vendor/github.com/ipfs/go-ipld-git/blob.go b/vendor/github.com/ipfs/go-ipld-git/blob.go new file mode 100644 index 00000000..8a67b981 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/blob.go @@ -0,0 +1,71 @@ +package ipldgit + +import ( + "encoding/json" + "errors" + + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +type Blob struct { + rawData []byte + cid cid.Cid +} + +func (b *Blob) Cid() cid.Cid { + return b.cid +} + +func (b *Blob) Copy() node.Node { + nb := *b + return &nb +} + +func (b *Blob) Links() []*node.Link { + return nil +} + +func (b *Blob) Resolve(_ []string) (interface{}, []string, error) { + return nil, nil, errors.New("no such link") +} + +func (b *Blob) ResolveLink(_ []string) (*node.Link, []string, error) { + return nil, nil, errors.New("no such link") +} + +func (b *Blob) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "git_blob", + } +} + +func (b *Blob) MarshalJSON() ([]byte, error) { + return json.Marshal(b.rawData) +} + +func (b *Blob) RawData() []byte { + return []byte(b.rawData) +} + +func (b *Blob) Size() (uint64, error) { + return uint64(len(b.rawData)), nil +} + +func (b *Blob) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +func (b *Blob) String() string { + return "[git blob]" +} + +func (b *Blob) Tree(p string, depth int) []string { + return nil +} + +func (b *Blob) GitSha() []byte { + return cidToSha(b.Cid()) +} + +var _ node.Node = (*Blob)(nil) diff --git a/vendor/github.com/ipfs/go-ipld-git/codecov.yml b/vendor/github.com/ipfs/go-ipld-git/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-ipld-git/commit.go b/vendor/github.com/ipfs/go-ipld-git/commit.go new file mode 100644 index 00000000..00b81e32 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/commit.go @@ -0,0 +1,286 @@ +package ipldgit + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "strconv" + "sync" + + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +type Commit struct { + DataSize string `json:"-"` + GitTree cid.Cid `json:"tree"` + Parents []cid.Cid `json:"parents"` + Message string `json:"message"` + Author *PersonInfo `json:"author"` + Committer *PersonInfo `json:"committer"` + Encoding string `json:"encoding,omitempty"` + Sig *GpgSig `json:"signature,omitempty"` + MergeTag []*MergeTag `json:"mergetag,omitempty"` + + // Other contains all the non-standard headers, such as 'HG:extra' + Other []string `json:"other,omitempty"` + + cid cid.Cid + + rawData []byte + rawDataOnce sync.Once +} + +type PersonInfo struct { + Name string + Email string + Date string + Timezone string +} + +func (pi *PersonInfo) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]string{ + "name": pi.Name, + "email": pi.Email, + "date": pi.Date + " " + pi.Timezone, + }) +} + +func (pi *PersonInfo) String() string { + f := "%s <%s>" + arg := []interface{}{pi.Name, pi.Email} + if pi.Date != "" { + f = f + " %s" + arg = append(arg, pi.Date) + } + + if pi.Timezone != "" { + f = f + " %s" + arg = append(arg, pi.Timezone) + } + return fmt.Sprintf(f, arg...) +} + +func (pi *PersonInfo) tree(name string, depth int) []string { + if depth == 1 { + return []string{name} + } + return []string{name + "/name", name + "/email", name + "/date"} +} + +func (pi *PersonInfo) resolve(p []string) (interface{}, []string, error) { + switch p[0] { + case "name": + return pi.Name, p[1:], nil + case "email": + return pi.Email, p[1:], nil + case "date": + return pi.Date + " " + pi.Timezone, p[1:], nil + default: + return nil, nil, errors.New("no such link") + } +} + +type MergeTag struct { + Object cid.Cid `json:"object"` + Type string `json:"type"` + Tag string `json:"tag"` + Tagger *PersonInfo `json:"tagger"` + Text string `json:"text"` +} + +type GpgSig struct { + Text string +} + +func (c *Commit) Cid() cid.Cid { + return c.cid +} + +func (c *Commit) Copy() node.Node { + nc := *c + return &nc +} + +func (c *Commit) Links() []*node.Link { + out := []*node.Link{ + {Cid: c.GitTree}, + } + + for _, p := range c.Parents { + out = append(out, &node.Link{Cid: p}) + } + return out +} + +func (c *Commit) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "git_commit", + } +} + +func (c *Commit) RawData() []byte { + c.rawDataOnce.Do(func() { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "commit %s\x00", c.DataSize) + fmt.Fprintf(buf, "tree %s\n", hex.EncodeToString(cidToSha(c.GitTree))) + for _, p := range c.Parents { + fmt.Fprintf(buf, "parent %s\n", hex.EncodeToString(cidToSha(p))) + } + fmt.Fprintf(buf, "author %s\n", c.Author.String()) + fmt.Fprintf(buf, "committer %s\n", c.Committer.String()) + if len(c.Encoding) > 0 { + fmt.Fprintf(buf, "encoding %s\n", c.Encoding) + } + for _, mtag := range c.MergeTag { + fmt.Fprintf(buf, "mergetag object %s\n", hex.EncodeToString(cidToSha(mtag.Object))) + fmt.Fprintf(buf, " type %s\n", mtag.Type) + fmt.Fprintf(buf, " tag %s\n", mtag.Tag) + fmt.Fprintf(buf, " tagger %s\n \n", mtag.Tagger.String()) + fmt.Fprintf(buf, "%s", mtag.Text) + } + if c.Sig != nil { + fmt.Fprintln(buf, "gpgsig -----BEGIN PGP SIGNATURE-----") + fmt.Fprint(buf, c.Sig.Text) + fmt.Fprintln(buf, " -----END PGP SIGNATURE-----") + } + for _, line := range c.Other { + fmt.Fprintln(buf, line) + } + fmt.Fprintf(buf, "\n%s", c.Message) + c.rawData = buf.Bytes() + }) + + return c.rawData +} + +func (c *Commit) Resolve(path []string) (interface{}, []string, error) { + if len(path) == 0 { + return nil, nil, fmt.Errorf("zero length path") + } + + switch path[0] { + case "parents": + if len(path) == 1 { + return c.Parents, nil, nil + } + + i, err := strconv.Atoi(path[1]) + if err != nil { + return nil, nil, err + } + + if i < 0 || i >= len(c.Parents) { + return nil, nil, fmt.Errorf("index out of range") + } + + return &node.Link{Cid: c.Parents[i]}, path[2:], nil + case "author": + if len(path) == 1 { + return c.Author, nil, nil + } + return c.Author.resolve(path[1:]) + case "committer": + if len(path) == 1 { + return c.Committer, nil, nil + } + return c.Committer.resolve(path[1:]) + case "signature": + return c.Sig.Text, path[1:], nil + case "message": + return c.Message, path[1:], nil + case "tree": + return &node.Link{Cid: c.GitTree}, path[1:], nil + case "mergetag": + if len(path) == 1 { + return c.MergeTag, nil, nil + } + + i, err := strconv.Atoi(path[1]) + if err != nil { + return nil, nil, err + } + + if i < 0 || i >= len(c.MergeTag) { + return nil, nil, fmt.Errorf("index out of range") + } + + if len(path) == 2 { + return c.MergeTag[i], nil, nil + } + return c.MergeTag[i].resolve(path[2:]) + default: + return nil, nil, errors.New("no such link") + } +} + +func (c *Commit) ResolveLink(path []string) (*node.Link, []string, error) { + out, rest, err := c.Resolve(path) + if err != nil { + return nil, nil, err + } + + lnk, ok := out.(*node.Link) + if !ok { + return nil, nil, errors.New("not a link") + } + + return lnk, rest, nil +} + +func (c *Commit) Size() (uint64, error) { + return uint64(len(c.RawData())), nil +} + +func (c *Commit) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +func (c *Commit) String() string { + return "[git commit object]" +} + +func (c *Commit) Tree(p string, depth int) []string { + if depth != -1 { + panic("proper tree not yet implemented") + } + tree := []string{"tree", "parents", "message", "gpgsig"} + tree = append(tree, c.Author.tree("author", depth)...) + tree = append(tree, c.Committer.tree("committer", depth)...) + for i := range c.Parents { + tree = append(tree, fmt.Sprintf("parents/%d", i)) + } + return tree +} + +func (c *Commit) GitSha() []byte { + return cidToSha(c.Cid()) +} + +func (t *MergeTag) resolve(path []string) (interface{}, []string, error) { + if len(path) == 0 { + return nil, nil, fmt.Errorf("zero length path") + } + + switch path[0] { + case "object": + return &node.Link{Cid: t.Object}, path[1:], nil + case "tag": + return t.Tag, path[1:], nil + case "tagger": + if len(path) == 1 { + return t.Tagger, nil, nil + } + return t.Tagger.resolve(path[1:]) + case "text": + return t.Text, path[1:], nil + case "type": + return t.Type, path[1:], nil + default: + return nil, nil, errors.New("no such link") + } +} + +var _ node.Node = (*Commit)(nil) diff --git a/vendor/github.com/ipfs/go-ipld-git/git.go b/vendor/github.com/ipfs/go-ipld-git/git.go new file mode 100644 index 00000000..8a443e84 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/git.go @@ -0,0 +1,478 @@ +package ipldgit + +import ( + "bufio" + "bytes" + "compress/zlib" + "encoding/hex" + "errors" + "fmt" + "io" + "io/ioutil" + "strconv" + "strings" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +func DecodeBlock(block blocks.Block) (node.Node, error) { + prefix := block.Cid().Prefix() + + if prefix.Codec != cid.GitRaw || prefix.MhType != mh.SHA1 || prefix.MhLength != mh.DefaultLengths[mh.SHA1] { + return nil, errors.New("invalid CID prefix") + } + + return ParseObjectFromBuffer(block.RawData()) +} + +var _ node.DecodeBlockFunc = DecodeBlock + +func ParseObjectFromBuffer(b []byte) (node.Node, error) { + return ParseObject(bytes.NewReader(b)) +} + +func ParseCompressedObject(r io.Reader) (node.Node, error) { + rc, err := zlib.NewReader(r) + if err != nil { + return nil, err + } + defer rc.Close() + + return ParseObject(rc) +} + +func ParseObject(r io.Reader) (node.Node, error) { + rd := bufio.NewReader(r) + + typ, err := rd.ReadString(' ') + if err != nil { + return nil, err + } + typ = typ[:len(typ)-1] + + switch typ { + case "tree": + return ReadTree(rd) + case "commit": + return ReadCommit(rd) + case "blob": + return ReadBlob(rd) + case "tag": + return ReadTag(rd) + default: + return nil, fmt.Errorf("unrecognized object type: %s", typ) + } +} + +func ReadBlob(rd *bufio.Reader) (*Blob, error) { + size, err := rd.ReadString(0) + if err != nil { + return nil, err + } + + sizen, err := strconv.Atoi(size[:len(size)-1]) + if err != nil { + return nil, err + } + + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "blob %d\x00", sizen) + + n, err := io.Copy(buf, rd) + if err != nil { + return nil, err + } + + if n != int64(sizen) { + return nil, fmt.Errorf("blob size was not accurate") + } + + out := &Blob{} + out.rawData = buf.Bytes() + out.cid = hashObject(out.RawData()) + + return out, nil +} + +func ReadCommit(rd *bufio.Reader) (*Commit, error) { + size, err := rd.ReadString(0) + if err != nil { + return nil, err + } + + out := &Commit{ + DataSize: size[:len(size)-1], + } + + for { + line, _, err := rd.ReadLine() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + + err = parseCommitLine(out, line, rd) + if err != nil { + return nil, err + } + } + + out.cid = hashObject(out.RawData()) + + return out, nil +} + +func parseCommitLine(out *Commit, line []byte, rd *bufio.Reader) error { + switch { + case bytes.HasPrefix(line, []byte("tree ")): + sha, err := hex.DecodeString(string(line[5:])) + if err != nil { + return err + } + + out.GitTree = shaToCid(sha) + case bytes.HasPrefix(line, []byte("parent ")): + psha, err := hex.DecodeString(string(line[7:])) + if err != nil { + return err + } + + out.Parents = append(out.Parents, shaToCid(psha)) + case bytes.HasPrefix(line, []byte("author ")): + a, err := parsePersonInfo(line) + if err != nil { + return err + } + + out.Author = a + case bytes.HasPrefix(line, []byte("committer ")): + c, err := parsePersonInfo(line) + if err != nil { + return err + } + + out.Committer = c + case bytes.HasPrefix(line, []byte("encoding ")): + out.Encoding = string(line[9:]) + case bytes.HasPrefix(line, []byte("mergetag object ")): + sha, err := hex.DecodeString(string(line)[16:]) + if err != nil { + return err + } + + mt, rest, err := ReadMergeTag(sha, rd) + if err != nil { + return err + } + + out.MergeTag = append(out.MergeTag, mt) + + if rest != nil { + err = parseCommitLine(out, rest, rd) + if err != nil { + return err + } + } + case bytes.HasPrefix(line, []byte("gpgsig ")): + sig, err := ReadGpgSig(rd) + if err != nil { + return err + } + out.Sig = sig + case len(line) == 0: + rest, err := ioutil.ReadAll(rd) + if err != nil { + return err + } + + out.Message = string(rest) + default: + out.Other = append(out.Other, string(line)) + } + return nil +} + +func ReadTag(rd *bufio.Reader) (*Tag, error) { + size, err := rd.ReadString(0) + if err != nil { + return nil, err + } + + out := &Tag{ + dataSize: size[:len(size)-1], + } + + for { + line, _, err := rd.ReadLine() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + + switch { + case bytes.HasPrefix(line, []byte("object ")): + sha, err := hex.DecodeString(string(line[7:])) + if err != nil { + return nil, err + } + + out.Object = shaToCid(sha) + case bytes.HasPrefix(line, []byte("tag ")): + out.Tag = string(line[4:]) + case bytes.HasPrefix(line, []byte("tagger ")): + c, err := parsePersonInfo(line) + if err != nil { + return nil, err + } + + out.Tagger = c + case bytes.HasPrefix(line, []byte("type ")): + out.Type = string(line[5:]) + case len(line) == 0: + rest, err := ioutil.ReadAll(rd) + if err != nil { + return nil, err + } + + out.Message = string(rest) + default: + fmt.Println("unhandled line: ", string(line)) + } + } + + out.cid = hashObject(out.RawData()) + + return out, nil +} + +func hashObject(data []byte) cid.Cid { + c, err := cid.Prefix{ + MhType: mh.SHA1, + MhLength: -1, + Codec: cid.GitRaw, + Version: 1, + }.Sum(data) + if err != nil { + panic(err) + } + return c +} + +func ReadMergeTag(hash []byte, rd *bufio.Reader) (*MergeTag, []byte, error) { + out := new(MergeTag) + + out.Object = shaToCid(hash) + for { + line, _, err := rd.ReadLine() + if err != nil { + if err == io.EOF { + break + } + return nil, nil, err + } + + switch { + case bytes.HasPrefix(line, []byte(" type ")): + out.Type = string(line[6:]) + case bytes.HasPrefix(line, []byte(" tag ")): + out.Tag = string(line[5:]) + case bytes.HasPrefix(line, []byte(" tagger ")): + tagger, err := parsePersonInfo(line[1:]) + if err != nil { + return nil, nil, err + } + out.Tagger = tagger + case string(line) == " ": + for { + line, _, err := rd.ReadLine() + if err != nil { + return nil, nil, err + } + + if !bytes.HasPrefix(line, []byte(" ")) { + return out, line, nil + } + + out.Text += string(line) + "\n" + } + } + } + return out, nil, nil +} + +func ReadGpgSig(rd *bufio.Reader) (*GpgSig, error) { + line, _, err := rd.ReadLine() + if err != nil { + return nil, err + } + + out := new(GpgSig) + + if string(line) != " " { + if strings.HasPrefix(string(line), " Version: ") || strings.HasPrefix(string(line), " Comment: ") { + out.Text += string(line) + "\n" + } else { + return nil, fmt.Errorf("expected first line of sig to be a single space or version") + } + } else { + out.Text += " \n" + } + + for { + line, _, err := rd.ReadLine() + if err != nil { + return nil, err + } + + if bytes.Equal(line, []byte(" -----END PGP SIGNATURE-----")) { + break + } + + out.Text += string(line) + "\n" + } + + return out, nil +} + +func parsePersonInfo(line []byte) (*PersonInfo, error) { + parts := bytes.Split(line, []byte{' '}) + if len(parts) < 3 { + fmt.Println(string(line)) + return nil, fmt.Errorf("incorrectly formatted person info line") + } + + //TODO: just use regex? + //skip prefix + at := 1 + + var pi PersonInfo + var name string + + for { + if at == len(parts) { + return nil, fmt.Errorf("invalid personInfo: %s\n", line) + } + part := parts[at] + if len(part) != 0 { + if part[0] == '<' { + break + } + name += string(part) + " " + } else if len(name) > 0 { + name += " " + } + at++ + } + if len(name) != 0 { + pi.Name = name[:len(name)-1] + } + + var email string + for { + if at == len(parts) { + return nil, fmt.Errorf("invalid personInfo: %s\n", line) + } + part := parts[at] + if part[0] == '<' { + part = part[1:] + } + + at++ + if part[len(part)-1] == '>' { + email += string(part[:len(part)-1]) + break + } + email += string(part) + " " + } + pi.Email = email + + if at == len(parts) { + return &pi, nil + } + pi.Date = string(parts[at]) + + at++ + if at == len(parts) { + return &pi, nil + } + pi.Timezone = string(parts[at]) + return &pi, nil +} + +func ReadTree(rd *bufio.Reader) (*Tree, error) { + lstr, err := rd.ReadString(0) + if err != nil { + return nil, err + } + lstr = lstr[:len(lstr)-1] + + n, err := strconv.Atoi(lstr) + if err != nil { + return nil, err + } + + t := &Tree{ + entries: make(map[string]*TreeEntry), + size: n, + } + var order []string + for { + e, err := ReadEntry(rd) + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + + order = append(order, e.name) + t.entries[e.name] = e + } + t.order = order + t.cid = hashObject(t.RawData()) + + return t, nil +} + +func cidToSha(c cid.Cid) []byte { + h := c.Hash() + return h[len(h)-20:] +} + +func shaToCid(sha []byte) cid.Cid { + h, _ := mh.Encode(sha, mh.SHA1) + return cid.NewCidV1(cid.GitRaw, h) +} + +func ReadEntry(r *bufio.Reader) (*TreeEntry, error) { + data, err := r.ReadString(' ') + if err != nil { + return nil, err + } + data = data[:len(data)-1] + + name, err := r.ReadString(0) + if err != nil { + return nil, err + } + name = name[:len(name)-1] + + sha := make([]byte, 20) + _, err = io.ReadFull(r, sha) + if err != nil { + return nil, err + } + + return &TreeEntry{ + name: name, + Mode: data, + Hash: shaToCid(sha), + }, nil +} diff --git a/vendor/github.com/ipfs/go-ipld-git/go.mod b/vendor/github.com/ipfs/go-ipld-git/go.mod new file mode 100644 index 00000000..433bb4e8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/go.mod @@ -0,0 +1,8 @@ +module github.com/ipfs/go-ipld-git + +require ( + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-ipld-format v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipld-git/go.sum b/vendor/github.com/ipfs/go-ipld-git/go.sum new file mode 100644 index 00000000..b524adb8 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/go.sum @@ -0,0 +1,30 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-ipld-git/make-test-repo.sh b/vendor/github.com/ipfs/go-ipld-git/make-test-repo.sh new file mode 100755 index 00000000..dbb3f230 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/make-test-repo.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash + +set -x +CUR_DIR=$(pwd) +TEST_DIR=$(mktemp -d) +cd ${TEST_DIR} + +git init + +# Test generic commit/blob + +git config user.name "John Doe" +git config user.email johndoe@example.com + +echo "Hello world" > file +git add file + +git commit -m "Init" + +# Test generic commit/tree/blob, weird person info + +mkdir dir +mkdir dir/subdir +mkdir dir2 + +echo "qwerty" > dir/f1 +echo "123456" > dir/subdir/f2 +echo "',.pyf" > dir2/f3 + +git add . + +git config user.name "John Doe & John Other" +git config user.email "johndoe@example.com, johnother@example.com" +git commit -m "Commit 2" + +# Test merge-tag +git config user.name "John Doe" +git config user.email johndoe@example.com + +git branch dev +git checkout dev + +echo ";qjkxb" > dir/f4 + +git add dir/f4 +git commit -m "Release" +git tag -a v1 -m "Some version" +git checkout master + +## defer eyes.Open() +## eyes.Close() + +git cat-file tag $(cat .git/refs/tags/v1) | head -n4 | sed 's/v1/v1sig/g' > sigobj +cat >>sigobj < sigtag +FILE=.git/objects/$(sha1sum sigtag | cut -d' ' -f1 | sed 's/../\0\//') +mkdir -p $(dirname ${FILE}) +cat sigtag | zlib-flate -compress > ${FILE} +echo $(sha1sum sigtag | cut -d' ' -f1) > .git/refs/tags/v1sig + +git merge v1sig --no-ff -m "Merge tag v1" + +# Test encoding +git config i18n.commitencoding "ISO-8859-1" +echo "fgcrl" > f6 +git add f6 +git commit -m "Encoded" + +# Test iplBlob/tree tags +git tag -a v1-file -m "Some file" 933b7583b7767b07ea4cf242c1be29162eb8bb85 +git tag -a v1-tree -m "Some tree" 672ef117424f54b71e5e058d1184de6a07450d0e + +# Create test 'signed' objects + +git cat-file commit $(cat .git/refs/heads/master) | head -n4 > sigobj +echo "gpgsig -----BEGIN PGP SIGNATURE-----" >> sigobj +echo " " >> sigobj +echo " NotReallyABase64Signature" >> sigobj +echo " ButItsGoodEnough" >> sigobj +echo " -----END PGP SIGNATURE-----" >> sigobj +echo "" >> sigobj +echo "Encoded" >> sigobj + +cat <(printf "commit %d\0" $(wc -c sigobj | cut -d' ' -f1); cat sigobj) > sigcommit +FILE=.git/objects/$(sha1sum sigcommit | cut -d' ' -f1 | sed 's/../\0\//') +mkdir -p $(dirname ${FILE}) +cat sigcommit | zlib-flate -compress > ${FILE} + +git cat-file commit $(cat .git/refs/heads/master) | head -n4 > sigobj +echo "gpgsig -----BEGIN PGP SIGNATURE-----" >> sigobj +echo " Version: 0.1.2" >> sigobj +echo " " >> sigobj +echo " NotReallyABase64Signature" >> sigobj +echo " ButItsGoodEnough" >> sigobj +echo " -----END PGP SIGNATURE-----" >> sigobj +echo " " >> sigobj +echo "" >> sigobj +echo "Encoded" >> sigobj + +cat <(printf "commit %d\0" $(wc -c sigobj | cut -d' ' -f1); cat sigobj) > sigcommit +FILE=.git/objects/$(sha1sum sigcommit | cut -d' ' -f1 | sed 's/../\0\//') +mkdir -p $(dirname ${FILE}) +cat sigcommit | zlib-flate -compress >> ${FILE} +rm sigobj sigcommit + +# Create test archive, clean up + +tar czf git.tar.gz .git +mv git.tar.gz ${CUR_DIR}/testdata.tar.gz +cd ${CUR_DIR} +rm -rf ${TEST_DIR} diff --git a/vendor/github.com/ipfs/go-ipld-git/package.json b/vendor/github.com/ipfs/go-ipld-git/package.json new file mode 100644 index 00000000..cff29bcf --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/package.json @@ -0,0 +1,42 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/ipfs/go-ipld-git" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipld-git" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + } + ], + "gxVersion": "0.10.0", + "language": "go", + "license": "", + "name": "go-ipld-git", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.3.6" +} + diff --git a/vendor/github.com/ipfs/go-ipld-git/tag.go b/vendor/github.com/ipfs/go-ipld-git/tag.go new file mode 100644 index 00000000..25245ac9 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/tag.go @@ -0,0 +1,136 @@ +package ipldgit + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "sync" + + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +type Tag struct { + Object cid.Cid `json:"object"` + Type string `json:"type"` + Tag string `json:"tag"` + Tagger *PersonInfo `json:"tagger"` + Message string `json:"message"` + dataSize string + + cid cid.Cid + + rawData []byte + rawDataOnce sync.Once +} + +func (t *Tag) Cid() cid.Cid { + return t.cid +} + +func (t *Tag) Copy() node.Node { + nt := *t + return &nt +} + +func (t *Tag) Links() []*node.Link { + return []*node.Link{{Cid: t.Object}} +} + +func (t *Tag) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "git_tag", + } +} + +func (t *Tag) RawData() []byte { + t.rawDataOnce.Do(func() { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "tag %s\x00", t.dataSize) + fmt.Fprintf(buf, "object %s\n", hex.EncodeToString(cidToSha(t.Object))) + fmt.Fprintf(buf, "type %s\n", t.Type) + fmt.Fprintf(buf, "tag %s\n", t.Tag) + if t.Tagger != nil { + fmt.Fprintf(buf, "tagger %s\n", t.Tagger.String()) + } + if t.Message != "" { + fmt.Fprintf(buf, "\n%s", t.Message) + } + t.rawData = buf.Bytes() + }) + + return t.rawData +} + +func (t *Tag) Resolve(path []string) (interface{}, []string, error) { + if len(path) == 0 { + return nil, nil, fmt.Errorf("zero length path") + } + + switch path[0] { + case "object": + return &node.Link{Cid: t.Object}, path[1:], nil + case "type": + return t.Type, path[1:], nil + case "tagger": + if len(path) == 1 { + return t.Tagger, nil, nil + } + return t.Tagger.resolve(path[1:]) + case "message": + return t.Message, path[1:], nil + case "tag": + return t.Tag, path[1:], nil + default: + return nil, nil, errors.New("no such link") + } +} + +func (t *Tag) ResolveLink(path []string) (*node.Link, []string, error) { + out, rest, err := t.Resolve(path) + if err != nil { + return nil, nil, err + } + + lnk, ok := out.(*node.Link) + if !ok { + return nil, nil, errors.New("not a link") + } + + return lnk, rest, nil +} + +func (t *Tag) Size() (uint64, error) { + return uint64(len(t.RawData())), nil +} + +func (t *Tag) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +func (t *Tag) String() string { + return "[git tag object]" +} + +func (t *Tag) Tree(p string, depth int) []string { + if p != "" { + if p == "tagger" { + return []string{"name", "email", "date"} + } + return nil + } + if depth == 0 { + return nil + } + + tree := []string{"object", "type", "tag", "message"} + tree = append(tree, t.Tagger.tree("tagger", depth)...) + return tree +} + +func (t *Tag) GitSha() []byte { + return cidToSha(t.Cid()) +} + +var _ node.Node = (*Tag)(nil) diff --git a/vendor/github.com/ipfs/go-ipld-git/testdata.tar.gz b/vendor/github.com/ipfs/go-ipld-git/testdata.tar.gz new file mode 100644 index 00000000..658dfe84 Binary files /dev/null and b/vendor/github.com/ipfs/go-ipld-git/testdata.tar.gz differ diff --git a/vendor/github.com/ipfs/go-ipld-git/tree.go b/vendor/github.com/ipfs/go-ipld-git/tree.go new file mode 100644 index 00000000..5ce354ac --- /dev/null +++ b/vendor/github.com/ipfs/go-ipld-git/tree.go @@ -0,0 +1,170 @@ +package ipldgit + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "sync" + + cid "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +type Tree struct { + entries map[string]*TreeEntry + size int + order []string + cid cid.Cid + rawData []byte + rawDataOnce sync.Once +} + +type TreeEntry struct { + name string + Mode string `json:"mode"` + Hash cid.Cid `json:"hash"` +} + +func (t *Tree) Cid() cid.Cid { + return t.cid +} + +func (t *Tree) String() string { + return "[git tree object]" +} + +func (t *Tree) GitSha() []byte { + return cidToSha(t.cid) +} + +func (t *Tree) Copy() node.Node { + out := &Tree{ + entries: make(map[string]*TreeEntry), + cid: t.cid, + size: t.size, + order: t.order, // TODO: make a deep copy of this + } + + for k, v := range t.entries { + nv := *v + out.entries[k] = &nv + } + return out +} + +func (t *Tree) MarshalJSON() ([]byte, error) { + return json.Marshal(t.entries) +} + +func (t *Tree) Tree(p string, depth int) []string { + if p != "" { + _, ok := t.entries[p] + if !ok { + return nil + } + + return []string{"mode", "type", "hash"} + } + + if depth == 0 { + return nil + } + + if depth == 1 { + return t.order + } + + var out []string + for k, _ := range t.entries { + out = append(out, k, k+"/mode", k+"/type", k+"/hash") + } + return out +} + +func (t *Tree) Links() []*node.Link { + var out []*node.Link + for _, v := range t.entries { + out = append(out, &node.Link{Cid: v.Hash}) + } + return out +} + +func (t *Tree) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "git tree object", + } +} + +func (t *Tree) RawData() []byte { + t.rawDataOnce.Do(func() { + buf := new(bytes.Buffer) + + fmt.Fprintf(buf, "tree %d\x00", t.size) + for _, s := range t.order { + t.entries[s].WriteTo(buf) + } + t.rawData = buf.Bytes() + }) + + return t.rawData +} + +func (t *Tree) Resolve(p []string) (interface{}, []string, error) { + e, ok := t.entries[p[0]] + if !ok { + return nil, nil, errors.New("no such link") + } + + if len(p) == 1 { + return e, nil, nil + } + + switch p[1] { + case "hash": + return &node.Link{Cid: e.Hash}, p[2:], nil + case "mode": + return e.Mode, p[2:], nil + default: + return nil, nil, errors.New("no such link") + } +} + +func (t Tree) ResolveLink(path []string) (*node.Link, []string, error) { + out, rest, err := t.Resolve(path) + if err != nil { + return nil, nil, err + } + + lnk, ok := out.(*node.Link) + if !ok { + return nil, nil, errors.New("not a link") + } + + return lnk, rest, nil +} + +func (t *Tree) Size() (uint64, error) { + return uint64(len(t.RawData())), nil +} + +func (t *Tree) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +func (te *TreeEntry) WriteTo(w io.Writer) (int, error) { + n, err := fmt.Fprintf(w, "%s %s\x00", te.Mode, te.name) + if err != nil { + return 0, err + } + + nn, err := w.Write(cidToSha(te.Hash)) + if err != nil { + return n, err + } + + return n + nn, nil +} + +var _ node.Node = (*Tree)(nil) diff --git a/vendor/github.com/ipfs/go-ipns/.travis.yml b/vendor/github.com/ipfs/go-ipns/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-ipns/LICENSE b/vendor/github.com/ipfs/go-ipns/LICENSE new file mode 100644 index 00000000..8ce02878 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/ipfs/go-ipns/Makefile b/vendor/github.com/ipfs/go-ipns/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/ipfs/go-ipns/README.md b/vendor/github.com/ipfs/go-ipns/README.md new file mode 100644 index 00000000..2ae0846a --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/README.md @@ -0,0 +1,61 @@ +# go-ipns + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-datastore?status.svg)](https://godoc.org/github.com/ipfs/go-ipns) + +> ipns record definitions + +This package contains all of the components necessary to create, understand, and validate IPNS records. It does *not* publish or resolve those records. [`go-ipfs`](https://github.com/ipfs/go-ipfs) uses this package internally to manipulate records. + +## Usage + +To create a new IPNS record: + +```go +import ( + "time" + + ipns "github.com/ipfs/go-ipns" + crypto "github.com/libp2p/go-libp2p-crypto" +) + +// Generate a private key to sign the IPNS record with. Most of the time, +// however, you'll want to retrieve an already-existing key from IPFS using the +// go-ipfs/core/coreapi CoreAPI.KeyAPI() interface. +privateKey, publicKey, err := crypto.GenerateKeyPair(crypto.RSA, 2048) +if err != nil { + panic(err) +} + +// Create an IPNS record that expires in one hour and points to the IPFS address +// /ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5 +ipnsRecord, err := ipns.Create(privateKey, []byte("/ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5"), 0, time.Now().Add(1*time.Hour)) +if err != nil { + panic(err) +} +``` + +Once you have the record, you’ll need to use IPFS to *publish* it. + +There are several other major operations you can do with `go-ipns`. Check out the [API docs](https://godoc.org/github.com/ipfs/go-ipns) or look at the tests in this repo for examples. + +## Documentation + +https://godoc.org/github.com/ipfs/go-ipns + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-ipns/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) + +## License + +Copyright (c) Protocol Labs, Inc. under the **MIT license**. See [LICENSE file](./LICENSE) for details. diff --git a/vendor/github.com/ipfs/go-ipns/codecov.yml b/vendor/github.com/ipfs/go-ipns/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/ipfs/go-ipns/errors.go b/vendor/github.com/ipfs/go-ipns/errors.go new file mode 100644 index 00000000..ebcd4e26 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/errors.go @@ -0,0 +1,37 @@ +package ipns + +import ( + "errors" +) + +// ErrExpiredRecord should be returned when an ipns record is +// invalid due to being too old +var ErrExpiredRecord = errors.New("expired record") + +// ErrUnrecognizedValidity is returned when an IpnsRecord has an +// unknown validity type. +var ErrUnrecognizedValidity = errors.New("unrecognized validity type") + +// ErrInvalidPath should be returned when an ipns record path +// is not in a valid format +var ErrInvalidPath = errors.New("record path invalid") + +// ErrSignature should be returned when an ipns record fails +// signature verification +var ErrSignature = errors.New("record signature verification failed") + +// ErrKeyFormat should be returned when an ipns record key is +// incorrectly formatted (not a peer ID) +var ErrKeyFormat = errors.New("record key could not be parsed into peer ID") + +// ErrPublicKeyNotFound should be returned when the public key +// corresponding to the ipns record path cannot be retrieved +// from the peer store +var ErrPublicKeyNotFound = errors.New("public key not found in peer store") + +// ErrPublicKeyMismatch should be returned when the public key embedded in the +// record doesn't match the expected public key. +var ErrPublicKeyMismatch = errors.New("public key in record did not match expected pubkey") + +// ErrBadRecord should be returned when an ipns record cannot be unmarshalled +var ErrBadRecord = errors.New("record could not be unmarshalled") diff --git a/vendor/github.com/ipfs/go-ipns/go.mod b/vendor/github.com/ipfs/go-ipns/go.mod new file mode 100644 index 00000000..842ca0d7 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/go.mod @@ -0,0 +1,11 @@ +module github.com/ipfs/go-ipns + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-crypto v0.0.1 + github.com/libp2p/go-libp2p-peer v0.0.1 + github.com/libp2p/go-libp2p-peerstore v0.0.1 + github.com/libp2p/go-libp2p-record v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-ipns/go.sum b/vendor/github.com/ipfs/go-ipns/go.sum new file mode 100644 index 00000000..6ef36abf --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/go.sum @@ -0,0 +1,114 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-ipns/ipns.go b/vendor/github.com/ipfs/go-ipns/ipns.go new file mode 100644 index 00000000..f145333b --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/ipns.go @@ -0,0 +1,168 @@ +package ipns + +import ( + "bytes" + "fmt" + "time" + + pb "github.com/ipfs/go-ipns/pb" + + u "github.com/ipfs/go-ipfs-util" + ic "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" +) + +// Create creates a new IPNS entry and signs it with the given private key. +// +// This function does not embed the public key. If you want to do that, use +// `EmbedPublicKey`. +func Create(sk ic.PrivKey, val []byte, seq uint64, eol time.Time) (*pb.IpnsEntry, error) { + entry := new(pb.IpnsEntry) + + entry.Value = val + typ := pb.IpnsEntry_EOL + entry.ValidityType = &typ + entry.Sequence = &seq + entry.Validity = []byte(u.FormatRFC3339(eol)) + + sig, err := sk.Sign(ipnsEntryDataForSig(entry)) + if err != nil { + return nil, err + } + entry.Signature = sig + + return entry, nil +} + +// Validates validates the given IPNS entry against the given public key. +func Validate(pk ic.PubKey, entry *pb.IpnsEntry) error { + // Check the ipns record signature with the public key + if ok, err := pk.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok { + return ErrSignature + } + + eol, err := GetEOL(entry) + if err != nil { + return err + } + if time.Now().After(eol) { + return ErrExpiredRecord + } + return nil +} + +// GetEOL returns the EOL of this IPNS entry +// +// This function returns ErrUnrecognizedValidity if the validity type of the +// record isn't EOL. Otherwise, it returns an error if it can't parse the EOL. +func GetEOL(entry *pb.IpnsEntry) (time.Time, error) { + if entry.GetValidityType() != pb.IpnsEntry_EOL { + return time.Time{}, ErrUnrecognizedValidity + } + return u.ParseRFC3339(string(entry.GetValidity())) +} + +// EmbedPublicKey embeds the given public key in the given ipns entry. While not +// strictly required, some nodes (e.g., DHT servers) may reject IPNS entries +// that don't embed their public keys as they may not be able to validate them +// efficiently. +func EmbedPublicKey(pk ic.PubKey, entry *pb.IpnsEntry) error { + // Try extracting the public key from the ID. If we can, *don't* embed + // it. + id, err := peer.IDFromPublicKey(pk) + if err != nil { + return err + } + if _, err := id.ExtractPublicKey(); err != peer.ErrNoPublicKey { + // Either a *real* error or nil. + return err + } + + // We failed to extract the public key from the peer ID, embed it in the + // record. + pkBytes, err := pk.Bytes() + if err != nil { + return err + } + entry.PubKey = pkBytes + return nil +} + +// ExtractPublicKey extracts a public key matching `pid` from the IPNS record, +// if possible. +// +// This function returns (nil, nil) when no public key can be extracted and +// nothing is malformed. +func ExtractPublicKey(pid peer.ID, entry *pb.IpnsEntry) (ic.PubKey, error) { + if entry.PubKey != nil { + pk, err := ic.UnmarshalPublicKey(entry.PubKey) + if err != nil { + return nil, fmt.Errorf("unmarshaling pubkey in record: %s", err) + } + + expPid, err := peer.IDFromPublicKey(pk) + if err != nil { + return nil, fmt.Errorf("could not regenerate peerID from pubkey: %s", err) + } + + if pid != expPid { + return nil, ErrPublicKeyMismatch + } + return pk, nil + } + + return pid.ExtractPublicKey() +} + +// Compare compares two IPNS entries. It returns: +// +// * -1 if a is older than b +// * 0 if a and b cannot be ordered (this doesn't mean that they are equal) +// * +1 if a is newer than b +// +// It returns an error when either a or b are malformed. +// +// NOTE: It *does not* validate the records, the caller is responsible for calling +// `Validate` first. +// +// NOTE: If a and b cannot be ordered by this function, you can determine their +// order by comparing their serialized byte representations (using +// `bytes.Compare`). You must do this if you are implementing a libp2p record +// validator (or you can just use the one provided for you by this package). +func Compare(a, b *pb.IpnsEntry) (int, error) { + as := a.GetSequence() + bs := b.GetSequence() + + if as > bs { + return 1, nil + } else if as < bs { + return -1, nil + } + + at, err := u.ParseRFC3339(string(a.GetValidity())) + if err != nil { + return 0, err + } + + bt, err := u.ParseRFC3339(string(b.GetValidity())) + if err != nil { + return 0, err + } + + if at.After(bt) { + return 1, nil + } else if bt.After(at) { + return -1, nil + } + + return 0, nil +} + +func ipnsEntryDataForSig(e *pb.IpnsEntry) []byte { + return bytes.Join([][]byte{ + e.Value, + e.Validity, + []byte(fmt.Sprint(e.GetValidityType())), + }, + []byte{}) +} diff --git a/vendor/github.com/ipfs/go-ipns/package.json b/vendor/github.com/ipfs/go-ipns/package.json new file mode 100644 index 00000000..e728289c --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/package.json @@ -0,0 +1,58 @@ +{ + "author": "stebalien", + "bugs": { + "url": "https://github.com/ipfs/go-ipns/issues" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-ipns" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + }, + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "whyrusleeping", + "hash": "QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK", + "name": "go-libp2p-crypto", + "version": "2.0.7" + }, + { + "author": "whyrusleeping", + "hash": "QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h", + "name": "go-libp2p-peer", + "version": "3.1.2" + }, + { + "author": "whyrusleeping", + "hash": "QmaCTz9RkrU13bm9kMB54f7atgqM4qkjDZpRwRoJiWXEqs", + "name": "go-libp2p-peerstore", + "version": "2.0.19" + }, + { + "hash": "QmbeHtaBy9nZsW4cHRcvgVY4CnDhXudE2Dr6qDxS7yg9rX", + "name": "go-libp2p-record", + "version": "4.1.15" + }, + { + "author": "whyrusleeping", + "hash": "QmddjPSGZb3ieihSseFeCfVRpZzcqczPNsD2DvarSwnjJB", + "name": "gogo-protobuf", + "version": "1.2.1" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-ipns", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.23" +} + diff --git a/vendor/github.com/ipfs/go-ipns/pb/Makefile b/vendor/github.com/ipfs/go-ipns/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/ipfs/go-ipns/pb/ipns.pb.go b/vendor/github.com/ipfs/go-ipns/pb/ipns.pb.go new file mode 100644 index 00000000..b38ce4ea --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/pb/ipns.pb.go @@ -0,0 +1,678 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ipns.proto + +package ipns_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type IpnsEntry_ValidityType int32 + +const ( + // setting an EOL says "this record is valid until..." + IpnsEntry_EOL IpnsEntry_ValidityType = 0 +) + +var IpnsEntry_ValidityType_name = map[int32]string{ + 0: "EOL", +} + +var IpnsEntry_ValidityType_value = map[string]int32{ + "EOL": 0, +} + +func (x IpnsEntry_ValidityType) Enum() *IpnsEntry_ValidityType { + p := new(IpnsEntry_ValidityType) + *p = x + return p +} + +func (x IpnsEntry_ValidityType) String() string { + return proto.EnumName(IpnsEntry_ValidityType_name, int32(x)) +} + +func (x *IpnsEntry_ValidityType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(IpnsEntry_ValidityType_value, data, "IpnsEntry_ValidityType") + if err != nil { + return err + } + *x = IpnsEntry_ValidityType(value) + return nil +} + +func (IpnsEntry_ValidityType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_4d5b16fb32bfe8ea, []int{0, 0} +} + +type IpnsEntry struct { + Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"` + ValidityType *IpnsEntry_ValidityType `protobuf:"varint,3,opt,name=validityType,enum=ipns.pb.IpnsEntry_ValidityType" json:"validityType,omitempty"` + Validity []byte `protobuf:"bytes,4,opt,name=validity" json:"validity,omitempty"` + Sequence *uint64 `protobuf:"varint,5,opt,name=sequence" json:"sequence,omitempty"` + Ttl *uint64 `protobuf:"varint,6,opt,name=ttl" json:"ttl,omitempty"` + // in order for nodes to properly validate a record upon receipt, they need the public + // key associated with it. For old RSA keys, its easiest if we just send this as part of + // the record itself. For newer ed25519 keys, the public key can be embedded in the + // peerID, making this field unnecessary. + PubKey []byte `protobuf:"bytes,7,opt,name=pubKey" json:"pubKey,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IpnsEntry) Reset() { *m = IpnsEntry{} } +func (m *IpnsEntry) String() string { return proto.CompactTextString(m) } +func (*IpnsEntry) ProtoMessage() {} +func (*IpnsEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_4d5b16fb32bfe8ea, []int{0} +} +func (m *IpnsEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IpnsEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IpnsEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IpnsEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_IpnsEntry.Merge(m, src) +} +func (m *IpnsEntry) XXX_Size() int { + return m.Size() +} +func (m *IpnsEntry) XXX_DiscardUnknown() { + xxx_messageInfo_IpnsEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_IpnsEntry proto.InternalMessageInfo + +func (m *IpnsEntry) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *IpnsEntry) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *IpnsEntry) GetValidityType() IpnsEntry_ValidityType { + if m != nil && m.ValidityType != nil { + return *m.ValidityType + } + return IpnsEntry_EOL +} + +func (m *IpnsEntry) GetValidity() []byte { + if m != nil { + return m.Validity + } + return nil +} + +func (m *IpnsEntry) GetSequence() uint64 { + if m != nil && m.Sequence != nil { + return *m.Sequence + } + return 0 +} + +func (m *IpnsEntry) GetTtl() uint64 { + if m != nil && m.Ttl != nil { + return *m.Ttl + } + return 0 +} + +func (m *IpnsEntry) GetPubKey() []byte { + if m != nil { + return m.PubKey + } + return nil +} + +func init() { + proto.RegisterEnum("ipns.pb.IpnsEntry_ValidityType", IpnsEntry_ValidityType_name, IpnsEntry_ValidityType_value) + proto.RegisterType((*IpnsEntry)(nil), "ipns.pb.IpnsEntry") +} + +func init() { proto.RegisterFile("ipns.proto", fileDescriptor_4d5b16fb32bfe8ea) } + +var fileDescriptor_4d5b16fb32bfe8ea = []byte{ + // 221 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xca, 0x2c, 0xc8, 0x2b, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0xb0, 0x93, 0x94, 0xfe, 0x33, 0x72, 0x71, + 0x7a, 0x16, 0xe4, 0x15, 0xbb, 0xe6, 0x95, 0x14, 0x55, 0x0a, 0x89, 0x70, 0xb1, 0x96, 0x25, 0xe6, + 0x94, 0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x69, 0xf0, 0x04, 0x41, 0x38, 0x42, 0x32, 0x5c, 0x9c, 0xc5, + 0x99, 0xe9, 0x79, 0x89, 0x25, 0xa5, 0x45, 0xa9, 0x12, 0x4c, 0x60, 0x19, 0x84, 0x80, 0x90, 0x33, + 0x17, 0x4f, 0x59, 0x62, 0x4e, 0x66, 0x4a, 0x66, 0x49, 0x65, 0x48, 0x65, 0x41, 0xaa, 0x04, 0xb3, + 0x02, 0xa3, 0x06, 0x9f, 0x91, 0xbc, 0x1e, 0xd4, 0x06, 0x3d, 0xb8, 0xe9, 0x7a, 0x61, 0x48, 0xca, + 0x82, 0x50, 0x34, 0x09, 0x49, 0x71, 0x71, 0xc0, 0xf8, 0x12, 0x2c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, + 0x70, 0x3e, 0x48, 0xae, 0x38, 0xb5, 0xb0, 0x34, 0x35, 0x2f, 0x39, 0x55, 0x82, 0x55, 0x81, 0x51, + 0x83, 0x25, 0x08, 0xce, 0x17, 0x12, 0xe0, 0x62, 0x2e, 0x29, 0xc9, 0x91, 0x60, 0x03, 0x0b, 0x83, + 0x98, 0x42, 0x62, 0x5c, 0x6c, 0x05, 0xa5, 0x49, 0xde, 0xa9, 0x95, 0x12, 0xec, 0x60, 0x73, 0xa0, + 0x3c, 0x25, 0x71, 0x2e, 0x1e, 0x64, 0xfb, 0x85, 0xd8, 0xb9, 0x98, 0x5d, 0xfd, 0x7d, 0x04, 0x18, + 0x9c, 0x78, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0x46, 0x40, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0x35, 0xc7, 0xf2, 0x25, 0x01, 0x00, 0x00, +} + +func (m *IpnsEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IpnsEntry) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } else { + dAtA[i] = 0xa + i++ + i = encodeVarintIpns(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if m.Signature == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("signature") + } else { + dAtA[i] = 0x12 + i++ + i = encodeVarintIpns(dAtA, i, uint64(len(m.Signature))) + i += copy(dAtA[i:], m.Signature) + } + if m.ValidityType != nil { + dAtA[i] = 0x18 + i++ + i = encodeVarintIpns(dAtA, i, uint64(*m.ValidityType)) + } + if m.Validity != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintIpns(dAtA, i, uint64(len(m.Validity))) + i += copy(dAtA[i:], m.Validity) + } + if m.Sequence != nil { + dAtA[i] = 0x28 + i++ + i = encodeVarintIpns(dAtA, i, uint64(*m.Sequence)) + } + if m.Ttl != nil { + dAtA[i] = 0x30 + i++ + i = encodeVarintIpns(dAtA, i, uint64(*m.Ttl)) + } + if m.PubKey != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintIpns(dAtA, i, uint64(len(m.PubKey))) + i += copy(dAtA[i:], m.PubKey) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintIpns(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *IpnsEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != nil { + l = len(m.Value) + n += 1 + l + sovIpns(uint64(l)) + } + if m.Signature != nil { + l = len(m.Signature) + n += 1 + l + sovIpns(uint64(l)) + } + if m.ValidityType != nil { + n += 1 + sovIpns(uint64(*m.ValidityType)) + } + if m.Validity != nil { + l = len(m.Validity) + n += 1 + l + sovIpns(uint64(l)) + } + if m.Sequence != nil { + n += 1 + sovIpns(uint64(*m.Sequence)) + } + if m.Ttl != nil { + n += 1 + sovIpns(uint64(*m.Ttl)) + } + if m.PubKey != nil { + l = len(m.PubKey) + n += 1 + l + sovIpns(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovIpns(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozIpns(x uint64) (n int) { + return sovIpns(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *IpnsEntry) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IpnsEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IpnsEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIpns + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIpns + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIpns + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIpns + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidityType", wireType) + } + var v IpnsEntry_ValidityType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= IpnsEntry_ValidityType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ValidityType = &v + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validity", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIpns + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIpns + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validity = append(m.Validity[:0], dAtA[iNdEx:postIndex]...) + if m.Validity == nil { + m.Validity = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Sequence = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ttl = &v + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIpns + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIpns + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIpns + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubKey = append(m.PubKey[:0], dAtA[iNdEx:postIndex]...) + if m.PubKey == nil { + m.PubKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIpns(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIpns + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIpns + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("value") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("signature") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIpns(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIpns + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIpns + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIpns + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthIpns + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthIpns + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIpns + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipIpns(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthIpns + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthIpns = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIpns = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-ipns/pb/ipns.proto b/vendor/github.com/ipfs/go-ipns/pb/ipns.proto new file mode 100644 index 00000000..f2e79fef --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/pb/ipns.proto @@ -0,0 +1,25 @@ +syntax = "proto2"; + +package ipns.pb; + +message IpnsEntry { + enum ValidityType { + // setting an EOL says "this record is valid until..." + EOL = 0; + } + required bytes value = 1; + required bytes signature = 2; + + optional ValidityType validityType = 3; + optional bytes validity = 4; + + optional uint64 sequence = 5; + + optional uint64 ttl = 6; + + // in order for nodes to properly validate a record upon receipt, they need the public + // key associated with it. For old RSA keys, its easiest if we just send this as part of + // the record itself. For newer ed25519 keys, the public key can be embedded in the + // peerID, making this field unnecessary. + optional bytes pubKey = 7; +} diff --git a/vendor/github.com/ipfs/go-ipns/record.go b/vendor/github.com/ipfs/go-ipns/record.go new file mode 100644 index 00000000..eb60ce6f --- /dev/null +++ b/vendor/github.com/ipfs/go-ipns/record.go @@ -0,0 +1,126 @@ +package ipns + +import ( + "bytes" + "errors" + + pb "github.com/ipfs/go-ipns/pb" + + proto "github.com/gogo/protobuf/proto" + logging "github.com/ipfs/go-log" + ic "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" + pstore "github.com/libp2p/go-libp2p-peerstore" + record "github.com/libp2p/go-libp2p-record" +) + +var log = logging.Logger("ipns") + +var _ record.Validator = Validator{} + +// RecordKey returns the libp2p record key for a given peer ID. +func RecordKey(pid peer.ID) string { + return "/ipns/" + string(pid) +} + +// Validator is an IPNS record validator that satisfies the libp2p record +// validator interface. +type Validator struct { + // KeyBook, if non-nil, will be used to lookup keys for validating IPNS + // records. + KeyBook pstore.KeyBook +} + +// Validate validates an IPNS record. +func (v Validator) Validate(key string, value []byte) error { + ns, pidString, err := record.SplitKey(key) + if err != nil || ns != "ipns" { + return ErrInvalidPath + } + + // Parse the value into an IpnsEntry + entry := new(pb.IpnsEntry) + err = proto.Unmarshal(value, entry) + if err != nil { + return ErrBadRecord + } + + // Get the public key defined by the ipns path + pid, err := peer.IDFromString(pidString) + if err != nil { + log.Debugf("failed to parse ipns record key %s into peer ID", pidString) + return ErrKeyFormat + } + + pubk, err := v.getPublicKey(pid, entry) + if err != nil { + return err + } + + return Validate(pubk, entry) +} + +func (v Validator) getPublicKey(pid peer.ID, entry *pb.IpnsEntry) (ic.PubKey, error) { + switch pk, err := ExtractPublicKey(pid, entry); err { + case peer.ErrNoPublicKey: + case nil: + return pk, nil + default: + return nil, err + } + + if v.KeyBook == nil { + log.Debugf("public key with hash %s not found in IPNS record and no peer store provided", pid) + return nil, ErrPublicKeyNotFound + } + + pubk := v.KeyBook.PubKey(pid) + if pubk == nil { + log.Debugf("public key with hash %s not found in peer store", pid) + return nil, ErrPublicKeyNotFound + } + return pubk, nil +} + +// Select selects the best record by checking which has the highest sequence +// number and latest EOL. +// +// This function returns an error if any of the records fail to parse. Validate +// your records first! +func (v Validator) Select(k string, vals [][]byte) (int, error) { + var recs []*pb.IpnsEntry + for _, v := range vals { + e := new(pb.IpnsEntry) + if err := proto.Unmarshal(v, e); err != nil { + return -1, err + } + recs = append(recs, e) + } + + return selectRecord(recs, vals) +} + +func selectRecord(recs []*pb.IpnsEntry, vals [][]byte) (int, error) { + switch len(recs) { + case 0: + return -1, errors.New("no usable records in given set") + case 1: + return 0, nil + } + + var i int + for j := 1; j < len(recs); j++ { + cmp, err := Compare(recs[i], recs[j]) + if err != nil { + return -1, err + } + if cmp == 0 { + cmp = bytes.Compare(vals[i], vals[j]) + } + if cmp < 0 { + i = j + } + } + + return i, nil +} diff --git a/vendor/github.com/ipfs/go-log/.travis.yml b/vendor/github.com/ipfs/go-log/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-log/LICENSE b/vendor/github.com/ipfs/go-log/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/ipfs/go-log/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-log/README.md b/vendor/github.com/ipfs/go-log/README.md new file mode 100644 index 00000000..344b25a4 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/README.md @@ -0,0 +1,79 @@ +# go-log + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-log?status.svg)](https://godoc.org/github.com/ipfs/go-log) +[![Build Status](https://travis-ci.org/ipfs/go-log.svg?branch=master)](https://travis-ci.org/ipfs/go-log) + + + + +> The logging library used by go-ipfs + +It currently uses a modified version of [go-logging](https://github.com/whyrusleeping/go-logging) to implement the standard printf-style log output. + +## Install + +```sh +go get github.com/ipfs/go-log +``` + +## Usage + +Once the pacakge is imported under the name `logging`, an instance of `EventLogger` can be created like so: + +```go +var log = logging.Logger("subsystem name") +``` + +It can then be used to emit log messages, either plain printf-style messages at six standard levels or structured messages using `Start`, `StartFromParentState`, `Finish` and `FinishWithErr` methods. + +## Example + +```go +func (s *Session) GetBlock(ctx context.Context, c *cid.Cid) (blk blocks.Block, err error) { + + // Starts Span called "Session.GetBlock", associates with `ctx` + ctx = log.Start(ctx, "Session.GetBlock") + + // defer so `blk` and `err` can be evaluated after call + defer func() { + // tag span associated with `ctx` + log.SetTags(ctx, map[string]interface{}{ + "cid": c, + "block", blk, + }) + // if err is non-nil tag the span with an error + log.FinishWithErr(ctx, err) + }() + + if shouldStartSomething() { + // log message on span associated with `ctx` + log.LogKV(ctx, "startSomething", true) + } + ... +} +``` +## Tracing + +`go-log` wraps the [opentracing-go](https://github.com/opentracing/opentracing-go) methods - `StartSpan`, `Finish`, `LogKV`, and `SetTag`. + +`go-log` implements its own tracer - `loggabletracer` - based on the [basictracer-go](https://github.com/opentracing/basictracer-go) implementation. If there is an active [`WriterGroup`](https://github.com/ipfs/go-log/blob/master/writer/option.go) the `loggabletracer` will [record](https://github.com/ipfs/go-log/blob/master/tracer/recorder.go) span data to the `WriterGroup`. An example of this can be seen in the [`log tail`](https://github.com/ipfs/go-ipfs/blob/master/core/commands/log.go) command of `go-ipfs`. + +Third party tracers may be used by calling `opentracing.SetGlobalTracer()` with your desired tracing implementation. An example of this can be seen using the [`go-jaeger-plugin`](https://github.com/ipfs/go-jaeger-plugin) and the `go-ipfs` [tracer plugin](https://github.com/ipfs/go-ipfs/blob/master/plugin/tracer.go) + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-log/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT diff --git a/vendor/github.com/ipfs/go-log/context.go b/vendor/github.com/ipfs/go-log/context.go new file mode 100644 index 00000000..b8ef5bc8 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/context.go @@ -0,0 +1,38 @@ +package log + +import ( + "context" + "errors" +) + +type key int + +const metadataKey key = 0 + +// ContextWithLoggable returns a derived context which contains the provided +// Loggable. Any Events logged with the derived context will include the +// provided Loggable. +func ContextWithLoggable(ctx context.Context, l Loggable) context.Context { + existing, err := MetadataFromContext(ctx) + if err != nil { + // context does not contain meta. just set the new metadata + child := context.WithValue(ctx, metadataKey, Metadata(l.Loggable())) + return child + } + + merged := DeepMerge(existing, l.Loggable()) + child := context.WithValue(ctx, metadataKey, merged) + return child +} + +// MetadataFromContext extracts Matadata from a given context's value. +func MetadataFromContext(ctx context.Context) (Metadata, error) { + value := ctx.Value(metadataKey) + if value != nil { + metadata, ok := value.(Metadata) + if ok { + return metadata, nil + } + } + return nil, errors.New("context contains no metadata") +} diff --git a/vendor/github.com/ipfs/go-log/entry.go b/vendor/github.com/ipfs/go-log/entry.go new file mode 100644 index 00000000..63c02135 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/entry.go @@ -0,0 +1,7 @@ +package log + +type entry struct { + loggables []Loggable + system string + event string +} diff --git a/vendor/github.com/ipfs/go-log/go.mod b/vendor/github.com/ipfs/go-log/go.mod new file mode 100644 index 00000000..c1716c85 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/go.mod @@ -0,0 +1,10 @@ +module github.com/ipfs/go-log + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/mattn/go-colorable v0.1.1 + github.com/opentracing/opentracing-go v1.0.2 + github.com/stretchr/testify v1.3.0 // indirect + github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc + golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 // indirect +) diff --git a/vendor/github.com/ipfs/go-log/go.sum b/vendor/github.com/ipfs/go-log/go.sum new file mode 100644 index 00000000..b9b0dc91 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/go.sum @@ -0,0 +1,24 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/ipfs/go-log/log.go b/vendor/github.com/ipfs/go-log/log.go new file mode 100644 index 00000000..735eebab --- /dev/null +++ b/vendor/github.com/ipfs/go-log/log.go @@ -0,0 +1,404 @@ +// Package log is the logging library used by IPFS +// (https://github.com/ipfs/go-ipfs). It uses a modified version of +// https://godoc.org/github.com/whyrusleeping/go-logging . +package log + +import ( + "bytes" + "context" + "encoding/json" + "path" + "runtime" + "time" + + writer "github.com/ipfs/go-log/writer" + + opentrace "github.com/opentracing/opentracing-go" + otExt "github.com/opentracing/opentracing-go/ext" +) + +var log = Logger("eventlog") + +// StandardLogger provides API compatibility with standard printf loggers +// eg. go-logging +type StandardLogger interface { + Debug(args ...interface{}) + Debugf(format string, args ...interface{}) + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Info(args ...interface{}) + Infof(format string, args ...interface{}) + Panic(args ...interface{}) + Panicf(format string, args ...interface{}) + Warning(args ...interface{}) + Warningf(format string, args ...interface{}) +} + +// EventLogger extends the StandardLogger interface to allow for log items +// containing structured metadata +type EventLogger interface { + StandardLogger + + // Event merges structured data from the provided inputs into a single + // machine-readable log event. + // + // If the context contains metadata, a copy of this is used as the base + // metadata accumulator. + // + // If one or more loggable objects are provided, these are deep-merged into base blob. + // + // Next, the event name is added to the blob under the key "event". If + // the key "event" already exists, it will be over-written. + // + // Finally the timestamp and package name are added to the accumulator and + // the metadata is logged. + // DEPRECATED + Event(ctx context.Context, event string, m ...Loggable) + + // DEPRECATED + EventBegin(ctx context.Context, event string, m ...Loggable) *EventInProgress + + // Start starts an opentracing span with `name`, using + // any Span found within `ctx` as a ChildOfRef. If no such parent could be + // found, Start creates a root (parentless) Span. + // + // The return value is a context.Context object built around the + // returned Span. + // + // Example usage: + // + // SomeFunction(ctx context.Context, ...) { + // ctx := log.Start(ctx, "SomeFunction") + // defer log.Finish(ctx) + // ... + // } + Start(ctx context.Context, name string) context.Context + + // StartFromParentState starts an opentracing span with `name`, using + // any Span found within `ctx` as a ChildOfRef. If no such parent could be + // found, StartSpanFromParentState creates a root (parentless) Span. + // + // StartFromParentState will attempt to deserialize a SpanContext from `parent`, + // using any Span found within to continue the trace + // + // The return value is a context.Context object built around the + // returned Span. + // + // An error is returned when `parent` cannot be deserialized to a SpanContext + // + // Example usage: + // + // SomeFunction(ctx context.Context, bParent []byte) { + // ctx := log.StartFromParentState(ctx, "SomeFunction", bParent) + // defer log.Finish(ctx) + // ... + // } + StartFromParentState(ctx context.Context, name string, parent []byte) (context.Context, error) + + // Finish completes the span associated with `ctx`. + // + // Finish() must be the last call made to any span instance, and to do + // otherwise leads to undefined behavior. + // Finish will do its best to notify (log) when used in correctly + // .e.g called twice, or called on a spanless `ctx` + Finish(ctx context.Context) + + // FinishWithErr completes the span associated with `ctx` and also calls + // SetErr if `err` is non-nil + // + // FinishWithErr() must be the last call made to any span instance, and to do + // otherwise leads to undefined behavior. + // FinishWithErr will do its best to notify (log) when used in correctly + // .e.g called twice, or called on a spanless `ctx` + FinishWithErr(ctx context.Context, err error) + + // SetErr tags the span associated with `ctx` to reflect an error occured, and + // logs the value `err` under key `error`. + SetErr(ctx context.Context, err error) + + // LogKV records key:value logging data about an event stored in `ctx` + // Eexample: + // log.LogKV( + // "error", "resolve failure", + // "type", "cache timeout", + // "waited.millis", 1500) + LogKV(ctx context.Context, alternatingKeyValues ...interface{}) + + // SetTag tags key `k` and value `v` on the span associated with `ctx` + SetTag(ctx context.Context, key string, value interface{}) + + // SetTags tags keys from the `tags` maps on the span associated with `ctx` + // Example: + // log.SetTags(ctx, map[string]{ + // "type": bizStruct, + // "request": req, + // }) + SetTags(ctx context.Context, tags map[string]interface{}) + + // SerializeContext takes the SpanContext instance stored in `ctx` and Seralizes + // it to bytes. An error is returned if the `ctx` cannot be serialized to + // a bytes array + SerializeContext(ctx context.Context) ([]byte, error) +} + +// Logger retrieves an event logger by name +func Logger(system string) EventLogger { + + // TODO if we would like to adjust log levels at run-time. Store this event + // logger in a map (just like the util.Logger impl) + if len(system) == 0 { + setuplog := getLogger("setup-logger") + setuplog.Warning("Missing name parameter") + system = "undefined" + } + + logger := getLogger(system) + + return &eventLogger{system: system, StandardLogger: logger} +} + +// eventLogger implements the EventLogger and wraps a go-logging Logger +type eventLogger struct { + StandardLogger + + system string + // TODO add log-level +} + +func (el *eventLogger) Start(ctx context.Context, operationName string) context.Context { + span, ctx := opentrace.StartSpanFromContext(ctx, operationName) + span.SetTag("system", el.system) + return ctx +} + +func (el *eventLogger) StartFromParentState(ctx context.Context, operationName string, parent []byte) (context.Context, error) { + sc, err := deserializeContext(parent) + if err != nil { + return nil, err + } + + //TODO RPCServerOption is probably not the best tag, as this is likely from a peer + span, ctx := opentrace.StartSpanFromContext(ctx, operationName, otExt.RPCServerOption(sc)) + span.SetTag("system", el.system) + return ctx, nil +} + +func (el *eventLogger) SerializeContext(ctx context.Context) ([]byte, error) { + gTracer := opentrace.GlobalTracer() + b := make([]byte, 0) + carrier := bytes.NewBuffer(b) + span := opentrace.SpanFromContext(ctx) + if err := gTracer.Inject(span.Context(), opentrace.Binary, carrier); err != nil { + return nil, err + } + return carrier.Bytes(), nil +} + +func (el *eventLogger) LogKV(ctx context.Context, alternatingKeyValues ...interface{}) { + span := opentrace.SpanFromContext(ctx) + if span == nil { + _, file, line, _ := runtime.Caller(1) + log.Errorf("LogKV with no Span in context called on %s:%d", path.Base(file), line) + return + } + span.LogKV(alternatingKeyValues...) +} + +func (el *eventLogger) SetTag(ctx context.Context, k string, v interface{}) { + span := opentrace.SpanFromContext(ctx) + if span == nil { + _, file, line, _ := runtime.Caller(1) + log.Errorf("SetTag with no Span in context called on %s:%d", path.Base(file), line) + return + } + span.SetTag(k, v) +} + +func (el *eventLogger) SetTags(ctx context.Context, tags map[string]interface{}) { + span := opentrace.SpanFromContext(ctx) + if span == nil { + _, file, line, _ := runtime.Caller(1) + log.Errorf("SetTags with no Span in context called on %s:%d", path.Base(file), line) + return + } + for k, v := range tags { + span.SetTag(k, v) + } +} + +func (el *eventLogger) setErr(ctx context.Context, err error, skip int) { + span := opentrace.SpanFromContext(ctx) + if span == nil { + _, file, line, _ := runtime.Caller(skip) + log.Errorf("SetErr with no Span in context called on %s:%d", path.Base(file), line) + return + } + if err == nil { + return + } + + otExt.Error.Set(span, true) + span.LogKV("error", err.Error()) +} + +func (el *eventLogger) SetErr(ctx context.Context, err error) { + el.setErr(ctx, err, 1) +} + +func (el *eventLogger) Finish(ctx context.Context) { + span := opentrace.SpanFromContext(ctx) + if span == nil { + _, file, line, _ := runtime.Caller(1) + log.Errorf("Finish with no Span in context called on %s:%d", path.Base(file), line) + return + } + span.Finish() +} + +func (el *eventLogger) FinishWithErr(ctx context.Context, err error) { + el.setErr(ctx, err, 2) + el.Finish(ctx) +} + +func deserializeContext(bCtx []byte) (opentrace.SpanContext, error) { + gTracer := opentrace.GlobalTracer() + carrier := bytes.NewReader(bCtx) + spanContext, err := gTracer.Extract(opentrace.Binary, carrier) + if err != nil { + log.Warning("Failed to deserialize context %s", err) + return nil, err + } + return spanContext, nil +} + +// DEPRECATED use `Start` +func (el *eventLogger) EventBegin(ctx context.Context, event string, metadata ...Loggable) *EventInProgress { + ctx = el.Start(ctx, event) + + for _, m := range metadata { + for l, v := range m.Loggable() { + el.LogKV(ctx, l, v) + } + } + + eip := &EventInProgress{} + eip.doneFunc = func(additional []Loggable) { + // anything added during the operation + // e.g. deprecated methods event.Append(...) or event.SetError(...) + for _, m := range eip.loggables { + for l, v := range m.Loggable() { + el.LogKV(ctx, l, v) + } + } + el.Finish(ctx) + } + return eip +} + +type activeEventKeyType struct{} + +var activeEventKey = activeEventKeyType{} + +// DEPRECATED use `Start` +func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Loggable) { + + // short circuit if theres nothing to write to + if !writer.WriterGroup.Active() { + return + } + + // Collect loggables for later logging + var loggables []Loggable + + // get any existing metadata from the context + existing, err := MetadataFromContext(ctx) + if err != nil { + existing = Metadata{} + } + loggables = append(loggables, existing) + + for _, datum := range metadata { + loggables = append(loggables, datum) + } + + e := entry{ + loggables: loggables, + system: el.system, + event: event, + } + + accum := Metadata{} + for _, loggable := range e.loggables { + accum = DeepMerge(accum, loggable.Loggable()) + } + + // apply final attributes to reserved keys + // TODO accum["level"] = level + accum["event"] = e.event + accum["system"] = e.system + accum["time"] = FormatRFC3339(time.Now()) + + var buf bytes.Buffer + encoder := json.NewEncoder(&buf) + encoder.SetEscapeHTML(false) + err = encoder.Encode(accum) + if err != nil { + el.Errorf("ERROR FORMATTING EVENT ENTRY: %s", err) + return + } + + writer.WriterGroup.Write(buf.Bytes()) +} + +// DEPRECATED +// EventInProgress represent and event which is happening +type EventInProgress struct { + loggables []Loggable + doneFunc func([]Loggable) +} + +// DEPRECATED use `LogKV` or `SetTag` +// Append adds loggables to be included in the call to Done +func (eip *EventInProgress) Append(l Loggable) { + eip.loggables = append(eip.loggables, l) +} + +// DEPRECATED use `SetError(ctx, error)` +// SetError includes the provided error +func (eip *EventInProgress) SetError(err error) { + eip.loggables = append(eip.loggables, LoggableMap{ + "error": err.Error(), + }) +} + +// DEPRECATED use `Finish` +// Done creates a new Event entry that includes the duration and appended +// loggables. +func (eip *EventInProgress) Done() { + eip.doneFunc(eip.loggables) // create final event with extra data +} + +// DEPRECATED use `FinishWithErr` +// DoneWithErr creates a new Event entry that includes the duration and appended +// loggables. DoneWithErr accepts an error, if err is non-nil, it is set on +// the EventInProgress. Otherwise the logic is the same as the `Done()` method +func (eip *EventInProgress) DoneWithErr(err error) { + if err != nil { + eip.SetError(err) + } + eip.doneFunc(eip.loggables) +} + +// DEPRECATED use `Finish` +// Close is an alias for done +func (eip *EventInProgress) Close() error { + eip.Done() + return nil +} + +// FormatRFC3339 returns the given time in UTC with RFC3999Nano format. +func FormatRFC3339(t time.Time) string { + return t.UTC().Format(time.RFC3339Nano) +} diff --git a/vendor/github.com/ipfs/go-log/loggable.go b/vendor/github.com/ipfs/go-log/loggable.go new file mode 100644 index 00000000..f4edb268 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/loggable.go @@ -0,0 +1,42 @@ +package log + +// Loggable describes objects that can be marshalled into Metadata for logging +type Loggable interface { + Loggable() map[string]interface{} +} + +// LoggableMap is just a generic map keyed by string. It +// implements the Loggable interface. +type LoggableMap map[string]interface{} + +// Loggable implements the Loggable interface for LoggableMap +func (l LoggableMap) Loggable() map[string]interface{} { + return l +} + +// LoggableF converts a func into a Loggable +type LoggableF func() map[string]interface{} + +// Loggable implements the Loggable interface by running +// the LoggableF function. +func (l LoggableF) Loggable() map[string]interface{} { + return l() +} + +// Deferred returns a LoggableF where the execution of the +// provided function is deferred. +func Deferred(key string, f func() string) Loggable { + function := func() map[string]interface{} { + return map[string]interface{}{ + key: f(), + } + } + return LoggableF(function) +} + +// Pair returns a Loggable where key is paired to Loggable. +func Pair(key string, l Loggable) Loggable { + return LoggableMap{ + key: l, + } +} diff --git a/vendor/github.com/ipfs/go-log/metadata.go b/vendor/github.com/ipfs/go-log/metadata.go new file mode 100644 index 00000000..07947b54 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/metadata.go @@ -0,0 +1,77 @@ +package log + +import ( + "encoding/json" + "errors" + "reflect" +) + +// Metadata is a convenience type for generic maps +type Metadata map[string]interface{} + +// DeepMerge merges the second Metadata parameter into the first. +// Nested Metadata are merged recursively. Primitives are over-written. +func DeepMerge(b, a Metadata) Metadata { + out := Metadata{} + for k, v := range b { + out[k] = v + } + for k, v := range a { + + maybe, err := Metadatify(v) + if err != nil { + // if the new value is not meta. just overwrite the dest vaue + if out[k] != nil { + log.Debugf("Overwriting key: %s, old: %s, new: %s", k, out[k], v) + } + out[k] = v + continue + } + + // it is meta. What about dest? + outv, exists := out[k] + if !exists { + // the new value is meta, but there's no dest value. just write it + out[k] = v + continue + } + + outMetadataValue, err := Metadatify(outv) + if err != nil { + // the new value is meta and there's a dest value, but the dest + // value isn't meta. just overwrite + out[k] = v + continue + } + + // both are meta. merge them. + out[k] = DeepMerge(outMetadataValue, maybe) + } + return out +} + +// Loggable implements the Loggable interface. +func (m Metadata) Loggable() map[string]interface{} { + // NB: method defined on value to avoid de-referencing nil Metadata + return m +} + +// JsonString returns the marshaled JSON string for the metadata. +func (m Metadata) JsonString() (string, error) { + // NB: method defined on value + b, err := json.Marshal(m) + return string(b), err +} + +// Metadatify converts maps into Metadata. +func Metadatify(i interface{}) (Metadata, error) { + value := reflect.ValueOf(i) + if value.Kind() == reflect.Map { + m := map[string]interface{}{} + for _, k := range value.MapKeys() { + m[k.String()] = value.MapIndex(k).Interface() + } + return Metadata(m), nil + } + return nil, errors.New("is not a map") +} diff --git a/vendor/github.com/ipfs/go-log/oldlog.go b/vendor/github.com/ipfs/go-log/oldlog.go new file mode 100644 index 00000000..c09ec849 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/oldlog.go @@ -0,0 +1,177 @@ +package log + +import ( + "errors" + "fmt" + "os" + "sync" + + tracer "github.com/ipfs/go-log/tracer" + lwriter "github.com/ipfs/go-log/writer" + + colorable "github.com/mattn/go-colorable" + opentrace "github.com/opentracing/opentracing-go" + logging "github.com/whyrusleeping/go-logging" +) + +func init() { + SetupLogging() +} + +var ansiGray = "\033[0;37m" +var ansiBlue = "\033[0;34m" + +// LogFormats defines formats for logging (i.e. "color") +var LogFormats = map[string]string{ + "nocolor": "%{time:2006-01-02 15:04:05.000000} %{level} %{module} %{shortfile}: %{message}", + "color": ansiGray + "%{time:15:04:05.000} %{color}%{level:5.5s} " + ansiBlue + + "%{module:10.10s}: %{color:reset}%{message} " + ansiGray + "%{shortfile}%{color:reset}", +} + +var defaultLogFormat = "color" + +// Logging environment variables +const ( + // TODO these env names should be more general, IPFS is not the only project to + // use go-log + envLogging = "IPFS_LOGGING" + envLoggingFmt = "IPFS_LOGGING_FMT" + + envLoggingFile = "GOLOG_FILE" // /path/to/file + envTracingFile = "GOLOG_TRACING_FILE" // /path/to/file +) + +// ErrNoSuchLogger is returned when the util pkg is asked for a non existant logger +var ErrNoSuchLogger = errors.New("Error: No such logger") + +// loggers is the set of loggers in the system +var loggerMutex sync.RWMutex +var loggers = map[string]*logging.Logger{} + +// SetupLogging will initialize the logger backend and set the flags. +// TODO calling this in `init` pushes all configuration to env variables +// - move it out of `init`? then we need to change all the code (js-ipfs, go-ipfs) to call this explicitly +// - have it look for a config file? need to define what that is +func SetupLogging() { + + // colorful or plain + lfmt := LogFormats[os.Getenv(envLoggingFmt)] + if lfmt == "" { + lfmt = LogFormats[defaultLogFormat] + } + + // check if we log to a file + var lgbe []logging.Backend + if logfp := os.Getenv(envLoggingFile); len(logfp) > 0 { + f, err := os.Create(logfp) + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR go-log: %s: failed to set logging file backend\n", err) + } else { + lgbe = append(lgbe, logging.NewLogBackend(f, "", 0)) + } + } + + // logs written to stderr + lgbe = append(lgbe, logging.NewLogBackend(colorable.NewColorableStderr(), "", 0)) + + // set the backend(s) + logging.SetBackend(lgbe...) + logging.SetFormatter(logging.MustStringFormatter(lfmt)) + + lvl := logging.ERROR + + if logenv := os.Getenv(envLogging); logenv != "" { + var err error + lvl, err = logging.LogLevel(logenv) + if err != nil { + fmt.Println("error setting log levels", err) + } + } + + // TracerPlugins are instantiated after this, so use loggable tracer + // by default, if a TracerPlugin is added it will override this + lgblRecorder := tracer.NewLoggableRecorder() + lgblTracer := tracer.New(lgblRecorder) + opentrace.SetGlobalTracer(lgblTracer) + + SetAllLoggers(lvl) + + if tracingfp := os.Getenv(envTracingFile); len(tracingfp) > 0 { + f, err := os.Create(tracingfp) + if err != nil { + log.Error("failed to create tracing file: %s", tracingfp) + } else { + lwriter.WriterGroup.AddWriter(f) + } + } +} + +// SetDebugLogging calls SetAllLoggers with logging.DEBUG +func SetDebugLogging() { + SetAllLoggers(logging.DEBUG) +} + +// SetAllLoggers changes the logging.Level of all loggers to lvl +func SetAllLoggers(lvl logging.Level) { + logging.SetLevel(lvl, "") + + loggerMutex.RLock() + defer loggerMutex.RUnlock() + + for n := range loggers { + logging.SetLevel(lvl, n) + } +} + +// SetLogLevel changes the log level of a specific subsystem +// name=="*" changes all subsystems +func SetLogLevel(name, level string) error { + lvl, err := logging.LogLevel(level) + if err != nil { + return err + } + + // wildcard, change all + if name == "*" { + SetAllLoggers(lvl) + return nil + } + + loggerMutex.RLock() + defer loggerMutex.RUnlock() + + // Check if we have a logger by that name + if _, ok := loggers[name]; !ok { + return ErrNoSuchLogger + } + + logging.SetLevel(lvl, name) + + return nil +} + +// GetSubsystems returns a slice containing the +// names of the current loggers +func GetSubsystems() []string { + loggerMutex.RLock() + defer loggerMutex.RUnlock() + subs := make([]string, 0, len(loggers)) + + for k := range loggers { + subs = append(subs, k) + } + return subs +} + +func getLogger(name string) *logging.Logger { + loggerMutex.Lock() + defer loggerMutex.Unlock() + + log := loggers[name] + if log == nil { + log = logging.MustGetLogger(name) + loggers[name] = log + } + + return log +} diff --git a/vendor/github.com/ipfs/go-log/package.json b/vendor/github.com/ipfs/go-log/package.json new file mode 100644 index 00000000..adcf8cd0 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/package.json @@ -0,0 +1,41 @@ +{ + "bugs": { + "url": "https://github.com/ipfs/go-log" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-log" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmcaSwFc5RBg8yCq54QURwEU4nwjfCpjbpmaAm4VbdGLKv", + "name": "go-logging", + "version": "0.0.0" + }, + { + "author": "frist", + "hash": "QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo", + "name": "opentracing-go", + "version": "0.0.3" + }, + { + "author": "mattn", + "hash": "QmTsHcKgTQ4VeYZd8eKYpTXeLW7KNwkRD9wjnrwsV2sToq", + "name": "go-colorable", + "version": "0.2.0" + }, + { + "author": "whyrusleeping", + "hash": "QmddjPSGZb3ieihSseFeCfVRpZzcqczPNsD2DvarSwnjJB", + "name": "gogo-protobuf", + "version": "1.2.1" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-log", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.5.9" +} + diff --git a/vendor/github.com/ipfs/go-log/tracer/LICENSE b/vendor/github.com/ipfs/go-log/tracer/LICENSE new file mode 100644 index 00000000..148509a4 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 The OpenTracing Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-log/tracer/context.go b/vendor/github.com/ipfs/go-log/tracer/context.go new file mode 100644 index 00000000..f1ebf61f --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/context.go @@ -0,0 +1,42 @@ +package loggabletracer + +// SpanContext holds the basic Span metadata. +type SpanContext struct { + // A probabilistically unique identifier for a [multi-span] trace. + TraceID uint64 + + // A probabilistically unique identifier for a span. + SpanID uint64 + + // Whether the trace is sampled. + Sampled bool + + // The span's associated baggage. + Baggage map[string]string // initialized on first use +} + +// ForeachBaggageItem belongs to the opentracing.SpanContext interface +func (c SpanContext) ForeachBaggageItem(handler func(k, v string) bool) { + for k, v := range c.Baggage { + if !handler(k, v) { + break + } + } +} + +// WithBaggageItem returns an entirely new loggabletracer SpanContext with the +// given key:value baggage pair set. +func (c SpanContext) WithBaggageItem(key, val string) SpanContext { + var newBaggage map[string]string + if c.Baggage == nil { + newBaggage = map[string]string{key: val} + } else { + newBaggage = make(map[string]string, len(c.Baggage)+1) + for k, v := range c.Baggage { + newBaggage[k] = v + } + newBaggage[key] = val + } + // Use positional parameters so the compiler will help catch new fields. + return SpanContext{c.TraceID, c.SpanID, c.Sampled, newBaggage} +} diff --git a/vendor/github.com/ipfs/go-log/tracer/debug.go b/vendor/github.com/ipfs/go-log/tracer/debug.go new file mode 100644 index 00000000..8c302b37 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/debug.go @@ -0,0 +1,78 @@ +package loggabletracer + +import ( + "bytes" + "fmt" + "runtime" + "strconv" + "sync" +) + +const debugGoroutineIDTag = "_initial_goroutine" + +type errAssertionFailed struct { + span *spanImpl + msg string +} + +// Error implements the error interface. +func (err *errAssertionFailed) Error() string { + return fmt.Sprintf("%s:\n%+v", err.msg, err.span) +} + +func (s *spanImpl) Lock() { + s.Mutex.Lock() + s.maybeAssertSanityLocked() +} + +func (s *spanImpl) maybeAssertSanityLocked() { + if s.tracer == nil { + s.Mutex.Unlock() + panic(&errAssertionFailed{span: s, msg: "span used after call to Finish()"}) + } + if s.tracer.options.DebugAssertSingleGoroutine { + startID := curGoroutineID() + curID, ok := s.raw.Tags[debugGoroutineIDTag].(uint64) + if !ok { + // This is likely invoked in the context of the SetTag which sets + // debugGoroutineTag. + return + } + if startID != curID { + s.Mutex.Unlock() + panic(&errAssertionFailed{ + span: s, + msg: fmt.Sprintf("span started on goroutine %d, but now running on %d", startID, curID), + }) + } + } +} + +var goroutineSpace = []byte("goroutine ") +var littleBuf = sync.Pool{ + New: func() interface{} { + buf := make([]byte, 64) + return &buf + }, +} + +// Credit to @bradfitz: +// https://github.com/golang/net/blob/master/http2/gotrack.go#L51 +func curGoroutineID() uint64 { + bp := littleBuf.Get().(*[]byte) + defer littleBuf.Put(bp) + b := *bp + b = b[:runtime.Stack(b, false)] + // Parse the 4707 out of "goroutine 4707 [" + b = bytes.TrimPrefix(b, goroutineSpace) + i := bytes.IndexByte(b, ' ') + if i < 0 { + panic(fmt.Sprintf("No space found in %q", b)) + } + b = b[:i] + n, err := strconv.ParseUint(string(b), 10, 64) + if err != nil { + panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err)) + } + return n +} diff --git a/vendor/github.com/ipfs/go-log/tracer/event.go b/vendor/github.com/ipfs/go-log/tracer/event.go new file mode 100644 index 00000000..9dbcb76a --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/event.go @@ -0,0 +1,62 @@ +package loggabletracer + +import "github.com/opentracing/opentracing-go" + +// A SpanEvent is emitted when a mutating command is called on a Span. +type SpanEvent interface{} + +// EventCreate is emitted when a Span is created. +type EventCreate struct{ OperationName string } + +// EventTag is received when SetTag is called. +type EventTag struct { + Key string + Value interface{} +} + +// EventBaggage is received when SetBaggageItem is called. +type EventBaggage struct { + Key, Value string +} + +// EventLogFields is received when LogFields or LogKV is called. +type EventLogFields opentracing.LogRecord + +// EventLog is received when Log (or one of its derivatives) is called. +// +// DEPRECATED +type EventLog opentracing.LogData + +// EventFinish is received when Finish is called. +type EventFinish RawSpan + +func (s *spanImpl) onCreate(opName string) { + if s.event != nil { + s.event(EventCreate{OperationName: opName}) + } +} +func (s *spanImpl) onTag(key string, value interface{}) { + if s.event != nil { + s.event(EventTag{Key: key, Value: value}) + } +} +func (s *spanImpl) onLog(ld opentracing.LogData) { + if s.event != nil { + s.event(EventLog(ld)) + } +} +func (s *spanImpl) onLogFields(lr opentracing.LogRecord) { + if s.event != nil { + s.event(EventLogFields(lr)) + } +} +func (s *spanImpl) onBaggage(key, value string) { + if s.event != nil { + s.event(EventBaggage{Key: key, Value: value}) + } +} +func (s *spanImpl) onFinish(sp RawSpan) { + if s.event != nil { + s.event(EventFinish(sp)) + } +} diff --git a/vendor/github.com/ipfs/go-log/tracer/propagation.go b/vendor/github.com/ipfs/go-log/tracer/propagation.go new file mode 100644 index 00000000..bb210659 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/propagation.go @@ -0,0 +1,61 @@ +package loggabletracer + +import opentracing "github.com/opentracing/opentracing-go" + +type accessorPropagator struct { + tracer *LoggableTracer +} + +// DelegatingCarrier is a flexible carrier interface which can be implemented +// by types which have a means of storing the trace metadata and already know +// how to serialize themselves (for example, protocol buffers). +type DelegatingCarrier interface { + SetState(traceID, spanID uint64, sampled bool) + State() (traceID, spanID uint64, sampled bool) + SetBaggageItem(key, value string) + GetBaggage(func(key, value string)) +} + +func (p *accessorPropagator) Inject( + spanContext opentracing.SpanContext, + carrier interface{}, +) error { + dc, ok := carrier.(DelegatingCarrier) + if !ok || dc == nil { + return opentracing.ErrInvalidCarrier + } + sc, ok := spanContext.(SpanContext) + if !ok { + return opentracing.ErrInvalidSpanContext + } + dc.SetState(sc.TraceID, sc.SpanID, sc.Sampled) + for k, v := range sc.Baggage { + dc.SetBaggageItem(k, v) + } + return nil +} + +func (p *accessorPropagator) Extract( + carrier interface{}, +) (opentracing.SpanContext, error) { + dc, ok := carrier.(DelegatingCarrier) + if !ok || dc == nil { + return nil, opentracing.ErrInvalidCarrier + } + + traceID, spanID, sampled := dc.State() + sc := SpanContext{ + TraceID: traceID, + SpanID: spanID, + Sampled: sampled, + Baggage: nil, + } + dc.GetBaggage(func(k, v string) { + if sc.Baggage == nil { + sc.Baggage = map[string]string{} + } + sc.Baggage[k] = v + }) + + return sc, nil +} diff --git a/vendor/github.com/ipfs/go-log/tracer/propagation_ot.go b/vendor/github.com/ipfs/go-log/tracer/propagation_ot.go new file mode 100644 index 00000000..4a4782ea --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/propagation_ot.go @@ -0,0 +1,180 @@ +package loggabletracer + +import ( + "encoding/binary" + "io" + "strconv" + "strings" + + "github.com/gogo/protobuf/proto" + "github.com/ipfs/go-log/tracer/wire" + opentracing "github.com/opentracing/opentracing-go" +) + +type textMapPropagator struct { + tracer *LoggableTracer +} +type binaryPropagator struct { + tracer *LoggableTracer +} + +const ( + prefixTracerState = "ot-tracer-" + prefixBaggage = "ot-baggage-" + + tracerStateFieldCount = 3 + fieldNameTraceID = prefixTracerState + "traceid" + fieldNameSpanID = prefixTracerState + "spanid" + fieldNameSampled = prefixTracerState + "sampled" +) + +func (p *textMapPropagator) Inject( + spanContext opentracing.SpanContext, + opaqueCarrier interface{}, +) error { + sc, ok := spanContext.(SpanContext) + if !ok { + return opentracing.ErrInvalidSpanContext + } + carrier, ok := opaqueCarrier.(opentracing.TextMapWriter) + if !ok { + return opentracing.ErrInvalidCarrier + } + carrier.Set(fieldNameTraceID, strconv.FormatUint(sc.TraceID, 16)) + carrier.Set(fieldNameSpanID, strconv.FormatUint(sc.SpanID, 16)) + carrier.Set(fieldNameSampled, strconv.FormatBool(sc.Sampled)) + + for k, v := range sc.Baggage { + carrier.Set(prefixBaggage+k, v) + } + return nil +} + +func (p *textMapPropagator) Extract( + opaqueCarrier interface{}, +) (opentracing.SpanContext, error) { + carrier, ok := opaqueCarrier.(opentracing.TextMapReader) + if !ok { + return nil, opentracing.ErrInvalidCarrier + } + requiredFieldCount := 0 + var traceID, spanID uint64 + var sampled bool + var err error + decodedBaggage := make(map[string]string) + err = carrier.ForeachKey(func(k, v string) error { + switch strings.ToLower(k) { + case fieldNameTraceID: + traceID, err = strconv.ParseUint(v, 16, 64) + if err != nil { + return opentracing.ErrSpanContextCorrupted + } + case fieldNameSpanID: + spanID, err = strconv.ParseUint(v, 16, 64) + if err != nil { + return opentracing.ErrSpanContextCorrupted + } + case fieldNameSampled: + sampled, err = strconv.ParseBool(v) + if err != nil { + return opentracing.ErrSpanContextCorrupted + } + default: + lowercaseK := strings.ToLower(k) + if strings.HasPrefix(lowercaseK, prefixBaggage) { + decodedBaggage[strings.TrimPrefix(lowercaseK, prefixBaggage)] = v + } + // Balance off the requiredFieldCount++ just below... + requiredFieldCount-- + } + requiredFieldCount++ + return nil + }) + if err != nil { + return nil, err + } + if requiredFieldCount < tracerStateFieldCount { + if requiredFieldCount == 0 { + return nil, opentracing.ErrSpanContextNotFound + } + return nil, opentracing.ErrSpanContextCorrupted + } + + return SpanContext{ + TraceID: traceID, + SpanID: spanID, + Sampled: sampled, + Baggage: decodedBaggage, + }, nil +} + +func (p *binaryPropagator) Inject( + spanContext opentracing.SpanContext, + opaqueCarrier interface{}, +) error { + sc, ok := spanContext.(SpanContext) + if !ok { + return opentracing.ErrInvalidSpanContext + } + carrier, ok := opaqueCarrier.(io.Writer) + if !ok { + return opentracing.ErrInvalidCarrier + } + + state := wire.TracerState{} + state.TraceId = sc.TraceID + state.SpanId = sc.SpanID + state.Sampled = sc.Sampled + state.BaggageItems = sc.Baggage + + b, err := proto.Marshal(&state) + if err != nil { + return err + } + + // Write the length of the marshalled binary to the writer. + length := uint32(len(b)) + if err := binary.Write(carrier, binary.BigEndian, &length); err != nil { + return err + } + + _, err = carrier.Write(b) + return err +} + +func (p *binaryPropagator) Extract( + opaqueCarrier interface{}, +) (opentracing.SpanContext, error) { + carrier, ok := opaqueCarrier.(io.Reader) + if !ok { + return nil, opentracing.ErrInvalidCarrier + } + + // Read the length of marshalled binary. io.ReadAll isn't that performant + // since it keeps resizing the underlying buffer as it encounters more bytes + // to read. By reading the length, we can allocate a fixed sized buf and read + // the exact amount of bytes into it. + var length uint32 + if err := binary.Read(carrier, binary.BigEndian, &length); err != nil { + return nil, opentracing.ErrSpanContextCorrupted + } + buf := make([]byte, length) + if n, err := carrier.Read(buf); err != nil { + if n > 0 { + return nil, opentracing.ErrSpanContextCorrupted + } + return nil, opentracing.ErrSpanContextNotFound + } + + ctx := wire.TracerState{} + if err := proto.Unmarshal(buf, &ctx); err != nil { + return nil, opentracing.ErrSpanContextCorrupted + } + + return SpanContext{ + TraceID: ctx.TraceId, + SpanID: ctx.SpanId, + Sampled: ctx.Sampled, + Baggage: ctx.BaggageItems, + }, nil +} diff --git a/vendor/github.com/ipfs/go-log/tracer/raw.go b/vendor/github.com/ipfs/go-log/tracer/raw.go new file mode 100644 index 00000000..75945427 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/raw.go @@ -0,0 +1,34 @@ +package loggabletracer + +import ( + "time" + + opentracing "github.com/opentracing/opentracing-go" +) + +// RawSpan encapsulates all state associated with a (finished) Span. +type RawSpan struct { + // Those recording the RawSpan should also record the contents of its + // SpanContext. + Context SpanContext + + // The SpanID of this SpanContext's first intra-trace reference (i.e., + // "parent"), or 0 if there is no parent. + ParentSpanID uint64 + + // The name of the "operation" this span is an instance of. (Called a "span + // name" in some implementations) + Operation string + + // We store rather than so that only + // one of the timestamps has global clock uncertainty issues. + Start time.Time + Duration time.Duration + + // Essentially an extension mechanism. Can be used for many purposes, + // not to be enumerated here. + Tags opentracing.Tags + + // The span's "microlog". + Logs []opentracing.LogRecord +} diff --git a/vendor/github.com/ipfs/go-log/tracer/recorder.go b/vendor/github.com/ipfs/go-log/tracer/recorder.go new file mode 100644 index 00000000..f298d639 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/recorder.go @@ -0,0 +1,103 @@ +package loggabletracer + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "os" + "time" + + writer "github.com/ipfs/go-log/writer" + opentrace "github.com/opentracing/opentracing-go" +) + +// A SpanRecorder handles all of the `RawSpan` data generated via an +// associated `Tracer` (see `NewStandardTracer`) instance. It also names +// the containing process and provides access to a straightforward tag map. +type SpanRecorder interface { + // Implementations must determine whether and where to store `span`. + RecordSpan(span RawSpan) +} + +type LoggableSpanRecorder struct{} + +// NewLoggableRecorder creates new LoggableSpanRecorder +func NewLoggableRecorder() *LoggableSpanRecorder { + return new(LoggableSpanRecorder) +} + +// Loggable Representation of a span, treated as an event log +type LoggableSpan struct { + TraceID uint64 `json:"TraceID"` + SpanID uint64 `json:"SpanID"` + ParentSpanID uint64 `json:"ParentSpanID"` + Operation string `json:"Operation"` + Start time.Time `json:"Start"` + Duration time.Duration `json:"Duration"` + Tags opentrace.Tags `json:"Tags"` + Logs []SpanLog `json:"Logs"` +} + +type SpanLog struct { + Timestamp time.Time `json:"Timestamp"` + Field []SpanField `json:"Fields"` +} + +type SpanField struct { + Key string `json:"Key"` + Value string `json:"Value"` +} + +// RecordSpan implements the respective method of SpanRecorder. +func (r *LoggableSpanRecorder) RecordSpan(span RawSpan) { + // short circuit if theres nothing to write to + if !writer.WriterGroup.Active() { + return + } + + sl := make([]SpanLog, len(span.Logs)) + for i := range span.Logs { + sl[i].Timestamp = span.Logs[i].Timestamp + sf := make([]SpanField, len(span.Logs[i].Fields)) + sl[i].Field = sf + for j := range span.Logs[i].Fields { + sf[j].Key = span.Logs[i].Fields[j].Key() + sf[j].Value = fmt.Sprint(span.Logs[i].Fields[j].Value()) + } + } + + tags := make(map[string]interface{}, len(span.Tags)) + for k, v := range span.Tags { + switch vt := v.(type) { + case bool, string, int, int8, int16, int32, int64, uint, uint8, uint16, uint64: + tags[k] = v + case []byte: + base64.StdEncoding.EncodeToString(vt) + default: + tags[k] = fmt.Sprint(v) + } + } + + spanlog := &LoggableSpan{ + TraceID: span.Context.TraceID, + SpanID: span.Context.SpanID, + ParentSpanID: span.ParentSpanID, + Operation: span.Operation, + Start: span.Start, + Duration: span.Duration, + Tags: tags, + Logs: sl, + } + + var buf bytes.Buffer + encoder := json.NewEncoder(&buf) + encoder.SetEscapeHTML(false) + err := encoder.Encode(spanlog) + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR FORMATTING SPAN ENTRY: %s\n", err) + return + } + + writer.WriterGroup.Write(buf.Bytes()) +} diff --git a/vendor/github.com/ipfs/go-log/tracer/span.go b/vendor/github.com/ipfs/go-log/tracer/span.go new file mode 100644 index 00000000..a23a57c3 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/span.go @@ -0,0 +1,274 @@ +package loggabletracer + +import ( + "sync" + "time" + + opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" +) + +// Span provides access to the essential details of the span, for use +// by loggabletracer consumers. These methods may only be called prior +// to (*opentracing.Span).Finish(). +type Span interface { + opentracing.Span + + // Operation names the work done by this span instance + Operation() string + + // Start indicates when the span began + Start() time.Time +} + +// Implements the `Span` interface. Created via LoggableTracer (see +// `loggabletracer.New()`). +type spanImpl struct { + tracer *LoggableTracer + event func(SpanEvent) + sync.Mutex // protects the fields below + raw RawSpan + // The number of logs dropped because of MaxLogsPerSpan. + numDroppedLogs int +} + +var spanPool = &sync.Pool{New: func() interface{} { + return &spanImpl{} +}} + +func (s *spanImpl) reset() { + s.tracer, s.event = nil, nil + // Note: Would like to do the following, but then the consumer of RawSpan + // (the recorder) needs to make sure that they're not holding on to the + // baggage or logs when they return (i.e. they need to copy if they care): + // + // logs, baggage := s.raw.Logs[:0], s.raw.Baggage + // for k := range baggage { + // delete(baggage, k) + // } + // s.raw.Logs, s.raw.Baggage = logs, baggage + // + // That's likely too much to ask for. But there is some magic we should + // be able to do with `runtime.SetFinalizer` to reclaim that memory into + // a buffer pool when GC considers them unreachable, which should ease + // some of the load. Hard to say how quickly that would be in practice + // though. + s.raw = RawSpan{ + Context: SpanContext{}, + } +} + +func (s *spanImpl) SetOperationName(operationName string) opentracing.Span { + s.Lock() + defer s.Unlock() + s.raw.Operation = operationName + return s +} + +func (s *spanImpl) trim() bool { + return !s.raw.Context.Sampled && s.tracer.options.TrimUnsampledSpans +} + +func (s *spanImpl) SetTag(key string, value interface{}) opentracing.Span { + defer s.onTag(key, value) + s.Lock() + defer s.Unlock() + if key == string(ext.SamplingPriority) { + if v, ok := value.(uint16); ok { + s.raw.Context.Sampled = v != 0 + return s + } + } + if s.trim() { + return s + } + + if s.raw.Tags == nil { + s.raw.Tags = opentracing.Tags{} + } + s.raw.Tags[key] = value + return s +} + +func (s *spanImpl) LogKV(keyValues ...interface{}) { + fields, err := log.InterleavedKVToFields(keyValues...) + if err != nil { + s.LogFields(log.Error(err), log.String("function", "LogKV")) + return + } + s.LogFields(fields...) +} + +func (s *spanImpl) appendLog(lr opentracing.LogRecord) { + maxLogs := s.tracer.options.MaxLogsPerSpan + if maxLogs == 0 || len(s.raw.Logs) < maxLogs { + s.raw.Logs = append(s.raw.Logs, lr) + return + } + + // We have too many logs. We don't touch the first numOld logs; we treat the + // rest as a circular buffer and overwrite the oldest log among those. + numOld := (maxLogs - 1) / 2 + numNew := maxLogs - numOld + s.raw.Logs[numOld+s.numDroppedLogs%numNew] = lr + s.numDroppedLogs++ +} + +func (s *spanImpl) LogFields(fields ...log.Field) { + lr := opentracing.LogRecord{ + Fields: fields, + } + defer s.onLogFields(lr) + s.Lock() + defer s.Unlock() + if s.trim() || s.tracer.options.DropAllLogs { + return + } + if lr.Timestamp.IsZero() { + lr.Timestamp = time.Now() + } + s.appendLog(lr) +} + +func (s *spanImpl) LogEvent(event string) { + s.Log(opentracing.LogData{ + Event: event, + }) +} + +func (s *spanImpl) LogEventWithPayload(event string, payload interface{}) { + s.Log(opentracing.LogData{ + Event: event, + Payload: payload, + }) +} + +func (s *spanImpl) Log(ld opentracing.LogData) { + defer s.onLog(ld) + s.Lock() + defer s.Unlock() + if s.trim() || s.tracer.options.DropAllLogs { + return + } + + if ld.Timestamp.IsZero() { + ld.Timestamp = time.Now() + } + + s.appendLog(ld.ToLogRecord()) +} + +func (s *spanImpl) Finish() { + s.FinishWithOptions(opentracing.FinishOptions{}) +} + +// rotateLogBuffer rotates the records in the buffer: records 0 to pos-1 move at +// the end (i.e. pos circular left shifts). +func rotateLogBuffer(buf []opentracing.LogRecord, pos int) { + // This algorithm is described in: + // http://www.cplusplus.com/reference/algorithm/rotate + for first, middle, next := 0, pos, pos; first != middle; { + buf[first], buf[next] = buf[next], buf[first] + first++ + next++ + if next == len(buf) { + next = middle + } else if first == middle { + middle = next + } + } +} + +func (s *spanImpl) FinishWithOptions(opts opentracing.FinishOptions) { + finishTime := opts.FinishTime + if finishTime.IsZero() { + finishTime = time.Now() + } + duration := finishTime.Sub(s.raw.Start) + + s.Lock() + defer s.Unlock() + + for _, lr := range opts.LogRecords { + s.appendLog(lr) + } + for _, ld := range opts.BulkLogData { + s.appendLog(ld.ToLogRecord()) + } + + if s.numDroppedLogs > 0 { + // We dropped some log events, which means that we used part of Logs as a + // circular buffer (see appendLog). De-circularize it. + numOld := (len(s.raw.Logs) - 1) / 2 + numNew := len(s.raw.Logs) - numOld + rotateLogBuffer(s.raw.Logs[numOld:], s.numDroppedLogs%numNew) + + // Replace the log in the middle (the oldest "new" log) with information + // about the dropped logs. This means that we are effectively dropping one + // more "new" log. + numDropped := s.numDroppedLogs + 1 + s.raw.Logs[numOld] = opentracing.LogRecord{ + // Keep the timestamp of the last dropped event. + Timestamp: s.raw.Logs[numOld].Timestamp, + Fields: []log.Field{ + log.String("event", "dropped Span logs"), + log.Int("dropped_log_count", numDropped), + log.String("component", "loggabletracer"), + }, + } + } + + s.raw.Duration = duration + + s.onFinish(s.raw) + s.tracer.options.Recorder.RecordSpan(s.raw) + + // Last chance to get options before the span is possibly reset. + poolEnabled := s.tracer.options.EnableSpanPool + if s.tracer.options.DebugAssertUseAfterFinish { + // This makes it much more likely to catch a panic on any subsequent + // operation since s.tracer is accessed on every call to `Lock`. + // We don't call `reset()` here to preserve the logs in the Span + // which are printed when the assertion triggers. + s.tracer = nil + } + + if poolEnabled { + spanPool.Put(s) + } +} + +func (s *spanImpl) Tracer() opentracing.Tracer { + return s.tracer +} + +func (s *spanImpl) Context() opentracing.SpanContext { + return s.raw.Context +} + +func (s *spanImpl) SetBaggageItem(key, val string) opentracing.Span { + s.onBaggage(key, val) + if s.trim() { + return s + } + + s.Lock() + defer s.Unlock() + s.raw.Context = s.raw.Context.WithBaggageItem(key, val) + return s +} + +func (s *spanImpl) BaggageItem(key string) string { + s.Lock() + defer s.Unlock() + return s.raw.Context.Baggage[key] +} + +func (s *spanImpl) Operation() string { + return s.raw.Operation +} + +func (s *spanImpl) Start() time.Time { + return s.raw.Start +} diff --git a/vendor/github.com/ipfs/go-log/tracer/tracer.go b/vendor/github.com/ipfs/go-log/tracer/tracer.go new file mode 100644 index 00000000..a6ea3a22 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/tracer.go @@ -0,0 +1,280 @@ +package loggabletracer + +import ( + "time" + + writer "github.com/ipfs/go-log/writer" + opentracing "github.com/opentracing/opentracing-go" +) + +// Tracer extends the opentracing.Tracer interface with methods to +// probe implementation state, for use by loggabletracer consumers. +type Tracer interface { + opentracing.Tracer + + // Options gets the Options used in New() or NewWithOptions(). + Options() Options +} + +// Options allows creating a customized Tracer via NewWithOptions. The object +// must not be updated when there is an active tracer using it. +type Options struct { + // ShouldSample is a function which is called when creating a new Span and + // determines whether that Span is sampled. The randomized TraceID is supplied + // to allow deterministic sampling decisions to be made across different nodes. + // For example, + // + // func(traceID uint64) { return traceID % 64 == 0 } + // + // samples every 64th trace on average. + ShouldSample func(traceID uint64) bool + // TrimUnsampledSpans turns potentially expensive operations on unsampled + // Spans into no-ops. More precisely, tags and log events are silently + // discarded. If NewSpanEventListener is set, the callbacks will still fire. + TrimUnsampledSpans bool + // Recorder receives Spans which have been finished. + Recorder SpanRecorder + // NewSpanEventListener can be used to enhance the tracer by effectively + // attaching external code to trace events. See NetTraceIntegrator for a + // practical example, and event.go for the list of possible events. + NewSpanEventListener func() func(SpanEvent) + // DropAllLogs turns log events on all Spans into no-ops. + // If NewSpanEventListener is set, the callbacks will still fire. + DropAllLogs bool + // MaxLogsPerSpan limits the number of Logs in a span (if set to a nonzero + // value). If a span has more logs than this value, logs are dropped as + // necessary (and replaced with a log describing how many were dropped). + // + // About half of the MaxLogPerSpan logs kept are the oldest logs, and about + // half are the newest logs. + // + // If NewSpanEventListener is set, the callbacks will still fire for all log + // events. This value is ignored if DropAllLogs is true. + MaxLogsPerSpan int + // DebugAssertSingleGoroutine internally records the ID of the goroutine + // creating each Span and verifies that no operation is carried out on + // it on a different goroutine. + // Provided strictly for development purposes. + // Passing Spans between goroutine without proper synchronization often + // results in use-after-Finish() errors. For a simple example, consider the + // following pseudocode: + // + // func (s *Server) Handle(req http.Request) error { + // sp := s.StartSpan("server") + // defer sp.Finish() + // wait := s.queueProcessing(opentracing.ContextWithSpan(context.Background(), sp), req) + // select { + // case resp := <-wait: + // return resp.Error + // case <-time.After(10*time.Second): + // sp.LogEvent("timed out waiting for processing") + // return ErrTimedOut + // } + // } + // + // This looks reasonable at first, but a request which spends more than ten + // seconds in the queue is abandoned by the main goroutine and its trace + // finished, leading to use-after-finish when the request is finally + // processed. Note also that even joining on to a finished Span via + // StartSpanWithOptions constitutes an illegal operation. + // + // Code bases which do not require (or decide they do not want) Spans to + // be passed across goroutine boundaries can run with this flag enabled in + // tests to increase their chances of spotting wrong-doers. + DebugAssertSingleGoroutine bool + // DebugAssertUseAfterFinish is provided strictly for development purposes. + // When set, it attempts to exacerbate issues emanating from use of Spans + // after calling Finish by running additional assertions. + DebugAssertUseAfterFinish bool + // EnableSpanPool enables the use of a pool, so that the tracer reuses spans + // after Finish has been called on it. Adds a slight performance gain as it + // reduces allocations. However, if you have any use-after-finish race + // conditions the code may panic. + EnableSpanPool bool +} + +// DefaultOptions returns an Options object with a 1 in 64 sampling rate and +// all options disabled. A Recorder needs to be set manually before using the +// returned object with a Tracer. +func DefaultOptions() Options { + return Options{ + ShouldSample: func(traceID uint64) bool { return traceID%64 == 0 }, + MaxLogsPerSpan: 100, + } +} + +// NewWithOptions creates a customized Tracer. +func NewWithOptions(opts Options) opentracing.Tracer { + rval := &LoggableTracer{options: opts} + rval.accessorPropagator = &accessorPropagator{rval} + return rval +} + +// New creates and returns a standard Tracer which defers completed Spans to +// `recorder`. +// Spans created by this Tracer support the ext.SamplingPriority tag: Setting +// ext.SamplingPriority causes the Span to be Sampled from that point on. +func New(recorder SpanRecorder) opentracing.Tracer { + opts := DefaultOptions() + opts.Recorder = recorder + return NewWithOptions(opts) +} + +// Implements the `Tracer` interface. +type LoggableTracer struct { + options Options + textPropagator *textMapPropagator + binaryPropagator *binaryPropagator + accessorPropagator *accessorPropagator +} + +func (t *LoggableTracer) StartSpan( + operationName string, + opts ...opentracing.StartSpanOption, +) opentracing.Span { + + if !writer.WriterGroup.Active() { + return opentracing.NoopTracer.StartSpan(opentracing.NoopTracer{}, operationName) + } + + sso := opentracing.StartSpanOptions{} + for _, o := range opts { + o.Apply(&sso) + } + return t.StartSpanWithOptions(operationName, sso) +} + +func (t *LoggableTracer) getSpan() *spanImpl { + if t.options.EnableSpanPool { + sp := spanPool.Get().(*spanImpl) + sp.reset() + return sp + } + return &spanImpl{} +} + +func (t *LoggableTracer) StartSpanWithOptions( + operationName string, + opts opentracing.StartSpanOptions, +) opentracing.Span { + if !writer.WriterGroup.Active() { + return opentracing.NoopTracer.StartSpan(opentracing.NoopTracer{}, operationName) + } + // Start time. + startTime := opts.StartTime + if startTime.IsZero() { + startTime = time.Now() + } + + // Tags. + tags := opts.Tags + + // Build the new span. This is the only allocation: We'll return this as + // an opentracing.Span. + sp := t.getSpan() + // Look for a parent in the list of References. + // + // TODO: would be nice if loggabletracer did something with all + // References, not just the first one. +ReferencesLoop: + for _, ref := range opts.References { + switch ref.Type { + case opentracing.ChildOfRef, + opentracing.FollowsFromRef: + + refCtx, ok := ref.ReferencedContext.(SpanContext) + if !ok { + // Could be a noopSpanContext + // Ignore that parent. + continue + } + sp.raw.Context.TraceID = refCtx.TraceID + sp.raw.Context.SpanID = randomID() + sp.raw.Context.Sampled = refCtx.Sampled + sp.raw.ParentSpanID = refCtx.SpanID + + if l := len(refCtx.Baggage); l > 0 { + sp.raw.Context.Baggage = make(map[string]string, l) + for k, v := range refCtx.Baggage { + sp.raw.Context.Baggage[k] = v + } + } + break ReferencesLoop + } + } + if sp.raw.Context.TraceID == 0 { + // No parent Span found; allocate new trace and span ids and determine + // the Sampled status. + sp.raw.Context.TraceID, sp.raw.Context.SpanID = randomID2() + sp.raw.Context.Sampled = t.options.ShouldSample(sp.raw.Context.TraceID) + } + + return t.startSpanInternal( + sp, + operationName, + startTime, + tags, + ) +} + +func (t *LoggableTracer) startSpanInternal( + sp *spanImpl, + operationName string, + startTime time.Time, + tags opentracing.Tags, +) opentracing.Span { + sp.tracer = t + if t.options.NewSpanEventListener != nil { + sp.event = t.options.NewSpanEventListener() + } + sp.raw.Operation = operationName + sp.raw.Start = startTime + sp.raw.Duration = -1 + sp.raw.Tags = tags + if t.options.DebugAssertSingleGoroutine { + sp.SetTag(debugGoroutineIDTag, curGoroutineID()) + } + defer sp.onCreate(operationName) + return sp +} + +type delegatorType struct{} + +// Delegator is the format to use for DelegatingCarrier. +var Delegator delegatorType + +func (t *LoggableTracer) Inject(sc opentracing.SpanContext, format interface{}, carrier interface{}) error { + if !writer.WriterGroup.Active() { + return opentracing.NoopTracer.Inject(opentracing.NoopTracer{}, sc, format, carrier) + } + switch format { + case opentracing.TextMap, opentracing.HTTPHeaders: + return t.textPropagator.Inject(sc, carrier) + case opentracing.Binary: + return t.binaryPropagator.Inject(sc, carrier) + } + if _, ok := format.(delegatorType); ok { + return t.accessorPropagator.Inject(sc, carrier) + } + return opentracing.ErrUnsupportedFormat +} + +func (t *LoggableTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) { + if !writer.WriterGroup.Active() { + return opentracing.NoopTracer.Extract(opentracing.NoopTracer{}, format, carrier) + } + switch format { + case opentracing.TextMap, opentracing.HTTPHeaders: + return t.textPropagator.Extract(carrier) + case opentracing.Binary: + return t.binaryPropagator.Extract(carrier) + } + if _, ok := format.(delegatorType); ok { + return t.accessorPropagator.Extract(carrier) + } + return nil, opentracing.ErrUnsupportedFormat +} + +func (t *LoggableTracer) Options() Options { + return t.options +} diff --git a/vendor/github.com/ipfs/go-log/tracer/util.go b/vendor/github.com/ipfs/go-log/tracer/util.go new file mode 100644 index 00000000..279e2aca --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/util.go @@ -0,0 +1,25 @@ +package loggabletracer + +import ( + "math/rand" + "sync" + "time" +) + +var ( + seededIDGen = rand.New(rand.NewSource(time.Now().UnixNano())) + // The golang rand generators are *not* intrinsically thread-safe. + seededIDLock sync.Mutex +) + +func randomID() uint64 { + seededIDLock.Lock() + defer seededIDLock.Unlock() + return uint64(seededIDGen.Int63()) +} + +func randomID2() (uint64, uint64) { + seededIDLock.Lock() + defer seededIDLock.Unlock() + return uint64(seededIDGen.Int63()), uint64(seededIDGen.Int63()) +} diff --git a/vendor/github.com/ipfs/go-log/tracer/wire/Makefile b/vendor/github.com/ipfs/go-log/tracer/wire/Makefile new file mode 100644 index 00000000..8677a371 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/wire/Makefile @@ -0,0 +1,6 @@ +pbgos := $(patsubst %.proto,%.pb.go,$(wildcard *.proto)) + +all: $(pbgos) + +%.pb.go: %.proto + protoc --gogofaster_out=. --proto_path=$(GOPATH)/src:. $< diff --git a/vendor/github.com/ipfs/go-log/tracer/wire/carrier.go b/vendor/github.com/ipfs/go-log/tracer/wire/carrier.go new file mode 100644 index 00000000..12ec98e9 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/wire/carrier.go @@ -0,0 +1,40 @@ +package wire + +// ProtobufCarrier is a DelegatingCarrier that uses protocol buffers as the +// the underlying datastructure. The reason for implementing DelagatingCarrier +// is to allow for end users to serialize the underlying protocol buffers using +// jsonpb or any other serialization forms they want. +type ProtobufCarrier TracerState + +// SetState set's the tracer state. +func (p *ProtobufCarrier) SetState(traceID, spanID uint64, sampled bool) { + p.TraceId = traceID + p.SpanId = spanID + p.Sampled = sampled +} + +// State returns the tracer state. +func (p *ProtobufCarrier) State() (traceID, spanID uint64, sampled bool) { + traceID = p.TraceId + spanID = p.SpanId + sampled = p.Sampled + return traceID, spanID, sampled +} + +// SetBaggageItem sets a baggage item. +func (p *ProtobufCarrier) SetBaggageItem(key, value string) { + if p.BaggageItems == nil { + p.BaggageItems = map[string]string{key: value} + return + } + + p.BaggageItems[key] = value +} + +// GetBaggage iterates over each baggage item and executes the callback with +// the key:value pair. +func (p *ProtobufCarrier) GetBaggage(f func(k, v string)) { + for k, v := range p.BaggageItems { + f(k, v) + } +} diff --git a/vendor/github.com/ipfs/go-log/tracer/wire/gen.go b/vendor/github.com/ipfs/go-log/tracer/wire/gen.go new file mode 100644 index 00000000..7d951fa4 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/wire/gen.go @@ -0,0 +1,6 @@ +package wire + +//go:generate protoc --gogofaster_out=$GOPATH/src/github.com/ipfs/go-log/tracer/wire wire.proto + +// Run `go get github.com/gogo/protobuf/protoc-gen-gogofaster` to install the +// gogofaster generator binary. diff --git a/vendor/github.com/ipfs/go-log/tracer/wire/wire.pb.go b/vendor/github.com/ipfs/go-log/tracer/wire/wire.pb.go new file mode 100644 index 00000000..2399892f --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/wire/wire.pb.go @@ -0,0 +1,554 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: wire.proto + +package wire + +import ( + encoding_binary "encoding/binary" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type TracerState struct { + TraceId uint64 `protobuf:"fixed64,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + SpanId uint64 `protobuf:"fixed64,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` + Sampled bool `protobuf:"varint,3,opt,name=sampled,proto3" json:"sampled,omitempty"` + BaggageItems map[string]string `protobuf:"bytes,4,rep,name=baggage_items,json=baggageItems,proto3" json:"baggage_items,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *TracerState) Reset() { *m = TracerState{} } +func (m *TracerState) String() string { return proto.CompactTextString(m) } +func (*TracerState) ProtoMessage() {} +func (*TracerState) Descriptor() ([]byte, []int) { + return fileDescriptor_f2dcdddcdf68d8e0, []int{0} +} +func (m *TracerState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TracerState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TracerState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TracerState) XXX_Merge(src proto.Message) { + xxx_messageInfo_TracerState.Merge(m, src) +} +func (m *TracerState) XXX_Size() int { + return m.Size() +} +func (m *TracerState) XXX_DiscardUnknown() { + xxx_messageInfo_TracerState.DiscardUnknown(m) +} + +var xxx_messageInfo_TracerState proto.InternalMessageInfo + +func (m *TracerState) GetTraceId() uint64 { + if m != nil { + return m.TraceId + } + return 0 +} + +func (m *TracerState) GetSpanId() uint64 { + if m != nil { + return m.SpanId + } + return 0 +} + +func (m *TracerState) GetSampled() bool { + if m != nil { + return m.Sampled + } + return false +} + +func (m *TracerState) GetBaggageItems() map[string]string { + if m != nil { + return m.BaggageItems + } + return nil +} + +func init() { + proto.RegisterType((*TracerState)(nil), "loggabletracer.wire.TracerState") + proto.RegisterMapType((map[string]string)(nil), "loggabletracer.wire.TracerState.BaggageItemsEntry") +} + +func init() { proto.RegisterFile("wire.proto", fileDescriptor_f2dcdddcdf68d8e0) } + +var fileDescriptor_f2dcdddcdf68d8e0 = []byte{ + // 250 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a, + 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xce, 0xc9, 0x4f, 0x4f, 0x4f, 0x4c, 0xca, 0x49, + 0x2d, 0x29, 0x4a, 0x4c, 0x4e, 0x2d, 0xd2, 0x03, 0x49, 0x29, 0x7d, 0x65, 0xe4, 0xe2, 0x0e, 0x01, + 0xf3, 0x83, 0x4b, 0x12, 0x4b, 0x52, 0x85, 0x24, 0xb9, 0x38, 0xc0, 0xd2, 0xf1, 0x99, 0x29, 0x12, + 0x8c, 0x0a, 0x8c, 0x1a, 0x6c, 0x41, 0xec, 0x60, 0xbe, 0x67, 0x8a, 0x90, 0x38, 0x17, 0x7b, 0x71, + 0x41, 0x62, 0x1e, 0x48, 0x86, 0x09, 0x2c, 0xc3, 0x06, 0xe2, 0x7a, 0xa6, 0x08, 0x49, 0x70, 0xb1, + 0x17, 0x27, 0xe6, 0x16, 0xe4, 0xa4, 0xa6, 0x48, 0x30, 0x2b, 0x30, 0x6a, 0x70, 0x04, 0xc1, 0xb8, + 0x42, 0xe1, 0x5c, 0xbc, 0x49, 0x89, 0xe9, 0xe9, 0x89, 0xe9, 0xa9, 0xf1, 0x99, 0x25, 0xa9, 0xb9, + 0xc5, 0x12, 0x2c, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, 0x46, 0x7a, 0x58, 0x9c, 0xa2, 0x87, 0xe4, 0x0c, + 0x3d, 0x27, 0x88, 0x2e, 0x4f, 0x90, 0x26, 0xd7, 0xbc, 0x92, 0xa2, 0xca, 0x20, 0x9e, 0x24, 0x24, + 0x21, 0x29, 0x7b, 0x2e, 0x41, 0x0c, 0x25, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x60, 0x67, + 0x73, 0x06, 0x81, 0x98, 0x42, 0x22, 0x5c, 0xac, 0x65, 0x89, 0x39, 0xa5, 0xa9, 0x60, 0x07, 0x73, + 0x06, 0x41, 0x38, 0x56, 0x4c, 0x16, 0x8c, 0x4e, 0x72, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, + 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, + 0x2c, 0xc7, 0x10, 0xc5, 0x02, 0x72, 0x4c, 0x12, 0x1b, 0x38, 0xcc, 0x8c, 0x01, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xe4, 0x48, 0xf4, 0xf8, 0x41, 0x01, 0x00, 0x00, +} + +func (m *TracerState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TracerState) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TraceId != 0 { + dAtA[i] = 0x9 + i++ + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.TraceId)) + i += 8 + } + if m.SpanId != 0 { + dAtA[i] = 0x11 + i++ + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(m.SpanId)) + i += 8 + } + if m.Sampled { + dAtA[i] = 0x18 + i++ + if m.Sampled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if len(m.BaggageItems) > 0 { + for k, _ := range m.BaggageItems { + dAtA[i] = 0x22 + i++ + v := m.BaggageItems[k] + mapSize := 1 + len(k) + sovWire(uint64(len(k))) + 1 + len(v) + sovWire(uint64(len(v))) + i = encodeVarintWire(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintWire(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintWire(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + return i, nil +} + +func encodeVarintWire(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *TracerState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TraceId != 0 { + n += 9 + } + if m.SpanId != 0 { + n += 9 + } + if m.Sampled { + n += 2 + } + if len(m.BaggageItems) > 0 { + for k, v := range m.BaggageItems { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovWire(uint64(len(k))) + 1 + len(v) + sovWire(uint64(len(v))) + n += mapEntrySize + 1 + sovWire(uint64(mapEntrySize)) + } + } + return n +} + +func sovWire(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozWire(x uint64) (n int) { + return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *TracerState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TracerState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TracerState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field TraceId", wireType) + } + m.TraceId = 0 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + m.TraceId = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field SpanId", wireType) + } + m.SpanId = 0 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + m.SpanId = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sampled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Sampled = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaggageItems", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BaggageItems == nil { + m.BaggageItems = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthWire + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthWire + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthWire + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthWire + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.BaggageItems[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipWire(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthWire + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthWire + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipWire(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthWire + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthWire = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowWire = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-log/tracer/wire/wire.proto b/vendor/github.com/ipfs/go-log/tracer/wire/wire.proto new file mode 100644 index 00000000..496fa198 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/tracer/wire/wire.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package loggabletracer.wire; +option go_package = "wire"; + +message TracerState { + fixed64 trace_id = 1; + fixed64 span_id = 2; + bool sampled = 3; + map baggage_items = 4; +} diff --git a/vendor/github.com/ipfs/go-log/writer/option.go b/vendor/github.com/ipfs/go-log/writer/option.go new file mode 100644 index 00000000..e467fc17 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/writer/option.go @@ -0,0 +1,55 @@ +package log + +import ( + "io" + + logging "github.com/whyrusleeping/go-logging" +) + +// WriterGroup is the global writer group for logs to output to +var WriterGroup = NewMirrorWriter() + +// Option is a generic function +type Option func() + +// Configure applies the provided options sequentially from left to right +func Configure(options ...Option) { + for _, f := range options { + f() + } +} + +// LdJSONFormatter Option formats the event log as line-delimited JSON +var LdJSONFormatter = func() { + logging.SetFormatter(&PoliteJSONFormatter{}) +} + +// TextFormatter Option formats the event log as human-readable plain-text +var TextFormatter = func() { + logging.SetFormatter(logging.DefaultFormatter) +} + +// Output returns an option which sets the the given writer as the new +// logging backend +func Output(w io.Writer) Option { + return func() { + backend := logging.NewLogBackend(w, "", 0) + logging.SetBackend(backend) + // TODO return previous Output option + } +} + +// LevelDebug Option sets the log level to debug +var LevelDebug = func() { + logging.SetLevel(logging.DEBUG, "") +} + +// LevelError Option sets the log level to error +var LevelError = func() { + logging.SetLevel(logging.ERROR, "") +} + +// LevelInfo Option sets the log level to info +var LevelInfo = func() { + logging.SetLevel(logging.INFO, "") +} diff --git a/vendor/github.com/ipfs/go-log/writer/polite_json_formatter.go b/vendor/github.com/ipfs/go-log/writer/polite_json_formatter.go new file mode 100644 index 00000000..c5e620fd --- /dev/null +++ b/vendor/github.com/ipfs/go-log/writer/polite_json_formatter.go @@ -0,0 +1,29 @@ +package log + +import ( + "encoding/json" + "io" + + logging "github.com/whyrusleeping/go-logging" +) + +// PoliteJSONFormatter marshals entries into JSON encoded slices (without +// overwriting user-provided keys). How polite of it! +type PoliteJSONFormatter struct{} + +// Format encodes a logging.Record in JSON and writes it to Writer. +func (f *PoliteJSONFormatter) Format(calldepth int, r *logging.Record, w io.Writer) error { + entry := make(map[string]interface{}) + entry["id"] = r.Id + entry["level"] = r.Level + entry["time"] = r.Time + entry["module"] = r.Module + entry["message"] = r.Message() + err := json.NewEncoder(w).Encode(entry) + if err != nil { + return err + } + + w.Write([]byte{'\n'}) + return nil +} diff --git a/vendor/github.com/ipfs/go-log/writer/writer.go b/vendor/github.com/ipfs/go-log/writer/writer.go new file mode 100644 index 00000000..ec5d7299 --- /dev/null +++ b/vendor/github.com/ipfs/go-log/writer/writer.go @@ -0,0 +1,258 @@ +package log + +import ( + "fmt" + "io" + "sync" + "sync/atomic" +) + +// MaxWriterBuffer specifies how big the writer buffer can get before +// killing the writer. +var MaxWriterBuffer = 512 * 1024 + +// MirrorWriter implements a WriteCloser which syncs incoming bytes to multiple +// [buffered] WriteClosers. They can be added with AddWriter(). +type MirrorWriter struct { + active uint32 + + // channel for incoming writers + writerAdd chan *writerAdd + + // slices of writer/sync-channel pairs + writers []*bufWriter + + // synchronization channel for incoming writes + msgSync chan []byte +} + +type writerSync struct { + w io.WriteCloser + br chan []byte +} + +// NewMirrorWriter initializes and returns a MirrorWriter. +func NewMirrorWriter() *MirrorWriter { + mw := &MirrorWriter{ + msgSync: make(chan []byte, 64), // sufficiently large buffer to avoid callers waiting + writerAdd: make(chan *writerAdd), + } + + go mw.logRoutine() + + return mw +} + +// Write broadcasts the written bytes to all Writers. +func (mw *MirrorWriter) Write(b []byte) (int, error) { + mycopy := make([]byte, len(b)) + copy(mycopy, b) + mw.msgSync <- mycopy + return len(b), nil +} + +// Close closes the MirrorWriter +func (mw *MirrorWriter) Close() error { + // it is up to the caller to ensure that write is not called during or + // after close is called. + close(mw.msgSync) + return nil +} + +func (mw *MirrorWriter) doClose() { + for _, w := range mw.writers { + w.writer.Close() + } +} + +func (mw *MirrorWriter) logRoutine() { + // rebind to avoid races on nilling out struct fields + msgSync := mw.msgSync + writerAdd := mw.writerAdd + + defer mw.doClose() + + for { + select { + case b, ok := <-msgSync: + if !ok { + return + } + + // write to all writers + dropped := mw.broadcastMessage(b) + + // consolidate the slice + if dropped { + mw.clearDeadWriters() + } + case wa := <-writerAdd: + mw.writers = append(mw.writers, newBufWriter(wa.w)) + + atomic.StoreUint32(&mw.active, 1) + close(wa.done) + } + } +} + +// broadcastMessage sends the given message to every writer +// if any writer is killed during the send, 'true' is returned +func (mw *MirrorWriter) broadcastMessage(b []byte) bool { + var dropped bool + for i, w := range mw.writers { + _, err := w.Write(b) + if err != nil { + mw.writers[i] = nil + dropped = true + } + } + return dropped +} + +func (mw *MirrorWriter) clearDeadWriters() { + writers := mw.writers + mw.writers = nil + for _, w := range writers { + if w != nil { + mw.writers = append(mw.writers, w) + } + } + if len(mw.writers) == 0 { + atomic.StoreUint32(&mw.active, 0) + } +} + +type writerAdd struct { + w io.WriteCloser + done chan struct{} +} + +// AddWriter attaches a new WriteCloser to this MirrorWriter. +// The new writer will start getting any bytes written to the mirror. +func (mw *MirrorWriter) AddWriter(w io.WriteCloser) { + wa := &writerAdd{ + w: w, + done: make(chan struct{}), + } + mw.writerAdd <- wa + <-wa.done +} + +// Active returns if there is at least one Writer +// attached to this MirrorWriter +func (mw *MirrorWriter) Active() (active bool) { + return atomic.LoadUint32(&mw.active) == 1 +} + +func newBufWriter(w io.WriteCloser) *bufWriter { + bw := &bufWriter{ + writer: w, + incoming: make(chan []byte, 1), + } + + go bw.loop() + return bw +} + +// writes incoming messages to a buffer and when it fills +// up, writes them to the writer +type bufWriter struct { + writer io.WriteCloser + + incoming chan []byte + + deathLock sync.Mutex + dead bool +} + +var errDeadWriter = fmt.Errorf("writer is dead") + +func (bw *bufWriter) Write(b []byte) (int, error) { + bw.deathLock.Lock() + dead := bw.dead + bw.deathLock.Unlock() + if dead { + if bw.incoming != nil { + close(bw.incoming) + bw.incoming = nil + } + return 0, errDeadWriter + } + + bw.incoming <- b + return len(b), nil +} + +func (bw *bufWriter) die() { + bw.deathLock.Lock() + bw.dead = true + bw.writer.Close() + bw.deathLock.Unlock() +} + +func (bw *bufWriter) loop() { + bufsize := 0 + bufBase := make([][]byte, 0, 16) // some initial memory + buffered := bufBase + nextCh := make(chan []byte) + + var nextMsg []byte + + go func() { + for b := range nextCh { + _, err := bw.writer.Write(b) + if err != nil { + // TODO: need a way to notify there was an error here + // wouldn't want to log here as it could casue an infinite loop + bw.die() + return + } + } + }() + + // collect and buffer messages + incoming := bw.incoming + for { + if nextMsg == nil || nextCh == nil { + // nextCh == nil implies we are 'dead' and draining the incoming channel + // until the caller notices and closes it for us + select { + case b, ok := <-incoming: + if !ok { + return + } + nextMsg = b + } + } + + select { + case b, ok := <-incoming: + if !ok { + return + } + bufsize += len(b) + buffered = append(buffered, b) + if bufsize > MaxWriterBuffer { + // if we have too many messages buffered, kill the writer + bw.die() + if nextCh != nil { + close(nextCh) + } + nextCh = nil + // explicity keep going here to drain incoming + } + case nextCh <- nextMsg: + nextMsg = nil + if len(buffered) > 0 { + nextMsg = buffered[0] + buffered = buffered[1:] + bufsize -= len(nextMsg) + } + + if len(buffered) == 0 { + // reset slice position + buffered = bufBase[:0] + } + } + } +} diff --git a/vendor/github.com/ipfs/go-merkledag/.travis.yml b/vendor/github.com/ipfs/go-merkledag/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-merkledag/LICENSE b/vendor/github.com/ipfs/go-merkledag/LICENSE new file mode 100644 index 00000000..7d5dcac4 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-merkledag/README.md b/vendor/github.com/ipfs/go-merkledag/README.md new file mode 100644 index 00000000..8bf135a4 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/README.md @@ -0,0 +1,36 @@ +go-merkledag +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-merkledag/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-merkledag/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-merkledag.svg?branch=master)](https://travis-ci.org/ipfs/go-merkledag) + +> go-merkledag implements the 'DAGService' interface and adds two ipld node types, Protobuf and Raw + + + +## Table of Contents + +- [TODO](#todo) +- [Contribute](#contribute) +- [License](#license) + +## TODO + +- Pull out dag-pb stuff into go-ipld-pb +- Pull 'raw nodes' out into go-ipld-raw (maybe main one instead) +- Move most other logic to go-ipld +- Make dagservice constructor take a 'blockstore' to avoid the blockservice offline nonsense +- deprecate this package + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-merkledag/coding.go b/vendor/github.com/ipfs/go-merkledag/coding.go new file mode 100644 index 00000000..8b419281 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/coding.go @@ -0,0 +1,139 @@ +package merkledag + +import ( + "fmt" + "sort" + "strings" + + "github.com/ipfs/go-block-format" + + pb "github.com/ipfs/go-merkledag/pb" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// Make sure the user doesn't upgrade this file. +// We need to check *here* as well as inside the `pb` package *just* in case the +// user replaces *all* go files in that package. +const _ = pb.DoNotUpgradeFileEverItWillChangeYourHashes + +// for now, we use a PBNode intermediate thing. +// because native go objects are nice. + +// unmarshal decodes raw data into a *Node instance. +// The conversion uses an intermediate PBNode. +func (n *ProtoNode) unmarshal(encoded []byte) error { + var pbn pb.PBNode + if err := pbn.Unmarshal(encoded); err != nil { + return fmt.Errorf("unmarshal failed. %v", err) + } + + pbnl := pbn.GetLinks() + n.links = make([]*ipld.Link, len(pbnl)) + for i, l := range pbnl { + n.links[i] = &ipld.Link{Name: l.GetName(), Size: l.GetTsize()} + c, err := cid.Cast(l.GetHash()) + if err != nil { + return fmt.Errorf("link hash #%d is not valid multihash. %v", i, err) + } + n.links[i].Cid = c + } + sort.Stable(LinkSlice(n.links)) // keep links sorted + + n.data = pbn.GetData() + n.encoded = encoded + return nil +} + +// Marshal encodes a *Node instance into a new byte slice. +// The conversion uses an intermediate PBNode. +func (n *ProtoNode) Marshal() ([]byte, error) { + pbn := n.getPBNode() + data, err := pbn.Marshal() + if err != nil { + return data, fmt.Errorf("marshal failed. %v", err) + } + return data, nil +} + +func (n *ProtoNode) getPBNode() *pb.PBNode { + pbn := &pb.PBNode{} + if len(n.links) > 0 { + pbn.Links = make([]*pb.PBLink, len(n.links)) + } + + sort.Stable(LinkSlice(n.links)) // keep links sorted + for i, l := range n.links { + pbn.Links[i] = &pb.PBLink{} + pbn.Links[i].Name = &l.Name + pbn.Links[i].Tsize = &l.Size + if l.Cid.Defined() { + pbn.Links[i].Hash = l.Cid.Bytes() + } + } + + if len(n.data) > 0 { + pbn.Data = n.data + } + return pbn +} + +// EncodeProtobuf returns the encoded raw data version of a Node instance. +// It may use a cached encoded version, unless the force flag is given. +func (n *ProtoNode) EncodeProtobuf(force bool) ([]byte, error) { + sort.Stable(LinkSlice(n.links)) // keep links sorted + if n.encoded == nil || force { + n.cached = cid.Undef + var err error + n.encoded, err = n.Marshal() + if err != nil { + return nil, err + } + } + + if !n.cached.Defined() { + c, err := n.CidBuilder().Sum(n.encoded) + if err != nil { + return nil, err + } + + n.cached = c + } + + return n.encoded, nil +} + +// DecodeProtobuf decodes raw data and returns a new Node instance. +func DecodeProtobuf(encoded []byte) (*ProtoNode, error) { + n := new(ProtoNode) + err := n.unmarshal(encoded) + if err != nil { + return nil, fmt.Errorf("incorrectly formatted merkledag node: %s", err) + } + return n, nil +} + +// DecodeProtobufBlock is a block decoder for protobuf IPLD nodes conforming to +// node.DecodeBlockFunc +func DecodeProtobufBlock(b blocks.Block) (ipld.Node, error) { + c := b.Cid() + if c.Type() != cid.DagProtobuf { + return nil, fmt.Errorf("this function can only decode protobuf nodes") + } + + decnd, err := DecodeProtobuf(b.RawData()) + if err != nil { + if strings.Contains(err.Error(), "Unmarshal failed") { + return nil, fmt.Errorf("the block referred to by '%s' was not a valid merkledag node", c) + } + return nil, fmt.Errorf("failed to decode Protocol Buffers: %v", err) + } + + decnd.cached = c + decnd.builder = c.Prefix() + return decnd, nil +} + +// Type assertion +var _ ipld.DecodeBlockFunc = DecodeProtobufBlock diff --git a/vendor/github.com/ipfs/go-merkledag/errservice.go b/vendor/github.com/ipfs/go-merkledag/errservice.go new file mode 100644 index 00000000..f4607615 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/errservice.go @@ -0,0 +1,47 @@ +package merkledag + +import ( + "context" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// ErrorService implements ipld.DAGService, returning 'Err' for every call. +type ErrorService struct { + Err error +} + +var _ ipld.DAGService = (*ErrorService)(nil) + +// Add returns the cs.Err. +func (cs *ErrorService) Add(ctx context.Context, nd ipld.Node) error { + return cs.Err +} + +// AddMany returns the cs.Err. +func (cs *ErrorService) AddMany(ctx context.Context, nds []ipld.Node) error { + return cs.Err +} + +// Get returns the cs.Err. +func (cs *ErrorService) Get(ctx context.Context, c cid.Cid) (ipld.Node, error) { + return nil, cs.Err +} + +// GetMany many returns the cs.Err. +func (cs *ErrorService) GetMany(ctx context.Context, cids []cid.Cid) <-chan *ipld.NodeOption { + ch := make(chan *ipld.NodeOption) + close(ch) + return ch +} + +// Remove returns the cs.Err. +func (cs *ErrorService) Remove(ctx context.Context, c cid.Cid) error { + return cs.Err +} + +// RemoveMany returns the cs.Err. +func (cs *ErrorService) RemoveMany(ctx context.Context, cids []cid.Cid) error { + return cs.Err +} diff --git a/vendor/github.com/ipfs/go-merkledag/go.mod b/vendor/github.com/ipfs/go-merkledag/go.mod new file mode 100644 index 00000000..6747fa35 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/go.mod @@ -0,0 +1,15 @@ +module github.com/ipfs/go-merkledag + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-block-format v0.0.2 + github.com/ipfs/go-blockservice v0.1.0 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs-blockstore v0.0.1 + github.com/ipfs/go-ipfs-exchange-offline v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-ipld-cbor v0.0.2 + github.com/ipfs/go-ipld-format v0.0.2 + github.com/multiformats/go-multihash v0.0.5 +) diff --git a/vendor/github.com/ipfs/go-merkledag/go.sum b/vendor/github.com/ipfs/go-merkledag/go.sum new file mode 100644 index 00000000..196e76bf --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/go.sum @@ -0,0 +1,342 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.1.0 h1:28YsHYw9ut6wootnImPXH0WpnU5Dbo3qm6cvQ6e6wYY= +github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.1.0 h1:dh2i7xjMbCtf0ZSMyQAF2qpV/pEEmM7yVpQ00+gik6U= +github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2 h1:amzFztBQQQ69UA5+f7JRfoXF/z2l//MGfEDHVkS20+s= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= +github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.1.0 h1:bpRbgv76eT4avutNPDFZuCPOQus6qTgurEYxfulgZW4= +github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.0 h1:8VXadcPNni74ODoZ+7326LMAppFYmz1fRQOUuT5iZvQ= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2 h1:86uOwW+O6Uc7NbaK4diuLZo2/Ikvqw2rgyV03VcSbLE= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-testutil v0.1.0 h1:4QhjaWGO89udplblLVpgGDOQjzFlRavZOjuEnz2rLMc= +github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158 h1:v73Zw0Y1htnV0qaOAYSNiuIAviPSBkNtdy1tPi1+zpY= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-merkledag/merkledag.go b/vendor/github.com/ipfs/go-merkledag/merkledag.go new file mode 100644 index 00000000..3153cf41 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/merkledag.go @@ -0,0 +1,478 @@ +// Package merkledag implements the IPFS Merkle DAG data structures. +package merkledag + +import ( + "context" + "fmt" + "sync" + + blocks "github.com/ipfs/go-block-format" + bserv "github.com/ipfs/go-blockservice" + cid "github.com/ipfs/go-cid" + ipldcbor "github.com/ipfs/go-ipld-cbor" + ipld "github.com/ipfs/go-ipld-format" +) + +// TODO: We should move these registrations elsewhere. Really, most of the IPLD +// functionality should go in a `go-ipld` repo but that will take a lot of work +// and design. +func init() { + ipld.Register(cid.DagProtobuf, DecodeProtobufBlock) + ipld.Register(cid.Raw, DecodeRawBlock) + ipld.Register(cid.DagCBOR, ipldcbor.DecodeBlock) +} + +// contextKey is a type to use as value for the ProgressTracker contexts. +type contextKey string + +const progressContextKey contextKey = "progress" + +// NewDAGService constructs a new DAGService (using the default implementation). +// Note that the default implementation is also an ipld.LinkGetter. +func NewDAGService(bs bserv.BlockService) *dagService { + return &dagService{Blocks: bs} +} + +// dagService is an IPFS Merkle DAG service. +// - the root is virtual (like a forest) +// - stores nodes' data in a BlockService +// TODO: should cache Nodes that are in memory, and be +// able to free some of them when vm pressure is high +type dagService struct { + Blocks bserv.BlockService +} + +// Add adds a node to the dagService, storing the block in the BlockService +func (n *dagService) Add(ctx context.Context, nd ipld.Node) error { + if n == nil { // FIXME remove this assertion. protect with constructor invariant + return fmt.Errorf("dagService is nil") + } + + return n.Blocks.AddBlock(nd) +} + +func (n *dagService) AddMany(ctx context.Context, nds []ipld.Node) error { + blks := make([]blocks.Block, len(nds)) + for i, nd := range nds { + blks[i] = nd + } + return n.Blocks.AddBlocks(blks) +} + +// Get retrieves a node from the dagService, fetching the block in the BlockService +func (n *dagService) Get(ctx context.Context, c cid.Cid) (ipld.Node, error) { + if n == nil { + return nil, fmt.Errorf("dagService is nil") + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + b, err := n.Blocks.GetBlock(ctx, c) + if err != nil { + if err == bserv.ErrNotFound { + return nil, ipld.ErrNotFound + } + return nil, fmt.Errorf("failed to get block for %s: %v", c, err) + } + + return ipld.Decode(b) +} + +// GetLinks return the links for the node, the node doesn't necessarily have +// to exist locally. +func (n *dagService) GetLinks(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { + if c.Type() == cid.Raw { + return nil, nil + } + node, err := n.Get(ctx, c) + if err != nil { + return nil, err + } + return node.Links(), nil +} + +func (n *dagService) Remove(ctx context.Context, c cid.Cid) error { + return n.Blocks.DeleteBlock(c) +} + +// RemoveMany removes multiple nodes from the DAG. It will likely be faster than +// removing them individually. +// +// This operation is not atomic. If it returns an error, some nodes may or may +// not have been removed. +func (n *dagService) RemoveMany(ctx context.Context, cids []cid.Cid) error { + // TODO(#4608): make this batch all the way down. + for _, c := range cids { + if err := n.Blocks.DeleteBlock(c); err != nil { + return err + } + } + return nil +} + +// GetLinksDirect creates a function to get the links for a node, from +// the node, bypassing the LinkService. If the node does not exist +// locally (and can not be retrieved) an error will be returned. +func GetLinksDirect(serv ipld.NodeGetter) GetLinks { + return func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { + nd, err := serv.Get(ctx, c) + if err != nil { + if err == bserv.ErrNotFound { + err = ipld.ErrNotFound + } + return nil, err + } + return nd.Links(), nil + } +} + +type sesGetter struct { + bs *bserv.Session +} + +// Get gets a single node from the DAG. +func (sg *sesGetter) Get(ctx context.Context, c cid.Cid) (ipld.Node, error) { + blk, err := sg.bs.GetBlock(ctx, c) + switch err { + case bserv.ErrNotFound: + return nil, ipld.ErrNotFound + default: + return nil, err + case nil: + // noop + } + + return ipld.Decode(blk) +} + +// GetMany gets many nodes at once, batching the request if possible. +func (sg *sesGetter) GetMany(ctx context.Context, keys []cid.Cid) <-chan *ipld.NodeOption { + return getNodesFromBG(ctx, sg.bs, keys) +} + +// Session returns a NodeGetter using a new session for block fetches. +func (n *dagService) Session(ctx context.Context) ipld.NodeGetter { + return &sesGetter{bserv.NewSession(ctx, n.Blocks)} +} + +// FetchGraph fetches all nodes that are children of the given node +func FetchGraph(ctx context.Context, root cid.Cid, serv ipld.DAGService) error { + return FetchGraphWithDepthLimit(ctx, root, -1, serv) +} + +// FetchGraphWithDepthLimit fetches all nodes that are children to the given +// node down to the given depth. maxDetph=0 means "only fetch root", +// maxDepth=1 means "fetch root and its direct children" and so on... +// maxDepth=-1 means unlimited. +func FetchGraphWithDepthLimit(ctx context.Context, root cid.Cid, depthLim int, serv ipld.DAGService) error { + var ng ipld.NodeGetter = serv + ds, ok := serv.(*dagService) + if ok { + ng = &sesGetter{bserv.NewSession(ctx, ds.Blocks)} + } + + set := make(map[string]int) + + // Visit function returns true when: + // * The element is not in the set and we're not over depthLim + // * The element is in the set but recorded depth is deeper + // than currently seen (if we find it higher in the tree we'll need + // to explore deeper than before). + // depthLim = -1 means we only return true if the element is not in the + // set. + visit := func(c cid.Cid, depth int) bool { + key := string(c.Bytes()) + oldDepth, ok := set[key] + + if (ok && depthLim < 0) || (depthLim >= 0 && depth > depthLim) { + return false + } + + if !ok || oldDepth > depth { + set[key] = depth + return true + } + return false + } + + v, _ := ctx.Value(progressContextKey).(*ProgressTracker) + if v == nil { + return EnumerateChildrenAsyncDepth(ctx, GetLinksDirect(ng), root, 0, visit) + } + + visitProgress := func(c cid.Cid, depth int) bool { + if visit(c, depth) { + v.Increment() + return true + } + return false + } + return EnumerateChildrenAsyncDepth(ctx, GetLinksDirect(ng), root, 0, visitProgress) +} + +// GetMany gets many nodes from the DAG at once. +// +// This method may not return all requested nodes (and may or may not return an +// error indicating that it failed to do so. It is up to the caller to verify +// that it received all nodes. +func (n *dagService) GetMany(ctx context.Context, keys []cid.Cid) <-chan *ipld.NodeOption { + return getNodesFromBG(ctx, n.Blocks, keys) +} + +func dedupKeys(keys []cid.Cid) []cid.Cid { + set := cid.NewSet() + for _, c := range keys { + set.Add(c) + } + if set.Len() == len(keys) { + return keys + } + return set.Keys() +} + +func getNodesFromBG(ctx context.Context, bs bserv.BlockGetter, keys []cid.Cid) <-chan *ipld.NodeOption { + keys = dedupKeys(keys) + + out := make(chan *ipld.NodeOption, len(keys)) + blocks := bs.GetBlocks(ctx, keys) + var count int + + go func() { + defer close(out) + for { + select { + case b, ok := <-blocks: + if !ok { + if count != len(keys) { + out <- &ipld.NodeOption{Err: fmt.Errorf("failed to fetch all nodes")} + } + return + } + + nd, err := ipld.Decode(b) + if err != nil { + out <- &ipld.NodeOption{Err: err} + return + } + + out <- &ipld.NodeOption{Node: nd} + count++ + + case <-ctx.Done(): + out <- &ipld.NodeOption{Err: ctx.Err()} + return + } + } + }() + return out +} + +// GetLinks is the type of function passed to the EnumerateChildren function(s) +// for getting the children of an IPLD node. +type GetLinks func(context.Context, cid.Cid) ([]*ipld.Link, error) + +// GetLinksWithDAG returns a GetLinks function that tries to use the given +// NodeGetter as a LinkGetter to get the children of a given IPLD node. This may +// allow us to traverse the DAG without actually loading and parsing the node in +// question (if we already have the links cached). +func GetLinksWithDAG(ng ipld.NodeGetter) GetLinks { + return func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) { + return ipld.GetLinks(ctx, ng, c) + } +} + +// EnumerateChildren will walk the dag below the given root node and add all +// unseen children to the passed in set. +// TODO: parallelize to avoid disk latency perf hits? +func EnumerateChildren(ctx context.Context, getLinks GetLinks, root cid.Cid, visit func(cid.Cid) bool) error { + visitDepth := func(c cid.Cid, depth int) bool { + return visit(c) + } + + return EnumerateChildrenDepth(ctx, getLinks, root, 0, visitDepth) +} + +// EnumerateChildrenDepth walks the dag below the given root and passes the +// current depth to a given visit function. The visit function can be used to +// limit DAG exploration. +func EnumerateChildrenDepth(ctx context.Context, getLinks GetLinks, root cid.Cid, depth int, visit func(cid.Cid, int) bool) error { + links, err := getLinks(ctx, root) + if err != nil { + return err + } + + for _, lnk := range links { + c := lnk.Cid + if visit(c, depth+1) { + err = EnumerateChildrenDepth(ctx, getLinks, c, depth+1, visit) + if err != nil { + return err + } + } + } + return nil +} + +// ProgressTracker is used to show progress when fetching nodes. +type ProgressTracker struct { + Total int + lk sync.Mutex +} + +// DeriveContext returns a new context with value "progress" derived from +// the given one. +func (p *ProgressTracker) DeriveContext(ctx context.Context) context.Context { + return context.WithValue(ctx, progressContextKey, p) +} + +// Increment adds one to the total progress. +func (p *ProgressTracker) Increment() { + p.lk.Lock() + defer p.lk.Unlock() + p.Total++ +} + +// Value returns the current progress. +func (p *ProgressTracker) Value() int { + p.lk.Lock() + defer p.lk.Unlock() + return p.Total +} + +// FetchGraphConcurrency is total number of concurrent fetches that +// 'fetchNodes' will start at a time +var FetchGraphConcurrency = 32 + +// EnumerateChildrenAsync is equivalent to EnumerateChildren *except* that it +// fetches children in parallel. +// +// NOTE: It *does not* make multiple concurrent calls to the passed `visit` function. +func EnumerateChildrenAsync(ctx context.Context, getLinks GetLinks, c cid.Cid, visit func(cid.Cid) bool) error { + visitDepth := func(c cid.Cid, depth int) bool { + return visit(c) + } + + return EnumerateChildrenAsyncDepth(ctx, getLinks, c, 0, visitDepth) +} + +// EnumerateChildrenAsyncDepth is equivalent to EnumerateChildrenDepth *except* +// that it fetches children in parallel (down to a maximum depth in the graph). +// +// NOTE: It *does not* make multiple concurrent calls to the passed `visit` function. +func EnumerateChildrenAsyncDepth(ctx context.Context, getLinks GetLinks, c cid.Cid, startDepth int, visit func(cid.Cid, int) bool) error { + type cidDepth struct { + cid cid.Cid + depth int + } + + type linksDepth struct { + links []*ipld.Link + depth int + } + + feed := make(chan *cidDepth) + out := make(chan *linksDepth) + done := make(chan struct{}) + + var setlk sync.Mutex + var wg sync.WaitGroup + + errChan := make(chan error) + fetchersCtx, cancel := context.WithCancel(ctx) + defer wg.Wait() + defer cancel() + for i := 0; i < FetchGraphConcurrency; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for cdepth := range feed { + ci := cdepth.cid + depth := cdepth.depth + + setlk.Lock() + shouldVisit := visit(ci, depth) + setlk.Unlock() + + if shouldVisit { + links, err := getLinks(ctx, ci) + if err != nil { + select { + case errChan <- err: + case <-fetchersCtx.Done(): + } + return + } + + outLinks := &linksDepth{ + links: links, + depth: depth + 1, + } + + select { + case out <- outLinks: + case <-fetchersCtx.Done(): + return + } + } + select { + case done <- struct{}{}: + case <-fetchersCtx.Done(): + } + } + }() + } + defer close(feed) + + send := feed + var todobuffer []*cidDepth + var inProgress int + + next := &cidDepth{ + cid: c, + depth: startDepth, + } + for { + select { + case send <- next: + inProgress++ + if len(todobuffer) > 0 { + next = todobuffer[0] + todobuffer = todobuffer[1:] + } else { + next = nil + send = nil + } + case <-done: + inProgress-- + if inProgress == 0 && next == nil { + return nil + } + case linksDepth := <-out: + for _, lnk := range linksDepth.links { + cd := &cidDepth{ + cid: lnk.Cid, + depth: linksDepth.depth, + } + + if next == nil { + next = cd + send = feed + } else { + todobuffer = append(todobuffer, cd) + } + } + case err := <-errChan: + return err + + case <-ctx.Done(): + return ctx.Err() + } + } + +} + +var _ ipld.LinkGetter = &dagService{} +var _ ipld.NodeGetter = &dagService{} +var _ ipld.NodeGetter = &sesGetter{} +var _ ipld.DAGService = &dagService{} diff --git a/vendor/github.com/ipfs/go-merkledag/node.go b/vendor/github.com/ipfs/go-merkledag/node.go new file mode 100644 index 00000000..09789040 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/node.go @@ -0,0 +1,384 @@ +package merkledag + +import ( + "context" + "encoding/json" + "fmt" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +// Common errors +var ( + ErrNotProtobuf = fmt.Errorf("expected protobuf dag node") + ErrLinkNotFound = fmt.Errorf("no link by that name") +) + +// ProtoNode represents a node in the IPFS Merkle DAG. +// nodes have opaque data and a set of navigable links. +type ProtoNode struct { + links []*ipld.Link + data []byte + + // cache encoded/marshaled value + encoded []byte + + cached cid.Cid + + // builder specifies cid version and hashing function + builder cid.Builder +} + +var v0CidPrefix = cid.Prefix{ + Codec: cid.DagProtobuf, + MhLength: -1, + MhType: mh.SHA2_256, + Version: 0, +} + +var v1CidPrefix = cid.Prefix{ + Codec: cid.DagProtobuf, + MhLength: -1, + MhType: mh.SHA2_256, + Version: 1, +} + +// V0CidPrefix returns a prefix for CIDv0 +func V0CidPrefix() cid.Prefix { return v0CidPrefix } + +// V1CidPrefix returns a prefix for CIDv1 with the default settings +func V1CidPrefix() cid.Prefix { return v1CidPrefix } + +// PrefixForCidVersion returns the Protobuf prefix for a given CID version +func PrefixForCidVersion(version int) (cid.Prefix, error) { + switch version { + case 0: + return v0CidPrefix, nil + case 1: + return v1CidPrefix, nil + default: + return cid.Prefix{}, fmt.Errorf("unknown CID version: %d", version) + } +} + +// CidBuilder returns the CID Builder for this ProtoNode, it is never nil +func (n *ProtoNode) CidBuilder() cid.Builder { + if n.builder == nil { + n.builder = v0CidPrefix + } + return n.builder +} + +// SetCidBuilder sets the CID builder if it is non nil, if nil then it +// is reset to the default value +func (n *ProtoNode) SetCidBuilder(builder cid.Builder) { + if builder == nil { + n.builder = v0CidPrefix + } else { + n.builder = builder.WithCodec(cid.DagProtobuf) + n.cached = cid.Undef + } +} + +// LinkSlice is a slice of ipld.Links +type LinkSlice []*ipld.Link + +func (ls LinkSlice) Len() int { return len(ls) } +func (ls LinkSlice) Swap(a, b int) { ls[a], ls[b] = ls[b], ls[a] } +func (ls LinkSlice) Less(a, b int) bool { return ls[a].Name < ls[b].Name } + +// NodeWithData builds a new Protonode with the given data. +func NodeWithData(d []byte) *ProtoNode { + return &ProtoNode{data: d} +} + +// AddNodeLink adds a link to another node. +func (n *ProtoNode) AddNodeLink(name string, that ipld.Node) error { + n.encoded = nil + + lnk, err := ipld.MakeLink(that) + if err != nil { + return err + } + + lnk.Name = name + + n.AddRawLink(name, lnk) + + return nil +} + +// AddRawLink adds a copy of a link to this node +func (n *ProtoNode) AddRawLink(name string, l *ipld.Link) error { + n.encoded = nil + n.links = append(n.links, &ipld.Link{ + Name: name, + Size: l.Size, + Cid: l.Cid, + }) + + return nil +} + +// RemoveNodeLink removes a link on this node by the given name. +func (n *ProtoNode) RemoveNodeLink(name string) error { + n.encoded = nil + + ref := n.links[:0] + found := false + + for _, v := range n.links { + if v.Name != name { + ref = append(ref, v) + } else { + found = true + } + } + + if !found { + return ipld.ErrNotFound + } + + n.links = ref + + return nil +} + +// GetNodeLink returns a copy of the link with the given name. +func (n *ProtoNode) GetNodeLink(name string) (*ipld.Link, error) { + for _, l := range n.links { + if l.Name == name { + return &ipld.Link{ + Name: l.Name, + Size: l.Size, + Cid: l.Cid, + }, nil + } + } + return nil, ErrLinkNotFound +} + +// GetLinkedProtoNode returns a copy of the ProtoNode with the given name. +func (n *ProtoNode) GetLinkedProtoNode(ctx context.Context, ds ipld.DAGService, name string) (*ProtoNode, error) { + nd, err := n.GetLinkedNode(ctx, ds, name) + if err != nil { + return nil, err + } + + pbnd, ok := nd.(*ProtoNode) + if !ok { + return nil, ErrNotProtobuf + } + + return pbnd, nil +} + +// GetLinkedNode returns a copy of the IPLD Node with the given name. +func (n *ProtoNode) GetLinkedNode(ctx context.Context, ds ipld.DAGService, name string) (ipld.Node, error) { + lnk, err := n.GetNodeLink(name) + if err != nil { + return nil, err + } + + return lnk.GetNode(ctx, ds) +} + +// Copy returns a copy of the node. +// NOTE: Does not make copies of Node objects in the links. +func (n *ProtoNode) Copy() ipld.Node { + nnode := new(ProtoNode) + if len(n.data) > 0 { + nnode.data = make([]byte, len(n.data)) + copy(nnode.data, n.data) + } + + if len(n.links) > 0 { + nnode.links = make([]*ipld.Link, len(n.links)) + copy(nnode.links, n.links) + } + + nnode.builder = n.builder + + return nnode +} + +// RawData returns the protobuf-encoded version of the node. +func (n *ProtoNode) RawData() []byte { + out, _ := n.EncodeProtobuf(false) + return out +} + +// Data returns the data stored by this node. +func (n *ProtoNode) Data() []byte { + return n.data +} + +// SetData stores data in this nodes. +func (n *ProtoNode) SetData(d []byte) { + n.encoded = nil + n.cached = cid.Undef + n.data = d +} + +// UpdateNodeLink return a copy of the node with the link name set to point to +// that. If a link of the same name existed, it is removed. +func (n *ProtoNode) UpdateNodeLink(name string, that *ProtoNode) (*ProtoNode, error) { + newnode := n.Copy().(*ProtoNode) + _ = newnode.RemoveNodeLink(name) // ignore error + err := newnode.AddNodeLink(name, that) + return newnode, err +} + +// Size returns the total size of the data addressed by node, +// including the total sizes of references. +func (n *ProtoNode) Size() (uint64, error) { + b, err := n.EncodeProtobuf(false) + if err != nil { + return 0, err + } + + s := uint64(len(b)) + for _, l := range n.links { + s += l.Size + } + return s, nil +} + +// Stat returns statistics on the node. +func (n *ProtoNode) Stat() (*ipld.NodeStat, error) { + enc, err := n.EncodeProtobuf(false) + if err != nil { + return nil, err + } + + cumSize, err := n.Size() + if err != nil { + return nil, err + } + + return &ipld.NodeStat{ + Hash: n.Cid().String(), + NumLinks: len(n.links), + BlockSize: len(enc), + LinksSize: len(enc) - len(n.data), // includes framing. + DataSize: len(n.data), + CumulativeSize: int(cumSize), + }, nil +} + +// Loggable implements the ipfs/go-log.Loggable interface. +func (n *ProtoNode) Loggable() map[string]interface{} { + return map[string]interface{}{ + "node": n.String(), + } +} + +// UnmarshalJSON reads the node fields from a JSON-encoded byte slice. +func (n *ProtoNode) UnmarshalJSON(b []byte) error { + s := struct { + Data []byte `json:"data"` + Links []*ipld.Link `json:"links"` + }{} + + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + n.data = s.Data + n.links = s.Links + return nil +} + +// MarshalJSON returns a JSON representation of the node. +func (n *ProtoNode) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{ + "data": n.data, + "links": n.links, + } + + return json.Marshal(out) +} + +// Cid returns the node's Cid, calculated according to its prefix +// and raw data contents. +func (n *ProtoNode) Cid() cid.Cid { + if n.encoded != nil && n.cached.Defined() { + return n.cached + } + + c, err := n.builder.Sum(n.RawData()) + if err != nil { + // programmer error + err = fmt.Errorf("invalid CID of length %d: %x: %v", len(n.RawData()), n.RawData(), err) + panic(err) + } + + n.cached = c + return c +} + +// String prints the node's Cid. +func (n *ProtoNode) String() string { + return n.Cid().String() +} + +// Multihash hashes the encoded data of this node. +func (n *ProtoNode) Multihash() mh.Multihash { + // NOTE: EncodeProtobuf generates the hash and puts it in n.cached. + _, err := n.EncodeProtobuf(false) + if err != nil { + // Note: no possibility exists for an error to be returned through here + panic(err) + } + + return n.cached.Hash() +} + +// Links returns the node links. +func (n *ProtoNode) Links() []*ipld.Link { + return n.links +} + +// SetLinks replaces the node links with the given ones. +func (n *ProtoNode) SetLinks(links []*ipld.Link) { + n.links = links +} + +// Resolve is an alias for ResolveLink. +func (n *ProtoNode) Resolve(path []string) (interface{}, []string, error) { + return n.ResolveLink(path) +} + +// ResolveLink consumes the first element of the path and obtains the link +// corresponding to it from the node. It returns the link +// and the path without the consumed element. +func (n *ProtoNode) ResolveLink(path []string) (*ipld.Link, []string, error) { + if len(path) == 0 { + return nil, nil, fmt.Errorf("end of path, no more links to resolve") + } + + lnk, err := n.GetNodeLink(path[0]) + if err != nil { + return nil, nil, err + } + + return lnk, path[1:], nil +} + +// Tree returns the link names of the ProtoNode. +// ProtoNodes are only ever one path deep, so anything different than an empty +// string for p results in nothing. The depth parameter is ignored. +func (n *ProtoNode) Tree(p string, depth int) []string { + if p != "" { + return nil + } + + out := make([]string, 0, len(n.links)) + for _, lnk := range n.links { + out = append(out, lnk.Name) + } + return out +} diff --git a/vendor/github.com/ipfs/go-merkledag/package.json b/vendor/github.com/ipfs/go-merkledag/package.json new file mode 100644 index 00000000..24801a0a --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/package.json @@ -0,0 +1,66 @@ +{ + "author": "why", + "bugs": { + "url": "https://github.com/ipfs/go-merkledag" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-merkledag" + }, + "gxDependencies": [ + { + "author": "stebalien", + "hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK", + "name": "go-block-format", + "version": "0.2.2" + }, + { + "author": "whyrusleeping", + "hash": "QmVwsD9oGSAKcCoD4BGi3Hx8XRo4jNy6aMzsjDHVTgYv2D", + "name": "go-ipld-cbor", + "version": "1.5.10" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + }, + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + }, + { + "author": "hsanjuan", + "hash": "Qmb9fkAWgcyVRnFdXGqA6jcWGFj6q35oJjwRAYRhfEboGS", + "name": "go-ipfs-exchange-offline", + "version": "0.1.7" + }, + { + "author": "whyrusleeping", + "hash": "QmddjPSGZb3ieihSseFeCfVRpZzcqczPNsD2DvarSwnjJB", + "name": "gogo-protobuf", + "version": "1.2.1" + }, + { + "author": "why", + "hash": "QmTRbLgKn2BKNvr9z5JQ3uZC4FSyLkad9t7qTVPkbH1LRB", + "name": "go-blockservice", + "version": "1.1.31" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-merkledag", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.1.40" +} + diff --git a/vendor/github.com/ipfs/go-merkledag/pb/Rules.mk b/vendor/github.com/ipfs/go-merkledag/pb/Rules.mk new file mode 100644 index 00000000..505f70e7 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/pb/Rules.mk @@ -0,0 +1,8 @@ +include mk/header.mk + +PB_$(d) = $(wildcard $(d)/*.proto) +TGTS_$(d) = $(PB_$(d):.proto=.pb.go) + +#DEPS_GO += $(TGTS_$(d)) + +include mk/footer.mk diff --git a/vendor/github.com/ipfs/go-merkledag/pb/merkledag.pb.go b/vendor/github.com/ipfs/go-merkledag/pb/merkledag.pb.go new file mode 100644 index 00000000..c6fc4360 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/pb/merkledag.pb.go @@ -0,0 +1,1072 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: merkledag.proto + +package merkledag_pb + +import ( + bytes "bytes" + fmt "fmt" + io "io" + math "math" + reflect "reflect" + strings "strings" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +// DoNotUpgradeFileEverItWillChangeYourHashes warns users about not breaking +// their file hashes. +const DoNotUpgradeFileEverItWillChangeYourHashes = ` +This file does not produce canonical protobufs. Unfortunately, if we change it, +we'll change the hashes of the files we produce. + +Do *not regenerate this file. +` + +// 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// An IPFS MerkleDAG Link +type PBLink struct { + // multihash of the target object + Hash []byte `protobuf:"bytes,1,opt,name=Hash" json:"Hash,omitempty"` + // utf string name. should be unique per object + Name *string `protobuf:"bytes,2,opt,name=Name" json:"Name,omitempty"` + // cumulative size of target object + Tsize *uint64 `protobuf:"varint,3,opt,name=Tsize" json:"Tsize,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PBLink) Reset() { *m = PBLink{} } +func (*PBLink) ProtoMessage() {} +func (*PBLink) Descriptor() ([]byte, []int) { + return fileDescriptor_10837cc3557cec00, []int{0} +} +func (m *PBLink) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PBLink) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PBLink.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PBLink) XXX_Merge(src proto.Message) { + xxx_messageInfo_PBLink.Merge(m, src) +} +func (m *PBLink) XXX_Size() int { + return m.Size() +} +func (m *PBLink) XXX_DiscardUnknown() { + xxx_messageInfo_PBLink.DiscardUnknown(m) +} + +var xxx_messageInfo_PBLink proto.InternalMessageInfo + +func (m *PBLink) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *PBLink) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *PBLink) GetTsize() uint64 { + if m != nil && m.Tsize != nil { + return *m.Tsize + } + return 0 +} + +// An IPFS MerkleDAG Node +type PBNode struct { + // refs to other objects + Links []*PBLink `protobuf:"bytes,2,rep,name=Links" json:"Links,omitempty"` + // opaque user data + Data []byte `protobuf:"bytes,1,opt,name=Data" json:"Data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PBNode) Reset() { *m = PBNode{} } +func (*PBNode) ProtoMessage() {} +func (*PBNode) Descriptor() ([]byte, []int) { + return fileDescriptor_10837cc3557cec00, []int{1} +} +func (m *PBNode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PBNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PBNode.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PBNode) XXX_Merge(src proto.Message) { + xxx_messageInfo_PBNode.Merge(m, src) +} +func (m *PBNode) XXX_Size() int { + return m.Size() +} +func (m *PBNode) XXX_DiscardUnknown() { + xxx_messageInfo_PBNode.DiscardUnknown(m) +} + +var xxx_messageInfo_PBNode proto.InternalMessageInfo + +func (m *PBNode) GetLinks() []*PBLink { + if m != nil { + return m.Links + } + return nil +} + +func (m *PBNode) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func init() { + proto.RegisterType((*PBLink)(nil), "merkledag.pb.PBLink") + proto.RegisterType((*PBNode)(nil), "merkledag.pb.PBNode") +} + +func init() { proto.RegisterFile("merkledag.proto", fileDescriptor_10837cc3557cec00) } + +var fileDescriptor_10837cc3557cec00 = []byte{ + // 227 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcf, 0x4d, 0x2d, 0xca, + 0xce, 0x49, 0x4d, 0x49, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x12, 0x48, + 0x92, 0xd2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, + 0xcf, 0xd7, 0x07, 0x2b, 0x4a, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0xa2, 0x59, 0xc9, + 0x8d, 0x8b, 0x2d, 0xc0, 0xc9, 0x27, 0x33, 0x2f, 0x5b, 0x48, 0x88, 0x8b, 0xc5, 0x23, 0xb1, 0x38, + 0x43, 0x82, 0x51, 0x81, 0x51, 0x83, 0x27, 0x08, 0xcc, 0x06, 0x89, 0xf9, 0x25, 0xe6, 0xa6, 0x4a, + 0x30, 0x29, 0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x22, 0x5c, 0xac, 0x21, 0xc5, 0x99, 0x55, + 0xa9, 0x12, 0xcc, 0x0a, 0x8c, 0x1a, 0x2c, 0x41, 0x10, 0x8e, 0x92, 0x07, 0xc8, 0x1c, 0xbf, 0xfc, + 0x94, 0x54, 0x21, 0x2d, 0x2e, 0x56, 0x90, 0x79, 0xc5, 0x12, 0x4c, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, + 0x22, 0x7a, 0xc8, 0xce, 0xd3, 0x83, 0x58, 0x16, 0x04, 0x51, 0x02, 0x32, 0xdf, 0x25, 0xb1, 0x24, + 0x11, 0x66, 0x27, 0x88, 0xed, 0xa4, 0x73, 0xe3, 0xa1, 0x1c, 0xc3, 0x83, 0x87, 0x72, 0x8c, 0x1f, + 0x1e, 0xca, 0x31, 0xfe, 0x78, 0x28, 0xc7, 0xd8, 0xf0, 0x48, 0x8e, 0x71, 0xc5, 0x23, 0x39, 0xc6, + 0x1d, 0x8f, 0xe4, 0x18, 0x0f, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, + 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x56, 0xb5, 0x6e, 0x0e, + 0x01, 0x00, 0x00, +} + +func (this *PBLink) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*PBLink) + if !ok { + that2, ok := that.(PBLink) + if ok { + that1 = &that2 + } else { + return fmt.Errorf("that is not of type *PBLink") + } + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *PBLink but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *PBLink but is not nil && this == nil") + } + if !bytes.Equal(this.Hash, that1.Hash) { + return fmt.Errorf("Hash this(%v) Not Equal that(%v)", this.Hash, that1.Hash) + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name) + } + } else if this.Name != nil { + return fmt.Errorf("this.Name == nil && that.Name != nil") + } else if that1.Name != nil { + return fmt.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name) + } + if this.Tsize != nil && that1.Tsize != nil { + if *this.Tsize != *that1.Tsize { + return fmt.Errorf("Tsize this(%v) Not Equal that(%v)", *this.Tsize, *that1.Tsize) + } + } else if this.Tsize != nil { + return fmt.Errorf("this.Tsize == nil && that.Tsize != nil") + } else if that1.Tsize != nil { + return fmt.Errorf("Tsize this(%v) Not Equal that(%v)", this.Tsize, that1.Tsize) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *PBLink) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PBLink) + if !ok { + that2, ok := that.(PBLink) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.Hash, that1.Hash) { + return false + } + if this.Name != nil && that1.Name != nil { + if *this.Name != *that1.Name { + return false + } + } else if this.Name != nil { + return false + } else if that1.Name != nil { + return false + } + if this.Tsize != nil && that1.Tsize != nil { + if *this.Tsize != *that1.Tsize { + return false + } + } else if this.Tsize != nil { + return false + } else if that1.Tsize != nil { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *PBNode) VerboseEqual(that interface{}) error { + if that == nil { + if this == nil { + return nil + } + return fmt.Errorf("that == nil && this != nil") + } + + that1, ok := that.(*PBNode) + if !ok { + that2, ok := that.(PBNode) + if ok { + that1 = &that2 + } else { + return fmt.Errorf("that is not of type *PBNode") + } + } + if that1 == nil { + if this == nil { + return nil + } + return fmt.Errorf("that is type *PBNode but is nil && this != nil") + } else if this == nil { + return fmt.Errorf("that is type *PBNode but is not nil && this == nil") + } + if len(this.Links) != len(that1.Links) { + return fmt.Errorf("Links this(%v) Not Equal that(%v)", len(this.Links), len(that1.Links)) + } + for i := range this.Links { + if !this.Links[i].Equal(that1.Links[i]) { + return fmt.Errorf("Links this[%v](%v) Not Equal that[%v](%v)", i, this.Links[i], i, that1.Links[i]) + } + } + if !bytes.Equal(this.Data, that1.Data) { + return fmt.Errorf("Data this(%v) Not Equal that(%v)", this.Data, that1.Data) + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return fmt.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized) + } + return nil +} +func (this *PBNode) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PBNode) + if !ok { + that2, ok := that.(PBNode) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Links) != len(that1.Links) { + return false + } + for i := range this.Links { + if !this.Links[i].Equal(that1.Links[i]) { + return false + } + } + if !bytes.Equal(this.Data, that1.Data) { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} +func (this *PBLink) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&merkledag_pb.PBLink{") + if this.Hash != nil { + s = append(s, "Hash: "+valueToGoStringMerkledag(this.Hash, "byte")+",\n") + } + if this.Name != nil { + s = append(s, "Name: "+valueToGoStringMerkledag(this.Name, "string")+",\n") + } + if this.Tsize != nil { + s = append(s, "Tsize: "+valueToGoStringMerkledag(this.Tsize, "uint64")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *PBNode) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&merkledag_pb.PBNode{") + if this.Links != nil { + s = append(s, "Links: "+fmt.Sprintf("%#v", this.Links)+",\n") + } + if this.Data != nil { + s = append(s, "Data: "+valueToGoStringMerkledag(this.Data, "byte")+",\n") + } + if this.XXX_unrecognized != nil { + s = append(s, "XXX_unrecognized:"+fmt.Sprintf("%#v", this.XXX_unrecognized)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringMerkledag(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func (m *PBLink) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PBLink) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Hash != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintMerkledag(dAtA, i, uint64(len(m.Hash))) + i += copy(dAtA[i:], m.Hash) + } + if m.Name != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintMerkledag(dAtA, i, uint64(len(*m.Name))) + i += copy(dAtA[i:], *m.Name) + } + if m.Tsize != nil { + dAtA[i] = 0x18 + i++ + i = encodeVarintMerkledag(dAtA, i, uint64(*m.Tsize)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PBNode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PBNode) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Links) > 0 { + for _, msg := range m.Links { + dAtA[i] = 0x12 + i++ + i = encodeVarintMerkledag(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.Data != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintMerkledag(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintMerkledag(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func NewPopulatedPBLink(r randyMerkledag, easy bool) *PBLink { + this := &PBLink{} + if r.Intn(10) != 0 { + v1 := r.Intn(100) + this.Hash = make([]byte, v1) + for i := 0; i < v1; i++ { + this.Hash[i] = byte(r.Intn(256)) + } + } + if r.Intn(10) != 0 { + v2 := string(randStringMerkledag(r)) + this.Name = &v2 + } + if r.Intn(10) != 0 { + v3 := uint64(uint64(r.Uint32())) + this.Tsize = &v3 + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMerkledag(r, 4) + } + return this +} + +func NewPopulatedPBNode(r randyMerkledag, easy bool) *PBNode { + this := &PBNode{} + if r.Intn(10) != 0 { + v4 := r.Intn(100) + this.Data = make([]byte, v4) + for i := 0; i < v4; i++ { + this.Data[i] = byte(r.Intn(256)) + } + } + if r.Intn(10) != 0 { + v5 := r.Intn(5) + this.Links = make([]*PBLink, v5) + for i := 0; i < v5; i++ { + this.Links[i] = NewPopulatedPBLink(r, easy) + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedMerkledag(r, 3) + } + return this +} + +type randyMerkledag interface { + Float32() float32 + Float64() float64 + Int63() int64 + Int31() int32 + Uint32() uint32 + Intn(n int) int +} + +func randUTF8RuneMerkledag(r randyMerkledag) rune { + ru := r.Intn(62) + if ru < 10 { + return rune(ru + 48) + } else if ru < 36 { + return rune(ru + 55) + } + return rune(ru + 61) +} +func randStringMerkledag(r randyMerkledag) string { + v6 := r.Intn(100) + tmps := make([]rune, v6) + for i := 0; i < v6; i++ { + tmps[i] = randUTF8RuneMerkledag(r) + } + return string(tmps) +} +func randUnrecognizedMerkledag(r randyMerkledag, maxFieldNumber int) (dAtA []byte) { + l := r.Intn(5) + for i := 0; i < l; i++ { + wire := r.Intn(4) + if wire == 3 { + wire = 5 + } + fieldNumber := maxFieldNumber + r.Intn(100) + dAtA = randFieldMerkledag(dAtA, r, fieldNumber, wire) + } + return dAtA +} +func randFieldMerkledag(dAtA []byte, r randyMerkledag, fieldNumber int, wire int) []byte { + key := uint32(fieldNumber)<<3 | uint32(wire) + switch wire { + case 0: + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(key)) + v7 := r.Int63() + if r.Intn(2) == 0 { + v7 *= -1 + } + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(v7)) + case 1: + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(key)) + dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + case 2: + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(key)) + ll := r.Intn(100) + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(ll)) + for j := 0; j < ll; j++ { + dAtA = append(dAtA, byte(r.Intn(256))) + } + default: + dAtA = encodeVarintPopulateMerkledag(dAtA, uint64(key)) + dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) + } + return dAtA +} +func encodeVarintPopulateMerkledag(dAtA []byte, v uint64) []byte { + for v >= 1<<7 { + dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80)) + v >>= 7 + } + dAtA = append(dAtA, uint8(v)) + return dAtA +} +func (m *PBLink) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hash != nil { + l = len(m.Hash) + n += 1 + l + sovMerkledag(uint64(l)) + } + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovMerkledag(uint64(l)) + } + if m.Tsize != nil { + n += 1 + sovMerkledag(uint64(*m.Tsize)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PBNode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovMerkledag(uint64(l)) + } + if len(m.Links) > 0 { + for _, e := range m.Links { + l = e.Size() + n += 1 + l + sovMerkledag(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovMerkledag(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozMerkledag(x uint64) (n int) { + return sovMerkledag(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *PBLink) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PBLink{`, + `Hash:` + valueToStringMerkledag(this.Hash) + `,`, + `Name:` + valueToStringMerkledag(this.Name) + `,`, + `Tsize:` + valueToStringMerkledag(this.Tsize) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *PBNode) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PBNode{`, + `Data:` + valueToStringMerkledag(this.Data) + `,`, + `Links:` + strings.Replace(fmt.Sprintf("%v", this.Links), "PBLink", "PBLink", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringMerkledag(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *PBLink) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PBLink: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PBLink: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMerkledag + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMerkledag + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + 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 ErrInvalidLengthMerkledag + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMerkledag + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Tsize", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Tsize = &v + default: + iNdEx = preIndex + skippy, err := skipMerkledag(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMerkledag + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMerkledag + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PBNode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PBNode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PBNode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthMerkledag + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthMerkledag + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Links", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMerkledag + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMerkledag + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMerkledag + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Links = append(m.Links, &PBLink{}) + if err := m.Links[len(m.Links)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMerkledag(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthMerkledag + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthMerkledag + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMerkledag(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMerkledag + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMerkledag + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMerkledag + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthMerkledag + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthMerkledag + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMerkledag + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipMerkledag(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthMerkledag + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthMerkledag = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMerkledag = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/ipfs/go-merkledag/pb/merkledag.proto b/vendor/github.com/ipfs/go-merkledag/pb/merkledag.proto new file mode 100644 index 00000000..01219590 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/pb/merkledag.proto @@ -0,0 +1,39 @@ +package merkledag.pb; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.gostring_all) = true; +option (gogoproto.equal_all) = true; +option (gogoproto.verbose_equal_all) = true; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = true; +option (gogoproto.populate_all) = true; +option (gogoproto.testgen_all) = true; +option (gogoproto.benchgen_all) = true; +option (gogoproto.marshaler_all) = true; +option (gogoproto.sizer_all) = true; +option (gogoproto.unmarshaler_all) = true; + + +// An IPFS MerkleDAG Link +message PBLink { + + // multihash of the target object + optional bytes Hash = 1; + + // utf string name. should be unique per object + optional string Name = 2; + + // cumulative size of target object + optional uint64 Tsize = 3; +} + +// An IPFS MerkleDAG Node +message PBNode { + + // refs to other objects + repeated PBLink Links = 2; + + // opaque user data + optional bytes Data = 1; +} diff --git a/vendor/github.com/ipfs/go-merkledag/pb/upgrade_check.go b/vendor/github.com/ipfs/go-merkledag/pb/upgrade_check.go new file mode 100644 index 00000000..e5a6473c --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/pb/upgrade_check.go @@ -0,0 +1,5 @@ +package merkledag_pb + +// Make sure the user doesn't upgrade this package! +// This will fail to build if the user does. +const _ = DoNotUpgradeFileEverItWillChangeYourHashes diff --git a/vendor/github.com/ipfs/go-merkledag/raw.go b/vendor/github.com/ipfs/go-merkledag/raw.go new file mode 100644 index 00000000..a0adb4a1 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/raw.go @@ -0,0 +1,103 @@ +package merkledag + +import ( + "encoding/json" + "fmt" + "github.com/ipfs/go-block-format" + + cid "github.com/ipfs/go-cid" + u "github.com/ipfs/go-ipfs-util" + ipld "github.com/ipfs/go-ipld-format" +) + +// RawNode represents a node which only contains data. +type RawNode struct { + blocks.Block +} + +// NewRawNode creates a RawNode using the default sha2-256 hash function. +func NewRawNode(data []byte) *RawNode { + h := u.Hash(data) + c := cid.NewCidV1(cid.Raw, h) + blk, _ := blocks.NewBlockWithCid(data, c) + + return &RawNode{blk} +} + +// DecodeRawBlock is a block decoder for raw IPLD nodes conforming to `node.DecodeBlockFunc`. +func DecodeRawBlock(block blocks.Block) (ipld.Node, error) { + if block.Cid().Type() != cid.Raw { + return nil, fmt.Errorf("raw nodes cannot be decoded from non-raw blocks: %d", block.Cid().Type()) + } + // Once you "share" a block, it should be immutable. Therefore, we can just use this block as-is. + return &RawNode{block}, nil +} + +var _ ipld.DecodeBlockFunc = DecodeRawBlock + +// NewRawNodeWPrefix creates a RawNode using the provided cid builder +func NewRawNodeWPrefix(data []byte, builder cid.Builder) (*RawNode, error) { + builder = builder.WithCodec(cid.Raw) + c, err := builder.Sum(data) + if err != nil { + return nil, err + } + blk, err := blocks.NewBlockWithCid(data, c) + if err != nil { + return nil, err + } + return &RawNode{blk}, nil +} + +// Links returns nil. +func (rn *RawNode) Links() []*ipld.Link { + return nil +} + +// ResolveLink returns an error. +func (rn *RawNode) ResolveLink(path []string) (*ipld.Link, []string, error) { + return nil, nil, ErrLinkNotFound +} + +// Resolve returns an error. +func (rn *RawNode) Resolve(path []string) (interface{}, []string, error) { + return nil, nil, ErrLinkNotFound +} + +// Tree returns nil. +func (rn *RawNode) Tree(p string, depth int) []string { + return nil +} + +// Copy performs a deep copy of this node and returns it as an ipld.Node +func (rn *RawNode) Copy() ipld.Node { + copybuf := make([]byte, len(rn.RawData())) + copy(copybuf, rn.RawData()) + nblk, err := blocks.NewBlockWithCid(rn.RawData(), rn.Cid()) + if err != nil { + // programmer error + panic("failure attempting to clone raw block: " + err.Error()) + } + + return &RawNode{nblk} +} + +// Size returns the size of this node +func (rn *RawNode) Size() (uint64, error) { + return uint64(len(rn.RawData())), nil +} + +// Stat returns some Stats about this node. +func (rn *RawNode) Stat() (*ipld.NodeStat, error) { + return &ipld.NodeStat{ + CumulativeSize: len(rn.RawData()), + DataSize: len(rn.RawData()), + }, nil +} + +// MarshalJSON is required for our "ipfs dag" commands. +func (rn *RawNode) MarshalJSON() ([]byte, error) { + return json.Marshal(string(rn.RawData())) +} + +var _ ipld.Node = (*RawNode)(nil) diff --git a/vendor/github.com/ipfs/go-merkledag/readonly.go b/vendor/github.com/ipfs/go-merkledag/readonly.go new file mode 100644 index 00000000..36242fbe --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/readonly.go @@ -0,0 +1,20 @@ +package merkledag + +import ( + "fmt" + + ipld "github.com/ipfs/go-ipld-format" +) + +// ErrReadOnly is used when a read-only datastructure is written to. +var ErrReadOnly = fmt.Errorf("cannot write to readonly DAGService") + +// NewReadOnlyDagService takes a NodeGetter, and returns a full DAGService +// implementation that returns ErrReadOnly when its 'write' methods are +// invoked. +func NewReadOnlyDagService(ng ipld.NodeGetter) ipld.DAGService { + return &ComboService{ + Read: ng, + Write: &ErrorService{ErrReadOnly}, + } +} diff --git a/vendor/github.com/ipfs/go-merkledag/rwservice.go b/vendor/github.com/ipfs/go-merkledag/rwservice.go new file mode 100644 index 00000000..a916350a --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/rwservice.go @@ -0,0 +1,47 @@ +package merkledag + +import ( + "context" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// ComboService implements ipld.DAGService, using 'Read' for all fetch methods, +// and 'Write' for all methods that add new objects. +type ComboService struct { + Read ipld.NodeGetter + Write ipld.DAGService +} + +var _ ipld.DAGService = (*ComboService)(nil) + +// Add writes a new node using the Write DAGService. +func (cs *ComboService) Add(ctx context.Context, nd ipld.Node) error { + return cs.Write.Add(ctx, nd) +} + +// AddMany adds nodes using the Write DAGService. +func (cs *ComboService) AddMany(ctx context.Context, nds []ipld.Node) error { + return cs.Write.AddMany(ctx, nds) +} + +// Get fetches a node using the Read DAGService. +func (cs *ComboService) Get(ctx context.Context, c cid.Cid) (ipld.Node, error) { + return cs.Read.Get(ctx, c) +} + +// GetMany fetches nodes using the Read DAGService. +func (cs *ComboService) GetMany(ctx context.Context, cids []cid.Cid) <-chan *ipld.NodeOption { + return cs.Read.GetMany(ctx, cids) +} + +// Remove deletes a node using the Write DAGService. +func (cs *ComboService) Remove(ctx context.Context, c cid.Cid) error { + return cs.Write.Remove(ctx, c) +} + +// RemoveMany deletes nodes using the Write DAGService. +func (cs *ComboService) RemoveMany(ctx context.Context, cids []cid.Cid) error { + return cs.Write.RemoveMany(ctx, cids) +} diff --git a/vendor/github.com/ipfs/go-merkledag/session.go b/vendor/github.com/ipfs/go-merkledag/session.go new file mode 100644 index 00000000..c7bbff16 --- /dev/null +++ b/vendor/github.com/ipfs/go-merkledag/session.go @@ -0,0 +1,21 @@ +package merkledag + +import ( + "context" + + ipld "github.com/ipfs/go-ipld-format" +) + +// SessionMaker is an object that can generate a new fetching session. +type SessionMaker interface { + Session(context.Context) ipld.NodeGetter +} + +// NewSession returns a session backed NodeGetter if the given NodeGetter +// implements SessionMaker. +func NewSession(ctx context.Context, g ipld.NodeGetter) ipld.NodeGetter { + if sm, ok := g.(SessionMaker); ok { + return sm.Session(ctx) + } + return g +} diff --git a/vendor/github.com/ipfs/go-metrics-interface/.gitignore b/vendor/github.com/ipfs/go-metrics-interface/.gitignore new file mode 100644 index 00000000..daf913b1 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/ipfs/go-metrics-interface/.travis.yml b/vendor/github.com/ipfs/go-metrics-interface/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-metrics-interface/LICENSE b/vendor/github.com/ipfs/go-metrics-interface/LICENSE new file mode 100644 index 00000000..ff687483 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-metrics-interface/context.go b/vendor/github.com/ipfs/go-metrics-interface/context.go new file mode 100644 index 00000000..8796b8b9 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/context.go @@ -0,0 +1,26 @@ +package metrics + +import "context" + +const CtxScopeKey = "ipfs.metrics.scope" + +func CtxGetScope(ctx context.Context) string { + s := ctx.Value(CtxScopeKey) + if s == nil { + return "" + } + str, ok := s.(string) + if !ok { + return "" + } + return str +} + +func CtxScope(ctx context.Context, scope string) context.Context { + return context.WithValue(ctx, CtxScopeKey, scope) +} + +func CtxSubScope(ctx context.Context, subscope string) context.Context { + curscope := CtxGetScope(ctx) + return CtxScope(ctx, curscope+"."+subscope) +} diff --git a/vendor/github.com/ipfs/go-metrics-interface/ctor.go b/vendor/github.com/ipfs/go-metrics-interface/ctor.go new file mode 100644 index 00000000..aac694e5 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/ctor.go @@ -0,0 +1,43 @@ +package metrics + +import ( + "context" + "errors" +) + +var ErrImplemented = errors.New("there is implemenation already injected") + +var ctorImpl InternalNew = nil + +// name is dot spearated path +// must be uniqe, use system naming, and unit postfix, examples: +// ipfs.blockstore.bloomcache.bloom.miss.total +// ipfs.routing.dht.notresuingstream.total +// +// both arguemnts are obligatory +func New(name, helptext string) Creator { + if ctorImpl == nil { + return &noop{} + } else { + return ctorImpl(name, helptext) + } +} + +func NewCtx(ctx context.Context, name, helptext string) Creator { + return New(CtxGetScope(ctx)+"."+name, helptext) +} + +type InternalNew func(string, string) Creator + +func InjectImpl(newimpl InternalNew) error { + if ctorImpl != nil { + return ErrImplemented + } else { + ctorImpl = newimpl + return nil + } +} + +func Active() bool { + return ctorImpl != nil +} diff --git a/vendor/github.com/ipfs/go-metrics-interface/go.mod b/vendor/github.com/ipfs/go-metrics-interface/go.mod new file mode 100644 index 00000000..57654087 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/go.mod @@ -0,0 +1 @@ +module github.com/ipfs/go-metrics-interface diff --git a/vendor/github.com/ipfs/go-metrics-interface/interface.go b/vendor/github.com/ipfs/go-metrics-interface/interface.go new file mode 100644 index 00000000..f1237593 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/interface.go @@ -0,0 +1,45 @@ +package metrics + +import ( + "time" +) + +// Increment only metric +type Counter interface { + Inc() + Add(float64) // Only positive +} + +// Increse and decrese metric +type Gauge interface { + Set(float64) // Introduced discontinuity + Inc() + Dec() + Add(float64) + Sub(float64) +} + +type Histogram interface { + Observe(float64) // Adds observation to Histogram +} + +type Summary interface { + Observe(float64) // Adds observation to Summary +} + +// Consult http://godoc.org/github.com/prometheus/client_golang/prometheus#SummaryOpts +type SummaryOpts struct { + Objectives map[float64]float64 + MaxAge time.Duration + AgeBuckets uint32 + BufCap uint32 +} + +type Creator interface { + Counter() Counter + Gauge() Gauge + Histogram(buckets []float64) Histogram + + // opts cannot be nil, use empty summary instance + Summary(opts SummaryOpts) Summary +} diff --git a/vendor/github.com/ipfs/go-metrics-interface/noop.go b/vendor/github.com/ipfs/go-metrics-interface/noop.go new file mode 100644 index 00000000..5b59aa83 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/noop.go @@ -0,0 +1,46 @@ +package metrics + +// Also implements the Counter interface +type noop struct{} + +func (g *noop) Set(v float64) { + // Noop +} + +func (g *noop) Inc() { + // Noop +} + +func (g *noop) Dec() { + // Noop +} + +func (g *noop) Add(v float64) { + // Noop +} + +func (g *noop) Sub(v float64) { + // Noop +} + +func (g *noop) Observe(v float64) { + // Noop +} + +// Creator functions + +func (g *noop) Counter() Counter { + return g +} + +func (g *noop) Gauge() Gauge { + return g +} + +func (g *noop) Histogram(buckets []float64) Histogram { + return g +} + +func (g *noop) Summary(opts SummaryOpts) Summary { + return g +} diff --git a/vendor/github.com/ipfs/go-metrics-interface/package.json b/vendor/github.com/ipfs/go-metrics-interface/package.json new file mode 100644 index 00000000..6ba42d76 --- /dev/null +++ b/vendor/github.com/ipfs/go-metrics-interface/package.json @@ -0,0 +1,16 @@ +{ + "author": "ipfs", + "bugs": { + "URL": "https://github.com/ipfs/go-metrics-interface/issues", + "url": "https://github.com/ipfs/go-metrics-interface/issues" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-metrics-interface" + }, + "gxVersion": "0.9.0", + "language": "go", + "license": "MIT", + "name": "go-metrics-interface", + "version": "0.2.0" +} + diff --git a/vendor/github.com/ipfs/go-mfs/.travis.yml b/vendor/github.com/ipfs/go-mfs/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-mfs/CODEOWNERS b/vendor/github.com/ipfs/go-mfs/CODEOWNERS new file mode 100644 index 00000000..ea812704 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/CODEOWNERS @@ -0,0 +1,8 @@ +# Please see https://help.github.com/articles/about-codeowners/ for more information + +# Global owner +* @schomatis + +# Subsystem specific owners + + diff --git a/vendor/github.com/ipfs/go-mfs/LICENSE b/vendor/github.com/ipfs/go-mfs/LICENSE new file mode 100644 index 00000000..e4224df5 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 IPFS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-mfs/Makefile b/vendor/github.com/ipfs/go-mfs/Makefile new file mode 100644 index 00000000..73f2841f --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/Makefile @@ -0,0 +1,18 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish + + diff --git a/vendor/github.com/ipfs/go-mfs/README.md b/vendor/github.com/ipfs/go-mfs/README.md new file mode 100644 index 00000000..4beaa661 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/README.md @@ -0,0 +1,64 @@ +# go-mfs + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/ipfs/go-mfs?status.svg)](https://godoc.org/github.com/ipfs/go-mfs) +[![Build Status](https://travis-ci.org/ipfs/go-mfs.svg?branch=master)](https://travis-ci.org/ipfs/go-mfs) + +> go-mfs implements an in-memory model of a mutable IPFS filesystem. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-mfs` works like a regular Go module: + +``` +> go get github.com/ipfs/go-mfs +``` + +It uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies. + +## Usage + +``` +import "github.com/ipfs/go-mfs" +``` + +Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-mfs) + +## Documentation + +Documentation around the MFS and the Files API in general around IPFS is a work in progress the following links may be of use: + +* [UnixFS](https://docs.ipfs.io/guides/concepts/unixfs/) +* [MFS](https://docs.ipfs.io/guides/concepts/mfs/) +* [General concept document about how are files handled in IPFS (WIP)](https://github.com/ipfs/docs/issues/133) + +## Repository Structure +This repository contains many files, all belonging to the root `mfs` package. + +* `file.go`: MFS `File`. +* `dir.go`: MFS `Directory`. +* `fd.go`: `FileDescriptor` used to operate on `File`s. +* `ops.go`: Functions that do not belong to either `File` nor `Directory` (although they mostly operate on them) that contain common operations to the MFS, e.g., find, move, add a file, make a directory. +* `root.go`: MFS `Root` (a `Directory` with republishing support). +* `repub.go`: `Republisher`. +* `mfs_test.go`: General tests (needs a [revision](https://github.com/ipfs/go-mfs/issues/9)). +* `repub_test.go`: Republisher-specific tests (contains only the `TestRepublisher` function). + +## Contribute + +PRs accepted. + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs, Inc. diff --git a/vendor/github.com/ipfs/go-mfs/dir.go b/vendor/github.com/ipfs/go-mfs/dir.go new file mode 100644 index 00000000..61f85d06 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/dir.go @@ -0,0 +1,450 @@ +package mfs + +import ( + "context" + "errors" + "fmt" + "os" + "path" + "sync" + "time" + + dag "github.com/ipfs/go-merkledag" + ft "github.com/ipfs/go-unixfs" + uio "github.com/ipfs/go-unixfs/io" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +var ErrNotYetImplemented = errors.New("not yet implemented") +var ErrInvalidChild = errors.New("invalid child node") +var ErrDirExists = errors.New("directory already has entry by that name") + +// TODO: There's too much functionality associated with this structure, +// let's organize it (and if possible extract part of it elsewhere) +// and document the main features of `Directory` here. +type Directory struct { + inode + + // Internal cache with added entries to the directory, its cotents + // are synched with the underlying `unixfsDir` node in `sync()`. + entriesCache map[string]FSNode + + lock sync.Mutex + // TODO: What content is being protected here exactly? The entire directory? + + ctx context.Context + + // UnixFS directory implementation used for creating, + // reading and editing directories. + unixfsDir uio.Directory + + modTime time.Time +} + +// NewDirectory constructs a new MFS directory. +// +// You probably don't want to call this directly. Instead, construct a new root +// using NewRoot. +func NewDirectory(ctx context.Context, name string, node ipld.Node, parent parent, dserv ipld.DAGService) (*Directory, error) { + db, err := uio.NewDirectoryFromNode(dserv, node) + if err != nil { + return nil, err + } + + return &Directory{ + inode: inode{ + name: name, + parent: parent, + dagService: dserv, + }, + ctx: ctx, + unixfsDir: db, + entriesCache: make(map[string]FSNode), + modTime: time.Now(), + }, nil +} + +// GetCidBuilder gets the CID builder of the root node +func (d *Directory) GetCidBuilder() cid.Builder { + return d.unixfsDir.GetCidBuilder() +} + +// SetCidBuilder sets the CID builder +func (d *Directory) SetCidBuilder(b cid.Builder) { + d.unixfsDir.SetCidBuilder(b) +} + +// This method implements the `parent` interface. It first does the local +// update of the child entry in the underlying UnixFS directory and saves +// the newly created directory node with the updated entry in the DAG +// service. Then it propagates the update upwards (through this same +// interface) repeating the whole process in the parent. +func (d *Directory) updateChildEntry(c child) error { + newDirNode, err := d.localUpdate(c) + if err != nil { + return err + } + + // Continue to propagate the update process upwards + // (all the way up to the root). + return d.parent.updateChildEntry(child{d.name, newDirNode}) +} + +// This method implements the part of `updateChildEntry` that needs +// to be locked around: in charge of updating the UnixFS layer and +// generating the new node reflecting the update. It also stores the +// new node in the DAG layer. +func (d *Directory) localUpdate(c child) (*dag.ProtoNode, error) { + d.lock.Lock() + defer d.lock.Unlock() + + err := d.updateChild(c) + if err != nil { + return nil, err + } + // TODO: Clearly define how are we propagating changes to lower layers + // like UnixFS. + + nd, err := d.unixfsDir.GetNode() + if err != nil { + return nil, err + } + + pbnd, ok := nd.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + err = d.dagService.Add(d.ctx, nd) + if err != nil { + return nil, err + } + + return pbnd.Copy().(*dag.ProtoNode), nil + // TODO: Why do we need a copy? +} + +// Update child entry in the underlying UnixFS directory. +func (d *Directory) updateChild(c child) error { + err := d.addUnixFSChild(c) + if err != nil { + return err + } + + d.modTime = time.Now() + + return nil +} + +func (d *Directory) Type() NodeType { + return TDir +} + +// childNode returns a FSNode under this directory by the given name if it exists. +// it does *not* check the cached dirs and files +func (d *Directory) childNode(name string) (FSNode, error) { + nd, err := d.childFromDag(name) + if err != nil { + return nil, err + } + + return d.cacheNode(name, nd) +} + +// cacheNode caches a node into d.childDirs or d.files and returns the FSNode. +func (d *Directory) cacheNode(name string, nd ipld.Node) (FSNode, error) { + switch nd := nd.(type) { + case *dag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return nil, err + } + + switch fsn.Type() { + case ft.TDirectory, ft.THAMTShard: + ndir, err := NewDirectory(d.ctx, name, nd, d, d.dagService) + if err != nil { + return nil, err + } + + d.entriesCache[name] = ndir + return ndir, nil + case ft.TFile, ft.TRaw, ft.TSymlink: + nfi, err := NewFile(name, nd, d, d.dagService) + if err != nil { + return nil, err + } + d.entriesCache[name] = nfi + return nfi, nil + case ft.TMetadata: + return nil, ErrNotYetImplemented + default: + return nil, ErrInvalidChild + } + case *dag.RawNode: + nfi, err := NewFile(name, nd, d, d.dagService) + if err != nil { + return nil, err + } + d.entriesCache[name] = nfi + return nfi, nil + default: + return nil, fmt.Errorf("unrecognized node type in cache node") + } +} + +// Child returns the child of this directory by the given name +func (d *Directory) Child(name string) (FSNode, error) { + d.lock.Lock() + defer d.lock.Unlock() + return d.childUnsync(name) +} + +func (d *Directory) Uncache(name string) { + d.lock.Lock() + defer d.lock.Unlock() + delete(d.entriesCache, name) +} + +// childFromDag searches through this directories dag node for a child link +// with the given name +func (d *Directory) childFromDag(name string) (ipld.Node, error) { + return d.unixfsDir.Find(d.ctx, name) +} + +// childUnsync returns the child under this directory by the given name +// without locking, useful for operations which already hold a lock +func (d *Directory) childUnsync(name string) (FSNode, error) { + entry, ok := d.entriesCache[name] + if ok { + return entry, nil + } + + return d.childNode(name) +} + +type NodeListing struct { + Name string + Type int + Size int64 + Hash string +} + +func (d *Directory) ListNames(ctx context.Context) ([]string, error) { + d.lock.Lock() + defer d.lock.Unlock() + + var out []string + err := d.unixfsDir.ForEachLink(ctx, func(l *ipld.Link) error { + out = append(out, l.Name) + return nil + }) + if err != nil { + return nil, err + } + + return out, nil +} + +func (d *Directory) List(ctx context.Context) ([]NodeListing, error) { + var out []NodeListing + err := d.ForEachEntry(ctx, func(nl NodeListing) error { + out = append(out, nl) + return nil + }) + return out, err +} + +func (d *Directory) ForEachEntry(ctx context.Context, f func(NodeListing) error) error { + d.lock.Lock() + defer d.lock.Unlock() + return d.unixfsDir.ForEachLink(ctx, func(l *ipld.Link) error { + c, err := d.childUnsync(l.Name) + if err != nil { + return err + } + + nd, err := c.GetNode() + if err != nil { + return err + } + + child := NodeListing{ + Name: l.Name, + Type: int(c.Type()), + Hash: nd.Cid().String(), + } + + if c, ok := c.(*File); ok { + size, err := c.Size() + if err != nil { + return err + } + child.Size = size + } + + return f(child) + }) +} + +func (d *Directory) Mkdir(name string) (*Directory, error) { + d.lock.Lock() + defer d.lock.Unlock() + + fsn, err := d.childUnsync(name) + if err == nil { + switch fsn := fsn.(type) { + case *Directory: + return fsn, os.ErrExist + case *File: + return nil, os.ErrExist + default: + return nil, fmt.Errorf("unrecognized type: %#v", fsn) + } + } + + ndir := ft.EmptyDirNode() + ndir.SetCidBuilder(d.GetCidBuilder()) + + err = d.dagService.Add(d.ctx, ndir) + if err != nil { + return nil, err + } + + err = d.addUnixFSChild(child{name, ndir}) + if err != nil { + return nil, err + } + + dirobj, err := NewDirectory(d.ctx, name, ndir, d, d.dagService) + if err != nil { + return nil, err + } + + d.entriesCache[name] = dirobj + return dirobj, nil +} + +func (d *Directory) Unlink(name string) error { + d.lock.Lock() + defer d.lock.Unlock() + + delete(d.entriesCache, name) + + return d.unixfsDir.RemoveChild(d.ctx, name) +} + +func (d *Directory) Flush() error { + nd, err := d.GetNode() + if err != nil { + return err + } + + return d.parent.updateChildEntry(child{d.name, nd}) +} + +// AddChild adds the node 'nd' under this directory giving it the name 'name' +func (d *Directory) AddChild(name string, nd ipld.Node) error { + d.lock.Lock() + defer d.lock.Unlock() + + _, err := d.childUnsync(name) + if err == nil { + return ErrDirExists + } + + err = d.dagService.Add(d.ctx, nd) + if err != nil { + return err + } + + err = d.addUnixFSChild(child{name, nd}) + if err != nil { + return err + } + + d.modTime = time.Now() + return nil +} + +// addUnixFSChild adds a child to the inner UnixFS directory +// and transitions to a HAMT implementation if needed. +func (d *Directory) addUnixFSChild(c child) error { + if uio.UseHAMTSharding { + // If the directory HAMT implementation is being used and this + // directory is actually a basic implementation switch it to HAMT. + if basicDir, ok := d.unixfsDir.(*uio.BasicDirectory); ok { + hamtDir, err := basicDir.SwitchToSharding(d.ctx) + if err != nil { + return err + } + d.unixfsDir = hamtDir + } + } + + err := d.unixfsDir.AddChild(d.ctx, c.Name, c.Node) + if err != nil { + return err + } + + return nil +} + +func (d *Directory) sync() error { + for name, entry := range d.entriesCache { + nd, err := entry.GetNode() + if err != nil { + return err + } + + err = d.updateChild(child{name, nd}) + if err != nil { + return err + } + } + + // TODO: Should we clean the cache here? + + return nil +} + +func (d *Directory) Path() string { + cur := d + var out string + for cur != nil { + switch parent := cur.parent.(type) { + case *Directory: + out = path.Join(cur.name, out) + cur = parent + case *Root: + return "/" + out + default: + panic("directory parent neither a directory nor a root") + } + } + return out +} + +func (d *Directory) GetNode() (ipld.Node, error) { + d.lock.Lock() + defer d.lock.Unlock() + + err := d.sync() + if err != nil { + return nil, err + } + + nd, err := d.unixfsDir.GetNode() + if err != nil { + return nil, err + } + + err = d.dagService.Add(d.ctx, nd) + if err != nil { + return nil, err + } + + return nd.Copy(), err +} diff --git a/vendor/github.com/ipfs/go-mfs/fd.go b/vendor/github.com/ipfs/go-mfs/fd.go new file mode 100644 index 00000000..77a82d69 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/fd.go @@ -0,0 +1,197 @@ +package mfs + +import ( + "fmt" + "io" + + mod "github.com/ipfs/go-unixfs/mod" + + context "context" + + ipld "github.com/ipfs/go-ipld-format" +) + +type state uint8 + +const ( + stateCreated state = iota + stateFlushed + stateDirty + stateClosed +) + +// One `File` can have many `FileDescriptor`s associated to it +// (only one if it's RW, many if they are RO, see `File.desclock`). +// A `FileDescriptor` contains the "view" of the file (through an +// instance of a `DagModifier`), that's why it (and not the `File`) +// has the responsibility to `Flush` (which crystallizes that view +// in the `File`'s `Node`). +type FileDescriptor interface { + io.Reader + CtxReadFull(context.Context, []byte) (int, error) + + io.Writer + io.WriterAt + + io.Closer + io.Seeker + + Truncate(int64) error + Size() (int64, error) + Flush() error +} + +type fileDescriptor struct { + inode *File + mod *mod.DagModifier + flags Flags + + state state +} + +func (fi *fileDescriptor) checkWrite() error { + if fi.state == stateClosed { + return ErrClosed + } + if !fi.flags.Write { + return fmt.Errorf("file is read-only") + } + return nil +} + +func (fi *fileDescriptor) checkRead() error { + if fi.state == stateClosed { + return ErrClosed + } + if !fi.flags.Read { + return fmt.Errorf("file is write-only") + } + return nil +} + +// Size returns the size of the file referred to by this descriptor +func (fi *fileDescriptor) Size() (int64, error) { + return fi.mod.Size() +} + +// Truncate truncates the file to size +func (fi *fileDescriptor) Truncate(size int64) error { + if err := fi.checkWrite(); err != nil { + return fmt.Errorf("truncate failed: %s", err) + } + fi.state = stateDirty + return fi.mod.Truncate(size) +} + +// Write writes the given data to the file at its current offset +func (fi *fileDescriptor) Write(b []byte) (int, error) { + if err := fi.checkWrite(); err != nil { + return 0, fmt.Errorf("write failed: %s", err) + } + fi.state = stateDirty + return fi.mod.Write(b) +} + +// Read reads into the given buffer from the current offset +func (fi *fileDescriptor) Read(b []byte) (int, error) { + if err := fi.checkRead(); err != nil { + return 0, fmt.Errorf("read failed: %s", err) + } + return fi.mod.Read(b) +} + +// Read reads into the given buffer from the current offset +func (fi *fileDescriptor) CtxReadFull(ctx context.Context, b []byte) (int, error) { + if err := fi.checkRead(); err != nil { + return 0, fmt.Errorf("read failed: %s", err) + } + return fi.mod.CtxReadFull(ctx, b) +} + +// Close flushes, then propogates the modified dag node up the directory structure +// and signals a republish to occur +func (fi *fileDescriptor) Close() error { + if fi.state == stateClosed { + return ErrClosed + } + if fi.flags.Write { + defer fi.inode.desclock.Unlock() + } else if fi.flags.Read { + defer fi.inode.desclock.RUnlock() + } + err := fi.flushUp(fi.flags.Sync) + fi.state = stateClosed + return err +} + +// Flush generates a new version of the node of the underlying +// UnixFS directory (adding it to the DAG service) and updates +// the entry in the parent directory (setting `fullSync` to +// propagate the update all the way to the root). +func (fi *fileDescriptor) Flush() error { + return fi.flushUp(true) +} + +// flushUp syncs the file and adds it to the dagservice +// it *must* be called with the File's lock taken +// If `fullSync` is set the changes are propagated upwards +// (the `Up` part of `flushUp`). +func (fi *fileDescriptor) flushUp(fullSync bool) error { + var nd ipld.Node + switch fi.state { + case stateCreated, stateDirty: + var err error + nd, err = fi.mod.GetNode() + if err != nil { + return err + } + err = fi.inode.dagService.Add(context.TODO(), nd) + if err != nil { + return err + } + + // TODO: Very similar logic to the update process in + // `Directory`, the logic should be unified, both structures + // (`File` and `Directory`) are backed by a IPLD node with + // a UnixFS format that is the actual target of the update + // (regenerating it and adding it to the DAG service). + fi.inode.nodeLock.Lock() + // Always update the file descriptor's inode with the created/modified node. + fi.inode.node = nd + // Save the members to be used for subsequent calls + parent := fi.inode.parent + name := fi.inode.name + fi.inode.nodeLock.Unlock() + + // Bubble up the update's to the parent, only if fullSync is set to true. + if fullSync { + if err := parent.updateChildEntry(child{name, nd}); err != nil { + return err + } + } + + fi.state = stateFlushed + return nil + case stateFlushed: + return nil + default: + panic("invalid state") + } +} + +// Seek implements io.Seeker +func (fi *fileDescriptor) Seek(offset int64, whence int) (int64, error) { + if fi.state == stateClosed { + return 0, fmt.Errorf("seek failed: %s", ErrClosed) + } + return fi.mod.Seek(offset, whence) +} + +// Write At writes the given bytes at the offset 'at' +func (fi *fileDescriptor) WriteAt(b []byte, at int64) (int, error) { + if err := fi.checkWrite(); err != nil { + return 0, fmt.Errorf("write-at failed: %s", err) + } + fi.state = stateDirty + return fi.mod.WriteAt(b, at) +} diff --git a/vendor/github.com/ipfs/go-mfs/file.go b/vendor/github.com/ipfs/go-mfs/file.go new file mode 100644 index 00000000..280bf93a --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/file.go @@ -0,0 +1,179 @@ +package mfs + +import ( + "context" + "fmt" + "sync" + + dag "github.com/ipfs/go-merkledag" + ft "github.com/ipfs/go-unixfs" + mod "github.com/ipfs/go-unixfs/mod" + + chunker "github.com/ipfs/go-ipfs-chunker" + ipld "github.com/ipfs/go-ipld-format" +) + +// File represents a file in the MFS, its logic its mainly targeted +// to coordinating (potentially many) `FileDescriptor`s pointing to +// it. +type File struct { + inode + + // Lock to coordinate the `FileDescriptor`s associated to this file. + desclock sync.RWMutex + + // This isn't any node, it's the root node that represents the + // entire DAG of nodes that comprise the file. + // TODO: Rename, there should be an explicit term for these root nodes + // of a particular sub-DAG that abstract an upper layer's entity. + node ipld.Node + + // Lock around the `node` that represents this file, necessary because + // there may be many `FileDescriptor`s operating on this `File`. + nodeLock sync.RWMutex + + RawLeaves bool +} + +// NewFile returns a NewFile object with the given parameters. If the +// Cid version is non-zero RawLeaves will be enabled. +func NewFile(name string, node ipld.Node, parent parent, dserv ipld.DAGService) (*File, error) { + fi := &File{ + inode: inode{ + name: name, + parent: parent, + dagService: dserv, + }, + node: node, + } + if node.Cid().Prefix().Version > 0 { + fi.RawLeaves = true + } + return fi, nil +} + +func (fi *File) Open(flags Flags) (_ FileDescriptor, _retErr error) { + if flags.Write { + fi.desclock.Lock() + defer func() { + if _retErr != nil { + fi.desclock.Unlock() + } + }() + } else if flags.Read { + fi.desclock.RLock() + defer func() { + if _retErr != nil { + fi.desclock.Unlock() + } + }() + } else { + return nil, fmt.Errorf("file opened for neither reading nor writing") + } + + fi.nodeLock.RLock() + node := fi.node + fi.nodeLock.RUnlock() + + // TODO: Move this `switch` logic outside (maybe even + // to another package, this seems like a job of UnixFS), + // `NewDagModifier` uses the IPLD node, we're not + // extracting anything just doing a safety check. + switch node := node.(type) { + case *dag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(node.Data()) + if err != nil { + return nil, err + } + + switch fsn.Type() { + default: + return nil, fmt.Errorf("unsupported fsnode type for 'file'") + case ft.TSymlink: + return nil, fmt.Errorf("symlinks not yet supported") + case ft.TFile, ft.TRaw: + // OK case + } + case *dag.RawNode: + // Ok as well. + } + + dmod, err := mod.NewDagModifier(context.TODO(), node, fi.dagService, chunker.DefaultSplitter) + // TODO: Remove the use of the `chunker` package here, add a new `NewDagModifier` in + // `go-unixfs` with the `DefaultSplitter` already included. + if err != nil { + return nil, err + } + dmod.RawLeaves = fi.RawLeaves + + return &fileDescriptor{ + inode: fi, + flags: flags, + mod: dmod, + state: stateCreated, + }, nil +} + +// Size returns the size of this file +// TODO: Should we be providing this API? +// TODO: There's already a `FileDescriptor.Size()` that +// through the `DagModifier`'s `fileSize` function is doing +// pretty much the same thing as here, we should at least call +// that function and wrap the `ErrNotUnixfs` with an MFS text. +func (fi *File) Size() (int64, error) { + fi.nodeLock.RLock() + defer fi.nodeLock.RUnlock() + switch nd := fi.node.(type) { + case *dag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return 0, err + } + return int64(fsn.FileSize()), nil + case *dag.RawNode: + return int64(len(nd.RawData())), nil + default: + return 0, fmt.Errorf("unrecognized node type in mfs/file.Size()") + } +} + +// GetNode returns the dag node associated with this file +// TODO: Use this method and do not access the `nodeLock` directly anywhere else. +func (fi *File) GetNode() (ipld.Node, error) { + fi.nodeLock.RLock() + defer fi.nodeLock.RUnlock() + return fi.node, nil +} + +// TODO: Tight coupling with the `FileDescriptor`, at the +// very least this should be an independent function that +// takes a `File` argument and automates the open/flush/close +// operations. +// TODO: Why do we need to flush a file that isn't opened? +// (the `OpenWriteOnly` seems to implicitly be targeting a +// closed file, a file we forgot to flush? can we close +// a file without flushing?) +func (fi *File) Flush() error { + // open the file in fullsync mode + fd, err := fi.Open(Flags{Write: true, Sync: true}) + if err != nil { + return err + } + + defer fd.Close() + + return fd.Flush() +} + +func (fi *File) Sync() error { + // just being able to take the writelock means the descriptor is synced + // TODO: Why? + fi.desclock.Lock() + fi.desclock.Unlock() + return nil +} + +// Type returns the type FSNode this is +func (fi *File) Type() NodeType { + return TFile +} diff --git a/vendor/github.com/ipfs/go-mfs/go.mod b/vendor/github.com/ipfs/go-mfs/go.mod new file mode 100644 index 00000000..6e1d925f --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/go.mod @@ -0,0 +1,17 @@ +module github.com/ipfs/go-mfs + +require ( + github.com/ipfs/go-blockservice v0.1.1 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs-blockstore v0.0.1 + github.com/ipfs/go-ipfs-chunker v0.0.1 + github.com/ipfs/go-ipfs-exchange-offline v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-ipld-format v0.0.2 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-merkledag v0.1.0 + github.com/ipfs/go-path v0.0.7 + github.com/ipfs/go-unixfs v0.1.0 + github.com/libp2p/go-libp2p-testing v0.0.4 +) diff --git a/vendor/github.com/ipfs/go-mfs/go.sum b/vendor/github.com/ipfs/go-mfs/go.sum new file mode 100644 index 00000000..7dbab573 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/go.sum @@ -0,0 +1,497 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= +github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 h1:4i3KsuVA0o0KoBxAC5x+MY7RbteiMK1V7gf/G08NGIQ= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.0.9 h1:Dy0qvYlaOd2E2FOL2gApJ21qVjepJsGNNfstLrGf+0I= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= +github.com/ipfs/go-bitswap v0.1.0 h1:28YsHYw9ut6wootnImPXH0WpnU5Dbo3qm6cvQ6e6wYY= +github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= +github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= +github.com/ipfs/go-bitswap v0.1.3 h1:jAl9Z/TYObpGeGATUemnOZ7RYb0F/kzNVlhcYZesz+0= +github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.0.7 h1:VRRVjgahs7r//MdO7yY5DJ2/i2fmkKOnxfSyfuPjTm0= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= +github.com/ipfs/go-blockservice v0.1.0 h1:dh2i7xjMbCtf0ZSMyQAF2qpV/pEEmM7yVpQ00+gik6U= +github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= +github.com/ipfs/go-blockservice v0.1.1 h1:HHIvLuOhW0DQSrVserYcZYUl++nJPEzqZP+spRMaVzw= +github.com/ipfs/go-blockservice v0.1.1/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= +github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.3 h1:ME+QnC3uOyla1ciRPezDW0ynQYK2ikOh9OCKAEg4uUA= +github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= +github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.0.1 h1:394mZeTLcbM/LDO12PneBYvkZAUA+nRnmC0lAzDXKOY= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2 h1:amzFztBQQQ69UA5+f7JRfoXF/z2l//MGfEDHVkS20+s= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= +github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-merkledag v0.0.6 h1:rYZc0yzhO7y1cKi3Rw425a2HhEJDdLvNOWsqtmO3PF0= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= +github.com/ipfs/go-merkledag v0.1.0 h1:CAEXjRFEDPvealQj3TgEjV1IJckwjvmxAqtq5QSXJrg= +github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= +github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= +github.com/ipfs/go-peertaskqueue v0.0.4 h1:i0JprfjjILYcWM1xguO/1MCS8XKVxLSl+ECEVr6i8nw= +github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= +github.com/ipfs/go-peertaskqueue v0.1.0 h1:bpRbgv76eT4avutNPDFZuCPOQus6qTgurEYxfulgZW4= +github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-peertaskqueue v0.1.1 h1:+gPjbI+V3NktXZOqJA1kzbms2pYmhjgQQal0MzZrOAY= +github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-unixfs v0.1.0 h1:KkjcfqObdNwUN8heMtt5OdrgrRKYTIWEvpGl1bDYIho= +github.com/ipfs/go-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security v0.0.1 h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.2 h1:Ykz0lnNjxk+0SdslUmlLNyrleqdpS1S/VW+dxFdt74Y= +github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.0.30 h1:mwCWAusLhRGUzZ/VaCatsrEQTsuWExmXqVcvGBV72EQ= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= +github.com/libp2p/go-libp2p v0.1.0 h1:8VXadcPNni74ODoZ+7326LMAppFYmz1fRQOUuT5iZvQ= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p v0.1.1 h1:52sB0TJuDk2nYMcMfHOKaPoaayDZjaYVCq6Vk1ejUTk= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= +github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.0.1 h1:/mZuuiwntNR8RywnCFlGHLKrKLYne+qciBpQXWqp5fk= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2 h1:86uOwW+O6Uc7NbaK4diuLZo2/Ikvqw2rgyV03VcSbLE= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3 h1:+IonUYY0nJZLb5Fdv6a6DOjtGP1L8Bb3faamiI2q5FY= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-host v0.0.3 h1:BB/1Z+4X0rjKP5lbQTmjEjLbDVbrcmLOlA6QDsN5/j4= +github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5 h1:KG/KNYL2tYzXAfMvQN5K1aAGTYSYUMJ1prgYa2/JI1E= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-loggables v0.0.1 h1:HVww9oAnINIxbt69LJNkxD8lnbfgteXR97Xm4p3l9ps= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-metrics v0.0.1 h1:yumdPC/P2VzINdmcKZd0pciSUCpou+s0lwYCjBbzQZU= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-mplex v0.1.1 h1:lSPS1VJ36P01gGO//KgcsmSah5uoC3X9r7WY5j+iP4c= +github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-net v0.0.2 h1:qP06u4TYXfl7uW/hzqPhlVVTSA2nw1B/bHBJaUnbh6M= +github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1 h1:LgD6+skofkOx8z6odD9+MZHKjupv3ng1u6KRhaADTnA= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= +github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-routing v0.0.1 h1:hPMAWktf9rYi3ME4MG48qE7dq1ofJxiQbfdvpNntjhc= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= +github.com/libp2p/go-libp2p-secio v0.0.3 h1:h3fPeDrej7bvvARnC2oSjAfcLZOaS4REZKgWCRQNpE4= +github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.0.6 h1:gE0P/v2h+KEXtAi9YTw2UBOSODJ4m9VuuJ+ktc2LVUo= +github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.5 h1:pV6+UlRxyDpASSGD+60vMvdifSCby6JkJDfi+yUMHac= +github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4 h1:uGMOd14BL1oFlfb/cGfOxPjiTKBhzWV4aMjjoCF1Z1o= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= +github.com/libp2p/go-libp2p-yamux v0.1.3 h1:HmKvv2jWJ4GEm3iP7cEKjuw0POa6rK+Hcsu1FBKzpLc= +github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.1 h1:apvYTg0aIxxQyBX+XHKOR+0+lYhGs1Yv+JmTH9nyl5I= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.4 h1:043XJ3Zr7/Oz5cfyUaJwxUZyP02TngTpt4oq8R5UizQ= +github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3 h1:VsOlWispTivSsOMg70e0W77y6oiSBSRCyP6URrWvE04= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0 h1:3ToDXUzx8pDC6RfuOzGsUYP5roMDthbUKRdMRRhqAqY= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= +github.com/libp2p/go-stream-muxer-multistream v0.1.1 h1:DhHqb4nu1fQv/vQKeLAaZGmhLsUA4SF77IdYJiWE1d4= +github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.0.4 h1:2iRu994wCT/iEz62F+c60FUoSkijNEQ0q2Itc+79XlQ= +github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-testutil v0.0.1 h1:Xg+O0G2HIMfHqBOBDcMS1iSZJ3GEcId4qOxCQvsGZHk= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-testutil v0.1.0 h1:4QhjaWGO89udplblLVpgGDOQjzFlRavZOjuEnz2rLMc= +github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14 h1:2m16U/rLwVaRdz7ANkHtHTodP3zTP3N451MADg64x5k= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4 h1:VSJ45BzqrVgR4clSx415y1rHH7QAGhGt71J0ZmhLYrc= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-mfs/inode.go b/vendor/github.com/ipfs/go-mfs/inode.go new file mode 100644 index 00000000..50bed0b3 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/inode.go @@ -0,0 +1,21 @@ +package mfs + +import ( + ipld "github.com/ipfs/go-ipld-format" +) + +// inode abstracts the common characteristics of the MFS `File` +// and `Directory`. All of its attributes are initialized at +// creation. +type inode struct { + // name of this `inode` in the MFS path (the same value + // is also stored as the name of the DAG link). + name string + + // parent directory of this `inode` (which may be the `Root`). + parent parent + + // dagService used to store modifications made to the contents + // of the file or directory the `inode` belongs to. + dagService ipld.DAGService +} diff --git a/vendor/github.com/ipfs/go-mfs/ops.go b/vendor/github.com/ipfs/go-mfs/ops.go new file mode 100644 index 00000000..2b290728 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/ops.go @@ -0,0 +1,246 @@ +package mfs + +import ( + "context" + "fmt" + "os" + gopath "path" + "strings" + + path "github.com/ipfs/go-path" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// TODO: Evaluate moving all this operations to as `Root` +// methods, since all of them use it as its first argument +// and there is no clear documentation that explains this +// separation. + +// Mv moves the file or directory at 'src' to 'dst' +// TODO: Document what the strings 'src' and 'dst' represent. +func Mv(r *Root, src, dst string) error { + srcDirName, srcFname := gopath.Split(src) + + var dstDirName string + var dstFname string + if dst[len(dst)-1] == '/' { + dstDirName = dst + dstFname = srcFname + } else { + dstDirName, dstFname = gopath.Split(dst) + } + + // get parent directories of both src and dest first + dstDir, err := lookupDir(r, dstDirName) + if err != nil { + return err + } + + srcDir, err := lookupDir(r, srcDirName) + if err != nil { + return err + } + + srcObj, err := srcDir.Child(srcFname) + if err != nil { + return err + } + + nd, err := srcObj.GetNode() + if err != nil { + return err + } + + fsn, err := dstDir.Child(dstFname) + if err == nil { + switch n := fsn.(type) { + case *File: + _ = dstDir.Unlink(dstFname) + case *Directory: + dstDir = n + dstFname = srcFname + default: + return fmt.Errorf("unexpected type at path: %s", dst) + } + } else if err != os.ErrNotExist { + return err + } + + err = dstDir.AddChild(dstFname, nd) + if err != nil { + return err + } + + if srcDir.name == dstDir.name && srcFname == dstFname { + return nil + } + + return srcDir.Unlink(srcFname) +} + +func lookupDir(r *Root, path string) (*Directory, error) { + di, err := Lookup(r, path) + if err != nil { + return nil, err + } + + d, ok := di.(*Directory) + if !ok { + return nil, fmt.Errorf("%s is not a directory", path) + } + + return d, nil +} + +// PutNode inserts 'nd' at 'path' in the given mfs +// TODO: Rename or clearly document that this is not about nodes but actually +// MFS files/directories (that in the underlying representation can be +// considered as just nodes). +// TODO: Document why are we handling IPLD nodes in the first place when we +// are actually referring to files/directories (that is, it can't be any +// node, it has to have a specific format). +// TODO: Can this function add directories or just files? What would be the +// difference between adding a directory with this method and creating it +// with `Mkdir`. +func PutNode(r *Root, path string, nd ipld.Node) error { + dirp, filename := gopath.Split(path) + if filename == "" { + return fmt.Errorf("cannot create file with empty name") + } + + pdir, err := lookupDir(r, dirp) + if err != nil { + return err + } + + return pdir.AddChild(filename, nd) +} + +// MkdirOpts is used by Mkdir +type MkdirOpts struct { + Mkparents bool + Flush bool + CidBuilder cid.Builder +} + +// Mkdir creates a directory at 'path' under the directory 'd', creating +// intermediary directories as needed if 'mkparents' is set to true +func Mkdir(r *Root, pth string, opts MkdirOpts) error { + if pth == "" { + return fmt.Errorf("no path given to Mkdir") + } + parts := path.SplitList(pth) + if parts[0] == "" { + parts = parts[1:] + } + + // allow 'mkdir /a/b/c/' to create c + if parts[len(parts)-1] == "" { + parts = parts[:len(parts)-1] + } + + if len(parts) == 0 { + // this will only happen on 'mkdir /' + if opts.Mkparents { + return nil + } + return fmt.Errorf("cannot create directory '/': Already exists") + } + + cur := r.GetDirectory() + for i, d := range parts[:len(parts)-1] { + fsn, err := cur.Child(d) + if err == os.ErrNotExist && opts.Mkparents { + mkd, err := cur.Mkdir(d) + if err != nil { + return err + } + if opts.CidBuilder != nil { + mkd.SetCidBuilder(opts.CidBuilder) + } + fsn = mkd + } else if err != nil { + return err + } + + next, ok := fsn.(*Directory) + if !ok { + return fmt.Errorf("%s was not a directory", path.Join(parts[:i])) + } + cur = next + } + + final, err := cur.Mkdir(parts[len(parts)-1]) + if err != nil { + if !opts.Mkparents || err != os.ErrExist || final == nil { + return err + } + } + if opts.CidBuilder != nil { + final.SetCidBuilder(opts.CidBuilder) + } + + if opts.Flush { + err := final.Flush() + if err != nil { + return err + } + } + + return nil +} + +// Lookup extracts the root directory and performs a lookup under it. +// TODO: Now that the root is always a directory, can this function +// be collapsed with `DirLookup`? Or at least be made a method of `Root`? +func Lookup(r *Root, path string) (FSNode, error) { + dir := r.GetDirectory() + + return DirLookup(dir, path) +} + +// DirLookup will look up a file or directory at the given path +// under the directory 'd' +func DirLookup(d *Directory, pth string) (FSNode, error) { + pth = strings.Trim(pth, "/") + parts := path.SplitList(pth) + if len(parts) == 1 && parts[0] == "" { + return d, nil + } + + var cur FSNode + cur = d + for i, p := range parts { + chdir, ok := cur.(*Directory) + if !ok { + return nil, fmt.Errorf("cannot access %s: Not a directory", path.Join(parts[:i+1])) + } + + child, err := chdir.Child(p) + if err != nil { + return nil, err + } + + cur = child + } + return cur, nil +} + +// TODO: Document this function and link its functionality +// with the republisher. +func FlushPath(ctx context.Context, rt *Root, pth string) (ipld.Node, error) { + nd, err := Lookup(rt, pth) + if err != nil { + return nil, err + } + + err = nd.Flush() + if err != nil { + return nil, err + } + + rt.repub.WaitPub(ctx) + return nd.GetNode() +} diff --git a/vendor/github.com/ipfs/go-mfs/options.go b/vendor/github.com/ipfs/go-mfs/options.go new file mode 100644 index 00000000..6bdcd710 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/options.go @@ -0,0 +1,7 @@ +package mfs + +type Flags struct { + Read bool + Write bool + Sync bool +} diff --git a/vendor/github.com/ipfs/go-mfs/package.json b/vendor/github.com/ipfs/go-mfs/package.json new file mode 100644 index 00000000..e8079f4c --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/package.json @@ -0,0 +1,48 @@ +{ + "author": "hsanjuan", + "bugs": { + "url": "https://github.com/ipfs/go-mfs" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-mfs" + }, + "gxDependencies": [ + { + "author": "why", + "hash": "QmY6UwsN3D6uoxrRkYpJ8Wos8R66gwLmdn3wy7jM7CCRQ1", + "name": "go-merkledag", + "version": "1.1.40" + }, + { + "author": "why", + "hash": "QmVmueix5wxmr8UWpfpcKw6F1xT7T8AS7CXQRM37BE29eX", + "name": "go-unixfs", + "version": "1.3.15" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + }, + { + "author": "why", + "hash": "QmUquHAkyh9phs4ojSuHcHcZnUMGDwDNJZWnRXkNks1qLB", + "name": "go-path", + "version": "1.1.41" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "MIT", + "name": "go-mfs", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.54" +} + diff --git a/vendor/github.com/ipfs/go-mfs/repub.go b/vendor/github.com/ipfs/go-mfs/repub.go new file mode 100644 index 00000000..2c9dbd25 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/repub.go @@ -0,0 +1,197 @@ +package mfs + +import ( + "context" + "time" + + cid "github.com/ipfs/go-cid" +) + +// PubFunc is the user-defined function that determines exactly what +// logic entails "publishing" a `Cid` value. +type PubFunc func(context.Context, cid.Cid) error + +// Republisher manages when to publish a given entry. +type Republisher struct { + TimeoutLong time.Duration + TimeoutShort time.Duration + RetryTimeout time.Duration + pubfunc PubFunc + + update chan cid.Cid + immediatePublish chan chan struct{} + + ctx context.Context + cancel func() +} + +// NewRepublisher creates a new Republisher object to republish the given root +// using the given short and long time intervals. +func NewRepublisher(ctx context.Context, pf PubFunc, tshort, tlong time.Duration) *Republisher { + ctx, cancel := context.WithCancel(ctx) + return &Republisher{ + TimeoutShort: tshort, + TimeoutLong: tlong, + RetryTimeout: tlong, + update: make(chan cid.Cid, 1), + pubfunc: pf, + immediatePublish: make(chan chan struct{}), + ctx: ctx, + cancel: cancel, + } +} + +// WaitPub waits for the current value to be published (or returns early +// if it already has). +func (rp *Republisher) WaitPub(ctx context.Context) error { + wait := make(chan struct{}) + select { + case rp.immediatePublish <- wait: + case <-ctx.Done(): + return ctx.Err() + } + select { + case <-wait: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (rp *Republisher) Close() error { + // TODO(steb): Wait for `Run` to stop + err := rp.WaitPub(rp.ctx) + rp.cancel() + return err +} + +// Update the current value. The value will be published after a delay but each +// consecutive call to Update may extend this delay up to TimeoutLong. +func (rp *Republisher) Update(c cid.Cid) { + select { + case <-rp.update: + select { + case rp.update <- c: + default: + // Don't try again. If we hit this case, there's a + // concurrent publish and we can safely let that + // concurrent publish win. + } + case rp.update <- c: + } +} + +// Run contains the core logic of the `Republisher`. It calls the user-defined +// `pubfunc` function whenever the `Cid` value is updated to a *new* value. The +// complexity comes from the fact that `pubfunc` may be slow so we need to batch +// updates. +// +// Algorithm: +// 1. When we receive the first update after publishing, we set a `longer` timer. +// 2. When we receive any update, we reset the `quick` timer. +// 3. If either the `quick` timeout or the `longer` timeout elapses, +// we call `publish` with the latest updated value. +// +// The `longer` timer ensures that we delay publishing by at most +// `TimeoutLong`. The `quick` timer allows us to publish sooner if +// it looks like there are no more updates coming down the pipe. +// +// Note: If a publish fails, we retry repeatedly every TimeoutRetry. +func (rp *Republisher) Run(lastPublished cid.Cid) { + quick := time.NewTimer(0) + if !quick.Stop() { + <-quick.C + } + longer := time.NewTimer(0) + if !longer.Stop() { + <-longer.C + } + + var toPublish cid.Cid + for rp.ctx.Err() == nil { + var waiter chan struct{} + + select { + case <-rp.ctx.Done(): + return + case newValue := <-rp.update: + // Skip already published values. + if lastPublished.Equals(newValue) { + // Break to the end of the switch to cleanup any + // timers. + toPublish = cid.Undef + break + } + + // If we aren't already waiting to publish something, + // reset the long timeout. + if !toPublish.Defined() { + longer.Reset(rp.TimeoutLong) + } + + // Always reset the short timeout. + quick.Reset(rp.TimeoutShort) + + // Finally, set the new value to publish. + toPublish = newValue + continue + case waiter = <-rp.immediatePublish: + // Make sure to grab the *latest* value to publish. + select { + case toPublish = <-rp.update: + default: + } + + // Avoid publishing duplicate values + if lastPublished.Equals(toPublish) { + toPublish = cid.Undef + } + case <-quick.C: + case <-longer.C: + } + + // Cleanup, publish, and close waiters. + + // 1. Stop any timers. Don't use the `if !t.Stop() { ... }` + // idiom as these timers may not be running. + + quick.Stop() + select { + case <-quick.C: + default: + } + + longer.Stop() + select { + case <-longer.C: + default: + } + + // 2. If we have a value to publish, publish it now. + if toPublish.Defined() { + for { + err := rp.pubfunc(rp.ctx, toPublish) + if err == nil { + break + } + // Keep retrying until we succeed or we abort. + // TODO(steb): We could try pulling new values + // off `update` but that's not critical (and + // complicates this code a bit). We'll pull off + // a new value on the next loop through. + select { + case <-time.After(rp.RetryTimeout): + case <-rp.ctx.Done(): + return + } + } + lastPublished = toPublish + toPublish = cid.Undef + } + + // 3. Trigger anything waiting in `WaitPub`. + if waiter != nil { + close(waiter) + } + } +} diff --git a/vendor/github.com/ipfs/go-mfs/root.go b/vendor/github.com/ipfs/go-mfs/root.go new file mode 100644 index 00000000..026a3202 --- /dev/null +++ b/vendor/github.com/ipfs/go-mfs/root.go @@ -0,0 +1,218 @@ +// package mfs implements an in memory model of a mutable IPFS filesystem. +// TODO: Develop on this line (and move it to `doc.go`). + +package mfs + +import ( + "context" + "errors" + "fmt" + "time" + + dag "github.com/ipfs/go-merkledag" + ft "github.com/ipfs/go-unixfs" + + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" +) + +// TODO: Remove if not used. +var ErrNotExist = errors.New("no such rootfs") +var ErrClosed = errors.New("file closed") + +var log = logging.Logger("mfs") + +// TODO: Remove if not used. +var ErrIsDirectory = errors.New("error: is a directory") + +// The information that an MFS `Directory` has about its children +// when updating one of its entries: when a child mutates it signals +// its parent directory to update its entry (under `Name`) with the +// new content (in `Node`). +type child struct { + Name string + Node ipld.Node +} + +// This interface represents the basic property of MFS directories of updating +// children entries with modified content. Implemented by both the MFS +// `Directory` and `Root` (which is basically a `Directory` with republishing +// support). +// +// TODO: What is `fullsync`? (unnamed `bool` argument) +// TODO: There are two types of persistence/flush that need to be +// distinguished here, one at the DAG level (when I store the modified +// nodes in the DAG service) and one in the UnixFS/MFS level (when I modify +// the entry/link of the directory that pointed to the modified node). +type parent interface { + // Method called by a child to its parent to signal to update the content + // pointed to in the entry by that child's name. The child sends its own + // information in the `child` structure. As modifying a directory entry + // entails modifying its contents the parent will also call *its* parent's + // `updateChildEntry` to update the entry pointing to the new directory, + // this mechanism is in turn repeated until reaching the `Root`. + updateChildEntry(c child) error +} + +type NodeType int + +const ( + TFile NodeType = iota + TDir +) + +// FSNode abstracts the `Directory` and `File` structures, it represents +// any child node in the MFS (i.e., all the nodes besides the `Root`). It +// is the counterpart of the `parent` interface which represents any +// parent node in the MFS (`Root` and `Directory`). +// (Not to be confused with the `unixfs.FSNode`.) +type FSNode interface { + GetNode() (ipld.Node, error) + + Flush() error + Type() NodeType +} + +// IsDir checks whether the FSNode is dir type +func IsDir(fsn FSNode) bool { + return fsn.Type() == TDir +} + +// IsFile checks whether the FSNode is file type +func IsFile(fsn FSNode) bool { + return fsn.Type() == TFile +} + +// Root represents the root of a filesystem tree. +type Root struct { + + // Root directory of the MFS layout. + dir *Directory + + repub *Republisher +} + +// NewRoot creates a new Root and starts up a republisher routine for it. +func NewRoot(parent context.Context, ds ipld.DAGService, node *dag.ProtoNode, pf PubFunc) (*Root, error) { + + var repub *Republisher + if pf != nil { + repub = NewRepublisher(parent, pf, time.Millisecond*300, time.Second*3) + + // No need to take the lock here since we just created + // the `Republisher` and no one has access to it yet. + + go repub.Run(node.Cid()) + } + + root := &Root{ + repub: repub, + } + + fsn, err := ft.FSNodeFromBytes(node.Data()) + if err != nil { + log.Error("IPNS pointer was not unixfs node") + // TODO: IPNS pointer? + return nil, err + } + + switch fsn.Type() { + case ft.TDirectory, ft.THAMTShard: + newDir, err := NewDirectory(parent, node.String(), node, root, ds) + if err != nil { + return nil, err + } + + root.dir = newDir + case ft.TFile, ft.TMetadata, ft.TRaw: + return nil, fmt.Errorf("root can't be a file (unixfs type: %s)", fsn.Type()) + // TODO: This special error reporting case doesn't seem worth it, we either + // have a UnixFS directory or we don't. + default: + return nil, fmt.Errorf("unrecognized unixfs type: %s", fsn.Type()) + } + return root, nil +} + +// GetDirectory returns the root directory. +func (kr *Root) GetDirectory() *Directory { + return kr.dir +} + +// Flush signals that an update has occurred since the last publish, +// and updates the Root republisher. +// TODO: We are definitely abusing the "flush" terminology here. +func (kr *Root) Flush() error { + nd, err := kr.GetDirectory().GetNode() + if err != nil { + return err + } + + if kr.repub != nil { + kr.repub.Update(nd.Cid()) + } + return nil +} + +// FlushMemFree flushes the root directory and then uncaches all of its links. +// This has the effect of clearing out potentially stale references and allows +// them to be garbage collected. +// CAUTION: Take care not to ever call this while holding a reference to any +// child directories. Those directories will be bad references and using them +// may have unintended racy side effects. +// A better implemented mfs system (one that does smarter internal caching and +// refcounting) shouldnt need this method. +// TODO: Review the motivation behind this method once the cache system is +// refactored. +func (kr *Root) FlushMemFree(ctx context.Context) error { + dir := kr.GetDirectory() + + if err := dir.Flush(); err != nil { + return err + } + + dir.lock.Lock() + defer dir.lock.Unlock() + + for name := range dir.entriesCache { + delete(dir.entriesCache, name) + } + // TODO: Can't we just create new maps? + + return nil +} + +// updateChildEntry implements the `parent` interface, and signals +// to the publisher that there are changes ready to be published. +// This is the only thing that separates a `Root` from a `Directory`. +// TODO: Evaluate merging both. +// TODO: The `sync` argument isn't used here (we've already reached +// the top), document it and maybe make it an anonymous variable (if +// that's possible). +func (kr *Root) updateChildEntry(c child) error { + err := kr.GetDirectory().dagService.Add(context.TODO(), c.Node) + if err != nil { + return err + } + // TODO: Why are we not using the inner directory lock nor + // applying the same procedure as `Directory.updateChildEntry`? + + if kr.repub != nil { + kr.repub.Update(c.Node.Cid()) + } + return nil +} + +func (kr *Root) Close() error { + nd, err := kr.GetDirectory().GetNode() + if err != nil { + return err + } + + if kr.repub != nil { + kr.repub.Update(nd.Cid()) + return kr.repub.Close() + } + + return nil +} diff --git a/vendor/github.com/ipfs/go-path/.travis.yml b/vendor/github.com/ipfs/go-path/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-path/LICENSE b/vendor/github.com/ipfs/go-path/LICENSE new file mode 100644 index 00000000..7d5dcac4 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-path/Makefile b/vendor/github.com/ipfs/go-path/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-path/README.md b/vendor/github.com/ipfs/go-path/README.md new file mode 100644 index 00000000..79dd9289 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/README.md @@ -0,0 +1,32 @@ +go-path +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-path/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-path/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-path.svg?branch=master)](https://travis-ci.org/ipfs/go-path) + +> go-path is a helper package that provides utilities for parsing and using ipfs paths + + +## Table of Contents + +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## TODO + +This package could probably be merged into go-ipld, or something along those lines. It +doesnt really make sense as its own standalone thing. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-path/error.go b/vendor/github.com/ipfs/go-path/error.go new file mode 100644 index 00000000..ca2e8416 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/error.go @@ -0,0 +1,23 @@ +package path + +import ( + "fmt" +) + +// helper type so path parsing errors include the path +type pathError struct { + error error + path string +} + +func (e *pathError) Error() string { + return fmt.Sprintf("invalid path %q: %s", e.path, e.error) +} + +func (e *pathError) Unwrap() error { + return e.error +} + +func (e *pathError) Path() string { + return e.path +} diff --git a/vendor/github.com/ipfs/go-path/go.mod b/vendor/github.com/ipfs/go-path/go.mod new file mode 100644 index 00000000..a048a15a --- /dev/null +++ b/vendor/github.com/ipfs/go-path/go.mod @@ -0,0 +1,8 @@ +module github.com/ipfs/go-path + +require ( + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-ipld-format v0.0.2 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-merkledag v0.0.6 +) diff --git a/vendor/github.com/ipfs/go-path/go.sum b/vendor/github.com/ipfs/go-path/go.sum new file mode 100644 index 00000000..3879972f --- /dev/null +++ b/vendor/github.com/ipfs/go-path/go.sum @@ -0,0 +1,391 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.0.9 h1:Dy0qvYlaOd2E2FOL2gApJ21qVjepJsGNNfstLrGf+0I= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.0.7 h1:VRRVjgahs7r//MdO7yY5DJ2/i2fmkKOnxfSyfuPjTm0= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.0.1 h1:394mZeTLcbM/LDO12PneBYvkZAUA+nRnmC0lAzDXKOY= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2 h1:amzFztBQQQ69UA5+f7JRfoXF/z2l//MGfEDHVkS20+s= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= +github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-merkledag v0.0.6 h1:rYZc0yzhO7y1cKi3Rw425a2HhEJDdLvNOWsqtmO3PF0= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.0.4 h1:i0JprfjjILYcWM1xguO/1MCS8XKVxLSl+ECEVr6i8nw= +github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security v0.0.1 h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.2 h1:Ykz0lnNjxk+0SdslUmlLNyrleqdpS1S/VW+dxFdt74Y= +github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.0.30 h1:mwCWAusLhRGUzZ/VaCatsrEQTsuWExmXqVcvGBV72EQ= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= +github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= +github.com/libp2p/go-libp2p-blankhost v0.0.1 h1:/mZuuiwntNR8RywnCFlGHLKrKLYne+qciBpQXWqp5fk= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= +github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-host v0.0.3 h1:BB/1Z+4X0rjKP5lbQTmjEjLbDVbrcmLOlA6QDsN5/j4= +github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5 h1:KG/KNYL2tYzXAfMvQN5K1aAGTYSYUMJ1prgYa2/JI1E= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-loggables v0.0.1 h1:HVww9oAnINIxbt69LJNkxD8lnbfgteXR97Xm4p3l9ps= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-metrics v0.0.1 h1:yumdPC/P2VzINdmcKZd0pciSUCpou+s0lwYCjBbzQZU= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-mplex v0.1.1 h1:lSPS1VJ36P01gGO//KgcsmSah5uoC3X9r7WY5j+iP4c= +github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-net v0.0.2 h1:qP06u4TYXfl7uW/hzqPhlVVTSA2nw1B/bHBJaUnbh6M= +github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1 h1:LgD6+skofkOx8z6odD9+MZHKjupv3ng1u6KRhaADTnA= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= +github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-routing v0.0.1 h1:hPMAWktf9rYi3ME4MG48qE7dq1ofJxiQbfdvpNntjhc= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= +github.com/libp2p/go-libp2p-secio v0.0.3 h1:h3fPeDrej7bvvARnC2oSjAfcLZOaS4REZKgWCRQNpE4= +github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= +github.com/libp2p/go-libp2p-swarm v0.0.6 h1:gE0P/v2h+KEXtAi9YTw2UBOSODJ4m9VuuJ+ktc2LVUo= +github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.5 h1:pV6+UlRxyDpASSGD+60vMvdifSCby6JkJDfi+yUMHac= +github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4 h1:uGMOd14BL1oFlfb/cGfOxPjiTKBhzWV4aMjjoCF1Z1o= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= +github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= +github.com/libp2p/go-libp2p-yamux v0.1.3 h1:HmKvv2jWJ4GEm3iP7cEKjuw0POa6rK+Hcsu1FBKzpLc= +github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= +github.com/libp2p/go-maddr-filter v0.0.1 h1:apvYTg0aIxxQyBX+XHKOR+0+lYhGs1Yv+JmTH9nyl5I= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.4 h1:043XJ3Zr7/Oz5cfyUaJwxUZyP02TngTpt4oq8R5UizQ= +github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0 h1:3ToDXUzx8pDC6RfuOzGsUYP5roMDthbUKRdMRRhqAqY= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= +github.com/libp2p/go-stream-muxer-multistream v0.1.1 h1:DhHqb4nu1fQv/vQKeLAaZGmhLsUA4SF77IdYJiWE1d4= +github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= +github.com/libp2p/go-tcp-transport v0.0.4 h1:2iRu994wCT/iEz62F+c60FUoSkijNEQ0q2Itc+79XlQ= +github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= +github.com/libp2p/go-testutil v0.0.1 h1:Xg+O0G2HIMfHqBOBDcMS1iSZJ3GEcId4qOxCQvsGZHk= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= +github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4 h1:VSJ45BzqrVgR4clSx415y1rHH7QAGhGt71J0ZmhLYrc= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-path/package.json b/vendor/github.com/ipfs/go-path/package.json new file mode 100644 index 00000000..54689501 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/package.json @@ -0,0 +1,41 @@ +{ + "author": "why", + "bugs": { + "url": "https://github.com/ipfs/go-path" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-path" + }, + "gxDependencies": [ + { + "author": "why", + "hash": "QmY6UwsN3D6uoxrRkYpJ8Wos8R66gwLmdn3wy7jM7CCRQ1", + "name": "go-merkledag", + "version": "1.1.40" + }, + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-path", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.1.41" +} + diff --git a/vendor/github.com/ipfs/go-path/path.go b/vendor/github.com/ipfs/go-path/path.go new file mode 100644 index 00000000..18a85a90 --- /dev/null +++ b/vendor/github.com/ipfs/go-path/path.go @@ -0,0 +1,182 @@ +// Package path contains utilities to work with ipfs paths. +package path + +import ( + "fmt" + "path" + "strings" + + cid "github.com/ipfs/go-cid" +) + +// A Path represents an ipfs content path: +// * //path/to/file +// * /ipfs/ +// * /ipns//path/to/folder +// * etc +type Path string + +// ^^^ +// TODO: debate making this a private struct wrapped in a public interface +// would allow us to control creation, and cache segments. + +// FromString safely converts a string type to a Path type. +func FromString(s string) Path { + return Path(s) +} + +// FromCid safely converts a cid.Cid type to a Path type. +func FromCid(c cid.Cid) Path { + return Path("/ipfs/" + c.String()) +} + +// Segments returns the different elements of a path +// (elements are delimited by a /). +func (p Path) Segments() []string { + cleaned := path.Clean(string(p)) + segments := strings.Split(cleaned, "/") + + // Ignore leading slash + if len(segments[0]) == 0 { + segments = segments[1:] + } + + return segments +} + +// String converts a path to string. +func (p Path) String() string { + return string(p) +} + +// IsJustAKey returns true if the path is of the form or /ipfs/, or +// /ipld/ +func (p Path) IsJustAKey() bool { + parts := p.Segments() + return len(parts) == 2 && (parts[0] == "ipfs" || parts[0] == "ipld") +} + +// PopLastSegment returns a new Path without its final segment, and the final +// segment, separately. If there is no more to pop (the path is just a key), +// the original path is returned. +func (p Path) PopLastSegment() (Path, string, error) { + + if p.IsJustAKey() { + return p, "", nil + } + + segs := p.Segments() + newPath, err := ParsePath("/" + strings.Join(segs[:len(segs)-1], "/")) + if err != nil { + return "", "", err + } + + return newPath, segs[len(segs)-1], nil +} + +// FromSegments returns a path given its different segments. +func FromSegments(prefix string, seg ...string) (Path, error) { + return ParsePath(prefix + strings.Join(seg, "/")) +} + +// ParsePath returns a well-formed ipfs Path. +// The returned path will always be prefixed with /ipfs/ or /ipns/. +// The prefix will be added if not present in the given string. +// This function will return an error when the given string is +// not a valid ipfs path. +func ParsePath(txt string) (Path, error) { + parts := strings.Split(txt, "/") + if len(parts) == 1 { + kp, err := ParseCidToPath(txt) + if err == nil { + return kp, nil + } + } + + // if the path doesnt begin with a '/' + // we expect this to start with a hash, and be an 'ipfs' path + if parts[0] != "" { + if _, err := cid.Decode(parts[0]); err != nil { + return "", &pathError{error: err, path: txt} + } + // The case when the path starts with hash without a protocol prefix + return Path("/ipfs/" + txt), nil + } + + if len(parts) < 3 { + return "", &pathError{error: fmt.Errorf("path does not begin with '/'"), path: txt} + } + + //TODO: make this smarter + switch parts[1] { + case "ipfs", "ipld": + if parts[2] == "" { + return "", &pathError{error: fmt.Errorf("not enough path components"), path: txt} + } + // Validate Cid. + _, err := cid.Decode(parts[2]) + if err != nil { + return "", &pathError{error: fmt.Errorf("invalid CID: %s", err), path: txt} + } + case "ipns": + if parts[2] == "" { + return "", &pathError{error: fmt.Errorf("not enough path components"), path: txt} + } + default: + return "", &pathError{error: fmt.Errorf("unknown namespace %q", parts[1]), path: txt} + } + + return Path(txt), nil +} + +// ParseCidToPath takes a CID in string form and returns a valid ipfs Path. +func ParseCidToPath(txt string) (Path, error) { + if txt == "" { + return "", &pathError{error: fmt.Errorf("empty"), path: txt} + } + + c, err := cid.Decode(txt) + if err != nil { + return "", &pathError{error: err, path: txt} + } + + return FromCid(c), nil +} + +// IsValid checks if a path is a valid ipfs Path. +func (p *Path) IsValid() error { + _, err := ParsePath(p.String()) + return err +} + +// Join joins strings slices using / +func Join(pths []string) string { + return strings.Join(pths, "/") +} + +// SplitList splits strings usings / +func SplitList(pth string) []string { + return strings.Split(pth, "/") +} + +// SplitAbsPath clean up and split fpath. It extracts the first component (which +// must be a Multihash) and return it separately. +func SplitAbsPath(fpath Path) (cid.Cid, []string, error) { + parts := fpath.Segments() + if parts[0] == "ipfs" || parts[0] == "ipld" { + parts = parts[1:] + } + + // if nothing, bail. + if len(parts) == 0 { + return cid.Cid{}, nil, &pathError{error: fmt.Errorf("empty"), path: string(fpath)} + } + + c, err := cid.Decode(parts[0]) + // first element in the path is a cid + if err != nil { + return cid.Cid{}, nil, &pathError{error: fmt.Errorf("invalid CID: %s", err), path: string(fpath)} + } + + return c, parts[1:], nil +} diff --git a/vendor/github.com/ipfs/go-path/resolver/resolver.go b/vendor/github.com/ipfs/go-path/resolver/resolver.go new file mode 100644 index 00000000..67bb9f6f --- /dev/null +++ b/vendor/github.com/ipfs/go-path/resolver/resolver.go @@ -0,0 +1,209 @@ +// Package resolver implements utilities for resolving paths within ipfs. +package resolver + +import ( + "context" + "errors" + "fmt" + "time" + + path "github.com/ipfs/go-path" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + logging "github.com/ipfs/go-log" + dag "github.com/ipfs/go-merkledag" +) + +var log = logging.Logger("pathresolv") + +// ErrNoComponents is used when Paths after a protocol +// do not contain at least one component +var ErrNoComponents = errors.New( + "path must contain at least one component") + +// ErrNoLink is returned when a link is not found in a path +type ErrNoLink struct { + Name string + Node cid.Cid +} + +// Error implements the Error interface for ErrNoLink with a useful +// human readable message. +func (e ErrNoLink) Error() string { + return fmt.Sprintf("no link named %q under %s", e.Name, e.Node.String()) +} + +// ResolveOnce resolves path through a single node +type ResolveOnce func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) + +// Resolver provides path resolution to IPFS +// It has a pointer to a DAGService, which is uses to resolve nodes. +// TODO: now that this is more modular, try to unify this code with the +// the resolvers in namesys +type Resolver struct { + DAG ipld.NodeGetter + + ResolveOnce ResolveOnce +} + +// NewBasicResolver constructs a new basic resolver. +func NewBasicResolver(ds ipld.DAGService) *Resolver { + return &Resolver{ + DAG: ds, + ResolveOnce: ResolveSingle, + } +} + +// ResolveToLastNode walks the given path and returns the cid of the last node +// referenced by the path +func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath path.Path) (cid.Cid, []string, error) { + c, p, err := path.SplitAbsPath(fpath) + if err != nil { + return cid.Cid{}, nil, err + } + + if len(p) == 0 { + return c, nil, nil + } + + nd, err := r.DAG.Get(ctx, c) + if err != nil { + return cid.Cid{}, nil, err + } + + for len(p) > 0 { + lnk, rest, err := r.ResolveOnce(ctx, r.DAG, nd, p) + + // Note: have to drop the error here as `ResolveOnce` doesn't handle 'leaf' + // paths (so e.g. for `echo '{"foo":123}' | ipfs dag put` we wouldn't be + // able to resolve `zdpu[...]/foo`) + if lnk == nil { + break + } + + if err != nil { + if err == dag.ErrLinkNotFound { + err = ErrNoLink{Name: p[0], Node: nd.Cid()} + } + return cid.Cid{}, nil, err + } + + next, err := lnk.GetNode(ctx, r.DAG) + if err != nil { + return cid.Cid{}, nil, err + } + nd = next + p = rest + } + + if len(p) == 0 { + return nd.Cid(), nil, nil + } + + // Confirm the path exists within the object + val, rest, err := nd.Resolve(p) + if err != nil { + if err == dag.ErrLinkNotFound { + err = ErrNoLink{Name: p[0], Node: nd.Cid()} + } + return cid.Cid{}, nil, err + } + + if len(rest) > 0 { + return cid.Cid{}, nil, errors.New("path failed to resolve fully") + } + switch val.(type) { + case *ipld.Link: + return cid.Cid{}, nil, errors.New("inconsistent ResolveOnce / nd.Resolve") + default: + return nd.Cid(), p, nil + } +} + +// ResolvePath fetches the node for given path. It returns the last item +// returned by ResolvePathComponents. +func (r *Resolver) ResolvePath(ctx context.Context, fpath path.Path) (ipld.Node, error) { + // validate path + if err := fpath.IsValid(); err != nil { + return nil, err + } + + nodes, err := r.ResolvePathComponents(ctx, fpath) + if err != nil || nodes == nil { + return nil, err + } + return nodes[len(nodes)-1], err +} + +// ResolveSingle simply resolves one hop of a path through a graph with no +// extra context (does not opaquely resolve through sharded nodes) +func ResolveSingle(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) { + return nd.ResolveLink(names) +} + +// ResolvePathComponents fetches the nodes for each segment of the given path. +// It uses the first path component as a hash (key) of the first node, then +// resolves all other components walking the links, with ResolveLinks. +func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ([]ipld.Node, error) { + evt := log.EventBegin(ctx, "resolvePathComponents", logging.LoggableMap{"fpath": fpath}) + defer evt.Done() + + h, parts, err := path.SplitAbsPath(fpath) + if err != nil { + evt.Append(logging.LoggableMap{"error": err.Error()}) + return nil, err + } + + log.Debug("resolve dag get") + nd, err := r.DAG.Get(ctx, h) + if err != nil { + evt.Append(logging.LoggableMap{"error": err.Error()}) + return nil, err + } + + return r.ResolveLinks(ctx, nd, parts) +} + +// ResolveLinks iteratively resolves names by walking the link hierarchy. +// Every node is fetched from the DAGService, resolving the next name. +// Returns the list of nodes forming the path, starting with ndd. This list is +// guaranteed never to be empty. +// +// ResolveLinks(nd, []string{"foo", "bar", "baz"}) +// would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links +func (r *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []string) ([]ipld.Node, error) { + + evt := log.EventBegin(ctx, "resolveLinks", logging.LoggableMap{"names": names}) + defer evt.Done() + result := make([]ipld.Node, 0, len(names)+1) + result = append(result, ndd) + nd := ndd // dup arg workaround + + // for each of the path components + for len(names) > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Minute) + defer cancel() + + lnk, rest, err := r.ResolveOnce(ctx, r.DAG, nd, names) + if err == dag.ErrLinkNotFound { + evt.Append(logging.LoggableMap{"error": err.Error()}) + return result, ErrNoLink{Name: names[0], Node: nd.Cid()} + } else if err != nil { + evt.Append(logging.LoggableMap{"error": err.Error()}) + return result, err + } + + nextnode, err := lnk.GetNode(ctx, r.DAG) + if err != nil { + evt.Append(logging.LoggableMap{"error": err.Error()}) + return result, err + } + + nd = nextnode + result = append(result, nextnode) + names = rest + } + return result, nil +} diff --git a/vendor/github.com/ipfs/go-peertaskqueue/.travis.yml b/vendor/github.com/ipfs/go-peertaskqueue/.travis.yml new file mode 100644 index 00000000..c8102833 --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/.travis.yml @@ -0,0 +1,33 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false + + diff --git a/vendor/github.com/ipfs/go-peertaskqueue/COPYRIGHT b/vendor/github.com/ipfs/go-peertaskqueue/COPYRIGHT new file mode 100644 index 00000000..771e6f7c --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/COPYRIGHT @@ -0,0 +1,3 @@ +Copyright 2019. Protocol Labs, Inc. + +This library is dual-licensed under Apache 2.0 and MIT terms. diff --git a/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-APACHE b/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-APACHE new file mode 100644 index 00000000..54651436 --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-APACHE @@ -0,0 +1,13 @@ +Copyright 2019. Protocol Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-MIT b/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-MIT new file mode 100644 index 00000000..ea532a83 --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2019. Protocol Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ipfs/go-peertaskqueue/go.mod b/vendor/github.com/ipfs/go-peertaskqueue/go.mod new file mode 100644 index 00000000..e093129c --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/go.mod @@ -0,0 +1,9 @@ +module github.com/ipfs/go-peertaskqueue + +go 1.12 + +require ( + github.com/ipfs/go-ipfs-pq v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multihash v0.0.5 // indirect +) diff --git a/vendor/github.com/ipfs/go-peertaskqueue/go.sum b/vendor/github.com/ipfs/go-peertaskqueue/go.sum new file mode 100644 index 00000000..9249ebfb --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/go.sum @@ -0,0 +1,84 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-peertaskqueue/peertask/peertask.go b/vendor/github.com/ipfs/go-peertaskqueue/peertask/peertask.go new file mode 100644 index 00000000..a91b4ecd --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/peertask/peertask.go @@ -0,0 +1,97 @@ +package peertask + +import ( + "time" + + pq "github.com/ipfs/go-ipfs-pq" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// FIFOCompare is a basic task comparator that returns tasks in the order created. +var FIFOCompare = func(a, b *TaskBlock) bool { + return a.created.Before(b.created) +} + +// PriorityCompare respects the target peer's task priority. For tasks involving +// different peers, the oldest task is prioritized. +var PriorityCompare = func(a, b *TaskBlock) bool { + if a.Target == b.Target { + return a.Priority > b.Priority + } + return FIFOCompare(a, b) +} + +// WrapCompare wraps a TaskBlock comparison function so it can be used as +// comparison for a priority queue +func WrapCompare(f func(a, b *TaskBlock) bool) func(a, b pq.Elem) bool { + return func(a, b pq.Elem) bool { + return f(a.(*TaskBlock), b.(*TaskBlock)) + } +} + +// Identifier is a unique identifier for a task. It's used by the client library +// to act on a task once it exits the queue. +type Identifier interface{} + +// Task is a single task to be executed as part of a task block. +type Task struct { + Identifier Identifier + Priority int +} + +// TaskBlock is a block of tasks to execute on a single peer. +type TaskBlock struct { + Tasks []Task + Priority int + Target peer.ID + + // A callback to signal that this task block has been completed + Done func([]Task) + + // toPrune are the tasks that have already been taken care of as part of + // a different task block which can be removed from the task block. + toPrune map[Identifier]struct{} + created time.Time // created marks the time that the task was added to the queue + index int // book-keeping field used by the pq container +} + +// NewTaskBlock creates a new task block with the given tasks, priority, target +// peer, and task completion function. +func NewTaskBlock(tasks []Task, priority int, target peer.ID, done func([]Task)) *TaskBlock { + return &TaskBlock{ + Tasks: tasks, + Priority: priority, + Target: target, + Done: done, + toPrune: make(map[Identifier]struct{}, len(tasks)), + created: time.Now(), + } +} + +// MarkPrunable marks any tasks with the given identifier as prunable at the time +// the task block is pulled of the queue to execute (because they've already been removed). +func (pt *TaskBlock) MarkPrunable(identifier Identifier) { + pt.toPrune[identifier] = struct{}{} +} + +// PruneTasks removes all tasks previously marked as prunable from the lists of +// tasks in the block +func (pt *TaskBlock) PruneTasks() { + newTasks := make([]Task, 0, len(pt.Tasks)-len(pt.toPrune)) + for _, task := range pt.Tasks { + if _, ok := pt.toPrune[task.Identifier]; !ok { + newTasks = append(newTasks, task) + } + } + pt.Tasks = newTasks +} + +// Index implements pq.Elem. +func (pt *TaskBlock) Index() int { + return pt.index +} + +// SetIndex implements pq.Elem. +func (pt *TaskBlock) SetIndex(i int) { + pt.index = i +} diff --git a/vendor/github.com/ipfs/go-peertaskqueue/peertaskqueue.go b/vendor/github.com/ipfs/go-peertaskqueue/peertaskqueue.go new file mode 100644 index 00000000..40200bdc --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/peertaskqueue.go @@ -0,0 +1,220 @@ +package peertaskqueue + +import ( + "sync" + + pq "github.com/ipfs/go-ipfs-pq" + "github.com/ipfs/go-peertaskqueue/peertask" + "github.com/ipfs/go-peertaskqueue/peertracker" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +type peerTaskQueueEvent int + +const ( + peerAdded = peerTaskQueueEvent(1) + peerRemoved = peerTaskQueueEvent(2) +) + +type hookFunc func(p peer.ID, event peerTaskQueueEvent) + +// PeerTaskQueue is a prioritized list of tasks to be executed on peers. +// The queue puts tasks on in blocks, then alternates between peers (roughly) +// to execute the block with the highest priority, or otherwise the one added +// first if priorities are equal. +type PeerTaskQueue struct { + lock sync.Mutex + pQueue pq.PQ + peerTrackers map[peer.ID]*peertracker.PeerTracker + frozenPeers map[peer.ID]struct{} + hooks []hookFunc + ignoreFreezing bool +} + +// Option is a function that configures the peer task queue +type Option func(*PeerTaskQueue) Option + +func chain(firstOption Option, secondOption Option) Option { + return func(ptq *PeerTaskQueue) Option { + firstReverse := firstOption(ptq) + secondReverse := secondOption(ptq) + return chain(secondReverse, firstReverse) + } +} + +// IgnoreFreezing is an option that can make the task queue ignore freezing and unfreezing +func IgnoreFreezing(ignoreFreezing bool) Option { + return func(ptq *PeerTaskQueue) Option { + previous := ptq.ignoreFreezing + ptq.ignoreFreezing = ignoreFreezing + return IgnoreFreezing(previous) + } +} + +func removeHook(hook hookFunc) Option { + return func(ptq *PeerTaskQueue) Option { + for i, testHook := range ptq.hooks { + if &hook == &testHook { + ptq.hooks = append(ptq.hooks[:i], ptq.hooks[i+1:]...) + break + } + } + return addHook(hook) + } +} + +func addHook(hook hookFunc) Option { + return func(ptq *PeerTaskQueue) Option { + ptq.hooks = append(ptq.hooks, hook) + return removeHook(hook) + } +} + +// OnPeerAddedHook adds a hook function that gets called whenever the ptq adds a new peer +func OnPeerAddedHook(onPeerAddedHook func(p peer.ID)) Option { + hook := func(p peer.ID, event peerTaskQueueEvent) { + if event == peerAdded { + onPeerAddedHook(p) + } + } + return addHook(hook) +} + +// OnPeerRemovedHook adds a hook function that gets called whenever the ptq adds a new peer +func OnPeerRemovedHook(onPeerRemovedHook func(p peer.ID)) Option { + hook := func(p peer.ID, event peerTaskQueueEvent) { + if event == peerRemoved { + onPeerRemovedHook(p) + } + } + return addHook(hook) +} + +// New creates a new PeerTaskQueue +func New(options ...Option) *PeerTaskQueue { + ptq := &PeerTaskQueue{ + peerTrackers: make(map[peer.ID]*peertracker.PeerTracker), + frozenPeers: make(map[peer.ID]struct{}), + pQueue: pq.New(peertracker.PeerCompare), + } + ptq.Options(options...) + return ptq +} + +// Options uses configuration functions to configure the peer task queue. +// It returns an Option that can be called to reverse the changes. +func (ptq *PeerTaskQueue) Options(options ...Option) Option { + if len(options) == 0 { + return nil + } + if len(options) == 1 { + return options[0](ptq) + } + reverse := options[0](ptq) + return chain(ptq.Options(options[1:]...), reverse) +} + +func (ptq *PeerTaskQueue) callHooks(to peer.ID, event peerTaskQueueEvent) { + for _, hook := range ptq.hooks { + hook(to, event) + } +} + +// PushBlock adds a new block of tasks for the given peer to the queue +func (ptq *PeerTaskQueue) PushBlock(to peer.ID, tasks ...peertask.Task) { + ptq.lock.Lock() + defer ptq.lock.Unlock() + peerTracker, ok := ptq.peerTrackers[to] + if !ok { + peerTracker = peertracker.New(to) + ptq.pQueue.Push(peerTracker) + ptq.peerTrackers[to] = peerTracker + ptq.callHooks(to, peerAdded) + } + + peerTracker.PushBlock(to, tasks, func(e []peertask.Task) { + ptq.lock.Lock() + for _, task := range e { + peerTracker.TaskDone(task.Identifier) + } + ptq.pQueue.Update(peerTracker.Index()) + ptq.lock.Unlock() + }) + ptq.pQueue.Update(peerTracker.Index()) +} + +// PopBlock 'pops' the next block of tasks to be performed. Returns nil if no block exists. +func (ptq *PeerTaskQueue) PopBlock() *peertask.TaskBlock { + ptq.lock.Lock() + defer ptq.lock.Unlock() + if ptq.pQueue.Len() == 0 { + return nil + } + peerTracker := ptq.pQueue.Pop().(*peertracker.PeerTracker) + + out := peerTracker.PopBlock() + if peerTracker.IsIdle() { + target := peerTracker.Target() + delete(ptq.peerTrackers, target) + delete(ptq.frozenPeers, target) + ptq.callHooks(target, peerRemoved) + } else { + ptq.pQueue.Push(peerTracker) + } + return out +} + +// Remove removes a task from the queue. +func (ptq *PeerTaskQueue) Remove(identifier peertask.Identifier, p peer.ID) { + ptq.lock.Lock() + peerTracker, ok := ptq.peerTrackers[p] + if ok { + if peerTracker.Remove(identifier) { + // we now also 'freeze' that partner. If they sent us a cancel for a + // block we were about to send them, we should wait a short period of time + // to make sure we receive any other in-flight cancels before sending + // them a block they already potentially have + if !ptq.ignoreFreezing { + if !peerTracker.IsFrozen() { + ptq.frozenPeers[p] = struct{}{} + } + + peerTracker.Freeze() + } + ptq.pQueue.Update(peerTracker.Index()) + } + } + ptq.lock.Unlock() +} + +// FullThaw completely thaws all peers in the queue so they can execute tasks. +func (ptq *PeerTaskQueue) FullThaw() { + ptq.lock.Lock() + defer ptq.lock.Unlock() + + for p := range ptq.frozenPeers { + peerTracker, ok := ptq.peerTrackers[p] + if ok { + peerTracker.FullThaw() + delete(ptq.frozenPeers, p) + ptq.pQueue.Update(peerTracker.Index()) + } + } +} + +// ThawRound unthaws peers incrementally, so that those have been frozen the least +// become unfrozen and able to execute tasks first. +func (ptq *PeerTaskQueue) ThawRound() { + ptq.lock.Lock() + defer ptq.lock.Unlock() + + for p := range ptq.frozenPeers { + peerTracker, ok := ptq.peerTrackers[p] + if ok { + if peerTracker.Thaw() { + delete(ptq.frozenPeers, p) + } + ptq.pQueue.Update(peerTracker.Index()) + } + } +} diff --git a/vendor/github.com/ipfs/go-peertaskqueue/peertracker/peertracker.go b/vendor/github.com/ipfs/go-peertaskqueue/peertracker/peertracker.go new file mode 100644 index 00000000..3b7451b6 --- /dev/null +++ b/vendor/github.com/ipfs/go-peertaskqueue/peertracker/peertracker.go @@ -0,0 +1,212 @@ +package peertracker + +import ( + "sync" + + pq "github.com/ipfs/go-ipfs-pq" + "github.com/ipfs/go-peertaskqueue/peertask" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// PeerTracker tracks task blocks for a single peer, as well as active tasks +// for that peer +type PeerTracker struct { + target peer.ID + // Active is the number of track tasks this peer is currently + // processing + // active must be locked around as it will be updated externally + activelk sync.Mutex + active int + activeTasks map[peertask.Identifier]struct{} + + // total number of task tasks for this task + numTasks int + + // for the PQ interface + index int + + freezeVal int + + taskMap map[peertask.Identifier]*peertask.TaskBlock + + // priority queue of tasks belonging to this peer + taskBlockQueue pq.PQ +} + +// New creates a new PeerTracker +func New(target peer.ID) *PeerTracker { + return &PeerTracker{ + target: target, + taskBlockQueue: pq.New(peertask.WrapCompare(peertask.PriorityCompare)), + taskMap: make(map[peertask.Identifier]*peertask.TaskBlock), + activeTasks: make(map[peertask.Identifier]struct{}), + } +} + +// PeerCompare implements pq.ElemComparator +// returns true if peer 'a' has higher priority than peer 'b' +func PeerCompare(a, b pq.Elem) bool { + pa := a.(*PeerTracker) + pb := b.(*PeerTracker) + + // having no tasks means lowest priority + // having both of these checks ensures stability of the sort + if pa.numTasks == 0 { + return false + } + if pb.numTasks == 0 { + return true + } + + if pa.freezeVal > pb.freezeVal { + return false + } + if pa.freezeVal < pb.freezeVal { + return true + } + + if pa.active == pb.active { + // sorting by taskQueue.Len() aids in cleaning out trash tasks faster + // if we sorted instead by requests, one peer could potentially build up + // a huge number of cancelled tasks in the queue resulting in a memory leak + return pa.taskBlockQueue.Len() > pb.taskBlockQueue.Len() + } + return pa.active < pb.active +} + +// StartTask signals that a task was started for this peer. +func (p *PeerTracker) StartTask(identifier peertask.Identifier) { + p.activelk.Lock() + p.activeTasks[identifier] = struct{}{} + p.active++ + p.activelk.Unlock() +} + +// TaskDone signals that a task was completed for this peer. +func (p *PeerTracker) TaskDone(identifier peertask.Identifier) { + p.activelk.Lock() + delete(p.activeTasks, identifier) + p.active-- + if p.active < 0 { + panic("more tasks finished than started!") + } + p.activelk.Unlock() +} + +// Target returns the peer that this peer tracker tracks tasks for +func (p *PeerTracker) Target() peer.ID { + return p.target +} + +// IsIdle returns true if the peer has no active tasks or queued tasks +func (p *PeerTracker) IsIdle() bool { + p.activelk.Lock() + defer p.activelk.Unlock() + return p.numTasks == 0 && p.active == 0 +} + +// Index implements pq.Elem. +func (p *PeerTracker) Index() int { + return p.index +} + +// SetIndex implements pq.Elem. +func (p *PeerTracker) SetIndex(i int) { + p.index = i +} + +// PushBlock adds a new block of tasks on to a peers queue from the given +// peer ID, list of tasks, and task block completion function +func (p *PeerTracker) PushBlock(target peer.ID, tasks []peertask.Task, done func(e []peertask.Task)) { + + p.activelk.Lock() + defer p.activelk.Unlock() + + var priority int + newTasks := make([]peertask.Task, 0, len(tasks)) + for _, task := range tasks { + if _, ok := p.activeTasks[task.Identifier]; ok { + continue + } + if taskBlock, ok := p.taskMap[task.Identifier]; ok { + if task.Priority > taskBlock.Priority { + taskBlock.Priority = task.Priority + p.taskBlockQueue.Update(taskBlock.Index()) + } + continue + } + if task.Priority > priority { + priority = task.Priority + } + newTasks = append(newTasks, task) + } + + if len(newTasks) == 0 { + return + } + + taskBlock := peertask.NewTaskBlock(newTasks, priority, target, done) + p.taskBlockQueue.Push(taskBlock) + for _, task := range newTasks { + p.taskMap[task.Identifier] = taskBlock + } + p.numTasks += len(newTasks) +} + +// PopBlock removes a block of tasks from this peers queue +func (p *PeerTracker) PopBlock() *peertask.TaskBlock { + var out *peertask.TaskBlock + for p.taskBlockQueue.Len() > 0 && p.freezeVal == 0 { + out = p.taskBlockQueue.Pop().(*peertask.TaskBlock) + + for _, task := range out.Tasks { + delete(p.taskMap, task.Identifier) + } + out.PruneTasks() + + if len(out.Tasks) > 0 { + for _, task := range out.Tasks { + p.numTasks-- + p.StartTask(task.Identifier) + } + } else { + out = nil + continue + } + break + } + return out +} + +// Remove removes the task with the given identifier from this peers queue +func (p *PeerTracker) Remove(identifier peertask.Identifier) bool { + taskBlock, ok := p.taskMap[identifier] + if ok { + taskBlock.MarkPrunable(identifier) + p.numTasks-- + } + return ok +} + +// Freeze increments the freeze value for this peer. While a peer is frozen +// (freeze value > 0) it will not execute tasks. +func (p *PeerTracker) Freeze() { + p.freezeVal++ +} + +// Thaw decrements the freeze value for this peer. While a peer is frozen +// (freeze value > 0) it will not execute tasks. +func (p *PeerTracker) Thaw() bool { + p.freezeVal -= (p.freezeVal + 1) / 2 + return p.freezeVal <= 0 +} + +// FullThaw completely unfreezes this peer so it can execute tasks. +func (p *PeerTracker) FullThaw() { + p.freezeVal = 0 +} + +// IsFrozen returns whether this peer is frozen and unable to execute tasks. +func (p *PeerTracker) IsFrozen() bool { + return p.freezeVal > 0 +} diff --git a/vendor/github.com/ipfs/go-todocounter/.travis.yml b/vendor/github.com/ipfs/go-todocounter/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-todocounter/LICENSE b/vendor/github.com/ipfs/go-todocounter/LICENSE new file mode 100644 index 00000000..808d2e01 --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 libp2p + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/ipfs/go-todocounter/Makefile b/vendor/github.com/ipfs/go-todocounter/Makefile new file mode 100644 index 00000000..45d0c77e --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/Makefile @@ -0,0 +1,10 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + go get ./... \ No newline at end of file diff --git a/vendor/github.com/ipfs/go-todocounter/README.md b/vendor/github.com/ipfs/go-todocounter/README.md new file mode 100644 index 00000000..7e8e4215 --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/README.md @@ -0,0 +1,26 @@ +# go-todocounter + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) + +> A threadsafe counter + +## Documenation + +See https://godoc.org/github.com/ipfs/go-todocounter. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-todocounter/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT \ No newline at end of file diff --git a/vendor/github.com/ipfs/go-todocounter/counter.go b/vendor/github.com/ipfs/go-todocounter/counter.go new file mode 100644 index 00000000..0df63820 --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/counter.go @@ -0,0 +1,118 @@ +package todocounter + +import ( + "sync" +) + +// Counter records things remaining to process. It is needed for complicated +// cases where multiple goroutines are spawned to process items, and they may +// generate more items to process. For example, say a query over a set of nodes +// may yield either a result value, or more nodes to query. Signaling is subtly +// complicated, because the queue may be empty while items are being processed, +// that will end up adding more items to the queue. +// +// Use Counter like this: +// +// todos := make(chan int, 10) +// ctr := todoctr.NewCounter() +// +// process := func(item int) { +// fmt.Println("processing %d\n...", item) +// +// // this task may randomly generate more tasks +// if rand.Intn(5) == 0 { +// todos<- item + 1 +// ctr.Increment(1) // increment counter for new task. +// } +// +// ctr.Decrement(1) // decrement one to signal the task being done. +// } +// +// // add some tasks. +// todos<- 1 +// todos<- 2 +// todos<- 3 +// todos<- 4 +// ctr.Increment(4) +// +// for { +// select { +// case item := <- todos: +// go process(item) +// case <-ctr.Done(): +// fmt.Println("done processing everything.") +// close(todos) +// } +// } +type Counter interface { + // Incrememnt adds a number of todos to track. + // If the counter is **below** zero, it panics. + Increment(i uint32) + + // Decrement removes a number of todos to track. + // If the count drops to zero, signals done and destroys the counter. + // If the count drops **below** zero, panics. It means you have tried to remove + // more things than you added, i.e. sync issues. + Decrement(i uint32) + + // Done returns a channel to wait upon. Use it in selects: + // + // select { + // case <-ctr.Done(): + // // done processing all items + // } + // + Done() <-chan struct{} +} + +type todoCounter struct { + count int32 + done chan struct{} + sync.RWMutex +} + +// NewSyncCounter constructs a new counter +func NewSyncCounter() Counter { + return &todoCounter{ + done: make(chan struct{}), + } +} + +func (c *todoCounter) Increment(i uint32) { + c.Lock() + defer c.Unlock() + + if c.count < 0 { + panic("counter already signaled done. use a new counter.") + } + + // increment count + c.count += int32(i) +} + +// Decrement removes a number of todos to track. +// If the count drops to zero, signals done and destroys the counter. +// If the count drops **below** zero, panics. It means you have tried to remove +// more things than you added, i.e. sync issues. +func (c *todoCounter) Decrement(i uint32) { + c.Lock() + defer c.Unlock() + + if c.count < 0 { + panic("counter already signaled done. probably have sync issues.") + } + + if int32(i) > c.count { + panic("decrement amount creater than counter. sync issues.") + } + + c.count -= int32(i) + if c.count == 0 { // done! signal it. + c.count-- // set it to -1 to prevent reuse + close(c.done) // a closed channel will always return nil + } +} + +func (c *todoCounter) Done() <-chan struct{} { + return c.done +} diff --git a/vendor/github.com/ipfs/go-todocounter/go.mod b/vendor/github.com/ipfs/go-todocounter/go.mod new file mode 100644 index 00000000..d631776e --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/go.mod @@ -0,0 +1 @@ +module github.com/ipfs/go-todocounter diff --git a/vendor/github.com/ipfs/go-todocounter/package.json b/vendor/github.com/ipfs/go-todocounter/package.json new file mode 100644 index 00000000..3141ae04 --- /dev/null +++ b/vendor/github.com/ipfs/go-todocounter/package.json @@ -0,0 +1,14 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/ipfs/go-todocounter/issues" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-todocounter" + }, + "gxVersion": "0.8.0", + "language": "go", + "license": "MIT", + "name": "go-todocounter", + "version": "1.0.1" +} diff --git a/vendor/github.com/ipfs/go-unixfs/.travis.yml b/vendor/github.com/ipfs/go-unixfs/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-unixfs/CODEOWNERS b/vendor/github.com/ipfs/go-unixfs/CODEOWNERS new file mode 100644 index 00000000..ea812704 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/CODEOWNERS @@ -0,0 +1,8 @@ +# Please see https://help.github.com/articles/about-codeowners/ for more information + +# Global owner +* @schomatis + +# Subsystem specific owners + + diff --git a/vendor/github.com/ipfs/go-unixfs/LICENSE b/vendor/github.com/ipfs/go-unixfs/LICENSE new file mode 100644 index 00000000..7d5dcac4 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-unixfs/Makefile b/vendor/github.com/ipfs/go-unixfs/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/ipfs/go-unixfs/README.md b/vendor/github.com/ipfs/go-unixfs/README.md new file mode 100644 index 00000000..9a22fbd3 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/README.md @@ -0,0 +1,63 @@ +go-unixfs +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![Coverage Status](https://codecov.io/gh/ipfs/go-unixfs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-unixfs/branch/master) +[![Travis CI](https://travis-ci.org/ipfs/go-unixfs.svg?branch=master)](https://travis-ci.org/ipfs/go-unixfs) + +> go-unixfs implements unix-like filesystem utilities on top of an ipld merkledag + + +## Table of Contents + +- [Directory](#directory) +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Package Directory +This package contains many subpackages, each of which can be very large on its own. + +### Top Level +The top level unixfs package defines the unixfs format datastructures, and some helper methods around it. + +### importers +The `importer` subpackage is what you'll use when you want to turn a normal file into a unixfs file. + +### io +The `io` subpackage provides helpers for reading files and manipulating directories. The `DagReader` takes a +reference to a unixfs file and returns a file handle that can be read from and seeked through. The `Directory` +interface allows you to easily read items in a directory, add items to a directory, and do lookups. + +### mod +The `mod` subpackage implements a `DagModifier` type that can be used to write to an existing unixfs file, or +create a new one. The logic for this is significantly more complicated than for the dagreader, so its a separate +type. (TODO: maybe it still belongs in the `io` subpackage though?) + +### hamt +The `hamt` subpackage implements a CHAMP hamt that is used in unixfs directory sharding. + +### archive +The `archive` subpackage implements a `tar` importer and exporter. The objects created here are not officially unixfs, +but in the future, this may be integrated more directly. + +### test +The `test` subpackage provides several utilities to make testing unixfs related things easier. + +## Install + +```sh +go get github.com/ipfs/go-unixfs +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Juan Batiz-Benet diff --git a/vendor/github.com/ipfs/go-unixfs/go.mod b/vendor/github.com/ipfs/go-unixfs/go.mod new file mode 100644 index 00000000..d44a3006 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/go.mod @@ -0,0 +1,15 @@ +module github.com/ipfs/go-unixfs + +require ( + github.com/Stebalien/go-bitfield v0.0.1 + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-ipfs-chunker v0.0.1 + github.com/ipfs/go-ipfs-files v0.0.3 + github.com/ipfs/go-ipfs-posinfo v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-ipld-format v0.0.2 + github.com/ipfs/go-merkledag v0.0.6 + github.com/multiformats/go-multihash v0.0.5 + github.com/spaolacci/murmur3 v1.1.0 +) diff --git a/vendor/github.com/ipfs/go-unixfs/go.sum b/vendor/github.com/ipfs/go-unixfs/go.sum new file mode 100644 index 00000000..9b8ea5f2 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/go.sum @@ -0,0 +1,402 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= +github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.0.9 h1:Dy0qvYlaOd2E2FOL2gApJ21qVjepJsGNNfstLrGf+0I= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.0.7 h1:VRRVjgahs7r//MdO7yY5DJ2/i2fmkKOnxfSyfuPjTm0= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= +github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.3 h1:ME+QnC3uOyla1ciRPezDW0ynQYK2ikOh9OCKAEg4uUA= +github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= +github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.0.1 h1:394mZeTLcbM/LDO12PneBYvkZAUA+nRnmC0lAzDXKOY= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2 h1:amzFztBQQQ69UA5+f7JRfoXF/z2l//MGfEDHVkS20+s= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.0.2 h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs= +github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-merkledag v0.0.6 h1:rYZc0yzhO7y1cKi3Rw425a2HhEJDdLvNOWsqtmO3PF0= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.0.4 h1:i0JprfjjILYcWM1xguO/1MCS8XKVxLSl+ECEVr6i8nw= +github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security v0.0.1 h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.2 h1:Ykz0lnNjxk+0SdslUmlLNyrleqdpS1S/VW+dxFdt74Y= +github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.0.30 h1:mwCWAusLhRGUzZ/VaCatsrEQTsuWExmXqVcvGBV72EQ= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= +github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= +github.com/libp2p/go-libp2p-blankhost v0.0.1 h1:/mZuuiwntNR8RywnCFlGHLKrKLYne+qciBpQXWqp5fk= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= +github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-host v0.0.3 h1:BB/1Z+4X0rjKP5lbQTmjEjLbDVbrcmLOlA6QDsN5/j4= +github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5 h1:KG/KNYL2tYzXAfMvQN5K1aAGTYSYUMJ1prgYa2/JI1E= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-loggables v0.0.1 h1:HVww9oAnINIxbt69LJNkxD8lnbfgteXR97Xm4p3l9ps= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-metrics v0.0.1 h1:yumdPC/P2VzINdmcKZd0pciSUCpou+s0lwYCjBbzQZU= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-mplex v0.1.1 h1:lSPS1VJ36P01gGO//KgcsmSah5uoC3X9r7WY5j+iP4c= +github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-net v0.0.2 h1:qP06u4TYXfl7uW/hzqPhlVVTSA2nw1B/bHBJaUnbh6M= +github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1 h1:LgD6+skofkOx8z6odD9+MZHKjupv3ng1u6KRhaADTnA= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= +github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-routing v0.0.1 h1:hPMAWktf9rYi3ME4MG48qE7dq1ofJxiQbfdvpNntjhc= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= +github.com/libp2p/go-libp2p-secio v0.0.3 h1:h3fPeDrej7bvvARnC2oSjAfcLZOaS4REZKgWCRQNpE4= +github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= +github.com/libp2p/go-libp2p-swarm v0.0.6 h1:gE0P/v2h+KEXtAi9YTw2UBOSODJ4m9VuuJ+ktc2LVUo= +github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.5 h1:pV6+UlRxyDpASSGD+60vMvdifSCby6JkJDfi+yUMHac= +github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4 h1:uGMOd14BL1oFlfb/cGfOxPjiTKBhzWV4aMjjoCF1Z1o= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= +github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= +github.com/libp2p/go-libp2p-yamux v0.1.3 h1:HmKvv2jWJ4GEm3iP7cEKjuw0POa6rK+Hcsu1FBKzpLc= +github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= +github.com/libp2p/go-maddr-filter v0.0.1 h1:apvYTg0aIxxQyBX+XHKOR+0+lYhGs1Yv+JmTH9nyl5I= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.4 h1:043XJ3Zr7/Oz5cfyUaJwxUZyP02TngTpt4oq8R5UizQ= +github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0 h1:3ToDXUzx8pDC6RfuOzGsUYP5roMDthbUKRdMRRhqAqY= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= +github.com/libp2p/go-stream-muxer-multistream v0.1.1 h1:DhHqb4nu1fQv/vQKeLAaZGmhLsUA4SF77IdYJiWE1d4= +github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= +github.com/libp2p/go-tcp-transport v0.0.4 h1:2iRu994wCT/iEz62F+c60FUoSkijNEQ0q2Itc+79XlQ= +github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= +github.com/libp2p/go-testutil v0.0.1 h1:Xg+O0G2HIMfHqBOBDcMS1iSZJ3GEcId4qOxCQvsGZHk= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= +github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4 h1:VSJ45BzqrVgR4clSx415y1rHH7QAGhGt71J0ZmhLYrc= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/go-unixfs/hamt/hamt.go b/vendor/github.com/ipfs/go-unixfs/hamt/hamt.go new file mode 100644 index 00000000..7947a2aa --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/hamt/hamt.go @@ -0,0 +1,677 @@ +// Package hamt implements a Hash Array Mapped Trie over ipfs merkledag nodes. +// It is implemented mostly as described in the wikipedia article on HAMTs, +// however the table size is variable (usually 256 in our usages) as opposed to +// 32 as suggested in the article. The hash function used is currently +// Murmur3, but this value is configurable (the datastructure reports which +// hash function its using). +// +// The one algorithmic change we implement that is not mentioned in the +// wikipedia article is the collapsing of empty shards. +// Given the following tree: ( '[' = shards, '{' = values ) +// [ 'A' ] -> [ 'B' ] -> { "ABC" } +// | L-> { "ABD" } +// L-> { "ASDF" } +// If we simply removed "ABC", we would end up with a tree where shard 'B' only +// has a single child. This causes two issues, the first, is that now we have +// an extra lookup required to get to "ABD". The second issue is that now we +// have a tree that contains only "ABD", but is not the same tree that we would +// get by simply inserting "ABD" into a new tree. To address this, we always +// check for empty shard nodes upon deletion and prune them to maintain a +// consistent tree, independent of insertion order. +package hamt + +import ( + "context" + "fmt" + "os" + + bitfield "github.com/Stebalien/go-bitfield" + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + dag "github.com/ipfs/go-merkledag" + format "github.com/ipfs/go-unixfs" +) + +const ( + // HashMurmur3 is the multiformats identifier for Murmur3 + HashMurmur3 uint64 = 0x22 +) + +func (ds *Shard) isValueNode() bool { + return ds.key != "" && ds.val != nil +} + +// A Shard represents the HAMT. It should be initialized with NewShard(). +type Shard struct { + cid cid.Cid + + childer *childer + + tableSize int + tableSizeLg2 int + + builder cid.Builder + hashFunc uint64 + + prefixPadStr string + maxpadlen int + + dserv ipld.DAGService + + // leaf node + key string + val *ipld.Link +} + +// NewShard creates a new, empty HAMT shard with the given size. +func NewShard(dserv ipld.DAGService, size int) (*Shard, error) { + ds, err := makeShard(dserv, size) + if err != nil { + return nil, err + } + + ds.hashFunc = HashMurmur3 + return ds, nil +} + +func makeShard(ds ipld.DAGService, size int) (*Shard, error) { + lg2s, err := logtwo(size) + if err != nil { + return nil, err + } + maxpadding := fmt.Sprintf("%X", size-1) + s := &Shard{ + tableSizeLg2: lg2s, + prefixPadStr: fmt.Sprintf("%%0%dX", len(maxpadding)), + maxpadlen: len(maxpadding), + childer: newChilder(ds, size), + tableSize: size, + dserv: ds, + } + + s.childer.sd = s + + return s, nil +} + +// NewHamtFromDag creates new a HAMT shard from the given DAG. +func NewHamtFromDag(dserv ipld.DAGService, nd ipld.Node) (*Shard, error) { + pbnd, ok := nd.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + fsn, err := format.FSNodeFromBytes(pbnd.Data()) + if err != nil { + return nil, err + } + + if fsn.Type() != format.THAMTShard { + return nil, fmt.Errorf("node was not a dir shard") + } + + if fsn.HashType() != HashMurmur3 { + return nil, fmt.Errorf("only murmur3 supported as hash function") + } + + size := int(fsn.Fanout()) + + ds, err := makeShard(dserv, size) + if err != nil { + return nil, err + } + + ds.childer.makeChilder(fsn.Data(), pbnd.Links()) + + ds.cid = pbnd.Cid() + ds.hashFunc = fsn.HashType() + ds.builder = pbnd.CidBuilder() + + return ds, nil +} + +// SetCidBuilder sets the CID Builder +func (ds *Shard) SetCidBuilder(builder cid.Builder) { + ds.builder = builder +} + +// CidBuilder gets the CID Builder, may be nil if unset +func (ds *Shard) CidBuilder() cid.Builder { + return ds.builder +} + +// Node serializes the HAMT structure into a merkledag node with unixfs formatting +func (ds *Shard) Node() (ipld.Node, error) { + out := new(dag.ProtoNode) + out.SetCidBuilder(ds.builder) + + sliceIndex := 0 + // TODO: optimized 'for each set bit' + for childIndex := 0; childIndex < ds.tableSize; childIndex++ { + if !ds.childer.has(childIndex) { + continue + } + + ch := ds.childer.child(sliceIndex) + if ch != nil { + clnk, err := ch.Link() + if err != nil { + return nil, err + } + + err = out.AddRawLink(ds.linkNamePrefix(childIndex)+ch.key, clnk) + if err != nil { + return nil, err + } + } else { + // child unloaded, just copy in link with updated name + lnk := ds.childer.link(sliceIndex) + label := lnk.Name[ds.maxpadlen:] + + err := out.AddRawLink(ds.linkNamePrefix(childIndex)+label, lnk) + if err != nil { + return nil, err + } + } + sliceIndex++ + } + + data, err := format.HAMTShardData(ds.childer.bitfield.Bytes(), uint64(ds.tableSize), HashMurmur3) + if err != nil { + return nil, err + } + + out.SetData(data) + + err = ds.dserv.Add(context.TODO(), out) + if err != nil { + return nil, err + } + + return out, nil +} + +func (ds *Shard) makeShardValue(lnk *ipld.Link) (*Shard, error) { + lnk2 := *lnk + s, err := makeShard(ds.dserv, ds.tableSize) + if err != nil { + return nil, err + } + + s.key = lnk.Name[ds.maxpadlen:] + s.val = &lnk2 + + return s, nil +} + +// Set sets 'name' = nd in the HAMT +func (ds *Shard) Set(ctx context.Context, name string, nd ipld.Node) error { + hv := &hashBits{b: hash([]byte(name))} + err := ds.dserv.Add(ctx, nd) + if err != nil { + return err + } + + lnk, err := ipld.MakeLink(nd) + if err != nil { + return err + } + lnk.Name = ds.linkNamePrefix(0) + name + + return ds.modifyValue(ctx, hv, name, lnk) +} + +// Remove deletes the named entry if it exists, this operation is idempotent. +func (ds *Shard) Remove(ctx context.Context, name string) error { + hv := &hashBits{b: hash([]byte(name))} + return ds.modifyValue(ctx, hv, name, nil) +} + +// Find searches for a child node by 'name' within this hamt +func (ds *Shard) Find(ctx context.Context, name string) (*ipld.Link, error) { + hv := &hashBits{b: hash([]byte(name))} + + var out *ipld.Link + err := ds.getValue(ctx, hv, name, func(sv *Shard) error { + out = sv.val + return nil + }) + if err != nil { + return nil, err + } + + return out, nil +} + +type linkType int + +const ( + invalidLink linkType = iota + shardLink + shardValueLink +) + +func (ds *Shard) childLinkType(lnk *ipld.Link) (linkType, error) { + if len(lnk.Name) < ds.maxpadlen { + return invalidLink, fmt.Errorf("invalid link name '%s'", lnk.Name) + } + if len(lnk.Name) == ds.maxpadlen { + return shardLink, nil + } + return shardValueLink, nil +} + +// Link returns a merklelink to this shard node +func (ds *Shard) Link() (*ipld.Link, error) { + if ds.isValueNode() { + return ds.val, nil + } + + nd, err := ds.Node() + if err != nil { + return nil, err + } + + err = ds.dserv.Add(context.TODO(), nd) + if err != nil { + return nil, err + } + + return ipld.MakeLink(nd) +} + +func (ds *Shard) getValue(ctx context.Context, hv *hashBits, key string, cb func(*Shard) error) error { + childIndex, err := hv.Next(ds.tableSizeLg2) + if err != nil { + return err + } + + if ds.childer.has(childIndex) { + child, err := ds.childer.get(ctx, ds.childer.sliceIndex(childIndex)) + if err != nil { + return err + } + + if child.isValueNode() { + if child.key == key { + return cb(child) + } + } else { + return child.getValue(ctx, hv, key, cb) + } + } + + return os.ErrNotExist +} + +// EnumLinks collects all links in the Shard. +func (ds *Shard) EnumLinks(ctx context.Context) ([]*ipld.Link, error) { + var links []*ipld.Link + + linkResults := ds.EnumLinksAsync(ctx) + + for linkResult := range linkResults { + if linkResult.Err != nil { + return links, linkResult.Err + } + links = append(links, linkResult.Link) + } + return links, nil +} + +// ForEachLink walks the Shard and calls the given function. +func (ds *Shard) ForEachLink(ctx context.Context, f func(*ipld.Link) error) error { + return ds.walkTrie(ctx, func(sv *Shard) error { + lnk := sv.val + lnk.Name = sv.key + + return f(lnk) + }) +} + +// EnumLinksAsync returns a channel which will receive Links in the directory +// as they are enumerated, where order is not gauranteed +func (ds *Shard) EnumLinksAsync(ctx context.Context) <-chan format.LinkResult { + linkResults := make(chan format.LinkResult) + ctx, cancel := context.WithCancel(ctx) + go func() { + defer close(linkResults) + defer cancel() + getLinks := makeAsyncTrieGetLinks(ds.dserv, linkResults) + cset := cid.NewSet() + err := dag.EnumerateChildrenAsync(ctx, getLinks, ds.cid, cset.Visit) + if err != nil { + emitResult(ctx, linkResults, format.LinkResult{Link: nil, Err: err}) + } + }() + return linkResults +} + +// makeAsyncTrieGetLinks builds a getLinks function that can be used with EnumerateChildrenAsync +// to iterate a HAMT shard. It takes an IPLD Dag Service to fetch nodes, and a call back that will get called +// on all links to leaf nodes in a HAMT tree, so they can be collected for an EnumLinks operation +func makeAsyncTrieGetLinks(dagService ipld.DAGService, linkResults chan<- format.LinkResult) dag.GetLinks { + + return func(ctx context.Context, currentCid cid.Cid) ([]*ipld.Link, error) { + node, err := dagService.Get(ctx, currentCid) + if err != nil { + return nil, err + } + directoryShard, err := NewHamtFromDag(dagService, node) + if err != nil { + return nil, err + } + + childShards := make([]*ipld.Link, 0, directoryShard.childer.length()) + links := directoryShard.childer.links + for idx := range directoryShard.childer.children { + lnk := links[idx] + lnkLinkType, err := directoryShard.childLinkType(lnk) + + if err != nil { + return nil, err + } + if lnkLinkType == shardLink { + childShards = append(childShards, lnk) + } else { + sv, err := directoryShard.makeShardValue(lnk) + if err != nil { + return nil, err + } + formattedLink := sv.val + formattedLink.Name = sv.key + emitResult(ctx, linkResults, format.LinkResult{Link: formattedLink, Err: nil}) + } + } + return childShards, nil + } +} + +func emitResult(ctx context.Context, linkResults chan<- format.LinkResult, r format.LinkResult) { + // make sure that context cancel is processed first + // the reason is due to the concurrency of EnumerateChildrenAsync + // it's possible for EnumLinksAsync to complete and close the linkResults + // channel before this code runs + select { + case <-ctx.Done(): + return + default: + } + select { + case linkResults <- r: + case <-ctx.Done(): + } +} + +func (ds *Shard) walkTrie(ctx context.Context, cb func(*Shard) error) error { + return ds.childer.each(ctx, func(s *Shard) error { + if s.isValueNode() { + if err := cb(s); err != nil { + return err + } + } else { + if err := s.walkTrie(ctx, cb); err != nil { + return err + } + } + return nil + }) +} + +func (ds *Shard) modifyValue(ctx context.Context, hv *hashBits, key string, val *ipld.Link) error { + idx, err := hv.Next(ds.tableSizeLg2) + if err != nil { + return err + } + + if !ds.childer.has(idx) { + return ds.childer.insert(key, val, idx) + } + + i := ds.childer.sliceIndex(idx) + + child, err := ds.childer.get(ctx, i) + if err != nil { + return err + } + + if child.isValueNode() { + if child.key == key { + // value modification + if val == nil { + return ds.childer.rm(idx) + } + + child.val = val + return nil + } + + if val == nil { + return os.ErrNotExist + } + + // replace value with another shard, one level deeper + ns, err := NewShard(ds.dserv, ds.tableSize) + if err != nil { + return err + } + ns.builder = ds.builder + chhv := &hashBits{ + b: hash([]byte(child.key)), + consumed: hv.consumed, + } + + err = ns.modifyValue(ctx, hv, key, val) + if err != nil { + return err + } + + err = ns.modifyValue(ctx, chhv, child.key, child.val) + if err != nil { + return err + } + + ds.childer.set(ns, i) + return nil + } else { + err := child.modifyValue(ctx, hv, key, val) + if err != nil { + return err + } + + if val == nil { + switch child.childer.length() { + case 0: + // empty sub-shard, prune it + // Note: this shouldnt normally ever happen + // in the event of another implementation creates flawed + // structures, this will help to normalize them. + return ds.childer.rm(idx) + case 1: + nchild := child.childer.children[0] + if nchild.isValueNode() { + // sub-shard with a single value element, collapse it + ds.childer.set(nchild, i) + } + return nil + } + } + + return nil + } +} + +// linkNamePrefix takes in the bitfield index of an entry and returns its hex prefix +func (ds *Shard) linkNamePrefix(idx int) string { + return fmt.Sprintf(ds.prefixPadStr, idx) +} + +// childer wraps the links, children and bitfield +// and provides basic operation (get, rm, insert and set) of manipulating children. +// The slices `links` and `children` are always coordinated to have the entries +// in the same index. A `childIndex` belonging to one of the original `Shard.size` +// entries corresponds to a `sliceIndex` in `links` and `children` (the conversion +// is done through `bitfield`). +type childer struct { + sd *Shard + dserv ipld.DAGService + bitfield bitfield.Bitfield + links []*ipld.Link + children []*Shard +} + +func newChilder(ds ipld.DAGService, size int) *childer { + return &childer{ + dserv: ds, + bitfield: bitfield.NewBitfield(size), + } +} + +func (s *childer) makeChilder(data []byte, links []*ipld.Link) *childer { + s.children = make([]*Shard, len(links)) + s.bitfield.SetBytes(data) + if len(links) > 0 { + s.links = make([]*ipld.Link, len(links)) + copy(s.links, links) + } + + return s +} + +// Return the `sliceIndex` associated with a child. +func (s *childer) sliceIndex(childIndex int) (sliceIndex int) { + return s.bitfield.OnesBefore(childIndex) +} + +func (s *childer) child(sliceIndex int) *Shard { + return s.children[sliceIndex] +} + +func (s *childer) link(sliceIndex int) *ipld.Link { + return s.links[sliceIndex] +} + +func (s *childer) insert(key string, lnk *ipld.Link, idx int) error { + if lnk == nil { + return os.ErrNotExist + } + + lnk.Name = s.sd.linkNamePrefix(idx) + key + i := s.sliceIndex(idx) + sd := &Shard{key: key, val: lnk} + + s.children = append(s.children[:i], append([]*Shard{sd}, s.children[i:]...)...) + s.links = append(s.links[:i], append([]*ipld.Link{nil}, s.links[i:]...)...) + // Add a `nil` placeholder in `links` so the rest of the entries keep the same + // index as `children`. + s.bitfield.SetBit(idx) + + return nil +} + +func (s *childer) set(sd *Shard, i int) { + s.children[i] = sd +} + +func (s *childer) rm(childIndex int) error { + i := s.sliceIndex(childIndex) + + if err := s.check(i); err != nil { + return err + } + + copy(s.children[i:], s.children[i+1:]) + s.children = s.children[:len(s.children)-1] + + copy(s.links[i:], s.links[i+1:]) + s.links = s.links[:len(s.links)-1] + + s.bitfield.UnsetBit(childIndex) + + return nil +} + +// get returns the i'th child of this shard. If it is cached in the +// children array, it will return it from there. Otherwise, it loads the child +// node from disk. +func (s *childer) get(ctx context.Context, sliceIndex int) (*Shard, error) { + if err := s.check(sliceIndex); err != nil { + return nil, err + } + + c := s.child(sliceIndex) + if c != nil { + return c, nil + } + + return s.loadChild(ctx, sliceIndex) +} + +// loadChild reads the i'th child node of this shard from disk and returns it +// as a 'child' interface +func (s *childer) loadChild(ctx context.Context, sliceIndex int) (*Shard, error) { + lnk := s.link(sliceIndex) + lnkLinkType, err := s.sd.childLinkType(lnk) + if err != nil { + return nil, err + } + + var c *Shard + if lnkLinkType == shardLink { + nd, err := lnk.GetNode(ctx, s.dserv) + if err != nil { + return nil, err + } + cds, err := NewHamtFromDag(s.dserv, nd) + if err != nil { + return nil, err + } + + c = cds + } else { + s, err := s.sd.makeShardValue(lnk) + if err != nil { + return nil, err + } + c = s + } + + s.set(c, sliceIndex) + + return c, nil +} + +func (s *childer) has(childIndex int) bool { + return s.bitfield.Bit(childIndex) +} + +func (s *childer) length() int { + return len(s.children) +} + +func (s *childer) each(ctx context.Context, cb func(*Shard) error) error { + for i := range s.children { + c, err := s.get(ctx, i) + if err != nil { + return err + } + + if err := cb(c); err != nil { + return err + } + } + + return nil +} + +func (s *childer) check(sliceIndex int) error { + if sliceIndex >= len(s.children) || sliceIndex < 0 { + return fmt.Errorf("invalid index passed to operate children (likely corrupt bitfield)") + } + + if len(s.children) != len(s.links) { + return fmt.Errorf("inconsistent lengths between children array and Links array") + } + + return nil +} diff --git a/vendor/github.com/ipfs/go-unixfs/hamt/util.go b/vendor/github.com/ipfs/go-unixfs/hamt/util.go new file mode 100644 index 00000000..7ae02dfb --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/hamt/util.go @@ -0,0 +1,68 @@ +package hamt + +import ( + "fmt" + + "github.com/spaolacci/murmur3" + "math/bits" +) + +// hashBits is a helper that allows the reading of the 'next n bits' as an integer. +type hashBits struct { + b []byte + consumed int +} + +func mkmask(n int) byte { + return (1 << uint(n)) - 1 +} + +// Next returns the next 'i' bits of the hashBits value as an integer, or an +// error if there aren't enough bits. +func (hb *hashBits) Next(i int) (int, error) { + if hb.consumed+i > len(hb.b)*8 { + return 0, fmt.Errorf("sharded directory too deep") + } + return hb.next(i), nil +} + +func (hb *hashBits) next(i int) int { + curbi := hb.consumed / 8 + leftb := 8 - (hb.consumed % 8) + + curb := hb.b[curbi] + if i == leftb { + out := int(mkmask(i) & curb) + hb.consumed += i + return out + } else if i < leftb { + a := curb & mkmask(leftb) // mask out the high bits we don't want + b := a & ^mkmask(leftb-i) // mask out the low bits we don't want + c := b >> uint(leftb-i) // shift whats left down + hb.consumed += i + return int(c) + } else { + out := int(mkmask(leftb) & curb) + out <<= uint(i - leftb) + hb.consumed += leftb + out += hb.next(i - leftb) + return out + } +} + +func logtwo(v int) (int, error) { + if v <= 0 { + return 0, fmt.Errorf("hamt size should be a power of two") + } + lg2 := bits.TrailingZeros(uint(v)) + if 1< BlockSizeLimit { + return nil, ErrSizeLimitExceeded + } + + if db.rawLeaves { + // Encapsulate the data in a raw node. + if db.cidBuilder == nil { + return dag.NewRawNode(data), nil + } + rawnode, err := dag.NewRawNodeWPrefix(data, db.cidBuilder) + if err != nil { + return nil, err + } + return rawnode, nil + } + + // Encapsulate the data in UnixFS node (instead of a raw node). + fsNodeOverDag := db.NewFSNodeOverDag(fsNodeType) + fsNodeOverDag.SetFileData(data) + node, err := fsNodeOverDag.Commit() + if err != nil { + return nil, err + } + // TODO: Encapsulate this sequence of calls into a function that + // just returns the final `ipld.Node` avoiding going through + // `FSNodeOverDag`. + + return node, nil +} + +// FillNodeLayer will add datanodes as children to the give node until +// it is full in this layer or no more data. +// NOTE: This function creates raw data nodes so it only works +// for the `trickle.Layout`. +func (db *DagBuilderHelper) FillNodeLayer(node *FSNodeOverDag) error { + + // while we have room AND we're not done + for node.NumChildren() < db.maxlinks && !db.Done() { + child, childFileSize, err := db.NewLeafDataNode(ft.TRaw) + if err != nil { + return err + } + + if err := node.AddChild(child, childFileSize, db); err != nil { + return err + } + } + node.Commit() + // TODO: Do we need to commit here? The caller who created the + // `FSNodeOverDag` should be in charge of that. + + return nil +} + +// NewLeafDataNode builds the `node` with the data obtained from the +// Splitter with the given constraints (BlockSizeLimit, RawLeaves) +// specified when creating the DagBuilderHelper. It returns +// `ipld.Node` with the `dataSize` (that will be used to keep track of +// the DAG file size). The size of the data is computed here because +// after that it will be hidden by `NewLeafNode` inside a generic +// `ipld.Node` representation. +func (db *DagBuilderHelper) NewLeafDataNode(fsNodeType pb.Data_DataType) (node ipld.Node, dataSize uint64, err error) { + fileData, err := db.Next() + if err != nil { + return nil, 0, err + } + dataSize = uint64(len(fileData)) + + // Create a new leaf node containing the file chunk data. + node, err = db.NewLeafNode(fileData, fsNodeType) + if err != nil { + return nil, 0, err + } + + // Convert this leaf to a `FilestoreNode` if needed. + node = db.ProcessFileStore(node, dataSize) + + return node, dataSize, nil +} + +// ProcessFileStore generates, if Filestore is being used, the +// `FilestoreNode` representation of the `ipld.Node` that +// contains the file data. If Filestore is not being used just +// return the same node to continue with its addition to the DAG. +// +// The `db.offset` is updated at this point (instead of when +// `NewLeafDataNode` is called, both work in tandem but the +// offset is more related to this function). +func (db *DagBuilderHelper) ProcessFileStore(node ipld.Node, dataSize uint64) ipld.Node { + // Check if Filestore is being used. + if db.fullPath != "" { + // Check if the node is actually a raw node (needed for + // Filestore support). + if _, ok := node.(*dag.RawNode); ok { + fn := &pi.FilestoreNode{ + Node: node, + PosInfo: &pi.PosInfo{ + Offset: db.offset, + FullPath: db.fullPath, + Stat: db.stat, + }, + } + + // Update `offset` with the size of the data generated by `db.Next`. + db.offset += dataSize + + return fn + } + } + + // Filestore is not used, return the same `node` argument. + return node +} + +// Add inserts the given node in the DAGService. +func (db *DagBuilderHelper) Add(node ipld.Node) error { + return db.dserv.Add(context.TODO(), node) +} + +// Maxlinks returns the configured maximum number for links +// for nodes built with this helper. +func (db *DagBuilderHelper) Maxlinks() int { + return db.maxlinks +} + +// FSNodeOverDag encapsulates an `unixfs.FSNode` that will be stored in a +// `dag.ProtoNode`. Instead of just having a single `ipld.Node` that +// would need to be constantly (un)packed to access and modify its +// internal `FSNode` in the process of creating a UnixFS DAG, this +// structure stores an `FSNode` cache to manipulate it (add child nodes) +// directly , and only when the node has reached its final (immutable) state +// (signaled by calling `Commit()`) is it committed to a single (indivisible) +// `ipld.Node`. +// +// It is used mainly for internal (non-leaf) nodes, and for some +// representations of data leaf nodes (that don't use raw nodes or +// Filestore). +// +// It aims to replace the `UnixfsNode` structure which encapsulated too +// many possible node state combinations. +// +// TODO: Revisit the name. +type FSNodeOverDag struct { + dag *dag.ProtoNode + file *ft.FSNode +} + +// NewFSNodeOverDag creates a new `dag.ProtoNode` and `ft.FSNode` +// decoupled from one onther (and will continue in that way until +// `Commit` is called), with `fsNodeType` specifying the type of +// the UnixFS layer node (either `File` or `Raw`). +func (db *DagBuilderHelper) NewFSNodeOverDag(fsNodeType pb.Data_DataType) *FSNodeOverDag { + node := new(FSNodeOverDag) + node.dag = new(dag.ProtoNode) + node.dag.SetCidBuilder(db.GetCidBuilder()) + + node.file = ft.NewFSNode(fsNodeType) + + return node +} + +// NewFSNFromDag reconstructs a FSNodeOverDag node from a given dag node +func (db *DagBuilderHelper) NewFSNFromDag(nd *dag.ProtoNode) (*FSNodeOverDag, error) { + return NewFSNFromDag(nd) +} + +// NewFSNFromDag reconstructs a FSNodeOverDag node from a given dag node +func NewFSNFromDag(nd *dag.ProtoNode) (*FSNodeOverDag, error) { + mb, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return nil, err + } + + return &FSNodeOverDag{ + dag: nd, + file: mb, + }, nil +} + +// AddChild adds a `child` `ipld.Node` to both node layers. The +// `dag.ProtoNode` creates a link to the child node while the +// `ft.FSNode` stores its file size (that is, not the size of the +// node but the size of the file data that it is storing at the +// UnixFS layer). The child is also stored in the `DAGService`. +func (n *FSNodeOverDag) AddChild(child ipld.Node, fileSize uint64, db *DagBuilderHelper) error { + err := n.dag.AddNodeLink("", child) + if err != nil { + return err + } + + n.file.AddBlockSize(fileSize) + + return db.Add(child) +} + +// RemoveChild deletes the child node at the given index. +func (n *FSNodeOverDag) RemoveChild(index int, dbh *DagBuilderHelper) { + n.file.RemoveBlockSize(index) + n.dag.SetLinks(append(n.dag.Links()[:index], n.dag.Links()[index+1:]...)) +} + +// Commit unifies (resolves) the cache nodes into a single `ipld.Node` +// that represents them: the `ft.FSNode` is encoded inside the +// `dag.ProtoNode`. +// +// TODO: Make it read-only after committing, allow to commit only once. +func (n *FSNodeOverDag) Commit() (ipld.Node, error) { + fileData, err := n.file.GetBytes() + if err != nil { + return nil, err + } + n.dag.SetData(fileData) + + return n.dag, nil +} + +// NumChildren returns the number of children of the `ft.FSNode`. +func (n *FSNodeOverDag) NumChildren() int { + return n.file.NumChildren() +} + +// FileSize returns the `Filesize` attribute from the underlying +// representation of the `ft.FSNode`. +func (n *FSNodeOverDag) FileSize() uint64 { + return n.file.FileSize() +} + +// SetFileData stores the `fileData` in the `ft.FSNode`. It +// should be used only when `FSNodeOverDag` represents a leaf +// node (internal nodes don't carry data, just file sizes). +func (n *FSNodeOverDag) SetFileData(fileData []byte) { + n.file.SetData(fileData) +} + +// GetDagNode fills out the proper formatting for the FSNodeOverDag node +// inside of a DAG node and returns the dag node. +// TODO: Check if we have committed (passed the UnixFS information +// to the DAG layer) before returning this. +func (n *FSNodeOverDag) GetDagNode() (ipld.Node, error) { + return n.dag, nil +} + +// GetChild gets the ith child of this node from the given DAGService. +func (n *FSNodeOverDag) GetChild(ctx context.Context, i int, ds ipld.DAGService) (*FSNodeOverDag, error) { + nd, err := n.dag.Links()[i].GetNode(ctx, ds) + if err != nil { + return nil, err + } + + pbn, ok := nd.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + return NewFSNFromDag(pbn) +} diff --git a/vendor/github.com/ipfs/go-unixfs/importer/helpers/helpers.go b/vendor/github.com/ipfs/go-unixfs/importer/helpers/helpers.go new file mode 100644 index 00000000..075b2d2d --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/importer/helpers/helpers.go @@ -0,0 +1,30 @@ +package helpers + +import ( + "fmt" +) + +// BlockSizeLimit specifies the maximum size an imported block can have. +var BlockSizeLimit = 1048576 // 1 MB + +// rough estimates on expected sizes +var roughLinkBlockSize = 1 << 13 // 8KB +var roughLinkSize = 34 + 8 + 5 // sha256 multihash + size + no name + protobuf framing + +// DefaultLinksPerBlock governs how the importer decides how many links there +// will be per block. This calculation is based on expected distributions of: +// * the expected distribution of block sizes +// * the expected distribution of link sizes +// * desired access speed +// For now, we use: +// +// var roughLinkBlockSize = 1 << 13 // 8KB +// var roughLinkSize = 34 + 8 + 5 // sha256 multihash + size + no name +// // + protobuf framing +// var DefaultLinksPerBlock = (roughLinkBlockSize / roughLinkSize) +// = ( 8192 / 47 ) +// = (approximately) 174 +var DefaultLinksPerBlock = roughLinkBlockSize / roughLinkSize + +// ErrSizeLimitExceeded signals that a block is larger than BlockSizeLimit. +var ErrSizeLimitExceeded = fmt.Errorf("object size limit exceeded") diff --git a/vendor/github.com/ipfs/go-unixfs/importer/trickle/trickledag.go b/vendor/github.com/ipfs/go-unixfs/importer/trickle/trickledag.go new file mode 100644 index 00000000..3a631adb --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/importer/trickle/trickledag.go @@ -0,0 +1,389 @@ +// Package trickle allows to build trickle DAGs. +// In this type of DAG, non-leave nodes are first filled +// with data leaves, and then incorporate "layers" of subtrees +// as additional links. +// +// Each layer is a trickle sub-tree and is limited by an increasing +// maximum depth. Thus, the nodes first layer +// can only hold leaves (depth 1) but subsequent layers can grow deeper. +// By default, this module places 4 nodes per layer (that is, 4 subtrees +// of the same maximum depth before increasing it). +// +// Trickle DAGs are very good for sequentially reading data, as the +// first data leaves are directly reachable from the root and those +// coming next are always nearby. They are +// suited for things like streaming applications. +package trickle + +import ( + "context" + "errors" + "fmt" + + ft "github.com/ipfs/go-unixfs" + h "github.com/ipfs/go-unixfs/importer/helpers" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" + dag "github.com/ipfs/go-merkledag" +) + +// depthRepeat specifies how many times to append a child tree of a +// given depth. Higher values increase the width of a given node, which +// improves seek speeds. +const depthRepeat = 4 + +// Layout builds a new DAG with the trickle format using the provided +// DagBuilderHelper. See the module's description for a more detailed +// explanation. +func Layout(db *h.DagBuilderHelper) (ipld.Node, error) { + newRoot := db.NewFSNodeOverDag(ft.TFile) + root, _, err := fillTrickleRec(db, newRoot, -1) + if err != nil { + return nil, err + } + + return root, db.Add(root) +} + +// fillTrickleRec creates a trickle (sub-)tree with an optional maximum specified depth +// in the case maxDepth is greater than zero, or with unlimited depth otherwise +// (where the DAG builder will signal the end of data to end the function). +func fillTrickleRec(db *h.DagBuilderHelper, node *h.FSNodeOverDag, maxDepth int) (filledNode ipld.Node, nodeFileSize uint64, err error) { + // Always do this, even in the base case + if err := db.FillNodeLayer(node); err != nil { + return nil, 0, err + } + + // For each depth in [1, `maxDepth`) (or without limit if `maxDepth` is -1, + // initial call from `Layout`) add `depthRepeat` sub-graphs of that depth. + for depth := 1; maxDepth == -1 || depth < maxDepth; depth++ { + if db.Done() { + break + // No more data, stop here, posterior append calls will figure out + // where we left off. + } + + for repeatIndex := 0; repeatIndex < depthRepeat && !db.Done(); repeatIndex++ { + + childNode, childFileSize, err := fillTrickleRec(db, db.NewFSNodeOverDag(ft.TFile), depth) + if err != nil { + return nil, 0, err + } + + if err := node.AddChild(childNode, childFileSize, db); err != nil { + return nil, 0, err + } + } + } + + // Get the final `dag.ProtoNode` with the `FSNode` data encoded inside. + filledNode, err = node.Commit() + if err != nil { + return nil, 0, err + } + + return filledNode, node.FileSize(), nil +} + +// Append appends the data in `db` to the dag, using the Trickledag format +func Append(ctx context.Context, basen ipld.Node, db *h.DagBuilderHelper) (out ipld.Node, errOut error) { + base, ok := basen.(*dag.ProtoNode) + if !ok { + return nil, dag.ErrNotProtobuf + } + + // Convert to unixfs node for working with easily + + fsn, err := h.NewFSNFromDag(base) + if err != nil { + return nil, err + } + + // Get depth of this 'tree' + depth, repeatNumber := trickleDepthInfo(fsn, db.Maxlinks()) + if depth == 0 { + // If direct blocks not filled... + if err := db.FillNodeLayer(fsn); err != nil { + return nil, err + } + + if db.Done() { + // TODO: If `FillNodeLayer` stop `Commit`ing this should be + // the place (besides the function end) to call it. + return fsn.GetDagNode() + } + + // If continuing, our depth has increased by one + depth++ + } + + // Last child in this node may not be a full tree, lets fill it up. + if err := appendFillLastChild(ctx, fsn, depth-1, repeatNumber, db); err != nil { + return nil, err + } + + // after appendFillLastChild, our depth is now increased by one + if !db.Done() { + depth++ + } + + // Now, continue filling out tree like normal + for i := depth; !db.Done(); i++ { + for j := 0; j < depthRepeat && !db.Done(); j++ { + nextChild := db.NewFSNodeOverDag(ft.TFile) + childNode, childFileSize, err := fillTrickleRec(db, nextChild, i) + if err != nil { + return nil, err + } + err = fsn.AddChild(childNode, childFileSize, db) + if err != nil { + return nil, err + } + } + } + _, err = fsn.Commit() + if err != nil { + return nil, err + } + return fsn.GetDagNode() +} + +func appendFillLastChild(ctx context.Context, fsn *h.FSNodeOverDag, depth int, repeatNumber int, db *h.DagBuilderHelper) error { + if fsn.NumChildren() <= db.Maxlinks() { + return nil + } + // TODO: Why do we need this check, didn't the caller already take + // care of this? + + // Recursive step, grab last child + last := fsn.NumChildren() - 1 + lastChild, err := fsn.GetChild(ctx, last, db.GetDagServ()) + if err != nil { + return err + } + + // Fill out last child (may not be full tree) + newChild, nchildSize, err := appendRec(ctx, lastChild, db, depth-1) + if err != nil { + return err + } + + // Update changed child in parent node + fsn.RemoveChild(last, db) + filledNode, err := newChild.Commit() + if err != nil { + return err + } + err = fsn.AddChild(filledNode, nchildSize, db) + if err != nil { + return err + } + + // Partially filled depth layer + if repeatNumber != 0 { + for ; repeatNumber < depthRepeat && !db.Done(); repeatNumber++ { + nextChild := db.NewFSNodeOverDag(ft.TFile) + childNode, childFileSize, err := fillTrickleRec(db, nextChild, depth) + if err != nil { + return err + } + + if err := fsn.AddChild(childNode, childFileSize, db); err != nil { + return err + } + } + } + + return nil +} + +// recursive call for Append +func appendRec(ctx context.Context, fsn *h.FSNodeOverDag, db *h.DagBuilderHelper, maxDepth int) (*h.FSNodeOverDag, uint64, error) { + if maxDepth == 0 || db.Done() { + return fsn, fsn.FileSize(), nil + } + + // Get depth of this 'tree' + depth, repeatNumber := trickleDepthInfo(fsn, db.Maxlinks()) + if depth == 0 { + // If direct blocks not filled... + if err := db.FillNodeLayer(fsn); err != nil { + return nil, 0, err + } + depth++ + } + // TODO: Same as `appendFillLastChild`, when is this case possible? + + // If at correct depth, no need to continue + if depth == maxDepth { + return fsn, fsn.FileSize(), nil + } + + if err := appendFillLastChild(ctx, fsn, depth, repeatNumber, db); err != nil { + return nil, 0, err + } + + // after appendFillLastChild, our depth is now increased by one + if !db.Done() { + depth++ + } + + // Now, continue filling out tree like normal + for i := depth; i < maxDepth && !db.Done(); i++ { + for j := 0; j < depthRepeat && !db.Done(); j++ { + nextChild := db.NewFSNodeOverDag(ft.TFile) + childNode, childFileSize, err := fillTrickleRec(db, nextChild, i) + if err != nil { + return nil, 0, err + } + + if err := fsn.AddChild(childNode, childFileSize, db); err != nil { + return nil, 0, err + } + } + } + + return fsn, fsn.FileSize(), nil +} + +// Deduce where we left off in `fillTrickleRec`, returns the `depth` +// with which new sub-graphs were being added and, within that depth, +// in which `repeatNumber` of the total `depthRepeat` we should add. +func trickleDepthInfo(node *h.FSNodeOverDag, maxlinks int) (depth int, repeatNumber int) { + n := node.NumChildren() + + if n < maxlinks { + // We didn't even added the initial `maxlinks` leaf nodes (`FillNodeLayer`). + return 0, 0 + } + + nonLeafChildren := n - maxlinks + // The number of non-leaf child nodes added in `fillTrickleRec` (after + // the `FillNodeLayer` call). + + depth = nonLeafChildren/depthRepeat + 1 + // "Deduplicate" the added `depthRepeat` sub-graphs at each depth + // (rounding it up since we may be on an unfinished depth with less + // than `depthRepeat` sub-graphs). + + repeatNumber = nonLeafChildren % depthRepeat + // What's left after taking full depths of `depthRepeat` sub-graphs + // is the current `repeatNumber` we're at (this fractional part is + // what we rounded up before). + + return +} + +// VerifyParams is used by VerifyTrickleDagStructure +type VerifyParams struct { + Getter ipld.NodeGetter + Direct int + LayerRepeat int + Prefix *cid.Prefix + RawLeaves bool +} + +// VerifyTrickleDagStructure checks that the given dag matches exactly the trickle dag datastructure +// layout +func VerifyTrickleDagStructure(nd ipld.Node, p VerifyParams) error { + return verifyTDagRec(nd, -1, p) +} + +// Recursive call for verifying the structure of a trickledag +func verifyTDagRec(n ipld.Node, depth int, p VerifyParams) error { + codec := cid.DagProtobuf + if depth == 0 { + if len(n.Links()) > 0 { + return errors.New("expected direct block") + } + // zero depth dag is raw data block + switch nd := n.(type) { + case *dag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return err + } + + if fsn.Type() != ft.TRaw { + return errors.New("expected raw block") + } + + if p.RawLeaves { + return errors.New("expected raw leaf, got a protobuf node") + } + case *dag.RawNode: + if !p.RawLeaves { + return errors.New("expected protobuf node as leaf") + } + codec = cid.Raw + default: + return errors.New("expected ProtoNode or RawNode") + } + } + + // verify prefix + if p.Prefix != nil { + prefix := n.Cid().Prefix() + expect := *p.Prefix // make a copy + expect.Codec = uint64(codec) + if codec == cid.Raw && expect.Version == 0 { + expect.Version = 1 + } + if expect.MhLength == -1 { + expect.MhLength = prefix.MhLength + } + if prefix != expect { + return fmt.Errorf("unexpected cid prefix: expected: %v; got %v", expect, prefix) + } + } + + if depth == 0 { + return nil + } + + nd, ok := n.(*dag.ProtoNode) + if !ok { + return errors.New("expected ProtoNode") + } + + // Verify this is a branch node + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return err + } + + if fsn.Type() != ft.TFile { + return fmt.Errorf("expected file as branch node, got: %s", fsn.Type()) + } + + if len(fsn.Data()) > 0 { + return errors.New("branch node should not have data") + } + + for i := 0; i < len(nd.Links()); i++ { + child, err := nd.Links()[i].GetNode(context.TODO(), p.Getter) + if err != nil { + return err + } + + if i < p.Direct { + // Direct blocks + err := verifyTDagRec(child, 0, p) + if err != nil { + return err + } + } else { + // Recursive trickle dags + rdepth := ((i - p.Direct) / p.LayerRepeat) + 1 + if rdepth >= depth && depth > 0 { + return errors.New("child dag was too deep") + } + err := verifyTDagRec(child, rdepth, p) + if err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/ipfs/go-unixfs/io/dagreader.go b/vendor/github.com/ipfs/go-unixfs/io/dagreader.go new file mode 100644 index 00000000..75fb5c71 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/io/dagreader.go @@ -0,0 +1,491 @@ +package io + +import ( + "bytes" + "context" + "errors" + "io" + + ipld "github.com/ipfs/go-ipld-format" + mdag "github.com/ipfs/go-merkledag" + unixfs "github.com/ipfs/go-unixfs" +) + +// Common errors +var ( + ErrIsDir = errors.New("this dag node is a directory") + ErrCantReadSymlinks = errors.New("cannot currently read symlinks") + ErrUnkownNodeType = errors.New("unknown node type") +) + +// TODO: Rename the `DagReader` interface, this doesn't read *any* DAG, just +// DAGs with UnixFS node (and it *belongs* to the `unixfs` package). Some +// alternatives: `FileReader`, `UnixFSFileReader`, `UnixFSReader`. + +// A DagReader provides read-only read and seek acess to a unixfs file. +// Different implementations of readers are used for the different +// types of unixfs/protobuf-encoded nodes. +type DagReader interface { + ReadSeekCloser + Size() uint64 + CtxReadFull(context.Context, []byte) (int, error) +} + +// A ReadSeekCloser implements interfaces to read, copy, seek and close. +type ReadSeekCloser interface { + io.Reader + io.Seeker + io.Closer + io.WriterTo +} + +// NewDagReader creates a new reader object that reads the data represented by +// the given node, using the passed in DAGService for data retrieval. +func NewDagReader(ctx context.Context, n ipld.Node, serv ipld.NodeGetter) (DagReader, error) { + var size uint64 + + switch n := n.(type) { + case *mdag.RawNode: + size = uint64(len(n.RawData())) + + case *mdag.ProtoNode: + fsNode, err := unixfs.FSNodeFromBytes(n.Data()) + if err != nil { + return nil, err + } + + switch fsNode.Type() { + case unixfs.TFile, unixfs.TRaw: + size = fsNode.FileSize() + + case unixfs.TDirectory, unixfs.THAMTShard: + // Dont allow reading directories + return nil, ErrIsDir + + case unixfs.TMetadata: + if len(n.Links()) == 0 { + return nil, errors.New("incorrectly formatted metadata object") + } + child, err := n.Links()[0].GetNode(ctx, serv) + if err != nil { + return nil, err + } + + childpb, ok := child.(*mdag.ProtoNode) + if !ok { + return nil, mdag.ErrNotProtobuf + } + return NewDagReader(ctx, childpb, serv) + case unixfs.TSymlink: + return nil, ErrCantReadSymlinks + default: + return nil, unixfs.ErrUnrecognizedType + } + default: + return nil, ErrUnkownNodeType + } + + ctxWithCancel, cancel := context.WithCancel(ctx) + + return &dagReader{ + ctx: ctxWithCancel, + cancel: cancel, + serv: serv, + size: size, + rootNode: n, + dagWalker: ipld.NewWalker(ctxWithCancel, ipld.NewNavigableIPLDNode(n, serv)), + }, nil +} + +// dagReader provides a way to easily read the data contained in a dag. +type dagReader struct { + + // Structure to perform the DAG iteration and search, the reader + // just needs to add logic to the `Visitor` callback passed to + // `Iterate` and `Seek`. + dagWalker *ipld.Walker + + // Buffer with the data extracted from the current node being visited. + // To avoid revisiting a node to complete a (potential) partial read + // (or read after seek) the node's data is fully extracted in a single + // `readNodeDataBuffer` operation. + currentNodeData *bytes.Reader + + // Implements the `Size()` API. + size uint64 + + // Current offset for the read head within the DAG file. + offset int64 + + // Root node of the DAG, stored to re-create the `dagWalker` (effectively + // re-setting the position of the reader, used during `Seek`). + rootNode ipld.Node + + // Context passed to the `dagWalker`, the `cancel` function is used to + // cancel read operations (cancelling requested child node promises, + // see `ipld.NavigableIPLDNode.FetchChild` for details). + ctx context.Context + cancel func() + + // Passed to the `dagWalker` that will use it to request nodes. + // TODO: Revisit name. + serv ipld.NodeGetter +} + +// Size returns the total size of the data from the DAG structured file. +func (dr *dagReader) Size() uint64 { + return dr.size +} + +// Read implements the `io.Reader` interface through the `CtxReadFull` +// method using the DAG reader's internal context. +func (dr *dagReader) Read(b []byte) (int, error) { + return dr.CtxReadFull(dr.ctx, b) +} + +// CtxReadFull reads data from the DAG structured file. It always +// attempts a full read of the DAG until the `out` buffer is full. +// It uses the `Walker` structure to iterate the file DAG and read +// every node's data into the `out` buffer. +func (dr *dagReader) CtxReadFull(ctx context.Context, out []byte) (n int, err error) { + // Set the `dagWalker`'s context to the `ctx` argument, it will be used + // to fetch the child node promises (see + // `ipld.NavigableIPLDNode.FetchChild` for details). + dr.dagWalker.SetContext(ctx) + + // If there was a partially read buffer from the last visited + // node read it before visiting a new one. + if dr.currentNodeData != nil { + // TODO: Move this check inside `readNodeDataBuffer`? + n = dr.readNodeDataBuffer(out) + + if n == len(out) { + return n, nil + // Output buffer full, no need to traverse the DAG. + } + } + + // Iterate the DAG calling the passed `Visitor` function on every node + // to read its data into the `out` buffer, stop if there is an error or + // if the entire DAG is traversed (`EndOfDag`). + err = dr.dagWalker.Iterate(func(visitedNode ipld.NavigableNode) error { + node := ipld.ExtractIPLDNode(visitedNode) + + // Skip internal nodes, they shouldn't have any file data + // (see the `balanced` package for more details). + if len(node.Links()) > 0 { + return nil + } + + err = dr.saveNodeData(node) + if err != nil { + return err + } + // Save the leaf node file data in a buffer in case it is only + // partially read now and future `CtxReadFull` calls reclaim the + // rest (as each node is visited only once during `Iterate`). + // + // TODO: We could check if the entire node's data can fit in the + // remaining `out` buffer free space to skip this intermediary step. + + n += dr.readNodeDataBuffer(out[n:]) + + if n == len(out) { + // Output buffer full, no need to keep traversing the DAG, + // signal the `Walker` to pause the iteration. + dr.dagWalker.Pause() + } + + return nil + }) + + if err == ipld.EndOfDag { + return n, io.EOF + // Reached the end of the (DAG) file, no more data to read. + } else if err != nil { + return n, err + // Pass along any other errors from the `Visitor`. + } + + return n, nil +} + +// Save the UnixFS `node`'s data into the internal `currentNodeData` buffer to +// later move it to the output buffer (`Read`) or seek into it (`Seek`). +func (dr *dagReader) saveNodeData(node ipld.Node) error { + extractedNodeData, err := unixfs.ReadUnixFSNodeData(node) + if err != nil { + return err + } + + dr.currentNodeData = bytes.NewReader(extractedNodeData) + return nil +} + +// Read the `currentNodeData` buffer into `out`. This function can't have +// any errors as it's always reading from a `bytes.Reader` and asking only +// the available data in it. +func (dr *dagReader) readNodeDataBuffer(out []byte) int { + + n, _ := dr.currentNodeData.Read(out) + // Ignore the error as the EOF may not be returned in the first + // `Read` call, explicitly ask for an empty buffer below to check + // if we've reached the end. + + if dr.currentNodeData.Len() == 0 { + dr.currentNodeData = nil + // Signal that the buffer was consumed (for later `Read` calls). + // This shouldn't return an EOF error as it's just the end of a + // single node's data, not the entire DAG. + } + + dr.offset += int64(n) + // TODO: Should `offset` be incremented here or in the calling function? + // (Doing it here saves LoC but may be confusing as it's more hidden). + + return n +} + +// Similar to `readNodeDataBuffer` but it writes the contents to +// an `io.Writer` argument. +// +// TODO: Check what part of the logic between the two functions +// can be extracted away. +func (dr *dagReader) writeNodeDataBuffer(w io.Writer) (int64, error) { + + n, err := dr.currentNodeData.WriteTo(w) + if err != nil { + return n, err + } + + if dr.currentNodeData.Len() == 0 { + dr.currentNodeData = nil + // Signal that the buffer was consumed (for later `Read` calls). + // This shouldn't return an EOF error as it's just the end of a + // single node's data, not the entire DAG. + } + + dr.offset += int64(n) + return n, nil +} + +// WriteTo writes to the given writer. +// This follows the `bytes.Reader.WriteTo` implementation +// where it starts from the internal index that may have +// been modified by other `Read` calls. +// +// TODO: This implementation is very similar to `CtxReadFull`, +// the common parts should be abstracted away. +func (dr *dagReader) WriteTo(w io.Writer) (n int64, err error) { + // Use the internal reader's context to fetch the child node promises + // (see `ipld.NavigableIPLDNode.FetchChild` for details). + dr.dagWalker.SetContext(dr.ctx) + + // If there was a partially read buffer from the last visited + // node read it before visiting a new one. + if dr.currentNodeData != nil { + n, err = dr.writeNodeDataBuffer(w) + if err != nil { + return n, err + } + } + + // Iterate the DAG calling the passed `Visitor` function on every node + // to read its data into the `out` buffer, stop if there is an error or + // if the entire DAG is traversed (`EndOfDag`). + err = dr.dagWalker.Iterate(func(visitedNode ipld.NavigableNode) error { + node := ipld.ExtractIPLDNode(visitedNode) + + // Skip internal nodes, they shouldn't have any file data + // (see the `balanced` package for more details). + if len(node.Links()) > 0 { + return nil + } + + err = dr.saveNodeData(node) + if err != nil { + return err + } + // Save the leaf node file data in a buffer in case it is only + // partially read now and future `CtxReadFull` calls reclaim the + // rest (as each node is visited only once during `Iterate`). + + written, err := dr.writeNodeDataBuffer(w) + n += written + if err != nil { + return err + } + + return nil + }) + + if err == ipld.EndOfDag { + return n, nil + } + + return n, err +} + +// Close the reader (cancelling fetch node operations requested with +// the internal context, that is, `Read` calls but not `CtxReadFull` +// with user-supplied contexts). +func (dr *dagReader) Close() error { + dr.cancel() + return nil +} + +// Seek implements `io.Seeker` seeking to a given offset in the DAG file, +// it matches the standard unix `seek`. It moves the position of the internal +// `dagWalker` and may also leave a `currentNodeData` buffer loaded in case +// the seek is performed to the middle of the data in a node. +// +// TODO: Support seeking from the current position (relative seek) +// through the `dagWalker` in `io.SeekCurrent`. +func (dr *dagReader) Seek(offset int64, whence int) (int64, error) { + switch whence { + case io.SeekStart: + if offset < 0 { + return -1, errors.New("invalid offset") + } + + if offset == dr.offset { + return offset, nil + // Already at the requested `offset`, nothing to do. + } + + left := offset + // Amount left to seek. + + // Seek from the beginning of the DAG. + dr.resetPosition() + + // Use the internal reader's context to fetch the child node promises + // (see `ipld.NavigableIPLDNode.FetchChild` for details). + dr.dagWalker.SetContext(dr.ctx) + // TODO: Performance: we could adjust here `preloadSize` of + // `ipld.NavigableIPLDNode` also, when seeking we only want + // to fetch one child at a time. + + // Seek the DAG by calling the provided `Visitor` function on every + // node the `dagWalker` descends to while searching which can be + // either an internal or leaf node. In the internal node case, check + // the child node sizes and set the corresponding child index to go + // down to next. In the leaf case (last visit of the search), if there + // is still an amount `left` to seek do it inside the node's data + // saved in the `currentNodeData` buffer, leaving it ready for a `Read` + // call. + err := dr.dagWalker.Seek(func(visitedNode ipld.NavigableNode) error { + node := ipld.ExtractIPLDNode(visitedNode) + + if len(node.Links()) > 0 { + // Internal node, should be a `mdag.ProtoNode` containing a + // `unixfs.FSNode` (see the `balanced` package for more details). + fsNode, err := unixfs.ExtractFSNode(node) + if err != nil { + return err + } + + // If there aren't enough size hints don't seek + // (see the `io.EOF` handling error comment below). + if fsNode.NumChildren() != len(node.Links()) { + return io.EOF + } + + // Internal nodes have no data, so just iterate through the + // sizes of its children (advancing the child index of the + // `dagWalker`) to find where we need to go down to next in + // the search. + for { + childSize := fsNode.BlockSize(int(dr.dagWalker.ActiveChildIndex())) + + if childSize > uint64(left) { + // This child's data contains the position requested + // in `offset`, go down this child. + return nil + } + + // Else, skip this child. + left -= int64(childSize) + err := dr.dagWalker.NextChild() + if err == ipld.ErrNextNoChild { + // No more child nodes available, nothing to do, + // the `Seek` will stop on its own. + return nil + } else if err != nil { + return err + // Pass along any other errors (that may in future + // implementations be returned by `Next`) to stop + // the search. + } + } + + } else { + // Leaf node, seek inside its data. + err := dr.saveNodeData(node) + if err != nil { + return err + } + + _, err = dr.currentNodeData.Seek(left, io.SeekStart) + if err != nil { + return err + } + // The corner case of a DAG consisting only of a single (leaf) + // node should make no difference here. In that case, where the + // node doesn't have a parent UnixFS node with size hints, this + // implementation would allow this `Seek` to be called with an + // argument larger than the buffer size which normally wouldn't + // happen (because we would skip the node based on the size + // hint) but that would just mean that a future `CtxReadFull` + // call would read no data from the `currentNodeData` buffer. + // TODO: Re-check this reasoning. + + return nil + // In the leaf node case the search will stop here. + } + }) + + if err == io.EOF { + // TODO: Taken from https://github.com/ipfs/go-ipfs/pull/4320, + // check if still valid. + // Return negative number if we can't figure out the file size. Using io.EOF + // for this seems to be good(-enough) solution as it's only returned by + // precalcNextBuf when we step out of file range. + // This is needed for gateway to function properly + return -1, nil + } + + if err != nil { + return 0, err + } + + dr.offset = offset + return dr.offset, nil + + case io.SeekCurrent: + if offset == 0 { + return dr.offset, nil + } + + return dr.Seek(dr.offset+offset, io.SeekStart) + // TODO: Performance. This can be improved supporting relative + // searches in the `Walker` (see `Walker.Seek`). + + case io.SeekEnd: + return dr.Seek(int64(dr.Size())+offset, io.SeekStart) + + default: + return 0, errors.New("invalid whence") + } +} + +// Reset the reader position by resetting the `dagWalker` and discarding +// any partially used node's data in the `currentNodeData` buffer, used +// in the `SeekStart` case. +func (dr *dagReader) resetPosition() { + dr.currentNodeData = nil + + dr.dagWalker = ipld.NewWalker(dr.ctx, ipld.NewNavigableIPLDNode(dr.rootNode, dr.serv)) + // TODO: This could be avoided (along with storing the `dr.rootNode` and + // `dr.serv` just for this call) if `Reset` is supported in the `Walker`. +} diff --git a/vendor/github.com/ipfs/go-unixfs/io/directory.go b/vendor/github.com/ipfs/go-unixfs/io/directory.go new file mode 100644 index 00000000..2e022762 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/io/directory.go @@ -0,0 +1,288 @@ +package io + +import ( + "context" + "fmt" + "os" + + mdag "github.com/ipfs/go-merkledag" + + format "github.com/ipfs/go-unixfs" + hamt "github.com/ipfs/go-unixfs/hamt" + + cid "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// UseHAMTSharding is a global flag that signifies whether or not to use the +// HAMT sharding scheme for directory creation +var UseHAMTSharding = false + +// DefaultShardWidth is the default value used for hamt sharding width. +var DefaultShardWidth = 256 + +// Directory defines a UnixFS directory. It is used for creating, reading and +// editing directories. It allows to work with different directory schemes, +// like the basic or the HAMT implementation. +// +// It just allows to perform explicit edits on a single directory, working with +// directory trees is out of its scope, they are managed by the MFS layer +// (which is the main consumer of this interface). +type Directory interface { + + // SetCidBuilder sets the CID Builder of the root node. + SetCidBuilder(cid.Builder) + + // AddChild adds a (name, key) pair to the root node. + AddChild(context.Context, string, ipld.Node) error + + // ForEachLink applies the given function to Links in the directory. + ForEachLink(context.Context, func(*ipld.Link) error) error + + // EnumLinksAsync returns a channel which will receive Links in the directory + // as they are enumerated, where order is not gauranteed + EnumLinksAsync(context.Context) <-chan format.LinkResult + + // Links returns the all the links in the directory node. + Links(context.Context) ([]*ipld.Link, error) + + // Find returns the root node of the file named 'name' within this directory. + // In the case of HAMT-directories, it will traverse the tree. + Find(context.Context, string) (ipld.Node, error) + + // RemoveChild removes the child with the given name. + RemoveChild(context.Context, string) error + + // GetNode returns the root of this directory. + GetNode() (ipld.Node, error) + + // GetCidBuilder returns the CID Builder used. + GetCidBuilder() cid.Builder +} + +// TODO: Evaluate removing `dserv` from this layer and providing it in MFS. +// (The functions should in that case add a `DAGService` argument.) + +// BasicDirectory is the basic implementation of `Directory`. All the entries +// are stored in a single node. +type BasicDirectory struct { + node *mdag.ProtoNode + dserv ipld.DAGService +} + +// HAMTDirectory is the HAMT implementation of `Directory`. +// (See package `hamt` for more information.) +type HAMTDirectory struct { + shard *hamt.Shard + dserv ipld.DAGService +} + +// NewDirectory returns a Directory. It needs a `DAGService` to add the children. +func NewDirectory(dserv ipld.DAGService) Directory { + if UseHAMTSharding { + dir := new(HAMTDirectory) + s, err := hamt.NewShard(dserv, DefaultShardWidth) + if err != nil { + panic(err) // will only panic if DefaultShardWidth is a bad value + } + dir.shard = s + dir.dserv = dserv + return dir + } + + dir := new(BasicDirectory) + dir.node = format.EmptyDirNode() + dir.dserv = dserv + return dir +} + +// ErrNotADir implies that the given node was not a unixfs directory +var ErrNotADir = fmt.Errorf("merkledag node was not a directory or shard") + +// NewDirectoryFromNode loads a unixfs directory from the given IPLD node and +// DAGService. +func NewDirectoryFromNode(dserv ipld.DAGService, node ipld.Node) (Directory, error) { + protoBufNode, ok := node.(*mdag.ProtoNode) + if !ok { + return nil, ErrNotADir + } + + fsNode, err := format.FSNodeFromBytes(protoBufNode.Data()) + if err != nil { + return nil, err + } + + switch fsNode.Type() { + case format.TDirectory: + return &BasicDirectory{ + dserv: dserv, + node: protoBufNode.Copy().(*mdag.ProtoNode), + }, nil + case format.THAMTShard: + shard, err := hamt.NewHamtFromDag(dserv, node) + if err != nil { + return nil, err + } + return &HAMTDirectory{ + dserv: dserv, + shard: shard, + }, nil + } + + return nil, ErrNotADir +} + +// SetCidBuilder implements the `Directory` interface. +func (d *BasicDirectory) SetCidBuilder(builder cid.Builder) { + d.node.SetCidBuilder(builder) +} + +// AddChild implements the `Directory` interface. It adds (or replaces) +// a link to the given `node` under `name`. +func (d *BasicDirectory) AddChild(ctx context.Context, name string, node ipld.Node) error { + d.node.RemoveNodeLink(name) + // Remove old link (if it existed), don't check a potential `ErrNotFound`. + + return d.node.AddNodeLink(name, node) +} + +// EnumLinksAsync returns a channel which will receive Links in the directory +// as they are enumerated, where order is not gauranteed +func (d *BasicDirectory) EnumLinksAsync(ctx context.Context) <-chan format.LinkResult { + linkResults := make(chan format.LinkResult) + go func() { + defer close(linkResults) + for _, l := range d.node.Links() { + select { + case linkResults <- format.LinkResult{ + Link: l, + Err: nil, + }: + case <-ctx.Done(): + return + } + } + }() + return linkResults +} + +// ForEachLink implements the `Directory` interface. +func (d *BasicDirectory) ForEachLink(ctx context.Context, f func(*ipld.Link) error) error { + for _, l := range d.node.Links() { + if err := f(l); err != nil { + return err + } + } + return nil +} + +// Links implements the `Directory` interface. +func (d *BasicDirectory) Links(ctx context.Context) ([]*ipld.Link, error) { + return d.node.Links(), nil +} + +// Find implements the `Directory` interface. +func (d *BasicDirectory) Find(ctx context.Context, name string) (ipld.Node, error) { + lnk, err := d.node.GetNodeLink(name) + if err == mdag.ErrLinkNotFound { + err = os.ErrNotExist + } + if err != nil { + return nil, err + } + + return d.dserv.Get(ctx, lnk.Cid) +} + +// RemoveChild implements the `Directory` interface. +func (d *BasicDirectory) RemoveChild(ctx context.Context, name string) error { + return d.node.RemoveNodeLink(name) +} + +// GetNode implements the `Directory` interface. +func (d *BasicDirectory) GetNode() (ipld.Node, error) { + return d.node, nil +} + +// GetCidBuilder implements the `Directory` interface. +func (d *BasicDirectory) GetCidBuilder() cid.Builder { + return d.node.CidBuilder() +} + +// SwitchToSharding returns a HAMT implementation of this directory. +func (d *BasicDirectory) SwitchToSharding(ctx context.Context) (Directory, error) { + hamtDir := new(HAMTDirectory) + hamtDir.dserv = d.dserv + + shard, err := hamt.NewShard(d.dserv, DefaultShardWidth) + if err != nil { + return nil, err + } + shard.SetCidBuilder(d.node.CidBuilder()) + hamtDir.shard = shard + + for _, lnk := range d.node.Links() { + node, err := d.dserv.Get(ctx, lnk.Cid) + if err != nil { + return nil, err + } + + err = hamtDir.shard.Set(ctx, lnk.Name, node) + if err != nil { + return nil, err + } + } + + return hamtDir, nil +} + +// SetCidBuilder implements the `Directory` interface. +func (d *HAMTDirectory) SetCidBuilder(builder cid.Builder) { + d.shard.SetCidBuilder(builder) +} + +// AddChild implements the `Directory` interface. +func (d *HAMTDirectory) AddChild(ctx context.Context, name string, nd ipld.Node) error { + return d.shard.Set(ctx, name, nd) +} + +// ForEachLink implements the `Directory` interface. +func (d *HAMTDirectory) ForEachLink(ctx context.Context, f func(*ipld.Link) error) error { + return d.shard.ForEachLink(ctx, f) +} + +// EnumLinksAsync returns a channel which will receive Links in the directory +// as they are enumerated, where order is not gauranteed +func (d *HAMTDirectory) EnumLinksAsync(ctx context.Context) <-chan format.LinkResult { + return d.shard.EnumLinksAsync(ctx) +} + +// Links implements the `Directory` interface. +func (d *HAMTDirectory) Links(ctx context.Context) ([]*ipld.Link, error) { + return d.shard.EnumLinks(ctx) +} + +// Find implements the `Directory` interface. It will traverse the tree. +func (d *HAMTDirectory) Find(ctx context.Context, name string) (ipld.Node, error) { + lnk, err := d.shard.Find(ctx, name) + if err != nil { + return nil, err + } + + return lnk.GetNode(ctx, d.dserv) +} + +// RemoveChild implements the `Directory` interface. +func (d *HAMTDirectory) RemoveChild(ctx context.Context, name string) error { + return d.shard.Remove(ctx, name) +} + +// GetNode implements the `Directory` interface. +func (d *HAMTDirectory) GetNode() (ipld.Node, error) { + return d.shard.Node() +} + +// GetCidBuilder implements the `Directory` interface. +func (d *HAMTDirectory) GetCidBuilder() cid.Builder { + return d.shard.CidBuilder() +} diff --git a/vendor/github.com/ipfs/go-unixfs/io/doc.go b/vendor/github.com/ipfs/go-unixfs/io/doc.go new file mode 100644 index 00000000..cf844bd2 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/io/doc.go @@ -0,0 +1,3 @@ +// Package io implements convenience objects for working with the ipfs +// unixfs data format. +package io diff --git a/vendor/github.com/ipfs/go-unixfs/io/resolve.go b/vendor/github.com/ipfs/go-unixfs/io/resolve.go new file mode 100644 index 00000000..c3dcffc2 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/io/resolve.go @@ -0,0 +1,41 @@ +package io + +import ( + "context" + + dag "github.com/ipfs/go-merkledag" + ft "github.com/ipfs/go-unixfs" + hamt "github.com/ipfs/go-unixfs/hamt" + + ipld "github.com/ipfs/go-ipld-format" +) + +// ResolveUnixfsOnce resolves a single hop of a path through a graph in a +// unixfs context. This includes handling traversing sharded directories. +func ResolveUnixfsOnce(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) { + pn, ok := nd.(*dag.ProtoNode) + if ok { + fsn, err := ft.FSNodeFromBytes(pn.Data()) + if err != nil { + // Not a unixfs node, use standard object traversal code + return nd.ResolveLink(names) + } + + if fsn.Type() == ft.THAMTShard { + rods := dag.NewReadOnlyDagService(ds) + s, err := hamt.NewHamtFromDag(rods, nd) + if err != nil { + return nil, nil, err + } + + out, err := s.Find(ctx, names[0]) + if err != nil { + return nil, nil, err + } + + return out, names[1:], nil + } + } + + return nd.ResolveLink(names) +} diff --git a/vendor/github.com/ipfs/go-unixfs/mod/dagmodifier.go b/vendor/github.com/ipfs/go-unixfs/mod/dagmodifier.go new file mode 100644 index 00000000..1e2b2dcc --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/mod/dagmodifier.go @@ -0,0 +1,605 @@ +// Package mod provides DAG modification utilities to, for example, +// insert additional nodes in a unixfs DAG or truncate them. +package mod + +import ( + "bytes" + "context" + "errors" + "io" + + ft "github.com/ipfs/go-unixfs" + help "github.com/ipfs/go-unixfs/importer/helpers" + trickle "github.com/ipfs/go-unixfs/importer/trickle" + uio "github.com/ipfs/go-unixfs/io" + + cid "github.com/ipfs/go-cid" + chunker "github.com/ipfs/go-ipfs-chunker" + ipld "github.com/ipfs/go-ipld-format" + mdag "github.com/ipfs/go-merkledag" +) + +// Common errors +var ( + ErrSeekFail = errors.New("failed to seek properly") + ErrUnrecognizedWhence = errors.New("unrecognized whence") + ErrNotUnixfs = errors.New("dagmodifier only supports unixfs nodes (proto or raw)") +) + +// 2MB +var writebufferSize = 1 << 21 + +// DagModifier is the only struct licensed and able to correctly +// perform surgery on a DAG 'file' +// Dear god, please rename this to something more pleasant +type DagModifier struct { + dagserv ipld.DAGService + curNode ipld.Node + + splitter chunker.SplitterGen + ctx context.Context + readCancel func() + + writeStart uint64 + curWrOff uint64 + wrBuf *bytes.Buffer + + Prefix cid.Prefix + RawLeaves bool + + read uio.DagReader +} + +// NewDagModifier returns a new DagModifier, the Cid prefix for newly +// created nodes will be inhered from the passed in node. If the Cid +// version if not 0 raw leaves will also be enabled. The Prefix and +// RawLeaves options can be overridden by changing them after the call. +func NewDagModifier(ctx context.Context, from ipld.Node, serv ipld.DAGService, spl chunker.SplitterGen) (*DagModifier, error) { + switch from.(type) { + case *mdag.ProtoNode, *mdag.RawNode: + // ok + default: + return nil, ErrNotUnixfs + } + + prefix := from.Cid().Prefix() + prefix.Codec = cid.DagProtobuf + rawLeaves := false + if prefix.Version > 0 { + rawLeaves = true + } + + return &DagModifier{ + curNode: from.Copy(), + dagserv: serv, + splitter: spl, + ctx: ctx, + Prefix: prefix, + RawLeaves: rawLeaves, + }, nil +} + +// WriteAt will modify a dag file in place +func (dm *DagModifier) WriteAt(b []byte, offset int64) (int, error) { + // TODO: this is currently VERY inefficient + // each write that happens at an offset other than the current one causes a + // flush to disk, and dag rewrite + if offset == int64(dm.writeStart) && dm.wrBuf != nil { + // If we would overwrite the previous write + if len(b) >= dm.wrBuf.Len() { + dm.wrBuf.Reset() + } + } else if uint64(offset) != dm.curWrOff { + size, err := dm.Size() + if err != nil { + return 0, err + } + if offset > size { + err := dm.expandSparse(offset - size) + if err != nil { + return 0, err + } + } + + err = dm.Sync() + if err != nil { + return 0, err + } + dm.writeStart = uint64(offset) + } + + return dm.Write(b) +} + +// A reader that just returns zeros +type zeroReader struct{} + +func (zr zeroReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + +// expandSparse grows the file with zero blocks of 4096 +// A small blocksize is chosen to aid in deduplication +func (dm *DagModifier) expandSparse(size int64) error { + r := io.LimitReader(zeroReader{}, size) + spl := chunker.NewSizeSplitter(r, 4096) + nnode, err := dm.appendData(dm.curNode, spl) + if err != nil { + return err + } + err = dm.dagserv.Add(dm.ctx, nnode) + return err +} + +// Write continues writing to the dag at the current offset +func (dm *DagModifier) Write(b []byte) (int, error) { + if dm.read != nil { + dm.read = nil + } + if dm.wrBuf == nil { + dm.wrBuf = new(bytes.Buffer) + } + + n, err := dm.wrBuf.Write(b) + if err != nil { + return n, err + } + dm.curWrOff += uint64(n) + if dm.wrBuf.Len() > writebufferSize { + err := dm.Sync() + if err != nil { + return n, err + } + } + return n, nil +} + +// Size returns the Filesize of the node +func (dm *DagModifier) Size() (int64, error) { + fileSize, err := fileSize(dm.curNode) + if err != nil { + return 0, err + } + if dm.wrBuf != nil && int64(dm.wrBuf.Len())+int64(dm.writeStart) > int64(fileSize) { + return int64(dm.wrBuf.Len()) + int64(dm.writeStart), nil + } + return int64(fileSize), nil +} + +func fileSize(n ipld.Node) (uint64, error) { + switch nd := n.(type) { + case *mdag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return 0, err + } + return fsn.FileSize(), nil + case *mdag.RawNode: + return uint64(len(nd.RawData())), nil + default: + return 0, ErrNotUnixfs + } +} + +// Sync writes changes to this dag to disk +func (dm *DagModifier) Sync() error { + // No buffer? Nothing to do + if dm.wrBuf == nil { + return nil + } + + // If we have an active reader, kill it + if dm.read != nil { + dm.read = nil + dm.readCancel() + } + + // Number of bytes we're going to write + buflen := dm.wrBuf.Len() + + fs, err := fileSize(dm.curNode) + if err != nil { + return err + } + if fs < dm.writeStart { + if err := dm.expandSparse(int64(dm.writeStart - fs)); err != nil { + return err + } + } + + // overwrite existing dag nodes + thisc, err := dm.modifyDag(dm.curNode, dm.writeStart) + if err != nil { + return err + } + + dm.curNode, err = dm.dagserv.Get(dm.ctx, thisc) + if err != nil { + return err + } + + // need to write past end of current dag + if dm.wrBuf.Len() > 0 { + dm.curNode, err = dm.appendData(dm.curNode, dm.splitter(dm.wrBuf)) + if err != nil { + return err + } + + err = dm.dagserv.Add(dm.ctx, dm.curNode) + if err != nil { + return err + } + } + + dm.writeStart += uint64(buflen) + dm.wrBuf = nil + + return nil +} + +// modifyDag writes the data in 'dm.wrBuf' over the data in 'node' starting at 'offset' +// returns the new key of the passed in node. +func (dm *DagModifier) modifyDag(n ipld.Node, offset uint64) (cid.Cid, error) { + // If we've reached a leaf node. + if len(n.Links()) == 0 { + switch nd0 := n.(type) { + case *mdag.ProtoNode: + fsn, err := ft.FSNodeFromBytes(nd0.Data()) + if err != nil { + return cid.Cid{}, err + } + + _, err = dm.wrBuf.Read(fsn.Data()[offset:]) + if err != nil && err != io.EOF { + return cid.Cid{}, err + } + + // Update newly written node.. + b, err := fsn.GetBytes() + if err != nil { + return cid.Cid{}, err + } + + nd := new(mdag.ProtoNode) + nd.SetData(b) + nd.SetCidBuilder(nd0.CidBuilder()) + err = dm.dagserv.Add(dm.ctx, nd) + if err != nil { + return cid.Cid{}, err + } + + return nd.Cid(), nil + case *mdag.RawNode: + origData := nd0.RawData() + bytes := make([]byte, len(origData)) + + // copy orig data up to offset + copy(bytes, origData[:offset]) + + // copy in new data + n, err := dm.wrBuf.Read(bytes[offset:]) + if err != nil && err != io.EOF { + return cid.Cid{}, err + } + + // copy remaining data + offsetPlusN := int(offset) + n + if offsetPlusN < len(origData) { + copy(bytes[offsetPlusN:], origData[offsetPlusN:]) + } + + nd, err := mdag.NewRawNodeWPrefix(bytes, nd0.Cid().Prefix()) + if err != nil { + return cid.Cid{}, err + } + err = dm.dagserv.Add(dm.ctx, nd) + if err != nil { + return cid.Cid{}, err + } + + return nd.Cid(), nil + } + } + + node, ok := n.(*mdag.ProtoNode) + if !ok { + return cid.Cid{}, ErrNotUnixfs + } + + fsn, err := ft.FSNodeFromBytes(node.Data()) + if err != nil { + return cid.Cid{}, err + } + + var cur uint64 + for i, bs := range fsn.BlockSizes() { + // We found the correct child to write into + if cur+bs > offset { + child, err := node.Links()[i].GetNode(dm.ctx, dm.dagserv) + if err != nil { + return cid.Cid{}, err + } + + k, err := dm.modifyDag(child, offset-cur) + if err != nil { + return cid.Cid{}, err + } + + node.Links()[i].Cid = k + + // Recache serialized node + _, err = node.EncodeProtobuf(true) + if err != nil { + return cid.Cid{}, err + } + + if dm.wrBuf.Len() == 0 { + // No more bytes to write! + break + } + offset = cur + bs + } + cur += bs + } + + err = dm.dagserv.Add(dm.ctx, node) + return node.Cid(), err +} + +// appendData appends the blocks from the given chan to the end of this dag +func (dm *DagModifier) appendData(nd ipld.Node, spl chunker.Splitter) (ipld.Node, error) { + switch nd := nd.(type) { + case *mdag.ProtoNode, *mdag.RawNode: + dbp := &help.DagBuilderParams{ + Dagserv: dm.dagserv, + Maxlinks: help.DefaultLinksPerBlock, + CidBuilder: dm.Prefix, + RawLeaves: dm.RawLeaves, + } + db, err := dbp.New(spl) + if err != nil { + return nil, err + } + return trickle.Append(dm.ctx, nd, db) + default: + return nil, ErrNotUnixfs + } +} + +// Read data from this dag starting at the current offset +func (dm *DagModifier) Read(b []byte) (int, error) { + err := dm.readPrep() + if err != nil { + return 0, err + } + + n, err := dm.read.Read(b) + dm.curWrOff += uint64(n) + return n, err +} + +func (dm *DagModifier) readPrep() error { + err := dm.Sync() + if err != nil { + return err + } + + if dm.read == nil { + ctx, cancel := context.WithCancel(dm.ctx) + dr, err := uio.NewDagReader(ctx, dm.curNode, dm.dagserv) + if err != nil { + cancel() + return err + } + + i, err := dr.Seek(int64(dm.curWrOff), io.SeekStart) + if err != nil { + cancel() + return err + } + + if i != int64(dm.curWrOff) { + cancel() + return ErrSeekFail + } + + dm.readCancel = cancel + dm.read = dr + } + + return nil +} + +// CtxReadFull reads data from this dag starting at the current offset +func (dm *DagModifier) CtxReadFull(ctx context.Context, b []byte) (int, error) { + err := dm.readPrep() + if err != nil { + return 0, err + } + + n, err := dm.read.CtxReadFull(ctx, b) + dm.curWrOff += uint64(n) + return n, err +} + +// GetNode gets the modified DAG Node +func (dm *DagModifier) GetNode() (ipld.Node, error) { + err := dm.Sync() + if err != nil { + return nil, err + } + return dm.curNode.Copy(), nil +} + +// HasChanges returned whether or not there are unflushed changes to this dag +func (dm *DagModifier) HasChanges() bool { + return dm.wrBuf != nil +} + +// Seek modifies the offset according to whence. See unixfs/io for valid whence +// values. +func (dm *DagModifier) Seek(offset int64, whence int) (int64, error) { + err := dm.Sync() + if err != nil { + return 0, err + } + + fisize, err := dm.Size() + if err != nil { + return 0, err + } + + var newoffset uint64 + switch whence { + case io.SeekCurrent: + newoffset = dm.curWrOff + uint64(offset) + case io.SeekStart: + newoffset = uint64(offset) + case io.SeekEnd: + newoffset = uint64(fisize) - uint64(offset) + default: + return 0, ErrUnrecognizedWhence + } + + if int64(newoffset) > fisize { + if err := dm.expandSparse(int64(newoffset) - fisize); err != nil { + return 0, err + } + } + dm.curWrOff = newoffset + dm.writeStart = newoffset + + if dm.read != nil { + _, err = dm.read.Seek(offset, whence) + if err != nil { + return 0, err + } + } + + return int64(dm.curWrOff), nil +} + +// Truncate truncates the current Node to 'size' and replaces it with the +// new one. +func (dm *DagModifier) Truncate(size int64) error { + err := dm.Sync() + if err != nil { + return err + } + + realSize, err := dm.Size() + if err != nil { + return err + } + if size == int64(realSize) { + return nil + } + + // Truncate can also be used to expand the file + if size > int64(realSize) { + return dm.expandSparse(int64(size) - realSize) + } + + nnode, err := dm.dagTruncate(dm.ctx, dm.curNode, uint64(size)) + if err != nil { + return err + } + + err = dm.dagserv.Add(dm.ctx, nnode) + if err != nil { + return err + } + + dm.curNode = nnode + return nil +} + +// dagTruncate truncates the given node to 'size' and returns the modified Node +func (dm *DagModifier) dagTruncate(ctx context.Context, n ipld.Node, size uint64) (ipld.Node, error) { + if len(n.Links()) == 0 { + switch nd := n.(type) { + case *mdag.ProtoNode: + // TODO: this can likely be done without marshaling and remarshaling + fsn, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return nil, err + } + nd.SetData(ft.WrapData(fsn.Data()[:size])) + return nd, nil + case *mdag.RawNode: + return mdag.NewRawNodeWPrefix(nd.RawData()[:size], nd.Cid().Prefix()) + } + } + + nd, ok := n.(*mdag.ProtoNode) + if !ok { + return nil, ErrNotUnixfs + } + + var cur uint64 + end := 0 + var modified ipld.Node + ndata, err := ft.FSNodeFromBytes(nd.Data()) + if err != nil { + return nil, err + } + // Reset the block sizes of the node to adjust them + // with the new values of the truncated children. + ndata.RemoveAllBlockSizes() + for i, lnk := range nd.Links() { + child, err := lnk.GetNode(ctx, dm.dagserv) + if err != nil { + return nil, err + } + + childsize, err := fileSize(child) + if err != nil { + return nil, err + } + + // found the child we want to cut + if size < cur+childsize { + nchild, err := dm.dagTruncate(ctx, child, size-cur) + if err != nil { + return nil, err + } + + ndata.AddBlockSize(size - cur) + + modified = nchild + end = i + break + } + cur += childsize + ndata.AddBlockSize(childsize) + } + + err = dm.dagserv.Add(ctx, modified) + if err != nil { + return nil, err + } + + nd.SetLinks(nd.Links()[:end]) + err = nd.AddNodeLink("", modified) + if err != nil { + return nil, err + } + + d, err := ndata.GetBytes() + if err != nil { + return nil, err + } + // Save the new block sizes to the original node. + nd.SetData(d) + + // invalidate cache and recompute serialized data + _, err = nd.EncodeProtobuf(true) + if err != nil { + return nil, err + } + + return nd, nil +} diff --git a/vendor/github.com/ipfs/go-unixfs/package.json b/vendor/github.com/ipfs/go-unixfs/package.json new file mode 100644 index 00000000..4d20bf8c --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/package.json @@ -0,0 +1,84 @@ +{ + "author": "why", + "bugs": { + "url": "https://github.com/ipfs/go-unixfs" + }, + "gx": { + "dvcsimport": "github.com/ipfs/go-unixfs" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmfJHywXQu98UeZtGJBQrPAR6AtmDjjbe3qjTo9piXHPnx", + "name": "murmur3", + "version": "0.0.0" + }, + { + "author": "whyrusleeping", + "hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz", + "name": "go-ipfs-util", + "version": "1.2.9" + }, + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "why", + "hash": "QmY6UwsN3D6uoxrRkYpJ8Wos8R66gwLmdn3wy7jM7CCRQ1", + "name": "go-merkledag", + "version": "1.1.40" + }, + { + "author": "hector", + "hash": "QmdiZuFuiFD1Gbuu8PdqmsfrCR3z4QKSR2bN1NAvnJgTY7", + "name": "go-ipfs-posinfo", + "version": "0.1.5" + }, + { + "author": "Stebalien", + "hash": "QmVA2fUfgswyFdhZZA3MvUtfwTS7TER4Hv4vSBLvoQu1QZ", + "name": "go-bitfield", + "version": "0.1.3" + }, + { + "author": "hsanjuan", + "hash": "QmYmZ81dU5nnmBFy5MmktXLZpt8QCWhRJd6M1uxVF6vke8", + "name": "go-ipfs-chunker", + "version": "0.1.6" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + }, + { + "author": "whyrusleeping", + "hash": "QmddjPSGZb3ieihSseFeCfVRpZzcqczPNsD2DvarSwnjJB", + "name": "gogo-protobuf", + "version": "1.2.1" + }, + { + "author": "whyrusleeping", + "hash": "QmZ6nzCLwGLVfRzYLpD7pW6UNuBDKEcA2imJtVpbEx2rxy", + "name": "go-ipld-format", + "version": "0.8.1" + }, + { + "author": "magik6k", + "hash": "QmRHcZ5ngUxZo8phLR3fpoqk9wA7VdGc5mhwkGSnB2nZ9F", + "name": "go-ipfs-files", + "version": "2.0.7" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-unixfs", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.3.15" +} + diff --git a/vendor/github.com/ipfs/go-unixfs/pb/Makefile b/vendor/github.com/ipfs/go-unixfs/pb/Makefile new file mode 100644 index 00000000..51552a09 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogo_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/ipfs/go-unixfs/pb/unixfs.pb.go b/vendor/github.com/ipfs/go-unixfs/pb/unixfs.pb.go new file mode 100644 index 00000000..6f1c8fe8 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/pb/unixfs.pb.go @@ -0,0 +1,217 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: unixfs.proto + +package unixfs_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Data_DataType int32 + +const ( + Data_Raw Data_DataType = 0 + Data_Directory Data_DataType = 1 + Data_File Data_DataType = 2 + Data_Metadata Data_DataType = 3 + Data_Symlink Data_DataType = 4 + Data_HAMTShard Data_DataType = 5 +) + +var Data_DataType_name = map[int32]string{ + 0: "Raw", + 1: "Directory", + 2: "File", + 3: "Metadata", + 4: "Symlink", + 5: "HAMTShard", +} + +var Data_DataType_value = map[string]int32{ + "Raw": 0, + "Directory": 1, + "File": 2, + "Metadata": 3, + "Symlink": 4, + "HAMTShard": 5, +} + +func (x Data_DataType) Enum() *Data_DataType { + p := new(Data_DataType) + *p = x + return p +} + +func (x Data_DataType) String() string { + return proto.EnumName(Data_DataType_name, int32(x)) +} + +func (x *Data_DataType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Data_DataType_value, data, "Data_DataType") + if err != nil { + return err + } + *x = Data_DataType(value) + return nil +} + +func (Data_DataType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e2fd76cc44dfc7c3, []int{0, 0} +} + +type Data struct { + Type *Data_DataType `protobuf:"varint,1,req,name=Type,enum=unixfs.pb.Data_DataType" json:"Type,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=Data" json:"Data,omitempty"` + Filesize *uint64 `protobuf:"varint,3,opt,name=filesize" json:"filesize,omitempty"` + Blocksizes []uint64 `protobuf:"varint,4,rep,name=blocksizes" json:"blocksizes,omitempty"` + HashType *uint64 `protobuf:"varint,5,opt,name=hashType" json:"hashType,omitempty"` + Fanout *uint64 `protobuf:"varint,6,opt,name=fanout" json:"fanout,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Data) Reset() { *m = Data{} } +func (m *Data) String() string { return proto.CompactTextString(m) } +func (*Data) ProtoMessage() {} +func (*Data) Descriptor() ([]byte, []int) { + return fileDescriptor_e2fd76cc44dfc7c3, []int{0} +} +func (m *Data) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Data.Unmarshal(m, b) +} +func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Data.Marshal(b, m, deterministic) +} +func (m *Data) XXX_Merge(src proto.Message) { + xxx_messageInfo_Data.Merge(m, src) +} +func (m *Data) XXX_Size() int { + return xxx_messageInfo_Data.Size(m) +} +func (m *Data) XXX_DiscardUnknown() { + xxx_messageInfo_Data.DiscardUnknown(m) +} + +var xxx_messageInfo_Data proto.InternalMessageInfo + +func (m *Data) GetType() Data_DataType { + if m != nil && m.Type != nil { + return *m.Type + } + return Data_Raw +} + +func (m *Data) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Data) GetFilesize() uint64 { + if m != nil && m.Filesize != nil { + return *m.Filesize + } + return 0 +} + +func (m *Data) GetBlocksizes() []uint64 { + if m != nil { + return m.Blocksizes + } + return nil +} + +func (m *Data) GetHashType() uint64 { + if m != nil && m.HashType != nil { + return *m.HashType + } + return 0 +} + +func (m *Data) GetFanout() uint64 { + if m != nil && m.Fanout != nil { + return *m.Fanout + } + return 0 +} + +type Metadata struct { + MimeType *string `protobuf:"bytes,1,opt,name=MimeType" json:"MimeType,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_e2fd76cc44dfc7c3, []int{1} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Metadata.Unmarshal(m, b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) +} +func (m *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) +} +func (m *Metadata) XXX_Size() int { + return xxx_messageInfo_Metadata.Size(m) +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetMimeType() string { + if m != nil && m.MimeType != nil { + return *m.MimeType + } + return "" +} + +func init() { + proto.RegisterEnum("unixfs.pb.Data_DataType", Data_DataType_name, Data_DataType_value) + proto.RegisterType((*Data)(nil), "unixfs.pb.Data") + proto.RegisterType((*Metadata)(nil), "unixfs.pb.Metadata") +} + +func init() { proto.RegisterFile("unixfs.proto", fileDescriptor_e2fd76cc44dfc7c3) } + +var fileDescriptor_e2fd76cc44dfc7c3 = []byte{ + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x6a, 0xeb, 0x30, + 0x18, 0x85, 0xaf, 0x6c, 0x25, 0xb1, 0xff, 0xeb, 0x16, 0xf1, 0x0f, 0x45, 0x74, 0x28, 0xc6, 0x43, + 0xd1, 0x50, 0x3c, 0xf4, 0x0d, 0x0a, 0xa1, 0x74, 0xf1, 0xa2, 0x84, 0xee, 0x4a, 0x22, 0x63, 0x11, + 0xc7, 0x0a, 0xb6, 0x42, 0xeb, 0x3e, 0x45, 0x1f, 0xb9, 0xc8, 0x8e, 0xdd, 0x2e, 0x82, 0x4f, 0xe7, + 0x7c, 0xe2, 0x20, 0x48, 0x2e, 0x8d, 0xf9, 0x2c, 0xbb, 0xfc, 0xdc, 0x5a, 0x67, 0x31, 0x9e, 0x68, + 0x97, 0x7d, 0x07, 0x40, 0xd7, 0xca, 0x29, 0x7c, 0x02, 0xba, 0xed, 0xcf, 0x9a, 0x93, 0x34, 0x10, + 0xb7, 0xcf, 0x3c, 0x9f, 0x2b, 0xb9, 0x8f, 0x87, 0xc3, 0xe7, 0x72, 0x68, 0x21, 0x8e, 0x16, 0x0f, + 0x52, 0x22, 0x12, 0x39, 0xbe, 0x70, 0x0f, 0x51, 0x69, 0x6a, 0xdd, 0x99, 0x2f, 0xcd, 0xc3, 0x94, + 0x08, 0x2a, 0x67, 0xc6, 0x07, 0x80, 0x5d, 0x6d, 0xf7, 0x47, 0x0f, 0x1d, 0xa7, 0x69, 0x28, 0xa8, + 0xfc, 0x73, 0xe3, 0xdd, 0x4a, 0x75, 0xd5, 0xb0, 0x60, 0x31, 0xba, 0x13, 0xe3, 0x1d, 0x2c, 0x4b, + 0xd5, 0xd8, 0x8b, 0xe3, 0xcb, 0x21, 0xb9, 0x52, 0xf6, 0x0e, 0xd1, 0xb4, 0x0a, 0x57, 0x10, 0x4a, + 0xf5, 0xc1, 0xfe, 0xe1, 0x0d, 0xc4, 0x6b, 0xd3, 0xea, 0xbd, 0xb3, 0x6d, 0xcf, 0x08, 0x46, 0x40, + 0x5f, 0x4d, 0xad, 0x59, 0x80, 0x09, 0x44, 0x85, 0x76, 0xea, 0xa0, 0x9c, 0x62, 0x21, 0xfe, 0x87, + 0xd5, 0xa6, 0x3f, 0xd5, 0xa6, 0x39, 0x32, 0xea, 0x9d, 0xb7, 0x97, 0x62, 0xbb, 0xa9, 0x54, 0x7b, + 0x60, 0x8b, 0xec, 0xf1, 0xb7, 0xe9, 0x77, 0x15, 0xe6, 0xa4, 0xaf, 0x3f, 0x43, 0x44, 0x2c, 0x67, + 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xa0, 0x51, 0x10, 0x54, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/ipfs/go-unixfs/pb/unixfs.proto b/vendor/github.com/ipfs/go-unixfs/pb/unixfs.proto new file mode 100644 index 00000000..ffc059e8 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/pb/unixfs.proto @@ -0,0 +1,26 @@ +syntax = "proto2"; + +package unixfs.pb; + +message Data { + enum DataType { + Raw = 0; + Directory = 1; + File = 2; + Metadata = 3; + Symlink = 4; + HAMTShard = 5; + } + + required DataType Type = 1; + optional bytes Data = 2; + optional uint64 filesize = 3; + repeated uint64 blocksizes = 4; + + optional uint64 hashType = 5; + optional uint64 fanout = 6; +} + +message Metadata { + optional string MimeType = 1; +} diff --git a/vendor/github.com/ipfs/go-unixfs/unixfs.go b/vendor/github.com/ipfs/go-unixfs/unixfs.go new file mode 100644 index 00000000..84caf6f4 --- /dev/null +++ b/vendor/github.com/ipfs/go-unixfs/unixfs.go @@ -0,0 +1,408 @@ +// Package unixfs implements a data format for files in the IPFS filesystem It +// is not the only format in ipfs, but it is the one that the filesystem +// assumes +package unixfs + +import ( + "errors" + "fmt" + + proto "github.com/gogo/protobuf/proto" + dag "github.com/ipfs/go-merkledag" + + ipld "github.com/ipfs/go-ipld-format" + pb "github.com/ipfs/go-unixfs/pb" +) + +// A LinkResult for any parallel enumeration of links +// TODO: Should this live in go-ipld-format? +type LinkResult struct { + Link *ipld.Link + Err error +} + +// Shorthands for protobuffer types +const ( + TRaw = pb.Data_Raw + TFile = pb.Data_File + TDirectory = pb.Data_Directory + TMetadata = pb.Data_Metadata + TSymlink = pb.Data_Symlink + THAMTShard = pb.Data_HAMTShard +) + +// Common errors +var ( + ErrMalformedFileFormat = errors.New("malformed data in file format") + ErrUnrecognizedType = errors.New("unrecognized node type") +) + +// FromBytes unmarshals a byte slice as protobuf Data. +// Deprecated: Use `FSNodeFromBytes` instead to avoid direct manipulation of `pb.Data`. +func FromBytes(data []byte) (*pb.Data, error) { + pbdata := new(pb.Data) + err := proto.Unmarshal(data, pbdata) + if err != nil { + return nil, err + } + return pbdata, nil +} + +// FilePBData creates a protobuf File with the given +// byte slice and returns the marshaled protobuf bytes representing it. +func FilePBData(data []byte, totalsize uint64) []byte { + pbfile := new(pb.Data) + typ := pb.Data_File + pbfile.Type = &typ + pbfile.Data = data + pbfile.Filesize = proto.Uint64(totalsize) + + data, err := proto.Marshal(pbfile) + if err != nil { + // This really shouldnt happen, i promise + // The only failure case for marshal is if required fields + // are not filled out, and they all are. If the proto object + // gets changed and nobody updates this function, the code + // should panic due to programmer error + panic(err) + } + return data +} + +//FolderPBData returns Bytes that represent a Directory. +func FolderPBData() []byte { + pbfile := new(pb.Data) + typ := pb.Data_Directory + pbfile.Type = &typ + + data, err := proto.Marshal(pbfile) + if err != nil { + //this really shouldnt happen, i promise + panic(err) + } + return data +} + +//WrapData marshals raw bytes into a `Data_Raw` type protobuf message. +func WrapData(b []byte) []byte { + pbdata := new(pb.Data) + typ := pb.Data_Raw + pbdata.Data = b + pbdata.Type = &typ + pbdata.Filesize = proto.Uint64(uint64(len(b))) + + out, err := proto.Marshal(pbdata) + if err != nil { + // This shouldnt happen. seriously. + panic(err) + } + + return out +} + +//SymlinkData returns a `Data_Symlink` protobuf message for the path you specify. +func SymlinkData(path string) ([]byte, error) { + pbdata := new(pb.Data) + typ := pb.Data_Symlink + pbdata.Data = []byte(path) + pbdata.Type = &typ + + out, err := proto.Marshal(pbdata) + if err != nil { + return nil, err + } + + return out, nil +} + +// HAMTShardData return a `Data_HAMTShard` protobuf message +func HAMTShardData(data []byte, fanout uint64, hashType uint64) ([]byte, error) { + pbdata := new(pb.Data) + typ := pb.Data_HAMTShard + pbdata.Type = &typ + pbdata.HashType = proto.Uint64(hashType) + pbdata.Data = data + pbdata.Fanout = proto.Uint64(fanout) + + out, err := proto.Marshal(pbdata) + if err != nil { + return nil, err + } + + return out, nil +} + +// UnwrapData unmarshals a protobuf messages and returns the contents. +func UnwrapData(data []byte) ([]byte, error) { + pbdata := new(pb.Data) + err := proto.Unmarshal(data, pbdata) + if err != nil { + return nil, err + } + return pbdata.GetData(), nil +} + +// DataSize returns the size of the contents in protobuf wrapped slice. +// For raw data it simply provides the length of it. For Data_Files, it +// will return the associated filesize. Note that Data_Directories will +// return an error. +func DataSize(data []byte) (uint64, error) { + pbdata := new(pb.Data) + err := proto.Unmarshal(data, pbdata) + if err != nil { + return 0, err + } + + switch pbdata.GetType() { + case pb.Data_Directory: + return 0, errors.New("can't get data size of directory") + case pb.Data_File: + return pbdata.GetFilesize(), nil + case pb.Data_Raw: + return uint64(len(pbdata.GetData())), nil + default: + return 0, errors.New("unrecognized node data type") + } +} + +// An FSNode represents a filesystem object using the UnixFS specification. +// +// The `NewFSNode` constructor should be used instead of just calling `new(FSNode)` +// to guarantee that the required (`Type` and `Filesize`) fields in the `format` +// structure are initialized before marshaling (in `GetBytes()`). +type FSNode struct { + + // UnixFS format defined as a protocol buffers message. + format pb.Data +} + +// FSNodeFromBytes unmarshal a protobuf message onto an FSNode. +func FSNodeFromBytes(b []byte) (*FSNode, error) { + n := new(FSNode) + err := proto.Unmarshal(b, &n.format) + if err != nil { + return nil, err + } + + return n, nil +} + +// NewFSNode creates a new FSNode structure with the given `dataType`. +// +// It initializes the (required) `Type` field (that doesn't have a `Set()` +// accessor so it must be specified at creation), otherwise the `Marshal()` +// method in `GetBytes()` would fail (`required field "Type" not set`). +// +// It also initializes the `Filesize` pointer field to ensure its value +// is never nil before marshaling, this is not a required field but it is +// done to be backwards compatible with previous `go-ipfs` versions hash. +// (If it wasn't initialized there could be cases where `Filesize` could +// have been left at nil, when the `FSNode` was created but no data or +// child nodes were set to adjust it, as is the case in `NewLeaf()`.) +func NewFSNode(dataType pb.Data_DataType) *FSNode { + n := new(FSNode) + n.format.Type = &dataType + + // Initialize by `Filesize` by updating it with a dummy (zero) value. + n.UpdateFilesize(0) + + return n +} + +// HashType gets hash type of format +func (n *FSNode) HashType() uint64 { + return n.format.GetHashType() +} + +// Fanout gets fanout of format +func (n *FSNode) Fanout() uint64 { + return n.format.GetFanout() +} + +// AddBlockSize adds the size of the next child block of this node +func (n *FSNode) AddBlockSize(s uint64) { + n.UpdateFilesize(int64(s)) + n.format.Blocksizes = append(n.format.Blocksizes, s) +} + +// RemoveBlockSize removes the given child block's size. +func (n *FSNode) RemoveBlockSize(i int) { + n.UpdateFilesize(-int64(n.format.Blocksizes[i])) + n.format.Blocksizes = append(n.format.Blocksizes[:i], n.format.Blocksizes[i+1:]...) +} + +// BlockSize returns the block size indexed by `i`. +// TODO: Evaluate if this function should be bounds checking. +func (n *FSNode) BlockSize(i int) uint64 { + return n.format.Blocksizes[i] +} + +// BlockSizes gets blocksizes of format +func (n *FSNode) BlockSizes() []uint64 { + return n.format.GetBlocksizes() +} + +// RemoveAllBlockSizes removes all the child block sizes of this node. +func (n *FSNode) RemoveAllBlockSizes() { + n.format.Blocksizes = []uint64{} + n.format.Filesize = proto.Uint64(uint64(len(n.Data()))) +} + +// GetBytes marshals this node as a protobuf message. +func (n *FSNode) GetBytes() ([]byte, error) { + return proto.Marshal(&n.format) +} + +// FileSize returns the total size of this tree. That is, the size of +// the data in this node plus the size of all its children. +func (n *FSNode) FileSize() uint64 { + return n.format.GetFilesize() +} + +// NumChildren returns the number of child blocks of this node +func (n *FSNode) NumChildren() int { + return len(n.format.Blocksizes) +} + +// Data retrieves the `Data` field from the internal `format`. +func (n *FSNode) Data() []byte { + return n.format.GetData() +} + +// SetData sets the `Data` field from the internal `format` +// updating its `Filesize`. +func (n *FSNode) SetData(newData []byte) { + n.UpdateFilesize(int64(len(newData) - len(n.Data()))) + n.format.Data = newData +} + +// UpdateFilesize updates the `Filesize` field from the internal `format` +// by a signed difference (`filesizeDiff`). +// TODO: Add assert to check for `Filesize` > 0? +func (n *FSNode) UpdateFilesize(filesizeDiff int64) { + n.format.Filesize = proto.Uint64(uint64( + int64(n.format.GetFilesize()) + filesizeDiff)) +} + +// Type retrieves the `Type` field from the internal `format`. +func (n *FSNode) Type() pb.Data_DataType { + return n.format.GetType() +} + +// IsDir checks whether the node represents a directory +func (n *FSNode) IsDir() bool { + switch n.Type() { + case pb.Data_Directory, pb.Data_HAMTShard: + return true + default: + return false + } +} + +// Metadata is used to store additional FSNode information. +type Metadata struct { + MimeType string + Size uint64 +} + +// MetadataFromBytes Unmarshals a protobuf Data message into Metadata. +// The provided slice should have been encoded with BytesForMetadata(). +func MetadataFromBytes(b []byte) (*Metadata, error) { + pbd := new(pb.Data) + err := proto.Unmarshal(b, pbd) + if err != nil { + return nil, err + } + if pbd.GetType() != pb.Data_Metadata { + return nil, errors.New("incorrect node type") + } + + pbm := new(pb.Metadata) + err = proto.Unmarshal(pbd.Data, pbm) + if err != nil { + return nil, err + } + md := new(Metadata) + md.MimeType = pbm.GetMimeType() + return md, nil +} + +// Bytes marshals Metadata as a protobuf message of Metadata type. +func (m *Metadata) Bytes() ([]byte, error) { + pbm := new(pb.Metadata) + pbm.MimeType = &m.MimeType + return proto.Marshal(pbm) +} + +// BytesForMetadata wraps the given Metadata as a profobuf message of Data type, +// setting the DataType to Metadata. The wrapped bytes are itself the +// result of calling m.Bytes(). +func BytesForMetadata(m *Metadata) ([]byte, error) { + pbd := new(pb.Data) + pbd.Filesize = proto.Uint64(m.Size) + typ := pb.Data_Metadata + pbd.Type = &typ + mdd, err := m.Bytes() + if err != nil { + return nil, err + } + + pbd.Data = mdd + return proto.Marshal(pbd) +} + +// EmptyDirNode creates an empty folder Protonode. +func EmptyDirNode() *dag.ProtoNode { + return dag.NodeWithData(FolderPBData()) +} + +// ReadUnixFSNodeData extracts the UnixFS data from an IPLD node. +// Raw nodes are (also) processed because they are used as leaf +// nodes containing (only) UnixFS data. +func ReadUnixFSNodeData(node ipld.Node) (data []byte, err error) { + switch node := node.(type) { + + case *dag.ProtoNode: + fsNode, err := FSNodeFromBytes(node.Data()) + if err != nil { + return nil, fmt.Errorf("incorrectly formatted protobuf: %s", err) + } + + switch fsNode.Type() { + case pb.Data_File, pb.Data_Raw: + return fsNode.Data(), nil + // Only leaf nodes (of type `Data_Raw`) contain data but due to a + // bug the `Data_File` type (normally used for internal nodes) is + // also used for leaf nodes, so both types are accepted here + // (see the `balanced` package for more details). + default: + return nil, fmt.Errorf("found %s node in unexpected place", + fsNode.Type().String()) + } + + case *dag.RawNode: + return node.RawData(), nil + + default: + return nil, ErrUnrecognizedType + // TODO: To avoid rewriting the error message, but a different error from + // `unixfs.ErrUnrecognizedType` should be used (defining it in the + // `merkledag` or `go-ipld-format` packages). + } +} + +// Extract the `unixfs.FSNode` from the `ipld.Node` (assuming this +// was implemented by a `mdag.ProtoNode`). +func ExtractFSNode(node ipld.Node) (*FSNode, error) { + protoNode, ok := node.(*dag.ProtoNode) + if !ok { + return nil, errors.New("expected a ProtoNode as internal node") + } + + fsNode, err := FSNodeFromBytes(protoNode.Data()) + if err != nil { + return nil, err + } + + return fsNode, nil +} diff --git a/vendor/github.com/ipfs/go-verifcid/.travis.yml b/vendor/github.com/ipfs/go-verifcid/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/ipfs/go-verifcid/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/go-verifcid/go.mod b/vendor/github.com/ipfs/go-verifcid/go.mod new file mode 100644 index 00000000..5db3e877 --- /dev/null +++ b/vendor/github.com/ipfs/go-verifcid/go.mod @@ -0,0 +1,6 @@ +module github.com/ipfs/go-verifcid + +require ( + github.com/ipfs/go-cid v0.0.1 + github.com/multiformats/go-multihash v0.0.1 +) diff --git a/vendor/github.com/ipfs/go-verifcid/go.sum b/vendor/github.com/ipfs/go-verifcid/go.sum new file mode 100644 index 00000000..4525c37e --- /dev/null +++ b/vendor/github.com/ipfs/go-verifcid/go.sum @@ -0,0 +1,22 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/ipfs/go-verifcid/package.json b/vendor/github.com/ipfs/go-verifcid/package.json new file mode 100644 index 00000000..a066b1d8 --- /dev/null +++ b/vendor/github.com/ipfs/go-verifcid/package.json @@ -0,0 +1,28 @@ +{ + "author": "why", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/ipfs/go-verifcid" + }, + "gxDependencies": [ + { + "author": "multiformats", + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + }, + { + "author": "whyrusleeping", + "hash": "QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN", + "name": "go-cid", + "version": "0.9.3" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-verifcid", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.1.2" +} + diff --git a/vendor/github.com/ipfs/go-verifcid/validate.go b/vendor/github.com/ipfs/go-verifcid/validate.go new file mode 100644 index 00000000..8a76e493 --- /dev/null +++ b/vendor/github.com/ipfs/go-verifcid/validate.go @@ -0,0 +1,62 @@ +package verifcid + +import ( + "fmt" + + cid "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +var ErrPossiblyInsecureHashFunction = fmt.Errorf("potentially insecure hash functions not allowed") +var ErrBelowMinimumHashLength = fmt.Errorf("hashes must be at %d least bytes long", minimumHashLength) + +const minimumHashLength = 20 + +var goodset = map[uint64]bool{ + mh.SHA2_256: true, + mh.SHA2_512: true, + mh.SHA3_224: true, + mh.SHA3_256: true, + mh.SHA3_384: true, + mh.SHA3_512: true, + mh.SHAKE_256: true, + mh.DBL_SHA2_256: true, + mh.KECCAK_224: true, + mh.KECCAK_256: true, + mh.KECCAK_384: true, + mh.KECCAK_512: true, + mh.ID: true, + + mh.SHA1: true, // not really secure but still useful +} + +func IsGoodHash(code uint64) bool { + good, found := goodset[code] + if good { + return true + } + + if !found { + if code >= mh.BLAKE2B_MIN+19 && code <= mh.BLAKE2B_MAX { + return true + } + if code >= mh.BLAKE2S_MIN+19 && code <= mh.BLAKE2S_MAX { + return true + } + } + + return false +} + +func ValidateCid(c cid.Cid) error { + pref := c.Prefix() + if !IsGoodHash(pref.MhType) { + return ErrPossiblyInsecureHashFunction + } + + if pref.MhType != mh.ID && pref.MhLength < minimumHashLength { + return ErrBelowMinimumHashLength + } + + return nil +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/.travis.yml b/vendor/github.com/ipfs/interface-go-ipfs-core/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/LICENSE b/vendor/github.com/ipfs/interface-go-ipfs-core/LICENSE new file mode 100644 index 00000000..14121ca7 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/Makefile b/vendor/github.com/ipfs/interface-go-ipfs-core/Makefile new file mode 100644 index 00000000..89fc88d7 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/Makefile @@ -0,0 +1,16 @@ +all: deps +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go +deps: gx + gx --verbose install --global + gx-go rewrite +test: deps + gx test -v -race -coverprofile=coverage.txt -covermode=atomic . +rw: + gx-go rewrite +rwundo: + gx-go rewrite --undo +publish: rwundo + gx publish +.PHONY: all gx deps test rw rwundo publish diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/block.go b/vendor/github.com/ipfs/interface-go-ipfs-core/block.go new file mode 100644 index 00000000..b105b079 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/block.go @@ -0,0 +1,37 @@ +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + "io" + + "github.com/ipfs/interface-go-ipfs-core/options" +) + +// BlockStat contains information about a block +type BlockStat interface { + // Size is the size of a block + Size() int + + // Path returns path to the block + Path() path.Resolved +} + +// BlockAPI specifies the interface to the block layer +type BlockAPI interface { + // Put imports raw block data, hashing it using specified settings. + Put(context.Context, io.Reader, ...options.BlockPutOption) (BlockStat, error) + + // Get attempts to resolve the path and return a reader for data in the block + Get(context.Context, path.Path) (io.Reader, error) + + // Rm removes the block specified by the path from local blockstore. + // By default an error will be returned if the block can't be found locally. + // + // NOTE: If the specified block is pinned it won't be removed and no error + // will be returned + Rm(context.Context, path.Path, ...options.BlockRmOption) error + + // Stat returns information on + Stat(context.Context, path.Path) (BlockStat, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/coreapi.go b/vendor/github.com/ipfs/interface-go-ipfs-core/coreapi.go new file mode 100644 index 00000000..12cb166a --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/coreapi.go @@ -0,0 +1,56 @@ +// Package iface defines IPFS Core API which is a set of interfaces used to +// interact with IPFS nodes. +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/interface-go-ipfs-core/options" + + ipld "github.com/ipfs/go-ipld-format" +) + +// CoreAPI defines an unified interface to IPFS for Go programs +type CoreAPI interface { + // Unixfs returns an implementation of Unixfs API + Unixfs() UnixfsAPI + + // Block returns an implementation of Block API + Block() BlockAPI + + // Dag returns an implementation of Dag API + Dag() APIDagService + + // Name returns an implementation of Name API + Name() NameAPI + + // Key returns an implementation of Key API + Key() KeyAPI + + // Pin returns an implementation of Pin API + Pin() PinAPI + + // ObjectAPI returns an implementation of Object API + Object() ObjectAPI + + // Dht returns an implementation of Dht API + Dht() DhtAPI + + // Swarm returns an implementation of Swarm API + Swarm() SwarmAPI + + // PubSub returns an implementation of PubSub API + PubSub() PubSubAPI + + // ResolvePath resolves the path using Unixfs resolver + ResolvePath(context.Context, path.Path) (path.Resolved, error) + + // ResolveNode resolves the path (if not resolved already) using Unixfs + // resolver, gets and returns the resolved Node + ResolveNode(context.Context, path.Path) (ipld.Node, error) + + // WithOptions creates new instance of CoreAPI based on this instance with + // a set of options applied + WithOptions(...options.ApiOption) (CoreAPI, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/dag.go b/vendor/github.com/ipfs/interface-go-ipfs-core/dag.go new file mode 100644 index 00000000..3cc3aeb4 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/dag.go @@ -0,0 +1,13 @@ +package iface + +import ( + ipld "github.com/ipfs/go-ipld-format" +) + +// APIDagService extends ipld.DAGService +type APIDagService interface { + ipld.DAGService + + // Pinning returns special NodeAdder which recursively pins added nodes + Pinning() ipld.NodeAdder +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/dht.go b/vendor/github.com/ipfs/interface-go-ipfs-core/dht.go new file mode 100644 index 00000000..5f49e74a --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/dht.go @@ -0,0 +1,26 @@ +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/interface-go-ipfs-core/options" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// DhtAPI specifies the interface to the DHT +// Note: This API will likely get deprecated in near future, see +// https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. +type DhtAPI interface { + // FindPeer queries the DHT for all of the multiaddresses associated with a + // Peer ID + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) + + // FindProviders finds peers in the DHT who can provide a specific value + // given a key. + FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) + + // Provide announces to the network that you are providing given values + Provide(context.Context, path.Path, ...options.DhtProvideOption) error +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/errors.go b/vendor/github.com/ipfs/interface-go-ipfs-core/errors.go new file mode 100644 index 00000000..e0bd7805 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/errors.go @@ -0,0 +1,10 @@ +package iface + +import "errors" + +var ( + ErrIsDir = errors.New("this dag node is a directory") + ErrNotFile = errors.New("this dag node is not a regular file") + ErrOffline = errors.New("this action must be run in online mode, try running 'ipfs daemon' first") + ErrNotSupported = errors.New("operation not supported") +) diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/go.mod b/vendor/github.com/ipfs/interface-go-ipfs-core/go.mod new file mode 100644 index 00000000..89c92120 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/go.mod @@ -0,0 +1,14 @@ +module github.com/ipfs/interface-go-ipfs-core + +require ( + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-ipfs-files v0.0.2 + github.com/ipfs/go-ipld-cbor v0.0.1 + github.com/ipfs/go-ipld-format v0.0.1 + github.com/ipfs/go-merkledag v0.0.3 + github.com/ipfs/go-path v0.0.3 + github.com/ipfs/go-unixfs v0.0.4 + github.com/libp2p/go-libp2p-core v0.0.2 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multihash v0.0.5 +) diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/go.sum b/vendor/github.com/ipfs/interface-go-ipfs-core/go.sum new file mode 100644 index 00000000..2df61ab6 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/go.sum @@ -0,0 +1,343 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fd/go-nat v1.0.0 h1:DPyQ97sxA9ThrWYRPcWUz/z9TnpTIGRYODIQc/dy64M= +github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824 h1:TF4mX7zXpeyz/xintezebSa7ZDxAGBnqDwcoobvaz2o= +github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324 h1:PV190X5/DzQ/tbFFG5YpT5mH6q+cHlfgqI5JuRnH9oE= +github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= +github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/go-bitswap v0.0.3 h1:uFcSI9dkjUn67S7IM60vr2wA27aAvn8o9xYjaQCug3o= +github.com/ipfs/go-bitswap v0.0.3/go.mod h1:jadAZYsP/tcRMl47ZhFxhaNuDQoXawT8iHMg+iFoQbg= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.0.3 h1:40OvwrxeudTAlUGUAKNYnNPcwQeLtXedjzTWecnUinQ= +github.com/ipfs/go-blockservice v0.0.3/go.mod h1:/NNihwTi6V2Yr6g8wBI+BSwPuURpBRMtYNGrlxZ8KuI= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= +github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.2 h1:fEEjF4H+1t8SFOHqUGp0KqcwgIRlbD2bu8CAS2sIggE= +github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-flags v0.0.1 h1:OH5cEkJYL0QgA+bvD55TNG9ud8HA2Nqaav47b2c/UJk= +github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA= +github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= +github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= +github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.0.1 h1:394mZeTLcbM/LDO12PneBYvkZAUA+nRnmC0lAzDXKOY= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.1 h1:g7yh27SznWP4CUbkFgjR+WQRjEeyxCpTR4iKVmXx1wA= +github.com/ipfs/go-ipld-cbor v0.0.1/go.mod h1:RXHr8s4k0NE0TKhnrxqZC9M888QfsBN9rhS5NjfKzY8= +github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-merkledag v0.0.3 h1:A5DlOMzqTRDVmdgkf3dzCKCFmVWH4Zqwb0cbYXUs+Ro= +github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-path v0.0.3 h1:G/VFcCMXtp36JUPPyytYQ1I3UsBUBf47M//uSdTLnFg= +github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo= +github.com/ipfs/go-unixfs v0.0.4 h1:IApzQ+SnY0tfjqM7aU2b80CFYLZNHvhLmEZDIWr4e/E= +github.com/ipfs/go-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/jackpal/gateway v1.0.4 h1:LS5EHkLuQ6jzaHwULi0vL+JO0mU/n4yUtK8oUjHHOlM= +github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-conn-security v0.0.1 h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.1 h1:XefjAQRHcnUaxKb26RGupToucx3uU4ecbOZ3aACXlDU= +github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.0.2 h1:+jvgi0Zy3y4TKXJKApchCk3pCBPZf1T54z3+vKie3gw= +github.com/libp2p/go-libp2p v0.0.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mWTDdFC9wE= +github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= +github.com/libp2p/go-libp2p-blankhost v0.0.1 h1:/mZuuiwntNR8RywnCFlGHLKrKLYne+qciBpQXWqp5fk= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE= +github.com/libp2p/go-libp2p-core v0.0.2 h1:86uOwW+O6Uc7NbaK4diuLZo2/Ikvqw2rgyV03VcSbLE= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-discovery v0.0.1/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI= +github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-loggables v0.0.1 h1:HVww9oAnINIxbt69LJNkxD8lnbfgteXR97Xm4p3l9ps= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-metrics v0.0.1 h1:yumdPC/P2VzINdmcKZd0pciSUCpou+s0lwYCjBbzQZU= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-nat v0.0.2 h1:sKI5hiCsGFhuEKdXMsF9mywQu2qhfoIGX6a+VG6zelE= +github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1 h1:LgD6+skofkOx8z6odD9+MZHKjupv3ng1u6KRhaADTnA= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-routing v0.0.1 h1:hPMAWktf9rYi3ME4MG48qE7dq1ofJxiQbfdvpNntjhc= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= +github.com/libp2p/go-libp2p-secio v0.0.1 h1:CqE/RdsizOwItdgLe632iyft/w0tshDLmZGAiKDcUAI= +github.com/libp2p/go-libp2p-secio v0.0.1/go.mod h1:IdG6iQybdcYmbTzxp4J5dwtUEDTOvZrT0opIDVNPrJs= +github.com/libp2p/go-libp2p-swarm v0.0.1 h1:Vne+hjaDwXqzgNwQ2vb2YKbnbOTyXjtS47stT66Apc4= +github.com/libp2p/go-libp2p-swarm v0.0.1/go.mod h1:mh+KZxkbd3lQnveQ3j2q60BM1Cw2mX36XXQqwfPOShs= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.4 h1:/CPHQMN75/IQwkhBxxIo6p6PtL3rwFZtlzBROT3e8mw= +github.com/libp2p/go-libp2p-transport v0.0.4/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.1 h1:rNtXkY6dty46mxYOHHAZQchI7gQdJStF683FhVnei/k= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c= +github.com/libp2p/go-maddr-filter v0.0.1 h1:apvYTg0aIxxQyBX+XHKOR+0+lYhGs1Yv+JmTH9nyl5I= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.1 h1:dn2XGSrUxLtz3/8u85bGrwhUEKPX8MOF3lpmcWBZCWc= +github.com/libp2p/go-mplex v0.0.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-msgio v0.0.1 h1:znj97n5FtXGCLDwe9x8jpHmY770SW4WStBGcCDh6GJw= +github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.1 h1:UIRneNxLDmEGNjGHpIiWzSWkZ5bhxMCP9x3Vh7BSc7E= +github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-tcp-transport v0.0.1 h1:WyvJVw2lYAnr6CU+GZZ4oCt06fvORlmvBlFX2+ZpZDM= +github.com/libp2p/go-tcp-transport v0.0.1/go.mod h1:mnjg0o0O5TmXUaUIanYPUqkW4+u6mK0en8rlpA6BBTs= +github.com/libp2p/go-testutil v0.0.1 h1:Xg+O0G2HIMfHqBOBDcMS1iSZJ3GEcId4qOxCQvsGZHk= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-ws-transport v0.0.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible h1:iqksILj8STw03EJQe7Laj4ubnw+ojOyik18cd5vPL1o= +github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4= +github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible h1:BdYHctE9HJZLquG9tpTdwWcbG4FaX6tVKPGjCGgiVxo= +github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ= +github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible h1:IGm/UP/JpEFS6D787sZnZg7RA6fZIR9c/Ms9DeAVNuk= +github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= +github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible h1:nVkExQ7pYlN9e45LcqTCOiDD0904fjtm0flnHZGbXkw= +github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/yamux v1.1.5 h1:4CK3aUUJQu0qpKZv5gEWJjNOQtdbdDhVVS6PJ+HimdE= +github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/key.go b/vendor/github.com/ipfs/interface-go-ipfs-core/key.go new file mode 100644 index 00000000..db729b3b --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/key.go @@ -0,0 +1,42 @@ +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/interface-go-ipfs-core/options" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// Key specifies the interface to Keys in KeyAPI Keystore +type Key interface { + // Key returns key name + Name() string + + // Path returns key path + Path() path.Path + + // ID returns key PeerID + ID() peer.ID +} + +// KeyAPI specifies the interface to Keystore +type KeyAPI interface { + // Generate generates new key, stores it in the keystore under the specified + // name and returns a base58 encoded multihash of it's public key + Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error) + + // Rename renames oldName key to newName. Returns the key and whether another + // key was overwritten, or an error + Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error) + + // List lists keys stored in keystore + List(ctx context.Context) ([]Key, error) + + // Self returns the 'main' node key + Self(ctx context.Context) (Key, error) + + // Remove removes keys from keystore. Returns ipns path of the removed key + Remove(ctx context.Context, name string) (Key, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/name.go b/vendor/github.com/ipfs/interface-go-ipfs-core/name.go new file mode 100644 index 00000000..3dc9f687 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/name.go @@ -0,0 +1,47 @@ +package iface + +import ( + "context" + "errors" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/interface-go-ipfs-core/options" +) + +var ErrResolveFailed = errors.New("could not resolve name") + +// IpnsEntry specifies the interface to IpnsEntries +type IpnsEntry interface { + // Name returns IpnsEntry name + Name() string + // Value returns IpnsEntry value + Value() path.Path +} + +type IpnsResult struct { + path.Path + Err error +} + +// NameAPI specifies the interface to IPNS. +// +// IPNS is a PKI namespace, where names are the hashes of public keys, and the +// private key enables publishing new (signed) values. In both publish and +// resolve, the default name used is the node's own PeerID, which is the hash of +// its public key. +// +// You can use .Key API to list and generate more names and their respective keys. +type NameAPI interface { + // Publish announces new IPNS name + Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (IpnsEntry, error) + + // Resolve attempts to resolve the newest version of the specified name + Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (path.Path, error) + + // Search is a version of Resolve which outputs paths as they are discovered, + // reducing the time to first entry + // + // Note: by default, all paths read from the channel are considered unsafe, + // except the latest (last path in channel read buffer). + Search(ctx context.Context, name string, opts ...options.NameResolveOption) (<-chan IpnsResult, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/object.go b/vendor/github.com/ipfs/interface-go-ipfs-core/object.go new file mode 100644 index 00000000..86536d42 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/object.go @@ -0,0 +1,107 @@ +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + "io" + + "github.com/ipfs/interface-go-ipfs-core/options" + + "github.com/ipfs/go-cid" + ipld "github.com/ipfs/go-ipld-format" +) + +// ObjectStat provides information about dag nodes +type ObjectStat struct { + // Cid is the CID of the node + Cid cid.Cid + + // NumLinks is number of links the node contains + NumLinks int + + // BlockSize is size of the raw serialized node + BlockSize int + + // LinksSize is size of the links block section + LinksSize int + + // DataSize is the size of data block section + DataSize int + + // CumulativeSize is size of the tree (BlockSize + link sizes) + CumulativeSize int +} + +// ChangeType denotes type of change in ObjectChange +type ChangeType int + +const ( + // DiffAdd is set when a link was added to the graph + DiffAdd ChangeType = iota + + // DiffRemove is set when a link was removed from the graph + DiffRemove + + // DiffMod is set when a link was changed in the graph + DiffMod +) + +// ObjectChange represents a change ia a graph +type ObjectChange struct { + // Type of the change, either: + // * DiffAdd - Added a link + // * DiffRemove - Removed a link + // * DiffMod - Modified a link + Type ChangeType + + // Path to the changed link + Path string + + // Before holds the link path before the change. Note that when a link is + // added, this will be nil. + Before path.Resolved + + // After holds the link path after the change. Note that when a link is + // removed, this will be nil. + After path.Resolved +} + +// ObjectAPI specifies the interface to MerkleDAG and contains useful utilities +// for manipulating MerkleDAG data structures. +type ObjectAPI interface { + // New creates new, empty (by default) dag-node. + New(context.Context, ...options.ObjectNewOption) (ipld.Node, error) + + // Put imports the data into merkledag + Put(context.Context, io.Reader, ...options.ObjectPutOption) (path.Resolved, error) + + // Get returns the node for the path + Get(context.Context, path.Path) (ipld.Node, error) + + // Data returns reader for data of the node + Data(context.Context, path.Path) (io.Reader, error) + + // Links returns lint or links the node contains + Links(context.Context, path.Path) ([]*ipld.Link, error) + + // Stat returns information about the node + Stat(context.Context, path.Path) (*ObjectStat, error) + + // AddLink adds a link under the specified path. child path can point to a + // subdirectory within the patent which must be present (can be overridden + // with WithCreate option). + AddLink(ctx context.Context, base path.Path, name string, child path.Path, opts ...options.ObjectAddLinkOption) (path.Resolved, error) + + // RmLink removes a link from the node + RmLink(ctx context.Context, base path.Path, link string) (path.Resolved, error) + + // AppendData appends data to the node + AppendData(context.Context, path.Path, io.Reader) (path.Resolved, error) + + // SetData sets the data contained in the node + SetData(context.Context, path.Path, io.Reader) (path.Resolved, error) + + // Diff returns a set of changes needed to transform the first object into the + // second. + Diff(context.Context, path.Path, path.Path) ([]ObjectChange, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/block.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/block.go new file mode 100644 index 00000000..043dfdea --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/block.go @@ -0,0 +1,126 @@ +package options + +import ( + "fmt" + cid "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +type BlockPutSettings struct { + Codec string + MhType uint64 + MhLength int + Pin bool +} + +type BlockRmSettings struct { + Force bool +} + +type BlockPutOption func(*BlockPutSettings) error +type BlockRmOption func(*BlockRmSettings) error + +func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, error) { + options := &BlockPutSettings{ + Codec: "", + MhType: mh.SHA2_256, + MhLength: -1, + Pin: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, cid.Prefix{}, err + } + } + + var pref cid.Prefix + pref.Version = 1 + + if options.Codec == "" { + if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { + options.Codec = "protobuf" + } else { + options.Codec = "v0" + } + } + + if options.Codec == "v0" && options.MhType == mh.SHA2_256 { + pref.Version = 0 + } + + formatval, ok := cid.Codecs[options.Codec] + if !ok { + return nil, cid.Prefix{}, fmt.Errorf("unrecognized format: %s", options.Codec) + } + + if options.Codec == "v0" { + if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) { + return nil, cid.Prefix{}, fmt.Errorf("only sha2-255-32 is allowed with CIDv0") + } + } + + pref.Codec = formatval + + pref.MhType = options.MhType + pref.MhLength = options.MhLength + + return options, pref, nil +} + +func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) { + options := &BlockRmSettings{ + Force: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type blockOpts struct{} + +var Block blockOpts + +// Format is an option for Block.Put which specifies the multicodec to use to +// serialize the object. Default is "v0" +func (blockOpts) Format(codec string) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.Codec = codec + return nil + } +} + +// Hash is an option for Block.Put which specifies the multihash settings to use +// when hashing the object. Default is mh.SHA2_256 (0x12). +// If mhLen is set to -1, default length for the hash will be used +func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.MhType = mhType + settings.MhLength = mhLen + return nil + } +} + +// Pin is an option for Block.Put which specifies whether to (recursively) pin +// added blocks +func (blockOpts) Pin(pin bool) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.Pin = pin + return nil + } +} + +// Force is an option for Block.Rm which, when set to true, will ignore +// non-existing blocks +func (blockOpts) Force(force bool) BlockRmOption { + return func(settings *BlockRmSettings) error { + settings.Force = force + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/dht.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/dht.go new file mode 100644 index 00000000..e13e1602 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/dht.go @@ -0,0 +1,62 @@ +package options + +type DhtProvideSettings struct { + Recursive bool +} + +type DhtFindProvidersSettings struct { + NumProviders int +} + +type DhtProvideOption func(*DhtProvideSettings) error +type DhtFindProvidersOption func(*DhtFindProvidersSettings) error + +func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { + options := &DhtProvideSettings{ + Recursive: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func DhtFindProvidersOptions(opts ...DhtFindProvidersOption) (*DhtFindProvidersSettings, error) { + options := &DhtFindProvidersSettings{ + NumProviders: 20, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type dhtOpts struct{} + +var Dht dhtOpts + +// Recursive is an option for Dht.Provide which specifies whether to provide +// the given path recursively +func (dhtOpts) Recursive(recursive bool) DhtProvideOption { + return func(settings *DhtProvideSettings) error { + settings.Recursive = recursive + return nil + } +} + +// NumProviders is an option for Dht.FindProviders which specifies the +// number of peers to look for. Default is 20 +func (dhtOpts) NumProviders(numProviders int) DhtFindProvidersOption { + return func(settings *DhtFindProvidersSettings) error { + settings.NumProviders = numProviders + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/global.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/global.go new file mode 100644 index 00000000..90e2586f --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/global.go @@ -0,0 +1,47 @@ +package options + +type ApiSettings struct { + Offline bool + FetchBlocks bool +} + +type ApiOption func(*ApiSettings) error + +func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { + options := &ApiSettings{ + Offline: false, + FetchBlocks: true, + } + + return ApiOptionsTo(options, opts...) +} + +func ApiOptionsTo(options *ApiSettings, opts ...ApiOption) (*ApiSettings, error) { + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type apiOpts struct{} + +var Api apiOpts + +func (apiOpts) Offline(offline bool) ApiOption { + return func(settings *ApiSettings) error { + settings.Offline = offline + return nil + } +} + +// FetchBlocks when set to false prevents api from fetching blocks from the +// network while allowing other services such as IPNS to still be online +func (apiOpts) FetchBlocks(fetch bool) ApiOption { + return func(settings *ApiSettings) error { + settings.FetchBlocks = fetch + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/key.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/key.go new file mode 100644 index 00000000..80beea35 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/key.go @@ -0,0 +1,87 @@ +package options + +const ( + RSAKey = "rsa" + Ed25519Key = "ed25519" + + DefaultRSALen = 2048 +) + +type KeyGenerateSettings struct { + Algorithm string + Size int +} + +type KeyRenameSettings struct { + Force bool +} + +type KeyGenerateOption func(*KeyGenerateSettings) error +type KeyRenameOption func(*KeyRenameSettings) error + +func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) { + options := &KeyGenerateSettings{ + Algorithm: RSAKey, + Size: -1, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) { + options := &KeyRenameSettings{ + Force: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type keyOpts struct{} + +var Key keyOpts + +// Type is an option for Key.Generate which specifies which algorithm +// should be used for the key. Default is options.RSAKey +// +// Supported key types: +// * options.RSAKey +// * options.Ed25519Key +func (keyOpts) Type(algorithm string) KeyGenerateOption { + return func(settings *KeyGenerateSettings) error { + settings.Algorithm = algorithm + return nil + } +} + +// Size is an option for Key.Generate which specifies the size of the key to +// generated. Default is -1 +// +// value of -1 means 'use default size for key type': +// * 2048 for RSA +func (keyOpts) Size(size int) KeyGenerateOption { + return func(settings *KeyGenerateSettings) error { + settings.Size = size + return nil + } +} + +// Force is an option for Key.Rename which specifies whether to allow to +// replace existing keys. +func (keyOpts) Force(force bool) KeyRenameOption { + return func(settings *KeyRenameSettings) error { + settings.Force = force + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/name.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/name.go new file mode 100644 index 00000000..59aaf2ca --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/name.go @@ -0,0 +1,122 @@ +package options + +import ( + "time" + + ropts "github.com/ipfs/interface-go-ipfs-core/options/namesys" +) + +const ( + DefaultNameValidTime = 24 * time.Hour +) + +type NamePublishSettings struct { + ValidTime time.Duration + Key string + + TTL *time.Duration + + AllowOffline bool +} + +type NameResolveSettings struct { + Cache bool + + ResolveOpts []ropts.ResolveOpt +} + +type NamePublishOption func(*NamePublishSettings) error +type NameResolveOption func(*NameResolveSettings) error + +func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) { + options := &NamePublishSettings{ + ValidTime: DefaultNameValidTime, + Key: "self", + + AllowOffline: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { + options := &NameResolveSettings{ + Cache: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type nameOpts struct{} + +var Name nameOpts + +// ValidTime is an option for Name.Publish which specifies for how long the +// entry will remain valid. Default value is 24h +func (nameOpts) ValidTime(validTime time.Duration) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.ValidTime = validTime + return nil + } +} + +// Key is an option for Name.Publish which specifies the key to use for +// publishing. Default value is "self" which is the node's own PeerID. +// The key parameter must be either PeerID or keystore key alias. +// +// You can use KeyAPI to list and generate more names and their respective keys. +func (nameOpts) Key(key string) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.Key = key + return nil + } +} + +// AllowOffline is an option for Name.Publish which specifies whether to allow +// publishing when the node is offline. Default value is false +func (nameOpts) AllowOffline(allow bool) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.AllowOffline = allow + return nil + } +} + +// TTL is an option for Name.Publish which specifies the time duration the +// published record should be cached for (caution: experimental). +func (nameOpts) TTL(ttl time.Duration) NamePublishOption { + return func(settings *NamePublishSettings) error { + settings.TTL = &ttl + return nil + } +} + +// Cache is an option for Name.Resolve which specifies if cache should be used. +// Default value is true +func (nameOpts) Cache(cache bool) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.Cache = cache + return nil + } +} + +// +func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption { + return func(settings *NameResolveSettings) error { + settings.ResolveOpts = append(settings.ResolveOpts, opt) + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/namesys/opts.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/namesys/opts.go new file mode 100644 index 00000000..ee2bd5ac --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/namesys/opts.go @@ -0,0 +1,74 @@ +package nsopts + +import ( + "time" +) + +const ( + // DefaultDepthLimit is the default depth limit used by Resolve. + DefaultDepthLimit = 32 + + // UnlimitedDepth allows infinite recursion in Resolve. You + // probably don't want to use this, but it's here if you absolutely + // trust resolution to eventually complete and can't put an upper + // limit on how many steps it will take. + UnlimitedDepth = 0 +) + +// ResolveOpts specifies options for resolving an IPNS path +type ResolveOpts struct { + // Recursion depth limit + Depth uint + // The number of IPNS records to retrieve from the DHT + // (the best record is selected from this set) + DhtRecordCount uint + // The amount of time to wait for DHT records to be fetched + // and verified. A zero value indicates that there is no explicit + // timeout (although there is an implicit timeout due to dial + // timeouts within the DHT) + DhtTimeout time.Duration +} + +// DefaultResolveOpts returns the default options for resolving +// an IPNS path +func DefaultResolveOpts() ResolveOpts { + return ResolveOpts{ + Depth: DefaultDepthLimit, + DhtRecordCount: 16, + DhtTimeout: time.Minute, + } +} + +// ResolveOpt is used to set an option +type ResolveOpt func(*ResolveOpts) + +// Depth is the recursion depth limit +func Depth(depth uint) ResolveOpt { + return func(o *ResolveOpts) { + o.Depth = depth + } +} + +// DhtRecordCount is the number of IPNS records to retrieve from the DHT +func DhtRecordCount(count uint) ResolveOpt { + return func(o *ResolveOpts) { + o.DhtRecordCount = count + } +} + +// DhtTimeout is the amount of time to wait for DHT records to be fetched +// and verified. A zero value indicates that there is no explicit timeout +func DhtTimeout(timeout time.Duration) ResolveOpt { + return func(o *ResolveOpts) { + o.DhtTimeout = timeout + } +} + +// ProcessOpts converts an array of ResolveOpt into a ResolveOpts object +func ProcessOpts(opts []ResolveOpt) ResolveOpts { + rsopts := DefaultResolveOpts() + for _, option := range opts { + option(&rsopts) + } + return rsopts +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/object.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/object.go new file mode 100644 index 00000000..e484a9f3 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/object.go @@ -0,0 +1,124 @@ +package options + +type ObjectNewSettings struct { + Type string +} + +type ObjectPutSettings struct { + InputEnc string + DataType string + Pin bool +} + +type ObjectAddLinkSettings struct { + Create bool +} + +type ObjectNewOption func(*ObjectNewSettings) error +type ObjectPutOption func(*ObjectPutSettings) error +type ObjectAddLinkOption func(*ObjectAddLinkSettings) error + +func ObjectNewOptions(opts ...ObjectNewOption) (*ObjectNewSettings, error) { + options := &ObjectNewSettings{ + Type: "empty", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { + options := &ObjectPutSettings{ + InputEnc: "json", + DataType: "text", + Pin: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func ObjectAddLinkOptions(opts ...ObjectAddLinkOption) (*ObjectAddLinkSettings, error) { + options := &ObjectAddLinkSettings{ + Create: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type objectOpts struct{} + +var Object objectOpts + +// Type is an option for Object.New which allows to change the type of created +// dag node. +// +// Supported types: +// * 'empty' - Empty node +// * 'unixfs-dir' - Empty UnixFS directory +func (objectOpts) Type(t string) ObjectNewOption { + return func(settings *ObjectNewSettings) error { + settings.Type = t + return nil + } +} + +// InputEnc is an option for Object.Put which specifies the input encoding of the +// data. Default is "json". +// +// Supported encodings: +// * "protobuf" +// * "json" +func (objectOpts) InputEnc(e string) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.InputEnc = e + return nil + } +} + +// DataType is an option for Object.Put which specifies the encoding of data +// field when using Json or XML input encoding. +// +// Supported types: +// * "text" (default) +// * "base64" +func (objectOpts) DataType(t string) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.DataType = t + return nil + } +} + +// Pin is an option for Object.Put which specifies whether to pin the added +// objects, default is false +func (objectOpts) Pin(pin bool) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.Pin = pin + return nil + } +} + +// Create is an option for Object.AddLink which specifies whether create required +// directories for the child +func (objectOpts) Create(create bool) ObjectAddLinkOption { + return func(settings *ObjectAddLinkSettings) error { + settings.Create = create + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/pin.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/pin.go new file mode 100644 index 00000000..6b211bb7 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/pin.go @@ -0,0 +1,163 @@ +package options + +type PinAddSettings struct { + Recursive bool +} + +type PinLsSettings struct { + Type string +} + +// PinRmSettings represents the settings of pin rm command +type PinRmSettings struct { + Recursive bool +} + +type PinUpdateSettings struct { + Unpin bool +} + +type PinAddOption func(*PinAddSettings) error + +// PinRmOption pin rm option func +type PinRmOption func(*PinRmSettings) error + +// PinLsOption pin ls option func +type PinLsOption func(*PinLsSettings) error +type PinUpdateOption func(*PinUpdateSettings) error + +func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { + options := &PinAddSettings{ + Recursive: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +// PinRmOptions pin rm options +func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { + options := &PinRmSettings{ + Recursive: true, + } + + for _, opt := range opts { + if err := opt(options); err != nil { + return nil, err + } + } + + return options, nil +} + +func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { + options := &PinLsSettings{ + Type: "all", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { + options := &PinUpdateSettings{ + Unpin: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type pinType struct{} + +type pinOpts struct { + Type pinType +} + +var Pin pinOpts + +// All is an option for Pin.Ls which will make it return all pins. It is +// the default +func (pinType) All() PinLsOption { + return Pin.pinType("all") +} + +// Recursive is an option for Pin.Ls which will make it only return recursive +// pins +func (pinType) Recursive() PinLsOption { + return Pin.pinType("recursive") +} + +// Direct is an option for Pin.Ls which will make it only return direct (non +// recursive) pins +func (pinType) Direct() PinLsOption { + return Pin.pinType("direct") +} + +// Indirect is an option for Pin.Ls which will make it only return indirect pins +// (objects referenced by other recursively pinned objects) +func (pinType) Indirect() PinLsOption { + return Pin.pinType("indirect") +} + +// Recursive is an option for Pin.Add which specifies whether to pin an entire +// object tree or just one object. Default: true +func (pinOpts) Recursive(recursive bool) PinAddOption { + return func(settings *PinAddSettings) error { + settings.Recursive = recursive + return nil + } +} + +// RmRecursive is an option for Pin.Rm which specifies whether to recursively +// unpin the object linked to by the specified object(s). This does not remove +// indirect pins referenced by other recursive pins. +func (pinOpts) RmRecursive(recursive bool) PinRmOption { + return func(settings *PinRmSettings) error { + settings.Recursive = recursive + return nil + } +} + +// Type is an option for Pin.Ls which allows to specify which pin types should +// be returned +// +// Supported values: +// * "direct" - directly pinned objects +// * "recursive" - roots of recursive pins +// * "indirect" - indirectly pinned objects (referenced by recursively pinned +// objects) +// * "all" - all pinned objects (default) +func (pinOpts) pinType(t string) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Type = t + return nil + } +} + +// Unpin is an option for Pin.Update which specifies whether to remove the old pin. +// Default is true. +func (pinOpts) Unpin(unpin bool) PinUpdateOption { + return func(settings *PinUpdateSettings) error { + settings.Unpin = unpin + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/pubsub.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/pubsub.go new file mode 100644 index 00000000..c387d613 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/pubsub.go @@ -0,0 +1,58 @@ +package options + +type PubSubPeersSettings struct { + Topic string +} + +type PubSubSubscribeSettings struct { + Discover bool +} + +type PubSubPeersOption func(*PubSubPeersSettings) error +type PubSubSubscribeOption func(*PubSubSubscribeSettings) error + +func PubSubPeersOptions(opts ...PubSubPeersOption) (*PubSubPeersSettings, error) { + options := &PubSubPeersSettings{ + Topic: "", + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func PubSubSubscribeOptions(opts ...PubSubSubscribeOption) (*PubSubSubscribeSettings, error) { + options := &PubSubSubscribeSettings{ + Discover: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type pubsubOpts struct{} + +var PubSub pubsubOpts + +func (pubsubOpts) Topic(topic string) PubSubPeersOption { + return func(settings *PubSubPeersSettings) error { + settings.Topic = topic + return nil + } +} + +func (pubsubOpts) Discover(discover bool) PubSubSubscribeOption { + return func(settings *PubSubSubscribeSettings) error { + settings.Discover = discover + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/options/unixfs.go b/vendor/github.com/ipfs/interface-go-ipfs-core/options/unixfs.go new file mode 100644 index 00000000..3fd96f77 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/options/unixfs.go @@ -0,0 +1,285 @@ +package options + +import ( + "errors" + "fmt" + + cid "github.com/ipfs/go-cid" + dag "github.com/ipfs/go-merkledag" + mh "github.com/multiformats/go-multihash" +) + +type Layout int + +const ( + BalancedLayout Layout = iota + TrickleLayout +) + +type UnixfsAddSettings struct { + CidVersion int + MhType uint64 + + Inline bool + InlineLimit int + RawLeaves bool + RawLeavesSet bool + + Chunker string + Layout Layout + + Pin bool + OnlyHash bool + FsCache bool + NoCopy bool + + Events chan<- interface{} + Silent bool + Progress bool +} + +type UnixfsLsSettings struct { + ResolveChildren bool +} + +type UnixfsAddOption func(*UnixfsAddSettings) error +type UnixfsLsOption func(*UnixfsLsSettings) error + +func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, error) { + options := &UnixfsAddSettings{ + CidVersion: -1, + MhType: mh.SHA2_256, + + Inline: false, + InlineLimit: 32, + RawLeaves: false, + RawLeavesSet: false, + + Chunker: "size-262144", + Layout: BalancedLayout, + + Pin: false, + OnlyHash: false, + FsCache: false, + NoCopy: false, + + Events: nil, + Silent: false, + Progress: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, cid.Prefix{}, err + } + } + + // nocopy -> rawblocks + if options.NoCopy && !options.RawLeaves { + // fixed? + if options.RawLeavesSet { + return nil, cid.Prefix{}, fmt.Errorf("nocopy option requires '--raw-leaves' to be enabled as well") + } + + // No, satisfy mandatory constraint. + options.RawLeaves = true + } + + // (hash != "sha2-256") -> CIDv1 + if options.MhType != mh.SHA2_256 { + switch options.CidVersion { + case 0: + return nil, cid.Prefix{}, errors.New("CIDv0 only supports sha2-256") + case 1, -1: + options.CidVersion = 1 + default: + return nil, cid.Prefix{}, fmt.Errorf("unknown CID version: %d", options.CidVersion) + } + } else { + if options.CidVersion < 0 { + // Default to CIDv0 + options.CidVersion = 0 + } + } + + // cidV1 -> raw blocks (by default) + if options.CidVersion > 0 && !options.RawLeavesSet { + options.RawLeaves = true + } + + prefix, err := dag.PrefixForCidVersion(options.CidVersion) + if err != nil { + return nil, cid.Prefix{}, err + } + + prefix.MhType = options.MhType + prefix.MhLength = -1 + + return options, prefix, nil +} + +func UnixfsLsOptions(opts ...UnixfsLsOption) (*UnixfsLsSettings, error) { + options := &UnixfsLsSettings{ + ResolveChildren: true, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + + return options, nil +} + +type unixfsOpts struct{} + +var Unixfs unixfsOpts + +// CidVersion specifies which CID version to use. Defaults to 0 unless an option +// that depends on CIDv1 is passed. +func (unixfsOpts) CidVersion(version int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.CidVersion = version + return nil + } +} + +// Hash function to use. Implies CIDv1 if not set to sha2-256 (default). +// +// Table of functions is declared in https://github.com/multiformats/go-multihash/blob/master/multihash.go +func (unixfsOpts) Hash(mhtype uint64) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.MhType = mhtype + return nil + } +} + +// RawLeaves specifies whether to use raw blocks for leaves (data nodes with no +// links) instead of wrapping them with unixfs structures. +func (unixfsOpts) RawLeaves(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.RawLeaves = enable + settings.RawLeavesSet = true + return nil + } +} + +// Inline tells the adder to inline small blocks into CIDs +func (unixfsOpts) Inline(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Inline = enable + return nil + } +} + +// InlineLimit sets the amount of bytes below which blocks will be encoded +// directly into CID instead of being stored and addressed by it's hash. +// Specifying this option won't enable block inlining. For that use `Inline` +// option. Default: 32 bytes +// +// Note that while there is no hard limit on the number of bytes, it should be +// kept at a reasonably low value, such as 64; implementations may choose to +// reject anything larger. +func (unixfsOpts) InlineLimit(limit int) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.InlineLimit = limit + return nil + } +} + +// Chunker specifies settings for the chunking algorithm to use. +// +// Default: size-262144, formats: +// size-[bytes] - Simple chunker splitting data into blocks of n bytes +// rabin-[min]-[avg]-[max] - Rabin chunker +func (unixfsOpts) Chunker(chunker string) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Chunker = chunker + return nil + } +} + +// Layout tells the adder how to balance data between leaves. +// options.BalancedLayout is the default, it's optimized for static seekable +// files. +// options.TrickleLayout is optimized for streaming data, +func (unixfsOpts) Layout(layout Layout) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Layout = layout + return nil + } +} + +// Pin tells the adder to pin the file root recursively after adding +func (unixfsOpts) Pin(pin bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Pin = pin + return nil + } +} + +// HashOnly will make the adder calculate data hash without storing it in the +// blockstore or announcing it to the network +func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.OnlyHash = hashOnly + return nil + } +} + +// Events specifies channel which will be used to report events about ongoing +// Add operation. +// +// Note that if this channel blocks it may slowdown the adder +func (unixfsOpts) Events(sink chan<- interface{}) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Events = sink + return nil + } +} + +// Silent reduces event output +func (unixfsOpts) Silent(silent bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Silent = silent + return nil + } +} + +// Progress tells the adder whether to enable progress events +func (unixfsOpts) Progress(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.Progress = enable + return nil + } +} + +// FsCache tells the adder to check the filestore for pre-existing blocks +// +// Experimental +func (unixfsOpts) FsCache(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.FsCache = enable + return nil + } +} + +// NoCopy tells the adder to add the files using filestore. Implies RawLeaves. +// +// Experimental +func (unixfsOpts) Nocopy(enable bool) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.NoCopy = enable + return nil + } +} + +func (unixfsOpts) ResolveChildren(resolve bool) UnixfsLsOption { + return func(settings *UnixfsLsSettings) error { + settings.ResolveChildren = resolve + return nil + } +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/path/path.go b/vendor/github.com/ipfs/interface-go-ipfs-core/path/path.go new file mode 100644 index 00000000..01b1673b --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/path/path.go @@ -0,0 +1,199 @@ +package path + +import ( + "strings" + + cid "github.com/ipfs/go-cid" + ipfspath "github.com/ipfs/go-path" +) + +// Path is a generic wrapper for paths used in the API. A path can be resolved +// to a CID using one of Resolve functions in the API. +// +// Paths must be prefixed with a valid prefix: +// +// * /ipfs - Immutable unixfs path (files) +// * /ipld - Immutable ipld path (data) +// * /ipns - Mutable names. Usually resolves to one of the immutable paths +//TODO: /local (MFS) +type Path interface { + // String returns the path as a string. + String() string + + // Namespace returns the first component of the path. + // + // For example path "/ipfs/QmHash", calling Namespace() will return "ipfs" + // + // Calling this method on invalid paths (IsValid() != nil) will result in + // empty string + Namespace() string + + // Mutable returns false if the data pointed to by this path in guaranteed + // to not change. + // + // Note that resolved mutable path can be immutable. + Mutable() bool + + // IsValid checks if this path is a valid ipfs Path, returning nil iff it is + // valid + IsValid() error +} + +// Resolved is a path which was resolved to the last resolvable node. +// ResolvedPaths are guaranteed to return nil from `IsValid` +type Resolved interface { + // Cid returns the CID of the node referenced by the path. Remainder of the + // path is guaranteed to be within the node. + // + // Examples: + // If you have 3 linked objects: QmRoot -> A -> B: + // + // cidB := {"foo": {"bar": 42 }} + // cidA := {"B": {"/": cidB }} + // cidRoot := {"A": {"/": cidA }} + // + // And resolve paths: + // + // * "/ipfs/${cidRoot}" + // * Calling Cid() will return `cidRoot` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A" + // * Calling Cid() will return `cidA` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `` + // + // * "/ipfs/${cidRoot}/A/B/foo" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo` + // + // * "/ipfs/${cidRoot}/A/B/foo/bar" + // * Calling Cid() will return `cidB` + // * Calling Root() will return `cidRoot` + // * Calling Remainder() will return `foo/bar` + Cid() cid.Cid + + // Root returns the CID of the root object of the path + // + // Example: + // If you have 3 linked objects: QmRoot -> A -> B, and resolve path + // "/ipfs/QmRoot/A/B", the Root method will return the CID of object QmRoot + // + // For more examples see the documentation of Cid() method + Root() cid.Cid + + // Remainder returns unresolved part of the path + // + // Example: + // If you have 2 linked objects: QmRoot -> A, where A is a CBOR node + // containing the following data: + // + // {"foo": {"bar": 42 }} + // + // When resolving "/ipld/QmRoot/A/foo/bar", Remainder will return "foo/bar" + // + // For more examples see the documentation of Cid() method + Remainder() string + + Path +} + +// path implements coreiface.Path +type path struct { + path string +} + +// resolvedPath implements coreiface.resolvedPath +type resolvedPath struct { + path + cid cid.Cid + root cid.Cid + remainder string +} + +// Join appends provided segments to the base path +func Join(base Path, a ...string) Path { + s := strings.Join(append([]string{base.String()}, a...), "/") + return &path{path: s} +} + +// IpfsPath creates new /ipfs path from the provided CID +func IpfsPath(c cid.Cid) Resolved { + return &resolvedPath{ + path: path{"/ipfs/" + c.String()}, + cid: c, + root: c, + remainder: "", + } +} + +// IpldPath creates new /ipld path from the provided CID +func IpldPath(c cid.Cid) Resolved { + return &resolvedPath{ + path: path{"/ipld/" + c.String()}, + cid: c, + root: c, + remainder: "", + } +} + +// New parses string path to a Path +func New(p string) Path { + if pp, err := ipfspath.ParsePath(p); err == nil { + p = pp.String() + } + + return &path{path: p} +} + +// NewResolvedPath creates new Resolved path. This function performs no checks +// and is intended to be used by resolver implementations. Incorrect inputs may +// cause panics. Handle with care. +func NewResolvedPath(ipath ipfspath.Path, c cid.Cid, root cid.Cid, remainder string) Resolved { + return &resolvedPath{ + path: path{ipath.String()}, + cid: c, + root: root, + remainder: remainder, + } +} + +func (p *path) String() string { + return p.path +} + +func (p *path) Namespace() string { + ip, err := ipfspath.ParsePath(p.path) + if err != nil { + return "" + } + + if len(ip.Segments()) < 1 { + panic("path without namespace") // this shouldn't happen under any scenario + } + return ip.Segments()[0] +} + +func (p *path) Mutable() bool { + // TODO: MFS: check for /local + return p.Namespace() == "ipns" +} + +func (p *path) IsValid() error { + _, err := ipfspath.ParsePath(p.path) + return err +} + +func (p *resolvedPath) Cid() cid.Cid { + return p.cid +} + +func (p *resolvedPath) Root() cid.Cid { + return p.root +} + +func (p *resolvedPath) Remainder() string { + return p.remainder +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/pin.go b/vendor/github.com/ipfs/interface-go-ipfs-core/pin.go new file mode 100644 index 00000000..7df2956f --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/pin.go @@ -0,0 +1,55 @@ +package iface + +import ( + "context" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/interface-go-ipfs-core/options" +) + +// Pin holds information about pinned resource +type Pin interface { + // Path to the pinned object + Path() path.Resolved + + // Type of the pin + Type() string +} + +// PinStatus holds information about pin health +type PinStatus interface { + // Ok indicates whether the pin has been verified to be correct + Ok() bool + + // BadNodes returns any bad (usually missing) nodes from the pin + BadNodes() []BadPinNode +} + +// BadPinNode is a node that has been marked as bad by Pin.Verify +type BadPinNode interface { + // Path is the path of the node + Path() path.Resolved + + // Err is the reason why the node has been marked as bad + Err() error +} + +// PinAPI specifies the interface to pining +type PinAPI interface { + // Add creates new pin, be default recursive - pinning the whole referenced + // tree + Add(context.Context, path.Path, ...options.PinAddOption) error + + // Ls returns list of pinned objects on this node + Ls(context.Context, ...options.PinLsOption) ([]Pin, error) + + // Rm removes pin for object specified by the path + Rm(context.Context, path.Path, ...options.PinRmOption) error + + // Update changes one pin to another, skipping checks for matching paths in + // the old tree + Update(ctx context.Context, from path.Path, to path.Path, opts ...options.PinUpdateOption) error + + // Verify verifies the integrity of pinned objects + Verify(context.Context) (<-chan PinStatus, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/pubsub.go b/vendor/github.com/ipfs/interface-go-ipfs-core/pubsub.go new file mode 100644 index 00000000..d9826551 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/pubsub.go @@ -0,0 +1,48 @@ +package iface + +import ( + "context" + "io" + + options "github.com/ipfs/interface-go-ipfs-core/options" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// PubSubSubscription is an active PubSub subscription +type PubSubSubscription interface { + io.Closer + + // Next return the next incoming message + Next(context.Context) (PubSubMessage, error) +} + +// PubSubMessage is a single PubSub message +type PubSubMessage interface { + // From returns id of a peer from which the message has arrived + From() peer.ID + + // Data returns the message body + Data() []byte + + // Seq returns message identifier + Seq() []byte + + // Topics returns list of topics this message was set to + Topics() []string +} + +// PubSubAPI specifies the interface to PubSub +type PubSubAPI interface { + // Ls lists subscribed topics by name + Ls(context.Context) ([]string, error) + + // Peers list peers we are currently pubsubbing with + Peers(context.Context, ...options.PubSubPeersOption) ([]peer.ID, error) + + // Publish a message to a given pubsub topic + Publish(context.Context, string, []byte) error + + // Subscribe to messages on a given topic + Subscribe(context.Context, string, ...options.PubSubSubscribeOption) (PubSubSubscription, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/swarm.go b/vendor/github.com/ipfs/interface-go-ipfs-core/swarm.go new file mode 100644 index 00000000..d7b25d5e --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/swarm.go @@ -0,0 +1,57 @@ +package iface + +import ( + "context" + "errors" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + + ma "github.com/multiformats/go-multiaddr" +) + +var ( + ErrNotConnected = errors.New("not connected") + ErrConnNotFound = errors.New("conn not found") +) + +// ConnectionInfo contains information about a peer +type ConnectionInfo interface { + // ID returns PeerID + ID() peer.ID + + // Address returns the multiaddress via which we are connected with the peer + Address() ma.Multiaddr + + // Direction returns which way the connection was established + Direction() network.Direction + + // Latency returns last known round trip time to the peer + Latency() (time.Duration, error) + + // Streams returns list of streams established with the peer + Streams() ([]protocol.ID, error) +} + +// SwarmAPI specifies the interface to libp2p swarm +type SwarmAPI interface { + // Connect to a given peer + Connect(context.Context, peer.AddrInfo) error + + // Disconnect from a given address + Disconnect(context.Context, ma.Multiaddr) error + + // Peers returns the list of peers we are connected to + Peers(context.Context) ([]ConnectionInfo, error) + + // KnownAddrs returns the list of all addresses this node is aware of + KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) + + // LocalAddrs returns the list of announced listening addresses + LocalAddrs(context.Context) ([]ma.Multiaddr, error) + + // ListenAddrs returns the list of all listening addresses + ListenAddrs(context.Context) ([]ma.Multiaddr, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/unixfs.go b/vendor/github.com/ipfs/interface-go-ipfs-core/unixfs.go new file mode 100644 index 00000000..686c4029 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/unixfs.go @@ -0,0 +1,79 @@ +package iface + +import ( + "context" + "github.com/ipfs/interface-go-ipfs-core/options" + path "github.com/ipfs/interface-go-ipfs-core/path" + + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs-files" +) + +type AddEvent struct { + Name string + Path path.Resolved `json:",omitempty"` + Bytes int64 `json:",omitempty"` + Size string `json:",omitempty"` +} + +// FileType is an enum of possible UnixFS file types. +type FileType int32 + +const ( + // TUnknown means the file type isn't known (e.g., it hasn't been + // resolved). + TUnknown FileType = iota + // TFile is a regular file. + TFile + // TDirectory is a directory. + TDirectory + // TSymlink is a symlink. + TSymlink +) + +func (t FileType) String() string { + switch t { + case TUnknown: + return "unknown" + case TFile: + return "file" + case TDirectory: + return "directory" + case TSymlink: + return "symlink" + default: + return "" + } +} + +// DirEntry is a directory entry returned by `Ls`. +type DirEntry struct { + Name string + Cid cid.Cid + + // Only filled when asked to resolve the directory entry. + Size uint64 // The size of the file in bytes (or the size of the symlink). + Type FileType // The type of the file. + Target string // The symlink target (if a symlink). + + Err error +} + +// UnixfsAPI is the basic interface to immutable files in IPFS +// NOTE: This API is heavily WIP, things are guaranteed to break frequently +type UnixfsAPI interface { + // Add imports the data from the reader into merkledag file + // + // TODO: a long useful comment on how to use this for many different scenarios + Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.Resolved, error) + + // Get returns a read-only handle to a file tree referenced by a path + // + // Note that some implementations of this API may apply the specified context + // to operations performed on the returned file + Get(context.Context, path.Path) (files.Node, error) + + // Ls returns the list of links in a directory. Links aren't guaranteed to be + // returned in order + Ls(context.Context, path.Path, ...options.UnixfsLsOption) (<-chan DirEntry, error) +} diff --git a/vendor/github.com/ipfs/interface-go-ipfs-core/util.go b/vendor/github.com/ipfs/interface-go-ipfs-core/util.go new file mode 100644 index 00000000..6d58bf40 --- /dev/null +++ b/vendor/github.com/ipfs/interface-go-ipfs-core/util.go @@ -0,0 +1,20 @@ +package iface + +import ( + "context" + "io" +) + +type Reader interface { + ReadSeekCloser + Size() uint64 + CtxReadFull(context.Context, []byte) (int, error) +} + +// A ReadSeekCloser implements interfaces to read, copy, seek and close. +type ReadSeekCloser interface { + io.Reader + io.Seeker + io.Closer + io.WriterTo +} diff --git a/vendor/github.com/jackpal/gateway/.travis.yml b/vendor/github.com/jackpal/gateway/.travis.yml new file mode 100644 index 00000000..9c3f6547 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/.travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + - 1.6.2 + - tip + +allowed_failures: + - go: tip + +install: + - go get -d -v ./... && go install -race -v ./... + +script: go test -race -v ./... diff --git a/vendor/github.com/jackpal/gateway/LICENSE b/vendor/github.com/jackpal/gateway/LICENSE new file mode 100644 index 00000000..c9efac32 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2010 Jack Palevich. All rights reserved. +// +// 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. diff --git a/vendor/github.com/jackpal/gateway/README.md b/vendor/github.com/jackpal/gateway/README.md new file mode 100644 index 00000000..6a2b2125 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/README.md @@ -0,0 +1,18 @@ +# gateway + +A simple library for discovering the IP address of the default gateway. + + +[![Build Status](https://travis-ci.org/jackpal/gateway.svg)](https://travis-ci.org/jackpal/gateway) + +Provides implementations for: + ++ FreeBSD ++ Linux ++ OS X (Darwin) ++ Solaris ++ Windows + +Other platforms use an implementation that always returns an error. + +Pull requests for other OSs happily considered! diff --git a/vendor/github.com/jackpal/gateway/gateway_common.go b/vendor/github.com/jackpal/gateway/gateway_common.go new file mode 100644 index 00000000..441ea62e --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_common.go @@ -0,0 +1,146 @@ +package gateway + +import ( + "errors" + "net" + "strings" +) + +var errNoGateway = errors.New("no gateway found") + +func parseWindowsRoutePrint(output []byte) (net.IP, error) { + // Windows route output format is always like this: + // =========================================================================== + // Active Routes: + // Network Destination Netmask Gateway Interface Metric + // 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 20 + // =========================================================================== + // I'm trying to pick the active route, + // then jump 2 lines and pick the third IP + // Not using regex because output is quite standard from Windows XP to 8 (NEEDS TESTING) + lines := strings.Split(string(output), "\n") + for idx, line := range lines { + if strings.HasPrefix(line, "Active Routes:") { + if len(lines) <= idx+2 { + return nil, errNoGateway + } + + fields := strings.Fields(lines[idx+2]) + if len(fields) < 3 { + return nil, errNoGateway + } + + ip := net.ParseIP(fields[2]) + if ip != nil { + return ip, nil + } + } + } + return nil, errNoGateway +} + +func parseLinuxIPRouteShow(output []byte) (net.IP, error) { + // Linux '/usr/bin/ip route show' format looks like this: + // default via 192.168.178.1 dev wlp3s0 metric 303 + // 192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303 + lines := strings.Split(string(output), "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) >= 3 && fields[0] == "default" { + ip := net.ParseIP(fields[2]) + if ip != nil { + return ip, nil + } + } + } + + return nil, errNoGateway +} + +func parseLinuxIPRouteGet(output []byte) (net.IP, error) { + // Linux '/usr/bin/ip route get 8.8.8.8' format looks like this: + // 8.8.8.8 via 10.0.1.1 dev eth0 src 10.0.1.36 uid 2000 + lines := strings.Split(string(output), "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) >= 2 && fields[1] == "via" { + ip := net.ParseIP(fields[2]) + if ip != nil { + return ip, nil + } + } + } + + return nil, errNoGateway +} + +func parseLinuxRoute(output []byte) (net.IP, error) { + // Linux route out format is always like this: + // Kernel IP routing table + // Destination Gateway Genmask Flags Metric Ref Use Iface + // 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 + lines := strings.Split(string(output), "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) >= 2 && fields[0] == "0.0.0.0" { + ip := net.ParseIP(fields[1]) + if ip != nil { + return ip, nil + } + } + } + + return nil, errNoGateway +} + +func parseDarwinRouteGet(output []byte) (net.IP, error) { + // Darwin route out format is always like this: + // route to: default + // destination: default + // mask: default + // gateway: 192.168.1.1 + lines := strings.Split(string(output), "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) >= 2 && fields[0] == "gateway:" { + ip := net.ParseIP(fields[1]) + if ip != nil { + return ip, nil + } + } + } + + return nil, errNoGateway +} + +func parseBSDSolarisNetstat(output []byte) (net.IP, error) { + // netstat -rn produces the following on FreeBSD: + // Routing tables + // + // Internet: + // Destination Gateway Flags Netif Expire + // default 10.88.88.2 UGS em0 + // 10.88.88.0/24 link#1 U em0 + // 10.88.88.148 link#1 UHS lo0 + // 127.0.0.1 link#2 UH lo0 + // + // Internet6: + // Destination Gateway Flags Netif Expire + // ::/96 ::1 UGRS lo0 + // ::1 link#2 UH lo0 + // ::ffff:0.0.0.0/96 ::1 UGRS lo0 + // fe80::/10 ::1 UGRS lo0 + // ... + outputLines := strings.Split(string(output), "\n") + for _, line := range outputLines { + fields := strings.Fields(line) + if len(fields) >= 2 && fields[0] == "default" { + ip := net.ParseIP(fields[1]) + if ip != nil { + return ip, nil + } + } + } + + return nil, errNoGateway +} diff --git a/vendor/github.com/jackpal/gateway/gateway_darwin.go b/vendor/github.com/jackpal/gateway/gateway_darwin.go new file mode 100644 index 00000000..32e755cb --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_darwin.go @@ -0,0 +1,16 @@ +package gateway + +import ( + "net" + "os/exec" +) + +func DiscoverGateway() (net.IP, error) { + routeCmd := exec.Command("/sbin/route", "-n", "get", "0.0.0.0") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseDarwinRouteGet(output) +} diff --git a/vendor/github.com/jackpal/gateway/gateway_freebsd.go b/vendor/github.com/jackpal/gateway/gateway_freebsd.go new file mode 100644 index 00000000..3d669108 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_freebsd.go @@ -0,0 +1,16 @@ +package gateway + +import ( + "net" + "os/exec" +) + +func DiscoverGateway() (ip net.IP, err error) { + routeCmd := exec.Command("netstat", "-rn") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseBSDSolarisNetstat(output) +} diff --git a/vendor/github.com/jackpal/gateway/gateway_linux.go b/vendor/github.com/jackpal/gateway/gateway_linux.go new file mode 100644 index 00000000..aacaa88e --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_linux.go @@ -0,0 +1,47 @@ +package gateway + +import ( + "net" + "os/exec" +) + +func DiscoverGateway() (ip net.IP, err error) { + ip, err = discoverGatewayUsingRoute() + if err != nil { + ip, err = discoverGatewayUsingIpRouteShow() + } + if err != nil { + ip, err = discoverGatewayUsingIpRouteGet() + } + return +} + +func discoverGatewayUsingIpRouteShow() (net.IP, error) { + routeCmd := exec.Command("ip", "route", "show") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseLinuxIPRouteShow(output) +} + +func discoverGatewayUsingIpRouteGet() (net.IP, error) { + routeCmd := exec.Command("ip", "route", "get", "8.8.8.8") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseLinuxIPRouteGet(output) +} + +func discoverGatewayUsingRoute() (net.IP, error) { + routeCmd := exec.Command("route", "-n") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseLinuxRoute(output) +} diff --git a/vendor/github.com/jackpal/gateway/gateway_solaris.go b/vendor/github.com/jackpal/gateway/gateway_solaris.go new file mode 100644 index 00000000..3d669108 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_solaris.go @@ -0,0 +1,16 @@ +package gateway + +import ( + "net" + "os/exec" +) + +func DiscoverGateway() (ip net.IP, err error) { + routeCmd := exec.Command("netstat", "-rn") + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseBSDSolarisNetstat(output) +} diff --git a/vendor/github.com/jackpal/gateway/gateway_unimplemented.go b/vendor/github.com/jackpal/gateway/gateway_unimplemented.go new file mode 100644 index 00000000..750ac4b7 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_unimplemented.go @@ -0,0 +1,14 @@ +// +build !darwin,!linux,!windows,!solaris,!freebsd + +package gateway + +import ( + "fmt" + "net" + "runtime" +) + +func DiscoverGateway() (ip net.IP, err error) { + err = fmt.Errorf("DiscoverGateway not implemented for OS %s", runtime.GOOS) + return +} diff --git a/vendor/github.com/jackpal/gateway/gateway_windows.go b/vendor/github.com/jackpal/gateway/gateway_windows.go new file mode 100644 index 00000000..2419c831 --- /dev/null +++ b/vendor/github.com/jackpal/gateway/gateway_windows.go @@ -0,0 +1,18 @@ +package gateway + +import ( + "net" + "os/exec" + "syscall" +) + +func DiscoverGateway() (ip net.IP, err error) { + routeCmd := exec.Command("route", "print", "0.0.0.0") + routeCmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} + output, err := routeCmd.CombinedOutput() + if err != nil { + return nil, err + } + + return parseWindowsRoutePrint(output) +} diff --git a/vendor/github.com/jbenet/go-is-domain/.travis.yml b/vendor/github.com/jbenet/go-is-domain/.travis.yml new file mode 100644 index 00000000..3590e6d9 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/.travis.yml @@ -0,0 +1,18 @@ +os: + - linux + +language: go + +go: + - 1.12.x + +env: + GO111MODULE=on + +cache: + directories: + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/jbenet/go-is-domain/LICENSE b/vendor/github.com/jbenet/go-is-domain/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/jbenet/go-is-domain/README.md b/vendor/github.com/jbenet/go-is-domain/README.md new file mode 100644 index 00000000..abf48bc1 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/README.md @@ -0,0 +1,29 @@ +# go-is-domain + +This package is dedicated to [@whyrusleeping](https://github.com/whyrusleeping). + +Docs: https://godoc.org/github.com/jbenet/go-is-domain + + +Check whether something is a domain. + + +```Go + +import ( + isd "github.com/jbenet/go-is-domain" +) + +isd.IsDomain("foo.com") // true +isd.IsDomain("foo.bar.com.") // true +isd.IsDomain("foo.bar.baz") // false + +``` + +MIT Licensed + +## Updating TLDs + +To update non-extended TLDs, IANA publishes, you can retrieve them from [data.iana.org](https://data.iana.org/TLD/tlds-alpha-by-domain.txt). + +After retrieving the updated list, enter them into the file `tlds-alpha-by-domain.txt`. In order to update the `TLDs` map in `tlds.go`, you can run the `gen.sh` script which will generate the contents of a `string -> bool` map. After that, you'll want to replace the contents of the existing `TLDs` map, with the one that was generated and stored in `formatted_tlds.txt` diff --git a/vendor/github.com/jbenet/go-is-domain/doc.go b/vendor/github.com/jbenet/go-is-domain/doc.go new file mode 100644 index 00000000..db6855c4 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/doc.go @@ -0,0 +1,13 @@ +/* +Package isdomain package allows users to check whether strings represent domain names. + + import ( + isd "github.com/jbenet/go-is-domain" + ) + + isd.IsDomain("foo.com") // true + isd.IsDomain("foo.bar.com.") // true + isd.IsDomain("foo.bar.baz") // false + +*/ +package isdomain diff --git a/vendor/github.com/jbenet/go-is-domain/domainre.go b/vendor/github.com/jbenet/go-is-domain/domainre.go new file mode 100644 index 00000000..b6caf4a8 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/domainre.go @@ -0,0 +1,12 @@ +package isdomain + +import "regexp" + +// DomainRegexpStr is a regular expression string to validate domains. +const DomainRegexpStr = "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*$" + +var domainRegexp *regexp.Regexp + +func init() { + domainRegexp = regexp.MustCompile(DomainRegexpStr) +} diff --git a/vendor/github.com/jbenet/go-is-domain/go.mod b/vendor/github.com/jbenet/go-is-domain/go.mod new file mode 100644 index 00000000..5a4885b3 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/go.mod @@ -0,0 +1,3 @@ +module github.com/jbenet/go-is-domain + +go 1.12 diff --git a/vendor/github.com/jbenet/go-is-domain/is_domain.go b/vendor/github.com/jbenet/go-is-domain/is_domain.go new file mode 100644 index 00000000..9e6f0469 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/is_domain.go @@ -0,0 +1,54 @@ +package isdomain + +import ( + "strings" +) + +//go:generate bash regenerate-tlds.sh + +// IsICANNTLD returns whether the given string is a TLD (Top Level Domain), +// according to ICANN. Well, really according to the TLDs listed in this +// package. +func IsICANNTLD(s string) bool { + s = strings.ToUpper(s) + _, found := TLDs[s] + return found +} + +// IsExtendedTLD returns whether the given string is a TLD (Top Level Domain), +// extended with a few other "TLDs": .bit, .onion +func IsExtendedTLD(s string) bool { + s = strings.ToUpper(s) + _, found := ExtendedTLDs[s] + return found +} + +// IsTLD returns whether the given string is a TLD (according to ICANN, or +// in the set of ExtendedTLDs listed in this package. +func IsTLD(s string) bool { + return IsICANNTLD(s) || IsExtendedTLD(s) +} + +// IsDomain returns whether given string is a domain. +// It first checks the TLD, and then uses a regular expression. +func IsDomain(s string) bool { + if strings.HasSuffix(s, ".") { + s = s[:len(s)-1] + } + split := strings.Split(s, ".") + + // Need a TLD and a domain. + if len(split) < 2 { + return false + } + + // Check the TLD + tld := split[len(split)-1] + if !IsTLD(tld) { + return false + } + + // Check the domain. + s = strings.ToLower(s) + return domainRegexp.MatchString(s) +} diff --git a/vendor/github.com/jbenet/go-is-domain/package.json b/vendor/github.com/jbenet/go-is-domain/package.json new file mode 100644 index 00000000..002aea25 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/package.json @@ -0,0 +1,16 @@ +{ + "author": "jbenet", + "bugs": { + "URL": "https://github.com/jbenet/go-is-domain/issues", + "url": "https://github.com/jbenet/go-is-domain/issues" + }, + "gx": { + "dvcsimport": "github.com/jbenet/go-is-domain" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "MIT", + "name": "go-is-domain", + "version": "1.0.2" +} + diff --git a/vendor/github.com/jbenet/go-is-domain/regenerate-tlds.sh b/vendor/github.com/jbenet/go-is-domain/regenerate-tlds.sh new file mode 100755 index 00000000..2420cac7 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/regenerate-tlds.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +out=${1-tlds_iana.go} + +list=$(mktemp) + +wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -O $list + +header=$(head -1 $list) + +cat > $out <> $out + +echo '}' >> $out + +gofmt -w $out diff --git a/vendor/github.com/jbenet/go-is-domain/tlds_custom.go b/vendor/github.com/jbenet/go-is-domain/tlds_custom.go new file mode 100644 index 00000000..8fe80f8c --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/tlds_custom.go @@ -0,0 +1,8 @@ +package isdomain + +// ExtendedTLDs is a set of additional "TLDs", allowing decentralized name +// systems, like TOR and Namecoin. +var ExtendedTLDs = map[string]bool{ + "BIT": true, + "ONION": true, +} diff --git a/vendor/github.com/jbenet/go-is-domain/tlds_iana.go b/vendor/github.com/jbenet/go-is-domain/tlds_iana.go new file mode 100644 index 00000000..221c0d54 --- /dev/null +++ b/vendor/github.com/jbenet/go-is-domain/tlds_iana.go @@ -0,0 +1,1537 @@ +package isdomain + +// # Version 2019032100, Last Updated Thu Mar 21 07:07:01 2019 UTC +var TLDs = map[string]bool{ + "AAA": true, + "AARP": true, + "ABARTH": true, + "ABB": true, + "ABBOTT": true, + "ABBVIE": true, + "ABC": true, + "ABLE": true, + "ABOGADO": true, + "ABUDHABI": true, + "AC": true, + "ACADEMY": true, + "ACCENTURE": true, + "ACCOUNTANT": true, + "ACCOUNTANTS": true, + "ACO": true, + "ACTOR": true, + "AD": true, + "ADAC": true, + "ADS": true, + "ADULT": true, + "AE": true, + "AEG": true, + "AERO": true, + "AETNA": true, + "AF": true, + "AFAMILYCOMPANY": true, + "AFL": true, + "AFRICA": true, + "AG": true, + "AGAKHAN": true, + "AGENCY": true, + "AI": true, + "AIG": true, + "AIGO": true, + "AIRBUS": true, + "AIRFORCE": true, + "AIRTEL": true, + "AKDN": true, + "AL": true, + "ALFAROMEO": true, + "ALIBABA": true, + "ALIPAY": true, + "ALLFINANZ": true, + "ALLSTATE": true, + "ALLY": true, + "ALSACE": true, + "ALSTOM": true, + "AM": true, + "AMERICANEXPRESS": true, + "AMERICANFAMILY": true, + "AMEX": true, + "AMFAM": true, + "AMICA": true, + "AMSTERDAM": true, + "ANALYTICS": true, + "ANDROID": true, + "ANQUAN": true, + "ANZ": true, + "AO": true, + "AOL": true, + "APARTMENTS": true, + "APP": true, + "APPLE": true, + "AQ": true, + "AQUARELLE": true, + "AR": true, + "ARAB": true, + "ARAMCO": true, + "ARCHI": true, + "ARMY": true, + "ARPA": true, + "ART": true, + "ARTE": true, + "AS": true, + "ASDA": true, + "ASIA": true, + "ASSOCIATES": true, + "AT": true, + "ATHLETA": true, + "ATTORNEY": true, + "AU": true, + "AUCTION": true, + "AUDI": true, + "AUDIBLE": true, + "AUDIO": true, + "AUSPOST": true, + "AUTHOR": true, + "AUTO": true, + "AUTOS": true, + "AVIANCA": true, + "AW": true, + "AWS": true, + "AX": true, + "AXA": true, + "AZ": true, + "AZURE": true, + "BA": true, + "BABY": true, + "BAIDU": true, + "BANAMEX": true, + "BANANAREPUBLIC": true, + "BAND": true, + "BANK": true, + "BAR": true, + "BARCELONA": true, + "BARCLAYCARD": true, + "BARCLAYS": true, + "BAREFOOT": true, + "BARGAINS": true, + "BASEBALL": true, + "BASKETBALL": true, + "BAUHAUS": true, + "BAYERN": true, + "BB": true, + "BBC": true, + "BBT": true, + "BBVA": true, + "BCG": true, + "BCN": true, + "BD": true, + "BE": true, + "BEATS": true, + "BEAUTY": true, + "BEER": true, + "BENTLEY": true, + "BERLIN": true, + "BEST": true, + "BESTBUY": true, + "BET": true, + "BF": true, + "BG": true, + "BH": true, + "BHARTI": true, + "BI": true, + "BIBLE": true, + "BID": true, + "BIKE": true, + "BING": true, + "BINGO": true, + "BIO": true, + "BIZ": true, + "BJ": true, + "BLACK": true, + "BLACKFRIDAY": true, + "BLOCKBUSTER": true, + "BLOG": true, + "BLOOMBERG": true, + "BLUE": true, + "BM": true, + "BMS": true, + "BMW": true, + "BN": true, + "BNL": true, + "BNPPARIBAS": true, + "BO": true, + "BOATS": true, + "BOEHRINGER": true, + "BOFA": true, + "BOM": true, + "BOND": true, + "BOO": true, + "BOOK": true, + "BOOKING": true, + "BOSCH": true, + "BOSTIK": true, + "BOSTON": true, + "BOT": true, + "BOUTIQUE": true, + "BOX": true, + "BR": true, + "BRADESCO": true, + "BRIDGESTONE": true, + "BROADWAY": true, + "BROKER": true, + "BROTHER": true, + "BRUSSELS": true, + "BS": true, + "BT": true, + "BUDAPEST": true, + "BUGATTI": true, + "BUILD": true, + "BUILDERS": true, + "BUSINESS": true, + "BUY": true, + "BUZZ": true, + "BV": true, + "BW": true, + "BY": true, + "BZ": true, + "BZH": true, + "CA": true, + "CAB": true, + "CAFE": true, + "CAL": true, + "CALL": true, + "CALVINKLEIN": true, + "CAM": true, + "CAMERA": true, + "CAMP": true, + "CANCERRESEARCH": true, + "CANON": true, + "CAPETOWN": true, + "CAPITAL": true, + "CAPITALONE": true, + "CAR": true, + "CARAVAN": true, + "CARDS": true, + "CARE": true, + "CAREER": true, + "CAREERS": true, + "CARS": true, + "CARTIER": true, + "CASA": true, + "CASE": true, + "CASEIH": true, + "CASH": true, + "CASINO": true, + "CAT": true, + "CATERING": true, + "CATHOLIC": true, + "CBA": true, + "CBN": true, + "CBRE": true, + "CBS": true, + "CC": true, + "CD": true, + "CEB": true, + "CENTER": true, + "CEO": true, + "CERN": true, + "CF": true, + "CFA": true, + "CFD": true, + "CG": true, + "CH": true, + "CHANEL": true, + "CHANNEL": true, + "CHARITY": true, + "CHASE": true, + "CHAT": true, + "CHEAP": true, + "CHINTAI": true, + "CHRISTMAS": true, + "CHROME": true, + "CHRYSLER": true, + "CHURCH": true, + "CI": true, + "CIPRIANI": true, + "CIRCLE": true, + "CISCO": true, + "CITADEL": true, + "CITI": true, + "CITIC": true, + "CITY": true, + "CITYEATS": true, + "CK": true, + "CL": true, + "CLAIMS": true, + "CLEANING": true, + "CLICK": true, + "CLINIC": true, + "CLINIQUE": true, + "CLOTHING": true, + "CLOUD": true, + "CLUB": true, + "CLUBMED": true, + "CM": true, + "CN": true, + "CO": true, + "COACH": true, + "CODES": true, + "COFFEE": true, + "COLLEGE": true, + "COLOGNE": true, + "COM": true, + "COMCAST": true, + "COMMBANK": true, + "COMMUNITY": true, + "COMPANY": true, + "COMPARE": true, + "COMPUTER": true, + "COMSEC": true, + "CONDOS": true, + "CONSTRUCTION": true, + "CONSULTING": true, + "CONTACT": true, + "CONTRACTORS": true, + "COOKING": true, + "COOKINGCHANNEL": true, + "COOL": true, + "COOP": true, + "CORSICA": true, + "COUNTRY": true, + "COUPON": true, + "COUPONS": true, + "COURSES": true, + "CR": true, + "CREDIT": true, + "CREDITCARD": true, + "CREDITUNION": true, + "CRICKET": true, + "CROWN": true, + "CRS": true, + "CRUISE": true, + "CRUISES": true, + "CSC": true, + "CU": true, + "CUISINELLA": true, + "CV": true, + "CW": true, + "CX": true, + "CY": true, + "CYMRU": true, + "CYOU": true, + "CZ": true, + "DABUR": true, + "DAD": true, + "DANCE": true, + "DATA": true, + "DATE": true, + "DATING": true, + "DATSUN": true, + "DAY": true, + "DCLK": true, + "DDS": true, + "DE": true, + "DEAL": true, + "DEALER": true, + "DEALS": true, + "DEGREE": true, + "DELIVERY": true, + "DELL": true, + "DELOITTE": true, + "DELTA": true, + "DEMOCRAT": true, + "DENTAL": true, + "DENTIST": true, + "DESI": true, + "DESIGN": true, + "DEV": true, + "DHL": true, + "DIAMONDS": true, + "DIET": true, + "DIGITAL": true, + "DIRECT": true, + "DIRECTORY": true, + "DISCOUNT": true, + "DISCOVER": true, + "DISH": true, + "DIY": true, + "DJ": true, + "DK": true, + "DM": true, + "DNP": true, + "DO": true, + "DOCS": true, + "DOCTOR": true, + "DODGE": true, + "DOG": true, + "DOHA": true, + "DOMAINS": true, + "DOT": true, + "DOWNLOAD": true, + "DRIVE": true, + "DTV": true, + "DUBAI": true, + "DUCK": true, + "DUNLOP": true, + "DUNS": true, + "DUPONT": true, + "DURBAN": true, + "DVAG": true, + "DVR": true, + "DZ": true, + "EARTH": true, + "EAT": true, + "EC": true, + "ECO": true, + "EDEKA": true, + "EDU": true, + "EDUCATION": true, + "EE": true, + "EG": true, + "EMAIL": true, + "EMERCK": true, + "ENERGY": true, + "ENGINEER": true, + "ENGINEERING": true, + "ENTERPRISES": true, + "EPSON": true, + "EQUIPMENT": true, + "ER": true, + "ERICSSON": true, + "ERNI": true, + "ES": true, + "ESQ": true, + "ESTATE": true, + "ESURANCE": true, + "ET": true, + "ETISALAT": true, + "EU": true, + "EUROVISION": true, + "EUS": true, + "EVENTS": true, + "EVERBANK": true, + "EXCHANGE": true, + "EXPERT": true, + "EXPOSED": true, + "EXPRESS": true, + "EXTRASPACE": true, + "FAGE": true, + "FAIL": true, + "FAIRWINDS": true, + "FAITH": true, + "FAMILY": true, + "FAN": true, + "FANS": true, + "FARM": true, + "FARMERS": true, + "FASHION": true, + "FAST": true, + "FEDEX": true, + "FEEDBACK": true, + "FERRARI": true, + "FERRERO": true, + "FI": true, + "FIAT": true, + "FIDELITY": true, + "FIDO": true, + "FILM": true, + "FINAL": true, + "FINANCE": true, + "FINANCIAL": true, + "FIRE": true, + "FIRESTONE": true, + "FIRMDALE": true, + "FISH": true, + "FISHING": true, + "FIT": true, + "FITNESS": true, + "FJ": true, + "FK": true, + "FLICKR": true, + "FLIGHTS": true, + "FLIR": true, + "FLORIST": true, + "FLOWERS": true, + "FLY": true, + "FM": true, + "FO": true, + "FOO": true, + "FOOD": true, + "FOODNETWORK": true, + "FOOTBALL": true, + "FORD": true, + "FOREX": true, + "FORSALE": true, + "FORUM": true, + "FOUNDATION": true, + "FOX": true, + "FR": true, + "FREE": true, + "FRESENIUS": true, + "FRL": true, + "FROGANS": true, + "FRONTDOOR": true, + "FRONTIER": true, + "FTR": true, + "FUJITSU": true, + "FUJIXEROX": true, + "FUN": true, + "FUND": true, + "FURNITURE": true, + "FUTBOL": true, + "FYI": true, + "GA": true, + "GAL": true, + "GALLERY": true, + "GALLO": true, + "GALLUP": true, + "GAME": true, + "GAMES": true, + "GAP": true, + "GARDEN": true, + "GB": true, + "GBIZ": true, + "GD": true, + "GDN": true, + "GE": true, + "GEA": true, + "GENT": true, + "GENTING": true, + "GEORGE": true, + "GF": true, + "GG": true, + "GGEE": true, + "GH": true, + "GI": true, + "GIFT": true, + "GIFTS": true, + "GIVES": true, + "GIVING": true, + "GL": true, + "GLADE": true, + "GLASS": true, + "GLE": true, + "GLOBAL": true, + "GLOBO": true, + "GM": true, + "GMAIL": true, + "GMBH": true, + "GMO": true, + "GMX": true, + "GN": true, + "GODADDY": true, + "GOLD": true, + "GOLDPOINT": true, + "GOLF": true, + "GOO": true, + "GOODYEAR": true, + "GOOG": true, + "GOOGLE": true, + "GOP": true, + "GOT": true, + "GOV": true, + "GP": true, + "GQ": true, + "GR": true, + "GRAINGER": true, + "GRAPHICS": true, + "GRATIS": true, + "GREEN": true, + "GRIPE": true, + "GROCERY": true, + "GROUP": true, + "GS": true, + "GT": true, + "GU": true, + "GUARDIAN": true, + "GUCCI": true, + "GUGE": true, + "GUIDE": true, + "GUITARS": true, + "GURU": true, + "GW": true, + "GY": true, + "HAIR": true, + "HAMBURG": true, + "HANGOUT": true, + "HAUS": true, + "HBO": true, + "HDFC": true, + "HDFCBANK": true, + "HEALTH": true, + "HEALTHCARE": true, + "HELP": true, + "HELSINKI": true, + "HERE": true, + "HERMES": true, + "HGTV": true, + "HIPHOP": true, + "HISAMITSU": true, + "HITACHI": true, + "HIV": true, + "HK": true, + "HKT": true, + "HM": true, + "HN": true, + "HOCKEY": true, + "HOLDINGS": true, + "HOLIDAY": true, + "HOMEDEPOT": true, + "HOMEGOODS": true, + "HOMES": true, + "HOMESENSE": true, + "HONDA": true, + "HONEYWELL": true, + "HORSE": true, + "HOSPITAL": true, + "HOST": true, + "HOSTING": true, + "HOT": true, + "HOTELES": true, + "HOTELS": true, + "HOTMAIL": true, + "HOUSE": true, + "HOW": true, + "HR": true, + "HSBC": true, + "HT": true, + "HU": true, + "HUGHES": true, + "HYATT": true, + "HYUNDAI": true, + "IBM": true, + "ICBC": true, + "ICE": true, + "ICU": true, + "ID": true, + "IE": true, + "IEEE": true, + "IFM": true, + "IKANO": true, + "IL": true, + "IM": true, + "IMAMAT": true, + "IMDB": true, + "IMMO": true, + "IMMOBILIEN": true, + "IN": true, + "INC": true, + "INDUSTRIES": true, + "INFINITI": true, + "INFO": true, + "ING": true, + "INK": true, + "INSTITUTE": true, + "INSURANCE": true, + "INSURE": true, + "INT": true, + "INTEL": true, + "INTERNATIONAL": true, + "INTUIT": true, + "INVESTMENTS": true, + "IO": true, + "IPIRANGA": true, + "IQ": true, + "IR": true, + "IRISH": true, + "IS": true, + "ISELECT": true, + "ISMAILI": true, + "IST": true, + "ISTANBUL": true, + "IT": true, + "ITAU": true, + "ITV": true, + "IVECO": true, + "JAGUAR": true, + "JAVA": true, + "JCB": true, + "JCP": true, + "JE": true, + "JEEP": true, + "JETZT": true, + "JEWELRY": true, + "JIO": true, + "JLL": true, + "JM": true, + "JMP": true, + "JNJ": true, + "JO": true, + "JOBS": true, + "JOBURG": true, + "JOT": true, + "JOY": true, + "JP": true, + "JPMORGAN": true, + "JPRS": true, + "JUEGOS": true, + "JUNIPER": true, + "KAUFEN": true, + "KDDI": true, + "KE": true, + "KERRYHOTELS": true, + "KERRYLOGISTICS": true, + "KERRYPROPERTIES": true, + "KFH": true, + "KG": true, + "KH": true, + "KI": true, + "KIA": true, + "KIM": true, + "KINDER": true, + "KINDLE": true, + "KITCHEN": true, + "KIWI": true, + "KM": true, + "KN": true, + "KOELN": true, + "KOMATSU": true, + "KOSHER": true, + "KP": true, + "KPMG": true, + "KPN": true, + "KR": true, + "KRD": true, + "KRED": true, + "KUOKGROUP": true, + "KW": true, + "KY": true, + "KYOTO": true, + "KZ": true, + "LA": true, + "LACAIXA": true, + "LADBROKES": true, + "LAMBORGHINI": true, + "LAMER": true, + "LANCASTER": true, + "LANCIA": true, + "LANCOME": true, + "LAND": true, + "LANDROVER": true, + "LANXESS": true, + "LASALLE": true, + "LAT": true, + "LATINO": true, + "LATROBE": true, + "LAW": true, + "LAWYER": true, + "LB": true, + "LC": true, + "LDS": true, + "LEASE": true, + "LECLERC": true, + "LEFRAK": true, + "LEGAL": true, + "LEGO": true, + "LEXUS": true, + "LGBT": true, + "LI": true, + "LIAISON": true, + "LIDL": true, + "LIFE": true, + "LIFEINSURANCE": true, + "LIFESTYLE": true, + "LIGHTING": true, + "LIKE": true, + "LILLY": true, + "LIMITED": true, + "LIMO": true, + "LINCOLN": true, + "LINDE": true, + "LINK": true, + "LIPSY": true, + "LIVE": true, + "LIVING": true, + "LIXIL": true, + "LK": true, + "LLC": true, + "LOAN": true, + "LOANS": true, + "LOCKER": true, + "LOCUS": true, + "LOFT": true, + "LOL": true, + "LONDON": true, + "LOTTE": true, + "LOTTO": true, + "LOVE": true, + "LPL": true, + "LPLFINANCIAL": true, + "LR": true, + "LS": true, + "LT": true, + "LTD": true, + "LTDA": true, + "LU": true, + "LUNDBECK": true, + "LUPIN": true, + "LUXE": true, + "LUXURY": true, + "LV": true, + "LY": true, + "MA": true, + "MACYS": true, + "MADRID": true, + "MAIF": true, + "MAISON": true, + "MAKEUP": true, + "MAN": true, + "MANAGEMENT": true, + "MANGO": true, + "MAP": true, + "MARKET": true, + "MARKETING": true, + "MARKETS": true, + "MARRIOTT": true, + "MARSHALLS": true, + "MASERATI": true, + "MATTEL": true, + "MBA": true, + "MC": true, + "MCKINSEY": true, + "MD": true, + "ME": true, + "MED": true, + "MEDIA": true, + "MEET": true, + "MELBOURNE": true, + "MEME": true, + "MEMORIAL": true, + "MEN": true, + "MENU": true, + "MERCKMSD": true, + "METLIFE": true, + "MG": true, + "MH": true, + "MIAMI": true, + "MICROSOFT": true, + "MIL": true, + "MINI": true, + "MINT": true, + "MIT": true, + "MITSUBISHI": true, + "MK": true, + "ML": true, + "MLB": true, + "MLS": true, + "MM": true, + "MMA": true, + "MN": true, + "MO": true, + "MOBI": true, + "MOBILE": true, + "MOBILY": true, + "MODA": true, + "MOE": true, + "MOI": true, + "MOM": true, + "MONASH": true, + "MONEY": true, + "MONSTER": true, + "MOPAR": true, + "MORMON": true, + "MORTGAGE": true, + "MOSCOW": true, + "MOTO": true, + "MOTORCYCLES": true, + "MOV": true, + "MOVIE": true, + "MOVISTAR": true, + "MP": true, + "MQ": true, + "MR": true, + "MS": true, + "MSD": true, + "MT": true, + "MTN": true, + "MTR": true, + "MU": true, + "MUSEUM": true, + "MUTUAL": true, + "MV": true, + "MW": true, + "MX": true, + "MY": true, + "MZ": true, + "NA": true, + "NAB": true, + "NADEX": true, + "NAGOYA": true, + "NAME": true, + "NATIONWIDE": true, + "NATURA": true, + "NAVY": true, + "NBA": true, + "NC": true, + "NE": true, + "NEC": true, + "NET": true, + "NETBANK": true, + "NETFLIX": true, + "NETWORK": true, + "NEUSTAR": true, + "NEW": true, + "NEWHOLLAND": true, + "NEWS": true, + "NEXT": true, + "NEXTDIRECT": true, + "NEXUS": true, + "NF": true, + "NFL": true, + "NG": true, + "NGO": true, + "NHK": true, + "NI": true, + "NICO": true, + "NIKE": true, + "NIKON": true, + "NINJA": true, + "NISSAN": true, + "NISSAY": true, + "NL": true, + "NO": true, + "NOKIA": true, + "NORTHWESTERNMUTUAL": true, + "NORTON": true, + "NOW": true, + "NOWRUZ": true, + "NOWTV": true, + "NP": true, + "NR": true, + "NRA": true, + "NRW": true, + "NTT": true, + "NU": true, + "NYC": true, + "NZ": true, + "OBI": true, + "OBSERVER": true, + "OFF": true, + "OFFICE": true, + "OKINAWA": true, + "OLAYAN": true, + "OLAYANGROUP": true, + "OLDNAVY": true, + "OLLO": true, + "OM": true, + "OMEGA": true, + "ONE": true, + "ONG": true, + "ONL": true, + "ONLINE": true, + "ONYOURSIDE": true, + "OOO": true, + "OPEN": true, + "ORACLE": true, + "ORANGE": true, + "ORG": true, + "ORGANIC": true, + "ORIGINS": true, + "OSAKA": true, + "OTSUKA": true, + "OTT": true, + "OVH": true, + "PA": true, + "PAGE": true, + "PANASONIC": true, + "PARIS": true, + "PARS": true, + "PARTNERS": true, + "PARTS": true, + "PARTY": true, + "PASSAGENS": true, + "PAY": true, + "PCCW": true, + "PE": true, + "PET": true, + "PF": true, + "PFIZER": true, + "PG": true, + "PH": true, + "PHARMACY": true, + "PHD": true, + "PHILIPS": true, + "PHONE": true, + "PHOTO": true, + "PHOTOGRAPHY": true, + "PHOTOS": true, + "PHYSIO": true, + "PIAGET": true, + "PICS": true, + "PICTET": true, + "PICTURES": true, + "PID": true, + "PIN": true, + "PING": true, + "PINK": true, + "PIONEER": true, + "PIZZA": true, + "PK": true, + "PL": true, + "PLACE": true, + "PLAY": true, + "PLAYSTATION": true, + "PLUMBING": true, + "PLUS": true, + "PM": true, + "PN": true, + "PNC": true, + "POHL": true, + "POKER": true, + "POLITIE": true, + "PORN": true, + "POST": true, + "PR": true, + "PRAMERICA": true, + "PRAXI": true, + "PRESS": true, + "PRIME": true, + "PRO": true, + "PROD": true, + "PRODUCTIONS": true, + "PROF": true, + "PROGRESSIVE": true, + "PROMO": true, + "PROPERTIES": true, + "PROPERTY": true, + "PROTECTION": true, + "PRU": true, + "PRUDENTIAL": true, + "PS": true, + "PT": true, + "PUB": true, + "PW": true, + "PWC": true, + "PY": true, + "QA": true, + "QPON": true, + "QUEBEC": true, + "QUEST": true, + "QVC": true, + "RACING": true, + "RADIO": true, + "RAID": true, + "RE": true, + "READ": true, + "REALESTATE": true, + "REALTOR": true, + "REALTY": true, + "RECIPES": true, + "RED": true, + "REDSTONE": true, + "REDUMBRELLA": true, + "REHAB": true, + "REISE": true, + "REISEN": true, + "REIT": true, + "RELIANCE": true, + "REN": true, + "RENT": true, + "RENTALS": true, + "REPAIR": true, + "REPORT": true, + "REPUBLICAN": true, + "REST": true, + "RESTAURANT": true, + "REVIEW": true, + "REVIEWS": true, + "REXROTH": true, + "RICH": true, + "RICHARDLI": true, + "RICOH": true, + "RIGHTATHOME": true, + "RIL": true, + "RIO": true, + "RIP": true, + "RMIT": true, + "RO": true, + "ROCHER": true, + "ROCKS": true, + "RODEO": true, + "ROGERS": true, + "ROOM": true, + "RS": true, + "RSVP": true, + "RU": true, + "RUGBY": true, + "RUHR": true, + "RUN": true, + "RW": true, + "RWE": true, + "RYUKYU": true, + "SA": true, + "SAARLAND": true, + "SAFE": true, + "SAFETY": true, + "SAKURA": true, + "SALE": true, + "SALON": true, + "SAMSCLUB": true, + "SAMSUNG": true, + "SANDVIK": true, + "SANDVIKCOROMANT": true, + "SANOFI": true, + "SAP": true, + "SARL": true, + "SAS": true, + "SAVE": true, + "SAXO": true, + "SB": true, + "SBI": true, + "SBS": true, + "SC": true, + "SCA": true, + "SCB": true, + "SCHAEFFLER": true, + "SCHMIDT": true, + "SCHOLARSHIPS": true, + "SCHOOL": true, + "SCHULE": true, + "SCHWARZ": true, + "SCIENCE": true, + "SCJOHNSON": true, + "SCOR": true, + "SCOT": true, + "SD": true, + "SE": true, + "SEARCH": true, + "SEAT": true, + "SECURE": true, + "SECURITY": true, + "SEEK": true, + "SELECT": true, + "SENER": true, + "SERVICES": true, + "SES": true, + "SEVEN": true, + "SEW": true, + "SEX": true, + "SEXY": true, + "SFR": true, + "SG": true, + "SH": true, + "SHANGRILA": true, + "SHARP": true, + "SHAW": true, + "SHELL": true, + "SHIA": true, + "SHIKSHA": true, + "SHOES": true, + "SHOP": true, + "SHOPPING": true, + "SHOUJI": true, + "SHOW": true, + "SHOWTIME": true, + "SHRIRAM": true, + "SI": true, + "SILK": true, + "SINA": true, + "SINGLES": true, + "SITE": true, + "SJ": true, + "SK": true, + "SKI": true, + "SKIN": true, + "SKY": true, + "SKYPE": true, + "SL": true, + "SLING": true, + "SM": true, + "SMART": true, + "SMILE": true, + "SN": true, + "SNCF": true, + "SO": true, + "SOCCER": true, + "SOCIAL": true, + "SOFTBANK": true, + "SOFTWARE": true, + "SOHU": true, + "SOLAR": true, + "SOLUTIONS": true, + "SONG": true, + "SONY": true, + "SOY": true, + "SPACE": true, + "SPORT": true, + "SPOT": true, + "SPREADBETTING": true, + "SR": true, + "SRL": true, + "SRT": true, + "SS": true, + "ST": true, + "STADA": true, + "STAPLES": true, + "STAR": true, + "STARHUB": true, + "STATEBANK": true, + "STATEFARM": true, + "STC": true, + "STCGROUP": true, + "STOCKHOLM": true, + "STORAGE": true, + "STORE": true, + "STREAM": true, + "STUDIO": true, + "STUDY": true, + "STYLE": true, + "SU": true, + "SUCKS": true, + "SUPPLIES": true, + "SUPPLY": true, + "SUPPORT": true, + "SURF": true, + "SURGERY": true, + "SUZUKI": true, + "SV": true, + "SWATCH": true, + "SWIFTCOVER": true, + "SWISS": true, + "SX": true, + "SY": true, + "SYDNEY": true, + "SYMANTEC": true, + "SYSTEMS": true, + "SZ": true, + "TAB": true, + "TAIPEI": true, + "TALK": true, + "TAOBAO": true, + "TARGET": true, + "TATAMOTORS": true, + "TATAR": true, + "TATTOO": true, + "TAX": true, + "TAXI": true, + "TC": true, + "TCI": true, + "TD": true, + "TDK": true, + "TEAM": true, + "TECH": true, + "TECHNOLOGY": true, + "TEL": true, + "TELEFONICA": true, + "TEMASEK": true, + "TENNIS": true, + "TEVA": true, + "TF": true, + "TG": true, + "TH": true, + "THD": true, + "THEATER": true, + "THEATRE": true, + "TIAA": true, + "TICKETS": true, + "TIENDA": true, + "TIFFANY": true, + "TIPS": true, + "TIRES": true, + "TIROL": true, + "TJ": true, + "TJMAXX": true, + "TJX": true, + "TK": true, + "TKMAXX": true, + "TL": true, + "TM": true, + "TMALL": true, + "TN": true, + "TO": true, + "TODAY": true, + "TOKYO": true, + "TOOLS": true, + "TOP": true, + "TORAY": true, + "TOSHIBA": true, + "TOTAL": true, + "TOURS": true, + "TOWN": true, + "TOYOTA": true, + "TOYS": true, + "TR": true, + "TRADE": true, + "TRADING": true, + "TRAINING": true, + "TRAVEL": true, + "TRAVELCHANNEL": true, + "TRAVELERS": true, + "TRAVELERSINSURANCE": true, + "TRUST": true, + "TRV": true, + "TT": true, + "TUBE": true, + "TUI": true, + "TUNES": true, + "TUSHU": true, + "TV": true, + "TVS": true, + "TW": true, + "TZ": true, + "UA": true, + "UBANK": true, + "UBS": true, + "UCONNECT": true, + "UG": true, + "UK": true, + "UNICOM": true, + "UNIVERSITY": true, + "UNO": true, + "UOL": true, + "UPS": true, + "US": true, + "UY": true, + "UZ": true, + "VA": true, + "VACATIONS": true, + "VANA": true, + "VANGUARD": true, + "VC": true, + "VE": true, + "VEGAS": true, + "VENTURES": true, + "VERISIGN": true, + "VERSICHERUNG": true, + "VET": true, + "VG": true, + "VI": true, + "VIAJES": true, + "VIDEO": true, + "VIG": true, + "VIKING": true, + "VILLAS": true, + "VIN": true, + "VIP": true, + "VIRGIN": true, + "VISA": true, + "VISION": true, + "VISTAPRINT": true, + "VIVA": true, + "VIVO": true, + "VLAANDEREN": true, + "VN": true, + "VODKA": true, + "VOLKSWAGEN": true, + "VOLVO": true, + "VOTE": true, + "VOTING": true, + "VOTO": true, + "VOYAGE": true, + "VU": true, + "VUELOS": true, + "WALES": true, + "WALMART": true, + "WALTER": true, + "WANG": true, + "WANGGOU": true, + "WARMAN": true, + "WATCH": true, + "WATCHES": true, + "WEATHER": true, + "WEATHERCHANNEL": true, + "WEBCAM": true, + "WEBER": true, + "WEBSITE": true, + "WED": true, + "WEDDING": true, + "WEIBO": true, + "WEIR": true, + "WF": true, + "WHOSWHO": true, + "WIEN": true, + "WIKI": true, + "WILLIAMHILL": true, + "WIN": true, + "WINDOWS": true, + "WINE": true, + "WINNERS": true, + "WME": true, + "WOLTERSKLUWER": true, + "WOODSIDE": true, + "WORK": true, + "WORKS": true, + "WORLD": true, + "WOW": true, + "WS": true, + "WTC": true, + "WTF": true, + "XBOX": true, + "XEROX": true, + "XFINITY": true, + "XIHUAN": true, + "XIN": true, + "XN--11B4C3D": true, + "XN--1CK2E1B": true, + "XN--1QQW23A": true, + "XN--2SCRJ9C": true, + "XN--30RR7Y": true, + "XN--3BST00M": true, + "XN--3DS443G": true, + "XN--3E0B707E": true, + "XN--3HCRJ9C": true, + "XN--3OQ18VL8PN36A": true, + "XN--3PXU8K": true, + "XN--42C2D9A": true, + "XN--45BR5CYL": true, + "XN--45BRJ9C": true, + "XN--45Q11C": true, + "XN--4GBRIM": true, + "XN--54B7FTA0CC": true, + "XN--55QW42G": true, + "XN--55QX5D": true, + "XN--5SU34J936BGSG": true, + "XN--5TZM5G": true, + "XN--6FRZ82G": true, + "XN--6QQ986B3XL": true, + "XN--80ADXHKS": true, + "XN--80AO21A": true, + "XN--80AQECDR1A": true, + "XN--80ASEHDB": true, + "XN--80ASWG": true, + "XN--8Y0A063A": true, + "XN--90A3AC": true, + "XN--90AE": true, + "XN--90AIS": true, + "XN--9DBQ2A": true, + "XN--9ET52U": true, + "XN--9KRT00A": true, + "XN--B4W605FERD": true, + "XN--BCK1B9A5DRE4C": true, + "XN--C1AVG": true, + "XN--C2BR7G": true, + "XN--CCK2B3B": true, + "XN--CG4BKI": true, + "XN--CLCHC0EA0B2G2A9GCD": true, + "XN--CZR694B": true, + "XN--CZRS0T": true, + "XN--CZRU2D": true, + "XN--D1ACJ3B": true, + "XN--D1ALF": true, + "XN--E1A4C": true, + "XN--ECKVDTC9D": true, + "XN--EFVY88H": true, + "XN--ESTV75G": true, + "XN--FCT429K": true, + "XN--FHBEI": true, + "XN--FIQ228C5HS": true, + "XN--FIQ64B": true, + "XN--FIQS8S": true, + "XN--FIQZ9S": true, + "XN--FJQ720A": true, + "XN--FLW351E": true, + "XN--FPCRJ9C3D": true, + "XN--FZC2C9E2C": true, + "XN--FZYS8D69UVGM": true, + "XN--G2XX48C": true, + "XN--GCKR3F0F": true, + "XN--GECRJ9C": true, + "XN--GK3AT1E": true, + "XN--H2BREG3EVE": true, + "XN--H2BRJ9C": true, + "XN--H2BRJ9C8C": true, + "XN--HXT814E": true, + "XN--I1B6B1A6A2E": true, + "XN--IMR513N": true, + "XN--IO0A7I": true, + "XN--J1AEF": true, + "XN--J1AMH": true, + "XN--J6W193G": true, + "XN--JLQ61U9W7B": true, + "XN--JVR189M": true, + "XN--KCRX77D1X4A": true, + "XN--KPRW13D": true, + "XN--KPRY57D": true, + "XN--KPU716F": true, + "XN--KPUT3I": true, + "XN--L1ACC": true, + "XN--LGBBAT1AD8J": true, + "XN--MGB9AWBF": true, + "XN--MGBA3A3EJT": true, + "XN--MGBA3A4F16A": true, + "XN--MGBA7C0BBN0A": true, + "XN--MGBAAKC7DVF": true, + "XN--MGBAAM7A8H": true, + "XN--MGBAB2BD": true, + "XN--MGBAH1A3HJKRD": true, + "XN--MGBAI9AZGQP6J": true, + "XN--MGBAYH7GPA": true, + "XN--MGBB9FBPOB": true, + "XN--MGBBH1A": true, + "XN--MGBBH1A71E": true, + "XN--MGBC0A9AZCG": true, + "XN--MGBCA7DZDO": true, + "XN--MGBERP4A5D4AR": true, + "XN--MGBGU82A": true, + "XN--MGBI4ECEXP": true, + "XN--MGBPL2FH": true, + "XN--MGBT3DHD": true, + "XN--MGBTX2B": true, + "XN--MGBX4CD0AB": true, + "XN--MIX891F": true, + "XN--MK1BU44C": true, + "XN--MXTQ1M": true, + "XN--NGBC5AZD": true, + "XN--NGBE9E0A": true, + "XN--NGBRX": true, + "XN--NODE": true, + "XN--NQV7F": true, + "XN--NQV7FS00EMA": true, + "XN--NYQY26A": true, + "XN--O3CW4H": true, + "XN--OGBPF8FL": true, + "XN--OTU796D": true, + "XN--P1ACF": true, + "XN--P1AI": true, + "XN--PBT977C": true, + "XN--PGBS0DH": true, + "XN--PSSY2U": true, + "XN--Q9JYB4C": true, + "XN--QCKA1PMC": true, + "XN--QXAM": true, + "XN--RHQV96G": true, + "XN--ROVU88B": true, + "XN--RVC1E0AM3E": true, + "XN--S9BRJ9C": true, + "XN--SES554G": true, + "XN--T60B56A": true, + "XN--TCKWE": true, + "XN--TIQ49XQYJ": true, + "XN--UNUP4Y": true, + "XN--VERMGENSBERATER-CTB": true, + "XN--VERMGENSBERATUNG-PWB": true, + "XN--VHQUV": true, + "XN--VUQ861B": true, + "XN--W4R85EL8FHU5DNRA": true, + "XN--W4RS40L": true, + "XN--WGBH1C": true, + "XN--WGBL6A": true, + "XN--XHQ521B": true, + "XN--XKC2AL3HYE2A": true, + "XN--XKC2DL3A5EE0H": true, + "XN--Y9A3AQ": true, + "XN--YFRO4I67O": true, + "XN--YGBI2AMMX": true, + "XN--ZFR164B": true, + "XXX": true, + "XYZ": true, + "YACHTS": true, + "YAHOO": true, + "YAMAXUN": true, + "YANDEX": true, + "YE": true, + "YODOBASHI": true, + "YOGA": true, + "YOKOHAMA": true, + "YOU": true, + "YOUTUBE": true, + "YT": true, + "YUN": true, + "ZA": true, + "ZAPPOS": true, + "ZARA": true, + "ZERO": true, + "ZIP": true, + "ZM": true, + "ZONE": true, + "ZUERICH": true, + "ZW": true, +} diff --git a/vendor/github.com/jbenet/go-temp-err-catcher/.travis.yml b/vendor/github.com/jbenet/go-temp-err-catcher/.travis.yml new file mode 100644 index 00000000..7b571f40 --- /dev/null +++ b/vendor/github.com/jbenet/go-temp-err-catcher/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.3 + - release + - tip + +script: + - go test -race -cpu=5 -v ./... diff --git a/vendor/github.com/jbenet/go-temp-err-catcher/LICENSE b/vendor/github.com/jbenet/go-temp-err-catcher/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/jbenet/go-temp-err-catcher/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/jbenet/go-temp-err-catcher/README.md b/vendor/github.com/jbenet/go-temp-err-catcher/README.md new file mode 100644 index 00000000..acd4cf53 --- /dev/null +++ b/vendor/github.com/jbenet/go-temp-err-catcher/README.md @@ -0,0 +1,78 @@ +# go-temp-err-catcher + +This is a little package to use with your net.Listeners. + +Docs: https://godoc.org/github.com/jbenet/go-temp-err-catcher + +Get: + + go get github.com/jbenet/go-temp-err-catcher + +## Examples + +It is meant to be used with things like net.Lister.Accept: + +```go +import ( + tec "github.com/jbenet/go-temp-err-catcher" +) + +func listen(listener net.Listener) { + var c tec.TempErrCatcher + + for { + conn, err := listener.Accept() + if err != nil && c.IsTemporary(c) { + continue + } + return conn, err + } +} +``` + +You can make your errors implement `Temporary`: + +```go +type errTemp struct { + e error +} + +func (e errTemp) Temporary() bool { + return true +} + +func (e errTemp) Error() string { + return e.e.Error() +} + +err := errors.New("beep boop") +var c tec.TempErrCatcher +c.IsTemporary(err) // false +c.IsTemporary(errTemp{err}) // true +``` + +Or just use `ErrTemp`: + +```go +err := errors.New("beep boop") +var c tec.TempErrCatcher +c.IsTemporary(err) // false +c.IsTemporary(tec.ErrTemp{err}) // true +``` + + +You can also define an `IsTemp` function to classify errors: + +```go +var ErrSkip = errors.New("this should be skipped") +var ErrNotSkip = errors.New("this should not be skipped") + +var c tec.TempErrCatcher +c.IsTemp = func(e error) bool { + return e == ErrSkip +} + +c.IsTemporary(ErrSkip) // true +c.IsTemporary(ErrNotSkip) // false +c.IsTemporary(ErrTemp) // false! no longer accepts Temporary() +``` diff --git a/vendor/github.com/jbenet/go-temp-err-catcher/doc.go b/vendor/github.com/jbenet/go-temp-err-catcher/doc.go new file mode 100644 index 00000000..766c8b6f --- /dev/null +++ b/vendor/github.com/jbenet/go-temp-err-catcher/doc.go @@ -0,0 +1,62 @@ +// Package temperrcatcher provides a TempErrCatcher object, +// which implements simple error-retrying functionality. +// It is meant to be used with things like net.Lister.Accept: +// +// import ( +// tec "github.com/jbenet/go-temp-err-catcher" +// ) +// +// func listen(listener net.Listener) { +// var c tec.TempErrCatcher +// +// for { +// conn, err := listener.Accept() +// if err != nil && c.IsTemporary(c) { +// continue +// } +// return conn, err +// } +// } +// +// You can make your errors implement `Temporary`: +// +// type errTemp struct { +// e error +// } +// +// func (e errTemp) Temporary() bool { +// return true +// } +// +// func (e errTemp) Error() string { +// return e.e.Error() +// } +// +// err := errors.New("beep boop") +// var c tec.TempErrCatcher +// c.IsTemporary(err) // false +// c.IsTemporary(errTemp{err}) // true +// +// Or just use `ErrTemp`: +// +// err := errors.New("beep boop") +// var c tec.TempErrCatcher +// c.IsTemporary(err) // false +// c.IsTemporary(tec.ErrTemp{err}) // true +// +// +// You can also define an `IsTemp` function to classify errors: +// +// var ErrSkip = errors.New("this should be skipped") +// var ErrNotSkip = errors.New("this should not be skipped") +// +// var c tec.TempErrCatcher +// c.IsTemp = func(e error) bool { +// return e == ErrSkip +// } +// +// c.IsTemporary(ErrSkip) // true +// c.IsTemporary(ErrNotSkip) // false +// c.IsTemporary(ErrTemp) // false! no longer accepts Temporary() +// +package temperrcatcher diff --git a/vendor/github.com/jbenet/go-temp-err-catcher/temp_err_catcher.go b/vendor/github.com/jbenet/go-temp-err-catcher/temp_err_catcher.go new file mode 100644 index 00000000..fe8e780c --- /dev/null +++ b/vendor/github.com/jbenet/go-temp-err-catcher/temp_err_catcher.go @@ -0,0 +1,124 @@ +// Package temperrcatcher provides a TempErrCatcher object, +// which implements simple error-retrying functionality. +package temperrcatcher + +import ( + "time" +) + +// InitialDelay governs how long to wait the first time. +// This is defaulted to time.Millisecond, which makes sense +// for network listener failures. You may want a much smaller +// delay. You can configure this package wide, or in each +// TempErrCatcher +var InitialDelay = time.Millisecond + +// Temporary is an interface errors can implement to +// ensure they are correctly classified by the default +// TempErrCatcher classifier +type Temporary interface { + Temporary() bool +} + +// ErrIsTemporary returns whether an error is Temporary(), +// iff it implements the Temporary interface. +func ErrIsTemporary(e error) bool { + te, ok := e.(Temporary) + return ok && te.Temporary() +} + +// TempErrCatcher catches temporary errors for you. It then sleeps +// for a bit before returning (you should then try again). This may +// seem odd, but it's exactly what net/http does: +// http://golang.org/src/net/http/server.go?s=51504:51550#L1728 +// +// You can set a few options in TempErrCatcher. They all have defaults +// so a zero TempErrCatcher is ready to be used: +// +// var c tec.TempErrCatcher +// c.IsTemporary(tempErr) +// +type TempErrCatcher struct { + IsTemp func(error) bool // the classifier to use. default: ErrIsTemporary + Wait func(time.Duration) // the wait func to call. default: time.Sleep + Max time.Duration // the maximum time to wait. default: time.Second + Start time.Duration // the delay to start with. default: InitialDelay + delay time.Duration + last time.Time +} + +func (tec *TempErrCatcher) init() { + if tec.Max == 0 { + tec.Max = time.Second + } + if tec.IsTemp == nil { + tec.IsTemp = ErrIsTemporary + } + if tec.Wait == nil { + tec.Wait = time.Sleep + } + if tec.Start == 0 { + tec.Start = InitialDelay + } +} + +// IsTemporary checks whether an error is temporary. It will call +// tec.Wait before returning, with a delay. The delay is also +// doubled, so we do not constantly spin. This is the strategy +// net.Listener uses. +// +// Note: you will want to call Reset() if you get a success, +// so that the stored delay is brough back to 0. +func (tec *TempErrCatcher) IsTemporary(e error) bool { + tec.init() + if tec.IsTemp(e) { + now := time.Now() + if now.Sub(tec.last) > (tec.delay * 5) { + // this is a "new streak" of temp failures. reset. + tec.Reset() + } + + if tec.delay == 0 { // init case. + tec.delay = tec.Start + } else { + tec.delay *= 2 + } + + if tec.delay > tec.Max { + tec.delay = tec.Max + } + tec.Wait(tec.delay) + tec.last = now + return true + } + tec.Reset() // different failure. call reset + return false +} + +// Reset sets the internal delay counter to 0 +func (tec *TempErrCatcher) Reset() { + tec.delay = 0 +} + +// ErrTemporary wraps any error and implements Temporary function. +// +// err := errors.New("beep boop") +// var c tec.TempErrCatcher +// c.IsTemporary(err) // false +// c.IsTemporary(tec.ErrTemp{err}) // true +// +type ErrTemporary struct { + Err error +} + +func (e ErrTemporary) Temporary() bool { + return true +} + +func (e ErrTemporary) Error() string { + return e.Err.Error() +} + +func (e ErrTemporary) String() string { + return e.Error() +} diff --git a/vendor/github.com/jbenet/goprocess/.travis.yml b/vendor/github.com/jbenet/goprocess/.travis.yml new file mode 100644 index 00000000..77d0e7d7 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/.travis.yml @@ -0,0 +1,9 @@ +sudo: false + +language: go + +go: + - 1.12 + +script: + - go test -race -v ./... diff --git a/vendor/github.com/jbenet/goprocess/LICENSE b/vendor/github.com/jbenet/goprocess/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/jbenet/goprocess/README.md b/vendor/github.com/jbenet/goprocess/README.md new file mode 100644 index 00000000..e2f12e16 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/README.md @@ -0,0 +1,132 @@ +# goprocess - lifecycles in go + +[![travisbadge](https://travis-ci.org/jbenet/goprocess.svg)](https://travis-ci.org/jbenet/goprocess) + +(Based on https://github.com/jbenet/go-ctxgroup) + +- Godoc: https://godoc.org/github.com/jbenet/goprocess + +`goprocess` introduces a way to manage process lifecycles in go. It is +much like [go.net/context](https://godoc.org/code.google.com/p/go.net/context) +(it actually uses a Context), but it is more like a Context-WaitGroup hybrid. +`goprocess` is about being able to start and stop units of work, which may +receive `Close` signals from many clients. Think of it like a UNIX process +tree, but inside go. + +`goprocess` seeks to minimally affect your objects, so you can use it +with both embedding or composition. At the heart of `goprocess` is the +`Process` interface: + +```Go +// Process is the basic unit of work in goprocess. It defines a computation +// with a lifecycle: +// - running (before calling Close), +// - closing (after calling Close at least once), +// - closed (after Close returns, and all teardown has _completed_). +// +// More specifically, it fits this: +// +// p := WithTeardown(tf) // new process is created, it is now running. +// p.AddChild(q) // can register children **before** Closing. +// go p.Close() // blocks until done running teardown func. +// <-p.Closing() // would now return true. +// <-p.childrenDone() // wait on all children to be done +// p.teardown() // runs the user's teardown function tf. +// p.Close() // now returns, with error teardown returned. +// <-p.Closed() // would now return true. +// +// Processes can be arranged in a process "tree", where children are +// automatically Closed if their parents are closed. (Note, it is actually +// a Process DAG, children may have multiple parents). A process may also +// optionally wait for another to fully Close before beginning to Close. +// This makes it easy to ensure order of operations and proper sequential +// teardown of resurces. For example: +// +// p1 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 1") +// }) +// p2 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 2") +// }) +// p3 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 3") +// }) +// +// p1.AddChild(p2) +// p2.AddChild(p3) +// +// +// go p1.Close() +// go p2.Close() +// go p3.Close() +// +// // Output: +// // closing 3 +// // closing 2 +// // closing 1 +// +// Process is modelled after the UNIX processes group idea, and heavily +// informed by sync.WaitGroup and go.net/context.Context. +// +// In the function documentation of this interface, `p` always refers to +// the self Process. +type Process interface { + + // WaitFor makes p wait for q before exiting. Thus, p will _always_ close + // _after_ q. Note well: a waiting cycle is deadlock. + // + // If q is already Closed, WaitFor calls p.Close() + // If p is already Closing or Closed, WaitFor panics. This is the same thing + // as calling Add(1) _after_ calling Done() on a wait group. Calling WaitFor + // on an already-closed process is a programming error likely due to bad + // synchronization + WaitFor(q Process) + + // AddChildNoWait registers child as a "child" of Process. As in UNIX, + // when parent is Closed, child is Closed -- child may Close beforehand. + // This is the equivalent of calling: + // + // go func(parent, child Process) { + // <-parent.Closing() + // child.Close() + // }(p, q) + // + // Note: the naming of functions is `AddChildNoWait` and `AddChild` (instead + // of `AddChild` and `AddChildWaitFor`) because: + // - it is the more common operation, + // - explicitness is helpful in the less common case (no waiting), and + // - usual "child" semantics imply parent Processes should wait for children. + AddChildNoWait(q Process) + + // AddChild is the equivalent of calling: + // parent.AddChildNoWait(q) + // parent.WaitFor(q) + AddChild(q Process) + + // Go creates a new process, adds it as a child, and spawns the ProcessFunc f + // in its own goroutine. It is equivalent to: + // + // GoChild(p, f) + // + // It is useful to construct simple asynchronous workers, children of p. + Go(f ProcessFunc) Process + + // Close ends the process. Close blocks until the process has completely + // shut down, and any teardown has run _exactly once_. The returned error + // is available indefinitely: calling Close twice returns the same error. + // If the process has already been closed, Close returns immediately. + Close() error + + // Closing is a signal to wait upon. The returned channel is closed + // _after_ Close has been called at least once, but teardown may or may + // not be done yet. The primary use case of Closing is for children who + // need to know when a parent is shutting down, and therefore also shut + // down. + Closing() <-chan struct{} + + // Closed is a signal to wait upon. The returned channel is closed + // _after_ Close has completed; teardown has finished. The primary use case + // of Closed is waiting for a Process to Close without _causing_ the Close. + Closed() <-chan struct{} +} +``` diff --git a/vendor/github.com/jbenet/goprocess/background.go b/vendor/github.com/jbenet/goprocess/background.go new file mode 100644 index 00000000..d6581570 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/background.go @@ -0,0 +1,33 @@ +package goprocess + +// Background returns the "bgProcess" Process: a statically allocated +// process that can _never_ close. It also never enters Closing() state. +// Calling Background().Close() will hang indefinitely. +func Background() Process { + return background +} + +var background = new(bgProcess) + +type bgProcess struct{} + +func (*bgProcess) WaitFor(q Process) {} +func (*bgProcess) AddChildNoWait(q Process) {} +func (*bgProcess) AddChild(q Process) {} +func (*bgProcess) Close() error { select {} } +func (*bgProcess) CloseAfterChildren() error { select {} } +func (*bgProcess) Closing() <-chan struct{} { return nil } +func (*bgProcess) Closed() <-chan struct{} { return nil } +func (*bgProcess) Err() error { select {} } + +func (*bgProcess) SetTeardown(tf TeardownFunc) { + panic("can't set teardown on bgProcess process") +} +func (*bgProcess) Go(f ProcessFunc) Process { + child := newProcess(nil) + go func() { + f(child) + child.Close() + }() + return child +} diff --git a/vendor/github.com/jbenet/goprocess/context/context.go b/vendor/github.com/jbenet/goprocess/context/context.go new file mode 100644 index 00000000..54d2d13c --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/context/context.go @@ -0,0 +1,117 @@ +package goprocessctx + +import ( + "context" + + goprocess "github.com/jbenet/goprocess" +) + +// WithContext constructs and returns a Process that respects +// given context. It is the equivalent of: +// +// func ProcessWithContext(ctx context.Context) goprocess.Process { +// p := goprocess.WithParent(goprocess.Background()) +// CloseAfterContext(p, ctx) +// return p +// } +// +func WithContext(ctx context.Context) goprocess.Process { + p := goprocess.WithParent(goprocess.Background()) + CloseAfterContext(p, ctx) + return p +} + +// WithContextAndTeardown is a helper function to set teardown at initiation +// of WithContext +func WithContextAndTeardown(ctx context.Context, tf goprocess.TeardownFunc) goprocess.Process { + p := goprocess.WithTeardown(tf) + CloseAfterContext(p, ctx) + return p +} + +// WaitForContext makes p WaitFor ctx. When Closing, p waits for +// ctx.Done(), before being Closed(). It is simply: +// +// p.WaitFor(goprocess.WithContext(ctx)) +// +func WaitForContext(ctx context.Context, p goprocess.Process) { + p.WaitFor(WithContext(ctx)) +} + +// CloseAfterContext schedules the process to close after the given +// context is done. It is the equivalent of: +// +// func CloseAfterContext(p goprocess.Process, ctx context.Context) { +// go func() { +// <-ctx.Done() +// p.Close() +// }() +// } +// +func CloseAfterContext(p goprocess.Process, ctx context.Context) { + if p == nil { + panic("nil Process") + } + if ctx == nil { + panic("nil Context") + } + + // Avoid a goroutine for both context.Background() and goprocess.Background(). + if ctx.Done() == nil || p.Closed() == nil { + return + } + + go func() { + select { + case <-ctx.Done(): + p.Close() + case <-p.Closed(): + } + }() +} + +// WithProcessClosing returns a context.Context derived from ctx that +// is cancelled as p is Closing (after: <-p.Closing()). It is simply: +// +// func WithProcessClosing(ctx context.Context, p goprocess.Process) context.Context { +// ctx, cancel := context.WithCancel(ctx) +// go func() { +// <-p.Closing() +// cancel() +// }() +// return ctx +// } +// +func WithProcessClosing(ctx context.Context, p goprocess.Process) context.Context { + ctx, cancel := context.WithCancel(ctx) + p.AddChildNoWait(goprocess.WithTeardown(func() error { + cancel() + return nil + })) + return ctx +} + +// WithProcessClosed returns a context.Context that is cancelled +// after Process p is Closed. It is the equivalent of: +// +// func WithProcessClosed(ctx context.Context, p goprocess.Process) context.Context { +// ctx, cancel := context.WithCancel(ctx) +// go func() { +// <-p.Closed() +// cancel() +// }() +// return ctx +// } +// +func WithProcessClosed(ctx context.Context, p goprocess.Process) context.Context { + ctx, cancel := context.WithCancel(ctx) + p.AddChildNoWait(goprocess.WithTeardown(func() error { + select { + case <-p.Closed(): + case <-ctx.Done(): + } + cancel() + return nil + })) + return ctx +} diff --git a/vendor/github.com/jbenet/goprocess/context/derive.go b/vendor/github.com/jbenet/goprocess/context/derive.go new file mode 100644 index 00000000..92e4d272 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/context/derive.go @@ -0,0 +1,19 @@ +package goprocessctx + +import ( + "context" + + goprocess "github.com/jbenet/goprocess" +) + +// OnClosingContext derives a context from a given goprocess that will +// be 'Done' when the process is closing +func OnClosingContext(p goprocess.Process) context.Context { + return WithProcessClosing(context.Background(), p) +} + +// OnClosedContext derives a context from a given goprocess that will +// be 'Done' when the process is closed +func OnClosedContext(p goprocess.Process) context.Context { + return WithProcessClosed(context.Background(), p) +} diff --git a/vendor/github.com/jbenet/goprocess/go.mod b/vendor/github.com/jbenet/goprocess/go.mod new file mode 100644 index 00000000..e22f17f2 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/go.mod @@ -0,0 +1,5 @@ +module github.com/jbenet/goprocess + +go 1.12 + +require github.com/jbenet/go-cienv v0.1.0 diff --git a/vendor/github.com/jbenet/goprocess/go.sum b/vendor/github.com/jbenet/goprocess/go.sum new file mode 100644 index 00000000..82fea79c --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/go.sum @@ -0,0 +1,2 @@ +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= diff --git a/vendor/github.com/jbenet/goprocess/goprocess.go b/vendor/github.com/jbenet/goprocess/goprocess.go new file mode 100644 index 00000000..48b76e2e --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/goprocess.go @@ -0,0 +1,263 @@ +// Package goprocess introduces a Process abstraction that allows simple +// organization, and orchestration of work. It is much like a WaitGroup, +// and much like a context.Context, but also ensures safe **exactly-once**, +// and well-ordered teardown semantics. +package goprocess + +import ( + "os" + "os/signal" +) + +// Process is the basic unit of work in goprocess. It defines a computation +// with a lifecycle: +// - running (before calling Close), +// - closing (after calling Close at least once), +// - closed (after Close returns, and all teardown has _completed_). +// +// More specifically, it fits this: +// +// p := WithTeardown(tf) // new process is created, it is now running. +// p.AddChild(q) // can register children **before** Closed(). +// go p.Close() // blocks until done running teardown func. +// <-p.Closing() // would now return true. +// <-p.childrenDone() // wait on all children to be done +// p.teardown() // runs the user's teardown function tf. +// p.Close() // now returns, with error teardown returned. +// <-p.Closed() // would now return true. +// +// Processes can be arranged in a process "tree", where children are +// automatically Closed if their parents are closed. (Note, it is actually +// a Process DAG, children may have multiple parents). A process may also +// optionally wait for another to fully Close before beginning to Close. +// This makes it easy to ensure order of operations and proper sequential +// teardown of resurces. For example: +// +// p1 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 1") +// }) +// p2 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 2") +// }) +// p3 := goprocess.WithTeardown(func() error { +// fmt.Println("closing 3") +// }) +// +// p1.AddChild(p2) +// p2.AddChild(p3) +// +// +// go p1.Close() +// go p2.Close() +// go p3.Close() +// +// // Output: +// // closing 3 +// // closing 2 +// // closing 1 +// +// Process is modelled after the UNIX processes group idea, and heavily +// informed by sync.WaitGroup and go.net/context.Context. +// +// In the function documentation of this interface, `p` always refers to +// the self Process. +type Process interface { + + // WaitFor makes p wait for q before exiting. Thus, p will _always_ close + // _after_ q. Note well: a waiting cycle is deadlock. + // + // If p is already Closed, WaitFor panics. This is the same thing as + // calling Add(1) _after_ calling Done() on a wait group. Calling + // WaitFor on an already-closed process is a programming error likely + // due to bad synchronization + WaitFor(q Process) + + // AddChildNoWait registers child as a "child" of Process. As in UNIX, + // when parent is Closed, child is Closed -- child may Close beforehand. + // This is the equivalent of calling: + // + // go func(parent, child Process) { + // <-parent.Closing() + // child.Close() + // }(p, q) + // + // Note: the naming of functions is `AddChildNoWait` and `AddChild` (instead + // of `AddChild` and `AddChildWaitFor`) because: + // - it is the more common operation, + // - explicitness is helpful in the less common case (no waiting), and + // - usual "child" semantics imply parent Processes should wait for children. + AddChildNoWait(q Process) + + // AddChild is the equivalent of calling: + // parent.AddChildNoWait(q) + // parent.WaitFor(q) + // + // It will _panic_ if the parent is already closed. + AddChild(q Process) + + // Go is much like `go`, as it runs a function in a newly spawned goroutine. + // The neat part of Process.Go is that the Process object you call it on will: + // * construct a child Process, and call AddChild(child) on it + // * spawn a goroutine, and call the given function + // * Close the child when the function exits. + // This way, you can rest assured each goroutine you spawn has its very own + // Process context, and that it will be closed when the function exits. + // It is the function's responsibility to respect the Closing of its Process, + // namely it should exit (return) when <-Closing() is ready. It is basically: + // + // func (p Process) Go(f ProcessFunc) Process { + // child := WithParent(p) + // go func () { + // f(child) + // child.Close() + // }() + // } + // + // It is useful to construct simple asynchronous workers, children of p. + Go(f ProcessFunc) Process + + // SetTeardown sets the process's teardown to tf. + SetTeardown(tf TeardownFunc) + + // Close ends the process. Close blocks until the process has completely + // shut down, and any teardown has run _exactly once_. The returned error + // is available indefinitely: calling Close twice returns the same error. + // If the process has already been closed, Close returns immediately. + Close() error + + // CloseAfterChildren calls Close _after_ its children have Closed + // normally (i.e. it _does not_ attempt to close them). + CloseAfterChildren() error + + // Closing is a signal to wait upon. The returned channel is closed + // _after_ Close has been called at least once, but teardown may or may + // not be done yet. The primary use case of Closing is for children who + // need to know when a parent is shutting down, and therefore also shut + // down. + Closing() <-chan struct{} + + // Closed is a signal to wait upon. The returned channel is closed + // _after_ Close has completed; teardown has finished. The primary use case + // of Closed is waiting for a Process to Close without _causing_ the Close. + Closed() <-chan struct{} + + // Err waits until the process is closed, and then returns any error that + // occurred during shutdown. + Err() error +} + +// TeardownFunc is a function used to cleanup state at the end of the +// lifecycle of a Process. +type TeardownFunc func() error + +// ProcessFunc is a function that takes a process. Its main use case is goprocess.Go, +// which spawns a ProcessFunc in its own goroutine, and returns a corresponding +// Process object. +type ProcessFunc func(proc Process) + +var nilProcessFunc = func(Process) {} + +// Go is much like `go`: it runs a function in a newly spawned goroutine. The neat +// part of Go is that it provides Process object to communicate between the +// function and the outside world. Thus, callers can easily WaitFor, or Close the +// function. It is the function's responsibility to respect the Closing of its Process, +// namely it should exit (return) when <-Closing() is ready. It is simply: +// +// func Go(f ProcessFunc) Process { +// p := WithParent(Background()) +// p.Go(f) +// return p +// } +// +// Note that a naive implementation of Go like the following would not work: +// +// func Go(f ProcessFunc) Process { +// return Background().Go(f) +// } +// +// This is because having the process you +func Go(f ProcessFunc) Process { + // return GoChild(Background(), f) + + // we use two processes, one for communication, and + // one for ensuring we wait on the function (unclosable from the outside). + p := newProcess(nil) + waitFor := newProcess(nil) + p.WaitFor(waitFor) // prevent p from closing + go func() { + f(p) + waitFor.Close() // allow p to close. + p.Close() // ensure p closes. + }() + return p +} + +// GoChild is like Go, but it registers the returned Process as a child of parent, +// **before** spawning the goroutine, which ensures proper synchronization with parent. +// It is somewhat like +// +// func GoChild(parent Process, f ProcessFunc) Process { +// p := WithParent(parent) +// p.Go(f) +// return p +// } +// +// And it is similar to the classic WaitGroup use case: +// +// func WaitGroupGo(wg sync.WaitGroup, child func()) { +// wg.Add(1) +// go func() { +// child() +// wg.Done() +// }() +// } +// +func GoChild(parent Process, f ProcessFunc) Process { + p := WithParent(parent) + p.Go(f) + return p +} + +// Spawn is an alias of `Go`. In many contexts, Spawn is a +// well-known Process launching word, which fits our use case. +var Spawn = Go + +// SpawnChild is an alias of `GoChild`. In many contexts, Spawn is a +// well-known Process launching word, which fits our use case. +var SpawnChild = GoChild + +// WithTeardown constructs and returns a Process with a TeardownFunc. +// TeardownFunc tf will be called **exactly-once** when Process is +// Closing, after all Children have fully closed, and before p is Closed. +// In fact, Process p will not be Closed until tf runs and exits. +// See lifecycle in Process doc. +func WithTeardown(tf TeardownFunc) Process { + if tf == nil { + panic("nil tf TeardownFunc") + } + return newProcess(tf) +} + +// WithParent constructs and returns a Process with a given parent. +func WithParent(parent Process) Process { + if parent == nil { + panic("nil parent Process") + } + q := newProcess(nil) + parent.AddChild(q) + return q +} + +// WithSignals returns a Process that will Close() when any given signal fires. +// This is useful to bind Process trees to syscall.SIGTERM, SIGKILL, etc. +func WithSignals(sig ...os.Signal) Process { + p := WithParent(Background()) + c := make(chan os.Signal, 1) + signal.Notify(c, sig...) + go func() { + <-c + signal.Stop(c) + p.Close() + }() + return p +} diff --git a/vendor/github.com/jbenet/goprocess/impl-mutex.go b/vendor/github.com/jbenet/goprocess/impl-mutex.go new file mode 100644 index 00000000..9cb6ae75 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/impl-mutex.go @@ -0,0 +1,297 @@ +package goprocess + +import ( + "sync" +) + +// process implements Process +type process struct { + children map[*processLink]struct{} // process to close with us + waitfors map[*processLink]struct{} // process to only wait for + waiters []*processLink // processes that wait for us. for gc. + + teardown TeardownFunc // called to run the teardown logic. + closing chan struct{} // closed once close starts. + closed chan struct{} // closed once close is done. + closeErr error // error to return to clients of Close() + + sync.Mutex +} + +// newProcess constructs and returns a Process. +// It will call tf TeardownFunc exactly once: +// **after** all children have fully Closed, +// **after** entering <-Closing(), and +// **before** <-Closed(). +func newProcess(tf TeardownFunc) *process { + return &process{ + teardown: tf, + closed: make(chan struct{}), + closing: make(chan struct{}), + waitfors: make(map[*processLink]struct{}), + children: make(map[*processLink]struct{}), + } +} + +func (p *process) WaitFor(q Process) { + if q == nil { + panic("waiting for nil process") + } + + p.Lock() + defer p.Unlock() + + select { + case <-p.Closed(): + panic("Process cannot wait after being closed") + default: + } + + pl := newProcessLink(p, q) + if p.waitfors == nil { + // This may be nil when we're closing. In close, we'll keep + // reading this map till it stays nil. + p.waitfors = make(map[*processLink]struct{}, 1) + } + p.waitfors[pl] = struct{}{} + go pl.AddToChild() +} + +func (p *process) AddChildNoWait(child Process) { + if child == nil { + panic("adding nil child process") + } + + p.Lock() + defer p.Unlock() + + select { + case <-p.Closing(): + // Either closed or closing, close child immediately. This is + // correct because we aren't asked to _wait_ on this child. + go child.Close() + // Wait for the child to start closing so the child is in the + // "correct" state after this function finishes (see #17). + <-child.Closing() + return + default: + } + + pl := newProcessLink(p, child) + p.children[pl] = struct{}{} + go pl.AddToChild() +} + +func (p *process) AddChild(child Process) { + if child == nil { + panic("adding nil child process") + } + + p.Lock() + defer p.Unlock() + + pl := newProcessLink(p, child) + + select { + case <-p.Closed(): + // AddChild must not be called on a dead process. Maybe that's + // too strict? + panic("Process cannot add children after being closed") + default: + } + + select { + case <-p.Closing(): + // Already closing, close child in background. + go child.Close() + // Wait for the child to start closing so the child is in the + // "correct" state after this function finishes (see #17). + <-child.Closing() + default: + // Only add the child when not closing. When closing, just add + // it to the "waitfors" list. + p.children[pl] = struct{}{} + } + + if p.waitfors == nil { + // This may be be nil when we're closing. In close, we'll keep + // reading this map till it stays nil. + p.waitfors = make(map[*processLink]struct{}, 1) + } + p.waitfors[pl] = struct{}{} + go pl.AddToChild() +} + +func (p *process) Go(f ProcessFunc) Process { + child := newProcess(nil) + waitFor := newProcess(nil) + child.WaitFor(waitFor) // prevent child from closing + + // add child last, to prevent a closing parent from + // closing all of them prematurely, before running the func. + p.AddChild(child) + go func() { + f(child) + waitFor.Close() // allow child to close. + child.CloseAfterChildren() // close to tear down. + }() + return child +} + +// SetTeardown to assign a teardown function +func (p *process) SetTeardown(tf TeardownFunc) { + if tf == nil { + panic("cannot set nil TeardownFunc") + } + + p.Lock() + if p.teardown != nil { + panic("cannot SetTeardown twice") + } + + p.teardown = tf + select { + case <-p.Closed(): + p.closeErr = tf() + default: + } + p.Unlock() +} + +// Close is the external close function. +// it's a wrapper around internalClose that waits on Closed() +func (p *process) Close() error { + p.Lock() + + // if already closing, or closed, get out. (but wait!) + select { + case <-p.Closing(): + p.Unlock() + <-p.Closed() + return p.closeErr + default: + } + + p.doClose() + p.Unlock() + return p.closeErr +} + +func (p *process) Closing() <-chan struct{} { + return p.closing +} + +func (p *process) Closed() <-chan struct{} { + return p.closed +} + +func (p *process) Err() error { + <-p.Closed() + return p.closeErr +} + +// the _actual_ close process. +func (p *process) doClose() { + // this function is only be called once (protected by p.Lock()). + // and it will panic (on closing channels) otherwise. + + close(p.closing) // signal that we're shutting down (Closing) + + // We won't add any children after we start closing so we can do this + // once. + for plc, _ := range p.children { + child := plc.Child() + if child != nil { // check because child may already have been removed. + go child.Close() // force all children to shut down + } + + // safe to call multiple times per link + plc.ParentClear() + } + p.children = nil // clear them. release memory. + + // We may repeatedly continue to add waiters while we wait to close so + // we have to do this in a loop. + for len(p.waitfors) > 0 { + // we must be careful not to iterate over waitfors directly, as it may + // change under our feet. + wf := p.waitfors + p.waitfors = nil // clear them. release memory. + for w, _ := range wf { + // Here, we wait UNLOCKED, so that waitfors who are in the middle of + // adding a child to us can finish. we will immediately close the child. + p.Unlock() + <-w.ChildClosed() // wait till all waitfors are fully closed (before teardown) + p.Lock() + + // safe to call multiple times per link + w.ParentClear() + } + } + + if p.teardown != nil { + p.closeErr = p.teardown() // actually run the close logic (ok safe to teardown) + } + close(p.closed) // signal that we're shut down (Closed) + + // go remove all the parents from the process links. optimization. + go func(waiters []*processLink) { + for _, pl := range waiters { + pl.ClearChild() + pr, ok := pl.Parent().(*process) + if !ok { + // parent has already been called to close + continue + } + pr.Lock() + delete(pr.waitfors, pl) + delete(pr.children, pl) + pr.Unlock() + } + }(p.waiters) // pass in so + p.waiters = nil // clear them. release memory. +} + +// We will only wait on the children we have now. +// We will not wait on children added subsequently. +// this may change in the future. +func (p *process) CloseAfterChildren() error { + p.Lock() + select { + case <-p.Closed(): + p.Unlock() + return p.Close() // get error. safe, after p.Closed() + default: + } + p.Unlock() + + // here only from one goroutine. + + nextToWaitFor := func() Process { + p.Lock() + defer p.Unlock() + for e, _ := range p.waitfors { + c := e.Child() + if c == nil { + continue + } + + select { + case <-c.Closed(): + default: + return c + } + } + return nil + } + + // wait for all processes we're waiting for are closed. + // the semantics here are simple: we will _only_ close + // if there are no processes currently waiting for. + for next := nextToWaitFor(); next != nil; next = nextToWaitFor() { + <-next.Closed() + } + + // YAY! we're done. close + return p.Close() +} diff --git a/vendor/github.com/jbenet/goprocess/link.go b/vendor/github.com/jbenet/goprocess/link.go new file mode 100644 index 00000000..f46d81f6 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/link.go @@ -0,0 +1,128 @@ +package goprocess + +import ( + "sync" +) + +// closedCh is an alread-closed channel. used to return +// in cases where we already know a channel is closed. +var closedCh chan struct{} + +func init() { + closedCh = make(chan struct{}) + close(closedCh) +} + +// a processLink is an internal bookkeeping datastructure. +// it's used to form a relationship between two processes. +// It is mostly for keeping memory usage down (letting +// children close and be garbage-collected). +type processLink struct { + // guards all fields. + // DO NOT HOLD while holding process locks. + // it may be slow, and could deadlock if not careful. + sync.Mutex + parent Process + child Process +} + +func newProcessLink(p, c Process) *processLink { + return &processLink{ + parent: p, + child: c, + } +} + +// Closing returns whether the child is closing +func (pl *processLink) ChildClosing() <-chan struct{} { + // grab a hold of it, and unlock, as .Closing may block. + pl.Lock() + child := pl.child + pl.Unlock() + + if child == nil { // already closed? memory optimization. + return closedCh + } + return child.Closing() +} + +func (pl *processLink) ChildClosed() <-chan struct{} { + // grab a hold of it, and unlock, as .Closed may block. + pl.Lock() + child := pl.child + pl.Unlock() + + if child == nil { // already closed? memory optimization. + return closedCh + } + return child.Closed() +} + +func (pl *processLink) ChildClose() { + // grab a hold of it, and unlock, as .Closed may block. + pl.Lock() + child := pl.child + pl.Unlock() + + if child != nil { // already closed? memory optimization. + child.Close() + } +} + +func (pl *processLink) ClearChild() { + pl.Lock() + pl.child = nil + pl.Unlock() +} + +func (pl *processLink) ParentClear() { + pl.Lock() + pl.parent = nil + pl.Unlock() +} + +func (pl *processLink) Child() Process { + pl.Lock() + defer pl.Unlock() + return pl.child +} + +func (pl *processLink) Parent() Process { + pl.Lock() + defer pl.Unlock() + return pl.parent +} + +func (pl *processLink) AddToChild() { + cp := pl.Child() + + // is it a *process ? if not... panic. + var c *process + switch cp := cp.(type) { + case *process: + c = cp + case *bgProcess: + // Background process never closes so we don't need to do + // anything. + return + default: + panic("goprocess does not yet support other process impls.") + } + + // first, is it Closed? + c.Lock() + select { + case <-c.Closed(): + c.Unlock() + + // already closed. must not add. + // we must clear it, though. do so without the lock. + pl.ClearChild() + return + + default: + // put the process link into q's waiters + c.waiters = append(c.waiters, pl) + c.Unlock() + } +} diff --git a/vendor/github.com/jbenet/goprocess/package.json b/vendor/github.com/jbenet/goprocess/package.json new file mode 100644 index 00000000..07485337 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/package.json @@ -0,0 +1,14 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/jbenet/goprocess" + }, + "gx": { + "dvcsimport": "github.com/jbenet/goprocess" + }, + "gxVersion": "0.8.0", + "language": "go", + "license": "", + "name": "goprocess", + "version": "1.0.0" +} diff --git a/vendor/github.com/jbenet/goprocess/periodic/README.md b/vendor/github.com/jbenet/goprocess/periodic/README.md new file mode 100644 index 00000000..7a2c55db --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/periodic/README.md @@ -0,0 +1,4 @@ +# goprocess/periodic - periodic process creation + +- goprocess: https://github.com/jbenet/goprocess +- Godoc: https://godoc.org/github.com/jbenet/goprocess/periodic diff --git a/vendor/github.com/jbenet/goprocess/periodic/periodic.go b/vendor/github.com/jbenet/goprocess/periodic/periodic.go new file mode 100644 index 00000000..823c43dc --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/periodic/periodic.go @@ -0,0 +1,232 @@ +// Package periodic is part of github.com/jbenet/goprocess. +// It provides a simple periodic processor that calls a function +// periodically based on some options. +// +// For example: +// +// // use a time.Duration +// p := periodicproc.Every(time.Second, func(proc goprocess.Process) { +// fmt.Printf("the time is %s and all is well", time.Now()) +// }) +// +// <-time.After(5*time.Second) +// p.Close() +// +// // use a time.Time channel (like time.Ticker) +// p := periodicproc.Tick(time.Tick(time.Second), func(proc goprocess.Process) { +// fmt.Printf("the time is %s and all is well", time.Now()) +// }) +// +// <-time.After(5*time.Second) +// p.Close() +// +// // or arbitrary signals +// signal := make(chan struct{}) +// p := periodicproc.OnSignal(signal, func(proc goprocess.Process) { +// fmt.Printf("the time is %s and all is well", time.Now()) +// }) +// +// signal<- struct{}{} +// signal<- struct{}{} +// <-time.After(5 * time.Second) +// signal<- struct{}{} +// p.Close() +// +package periodicproc + +import ( + "time" + + gp "github.com/jbenet/goprocess" +) + +// Every calls the given ProcessFunc at periodic intervals. Internally, it uses +// <-time.After(interval), so it will have the behavior of waiting _at least_ +// interval in between calls. If you'd prefer the time.Ticker behavior, use +// periodicproc.Tick instead. +// This is sequentially rate limited, only one call will be in-flight at a time. +func Every(interval time.Duration, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + for { + select { + case <-time.After(interval): + select { + case <-proc.Go(procfunc).Closed(): // spin it out as a child, and wait till it's done. + case <-proc.Closing(): // we're told to close + return + } + case <-proc.Closing(): // we're told to close + return + } + } + }) +} + +// EveryGo calls the given ProcessFunc at periodic intervals. Internally, it uses +// <-time.After(interval) +// This is not rate limited, multiple calls could be in-flight at the same time. +func EveryGo(interval time.Duration, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + for { + select { + case <-time.After(interval): + proc.Go(procfunc) + case <-proc.Closing(): // we're told to close + return + } + } + }) +} + +// Tick constructs a ticker with interval, and calls the given ProcessFunc every +// time the ticker fires. +// This is sequentially rate limited, only one call will be in-flight at a time. +// +// p := periodicproc.Tick(time.Second, func(proc goprocess.Process) { +// fmt.Println("fire!") +// }) +// +// <-time.After(3 * time.Second) +// p.Close() +// +// // Output: +// // fire! +// // fire! +// // fire! +func Tick(interval time.Duration, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + ticker := time.NewTicker(interval) + callOnTicker(ticker.C, procfunc)(proc) + ticker.Stop() + }) +} + +// TickGo constructs a ticker with interval, and calls the given ProcessFunc every +// time the ticker fires. +// This is not rate limited, multiple calls could be in-flight at the same time. +// +// p := periodicproc.TickGo(time.Second, func(proc goprocess.Process) { +// fmt.Println("fire!") +// <-time.After(10 * time.Second) // will not block sequential execution +// }) +// +// <-time.After(3 * time.Second) +// p.Close() +// +// // Output: +// // fire! +// // fire! +// // fire! +func TickGo(interval time.Duration, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + ticker := time.NewTicker(interval) + goCallOnTicker(ticker.C, procfunc)(proc) + ticker.Stop() + }) +} + +// Ticker calls the given ProcessFunc every time the ticker fires. +// This is sequentially rate limited, only one call will be in-flight at a time. +func Ticker(ticker <-chan time.Time, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(callOnTicker(ticker, procfunc)) +} + +// TickerGo calls the given ProcessFunc every time the ticker fires. +// This is not rate limited, multiple calls could be in-flight at the same time. +func TickerGo(ticker <-chan time.Time, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(goCallOnTicker(ticker, procfunc)) +} + +func callOnTicker(ticker <-chan time.Time, pf gp.ProcessFunc) gp.ProcessFunc { + return func(proc gp.Process) { + for { + select { + case <-ticker: + select { + case <-proc.Go(pf).Closed(): // spin it out as a child, and wait till it's done. + case <-proc.Closing(): // we're told to close + return + } + case <-proc.Closing(): // we're told to close + return + } + } + } +} + +func goCallOnTicker(ticker <-chan time.Time, pf gp.ProcessFunc) gp.ProcessFunc { + return func(proc gp.Process) { + for { + select { + case <-ticker: + proc.Go(pf) + case <-proc.Closing(): // we're told to close + return + } + } + } +} + +// OnSignal calls the given ProcessFunc every time the signal fires, and waits for it to exit. +// This is sequentially rate limited, only one call will be in-flight at a time. +// +// sig := make(chan struct{}) +// p := periodicproc.OnSignal(sig, func(proc goprocess.Process) { +// fmt.Println("fire!") +// <-time.After(time.Second) // delays sequential execution by 1 second +// }) +// +// sig<- struct{} +// sig<- struct{} +// sig<- struct{} +// +// // Output: +// // fire! +// // fire! +// // fire! +func OnSignal(sig <-chan struct{}, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + for { + select { + case <-sig: + select { + case <-proc.Go(procfunc).Closed(): // spin it out as a child, and wait till it's done. + case <-proc.Closing(): // we're told to close + return + } + case <-proc.Closing(): // we're told to close + return + } + } + }) +} + +// OnSignalGo calls the given ProcessFunc every time the signal fires. +// This is not rate limited, multiple calls could be in-flight at the same time. +// +// sig := make(chan struct{}) +// p := periodicproc.OnSignalGo(sig, func(proc goprocess.Process) { +// fmt.Println("fire!") +// <-time.After(time.Second) // wont block execution +// }) +// +// sig<- struct{} +// sig<- struct{} +// sig<- struct{} +// +// // Output: +// // fire! +// // fire! +// // fire! +func OnSignalGo(sig <-chan struct{}, procfunc gp.ProcessFunc) gp.Process { + return gp.Go(func(proc gp.Process) { + for { + select { + case <-sig: + proc.Go(procfunc) + case <-proc.Closing(): // we're told to close + return + } + } + }) +} diff --git a/vendor/github.com/jbenet/goprocess/ratelimit/README.md b/vendor/github.com/jbenet/goprocess/ratelimit/README.md new file mode 100644 index 00000000..3c91185e --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/ratelimit/README.md @@ -0,0 +1,4 @@ +# goprocess/ratelimit - ratelimit children creation + +- goprocess: https://github.com/jbenet/goprocess +- Godoc: https://godoc.org/github.com/jbenet/goprocess/ratelimit diff --git a/vendor/github.com/jbenet/goprocess/ratelimit/ratelimit.go b/vendor/github.com/jbenet/goprocess/ratelimit/ratelimit.go new file mode 100644 index 00000000..1838d053 --- /dev/null +++ b/vendor/github.com/jbenet/goprocess/ratelimit/ratelimit.go @@ -0,0 +1,68 @@ +// Package ratelimit is part of github.com/jbenet/goprocess. +// It provides a simple process that ratelimits child creation. +// This is done internally with a channel/semaphore. +// So the call `RateLimiter.LimitedGo` may block until another +// child is Closed(). +package ratelimit + +import ( + process "github.com/jbenet/goprocess" +) + +// RateLimiter limits the spawning of children. It does so +// with an internal semaphore. Note that Go will continue +// to be the unlimited process.Process.Go, and ONLY the +// added function `RateLimiter.LimitedGo` will honor the +// limit. This is to improve readability and avoid confusion +// for the reader, particularly if code changes over time. +type RateLimiter struct { + process.Process + + limiter chan struct{} +} + +func NewRateLimiter(parent process.Process, limit int) *RateLimiter { + proc := process.WithParent(parent) + return &RateLimiter{Process: proc, limiter: LimitChan(limit)} +} + +// LimitedGo creates a new process, adds it as a child, and spawns the +// ProcessFunc f in its own goroutine, but may block according to the +// internal rate limit. It is equivalent to: +// +// func(f process.ProcessFunc) { +// <-limitch +// p.Go(func (child process.Process) { +// f(child) +// f.Close() // make sure its children close too! +// limitch<- struct{}{} +// }) +/// } +// +// It is useful to construct simple asynchronous workers, children of p, +// and rate limit their creation, to avoid spinning up too many, too fast. +// This is great for providing backpressure to producers. +func (rl *RateLimiter) LimitedGo(f process.ProcessFunc) { + + <-rl.limiter + p := rl.Go(f) + + // this <-closed() is here because the child may have spawned + // children of its own, and our rate limiter should capture that. + go func() { + <-p.Closed() + rl.limiter <- struct{}{} + }() +} + +// LimitChan returns a rate-limiting channel. it is the usual, simple, +// golang-idiomatic rate-limiting semaphore. This function merely +// initializes it with certain buffer size, and sends that many values, +// so it is ready to be used. +func LimitChan(limit int) chan struct{} { + limitch := make(chan struct{}, limit) + for i := 0; i < limit; i++ { + limitch <- struct{}{} + } + return limitch +} diff --git a/vendor/github.com/jmoiron/sqlx/.travis.yml b/vendor/github.com/jmoiron/sqlx/.travis.yml new file mode 100644 index 00000000..d7281526 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/.travis.yml @@ -0,0 +1,27 @@ +# vim: ft=yaml sw=2 ts=2 + +language: go + +# enable database services +services: + - mysql + - postgresql + +# create test database +before_install: + - mysql -e 'CREATE DATABASE IF NOT EXISTS sqlxtest;' + - psql -c 'create database sqlxtest;' -U postgres + - go get github.com/mattn/goveralls + - export SQLX_MYSQL_DSN="travis:@/sqlxtest?parseTime=true" + - export SQLX_POSTGRES_DSN="postgres://postgres:@localhost/sqlxtest?sslmode=disable" + - export SQLX_SQLITE_DSN="$HOME/sqlxtest.db" + +# go versions to test +go: + - "1.10.x" + - "1.11.x" + - "1.12.x" + +# run tests w/ coverage +script: + - travis_retry $GOPATH/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/jmoiron/sqlx/README.md b/vendor/github.com/jmoiron/sqlx/README.md new file mode 100644 index 00000000..6b586160 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/README.md @@ -0,0 +1,187 @@ +# sqlx + +[![Build Status](https://travis-ci.org/jmoiron/sqlx.svg?branch=master)](https://travis-ci.org/jmoiron/sqlx) [![Coverage Status](https://coveralls.io/repos/github/jmoiron/sqlx/badge.svg?branch=master)](https://coveralls.io/github/jmoiron/sqlx?branch=master) [![Godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/jmoiron/sqlx) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/jmoiron/sqlx/master/LICENSE) + +sqlx is a library which provides a set of extensions on go's standard +`database/sql` library. The sqlx versions of `sql.DB`, `sql.TX`, `sql.Stmt`, +et al. all leave the underlying interfaces untouched, so that their interfaces +are a superset on the standard ones. This makes it relatively painless to +integrate existing codebases using database/sql with sqlx. + +Major additional concepts are: + +* Marshal rows into structs (with embedded struct support), maps, and slices +* Named parameter support including prepared statements +* `Get` and `Select` to go quickly from query to struct/slice + +In addition to the [godoc API documentation](http://godoc.org/github.com/jmoiron/sqlx), +there is also some [user documentation](http://jmoiron.github.io/sqlx/) that +explains how to use `database/sql` along with sqlx. + +## Recent Changes + +* The [introduction](https://github.com/jmoiron/sqlx/pull/387) of `sql.ColumnType` sets the required minimum Go version to 1.8. + +* sqlx/types.JsonText has been renamed to JSONText to follow Go naming conventions. + +This breaks backwards compatibility, but it's in a way that is trivially fixable +(`s/JsonText/JSONText/g`). The `types` package is both experimental and not in +active development currently. + +* Using Go 1.6 and below with `types.JSONText` and `types.GzippedText` can be _potentially unsafe_, **especially** when used with common auto-scan sqlx idioms like `Select` and `Get`. See [golang bug #13905](https://github.com/golang/go/issues/13905). + +### Backwards Compatibility + +There is no Go1-like promise of absolute stability, but I take the issue seriously +and will maintain the library in a compatible state unless vital bugs prevent me +from doing so. Since [#59](https://github.com/jmoiron/sqlx/issues/59) and +[#60](https://github.com/jmoiron/sqlx/issues/60) necessitated breaking behavior, +a wider API cleanup was done at the time of fixing. It's possible this will happen +in future; if it does, a git tag will be provided for users requiring the old +behavior to continue to use it until such a time as they can migrate. + +## install + + go get github.com/jmoiron/sqlx + +## issues + +Row headers can be ambiguous (`SELECT 1 AS a, 2 AS a`), and the result of +`Columns()` does not fully qualify column names in queries like: + +```sql +SELECT a.id, a.name, b.id, b.name FROM foos AS a JOIN foos AS b ON a.parent = b.id; +``` + +making a struct or map destination ambiguous. Use `AS` in your queries +to give columns distinct names, `rows.Scan` to scan them manually, or +`SliceScan` to get a slice of results. + +## usage + +Below is an example which shows some common use cases for sqlx. Check +[sqlx_test.go](https://github.com/jmoiron/sqlx/blob/master/sqlx_test.go) for more +usage. + + +```go +package main + +import ( + "database/sql" + "fmt" + "log" + + _ "github.com/lib/pq" + "github.com/jmoiron/sqlx" +) + +var schema = ` +CREATE TABLE person ( + first_name text, + last_name text, + email text +); + +CREATE TABLE place ( + country text, + city text NULL, + telcode integer +)` + +type Person struct { + FirstName string `db:"first_name"` + LastName string `db:"last_name"` + Email string +} + +type Place struct { + Country string + City sql.NullString + TelCode int +} + +func main() { + // this Pings the database trying to connect, panics on error + // use sqlx.Open() for sql.Open() semantics + db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable") + if err != nil { + log.Fatalln(err) + } + + // exec the schema or fail; multi-statement Exec behavior varies between + // database drivers; pq will exec them all, sqlite3 won't, ymmv + db.MustExec(schema) + + tx := db.MustBegin() + tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "jmoiron@jmoiron.net") + tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "John", "Doe", "johndoeDNE@gmail.net") + tx.MustExec("INSERT INTO place (country, city, telcode) VALUES ($1, $2, $3)", "United States", "New York", "1") + tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Hong Kong", "852") + tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Singapore", "65") + // Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person + tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "jane.citzen@example.com"}) + tx.Commit() + + // Query the database, storing results in a []Person (wrapped in []interface{}) + people := []Person{} + db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC") + jason, john := people[0], people[1] + + fmt.Printf("%#v\n%#v", jason, john) + // Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"} + // Person{FirstName:"John", LastName:"Doe", Email:"johndoeDNE@gmail.net"} + + // You can also get a single result, a la QueryRow + jason = Person{} + err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason") + fmt.Printf("%#v\n", jason) + // Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"} + + // if you have null fields and use SELECT *, you must use sql.Null* in your struct + places := []Place{} + err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC") + if err != nil { + fmt.Println(err) + return + } + usa, singsing, honkers := places[0], places[1], places[2] + + fmt.Printf("%#v\n%#v\n%#v\n", usa, singsing, honkers) + // Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1} + // Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65} + // Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852} + + // Loop through rows using only one struct + place := Place{} + rows, err := db.Queryx("SELECT * FROM place") + for rows.Next() { + err := rows.StructScan(&place) + if err != nil { + log.Fatalln(err) + } + fmt.Printf("%#v\n", place) + } + // Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1} + // Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852} + // Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65} + + // Named queries, using `:name` as the bindvar. Automatic bindvar support + // which takes into account the dbtype based on the driverName on sqlx.Open/Connect + _, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`, + map[string]interface{}{ + "first": "Bin", + "last": "Smuth", + "email": "bensmith@allblacks.nz", + }) + + // Selects Mr. Smith from the database + rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:fn`, map[string]interface{}{"fn": "Bin"}) + + // Named queries can also use structs. Their bind names follow the same rules + // as the name -> db mapping, so struct fields are lowercased and the `db` tag + // is taken into consideration. + rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason) +} +``` + diff --git a/vendor/github.com/jmoiron/sqlx/bind.go b/vendor/github.com/jmoiron/sqlx/bind.go new file mode 100644 index 00000000..a3fc22cf --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/bind.go @@ -0,0 +1,217 @@ +package sqlx + +import ( + "bytes" + "database/sql/driver" + "errors" + "reflect" + "strconv" + "strings" + + "github.com/jmoiron/sqlx/reflectx" +) + +// Bindvar types supported by Rebind, BindMap and BindStruct. +const ( + UNKNOWN = iota + QUESTION + DOLLAR + NAMED + AT +) + +// BindType returns the bindtype for a given database given a drivername. +func BindType(driverName string) int { + switch driverName { + case "postgres", "pgx", "pq-timeouts", "cloudsqlpostgres", "ql": + return DOLLAR + case "mysql": + return QUESTION + case "sqlite3": + return QUESTION + case "oci8", "ora", "goracle": + return NAMED + case "sqlserver": + return AT + } + return UNKNOWN +} + +// FIXME: this should be able to be tolerant of escaped ?'s in queries without +// losing much speed, and should be to avoid confusion. + +// Rebind a query from the default bindtype (QUESTION) to the target bindtype. +func Rebind(bindType int, query string) string { + switch bindType { + case QUESTION, UNKNOWN: + return query + } + + // Add space enough for 10 params before we have to allocate + rqb := make([]byte, 0, len(query)+10) + + var i, j int + + for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") { + rqb = append(rqb, query[:i]...) + + switch bindType { + case DOLLAR: + rqb = append(rqb, '$') + case NAMED: + rqb = append(rqb, ':', 'a', 'r', 'g') + case AT: + rqb = append(rqb, '@', 'p') + } + + j++ + rqb = strconv.AppendInt(rqb, int64(j), 10) + + query = query[i+1:] + } + + return string(append(rqb, query...)) +} + +// Experimental implementation of Rebind which uses a bytes.Buffer. The code is +// much simpler and should be more resistant to odd unicode, but it is twice as +// slow. Kept here for benchmarking purposes and to possibly replace Rebind if +// problems arise with its somewhat naive handling of unicode. +func rebindBuff(bindType int, query string) string { + if bindType != DOLLAR { + return query + } + + b := make([]byte, 0, len(query)) + rqb := bytes.NewBuffer(b) + j := 1 + for _, r := range query { + if r == '?' { + rqb.WriteRune('$') + rqb.WriteString(strconv.Itoa(j)) + j++ + } else { + rqb.WriteRune(r) + } + } + + return rqb.String() +} + +// In expands slice values in args, returning the modified query string +// and a new arg list that can be executed by a database. The `query` should +// use the `?` bindVar. The return value uses the `?` bindVar. +func In(query string, args ...interface{}) (string, []interface{}, error) { + // argMeta stores reflect.Value and length for slices and + // the value itself for non-slice arguments + type argMeta struct { + v reflect.Value + i interface{} + length int + } + + var flatArgsCount int + var anySlices bool + + meta := make([]argMeta, len(args)) + + for i, arg := range args { + if a, ok := arg.(driver.Valuer); ok { + arg, _ = a.Value() + } + v := reflect.ValueOf(arg) + t := reflectx.Deref(v.Type()) + + // []byte is a driver.Value type so it should not be expanded + if t.Kind() == reflect.Slice && t != reflect.TypeOf([]byte{}) { + meta[i].length = v.Len() + meta[i].v = v + + anySlices = true + flatArgsCount += meta[i].length + + if meta[i].length == 0 { + return "", nil, errors.New("empty slice passed to 'in' query") + } + } else { + meta[i].i = arg + flatArgsCount++ + } + } + + // don't do any parsing if there aren't any slices; note that this means + // some errors that we might have caught below will not be returned. + if !anySlices { + return query, args, nil + } + + newArgs := make([]interface{}, 0, flatArgsCount) + buf := make([]byte, 0, len(query)+len(", ?")*flatArgsCount) + + var arg, offset int + + for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') { + if arg >= len(meta) { + // if an argument wasn't passed, lets return an error; this is + // not actually how database/sql Exec/Query works, but since we are + // creating an argument list programmatically, we want to be able + // to catch these programmer errors earlier. + return "", nil, errors.New("number of bindVars exceeds arguments") + } + + argMeta := meta[arg] + arg++ + + // not a slice, continue. + // our questionmark will either be written before the next expansion + // of a slice or after the loop when writing the rest of the query + if argMeta.length == 0 { + offset = offset + i + 1 + newArgs = append(newArgs, argMeta.i) + continue + } + + // write everything up to and including our ? character + buf = append(buf, query[:offset+i+1]...) + + for si := 1; si < argMeta.length; si++ { + buf = append(buf, ", ?"...) + } + + newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length) + + // slice the query and reset the offset. this avoids some bookkeeping for + // the write after the loop + query = query[offset+i+1:] + offset = 0 + } + + buf = append(buf, query...) + + if arg < len(meta) { + return "", nil, errors.New("number of bindVars less than number arguments") + } + + return string(buf), newArgs, nil +} + +func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} { + switch val := v.Interface().(type) { + case []interface{}: + args = append(args, val...) + case []int: + for i := range val { + args = append(args, val[i]) + } + case []string: + for i := range val { + args = append(args, val[i]) + } + default: + for si := 0; si < vlen; si++ { + args = append(args, v.Index(si).Interface()) + } + } + + return args +} diff --git a/vendor/github.com/jmoiron/sqlx/go.mod b/vendor/github.com/jmoiron/sqlx/go.mod new file mode 100644 index 00000000..66c67561 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/go.mod @@ -0,0 +1,7 @@ +module github.com/jmoiron/sqlx + +require ( + github.com/go-sql-driver/mysql v1.4.0 + github.com/lib/pq v1.0.0 + github.com/mattn/go-sqlite3 v1.9.0 +) diff --git a/vendor/github.com/jmoiron/sqlx/go.sum b/vendor/github.com/jmoiron/sqlx/go.sum new file mode 100644 index 00000000..a3239ada --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/go.sum @@ -0,0 +1,6 @@ +github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= diff --git a/vendor/github.com/jmoiron/sqlx/named.go b/vendor/github.com/jmoiron/sqlx/named.go new file mode 100644 index 00000000..a4056de0 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/named.go @@ -0,0 +1,413 @@ +package sqlx + +// Named Query Support +// +// * BindMap - bind query bindvars to map/struct args +// * NamedExec, NamedQuery - named query w/ struct or map +// * NamedStmt - a pre-compiled named query which is a prepared statement +// +// Internal Interfaces: +// +// * compileNamedQuery - rebind a named query, returning a query and list of names +// * bindArgs, bindMapArgs, bindAnyArgs - given a list of names, return an arglist +// +import ( + "bytes" + "database/sql" + "errors" + "fmt" + "reflect" + "regexp" + "strconv" + "unicode" + + "github.com/jmoiron/sqlx/reflectx" +) + +// NamedStmt is a prepared statement that executes named queries. Prepare it +// how you would execute a NamedQuery, but pass in a struct or map when executing. +type NamedStmt struct { + Params []string + QueryString string + Stmt *Stmt +} + +// Close closes the named statement. +func (n *NamedStmt) Close() error { + return n.Stmt.Close() +} + +// Exec executes a named statement using the struct passed. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) Exec(arg interface{}) (sql.Result, error) { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return *new(sql.Result), err + } + return n.Stmt.Exec(args...) +} + +// Query executes a named statement using the struct argument, returning rows. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) Query(arg interface{}) (*sql.Rows, error) { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return nil, err + } + return n.Stmt.Query(args...) +} + +// QueryRow executes a named statement against the database. Because sqlx cannot +// create a *sql.Row with an error condition pre-set for binding errors, sqlx +// returns a *sqlx.Row instead. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryRow(arg interface{}) *Row { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return &Row{err: err} + } + return n.Stmt.QueryRowx(args...) +} + +// MustExec execs a NamedStmt, panicing on error +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) MustExec(arg interface{}) sql.Result { + res, err := n.Exec(arg) + if err != nil { + panic(err) + } + return res +} + +// Queryx using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) Queryx(arg interface{}) (*Rows, error) { + r, err := n.Query(arg) + if err != nil { + return nil, err + } + return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err +} + +// QueryRowx this NamedStmt. Because of limitations with QueryRow, this is +// an alias for QueryRow. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryRowx(arg interface{}) *Row { + return n.QueryRow(arg) +} + +// Select using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) Select(dest interface{}, arg interface{}) error { + rows, err := n.Queryx(arg) + if err != nil { + return err + } + // if something happens here, we want to make sure the rows are Closed + defer rows.Close() + return scanAll(rows, dest, false) +} + +// Get using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) Get(dest interface{}, arg interface{}) error { + r := n.QueryRowx(arg) + return r.scanAny(dest, false) +} + +// Unsafe creates an unsafe version of the NamedStmt +func (n *NamedStmt) Unsafe() *NamedStmt { + r := &NamedStmt{Params: n.Params, Stmt: n.Stmt, QueryString: n.QueryString} + r.Stmt.unsafe = true + return r +} + +// A union interface of preparer and binder, required to be able to prepare +// named statements (as the bindtype must be determined). +type namedPreparer interface { + Preparer + binder +} + +func prepareNamed(p namedPreparer, query string) (*NamedStmt, error) { + bindType := BindType(p.DriverName()) + q, args, err := compileNamedQuery([]byte(query), bindType) + if err != nil { + return nil, err + } + stmt, err := Preparex(p, q) + if err != nil { + return nil, err + } + return &NamedStmt{ + QueryString: q, + Params: args, + Stmt: stmt, + }, nil +} + +func bindAnyArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) { + if maparg, ok := arg.(map[string]interface{}); ok { + return bindMapArgs(names, maparg) + } + return bindArgs(names, arg, m) +} + +// private interface to generate a list of interfaces from a given struct +// type, given a list of names to pull out of the struct. Used by public +// BindStruct interface. +func bindArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) { + arglist := make([]interface{}, 0, len(names)) + + // grab the indirected value of arg + v := reflect.ValueOf(arg) + for v = reflect.ValueOf(arg); v.Kind() == reflect.Ptr; { + v = v.Elem() + } + + err := m.TraversalsByNameFunc(v.Type(), names, func(i int, t []int) error { + if len(t) == 0 { + return fmt.Errorf("could not find name %s in %#v", names[i], arg) + } + + val := reflectx.FieldByIndexesReadOnly(v, t) + arglist = append(arglist, val.Interface()) + + return nil + }) + + return arglist, err +} + +// like bindArgs, but for maps. +func bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, error) { + arglist := make([]interface{}, 0, len(names)) + + for _, name := range names { + val, ok := arg[name] + if !ok { + return arglist, fmt.Errorf("could not find name %s in %#v", name, arg) + } + arglist = append(arglist, val) + } + return arglist, nil +} + +// bindStruct binds a named parameter query with fields from a struct argument. +// The rules for binding field names to parameter names follow the same +// conventions as for StructScan, including obeying the `db` struct tags. +func bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) { + bound, names, err := compileNamedQuery([]byte(query), bindType) + if err != nil { + return "", []interface{}{}, err + } + + arglist, err := bindArgs(names, arg, m) + if err != nil { + return "", []interface{}{}, err + } + + return bound, arglist, nil +} + +var valueBracketReg = regexp.MustCompile(`\([^(]*\?+[^)]*\)`) + +func fixBound(bound string, loop int) string { + loc := valueBracketReg.FindStringIndex(bound) + if len(loc) != 2 { + return bound + } + var buffer bytes.Buffer + + buffer.WriteString(bound[0:loc[1]]) + for i := 0; i < loop-1; i++ { + buffer.WriteString(",") + buffer.WriteString(bound[loc[0]:loc[1]]) + } + buffer.WriteString(bound[loc[1]:]) + return buffer.String() +} + +// bindArray binds a named parameter query with fields from an array or slice of +// structs argument. +func bindArray(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) { + // do the initial binding with QUESTION; if bindType is not question, + // we can rebind it at the end. + bound, names, err := compileNamedQuery([]byte(query), QUESTION) + if err != nil { + return "", []interface{}{}, err + } + arrayValue := reflect.ValueOf(arg) + arrayLen := arrayValue.Len() + if arrayLen == 0 { + return "", []interface{}{}, fmt.Errorf("length of array is 0: %#v", arg) + } + var arglist []interface{} + for i := 0; i < arrayLen; i++ { + elemArglist, err := bindArgs(names, arrayValue.Index(i).Interface(), m) + if err != nil { + return "", []interface{}{}, err + } + arglist = append(arglist, elemArglist...) + } + if arrayLen > 1 { + bound = fixBound(bound, arrayLen) + } + // adjust binding type if we weren't on question + if bindType != QUESTION { + bound = Rebind(bindType, bound) + } + return bound, arglist, nil +} + +// bindMap binds a named parameter query with a map of arguments. +func bindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) { + bound, names, err := compileNamedQuery([]byte(query), bindType) + if err != nil { + return "", []interface{}{}, err + } + + arglist, err := bindMapArgs(names, args) + return bound, arglist, err +} + +// -- Compilation of Named Queries + +// Allow digits and letters in bind params; additionally runes are +// checked against underscores, meaning that bind params can have be +// alphanumeric with underscores. Mind the difference between unicode +// digits and numbers, where '5' is a digit but '五' is not. +var allowedBindRunes = []*unicode.RangeTable{unicode.Letter, unicode.Digit} + +// FIXME: this function isn't safe for unicode named params, as a failing test +// can testify. This is not a regression but a failure of the original code +// as well. It should be modified to range over runes in a string rather than +// bytes, even though this is less convenient and slower. Hopefully the +// addition of the prepared NamedStmt (which will only do this once) will make +// up for the slightly slower ad-hoc NamedExec/NamedQuery. + +// compile a NamedQuery into an unbound query (using the '?' bindvar) and +// a list of names. +func compileNamedQuery(qs []byte, bindType int) (query string, names []string, err error) { + names = make([]string, 0, 10) + rebound := make([]byte, 0, len(qs)) + + inName := false + last := len(qs) - 1 + currentVar := 1 + name := make([]byte, 0, 10) + + for i, b := range qs { + // a ':' while we're in a name is an error + if b == ':' { + // if this is the second ':' in a '::' escape sequence, append a ':' + if inName && i > 0 && qs[i-1] == ':' { + rebound = append(rebound, ':') + inName = false + continue + } else if inName { + err = errors.New("unexpected `:` while reading named param at " + strconv.Itoa(i)) + return query, names, err + } + inName = true + name = []byte{} + } else if inName && i > 0 && b == '=' && len(name) == 0 { + rebound = append(rebound, ':', '=') + inName = false + continue + // if we're in a name, and this is an allowed character, continue + } else if inName && (unicode.IsOneOf(allowedBindRunes, rune(b)) || b == '_' || b == '.') && i != last { + // append the byte to the name if we are in a name and not on the last byte + name = append(name, b) + // if we're in a name and it's not an allowed character, the name is done + } else if inName { + inName = false + // if this is the final byte of the string and it is part of the name, then + // make sure to add it to the name + if i == last && unicode.IsOneOf(allowedBindRunes, rune(b)) { + name = append(name, b) + } + // add the string representation to the names list + names = append(names, string(name)) + // add a proper bindvar for the bindType + switch bindType { + // oracle only supports named type bind vars even for positional + case NAMED: + rebound = append(rebound, ':') + rebound = append(rebound, name...) + case QUESTION, UNKNOWN: + rebound = append(rebound, '?') + case DOLLAR: + rebound = append(rebound, '$') + for _, b := range strconv.Itoa(currentVar) { + rebound = append(rebound, byte(b)) + } + currentVar++ + case AT: + rebound = append(rebound, '@', 'p') + for _, b := range strconv.Itoa(currentVar) { + rebound = append(rebound, byte(b)) + } + currentVar++ + } + // add this byte to string unless it was not part of the name + if i != last { + rebound = append(rebound, b) + } else if !unicode.IsOneOf(allowedBindRunes, rune(b)) { + rebound = append(rebound, b) + } + } else { + // this is a normal byte and should just go onto the rebound query + rebound = append(rebound, b) + } + } + + return string(rebound), names, err +} + +// BindNamed binds a struct or a map to a query with named parameters. +// DEPRECATED: use sqlx.Named` instead of this, it may be removed in future. +func BindNamed(bindType int, query string, arg interface{}) (string, []interface{}, error) { + return bindNamedMapper(bindType, query, arg, mapper()) +} + +// Named takes a query using named parameters and an argument and +// returns a new query with a list of args that can be executed by +// a database. The return value uses the `?` bindvar. +func Named(query string, arg interface{}) (string, []interface{}, error) { + return bindNamedMapper(QUESTION, query, arg, mapper()) +} + +func bindNamedMapper(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) { + if maparg, ok := arg.(map[string]interface{}); ok { + return bindMap(bindType, query, maparg) + } + switch reflect.TypeOf(arg).Kind() { + case reflect.Array, reflect.Slice: + return bindArray(bindType, query, arg, m) + default: + return bindStruct(bindType, query, arg, m) + } +} + +// NamedQuery binds a named query and then runs Query on the result using the +// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with +// map[string]interface{} types. +func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) { + q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e)) + if err != nil { + return nil, err + } + return e.Queryx(q, args...) +} + +// NamedExec uses BindStruct to get a query executable by the driver and +// then runs Exec on the result. Returns an error from the binding +// or the query execution itself. +func NamedExec(e Ext, query string, arg interface{}) (sql.Result, error) { + q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e)) + if err != nil { + return nil, err + } + return e.Exec(q, args...) +} diff --git a/vendor/github.com/jmoiron/sqlx/named_context.go b/vendor/github.com/jmoiron/sqlx/named_context.go new file mode 100644 index 00000000..07ad2165 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/named_context.go @@ -0,0 +1,132 @@ +// +build go1.8 + +package sqlx + +import ( + "context" + "database/sql" +) + +// A union interface of contextPreparer and binder, required to be able to +// prepare named statements with context (as the bindtype must be determined). +type namedPreparerContext interface { + PreparerContext + binder +} + +func prepareNamedContext(ctx context.Context, p namedPreparerContext, query string) (*NamedStmt, error) { + bindType := BindType(p.DriverName()) + q, args, err := compileNamedQuery([]byte(query), bindType) + if err != nil { + return nil, err + } + stmt, err := PreparexContext(ctx, p, q) + if err != nil { + return nil, err + } + return &NamedStmt{ + QueryString: q, + Params: args, + Stmt: stmt, + }, nil +} + +// ExecContext executes a named statement using the struct passed. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) ExecContext(ctx context.Context, arg interface{}) (sql.Result, error) { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return *new(sql.Result), err + } + return n.Stmt.ExecContext(ctx, args...) +} + +// QueryContext executes a named statement using the struct argument, returning rows. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryContext(ctx context.Context, arg interface{}) (*sql.Rows, error) { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return nil, err + } + return n.Stmt.QueryContext(ctx, args...) +} + +// QueryRowContext executes a named statement against the database. Because sqlx cannot +// create a *sql.Row with an error condition pre-set for binding errors, sqlx +// returns a *sqlx.Row instead. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryRowContext(ctx context.Context, arg interface{}) *Row { + args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper) + if err != nil { + return &Row{err: err} + } + return n.Stmt.QueryRowxContext(ctx, args...) +} + +// MustExecContext execs a NamedStmt, panicing on error +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) MustExecContext(ctx context.Context, arg interface{}) sql.Result { + res, err := n.ExecContext(ctx, arg) + if err != nil { + panic(err) + } + return res +} + +// QueryxContext using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryxContext(ctx context.Context, arg interface{}) (*Rows, error) { + r, err := n.QueryContext(ctx, arg) + if err != nil { + return nil, err + } + return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err +} + +// QueryRowxContext this NamedStmt. Because of limitations with QueryRow, this is +// an alias for QueryRow. +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) QueryRowxContext(ctx context.Context, arg interface{}) *Row { + return n.QueryRowContext(ctx, arg) +} + +// SelectContext using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) SelectContext(ctx context.Context, dest interface{}, arg interface{}) error { + rows, err := n.QueryxContext(ctx, arg) + if err != nil { + return err + } + // if something happens here, we want to make sure the rows are Closed + defer rows.Close() + return scanAll(rows, dest, false) +} + +// GetContext using this NamedStmt +// Any named placeholder parameters are replaced with fields from arg. +func (n *NamedStmt) GetContext(ctx context.Context, dest interface{}, arg interface{}) error { + r := n.QueryRowxContext(ctx, arg) + return r.scanAny(dest, false) +} + +// NamedQueryContext binds a named query and then runs Query on the result using the +// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with +// map[string]interface{} types. +func NamedQueryContext(ctx context.Context, e ExtContext, query string, arg interface{}) (*Rows, error) { + q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e)) + if err != nil { + return nil, err + } + return e.QueryxContext(ctx, q, args...) +} + +// NamedExecContext uses BindStruct to get a query executable by the driver and +// then runs Exec on the result. Returns an error from the binding +// or the query execution itself. +func NamedExecContext(ctx context.Context, e ExtContext, query string, arg interface{}) (sql.Result, error) { + q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e)) + if err != nil { + return nil, err + } + return e.ExecContext(ctx, q, args...) +} diff --git a/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go b/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go new file mode 100644 index 00000000..458021dc --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go @@ -0,0 +1,439 @@ +// Package reflectx implements extensions to the standard reflect lib suitable +// for implementing marshalling and unmarshalling packages. The main Mapper type +// allows for Go-compatible named attribute access, including accessing embedded +// struct attributes and the ability to use functions and struct tags to +// customize field names. +// +package reflectx + +import ( + "reflect" + "runtime" + "strings" + "sync" +) + +// A FieldInfo is metadata for a struct field. +type FieldInfo struct { + Index []int + Path string + Field reflect.StructField + Zero reflect.Value + Name string + Options map[string]string + Embedded bool + Children []*FieldInfo + Parent *FieldInfo +} + +// A StructMap is an index of field metadata for a struct. +type StructMap struct { + Tree *FieldInfo + Index []*FieldInfo + Paths map[string]*FieldInfo + Names map[string]*FieldInfo +} + +// GetByPath returns a *FieldInfo for a given string path. +func (f StructMap) GetByPath(path string) *FieldInfo { + return f.Paths[path] +} + +// GetByTraversal returns a *FieldInfo for a given integer path. It is +// analogous to reflect.FieldByIndex, but using the cached traversal +// rather than re-executing the reflect machinery each time. +func (f StructMap) GetByTraversal(index []int) *FieldInfo { + if len(index) == 0 { + return nil + } + + tree := f.Tree + for _, i := range index { + if i >= len(tree.Children) || tree.Children[i] == nil { + return nil + } + tree = tree.Children[i] + } + return tree +} + +// Mapper is a general purpose mapper of names to struct fields. A Mapper +// behaves like most marshallers in the standard library, obeying a field tag +// for name mapping but also providing a basic transform function. +type Mapper struct { + cache map[reflect.Type]*StructMap + tagName string + tagMapFunc func(string) string + mapFunc func(string) string + mutex sync.Mutex +} + +// NewMapper returns a new mapper using the tagName as its struct field tag. +// If tagName is the empty string, it is ignored. +func NewMapper(tagName string) *Mapper { + return &Mapper{ + cache: make(map[reflect.Type]*StructMap), + tagName: tagName, + } +} + +// NewMapperTagFunc returns a new mapper which contains a mapper for field names +// AND a mapper for tag values. This is useful for tags like json which can +// have values like "name,omitempty". +func NewMapperTagFunc(tagName string, mapFunc, tagMapFunc func(string) string) *Mapper { + return &Mapper{ + cache: make(map[reflect.Type]*StructMap), + tagName: tagName, + mapFunc: mapFunc, + tagMapFunc: tagMapFunc, + } +} + +// NewMapperFunc returns a new mapper which optionally obeys a field tag and +// a struct field name mapper func given by f. Tags will take precedence, but +// for any other field, the mapped name will be f(field.Name) +func NewMapperFunc(tagName string, f func(string) string) *Mapper { + return &Mapper{ + cache: make(map[reflect.Type]*StructMap), + tagName: tagName, + mapFunc: f, + } +} + +// TypeMap returns a mapping of field strings to int slices representing +// the traversal down the struct to reach the field. +func (m *Mapper) TypeMap(t reflect.Type) *StructMap { + m.mutex.Lock() + mapping, ok := m.cache[t] + if !ok { + mapping = getMapping(t, m.tagName, m.mapFunc, m.tagMapFunc) + m.cache[t] = mapping + } + m.mutex.Unlock() + return mapping +} + +// FieldMap returns the mapper's mapping of field names to reflect values. Panics +// if v's Kind is not Struct, or v is not Indirectable to a struct kind. +func (m *Mapper) FieldMap(v reflect.Value) map[string]reflect.Value { + v = reflect.Indirect(v) + mustBe(v, reflect.Struct) + + r := map[string]reflect.Value{} + tm := m.TypeMap(v.Type()) + for tagName, fi := range tm.Names { + r[tagName] = FieldByIndexes(v, fi.Index) + } + return r +} + +// FieldByName returns a field by its mapped name as a reflect.Value. +// Panics if v's Kind is not Struct or v is not Indirectable to a struct Kind. +// Returns zero Value if the name is not found. +func (m *Mapper) FieldByName(v reflect.Value, name string) reflect.Value { + v = reflect.Indirect(v) + mustBe(v, reflect.Struct) + + tm := m.TypeMap(v.Type()) + fi, ok := tm.Names[name] + if !ok { + return v + } + return FieldByIndexes(v, fi.Index) +} + +// FieldsByName returns a slice of values corresponding to the slice of names +// for the value. Panics if v's Kind is not Struct or v is not Indirectable +// to a struct Kind. Returns zero Value for each name not found. +func (m *Mapper) FieldsByName(v reflect.Value, names []string) []reflect.Value { + v = reflect.Indirect(v) + mustBe(v, reflect.Struct) + + tm := m.TypeMap(v.Type()) + vals := make([]reflect.Value, 0, len(names)) + for _, name := range names { + fi, ok := tm.Names[name] + if !ok { + vals = append(vals, *new(reflect.Value)) + } else { + vals = append(vals, FieldByIndexes(v, fi.Index)) + } + } + return vals +} + +// TraversalsByName returns a slice of int slices which represent the struct +// traversals for each mapped name. Panics if t is not a struct or Indirectable +// to a struct. Returns empty int slice for each name not found. +func (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int { + r := make([][]int, 0, len(names)) + m.TraversalsByNameFunc(t, names, func(_ int, i []int) error { + if i == nil { + r = append(r, []int{}) + } else { + r = append(r, i) + } + + return nil + }) + return r +} + +// TraversalsByNameFunc traverses the mapped names and calls fn with the index of +// each name and the struct traversal represented by that name. Panics if t is not +// a struct or Indirectable to a struct. Returns the first error returned by fn or nil. +func (m *Mapper) TraversalsByNameFunc(t reflect.Type, names []string, fn func(int, []int) error) error { + t = Deref(t) + mustBe(t, reflect.Struct) + tm := m.TypeMap(t) + for i, name := range names { + fi, ok := tm.Names[name] + if !ok { + if err := fn(i, nil); err != nil { + return err + } + } else { + if err := fn(i, fi.Index); err != nil { + return err + } + } + } + return nil +} + +// FieldByIndexes returns a value for the field given by the struct traversal +// for the given value. +func FieldByIndexes(v reflect.Value, indexes []int) reflect.Value { + for _, i := range indexes { + v = reflect.Indirect(v).Field(i) + // if this is a pointer and it's nil, allocate a new value and set it + if v.Kind() == reflect.Ptr && v.IsNil() { + alloc := reflect.New(Deref(v.Type())) + v.Set(alloc) + } + if v.Kind() == reflect.Map && v.IsNil() { + v.Set(reflect.MakeMap(v.Type())) + } + } + return v +} + +// FieldByIndexesReadOnly returns a value for a particular struct traversal, +// but is not concerned with allocating nil pointers because the value is +// going to be used for reading and not setting. +func FieldByIndexesReadOnly(v reflect.Value, indexes []int) reflect.Value { + for _, i := range indexes { + v = reflect.Indirect(v).Field(i) + } + return v +} + +// Deref is Indirect for reflect.Types +func Deref(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + +// -- helpers & utilities -- + +type kinder interface { + Kind() reflect.Kind +} + +// mustBe checks a value against a kind, panicing with a reflect.ValueError +// if the kind isn't that which is required. +func mustBe(v kinder, expected reflect.Kind) { + if k := v.Kind(); k != expected { + panic(&reflect.ValueError{Method: methodName(), Kind: k}) + } +} + +// methodName returns the caller of the function calling methodName +func methodName() string { + pc, _, _, _ := runtime.Caller(2) + f := runtime.FuncForPC(pc) + if f == nil { + return "unknown method" + } + return f.Name() +} + +type typeQueue struct { + t reflect.Type + fi *FieldInfo + pp string // Parent path +} + +// A copying append that creates a new slice each time. +func apnd(is []int, i int) []int { + x := make([]int, len(is)+1) + copy(x, is) + x[len(x)-1] = i + return x +} + +type mapf func(string) string + +// parseName parses the tag and the target name for the given field using +// the tagName (eg 'json' for `json:"foo"` tags), mapFunc for mapping the +// field's name to a target name, and tagMapFunc for mapping the tag to +// a target name. +func parseName(field reflect.StructField, tagName string, mapFunc, tagMapFunc mapf) (tag, fieldName string) { + // first, set the fieldName to the field's name + fieldName = field.Name + // if a mapFunc is set, use that to override the fieldName + if mapFunc != nil { + fieldName = mapFunc(fieldName) + } + + // if there's no tag to look for, return the field name + if tagName == "" { + return "", fieldName + } + + // if this tag is not set using the normal convention in the tag, + // then return the fieldname.. this check is done because according + // to the reflect documentation: + // If the tag does not have the conventional format, + // the value returned by Get is unspecified. + // which doesn't sound great. + if !strings.Contains(string(field.Tag), tagName+":") { + return "", fieldName + } + + // at this point we're fairly sure that we have a tag, so lets pull it out + tag = field.Tag.Get(tagName) + + // if we have a mapper function, call it on the whole tag + // XXX: this is a change from the old version, which pulled out the name + // before the tagMapFunc could be run, but I think this is the right way + if tagMapFunc != nil { + tag = tagMapFunc(tag) + } + + // finally, split the options from the name + parts := strings.Split(tag, ",") + fieldName = parts[0] + + return tag, fieldName +} + +// parseOptions parses options out of a tag string, skipping the name +func parseOptions(tag string) map[string]string { + parts := strings.Split(tag, ",") + options := make(map[string]string, len(parts)) + if len(parts) > 1 { + for _, opt := range parts[1:] { + // short circuit potentially expensive split op + if strings.Contains(opt, "=") { + kv := strings.Split(opt, "=") + options[kv[0]] = kv[1] + continue + } + options[opt] = "" + } + } + return options +} + +// getMapping returns a mapping for the t type, using the tagName, mapFunc and +// tagMapFunc to determine the canonical names of fields. +func getMapping(t reflect.Type, tagName string, mapFunc, tagMapFunc mapf) *StructMap { + m := []*FieldInfo{} + + root := &FieldInfo{} + queue := []typeQueue{} + queue = append(queue, typeQueue{Deref(t), root, ""}) + +QueueLoop: + for len(queue) != 0 { + // pop the first item off of the queue + tq := queue[0] + queue = queue[1:] + + // ignore recursive field + for p := tq.fi.Parent; p != nil; p = p.Parent { + if tq.fi.Field.Type == p.Field.Type { + continue QueueLoop + } + } + + nChildren := 0 + if tq.t.Kind() == reflect.Struct { + nChildren = tq.t.NumField() + } + tq.fi.Children = make([]*FieldInfo, nChildren) + + // iterate through all of its fields + for fieldPos := 0; fieldPos < nChildren; fieldPos++ { + + f := tq.t.Field(fieldPos) + + // parse the tag and the target name using the mapping options for this field + tag, name := parseName(f, tagName, mapFunc, tagMapFunc) + + // if the name is "-", disabled via a tag, skip it + if name == "-" { + continue + } + + fi := FieldInfo{ + Field: f, + Name: name, + Zero: reflect.New(f.Type).Elem(), + Options: parseOptions(tag), + } + + // if the path is empty this path is just the name + if tq.pp == "" { + fi.Path = fi.Name + } else { + fi.Path = tq.pp + "." + fi.Name + } + + // skip unexported fields + if len(f.PkgPath) != 0 && !f.Anonymous { + continue + } + + // bfs search of anonymous embedded structs + if f.Anonymous { + pp := tq.pp + if tag != "" { + pp = fi.Path + } + + fi.Embedded = true + fi.Index = apnd(tq.fi.Index, fieldPos) + nChildren := 0 + ft := Deref(f.Type) + if ft.Kind() == reflect.Struct { + nChildren = ft.NumField() + } + fi.Children = make([]*FieldInfo, nChildren) + queue = append(queue, typeQueue{Deref(f.Type), &fi, pp}) + } else if fi.Zero.Kind() == reflect.Struct || (fi.Zero.Kind() == reflect.Ptr && fi.Zero.Type().Elem().Kind() == reflect.Struct) { + fi.Index = apnd(tq.fi.Index, fieldPos) + fi.Children = make([]*FieldInfo, Deref(f.Type).NumField()) + queue = append(queue, typeQueue{Deref(f.Type), &fi, fi.Path}) + } + + fi.Index = apnd(tq.fi.Index, fieldPos) + fi.Parent = tq.fi + tq.fi.Children[fieldPos] = &fi + m = append(m, &fi) + } + } + + flds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}} + for _, fi := range flds.Index { + flds.Paths[fi.Path] = fi + if fi.Name != "" && !fi.Embedded { + flds.Names[fi.Path] = fi + } + } + + return flds +} diff --git a/vendor/github.com/jmoiron/sqlx/sqlx.go b/vendor/github.com/jmoiron/sqlx/sqlx.go new file mode 100644 index 00000000..ce64cbc9 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/sqlx.go @@ -0,0 +1,1045 @@ +package sqlx + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + + "io/ioutil" + "path/filepath" + "reflect" + "strings" + "sync" + + "github.com/jmoiron/sqlx/reflectx" +) + +// Although the NameMapper is convenient, in practice it should not +// be relied on except for application code. If you are writing a library +// that uses sqlx, you should be aware that the name mappings you expect +// can be overridden by your user's application. + +// NameMapper is used to map column names to struct field names. By default, +// it uses strings.ToLower to lowercase struct field names. It can be set +// to whatever you want, but it is encouraged to be set before sqlx is used +// as name-to-field mappings are cached after first use on a type. +var NameMapper = strings.ToLower +var origMapper = reflect.ValueOf(NameMapper) + +// Rather than creating on init, this is created when necessary so that +// importers have time to customize the NameMapper. +var mpr *reflectx.Mapper + +// mprMu protects mpr. +var mprMu sync.Mutex + +// mapper returns a valid mapper using the configured NameMapper func. +func mapper() *reflectx.Mapper { + mprMu.Lock() + defer mprMu.Unlock() + + if mpr == nil { + mpr = reflectx.NewMapperFunc("db", NameMapper) + } else if origMapper != reflect.ValueOf(NameMapper) { + // if NameMapper has changed, create a new mapper + mpr = reflectx.NewMapperFunc("db", NameMapper) + origMapper = reflect.ValueOf(NameMapper) + } + return mpr +} + +// isScannable takes the reflect.Type and the actual dest value and returns +// whether or not it's Scannable. Something is scannable if: +// * it is not a struct +// * it implements sql.Scanner +// * it has no exported fields +func isScannable(t reflect.Type) bool { + if reflect.PtrTo(t).Implements(_scannerInterface) { + return true + } + if t.Kind() != reflect.Struct { + return true + } + + // it's not important that we use the right mapper for this particular object, + // we're only concerned on how many exported fields this struct has + m := mapper() + if len(m.TypeMap(t).Index) == 0 { + return true + } + return false +} + +// ColScanner is an interface used by MapScan and SliceScan +type ColScanner interface { + Columns() ([]string, error) + Scan(dest ...interface{}) error + Err() error +} + +// Queryer is an interface used by Get and Select +type Queryer interface { + Query(query string, args ...interface{}) (*sql.Rows, error) + Queryx(query string, args ...interface{}) (*Rows, error) + QueryRowx(query string, args ...interface{}) *Row +} + +// Execer is an interface used by MustExec and LoadFile +type Execer interface { + Exec(query string, args ...interface{}) (sql.Result, error) +} + +// Binder is an interface for something which can bind queries (Tx, DB) +type binder interface { + DriverName() string + Rebind(string) string + BindNamed(string, interface{}) (string, []interface{}, error) +} + +// Ext is a union interface which can bind, query, and exec, used by +// NamedQuery and NamedExec. +type Ext interface { + binder + Queryer + Execer +} + +// Preparer is an interface used by Preparex. +type Preparer interface { + Prepare(query string) (*sql.Stmt, error) +} + +// determine if any of our extensions are unsafe +func isUnsafe(i interface{}) bool { + switch v := i.(type) { + case Row: + return v.unsafe + case *Row: + return v.unsafe + case Rows: + return v.unsafe + case *Rows: + return v.unsafe + case NamedStmt: + return v.Stmt.unsafe + case *NamedStmt: + return v.Stmt.unsafe + case Stmt: + return v.unsafe + case *Stmt: + return v.unsafe + case qStmt: + return v.unsafe + case *qStmt: + return v.unsafe + case DB: + return v.unsafe + case *DB: + return v.unsafe + case Tx: + return v.unsafe + case *Tx: + return v.unsafe + case sql.Rows, *sql.Rows: + return false + default: + return false + } +} + +func mapperFor(i interface{}) *reflectx.Mapper { + switch i := i.(type) { + case DB: + return i.Mapper + case *DB: + return i.Mapper + case Tx: + return i.Mapper + case *Tx: + return i.Mapper + default: + return mapper() + } +} + +var _scannerInterface = reflect.TypeOf((*sql.Scanner)(nil)).Elem() +var _valuerInterface = reflect.TypeOf((*driver.Valuer)(nil)).Elem() + +// Row is a reimplementation of sql.Row in order to gain access to the underlying +// sql.Rows.Columns() data, necessary for StructScan. +type Row struct { + err error + unsafe bool + rows *sql.Rows + Mapper *reflectx.Mapper +} + +// Scan is a fixed implementation of sql.Row.Scan, which does not discard the +// underlying error from the internal rows object if it exists. +func (r *Row) Scan(dest ...interface{}) error { + if r.err != nil { + return r.err + } + + // TODO(bradfitz): for now we need to defensively clone all + // []byte that the driver returned (not permitting + // *RawBytes in Rows.Scan), since we're about to close + // the Rows in our defer, when we return from this function. + // the contract with the driver.Next(...) interface is that it + // can return slices into read-only temporary memory that's + // only valid until the next Scan/Close. But the TODO is that + // for a lot of drivers, this copy will be unnecessary. We + // should provide an optional interface for drivers to + // implement to say, "don't worry, the []bytes that I return + // from Next will not be modified again." (for instance, if + // they were obtained from the network anyway) But for now we + // don't care. + defer r.rows.Close() + for _, dp := range dest { + if _, ok := dp.(*sql.RawBytes); ok { + return errors.New("sql: RawBytes isn't allowed on Row.Scan") + } + } + + if !r.rows.Next() { + if err := r.rows.Err(); err != nil { + return err + } + return sql.ErrNoRows + } + err := r.rows.Scan(dest...) + if err != nil { + return err + } + // Make sure the query can be processed to completion with no errors. + if err := r.rows.Close(); err != nil { + return err + } + return nil +} + +// Columns returns the underlying sql.Rows.Columns(), or the deferred error usually +// returned by Row.Scan() +func (r *Row) Columns() ([]string, error) { + if r.err != nil { + return []string{}, r.err + } + return r.rows.Columns() +} + +// ColumnTypes returns the underlying sql.Rows.ColumnTypes(), or the deferred error +func (r *Row) ColumnTypes() ([]*sql.ColumnType, error) { + if r.err != nil { + return []*sql.ColumnType{}, r.err + } + return r.rows.ColumnTypes() +} + +// Err returns the error encountered while scanning. +func (r *Row) Err() error { + return r.err +} + +// DB is a wrapper around sql.DB which keeps track of the driverName upon Open, +// used mostly to automatically bind named queries using the right bindvars. +type DB struct { + *sql.DB + driverName string + unsafe bool + Mapper *reflectx.Mapper +} + +// NewDb returns a new sqlx DB wrapper for a pre-existing *sql.DB. The +// driverName of the original database is required for named query support. +func NewDb(db *sql.DB, driverName string) *DB { + return &DB{DB: db, driverName: driverName, Mapper: mapper()} +} + +// DriverName returns the driverName passed to the Open function for this DB. +func (db *DB) DriverName() string { + return db.driverName +} + +// Open is the same as sql.Open, but returns an *sqlx.DB instead. +func Open(driverName, dataSourceName string) (*DB, error) { + db, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return &DB{DB: db, driverName: driverName, Mapper: mapper()}, err +} + +// MustOpen is the same as sql.Open, but returns an *sqlx.DB instead and panics on error. +func MustOpen(driverName, dataSourceName string) *DB { + db, err := Open(driverName, dataSourceName) + if err != nil { + panic(err) + } + return db +} + +// MapperFunc sets a new mapper for this db using the default sqlx struct tag +// and the provided mapper function. +func (db *DB) MapperFunc(mf func(string) string) { + db.Mapper = reflectx.NewMapperFunc("db", mf) +} + +// Rebind transforms a query from QUESTION to the DB driver's bindvar type. +func (db *DB) Rebind(query string) string { + return Rebind(BindType(db.driverName), query) +} + +// Unsafe returns a version of DB which will silently succeed to scan when +// columns in the SQL result have no fields in the destination struct. +// sqlx.Stmt and sqlx.Tx which are created from this DB will inherit its +// safety behavior. +func (db *DB) Unsafe() *DB { + return &DB{DB: db.DB, driverName: db.driverName, unsafe: true, Mapper: db.Mapper} +} + +// BindNamed binds a query using the DB driver's bindvar type. +func (db *DB) BindNamed(query string, arg interface{}) (string, []interface{}, error) { + return bindNamedMapper(BindType(db.driverName), query, arg, db.Mapper) +} + +// NamedQuery using this DB. +// Any named placeholder parameters are replaced with fields from arg. +func (db *DB) NamedQuery(query string, arg interface{}) (*Rows, error) { + return NamedQuery(db, query, arg) +} + +// NamedExec using this DB. +// Any named placeholder parameters are replaced with fields from arg. +func (db *DB) NamedExec(query string, arg interface{}) (sql.Result, error) { + return NamedExec(db, query, arg) +} + +// Select using this DB. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) Select(dest interface{}, query string, args ...interface{}) error { + return Select(db, dest, query, args...) +} + +// Get using this DB. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (db *DB) Get(dest interface{}, query string, args ...interface{}) error { + return Get(db, dest, query, args...) +} + +// MustBegin starts a transaction, and panics on error. Returns an *sqlx.Tx instead +// of an *sql.Tx. +func (db *DB) MustBegin() *Tx { + tx, err := db.Beginx() + if err != nil { + panic(err) + } + return tx +} + +// Beginx begins a transaction and returns an *sqlx.Tx instead of an *sql.Tx. +func (db *DB) Beginx() (*Tx, error) { + tx, err := db.DB.Begin() + if err != nil { + return nil, err + } + return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err +} + +// Queryx queries the database and returns an *sqlx.Rows. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) Queryx(query string, args ...interface{}) (*Rows, error) { + r, err := db.DB.Query(query, args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err +} + +// QueryRowx queries the database and returns an *sqlx.Row. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) QueryRowx(query string, args ...interface{}) *Row { + rows, err := db.DB.Query(query, args...) + return &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper} +} + +// MustExec (panic) runs MustExec using this database. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) MustExec(query string, args ...interface{}) sql.Result { + return MustExec(db, query, args...) +} + +// Preparex returns an sqlx.Stmt instead of a sql.Stmt +func (db *DB) Preparex(query string) (*Stmt, error) { + return Preparex(db, query) +} + +// PrepareNamed returns an sqlx.NamedStmt +func (db *DB) PrepareNamed(query string) (*NamedStmt, error) { + return prepareNamed(db, query) +} + +// Tx is an sqlx wrapper around sql.Tx with extra functionality +type Tx struct { + *sql.Tx + driverName string + unsafe bool + Mapper *reflectx.Mapper +} + +// DriverName returns the driverName used by the DB which began this transaction. +func (tx *Tx) DriverName() string { + return tx.driverName +} + +// Rebind a query within a transaction's bindvar type. +func (tx *Tx) Rebind(query string) string { + return Rebind(BindType(tx.driverName), query) +} + +// Unsafe returns a version of Tx which will silently succeed to scan when +// columns in the SQL result have no fields in the destination struct. +func (tx *Tx) Unsafe() *Tx { + return &Tx{Tx: tx.Tx, driverName: tx.driverName, unsafe: true, Mapper: tx.Mapper} +} + +// BindNamed binds a query within a transaction's bindvar type. +func (tx *Tx) BindNamed(query string, arg interface{}) (string, []interface{}, error) { + return bindNamedMapper(BindType(tx.driverName), query, arg, tx.Mapper) +} + +// NamedQuery within a transaction. +// Any named placeholder parameters are replaced with fields from arg. +func (tx *Tx) NamedQuery(query string, arg interface{}) (*Rows, error) { + return NamedQuery(tx, query, arg) +} + +// NamedExec a named query within a transaction. +// Any named placeholder parameters are replaced with fields from arg. +func (tx *Tx) NamedExec(query string, arg interface{}) (sql.Result, error) { + return NamedExec(tx, query, arg) +} + +// Select within a transaction. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) Select(dest interface{}, query string, args ...interface{}) error { + return Select(tx, dest, query, args...) +} + +// Queryx within a transaction. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) Queryx(query string, args ...interface{}) (*Rows, error) { + r, err := tx.Tx.Query(query, args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err +} + +// QueryRowx within a transaction. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) QueryRowx(query string, args ...interface{}) *Row { + rows, err := tx.Tx.Query(query, args...) + return &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper} +} + +// Get within a transaction. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (tx *Tx) Get(dest interface{}, query string, args ...interface{}) error { + return Get(tx, dest, query, args...) +} + +// MustExec runs MustExec within a transaction. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) MustExec(query string, args ...interface{}) sql.Result { + return MustExec(tx, query, args...) +} + +// Preparex a statement within a transaction. +func (tx *Tx) Preparex(query string) (*Stmt, error) { + return Preparex(tx, query) +} + +// Stmtx returns a version of the prepared statement which runs within a transaction. Provided +// stmt can be either *sql.Stmt or *sqlx.Stmt. +func (tx *Tx) Stmtx(stmt interface{}) *Stmt { + var s *sql.Stmt + switch v := stmt.(type) { + case Stmt: + s = v.Stmt + case *Stmt: + s = v.Stmt + case *sql.Stmt: + s = v + default: + panic(fmt.Sprintf("non-statement type %v passed to Stmtx", reflect.ValueOf(stmt).Type())) + } + return &Stmt{Stmt: tx.Stmt(s), Mapper: tx.Mapper} +} + +// NamedStmt returns a version of the prepared statement which runs within a transaction. +func (tx *Tx) NamedStmt(stmt *NamedStmt) *NamedStmt { + return &NamedStmt{ + QueryString: stmt.QueryString, + Params: stmt.Params, + Stmt: tx.Stmtx(stmt.Stmt), + } +} + +// PrepareNamed returns an sqlx.NamedStmt +func (tx *Tx) PrepareNamed(query string) (*NamedStmt, error) { + return prepareNamed(tx, query) +} + +// Stmt is an sqlx wrapper around sql.Stmt with extra functionality +type Stmt struct { + *sql.Stmt + unsafe bool + Mapper *reflectx.Mapper +} + +// Unsafe returns a version of Stmt which will silently succeed to scan when +// columns in the SQL result have no fields in the destination struct. +func (s *Stmt) Unsafe() *Stmt { + return &Stmt{Stmt: s.Stmt, unsafe: true, Mapper: s.Mapper} +} + +// Select using the prepared statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) Select(dest interface{}, args ...interface{}) error { + return Select(&qStmt{s}, dest, "", args...) +} + +// Get using the prepared statement. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (s *Stmt) Get(dest interface{}, args ...interface{}) error { + return Get(&qStmt{s}, dest, "", args...) +} + +// MustExec (panic) using this statement. Note that the query portion of the error +// output will be blank, as Stmt does not expose its query. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) MustExec(args ...interface{}) sql.Result { + return MustExec(&qStmt{s}, "", args...) +} + +// QueryRowx using this statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) QueryRowx(args ...interface{}) *Row { + qs := &qStmt{s} + return qs.QueryRowx("", args...) +} + +// Queryx using this statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) Queryx(args ...interface{}) (*Rows, error) { + qs := &qStmt{s} + return qs.Queryx("", args...) +} + +// qStmt is an unexposed wrapper which lets you use a Stmt as a Queryer & Execer by +// implementing those interfaces and ignoring the `query` argument. +type qStmt struct{ *Stmt } + +func (q *qStmt) Query(query string, args ...interface{}) (*sql.Rows, error) { + return q.Stmt.Query(args...) +} + +func (q *qStmt) Queryx(query string, args ...interface{}) (*Rows, error) { + r, err := q.Stmt.Query(args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err +} + +func (q *qStmt) QueryRowx(query string, args ...interface{}) *Row { + rows, err := q.Stmt.Query(args...) + return &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper} +} + +func (q *qStmt) Exec(query string, args ...interface{}) (sql.Result, error) { + return q.Stmt.Exec(args...) +} + +// Rows is a wrapper around sql.Rows which caches costly reflect operations +// during a looped StructScan +type Rows struct { + *sql.Rows + unsafe bool + Mapper *reflectx.Mapper + // these fields cache memory use for a rows during iteration w/ structScan + started bool + fields [][]int + values []interface{} +} + +// SliceScan using this Rows. +func (r *Rows) SliceScan() ([]interface{}, error) { + return SliceScan(r) +} + +// MapScan using this Rows. +func (r *Rows) MapScan(dest map[string]interface{}) error { + return MapScan(r, dest) +} + +// StructScan is like sql.Rows.Scan, but scans a single Row into a single Struct. +// Use this and iterate over Rows manually when the memory load of Select() might be +// prohibitive. *Rows.StructScan caches the reflect work of matching up column +// positions to fields to avoid that overhead per scan, which means it is not safe +// to run StructScan on the same Rows instance with different struct types. +func (r *Rows) StructScan(dest interface{}) error { + v := reflect.ValueOf(dest) + + if v.Kind() != reflect.Ptr { + return errors.New("must pass a pointer, not a value, to StructScan destination") + } + + v = v.Elem() + + if !r.started { + columns, err := r.Columns() + if err != nil { + return err + } + m := r.Mapper + + r.fields = m.TraversalsByName(v.Type(), columns) + // if we are not unsafe and are missing fields, return an error + if f, err := missingFields(r.fields); err != nil && !r.unsafe { + return fmt.Errorf("missing destination name %s in %T", columns[f], dest) + } + r.values = make([]interface{}, len(columns)) + r.started = true + } + + err := fieldsByTraversal(v, r.fields, r.values, true) + if err != nil { + return err + } + // scan into the struct field pointers and append to our results + err = r.Scan(r.values...) + if err != nil { + return err + } + return r.Err() +} + +// Connect to a database and verify with a ping. +func Connect(driverName, dataSourceName string) (*DB, error) { + db, err := Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + err = db.Ping() + if err != nil { + db.Close() + return nil, err + } + return db, nil +} + +// MustConnect connects to a database and panics on error. +func MustConnect(driverName, dataSourceName string) *DB { + db, err := Connect(driverName, dataSourceName) + if err != nil { + panic(err) + } + return db +} + +// Preparex prepares a statement. +func Preparex(p Preparer, query string) (*Stmt, error) { + s, err := p.Prepare(query) + if err != nil { + return nil, err + } + return &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err +} + +// Select executes a query using the provided Queryer, and StructScans each row +// into dest, which must be a slice. If the slice elements are scannable, then +// the result set must have only one column. Otherwise, StructScan is used. +// The *sql.Rows are closed automatically. +// Any placeholder parameters are replaced with supplied args. +func Select(q Queryer, dest interface{}, query string, args ...interface{}) error { + rows, err := q.Queryx(query, args...) + if err != nil { + return err + } + // if something happens here, we want to make sure the rows are Closed + defer rows.Close() + return scanAll(rows, dest, false) +} + +// Get does a QueryRow using the provided Queryer, and scans the resulting row +// to dest. If dest is scannable, the result must only have one column. Otherwise, +// StructScan is used. Get will return sql.ErrNoRows like row.Scan would. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func Get(q Queryer, dest interface{}, query string, args ...interface{}) error { + r := q.QueryRowx(query, args...) + return r.scanAny(dest, false) +} + +// LoadFile exec's every statement in a file (as a single call to Exec). +// LoadFile may return a nil *sql.Result if errors are encountered locating or +// reading the file at path. LoadFile reads the entire file into memory, so it +// is not suitable for loading large data dumps, but can be useful for initializing +// schemas or loading indexes. +// +// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3 +// or the go-mysql-driver/mysql drivers; pq seems to be an exception here. Detecting +// this by requiring something with DriverName() and then attempting to split the +// queries will be difficult to get right, and its current driver-specific behavior +// is deemed at least not complex in its incorrectness. +func LoadFile(e Execer, path string) (*sql.Result, error) { + realpath, err := filepath.Abs(path) + if err != nil { + return nil, err + } + contents, err := ioutil.ReadFile(realpath) + if err != nil { + return nil, err + } + res, err := e.Exec(string(contents)) + return &res, err +} + +// MustExec execs the query using e and panics if there was an error. +// Any placeholder parameters are replaced with supplied args. +func MustExec(e Execer, query string, args ...interface{}) sql.Result { + res, err := e.Exec(query, args...) + if err != nil { + panic(err) + } + return res +} + +// SliceScan using this Rows. +func (r *Row) SliceScan() ([]interface{}, error) { + return SliceScan(r) +} + +// MapScan using this Rows. +func (r *Row) MapScan(dest map[string]interface{}) error { + return MapScan(r, dest) +} + +func (r *Row) scanAny(dest interface{}, structOnly bool) error { + if r.err != nil { + return r.err + } + if r.rows == nil { + r.err = sql.ErrNoRows + return r.err + } + defer r.rows.Close() + + v := reflect.ValueOf(dest) + if v.Kind() != reflect.Ptr { + return errors.New("must pass a pointer, not a value, to StructScan destination") + } + if v.IsNil() { + return errors.New("nil pointer passed to StructScan destination") + } + + base := reflectx.Deref(v.Type()) + scannable := isScannable(base) + + if structOnly && scannable { + return structOnlyError(base) + } + + columns, err := r.Columns() + if err != nil { + return err + } + + if scannable && len(columns) > 1 { + return fmt.Errorf("scannable dest type %s with >1 columns (%d) in result", base.Kind(), len(columns)) + } + + if scannable { + return r.Scan(dest) + } + + m := r.Mapper + + fields := m.TraversalsByName(v.Type(), columns) + // if we are not unsafe and are missing fields, return an error + if f, err := missingFields(fields); err != nil && !r.unsafe { + return fmt.Errorf("missing destination name %s in %T", columns[f], dest) + } + values := make([]interface{}, len(columns)) + + err = fieldsByTraversal(v, fields, values, true) + if err != nil { + return err + } + // scan into the struct field pointers and append to our results + return r.Scan(values...) +} + +// StructScan a single Row into dest. +func (r *Row) StructScan(dest interface{}) error { + return r.scanAny(dest, true) +} + +// SliceScan a row, returning a []interface{} with values similar to MapScan. +// This function is primarily intended for use where the number of columns +// is not known. Because you can pass an []interface{} directly to Scan, +// it's recommended that you do that as it will not have to allocate new +// slices per row. +func SliceScan(r ColScanner) ([]interface{}, error) { + // ignore r.started, since we needn't use reflect for anything. + columns, err := r.Columns() + if err != nil { + return []interface{}{}, err + } + + values := make([]interface{}, len(columns)) + for i := range values { + values[i] = new(interface{}) + } + + err = r.Scan(values...) + + if err != nil { + return values, err + } + + for i := range columns { + values[i] = *(values[i].(*interface{})) + } + + return values, r.Err() +} + +// MapScan scans a single Row into the dest map[string]interface{}. +// Use this to get results for SQL that might not be under your control +// (for instance, if you're building an interface for an SQL server that +// executes SQL from input). Please do not use this as a primary interface! +// This will modify the map sent to it in place, so reuse the same map with +// care. Columns which occur more than once in the result will overwrite +// each other! +func MapScan(r ColScanner, dest map[string]interface{}) error { + // ignore r.started, since we needn't use reflect for anything. + columns, err := r.Columns() + if err != nil { + return err + } + + values := make([]interface{}, len(columns)) + for i := range values { + values[i] = new(interface{}) + } + + err = r.Scan(values...) + if err != nil { + return err + } + + for i, column := range columns { + dest[column] = *(values[i].(*interface{})) + } + + return r.Err() +} + +type rowsi interface { + Close() error + Columns() ([]string, error) + Err() error + Next() bool + Scan(...interface{}) error +} + +// structOnlyError returns an error appropriate for type when a non-scannable +// struct is expected but something else is given +func structOnlyError(t reflect.Type) error { + isStruct := t.Kind() == reflect.Struct + isScanner := reflect.PtrTo(t).Implements(_scannerInterface) + if !isStruct { + return fmt.Errorf("expected %s but got %s", reflect.Struct, t.Kind()) + } + if isScanner { + return fmt.Errorf("structscan expects a struct dest but the provided struct type %s implements scanner", t.Name()) + } + return fmt.Errorf("expected a struct, but struct %s has no exported fields", t.Name()) +} + +// scanAll scans all rows into a destination, which must be a slice of any +// type. If the destination slice type is a Struct, then StructScan will be +// used on each row. If the destination is some other kind of base type, then +// each row must only have one column which can scan into that type. This +// allows you to do something like: +// +// rows, _ := db.Query("select id from people;") +// var ids []int +// scanAll(rows, &ids, false) +// +// and ids will be a list of the id results. I realize that this is a desirable +// interface to expose to users, but for now it will only be exposed via changes +// to `Get` and `Select`. The reason that this has been implemented like this is +// this is the only way to not duplicate reflect work in the new API while +// maintaining backwards compatibility. +func scanAll(rows rowsi, dest interface{}, structOnly bool) error { + var v, vp reflect.Value + + value := reflect.ValueOf(dest) + + // json.Unmarshal returns errors for these + if value.Kind() != reflect.Ptr { + return errors.New("must pass a pointer, not a value, to StructScan destination") + } + if value.IsNil() { + return errors.New("nil pointer passed to StructScan destination") + } + direct := reflect.Indirect(value) + + slice, err := baseType(value.Type(), reflect.Slice) + if err != nil { + return err + } + + isPtr := slice.Elem().Kind() == reflect.Ptr + base := reflectx.Deref(slice.Elem()) + scannable := isScannable(base) + + if structOnly && scannable { + return structOnlyError(base) + } + + columns, err := rows.Columns() + if err != nil { + return err + } + + // if it's a base type make sure it only has 1 column; if not return an error + if scannable && len(columns) > 1 { + return fmt.Errorf("non-struct dest type %s with >1 columns (%d)", base.Kind(), len(columns)) + } + + if !scannable { + var values []interface{} + var m *reflectx.Mapper + + switch rows.(type) { + case *Rows: + m = rows.(*Rows).Mapper + default: + m = mapper() + } + + fields := m.TraversalsByName(base, columns) + // if we are not unsafe and are missing fields, return an error + if f, err := missingFields(fields); err != nil && !isUnsafe(rows) { + return fmt.Errorf("missing destination name %s in %T", columns[f], dest) + } + values = make([]interface{}, len(columns)) + + for rows.Next() { + // create a new struct type (which returns PtrTo) and indirect it + vp = reflect.New(base) + v = reflect.Indirect(vp) + + err = fieldsByTraversal(v, fields, values, true) + if err != nil { + return err + } + + // scan into the struct field pointers and append to our results + err = rows.Scan(values...) + if err != nil { + return err + } + + if isPtr { + direct.Set(reflect.Append(direct, vp)) + } else { + direct.Set(reflect.Append(direct, v)) + } + } + } else { + for rows.Next() { + vp = reflect.New(base) + err = rows.Scan(vp.Interface()) + if err != nil { + return err + } + // append + if isPtr { + direct.Set(reflect.Append(direct, vp)) + } else { + direct.Set(reflect.Append(direct, reflect.Indirect(vp))) + } + } + } + + return rows.Err() +} + +// FIXME: StructScan was the very first bit of API in sqlx, and now unfortunately +// it doesn't really feel like it's named properly. There is an incongruency +// between this and the way that StructScan (which might better be ScanStruct +// anyway) works on a rows object. + +// StructScan all rows from an sql.Rows or an sqlx.Rows into the dest slice. +// StructScan will scan in the entire rows result, so if you do not want to +// allocate structs for the entire result, use Queryx and see sqlx.Rows.StructScan. +// If rows is sqlx.Rows, it will use its mapper, otherwise it will use the default. +func StructScan(rows rowsi, dest interface{}) error { + return scanAll(rows, dest, true) + +} + +// reflect helpers + +func baseType(t reflect.Type, expected reflect.Kind) (reflect.Type, error) { + t = reflectx.Deref(t) + if t.Kind() != expected { + return nil, fmt.Errorf("expected %s but got %s", expected, t.Kind()) + } + return t, nil +} + +// fieldsByName fills a values interface with fields from the passed value based +// on the traversals in int. If ptrs is true, return addresses instead of values. +// We write this instead of using FieldsByName to save allocations and map lookups +// when iterating over many rows. Empty traversals will get an interface pointer. +// Because of the necessity of requesting ptrs or values, it's considered a bit too +// specialized for inclusion in reflectx itself. +func fieldsByTraversal(v reflect.Value, traversals [][]int, values []interface{}, ptrs bool) error { + v = reflect.Indirect(v) + if v.Kind() != reflect.Struct { + return errors.New("argument not a struct") + } + + for i, traversal := range traversals { + if len(traversal) == 0 { + values[i] = new(interface{}) + continue + } + f := reflectx.FieldByIndexes(v, traversal) + if ptrs { + values[i] = f.Addr().Interface() + } else { + values[i] = f.Interface() + } + } + return nil +} + +func missingFields(transversals [][]int) (field int, err error) { + for i, t := range transversals { + if len(t) == 0 { + return i, errors.New("missing field") + } + } + return 0, nil +} diff --git a/vendor/github.com/jmoiron/sqlx/sqlx_context.go b/vendor/github.com/jmoiron/sqlx/sqlx_context.go new file mode 100644 index 00000000..06033111 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/sqlx_context.go @@ -0,0 +1,346 @@ +// +build go1.8 + +package sqlx + +import ( + "context" + "database/sql" + "fmt" + "io/ioutil" + "path/filepath" + "reflect" +) + +// ConnectContext to a database and verify with a ping. +func ConnectContext(ctx context.Context, driverName, dataSourceName string) (*DB, error) { + db, err := Open(driverName, dataSourceName) + if err != nil { + return db, err + } + err = db.PingContext(ctx) + return db, err +} + +// QueryerContext is an interface used by GetContext and SelectContext +type QueryerContext interface { + QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) + QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row +} + +// PreparerContext is an interface used by PreparexContext. +type PreparerContext interface { + PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) +} + +// ExecerContext is an interface used by MustExecContext and LoadFileContext +type ExecerContext interface { + ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) +} + +// ExtContext is a union interface which can bind, query, and exec, with Context +// used by NamedQueryContext and NamedExecContext. +type ExtContext interface { + binder + QueryerContext + ExecerContext +} + +// SelectContext executes a query using the provided Queryer, and StructScans +// each row into dest, which must be a slice. If the slice elements are +// scannable, then the result set must have only one column. Otherwise, +// StructScan is used. The *sql.Rows are closed automatically. +// Any placeholder parameters are replaced with supplied args. +func SelectContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error { + rows, err := q.QueryxContext(ctx, query, args...) + if err != nil { + return err + } + // if something happens here, we want to make sure the rows are Closed + defer rows.Close() + return scanAll(rows, dest, false) +} + +// PreparexContext prepares a statement. +// +// The provided context is used for the preparation of the statement, not for +// the execution of the statement. +func PreparexContext(ctx context.Context, p PreparerContext, query string) (*Stmt, error) { + s, err := p.PrepareContext(ctx, query) + if err != nil { + return nil, err + } + return &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err +} + +// GetContext does a QueryRow using the provided Queryer, and scans the +// resulting row to dest. If dest is scannable, the result must only have one +// column. Otherwise, StructScan is used. Get will return sql.ErrNoRows like +// row.Scan would. Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func GetContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error { + r := q.QueryRowxContext(ctx, query, args...) + return r.scanAny(dest, false) +} + +// LoadFileContext exec's every statement in a file (as a single call to Exec). +// LoadFileContext may return a nil *sql.Result if errors are encountered +// locating or reading the file at path. LoadFile reads the entire file into +// memory, so it is not suitable for loading large data dumps, but can be useful +// for initializing schemas or loading indexes. +// +// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3 +// or the go-mysql-driver/mysql drivers; pq seems to be an exception here. Detecting +// this by requiring something with DriverName() and then attempting to split the +// queries will be difficult to get right, and its current driver-specific behavior +// is deemed at least not complex in its incorrectness. +func LoadFileContext(ctx context.Context, e ExecerContext, path string) (*sql.Result, error) { + realpath, err := filepath.Abs(path) + if err != nil { + return nil, err + } + contents, err := ioutil.ReadFile(realpath) + if err != nil { + return nil, err + } + res, err := e.ExecContext(ctx, string(contents)) + return &res, err +} + +// MustExecContext execs the query using e and panics if there was an error. +// Any placeholder parameters are replaced with supplied args. +func MustExecContext(ctx context.Context, e ExecerContext, query string, args ...interface{}) sql.Result { + res, err := e.ExecContext(ctx, query, args...) + if err != nil { + panic(err) + } + return res +} + +// PrepareNamedContext returns an sqlx.NamedStmt +func (db *DB) PrepareNamedContext(ctx context.Context, query string) (*NamedStmt, error) { + return prepareNamedContext(ctx, db, query) +} + +// NamedQueryContext using this DB. +// Any named placeholder parameters are replaced with fields from arg. +func (db *DB) NamedQueryContext(ctx context.Context, query string, arg interface{}) (*Rows, error) { + return NamedQueryContext(ctx, db, query, arg) +} + +// NamedExecContext using this DB. +// Any named placeholder parameters are replaced with fields from arg. +func (db *DB) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) { + return NamedExecContext(ctx, db, query, arg) +} + +// SelectContext using this DB. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return SelectContext(ctx, db, dest, query, args...) +} + +// GetContext using this DB. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (db *DB) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return GetContext(ctx, db, dest, query, args...) +} + +// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt. +// +// The provided context is used for the preparation of the statement, not for +// the execution of the statement. +func (db *DB) PreparexContext(ctx context.Context, query string) (*Stmt, error) { + return PreparexContext(ctx, db, query) +} + +// QueryxContext queries the database and returns an *sqlx.Rows. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { + r, err := db.DB.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err +} + +// QueryRowxContext queries the database and returns an *sqlx.Row. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row { + rows, err := db.DB.QueryContext(ctx, query, args...) + return &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper} +} + +// MustBeginTx starts a transaction, and panics on error. Returns an *sqlx.Tx instead +// of an *sql.Tx. +// +// The provided context is used until the transaction is committed or rolled +// back. If the context is canceled, the sql package will roll back the +// transaction. Tx.Commit will return an error if the context provided to +// MustBeginContext is canceled. +func (db *DB) MustBeginTx(ctx context.Context, opts *sql.TxOptions) *Tx { + tx, err := db.BeginTxx(ctx, opts) + if err != nil { + panic(err) + } + return tx +} + +// MustExecContext (panic) runs MustExec using this database. +// Any placeholder parameters are replaced with supplied args. +func (db *DB) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result { + return MustExecContext(ctx, db, query, args...) +} + +// BeginTxx begins a transaction and returns an *sqlx.Tx instead of an +// *sql.Tx. +// +// The provided context is used until the transaction is committed or rolled +// back. If the context is canceled, the sql package will roll back the +// transaction. Tx.Commit will return an error if the context provided to +// BeginxContext is canceled. +func (db *DB) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { + tx, err := db.DB.BeginTx(ctx, opts) + if err != nil { + return nil, err + } + return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err +} + +// StmtxContext returns a version of the prepared statement which runs within a +// transaction. Provided stmt can be either *sql.Stmt or *sqlx.Stmt. +func (tx *Tx) StmtxContext(ctx context.Context, stmt interface{}) *Stmt { + var s *sql.Stmt + switch v := stmt.(type) { + case Stmt: + s = v.Stmt + case *Stmt: + s = v.Stmt + case *sql.Stmt: + s = v + default: + panic(fmt.Sprintf("non-statement type %v passed to Stmtx", reflect.ValueOf(stmt).Type())) + } + return &Stmt{Stmt: tx.StmtContext(ctx, s), Mapper: tx.Mapper} +} + +// NamedStmtContext returns a version of the prepared statement which runs +// within a transaction. +func (tx *Tx) NamedStmtContext(ctx context.Context, stmt *NamedStmt) *NamedStmt { + return &NamedStmt{ + QueryString: stmt.QueryString, + Params: stmt.Params, + Stmt: tx.StmtxContext(ctx, stmt.Stmt), + } +} + +// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt. +// +// The provided context is used for the preparation of the statement, not for +// the execution of the statement. +func (tx *Tx) PreparexContext(ctx context.Context, query string) (*Stmt, error) { + return PreparexContext(ctx, tx, query) +} + +// PrepareNamedContext returns an sqlx.NamedStmt +func (tx *Tx) PrepareNamedContext(ctx context.Context, query string) (*NamedStmt, error) { + return prepareNamedContext(ctx, tx, query) +} + +// MustExecContext runs MustExecContext within a transaction. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result { + return MustExecContext(ctx, tx, query, args...) +} + +// QueryxContext within a transaction and context. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { + r, err := tx.Tx.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err +} + +// SelectContext within a transaction and context. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return SelectContext(ctx, tx, dest, query, args...) +} + +// GetContext within a transaction and context. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (tx *Tx) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return GetContext(ctx, tx, dest, query, args...) +} + +// QueryRowxContext within a transaction and context. +// Any placeholder parameters are replaced with supplied args. +func (tx *Tx) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row { + rows, err := tx.Tx.QueryContext(ctx, query, args...) + return &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper} +} + +// NamedExecContext using this Tx. +// Any named placeholder parameters are replaced with fields from arg. +func (tx *Tx) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) { + return NamedExecContext(ctx, tx, query, arg) +} + +// SelectContext using the prepared statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error { + return SelectContext(ctx, &qStmt{s}, dest, "", args...) +} + +// GetContext using the prepared statement. +// Any placeholder parameters are replaced with supplied args. +// An error is returned if the result set is empty. +func (s *Stmt) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error { + return GetContext(ctx, &qStmt{s}, dest, "", args...) +} + +// MustExecContext (panic) using this statement. Note that the query portion of +// the error output will be blank, as Stmt does not expose its query. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) MustExecContext(ctx context.Context, args ...interface{}) sql.Result { + return MustExecContext(ctx, &qStmt{s}, "", args...) +} + +// QueryRowxContext using this statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) QueryRowxContext(ctx context.Context, args ...interface{}) *Row { + qs := &qStmt{s} + return qs.QueryRowxContext(ctx, "", args...) +} + +// QueryxContext using this statement. +// Any placeholder parameters are replaced with supplied args. +func (s *Stmt) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) { + qs := &qStmt{s} + return qs.QueryxContext(ctx, "", args...) +} + +func (q *qStmt) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { + return q.Stmt.QueryContext(ctx, args...) +} + +func (q *qStmt) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { + r, err := q.Stmt.QueryContext(ctx, args...) + if err != nil { + return nil, err + } + return &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err +} + +func (q *qStmt) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row { + rows, err := q.Stmt.QueryContext(ctx, args...) + return &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper} +} + +func (q *qStmt) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { + return q.Stmt.ExecContext(ctx, args...) +} diff --git a/vendor/github.com/karalabe/usb/.travis.yml b/vendor/github.com/karalabe/usb/.travis.yml new file mode 100644 index 00000000..de0337b2 --- /dev/null +++ b/vendor/github.com/karalabe/usb/.travis.yml @@ -0,0 +1,49 @@ +language: go + +matrix: + include: + - os: linux + dist: trusty + go: 1.5.x + - os: linux + dist: trusty + go: 1.6.x + - os: linux + dist: trusty + go: 1.7.x + - os: linux + dist: trusty + go: 1.8.x + - os: linux + dist: trusty + go: 1.9.x + - os: linux + dist: xenial + go: 1.9.x + - os: linux + dist: xenial + go: 1.10.x + - os: linux + dist: xenial + go: 1.11.x + - os: linux + dist: xenial + go: 1.12.x + - os: osx + go: 1.12.x + - os: linux + dist: xenial + go: 1.12.x + services: + - docker + env: + - docker + script: + - docker build -f Dockerfile.ubuntu . + - docker build -f Dockerfile.alpine . + +script: + - go install ./... + - go test -v ./... + - CGO_ENABLED=0 go install ./... + - CGO_ENABLED=0 go test -v ./... diff --git a/vendor/github.com/karalabe/usb/AUTHORS b/vendor/github.com/karalabe/usb/AUTHORS new file mode 100644 index 00000000..bae45b3e --- /dev/null +++ b/vendor/github.com/karalabe/usb/AUTHORS @@ -0,0 +1,7 @@ +Felix Lange +Guillaume Ballet +Jakob Weisblat +Martin Holst Swende +Mateusz Mikołajczyk +Péter Szilágyi +Rosen Penev diff --git a/vendor/github.com/karalabe/usb/Dockerfile.alpine b/vendor/github.com/karalabe/usb/Dockerfile.alpine new file mode 100644 index 00000000..342bdf79 --- /dev/null +++ b/vendor/github.com/karalabe/usb/Dockerfile.alpine @@ -0,0 +1,6 @@ +FROM golang:alpine + +RUN apk add --no-cache git gcc musl-dev linux-headers + +ADD . $GOPATH/src/github.com/karalabe/usb +RUN cd $GOPATH/src/github.com/karalabe/usb && go install diff --git a/vendor/github.com/karalabe/usb/Dockerfile.ubuntu b/vendor/github.com/karalabe/usb/Dockerfile.ubuntu new file mode 100644 index 00000000..b861e497 --- /dev/null +++ b/vendor/github.com/karalabe/usb/Dockerfile.ubuntu @@ -0,0 +1,4 @@ +FROM golang:latest + +ADD . $GOPATH/src/github.com/karalabe/usb +RUN cd $GOPATH/src/github.com/karalabe/usb && go install diff --git a/vendor/github.com/karalabe/usb/LICENSE b/vendor/github.com/karalabe/usb/LICENSE new file mode 100644 index 00000000..65c5ca88 --- /dev/null +++ b/vendor/github.com/karalabe/usb/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/github.com/karalabe/usb/README.md b/vendor/github.com/karalabe/usb/README.md new file mode 100644 index 00000000..b6920f51 --- /dev/null +++ b/vendor/github.com/karalabe/usb/README.md @@ -0,0 +1,47 @@ +[![Travis][travisimg]][travisurl] +[![AppVeyor][appveyorimg]][appveyorurl] +[![GoDoc][docimg]][docurl] + +[travisimg]: https://travis-ci.org/karalabe/usb.svg?branch=master +[travisurl]: https://travis-ci.org/karalabe/usb +[appveyorimg]: https://ci.appveyor.com/api/projects/status/u96eq262bj2itprh/branch/master?svg=true +[appveyorurl]: https://ci.appveyor.com/project/karalabe/usb +[docimg]: https://godoc.org/github.com/karalabe/usb?status.svg +[docurl]: https://godoc.org/github.com/karalabe/usb + +# Yet another USB library for Go + +The `usb` package is a cross platform, fully self-contained library for accessing and communicating with USB devices **either via HID or low level interrupts**. The goal of the library was to create a simple way to find-, attach to- and read/write form USB devices. + +There are multiple already existing USB libraries: + + * The original `gousb` package [created by @kylelemons](https://github.com/kylelemons/gousb) and nowadays [maintained by @google](https://github.com/google/gousb) is a CGO wrapper around `libusb`. It is the most advanced USB library for Go out there. + * Unfortunately, `gousb` requires the `libusb` C library to be installed both during build as well as during runtime on the host operating system. This breaks binary portability and also adds unnecessary hurdles on Windows. + * Furthermore, whilst HID devices are supported by `libusb`, the OS on Macos and Windows explicitly takes over these devices, so only native system calls can be used on recent versions (i.e. you **cannot** use `libusb` for HID). + * There is a fork of `gousb` [created by @karalabe](https://github.com/karalabe/gousb) that statically linked `libusb` during build, but with the lack of HID access, that work was abandoned. + * For HID-only devices, a previous self-contained package was created at [`github.com/karalabe/hid`](https://github.com/karalabe/hid), which worked well for hardware wallet uses cases in [`go-ethereum`](https://github.com/ethereum/go-ethereum). It's a simple package that does it's thing well. + * Unfortunately, `hid` is not capable of talking to generic USB devices. When multiple different devices are needed, eventually some will not support the HID spec (e.g. WebUSB). Pulling in both `hid` and `gousb` will break down due to both depending internally on different versions of `libusb` on Linux. + +This `usb` package is a proper integration of `hidapi` and `libusb` so that communication with HID devices is done via system calls, whereas communication with lower level USB devices is done via interrupts. All this detail is hidden away behind a tiny interface. + +The package supports Linux, macOS, Windows and FreeBSD. Exclude constraints are also specified for Android and iOS to allow smoother vendoring into cross platform projects. + +## Cross-compiling + +Using `go get`, the embedded C library is compiled into the binary format of your host OS. Cross compiling to a different platform or architecture entails disabling CGO by default in Go, causing device enumeration `hid.Enumerate()` to yield no results. + +To cross compile a functional version of this library, you'll need to enable CGO during cross compilation via `CGO_ENABLED=1` and you'll need to install and set a cross compilation enabled C toolkit via `CC=your-cross-gcc`. + +## Acknowledgements + +Although the `usb` package is an implementation from scratch, HID support was heavily inspired by the existing [`go.hid`](https://github.com/GeertJohan/go.hid) library, which seems abandoned since 2015; is incompatible with Go 1.6+; and has various external dependencies. + +Wide character support in the HID support is done via the [`gowchar`](https://github.com/orofarne/gowchar) library, unmaintained since 2013; non buildable with a modern Go release and failing `go vet` checks. As such, `gowchar` was also vendored in inline. + +Error handling for the `libusb` integration originates from the [`gousb`](https://github.com/google/gousb) library. + +## License + +This USB library is licensed under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html) (dictated by libusb). + +If you are only interested in Human Interface devices, a less restrictive package can be found at [`github.com/karalabe/hid`](https://github.com/karalabe/hid). diff --git a/vendor/github.com/karalabe/usb/appveyor.yml b/vendor/github.com/karalabe/usb/appveyor.yml new file mode 100644 index 00000000..1d921ae5 --- /dev/null +++ b/vendor/github.com/karalabe/usb/appveyor.yml @@ -0,0 +1,35 @@ +os: Visual Studio 2015 + +# Clone directly into GOPATH. +clone_folder: C:\gopath\src\github.com\karalabe\usb +clone_depth: 1 +version: "{branch}.{build}" +environment: + global: + GOPATH: C:\gopath + CC: gcc.exe + matrix: + - GOARCH: amd64 + MSYS2_ARCH: x86_64 + MSYS2_BITS: 64 + MSYSTEM: MINGW64 + PATH: C:\msys64\mingw64\bin\;%PATH% + - GOARCH: 386 + MSYS2_ARCH: i686 + MSYS2_BITS: 32 + MSYSTEM: MINGW32 + PATH: C:\msys64\mingw32\bin\;%PATH% + +install: + - rmdir C:\go /s /q + - appveyor DownloadFile https://storage.googleapis.com/golang/go1.12.6.windows-%GOARCH%.zip + - 7z x go1.12.6.windows-%GOARCH%.zip -y -oC:\ > NUL + - go version + - gcc --version + +build_script: + - go install ./... + - go test -v ./... + - set CGO_ENABLED=0 + - go install ./... + - go test -v ./... diff --git a/vendor/github.com/karalabe/usb/demo.go b/vendor/github.com/karalabe/usb/demo.go new file mode 100644 index 00000000..229faaf5 --- /dev/null +++ b/vendor/github.com/karalabe/usb/demo.go @@ -0,0 +1,76 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build none + +package main + +import ( + "fmt" + "strings" + + "github.com/karalabe/usb" +) + +func main() { + // Enumerate all the HID devices in alphabetical path order + hids, err := usb.EnumerateHid(0, 0) + if err != nil { + panic(err) + } + for i := 0; i < len(hids); i++ { + for j := i + 1; j < len(hids); j++ { + if hids[i].Path > hids[j].Path { + hids[i], hids[j] = hids[j], hids[i] + } + } + } + for i, hid := range hids { + fmt.Println(strings.Repeat("-", 128)) + fmt.Printf("HID #%d\n", i) + fmt.Printf(" OS Path: %s\n", hid.Path) + fmt.Printf(" Vendor ID: %#04x\n", hid.VendorID) + fmt.Printf(" Product ID: %#04x\n", hid.ProductID) + fmt.Printf(" Release: %d\n", hid.Release) + fmt.Printf(" Serial: %s\n", hid.Serial) + fmt.Printf(" Manufacturer: %s\n", hid.Manufacturer) + fmt.Printf(" Product: %s\n", hid.Product) + fmt.Printf(" Usage Page: %d\n", hid.UsagePage) + fmt.Printf(" Usage: %d\n", hid.Usage) + fmt.Printf(" Interface: %d\n", hid.Interface) + } + fmt.Println(strings.Repeat("=", 128)) + + // Enumerate all the non-HID devices in alphabetical path order + raws, err := usb.EnumerateRaw(0, 0) + if err != nil { + panic(err) + } + for i := 0; i < len(raws); i++ { + for j := i + 1; j < len(raws); j++ { + if raws[i].Path > raws[j].Path { + raws[i], raws[j] = raws[j], raws[i] + } + } + } + for i, raw := range raws { + fmt.Printf("RAW #%d\n", i) + fmt.Printf(" OS Path: %s\n", raw.Path) + fmt.Printf(" Vendor ID: %#04x\n", raw.VendorID) + fmt.Printf(" Product ID: %#04x\n", raw.ProductID) + fmt.Printf(" Interface: %d\n", raw.Interface) + fmt.Println(strings.Repeat("-", 128)) + } +} diff --git a/vendor/github.com/karalabe/usb/go.mod b/vendor/github.com/karalabe/usb/go.mod new file mode 100644 index 00000000..ef549d28 --- /dev/null +++ b/vendor/github.com/karalabe/usb/go.mod @@ -0,0 +1,3 @@ +module github.com/karalabe/usb + +go 1.12 diff --git a/vendor/github.com/karalabe/usb/hid_disabled.go b/vendor/github.com/karalabe/usb/hid_disabled.go new file mode 100644 index 00000000..a85964bf --- /dev/null +++ b/vendor/github.com/karalabe/usb/hid_disabled.go @@ -0,0 +1,42 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2017 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build !freebsd,!linux,!darwin,!windows ios !cgo + +package usb + +// HidDevice is a live HID USB connected device handle. On platforms that this file +// implements, the type lacks the actual HID device and all methods are noop. +type HidDevice struct { + DeviceInfo // Embed the infos for easier access +} + +// Close releases the HID USB device handle. On platforms that this file implements, +// the method is just a noop. +func (dev *HidDevice) Close() error { + return ErrUnsupportedPlatform +} + +// Write sends an output report to a HID device. On platforms that this file +// implements, the method just returns an error. +func (dev *HidDevice) Write(b []byte) (int, error) { + return 0, ErrUnsupportedPlatform +} + +// Read retrieves an input report from a HID device. On platforms that this file +// implements, the method just returns an error. +func (dev *HidDevice) Read(b []byte) (int, error) { + return 0, ErrUnsupportedPlatform +} diff --git a/vendor/github.com/karalabe/usb/hid_enabled.go b/vendor/github.com/karalabe/usb/hid_enabled.go new file mode 100644 index 00000000..c2b37209 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hid_enabled.go @@ -0,0 +1,187 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2017 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build freebsd,cgo linux,cgo darwin,!ios,cgo windows,cgo + +package usb + +/* +#include +#include "./hidapi/hidapi/hidapi.h" +*/ +import "C" + +import ( + "errors" + "runtime" + "sync" + "unsafe" +) + +// enumerateHid returns a list of all the HID devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all HID devices are returned. +func enumerateHid(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + // Gather all device infos and ensure they are freed before returning + head := C.hid_enumerate(C.ushort(vendorID), C.ushort(productID)) + if head == nil { + return nil, nil + } + defer C.hid_free_enumeration(head) + + // Iterate the list and retrieve the device details + var infos []DeviceInfo + for ; head != nil; head = head.next { + info := DeviceInfo{ + Path: C.GoString(head.path), + VendorID: uint16(head.vendor_id), + ProductID: uint16(head.product_id), + Release: uint16(head.release_number), + UsagePage: uint16(head.usage_page), + Usage: uint16(head.usage), + Interface: int(head.interface_number), + } + if head.serial_number != nil { + info.Serial, _ = wcharTToString(head.serial_number) + } + if head.product_string != nil { + info.Product, _ = wcharTToString(head.product_string) + } + if head.manufacturer_string != nil { + info.Manufacturer, _ = wcharTToString(head.manufacturer_string) + } + infos = append(infos, info) + } + return infos, nil +} + +// openHid connects to an HID device by its path name. +func openHid(info DeviceInfo) (*hidDevice, error) { + path := C.CString(info.Path) + defer C.free(unsafe.Pointer(path)) + + device := C.hid_open_path(path) + if device == nil { + return nil, errors.New("hidapi: failed to open device") + } + return &hidDevice{ + DeviceInfo: info, + device: device, + }, nil +} + +// hidDevice is a live HID USB connected device handle. +type hidDevice struct { + DeviceInfo // Embed the infos for easier access + + device *C.hid_device // Low level HID device to communicate through + lock sync.Mutex +} + +// Close releases the HID USB device handle. +func (dev *hidDevice) Close() error { + dev.lock.Lock() + defer dev.lock.Unlock() + + if dev.device != nil { + C.hid_close(dev.device) + dev.device = nil + } + return nil +} + +// Write sends an output report to a HID device. +// +// Write will send the data on the first OUT endpoint, if one exists. If it does +// not, it will send the data through the Control Endpoint (Endpoint 0). +func (dev *hidDevice) Write(b []byte) (int, error) { + // Abort if nothing to write + if len(b) == 0 { + return 0, nil + } + // Abort if device closed in between + dev.lock.Lock() + device := dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Prepend a HID report ID on Windows, other OSes don't need it + var report []byte + if runtime.GOOS == "windows" { + report = append([]byte{0x00}, b...) + } else { + report = b + } + // Execute the write operation + written := int(C.hid_write(device, (*C.uchar)(&report[0]), C.size_t(len(report)))) + if written == -1 { + // If the write failed, verify if closed or other error + dev.lock.Lock() + device = dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Device not closed, some other error occurred + message := C.hid_error(device) + if message == nil { + return 0, errors.New("hidapi: unknown failure") + } + failure, _ := wcharTToString(message) + return 0, errors.New("hidapi: " + failure) + } + return written, nil +} + +// Read retrieves an input report from a HID device. +func (dev *hidDevice) Read(b []byte) (int, error) { + // Aborth if nothing to read + if len(b) == 0 { + return 0, nil + } + // Abort if device closed in between + dev.lock.Lock() + device := dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Execute the read operation + read := int(C.hid_read(device, (*C.uchar)(&b[0]), C.size_t(len(b)))) + if read == -1 { + // If the read failed, verify if closed or other error + dev.lock.Lock() + device = dev.device + dev.lock.Unlock() + + if device == nil { + return 0, ErrDeviceClosed + } + // Device not closed, some other error occurred + message := C.hid_error(device) + if message == nil { + return 0, errors.New("hidapi: unknown failure") + } + failure, _ := wcharTToString(message) + return 0, errors.New("hidapi: " + failure) + } + return read, nil +} diff --git a/vendor/github.com/karalabe/usb/hidapi/AUTHORS.txt b/vendor/github.com/karalabe/usb/hidapi/AUTHORS.txt new file mode 100644 index 00000000..7acafd78 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/AUTHORS.txt @@ -0,0 +1,16 @@ + +HIDAPI Authors: + +Alan Ott : + Original Author and Maintainer + Linux, Windows, and Mac implementations + +Ludovic Rousseau : + Formatting for Doxygen documentation + Bug fixes + Correctness fixes + + +For a comprehensive list of contributions, see the commit list at github: + http://github.com/signal11/hidapi/commits/master + diff --git a/vendor/github.com/karalabe/usb/hidapi/LICENSE-bsd.txt b/vendor/github.com/karalabe/usb/hidapi/LICENSE-bsd.txt new file mode 100644 index 00000000..538cdf95 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/LICENSE-bsd.txt @@ -0,0 +1,26 @@ +Copyright (c) 2010, Alan Ott, Signal 11 Software +All rights reserved. + +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 Signal 11 Software 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 HOLDER 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. diff --git a/vendor/github.com/karalabe/usb/hidapi/LICENSE-gpl3.txt b/vendor/github.com/karalabe/usb/hidapi/LICENSE-gpl3.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/LICENSE-gpl3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/vendor/github.com/karalabe/usb/hidapi/LICENSE-orig.txt b/vendor/github.com/karalabe/usb/hidapi/LICENSE-orig.txt new file mode 100644 index 00000000..e3f33808 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/LICENSE-orig.txt @@ -0,0 +1,9 @@ + HIDAPI - Multi-Platform library for + communication with HID devices. + + Copyright 2009, Alan Ott, Signal 11 Software. + All Rights Reserved. + + This software may be used by anyone for any reason so + long as the copyright notice in the source files + remains intact. diff --git a/vendor/github.com/karalabe/usb/hidapi/LICENSE.txt b/vendor/github.com/karalabe/usb/hidapi/LICENSE.txt new file mode 100644 index 00000000..e1676d4c --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/LICENSE.txt @@ -0,0 +1,13 @@ +HIDAPI can be used under one of three licenses. + +1. The GNU General Public License, version 3.0, in LICENSE-gpl3.txt +2. A BSD-Style License, in LICENSE-bsd.txt. +3. The more liberal original HIDAPI license. LICENSE-orig.txt + +The license chosen is at the discretion of the user of HIDAPI. For example: +1. An author of GPL software would likely use HIDAPI under the terms of the +GPL. + +2. An author of commercial closed-source software would likely use HIDAPI +under the terms of the BSD-style license or the original HIDAPI license. + diff --git a/vendor/github.com/karalabe/usb/hidapi/README.txt b/vendor/github.com/karalabe/usb/hidapi/README.txt new file mode 100644 index 00000000..f19dae4a --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/README.txt @@ -0,0 +1,339 @@ + HIDAPI library for Windows, Linux, FreeBSD and Mac OS X + ========================================================= + +About +====== + +HIDAPI is a multi-platform library which allows an application to interface +with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and Mac +OS X. HIDAPI can be either built as a shared library (.so or .dll) or +can be embedded directly into a target application by adding a single source +file (per platform) and a single header. + +HIDAPI has four back-ends: + * Windows (using hid.dll) + * Linux/hidraw (using the Kernel's hidraw driver) + * Linux/libusb (using libusb-1.0) + * FreeBSD (using libusb-1.0) + * Mac (using IOHidManager) + +On Linux, either the hidraw or the libusb back-end can be used. There are +tradeoffs, and the functionality supported is slightly different. + +Linux/hidraw (linux/hid.c): +This back-end uses the hidraw interface in the Linux kernel. While this +back-end will support both USB and Bluetooth, it has some limitations on +kernels prior to 2.6.39, including the inability to send or receive feature +reports. In addition, it will only communicate with devices which have +hidraw nodes associated with them. Keyboards, mice, and some other devices +which are blacklisted from having hidraw nodes will not work. Fortunately, +for nearly all the uses of hidraw, this is not a problem. + +Linux/FreeBSD/libusb (libusb/hid.c): +This back-end uses libusb-1.0 to communicate directly to a USB device. This +back-end will of course not work with Bluetooth devices. + +HIDAPI also comes with a Test GUI. The Test GUI is cross-platform and uses +Fox Toolkit (http://www.fox-toolkit.org). It will build on every platform +which HIDAPI supports. Since it relies on a 3rd party library, building it +is optional but recommended because it is so useful when debugging hardware. + +What Does the API Look Like? +============================= +The API provides the the most commonly used HID functions including sending +and receiving of input, output, and feature reports. The sample program, +which communicates with a heavily hacked up version of the Microchip USB +Generic HID sample looks like this (with error checking removed for +simplicity): + +#ifdef WIN32 +#include +#endif +#include +#include +#include "hidapi.h" + +#define MAX_STR 255 + +int main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + wchar_t wstr[MAX_STR]; + hid_device *handle; + int i; + + // Initialize the hidapi library + res = hid_init(); + + // Open the device using the VID, PID, + // and optionally the Serial number. + handle = hid_open(0x4d8, 0x3f, NULL); + + // Read the Manufacturer String + res = hid_get_manufacturer_string(handle, wstr, MAX_STR); + wprintf(L"Manufacturer String: %s\n", wstr); + + // Read the Product String + res = hid_get_product_string(handle, wstr, MAX_STR); + wprintf(L"Product String: %s\n", wstr); + + // Read the Serial Number String + res = hid_get_serial_number_string(handle, wstr, MAX_STR); + wprintf(L"Serial Number String: (%d) %s\n", wstr[0], wstr); + + // Read Indexed String 1 + res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); + wprintf(L"Indexed String 1: %s\n", wstr); + + // Toggle LED (cmd 0x80). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x80; + res = hid_write(handle, buf, 65); + + // Request state (cmd 0x81). The first byte is the report number (0x0). + buf[0] = 0x0; + buf[1] = 0x81; + res = hid_write(handle, buf, 65); + + // Read requested state + res = hid_read(handle, buf, 65); + + // Print out the returned buffer. + for (i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + // Finalize the hidapi library + res = hid_exit(); + + return 0; +} + +If you have your own simple test programs which communicate with standard +hardware development boards (such as those from Microchip, TI, Atmel, +FreeScale and others), please consider sending me something like the above +for inclusion into the HIDAPI source. This will help others who have the +same hardware as you do. + +License +======== +HIDAPI may be used by one of three licenses as outlined in LICENSE.txt. + +Download +========= +HIDAPI can be downloaded from github + git clone git://github.com/signal11/hidapi.git + +Build Instructions +=================== + +This section is long. Don't be put off by this. It's not long because it's +complicated to build HIDAPI; it's quite the opposite. This section is long +because of the flexibility of HIDAPI and the large number of ways in which +it can be built and used. You will likely pick a single build method. + +HIDAPI can be built in several different ways. If you elect to build a +shared library, you will need to build it from the HIDAPI source +distribution. If you choose instead to embed HIDAPI directly into your +application, you can skip the building and look at the provided platform +Makefiles for guidance. These platform Makefiles are located in linux/ +libusb/ mac/ and windows/ and are called Makefile-manual. In addition, +Visual Studio projects are provided. Even if you're going to embed HIDAPI +into your project, it is still beneficial to build the example programs. + + +Prerequisites: +--------------- + + Linux: + ------- + On Linux, you will need to install development packages for libudev, + libusb and optionally Fox-toolkit (for the test GUI). On + Debian/Ubuntu systems these can be installed by running: + sudo apt-get install libudev-dev libusb-1.0-0-dev libfox-1.6-dev + + If you downloaded the source directly from the git repository (using + git clone), you'll need Autotools: + sudo apt-get install autotools-dev autoconf automake libtool + + FreeBSD: + --------- + On FreeBSD you will need to install GNU make, libiconv, and + optionally Fox-Toolkit (for the test GUI). This is done by running + the following: + pkg_add -r gmake libiconv fox16 + + If you downloaded the source directly from the git repository (using + git clone), you'll need Autotools: + pkg_add -r autotools + + Mac: + ----- + On Mac, you will need to install Fox-Toolkit if you wish to build + the Test GUI. There are two ways to do this, and each has a slight + complication. Which method you use depends on your use case. + + If you wish to build the Test GUI just for your own testing on your + own computer, then the easiest method is to install Fox-Toolkit + using ports: + sudo port install fox + + If you wish to build the TestGUI app bundle to redistribute to + others, you will need to install Fox-toolkit from source. This is + because the version of fox that gets installed using ports uses the + ports X11 libraries which are not compatible with the Apple X11 + libraries. If you install Fox with ports and then try to distribute + your built app bundle, it will simply fail to run on other systems. + To install Fox-Toolkit manually, download the source package from + http://www.fox-toolkit.org, extract it, and run the following from + within the extracted source: + ./configure && make && make install + + Windows: + --------- + On Windows, if you want to build the test GUI, you will need to get + the hidapi-externals.zip package from the download site. This + contains pre-built binaries for Fox-toolkit. Extract + hidapi-externals.zip just outside of hidapi, so that + hidapi-externals and hidapi are on the same level, as shown: + + Parent_Folder + | + +hidapi + +hidapi-externals + + Again, this step is not required if you do not wish to build the + test GUI. + + +Building HIDAPI into a shared library on Unix Platforms: +--------------------------------------------------------- + +On Unix-like systems such as Linux, FreeBSD, Mac, and even Windows, using +Mingw or Cygwin, the easiest way to build a standard system-installed shared +library is to use the GNU Autotools build system. If you checked out the +source from the git repository, run the following: + + ./bootstrap + ./configure + make + make install <----- as root, or using sudo + +If you downloaded a source package (ie: if you did not run git clone), you +can skip the ./bootstrap step. + +./configure can take several arguments which control the build. The two most +likely to be used are: + --enable-testgui + Enable build of the Test GUI. This requires Fox toolkit to + be installed. Instructions for installing Fox-Toolkit on + each platform are in the Prerequisites section above. + + --prefix=/usr + Specify where you want the output headers and libraries to + be installed. The example above will put the headers in + /usr/include and the binaries in /usr/lib. The default is to + install into /usr/local which is fine on most systems. + +Building the manual way on Unix platforms: +------------------------------------------- + +Manual Makefiles are provided mostly to give the user and idea what it takes +to build a program which embeds HIDAPI directly inside of it. These should +really be used as examples only. If you want to build a system-wide shared +library, use the Autotools method described above. + + To build HIDAPI using the manual makefiles, change to the directory + of your platform and run make. For example, on Linux run: + cd linux/ + make -f Makefile-manual + + To build the Test GUI using the manual makefiles: + cd testgui/ + make -f Makefile-manual + +Building on Windows: +--------------------- + +To build the HIDAPI DLL on Windows using Visual Studio, build the .sln file +in the windows/ directory. + +To build the Test GUI on windows using Visual Studio, build the .sln file in +the testgui/ directory. + +To build HIDAPI using MinGW or Cygwin using Autotools, use the instructions +in the section titled "Building HIDAPI into a shared library on Unix +Platforms" above. Note that building the Test GUI with MinGW or Cygwin will +require the Windows procedure in the Prerequisites section above (ie: +hidapi-externals.zip). + +To build HIDAPI using MinGW using the Manual Makefiles, see the section +"Building the manual way on Unix platforms" above. + +HIDAPI can also be built using the Windows DDK (now also called the Windows +Driver Kit or WDK). This method was originally required for the HIDAPI build +but not anymore. However, some users still prefer this method. It is not as +well supported anymore but should still work. Patches are welcome if it does +not. To build using the DDK: + + 1. Install the Windows Driver Kit (WDK) from Microsoft. + 2. From the Start menu, in the Windows Driver Kits folder, select Build + Environments, then your operating system, then the x86 Free Build + Environment (or one that is appropriate for your system). + 3. From the console, change directory to the windows/ddk_build/ directory, + which is part of the HIDAPI distribution. + 4. Type build. + 5. You can find the output files (DLL and LIB) in a subdirectory created + by the build system which is appropriate for your environment. On + Windows XP, this directory is objfre_wxp_x86/i386. + +Cross Compiling +================ + +This section talks about cross compiling HIDAPI for Linux using autotools. +This is useful for using HIDAPI on embedded Linux targets. These +instructions assume the most raw kind of embedded Linux build, where all +prerequisites will need to be built first. This process will of course vary +based on your embedded Linux build system if you are using one, such as +OpenEmbedded or Buildroot. + +For the purpose of this section, it will be assumed that the following +environment variables are exported. + + $ export STAGING=$HOME/out + $ export HOST=arm-linux + +STAGING and HOST can be modified to suit your setup. + +Prerequisites +-------------- + +Note that the build of libudev is the very basic configuration. + +Build Libusb. From the libusb source directory, run: + ./configure --host=$HOST --prefix=$STAGING + make + make install + +Build libudev. From the libudev source directory, run: + ./configure --disable-gudev --disable-introspection --disable-hwdb \ + --host=$HOST --prefix=$STAGING + make + make install + +Building HIDAPI +---------------- + +Build HIDAPI: + + PKG_CONFIG_DIR= \ + PKG_CONFIG_LIBDIR=$STAGING/lib/pkgconfig:$STAGING/share/pkgconfig \ + PKG_CONFIG_SYSROOT_DIR=$STAGING \ + ./configure --host=$HOST --prefix=$STAGING + + +Signal 11 Software - 2010-04-11 + 2010-07-28 + 2011-09-10 + 2012-05-01 + 2012-07-03 diff --git a/vendor/github.com/karalabe/usb/hidapi/hidapi/hidapi.h b/vendor/github.com/karalabe/usb/hidapi/hidapi/hidapi.h new file mode 100644 index 00000000..166f3509 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/hidapi/hidapi.h @@ -0,0 +1,390 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. Valid on both Linux implementations + in all cases, and valid on the Windows implementation + only if the device contains more than one interface. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id is set to 0 then any vendor matches. + If @p product_id is set to 0 then any product matches. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read within + the timeout period, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read and + the handle is in non-blocking mode, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param device A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Set the first byte of @p data[] to the Report ID of the + report to be read. Make sure to allow space for this + extra byte in @p data[]. Upon return, the first byte will + still contain the Report ID, and the report data will + start in data[1]. + + @ingroup API + @param device A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read, or set it to zero + if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read plus + one for the report ID (which is still in the first + byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param device A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param device A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/github.com/karalabe/usb/hidapi/libusb/hid.c b/vendor/github.com/karalabe/usb/hidapi/libusb/hid.c new file mode 100644 index 00000000..474dff41 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/libusb/hid.c @@ -0,0 +1,1512 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + Linux Version - 6/2/2010 + Libusb Version - 8/13/2010 + FreeBSD Version - 11/1/2011 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/* C */ +#include +#include +#include +#include +#include +#include + +/* Unix */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* GNU / LibUSB */ +#include +#ifndef __ANDROID__ +#include +#endif + +#include "hidapi.h" + +#ifdef __ANDROID__ + +/* Barrier implementation because Android/Bionic don't have pthread_barrier. + This implementation came from Brent Priddy and was posted on + StackOverflow. It is used with his permission. */ +typedef int pthread_barrierattr_t; +typedef struct pthread_barrier { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int trip_count; +} pthread_barrier_t; + +static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) +{ + if(count == 0) { + errno = EINVAL; + return -1; + } + + if(pthread_mutex_init(&barrier->mutex, 0) < 0) { + return -1; + } + if(pthread_cond_init(&barrier->cond, 0) < 0) { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->trip_count = count; + barrier->count = 0; + + return 0; +} + +static int pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +static int pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if(barrier->count >= barrier->trip_count) + { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } + else + { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEBUG_PRINTF +#define LOG(...) fprintf(stderr, __VA_ARGS__) +#else +#define LOG(...) do {} while (0) +#endif + +#ifndef __FreeBSD__ +#define DETACH_KERNEL_DRIVER +#endif + +/* Uncomment to enable the retrieval of Usage and Usage Page in +hid_enumerate(). Warning, on platforms different from FreeBSD +this is very invasive as it requires the detach +and re-attach of the kernel driver. See comments inside hid_enumerate(). +libusb HIDAPI programs are encouraged to use the interface number +instead to differentiate between interfaces on a composite HID device. */ +/*#define INVASIVE_GET_USAGE*/ + +/* Linked List of input reports received from the device. */ +struct input_report { + uint8_t *data; + size_t len; + struct input_report *next; +}; + + +struct hid_device_ { + /* Handle to the actual device. */ + libusb_device_handle *device_handle; + + /* Endpoint information */ + int input_endpoint; + int output_endpoint; + int input_ep_max_packet_size; + + /* The interface number of the HID */ + int interface; + + /* Indexes of Strings */ + int manufacturer_index; + int product_index; + int serial_index; + + /* Whether blocking reads are used */ + int blocking; /* boolean */ + + /* Read thread objects */ + pthread_t thread; + pthread_mutex_t mutex; /* Protects input_reports */ + pthread_cond_t condition; + pthread_barrier_t barrier; /* Ensures correct startup sequence */ + int shutdown_thread; + int cancelled; + struct libusb_transfer *transfer; + + /* List of received input reports. */ + struct input_report *input_reports; +}; + +static libusb_context *usb_context = NULL; + +uint16_t get_usb_code_for_current_locale(void); +static int return_data(hid_device *dev, unsigned char *data, size_t length); + +static hid_device *new_hid_device(void) +{ + hid_device *dev = calloc(1, sizeof(hid_device)); + dev->blocking = 1; + + pthread_mutex_init(&dev->mutex, NULL); + pthread_cond_init(&dev->condition, NULL); + pthread_barrier_init(&dev->barrier, NULL, 2); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + /* Clean up the thread objects */ + pthread_barrier_destroy(&dev->barrier); + pthread_cond_destroy(&dev->condition); + pthread_mutex_destroy(&dev->mutex); + + /* Free the device itself */ + free(dev); +} + +#if 0 +/*TODO: Implement this funciton on hidapi/libusb.. */ +static void register_error(hid_device *device, const char *op) +{ + +} +#endif + +#ifdef INVASIVE_GET_USAGE +/* Get bytes from a HID Report Descriptor. + Only call with a num_bytes of 0, 1, 2, or 4. */ +static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur) +{ + /* Return if there aren't enough bytes. */ + if (cur + num_bytes >= len) + return 0; + + if (num_bytes == 0) + return 0; + else if (num_bytes == 1) { + return rpt[cur+1]; + } + else if (num_bytes == 2) { + return (rpt[cur+2] * 256 + rpt[cur+1]); + } + else if (num_bytes == 4) { + return (rpt[cur+4] * 0x01000000 + + rpt[cur+3] * 0x00010000 + + rpt[cur+2] * 0x00000100 + + rpt[cur+1] * 0x00000001); + } + else + return 0; +} + +/* Retrieves the device's Usage Page and Usage from the report + descriptor. The algorithm is simple, as it just returns the first + Usage and Usage Page that it finds in the descriptor. + The return value is 0 on success and -1 on failure. */ +static int get_usage(uint8_t *report_descriptor, size_t size, + unsigned short *usage_page, unsigned short *usage) +{ + unsigned int i = 0; + int size_code; + int data_len, key_size; + int usage_found = 0, usage_page_found = 0; + + while (i < size) { + int key = report_descriptor[i]; + int key_cmd = key & 0xfc; + + //printf("key: %02hhx\n", key); + + if ((key & 0xf0) == 0xf0) { + /* This is a Long Item. The next byte contains the + length of the data section (value) for this key. + See the HID specification, version 1.11, section + 6.2.2.3, titled "Long Items." */ + if (i+1 < size) + data_len = report_descriptor[i+1]; + else + data_len = 0; /* malformed report */ + key_size = 3; + } + else { + /* This is a Short Item. The bottom two bits of the + key contain the size code for the data section + (value) for this key. Refer to the HID + specification, version 1.11, section 6.2.2.2, + titled "Short Items." */ + size_code = key & 0x3; + switch (size_code) { + case 0: + case 1: + case 2: + data_len = size_code; + break; + case 3: + data_len = 4; + break; + default: + /* Can't ever happen since size_code is & 0x3 */ + data_len = 0; + break; + }; + key_size = 1; + } + + if (key_cmd == 0x4) { + *usage_page = get_bytes(report_descriptor, size, data_len, i); + usage_page_found = 1; + //printf("Usage Page: %x\n", (uint32_t)*usage_page); + } + if (key_cmd == 0x8) { + *usage = get_bytes(report_descriptor, size, data_len, i); + usage_found = 1; + //printf("Usage: %x\n", (uint32_t)*usage); + } + + if (usage_page_found && usage_found) + return 0; /* success */ + + /* Skip over this key and it's associated data */ + i += data_len + key_size; + } + + return -1; /* failure */ +} +#endif /* INVASIVE_GET_USAGE */ + +#if defined(__FreeBSD__) && __FreeBSD__ < 10 +/* The libusb version included in FreeBSD < 10 doesn't have this function. In + mainline libusb, it's inlined in libusb.h. This function will bear a striking + resemblance to that one, because there's about one way to code it. + + Note that the data parameter is Unicode in UTF-16LE encoding. + Return value is the number of bytes in data, or LIBUSB_ERROR_*. + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t descriptor_index, uint16_t lang_id, + unsigned char *data, int length) +{ + return libusb_control_transfer(dev, + LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */ + LIBUSB_REQUEST_GET_DESCRIPTOR, + (LIBUSB_DT_STRING << 8) | descriptor_index, + lang_id, data, (uint16_t) length, 1000); +} + +#endif + + +/* Get the first language the device says it reports. This comes from + USB string #0. */ +static uint16_t get_first_language(libusb_device_handle *dev) +{ + uint16_t buf[32]; + int len; + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + 0x0, /* String ID */ + 0x0, /* Language */ + (unsigned char*)buf, + sizeof(buf)); + if (len < 4) + return 0x0; + + return buf[1]; /* First two bytes are len and descriptor type. */ +} + +static int is_language_supported(libusb_device_handle *dev, uint16_t lang) +{ + uint16_t buf[32]; + int len; + int i; + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + 0x0, /* String ID */ + 0x0, /* Language */ + (unsigned char*)buf, + sizeof(buf)); + if (len < 4) + return 0x0; + + + len /= 2; /* language IDs are two-bytes each. */ + /* Start at index 1 because there are two bytes of protocol data. */ + for (i = 1; i < len; i++) { + if (buf[i] == lang) + return 1; + } + + return 0; +} + + +/* This function returns a newly allocated wide string containing the USB + device string numbered by the index. The returned string must be freed + by using free(). */ +static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) +{ + char buf[512]; + int len; + wchar_t *str = NULL; + +#ifndef __ANDROID__ /* we don't use iconv on Android */ + wchar_t wbuf[256]; + /* iconv variables */ + iconv_t ic; + size_t inbytes; + size_t outbytes; + size_t res; +#ifdef __FreeBSD__ + const char *inptr; +#else + char *inptr; +#endif + char *outptr; +#endif + + /* Determine which language to use. */ + uint16_t lang; + lang = get_usb_code_for_current_locale(); + if (!is_language_supported(dev, lang)) + lang = get_first_language(dev); + + /* Get the string from libusb. */ + len = libusb_get_string_descriptor(dev, + idx, + lang, + (unsigned char*)buf, + sizeof(buf)); + if (len < 0) + return NULL; + +#ifdef __ANDROID__ + + /* Bionic does not have iconv support nor wcsdup() function, so it + has to be done manually. The following code will only work for + code points that can be represented as a single UTF-16 character, + and will incorrectly convert any code points which require more + than one UTF-16 character. + + Skip over the first character (2-bytes). */ + len -= 2; + str = malloc((len / 2 + 1) * sizeof(wchar_t)); + int i; + for (i = 0; i < len / 2; i++) { + str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); + } + str[len / 2] = 0x00000000; + +#else + + /* buf does not need to be explicitly NULL-terminated because + it is only passed into iconv() which does not need it. */ + + /* Initialize iconv. */ + ic = iconv_open("WCHAR_T", "UTF-16LE"); + if (ic == (iconv_t)-1) { + LOG("iconv_open() failed\n"); + return NULL; + } + + /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). + Skip the first character (2-bytes). */ + inptr = buf+2; + inbytes = len-2; + outptr = (char*) wbuf; + outbytes = sizeof(wbuf); + res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); + if (res == (size_t)-1) { + LOG("iconv() failed\n"); + goto err; + } + + /* Write the terminating NULL. */ + wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; + if (outbytes >= sizeof(wbuf[0])) + *((wchar_t*)outptr) = 0x00000000; + + /* Allocate and copy the string. */ + str = wcsdup(wbuf); + +err: + iconv_close(ic); + +#endif + + return str; +} + +static char *make_path(libusb_device *dev, int interface_number) +{ + char str[64]; + snprintf(str, sizeof(str), "%04x:%04x:%02x", + libusb_get_bus_number(dev), + libusb_get_device_address(dev), + interface_number); + str[sizeof(str)-1] = '\0'; + + return strdup(str); +} + + +int HID_API_EXPORT hid_init(void) +{ + if (!usb_context) { + const char *locale; + + /* Init Libusb */ + if (libusb_init(&usb_context)) + return -1; + + /* Set the locale if it's not set. */ + locale = setlocale(LC_CTYPE, NULL); + if (!locale) + setlocale(LC_CTYPE, ""); + } + + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ + if (usb_context) { + libusb_exit(usb_context); + usb_context = NULL; + } + + return 0; +} + +struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + libusb_device **devs; + libusb_device *dev; + libusb_device_handle *handle; + ssize_t num_devs; + int i = 0; + + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + if(hid_init() < 0) + return NULL; + + num_devs = libusb_get_device_list(usb_context, &devs); + if (num_devs < 0) + return NULL; + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + struct libusb_config_descriptor *conf_desc = NULL; + int j, k; + int interface_num = 0; + + int res = libusb_get_device_descriptor(dev, &desc); + unsigned short dev_vid = desc.idVendor; + unsigned short dev_pid = desc.idProduct; + + res = libusb_get_active_config_descriptor(dev, &conf_desc); + if (res < 0) + libusb_get_config_descriptor(dev, 0, &conf_desc); + if (conf_desc) { + for (j = 0; j < conf_desc->bNumInterfaces; j++) { + const struct libusb_interface *intf = &conf_desc->interface[j]; + for (k = 0; k < intf->num_altsetting; k++) { + const struct libusb_interface_descriptor *intf_desc; + intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { + interface_num = intf_desc->bInterfaceNumber; + + /* Check the VID/PID against the arguments */ + if ((vendor_id == 0x0 || vendor_id == dev_vid) && + (product_id == 0x0 || product_id == dev_pid)) { + struct hid_device_info *tmp; + + /* VID/PID match. Create the record. */ + tmp = calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Fill out the record */ + cur_dev->next = NULL; + cur_dev->path = make_path(dev, interface_num); + + res = libusb_open(dev, &handle); + + if (res >= 0) { + /* Serial Number */ + if (desc.iSerialNumber > 0) + cur_dev->serial_number = + get_usb_string(handle, desc.iSerialNumber); + + /* Manufacturer and Product strings */ + if (desc.iManufacturer > 0) + cur_dev->manufacturer_string = + get_usb_string(handle, desc.iManufacturer); + if (desc.iProduct > 0) + cur_dev->product_string = + get_usb_string(handle, desc.iProduct); + +#ifdef INVASIVE_GET_USAGE +{ + /* + This section is removed because it is too + invasive on the system. Getting a Usage Page + and Usage requires parsing the HID Report + descriptor. Getting a HID Report descriptor + involves claiming the interface. Claiming the + interface involves detaching the kernel driver. + Detaching the kernel driver is hard on the system + because it will unclaim interfaces (if another + app has them claimed) and the re-attachment of + the driver will sometimes change /dev entry names. + It is for these reasons that this section is + #if 0. For composite devices, use the interface + field in the hid_device_info struct to distinguish + between interfaces. */ + unsigned char data[256]; +#ifdef DETACH_KERNEL_DRIVER + int detached = 0; + /* Usage Page and Usage */ + res = libusb_kernel_driver_active(handle, interface_num); + if (res == 1) { + res = libusb_detach_kernel_driver(handle, interface_num); + if (res < 0) + LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); + else + detached = 1; + } +#endif + res = libusb_claim_interface(handle, interface_num); + if (res >= 0) { + /* Get the HID Report Descriptor. */ + res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); + if (res >= 0) { + unsigned short page=0, usage=0; + /* Parse the usage and usage page + out of the report descriptor. */ + get_usage(data, res, &page, &usage); + cur_dev->usage_page = page; + cur_dev->usage = usage; + } + else + LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); + + /* Release the interface */ + res = libusb_release_interface(handle, interface_num); + if (res < 0) + LOG("Can't release the interface.\n"); + } + else + LOG("Can't claim interface %d\n", res); +#ifdef DETACH_KERNEL_DRIVER + /* Re-attach kernel driver if necessary. */ + if (detached) { + res = libusb_attach_kernel_driver(handle, interface_num); + if (res < 0) + LOG("Couldn't re-attach kernel driver.\n"); + } +#endif +} +#endif /* INVASIVE_GET_USAGE */ + + libusb_close(handle); + } + /* VID/PID */ + cur_dev->vendor_id = dev_vid; + cur_dev->product_id = dev_pid; + + /* Release Number */ + cur_dev->release_number = desc.bcdDevice; + + /* Interface Number */ + cur_dev->interface_number = interface_num; + } + } + } /* altsettings */ + } /* interfaces */ + libusb_free_config_descriptor(conf_desc); + } + } + + libusb_free_device_list(devs, 1); + + return root; +} + +void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) +{ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + +hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (cur_dev->serial_number && + wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +static void read_callback(struct libusb_transfer *transfer) +{ + hid_device *dev = transfer->user_data; + int res; + + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { + + struct input_report *rpt = malloc(sizeof(*rpt)); + rpt->data = malloc(transfer->actual_length); + memcpy(rpt->data, transfer->buffer, transfer->actual_length); + rpt->len = transfer->actual_length; + rpt->next = NULL; + + pthread_mutex_lock(&dev->mutex); + + /* Attach the new report object to the end of the list. */ + if (dev->input_reports == NULL) { + /* The list is empty. Put it at the root. */ + dev->input_reports = rpt; + pthread_cond_signal(&dev->condition); + } + else { + /* Find the end of the list and attach. */ + struct input_report *cur = dev->input_reports; + int num_queued = 0; + while (cur->next != NULL) { + cur = cur->next; + num_queued++; + } + cur->next = rpt; + + /* Pop one off if we've reached 30 in the queue. This + way we don't grow forever if the user never reads + anything from the device. */ + if (num_queued > 30) { + return_data(dev, NULL, 0); + } + } + pthread_mutex_unlock(&dev->mutex); + } + else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { + dev->shutdown_thread = 1; + dev->cancelled = 1; + return; + } + else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { + dev->shutdown_thread = 1; + dev->cancelled = 1; + return; + } + else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { + //LOG("Timeout (normal)\n"); + } + else { + LOG("Unknown transfer code: %d\n", transfer->status); + } + + /* Re-submit the transfer object. */ + res = libusb_submit_transfer(transfer); + if (res != 0) { + LOG("Unable to submit URB. libusb error code: %d\n", res); + dev->shutdown_thread = 1; + dev->cancelled = 1; + } +} + + +static void *read_thread(void *param) +{ + hid_device *dev = param; + unsigned char *buf; + const size_t length = dev->input_ep_max_packet_size; + + /* Set up the transfer object. */ + buf = malloc(length); + dev->transfer = libusb_alloc_transfer(0); + libusb_fill_interrupt_transfer(dev->transfer, + dev->device_handle, + dev->input_endpoint, + buf, + length, + read_callback, + dev, + 5000/*timeout*/); + + /* Make the first submission. Further submissions are made + from inside read_callback() */ + libusb_submit_transfer(dev->transfer); + + /* Notify the main thread that the read thread is up and running. */ + pthread_barrier_wait(&dev->barrier); + + /* Handle all the events. */ + while (!dev->shutdown_thread) { + int res; + res = libusb_handle_events(usb_context); + if (res < 0) { + /* There was an error. */ + LOG("read_thread(): libusb reports error # %d\n", res); + + /* Break out of this loop only on fatal error.*/ + if (res != LIBUSB_ERROR_BUSY && + res != LIBUSB_ERROR_TIMEOUT && + res != LIBUSB_ERROR_OVERFLOW && + res != LIBUSB_ERROR_INTERRUPTED) { + break; + } + } + } + + /* Cancel any transfer that may be pending. This call will fail + if no transfers are pending, but that's OK. */ + libusb_cancel_transfer(dev->transfer); + + while (!dev->cancelled) + libusb_handle_events_completed(usb_context, &dev->cancelled); + + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on + the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); + pthread_mutex_unlock(&dev->mutex); + + /* The dev->transfer->buffer and dev->transfer objects are cleaned up + in hid_close(). They are not cleaned up here because this thread + could end either due to a disconnect or due to a user + call to hid_close(). In both cases the objects can be safely + cleaned up after the call to pthread_join() (in hid_close()), but + since hid_close() calls libusb_cancel_transfer(), on these objects, + they can not be cleaned up here. */ + + return NULL; +} + + +hid_device * HID_API_EXPORT hid_open_path(const char *path) +{ + hid_device *dev = NULL; + + libusb_device **devs; + libusb_device *usb_dev; + int res; + int d = 0; + int good_open = 0; + + if(hid_init() < 0) + return NULL; + + dev = new_hid_device(); + + libusb_get_device_list(usb_context, &devs); + while ((usb_dev = devs[d++]) != NULL) { + struct libusb_device_descriptor desc; + struct libusb_config_descriptor *conf_desc = NULL; + int i,j,k; + libusb_get_device_descriptor(usb_dev, &desc); + + if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0) + continue; + for (j = 0; j < conf_desc->bNumInterfaces; j++) { + const struct libusb_interface *intf = &conf_desc->interface[j]; + for (k = 0; k < intf->num_altsetting; k++) { + const struct libusb_interface_descriptor *intf_desc; + intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { + char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber); + if (!strcmp(dev_path, path)) { + /* Matched Paths. Open this device */ + + /* OPEN HERE */ + res = libusb_open(usb_dev, &dev->device_handle); + if (res < 0) { + LOG("can't open device\n"); + free(dev_path); + break; + } + good_open = 1; +#ifdef DETACH_KERNEL_DRIVER + /* Detach the kernel driver, but only if the + device is managed by the kernel */ + if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) { + res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + libusb_close(dev->device_handle); + LOG("Unable to detach Kernel Driver\n"); + free(dev_path); + good_open = 0; + break; + } + } +#endif + res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); + free(dev_path); + libusb_close(dev->device_handle); + good_open = 0; + break; + } + + /* Store off the string descriptor indexes */ + dev->manufacturer_index = desc.iManufacturer; + dev->product_index = desc.iProduct; + dev->serial_index = desc.iSerialNumber; + + /* Store off the interface number */ + dev->interface = intf_desc->bInterfaceNumber; + + /* Find the INPUT and OUTPUT endpoints. An + OUTPUT endpoint is not required. */ + for (i = 0; i < intf_desc->bNumEndpoints; i++) { + const struct libusb_endpoint_descriptor *ep + = &intf_desc->endpoint[i]; + + /* Determine the type and direction of this + endpoint. */ + int is_interrupt = + (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + == LIBUSB_TRANSFER_TYPE_INTERRUPT; + int is_output = + (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; + int is_input = + (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_IN; + + /* Decide whether to use it for input or output. */ + if (dev->input_endpoint == 0 && + is_interrupt && is_input) { + /* Use this endpoint for INPUT */ + dev->input_endpoint = ep->bEndpointAddress; + dev->input_ep_max_packet_size = ep->wMaxPacketSize; + } + if (dev->output_endpoint == 0 && + is_interrupt && is_output) { + /* Use this endpoint for OUTPUT */ + dev->output_endpoint = ep->bEndpointAddress; + } + } + + pthread_create(&dev->thread, NULL, read_thread, dev); + + /* Wait here for the read thread to be initialized. */ + pthread_barrier_wait(&dev->barrier); + + } + free(dev_path); + } + } + } + libusb_free_config_descriptor(conf_desc); + + } + + libusb_free_device_list(devs, 1); + + /* If we have a good handle, return it. */ + if (good_open) { + return dev; + } + else { + /* Unable to open any devices. */ + free_hid_device(dev); + return NULL; + } +} + + +int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + int res; + int report_number = data[0]; + int skipped_report_id = 0; + + if (report_number == 0x0) { + data++; + length--; + skipped_report_id = 1; + } + + + if (dev->output_endpoint <= 0) { + /* No interrupt out endpoint. Use the Control Endpoint */ + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, + 0x09/*HID Set_Report*/, + (2/*HID output*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + if (skipped_report_id) + length++; + + return length; + } + else { + /* Use the interrupt out endpoint */ + int actual_length; + res = libusb_interrupt_transfer(dev->device_handle, + dev->output_endpoint, + (unsigned char*)data, + length, + &actual_length, 1000); + + if (res < 0) + return -1; + + if (skipped_report_id) + actual_length++; + + return actual_length; + } +} + +/* Helper function, to simplify hid_read(). + This should be called with dev->mutex locked. */ +static int return_data(hid_device *dev, unsigned char *data, size_t length) +{ + /* Copy the data out of the linked list item (rpt) into the + return buffer (data), and delete the liked list item. */ + struct input_report *rpt = dev->input_reports; + size_t len = (length < rpt->len)? length: rpt->len; + if (len > 0) + memcpy(data, rpt->data, len); + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + return len; +} + +static void cleanup_mutex(void *param) +{ + hid_device *dev = param; + pthread_mutex_unlock(&dev->mutex); +} + + +int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + int bytes_read = -1; + +#if 0 + int transferred; + int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); + LOG("transferred: %d\n", transferred); + return transferred; +#endif + + pthread_mutex_lock(&dev->mutex); + pthread_cleanup_push(&cleanup_mutex, dev); + + /* There's an input report queued up. Return it. */ + if (dev->input_reports) { + /* Return the first one */ + bytes_read = return_data(dev, data, length); + goto ret; + } + + if (dev->shutdown_thread) { + /* This means the device has been disconnected. + An error code of -1 should be returned. */ + bytes_read = -1; + goto ret; + } + + if (milliseconds == -1) { + /* Blocking */ + while (!dev->input_reports && !dev->shutdown_thread) { + pthread_cond_wait(&dev->condition, &dev->mutex); + } + if (dev->input_reports) { + bytes_read = return_data(dev, data, length); + } + } + else if (milliseconds > 0) { + /* Non-blocking, but called with timeout. */ + int res; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += milliseconds / 1000; + ts.tv_nsec += (milliseconds % 1000) * 1000000; + if (ts.tv_nsec >= 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + while (!dev->input_reports && !dev->shutdown_thread) { + res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts); + if (res == 0) { + if (dev->input_reports) { + bytes_read = return_data(dev, data, length); + break; + } + + /* If we're here, there was a spurious wake up + or the read thread was shutdown. Run the + loop again (ie: don't break). */ + } + else if (res == ETIMEDOUT) { + /* Timed out. */ + bytes_read = 0; + break; + } + else { + /* Error. */ + bytes_read = -1; + break; + } + } + } + else { + /* Purely non-blocking */ + bytes_read = 0; + } + +ret: + pthread_mutex_unlock(&dev->mutex); + pthread_cleanup_pop(0); + + return bytes_read; +} + +int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0); +} + +int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + + return 0; +} + + +int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + int res = -1; + int skipped_report_id = 0; + int report_number = data[0]; + + if (report_number == 0x0) { + data++; + length--; + skipped_report_id = 1; + } + + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, + 0x09/*HID set_report*/, + (3/*HID feature*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + /* Account for the report ID */ + if (skipped_report_id) + length++; + + return length; +} + +int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + int res = -1; + int skipped_report_id = 0; + int report_number = data[0]; + + if (report_number == 0x0) { + /* Offset the return buffer by 1, so that the report ID + will remain in byte 0. */ + data++; + length--; + skipped_report_id = 1; + } + res = libusb_control_transfer(dev->device_handle, + LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, + 0x01/*HID get_report*/, + (3/*HID feature*/ << 8) | report_number, + dev->interface, + (unsigned char *)data, length, + 1000/*timeout millis*/); + + if (res < 0) + return -1; + + if (skipped_report_id) + res++; + + return res; +} + + +void HID_API_EXPORT hid_close(hid_device *dev) +{ + if (!dev) + return; + + /* Cause read_thread() to stop. */ + dev->shutdown_thread = 1; + libusb_cancel_transfer(dev->transfer); + + /* Wait for read_thread() to end. */ + pthread_join(dev->thread, NULL); + + /* Clean up the Transfer objects allocated in read_thread(). */ + free(dev->transfer->buffer); + libusb_free_transfer(dev->transfer); + + /* release the interface */ + libusb_release_interface(dev->device_handle, dev->interface); + + /* Close the handle */ + libusb_close(dev->device_handle); + + /* Clear out the queue of received reports. */ + pthread_mutex_lock(&dev->mutex); + while (dev->input_reports) { + return_data(dev, NULL, 0); + } + pthread_mutex_unlock(&dev->mutex); + + free_hid_device(dev); +} + + +int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->product_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return hid_get_indexed_string(dev, dev->serial_index, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + wchar_t *str; + + str = get_usb_string(dev->device_handle, string_index); + if (str) { + wcsncpy(string, str, maxlen); + string[maxlen-1] = L'\0'; + free(str); + return 0; + } + else + return -1; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + return NULL; +} + + +struct lang_map_entry { + const char *name; + const char *string_code; + uint16_t usb_code; +}; + +#define LANG(name,code,usb_code) { name, code, usb_code } +static struct lang_map_entry lang_map[] = { + LANG("Afrikaans", "af", 0x0436), + LANG("Albanian", "sq", 0x041C), + LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801), + LANG("Arabic - Bahrain", "ar_bh", 0x3C01), + LANG("Arabic - Algeria", "ar_dz", 0x1401), + LANG("Arabic - Egypt", "ar_eg", 0x0C01), + LANG("Arabic - Iraq", "ar_iq", 0x0801), + LANG("Arabic - Jordan", "ar_jo", 0x2C01), + LANG("Arabic - Kuwait", "ar_kw", 0x3401), + LANG("Arabic - Lebanon", "ar_lb", 0x3001), + LANG("Arabic - Libya", "ar_ly", 0x1001), + LANG("Arabic - Morocco", "ar_ma", 0x1801), + LANG("Arabic - Oman", "ar_om", 0x2001), + LANG("Arabic - Qatar", "ar_qa", 0x4001), + LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401), + LANG("Arabic - Syria", "ar_sy", 0x2801), + LANG("Arabic - Tunisia", "ar_tn", 0x1C01), + LANG("Arabic - Yemen", "ar_ye", 0x2401), + LANG("Armenian", "hy", 0x042B), + LANG("Azeri - Latin", "az_az", 0x042C), + LANG("Azeri - Cyrillic", "az_az", 0x082C), + LANG("Basque", "eu", 0x042D), + LANG("Belarusian", "be", 0x0423), + LANG("Bulgarian", "bg", 0x0402), + LANG("Catalan", "ca", 0x0403), + LANG("Chinese - China", "zh_cn", 0x0804), + LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04), + LANG("Chinese - Macau SAR", "zh_mo", 0x1404), + LANG("Chinese - Singapore", "zh_sg", 0x1004), + LANG("Chinese - Taiwan", "zh_tw", 0x0404), + LANG("Croatian", "hr", 0x041A), + LANG("Czech", "cs", 0x0405), + LANG("Danish", "da", 0x0406), + LANG("Dutch - Netherlands", "nl_nl", 0x0413), + LANG("Dutch - Belgium", "nl_be", 0x0813), + LANG("English - Australia", "en_au", 0x0C09), + LANG("English - Belize", "en_bz", 0x2809), + LANG("English - Canada", "en_ca", 0x1009), + LANG("English - Caribbean", "en_cb", 0x2409), + LANG("English - Ireland", "en_ie", 0x1809), + LANG("English - Jamaica", "en_jm", 0x2009), + LANG("English - New Zealand", "en_nz", 0x1409), + LANG("English - Phillippines", "en_ph", 0x3409), + LANG("English - Southern Africa", "en_za", 0x1C09), + LANG("English - Trinidad", "en_tt", 0x2C09), + LANG("English - Great Britain", "en_gb", 0x0809), + LANG("English - United States", "en_us", 0x0409), + LANG("Estonian", "et", 0x0425), + LANG("Farsi", "fa", 0x0429), + LANG("Finnish", "fi", 0x040B), + LANG("Faroese", "fo", 0x0438), + LANG("French - France", "fr_fr", 0x040C), + LANG("French - Belgium", "fr_be", 0x080C), + LANG("French - Canada", "fr_ca", 0x0C0C), + LANG("French - Luxembourg", "fr_lu", 0x140C), + LANG("French - Switzerland", "fr_ch", 0x100C), + LANG("Gaelic - Ireland", "gd_ie", 0x083C), + LANG("Gaelic - Scotland", "gd", 0x043C), + LANG("German - Germany", "de_de", 0x0407), + LANG("German - Austria", "de_at", 0x0C07), + LANG("German - Liechtenstein", "de_li", 0x1407), + LANG("German - Luxembourg", "de_lu", 0x1007), + LANG("German - Switzerland", "de_ch", 0x0807), + LANG("Greek", "el", 0x0408), + LANG("Hebrew", "he", 0x040D), + LANG("Hindi", "hi", 0x0439), + LANG("Hungarian", "hu", 0x040E), + LANG("Icelandic", "is", 0x040F), + LANG("Indonesian", "id", 0x0421), + LANG("Italian - Italy", "it_it", 0x0410), + LANG("Italian - Switzerland", "it_ch", 0x0810), + LANG("Japanese", "ja", 0x0411), + LANG("Korean", "ko", 0x0412), + LANG("Latvian", "lv", 0x0426), + LANG("Lithuanian", "lt", 0x0427), + LANG("F.Y.R.O. Macedonia", "mk", 0x042F), + LANG("Malay - Malaysia", "ms_my", 0x043E), + LANG("Malay – Brunei", "ms_bn", 0x083E), + LANG("Maltese", "mt", 0x043A), + LANG("Marathi", "mr", 0x044E), + LANG("Norwegian - Bokml", "no_no", 0x0414), + LANG("Norwegian - Nynorsk", "no_no", 0x0814), + LANG("Polish", "pl", 0x0415), + LANG("Portuguese - Portugal", "pt_pt", 0x0816), + LANG("Portuguese - Brazil", "pt_br", 0x0416), + LANG("Raeto-Romance", "rm", 0x0417), + LANG("Romanian - Romania", "ro", 0x0418), + LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818), + LANG("Russian", "ru", 0x0419), + LANG("Russian - Republic of Moldova", "ru_mo", 0x0819), + LANG("Sanskrit", "sa", 0x044F), + LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A), + LANG("Serbian - Latin", "sr_sp", 0x081A), + LANG("Setsuana", "tn", 0x0432), + LANG("Slovenian", "sl", 0x0424), + LANG("Slovak", "sk", 0x041B), + LANG("Sorbian", "sb", 0x042E), + LANG("Spanish - Spain (Traditional)", "es_es", 0x040A), + LANG("Spanish - Argentina", "es_ar", 0x2C0A), + LANG("Spanish - Bolivia", "es_bo", 0x400A), + LANG("Spanish - Chile", "es_cl", 0x340A), + LANG("Spanish - Colombia", "es_co", 0x240A), + LANG("Spanish - Costa Rica", "es_cr", 0x140A), + LANG("Spanish - Dominican Republic", "es_do", 0x1C0A), + LANG("Spanish - Ecuador", "es_ec", 0x300A), + LANG("Spanish - Guatemala", "es_gt", 0x100A), + LANG("Spanish - Honduras", "es_hn", 0x480A), + LANG("Spanish - Mexico", "es_mx", 0x080A), + LANG("Spanish - Nicaragua", "es_ni", 0x4C0A), + LANG("Spanish - Panama", "es_pa", 0x180A), + LANG("Spanish - Peru", "es_pe", 0x280A), + LANG("Spanish - Puerto Rico", "es_pr", 0x500A), + LANG("Spanish - Paraguay", "es_py", 0x3C0A), + LANG("Spanish - El Salvador", "es_sv", 0x440A), + LANG("Spanish - Uruguay", "es_uy", 0x380A), + LANG("Spanish - Venezuela", "es_ve", 0x200A), + LANG("Southern Sotho", "st", 0x0430), + LANG("Swahili", "sw", 0x0441), + LANG("Swedish - Sweden", "sv_se", 0x041D), + LANG("Swedish - Finland", "sv_fi", 0x081D), + LANG("Tamil", "ta", 0x0449), + LANG("Tatar", "tt", 0X0444), + LANG("Thai", "th", 0x041E), + LANG("Turkish", "tr", 0x041F), + LANG("Tsonga", "ts", 0x0431), + LANG("Ukrainian", "uk", 0x0422), + LANG("Urdu", "ur", 0x0420), + LANG("Uzbek - Cyrillic", "uz_uz", 0x0843), + LANG("Uzbek – Latin", "uz_uz", 0x0443), + LANG("Vietnamese", "vi", 0x042A), + LANG("Xhosa", "xh", 0x0434), + LANG("Yiddish", "yi", 0x043D), + LANG("Zulu", "zu", 0x0435), + LANG(NULL, NULL, 0x0), +}; + +uint16_t get_usb_code_for_current_locale(void) +{ + char *locale; + char search_string[64]; + char *ptr; + struct lang_map_entry *lang; + + /* Get the current locale. */ + locale = setlocale(0, NULL); + if (!locale) + return 0x0; + + /* Make a copy of the current locale string. */ + strncpy(search_string, locale, sizeof(search_string)); + search_string[sizeof(search_string)-1] = '\0'; + + /* Chop off the encoding part, and make it lower case. */ + ptr = search_string; + while (*ptr) { + *ptr = tolower(*ptr); + if (*ptr == '.') { + *ptr = '\0'; + break; + } + ptr++; + } + + /* Find the entry which matches the string code of our locale. */ + lang = lang_map; + while (lang->string_code) { + if (!strcmp(lang->string_code, search_string)) { + return lang->usb_code; + } + lang++; + } + + /* There was no match. Find with just the language only. */ + /* Chop off the variant. Chop it off at the '_'. */ + ptr = search_string; + while (*ptr) { + *ptr = tolower(*ptr); + if (*ptr == '_') { + *ptr = '\0'; + break; + } + ptr++; + } + +#if 0 /* TODO: Do we need this? */ + /* Find the entry which matches the string code of our language. */ + lang = lang_map; + while (lang->string_code) { + if (!strcmp(lang->string_code, search_string)) { + return lang->usb_code; + } + lang++; + } +#endif + + /* Found nothing. */ + return 0x0; +} + +#ifdef __cplusplus +} +#endif diff --git a/vendor/github.com/karalabe/usb/hidapi/mac/hid.c b/vendor/github.com/karalabe/usb/hidapi/mac/hid.c new file mode 100644 index 00000000..e0756a15 --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/mac/hid.c @@ -0,0 +1,1110 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 2010-07-03 + + Copyright 2010, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/* See Apple Technical Note TN2187 for details on IOHidManager. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hidapi.h" + +/* Barrier implementation because Mac OSX doesn't have pthread_barrier. + It also doesn't have clock_gettime(). So much for POSIX and SUSv2. + This implementation came from Brent Priddy and was posted on + StackOverflow. It is used with his permission. */ +typedef int pthread_barrierattr_t; +typedef struct pthread_barrier { + pthread_mutex_t mutex; + pthread_cond_t cond; + int count; + int trip_count; +} pthread_barrier_t; + +static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) +{ + if(count == 0) { + errno = EINVAL; + return -1; + } + + if(pthread_mutex_init(&barrier->mutex, 0) < 0) { + return -1; + } + if(pthread_cond_init(&barrier->cond, 0) < 0) { + pthread_mutex_destroy(&barrier->mutex); + return -1; + } + barrier->trip_count = count; + barrier->count = 0; + + return 0; +} + +static int pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + pthread_cond_destroy(&barrier->cond); + pthread_mutex_destroy(&barrier->mutex); + return 0; +} + +static int pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_mutex_lock(&barrier->mutex); + ++(barrier->count); + if(barrier->count >= barrier->trip_count) + { + barrier->count = 0; + pthread_cond_broadcast(&barrier->cond); + pthread_mutex_unlock(&barrier->mutex); + return 1; + } + else + { + pthread_cond_wait(&barrier->cond, &(barrier->mutex)); + pthread_mutex_unlock(&barrier->mutex); + return 0; + } +} + +static int return_data(hid_device *dev, unsigned char *data, size_t length); + +/* Linked List of input reports received from the device. */ +struct input_report { + uint8_t *data; + size_t len; + struct input_report *next; +}; + +struct hid_device_ { + IOHIDDeviceRef device_handle; + int blocking; + int uses_numbered_reports; + int disconnected; + CFStringRef run_loop_mode; + CFRunLoopRef run_loop; + CFRunLoopSourceRef source; + uint8_t *input_report_buf; + CFIndex max_input_report_len; + struct input_report *input_reports; + + pthread_t thread; + pthread_mutex_t mutex; /* Protects input_reports */ + pthread_cond_t condition; + pthread_barrier_t barrier; /* Ensures correct startup sequence */ + pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */ + int shutdown_thread; +}; + +static hid_device *new_hid_device(void) +{ + hid_device *dev = calloc(1, sizeof(hid_device)); + dev->device_handle = NULL; + dev->blocking = 1; + dev->uses_numbered_reports = 0; + dev->disconnected = 0; + dev->run_loop_mode = NULL; + dev->run_loop = NULL; + dev->source = NULL; + dev->input_report_buf = NULL; + dev->input_reports = NULL; + dev->shutdown_thread = 0; + + /* Thread objects */ + pthread_mutex_init(&dev->mutex, NULL); + pthread_cond_init(&dev->condition, NULL); + pthread_barrier_init(&dev->barrier, NULL, 2); + pthread_barrier_init(&dev->shutdown_barrier, NULL, 2); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + if (!dev) + return; + + /* Delete any input reports still left over. */ + struct input_report *rpt = dev->input_reports; + while (rpt) { + struct input_report *next = rpt->next; + free(rpt->data); + free(rpt); + rpt = next; + } + + /* Free the string and the report buffer. The check for NULL + is necessary here as CFRelease() doesn't handle NULL like + free() and others do. */ + if (dev->run_loop_mode) + CFRelease(dev->run_loop_mode); + if (dev->source) + CFRelease(dev->source); + free(dev->input_report_buf); + + /* Clean up the thread objects */ + pthread_barrier_destroy(&dev->shutdown_barrier); + pthread_barrier_destroy(&dev->barrier); + pthread_cond_destroy(&dev->condition); + pthread_mutex_destroy(&dev->mutex); + + /* Free the structure itself. */ + free(dev); +} + +static IOHIDManagerRef hid_mgr = 0x0; + + +#if 0 +static void register_error(hid_device *device, const char *op) +{ + +} +#endif + + +static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key) +{ + CFTypeRef ref; + int32_t value; + + ref = IOHIDDeviceGetProperty(device, key); + if (ref) { + if (CFGetTypeID(ref) == CFNumberGetTypeID()) { + CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value); + return value; + } + } + return 0; +} + +static unsigned short get_vendor_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDVendorIDKey)); +} + +static unsigned short get_product_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDProductIDKey)); +} + +static int32_t get_max_report_length(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey)); +} + +static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len) +{ + CFStringRef str; + + if (!len) + return 0; + + str = IOHIDDeviceGetProperty(device, prop); + + buf[0] = 0; + + if (str) { + CFIndex str_len = CFStringGetLength(str); + CFRange range; + CFIndex used_buf_len; + CFIndex chars_copied; + + len --; + + range.location = 0; + range.length = ((size_t)str_len > len)? len: (size_t)str_len; + chars_copied = CFStringGetBytes(str, + range, + kCFStringEncodingUTF32LE, + (char)'?', + FALSE, + (UInt8*)buf, + len * sizeof(wchar_t), + &used_buf_len); + + if (chars_copied == len) + buf[len] = 0; /* len is decremented above */ + else + buf[chars_copied] = 0; + + return 0; + } + else + return -1; + +} + +static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len); +} + +static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len); +} + +static int get_product_string(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len); +} + + +/* Implementation of wcsdup() for Mac. */ +static wchar_t *dup_wcs(const wchar_t *s) +{ + size_t len = wcslen(s); + wchar_t *ret = malloc((len+1)*sizeof(wchar_t)); + wcscpy(ret, s); + + return ret; +} + +/* hidapi_IOHIDDeviceGetService() + * + * Return the io_service_t corresponding to a given IOHIDDeviceRef, either by: + * - on OS X 10.6 and above, calling IOHIDDeviceGetService() + * - on OS X 10.5, extract it from the IOHIDDevice struct + */ +static io_service_t hidapi_IOHIDDeviceGetService(IOHIDDeviceRef device) +{ + static void *iokit_framework = NULL; + static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef device) = NULL; + + /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if it exists. + * If any of these steps fail, dynamic_IOHIDDeviceGetService will be left NULL + * and the fallback method will be used. + */ + if (iokit_framework == NULL) { + iokit_framework = dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY); + + if (iokit_framework != NULL) + dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, "IOHIDDeviceGetService"); + } + + if (dynamic_IOHIDDeviceGetService != NULL) { + /* Running on OS X 10.6 and above: IOHIDDeviceGetService() exists */ + return dynamic_IOHIDDeviceGetService(device); + } + else + { + /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist. + * + * Be naughty and pull the service out of the IOHIDDevice. + * IOHIDDevice is an opaque struct not exposed to applications, but its + * layout is stable through all available versions of OS X. + * Tested and working on OS X 10.5.8 i386, x86_64, and ppc. + */ + struct IOHIDDevice_internal { + /* The first field of the IOHIDDevice struct is a + * CFRuntimeBase (which is a private CF struct). + * + * a, b, and c are the 3 fields that make up a CFRuntimeBase. + * See http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h + * + * The second field of the IOHIDDevice is the io_service_t we're looking for. + */ + uintptr_t a; + uint8_t b[4]; +#if __LP64__ + uint32_t c; +#endif + io_service_t service; + }; + struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal *)device; + + return tmp->service; + } +} + +/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ +static int init_hid_manager(void) +{ + /* Initialize all the HID Manager Objects */ + hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (hid_mgr) { + IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + return 0; + } + + return -1; +} + +/* Initialize the IOHIDManager if necessary. This is the public function, and + it is safe to call this function repeatedly. Return 0 for success and -1 + for failure. */ +int HID_API_EXPORT hid_init(void) +{ + if (!hid_mgr) { + return init_hid_manager(); + } + + /* Already initialized. */ + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ + if (hid_mgr) { + /* Close the HID manager. */ + IOHIDManagerClose(hid_mgr, kIOHIDOptionsTypeNone); + CFRelease(hid_mgr); + hid_mgr = NULL; + } + + return 0; +} + +static void process_pending_events(void) { + SInt32 res; + do { + res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE); + } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut); +} + +struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + CFIndex num_devices; + int i; + + /* Set up the HID Manager if it hasn't been done */ + if (hid_init() < 0) + return NULL; + + /* give the IOHIDManager a chance to update itself */ + process_pending_events(); + + /* Get a list of the Devices */ + IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); + + /* Convert the list into a C array so we can iterate easily. */ + num_devices = CFSetGetCount(device_set); + IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); + CFSetGetValues(device_set, (const void **) device_array); + + /* Iterate over each device, making an entry for it. */ + for (i = 0; i < num_devices; i++) { + unsigned short dev_vid; + unsigned short dev_pid; + #define BUF_LEN 256 + wchar_t buf[BUF_LEN]; + + IOHIDDeviceRef dev = device_array[i]; + + if (!dev) { + continue; + } + dev_vid = get_vendor_id(dev); + dev_pid = get_product_id(dev); + + /* Check the VID/PID against the arguments */ + if ((vendor_id == 0x0 || vendor_id == dev_vid) && + (product_id == 0x0 || product_id == dev_pid)) { + struct hid_device_info *tmp; + io_object_t iokit_dev; + kern_return_t res; + io_string_t path; + + /* VID/PID match. Create the record. */ + tmp = malloc(sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Get the Usage Page and Usage for this device. */ + cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey)); + cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey)); + + /* Fill out the record */ + cur_dev->next = NULL; + + /* Fill in the path (IOService plane) */ + iokit_dev = hidapi_IOHIDDeviceGetService(dev); + res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path); + if (res == KERN_SUCCESS) + cur_dev->path = strdup(path); + else + cur_dev->path = strdup(""); + + /* Serial Number */ + get_serial_number(dev, buf, BUF_LEN); + cur_dev->serial_number = dup_wcs(buf); + + /* Manufacturer and Product strings */ + get_manufacturer_string(dev, buf, BUF_LEN); + cur_dev->manufacturer_string = dup_wcs(buf); + get_product_string(dev, buf, BUF_LEN); + cur_dev->product_string = dup_wcs(buf); + + /* VID/PID */ + cur_dev->vendor_id = dev_vid; + cur_dev->product_id = dev_pid; + + /* Release Number */ + cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey)); + + /* Interface Number (Unsupported on Mac)*/ + cur_dev->interface_number = -1; + } + } + + free(device_array); + CFRelease(device_set); + + return root; +} + +void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) +{ + /* This function is identical to the Linux version. Platform independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + +hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* This function is identical to the Linux version. Platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device * handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +static void hid_device_removal_callback(void *context, IOReturn result, + void *sender) +{ + /* Stop the Run Loop for this device. */ + hid_device *d = context; + + d->disconnected = 1; + CFRunLoopStop(d->run_loop); +} + +/* The Run Loop calls this function for each input report received. + This function puts the data into a linked list to be picked up by + hid_read(). */ +static void hid_report_callback(void *context, IOReturn result, void *sender, + IOHIDReportType report_type, uint32_t report_id, + uint8_t *report, CFIndex report_length) +{ + struct input_report *rpt; + hid_device *dev = context; + + /* Make a new Input Report object */ + rpt = calloc(1, sizeof(struct input_report)); + rpt->data = calloc(1, report_length); + memcpy(rpt->data, report, report_length); + rpt->len = report_length; + rpt->next = NULL; + + /* Lock this section */ + pthread_mutex_lock(&dev->mutex); + + /* Attach the new report object to the end of the list. */ + if (dev->input_reports == NULL) { + /* The list is empty. Put it at the root. */ + dev->input_reports = rpt; + } + else { + /* Find the end of the list and attach. */ + struct input_report *cur = dev->input_reports; + int num_queued = 0; + while (cur->next != NULL) { + cur = cur->next; + num_queued++; + } + cur->next = rpt; + + /* Pop one off if we've reached 30 in the queue. This + way we don't grow forever if the user never reads + anything from the device. */ + if (num_queued > 30) { + return_data(dev, NULL, 0); + } + } + + /* Signal a waiting thread that there is data. */ + pthread_cond_signal(&dev->condition); + + /* Unlock */ + pthread_mutex_unlock(&dev->mutex); + +} + +/* This gets called when the read_thread's run loop gets signaled by + hid_close(), and serves to stop the read_thread's run loop. */ +static void perform_signal_callback(void *context) +{ + hid_device *dev = context; + CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/ +} + +static void *read_thread(void *param) +{ + hid_device *dev = param; + SInt32 code; + + /* Move the device's run loop to this thread. */ + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); + + /* Create the RunLoopSource which is used to signal the + event loop to stop when hid_close() is called. */ + CFRunLoopSourceContext ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.version = 0; + ctx.info = dev; + ctx.perform = &perform_signal_callback; + dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx); + CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode); + + /* Store off the Run Loop so it can be stopped from hid_close() + and on device disconnection. */ + dev->run_loop = CFRunLoopGetCurrent(); + + /* Notify the main thread that the read thread is up and running. */ + pthread_barrier_wait(&dev->barrier); + + /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input + reports into the hid_report_callback(). */ + while (!dev->shutdown_thread && !dev->disconnected) { + code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); + /* Return if the device has been disconnected */ + if (code == kCFRunLoopRunFinished) { + dev->disconnected = 1; + break; + } + + + /* Break if The Run Loop returns Finished or Stopped. */ + if (code != kCFRunLoopRunTimedOut && + code != kCFRunLoopRunHandledSource) { + /* There was some kind of error. Setting + shutdown seems to make sense, but + there may be something else more appropriate */ + dev->shutdown_thread = 1; + break; + } + } + + /* Now that the read thread is stopping, Wake any threads which are + waiting on data (in hid_read_timeout()). Do this under a mutex to + make sure that a thread which is about to go to sleep waiting on + the condition actually will go to sleep before the condition is + signaled. */ + pthread_mutex_lock(&dev->mutex); + pthread_cond_broadcast(&dev->condition); + pthread_mutex_unlock(&dev->mutex); + + /* Wait here until hid_close() is called and makes it past + the call to CFRunLoopWakeUp(). This thread still needs to + be valid when that function is called on the other thread. */ + pthread_barrier_wait(&dev->shutdown_barrier); + + return NULL; +} + +/* hid_open_path() + * + * path must be a valid path to an IOHIDDevice in the IOService plane + * Example: "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/AppleUSBEHCI/PLAYSTATION(R)3 Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver" + */ +hid_device * HID_API_EXPORT hid_open_path(const char *path) +{ + hid_device *dev = NULL; + io_registry_entry_t entry = MACH_PORT_NULL; + + dev = new_hid_device(); + + /* Set up the HID Manager if it hasn't been done */ + if (hid_init() < 0) + return NULL; + + /* Get the IORegistry entry for the given path */ + entry = IORegistryEntryFromPath(kIOMasterPortDefault, path); + if (entry == MACH_PORT_NULL) { + /* Path wasn't valid (maybe device was removed?) */ + goto return_error; + } + + /* Create an IOHIDDevice for the entry */ + dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry); + if (dev->device_handle == NULL) { + /* Error creating the HID device */ + goto return_error; + } + + /* Open the IOHIDDevice */ + IOReturn ret = IOHIDDeviceOpen(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); + if (ret == kIOReturnSuccess) { + char str[32]; + + /* Create the buffers for receiving data */ + dev->max_input_report_len = (CFIndex) get_max_report_length(dev->device_handle); + dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t)); + + /* Create the Run Loop Mode for this device. + printing the reference seems to work. */ + sprintf(str, "HIDAPI_%p", dev->device_handle); + dev->run_loop_mode = + CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); + + /* Attach the device to a Run Loop */ + IOHIDDeviceRegisterInputReportCallback( + dev->device_handle, dev->input_report_buf, dev->max_input_report_len, + &hid_report_callback, dev); + IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev); + + /* Start the read thread */ + pthread_create(&dev->thread, NULL, read_thread, dev); + + /* Wait here for the read thread to be initialized. */ + pthread_barrier_wait(&dev->barrier); + + IOObjectRelease(entry); + return dev; + } + else { + goto return_error; + } + +return_error: + if (dev->device_handle != NULL) + CFRelease(dev->device_handle); + + if (entry != MACH_PORT_NULL) + IOObjectRelease(entry); + + free_hid_device(dev); + return NULL; +} + +static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length) +{ + const unsigned char *data_to_send; + size_t length_to_send; + IOReturn res; + + /* Return if the device has been disconnected. */ + if (dev->disconnected) + return -1; + + if (data[0] == 0x0) { + /* Not using numbered Reports. + Don't send the report number. */ + data_to_send = data+1; + length_to_send = length-1; + } + else { + /* Using numbered Reports. + Send the Report Number */ + data_to_send = data; + length_to_send = length; + } + + if (!dev->disconnected) { + res = IOHIDDeviceSetReport(dev->device_handle, + type, + data[0], /* Report ID*/ + data_to_send, length_to_send); + + if (res == kIOReturnSuccess) { + return length; + } + else + return -1; + } + + return -1; +} + +int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + return set_report(dev, kIOHIDReportTypeOutput, data, length); +} + +/* Helper function, so that this isn't duplicated in hid_read(). */ +static int return_data(hid_device *dev, unsigned char *data, size_t length) +{ + /* Copy the data out of the linked list item (rpt) into the + return buffer (data), and delete the liked list item. */ + struct input_report *rpt = dev->input_reports; + size_t len = (length < rpt->len)? length: rpt->len; + memcpy(data, rpt->data, len); + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + return len; +} + +static int cond_wait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + while (!dev->input_reports) { + int res = pthread_cond_wait(cond, mutex); + if (res != 0) + return res; + + /* A res of 0 means we may have been signaled or it may + be a spurious wakeup. Check to see that there's acutally + data in the queue before returning, and if not, go back + to sleep. See the pthread_cond_timedwait() man page for + details. */ + + if (dev->shutdown_thread || dev->disconnected) + return -1; + } + + return 0; +} + +static int cond_timedwait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) +{ + while (!dev->input_reports) { + int res = pthread_cond_timedwait(cond, mutex, abstime); + if (res != 0) + return res; + + /* A res of 0 means we may have been signaled or it may + be a spurious wakeup. Check to see that there's acutally + data in the queue before returning, and if not, go back + to sleep. See the pthread_cond_timedwait() man page for + details. */ + + if (dev->shutdown_thread || dev->disconnected) + return -1; + } + + return 0; + +} + +int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + int bytes_read = -1; + + /* Lock the access to the report list. */ + pthread_mutex_lock(&dev->mutex); + + /* There's an input report queued up. Return it. */ + if (dev->input_reports) { + /* Return the first one */ + bytes_read = return_data(dev, data, length); + goto ret; + } + + /* Return if the device has been disconnected. */ + if (dev->disconnected) { + bytes_read = -1; + goto ret; + } + + if (dev->shutdown_thread) { + /* This means the device has been closed (or there + has been an error. An error code of -1 should + be returned. */ + bytes_read = -1; + goto ret; + } + + /* There is no data. Go to sleep and wait for data. */ + + if (milliseconds == -1) { + /* Blocking */ + int res; + res = cond_wait(dev, &dev->condition, &dev->mutex); + if (res == 0) + bytes_read = return_data(dev, data, length); + else { + /* There was an error, or a device disconnection. */ + bytes_read = -1; + } + } + else if (milliseconds > 0) { + /* Non-blocking, but called with timeout. */ + int res; + struct timespec ts; + struct timeval tv; + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, &ts); + ts.tv_sec += milliseconds / 1000; + ts.tv_nsec += (milliseconds % 1000) * 1000000; + if (ts.tv_nsec >= 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts); + if (res == 0) + bytes_read = return_data(dev, data, length); + else if (res == ETIMEDOUT) + bytes_read = 0; + else + bytes_read = -1; + } + else { + /* Purely non-blocking */ + bytes_read = 0; + } + +ret: + /* Unlock */ + pthread_mutex_unlock(&dev->mutex); + return bytes_read; +} + +int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) +{ + /* All Nonblocking operation is handled by the library. */ + dev->blocking = !nonblock; + + return 0; +} + +int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + return set_report(dev, kIOHIDReportTypeFeature, data, length); +} + +int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + CFIndex len = length; + IOReturn res; + + /* Return if the device has been unplugged. */ + if (dev->disconnected) + return -1; + + res = IOHIDDeviceGetReport(dev->device_handle, + kIOHIDReportTypeFeature, + data[0], /* Report ID */ + data, &len); + if (res == kIOReturnSuccess) + return len; + else + return -1; +} + + +void HID_API_EXPORT hid_close(hid_device *dev) +{ + if (!dev) + return; + + /* Disconnect the report callback before close. */ + if (!dev->disconnected) { + IOHIDDeviceRegisterInputReportCallback( + dev->device_handle, dev->input_report_buf, dev->max_input_report_len, + NULL, dev); + IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev); + IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode); + IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + } + + /* Cause read_thread() to stop. */ + dev->shutdown_thread = 1; + + /* Wake up the run thread's event loop so that the thread can exit. */ + CFRunLoopSourceSignal(dev->source); + CFRunLoopWakeUp(dev->run_loop); + + /* Notify the read thread that it can shut down now. */ + pthread_barrier_wait(&dev->shutdown_barrier); + + /* Wait for read_thread() to end. */ + pthread_join(dev->thread, NULL); + + /* Close the OS handle to the device, but only if it's not + been unplugged. If it's been unplugged, then calling + IOHIDDeviceClose() will crash. */ + if (!dev->disconnected) { + IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeSeizeDevice); + } + + /* Clear out the queue of received reports. */ + pthread_mutex_lock(&dev->mutex); + while (dev->input_reports) { + return_data(dev, NULL, 0); + } + pthread_mutex_unlock(&dev->mutex); + CFRelease(dev->device_handle); + + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_manufacturer_string(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_product_string(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + return get_serial_number(dev->device_handle, string, maxlen); +} + +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + /* TODO: */ + + return 0; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + /* TODO: */ + + return NULL; +} + + + + + + + +#if 0 +static int32_t get_location_id(IOHIDDeviceRef device) +{ + return get_int_property(device, CFSTR(kIOHIDLocationIDKey)); +} + +static int32_t get_usage(IOHIDDeviceRef device) +{ + int32_t res; + res = get_int_property(device, CFSTR(kIOHIDDeviceUsageKey)); + if (!res) + res = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey)); + return res; +} + +static int32_t get_usage_page(IOHIDDeviceRef device) +{ + int32_t res; + res = get_int_property(device, CFSTR(kIOHIDDeviceUsagePageKey)); + if (!res) + res = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey)); + return res; +} + +static int get_transport(IOHIDDeviceRef device, wchar_t *buf, size_t len) +{ + return get_string_property(device, CFSTR(kIOHIDTransportKey), buf, len); +} + + +int main(void) +{ + IOHIDManagerRef mgr; + int i; + + mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + IOHIDManagerSetDeviceMatching(mgr, NULL); + IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone); + + CFSetRef device_set = IOHIDManagerCopyDevices(mgr); + + CFIndex num_devices = CFSetGetCount(device_set); + IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); + CFSetGetValues(device_set, (const void **) device_array); + + for (i = 0; i < num_devices; i++) { + IOHIDDeviceRef dev = device_array[i]; + printf("Device: %p\n", dev); + printf(" %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev)); + + wchar_t serial[256], buf[256]; + char cbuf[256]; + get_serial_number(dev, serial, 256); + + + printf(" Serial: %ls\n", serial); + printf(" Loc: %ld\n", get_location_id(dev)); + get_transport(dev, buf, 256); + printf(" Trans: %ls\n", buf); + make_path(dev, cbuf, 256); + printf(" Path: %s\n", cbuf); + + } + + return 0; +} +#endif diff --git a/vendor/github.com/karalabe/usb/hidapi/windows/hid.c b/vendor/github.com/karalabe/usb/hidapi/windows/hid.c new file mode 100644 index 00000000..4e92cc8b --- /dev/null +++ b/vendor/github.com/karalabe/usb/hidapi/windows/hid.c @@ -0,0 +1,944 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +#include + +#ifndef _NTDEF_ +typedef LONG NTSTATUS; +#endif + +#ifdef __MINGW32__ +#include +#include +#endif + +#ifdef __CYGWIN__ +#include +#define _wcsdup wcsdup +#endif + +/* The maximum number of characters that can be passed into the + HidD_Get*String() functions without it failing.*/ +#define MAX_STRING_WCHARS 0xFFF + +/*#define HIDAPI_USE_DDK*/ + +#ifdef __cplusplus +extern "C" { +#endif + #include + #include + #ifdef HIDAPI_USE_DDK + #include + #endif + + /* Copied from inc/ddk/hidclass.h, part of the Windows DDK. */ + #define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + #define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include +#include + + +#include "hidapi.h" + +#undef MIN +#define MIN(x,y) ((x) < (y)? (x): (y)) + +#ifdef _MSC_VER + /* Thanks Microsoft, but I know how to use strncpy(). */ + #pragma warning(disable:4996) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HIDAPI_USE_DDK + /* Since we're not building with the DDK, and the HID header + files aren't part of the SDK, we have to define all this + stuff here. In lookup_functions(), the function pointers + defined below are set. */ + typedef struct _HIDD_ATTRIBUTES{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + + typedef USHORT USAGE; + typedef struct _HIDP_CAPS { + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + USHORT fields_not_used_by_hidapi[10]; + } HIDP_CAPS, *PHIDP_CAPS; + typedef void* PHIDP_PREPARSED_DATA; + #define HIDP_STATUS_SUCCESS 0x110000 + + typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib); + typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length); + typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len); + typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data); + typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data); + typedef NTSTATUS (__stdcall *HidP_GetCaps_)(PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *caps); + typedef BOOLEAN (__stdcall *HidD_SetNumInputBuffers_)(HANDLE handle, ULONG number_buffers); + + static HidD_GetAttributes_ HidD_GetAttributes; + static HidD_GetSerialNumberString_ HidD_GetSerialNumberString; + static HidD_GetManufacturerString_ HidD_GetManufacturerString; + static HidD_GetProductString_ HidD_GetProductString; + static HidD_SetFeature_ HidD_SetFeature; + static HidD_GetFeature_ HidD_GetFeature; + static HidD_GetIndexedString_ HidD_GetIndexedString; + static HidD_GetPreparsedData_ HidD_GetPreparsedData; + static HidD_FreePreparsedData_ HidD_FreePreparsedData; + static HidP_GetCaps_ HidP_GetCaps; + static HidD_SetNumInputBuffers_ HidD_SetNumInputBuffers; + + static HMODULE lib_handle = NULL; + static BOOLEAN initialized = FALSE; +#endif /* HIDAPI_USE_DDK */ + +struct hid_device_ { + HANDLE device_handle; + BOOL blocking; + USHORT output_report_length; + size_t input_report_length; + void *last_error_str; + DWORD last_error_num; + BOOL read_pending; + char *read_buf; + OVERLAPPED ol; +}; + +static hid_device *new_hid_device() +{ + hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); + dev->device_handle = INVALID_HANDLE_VALUE; + dev->blocking = TRUE; + dev->output_report_length = 0; + dev->input_report_length = 0; + dev->last_error_str = NULL; + dev->last_error_num = 0; + dev->read_pending = FALSE; + dev->read_buf = NULL; + memset(&dev->ol, 0, sizeof(dev->ol)); + dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL); + + return dev; +} + +static void free_hid_device(hid_device *dev) +{ + CloseHandle(dev->ol.hEvent); + CloseHandle(dev->device_handle); + LocalFree(dev->last_error_str); + free(dev->read_buf); + free(dev); +} + +static void register_error(hid_device *device, const char *op) +{ + WCHAR *ptr, *msg; + + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPVOID)&msg, 0/*sz*/, + NULL); + + /* Get rid of the CR and LF that FormatMessage() sticks at the + end of the message. Thanks Microsoft! */ + ptr = msg; + while (*ptr) { + if (*ptr == '\r') { + *ptr = 0x0000; + break; + } + ptr++; + } + + /* Store the message off in the Device entry so that + the hid_error() function can pick it up. */ + LocalFree(device->last_error_str); + device->last_error_str = msg; +} + +#ifndef HIDAPI_USE_DDK +static int lookup_functions() +{ + lib_handle = LoadLibraryA("hid.dll"); + if (lib_handle) { +#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; + RESOLVE(HidD_GetAttributes); + RESOLVE(HidD_GetSerialNumberString); + RESOLVE(HidD_GetManufacturerString); + RESOLVE(HidD_GetProductString); + RESOLVE(HidD_SetFeature); + RESOLVE(HidD_GetFeature); + RESOLVE(HidD_GetIndexedString); + RESOLVE(HidD_GetPreparsedData); + RESOLVE(HidD_FreePreparsedData); + RESOLVE(HidP_GetCaps); + RESOLVE(HidD_SetNumInputBuffers); +#undef RESOLVE + } + else + return -1; + + return 0; +} +#endif + +static HANDLE open_device(const char *path, BOOL enumerate) +{ + HANDLE handle; + DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ); + DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; + + handle = CreateFileA(path, + desired_access, + share_mode, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/ + 0); + + return handle; +} + +int HID_API_EXPORT hid_init(void) +{ +#ifndef HIDAPI_USE_DDK + if (!initialized) { + if (lookup_functions() < 0) { + hid_exit(); + return -1; + } + initialized = TRUE; + } +#endif + return 0; +} + +int HID_API_EXPORT hid_exit(void) +{ +#ifndef HIDAPI_USE_DDK + if (lib_handle) + FreeLibrary(lib_handle); + lib_handle = NULL; + initialized = FALSE; +#endif + return 0; +} + +struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ + BOOL res; + struct hid_device_info *root = NULL; /* return object */ + struct hid_device_info *cur_dev = NULL; + + /* Windows objects for interacting with the driver. */ + GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; + SP_DEVINFO_DATA devinfo_data; + SP_DEVICE_INTERFACE_DATA device_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; + HDEVINFO device_info_set = INVALID_HANDLE_VALUE; + int device_index = 0; + int i; + + if (hid_init() < 0) + return NULL; + + /* Initialize the Windows objects. */ + memset(&devinfo_data, 0x0, sizeof(devinfo_data)); + devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); + device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + /* Get information for all the devices belonging to the HID class. */ + device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + /* Iterate over each device in the HID class, looking for the right one. */ + + for (;;) { + HANDLE write_handle = INVALID_HANDLE_VALUE; + DWORD required_size = 0; + HIDD_ATTRIBUTES attrib; + + res = SetupDiEnumDeviceInterfaces(device_info_set, + NULL, + &InterfaceClassGuid, + device_index, + &device_interface_data); + + if (!res) { + /* A return of FALSE from this function means that + there are no more devices. */ + break; + } + + /* Call with 0-sized detail size, and let the function + tell us how long the detail struct needs to be. The + size is put in &required_size. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + NULL, + 0, + &required_size, + NULL); + + /* Allocate a long enough structure for device_interface_detail_data. */ + device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); + device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + + /* Get the detailed data for this device. The detail data gives us + the device path for this device, which is then passed into + CreateFile() to get a handle to the device. */ + res = SetupDiGetDeviceInterfaceDetailA(device_info_set, + &device_interface_data, + device_interface_detail_data, + required_size, + NULL, + NULL); + + if (!res) { + /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); + Continue to the next device. */ + goto cont; + } + + /* Make sure this device is of Setup Class "HIDClass" and has a + driver bound to it. */ + for (i = 0; ; i++) { + char driver_name[256]; + + /* Populate devinfo_data. This function will return failure + when there are no more interfaces left. */ + res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); + if (!res) + goto cont; + + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (!res) + goto cont; + + if (strcmp(driver_name, "HIDClass") == 0) { + /* See if there's a driver bound. */ + res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, + SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); + if (res) + break; + } + } + + //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); + + /* Open a handle to the device */ + write_handle = open_device(device_interface_detail_data->DevicePath, TRUE); + + /* Check validity of write_handle. */ + if (write_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + //register_error(dev, "CreateFile"); + goto cont_close; + } + + + /* Get the Vendor ID and Product ID for this device. */ + attrib.Size = sizeof(HIDD_ATTRIBUTES); + HidD_GetAttributes(write_handle, &attrib); + //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + + /* Check the VID/PID to see if we should add this + device to the enumeration list. */ + if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && + (product_id == 0x0 || attrib.ProductID == product_id)) { + + #define WSTR_LEN 512 + const char *str; + struct hid_device_info *tmp; + PHIDP_PREPARSED_DATA pp_data = NULL; + HIDP_CAPS caps; + BOOLEAN res; + NTSTATUS nt_res; + wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ + size_t len; + + /* VID/PID match. Create the record. */ + tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); + if (cur_dev) { + cur_dev->next = tmp; + } + else { + root = tmp; + } + cur_dev = tmp; + + /* Get the Usage Page and Usage for this device. */ + res = HidD_GetPreparsedData(write_handle, &pp_data); + if (res) { + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res == HIDP_STATUS_SUCCESS) { + cur_dev->usage_page = caps.UsagePage; + cur_dev->usage = caps.Usage; + } + + HidD_FreePreparsedData(pp_data); + } + + /* Fill out the record */ + cur_dev->next = NULL; + str = device_interface_detail_data->DevicePath; + if (str) { + len = strlen(str); + cur_dev->path = (char*) calloc(len+1, sizeof(char)); + strncpy(cur_dev->path, str, sizeof(cur_dev->path)); + cur_dev->path[len] = '\0'; + } + else + cur_dev->path = NULL; + + /* Serial Number */ + res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->serial_number = _wcsdup(wstr); + } + + /* Manufacturer String */ + res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->manufacturer_string = _wcsdup(wstr); + } + + /* Product String */ + res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); + wstr[WSTR_LEN-1] = 0x0000; + if (res) { + cur_dev->product_string = _wcsdup(wstr); + } + + /* VID/PID */ + cur_dev->vendor_id = attrib.VendorID; + cur_dev->product_id = attrib.ProductID; + + /* Release Number */ + cur_dev->release_number = attrib.VersionNumber; + + /* Interface Number. It can sometimes be parsed out of the path + on Windows if a device has multiple interfaces. See + http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or + search for "Hardware IDs for HID Devices" at MSDN. If it's not + in the path, it's set to -1. */ + cur_dev->interface_number = -1; + if (cur_dev->path) { + char *interface_component = strstr(cur_dev->path, "&mi_"); + if (interface_component) { + char *hex_str = interface_component + 4; + char *endptr = NULL; + cur_dev->interface_number = strtol(hex_str, &endptr, 16); + if (endptr == hex_str) { + /* The parsing failed. Set interface_number to -1. */ + cur_dev->interface_number = -1; + } + } + } + } + +cont_close: + CloseHandle(write_handle); +cont: + /* We no longer need the detail data. It can be freed */ + free(device_interface_detail_data); + + device_index++; + + } + + /* Close the device information handle. */ + SetupDiDestroyDeviceInfoList(device_info_set); + + return root; + +} + +void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) +{ + /* TODO: Merge this with the Linux version. This function is platform-independent. */ + struct hid_device_info *d = devs; + while (d) { + struct hid_device_info *next = d->next; + free(d->path); + free(d->serial_number); + free(d->manufacturer_string); + free(d->product_string); + free(d); + d = next; + } +} + + +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + /* TODO: Merge this functions with the Linux version. This function should be platform independent. */ + struct hid_device_info *devs, *cur_dev; + const char *path_to_open = NULL; + hid_device *handle = NULL; + + devs = hid_enumerate(vendor_id, product_id); + cur_dev = devs; + while (cur_dev) { + if (cur_dev->vendor_id == vendor_id && + cur_dev->product_id == product_id) { + if (serial_number) { + if (wcscmp(serial_number, cur_dev->serial_number) == 0) { + path_to_open = cur_dev->path; + break; + } + } + else { + path_to_open = cur_dev->path; + break; + } + } + cur_dev = cur_dev->next; + } + + if (path_to_open) { + /* Open the device */ + handle = hid_open_path(path_to_open); + } + + hid_free_enumeration(devs); + + return handle; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path) +{ + hid_device *dev; + HIDP_CAPS caps; + PHIDP_PREPARSED_DATA pp_data = NULL; + BOOLEAN res; + NTSTATUS nt_res; + + if (hid_init() < 0) { + return NULL; + } + + dev = new_hid_device(); + + /* Open a handle to the device */ + dev->device_handle = open_device(path, FALSE); + + /* Check validity of write_handle. */ + if (dev->device_handle == INVALID_HANDLE_VALUE) { + /* Unable to open the device. */ + register_error(dev, "CreateFile"); + goto err; + } + + /* Set the Input Report buffer size to 64 reports. */ + res = HidD_SetNumInputBuffers(dev->device_handle, 64); + if (!res) { + register_error(dev, "HidD_SetNumInputBuffers"); + goto err; + } + + /* Get the Input Report length for the device. */ + res = HidD_GetPreparsedData(dev->device_handle, &pp_data); + if (!res) { + register_error(dev, "HidD_GetPreparsedData"); + goto err; + } + nt_res = HidP_GetCaps(pp_data, &caps); + if (nt_res != HIDP_STATUS_SUCCESS) { + register_error(dev, "HidP_GetCaps"); + goto err_pp_data; + } + dev->output_report_length = caps.OutputReportByteLength; + dev->input_report_length = caps.InputReportByteLength; + HidD_FreePreparsedData(pp_data); + + dev->read_buf = (char*) malloc(dev->input_report_length); + + return dev; + +err_pp_data: + HidD_FreePreparsedData(pp_data); +err: + free_hid_device(dev); + return NULL; +} + +int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) +{ + DWORD bytes_written; + BOOL res; + + OVERLAPPED ol; + unsigned char *buf; + memset(&ol, 0, sizeof(ol)); + + /* Make sure the right number of bytes are passed to WriteFile. Windows + expects the number of bytes which are in the _longest_ report (plus + one for the report number) bytes even if the data is a report + which is shorter than that. Windows gives us this value in + caps.OutputReportByteLength. If a user passes in fewer bytes than this, + create a temporary buffer which is the proper size. */ + if (length >= dev->output_report_length) { + /* The user passed the right number of bytes. Use the buffer as-is. */ + buf = (unsigned char *) data; + } else { + /* Create a temporary buffer and copy the user's data + into it, padding the rest with zeros. */ + buf = (unsigned char *) malloc(dev->output_report_length); + memcpy(buf, data, length); + memset(buf + length, 0, dev->output_report_length - length); + length = dev->output_report_length; + } + + res = WriteFile(dev->device_handle, buf, length, NULL, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + } + + /* Wait here until the write is done. This makes + hid_write() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = -1; + goto end_of_function; + } + +end_of_function: + if (buf != data) + free(buf); + + return bytes_written; +} + + +int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) +{ + DWORD bytes_read = 0; + size_t copy_len = 0; + BOOL res; + + /* Copy the handle for convenience. */ + HANDLE ev = dev->ol.hEvent; + + if (!dev->read_pending) { + /* Start an Overlapped I/O read. */ + dev->read_pending = TRUE; + memset(dev->read_buf, 0, dev->input_report_length); + ResetEvent(ev); + res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* ReadFile() has failed. + Clean up and return error. */ + CancelIo(dev->device_handle); + dev->read_pending = FALSE; + goto end_of_function; + } + } + } + + if (milliseconds >= 0) { + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; + } + } + + /* Either WaitForSingleObject() told us that ReadFile has completed, or + we are in non-blocking mode. Get the number of bytes read. The actual + data has been copied to the data[] array which was passed to ReadFile(). */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + + /* Set pending back to false, even if GetOverlappedResult() returned error. */ + dev->read_pending = FALSE; + + if (res && bytes_read > 0) { + if (dev->read_buf[0] == 0x0) { + /* If report numbers aren't being used, but Windows sticks a report + number (0x0) on the beginning of the report anyway. To make this + work like the other platforms, and to make it work more like the + HID spec, we'll skip over this byte. */ + bytes_read--; + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf+1, copy_len); + } + else { + /* Copy the whole buffer, report number and all. */ + copy_len = length > bytes_read ? bytes_read : length; + memcpy(data, dev->read_buf, copy_len); + } + } + +end_of_function: + if (!res) { + register_error(dev, "GetOverlappedResult"); + return -1; + } + + return copy_len; +} + +int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length) +{ + return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0); +} + +int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock) +{ + dev->blocking = !nonblock; + return 0; /* Success */ +} + +int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) +{ + BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length); + if (!res) { + register_error(dev, "HidD_SetFeature"); + return -1; + } + + return length; +} + + +int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) +{ + BOOL res; +#if 0 + res = HidD_GetFeature(dev->device_handle, data, length); + if (!res) { + register_error(dev, "HidD_GetFeature"); + return -1; + } + return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */ +#else + DWORD bytes_returned; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + res = DeviceIoControl(dev->device_handle, + IOCTL_HID_GET_FEATURE, + data, length, + data, length, + &bytes_returned, &ol); + + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* DeviceIoControl() failed. Return error. */ + register_error(dev, "Send Feature Report DeviceIoControl"); + return -1; + } + } + + /* Wait here until the write is done. This makes + hid_get_feature_report() synchronous. */ + res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/); + if (!res) { + /* The operation failed. */ + register_error(dev, "Send Feature Report GetOverLappedResult"); + return -1; + } + + /* bytes_returned does not include the first byte which contains the + report ID. The data buffer actually contains one more byte than + bytes_returned. */ + bytes_returned++; + + return bytes_returned; +#endif +} + +void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) +{ + if (!dev) + return; + CancelIo(dev->device_handle); + free_hid_device(dev); +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetManufacturerString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetProductString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetSerialNumberString"); + return -1; + } + + return 0; +} + +int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + BOOL res; + + res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)); + if (!res) { + register_error(dev, "HidD_GetIndexedString"); + return -1; + } + + return 0; +} + + +HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) +{ + return (wchar_t*)dev->last_error_str; +} + + +/*#define PICPGM*/ +/*#define S11*/ +#define P32 +#ifdef S11 + unsigned short VendorID = 0xa0a0; + unsigned short ProductID = 0x0001; +#endif + +#ifdef P32 + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x3f; +#endif + + +#ifdef PICPGM + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x0033; +#endif + + +#if 0 +int __cdecl main(int argc, char* argv[]) +{ + int res; + unsigned char buf[65]; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + /* Set up the command buffer. */ + memset(buf,0x00,sizeof(buf)); + buf[0] = 0; + buf[1] = 0x81; + + + /* Open the device. */ + int handle = open(VendorID, ProductID, L"12345"); + if (handle < 0) + printf("unable to open device\n"); + + + /* Toggle LED (cmd 0x80) */ + buf[1] = 0x80; + res = write(handle, buf, 65); + if (res < 0) + printf("Unable to write()\n"); + + /* Request state (cmd 0x81) */ + buf[1] = 0x81; + write(handle, buf, 65); + if (res < 0) + printf("Unable to write() (2)\n"); + + /* Read requested state */ + read(handle, buf, 65); + if (res < 0) + printf("Unable to read()\n"); + + /* Print out the returned buffer. */ + for (int i = 0; i < 4; i++) + printf("buf[%d]: %d\n", i, buf[i]); + + return 0; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/vendor/github.com/karalabe/usb/libs.go b/vendor/github.com/karalabe/usb/libs.go new file mode 100644 index 00000000..6446acee --- /dev/null +++ b/vendor/github.com/karalabe/usb/libs.go @@ -0,0 +1,74 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build freebsd,cgo linux,cgo darwin,!ios,cgo windows,cgo + +package usb + +/* +#cgo CFLAGS: -I./hidapi/hidapi +#cgo CFLAGS: -I./libusb/libusb +#cgo CFLAGS: -DDEFAULT_VISIBILITY="" +#cgo CFLAGS: -DPOLL_NFDS_TYPE=int + +#cgo linux CFLAGS: -DOS_LINUX -D_GNU_SOURCE -DHAVE_SYS_TIME_H +#cgo linux,!android LDFLAGS: -lrt +#cgo darwin CFLAGS: -DOS_DARWIN -DHAVE_SYS_TIME_H +#cgo darwin LDFLAGS: -framework CoreFoundation -framework IOKit -lobjc +#cgo windows CFLAGS: -DOS_WINDOWS +#cgo windows LDFLAGS: -lsetupapi +#cgo freebsd CFLAGS: -DOS_FREEBSD +#cgo freebsd LDFLAGS: -lusb +#cgo openbsd CFLAGS: -DOS_OPENBSD + +#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(DOS_FREEBSD) || defined(OS_OPENBSD) + #include + #include "os/threads_posix.c" + #include "os/poll_posix.c" +#elif defined(OS_WINDOWS) + #include "os/poll_windows.c" + #include "os/threads_windows.c" +#endif + +#ifdef OS_LINUX + #include "os/linux_usbfs.c" + #include "os/linux_netlink.c" + #include "hidapi/libusb/hid.c" +#elif OS_DARWIN + #include "os/darwin_usb.c" + #include "hidapi/mac/hid.c" +#elif OS_WINDOWS + #include "os/windows_nt_common.c" + #include "os/windows_usbdk.c" + #include "os/windows_winusb.c" + #include "hidapi/windows/hid.c" +#elif OS_FREEBSD + #include + #include "hidapi/libusb/hid.c" +#elif DOS_OPENBSD + #include "os/openbsd_usb.c" + #include "hidapi/libusb/hid.c" +#endif + +#ifndef OS_FREEBSD + #include "core.c" + #include "descriptor.c" + #include "hotplug.c" + #include "io.c" + #include "strerror.c" + #include "sync.c" +#endif +*/ +import "C" diff --git a/vendor/github.com/karalabe/usb/libusb/AUTHORS b/vendor/github.com/karalabe/usb/libusb/AUTHORS new file mode 100644 index 00000000..e90ad9bb --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/AUTHORS @@ -0,0 +1,119 @@ +Copyright © 2001 Johannes Erdfelt +Copyright © 2007-2009 Daniel Drake +Copyright © 2010-2012 Peter Stuge +Copyright © 2008-2016 Nathan Hjelm +Copyright © 2009-2013 Pete Batard +Copyright © 2009-2013 Ludovic Rousseau +Copyright © 2010-2012 Michael Plante +Copyright © 2011-2013 Hans de Goede +Copyright © 2012-2013 Martin Pieuchot +Copyright © 2012-2013 Toby Gray +Copyright © 2013-2018 Chris Dickens + +Other contributors: +Adrian Bunk +Akshay Jaggi +Alan Ott +Alan Stern +Alex Vatchenko +Andrew Fernandes +Andy Chunyu +Andy McFadden +Angus Gratton +Anil Nair +Anthony Clay +Antonio Ospite +Artem Egorkine +Aurelien Jarno +Bastien Nocera +Bei Zhang +Benjamin Dobell +Brent Rector +Carl Karsten +Christophe Zeitouny +Colin Walters +Dave Camarillo +David Engraf +David Moore +Davidlohr Bueso +Dmitry Fleytman +Doug Johnston +Evan Hunter +Federico Manzan +Felipe Balbi +Florian Albrechtskirchinger +Francesco Montorsi +Francisco Facioni +Gaurav Gupta +Graeme Gill +Gustavo Zacarias +Hans Ulrich Niedermann +Hector Martin +Hoi-Ho Chan +Ilya Konstantinov +Jakub Klama +James Hanko +Jeffrey Nichols +Johann Richard +John Sheu +Jonathon Jongsma +Joost Muller +Josh Gao +Joshua Blake +Justin Bischoff +KIMURA Masaru +Karsten Koenig +Konrad Rzepecki +Kuangye Guo +Lars Kanis +Lars Wirzenius +Lei Chen +Luca Longinotti +Marcus Meissner +Markus Heidelberg +Martin Ettl +Martin Koegler +Matthew Stapleton +Matthias Bolte +Michel Zou +Mike Frysinger +Mikhail Gusarov +Morgan Leborgne +Moritz Fischer +Ларионов Даниил +Nicholas Corgan +Omri Iluz +Orin Eman +Paul Fertser +Pekka Nikander +Rob Walker +Romain Vimont +Roman Kalashnikov +Sameeh Jubran +Sean McBride +Sebastian Pipping +Sergey Serb +Simon Haggett +Simon Newton +Stefan Agner +Stefan Tauner +Steinar H. Gunderson +Thomas Röfer +Tim Hutt +Tim Roberts +Tobias Klauser +Toby Peterson +Tormod Volden +Trygve Laugstøl +Uri Lublin +Vasily Khoruzhick +Vegard Storheil Eriksen +Venkatesh Shukla +Vianney le Clément de Saint-Marcq +Victor Toso +Vitali Lovich +William Skellenger +Xiaofan Chen +Zoltán Kovács +Роман Донченко +parafin diff --git a/vendor/github.com/karalabe/usb/libusb/COPYING b/vendor/github.com/karalabe/usb/libusb/COPYING new file mode 100644 index 00000000..5ab7695a --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/config.h b/vendor/github.com/karalabe/usb/libusb/libusb/config.h new file mode 100644 index 00000000..e004f03c --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/config.h @@ -0,0 +1,3 @@ +#ifndef CONFIG_H +#define CONFIG_H +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/core.c b/vendor/github.com/karalabe/usb/libusb/libusb/core.c new file mode 100644 index 00000000..50f92f6b --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/core.c @@ -0,0 +1,2579 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Core functions for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYSLOG_H +#include +#endif + +#ifdef __ANDROID__ +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +struct libusb_context *usbi_default_context = NULL; +static const struct libusb_version libusb_version_internal = + { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO, + LIBUSB_RC, "http://libusb.info" }; +static int default_context_refcnt = 0; +static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER; +static struct timespec timestamp_origin = { 0, 0 }; + +usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER; +struct list_head active_contexts_list; + +/** + * \mainpage libusb-1.0 API Reference + * + * \section intro Introduction + * + * libusb is an open source library that allows you to communicate with USB + * devices from userspace. For more info, see the + * libusb homepage. + * + * This documentation is aimed at application developers wishing to + * communicate with USB peripherals from their own software. After reviewing + * this documentation, feedback and questions can be sent to the + * libusb-devel mailing list. + * + * This documentation assumes knowledge of how to operate USB devices from + * a software standpoint (descriptors, configurations, interfaces, endpoints, + * control/bulk/interrupt/isochronous transfers, etc). Full information + * can be found in the USB 3.0 + * Specification which is available for free download. You can probably + * find less verbose introductions by searching the web. + * + * \section API Application Programming Interface (API) + * + * See the \ref libusb_api page for a complete list of the libusb functions. + * + * \section features Library features + * + * - All transfer types supported (control/bulk/interrupt/isochronous) + * - 2 transfer interfaces: + * -# Synchronous (simple) + * -# Asynchronous (more complicated, but more powerful) + * - Thread safe (although the asynchronous interface means that you + * usually won't need to thread) + * - Lightweight with lean API + * - Compatible with libusb-0.1 through the libusb-compat-0.1 translation layer + * - Hotplug support (on some platforms). See \ref libusb_hotplug. + * + * \section gettingstarted Getting Started + * + * To begin reading the API documentation, start with the Modules page which + * links to the different categories of libusb's functionality. + * + * One decision you will have to make is whether to use the synchronous + * or the asynchronous data transfer interface. The \ref libusb_io documentation + * provides some insight into this topic. + * + * Some example programs can be found in the libusb source distribution under + * the "examples" subdirectory. The libusb homepage includes a list of + * real-life project examples which use libusb. + * + * \section errorhandling Error handling + * + * libusb functions typically return 0 on success or a negative error code + * on failure. These negative error codes relate to LIBUSB_ERROR constants + * which are listed on the \ref libusb_misc "miscellaneous" documentation page. + * + * \section msglog Debug message logging + * + * libusb uses stderr for all logging. By default, logging is set to NONE, + * which means that no output will be produced. However, unless the library + * has been compiled with logging disabled, then any application calls to + * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level), or the setting of the + * environmental variable LIBUSB_DEBUG outside of the application, can result + * in logging being produced. Your application should therefore not close + * stderr, but instead direct it to the null device if its output is + * undesirable. + * + * The libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) function can be + * used to enable logging of certain messages. Under standard configuration, + * libusb doesn't really log much so you are advised to use this function + * to enable all error/warning/ informational messages. It will help debug + * problems with your software. + * + * The logged messages are unstructured. There is no one-to-one correspondence + * between messages being logged and success or failure return codes from + * libusb functions. There is no format to the messages, so you should not + * try to capture or parse them. They are not and will not be localized. + * These messages are not intended to being passed to your application user; + * instead, you should interpret the error codes returned from libusb functions + * and provide appropriate notification to the user. The messages are simply + * there to aid you as a programmer, and if you're confused because you're + * getting a strange error code from a libusb function, enabling message + * logging may give you a suitable explanation. + * + * The LIBUSB_DEBUG environment variable can be used to enable message logging + * at run-time. This environment variable should be set to a log level number, + * which is interpreted the same as the + * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) parameter. When this + * environment variable is set, the message logging verbosity level is fixed + * and libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) effectively does + * nothing. + * + * libusb can be compiled without any logging functions, useful for embedded + * systems. In this case, libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) + * and the LIBUSB_DEBUG environment variable have no effects. + * + * libusb can also be compiled with verbose debugging messages always. When + * the library is compiled in this way, all messages of all verbosities are + * always logged. libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) and + * the LIBUSB_DEBUG environment variable have no effects. + * + * \section remarks Other remarks + * + * libusb does have imperfections. The \ref libusb_caveats "caveats" page attempts + * to document these. + */ + +/** + * \page libusb_caveats Caveats + * + * \section fork Fork considerations + * + * libusb is not designed to work across fork() calls. Depending on + * the platform, there may be resources in the parent process that are not + * available to the child (e.g. the hotplug monitor thread on Linux). In + * addition, since the parent and child will share libusb's internal file + * descriptors, using libusb in any way from the child could cause the parent + * process's \ref libusb_context to get into an inconsistent state. + * + * On Linux, libusb's file descriptors will be marked as CLOEXEC, which means + * that it is safe to fork() and exec() without worrying about the child + * process needing to clean up state or having access to these file descriptors. + * Other platforms may not be so forgiving, so consider yourself warned! + * + * \section devresets Device resets + * + * The libusb_reset_device() function allows you to reset a device. If your + * program has to call such a function, it should obviously be aware that + * the reset will cause device state to change (e.g. register values may be + * reset). + * + * The problem is that any other program could reset the device your program + * is working with, at any time. libusb does not offer a mechanism to inform + * you when this has happened, so if someone else resets your device it will + * not be clear to your own program why the device state has changed. + * + * Ultimately, this is a limitation of writing drivers in userspace. + * Separation from the USB stack in the underlying kernel makes it difficult + * for the operating system to deliver such notifications to your program. + * The Linux kernel USB stack allows such reset notifications to be delivered + * to in-kernel USB drivers, but it is not clear how such notifications could + * be delivered to second-class drivers that live in userspace. + * + * \section blockonly Blocking-only functionality + * + * The functionality listed below is only available through synchronous, + * blocking functions. There are no asynchronous/non-blocking alternatives, + * and no clear ways of implementing these. + * + * - Configuration activation (libusb_set_configuration()) + * - Interface/alternate setting activation (libusb_set_interface_alt_setting()) + * - Releasing of interfaces (libusb_release_interface()) + * - Clearing of halt/stall condition (libusb_clear_halt()) + * - Device resets (libusb_reset_device()) + * + * \section configsel Configuration selection and handling + * + * When libusb presents a device handle to an application, there is a chance + * that the corresponding device may be in unconfigured state. For devices + * with multiple configurations, there is also a chance that the configuration + * currently selected is not the one that the application wants to use. + * + * The obvious solution is to add a call to libusb_set_configuration() early + * on during your device initialization routines, but there are caveats to + * be aware of: + * -# If the device is already in the desired configuration, calling + * libusb_set_configuration() using the same configuration value will cause + * a lightweight device reset. This may not be desirable behaviour. + * -# In the case where the desired configuration is already active, libusb + * may not even be able to perform a lightweight device reset. For example, + * take my USB keyboard with fingerprint reader: I'm interested in driving + * the fingerprint reader interface through libusb, but the kernel's + * USB-HID driver will almost always have claimed the keyboard interface. + * Because the kernel has claimed an interface, it is not even possible to + * perform the lightweight device reset, so libusb_set_configuration() will + * fail. (Luckily the device in question only has a single configuration.) + * -# libusb will be unable to set a configuration if other programs or + * drivers have claimed interfaces. In particular, this means that kernel + * drivers must be detached from all the interfaces before + * libusb_set_configuration() may succeed. + * + * One solution to some of the above problems is to consider the currently + * active configuration. If the configuration we want is already active, then + * we don't have to select any configuration: +\code +cfg = -1; +libusb_get_configuration(dev, &cfg); +if (cfg != desired) + libusb_set_configuration(dev, desired); +\endcode + * + * This is probably suitable for most scenarios, but is inherently racy: + * another application or driver may change the selected configuration + * after the libusb_get_configuration() call. + * + * Even in cases where libusb_set_configuration() succeeds, consider that other + * applications or drivers may change configuration after your application + * calls libusb_set_configuration(). + * + * One possible way to lock your device into a specific configuration is as + * follows: + * -# Set the desired configuration (or use the logic above to realise that + * it is already in the desired configuration) + * -# Claim the interface that you wish to use + * -# Check that the currently active configuration is the one that you want + * to use. + * + * The above method works because once an interface is claimed, no application + * or driver is able to select another configuration. + * + * \section earlycomp Early transfer completion + * + * NOTE: This section is currently Linux-centric. I am not sure if any of these + * considerations apply to Darwin or other platforms. + * + * When a transfer completes early (i.e. when less data is received/sent in + * any one packet than the transfer buffer allows for) then libusb is designed + * to terminate the transfer immediately, not transferring or receiving any + * more data unless other transfers have been queued by the user. + * + * On legacy platforms, libusb is unable to do this in all situations. After + * the incomplete packet occurs, "surplus" data may be transferred. For recent + * versions of libusb, this information is kept (the data length of the + * transfer is updated) and, for device-to-host transfers, any surplus data was + * added to the buffer. Still, this is not a nice solution because it loses the + * information about the end of the short packet, and the user probably wanted + * that surplus data to arrive in the next logical transfer. + * + * \section zlp Zero length packets + * + * - libusb is able to send a packet of zero length to an endpoint simply by + * submitting a transfer of zero length. + * - The \ref libusb_transfer_flags::LIBUSB_TRANSFER_ADD_ZERO_PACKET + * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently only supported on Linux. + */ + +/** + * \page libusb_contexts Contexts + * + * It is possible that libusb may be used simultaneously from two independent + * libraries linked into the same executable. For example, if your application + * has a plugin-like system which allows the user to dynamically load a range + * of modules into your program, it is feasible that two independently + * developed modules may both use libusb. + * + * libusb is written to allow for these multiple user scenarios. The two + * "instances" of libusb will not interfere: libusb_set_option() calls + * from one user will not affect the same settings for other users, other + * users can continue using libusb after one of them calls libusb_exit(), etc. + * + * This is made possible through libusb's context concept. When you + * call libusb_init(), you are (optionally) given a context. You can then pass + * this context pointer back into future libusb functions. + * + * In order to keep things simple for more simplistic applications, it is + * legal to pass NULL to all functions requiring a context pointer (as long as + * you're sure no other code will attempt to use libusb from the same process). + * When you pass NULL, the default context will be used. The default context + * is created the first time a process calls libusb_init() when no other + * context is alive. Contexts are destroyed during libusb_exit(). + * + * The default context is reference-counted and can be shared. That means that + * if libusb_init(NULL) is called twice within the same process, the two + * users end up sharing the same context. The deinitialization and freeing of + * the default context will only happen when the last user calls libusb_exit(). + * In other words, the default context is created and initialized when its + * reference count goes from 0 to 1, and is deinitialized and destroyed when + * its reference count goes from 1 to 0. + * + * You may be wondering why only a subset of libusb functions require a + * context pointer in their function definition. Internally, libusb stores + * context pointers in other objects (e.g. libusb_device instances) and hence + * can infer the context from those objects. + */ + + /** + * \page libusb_api Application Programming Interface + * + * This is the complete list of libusb functions, structures and + * enumerations in alphabetical order. + * + * \section Functions + * - libusb_alloc_streams() + * - libusb_alloc_transfer() + * - libusb_attach_kernel_driver() + * - libusb_bulk_transfer() + * - libusb_cancel_transfer() + * - libusb_claim_interface() + * - libusb_clear_halt() + * - libusb_close() + * - libusb_control_transfer() + * - libusb_control_transfer_get_data() + * - libusb_control_transfer_get_setup() + * - libusb_cpu_to_le16() + * - libusb_detach_kernel_driver() + * - libusb_dev_mem_alloc() + * - libusb_dev_mem_free() + * - libusb_error_name() + * - libusb_event_handler_active() + * - libusb_event_handling_ok() + * - libusb_exit() + * - libusb_fill_bulk_stream_transfer() + * - libusb_fill_bulk_transfer() + * - libusb_fill_control_setup() + * - libusb_fill_control_transfer() + * - libusb_fill_interrupt_transfer() + * - libusb_fill_iso_transfer() + * - libusb_free_bos_descriptor() + * - libusb_free_config_descriptor() + * - libusb_free_container_id_descriptor() + * - libusb_free_device_list() + * - libusb_free_pollfds() + * - libusb_free_ss_endpoint_companion_descriptor() + * - libusb_free_ss_usb_device_capability_descriptor() + * - libusb_free_streams() + * - libusb_free_transfer() + * - libusb_free_usb_2_0_extension_descriptor() + * - libusb_get_active_config_descriptor() + * - libusb_get_bos_descriptor() + * - libusb_get_bus_number() + * - libusb_get_config_descriptor() + * - libusb_get_config_descriptor_by_value() + * - libusb_get_configuration() + * - libusb_get_container_id_descriptor() + * - libusb_get_descriptor() + * - libusb_get_device() + * - libusb_get_device_address() + * - libusb_get_device_descriptor() + * - libusb_get_device_list() + * - libusb_get_device_speed() + * - libusb_get_iso_packet_buffer() + * - libusb_get_iso_packet_buffer_simple() + * - libusb_get_max_iso_packet_size() + * - libusb_get_max_packet_size() + * - libusb_get_next_timeout() + * - libusb_get_parent() + * - libusb_get_pollfds() + * - libusb_get_port_number() + * - libusb_get_port_numbers() + * - libusb_get_port_path() + * - libusb_get_ss_endpoint_companion_descriptor() + * - libusb_get_ss_usb_device_capability_descriptor() + * - libusb_get_string_descriptor() + * - libusb_get_string_descriptor_ascii() + * - libusb_get_usb_2_0_extension_descriptor() + * - libusb_get_version() + * - libusb_handle_events() + * - libusb_handle_events_completed() + * - libusb_handle_events_locked() + * - libusb_handle_events_timeout() + * - libusb_handle_events_timeout_completed() + * - libusb_has_capability() + * - libusb_hotplug_deregister_callback() + * - libusb_hotplug_register_callback() + * - libusb_init() + * - libusb_interrupt_event_handler() + * - libusb_interrupt_transfer() + * - libusb_kernel_driver_active() + * - libusb_lock_events() + * - libusb_lock_event_waiters() + * - libusb_open() + * - libusb_open_device_with_vid_pid() + * - libusb_pollfds_handle_timeouts() + * - libusb_ref_device() + * - libusb_release_interface() + * - libusb_reset_device() + * - libusb_set_auto_detach_kernel_driver() + * - libusb_set_configuration() + * - libusb_set_debug() + * - libusb_set_interface_alt_setting() + * - libusb_set_iso_packet_lengths() + * - libusb_set_option() + * - libusb_setlocale() + * - libusb_set_pollfd_notifiers() + * - libusb_strerror() + * - libusb_submit_transfer() + * - libusb_transfer_get_stream_id() + * - libusb_transfer_set_stream_id() + * - libusb_try_lock_events() + * - libusb_unlock_events() + * - libusb_unlock_event_waiters() + * - libusb_unref_device() + * - libusb_wait_for_event() + * + * \section Structures + * - libusb_bos_descriptor + * - libusb_bos_dev_capability_descriptor + * - libusb_config_descriptor + * - libusb_container_id_descriptor + * - \ref libusb_context + * - libusb_control_setup + * - \ref libusb_device + * - libusb_device_descriptor + * - \ref libusb_device_handle + * - libusb_endpoint_descriptor + * - libusb_interface + * - libusb_interface_descriptor + * - libusb_iso_packet_descriptor + * - libusb_pollfd + * - libusb_ss_endpoint_companion_descriptor + * - libusb_ss_usb_device_capability_descriptor + * - libusb_transfer + * - libusb_usb_2_0_extension_descriptor + * - libusb_version + * + * \section Enums + * - \ref libusb_bos_type + * - \ref libusb_capability + * - \ref libusb_class_code + * - \ref libusb_descriptor_type + * - \ref libusb_endpoint_direction + * - \ref libusb_error + * - \ref libusb_iso_sync_type + * - \ref libusb_iso_usage_type + * - \ref libusb_log_level + * - \ref libusb_option + * - \ref libusb_request_recipient + * - \ref libusb_request_type + * - \ref libusb_speed + * - \ref libusb_ss_usb_device_capability_attributes + * - \ref libusb_standard_request + * - \ref libusb_supported_speed + * - \ref libusb_transfer_flags + * - \ref libusb_transfer_status + * - \ref libusb_transfer_type + * - \ref libusb_usb_2_0_extension_attributes + */ + +/** + * @defgroup libusb_lib Library initialization/deinitialization + * This page details how to initialize and deinitialize libusb. Initialization + * must be performed before using any libusb functionality, and similarly you + * must not call any libusb functions after deinitialization. + */ + +/** + * @defgroup libusb_dev Device handling and enumeration + * The functionality documented below is designed to help with the following + * operations: + * - Enumerating the USB devices currently attached to the system + * - Choosing a device to operate from your software + * - Opening and closing the chosen device + * + * \section nutshell In a nutshell... + * + * The description below really makes things sound more complicated than they + * actually are. The following sequence of function calls will be suitable + * for almost all scenarios and does not require you to have such a deep + * understanding of the resource management issues: + * \code +// discover devices +libusb_device **list; +libusb_device *found = NULL; +ssize_t cnt = libusb_get_device_list(NULL, &list); +ssize_t i = 0; +int err = 0; +if (cnt < 0) + error(); + +for (i = 0; i < cnt; i++) { + libusb_device *device = list[i]; + if (is_interesting(device)) { + found = device; + break; + } +} + +if (found) { + libusb_device_handle *handle; + + err = libusb_open(found, &handle); + if (err) + error(); + // etc +} + +libusb_free_device_list(list, 1); +\endcode + * + * The two important points: + * - You asked libusb_free_device_list() to unreference the devices (2nd + * parameter) + * - You opened the device before freeing the list and unreferencing the + * devices + * + * If you ended up with a handle, you can now proceed to perform I/O on the + * device. + * + * \section devshandles Devices and device handles + * libusb has a concept of a USB device, represented by the + * \ref libusb_device opaque type. A device represents a USB device that + * is currently or was previously connected to the system. Using a reference + * to a device, you can determine certain information about the device (e.g. + * you can read the descriptor data). + * + * The libusb_get_device_list() function can be used to obtain a list of + * devices currently connected to the system. This is known as device + * discovery. + * + * Just because you have a reference to a device does not mean it is + * necessarily usable. The device may have been unplugged, you may not have + * permission to operate such device, or another program or driver may be + * using the device. + * + * When you've found a device that you'd like to operate, you must ask + * libusb to open the device using the libusb_open() function. Assuming + * success, libusb then returns you a device handle + * (a \ref libusb_device_handle pointer). All "real" I/O operations then + * operate on the handle rather than the original device pointer. + * + * \section devref Device discovery and reference counting + * + * Device discovery (i.e. calling libusb_get_device_list()) returns a + * freshly-allocated list of devices. The list itself must be freed when + * you are done with it. libusb also needs to know when it is OK to free + * the contents of the list - the devices themselves. + * + * To handle these issues, libusb provides you with two separate items: + * - A function to free the list itself + * - A reference counting system for the devices inside + * + * New devices presented by the libusb_get_device_list() function all have a + * reference count of 1. You can increase and decrease reference count using + * libusb_ref_device() and libusb_unref_device(). A device is destroyed when + * its reference count reaches 0. + * + * With the above information in mind, the process of opening a device can + * be viewed as follows: + * -# Discover devices using libusb_get_device_list(). + * -# Choose the device that you want to operate, and call libusb_open(). + * -# Unref all devices in the discovered device list. + * -# Free the discovered device list. + * + * The order is important - you must not unreference the device before + * attempting to open it, because unreferencing it may destroy the device. + * + * For convenience, the libusb_free_device_list() function includes a + * parameter to optionally unreference all the devices in the list before + * freeing the list itself. This combines steps 3 and 4 above. + * + * As an implementation detail, libusb_open() actually adds a reference to + * the device in question. This is because the device remains available + * through the handle via libusb_get_device(). The reference is deleted during + * libusb_close(). + */ + +/** @defgroup libusb_misc Miscellaneous */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +#define DISCOVERED_DEVICES_SIZE_STEP 8 + +static struct discovered_devs *discovered_devs_alloc(void) +{ + struct discovered_devs *ret = + malloc(sizeof(*ret) + (sizeof(void *) * DISCOVERED_DEVICES_SIZE_STEP)); + + if (ret) { + ret->len = 0; + ret->capacity = DISCOVERED_DEVICES_SIZE_STEP; + } + return ret; +} + +static void discovered_devs_free(struct discovered_devs *discdevs) +{ + size_t i; + + for (i = 0; i < discdevs->len; i++) + libusb_unref_device(discdevs->devices[i]); + + free(discdevs); +} + +/* append a device to the discovered devices collection. may realloc itself, + * returning new discdevs. returns NULL on realloc failure. */ +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev) +{ + size_t len = discdevs->len; + size_t capacity; + struct discovered_devs *new_discdevs; + + /* if there is space, just append the device */ + if (len < discdevs->capacity) { + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + return discdevs; + } + + /* exceeded capacity, need to grow */ + usbi_dbg("need to increase capacity"); + capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP; + /* can't use usbi_reallocf here because in failure cases it would + * free the existing discdevs without unreferencing its devices. */ + new_discdevs = realloc(discdevs, + sizeof(*discdevs) + (sizeof(void *) * capacity)); + if (!new_discdevs) { + discovered_devs_free(discdevs); + return NULL; + } + + discdevs = new_discdevs; + discdevs->capacity = capacity; + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + + return discdevs; +} + +/* Allocate a new device with a specific session ID. The returned device has + * a reference count of 1. */ +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id) +{ + size_t priv_size = usbi_backend.device_priv_size; + struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size); + int r; + + if (!dev) + return NULL; + + r = usbi_mutex_init(&dev->lock); + if (r) { + free(dev); + return NULL; + } + + dev->ctx = ctx; + dev->refcnt = 1; + dev->session_data = session_id; + dev->speed = LIBUSB_SPEED_UNKNOWN; + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_connect_device (dev); + } + + return dev; +} + +void usbi_connect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + dev->attached = 1; + + usbi_mutex_lock(&dev->ctx->usb_devs_lock); + list_add(&dev->list, &dev->ctx->usb_devs); + usbi_mutex_unlock(&dev->ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED); + } +} + +void usbi_disconnect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + usbi_mutex_lock(&dev->lock); + dev->attached = 0; + usbi_mutex_unlock(&dev->lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_del(&dev->list); + usbi_mutex_unlock(&ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. libusb_handle_events will take care of dereferencing + * the device. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT); + } +} + +/* Perform some final sanity checks on a newly discovered device. If this + * function fails (negative return code), the device should not be added + * to the discovered device list. */ +int usbi_sanitize_device(struct libusb_device *dev) +{ + int r; + uint8_t num_configurations; + + r = usbi_device_cache_descriptor(dev); + if (r < 0) + return r; + + num_configurations = dev->device_descriptor.bNumConfigurations; + if (num_configurations > USB_MAXCONFIG) { + usbi_err(DEVICE_CTX(dev), "too many configurations"); + return LIBUSB_ERROR_IO; + } else if (0 == num_configurations) + usbi_dbg("zero configurations, maybe an unauthorized device"); + + dev->num_configurations = num_configurations; + return 0; +} + +/* Examine libusb's internal list of known devices, looking for one with + * a specific session ID. Returns the matching device if it was found, and + * NULL otherwise. */ +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id) +{ + struct libusb_device *dev; + struct libusb_device *ret = NULL; + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) + if (dev->session_data == session_id) { + ret = libusb_ref_device(dev); + break; + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + return ret; +} + +/** @ingroup libusb_dev + * Returns a list of USB devices currently attached to the system. This is + * your entry point into finding a USB device to operate. + * + * You are expected to unreference all the devices when you are done with + * them, and then free the list with libusb_free_device_list(). Note that + * libusb_free_device_list() can unref all the devices for you. Be careful + * not to unreference a device you are about to open until after you have + * opened it. + * + * This return value of this function indicates the number of devices in + * the resultant list. The list is actually one element larger, as it is + * NULL-terminated. + * + * \param ctx the context to operate on, or NULL for the default context + * \param list output location for a list of devices. Must be later freed with + * libusb_free_device_list(). + * \returns the number of devices in the outputted list, or any + * \ref libusb_error according to errors encountered by the backend. + */ +ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, + libusb_device ***list) +{ + struct discovered_devs *discdevs = discovered_devs_alloc(); + struct libusb_device **ret; + int r = 0; + ssize_t i, len; + USBI_GET_CONTEXT(ctx); + usbi_dbg(""); + + if (!discdevs) + return LIBUSB_ERROR_NO_MEM; + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend provides hotplug support */ + struct libusb_device *dev; + + if (usbi_backend.hotplug_poll) + usbi_backend.hotplug_poll(); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) { + discdevs = discovered_devs_append(discdevs, dev); + + if (!discdevs) { + r = LIBUSB_ERROR_NO_MEM; + break; + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } else { + /* backend does not provide hotplug support */ + r = usbi_backend.get_device_list(ctx, &discdevs); + } + + if (r < 0) { + len = r; + goto out; + } + + /* convert discovered_devs into a list */ + len = discdevs->len; + ret = calloc(len + 1, sizeof(struct libusb_device *)); + if (!ret) { + len = LIBUSB_ERROR_NO_MEM; + goto out; + } + + ret[len] = NULL; + for (i = 0; i < len; i++) { + struct libusb_device *dev = discdevs->devices[i]; + ret[i] = libusb_ref_device(dev); + } + *list = ret; + +out: + if (discdevs) + discovered_devs_free(discdevs); + return len; +} + +/** \ingroup libusb_dev + * Frees a list of devices previously discovered using + * libusb_get_device_list(). If the unref_devices parameter is set, the + * reference count of each device in the list is decremented by 1. + * \param list the list to free + * \param unref_devices whether to unref the devices in the list + */ +void API_EXPORTED libusb_free_device_list(libusb_device **list, + int unref_devices) +{ + if (!list) + return; + + if (unref_devices) { + int i = 0; + struct libusb_device *dev; + + while ((dev = list[i++]) != NULL) + libusb_unref_device(dev); + } + free(list); +} + +/** \ingroup libusb_dev + * Get the number of the bus that a device is connected to. + * \param dev a device + * \returns the bus number + */ +uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev) +{ + return dev->bus_number; +} + +/** \ingroup libusb_dev + * Get the number of the port that a device is connected to. + * Unless the OS does something funky, or you are hot-plugging USB extension cards, + * the port number returned by this call is usually guaranteed to be uniquely tied + * to a physical port, meaning that different devices plugged on the same physical + * port should return the same port number. + * + * But outside of this, there is no guarantee that the port number returned by this + * call will remain the same, or even match the order in which ports have been + * numbered by the HUB/HCD manufacturer. + * + * \param dev a device + * \returns the port number (0 if not available) + */ +uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev) +{ + return dev->port_number; +} + +/** \ingroup libusb_dev + * Get the list of all port numbers from root for the specified device + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * \param dev a device + * \param port_numbers the array that should contain the port numbers + * \param port_numbers_len the maximum length of the array. As per the USB 3.0 + * specs, the current maximum limit for the depth is 7. + * \returns the number of elements filled + * \returns LIBUSB_ERROR_OVERFLOW if the array is too small + */ +int API_EXPORTED libusb_get_port_numbers(libusb_device *dev, + uint8_t* port_numbers, int port_numbers_len) +{ + int i = port_numbers_len; + struct libusb_context *ctx = DEVICE_CTX(dev); + + if (port_numbers_len <= 0) + return LIBUSB_ERROR_INVALID_PARAM; + + // HCDs can be listed as devices with port #0 + while((dev) && (dev->port_number != 0)) { + if (--i < 0) { + usbi_warn(ctx, "port numbers array is too small"); + return LIBUSB_ERROR_OVERFLOW; + } + port_numbers[i] = dev->port_number; + dev = dev->parent_dev; + } + if (i < port_numbers_len) + memmove(port_numbers, &port_numbers[i], port_numbers_len - i); + return port_numbers_len - i; +} + +/** \ingroup libusb_dev + * Deprecated please use libusb_get_port_numbers instead. + */ +int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev, + uint8_t* port_numbers, uint8_t port_numbers_len) +{ + UNUSED(ctx); + + return libusb_get_port_numbers(dev, port_numbers, port_numbers_len); +} + +/** \ingroup libusb_dev + * Get the the parent from the specified device. + * \param dev a device + * \returns the device parent or NULL if not available + * You should issue a \ref libusb_get_device_list() before calling this + * function and make sure that you only access the parent before issuing + * \ref libusb_free_device_list(). The reason is that libusb currently does + * not maintain a permanent list of device instances, and therefore can + * only guarantee that parents are fully instantiated within a + * libusb_get_device_list() - libusb_free_device_list() block. + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev) +{ + return dev->parent_dev; +} + +/** \ingroup libusb_dev + * Get the address of the device on the bus it is connected to. + * \param dev a device + * \returns the device address + */ +uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) +{ + return dev->device_address; +} + +/** \ingroup libusb_dev + * Get the negotiated connection speed for a device. + * \param dev a device + * \returns a \ref libusb_speed code, where LIBUSB_SPEED_UNKNOWN means that + * the OS doesn't know or doesn't support returning the negotiated speed. + */ +int API_EXPORTED libusb_get_device_speed(libusb_device *dev) +{ + return dev->speed; +} + +static const struct libusb_endpoint_descriptor *find_endpoint( + struct libusb_config_descriptor *config, unsigned char endpoint) +{ + int iface_idx; + for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) { + const struct libusb_interface *iface = &config->interface[iface_idx]; + int altsetting_idx; + + for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting; + altsetting_idx++) { + const struct libusb_interface_descriptor *altsetting + = &iface->altsetting[altsetting_idx]; + int ep_idx; + + for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) { + const struct libusb_endpoint_descriptor *ep = + &altsetting->endpoint[ep_idx]; + if (ep->bEndpointAddress == endpoint) + return ep; + } + } + } + return NULL; +} + +/** \ingroup libusb_dev + * Convenience function to retrieve the wMaxPacketSize value for a particular + * endpoint in the active device configuration. + * + * This function was originally intended to be of assistance when setting up + * isochronous transfers, but a design mistake resulted in this function + * instead. It simply returns the wMaxPacketSize value without considering + * its contents. If you're dealing with isochronous transfers, you probably + * want libusb_get_max_iso_packet_size() instead. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the wMaxPacketSize value + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = ep->wMaxPacketSize; + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup libusb_dev + * Calculate the maximum packet size which a specific endpoint is capable is + * sending or receiving in the duration of 1 microframe + * + * Only the active configuration is examined. The calculation is based on the + * wMaxPacketSize field in the endpoint descriptor as described in section + * 9.6.6 in the USB 2.0 specifications. + * + * If acting on an isochronous or interrupt endpoint, this function will + * multiply the value found in bits 0:10 by the number of transactions per + * microframe (determined by bits 11:12). Otherwise, this function just + * returns the numeric value found in bits 0:10. + * + * This function is useful for setting up isochronous transfers, for example + * you might pass the return value from this function to + * libusb_set_iso_packet_lengths() in order to set the length field of every + * isochronous packet in a transfer. + * + * Since v1.0.3. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the maximum packet size which can be sent/received on this endpoint + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + enum libusb_transfer_type ep_type; + uint16_t val; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + val = ep->wMaxPacketSize; + ep_type = (enum libusb_transfer_type) (ep->bmAttributes & 0x3); + + r = val & 0x07ff; + if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) + r *= (1 + ((val >> 11) & 3)); + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup libusb_dev + * Increment the reference count of a device. + * \param dev the device to reference + * \returns the same device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev) +{ + usbi_mutex_lock(&dev->lock); + dev->refcnt++; + usbi_mutex_unlock(&dev->lock); + return dev; +} + +/** \ingroup libusb_dev + * Decrement the reference count of a device. If the decrement operation + * causes the reference count to reach zero, the device shall be destroyed. + * \param dev the device to unreference + */ +void API_EXPORTED libusb_unref_device(libusb_device *dev) +{ + int refcnt; + + if (!dev) + return; + + usbi_mutex_lock(&dev->lock); + refcnt = --dev->refcnt; + usbi_mutex_unlock(&dev->lock); + + if (refcnt == 0) { + usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address); + + libusb_unref_device(dev->parent_dev); + + if (usbi_backend.destroy_device) + usbi_backend.destroy_device(dev); + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend does not support hotplug */ + usbi_disconnect_device(dev); + } + + usbi_mutex_destroy(&dev->lock); + free(dev); + } +} + +/* + * Signal the event pipe so that the event handling thread will be + * interrupted to process an internal event. + */ +int usbi_signal_event(struct libusb_context *ctx) +{ + unsigned char dummy = 1; + ssize_t r; + + /* write some data on event pipe to interrupt event handlers */ + r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling write failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/* + * Clear the event pipe so that the event handling will no longer be + * interrupted. + */ +int usbi_clear_event(struct libusb_context *ctx) +{ + unsigned char dummy; + ssize_t r; + + /* read some data on event pipe to clear it */ + r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling read failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/** \ingroup libusb_dev + * Open a device and obtain a device handle. A handle allows you to perform + * I/O on the device in question. + * + * Internally, this function adds a reference to the device and makes it + * available to you through libusb_get_device(). This reference is removed + * during libusb_close(). + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev the device to open + * \param dev_handle output location for the returned device handle pointer. Only + * populated when the return code is 0. + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure + * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_open(libusb_device *dev, + libusb_device_handle **dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device_handle *_dev_handle; + size_t priv_size = usbi_backend.device_handle_priv_size; + int r; + usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); + + if (!dev->attached) { + return LIBUSB_ERROR_NO_DEVICE; + } + + _dev_handle = malloc(sizeof(*_dev_handle) + priv_size); + if (!_dev_handle) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_mutex_init(&_dev_handle->lock); + if (r) { + free(_dev_handle); + return LIBUSB_ERROR_OTHER; + } + + _dev_handle->dev = libusb_ref_device(dev); + _dev_handle->auto_detach_kernel_driver = 0; + _dev_handle->claimed_interfaces = 0; + memset(&_dev_handle->os_priv, 0, priv_size); + + r = usbi_backend.open(_dev_handle); + if (r < 0) { + usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); + libusb_unref_device(dev); + usbi_mutex_destroy(&_dev_handle->lock); + free(_dev_handle); + return r; + } + + usbi_mutex_lock(&ctx->open_devs_lock); + list_add(&_dev_handle->list, &ctx->open_devs); + usbi_mutex_unlock(&ctx->open_devs_lock); + *dev_handle = _dev_handle; + + return 0; +} + +/** \ingroup libusb_dev + * Convenience function for finding a device with a particular + * idVendor/idProduct combination. This function is intended + * for those scenarios where you are using libusb to knock up a quick test + * application - it allows you to avoid calling libusb_get_device_list() and + * worrying about traversing/freeing the list. + * + * This function has limitations and is hence not intended for use in real + * applications: if multiple devices have the same IDs it will only + * give you the first one, etc. + * + * \param ctx the context to operate on, or NULL for the default context + * \param vendor_id the idVendor value to search for + * \param product_id the idProduct value to search for + * \returns a device handle for the first found device, or NULL on error + * or if the device could not be found. */ +DEFAULT_VISIBILITY +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id) +{ + struct libusb_device **devs; + struct libusb_device *found = NULL; + struct libusb_device *dev; + struct libusb_device_handle *dev_handle = NULL; + size_t i = 0; + int r; + + if (libusb_get_device_list(ctx, &devs) < 0) + return NULL; + + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) + goto out; + if (desc.idVendor == vendor_id && desc.idProduct == product_id) { + found = dev; + break; + } + } + + if (found) { + r = libusb_open(found, &dev_handle); + if (r < 0) + dev_handle = NULL; + } + +out: + libusb_free_device_list(devs, 1); + return dev_handle; +} + +static void do_close(struct libusb_context *ctx, + struct libusb_device_handle *dev_handle) +{ + struct usbi_transfer *itransfer; + struct usbi_transfer *tmp; + + /* remove any transfers in flight that are for this device */ + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* safe iteration because transfers may be being deleted */ + list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) { + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + if (transfer->dev_handle != dev_handle) + continue; + + usbi_mutex_lock(&itransfer->lock); + if (!(itransfer->state_flags & USBI_TRANSFER_DEVICE_DISAPPEARED)) { + usbi_err(ctx, "Device handle closed while transfer was still being processed, but the device is still connected as far as we know"); + + if (itransfer->state_flags & USBI_TRANSFER_CANCELLING) + usbi_warn(ctx, "A cancellation for an in-flight transfer hasn't completed but closing the device handle"); + else + usbi_err(ctx, "A cancellation hasn't even been scheduled on the transfer for which the device is closing"); + } + usbi_mutex_unlock(&itransfer->lock); + + /* remove from the list of in-flight transfers and make sure + * we don't accidentally use the device handle in the future + * (or that such accesses will be easily caught and identified as a crash) + */ + list_del(&itransfer->list); + transfer->dev_handle = NULL; + + /* it is up to the user to free up the actual transfer struct. this is + * just making sure that we don't attempt to process the transfer after + * the device handle is invalid + */ + usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed", + transfer, dev_handle); + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + usbi_mutex_lock(&ctx->open_devs_lock); + list_del(&dev_handle->list); + usbi_mutex_unlock(&ctx->open_devs_lock); + + usbi_backend.close(dev_handle); + libusb_unref_device(dev_handle->dev); + usbi_mutex_destroy(&dev_handle->lock); + free(dev_handle); +} + +/** \ingroup libusb_dev + * Close a device handle. Should be called on all open handles before your + * application exits. + * + * Internally, this function destroys the reference that was added by + * libusb_open() on the given device. + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev_handle the device handle to close + */ +void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx; + int handling_events; + int pending_events; + + if (!dev_handle) + return; + usbi_dbg(""); + + ctx = HANDLE_CTX(dev_handle); + handling_events = usbi_handling_events(ctx); + + /* Similarly to libusb_open(), we want to interrupt all event handlers + * at this point. More importantly, we want to perform the actual close of + * the device while holding the event handling lock (preventing any other + * thread from doing event handling) because we will be removing a file + * descriptor from the polling loop. If this is being called by the current + * event handler, we can bypass the interruption code because we already + * hold the event handling lock. */ + + if (!handling_events) { + /* Record that we are closing a device. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + ctx->device_close++; + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* take event handling lock */ + libusb_lock_events(ctx); + } + + /* Close the device */ + do_close(ctx, dev_handle); + + if (!handling_events) { + /* We're done with closing this device. + * Clear the event pipe if there are no further pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + ctx->device_close--; + pending_events = usbi_pending_events(ctx); + if (!pending_events) + usbi_clear_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* Release event handling lock and wake up event waiters */ + libusb_unlock_events(ctx); + } +} + +/** \ingroup libusb_dev + * Get the underlying device for a device handle. This function does not modify + * the reference count of the returned device, so do not feel compelled to + * unreference it when you are done. + * \param dev_handle a device handle + * \returns the underlying device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) +{ + return dev_handle->dev; +} + +/** \ingroup libusb_dev + * Determine the bConfigurationValue of the currently active configuration. + * + * You could formulate your own control request to obtain this information, + * but this function has the advantage that it may be able to retrieve the + * information from operating system caches (no I/O involved). + * + * If the OS does not cache this information, then this function will block + * while a control transfer is submitted to retrieve the information. + * + * This function will return a value of 0 in the config output + * parameter if the device is in unconfigured state. + * + * \param dev_handle a device handle + * \param config output location for the bConfigurationValue of the active + * configuration (only valid for return code 0) + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle, + int *config) +{ + int r = LIBUSB_ERROR_NOT_SUPPORTED; + + usbi_dbg(""); + if (usbi_backend.get_configuration) + r = usbi_backend.get_configuration(dev_handle, config); + + if (r == LIBUSB_ERROR_NOT_SUPPORTED) { + uint8_t tmp = 0; + usbi_dbg("falling back to control message"); + r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000); + if (r == 0) { + usbi_err(HANDLE_CTX(dev_handle), "zero bytes returned in ctrl transfer?"); + r = LIBUSB_ERROR_IO; + } else if (r == 1) { + r = 0; + *config = tmp; + } else { + usbi_dbg("control failed, error %d", r); + } + } + + if (r == 0) + usbi_dbg("active config %d", *config); + + return r; +} + +/** \ingroup libusb_dev + * Set the active configuration for a device. + * + * The operating system may or may not have already set an active + * configuration on the device. It is up to your application to ensure the + * correct configuration is selected before you attempt to claim interfaces + * and perform other operations. + * + * If you call this function on a device already configured with the selected + * configuration, then this function will act as a lightweight device reset: + * it will issue a SET_CONFIGURATION request using the current configuration, + * causing most USB-related device state to be reset (altsetting reset to zero, + * endpoint halts cleared, toggles reset). + * + * You cannot change/reset configuration if your application has claimed + * interfaces. It is advised to set the desired configuration before claiming + * interfaces. + * + * Alternatively you can call libusb_release_interface() first. Note if you + * do things this way you must ensure that auto_detach_kernel_driver for + * dev is 0, otherwise the kernel driver will be re-attached when you + * release the interface(s). + * + * You cannot change/reset configuration if other applications or drivers have + * claimed interfaces. + * + * A configuration value of -1 will put the device in unconfigured state. + * The USB specifications state that a configuration value of 0 does this, + * however buggy devices exist which actually have a configuration 0. + * + * You should always use this function rather than formulating your own + * SET_CONFIGURATION control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param configuration the bConfigurationValue of the configuration you + * wish to activate, or -1 if you wish to put the device in an unconfigured + * state + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist + * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle, + int configuration) +{ + usbi_dbg("configuration %d", configuration); + return usbi_backend.set_configuration(dev_handle, configuration); +} + +/** \ingroup libusb_dev + * Claim an interface on a given device handle. You must claim the interface + * you wish to use before you can perform I/O on any of its endpoints. + * + * It is legal to attempt to claim an already-claimed interface, in which + * case libusb just returns 0 without doing anything. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel driver + * will be detached if necessary, on failure the detach error is returned. + * + * Claiming of interfaces is a purely logical operation; it does not cause + * any requests to be sent over the bus. Interface claiming is used to + * instruct the underlying operating system that your application wishes + * to take ownership of the interface. + * + * This is a non-blocking function. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the interface you + * wish to claim + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist + * \returns LIBUSB_ERROR_BUSY if another program or driver has claimed the + * interface + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns a LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle, + int interface_number) +{ + int r = 0; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_mutex_lock(&dev_handle->lock); + if (dev_handle->claimed_interfaces & (1 << interface_number)) + goto out; + + r = usbi_backend.claim_interface(dev_handle, interface_number); + if (r == 0) + dev_handle->claimed_interfaces |= 1 << interface_number; + +out: + usbi_mutex_unlock(&dev_handle->lock); + return r; +} + +/** \ingroup libusb_dev + * Release an interface previously claimed with libusb_claim_interface(). You + * should release all claimed interfaces before closing a device handle. + * + * This is a blocking function. A SET_INTERFACE control request will be sent + * to the device, resetting interface state to the first alternate setting. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel + * driver will be re-attached after releasing the interface. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle, + int interface_number) +{ + int r; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev_handle->lock); + if (!(dev_handle->claimed_interfaces & (1 << interface_number))) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = usbi_backend.release_interface(dev_handle, interface_number); + if (r == 0) + dev_handle->claimed_interfaces &= ~(1 << interface_number); + +out: + usbi_mutex_unlock(&dev_handle->lock); + return r; +} + +/** \ingroup libusb_dev + * Activate an alternate setting for an interface. The interface must have + * been previously claimed with libusb_claim_interface(). + * + * You should always use this function rather than formulating your own + * SET_INTERFACE control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \param alternate_setting the bAlternateSetting of the alternate + * setting to activate + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed, or the + * requested alternate setting does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, + int interface_number, int alternate_setting) +{ + usbi_dbg("interface %d altsetting %d", + interface_number, alternate_setting); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev_handle->lock); + if (!dev_handle->dev->attached) { + usbi_mutex_unlock(&dev_handle->lock); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (!(dev_handle->claimed_interfaces & (1 << interface_number))) { + usbi_mutex_unlock(&dev_handle->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + usbi_mutex_unlock(&dev_handle->lock); + + return usbi_backend.set_interface_altsetting(dev_handle, interface_number, + alternate_setting); +} + +/** \ingroup libusb_dev + * Clear the halt/stall condition for an endpoint. Endpoints with halt status + * are unable to receive or transmit data until the halt condition is stalled. + * + * You should cancel all pending transfers before attempting to clear the halt + * condition. + * + * This is a blocking function. + * + * \param dev_handle a device handle + * \param endpoint the endpoint to clear halt status + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle, + unsigned char endpoint) +{ + usbi_dbg("endpoint %x", endpoint); + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend.clear_halt(dev_handle, endpoint); +} + +/** \ingroup libusb_dev + * Perform a USB port reset to reinitialize a device. The system will attempt + * to restore the previous configuration and alternate settings after the + * reset has completed. + * + * If the reset fails, the descriptors change, or the previous state cannot be + * restored, the device will appear to be disconnected and reconnected. This + * means that the device handle is no longer valid (you should close it) and + * rediscover the device. A return code of LIBUSB_ERROR_NOT_FOUND indicates + * when this is the case. + * + * This is a blocking function which usually incurs a noticeable delay. + * + * \param dev_handle a handle of the device to reset + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the + * device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle) +{ + usbi_dbg(""); + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend.reset_device(dev_handle); +} + +/** \ingroup libusb_asyncio + * Allocate up to num_streams usb bulk streams on the specified endpoints. This + * function takes an array of endpoints rather then a single endpoint because + * some protocols require that endpoints are setup with similar stream ids. + * All endpoints passed in must belong to the same interface. + * + * Note this function may return less streams then requested. Also note that the + * same number of streams are allocated for each endpoint in the endpoint array. + * + * Stream id 0 is reserved, and should not be used to communicate with devices. + * If libusb_alloc_streams() returns with a value of N, you may use stream ids + * 1 to N. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev_handle a device handle + * \param num_streams number of streams to try to allocate + * \param endpoints array of endpoints to allocate streams on + * \param num_endpoints length of the endpoints array + * \returns number of streams allocated, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend.alloc_streams) + return usbi_backend.alloc_streams(dev_handle, num_streams, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_asyncio + * Free usb bulk streams allocated with libusb_alloc_streams(). + * + * Note streams are automatically free-ed when releasing an interface. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev_handle a device handle + * \param endpoints array of endpoints to free streams on + * \param num_endpoints length of the endpoints array + * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("eps %d", num_endpoints); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend.free_streams) + return usbi_backend.free_streams(dev_handle, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_asyncio + * Attempts to allocate a block of persistent DMA memory suitable for transfers + * against the given device. If successful, will return a block of memory + * that is suitable for use as "buffer" in \ref libusb_transfer against this + * device. Using this memory instead of regular memory means that the host + * controller can use DMA directly into the buffer to increase performance, and + * also that transfers can no longer fail due to kernel memory fragmentation. + * + * Note that this means you should not modify this memory (or even data on + * the same cache lines) when a transfer is in progress, although it is legal + * to have several transfers going on within the same memory block. + * + * Will return NULL on failure. Many systems do not support such zerocopy + * and will always return NULL. Memory allocated with this function must be + * freed with \ref libusb_dev_mem_free. Specifically, this means that the + * flag \ref LIBUSB_TRANSFER_FREE_BUFFER cannot be used to free memory allocated + * with this function. + * + * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105 + * + * \param dev_handle a device handle + * \param length size of desired data buffer + * \returns a pointer to the newly allocated memory, or NULL on failure + */ +DEFAULT_VISIBILITY +unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle, + size_t length) +{ + if (!dev_handle->dev->attached) + return NULL; + + if (usbi_backend.dev_mem_alloc) + return usbi_backend.dev_mem_alloc(dev_handle, length); + else + return NULL; +} + +/** \ingroup libusb_asyncio + * Free device memory allocated with libusb_dev_mem_alloc(). + * + * \param dev_handle a device handle + * \param buffer pointer to the previously allocated memory + * \param length size of previously allocated memory + * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_dev_mem_free(libusb_device_handle *dev_handle, + unsigned char *buffer, size_t length) +{ + if (usbi_backend.dev_mem_free) + return usbi_backend.dev_mem_free(dev_handle, buffer, length); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Determine if a kernel driver is active on an interface. If a kernel driver + * is active, you cannot claim the interface, and libusb will be unable to + * perform I/O. + * + * This functionality is not available on Windows. + * + * \param dev_handle a device handle + * \param interface_number the interface to check + * \returns 0 if no kernel driver is active + * \returns 1 if a kernel driver is active + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_detach_kernel_driver() + */ +int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend.kernel_driver_active) + return usbi_backend.kernel_driver_active(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Detach a kernel driver from an interface. If successful, you will then be + * able to claim the interface and perform I/O. + * + * This functionality is not available on Darwin or Windows. + * + * Note that libusb itself also talks to the device through a special kernel + * driver, if this driver is already attached to the device, this call will + * not detach it and return LIBUSB_ERROR_NOT_FOUND. + * + * \param dev_handle a device handle + * \param interface_number the interface to detach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend.detach_kernel_driver) + return usbi_backend.detach_kernel_driver(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Re-attach an interface's kernel driver, which was previously detached + * using libusb_detach_kernel_driver(). This call is only effective on + * Linux and returns LIBUSB_ERROR_NOT_SUPPORTED on all other platforms. + * + * This functionality is not available on Darwin or Windows. + * + * \param dev_handle a device handle + * \param interface_number the interface to attach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns LIBUSB_ERROR_BUSY if the driver cannot be attached because the + * interface is claimed by a program or driver + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev_handle->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend.attach_kernel_driver) + return usbi_backend.attach_kernel_driver(dev_handle, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup libusb_dev + * Enable/disable libusb's automatic kernel driver detachment. When this is + * enabled libusb will automatically detach the kernel driver on an interface + * when claiming the interface, and attach it when releasing the interface. + * + * Automatic kernel driver detachment is disabled on newly opened device + * handles by default. + * + * On platforms which do not have LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER + * this function will return LIBUSB_ERROR_NOT_SUPPORTED, and libusb will + * continue as if this function was never called. + * + * \param dev_handle a device handle + * \param enable whether to enable or disable auto kernel driver detachment + * + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \see libusb_claim_interface() + * \see libusb_release_interface() + * \see libusb_set_configuration() + */ +int API_EXPORTED libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev_handle, int enable) +{ + if (!(usbi_backend.caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + dev_handle->auto_detach_kernel_driver = enable; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_lib + * \deprecated Use libusb_set_option() instead using the + * \ref LIBUSB_OPTION_LOG_LEVEL option. + */ +void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) +{ +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + USBI_GET_CONTEXT(ctx); + if (!ctx->debug_fixed) { + level = CLAMP(level, LIBUSB_LOG_LEVEL_NONE, LIBUSB_LOG_LEVEL_DEBUG); + ctx->debug = (enum libusb_log_level)level; + } +#else + UNUSED(ctx); + UNUSED(level); +#endif +} + +/** \ingroup libusb_lib + * Set an option in the library. + * + * Use this function to configure a specific option within the library. + * + * Some options require one or more arguments to be provided. Consult each + * option's documentation for specific requirements. + * + * Since version 1.0.22, \ref LIBUSB_API_VERSION >= 0x01000106 + * + * \param ctx context on which to operate + * \param option which option to set + * \param ... any required arguments for the specified option + * + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_INVALID_PARAM if the option or arguments are invalid + * \returns LIBUSB_ERROR_NOT_SUPPORTED if the option is valid but not supported + * on this platform + */ +int API_EXPORTED libusb_set_option(libusb_context *ctx, + enum libusb_option option, ...) +{ + int arg, r = LIBUSB_SUCCESS; + va_list ap; + + USBI_GET_CONTEXT(ctx); + + va_start(ap, option); + switch (option) { + case LIBUSB_OPTION_LOG_LEVEL: + arg = va_arg(ap, int); + if (arg < LIBUSB_LOG_LEVEL_NONE || arg > LIBUSB_LOG_LEVEL_DEBUG) { + r = LIBUSB_ERROR_INVALID_PARAM; + break; + } +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + if (!ctx->debug_fixed) + ctx->debug = (enum libusb_log_level)arg; +#endif + break; + + /* Handle all backend-specific options here */ + case LIBUSB_OPTION_USE_USBDK: + if (usbi_backend.set_option) + r = usbi_backend.set_option(ctx, option, ap); + else + r = LIBUSB_ERROR_NOT_SUPPORTED; + break; + + default: + r = LIBUSB_ERROR_INVALID_PARAM; + } + va_end(ap); + + return r; +} + +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) +/* returns the log level as defined in the LIBUSB_DEBUG environment variable. + * if LIBUSB_DEBUG is not present or not a number, returns LIBUSB_LOG_LEVEL_NONE. + * value is clamped to ensure it is within the valid range of possibilities. + */ +static enum libusb_log_level get_env_debug_level(void) +{ + const char *dbg = getenv("LIBUSB_DEBUG"); + enum libusb_log_level level; + if (dbg) { + int dbg_level = atoi(dbg); + dbg_level = CLAMP(dbg_level, LIBUSB_LOG_LEVEL_NONE, LIBUSB_LOG_LEVEL_DEBUG); + level = (enum libusb_log_level)dbg_level; + } else { + level = LIBUSB_LOG_LEVEL_NONE; + } + return level; +} +#endif + +/** \ingroup libusb_lib + * Initialize libusb. This function must be called before calling any other + * libusb function. + * + * If you do not provide an output location for a context pointer, a default + * context will be created. If there was already a default context, it will + * be reused (and nothing will be initialized/reinitialized). + * + * \param context Optional output location for context pointer. + * Only valid on return code 0. + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \see libusb_contexts + */ +int API_EXPORTED libusb_init(libusb_context **context) +{ + struct libusb_device *dev, *next; + size_t priv_size = usbi_backend.context_priv_size; + struct libusb_context *ctx; + static int first_init = 1; + int r = 0; + + usbi_mutex_static_lock(&default_context_lock); + + if (!timestamp_origin.tv_sec) { + usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, ×tamp_origin); + } + + if (!context && usbi_default_context) { + usbi_dbg("reusing default context"); + default_context_refcnt++; + usbi_mutex_static_unlock(&default_context_lock); + return 0; + } + + ctx = calloc(1, sizeof(*ctx) + priv_size); + if (!ctx) { + r = LIBUSB_ERROR_NO_MEM; + goto err_unlock; + } + +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + ctx->debug = get_env_debug_level(); + if (ctx->debug != LIBUSB_LOG_LEVEL_NONE) + ctx->debug_fixed = 1; +#endif + + /* default context should be initialized before calling usbi_dbg */ + if (!usbi_default_context) { + usbi_default_context = ctx; + default_context_refcnt++; + usbi_dbg("created default context"); + } + + usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor, + libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc); + + usbi_mutex_init(&ctx->usb_devs_lock); + usbi_mutex_init(&ctx->open_devs_lock); + usbi_mutex_init(&ctx->hotplug_cbs_lock); + list_init(&ctx->usb_devs); + list_init(&ctx->open_devs); + list_init(&ctx->hotplug_cbs); + ctx->next_hotplug_cb_handle = 1; + + usbi_mutex_static_lock(&active_contexts_lock); + if (first_init) { + first_init = 0; + list_init (&active_contexts_list); + } + list_add (&ctx->list, &active_contexts_list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (usbi_backend.init) { + r = usbi_backend.init(ctx); + if (r) + goto err_free_ctx; + } + + r = usbi_io_init(ctx); + if (r < 0) + goto err_backend_exit; + + usbi_mutex_static_unlock(&default_context_lock); + + if (context) + *context = ctx; + + return 0; + +err_backend_exit: + if (usbi_backend.exit) + usbi_backend.exit(ctx); +err_free_ctx: + if (ctx == usbi_default_context) { + usbi_default_context = NULL; + default_context_refcnt--; + } + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + + free(ctx); +err_unlock: + usbi_mutex_static_unlock(&default_context_lock); + return r; +} + +/** \ingroup libusb_lib + * Deinitialize libusb. Should be called after closing all open devices and + * before your application terminates. + * \param ctx the context to deinitialize, or NULL for the default context + */ +void API_EXPORTED libusb_exit(struct libusb_context *ctx) +{ + struct libusb_device *dev, *next; + struct timeval tv = { 0, 0 }; + + usbi_dbg(""); + USBI_GET_CONTEXT(ctx); + + /* if working with default context, only actually do the deinitialization + * if we're the last user */ + usbi_mutex_static_lock(&default_context_lock); + if (ctx == usbi_default_context) { + if (--default_context_refcnt > 0) { + usbi_dbg("not destroying default context"); + usbi_mutex_static_unlock(&default_context_lock); + return; + } + usbi_dbg("destroying default context"); + usbi_default_context = NULL; + } + usbi_mutex_static_unlock(&default_context_lock); + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_hotplug_deregister(ctx, 1); + + /* + * Ensure any pending unplug events are read from the hotplug + * pipe. The usb_device-s hold in the events are no longer part + * of usb_devs, but the events still hold a reference! + * + * Note we don't do this if the application has left devices + * open (which implies a buggy app) to avoid packet completion + * handlers running when the app does not expect them to run. + */ + if (list_empty(&ctx->open_devs)) + libusb_handle_events_timeout(ctx, &tv); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } + + /* a few sanity checks. don't bother with locking because unless + * there is an application bug, nobody will be accessing these. */ + if (!list_empty(&ctx->usb_devs)) + usbi_warn(ctx, "some libusb_devices were leaked"); + if (!list_empty(&ctx->open_devs)) + usbi_warn(ctx, "application left some devices open"); + + usbi_io_exit(ctx); + if (usbi_backend.exit) + usbi_backend.exit(ctx); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + free(ctx); +} + +/** \ingroup libusb_misc + * Check at runtime if the loaded library has a given capability. + * This call should be performed after \ref libusb_init(), to ensure the + * backend has updated its capability set. + * + * \param capability the \ref libusb_capability to check for + * \returns nonzero if the running library has the capability, 0 otherwise + */ +int API_EXPORTED libusb_has_capability(uint32_t capability) +{ + switch (capability) { + case LIBUSB_CAP_HAS_CAPABILITY: + return 1; + case LIBUSB_CAP_HAS_HOTPLUG: + return !(usbi_backend.get_device_list); + case LIBUSB_CAP_HAS_HID_ACCESS: + return (usbi_backend.caps & USBI_CAP_HAS_HID_ACCESS); + case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER: + return (usbi_backend.caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER); + } + return 0; +} + +#ifdef ENABLE_LOGGING + +/* this is defined in libusbi.h if needed */ +#ifdef LIBUSB_PRINTF_WIN32 +/* + * Prior to VS2015, Microsoft did not provide the snprintf() function and + * provided a vsnprintf() that did not guarantee NULL-terminated output. + * Microsoft did provide a _snprintf() function, but again it did not + * guarantee NULL-terminated output. + * + * The below implementations guarantee NULL-terminated output and are + * C99 compliant. + */ + +int usbi_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = usbi_vsnprintf(str, size, format, ap); + va_end(ap); + + return ret; +} + +int usbi_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + int ret; + + ret = _vsnprintf(str, size, format, ap); + if (ret < 0 || ret == (int)size) { + /* Output is truncated, ensure buffer is NULL-terminated and + * determine how many characters would have been written. */ + str[size - 1] = '\0'; + if (ret < 0) + ret = _vsnprintf(NULL, 0, format, ap); + } + + return ret; +} +#endif /* LIBUSB_PRINTF_WIN32 */ + +static void usbi_log_str(enum libusb_log_level level, const char *str) +{ +#if defined(USE_SYSTEM_LOGGING_FACILITY) +#if defined(OS_WINDOWS) + OutputDebugString(str); +#elif defined(OS_WINCE) + /* Windows CE only supports the Unicode version of OutputDebugString. */ + WCHAR wbuf[USBI_MAX_LOG_LEN]; + MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)); + OutputDebugStringW(wbuf); +#elif defined(__ANDROID__) + int priority = ANDROID_LOG_UNKNOWN; + switch (level) { + case LIBUSB_LOG_LEVEL_NONE: return; + case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break; + case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break; + case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break; + case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break; + } + __android_log_write(priority, "libusb", str); +#elif defined(HAVE_SYSLOG_FUNC) + int syslog_level = LOG_INFO; + switch (level) { + case LIBUSB_LOG_LEVEL_NONE: return; + case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break; + case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break; + case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break; + case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break; + } + syslog(syslog_level, "%s", str); +#else /* All of gcc, Clang, XCode seem to use #warning */ +#warning System logging is not supported on this platform. Logging to stderr will be used instead. + fputs(str, stderr); +#endif +#else + fputs(str, stderr); +#endif /* USE_SYSTEM_LOGGING_FACILITY */ + UNUSED(level); +} + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args) +{ + const char *prefix; + char buf[USBI_MAX_LOG_LEN]; + struct timespec now; + int global_debug, header_len, text_len; + static int has_debug_header_been_displayed = 0; + +#ifdef ENABLE_DEBUG_LOGGING + global_debug = 1; + UNUSED(ctx); +#else + enum libusb_log_level ctx_level = LIBUSB_LOG_LEVEL_NONE; + + USBI_GET_CONTEXT(ctx); + if (ctx) + ctx_level = ctx->debug; + else + ctx_level = get_env_debug_level(); + + if (ctx_level == LIBUSB_LOG_LEVEL_NONE) + return; + if (level == LIBUSB_LOG_LEVEL_WARNING && ctx_level < LIBUSB_LOG_LEVEL_WARNING) + return; + if (level == LIBUSB_LOG_LEVEL_INFO && ctx_level < LIBUSB_LOG_LEVEL_INFO) + return; + if (level == LIBUSB_LOG_LEVEL_DEBUG && ctx_level < LIBUSB_LOG_LEVEL_DEBUG) + return; + + global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG); +#endif + + usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &now); + if ((global_debug) && (!has_debug_header_been_displayed)) { + has_debug_header_been_displayed = 1; + usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] " USBI_LOG_LINE_END); + usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END); + } + if (now.tv_nsec < timestamp_origin.tv_nsec) { + now.tv_sec--; + now.tv_nsec += 1000000000L; + } + now.tv_sec -= timestamp_origin.tv_sec; + now.tv_nsec -= timestamp_origin.tv_nsec; + + switch (level) { + case LIBUSB_LOG_LEVEL_NONE: + return; + case LIBUSB_LOG_LEVEL_ERROR: + prefix = "error"; + break; + case LIBUSB_LOG_LEVEL_WARNING: + prefix = "warning"; + break; + case LIBUSB_LOG_LEVEL_INFO: + prefix = "info"; + break; + case LIBUSB_LOG_LEVEL_DEBUG: + prefix = "debug"; + break; + default: + prefix = "unknown"; + break; + } + + if (global_debug) { + header_len = snprintf(buf, sizeof(buf), + "[%2d.%06d] [%08x] libusb: %s [%s] ", + (int)now.tv_sec, (int)(now.tv_nsec / 1000L), usbi_get_tid(), prefix, function); + } else { + header_len = snprintf(buf, sizeof(buf), + "libusb: %s [%s] ", prefix, function); + } + + if (header_len < 0 || header_len >= (int)sizeof(buf)) { + /* Somehow snprintf failed to write to the buffer, + * remove the header so something useful is output. */ + header_len = 0; + } + /* Make sure buffer is NUL terminated */ + buf[header_len] = '\0'; + text_len = vsnprintf(buf + header_len, sizeof(buf) - header_len, + format, args); + if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) { + /* Truncated log output. On some platforms a -1 return value means + * that the output was truncated. */ + text_len = sizeof(buf) - header_len; + } + if (header_len + text_len + sizeof(USBI_LOG_LINE_END) >= sizeof(buf)) { + /* Need to truncate the text slightly to fit on the terminator. */ + text_len -= (header_len + text_len + sizeof(USBI_LOG_LINE_END)) - sizeof(buf); + } + strcpy(buf + header_len + text_len, USBI_LOG_LINE_END); + + usbi_log_str(level, buf); +} + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...) +{ + va_list args; + + va_start (args, format); + usbi_log_v(ctx, level, function, format, args); + va_end (args); +} + +#endif /* ENABLE_LOGGING */ + +/** \ingroup libusb_misc + * Returns a constant NULL-terminated string with the ASCII name of a libusb + * error or transfer status code. The caller must not free() the returned + * string. + * + * \param error_code The \ref libusb_error or libusb_transfer_status code to + * return the name of. + * \returns The error name, or the string **UNKNOWN** if the value of + * error_code is not a known error / status code. + */ +DEFAULT_VISIBILITY const char * LIBUSB_CALL libusb_error_name(int error_code) +{ + switch (error_code) { + case LIBUSB_ERROR_IO: + return "LIBUSB_ERROR_IO"; + case LIBUSB_ERROR_INVALID_PARAM: + return "LIBUSB_ERROR_INVALID_PARAM"; + case LIBUSB_ERROR_ACCESS: + return "LIBUSB_ERROR_ACCESS"; + case LIBUSB_ERROR_NO_DEVICE: + return "LIBUSB_ERROR_NO_DEVICE"; + case LIBUSB_ERROR_NOT_FOUND: + return "LIBUSB_ERROR_NOT_FOUND"; + case LIBUSB_ERROR_BUSY: + return "LIBUSB_ERROR_BUSY"; + case LIBUSB_ERROR_TIMEOUT: + return "LIBUSB_ERROR_TIMEOUT"; + case LIBUSB_ERROR_OVERFLOW: + return "LIBUSB_ERROR_OVERFLOW"; + case LIBUSB_ERROR_PIPE: + return "LIBUSB_ERROR_PIPE"; + case LIBUSB_ERROR_INTERRUPTED: + return "LIBUSB_ERROR_INTERRUPTED"; + case LIBUSB_ERROR_NO_MEM: + return "LIBUSB_ERROR_NO_MEM"; + case LIBUSB_ERROR_NOT_SUPPORTED: + return "LIBUSB_ERROR_NOT_SUPPORTED"; + case LIBUSB_ERROR_OTHER: + return "LIBUSB_ERROR_OTHER"; + + case LIBUSB_TRANSFER_ERROR: + return "LIBUSB_TRANSFER_ERROR"; + case LIBUSB_TRANSFER_TIMED_OUT: + return "LIBUSB_TRANSFER_TIMED_OUT"; + case LIBUSB_TRANSFER_CANCELLED: + return "LIBUSB_TRANSFER_CANCELLED"; + case LIBUSB_TRANSFER_STALL: + return "LIBUSB_TRANSFER_STALL"; + case LIBUSB_TRANSFER_NO_DEVICE: + return "LIBUSB_TRANSFER_NO_DEVICE"; + case LIBUSB_TRANSFER_OVERFLOW: + return "LIBUSB_TRANSFER_OVERFLOW"; + + case 0: + return "LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED"; + default: + return "**UNKNOWN**"; + } +} + +/** \ingroup libusb_misc + * Returns a pointer to const struct libusb_version with the version + * (major, minor, micro, nano and rc) of the running library. + */ +DEFAULT_VISIBILITY +const struct libusb_version * LIBUSB_CALL libusb_get_version(void) +{ + return &libusb_version_internal; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/descriptor.c b/vendor/github.com/karalabe/usb/libusb/libusb/descriptor.c new file mode 100644 index 00000000..74d6de55 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/descriptor.c @@ -0,0 +1,1192 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * USB descriptor handling functions for libusb + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +#define DESC_HEADER_LENGTH 2 +#define DEVICE_DESC_LENGTH 18 +#define CONFIG_DESC_LENGTH 9 +#define INTERFACE_DESC_LENGTH 9 +#define ENDPOINT_DESC_LENGTH 7 +#define ENDPOINT_AUDIO_DESC_LENGTH 9 + +/** @defgroup libusb_desc USB descriptors + * This page details how to examine the various standard USB descriptors + * for detected devices + */ + +/* set host_endian if the w values are already in host endian format, + * as opposed to bus endian. */ +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian) +{ + const unsigned char *sp = source; + unsigned char *dp = dest; + uint16_t w; + const char *cp; + uint32_t d; + + for (cp = descriptor; *cp; cp++) { + switch (*cp) { + case 'b': /* 8-bit byte */ + *dp++ = *sp++; + break; + case 'w': /* 16-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 2); + } else { + w = (sp[1] << 8) | sp[0]; + *((uint16_t *)dp) = w; + } + sp += 2; + dp += 2; + break; + case 'd': /* 32-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 4); + } else { + d = (sp[3] << 24) | (sp[2] << 16) | + (sp[1] << 8) | sp[0]; + *((uint32_t *)dp) = d; + } + sp += 4; + dp += 4; + break; + case 'u': /* 16 byte UUID */ + memcpy(dp, sp, 16); + sp += 16; + dp += 16; + break; + } + } + + return (int) (sp - source); +} + +static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) +{ + free((void *) endpoint->extra); +} + +static int parse_endpoint(struct libusb_context *ctx, + struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer, + int size, int host_endian) +{ + struct usb_descriptor_header header; + unsigned char *extra; + unsigned char *begin; + int parsed = 0; + int len; + + if (size < DESC_HEADER_LENGTH) { + usbi_err(ctx, "short endpoint descriptor read %d/%d", + size, DESC_HEADER_LENGTH); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + header.bDescriptorType, LIBUSB_DT_ENDPOINT); + return parsed; + } + if (header.bLength > size) { + usbi_warn(ctx, "short endpoint descriptor read %d/%d", + size, header.bLength); + return parsed; + } + if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian); + else if (header.bLength >= ENDPOINT_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian); + else { + usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength); + return LIBUSB_ERROR_IO; + } + + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + + /* Skip over the rest of the Class Specific or Vendor Specific */ + /* descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, "invalid extra ep desc len (%d)", + header.bLength); + return LIBUSB_ERROR_IO; + } else if (header.bLength > size) { + usbi_warn(ctx, "short extra ep desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor %x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + } + + /* Copy any unknown descriptors into a storage area for drivers */ + /* to later parse */ + len = (int)(buffer - begin); + if (!len) { + endpoint->extra = NULL; + endpoint->extra_length = 0; + return parsed; + } + + extra = malloc(len); + endpoint->extra = extra; + if (!extra) { + endpoint->extra_length = 0; + return LIBUSB_ERROR_NO_MEM; + } + + memcpy(extra, begin, len); + endpoint->extra_length = len; + + return parsed; +} + +static void clear_interface(struct libusb_interface *usb_interface) +{ + int i; + int j; + + if (usb_interface->altsetting) { + for (i = 0; i < usb_interface->num_altsetting; i++) { + struct libusb_interface_descriptor *ifp = + (struct libusb_interface_descriptor *) + usb_interface->altsetting + i; + free((void *) ifp->extra); + if (ifp->endpoint) { + for (j = 0; j < ifp->bNumEndpoints; j++) + clear_endpoint((struct libusb_endpoint_descriptor *) + ifp->endpoint + j); + } + free((void *) ifp->endpoint); + } + } + free((void *) usb_interface->altsetting); + usb_interface->altsetting = NULL; +} + +static int parse_interface(libusb_context *ctx, + struct libusb_interface *usb_interface, unsigned char *buffer, int size, + int host_endian) +{ + int i; + int len; + int r; + int parsed = 0; + int interface_number = -1; + struct usb_descriptor_header header; + struct libusb_interface_descriptor *ifp; + unsigned char *begin; + + usb_interface->num_altsetting = 0; + + while (size >= INTERFACE_DESC_LENGTH) { + struct libusb_interface_descriptor *altsetting = + (struct libusb_interface_descriptor *) usb_interface->altsetting; + altsetting = usbi_reallocf(altsetting, + sizeof(struct libusb_interface_descriptor) * + (usb_interface->num_altsetting + 1)); + if (!altsetting) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + usb_interface->altsetting = altsetting; + + ifp = altsetting + usb_interface->num_altsetting; + usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0); + if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + ifp->bDescriptorType, LIBUSB_DT_INTERFACE); + return parsed; + } + if (ifp->bLength < INTERFACE_DESC_LENGTH) { + usbi_err(ctx, "invalid interface bLength (%d)", + ifp->bLength); + r = LIBUSB_ERROR_IO; + goto err; + } + if (ifp->bLength > size) { + usbi_warn(ctx, "short intf descriptor read %d/%d", + size, ifp->bLength); + return parsed; + } + if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { + usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints); + r = LIBUSB_ERROR_IO; + goto err; + } + + usb_interface->num_altsetting++; + ifp->extra = NULL; + ifp->extra_length = 0; + ifp->endpoint = NULL; + + if (interface_number == -1) + interface_number = ifp->bInterfaceNumber; + + /* Skip over the interface */ + buffer += ifp->bLength; + parsed += ifp->bLength; + size -= ifp->bLength; + + begin = buffer; + + /* Skip over any interface, class or vendor descriptors */ + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra intf desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra intf desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + buffer += header.bLength; + parsed += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + ifp->extra = malloc(len); + if (!ifp->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + memcpy((unsigned char *) ifp->extra, begin, len); + ifp->extra_length = len; + } + + if (ifp->bNumEndpoints > 0) { + struct libusb_endpoint_descriptor *endpoint; + endpoint = calloc(ifp->bNumEndpoints, sizeof(struct libusb_endpoint_descriptor)); + ifp->endpoint = endpoint; + if (!endpoint) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + for (i = 0; i < ifp->bNumEndpoints; i++) { + r = parse_endpoint(ctx, endpoint + i, buffer, size, + host_endian); + if (r < 0) + goto err; + if (r == 0) { + ifp->bNumEndpoints = (uint8_t)i; + break; + } + + buffer += r; + parsed += r; + size -= r; + } + } + + /* We check to see if it's an alternate to this one */ + ifp = (struct libusb_interface_descriptor *) buffer; + if (size < LIBUSB_DT_INTERFACE_SIZE || + ifp->bDescriptorType != LIBUSB_DT_INTERFACE || + ifp->bInterfaceNumber != interface_number) + return parsed; + } + + return parsed; +err: + clear_interface(usb_interface); + return r; +} + +static void clear_configuration(struct libusb_config_descriptor *config) +{ + int i; + if (config->interface) { + for (i = 0; i < config->bNumInterfaces; i++) + clear_interface((struct libusb_interface *) + config->interface + i); + } + free((void *) config->interface); + free((void *) config->extra); +} + +static int parse_configuration(struct libusb_context *ctx, + struct libusb_config_descriptor *config, unsigned char *buffer, + int size, int host_endian) +{ + int i; + int r; + struct usb_descriptor_header header; + struct libusb_interface *usb_interface; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian); + if (config->bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + config->bDescriptorType, LIBUSB_DT_CONFIG); + return LIBUSB_ERROR_IO; + } + if (config->bLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid config bLength (%d)", config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bLength > size) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bNumInterfaces > USB_MAXINTERFACES) { + usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces); + return LIBUSB_ERROR_IO; + } + + usb_interface = calloc(config->bNumInterfaces, sizeof(struct libusb_interface)); + config->interface = usb_interface; + if (!usb_interface) + return LIBUSB_ERROR_NO_MEM; + + buffer += config->bLength; + size -= config->bLength; + + config->extra = NULL; + config->extra_length = 0; + + for (i = 0; i < config->bNumInterfaces; i++) { + int len; + unsigned char *begin; + + /* Skip over the rest of the Class Specific or Vendor */ + /* Specific descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra config desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra config desc read %d/%d", + size, header.bLength); + config->bNumInterfaces = (uint8_t)i; + return size; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor 0x%x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + /* FIXME: We should realloc and append here */ + if (!config->extra_length) { + config->extra = malloc(len); + if (!config->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + memcpy((unsigned char *) config->extra, begin, len); + config->extra_length = len; + } + } + + r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian); + if (r < 0) + goto err; + if (r == 0) { + config->bNumInterfaces = (uint8_t)i; + break; + } + + buffer += r; + size -= r; + } + + return size; + +err: + clear_configuration(config); + return r; +} + +static int raw_desc_to_config(struct libusb_context *ctx, + unsigned char *buf, int size, int host_endian, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); + int r; + + if (!_config) + return LIBUSB_ERROR_NO_MEM; + + r = parse_configuration(ctx, _config, buf, size, host_endian); + if (r < 0) { + usbi_err(ctx, "parse_configuration failed with error %d", r); + free(_config); + return r; + } else if (r > 0) { + usbi_warn(ctx, "still %d bytes of descriptor data left", r); + } + + *config = _config; + return LIBUSB_SUCCESS; +} + +int usbi_device_cache_descriptor(libusb_device *dev) +{ + int r, host_endian = 0; + + r = usbi_backend.get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor, + &host_endian); + if (r < 0) + return r; + + if (!host_endian) { + dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB); + dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor); + dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct); + dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice); + } + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Get the USB device descriptor for a given device. + * + * This is a non-blocking function; the device descriptor is cached in memory. + * + * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this + * function always succeeds. + * + * \param dev the device + * \param desc output location for the descriptor data + * \returns 0 on success or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc) +{ + usbi_dbg(""); + memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor, + sizeof (dev->device_descriptor)); + return 0; +} + +/** \ingroup libusb_desc + * Get the USB configuration descriptor for the currently active configuration. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_config_descriptor + */ +int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + r = usbi_backend.get_active_config_descriptor(dev, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend.get_active_config_descriptor(dev, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/** \ingroup libusb_desc + * Get a USB configuration descriptor based on its index. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config_index the index of the configuration you wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor_by_value() + */ +int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + usbi_dbg("index %d", config_index); + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_NOT_FOUND; + + r = usbi_backend.get_config_descriptor(dev, config_index, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend.get_config_descriptor(dev, config_index, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/* iterate through all configurations, returning the index of the configuration + * matching a specific bConfigurationValue in the idx output parameter, or -1 + * if the config was not found. + * returns 0 on success or a LIBUSB_ERROR code + */ +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx) +{ + uint8_t i; + + usbi_dbg("value %d", bConfigurationValue); + for (i = 0; i < dev->num_configurations; i++) { + unsigned char tmp[6]; + int host_endian; + int r = usbi_backend.get_config_descriptor(dev, i, tmp, sizeof(tmp), + &host_endian); + if (r < 0) { + *idx = -1; + return r; + } + if (tmp[5] == bConfigurationValue) { + *idx = i; + return 0; + } + } + + *idx = -1; + return 0; +} + +/** \ingroup libusb_desc + * Get a USB configuration descriptor with a specific bConfigurationValue. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param bConfigurationValue the bConfigurationValue of the configuration you + * wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor() + */ +int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config) +{ + int r, idx, host_endian; + unsigned char *buf = NULL; + + if (usbi_backend.get_config_descriptor_by_value) { + r = usbi_backend.get_config_descriptor_by_value(dev, + bConfigurationValue, &buf, &host_endian); + if (r < 0) + return r; + return raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + } + + r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); + if (r < 0) + return r; + else if (idx == -1) + return LIBUSB_ERROR_NOT_FOUND; + else + return libusb_get_config_descriptor(dev, (uint8_t) idx, config); +} + +/** \ingroup libusb_desc + * Free a configuration descriptor obtained from + * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). + * It is safe to call this function with a NULL config parameter, in which + * case the function simply returns. + * + * \param config the configuration descriptor to free + */ +void API_EXPORTED libusb_free_config_descriptor( + struct libusb_config_descriptor *config) +{ + if (!config) + return; + + clear_configuration(config); + free(config); +} + +/** \ingroup libusb_desc + * Get an endpoints superspeed endpoint companion descriptor (if any) + * + * \param ctx the context to operate on, or NULL for the default context + * \param endpoint endpoint descriptor from which to get the superspeed + * endpoint companion descriptor + * \param ep_comp output location for the superspeed endpoint companion + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_endpoint_companion_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp) +{ + struct usb_descriptor_header header; + int size = endpoint->extra_length; + const unsigned char *buffer = endpoint->extra; + + *ep_comp = NULL; + + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < 2 || header.bLength > size) { + usbi_err(ctx, "invalid descriptor length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) { + buffer += header.bLength; + size -= header.bLength; + continue; + } + if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) { + usbi_err(ctx, "invalid ss-ep-comp-desc length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + *ep_comp = malloc(sizeof(**ep_comp)); + if (*ep_comp == NULL) + return LIBUSB_ERROR_NO_MEM; + usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0); + return LIBUSB_SUCCESS; + } + return LIBUSB_ERROR_NOT_FOUND; +} + +/** \ingroup libusb_desc + * Free a superspeed endpoint companion descriptor obtained from + * libusb_get_ss_endpoint_companion_descriptor(). + * It is safe to call this function with a NULL ep_comp parameter, in which + * case the function simply returns. + * + * \param ep_comp the superspeed endpoint companion descriptor to free + */ +void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp) +{ + free(ep_comp); +} + +static int parse_bos(struct libusb_context *ctx, + struct libusb_bos_descriptor **bos, + unsigned char *buffer, int size, int host_endian) +{ + struct libusb_bos_descriptor bos_header, *_bos; + struct libusb_bos_dev_capability_descriptor dev_cap; + int i; + + if (size < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian); + if (bos_header.bDescriptorType != LIBUSB_DT_BOS) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + bos_header.bDescriptorType, LIBUSB_DT_BOS); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength > size) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, bos_header.bLength); + return LIBUSB_ERROR_IO; + } + + _bos = calloc (1, + sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *)); + if (!_bos) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian); + buffer += bos_header.bLength; + size -= bos_header.bLength; + + /* Get the device capability descriptors */ + for (i = 0; i < bos_header.bNumDeviceCaps; i++) { + if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE); + break; + } + usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian); + if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) { + usbi_warn(ctx, "unexpected descriptor %x (expected %x)", + dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY); + break; + } + if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "invalid dev-cap bLength (%d)", + dev_cap.bLength); + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_IO; + } + if (dev_cap.bLength > size) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, dev_cap.bLength); + break; + } + + _bos->dev_capability[i] = malloc(dev_cap.bLength); + if (!_bos->dev_capability[i]) { + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_NO_MEM; + } + memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength); + buffer += dev_cap.bLength; + size -= dev_cap.bLength; + } + _bos->bNumDeviceCaps = (uint8_t)i; + *bos = _bos; + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Get a Binary Object Store (BOS) descriptor + * This is a BLOCKING function, which will send requests to the device. + * + * \param dev_handle the handle of an open libusb device + * \param bos output location for the BOS descriptor. Only valid if 0 was returned. + * Must be freed with \ref libusb_free_bos_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle, + struct libusb_bos_descriptor **bos) +{ + struct libusb_bos_descriptor _bos; + uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0}; + unsigned char *bos_data = NULL; + const int host_endian = 0; + int r; + + /* Read the BOS. This generates 2 requests on the bus, + * one for the header, and one for the full BOS */ + r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_header, + LIBUSB_DT_BOS_SIZE); + if (r < 0) { + if (r != LIBUSB_ERROR_PIPE) + usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r); + return r; + } + if (r < LIBUSB_DT_BOS_SIZE) { + usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d", + r, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian); + usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities", + _bos.wTotalLength, _bos.bNumDeviceCaps); + bos_data = calloc(_bos.wTotalLength, 1); + if (bos_data == NULL) + return LIBUSB_ERROR_NO_MEM; + + r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, + _bos.wTotalLength); + if (r >= 0) + r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r, host_endian); + else + usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r); + + free(bos_data); + return r; +} + +/** \ingroup libusb_desc + * Free a BOS descriptor obtained from libusb_get_bos_descriptor(). + * It is safe to call this function with a NULL bos parameter, in which + * case the function simply returns. + * + * \param bos the BOS descriptor to free + */ +void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos) +{ + int i; + + if (!bos) + return; + + for (i = 0; i < bos->bNumDeviceCaps; i++) + free(bos->dev_capability[i]); + free(bos); +} + +/** \ingroup libusb_desc + * Get an USB 2.0 Extension descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION + * \param usb_2_0_extension output location for the USB 2.0 Extension + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_usb_2_0_extension_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension) +{ + struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_USB_2_0_EXTENSION); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE); + return LIBUSB_ERROR_IO; + } + + _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension)); + if (!_usb_2_0_extension) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd", + _usb_2_0_extension, host_endian); + + *usb_2_0_extension = _usb_2_0_extension; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a USB 2.0 Extension descriptor obtained from + * libusb_get_usb_2_0_extension_descriptor(). + * It is safe to call this function with a NULL usb_2_0_extension parameter, + * in which case the function simply returns. + * + * \param usb_2_0_extension the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension) +{ + free(usb_2_0_extension); +} + +/** \ingroup libusb_desc + * Get a SuperSpeed USB Device Capability descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * \param ss_usb_device_cap output location for the SuperSpeed USB Device + * Capability descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_usb_device_capability_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap) +{ + struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE); + return LIBUSB_ERROR_IO; + } + + _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap)); + if (!_ss_usb_device_cap) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw", + _ss_usb_device_cap, host_endian); + + *ss_usb_device_cap = _ss_usb_device_cap; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a SuperSpeed USB Device Capability descriptor obtained from + * libusb_get_ss_usb_device_capability_descriptor(). + * It is safe to call this function with a NULL ss_usb_device_cap + * parameter, in which case the function simply returns. + * + * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap) +{ + free(ss_usb_device_cap); +} + +/** \ingroup libusb_desc + * Get a Container ID descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID + * \param container_id output location for the Container ID descriptor. + * Only valid if 0 was returned. Must be freed with + * libusb_free_container_id_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id) +{ + struct libusb_container_id_descriptor *_container_id; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_CONTAINER_ID); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE); + return LIBUSB_ERROR_IO; + } + + _container_id = malloc(sizeof(*_container_id)); + if (!_container_id) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu", + _container_id, host_endian); + + *container_id = _container_id; + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_desc + * Free a Container ID descriptor obtained from + * libusb_get_container_id_descriptor(). + * It is safe to call this function with a NULL container_id parameter, + * in which case the function simply returns. + * + * \param container_id the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id) +{ + free(container_id); +} + +/** \ingroup libusb_desc + * Retrieve a string descriptor in C style ASCII. + * + * Wrapper around libusb_get_string_descriptor(). Uses the first language + * supported by the device. + * + * \param dev_handle a device handle + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for ASCII string descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, + uint8_t desc_index, unsigned char *data, int length) +{ + unsigned char tbuf[255]; /* Some devices choke on size > 255 */ + int r, si, di; + uint16_t langid; + + /* Asking for the zero'th index is special - it returns a string + * descriptor that contains all the language IDs supported by the + * device. Typically there aren't many - often only one. Language + * IDs are 16 bit numbers, and they start at the third byte in the + * descriptor. There's also no point in trying to read descriptor 0 + * with this function. See USB 2.0 specification section 9.6.7 for + * more information. + */ + + if (desc_index == 0) + return LIBUSB_ERROR_INVALID_PARAM; + + r = libusb_get_string_descriptor(dev_handle, 0, 0, tbuf, sizeof(tbuf)); + if (r < 0) + return r; + + if (r < 4) + return LIBUSB_ERROR_IO; + + langid = tbuf[2] | (tbuf[3] << 8); + + r = libusb_get_string_descriptor(dev_handle, desc_index, langid, tbuf, + sizeof(tbuf)); + if (r < 0) + return r; + + if (tbuf[1] != LIBUSB_DT_STRING) + return LIBUSB_ERROR_IO; + + if (tbuf[0] > r) + return LIBUSB_ERROR_IO; + + di = 0; + for (si = 2; si < tbuf[0]; si += 2) { + if (di >= (length - 1)) + break; + + if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */ + data[di++] = '?'; + else + data[di++] = tbuf[si]; + } + + data[di] = 0; + return di; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.c b/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.c new file mode 100644 index 00000000..a4320bc4 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.c @@ -0,0 +1,373 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug functions for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + +#include "libusbi.h" +#include "hotplug.h" + +/** + * @defgroup libusb_hotplug Device hotplug event notification + * This page details how to use the libusb hotplug interface, where available. + * + * Be mindful that not all platforms currently implement hotplug notification and + * that you should first call on \ref libusb_has_capability() with parameter + * \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available. + * + * \page libusb_hotplug Device hotplug event notification + * + * \section hotplug_intro Introduction + * + * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support + * for hotplug events on some platforms (you should test if your platform + * supports hotplug notification by calling \ref libusb_has_capability() with + * parameter \ref LIBUSB_CAP_HAS_HOTPLUG). + * + * This interface allows you to request notification for the arrival and departure + * of matching USB devices. + * + * To receive hotplug notification you register a callback by calling + * \ref libusb_hotplug_register_callback(). This function will optionally return + * a callback handle that can be passed to \ref libusb_hotplug_deregister_callback(). + * + * A callback function must return an int (0 or 1) indicating whether the callback is + * expecting additional events. Returning 0 will rearm the callback and 1 will cause + * the callback to be deregistered. Note that when callbacks are called from + * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE + * flag, the callback return value is ignored, iow you cannot cause a callback + * to be deregistered by returning 1 when it is called from + * libusb_hotplug_register_callback(). + * + * Callbacks for a particular context are automatically deregistered by libusb_exit(). + * + * As of 1.0.16 there are two supported hotplug events: + * - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use + * - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available + * + * A hotplug event can listen for either or both of these events. + * + * Note: If you receive notification that a device has left and you have any + * a libusb_device_handles for the device it is up to you to call libusb_close() + * on each device handle to free up any remaining resources associated with the device. + * Once a device has left any libusb_device_handle associated with the device + * are invalid and will remain so even if the device comes back. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered + * safe to call any libusb function that takes a libusb_device. It also safe to + * open a device and submit asynchronous transfers. However, most other functions + * that take a libusb_device_handle are not safe to call. Examples of such + * functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking + * functions that retrieve various \ref libusb_desc "USB descriptors". These functions must + * be used outside of the context of the hotplug callback. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function + * is libusb_get_device_descriptor(). + * + * The following code provides an example of the usage of the hotplug interface: +\code +#include +#include +#include +#include + +static int count = 0; + +int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event, void *user_data) { + static libusb_device_handle *dev_handle = NULL; + struct libusb_device_descriptor desc; + int rc; + + (void)libusb_get_device_descriptor(dev, &desc); + + if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) { + rc = libusb_open(dev, &dev_handle); + if (LIBUSB_SUCCESS != rc) { + printf("Could not open USB device\n"); + } + } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { + if (dev_handle) { + libusb_close(dev_handle); + dev_handle = NULL; + } + } else { + printf("Unhandled event %d\n", event); + } + count++; + + return 0; +} + +int main (void) { + libusb_hotplug_callback_handle callback_handle; + int rc; + + libusb_init(NULL); + + rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005, + LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, + &callback_handle); + if (LIBUSB_SUCCESS != rc) { + printf("Error creating a hotplug callback\n"); + libusb_exit(NULL); + return EXIT_FAILURE; + } + + while (count < 2) { + libusb_handle_events_completed(NULL, NULL); + nanosleep(&(struct timespec){0, 10000000UL}, NULL); + } + + libusb_hotplug_deregister_callback(NULL, callback_handle); + libusb_exit(NULL); + + return 0; +} +\endcode + */ + +static int usbi_hotplug_match_cb(struct libusb_context *ctx, + struct libusb_device *dev, libusb_hotplug_event event, + struct libusb_hotplug_callback *hotplug_cb) +{ + if (!(hotplug_cb->flags & event)) { + return 0; + } + + if ((hotplug_cb->flags & USBI_HOTPLUG_VENDOR_ID_VALID) && + hotplug_cb->vendor_id != dev->device_descriptor.idVendor) { + return 0; + } + + if ((hotplug_cb->flags & USBI_HOTPLUG_PRODUCT_ID_VALID) && + hotplug_cb->product_id != dev->device_descriptor.idProduct) { + return 0; + } + + if ((hotplug_cb->flags & USBI_HOTPLUG_DEV_CLASS_VALID) && + hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) { + return 0; + } + + return hotplug_cb->cb(ctx, dev, event, hotplug_cb->user_data); +} + +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + struct libusb_hotplug_callback *hotplug_cb, *next; + int ret; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { + if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) { + /* process deregistration in usbi_hotplug_deregister() */ + continue; + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + ret = usbi_hotplug_match_cb(ctx, dev, event, hotplug_cb); + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + if (ret) { + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); +} + +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + int pending_events; + struct libusb_hotplug_message *message = calloc(1, sizeof(*message)); + + if (!message) { + usbi_err(ctx, "error allocating hotplug message"); + return; + } + + message->event = event; + message->device = dev; + + /* Take the event data lock and add this message to the list. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&message->list, &ctx->hotplug_msgs); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, libusb_hotplug_flag flags, + int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data, + libusb_hotplug_callback_handle *callback_handle) +{ + struct libusb_hotplug_callback *new_callback; + + /* check for sane values */ + if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) || + (flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) || + (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) || + !cb_fn) { + return LIBUSB_ERROR_INVALID_PARAM; + } + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + USBI_GET_CONTEXT(ctx); + + new_callback = calloc(1, sizeof(*new_callback)); + if (!new_callback) { + return LIBUSB_ERROR_NO_MEM; + } + + new_callback->flags = (uint8_t)events; + if (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id) { + new_callback->flags |= USBI_HOTPLUG_VENDOR_ID_VALID; + new_callback->vendor_id = (uint16_t)vendor_id; + } + if (LIBUSB_HOTPLUG_MATCH_ANY != product_id) { + new_callback->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID; + new_callback->product_id = (uint16_t)product_id; + } + if (LIBUSB_HOTPLUG_MATCH_ANY != dev_class) { + new_callback->flags |= USBI_HOTPLUG_DEV_CLASS_VALID; + new_callback->dev_class = (uint8_t)dev_class; + } + new_callback->cb = cb_fn; + new_callback->user_data = user_data; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + /* protect the handle by the context hotplug lock */ + new_callback->handle = ctx->next_hotplug_cb_handle++; + + /* handle the unlikely case of overflow */ + if (ctx->next_hotplug_cb_handle < 0) + ctx->next_hotplug_cb_handle = 1; + + list_add(&new_callback->list, &ctx->hotplug_cbs); + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle); + + if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) { + ssize_t i, len; + struct libusb_device **devs; + + len = libusb_get_device_list(ctx, &devs); + if (len < 0) { + libusb_hotplug_deregister_callback(ctx, + new_callback->handle); + return (int)len; + } + + for (i = 0; i < len; i++) { + usbi_hotplug_match_cb(ctx, devs[i], + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, + new_callback); + } + + libusb_free_device_list(devs, 1); + } + + + if (callback_handle) + *callback_handle = new_callback->handle; + + return LIBUSB_SUCCESS; +} + +void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle) +{ + struct libusb_hotplug_callback *hotplug_cb; + int deregistered = 0; + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return; + } + + USBI_GET_CONTEXT(ctx); + + usbi_dbg("deregister hotplug cb %d", callback_handle); + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { + if (callback_handle == hotplug_cb->handle) { + /* Mark this callback for deregistration */ + hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE; + deregistered = 1; + } + } + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + if (deregistered) { + int pending_events; + + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED; + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + } +} + +void usbi_hotplug_deregister(struct libusb_context *ctx, int forced) +{ + struct libusb_hotplug_callback *hotplug_cb, *next; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { + if (forced || (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)) { + usbi_dbg("freeing hotplug cb %p with handle %d", hotplug_cb, + hotplug_cb->handle); + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + } + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.h b/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.h new file mode 100644 index 00000000..dbadbcb9 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/hotplug.h @@ -0,0 +1,99 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug support for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef USBI_HOTPLUG_H +#define USBI_HOTPLUG_H + +#include "libusbi.h" + +enum usbi_hotplug_flags { + /* This callback is interested in device arrivals */ + USBI_HOTPLUG_DEVICE_ARRIVED = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, + + /* This callback is interested in device removals */ + USBI_HOTPLUG_DEVICE_LEFT = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, + + /* IMPORTANT: The values for the below entries must start *after* + * the highest value of the above entries!!! + */ + + /* The vendor_id field is valid for matching */ + USBI_HOTPLUG_VENDOR_ID_VALID = (1 << 3), + + /* The product_id field is valid for matching */ + USBI_HOTPLUG_PRODUCT_ID_VALID = (1 << 4), + + /* The dev_class field is valid for matching */ + USBI_HOTPLUG_DEV_CLASS_VALID = (1 << 5), + + /* This callback has been unregistered and needs to be freed */ + USBI_HOTPLUG_NEEDS_FREE = (1 << 6), +}; + +/** \ingroup hotplug + * The hotplug callback structure. The user populates this structure with + * libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback() + * to receive notification of hotplug events. + */ +struct libusb_hotplug_callback { + /** Flags that control how this callback behaves */ + uint8_t flags; + + /** Vendor ID to match (if flags says this is valid) */ + uint16_t vendor_id; + + /** Product ID to match (if flags says this is valid) */ + uint16_t product_id; + + /** Device class to match (if flags says this is valid) */ + uint8_t dev_class; + + /** Callback function to invoke for matching event/device */ + libusb_hotplug_callback_fn cb; + + /** Handle for this callback (used to match on deregister) */ + libusb_hotplug_callback_handle handle; + + /** User data that will be passed to the callback function */ + void *user_data; + + /** List this callback is registered in (ctx->hotplug_cbs) */ + struct list_head list; +}; + +struct libusb_hotplug_message { + /** The hotplug event that occurred */ + libusb_hotplug_event event; + + /** The device for which this hotplug event occurred */ + struct libusb_device *device; + + /** List this message is contained in (ctx->hotplug_msgs) */ + struct list_head list; +}; + +void usbi_hotplug_deregister(struct libusb_context *ctx, int forced); +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); + +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/io.c b/vendor/github.com/karalabe/usb/libusb/libusb/io.c new file mode 100644 index 00000000..a03bfaae --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/io.c @@ -0,0 +1,2822 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * I/O functions for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef USBI_TIMERFD_AVAILABLE +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +/** + * \page libusb_io Synchronous and asynchronous device I/O + * + * \section io_intro Introduction + * + * If you're using libusb in your application, you're probably wanting to + * perform I/O with devices - you want to perform USB data transfers. + * + * libusb offers two separate interfaces for device I/O. This page aims to + * introduce the two in order to help you decide which one is more suitable + * for your application. You can also choose to use both interfaces in your + * application by considering each transfer on a case-by-case basis. + * + * Once you have read through the following discussion, you should consult the + * detailed API documentation pages for the details: + * - \ref libusb_syncio + * - \ref libusb_asyncio + * + * \section theory Transfers at a logical level + * + * At a logical level, USB transfers typically happen in two parts. For + * example, when reading data from a endpoint: + * -# A request for data is sent to the device + * -# Some time later, the incoming data is received by the host + * + * or when writing data to an endpoint: + * + * -# The data is sent to the device + * -# Some time later, the host receives acknowledgement from the device that + * the data has been transferred. + * + * There may be an indefinite delay between the two steps. Consider a + * fictional USB input device with a button that the user can press. In order + * to determine when the button is pressed, you would likely submit a request + * to read data on a bulk or interrupt endpoint and wait for data to arrive. + * Data will arrive when the button is pressed by the user, which is + * potentially hours later. + * + * libusb offers both a synchronous and an asynchronous interface to performing + * USB transfers. The main difference is that the synchronous interface + * combines both steps indicated above into a single function call, whereas + * the asynchronous interface separates them. + * + * \section sync The synchronous interface + * + * The synchronous I/O interface allows you to perform a USB transfer with + * a single function call. When the function call returns, the transfer has + * completed and you can parse the results. + * + * If you have used the libusb-0.1 before, this I/O style will seem familar to + * you. libusb-0.1 only offered a synchronous interface. + * + * In our input device example, to read button presses you might write code + * in the following style: +\code +unsigned char data[4]; +int actual_length; +int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0); +if (r == 0 && actual_length == sizeof(data)) { + // results of the transaction can now be found in the data buffer + // parse them here and report button press +} else { + error(); +} +\endcode + * + * The main advantage of this model is simplicity: you did everything with + * a single simple function call. + * + * However, this interface has its limitations. Your application will sleep + * inside libusb_bulk_transfer() until the transaction has completed. If it + * takes the user 3 hours to press the button, your application will be + * sleeping for that long. Execution will be tied up inside the library - + * the entire thread will be useless for that duration. + * + * Another issue is that by tieing up the thread with that single transaction + * there is no possibility of performing I/O with multiple endpoints and/or + * multiple devices simultaneously, unless you resort to creating one thread + * per transaction. + * + * Additionally, there is no opportunity to cancel the transfer after the + * request has been submitted. + * + * For details on how to use the synchronous API, see the + * \ref libusb_syncio "synchronous I/O API documentation" pages. + * + * \section async The asynchronous interface + * + * Asynchronous I/O is the most significant new feature in libusb-1.0. + * Although it is a more complex interface, it solves all the issues detailed + * above. + * + * Instead of providing which functions that block until the I/O has complete, + * libusb's asynchronous interface presents non-blocking functions which + * begin a transfer and then return immediately. Your application passes a + * callback function pointer to this non-blocking function, which libusb will + * call with the results of the transaction when it has completed. + * + * Transfers which have been submitted through the non-blocking functions + * can be cancelled with a separate function call. + * + * The non-blocking nature of this interface allows you to be simultaneously + * performing I/O to multiple endpoints on multiple devices, without having + * to use threads. + * + * This added flexibility does come with some complications though: + * - In the interest of being a lightweight library, libusb does not create + * threads and can only operate when your application is calling into it. Your + * application must call into libusb from it's main loop when events are ready + * to be handled, or you must use some other scheme to allow libusb to + * undertake whatever work needs to be done. + * - libusb also needs to be called into at certain fixed points in time in + * order to accurately handle transfer timeouts. + * - Memory handling becomes more complex. You cannot use stack memory unless + * the function with that stack is guaranteed not to return until the transfer + * callback has finished executing. + * - You generally lose some linearity from your code flow because submitting + * the transfer request is done in a separate function from where the transfer + * results are handled. This becomes particularly obvious when you want to + * submit a second transfer based on the results of an earlier transfer. + * + * Internally, libusb's synchronous interface is expressed in terms of function + * calls to the asynchronous interface. + * + * For details on how to use the asynchronous API, see the + * \ref libusb_asyncio "asynchronous I/O API" documentation pages. + */ + + +/** + * \page libusb_packetoverflow Packets and overflows + * + * \section packets Packet abstraction + * + * The USB specifications describe how data is transmitted in packets, with + * constraints on packet size defined by endpoint descriptors. The host must + * not send data payloads larger than the endpoint's maximum packet size. + * + * libusb and the underlying OS abstract out the packet concept, allowing you + * to request transfers of any size. Internally, the request will be divided + * up into correctly-sized packets. You do not have to be concerned with + * packet sizes, but there is one exception when considering overflows. + * + * \section overflow Bulk/interrupt transfer overflows + * + * When requesting data on a bulk endpoint, libusb requires you to supply a + * buffer and the maximum number of bytes of data that libusb can put in that + * buffer. However, the size of the buffer is not communicated to the device - + * the device is just asked to send any amount of data. + * + * There is no problem if the device sends an amount of data that is less than + * or equal to the buffer size. libusb reports this condition to you through + * the \ref libusb_transfer::actual_length "libusb_transfer.actual_length" + * field. + * + * Problems may occur if the device attempts to send more data than can fit in + * the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but + * other behaviour is largely undefined: actual_length may or may not be + * accurate, the chunk of data that can fit in the buffer (before overflow) + * may or may not have been transferred. + * + * Overflows are nasty, but can be avoided. Even though you were told to + * ignore packets above, think about the lower level details: each transfer is + * split into packets (typically small, with a maximum size of 512 bytes). + * Overflows can only happen if the final packet in an incoming data transfer + * is smaller than the actual packet that the device wants to transfer. + * Therefore, you will never see an overflow if your transfer buffer size is a + * multiple of the endpoint's packet size: the final packet will either + * fill up completely or will be only partially filled. + */ + +/** + * @defgroup libusb_asyncio Asynchronous device I/O + * + * This page details libusb's asynchronous (non-blocking) API for USB device + * I/O. This interface is very powerful but is also quite complex - you will + * need to read this page carefully to understand the necessary considerations + * and issues surrounding use of this interface. Simplistic applications + * may wish to consider the \ref libusb_syncio "synchronous I/O API" instead. + * + * The asynchronous interface is built around the idea of separating transfer + * submission and handling of transfer completion (the synchronous model + * combines both of these into one). There may be a long delay between + * submission and completion, however the asynchronous submission function + * is non-blocking so will return control to your application during that + * potentially long delay. + * + * \section asyncabstraction Transfer abstraction + * + * For the asynchronous I/O, libusb implements the concept of a generic + * transfer entity for all types of I/O (control, bulk, interrupt, + * isochronous). The generic transfer object must be treated slightly + * differently depending on which type of I/O you are performing with it. + * + * This is represented by the public libusb_transfer structure type. + * + * \section asynctrf Asynchronous transfers + * + * We can view asynchronous I/O as a 5 step process: + * -# Allocation: allocate a libusb_transfer + * -# Filling: populate the libusb_transfer instance with information + * about the transfer you wish to perform + * -# Submission: ask libusb to submit the transfer + * -# Completion handling: examine transfer results in the + * libusb_transfer structure + * -# Deallocation: clean up resources + * + * + * \subsection asyncalloc Allocation + * + * This step involves allocating memory for a USB transfer. This is the + * generic transfer object mentioned above. At this stage, the transfer + * is "blank" with no details about what type of I/O it will be used for. + * + * Allocation is done with the libusb_alloc_transfer() function. You must use + * this function rather than allocating your own transfers. + * + * \subsection asyncfill Filling + * + * This step is where you take a previously allocated transfer and fill it + * with information to determine the message type and direction, data buffer, + * callback function, etc. + * + * You can either fill the required fields yourself or you can use the + * helper functions: libusb_fill_control_transfer(), libusb_fill_bulk_transfer() + * and libusb_fill_interrupt_transfer(). + * + * \subsection asyncsubmit Submission + * + * When you have allocated a transfer and filled it, you can submit it using + * libusb_submit_transfer(). This function returns immediately but can be + * regarded as firing off the I/O request in the background. + * + * \subsection asynccomplete Completion handling + * + * After a transfer has been submitted, one of four things can happen to it: + * + * - The transfer completes (i.e. some data was transferred) + * - The transfer has a timeout and the timeout expires before all data is + * transferred + * - The transfer fails due to an error + * - The transfer is cancelled + * + * Each of these will cause the user-specified transfer callback function to + * be invoked. It is up to the callback function to determine which of the + * above actually happened and to act accordingly. + * + * The user-specified callback is passed a pointer to the libusb_transfer + * structure which was used to setup and submit the transfer. At completion + * time, libusb has populated this structure with results of the transfer: + * success or failure reason, number of bytes of data transferred, etc. See + * the libusb_transfer structure documentation for more information. + * + * Important Note: The user-specified callback is called from an event + * handling context. It is therefore important that no calls are made into + * libusb that will attempt to perform any event handling. Examples of such + * functions are any listed in the \ref libusb_syncio "synchronous API" and any of + * the blocking functions that retrieve \ref libusb_desc "USB descriptors". + * + * \subsection Deallocation + * + * When a transfer has completed (i.e. the callback function has been invoked), + * you are advised to free the transfer (unless you wish to resubmit it, see + * below). Transfers are deallocated with libusb_free_transfer(). + * + * It is undefined behaviour to free a transfer which has not completed. + * + * \section asyncresubmit Resubmission + * + * You may be wondering why allocation, filling, and submission are all + * separated above where they could reasonably be combined into a single + * operation. + * + * The reason for separation is to allow you to resubmit transfers without + * having to allocate new ones every time. This is especially useful for + * common situations dealing with interrupt endpoints - you allocate one + * transfer, fill and submit it, and when it returns with results you just + * resubmit it for the next interrupt. + * + * \section asynccancel Cancellation + * + * Another advantage of using the asynchronous interface is that you have + * the ability to cancel transfers which have not yet completed. This is + * done by calling the libusb_cancel_transfer() function. + * + * libusb_cancel_transfer() is asynchronous/non-blocking in itself. When the + * cancellation actually completes, the transfer's callback function will + * be invoked, and the callback function should check the transfer status to + * determine that it was cancelled. + * + * Freeing the transfer after it has been cancelled but before cancellation + * has completed will result in undefined behaviour. + * + * When a transfer is cancelled, some of the data may have been transferred. + * libusb will communicate this to you in the transfer callback. Do not assume + * that no data was transferred. + * + * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints + * + * If your device does not have predictable transfer sizes (or it misbehaves), + * your application may submit a request for data on an IN endpoint which is + * smaller than the data that the device wishes to send. In some circumstances + * this will cause an overflow, which is a nasty condition to deal with. See + * the \ref libusb_packetoverflow page for discussion. + * + * \section asyncctrl Considerations for control transfers + * + * The libusb_transfer structure is generic and hence does not + * include specific fields for the control-specific setup packet structure. + * + * In order to perform a control transfer, you must place the 8-byte setup + * packet at the start of the data buffer. To simplify this, you could + * cast the buffer pointer to type struct libusb_control_setup, or you can + * use the helper function libusb_fill_control_setup(). + * + * The wLength field placed in the setup packet must be the length you would + * expect to be sent in the setup packet: the length of the payload that + * follows (or the expected maximum number of bytes to receive). However, + * the length field of the libusb_transfer object must be the length of + * the data buffer - i.e. it should be wLength plus the size of + * the setup packet (LIBUSB_CONTROL_SETUP_SIZE). + * + * If you use the helper functions, this is simplified for you: + * -# Allocate a buffer of size LIBUSB_CONTROL_SETUP_SIZE plus the size of the + * data you are sending/requesting. + * -# Call libusb_fill_control_setup() on the data buffer, using the transfer + * request size as the wLength value (i.e. do not include the extra space you + * allocated for the control setup). + * -# If this is a host-to-device transfer, place the data to be transferred + * in the data buffer, starting at offset LIBUSB_CONTROL_SETUP_SIZE. + * -# Call libusb_fill_control_transfer() to associate the data buffer with + * the transfer (and to set the remaining details such as callback and timeout). + * - Note that there is no parameter to set the length field of the transfer. + * The length is automatically inferred from the wLength field of the setup + * packet. + * -# Submit the transfer. + * + * The multi-byte control setup fields (wValue, wIndex and wLength) must + * be given in little-endian byte order (the endianness of the USB bus). + * Endianness conversion is transparently handled by + * libusb_fill_control_setup() which is documented to accept host-endian + * values. + * + * Further considerations are needed when handling transfer completion in + * your callback function: + * - As you might expect, the setup packet will still be sitting at the start + * of the data buffer. + * - If this was a device-to-host transfer, the received data will be sitting + * at offset LIBUSB_CONTROL_SETUP_SIZE into the buffer. + * - The actual_length field of the transfer structure is relative to the + * wLength of the setup packet, rather than the size of the data buffer. So, + * if your wLength was 4, your transfer's length was 12, then you + * should expect an actual_length of 4 to indicate that the data was + * transferred in entirity. + * + * To simplify parsing of setup packets and obtaining the data from the + * correct offset, you may wish to use the libusb_control_transfer_get_data() + * and libusb_control_transfer_get_setup() functions within your transfer + * callback. + * + * Even though control endpoints do not halt, a completed control transfer + * may have a LIBUSB_TRANSFER_STALL status code. This indicates the control + * request was not supported. + * + * \section asyncintr Considerations for interrupt transfers + * + * All interrupt transfers are performed using the polling interval presented + * by the bInterval value of the endpoint descriptor. + * + * \section asynciso Considerations for isochronous transfers + * + * Isochronous transfers are more complicated than transfers to + * non-isochronous endpoints. + * + * To perform I/O to an isochronous endpoint, allocate the transfer by calling + * libusb_alloc_transfer() with an appropriate number of isochronous packets. + * + * During filling, set \ref libusb_transfer::type "type" to + * \ref libusb_transfer_type::LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + * "LIBUSB_TRANSFER_TYPE_ISOCHRONOUS", and set + * \ref libusb_transfer::num_iso_packets "num_iso_packets" to a value less than + * or equal to the number of packets you requested during allocation. + * libusb_alloc_transfer() does not set either of these fields for you, given + * that you might not even use the transfer on an isochronous endpoint. + * + * Next, populate the length field for the first num_iso_packets entries in + * the \ref libusb_transfer::iso_packet_desc "iso_packet_desc" array. Section + * 5.6.3 of the USB2 specifications describe how the maximum isochronous + * packet length is determined by the wMaxPacketSize field in the endpoint + * descriptor. + * Two functions can help you here: + * + * - libusb_get_max_iso_packet_size() is an easy way to determine the max + * packet size for an isochronous endpoint. Note that the maximum packet + * size is actually the maximum number of bytes that can be transmitted in + * a single microframe, therefore this function multiplies the maximum number + * of bytes per transaction by the number of transaction opportunities per + * microframe. + * - libusb_set_iso_packet_lengths() assigns the same length to all packets + * within a transfer, which is usually what you want. + * + * For outgoing transfers, you'll obviously fill the buffer and populate the + * packet descriptors in hope that all the data gets transferred. For incoming + * transfers, you must ensure the buffer has sufficient capacity for + * the situation where all packets transfer the full amount of requested data. + * + * Completion handling requires some extra consideration. The + * \ref libusb_transfer::actual_length "actual_length" field of the transfer + * is meaningless and should not be examined; instead you must refer to the + * \ref libusb_iso_packet_descriptor::actual_length "actual_length" field of + * each individual packet. + * + * The \ref libusb_transfer::status "status" field of the transfer is also a + * little misleading: + * - If the packets were submitted and the isochronous data microframes + * completed normally, status will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_COMPLETED + * "LIBUSB_TRANSFER_COMPLETED". Note that bus errors and software-incurred + * delays are not counted as transfer errors; the transfer.status field may + * indicate COMPLETED even if some or all of the packets failed. Refer to + * the \ref libusb_iso_packet_descriptor::status "status" field of each + * individual packet to determine packet failures. + * - The status field will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR + * "LIBUSB_TRANSFER_ERROR" only when serious errors were encountered. + * - Other transfer status codes occur with normal behaviour. + * + * The data for each packet will be found at an offset into the buffer that + * can be calculated as if each prior packet completed in full. The + * libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple() + * functions may help you here. + * + * Note: Some operating systems (e.g. Linux) may impose limits on the + * length of individual isochronous packets and/or the total length of the + * isochronous transfer. Such limits can be difficult for libusb to detect, + * so the library will simply try and submit the transfer as set up by you. + * If the transfer fails to submit because it is too large, + * libusb_submit_transfer() will return + * \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM". + * + * \section asyncmem Memory caveats + * + * In most circumstances, it is not safe to use stack memory for transfer + * buffers. This is because the function that fired off the asynchronous + * transfer may return before libusb has finished using the buffer, and when + * the function returns it's stack gets destroyed. This is true for both + * host-to-device and device-to-host transfers. + * + * The only case in which it is safe to use stack memory is where you can + * guarantee that the function owning the stack space for the buffer does not + * return until after the transfer's callback function has completed. In every + * other case, you need to use heap memory instead. + * + * \section asyncflags Fine control + * + * Through using this asynchronous interface, you may find yourself repeating + * a few simple operations many times. You can apply a bitwise OR of certain + * flags to a transfer to simplify certain things: + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_SHORT_NOT_OK + * "LIBUSB_TRANSFER_SHORT_NOT_OK" results in transfers which transferred + * less than the requested amount of data being marked with status + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR "LIBUSB_TRANSFER_ERROR" + * (they would normally be regarded as COMPLETED) + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusb to free the transfer + * buffer when freeing the transfer. + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_TRANSFER + * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusb to automatically free the + * transfer after the transfer callback returns. + * + * \section asyncevent Event handling + * + * An asynchronous model requires that libusb perform work at various + * points in time - namely processing the results of previously-submitted + * transfers and invoking the user-supplied callback function. + * + * This gives rise to the libusb_handle_events() function which your + * application must call into when libusb has work do to. This gives libusb + * the opportunity to reap pending transfers, invoke callbacks, etc. + * + * There are 2 different approaches to dealing with libusb_handle_events: + * + * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated + * thread. + * -# Integrate libusb with your application's main event loop. libusb + * exposes a set of file descriptors which allow you to do this. + * + * The first approach has the big advantage that it will also work on Windows + * were libusb' poll API for select / poll integration is not available. So + * if you want to support Windows and use the async API, you must use this + * approach, see the \ref eventthread "Using an event handling thread" section + * below for details. + * + * If you prefer a single threaded approach with a single central event loop, + * see the \ref libusb_poll "polling and timing" section for how to integrate libusb + * into your application's main event loop. + * + * \section eventthread Using an event handling thread + * + * Lets begin with stating the obvious: If you're going to use a separate + * thread for libusb event handling, your callback functions MUST be + * threadsafe. + * + * Other then that doing event handling from a separate thread, is mostly + * simple. You can use an event thread function as follows: +\code +void *event_thread_func(void *ctx) +{ + while (event_thread_run) + libusb_handle_events(ctx); + + return NULL; +} +\endcode + * + * There is one caveat though, stopping this thread requires setting the + * event_thread_run variable to 0, and after that libusb_handle_events() needs + * to return control to event_thread_func. But unless some event happens, + * libusb_handle_events() will not return. + * + * There are 2 different ways of dealing with this, depending on if your + * application uses libusb' \ref libusb_hotplug "hotplug" support or not. + * + * Applications which do not use hotplug support, should not start the event + * thread until after their first call to libusb_open(), and should stop the + * thread when closing the last open device as follows: +\code +void my_close_handle(libusb_device_handle *dev_handle) +{ + if (open_devs == 1) + event_thread_run = 0; + + libusb_close(dev_handle); // This wakes up libusb_handle_events() + + if (open_devs == 1) + pthread_join(event_thread); + + open_devs--; +} +\endcode + * + * Applications using hotplug support should start the thread at program init, + * after having successfully called libusb_hotplug_register_callback(), and + * should stop the thread at program exit as follows: +\code +void my_libusb_exit(void) +{ + event_thread_run = 0; + libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events() + pthread_join(event_thread); + libusb_exit(ctx); +} +\endcode + */ + +/** + * @defgroup libusb_poll Polling and timing + * + * This page documents libusb's functions for polling events and timing. + * These functions are only necessary for users of the + * \ref libusb_asyncio "asynchronous API". If you are only using the simpler + * \ref libusb_syncio "synchronous API" then you do not need to ever call these + * functions. + * + * The justification for the functionality described here has already been + * discussed in the \ref asyncevent "event handling" section of the + * asynchronous API documentation. In summary, libusb does not create internal + * threads for event processing and hence relies on your application calling + * into libusb at certain points in time so that pending events can be handled. + * + * Your main loop is probably already calling poll() or select() or a + * variant on a set of file descriptors for other event sources (e.g. keyboard + * button presses, mouse movements, network sockets, etc). You then add + * libusb's file descriptors to your poll()/select() calls, and when activity + * is detected on such descriptors you know it is time to call + * libusb_handle_events(). + * + * There is one final event handling complication. libusb supports + * asynchronous transfers which time out after a specified time period. + * + * On some platforms a timerfd is used, so the timeout handling is just another + * fd, on other platforms this requires that libusb is called into at or after + * the timeout to handle it. So, in addition to considering libusb's file + * descriptors in your main event loop, you must also consider that libusb + * sometimes needs to be called into at fixed points in time even when there + * is no file descriptor activity, see \ref polltime details. + * + * In order to know precisely when libusb needs to be called into, libusb + * offers you a set of pollable file descriptors and information about when + * the next timeout expires. + * + * If you are using the asynchronous I/O API, you must take one of the two + * following options, otherwise your I/O will not complete. + * + * \section pollsimple The simple option + * + * If your application revolves solely around libusb and does not need to + * handle other event sources, you can have a program structure as follows: +\code +// initialize libusb +// find and open device +// maybe fire off some initial async I/O + +while (user_has_not_requested_exit) + libusb_handle_events(ctx); + +// clean up and exit +\endcode + * + * With such a simple main loop, you do not have to worry about managing + * sets of file descriptors or handling timeouts. libusb_handle_events() will + * handle those details internally. + * + * \section libusb_pollmain The more advanced option + * + * \note This functionality is currently only available on Unix-like platforms. + * On Windows, libusb_get_pollfds() simply returns NULL. Applications which + * want to support Windows are advised to use an \ref eventthread + * "event handling thread" instead. + * + * In more advanced applications, you will already have a main loop which + * is monitoring other event sources: network sockets, X11 events, mouse + * movements, etc. Through exposing a set of file descriptors, libusb is + * designed to cleanly integrate into such main loops. + * + * In addition to polling file descriptors for the other event sources, you + * take a set of file descriptors from libusb and monitor those too. When you + * detect activity on libusb's file descriptors, you call + * libusb_handle_events_timeout() in non-blocking mode. + * + * What's more, libusb may also need to handle events at specific moments in + * time. No file descriptor activity is generated at these times, so your + * own application needs to be continually aware of when the next one of these + * moments occurs (through calling libusb_get_next_timeout()), and then it + * needs to call libusb_handle_events_timeout() in non-blocking mode when + * these moments occur. This means that you need to adjust your + * poll()/select() timeout accordingly. + * + * libusb provides you with a set of file descriptors to poll and expects you + * to poll all of them, treating them as a single entity. The meaning of each + * file descriptor in the set is an internal implementation detail, + * platform-dependent and may vary from release to release. Don't try and + * interpret the meaning of the file descriptors, just do as libusb indicates, + * polling all of them at once. + * + * In pseudo-code, you want something that looks like: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + libusb_get_next_timeout(ctx); + poll(on libusb file descriptors plus any other event sources of interest, + using a timeout no larger than the value libusb just suggested) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + if (time has elapsed to or beyond the libusb timeout) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * \subsection polltime Notes on time-based events + * + * The above complication with having to track time and call into libusb at + * specific moments is a bit of a headache. For maximum compatibility, you do + * need to write your main loop as above, but you may decide that you can + * restrict the supported platforms of your application and get away with + * a more simplistic scheme. + * + * These time-based event complications are \b not required on the following + * platforms: + * - Darwin + * - Linux, provided that the following version requirements are satisfied: + * - Linux v2.6.27 or newer, compiled with timerfd support + * - glibc v2.9 or newer + * - libusb v1.0.5 or newer + * + * Under these configurations, libusb_get_next_timeout() will \em always return + * 0, so your main loop can be simplified to: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + poll(on libusb file descriptors plus any other event sources of interest, + using any timeout that you like) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * Do remember that if you simplify your main loop to the above, you will + * lose compatibility with some platforms (including legacy Linux platforms, + * and any future platforms supported by libusb which may have time-based + * event requirements). The resultant problems will likely appear as + * strange bugs in your application. + * + * You can use the libusb_pollfds_handle_timeouts() function to do a runtime + * check to see if it is safe to ignore the time-based event complications. + * If your application has taken the shortcut of ignoring libusb's next timeout + * in your main loop, then you are advised to check the return value of + * libusb_pollfds_handle_timeouts() during application startup, and to abort + * if the platform does suffer from these timing complications. + * + * \subsection fdsetchange Changes in the file descriptor set + * + * The set of file descriptors that libusb uses as event sources may change + * during the life of your application. Rather than having to repeatedly + * call libusb_get_pollfds(), you can set up notification functions for when + * the file descriptor set changes using libusb_set_pollfd_notifiers(). + * + * \subsection mtissues Multi-threaded considerations + * + * Unfortunately, the situation is complicated further when multiple threads + * come into play. If two threads are monitoring the same file descriptors, + * the fact that only one thread will be woken up when an event occurs causes + * some headaches. + * + * The events lock, event waiters lock, and libusb_handle_events_locked() + * entities are added to solve these problems. You do not need to be concerned + * with these entities otherwise. + * + * See the extra documentation: \ref libusb_mtasync + */ + +/** \page libusb_mtasync Multi-threaded applications and asynchronous I/O + * + * libusb is a thread-safe library, but extra considerations must be applied + * to applications which interact with libusb from multiple threads. + * + * The underlying issue that must be addressed is that all libusb I/O + * revolves around monitoring file descriptors through the poll()/select() + * system calls. This is directly exposed at the + * \ref libusb_asyncio "asynchronous interface" but it is important to note that the + * \ref libusb_syncio "synchronous interface" is implemented on top of the + * asynchonrous interface, therefore the same considerations apply. + * + * The issue is that if two or more threads are concurrently calling poll() + * or select() on libusb's file descriptors then only one of those threads + * will be woken up when an event arrives. The others will be completely + * oblivious that anything has happened. + * + * Consider the following pseudo-code, which submits an asynchronous transfer + * then waits for its completion. This style is one way you could implement a + * synchronous interface on top of the asynchronous interface (and libusb + * does something similar, albeit more advanced due to the complications + * explained on this page). + * +\code +void cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; +} + +void myfunc() { + struct libusb_transfer *transfer; + unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned (2))); + int completed = 0; + + transfer = libusb_alloc_transfer(0); + libusb_fill_control_setup(buffer, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 0x04, 0x01, 0, 0); + libusb_fill_control_transfer(transfer, dev, buffer, cb, &completed, 1000); + libusb_submit_transfer(transfer); + + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + printf("completed!"); + // other code here +} +\endcode + * + * Here we are serializing completion of an asynchronous event + * against a condition - the condition being completion of a specific transfer. + * The poll() loop has a long timeout to minimize CPU usage during situations + * when nothing is happening (it could reasonably be unlimited). + * + * If this is the only thread that is polling libusb's file descriptors, there + * is no problem: there is no danger that another thread will swallow up the + * event that we are interested in. On the other hand, if there is another + * thread polling the same descriptors, there is a chance that it will receive + * the event that we were interested in. In this situation, myfunc() + * will only realise that the transfer has completed on the next iteration of + * the loop, up to 120 seconds later. Clearly a two-minute delay is + * undesirable, and don't even think about using short timeouts to circumvent + * this issue! + * + * The solution here is to ensure that no two threads are ever polling the + * file descriptors at the same time. A naive implementation of this would + * impact the capabilities of the library, so libusb offers the scheme + * documented below to ensure no loss of functionality. + * + * Before we go any further, it is worth mentioning that all libusb-wrapped + * event handling procedures fully adhere to the scheme documented below. + * This includes libusb_handle_events() and its variants, and all the + * synchronous I/O functions - libusb hides this headache from you. + * + * \section Using libusb_handle_events() from multiple threads + * + * Even when only using libusb_handle_events() and synchronous I/O functions, + * you can still have a race condition. You might be tempted to solve the + * above with libusb_handle_events() like so: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events(ctx); + } + printf("completed!"); +\endcode + * + * This however has a race between the checking of completed and + * libusb_handle_events() acquiring the events lock, so another thread + * could have completed the transfer, resulting in this thread hanging + * until either a timeout or another event occurs. See also commit + * 6696512aade99bb15d6792af90ae329af270eba6 which fixes this in the + * synchronous API implementation of libusb. + * + * Fixing this race requires checking the variable completed only after + * taking the event lock, which defeats the concept of just calling + * libusb_handle_events() without worrying about locking. This is why + * libusb-1.0.9 introduces the new libusb_handle_events_timeout_completed() + * and libusb_handle_events_completed() functions, which handles doing the + * completion check for you after they have acquired the lock: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events_completed(ctx, &completed); + } + printf("completed!"); +\endcode + * + * This nicely fixes the race in our example. Note that if all you want to + * do is submit a single transfer and wait for its completion, then using + * one of the synchronous I/O functions is much easier. + * + * \section eventlock The events lock + * + * The problem is when we consider the fact that libusb exposes file + * descriptors to allow for you to integrate asynchronous USB I/O into + * existing main loops, effectively allowing you to do some work behind + * libusb's back. If you do take libusb's file descriptors and pass them to + * poll()/select() yourself, you need to be aware of the associated issues. + * + * The first concept to be introduced is the events lock. The events lock + * is used to serialize threads that want to handle events, such that only + * one thread is handling events at any one time. + * + * You must take the events lock before polling libusb file descriptors, + * using libusb_lock_events(). You must release the lock as soon as you have + * aborted your poll()/select() loop, using libusb_unlock_events(). + * + * \section threadwait Letting other threads do the work for you + * + * Although the events lock is a critical part of the solution, it is not + * enough on it's own. You might wonder if the following is sufficient... +\code + libusb_lock_events(ctx); + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + libusb_unlock_events(ctx); +\endcode + * ...and the answer is that it is not. This is because the transfer in the + * code shown above may take a long time (say 30 seconds) to complete, and + * the lock is not released until the transfer is completed. + * + * Another thread with similar code that wants to do event handling may be + * working with a transfer that completes after a few milliseconds. Despite + * having such a quick completion time, the other thread cannot check that + * status of its transfer until the code above has finished (30 seconds later) + * due to contention on the lock. + * + * To solve this, libusb offers you a mechanism to determine when another + * thread is handling events. It also offers a mechanism to block your thread + * until the event handling thread has completed an event (and this mechanism + * does not involve polling of file descriptors). + * + * After determining that another thread is currently handling events, you + * obtain the event waiters lock using libusb_lock_event_waiters(). + * You then re-check that some other thread is still handling events, and if + * so, you call libusb_wait_for_event(). + * + * libusb_wait_for_event() puts your application to sleep until an event + * occurs, or until a thread releases the events lock. When either of these + * things happen, your thread is woken up, and should re-check the condition + * it was waiting on. It should also re-check that another thread is handling + * events, and if not, it should start handling events itself. + * + * This looks like the following, as pseudo-code: +\code +retry: +if (libusb_try_lock_events(ctx) == 0) { + // we obtained the event lock: do our own event handling + while (!completed) { + if (!libusb_event_handling_ok(ctx)) { + libusb_unlock_events(ctx); + goto retry; + } + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_locked(ctx, 0); + } + libusb_unlock_events(ctx); +} else { + // another thread is doing event handling. wait for it to signal us that + // an event has completed + libusb_lock_event_waiters(ctx); + + while (!completed) { + // now that we have the event waiters lock, double check that another + // thread is still handling events for us. (it may have ceased handling + // events in the time it took us to reach this point) + if (!libusb_event_handler_active(ctx)) { + // whoever was handling events is no longer doing so, try again + libusb_unlock_event_waiters(ctx); + goto retry; + } + + libusb_wait_for_event(ctx, NULL); + } + libusb_unlock_event_waiters(ctx); +} +printf("completed!\n"); +\endcode + * + * A naive look at the above code may suggest that this can only support + * one event waiter (hence a total of 2 competing threads, the other doing + * event handling), because the event waiter seems to have taken the event + * waiters lock while waiting for an event. However, the system does support + * multiple event waiters, because libusb_wait_for_event() actually drops + * the lock while waiting, and reaquires it before continuing. + * + * We have now implemented code which can dynamically handle situations where + * nobody is handling events (so we should do it ourselves), and it can also + * handle situations where another thread is doing event handling (so we can + * piggyback onto them). It is also equipped to handle a combination of + * the two, for example, another thread is doing event handling, but for + * whatever reason it stops doing so before our condition is met, so we take + * over the event handling. + * + * Four functions were introduced in the above pseudo-code. Their importance + * should be apparent from the code shown above. + * -# libusb_try_lock_events() is a non-blocking function which attempts + * to acquire the events lock but returns a failure code if it is contended. + * -# libusb_event_handling_ok() checks that libusb is still happy for your + * thread to be performing event handling. Sometimes, libusb needs to + * interrupt the event handler, and this is how you can check if you have + * been interrupted. If this function returns 0, the correct behaviour is + * for you to give up the event handling lock, and then to repeat the cycle. + * The following libusb_try_lock_events() will fail, so you will become an + * events waiter. For more information on this, read \ref fullstory below. + * -# libusb_handle_events_locked() is a variant of + * libusb_handle_events_timeout() that you can call while holding the + * events lock. libusb_handle_events_timeout() itself implements similar + * logic to the above, so be sure not to call it when you are + * "working behind libusb's back", as is the case here. + * -# libusb_event_handler_active() determines if someone is currently + * holding the events lock + * + * You might be wondering why there is no function to wake up all threads + * blocked on libusb_wait_for_event(). This is because libusb can do this + * internally: it will wake up all such threads when someone calls + * libusb_unlock_events() or when a transfer completes (at the point after its + * callback has returned). + * + * \subsection fullstory The full story + * + * The above explanation should be enough to get you going, but if you're + * really thinking through the issues then you may be left with some more + * questions regarding libusb's internals. If you're curious, read on, and if + * not, skip to the next section to avoid confusing yourself! + * + * The immediate question that may spring to mind is: what if one thread + * modifies the set of file descriptors that need to be polled while another + * thread is doing event handling? + * + * There are 2 situations in which this may happen. + * -# libusb_open() will add another file descriptor to the poll set, + * therefore it is desirable to interrupt the event handler so that it + * restarts, picking up the new descriptor. + * -# libusb_close() will remove a file descriptor from the poll set. There + * are all kinds of race conditions that could arise here, so it is + * important that nobody is doing event handling at this time. + * + * libusb handles these issues internally, so application developers do not + * have to stop their event handlers while opening/closing devices. Here's how + * it works, focusing on the libusb_close() situation first: + * + * -# During initialization, libusb opens an internal pipe, and it adds the read + * end of this pipe to the set of file descriptors to be polled. + * -# During libusb_close(), libusb writes some dummy data on this event pipe. + * This immediately interrupts the event handler. libusb also records + * internally that it is trying to interrupt event handlers for this + * high-priority event. + * -# At this point, some of the functions described above start behaving + * differently: + * - libusb_event_handling_ok() starts returning 1, indicating that it is NOT + * OK for event handling to continue. + * - libusb_try_lock_events() starts returning 1, indicating that another + * thread holds the event handling lock, even if the lock is uncontended. + * - libusb_event_handler_active() starts returning 1, indicating that + * another thread is doing event handling, even if that is not true. + * -# The above changes in behaviour result in the event handler stopping and + * giving up the events lock very quickly, giving the high-priority + * libusb_close() operation a "free ride" to acquire the events lock. All + * threads that are competing to do event handling become event waiters. + * -# With the events lock held inside libusb_close(), libusb can safely remove + * a file descriptor from the poll set, in the safety of knowledge that + * nobody is polling those descriptors or trying to access the poll set. + * -# After obtaining the events lock, the close operation completes very + * quickly (usually a matter of milliseconds) and then immediately releases + * the events lock. + * -# At the same time, the behaviour of libusb_event_handling_ok() and friends + * reverts to the original, documented behaviour. + * -# The release of the events lock causes the threads that are waiting for + * events to be woken up and to start competing to become event handlers + * again. One of them will succeed; it will then re-obtain the list of poll + * descriptors, and USB I/O will then continue as normal. + * + * libusb_open() is similar, and is actually a more simplistic case. Upon a + * call to libusb_open(): + * + * -# The device is opened and a file descriptor is added to the poll set. + * -# libusb sends some dummy data on the event pipe, and records that it + * is trying to modify the poll descriptor set. + * -# The event handler is interrupted, and the same behaviour change as for + * libusb_close() takes effect, causing all event handling threads to become + * event waiters. + * -# The libusb_open() implementation takes its free ride to the events lock. + * -# Happy that it has successfully paused the events handler, libusb_open() + * releases the events lock. + * -# The event waiter threads are all woken up and compete to become event + * handlers again. The one that succeeds will obtain the list of poll + * descriptors again, which will include the addition of the new device. + * + * \subsection concl Closing remarks + * + * The above may seem a little complicated, but hopefully I have made it clear + * why such complications are necessary. Also, do not forget that this only + * applies to applications that take libusb's file descriptors and integrate + * them into their own polling loops. + * + * You may decide that it is OK for your multi-threaded application to ignore + * some of the rules and locks detailed above, because you don't think that + * two threads can ever be polling the descriptors at the same time. If that + * is the case, then that's good news for you because you don't have to worry. + * But be careful here; remember that the synchronous I/O functions do event + * handling internally. If you have one thread doing event handling in a loop + * (without implementing the rules and locking semantics documented above) + * and another trying to send a synchronous USB transfer, you will end up with + * two threads monitoring the same descriptors, and the above-described + * undesirable behaviour occurring. The solution is for your polling thread to + * play by the rules; the synchronous I/O functions do so, and this will result + * in them getting along in perfect harmony. + * + * If you do have a dedicated thread doing event handling, it is perfectly + * legal for it to take the event handling lock for long periods of time. Any + * synchronous I/O functions you call from other threads will transparently + * fall back to the "event waiters" mechanism detailed above. The only + * consideration that your event handling thread must apply is the one related + * to libusb_event_handling_ok(): you must call this before every poll(), and + * give up the events lock if instructed. + */ + +int usbi_io_init(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_init(&ctx->flying_transfers_lock); + usbi_mutex_init(&ctx->events_lock); + usbi_mutex_init(&ctx->event_waiters_lock); + usbi_cond_init(&ctx->event_waiters_cond); + usbi_mutex_init(&ctx->event_data_lock); + usbi_tls_key_create(&ctx->event_handling_key); + list_init(&ctx->flying_transfers); + list_init(&ctx->ipollfds); + list_init(&ctx->hotplug_msgs); + list_init(&ctx->completed_transfers); + + /* FIXME should use an eventfd on kernels that support it */ + r = usbi_pipe(ctx->event_pipe); + if (r < 0) { + r = LIBUSB_ERROR_OTHER; + goto err; + } + + r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN); + if (r < 0) + goto err_close_pipe; + +#ifdef USBI_TIMERFD_AVAILABLE + ctx->timerfd = timerfd_create(usbi_backend.get_timerfd_clockid(), + TFD_NONBLOCK | TFD_CLOEXEC); + if (ctx->timerfd >= 0) { + usbi_dbg("using timerfd for timeouts"); + r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN); + if (r < 0) + goto err_close_timerfd; + } else { + usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno); + ctx->timerfd = -1; + } +#endif + + return 0; + +#ifdef USBI_TIMERFD_AVAILABLE +err_close_timerfd: + close(ctx->timerfd); + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); +#endif +err_close_pipe: + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +err: + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + return r; +} + +void usbi_io_exit(struct libusb_context *ctx) +{ + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +#ifdef USBI_TIMERFD_AVAILABLE + if (usbi_using_timerfd(ctx)) { + usbi_remove_pollfd(ctx, ctx->timerfd); + close(ctx->timerfd); + } +#endif + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + if (ctx->pollfds) + free(ctx->pollfds); +} + +static int calculate_timeout(struct usbi_transfer *transfer) +{ + int r; + struct timespec current_time; + unsigned int timeout = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout; + + if (!timeout) { + timerclear(&transfer->timeout); + return 0; + } + + r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, ¤t_time); + if (r < 0) { + usbi_err(ITRANSFER_CTX(transfer), + "failed to read monotonic clock, errno=%d", errno); + return r; + } + + current_time.tv_sec += timeout / 1000; + current_time.tv_nsec += (timeout % 1000) * 1000000; + + while (current_time.tv_nsec >= 1000000000) { + current_time.tv_nsec -= 1000000000; + current_time.tv_sec++; + } + + TIMESPEC_TO_TIMEVAL(&transfer->timeout, ¤t_time); + return 0; +} + +/** \ingroup libusb_asyncio + * Allocate a libusb transfer with a specified number of isochronous packet + * descriptors. The returned transfer is pre-initialized for you. When the new + * transfer is no longer needed, it should be freed with + * libusb_free_transfer(). + * + * Transfers intended for non-isochronous endpoints (e.g. control, bulk, + * interrupt) should specify an iso_packets count of zero. + * + * For transfers intended for isochronous endpoints, specify an appropriate + * number of packet descriptors to be allocated as part of the transfer. + * The returned transfer is not specially initialized for isochronous I/O; + * you are still required to set the + * \ref libusb_transfer::num_iso_packets "num_iso_packets" and + * \ref libusb_transfer::type "type" fields accordingly. + * + * It is safe to allocate a transfer with some isochronous packets and then + * use it on a non-isochronous endpoint. If you do this, ensure that at time + * of submission, num_iso_packets is 0 and that type is set appropriately. + * + * \param iso_packets number of isochronous packet descriptors to allocate + * \returns a newly allocated transfer, or NULL on error + */ +DEFAULT_VISIBILITY +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( + int iso_packets) +{ + struct libusb_transfer *transfer; + size_t os_alloc_size = usbi_backend.transfer_priv_size; + size_t alloc_size = sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (sizeof(struct libusb_iso_packet_descriptor) * iso_packets) + + os_alloc_size; + struct usbi_transfer *itransfer = calloc(1, alloc_size); + if (!itransfer) + return NULL; + + itransfer->num_iso_packets = iso_packets; + usbi_mutex_init(&itransfer->lock); + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + usbi_dbg("transfer %p", transfer); + return transfer; +} + +/** \ingroup libusb_asyncio + * Free a transfer structure. This should be called for all transfers + * allocated with libusb_alloc_transfer(). + * + * If the \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" flag is set and the transfer buffer is + * non-NULL, this function will also free the transfer buffer using the + * standard system memory allocator (e.g. free()). + * + * It is legal to call this function with a NULL transfer. In this case, + * the function will simply return safely. + * + * It is not legal to free an active transfer (one which has been submitted + * and has not yet completed). + * + * \param transfer the transfer to free + */ +void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer; + if (!transfer) + return; + + usbi_dbg("transfer %p", transfer); + if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER && transfer->buffer) + free(transfer->buffer); + + itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + usbi_mutex_destroy(&itransfer->lock); + free(itransfer); +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int disarm_timerfd(struct libusb_context *ctx) +{ + const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } }; + int r; + + usbi_dbg(""); + r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + else + return 0; +} + +/* iterates through the flying transfers, and rearms the timerfd based on the + * next upcoming timeout. + * must be called with flying_list locked. + * returns 0 on success or a LIBUSB_ERROR code on failure. + */ +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + struct usbi_transfer *transfer; + + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, then we have no + * arming to do */ + if (!timerisset(cur_tv)) + goto disarm; + + /* act on first transfer that has not already been handled */ + if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) { + int r; + const struct itimerspec it = { {0, 0}, + { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } }; + usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + return 0; + } + } + +disarm: + return disarm_timerfd(ctx); +} +#else +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + UNUSED(ctx); + return 0; +} +#endif + +/* add a transfer to the (timeout-sorted) active transfers list. + * This function will return non 0 if fails to update the timer, + * in which case the transfer is *not* on the flying_transfers list. */ +static int add_to_flying_list(struct usbi_transfer *transfer) +{ + struct usbi_transfer *cur; + struct timeval *timeout = &transfer->timeout; + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int r; + int first = 1; + + r = calculate_timeout(transfer); + if (r) + return r; + + /* if we have no other flying transfers, start the list with this one */ + if (list_empty(&ctx->flying_transfers)) { + list_add(&transfer->list, &ctx->flying_transfers); + goto out; + } + + /* if we have infinite timeout, append to end of list */ + if (!timerisset(timeout)) { + list_add_tail(&transfer->list, &ctx->flying_transfers); + /* first is irrelevant in this case */ + goto out; + } + + /* otherwise, find appropriate place in list */ + list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) { + /* find first timeout that occurs after the transfer in question */ + struct timeval *cur_tv = &cur->timeout; + + if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) || + (cur_tv->tv_sec == timeout->tv_sec && + cur_tv->tv_usec > timeout->tv_usec)) { + list_add_tail(&transfer->list, &cur->list); + goto out; + } + first = 0; + } + /* first is 0 at this stage (list not empty) */ + + /* otherwise we need to be inserted at the end */ + list_add_tail(&transfer->list, &ctx->flying_transfers); +out: +#ifdef USBI_TIMERFD_AVAILABLE + if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) { + /* if this transfer has the lowest timeout of all active transfers, + * rearm the timerfd with this transfer's timeout */ + const struct itimerspec it = { {0, 0}, + { timeout->tv_sec, timeout->tv_usec * 1000 } }; + usbi_dbg("arm timerfd for timeout in %dms (first in line)", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) { + usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno); + r = LIBUSB_ERROR_OTHER; + } + } +#else + UNUSED(first); +#endif + + if (r) + list_del(&transfer->list); + + return r; +} + +/* remove a transfer from the active transfers list. + * This function will *always* remove the transfer from the + * flying_transfers list. It will return a LIBUSB_ERROR code + * if it fails to update the timer for the next timeout. */ +static int remove_from_flying_list(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int rearm_timerfd; + int r = 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + rearm_timerfd = (timerisset(&transfer->timeout) && + list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == transfer); + list_del(&transfer->list); + if (usbi_using_timerfd(ctx) && rearm_timerfd) + r = arm_timerfd_for_next_timeout(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + return r; +} + +/** \ingroup libusb_asyncio + * Submit a transfer. This function will fire off the USB transfer and then + * return immediately. + * + * \param transfer the transfer to submit + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted. + * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported + * by the operating system. + * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than + * the operating system and/or hardware can support + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + int r; + + usbi_dbg("transfer %p", transfer); + + /* + * Important note on locking, this function takes / releases locks + * in the following order: + * take flying_transfers_lock + * take itransfer->lock + * clear transfer + * add to flying_transfers list + * release flying_transfers_lock + * submit transfer + * release itransfer->lock + * if submit failed: + * take flying_transfers_lock + * remove from flying_transfers list + * release flying_transfers_lock + * + * Note that it takes locks in the order a-b and then releases them + * in the same order a-b. This is somewhat unusual but not wrong, + * release order is not important as long as *all* locks are released + * before re-acquiring any locks. + * + * This means that the ordering of first releasing itransfer->lock + * and then re-acquiring the flying_transfers_list on error is + * important and must not be changed! + * + * This is done this way because when we take both locks we must always + * take flying_transfers_lock first to avoid ab-ba style deadlocks with + * the timeout handling and usbi_handle_disconnect paths. + * + * And we cannot release itransfer->lock before the submission is + * complete otherwise timeout handling for transfers with short + * timeouts may run before submission. + */ + usbi_mutex_lock(&ctx->flying_transfers_lock); + usbi_mutex_lock(&itransfer->lock); + if (itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&itransfer->lock); + return LIBUSB_ERROR_BUSY; + } + itransfer->transferred = 0; + itransfer->state_flags = 0; + itransfer->timeout_flags = 0; + r = add_to_flying_list(itransfer); + if (r) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_mutex_unlock(&itransfer->lock); + return r; + } + /* + * We must release the flying transfers lock here, because with + * some backends the submit_transfer method is synchroneous. + */ + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + r = usbi_backend.submit_transfer(itransfer); + if (r == LIBUSB_SUCCESS) { + itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT; + /* keep a reference to this device */ + libusb_ref_device(transfer->dev_handle->dev); + } + usbi_mutex_unlock(&itransfer->lock); + + if (r != LIBUSB_SUCCESS) + remove_from_flying_list(itransfer); + + return r; +} + +/** \ingroup libusb_asyncio + * Asynchronously cancel a previously submitted transfer. + * This function returns immediately, but this does not indicate cancellation + * is complete. Your callback function will be invoked at some later time + * with a transfer status of + * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED + * "LIBUSB_TRANSFER_CANCELLED." + * + * \param transfer the transfer to cancel + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress, + * already complete, or already cancelled. + * \returns a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + int r; + + usbi_dbg("transfer %p", transfer ); + usbi_mutex_lock(&itransfer->lock); + if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) + || (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + r = usbi_backend.cancel_transfer(itransfer); + if (r < 0) { + if (r != LIBUSB_ERROR_NOT_FOUND && + r != LIBUSB_ERROR_NO_DEVICE) + usbi_err(TRANSFER_CTX(transfer), + "cancel transfer failed error %d", r); + else + usbi_dbg("cancel transfer failed error %d", r); + + if (r == LIBUSB_ERROR_NO_DEVICE) + itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED; + } + + itransfer->state_flags |= USBI_TRANSFER_CANCELLING; + +out: + usbi_mutex_unlock(&itransfer->lock); + return r; +} + +/** \ingroup libusb_asyncio + * Set a transfers bulk stream id. Note users are advised to use + * libusb_fill_bulk_stream_transfer() instead of calling this function + * directly. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to set the stream id for + * \param stream_id the stream id to set + * \see libusb_alloc_streams() + */ +void API_EXPORTED libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + itransfer->stream_id = stream_id; +} + +/** \ingroup libusb_asyncio + * Get a transfers bulk stream id. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to get the stream id for + * \returns the stream id for the transfer + */ +uint32_t API_EXPORTED libusb_transfer_get_stream_id( + struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + return itransfer->stream_id; +} + +/* Handle completion of a transfer (completion might be an error condition). + * This will invoke the user-supplied callback function, which may end up + * freeing the transfer. Therefore you cannot use the transfer structure + * after calling this function, and you should free all backend-specific + * data before calling it. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_device_handle *dev_handle = transfer->dev_handle; + uint8_t flags; + int r; + + r = remove_from_flying_list(itransfer); + if (r < 0) + usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno); + + usbi_mutex_lock(&itransfer->lock); + itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT; + usbi_mutex_unlock(&itransfer->lock); + + if (status == LIBUSB_TRANSFER_COMPLETED + && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { + int rqlen = transfer->length; + if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL) + rqlen -= LIBUSB_CONTROL_SETUP_SIZE; + if (rqlen != itransfer->transferred) { + usbi_dbg("interpreting short transfer as error"); + status = LIBUSB_TRANSFER_ERROR; + } + } + + flags = transfer->flags; + transfer->status = status; + transfer->actual_length = itransfer->transferred; + usbi_dbg("transfer %p has callback %p", transfer, transfer->callback); + if (transfer->callback) + transfer->callback(transfer); + /* transfer might have been freed by the above call, do not use from + * this point. */ + if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) + libusb_free_transfer(transfer); + libusb_unref_device(dev_handle->dev); + return r; +} + +/* Similar to usbi_handle_transfer_completion() but exclusively for transfers + * that were asynchronously cancelled. The same concerns w.r.t. freeing of + * transfers exist here. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + uint8_t timed_out; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT; + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + /* if the URB was cancelled due to timeout, report timeout to the user */ + if (timed_out) { + usbi_dbg("detected timeout cancellation"); + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT); + } + + /* otherwise its a normal async cancel */ + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED); +} + +/* Add a completed transfer to the completed_transfers list of the + * context and signal the event. The backend's handle_transfer_completion() + * function will be called the next time an event handler runs. */ +void usbi_signal_transfer_completion(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int pending_events; + + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&transfer->completed_list, &ctx->completed_transfers); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup libusb_poll + * Attempt to acquire the event handling lock. This lock is used to ensure that + * only one thread is monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if the lock was obtained successfully + * \returns 1 if the lock was not obtained (i.e. another thread holds the lock) + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_try_lock_events(libusb_context *ctx) +{ + int r; + unsigned int ru; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + ru = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (ru) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + r = usbi_mutex_trylock(&ctx->events_lock); + if (r) + return 1; + + ctx->event_handler_active = 1; + return 0; +} + +/** \ingroup libusb_poll + * Acquire the event handling lock, blocking until successful acquisition if + * it is contended. This lock is used to ensure that only one thread is + * monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_lock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->events_lock); + ctx->event_handler_active = 1; +} + +/** \ingroup libusb_poll + * Release the lock previously acquired with libusb_try_lock_events() or + * libusb_lock_events(). Releasing this lock will wake up any threads blocked + * on libusb_wait_for_event(). + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_unlock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + ctx->event_handler_active = 0; + usbi_mutex_unlock(&ctx->events_lock); + + /* FIXME: perhaps we should be a bit more efficient by not broadcasting + * the availability of the events lock when we are modifying pollfds + * (check ctx->device_close)? */ + usbi_mutex_lock(&ctx->event_waiters_lock); + usbi_cond_broadcast(&ctx->event_waiters_cond); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Determine if it is still OK for this thread to be doing event handling. + * + * Sometimes, libusb needs to temporarily pause all event handlers, and this + * is the function you should use before polling file descriptors to see if + * this is the case. + * + * If this function instructs your thread to give up the events lock, you + * should just continue the usual logic that is documented in \ref libusb_mtasync. + * On the next iteration, your thread will fail to obtain the events lock, + * and will hence become an event waiter. + * + * This function should be called while the events lock is held: you don't + * need to worry about the results of this function if your thread is not + * the current event handler. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if event handling can start or continue + * \returns 0 if this thread must give up the events lock + * \ref fullstory "Multi-threaded I/O: the full story" + */ +int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * continue event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 0; + } + + return 1; +} + + +/** \ingroup libusb_poll + * Determine if an active thread is handling events (i.e. if anyone is holding + * the event handling lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if a thread is handling events + * \returns 0 if there are no threads currently handling events + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling -- indicate that event handling is happening */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + return ctx->event_handler_active; +} + +/** \ingroup libusb_poll + * Interrupt any active thread that is handling events. This is mainly useful + * for interrupting a dedicated event handling thread when an application + * wishes to call libusb_exit(). + * + * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105 + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx) +{ + int pending_events; + USBI_GET_CONTEXT(ctx); + + usbi_dbg(""); + usbi_mutex_lock(&ctx->event_data_lock); + + pending_events = usbi_pending_events(ctx); + ctx->event_flags |= USBI_EVENT_USER_INTERRUPT; + if (!pending_events) + usbi_signal_event(ctx); + + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup libusb_poll + * Acquire the event waiters lock. This lock is designed to be obtained under + * the situation where you want to be aware when events are completed, but + * some other thread is event handling so calling libusb_handle_events() is not + * allowed. + * + * You then obtain this lock, re-check that another thread is still handling + * events, then call libusb_wait_for_event(). + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly, + * and may potentially be handling events from 2 threads simultaenously. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Release the event waiters lock. + * \param ctx the context to operate on, or NULL for the default context + * \ref libusb_mtasync + */ +void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup libusb_poll + * Wait for another thread to signal completion of an event. Must be called + * with the event waiters lock held, see libusb_lock_event_waiters(). + * + * This function will block until any of the following conditions are met: + * -# The timeout expires + * -# A transfer completes + * -# A thread releases the event handling lock through libusb_unlock_events() + * + * Condition 1 is obvious. Condition 2 unblocks your thread after + * the callback for the transfer has completed. Condition 3 is important + * because it means that the thread that was previously handling events is no + * longer doing so, so if any events are to complete, another thread needs to + * step up and start event handling. + * + * This function releases the event waiters lock before putting your thread + * to sleep, and reacquires the lock as it is being woken up. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv maximum timeout for this blocking function. A NULL value + * indicates unlimited timeout. + * \returns 0 after a transfer completes or another thread stops event handling + * \returns 1 if the timeout expired + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) +{ + int r; + + USBI_GET_CONTEXT(ctx); + if (tv == NULL) { + usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock); + return 0; + } + + r = usbi_cond_timedwait(&ctx->event_waiters_cond, + &ctx->event_waiters_lock, tv); + + if (r < 0) + return r; + else + return (r == ETIMEDOUT); +} + +static void handle_timeout(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + itransfer->timeout_flags |= USBI_TRANSFER_TIMEOUT_HANDLED; + r = libusb_cancel_transfer(transfer); + if (r == LIBUSB_SUCCESS) + itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT; + else + usbi_warn(TRANSFER_CTX(transfer), + "async cancel failed %d errno=%d", r, errno); +} + +static int handle_timeouts_locked(struct libusb_context *ctx) +{ + int r; + struct timespec systime_ts; + struct timeval systime; + struct usbi_transfer *transfer; + + if (list_empty(&ctx->flying_transfers)) + return 0; + + /* get current time */ + r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts); + if (r < 0) + return r; + + TIMESPEC_TO_TIMEVAL(&systime, &systime_ts); + + /* iterate through flying transfers list, finding all transfers that + * have expired timeouts */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, we're all done */ + if (!timerisset(cur_tv)) + return 0; + + /* ignore timeouts we've already handled */ + if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if transfer has non-expired timeout, nothing more to do */ + if ((cur_tv->tv_sec > systime.tv_sec) || + (cur_tv->tv_sec == systime.tv_sec && + cur_tv->tv_usec > systime.tv_usec)) + return 0; + + /* otherwise, we've got an expired timeout to handle */ + handle_timeout(transfer); + } + return 0; +} + +static int handle_timeouts(struct libusb_context *ctx) +{ + int r; + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->flying_transfers_lock); + r = handle_timeouts_locked(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int handle_timerfd_trigger(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* process the timeout that just happened */ + r = handle_timeouts_locked(ctx); + if (r < 0) + goto out; + + /* arm for next timeout*/ + r = arm_timerfd_for_next_timeout(ctx); + +out: + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} +#endif + +/* do the actual event handling. assumes that no other thread is concurrently + * doing the same thing. */ +static int handle_events(struct libusb_context *ctx, struct timeval *tv) +{ + int r; + struct usbi_pollfd *ipollfd; + POLL_NFDS_TYPE nfds = 0; + POLL_NFDS_TYPE internal_nfds; + struct pollfd *fds = NULL; + int i = -1; + int timeout_ms; + + /* prevent attempts to recursively handle events (e.g. calling into + * libusb_handle_events() from within a hotplug or transfer callback) */ + if (usbi_handling_events(ctx)) + return LIBUSB_ERROR_BUSY; + usbi_start_event_handling(ctx); + + /* there are certain fds that libusb uses internally, currently: + * + * 1) event pipe + * 2) timerfd + * + * the backend will never need to attempt to handle events on these fds, so + * we determine how many fds are in use internally for this context and when + * handle_events() is called in the backend, the pollfd list and count will + * be adjusted to skip over these internal fds */ + if (usbi_using_timerfd(ctx)) + internal_nfds = 2; + else + internal_nfds = 1; + + /* only reallocate the poll fds when the list of poll fds has been modified + * since the last poll, otherwise reuse them to save the additional overhead */ + usbi_mutex_lock(&ctx->event_data_lock); + if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) { + usbi_dbg("poll fds modified, reallocating"); + + if (ctx->pollfds) { + free(ctx->pollfds); + ctx->pollfds = NULL; + } + + /* sanity check - it is invalid for a context to have fewer than the + * required internal fds (memory corruption?) */ + assert(ctx->pollfds_cnt >= internal_nfds); + + ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds)); + if (!ctx->pollfds) { + usbi_mutex_unlock(&ctx->event_data_lock); + r = LIBUSB_ERROR_NO_MEM; + goto done; + } + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) { + struct libusb_pollfd *pollfd = &ipollfd->pollfd; + i++; + ctx->pollfds[i].fd = pollfd->fd; + ctx->pollfds[i].events = pollfd->events; + } + + /* reset the flag now that we have the updated list */ + ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED; + + /* if no further pending events, clear the event pipe so that we do + * not immediately return from poll */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + } + fds = ctx->pollfds; + nfds = ctx->pollfds_cnt; + usbi_mutex_unlock(&ctx->event_data_lock); + + timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + + /* round up to next millisecond */ + if (tv->tv_usec % 1000) + timeout_ms++; + + usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms); + r = usbi_poll(fds, nfds, timeout_ms); + usbi_dbg("poll() returned %d", r); + if (r == 0) { + r = handle_timeouts(ctx); + goto done; + } else if (r == -1 && errno == EINTR) { + r = LIBUSB_ERROR_INTERRUPTED; + goto done; + } else if (r < 0) { + usbi_err(ctx, "poll failed %d err=%d", r, errno); + r = LIBUSB_ERROR_IO; + goto done; + } + + /* fds[0] is always the event pipe */ + if (fds[0].revents) { + struct list_head hotplug_msgs; + struct usbi_transfer *itransfer; + int hotplug_cb_deregistered = 0; + int ret = 0; + + list_init(&hotplug_msgs); + + usbi_dbg("caught a fish on the event pipe"); + + /* take the the event data lock while processing events */ + usbi_mutex_lock(&ctx->event_data_lock); + + /* check if someone added a new poll fd */ + if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) + usbi_dbg("someone updated the poll fds"); + + if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) { + usbi_dbg("someone purposely interrupted"); + ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT; + } + + if (ctx->event_flags & USBI_EVENT_HOTPLUG_CB_DEREGISTERED) { + usbi_dbg("someone unregistered a hotplug cb"); + ctx->event_flags &= ~USBI_EVENT_HOTPLUG_CB_DEREGISTERED; + hotplug_cb_deregistered = 1; + } + + /* check if someone is closing a device */ + if (ctx->device_close) + usbi_dbg("someone is closing a device"); + + /* check for any pending hotplug messages */ + if (!list_empty(&ctx->hotplug_msgs)) { + usbi_dbg("hotplug message received"); + list_cut(&hotplug_msgs, &ctx->hotplug_msgs); + } + + /* complete any pending transfers */ + while (ret == 0 && !list_empty(&ctx->completed_transfers)) { + itransfer = list_first_entry(&ctx->completed_transfers, struct usbi_transfer, completed_list); + list_del(&itransfer->completed_list); + usbi_mutex_unlock(&ctx->event_data_lock); + ret = usbi_backend.handle_transfer_completion(itransfer); + if (ret) + usbi_err(ctx, "backend handle_transfer_completion failed with error %d", ret); + usbi_mutex_lock(&ctx->event_data_lock); + } + + /* if no further pending events, clear the event pipe */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + + usbi_mutex_unlock(&ctx->event_data_lock); + + if (hotplug_cb_deregistered) + usbi_hotplug_deregister(ctx, 0); + + /* process the hotplug messages, if any */ + while (!list_empty(&hotplug_msgs)) { + struct libusb_hotplug_message *message = + list_first_entry(&hotplug_msgs, struct libusb_hotplug_message, list); + + usbi_hotplug_match(ctx, message->device, message->event); + + /* the device left, dereference the device */ + if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message->event) + libusb_unref_device(message->device); + + list_del(&message->list); + free(message); + } + + if (ret) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto done; + } + +#ifdef USBI_TIMERFD_AVAILABLE + /* on timerfd configurations, fds[1] is the timerfd */ + if (usbi_using_timerfd(ctx) && fds[1].revents) { + /* timerfd indicates that a timeout has expired */ + int ret; + usbi_dbg("timerfd triggered"); + + ret = handle_timerfd_trigger(ctx); + if (ret < 0) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto done; + } +#endif + + r = usbi_backend.handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r); + if (r) + usbi_err(ctx, "backend handle_events failed with error %d", r); + +done: + usbi_end_event_handling(ctx); + return r; +} + +/* returns the smallest of: + * 1. timeout of next URB + * 2. user-supplied timeout + * returns 1 if there is an already-expired timeout, otherwise returns 0 + * and populates out + */ +static int get_next_timeout(libusb_context *ctx, struct timeval *tv, + struct timeval *out) +{ + struct timeval timeout; + int r = libusb_get_next_timeout(ctx, &timeout); + if (r) { + /* timeout already expired? */ + if (!timerisset(&timeout)) + return 1; + + /* choose the smallest of next URB timeout or user specified timeout */ + if (timercmp(&timeout, tv, <)) + *out = timeout; + else + *out = *tv; + } else { + *out = *tv; + } + return 0; +} + +/** \ingroup libusb_poll + * Handle any pending events. + * + * libusb determines "pending events" by checking if any timeouts have expired + * and by checking the set of file descriptors for activity. + * + * If a zero timeval is passed, this function will handle any already-pending + * events and then immediately return in non-blocking style. + * + * If a non-zero timeval is passed and no events are currently pending, this + * function will block waiting for events to handle up until the specified + * timeout. If an event arrives or a signal is raised, this function will + * return early. + * + * If the parameter completed is not NULL then after obtaining the event + * handling lock this function will return immediately if the integer + * pointed to is not 0. This allows for race free waiting for the completion + * of a specific transfer. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + +retry: + if (libusb_try_lock_events(ctx) == 0) { + if (completed == NULL || !*completed) { + /* we obtained the event lock: do our own event handling */ + usbi_dbg("doing our own event handling"); + r = handle_events(ctx, &poll_timeout); + } + libusb_unlock_events(ctx); + return r; + } + + /* another thread is doing event handling. wait for thread events that + * notify event completion. */ + libusb_lock_event_waiters(ctx); + + if (completed && *completed) + goto already_done; + + if (!libusb_event_handler_active(ctx)) { + /* we hit a race: whoever was event handling earlier finished in the + * time it took us to reach this point. try the cycle again. */ + libusb_unlock_event_waiters(ctx); + usbi_dbg("event handler was active but went away, retrying"); + goto retry; + } + + usbi_dbg("another thread is doing event handling"); + r = libusb_wait_for_event(ctx, &poll_timeout); + +already_done: + libusb_unlock_event_waiters(ctx); + + if (r < 0) + return r; + else if (r == 1) + return handle_timeouts(ctx); + else + return 0; +} + +/** \ingroup libusb_poll + * Handle any pending events + * + * Like libusb_handle_events_timeout_completed(), but without the completed + * parameter, calling this function is equivalent to calling + * libusb_handle_events_timeout_completed() with a NULL completed parameter. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv) +{ + return libusb_handle_events_timeout_completed(ctx, tv, NULL); +} + +/** \ingroup libusb_poll + * Handle any pending events in blocking mode. There is currently a timeout + * hardcoded at 60 seconds but we plan to make it unlimited in future. For + * finer control over whether this function is blocking or non-blocking, or + * for control over the timeout, use libusb_handle_events_timeout_completed() + * instead. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events(libusb_context *ctx) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, NULL); +} + +/** \ingroup libusb_poll + * Handle any pending events in blocking mode. + * + * Like libusb_handle_events(), with the addition of a completed parameter + * to allow for race free waiting for the completion of a specific transfer. + * + * See libusb_handle_events_timeout_completed() for details on the completed + * parameter. + * + * \param ctx the context to operate on, or NULL for the default context + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx, + int *completed) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, completed); +} + +/** \ingroup libusb_poll + * Handle any pending events by polling file descriptors, without checking if + * any other threads are already doing so. Must be called with the event lock + * held, see libusb_lock_events(). + * + * This function is designed to be called under the situation where you have + * taken the event lock and are calling poll()/select() directly on libusb's + * file descriptors (as opposed to using libusb_handle_events() or similar). + * You detect events on libusb's descriptors, so you then call this function + * with a zero timeout value (while still holding the event lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or zero for + * non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref libusb_mtasync + */ +int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + + return handle_events(ctx, &poll_timeout); +} + +/** \ingroup libusb_poll + * Determines whether your application must apply special timing considerations + * when monitoring libusb's file descriptors. + * + * This function is only useful for applications which retrieve and poll + * libusb's file descriptors in their own main loop (\ref libusb_pollmain). + * + * Ordinarily, libusb's event handler needs to be called into at specific + * moments in time (in addition to times when there is activity on the file + * descriptor set). The usual approach is to use libusb_get_next_timeout() + * to learn about when the next timeout occurs, and to adjust your + * poll()/select() timeout accordingly so that you can make a call into the + * library at that time. + * + * Some platforms supported by libusb do not come with this baggage - any + * events relevant to timing will be represented by activity on the file + * descriptor set, and libusb_get_next_timeout() will always return 0. + * This function allows you to detect whether you are running on such a + * platform. + * + * Since v1.0.5. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if you must call into libusb at times determined by + * libusb_get_next_timeout(), or 1 if all timeout events are handled internally + * or through regular activity on the file descriptors. + * \ref libusb_pollmain "Polling libusb file descriptors for event handling" + */ +int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx) +{ +#if defined(USBI_TIMERFD_AVAILABLE) + USBI_GET_CONTEXT(ctx); + return usbi_using_timerfd(ctx); +#else + UNUSED(ctx); + return 0; +#endif +} + +/** \ingroup libusb_poll + * Determine the next internal timeout that libusb needs to handle. You only + * need to use this function if you are calling poll() or select() or similar + * on libusb's file descriptors yourself - you do not need to use it if you + * are calling libusb_handle_events() or a variant directly. + * + * You should call this function in your main loop in order to determine how + * long to wait for select() or poll() to return results. libusb needs to be + * called into at this timeout, so you should use it as an upper bound on + * your select() or poll() call. + * + * When the timeout has expired, call into libusb_handle_events_timeout() + * (perhaps in non-blocking mode) so that libusb can handle the timeout. + * + * This function may return 1 (success) and an all-zero timeval. If this is + * the case, it indicates that libusb has a timeout that has already expired + * so you should call libusb_handle_events_timeout() or similar immediately. + * A return code of 0 indicates that there are no pending timeouts. + * + * On some platforms, this function will always returns 0 (no pending + * timeouts). See \ref polltime. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv output location for a relative time against the current + * clock in which libusb must be called into in order to process timeout events + * \returns 0 if there are no pending timeouts, 1 if a timeout was returned, + * or LIBUSB_ERROR_OTHER on failure + */ +int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv) +{ + struct usbi_transfer *transfer; + struct timespec cur_ts; + struct timeval cur_tv; + struct timeval next_timeout = { 0, 0 }; + int r; + + USBI_GET_CONTEXT(ctx); + if (usbi_using_timerfd(ctx)) + return 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + if (list_empty(&ctx->flying_transfers)) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_dbg("no URBs, no timeout!"); + return 0; + } + + /* find next transfer which hasn't already been processed as timed out */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if we've reached transfers of infinte timeout, we're done looking */ + if (!timerisset(&transfer->timeout)) + break; + + next_timeout = transfer->timeout; + break; + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (!timerisset(&next_timeout)) { + usbi_dbg("no URB with timeout or all handled by OS; no timeout!"); + return 0; + } + + r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts); + if (r < 0) { + usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno); + return 0; + } + TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); + + if (!timercmp(&cur_tv, &next_timeout, <)) { + usbi_dbg("first timeout already expired"); + timerclear(tv); + } else { + timersub(&next_timeout, &cur_tv, tv); + usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec); + } + + return 1; +} + +/** \ingroup libusb_poll + * Register notification functions for file descriptor additions/removals. + * These functions will be invoked for every new or removed file descriptor + * that libusb uses as an event source. + * + * To remove notifiers, pass NULL values for the function pointers. + * + * Note that file descriptors may have been added even before you register + * these notifiers (e.g. at libusb_init() time). + * + * Additionally, note that the removal notifier may be called during + * libusb_exit() (e.g. when it is closing file descriptors that were opened + * and added to the poll set at libusb_init() time). If you don't want this, + * remove the notifiers immediately before calling libusb_exit(). + * + * \param ctx the context to operate on, or NULL for the default context + * \param added_cb pointer to function for addition notifications + * \param removed_cb pointer to function for removal notifications + * \param user_data User data to be passed back to callbacks (useful for + * passing context information) + */ +void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data) +{ + USBI_GET_CONTEXT(ctx); + ctx->fd_added_cb = added_cb; + ctx->fd_removed_cb = removed_cb; + ctx->fd_cb_user_data = user_data; +} + +/* + * Interrupt the iteration of the event handling thread, so that it picks + * up the fd change. Callers of this function must hold the event_data_lock. + */ +static void usbi_fd_notification(struct libusb_context *ctx) +{ + int pending_events; + + /* Record that there is a new poll fd. + * Only signal an event if there are no prior pending events. */ + pending_events = usbi_pending_events(ctx); + ctx->event_flags |= USBI_EVENT_POLLFDS_MODIFIED; + if (!pending_events) + usbi_signal_event(ctx); +} + +/* Add a file descriptor to the list of file descriptors to be monitored. + * events should be specified as a bitmask of events passed to poll(), e.g. + * POLLIN and/or POLLOUT. */ +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events) +{ + struct usbi_pollfd *ipollfd = malloc(sizeof(*ipollfd)); + if (!ipollfd) + return LIBUSB_ERROR_NO_MEM; + + usbi_dbg("add fd %d events %d", fd, events); + ipollfd->pollfd.fd = fd; + ipollfd->pollfd.events = events; + usbi_mutex_lock(&ctx->event_data_lock); + list_add_tail(&ipollfd->list, &ctx->ipollfds); + ctx->pollfds_cnt++; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + if (ctx->fd_added_cb) + ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); + return 0; +} + +/* Remove a file descriptor from the list of file descriptors to be polled. */ +void usbi_remove_pollfd(struct libusb_context *ctx, int fd) +{ + struct usbi_pollfd *ipollfd; + int found = 0; + + usbi_dbg("remove fd %d", fd); + usbi_mutex_lock(&ctx->event_data_lock); + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + if (ipollfd->pollfd.fd == fd) { + found = 1; + break; + } + + if (!found) { + usbi_dbg("couldn't find fd %d to remove", fd); + usbi_mutex_unlock(&ctx->event_data_lock); + return; + } + + list_del(&ipollfd->list); + ctx->pollfds_cnt--; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + free(ipollfd); + if (ctx->fd_removed_cb) + ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); +} + +/** \ingroup libusb_poll + * Retrieve a list of file descriptors that should be polled by your main loop + * as libusb event sources. + * + * The returned list is NULL-terminated and should be freed with libusb_free_pollfds() + * when done. The actual list contents must not be touched. + * + * As file descriptors are a Unix-specific concept, this function is not + * available on Windows and will always return NULL. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns a NULL-terminated list of libusb_pollfd structures + * \returns NULL on error + * \returns NULL on platforms where the functionality is not available + */ +DEFAULT_VISIBILITY +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx) +{ +#ifndef OS_WINDOWS + struct libusb_pollfd **ret = NULL; + struct usbi_pollfd *ipollfd; + size_t i = 0; + USBI_GET_CONTEXT(ctx); + + usbi_mutex_lock(&ctx->event_data_lock); + + ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *)); + if (!ret) + goto out; + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + ret[i++] = (struct libusb_pollfd *) ipollfd; + ret[ctx->pollfds_cnt] = NULL; + +out: + usbi_mutex_unlock(&ctx->event_data_lock); + return (const struct libusb_pollfd **) ret; +#else + usbi_err(ctx, "external polling of libusb's internal descriptors "\ + "is not yet supported on Windows platforms"); + return NULL; +#endif +} + +/** \ingroup libusb_poll + * Free a list of libusb_pollfd structures. This should be called for all + * pollfd lists allocated with libusb_get_pollfds(). + * + * Since version 1.0.20, \ref LIBUSB_API_VERSION >= 0x01000104 + * + * It is legal to call this function with a NULL pollfd list. In this case, + * the function will simply return safely. + * + * \param pollfds the list of libusb_pollfd structures to free + */ +void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds) +{ + if (!pollfds) + return; + + free((void *)pollfds); +} + +/* Backends may call this from handle_events to report disconnection of a + * device. This function ensures transfers get cancelled appropriately. + * Callers of this function must hold the events_lock. + */ +void usbi_handle_disconnect(struct libusb_device_handle *dev_handle) +{ + struct usbi_transfer *cur; + struct usbi_transfer *to_cancel; + + usbi_dbg("device %d.%d", + dev_handle->dev->bus_number, dev_handle->dev->device_address); + + /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE + * status code. + * + * when we find a transfer for this device on the list, there are two + * possible scenarios: + * 1. the transfer is currently in-flight, in which case we terminate the + * transfer here + * 2. the transfer has been added to the flying transfer list by + * libusb_submit_transfer, has failed to submit and + * libusb_submit_transfer is waiting for us to release the + * flying_transfers_lock to remove it, so we ignore it + */ + + while (1) { + to_cancel = NULL; + usbi_mutex_lock(&HANDLE_CTX(dev_handle)->flying_transfers_lock); + list_for_each_entry(cur, &HANDLE_CTX(dev_handle)->flying_transfers, list, struct usbi_transfer) + if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) { + usbi_mutex_lock(&cur->lock); + if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT) + to_cancel = cur; + usbi_mutex_unlock(&cur->lock); + + if (to_cancel) + break; + } + usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock); + + if (!to_cancel) + break; + + usbi_dbg("cancelling transfer %p from disconnect", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel)); + + usbi_mutex_lock(&to_cancel->lock); + usbi_backend.clear_transfer_priv(to_cancel); + usbi_mutex_unlock(&to_cancel->lock); + usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE); + } + +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/libusb.h b/vendor/github.com/karalabe/usb/libusb/libusb/libusb.h new file mode 100644 index 00000000..430136b2 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/libusb.h @@ -0,0 +1,2039 @@ +/* + * Public libusb header file + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2012 Pete Batard + * Copyright © 2012 Nathan Hjelm + * For more information, please visit: http://libusb.info + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_H +#define LIBUSB_H + +#ifdef _MSC_VER +/* on MS environments, the inline keyword is available in C++ only */ +#if !defined(__cplusplus) +#define inline __inline +#endif +/* ssize_t is also not available (copy/paste from MinGW) */ +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 + typedef __int64 ssize_t; +#else + typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ +#endif /* _MSC_VER */ + +/* stdint.h is not available on older MSVC */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#if !defined(_WIN32_WCE) +#include +#endif + +#if defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__) +#include +#endif + +#include +#include + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define ZERO_SIZED_ARRAY /* [] - valid C99 code */ +#else +#define ZERO_SIZED_ARRAY 0 /* [0] - non-standard, but usually working code */ +#endif + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libusb API, because + * libusb_config_descriptor has an 'interface' member + * As this can be problematic if you include windows.h after libusb.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#include +#if defined(interface) +#undef interface +#endif +#if !defined(__CYGWIN__) +#include +#endif +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define LIBUSB_DEPRECATED_FOR(f) \ + __attribute__((deprecated("Use " #f " instead"))) +#elif __GNUC__ >= 3 +#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated)) +#else +#define LIBUSB_DEPRECATED_FOR(f) +#endif /* __GNUC__ */ + +/** \def LIBUSB_CALL + * \ingroup libusb_misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to functions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + +/** \def LIBUSB_API_VERSION + * \ingroup libusb_misc + * libusb's API version. + * + * Since version 1.0.13, to help with feature detection, libusb defines + * a LIBUSB_API_VERSION macro that gets increased every time there is a + * significant change to the API, such as the introduction of a new call, + * the definition of a new macro/enum member, or any other element that + * libusb applications may want to detect at compilation time. + * + * The macro is typically used in an application as follows: + * \code + * #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01001234) + * // Use one of the newer features from the libusb API + * #endif + * \endcode + * + * Internally, LIBUSB_API_VERSION is defined as follows: + * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) + */ +#define LIBUSB_API_VERSION 0x01000106 + +/* The following is kept for compatibility, but will be deprecated in the future */ +#define LIBUSBX_API_VERSION LIBUSB_API_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup libusb_misc + * Convert a 16-bit value from host-endian to little-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the host-endian value to convert + * \returns the value in little-endian byte order + */ +static inline uint16_t libusb_cpu_to_le16(const uint16_t x) +{ + union { + uint8_t b8[2]; + uint16_t b16; + } _tmp; + _tmp.b8[1] = (uint8_t) (x >> 8); + _tmp.b8[0] = (uint8_t) (x & 0xff); + return _tmp.b16; +} + +/** \def libusb_le16_to_cpu + * \ingroup libusb_misc + * Convert a 16-bit value from little-endian to host-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the little-endian value to convert + * \returns the value in host-endian byte order + */ +#define libusb_le16_to_cpu libusb_cpu_to_le16 + +/* standard USB stuff */ + +/** \ingroup libusb_desc + * Device and/or Interface Class codes */ +enum libusb_class_code { + /** In the context of a \ref libusb_device_descriptor "device descriptor", + * this bDeviceClass value indicates that each interface specifies its + * own class information and all interfaces operate independently. + */ + LIBUSB_CLASS_PER_INTERFACE = 0, + + /** Audio class */ + LIBUSB_CLASS_AUDIO = 1, + + /** Communications class */ + LIBUSB_CLASS_COMM = 2, + + /** Human Interface Device class */ + LIBUSB_CLASS_HID = 3, + + /** Physical */ + LIBUSB_CLASS_PHYSICAL = 5, + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 7, + + /** Image class */ + LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + LIBUSB_CLASS_IMAGE = 6, + + /** Mass storage class */ + LIBUSB_CLASS_MASS_STORAGE = 8, + + /** Hub class */ + LIBUSB_CLASS_HUB = 9, + + /** Data class */ + LIBUSB_CLASS_DATA = 10, + + /** Smart Card */ + LIBUSB_CLASS_SMART_CARD = 0x0b, + + /** Content Security */ + LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, + + /** Video */ + LIBUSB_CLASS_VIDEO = 0x0e, + + /** Personal Healthcare */ + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + + /** Diagnostic Device */ + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + + /** Wireless class */ + LIBUSB_CLASS_WIRELESS = 0xe0, + + /** Application class */ + LIBUSB_CLASS_APPLICATION = 0xfe, + + /** Class is vendor-specific */ + LIBUSB_CLASS_VENDOR_SPEC = 0xff +}; + +/** \ingroup libusb_desc + * Descriptor types as defined by the USB specification. */ +enum libusb_descriptor_type { + /** Device descriptor. See libusb_device_descriptor. */ + LIBUSB_DT_DEVICE = 0x01, + + /** Configuration descriptor. See libusb_config_descriptor. */ + LIBUSB_DT_CONFIG = 0x02, + + /** String descriptor */ + LIBUSB_DT_STRING = 0x03, + + /** Interface descriptor. See libusb_interface_descriptor. */ + LIBUSB_DT_INTERFACE = 0x04, + + /** Endpoint descriptor. See libusb_endpoint_descriptor. */ + LIBUSB_DT_ENDPOINT = 0x05, + + /** BOS descriptor */ + LIBUSB_DT_BOS = 0x0f, + + /** Device Capability descriptor */ + LIBUSB_DT_DEVICE_CAPABILITY = 0x10, + + /** HID descriptor */ + LIBUSB_DT_HID = 0x21, + + /** HID report descriptor */ + LIBUSB_DT_REPORT = 0x22, + + /** Physical descriptor */ + LIBUSB_DT_PHYSICAL = 0x23, + + /** Hub descriptor */ + LIBUSB_DT_HUB = 0x29, + + /** SuperSpeed Hub descriptor */ + LIBUSB_DT_SUPERSPEED_HUB = 0x2a, + + /** SuperSpeed Endpoint Companion descriptor */ + LIBUSB_DT_SS_ENDPOINT_COMPANION = 0x30 +}; + +/* Descriptor sizes per descriptor type */ +#define LIBUSB_DT_DEVICE_SIZE 18 +#define LIBUSB_DT_CONFIG_SIZE 9 +#define LIBUSB_DT_INTERFACE_SIZE 9 +#define LIBUSB_DT_ENDPOINT_SIZE 7 +#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define LIBUSB_DT_HUB_NONVAR_SIZE 7 +#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6 +#define LIBUSB_DT_BOS_SIZE 5 +#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3 + +/* BOS descriptor sizes */ +#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 +#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_CONTAINER_ID_SIZE 20 + +/* We unwrap the BOS => define its max size */ +#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\ + (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\ + (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\ + (LIBUSB_BT_CONTAINER_ID_SIZE)) + +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_DIR_MASK 0x80 + +/** \ingroup libusb_desc + * Endpoint direction. Values for bit 7 of the + * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. + */ +enum libusb_endpoint_direction { + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80, + + /** Out: host-to-device */ + LIBUSB_ENDPOINT_OUT = 0x00 +}; + +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/** \ingroup libusb_desc + * Endpoint transfer type. Values for bits 0:1 of the + * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. + */ +enum libusb_transfer_type { + /** Control endpoint */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0, + + /** Isochronous endpoint */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + + /** Bulk endpoint */ + LIBUSB_TRANSFER_TYPE_BULK = 2, + + /** Interrupt endpoint */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, + + /** Stream endpoint */ + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, +}; + +/** \ingroup libusb_misc + * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */ +enum libusb_standard_request { + /** Request status of the specific recipient */ + LIBUSB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + LIBUSB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + LIBUSB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + LIBUSB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + LIBUSB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + + /** Sets both the U1 and U2 Exit Latency */ + LIBUSB_REQUEST_SET_SEL = 0x30, + + /** Delay from the time a host transmits a packet to the time it is + * received by the device. */ + LIBUSB_SET_ISOCH_DELAY = 0x31, +}; + +/** \ingroup libusb_misc + * Request type bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. */ +enum libusb_request_type { + /** Standard */ + LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), + + /** Class */ + LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), + + /** Vendor */ + LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), + + /** Reserved */ + LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) +}; + +/** \ingroup libusb_misc + * Recipient bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. Values 4 through 31 are reserved. */ +enum libusb_request_recipient { + /** Device */ + LIBUSB_RECIPIENT_DEVICE = 0x00, + + /** Interface */ + LIBUSB_RECIPIENT_INTERFACE = 0x01, + + /** Endpoint */ + LIBUSB_RECIPIENT_ENDPOINT = 0x02, + + /** Other */ + LIBUSB_RECIPIENT_OTHER = 0x03, +}; + +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C + +/** \ingroup libusb_desc + * Synchronization type for isochronous endpoints. Values for bits 2:3 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_sync_type { + /** No synchronization */ + LIBUSB_ISO_SYNC_TYPE_NONE = 0, + + /** Asynchronous */ + LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + + /** Adaptive */ + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + + /** Synchronous */ + LIBUSB_ISO_SYNC_TYPE_SYNC = 3 +}; + +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 + +/** \ingroup libusb_desc + * Usage type for isochronous endpoints. Values for bits 4:5 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_usage_type { + /** Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_DATA = 0, + + /** Feedback endpoint */ + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + + /** Implicit feedback Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB device descriptor. This + * descriptor is documented in section 9.6.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_device_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + * context. */ + uint8_t bDescriptorType; + + /** USB specification release number in binary-coded decimal. A value of + * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ + uint16_t bcdUSB; + + /** USB-IF class code for the device. See \ref libusb_class_code. */ + uint8_t bDeviceClass; + + /** USB-IF subclass code for the device, qualified by the bDeviceClass + * value */ + uint8_t bDeviceSubClass; + + /** USB-IF protocol code for the device, qualified by the bDeviceClass and + * bDeviceSubClass values */ + uint8_t bDeviceProtocol; + + /** Maximum packet size for endpoint 0 */ + uint8_t bMaxPacketSize0; + + /** USB-IF vendor ID */ + uint16_t idVendor; + + /** USB-IF product ID */ + uint16_t idProduct; + + /** Device release number in binary-coded decimal */ + uint16_t bcdDevice; + + /** Index of string descriptor describing manufacturer */ + uint8_t iManufacturer; + + /** Index of string descriptor describing product */ + uint8_t iProduct; + + /** Index of string descriptor containing device serial number */ + uint8_t iSerialNumber; + + /** Number of possible configurations */ + uint8_t bNumConfigurations; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB endpoint descriptor. This + * descriptor is documented in section 9.6.6 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_endpoint_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + * this context. */ + uint8_t bDescriptorType; + + /** The address of the endpoint described by this descriptor. Bits 0:3 are + * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + * see \ref libusb_endpoint_direction. + */ + uint8_t bEndpointAddress; + + /** Attributes which apply to the endpoint when it is configured using + * the bConfigurationValue. Bits 0:1 determine the transfer type and + * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * Bits 4:5 are also only used for isochronous endpoints and correspond to + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. + */ + uint8_t bmAttributes; + + /** Maximum packet size this endpoint is capable of sending/receiving. */ + uint16_t wMaxPacketSize; + + /** Interval for polling endpoint for data transfers. */ + uint8_t bInterval; + + /** For audio devices only: the rate at which synchronization feedback + * is provided. */ + uint8_t bRefresh; + + /** For audio devices only: the address if the synch endpoint */ + uint8_t bSynchAddress; + + /** Extra descriptors. If libusb encounters unknown endpoint descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB interface descriptor. This + * descriptor is documented in section 9.6.5 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + * in this context. */ + uint8_t bDescriptorType; + + /** Number of this interface */ + uint8_t bInterfaceNumber; + + /** Value used to select this alternate setting for this interface */ + uint8_t bAlternateSetting; + + /** Number of endpoints used by this interface (excluding the control + * endpoint). */ + uint8_t bNumEndpoints; + + /** USB-IF class code for this interface. See \ref libusb_class_code. */ + uint8_t bInterfaceClass; + + /** USB-IF subclass code for this interface, qualified by the + * bInterfaceClass value */ + uint8_t bInterfaceSubClass; + + /** USB-IF protocol code for this interface, qualified by the + * bInterfaceClass and bInterfaceSubClass values */ + uint8_t bInterfaceProtocol; + + /** Index of string descriptor describing this interface */ + uint8_t iInterface; + + /** Array of endpoint descriptors. This length of this array is determined + * by the bNumEndpoints field. */ + const struct libusb_endpoint_descriptor *endpoint; + + /** Extra descriptors. If libusb encounters unknown interface descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A collection of alternate settings for a particular USB interface. + */ +struct libusb_interface { + /** Array of interface descriptors. The length of this array is determined + * by the num_altsetting field. */ + const struct libusb_interface_descriptor *altsetting; + + /** The number of alternate settings that belong to this interface */ + int num_altsetting; +}; + +/** \ingroup libusb_desc + * A structure representing the standard USB configuration descriptor. This + * descriptor is documented in section 9.6.3 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_config_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + * in this context. */ + uint8_t bDescriptorType; + + /** Total length of data returned for this configuration */ + uint16_t wTotalLength; + + /** Number of interfaces supported by this configuration */ + uint8_t bNumInterfaces; + + /** Identifier value for this configuration */ + uint8_t bConfigurationValue; + + /** Index of string descriptor describing this configuration */ + uint8_t iConfiguration; + + /** Configuration characteristics */ + uint8_t bmAttributes; + + /** Maximum power consumption of the USB device from this bus in this + * configuration when the device is fully operation. Expressed in units + * of 2 mA when the device is operating in high-speed mode and in units + * of 8 mA when the device is operating in super-speed mode. */ + uint8_t MaxPower; + + /** Array of interfaces supported by this configuration. The length of + * this array is determined by the bNumInterfaces field. */ + const struct libusb_interface *interface; + + /** Extra descriptors. If libusb encounters unknown configuration + * descriptors, it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup libusb_desc + * A structure representing the superspeed endpoint companion + * descriptor. This descriptor is documented in section 9.6.7 of + * the USB 3.0 specification. All multiple-byte fields are represented in + * host-endian format. + */ +struct libusb_ss_endpoint_companion_descriptor { + + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in + * this context. */ + uint8_t bDescriptorType; + + + /** The maximum number of packets the endpoint can send or + * receive as part of a burst. */ + uint8_t bMaxBurst; + + /** In bulk EP: bits 4:0 represents the maximum number of + * streams the EP supports. In isochronous EP: bits 1:0 + * represents the Mult - a zero based value that determines + * the maximum number of packets within a service interval */ + uint8_t bmAttributes; + + /** The total number of bytes this EP will transfer every + * service interval. valid only for periodic EPs. */ + uint16_t wBytesPerInterval; +}; + +/** \ingroup libusb_desc + * A generic representation of a BOS Device Capability descriptor. It is + * advised to check bDevCapabilityType and call the matching + * libusb_get_*_descriptor function to get a structure fully matching the type. + */ +struct libusb_bos_dev_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + /** Device Capability type */ + uint8_t bDevCapabilityType; + /** Device Capability data (bLength - 3 bytes) */ + uint8_t dev_capability_data[ZERO_SIZED_ARRAY]; +}; + +/** \ingroup libusb_desc + * A structure representing the Binary Device Object Store (BOS) descriptor. + * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_bos_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS + * in this context. */ + uint8_t bDescriptorType; + + /** Length of this descriptor and all of its sub descriptors */ + uint16_t wTotalLength; + + /** The number of separate device capability descriptors in + * the BOS */ + uint8_t bNumDeviceCaps; + + /** bNumDeviceCap Device Capability Descriptors */ + struct libusb_bos_dev_capability_descriptor *dev_capability[ZERO_SIZED_ARRAY]; +}; + +/** \ingroup libusb_desc + * A structure representing the USB 2.0 Extension descriptor + * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_usb_2_0_extension_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_usb_2_0_extension_attributes. */ + uint32_t bmAttributes; +}; + +/** \ingroup libusb_desc + * A structure representing the SuperSpeed USB Device Capability descriptor + * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_ss_usb_device_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_ss_usb_device_capability_attributes. */ + uint8_t bmAttributes; + + /** Bitmap encoding of the speed supported by this device when + * operating in SuperSpeed mode. See \ref libusb_supported_speed. */ + uint16_t wSpeedSupported; + + /** The lowest speed at which all the functionality supported + * by the device is available to the user. For example if the + * device supports all its functionality when connected at + * full speed and above then it sets this value to 1. */ + uint8_t bFunctionalitySupport; + + /** U1 Device Exit Latency. */ + uint8_t bU1DevExitLat; + + /** U2 Device Exit Latency. */ + uint16_t bU2DevExitLat; +}; + +/** \ingroup libusb_desc + * A structure representing the Container ID descriptor. + * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. + * All multiple-byte fields, except UUIDs, are represented in host-endian format. + */ +struct libusb_container_id_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID in this context. */ + uint8_t bDevCapabilityType; + + /** Reserved field */ + uint8_t bReserved; + + /** 128 bit UUID */ + uint8_t ContainerID[16]; +}; + +/** \ingroup libusb_asyncio + * Setup packet for control transfers. */ +struct libusb_control_setup { + /** Request type. Bits 0:4 determine recipient, see + * \ref libusb_request_recipient. Bits 5:6 determine type, see + * \ref libusb_request_type. Bit 7 determines data transfer direction, see + * \ref libusb_endpoint_direction. + */ + uint8_t bmRequestType; + + /** Request. If the type bits of bmRequestType are equal to + * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref libusb_standard_request. For other cases, use of this field is + * application-specific. */ + uint8_t bRequest; + + /** Value. Varies according to request */ + uint16_t wValue; + + /** Index. Varies according to request, typically used to pass an index + * or offset */ + uint16_t wIndex; + + /** Number of bytes to transfer */ + uint16_t wLength; +}; + +#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) + +/* libusb */ + +struct libusb_context; +struct libusb_device; +struct libusb_device_handle; + +/** \ingroup libusb_lib + * Structure providing the version of the libusb runtime + */ +struct libusb_version { + /** Library major version. */ + const uint16_t major; + + /** Library minor version. */ + const uint16_t minor; + + /** Library micro version. */ + const uint16_t micro; + + /** Library nano version. */ + const uint16_t nano; + + /** Library release candidate suffix string, e.g. "-rc4". */ + const char *rc; + + /** For ABI compatibility only. */ + const char* describe; +}; + +/** \ingroup libusb_lib + * Structure representing a libusb session. The concept of individual libusb + * sessions allows for your program to use two libraries (or dynamically + * load two modules) which both independently use libusb. This will prevent + * interference between the individual libusb users - for example + * libusb_set_option() will not affect the other user of the library, and + * libusb_exit() will not destroy resources that the other user is still + * using. + * + * Sessions are created by libusb_init() and destroyed through libusb_exit(). + * If your application is guaranteed to only ever include a single libusb + * user (i.e. you), you do not have to worry about contexts: pass NULL in + * every function call where a context is required. The default context + * will be used. + * + * For more information, see \ref libusb_contexts. + */ +typedef struct libusb_context libusb_context; + +/** \ingroup libusb_dev + * Structure representing a USB device detected on the system. This is an + * opaque type for which you are only ever provided with a pointer, usually + * originating from libusb_get_device_list(). + * + * Certain operations can be performed on a device, but in order to do any + * I/O you will have to first obtain a device handle using libusb_open(). + * + * Devices are reference counted with libusb_ref_device() and + * libusb_unref_device(), and are freed when the reference count reaches 0. + * New devices presented by libusb_get_device_list() have a reference count of + * 1, and libusb_free_device_list() can optionally decrease the reference count + * on all devices in the list. libusb_open() adds another reference which is + * later destroyed by libusb_close(). + */ +typedef struct libusb_device libusb_device; + + +/** \ingroup libusb_dev + * Structure representing a handle on a USB device. This is an opaque type for + * which you are only ever provided with a pointer, usually originating from + * libusb_open(). + * + * A device handle is used to perform I/O and other operations. When finished + * with a device handle, you should call libusb_close(). + */ +typedef struct libusb_device_handle libusb_device_handle; + +/** \ingroup libusb_dev + * Speed codes. Indicates the speed at which the device is operating. + */ +enum libusb_speed { + /** The OS doesn't report or know the device speed. */ + LIBUSB_SPEED_UNKNOWN = 0, + + /** The device is operating at low speed (1.5MBit/s). */ + LIBUSB_SPEED_LOW = 1, + + /** The device is operating at full speed (12MBit/s). */ + LIBUSB_SPEED_FULL = 2, + + /** The device is operating at high speed (480MBit/s). */ + LIBUSB_SPEED_HIGH = 3, + + /** The device is operating at super speed (5000MBit/s). */ + LIBUSB_SPEED_SUPER = 4, + + /** The device is operating at super speed plus (10000MBit/s). */ + LIBUSB_SPEED_SUPER_PLUS = 5, +}; + +/** \ingroup libusb_dev + * Supported speeds (wSpeedSupported) bitfield. Indicates what + * speeds the device supports. + */ +enum libusb_supported_speed { + /** Low speed operation supported (1.5MBit/s). */ + LIBUSB_LOW_SPEED_OPERATION = 1, + + /** Full speed operation supported (12MBit/s). */ + LIBUSB_FULL_SPEED_OPERATION = 2, + + /** High speed operation supported (480MBit/s). */ + LIBUSB_HIGH_SPEED_OPERATION = 4, + + /** Superspeed operation supported (5000MBit/s). */ + LIBUSB_SUPER_SPEED_OPERATION = 8, +}; + +/** \ingroup libusb_dev + * Masks for the bits of the + * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field + * of the USB 2.0 Extension descriptor. + */ +enum libusb_usb_2_0_extension_attributes { + /** Supports Link Power Management (LPM) */ + LIBUSB_BM_LPM_SUPPORT = 2, +}; + +/** \ingroup libusb_dev + * Masks for the bits of the + * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field + * field of the SuperSpeed USB Device Capability descriptor. + */ +enum libusb_ss_usb_device_capability_attributes { + /** Supports Latency Tolerance Messages (LTM) */ + LIBUSB_BM_LTM_SUPPORT = 2, +}; + +/** \ingroup libusb_dev + * USB capability types + */ +enum libusb_bos_type { + /** Wireless USB device capability */ + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, + + /** USB 2.0 extensions */ + LIBUSB_BT_USB_2_0_EXTENSION = 2, + + /** SuperSpeed USB device capability */ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, + + /** Container ID type */ + LIBUSB_BT_CONTAINER_ID = 4, +}; + +/** \ingroup libusb_misc + * Error codes. Most libusb functions return 0 on success or one of these + * codes on failure. + * You can call libusb_error_name() to retrieve a string representation of an + * error code or libusb_strerror() to get an end-user suitable description of + * an error code. + */ +enum libusb_error { + /** Success (no error) */ + LIBUSB_SUCCESS = 0, + + /** Input/output error */ + LIBUSB_ERROR_IO = -1, + + /** Invalid parameter */ + LIBUSB_ERROR_INVALID_PARAM = -2, + + /** Access denied (insufficient permissions) */ + LIBUSB_ERROR_ACCESS = -3, + + /** No such device (it may have been disconnected) */ + LIBUSB_ERROR_NO_DEVICE = -4, + + /** Entity not found */ + LIBUSB_ERROR_NOT_FOUND = -5, + + /** Resource busy */ + LIBUSB_ERROR_BUSY = -6, + + /** Operation timed out */ + LIBUSB_ERROR_TIMEOUT = -7, + + /** Overflow */ + LIBUSB_ERROR_OVERFLOW = -8, + + /** Pipe error */ + LIBUSB_ERROR_PIPE = -9, + + /** System call interrupted (perhaps due to signal) */ + LIBUSB_ERROR_INTERRUPTED = -10, + + /** Insufficient memory */ + LIBUSB_ERROR_NO_MEM = -11, + + /** Operation not supported or unimplemented on this platform */ + LIBUSB_ERROR_NOT_SUPPORTED = -12, + + /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the + message strings in strerror.c when adding new error codes here. */ + + /** Other error */ + LIBUSB_ERROR_OTHER = -99, +}; + +/* Total number of error codes in enum libusb_error */ +#define LIBUSB_ERROR_COUNT 14 + +/** \ingroup libusb_asyncio + * Transfer status codes */ +enum libusb_transfer_status { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + LIBUSB_TRANSFER_COMPLETED, + + /** Transfer failed */ + LIBUSB_TRANSFER_ERROR, + + /** Transfer timed out */ + LIBUSB_TRANSFER_TIMED_OUT, + + /** Transfer was cancelled */ + LIBUSB_TRANSFER_CANCELLED, + + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + LIBUSB_TRANSFER_STALL, + + /** Device was disconnected */ + LIBUSB_TRANSFER_NO_DEVICE, + + /** Device sent more data than requested */ + LIBUSB_TRANSFER_OVERFLOW, + + /* NB! Remember to update libusb_error_name() + when adding new status codes here. */ +}; + +/** \ingroup libusb_asyncio + * libusb_transfer.flags values */ +enum libusb_transfer_flags { + /** Report short frames as errors */ + LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, + + /** Automatically free() transfer buffer during libusb_free_transfer(). + * Note that buffers allocated with libusb_dev_mem_alloc() should not + * be attempted freed in this way, since free() is not an appropriate + * way to release such memory. */ + LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, + + /** Automatically call libusb_free_transfer() after callback returns. + * If this flag is set, it is illegal to call libusb_free_transfer() + * from your transfer callback, as this will result in a double-free + * when this flag is acted upon. */ + LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, + + /** Terminate transfers that are a multiple of the endpoint's + * wMaxPacketSize with an extra zero length packet. This is useful + * when a device protocol mandates that each logical request is + * terminated by an incomplete packet (i.e. the logical requests are + * not separated by other means). + * + * This flag only affects host-to-device transfers to bulk and interrupt + * endpoints. In other situations, it is ignored. + * + * This flag only affects transfers with a length that is a multiple of + * the endpoint's wMaxPacketSize. On transfers of other lengths, this + * flag has no effect. Therefore, if you are working with a device that + * needs a ZLP whenever the end of the logical request falls on a packet + * boundary, then it is sensible to set this flag on every + * transfer (you do not have to worry about only setting it on transfers + * that end on the boundary). + * + * This flag is currently only supported on Linux. + * On other systems, libusb_submit_transfer() will return + * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * + * Available since libusb-1.0.9. + */ + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, +}; + +/** \ingroup libusb_asyncio + * Isochronous packet descriptor. */ +struct libusb_iso_packet_descriptor { + /** Length of data to request in this packet */ + unsigned int length; + + /** Amount of data that was actually transferred */ + unsigned int actual_length; + + /** Status code for this packet */ + enum libusb_transfer_status status; +}; + +struct libusb_transfer; + +/** \ingroup libusb_asyncio + * Asynchronous transfer callback function type. When submitting asynchronous + * transfers, you pass a pointer to a callback function of this type via the + * \ref libusb_transfer::callback "callback" member of the libusb_transfer + * structure. libusb will call this function later, when the transfer has + * completed or failed. See \ref libusb_asyncio for more information. + * \param transfer The libusb_transfer struct the callback function is being + * notified about. + */ +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); + +/** \ingroup libusb_asyncio + * The generic USB transfer structure. The user populates this structure and + * then submits it in order to request a transfer. After the transfer has + * completed, the library populates the transfer with the results and passes + * it back to the user. + */ +struct libusb_transfer { + /** Handle of the device that this transfer will be submitted to */ + libusb_device_handle *dev_handle; + + /** A bitwise OR combination of \ref libusb_transfer_flags. */ + uint8_t flags; + + /** Address of the endpoint where this transfer will be sent. */ + unsigned char endpoint; + + /** Type of the endpoint from \ref libusb_transfer_type */ + unsigned char type; + + /** Timeout for this transfer in milliseconds. A value of 0 indicates no + * timeout. */ + unsigned int timeout; + + /** The status of the transfer. Read-only, and only for use within + * transfer callback function. + * + * If this is an isochronous transfer, this field may read COMPLETED even + * if there were errors in the frames. Use the + * \ref libusb_iso_packet_descriptor::status "status" field in each packet + * to determine if errors occurred. */ + enum libusb_transfer_status status; + + /** Length of the data buffer */ + int length; + + /** Actual length of data that was transferred. Read-only, and only for + * use within transfer callback function. Not valid for isochronous + * endpoint transfers. */ + int actual_length; + + /** Callback function. This will be invoked when the transfer completes, + * fails, or is cancelled. */ + libusb_transfer_cb_fn callback; + + /** User context data to pass to the callback function. */ + void *user_data; + + /** Data buffer */ + unsigned char *buffer; + + /** Number of isochronous packets. Only used for I/O with isochronous + * endpoints. */ + int num_iso_packets; + + /** Isochronous packet descriptors, for isochronous transfers only. */ + struct libusb_iso_packet_descriptor iso_packet_desc[ZERO_SIZED_ARRAY]; +}; + +/** \ingroup libusb_misc + * Capabilities supported by an instance of libusb on the current running + * platform. Test if the loaded library supports a given capability by calling + * \ref libusb_has_capability(). + */ +enum libusb_capability { + /** The libusb_has_capability() API is available. */ + LIBUSB_CAP_HAS_CAPABILITY = 0x0000, + /** Hotplug support is available on this platform. */ + LIBUSB_CAP_HAS_HOTPLUG = 0x0001, + /** The library can access HID devices without requiring user intervention. + * Note that before being able to actually access an HID device, you may + * still have to call additional libusb functions such as + * \ref libusb_detach_kernel_driver(). */ + LIBUSB_CAP_HAS_HID_ACCESS = 0x0100, + /** The library supports detaching of the default USB driver, using + * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */ + LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 +}; + +/** \ingroup libusb_lib + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr + */ +enum libusb_log_level { + LIBUSB_LOG_LEVEL_NONE = 0, + LIBUSB_LOG_LEVEL_ERROR = 1, + LIBUSB_LOG_LEVEL_WARNING = 2, + LIBUSB_LOG_LEVEL_INFO = 3, + LIBUSB_LOG_LEVEL_DEBUG = 4, +}; + +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +LIBUSB_DEPRECATED_FOR(libusb_set_option) +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const struct libusb_version * LIBUSB_CALL libusb_get_version(void); +int LIBUSB_CALL libusb_has_capability(uint32_t capability); +const char * LIBUSB_CALL libusb_error_name(int errcode); +int LIBUSB_CALL libusb_setlocale(const char *locale); +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); + +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc); +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config); +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp); +void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp); +int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle, + struct libusb_bos_descriptor **bos); +void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); +int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); +void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); +int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap); +void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap); +int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id); +void LIBUSB_CALL libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev); +int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len); +LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers) +int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length); +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev_handle, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, + int interface_number, int alternate_setting); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev_handle, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); +int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints); + +unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle, + size_t length); +int LIBUSB_CALL libusb_dev_mem_free(libusb_device_handle *dev_handle, + unsigned char *buffer, size_t length); + +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev_handle, + int interface_number); +int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev_handle, int enable); + +/* async I/O */ + +/** \ingroup libusb_asyncio + * Get the data section of a control transfer. This convenience function is here + * to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns pointer to the first byte of the data section + */ +static inline unsigned char *libusb_control_transfer_get_data( + struct libusb_transfer *transfer) +{ + return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; +} + +/** \ingroup libusb_asyncio + * Get the control setup packet of a control transfer. This convenience + * function is here to remind you that the control setup occupies the first + * 8 bytes of the transfer data buffer. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns a casted pointer to the start of the transfer data buffer + */ +static inline struct libusb_control_setup *libusb_control_transfer_get_setup( + struct libusb_transfer *transfer) +{ + return (struct libusb_control_setup *)(void *) transfer->buffer; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the setup packet (first 8 bytes of the data + * buffer) for a control transfer. The wIndex, wValue and wLength values should + * be given in host-endian byte order. + * + * \param buffer buffer to output the setup packet into + * This pointer must be aligned to at least 2 bytes boundary. + * \param bmRequestType see the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field of + * \ref libusb_control_setup + * \param bRequest see the + * \ref libusb_control_setup::bRequest "bRequest" field of + * \ref libusb_control_setup + * \param wValue see the + * \ref libusb_control_setup::wValue "wValue" field of + * \ref libusb_control_setup + * \param wIndex see the + * \ref libusb_control_setup::wIndex "wIndex" field of + * \ref libusb_control_setup + * \param wLength see the + * \ref libusb_control_setup::wLength "wLength" field of + * \ref libusb_control_setup + */ +static inline void libusb_fill_control_setup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + setup->bmRequestType = bmRequestType; + setup->bRequest = bRequest; + setup->wValue = libusb_cpu_to_le16(wValue); + setup->wIndex = libusb_cpu_to_le16(wIndex); + setup->wLength = libusb_cpu_to_le16(wLength); +} + +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id); +uint32_t LIBUSB_CALL libusb_transfer_get_stream_id( + struct libusb_transfer *transfer); + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a control transfer. + * + * If you pass a transfer buffer to this function, the first 8 bytes will + * be interpreted as a control setup packet, and the wLength field will be + * used to automatically populate the \ref libusb_transfer::length "length" + * field of the transfer. Therefore the recommended approach is: + * -# Allocate a suitably sized data buffer (including space for control setup) + * -# Call libusb_fill_control_setup() + * -# If this is a host-to-device transfer with a data stage, put the data + * in place after the setup packet + * -# Call this function + * -# Call libusb_submit_transfer() + * + * It is also legal to pass a NULL buffer to this function, in which case this + * function will not attempt to populate the length field. Remember that you + * must then populate the buffer and length fields later. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param buffer data buffer. If provided, this function will interpret the + * first 8 bytes as a setup packet and infer the transfer length from that. + * This pointer must be aligned to at least 2 bytes boundary. + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_control_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + transfer->dev_handle = dev_handle; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buffer; + if (setup) + transfer->length = (int) (LIBUSB_CONTROL_SETUP_SIZE + + libusb_le16_to_cpu(setup->wLength)); + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer using bulk streams. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param stream_id bulk stream id for this transfer + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_stream_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, uint32_t stream_id, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, + length, callback, user_data, timeout); + transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM; + libusb_transfer_set_stream_id(transfer, stream_id); +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an interrupt transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_interrupt_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an isochronous transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param num_iso_packets the number of isochronous packets + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, int num_iso_packets, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->num_iso_packets = num_iso_packets; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup libusb_asyncio + * Convenience function to set the length of all packets in an isochronous + * transfer, based on the num_iso_packets field in the transfer structure. + * + * \param transfer a transfer + * \param length the length to set in each isochronous packet descriptor + * \see libusb_get_max_packet_size() + */ +static inline void libusb_set_iso_packet_lengths( + struct libusb_transfer *transfer, unsigned int length) +{ + int i; + for (i = 0; i < transfer->num_iso_packets; i++) + transfer->iso_packet_desc[i].length = length; +} + +/** \ingroup libusb_asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer. + * + * This is a thorough function which loops through all preceding packets, + * accumulating their lengths to find the position of the specified packet. + * Typically you will assign equal lengths to each packet in the transfer, + * and hence the above method is sub-optimal. You may wish to use + * libusb_get_iso_packet_buffer_simple() instead. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer_simple() + */ +static inline unsigned char *libusb_get_iso_packet_buffer( + struct libusb_transfer *transfer, unsigned int packet) +{ + int i; + size_t offset = 0; + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + for (i = 0; i < _packet; i++) + offset += transfer->iso_packet_desc[i].length; + + return transfer->buffer + offset; +} + +/** \ingroup libusb_asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer, for transfers where each + * packet is of identical size. + * + * This function relies on the assumption that every packet within the transfer + * is of identical size to the first packet. Calculating the location of + * the packet buffer is then just a simple calculation: + * buffer + (packet_size * packet) + * + * Do not use this function on transfers other than those that have identical + * packet lengths for each packet. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer() + */ +static inline unsigned char *libusb_get_iso_packet_buffer_simple( + struct libusb_transfer *transfer, unsigned int packet) +{ + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + return transfer->buffer + ((int) transfer->iso_packet_desc[0].length * _packet); +} + +/* sync I/O */ + +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout); + +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +/** \ingroup libusb_desc + * Retrieve a descriptor from the default control pipe. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. + * + * \param dev_handle a device handle + * \param desc_type the descriptor type, see \ref libusb_descriptor_type + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +static inline int libusb_get_descriptor(libusb_device_handle *dev_handle, + uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) +{ + return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index), + 0, data, (uint16_t) length, 1000); +} + +/** \ingroup libusb_desc + * Retrieve a descriptor from a device. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. The string returned is Unicode, as + * detailed in the USB specifications. + * + * \param dev_handle a device handle + * \param desc_index the index of the descriptor to retrieve + * \param langid the language ID for the string descriptor + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + * \see libusb_get_string_descriptor_ascii() + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev_handle, + uint8_t desc_index, uint16_t langid, unsigned char *data, int length) +{ + return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), + langid, data, (uint16_t) length, 1000); +} + +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, + uint8_t desc_index, unsigned char *data, int length); + +/* polling and timeouts */ + +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); + +/** \ingroup libusb_poll + * File descriptor for polling + */ +struct libusb_pollfd { + /** Numeric file descriptor */ + int fd; + + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + short events; +}; + +/** \ingroup libusb_poll + * Callback function, invoked when a new file descriptor should be added + * to the set of file descriptors monitored for events. + * \param fd the new file descriptor + * \param events events to monitor for, see \ref libusb_pollfd for a + * description + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); + +/** \ingroup libusb_poll + * Callback function, invoked when a file descriptor should be removed from + * the set of file descriptors being monitored for events. After returning + * from this callback, do not use that file descriptor again. + * \param fd the file descriptor to stop monitoring + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); + +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data); + +/** \ingroup libusb_hotplug + * Callback handle. + * + * Callbacks handles are generated by libusb_hotplug_register_callback() + * and can be used to deregister callbacks. Callback handles are unique + * per libusb_context and it is safe to call libusb_hotplug_deregister_callback() + * on an already deregisted callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * For more information, see \ref libusb_hotplug. + */ +typedef int libusb_hotplug_callback_handle; + +/** \ingroup libusb_hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Flags for hotplug events */ +typedef enum { + /** Default value when not using any flags. */ + LIBUSB_HOTPLUG_NO_FLAGS = 0, + + /** Arm the callback and fire it for all matching currently attached devices. */ + LIBUSB_HOTPLUG_ENUMERATE = 1<<0, +} libusb_hotplug_flag; + +/** \ingroup libusb_hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Hotplug events */ +typedef enum { + /** A device has been plugged in and is ready to use */ + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01, + + /** A device has left and is no longer available. + * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. + * It is safe to call libusb_get_device_descriptor on a device that has left */ + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02, +} libusb_hotplug_event; + +/** \ingroup libusb_hotplug + * Wildcard matching for hotplug events */ +#define LIBUSB_HOTPLUG_MATCH_ANY -1 + +/** \ingroup libusb_hotplug + * Hotplug callback function type. When requesting hotplug event notifications, + * you pass a pointer to a callback function of this type. + * + * This callback may be called by an internal event thread and as such it is + * recommended the callback do minimal processing before returning. + * + * libusb will call this function later, when a matching event had happened on + * a matching device. See \ref libusb_hotplug for more information. + * + * It is safe to call either libusb_hotplug_register_callback() or + * libusb_hotplug_deregister_callback() from within a callback function. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param ctx context of this notification + * \param device libusb_device this event occurred on + * \param event event that occurred + * \param user_data user data provided when this callback was registered + * \returns bool whether this callback is finished processing events. + * returning 1 will cause this callback to be deregistered + */ +typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, + libusb_device *device, + libusb_hotplug_event event, + void *user_data); + +/** \ingroup libusb_hotplug + * Register a hotplug callback function + * + * Register a callback with the libusb_context. The callback will fire + * when a matching event occurs on a matching device. The callback is + * armed until either it is deregistered with libusb_hotplug_deregister_callback() + * or the supplied callback returns 1 to indicate it is finished processing events. + * + * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be + * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices + * already plugged into the machine. Note that libusb modifies its internal + * device list from a separate thread, while calling hotplug callbacks from + * libusb_handle_events(), so it is possible for a device to already be present + * on, or removed from, its internal device list, while the hotplug callbacks + * still need to be dispatched. This means that when using \ref + * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival + * of the same device, once from libusb_hotplug_register_callback() and once + * from libusb_handle_events(); and/or your callback may be called for the + * removal of a device for which an arrived call was never made. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context to register this callback with + * \param[in] events bitwise or of events that will trigger this callback. See \ref + * libusb_hotplug_event + * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] cb_fn the function to be invoked on a matching event/device + * \param[in] user_data user data to pass to the callback function + * \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL) + * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + */ +int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, + libusb_hotplug_flag flags, + int vendor_id, int product_id, + int dev_class, + libusb_hotplug_callback_fn cb_fn, + void *user_data, + libusb_hotplug_callback_handle *callback_handle); + +/** \ingroup libusb_hotplug + * Deregisters a hotplug callback. + * + * Deregister a callback from a libusb_context. This function is safe to call from within + * a hotplug callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context this callback is registered with + * \param[in] callback_handle the handle of the callback to deregister + */ +void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle); + +/** \ingroup libusb_lib + * Available option values for libusb_set_option(). + */ +enum libusb_option { + /** Set the log message verbosity. + * + * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever + * printed. If you choose to increase the message verbosity level, ensure + * that your application does not close the stderr file descriptor. + * + * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative + * with its message logging and most of the time, will only log messages that + * explain error conditions and other oddities. This will help you debug + * your software. + * + * If the LIBUSB_DEBUG environment variable was set when libusb was + * initialized, this function does nothing: the message verbosity is fixed + * to the value in the environment variable. + * + * If libusb was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusb was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + */ + LIBUSB_OPTION_LOG_LEVEL, + + /** Use the UsbDk backend for a specific context, if available. + * + * This option should be set immediately after calling libusb_init(), otherwise + * unspecified behavior may occur. + * + * Only valid on Windows. + */ + LIBUSB_OPTION_USE_USBDK, +}; + +int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/libusbi.h b/vendor/github.com/karalabe/usb/libusb/libusb/libusbi.h new file mode 100644 index 00000000..31d6ce98 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/libusbi.h @@ -0,0 +1,1165 @@ +/* + * Internal header for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSBI_H +#define LIBUSBI_H + +#include + +#include + +#include +#include +#include +#include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_MISSING_H +#include +#endif + +#include "libusb.h" +#include "version.h" + +/* Attribute to ensure that a structure member is aligned to a natural + * pointer alignment. Used for os_priv member. */ +#if defined(_MSC_VER) +#if defined(_WIN64) +#define PTR_ALIGNED __declspec(align(8)) +#else +#define PTR_ALIGNED __declspec(align(4)) +#endif +#elif defined(__GNUC__) +#define PTR_ALIGNED __attribute__((aligned(sizeof(void *)))) +#else +#define PTR_ALIGNED +#endif + +/* Inside the libusb code, mark all public functions as follows: + * return_type API_EXPORTED function_name(params) { ... } + * But if the function returns a pointer, mark it as follows: + * DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... } + * In the libusb public header, mark all declarations as: + * return_type LIBUSB_CALL function_name(params); + */ +#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_DESC_LENGTH 18 + +#define USB_MAXENDPOINTS 32 +#define USB_MAXINTERFACES 32 +#define USB_MAXCONFIG 8 + +/* Backend specific capabilities */ +#define USBI_CAP_HAS_HID_ACCESS 0x00010000 +#define USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 0x00020000 + +/* Maximum number of bytes in a log line */ +#define USBI_MAX_LOG_LEN 1024 +/* Terminator for log lines */ +#define USBI_LOG_LINE_END "\n" + +/* The following is used to silence warnings for unused variables */ +#define UNUSED(var) do { (void)(var); } while(0) + +#if !defined(ARRAYSIZE) +#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0])) +#endif + +struct list_head { + struct list_head *prev, *next; +}; + +/* Get an entry from the list + * ptr - the address of this list_head element in "type" + * type - the data type that contains "member" + * member - the list_head element in "type" + */ +#define list_entry(ptr, type, member) \ + ((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member))) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/* Get each entry from a list + * pos - A structure pointer has a "member" element + * head - list head + * member - the list_head element in "pos" + * type - the type of the first parameter + */ +#define list_for_each_entry(pos, head, member, type) \ + for (pos = list_entry((head)->next, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, type, member)) + +#define list_for_each_entry_safe(pos, n, head, member, type) \ + for (pos = list_entry((head)->next, type, member), \ + n = list_entry(pos->member.next, type, member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, type, member)) + +#define list_empty(entry) ((entry)->next == (entry)) + +static inline void list_init(struct list_head *entry) +{ + entry->prev = entry->next = entry; +} + +static inline void list_add(struct list_head *entry, struct list_head *head) +{ + entry->next = head->next; + entry->prev = head; + + head->next->prev = entry; + head->next = entry; +} + +static inline void list_add_tail(struct list_head *entry, + struct list_head *head) +{ + entry->next = head; + entry->prev = head->prev; + + head->prev->next = entry; + head->prev = entry; +} + +static inline void list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = entry->prev = NULL; +} + +static inline void list_cut(struct list_head *list, struct list_head *head) +{ + if (list_empty(head)) + return; + + list->next = head->next; + list->next->prev = list; + list->prev = head->prev; + list->prev->next = list; + + list_init(head); +} + +static inline void *usbi_reallocf(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret) + free(ptr); + return ret; +} + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *mptr = (ptr); \ + (type *)( (char *)mptr - offsetof(type,member) );}) + +#ifndef CLAMP +#define CLAMP(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? (max) : (val))) +#endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0) + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define TIMEVAL_TV_SEC_TYPE long +#else +#define TIMEVAL_TV_SEC_TYPE time_t +#endif + +/* Some platforms don't have this define */ +#ifndef TIMESPEC_TO_TIMEVAL +#define TIMESPEC_TO_TIMEVAL(tv, ts) \ + do { \ + (tv)->tv_sec = (TIMEVAL_TV_SEC_TYPE) (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) +#endif + +#ifdef ENABLE_LOGGING + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define snprintf usbi_snprintf +#define vsnprintf usbi_vsnprintf +int usbi_snprintf(char *dst, size_t size, const char *format, ...); +int usbi_vsnprintf(char *dst, size_t size, const char *format, va_list ap); +#define LIBUSB_PRINTF_WIN32 +#endif /* defined(_MSC_VER) && (_MSC_VER < 1900) */ + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...); + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args); + +#if !defined(_MSC_VER) || (_MSC_VER >= 1400) + +#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__) + +#define usbi_err(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__) +#define usbi_warn(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__) +#define usbi_info(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__) +#define usbi_dbg(...) _usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__) + +#else /* !defined(_MSC_VER) || (_MSC_VER >= 1400) */ + +#define LOG_BODY(ctxt, level) \ +{ \ + va_list args; \ + va_start(args, format); \ + usbi_log_v(ctxt, level, "", format, args); \ + va_end(args); \ +} + +static inline void usbi_err(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_ERROR) +static inline void usbi_warn(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_WARNING) +static inline void usbi_info(struct libusb_context *ctx, const char *format, ...) + LOG_BODY(ctx, LIBUSB_LOG_LEVEL_INFO) +static inline void usbi_dbg(const char *format, ...) + LOG_BODY(NULL, LIBUSB_LOG_LEVEL_DEBUG) + +#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1400) */ + +#else /* ENABLE_LOGGING */ + +#define usbi_err(ctx, ...) do { (void)ctx; } while (0) +#define usbi_warn(ctx, ...) do { (void)ctx; } while (0) +#define usbi_info(ctx, ...) do { (void)ctx; } while (0) +#define usbi_dbg(...) do {} while (0) + +#endif /* ENABLE_LOGGING */ + +#define USBI_GET_CONTEXT(ctx) \ + do { \ + if (!(ctx)) \ + (ctx) = usbi_default_context; \ + } while(0) + +#define DEVICE_CTX(dev) ((dev)->ctx) +#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev)) +#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle)) +#define ITRANSFER_CTX(transfer) \ + (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer))) + +#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN)) +#define IS_EPOUT(ep) (!IS_EPIN(ep)) +#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN)) +#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer)) + +/* Internal abstraction for thread synchronization */ +#if defined(THREADS_POSIX) +#include "os/threads_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include "os/threads_windows.h" +#endif + +extern struct libusb_context *usbi_default_context; + +/* Forward declaration for use in context (fully defined inside poll abstraction) */ +struct pollfd; + +struct libusb_context { +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + enum libusb_log_level debug; + int debug_fixed; +#endif + + /* internal event pipe, used for signalling occurrence of an internal event. */ + int event_pipe[2]; + + struct list_head usb_devs; + usbi_mutex_t usb_devs_lock; + + /* A list of open handles. Backends are free to traverse this if required. + */ + struct list_head open_devs; + usbi_mutex_t open_devs_lock; + + /* A list of registered hotplug callbacks */ + struct list_head hotplug_cbs; + libusb_hotplug_callback_handle next_hotplug_cb_handle; + usbi_mutex_t hotplug_cbs_lock; + + /* this is a list of in-flight transfer handles, sorted by timeout + * expiration. URBs to timeout the soonest are placed at the beginning of + * the list, URBs that will time out later are placed after, and urbs with + * infinite timeout are always placed at the very end. */ + struct list_head flying_transfers; + /* Note paths taking both this and usbi_transfer->lock must always + * take this lock first */ + usbi_mutex_t flying_transfers_lock; + + /* user callbacks for pollfd changes */ + libusb_pollfd_added_cb fd_added_cb; + libusb_pollfd_removed_cb fd_removed_cb; + void *fd_cb_user_data; + + /* ensures that only one thread is handling events at any one time */ + usbi_mutex_t events_lock; + + /* used to see if there is an active thread doing event handling */ + int event_handler_active; + + /* A thread-local storage key to track which thread is performing event + * handling */ + usbi_tls_key_t event_handling_key; + + /* used to wait for event completion in threads other than the one that is + * event handling */ + usbi_mutex_t event_waiters_lock; + usbi_cond_t event_waiters_cond; + + /* A lock to protect internal context event data. */ + usbi_mutex_t event_data_lock; + + /* A bitmask of flags that are set to indicate specific events that need to + * be handled. Protected by event_data_lock. */ + unsigned int event_flags; + + /* A counter that is set when we want to interrupt and prevent event handling, + * in order to safely close a device. Protected by event_data_lock. */ + unsigned int device_close; + + /* list and count of poll fds and an array of poll fd structures that is + * (re)allocated as necessary prior to polling. Protected by event_data_lock. */ + struct list_head ipollfds; + struct pollfd *pollfds; + POLL_NFDS_TYPE pollfds_cnt; + + /* A list of pending hotplug messages. Protected by event_data_lock. */ + struct list_head hotplug_msgs; + + /* A list of pending completed transfers. Protected by event_data_lock. */ + struct list_head completed_transfers; + +#ifdef USBI_TIMERFD_AVAILABLE + /* used for timeout handling, if supported by OS. + * this timerfd is maintained to trigger on the next pending timeout */ + int timerfd; +#endif + + struct list_head list; + + PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY]; +}; + +enum usbi_event_flags { + /* The list of pollfds has been modified */ + USBI_EVENT_POLLFDS_MODIFIED = 1 << 0, + + /* The user has interrupted the event handler */ + USBI_EVENT_USER_INTERRUPT = 1 << 1, + + /* A hotplug callback deregistration is pending */ + USBI_EVENT_HOTPLUG_CB_DEREGISTERED = 1 << 2, +}; + +/* Macros for managing event handling state */ +#define usbi_handling_events(ctx) \ + (usbi_tls_key_get((ctx)->event_handling_key) != NULL) + +#define usbi_start_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, ctx) + +#define usbi_end_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, NULL) + +/* Update the following macro if new event sources are added */ +#define usbi_pending_events(ctx) \ + ((ctx)->event_flags || (ctx)->device_close \ + || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers)) + +#ifdef USBI_TIMERFD_AVAILABLE +#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0) +#else +#define usbi_using_timerfd(ctx) (0) +#endif + +struct libusb_device { + /* lock protects refcnt, everything else is finalized at initialization + * time */ + usbi_mutex_t lock; + int refcnt; + + struct libusb_context *ctx; + + uint8_t bus_number; + uint8_t port_number; + struct libusb_device* parent_dev; + uint8_t device_address; + uint8_t num_configurations; + enum libusb_speed speed; + + struct list_head list; + unsigned long session_data; + + struct libusb_device_descriptor device_descriptor; + int attached; + + PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY]; +}; + +struct libusb_device_handle { + /* lock protects claimed_interfaces */ + usbi_mutex_t lock; + unsigned long claimed_interfaces; + + struct list_head list; + struct libusb_device *dev; + int auto_detach_kernel_driver; + + PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY]; +}; + +enum { + USBI_CLOCK_MONOTONIC, + USBI_CLOCK_REALTIME +}; + +/* in-memory transfer layout: + * + * 1. struct usbi_transfer + * 2. struct libusb_transfer (which includes iso packets) [variable size] + * 3. os private data [variable size] + * + * from a libusb_transfer, you can get the usbi_transfer by rewinding the + * appropriate number of bytes. + * the usbi_transfer includes the number of allocated packets, so you can + * determine the size of the transfer and hence the start and length of the + * OS-private data. + */ + +struct usbi_transfer { + int num_iso_packets; + struct list_head list; + struct list_head completed_list; + struct timeval timeout; + int transferred; + uint32_t stream_id; + uint8_t state_flags; /* Protected by usbi_transfer->lock */ + uint8_t timeout_flags; /* Protected by the flying_stransfers_lock */ + + /* this lock is held during libusb_submit_transfer() and + * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate + * cancellation, submission-during-cancellation, etc). the OS backend + * should also take this lock in the handle_events path, to prevent the user + * cancelling the transfer from another thread while you are processing + * its completion (presumably there would be races within your OS backend + * if this were possible). + * Note paths taking both this and the flying_transfers_lock must + * always take the flying_transfers_lock first */ + usbi_mutex_t lock; +}; + +enum usbi_transfer_state_flags { + /* Transfer successfully submitted by backend */ + USBI_TRANSFER_IN_FLIGHT = 1 << 0, + + /* Cancellation was requested via libusb_cancel_transfer() */ + USBI_TRANSFER_CANCELLING = 1 << 1, + + /* Operation on the transfer failed because the device disappeared */ + USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 2, +}; + +enum usbi_transfer_timeout_flags { + /* Set by backend submit_transfer() if the OS handles timeout */ + USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 0, + + /* The transfer timeout has been handled */ + USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 1, + + /* The transfer timeout was successfully processed */ + USBI_TRANSFER_TIMED_OUT = 1 << 2, +}; + +#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ + ((struct libusb_transfer *)(((unsigned char *)(transfer)) \ + + sizeof(struct usbi_transfer))) +#define LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \ + ((struct usbi_transfer *)(((unsigned char *)(transfer)) \ + - sizeof(struct usbi_transfer))) + +static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer) +{ + return ((unsigned char *)transfer) + sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (transfer->num_iso_packets + * sizeof(struct libusb_iso_packet_descriptor)); +} + +/* bus structures */ + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header { + uint8_t bLength; + uint8_t bDescriptorType; +}; + +/* shared data and functions */ + +int usbi_io_init(struct libusb_context *ctx); +void usbi_io_exit(struct libusb_context *ctx); + +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id); +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id); +int usbi_sanitize_device(struct libusb_device *dev); +void usbi_handle_disconnect(struct libusb_device_handle *dev_handle); + +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status); +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); +void usbi_signal_transfer_completion(struct usbi_transfer *transfer); + +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian); +int usbi_device_cache_descriptor(libusb_device *dev); +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx); + +void usbi_connect_device (struct libusb_device *dev); +void usbi_disconnect_device (struct libusb_device *dev); + +int usbi_signal_event(struct libusb_context *ctx); +int usbi_clear_event(struct libusb_context *ctx); + +/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ +#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) ||\ + defined(OS_HAIKU) || defined(OS_SUNOS) +#include +#include "os/poll_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include "os/poll_windows.h" +#endif + +struct usbi_pollfd { + /* must come first */ + struct libusb_pollfd pollfd; + + struct list_head list; +}; + +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events); +void usbi_remove_pollfd(struct libusb_context *ctx, int fd); + +/* device discovery */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +struct discovered_devs { + size_t len; + size_t capacity; + struct libusb_device *devices[ZERO_SIZED_ARRAY]; +}; + +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev); + +/* OS abstraction */ + +/* This is the interface that OS backends need to implement. + * All fields are mandatory, except ones explicitly noted as optional. */ +struct usbi_os_backend { + /* A human-readable name for your backend, e.g. "Linux usbfs" */ + const char *name; + + /* Binary mask for backend specific capabilities */ + uint32_t caps; + + /* Perform initialization of your backend. You might use this function + * to determine specific capabilities of the system, allocate required + * data structures for later, etc. + * + * This function is called when a libusb user initializes the library + * prior to use. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*init)(struct libusb_context *ctx); + + /* Deinitialization. Optional. This function should destroy anything + * that was set up by init. + * + * This function is called when the user deinitializes the library. + */ + void (*exit)(struct libusb_context *ctx); + + /* Set a backend-specific option. Optional. + * + * This function is called when the user calls libusb_set_option() and + * the option is not handled by the core library. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*set_option)(struct libusb_context *ctx, enum libusb_option option, + va_list args); + + /* Enumerate all the USB devices on the system, returning them in a list + * of discovered devices. + * + * Your implementation should enumerate all devices on the system, + * regardless of whether they have been seen before or not. + * + * When you have found a device, compute a session ID for it. The session + * ID should uniquely represent that particular device for that particular + * connection session since boot (i.e. if you disconnect and reconnect a + * device immediately after, it should be assigned a different session ID). + * If your OS cannot provide a unique session ID as described above, + * presenting a session ID of (bus_number << 8 | device_address) should + * be sufficient. Bus numbers and device addresses wrap and get reused, + * but that is an unlikely case. + * + * After computing a session ID for a device, call + * usbi_get_device_by_session_id(). This function checks if libusb already + * knows about the device, and if so, it provides you with a reference + * to a libusb_device structure for it. + * + * If usbi_get_device_by_session_id() returns NULL, it is time to allocate + * a new device structure for the device. Call usbi_alloc_device() to + * obtain a new libusb_device structure with reference count 1. Populate + * the bus_number and device_address attributes of the new device, and + * perform any other internal backend initialization you need to do. At + * this point, you should be ready to provide device descriptors and so + * on through the get_*_descriptor functions. Finally, call + * usbi_sanitize_device() to perform some final sanity checks on the + * device. Assuming all of the above succeeded, we can now continue. + * If any of the above failed, remember to unreference the device that + * was returned by usbi_alloc_device(). + * + * At this stage we have a populated libusb_device structure (either one + * that was found earlier, or one that we have just allocated and + * populated). This can now be added to the discovered devices list + * using discovered_devs_append(). Note that discovered_devs_append() + * may reallocate the list, returning a new location for it, and also + * note that reallocation can fail. Your backend should handle these + * error conditions appropriately. + * + * This function should not generate any bus I/O and should not block. + * If I/O is required (e.g. reading the active configuration value), it is + * OK to ignore these suggestions :) + * + * This function is executed when the user wishes to retrieve a list + * of USB devices connected to the system. + * + * If the backend has hotplug support, this function is not used! + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*get_device_list)(struct libusb_context *ctx, + struct discovered_devs **discdevs); + + /* Apps which were written before hotplug support, may listen for + * hotplug events on their own and call libusb_get_device_list on + * device addition. In this case libusb_get_device_list will likely + * return a list without the new device in there, as the hotplug + * event thread will still be busy enumerating the device, which may + * take a while, or may not even have seen the event yet. + * + * To avoid this libusb_get_device_list will call this optional + * function for backends with hotplug support before copying + * ctx->usb_devs to the user. In this function the backend should + * ensure any pending hotplug events are fully processed before + * returning. + * + * Optional, should be implemented by backends with hotplug support. + */ + void (*hotplug_poll)(void); + + /* Open a device for I/O and other USB operations. The device handle + * is preallocated for you, you can retrieve the device in question + * through handle->dev. + * + * Your backend should allocate any internal resources required for I/O + * and other operations so that those operations can happen (hopefully) + * without hiccup. This is also a good place to inform libusb that it + * should monitor certain file descriptors related to this device - + * see the usbi_add_pollfd() function. + * + * This function should not generate any bus I/O and should not block. + * + * This function is called when the user attempts to obtain a device + * handle for a device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since + * discovery + * - another LIBUSB_ERROR code on other failure + * + * Do not worry about freeing the handle on failed open, the upper layers + * do this for you. + */ + int (*open)(struct libusb_device_handle *dev_handle); + + /* Close a device such that the handle cannot be used again. Your backend + * should destroy any resources that were allocated in the open path. + * This may also be a good place to call usbi_remove_pollfd() to inform + * libusb of any file descriptors associated with this device that should + * no longer be monitored. + * + * This function is called when the user closes a device handle. + */ + void (*close)(struct libusb_device_handle *dev_handle); + + /* Retrieve the device descriptor from a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. Alternatively, you may be able + * to retrieve it from a kernel interface (some Linux setups can do this) + * still without generating bus I/O. + * + * This function is expected to write DEVICE_DESC_LENGTH (18) bytes into + * buffer, which is guaranteed to be big enough. + * + * This function is called when sanity-checking a device before adding + * it to the list of discovered devices, and also when the user requests + * to read the device descriptor. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return 0 on success or a LIBUSB_ERROR code on failure. + */ + int (*get_device_descriptor)(struct libusb_device *device, + unsigned char *buffer, int *host_endian); + + /* Get the ACTIVE configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. You may also have to keep track + * of which configuration is active when the user changes it. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * - another LIBUSB_ERROR code on other failure + */ + int (*get_active_config_descriptor)(struct libusb_device *device, + unsigned char *buffer, size_t len, int *host_endian); + + /* Get a specific configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. + * + * The requested descriptor is expressed as a zero-based index (i.e. 0 + * indicates that we are requesting the first descriptor). The index does + * not (necessarily) equal the bConfigurationValue of the configuration + * being requested. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return the length read on success or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor)(struct libusb_device *device, + uint8_t config_index, unsigned char *buffer, size_t len, + int *host_endian); + + /* Like get_config_descriptor but then by bConfigurationValue instead + * of by index. + * + * Optional, if not present the core will call get_config_descriptor + * for all configs until it finds the desired bConfigurationValue. + * + * Returns a pointer to the raw-descriptor in *buffer, this memory + * is valid as long as device is valid. + * + * Returns the length of the returned raw-descriptor on success, + * or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor_by_value)(struct libusb_device *device, + uint8_t bConfigurationValue, unsigned char **buffer, + int *host_endian); + + /* Get the bConfigurationValue for the active configuration for a device. + * Optional. This should only be implemented if you can retrieve it from + * cache (don't generate I/O). + * + * If you cannot retrieve this from cache, either do not implement this + * function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause + * libusb to retrieve the information through a standard control transfer. + * + * This function must be non-blocking. + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_NOT_SUPPORTED if the value cannot be retrieved without + * blocking + * - another LIBUSB_ERROR code on other failure. + */ + int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config); + + /* Set the active configuration for a device. + * + * A configuration value of -1 should put the device in unconfigured state. + * + * This function can block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * - LIBUSB_ERROR_BUSY if interfaces are currently claimed (and hence + * configuration cannot be changed) + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure. + */ + int (*set_configuration)(struct libusb_device_handle *dev_handle, int config); + + /* Claim an interface. When claimed, the application can then perform + * I/O to an interface's endpoints. + * + * This function should not generate any bus I/O and should not block. + * Interface claiming is a logical operation that simply ensures that + * no other drivers/applications are using the interface, and after + * claiming, no other drivers/applications can use the interface because + * we now "own" it. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the interface does not exist + * - LIBUSB_ERROR_BUSY if the interface is in use by another driver/app + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number); + + /* Release a previously claimed interface. + * + * This function should also generate a SET_INTERFACE control request, + * resetting the alternate setting of that interface to 0. It's OK for + * this function to block as a result. + * + * You will only ever be asked to release an interface which was + * successfully claimed earlier. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number); + + /* Set the alternate setting for an interface. + * + * You will only ever be asked to set the alternate setting for an + * interface which was successfully claimed earlier. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the alternate setting does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, + int interface_number, int altsetting); + + /* Clear a halt/stall condition on an endpoint. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*clear_halt)(struct libusb_device_handle *dev_handle, + unsigned char endpoint); + + /* Perform a USB port reset to reinitialize a device. + * + * If possible, the device handle should still be usable after the reset + * completes, assuming that the device descriptors did not change during + * reset and all previous interface state can be restored. + * + * If something changes, or you cannot easily locate/verify the resetted + * device, return LIBUSB_ERROR_NOT_FOUND. This prompts the application + * to close the old handle and re-enumerate the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the device + * has been disconnected since it was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*reset_device)(struct libusb_device_handle *dev_handle); + + /* Alloc num_streams usb3 bulk streams on the passed in endpoints */ + int (*alloc_streams)(struct libusb_device_handle *dev_handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); + + /* Free usb3 bulk streams allocated with alloc_streams */ + int (*free_streams)(struct libusb_device_handle *dev_handle, + unsigned char *endpoints, int num_endpoints); + + /* Allocate persistent DMA memory for the given device, suitable for + * zerocopy. May return NULL on failure. Optional to implement. + */ + unsigned char *(*dev_mem_alloc)(struct libusb_device_handle *handle, + size_t len); + + /* Free memory allocated by dev_mem_alloc. */ + int (*dev_mem_free)(struct libusb_device_handle *handle, + unsigned char *buffer, size_t len); + + /* Determine if a kernel driver is active on an interface. Optional. + * + * The presence of a kernel driver on an interface indicates that any + * calls to claim_interface would fail with the LIBUSB_ERROR_BUSY code. + * + * Return: + * - 0 if no driver is active + * - 1 if a driver is active + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*kernel_driver_active)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Detach a kernel driver from an interface. Optional. + * + * After detaching a kernel driver, the interface should be available + * for claim. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*detach_kernel_driver)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Attach a kernel driver to an interface. Optional. + * + * Reattach a kernel driver to the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_BUSY if a program or driver has claimed the interface, + * preventing reattachment + * - another LIBUSB_ERROR code on other failure + */ + int (*attach_kernel_driver)(struct libusb_device_handle *dev_handle, + int interface_number); + + /* Destroy a device. Optional. + * + * This function is called when the last reference to a device is + * destroyed. It should free any resources allocated in the get_device_list + * path. + */ + void (*destroy_device)(struct libusb_device *dev); + + /* Submit a transfer. Your implementation should take the transfer, + * morph it into whatever form your platform requires, and submit it + * asynchronously. + * + * This function must not block. + * + * This function gets called with the flying_transfers_lock locked! + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * - another LIBUSB_ERROR code on other failure + */ + int (*submit_transfer)(struct usbi_transfer *itransfer); + + /* Cancel a previously submitted transfer. + * + * This function must not block. The transfer cancellation must complete + * later, resulting in a call to usbi_handle_transfer_cancellation() + * from the context of handle_events. + */ + int (*cancel_transfer)(struct usbi_transfer *itransfer); + + /* Clear a transfer as if it has completed or cancelled, but do not + * report any completion/cancellation to the library. You should free + * all private data from the transfer as if you were just about to report + * completion or cancellation. + * + * This function might seem a bit out of place. It is used when libusb + * detects a disconnected device - it calls this function for all pending + * transfers before reporting completion (with the disconnect code) to + * the user. Maybe we can improve upon this internal interface in future. + */ + void (*clear_transfer_priv)(struct usbi_transfer *itransfer); + + /* Handle any pending events on file descriptors. Optional. + * + * Provide this function when file descriptors directly indicate device + * or transfer activity. If your backend does not have such file descriptors, + * implement the handle_transfer_completion function below. + * + * This involves monitoring any active transfers and processing their + * completion or cancellation. + * + * The function is passed an array of pollfd structures (size nfds) + * as a result of the poll() system call. The num_ready parameter + * indicates the number of file descriptors that have reported events + * (i.e. the poll() return value). This should be enough information + * for you to determine which actions need to be taken on the currently + * active transfers. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * This function should also be able to detect disconnection of the + * device, reporting that situation with usbi_handle_disconnect(). + * + * When processing an event related to a transfer, you probably want to + * take usbi_transfer.lock to prevent races. See the documentation for + * the usbi_transfer structure. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_events)(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready); + + /* Handle transfer completion. Optional. + * + * Provide this function when there are no file descriptors available + * that directly indicate device or transfer activity. If your backend does + * have such file descriptors, implement the handle_events function above. + * + * Your backend must tell the library when a transfer has completed by + * calling usbi_signal_transfer_completion(). You should store any private + * information about the transfer and its completion status in the transfer's + * private backend data. + * + * During event handling, this function will be called on each transfer for + * which usbi_signal_transfer_completion() was called. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_transfer_completion)(struct usbi_transfer *itransfer); + + /* Get time from specified clock. At least two clocks must be implemented + by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC. + + Description of clocks: + USBI_CLOCK_REALTIME : clock returns time since system epoch. + USBI_CLOCK_MONOTONIC: clock returns time since unspecified start + time (usually boot). + */ + int (*clock_gettime)(int clkid, struct timespec *tp); + +#ifdef USBI_TIMERFD_AVAILABLE + /* clock ID of the clock that should be used for timerfd */ + clockid_t (*get_timerfd_clockid)(void); +#endif + + /* Number of bytes to reserve for per-context private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_context. */ + size_t context_priv_size; + + /* Number of bytes to reserve for per-device private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_priv_size; + + /* Number of bytes to reserve for per-handle private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_handle_priv_size; + + /* Number of bytes to reserve for per-transfer private backend data. + * This private data area is accessible by calling + * usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance. + */ + size_t transfer_priv_size; +}; + +extern const struct usbi_os_backend usbi_backend; + +extern struct list_head active_contexts_list; +extern usbi_mutex_static_t active_contexts_lock; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.c new file mode 100644 index 00000000..35ea1c32 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.c @@ -0,0 +1,2142 @@ +/* -*- Mode: C; indent-tabs-mode:nil -*- */ +/* + * darwin backend for libusb 1.0 + * Copyright © 2008-2017 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector + * function. Its use is also conditionalized to only older deployment targets. */ +#define OBJC_SILENCE_GC_DEPRECATIONS 1 + +#include +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + #include +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 +/* Apple deprecated the darwin atomics in 10.12 in favor of C11 atomics */ +#include +#define libusb_darwin_atomic_fetch_add(x, y) atomic_fetch_add(x, y) + +_Atomic int32_t initCount = ATOMIC_VAR_INIT(0); +#else +/* use darwin atomics if the target is older than 10.12 */ +#include + +/* OSAtomicAdd32Barrier returns the new value */ +#define libusb_darwin_atomic_fetch_add(x, y) (OSAtomicAdd32Barrier(y, x) - y) + +static volatile int32_t initCount = 0; + +#endif + +/* On 10.12 and later, use newly available clock_*() functions */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 +#define OSX_USE_CLOCK_GETTIME 1 +#else +#define OSX_USE_CLOCK_GETTIME 0 +#endif + +#include "darwin_usb.h" + +/* async event thread */ +static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER; + +static pthread_once_t darwin_init_once = PTHREAD_ONCE_INIT; + +#if !OSX_USE_CLOCK_GETTIME +static clock_serv_t clock_realtime; +static clock_serv_t clock_monotonic; +#endif + +static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */ +static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */ + +static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER; +static struct list_head darwin_cached_devices = {&darwin_cached_devices, &darwin_cached_devices}; +static const char *darwin_device_class = kIOUSBDeviceClassName; + +#define DARWIN_CACHED_DEVICE(a) ((struct darwin_cached_device *) (((struct darwin_device_priv *)((a)->os_priv))->dev)) + +/* async event thread */ +static pthread_t libusb_darwin_at; + +static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian); +static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface); +static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface); +static int darwin_reset_device(struct libusb_device_handle *dev_handle); +static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0); + +static int darwin_scan_devices(struct libusb_context *ctx); +static int process_new_device (struct libusb_context *ctx, io_service_t service); + +#if defined(ENABLE_LOGGING) +static const char *darwin_error_str (int result) { + static char string_buffer[50]; + switch (result) { + case kIOReturnSuccess: + return "no error"; + case kIOReturnNotOpen: + return "device not opened for exclusive access"; + case kIOReturnNoDevice: + return "no connection to an IOService"; + case kIOUSBNoAsyncPortErr: + return "no async port has been opened for interface"; + case kIOReturnExclusiveAccess: + return "another process has device opened for exclusive access"; + case kIOUSBPipeStalled: + return "pipe is stalled"; + case kIOReturnError: + return "could not establish a connection to the Darwin kernel"; + case kIOUSBTransactionTimeout: + return "transaction timed out"; + case kIOReturnBadArgument: + return "invalid argument"; + case kIOReturnAborted: + return "transaction aborted"; + case kIOReturnNotResponding: + return "device not responding"; + case kIOReturnOverrun: + return "data overrun"; + case kIOReturnCannotWire: + return "physical memory can not be wired down"; + case kIOReturnNoResources: + return "out of resources"; + case kIOUSBHighSpeedSplitError: + return "high speed split error"; + default: + snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result); + return string_buffer; + } +} +#endif + +static int darwin_to_libusb (int result) { + switch (result) { + case kIOReturnUnderrun: + case kIOReturnSuccess: + return LIBUSB_SUCCESS; + case kIOReturnNotOpen: + case kIOReturnNoDevice: + return LIBUSB_ERROR_NO_DEVICE; + case kIOReturnExclusiveAccess: + return LIBUSB_ERROR_ACCESS; + case kIOUSBPipeStalled: + return LIBUSB_ERROR_PIPE; + case kIOReturnBadArgument: + return LIBUSB_ERROR_INVALID_PARAM; + case kIOUSBTransactionTimeout: + return LIBUSB_ERROR_TIMEOUT; + case kIOReturnNotResponding: + case kIOReturnAborted: + case kIOReturnError: + case kIOUSBNoAsyncPortErr: + default: + return LIBUSB_ERROR_OTHER; + } +} + +/* this function must be called with the darwin_cached_devices_lock held */ +static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) { + cached_dev->refcount--; + /* free the device and remove it from the cache */ + if (0 == cached_dev->refcount) { + list_del(&cached_dev->list); + + (*(cached_dev->device))->Release(cached_dev->device); + free (cached_dev); + } +} + +static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) { + cached_dev->refcount++; +} + +static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp, struct darwin_interface **interface_out) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + + /* current interface */ + struct darwin_interface *cInterface; + + int8_t i, iface; + + usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep); + + for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) { + cInterface = &priv->interfaces[iface]; + + if (dev_handle->claimed_interfaces & (1 << iface)) { + for (i = 0 ; i < cInterface->num_endpoints ; i++) { + if (cInterface->endpoint_addrs[i] == ep) { + *pipep = i + 1; + + if (ifcp) + *ifcp = iface; + + if (interface_out) + *interface_out = cInterface; + + usbi_dbg ("pipe %d on interface %d matches", *pipep, iface); + return 0; + } + } + } + } + + /* No pipe found with the correct endpoint address */ + usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep); + + return LIBUSB_ERROR_NOT_FOUND; +} + +static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) { + CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class); + + if (!matchingDict) + return kIOReturnError; + + if (location) { + CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this + internally (CFNumberType of locationID is kCFNumberSInt32Type) */ + CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location); + + if (propertyMatchDict && locationCF) { + CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF); + CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict); + } + /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */ + + /* release our references as per the Create Rule */ + if (propertyMatchDict) + CFRelease (propertyMatchDict); + if (locationCF) + CFRelease (locationCF); + } + + return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator); +} + +/* Returns 1 on success, 0 on failure. */ +static int get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) { + CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0); + int ret = 0; + + if (cfNumber) { + if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) { + ret = CFNumberGetValue(cfNumber, type, p); + } + + CFRelease (cfNumber); + } + + return ret; +} + +static int get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) { + CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0); + int ret = 0; + + if (cfData) { + if (CFGetTypeID (cfData) == CFDataGetTypeID ()) { + CFIndex length = CFDataGetLength (cfData); + if (length < size) { + size = length; + } + + CFDataGetBytes (cfData, CFRangeMake(0, size), p); + ret = 1; + } + + CFRelease (cfData); + } + + return ret; +} + +static usb_device_t **darwin_device_from_service (io_service_t service) +{ + io_cf_plugin_ref_t *plugInInterface = NULL; + usb_device_t **device; + kern_return_t result; + SInt32 score; + + result = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &plugInInterface, + &score); + + if (kIOReturnSuccess != result || !plugInInterface) { + usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (result)); + return NULL; + } + + (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID), + (LPVOID)&device); + /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */ + (*plugInInterface)->Release (plugInInterface); + + return device; +} + +static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) { + UNUSED(ptr); + struct libusb_context *ctx; + io_service_t service; + + usbi_mutex_lock(&active_contexts_lock); + + while ((service = IOIteratorNext(add_devices))) { + /* add this device to each active context's device list */ + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + process_new_device (ctx, service); + } + + IOObjectRelease(service); + } + + usbi_mutex_unlock(&active_contexts_lock); +} + +static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { + UNUSED(ptr); + struct libusb_device *dev = NULL; + struct libusb_context *ctx; + struct darwin_cached_device *old_device; + + io_service_t device; + UInt64 session; + int ret; + + usbi_mutex_lock(&active_contexts_lock); + + while ((device = IOIteratorNext (rem_devices)) != 0) { + /* get the location from the i/o registry */ + ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session); + IOObjectRelease (device); + if (!ret) + continue; + + /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function + otherwise no cached device will ever get freed */ + usbi_mutex_lock(&darwin_cached_devices_lock); + list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) { + if (old_device->session == session) { + darwin_deref_cached_device (old_device); + break; + } + } + usbi_mutex_unlock(&darwin_cached_devices_lock); + + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + usbi_dbg ("notifying context %p of device disconnect", ctx); + + dev = usbi_get_device_by_session_id(ctx, (unsigned long) session); + if (dev) { + /* signal the core that this device has been disconnected. the core will tear down this device + when the reference count reaches 0 */ + usbi_disconnect_device(dev); + libusb_unref_device(dev); + } + } + } + + usbi_mutex_unlock(&active_contexts_lock); +} + +static void darwin_hotplug_poll (void) +{ + /* not sure if 5 seconds will be too long/short but it should work ok */ + mach_timespec_t timeout = {.tv_sec = 5, .tv_nsec = 0}; + + /* since a kernel thread may nodify the IOInterators used for + * hotplug notidication we can't just clear the iterators. + * instead just wait until all IOService providers are quiet */ + (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout); +} + +static void darwin_clear_iterator (io_iterator_t iter) { + io_service_t device; + + while ((device = IOIteratorNext (iter)) != 0) + IOObjectRelease (device); +} + +static void *darwin_event_thread_main (void *arg0) { + IOReturn kresult; + struct libusb_context *ctx = (struct libusb_context *)arg0; + CFRunLoopRef runloop; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + /* Set this thread's name, so it can be seen in the debugger + and crash reports. */ + pthread_setname_np ("org.libusb.device-hotplug"); +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + /* Tell the Objective-C garbage collector about this thread. + This is required because, unlike NSThreads, pthreads are + not automatically registered. Although we don't use + Objective-C, we use CoreFoundation, which does. + Garbage collection support was entirely removed in 10.12, + so don't bother there. */ + objc_registerThreadWithCollector(); +#endif + + /* hotplug (device arrival/removal) sources */ + CFRunLoopSourceContext libusb_shutdown_cfsourcectx; + CFRunLoopSourceRef libusb_notification_cfsource; + io_notification_port_t libusb_notification_port; + io_iterator_t libusb_rem_device_iterator; + io_iterator_t libusb_add_device_iterator; + + usbi_dbg ("creating hotplug event source"); + + runloop = CFRunLoopGetCurrent (); + CFRetain (runloop); + + /* add the shutdown cfsource to the run loop */ + memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx)); + libusb_shutdown_cfsourcectx.info = runloop; + libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop; + libusb_darwin_acfls = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx); + CFRunLoopAddSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode); + + /* add the notification port to the run loop */ + libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault); + libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port); + CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode); + + /* create notifications for removed devices */ + kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification, + IOServiceMatching(darwin_device_class), + darwin_devices_detached, + ctx, &libusb_rem_device_iterator); + + if (kresult != kIOReturnSuccess) { + usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult)); + + pthread_exit (NULL); + } + + /* create notifications for attached devices */ + kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification, + IOServiceMatching(darwin_device_class), + darwin_devices_attached, + ctx, &libusb_add_device_iterator); + + if (kresult != kIOReturnSuccess) { + usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult)); + + pthread_exit (NULL); + } + + /* arm notifiers */ + darwin_clear_iterator (libusb_rem_device_iterator); + darwin_clear_iterator (libusb_add_device_iterator); + + usbi_dbg ("darwin event thread ready to receive events"); + + /* signal the main thread that the hotplug runloop has been created. */ + pthread_mutex_lock (&libusb_darwin_at_mutex); + libusb_darwin_acfl = runloop; + pthread_cond_signal (&libusb_darwin_at_cond); + pthread_mutex_unlock (&libusb_darwin_at_mutex); + + /* run the runloop */ + CFRunLoopRun(); + + usbi_dbg ("darwin event thread exiting"); + + /* remove the notification cfsource */ + CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode); + + /* remove the shutdown cfsource */ + CFRunLoopRemoveSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode); + + /* delete notification port */ + IONotificationPortDestroy (libusb_notification_port); + + /* delete iterators */ + IOObjectRelease (libusb_rem_device_iterator); + IOObjectRelease (libusb_add_device_iterator); + + CFRelease (libusb_darwin_acfls); + CFRelease (runloop); + + libusb_darwin_acfls = NULL; + libusb_darwin_acfl = NULL; + + pthread_exit (NULL); +} + +/* cleanup function to destroy cached devices */ +static void __attribute__((destructor)) _darwin_finalize(void) { + struct darwin_cached_device *dev, *next; + + usbi_mutex_lock(&darwin_cached_devices_lock); + list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) { + darwin_deref_cached_device(dev); + } + usbi_mutex_unlock(&darwin_cached_devices_lock); +} + +static void darwin_check_version (void) { + /* adjust for changes in the USB stack in xnu 15 */ + int sysctl_args[] = {CTL_KERN, KERN_OSRELEASE}; + long version; + char version_string[256] = {'\0',}; + size_t length = 256; + + sysctl(sysctl_args, 2, version_string, &length, NULL, 0); + + errno = 0; + version = strtol (version_string, NULL, 10); + if (0 == errno && version >= 15) { + darwin_device_class = "IOUSBHostDevice"; + } +} + +static int darwin_init(struct libusb_context *ctx) { + int rc; + + rc = pthread_once (&darwin_init_once, darwin_check_version); + if (rc) { + return LIBUSB_ERROR_OTHER; + } + + rc = darwin_scan_devices (ctx); + if (LIBUSB_SUCCESS != rc) { + return rc; + } + + if (libusb_darwin_atomic_fetch_add (&initCount, 1) == 0) { +#if !OSX_USE_CLOCK_GETTIME + /* create the clocks that will be used if clock_gettime() is not available */ + host_name_port_t host_self; + + host_self = mach_host_self(); + host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime); + host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic); + mach_port_deallocate(mach_task_self(), host_self); +#endif + + pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx); + + pthread_mutex_lock (&libusb_darwin_at_mutex); + while (!libusb_darwin_acfl) + pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex); + pthread_mutex_unlock (&libusb_darwin_at_mutex); + } + + return rc; +} + +static void darwin_exit (struct libusb_context *ctx) { + UNUSED(ctx); + if (libusb_darwin_atomic_fetch_add (&initCount, -1) == 1) { +#if !OSX_USE_CLOCK_GETTIME + mach_port_deallocate(mach_task_self(), clock_realtime); + mach_port_deallocate(mach_task_self(), clock_monotonic); +#endif + + /* stop the event runloop and wait for the thread to terminate. */ + CFRunLoopSourceSignal(libusb_darwin_acfls); + CFRunLoopWakeUp (libusb_darwin_acfl); + pthread_join (libusb_darwin_at, NULL); + } +} + +static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + + /* return cached copy */ + memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return 0; +} + +static int get_configuration_index (struct libusb_device *dev, int config_value) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + UInt8 i, numConfig; + IOUSBConfigurationDescriptorPtr desc; + IOReturn kresult; + + /* is there a simpler way to determine the index? */ + kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + for (i = 0 ; i < numConfig ; i++) { + (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc); + + if (desc->bConfigurationValue == config_value) + return i; + } + + /* configuration not found */ + return LIBUSB_ERROR_NOT_FOUND; +} + +static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + int config_index; + + if (0 == priv->active_config) + return LIBUSB_ERROR_NOT_FOUND; + + config_index = get_configuration_index (dev, priv->active_config); + if (config_index < 0) + return config_index; + + return darwin_get_config_descriptor (dev, config_index, buffer, len, host_endian); +} + +static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) { + struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev); + IOUSBConfigurationDescriptorPtr desc; + IOReturn kresult; + int ret; + + if (!priv || !priv->device) + return LIBUSB_ERROR_OTHER; + + kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc); + if (kresult == kIOReturnSuccess) { + /* copy descriptor */ + if (libusb_le16_to_cpu(desc->wTotalLength) < len) + len = libusb_le16_to_cpu(desc->wTotalLength); + + memmove (buffer, desc, len); + + /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */ + *host_endian = 0; + } + + ret = darwin_to_libusb (kresult); + if (ret != LIBUSB_SUCCESS) + return ret; + + return (int) len; +} + +/* check whether the os has configured the device */ +static int darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) { + usb_device_t **darwin_device = dev->device; + + IOUSBConfigurationDescriptorPtr configDesc; + IOUSBFindInterfaceRequest request; + kern_return_t kresult; + io_iterator_t interface_iterator; + io_service_t firstInterface; + + if (dev->dev_descriptor.bNumConfigurations < 1) { + usbi_err (ctx, "device has no configurations"); + return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */ + } + + /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is + not usable anyway */ + if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) { + usbi_dbg ("ignoring configuration on root hub simulation"); + dev->active_config = 0; + return 0; + } + + /* find the first configuration */ + kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc); + dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1; + + /* check if the device is already configured. there is probably a better way than iterating over the + to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices + might lock up on the device request) */ + + /* Setup the Interface Request */ + request.bInterfaceClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + + kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator); + if (kresult) + return darwin_to_libusb (kresult); + + /* iterate once */ + firstInterface = IOIteratorNext(interface_iterator); + + /* done with the interface iterator */ + IOObjectRelease(interface_iterator); + + if (firstInterface) { + IOObjectRelease (firstInterface); + + /* device is configured */ + if (dev->dev_descriptor.bNumConfigurations == 1) + /* to avoid problems with some devices get the configurations value from the configuration descriptor */ + dev->active_config = dev->first_config; + else + /* devices with more than one configuration should work with GetConfiguration */ + (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config); + } else + /* not configured */ + dev->active_config = 0; + + usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config); + + return 0; +} + +static int darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) { + IOUSBDevRequestTO req; + + memset (buffer, 0, buffer_size); + + /* Set up request for descriptor/ */ + req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); + req.bRequest = kUSBRqGetDescriptor; + req.wValue = desc << 8; + req.wIndex = desc_index; + req.wLength = buffer_size; + req.pData = buffer; + req.noDataTimeout = 20; + req.completionTimeout = 100; + + return (*device)->DeviceRequestTO (device, &req); +} + +static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) { + usb_device_t **device = dev->device; + int retries = 1, delay = 30000; + int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1; + int is_open = 0; + int ret = 0, ret2; + UInt8 bDeviceClass; + UInt16 idProduct, idVendor; + + dev->can_enumerate = 0; + + (*device)->GetDeviceClass (device, &bDeviceClass); + (*device)->GetDeviceProduct (device, &idProduct); + (*device)->GetDeviceVendor (device, &idVendor); + + /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some + * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still, + * to follow the spec as closely as possible, try opening the device */ + is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess); + + do { + /**** retrieve device descriptor ****/ + ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor)); + + if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType) + /* received an overrun error but we still received a device descriptor */ + ret = kIOReturnSuccess; + + if (kIOUSBVendorIDAppleComputer == idVendor) { + /* NTH: don't bother retrying or unsuspending Apple devices */ + break; + } + + if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations || + 0 == dev->dev_descriptor.bcdUSB)) { + /* work around for incorrectly configured devices */ + if (try_reconfigure && is_open) { + usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again..."); + + /* set the first configuration */ + (*device)->SetConfiguration(device, 1); + + /* don't try to reconfigure again */ + try_reconfigure = 0; + } + + ret = kIOUSBPipeStalled; + } + + if (kIOReturnSuccess != ret && is_open && try_unsuspend) { + /* device may be suspended. unsuspend it and try again */ +#if DeviceVersion >= 320 + UInt32 info = 0; + + /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */ + (void)(*device)->GetUSBDeviceInformation (device, &info); + + /* note that the device was suspended */ + if (info & (1 << kUSBInformationDeviceIsSuspendedBit) || 0 == info) + try_unsuspend = 1; +#endif + + if (try_unsuspend) { + /* try to unsuspend the device */ + ret2 = (*device)->USBDeviceSuspend (device, 0); + if (kIOReturnSuccess != ret2) { + /* prevent log spew from poorly behaving devices. this indicates the + os actually had trouble communicating with the device */ + usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2)); + } else + unsuspended = 1; + + try_unsuspend = 0; + } + } + + if (kIOReturnSuccess != ret) { + usbi_dbg("kernel responded with code: 0x%08x. sleeping for %d ms before trying again", ret, delay/1000); + /* sleep for a little while before trying again */ + nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL); + } + } while (kIOReturnSuccess != ret && retries--); + + if (unsuspended) + /* resuspend the device */ + (void)(*device)->USBDeviceSuspend (device, 1); + + if (is_open) + (void) (*device)->USBDeviceClose (device); + + if (ret != kIOReturnSuccess) { + /* a debug message was already printed out for this error */ + if (LIBUSB_CLASS_HUB == bDeviceClass) + usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device", + idVendor, idProduct, darwin_error_str (ret), ret); + else + usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device", + idVendor, idProduct, darwin_error_str (ret), ret); + return darwin_to_libusb (ret); + } + + /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */ + if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) { + /* not a valid device */ + usbi_warn (ctx, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device", + idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct)); + return LIBUSB_ERROR_NO_DEVICE; + } + + usbi_dbg ("cached device descriptor:"); + usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType); + usbi_dbg (" bcdUSB: 0x%04x", dev->dev_descriptor.bcdUSB); + usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass); + usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass); + usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol); + usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0); + usbi_dbg (" idVendor: 0x%04x", dev->dev_descriptor.idVendor); + usbi_dbg (" idProduct: 0x%04x", dev->dev_descriptor.idProduct); + usbi_dbg (" bcdDevice: 0x%04x", dev->dev_descriptor.bcdDevice); + usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer); + usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct); + usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber); + usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations); + + dev->can_enumerate = 1; + + return LIBUSB_SUCCESS; +} + +static int get_device_port (io_service_t service, UInt8 *port) { + kern_return_t result; + io_service_t parent; + int ret = 0; + + if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) { + return 1; + } + + result = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent); + if (kIOReturnSuccess == result) { + ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port); + IOObjectRelease (parent); + } + + return ret; +} + +static int get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) { + kern_return_t result; + io_service_t parent; + + /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */ + parent = service; + while((result = IORegistryEntryGetParentEntry (parent, kIOServicePlane, &parent)) == kIOReturnSuccess) { + if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) { + /* Success */ + return 1; + } + } + + /* We ran out of parents */ + return 0; +} + +static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, + struct darwin_cached_device **cached_out) { + struct darwin_cached_device *new_device; + UInt64 sessionID = 0, parent_sessionID = 0; + int ret = LIBUSB_SUCCESS; + usb_device_t **device; + UInt8 port = 0; + + /* get some info from the io registry */ + (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID); + if (!get_device_port (service, &port)) { + usbi_dbg("could not get connected port number"); + } + + usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID); + + if (get_device_parent_sessionID(service, &parent_sessionID)) { + usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID); + } + + usbi_mutex_lock(&darwin_cached_devices_lock); + do { + *cached_out = NULL; + + list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) { + usbi_dbg("matching sessionID 0x%" PRIx64 " against cached device with sessionID 0x%" PRIx64, sessionID, new_device->session); + if (new_device->session == sessionID) { + usbi_dbg("using cached device for device"); + *cached_out = new_device; + break; + } + } + + if (*cached_out) + break; + + usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID); + + device = darwin_device_from_service (service); + if (!device) { + ret = LIBUSB_ERROR_NO_DEVICE; + break; + } + + new_device = calloc (1, sizeof (*new_device)); + if (!new_device) { + ret = LIBUSB_ERROR_NO_MEM; + break; + } + + /* add this device to the cached device list */ + list_add(&new_device->list, &darwin_cached_devices); + + (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address); + + /* keep a reference to this device */ + darwin_ref_cached_device(new_device); + + new_device->device = device; + new_device->session = sessionID; + (*device)->GetLocationID (device, &new_device->location); + new_device->port = port; + new_device->parent_session = parent_sessionID; + + /* cache the device descriptor */ + ret = darwin_cache_device_descriptor(ctx, new_device); + if (ret) + break; + + if (new_device->can_enumerate) { + snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address, + new_device->dev_descriptor.idVendor, new_device->dev_descriptor.idProduct, + new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass); + } + } while (0); + + usbi_mutex_unlock(&darwin_cached_devices_lock); + + /* keep track of devices regardless of if we successfully enumerate them to + prevent them from being enumerated multiple times */ + + *cached_out = new_device; + + return ret; +} + +static int process_new_device (struct libusb_context *ctx, io_service_t service) { + struct darwin_device_priv *priv; + struct libusb_device *dev = NULL; + struct darwin_cached_device *cached_device; + UInt8 devSpeed; + int ret = 0; + + do { + ret = darwin_get_cached_device (ctx, service, &cached_device); + + if (ret < 0 || !cached_device->can_enumerate) { + return ret; + } + + /* check current active configuration (and cache the first configuration value-- + which may be used by claim_interface) */ + ret = darwin_check_configuration (ctx, cached_device); + if (ret) + break; + + usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64, + ctx, cached_device->session); + + dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session); + if (!dev) { + return LIBUSB_ERROR_NO_MEM; + } + + priv = (struct darwin_device_priv *)dev->os_priv; + + priv->dev = cached_device; + darwin_ref_cached_device (priv->dev); + + if (cached_device->parent_session > 0) { + dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session); + } else { + dev->parent_dev = NULL; + } + dev->port_number = cached_device->port; + dev->bus_number = cached_device->location >> 24; + dev->device_address = cached_device->address; + + (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed); + + switch (devSpeed) { + case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break; + case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break; + case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break; +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 + case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break; +#endif + default: + usbi_warn (ctx, "Got unknown device speed %d", devSpeed); + } + + ret = usbi_sanitize_device (dev); + if (ret < 0) + break; + + usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address, + dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path); + } while (0); + + if (0 == ret) { + usbi_connect_device (dev); + } else { + libusb_unref_device (dev); + } + + return ret; +} + +static int darwin_scan_devices(struct libusb_context *ctx) { + io_iterator_t deviceIterator; + io_service_t service; + kern_return_t kresult; + + kresult = usb_setup_device_iterator (&deviceIterator, 0); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + while ((service = IOIteratorNext (deviceIterator))) { + (void) process_new_device (ctx, service); + + IOObjectRelease(service); + } + + IOObjectRelease(deviceIterator); + + return 0; +} + +static int darwin_open (struct libusb_device_handle *dev_handle) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + + if (0 == dpriv->open_count) { + /* try to open the device */ + kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device); + if (kresult != kIOReturnSuccess) { + usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult)); + + if (kIOReturnExclusiveAccess != kresult) { + return darwin_to_libusb (kresult); + } + + /* it is possible to perform some actions on a device that is not open so do not return an error */ + priv->is_open = 0; + } else { + priv->is_open = 1; + } + + /* create async event source */ + kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource); + if (kresult != kIOReturnSuccess) { + usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult)); + + if (priv->is_open) { + (*(dpriv->device))->USBDeviceClose (dpriv->device); + } + + priv->is_open = 0; + + return darwin_to_libusb (kresult); + } + + CFRetain (libusb_darwin_acfl); + + /* add the cfSource to the aync run loop */ + CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes); + } + + /* device opened successfully */ + dpriv->open_count++; + + usbi_dbg ("device open for access"); + + return 0; +} + +static void darwin_close (struct libusb_device_handle *dev_handle) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + int i; + + if (dpriv->open_count == 0) { + /* something is probably very wrong if this is the case */ + usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!"); + return; + } + + dpriv->open_count--; + + /* make sure all interfaces are released */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + libusb_release_interface (dev_handle, i); + + if (0 == dpriv->open_count) { + /* delete the device's async event source */ + if (priv->cfSource) { + CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode); + CFRelease (priv->cfSource); + priv->cfSource = NULL; + CFRelease (libusb_darwin_acfl); + } + + if (priv->is_open) { + /* close the device */ + kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device); + if (kresult) { + /* Log the fact that we had a problem closing the file, however failing a + * close isn't really an error, so return success anyway */ + usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult)); + } + } + } +} + +static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + + *config = (int) dpriv->active_config; + + return 0; +} + +static int darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOReturn kresult; + int i; + + /* Setting configuration will invalidate the interface, so we need + to reclaim it. First, dispose of existing interfaces, if any. */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + darwin_release_interface (dev_handle, i); + + kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, config); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + /* Reclaim any interfaces. */ + for (i = 0 ; i < USB_MAXINTERFACES ; i++) + if (dev_handle->claimed_interfaces & (1 << i)) + darwin_claim_interface (dev_handle, i); + + dpriv->active_config = config; + + return 0; +} + +static int darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) { + IOUSBFindInterfaceRequest request; + kern_return_t kresult; + io_iterator_t interface_iterator; + UInt8 bInterfaceNumber; + int ret; + + *usbInterfacep = IO_OBJECT_NULL; + + /* Setup the Interface Request */ + request.bInterfaceClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; + request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + + kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator); + if (kresult) + return kresult; + + while ((*usbInterfacep = IOIteratorNext(interface_iterator))) { + /* find the interface number */ + ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type, + &bInterfaceNumber); + + if (ret && bInterfaceNumber == ifc) { + break; + } + + (void) IOObjectRelease (*usbInterfacep); + } + + /* done with the interface iterator */ + IOObjectRelease(interface_iterator); + + return 0; +} + +static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + kern_return_t kresult; + + UInt8 numep, direction, number; + UInt8 dont_care1, dont_care3; + UInt16 dont_care2; + int rc; + + usbi_dbg ("building table of endpoints."); + + /* retrieve the total number of endpoints on this interface */ + kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* iterate through pipe references */ + for (int i = 1 ; i <= numep ; i++) { + kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1, + &dont_care2, &dont_care3); + + if (kresult != kIOReturnSuccess) { + /* probably a buggy device. try to get the endpoint address from the descriptors */ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *endpoint_desc; + UInt8 alt_setting; + + kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface"); + return darwin_to_libusb (kresult); + } + + rc = libusb_get_active_config_descriptor (dev_handle->dev, &config); + if (LIBUSB_SUCCESS != rc) { + return rc; + } + + endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1; + + cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress; + } else { + cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK)); + } + + usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift, + cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK); + } + + cInterface->num_endpoints = numep; + + return 0; +} + +static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + io_service_t usbInterface = IO_OBJECT_NULL; + IOReturn kresult; + IOCFPlugInInterface **plugInInterface = NULL; + SInt32 score; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + kresult = darwin_get_interface (dpriv->device, iface, &usbInterface); + if (kresult != kIOReturnSuccess) + return darwin_to_libusb (kresult); + + /* make sure we have an interface */ + if (!usbInterface && dpriv->first_config != 0) { + usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config); + + /* set the configuration */ + kresult = darwin_set_configuration (dev_handle, dpriv->first_config); + if (kresult != LIBUSB_SUCCESS) { + usbi_err (HANDLE_CTX (dev_handle), "could not set configuration"); + return kresult; + } + + kresult = darwin_get_interface (dpriv->device, iface, &usbInterface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + } + + if (!usbInterface) { + usbi_err (HANDLE_CTX (dev_handle), "interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } + + /* get an interface to the device's interface */ + kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID, + kIOCFPlugInInterfaceID, &plugInInterface, &score); + + /* ignore release error */ + (void)IOObjectRelease (usbInterface); + + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + if (!plugInInterface) { + usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found"); + return LIBUSB_ERROR_NOT_FOUND; + } + + /* Do the actual claim */ + kresult = (*plugInInterface)->QueryInterface(plugInInterface, + CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), + (LPVOID)&cInterface->interface); + /* We no longer need the intermediate plug-in */ + /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */ + (*plugInInterface)->Release (plugInInterface); + if (kresult || !cInterface->interface) { + usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* claim the interface */ + kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); + } + + /* update list of endpoints */ + kresult = get_endpoints (dev_handle, iface); + if (kresult) { + /* this should not happen */ + darwin_release_interface (dev_handle, iface); + usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table"); + return kresult; + } + + cInterface->cfSource = NULL; + + /* create async event source */ + kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource); + if (kresult != kIOReturnSuccess) { + usbi_err (HANDLE_CTX (dev_handle), "could not create async event source"); + + /* can't continue without an async event source */ + (void)darwin_release_interface (dev_handle, iface); + + return darwin_to_libusb (kresult); + } + + /* add the cfSource to the async thread's run loop */ + CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode); + + usbi_dbg ("interface opened"); + + return 0; +} + +static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + IOReturn kresult; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + /* Check to see if an interface is open */ + if (!cInterface->interface) + return LIBUSB_SUCCESS; + + /* clean up endpoint data */ + cInterface->num_endpoints = 0; + + /* delete the interface's async event source */ + if (cInterface->cfSource) { + CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode); + CFRelease (cInterface->cfSource); + } + + kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface); + if (kresult) + usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult)); + + kresult = (*(cInterface->interface))->Release(cInterface->interface); + if (kresult != kIOReturnSuccess) + usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult)); + + cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL; + + return darwin_to_libusb (kresult); +} + +static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) { + struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv; + IOReturn kresult; + + /* current interface */ + struct darwin_interface *cInterface = &priv->interfaces[iface]; + + if (!cInterface->interface) + return LIBUSB_ERROR_NO_DEVICE; + + kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting); + if (kresult != kIOReturnSuccess) + darwin_reset_device (dev_handle); + + /* update list of endpoints */ + kresult = get_endpoints (dev_handle, iface); + if (kresult) { + /* this should not happen */ + darwin_release_interface (dev_handle, iface); + usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table"); + return kresult; + } + + return darwin_to_libusb (kresult); +} + +static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) { + /* current interface */ + struct darwin_interface *cInterface; + IOReturn kresult; + uint8_t pipeRef; + + /* determine the interface/endpoint to use */ + if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + /* newer versions of darwin support clearing additional bits on the device's endpoint */ + kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef); + if (kresult) + usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult)); + + return darwin_to_libusb (kresult); +} + +static int darwin_reset_device(struct libusb_device_handle *dev_handle) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + IOUSBDeviceDescriptor descriptor; + IOUSBConfigurationDescriptorPtr cached_configuration; + IOUSBConfigurationDescriptor configuration; + bool reenumerate = false; + IOReturn kresult; + int i; + + kresult = (*(dpriv->device))->ResetDevice (dpriv->device); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "ResetDevice: %s", darwin_error_str (kresult)); + return darwin_to_libusb (kresult); + } + + do { + usbi_dbg ("darwin/reset_device: checking if device descriptor changed"); + + /* ignore return code. if we can't get a descriptor it might be worthwhile re-enumerating anway */ + (void) darwin_request_descriptor (dpriv->device, kUSBDeviceDesc, 0, &descriptor, sizeof (descriptor)); + + /* check if the device descriptor has changed */ + if (0 != memcmp (&dpriv->dev_descriptor, &descriptor, sizeof (descriptor))) { + reenumerate = true; + break; + } + + /* check if any configuration descriptor has changed */ + for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) { + usbi_dbg ("darwin/reset_device: checking if configuration descriptor %d changed", i); + + (void) darwin_request_descriptor (dpriv->device, kUSBConfDesc, i, &configuration, sizeof (configuration)); + (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration); + + if (!cached_configuration || 0 != memcmp (cached_configuration, &configuration, sizeof (configuration))) { + reenumerate = true; + break; + } + } + } while (0); + + if (reenumerate) { + usbi_dbg ("darwin/reset_device: device requires reenumeration"); + (void) (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg ("darwin/reset_device: device reset complete"); + + return LIBUSB_SUCCESS; +} + +static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) { + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); + io_service_t usbInterface; + CFTypeRef driver; + IOReturn kresult; + + kresult = darwin_get_interface (dpriv->device, interface, &usbInterface); + if (kresult) { + usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult)); + + return darwin_to_libusb (kresult); + } + + driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0); + IOObjectRelease (usbInterface); + + if (driver) { + CFRelease (driver); + + return 1; + } + + /* no driver */ + return 0; +} + +/* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */ +static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { + UNUSED(dev_handle); + UNUSED(interface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) { + UNUSED(dev_handle); + UNUSED(interface); + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +static void darwin_destroy_device(struct libusb_device *dev) { + struct darwin_device_priv *dpriv = (struct darwin_device_priv *) dev->os_priv; + + if (dpriv->dev) { + /* need to hold the lock in case this is the last reference to the device */ + usbi_mutex_lock(&darwin_cached_devices_lock); + darwin_deref_cached_device (dpriv->dev); + dpriv->dev = NULL; + usbi_mutex_unlock(&darwin_cached_devices_lock); + } +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + IOReturn ret; + uint8_t transferType; + /* None of the values below are used in libusbx for bulk transfers */ + uint8_t direction, number, interval, pipeRef; + uint16_t maxPacketSize; + + struct darwin_interface *cInterface; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + if (ret) { + usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + return darwin_to_libusb (ret); + } + + if (0 != (transfer->length % maxPacketSize)) { + /* do not need a zero packet */ + transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET; + } + + /* submit the request */ + /* timeouts are unavailable on interrupt endpoints */ + if (transferType == kUSBInterrupt) { + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, darwin_async_io_callback, itransfer); + else + ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, darwin_async_io_callback, itransfer); + } else { + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, transfer->timeout, transfer->timeout, + darwin_async_io_callback, (void *)itransfer); + else + ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer, + transfer->length, transfer->timeout, transfer->timeout, + darwin_async_io_callback, (void *)itransfer); + } + + if (ret) + usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + + return darwin_to_libusb (ret); +} + +#if InterfaceVersion >= 550 +static int submit_stream_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_interface *cInterface; + uint8_t pipeRef; + IOReturn ret; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + if (IS_XFERIN(transfer)) + ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id, + transfer->buffer, transfer->length, transfer->timeout, + transfer->timeout, darwin_async_io_callback, (void *)itransfer); + else + ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id, + transfer->buffer, transfer->length, transfer->timeout, + transfer->timeout, darwin_async_io_callback, (void *)itransfer); + + if (ret) + usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(ret), ret); + + return darwin_to_libusb (ret); +} +#endif + +static int submit_iso_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + IOReturn kresult; + uint8_t direction, number, interval, pipeRef, transferType; + uint16_t maxPacketSize; + UInt64 frame; + AbsoluteTime atTime; + int i; + + struct darwin_interface *cInterface; + + /* construct an array of IOUSBIsocFrames, reuse the old one if possible */ + if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) { + free(tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } + + if (!tpriv->isoc_framelist) { + tpriv->num_iso_packets = transfer->num_iso_packets; + tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame)); + if (!tpriv->isoc_framelist) + return LIBUSB_ERROR_NO_MEM; + } + + /* copy the frame list from the libusb descriptor (the structures differ only is member order) */ + for (i = 0 ; i < transfer->num_iso_packets ; i++) + tpriv->isoc_framelist[i].frReqCount = transfer->iso_packet_desc[i].length; + + /* determine the interface/endpoint to use */ + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + /* determine the properties of this endpoint and the speed of the device */ + (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + /* Last but not least we need the bus frame number */ + kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime); + if (kresult) { + usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult); + free(tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + + return darwin_to_libusb (kresult); + } + + (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number, + &transferType, &maxPacketSize, &interval); + + /* schedule for a frame a little in the future */ + frame += 4; + + if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint]) + frame = cInterface->frames[transfer->endpoint]; + + /* submit the request */ + if (IS_XFERIN(transfer)) + kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame, + transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback, + itransfer); + else + kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame, + transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback, + itransfer); + + if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed) + /* Full speed */ + cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets * (1 << (interval - 1)); + else + /* High/super speed */ + cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets * (1 << (interval - 1)) / 8; + + if (kresult != kIOReturnSuccess) { + usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out", + darwin_error_str(kresult)); + free (tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } + + return darwin_to_libusb (kresult); +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + IOReturn kresult; + + memset(&tpriv->req, 0, sizeof(tpriv->req)); + + /* IOUSBDeviceInterface expects the request in cpu endianness */ + tpriv->req.bmRequestType = setup->bmRequestType; + tpriv->req.bRequest = setup->bRequest; + /* these values should be in bus order from libusb_fill_control_setup */ + tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue); + tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex); + tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength); + /* data is stored after the libusb control block */ + tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + tpriv->req.completionTimeout = transfer->timeout; + tpriv->req.noDataTimeout = transfer->timeout; + + itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT; + + /* all transfers in libusb-1.0 are async */ + + if (transfer->endpoint) { + struct darwin_interface *cInterface; + uint8_t pipeRef; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer); + } else + /* control request on endpoint 0 */ + kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer); + + if (kresult != kIOReturnSuccess) + usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult)); + + return darwin_to_libusb (kresult); +} + +static int darwin_submit_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: +#if InterfaceVersion >= 550 + return submit_stream_transfer(itransfer); +#else + usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers"); + return LIBUSB_ERROR_NOT_SUPPORTED; +#endif + default: + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int cancel_control_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + IOReturn kresult; + + usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe"); + + if (!dpriv->device) + return LIBUSB_ERROR_NO_DEVICE; + + kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device); + + return darwin_to_libusb (kresult); +} + +static int darwin_abort_transfers (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev); + struct darwin_interface *cInterface; + uint8_t pipeRef, iface; + IOReturn kresult; + + if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) { + usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface"); + + return LIBUSB_ERROR_NOT_FOUND; + } + + if (!dpriv->device) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef); + + /* abort transactions */ +#if InterfaceVersion >= 550 + if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type) + (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id); + else +#endif + (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef); + + usbi_dbg ("calling clear pipe stall to clear the data toggle bit"); + + /* newer versions of darwin support clearing additional bits on the device's endpoint */ + kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef); + + return darwin_to_libusb (kresult); +} + +static int darwin_cancel_transfer(struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return cancel_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return darwin_abort_transfers (itransfer); + default: + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && tpriv->isoc_framelist) { + free (tpriv->isoc_framelist); + tpriv->isoc_framelist = NULL; + } +} + +static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) { + struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon; + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + usbi_dbg ("an async io operation has completed"); + + /* if requested write a zero packet */ + if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + struct darwin_interface *cInterface; + uint8_t pipeRef; + + (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface); + + (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0); + } + + tpriv->result = result; + tpriv->size = (UInt32) (uintptr_t) arg0; + + /* signal the core that this transfer is complete */ + usbi_signal_transfer_completion(itransfer); +} + +static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) { + if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT) + result = kIOUSBTransactionTimeout; + + switch (result) { + case kIOReturnUnderrun: + case kIOReturnSuccess: + return LIBUSB_TRANSFER_COMPLETED; + case kIOReturnAborted: + return LIBUSB_TRANSFER_CANCELLED; + case kIOUSBPipeStalled: + usbi_dbg ("transfer error: pipe is stalled"); + return LIBUSB_TRANSFER_STALL; + case kIOReturnOverrun: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun"); + return LIBUSB_TRANSFER_OVERFLOW; + case kIOUSBTransactionTimeout: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out"); + itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT; + return LIBUSB_TRANSFER_TIMED_OUT; + default: + usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result); + return LIBUSB_TRANSFER_ERROR; + } +} + +static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type; + int isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type; + int isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type; + int isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type; + int i; + + if (!isIsoc && !isBulk && !isControl && !isInterrupt) { + usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } + + usbi_dbg ("handling %s completion with kernel status %d", + isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result); + + if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) { + if (isIsoc && tpriv->isoc_framelist) { + /* copy isochronous results back */ + + for (i = 0; i < transfer->num_iso_packets ; i++) { + struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i]; + lib_desc->status = darwin_to_libusb (tpriv->isoc_framelist[i].frStatus); + lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount; + } + } else if (!isIsoc) + itransfer->transferred += tpriv->size; + } + + /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */ + return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result)); +} + +static int darwin_clock_gettime(int clk_id, struct timespec *tp) { +#if !OSX_USE_CLOCK_GETTIME + mach_timespec_t sys_time; + clock_serv_t clock_ref; + + switch (clk_id) { + case USBI_CLOCK_REALTIME: + /* CLOCK_REALTIME represents time since the epoch */ + clock_ref = clock_realtime; + break; + case USBI_CLOCK_MONOTONIC: + /* use system boot time as reference for the monotonic clock */ + clock_ref = clock_monotonic; + break; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } + + clock_get_time (clock_ref, &sys_time); + + tp->tv_sec = sys_time.tv_sec; + tp->tv_nsec = sys_time.tv_nsec; + + return 0; +#else + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + return clock_gettime(CLOCK_MONOTONIC, tp); + case USBI_CLOCK_REALTIME: + return clock_gettime(CLOCK_REALTIME, tp); + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +#endif +} + +#if InterfaceVersion >= 550 +static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints, + int num_endpoints) { + struct darwin_interface *cInterface; + UInt32 supportsStreams; + uint8_t pipeRef; + int rc, i; + + /* find the mimimum number of supported streams on the endpoint list */ + for (i = 0 ; i < num_endpoints ; ++i) { + if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) { + return rc; + } + + (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams); + if (num_streams > supportsStreams) + num_streams = supportsStreams; + } + + /* it is an error if any endpoint in endpoints does not support streams */ + if (0 == num_streams) + return LIBUSB_ERROR_INVALID_PARAM; + + /* create the streams */ + for (i = 0 ; i < num_endpoints ; ++i) { + (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface); + + rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams); + if (kIOReturnSuccess != rc) + return darwin_to_libusb(rc); + } + + return num_streams; +} + +static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) { + struct darwin_interface *cInterface; + UInt32 supportsStreams; + uint8_t pipeRef; + int rc; + + for (int i = 0 ; i < num_endpoints ; ++i) { + if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) + return rc; + + (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams); + if (0 == supportsStreams) + return LIBUSB_ERROR_INVALID_PARAM; + + rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0); + if (kIOReturnSuccess != rc) + return darwin_to_libusb(rc); + } + + return LIBUSB_SUCCESS; +} +#endif + +const struct usbi_os_backend usbi_backend = { + .name = "Darwin", + .caps = 0, + .init = darwin_init, + .exit = darwin_exit, + .get_device_list = NULL, /* not needed */ + .get_device_descriptor = darwin_get_device_descriptor, + .get_active_config_descriptor = darwin_get_active_config_descriptor, + .get_config_descriptor = darwin_get_config_descriptor, + .hotplug_poll = darwin_hotplug_poll, + + .open = darwin_open, + .close = darwin_close, + .get_configuration = darwin_get_configuration, + .set_configuration = darwin_set_configuration, + .claim_interface = darwin_claim_interface, + .release_interface = darwin_release_interface, + + .set_interface_altsetting = darwin_set_interface_altsetting, + .clear_halt = darwin_clear_halt, + .reset_device = darwin_reset_device, + +#if InterfaceVersion >= 550 + .alloc_streams = darwin_alloc_streams, + .free_streams = darwin_free_streams, +#endif + + .kernel_driver_active = darwin_kernel_driver_active, + .detach_kernel_driver = darwin_detach_kernel_driver, + .attach_kernel_driver = darwin_attach_kernel_driver, + + .destroy_device = darwin_destroy_device, + + .submit_transfer = darwin_submit_transfer, + .cancel_transfer = darwin_cancel_transfer, + .clear_transfer_priv = darwin_clear_transfer_priv, + + .handle_transfer_completion = darwin_handle_transfer_completion, + + .clock_gettime = darwin_clock_gettime, + + .device_priv_size = sizeof(struct darwin_device_priv), + .device_handle_priv_size = sizeof(struct darwin_device_handle_priv), + .transfer_priv_size = sizeof(struct darwin_transfer_priv), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.h new file mode 100644 index 00000000..474567f6 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/darwin_usb.h @@ -0,0 +1,199 @@ +/* + * darwin backend for libusb 1.0 + * Copyright © 2008-2015 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(LIBUSB_DARWIN_H) +#define LIBUSB_DARWIN_H + +#include "libusbi.h" + +#include +#include +#include +#include + +/* IOUSBInterfaceInferface */ + +/* New in OS 10.12.0. */ +#if defined (kIOUSBInterfaceInterfaceID800) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) + +#define usb_interface_t IOUSBInterfaceInterface800 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID800 +#define InterfaceVersion 800 + +/* New in OS 10.10.0. */ +#elif defined (kIOUSBInterfaceInterfaceID700) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) + +#define usb_interface_t IOUSBInterfaceInterface700 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID700 +#define InterfaceVersion 700 + +/* New in OS 10.9.0. */ +#elif defined (kIOUSBInterfaceInterfaceID650) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) + +#define usb_interface_t IOUSBInterfaceInterface650 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID650 +#define InterfaceVersion 650 + +/* New in OS 10.8.2 but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBInterfaceInterfaceID550) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) + +#define usb_interface_t IOUSBInterfaceInterface550 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550 +#define InterfaceVersion 550 + +/* New in OS 10.7.3 but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBInterfaceInterfaceID500) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) + +#define usb_interface_t IOUSBInterfaceInterface500 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500 +#define InterfaceVersion 500 + +/* New in OS 10.5.0. */ +#elif defined (kIOUSBInterfaceInterfaceID300) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) + +#define usb_interface_t IOUSBInterfaceInterface300 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300 +#define InterfaceVersion 300 + +/* New in OS 10.4.5 (or 10.4.6?) but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBInterfaceInterfaceID245) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) + +#define usb_interface_t IOUSBInterfaceInterface245 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245 +#define InterfaceVersion 245 + +/* New in OS 10.4.0. */ +#elif defined (kIOUSBInterfaceInterfaceID220) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040) + +#define usb_interface_t IOUSBInterfaceInterface220 +#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220 +#define InterfaceVersion 220 + +#else + +#error "IOUSBFamily is too old. Please upgrade your SDK and/or deployment target" + +#endif + +/* IOUSBDeviceInterface */ + +/* New in OS 10.9.0. */ +#if defined (kIOUSBDeviceInterfaceID650) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) + +#define usb_device_t IOUSBDeviceInterface650 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID650 +#define DeviceVersion 650 + +/* New in OS 10.7.3 but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBDeviceInterfaceID500) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) + +#define usb_device_t IOUSBDeviceInterface500 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID500 +#define DeviceVersion 500 + +/* New in OS 10.5.4 but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBDeviceInterfaceID320) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) + +#define usb_device_t IOUSBDeviceInterface320 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID320 +#define DeviceVersion 320 + +/* New in OS 10.5.0. */ +#elif defined (kIOUSBDeviceInterfaceID300) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) + +#define usb_device_t IOUSBDeviceInterface300 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID300 +#define DeviceVersion 300 + +/* New in OS 10.4.5 (or 10.4.6?) but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBDeviceInterfaceID245) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) + +#define usb_device_t IOUSBDeviceInterface245 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID245 +#define DeviceVersion 245 + +/* New in OS 10.2.3 but can't test deployment target to that granularity, so round up. */ +#elif defined (kIOUSBDeviceInterfaceID197) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1030) + +#define usb_device_t IOUSBDeviceInterface197 +#define DeviceInterfaceID kIOUSBDeviceInterfaceID197 +#define DeviceVersion 197 + +#else + +#error "IOUSBFamily is too old. Please upgrade your SDK and/or deployment target" + +#endif + +#if !defined(IO_OBJECT_NULL) +#define IO_OBJECT_NULL ((io_object_t) 0) +#endif + +typedef IOCFPlugInInterface *io_cf_plugin_ref_t; +typedef IONotificationPortRef io_notification_port_t; + +/* private structures */ +struct darwin_cached_device { + struct list_head list; + IOUSBDeviceDescriptor dev_descriptor; + UInt32 location; + UInt64 parent_session; + UInt64 session; + UInt16 address; + char sys_path[21]; + usb_device_t **device; + int open_count; + UInt8 first_config, active_config, port; + int can_enumerate; + int refcount; +}; + +struct darwin_device_priv { + struct darwin_cached_device *dev; +}; + +struct darwin_device_handle_priv { + int is_open; + CFRunLoopSourceRef cfSource; + + struct darwin_interface { + usb_interface_t **interface; + uint8_t num_endpoints; + CFRunLoopSourceRef cfSource; + uint64_t frames[256]; + uint8_t endpoint_addrs[USB_MAXENDPOINTS]; + } interfaces[USB_MAXINTERFACES]; +}; + +struct darwin_transfer_priv { + /* Isoc */ + IOUSBIsocFrame *isoc_framelist; + int num_iso_packets; + + /* Control */ + IOUSBDevRequestTO req; + + /* Bulk */ + + /* Completion status */ + IOReturn result; + UInt32 size; +}; + +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_pollfs.cpp b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_pollfs.cpp new file mode 100644 index 00000000..e0c77132 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_pollfs.cpp @@ -0,0 +1,367 @@ +/* + * Copyright 2007-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Lotz + */ + +#include "haiku_usb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class WatchedEntry { +public: + WatchedEntry(BMessenger *, entry_ref *); + ~WatchedEntry(); + bool EntryCreated(entry_ref *ref); + bool EntryRemoved(ino_t node); + bool InitCheck(); + +private: + BMessenger* fMessenger; + node_ref fNode; + bool fIsDirectory; + USBDevice* fDevice; + WatchedEntry* fEntries; + WatchedEntry* fLink; + bool fInitCheck; +}; + + +class RosterLooper : public BLooper { +public: + RosterLooper(USBRoster *); + void Stop(); + virtual void MessageReceived(BMessage *); + bool InitCheck(); + +private: + USBRoster* fRoster; + WatchedEntry* fRoot; + BMessenger* fMessenger; + bool fInitCheck; +}; + + +WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref) + : fMessenger(messenger), + fIsDirectory(false), + fDevice(NULL), + fEntries(NULL), + fLink(NULL), + fInitCheck(false) +{ + BEntry entry(ref); + entry.GetNodeRef(&fNode); + + BDirectory directory; + if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) { + fIsDirectory = true; + + while (directory.GetNextEntry(&entry) >= B_OK) { + if (entry.GetRef(ref) < B_OK) + continue; + + WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref); + if (child == NULL) + continue; + if (child->InitCheck() == false) { + delete child; + continue; + } + + child->fLink = fEntries; + fEntries = child; + } + + watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger); + } + else { + if (strncmp(ref->name, "raw", 3) == 0) + return; + + BPath path, parent_path; + entry.GetPath(&path); + fDevice = new(std::nothrow) USBDevice(path.Path()); + if (fDevice != NULL && fDevice->InitCheck() == true) { + // Add this new device to each active context's device list + struct libusb_context *ctx; + unsigned long session_id = (unsigned long)&fDevice; + + usbi_mutex_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + usbi_dbg("using previously allocated device with location %lu", session_id); + libusb_unref_device(dev); + continue; + } + usbi_dbg("allocating new device with location %lu", session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) { + usbi_dbg("device allocation failed"); + continue; + } + *((USBDevice **)dev->os_priv) = fDevice; + + // Calculate pseudo-device-address + int addr, tmp; + if (strcmp(path.Leaf(), "hub") == 0) + tmp = 100; //Random Number + else + sscanf(path.Leaf(), "%d", &tmp); + addr = tmp + 1; + path.GetParent(&parent_path); + while (strcmp(parent_path.Leaf(), "usb") != 0) { + sscanf(parent_path.Leaf(), "%d", &tmp); + addr += tmp + 1; + parent_path.GetParent(&parent_path); + } + sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number); + dev->device_address = addr - (dev->bus_number + 1); + + if (usbi_sanitize_device(dev) < 0) { + usbi_dbg("device sanitization failed"); + libusb_unref_device(dev); + continue; + } + usbi_connect_device(dev); + } + usbi_mutex_unlock(&active_contexts_lock); + } + else if (fDevice) { + delete fDevice; + fDevice = NULL; + return; + } + } + fInitCheck = true; +} + + +WatchedEntry::~WatchedEntry() +{ + if (fIsDirectory) { + watch_node(&fNode, B_STOP_WATCHING, *fMessenger); + + WatchedEntry *child = fEntries; + while (child) { + WatchedEntry *next = child->fLink; + delete child; + child = next; + } + } + + if (fDevice) { + // Remove this device from each active context's device list + struct libusb_context *ctx; + struct libusb_device *dev; + unsigned long session_id = (unsigned long)&fDevice; + + usbi_mutex_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev != NULL) { + usbi_disconnect_device(dev); + libusb_unref_device(dev); + } else { + usbi_dbg("device with location %lu not found", session_id); + } + } + usbi_mutex_static_unlock(&active_contexts_lock); + delete fDevice; + } +} + + +bool +WatchedEntry::EntryCreated(entry_ref *ref) +{ + if (!fIsDirectory) + return false; + + if (ref->directory != fNode.node) { + WatchedEntry *child = fEntries; + while (child) { + if (child->EntryCreated(ref)) + return true; + child = child->fLink; + } + return false; + } + + WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref); + if (child == NULL) + return false; + child->fLink = fEntries; + fEntries = child; + return true; +} + + +bool +WatchedEntry::EntryRemoved(ino_t node) +{ + if (!fIsDirectory) + return false; + + WatchedEntry *child = fEntries; + WatchedEntry *lastChild = NULL; + while (child) { + if (child->fNode.node == node) { + if (lastChild) + lastChild->fLink = child->fLink; + else + fEntries = child->fLink; + delete child; + return true; + } + + if (child->EntryRemoved(node)) + return true; + + lastChild = child; + child = child->fLink; + } + return false; +} + + +bool +WatchedEntry::InitCheck() +{ + return fInitCheck; +} + + +RosterLooper::RosterLooper(USBRoster *roster) + : BLooper("LibusbRoster Looper"), + fRoster(roster), + fRoot(NULL), + fMessenger(NULL), + fInitCheck(false) +{ + BEntry entry("/dev/bus/usb"); + if (!entry.Exists()) { + usbi_err(NULL, "usb_raw not published"); + return; + } + + Run(); + fMessenger = new(std::nothrow) BMessenger(this); + if (fMessenger == NULL) { + usbi_err(NULL, "error creating BMessenger object"); + return; + } + + if (Lock()) { + entry_ref ref; + entry.GetRef(&ref); + fRoot = new(std::nothrow) WatchedEntry(fMessenger, &ref); + Unlock(); + if (fRoot == NULL) + return; + if (fRoot->InitCheck() == false) { + delete fRoot; + fRoot = NULL; + return; + } + } + fInitCheck = true; +} + + +void +RosterLooper::Stop() +{ + Lock(); + delete fRoot; + delete fMessenger; + Quit(); +} + + +void +RosterLooper::MessageReceived(BMessage *message) +{ + int32 opcode; + if (message->FindInt32("opcode", &opcode) < B_OK) + return; + + switch (opcode) { + case B_ENTRY_CREATED: + { + dev_t device; + ino_t directory; + const char *name; + if (message->FindInt32("device", &device) < B_OK || + message->FindInt64("directory", &directory) < B_OK || + message->FindString("name", &name) < B_OK) + break; + + entry_ref ref(device, directory, name); + fRoot->EntryCreated(&ref); + break; + } + case B_ENTRY_REMOVED: + { + ino_t node; + if (message->FindInt64("node", &node) < B_OK) + break; + fRoot->EntryRemoved(node); + break; + } + } +} + + +bool +RosterLooper::InitCheck() +{ + return fInitCheck; +} + + +USBRoster::USBRoster() + : fLooper(NULL) +{ +} + + +USBRoster::~USBRoster() +{ + Stop(); +} + + +int +USBRoster::Start() +{ + if (fLooper == NULL) { + fLooper = new(std::nothrow) RosterLooper(this); + if (fLooper == NULL || ((RosterLooper *)fLooper)->InitCheck() == false) { + if (fLooper) + fLooper = NULL; + return LIBUSB_ERROR_OTHER; + } + } + return LIBUSB_SUCCESS; +} + + +void +USBRoster::Stop() +{ + if (fLooper) { + ((RosterLooper *)fLooper)->Stop(); + fLooper = NULL; + } +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb.h new file mode 100644 index 00000000..d51ae9ea --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb.h @@ -0,0 +1,112 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "libusbi.h" +#include "haiku_usb_raw.h" + +using namespace std; + +class USBDevice; +class USBDeviceHandle; +class USBTransfer; + +class USBDevice { +public: + USBDevice(const char *); + virtual ~USBDevice(); + const char* Location() const; + uint8 CountConfigurations() const; + const usb_device_descriptor* Descriptor() const; + const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const; + const usb_configuration_descriptor* ActiveConfiguration() const; + uint8 EndpointToIndex(uint8) const; + uint8 EndpointToInterface(uint8) const; + int ClaimInterface(int); + int ReleaseInterface(int); + int CheckInterfacesFree(int); + int SetActiveConfiguration(int); + int ActiveConfigurationIndex() const; + bool InitCheck(); +private: + int Initialise(); + unsigned int fClaimedInterfaces; // Max Interfaces can be 32. Using a bitmask + usb_device_descriptor fDeviceDescriptor; + unsigned char** fConfigurationDescriptors; + int fActiveConfiguration; + char* fPath; + map fConfigToIndex; + map* fEndpointToIndex; + map* fEndpointToInterface; + bool fInitCheck; +}; + +class USBDeviceHandle { +public: + USBDeviceHandle(USBDevice *dev); + virtual ~USBDeviceHandle(); + int ClaimInterface(int); + int ReleaseInterface(int); + int SetConfiguration(int); + int SetAltSetting(int, int); + status_t SubmitTransfer(struct usbi_transfer *); + status_t CancelTransfer(USBTransfer *); + bool InitCheck(); +private: + int fRawFD; + static status_t TransfersThread(void *); + void TransfersWorker(); + USBDevice* fUSBDevice; + unsigned int fClaimedInterfaces; + BList fTransfers; + BLocker fTransfersLock; + sem_id fTransfersSem; + thread_id fTransfersThread; + bool fInitCheck; +}; + +class USBTransfer { +public: + USBTransfer(struct usbi_transfer *, USBDevice *); + virtual ~USBTransfer(); + void Do(int); + struct usbi_transfer* UsbiTransfer(); + void SetCancelled(); + bool IsCancelled(); +private: + struct usbi_transfer* fUsbiTransfer; + struct libusb_transfer* fLibusbTransfer; + USBDevice* fUSBDevice; + BLocker fStatusLock; + bool fCancelled; +}; + +class USBRoster { +public: + USBRoster(); + virtual ~USBRoster(); + int Start(); + void Stop(); +private: + void* fLooper; +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_backend.cpp b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_backend.cpp new file mode 100644 index 00000000..d3de8cc0 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_backend.cpp @@ -0,0 +1,517 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include +#include + +#include "haiku_usb.h" + +int _errno_to_libusb(int status) +{ + return status; +} + +USBTransfer::USBTransfer(struct usbi_transfer *itransfer, USBDevice *device) +{ + fUsbiTransfer = itransfer; + fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + fUSBDevice = device; + fCancelled = false; +} + +USBTransfer::~USBTransfer() +{ +} + +struct usbi_transfer * +USBTransfer::UsbiTransfer() +{ + return fUsbiTransfer; +} + +void +USBTransfer::SetCancelled() +{ + fCancelled = true; +} + +bool +USBTransfer::IsCancelled() +{ + return fCancelled; +} + +void +USBTransfer::Do(int fRawFD) +{ + switch (fLibusbTransfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + { + struct libusb_control_setup *setup = (struct libusb_control_setup *)fLibusbTransfer->buffer; + usb_raw_command command; + command.control.request_type = setup->bmRequestType; + command.control.request = setup->bRequest; + command.control.value = setup->wValue; + command.control.index = setup->wIndex; + command.control.length = setup->wLength; + command.control.data = fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + if (fCancelled) + break; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) || + command.control.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed control transfer"); + break; + } + fUsbiTransfer->transferred = command.control.length; + } + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + { + usb_raw_command command; + command.transfer.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint); + command.transfer.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint); + command.transfer.data = fLibusbTransfer->buffer; + command.transfer.length = fLibusbTransfer->length; + if (fCancelled) + break; + if (fLibusbTransfer->type == LIBUSB_TRANSFER_TYPE_BULK) { + if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command, sizeof(command)) || + command.transfer.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed bulk transfer"); + break; + } + } + else { + if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command, sizeof(command)) || + command.transfer.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed interrupt transfer"); + break; + } + } + fUsbiTransfer->transferred = command.transfer.length; + } + break; + // IsochronousTransfers not tested + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + { + usb_raw_command command; + command.isochronous.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint); + command.isochronous.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint); + command.isochronous.data = fLibusbTransfer->buffer; + command.isochronous.length = fLibusbTransfer->length; + command.isochronous.packet_count = fLibusbTransfer->num_iso_packets; + int i; + usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets]; + for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) { + if ((int16)(fLibusbTransfer->iso_packet_desc[i]).length != (fLibusbTransfer->iso_packet_desc[i]).length) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer"); + break; + } + packetDescriptors[i].request_length = (int16)(fLibusbTransfer->iso_packet_desc[i]).length; + } + if (i < fLibusbTransfer->num_iso_packets) + break; // TODO Handle this error + command.isochronous.packet_descriptors = packetDescriptors; + if (fCancelled) + break; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command, sizeof(command)) || + command.isochronous.status != B_USB_RAW_STATUS_SUCCESS) { + fUsbiTransfer->transferred = -1; + usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer"); + break; + } + for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) { + (fLibusbTransfer->iso_packet_desc[i]).actual_length = packetDescriptors[i].actual_length; + switch (packetDescriptors[i].status) { + case B_OK: + (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_COMPLETED; + break; + default: + (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_ERROR; + break; + } + } + delete[] packetDescriptors; + // Do we put the length of transfer here, for isochronous transfers? + fUsbiTransfer->transferred = command.transfer.length; + } + break; + default: + usbi_err(TRANSFER_CTX(fLibusbTransfer), "Unknown type of transfer"); + } +} + +bool +USBDeviceHandle::InitCheck() +{ + return fInitCheck; +} + +status_t +USBDeviceHandle::TransfersThread(void *self) +{ + USBDeviceHandle *handle = (USBDeviceHandle *)self; + handle->TransfersWorker(); + return B_OK; +} + +void +USBDeviceHandle::TransfersWorker() +{ + while (true) { + status_t status = acquire_sem(fTransfersSem); + if (status == B_BAD_SEM_ID) + break; + if (status == B_INTERRUPTED) + continue; + fTransfersLock.Lock(); + USBTransfer *fPendingTransfer = (USBTransfer *) fTransfers.RemoveItem((int32)0); + fTransfersLock.Unlock(); + fPendingTransfer->Do(fRawFD); + usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer()); + } +} + +status_t +USBDeviceHandle::SubmitTransfer(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = new USBTransfer(itransfer, fUSBDevice); + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = transfer; + BAutolock locker(fTransfersLock); + fTransfers.AddItem(transfer); + release_sem(fTransfersSem); + return LIBUSB_SUCCESS; +} + +status_t +USBDeviceHandle::CancelTransfer(USBTransfer *transfer) +{ + transfer->SetCancelled(); + fTransfersLock.Lock(); + bool removed = fTransfers.RemoveItem(transfer); + fTransfersLock.Unlock(); + if(removed) + usbi_signal_transfer_completion(transfer->UsbiTransfer()); + return LIBUSB_SUCCESS; +} + +USBDeviceHandle::USBDeviceHandle(USBDevice *dev) + : + fTransfersThread(-1), + fUSBDevice(dev), + fClaimedInterfaces(0), + fInitCheck(false) +{ + fRawFD = open(dev->Location(), O_RDWR | O_CLOEXEC); + if (fRawFD < 0) { + usbi_err(NULL,"failed to open device"); + return; + } + fTransfersSem = create_sem(0, "Transfers Queue Sem"); + fTransfersThread = spawn_thread(TransfersThread, "Transfer Worker", B_NORMAL_PRIORITY, this); + resume_thread(fTransfersThread); + fInitCheck = true; +} + +USBDeviceHandle::~USBDeviceHandle() +{ + if (fRawFD > 0) + close(fRawFD); + for(int i = 0; i < 32; i++) { + if (fClaimedInterfaces & (1 << i)) + ReleaseInterface(i); + } + delete_sem(fTransfersSem); + if (fTransfersThread > 0) + wait_for_thread(fTransfersThread, NULL); +} + +int +USBDeviceHandle::ClaimInterface(int inumber) +{ + int status = fUSBDevice->ClaimInterface(inumber); + if (status == LIBUSB_SUCCESS) + fClaimedInterfaces |= (1 << inumber); + return status; +} + +int +USBDeviceHandle::ReleaseInterface(int inumber) +{ + fUSBDevice->ReleaseInterface(inumber); + fClaimedInterfaces &= ~(1 << inumber); + return LIBUSB_SUCCESS; +} + +int +USBDeviceHandle::SetConfiguration(int config) +{ + int config_index = fUSBDevice->CheckInterfacesFree(config); + if(config_index == LIBUSB_ERROR_BUSY || config_index == LIBUSB_ERROR_NOT_FOUND) + return config_index; + usb_raw_command command; + command.config.config_index = config_index; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_CONFIGURATION, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + return _errno_to_libusb(command.config.status); + } + fUSBDevice->SetActiveConfiguration(config_index); + return LIBUSB_SUCCESS; +} + +int +USBDeviceHandle::SetAltSetting(int inumber, int alt) +{ + usb_raw_command command; + command.alternate.config_index = fUSBDevice->ActiveConfigurationIndex(); + command.alternate.interface_index = inumber; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command, sizeof(command)) || + command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "Error retrieving active alternate interface"); + return _errno_to_libusb(command.alternate.status); + } + if (command.alternate.alternate_info == alt) { + usbi_dbg("Setting alternate interface successful"); + return LIBUSB_SUCCESS; + } + command.alternate.alternate_info = alt; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command)) || + command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY + usbi_err(NULL, "Error setting alternate interface"); + return _errno_to_libusb(command.alternate.status); + } + usbi_dbg("Setting alternate interface successful"); + return LIBUSB_SUCCESS; +} + + +USBDevice::USBDevice(const char *path) + : + fPath(NULL), + fActiveConfiguration(0), //0? + fConfigurationDescriptors(NULL), + fClaimedInterfaces(0), + fEndpointToIndex(NULL), + fEndpointToInterface(NULL), + fInitCheck(false) +{ + fPath=strdup(path); + Initialise(); +} + +USBDevice::~USBDevice() +{ + free(fPath); + if (fConfigurationDescriptors) { + for(int i = 0; i < fDeviceDescriptor.num_configurations; i++) { + if (fConfigurationDescriptors[i]) + delete fConfigurationDescriptors[i]; + } + delete[] fConfigurationDescriptors; + } + if (fEndpointToIndex) + delete[] fEndpointToIndex; + if (fEndpointToInterface) + delete[] fEndpointToInterface; +} + +bool +USBDevice::InitCheck() +{ + return fInitCheck; +} + +const char * +USBDevice::Location() const +{ + return fPath; +} + +uint8 +USBDevice::CountConfigurations() const +{ + return fDeviceDescriptor.num_configurations; +} + +const usb_device_descriptor * +USBDevice::Descriptor() const +{ + return &fDeviceDescriptor; +} + +const usb_configuration_descriptor * +USBDevice::ConfigurationDescriptor(uint32 index) const +{ + if (index > CountConfigurations()) + return NULL; + return (usb_configuration_descriptor *) fConfigurationDescriptors[index]; +} + +const usb_configuration_descriptor * +USBDevice::ActiveConfiguration() const +{ + return (usb_configuration_descriptor *) fConfigurationDescriptors[fActiveConfiguration]; +} + +int +USBDevice::ActiveConfigurationIndex() const +{ + return fActiveConfiguration; +} + +int USBDevice::ClaimInterface(int interface) +{ + if (interface > ActiveConfiguration()->number_interfaces) + return LIBUSB_ERROR_NOT_FOUND; + if (fClaimedInterfaces & (1 << interface)) + return LIBUSB_ERROR_BUSY; + fClaimedInterfaces |= (1 << interface); + return LIBUSB_SUCCESS; +} + +int USBDevice::ReleaseInterface(int interface) +{ + fClaimedInterfaces &= ~(1 << interface); + return LIBUSB_SUCCESS; +} + +int +USBDevice::CheckInterfacesFree(int config) +{ + if (fConfigToIndex.count(config) == 0) + return LIBUSB_ERROR_NOT_FOUND; + if (fClaimedInterfaces == 0) + return fConfigToIndex[(uint8)config]; + return LIBUSB_ERROR_BUSY; +} + +int +USBDevice::SetActiveConfiguration(int config_index) +{ + fActiveConfiguration = config_index; + return LIBUSB_SUCCESS; +} + +uint8 +USBDevice::EndpointToIndex(uint8 address) const +{ + return fEndpointToIndex[fActiveConfiguration][address]; +} + +uint8 +USBDevice::EndpointToInterface(uint8 address) const +{ + return fEndpointToInterface[fActiveConfiguration][address]; +} + +int +USBDevice::Initialise() //Do we need more error checking, etc? How to report? +{ + int fRawFD = open(fPath, O_RDWR | O_CLOEXEC); + if (fRawFD < 0) + return B_ERROR; + usb_raw_command command; + command.device.descriptor = &fDeviceDescriptor; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command, sizeof(command)) || + command.device.status != B_USB_RAW_STATUS_SUCCESS) { + close(fRawFD); + return B_ERROR; + } + + fConfigurationDescriptors = new(std::nothrow) unsigned char *[fDeviceDescriptor.num_configurations]; + fEndpointToIndex = new(std::nothrow) map [fDeviceDescriptor.num_configurations]; + fEndpointToInterface = new(std::nothrow) map [fDeviceDescriptor.num_configurations]; + for (int i = 0; i < fDeviceDescriptor.num_configurations; i++) { + usb_configuration_descriptor tmp_config; + command.config.descriptor = &tmp_config; + command.config.config_index = i; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving configuration descriptor"); + close(fRawFD); + return B_ERROR; + } + fConfigToIndex[tmp_config.configuration_value] = i; + fConfigurationDescriptors[i] = new(std::nothrow) unsigned char[tmp_config.total_length]; + command.control.request_type = 128; + command.control.request = 6; + command.control.value = (2 << 8) | i; + command.control.index = 0; + command.control.length = tmp_config.total_length; + command.control.data = fConfigurationDescriptors[i]; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) || + command.control.status!=B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving full configuration descriptor"); + close(fRawFD); + return B_ERROR; + } + for (int j = 0; j < tmp_config.number_interfaces; j++) { + command.alternate.config_index = i; + command.alternate.interface_index = j; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving number of alternate interfaces"); + close(fRawFD); + return B_ERROR; + } + int num_alternate = command.alternate.alternate_info; + for (int k = 0; k < num_alternate; k++) { + usb_interface_descriptor tmp_interface; + command.interface_etc.config_index = i; + command.interface_etc.interface_index = j; + command.interface_etc.alternate_index = k; + command.interface_etc.descriptor = &tmp_interface; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving interface descriptor"); + close(fRawFD); + return B_ERROR; + } + for (int l = 0; l < tmp_interface.num_endpoints; l++) { + usb_endpoint_descriptor tmp_endpoint; + command.endpoint_etc.config_index = i; + command.endpoint_etc.interface_index = j; + command.endpoint_etc.alternate_index = k; + command.endpoint_etc.endpoint_index = l; + command.endpoint_etc.descriptor = &tmp_endpoint; + if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command, sizeof(command)) || + command.config.status != B_USB_RAW_STATUS_SUCCESS) { + usbi_err(NULL, "failed retrieving endpoint descriptor"); + close(fRawFD); + return B_ERROR; + } + fEndpointToIndex[i][tmp_endpoint.endpoint_address] = l; + fEndpointToInterface[i][tmp_endpoint.endpoint_address] = j; + } + } + } + } + close(fRawFD); + fInitCheck = true; + return B_OK; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.cpp b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.cpp new file mode 100644 index 00000000..c701e344 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.cpp @@ -0,0 +1,253 @@ +/* + * Haiku Backend for libusb + * Copyright © 2014 Akshay Jaggi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include +#include + +#include "haiku_usb.h" + +USBRoster gUsbRoster; +int32 gInitCount = 0; + +static int +haiku_init(struct libusb_context *ctx) +{ + if (atomic_add(&gInitCount, 1) == 0) + return gUsbRoster.Start(); + return LIBUSB_SUCCESS; +} + +static void +haiku_exit(struct libusb_context *ctx) +{ + UNUSED(ctx); + if (atomic_add(&gInitCount, -1) == 1) + gUsbRoster.Stop(); +} + +static int +haiku_open(struct libusb_device_handle *dev_handle) +{ + USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv); + USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev); + if (handle == NULL) + return LIBUSB_ERROR_NO_MEM; + if (handle->InitCheck() == false) { + delete handle; + return LIBUSB_ERROR_NO_DEVICE; + } + *((USBDeviceHandle **)dev_handle->os_priv) = handle; + return LIBUSB_SUCCESS; +} + +static void +haiku_close(struct libusb_device_handle *dev_handle) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + if (handle == NULL) + return; + delete handle; + *((USBDeviceHandle **)dev_handle->os_priv) = NULL; +} + +static int +haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH); + *host_endian = 0; + return LIBUSB_SUCCESS; +} + +static int +haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + const usb_configuration_descriptor *act_config = dev->ActiveConfiguration(); + if (len > act_config->total_length) + return LIBUSB_ERROR_OVERFLOW; + memcpy(buffer, act_config, len); + *host_endian = 0; + return LIBUSB_SUCCESS; +} + +static int +haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + USBDevice *dev = *((USBDevice **)device->os_priv); + const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index); + if (config == NULL) { + usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor"); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (len > config->total_length) + len = config->total_length; + memcpy(buffer, config, len); + *host_endian = 0; + return len; +} + +static int +haiku_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv); + return handle->SetConfiguration(config); +} + +static int +haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + return handle->ClaimInterface(interface_number); +} + +static int +haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + return handle->SetAltSetting(interface_number, altsetting); +} + +static int +haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv); + haiku_set_altsetting(dev_handle,interface_number, 0); + return handle->ReleaseInterface(interface_number); +} + +static int +haiku_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv); + return fDeviceHandle->SubmitTransfer(itransfer); +} + +static int +haiku_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv); + return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer))); +} + +static void +haiku_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)); + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; +} + +static int +haiku_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)); + + usbi_mutex_lock(&itransfer->lock); + if (transfer->IsCancelled()) { + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; + usbi_mutex_unlock(&itransfer->lock); + if (itransfer->transferred < 0) + itransfer->transferred = 0; + return usbi_handle_transfer_cancellation(itransfer); + } + libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; + if (itransfer->transferred < 0) { + usbi_err(ITRANSFER_CTX(itransfer), "error in transfer"); + status = LIBUSB_TRANSFER_ERROR; + itransfer->transferred = 0; + } + delete transfer; + *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); +} + +static int +haiku_clock_gettime(int clkid, struct timespec *tp) +{ + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + return LIBUSB_ERROR_INVALID_PARAM; +} + +const struct usbi_os_backend usbi_backend = { + /*.name =*/ "Haiku usbfs", + /*.caps =*/ 0, + /*.init =*/ haiku_init, + /*.exit =*/ haiku_exit, + /*.set_option =*/ NULL, + /*.get_device_list =*/ NULL, + /*.hotplug_poll =*/ NULL, + /*.open =*/ haiku_open, + /*.close =*/ haiku_close, + /*.get_device_descriptor =*/ haiku_get_device_descriptor, + /*.get_active_config_descriptor =*/ haiku_get_active_config_descriptor, + /*.get_config_descriptor =*/ haiku_get_config_descriptor, + /*.get_config_descriptor_by_value =*/ NULL, + + + /*.get_configuration =*/ NULL, + /*.set_configuration =*/ haiku_set_configuration, + /*.claim_interface =*/ haiku_claim_interface, + /*.release_interface =*/ haiku_release_interface, + + /*.set_interface_altsetting =*/ haiku_set_altsetting, + /*.clear_halt =*/ NULL, + /*.reset_device =*/ NULL, + + /*.alloc_streams =*/ NULL, + /*.free_streams =*/ NULL, + + /*.dev_mem_alloc =*/ NULL, + /*.dev_mem_free =*/ NULL, + + /*.kernel_driver_active =*/ NULL, + /*.detach_kernel_driver =*/ NULL, + /*.attach_kernel_driver =*/ NULL, + + /*.destroy_device =*/ NULL, + + /*.submit_transfer =*/ haiku_submit_transfer, + /*.cancel_transfer =*/ haiku_cancel_transfer, + /*.clear_transfer_priv =*/ haiku_clear_transfer_priv, + + /*.handle_events =*/ NULL, + /*.handle_transfer_completion =*/ haiku_handle_transfer_completion, + + /*.clock_gettime =*/ haiku_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + /*.get_timerfd_clockid =*/ NULL, +#endif + + /*.context_priv_size=*/ 0, + /*.device_priv_size =*/ sizeof(USBDevice *), + /*.device_handle_priv_size =*/ sizeof(USBDeviceHandle *), + /*.transfer_priv_size =*/ sizeof(USBTransfer *), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.h new file mode 100644 index 00000000..5baf53d7 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/haiku_usb_raw.h @@ -0,0 +1,180 @@ +/* + * Copyright 2006-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#ifndef _USB_RAW_H_ +#define _USB_RAW_H_ + +#include + +#define B_USB_RAW_PROTOCOL_VERSION 0x0015 +#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff + +typedef enum { + B_USB_RAW_COMMAND_GET_VERSION = 0x1000, + + B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR = 0x2000, + B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR, + B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, + B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, + B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, + B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, + B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC, + + B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000, + B_USB_RAW_COMMAND_SET_FEATURE, + B_USB_RAW_COMMAND_CLEAR_FEATURE, + B_USB_RAW_COMMAND_GET_STATUS, + B_USB_RAW_COMMAND_GET_DESCRIPTOR, + B_USB_RAW_COMMAND_SET_ALT_INTERFACE, + + B_USB_RAW_COMMAND_CONTROL_TRANSFER = 0x4000, + B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, + B_USB_RAW_COMMAND_BULK_TRANSFER, + B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER +} usb_raw_command_id; + + +typedef enum { + B_USB_RAW_STATUS_SUCCESS = 0, + + B_USB_RAW_STATUS_FAILED, + B_USB_RAW_STATUS_ABORTED, + B_USB_RAW_STATUS_STALLED, + B_USB_RAW_STATUS_CRC_ERROR, + B_USB_RAW_STATUS_TIMEOUT, + + B_USB_RAW_STATUS_INVALID_CONFIGURATION, + B_USB_RAW_STATUS_INVALID_INTERFACE, + B_USB_RAW_STATUS_INVALID_ENDPOINT, + B_USB_RAW_STATUS_INVALID_STRING, + + B_USB_RAW_STATUS_NO_MEMORY +} usb_raw_command_status; + + +typedef union { + struct { + status_t status; + } version; + + struct { + status_t status; + usb_device_descriptor *descriptor; + } device; + + struct { + status_t status; + usb_configuration_descriptor *descriptor; + uint32 config_index; + } config; + + struct { + status_t status; + uint32 alternate_info; + uint32 config_index; + uint32 interface_index; + } alternate; + + struct { + status_t status; + usb_interface_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + } interface; + + struct { + status_t status; + usb_interface_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + } interface_etc; + + struct { + status_t status; + usb_endpoint_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 endpoint_index; + } endpoint; + + struct { + status_t status; + usb_endpoint_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + uint32 endpoint_index; + } endpoint_etc; + + struct { + status_t status; + usb_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 generic_index; + size_t length; + } generic; + + struct { + status_t status; + usb_descriptor *descriptor; + uint32 config_index; + uint32 interface_index; + uint32 alternate_index; + uint32 generic_index; + size_t length; + } generic_etc; + + struct { + status_t status; + usb_string_descriptor *descriptor; + uint32 string_index; + size_t length; + } string; + + struct { + status_t status; + uint8 type; + uint8 index; + uint16 language_id; + void *data; + size_t length; + } descriptor; + + struct { + status_t status; + uint8 request_type; + uint8 request; + uint16 value; + uint16 index; + uint16 length; + void *data; + } control; + + struct { + status_t status; + uint32 interface; + uint32 endpoint; + void *data; + size_t length; + } transfer; + + struct { + status_t status; + uint32 interface; + uint32 endpoint; + void *data; + size_t length; + usb_iso_packet_descriptor *packet_descriptors; + uint32 packet_count; + } isochronous; +} usb_raw_command; + +#endif // _USB_RAW_H_ diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_netlink.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_netlink.c new file mode 100644 index 00000000..c1ad1ec5 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_netlink.c @@ -0,0 +1,409 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright (C) 2007-2009 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * Copyright (c) 2013 Nathan Hjelm + * Copyright (c) 2016 Chris Dickens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +#define NL_GROUP_KERNEL 1 + +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif + +#ifndef SOCK_NONBLOCK +#define SOCK_NONBLOCK 0 +#endif + +static int linux_netlink_socket = -1; +static int netlink_control_pipe[2] = { -1, -1 }; +static pthread_t libusb_linux_event_thread; + +static void *linux_netlink_event_thread_main(void *arg); + +static int set_fd_cloexec_nb(int fd, int socktype) +{ + int flags; + +#if defined(FD_CLOEXEC) + /* Make sure the netlink socket file descriptor is marked as CLOEXEC */ + if (!(socktype & SOCK_CLOEXEC)) { + flags = fcntl(fd, F_GETFD); + if (flags == -1) { + usbi_err(NULL, "failed to get netlink fd flags (%d)", errno); + return -1; + } + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + usbi_err(NULL, "failed to set netlink fd flags (%d)", errno); + return -1; + } + } +#endif + + /* Make sure the netlink socket is non-blocking */ + if (!(socktype & SOCK_NONBLOCK)) { + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + usbi_err(NULL, "failed to get netlink fd status flags (%d)", errno); + return -1; + } + + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + usbi_err(NULL, "failed to set netlink fd status flags (%d)", errno); + return -1; + } + } + + return 0; +} + +int linux_netlink_start_event_monitor(void) +{ + struct sockaddr_nl sa_nl = { .nl_family = AF_NETLINK, .nl_groups = NL_GROUP_KERNEL }; + int socktype = SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC; + int opt = 1; + int ret; + + linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); + if (linux_netlink_socket == -1 && errno == EINVAL) { + usbi_dbg("failed to create netlink socket of type %d, attempting SOCK_RAW", socktype); + socktype = SOCK_RAW; + linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); + } + + if (linux_netlink_socket == -1) { + usbi_err(NULL, "failed to create netlink socket (%d)", errno); + goto err; + } + + ret = set_fd_cloexec_nb(linux_netlink_socket, socktype); + if (ret == -1) + goto err_close_socket; + + ret = bind(linux_netlink_socket, (struct sockaddr *)&sa_nl, sizeof(sa_nl)); + if (ret == -1) { + usbi_err(NULL, "failed to bind netlink socket (%d)", errno); + goto err_close_socket; + } + + ret = setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)); + if (ret == -1) { + usbi_err(NULL, "failed to set netlink socket SO_PASSCRED option (%d)", errno); + goto err_close_socket; + } + + ret = usbi_pipe(netlink_control_pipe); + if (ret) { + usbi_err(NULL, "failed to create netlink control pipe"); + goto err_close_socket; + } + + ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL); + if (ret != 0) { + usbi_err(NULL, "failed to create netlink event thread (%d)", ret); + goto err_close_pipe; + } + + return LIBUSB_SUCCESS; + +err_close_pipe: + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + netlink_control_pipe[0] = -1; + netlink_control_pipe[1] = -1; +err_close_socket: + close(linux_netlink_socket); + linux_netlink_socket = -1; +err: + return LIBUSB_ERROR_OTHER; +} + +int linux_netlink_stop_event_monitor(void) +{ + char dummy = 1; + ssize_t r; + + assert(linux_netlink_socket != -1); + + /* Write some dummy data to the control pipe and + * wait for the thread to exit */ + r = write(netlink_control_pipe[1], &dummy, sizeof(dummy)); + if (r <= 0) + usbi_warn(NULL, "netlink control pipe signal failed"); + + pthread_join(libusb_linux_event_thread, NULL); + + close(linux_netlink_socket); + linux_netlink_socket = -1; + + /* close and reset control pipe */ + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + netlink_control_pipe[0] = -1; + netlink_control_pipe[1] = -1; + + return LIBUSB_SUCCESS; +} + +static const char *netlink_message_parse(const char *buffer, size_t len, const char *key) +{ + const char *end = buffer + len; + size_t keylen = strlen(key); + + while (buffer < end && *buffer) { + if (strncmp(buffer, key, keylen) == 0 && buffer[keylen] == '=') + return buffer + keylen + 1; + buffer += strlen(buffer) + 1; + } + + return NULL; +} + +/* parse parts of netlink message common to both libudev and the kernel */ +static int linux_netlink_parse(const char *buffer, size_t len, int *detached, + const char **sys_name, uint8_t *busnum, uint8_t *devaddr) +{ + const char *tmp, *slash; + + errno = 0; + + *sys_name = NULL; + *detached = 0; + *busnum = 0; + *devaddr = 0; + + tmp = netlink_message_parse(buffer, len, "ACTION"); + if (!tmp) { + return -1; + } else if (strcmp(tmp, "remove") == 0) { + *detached = 1; + } else if (strcmp(tmp, "add") != 0) { + usbi_dbg("unknown device action %s", tmp); + return -1; + } + + /* check that this is a usb message */ + tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); + if (!tmp || strcmp(tmp, "usb") != 0) { + /* not usb. ignore */ + return -1; + } + + /* check that this is an actual usb device */ + tmp = netlink_message_parse(buffer, len, "DEVTYPE"); + if (!tmp || strcmp(tmp, "usb_device") != 0) { + /* not usb. ignore */ + return -1; + } + + tmp = netlink_message_parse(buffer, len, "BUSNUM"); + if (tmp) { + *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + tmp = netlink_message_parse(buffer, len, "DEVNUM"); + if (NULL == tmp) + return -1; + + *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + } else { + /* no bus number. try "DEVICE" */ + tmp = netlink_message_parse(buffer, len, "DEVICE"); + if (!tmp) { + /* not usb. ignore */ + return -1; + } + + /* Parse a device path such as /dev/bus/usb/003/004 */ + slash = strrchr(tmp, '/'); + if (!slash) + return -1; + + *busnum = (uint8_t)(strtoul(slash - 3, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + *devaddr = (uint8_t)(strtoul(slash + 1, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + return 0; + } + + tmp = netlink_message_parse(buffer, len, "DEVPATH"); + if (!tmp) + return -1; + + slash = strrchr(tmp, '/'); + if (slash) + *sys_name = slash + 1; + + /* found a usb device */ + return 0; +} + +static int linux_netlink_read_message(void) +{ + char cred_buffer[CMSG_SPACE(sizeof(struct ucred))]; + char msg_buffer[2048]; + const char *sys_name = NULL; + uint8_t busnum, devaddr; + int detached, r; + ssize_t len; + struct cmsghdr *cmsg; + struct ucred *cred; + struct sockaddr_nl sa_nl; + struct iovec iov = { .iov_base = msg_buffer, .iov_len = sizeof(msg_buffer) }; + struct msghdr msg = { + .msg_iov = &iov, .msg_iovlen = 1, + .msg_control = cred_buffer, .msg_controllen = sizeof(cred_buffer), + .msg_name = &sa_nl, .msg_namelen = sizeof(sa_nl) + }; + + /* read netlink message */ + len = recvmsg(linux_netlink_socket, &msg, 0); + if (len == -1) { + if (errno != EAGAIN && errno != EINTR) + usbi_err(NULL, "error receiving message from netlink (%d)", errno); + return -1; + } + + if (len < 32 || (msg.msg_flags & MSG_TRUNC)) { + usbi_err(NULL, "invalid netlink message length"); + return -1; + } + + if (sa_nl.nl_groups != NL_GROUP_KERNEL || sa_nl.nl_pid != 0) { + usbi_dbg("ignoring netlink message from unknown group/PID (%u/%u)", + (unsigned int)sa_nl.nl_groups, (unsigned int)sa_nl.nl_pid); + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) { + usbi_dbg("ignoring netlink message with no sender credentials"); + return -1; + } + + cred = (struct ucred *)CMSG_DATA(cmsg); + if (cred->uid != 0) { + usbi_dbg("ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid); + return -1; + } + + r = linux_netlink_parse(msg_buffer, (size_t)len, &detached, &sys_name, &busnum, &devaddr); + if (r) + return r; + + usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s", + busnum, devaddr, sys_name, detached ? "yes" : "no"); + + /* signal device is available (or not) to all contexts */ + if (detached) + linux_device_disconnected(busnum, devaddr); + else + linux_hotplug_enumerate(busnum, devaddr, sys_name); + + return 0; +} + +static void *linux_netlink_event_thread_main(void *arg) +{ + char dummy; + int r; + ssize_t nb; + struct pollfd fds[] = { + { .fd = netlink_control_pipe[0], + .events = POLLIN }, + { .fd = linux_netlink_socket, + .events = POLLIN }, + }; + + UNUSED(arg); + + usbi_dbg("netlink event thread entering"); + + while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) { + if (r < 0) { + /* temporary failure */ + continue; + } + if (fds[0].revents & POLLIN) { + /* activity on control pipe, read the byte and exit */ + nb = read(netlink_control_pipe[0], &dummy, sizeof(dummy)); + if (nb <= 0) + usbi_warn(NULL, "netlink control pipe read failed"); + break; + } + if (fds[1].revents & POLLIN) { + usbi_mutex_static_lock(&linux_hotplug_lock); + linux_netlink_read_message(); + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + } + + usbi_dbg("netlink event thread exiting"); + + return NULL; +} + +void linux_netlink_hotplug_poll(void) +{ + int r; + + usbi_mutex_static_lock(&linux_hotplug_lock); + do { + r = linux_netlink_read_message(); + } while (r == 0); + usbi_mutex_static_unlock(&linux_hotplug_lock); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_udev.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_udev.c new file mode 100644 index 00000000..c97806ba --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_udev.c @@ -0,0 +1,329 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright (C) 2007-2009 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * Copyright (c) 2012-2013 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +/* udev context */ +static struct udev *udev_ctx = NULL; +static int udev_monitor_fd = -1; +static int udev_control_pipe[2] = {-1, -1}; +static struct udev_monitor *udev_monitor = NULL; +static pthread_t linux_event_thread; + +static void udev_hotplug_event(struct udev_device* udev_dev); +static void *linux_udev_event_thread_main(void *arg); + +int linux_udev_start_event_monitor(void) +{ + int r; + + assert(udev_ctx == NULL); + udev_ctx = udev_new(); + if (!udev_ctx) { + usbi_err(NULL, "could not create udev context"); + goto err; + } + + udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev"); + if (!udev_monitor) { + usbi_err(NULL, "could not initialize udev monitor"); + goto err_free_ctx; + } + + r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device"); + if (r) { + usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem"); + goto err_free_monitor; + } + + if (udev_monitor_enable_receiving(udev_monitor)) { + usbi_err(NULL, "failed to enable the udev monitor"); + goto err_free_monitor; + } + + udev_monitor_fd = udev_monitor_get_fd(udev_monitor); + +#if defined(FD_CLOEXEC) + /* Make sure the udev file descriptor is marked as CLOEXEC */ + r = fcntl(udev_monitor_fd, F_GETFD); + if (r == -1) { + usbi_err(NULL, "geting udev monitor fd flags (%d)", errno); + goto err_free_monitor; + } + if (!(r & FD_CLOEXEC)) { + if (fcntl(udev_monitor_fd, F_SETFD, r | FD_CLOEXEC) == -1) { + usbi_err(NULL, "setting udev monitor fd flags (%d)", errno); + goto err_free_monitor; + } + } +#endif + + /* Some older versions of udev are not non-blocking by default, + * so make sure this is set */ + r = fcntl(udev_monitor_fd, F_GETFL); + if (r == -1) { + usbi_err(NULL, "getting udev monitor fd status flags (%d)", errno); + goto err_free_monitor; + } + if (!(r & O_NONBLOCK)) { + if (fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK) == -1) { + usbi_err(NULL, "setting udev monitor fd status flags (%d)", errno); + goto err_free_monitor; + } + } + + r = usbi_pipe(udev_control_pipe); + if (r) { + usbi_err(NULL, "could not create udev control pipe"); + goto err_free_monitor; + } + + r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL); + if (r) { + usbi_err(NULL, "creating hotplug event thread (%d)", r); + goto err_close_pipe; + } + + return LIBUSB_SUCCESS; + +err_close_pipe: + close(udev_control_pipe[0]); + close(udev_control_pipe[1]); +err_free_monitor: + udev_monitor_unref(udev_monitor); + udev_monitor = NULL; + udev_monitor_fd = -1; +err_free_ctx: + udev_unref(udev_ctx); +err: + udev_ctx = NULL; + return LIBUSB_ERROR_OTHER; +} + +int linux_udev_stop_event_monitor(void) +{ + char dummy = 1; + int r; + + assert(udev_ctx != NULL); + assert(udev_monitor != NULL); + assert(udev_monitor_fd != -1); + + /* Write some dummy data to the control pipe and + * wait for the thread to exit */ + r = write(udev_control_pipe[1], &dummy, sizeof(dummy)); + if (r <= 0) { + usbi_warn(NULL, "udev control pipe signal failed"); + } + pthread_join(linux_event_thread, NULL); + + /* Release the udev monitor */ + udev_monitor_unref(udev_monitor); + udev_monitor = NULL; + udev_monitor_fd = -1; + + /* Clean up the udev context */ + udev_unref(udev_ctx); + udev_ctx = NULL; + + /* close and reset control pipe */ + close(udev_control_pipe[0]); + close(udev_control_pipe[1]); + udev_control_pipe[0] = -1; + udev_control_pipe[1] = -1; + + return LIBUSB_SUCCESS; +} + +static void *linux_udev_event_thread_main(void *arg) +{ + char dummy; + int r; + ssize_t nb; + struct udev_device* udev_dev; + struct pollfd fds[] = { + {.fd = udev_control_pipe[0], + .events = POLLIN}, + {.fd = udev_monitor_fd, + .events = POLLIN}, + }; + + usbi_dbg("udev event thread entering."); + + while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) { + if (r < 0) { + /* temporary failure */ + continue; + } + if (fds[0].revents & POLLIN) { + /* activity on control pipe, read the byte and exit */ + nb = read(udev_control_pipe[0], &dummy, sizeof(dummy)); + if (nb <= 0) { + usbi_warn(NULL, "udev control pipe read failed"); + } + break; + } + if (fds[1].revents & POLLIN) { + usbi_mutex_static_lock(&linux_hotplug_lock); + udev_dev = udev_monitor_receive_device(udev_monitor); + if (udev_dev) + udev_hotplug_event(udev_dev); + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + } + + usbi_dbg("udev event thread exiting"); + + return NULL; +} + +static int udev_device_info(struct libusb_context *ctx, int detached, + struct udev_device *udev_dev, uint8_t *busnum, + uint8_t *devaddr, const char **sys_name) { + const char *dev_node; + + dev_node = udev_device_get_devnode(udev_dev); + if (!dev_node) { + return LIBUSB_ERROR_OTHER; + } + + *sys_name = udev_device_get_sysname(udev_dev); + if (!*sys_name) { + return LIBUSB_ERROR_OTHER; + } + + return linux_get_device_address(ctx, detached, busnum, devaddr, + dev_node, *sys_name); +} + +static void udev_hotplug_event(struct udev_device* udev_dev) +{ + const char* udev_action; + const char* sys_name = NULL; + uint8_t busnum = 0, devaddr = 0; + int detached; + int r; + + do { + udev_action = udev_device_get_action(udev_dev); + if (!udev_action) { + break; + } + + detached = !strncmp(udev_action, "remove", 6); + + r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name); + if (LIBUSB_SUCCESS != r) { + break; + } + + usbi_dbg("udev hotplug event. action: %s.", udev_action); + + if (strncmp(udev_action, "add", 3) == 0) { + linux_hotplug_enumerate(busnum, devaddr, sys_name); + } else if (detached) { + linux_device_disconnected(busnum, devaddr); + } else { + usbi_err(NULL, "ignoring udev action %s", udev_action); + } + } while (0); + + udev_device_unref(udev_dev); +} + +int linux_udev_scan_devices(struct libusb_context *ctx) +{ + struct udev_enumerate *enumerator; + struct udev_list_entry *devices, *entry; + struct udev_device *udev_dev; + const char *sys_name; + int r; + + assert(udev_ctx != NULL); + + enumerator = udev_enumerate_new(udev_ctx); + if (NULL == enumerator) { + usbi_err(ctx, "error creating udev enumerator"); + return LIBUSB_ERROR_OTHER; + } + + udev_enumerate_add_match_subsystem(enumerator, "usb"); + udev_enumerate_add_match_property(enumerator, "DEVTYPE", "usb_device"); + udev_enumerate_scan_devices(enumerator); + devices = udev_enumerate_get_list_entry(enumerator); + + entry = NULL; + udev_list_entry_foreach(entry, devices) { + const char *path = udev_list_entry_get_name(entry); + uint8_t busnum = 0, devaddr = 0; + + udev_dev = udev_device_new_from_syspath(udev_ctx, path); + + r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name); + if (r) { + udev_device_unref(udev_dev); + continue; + } + + linux_enumerate_device(ctx, busnum, devaddr, sys_name); + udev_device_unref(udev_dev); + } + + udev_enumerate_unref(enumerator); + + return LIBUSB_SUCCESS; +} + +void linux_udev_hotplug_poll(void) +{ + struct udev_device* udev_dev; + + usbi_mutex_static_lock(&linux_hotplug_lock); + do { + udev_dev = udev_monitor_receive_device(udev_monitor); + if (udev_dev) { + usbi_dbg("Handling hotplug event from hotplug_poll"); + udev_hotplug_event(udev_dev); + } + } while (udev_dev); + usbi_mutex_static_unlock(&linux_hotplug_lock); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.c new file mode 100644 index 00000000..768e7d5a --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.c @@ -0,0 +1,2800 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2013 Nathan Hjelm + * Copyright © 2012-2013 Hans de Goede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +/* sysfs vs usbfs: + * opening a usbfs node causes the device to be resumed, so we attempt to + * avoid this during enumeration. + * + * sysfs allows us to read the kernel's in-memory copies of device descriptors + * and so forth, avoiding the need to open the device: + * - The binary "descriptors" file contains all config descriptors since + * 2.6.26, commit 217a9081d8e69026186067711131b77f0ce219ed + * - The binary "descriptors" file was added in 2.6.23, commit + * 69d42a78f935d19384d1f6e4f94b65bb162b36df, but it only contains the + * active config descriptors + * - The "busnum" file was added in 2.6.22, commit + * 83f7d958eab2fbc6b159ee92bf1493924e1d0f72 + * - The "devnum" file has been present since pre-2.6.18 + * - the "bConfigurationValue" file has been present since pre-2.6.18 + * + * If we have bConfigurationValue, busnum, and devnum, then we can determine + * the active configuration without having to open the usbfs node in RDWR mode. + * The busnum file is important as that is the only way we can relate sysfs + * devices to usbfs nodes. + * + * If we also have all descriptors, we can obtain the device descriptor and + * configuration without touching usbfs at all. + */ + +/* endianness for multi-byte fields: + * + * Descriptors exposed by usbfs have the multi-byte fields in the device + * descriptor as host endian. Multi-byte fields in the other descriptors are + * bus-endian. The kernel documentation says otherwise, but it is wrong. + * + * In sysfs all descriptors are bus-endian. + */ + +static const char *usbfs_path = NULL; + +/* use usbdev*.* device names in /dev instead of the usbfs bus directories */ +static int usbdev_names = 0; + +/* Linux has changed the maximum length of an individual isochronous packet + * over time. Initially this limit was 1,023 bytes, but Linux 2.6.18 + * (commit 3612242e527eb47ee4756b5350f8bdf791aa5ede) increased this value to + * 8,192 bytes to support higher bandwidth devices. Linux 3.10 + * (commit e2e2f0ea1c935edcf53feb4c4c8fdb4f86d57dd9) further increased this + * value to 49,152 bytes to support super speed devices. + */ +static unsigned int max_iso_packet_len = 0; + +/* Linux 2.6.23 adds support for O_CLOEXEC when opening files, which marks the + * close-on-exec flag in the underlying file descriptor. */ +static int supports_flag_cloexec = -1; + +/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically + * allows us to mark URBs as being part of a specific logical transfer when + * we submit them to the kernel. then, on any error except a cancellation, all + * URBs within that transfer will be cancelled and no more URBs will be + * accepted for the transfer, meaning that no more data can creep in. + * + * The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer + * (in either direction) except the first. + * For IN transfers, we must also set SHORT_NOT_OK on all URBs except the + * last; it means that the kernel should treat a short reply as an error. + * For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT + * transfers can't be short unless there's already some sort of error), and + * setting this flag is disallowed (a kernel with USB debugging enabled will + * reject such URBs). + */ +static int supports_flag_bulk_continuation = -1; + +/* Linux 2.6.31 fixes support for the zero length packet URB flag. This + * allows us to mark URBs that should be followed by a zero length data + * packet, which can be required by device- or class-specific protocols. + */ +static int supports_flag_zero_packet = -1; + +/* clock ID for monotonic clock, as not all clock sources are available on all + * systems. appropriate choice made at initialization time. */ +static clockid_t monotonic_clkid = -1; + +/* Linux 2.6.22 (commit 83f7d958eab2fbc6b159ee92bf1493924e1d0f72) adds a busnum + * to sysfs, so we can relate devices. This also implies that we can read + * the active configuration through bConfigurationValue */ +static int sysfs_can_relate_devices = -1; + +/* Linux 2.6.26 (commit 217a9081d8e69026186067711131b77f0ce219ed) adds all + * config descriptors (rather then just the active config) to the sysfs + * descriptors file, so from then on we can use them. */ +static int sysfs_has_descriptors = -1; + +/* how many times have we initted (and not exited) ? */ +static int init_count = 0; + +/* Serialize hotplug start/stop */ +static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; +/* Serialize scan-devices, event-thread, and poll */ +usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; + +static int linux_start_event_monitor(void); +static int linux_stop_event_monitor(void); +static int linux_scan_devices(struct libusb_context *ctx); +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname); +static int detach_kernel_driver_and_claim(struct libusb_device_handle *, int); + +#if !defined(USE_UDEV) +static int linux_default_scan_devices (struct libusb_context *ctx); +#endif + +struct kernel_version { + int major; + int minor; + int sublevel; +}; + +struct linux_device_priv { + char *sysfs_dir; + unsigned char *descriptors; + int descriptors_len; + int active_config; /* cache val for !sysfs_can_relate_devices */ +}; + +struct linux_device_handle_priv { + int fd; + int fd_removed; + uint32_t caps; +}; + +enum reap_action { + NORMAL = 0, + /* submission failed after the first URB, so await cancellation/completion + * of all the others */ + SUBMIT_FAILED, + + /* cancelled by user or timeout */ + CANCELLED, + + /* completed multi-URB transfer in non-final URB */ + COMPLETED_EARLY, + + /* one or more urbs encountered a low-level error */ + ERROR, +}; + +struct linux_transfer_priv { + union { + struct usbfs_urb *urbs; + struct usbfs_urb **iso_urbs; + }; + + enum reap_action reap_action; + int num_urbs; + int num_retired; + enum libusb_transfer_status reap_status; + + /* next iso packet in user-supplied transfer to be populated */ + int iso_packet_offset; +}; + +static int _open(const char *path, int flags) +{ +#if defined(O_CLOEXEC) + if (supports_flag_cloexec) + return open(path, flags | O_CLOEXEC); + else +#endif + return open(path, flags); +} + +static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + char path[PATH_MAX]; + int fd; + int delay = 10000; + + if (usbdev_names) + snprintf(path, PATH_MAX, "%s/usbdev%d.%d", + usbfs_path, dev->bus_number, dev->device_address); + else + snprintf(path, PATH_MAX, "%s/%03d/%03d", + usbfs_path, dev->bus_number, dev->device_address); + + fd = _open(path, mode); + if (fd != -1) + return fd; /* Success */ + + if (errno == ENOENT) { + if (!silent) + usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000); + + /* Wait 10ms for USB device path creation.*/ + nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL); + + fd = _open(path, mode); + if (fd != -1) + return fd; /* Success */ + } + + if (!silent) { + usbi_err(ctx, "libusb couldn't open USB device %s: %s", + path, strerror(errno)); + if (errno == EACCES && mode == O_RDWR) + usbi_err(ctx, "libusb requires write access to USB " + "device nodes."); + } + + if (errno == EACCES) + return LIBUSB_ERROR_ACCESS; + if (errno == ENOENT) + return LIBUSB_ERROR_NO_DEVICE; + return LIBUSB_ERROR_IO; +} + +static struct linux_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct linux_device_priv *) dev->os_priv; +} + +static struct linux_device_handle_priv *_device_handle_priv( + struct libusb_device_handle *handle) +{ + return (struct linux_device_handle_priv *) handle->os_priv; +} + +/* check dirent for a /dev/usbdev%d.%d name + * optionally return bus/device on success */ +static int _is_usbdev_entry(struct dirent *entry, int *bus_p, int *dev_p) +{ + int busnum, devnum; + + if (sscanf(entry->d_name, "usbdev%d.%d", &busnum, &devnum) != 2) + return 0; + + usbi_dbg("found: %s", entry->d_name); + if (bus_p != NULL) + *bus_p = busnum; + if (dev_p != NULL) + *dev_p = devnum; + return 1; +} + +static int check_usb_vfs(const char *dirname) +{ + DIR *dir; + struct dirent *entry; + int found = 0; + + dir = opendir(dirname); + if (!dir) + return 0; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_name[0] == '.') + continue; + + /* We assume if we find any files that it must be the right place */ + found = 1; + break; + } + + closedir(dir); + return found; +} + +static const char *find_usbfs_path(void) +{ + const char *path = "/dev/bus/usb"; + const char *ret = NULL; + + if (check_usb_vfs(path)) { + ret = path; + } else { + path = "/proc/bus/usb"; + if (check_usb_vfs(path)) + ret = path; + } + + /* look for /dev/usbdev*.* if the normal places fail */ + if (ret == NULL) { + struct dirent *entry; + DIR *dir; + + path = "/dev"; + dir = opendir(path); + if (dir != NULL) { + while ((entry = readdir(dir)) != NULL) { + if (_is_usbdev_entry(entry, NULL, NULL)) { + /* found one; that's enough */ + ret = path; + usbdev_names = 1; + break; + } + } + closedir(dir); + } + } + +/* On udev based systems without any usb-devices /dev/bus/usb will not + * exist. So if we've not found anything and we're using udev for hotplug + * simply assume /dev/bus/usb rather then making libusb_init fail. */ +#if defined(USE_UDEV) + if (ret == NULL) + ret = "/dev/bus/usb"; +#endif + + if (ret != NULL) + usbi_dbg("found usbfs at %s", ret); + + return ret; +} + +/* the monotonic clock is not usable on all systems (e.g. embedded ones often + * seem to lack it). fall back to REALTIME if we have to. */ +static clockid_t find_monotonic_clock(void) +{ +#ifdef CLOCK_MONOTONIC + struct timespec ts; + int r; + + /* Linux 2.6.28 adds CLOCK_MONOTONIC_RAW but we don't use it + * because it's not available through timerfd */ + r = clock_gettime(CLOCK_MONOTONIC, &ts); + if (r == 0) + return CLOCK_MONOTONIC; + usbi_dbg("monotonic clock doesn't work, errno %d", errno); +#endif + + return CLOCK_REALTIME; +} + +static int get_kernel_version(struct libusb_context *ctx, + struct kernel_version *ver) +{ + struct utsname uts; + int atoms; + + if (uname(&uts) < 0) { + usbi_err(ctx, "uname failed, errno %d", errno); + return -1; + } + + atoms = sscanf(uts.release, "%d.%d.%d", &ver->major, &ver->minor, &ver->sublevel); + if (atoms < 1) { + usbi_err(ctx, "failed to parse uname release '%s'", uts.release); + return -1; + } + + if (atoms < 2) + ver->minor = -1; + if (atoms < 3) + ver->sublevel = -1; + + usbi_dbg("reported kernel version is %s", uts.release); + + return 0; +} + +static int kernel_version_ge(const struct kernel_version *ver, + int major, int minor, int sublevel) +{ + if (ver->major > major) + return 1; + else if (ver->major < major) + return 0; + + /* kmajor == major */ + if (ver->minor == -1 && ver->sublevel == -1) + return 0 == minor && 0 == sublevel; + else if (ver->minor > minor) + return 1; + else if (ver->minor < minor) + return 0; + + /* kminor == minor */ + if (ver->sublevel == -1) + return 0 == sublevel; + + return ver->sublevel >= sublevel; +} + +static int op_init(struct libusb_context *ctx) +{ + struct kernel_version kversion; + struct stat statbuf; + int r; + + usbfs_path = find_usbfs_path(); + if (!usbfs_path) { + usbi_err(ctx, "could not find usbfs"); + return LIBUSB_ERROR_OTHER; + } + + if (monotonic_clkid == -1) + monotonic_clkid = find_monotonic_clock(); + + if (get_kernel_version(ctx, &kversion) < 0) + return LIBUSB_ERROR_OTHER; + + if (supports_flag_cloexec == -1) { + /* O_CLOEXEC flag available from Linux 2.6.23 */ + supports_flag_cloexec = kernel_version_ge(&kversion,2,6,23); + } + + if (supports_flag_bulk_continuation == -1) { + /* bulk continuation URB flag available from Linux 2.6.32 */ + supports_flag_bulk_continuation = kernel_version_ge(&kversion,2,6,32); + } + + if (supports_flag_bulk_continuation) + usbi_dbg("bulk continuation flag supported"); + + if (-1 == supports_flag_zero_packet) { + /* zero length packet URB flag fixed since Linux 2.6.31 */ + supports_flag_zero_packet = kernel_version_ge(&kversion,2,6,31); + } + + if (supports_flag_zero_packet) + usbi_dbg("zero length packet flag supported"); + + if (!max_iso_packet_len) { + if (kernel_version_ge(&kversion,3,10,0)) + max_iso_packet_len = 49152; + else if (kernel_version_ge(&kversion,2,6,18)) + max_iso_packet_len = 8192; + else + max_iso_packet_len = 1023; + } + + usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len); + + if (-1 == sysfs_has_descriptors) { + /* sysfs descriptors has all descriptors since Linux 2.6.26 */ + sysfs_has_descriptors = kernel_version_ge(&kversion,2,6,26); + } + + if (-1 == sysfs_can_relate_devices) { + /* sysfs has busnum since Linux 2.6.22 */ + sysfs_can_relate_devices = kernel_version_ge(&kversion,2,6,22); + } + + if (sysfs_can_relate_devices || sysfs_has_descriptors) { + r = stat(SYSFS_DEVICE_PATH, &statbuf); + if (r != 0 || !S_ISDIR(statbuf.st_mode)) { + usbi_warn(ctx, "sysfs not mounted"); + sysfs_can_relate_devices = 0; + sysfs_has_descriptors = 0; + } + } + + if (sysfs_can_relate_devices) + usbi_dbg("sysfs can relate devices"); + + if (sysfs_has_descriptors) + usbi_dbg("sysfs has complete descriptors"); + + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + r = LIBUSB_SUCCESS; + if (init_count == 0) { + /* start up hotplug event handler */ + r = linux_start_event_monitor(); + } + if (r == LIBUSB_SUCCESS) { + r = linux_scan_devices(ctx); + if (r == LIBUSB_SUCCESS) + init_count++; + else if (init_count == 0) + linux_stop_event_monitor(); + } else + usbi_err(ctx, "error starting hotplug event monitor"); + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); + + return r; +} + +static void op_exit(struct libusb_context *ctx) +{ + UNUSED(ctx); + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + assert(init_count != 0); + if (!--init_count) { + /* tear down event handler */ + (void)linux_stop_event_monitor(); + } + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); +} + +static int linux_start_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_start_event_monitor(); +#else + return linux_netlink_start_event_monitor(); +#endif +} + +static int linux_stop_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_stop_event_monitor(); +#else + return linux_netlink_stop_event_monitor(); +#endif +} + +static int linux_scan_devices(struct libusb_context *ctx) +{ + int ret; + + usbi_mutex_static_lock(&linux_hotplug_lock); + +#if defined(USE_UDEV) + ret = linux_udev_scan_devices(ctx); +#else + ret = linux_default_scan_devices(ctx); +#endif + + usbi_mutex_static_unlock(&linux_hotplug_lock); + + return ret; +} + +static void op_hotplug_poll(void) +{ +#if defined(USE_UDEV) + linux_udev_hotplug_poll(); +#else + linux_netlink_hotplug_poll(); +#endif +} + +static int _open_sysfs_attr(struct libusb_device *dev, const char *attr) +{ + struct linux_device_priv *priv = _device_priv(dev); + char filename[PATH_MAX]; + int fd; + + snprintf(filename, PATH_MAX, "%s/%s/%s", + SYSFS_DEVICE_PATH, priv->sysfs_dir, attr); + fd = _open(filename, O_RDONLY); + if (fd < 0) { + usbi_err(DEVICE_CTX(dev), + "open %s failed ret=%d errno=%d", filename, fd, errno); + return LIBUSB_ERROR_IO; + } + + return fd; +} + +/* Note only suitable for attributes which always read >= 0, < 0 is error */ +static int __read_sysfs_attr(struct libusb_context *ctx, + const char *devname, const char *attr) +{ + char filename[PATH_MAX]; + FILE *f; + int fd, r, value; + + snprintf(filename, PATH_MAX, "%s/%s/%s", SYSFS_DEVICE_PATH, + devname, attr); + fd = _open(filename, O_RDONLY); + if (fd == -1) { + if (errno == ENOENT) { + /* File doesn't exist. Assume the device has been + disconnected (see trac ticket #70). */ + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(ctx, "open %s failed errno=%d", filename, errno); + return LIBUSB_ERROR_IO; + } + + f = fdopen(fd, "r"); + if (f == NULL) { + usbi_err(ctx, "fdopen %s failed errno=%d", filename, errno); + close(fd); + return LIBUSB_ERROR_OTHER; + } + + r = fscanf(f, "%d", &value); + fclose(f); + if (r != 1) { + usbi_err(ctx, "fscanf %s returned %d, errno=%d", attr, r, errno); + return LIBUSB_ERROR_NO_DEVICE; /* For unplug race (trac #70) */ + } + if (value < 0) { + usbi_err(ctx, "%s contains a negative value", filename); + return LIBUSB_ERROR_IO; + } + + return value; +} + +static int op_get_device_descriptor(struct libusb_device *dev, + unsigned char *buffer, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + + *host_endian = sysfs_has_descriptors ? 0 : 1; + memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH); + + return 0; +} + +/* read the bConfigurationValue for a device */ +static int sysfs_get_active_config(struct libusb_device *dev, int *config) +{ + char *endptr; + char tmp[5] = {0, 0, 0, 0, 0}; + long num; + int fd; + ssize_t r; + + fd = _open_sysfs_attr(dev, "bConfigurationValue"); + if (fd < 0) + return fd; + + r = read(fd, tmp, sizeof(tmp)); + close(fd); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "read bConfigurationValue failed ret=%d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } else if (r == 0) { + usbi_dbg("device unconfigured"); + *config = -1; + return 0; + } + + if (tmp[sizeof(tmp) - 1] != 0) { + usbi_err(DEVICE_CTX(dev), "not null-terminated?"); + return LIBUSB_ERROR_IO; + } else if (tmp[0] == 0) { + usbi_err(DEVICE_CTX(dev), "no configuration value?"); + return LIBUSB_ERROR_IO; + } + + num = strtol(tmp, &endptr, 10); + if (endptr == tmp) { + usbi_err(DEVICE_CTX(dev), "error converting '%s' to integer", tmp); + return LIBUSB_ERROR_IO; + } + + *config = (int) num; + return 0; +} + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr,const char *dev_node, + const char *sys_name) +{ + int sysfs_attr; + + usbi_dbg("getting address for device: %s detached: %d", sys_name, detached); + /* can't use sysfs to read the bus and device number if the + * device has been detached */ + if (!sysfs_can_relate_devices || detached || NULL == sys_name) { + if (NULL == dev_node) { + return LIBUSB_ERROR_OTHER; + } + + /* will this work with all supported kernel versions? */ + if (!strncmp(dev_node, "/dev/bus/usb", 12)) { + sscanf (dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr); + } else if (!strncmp(dev_node, "/proc/bus/usb", 13)) { + sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr); + } + + return LIBUSB_SUCCESS; + } + + usbi_dbg("scan %s", sys_name); + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "busnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + *busnum = (uint8_t) sysfs_attr; + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "devnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + + *devaddr = (uint8_t) sysfs_attr; + + usbi_dbg("bus=%d dev=%d", *busnum, *devaddr); + + return LIBUSB_SUCCESS; +} + +/* Return offset of the next descriptor with the given type */ +static int seek_to_next_descriptor(struct libusb_context *ctx, + uint8_t descriptor_type, unsigned char *buffer, int size) +{ + struct usb_descriptor_header header; + int i; + + for (i = 0; size >= 0; i += header.bLength, size -= header.bLength) { + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < 2) { + usbi_err(ctx, "short descriptor read %d/2", size); + return LIBUSB_ERROR_IO; + } + usbi_parse_descriptor(buffer + i, "bb", &header, 0); + + if (i && header.bDescriptorType == descriptor_type) + return i; + } + usbi_err(ctx, "bLength overflow by %d bytes", -size); + return LIBUSB_ERROR_IO; +} + +/* Return offset to next config */ +static int seek_to_next_config(struct libusb_context *ctx, + unsigned char *buffer, int size) +{ + struct libusb_config_descriptor config; + + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", &config, 0); + if (config.bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "descriptor is not a config desc (type 0x%02x)", + config.bDescriptorType); + return LIBUSB_ERROR_IO; + } + + /* + * In usbfs the config descriptors are config.wTotalLength bytes apart, + * with any short reads from the device appearing as holes in the file. + * + * In sysfs wTotalLength is ignored, instead the kernel returns a + * config descriptor with verified bLength fields, with descriptors + * with an invalid bLength removed. + */ + if (sysfs_has_descriptors) { + int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG, + buffer, size); + if (next == LIBUSB_ERROR_NOT_FOUND) + next = size; + if (next < 0) + return next; + + if (next != config.wTotalLength) + usbi_warn(ctx, "config length mismatch wTotalLength " + "%d real %d", config.wTotalLength, next); + return next; + } else { + if (config.wTotalLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid wTotalLength %d", + config.wTotalLength); + return LIBUSB_ERROR_IO; + } else if (config.wTotalLength > size) { + usbi_warn(ctx, "short descriptor read %d/%d", + size, config.wTotalLength); + return size; + } else + return config.wTotalLength; + } +} + +static int op_get_config_descriptor_by_value(struct libusb_device *dev, + uint8_t value, unsigned char **buffer, int *host_endian) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int size = priv->descriptors_len; + struct libusb_config_descriptor *config; + + *buffer = NULL; + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + while (1) { + int next = seek_to_next_config(ctx, descriptors, size); + if (next < 0) + return next; + config = (struct libusb_config_descriptor *)descriptors; + if (config->bConfigurationValue == value) { + *buffer = descriptors; + return next; + } + size -= next; + descriptors += next; + } +} + +static int op_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buffer, size_t len, int *host_endian) +{ + int r, config; + unsigned char *config_desc; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(dev, &config); + if (r < 0) + return r; + } else { + /* Use cached bConfigurationValue */ + struct linux_device_priv *priv = _device_priv(dev); + config = priv->active_config; + } + if (config == -1) + return LIBUSB_ERROR_NOT_FOUND; + + r = op_get_config_descriptor_by_value(dev, config, &config_desc, + host_endian); + if (r < 0) + return r; + + len = MIN(len, (size_t)r); + memcpy(buffer, config_desc, len); + return len; +} + +static int op_get_config_descriptor(struct libusb_device *dev, + uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int i, r, size = priv->descriptors_len; + + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + for (i = 0; ; i++) { + r = seek_to_next_config(DEVICE_CTX(dev), descriptors, size); + if (r < 0) + return r; + if (i == config_index) + break; + size -= r; + descriptors += r; + } + + len = MIN(len, (size_t)r); + memcpy(buffer, descriptors, len); + return len; +} + +/* send a control message to retrieve active configuration */ +static int usbfs_get_active_config(struct libusb_device *dev, int fd) +{ + struct linux_device_priv *priv = _device_priv(dev); + unsigned char active_config = 0; + int r; + + struct usbfs_ctrltransfer ctrl = { + .bmRequestType = LIBUSB_ENDPOINT_IN, + .bRequest = LIBUSB_REQUEST_GET_CONFIGURATION, + .wValue = 0, + .wIndex = 0, + .wLength = 1, + .timeout = 1000, + .data = &active_config + }; + + r = ioctl(fd, IOCTL_USBFS_CONTROL, &ctrl); + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + /* we hit this error path frequently with buggy devices :( */ + usbi_warn(DEVICE_CTX(dev), + "get_configuration failed ret=%d errno=%d", r, errno); + priv->active_config = -1; + } else { + if (active_config > 0) { + priv->active_config = active_config; + } else { + /* some buggy devices have a configuration 0, but we're + * reaching into the corner of a corner case here, so let's + * not support buggy devices in these circumstances. + * stick to the specs: a configuration value of 0 means + * unconfigured. */ + usbi_warn(DEVICE_CTX(dev), + "active cfg 0? assuming unconfigured device"); + priv->active_config = -1; + } + } + + return LIBUSB_SUCCESS; +} + +static int initialize_device(struct libusb_device *dev, uint8_t busnum, + uint8_t devaddr, const char *sysfs_dir) +{ + struct linux_device_priv *priv = _device_priv(dev); + struct libusb_context *ctx = DEVICE_CTX(dev); + int descriptors_size = 512; /* Begin with a 1024 byte alloc */ + int fd, speed; + ssize_t r; + + dev->bus_number = busnum; + dev->device_address = devaddr; + + if (sysfs_dir) { + priv->sysfs_dir = strdup(sysfs_dir); + if (!priv->sysfs_dir) + return LIBUSB_ERROR_NO_MEM; + + /* Note speed can contain 1.5, in this case __read_sysfs_attr + will stop parsing at the '.' and return 1 */ + speed = __read_sysfs_attr(DEVICE_CTX(dev), sysfs_dir, "speed"); + if (speed >= 0) { + switch (speed) { + case 1: dev->speed = LIBUSB_SPEED_LOW; break; + case 12: dev->speed = LIBUSB_SPEED_FULL; break; + case 480: dev->speed = LIBUSB_SPEED_HIGH; break; + case 5000: dev->speed = LIBUSB_SPEED_SUPER; break; + case 10000: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break; + default: + usbi_warn(DEVICE_CTX(dev), "Unknown device speed: %d Mbps", speed); + } + } + } + + /* cache descriptors in memory */ + if (sysfs_has_descriptors) + fd = _open_sysfs_attr(dev, "descriptors"); + else + fd = _get_usbfs_fd(dev, O_RDONLY, 0); + if (fd < 0) + return fd; + + do { + descriptors_size *= 2; + priv->descriptors = usbi_reallocf(priv->descriptors, + descriptors_size); + if (!priv->descriptors) { + close(fd); + return LIBUSB_ERROR_NO_MEM; + } + /* usbfs has holes in the file */ + if (!sysfs_has_descriptors) { + memset(priv->descriptors + priv->descriptors_len, + 0, descriptors_size - priv->descriptors_len); + } + r = read(fd, priv->descriptors + priv->descriptors_len, + descriptors_size - priv->descriptors_len); + if (r < 0) { + usbi_err(ctx, "read descriptor failed ret=%d errno=%d", + fd, errno); + close(fd); + return LIBUSB_ERROR_IO; + } + priv->descriptors_len += r; + } while (priv->descriptors_len == descriptors_size); + + close(fd); + + if (priv->descriptors_len < DEVICE_DESC_LENGTH) { + usbi_err(ctx, "short descriptor read (%d)", + priv->descriptors_len); + return LIBUSB_ERROR_IO; + } + + if (sysfs_can_relate_devices) + return LIBUSB_SUCCESS; + + /* cache active config */ + fd = _get_usbfs_fd(dev, O_RDWR, 1); + if (fd < 0) { + /* cannot send a control message to determine the active + * config. just assume the first one is active. */ + usbi_warn(ctx, "Missing rw usbfs access; cannot determine " + "active configuration descriptor"); + if (priv->descriptors_len >= + (DEVICE_DESC_LENGTH + LIBUSB_DT_CONFIG_SIZE)) { + struct libusb_config_descriptor config; + usbi_parse_descriptor( + priv->descriptors + DEVICE_DESC_LENGTH, + "bbwbbbbb", &config, 0); + priv->active_config = config.bConfigurationValue; + } else + priv->active_config = -1; /* No config dt */ + + return LIBUSB_SUCCESS; + } + + r = usbfs_get_active_config(dev, fd); + close(fd); + + return r; +} + +static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_dir) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device *it; + char *parent_sysfs_dir, *tmp; + int ret, add_parent = 1; + + /* XXX -- can we figure out the topology when using usbfs? */ + if (NULL == sysfs_dir || 0 == strncmp(sysfs_dir, "usb", 3)) { + /* either using usbfs or finding the parent of a root hub */ + return LIBUSB_SUCCESS; + } + + parent_sysfs_dir = strdup(sysfs_dir); + if (NULL == parent_sysfs_dir) { + return LIBUSB_ERROR_NO_MEM; + } + if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) || + NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) { + dev->port_number = atoi(tmp + 1); + *tmp = '\0'; + } else { + usbi_warn(ctx, "Can not parse sysfs_dir: %s, no parent info", + parent_sysfs_dir); + free (parent_sysfs_dir); + return LIBUSB_SUCCESS; + } + + /* is the parent a root hub? */ + if (NULL == strchr(parent_sysfs_dir, '-')) { + tmp = parent_sysfs_dir; + ret = asprintf (&parent_sysfs_dir, "usb%s", tmp); + free (tmp); + if (0 > ret) { + return LIBUSB_ERROR_NO_MEM; + } + } + +retry: + /* find the parent in the context */ + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(it, &ctx->usb_devs, list, struct libusb_device) { + struct linux_device_priv *priv = _device_priv(it); + if (priv->sysfs_dir) { + if (0 == strcmp (priv->sysfs_dir, parent_sysfs_dir)) { + dev->parent_dev = libusb_ref_device(it); + break; + } + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + if (!dev->parent_dev && add_parent) { + usbi_dbg("parent_dev %s not enumerated yet, enumerating now", + parent_sysfs_dir); + sysfs_scan_device(ctx, parent_sysfs_dir); + add_parent = 0; + goto retry; + } + + usbi_dbg("Dev %p (%s) has parent %p (%s) port %d", dev, sysfs_dir, + dev->parent_dev, parent_sysfs_dir, dev->port_number); + + free (parent_sysfs_dir); + + return LIBUSB_SUCCESS; +} + +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir) +{ + unsigned long session_id; + struct libusb_device *dev; + int r = 0; + + /* FIXME: session ID is not guaranteed unique as addresses can wrap and + * will be reused. instead we should add a simple sysfs attribute with + * a session ID. */ + session_id = busnum << 8 | devaddr; + usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr, + session_id); + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + /* device already exists in the context */ + usbi_dbg("session_id %ld already exists", session_id); + libusb_unref_device(dev); + return LIBUSB_SUCCESS; + } + + usbi_dbg("allocating new device for %d/%d (session %ld)", + busnum, devaddr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) + return LIBUSB_ERROR_NO_MEM; + + r = initialize_device(dev, busnum, devaddr, sysfs_dir); + if (r < 0) + goto out; + r = usbi_sanitize_device(dev); + if (r < 0) + goto out; + + r = linux_get_parent_info(dev, sysfs_dir); + if (r < 0) + goto out; +out: + if (r < 0) + libusb_unref_device(dev); + else + usbi_connect_device(dev); + + return r; +} + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name) +{ + struct libusb_context *ctx; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + linux_enumerate_device(ctx, busnum, devaddr, sys_name); + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr) +{ + struct libusb_context *ctx; + struct libusb_device *dev; + unsigned long session_id = busnum << 8 | devaddr; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + dev = usbi_get_device_by_session_id (ctx, session_id); + if (NULL != dev) { + usbi_disconnect_device (dev); + libusb_unref_device(dev); + } else { + usbi_dbg("device not found for session %x", session_id); + } + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +#if !defined(USE_UDEV) +/* open a bus directory and adds all discovered devices to the context */ +static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum) +{ + DIR *dir; + char dirpath[PATH_MAX]; + struct dirent *entry; + int r = LIBUSB_ERROR_IO; + + snprintf(dirpath, PATH_MAX, "%s/%03d", usbfs_path, busnum); + usbi_dbg("%s", dirpath); + dir = opendir(dirpath); + if (!dir) { + usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno); + /* FIXME: should handle valid race conditions like hub unplugged + * during directory iteration - this is not an error */ + return r; + } + + while ((entry = readdir(dir))) { + int devaddr; + + if (entry->d_name[0] == '.') + continue; + + devaddr = atoi(entry->d_name); + if (devaddr == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + if (linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + r = 0; + } + + closedir(dir); + return r; +} + +static int usbfs_get_device_list(struct libusb_context *ctx) +{ + struct dirent *entry; + DIR *buses = opendir(usbfs_path); + int r = 0; + + if (!buses) { + usbi_err(ctx, "opendir buses failed errno=%d", errno); + return LIBUSB_ERROR_IO; + } + + while ((entry = readdir(buses))) { + int busnum; + + if (entry->d_name[0] == '.') + continue; + + if (usbdev_names) { + int devaddr; + if (!_is_usbdev_entry(entry, &busnum, &devaddr)) + continue; + + r = linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL); + if (r < 0) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + } else { + busnum = atoi(entry->d_name); + if (busnum == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + r = usbfs_scan_busdir(ctx, busnum); + if (r < 0) + break; + } + } + + closedir(buses); + return r; + +} +#endif + +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname) +{ + uint8_t busnum, devaddr; + int ret; + + ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname); + if (LIBUSB_SUCCESS != ret) { + return ret; + } + + return linux_enumerate_device(ctx, busnum & 0xff, devaddr & 0xff, + devname); +} + +#if !defined(USE_UDEV) +static int sysfs_get_device_list(struct libusb_context *ctx) +{ + DIR *devices = opendir(SYSFS_DEVICE_PATH); + struct dirent *entry; + int num_devices = 0; + int num_enumerated = 0; + + if (!devices) { + usbi_err(ctx, "opendir devices failed errno=%d", errno); + return LIBUSB_ERROR_IO; + } + + while ((entry = readdir(devices))) { + if ((!isdigit(entry->d_name[0]) && strncmp(entry->d_name, "usb", 3)) + || strchr(entry->d_name, ':')) + continue; + + num_devices++; + + if (sysfs_scan_device(ctx, entry->d_name)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + num_enumerated++; + } + + closedir(devices); + + /* successful if at least one device was enumerated or no devices were found */ + if (num_enumerated || !num_devices) + return LIBUSB_SUCCESS; + else + return LIBUSB_ERROR_IO; +} + +static int linux_default_scan_devices (struct libusb_context *ctx) +{ + /* we can retrieve device list and descriptors from sysfs or usbfs. + * sysfs is preferable, because if we use usbfs we end up resuming + * any autosuspended USB devices. however, sysfs is not available + * everywhere, so we need a usbfs fallback too. + * + * as described in the "sysfs vs usbfs" comment at the top of this + * file, sometimes we have sysfs but not enough information to + * relate sysfs devices to usbfs nodes. op_init() determines the + * adequacy of sysfs and sets sysfs_can_relate_devices. + */ + if (sysfs_can_relate_devices != 0) + return sysfs_get_device_list(ctx); + else + return usbfs_get_device_list(ctx); +} +#endif + +static int op_open(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + + hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0); + if (hpriv->fd < 0) { + if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) { + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) { + usbi_dbg("open failed with no device, but device still attached"); + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + } + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + return hpriv->fd; + } + + r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); + if (r < 0) { + if (errno == ENOTTY) + usbi_dbg("getcap not available"); + else + usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno); + hpriv->caps = 0; + if (supports_flag_zero_packet) + hpriv->caps |= USBFS_CAP_ZERO_PACKET; + if (supports_flag_bulk_continuation) + hpriv->caps |= USBFS_CAP_BULK_CONTINUATION; + } + + r = usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); + if (r < 0) + close(hpriv->fd); + + return r; +} + +static void op_close(struct libusb_device_handle *dev_handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle); + /* fd may have already been removed by POLLERR condition in op_handle_events() */ + if (!hpriv->fd_removed) + usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd); + close(hpriv->fd); +} + +static int op_get_configuration(struct libusb_device_handle *handle, + int *config) +{ + int r; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(handle->dev, config); + } else { + r = usbfs_get_active_config(handle->dev, + _device_handle_priv(handle)->fd); + if (r == LIBUSB_SUCCESS) + *config = _device_priv(handle->dev)->active_config; + } + if (r < 0) + return r; + + if (*config == -1) { + usbi_err(HANDLE_CTX(handle), "device unconfigured"); + *config = 0; + } + + return 0; +} + +static int op_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct linux_device_priv *priv = _device_priv(handle->dev); + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_SETCONFIG, &config); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + /* update our cached active config descriptor */ + priv->active_config = config; + + return LIBUSB_SUCCESS; +} + +static int claim_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_CLAIMINTF, &iface); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "claim interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int release_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_RELEASEINTF, &iface); + if (r) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "release interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int op_set_interface(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_setinterface setintf; + int r; + + setintf.interface = iface; + setintf.altsetting = altsetting; + r = ioctl(fd, IOCTL_USBFS_SETINTF, &setintf); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "setintf failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_clear_halt(struct libusb_device_handle *handle, + unsigned char endpoint) +{ + int fd = _device_handle_priv(handle)->fd; + unsigned int _endpoint = endpoint; + int r = ioctl(fd, IOCTL_USBFS_CLEAR_HALT, &_endpoint); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "clear_halt failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_reset_device(struct libusb_device_handle *handle) +{ + int fd = _device_handle_priv(handle)->fd; + int i, r, ret = 0; + + /* Doing a device reset will cause the usbfs driver to get unbound + from any interfaces it is bound to. By voluntarily unbinding + the usbfs driver ourself, we stop the kernel from rebinding + the interface after reset (which would end up with the interface + getting bound to the in kernel driver if any). */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + release_interface(handle, i); + } + } + + usbi_mutex_lock(&handle->lock); + r = ioctl(fd, IOCTL_USBFS_RESET, NULL); + if (r) { + if (errno == ENODEV) { + ret = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + usbi_err(HANDLE_CTX(handle), + "reset failed error %d errno %d", r, errno); + ret = LIBUSB_ERROR_OTHER; + goto out; + } + + /* And re-claim any interfaces which were claimed before the reset */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + /* + * A driver may have completed modprobing during + * IOCTL_USBFS_RESET, and bound itself as soon as + * IOCTL_USBFS_RESET released the device lock + */ + r = detach_kernel_driver_and_claim(handle, i); + if (r) { + usbi_warn(HANDLE_CTX(handle), + "failed to re-claim interface %d after reset: %s", + i, libusb_error_name(r)); + handle->claimed_interfaces &= ~(1L << i); + ret = LIBUSB_ERROR_NOT_FOUND; + } + } + } +out: + usbi_mutex_unlock(&handle->lock); + return ret; +} + +static int do_streams_ioctl(struct libusb_device_handle *handle, long req, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + int r, fd = _device_handle_priv(handle)->fd; + struct usbfs_streams *streams; + + if (num_endpoints > 30) /* Max 15 in + 15 out eps */ + return LIBUSB_ERROR_INVALID_PARAM; + + streams = malloc(sizeof(struct usbfs_streams) + num_endpoints); + if (!streams) + return LIBUSB_ERROR_NO_MEM; + + streams->num_streams = num_streams; + streams->num_eps = num_endpoints; + memcpy(streams->eps, endpoints, num_endpoints); + + r = ioctl(fd, req, streams); + + free(streams); + + if (r < 0) { + if (errno == ENOTTY) + return LIBUSB_ERROR_NOT_SUPPORTED; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "streams-ioctl failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return r; +} + +static int op_alloc_streams(struct libusb_device_handle *handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_ALLOC_STREAMS, + num_streams, endpoints, num_endpoints); +} + +static int op_free_streams(struct libusb_device_handle *handle, + unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_FREE_STREAMS, 0, + endpoints, num_endpoints); +} + +static unsigned char *op_dev_mem_alloc(struct libusb_device_handle *handle, + size_t len) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + unsigned char *buffer = (unsigned char *)mmap(NULL, len, + PROT_READ | PROT_WRITE, MAP_SHARED, hpriv->fd, 0); + if (buffer == MAP_FAILED) { + usbi_err(HANDLE_CTX(handle), "alloc dev mem failed errno %d", + errno); + return NULL; + } + return buffer; +} + +static int op_dev_mem_free(struct libusb_device_handle *handle, + unsigned char *buffer, size_t len) +{ + if (munmap(buffer, len) != 0) { + usbi_err(HANDLE_CTX(handle), "free dev mem failed errno %d", + errno); + return LIBUSB_ERROR_OTHER; + } else { + return LIBUSB_SUCCESS; + } +} + +static int op_kernel_driver_active(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_getdriver getdrv; + int r; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r) { + if (errno == ENODATA) + return 0; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "get driver failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return (strcmp(getdrv.driver, "usbfs") == 0) ? 0 : 1; +} + +static int op_detach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + struct usbfs_getdriver getdrv; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_DISCONNECT; + command.data = NULL; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r == 0 && strcmp(getdrv.driver, "usbfs") == 0) + return LIBUSB_ERROR_NOT_FOUND; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "detach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_attach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_CONNECT; + command.data = NULL; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r < 0) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + + usbi_err(HANDLE_CTX(handle), + "attach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } else if (r == 0) { + return LIBUSB_ERROR_NOT_FOUND; + } + + return 0; +} + +static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle, + int interface) +{ + struct usbfs_disconnect_claim dc; + int r, fd = _device_handle_priv(handle)->fd; + + dc.interface = interface; + strcpy(dc.driver, "usbfs"); + dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER; + r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc); + if (r != 0 && errno != ENOTTY) { + switch (errno) { + case EBUSY: + return LIBUSB_ERROR_BUSY; + case EINVAL: + return LIBUSB_ERROR_INVALID_PARAM; + case ENODEV: + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(HANDLE_CTX(handle), + "disconnect-and-claim failed errno %d", errno); + return LIBUSB_ERROR_OTHER; + } else if (r == 0) + return 0; + + /* Fallback code for kernels which don't support the + disconnect-and-claim ioctl */ + r = op_detach_kernel_driver(handle, interface); + if (r != 0 && r != LIBUSB_ERROR_NOT_FOUND) + return r; + + return claim_interface(handle, interface); +} + +static int op_claim_interface(struct libusb_device_handle *handle, int iface) +{ + if (handle->auto_detach_kernel_driver) + return detach_kernel_driver_and_claim(handle, iface); + else + return claim_interface(handle, iface); +} + +static int op_release_interface(struct libusb_device_handle *handle, int iface) +{ + int r; + + r = release_interface(handle, iface); + if (r) + return r; + + if (handle->auto_detach_kernel_driver) + op_attach_kernel_driver(handle, iface); + + return 0; +} + +static void op_destroy_device(struct libusb_device *dev) +{ + struct linux_device_priv *priv = _device_priv(dev); + if (priv->descriptors) + free(priv->descriptors); + if (priv->sysfs_dir) + free(priv->sysfs_dir); +} + +/* URBs are discarded in reverse order of submission to avoid races. */ +static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plus_one) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = + usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + int i, ret = 0; + struct usbfs_urb *urb; + + for (i = last_plus_one - 1; i >= first; i--) { + if (LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type) + urb = tpriv->iso_urbs[i]; + else + urb = &tpriv->urbs[i]; + + if (0 == ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urb)) + continue; + + if (EINVAL == errno) { + usbi_dbg("URB not found --> assuming ready to be reaped"); + if (i == (last_plus_one - 1)) + ret = LIBUSB_ERROR_NOT_FOUND; + } else if (ENODEV == errno) { + usbi_dbg("Device not found for URB --> assuming ready to be reaped"); + ret = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised discard errno %d", errno); + ret = LIBUSB_ERROR_OTHER; + } + } + return ret; +} + +static void free_iso_urbs(struct linux_transfer_priv *tpriv) +{ + int i; + for (i = 0; i < tpriv->num_urbs; i++) { + struct usbfs_urb *urb = tpriv->iso_urbs[i]; + if (!urb) + break; + free(urb); + } + + free(tpriv->iso_urbs); + tpriv->iso_urbs = NULL; +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urbs; + int is_out = (transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; + int bulk_buffer_len, use_bulk_continuation; + int r; + int i; + + if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) && + !(dpriv->caps & USBFS_CAP_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + /* + * Older versions of usbfs place a 16kb limit on bulk URBs. We work + * around this by splitting large transfers into 16k blocks, and then + * submit all urbs at once. it would be simpler to submit one urb at + * a time, but there is a big performance gain doing it this way. + * + * Newer versions lift the 16k limit (USBFS_CAP_NO_PACKET_SIZE_LIM), + * using arbritary large transfers can still be a bad idea though, as + * the kernel needs to allocate physical contiguous memory for this, + * which may fail for large buffers. + * + * The kernel solves this problem by splitting the transfer into + * blocks itself when the host-controller is scatter-gather capable + * (USBFS_CAP_BULK_SCATTER_GATHER), which most controllers are. + * + * Last, there is the issue of short-transfers when splitting, for + * short split-transfers to work reliable USBFS_CAP_BULK_CONTINUATION + * is needed, but this is not always available. + */ + if (dpriv->caps & USBFS_CAP_BULK_SCATTER_GATHER) { + /* Good! Just submit everything in one go */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else if (dpriv->caps & USBFS_CAP_BULK_CONTINUATION) { + /* Split the transfers and use bulk-continuation to + avoid issues with short-transfers */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 1; + } else if (dpriv->caps & USBFS_CAP_NO_PACKET_SIZE_LIM) { + /* Don't split, assume the kernel can alloc the buffer + (otherwise the submit will fail with -ENOMEM) */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else { + /* Bad, splitting without bulk-continuation, short transfers + which end before the last urb will not work reliable! */ + /* Note we don't warn here as this is "normal" on kernels < + 2.6.32 and not a problem for most applications */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 0; + } + + int num_urbs = transfer->length / bulk_buffer_len; + int last_urb_partial = 0; + + if (transfer->length == 0) { + num_urbs = 1; + } else if ((transfer->length % bulk_buffer_len) > 0) { + last_urb_partial = 1; + num_urbs++; + } + usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, + transfer->length); + urbs = calloc(num_urbs, sizeof(struct usbfs_urb)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->reap_status = LIBUSB_TRANSFER_COMPLETED; + + for (i = 0; i < num_urbs; i++) { + struct usbfs_urb *urb = &urbs[i]; + urb->usercontext = itransfer; + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = 0; + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = itransfer->stream_id; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + urb->type = USBFS_URB_TYPE_INTERRUPT; + break; + } + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer + (i * bulk_buffer_len); + /* don't set the short not ok flag for the last URB */ + if (use_bulk_continuation && !is_out && (i < num_urbs - 1)) + urb->flags = USBFS_URB_SHORT_NOT_OK; + if (i == num_urbs - 1 && last_urb_partial) + urb->buffer_length = transfer->length % bulk_buffer_len; + else if (transfer->length == 0) + urb->buffer_length = 0; + else + urb->buffer_length = bulk_buffer_len; + + if (i > 0 && use_bulk_continuation) + urb->flags |= USBFS_URB_BULK_CONTINUATION; + + /* we have already checked that the flag is supported */ + if (is_out && i == num_urbs - 1 && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) + urb->flags |= USBFS_URB_ZERO_PACKET; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free(urbs); + tpriv->urbs = NULL; + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we may need to discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * - this URB failing may be no error; EREMOTEIO means that + * this transfer simply didn't need all the URBs we submitted + * so, we report that the transfer was submitted successfully and + * in case of error we discard all previous URBs. later when + * the final reap completes we can report error to the user, + * or success if an earlier URB was completed successfully. + */ + tpriv->reap_action = EREMOTEIO == errno ? COMPLETED_EARLY : SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired += num_urbs - i; + + /* If we completed short then don't try to discard. */ + if (COMPLETED_EARLY == tpriv->reap_action) + return 0; + + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb **urbs; + int num_packets = transfer->num_iso_packets; + int num_packets_remaining; + int i, j; + int num_urbs; + unsigned int packet_len; + unsigned int total_len = 0; + unsigned char *urb_buffer = transfer->buffer; + + if (num_packets < 1) + return LIBUSB_ERROR_INVALID_PARAM; + + /* usbfs places arbitrary limits on iso URBs. this limit has changed + * at least three times, but we attempt to detect this limit during + * init and check it here. if the kernel rejects the request due to + * its size, we return an error indicating such to the user. + */ + for (i = 0; i < num_packets; i++) { + packet_len = transfer->iso_packet_desc[i].length; + + if (packet_len > max_iso_packet_len) { + usbi_warn(TRANSFER_CTX(transfer), + "iso packet length of %u bytes exceeds maximum of %u bytes", + packet_len, max_iso_packet_len); + return LIBUSB_ERROR_INVALID_PARAM; + } + + total_len += packet_len; + } + + if (transfer->length < (int)total_len) + return LIBUSB_ERROR_INVALID_PARAM; + + /* usbfs limits the number of iso packets per URB */ + num_urbs = (num_packets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB; + + usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, + transfer->length); + + urbs = calloc(num_urbs, sizeof(*urbs)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + + tpriv->iso_urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->iso_packet_offset = 0; + + /* allocate + initialize each URB with the correct number of packets */ + num_packets_remaining = num_packets; + for (i = 0, j = 0; i < num_urbs; i++) { + int num_packets_in_urb = MIN(num_packets_remaining, MAX_ISO_PACKETS_PER_URB); + struct usbfs_urb *urb; + size_t alloc_size; + int k; + + alloc_size = sizeof(*urb) + + (num_packets_in_urb * sizeof(struct usbfs_iso_packet_desc)); + urb = calloc(1, alloc_size); + if (!urb) { + free_iso_urbs(tpriv); + return LIBUSB_ERROR_NO_MEM; + } + urbs[i] = urb; + + /* populate packet lengths */ + for (k = 0; k < num_packets_in_urb; j++, k++) { + packet_len = transfer->iso_packet_desc[j].length; + urb->buffer_length += packet_len; + urb->iso_frame_desc[k].length = packet_len; + } + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_ISO; + /* FIXME: interface for non-ASAP data? */ + urb->flags = USBFS_URB_ISO_ASAP; + urb->endpoint = transfer->endpoint; + urb->number_of_packets = num_packets_in_urb; + urb->buffer = urb_buffer; + + urb_buffer += urb->buffer_length; + num_packets_remaining -= num_packets_in_urb; + } + + /* submit URBs */ + for (i = 0; i < num_urbs; i++) { + int r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else if (errno == EINVAL) { + usbi_warn(TRANSFER_CTX(transfer), + "submiturb failed, transfer too large"); + r = LIBUSB_ERROR_INVALID_PARAM; + } else if (errno == EMSGSIZE) { + usbi_warn(TRANSFER_CTX(transfer), + "submiturb failed, iso packet length too large"); + r = LIBUSB_ERROR_INVALID_PARAM; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free_iso_urbs(tpriv); + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we must discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * so, in this case we discard all the previous URBs BUT we report + * that the transfer was submitted successfully. then later when + * the final discard completes we can report error to the user. + */ + tpriv->reap_action = SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired = num_urbs - i; + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urb; + int r; + + if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + + urb = calloc(1, sizeof(struct usbfs_urb)); + if (!urb) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urb; + tpriv->num_urbs = 1; + tpriv->reap_action = NORMAL; + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_CONTROL; + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer; + urb->buffer_length = transfer->length; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + free(urb); + tpriv->urbs = NULL; + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } + return 0; +} + +static int op_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int op_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + if (!tpriv->urbs) + return LIBUSB_ERROR_NOT_FOUND; + + r = discard_urbs(itransfer, 0, tpriv->num_urbs); + if (r != 0) + return r; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + if (tpriv->reap_action == ERROR) + break; + /* else, fall through */ + default: + tpriv->reap_action = CANCELLED; + } + + return 0; +} + +static void op_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (tpriv->urbs) { + free(tpriv->urbs); + tpriv->urbs = NULL; + } + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (tpriv->iso_urbs) { + free_iso_urbs(tpriv); + tpriv->iso_urbs = NULL; + } + break; + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + } +} + +static int handle_bulk_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int urb_idx = urb - tpriv->urbs; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status, + urb_idx + 1, tpriv->num_urbs); + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { + /* cancelled, submit_fail, or completed early */ + usbi_dbg("abnormal reap: urb status %d", urb->status); + + /* even though we're in the process of cancelling, it's possible that + * we may receive some data in these URBs that we don't want to lose. + * examples: + * 1. while the kernel is cancelling all the packets that make up an + * URB, a few of them might complete. so we get back a successful + * cancellation *and* some data. + * 2. we receive a short URB which marks the early completion condition, + * so we start cancelling the remaining URBs. however, we're too + * slow and another URB completes (or at least completes partially). + * (this can't happen since we always use BULK_CONTINUATION.) + * + * When this happens, our objectives are not to lose any "surplus" data, + * and also to stick it at the end of the previously-received data + * (closing any holes), so that libusb reports the total amount of + * transferred data and presents it in a contiguous chunk. + */ + if (urb->actual_length > 0) { + unsigned char *target = transfer->buffer + itransfer->transferred; + usbi_dbg("received %d bytes of surplus data", urb->actual_length); + if (urb->buffer != target) { + usbi_dbg("moving surplus data from offset %d to offset %d", + (unsigned char *) urb->buffer - transfer->buffer, + target - transfer->buffer); + memmove(target, urb->buffer, urb->actual_length); + } + itransfer->transferred += urb->actual_length; + } + + if (tpriv->num_retired == tpriv->num_urbs) { + usbi_dbg("abnormal reap: last URB handled, reporting"); + if (tpriv->reap_action != COMPLETED_EARLY && + tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + goto completed; + } + goto out_unlock; + } + + itransfer->transferred += urb->actual_length; + + /* Many of these errors can occur on *any* urb of a multi-urb + * transfer. When they do, we tear down the rest of the transfer. + */ + switch (urb->status) { + case 0: + break; + case -EREMOTEIO: /* short transfer */ + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE; + goto cancel_remaining; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_STALL; + goto cancel_remaining; + case -EOVERFLOW: + /* overflow can only ever occur in the last urb */ + usbi_dbg("overflow, actual_length=%d", urb->actual_length); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW; + goto completed; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low level error %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + } + + /* if we're the last urb or we got less data than requested then we're + * done */ + if (urb_idx == tpriv->num_urbs - 1) { + usbi_dbg("last URB in transfer --> complete!"); + goto completed; + } else if (urb->actual_length < urb->buffer_length) { + usbi_dbg("short transfer %d/%d --> complete!", + urb->actual_length, urb->buffer_length); + if (tpriv->reap_action == NORMAL) + tpriv->reap_action = COMPLETED_EARLY; + } else + goto out_unlock; + +cancel_remaining: + if (ERROR == tpriv->reap_action && LIBUSB_TRANSFER_COMPLETED == tpriv->reap_status) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + + if (tpriv->num_retired == tpriv->num_urbs) /* nothing to cancel */ + goto completed; + + /* cancel remaining urbs and wait for their completion before + * reporting results */ + discard_urbs(itransfer, urb_idx + 1, tpriv->num_urbs); + +out_unlock: + usbi_mutex_unlock(&itransfer->lock); + return 0; + +completed: + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return CANCELLED == tpriv->reap_action ? + usbi_handle_transfer_cancellation(itransfer) : + usbi_handle_transfer_completion(itransfer, tpriv->reap_status); +} + +static int handle_iso_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int num_urbs = tpriv->num_urbs; + int urb_idx = 0; + int i; + enum libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; + + usbi_mutex_lock(&itransfer->lock); + for (i = 0; i < num_urbs; i++) { + if (urb == tpriv->iso_urbs[i]) { + urb_idx = i + 1; + break; + } + } + if (urb_idx == 0) { + usbi_err(TRANSFER_CTX(transfer), "could not locate urb!"); + usbi_mutex_unlock(&itransfer->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status, + urb_idx, num_urbs); + + /* copy isochronous results back in */ + + for (i = 0; i < urb->number_of_packets; i++) { + struct usbfs_iso_packet_desc *urb_desc = &urb->iso_frame_desc[i]; + struct libusb_iso_packet_descriptor *lib_desc = + &transfer->iso_packet_desc[tpriv->iso_packet_offset++]; + lib_desc->status = LIBUSB_TRANSFER_COMPLETED; + switch (urb_desc->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + lib_desc->status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("overflow error"); + lib_desc->status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + case -EXDEV: + usbi_dbg("low-level USB error %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + } + lib_desc->actual_length = urb_desc->actual_length; + } + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */ + usbi_dbg("CANCEL: urb status %d", urb->status); + + if (tpriv->num_retired == num_urbs) { + usbi_dbg("CANCEL: last URB handled, reporting"); + free_iso_urbs(tpriv); + if (tpriv->reap_action == CANCELLED) { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } else { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, + LIBUSB_TRANSFER_ERROR); + } + } + goto out; + } + + switch (urb->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + /* if we're the last urb then we're done */ + if (urb_idx == num_urbs) { + usbi_dbg("last URB in transfer --> complete!"); + free_iso_urbs(tpriv); + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); + } + +out: + usbi_mutex_unlock(&itransfer->lock); + return 0; +} + +static int handle_control_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int status; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d", urb->status); + + itransfer->transferred += urb->actual_length; + + if (tpriv->reap_action == CANCELLED) { + if (urb->status != 0 && urb->status != -ENOENT) + usbi_warn(ITRANSFER_CTX(itransfer), + "cancel: unrecognised urb status %d", urb->status); + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } + + switch (urb->status) { + case 0: + status = LIBUSB_TRANSFER_COMPLETED; + break; + case -ENOENT: /* cancelled */ + status = LIBUSB_TRANSFER_CANCELLED; + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("unsupported control request"); + status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("control overflow error"); + status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low-level bus error occurred"); + status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); +} + +static int reap_for_handle(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + struct usbfs_urb *urb; + struct usbi_transfer *itransfer; + struct libusb_transfer *transfer; + + r = ioctl(hpriv->fd, IOCTL_USBFS_REAPURBNDELAY, &urb); + if (r == -1 && errno == EAGAIN) + return 1; + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "reap failed error %d errno=%d", + r, errno); + return LIBUSB_ERROR_IO; + } + + itransfer = urb->usercontext; + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status, + urb->actual_length); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return handle_iso_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return handle_bulk_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_CONTROL: + return handle_control_completion(itransfer, urb); + default: + usbi_err(HANDLE_CTX(handle), "unrecognised endpoint type %x", + transfer->type); + return LIBUSB_ERROR_OTHER; + } +} + +static int op_handle_events(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + int r; + unsigned int i = 0; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + struct pollfd *pollfd = &fds[i]; + struct libusb_device_handle *handle; + struct linux_device_handle_priv *hpriv = NULL; + + if (!pollfd->revents) + continue; + + num_ready--; + list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { + hpriv = _device_handle_priv(handle); + if (hpriv->fd == pollfd->fd) + break; + } + + if (!hpriv || hpriv->fd != pollfd->fd) { + usbi_err(ctx, "cannot find handle for fd %d", + pollfd->fd); + continue; + } + + if (pollfd->revents & POLLERR) { + /* remove the fd from the pollfd set so that it doesn't continuously + * trigger an event, and flag that it has been removed so op_close() + * doesn't try to remove it a second time */ + usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); + hpriv->fd_removed = 1; + + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + usbi_mutex_static_unlock(&linux_hotplug_lock); + + if (hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT) { + do { + r = reap_for_handle(handle); + } while (r == 0); + } + + usbi_handle_disconnect(handle); + continue; + } + + do { + r = reap_for_handle(handle); + } while (r == 0); + if (r == 1 || r == LIBUSB_ERROR_NO_DEVICE) + continue; + else if (r < 0) + goto out; + } + + r = 0; +out: + usbi_mutex_unlock(&ctx->open_devs_lock); + return r; +} + +static int op_clock_gettime(int clk_id, struct timespec *tp) +{ + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + return clock_gettime(monotonic_clkid, tp); + case USBI_CLOCK_REALTIME: + return clock_gettime(CLOCK_REALTIME, tp); + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +#ifdef USBI_TIMERFD_AVAILABLE +static clockid_t op_get_timerfd_clockid(void) +{ + return monotonic_clkid; + +} +#endif + +const struct usbi_os_backend usbi_backend = { + .name = "Linux usbfs", + .caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER, + .init = op_init, + .exit = op_exit, + .get_device_list = NULL, + .hotplug_poll = op_hotplug_poll, + .get_device_descriptor = op_get_device_descriptor, + .get_active_config_descriptor = op_get_active_config_descriptor, + .get_config_descriptor = op_get_config_descriptor, + .get_config_descriptor_by_value = op_get_config_descriptor_by_value, + + .open = op_open, + .close = op_close, + .get_configuration = op_get_configuration, + .set_configuration = op_set_configuration, + .claim_interface = op_claim_interface, + .release_interface = op_release_interface, + + .set_interface_altsetting = op_set_interface, + .clear_halt = op_clear_halt, + .reset_device = op_reset_device, + + .alloc_streams = op_alloc_streams, + .free_streams = op_free_streams, + + .dev_mem_alloc = op_dev_mem_alloc, + .dev_mem_free = op_dev_mem_free, + + .kernel_driver_active = op_kernel_driver_active, + .detach_kernel_driver = op_detach_kernel_driver, + .attach_kernel_driver = op_attach_kernel_driver, + + .destroy_device = op_destroy_device, + + .submit_transfer = op_submit_transfer, + .cancel_transfer = op_cancel_transfer, + .clear_transfer_priv = op_clear_transfer_priv, + + .handle_events = op_handle_events, + + .clock_gettime = op_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + .get_timerfd_clockid = op_get_timerfd_clockid, +#endif + + .device_priv_size = sizeof(struct linux_device_priv), + .device_handle_priv_size = sizeof(struct linux_device_handle_priv), + .transfer_priv_size = sizeof(struct linux_transfer_priv), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.h new file mode 100644 index 00000000..24496325 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/linux_usbfs.h @@ -0,0 +1,194 @@ +/* + * usbfs header structures + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_USBFS_H +#define LIBUSB_USBFS_H + +#include + +#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices" + +struct usbfs_ctrltransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + + uint32_t timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_bulktransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */ + unsigned int ep; + unsigned int len; + unsigned int timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_setinterface { + /* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */ + unsigned int interface; + unsigned int altsetting; +}; + +#define USBFS_MAXDRIVERNAME 255 + +struct usbfs_getdriver { + unsigned int interface; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +#define USBFS_URB_SHORT_NOT_OK 0x01 +#define USBFS_URB_ISO_ASAP 0x02 +#define USBFS_URB_BULK_CONTINUATION 0x04 +#define USBFS_URB_QUEUE_BULK 0x10 +#define USBFS_URB_ZERO_PACKET 0x40 + +enum usbfs_urb_type { + USBFS_URB_TYPE_ISO = 0, + USBFS_URB_TYPE_INTERRUPT = 1, + USBFS_URB_TYPE_CONTROL = 2, + USBFS_URB_TYPE_BULK = 3, +}; + +struct usbfs_iso_packet_desc { + unsigned int length; + unsigned int actual_length; + unsigned int status; +}; + +#define MAX_BULK_BUFFER_LENGTH 16384 +#define MAX_CTRL_BUFFER_LENGTH 4096 + +#define MAX_ISO_PACKETS_PER_URB 128 + +struct usbfs_urb { + unsigned char type; + unsigned char endpoint; + int status; + unsigned int flags; + void *buffer; + int buffer_length; + int actual_length; + int start_frame; + union { + int number_of_packets; /* Only used for isoc urbs */ + unsigned int stream_id; /* Only used with bulk streams */ + }; + int error_count; + unsigned int signr; + void *usercontext; + struct usbfs_iso_packet_desc iso_frame_desc[0]; +}; + +struct usbfs_connectinfo { + unsigned int devnum; + unsigned char slow; +}; + +struct usbfs_ioctl { + int ifno; /* interface 0..N ; negative numbers reserved */ + int ioctl_code; /* MUST encode size + direction of data so the + * macros in give correct values */ + void *data; /* param buffer (in, or out) */ +}; + +struct usbfs_hub_portinfo { + unsigned char numports; + unsigned char port[127]; /* port to device num mapping */ +}; + +#define USBFS_CAP_ZERO_PACKET 0x01 +#define USBFS_CAP_BULK_CONTINUATION 0x02 +#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04 +#define USBFS_CAP_BULK_SCATTER_GATHER 0x08 +#define USBFS_CAP_REAP_AFTER_DISCONNECT 0x10 + +#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01 +#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02 + +struct usbfs_disconnect_claim { + unsigned int interface; + unsigned int flags; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +struct usbfs_streams { + unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */ + unsigned int num_eps; + unsigned char eps[0]; +}; + +#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer) +#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer) +#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int) +#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface) +#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int) +#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver) +#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb) +#define IOCTL_USBFS_DISCARDURB _IO('U', 11) +#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *) +#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *) +#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int) +#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int) +#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo) +#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl) +#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo) +#define IOCTL_USBFS_RESET _IO('U', 20) +#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int) +#define IOCTL_USBFS_DISCONNECT _IO('U', 22) +#define IOCTL_USBFS_CONNECT _IO('U', 23) +#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int) +#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int) +#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32) +#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim) +#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams) +#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams) + +extern usbi_mutex_static_t linux_hotplug_lock; + +#if defined(HAVE_LIBUDEV) +int linux_udev_start_event_monitor(void); +int linux_udev_stop_event_monitor(void); +int linux_udev_scan_devices(struct libusb_context *ctx); +void linux_udev_hotplug_poll(void); +#else +int linux_netlink_start_event_monitor(void); +int linux_netlink_stop_event_monitor(void); +void linux_netlink_hotplug_poll(void); +#endif + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name); +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr); + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr, const char *dev_node, + const char *sys_name); +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir); + +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/netbsd_usb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/netbsd_usb.c new file mode 100644 index 00000000..d9c059a7 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/netbsd_usb.c @@ -0,0 +1,677 @@ +/* + * Copyright © 2011 Martin Pieuchot + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "libusbi.h" + +struct device_priv { + char devnode[16]; + int fd; + + unsigned char *cdesc; /* active config descriptor */ + usb_device_descriptor_t ddesc; /* usb device descriptor */ +}; + +struct handle_priv { + int endpoints[USB_MAX_ENDPOINTS]; +}; + +/* + * Backend functions + */ +static int netbsd_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int netbsd_open(struct libusb_device_handle *); +static void netbsd_close(struct libusb_device_handle *); + +static int netbsd_get_device_descriptor(struct libusb_device *, unsigned char *, + int *); +static int netbsd_get_active_config_descriptor(struct libusb_device *, + unsigned char *, size_t, int *); +static int netbsd_get_config_descriptor(struct libusb_device *, uint8_t, + unsigned char *, size_t, int *); + +static int netbsd_get_configuration(struct libusb_device_handle *, int *); +static int netbsd_set_configuration(struct libusb_device_handle *, int); + +static int netbsd_claim_interface(struct libusb_device_handle *, int); +static int netbsd_release_interface(struct libusb_device_handle *, int); + +static int netbsd_set_interface_altsetting(struct libusb_device_handle *, int, + int); +static int netbsd_clear_halt(struct libusb_device_handle *, unsigned char); +static int netbsd_reset_device(struct libusb_device_handle *); +static void netbsd_destroy_device(struct libusb_device *); + +static int netbsd_submit_transfer(struct usbi_transfer *); +static int netbsd_cancel_transfer(struct usbi_transfer *); +static void netbsd_clear_transfer_priv(struct usbi_transfer *); +static int netbsd_handle_transfer_completion(struct usbi_transfer *); +static int netbsd_clock_gettime(int, struct timespec *); + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int _cache_active_config_descriptor(struct libusb_device *, int); +static int _sync_control_transfer(struct usbi_transfer *); +static int _sync_gen_transfer(struct usbi_transfer *); +static int _access_endpoint(struct libusb_transfer *); + +const struct usbi_os_backend usbi_backend = { + "Synchronous NetBSD backend", + 0, + NULL, /* init() */ + NULL, /* exit() */ + NULL, /* set_option() */ + netbsd_get_device_list, + NULL, /* hotplug_poll */ + netbsd_open, + netbsd_close, + + netbsd_get_device_descriptor, + netbsd_get_active_config_descriptor, + netbsd_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + netbsd_get_configuration, + netbsd_set_configuration, + + netbsd_claim_interface, + netbsd_release_interface, + + netbsd_set_interface_altsetting, + netbsd_clear_halt, + netbsd_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + NULL, /* kernel_driver_active() */ + NULL, /* detach_kernel_driver() */ + NULL, /* attach_kernel_driver() */ + + netbsd_destroy_device, + + netbsd_submit_transfer, + netbsd_cancel_transfer, + netbsd_clear_transfer_priv, + + NULL, /* handle_events() */ + netbsd_handle_transfer_completion, + + netbsd_clock_gettime, + 0, /* context_priv_size */ + sizeof(struct device_priv), + sizeof(struct handle_priv), + 0, /* transfer_priv_size */ +}; + +int +netbsd_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + struct libusb_device *dev; + struct device_priv *dpriv; + struct usb_device_info di; + unsigned long session_id; + char devnode[16]; + int fd, err, i; + + usbi_dbg(""); + + /* Only ugen(4) is supported */ + for (i = 0; i < USB_MAX_DEVICES; i++) { + /* Control endpoint is always .00 */ + snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i); + + if ((fd = open(devnode, O_RDONLY)) < 0) { + if (errno != ENOENT && errno != ENXIO) + usbi_err(ctx, "could not open %s", devnode); + continue; + } + + if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0) + continue; + + session_id = (di.udi_bus << 8 | di.udi_addr); + dev = usbi_get_device_by_session_id(ctx, session_id); + + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) + return (LIBUSB_ERROR_NO_MEM); + + dev->bus_number = di.udi_bus; + dev->device_address = di.udi_addr; + dev->speed = di.udi_speed; + + dpriv = (struct device_priv *)dev->os_priv; + strlcpy(dpriv->devnode, devnode, sizeof(devnode)); + dpriv->fd = -1; + + if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) { + err = errno; + goto error; + } + + dpriv->cdesc = NULL; + if (_cache_active_config_descriptor(dev, fd)) { + err = errno; + goto error; + } + + if ((err = usbi_sanitize_device(dev))) + goto error; + } + close(fd); + + if (discovered_devs_append(*discdevs, dev) == NULL) + return (LIBUSB_ERROR_NO_MEM); + + libusb_unref_device(dev); + } + + return (LIBUSB_SUCCESS); + +error: + close(fd); + libusb_unref_device(dev); + return _errno_to_libusb(err); +} + +int +netbsd_open(struct libusb_device_handle *handle) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + dpriv->fd = open(dpriv->devnode, O_RDWR); + if (dpriv->fd < 0) { + dpriv->fd = open(dpriv->devnode, O_RDONLY); + if (dpriv->fd < 0) + return _errno_to_libusb(errno); + } + + usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd); + + return (LIBUSB_SUCCESS); +} + +void +netbsd_close(struct libusb_device_handle *handle) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg("close: fd %d", dpriv->fd); + + close(dpriv->fd); + dpriv->fd = -1; +} + +int +netbsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, + int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +netbsd_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + usb_config_descriptor_t *ucd; + + ucd = (usb_config_descriptor_t *) dpriv->cdesc; + len = MIN(len, UGETW(ucd->wTotalLength)); + + usbi_dbg("len %d", len); + + memcpy(buf, dpriv->cdesc, len); + + *host_endian = 0; + + return len; +} + +int +netbsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_full_desc ufd; + int fd, err; + + usbi_dbg("index %d, len %d", idx, len); + + /* A config descriptor may be requested before opening the device */ + if (dpriv->fd >= 0) { + fd = dpriv->fd; + } else { + fd = open(dpriv->devnode, O_RDONLY); + if (fd < 0) + return _errno_to_libusb(errno); + } + + ufd.ufd_config_index = idx; + ufd.ufd_size = len; + ufd.ufd_data = buf; + + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { + err = errno; + if (dpriv->fd < 0) + close(fd); + return _errno_to_libusb(err); + } + + if (dpriv->fd < 0) + close(fd); + + *host_endian = 0; + + return len; +} + +int +netbsd_get_configuration(struct libusb_device_handle *handle, int *config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg(""); + + if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("configuration %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + usbi_dbg("configuration %d", config); + + if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) + return _errno_to_libusb(errno); + + return _cache_active_config_descriptor(handle->dev, dpriv->fd); +} + +int +netbsd_claim_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + hpriv->endpoints[i] = -1; + + return (LIBUSB_SUCCESS); +} + +int +netbsd_release_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + if (hpriv->endpoints[i] >= 0) + close(hpriv->endpoints[i]); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_alt_interface intf; + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + memset(&intf, 0, sizeof(intf)); + + intf.uai_interface_index = iface; + intf.uai_alt_no = altsetting; + + if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_ctl_request req; + + usbi_dbg(""); + + req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + req.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(req.ucr_request.wIndex, endpoint); + USETW(req.ucr_request.wLength, 0); + + if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +netbsd_destroy_device(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + free(dpriv->cdesc); +} + +int +netbsd_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct handle_priv *hpriv; + int err = 0; + + usbi_dbg(""); + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + err = _sync_control_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (IS_XFEROUT(transfer)) { + /* Isochronous write is not supported */ + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + if (err) + return (err); + + usbi_signal_transfer_completion(itransfer); + + return (LIBUSB_SUCCESS); +} + +int +netbsd_cancel_transfer(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +netbsd_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +netbsd_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +netbsd_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + } + + usbi_dbg("error: %s", strerror(err)); + + return (LIBUSB_ERROR_OTHER); +} + +int +_cache_active_config_descriptor(struct libusb_device *dev, int fd) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_config_desc ucd; + struct usb_full_desc ufd; + unsigned char* buf; + int len; + + usbi_dbg("fd %d", fd); + + ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX; + + if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("active bLength %d", ucd.ucd_desc.bLength); + + len = UGETW(ucd.ucd_desc.wTotalLength); + buf = malloc(len); + if (buf == NULL) + return (LIBUSB_ERROR_NO_MEM); + + ufd.ufd_config_index = ucd.ucd_config_index; + ufd.ufd_size = len; + ufd.ufd_data = buf; + + usbi_dbg("index %d, len %d", ufd.ufd_config_index, len); + + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { + free(buf); + return _errno_to_libusb(errno); + } + + if (dpriv->cdesc) + free(dpriv->cdesc); + dpriv->cdesc = buf; + + return (0); +} + +int +_sync_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_control_setup *setup; + struct device_priv *dpriv; + struct usb_ctl_request req; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + setup = (struct libusb_control_setup *)transfer->buffer; + + usbi_dbg("type %d request %d value %d index %d length %d timeout %d", + setup->bmRequestType, setup->bRequest, + libusb_le16_to_cpu(setup->wValue), + libusb_le16_to_cpu(setup->wIndex), + libusb_le16_to_cpu(setup->wLength), transfer->timeout); + + req.ucr_request.bmRequestType = setup->bmRequestType; + req.ucr_request.bRequest = setup->bRequest; + /* Don't use USETW, libusb already deals with the endianness */ + (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; + (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; + (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; + req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + req.ucr_flags = USBD_SHORT_XFER_OK; + + if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = req.ucr_actlen; + + usbi_dbg("transferred %d", itransfer->transferred); + + return (0); +} + +int +_access_endpoint(struct libusb_transfer *transfer) +{ + struct handle_priv *hpriv; + struct device_priv *dpriv; + char *s, devnode[16]; + int fd, endpt; + mode_t mode; + + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + endpt = UE_GET_ADDR(transfer->endpoint); + mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; + + usbi_dbg("endpoint %d mode %d", endpt, mode); + + if (hpriv->endpoints[endpt] < 0) { + /* Pick the right node given the control one */ + strlcpy(devnode, dpriv->devnode, sizeof(devnode)); + s = strchr(devnode, '.'); + snprintf(s, 4, ".%02d", endpt); + + /* We may need to read/write to the same endpoint later. */ + if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) + if ((fd = open(devnode, mode)) < 0) + return (-1); + + hpriv->endpoints[endpt] = fd; + } + + return (hpriv->endpoints[endpt]); +} + +int +_sync_gen_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + int fd, nr = 1; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + /* + * Bulk, Interrupt or Isochronous transfer depends on the + * endpoint and thus the node to open. + */ + if ((fd = _access_endpoint(transfer)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if (IS_XFERIN(transfer)) { + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) + return _errno_to_libusb(errno); + + nr = read(fd, transfer->buffer, transfer->length); + } else { + nr = write(fd, transfer->buffer, transfer->length); + } + + if (nr < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = nr; + + return (0); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/openbsd_usb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/openbsd_usb.c new file mode 100644 index 00000000..f174e496 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/openbsd_usb.c @@ -0,0 +1,771 @@ +/* + * Copyright © 2011-2013 Martin Pieuchot + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "libusbi.h" + +struct device_priv { + char *devname; /* name of the ugen(4) node */ + int fd; /* device file descriptor */ + + unsigned char *cdesc; /* active config descriptor */ + usb_device_descriptor_t ddesc; /* usb device descriptor */ +}; + +struct handle_priv { + int endpoints[USB_MAX_ENDPOINTS]; +}; + +/* + * Backend functions + */ +static int obsd_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int obsd_open(struct libusb_device_handle *); +static void obsd_close(struct libusb_device_handle *); + +static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *, + int *); +static int obsd_get_active_config_descriptor(struct libusb_device *, + unsigned char *, size_t, int *); +static int obsd_get_config_descriptor(struct libusb_device *, uint8_t, + unsigned char *, size_t, int *); + +static int obsd_get_configuration(struct libusb_device_handle *, int *); +static int obsd_set_configuration(struct libusb_device_handle *, int); + +static int obsd_claim_interface(struct libusb_device_handle *, int); +static int obsd_release_interface(struct libusb_device_handle *, int); + +static int obsd_set_interface_altsetting(struct libusb_device_handle *, int, + int); +static int obsd_clear_halt(struct libusb_device_handle *, unsigned char); +static int obsd_reset_device(struct libusb_device_handle *); +static void obsd_destroy_device(struct libusb_device *); + +static int obsd_submit_transfer(struct usbi_transfer *); +static int obsd_cancel_transfer(struct usbi_transfer *); +static void obsd_clear_transfer_priv(struct usbi_transfer *); +static int obsd_handle_transfer_completion(struct usbi_transfer *); +static int obsd_clock_gettime(int, struct timespec *); + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int _cache_active_config_descriptor(struct libusb_device *); +static int _sync_control_transfer(struct usbi_transfer *); +static int _sync_gen_transfer(struct usbi_transfer *); +static int _access_endpoint(struct libusb_transfer *); + +static int _bus_open(int); + + +const struct usbi_os_backend usbi_backend = { + "Synchronous OpenBSD backend", + 0, + NULL, /* init() */ + NULL, /* exit() */ + NULL, /* set_option() */ + obsd_get_device_list, + NULL, /* hotplug_poll */ + obsd_open, + obsd_close, + + obsd_get_device_descriptor, + obsd_get_active_config_descriptor, + obsd_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + obsd_get_configuration, + obsd_set_configuration, + + obsd_claim_interface, + obsd_release_interface, + + obsd_set_interface_altsetting, + obsd_clear_halt, + obsd_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + NULL, /* kernel_driver_active() */ + NULL, /* detach_kernel_driver() */ + NULL, /* attach_kernel_driver() */ + + obsd_destroy_device, + + obsd_submit_transfer, + obsd_cancel_transfer, + obsd_clear_transfer_priv, + + NULL, /* handle_events() */ + obsd_handle_transfer_completion, + + obsd_clock_gettime, + 0, /* context_priv_size */ + sizeof(struct device_priv), + sizeof(struct handle_priv), + 0, /* transfer_priv_size */ +}; + +#define DEVPATH "/dev/" +#define USBDEV DEVPATH "usb" + +int +obsd_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + struct discovered_devs *ddd; + struct libusb_device *dev; + struct device_priv *dpriv; + struct usb_device_info di; + struct usb_device_ddesc dd; + unsigned long session_id; + char devices[USB_MAX_DEVICES]; + char busnode[16]; + char *udevname; + int fd, addr, i, j; + + usbi_dbg(""); + + for (i = 0; i < 8; i++) { + snprintf(busnode, sizeof(busnode), USBDEV "%d", i); + + if ((fd = open(busnode, O_RDWR)) < 0) { + if (errno != ENOENT && errno != ENXIO) + usbi_err(ctx, "could not open %s", busnode); + continue; + } + + bzero(devices, sizeof(devices)); + for (addr = 1; addr < USB_MAX_DEVICES; addr++) { + if (devices[addr]) + continue; + + di.udi_addr = addr; + if (ioctl(fd, USB_DEVICEINFO, &di) < 0) + continue; + + /* + * XXX If ugen(4) is attached to the USB device + * it will be used. + */ + udevname = NULL; + for (j = 0; j < USB_MAX_DEVNAMES; j++) + if (!strncmp("ugen", di.udi_devnames[j], 4)) { + udevname = strdup(di.udi_devnames[j]); + break; + } + + session_id = (di.udi_bus << 8 | di.udi_addr); + dev = usbi_get_device_by_session_id(ctx, session_id); + + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) { + close(fd); + return (LIBUSB_ERROR_NO_MEM); + } + + dev->bus_number = di.udi_bus; + dev->device_address = di.udi_addr; + dev->speed = di.udi_speed; + + dpriv = (struct device_priv *)dev->os_priv; + dpriv->fd = -1; + dpriv->cdesc = NULL; + dpriv->devname = udevname; + + dd.udd_bus = di.udi_bus; + dd.udd_addr = di.udi_addr; + if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) { + libusb_unref_device(dev); + continue; + } + dpriv->ddesc = dd.udd_desc; + + if (_cache_active_config_descriptor(dev)) { + libusb_unref_device(dev); + continue; + } + + if (usbi_sanitize_device(dev)) { + libusb_unref_device(dev); + continue; + } + } + + ddd = discovered_devs_append(*discdevs, dev); + if (ddd == NULL) { + close(fd); + return (LIBUSB_ERROR_NO_MEM); + } + libusb_unref_device(dev); + + *discdevs = ddd; + devices[addr] = 1; + } + + close(fd); + } + + return (LIBUSB_SUCCESS); +} + +int +obsd_open(struct libusb_device_handle *handle) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + char devnode[16]; + + if (dpriv->devname) { + /* + * Only open ugen(4) attached devices read-write, all + * read-only operations are done through the bus node. + */ + snprintf(devnode, sizeof(devnode), DEVPATH "%s.00", + dpriv->devname); + dpriv->fd = open(devnode, O_RDWR); + if (dpriv->fd < 0) + return _errno_to_libusb(errno); + + usbi_dbg("open %s: fd %d", devnode, dpriv->fd); + } + + return (LIBUSB_SUCCESS); +} + +void +obsd_close(struct libusb_device_handle *handle) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + if (dpriv->devname) { + usbi_dbg("close: fd %d", dpriv->fd); + + close(dpriv->fd); + dpriv->fd = -1; + } +} + +int +obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, + int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); + + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +obsd_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buf, size_t len, int *host_endian) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; + + len = MIN(len, UGETW(ucd->wTotalLength)); + + usbi_dbg("len %d", len); + + memcpy(buf, dpriv->cdesc, len); + + *host_endian = 0; + + return (len); +} + +int +obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + unsigned char *buf, size_t len, int *host_endian) +{ + struct usb_device_fdesc udf; + int fd, err; + + if ((fd = _bus_open(dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + udf.udf_bus = dev->bus_number; + udf.udf_addr = dev->device_address; + udf.udf_config_index = idx; + udf.udf_size = len; + udf.udf_data = buf; + + usbi_dbg("index %d, len %d", udf.udf_config_index, len); + + if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + + *host_endian = 0; + + return (len); +} + +int +obsd_get_configuration(struct libusb_device_handle *handle, int *config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; + + *config = ucd->bConfigurationValue; + + usbi_dbg("bConfigurationValue %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +obsd_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + usbi_dbg("bConfigurationValue %d", config); + + if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) + return _errno_to_libusb(errno); + + return _cache_active_config_descriptor(handle->dev); +} + +int +obsd_claim_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + hpriv->endpoints[i] = -1; + + return (LIBUSB_SUCCESS); +} + +int +obsd_release_interface(struct libusb_device_handle *handle, int iface) +{ + struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; + int i; + + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + if (hpriv->endpoints[i] >= 0) + close(hpriv->endpoints[i]); + + return (LIBUSB_SUCCESS); +} + +int +obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; + struct usb_alt_interface intf; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + memset(&intf, 0, sizeof(intf)); + + intf.uai_interface_index = iface; + intf.uai_alt_no = altsetting; + + if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) + return _errno_to_libusb(errno); + + return (LIBUSB_SUCCESS); +} + +int +obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) +{ + struct usb_ctl_request req; + int fd, err; + + if ((fd = _bus_open(handle->dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg(""); + + req.ucr_addr = handle->dev->device_address; + req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + req.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(req.ucr_request.wIndex, endpoint); + USETW(req.ucr_request.wLength, 0); + + if (ioctl(fd, USB_REQUEST, &req) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + + return (LIBUSB_SUCCESS); +} + +int +obsd_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +obsd_destroy_device(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + + usbi_dbg(""); + + free(dpriv->cdesc); + free(dpriv->devname); +} + +int +obsd_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct handle_priv *hpriv; + int err = 0; + + usbi_dbg(""); + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + err = _sync_control_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (IS_XFEROUT(transfer)) { + /* Isochronous write is not supported */ + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + err = _sync_gen_transfer(itransfer); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + if (err) + return (err); + + usbi_signal_transfer_completion(itransfer); + + return (LIBUSB_SUCCESS); +} + +int +obsd_cancel_transfer(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +obsd_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +obsd_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +obsd_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + usbi_dbg("error: %s (%d)", strerror(err), err); + + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + case ETIMEDOUT: + return (LIBUSB_ERROR_TIMEOUT); + } + + return (LIBUSB_ERROR_OTHER); +} + +int +_cache_active_config_descriptor(struct libusb_device *dev) +{ + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_device_cdesc udc; + struct usb_device_fdesc udf; + unsigned char* buf; + int fd, len, err; + + if ((fd = _bus_open(dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("fd %d, addr %d", fd, dev->device_address); + + udc.udc_bus = dev->bus_number; + udc.udc_addr = dev->device_address; + udc.udc_config_index = USB_CURRENT_CONFIG_INDEX; + if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(errno); + } + + usbi_dbg("active bLength %d", udc.udc_desc.bLength); + + len = UGETW(udc.udc_desc.wTotalLength); + buf = malloc(len); + if (buf == NULL) + return (LIBUSB_ERROR_NO_MEM); + + udf.udf_bus = dev->bus_number; + udf.udf_addr = dev->device_address; + udf.udf_config_index = udc.udc_config_index; + udf.udf_size = len; + udf.udf_data = buf; + + usbi_dbg("index %d, len %d", udf.udf_config_index, len); + + if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { + err = errno; + close(fd); + free(buf); + return _errno_to_libusb(err); + } + close(fd); + + if (dpriv->cdesc) + free(dpriv->cdesc); + dpriv->cdesc = buf; + + return (LIBUSB_SUCCESS); +} + +int +_sync_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_control_setup *setup; + struct device_priv *dpriv; + struct usb_ctl_request req; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + setup = (struct libusb_control_setup *)transfer->buffer; + + usbi_dbg("type %x request %x value %x index %d length %d timeout %d", + setup->bmRequestType, setup->bRequest, + libusb_le16_to_cpu(setup->wValue), + libusb_le16_to_cpu(setup->wIndex), + libusb_le16_to_cpu(setup->wLength), transfer->timeout); + + req.ucr_addr = transfer->dev_handle->dev->device_address; + req.ucr_request.bmRequestType = setup->bmRequestType; + req.ucr_request.bRequest = setup->bRequest; + /* Don't use USETW, libusb already deals with the endianness */ + (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; + (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; + (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; + req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; + + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + req.ucr_flags = USBD_SHORT_XFER_OK; + + if (dpriv->devname == NULL) { + /* + * XXX If the device is not attached to ugen(4) it is + * XXX still possible to submit a control transfer but + * XXX with the default timeout only. + */ + int fd, err; + + if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_REQUEST, &req)) < 0) { + err = errno; + close(fd); + return _errno_to_libusb(err); + } + close(fd); + } else { + if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) + return _errno_to_libusb(errno); + } + + itransfer->transferred = req.ucr_actlen; + + usbi_dbg("transferred %d", itransfer->transferred); + + return (0); +} + +int +_access_endpoint(struct libusb_transfer *transfer) +{ + struct handle_priv *hpriv; + struct device_priv *dpriv; + char devnode[16]; + int fd, endpt; + mode_t mode; + + hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + endpt = UE_GET_ADDR(transfer->endpoint); + mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; + + usbi_dbg("endpoint %d mode %d", endpt, mode); + + if (hpriv->endpoints[endpt] < 0) { + /* Pick the right endpoint node */ + snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", + dpriv->devname, endpt); + + /* We may need to read/write to the same endpoint later. */ + if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) + if ((fd = open(devnode, mode)) < 0) + return (-1); + + hpriv->endpoints[endpt] = fd; + } + + return (hpriv->endpoints[endpt]); +} + +int +_sync_gen_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct device_priv *dpriv; + int fd, nr = 1; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; + + if (dpriv->devname == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + /* + * Bulk, Interrupt or Isochronous transfer depends on the + * endpoint and thus the node to open. + */ + if ((fd = _access_endpoint(transfer)) < 0) + return _errno_to_libusb(errno); + + if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); + + if (IS_XFERIN(transfer)) { + if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) + if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) + return _errno_to_libusb(errno); + + nr = read(fd, transfer->buffer, transfer->length); + } else { + nr = write(fd, transfer->buffer, transfer->length); + } + + if (nr < 0) + return _errno_to_libusb(errno); + + itransfer->transferred = nr; + + return (0); +} + +int +_bus_open(int number) +{ + char busnode[16]; + + snprintf(busnode, sizeof(busnode), USBDEV "%d", number); + + return open(busnode, O_RDWR); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.c new file mode 100644 index 00000000..337714aa --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.c @@ -0,0 +1,84 @@ +/* + * poll_posix: poll compatibility wrapper for POSIX systems + * Copyright © 2013 RealVNC Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +int usbi_pipe(int pipefd[2]) +{ +#if defined(HAVE_PIPE2) + int ret = pipe2(pipefd, O_CLOEXEC); +#else + int ret = pipe(pipefd); +#endif + + if (ret != 0) { + usbi_err(NULL, "failed to create pipe (%d)", errno); + return ret; + } + +#if !defined(HAVE_PIPE2) && defined(FD_CLOEXEC) + ret = fcntl(pipefd[0], F_GETFD); + if (ret == -1) { + usbi_err(NULL, "failed to get pipe fd flags (%d)", errno); + goto err_close_pipe; + } + ret = fcntl(pipefd[0], F_SETFD, ret | FD_CLOEXEC); + if (ret == -1) { + usbi_err(NULL, "failed to set pipe fd flags (%d)", errno); + goto err_close_pipe; + } + + ret = fcntl(pipefd[1], F_GETFD); + if (ret == -1) { + usbi_err(NULL, "failed to get pipe fd flags (%d)", errno); + goto err_close_pipe; + } + ret = fcntl(pipefd[1], F_SETFD, ret | FD_CLOEXEC); + if (ret == -1) { + usbi_err(NULL, "failed to set pipe fd flags (%d)", errno); + goto err_close_pipe; + } +#endif + + ret = fcntl(pipefd[1], F_GETFL); + if (ret == -1) { + usbi_err(NULL, "failed to get pipe fd status flags (%d)", errno); + goto err_close_pipe; + } + ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK); + if (ret == -1) { + usbi_err(NULL, "failed to set pipe fd status flags (%d)", errno); + goto err_close_pipe; + } + + return 0; + +err_close_pipe: + close(pipefd[0]); + close(pipefd[1]); + return ret; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.h new file mode 100644 index 00000000..5b4b2c90 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_posix.h @@ -0,0 +1,11 @@ +#ifndef LIBUSB_POLL_POSIX_H +#define LIBUSB_POLL_POSIX_H + +#define usbi_write write +#define usbi_read read +#define usbi_close close +#define usbi_poll poll + +int usbi_pipe(int pipefd[2]); + +#endif /* LIBUSB_POLL_POSIX_H */ diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.c new file mode 100644 index 00000000..4d283333 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.c @@ -0,0 +1,364 @@ +/* + * poll_windows: poll compatibility wrapper for Windows + * Copyright © 2017 Chris Dickens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + * poll() and pipe() Windows compatibility layer for libusb 1.0 + * + * The way this layer works is by using OVERLAPPED with async I/O transfers, as + * OVERLAPPED have an associated event which is flagged for I/O completion. + * + * For USB pollable async I/O, you would typically: + * - obtain a Windows HANDLE to a file or device that has been opened in + * OVERLAPPED mode + * - call usbi_create_fd with this handle to obtain a custom fd. + * - leave the core functions call the poll routine and flag POLLIN/POLLOUT + * + * The pipe pollable synchronous I/O works using the overlapped event associated + * with a fake pipe. The read/write functions are only meant to be used in that + * context. + */ +#include + +#include +#include +#include + +#include "libusbi.h" +#include "windows_common.h" + +// public fd data +const struct winfd INVALID_WINFD = { -1, NULL }; + +// private data +struct file_descriptor { + enum fd_type { FD_TYPE_PIPE, FD_TYPE_TRANSFER } type; + OVERLAPPED overlapped; +}; + +static usbi_mutex_static_t fd_table_lock = USBI_MUTEX_INITIALIZER; +static struct file_descriptor *fd_table[MAX_FDS]; + +static struct file_descriptor *create_fd(enum fd_type type) +{ + struct file_descriptor *fd = calloc(1, sizeof(*fd)); + if (fd == NULL) + return NULL; + fd->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (fd->overlapped.hEvent == NULL) { + free(fd); + return NULL; + } + fd->type = type; + return fd; +} + +static void free_fd(struct file_descriptor *fd) +{ + CloseHandle(fd->overlapped.hEvent); + free(fd); +} + +/* + * Create both an fd and an OVERLAPPED, so that it can be used with our + * polling function + * The handle MUST support overlapped transfers (usually requires CreateFile + * with FILE_FLAG_OVERLAPPED) + * Return a pollable file descriptor struct, or INVALID_WINFD on error + * + * Note that the fd returned by this function is a per-transfer fd, rather + * than a per-session fd and cannot be used for anything else but our + * custom functions. + * if you plan to do R/W on the same handle, you MUST create 2 fds: one for + * read and one for write. Using a single R/W fd is unsupported and will + * produce unexpected results + */ +struct winfd usbi_create_fd(void) +{ + struct file_descriptor *fd; + struct winfd wfd; + + fd = create_fd(FD_TYPE_TRANSFER); + if (fd == NULL) + return INVALID_WINFD; + + usbi_mutex_static_lock(&fd_table_lock); + for (wfd.fd = 0; wfd.fd < MAX_FDS; wfd.fd++) { + if (fd_table[wfd.fd] != NULL) + continue; + fd_table[wfd.fd] = fd; + break; + } + usbi_mutex_static_unlock(&fd_table_lock); + + if (wfd.fd == MAX_FDS) { + free_fd(fd); + return INVALID_WINFD; + } + + wfd.overlapped = &fd->overlapped; + + return wfd; +} + +static int check_pollfds(struct pollfd *fds, unsigned int nfds, + HANDLE *wait_handles, DWORD *nb_wait_handles) +{ + struct file_descriptor *fd; + unsigned int n; + int nready = 0; + + usbi_mutex_static_lock(&fd_table_lock); + + for (n = 0; n < nfds; ++n) { + fds[n].revents = 0; + + // Keep it simple - only allow either POLLIN *or* POLLOUT + assert((fds[n].events == POLLIN) || (fds[n].events == POLLOUT)); + if ((fds[n].events != POLLIN) && (fds[n].events != POLLOUT)) { + fds[n].revents = POLLNVAL; + nready++; + continue; + } + + if ((fds[n].fd >= 0) && (fds[n].fd < MAX_FDS)) + fd = fd_table[fds[n].fd]; + else + fd = NULL; + + assert(fd != NULL); + if (fd == NULL) { + fds[n].revents = POLLNVAL; + nready++; + continue; + } + + if (HasOverlappedIoCompleted(&fd->overlapped) + && (WaitForSingleObject(fd->overlapped.hEvent, 0) == WAIT_OBJECT_0)) { + fds[n].revents = fds[n].events; + nready++; + } else if (wait_handles != NULL) { + if (*nb_wait_handles == MAXIMUM_WAIT_OBJECTS) { + usbi_warn(NULL, "too many HANDLEs to wait on"); + continue; + } + wait_handles[*nb_wait_handles] = fd->overlapped.hEvent; + (*nb_wait_handles)++; + } + } + + usbi_mutex_static_unlock(&fd_table_lock); + + return nready; +} +/* + * POSIX poll equivalent, using Windows OVERLAPPED + * Currently, this function only accepts one of POLLIN or POLLOUT per fd + * (but you can create multiple fds from the same handle for read and write) + */ +int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout) +{ + HANDLE wait_handles[MAXIMUM_WAIT_OBJECTS]; + DWORD nb_wait_handles = 0; + DWORD ret; + int nready; + + nready = check_pollfds(fds, nfds, wait_handles, &nb_wait_handles); + + // If nothing was triggered, wait on all fds that require it + if ((nready == 0) && (nb_wait_handles != 0) && (timeout != 0)) { + ret = WaitForMultipleObjects(nb_wait_handles, wait_handles, + FALSE, (timeout < 0) ? INFINITE : (DWORD)timeout); + if (ret < (WAIT_OBJECT_0 + nb_wait_handles)) { + nready = check_pollfds(fds, nfds, NULL, NULL); + } else if (ret != WAIT_TIMEOUT) { + if (ret == WAIT_FAILED) + usbi_err(NULL, "WaitForMultipleObjects failed: %u", (unsigned int)GetLastError()); + nready = -1; + } + } + + return nready; +} + +/* + * close a fake file descriptor + */ +int usbi_close(int _fd) +{ + struct file_descriptor *fd; + + if (_fd < 0 || _fd >= MAX_FDS) + goto err_badfd; + + usbi_mutex_static_lock(&fd_table_lock); + fd = fd_table[_fd]; + fd_table[_fd] = NULL; + usbi_mutex_static_unlock(&fd_table_lock); + + if (fd == NULL) + goto err_badfd; + + if (fd->type == FD_TYPE_PIPE) { + // InternalHigh is our reference count + fd->overlapped.InternalHigh--; + if (fd->overlapped.InternalHigh == 0) + free_fd(fd); + } else { + free_fd(fd); + } + + return 0; + +err_badfd: + errno = EBADF; + return -1; +} + +/* +* Create a fake pipe. +* As libusb only uses pipes for signaling, all we need from a pipe is an +* event. To that extent, we create a single wfd and overlapped as a means +* to access that event. +*/ +int usbi_pipe(int filedes[2]) +{ + struct file_descriptor *fd; + int r_fd = -1, w_fd = -1; + int i; + + fd = create_fd(FD_TYPE_PIPE); + if (fd == NULL) { + errno = ENOMEM; + return -1; + } + + // Use InternalHigh as a reference count + fd->overlapped.Internal = STATUS_PENDING; + fd->overlapped.InternalHigh = 2; + + usbi_mutex_static_lock(&fd_table_lock); + do { + for (i = 0; i < MAX_FDS; i++) { + if (fd_table[i] != NULL) + continue; + if (r_fd == -1) { + r_fd = i; + } else if (w_fd == -1) { + w_fd = i; + break; + } + } + + if (i == MAX_FDS) + break; + + fd_table[r_fd] = fd; + fd_table[w_fd] = fd; + + } while (0); + usbi_mutex_static_unlock(&fd_table_lock); + + if (i == MAX_FDS) { + free_fd(fd); + errno = EMFILE; + return -1; + } + + filedes[0] = r_fd; + filedes[1] = w_fd; + + return 0; +} + +/* + * synchronous write for fake "pipe" signaling + */ +ssize_t usbi_write(int fd, const void *buf, size_t count) +{ + int error = EBADF; + + UNUSED(buf); + + if (fd < 0 || fd >= MAX_FDS) + goto err_out; + + if (count != sizeof(unsigned char)) { + usbi_err(NULL, "this function should only used for signaling"); + error = EINVAL; + goto err_out; + } + + usbi_mutex_static_lock(&fd_table_lock); + if ((fd_table[fd] != NULL) && (fd_table[fd]->type == FD_TYPE_PIPE)) { + assert(fd_table[fd]->overlapped.Internal == STATUS_PENDING); + assert(fd_table[fd]->overlapped.InternalHigh == 2); + fd_table[fd]->overlapped.Internal = STATUS_WAIT_0; + SetEvent(fd_table[fd]->overlapped.hEvent); + error = 0; + } + usbi_mutex_static_unlock(&fd_table_lock); + + if (error) + goto err_out; + + return sizeof(unsigned char); + +err_out: + errno = error; + return -1; +} + +/* + * synchronous read for fake "pipe" signaling + */ +ssize_t usbi_read(int fd, void *buf, size_t count) +{ + int error = EBADF; + + UNUSED(buf); + + if (fd < 0 || fd >= MAX_FDS) + goto err_out; + + if (count != sizeof(unsigned char)) { + usbi_err(NULL, "this function should only used for signaling"); + error = EINVAL; + goto err_out; + } + + usbi_mutex_static_lock(&fd_table_lock); + if ((fd_table[fd] != NULL) && (fd_table[fd]->type == FD_TYPE_PIPE)) { + assert(fd_table[fd]->overlapped.Internal == STATUS_WAIT_0); + assert(fd_table[fd]->overlapped.InternalHigh == 2); + fd_table[fd]->overlapped.Internal = STATUS_PENDING; + ResetEvent(fd_table[fd]->overlapped.hEvent); + error = 0; + } + usbi_mutex_static_unlock(&fd_table_lock); + + if (error) + goto err_out; + + return sizeof(unsigned char); + +err_out: + errno = error; + return -1; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.h new file mode 100644 index 00000000..bd22c7f6 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/poll_windows.h @@ -0,0 +1,97 @@ +/* + * Windows compat: POSIX compatibility wrapper + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2010 Pete Batard + * Copyright © 2016-2018 Chris Dickens + * With contributions from Michael Plante, Orin Eman et al. + * Parts of poll implementation from libusb-win32, by Stephan Meyer et al. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#pragma once + +#if defined(_MSC_VER) +// disable /W4 MSVC warnings that are benign +#pragma warning(disable:4127) // conditional expression is constant +#endif + +// Handle synchronous completion through the overlapped structure +#if !defined(STATUS_REPARSE) // reuse the REPARSE status code +#define STATUS_REPARSE ((LONG)0x00000104L) +#endif +#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE +#if defined(_WIN32_WCE) +// WinCE doesn't have a HasOverlappedIoCompleted() macro, so attempt to emulate it +#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) != STATUS_PENDING) +#endif +#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY) + +#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2) + +#define MAX_FDS 256 + +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ + +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +struct winfd { + int fd; // what's exposed to libusb core + OVERLAPPED *overlapped; // what will report our I/O status +}; + +extern const struct winfd INVALID_WINFD; + +struct winfd usbi_create_fd(void); + +int usbi_pipe(int pipefd[2]); +int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout); +ssize_t usbi_write(int fd, const void *buf, size_t count); +ssize_t usbi_read(int fd, void *buf, size_t count); +int usbi_close(int fd); + +/* + * Timeval operations + */ +#if defined(DDKBUILD) +#include // defines timeval functions on DDK +#endif + +#if !defined(TIMESPEC_TO_TIMEVAL) +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (long)(ts)->tv_sec; \ + (tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \ +} +#endif +#if !defined(timersub) +#define timersub(a, b, result) \ +do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ +} while (0) +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.c new file mode 100644 index 00000000..7150a3e9 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.c @@ -0,0 +1,1675 @@ +/* + * + * Copyright (c) 2016, Oracle and/or its affiliates. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "sunos_usb.h" + +#define UPDATEDRV_PATH "/usr/sbin/update_drv" +#define UPDATEDRV "update_drv" + +typedef list_t string_list_t; +typedef struct string_node { + char *string; + list_node_t link; +} string_node_t; + +/* + * Backend functions + */ +static int sunos_init(struct libusb_context *); +static void sunos_exit(struct libusb_context *); +static int sunos_get_device_list(struct libusb_context *, + struct discovered_devs **); +static int sunos_open(struct libusb_device_handle *); +static void sunos_close(struct libusb_device_handle *); +static int sunos_get_device_descriptor(struct libusb_device *, + uint8_t*, int *); +static int sunos_get_active_config_descriptor(struct libusb_device *, + uint8_t*, size_t, int *); +static int sunos_get_config_descriptor(struct libusb_device *, uint8_t, + uint8_t*, size_t, int *); +static int sunos_get_configuration(struct libusb_device_handle *, int *); +static int sunos_set_configuration(struct libusb_device_handle *, int); +static int sunos_claim_interface(struct libusb_device_handle *, int); +static int sunos_release_interface(struct libusb_device_handle *, int); +static int sunos_set_interface_altsetting(struct libusb_device_handle *, + int, int); +static int sunos_clear_halt(struct libusb_device_handle *, uint8_t); +static int sunos_reset_device(struct libusb_device_handle *); +static void sunos_destroy_device(struct libusb_device *); +static int sunos_submit_transfer(struct usbi_transfer *); +static int sunos_cancel_transfer(struct usbi_transfer *); +static void sunos_clear_transfer_priv(struct usbi_transfer *); +static int sunos_handle_transfer_completion(struct usbi_transfer *); +static int sunos_clock_gettime(int, struct timespec *); +static int sunos_kernel_driver_active(struct libusb_device_handle *, int interface); +static int sunos_detach_kernel_driver (struct libusb_device_handle *dev, int interface_number); +static int sunos_attach_kernel_driver (struct libusb_device_handle *dev, int interface_number); +static int sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv); +static int sunos_usb_ioctl(struct libusb_device *dev, int cmd); + +static struct devctl_iocdata iocdata; +static int sunos_get_link(di_devlink_t devlink, void *arg) +{ + walk_link_t *larg = (walk_link_t *)arg; + const char *p; + const char *q; + + if (larg->path) { + char *content = (char *)di_devlink_content(devlink); + char *start = strstr(content, "/devices/"); + start += strlen("/devices"); + usbi_dbg("%s", start); + + /* line content must have minor node */ + if (start == NULL || + strncmp(start, larg->path, larg->len) != 0 || + start[larg->len] != ':') + return (DI_WALK_CONTINUE); + } + + p = di_devlink_path(devlink); + q = strrchr(p, '/'); + usbi_dbg("%s", q); + + *(larg->linkpp) = strndup(p, strlen(p) - strlen(q)); + + return (DI_WALK_TERMINATE); +} + + +static int sunos_physpath_to_devlink( + const char *node_path, const char *match, char **link_path) +{ + walk_link_t larg; + di_devlink_handle_t hdl; + + *link_path = NULL; + larg.linkpp = link_path; + if ((hdl = di_devlink_init(NULL, 0)) == NULL) { + usbi_dbg("di_devlink_init failure"); + return (-1); + } + + larg.len = strlen(node_path); + larg.path = (char *)node_path; + + (void) di_devlink_walk(hdl, match, NULL, DI_PRIMARY_LINK, + (void *)&larg, sunos_get_link); + + (void) di_devlink_fini(&hdl); + + if (*link_path == NULL) { + usbi_dbg("there is no devlink for this path"); + return (-1); + } + + return 0; +} + +static int +sunos_usb_ioctl(struct libusb_device *dev, int cmd) +{ + int fd; + nvlist_t *nvlist; + char *end; + char *phypath; + char *hubpath; + char path_arg[PATH_MAX]; + sunos_dev_priv_t *dpriv; + devctl_ap_state_t devctl_ap_state; + + dpriv = (sunos_dev_priv_t *)dev->os_priv; + phypath = dpriv->phypath; + + end = strrchr(phypath, '/'); + if (end == NULL) + return (-1); + hubpath = strndup(phypath, end - phypath); + if (hubpath == NULL) + return (-1); + + end = strrchr(hubpath, '@'); + if (end == NULL) { + free(hubpath); + return (-1); + } + end++; + usbi_dbg("unitaddr: %s", end); + + nvlist_alloc(&nvlist, NV_UNIQUE_NAME_TYPE, KM_NOSLEEP); + nvlist_add_int32(nvlist, "port", dev->port_number); + //find the hub path + snprintf(path_arg, sizeof(path_arg), "/devices%s:hubd", hubpath); + usbi_dbg("ioctl hub path: %s", path_arg); + + fd = open(path_arg, O_RDONLY); + if (fd < 0) { + usbi_err(DEVICE_CTX(dev), "open failed: %d (%s)", errno, strerror(errno)); + nvlist_free(nvlist); + free(hubpath); + return (-1); + } + + memset(&iocdata, 0, sizeof(iocdata)); + memset(&devctl_ap_state, 0, sizeof(devctl_ap_state)); + + nvlist_pack(nvlist, (char **)&iocdata.nvl_user, &iocdata.nvl_usersz, NV_ENCODE_NATIVE, 0); + + iocdata.cmd = DEVCTL_AP_GETSTATE; + iocdata.flags = 0; + iocdata.c_nodename = "hub"; + iocdata.c_unitaddr = end; + iocdata.cpyout_buf = &devctl_ap_state; + usbi_dbg("%p, %d", iocdata.nvl_user, iocdata.nvl_usersz); + + errno = 0; + if (ioctl(fd, DEVCTL_AP_GETSTATE, &iocdata) == -1) { + usbi_err(DEVICE_CTX(dev), "ioctl failed: fd %d, cmd %x, errno %d (%s)", + fd, DEVCTL_AP_GETSTATE, errno, strerror(errno)); + } else { + usbi_dbg("dev rstate: %d", devctl_ap_state.ap_rstate); + usbi_dbg("dev ostate: %d", devctl_ap_state.ap_ostate); + } + + errno = 0; + iocdata.cmd = cmd; + if (ioctl(fd, (int)cmd, &iocdata) != 0) { + usbi_err(DEVICE_CTX(dev), "ioctl failed: fd %d, cmd %x, errno %d (%s)", + fd, cmd, errno, strerror(errno)); + sleep(2); + } + + close(fd); + free(iocdata.nvl_user); + nvlist_free(nvlist); + free(hubpath); + + return (-errno); +} + +static int +sunos_kernel_driver_active(struct libusb_device_handle *dev, int interface) +{ + sunos_dev_priv_t *dpriv; + dpriv = (sunos_dev_priv_t *)dev->dev->os_priv; + + usbi_dbg("%s", dpriv->ugenpath); + + return (dpriv->ugenpath == NULL); +} + +/* + * Private functions + */ +static int _errno_to_libusb(int); +static int sunos_usb_get_status(int fd); + +static int sunos_init(struct libusb_context *ctx) +{ + return (LIBUSB_SUCCESS); +} + +static void sunos_exit(struct libusb_context *ctx) +{ + usbi_dbg(""); +} + +static string_list_t * +sunos_new_string_list(void) +{ + string_list_t *list; + + list = calloc(1, sizeof(*list)); + if (list != NULL) + list_create(list, sizeof(string_node_t), + offsetof(string_node_t, link)); + + return (list); +} + +static int +sunos_append_to_string_list(string_list_t *list, const char *arg) +{ + string_node_t *np; + + np = calloc(1, sizeof(*np)); + if (!np) + return (-1); + + np->string = strdup(arg); + if (!np->string) { + free(np); + return (-1); + } + + list_insert_tail(list, np); + + return (0); +} + +static void +sunos_free_string_list(string_list_t *list) +{ + string_node_t *np; + + while ((np = list_remove_head(list)) != NULL) { + free(np->string); + free(np); + } + + free(list); +} + +static char ** +sunos_build_argv_list(string_list_t *list) +{ + char **argv_list; + string_node_t *np; + int n; + + n = 1; /* Start at 1 for NULL terminator */ + for (np = list_head(list); np != NULL; np = list_next(list, np)) + n++; + + argv_list = calloc(n, sizeof(char *)); + if (argv_list == NULL) + return NULL; + + n = 0; + for (np = list_head(list); np != NULL; np = list_next(list, np)) + argv_list[n++] = np->string; + + return (argv_list); +} + + +static int +sunos_exec_command(struct libusb_context *ctx, const char *path, + string_list_t *list) +{ + pid_t pid; + int status; + int waitstat; + int exit_status; + char **argv_list; + + argv_list = sunos_build_argv_list(list); + if (argv_list == NULL) + return (-1); + + pid = fork(); + if (pid == 0) { + /* child */ + execv(path, argv_list); + _exit(127); + } else if (pid > 0) { + /* parent */ + do { + waitstat = waitpid(pid, &status, 0); + } while ((waitstat == -1 && errno == EINTR) || + (waitstat == 0 && !WIFEXITED(status) && !WIFSIGNALED(status))); + + if (waitstat == 0) { + if (WIFEXITED(status)) + exit_status = WEXITSTATUS(status); + else + exit_status = WTERMSIG(status); + } else { + usbi_err(ctx, "waitpid failed: errno %d (%s)", errno, strerror(errno)); + exit_status = -1; + } + } else { + /* fork failed */ + usbi_err(ctx, "fork failed: errno %d (%s)", errno, strerror(errno)); + exit_status = -1; + } + + free(argv_list); + + return (exit_status); +} + +static int +sunos_detach_kernel_driver(struct libusb_device_handle *dev_handle, + int interface_number) +{ + struct libusb_context *ctx = HANDLE_CTX(dev_handle); + string_list_t *list; + char path_arg[PATH_MAX]; + sunos_dev_priv_t *dpriv; + int r; + + dpriv = (sunos_dev_priv_t *)dev_handle->dev->os_priv; + snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath); + usbi_dbg("%s", path_arg); + + list = sunos_new_string_list(); + if (list == NULL) + return (LIBUSB_ERROR_NO_MEM); + + /* attach ugen driver */ + r = 0; + r |= sunos_append_to_string_list(list, UPDATEDRV); + r |= sunos_append_to_string_list(list, "-a"); /* add rule */ + r |= sunos_append_to_string_list(list, "-i"); /* specific device */ + r |= sunos_append_to_string_list(list, path_arg); /* physical path */ + r |= sunos_append_to_string_list(list, "ugen"); + if (r) { + sunos_free_string_list(list); + return (LIBUSB_ERROR_NO_MEM); + } + + r = sunos_exec_command(ctx, UPDATEDRV_PATH, list); + sunos_free_string_list(list); + if (r < 0) + return (LIBUSB_ERROR_OTHER); + + /* reconfigure the driver node */ + r = 0; + r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_DISCONNECT); + r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE); + if (r) + usbi_warn(HANDLE_CTX(dev_handle), "one or more ioctls failed"); + + snprintf(path_arg, sizeof(path_arg), "^usb/%x.%x", dpriv->dev_descr.idVendor, + dpriv->dev_descr.idProduct); + sunos_physpath_to_devlink(dpriv->phypath, path_arg, &dpriv->ugenpath); + + if (access(dpriv->ugenpath, F_OK) == -1) { + usbi_err(HANDLE_CTX(dev_handle), "fail to detach kernel driver"); + return (LIBUSB_ERROR_IO); + } + + return sunos_usb_open_ep0((sunos_dev_handle_priv_t *)dev_handle->os_priv, dpriv); +} + +static int +sunos_attach_kernel_driver(struct libusb_device_handle *dev_handle, + int interface_number) +{ + struct libusb_context *ctx = HANDLE_CTX(dev_handle); + string_list_t *list; + char path_arg[PATH_MAX]; + sunos_dev_priv_t *dpriv; + int r; + + /* we open the dev in detach driver, so we need close it first. */ + sunos_close(dev_handle); + + dpriv = (sunos_dev_priv_t *)dev_handle->dev->os_priv; + snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath); + usbi_dbg("%s", path_arg); + + list = sunos_new_string_list(); + if (list == NULL) + return (LIBUSB_ERROR_NO_MEM); + + /* detach ugen driver */ + r = 0; + r |= sunos_append_to_string_list(list, UPDATEDRV); + r |= sunos_append_to_string_list(list, "-d"); /* add rule */ + r |= sunos_append_to_string_list(list, "-i"); /* specific device */ + r |= sunos_append_to_string_list(list, path_arg); /* physical path */ + r |= sunos_append_to_string_list(list, "ugen"); + if (r) { + sunos_free_string_list(list); + return (LIBUSB_ERROR_NO_MEM); + } + + r = sunos_exec_command(ctx, UPDATEDRV_PATH, list); + sunos_free_string_list(list); + if (r < 0) + return (LIBUSB_ERROR_OTHER); + + /* reconfigure the driver node */ + r = 0; + r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE); + r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_DISCONNECT); + r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE); + if (r) + usbi_warn(HANDLE_CTX(dev_handle), "one or more ioctls failed"); + + return 0; +} + +static int +sunos_fill_in_dev_info(di_node_t node, struct libusb_device *dev) +{ + int proplen; + int n, *addr, *port_prop; + char *phypath; + uint8_t *rdata; + struct libusb_device_descriptor *descr; + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + char match_str[PATH_MAX]; + + /* Device descriptors */ + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-dev-descriptor", &rdata); + if (proplen <= 0) { + + return (LIBUSB_ERROR_IO); + } + + descr = (struct libusb_device_descriptor *)rdata; + bcopy(descr, &dpriv->dev_descr, LIBUSB_DT_DEVICE_SIZE); + dpriv->dev_descr.bcdUSB = libusb_cpu_to_le16(descr->bcdUSB); + dpriv->dev_descr.idVendor = libusb_cpu_to_le16(descr->idVendor); + dpriv->dev_descr.idProduct = libusb_cpu_to_le16(descr->idProduct); + dpriv->dev_descr.bcdDevice = libusb_cpu_to_le16(descr->bcdDevice); + + /* Raw configuration descriptors */ + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-raw-cfg-descriptors", &rdata); + if (proplen <= 0) { + usbi_dbg("can't find raw config descriptors"); + + return (LIBUSB_ERROR_IO); + } + dpriv->raw_cfgdescr = calloc(1, proplen); + if (dpriv->raw_cfgdescr == NULL) { + return (LIBUSB_ERROR_NO_MEM); + } else { + bcopy(rdata, dpriv->raw_cfgdescr, proplen); + dpriv->cfgvalue = ((struct libusb_config_descriptor *) + rdata)->bConfigurationValue; + } + + n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &port_prop); + + if ((n != 1) || (*port_prop <= 0)) { + return (LIBUSB_ERROR_IO); + } + dev->port_number = *port_prop; + + /* device physical path */ + phypath = di_devfs_path(node); + if (phypath) { + dpriv->phypath = strdup(phypath); + snprintf(match_str, sizeof(match_str), "^usb/%x.%x", dpriv->dev_descr.idVendor, dpriv->dev_descr.idProduct); + usbi_dbg("match is %s", match_str); + sunos_physpath_to_devlink(dpriv->phypath, match_str, &dpriv->ugenpath); + di_devfs_path_free(phypath); + + } else { + free(dpriv->raw_cfgdescr); + + return (LIBUSB_ERROR_IO); + } + + /* address */ + n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "assigned-address", &addr); + if (n != 1 || *addr == 0) { + usbi_dbg("can't get address"); + } else { + dev->device_address = *addr; + } + + /* speed */ + if (di_prop_exists(DDI_DEV_T_ANY, node, "low-speed") == 1) { + dev->speed = LIBUSB_SPEED_LOW; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "high-speed") == 1) { + dev->speed = LIBUSB_SPEED_HIGH; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "full-speed") == 1) { + dev->speed = LIBUSB_SPEED_FULL; + } else if (di_prop_exists(DDI_DEV_T_ANY, node, "super-speed") == 1) { + dev->speed = LIBUSB_SPEED_SUPER; + } + + usbi_dbg("vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, " + "speed=%d", dpriv->dev_descr.idVendor, dpriv->dev_descr.idProduct, + dpriv->phypath, dev->bus_number, dev->port_number, dev->speed); + + return (LIBUSB_SUCCESS); +} + +static int +sunos_add_devices(di_devlink_t link, void *arg) +{ + struct devlink_cbarg *largs = (struct devlink_cbarg *)arg; + struct node_args *nargs; + di_node_t myself, dn; + uint64_t session_id = 0; + uint64_t sid = 0; + uint64_t bdf = 0; + struct libusb_device *dev; + sunos_dev_priv_t *devpriv; + int n; + int i = 0; + int *addr_prop; + uint8_t bus_number = 0; + uint32_t * regbuf = NULL; + uint32_t reg; + + nargs = (struct node_args *)largs->nargs; + myself = largs->myself; + + /* + * Construct session ID. + * session ID = dev_addr | hub addr |parent hub addr|...|root hub bdf + * 8 bits 8bits 8 bits 16bits + */ + if (myself == DI_NODE_NIL) + return (DI_WALK_CONTINUE); + + dn = myself; + /* find the root hub */ + while (di_prop_exists(DDI_DEV_T_ANY, dn, "root-hub") != 1) { + usbi_dbg("find_root_hub:%s", di_devfs_path(dn)); + n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, + "assigned-address", &addr_prop); + session_id |= ((addr_prop[0] & 0xff) << i++ * 8); + dn = di_parent_node(dn); + } + + /* dn is the root hub node */ + n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "reg", (int **)®buf); + reg = regbuf[0]; + bdf = (PCI_REG_BUS_G(reg) << 8) | (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); + /* bdf must larger than i*8 bits */ + session_id |= (bdf << i * 8); + bus_number = (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); + + usbi_dbg("device bus address=%s:%x, name:%s", + di_bus_addr(myself), bus_number, di_node_name(dn)); + usbi_dbg("session id org:%lx", session_id); + + /* dn is the usb device */ + for (dn = di_child_node(myself); dn != DI_NODE_NIL; dn = di_sibling_node(dn)) { + usbi_dbg("device path:%s", di_devfs_path(dn)); + /* skip hub devices, because its driver can not been unload */ + if (di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "usb-port-count", &addr_prop) != -1) + continue; + /* usb_addr */ + n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, + "assigned-address", &addr_prop); + if ((n != 1) || (addr_prop[0] == 0)) { + usbi_dbg("cannot get valid usb_addr"); + continue; + } + + sid = (session_id << 8) | (addr_prop[0] & 0xff) ; + usbi_dbg("session id %lx", sid); + + dev = usbi_get_device_by_session_id(nargs->ctx, sid); + if (dev == NULL) { + dev = usbi_alloc_device(nargs->ctx, sid); + if (dev == NULL) { + usbi_dbg("can't alloc device"); + continue; + } + devpriv = (sunos_dev_priv_t *)dev->os_priv; + dev->bus_number = bus_number; + + if (sunos_fill_in_dev_info(dn, dev) != LIBUSB_SUCCESS) { + libusb_unref_device(dev); + usbi_dbg("get infomation fail"); + continue; + } + if (usbi_sanitize_device(dev) < 0) { + libusb_unref_device(dev); + usbi_dbg("sanatize failed: "); + return (DI_WALK_TERMINATE); + } + } else { + devpriv = (sunos_dev_priv_t *)dev->os_priv; + usbi_dbg("Dev %s exists", devpriv->ugenpath); + } + + if (discovered_devs_append(*(nargs->discdevs), dev) == NULL) { + usbi_dbg("cannot append device"); + } + + /* + * we alloc and hence ref this dev. We don't need to ref it + * hereafter. Front end or app should take care of their ref. + */ + libusb_unref_device(dev); + + usbi_dbg("Device %s %s id=0x%llx, devcount:%d, bdf=%x", + devpriv->ugenpath, di_devfs_path(dn), (uint64_t)sid, + (*nargs->discdevs)->len, bdf); + } + + return (DI_WALK_CONTINUE); +} + +static int +sunos_walk_minor_node_link(di_node_t node, void *args) +{ + di_minor_t minor = DI_MINOR_NIL; + char *minor_path; + struct devlink_cbarg arg; + struct node_args *nargs = (struct node_args *)args; + di_devlink_handle_t devlink_hdl = nargs->dlink_hdl; + + /* walk each minor to find usb devices */ + while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { + minor_path = di_devfs_minor_path(minor); + arg.nargs = args; + arg.myself = node; + arg.minor = minor; + (void) di_devlink_walk(devlink_hdl, + "^usb/hub[0-9]+", minor_path, + DI_PRIMARY_LINK, (void *)&arg, sunos_add_devices); + di_devfs_path_free(minor_path); + } + + /* switch to a different node */ + nargs->last_ugenpath = NULL; + + return (DI_WALK_CONTINUE); +} + +int +sunos_get_device_list(struct libusb_context * ctx, + struct discovered_devs **discdevs) +{ + di_node_t root_node; + struct node_args args; + di_devlink_handle_t devlink_hdl; + + args.ctx = ctx; + args.discdevs = discdevs; + args.last_ugenpath = NULL; + if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { + usbi_dbg("di_int() failed: %s", strerror(errno)); + return (LIBUSB_ERROR_IO); + } + + if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) { + di_fini(root_node); + usbi_dbg("di_devlink_init() failed: %s", strerror(errno)); + + return (LIBUSB_ERROR_IO); + } + args.dlink_hdl = devlink_hdl; + + /* walk each node to find USB devices */ + if (di_walk_node(root_node, DI_WALK_SIBFIRST, &args, + sunos_walk_minor_node_link) == -1) { + usbi_dbg("di_walk_node() failed: %s", strerror(errno)); + di_fini(root_node); + + return (LIBUSB_ERROR_IO); + } + + di_fini(root_node); + di_devlink_fini(&devlink_hdl); + + usbi_dbg("%d devices", (*discdevs)->len); + + return ((*discdevs)->len); +} + +static int +sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv) +{ + char filename[PATH_MAX + 1]; + + if (hpriv->eps[0].datafd > 0) { + + return (LIBUSB_SUCCESS); + } + snprintf(filename, PATH_MAX, "%s/cntrl0", dpriv->ugenpath); + + usbi_dbg("opening %s", filename); + hpriv->eps[0].datafd = open(filename, O_RDWR); + if (hpriv->eps[0].datafd < 0) { + return(_errno_to_libusb(errno)); + } + + snprintf(filename, PATH_MAX, "%s/cntrl0stat", dpriv->ugenpath); + hpriv->eps[0].statfd = open(filename, O_RDONLY); + if (hpriv->eps[0].statfd < 0) { + close(hpriv->eps[0].datafd); + hpriv->eps[0].datafd = -1; + + return(_errno_to_libusb(errno)); + } + + return (LIBUSB_SUCCESS); +} + +static void +sunos_usb_close_all_eps(sunos_dev_handle_priv_t *hdev) +{ + int i; + + /* not close ep0 */ + for (i = 1; i < USB_MAXENDPOINTS; i++) { + if (hdev->eps[i].datafd != -1) { + (void) close(hdev->eps[i].datafd); + hdev->eps[i].datafd = -1; + } + if (hdev->eps[i].statfd != -1) { + (void) close(hdev->eps[i].statfd); + hdev->eps[i].statfd = -1; + } + } +} + +static void +sunos_usb_close_ep0(sunos_dev_handle_priv_t *hdev, sunos_dev_priv_t *dpriv) +{ + if (hdev->eps[0].datafd >= 0) { + close(hdev->eps[0].datafd); + close(hdev->eps[0].statfd); + hdev->eps[0].datafd = -1; + hdev->eps[0].statfd = -1; + } +} + +static uchar_t +sunos_usb_ep_index(uint8_t ep_addr) +{ + return ((ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK) + + ((ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? 16 : 0)); +} + +static int +sunos_find_interface(struct libusb_device_handle *hdev, + uint8_t endpoint, uint8_t *interface) +{ + struct libusb_config_descriptor *config; + int r; + int iface_idx; + + r = libusb_get_active_config_descriptor(hdev->dev, &config); + if (r < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) { + const struct libusb_interface *iface = + &config->interface[iface_idx]; + int altsetting_idx; + + for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting; + altsetting_idx++) { + const struct libusb_interface_descriptor *altsetting = + &iface->altsetting[altsetting_idx]; + int ep_idx; + + for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; + ep_idx++) { + const struct libusb_endpoint_descriptor *ep = + &altsetting->endpoint[ep_idx]; + if (ep->bEndpointAddress == endpoint) { + *interface = iface_idx; + libusb_free_config_descriptor(config); + + return (LIBUSB_SUCCESS); + } + } + } + } + libusb_free_config_descriptor(config); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +static int +sunos_check_device_and_status_open(struct libusb_device_handle *hdl, + uint8_t ep_addr, int ep_type) +{ + char filename[PATH_MAX + 1], statfilename[PATH_MAX + 1]; + char cfg_num[16], alt_num[16]; + int fd, fdstat, mode; + uint8_t ifc = 0; + uint8_t ep_index; + sunos_dev_handle_priv_t *hpriv; + + usbi_dbg("open ep 0x%02x", ep_addr); + hpriv = (sunos_dev_handle_priv_t *)hdl->os_priv; + ep_index = sunos_usb_ep_index(ep_addr); + /* ep already opened */ + if ((hpriv->eps[ep_index].datafd > 0) && + (hpriv->eps[ep_index].statfd > 0)) { + usbi_dbg("ep 0x%02x already opened, return success", + ep_addr); + + return (0); + } + + if (sunos_find_interface(hdl, ep_addr, &ifc) < 0) { + usbi_dbg("can't find interface for endpoint 0x%02x", + ep_addr); + + return (EACCES); + } + + /* create filename */ + if (hpriv->config_index > 0) { + (void) snprintf(cfg_num, sizeof (cfg_num), "cfg%d", + hpriv->config_index + 1); + } else { + bzero(cfg_num, sizeof (cfg_num)); + } + + if (hpriv->altsetting[ifc] > 0) { + (void) snprintf(alt_num, sizeof (alt_num), ".%d", + hpriv->altsetting[ifc]); + } else { + bzero(alt_num, sizeof (alt_num)); + } + + (void) snprintf(filename, PATH_MAX, "%s/%sif%d%s%s%d", + hpriv->dpriv->ugenpath, cfg_num, ifc, alt_num, + (ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? "in" : + "out", (ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK)); + (void) snprintf(statfilename, PATH_MAX, "%sstat", filename); + + /* + * for interrupt IN endpoints, we need to enable one xfer + * mode before opening the endpoint + */ + if ((ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) && + (ep_addr & LIBUSB_ENDPOINT_IN)) { + char control = USB_EP_INTR_ONE_XFER; + int count; + + /* open the status device node for the ep first RDWR */ + if ((fdstat = open(statfilename, O_RDWR)) == -1) { + usbi_dbg("can't open %s RDWR: %d", + statfilename, errno); + } else { + count = write(fdstat, &control, sizeof (control)); + if (count != 1) { + /* this should have worked */ + usbi_dbg("can't write to %s: %d", + statfilename, errno); + (void) close(fdstat); + + return (errno); + } + /* close status node and open xfer node first */ + close (fdstat); + } + } + + /* open the xfer node first in case alt needs to be changed */ + if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + mode = O_RDWR; + } else if (ep_addr & LIBUSB_ENDPOINT_IN) { + mode = O_RDONLY; + } else { + mode = O_WRONLY; + } + + /* + * IMPORTANT: must open data xfer node first and then open stat node + * Otherwise, it will fail on multi-config or multi-altsetting devices + * with "Device Busy" error. See ugen_epxs_switch_cfg_alt() and + * ugen_epxs_check_alt_switch() in ugen driver source code. + */ + if ((fd = open(filename, mode)) == -1) { + usbi_dbg("can't open %s: %d(%s)", filename, errno, + strerror(errno)); + + return (errno); + } + /* open the status node */ + if ((fdstat = open(statfilename, O_RDONLY)) == -1) { + usbi_dbg("can't open %s: %d", statfilename, errno); + + (void) close(fd); + + return (errno); + } + + hpriv->eps[ep_index].datafd = fd; + hpriv->eps[ep_index].statfd = fdstat; + usbi_dbg("ep=0x%02x datafd=%d, statfd=%d", ep_addr, fd, fdstat); + + return (0); +} + +int +sunos_open(struct libusb_device_handle *handle) +{ + sunos_dev_handle_priv_t *hpriv; + sunos_dev_priv_t *dpriv; + int i; + int ret; + + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + hpriv->dpriv = dpriv; + + /* set all file descriptors to "closed" */ + for (i = 0; i < USB_MAXENDPOINTS; i++) { + hpriv->eps[i].datafd = -1; + hpriv->eps[i].statfd = -1; + } + + if (sunos_kernel_driver_active(handle, 0)) { + /* pretend we can open the device */ + return (LIBUSB_SUCCESS); + } + + if ((ret = sunos_usb_open_ep0(hpriv, dpriv)) != LIBUSB_SUCCESS) { + usbi_dbg("fail: %d", ret); + return (ret); + } + + return (LIBUSB_SUCCESS); +} + +void +sunos_close(struct libusb_device_handle *handle) +{ + sunos_dev_handle_priv_t *hpriv; + sunos_dev_priv_t *dpriv; + + usbi_dbg(""); + if (!handle) { + return; + } + + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + if (!hpriv) { + return; + } + dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + if (!dpriv) { + return; + } + + sunos_usb_close_all_eps(hpriv); + sunos_usb_close_ep0(hpriv, dpriv); +} + +int +sunos_get_device_descriptor(struct libusb_device *dev, uint8_t *buf, + int *host_endian) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + + memcpy(buf, &dpriv->dev_descr, LIBUSB_DT_DEVICE_SIZE); + *host_endian = 0; + + return (LIBUSB_SUCCESS); +} + +int +sunos_get_active_config_descriptor(struct libusb_device *dev, + uint8_t *buf, size_t len, int *host_endian) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + struct libusb_config_descriptor *cfg; + int proplen; + di_node_t node; + uint8_t *rdata; + + /* + * Keep raw configuration descriptors updated, in case config + * has ever been changed through setCfg. + */ + if ((node = di_init(dpriv->phypath, DINFOCPYALL)) == DI_NODE_NIL) { + usbi_dbg("di_int() failed: %s", strerror(errno)); + return (LIBUSB_ERROR_IO); + } + proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, + "usb-raw-cfg-descriptors", &rdata); + if (proplen <= 0) { + usbi_dbg("can't find raw config descriptors"); + + return (LIBUSB_ERROR_IO); + } + dpriv->raw_cfgdescr = realloc(dpriv->raw_cfgdescr, proplen); + if (dpriv->raw_cfgdescr == NULL) { + return (LIBUSB_ERROR_NO_MEM); + } else { + bcopy(rdata, dpriv->raw_cfgdescr, proplen); + dpriv->cfgvalue = ((struct libusb_config_descriptor *) + rdata)->bConfigurationValue; + } + di_fini(node); + + cfg = (struct libusb_config_descriptor *)dpriv->raw_cfgdescr; + len = MIN(len, libusb_le16_to_cpu(cfg->wTotalLength)); + memcpy(buf, dpriv->raw_cfgdescr, len); + *host_endian = 0; + usbi_dbg("path:%s len %d", dpriv->phypath, len); + + return (len); +} + +int +sunos_get_config_descriptor(struct libusb_device *dev, uint8_t idx, + uint8_t *buf, size_t len, int *host_endian) +{ + /* XXX */ + return(sunos_get_active_config_descriptor(dev, buf, len, host_endian)); +} + +int +sunos_get_configuration(struct libusb_device_handle *handle, int *config) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + + *config = dpriv->cfgvalue; + + usbi_dbg("bConfigurationValue %d", *config); + + return (LIBUSB_SUCCESS); +} + +int +sunos_set_configuration(struct libusb_device_handle *handle, int config) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + sunos_dev_handle_priv_t *hpriv; + + usbi_dbg("bConfigurationValue %d", config); + hpriv = (sunos_dev_handle_priv_t *)handle->os_priv; + + if (dpriv->ugenpath == NULL) + return (LIBUSB_ERROR_NOT_SUPPORTED); + + if (config < 1 || config > dpriv->dev_descr.bNumConfigurations) + return (LIBUSB_ERROR_INVALID_PARAM); + + dpriv->cfgvalue = config; + hpriv->config_index = config - 1; + + return (LIBUSB_SUCCESS); +} + +int +sunos_claim_interface(struct libusb_device_handle *handle, int iface) +{ + usbi_dbg("iface %d", iface); + if (iface < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + return (LIBUSB_SUCCESS); +} + +int +sunos_release_interface(struct libusb_device_handle *handle, int iface) +{ + sunos_dev_handle_priv_t *hpriv = + (sunos_dev_handle_priv_t *)handle->os_priv; + + usbi_dbg("iface %d", iface); + if (iface < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + + /* XXX: can we release it? */ + hpriv->altsetting[iface] = 0; + + return (LIBUSB_SUCCESS); +} + +int +sunos_set_interface_altsetting(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)handle->dev->os_priv; + sunos_dev_handle_priv_t *hpriv = + (sunos_dev_handle_priv_t *)handle->os_priv; + + usbi_dbg("iface %d, setting %d", iface, altsetting); + + if (iface < 0 || altsetting < 0) { + return (LIBUSB_ERROR_INVALID_PARAM); + } + if (dpriv->ugenpath == NULL) + return (LIBUSB_ERROR_NOT_FOUND); + + /* XXX: can we switch altsetting? */ + hpriv->altsetting[iface] = altsetting; + + return (LIBUSB_SUCCESS); +} + +static void +usb_dump_data(unsigned char *data, size_t size) +{ + int i; + + if (getenv("LIBUSB_DEBUG") == NULL) { + return; + } + + (void) fprintf(stderr, "data dump:"); + for (i = 0; i < size; i++) { + if (i % 16 == 0) { + (void) fprintf(stderr, "\n%08x ", i); + } + (void) fprintf(stderr, "%02x ", (uchar_t)data[i]); + } + (void) fprintf(stderr, "\n"); +} + +static void +sunos_async_callback(union sigval arg) +{ + struct sunos_transfer_priv *tpriv = + (struct sunos_transfer_priv *)arg.sival_ptr; + struct libusb_transfer *xfer = tpriv->transfer; + struct aiocb *aiocb = &tpriv->aiocb; + int ret; + sunos_dev_handle_priv_t *hpriv; + uint8_t ep; + + hpriv = (sunos_dev_handle_priv_t *)xfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(xfer->endpoint); + + ret = aio_error(aiocb); + if (ret != 0) { + xfer->status = sunos_usb_get_status(hpriv->eps[ep].statfd); + } else { + xfer->actual_length = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred = + aio_return(aiocb); + } + + usb_dump_data(xfer->buffer, xfer->actual_length); + + usbi_dbg("ret=%d, len=%d, actual_len=%d", ret, xfer->length, + xfer->actual_length); + + /* async notification */ + usbi_signal_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)); +} + +static int +sunos_do_async_io(struct libusb_transfer *transfer) +{ + int ret = -1; + struct aiocb *aiocb; + sunos_dev_handle_priv_t *hpriv; + uint8_t ep; + struct sunos_transfer_priv *tpriv; + + usbi_dbg(""); + + tpriv = usbi_transfer_get_os_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)); + hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(transfer->endpoint); + + tpriv->transfer = transfer; + aiocb = &tpriv->aiocb; + bzero(aiocb, sizeof (*aiocb)); + aiocb->aio_fildes = hpriv->eps[ep].datafd; + aiocb->aio_buf = transfer->buffer; + aiocb->aio_nbytes = transfer->length; + aiocb->aio_lio_opcode = + ((transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_IN) ? LIO_READ:LIO_WRITE; + aiocb->aio_sigevent.sigev_notify = SIGEV_THREAD; + aiocb->aio_sigevent.sigev_value.sival_ptr = tpriv; + aiocb->aio_sigevent.sigev_notify_function = sunos_async_callback; + + if (aiocb->aio_lio_opcode == LIO_READ) { + ret = aio_read(aiocb); + } else { + ret = aio_write(aiocb); + } + + return (ret); +} + +/* return the number of bytes read/written */ +static int +usb_do_io(int fd, int stat_fd, char *data, size_t size, int flag, int *status) +{ + int error; + int ret = -1; + + usbi_dbg("usb_do_io(): datafd=%d statfd=%d size=0x%x flag=%s", + fd, stat_fd, size, flag? "WRITE":"READ"); + + switch (flag) { + case READ: + errno = 0; + ret = read(fd, data, size); + usb_dump_data(data, size); + break; + case WRITE: + usb_dump_data(data, size); + errno = 0; + ret = write(fd, data, size); + break; + } + + usbi_dbg("usb_do_io(): amount=%d", ret); + + if (ret < 0) { + int save_errno = errno; + + usbi_dbg("TID=%x io %s errno=%d(%s) ret=%d", pthread_self(), + flag?"WRITE":"READ", errno, strerror(errno), ret); + + /* sunos_usb_get_status will do a read and overwrite errno */ + error = sunos_usb_get_status(stat_fd); + usbi_dbg("io status=%d errno=%d(%s)", error, + save_errno, strerror(save_errno)); + + if (status) { + *status = save_errno; + } + + return (save_errno); + + } else if (status) { + *status = 0; + } + + return (ret); +} + +static int +solaris_submit_ctrl_on_default(struct libusb_transfer *transfer) +{ + int ret = -1, setup_ret; + int status; + sunos_dev_handle_priv_t *hpriv; + struct libusb_device_handle *hdl = transfer->dev_handle; + uint16_t wLength; + uint8_t *data = transfer->buffer; + + hpriv = (sunos_dev_handle_priv_t *)hdl->os_priv; + wLength = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + if (hpriv->eps[0].datafd == -1) { + usbi_dbg("ep0 not opened"); + + return (LIBUSB_ERROR_NOT_FOUND); + } + + if ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) { + usbi_dbg("IN request"); + ret = usb_do_io(hpriv->eps[0].datafd, + hpriv->eps[0].statfd, (char *)data, LIBUSB_CONTROL_SETUP_SIZE, + WRITE, (int *)&status); + } else { + usbi_dbg("OUT request"); + ret = usb_do_io(hpriv->eps[0].datafd, hpriv->eps[0].statfd, + transfer->buffer, transfer->length, WRITE, + (int *)&transfer->status); + } + + setup_ret = ret; + if (ret < LIBUSB_CONTROL_SETUP_SIZE) { + usbi_dbg("error sending control msg: %d", ret); + + return (LIBUSB_ERROR_IO); + } + + ret = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + /* Read the remaining bytes for IN request */ + if ((wLength) && ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == + LIBUSB_ENDPOINT_IN)) { + usbi_dbg("DATA: %d", transfer->length - setup_ret); + ret = usb_do_io(hpriv->eps[0].datafd, + hpriv->eps[0].statfd, + (char *)transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, + wLength, READ, (int *)&transfer->status); + } + + if (ret >= 0) { + transfer->actual_length = ret; + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->transferred = ret; + } + usbi_dbg("Done: ctrl data bytes %d", ret); + + /* sync transfer handling */ + ret = usbi_handle_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer), + transfer->status); + + return (ret); +} + +int +sunos_clear_halt(struct libusb_device_handle *handle, uint8_t endpoint) +{ + int ret; + + usbi_dbg("endpoint=0x%02x", endpoint); + + ret = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT | + LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_REQUEST_TYPE_STANDARD, + LIBUSB_REQUEST_CLEAR_FEATURE, 0, endpoint, NULL, 0, 1000); + + usbi_dbg("ret=%d", ret); + + return (ret); +} + +int +sunos_reset_device(struct libusb_device_handle *handle) +{ + usbi_dbg(""); + + return (LIBUSB_ERROR_NOT_SUPPORTED); +} + +void +sunos_destroy_device(struct libusb_device *dev) +{ + sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; + usbi_dbg("destroy everyting"); + free(dpriv->raw_cfgdescr); + free(dpriv->ugenpath); + free(dpriv->phypath); +} + +int +sunos_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer; + struct libusb_device_handle *hdl; + int err = 0; + + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hdl = transfer->dev_handle; + + err = sunos_check_device_and_status_open(hdl, + transfer->endpoint, transfer->type); + if (err < 0) { + + return (_errno_to_libusb(err)); + } + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + /* sync transfer */ + usbi_dbg("CTRL transfer: %d", transfer->length); + err = solaris_submit_ctrl_on_default(transfer); + break; + + case LIBUSB_TRANSFER_TYPE_BULK: + /* fallthru */ + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (transfer->type == LIBUSB_TRANSFER_TYPE_BULK) + usbi_dbg("BULK transfer: %d", transfer->length); + else + usbi_dbg("INTR transfer: %d", transfer->length); + err = sunos_do_async_io(transfer); + break; + + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + /* Isochronous/Stream is not supported */ + + /* fallthru */ + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) + usbi_dbg("ISOC transfer: %d", transfer->length); + else + usbi_dbg("BULK STREAM transfer: %d", transfer->length); + err = LIBUSB_ERROR_NOT_SUPPORTED; + break; + } + + return (err); +} + +int +sunos_cancel_transfer(struct usbi_transfer *itransfer) +{ + sunos_xfer_priv_t *tpriv; + sunos_dev_handle_priv_t *hpriv; + struct libusb_transfer *transfer; + struct aiocb *aiocb; + uint8_t ep; + int ret; + + tpriv = usbi_transfer_get_os_priv(itransfer); + aiocb = &tpriv->aiocb; + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv; + ep = sunos_usb_ep_index(transfer->endpoint); + + ret = aio_cancel(hpriv->eps[ep].datafd, aiocb); + + usbi_dbg("aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes, + hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)? + strerror(0):strerror(errno)); + + if (ret != AIO_CANCELED) { + ret = _errno_to_libusb(errno); + } else { + /* + * we don't need to call usbi_handle_transfer_cancellation(), + * because we'll handle everything in sunos_async_callback. + */ + ret = LIBUSB_SUCCESS; + } + + return (ret); +} + +void +sunos_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + usbi_dbg(""); + + /* Nothing to do */ +} + +int +sunos_handle_transfer_completion(struct usbi_transfer *itransfer) +{ + return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED); +} + +int +sunos_clock_gettime(int clkid, struct timespec *tp) +{ + usbi_dbg("clock %d", clkid); + + if (clkid == USBI_CLOCK_REALTIME) + return clock_gettime(CLOCK_REALTIME, tp); + + if (clkid == USBI_CLOCK_MONOTONIC) + return clock_gettime(CLOCK_MONOTONIC, tp); + + return (LIBUSB_ERROR_INVALID_PARAM); +} + +int +_errno_to_libusb(int err) +{ + usbi_dbg("error: %s (%d)", strerror(err), err); + + switch (err) { + case EIO: + return (LIBUSB_ERROR_IO); + case EACCES: + return (LIBUSB_ERROR_ACCESS); + case ENOENT: + return (LIBUSB_ERROR_NO_DEVICE); + case ENOMEM: + return (LIBUSB_ERROR_NO_MEM); + case ETIMEDOUT: + return (LIBUSB_ERROR_TIMEOUT); + } + + return (LIBUSB_ERROR_OTHER); +} + +/* + * sunos_usb_get_status: + * gets status of endpoint + * + * Returns: ugen's last cmd status + */ +static int +sunos_usb_get_status(int fd) +{ + int status, ret; + + usbi_dbg("sunos_usb_get_status(): fd=%d", fd); + + ret = read(fd, &status, sizeof (status)); + if (ret == sizeof (status)) { + switch (status) { + case USB_LC_STAT_NOERROR: + usbi_dbg("No Error"); + break; + case USB_LC_STAT_CRC: + usbi_dbg("CRC Timeout Detected\n"); + break; + case USB_LC_STAT_BITSTUFFING: + usbi_dbg("Bit Stuffing Violation\n"); + break; + case USB_LC_STAT_DATA_TOGGLE_MM: + usbi_dbg("Data Toggle Mismatch\n"); + break; + case USB_LC_STAT_STALL: + usbi_dbg("End Point Stalled\n"); + break; + case USB_LC_STAT_DEV_NOT_RESP: + usbi_dbg("Device is Not Responding\n"); + break; + case USB_LC_STAT_PID_CHECKFAILURE: + usbi_dbg("PID Check Failure\n"); + break; + case USB_LC_STAT_UNEXP_PID: + usbi_dbg("Unexpected PID\n"); + break; + case USB_LC_STAT_DATA_OVERRUN: + usbi_dbg("Data Exceeded Size\n"); + break; + case USB_LC_STAT_DATA_UNDERRUN: + usbi_dbg("Less data received\n"); + break; + case USB_LC_STAT_BUFFER_OVERRUN: + usbi_dbg("Buffer Size Exceeded\n"); + break; + case USB_LC_STAT_BUFFER_UNDERRUN: + usbi_dbg("Buffer Underrun\n"); + break; + case USB_LC_STAT_TIMEOUT: + usbi_dbg("Command Timed Out\n"); + break; + case USB_LC_STAT_NOT_ACCESSED: + usbi_dbg("Not Accessed by h/w\n"); + break; + case USB_LC_STAT_UNSPECIFIED_ERR: + usbi_dbg("Unspecified Error\n"); + break; + case USB_LC_STAT_NO_BANDWIDTH: + usbi_dbg("No Bandwidth\n"); + break; + case USB_LC_STAT_HW_ERR: + usbi_dbg("Host Controller h/w Error\n"); + break; + case USB_LC_STAT_SUSPENDED: + usbi_dbg("Device was Suspended\n"); + break; + case USB_LC_STAT_DISCONNECTED: + usbi_dbg("Device was Disconnected\n"); + break; + case USB_LC_STAT_INTR_BUF_FULL: + usbi_dbg("Interrupt buffer was full\n"); + break; + case USB_LC_STAT_INVALID_REQ: + usbi_dbg("Request was Invalid\n"); + break; + case USB_LC_STAT_INTERRUPTED: + usbi_dbg("Request was Interrupted\n"); + break; + case USB_LC_STAT_NO_RESOURCES: + usbi_dbg("No resources available for " + "request\n"); + break; + case USB_LC_STAT_INTR_POLLING_FAILED: + usbi_dbg("Failed to Restart Poll"); + break; + default: + usbi_dbg("Error Not Determined %d\n", + status); + break; + } + } else { + usbi_dbg("read stat error: %s",strerror(errno)); + status = -1; + } + + return (status); +} + +const struct usbi_os_backend usbi_backend = { + .name = "Solaris", + .caps = 0, + .init = sunos_init, + .exit = sunos_exit, + .get_device_list = sunos_get_device_list, + .get_device_descriptor = sunos_get_device_descriptor, + .get_active_config_descriptor = sunos_get_active_config_descriptor, + .get_config_descriptor = sunos_get_config_descriptor, + .hotplug_poll = NULL, + .open = sunos_open, + .close = sunos_close, + .get_configuration = sunos_get_configuration, + .set_configuration = sunos_set_configuration, + + .claim_interface = sunos_claim_interface, + .release_interface = sunos_release_interface, + .set_interface_altsetting = sunos_set_interface_altsetting, + .clear_halt = sunos_clear_halt, + .reset_device = sunos_reset_device, /* TODO */ + .alloc_streams = NULL, + .free_streams = NULL, + .kernel_driver_active = sunos_kernel_driver_active, + .detach_kernel_driver = sunos_detach_kernel_driver, + .attach_kernel_driver = sunos_attach_kernel_driver, + .destroy_device = sunos_destroy_device, + .submit_transfer = sunos_submit_transfer, + .cancel_transfer = sunos_cancel_transfer, + .handle_events = NULL, + .clear_transfer_priv = sunos_clear_transfer_priv, + .handle_transfer_completion = sunos_handle_transfer_completion, + .clock_gettime = sunos_clock_gettime, + .device_priv_size = sizeof(sunos_dev_priv_t), + .device_handle_priv_size = sizeof(sunos_dev_handle_priv_t), + .transfer_priv_size = sizeof(sunos_xfer_priv_t), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.h new file mode 100644 index 00000000..52bb3d33 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/sunos_usb.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2016, Oracle and/or its affiliates. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_SUNOS_H +#define LIBUSB_SUNOS_H + +#include +#include +#include "libusbi.h" + +#define READ 0 +#define WRITE 1 + +typedef struct sunos_device_priv { + uint8_t cfgvalue; /* active config value */ + uint8_t *raw_cfgdescr; /* active config descriptor */ + struct libusb_device_descriptor dev_descr; /* usb device descriptor */ + char *ugenpath; /* name of the ugen(4) node */ + char *phypath; /* physical path */ +} sunos_dev_priv_t; + +typedef struct endpoint { + int datafd; /* data file */ + int statfd; /* state file */ +} sunos_ep_priv_t; + +typedef struct sunos_device_handle_priv { + uint8_t altsetting[USB_MAXINTERFACES]; /* a interface's alt */ + uint8_t config_index; + sunos_ep_priv_t eps[USB_MAXENDPOINTS]; + sunos_dev_priv_t *dpriv; /* device private */ +} sunos_dev_handle_priv_t; + +typedef struct sunos_transfer_priv { + struct aiocb aiocb; + struct libusb_transfer *transfer; +} sunos_xfer_priv_t; + +struct node_args { + struct libusb_context *ctx; + struct discovered_devs **discdevs; + const char *last_ugenpath; + di_devlink_handle_t dlink_hdl; +}; + +struct devlink_cbarg { + struct node_args *nargs; /* di node walk arguments */ + di_node_t myself; /* the di node */ + di_minor_t minor; +}; + +typedef struct walk_link { + char *path; + int len; + char **linkpp; +} walk_link_t; + +/* AIO callback args */ +struct aio_callback_args{ + struct libusb_transfer *transfer; + struct aiocb aiocb; +}; + +#endif /* LIBUSB_SUNOS_H */ diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.c new file mode 100644 index 00000000..16a7578b --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.c @@ -0,0 +1,80 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2011 Vitali Lovich + * Copyright © 2011 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#if defined(__linux__) || defined(__OpenBSD__) +# if defined(__OpenBSD__) +# define _BSD_SOURCE +# endif +# include +# include +#elif defined(__APPLE__) +# include +#elif defined(__CYGWIN__) +# include +#endif + +#include "threads_posix.h" +#include "libusbi.h" + +int usbi_cond_timedwait(pthread_cond_t *cond, + pthread_mutex_t *mutex, const struct timeval *tv) +{ + struct timespec timeout; + int r; + + r = usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timeout); + if (r < 0) + return r; + + timeout.tv_sec += tv->tv_sec; + timeout.tv_nsec += tv->tv_usec * 1000; + while (timeout.tv_nsec >= 1000000000L) { + timeout.tv_nsec -= 1000000000L; + timeout.tv_sec++; + } + + return pthread_cond_timedwait(cond, mutex, &timeout); +} + +int usbi_get_tid(void) +{ + int ret; +#if defined(__ANDROID__) + ret = gettid(); +#elif defined(__linux__) + ret = syscall(SYS_gettid); +#elif defined(__OpenBSD__) + /* The following only works with OpenBSD > 5.1 as it requires + real thread support. For 5.1 and earlier, -1 is returned. */ + ret = syscall(SYS_getthrid); +#elif defined(__APPLE__) + ret = (int)pthread_mach_thread_np(pthread_self()); +#elif defined(__CYGWIN__) + ret = GetCurrentThreadId(); +#else + ret = -1; +#endif +/* TODO: NetBSD thread ID support */ + return ret; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.h new file mode 100644 index 00000000..9f1ef94b --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_posix.h @@ -0,0 +1,102 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2010 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_THREADS_POSIX_H +#define LIBUSB_THREADS_POSIX_H + +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t usbi_mutex_static_t; +static inline void usbi_mutex_static_lock(usbi_mutex_static_t *mutex) +{ + (void)pthread_mutex_lock(mutex); +} +static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) +{ + (void)pthread_mutex_unlock(mutex); +} + +typedef pthread_mutex_t usbi_mutex_t; +static inline int usbi_mutex_init(usbi_mutex_t *mutex) +{ + return pthread_mutex_init(mutex, NULL); +} +static inline void usbi_mutex_lock(usbi_mutex_t *mutex) +{ + (void)pthread_mutex_lock(mutex); +} +static inline void usbi_mutex_unlock(usbi_mutex_t *mutex) +{ + (void)pthread_mutex_unlock(mutex); +} +static inline int usbi_mutex_trylock(usbi_mutex_t *mutex) +{ + return pthread_mutex_trylock(mutex); +} +static inline void usbi_mutex_destroy(usbi_mutex_t *mutex) +{ + (void)pthread_mutex_destroy(mutex); +} + +typedef pthread_cond_t usbi_cond_t; +static inline void usbi_cond_init(pthread_cond_t *cond) +{ + (void)pthread_cond_init(cond, NULL); +} +static inline int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) +{ + return pthread_cond_wait(cond, mutex); +} +int usbi_cond_timedwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, const struct timeval *tv); +static inline void usbi_cond_broadcast(usbi_cond_t *cond) +{ + (void)pthread_cond_broadcast(cond); +} +static inline void usbi_cond_destroy(usbi_cond_t *cond) +{ + (void)pthread_cond_destroy(cond); +} + +typedef pthread_key_t usbi_tls_key_t; +static inline void usbi_tls_key_create(usbi_tls_key_t *key) +{ + (void)pthread_key_create(key, NULL); +} +static inline void *usbi_tls_key_get(usbi_tls_key_t key) +{ + return pthread_getspecific(key); +} +static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr) +{ + (void)pthread_setspecific(key, ptr); +} +static inline void usbi_tls_key_delete(usbi_tls_key_t key) +{ + (void)pthread_key_delete(key); +} + +int usbi_get_tid(void); + +#endif /* LIBUSB_THREADS_POSIX_H */ diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.c new file mode 100644 index 00000000..409c4905 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.c @@ -0,0 +1,126 @@ +/* + * libusb synchronization on Microsoft Windows + * + * Copyright © 2010 Michael Plante + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include + +#include "libusbi.h" + +struct usbi_cond_perthread { + struct list_head list; + HANDLE event; +}; + +void usbi_mutex_static_lock(usbi_mutex_static_t *mutex) +{ + while (InterlockedExchange(mutex, 1L) == 1L) + SleepEx(0, TRUE); +} + +void usbi_cond_init(usbi_cond_t *cond) +{ + list_init(&cond->waiters); + list_init(&cond->not_waiting); +} + +static int usbi_cond_intwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, DWORD timeout_ms) +{ + struct usbi_cond_perthread *pos; + DWORD r; + + // Same assumption as usbi_cond_broadcast() holds + if (list_empty(&cond->not_waiting)) { + pos = malloc(sizeof(*pos)); + if (pos == NULL) + return ENOMEM; // This errno is not POSIX-allowed. + pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset. + if (pos->event == NULL) { + free(pos); + return ENOMEM; + } + } else { + pos = list_first_entry(&cond->not_waiting, struct usbi_cond_perthread, list); + list_del(&pos->list); // remove from not_waiting list. + // Ensure the event is clear before waiting + WaitForSingleObject(pos->event, 0); + } + + list_add(&pos->list, &cond->waiters); + + LeaveCriticalSection(mutex); + r = WaitForSingleObject(pos->event, timeout_ms); + EnterCriticalSection(mutex); + + list_del(&pos->list); + list_add(&pos->list, &cond->not_waiting); + + if (r == WAIT_OBJECT_0) + return 0; + else if (r == WAIT_TIMEOUT) + return ETIMEDOUT; + else + return EINVAL; +} + +// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot! +int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) +{ + return usbi_cond_intwait(cond, mutex, INFINITE); +} + +int usbi_cond_timedwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, const struct timeval *tv) +{ + DWORD millis; + + millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + /* round up to next millisecond */ + if (tv->tv_usec % 1000) + millis++; + return usbi_cond_intwait(cond, mutex, millis); +} + +void usbi_cond_broadcast(usbi_cond_t *cond) +{ + // Assumes mutex is locked; this is not in keeping with POSIX spec, but + // libusb does this anyway, so we simplify by not adding more sync + // primitives to the CV definition! + struct usbi_cond_perthread *pos; + + list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) + SetEvent(pos->event); + // The wait function will remove its respective item from the list. +} + +void usbi_cond_destroy(usbi_cond_t *cond) +{ + // This assumes no one is using this anymore. The check MAY NOT BE safe. + struct usbi_cond_perthread *pos, *next; + + if (!list_empty(&cond->waiters)) + return; // (!see above!) + list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) { + CloseHandle(pos->event); + list_del(&pos->list); + free(pos); + } +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.h new file mode 100644 index 00000000..409de2d0 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/threads_windows.h @@ -0,0 +1,111 @@ +/* + * libusb synchronization on Microsoft Windows + * + * Copyright © 2010 Michael Plante + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_THREADS_WINDOWS_H +#define LIBUSB_THREADS_WINDOWS_H + +#define USBI_MUTEX_INITIALIZER 0L +#ifdef _WIN32_WCE +typedef LONG usbi_mutex_static_t; +#else +typedef volatile LONG usbi_mutex_static_t; +#endif +void usbi_mutex_static_lock(usbi_mutex_static_t *mutex); +static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) +{ + InterlockedExchange(mutex, 0L); +} + +typedef CRITICAL_SECTION usbi_mutex_t; +static inline int usbi_mutex_init(usbi_mutex_t *mutex) +{ + InitializeCriticalSection(mutex); + return 0; +} +static inline void usbi_mutex_lock(usbi_mutex_t *mutex) +{ + EnterCriticalSection(mutex); +} +static inline void usbi_mutex_unlock(usbi_mutex_t *mutex) +{ + LeaveCriticalSection(mutex); +} +static inline int usbi_mutex_trylock(usbi_mutex_t *mutex) +{ + return !TryEnterCriticalSection(mutex); +} +static inline void usbi_mutex_destroy(usbi_mutex_t *mutex) +{ + DeleteCriticalSection(mutex); +} + +// We *were* getting timespec from pthread.h: +#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED)) +#define HAVE_STRUCT_TIMESPEC 1 +#define _TIMESPEC_DEFINED 1 +struct timespec { + long tv_sec; + long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */ + +// We *were* getting ETIMEDOUT from pthread.h: +#ifndef ETIMEDOUT +#define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +typedef struct usbi_cond { + // Every time a thread touches the CV, it winds up in one of these lists. + // It stays there until the CV is destroyed, even if the thread terminates. + struct list_head waiters; + struct list_head not_waiting; +} usbi_cond_t; + +void usbi_cond_init(usbi_cond_t *cond); +int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex); +int usbi_cond_timedwait(usbi_cond_t *cond, + usbi_mutex_t *mutex, const struct timeval *tv); +void usbi_cond_broadcast(usbi_cond_t *cond); +void usbi_cond_destroy(usbi_cond_t *cond); + +typedef DWORD usbi_tls_key_t; +static inline void usbi_tls_key_create(usbi_tls_key_t *key) +{ + *key = TlsAlloc(); +} +static inline void *usbi_tls_key_get(usbi_tls_key_t key) +{ + return TlsGetValue(key); +} +static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr) +{ + (void)TlsSetValue(key, ptr); +} +static inline void usbi_tls_key_delete(usbi_tls_key_t key) +{ + (void)TlsFree(key); +} + +static inline int usbi_get_tid(void) +{ + return (int)GetCurrentThreadId(); +} + +#endif /* LIBUSB_THREADS_WINDOWS_H */ diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.c new file mode 100644 index 00000000..a0f35e93 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.c @@ -0,0 +1,888 @@ +/* + * Windows CE backend for libusb 1.0 + * Copyright © 2011-2013 RealVNC Ltd. + * Large portions taken from Windows backend, which is + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "libusbi.h" +#include "wince_usb.h" + +// Global variables +int errno = 0; +static uint64_t hires_frequency, hires_ticks_to_ps; +static HANDLE driver_handle = INVALID_HANDLE_VALUE; +static int concurrent_usage = -1; + +/* + * Converts a windows error to human readable string + * uses retval as errorcode, or, if 0, use GetLastError() + */ +#if defined(ENABLE_LOGGING) +static const char *windows_error_str(DWORD error_code) +{ + static TCHAR wErr_string[ERR_BUFFER_SIZE]; + static char err_string[ERR_BUFFER_SIZE]; + + DWORD size; + int len; + + if (error_code == 0) + error_code = GetLastError(); + + len = sprintf(err_string, "[%u] ", (unsigned int)error_code); + + size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + wErr_string, ERR_BUFFER_SIZE, NULL); + if (size == 0) { + DWORD format_error = GetLastError(); + if (format_error) + snprintf(err_string, ERR_BUFFER_SIZE, + "Windows error code %u (FormatMessage error code %u)", + (unsigned int)error_code, (unsigned int)format_error); + else + snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code); + } else { + // Remove CR/LF terminators, if present + size_t pos = size - 2; + if (wErr_string[pos] == 0x0D) + wErr_string[pos] = 0; + + if (!WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, &err_string[len], ERR_BUFFER_SIZE - len, NULL, NULL)) + strcpy(err_string, "Unable to convert error string"); + } + + return err_string; +} +#endif + +static struct wince_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct wince_device_priv *)dev->os_priv; +} + +// ceusbkwrapper to libusb error code mapping +static int translate_driver_error(DWORD error) +{ + switch (error) { + case ERROR_INVALID_PARAMETER: + return LIBUSB_ERROR_INVALID_PARAM; + case ERROR_CALL_NOT_IMPLEMENTED: + case ERROR_NOT_SUPPORTED: + return LIBUSB_ERROR_NOT_SUPPORTED; + case ERROR_NOT_ENOUGH_MEMORY: + return LIBUSB_ERROR_NO_MEM; + case ERROR_INVALID_HANDLE: + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_BUSY: + return LIBUSB_ERROR_BUSY; + + // Error codes that are either unexpected, or have + // no suitable LIBUSB_ERROR equivalent. + case ERROR_CANCELLED: + case ERROR_INTERNAL_ERROR: + default: + return LIBUSB_ERROR_OTHER; + } +} + +static BOOL init_dllimports(void) +{ + DLL_GET_HANDLE(ceusbkwrapper); + DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE); + DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE); + + return TRUE; +} + +static void exit_dllimports(void) +{ + DLL_FREE_HANDLE(ceusbkwrapper); +} + +static int init_device( + struct libusb_device *dev, UKW_DEVICE drv_dev, + unsigned char bus_addr, unsigned char dev_addr) +{ + struct wince_device_priv *priv = _device_priv(dev); + int r = LIBUSB_SUCCESS; + + dev->bus_number = bus_addr; + dev->device_address = dev_addr; + priv->dev = drv_dev; + + if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc))) + r = translate_driver_error(GetLastError()); + + return r; +} + +// Internal API functions +static int wince_init(struct libusb_context *ctx) +{ + int r = LIBUSB_ERROR_OTHER; + HANDLE semaphore; + LARGE_INTEGER li_frequency; + TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + + _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphore(NULL, 1, 1, sem_name); + if (semaphore == NULL) { + usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_MEM; + } + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore's release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0)); + CloseHandle(semaphore); + return LIBUSB_ERROR_NO_MEM; + } + + // NB: concurrent usage supposes that init calls are equally balanced with + // exit calls. If init is called more than exit, we will not exit properly + if ( ++concurrent_usage == 0 ) { // First init? + // Load DLL imports + if (!init_dllimports()) { + usbi_err(ctx, "could not resolve DLL functions"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + // try to open a handle to the driver + driver_handle = UkwOpenDriver(); + if (driver_handle == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "could not connect to driver"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + // find out if we have access to a monotonic (hires) timer + if (QueryPerformanceFrequency(&li_frequency)) { + hires_frequency = li_frequency.QuadPart; + // The hires frequency can go as high as 4 GHz, so we'll use a conversion + // to picoseconds to compute the tv_nsecs part in clock_gettime + hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency; + usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); + } else { + usbi_dbg("no hires timer available on this platform"); + hires_frequency = 0; + hires_ticks_to_ps = UINT64_C(0); + } + } + // At this stage, either we went through full init successfully, or didn't need to + r = LIBUSB_SUCCESS; + +init_exit: // Holds semaphore here. + if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed? + exit_dllimports(); + + if (driver_handle != INVALID_HANDLE_VALUE) { + UkwCloseDriver(driver_handle); + driver_handle = INVALID_HANDLE_VALUE; + } + } + + if (r != LIBUSB_SUCCESS) + --concurrent_usage; // Not expected to call libusb_exit if we failed. + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); + return r; +} + +static void wince_exit(struct libusb_context *ctx) +{ + HANDLE semaphore; + TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + UNUSED(ctx); + + _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphore(NULL, 1, 1, sem_name); + if (semaphore == NULL) + return; + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + CloseHandle(semaphore); + return; + } + + // Only works if exits and inits are balanced exactly + if (--concurrent_usage < 0) { // Last exit + exit_dllimports(); + + if (driver_handle != INVALID_HANDLE_VALUE) { + UkwCloseDriver(driver_handle); + driver_handle = INVALID_HANDLE_VALUE; + } + } + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); +} + +static int wince_get_device_list( + struct libusb_context *ctx, + struct discovered_devs **discdevs) +{ + UKW_DEVICE devices[MAX_DEVICE_COUNT]; + struct discovered_devs *new_devices = *discdevs; + DWORD count = 0, i; + struct libusb_device *dev = NULL; + unsigned char bus_addr, dev_addr; + unsigned long session_id; + BOOL success; + DWORD release_list_offset = 0; + int r = LIBUSB_SUCCESS; + + success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count); + if (!success) { + int libusbErr = translate_driver_error(GetLastError()); + usbi_err(ctx, "could not get devices: %s", windows_error_str(0)); + return libusbErr; + } + + for (i = 0; i < count; ++i) { + release_list_offset = i; + success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id); + if (!success) { + r = translate_driver_error(GetLastError()); + usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0)); + goto err_out; + } + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + usbi_dbg("using existing device for %u/%u (session %lu)", + bus_addr, dev_addr, session_id); + // Release just this element in the device list (as we already hold a + // reference to it). + UkwReleaseDeviceList(driver_handle, &devices[i], 1); + release_list_offset++; + } else { + usbi_dbg("allocating new device for %u/%u (session %lu)", + bus_addr, dev_addr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) { + r = LIBUSB_ERROR_NO_MEM; + goto err_out; + } + + r = init_device(dev, devices[i], bus_addr, dev_addr); + if (r < 0) + goto err_out; + + r = usbi_sanitize_device(dev); + if (r < 0) + goto err_out; + } + + new_devices = discovered_devs_append(new_devices, dev); + if (!new_devices) { + r = LIBUSB_ERROR_NO_MEM; + goto err_out; + } + + libusb_unref_device(dev); + } + + *discdevs = new_devices; + return r; +err_out: + *discdevs = new_devices; + libusb_unref_device(dev); + // Release the remainder of the unprocessed device list. + // The devices added to new_devices already will still be passed up to libusb, + // which can dispose of them at its leisure. + UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset); + return r; +} + +static int wince_open(struct libusb_device_handle *handle) +{ + // Nothing to do to open devices as a handle to it has + // been retrieved by wince_get_device_list + return LIBUSB_SUCCESS; +} + +static void wince_close(struct libusb_device_handle *handle) +{ + // Nothing to do as wince_open does nothing. +} + +static int wince_get_device_descriptor( + struct libusb_device *device, + unsigned char *buffer, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + + *host_endian = 1; + memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH); + return LIBUSB_SUCCESS; +} + +static int wince_get_active_config_descriptor( + struct libusb_device *device, + unsigned char *buffer, size_t len, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + DWORD actualSize = len; + + *host_endian = 0; + if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize)) + return translate_driver_error(GetLastError()); + + return actualSize; +} + +static int wince_get_config_descriptor( + struct libusb_device *device, + uint8_t config_index, + unsigned char *buffer, size_t len, int *host_endian) +{ + struct wince_device_priv *priv = _device_priv(device); + DWORD actualSize = len; + + *host_endian = 0; + if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize)) + return translate_driver_error(GetLastError()); + + return actualSize; +} + +static int wince_get_configuration( + struct libusb_device_handle *handle, + int *config) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + UCHAR cv = 0; + + if (!UkwGetConfig(priv->dev, &cv)) + return translate_driver_error(GetLastError()); + + (*config) = cv; + return LIBUSB_SUCCESS; +} + +static int wince_set_configuration( + struct libusb_device_handle *handle, + int config) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + // Setting configuration 0 places the device in Address state. + // This should correspond to the "unconfigured state" required by + // libusb when the specified configuration is -1. + UCHAR cv = (config < 0) ? 0 : config; + if (!UkwSetConfig(priv->dev, cv)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_claim_interface( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwClaimInterface(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_release_interface( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0)) + return translate_driver_error(GetLastError()); + + if (!UkwReleaseInterface(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_set_interface_altsetting( + struct libusb_device_handle *handle, + int interface_number, int altsetting) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_clear_halt( + struct libusb_device_handle *handle, + unsigned char endpoint) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwClearHaltHost(priv->dev, endpoint)) + return translate_driver_error(GetLastError()); + + if (!UkwClearHaltDevice(priv->dev, endpoint)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_reset_device( + struct libusb_device_handle *handle) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwResetDevice(priv->dev)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_kernel_driver_active( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + BOOL result = FALSE; + + if (!UkwKernelDriverActive(priv->dev, interface_number, &result)) + return translate_driver_error(GetLastError()); + + return result ? 1 : 0; +} + +static int wince_detach_kernel_driver( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwDetachKernelDriver(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_attach_kernel_driver( + struct libusb_device_handle *handle, + int interface_number) +{ + struct wince_device_priv *priv = _device_priv(handle->dev); + + if (!UkwAttachKernelDriver(priv->dev, interface_number)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static void wince_destroy_device(struct libusb_device *dev) +{ + struct wince_device_priv *priv = _device_priv(dev); + + UkwReleaseDeviceList(driver_handle, &priv->dev, 1); +} + +static void wince_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + + usbi_close(transfer_priv->pollable_fd.fd); + transfer_priv->pollable_fd = INVALID_WINFD; +} + +static int wince_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + + if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT)) + return translate_driver_error(GetLastError()); + + return LIBUSB_SUCCESS; +} + +static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + BOOL direction_in, ret; + struct winfd wfd; + DWORD flags; + PUKW_CONTROL_HEADER setup = NULL; + const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL; + int r; + + if (control_transfer) { + setup = (PUKW_CONTROL_HEADER) transfer->buffer; + direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN; + } else { + direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN; + } + flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER; + flags |= UKW_TF_SHORT_TRANSFER_OK; + + wfd = usbi_create_fd(); + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_add_pollfd(ctx, wfd.fd, direction_in ? POLLIN : POLLOUT); + if (r) { + usbi_close(wfd.fd); + return r; + } + + transfer_priv->pollable_fd = wfd; + + if (control_transfer) { + // Split out control setup header and data buffer + DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER); + PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)]; + + ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped); + } else { + ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, + transfer->length, &transfer->actual_length, wfd.overlapped); + } + + if (!ret) { + int libusbErr = translate_driver_error(GetLastError()); + usbi_err(ctx, "UkwIssue%sTransfer failed: error %u", + control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError()); + usbi_remove_pollfd(ctx, wfd.fd); + usbi_close(wfd.fd); + transfer_priv->pollable_fd = INVALID_WINFD; + return libusbErr; + } + + + return LIBUSB_SUCCESS; +} + +static int wince_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return wince_submit_control_or_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static void wince_transfer_callback( + struct usbi_transfer *itransfer, + uint32_t io_result, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); + struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int status; + + usbi_dbg("handling I/O completion with errcode %u", io_result); + + if (io_result == ERROR_NOT_SUPPORTED && + transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) { + /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper + * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the + * endpoint isn't actually stalled. + * + * One example of this is that some devices will occasionally fail to reply to an IN + * token. The WinCE USB layer carries on with the transaction until it is completed + * (or cancelled) but then completes it with USB_ERROR_STALL. + * + * This code therefore needs to confirm that there really is a stall error, by both + * checking the pipe status and requesting the endpoint status from the device. + */ + BOOL halted = FALSE; + usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall"); + if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) { + /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS + * control request to the device. This is done synchronously, which is a bit + * naughty, but this is a special corner case. + */ + WORD wStatus = 0; + DWORD written = 0; + UKW_CONTROL_HEADER ctrlHeader; + ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD | + LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT; + ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS; + ctrlHeader.wValue = 0; + ctrlHeader.wIndex = transfer->endpoint; + ctrlHeader.wLength = sizeof(wStatus); + if (UkwIssueControlTransfer(priv->dev, + UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT, + &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) { + if (written == sizeof(wStatus) && + (wStatus & STATUS_HALT_FLAG) == 0) { + if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) { + usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success"); + io_result = ERROR_SUCCESS; + } else { + usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error"); + io_result = ERROR_IO_DEVICE; + } + } + } + } + } + + switch(io_result) { + case ERROR_SUCCESS: + itransfer->transferred += io_size; + status = LIBUSB_TRANSFER_COMPLETED; + break; + case ERROR_CANCELLED: + usbi_dbg("detected transfer cancel"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + case ERROR_NOT_SUPPORTED: + case ERROR_GEN_FAILURE: + usbi_dbg("detected endpoint stall"); + status = LIBUSB_TRANSFER_STALL; + break; + case ERROR_SEM_TIMEOUT: + usbi_dbg("detected semaphore timeout"); + status = LIBUSB_TRANSFER_TIMED_OUT; + break; + case ERROR_OPERATION_ABORTED: + usbi_dbg("detected operation aborted"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result)); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + wince_clear_transfer_priv(itransfer); + if (status == LIBUSB_TRANSFER_CANCELLED) + usbi_handle_transfer_cancellation(itransfer); + else + usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); +} + +static void wince_handle_callback( + struct usbi_transfer *itransfer, + uint32_t io_result, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + wince_transfer_callback (itransfer, io_result, io_size); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + } +} + +static int wince_handle_events( + struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + struct wince_transfer_priv* transfer_priv = NULL; + POLL_NFDS_TYPE i = 0; + BOOL found = FALSE; + struct usbi_transfer *itransfer; + DWORD io_size, io_result; + int r = LIBUSB_SUCCESS; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + + usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents); + + if (!fds[i].revents) + continue; + + num_ready--; + + // Because a Windows OVERLAPPED is used for poll emulation, + // a pollable fd is created and stored with each transfer + usbi_mutex_lock(&ctx->flying_transfers_lock); + list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) { + transfer_priv = usbi_transfer_get_os_priv(itransfer); + if (transfer_priv->pollable_fd.fd == fds[i].fd) { + found = TRUE; + break; + } + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) { + io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal; + io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh; + usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd); + // let handle_callback free the event using the transfer wfd + // If you don't use the transfer wfd, you run a risk of trying to free a + // newly allocated wfd that took the place of the one from the transfer. + wince_handle_callback(itransfer, io_result, io_size); + } else if (found) { + usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]); + r = LIBUSB_ERROR_OTHER; + break; + } else { + usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]); + r = LIBUSB_ERROR_NOT_FOUND; + break; + } + } + usbi_mutex_unlock(&ctx->open_devs_lock); + + return r; +} + +/* + * Monotonic and real time functions + */ +static int wince_clock_gettime(int clk_id, struct timespec *tp) +{ + LARGE_INTEGER hires_counter; + ULARGE_INTEGER rtime; + FILETIME filetime; + SYSTEMTIME st; + + switch(clk_id) { + case USBI_CLOCK_MONOTONIC: + if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) { + tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency); + tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps); + return LIBUSB_SUCCESS; + } + // Fall through and return real-time if monotonic read failed or was not detected @ init + case USBI_CLOCK_REALTIME: + // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx + // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00 + // Note however that our resolution is bounded by the Windows system time + // functions and is at best of the order of 1 ms (or, usually, worse) + GetSystemTime(&st); + SystemTimeToFileTime(&st, &filetime); + rtime.LowPart = filetime.dwLowDateTime; + rtime.HighPart = filetime.dwHighDateTime; + rtime.QuadPart -= EPOCH_TIME; + tp->tv_sec = (long)(rtime.QuadPart / 10000000); + tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100); + return LIBUSB_SUCCESS; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +const struct usbi_os_backend usbi_backend = { + "Windows CE", + 0, + wince_init, + wince_exit, + NULL, /* set_option() */ + + wince_get_device_list, + NULL, /* hotplug_poll */ + wince_open, + wince_close, + + wince_get_device_descriptor, + wince_get_active_config_descriptor, + wince_get_config_descriptor, + NULL, /* get_config_descriptor_by_value() */ + + wince_get_configuration, + wince_set_configuration, + wince_claim_interface, + wince_release_interface, + + wince_set_interface_altsetting, + wince_clear_halt, + wince_reset_device, + + NULL, /* alloc_streams */ + NULL, /* free_streams */ + + NULL, /* dev_mem_alloc() */ + NULL, /* dev_mem_free() */ + + wince_kernel_driver_active, + wince_detach_kernel_driver, + wince_attach_kernel_driver, + + wince_destroy_device, + + wince_submit_transfer, + wince_cancel_transfer, + wince_clear_transfer_priv, + + wince_handle_events, + NULL, /* handle_transfer_completion() */ + + wince_clock_gettime, + 0, + sizeof(struct wince_device_priv), + 0, + sizeof(struct wince_transfer_priv), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.h new file mode 100644 index 00000000..edcb9fcc --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/wince_usb.h @@ -0,0 +1,126 @@ +/* + * Windows CE backend for libusb 1.0 + * Copyright © 2011-2013 RealVNC Ltd. + * Portions taken from Windows backend, which is + * Copyright © 2009-2010 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#pragma once + +#include "windows_common.h" + +#include +#include "poll_windows.h" + +#define MAX_DEVICE_COUNT 256 + +// This is a modified dump of the types in the ceusbkwrapper.h library header +// with functions transformed into extern pointers. +// +// This backend dynamically loads ceusbkwrapper.dll and doesn't include +// ceusbkwrapper.h directly to simplify the build process. The kernel +// side wrapper driver is built using the platform image build tools, +// which makes it difficult to reference directly from the libusb build +// system. +struct UKW_DEVICE_PRIV; +typedef struct UKW_DEVICE_PRIV *UKW_DEVICE; +typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE; + +typedef struct { + UINT8 bLength; + UINT8 bDescriptorType; + UINT16 bcdUSB; + UINT8 bDeviceClass; + UINT8 bDeviceSubClass; + UINT8 bDeviceProtocol; + UINT8 bMaxPacketSize0; + UINT16 idVendor; + UINT16 idProduct; + UINT16 bcdDevice; + UINT8 iManufacturer; + UINT8 iProduct; + UINT8 iSerialNumber; + UINT8 bNumConfigurations; +} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR; + +typedef struct { + UINT8 bmRequestType; + UINT8 bRequest; + UINT16 wValue; + UINT16 wIndex; + UINT16 wLength; +} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER; + +// Collection of flags which can be used when issuing transfer requests +/* Indicates that the transfer direction is 'in' */ +#define UKW_TF_IN_TRANSFER 0x00000001 +/* Indicates that the transfer direction is 'out' */ +#define UKW_TF_OUT_TRANSFER 0x00000000 +/* Specifies that the transfer should complete as soon as possible, + * even if no OVERLAPPED structure has been provided. */ +#define UKW_TF_NO_WAIT 0x00000100 +/* Indicates that transfers shorter than the buffer are ok */ +#define UKW_TF_SHORT_TRANSFER_OK 0x00000200 +#define UKW_TF_SEND_TO_DEVICE 0x00010000 +#define UKW_TF_SEND_TO_INTERFACE 0x00020000 +#define UKW_TF_SEND_TO_ENDPOINT 0x00040000 +/* Don't block when waiting for memory allocations */ +#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000 + +/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor, + * to specify the currently active configuration for the device. */ +#define UKW_ACTIVE_CONFIGURATION -1 + +DLL_DECLARE_HANDLE(ceusbkwrapper); +DLL_DECLARE_FUNC(WINAPI, HANDLE, UkwOpenDriver, ()); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD)); +DLL_DECLARE_FUNC(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD)); +DLL_DECLARE_FUNC(WINAPI, void, UkwCloseDriver, (HANDLE)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)); +DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL)); + +// Used to determine if an endpoint status really is halted on a failed transfer. +#define STATUS_HALT_FLAG 0x1 + +struct wince_device_priv { + UKW_DEVICE dev; + UKW_DEVICE_DESCRIPTOR desc; +}; + +struct wince_transfer_priv { + struct winfd pollable_fd; + uint8_t interface_number; +}; + diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_common.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_common.h new file mode 100644 index 00000000..b1725c2e --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_common.h @@ -0,0 +1,128 @@ +/* + * Windows backend common header for libusb 1.0 + * + * This file brings together header code common between + * the desktop Windows and Windows CE backends. + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// Windows API default is uppercase - ugh! +#if !defined(bool) +#define bool BOOL +#endif +#if !defined(true) +#define true TRUE +#endif +#if !defined(false) +#define false FALSE +#endif + +#define EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime + +#if defined(__CYGWIN__ ) +#define _stricmp strcasecmp +#define _strdup strdup +// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread +#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, (LPDWORD)f) +#endif + +#define safe_free(p) do {if (p != NULL) {free((void *)p); p = NULL;}} while (0) + +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +#define ERR_BUFFER_SIZE 256 + +/* + * API macros - leveraged from libusb-win32 1.x + */ +#ifndef _WIN32_WCE +#define DLL_STRINGIFY(s) #s +#define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name)) +#else +#define DLL_STRINGIFY(s) L#s +#define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name)) +#endif + +/* + * Macros for handling DLL themselves + */ +#define DLL_HANDLE_NAME(name) __dll_##name##_handle + +#define DLL_DECLARE_HANDLE(name) \ + static HMODULE DLL_HANDLE_NAME(name) = NULL + +#define DLL_GET_HANDLE(name) \ + do { \ + DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name); \ + if (!DLL_HANDLE_NAME(name)) \ + return FALSE; \ + } while (0) + +#define DLL_FREE_HANDLE(name) \ + do { \ + if (DLL_HANDLE_NAME(name)) { \ + FreeLibrary(DLL_HANDLE_NAME(name)); \ + DLL_HANDLE_NAME(name) = NULL; \ + } \ + } while (0) + + +/* + * Macros for handling functions within a DLL + */ +#define DLL_FUNC_NAME(name) __dll_##name##_func_t + +#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \ + typedef ret (api * DLL_FUNC_NAME(name))args; \ + static DLL_FUNC_NAME(name) prefixname = NULL + +#define DLL_DECLARE_FUNC(api, ret, name, args) \ + DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args) +#define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \ + DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args) + +#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \ + do { \ + HMODULE h = DLL_HANDLE_NAME(dll); \ + prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \ + DLL_STRINGIFY(name)); \ + if (prefixname) \ + break; \ + prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \ + DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \ + if (prefixname) \ + break; \ + prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \ + DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \ + if (prefixname) \ + break; \ + if (ret_on_failure) \ + return FALSE; \ + } while (0) + +#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \ + DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure) +#define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \ + DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure) diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.c new file mode 100644 index 00000000..92dbde5a --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.c @@ -0,0 +1,1008 @@ +/* + * windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software + * Hash table functions adapted from glibc, by Ulrich Drepper et al. + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include + +#include "libusbi.h" +#include "windows_common.h" +#include "windows_nt_common.h" + +// Public +BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED); +enum windows_version windows_version = WINDOWS_UNDEFINED; + + // Global variables for init/exit +static unsigned int init_count = 0; +static bool usbdk_available = false; + +// Global variables for clock_gettime mechanism +static uint64_t hires_ticks_to_ps; +static uint64_t hires_frequency; + +#define TIMER_REQUEST_RETRY_MS 100 +#define WM_TIMER_REQUEST (WM_USER + 1) +#define WM_TIMER_EXIT (WM_USER + 2) + +// used for monotonic clock_gettime() +struct timer_request { + struct timespec *tp; + HANDLE event; +}; + +// Timer thread +static HANDLE timer_thread = NULL; +static DWORD timer_thread_id = 0; + +/* Kernel32 dependencies */ +DLL_DECLARE_HANDLE(Kernel32); +/* This call is only available from XP SP2 */ +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL)); + +/* User32 dependencies */ +DLL_DECLARE_HANDLE(User32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM)); + +static unsigned __stdcall windows_clock_gettime_threaded(void *param); + +/* +* Converts a windows error to human readable string +* uses retval as errorcode, or, if 0, use GetLastError() +*/ +#if defined(ENABLE_LOGGING) +const char *windows_error_str(DWORD error_code) +{ + static char err_string[ERR_BUFFER_SIZE]; + + DWORD size; + int len; + + if (error_code == 0) + error_code = GetLastError(); + + len = sprintf(err_string, "[%u] ", (unsigned int)error_code); + + // Translate codes returned by SetupAPI. The ones we are dealing with are either + // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes. + // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff545011.aspx + switch (error_code & 0xE0000000) { + case 0: + error_code = HRESULT_FROM_WIN32(error_code); // Still leaves ERROR_SUCCESS unmodified + break; + case 0xE0000000: + error_code = 0x80000000 | (FACILITY_SETUPAPI << 16) | (error_code & 0x0000FFFF); + break; + default: + break; + } + + size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + &err_string[len], ERR_BUFFER_SIZE - len, NULL); + if (size == 0) { + DWORD format_error = GetLastError(); + if (format_error) + snprintf(err_string, ERR_BUFFER_SIZE, + "Windows error code %u (FormatMessage error code %u)", + (unsigned int)error_code, (unsigned int)format_error); + else + snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code); + } else { + // Remove CRLF from end of message, if present + size_t pos = len + size - 2; + if (err_string[pos] == '\r') + err_string[pos] = '\0'; + } + + return err_string; +} +#endif + +static inline struct windows_context_priv *_context_priv(struct libusb_context *ctx) +{ + return (struct windows_context_priv *)ctx->os_priv; +} + +/* Hash table functions - modified From glibc 2.3.2: + [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 + [Knuth] The Art of Computer Programming, part 3 (6.4) */ + +#define HTAB_SIZE 1021UL // *MUST* be a prime number!! + +typedef struct htab_entry { + unsigned long used; + char *str; +} htab_entry; + +static htab_entry *htab_table = NULL; +static usbi_mutex_t htab_mutex; +static unsigned long htab_filled; + +/* Before using the hash table we must allocate memory for it. + We allocate one element more as the found prime number says. + This is done for more effective indexing as explained in the + comment for the hash function. */ +static bool htab_create(struct libusb_context *ctx) +{ + if (htab_table != NULL) { + usbi_err(ctx, "hash table already allocated"); + return true; + } + + // Create a mutex + usbi_mutex_init(&htab_mutex); + + usbi_dbg("using %lu entries hash table", HTAB_SIZE); + htab_filled = 0; + + // allocate memory and zero out. + htab_table = calloc(HTAB_SIZE + 1, sizeof(htab_entry)); + if (htab_table == NULL) { + usbi_err(ctx, "could not allocate space for hash table"); + return false; + } + + return true; +} + +/* After using the hash table it has to be destroyed. */ +static void htab_destroy(void) +{ + unsigned long i; + + if (htab_table == NULL) + return; + + for (i = 0; i < HTAB_SIZE; i++) + free(htab_table[i].str); + + safe_free(htab_table); + + usbi_mutex_destroy(&htab_mutex); +} + +/* This is the search function. It uses double hashing with open addressing. + We use a trick to speed up the lookup. The table is created with one + more element available. This enables us to use the index zero special. + This index will never be used because we store the first hash index in + the field used where zero means not used. Every other value means used. + The used field can be used as a first fast comparison for equality of + the stored and the parameter value. This helps to prevent unnecessary + expensive calls of strcmp. */ +unsigned long htab_hash(const char *str) +{ + unsigned long hval, hval2; + unsigned long idx; + unsigned long r = 5381; + int c; + const char *sz = str; + + if (str == NULL) + return 0; + + // Compute main hash value (algorithm suggested by Nokia) + while ((c = *sz++) != 0) + r = ((r << 5) + r) + c; + if (r == 0) + ++r; + + // compute table hash: simply take the modulus + hval = r % HTAB_SIZE; + if (hval == 0) + ++hval; + + // Try the first index + idx = hval; + + // Mutually exclusive access (R/W lock would be better) + usbi_mutex_lock(&htab_mutex); + + if (htab_table[idx].used) { + if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0)) + goto out_unlock; // existing hash + + usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str); + + // Second hash function, as suggested in [Knuth] + hval2 = 1 + hval % (HTAB_SIZE - 2); + + do { + // Because size is prime this guarantees to step through all available indexes + if (idx <= hval2) + idx = HTAB_SIZE + idx - hval2; + else + idx -= hval2; + + // If we visited all entries leave the loop unsuccessfully + if (idx == hval) + break; + + // If entry is found use it. + if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0)) + goto out_unlock; + } while (htab_table[idx].used); + } + + // Not found => New entry + + // If the table is full return an error + if (htab_filled >= HTAB_SIZE) { + usbi_err(NULL, "hash table is full (%lu entries)", HTAB_SIZE); + idx = 0; + goto out_unlock; + } + + htab_table[idx].str = _strdup(str); + if (htab_table[idx].str == NULL) { + usbi_err(NULL, "could not duplicate string for hash table"); + idx = 0; + goto out_unlock; + } + + htab_table[idx].used = hval; + ++htab_filled; + +out_unlock: + usbi_mutex_unlock(&htab_mutex); + + return idx; +} + +/* +* Make a transfer complete synchronously +*/ +void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size) +{ + overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; + overlapped->InternalHigh = size; + SetEvent(overlapped->hEvent); +} + +static BOOL windows_init_dlls(void) +{ + DLL_GET_HANDLE(Kernel32); + DLL_LOAD_FUNC_PREFIXED(Kernel32, p, IsWow64Process, FALSE); + pCancelIoEx = (BOOL (WINAPI *)(HANDLE, LPOVERLAPPED)) + GetProcAddress(DLL_HANDLE_NAME(Kernel32), "CancelIoEx"); + usbi_dbg("Will use CancelIo%s for I/O cancellation", pCancelIoEx ? "Ex" : ""); + + DLL_GET_HANDLE(User32); + DLL_LOAD_FUNC_PREFIXED(User32, p, GetMessageA, TRUE); + DLL_LOAD_FUNC_PREFIXED(User32, p, PeekMessageA, TRUE); + DLL_LOAD_FUNC_PREFIXED(User32, p, PostThreadMessageA, TRUE); + + return TRUE; +} + +static void windows_exit_dlls(void) +{ + DLL_FREE_HANDLE(Kernel32); + DLL_FREE_HANDLE(User32); +} + +static bool windows_init_clock(struct libusb_context *ctx) +{ + DWORD_PTR affinity, dummy; + HANDLE event; + LARGE_INTEGER li_frequency; + int i; + + if (QueryPerformanceFrequency(&li_frequency)) { + // The hires frequency can go as high as 4 GHz, so we'll use a conversion + // to picoseconds to compute the tv_nsecs part in clock_gettime + hires_frequency = li_frequency.QuadPart; + hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency; + usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); + + // Because QueryPerformanceCounter might report different values when + // running on different cores, we create a separate thread for the timer + // calls, which we glue to the first available core always to prevent timing discrepancies. + if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) { + usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0)); + return false; + } + + // The process affinity mask is a bitmask where each set bit represents a core on + // which this process is allowed to run, so we find the first set bit + for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++); + affinity = (DWORD_PTR)(1 << i); + + usbi_dbg("timer thread will run on core #%d", i); + + event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (event == NULL) { + usbi_err(ctx, "could not create event: %s", windows_error_str(0)); + return false; + } + + timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event, + 0, (unsigned int *)&timer_thread_id); + if (timer_thread == NULL) { + usbi_err(ctx, "unable to create timer thread - aborting"); + CloseHandle(event); + return false; + } + + if (!SetThreadAffinityMask(timer_thread, affinity)) + usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise"); + + // Wait for timer thread to init before continuing. + if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failed to wait for timer thread to become ready - aborting"); + CloseHandle(event); + return false; + } + + CloseHandle(event); + } else { + usbi_dbg("no hires timer available on this platform"); + hires_frequency = 0; + hires_ticks_to_ps = UINT64_C(0); + } + + return true; +} + +static void windows_destroy_clock(void) +{ + if (timer_thread) { + // actually the signal to quit the thread. + if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) + || (WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) { + usbi_dbg("could not wait for timer thread to quit"); + TerminateThread(timer_thread, 1); + // shouldn't happen, but we're destroying + // all objects it might have held anyway. + } + CloseHandle(timer_thread); + timer_thread = NULL; + timer_thread_id = 0; + } +} + +/* Windows version detection */ +static BOOL is_x64(void) +{ + BOOL ret = FALSE; + + // Detect if we're running a 32 or 64 bit system + if (sizeof(uintptr_t) < 8) { + if (pIsWow64Process != NULL) + pIsWow64Process(GetCurrentProcess(), &ret); + } else { + ret = TRUE; + } + + return ret; +} + +static void get_windows_version(void) +{ + OSVERSIONINFOEXA vi, vi2; + const char *arch, *w = NULL; + unsigned major, minor, version; + ULONGLONG major_equal, minor_equal; + BOOL ws; + + windows_version = WINDOWS_UNDEFINED; + + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionExA((OSVERSIONINFOA *)&vi)) { + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA((OSVERSIONINFOA *)&vi)) + return; + } + + if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) + return; + + if ((vi.dwMajorVersion > 6) || ((vi.dwMajorVersion == 6) && (vi.dwMinorVersion >= 2))) { + // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version + // See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx + + major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); + for (major = vi.dwMajorVersion; major <= 9; major++) { + memset(&vi2, 0, sizeof(vi2)); + vi2.dwOSVersionInfoSize = sizeof(vi2); + vi2.dwMajorVersion = major; + if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal)) + continue; + + if (vi.dwMajorVersion < major) { + vi.dwMajorVersion = major; + vi.dwMinorVersion = 0; + } + + minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); + for (minor = vi.dwMinorVersion; minor <= 9; minor++) { + memset(&vi2, 0, sizeof(vi2)); + vi2.dwOSVersionInfoSize = sizeof(vi2); + vi2.dwMinorVersion = minor; + if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal)) + continue; + + vi.dwMinorVersion = minor; + break; + } + + break; + } + } + + if ((vi.dwMajorVersion > 0xf) || (vi.dwMinorVersion > 0xf)) + return; + + ws = (vi.wProductType <= VER_NT_WORKSTATION); + version = vi.dwMajorVersion << 4 | vi.dwMinorVersion; + switch (version) { + case 0x50: windows_version = WINDOWS_2000; w = "2000"; break; + case 0x51: windows_version = WINDOWS_XP; w = "XP"; break; + case 0x52: windows_version = WINDOWS_2003; w = "2003"; break; + case 0x60: windows_version = WINDOWS_VISTA; w = (ws ? "Vista" : "2008"); break; + case 0x61: windows_version = WINDOWS_7; w = (ws ? "7" : "2008_R2"); break; + case 0x62: windows_version = WINDOWS_8; w = (ws ? "8" : "2012"); break; + case 0x63: windows_version = WINDOWS_8_1; w = (ws ? "8.1" : "2012_R2"); break; + case 0x64: windows_version = WINDOWS_10; w = (ws ? "10" : "2016"); break; + default: + if (version < 0x50) { + return; + } else { + windows_version = WINDOWS_11_OR_LATER; + w = "11 or later"; + } + } + + arch = is_x64() ? "64-bit" : "32-bit"; + + if (vi.wServicePackMinor) + usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch); + else if (vi.wServicePackMajor) + usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch); + else + usbi_dbg("Windows %s %s", w, arch); +} + +/* +* Monotonic and real time functions +*/ +static unsigned __stdcall windows_clock_gettime_threaded(void *param) +{ + struct timer_request *request; + LARGE_INTEGER hires_counter; + MSG msg; + + // The following call will create this thread's message queue + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx + pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + // Signal windows_init_clock() that we're ready to service requests + if (!SetEvent((HANDLE)param)) + usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0)); + param = NULL; + + // Main loop - wait for requests + while (1) { + if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) { + usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0)); + return 1; + } + + switch (msg.message) { + case WM_TIMER_REQUEST: + // Requests to this thread are for hires always + // Microsoft says that this function always succeeds on XP and later + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx + request = (struct timer_request *)msg.lParam; + QueryPerformanceCounter(&hires_counter); + request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency); + request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps); + if (!SetEvent(request->event)) + usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0)); + break; + case WM_TIMER_EXIT: + usbi_dbg("timer thread quitting"); + return 0; + } + } +} + +static void windows_transfer_callback(const struct windows_backend *backend, + struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size) +{ + int status, istatus; + + usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size); + + switch (io_result) { + case NO_ERROR: + status = backend->copy_transfer_data(itransfer, (uint32_t)io_size); + break; + case ERROR_GEN_FAILURE: + usbi_dbg("detected endpoint stall"); + status = LIBUSB_TRANSFER_STALL; + break; + case ERROR_SEM_TIMEOUT: + usbi_dbg("detected semaphore timeout"); + status = LIBUSB_TRANSFER_TIMED_OUT; + break; + case ERROR_OPERATION_ABORTED: + istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size); + if (istatus != LIBUSB_TRANSFER_COMPLETED) + usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); + + usbi_dbg("detected operation aborted"); + status = LIBUSB_TRANSFER_CANCELLED; + break; + case ERROR_FILE_NOT_FOUND: + usbi_dbg("detected device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result)); + status = LIBUSB_TRANSFER_ERROR; + break; + } + backend->clear_transfer_priv(itransfer); // Cancel polling + if (status == LIBUSB_TRANSFER_CANCELLED) + usbi_handle_transfer_cancellation(itransfer); + else + usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); +} + +static void windows_handle_callback(const struct windows_backend *backend, + struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + windows_transfer_callback(backend, itransfer, io_result, io_size); + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform"); + break; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + } +} + +static int windows_init(struct libusb_context *ctx) +{ + struct windows_context_priv *priv = _context_priv(ctx); + HANDLE semaphore; + char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + int r = LIBUSB_ERROR_OTHER; + bool winusb_backend_init = false; + + sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name); + if (semaphore == NULL) { + usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_MEM; + } + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore's release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0)); + CloseHandle(semaphore); + return LIBUSB_ERROR_NO_MEM; + } + + // NB: concurrent usage supposes that init calls are equally balanced with + // exit calls. If init is called more than exit, we will not exit properly + if (++init_count == 1) { // First init? + // Load DLL imports + if (!windows_init_dlls()) { + usbi_err(ctx, "could not resolve DLL functions"); + goto init_exit; + } + + get_windows_version(); + + if (windows_version == WINDOWS_UNDEFINED) { + usbi_err(ctx, "failed to detect Windows version"); + r = LIBUSB_ERROR_NOT_SUPPORTED; + goto init_exit; + } + + if (!windows_init_clock(ctx)) + goto init_exit; + + if (!htab_create(ctx)) + goto init_exit; + + r = winusb_backend.init(ctx); + if (r != LIBUSB_SUCCESS) + goto init_exit; + winusb_backend_init = true; + + r = usbdk_backend.init(ctx); + if (r == LIBUSB_SUCCESS) { + usbi_dbg("UsbDk backend is available"); + usbdk_available = true; + } else { + usbi_info(ctx, "UsbDk backend is not available"); + // Do not report this as an error + r = LIBUSB_SUCCESS; + } + } + + // By default, new contexts will use the WinUSB backend + priv->backend = &winusb_backend; + + r = LIBUSB_SUCCESS; + +init_exit: // Holds semaphore here + if ((init_count == 1) && (r != LIBUSB_SUCCESS)) { // First init failed? + if (winusb_backend_init) + winusb_backend.exit(ctx); + htab_destroy(); + windows_destroy_clock(); + windows_exit_dlls(); + --init_count; + } + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); + return r; +} + +static void windows_exit(struct libusb_context *ctx) +{ + HANDLE semaphore; + char sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0' + UNUSED(ctx); + + sprintf(sem_name, "libusb_init%08X", (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF)); + semaphore = CreateSemaphoreA(NULL, 1, 1, sem_name); + if (semaphore == NULL) + return; + + // A successful wait brings our semaphore count to 0 (unsignaled) + // => any concurent wait stalls until the semaphore release + if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) { + CloseHandle(semaphore); + return; + } + + // Only works if exits and inits are balanced exactly + if (--init_count == 0) { // Last exit + if (usbdk_available) { + usbdk_backend.exit(ctx); + usbdk_available = false; + } + winusb_backend.exit(ctx); + htab_destroy(); + windows_destroy_clock(); + windows_exit_dlls(); + } + + ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1 + CloseHandle(semaphore); +} + +static int windows_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap) +{ + struct windows_context_priv *priv = _context_priv(ctx); + + UNUSED(ap); + + switch (option) { + case LIBUSB_OPTION_USE_USBDK: + if (usbdk_available) { + usbi_dbg("switching context %p to use UsbDk backend", ctx); + priv->backend = &usbdk_backend; + } else { + usbi_err(ctx, "UsbDk backend not available"); + return LIBUSB_ERROR_NOT_FOUND; + } + return LIBUSB_SUCCESS; + default: + return LIBUSB_ERROR_NOT_SUPPORTED; + } + +} + +static int windows_get_device_list(struct libusb_context *ctx, struct discovered_devs **discdevs) +{ + struct windows_context_priv *priv = _context_priv(ctx); + return priv->backend->get_device_list(ctx, discdevs); +} + +static int windows_open(struct libusb_device_handle *dev_handle) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->open(dev_handle); +} + +static void windows_close(struct libusb_device_handle *dev_handle) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + priv->backend->close(dev_handle); +} + +static int windows_get_device_descriptor(struct libusb_device *dev, + unsigned char *buffer, int *host_endian) +{ + struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); + *host_endian = 0; + return priv->backend->get_device_descriptor(dev, buffer); +} + +static int windows_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buffer, size_t len, int *host_endian) +{ + struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); + *host_endian = 0; + return priv->backend->get_active_config_descriptor(dev, buffer, len); +} + +static int windows_get_config_descriptor(struct libusb_device *dev, + uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); + *host_endian = 0; + return priv->backend->get_config_descriptor(dev, config_index, buffer, len); +} + +static int windows_get_config_descriptor_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, unsigned char **buffer, int *host_endian) +{ + struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); + *host_endian = 0; + return priv->backend->get_config_descriptor_by_value(dev, bConfigurationValue, buffer); +} + +static int windows_get_configuration(struct libusb_device_handle *dev_handle, int *config) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->get_configuration(dev_handle, config); +} + +static int windows_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->set_configuration(dev_handle, config); +} + +static int windows_claim_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->claim_interface(dev_handle, interface_number); +} + +static int windows_release_interface(struct libusb_device_handle *dev_handle, int interface_number) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->release_interface(dev_handle, interface_number); +} + +static int windows_set_interface_altsetting(struct libusb_device_handle *dev_handle, + int interface_number, int altsetting) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->set_interface_altsetting(dev_handle, interface_number, altsetting); +} + +static int windows_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->clear_halt(dev_handle, endpoint); +} + +static int windows_reset_device(struct libusb_device_handle *dev_handle) +{ + struct windows_context_priv *priv = _context_priv(HANDLE_CTX(dev_handle)); + return priv->backend->reset_device(dev_handle); +} + +static void windows_destroy_device(struct libusb_device *dev) +{ + struct windows_context_priv *priv = _context_priv(DEVICE_CTX(dev)); + priv->backend->destroy_device(dev); +} + +static int windows_submit_transfer(struct usbi_transfer *itransfer) +{ + struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer)); + return priv->backend->submit_transfer(itransfer); +} + +static int windows_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer)); + return priv->backend->cancel_transfer(itransfer); +} + +static void windows_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer)); + priv->backend->clear_transfer_priv(itransfer); +} + +static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + struct windows_context_priv *priv = _context_priv(ctx); + struct usbi_transfer *itransfer; + DWORD io_size, io_result; + POLL_NFDS_TYPE i; + bool found; + int transfer_fd; + int r = LIBUSB_SUCCESS; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + + usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents); + + if (!fds[i].revents) + continue; + + num_ready--; + + // Because a Windows OVERLAPPED is used for poll emulation, + // a pollable fd is created and stored with each transfer + found = false; + transfer_fd = -1; + usbi_mutex_lock(&ctx->flying_transfers_lock); + list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) { + transfer_fd = priv->backend->get_transfer_fd(itransfer); + if (transfer_fd == fds[i].fd) { + found = true; + break; + } + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (found) { + priv->backend->get_overlapped_result(itransfer, &io_result, &io_size); + + usbi_remove_pollfd(ctx, transfer_fd); + + // let handle_callback free the event using the transfer wfd + // If you don't use the transfer wfd, you run a risk of trying to free a + // newly allocated wfd that took the place of the one from the transfer. + windows_handle_callback(priv->backend, itransfer, io_result, io_size); + } else { + usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd); + r = LIBUSB_ERROR_NOT_FOUND; + break; + } + } + usbi_mutex_unlock(&ctx->open_devs_lock); + + return r; +} + +static int windows_clock_gettime(int clk_id, struct timespec *tp) +{ + struct timer_request request; +#if !defined(_MSC_VER) || (_MSC_VER < 1900) + FILETIME filetime; + ULARGE_INTEGER rtime; +#endif + DWORD r; + + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + if (timer_thread) { + request.tp = tp; + request.event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (request.event == NULL) + return LIBUSB_ERROR_NO_MEM; + + if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) { + usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0)); + CloseHandle(request.event); + return LIBUSB_ERROR_OTHER; + } + + do { + r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS); + if (r == WAIT_TIMEOUT) + usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?"); + else if (r == WAIT_FAILED) + usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0)); + } while (r == WAIT_TIMEOUT); + CloseHandle(request.event); + + if (r == WAIT_OBJECT_0) + return LIBUSB_SUCCESS; + else + return LIBUSB_ERROR_OTHER; + } + // Fall through and return real-time if monotonic was not detected @ timer init + case USBI_CLOCK_REALTIME: +#if defined(_MSC_VER) && (_MSC_VER >= 1900) + timespec_get(tp, TIME_UTC); +#else + // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx + // with a predef epoch time to have an epoch that starts at 1970.01.01 00:00 + // Note however that our resolution is bounded by the Windows system time + // functions and is at best of the order of 1 ms (or, usually, worse) + GetSystemTimeAsFileTime(&filetime); + rtime.LowPart = filetime.dwLowDateTime; + rtime.HighPart = filetime.dwHighDateTime; + rtime.QuadPart -= EPOCH_TIME; + tp->tv_sec = (long)(rtime.QuadPart / 10000000); + tp->tv_nsec = (long)((rtime.QuadPart % 10000000) * 100); +#endif + return LIBUSB_SUCCESS; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +// NB: MSVC6 does not support named initializers. +const struct usbi_os_backend usbi_backend = { + "Windows", + USBI_CAP_HAS_HID_ACCESS, + windows_init, + windows_exit, + windows_set_option, + windows_get_device_list, + NULL, /* hotplug_poll */ + windows_open, + windows_close, + windows_get_device_descriptor, + windows_get_active_config_descriptor, + windows_get_config_descriptor, + windows_get_config_descriptor_by_value, + windows_get_configuration, + windows_set_configuration, + windows_claim_interface, + windows_release_interface, + windows_set_interface_altsetting, + windows_clear_halt, + windows_reset_device, + NULL, /* alloc_streams */ + NULL, /* free_streams */ + NULL, /* dev_mem_alloc */ + NULL, /* dev_mem_free */ + NULL, /* kernel_driver_active */ + NULL, /* detach_kernel_driver */ + NULL, /* attach_kernel_driver */ + windows_destroy_device, + windows_submit_transfer, + windows_cancel_transfer, + windows_clear_transfer_priv, + windows_handle_events, + NULL, /* handle_transfer_completion */ + windows_clock_gettime, + sizeof(struct windows_context_priv), + sizeof(union windows_device_priv), + sizeof(union windows_device_handle_priv), + sizeof(union windows_transfer_priv), +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.h new file mode 100644 index 00000000..e155b5d3 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_common.h @@ -0,0 +1,110 @@ +/* + * Windows backend common header for libusb 1.0 + * + * This file brings together header code common between + * the desktop Windows backends. + * Copyright © 2012-2013 RealVNC Ltd. + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "windows_nt_shared_types.h" + + /* Windows versions */ +enum windows_version { + WINDOWS_UNDEFINED, + WINDOWS_2000, + WINDOWS_XP, + WINDOWS_2003, // Also XP x64 + WINDOWS_VISTA, + WINDOWS_7, + WINDOWS_8, + WINDOWS_8_1, + WINDOWS_10, + WINDOWS_11_OR_LATER +}; + +extern enum windows_version windows_version; + +/* This call is only available from Vista */ +extern BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED); + +struct windows_backend { + int (*init)(struct libusb_context *ctx); + void (*exit)(struct libusb_context *ctx); + int (*get_device_list)(struct libusb_context *ctx, + struct discovered_devs **discdevs); + int (*open)(struct libusb_device_handle *dev_handle); + void (*close)(struct libusb_device_handle *dev_handle); + int (*get_device_descriptor)(struct libusb_device *device, unsigned char *buffer); + int (*get_active_config_descriptor)(struct libusb_device *device, + unsigned char *buffer, size_t len); + int (*get_config_descriptor)(struct libusb_device *device, + uint8_t config_index, unsigned char *buffer, size_t len); + int (*get_config_descriptor_by_value)(struct libusb_device *device, + uint8_t bConfigurationValue, unsigned char **buffer); + int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config); + int (*set_configuration)(struct libusb_device_handle *dev_handle, int config); + int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number); + int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number); + int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle, + int interface_number, int altsetting); + int (*clear_halt)(struct libusb_device_handle *dev_handle, + unsigned char endpoint); + int (*reset_device)(struct libusb_device_handle *dev_handle); + void (*destroy_device)(struct libusb_device *dev); + int (*submit_transfer)(struct usbi_transfer *itransfer); + int (*cancel_transfer)(struct usbi_transfer *itransfer); + void (*clear_transfer_priv)(struct usbi_transfer *itransfer); + int (*copy_transfer_data)(struct usbi_transfer *itransfer, uint32_t io_size); + int (*get_transfer_fd)(struct usbi_transfer *itransfer); + void (*get_overlapped_result)(struct usbi_transfer *itransfer, + DWORD *io_result, DWORD *io_size); +}; + +struct windows_context_priv { + const struct windows_backend *backend; +}; + +union windows_device_priv { + struct usbdk_device_priv usbdk_priv; + struct winusb_device_priv winusb_priv; +}; + +union windows_device_handle_priv { + struct usbdk_device_handle_priv usbdk_priv; + struct winusb_device_handle_priv winusb_priv; +}; + +union windows_transfer_priv { + struct usbdk_transfer_priv usbdk_priv; + struct winusb_transfer_priv winusb_priv; +}; + +extern const struct windows_backend usbdk_backend; +extern const struct windows_backend winusb_backend; + +unsigned long htab_hash(const char *str); +void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size); + +#if defined(ENABLE_LOGGING) +const char *windows_error_str(DWORD error_code); +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_shared_types.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_shared_types.h new file mode 100644 index 00000000..68bf261d --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_nt_shared_types.h @@ -0,0 +1,138 @@ +#pragma once + +#include "windows_common.h" + +#include + +typedef struct USB_DEVICE_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + USHORT bcdUSB; + UCHAR bDeviceClass; + UCHAR bDeviceSubClass; + UCHAR bDeviceProtocol; + UCHAR bMaxPacketSize0; + USHORT idVendor; + USHORT idProduct; + USHORT bcdDevice; + UCHAR iManufacturer; + UCHAR iProduct; + UCHAR iSerialNumber; + UCHAR bNumConfigurations; +} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; + +typedef struct USB_CONFIGURATION_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + USHORT wTotalLength; + UCHAR bNumInterfaces; + UCHAR bConfigurationValue; + UCHAR iConfiguration; + UCHAR bmAttributes; + UCHAR MaxPower; +} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; + +#include + +#define MAX_DEVICE_ID_LEN 200 + +typedef struct USB_DK_DEVICE_ID { + WCHAR DeviceID[MAX_DEVICE_ID_LEN]; + WCHAR InstanceID[MAX_DEVICE_ID_LEN]; +} USB_DK_DEVICE_ID, *PUSB_DK_DEVICE_ID; + +typedef struct USB_DK_DEVICE_INFO { + USB_DK_DEVICE_ID ID; + ULONG64 FilterID; + ULONG64 Port; + ULONG64 Speed; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; +} USB_DK_DEVICE_INFO, *PUSB_DK_DEVICE_INFO; + +typedef struct USB_DK_ISO_TRANSFER_RESULT { + ULONG64 ActualLength; + ULONG64 TransferResult; +} USB_DK_ISO_TRANSFER_RESULT, *PUSB_DK_ISO_TRANSFER_RESULT; + +typedef struct USB_DK_GEN_TRANSFER_RESULT { + ULONG64 BytesTransferred; + ULONG64 UsbdStatus; // USBD_STATUS code +} USB_DK_GEN_TRANSFER_RESULT, *PUSB_DK_GEN_TRANSFER_RESULT; + +typedef struct USB_DK_TRANSFER_RESULT { + USB_DK_GEN_TRANSFER_RESULT GenResult; + PVOID64 IsochronousResultsArray; // array of USB_DK_ISO_TRANSFER_RESULT +} USB_DK_TRANSFER_RESULT, *PUSB_DK_TRANSFER_RESULT; + +typedef struct USB_DK_TRANSFER_REQUEST { + ULONG64 EndpointAddress; + PVOID64 Buffer; + ULONG64 BufferLength; + ULONG64 TransferType; + ULONG64 IsochronousPacketsArraySize; + PVOID64 IsochronousPacketsArray; + USB_DK_TRANSFER_RESULT Result; +} USB_DK_TRANSFER_REQUEST, *PUSB_DK_TRANSFER_REQUEST; + +struct usbdk_device_priv { + USB_DK_DEVICE_INFO info; + PUSB_CONFIGURATION_DESCRIPTOR *config_descriptors; + HANDLE redirector_handle; + HANDLE system_handle; + uint8_t active_configuration; +}; + +struct winusb_device_priv { + bool initialized; + bool root_hub; + uint8_t active_config; + uint8_t depth; // distance to HCD + const struct windows_usb_api_backend *apib; + char *dev_id; + char *path; // device interface path + int sub_api; // for WinUSB-like APIs + struct { + char *path; // each interface needs a device interface path, + const struct windows_usb_api_backend *apib; // an API backend (multiple drivers support), + int sub_api; + int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS) + uint8_t *endpoint; + bool restricted_functionality; // indicates if the interface functionality is restricted + // by Windows (eg. HID keyboards or mice cannot do R/W) + } usb_interface[USB_MAXINTERFACES]; + struct hid_device_priv *hid; + USB_DEVICE_DESCRIPTOR dev_descriptor; + PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors +}; + +struct usbdk_device_handle_priv { + // Not currently used + char dummy; +}; + +struct winusb_device_handle_priv { + int active_interface; + struct { + HANDLE dev_handle; // WinUSB needs an extra handle for the file + HANDLE api_handle; // used by the API to communicate with the device + } interface_handle[USB_MAXINTERFACES]; + int autoclaim_count[USB_MAXINTERFACES]; // For auto-release +}; + +struct usbdk_transfer_priv { + USB_DK_TRANSFER_REQUEST request; + struct winfd pollable_fd; + HANDLE system_handle; + PULONG64 IsochronousPacketsArray; + PUSB_DK_ISO_TRANSFER_RESULT IsochronousResultsArray; +}; + +struct winusb_transfer_priv { + struct winfd pollable_fd; + HANDLE handle; + uint8_t interface_number; + uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID + uint8_t *hid_dest; // transfer buffer destination, required for HID + size_t hid_expected_size; + void *iso_context; +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.c new file mode 100644 index 00000000..fbccbd5c --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.c @@ -0,0 +1,830 @@ +/* + * windows UsbDk backend for libusb 1.0 + * Copyright © 2014 Red Hat, Inc. + + * Authors: + * Dmitry Fleytman + * Pavel Gurvich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "libusbi.h" +#include "windows_common.h" +#include "windows_nt_common.h" +#include "windows_usbdk.h" + +#if !defined(STATUS_SUCCESS) +typedef LONG NTSTATUS; +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif + +#if !defined(STATUS_CANCELLED) +#define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) +#endif + +#if !defined(STATUS_REQUEST_CANCELED) +#define STATUS_REQUEST_CANCELED ((NTSTATUS)0xC0000703L) +#endif + +#if !defined(USBD_SUCCESS) +typedef LONG USBD_STATUS; +#define USBD_SUCCESS(Status) ((USBD_STATUS) (Status) >= 0) +#define USBD_PENDING(Status) ((ULONG) (Status) >> 30 == 1) +#define USBD_ERROR(Status) ((USBD_STATUS) (Status) < 0) +#define USBD_STATUS_STALL_PID ((USBD_STATUS) 0xc0000004) +#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS) 0xc0000030) +#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS) 0xc0000a00) +#define USBD_STATUS_TIMEOUT ((USBD_STATUS) 0xc0006000) +#define USBD_STATUS_CANCELED ((USBD_STATUS) 0xc0010000) +#endif + +static inline struct usbdk_device_priv *_usbdk_device_priv(struct libusb_device *dev) +{ + return (struct usbdk_device_priv *)dev->os_priv; +} + +static inline struct usbdk_transfer_priv *_usbdk_transfer_priv(struct usbi_transfer *itransfer) +{ + return (struct usbdk_transfer_priv *)usbi_transfer_get_os_priv(itransfer); +} + +static struct { + HMODULE module; + + USBDK_GET_DEVICES_LIST GetDevicesList; + USBDK_RELEASE_DEVICES_LIST ReleaseDevicesList; + USBDK_START_REDIRECT StartRedirect; + USBDK_STOP_REDIRECT StopRedirect; + USBDK_GET_CONFIGURATION_DESCRIPTOR GetConfigurationDescriptor; + USBDK_RELEASE_CONFIGURATION_DESCRIPTOR ReleaseConfigurationDescriptor; + USBDK_READ_PIPE ReadPipe; + USBDK_WRITE_PIPE WritePipe; + USBDK_ABORT_PIPE AbortPipe; + USBDK_RESET_PIPE ResetPipe; + USBDK_SET_ALTSETTING SetAltsetting; + USBDK_RESET_DEVICE ResetDevice; + USBDK_GET_REDIRECTOR_SYSTEM_HANDLE GetRedirectorSystemHandle; +} usbdk_helper; + +static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name) +{ + FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name); + + if (api_ptr == NULL) + usbi_err(ctx, "UsbDkHelper API %s not found: %s", api_name, windows_error_str(0)); + + return api_ptr; +} + +static void unload_usbdk_helper_dll(void) +{ + if (usbdk_helper.module != NULL) { + FreeLibrary(usbdk_helper.module); + usbdk_helper.module = NULL; + } +} + +static int load_usbdk_helper_dll(struct libusb_context *ctx) +{ + usbdk_helper.module = LoadLibraryA("UsbDkHelper"); + if (usbdk_helper.module == NULL) { + usbi_err(ctx, "Failed to load UsbDkHelper.dll: %s", windows_error_str(0)); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbdk_helper.GetDevicesList = (USBDK_GET_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_GetDevicesList"); + if (usbdk_helper.GetDevicesList == NULL) + goto error_unload; + + usbdk_helper.ReleaseDevicesList = (USBDK_RELEASE_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseDevicesList"); + if (usbdk_helper.ReleaseDevicesList == NULL) + goto error_unload; + + usbdk_helper.StartRedirect = (USBDK_START_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StartRedirect"); + if (usbdk_helper.StartRedirect == NULL) + goto error_unload; + + usbdk_helper.StopRedirect = (USBDK_STOP_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StopRedirect"); + if (usbdk_helper.StopRedirect == NULL) + goto error_unload; + + usbdk_helper.GetConfigurationDescriptor = (USBDK_GET_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_GetConfigurationDescriptor"); + if (usbdk_helper.GetConfigurationDescriptor == NULL) + goto error_unload; + + usbdk_helper.ReleaseConfigurationDescriptor = (USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseConfigurationDescriptor"); + if (usbdk_helper.ReleaseConfigurationDescriptor == NULL) + goto error_unload; + + usbdk_helper.ReadPipe = (USBDK_READ_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ReadPipe"); + if (usbdk_helper.ReadPipe == NULL) + goto error_unload; + + usbdk_helper.WritePipe = (USBDK_WRITE_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_WritePipe"); + if (usbdk_helper.WritePipe == NULL) + goto error_unload; + + usbdk_helper.AbortPipe = (USBDK_ABORT_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_AbortPipe"); + if (usbdk_helper.AbortPipe == NULL) + goto error_unload; + + usbdk_helper.ResetPipe = (USBDK_RESET_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ResetPipe"); + if (usbdk_helper.ResetPipe == NULL) + goto error_unload; + + usbdk_helper.SetAltsetting = (USBDK_SET_ALTSETTING)get_usbdk_proc_addr(ctx, "UsbDk_SetAltsetting"); + if (usbdk_helper.SetAltsetting == NULL) + goto error_unload; + + usbdk_helper.ResetDevice = (USBDK_RESET_DEVICE)get_usbdk_proc_addr(ctx, "UsbDk_ResetDevice"); + if (usbdk_helper.ResetDevice == NULL) + goto error_unload; + + usbdk_helper.GetRedirectorSystemHandle = (USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)get_usbdk_proc_addr(ctx, "UsbDk_GetRedirectorSystemHandle"); + if (usbdk_helper.GetRedirectorSystemHandle == NULL) + goto error_unload; + + return LIBUSB_SUCCESS; + +error_unload: + FreeLibrary(usbdk_helper.module); + usbdk_helper.module = NULL; + return LIBUSB_ERROR_NOT_FOUND; +} + +static int usbdk_init(struct libusb_context *ctx) +{ + SC_HANDLE managerHandle; + SC_HANDLE serviceHandle; + + managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + if (managerHandle == NULL) { + usbi_warn(ctx, "failed to open service control manager: %s", windows_error_str(0)); + return LIBUSB_ERROR_OTHER; + } + + serviceHandle = OpenServiceA(managerHandle, "UsbDk", GENERIC_READ); + CloseServiceHandle(managerHandle); + + if (serviceHandle == NULL) { + if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) + usbi_warn(ctx, "failed to open UsbDk service: %s", windows_error_str(0)); + return LIBUSB_ERROR_NOT_FOUND; + } + + CloseServiceHandle(serviceHandle); + + return load_usbdk_helper_dll(ctx); +} + +static void usbdk_exit(struct libusb_context *ctx) +{ + UNUSED(ctx); + unload_usbdk_helper_dll(); +} + +static int usbdk_get_session_id_for_device(struct libusb_context *ctx, + PUSB_DK_DEVICE_ID id, unsigned long *session_id) +{ + char dev_identity[ARRAYSIZE(id->DeviceID) + ARRAYSIZE(id->InstanceID) + 1]; + + if (snprintf(dev_identity, sizeof(dev_identity), "%S%S", id->DeviceID, id->InstanceID) == -1) { + usbi_warn(ctx, "cannot form device identity", id->DeviceID); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + *session_id = htab_hash(dev_identity); + + return LIBUSB_SUCCESS; +} + +static void usbdk_release_config_descriptors(struct usbdk_device_priv *p, uint8_t count) +{ + uint8_t i; + + for (i = 0; i < count; i++) + usbdk_helper.ReleaseConfigurationDescriptor(p->config_descriptors[i]); + + free(p->config_descriptors); + p->config_descriptors = NULL; +} + +static int usbdk_cache_config_descriptors(struct libusb_context *ctx, + struct usbdk_device_priv *p, PUSB_DK_DEVICE_INFO info) +{ + uint8_t i; + USB_DK_CONFIG_DESCRIPTOR_REQUEST Request; + Request.ID = info->ID; + + p->config_descriptors = calloc(info->DeviceDescriptor.bNumConfigurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)); + if (p->config_descriptors == NULL) { + usbi_err(ctx, "failed to allocate configuration descriptors holder"); + return LIBUSB_ERROR_NO_MEM; + } + + for (i = 0; i < info->DeviceDescriptor.bNumConfigurations; i++) { + ULONG Length; + + Request.Index = i; + if (!usbdk_helper.GetConfigurationDescriptor(&Request, &p->config_descriptors[i], &Length)) { + usbi_err(ctx, "failed to retrieve configuration descriptors"); + usbdk_release_config_descriptors(p, i); + return LIBUSB_ERROR_OTHER; + } + } + + return LIBUSB_SUCCESS; +} + +static inline int usbdk_device_priv_init(struct libusb_context *ctx, struct libusb_device *dev, PUSB_DK_DEVICE_INFO info) +{ + struct usbdk_device_priv *p = _usbdk_device_priv(dev); + + p->info = *info; + p->active_configuration = 0; + + return usbdk_cache_config_descriptors(ctx, p, info); +} + +static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info) +{ + dev->bus_number = (uint8_t)info->FilterID; + dev->port_number = (uint8_t)info->Port; + dev->parent_dev = NULL; + + // Addresses in libusb are 1-based + dev->device_address = (uint8_t)(info->Port + 1); + + dev->num_configurations = info->DeviceDescriptor.bNumConfigurations; + memcpy(&dev->device_descriptor, &info->DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE); + + switch (info->Speed) { + case LowSpeed: + dev->speed = LIBUSB_SPEED_LOW; + break; + case FullSpeed: + dev->speed = LIBUSB_SPEED_FULL; + break; + case HighSpeed: + dev->speed = LIBUSB_SPEED_HIGH; + break; + case SuperSpeed: + dev->speed = LIBUSB_SPEED_SUPER; + break; + case NoSpeed: + default: + dev->speed = LIBUSB_SPEED_UNKNOWN; + break; + } +} + +static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) +{ + int r = LIBUSB_SUCCESS; + ULONG i; + struct discovered_devs *discdevs = NULL; + ULONG dev_number; + PUSB_DK_DEVICE_INFO devices; + + if (!usbdk_helper.GetDevicesList(&devices, &dev_number)) + return LIBUSB_ERROR_OTHER; + + for (i = 0; i < dev_number; i++) { + unsigned long session_id; + struct libusb_device *dev = NULL; + + if (usbdk_get_session_id_for_device(ctx, &devices[i].ID, &session_id)) + continue; + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev == NULL) { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) { + usbi_err(ctx, "failed to allocate a new device structure"); + continue; + } + + usbdk_device_init(dev, &devices[i]); + if (usbdk_device_priv_init(ctx, dev, &devices[i]) != LIBUSB_SUCCESS) { + libusb_unref_device(dev); + continue; + } + } + + discdevs = discovered_devs_append(*_discdevs, dev); + libusb_unref_device(dev); + if (!discdevs) { + usbi_err(ctx, "cannot append new device to list"); + r = LIBUSB_ERROR_NO_MEM; + goto func_exit; + } + + *_discdevs = discdevs; + } + +func_exit: + usbdk_helper.ReleaseDevicesList(devices); + return r; +} + +static int usbdk_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev); + + memcpy(buffer, &priv->info.DeviceDescriptor, DEVICE_DESC_LENGTH); + + return LIBUSB_SUCCESS; +} + +static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + size_t size; + + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_INVALID_PARAM; + + config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptors[config_index]; + + size = min(config_header->wTotalLength, len); + memcpy(buffer, config_header, size); + return (int)size; +} + +static int usbdk_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, + unsigned char **buffer) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + uint8_t index; + + for (index = 0; index < dev->num_configurations; index++) { + config_header = priv->config_descriptors[index]; + if (config_header->bConfigurationValue == bConfigurationValue) { + *buffer = (unsigned char *)priv->config_descriptors[index]; + return (int)config_header->wTotalLength; + } + } + + return LIBUSB_ERROR_NOT_FOUND; +} + +static int usbdk_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len) +{ + return usbdk_get_config_descriptor(dev, _usbdk_device_priv(dev)->active_configuration, + buffer, len); +} + +static int usbdk_open(struct libusb_device_handle *dev_handle) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + priv->redirector_handle = usbdk_helper.StartRedirect(&priv->info.ID); + if (priv->redirector_handle == INVALID_HANDLE_VALUE) { + usbi_err(DEVICE_CTX(dev_handle->dev), "Redirector startup failed"); + return LIBUSB_ERROR_OTHER; + } + + priv->system_handle = usbdk_helper.GetRedirectorSystemHandle(priv->redirector_handle); + + return LIBUSB_SUCCESS; +} + +static void usbdk_close(struct libusb_device_handle *dev_handle) +{ + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.StopRedirect(priv->redirector_handle)) + usbi_err(HANDLE_CTX(dev_handle), "Redirector shutdown failed"); +} + +static int usbdk_get_configuration(struct libusb_device_handle *dev_handle, int *config) +{ + *config = _usbdk_device_priv(dev_handle->dev)->active_configuration; + + return LIBUSB_SUCCESS; +} + +static int usbdk_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + UNUSED(dev_handle); + UNUSED(config); + return LIBUSB_SUCCESS; +} + +static int usbdk_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_SUCCESS; +} + +static int usbdk_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct libusb_context *ctx = HANDLE_CTX(dev_handle); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.SetAltsetting(priv->redirector_handle, iface, altsetting)) { + usbi_err(ctx, "SetAltsetting failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + UNUSED(dev_handle); + UNUSED(iface); + return LIBUSB_SUCCESS; +} + +static int usbdk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = HANDLE_CTX(dev_handle); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.ResetPipe(priv->redirector_handle, endpoint)) { + usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_reset_device(struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = HANDLE_CTX(dev_handle); + struct usbdk_device_priv *priv = _usbdk_device_priv(dev_handle->dev); + + if (!usbdk_helper.ResetDevice(priv->redirector_handle)) { + usbi_err(ctx, "ResetDevice failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +static void usbdk_destroy_device(struct libusb_device *dev) +{ + struct usbdk_device_priv* p = _usbdk_device_priv(dev); + + if (p->config_descriptors != NULL) + usbdk_release_config_descriptors(p, p->info.DeviceDescriptor.bNumConfigurations); +} + +static void usbdk_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + usbi_close(transfer_priv->pollable_fd.fd); + transfer_priv->pollable_fd = INVALID_WINFD; + transfer_priv->system_handle = NULL; + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + safe_free(transfer_priv->IsochronousPacketsArray); + safe_free(transfer_priv->IsochronousResultsArray); + } +} + +static int usbdk_do_control_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + OVERLAPPED *overlapped = transfer_priv->pollable_fd.overlapped; + TransferResult transResult; + + transfer_priv->request.Buffer = (PVOID64)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.TransferType = ControlTransferType; + + if (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) + transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped); + else + transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped); + + switch (transResult) { + case TransferSuccess: + windows_force_sync_completion(overlapped, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred); + break; + case TransferSuccessAsync: + break; + case TransferFailure: + usbi_err(ctx, "ControlTransfer failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + OVERLAPPED *overlapped = transfer_priv->pollable_fd.overlapped; + TransferResult transferRes; + + transfer_priv->request.Buffer = (PVOID64)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.EndpointAddress = transfer->endpoint; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + transfer_priv->request.TransferType = BulkTransferType; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + transfer_priv->request.TransferType = InterruptTransferType; + break; + default: + usbi_err(ctx, "Wrong transfer type (%d) in usbdk_do_bulk_transfer", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } + + if (IS_XFERIN(transfer)) + transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped); + else + transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped); + + switch (transferRes) { + case TransferSuccess: + windows_force_sync_completion(overlapped, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred); + break; + case TransferSuccessAsync: + break; + case TransferFailure: + usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + OVERLAPPED *overlapped = transfer_priv->pollable_fd.overlapped; + TransferResult transferRes; + int i; + + transfer_priv->request.Buffer = (PVOID64)transfer->buffer; + transfer_priv->request.BufferLength = transfer->length; + transfer_priv->request.EndpointAddress = transfer->endpoint; + transfer_priv->request.TransferType = IsochronousTransferType; + transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets; + transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64)); + transfer_priv->request.IsochronousPacketsArray = (PVOID64)transfer_priv->IsochronousPacketsArray; + if (!transfer_priv->IsochronousPacketsArray) { + usbi_err(ctx, "Allocation of IsochronousPacketsArray failed"); + return LIBUSB_ERROR_NO_MEM; + } + + transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT)); + transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)transfer_priv->IsochronousResultsArray; + if (!transfer_priv->IsochronousResultsArray) { + usbi_err(ctx, "Allocation of isochronousResultsArray failed"); + return LIBUSB_ERROR_NO_MEM; + } + + for (i = 0; i < transfer->num_iso_packets; i++) + transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length; + + if (IS_XFERIN(transfer)) + transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped); + else + transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped); + + switch (transferRes) { + case TransferSuccess: + windows_force_sync_completion(overlapped, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred); + break; + case TransferSuccessAsync: + break; + case TransferFailure: + return LIBUSB_ERROR_IO; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_do_submit_transfer(struct usbi_transfer *itransfer, + short events, int (*transfer_fn)(struct usbi_transfer *)) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct winfd wfd; + int r; + + wfd = usbi_create_fd(); + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_add_pollfd(ctx, wfd.fd, events); + if (r) { + usbi_close(wfd.fd); + return r; + } + + // Use transfer_priv to store data needed for async polling + transfer_priv->pollable_fd = wfd; + transfer_priv->system_handle = priv->system_handle; + + r = transfer_fn(itransfer); + if (r != LIBUSB_SUCCESS) { + usbi_remove_pollfd(ctx, wfd.fd); + usbdk_clear_transfer_priv(itransfer); + return r; + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int (*transfer_fn)(struct usbi_transfer *); + short events; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + events = (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) ? POLLIN : POLLOUT; + transfer_fn = usbdk_do_control_transfer; + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; //TODO: Check whether we can support this in UsbDk + events = IS_XFERIN(transfer) ? POLLIN : POLLOUT; + transfer_fn = usbdk_do_bulk_transfer; + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + events = IS_XFERIN(transfer) ? POLLIN : POLLOUT; + transfer_fn = usbdk_do_iso_transfer; + break; + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } + + return usbdk_do_submit_transfer(itransfer, events, transfer_fn); +} + +static int usbdk_abort_transfers(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = TRANSFER_CTX(transfer); + struct usbdk_device_priv *priv = _usbdk_device_priv(transfer->dev_handle->dev); + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct winfd *pollable_fd = &transfer_priv->pollable_fd; + + if (pCancelIoEx != NULL) { + // Use CancelIoEx if available to cancel just a single transfer + if (!pCancelIoEx(priv->system_handle, pollable_fd->overlapped)) { + usbi_err(ctx, "CancelIoEx failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + } else { + if (!usbdk_helper.AbortPipe(priv->redirector_handle, transfer->endpoint)) { + usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + } + + return LIBUSB_SUCCESS; +} + +static int usbdk_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + // Control transfers cancelled by IoCancelXXX() API + // No special treatment needed + return LIBUSB_SUCCESS; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return usbdk_abort_transfers(itransfer); + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int usbdk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +{ + itransfer->transferred += io_size; + return LIBUSB_TRANSFER_COMPLETED; +} + +static int usbdk_get_transfer_fd(struct usbi_transfer *itransfer) +{ + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + return transfer_priv->pollable_fd.fd; +} + +static DWORD usbdk_translate_usbd_status(USBD_STATUS UsbdStatus) +{ + if (USBD_SUCCESS(UsbdStatus)) + return NO_ERROR; + + switch (UsbdStatus) { + case USBD_STATUS_TIMEOUT: + return ERROR_SEM_TIMEOUT; + case USBD_STATUS_CANCELED: + return ERROR_OPERATION_ABORTED; + default: + return ERROR_GEN_FAILURE; + } +} + +static void usbdk_get_overlapped_result(struct usbi_transfer *itransfer, DWORD *io_result, DWORD *io_size) +{ + struct usbdk_transfer_priv *transfer_priv = _usbdk_transfer_priv(itransfer); + struct winfd *pollable_fd = &transfer_priv->pollable_fd; + + if (HasOverlappedIoCompletedSync(pollable_fd->overlapped) // Handle async requests that completed synchronously first + || GetOverlappedResult(transfer_priv->system_handle, pollable_fd->overlapped, io_size, FALSE)) { // Regular async overlapped + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + ULONG64 i; + for (i = 0; i < transfer_priv->request.IsochronousPacketsArraySize; i++) { + struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i]; + + switch (transfer_priv->IsochronousResultsArray[i].TransferResult) { + case STATUS_SUCCESS: + case STATUS_CANCELLED: + case STATUS_REQUEST_CANCELED: + lib_desc->status = LIBUSB_TRANSFER_COMPLETED; // == ERROR_SUCCESS + break; + default: + lib_desc->status = LIBUSB_TRANSFER_ERROR; // ERROR_UNKNOWN_EXCEPTION; + break; + } + + lib_desc->actual_length = (unsigned int)transfer_priv->IsochronousResultsArray[i].ActualLength; + } + } + + *io_size = (DWORD)transfer_priv->request.Result.GenResult.BytesTransferred; + *io_result = usbdk_translate_usbd_status((USBD_STATUS)transfer_priv->request.Result.GenResult.UsbdStatus); + } else { + *io_result = GetLastError(); + } +} + +const struct windows_backend usbdk_backend = { + usbdk_init, + usbdk_exit, + usbdk_get_device_list, + usbdk_open, + usbdk_close, + usbdk_get_device_descriptor, + usbdk_get_active_config_descriptor, + usbdk_get_config_descriptor, + usbdk_get_config_descriptor_by_value, + usbdk_get_configuration, + usbdk_set_configuration, + usbdk_claim_interface, + usbdk_release_interface, + usbdk_set_interface_altsetting, + usbdk_clear_halt, + usbdk_reset_device, + usbdk_destroy_device, + usbdk_submit_transfer, + usbdk_cancel_transfer, + usbdk_clear_transfer_priv, + usbdk_copy_transfer_data, + usbdk_get_transfer_fd, + usbdk_get_overlapped_result, +}; diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.h new file mode 100644 index 00000000..77660ae9 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_usbdk.h @@ -0,0 +1,103 @@ +/* +* windows UsbDk backend for libusb 1.0 +* Copyright © 2014 Red Hat, Inc. + +* Authors: +* Dmitry Fleytman +* Pavel Gurvich +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include "windows_nt_common.h" + +typedef struct USB_DK_CONFIG_DESCRIPTOR_REQUEST { + USB_DK_DEVICE_ID ID; + ULONG64 Index; +} USB_DK_CONFIG_DESCRIPTOR_REQUEST, *PUSB_DK_CONFIG_DESCRIPTOR_REQUEST; + +typedef enum { + TransferFailure = 0, + TransferSuccess, + TransferSuccessAsync +} TransferResult; + +typedef enum { + NoSpeed = 0, + LowSpeed, + FullSpeed, + HighSpeed, + SuperSpeed +} USB_DK_DEVICE_SPEED; + +typedef enum { + ControlTransferType, + BulkTransferType, + InterruptTransferType, + IsochronousTransferType +} USB_DK_TRANSFER_TYPE; + +typedef BOOL (__cdecl *USBDK_GET_DEVICES_LIST)( + PUSB_DK_DEVICE_INFO *DeviceInfo, + PULONG DeviceNumber +); +typedef void (__cdecl *USBDK_RELEASE_DEVICES_LIST)( + PUSB_DK_DEVICE_INFO DeviceInfo +); +typedef HANDLE (__cdecl *USBDK_START_REDIRECT)( + PUSB_DK_DEVICE_ID DeviceId +); +typedef BOOL (__cdecl *USBDK_STOP_REDIRECT)( + HANDLE DeviceHandle +); +typedef BOOL (__cdecl *USBDK_GET_CONFIGURATION_DESCRIPTOR)( + PUSB_DK_CONFIG_DESCRIPTOR_REQUEST Request, + PUSB_CONFIGURATION_DESCRIPTOR *Descriptor, + PULONG Length +); +typedef void (__cdecl *USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)( + PUSB_CONFIGURATION_DESCRIPTOR Descriptor +); +typedef TransferResult (__cdecl *USBDK_WRITE_PIPE)( + HANDLE DeviceHandle, + PUSB_DK_TRANSFER_REQUEST Request, + LPOVERLAPPED lpOverlapped +); +typedef TransferResult (__cdecl *USBDK_READ_PIPE)( + HANDLE DeviceHandle, + PUSB_DK_TRANSFER_REQUEST Request, + LPOVERLAPPED lpOverlapped +); +typedef BOOL (__cdecl *USBDK_ABORT_PIPE)( + HANDLE DeviceHandle, + ULONG64 PipeAddress +); +typedef BOOL (__cdecl *USBDK_RESET_PIPE)( + HANDLE DeviceHandle, + ULONG64 PipeAddress +); +typedef BOOL (__cdecl *USBDK_SET_ALTSETTING)( + HANDLE DeviceHandle, + ULONG64 InterfaceIdx, + ULONG64 AltSettingIdx +); +typedef BOOL (__cdecl *USBDK_RESET_DEVICE)( + HANDLE DeviceHandle +); +typedef HANDLE (__cdecl *USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)( + HANDLE DeviceHandle +); diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.c b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.c new file mode 100644 index 00000000..ce1b55cd --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.c @@ -0,0 +1,3009 @@ +/* + * windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * Copyright © 2016-2018 Chris Dickens + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software + * Hash table functions adapted from glibc, by Ulrich Drepper et al. + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "windows_common.h" +#include "windows_nt_common.h" +#include "windows_winusb.h" + +// Unfuckup the 'inferface' keyword +#undef interface + +#define HANDLE_VALID(h) (((h) != NULL) && ((h) != INVALID_HANDLE_VALUE)) + +// The 2 macros below are used in conjunction with safe loops. +#define LOOP_CHECK(fcall) \ + { \ + r = fcall; \ + if (r != LIBUSB_SUCCESS) \ + continue; \ + } +#define LOOP_BREAK(err) \ + { \ + r = err; \ + continue; \ + } + +// WinUSB-like API prototypes +static int winusbx_init(struct libusb_context *ctx); +static void winusbx_exit(void); +static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle); +static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle); +static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); +static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); +static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer); +static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle); +static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); +// Composite API prototypes +static int composite_open(int sub_api, struct libusb_device_handle *dev_handle); +static void composite_close(int sub_api, struct libusb_device_handle *dev_handle); +static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); +static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); +static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer); +static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); +static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer); +static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer); +static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle); +static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); + +static usbi_mutex_t autoclaim_lock; + +// API globals +static HMODULE WinUSBX_handle = NULL; +static struct winusb_interface WinUSBX[SUB_API_MAX]; +#define CHECK_WINUSBX_AVAILABLE(sub_api) \ + do { \ + if (sub_api == SUB_API_NOTSET) \ + sub_api = priv->sub_api; \ + if (!WinUSBX[sub_api].initialized) \ + return LIBUSB_ERROR_ACCESS; \ + } while (0) + +static bool api_hid_available = false; +#define CHECK_HID_AVAILABLE \ + do { \ + if (!api_hid_available) \ + return LIBUSB_ERROR_ACCESS; \ + } while (0) + +#if defined(ENABLE_LOGGING) +static const char *guid_to_string(const GUID *guid) +{ + static char guid_string[MAX_GUID_STRING_LENGTH]; + + if (guid == NULL) + return ""; + + sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + (unsigned int)guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); + + return guid_string; +} +#endif + +/* + * Sanitize Microsoft's paths: convert to uppercase, add prefix and fix backslashes. + * Return an allocated sanitized string or NULL on error. + */ +static char *sanitize_path(const char *path) +{ + const char root_prefix[] = {'\\', '\\', '.', '\\'}; + size_t j, size; + char *ret_path; + size_t add_root = 0; + + if (path == NULL) + return NULL; + + size = strlen(path) + 1; + + // Microsoft indiscriminately uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes. + if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) + || ((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) { + add_root = sizeof(root_prefix); + size += add_root; + } + + ret_path = malloc(size); + if (ret_path == NULL) + return NULL; + + strcpy(&ret_path[add_root], path); + + // Ensure consistency with root prefix + memcpy(ret_path, root_prefix, sizeof(root_prefix)); + + // Same goes for '\' and '#' after the root prefix. Ensure '#' is used + for (j = sizeof(root_prefix); j < size; j++) { + ret_path[j] = (char)toupper((int)ret_path[j]); // Fix case too + if (ret_path[j] == '\\') + ret_path[j] = '#'; + } + + return ret_path; +} + +/* + * Cfgmgr32, AdvAPI32, OLE32 and SetupAPI DLL functions + */ +static BOOL init_dlls(void) +{ + DLL_GET_HANDLE(Cfgmgr32); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Parent, TRUE); + DLL_LOAD_FUNC(Cfgmgr32, CM_Get_Child, TRUE); + + // Prefixed to avoid conflict with header files + DLL_GET_HANDLE(AdvAPI32); + DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExW, TRUE); + DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, TRUE); + + DLL_GET_HANDLE(OLE32); + DLL_LOAD_FUNC_PREFIXED(OLE32, p, IIDFromString, TRUE); + + DLL_GET_HANDLE(SetupAPI); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInstanceIdA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, TRUE); + DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, TRUE); + + return TRUE; +} + +static void exit_dlls(void) +{ + DLL_FREE_HANDLE(Cfgmgr32); + DLL_FREE_HANDLE(AdvAPI32); + DLL_FREE_HANDLE(OLE32); + DLL_FREE_HANDLE(SetupAPI); +} + +/* + * enumerate interfaces for the whole USB class + * + * Parameters: + * dev_info: a pointer to a dev_info list + * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed) + * enumerator: the generic USB class for which to retrieve interface details + * index: zero based index of the interface in the device info list + * + * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA + * structure returned and call this function repeatedly using the same guid (with an + * incremented index starting at zero) until all interfaces have been returned. + */ +static bool get_devinfo_data(struct libusb_context *ctx, + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char *enumerator, unsigned _index) +{ + if (_index == 0) { + *dev_info = pSetupDiGetClassDevsA(NULL, enumerator, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); + if (*dev_info == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "could not obtain device info set for PnP enumerator '%s': %s", + enumerator, windows_error_str(0)); + return false; + } + } + + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "could not obtain device info data for PnP enumerator '%s' index %u: %s", + enumerator, _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return false; + } + return true; +} + +/* + * enumerate interfaces for a specific GUID + * + * Parameters: + * dev_info: a pointer to a dev_info list + * dev_info_data: a pointer to an SP_DEVINFO_DATA to be filled (or NULL if not needed) + * guid: the GUID for which to retrieve interface details + * index: zero based index of the interface in the device info list + * + * Note: it is the responsibility of the caller to free the DEVICE_INTERFACE_DETAIL_DATA + * structure returned and call this function repeatedly using the same guid (with an + * incremented index starting at zero) until all interfaces have been returned. + */ +static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info, + PSP_DEVINFO_DATA dev_info_data, LPCGUID guid, DWORD *_index, char **dev_interface_path) +{ + SP_DEVICE_INTERFACE_DATA dev_interface_data; + PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details; + DWORD size; + + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + for (;;) { + if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) { + usbi_err(ctx, "Could not obtain device info data for %s index %u: %s", + guid_to_string(guid), *_index, windows_error_str(0)); + return LIBUSB_ERROR_OTHER; + } + + // No more devices + return LIBUSB_SUCCESS; + } + + // Always advance the index for the next iteration + (*_index)++; + + if (pSetupDiEnumDeviceInterfaces(dev_info, dev_info_data, guid, 0, &dev_interface_data)) + break; + + if (GetLastError() != ERROR_NO_MORE_ITEMS) { + usbi_err(ctx, "Could not obtain interface data for %s devInst %X: %s", + guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0)); + return LIBUSB_ERROR_OTHER; + } + + // Device does not have an interface matching this GUID, skip + } + + // Read interface data (dummy + actual) to access the device path + if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + usbi_err(ctx, "could not access interface data (dummy) for %s devInst %X: %s", + guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0)); + return LIBUSB_ERROR_OTHER; + } + } else { + usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong"); + return LIBUSB_ERROR_OTHER; + } + + dev_interface_details = malloc(size); + if (dev_interface_details == NULL) { + usbi_err(ctx, "could not allocate interface data for %s devInst %X", + guid_to_string(guid), dev_info_data->DevInst); + return LIBUSB_ERROR_NO_MEM; + } + + dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data, + dev_interface_details, size, NULL, NULL)) { + usbi_err(ctx, "could not access interface data (actual) for %s devInst %X: %s", + guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0)); + free(dev_interface_details); + return LIBUSB_ERROR_OTHER; + } + + *dev_interface_path = sanitize_path(dev_interface_details->DevicePath); + free(dev_interface_details); + + if (*dev_interface_path == NULL) { + usbi_err(ctx, "could not allocate interface path for %s devInst %X", + guid_to_string(guid), dev_info_data->DevInst); + return LIBUSB_ERROR_NO_MEM; + } + + return LIBUSB_SUCCESS; +} + +/* For libusb0 filter */ +static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx, + HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID *guid, unsigned _index, char *filter_path) +{ + SP_DEVICE_INTERFACE_DATA dev_interface_data; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details; + DWORD size; + + if (_index == 0) + *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); + + if (dev_info_data != NULL) { + dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain device info data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + } + + dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { + if (GetLastError() != ERROR_NO_MORE_ITEMS) + usbi_err(ctx, "Could not obtain interface data for index %u: %s", + _index, windows_error_str(0)); + + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; + } + + // Read interface data (dummy + actual) to access the device path + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + usbi_err(ctx, "could not access interface data (dummy) for index %u: %s", + _index, windows_error_str(0)); + goto err_exit; + } + } else { + usbi_err(ctx, "program assertion failed - http://msdn.microsoft.com/en-us/library/ms792901.aspx is wrong."); + goto err_exit; + } + + dev_interface_details = calloc(1, size); + if (dev_interface_details == NULL) { + usbi_err(ctx, "could not allocate interface data for index %u.", _index); + goto err_exit; + } + + dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, &size, NULL)) + usbi_err(ctx, "could not access interface data (actual) for index %u: %s", + _index, windows_error_str(0)); + + // [trobinso] lookup the libusb0 symbolic index. + if (dev_interface_details) { + HKEY hkey_device_interface = pSetupDiOpenDeviceInterfaceRegKey(*dev_info, &dev_interface_data, 0, KEY_READ); + if (hkey_device_interface != INVALID_HANDLE_VALUE) { + DWORD libusb0_symboliclink_index = 0; + DWORD value_length = sizeof(DWORD); + DWORD value_type = 0; + LONG status; + + status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type, + (LPBYTE)&libusb0_symboliclink_index, &value_length); + if (status == ERROR_SUCCESS) { + if (libusb0_symboliclink_index < 256) { + // libusb0.sys is connected to this device instance. + // If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter. + sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index); + usbi_dbg("assigned libusb0 symbolic link %s", filter_path); + } else { + // libusb0.sys was connected to this device instance at one time; but not anymore. + } + } + pRegCloseKey(hkey_device_interface); + } + } + + return dev_interface_details; + +err_exit: + pSetupDiDestroyDeviceInfoList(*dev_info); + *dev_info = INVALID_HANDLE_VALUE; + return NULL; +} + +/* + * Returns the first known ancestor of a device + */ +static struct libusb_device *get_ancestor(struct libusb_context *ctx, + DEVINST devinst, PDEVINST _parent_devinst) +{ + struct libusb_device *dev = NULL; + DEVINST parent_devinst; + + while (dev == NULL) { + if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) + break; + devinst = parent_devinst; + dev = usbi_get_device_by_session_id(ctx, (unsigned long)devinst); + } + + if ((dev != NULL) && (_parent_devinst != NULL)) + *_parent_devinst = devinst; + + return dev; +} + +/* + * Determine which interface the given endpoint address belongs to + */ +static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep) +{ + const struct libusb_interface *intf; + const struct libusb_interface_descriptor *intf_desc; + int i, j, k; + + for (i = 0; i < conf_desc->bNumInterfaces; i++) { + intf = &conf_desc->interface[i]; + for (j = 0; j < intf->num_altsetting; j++) { + intf_desc = &intf->altsetting[j]; + for (k = 0; k < intf_desc->bNumEndpoints; k++) { + if (intf_desc->endpoint[k].bEndpointAddress == ep) { + usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i); + return intf_desc->bInterfaceNumber; + } + } + } + } + + usbi_dbg("endpoint %02X not found on any interface", ep); + return LIBUSB_ERROR_NOT_FOUND; +} + +/* + * Populate the endpoints addresses of the device_priv interface helper structs + */ +static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + int i, r; + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + struct libusb_config_descriptor *conf_desc; + const struct libusb_interface_descriptor *if_desc; + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + + r = libusb_get_active_config_descriptor(dev_handle->dev, &conf_desc); + if (r != LIBUSB_SUCCESS) { + usbi_warn(ctx, "could not read config descriptor: error %d", r); + return r; + } + + if_desc = &conf_desc->interface[iface].altsetting[altsetting]; + safe_free(priv->usb_interface[iface].endpoint); + + if (if_desc->bNumEndpoints == 0) { + usbi_dbg("no endpoints found for interface %d", iface); + libusb_free_config_descriptor(conf_desc); + return LIBUSB_SUCCESS; + } + + priv->usb_interface[iface].endpoint = malloc(if_desc->bNumEndpoints); + if (priv->usb_interface[iface].endpoint == NULL) { + libusb_free_config_descriptor(conf_desc); + return LIBUSB_ERROR_NO_MEM; + } + + priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints; + for (i = 0; i < if_desc->bNumEndpoints; i++) { + priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress; + usbi_dbg("(re)assigned endpoint %02X to interface %d", priv->usb_interface[iface].endpoint[i], iface); + } + libusb_free_config_descriptor(conf_desc); + + // Extra init may be required to configure endpoints + if (priv->apib->configure_endpoints) + r = priv->apib->configure_endpoints(SUB_API_NOTSET, dev_handle, iface); + + return r; +} + +// Lookup for a match in the list of API driver names +// return -1 if not found, driver match number otherwise +static int get_sub_api(char *driver, int api) +{ + int i; + const char sep_str[2] = {LIST_SEPARATOR, 0}; + char *tok, *tmp_str; + size_t len = strlen(driver); + + if (len == 0) + return SUB_API_NOTSET; + + tmp_str = _strdup(driver); + if (tmp_str == NULL) + return SUB_API_NOTSET; + + tok = strtok(tmp_str, sep_str); + while (tok != NULL) { + for (i = 0; i < usb_api_backend[api].nb_driver_names; i++) { + if (_stricmp(tok, usb_api_backend[api].driver_name_list[i]) == 0) { + free(tmp_str); + return i; + } + } + tok = strtok(NULL, sep_str); + } + + free(tmp_str); + return SUB_API_NOTSET; +} + +/* + * auto-claiming and auto-release helper functions + */ +static int auto_claim(struct libusb_transfer *transfer, int *interface_number, int api_type) +{ + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv( + transfer->dev_handle); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface = *interface_number; + int r = LIBUSB_SUCCESS; + + switch (api_type) { + case USB_API_WINUSBX: + case USB_API_HID: + break; + default: + return LIBUSB_ERROR_INVALID_PARAM; + } + + usbi_mutex_lock(&autoclaim_lock); + if (current_interface < 0) { // No serviceable interface was found + for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) { + // Must claim an interface of the same API type + if ((priv->usb_interface[current_interface].apib->id == api_type) + && (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) { + usbi_dbg("auto-claimed interface %d for control request", current_interface); + if (handle_priv->autoclaim_count[current_interface] != 0) + usbi_warn(ctx, "program assertion failed - autoclaim_count was nonzero"); + handle_priv->autoclaim_count[current_interface]++; + break; + } + } + if (current_interface == USB_MAXINTERFACES) { + usbi_err(ctx, "could not auto-claim any interface"); + r = LIBUSB_ERROR_NOT_FOUND; + } + } else { + // If we have a valid interface that was autoclaimed, we must increment + // its autoclaim count so that we can prevent an early release. + if (handle_priv->autoclaim_count[current_interface] != 0) + handle_priv->autoclaim_count[current_interface]++; + } + usbi_mutex_unlock(&autoclaim_lock); + + *interface_number = current_interface; + return r; +} + +static void auto_release(struct usbi_transfer *itransfer) +{ + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + libusb_device_handle *dev_handle = transfer->dev_handle; + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + int r; + + usbi_mutex_lock(&autoclaim_lock); + if (handle_priv->autoclaim_count[transfer_priv->interface_number] > 0) { + handle_priv->autoclaim_count[transfer_priv->interface_number]--; + if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) { + r = libusb_release_interface(dev_handle, transfer_priv->interface_number); + if (r == LIBUSB_SUCCESS) + usbi_dbg("auto-released interface %d", transfer_priv->interface_number); + else + usbi_dbg("failed to auto-release interface %d (%s)", + transfer_priv->interface_number, libusb_error_name((enum libusb_error)r)); + } + } + usbi_mutex_unlock(&autoclaim_lock); +} + +/* + * init: libusb backend init function + */ +static int winusb_init(struct libusb_context *ctx) +{ + int i; + + // We need a lock for proper auto-release + usbi_mutex_init(&autoclaim_lock); + + // Load DLL imports + if (!init_dlls()) { + usbi_err(ctx, "could not resolve DLL functions"); + return LIBUSB_ERROR_OTHER; + } + + // Initialize the low level APIs (we don't care about errors at this stage) + for (i = 0; i < USB_API_MAX; i++) { + if (usb_api_backend[i].init && usb_api_backend[i].init(ctx)) + usbi_warn(ctx, "error initializing %s backend", + usb_api_backend[i].designation); + } + + return LIBUSB_SUCCESS; +} + +/* +* exit: libusb backend deinitialization function +*/ +static void winusb_exit(struct libusb_context *ctx) +{ + int i; + + for (i = 0; i < USB_API_MAX; i++) { + if (usb_api_backend[i].exit) + usb_api_backend[i].exit(); + } + + exit_dlls(); + usbi_mutex_destroy(&autoclaim_lock); +} + +/* + * fetch and cache all the config descriptors through I/O + */ +static void cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct winusb_device_priv *priv = _device_priv(dev); + DWORD size, ret_size; + uint8_t i; + + USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request + PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request + PUSB_CONFIGURATION_DESCRIPTOR cd_data; + + if (dev->num_configurations == 0) + return; + + priv->config_descriptor = calloc(dev->num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)); + if (priv->config_descriptor == NULL) { + usbi_err(ctx, "could not allocate configuration descriptor array for '%s'", priv->dev_id); + return; + } + + for (i = 0; i <= dev->num_configurations; i++) { + safe_free(cd_buf_actual); + + if (i == dev->num_configurations) + break; + + size = sizeof(cd_buf_short); + memset(&cd_buf_short, 0, size); + + cd_buf_short.req.ConnectionIndex = (ULONG)dev->port_number; + cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN; + cd_buf_short.req.SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR; + cd_buf_short.req.SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i; + cd_buf_short.req.SetupPacket.wIndex = 0; + cd_buf_short.req.SetupPacket.wLength = (USHORT)sizeof(USB_CONFIGURATION_DESCRIPTOR); + + // Dummy call to get the required data size. Initial failures are reported as info rather + // than error as they can occur for non-penalizing situations, such as with some hubs. + // coverity[tainted_data_argument] + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size, + &cd_buf_short, size, &ret_size, NULL)) { + usbi_info(ctx, "could not access configuration descriptor %u (dummy) for '%s': %s", i, priv->dev_id, windows_error_str(0)); + continue; + } + + if ((ret_size != size) || (cd_buf_short.desc.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))) { + usbi_info(ctx, "unexpected configuration descriptor %u size (dummy) for '%s'", i, priv->dev_id); + continue; + } + + size = sizeof(USB_DESCRIPTOR_REQUEST) + cd_buf_short.desc.wTotalLength; + cd_buf_actual = malloc(size); + if (cd_buf_actual == NULL) { + usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id); + continue; + } + + // Actual call + cd_buf_actual->ConnectionIndex = (ULONG)dev->port_number; + cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN; + cd_buf_actual->SetupPacket.bRequest = LIBUSB_REQUEST_GET_DESCRIPTOR; + cd_buf_actual->SetupPacket.wValue = (LIBUSB_DT_CONFIG << 8) | i; + cd_buf_actual->SetupPacket.wIndex = 0; + cd_buf_actual->SetupPacket.wLength = cd_buf_short.desc.wTotalLength; + + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size, + cd_buf_actual, size, &ret_size, NULL)) { + usbi_err(ctx, "could not access configuration descriptor %u (actual) for '%s': %s", i, priv->dev_id, windows_error_str(0)); + continue; + } + + cd_data = (PUSB_CONFIGURATION_DESCRIPTOR)((UCHAR *)cd_buf_actual + sizeof(USB_DESCRIPTOR_REQUEST)); + + if ((size != ret_size) || (cd_data->wTotalLength != cd_buf_short.desc.wTotalLength)) { + usbi_err(ctx, "unexpected configuration descriptor %u size (actual) for '%s'", i, priv->dev_id); + continue; + } + + if (cd_data->bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "descriptor %u not a configuration descriptor for '%s'", i, priv->dev_id); + continue; + } + + usbi_dbg("cached config descriptor %u (bConfigurationValue=%u, %u bytes)", + i, cd_data->bConfigurationValue, cd_data->wTotalLength); + + // Cache the descriptor + priv->config_descriptor[i] = malloc(cd_data->wTotalLength); + if (priv->config_descriptor[i] != NULL) { + memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength); + } else { + usbi_err(ctx, "could not allocate configuration descriptor %u buffer for '%s'", i, priv->dev_id); + } + } +} + +/* + * Populate a libusb device structure + */ +static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev, + uint8_t port_number, DEVINST devinst) +{ + struct libusb_context *ctx; + struct libusb_device *tmp_dev; + struct winusb_device_priv *priv, *parent_priv; + USB_NODE_CONNECTION_INFORMATION_EX conn_info; + USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2; + HANDLE hub_handle; + DWORD size; + uint8_t bus_number, depth; + int r; + + priv = _device_priv(dev); + + // If the device is already initialized, we can stop here + if (priv->initialized) + return LIBUSB_SUCCESS; + + if (parent_dev != NULL) { // Not a HCD root hub + ctx = DEVICE_CTX(dev); + parent_priv = _device_priv(parent_dev); + if (parent_priv->apib->id != USB_API_HUB) { + usbi_warn(ctx, "parent for device '%s' is not a hub", priv->dev_id); + return LIBUSB_ERROR_NOT_FOUND; + } + + // Calculate depth and fetch bus number + bus_number = parent_dev->bus_number; + if (bus_number == 0) { + tmp_dev = get_ancestor(ctx, devinst, &devinst); + if (tmp_dev != parent_dev) { + usbi_err(ctx, "program assertion failed - first ancestor is not parent"); + return LIBUSB_ERROR_NOT_FOUND; + } + libusb_unref_device(tmp_dev); + + for (depth = 1; bus_number == 0; depth++) { + tmp_dev = get_ancestor(ctx, devinst, &devinst); + if (tmp_dev->bus_number != 0) { + bus_number = tmp_dev->bus_number; + depth += _device_priv(tmp_dev)->depth; + } + libusb_unref_device(tmp_dev); + } + } else { + depth = parent_priv->depth + 1; + } + + if (bus_number == 0) { + usbi_err(ctx, "program assertion failed - bus number not found for '%s'", priv->dev_id); + return LIBUSB_ERROR_NOT_FOUND; + } + + dev->bus_number = bus_number; + dev->port_number = port_number; + dev->parent_dev = parent_dev; + priv->depth = depth; + + hub_handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + 0, NULL); + if (hub_handle == INVALID_HANDLE_VALUE) { + usbi_warn(ctx, "could not open hub %s: %s", parent_priv->path, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + + memset(&conn_info, 0, sizeof(conn_info)); + conn_info.ConnectionIndex = (ULONG)port_number; + // coverity[tainted_data_argument] + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, sizeof(conn_info), + &conn_info, sizeof(conn_info), &size, NULL)) { + usbi_warn(ctx, "could not get node connection information for device '%s': %s", + priv->dev_id, windows_error_str(0)); + CloseHandle(hub_handle); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (conn_info.ConnectionStatus == NoDeviceConnected) { + usbi_err(ctx, "device '%s' is no longer connected!", priv->dev_id); + CloseHandle(hub_handle); + return LIBUSB_ERROR_NO_DEVICE; + } + + memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR)); + dev->num_configurations = priv->dev_descriptor.bNumConfigurations; + priv->active_config = conn_info.CurrentConfigurationValue; + usbi_dbg("found %u configurations (active conf: %u)", dev->num_configurations, priv->active_config); + + // Cache as many config descriptors as we can + cache_config_descriptors(dev, hub_handle); + + // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8 + if (windows_version >= WINDOWS_8) { + conn_info_v2.ConnectionIndex = (ULONG)port_number; + conn_info_v2.Length = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2); + conn_info_v2.SupportedUsbProtocols.Usb300 = 1; + if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, + &conn_info_v2, sizeof(conn_info_v2), &conn_info_v2, sizeof(conn_info_v2), &size, NULL)) { + usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s", + priv->dev_id, windows_error_str(0)); + } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) { + conn_info.Speed = 3; + } + } + + CloseHandle(hub_handle); + + if (conn_info.DeviceAddress > UINT8_MAX) + usbi_err(ctx, "program assertion failed - device address overflow"); + + dev->device_address = (uint8_t)conn_info.DeviceAddress; + + switch (conn_info.Speed) { + case 0: dev->speed = LIBUSB_SPEED_LOW; break; + case 1: dev->speed = LIBUSB_SPEED_FULL; break; + case 2: dev->speed = LIBUSB_SPEED_HIGH; break; + case 3: dev->speed = LIBUSB_SPEED_SUPER; break; + default: + usbi_warn(ctx, "unknown device speed %u", conn_info.Speed); + break; + } + } + + r = usbi_sanitize_device(dev); + if (r) + return r; + + priv->initialized = true; + + usbi_dbg("(bus: %u, addr: %u, depth: %u, port: %u): '%s'", + dev->bus_number, dev->device_address, priv->depth, dev->port_number, priv->dev_id); + + return LIBUSB_SUCCESS; +} + +static int enumerate_hcd_root_hub(struct libusb_context *ctx, const char *dev_id, + uint8_t bus_number, DEVINST devinst) +{ + struct libusb_device *dev; + struct winusb_device_priv *priv; + unsigned long session_id; + DEVINST child_devinst; + + if (CM_Get_Child(&child_devinst, devinst, 0) != CR_SUCCESS) { + usbi_err(ctx, "could not get child devinst for '%s'", dev_id); + return LIBUSB_ERROR_OTHER; + } + + session_id = (unsigned long)child_devinst; + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev == NULL) { + usbi_err(ctx, "program assertion failed - HCD '%s' child not found", dev_id); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (dev->bus_number == 0) { + // Only do this once + usbi_dbg("assigning HCD '%s' bus number %u", dev_id, bus_number); + priv = _device_priv(dev); + dev->bus_number = bus_number; + dev->num_configurations = 1; + priv->dev_descriptor.bLength = LIBUSB_DT_DEVICE_SIZE; + priv->dev_descriptor.bDescriptorType = LIBUSB_DT_DEVICE; + priv->dev_descriptor.bDeviceClass = LIBUSB_CLASS_HUB; + priv->dev_descriptor.bNumConfigurations = 1; + priv->active_config = 1; + priv->root_hub = true; + if (sscanf(dev_id, "PCI\\VEN_%04hx&DEV_%04hx%*s", &priv->dev_descriptor.idVendor, &priv->dev_descriptor.idProduct) != 2) { + usbi_warn(ctx, "could not infer VID/PID of HCD root hub from '%s'", dev_id); + priv->dev_descriptor.idVendor = 0x1d6b; // Linux Foundation root hub + priv->dev_descriptor.idProduct = 1; + } + } + + libusb_unref_device(dev); + return LIBUSB_SUCCESS; +} + +// Returns the api type, or 0 if not found/unsupported +static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info, + SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api) +{ + // Precedence for filter drivers vs driver is in the order of this array + struct driver_lookup lookup[3] = { + {"\0\0", SPDRP_SERVICE, "driver"}, + {"\0\0", SPDRP_UPPERFILTERS, "upper filter driver"}, + {"\0\0", SPDRP_LOWERFILTERS, "lower filter driver"} + }; + DWORD size, reg_type; + unsigned k, l; + int i, j; + + // Check the service & filter names to know the API we should use + for (k = 0; k < 3; k++) { + if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop, + ®_type, (PBYTE)lookup[k].list, MAX_KEY_LENGTH, &size)) { + // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ + if (lookup[k].reg_prop == SPDRP_SERVICE) + // our buffers are MAX_KEY_LENGTH + 1 so we can overflow if needed + lookup[k].list[strlen(lookup[k].list) + 1] = 0; + + // MULTI_SZ is a pain to work with. Turn it into something much more manageable + // NB: none of the driver names we check against contain LIST_SEPARATOR, + // (currently ';'), so even if an unsuported one does, it's not an issue + for (l = 0; (lookup[k].list[l] != 0) || (lookup[k].list[l + 1] != 0); l++) { + if (lookup[k].list[l] == 0) + lookup[k].list[l] = LIST_SEPARATOR; + } + usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list); + } else { + if (GetLastError() != ERROR_INVALID_DATA) + usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0)); + lookup[k].list[0] = 0; + } + } + + for (i = 2; i < USB_API_MAX; i++) { + for (k = 0; k < 3; k++) { + j = get_sub_api(lookup[k].list, i); + if (j >= 0) { + usbi_dbg("matched %s name against %s", lookup[k].designation, + (i != USB_API_WINUSBX) ? usb_api_backend[i].designation : usb_api_backend[i].driver_name_list[j]); + *api = i; + *sub_api = j; + return; + } + } + } +} + +static int set_composite_interface(struct libusb_context *ctx, struct libusb_device *dev, + char *dev_interface_path, char *device_id, int api, int sub_api) +{ + struct winusb_device_priv *priv = _device_priv(dev); + int interface_number; + const char *mi_str; + + // Because MI_## are not necessarily in sequential order (some composite + // devices will have only MI_00 & MI_03 for instance), we retrieve the actual + // interface number from the path's MI value + mi_str = strstr(device_id, "MI_"); + if ((mi_str != NULL) && isdigit(mi_str[3]) && isdigit(mi_str[4])) { + interface_number = ((mi_str[3] - '0') * 10) + (mi_str[4] - '0'); + } else { + usbi_warn(ctx, "failure to read interface number for %s, using default value", device_id); + interface_number = 0; + } + + if (interface_number >= USB_MAXINTERFACES) { + usbi_warn(ctx, "interface %d too large - ignoring interface path %s", interface_number, dev_interface_path); + return LIBUSB_ERROR_ACCESS; + } + + if (priv->usb_interface[interface_number].path != NULL) { + if (api == USB_API_HID) { + // HID devices can have multiple collections (COL##) for each MI_## interface + usbi_dbg("interface[%d] already set - ignoring HID collection: %s", + interface_number, device_id); + return LIBUSB_ERROR_ACCESS; + } + // In other cases, just use the latest data + safe_free(priv->usb_interface[interface_number].path); + } + + usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path); + priv->usb_interface[interface_number].path = dev_interface_path; + priv->usb_interface[interface_number].apib = &usb_api_backend[api]; + priv->usb_interface[interface_number].sub_api = sub_api; + if ((api == USB_API_HID) && (priv->hid == NULL)) { + priv->hid = calloc(1, sizeof(struct hid_device_priv)); + if (priv->hid == NULL) + return LIBUSB_ERROR_NO_MEM; + } + + return LIBUSB_SUCCESS; +} + +static int set_hid_interface(struct libusb_context *ctx, struct libusb_device *dev, + char *dev_interface_path) +{ + int i; + struct winusb_device_priv *priv = _device_priv(dev); + + if (priv->hid == NULL) { + usbi_err(ctx, "program assertion failed: parent is not HID"); + return LIBUSB_ERROR_NO_DEVICE; + } else if (priv->hid->nb_interfaces == USB_MAXINTERFACES) { + usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device"); + return LIBUSB_ERROR_NO_DEVICE; + } + + for (i = 0; i < priv->hid->nb_interfaces; i++) { + if ((priv->usb_interface[i].path != NULL) && strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) { + usbi_dbg("interface[%d] already set to %s", i, dev_interface_path); + return LIBUSB_ERROR_ACCESS; + } + } + + priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path; + priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID]; + usbi_dbg("interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path); + priv->hid->nb_interfaces++; + return LIBUSB_SUCCESS; +} + +/* + * get_device_list: libusb backend device enumeration function + */ +static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) +{ + struct discovered_devs *discdevs; + HDEVINFO *dev_info, dev_info_intf, dev_info_enum; + SP_DEVINFO_DATA dev_info_data; + DWORD _index = 0; + GUID hid_guid; + int r = LIBUSB_SUCCESS; + int api, sub_api; + unsigned int pass, i, j; + char enumerator[16]; + char dev_id[MAX_PATH_LENGTH]; + struct libusb_device *dev, *parent_dev; + struct winusb_device_priv *priv, *parent_priv; + char *dev_interface_path = NULL; + unsigned long session_id; + DWORD size, port_nr, reg_type, install_state; + HKEY key; + WCHAR guid_string_w[MAX_GUID_STRING_LENGTH]; + GUID *if_guid; + LONG s; +#define HUB_PASS 0 +#define DEV_PASS 1 +#define HCD_PASS 2 +#define GEN_PASS 3 +#define HID_PASS 4 +#define EXT_PASS 5 + // Keep a list of guids that will be enumerated +#define GUID_SIZE_STEP 8 + const GUID **guid_list, **new_guid_list; + unsigned int guid_size = GUID_SIZE_STEP; + unsigned int nb_guids; + // Keep a list of PnP enumerator strings that are found + char *usb_enumerator[8] = { "USB" }; + unsigned int nb_usb_enumerators = 1; + unsigned int usb_enum_index = 0; + // Keep a list of newly allocated devs to unref +#define UNREF_SIZE_STEP 16 + libusb_device **unref_list, **new_unref_list; + unsigned int unref_size = UNREF_SIZE_STEP; + unsigned int unref_cur = 0; + + // PASS 1 : (re)enumerate HCDs (allows for HCD hotplug) + // PASS 2 : (re)enumerate HUBS + // PASS 3 : (re)enumerate generic USB devices (including driverless) + // and list additional USB device interface GUIDs to explore + // PASS 4 : (re)enumerate master USB devices that have a device interface + // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and + // set the device interfaces. + + // Init the GUID table + guid_list = malloc(guid_size * sizeof(void *)); + if (guid_list == NULL) { + usbi_err(ctx, "failed to alloc guid list"); + return LIBUSB_ERROR_NO_MEM; + } + + guid_list[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB; + guid_list[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE; + guid_list[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER; + guid_list[GEN_PASS] = NULL; + if (api_hid_available) { + HidD_GetHidGuid(&hid_guid); + guid_list[HID_PASS] = &hid_guid; + } else { + guid_list[HID_PASS] = NULL; + } + nb_guids = EXT_PASS; + + unref_list = malloc(unref_size * sizeof(void *)); + if (unref_list == NULL) { + usbi_err(ctx, "failed to alloc unref list"); + free((void *)guid_list); + return LIBUSB_ERROR_NO_MEM; + } + + dev_info_intf = pSetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (dev_info_intf == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "failed to obtain device info list: %s", windows_error_str(0)); + free(unref_list); + free((void *)guid_list); + return LIBUSB_ERROR_OTHER; + } + + for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) { +//#define ENUM_DEBUG +#if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG) + const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"}; + usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass])); +#endif + if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL)) + continue; + + dev_info = (pass != GEN_PASS) ? &dev_info_intf : &dev_info_enum; + + for (i = 0; ; i++) { + // safe loop: free up any (unprotected) dynamic resource + // NB: this is always executed before breaking the loop + safe_free(dev_interface_path); + priv = parent_priv = NULL; + dev = parent_dev = NULL; + + // Safe loop: end of loop conditions + if (r != LIBUSB_SUCCESS) + break; + + if ((pass == HCD_PASS) && (i == UINT8_MAX)) { + usbi_warn(ctx, "program assertion failed - found more than %u buses, skipping the rest.", UINT8_MAX); + break; + } + + if (pass != GEN_PASS) { + // Except for GEN, all passes deal with device interfaces + r = get_interface_details(ctx, *dev_info, &dev_info_data, guid_list[pass], &_index, &dev_interface_path); + if ((r != LIBUSB_SUCCESS) || (dev_interface_path == NULL)) { + _index = 0; + break; + } + } else { + // Workaround for a Nec/Renesas USB 3.0 driver bug where root hubs are + // being listed under the "NUSB3" PnP Symbolic Name rather than "USB". + // The Intel USB 3.0 driver behaves similar, but uses "IUSB3" + // The Intel Alpine Ridge USB 3.1 driver uses "IARUSB3" + for (; usb_enum_index < nb_usb_enumerators; usb_enum_index++) { + if (get_devinfo_data(ctx, dev_info, &dev_info_data, usb_enumerator[usb_enum_index], i)) + break; + i = 0; + } + if (usb_enum_index == nb_usb_enumerators) + break; + } + + // Read the Device ID path + if (!pSetupDiGetDeviceInstanceIdA(*dev_info, &dev_info_data, dev_id, sizeof(dev_id), NULL)) { + usbi_warn(ctx, "could not read the device instance ID for devInst %X, skipping", + dev_info_data.DevInst); + continue; + } + +#ifdef ENUM_DEBUG + usbi_dbg("PRO: %s", dev_id); +#endif + + // Set API to use or get additional data from generic pass + api = USB_API_UNSUPPORTED; + sub_api = SUB_API_NOTSET; + switch (pass) { + case HCD_PASS: + break; + case HUB_PASS: + api = USB_API_HUB; + // Fetch the PnP enumerator class for this hub + // This will allow us to enumerate all classes during the GEN pass + if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME, + NULL, (PBYTE)enumerator, sizeof(enumerator), NULL)) { + usbi_err(ctx, "could not read enumerator string for device '%s': %s", dev_id, windows_error_str(0)); + LOOP_BREAK(LIBUSB_ERROR_OTHER); + } + for (j = 0; j < nb_usb_enumerators; j++) { + if (strcmp(usb_enumerator[j], enumerator) == 0) + break; + } + if (j == nb_usb_enumerators) { + usbi_dbg("found new PnP enumerator string '%s'", enumerator); + if (nb_usb_enumerators < ARRAYSIZE(usb_enumerator)) { + usb_enumerator[nb_usb_enumerators] = _strdup(enumerator); + if (usb_enumerator[nb_usb_enumerators] != NULL) { + nb_usb_enumerators++; + } else { + usbi_err(ctx, "could not allocate enumerator string '%s'", enumerator); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + } else { + usbi_warn(ctx, "too many enumerator strings, some devices may not be accessible"); + } + } + break; + case GEN_PASS: + // We use the GEN pass to detect driverless devices... + if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_DRIVER, + NULL, NULL, 0, NULL) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { + usbi_info(ctx, "The following device has no driver: '%s'", dev_id); + usbi_info(ctx, "libusb will not be able to access it"); + } + // ...and to add the additional device interface GUIDs + key = pSetupDiOpenDevRegKey(*dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + if (key == INVALID_HANDLE_VALUE) + break; + // Look for both DeviceInterfaceGUIDs *and* DeviceInterfaceGUID, in that order + size = sizeof(guid_string_w); + s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type, + (LPBYTE)guid_string_w, &size); + if (s == ERROR_FILE_NOT_FOUND) + s = pRegQueryValueExW(key, L"DeviceInterfaceGUID", NULL, ®_type, + (LPBYTE)guid_string_w, &size); + pRegCloseKey(key); + if ((s == ERROR_SUCCESS) && + (((reg_type == REG_SZ) && (size == (sizeof(guid_string_w) - sizeof(WCHAR)))) || + ((reg_type == REG_MULTI_SZ) && (size == sizeof(guid_string_w))))) { + if (nb_guids == guid_size) { + new_guid_list = realloc((void *)guid_list, (guid_size + GUID_SIZE_STEP) * sizeof(void *)); + if (new_guid_list == NULL) { + usbi_err(ctx, "failed to realloc guid list"); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + guid_list = new_guid_list; + guid_size += GUID_SIZE_STEP; + } + if_guid = malloc(sizeof(*if_guid)); + if (if_guid == NULL) { + usbi_err(ctx, "failed to alloc if_guid"); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + if (pIIDFromString(guid_string_w, if_guid) != 0) { + usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string, skipping", dev_id); + free(if_guid); + } else { + // Check if we've already seen this GUID + for (j = EXT_PASS; j < nb_guids; j++) { + if (memcmp(guid_list[j], if_guid, sizeof(*if_guid)) == 0) + break; + } + if (j == nb_guids) { + usbi_dbg("extra GUID: %s", guid_to_string(if_guid)); + guid_list[nb_guids++] = if_guid; + } else { + // Duplicate, ignore + free(if_guid); + } + } + } else if (s == ERROR_SUCCESS) { + usbi_warn(ctx, "unexpected type/size of DeviceInterfaceGUID for '%s'", dev_id); + } + break; + case HID_PASS: + api = USB_API_HID; + break; + default: + // Get the API type (after checking that the driver installation is OK) + if ((!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_INSTALL_STATE, + NULL, (PBYTE)&install_state, sizeof(install_state), &size)) || (size != sizeof(install_state))) { + usbi_warn(ctx, "could not detect installation state of driver for '%s': %s", + dev_id, windows_error_str(0)); + } else if (install_state != 0) { + usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %u) - skipping", + dev_id, (unsigned int)install_state); + continue; + } + get_api_type(ctx, dev_info, &dev_info_data, &api, &sub_api); + break; + } + + // Find parent device (for the passes that need it) + if (pass >= GEN_PASS) { + parent_dev = get_ancestor(ctx, dev_info_data.DevInst, NULL); + if (parent_dev == NULL) { + // Root hubs will not have a parent + dev = usbi_get_device_by_session_id(ctx, (unsigned long)dev_info_data.DevInst); + if (dev != NULL) { + priv = _device_priv(dev); + if (priv->root_hub) + goto track_unref; + libusb_unref_device(dev); + } + + usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id); + continue; + } + + parent_priv = _device_priv(parent_dev); + // virtual USB devices are also listed during GEN - don't process these yet + if ((pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB)) { + libusb_unref_device(parent_dev); + continue; + } + } + + // Create new or match existing device, using the devInst as session id + if ((pass <= GEN_PASS) && (pass != HCD_PASS)) { // For subsequent passes, we'll lookup the parent + // These are the passes that create "new" devices + session_id = (unsigned long)dev_info_data.DevInst; + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev == NULL) { + alloc_device: + usbi_dbg("allocating new device for session [%lX]", session_id); + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + + priv = winusb_device_priv_init(dev); + priv->dev_id = _strdup(dev_id); + if (priv->dev_id == NULL) { + libusb_unref_device(dev); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + } else { + usbi_dbg("found existing device for session [%lX]", session_id); + + priv = _device_priv(dev); + if (strcmp(priv->dev_id, dev_id) != 0) { + usbi_dbg("device instance ID for session [%lX] changed", session_id); + usbi_disconnect_device(dev); + libusb_unref_device(dev); + goto alloc_device; + } + } + + track_unref: + // Keep track of devices that need unref + if (unref_cur == unref_size) { + new_unref_list = realloc(unref_list, (unref_size + UNREF_SIZE_STEP) * sizeof(void *)); + if (new_unref_list == NULL) { + usbi_err(ctx, "could not realloc list for unref - aborting"); + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + } + unref_list = new_unref_list; + unref_size += UNREF_SIZE_STEP; + } + unref_list[unref_cur++] = dev; + } + + // Setup device + switch (pass) { + case HUB_PASS: + case DEV_PASS: + // If the device has already been setup, don't do it again + if (priv->path != NULL) + break; + // Take care of API initialization + priv->path = dev_interface_path; + dev_interface_path = NULL; + priv->apib = &usb_api_backend[api]; + priv->sub_api = sub_api; + switch (api) { + case USB_API_COMPOSITE: + case USB_API_HUB: + break; + case USB_API_HID: + priv->hid = calloc(1, sizeof(struct hid_device_priv)); + if (priv->hid == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + break; + default: + // For other devices, the first interface is the same as the device + priv->usb_interface[0].path = _strdup(priv->path); + if (priv->usb_interface[0].path == NULL) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + // The following is needed if we want API calls to work for both simple + // and composite devices. + for (j = 0; j < USB_MAXINTERFACES; j++) + priv->usb_interface[j].apib = &usb_api_backend[api]; + break; + } + break; + case HCD_PASS: + r = enumerate_hcd_root_hub(ctx, dev_id, (uint8_t)(i + 1), dev_info_data.DevInst); + break; + case GEN_PASS: + // The SPDRP_ADDRESS for USB devices is the device port number on the hub + port_nr = 0; + if (!pSetupDiGetDeviceRegistryPropertyA(*dev_info, &dev_info_data, SPDRP_ADDRESS, + NULL, (PBYTE)&port_nr, sizeof(port_nr), &size) || (size != sizeof(port_nr))) + usbi_warn(ctx, "could not retrieve port number for device '%s': %s", dev_id, windows_error_str(0)); + r = init_device(dev, parent_dev, (uint8_t)port_nr, dev_info_data.DevInst); + if (r == LIBUSB_SUCCESS) { + // Append device to the list of discovered devices + discdevs = discovered_devs_append(*_discdevs, dev); + if (!discdevs) + LOOP_BREAK(LIBUSB_ERROR_NO_MEM); + + *_discdevs = discdevs; + } else if (r == LIBUSB_ERROR_NO_DEVICE) { + // This can occur if the device was disconnected but Windows hasn't + // refreshed its enumeration yet - in that case, we ignore the device + r = LIBUSB_SUCCESS; + } + break; + default: // HID_PASS and later + if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) { + if (parent_priv->apib->id == USB_API_HID) { + usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data); + r = set_hid_interface(ctx, parent_dev, dev_interface_path); + } else { + usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data); + r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id, api, sub_api); + } + switch (r) { + case LIBUSB_SUCCESS: + dev_interface_path = NULL; + break; + case LIBUSB_ERROR_ACCESS: + // interface has already been set => make sure dev_interface_path is freed then + r = LIBUSB_SUCCESS; + break; + default: + LOOP_BREAK(r); + break; + } + } + libusb_unref_device(parent_dev); + break; + } + } + } + + pSetupDiDestroyDeviceInfoList(dev_info_intf); + + // Free any additional GUIDs + for (pass = EXT_PASS; pass < nb_guids; pass++) + free((void *)guid_list[pass]); + free((void *)guid_list); + + // Free any PnP enumerator strings + for (i = 1; i < nb_usb_enumerators; i++) + free(usb_enumerator[i]); + + // Unref newly allocated devs + for (i = 0; i < unref_cur; i++) + libusb_unref_device(unref_list[i]); + free(unref_list); + + return r; +} + +static int winusb_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer) +{ + struct winusb_device_priv *priv = _device_priv(dev); + + memcpy(buffer, &priv->dev_descriptor, DEVICE_DESC_LENGTH); + return LIBUSB_SUCCESS; +} + +static int winusb_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len) +{ + struct winusb_device_priv *priv = _device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + size_t size; + + // config index is zero based + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_INVALID_PARAM; + + if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL)) + return LIBUSB_ERROR_NOT_FOUND; + + config_header = priv->config_descriptor[config_index]; + + size = MIN(config_header->wTotalLength, len); + memcpy(buffer, priv->config_descriptor[config_index], size); + return (int)size; +} + +static int winusb_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, + unsigned char **buffer) +{ + struct winusb_device_priv *priv = _device_priv(dev); + PUSB_CONFIGURATION_DESCRIPTOR config_header; + uint8_t index; + + if (priv->config_descriptor == NULL) + return LIBUSB_ERROR_NOT_FOUND; + + for (index = 0; index < dev->num_configurations; index++) { + config_header = priv->config_descriptor[index]; + if (config_header == NULL) + continue; + if (config_header->bConfigurationValue == bConfigurationValue) { + *buffer = (unsigned char *)priv->config_descriptor[index]; + return (int)config_header->wTotalLength; + } + } + + return LIBUSB_ERROR_NOT_FOUND; +} + +/* + * return the cached copy of the active config descriptor + */ +static int winusb_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len) +{ + struct winusb_device_priv *priv = _device_priv(dev); + unsigned char *config_desc; + int r; + + if (priv->active_config == 0) + return LIBUSB_ERROR_NOT_FOUND; + + r = winusb_get_config_descriptor_by_value(dev, priv->active_config, &config_desc); + if (r < 0) + return r; + + len = MIN((size_t)r, len); + memcpy(buffer, config_desc, len); + return (int)len; +} + +static int winusb_open(struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, open); + + return priv->apib->open(SUB_API_NOTSET, dev_handle); +} + +static void winusb_close(struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + if (priv->apib->close) + priv->apib->close(SUB_API_NOTSET, dev_handle); +} + +static int winusb_get_configuration(struct libusb_device_handle *dev_handle, int *config) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + if (priv->active_config == 0) { + *config = 0; + return LIBUSB_ERROR_NOT_FOUND; + } + + *config = priv->active_config; + return LIBUSB_SUCCESS; +} + +/* + * from http://msdn.microsoft.com/en-us/library/ms793522.aspx: "The port driver + * does not currently expose a service that allows higher-level drivers to set + * the configuration." + */ +static int winusb_set_configuration(struct libusb_device_handle *dev_handle, int config) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int r = LIBUSB_SUCCESS; + + if (config >= USB_MAXCONFIG) + return LIBUSB_ERROR_INVALID_PARAM; + + r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT | + LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, + LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config, + 0, NULL, 0, 1000); + + if (r == LIBUSB_SUCCESS) + priv->active_config = (uint8_t)config; + + return r; +} + +static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int r; + + CHECK_SUPPORTED_API(priv->apib, claim_interface); + + safe_free(priv->usb_interface[iface].endpoint); + priv->usb_interface[iface].nb_endpoints = 0; + + r = priv->apib->claim_interface(SUB_API_NOTSET, dev_handle, iface); + + if (r == LIBUSB_SUCCESS) + r = windows_assign_endpoints(dev_handle, iface, 0); + + return r; +} + +static int winusb_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int r; + + CHECK_SUPPORTED_API(priv->apib, set_interface_altsetting); + + safe_free(priv->usb_interface[iface].endpoint); + priv->usb_interface[iface].nb_endpoints = 0; + + r = priv->apib->set_interface_altsetting(SUB_API_NOTSET, dev_handle, iface, altsetting); + + if (r == LIBUSB_SUCCESS) + r = windows_assign_endpoints(dev_handle, iface, altsetting); + + return r; +} + +static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, release_interface); + + return priv->apib->release_interface(SUB_API_NOTSET, dev_handle, iface); +} + +static int winusb_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, clear_halt); + + return priv->apib->clear_halt(SUB_API_NOTSET, dev_handle, endpoint); +} + +static int winusb_reset_device(struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, reset_device); + + return priv->apib->reset_device(SUB_API_NOTSET, dev_handle); +} + +static void winusb_destroy_device(struct libusb_device *dev) +{ + winusb_device_priv_release(dev); +} + +static void winusb_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + + usbi_close(transfer_priv->pollable_fd.fd); + transfer_priv->pollable_fd = INVALID_WINFD; + transfer_priv->handle = NULL; + safe_free(transfer_priv->hid_buffer); + safe_free(transfer_priv->iso_context); + + // When auto claim is in use, attempt to release the auto-claimed interface + auto_release(itransfer); +} + +static int do_submit_transfer(struct usbi_transfer *itransfer, short events, + int (*transfer_fn)(int, struct usbi_transfer *)) +{ + struct libusb_context *ctx = ITRANSFER_CTX(itransfer); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winfd wfd; + int r; + + wfd = usbi_create_fd(); + if (wfd.fd < 0) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_add_pollfd(ctx, wfd.fd, events); + if (r) { + usbi_close(wfd.fd); + return r; + } + + // Use transfer_priv to store data needed for async polling + transfer_priv->pollable_fd = wfd; + + r = transfer_fn(SUB_API_NOTSET, itransfer); + + if ((r != LIBUSB_SUCCESS) && (r != LIBUSB_ERROR_OVERFLOW)) { + usbi_remove_pollfd(ctx, wfd.fd); + usbi_close(wfd.fd); + transfer_priv->pollable_fd = INVALID_WINFD; + } + + return r; +} + +static int winusb_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int (*transfer_fn)(int, struct usbi_transfer *); + short events; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + events = (transfer->buffer[0] & LIBUSB_ENDPOINT_IN) ? POLLIN : POLLOUT; + transfer_fn = priv->apib->submit_control_transfer; + break; + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; + events = IS_XFERIN(transfer) ? POLLIN : POLLOUT; + transfer_fn = priv->apib->submit_bulk_transfer; + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + events = IS_XFERIN(transfer) ? POLLIN : POLLOUT; + transfer_fn = priv->apib->submit_iso_transfer; + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } + + if (transfer_fn == NULL) { + usbi_warn(TRANSFER_CTX(transfer), + "unsupported transfer type %d (unrecognized device driver)", + transfer->type); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + return do_submit_transfer(itransfer, events, transfer_fn); +} + +static int windows_abort_control(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, abort_control); + + return priv->apib->abort_control(SUB_API_NOTSET, itransfer); +} + +static int windows_abort_transfers(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + + CHECK_SUPPORTED_API(priv->apib, abort_transfers); + + return priv->apib->abort_transfers(SUB_API_NOTSET, itransfer); +} + +static int winusb_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return windows_abort_control(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return windows_abort_transfers(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return LIBUSB_ERROR_NOT_SUPPORTED; + default: + usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int winusb_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + return priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size); +} + +static int winusb_get_transfer_fd(struct usbi_transfer *itransfer) +{ + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + return transfer_priv->pollable_fd.fd; +} + +static void winusb_get_overlapped_result(struct usbi_transfer *itransfer, + DWORD *io_result, DWORD *io_size) +{ + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winfd *pollable_fd = &transfer_priv->pollable_fd; + + if (HasOverlappedIoCompletedSync(pollable_fd->overlapped)) { + *io_result = NO_ERROR; + *io_size = (DWORD)pollable_fd->overlapped->InternalHigh; + } else if (GetOverlappedResult(transfer_priv->handle, pollable_fd->overlapped, io_size, FALSE)) { + // Regular async overlapped + *io_result = NO_ERROR; + } else { + *io_result = GetLastError(); + } +} + +// NB: MSVC6 does not support named initializers. +const struct windows_backend winusb_backend = { + winusb_init, + winusb_exit, + winusb_get_device_list, + winusb_open, + winusb_close, + winusb_get_device_descriptor, + winusb_get_active_config_descriptor, + winusb_get_config_descriptor, + winusb_get_config_descriptor_by_value, + winusb_get_configuration, + winusb_set_configuration, + winusb_claim_interface, + winusb_release_interface, + winusb_set_interface_altsetting, + winusb_clear_halt, + winusb_reset_device, + winusb_destroy_device, + winusb_submit_transfer, + winusb_cancel_transfer, + winusb_clear_transfer_priv, + winusb_copy_transfer_data, + winusb_get_transfer_fd, + winusb_get_overlapped_result, +}; + +/* + * USB API backends + */ + +static const char * const composite_driver_names[] = {"USBCCGP"}; +static const char * const winusbx_driver_names[] = {"libusbK", "libusb0", "WinUSB"}; +static const char * const hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"}; +const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { + { + USB_API_UNSUPPORTED, + "Unsupported API", + // No supported operations + }, + { + USB_API_HUB, + "HUB API", + // No supported operations + }, + { + USB_API_COMPOSITE, + "Composite API", + composite_driver_names, + ARRAYSIZE(composite_driver_names), + NULL, /* init */ + NULL, /* exit */ + composite_open, + composite_close, + NULL, /* configure_endpoints */ + composite_claim_interface, + composite_set_interface_altsetting, + composite_release_interface, + composite_clear_halt, + composite_reset_device, + composite_submit_bulk_transfer, + composite_submit_iso_transfer, + composite_submit_control_transfer, + composite_abort_control, + composite_abort_transfers, + composite_copy_transfer_data, + }, + { + USB_API_WINUSBX, + "WinUSB-like APIs", + winusbx_driver_names, + ARRAYSIZE(winusbx_driver_names), + winusbx_init, + winusbx_exit, + winusbx_open, + winusbx_close, + winusbx_configure_endpoints, + winusbx_claim_interface, + winusbx_set_interface_altsetting, + winusbx_release_interface, + winusbx_clear_halt, + winusbx_reset_device, + winusbx_submit_bulk_transfer, + winusbx_submit_iso_transfer, + winusbx_submit_control_transfer, + winusbx_abort_control, + winusbx_abort_transfers, + winusbx_copy_transfer_data, + }, + { + USB_API_HID, + "HID API", + // No supported operations + }, +}; + + +/* + * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions + */ +#define WinUSBX_Set(fn) \ + do { \ + if (native_winusb) \ + WinUSBX[i].fn = (WinUsb_##fn##_t)GetProcAddress(h, "WinUsb_" #fn); \ + else \ + pLibK_GetProcAddress((PVOID *)&WinUSBX[i].fn, i, KUSB_FNID_##fn); \ + } while (0) + +static int winusbx_init(struct libusb_context *ctx) +{ + HMODULE h; + bool native_winusb; + int i; + KLIB_VERSION LibK_Version; + LibK_GetProcAddress_t pLibK_GetProcAddress = NULL; + LibK_GetVersion_t pLibK_GetVersion; + + h = LoadLibraryA("libusbK"); + + if (h == NULL) { + usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB"); + h = LoadLibraryA("WinUSB"); + + if (h == NULL) { + usbi_warn(ctx, "WinUSB DLL is not available either, " + "you will not be able to access devices outside of enumeration"); + return LIBUSB_ERROR_NOT_FOUND; + } + } else { + usbi_dbg("using libusbK DLL for universal access"); + pLibK_GetVersion = (LibK_GetVersion_t)GetProcAddress(h, "LibK_GetVersion"); + if (pLibK_GetVersion != NULL) { + pLibK_GetVersion(&LibK_Version); + usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor, + LibK_Version.Micro, LibK_Version.Nano); + } + pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(h, "LibK_GetProcAddress"); + if (pLibK_GetProcAddress == NULL) { + usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL"); + FreeLibrary(h); + return LIBUSB_ERROR_NOT_FOUND; + } + } + + native_winusb = (pLibK_GetProcAddress == NULL); + for (i = 0; i < SUB_API_MAX; i++) { + WinUSBX_Set(AbortPipe); + WinUSBX_Set(ControlTransfer); + WinUSBX_Set(FlushPipe); + WinUSBX_Set(Free); + WinUSBX_Set(GetAssociatedInterface); + WinUSBX_Set(Initialize); + WinUSBX_Set(ReadPipe); + if (!native_winusb) + WinUSBX_Set(ResetDevice); + WinUSBX_Set(ResetPipe); + WinUSBX_Set(SetCurrentAlternateSetting); + WinUSBX_Set(SetPipePolicy); + WinUSBX_Set(WritePipe); + WinUSBX_Set(IsoReadPipe); + WinUSBX_Set(IsoWritePipe); + + if (WinUSBX[i].Initialize != NULL) { + WinUSBX[i].initialized = true; + // Assume driver supports CancelIoEx() if it is available + WinUSBX[i].CancelIoEx_supported = (pCancelIoEx != NULL); + usbi_dbg("initalized sub API %s", winusbx_driver_names[i]); + } else { + usbi_warn(ctx, "Failed to initalize sub API %s", winusbx_driver_names[i]); + WinUSBX[i].initialized = false; + } + } + + WinUSBX_handle = h; + return LIBUSB_SUCCESS; +} + +static void winusbx_exit(void) +{ + if (WinUSBX_handle != NULL) { + FreeLibrary(WinUSBX_handle); + WinUSBX_handle = NULL; + + /* Reset the WinUSBX API structures */ + memset(&WinUSBX, 0, sizeof(WinUSBX)); + } +} + +// NB: open and close must ensure that they only handle interface of +// the right API type, as these functions can be called wholesale from +// composite_open(), with interfaces belonging to different APIs +static int winusbx_open(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + HANDLE file_handle; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // WinUSB requires a separate handle for each interface + for (i = 0; i < USB_MAXINTERFACES; i++) { + if ((priv->usb_interface[i].path != NULL) + && (priv->usb_interface[i].apib->id == USB_API_WINUSBX)) { + file_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (file_handle == INVALID_HANDLE_VALUE) { + usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0)); + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: // The device was disconnected + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_ACCESS_DENIED: + return LIBUSB_ERROR_ACCESS; + default: + return LIBUSB_ERROR_IO; + } + } + handle_priv->interface_handle[i].dev_handle = file_handle; + } + } + return LIBUSB_SUCCESS; +} + +static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE handle; + int i; + + if (sub_api == SUB_API_NOTSET) + sub_api = priv->sub_api; + + if (!WinUSBX[sub_api].initialized) + return; + + if (priv->apib->id == USB_API_COMPOSITE) { + // If this is a composite device, just free and close all WinUSB-like + // interfaces directly (each is independent and not associated with another) + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) { + handle = handle_priv->interface_handle[i].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + + handle = handle_priv->interface_handle[i].dev_handle; + if (HANDLE_VALID(handle)) + CloseHandle(handle); + } + } + } else { + // If this is a WinUSB device, free all interfaces above interface 0, + // then free and close interface 0 last + for (i = 1; i < USB_MAXINTERFACES; i++) { + handle = handle_priv->interface_handle[i].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + } + handle = handle_priv->interface_handle[0].api_handle; + if (HANDLE_VALID(handle)) + WinUSBX[sub_api].Free(handle); + + handle = handle_priv->interface_handle[0].dev_handle; + if (HANDLE_VALID(handle)) + CloseHandle(handle); + } +} + +static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle = handle_priv->interface_handle[iface].api_handle; + UCHAR policy; + ULONG timeout = 0; + uint8_t endpoint_address; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // With handle and enpoints set (in parent), we can setup the default pipe properties + // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx + for (i = -1; i < priv->usb_interface[iface].nb_endpoints; i++) { + endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i]; + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) + usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address); + + if ((i == -1) || (sub_api == SUB_API_LIBUSB0)) + continue; // Other policies don't apply to control endpoint or libusb0 + + policy = false; + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) + usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address); + + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) + usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address); + + policy = true; + /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See: + https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */ + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) + usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address); + + if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) + usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address); + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE); + SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; + HDEVINFO dev_info = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA dev_info_data; + char *dev_path_no_guid = NULL; + char filter_path[] = "\\\\.\\libusb0-0000"; + bool found_filter = false; + HANDLE file_handle, winusb_handle; + DWORD err; + int i; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // If the device is composite, but using the default Windows composite parent driver (usbccgp) + // or if it's the first WinUSB-like interface, we get a handle through Initialize(). + if ((is_using_usbccgp) || (iface == 0)) { + // composite device (independent interfaces) or interface 0 + file_handle = handle_priv->interface_handle[iface].dev_handle; + if (!HANDLE_VALID(file_handle)) + return LIBUSB_ERROR_NOT_FOUND; + + if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + err = GetLastError(); + switch (err) { + case ERROR_BAD_COMMAND: + // The device was disconnected + usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + default: + // it may be that we're using the libusb0 filter driver. + // TODO: can we move this whole business into the K/0 DLL? + for (i = 0; ; i++) { + safe_free(dev_interface_details); + safe_free(dev_path_no_guid); + + dev_interface_details = get_interface_details_filter(ctx, &dev_info, &dev_info_data, &GUID_DEVINTERFACE_LIBUSB0_FILTER, i, filter_path); + if ((found_filter) || (dev_interface_details == NULL)) + break; + + // ignore GUID part + dev_path_no_guid = sanitize_path(strtok(dev_interface_details->DevicePath, "{")); + if (dev_path_no_guid == NULL) + continue; + + if (strncmp(dev_path_no_guid, priv->usb_interface[iface].path, strlen(dev_path_no_guid)) == 0) { + file_handle = CreateFileA(filter_path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (file_handle != INVALID_HANDLE_VALUE) { + if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + // Replace the existing file handle with the working one + CloseHandle(handle_priv->interface_handle[iface].dev_handle); + handle_priv->interface_handle[iface].dev_handle = file_handle; + found_filter = true; + } else { + usbi_err(ctx, "could not initialize filter driver for %s", filter_path); + CloseHandle(file_handle); + } + } else { + usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0)); + } + } + } + free(dev_interface_details); + if (!found_filter) { + usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err)); + return LIBUSB_ERROR_ACCESS; + } + } + } + handle_priv->interface_handle[iface].api_handle = winusb_handle; + } else { + // For all other interfaces, use GetAssociatedInterface() + winusb_handle = handle_priv->interface_handle[0].api_handle; + // It is a requirement for multiple interface devices on Windows that, to you + // must first claim the first interface before you claim the others + if (!HANDLE_VALID(winusb_handle)) { + file_handle = handle_priv->interface_handle[0].dev_handle; + if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + handle_priv->interface_handle[0].api_handle = winusb_handle; + usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface); + } else { + usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + } + if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1), + &handle_priv->interface_handle[iface].api_handle)) { + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + switch (GetLastError()) { + case ERROR_NO_MORE_ITEMS: // invalid iface + return LIBUSB_ERROR_NOT_FOUND; + case ERROR_BAD_COMMAND: // The device was disconnected + return LIBUSB_ERROR_NO_DEVICE; + case ERROR_ALREADY_EXISTS: // already claimed + return LIBUSB_ERROR_BUSY; + default: + usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0)); + return LIBUSB_ERROR_ACCESS; + } + } + } + usbi_dbg("claimed interface %d", iface); + handle_priv->active_interface = iface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + winusb_handle = handle_priv->interface_handle[iface].api_handle; + if (!HANDLE_VALID(winusb_handle)) + return LIBUSB_ERROR_NOT_FOUND; + + WinUSBX[sub_api].Free(winusb_handle); + handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; + + return LIBUSB_SUCCESS; +} + +/* + * Return the first valid interface (of the same API type), for control transfers + */ +static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id) +{ + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int i; + + if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) { + usbi_dbg("unsupported API ID"); + return -1; + } + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle) + && HANDLE_VALID(handle_priv->interface_handle[i].api_handle) + && (priv->usb_interface[i].apib->id == api_id)) + return i; + } + + return -1; +} + +/* + * Lookup interface by endpoint address. -1 if not found + */ +static int interface_by_endpoint(struct winusb_device_priv *priv, + struct winusb_device_handle_priv *handle_priv, uint8_t endpoint_address) +{ + int i, j; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (!HANDLE_VALID(handle_priv->interface_handle[i].api_handle)) + continue; + if (priv->usb_interface[i].endpoint == NULL) + continue; + for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) { + if (priv->usb_interface[i].endpoint[j] == endpoint_address) + return i; + } + } + + return -1; +} + +static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + PWINUSB_SETUP_PACKET setup = (PWINUSB_SETUP_PACKET)transfer->buffer; + ULONG size; + HANDLE winusb_handle; + OVERLAPPED *overlapped; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; + + // Windows places upper limits on the control transfer size + // See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538112.aspx + if (size > MAX_CTRL_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + + current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX); + if (current_interface < 0) { + if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("will use interface %d", current_interface); + + transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + overlapped = transfer_priv->pollable_fd.overlapped; + + // Sending of set configuration control requests from WinUSB creates issues + if ((LIBUSB_REQ_TYPE(setup->RequestType) == LIBUSB_REQUEST_TYPE_STANDARD) + && (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION)) { + if (setup->Value != priv->active_config) { + usbi_warn(ctx, "cannot set configuration other than the default one"); + return LIBUSB_ERROR_INVALID_PARAM; + } + windows_force_sync_completion(overlapped, 0); + } else { + if (!WinUSBX[sub_api].ControlTransfer(winusb_handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) { + usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + } else { + windows_force_sync_completion(overlapped, size); + } + } + + transfer_priv->interface_number = (uint8_t)current_interface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + if (altsetting > 255) + return LIBUSB_ERROR_INVALID_PARAM; + + winusb_handle = handle_priv->interface_handle[iface].api_handle; + if (!HANDLE_VALID(winusb_handle)) { + usbi_err(ctx, "interface must be claimed first"); + return LIBUSB_ERROR_NOT_FOUND; + } + + if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) { + usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + HANDLE winusb_handle; + OVERLAPPED *overlapped; + bool ret; + int current_interface; + int i; + UINT offset; + PKISO_CONTEXT iso_context; + size_t iso_ctx_size; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + if ((sub_api != SUB_API_LIBUSBK) && (sub_api != SUB_API_LIBUSB0)) { + // iso only supported on libusbk-based backends + PRINT_UNSUPPORTED_API(submit_iso_transfer); + return LIBUSB_ERROR_NOT_SUPPORTED; + }; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface); + + transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + overlapped = transfer_priv->pollable_fd.overlapped; + + iso_ctx_size = sizeof(KISO_CONTEXT) + (transfer->num_iso_packets * sizeof(KISO_PACKET)); + transfer_priv->iso_context = iso_context = calloc(1, iso_ctx_size); + if (transfer_priv->iso_context == NULL) + return LIBUSB_ERROR_NO_MEM; + + // start ASAP + iso_context->StartFrame = 0; + iso_context->NumberOfPackets = (SHORT)transfer->num_iso_packets; + + // convert the transfer packet lengths to iso_packet offsets + offset = 0; + for (i = 0; i < transfer->num_iso_packets; i++) { + iso_context->IsoPackets[i].offset = offset; + offset += transfer->iso_packet_desc[i].length; + } + + if (IS_XFERIN(transfer)) { + usbi_dbg("reading %d iso packets", transfer->num_iso_packets); + ret = WinUSBX[sub_api].IsoReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context); + } else { + usbi_dbg("writing %d iso packets", transfer->num_iso_packets); + ret = WinUSBX[sub_api].IsoWritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context); + } + + if (!ret) { + if (GetLastError() != ERROR_IO_PENDING) { + usbi_err(ctx, "IsoReadPipe/IsoWritePipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + } else { + windows_force_sync_completion(overlapped, (ULONG)transfer->length); + } + + transfer_priv->interface_number = (uint8_t)current_interface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + HANDLE winusb_handle; + OVERLAPPED *overlapped; + bool ret; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface); + + transfer_priv->handle = winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + overlapped = transfer_priv->pollable_fd.overlapped; + + if (IS_XFERIN(transfer)) { + usbi_dbg("reading %d bytes", transfer->length); + ret = WinUSBX[sub_api].ReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped); + } else { + usbi_dbg("writing %d bytes", transfer->length); + ret = WinUSBX[sub_api].WritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped); + } + + if (!ret) { + if (GetLastError() != ERROR_IO_PENDING) { + usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_IO; + } + } else { + windows_force_sync_completion(overlapped, (ULONG)transfer->length); + } + + transfer_priv->interface_number = (uint8_t)current_interface; + + return LIBUSB_SUCCESS; +} + +static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + current_interface = interface_by_endpoint(priv, handle_priv, endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface); + winusb_handle = handle_priv->interface_handle[current_interface].api_handle; + + if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) { + usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +/* + * from http://www.winvistatips.com/winusb-bugchecks-t335323.html (confirmed + * through testing as well): + * "You can not call WinUsb_AbortPipe on control pipe. You can possibly cancel + * the control transfer using CancelIo" + */ +static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer) +{ + // Cancelling of the I/O is done in the parent + return LIBUSB_SUCCESS; +} + +static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + HANDLE handle; + int current_interface; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + current_interface = transfer_priv->interface_number; + if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) { + usbi_err(ctx, "program assertion failed: invalid interface_number"); + return LIBUSB_ERROR_NOT_FOUND; + } + usbi_dbg("will use interface %d", current_interface); + + if (WinUSBX[sub_api].CancelIoEx_supported) { + // Try to use CancelIoEx if available to cancel just a single transfer + handle = handle_priv->interface_handle[current_interface].dev_handle; + if (pCancelIoEx(handle, transfer_priv->pollable_fd.overlapped)) + return LIBUSB_SUCCESS; + else if (GetLastError() == ERROR_NOT_FOUND) + return LIBUSB_ERROR_NOT_FOUND; + + // Not every driver implements the necessary functionality for CancelIoEx + usbi_warn(ctx, "CancelIoEx not supported for sub API %s", winusbx_driver_names[sub_api]); + WinUSBX[sub_api].CancelIoEx_supported = false; + } + + handle = handle_priv->interface_handle[current_interface].api_handle; + if (!WinUSBX[sub_api].AbortPipe(handle, transfer->endpoint)) { + usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); + return LIBUSB_ERROR_NO_DEVICE; + } + + return LIBUSB_SUCCESS; +} + +/* + * from the "How to Use WinUSB to Communicate with a USB Device" Microsoft white paper + * (http://www.microsoft.com/whdc/connect/usb/winusb_howto.mspx): + * "WinUSB does not support host-initiated reset port and cycle port operations" and + * IOCTL_INTERNAL_USB_CYCLE_PORT is only available in kernel mode and the + * IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is + * cycle the pipes (and even then, the control pipe can not be reset using WinUSB) + */ +// TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?) +static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + HANDLE winusb_handle; + int i, j; + + CHECK_WINUSBX_AVAILABLE(sub_api); + + // Reset any available pipe (except control) + for (i = 0; i < USB_MAXINTERFACES; i++) { + winusb_handle = handle_priv->interface_handle[i].api_handle; + if (HANDLE_VALID(winusb_handle)) { + for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) { + usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]); + if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) + usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + + // FlushPipe seems to fail on OUT pipes + if (IS_EPIN(priv->usb_interface[i].endpoint[j]) + && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))) + usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + + if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) + usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s", + priv->usb_interface[i].endpoint[j], windows_error_str(0)); + } + } + } + + // libusbK & libusb0 have the ability to issue an actual device reset + if (WinUSBX[sub_api].ResetDevice != NULL) { + winusb_handle = handle_priv->interface_handle[0].api_handle; + if (HANDLE_VALID(winusb_handle)) + WinUSBX[sub_api].ResetDevice(winusb_handle); + } + + return LIBUSB_SUCCESS; +} + +static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + PKISO_CONTEXT iso_context; + int i; + + if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { + CHECK_WINUSBX_AVAILABLE(sub_api); + + // for isochronous, need to copy the individual iso packet actual_lengths and statuses + if ((sub_api == SUB_API_LIBUSBK) || (sub_api == SUB_API_LIBUSB0)) { + // iso only supported on libusbk-based backends for now + iso_context = transfer_priv->iso_context; + for (i = 0; i < transfer->num_iso_packets; i++) { + transfer->iso_packet_desc[i].actual_length = iso_context->IsoPackets[i].actual_length; + // TODO translate USDB_STATUS codes http://msdn.microsoft.com/en-us/library/ff539136(VS.85).aspx to libusb_transfer_status + //transfer->iso_packet_desc[i].status = transfer_priv->iso_context->IsoPackets[i].status; + } + } else { + // This should only occur if backend is not set correctly or other backend isoc is partially implemented + PRINT_UNSUPPORTED_API(copy_transfer_data); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + } + + itransfer->transferred += io_size; + return LIBUSB_TRANSFER_COMPLETED; +} + +/* + * Composite API functions + */ +static int composite_open(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int r = LIBUSB_ERROR_NOT_FOUND; + uint8_t i; + // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID + bool available[SUB_API_MAX + 1] = { 0 }; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + switch (priv->usb_interface[i].apib->id) { + case USB_API_WINUSBX: + if (priv->usb_interface[i].sub_api != SUB_API_NOTSET) { + available[priv->usb_interface[i].sub_api] = true; + } + break; + case USB_API_HID: + available[SUB_API_MAX] = true; + break; + default: + break; + } + } + + for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers + if (available[i]) { + r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle); + if (r != LIBUSB_SUCCESS) { + return r; + } + } + } +/* + if (available[SUB_API_MAX]) // HID driver + r = hid_open(SUB_API_NOTSET, dev_handle); +*/ + return r; +} + +static void composite_close(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + uint8_t i; + // SUB_API_MAX + 1 as the SUB_API_MAX pos is used to indicate availability of HID + bool available[SUB_API_MAX + 1] = { 0 }; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + switch (priv->usb_interface[i].apib->id) { + case USB_API_WINUSBX: + if (priv->usb_interface[i].sub_api != SUB_API_NOTSET) + available[priv->usb_interface[i].sub_api] = true; + break; + case USB_API_HID: + available[SUB_API_MAX] = true; + break; + default: + break; + } + } + + for (i = 0; i < SUB_API_MAX; i++) { // WinUSB-like drivers + if (available[i]) + usb_api_backend[USB_API_WINUSBX].close(i, dev_handle); + } +/* + if (available[SUB_API_MAX]) // HID driver + hid_close(SUB_API_NOTSET, dev_handle); +*/ +} + +static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, claim_interface); + + return priv->usb_interface[iface].apib-> + claim_interface(priv->usb_interface[iface].sub_api, dev_handle, iface); +} + +static int composite_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, set_interface_altsetting); + + return priv->usb_interface[iface].apib-> + set_interface_altsetting(priv->usb_interface[iface].sub_api, dev_handle, iface, altsetting); +} + +static int composite_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + CHECK_SUPPORTED_API(priv->usb_interface[iface].apib, release_interface); + + return priv->usb_interface[iface].apib-> + release_interface(priv->usb_interface[iface].sub_api, dev_handle, iface); +} + +static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + struct libusb_config_descriptor *conf_desc; + WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *)transfer->buffer; + int iface, pass, r; + + // Interface shouldn't matter for control, but it does in practice, with Windows' + // restrictions with regards to accessing HID keyboards and mice. Try to target + // a specific interface first, if possible. + switch (LIBUSB_REQ_RECIPIENT(setup->RequestType)) { + case LIBUSB_RECIPIENT_INTERFACE: + iface = setup->Index & 0xFF; + break; + case LIBUSB_RECIPIENT_ENDPOINT: + r = libusb_get_active_config_descriptor(transfer->dev_handle->dev, &conf_desc); + if (r == LIBUSB_SUCCESS) { + iface = get_interface_by_endpoint(conf_desc, (setup->Index & 0xFF)); + libusb_free_config_descriptor(conf_desc); + break; + } + // Fall through if not able to determine interface + default: + iface = -1; + break; + } + + // Try and target a specific interface if the control setup indicates such + if ((iface >= 0) && (iface < USB_MAXINTERFACES)) { + usbi_dbg("attempting control transfer targeted to interface %d", iface); + if ((priv->usb_interface[iface].path != NULL) + && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) { + r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer); + if (r == LIBUSB_SUCCESS) + return r; + } + } + + // Either not targeted to a specific interface or no luck in doing so. + // Try a 2 pass approach with all interfaces. + for (pass = 0; pass < 2; pass++) { + for (iface = 0; iface < USB_MAXINTERFACES; iface++) { + if ((priv->usb_interface[iface].path != NULL) + && (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) { + if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) { + usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface); + continue; + } + usbi_dbg("using interface %d", iface); + r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer); + // If not supported on this API, it may be supported on another, so don't give up yet!! + if (r == LIBUSB_ERROR_NOT_SUPPORTED) + continue; + return r; + } + } + } + usbi_err(ctx, "no libusb supported interfaces to complete request"); + return LIBUSB_ERROR_NOT_FOUND; +} + +static int composite_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_bulk_transfer); + + return priv->usb_interface[current_interface].apib-> + submit_bulk_transfer(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer) { + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); + return LIBUSB_ERROR_NOT_FOUND; + } + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, submit_iso_transfer); + + return priv->usb_interface[current_interface].apib-> + submit_iso_transfer(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) +{ + struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int current_interface; + + current_interface = interface_by_endpoint(priv, handle_priv, endpoint); + if (current_interface < 0) { + usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); + return LIBUSB_ERROR_NOT_FOUND; + } + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, clear_halt); + + return priv->usb_interface[current_interface].apib-> + clear_halt(priv->usb_interface[current_interface].sub_api, dev_handle, endpoint); +} + +static int composite_abort_control(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface = transfer_priv->interface_number; + + if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) { + usbi_err(TRANSFER_CTX(transfer), "program assertion failed: invalid interface_number"); + return LIBUSB_ERROR_NOT_FOUND; + } + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, abort_control); + + return priv->usb_interface[current_interface].apib-> + abort_control(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_abort_transfers(int sub_api, struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface = transfer_priv->interface_number; + + if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) { + usbi_err(TRANSFER_CTX(transfer), "program assertion failed: invalid interface_number"); + return LIBUSB_ERROR_NOT_FOUND; + } + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, abort_transfers); + + return priv->usb_interface[current_interface].apib-> + abort_transfers(priv->usb_interface[current_interface].sub_api, itransfer); +} + +static int composite_reset_device(int sub_api, struct libusb_device_handle *dev_handle) +{ + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + int r; + uint8_t i; + bool available[SUB_API_MAX]; + + for (i = 0; i < SUB_API_MAX; i++) + available[i] = false; + + for (i = 0; i < USB_MAXINTERFACES; i++) { + if ((priv->usb_interface[i].apib->id == USB_API_WINUSBX) + && (priv->usb_interface[i].sub_api != SUB_API_NOTSET)) + available[priv->usb_interface[i].sub_api] = true; + } + + for (i = 0; i < SUB_API_MAX; i++) { + if (available[i]) { + r = usb_api_backend[USB_API_WINUSBX].reset_device(i, dev_handle); + if (r != LIBUSB_SUCCESS) + return r; + } + } + + return LIBUSB_SUCCESS; +} + +static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) +{ + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct winusb_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); + struct winusb_device_priv *priv = _device_priv(transfer->dev_handle->dev); + int current_interface = transfer_priv->interface_number; + + CHECK_SUPPORTED_API(priv->usb_interface[current_interface].apib, copy_transfer_data); + + return priv->usb_interface[current_interface].apib-> + copy_transfer_data(priv->usb_interface[current_interface].sub_api, itransfer, io_size); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.h b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.h new file mode 100644 index 00000000..c1ad4eb9 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/os/windows_winusb.h @@ -0,0 +1,680 @@ +/* + * Windows backend for libusb 1.0 + * Copyright © 2009-2012 Pete Batard + * With contributions from Michael Plante, Orin Eman et al. + * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "windows_common.h" +#include "windows_nt_common.h" + +#if defined(_MSC_VER) +// disable /W4 MSVC warnings that are benign +#pragma warning(disable:4100) // unreferenced formal parameter +#pragma warning(disable:4127) // conditional expression is constant +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int +#pragma warning(disable:4996) // deprecated API calls +#pragma warning(disable:28159) // more deprecated API calls +#endif + +// Missing from MSVC6 setupapi.h +#ifndef SPDRP_ADDRESS +#define SPDRP_ADDRESS 28 +#endif +#ifndef SPDRP_INSTALL_STATE +#define SPDRP_INSTALL_STATE 34 +#endif + +#define MAX_CTRL_BUFFER_LENGTH 4096 +#define MAX_USB_STRING_LENGTH 128 +#define MAX_HID_REPORT_SIZE 1024 +#define MAX_HID_DESCRIPTOR_SIZE 256 +#define MAX_GUID_STRING_LENGTH 40 +#define MAX_PATH_LENGTH 128 +#define MAX_KEY_LENGTH 256 +#define LIST_SEPARATOR ';' + +// Handle code for HID interface that have been claimed ("dibs") +#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5) +// Additional return code for HID operations that completed synchronously +#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1) + +// http://msdn.microsoft.com/en-us/library/ff545978.aspx +// http://msdn.microsoft.com/en-us/library/ff545972.aspx +// http://msdn.microsoft.com/en-us/library/ff545982.aspx +#ifndef GUID_DEVINTERFACE_USB_HOST_CONTROLLER +const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = {0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27}}; +#endif +#ifndef GUID_DEVINTERFACE_USB_DEVICE +const GUID GUID_DEVINTERFACE_USB_DEVICE = {0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}}; +#endif +#ifndef GUID_DEVINTERFACE_USB_HUB +const GUID GUID_DEVINTERFACE_USB_HUB = {0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8}}; +#endif +#ifndef GUID_DEVINTERFACE_LIBUSB0_FILTER +const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = {0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9}}; +#endif + + +/* + * Multiple USB API backend support + */ +#define USB_API_UNSUPPORTED 0 +#define USB_API_HUB 1 +#define USB_API_COMPOSITE 2 +#define USB_API_WINUSBX 3 +#define USB_API_HID 4 +#define USB_API_MAX 5 + +// Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL) +// Must have the same values as the KUSB_DRVID enum from libusbk.h +#define SUB_API_NOTSET -1 +#define SUB_API_LIBUSBK 0 +#define SUB_API_LIBUSB0 1 +#define SUB_API_WINUSB 2 +#define SUB_API_MAX 3 + +struct windows_usb_api_backend { + const uint8_t id; + const char * const designation; + const char * const * const driver_name_list; // Driver name, without .sys, e.g. "usbccgp" + const uint8_t nb_driver_names; + int (*init)(struct libusb_context *ctx); + void (*exit)(void); + int (*open)(int sub_api, struct libusb_device_handle *dev_handle); + void (*close)(int sub_api, struct libusb_device_handle *dev_handle); + int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); + int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface); + int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); + int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle); + int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer); + int (*abort_control)(int sub_api, struct usbi_transfer *itransfer); + int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer); + int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); +}; + +extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX]; + +#define PRINT_UNSUPPORTED_API(fname) \ + usbi_dbg("unsupported API call for '%s' " \ + "(unrecognized device driver)", #fname) + +#define CHECK_SUPPORTED_API(apip, fname) \ + do { \ + if ((apip)->fname == NULL) { \ + PRINT_UNSUPPORTED_API(fname); \ + return LIBUSB_ERROR_NOT_SUPPORTED; \ + } \ + } while (0) + +/* + * private structures definition + * with inline pseudo constructors/destructors + */ + +// TODO (v2+): move hid desc to libusb.h? +struct libusb_hid_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + uint8_t bClassDescriptorType; + uint16_t wClassDescriptorLength; +}; + +#define LIBUSB_DT_HID_SIZE 9 +#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \ + + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE) +#define HID_MAX_REPORT_SIZE 1024 +#define HID_IN_EP 0x81 +#define HID_OUT_EP 0x02 +#define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F) +#define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5)) +#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN) +#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type)) + +#ifndef CTL_CODE +#define CTL_CODE(DeviceType, Function, Method, Access) \ + (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) +#endif + +// The following are used for HID reports IOCTLs +#define HID_IN_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define HID_OUT_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) +#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104) +#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100) +#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101) + +enum libusb_hid_request_type { + HID_REQ_GET_REPORT = 0x01, + HID_REQ_GET_IDLE = 0x02, + HID_REQ_GET_PROTOCOL = 0x03, + HID_REQ_SET_REPORT = 0x09, + HID_REQ_SET_IDLE = 0x0A, + HID_REQ_SET_PROTOCOL = 0x0B +}; + +enum libusb_hid_report_type { + HID_REPORT_TYPE_INPUT = 0x01, + HID_REPORT_TYPE_OUTPUT = 0x02, + HID_REPORT_TYPE_FEATURE = 0x03 +}; + +struct hid_device_priv { + uint16_t vid; + uint16_t pid; + uint8_t config; + uint8_t nb_interfaces; + bool uses_report_ids[3]; // input, ouptput, feature + uint16_t input_report_size; + uint16_t output_report_size; + uint16_t feature_report_size; + uint16_t usage; + uint16_t usagePage; + WCHAR string[3][MAX_USB_STRING_LENGTH]; + uint8_t string_index[3]; // man, prod, ser +}; + +static inline struct winusb_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct winusb_device_priv *)dev->os_priv; +} + +static inline struct winusb_device_priv *winusb_device_priv_init(struct libusb_device *dev) +{ + struct winusb_device_priv *p = _device_priv(dev); + int i; + + p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; + p->sub_api = SUB_API_NOTSET; + for (i = 0; i < USB_MAXINTERFACES; i++) { + p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED]; + p->usb_interface[i].sub_api = SUB_API_NOTSET; + } + + return p; +} + +static inline void winusb_device_priv_release(struct libusb_device *dev) +{ + struct winusb_device_priv *p = _device_priv(dev); + int i; + + free(p->dev_id); + free(p->path); + if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) { + for (i = 0; i < dev->num_configurations; i++) + free(p->config_descriptor[i]); + } + free(p->config_descriptor); + free(p->hid); + for (i = 0; i < USB_MAXINTERFACES; i++) { + free(p->usb_interface[i].path); + free(p->usb_interface[i].endpoint); + } +} + +static inline struct winusb_device_handle_priv *_device_handle_priv( + struct libusb_device_handle *handle) +{ + return (struct winusb_device_handle_priv *)handle->os_priv; +} + +// used to match a device driver (including filter drivers) against a supported API +struct driver_lookup { + char list[MAX_KEY_LENGTH + 1]; // REG_MULTI_SZ list of services (driver) names + const DWORD reg_prop; // SPDRP registry key to use to retrieve list + const char* designation; // internal designation (for debug output) +}; + +/* + * Windows DDK API definitions. Most of it copied from MinGW's includes + */ +typedef DWORD DEVNODE, DEVINST; +typedef DEVNODE *PDEVNODE, *PDEVINST; +typedef DWORD RETURN_TYPE; +typedef RETURN_TYPE CONFIGRET; + +#define CR_SUCCESS 0x00000000 + +/* Cfgmgr32 dependencies */ +DLL_DECLARE_HANDLE(Cfgmgr32); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG)); +DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG)); + +/* AdvAPI32 dependencies */ +DLL_DECLARE_HANDLE(AdvAPI32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY)); + +/* OLE32 dependency */ +DLL_DECLARE_HANDLE(OLE32); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID)); + +/* SetupAPI dependencies */ +DLL_DECLARE_HANDLE(SetupAPI); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA, + LPCGUID, DWORD, PSP_DEVICE_INTERFACE_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInstanceIdA, (HDEVINFO, PSP_DEVINFO_DATA, + PCSTR, DWORD, PDWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, + PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO, + PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM)); +DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD)); + + +#ifndef USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION +#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260 +#endif +#ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX +#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274 +#endif +#ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 +#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279 +#endif + +#ifndef FILE_DEVICE_USB +#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN +#endif + +#define USB_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_USB, (id), METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \ + USB_CTL_CODE(USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION) + +#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \ + USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX) + +#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \ + USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2) + +typedef enum USB_CONNECTION_STATUS { + NoDeviceConnected, + DeviceConnected, + DeviceFailedEnumeration, + DeviceGeneralFailure, + DeviceCausedOvercurrent, + DeviceNotEnoughPower, + DeviceNotEnoughBandwidth, + DeviceHubNestedTooDeeply, + DeviceInLegacyHub +} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS; + +typedef enum USB_HUB_NODE { + UsbHub, + UsbMIParent +} USB_HUB_NODE; + +// Most of the structures below need to be packed +#include + +typedef struct _USB_DESCRIPTOR_REQUEST { + ULONG ConnectionIndex; + struct { + UCHAR bmRequest; + UCHAR bRequest; + USHORT wValue; + USHORT wIndex; + USHORT wLength; + } SetupPacket; +// UCHAR Data[0]; +} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST; + +typedef struct _USB_CONFIGURATION_DESCRIPTOR_SHORT { + USB_DESCRIPTOR_REQUEST req; + USB_CONFIGURATION_DESCRIPTOR desc; +} USB_CONFIGURATION_DESCRIPTOR_SHORT; + +typedef struct USB_INTERFACE_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bInterfaceNumber; + UCHAR bAlternateSetting; + UCHAR bNumEndpoints; + UCHAR bInterfaceClass; + UCHAR bInterfaceSubClass; + UCHAR bInterfaceProtocol; + UCHAR iInterface; +} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; + +typedef struct _USB_NODE_CONNECTION_INFORMATION_EX { + ULONG ConnectionIndex; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; + UCHAR CurrentConfigurationValue; + UCHAR Speed; + BOOLEAN DeviceIsHub; + USHORT DeviceAddress; + ULONG NumberOfOpenPipes; + USB_CONNECTION_STATUS ConnectionStatus; +// USB_PIPE_INFO PipeList[0]; +} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX; + +typedef union _USB_PROTOCOLS { + ULONG ul; + struct { + ULONG Usb110:1; + ULONG Usb200:1; + ULONG Usb300:1; + ULONG ReservedMBZ:29; + }; +} USB_PROTOCOLS, *PUSB_PROTOCOLS; + +typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS { + ULONG ul; + struct { + ULONG DeviceIsOperatingAtSuperSpeedOrHigher:1; + ULONG DeviceIsSuperSpeedCapableOrHigher:1; + ULONG ReservedMBZ:30; + }; +} USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS; + +typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 { + ULONG ConnectionIndex; + ULONG Length; + USB_PROTOCOLS SupportedUsbProtocols; + USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags; +} USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2; + +#include + +/* winusb.dll interface */ + +#define SHORT_PACKET_TERMINATE 0x01 +#define AUTO_CLEAR_STALL 0x02 +#define PIPE_TRANSFER_TIMEOUT 0x03 +#define IGNORE_SHORT_PACKETS 0x04 +#define ALLOW_PARTIAL_READS 0x05 +#define AUTO_FLUSH 0x06 +#define RAW_IO 0x07 +#define MAXIMUM_TRANSFER_SIZE 0x08 + +typedef enum _USBD_PIPE_TYPE { + UsbdPipeTypeControl, + UsbdPipeTypeIsochronous, + UsbdPipeTypeBulk, + UsbdPipeTypeInterrupt +} USBD_PIPE_TYPE; + +#include + +typedef struct _WINUSB_SETUP_PACKET { + UCHAR RequestType; + UCHAR Request; + USHORT Value; + USHORT Index; + USHORT Length; +} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET; + +#include + +typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; + +typedef BOOL (WINAPI *WinUsb_AbortPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + WINUSB_SETUP_PACKET SetupPacket, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); +typedef BOOL (WINAPI *WinUsb_FlushPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_Free_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AssociatedInterfaceIndex, + PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_Initialize_t)( + HANDLE DeviceHandle, + PWINUSB_INTERFACE_HANDLE InterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_ReadPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); +typedef BOOL (WINAPI *WinUsb_ResetDevice_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle +); +typedef BOOL (WINAPI *WinUsb_ResetPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID +); +typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR AlternateSetting +); +typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + ULONG PolicyType, + ULONG ValueLength, + PVOID Value +); +typedef BOOL (WINAPI *WinUsb_WritePipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + PULONG LengthTransferred, + LPOVERLAPPED Overlapped +); + +/* /!\ These must match the ones from the official libusbk.h */ +typedef enum _KUSB_FNID { + KUSB_FNID_Init, + KUSB_FNID_Free, + KUSB_FNID_ClaimInterface, + KUSB_FNID_ReleaseInterface, + KUSB_FNID_SetAltInterface, + KUSB_FNID_GetAltInterface, + KUSB_FNID_GetDescriptor, + KUSB_FNID_ControlTransfer, + KUSB_FNID_SetPowerPolicy, + KUSB_FNID_GetPowerPolicy, + KUSB_FNID_SetConfiguration, + KUSB_FNID_GetConfiguration, + KUSB_FNID_ResetDevice, + KUSB_FNID_Initialize, + KUSB_FNID_SelectInterface, + KUSB_FNID_GetAssociatedInterface, + KUSB_FNID_Clone, + KUSB_FNID_QueryInterfaceSettings, + KUSB_FNID_QueryDeviceInformation, + KUSB_FNID_SetCurrentAlternateSetting, + KUSB_FNID_GetCurrentAlternateSetting, + KUSB_FNID_QueryPipe, + KUSB_FNID_SetPipePolicy, + KUSB_FNID_GetPipePolicy, + KUSB_FNID_ReadPipe, + KUSB_FNID_WritePipe, + KUSB_FNID_ResetPipe, + KUSB_FNID_AbortPipe, + KUSB_FNID_FlushPipe, + KUSB_FNID_IsoReadPipe, + KUSB_FNID_IsoWritePipe, + KUSB_FNID_GetCurrentFrameNumber, + KUSB_FNID_GetOverlappedResult, + KUSB_FNID_GetProperty, + KUSB_FNID_COUNT, +} KUSB_FNID; + +typedef struct _KLIB_VERSION { + INT Major; + INT Minor; + INT Micro; + INT Nano; +} KLIB_VERSION, *PKLIB_VERSION; + +typedef BOOL (WINAPI *LibK_GetProcAddress_t)( + PVOID *ProcAddress, + ULONG DriverID, + ULONG FunctionID +); + +typedef VOID (WINAPI *LibK_GetVersion_t)( + PKLIB_VERSION Version +); + +//KISO_PACKET is equivalent of libusb_iso_packet_descriptor except uses absolute "offset" field instead of sequential Lengths +typedef struct _KISO_PACKET { + UINT offset; + USHORT actual_length; //changed from libusbk_shared.h "Length" for clarity + USHORT status; +} KISO_PACKET, *PKISO_PACKET; + +typedef enum _KISO_FLAG { + KISO_FLAG_NONE = 0, + KISO_FLAG_SET_START_FRAME = 0x00000001, +} KISO_FLAG; + +//KISO_CONTEXT is the conceptual equivalent of libusb_transfer except is isochronous-specific and must match libusbk's version +typedef struct _KISO_CONTEXT { + KISO_FLAG Flags; + UINT StartFrame; + SHORT ErrorCount; + SHORT NumberOfPackets; + UINT UrbHdrStatus; + KISO_PACKET IsoPackets[0]; +} KISO_CONTEXT, *PKISO_CONTEXT; + +typedef BOOL(WINAPI *WinUsb_IsoReadPipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + LPOVERLAPPED Overlapped, + PKISO_CONTEXT IsoContext +); + +typedef BOOL(WINAPI *WinUsb_IsoWritePipe_t)( + WINUSB_INTERFACE_HANDLE InterfaceHandle, + UCHAR PipeID, + PUCHAR Buffer, + ULONG BufferLength, + LPOVERLAPPED Overlapped, + PKISO_CONTEXT IsoContext +); + +struct winusb_interface { + bool initialized; + bool CancelIoEx_supported; + WinUsb_AbortPipe_t AbortPipe; + WinUsb_ControlTransfer_t ControlTransfer; + WinUsb_FlushPipe_t FlushPipe; + WinUsb_Free_t Free; + WinUsb_GetAssociatedInterface_t GetAssociatedInterface; + WinUsb_Initialize_t Initialize; + WinUsb_ReadPipe_t ReadPipe; + WinUsb_ResetDevice_t ResetDevice; + WinUsb_ResetPipe_t ResetPipe; + WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting; + WinUsb_SetPipePolicy_t SetPipePolicy; + WinUsb_WritePipe_t WritePipe; + WinUsb_IsoReadPipe_t IsoReadPipe; + WinUsb_IsoWritePipe_t IsoWritePipe; +}; + +/* hid.dll interface */ + +#define HIDP_STATUS_SUCCESS 0x110000 +typedef void * PHIDP_PREPARSED_DATA; + +#include +#include + +typedef USHORT USAGE; + +typedef enum _HIDP_REPORT_TYPE { + HidP_Input, + HidP_Output, + HidP_Feature +} HIDP_REPORT_TYPE; + +typedef struct _HIDP_VALUE_CAPS { + USAGE UsagePage; + UCHAR ReportID; + BOOLEAN IsAlias; + USHORT BitField; + USHORT LinkCollection; + USAGE LinkUsage; + USAGE LinkUsagePage; + BOOLEAN IsRange; + BOOLEAN IsStringRange; + BOOLEAN IsDesignatorRange; + BOOLEAN IsAbsolute; + BOOLEAN HasNull; + UCHAR Reserved; + USHORT BitSize; + USHORT ReportCount; + USHORT Reserved2[5]; + ULONG UnitsExp; + ULONG Units; + LONG LogicalMin, LogicalMax; + LONG PhysicalMin, PhysicalMax; + union { + struct { + USAGE UsageMin, UsageMax; + USHORT StringMin, StringMax; + USHORT DesignatorMin, DesignatorMax; + USHORT DataIndexMin, DataIndexMax; + } Range; + struct { + USAGE Usage, Reserved1; + USHORT StringIndex, Reserved2; + USHORT DesignatorIndex, Reserved3; + USHORT DataIndex, Reserved4; + } NotRange; + } u; +} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS; + +DLL_DECLARE_HANDLE(hid); +DLL_DECLARE_FUNC(WINAPI, VOID, HidD_GetHidGuid, (LPGUID)); +DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG)); +DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FlushQueue, (HANDLE)); +DLL_DECLARE_FUNC(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA)); diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/strerror.c b/vendor/github.com/karalabe/usb/libusb/libusb/strerror.c new file mode 100644 index 00000000..d2be0e2a --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/strerror.c @@ -0,0 +1,202 @@ +/* + * libusb strerror code + * Copyright © 2013 Hans de Goede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#if defined(HAVE_STRINGS_H) +#include +#endif + +#include "libusbi.h" + +#if defined(_MSC_VER) +#define strncasecmp _strnicmp +#endif + +static size_t usbi_locale = 0; + +/** \ingroup libusb_misc + * How to add a new \ref libusb_strerror() translation: + *
    + *
  1. Download the latest \c strerror.c from:
    + * https://raw.github.com/libusb/libusb/master/libusb/sterror.c
  2. + *
  3. Open the file in an UTF-8 capable editor
  4. + *
  5. Add the 2 letter ISO 639-1 + * code for your locale at the end of \c usbi_locale_supported[]
    + * Eg. for Chinese, you would add "zh" so that: + * \code... usbi_locale_supported[] = { "en", "nl", "fr" };\endcode + * becomes: + * \code... usbi_locale_supported[] = { "en", "nl", "fr", "zh" };\endcode
  6. + *
  7. Copy the { / * English (en) * / ... } section and add it at the end of \c usbi_localized_errors
    + * Eg. for Chinese, the last section of \c usbi_localized_errors could look like: + * \code + * }, { / * Chinese (zh) * / + * "Success", + * ... + * "Other error", + * } + * };\endcode
  8. + *
  9. Translate each of the English messages from the section you copied into your language
  10. + *
  11. Save the file (in UTF-8 format) and send it to \c libusb-devel\@lists.sourceforge.net
  12. + *
+ */ + +static const char* usbi_locale_supported[] = { "en", "nl", "fr", "ru" }; +static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = { + { /* English (en) */ + "Success", + "Input/Output Error", + "Invalid parameter", + "Access denied (insufficient permissions)", + "No such device (it may have been disconnected)", + "Entity not found", + "Resource busy", + "Operation timed out", + "Overflow", + "Pipe error", + "System call interrupted (perhaps due to signal)", + "Insufficient memory", + "Operation not supported or unimplemented on this platform", + "Other error", + }, { /* Dutch (nl) */ + "Gelukt", + "Invoer-/uitvoerfout", + "Ongeldig argument", + "Toegang geweigerd (onvoldoende toegangsrechten)", + "Apparaat bestaat niet (verbinding met apparaat verbroken?)", + "Niet gevonden", + "Apparaat of hulpbron is bezig", + "Bewerking verlopen", + "Waarde is te groot", + "Gebroken pijp", + "Onderbroken systeemaanroep", + "Onvoldoende geheugen beschikbaar", + "Bewerking wordt niet ondersteund", + "Andere fout", + }, { /* French (fr) */ + "Succès", + "Erreur d'entrée/sortie", + "Paramètre invalide", + "Accès refusé (permissions insuffisantes)", + "Périphérique introuvable (peut-être déconnecté)", + "Elément introuvable", + "Resource déjà occupée", + "Operation expirée", + "Débordement", + "Erreur de pipe", + "Appel système abandonné (peut-être à cause d’un signal)", + "Mémoire insuffisante", + "Opération non supportée or non implémentée sur cette plateforme", + "Autre erreur", + }, { /* Russian (ru) */ + "Успех", + "Ошибка ввода/вывода", + "Неверный параметр", + "Доступ запрещён (не хватает прав)", + "Устройство отсутствует (возможно, оно было отсоединено)", + "Элемент не найден", + "Ресурс занят", + "Истекло время ожидания операции", + "Переполнение", + "Ошибка канала", + "Системный вызов прерван (возможно, сигналом)", + "Память исчерпана", + "Операция не поддерживается данной платформой", + "Неизвестная ошибка" + } +}; + +/** \ingroup libusb_misc + * Set the language, and only the language, not the encoding! used for + * translatable libusb messages. + * + * This takes a locale string in the default setlocale format: lang[-region] + * or lang[_country_region][.codeset]. Only the lang part of the string is + * used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de". + * The optional region, country_region or codeset parts are ignored. This + * means that functions which return translatable strings will NOT honor the + * specified encoding. + * All strings returned are encoded as UTF-8 strings. + * + * If libusb_setlocale() is not called, all messages will be in English. + * + * The following functions return translatable strings: libusb_strerror(). + * Note that the libusb log messages controlled through libusb_set_debug() + * are not translated, they are always in English. + * + * For POSIX UTF-8 environments if you want libusb to follow the standard + * locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)), + * after your app has done its locale setup. + * + * \param locale locale-string in the form of lang[_country_region][.codeset] + * or lang[-region], where lang is a 2 letter ISO 639-1 code + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_INVALID_PARAM if the locale doesn't meet the requirements + * \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported + * \returns a LIBUSB_ERROR code on other errors + */ + +int API_EXPORTED libusb_setlocale(const char *locale) +{ + size_t i; + + if ( (locale == NULL) || (strlen(locale) < 2) + || ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) ) + return LIBUSB_ERROR_INVALID_PARAM; + + for (i=0; i= ARRAYSIZE(usbi_locale_supported)) { + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_locale = i; + + return LIBUSB_SUCCESS; +} + +/** \ingroup libusb_misc + * Returns a constant string with a short description of the given error code, + * this description is intended for displaying to the end user and will be in + * the language set by libusb_setlocale(). + * + * The returned string is encoded in UTF-8. + * + * The messages always start with a capital letter and end without any dot. + * The caller must not free() the returned string. + * + * \param errcode the error code whose description is desired + * \returns a short description of the error code in UTF-8 encoding + */ +DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error errcode) +{ + int errcode_index = -errcode; + + if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) { + /* "Other Error", which should always be our last message, is returned */ + errcode_index = LIBUSB_ERROR_COUNT - 1; + } + + return usbi_localized_errors[usbi_locale][errcode_index]; +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/sync.c b/vendor/github.com/karalabe/usb/libusb/libusb/sync.c new file mode 100644 index 00000000..a609f65f --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/sync.c @@ -0,0 +1,327 @@ +/* + * Synchronous I/O functions for libusb + * Copyright © 2007-2008 Daniel Drake + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +/** + * @defgroup libusb_syncio Synchronous device I/O + * + * This page documents libusb's synchronous (blocking) API for USB device I/O. + * This interface is easy to use but has some limitations. More advanced users + * may wish to consider using the \ref libusb_asyncio "asynchronous I/O API" instead. + */ + +static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; + usbi_dbg("actual_length=%d", transfer->actual_length); + /* caller interprets result and frees transfer */ +} + +static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) +{ + int r, *completed = transfer->user_data; + struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle); + + while (!*completed) { + r = libusb_handle_events_completed(ctx, completed); + if (r < 0) { + if (r == LIBUSB_ERROR_INTERRUPTED) + continue; + usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying", + libusb_error_name(r)); + libusb_cancel_transfer(transfer); + continue; + } + } +} + +/** \ingroup libusb_syncio + * Perform a USB control transfer. + * + * The direction of the transfer is inferred from the bmRequestType field of + * the setup packet. + * + * The wValue, wIndex and wLength fields values should be given in host-endian + * byte order. + * + * \param dev_handle a handle for the device to communicate with + * \param bmRequestType the request type field for the setup packet + * \param bRequest the request field for the setup packet + * \param wValue the value field for the setup packet + * \param wIndex the index field for the setup packet + * \param data a suitably-sized data buffer for either input or output + * (depending on direction bits within bmRequestType) + * \param wLength the length field for the setup packet. The data buffer should + * be at least this size. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * \returns on success, the number of bytes actually transferred + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the + * device + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than + * the operating system and/or hardware can support + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout) +{ + struct libusb_transfer *transfer; + unsigned char *buffer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength); + if (!buffer) { + libusb_free_transfer(transfer); + return LIBUSB_ERROR_NO_MEM; + } + + libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, + wLength); + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) + memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); + + libusb_fill_control_transfer(transfer, dev_handle, buffer, + sync_transfer_cb, &completed, timeout); + transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) + memcpy(data, libusb_control_transfer_get_data(transfer), + transfer->actual_length); + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = transfer->actual_length; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + int *transferred, unsigned int timeout, unsigned char type) +{ + struct libusb_transfer *transfer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, + sync_transfer_cb, &completed, timeout); + transfer->type = type; + + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + if (transferred) + *transferred = transfer->actual_length; + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = 0; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +/** \ingroup libusb_syncio + * Perform a USB bulk transfer. The direction of the transfer is inferred from + * the direction bits of the endpoint address. + * + * For bulk reads, the length field indicates the maximum length of + * data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for bulk writes. + * Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), + * it is legal to pass a NULL pointer if you do not wish to receive this + * information. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates + * transferred) + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref libusb_packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, int *transferred, + unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); +} + +/** \ingroup libusb_syncio + * Perform a USB interrupt transfer. The direction of the transfer is inferred + * from the direction bits of the endpoint address. + * + * For interrupt reads, the length field indicates the maximum length + * of data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for interrupt + * writes. Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * The default endpoint bInterval value is used as the polling interval. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), + * it is legal to pass a NULL pointer if you do not wish to receive this + * information. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref libusb_packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other error + */ +int API_EXPORTED libusb_interrupt_transfer( + struct libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *data, int length, int *transferred, unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); +} diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/version.h b/vendor/github.com/karalabe/usb/libusb/libusb/version.h new file mode 100644 index 00000000..c6dfe370 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/version.h @@ -0,0 +1,18 @@ +/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */ +#include "version_nano.h" +#ifndef LIBUSB_MAJOR +#define LIBUSB_MAJOR 1 +#endif +#ifndef LIBUSB_MINOR +#define LIBUSB_MINOR 0 +#endif +#ifndef LIBUSB_MICRO +#define LIBUSB_MICRO 22 +#endif +#ifndef LIBUSB_NANO +#define LIBUSB_NANO 0 +#endif +/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */ +#ifndef LIBUSB_RC +#define LIBUSB_RC "" +#endif diff --git a/vendor/github.com/karalabe/usb/libusb/libusb/version_nano.h b/vendor/github.com/karalabe/usb/libusb/libusb/version_nano.h new file mode 100644 index 00000000..90a782a6 --- /dev/null +++ b/vendor/github.com/karalabe/usb/libusb/libusb/version_nano.h @@ -0,0 +1 @@ +#define LIBUSB_NANO 11312 diff --git a/vendor/github.com/karalabe/usb/raw_disabled.go b/vendor/github.com/karalabe/usb/raw_disabled.go new file mode 100644 index 00000000..a05ef8eb --- /dev/null +++ b/vendor/github.com/karalabe/usb/raw_disabled.go @@ -0,0 +1,42 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2017 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build !freebsd,!linux,!darwin,!windows ios !cgo + +package usb + +// RawDevice is a live raw USB connected device handle. On platforms that this file +// implements, the type lacks the actual USB device and all methods are noop. +type RawDevice struct { + DeviceInfo // Embed the infos for easier access +} + +// Close releases the USB device handle. On platforms that this file implements, +// the method is just a noop. +func (dev *RawDevice) Close() error { + return ErrUnsupportedPlatform +} + +// Write sends a binary blob to a USB device. On platforms that this file +// implements, the method just returns an error. +func (dev *RawDevice) Write(b []byte) (int, error) { + return 0, ErrUnsupportedPlatform +} + +// Read retrieves a binary blob from a USB device. On platforms that this file +// implements, the method just returns an error. +func (dev *RawDevice) Read(b []byte) (int, error) { + return 0, ErrUnsupportedPlatform +} diff --git a/vendor/github.com/karalabe/usb/raw_enabled.go b/vendor/github.com/karalabe/usb/raw_enabled.go new file mode 100644 index 00000000..326ac97a --- /dev/null +++ b/vendor/github.com/karalabe/usb/raw_enabled.go @@ -0,0 +1,253 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build freebsd,cgo linux,cgo darwin,!ios,cgo windows,cgo + +package usb + +/* + #include "./libusb/libusb/libusb.h" + + // ctx is a global libusb context to interact with devices through. + libusb_context* ctx; +*/ +import "C" + +import ( + "fmt" + "reflect" + "sync" + "unsafe" +) + +// enumerateRaw returns a list of all the USB devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all USB devices are returned. +func enumerateRaw(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + // Enumerate the devices, and free all the matching refcounts (we'll reopen any + // explicitly requested). + infos, err := enumerateRawWithRef(vendorID, productID) + for _, info := range infos { + C.libusb_unref_device(info.rawDevice.(*C.libusb_device)) + } + // If enumeration failed, don't return anything, otherwise everything + if err != nil { + return nil, err + } + return infos, nil +} + +// enumerateRawWithRef is the internal device enumerator that retains 1 reference +// to every matched device so they may selectively be opened on request. +func enumerateRawWithRef(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + // Ensure we have a libusb context to interact through. The enumerate call is + // protexted by a mutex outside, so it's fine to do the below check and init. + if C.ctx == nil { + if err := fromRawErrno(C.libusb_init((**C.libusb_context)(&C.ctx))); err != nil { + return nil, fmt.Errorf("failed to initialize libusb: %v", err) + } + } + // Retrieve all the available USB devices and wrap them in Go + var deviceList **C.libusb_device + count := C.libusb_get_device_list(C.ctx, &deviceList) + if count < 0 { + return nil, rawError(count) + } + defer C.libusb_free_device_list(deviceList, 1) + + var devices []*C.libusb_device + *(*reflect.SliceHeader)(unsafe.Pointer(&devices)) = reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(deviceList)), + Len: int(count), + Cap: int(count), + } + // + var infos []DeviceInfo + for devnum, dev := range devices { + // Retrieve the libusb device descriptor and skip non-queried ones + var desc C.struct_libusb_device_descriptor + if err := fromRawErrno(C.libusb_get_device_descriptor(dev, &desc)); err != nil { + return infos, fmt.Errorf("failed to get device %d descriptor: %v", devnum, err) + } + if (vendorID > 0 && uint16(desc.idVendor) != vendorID) || (productID > 0 && uint16(desc.idProduct) != productID) { + continue + } + // Skip HID devices, they are handled directly by OS libraries + if desc.bDeviceClass == C.LIBUSB_CLASS_HID { + continue + } + // Iterate over all the configurations and find raw interfaces + for cfgnum := 0; cfgnum < int(desc.bNumConfigurations); cfgnum++ { + // Retrieve the all the possible USB configurations of the device + var cfg *C.struct_libusb_config_descriptor + if err := fromRawErrno(C.libusb_get_config_descriptor(dev, C.uint8_t(cfgnum), &cfg)); err != nil { + return infos, fmt.Errorf("failed to get device %d config %d: %v", devnum, cfgnum, err) + } + var ifaces []C.struct_libusb_interface + *(*reflect.SliceHeader)(unsafe.Pointer(&ifaces)) = reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cfg._interface)), + Len: int(cfg.bNumInterfaces), + Cap: int(cfg.bNumInterfaces), + } + // Drill down into each advertised interface + for ifacenum, iface := range ifaces { + if iface.num_altsetting == 0 { + continue + } + var alts []C.struct_libusb_interface_descriptor + *(*reflect.SliceHeader)(unsafe.Pointer(&alts)) = reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(iface.altsetting)), + Len: int(iface.num_altsetting), + Cap: int(iface.num_altsetting), + } + for _, alt := range alts { + // Skip HID interfaces, they are handled directly by OS libraries + if alt.bInterfaceClass == C.LIBUSB_CLASS_HID { + continue + } + // Find the endpoints that can speak libusb interrupts + var ends []C.struct_libusb_endpoint_descriptor + *(*reflect.SliceHeader)(unsafe.Pointer(&ends)) = reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(alt.endpoint)), + Len: int(alt.bNumEndpoints), + Cap: int(alt.bNumEndpoints), + } + var reader, writer *uint8 + for _, end := range ends { + // Skip any non-interrupt endpoints + if end.bmAttributes != C.LIBUSB_TRANSFER_TYPE_INTERRUPT { + continue + } + if end.bEndpointAddress&C.LIBUSB_ENDPOINT_IN == C.LIBUSB_ENDPOINT_IN { + reader = new(uint8) + *reader = uint8(end.bEndpointAddress) + } else { + writer = new(uint8) + *writer = uint8(end.bEndpointAddress) + } + } + // If both in and out interrupts are available, match the device + if reader != nil && writer != nil { + // Enumeration matched, bump the device refcount to avoid cleaning it up + C.libusb_ref_device(dev) + + port := uint8(C.libusb_get_port_number(dev)) + infos = append(infos, DeviceInfo{ + Path: fmt.Sprintf("%04x:%04x:%02d", vendorID, uint16(desc.idProduct), port), + VendorID: uint16(desc.idVendor), + ProductID: uint16(desc.idProduct), + Interface: ifacenum, + rawDevice: dev, + rawPort: &port, + rawReader: reader, + rawWriter: writer, + }) + } + } + } + } + } + return infos, nil +} + +// openRaw connects to a low level libusb device by its path name. +func openRaw(info DeviceInfo) (*rawDevice, error) { + // Enumerate all the devices matching this particular info + matches, err := enumerateRawWithRef(info.VendorID, info.ProductID) + if err != nil { + // Enumeration failed, make sure any subresults are released + for _, match := range matches { + C.libusb_unref_device(match.rawDevice.(*C.libusb_device)) + } + return nil, err + } + // Find the specific endpoint we're interested in + var device *C.libusb_device + for _, match := range matches { + // Keep the matching device reference, release anything else + if device == nil && *match.rawPort == *info.rawPort && match.Interface == info.Interface { + device = match.rawDevice.(*C.libusb_device) + } else { + C.libusb_unref_device(match.rawDevice.(*C.libusb_device)) + } + } + if device == nil { + return nil, fmt.Errorf("failed to open device: not found") + } + // Open the mathcing device + info.rawDevice = device + + var handle *C.struct_libusb_device_handle + if err := fromRawErrno(C.libusb_open(info.rawDevice.(*C.libusb_device), (**C.struct_libusb_device_handle)(&handle))); err != nil { + return nil, fmt.Errorf("failed to open device: %v", err) + } + if err := fromRawErrno(C.libusb_claim_interface(handle, (C.int)(info.Interface))); err != nil { + C.libusb_close(handle) + return nil, fmt.Errorf("failed to claim interface: %v", err) + } + return &rawDevice{ + DeviceInfo: info, + handle: handle, + }, nil +} + +// rawDevice is a live low level USB connected device handle. +type rawDevice struct { + DeviceInfo // Embed the infos for easier access + + handle *C.struct_libusb_device_handle // Low level USB device to communicate through + lock sync.Mutex +} + +// Close releases the raw USB device handle. +func (dev *rawDevice) Close() error { + dev.lock.Lock() + defer dev.lock.Unlock() + + if dev.handle != nil { + C.libusb_release_interface(dev.handle, (C.int)(dev.Interface)) + C.libusb_close(dev.handle) + dev.handle = nil + } + C.libusb_unref_device(dev.rawDevice.(*C.libusb_device)) + + return nil +} + +// Write sends a binary blob to a low level USB device. +func (dev *rawDevice) Write(b []byte) (int, error) { + dev.lock.Lock() + defer dev.lock.Unlock() + + var transferred C.int + if err := fromRawErrno(C.libusb_interrupt_transfer(dev.handle, (C.uchar)(*dev.rawWriter), (*C.uchar)(&b[0]), (C.int)(len(b)), &transferred, (C.uint)(0))); err != nil { + return 0, fmt.Errorf("failed to write to device: %v", err) + } + return int(transferred), nil +} + +// Read retrieves a binary blob from a low level USB device. +func (dev *rawDevice) Read(b []byte) (int, error) { + dev.lock.Lock() + defer dev.lock.Unlock() + + var transferred C.int + if err := fromRawErrno(C.libusb_interrupt_transfer(dev.handle, (C.uchar)(*dev.rawReader), (*C.uchar)(&b[0]), (C.int)(len(b)), &transferred, (C.uint)(0))); err != nil { + return 0, fmt.Errorf("failed to read from device: %v", err) + } + return int(transferred), nil +} diff --git a/vendor/github.com/karalabe/usb/raw_errors.go b/vendor/github.com/karalabe/usb/raw_errors.go new file mode 100644 index 00000000..9e071f86 --- /dev/null +++ b/vendor/github.com/karalabe/usb/raw_errors.go @@ -0,0 +1,74 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Copyright 2016 the gousb Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package usb + +import ( + "fmt" +) + +// #include "./libusb/libusb/libusb.h" +import "C" + +// rawError is an error code from libusb. +type rawError C.int + +// Error implements the error interface. +func (e rawError) Error() string { + return fmt.Sprintf("libusb: %s [code %d]", rawErrorString[e], e) +} + +// fromRawErrno converts a raw libusb error into a Go type. +func fromRawErrno(errno C.int) error { + err := rawError(errno) + if err == errSuccess { + return nil + } + return err +} + +const ( + errSuccess rawError = C.LIBUSB_SUCCESS + errIO rawError = C.LIBUSB_ERROR_IO + errInvalidParam rawError = C.LIBUSB_ERROR_INVALID_PARAM + errAccess rawError = C.LIBUSB_ERROR_ACCESS + errNoDevice rawError = C.LIBUSB_ERROR_NO_DEVICE + errNotFound rawError = C.LIBUSB_ERROR_NOT_FOUND + errBusy rawError = C.LIBUSB_ERROR_BUSY + errTimeout rawError = C.LIBUSB_ERROR_TIMEOUT + errOverflow rawError = C.LIBUSB_ERROR_OVERFLOW + errPipe rawError = C.LIBUSB_ERROR_PIPE + errInterrupted rawError = C.LIBUSB_ERROR_INTERRUPTED + errNoMem rawError = C.LIBUSB_ERROR_NO_MEM + errNotSupported rawError = C.LIBUSB_ERROR_NOT_SUPPORTED + errOther rawError = C.LIBUSB_ERROR_OTHER +) + +var rawErrorString = map[rawError]string{ + errSuccess: "success", + errIO: "i/o error", + errInvalidParam: "invalid param", + errAccess: "bad access", + errNoDevice: "no device", + errNotFound: "not found", + errBusy: "device or resource busy", + errTimeout: "timeout", + errOverflow: "overflow", + errPipe: "pipe error", + errInterrupted: "interrupted", + errNoMem: "out of memory", + errNotSupported: "not supported", + errOther: "unknown error", +} diff --git a/vendor/github.com/karalabe/usb/usb.go b/vendor/github.com/karalabe/usb/usb.go new file mode 100644 index 00000000..96a1e250 --- /dev/null +++ b/vendor/github.com/karalabe/usb/usb.go @@ -0,0 +1,68 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// Package usb provide interfaces for generic USB devices. +package usb + +import "errors" + +// ErrDeviceClosed is returned for operations where the device closed before or +// during the execution. +var ErrDeviceClosed = errors.New("usb: device closed") + +// ErrUnsupportedPlatform is returned for all operations where the underlying +// operating system is not supported by the library. +var ErrUnsupportedPlatform = errors.New("usb: unsupported platform") + +// DeviceInfo contains all the information we know about a USB device. In case of +// HID devices, that might be a lot more extensive (empty fields for raw USB). +type DeviceInfo struct { + Path string // Platform-specific device path + VendorID uint16 // Device Vendor ID + ProductID uint16 // Device Product ID + Release uint16 // Device Release Number in binary-coded decimal, also known as Device Version Number + Serial string // Serial Number + Manufacturer string // Manufacturer String + Product string // Product string + UsagePage uint16 // Usage Page for this Device/Interface (Windows/Mac only) + Usage uint16 // Usage for this Device/Interface (Windows/Mac only) + + // The USB interface which this logical device + // represents. Valid on both Linux implementations + // in all cases, and valid on the Windows implementation + // only if the device contains more than one interface. + Interface int + + // Raw low level libusb endpoint data for simplified communication + rawDevice interface{} + rawPort *uint8 // Pointer to differentiate between unset and port 0 + rawReader *uint8 // Pointer to differentiate between unset and endpoint 0 + rawWriter *uint8 // Pointer to differentiate between unset and endpoint 0 +} + +// Device is a generic USB device interface. It may either be backed by a USB HID +// device or a low level raw (libusb) device. +type Device interface { + // Close releases the USB device handle. + Close() error + + // Write sends a binary blob to a USB device. For HID devices write uses reports, + // for low level USB write uses interrupt transfers. + Write(b []byte) (int, error) + + // Read retrieves a binary blob from a USB device. For HID devices read uses + // reports, for low level USB read uses interrupt transfers. + Read(b []byte) (int, error) +} diff --git a/vendor/github.com/karalabe/usb/usb_disabled.go b/vendor/github.com/karalabe/usb/usb_disabled.go new file mode 100644 index 00000000..f7f42a4c --- /dev/null +++ b/vendor/github.com/karalabe/usb/usb_disabled.go @@ -0,0 +1,46 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build !freebsd,!linux,!darwin,!windows ios !cgo + +package usb + +// Supported returns whether this platform is supported by the USB library or not. +// The goal of this method is to allow programatically handling platforms that do +// not support USB and not having to fall back to build constraints. +func Supported() bool { + return false +} + +// Enumerate returns a list of all the USB devices attached to the system which +// match the vendor and product id. On platforms that this file implements the +// function is a noop and returns an empty list always. +func Enumerate(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + return nil, nil +} + +// EnumerateRaw returns a list of all the USB devices attached to the system which +// match the vendor and product id. On platforms that this file implements the +// function is a noop and returns an empty list always. +func EnumerateRaw(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + return nil, nil +} + +// EnumerateHid returns a list of all the HID devices attached to the system which +// match the vendor and product id. On platforms that this file implements the +// function is a noop and returns an empty list always. +func EnumerateHid(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + return nil, nil +} diff --git a/vendor/github.com/karalabe/usb/usb_enabled.go b/vendor/github.com/karalabe/usb/usb_enabled.go new file mode 100644 index 00000000..6ba37af7 --- /dev/null +++ b/vendor/github.com/karalabe/usb/usb_enabled.go @@ -0,0 +1,98 @@ +// usb - Self contained USB and HID library for Go +// Copyright 2019 The library Authors +// +// This library is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// The library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with the library. If not, see . + +// +build freebsd,cgo linux,cgo darwin,!ios,cgo windows,cgo + +package usb + +import ( + "sync" +) + +// enumerateLock is a mutex serializing access to USB device enumeration needed +// by the macOS USB HID system calls, which require 2 consecutive method calls +// for enumeration, causing crashes if called concurrently. +// +// For more details, see: +// https://developer.apple.com/documentation/iokit/1438371-iohidmanagersetdevicematching +// > "subsequent calls will cause the hid manager to release previously enumerated devices" +var enumerateLock sync.Mutex + +// Supported returns whether this platform is supported by the USB library or not. +// The goal of this method is to allow programatically handling platforms that do +// not support USB and not having to fall back to build constraints. +func Supported() bool { + return true +} + +// Enumerate returns a list of all the USB devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all devices are returned. +// +// For any device that is HID capable, the enumeration will return an interface +// to the HID endpoints. For pure raw USB access, please use EnumerateRaw. +func Enumerate(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + enumerateLock.Lock() + defer enumerateLock.Unlock() + + // Enumerate all the raw USB devices and skip the HID ones + raws, err := enumerateRaw(vendorID, productID) + if err != nil { + return nil, err + } + // Enumerate all the HID USB devices + hids, err := enumerateHid(vendorID, productID) + if err != nil { + return nil, err + } + return append(raws, hids...), nil +} + +// EnumerateRaw returns a list of all the USB devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all devices are returned. +func EnumerateRaw(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + enumerateLock.Lock() + defer enumerateLock.Unlock() + + return enumerateRaw(vendorID, productID) +} + +// EnumerateHid returns a list of all the HID devices attached to the system which +// match the vendor and product id: +// - If the vendor id is set to 0 then any vendor matches. +// - If the product id is set to 0 then any product matches. +// - If the vendor and product id are both 0, all devices are returned. +func EnumerateHid(vendorID uint16, productID uint16) ([]DeviceInfo, error) { + enumerateLock.Lock() + defer enumerateLock.Unlock() + + return enumerateHid(vendorID, productID) +} + +// Open connects to a previsouly discovered USB device. +func (info DeviceInfo) Open() (Device, error) { + enumerateLock.Lock() + defer enumerateLock.Unlock() + + if info.rawDevice == nil { + return openHid(info) + } + return openRaw(info) +} diff --git a/vendor/github.com/karalabe/usb/wchar.go b/vendor/github.com/karalabe/usb/wchar.go new file mode 100644 index 00000000..cbc7e4d5 --- /dev/null +++ b/vendor/github.com/karalabe/usb/wchar.go @@ -0,0 +1,227 @@ +// This file is https://github.com/orofarne/gowchar/blob/master/gowchar.go +// +// It was vendored inline to work around CGO limitations that don't allow C types +// to directly cross package API boundaries. +// +// The vendored file is licensed under the 3-clause BSD license, according to: +// https://github.com/orofarne/gowchar/blob/master/LICENSE + +// +build !ios +// +build freebsd linux darwin windows + +package usb + +/* +#include + +const size_t SIZEOF_WCHAR_T = sizeof(wchar_t); + +void gowchar_set (wchar_t *arr, int pos, wchar_t val) +{ + arr[pos] = val; +} + +wchar_t gowchar_get (wchar_t *arr, int pos) +{ + return arr[pos]; +} +*/ +import "C" + +import ( + "fmt" + "unicode/utf16" + "unicode/utf8" +) + +var sizeofWcharT C.size_t = C.size_t(C.SIZEOF_WCHAR_T) + +func stringToWcharT(s string) (*C.wchar_t, C.size_t) { + switch sizeofWcharT { + case 2: + return stringToWchar2(s) // Windows + case 4: + return stringToWchar4(s) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +func wcharTToString(s *C.wchar_t) (string, error) { + switch sizeofWcharT { + case 2: + return wchar2ToString(s) // Windows + case 4: + return wchar4ToString(s) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +func wcharTNToString(s *C.wchar_t, size C.size_t) (string, error) { + switch sizeofWcharT { + case 2: + return wchar2NToString(s, size) // Windows + case 4: + return wchar4NToString(s, size) // Unix + default: + panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", sizeofWcharT)) + } +} + +// Windows +func stringToWchar2(s string) (*C.wchar_t, C.size_t) { + var slen int + s1 := s + for len(s1) > 0 { + r, size := utf8.DecodeRuneInString(s1) + if er, _ := utf16.EncodeRune(r); er == '\uFFFD' { + slen += 1 + } else { + slen += 2 + } + s1 = s1[size:] + } + slen++ // \0 + res := C.malloc(C.size_t(slen) * sizeofWcharT) + var i int + for len(s) > 0 { + r, size := utf8.DecodeRuneInString(s) + if r1, r2 := utf16.EncodeRune(r); r1 != '\uFFFD' { + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r1)) + i++ + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r2)) + i++ + } else { + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r)) + i++ + } + s = s[size:] + } + C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0 + return (*C.wchar_t)(res), C.size_t(slen) +} + +// Unix +func stringToWchar4(s string) (*C.wchar_t, C.size_t) { + slen := utf8.RuneCountInString(s) + slen++ // \0 + res := C.malloc(C.size_t(slen) * sizeofWcharT) + var i int + for len(s) > 0 { + r, size := utf8.DecodeRuneInString(s) + C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r)) + s = s[size:] + i++ + } + C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0 + return (*C.wchar_t)(res), C.size_t(slen) +} + +// Windows +func wchar2ToString(s *C.wchar_t) (string, error) { + var i int + var res string + for { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + i++ + if !utf16.IsSurrogate(r) { + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + } else { + ch2 := C.gowchar_get(s, C.int(i)) + r2 := rune(ch2) + r12 := utf16.DecodeRune(r, r2) + if r12 == '\uFFFD' { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + res += string(r12) + i++ + } + } + return res, nil +} + +// Unix +func wchar4ToString(s *C.wchar_t) (string, error) { + var i int + var res string + for { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + i++ + } + return res, nil +} + +// Windows +func wchar2NToString(s *C.wchar_t, size C.size_t) (string, error) { + var i int + var res string + N := int(size) + for i < N { + ch := C.gowchar_get(s, C.int(i)) + if ch == 0 { + break + } + r := rune(ch) + i++ + if !utf16.IsSurrogate(r) { + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + + res += string(r) + } else { + if i >= N { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + ch2 := C.gowchar_get(s, C.int(i)) + r2 := rune(ch2) + r12 := utf16.DecodeRune(r, r2) + if r12 == '\uFFFD' { + err := fmt.Errorf("Invalid surrogate pair at position %v", i-1) + return "", err + } + res += string(r12) + i++ + } + } + return res, nil +} + +// Unix +func wchar4NToString(s *C.wchar_t, size C.size_t) (string, error) { + var i int + var res string + N := int(size) + for i < N { + ch := C.gowchar_get(s, C.int(i)) + r := rune(ch) + if !utf8.ValidRune(r) { + err := fmt.Errorf("Invalid rune at position %v", i) + return "", err + } + res += string(r) + i++ + } + return res, nil +} diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md new file mode 100644 index 00000000..195333e5 --- /dev/null +++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md @@ -0,0 +1,41 @@ +# Windows Terminal Sequences + +This library allow for enabling Windows terminal color support for Go. + +See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details. + +## Usage + +```go +import ( + "syscall" + + sequences "github.com/konsorten/go-windows-terminal-sequences" +) + +func main() { + sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true) +} + +``` + +## Authors + +The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de). + +We thank all the authors who provided code to this library: + +* Felix Kollmann +* Nicolas Perraut + +## License + +(The MIT License) + +Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go new file mode 100644 index 00000000..df61a6f2 --- /dev/null +++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go @@ -0,0 +1,11 @@ +// +build linux darwin + +package sequences + +import ( + "fmt" +) + +func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error { + return fmt.Errorf("windows only package") +} diff --git a/vendor/github.com/koron/go-ssdp/.gitignore b/vendor/github.com/koron/go-ssdp/.gitignore new file mode 100644 index 00000000..6e55ea03 --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/.gitignore @@ -0,0 +1,3 @@ +*.exe +/tmp/ +tags diff --git a/vendor/github.com/koron/go-ssdp/LICENSE b/vendor/github.com/koron/go-ssdp/LICENSE new file mode 100644 index 00000000..a00a41d5 --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 MURAOKA Taro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/koron/go-ssdp/Makefile b/vendor/github.com/koron/go-ssdp/Makefile new file mode 100644 index 00000000..d06fa31c --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/Makefile @@ -0,0 +1,57 @@ +EXAMPLES = advertise alive bye monitor search + +default: test + +test: + go test . + +test-full: + go test -v -race . + +lint: + go vet ./... + @echo "" + golint ./... + +cyclo: + -gocyclo -top 10 -avg . + +report: + @echo "misspell" + @find . -name "*.go" | xargs misspell + @echo "" + -gocyclo -over 14 -avg . + @echo "" + go vet ./... + @echo "" + golint ./... + +deps: + go get -v -u -d -t ./... + +clean: examples-clean + +examples: examples-build + +examples-build: $(EXAMPLES) + +examples-clean: + rm -f $(EXAMPLES) + +advertise: examples/advertise/*.go *.go + go build ./examples/advertise + +alive: examples/alive/*.go *.go + go build ./examples/alive + +bye: examples/bye/*.go *.go + go build ./examples/bye + +monitor: examples/monitor/*.go *.go + go build ./examples/monitor + +search: examples/search/*.go *.go + go build ./examples/search + +.PHONY: test test-full lint cyclo report deps clean \ + examples examples-build examples-clean diff --git a/vendor/github.com/koron/go-ssdp/README.md b/vendor/github.com/koron/go-ssdp/README.md new file mode 100644 index 00000000..b24f071c --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/README.md @@ -0,0 +1,3 @@ +# SSDP libraries + + * diff --git a/vendor/github.com/koron/go-ssdp/advertise.go b/vendor/github.com/koron/go-ssdp/advertise.go new file mode 100644 index 00000000..75c54c16 --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/advertise.go @@ -0,0 +1,181 @@ +package ssdp + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net" + "net/http" + "sync" +) + +type message struct { + to *net.UDPAddr + data []byte +} + +// Advertiser is a server to advertise a service. +type Advertiser struct { + st string + usn string + location string + server string + maxAge int + + conn *net.UDPConn + ch chan *message + wg sync.WaitGroup + quit chan bool +} + +// Advertise starts advertisement of service. +func Advertise(st, usn, location, server string, maxAge int) (*Advertiser, error) { + conn, err := multicastListen("0.0.0.0:1900") + if err != nil { + return nil, err + } + logf("advertising on %s", conn.LocalAddr().String()) + a := &Advertiser{ + st: st, + usn: usn, + location: location, + server: server, + maxAge: maxAge, + conn: conn, + ch: make(chan *message), + quit: make(chan bool), + } + a.wg.Add(2) + go func() { + a.sendMain() + a.wg.Done() + }() + go func() { + a.serve() + a.wg.Done() + }() + return a, nil +} + +func (a *Advertiser) serve() error { + buf := make([]byte, 65535) + for { + n, addr, err := a.conn.ReadFromUDP(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + select { + case _ = <-a.quit: + return nil + default: + } + msg := buf[:n] + if err := a.handleRaw(addr, msg); err != nil { + logf("failed to handle message: %s", err) + } + } +} + +func (a *Advertiser) sendMain() error { + for { + select { + case msg, ok := <-a.ch: + if !ok { + return nil + } + _, err := sendTo(msg.to, msg.data) + if err != nil { + if nerr, ok := err.(net.Error); !ok || !nerr.Temporary() { + logf("failed to send: %s", err) + } + } + case _ = <-a.quit: + return nil + } + } +} + +func (a *Advertiser) handleRaw(from *net.UDPAddr, raw []byte) error { + if !bytes.HasPrefix(raw, []byte("M-SEARCH ")) { + // unexpected method. + return nil + } + req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(raw))) + if err != nil { + return err + } + var ( + man = req.Header.Get("MAN") + st = req.Header.Get("ST") + ) + if man != `"ssdp:discover"` { + return fmt.Errorf("unexpected MAN: %s", man) + } + if st != All && st != RootDevice && st != a.st { + // skip when ST is not matched/expected. + return nil + } + logf("received M-SEARCH MAN=%s ST=%s from %s", man, st, from.String()) + // build and send a response. + msg, err := buildOK(a.st, a.usn, a.location, a.server, a.maxAge) + if err != nil { + return err + } + a.ch <- &message{to: from, data: msg} + return nil +} + +func buildOK(st, usn, location, server string, maxAge int) ([]byte, error) { + b := new(bytes.Buffer) + // FIXME: error should be checked. + b.WriteString("HTTP/1.1 200 OK\r\n") + fmt.Fprintf(b, "ST: %s\r\n", st) + fmt.Fprintf(b, "USN: %s\r\n", usn) + if location != "" { + fmt.Fprintf(b, "LOCATION: %s\r\n", location) + } + if server != "" { + fmt.Fprintf(b, "SERVER: %s\r\n", server) + } + fmt.Fprintf(b, "CACHE-CONTROL: max-age=%d\r\n", maxAge) + b.WriteString("\r\n") + return b.Bytes(), nil +} + +// Close stops advertisement. +func (a *Advertiser) Close() error { + if a.conn != nil { + // closing order is very important. be caraful to change. + close(a.quit) + a.conn.Close() + a.wg.Wait() + close(a.ch) + a.conn = nil + } + return nil +} + +// Alive announces ssdp:alive message. +func (a *Advertiser) Alive() error { + msg, err := buildAlive(ssdpAddrIPv4, a.st, a.usn, a.location, a.server, + a.maxAge) + if err != nil { + return err + } + a.ch <- &message{to: ssdpAddrIPv4, data: msg} + return nil +} + +// Bye announces ssdp:byebye message. +func (a *Advertiser) Bye() error { + msg, err := buildBye(ssdpAddrIPv4, a.st, a.usn) + if err != nil { + return err + } + a.ch <- &message{to: ssdpAddrIPv4, data: msg} + return nil +} diff --git a/vendor/github.com/koron/go-ssdp/announce.go b/vendor/github.com/koron/go-ssdp/announce.go new file mode 100644 index 00000000..28157efb --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/announce.go @@ -0,0 +1,76 @@ +package ssdp + +import ( + "bytes" + "fmt" + "net" +) + +// AnnounceAlive sends ssdp:alive message. +func AnnounceAlive(nt, usn, location, server string, maxAge int, localAddr string) error { + // dial multicast UDP packet. + conn, err := multicastListen(localAddr) + if err != nil { + return err + } + defer conn.Close() + // build and send message. + msg, err := buildAlive(ssdpAddrIPv4, nt, usn, location, server, maxAge) + if err != nil { + return err + } + if _, err := conn.WriteTo(msg, ssdpAddrIPv4); err != nil { + return err + } + return nil +} + +func buildAlive(raddr net.Addr, nt, usn, location, server string, maxAge int) ([]byte, error) { + b := new(bytes.Buffer) + // FIXME: error should be checked. + b.WriteString("NOTIFY * HTTP/1.1\r\n") + fmt.Fprintf(b, "HOST: %s\r\n", raddr.String()) + fmt.Fprintf(b, "NT: %s\r\n", nt) + fmt.Fprintf(b, "NTS: %s\r\n", "ssdp:alive") + fmt.Fprintf(b, "USN: %s\r\n", usn) + if location != "" { + fmt.Fprintf(b, "LOCATION: %s\r\n", location) + } + if server != "" { + fmt.Fprintf(b, "SERVER: %s\r\n", server) + } + fmt.Fprintf(b, "CACHE-CONTROL: max-age=%d\r\n", maxAge) + b.WriteString("\r\n") + return b.Bytes(), nil +} + +// AnnounceBye sends ssdp:byebye message. +func AnnounceBye(nt, usn, localAddr string) error { + // dial multicast UDP packet. + conn, err := multicastListen(localAddr) + if err != nil { + return err + } + defer conn.Close() + // build and send message. + msg, err := buildBye(ssdpAddrIPv4, nt, usn) + if err != nil { + return err + } + if _, err := conn.WriteTo(msg, ssdpAddrIPv4); err != nil { + return err + } + return nil +} + +func buildBye(raddr net.Addr, nt, usn string) ([]byte, error) { + b := new(bytes.Buffer) + // FIXME: error should be checked. + b.WriteString("NOTIFY * HTTP/1.1\r\n") + fmt.Fprintf(b, "HOST: %s\r\n", raddr.String()) + fmt.Fprintf(b, "NT: %s\r\n", nt) + fmt.Fprintf(b, "NTS: %s\r\n", "ssdp:byebye") + fmt.Fprintf(b, "USN: %s\r\n", usn) + b.WriteString("\r\n") + return b.Bytes(), nil +} diff --git a/vendor/github.com/koron/go-ssdp/interface.go b/vendor/github.com/koron/go-ssdp/interface.go new file mode 100644 index 00000000..8c4cf55d --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/interface.go @@ -0,0 +1,39 @@ +package ssdp + +import "net" + +// Interfaces specify target interfaces to multicast. If no interfaces are +// specified, all interfaces will be used. +var Interfaces []net.Interface + +func interfacesIPv4() []net.Interface { + iflist, err := net.Interfaces() + if err != nil { + return nil + } + list := make([]net.Interface, 0, len(iflist)) + for _, ifi := range iflist { + if !hasIPv4Address(&ifi) { + continue + } + list = append(list, ifi) + } + return list +} + +func hasIPv4Address(ifi *net.Interface) bool { + addrs, err := ifi.Addrs() + if err != nil { + return false + } + for _, a := range addrs { + ip, _, err := net.ParseCIDR(a.String()) + if err != nil { + continue + } + if len(ip.To4()) == net.IPv4len && !ip.IsUnspecified() { + return true + } + } + return false +} diff --git a/vendor/github.com/koron/go-ssdp/log.go b/vendor/github.com/koron/go-ssdp/log.go new file mode 100644 index 00000000..a4be85ad --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/log.go @@ -0,0 +1,12 @@ +package ssdp + +import "log" + +// Logger is default logger for SSDP module. +var Logger *log.Logger + +func logf(s string, a ...interface{}) { + if Logger != nil { + Logger.Printf(s, a...) + } +} diff --git a/vendor/github.com/koron/go-ssdp/monitor.go b/vendor/github.com/koron/go-ssdp/monitor.go new file mode 100644 index 00000000..686d4f9f --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/monitor.go @@ -0,0 +1,173 @@ +package ssdp + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net" + "net/http" + "sync" +) + +// Monitor monitors SSDP's alive and byebye messages. +type Monitor struct { + alive AliveHandler + bye ByeHandler + conn net.PacketConn + wg sync.WaitGroup +} + +// NewMonitor creates a new Monitor. +func NewMonitor(alive AliveHandler, bye ByeHandler) (*Monitor, error) { + if alive == nil { + alive = nullAlive + } + if bye == nil { + bye = nullBye + } + conn, err := multicastListen("0.0.0.0:1900") + if err != nil { + return nil, err + } + logf("monitoring on %s", conn.LocalAddr().String()) + m := &Monitor{ + alive: alive, + bye: bye, + conn: conn, + } + m.wg.Add(1) + go func() { + m.serve() + m.wg.Done() + }() + return m, nil +} + +func (m *Monitor) serve() error { + buf := make([]byte, 65535) + for { + n, addr, err := m.conn.ReadFrom(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + msg := make([]byte, n) + copy(msg, buf[:n]) + go m.handleRaw(addr, msg) + } +} + +func (m *Monitor) handleRaw(addr net.Addr, raw []byte) error { + req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(raw))) + if err != nil { + return err + } + switch nts := req.Header.Get("NTS"); nts { + case "ssdp:alive": + if req.Method != "NOTIFY" { + return fmt.Errorf("unexpected method for %q: %s", "ssdp:alive", req.Method) + } + m.alive(&Alive{ + From: addr, + Type: req.Header.Get("NT"), + USN: req.Header.Get("USN"), + Location: req.Header.Get("LOCATION"), + Server: req.Header.Get("SERVER"), + rawHeader: req.Header, + }) + case "ssdp:byebye": + if req.Method != "NOTIFY" { + return fmt.Errorf("unexpected method for %q: %s", "ssdp:byebye", req.Method) + } + m.bye(&Bye{ + From: addr, + Type: req.Header.Get("NT"), + USN: req.Header.Get("USN"), + rawHeader: req.Header, + }) + default: + return fmt.Errorf("unknown NTS: %s", nts) + } + return nil +} + +// Close closes monitoring. +func (m *Monitor) Close() error { + if m.conn != nil { + m.conn.Close() + m.conn = nil + m.wg.Wait() + } + return nil +} + +// Alive represents SSDP's ssdp:alive message. +type Alive struct { + // From is a sender of this message + From net.Addr + + // Type is a property of "NT" + Type string + + // USN is a property of "USN" + USN string + + // Location is a property of "LOCATION" + Location string + + // Server is a property of "SERVER" + Server string + + rawHeader http.Header + maxAge *int +} + +// Header returns all properties in response of search. +func (m *Alive) Header() http.Header { + return m.rawHeader +} + +// MaxAge extracts "max-age" value from "CACHE-CONTROL" property. +func (m *Alive) MaxAge() int { + if m.maxAge == nil { + m.maxAge = new(int) + *m.maxAge = extractMaxAge(m.rawHeader.Get("CACHE-CONTROL"), -1) + } + return *m.maxAge +} + +// AliveHandler is handler of Alive message. +type AliveHandler func(*Alive) + +func nullAlive(*Alive) { + // nothing to do. +} + +// Bye represents SSDP's ssdp:byebye message. +type Bye struct { + // From is a sender of this message + From net.Addr + + // Type is a property of "NT" + Type string + + // USN is a property of "USN" + USN string + + rawHeader http.Header +} + +// Header returns all properties in response of search. +func (m *Bye) Header() http.Header { + return m.rawHeader +} + +// ByeHandler is handler of Bye message. +type ByeHandler func(*Bye) + +func nullBye(*Bye) { + // nothing to do. +} diff --git a/vendor/github.com/koron/go-ssdp/search.go b/vendor/github.com/koron/go-ssdp/search.go new file mode 100644 index 00000000..0bc07758 --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/search.go @@ -0,0 +1,139 @@ +package ssdp + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "net" + "net/http" + "regexp" + "strconv" + "time" +) + +// Service is discovered service. +type Service struct { + // Type is a property of "ST" + Type string + + // USN is a property of "USN" + USN string + + // Location is a property of "LOCATION" + Location string + + // Server is a property of "SERVER" + Server string + + rawHeader http.Header + maxAge *int +} + +var rxMaxAge = regexp.MustCompile(`\bmax-age\s*=\s*(\d+)\b`) + +func extractMaxAge(s string, value int) int { + v := value + if m := rxMaxAge.FindStringSubmatch(s); m != nil { + i64, err := strconv.ParseInt(m[1], 10, 32) + if err == nil { + v = int(i64) + } + } + return v +} + +// MaxAge extracts "max-age" value from "CACHE-CONTROL" property. +func (s *Service) MaxAge() int { + if s.maxAge == nil { + s.maxAge = new(int) + *s.maxAge = extractMaxAge(s.rawHeader.Get("CACHE-CONTROL"), -1) + } + return *s.maxAge +} + +// Header returns all properties in response of search. +func (s *Service) Header() http.Header { + return s.rawHeader +} + +const ( + // All is a search type to search all services and devices. + All = "ssdp:all" + + // RootDevice is a search type to search UPnP root devices. + RootDevice = "upnp:rootdevice" +) + +// Search searchs services by SSDP. +func Search(searchType string, waitSec int, localAddr string) ([]Service, error) { + // dial multicast UDP packet. + conn, err := multicastListen(localAddr) + if err != nil { + return nil, err + } + defer conn.Close() + logf("search on %s", conn.LocalAddr().String()) + + // send request. + msg, err := buildSearch(ssdpAddrIPv4, searchType, waitSec) + if err != nil { + return nil, err + } + if _, err := conn.WriteTo(msg, ssdpAddrIPv4); err != nil { + return nil, err + } + + // wait response. + var list []Service + h := func(a net.Addr, d []byte) error { + srv, err := parseService(a, d) + if err != nil { + logf("invalid search response from %s: %s", a.String(), err) + return nil + } + list = append(list, *srv) + logf("search response from %s: %s", a.String(), srv.USN) + return nil + } + d := time.Second * time.Duration(waitSec) + if err := readPackets(conn, d, h); err != nil { + return nil, err + } + + return list, err +} + +func buildSearch(raddr net.Addr, searchType string, waitSec int) ([]byte, error) { + b := new(bytes.Buffer) + // FIXME: error should be checked. + b.WriteString("M-SEARCH * HTTP/1.1\r\n") + fmt.Fprintf(b, "HOST: %s\r\n", raddr.String()) + fmt.Fprintf(b, "MAN: %q\r\n", "ssdp:discover") + fmt.Fprintf(b, "MX: %d\r\n", waitSec) + fmt.Fprintf(b, "ST: %s\r\n", searchType) + b.WriteString("\r\n") + return b.Bytes(), nil +} + +var ( + errWithoutHTTPPrefix = errors.New("without HTTP prefix") +) + +func parseService(addr net.Addr, data []byte) (*Service, error) { + if !bytes.HasPrefix(data, []byte("HTTP")) { + return nil, errWithoutHTTPPrefix + } + resp, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(data)), nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + return &Service{ + Type: resp.Header.Get("ST"), + USN: resp.Header.Get("USN"), + Location: resp.Header.Get("LOCATION"), + Server: resp.Header.Get("SERVER"), + rawHeader: resp.Header, + }, nil +} diff --git a/vendor/github.com/koron/go-ssdp/udp.go b/vendor/github.com/koron/go-ssdp/udp.go new file mode 100644 index 00000000..f227e3a3 --- /dev/null +++ b/vendor/github.com/koron/go-ssdp/udp.go @@ -0,0 +1,96 @@ +package ssdp + +import ( + "errors" + "net" + "time" + + "golang.org/x/net/ipv4" +) + +var ( + ssdpAddrIPv4 *net.UDPAddr +) + +func init() { + var err error + ssdpAddrIPv4, err = net.ResolveUDPAddr("udp4", "239.255.255.250:1900") + if err != nil { + panic(err) + } +} + +type packetHandler func(net.Addr, []byte) error + +func readPackets(conn *net.UDPConn, timeout time.Duration, h packetHandler) error { + buf := make([]byte, 65535) + conn.SetReadBuffer(len(buf)) + conn.SetReadDeadline(time.Now().Add(timeout)) + for { + n, addr, err := conn.ReadFrom(buf) + if err != nil { + if nerr, ok := err.(net.Error); ok && nerr.Timeout() { + return nil + } + return err + } + if err := h(addr, buf[:n]); err != nil { + return err + } + } +} + +func sendTo(to *net.UDPAddr, data []byte) (int, error) { + conn, err := net.DialUDP("udp4", nil, to) + if err != nil { + return 0, err + } + defer conn.Close() + n, err := conn.Write(data) + if err != nil { + return 0, err + } + return n, nil +} + +func multicastListen(localAddr string) (*net.UDPConn, error) { + // prepare parameters. + laddr, err := net.ResolveUDPAddr("udp4", localAddr) + if err != nil { + return nil, err + } + // connect. + conn, err := net.ListenUDP("udp4", laddr) + if err != nil { + return nil, err + } + // configure socket to use with multicast. + if err := joinGroupIPv4(conn, Interfaces, ssdpAddrIPv4); err != nil { + conn.Close() + return nil, err + } + return conn, err +} + +// joinGroupIPv4 makes the connection join to a group on interfaces. +func joinGroupIPv4(conn net.PacketConn, iflist []net.Interface, gaddr net.Addr) error { + wrap := ipv4.NewPacketConn(conn) + wrap.SetMulticastLoopback(true) + if len(iflist) == 0 { + iflist = interfacesIPv4() + } + // add interfaces to multicast group. + joined := 0 + for _, ifi := range iflist { + if err := wrap.JoinGroup(&ifi, gaddr); err != nil { + logf("failed to join group %s on %s: %s", gaddr.String(), ifi.Name, err) + continue + } + joined++ + logf("joined gropup %s on %s", gaddr.String(), ifi.Name) + } + if joined == 0 { + return errors.New("no interfaces had joined to group") + } + return nil +} diff --git a/vendor/github.com/lib/pq/.travis.sh b/vendor/github.com/lib/pq/.travis.sh new file mode 100755 index 00000000..21a52644 --- /dev/null +++ b/vendor/github.com/lib/pq/.travis.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +set -eu + +client_configure() { + sudo chmod 600 $PQSSLCERTTEST_PATH/postgresql.key +} + +pgdg_repository() { + local sourcelist='sources.list.d/postgresql.list' + + curl -sS 'https://www.postgresql.org/media/keys/ACCC4CF8.asc' | sudo apt-key add - + echo deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main $PGVERSION | sudo tee "/etc/apt/$sourcelist" + sudo apt-get -o Dir::Etc::sourcelist="$sourcelist" -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0' update +} + +postgresql_configure() { + sudo tee /etc/postgresql/$PGVERSION/main/pg_hba.conf > /dev/null <<-config + local all all trust + hostnossl all pqgossltest 127.0.0.1/32 reject + hostnossl all pqgosslcert 127.0.0.1/32 reject + hostssl all pqgossltest 127.0.0.1/32 trust + hostssl all pqgosslcert 127.0.0.1/32 cert + host all all 127.0.0.1/32 trust + hostnossl all pqgossltest ::1/128 reject + hostnossl all pqgosslcert ::1/128 reject + hostssl all pqgossltest ::1/128 trust + hostssl all pqgosslcert ::1/128 cert + host all all ::1/128 trust + config + + xargs sudo install -o postgres -g postgres -m 600 -t /var/lib/postgresql/$PGVERSION/main/ <<-certificates + certs/root.crt + certs/server.crt + certs/server.key + certificates + + sort -VCu <<-versions || + $PGVERSION + 9.2 + versions + sudo tee -a /etc/postgresql/$PGVERSION/main/postgresql.conf > /dev/null <<-config + ssl_ca_file = 'root.crt' + ssl_cert_file = 'server.crt' + ssl_key_file = 'server.key' + config + + echo 127.0.0.1 postgres | sudo tee -a /etc/hosts > /dev/null + + sudo service postgresql restart +} + +postgresql_install() { + xargs sudo apt-get -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confnew' install <<-packages + postgresql-$PGVERSION + postgresql-server-dev-$PGVERSION + postgresql-contrib-$PGVERSION + packages +} + +postgresql_uninstall() { + sudo service postgresql stop + xargs sudo apt-get -y --purge remove <<-packages + libpq-dev + libpq5 + postgresql + postgresql-client-common + postgresql-common + packages + sudo rm -rf /var/lib/postgresql +} + +megacheck_install() { + # Lock megacheck version at $MEGACHECK_VERSION to prevent spontaneous + # new error messages in old code. + go get -d honnef.co/go/tools/... + git -C $GOPATH/src/honnef.co/go/tools/ checkout $MEGACHECK_VERSION + go install honnef.co/go/tools/cmd/megacheck + megacheck --version +} + +golint_install() { + go get golang.org/x/lint/golint +} + +$1 diff --git a/vendor/github.com/lib/pq/.travis.yml b/vendor/github.com/lib/pq/.travis.yml new file mode 100644 index 00000000..f0305809 --- /dev/null +++ b/vendor/github.com/lib/pq/.travis.yml @@ -0,0 +1,50 @@ +language: go + +go: + - 1.9.x + - 1.10.x + - 1.11.x + - master + +sudo: true + +env: + global: + - PGUSER=postgres + - PQGOSSLTESTS=1 + - PQSSLCERTTEST_PATH=$PWD/certs + - PGHOST=127.0.0.1 + - MEGACHECK_VERSION=2017.2.2 + matrix: + - PGVERSION=10 + - PGVERSION=9.6 + - PGVERSION=9.5 + - PGVERSION=9.4 + - PGVERSION=9.3 + - PGVERSION=9.2 + - PGVERSION=9.1 + - PGVERSION=9.0 + +before_install: + - ./.travis.sh postgresql_uninstall + - ./.travis.sh pgdg_repository + - ./.travis.sh postgresql_install + - ./.travis.sh postgresql_configure + - ./.travis.sh client_configure + - ./.travis.sh megacheck_install + - ./.travis.sh golint_install + - go get golang.org/x/tools/cmd/goimports + +before_script: + - createdb pqgotest + - createuser -DRS pqgossltest + - createuser -DRS pqgosslcert + +script: + - > + goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }' + - go vet ./... + - megacheck -go 1.9 ./... + - golint ./... + - PQTEST_BINARY_PARAMETERS=no go test -race -v ./... + - PQTEST_BINARY_PARAMETERS=yes go test -race -v ./... diff --git a/vendor/github.com/lib/pq/README.md b/vendor/github.com/lib/pq/README.md new file mode 100644 index 00000000..385fe735 --- /dev/null +++ b/vendor/github.com/lib/pq/README.md @@ -0,0 +1,95 @@ +# pq - A pure Go postgres driver for Go's database/sql package + +[![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://godoc.org/github.com/lib/pq) +[![Build Status](https://travis-ci.org/lib/pq.svg?branch=master)](https://travis-ci.org/lib/pq) + +## Install + + go get github.com/lib/pq + +## Docs + +For detailed documentation and basic usage examples, please see the package +documentation at . + +## Tests + +`go test` is used for testing. See [TESTS.md](TESTS.md) for more details. + +## Features + +* SSL +* Handles bad connections for `database/sql` +* Scan `time.Time` correctly (i.e. `timestamp[tz]`, `time[tz]`, `date`) +* Scan binary blobs correctly (i.e. `bytea`) +* Package for `hstore` support +* COPY FROM support +* pq.ParseURL for converting urls to connection strings for sql.Open. +* Many libpq compatible environment variables +* Unix socket support +* Notifications: `LISTEN`/`NOTIFY` +* pgpass support + +## Future / Things you can help with + +* Better COPY FROM / COPY TO (see discussion in #181) + +## Thank you (alphabetical) + +Some of these contributors are from the original library `bmizerany/pq.go` whose +code still exists in here. + +* Andy Balholm (andybalholm) +* Ben Berkert (benburkert) +* Benjamin Heatwole (bheatwole) +* Bill Mill (llimllib) +* Bjørn Madsen (aeons) +* Blake Gentry (bgentry) +* Brad Fitzpatrick (bradfitz) +* Charlie Melbye (cmelbye) +* Chris Bandy (cbandy) +* Chris Gilling (cgilling) +* Chris Walsh (cwds) +* Dan Sosedoff (sosedoff) +* Daniel Farina (fdr) +* Eric Chlebek (echlebek) +* Eric Garrido (minusnine) +* Eric Urban (hydrogen18) +* Everyone at The Go Team +* Evan Shaw (edsrzf) +* Ewan Chou (coocood) +* Fazal Majid (fazalmajid) +* Federico Romero (federomero) +* Fumin (fumin) +* Gary Burd (garyburd) +* Heroku (heroku) +* James Pozdena (jpoz) +* Jason McVetta (jmcvetta) +* Jeremy Jay (pbnjay) +* Joakim Sernbrant (serbaut) +* John Gallagher (jgallagher) +* Jonathan Rudenberg (titanous) +* Joël Stemmer (jstemmer) +* Kamil Kisiel (kisielk) +* Kelly Dunn (kellydunn) +* Keith Rarick (kr) +* Kir Shatrov (kirs) +* Lann Martin (lann) +* Maciek Sakrejda (uhoh-itsmaciek) +* Marc Brinkmann (mbr) +* Marko Tiikkaja (johto) +* Matt Newberry (MattNewberry) +* Matt Robenolt (mattrobenolt) +* Martin Olsen (martinolsen) +* Mike Lewis (mikelikespie) +* Nicolas Patry (Narsil) +* Oliver Tonnhofer (olt) +* Patrick Hayes (phayes) +* Paul Hammond (paulhammond) +* Ryan Smith (ryandotsmith) +* Samuel Stauffer (samuel) +* Timothée Peignier (cyberdelia) +* Travis Cline (tmc) +* TruongSinh Tran-Nguyen (truongsinh) +* Yaismel Miranda (ympons) +* notedit (notedit) diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go new file mode 100644 index 00000000..012c8c7c --- /dev/null +++ b/vendor/github.com/lib/pq/conn.go @@ -0,0 +1,1919 @@ +package pq + +import ( + "bufio" + "context" + "crypto/md5" + "crypto/sha256" + "database/sql" + "database/sql/driver" + "encoding/binary" + "errors" + "fmt" + "io" + "net" + "os" + "os/user" + "path" + "path/filepath" + "strconv" + "strings" + "time" + "unicode" + + "github.com/lib/pq/oid" + "github.com/lib/pq/scram" +) + +// Common error types +var ( + ErrNotSupported = errors.New("pq: Unsupported command") + ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction") + ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server") + ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less") + ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly") + + errUnexpectedReady = errors.New("unexpected ReadyForQuery") + errNoRowsAffected = errors.New("no RowsAffected available after the empty statement") + errNoLastInsertID = errors.New("no LastInsertId available after the empty statement") +) + +// Driver is the Postgres database driver. +type Driver struct{} + +// Open opens a new connection to the database. name is a connection string. +// Most users should only use it through database/sql package from the standard +// library. +func (d *Driver) Open(name string) (driver.Conn, error) { + return Open(name) +} + +func init() { + sql.Register("postgres", &Driver{}) +} + +type parameterStatus struct { + // server version in the same format as server_version_num, or 0 if + // unavailable + serverVersion int + + // the current location based on the TimeZone value of the session, if + // available + currentLocation *time.Location +} + +type transactionStatus byte + +const ( + txnStatusIdle transactionStatus = 'I' + txnStatusIdleInTransaction transactionStatus = 'T' + txnStatusInFailedTransaction transactionStatus = 'E' +) + +func (s transactionStatus) String() string { + switch s { + case txnStatusIdle: + return "idle" + case txnStatusIdleInTransaction: + return "idle in transaction" + case txnStatusInFailedTransaction: + return "in a failed transaction" + default: + errorf("unknown transactionStatus %d", s) + } + + panic("not reached") +} + +// Dialer is the dialer interface. It can be used to obtain more control over +// how pq creates network connections. +type Dialer interface { + Dial(network, address string) (net.Conn, error) + DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) +} + +type DialerContext interface { + DialContext(ctx context.Context, network, address string) (net.Conn, error) +} + +type defaultDialer struct { + d net.Dialer +} + +func (d defaultDialer) Dial(network, address string) (net.Conn, error) { + return d.d.Dial(network, address) +} +func (d defaultDialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + return d.DialContext(ctx, network, address) +} +func (d defaultDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + return d.d.DialContext(ctx, network, address) +} + +type conn struct { + c net.Conn + buf *bufio.Reader + namei int + scratch [512]byte + txnStatus transactionStatus + txnFinish func() + + // Save connection arguments to use during CancelRequest. + dialer Dialer + opts values + + // Cancellation key data for use with CancelRequest messages. + processID int + secretKey int + + parameterStatus parameterStatus + + saveMessageType byte + saveMessageBuffer []byte + + // If true, this connection is bad and all public-facing functions should + // return ErrBadConn. + bad bool + + // If set, this connection should never use the binary format when + // receiving query results from prepared statements. Only provided for + // debugging. + disablePreparedBinaryResult bool + + // Whether to always send []byte parameters over as binary. Enables single + // round-trip mode for non-prepared Query calls. + binaryParameters bool + + // If true this connection is in the middle of a COPY + inCopy bool +} + +// Handle driver-side settings in parsed connection string. +func (cn *conn) handleDriverSettings(o values) (err error) { + boolSetting := func(key string, val *bool) error { + if value, ok := o[key]; ok { + if value == "yes" { + *val = true + } else if value == "no" { + *val = false + } else { + return fmt.Errorf("unrecognized value %q for %s", value, key) + } + } + return nil + } + + err = boolSetting("disable_prepared_binary_result", &cn.disablePreparedBinaryResult) + if err != nil { + return err + } + return boolSetting("binary_parameters", &cn.binaryParameters) +} + +func (cn *conn) handlePgpass(o values) { + // if a password was supplied, do not process .pgpass + if _, ok := o["password"]; ok { + return + } + filename := os.Getenv("PGPASSFILE") + if filename == "" { + // XXX this code doesn't work on Windows where the default filename is + // XXX %APPDATA%\postgresql\pgpass.conf + // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470 + userHome := os.Getenv("HOME") + if userHome == "" { + user, err := user.Current() + if err != nil { + return + } + userHome = user.HomeDir + } + filename = filepath.Join(userHome, ".pgpass") + } + fileinfo, err := os.Stat(filename) + if err != nil { + return + } + mode := fileinfo.Mode() + if mode&(0x77) != 0 { + // XXX should warn about incorrect .pgpass permissions as psql does + return + } + file, err := os.Open(filename) + if err != nil { + return + } + defer file.Close() + scanner := bufio.NewScanner(io.Reader(file)) + hostname := o["host"] + ntw, _ := network(o) + port := o["port"] + db := o["dbname"] + username := o["user"] + // From: https://github.com/tg/pgpass/blob/master/reader.go + getFields := func(s string) []string { + fs := make([]string, 0, 5) + f := make([]rune, 0, len(s)) + + var esc bool + for _, c := range s { + switch { + case esc: + f = append(f, c) + esc = false + case c == '\\': + esc = true + case c == ':': + fs = append(fs, string(f)) + f = f[:0] + default: + f = append(f, c) + } + } + return append(fs, string(f)) + } + for scanner.Scan() { + line := scanner.Text() + if len(line) == 0 || line[0] == '#' { + continue + } + split := getFields(line) + if len(split) != 5 { + continue + } + if (split[0] == "*" || split[0] == hostname || (split[0] == "localhost" && (hostname == "" || ntw == "unix"))) && (split[1] == "*" || split[1] == port) && (split[2] == "*" || split[2] == db) && (split[3] == "*" || split[3] == username) { + o["password"] = split[4] + return + } + } +} + +func (cn *conn) writeBuf(b byte) *writeBuf { + cn.scratch[0] = b + return &writeBuf{ + buf: cn.scratch[:5], + pos: 1, + } +} + +// Open opens a new connection to the database. dsn is a connection string. +// Most users should only use it through database/sql package from the standard +// library. +func Open(dsn string) (_ driver.Conn, err error) { + return DialOpen(defaultDialer{}, dsn) +} + +// DialOpen opens a new connection to the database using a dialer. +func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error) { + c, err := NewConnector(dsn) + if err != nil { + return nil, err + } + c.dialer = d + return c.open(context.Background()) +} + +func (c *Connector) open(ctx context.Context) (cn *conn, err error) { + // Handle any panics during connection initialization. Note that we + // specifically do *not* want to use errRecover(), as that would turn any + // connection errors into ErrBadConns, hiding the real error message from + // the user. + defer errRecoverNoErrBadConn(&err) + + o := c.opts + + cn = &conn{ + opts: o, + dialer: c.dialer, + } + err = cn.handleDriverSettings(o) + if err != nil { + return nil, err + } + cn.handlePgpass(o) + + cn.c, err = dial(ctx, c.dialer, o) + if err != nil { + return nil, err + } + + err = cn.ssl(o) + if err != nil { + if cn.c != nil { + cn.c.Close() + } + return nil, err + } + + // cn.startup panics on error. Make sure we don't leak cn.c. + panicking := true + defer func() { + if panicking { + cn.c.Close() + } + }() + + cn.buf = bufio.NewReader(cn.c) + cn.startup(o) + + // reset the deadline, in case one was set (see dial) + if timeout, ok := o["connect_timeout"]; ok && timeout != "0" { + err = cn.c.SetDeadline(time.Time{}) + } + panicking = false + return cn, err +} + +func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) { + network, address := network(o) + // SSL is not necessary or supported over UNIX domain sockets + if network == "unix" { + o["sslmode"] = "disable" + } + + // Zero or not specified means wait indefinitely. + if timeout, ok := o["connect_timeout"]; ok && timeout != "0" { + seconds, err := strconv.ParseInt(timeout, 10, 0) + if err != nil { + return nil, fmt.Errorf("invalid value for parameter connect_timeout: %s", err) + } + duration := time.Duration(seconds) * time.Second + + // connect_timeout should apply to the entire connection establishment + // procedure, so we both use a timeout for the TCP connection + // establishment and set a deadline for doing the initial handshake. + // The deadline is then reset after startup() is done. + deadline := time.Now().Add(duration) + var conn net.Conn + if dctx, ok := d.(DialerContext); ok { + ctx, cancel := context.WithTimeout(ctx, duration) + defer cancel() + conn, err = dctx.DialContext(ctx, network, address) + } else { + conn, err = d.DialTimeout(network, address, duration) + } + if err != nil { + return nil, err + } + err = conn.SetDeadline(deadline) + return conn, err + } + if dctx, ok := d.(DialerContext); ok { + return dctx.DialContext(ctx, network, address) + } + return d.Dial(network, address) +} + +func network(o values) (string, string) { + host := o["host"] + + if strings.HasPrefix(host, "/") { + sockPath := path.Join(host, ".s.PGSQL."+o["port"]) + return "unix", sockPath + } + + return "tcp", net.JoinHostPort(host, o["port"]) +} + +type values map[string]string + +// scanner implements a tokenizer for libpq-style option strings. +type scanner struct { + s []rune + i int +} + +// newScanner returns a new scanner initialized with the option string s. +func newScanner(s string) *scanner { + return &scanner{[]rune(s), 0} +} + +// Next returns the next rune. +// It returns 0, false if the end of the text has been reached. +func (s *scanner) Next() (rune, bool) { + if s.i >= len(s.s) { + return 0, false + } + r := s.s[s.i] + s.i++ + return r, true +} + +// SkipSpaces returns the next non-whitespace rune. +// It returns 0, false if the end of the text has been reached. +func (s *scanner) SkipSpaces() (rune, bool) { + r, ok := s.Next() + for unicode.IsSpace(r) && ok { + r, ok = s.Next() + } + return r, ok +} + +// parseOpts parses the options from name and adds them to the values. +// +// The parsing code is based on conninfo_parse from libpq's fe-connect.c +func parseOpts(name string, o values) error { + s := newScanner(name) + + for { + var ( + keyRunes, valRunes []rune + r rune + ok bool + ) + + if r, ok = s.SkipSpaces(); !ok { + break + } + + // Scan the key + for !unicode.IsSpace(r) && r != '=' { + keyRunes = append(keyRunes, r) + if r, ok = s.Next(); !ok { + break + } + } + + // Skip any whitespace if we're not at the = yet + if r != '=' { + r, ok = s.SkipSpaces() + } + + // The current character should be = + if r != '=' || !ok { + return fmt.Errorf(`missing "=" after %q in connection info string"`, string(keyRunes)) + } + + // Skip any whitespace after the = + if r, ok = s.SkipSpaces(); !ok { + // If we reach the end here, the last value is just an empty string as per libpq. + o[string(keyRunes)] = "" + break + } + + if r != '\'' { + for !unicode.IsSpace(r) { + if r == '\\' { + if r, ok = s.Next(); !ok { + return fmt.Errorf(`missing character after backslash`) + } + } + valRunes = append(valRunes, r) + + if r, ok = s.Next(); !ok { + break + } + } + } else { + quote: + for { + if r, ok = s.Next(); !ok { + return fmt.Errorf(`unterminated quoted string literal in connection string`) + } + switch r { + case '\'': + break quote + case '\\': + r, _ = s.Next() + fallthrough + default: + valRunes = append(valRunes, r) + } + } + } + + o[string(keyRunes)] = string(valRunes) + } + + return nil +} + +func (cn *conn) isInTransaction() bool { + return cn.txnStatus == txnStatusIdleInTransaction || + cn.txnStatus == txnStatusInFailedTransaction +} + +func (cn *conn) checkIsInTransaction(intxn bool) { + if cn.isInTransaction() != intxn { + cn.bad = true + errorf("unexpected transaction status %v", cn.txnStatus) + } +} + +func (cn *conn) Begin() (_ driver.Tx, err error) { + return cn.begin("") +} + +func (cn *conn) begin(mode string) (_ driver.Tx, err error) { + if cn.bad { + return nil, driver.ErrBadConn + } + defer cn.errRecover(&err) + + cn.checkIsInTransaction(false) + _, commandTag, err := cn.simpleExec("BEGIN" + mode) + if err != nil { + return nil, err + } + if commandTag != "BEGIN" { + cn.bad = true + return nil, fmt.Errorf("unexpected command tag %s", commandTag) + } + if cn.txnStatus != txnStatusIdleInTransaction { + cn.bad = true + return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus) + } + return cn, nil +} + +func (cn *conn) closeTxn() { + if finish := cn.txnFinish; finish != nil { + finish() + } +} + +func (cn *conn) Commit() (err error) { + defer cn.closeTxn() + if cn.bad { + return driver.ErrBadConn + } + defer cn.errRecover(&err) + + cn.checkIsInTransaction(true) + // We don't want the client to think that everything is okay if it tries + // to commit a failed transaction. However, no matter what we return, + // database/sql will release this connection back into the free connection + // pool so we have to abort the current transaction here. Note that you + // would get the same behaviour if you issued a COMMIT in a failed + // transaction, so it's also the least surprising thing to do here. + if cn.txnStatus == txnStatusInFailedTransaction { + if err := cn.Rollback(); err != nil { + return err + } + return ErrInFailedTransaction + } + + _, commandTag, err := cn.simpleExec("COMMIT") + if err != nil { + if cn.isInTransaction() { + cn.bad = true + } + return err + } + if commandTag != "COMMIT" { + cn.bad = true + return fmt.Errorf("unexpected command tag %s", commandTag) + } + cn.checkIsInTransaction(false) + return nil +} + +func (cn *conn) Rollback() (err error) { + defer cn.closeTxn() + if cn.bad { + return driver.ErrBadConn + } + defer cn.errRecover(&err) + + cn.checkIsInTransaction(true) + _, commandTag, err := cn.simpleExec("ROLLBACK") + if err != nil { + if cn.isInTransaction() { + cn.bad = true + } + return err + } + if commandTag != "ROLLBACK" { + return fmt.Errorf("unexpected command tag %s", commandTag) + } + cn.checkIsInTransaction(false) + return nil +} + +func (cn *conn) gname() string { + cn.namei++ + return strconv.FormatInt(int64(cn.namei), 10) +} + +func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err error) { + b := cn.writeBuf('Q') + b.string(q) + cn.send(b) + + for { + t, r := cn.recv1() + switch t { + case 'C': + res, commandTag = cn.parseComplete(r.string()) + case 'Z': + cn.processReadyForQuery(r) + if res == nil && err == nil { + err = errUnexpectedReady + } + // done + return + case 'E': + err = parseError(r) + case 'I': + res = emptyRows + case 'T', 'D': + // ignore any results + default: + cn.bad = true + errorf("unknown response for simple query: %q", t) + } + } +} + +func (cn *conn) simpleQuery(q string) (res *rows, err error) { + defer cn.errRecover(&err) + + b := cn.writeBuf('Q') + b.string(q) + cn.send(b) + + for { + t, r := cn.recv1() + switch t { + case 'C', 'I': + // We allow queries which don't return any results through Query as + // well as Exec. We still have to give database/sql a rows object + // the user can close, though, to avoid connections from being + // leaked. A "rows" with done=true works fine for that purpose. + if err != nil { + cn.bad = true + errorf("unexpected message %q in simple query execution", t) + } + if res == nil { + res = &rows{ + cn: cn, + } + } + // Set the result and tag to the last command complete if there wasn't a + // query already run. Although queries usually return from here and cede + // control to Next, a query with zero results does not. + if t == 'C' && res.colNames == nil { + res.result, res.tag = cn.parseComplete(r.string()) + } + res.done = true + case 'Z': + cn.processReadyForQuery(r) + // done + return + case 'E': + res = nil + err = parseError(r) + case 'D': + if res == nil { + cn.bad = true + errorf("unexpected DataRow in simple query execution") + } + // the query didn't fail; kick off to Next + cn.saveMessage(t, r) + return + case 'T': + // res might be non-nil here if we received a previous + // CommandComplete, but that's fine; just overwrite it + res = &rows{cn: cn} + res.rowsHeader = parsePortalRowDescribe(r) + + // To work around a bug in QueryRow in Go 1.2 and earlier, wait + // until the first DataRow has been received. + default: + cn.bad = true + errorf("unknown response for simple query: %q", t) + } + } +} + +type noRows struct{} + +var emptyRows noRows + +var _ driver.Result = noRows{} + +func (noRows) LastInsertId() (int64, error) { + return 0, errNoLastInsertID +} + +func (noRows) RowsAffected() (int64, error) { + return 0, errNoRowsAffected +} + +// Decides which column formats to use for a prepared statement. The input is +// an array of type oids, one element per result column. +func decideColumnFormats(colTyps []fieldDesc, forceText bool) (colFmts []format, colFmtData []byte) { + if len(colTyps) == 0 { + return nil, colFmtDataAllText + } + + colFmts = make([]format, len(colTyps)) + if forceText { + return colFmts, colFmtDataAllText + } + + allBinary := true + allText := true + for i, t := range colTyps { + switch t.OID { + // This is the list of types to use binary mode for when receiving them + // through a prepared statement. If a type appears in this list, it + // must also be implemented in binaryDecode in encode.go. + case oid.T_bytea: + fallthrough + case oid.T_int8: + fallthrough + case oid.T_int4: + fallthrough + case oid.T_int2: + fallthrough + case oid.T_uuid: + colFmts[i] = formatBinary + allText = false + + default: + allBinary = false + } + } + + if allBinary { + return colFmts, colFmtDataAllBinary + } else if allText { + return colFmts, colFmtDataAllText + } else { + colFmtData = make([]byte, 2+len(colFmts)*2) + binary.BigEndian.PutUint16(colFmtData, uint16(len(colFmts))) + for i, v := range colFmts { + binary.BigEndian.PutUint16(colFmtData[2+i*2:], uint16(v)) + } + return colFmts, colFmtData + } +} + +func (cn *conn) prepareTo(q, stmtName string) *stmt { + st := &stmt{cn: cn, name: stmtName} + + b := cn.writeBuf('P') + b.string(st.name) + b.string(q) + b.int16(0) + + b.next('D') + b.byte('S') + b.string(st.name) + + b.next('S') + cn.send(b) + + cn.readParseResponse() + st.paramTyps, st.colNames, st.colTyps = cn.readStatementDescribeResponse() + st.colFmts, st.colFmtData = decideColumnFormats(st.colTyps, cn.disablePreparedBinaryResult) + cn.readReadyForQuery() + return st +} + +func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) { + if cn.bad { + return nil, driver.ErrBadConn + } + defer cn.errRecover(&err) + + if len(q) >= 4 && strings.EqualFold(q[:4], "COPY") { + s, err := cn.prepareCopyIn(q) + if err == nil { + cn.inCopy = true + } + return s, err + } + return cn.prepareTo(q, cn.gname()), nil +} + +func (cn *conn) Close() (err error) { + // Skip cn.bad return here because we always want to close a connection. + defer cn.errRecover(&err) + + // Ensure that cn.c.Close is always run. Since error handling is done with + // panics and cn.errRecover, the Close must be in a defer. + defer func() { + cerr := cn.c.Close() + if err == nil { + err = cerr + } + }() + + // Don't go through send(); ListenerConn relies on us not scribbling on the + // scratch buffer of this connection. + return cn.sendSimpleMessage('X') +} + +// Implement the "Queryer" interface +func (cn *conn) Query(query string, args []driver.Value) (driver.Rows, error) { + return cn.query(query, args) +} + +func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) { + if cn.bad { + return nil, driver.ErrBadConn + } + if cn.inCopy { + return nil, errCopyInProgress + } + defer cn.errRecover(&err) + + // Check to see if we can use the "simpleQuery" interface, which is + // *much* faster than going through prepare/exec + if len(args) == 0 { + return cn.simpleQuery(query) + } + + if cn.binaryParameters { + cn.sendBinaryModeQuery(query, args) + + cn.readParseResponse() + cn.readBindResponse() + rows := &rows{cn: cn} + rows.rowsHeader = cn.readPortalDescribeResponse() + cn.postExecuteWorkaround() + return rows, nil + } + st := cn.prepareTo(query, "") + st.exec(args) + return &rows{ + cn: cn, + rowsHeader: st.rowsHeader, + }, nil +} + +// Implement the optional "Execer" interface for one-shot queries +func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) { + if cn.bad { + return nil, driver.ErrBadConn + } + defer cn.errRecover(&err) + + // Check to see if we can use the "simpleExec" interface, which is + // *much* faster than going through prepare/exec + if len(args) == 0 { + // ignore commandTag, our caller doesn't care + r, _, err := cn.simpleExec(query) + return r, err + } + + if cn.binaryParameters { + cn.sendBinaryModeQuery(query, args) + + cn.readParseResponse() + cn.readBindResponse() + cn.readPortalDescribeResponse() + cn.postExecuteWorkaround() + res, _, err = cn.readExecuteResponse("Execute") + return res, err + } + // Use the unnamed statement to defer planning until bind + // time, or else value-based selectivity estimates cannot be + // used. + st := cn.prepareTo(query, "") + r, err := st.Exec(args) + if err != nil { + panic(err) + } + return r, err +} + +func (cn *conn) send(m *writeBuf) { + _, err := cn.c.Write(m.wrap()) + if err != nil { + panic(err) + } +} + +func (cn *conn) sendStartupPacket(m *writeBuf) error { + _, err := cn.c.Write((m.wrap())[1:]) + return err +} + +// Send a message of type typ to the server on the other end of cn. The +// message should have no payload. This method does not use the scratch +// buffer. +func (cn *conn) sendSimpleMessage(typ byte) (err error) { + _, err = cn.c.Write([]byte{typ, '\x00', '\x00', '\x00', '\x04'}) + return err +} + +// saveMessage memorizes a message and its buffer in the conn struct. +// recvMessage will then return these values on the next call to it. This +// method is useful in cases where you have to see what the next message is +// going to be (e.g. to see whether it's an error or not) but you can't handle +// the message yourself. +func (cn *conn) saveMessage(typ byte, buf *readBuf) { + if cn.saveMessageType != 0 { + cn.bad = true + errorf("unexpected saveMessageType %d", cn.saveMessageType) + } + cn.saveMessageType = typ + cn.saveMessageBuffer = *buf +} + +// recvMessage receives any message from the backend, or returns an error if +// a problem occurred while reading the message. +func (cn *conn) recvMessage(r *readBuf) (byte, error) { + // workaround for a QueryRow bug, see exec + if cn.saveMessageType != 0 { + t := cn.saveMessageType + *r = cn.saveMessageBuffer + cn.saveMessageType = 0 + cn.saveMessageBuffer = nil + return t, nil + } + + x := cn.scratch[:5] + _, err := io.ReadFull(cn.buf, x) + if err != nil { + return 0, err + } + + // read the type and length of the message that follows + t := x[0] + n := int(binary.BigEndian.Uint32(x[1:])) - 4 + var y []byte + if n <= len(cn.scratch) { + y = cn.scratch[:n] + } else { + y = make([]byte, n) + } + _, err = io.ReadFull(cn.buf, y) + if err != nil { + return 0, err + } + *r = y + return t, nil +} + +// recv receives a message from the backend, but if an error happened while +// reading the message or the received message was an ErrorResponse, it panics. +// NoticeResponses are ignored. This function should generally be used only +// during the startup sequence. +func (cn *conn) recv() (t byte, r *readBuf) { + for { + var err error + r = &readBuf{} + t, err = cn.recvMessage(r) + if err != nil { + panic(err) + } + switch t { + case 'E': + panic(parseError(r)) + case 'N': + // ignore + default: + return + } + } +} + +// recv1Buf is exactly equivalent to recv1, except it uses a buffer supplied by +// the caller to avoid an allocation. +func (cn *conn) recv1Buf(r *readBuf) byte { + for { + t, err := cn.recvMessage(r) + if err != nil { + panic(err) + } + + switch t { + case 'A', 'N': + // ignore + case 'S': + cn.processParameterStatus(r) + default: + return t + } + } +} + +// recv1 receives a message from the backend, panicking if an error occurs +// while attempting to read it. All asynchronous messages are ignored, with +// the exception of ErrorResponse. +func (cn *conn) recv1() (t byte, r *readBuf) { + r = &readBuf{} + t = cn.recv1Buf(r) + return t, r +} + +func (cn *conn) ssl(o values) error { + upgrade, err := ssl(o) + if err != nil { + return err + } + + if upgrade == nil { + // Nothing to do + return nil + } + + w := cn.writeBuf(0) + w.int32(80877103) + if err = cn.sendStartupPacket(w); err != nil { + return err + } + + b := cn.scratch[:1] + _, err = io.ReadFull(cn.c, b) + if err != nil { + return err + } + + if b[0] != 'S' { + return ErrSSLNotSupported + } + + cn.c, err = upgrade(cn.c) + return err +} + +// isDriverSetting returns true iff a setting is purely for configuring the +// driver's options and should not be sent to the server in the connection +// startup packet. +func isDriverSetting(key string) bool { + switch key { + case "host", "port": + return true + case "password": + return true + case "sslmode", "sslcert", "sslkey", "sslrootcert": + return true + case "fallback_application_name": + return true + case "connect_timeout": + return true + case "disable_prepared_binary_result": + return true + case "binary_parameters": + return true + + default: + return false + } +} + +func (cn *conn) startup(o values) { + w := cn.writeBuf(0) + w.int32(196608) + // Send the backend the name of the database we want to connect to, and the + // user we want to connect as. Additionally, we send over any run-time + // parameters potentially included in the connection string. If the server + // doesn't recognize any of them, it will reply with an error. + for k, v := range o { + if isDriverSetting(k) { + // skip options which can't be run-time parameters + continue + } + // The protocol requires us to supply the database name as "database" + // instead of "dbname". + if k == "dbname" { + k = "database" + } + w.string(k) + w.string(v) + } + w.string("") + if err := cn.sendStartupPacket(w); err != nil { + panic(err) + } + + for { + t, r := cn.recv() + switch t { + case 'K': + cn.processBackendKeyData(r) + case 'S': + cn.processParameterStatus(r) + case 'R': + cn.auth(r, o) + case 'Z': + cn.processReadyForQuery(r) + return + default: + errorf("unknown response for startup: %q", t) + } + } +} + +func (cn *conn) auth(r *readBuf, o values) { + switch code := r.int32(); code { + case 0: + // OK + case 3: + w := cn.writeBuf('p') + w.string(o["password"]) + cn.send(w) + + t, r := cn.recv() + if t != 'R' { + errorf("unexpected password response: %q", t) + } + + if r.int32() != 0 { + errorf("unexpected authentication response: %q", t) + } + case 5: + s := string(r.next(4)) + w := cn.writeBuf('p') + w.string("md5" + md5s(md5s(o["password"]+o["user"])+s)) + cn.send(w) + + t, r := cn.recv() + if t != 'R' { + errorf("unexpected password response: %q", t) + } + + if r.int32() != 0 { + errorf("unexpected authentication response: %q", t) + } + case 10: + sc := scram.NewClient(sha256.New, o["user"], o["password"]) + sc.Step(nil) + if sc.Err() != nil { + errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) + } + scOut := sc.Out() + + w := cn.writeBuf('p') + w.string("SCRAM-SHA-256") + w.int32(len(scOut)) + w.bytes(scOut) + cn.send(w) + + t, r := cn.recv() + if t != 'R' { + errorf("unexpected password response: %q", t) + } + + if r.int32() != 11 { + errorf("unexpected authentication response: %q", t) + } + + nextStep := r.next(len(*r)) + sc.Step(nextStep) + if sc.Err() != nil { + errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) + } + + scOut = sc.Out() + w = cn.writeBuf('p') + w.bytes(scOut) + cn.send(w) + + t, r = cn.recv() + if t != 'R' { + errorf("unexpected password response: %q", t) + } + + if r.int32() != 12 { + errorf("unexpected authentication response: %q", t) + } + + nextStep = r.next(len(*r)) + sc.Step(nextStep) + if sc.Err() != nil { + errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) + } + + default: + errorf("unknown authentication response: %d", code) + } +} + +type format int + +const formatText format = 0 +const formatBinary format = 1 + +// One result-column format code with the value 1 (i.e. all binary). +var colFmtDataAllBinary = []byte{0, 1, 0, 1} + +// No result-column format codes (i.e. all text). +var colFmtDataAllText = []byte{0, 0} + +type stmt struct { + cn *conn + name string + rowsHeader + colFmtData []byte + paramTyps []oid.Oid + closed bool +} + +func (st *stmt) Close() (err error) { + if st.closed { + return nil + } + if st.cn.bad { + return driver.ErrBadConn + } + defer st.cn.errRecover(&err) + + w := st.cn.writeBuf('C') + w.byte('S') + w.string(st.name) + st.cn.send(w) + + st.cn.send(st.cn.writeBuf('S')) + + t, _ := st.cn.recv1() + if t != '3' { + st.cn.bad = true + errorf("unexpected close response: %q", t) + } + st.closed = true + + t, r := st.cn.recv1() + if t != 'Z' { + st.cn.bad = true + errorf("expected ready for query, but got: %q", t) + } + st.cn.processReadyForQuery(r) + + return nil +} + +func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { + if st.cn.bad { + return nil, driver.ErrBadConn + } + defer st.cn.errRecover(&err) + + st.exec(v) + return &rows{ + cn: st.cn, + rowsHeader: st.rowsHeader, + }, nil +} + +func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) { + if st.cn.bad { + return nil, driver.ErrBadConn + } + defer st.cn.errRecover(&err) + + st.exec(v) + res, _, err = st.cn.readExecuteResponse("simple query") + return res, err +} + +func (st *stmt) exec(v []driver.Value) { + if len(v) >= 65536 { + errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(v)) + } + if len(v) != len(st.paramTyps) { + errorf("got %d parameters but the statement requires %d", len(v), len(st.paramTyps)) + } + + cn := st.cn + w := cn.writeBuf('B') + w.byte(0) // unnamed portal + w.string(st.name) + + if cn.binaryParameters { + cn.sendBinaryParameters(w, v) + } else { + w.int16(0) + w.int16(len(v)) + for i, x := range v { + if x == nil { + w.int32(-1) + } else { + b := encode(&cn.parameterStatus, x, st.paramTyps[i]) + w.int32(len(b)) + w.bytes(b) + } + } + } + w.bytes(st.colFmtData) + + w.next('E') + w.byte(0) + w.int32(0) + + w.next('S') + cn.send(w) + + cn.readBindResponse() + cn.postExecuteWorkaround() + +} + +func (st *stmt) NumInput() int { + return len(st.paramTyps) +} + +// parseComplete parses the "command tag" from a CommandComplete message, and +// returns the number of rows affected (if applicable) and a string +// identifying only the command that was executed, e.g. "ALTER TABLE". If the +// command tag could not be parsed, parseComplete panics. +func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { + commandsWithAffectedRows := []string{ + "SELECT ", + // INSERT is handled below + "UPDATE ", + "DELETE ", + "FETCH ", + "MOVE ", + "COPY ", + } + + var affectedRows *string + for _, tag := range commandsWithAffectedRows { + if strings.HasPrefix(commandTag, tag) { + t := commandTag[len(tag):] + affectedRows = &t + commandTag = tag[:len(tag)-1] + break + } + } + // INSERT also includes the oid of the inserted row in its command tag. + // Oids in user tables are deprecated, and the oid is only returned when + // exactly one row is inserted, so it's unlikely to be of value to any + // real-world application and we can ignore it. + if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") { + parts := strings.Split(commandTag, " ") + if len(parts) != 3 { + cn.bad = true + errorf("unexpected INSERT command tag %s", commandTag) + } + affectedRows = &parts[len(parts)-1] + commandTag = "INSERT" + } + // There should be no affected rows attached to the tag, just return it + if affectedRows == nil { + return driver.RowsAffected(0), commandTag + } + n, err := strconv.ParseInt(*affectedRows, 10, 64) + if err != nil { + cn.bad = true + errorf("could not parse commandTag: %s", err) + } + return driver.RowsAffected(n), commandTag +} + +type rowsHeader struct { + colNames []string + colTyps []fieldDesc + colFmts []format +} + +type rows struct { + cn *conn + finish func() + rowsHeader + done bool + rb readBuf + result driver.Result + tag string + + next *rowsHeader +} + +func (rs *rows) Close() error { + if finish := rs.finish; finish != nil { + defer finish() + } + // no need to look at cn.bad as Next() will + for { + err := rs.Next(nil) + switch err { + case nil: + case io.EOF: + // rs.Next can return io.EOF on both 'Z' (ready for query) and 'T' (row + // description, used with HasNextResultSet). We need to fetch messages until + // we hit a 'Z', which is done by waiting for done to be set. + if rs.done { + return nil + } + default: + return err + } + } +} + +func (rs *rows) Columns() []string { + return rs.colNames +} + +func (rs *rows) Result() driver.Result { + if rs.result == nil { + return emptyRows + } + return rs.result +} + +func (rs *rows) Tag() string { + return rs.tag +} + +func (rs *rows) Next(dest []driver.Value) (err error) { + if rs.done { + return io.EOF + } + + conn := rs.cn + if conn.bad { + return driver.ErrBadConn + } + defer conn.errRecover(&err) + + for { + t := conn.recv1Buf(&rs.rb) + switch t { + case 'E': + err = parseError(&rs.rb) + case 'C', 'I': + if t == 'C' { + rs.result, rs.tag = conn.parseComplete(rs.rb.string()) + } + continue + case 'Z': + conn.processReadyForQuery(&rs.rb) + rs.done = true + if err != nil { + return err + } + return io.EOF + case 'D': + n := rs.rb.int16() + if err != nil { + conn.bad = true + errorf("unexpected DataRow after error %s", err) + } + if n < len(dest) { + dest = dest[:n] + } + for i := range dest { + l := rs.rb.int32() + if l == -1 { + dest[i] = nil + continue + } + dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i].OID, rs.colFmts[i]) + } + return + case 'T': + next := parsePortalRowDescribe(&rs.rb) + rs.next = &next + return io.EOF + default: + errorf("unexpected message after execute: %q", t) + } + } +} + +func (rs *rows) HasNextResultSet() bool { + hasNext := rs.next != nil && !rs.done + return hasNext +} + +func (rs *rows) NextResultSet() error { + if rs.next == nil { + return io.EOF + } + rs.rowsHeader = *rs.next + rs.next = nil + return nil +} + +// QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be +// used as part of an SQL statement. For example: +// +// tblname := "my_table" +// data := "my_data" +// quoted := pq.QuoteIdentifier(tblname) +// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data) +// +// Any double quotes in name will be escaped. The quoted identifier will be +// case sensitive when used in a query. If the input string contains a zero +// byte, the result will be truncated immediately before it. +func QuoteIdentifier(name string) string { + end := strings.IndexRune(name, 0) + if end > -1 { + name = name[:end] + } + return `"` + strings.Replace(name, `"`, `""`, -1) + `"` +} + +// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal +// to DDL and other statements that do not accept parameters) to be used as part +// of an SQL statement. For example: +// +// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z") +// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date)) +// +// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be +// replaced by two backslashes (i.e. "\\") and the C-style escape identifier +// that PostgreSQL provides ('E') will be prepended to the string. +func QuoteLiteral(literal string) string { + // This follows the PostgreSQL internal algorithm for handling quoted literals + // from libpq, which can be found in the "PQEscapeStringInternal" function, + // which is found in the libpq/fe-exec.c source file: + // https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c + // + // substitute any single-quotes (') with two single-quotes ('') + literal = strings.Replace(literal, `'`, `''`, -1) + // determine if the string has any backslashes (\) in it. + // if it does, replace any backslashes (\) with two backslashes (\\) + // then, we need to wrap the entire string with a PostgreSQL + // C-style escape. Per how "PQEscapeStringInternal" handles this case, we + // also add a space before the "E" + if strings.Contains(literal, `\`) { + literal = strings.Replace(literal, `\`, `\\`, -1) + literal = ` E'` + literal + `'` + } else { + // otherwise, we can just wrap the literal with a pair of single quotes + literal = `'` + literal + `'` + } + return literal +} + +func md5s(s string) string { + h := md5.New() + h.Write([]byte(s)) + return fmt.Sprintf("%x", h.Sum(nil)) +} + +func (cn *conn) sendBinaryParameters(b *writeBuf, args []driver.Value) { + // Do one pass over the parameters to see if we're going to send any of + // them over in binary. If we are, create a paramFormats array at the + // same time. + var paramFormats []int + for i, x := range args { + _, ok := x.([]byte) + if ok { + if paramFormats == nil { + paramFormats = make([]int, len(args)) + } + paramFormats[i] = 1 + } + } + if paramFormats == nil { + b.int16(0) + } else { + b.int16(len(paramFormats)) + for _, x := range paramFormats { + b.int16(x) + } + } + + b.int16(len(args)) + for _, x := range args { + if x == nil { + b.int32(-1) + } else { + datum := binaryEncode(&cn.parameterStatus, x) + b.int32(len(datum)) + b.bytes(datum) + } + } +} + +func (cn *conn) sendBinaryModeQuery(query string, args []driver.Value) { + if len(args) >= 65536 { + errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(args)) + } + + b := cn.writeBuf('P') + b.byte(0) // unnamed statement + b.string(query) + b.int16(0) + + b.next('B') + b.int16(0) // unnamed portal and statement + cn.sendBinaryParameters(b, args) + b.bytes(colFmtDataAllText) + + b.next('D') + b.byte('P') + b.byte(0) // unnamed portal + + b.next('E') + b.byte(0) + b.int32(0) + + b.next('S') + cn.send(b) +} + +func (cn *conn) processParameterStatus(r *readBuf) { + var err error + + param := r.string() + switch param { + case "server_version": + var major1 int + var major2 int + var minor int + _, err = fmt.Sscanf(r.string(), "%d.%d.%d", &major1, &major2, &minor) + if err == nil { + cn.parameterStatus.serverVersion = major1*10000 + major2*100 + minor + } + + case "TimeZone": + cn.parameterStatus.currentLocation, err = time.LoadLocation(r.string()) + if err != nil { + cn.parameterStatus.currentLocation = nil + } + + default: + // ignore + } +} + +func (cn *conn) processReadyForQuery(r *readBuf) { + cn.txnStatus = transactionStatus(r.byte()) +} + +func (cn *conn) readReadyForQuery() { + t, r := cn.recv1() + switch t { + case 'Z': + cn.processReadyForQuery(r) + return + default: + cn.bad = true + errorf("unexpected message %q; expected ReadyForQuery", t) + } +} + +func (cn *conn) processBackendKeyData(r *readBuf) { + cn.processID = r.int32() + cn.secretKey = r.int32() +} + +func (cn *conn) readParseResponse() { + t, r := cn.recv1() + switch t { + case '1': + return + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Parse response %q", t) + } +} + +func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []fieldDesc) { + for { + t, r := cn.recv1() + switch t { + case 't': + nparams := r.int16() + paramTyps = make([]oid.Oid, nparams) + for i := range paramTyps { + paramTyps[i] = r.oid() + } + case 'n': + return paramTyps, nil, nil + case 'T': + colNames, colTyps = parseStatementRowDescribe(r) + return paramTyps, colNames, colTyps + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Describe statement response %q", t) + } + } +} + +func (cn *conn) readPortalDescribeResponse() rowsHeader { + t, r := cn.recv1() + switch t { + case 'T': + return parsePortalRowDescribe(r) + case 'n': + return rowsHeader{} + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Describe response %q", t) + } + panic("not reached") +} + +func (cn *conn) readBindResponse() { + t, r := cn.recv1() + switch t { + case '2': + return + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Bind response %q", t) + } +} + +func (cn *conn) postExecuteWorkaround() { + // Work around a bug in sql.DB.QueryRow: in Go 1.2 and earlier it ignores + // any errors from rows.Next, which masks errors that happened during the + // execution of the query. To avoid the problem in common cases, we wait + // here for one more message from the database. If it's not an error the + // query will likely succeed (or perhaps has already, if it's a + // CommandComplete), so we push the message into the conn struct; recv1 + // will return it as the next message for rows.Next or rows.Close. + // However, if it's an error, we wait until ReadyForQuery and then return + // the error to our caller. + for { + t, r := cn.recv1() + switch t { + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + case 'C', 'D', 'I': + // the query didn't fail, but we can't process this message + cn.saveMessage(t, r) + return + default: + cn.bad = true + errorf("unexpected message during extended query execution: %q", t) + } + } +} + +// Only for Exec(), since we ignore the returned data +func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, commandTag string, err error) { + for { + t, r := cn.recv1() + switch t { + case 'C': + if err != nil { + cn.bad = true + errorf("unexpected CommandComplete after error %s", err) + } + res, commandTag = cn.parseComplete(r.string()) + case 'Z': + cn.processReadyForQuery(r) + if res == nil && err == nil { + err = errUnexpectedReady + } + return res, commandTag, err + case 'E': + err = parseError(r) + case 'T', 'D', 'I': + if err != nil { + cn.bad = true + errorf("unexpected %q after error %s", t, err) + } + if t == 'I' { + res = emptyRows + } + // ignore any results + default: + cn.bad = true + errorf("unknown %s response: %q", protocolState, t) + } + } +} + +func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []fieldDesc) { + n := r.int16() + colNames = make([]string, n) + colTyps = make([]fieldDesc, n) + for i := range colNames { + colNames[i] = r.string() + r.next(6) + colTyps[i].OID = r.oid() + colTyps[i].Len = r.int16() + colTyps[i].Mod = r.int32() + // format code not known when describing a statement; always 0 + r.next(2) + } + return +} + +func parsePortalRowDescribe(r *readBuf) rowsHeader { + n := r.int16() + colNames := make([]string, n) + colFmts := make([]format, n) + colTyps := make([]fieldDesc, n) + for i := range colNames { + colNames[i] = r.string() + r.next(6) + colTyps[i].OID = r.oid() + colTyps[i].Len = r.int16() + colTyps[i].Mod = r.int32() + colFmts[i] = format(r.int16()) + } + return rowsHeader{ + colNames: colNames, + colFmts: colFmts, + colTyps: colTyps, + } +} + +// parseEnviron tries to mimic some of libpq's environment handling +// +// To ease testing, it does not directly reference os.Environ, but is +// designed to accept its output. +// +// Environment-set connection information is intended to have a higher +// precedence than a library default but lower than any explicitly +// passed information (such as in the URL or connection string). +func parseEnviron(env []string) (out map[string]string) { + out = make(map[string]string) + + for _, v := range env { + parts := strings.SplitN(v, "=", 2) + + accrue := func(keyname string) { + out[keyname] = parts[1] + } + unsupported := func() { + panic(fmt.Sprintf("setting %v not supported", parts[0])) + } + + // The order of these is the same as is seen in the + // PostgreSQL 9.1 manual. Unsupported but well-defined + // keys cause a panic; these should be unset prior to + // execution. Options which pq expects to be set to a + // certain value are allowed, but must be set to that + // value if present (they can, of course, be absent). + switch parts[0] { + case "PGHOST": + accrue("host") + case "PGHOSTADDR": + unsupported() + case "PGPORT": + accrue("port") + case "PGDATABASE": + accrue("dbname") + case "PGUSER": + accrue("user") + case "PGPASSWORD": + accrue("password") + case "PGSERVICE", "PGSERVICEFILE", "PGREALM": + unsupported() + case "PGOPTIONS": + accrue("options") + case "PGAPPNAME": + accrue("application_name") + case "PGSSLMODE": + accrue("sslmode") + case "PGSSLCERT": + accrue("sslcert") + case "PGSSLKEY": + accrue("sslkey") + case "PGSSLROOTCERT": + accrue("sslrootcert") + case "PGREQUIRESSL", "PGSSLCRL": + unsupported() + case "PGREQUIREPEER": + unsupported() + case "PGKRBSRVNAME", "PGGSSLIB": + unsupported() + case "PGCONNECT_TIMEOUT": + accrue("connect_timeout") + case "PGCLIENTENCODING": + accrue("client_encoding") + case "PGDATESTYLE": + accrue("datestyle") + case "PGTZ": + accrue("timezone") + case "PGGEQO": + accrue("geqo") + case "PGSYSCONFDIR", "PGLOCALEDIR": + unsupported() + } + } + + return out +} + +// isUTF8 returns whether name is a fuzzy variation of the string "UTF-8". +func isUTF8(name string) bool { + // Recognize all sorts of silly things as "UTF-8", like Postgres does + s := strings.Map(alnumLowerASCII, name) + return s == "utf8" || s == "unicode" +} + +func alnumLowerASCII(ch rune) rune { + if 'A' <= ch && ch <= 'Z' { + return ch + ('a' - 'A') + } + if 'a' <= ch && ch <= 'z' || '0' <= ch && ch <= '9' { + return ch + } + return -1 // discard +} diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go new file mode 100644 index 00000000..0fdd06a6 --- /dev/null +++ b/vendor/github.com/lib/pq/conn_go18.go @@ -0,0 +1,149 @@ +package pq + +import ( + "context" + "database/sql" + "database/sql/driver" + "fmt" + "io" + "io/ioutil" + "time" +) + +// Implement the "QueryerContext" interface +func (cn *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { + list := make([]driver.Value, len(args)) + for i, nv := range args { + list[i] = nv.Value + } + finish := cn.watchCancel(ctx) + r, err := cn.query(query, list) + if err != nil { + if finish != nil { + finish() + } + return nil, err + } + r.finish = finish + return r, nil +} + +// Implement the "ExecerContext" interface +func (cn *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { + list := make([]driver.Value, len(args)) + for i, nv := range args { + list[i] = nv.Value + } + + if finish := cn.watchCancel(ctx); finish != nil { + defer finish() + } + + return cn.Exec(query, list) +} + +// Implement the "ConnBeginTx" interface +func (cn *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { + var mode string + + switch sql.IsolationLevel(opts.Isolation) { + case sql.LevelDefault: + // Don't touch mode: use the server's default + case sql.LevelReadUncommitted: + mode = " ISOLATION LEVEL READ UNCOMMITTED" + case sql.LevelReadCommitted: + mode = " ISOLATION LEVEL READ COMMITTED" + case sql.LevelRepeatableRead: + mode = " ISOLATION LEVEL REPEATABLE READ" + case sql.LevelSerializable: + mode = " ISOLATION LEVEL SERIALIZABLE" + default: + return nil, fmt.Errorf("pq: isolation level not supported: %d", opts.Isolation) + } + + if opts.ReadOnly { + mode += " READ ONLY" + } else { + mode += " READ WRITE" + } + + tx, err := cn.begin(mode) + if err != nil { + return nil, err + } + cn.txnFinish = cn.watchCancel(ctx) + return tx, nil +} + +func (cn *conn) Ping(ctx context.Context) error { + if finish := cn.watchCancel(ctx); finish != nil { + defer finish() + } + rows, err := cn.simpleQuery("SELECT 'lib/pq ping test';") + if err != nil { + return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger + } + rows.Close() + return nil +} + +func (cn *conn) watchCancel(ctx context.Context) func() { + if done := ctx.Done(); done != nil { + finished := make(chan struct{}) + go func() { + select { + case <-done: + // At this point the function level context is canceled, + // so it must not be used for the additional network + // request to cancel the query. + // Create a new context to pass into the dial. + ctxCancel, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + _ = cn.cancel(ctxCancel) + finished <- struct{}{} + case <-finished: + } + }() + return func() { + select { + case <-finished: + case finished <- struct{}{}: + } + } + } + return nil +} + +func (cn *conn) cancel(ctx context.Context) error { + c, err := dial(ctx, cn.dialer, cn.opts) + if err != nil { + return err + } + defer c.Close() + + { + can := conn{ + c: c, + } + err = can.ssl(cn.opts) + if err != nil { + return err + } + + w := can.writeBuf(0) + w.int32(80877102) // cancel request code + w.int32(cn.processID) + w.int32(cn.secretKey) + + if err := can.sendStartupPacket(w); err != nil { + return err + } + } + + // Read until EOF to ensure that the server received the cancel. + { + _, err := io.Copy(ioutil.Discard, c) + return err + } +} diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go new file mode 100644 index 00000000..2f8ced67 --- /dev/null +++ b/vendor/github.com/lib/pq/connector.go @@ -0,0 +1,110 @@ +package pq + +import ( + "context" + "database/sql/driver" + "errors" + "fmt" + "os" + "strings" +) + +// Connector represents a fixed configuration for the pq driver with a given +// name. Connector satisfies the database/sql/driver Connector interface and +// can be used to create any number of DB Conn's via the database/sql OpenDB +// function. +// +// See https://golang.org/pkg/database/sql/driver/#Connector. +// See https://golang.org/pkg/database/sql/#OpenDB. +type Connector struct { + opts values + dialer Dialer +} + +// Connect returns a connection to the database using the fixed configuration +// of this Connector. Context is not used. +func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) { + return c.open(ctx) +} + +// Driver returnst the underlying driver of this Connector. +func (c *Connector) Driver() driver.Driver { + return &Driver{} +} + +// NewConnector returns a connector for the pq driver in a fixed configuration +// with the given dsn. The returned connector can be used to create any number +// of equivalent Conn's. The returned connector is intended to be used with +// database/sql.OpenDB. +// +// See https://golang.org/pkg/database/sql/driver/#Connector. +// See https://golang.org/pkg/database/sql/#OpenDB. +func NewConnector(dsn string) (*Connector, error) { + var err error + o := make(values) + + // A number of defaults are applied here, in this order: + // + // * Very low precedence defaults applied in every situation + // * Environment variables + // * Explicitly passed connection information + o["host"] = "localhost" + o["port"] = "5432" + // N.B.: Extra float digits should be set to 3, but that breaks + // Postgres 8.4 and older, where the max is 2. + o["extra_float_digits"] = "2" + for k, v := range parseEnviron(os.Environ()) { + o[k] = v + } + + if strings.HasPrefix(dsn, "postgres://") || strings.HasPrefix(dsn, "postgresql://") { + dsn, err = ParseURL(dsn) + if err != nil { + return nil, err + } + } + + if err := parseOpts(dsn, o); err != nil { + return nil, err + } + + // Use the "fallback" application name if necessary + if fallback, ok := o["fallback_application_name"]; ok { + if _, ok := o["application_name"]; !ok { + o["application_name"] = fallback + } + } + + // We can't work with any client_encoding other than UTF-8 currently. + // However, we have historically allowed the user to set it to UTF-8 + // explicitly, and there's no reason to break such programs, so allow that. + // Note that the "options" setting could also set client_encoding, but + // parsing its value is not worth it. Instead, we always explicitly send + // client_encoding as a separate run-time parameter, which should override + // anything set in options. + if enc, ok := o["client_encoding"]; ok && !isUTF8(enc) { + return nil, errors.New("client_encoding must be absent or 'UTF8'") + } + o["client_encoding"] = "UTF8" + // DateStyle needs a similar treatment. + if datestyle, ok := o["datestyle"]; ok { + if datestyle != "ISO, MDY" { + return nil, fmt.Errorf("setting datestyle must be absent or %v; got %v", "ISO, MDY", datestyle) + } + } else { + o["datestyle"] = "ISO, MDY" + } + + // If a user is not provided by any other means, the last + // resort is to use the current operating system provided user + // name. + if _, ok := o["user"]; !ok { + u, err := userCurrent() + if err != nil { + return nil, err + } + o["user"] = u + } + + return &Connector{opts: o, dialer: defaultDialer{}}, nil +} diff --git a/vendor/github.com/lib/pq/doc.go b/vendor/github.com/lib/pq/doc.go new file mode 100644 index 00000000..2a60054e --- /dev/null +++ b/vendor/github.com/lib/pq/doc.go @@ -0,0 +1,245 @@ +/* +Package pq is a pure Go Postgres driver for the database/sql package. + +In most cases clients will use the database/sql package instead of +using this package directly. For example: + + import ( + "database/sql" + + _ "github.com/lib/pq" + ) + + func main() { + connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full" + db, err := sql.Open("postgres", connStr) + if err != nil { + log.Fatal(err) + } + + age := 21 + rows, err := db.Query("SELECT name FROM users WHERE age = $1", age) + … + } + +You can also connect to a database using a URL. For example: + + connStr := "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full" + db, err := sql.Open("postgres", connStr) + + +Connection String Parameters + + +Similarly to libpq, when establishing a connection using pq you are expected to +supply a connection string containing zero or more parameters. +A subset of the connection parameters supported by libpq are also supported by pq. +Additionally, pq also lets you specify run-time parameters (such as search_path or work_mem) +directly in the connection string. This is different from libpq, which does not allow +run-time parameters in the connection string, instead requiring you to supply +them in the options parameter. + +For compatibility with libpq, the following special connection parameters are +supported: + + * dbname - The name of the database to connect to + * user - The user to sign in as + * password - The user's password + * host - The host to connect to. Values that start with / are for unix + domain sockets. (default is localhost) + * port - The port to bind to. (default is 5432) + * sslmode - Whether or not to use SSL (default is require, this is not + the default for libpq) + * fallback_application_name - An application_name to fall back to if one isn't provided. + * connect_timeout - Maximum wait for connection, in seconds. Zero or + not specified means wait indefinitely. + * sslcert - Cert file location. The file must contain PEM encoded data. + * sslkey - Key file location. The file must contain PEM encoded data. + * sslrootcert - The location of the root certificate file. The file + must contain PEM encoded data. + +Valid values for sslmode are: + + * disable - No SSL + * require - Always SSL (skip verification) + * verify-ca - Always SSL (verify that the certificate presented by the + server was signed by a trusted CA) + * verify-full - Always SSL (verify that the certification presented by + the server was signed by a trusted CA and the server host name + matches the one in the certificate) + +See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING +for more information about connection string parameters. + +Use single quotes for values that contain whitespace: + + "user=pqgotest password='with spaces'" + +A backslash will escape the next character in values: + + "user=space\ man password='it\'s valid'" + +Note that the connection parameter client_encoding (which sets the +text encoding for the connection) may be set but must be "UTF8", +matching with the same rules as Postgres. It is an error to provide +any other value. + +In addition to the parameters listed above, any run-time parameter that can be +set at backend start time can be set in the connection string. For more +information, see +http://www.postgresql.org/docs/current/static/runtime-config.html. + +Most environment variables as specified at http://www.postgresql.org/docs/current/static/libpq-envars.html +supported by libpq are also supported by pq. If any of the environment +variables not supported by pq are set, pq will panic during connection +establishment. Environment variables have a lower precedence than explicitly +provided connection parameters. + +The pgpass mechanism as described in http://www.postgresql.org/docs/current/static/libpq-pgpass.html +is supported, but on Windows PGPASSFILE must be specified explicitly. + + +Queries + + +database/sql does not dictate any specific format for parameter +markers in query strings, and pq uses the Postgres-native ordinal markers, +as shown above. The same marker can be reused for the same parameter: + + rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1 + OR age BETWEEN $2 AND $2 + 3`, "orange", 64) + +pq does not support the LastInsertId() method of the Result type in database/sql. +To return the identifier of an INSERT (or UPDATE or DELETE), use the Postgres +RETURNING clause with a standard Query or QueryRow call: + + var userid int + err := db.QueryRow(`INSERT INTO users(name, favorite_fruit, age) + VALUES('beatrice', 'starfruit', 93) RETURNING id`).Scan(&userid) + +For more details on RETURNING, see the Postgres documentation: + + http://www.postgresql.org/docs/current/static/sql-insert.html + http://www.postgresql.org/docs/current/static/sql-update.html + http://www.postgresql.org/docs/current/static/sql-delete.html + +For additional instructions on querying see the documentation for the database/sql package. + + +Data Types + + +Parameters pass through driver.DefaultParameterConverter before they are handled +by this package. When the binary_parameters connection option is enabled, +[]byte values are sent directly to the backend as data in binary format. + +This package returns the following types for values from the PostgreSQL backend: + + - integer types smallint, integer, and bigint are returned as int64 + - floating-point types real and double precision are returned as float64 + - character types char, varchar, and text are returned as string + - temporal types date, time, timetz, timestamp, and timestamptz are + returned as time.Time + - the boolean type is returned as bool + - the bytea type is returned as []byte + +All other types are returned directly from the backend as []byte values in text format. + + +Errors + + +pq may return errors of type *pq.Error which can be interrogated for error details: + + if err, ok := err.(*pq.Error); ok { + fmt.Println("pq error:", err.Code.Name()) + } + +See the pq.Error type for details. + + +Bulk imports + +You can perform bulk imports by preparing a statement returned by pq.CopyIn (or +pq.CopyInSchema) in an explicit transaction (sql.Tx). The returned statement +handle can then be repeatedly "executed" to copy data into the target table. +After all data has been processed you should call Exec() once with no arguments +to flush all buffered data. Any call to Exec() might return an error which +should be handled appropriately, but because of the internal buffering an error +returned by Exec() might not be related to the data passed in the call that +failed. + +CopyIn uses COPY FROM internally. It is not possible to COPY outside of an +explicit transaction in pq. + +Usage example: + + txn, err := db.Begin() + if err != nil { + log.Fatal(err) + } + + stmt, err := txn.Prepare(pq.CopyIn("users", "name", "age")) + if err != nil { + log.Fatal(err) + } + + for _, user := range users { + _, err = stmt.Exec(user.Name, int64(user.Age)) + if err != nil { + log.Fatal(err) + } + } + + _, err = stmt.Exec() + if err != nil { + log.Fatal(err) + } + + err = stmt.Close() + if err != nil { + log.Fatal(err) + } + + err = txn.Commit() + if err != nil { + log.Fatal(err) + } + + +Notifications + + +PostgreSQL supports a simple publish/subscribe model over database +connections. See http://www.postgresql.org/docs/current/static/sql-notify.html +for more information about the general mechanism. + +To start listening for notifications, you first have to open a new connection +to the database by calling NewListener. This connection can not be used for +anything other than LISTEN / NOTIFY. Calling Listen will open a "notification +channel"; once a notification channel is open, a notification generated on that +channel will effect a send on the Listener.Notify channel. A notification +channel will remain open until Unlisten is called, though connection loss might +result in some notifications being lost. To solve this problem, Listener sends +a nil pointer over the Notify channel any time the connection is re-established +following a connection loss. The application can get information about the +state of the underlying connection by setting an event callback in the call to +NewListener. + +A single Listener can safely be used from concurrent goroutines, which means +that there is often no need to create more than one Listener in your +application. However, a Listener is always connected to a single database, so +you will need to create a new Listener instance for every database you want to +receive notifications in. + +The channel name in both Listen and Unlisten is case sensitive, and can contain +any characters legal in an identifier (see +http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS +for more information). Note that the channel name will be truncated to 63 +bytes by the PostgreSQL server. + +You can find a complete, working example of Listener usage at +https://godoc.org/github.com/lib/pq/example/listen. + +*/ +package pq diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go new file mode 100644 index 00000000..a6902fae --- /dev/null +++ b/vendor/github.com/lib/pq/encode.go @@ -0,0 +1,602 @@ +package pq + +import ( + "bytes" + "database/sql/driver" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "math" + "strconv" + "strings" + "sync" + "time" + + "github.com/lib/pq/oid" +) + +func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte { + switch v := x.(type) { + case []byte: + return v + default: + return encode(parameterStatus, x, oid.T_unknown) + } +} + +func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) []byte { + switch v := x.(type) { + case int64: + return strconv.AppendInt(nil, v, 10) + case float64: + return strconv.AppendFloat(nil, v, 'f', -1, 64) + case []byte: + if pgtypOid == oid.T_bytea { + return encodeBytea(parameterStatus.serverVersion, v) + } + + return v + case string: + if pgtypOid == oid.T_bytea { + return encodeBytea(parameterStatus.serverVersion, []byte(v)) + } + + return []byte(v) + case bool: + return strconv.AppendBool(nil, v) + case time.Time: + return formatTs(v) + + default: + errorf("encode: unknown type for %T", v) + } + + panic("not reached") +} + +func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid, f format) interface{} { + switch f { + case formatBinary: + return binaryDecode(parameterStatus, s, typ) + case formatText: + return textDecode(parameterStatus, s, typ) + default: + panic("not reached") + } +} + +func binaryDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { + switch typ { + case oid.T_bytea: + return s + case oid.T_int8: + return int64(binary.BigEndian.Uint64(s)) + case oid.T_int4: + return int64(int32(binary.BigEndian.Uint32(s))) + case oid.T_int2: + return int64(int16(binary.BigEndian.Uint16(s))) + case oid.T_uuid: + b, err := decodeUUIDBinary(s) + if err != nil { + panic(err) + } + return b + + default: + errorf("don't know how to decode binary parameter of type %d", uint32(typ)) + } + + panic("not reached") +} + +func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { + switch typ { + case oid.T_char, oid.T_varchar, oid.T_text: + return string(s) + case oid.T_bytea: + b, err := parseBytea(s) + if err != nil { + errorf("%s", err) + } + return b + case oid.T_timestamptz: + return parseTs(parameterStatus.currentLocation, string(s)) + case oid.T_timestamp, oid.T_date: + return parseTs(nil, string(s)) + case oid.T_time: + return mustParse("15:04:05", typ, s) + case oid.T_timetz: + return mustParse("15:04:05-07", typ, s) + case oid.T_bool: + return s[0] == 't' + case oid.T_int8, oid.T_int4, oid.T_int2: + i, err := strconv.ParseInt(string(s), 10, 64) + if err != nil { + errorf("%s", err) + } + return i + case oid.T_float4, oid.T_float8: + // We always use 64 bit parsing, regardless of whether the input text is for + // a float4 or float8, because clients expect float64s for all float datatypes + // and returning a 32-bit parsed float64 produces lossy results. + f, err := strconv.ParseFloat(string(s), 64) + if err != nil { + errorf("%s", err) + } + return f + } + + return s +} + +// appendEncodedText encodes item in text format as required by COPY +// and appends to buf +func appendEncodedText(parameterStatus *parameterStatus, buf []byte, x interface{}) []byte { + switch v := x.(type) { + case int64: + return strconv.AppendInt(buf, v, 10) + case float64: + return strconv.AppendFloat(buf, v, 'f', -1, 64) + case []byte: + encodedBytea := encodeBytea(parameterStatus.serverVersion, v) + return appendEscapedText(buf, string(encodedBytea)) + case string: + return appendEscapedText(buf, v) + case bool: + return strconv.AppendBool(buf, v) + case time.Time: + return append(buf, formatTs(v)...) + case nil: + return append(buf, "\\N"...) + default: + errorf("encode: unknown type for %T", v) + } + + panic("not reached") +} + +func appendEscapedText(buf []byte, text string) []byte { + escapeNeeded := false + startPos := 0 + var c byte + + // check if we need to escape + for i := 0; i < len(text); i++ { + c = text[i] + if c == '\\' || c == '\n' || c == '\r' || c == '\t' { + escapeNeeded = true + startPos = i + break + } + } + if !escapeNeeded { + return append(buf, text...) + } + + // copy till first char to escape, iterate the rest + result := append(buf, text[:startPos]...) + for i := startPos; i < len(text); i++ { + c = text[i] + switch c { + case '\\': + result = append(result, '\\', '\\') + case '\n': + result = append(result, '\\', 'n') + case '\r': + result = append(result, '\\', 'r') + case '\t': + result = append(result, '\\', 't') + default: + result = append(result, c) + } + } + return result +} + +func mustParse(f string, typ oid.Oid, s []byte) time.Time { + str := string(s) + + // check for a 30-minute-offset timezone + if (typ == oid.T_timestamptz || typ == oid.T_timetz) && + str[len(str)-3] == ':' { + f += ":00" + } + t, err := time.Parse(f, str) + if err != nil { + errorf("decode: %s", err) + } + return t +} + +var errInvalidTimestamp = errors.New("invalid timestamp") + +type timestampParser struct { + err error +} + +func (p *timestampParser) expect(str string, char byte, pos int) { + if p.err != nil { + return + } + if pos+1 > len(str) { + p.err = errInvalidTimestamp + return + } + if c := str[pos]; c != char && p.err == nil { + p.err = fmt.Errorf("expected '%v' at position %v; got '%v'", char, pos, c) + } +} + +func (p *timestampParser) mustAtoi(str string, begin int, end int) int { + if p.err != nil { + return 0 + } + if begin < 0 || end < 0 || begin > end || end > len(str) { + p.err = errInvalidTimestamp + return 0 + } + result, err := strconv.Atoi(str[begin:end]) + if err != nil { + if p.err == nil { + p.err = fmt.Errorf("expected number; got '%v'", str) + } + return 0 + } + return result +} + +// The location cache caches the time zones typically used by the client. +type locationCache struct { + cache map[int]*time.Location + lock sync.Mutex +} + +// All connections share the same list of timezones. Benchmarking shows that +// about 5% speed could be gained by putting the cache in the connection and +// losing the mutex, at the cost of a small amount of memory and a somewhat +// significant increase in code complexity. +var globalLocationCache = newLocationCache() + +func newLocationCache() *locationCache { + return &locationCache{cache: make(map[int]*time.Location)} +} + +// Returns the cached timezone for the specified offset, creating and caching +// it if necessary. +func (c *locationCache) getLocation(offset int) *time.Location { + c.lock.Lock() + defer c.lock.Unlock() + + location, ok := c.cache[offset] + if !ok { + location = time.FixedZone("", offset) + c.cache[offset] = location + } + + return location +} + +var infinityTsEnabled = false +var infinityTsNegative time.Time +var infinityTsPositive time.Time + +const ( + infinityTsEnabledAlready = "pq: infinity timestamp enabled already" + infinityTsNegativeMustBeSmaller = "pq: infinity timestamp: negative value must be smaller (before) than positive" +) + +// EnableInfinityTs controls the handling of Postgres' "-infinity" and +// "infinity" "timestamp"s. +// +// If EnableInfinityTs is not called, "-infinity" and "infinity" will return +// []byte("-infinity") and []byte("infinity") respectively, and potentially +// cause error "sql: Scan error on column index 0: unsupported driver -> Scan +// pair: []uint8 -> *time.Time", when scanning into a time.Time value. +// +// Once EnableInfinityTs has been called, all connections created using this +// driver will decode Postgres' "-infinity" and "infinity" for "timestamp", +// "timestamp with time zone" and "date" types to the predefined minimum and +// maximum times, respectively. When encoding time.Time values, any time which +// equals or precedes the predefined minimum time will be encoded to +// "-infinity". Any values at or past the maximum time will similarly be +// encoded to "infinity". +// +// If EnableInfinityTs is called with negative >= positive, it will panic. +// Calling EnableInfinityTs after a connection has been established results in +// undefined behavior. If EnableInfinityTs is called more than once, it will +// panic. +func EnableInfinityTs(negative time.Time, positive time.Time) { + if infinityTsEnabled { + panic(infinityTsEnabledAlready) + } + if !negative.Before(positive) { + panic(infinityTsNegativeMustBeSmaller) + } + infinityTsEnabled = true + infinityTsNegative = negative + infinityTsPositive = positive +} + +/* + * Testing might want to toggle infinityTsEnabled + */ +func disableInfinityTs() { + infinityTsEnabled = false +} + +// This is a time function specific to the Postgres default DateStyle +// setting ("ISO, MDY"), the only one we currently support. This +// accounts for the discrepancies between the parsing available with +// time.Parse and the Postgres date formatting quirks. +func parseTs(currentLocation *time.Location, str string) interface{} { + switch str { + case "-infinity": + if infinityTsEnabled { + return infinityTsNegative + } + return []byte(str) + case "infinity": + if infinityTsEnabled { + return infinityTsPositive + } + return []byte(str) + } + t, err := ParseTimestamp(currentLocation, str) + if err != nil { + panic(err) + } + return t +} + +// ParseTimestamp parses Postgres' text format. It returns a time.Time in +// currentLocation iff that time's offset agrees with the offset sent from the +// Postgres server. Otherwise, ParseTimestamp returns a time.Time with the +// fixed offset offset provided by the Postgres server. +func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, error) { + p := timestampParser{} + + monSep := strings.IndexRune(str, '-') + // this is Gregorian year, not ISO Year + // In Gregorian system, the year 1 BC is followed by AD 1 + year := p.mustAtoi(str, 0, monSep) + daySep := monSep + 3 + month := p.mustAtoi(str, monSep+1, daySep) + p.expect(str, '-', daySep) + timeSep := daySep + 3 + day := p.mustAtoi(str, daySep+1, timeSep) + + minLen := monSep + len("01-01") + 1 + + isBC := strings.HasSuffix(str, " BC") + if isBC { + minLen += 3 + } + + var hour, minute, second int + if len(str) > minLen { + p.expect(str, ' ', timeSep) + minSep := timeSep + 3 + p.expect(str, ':', minSep) + hour = p.mustAtoi(str, timeSep+1, minSep) + secSep := minSep + 3 + p.expect(str, ':', secSep) + minute = p.mustAtoi(str, minSep+1, secSep) + secEnd := secSep + 3 + second = p.mustAtoi(str, secSep+1, secEnd) + } + remainderIdx := monSep + len("01-01 00:00:00") + 1 + // Three optional (but ordered) sections follow: the + // fractional seconds, the time zone offset, and the BC + // designation. We set them up here and adjust the other + // offsets if the preceding sections exist. + + nanoSec := 0 + tzOff := 0 + + if remainderIdx < len(str) && str[remainderIdx] == '.' { + fracStart := remainderIdx + 1 + fracOff := strings.IndexAny(str[fracStart:], "-+ ") + if fracOff < 0 { + fracOff = len(str) - fracStart + } + fracSec := p.mustAtoi(str, fracStart, fracStart+fracOff) + nanoSec = fracSec * (1000000000 / int(math.Pow(10, float64(fracOff)))) + + remainderIdx += fracOff + 1 + } + if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') { + // time zone separator is always '-' or '+' (UTC is +00) + var tzSign int + switch c := str[tzStart]; c { + case '-': + tzSign = -1 + case '+': + tzSign = +1 + default: + return time.Time{}, fmt.Errorf("expected '-' or '+' at position %v; got %v", tzStart, c) + } + tzHours := p.mustAtoi(str, tzStart+1, tzStart+3) + remainderIdx += 3 + var tzMin, tzSec int + if remainderIdx < len(str) && str[remainderIdx] == ':' { + tzMin = p.mustAtoi(str, remainderIdx+1, remainderIdx+3) + remainderIdx += 3 + } + if remainderIdx < len(str) && str[remainderIdx] == ':' { + tzSec = p.mustAtoi(str, remainderIdx+1, remainderIdx+3) + remainderIdx += 3 + } + tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec) + } + var isoYear int + + if isBC { + isoYear = 1 - year + remainderIdx += 3 + } else { + isoYear = year + } + if remainderIdx < len(str) { + return time.Time{}, fmt.Errorf("expected end of input, got %v", str[remainderIdx:]) + } + t := time.Date(isoYear, time.Month(month), day, + hour, minute, second, nanoSec, + globalLocationCache.getLocation(tzOff)) + + if currentLocation != nil { + // Set the location of the returned Time based on the session's + // TimeZone value, but only if the local time zone database agrees with + // the remote database on the offset. + lt := t.In(currentLocation) + _, newOff := lt.Zone() + if newOff == tzOff { + t = lt + } + } + + return t, p.err +} + +// formatTs formats t into a format postgres understands. +func formatTs(t time.Time) []byte { + if infinityTsEnabled { + // t <= -infinity : ! (t > -infinity) + if !t.After(infinityTsNegative) { + return []byte("-infinity") + } + // t >= infinity : ! (!t < infinity) + if !t.Before(infinityTsPositive) { + return []byte("infinity") + } + } + return FormatTimestamp(t) +} + +// FormatTimestamp formats t into Postgres' text format for timestamps. +func FormatTimestamp(t time.Time) []byte { + // Need to send dates before 0001 A.D. with " BC" suffix, instead of the + // minus sign preferred by Go. + // Beware, "0000" in ISO is "1 BC", "-0001" is "2 BC" and so on + bc := false + if t.Year() <= 0 { + // flip year sign, and add 1, e.g: "0" will be "1", and "-10" will be "11" + t = t.AddDate((-t.Year())*2+1, 0, 0) + bc = true + } + b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00")) + + _, offset := t.Zone() + offset = offset % 60 + if offset != 0 { + // RFC3339Nano already printed the minus sign + if offset < 0 { + offset = -offset + } + + b = append(b, ':') + if offset < 10 { + b = append(b, '0') + } + b = strconv.AppendInt(b, int64(offset), 10) + } + + if bc { + b = append(b, " BC"...) + } + return b +} + +// Parse a bytea value received from the server. Both "hex" and the legacy +// "escape" format are supported. +func parseBytea(s []byte) (result []byte, err error) { + if len(s) >= 2 && bytes.Equal(s[:2], []byte("\\x")) { + // bytea_output = hex + s = s[2:] // trim off leading "\\x" + result = make([]byte, hex.DecodedLen(len(s))) + _, err := hex.Decode(result, s) + if err != nil { + return nil, err + } + } else { + // bytea_output = escape + for len(s) > 0 { + if s[0] == '\\' { + // escaped '\\' + if len(s) >= 2 && s[1] == '\\' { + result = append(result, '\\') + s = s[2:] + continue + } + + // '\\' followed by an octal number + if len(s) < 4 { + return nil, fmt.Errorf("invalid bytea sequence %v", s) + } + r, err := strconv.ParseInt(string(s[1:4]), 8, 9) + if err != nil { + return nil, fmt.Errorf("could not parse bytea value: %s", err.Error()) + } + result = append(result, byte(r)) + s = s[4:] + } else { + // We hit an unescaped, raw byte. Try to read in as many as + // possible in one go. + i := bytes.IndexByte(s, '\\') + if i == -1 { + result = append(result, s...) + break + } + result = append(result, s[:i]...) + s = s[i:] + } + } + } + + return result, nil +} + +func encodeBytea(serverVersion int, v []byte) (result []byte) { + if serverVersion >= 90000 { + // Use the hex format if we know that the server supports it + result = make([]byte, 2+hex.EncodedLen(len(v))) + result[0] = '\\' + result[1] = 'x' + hex.Encode(result[2:], v) + } else { + // .. or resort to "escape" + for _, b := range v { + if b == '\\' { + result = append(result, '\\', '\\') + } else if b < 0x20 || b > 0x7e { + result = append(result, []byte(fmt.Sprintf("\\%03o", b))...) + } else { + result = append(result, b) + } + } + } + + return result +} + +// NullTime represents a time.Time that may be null. NullTime implements the +// sql.Scanner interface so it can be used as a scan destination, similar to +// sql.NullString. +type NullTime struct { + Time time.Time + Valid bool // Valid is true if Time is not NULL +} + +// Scan implements the Scanner interface. +func (nt *NullTime) Scan(value interface{}) error { + nt.Time, nt.Valid = value.(time.Time) + return nil +} + +// Value implements the driver Valuer interface. +func (nt NullTime) Value() (driver.Value, error) { + if !nt.Valid { + return nil, nil + } + return nt.Time, nil +} diff --git a/vendor/github.com/lib/pq/scram/scram.go b/vendor/github.com/lib/pq/scram/scram.go new file mode 100644 index 00000000..5d0358f8 --- /dev/null +++ b/vendor/github.com/lib/pq/scram/scram.go @@ -0,0 +1,264 @@ +// Copyright (c) 2014 - Gustavo Niemeyer +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. 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. +// +// 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. + +// Pacakage scram implements a SCRAM-{SHA-1,etc} client per RFC5802. +// +// http://tools.ietf.org/html/rfc5802 +// +package scram + +import ( + "bytes" + "crypto/hmac" + "crypto/rand" + "encoding/base64" + "fmt" + "hash" + "strconv" + "strings" +) + +// Client implements a SCRAM-* client (SCRAM-SHA-1, SCRAM-SHA-256, etc). +// +// A Client may be used within a SASL conversation with logic resembling: +// +// var in []byte +// var client = scram.NewClient(sha1.New, user, pass) +// for client.Step(in) { +// out := client.Out() +// // send out to server +// in := serverOut +// } +// if client.Err() != nil { +// // auth failed +// } +// +type Client struct { + newHash func() hash.Hash + + user string + pass string + step int + out bytes.Buffer + err error + + clientNonce []byte + serverNonce []byte + saltedPass []byte + authMsg bytes.Buffer +} + +// NewClient returns a new SCRAM-* client with the provided hash algorithm. +// +// For SCRAM-SHA-256, for example, use: +// +// client := scram.NewClient(sha256.New, user, pass) +// +func NewClient(newHash func() hash.Hash, user, pass string) *Client { + c := &Client{ + newHash: newHash, + user: user, + pass: pass, + } + c.out.Grow(256) + c.authMsg.Grow(256) + return c +} + +// Out returns the data to be sent to the server in the current step. +func (c *Client) Out() []byte { + if c.out.Len() == 0 { + return nil + } + return c.out.Bytes() +} + +// Err returns the error that ocurred, or nil if there were no errors. +func (c *Client) Err() error { + return c.err +} + +// SetNonce sets the client nonce to the provided value. +// If not set, the nonce is generated automatically out of crypto/rand on the first step. +func (c *Client) SetNonce(nonce []byte) { + c.clientNonce = nonce +} + +var escaper = strings.NewReplacer("=", "=3D", ",", "=2C") + +// Step processes the incoming data from the server and makes the +// next round of data for the server available via Client.Out. +// Step returns false if there are no errors and more data is +// still expected. +func (c *Client) Step(in []byte) bool { + c.out.Reset() + if c.step > 2 || c.err != nil { + return false + } + c.step++ + switch c.step { + case 1: + c.err = c.step1(in) + case 2: + c.err = c.step2(in) + case 3: + c.err = c.step3(in) + } + return c.step > 2 || c.err != nil +} + +func (c *Client) step1(in []byte) error { + if len(c.clientNonce) == 0 { + const nonceLen = 16 + buf := make([]byte, nonceLen+b64.EncodedLen(nonceLen)) + if _, err := rand.Read(buf[:nonceLen]); err != nil { + return fmt.Errorf("cannot read random SCRAM-SHA-256 nonce from operating system: %v", err) + } + c.clientNonce = buf[nonceLen:] + b64.Encode(c.clientNonce, buf[:nonceLen]) + } + c.authMsg.WriteString("n=") + escaper.WriteString(&c.authMsg, c.user) + c.authMsg.WriteString(",r=") + c.authMsg.Write(c.clientNonce) + + c.out.WriteString("n,,") + c.out.Write(c.authMsg.Bytes()) + return nil +} + +var b64 = base64.StdEncoding + +func (c *Client) step2(in []byte) error { + c.authMsg.WriteByte(',') + c.authMsg.Write(in) + + fields := bytes.Split(in, []byte(",")) + if len(fields) != 3 { + return fmt.Errorf("expected 3 fields in first SCRAM-SHA-256 server message, got %d: %q", len(fields), in) + } + if !bytes.HasPrefix(fields[0], []byte("r=")) || len(fields[0]) < 2 { + return fmt.Errorf("server sent an invalid SCRAM-SHA-256 nonce: %q", fields[0]) + } + if !bytes.HasPrefix(fields[1], []byte("s=")) || len(fields[1]) < 6 { + return fmt.Errorf("server sent an invalid SCRAM-SHA-256 salt: %q", fields[1]) + } + if !bytes.HasPrefix(fields[2], []byte("i=")) || len(fields[2]) < 6 { + return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2]) + } + + c.serverNonce = fields[0][2:] + if !bytes.HasPrefix(c.serverNonce, c.clientNonce) { + return fmt.Errorf("server SCRAM-SHA-256 nonce is not prefixed by client nonce: got %q, want %q+\"...\"", c.serverNonce, c.clientNonce) + } + + salt := make([]byte, b64.DecodedLen(len(fields[1][2:]))) + n, err := b64.Decode(salt, fields[1][2:]) + if err != nil { + return fmt.Errorf("cannot decode SCRAM-SHA-256 salt sent by server: %q", fields[1]) + } + salt = salt[:n] + iterCount, err := strconv.Atoi(string(fields[2][2:])) + if err != nil { + return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2]) + } + c.saltPassword(salt, iterCount) + + c.authMsg.WriteString(",c=biws,r=") + c.authMsg.Write(c.serverNonce) + + c.out.WriteString("c=biws,r=") + c.out.Write(c.serverNonce) + c.out.WriteString(",p=") + c.out.Write(c.clientProof()) + return nil +} + +func (c *Client) step3(in []byte) error { + var isv, ise bool + var fields = bytes.Split(in, []byte(",")) + if len(fields) == 1 { + isv = bytes.HasPrefix(fields[0], []byte("v=")) + ise = bytes.HasPrefix(fields[0], []byte("e=")) + } + if ise { + return fmt.Errorf("SCRAM-SHA-256 authentication error: %s", fields[0][2:]) + } else if !isv { + return fmt.Errorf("unsupported SCRAM-SHA-256 final message from server: %q", in) + } + if !bytes.Equal(c.serverSignature(), fields[0][2:]) { + return fmt.Errorf("cannot authenticate SCRAM-SHA-256 server signature: %q", fields[0][2:]) + } + return nil +} + +func (c *Client) saltPassword(salt []byte, iterCount int) { + mac := hmac.New(c.newHash, []byte(c.pass)) + mac.Write(salt) + mac.Write([]byte{0, 0, 0, 1}) + ui := mac.Sum(nil) + hi := make([]byte, len(ui)) + copy(hi, ui) + for i := 1; i < iterCount; i++ { + mac.Reset() + mac.Write(ui) + mac.Sum(ui[:0]) + for j, b := range ui { + hi[j] ^= b + } + } + c.saltedPass = hi +} + +func (c *Client) clientProof() []byte { + mac := hmac.New(c.newHash, c.saltedPass) + mac.Write([]byte("Client Key")) + clientKey := mac.Sum(nil) + hash := c.newHash() + hash.Write(clientKey) + storedKey := hash.Sum(nil) + mac = hmac.New(c.newHash, storedKey) + mac.Write(c.authMsg.Bytes()) + clientProof := mac.Sum(nil) + for i, b := range clientKey { + clientProof[i] ^= b + } + clientProof64 := make([]byte, b64.EncodedLen(len(clientProof))) + b64.Encode(clientProof64, clientProof) + return clientProof64 +} + +func (c *Client) serverSignature() []byte { + mac := hmac.New(c.newHash, c.saltedPass) + mac.Write([]byte("Server Key")) + serverKey := mac.Sum(nil) + + mac = hmac.New(c.newHash, serverKey) + mac.Write(c.authMsg.Bytes()) + serverSignature := mac.Sum(nil) + + encoded := make([]byte, b64.EncodedLen(len(serverSignature))) + b64.Encode(encoded, serverSignature) + return encoded +} diff --git a/vendor/github.com/lib/pq/ssl.go b/vendor/github.com/lib/pq/ssl.go new file mode 100644 index 00000000..d9020845 --- /dev/null +++ b/vendor/github.com/lib/pq/ssl.go @@ -0,0 +1,175 @@ +package pq + +import ( + "crypto/tls" + "crypto/x509" + "io/ioutil" + "net" + "os" + "os/user" + "path/filepath" +) + +// ssl generates a function to upgrade a net.Conn based on the "sslmode" and +// related settings. The function is nil when no upgrade should take place. +func ssl(o values) (func(net.Conn) (net.Conn, error), error) { + verifyCaOnly := false + tlsConf := tls.Config{} + switch mode := o["sslmode"]; mode { + // "require" is the default. + case "", "require": + // We must skip TLS's own verification since it requires full + // verification since Go 1.3. + tlsConf.InsecureSkipVerify = true + + // From http://www.postgresql.org/docs/current/static/libpq-ssl.html: + // + // Note: For backwards compatibility with earlier versions of + // PostgreSQL, if a root CA file exists, the behavior of + // sslmode=require will be the same as that of verify-ca, meaning the + // server certificate is validated against the CA. Relying on this + // behavior is discouraged, and applications that need certificate + // validation should always use verify-ca or verify-full. + if sslrootcert, ok := o["sslrootcert"]; ok { + if _, err := os.Stat(sslrootcert); err == nil { + verifyCaOnly = true + } else { + delete(o, "sslrootcert") + } + } + case "verify-ca": + // We must skip TLS's own verification since it requires full + // verification since Go 1.3. + tlsConf.InsecureSkipVerify = true + verifyCaOnly = true + case "verify-full": + tlsConf.ServerName = o["host"] + case "disable": + return nil, nil + default: + return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode) + } + + err := sslClientCertificates(&tlsConf, o) + if err != nil { + return nil, err + } + err = sslCertificateAuthority(&tlsConf, o) + if err != nil { + return nil, err + } + + // Accept renegotiation requests initiated by the backend. + // + // Renegotiation was deprecated then removed from PostgreSQL 9.5, but + // the default configuration of older versions has it enabled. Redshift + // also initiates renegotiations and cannot be reconfigured. + tlsConf.Renegotiation = tls.RenegotiateFreelyAsClient + + return func(conn net.Conn) (net.Conn, error) { + client := tls.Client(conn, &tlsConf) + if verifyCaOnly { + err := sslVerifyCertificateAuthority(client, &tlsConf) + if err != nil { + return nil, err + } + } + return client, nil + }, nil +} + +// sslClientCertificates adds the certificate specified in the "sslcert" and +// "sslkey" settings, or if they aren't set, from the .postgresql directory +// in the user's home directory. The configured files must exist and have +// the correct permissions. +func sslClientCertificates(tlsConf *tls.Config, o values) error { + // user.Current() might fail when cross-compiling. We have to ignore the + // error and continue without home directory defaults, since we wouldn't + // know from where to load them. + user, _ := user.Current() + + // In libpq, the client certificate is only loaded if the setting is not blank. + // + // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1036-L1037 + sslcert := o["sslcert"] + if len(sslcert) == 0 && user != nil { + sslcert = filepath.Join(user.HomeDir, ".postgresql", "postgresql.crt") + } + // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1045 + if len(sslcert) == 0 { + return nil + } + // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1050:L1054 + if _, err := os.Stat(sslcert); os.IsNotExist(err) { + return nil + } else if err != nil { + return err + } + + // In libpq, the ssl key is only loaded if the setting is not blank. + // + // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1123-L1222 + sslkey := o["sslkey"] + if len(sslkey) == 0 && user != nil { + sslkey = filepath.Join(user.HomeDir, ".postgresql", "postgresql.key") + } + + if len(sslkey) > 0 { + if err := sslKeyPermissions(sslkey); err != nil { + return err + } + } + + cert, err := tls.LoadX509KeyPair(sslcert, sslkey) + if err != nil { + return err + } + + tlsConf.Certificates = []tls.Certificate{cert} + return nil +} + +// sslCertificateAuthority adds the RootCA specified in the "sslrootcert" setting. +func sslCertificateAuthority(tlsConf *tls.Config, o values) error { + // In libpq, the root certificate is only loaded if the setting is not blank. + // + // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L950-L951 + if sslrootcert := o["sslrootcert"]; len(sslrootcert) > 0 { + tlsConf.RootCAs = x509.NewCertPool() + + cert, err := ioutil.ReadFile(sslrootcert) + if err != nil { + return err + } + + if !tlsConf.RootCAs.AppendCertsFromPEM(cert) { + return fmterrorf("couldn't parse pem in sslrootcert") + } + } + + return nil +} + +// sslVerifyCertificateAuthority carries out a TLS handshake to the server and +// verifies the presented certificate against the CA, i.e. the one specified in +// sslrootcert or the system CA if sslrootcert was not specified. +func sslVerifyCertificateAuthority(client *tls.Conn, tlsConf *tls.Config) error { + err := client.Handshake() + if err != nil { + return err + } + certs := client.ConnectionState().PeerCertificates + opts := x509.VerifyOptions{ + DNSName: client.ConnectionState().ServerName, + Intermediates: x509.NewCertPool(), + Roots: tlsConf.RootCAs, + } + for i, cert := range certs { + if i == 0 { + continue + } + opts.Intermediates.AddCert(cert) + } + _, err = certs[0].Verify(opts) + return err +} diff --git a/vendor/github.com/libp2p/go-addr-util/.travis.yml b/vendor/github.com/libp2p/go-addr-util/.travis.yml new file mode 100644 index 00000000..dde69d1a --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - /Users/raul/go/src/gx + - /Users/raul/go/pkg/mod + - /Users/raul/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-addr-util/LICENSE b/vendor/github.com/libp2p/go-addr-util/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-addr-util/Makefile b/vendor/github.com/libp2p/go-addr-util/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/libp2p/go-addr-util/README.md b/vendor/github.com/libp2p/go-addr-util/README.md new file mode 100644 index 00000000..617ea6af --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/README.md @@ -0,0 +1,34 @@ +go-addr-util +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![codecov](https://codecov.io/gh/libp2p/go-addr-util/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-addr-util) +[![Travis CI](https://travis-ci.org/libp2p/go-addr-util.svg?branch=master)](https://travis-ci.org/libp2p/go-addr-util) + +> Address utilities for libp2p swarm. + +## Table of Contents + +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-addr-util/issues)! + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to libp2p are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © Jeromy Johnson diff --git a/vendor/github.com/libp2p/go-addr-util/addr.go b/vendor/github.com/libp2p/go-addr-util/addr.go new file mode 100644 index 00000000..3a922a6e --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/addr.go @@ -0,0 +1,197 @@ +package addrutil + +import ( + "context" + "fmt" + + logging "github.com/ipfs/go-log" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +var log = logging.Logger("addrutil") + +// FilterAddrs is a filter that removes certain addresses, according to the given filters. +// If all filters return true, the address is kept. +func FilterAddrs(a []ma.Multiaddr, filters ...func(ma.Multiaddr) bool) []ma.Multiaddr { + b := make([]ma.Multiaddr, 0, len(a)) + for _, addr := range a { + good := true + for _, filter := range filters { + good = good && filter(addr) + } + if good { + b = append(b, addr) + } + } + return b +} + +// AddrOverNonLocalIP returns whether the addr uses a non-local ip link +func AddrOverNonLocalIP(a ma.Multiaddr) bool { + split := ma.Split(a) + if len(split) < 1 { + return false + } + if manet.IsIP6LinkLocal(split[0]) { + return false + } + return true +} + +// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to +// use the known local interfaces. If ifaceAddr is nil, we request interface addresses +// from the network stack. (this is so you can provide a cached value if resolving many addrs) +func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) { + // split address into its components + split := ma.Split(resolve) + + // if first component (ip) is not unspecified, use it as is. + if !manet.IsIPUnspecified(split[0]) { + return []ma.Multiaddr{resolve}, nil + } + + out := make([]ma.Multiaddr, 0, len(ifaceAddrs)) + for _, ia := range ifaceAddrs { + // must match the first protocol to be resolve. + if ia.Protocols()[0].Code != resolve.Protocols()[0].Code { + continue + } + + split[0] = ia + joined := ma.Join(split...) + out = append(out, joined) + log.Debug("adding resolved addr:", resolve, joined, out) + } + if len(out) < 1 { + return nil, fmt.Errorf("failed to resolve: %s", resolve) + } + return out, nil +} + +// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to +// use the known local interfaces. +func ResolveUnspecifiedAddresses(unspecAddrs, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) { + + // todo optimize: only fetch these if we have a "any" addr. + if len(ifaceAddrs) < 1 { + var err error + ifaceAddrs, err = InterfaceAddresses() + if err != nil { + return nil, err + } + // log.Debug("InterfaceAddresses:", ifaceAddrs) + } + + var outputAddrs []ma.Multiaddr + for _, a := range unspecAddrs { + // unspecified? + resolved, err := ResolveUnspecifiedAddress(a, ifaceAddrs) + if err != nil { + continue // optimistic. if we cant resolve anything, we'll know at the bottom. + } + // log.Debug("resolved:", a, resolved) + outputAddrs = append(outputAddrs, resolved...) + } + + if len(outputAddrs) < 1 { + return nil, fmt.Errorf("failed to specify addrs: %s", unspecAddrs) + } + + log.Event(context.TODO(), "interfaceListenAddresses", func() logging.Loggable { + var addrs []string + for _, addr := range outputAddrs { + addrs = append(addrs, addr.String()) + } + return logging.Metadata{"addresses": addrs} + }()) + + log.Debug("ResolveUnspecifiedAddresses:", unspecAddrs, ifaceAddrs, outputAddrs) + return outputAddrs, nil +} + +// InterfaceAddresses returns a list of addresses associated with local machine +// Note: we do not return link local addresses. IP loopback is ok, because we +// may be connecting to other nodes in the same machine. +func InterfaceAddresses() ([]ma.Multiaddr, error) { + maddrs, err := manet.InterfaceMultiaddrs() + if err != nil { + return nil, err + } + log.Debug("InterfaceAddresses: from manet:", maddrs) + + var out []ma.Multiaddr + for _, a := range maddrs { + if !AddrOverNonLocalIP(a) { + // log.Debug("InterfaceAddresses: skipping unusable:", a) + continue + } + + out = append(out, a) + } + + log.Debug("InterfaceAddresses: usable:", out) + return out, nil +} + +// AddrInList returns whether or not an address is part of a list. +// this is useful to check if NAT is happening (or other bugs?) +func AddrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool { + for _, addr2 := range list { + if addr.Equal(addr2) { + return true + } + } + return false +} + +// AddrIsShareableOnWAN returns whether the given address should be shareable on the +// wide area network (wide internet). +func AddrIsShareableOnWAN(addr ma.Multiaddr) bool { + s := ma.Split(addr) + if len(s) < 1 { + return false + } + a := s[0] + if manet.IsIPLoopback(a) || manet.IsIP6LinkLocal(a) || manet.IsIPUnspecified(a) { + return false + } + return manet.IsThinWaist(a) +} + +// WANShareableAddrs filters addresses based on whether they're shareable on WAN +func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr { + return FilterAddrs(inp, AddrIsShareableOnWAN) +} + +// Subtract filters out all addrs in b from a +func Subtract(a, b []ma.Multiaddr) []ma.Multiaddr { + return FilterAddrs(a, func(m ma.Multiaddr) bool { + for _, bb := range b { + if m.Equal(bb) { + return false + } + } + return true + }) +} + +// CheckNATWarning checks if our observed addresses differ. if so, +// informs the user that certain things might not work yet +func CheckNATWarning(observed, expected ma.Multiaddr, listen []ma.Multiaddr) { + if observed.Equal(expected) { + return + } + + if !AddrInList(observed, listen) { // probably a nat + log.Warningf(natWarning, observed, listen) + } +} + +const natWarning = `Remote peer observed our address to be: %s +The local addresses are: %s +Thus, connection is going through NAT, and other connections may fail. + +IPFS NAT traversal is still under development. Please bug us on github or irc to fix this. +Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif +` diff --git a/vendor/github.com/libp2p/go-addr-util/codecov.yml b/vendor/github.com/libp2p/go-addr-util/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-addr-util/filter.go b/vendor/github.com/libp2p/go-addr-util/filter.go new file mode 100644 index 00000000..dc9cddbf --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/filter.go @@ -0,0 +1,31 @@ +package addrutil + +import ( + ma "github.com/multiformats/go-multiaddr" + mafmt "github.com/whyrusleeping/mafmt" +) + +// SubtractFilter returns a filter func that filters all of the given addresses +func SubtractFilter(addrs ...ma.Multiaddr) func(ma.Multiaddr) bool { + addrmap := make(map[string]bool, len(addrs)) + for _, a := range addrs { + addrmap[string(a.Bytes())] = true + } + + return func(a ma.Multiaddr) bool { + return !addrmap[string(a.Bytes())] + } +} + +// IsFDCostlyTransport returns true for transports that require a new file +// descriptor per connection created +func IsFDCostlyTransport(a ma.Multiaddr) bool { + return mafmt.TCP.Matches(a) +} + +// FilterNeg returns a negated version of the passed in filter +func FilterNeg(f func(ma.Multiaddr) bool) func(ma.Multiaddr) bool { + return func(a ma.Multiaddr) bool { + return !f(a) + } +} diff --git a/vendor/github.com/libp2p/go-addr-util/go.mod b/vendor/github.com/libp2p/go-addr-util/go.mod new file mode 100644 index 00000000..f13ba7fc --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-addr-util + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/multiformats/go-multiaddr v0.0.1 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/whyrusleeping/mafmt v1.2.8 +) diff --git a/vendor/github.com/libp2p/go-addr-util/go.sum b/vendor/github.com/libp2p/go-addr-util/go.sum new file mode 100644 index 00000000..a9e0c634 --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/go.sum @@ -0,0 +1,49 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/libp2p/go-addr-util/package.json b/vendor/github.com/libp2p/go-addr-util/package.json new file mode 100644 index 00000000..55abab99 --- /dev/null +++ b/vendor/github.com/libp2p/go-addr-util/package.json @@ -0,0 +1,41 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/libp2p/go-addr-util/issues" + }, + "gx": { + "dvcsimport": "github.com/libp2p/go-addr-util" + }, + "gxDependencies": [ + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "jbenet", + "hash": "Qmc85NSvmSG4Frn9Vb2cBc1rMyULH6D3TNVEfCzSKoUpip", + "name": "go-multiaddr-net", + "version": "1.7.2" + }, + { + "author": "whyrusleeping", + "hash": "QmUrZZavcArYChpibtP8KgQXsAEpvgzUk73B2oj3HLbWc4", + "name": "mafmt", + "version": "1.2.11" + }, + { + "author": "multiformats", + "hash": "QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL", + "name": "go-multiaddr", + "version": "1.4.1" + } + ], + "gxVersion": "0.9.1", + "language": "go", + "license": "MIT", + "name": "go-addr-util", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "2.0.11" +} + diff --git a/vendor/github.com/libp2p/go-buffer-pool/.travis.yml b/vendor/github.com/libp2p/go-buffer-pool/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-buffer-pool/LICENSE b/vendor/github.com/libp2p/go-buffer-pool/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-buffer-pool/LICENSE-BSD b/vendor/github.com/libp2p/go-buffer-pool/LICENSE-BSD new file mode 100644 index 00000000..97ece789 --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/LICENSE-BSD @@ -0,0 +1,29 @@ +### Applies to buffer.go and buffer_test.go ### + +Copyright (c) 2009 The Go Authors. All rights reserved. + +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. diff --git a/vendor/github.com/libp2p/go-buffer-pool/README.md b/vendor/github.com/libp2p/go-buffer-pool/README.md new file mode 100644 index 00000000..830cb562 --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/README.md @@ -0,0 +1,53 @@ +go-buffer-pool +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23libp2p) +[![codecov](https://codecov.io/gh/libp2p/go-buffer-pool/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-buffer-pool) +[![Travis CI](https://travis-ci.org/libp2p/go-buffer-pool.svg?branch=master)](https://travis-ci.org/libp2p/go-buffer-pool) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A variable size buffer pool for go. + +## Table of Contents + +- [Use Case](#use-case) + - [Advantages over GC](#advantages-over-gc) + - [Disadvantages over GC:](#disadvantages-over-gc) +- [Contribute](#contribute) +- [License](#license) + +## Use Case + +Use this when you need to repeatedly allocate and free a bunch of temporary buffers of approximately the same size. + +### Advantages over GC + +* Reduces Memory Usage: + * We don't have to wait for a GC to run before we can reuse memory. This is essential if you're repeatedly allocating large short-lived buffers. + +* Reduces CPU usage: + * It takes some load off of the GC (due to buffer reuse). + * We don't have to zero buffers (fewer wasteful memory writes). + +### Disadvantages over GC: + +* Can leak memory contents. Unlike the go GC, we *don't* zero memory. +* All buffers have a capacity of a power of 2. This is fine if you either (a) actually need buffers with this size or (b) expect these buffers to be temporary. +* Requires that buffers be returned explicitly. This can lead to race conditions and memory corruption if the buffer is released while it's still in use. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs +BSD © The Go Authors + +--- + +The last gx published version of this module was: 0.1.3: QmQDvJoB6aJWN3sjr3xsgXqKCXf4jU5zdMXpDMsBkYVNqa diff --git a/vendor/github.com/libp2p/go-buffer-pool/buffer.go b/vendor/github.com/libp2p/go-buffer-pool/buffer.go new file mode 100644 index 00000000..2e4645a9 --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/buffer.go @@ -0,0 +1,302 @@ +// This is a derivitive work of Go's bytes.Buffer implementation. +// +// Originally copyright 2009 The Go Authors. All rights reserved. +// +// Modifications copyright 2018 Steven Allen. All rights reserved. +// +// Use of this source code is governed by both a BSD-style and an MIT-style +// license that can be found in the LICENSE_BSD and LICENSE files. + +package pool + +import ( + "io" +) + +// Buffer is a buffer like bytes.Buffer that: +// +// 1. Uses a buffer pool. +// 2. Frees memory on read. +// +// If you only have a few buffers and read/write at a steady rate, *don't* use +// this package, it'll be slower. +// +// However: +// +// 1. If you frequently create/destroy buffers, this implementation will be +// significantly nicer to the allocator. +// 2. If you have many buffers with bursty traffic, this implementation will use +// significantly less memory. +type Buffer struct { + // Pool is the buffer pool to use. If nil, this Buffer will use the + // global buffer pool. + Pool *BufferPool + + buf []byte + rOff int + + // Preallocated slice for samll reads/writes. + // This is *really* important for performance and only costs 8 words. + bootstrap [64]byte +} + +// NewBuffer constructs a new buffer initialized to `buf`. +// Unlike `bytes.Buffer`, we *copy* the buffer but don't reuse it (to ensure +// that we *only* use buffers from the pool). +func NewBuffer(buf []byte) *Buffer { + b := new(Buffer) + if len(buf) > 0 { + b.buf = b.getBuf(len(buf)) + copy(b.buf, buf) + } + return b +} + +// NewBufferString is identical to NewBuffer *except* that it allows one to +// initialize the buffer from a string (without having to allocate an +// intermediate bytes slice). +func NewBufferString(buf string) *Buffer { + b := new(Buffer) + if len(buf) > 0 { + b.buf = b.getBuf(len(buf)) + copy(b.buf, buf) + } + return b +} + +func (b *Buffer) grow(n int) int { + wOff := len(b.buf) + bCap := cap(b.buf) + + if bCap >= wOff+n { + b.buf = b.buf[:wOff+n] + return wOff + } + + bSize := b.Len() + + minCap := 2*bSize + n + + // Slide if cap >= minCap. + // Reallocate otherwise. + if bCap >= minCap { + copy(b.buf, b.buf[b.rOff:]) + } else { + // Needs new buffer. + newBuf := b.getBuf(minCap) + copy(newBuf, b.buf[b.rOff:]) + b.returnBuf() + b.buf = newBuf + } + + b.rOff = 0 + b.buf = b.buf[:bSize+n] + return bSize +} + +func (b *Buffer) getPool() *BufferPool { + if b.Pool == nil { + return GlobalPool + } + return b.Pool +} + +func (b *Buffer) returnBuf() { + if cap(b.buf) > len(b.bootstrap) { + b.getPool().Put(b.buf) + } + b.buf = nil +} + +func (b *Buffer) getBuf(n int) []byte { + if n <= len(b.bootstrap) { + return b.bootstrap[:n] + } + return b.getPool().Get(n) +} + +// Len returns the number of bytes that can be read from this buffer. +func (b *Buffer) Len() int { + return len(b.buf) - b.rOff +} + +// Cap returns the current capacity of the buffer. +// +// Note: Buffer *may* re-allocate when writing (or growing by) `n` bytes even if +// `Cap() < Len() + n` to avoid excessive copying. +func (b *Buffer) Cap() int { + return cap(b.buf) +} + +// Bytes returns the slice of bytes currently buffered in the Buffer. +// +// The buffer returned by Bytes is valid until the next call grow, truncate, +// read, or write. Really, just don't touch the Buffer until you're done with +// the return value of this function. +func (b *Buffer) Bytes() []byte { + return b.buf[b.rOff:] +} + +// String returns the string representation of the buffer. +// +// It returns `` the buffer is a nil pointer. +func (b *Buffer) String() string { + if b == nil { + return "" + } + return string(b.buf[b.rOff:]) +} + +// WriteString writes a string to the buffer. +// +// This function is identical to Write except that it allows one to write a +// string directly without allocating an intermediate byte slice. +func (b *Buffer) WriteString(buf string) (int, error) { + wOff := b.grow(len(buf)) + return copy(b.buf[wOff:], buf), nil +} + +// Truncate truncates the Buffer. +// +// Panics if `n > b.Len()`. +// +// This function may free memory by shrinking the internal buffer. +func (b *Buffer) Truncate(n int) { + if n < 0 || n > b.Len() { + panic("truncation out of range") + } + b.buf = b.buf[:b.rOff+n] + b.shrink() +} + +// Reset is equivalent to Truncate(0). +func (b *Buffer) Reset() { + b.returnBuf() + b.rOff = 0 +} + +// ReadByte reads a single byte from the Buffer. +func (b *Buffer) ReadByte() (byte, error) { + if b.rOff >= len(b.buf) { + return 0, io.EOF + } + c := b.buf[b.rOff] + b.rOff++ + return c, nil +} + +// WriteByte writes a single byte to the Buffer. +func (b *Buffer) WriteByte(c byte) error { + wOff := b.grow(1) + b.buf[wOff] = c + return nil +} + +// Grow grows the internal buffer such that `n` bytes can be written without +// reallocating. +func (b *Buffer) Grow(n int) { + wOff := b.grow(n) + b.buf = b.buf[:wOff] +} + +// Next is an alternative to `Read` that returns a byte slice instead of taking +// one. +// +// The returned byte slice is valid until the next read, write, grow, or +// truncate. +func (b *Buffer) Next(n int) []byte { + m := b.Len() + if m < n { + n = m + } + data := b.buf[b.rOff : b.rOff+n] + b.rOff += n + return data +} + +// Write writes the byte slice to the buffer. +func (b *Buffer) Write(buf []byte) (int, error) { + wOff := b.grow(len(buf)) + return copy(b.buf[wOff:], buf), nil +} + +// WriteTo copies from the buffer into the given writer until the buffer is +// empty. +func (b *Buffer) WriteTo(w io.Writer) (int64, error) { + if b.rOff < len(b.buf) { + n, err := w.Write(b.buf[b.rOff:]) + b.rOff += n + if b.rOff > len(b.buf) { + panic("invalid write count") + } + b.shrink() + return int64(n), err + } + return 0, nil +} + +// MinRead is the minimum slice size passed to a Read call by +// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond +// what is required to hold the contents of r, ReadFrom will not grow the +// underlying buffer. +const MinRead = 512 + +// ReadFrom reads from the given reader into the buffer. +func (b *Buffer) ReadFrom(r io.Reader) (int64, error) { + n := int64(0) + for { + wOff := b.grow(MinRead) + // Use *entire* buffer. + b.buf = b.buf[:cap(b.buf)] + + read, err := r.Read(b.buf[wOff:]) + b.buf = b.buf[:wOff+read] + n += int64(read) + switch err { + case nil: + case io.EOF: + err = nil + fallthrough + default: + b.shrink() + return n, err + } + } +} + +// Read reads at most `len(buf)` bytes from the internal buffer into the given +// buffer. +func (b *Buffer) Read(buf []byte) (int, error) { + if len(buf) == 0 { + return 0, nil + } + if b.rOff >= len(b.buf) { + return 0, io.EOF + } + n := copy(buf, b.buf[b.rOff:]) + b.rOff += n + b.shrink() + return n, nil +} + +func (b *Buffer) shrink() { + c := b.Cap() + // Either nil or bootstrap. + if c <= len(b.bootstrap) { + return + } + + l := b.Len() + if l == 0 { + // Shortcut if empty. + b.returnBuf() + b.rOff = 0 + } else if l*8 < c { + // Only shrink when capacity > 8x length. Avoids shrinking too aggressively. + newBuf := b.getBuf(l) + copy(newBuf, b.buf[b.rOff:]) + b.returnBuf() + b.rOff = 0 + b.buf = newBuf[:l] + } +} diff --git a/vendor/github.com/libp2p/go-buffer-pool/codecov.yml b/vendor/github.com/libp2p/go-buffer-pool/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-buffer-pool/go.mod b/vendor/github.com/libp2p/go-buffer-pool/go.mod new file mode 100644 index 00000000..02b140dd --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/go.mod @@ -0,0 +1,3 @@ +module github.com/libp2p/go-buffer-pool + +go 1.12 diff --git a/vendor/github.com/libp2p/go-buffer-pool/pool.go b/vendor/github.com/libp2p/go-buffer-pool/pool.go new file mode 100644 index 00000000..d812840a --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/pool.go @@ -0,0 +1,115 @@ +// Package pool provides a sync.Pool equivalent that buckets incoming +// requests to one of 32 sub-pools, one for each power of 2, 0-32. +// +// import (pool "github.com/libp2p/go-buffer-pool") +// var p pool.BufferPool +// +// small := make([]byte, 1024) +// large := make([]byte, 4194304) +// p.Put(small) +// p.Put(large) +// +// small2 := p.Get(1024) +// large2 := p.Get(4194304) +// fmt.Println("small2 len:", len(small2)) +// fmt.Println("large2 len:", len(large2)) +// +// // Output: +// // small2 len: 1024 +// // large2 len: 4194304 +// +package pool + +import ( + "math" + "math/bits" + "sync" +) + +// GlobalPool is a static Pool for reusing byteslices of various sizes. +var GlobalPool = new(BufferPool) + +// MaxLength is the maximum length of an element that can be added to the Pool. +const MaxLength = math.MaxInt32 + +// BufferPool is a pool to handle cases of reusing elements of varying sizes. It +// maintains 32 internal pools, for each power of 2 in 0-32. +// +// You should generally just call the package level Get and Put methods or use +// the GlobalPool BufferPool instead of constructing your own. +// +// You MUST NOT copy Pool after using. +type BufferPool struct { + pools [32]sync.Pool // a list of singlePools + ptrs sync.Pool +} + +type bufp struct { + buf []byte +} + +// Get retrieves a buffer of the appropriate length from the buffer pool or +// allocates a new one. Get may choose to ignore the pool and treat it as empty. +// Callers should not assume any relation between values passed to Put and the +// values returned by Get. +// +// If no suitable buffer exists in the pool, Get creates one. +func (p *BufferPool) Get(length int) []byte { + if length == 0 { + return nil + } + if length > MaxLength { + return make([]byte, length) + } + idx := nextLogBase2(uint32(length)) + if ptr := p.pools[idx].Get(); ptr != nil { + bp := ptr.(*bufp) + buf := bp.buf[:uint32(length)] + bp.buf = nil + p.ptrs.Put(ptr) + return buf + } + return make([]byte, 1< MaxLength { + return // drop it + } + idx := prevLogBase2(uint32(capacity)) + var bp *bufp + if ptr := p.ptrs.Get(); ptr != nil { + bp = ptr.(*bufp) + } else { + bp = new(bufp) + } + bp.buf = buf + p.pools[idx].Put(bp) +} + +// Get retrieves a buffer of the appropriate length from the global buffer pool +// (or allocates a new one). +func Get(length int) []byte { + return GlobalPool.Get(length) +} + +// Put returns a buffer to the global buffer pool. +func Put(slice []byte) { + GlobalPool.Put(slice) +} + +// Log of base two, round up (for v > 0). +func nextLogBase2(v uint32) uint32 { + return uint32(bits.Len32(v - 1)) +} + +// Log of base two, round down (for v > 0) +func prevLogBase2(num uint32) uint32 { + next := nextLogBase2(num) + if num == (1 << uint32(next)) { + return next + } + return next - 1 +} diff --git a/vendor/github.com/libp2p/go-buffer-pool/writer.go b/vendor/github.com/libp2p/go-buffer-pool/writer.go new file mode 100644 index 00000000..cea83f92 --- /dev/null +++ b/vendor/github.com/libp2p/go-buffer-pool/writer.go @@ -0,0 +1,119 @@ +package pool + +import ( + "bufio" + "io" + "sync" +) + +const WriterBufferSize = 4096 + +var bufioWriterPool = sync.Pool{ + New: func() interface{} { + return bufio.NewWriterSize(nil, WriterBufferSize) + }, +} + +// Writer is a buffered writer that returns its internal buffer in a pool when +// not in use. +type Writer struct { + W io.Writer + bufw *bufio.Writer +} + +func (w *Writer) ensureBuffer() { + if w.bufw == nil { + w.bufw = bufioWriterPool.Get().(*bufio.Writer) + w.bufw.Reset(w.W) + } +} + +// Write writes the given byte slice to the underlying connection. +// +// Note: Write won't return the write buffer to the pool even if it ends up +// being empty after the write. You must call Flush() to do that. +func (w *Writer) Write(b []byte) (int, error) { + if w.bufw == nil { + if len(b) >= WriterBufferSize { + return w.W.Write(b) + } + w.bufw = bufioWriterPool.Get().(*bufio.Writer) + w.bufw.Reset(w.W) + } + return w.bufw.Write(b) +} + +// Size returns the size of the underlying buffer. +func (w *Writer) Size() int { + return WriterBufferSize +} + +// Available returns the amount buffer space available. +func (w *Writer) Available() int { + if w.bufw != nil { + return w.bufw.Available() + } + return WriterBufferSize +} + +// Buffered returns the amount of data buffered. +func (w *Writer) Buffered() int { + if w.bufw != nil { + return w.bufw.Buffered() + } + return 0 +} + +// WriteByte writes a single byte. +func (w *Writer) WriteByte(b byte) error { + w.ensureBuffer() + return w.bufw.WriteByte(b) +} + +// WriteRune writes a single rune, returning the number of bytes written. +func (w *Writer) WriteRune(r rune) (int, error) { + w.ensureBuffer() + return w.bufw.WriteRune(r) +} + +// WriteString writes a string, returning the number of bytes written. +func (w *Writer) WriteString(s string) (int, error) { + w.ensureBuffer() + return w.bufw.WriteString(s) +} + +// Flush flushes the write buffer, if any, and returns it to the pool. +func (w *Writer) Flush() error { + if w.bufw == nil { + return nil + } + if err := w.bufw.Flush(); err != nil { + return err + } + w.bufw.Reset(nil) + bufioWriterPool.Put(w.bufw) + w.bufw = nil + return nil +} + +// Close flushes the underlying writer and closes it if it implements the +// io.Closer interface. +// +// Note: Close() closes the writer even if Flush() fails to avoid leaking system +// resources. If you want to make sure Flush() succeeds, call it first. +func (w *Writer) Close() error { + var ( + ferr, cerr error + ) + ferr = w.Flush() + + // always close even if flush fails. + if closer, ok := w.W.(io.Closer); ok { + cerr = closer.Close() + } + + if ferr != nil { + return ferr + } + return cerr +} diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/.travis.yml b/vendor/github.com/libp2p/go-conn-security-multistream/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/LICENSE b/vendor/github.com/libp2p/go-conn-security-multistream/LICENSE new file mode 100644 index 00000000..6cccfc2b --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/README.md b/vendor/github.com/libp2p/go-conn-security-multistream/README.md new file mode 100644 index 00000000..fdffd716 --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/README.md @@ -0,0 +1,53 @@ +# go-conn-security-multistream + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) +[![GoDoc](https://godoc.org/github.com/libp2p/go-conn-security-multistream?status.svg)](https://godoc.org/github.com/libp2p/go-conn-security-multistream) + +> Connection security multistream multiplexer + +This package provides a multistream multiplexed [security transport](https://github.com/libp2p/go-conn-security). It: + +1. Selects a security security transport using multistream-select. +2. Secures the stream using the selected transport. + +Known libp2p security transports include: + +* [go-libp2p-secio](https://github.com/libp2p/go-libp2p-secio) + +## Install + +`go-conn-security-multistream` is a standard Go module which can be installed with: + +```sh +go get github.com/libp2p/go-conn-security-multistream +``` + +This repo is [gomod](https://github.com/golang/go/wiki/Modules)-compatible, and users of +go 1.11 and later with modules enabled will automatically pull the latest tagged release +by referencing this package. Upgrades to future releases can be managed using `go get`, +or by editing your `go.mod` file as [described by the gomod documentation](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies). + +## Usage + +For more information about how `go-conn-security-multistream` is used in the libp2p context, you can see the [go-libp2p-conn](https://github.com/libp2p/go-libp2p-conn) module. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-conn-security-multistream/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 0.1.26: QmZWmFkMm28sWeDr5Xh1LexdKBGYGp946MNCfgtLqfX73z diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/go.mod b/vendor/github.com/libp2p/go-conn-security-multistream/go.mod new file mode 100644 index 00000000..2556ff56 --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/go.mod @@ -0,0 +1,9 @@ +module github.com/libp2p/go-conn-security-multistream + +go 1.12 + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-testing v0.0.2 + github.com/multiformats/go-multistream v0.1.0 +) diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/go.sum b/vendor/github.com/libp2p/go-conn-security-multistream/go.sum new file mode 100644 index 00000000..ac3782da --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/go.sum @@ -0,0 +1,89 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-conn-security v0.1.0 h1:q8ii9TUOtSBD1gIoKTSOZIzPFP/agPM28amrCCoeIIA= +github.com/libp2p/go-conn-security v0.1.0/go.mod h1:NQdPF4opCZ5twtEUadzPL0tNSdkrbFc/HmLO7eWqEzY= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-conn-security-multistream/ssms.go b/vendor/github.com/libp2p/go-conn-security-multistream/ssms.go new file mode 100644 index 00000000..219ee6fc --- /dev/null +++ b/vendor/github.com/libp2p/go-conn-security-multistream/ssms.go @@ -0,0 +1,88 @@ +package csms + +import ( + "context" + "fmt" + "net" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" + mss "github.com/multiformats/go-multistream" +) + +// SSMuxer is a multistream stream security transport multiplexer. +// +// SSMuxer is safe to use without initialization. However, it's not safe to move +// after use. +type SSMuxer struct { + mux mss.MultistreamMuxer + tpts map[string]sec.SecureTransport + OrderPreference []string +} + +var _ sec.SecureTransport = (*SSMuxer)(nil) + +// AddTransport adds a stream security transport to this multistream muxer. +// +// This method is *not* thread-safe. It should be called only when initializing +// the SSMuxer. +func (sm *SSMuxer) AddTransport(path string, transport sec.SecureTransport) { + if sm.tpts == nil { + sm.tpts = make(map[string]sec.SecureTransport, 1) + } + + sm.mux.AddHandler(path, nil) + sm.tpts[path] = transport + sm.OrderPreference = append(sm.OrderPreference, path) +} + +// SecureInbound secures an inbound connection using this multistream +// multiplexed stream security transport. +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { + tpt, err := sm.selectProto(ctx, insecure, true) + if err != nil { + return nil, err + } + return tpt.SecureInbound(ctx, insecure) +} + +// SecureOutbound secures an outbound connection using this multistream +// multiplexed stream security transport. +func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + tpt, err := sm.selectProto(ctx, insecure, false) + if err != nil { + return nil, err + } + return tpt.SecureOutbound(ctx, insecure, p) +} + +func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (sec.SecureTransport, error) { + var proto string + var err error + done := make(chan struct{}) + go func() { + defer close(done) + if server { + proto, _, err = sm.mux.Negotiate(insecure) + } else { + proto, err = mss.SelectOneOf(sm.OrderPreference, insecure) + } + }() + + select { + case <-done: + if err != nil { + return nil, err + } + if tpt, ok := sm.tpts[proto]; ok { + return tpt, nil + } + return nil, fmt.Errorf("selected unknown security transport") + case <-ctx.Done(): + // We *must* do this. We have outstanding work on the connection + // and it's no longer safe to use. + insecure.Close() + <-done // wait to stop using the connection. + return nil, ctx.Err() + } +} diff --git a/vendor/github.com/libp2p/go-flow-metrics/.travis.yml b/vendor/github.com/libp2p/go-flow-metrics/.travis.yml new file mode 100644 index 00000000..dde69d1a --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - /Users/raul/go/src/gx + - /Users/raul/go/pkg/mod + - /Users/raul/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-flow-metrics/LICENSE b/vendor/github.com/libp2p/go-flow-metrics/LICENSE new file mode 100644 index 00000000..fa878af7 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-flow-metrics/Makefile b/vendor/github.com/libp2p/go-flow-metrics/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/libp2p/go-flow-metrics/README.md b/vendor/github.com/libp2p/go-flow-metrics/README.md new file mode 100644 index 00000000..11470a68 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/README.md @@ -0,0 +1,33 @@ +go-flow-metrics +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![Travis CI](https://travis-ci.org/libp2p/go-flow-metrics.svg?branch=master)](https://travis-ci.org/libp2p/go-flow-metrics) + +> A simple library for tracking flow metrics. + +A simple alternative to [rcrowley's +go-metrics](https://github.com/rcrowley/go-metrics) that's a lot faster (and +only does simple bandwidth metrics). + +## Table of Contents + +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Protocol Labs diff --git a/vendor/github.com/libp2p/go-flow-metrics/go.mod b/vendor/github.com/libp2p/go-flow-metrics/go.mod new file mode 100644 index 00000000..908c4c39 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/go.mod @@ -0,0 +1 @@ +module github.com/libp2p/go-flow-metrics diff --git a/vendor/github.com/libp2p/go-flow-metrics/meter.go b/vendor/github.com/libp2p/go-flow-metrics/meter.go new file mode 100644 index 00000000..412dd3de --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/meter.go @@ -0,0 +1,44 @@ +package flow + +import ( + "fmt" + "sync/atomic" +) + +// Snapshot is a rate/total snapshot. +type Snapshot struct { + Rate float64 + Total uint64 +} + +func (s Snapshot) String() string { + return fmt.Sprintf("%d (%f/s)", s.Total, s.Rate) +} + +// Meter is a meter for monitoring a flow. +type Meter struct { + accumulator uint64 + + // Take lock. + snapshot Snapshot +} + +// Mark updates the total. +func (m *Meter) Mark(count uint64) { + if count > 0 && atomic.AddUint64(&m.accumulator, count) == count { + // I'm the first one to bump this above 0. + // Register it. + globalSweeper.Register(m) + } +} + +// Snapshot gets a consistent snapshot of the total and rate. +func (m *Meter) Snapshot() Snapshot { + globalSweeper.mutex.RLock() + defer globalSweeper.mutex.RUnlock() + return m.snapshot +} + +func (m *Meter) String() string { + return m.Snapshot().String() +} diff --git a/vendor/github.com/libp2p/go-flow-metrics/package.json b/vendor/github.com/libp2p/go-flow-metrics/package.json new file mode 100644 index 00000000..df05d207 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/package.json @@ -0,0 +1,16 @@ +{ + "author": "Stebalien", + "bugs": { + "url": "github.com/libp2p/go-flow-metrics" + }, + "gx": { + "dvcsimport": "github.com/libp2p/go-flow-metrics" + }, + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-flow-metrics", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.2.0" +} + diff --git a/vendor/github.com/libp2p/go-flow-metrics/registry.go b/vendor/github.com/libp2p/go-flow-metrics/registry.go new file mode 100644 index 00000000..226a4827 --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/registry.go @@ -0,0 +1,35 @@ +package flow + +import ( + "sync" +) + +// MeterRegistry is a registry for named meters. +type MeterRegistry struct { + meters sync.Map +} + +// Get gets (or creates) a meter by name. +func (r *MeterRegistry) Get(name string) *Meter { + if m, ok := r.meters.Load(name); ok { + return m.(*Meter) + } + m, _ := r.meters.LoadOrStore(name, new(Meter)) + return m.(*Meter) +} + +// Remove removes the named meter from the registry. +// +// Note: The only reason to do this is to save a bit of memory. Unused meters +// don't consume any CPU (after they go idle). +func (r *MeterRegistry) Remove(name string) { + r.meters.Delete(name) +} + +// ForEach calls the passed function for each registered meter. +func (r *MeterRegistry) ForEach(iterFunc func(string, *Meter)) { + r.meters.Range(func(k, v interface{}) bool { + iterFunc(k.(string), v.(*Meter)) + return true + }) +} diff --git a/vendor/github.com/libp2p/go-flow-metrics/sweeper.go b/vendor/github.com/libp2p/go-flow-metrics/sweeper.go new file mode 100644 index 00000000..21ecf31c --- /dev/null +++ b/vendor/github.com/libp2p/go-flow-metrics/sweeper.go @@ -0,0 +1,153 @@ +package flow + +import ( + "math" + "sync" + "sync/atomic" + "time" +) + +// IdleRate the rate at which we declare a meter idle (and stop tracking it +// until it's re-registered). +// +// The default ensures that 1 event every ~30s will keep the meter from going +// idle. +var IdleRate = 1e-13 + +// Alpha for EWMA of 1s +var alpha = 1 - math.Exp(-1.0) + +// The global sweeper. +var globalSweeper sweeper + +type sweeper struct { + sweepOnce sync.Once + meters []*Meter + mutex sync.RWMutex + lastUpdateTime time.Time + registerChannel chan *Meter +} + +func (sw *sweeper) start() { + sw.registerChannel = make(chan *Meter, 16) + go sw.run() +} + +func (sw *sweeper) run() { + for m := range sw.registerChannel { + sw.register(m) + sw.runActive() + } +} + +func (sw *sweeper) register(m *Meter) { + // Add back the snapshot total. If we unregistered this + // one, we set it to zero. + atomic.AddUint64(&m.accumulator, m.snapshot.Total) + sw.meters = append(sw.meters, m) +} + +func (sw *sweeper) runActive() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + sw.lastUpdateTime = time.Now() + for len(sw.meters) > 0 { + // Scale back allocation. + if len(sw.meters)*2 < cap(sw.meters) { + newMeters := make([]*Meter, len(sw.meters)) + copy(newMeters, sw.meters) + sw.meters = newMeters + } + + select { + case <-ticker.C: + sw.update() + case m := <-sw.registerChannel: + sw.register(m) + } + } + sw.meters = nil + // Till next time. +} + +func (sw *sweeper) update() { + sw.mutex.Lock() + defer sw.mutex.Unlock() + + now := time.Now() + tdiff := now.Sub(sw.lastUpdateTime) + if tdiff <= 0 { + return + } + sw.lastUpdateTime = now + timeMultiplier := float64(time.Second) / float64(tdiff) + + newLen := len(sw.meters) + + for i, m := range sw.meters { + total := atomic.LoadUint64(&m.accumulator) + instant := timeMultiplier * float64(total-m.snapshot.Total) + + if m.snapshot.Rate == 0 { + m.snapshot.Rate = instant + } else { + m.snapshot.Rate += alpha * (instant - m.snapshot.Rate) + } + m.snapshot.Total = total + + // This is equivalent to one zeros, then one, then 30 zeros. + // We'll consider that to be "idle". + if m.snapshot.Rate > IdleRate { + continue + } + + // Ok, so we are idle... + + // Mark this as idle by zeroing the accumulator. + swappedTotal := atomic.SwapUint64(&m.accumulator, 0) + + // So..., are we really idle? + if swappedTotal > total { + // Not so idle... + // Now we need to make sure this gets re-registered. + + // First, add back what we removed. If we can do this + // fast enough, we can put it back before anyone + // notices. + currentTotal := atomic.AddUint64(&m.accumulator, swappedTotal) + + // Did we make it? + if currentTotal == swappedTotal { + // Yes! Nobody noticed, move along. + continue + } + // No. Someone noticed and will (or has) put back into + // the registration channel. + // + // Remove the snapshot total, it'll get added back on + // registration. + // + // `^uint64(total - 1)` is the two's complement of + // `total`. It's the "correct" way to subtract + // atomically in go. + atomic.AddUint64(&m.accumulator, ^uint64(m.snapshot.Total-1)) + } + + // Reset the rate, keep the total. + m.snapshot.Rate = 0 + newLen-- + sw.meters[i] = sw.meters[newLen] + } + + // trim the meter list + for i := newLen; i < len(sw.meters); i++ { + sw.meters[i] = nil + } + sw.meters = sw.meters[:newLen] +} + +func (sw *sweeper) Register(m *Meter) { + sw.sweepOnce.Do(sw.start) + sw.registerChannel <- m +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/.gitignore b/vendor/github.com/libp2p/go-libp2p-autonat-svc/.gitignore new file mode 100644 index 00000000..f1c181ec --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/.travis.yml b/vendor/github.com/libp2p/go-libp2p-autonat-svc/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/LICENSE b/vendor/github.com/libp2p/go-libp2p-autonat-svc/LICENSE new file mode 100644 index 00000000..3f05397b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 libp2p + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/README.md b/vendor/github.com/libp2p/go-libp2p-autonat-svc/README.md new file mode 100644 index 00000000..181415db --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/README.md @@ -0,0 +1,29 @@ +# go-libp2p-autonat-svc + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) + [![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + + +> AutoNAT service implementation + +This package provides an implementation of the AutoNATService; see [autonat](https://github.com/libp2p/go-libp2p-autonat). + +## Documentation + +See https://godoc.org/github.com/libp2p/go-libp2p-autonat-svc. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-discovery/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +## License + +MIT + +--- + +The last gx published version of this module was: 1.0.15: QmS4vFMsoH5BwxfWdMBeMt6sBdcBAB5mik1ATADySymLZW diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.mod b/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.mod new file mode 100644 index 00000000..9c726a4a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.mod @@ -0,0 +1,11 @@ +module github.com/libp2p/go-libp2p-autonat-svc + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p v0.1.0 + github.com/libp2p/go-libp2p-autonat v0.1.0 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 +) diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.sum b/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.sum new file mode 100644 index 00000000..2116a4ed --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/go.sum @@ -0,0 +1,252 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.0 h1:8VXadcPNni74ODoZ+7326LMAppFYmz1fRQOUuT5iZvQ= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0 h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3 h1:YiMaevQcZtFU6DmKIF8xEO0vaui5kM5HJ1V1xkWQv14= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/proto.go b/vendor/github.com/libp2p/go-libp2p-autonat-svc/proto.go new file mode 100644 index 00000000..c0bd44a8 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/proto.go @@ -0,0 +1,24 @@ +package autonat + +import ( + pb "github.com/libp2p/go-libp2p-autonat/pb" + + logging "github.com/ipfs/go-log" + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("autonat-svc") + +func newDialResponseOK(addr ma.Multiaddr) *pb.Message_DialResponse { + dr := new(pb.Message_DialResponse) + dr.Status = pb.Message_OK.Enum() + dr.Addr = addr.Bytes() + return dr +} + +func newDialResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DialResponse { + dr := new(pb.Message_DialResponse) + dr.Status = status.Enum() + dr.StatusText = &text + return dr +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat-svc/svc.go b/vendor/github.com/libp2p/go-libp2p-autonat-svc/svc.go new file mode 100644 index 00000000..a685f3d3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat-svc/svc.go @@ -0,0 +1,217 @@ +package autonat + +import ( + "context" + "sync" + "time" + + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + pb "github.com/libp2p/go-libp2p-autonat/pb" + + ggio "github.com/gogo/protobuf/io" + autonat "github.com/libp2p/go-libp2p-autonat" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +const P_CIRCUIT = 290 + +var ( + AutoNATServiceDialTimeout = 15 * time.Second + AutoNATServiceResetInterval = 1 * time.Minute + + AutoNATServiceThrottle = 3 +) + +// AutoNATService provides NAT autodetection services to other peers +type AutoNATService struct { + ctx context.Context + dialer host.Host + + // rate limiter + mx sync.Mutex + reqs map[peer.ID]int +} + +// NewAutoNATService creates a new AutoNATService instance attached to a host +func NewAutoNATService(ctx context.Context, h host.Host, opts ...libp2p.Option) (*AutoNATService, error) { + opts = append(opts, libp2p.NoListenAddrs) + dialer, err := libp2p.New(ctx, opts...) + if err != nil { + return nil, err + } + + as := &AutoNATService{ + ctx: ctx, + dialer: dialer, + reqs: make(map[peer.ID]int), + } + h.SetStreamHandler(autonat.AutoNATProto, as.handleStream) + + go as.resetRateLimiter() + + return as, nil +} + +func (as *AutoNATService) handleStream(s network.Stream) { + defer helpers.FullClose(s) + + pid := s.Conn().RemotePeer() + log.Debugf("New stream from %s", pid.Pretty()) + + r := ggio.NewDelimitedReader(s, network.MessageSizeMax) + w := ggio.NewDelimitedWriter(s) + + var req pb.Message + var res pb.Message + + err := r.ReadMsg(&req) + if err != nil { + log.Debugf("Error reading message from %s: %s", pid.Pretty(), err.Error()) + s.Reset() + return + } + + t := req.GetType() + if t != pb.Message_DIAL { + log.Debugf("Unexpected message from %s: %s (%d)", pid.Pretty(), t.String(), t) + s.Reset() + return + } + + dr := as.handleDial(pid, s.Conn().RemoteMultiaddr(), req.GetDial().GetPeer()) + res.Type = pb.Message_DIAL_RESPONSE.Enum() + res.DialResponse = dr + + err = w.WriteMsg(&res) + if err != nil { + log.Debugf("Error writing response to %s: %s", pid.Pretty(), err.Error()) + s.Reset() + return + } +} + +func (as *AutoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Message_PeerInfo) *pb.Message_DialResponse { + if mpi == nil { + return newDialResponseError(pb.Message_E_BAD_REQUEST, "missing peer info") + } + + mpid := mpi.GetId() + if mpid != nil { + mp, err := peer.IDFromBytes(mpid) + if err != nil { + return newDialResponseError(pb.Message_E_BAD_REQUEST, "bad peer id") + } + + if mp != p { + return newDialResponseError(pb.Message_E_BAD_REQUEST, "peer id mismatch") + } + } + + addrs := make([]ma.Multiaddr, 0) + seen := make(map[string]struct{}) + + // add observed addr to the list of addresses to dial + if !as.skipDial(obsaddr) { + addrs = append(addrs, obsaddr) + seen[obsaddr.String()] = struct{}{} + } + + for _, maddr := range mpi.GetAddrs() { + addr, err := ma.NewMultiaddrBytes(maddr) + if err != nil { + log.Debugf("Error parsing multiaddr: %s", err.Error()) + continue + } + + if as.skipDial(addr) { + continue + } + + str := addr.String() + _, ok := seen[str] + if ok { + continue + } + + addrs = append(addrs, addr) + seen[str] = struct{}{} + } + + if len(addrs) == 0 { + return newDialResponseError(pb.Message_E_DIAL_ERROR, "no dialable addresses") + } + + return as.doDial(peer.AddrInfo{ID: p, Addrs: addrs}) +} + +func (as *AutoNATService) skipDial(addr ma.Multiaddr) bool { + // skip relay addresses + _, err := addr.ValueForProtocol(P_CIRCUIT) + if err == nil { + return true + } + + // skip private network (unroutable) addresses + if !manet.IsPublicAddr(addr) { + return true + } + + return false +} + +func (as *AutoNATService) doDial(pi peer.AddrInfo) *pb.Message_DialResponse { + // rate limit check + as.mx.Lock() + count := as.reqs[pi.ID] + if count >= AutoNATServiceThrottle { + as.mx.Unlock() + return newDialResponseError(pb.Message_E_DIAL_REFUSED, "too many dials") + } + as.reqs[pi.ID] = count + 1 + as.mx.Unlock() + + ctx, cancel := context.WithTimeout(as.ctx, AutoNATServiceDialTimeout) + defer cancel() + + err := as.dialer.Connect(ctx, pi) + if err != nil { + log.Debugf("error dialing %s: %s", pi.ID.Pretty(), err.Error()) + // wait for the context to timeout to avoid leaking timing information + // this renders the service ineffective as a port scanner + <-ctx.Done() + return newDialResponseError(pb.Message_E_DIAL_ERROR, "dial failed") + } + + conns := as.dialer.Network().ConnsToPeer(pi.ID) + if len(conns) == 0 { + log.Errorf("supposedly connected to %s, but no connection to peer", pi.ID.Pretty()) + return newDialResponseError(pb.Message_E_INTERNAL_ERROR, "internal service error") + } + + ra := conns[0].RemoteMultiaddr() + as.dialer.Network().ClosePeer(pi.ID) + return newDialResponseOK(ra) +} + +func (as *AutoNATService) resetRateLimiter() { + ticker := time.NewTicker(AutoNATServiceResetInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + as.mx.Lock() + as.reqs = make(map[peer.ID]int) + as.mx.Unlock() + + case <-as.ctx.Done(): + return + } + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/.gitignore b/vendor/github.com/libp2p/go-libp2p-autonat/.gitignore new file mode 100644 index 00000000..a1338d68 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/.gitignore @@ -0,0 +1,14 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/.travis.yml b/vendor/github.com/libp2p/go-libp2p-autonat/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/LICENSE b/vendor/github.com/libp2p/go-libp2p-autonat/LICENSE new file mode 100644 index 00000000..3f05397b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 libp2p + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/README.md b/vendor/github.com/libp2p/go-libp2p-autonat/README.md new file mode 100644 index 00000000..97420373 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/README.md @@ -0,0 +1,31 @@ +# go-libp2p-autonat + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) + [![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + + + +> Ambient NAT discovery + +This package provides an ambient NAT autodiscovery service. +It allows peers to figure out their NAT dialability situation by using test dial backs through peers providing the AutoNAT service. + +## Documentation + +See https://godoc.org/github.com/libp2p/go-libp2p-autonat + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-discovery/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +## License + +MIT + +--- + +The last gx published version of this module was: 1.0.14: QmNnJhrc4ZtcPZg3oXDVdJ7HRtxDfLE2ccH56cZZjZ6y3p diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/autonat.go b/vendor/github.com/libp2p/go-libp2p-autonat/autonat.go new file mode 100644 index 00000000..7e839ddd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/autonat.go @@ -0,0 +1,253 @@ +package autonat + +import ( + "context" + "errors" + "math/rand" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + ma "github.com/multiformats/go-multiaddr" +) + +// NATStatus is the state of NAT as detected by the ambient service. +type NATStatus int + +const ( + // NAT status is unknown; this means that the ambient service has not been + // able to decide the presence of NAT in the most recent attempt to test + // dial through known autonat peers. initial state. + NATStatusUnknown NATStatus = iota + // NAT status is publicly dialable + NATStatusPublic + // NAT status is private network + NATStatusPrivate +) + +var ( + AutoNATBootDelay = 15 * time.Second + AutoNATRetryInterval = 90 * time.Second + AutoNATRefreshInterval = 15 * time.Minute + AutoNATRequestTimeout = 30 * time.Second +) + +// AutoNAT is the interface for ambient NAT autodiscovery +type AutoNAT interface { + // Status returns the current NAT status + Status() NATStatus + // PublicAddr returns the public dial address when NAT status is public and an + // error otherwise + PublicAddr() (ma.Multiaddr, error) +} + +// AmbientAutoNAT is the implementation of ambient NAT autodiscovery +type AmbientAutoNAT struct { + ctx context.Context + host host.Host + + getAddrs GetAddrs + + mx sync.Mutex + peers map[peer.ID][]ma.Multiaddr + status NATStatus + addr ma.Multiaddr + // Reflects the confidence on of the NATStatus being private, as a single + // dialback may fail for reasons unrelated to NAT. + // If it is <3, then multiple autoNAT peers may be contacted for dialback + // If only a single autoNAT peer is known, then the confidence increases + // for each failure until it reaches 3. + confidence int +} + +// NewAutoNAT creates a new ambient NAT autodiscovery instance attached to a host +// If getAddrs is nil, h.Addrs will be used +func NewAutoNAT(ctx context.Context, h host.Host, getAddrs GetAddrs) AutoNAT { + if getAddrs == nil { + getAddrs = h.Addrs + } + + as := &AmbientAutoNAT{ + ctx: ctx, + host: h, + getAddrs: getAddrs, + peers: make(map[peer.ID][]ma.Multiaddr), + status: NATStatusUnknown, + } + + h.Network().Notify(as) + go as.background() + + return as +} + +func (as *AmbientAutoNAT) Status() NATStatus { + as.mx.Lock() + defer as.mx.Unlock() + return as.status +} + +func (as *AmbientAutoNAT) PublicAddr() (ma.Multiaddr, error) { + as.mx.Lock() + defer as.mx.Unlock() + + if as.status != NATStatusPublic { + return nil, errors.New("NAT Status is not public") + } + + return as.addr, nil +} + +func (as *AmbientAutoNAT) background() { + // wait a bit for the node to come online and establish some connections + // before starting autodetection + select { + case <-time.After(AutoNATBootDelay): + case <-as.ctx.Done(): + return + } + + for { + as.autodetect() + + delay := AutoNATRefreshInterval + if as.status == NATStatusUnknown { + delay = AutoNATRetryInterval + } + + select { + case <-time.After(delay): + case <-as.ctx.Done(): + return + } + } +} + +func (as *AmbientAutoNAT) autodetect() { + peers := as.getPeers() + + if len(peers) == 0 { + log.Debugf("skipping NAT auto detection; no autonat peers") + return + } + + cli := NewAutoNATClient(as.host, as.getAddrs) + ctx, cancel := context.WithTimeout(as.ctx, AutoNATRequestTimeout) + defer cancel() + + var result struct { + sync.Mutex + private int + public int + pubaddr ma.Multiaddr + } + + probe := 3 - as.confidence + if probe == 0 { + probe = 1 + } + if probe > len(peers) { + probe = len(peers) + } + + var wg sync.WaitGroup + + for _, pi := range peers[:probe] { + wg.Add(1) + go func(pi peer.AddrInfo) { + defer wg.Done() + + as.host.Peerstore().AddAddrs(pi.ID, pi.Addrs, peerstore.TempAddrTTL) + a, err := cli.DialBack(ctx, pi.ID) + + switch { + case err == nil: + log.Debugf("Dialback through %s successful; public address is %s", pi.ID.Pretty(), a.String()) + result.Lock() + result.public++ + result.pubaddr = a + result.Unlock() + + case IsDialError(err): + log.Debugf("Dialback through %s failed", pi.ID.Pretty()) + result.Lock() + result.private++ + result.Unlock() + + default: + log.Debugf("Dialback error through %s: %s", pi.ID.Pretty(), err) + } + }(pi) + } + + wg.Wait() + + as.mx.Lock() + if result.public > 0 { + log.Debugf("NAT status is public") + if as.status == NATStatusPrivate { + // we are flipping our NATStatus, so confidence drops to 0 + as.confidence = 0 + } else if as.confidence < 3 { + as.confidence++ + } + as.status = NATStatusPublic + as.addr = result.pubaddr + } else if result.private > 0 { + log.Debugf("NAT status is private") + if as.status == NATStatusPublic { + // we are flipping our NATStatus, so confidence drops to 0 + as.confidence = 0 + } else if as.confidence < 3 { + as.confidence++ + } + as.status = NATStatusPrivate + as.addr = nil + } else if as.confidence > 0 { + // don't just flip to unknown, reduce confidence first + as.confidence-- + } else { + log.Debugf("NAT status is unknown") + as.status = NATStatusUnknown + as.addr = nil + } + as.mx.Unlock() +} + +func (as *AmbientAutoNAT) getPeers() []peer.AddrInfo { + as.mx.Lock() + defer as.mx.Unlock() + + if len(as.peers) == 0 { + return nil + } + + var connected, others []peer.AddrInfo + + for p, addrs := range as.peers { + if as.host.Network().Connectedness(p) == network.Connected { + connected = append(connected, peer.AddrInfo{ID: p, Addrs: addrs}) + } else { + others = append(others, peer.AddrInfo{ID: p, Addrs: addrs}) + } + } + + shufflePeers(connected) + + if len(connected) < 3 { + shufflePeers(others) + return append(connected, others...) + } else { + return connected + } +} + +func shufflePeers(peers []peer.AddrInfo) { + for i := range peers { + j := rand.Intn(i + 1) + peers[i], peers[j] = peers[j], peers[i] + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/client.go b/vendor/github.com/libp2p/go-libp2p-autonat/client.go new file mode 100644 index 00000000..0d8549b4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/client.go @@ -0,0 +1,110 @@ +package autonat + +import ( + "context" + "fmt" + + pb "github.com/libp2p/go-libp2p-autonat/pb" + "github.com/libp2p/go-libp2p-core/helpers" + + ggio "github.com/gogo/protobuf/io" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" +) + +// AutoNATClient is a stateless client interface to AutoNAT peers +type AutoNATClient interface { + // DialBack requests from a peer providing AutoNAT services to test dial back + // and report the address on a successful connection. + DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error) +} + +// AutoNATError is the class of errors signalled by AutoNAT services +type AutoNATError struct { + Status pb.Message_ResponseStatus + Text string +} + +// GetAddrs is a function that returns the addresses to dial back +type GetAddrs func() []ma.Multiaddr + +// NewAutoNATClient creates a fresh instance of an AutoNATClient +// If getAddrs is nil, h.Addrs will be used +func NewAutoNATClient(h host.Host, getAddrs GetAddrs) AutoNATClient { + if getAddrs == nil { + getAddrs = h.Addrs + } + return &client{h: h, getAddrs: getAddrs} +} + +type client struct { + h host.Host + getAddrs GetAddrs +} + +func (c *client) DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error) { + s, err := c.h.NewStream(ctx, p, AutoNATProto) + if err != nil { + return nil, err + } + // Might as well just reset the stream. Once we get to this point, we + // don't care about being nice. + defer helpers.FullClose(s) + + r := ggio.NewDelimitedReader(s, network.MessageSizeMax) + w := ggio.NewDelimitedWriter(s) + + req := newDialMessage(peer.AddrInfo{ID: c.h.ID(), Addrs: c.getAddrs()}) + err = w.WriteMsg(req) + if err != nil { + s.Reset() + return nil, err + } + + var res pb.Message + err = r.ReadMsg(&res) + if err != nil { + s.Reset() + return nil, err + } + + if res.GetType() != pb.Message_DIAL_RESPONSE { + return nil, fmt.Errorf("Unexpected response: %s", res.GetType().String()) + } + + status := res.GetDialResponse().GetStatus() + switch status { + case pb.Message_OK: + addr := res.GetDialResponse().GetAddr() + return ma.NewMultiaddrBytes(addr) + + default: + return nil, AutoNATError{Status: status, Text: res.GetDialResponse().GetStatusText()} + } +} + +func (e AutoNATError) Error() string { + return fmt.Sprintf("AutoNAT error: %s (%s)", e.Text, e.Status.String()) +} + +func (e AutoNATError) IsDialError() bool { + return e.Status == pb.Message_E_DIAL_ERROR +} + +func (e AutoNATError) IsDialRefused() bool { + return e.Status == pb.Message_E_DIAL_REFUSED +} + +// IsDialError returns true if the AutoNAT peer signalled an error dialing back +func IsDialError(e error) bool { + ae, ok := e.(AutoNATError) + return ok && ae.IsDialError() +} + +// IsDialRefused returns true if the AutoNAT peer signalled refusal to dial back +func IsDialRefused(e error) bool { + ae, ok := e.(AutoNATError) + return ok && ae.IsDialRefused() +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/go.mod b/vendor/github.com/libp2p/go-libp2p-autonat/go.mod new file mode 100644 index 00000000..531d4b2e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/go.mod @@ -0,0 +1,10 @@ +module github.com/libp2p/go-libp2p-autonat + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/multiformats/go-multiaddr v0.0.4 +) diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/go.sum b/vendor/github.com/libp2p/go-libp2p-autonat/go.sum new file mode 100644 index 00000000..e2d20f17 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/go.sum @@ -0,0 +1,216 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/notify.go b/vendor/github.com/libp2p/go-libp2p-autonat/notify.go new file mode 100644 index 00000000..4ea65616 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/notify.go @@ -0,0 +1,42 @@ +package autonat + +import ( + "time" + + "github.com/libp2p/go-libp2p-core/network" + + ma "github.com/multiformats/go-multiaddr" +) + +var _ network.Notifiee = (*AmbientAutoNAT)(nil) + +var AutoNATIdentifyDelay = 5 * time.Second + +func (as *AmbientAutoNAT) Listen(net network.Network, a ma.Multiaddr) {} +func (as *AmbientAutoNAT) ListenClose(net network.Network, a ma.Multiaddr) {} +func (as *AmbientAutoNAT) OpenedStream(net network.Network, s network.Stream) {} +func (as *AmbientAutoNAT) ClosedStream(net network.Network, s network.Stream) {} + +func (as *AmbientAutoNAT) Connected(net network.Network, c network.Conn) { + p := c.RemotePeer() + + go func() { + // add some delay for identify + time.Sleep(AutoNATIdentifyDelay) + + protos, err := as.host.Peerstore().SupportsProtocols(p, AutoNATProto) + if err != nil { + log.Debugf("error retrieving supported protocols for peer %s: %s", p, err) + return + } + + if len(protos) > 0 { + log.Infof("Discovered AutoNAT peer %s", p.Pretty()) + as.mx.Lock() + as.peers[p] = as.host.Peerstore().Addrs(p) + as.mx.Unlock() + } + }() +} + +func (as *AmbientAutoNAT) Disconnected(net network.Network, c network.Conn) {} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-autonat/pb/Makefile new file mode 100644 index 00000000..dd21e878 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/pb/Makefile @@ -0,0 +1,6 @@ +pbgos := $(patsubst %.proto,%.pb.go,$(wildcard *.proto)) + +all: $(pbgos) + +%.pb.go: %.proto + protoc --gogofast_out=. --proto_path=$(GOPATH)/src:. $< diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.pb.go b/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.pb.go new file mode 100644 index 00000000..3617b461 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.pb.go @@ -0,0 +1,1242 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: autonat.proto + +package autonat_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Message_MessageType int32 + +const ( + Message_DIAL Message_MessageType = 0 + Message_DIAL_RESPONSE Message_MessageType = 1 +) + +var Message_MessageType_name = map[int32]string{ + 0: "DIAL", + 1: "DIAL_RESPONSE", +} + +var Message_MessageType_value = map[string]int32{ + "DIAL": 0, + "DIAL_RESPONSE": 1, +} + +func (x Message_MessageType) Enum() *Message_MessageType { + p := new(Message_MessageType) + *p = x + return p +} + +func (x Message_MessageType) String() string { + return proto.EnumName(Message_MessageType_name, int32(x)) +} + +func (x *Message_MessageType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Message_MessageType_value, data, "Message_MessageType") + if err != nil { + return err + } + *x = Message_MessageType(value) + return nil +} + +func (Message_MessageType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0, 0} +} + +type Message_ResponseStatus int32 + +const ( + Message_OK Message_ResponseStatus = 0 + Message_E_DIAL_ERROR Message_ResponseStatus = 100 + Message_E_DIAL_REFUSED Message_ResponseStatus = 101 + Message_E_BAD_REQUEST Message_ResponseStatus = 200 + Message_E_INTERNAL_ERROR Message_ResponseStatus = 300 +) + +var Message_ResponseStatus_name = map[int32]string{ + 0: "OK", + 100: "E_DIAL_ERROR", + 101: "E_DIAL_REFUSED", + 200: "E_BAD_REQUEST", + 300: "E_INTERNAL_ERROR", +} + +var Message_ResponseStatus_value = map[string]int32{ + "OK": 0, + "E_DIAL_ERROR": 100, + "E_DIAL_REFUSED": 101, + "E_BAD_REQUEST": 200, + "E_INTERNAL_ERROR": 300, +} + +func (x Message_ResponseStatus) Enum() *Message_ResponseStatus { + p := new(Message_ResponseStatus) + *p = x + return p +} + +func (x Message_ResponseStatus) String() string { + return proto.EnumName(Message_ResponseStatus_name, int32(x)) +} + +func (x *Message_ResponseStatus) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Message_ResponseStatus_value, data, "Message_ResponseStatus") + if err != nil { + return err + } + *x = Message_ResponseStatus(value) + return nil +} + +func (Message_ResponseStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0, 1} +} + +type Message struct { + Type *Message_MessageType `protobuf:"varint,1,opt,name=type,enum=autonat.pb.Message_MessageType" json:"type,omitempty"` + Dial *Message_Dial `protobuf:"bytes,2,opt,name=dial" json:"dial,omitempty"` + DialResponse *Message_DialResponse `protobuf:"bytes,3,opt,name=dialResponse" json:"dialResponse,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0} +} +func (m *Message) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) +} +func (m *Message) XXX_Size() int { + return m.Size() +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetType() Message_MessageType { + if m != nil && m.Type != nil { + return *m.Type + } + return Message_DIAL +} + +func (m *Message) GetDial() *Message_Dial { + if m != nil { + return m.Dial + } + return nil +} + +func (m *Message) GetDialResponse() *Message_DialResponse { + if m != nil { + return m.DialResponse + } + return nil +} + +type Message_PeerInfo struct { + Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message_PeerInfo) Reset() { *m = Message_PeerInfo{} } +func (m *Message_PeerInfo) String() string { return proto.CompactTextString(m) } +func (*Message_PeerInfo) ProtoMessage() {} +func (*Message_PeerInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0, 0} +} +func (m *Message_PeerInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_PeerInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_PeerInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_PeerInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_PeerInfo.Merge(m, src) +} +func (m *Message_PeerInfo) XXX_Size() int { + return m.Size() +} +func (m *Message_PeerInfo) XXX_DiscardUnknown() { + xxx_messageInfo_Message_PeerInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_PeerInfo proto.InternalMessageInfo + +func (m *Message_PeerInfo) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Message_PeerInfo) GetAddrs() [][]byte { + if m != nil { + return m.Addrs + } + return nil +} + +type Message_Dial struct { + Peer *Message_PeerInfo `protobuf:"bytes,1,opt,name=peer" json:"peer,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message_Dial) Reset() { *m = Message_Dial{} } +func (m *Message_Dial) String() string { return proto.CompactTextString(m) } +func (*Message_Dial) ProtoMessage() {} +func (*Message_Dial) Descriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0, 1} +} +func (m *Message_Dial) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_Dial) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_Dial.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_Dial) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_Dial.Merge(m, src) +} +func (m *Message_Dial) XXX_Size() int { + return m.Size() +} +func (m *Message_Dial) XXX_DiscardUnknown() { + xxx_messageInfo_Message_Dial.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_Dial proto.InternalMessageInfo + +func (m *Message_Dial) GetPeer() *Message_PeerInfo { + if m != nil { + return m.Peer + } + return nil +} + +type Message_DialResponse struct { + Status *Message_ResponseStatus `protobuf:"varint,1,opt,name=status,enum=autonat.pb.Message_ResponseStatus" json:"status,omitempty"` + StatusText *string `protobuf:"bytes,2,opt,name=statusText" json:"statusText,omitempty"` + Addr []byte `protobuf:"bytes,3,opt,name=addr" json:"addr,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message_DialResponse) Reset() { *m = Message_DialResponse{} } +func (m *Message_DialResponse) String() string { return proto.CompactTextString(m) } +func (*Message_DialResponse) ProtoMessage() {} +func (*Message_DialResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a04e278ef61ac07a, []int{0, 2} +} +func (m *Message_DialResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_DialResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_DialResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_DialResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_DialResponse.Merge(m, src) +} +func (m *Message_DialResponse) XXX_Size() int { + return m.Size() +} +func (m *Message_DialResponse) XXX_DiscardUnknown() { + xxx_messageInfo_Message_DialResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_DialResponse proto.InternalMessageInfo + +func (m *Message_DialResponse) GetStatus() Message_ResponseStatus { + if m != nil && m.Status != nil { + return *m.Status + } + return Message_OK +} + +func (m *Message_DialResponse) GetStatusText() string { + if m != nil && m.StatusText != nil { + return *m.StatusText + } + return "" +} + +func (m *Message_DialResponse) GetAddr() []byte { + if m != nil { + return m.Addr + } + return nil +} + +func init() { + proto.RegisterEnum("autonat.pb.Message_MessageType", Message_MessageType_name, Message_MessageType_value) + proto.RegisterEnum("autonat.pb.Message_ResponseStatus", Message_ResponseStatus_name, Message_ResponseStatus_value) + proto.RegisterType((*Message)(nil), "autonat.pb.Message") + proto.RegisterType((*Message_PeerInfo)(nil), "autonat.pb.Message.PeerInfo") + proto.RegisterType((*Message_Dial)(nil), "autonat.pb.Message.Dial") + proto.RegisterType((*Message_DialResponse)(nil), "autonat.pb.Message.DialResponse") +} + +func init() { proto.RegisterFile("autonat.proto", fileDescriptor_a04e278ef61ac07a) } + +var fileDescriptor_a04e278ef61ac07a = []byte{ + // 372 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xcf, 0x8a, 0xda, 0x50, + 0x14, 0xc6, 0xbd, 0x31, 0xb5, 0xf6, 0x18, 0xc3, 0xed, 0xa1, 0x85, 0x20, 0x25, 0x0d, 0x59, 0x49, + 0x29, 0x22, 0x76, 0x53, 0xba, 0x53, 0x72, 0x0b, 0xd2, 0x56, 0xed, 0x49, 0x5c, 0x87, 0x94, 0xdc, + 0x0e, 0x01, 0x31, 0x21, 0x89, 0x30, 0x6e, 0xe6, 0x89, 0x66, 0x3b, 0xef, 0xe0, 0x72, 0x1e, 0x61, + 0xf0, 0x49, 0x86, 0x5c, 0xa3, 0xa3, 0xe0, 0xac, 0xce, 0x1f, 0x7e, 0xdf, 0x39, 0x1f, 0x1f, 0x74, + 0xa3, 0x4d, 0x99, 0xae, 0xa3, 0x72, 0x90, 0xe5, 0x69, 0x99, 0x22, 0x9c, 0xc6, 0x7f, 0xee, 0x83, + 0x0e, 0x6f, 0xff, 0xc8, 0xa2, 0x88, 0x6e, 0x24, 0x7e, 0x03, 0xbd, 0xdc, 0x66, 0xd2, 0x62, 0x0e, + 0xeb, 0x9b, 0xa3, 0xcf, 0x83, 0x17, 0x6c, 0x50, 0x23, 0xc7, 0x1a, 0x6c, 0x33, 0x49, 0x0a, 0xc6, + 0xaf, 0xa0, 0xc7, 0x49, 0xb4, 0xb2, 0x34, 0x87, 0xf5, 0x3b, 0x23, 0xeb, 0x9a, 0xc8, 0x4b, 0xa2, + 0x15, 0x29, 0x0a, 0x3d, 0x30, 0xaa, 0x4a, 0xb2, 0xc8, 0xd2, 0x75, 0x21, 0xad, 0xa6, 0x52, 0x39, + 0xaf, 0xaa, 0x6a, 0x8e, 0x2e, 0x54, 0xbd, 0x21, 0xb4, 0x17, 0x52, 0xe6, 0xd3, 0xf5, 0xff, 0x14, + 0x4d, 0xd0, 0x92, 0x58, 0x59, 0x36, 0x48, 0x4b, 0x62, 0xfc, 0x00, 0x6f, 0xa2, 0x38, 0xce, 0x0b, + 0x4b, 0x73, 0x9a, 0x7d, 0x83, 0x0e, 0x43, 0xef, 0x3b, 0xe8, 0xd5, 0x3d, 0x1c, 0x82, 0x9e, 0x49, + 0x99, 0x2b, 0xbe, 0x33, 0xfa, 0x74, 0xed, 0xef, 0xf1, 0x32, 0x29, 0xb2, 0x77, 0x07, 0xc6, 0xb9, + 0x13, 0xfc, 0x01, 0xad, 0xa2, 0x8c, 0xca, 0x4d, 0x51, 0xc7, 0xe4, 0x5e, 0xbb, 0x71, 0xa4, 0x7d, + 0x45, 0x52, 0xad, 0x40, 0x1b, 0xe0, 0xd0, 0x05, 0xf2, 0xb6, 0x54, 0x89, 0xbd, 0xa3, 0xb3, 0x0d, + 0x22, 0xe8, 0x95, 0x5d, 0x95, 0x8a, 0x41, 0xaa, 0x77, 0xbf, 0x40, 0xe7, 0x2c, 0x74, 0x6c, 0x83, + 0xee, 0x4d, 0xc7, 0xbf, 0x79, 0x03, 0xdf, 0x43, 0xb7, 0xea, 0x42, 0x12, 0xfe, 0x62, 0x3e, 0xf3, + 0x05, 0x67, 0x6e, 0x02, 0xe6, 0xe5, 0x67, 0x6c, 0x81, 0x36, 0xff, 0xc5, 0x1b, 0xc8, 0xc1, 0x10, + 0xa1, 0xc2, 0x05, 0xd1, 0x9c, 0x78, 0x8c, 0x08, 0x66, 0xbd, 0x21, 0xf1, 0x73, 0xe9, 0x0b, 0x8f, + 0x4b, 0x44, 0xe8, 0x8a, 0x70, 0x32, 0xf6, 0x42, 0x12, 0x7f, 0x97, 0xc2, 0x0f, 0xf8, 0x8e, 0xe1, + 0x47, 0xe0, 0x22, 0x9c, 0xce, 0x02, 0x41, 0xb3, 0x93, 0xfa, 0x5e, 0x9b, 0x18, 0xbb, 0xbd, 0xcd, + 0x1e, 0xf7, 0x36, 0x7b, 0xda, 0xdb, 0xec, 0x39, 0x00, 0x00, 0xff, 0xff, 0x8e, 0xe2, 0x93, 0x4e, + 0x61, 0x02, 0x00, 0x00, +} + +func (m *Message) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type != nil { + dAtA[i] = 0x8 + i++ + i = encodeVarintAutonat(dAtA, i, uint64(*m.Type)) + } + if m.Dial != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintAutonat(dAtA, i, uint64(m.Dial.Size())) + n1, err := m.Dial.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.DialResponse != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintAutonat(dAtA, i, uint64(m.DialResponse.Size())) + n2, err := m.DialResponse.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Message_PeerInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_PeerInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintAutonat(dAtA, i, uint64(len(m.Id))) + i += copy(dAtA[i:], m.Id) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + dAtA[i] = 0x12 + i++ + i = encodeVarintAutonat(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Message_Dial) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_Dial) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Peer != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintAutonat(dAtA, i, uint64(m.Peer.Size())) + n3, err := m.Peer.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Message_DialResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_DialResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Status != nil { + dAtA[i] = 0x8 + i++ + i = encodeVarintAutonat(dAtA, i, uint64(*m.Status)) + } + if m.StatusText != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintAutonat(dAtA, i, uint64(len(*m.StatusText))) + i += copy(dAtA[i:], *m.StatusText) + } + if m.Addr != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintAutonat(dAtA, i, uint64(len(m.Addr))) + i += copy(dAtA[i:], m.Addr) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintAutonat(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Message) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != nil { + n += 1 + sovAutonat(uint64(*m.Type)) + } + if m.Dial != nil { + l = m.Dial.Size() + n += 1 + l + sovAutonat(uint64(l)) + } + if m.DialResponse != nil { + l = m.DialResponse.Size() + n += 1 + l + sovAutonat(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Message_PeerInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = len(m.Id) + n += 1 + l + sovAutonat(uint64(l)) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + l = len(b) + n += 1 + l + sovAutonat(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Message_Dial) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Peer != nil { + l = m.Peer.Size() + n += 1 + l + sovAutonat(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Message_DialResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Status != nil { + n += 1 + sovAutonat(uint64(*m.Status)) + } + if m.StatusText != nil { + l = len(*m.StatusText) + n += 1 + l + sovAutonat(uint64(l)) + } + if m.Addr != nil { + l = len(m.Addr) + n += 1 + l + sovAutonat(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovAutonat(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozAutonat(x uint64) (n int) { + return sovAutonat(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Message) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v Message_MessageType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= Message_MessageType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dial", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Dial == nil { + m.Dial = &Message_Dial{} + } + if err := m.Dial.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DialResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DialResponse == nil { + m.DialResponse = &Message_DialResponse{} + } + if err := m.DialResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAutonat(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_PeerInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PeerInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PeerInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) + copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAutonat(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_Dial) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Dial: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Dial: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Peer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Peer == nil { + m.Peer = &Message_PeerInfo{} + } + if err := m.Peer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAutonat(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_DialResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DialResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DialResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var v Message_ResponseStatus + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= Message_ResponseStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Status = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusText", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + 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 ErrInvalidLengthAutonat + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.StatusText = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAutonat + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAutonat + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAutonat + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addr = append(m.Addr[:0], dAtA[iNdEx:postIndex]...) + if m.Addr == nil { + m.Addr = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAutonat(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthAutonat + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAutonat(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAutonat + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAutonat + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAutonat + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAutonat + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthAutonat + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAutonat + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipAutonat(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthAutonat + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthAutonat = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAutonat = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.proto b/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.proto new file mode 100644 index 00000000..7107e1c0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/pb/autonat.proto @@ -0,0 +1,35 @@ +package autonat.pb; + +message Message { + enum MessageType { + DIAL = 0; + DIAL_RESPONSE = 1; + } + + enum ResponseStatus { + OK = 0; + E_DIAL_ERROR = 100; + E_DIAL_REFUSED = 101; + E_BAD_REQUEST = 200; + E_INTERNAL_ERROR = 300; + } + + message PeerInfo { + optional bytes id = 1; + repeated bytes addrs = 2; + } + + message Dial { + optional PeerInfo peer = 1; + } + + message DialResponse { + optional ResponseStatus status = 1; + optional string statusText = 2; + optional bytes addr = 3; + } + + optional MessageType type = 1; + optional Dial dial = 2; + optional DialResponse dialResponse = 3; +} diff --git a/vendor/github.com/libp2p/go-libp2p-autonat/proto.go b/vendor/github.com/libp2p/go-libp2p-autonat/proto.go new file mode 100644 index 00000000..61ef986d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-autonat/proto.go @@ -0,0 +1,27 @@ +package autonat + +import ( + pb "github.com/libp2p/go-libp2p-autonat/pb" + + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" +) + +const AutoNATProto = "/libp2p/autonat/1.0.0" + +var log = logging.Logger("autonat") + +func newDialMessage(pi peer.AddrInfo) *pb.Message { + msg := new(pb.Message) + msg.Type = pb.Message_DIAL.Enum() + msg.Dial = new(pb.Message_Dial) + msg.Dial.Peer = new(pb.Message_PeerInfo) + msg.Dial.Peer.Id = []byte(pi.ID) + msg.Dial.Peer.Addrs = make([][]byte, len(pi.Addrs)) + for i, addr := range pi.Addrs { + msg.Dial.Peer.Addrs[i] = addr.Bytes() + } + + return msg +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/.travis.yml b/vendor/github.com/libp2p/go-libp2p-circuit/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/LICENSE b/vendor/github.com/libp2p/go-libp2p-circuit/LICENSE new file mode 100644 index 00000000..2f06d0eb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/README.md b/vendor/github.com/libp2p/go-libp2p-circuit/README.md new file mode 100644 index 00000000..b777eb3b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/README.md @@ -0,0 +1,43 @@ +go-libp2p-circuit +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23libp2p) +[![Coverage Status](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-circuit.svg?style=flat-square&branch=master)](https://codecov.io/github/libp2p/go-libp2p-circuit?branch=master) +[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-circuit.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-circuit) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + + +> The libp2p relay allows peers to relay connections on behalf of others. + + +## Table of Contents + +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +go get -u github.com/libp2p/go-libp2p-circuit +``` + +## Usage + +Refer to the [relay example](https://github.com/libp2p/go-libp2p-examples/tree/master/relay) in the `go-libp2p-examples` repository for usage instructions. + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson + +--- + +The last gx published version of this module was: 2.3.15: QmRTkLxADQRbgnhpt2zzQQJr8Ri764b7dujoDkZw33b3iE diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/codecov.yml b/vendor/github.com/libp2p/go-libp2p-circuit/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/conn.go b/vendor/github.com/libp2p/go-libp2p-circuit/conn.go new file mode 100644 index 00000000..8fa53b3d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/conn.go @@ -0,0 +1,102 @@ +package relay + +import ( + "fmt" + "net" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +type Conn struct { + stream network.Stream + remote peer.AddrInfo + host host.Host +} + +type NetAddr struct { + Relay string + Remote string +} + +func (n *NetAddr) Network() string { + return "libp2p-circuit-relay" +} + +func (n *NetAddr) String() string { + return fmt.Sprintf("relay[%s-%s]", n.Remote, n.Relay) +} + +func (c *Conn) Close() error { + c.untagHop() + return c.stream.Reset() +} + +func (c *Conn) Read(buf []byte) (int, error) { + return c.stream.Read(buf) +} + +func (c *Conn) Write(buf []byte) (int, error) { + return c.stream.Write(buf) +} + +func (c *Conn) SetDeadline(t time.Time) error { + return c.stream.SetDeadline(t) +} + +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.stream.SetReadDeadline(t) +} + +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.stream.SetWriteDeadline(t) +} + +func (c *Conn) RemoteAddr() net.Addr { + return &NetAddr{ + Relay: c.stream.Conn().RemotePeer().Pretty(), + Remote: c.remote.ID.Pretty(), + } +} + +// Increment the underlying relay connection tag by 1, thus increasing its protection from +// connection pruning. This ensures that connections to relays are not accidentally closed, +// by the connection manager, taking with them all the relayed connections (that may themselves +// be protected). +func (c *Conn) tagHop() { + c.host.ConnManager().UpsertTag(c.stream.Conn().RemotePeer(), "relay-hop-stream", incrementTag) +} + +// Decrement the underlying relay connection tag by 1; this is performed when we close the +// relayed connection. +func (c *Conn) untagHop() { + c.host.ConnManager().UpsertTag(c.stream.Conn().RemotePeer(), "relay-hop-stream", decrementTag) +} + +// TODO: is it okay to cast c.Conn().RemotePeer() into a multiaddr? might be "user input" +func (c *Conn) RemoteMultiaddr() ma.Multiaddr { + proto := ma.ProtocolWithCode(ma.P_P2P).Name + peerid := c.stream.Conn().RemotePeer().Pretty() + p2paddr := ma.StringCast(fmt.Sprintf("/%s/%s", proto, peerid)) + + circaddr := ma.Cast(ma.CodeToVarint(P_CIRCUIT)) + return p2paddr.Encapsulate(circaddr) +} + +func (c *Conn) LocalMultiaddr() ma.Multiaddr { + return c.stream.Conn().LocalMultiaddr() +} + +func (c *Conn) LocalAddr() net.Addr { + na, err := manet.ToNetAddr(c.stream.Conn().LocalMultiaddr()) + if err != nil { + log.Error("failed to convert local multiaddr to net addr:", err) + return nil + } + return na +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/dial.go b/vendor/github.com/libp2p/go-libp2p-circuit/dial.go new file mode 100644 index 00000000..6668f397 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/dial.go @@ -0,0 +1,89 @@ +package relay + +import ( + "context" + "fmt" + "math/rand" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + ma "github.com/multiformats/go-multiaddr" +) + +func (d *RelayTransport) Dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (transport.CapableConn, error) { + c, err := d.Relay().Dial(ctx, a, p) + if err != nil { + return nil, err + } + c.tagHop() + return d.upgrader.UpgradeOutbound(ctx, d, c, p) +} + +func (r *Relay) Dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, error) { + if !r.Matches(a) { + return nil, fmt.Errorf("%s is not a relay address", a) + } + parts := ma.Split(a) + + spl := ma.Cast(ma.CodeToVarint(P_CIRCUIT)) + + var relayaddr, destaddr ma.Multiaddr + for i, p := range parts { + if p.Equal(spl) { + relayaddr = ma.Join(parts[:i]...) + destaddr = ma.Join(parts[i+1:]...) + break + } + } + + dinfo := &peer.AddrInfo{ID: p, Addrs: []ma.Multiaddr{}} + if len(destaddr.Bytes()) > 0 { + dinfo.Addrs = append(dinfo.Addrs, destaddr) + } + + if len(relayaddr.Bytes()) == 0 { + // unspecific relay address, try dialing using known hop relays + return r.tryDialRelays(ctx, *dinfo) + } + + var rinfo *peer.AddrInfo + rinfo, err := peer.AddrInfoFromP2pAddr(relayaddr) + if err != nil { + return nil, fmt.Errorf("error parsing multiaddr '%s': %s", relayaddr.String(), err) + } + + return r.DialPeer(ctx, *rinfo, *dinfo) +} + +func (r *Relay) tryDialRelays(ctx context.Context, dinfo peer.AddrInfo) (*Conn, error) { + var relays []peer.ID + r.mx.Lock() + for p := range r.relays { + relays = append(relays, p) + } + r.mx.Unlock() + + // shuffle list of relays, avoid overloading a specific relay + for i := range relays { + j := rand.Intn(i + 1) + relays[i], relays[j] = relays[j], relays[i] + } + + for _, relay := range relays { + if len(r.host.Network().ConnsToPeer(relay)) == 0 { + continue + } + + rctx, cancel := context.WithTimeout(ctx, HopConnectTimeout) + c, err := r.DialPeer(rctx, peer.AddrInfo{ID: relay}, dinfo) + cancel() + + if err == nil { + return c, nil + } + + log.Debugf("error opening relay connection through %s: %s", dinfo.ID, err.Error()) + } + + return nil, fmt.Errorf("Failed to dial through %d known relay hosts", len(relays)) +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/go.mod b/vendor/github.com/libp2p/go-libp2p-circuit/go.mod new file mode 100644 index 00000000..c9fb8216 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/go.mod @@ -0,0 +1,13 @@ +module github.com/libp2p/go-libp2p-circuit + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.2 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 +) diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/go.sum b/vendor/github.com/libp2p/go-libp2p-circuit/go.sum new file mode 100644 index 00000000..fd879b2b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/go.sum @@ -0,0 +1,207 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/listen.go b/vendor/github.com/libp2p/go-libp2p-circuit/listen.go new file mode 100644 index 00000000..b00015b5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/listen.go @@ -0,0 +1,59 @@ +package relay + +import ( + "net" + + pb "github.com/libp2p/go-libp2p-circuit/pb" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +var _ manet.Listener = (*RelayListener)(nil) + +type RelayListener Relay + +func (l *RelayListener) Relay() *Relay { + return (*Relay)(l) +} + +func (r *Relay) Listener() *RelayListener { + // TODO: Only allow one! + return (*RelayListener)(r) +} + +func (l *RelayListener) Accept() (manet.Conn, error) { + select { + case c := <-l.incoming: + err := l.Relay().writeResponse(c.stream, pb.CircuitRelay_SUCCESS) + if err != nil { + log.Debugf("error writing relay response: %s", err.Error()) + c.stream.Reset() + return nil, err + } + + // TODO: Pretty print. + log.Infof("accepted relay connection: %q", c) + + c.tagHop() + return c, nil + case <-l.ctx.Done(): + return nil, l.ctx.Err() + } +} + +func (l *RelayListener) Addr() net.Addr { + return &NetAddr{ + Relay: "any", + Remote: "any", + } +} + +func (l *RelayListener) Multiaddr() ma.Multiaddr { + return ma.Cast(ma.CodeToVarint(P_CIRCUIT)) +} + +func (l *RelayListener) Close() error { + // TODO: noop? + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/notify.go b/vendor/github.com/libp2p/go-libp2p-circuit/notify.go new file mode 100644 index 00000000..813daed4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/notify.go @@ -0,0 +1,54 @@ +package relay + +import ( + "context" + "time" + + inet "github.com/libp2p/go-libp2p-core/network" + peer "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" +) + +var _ inet.Notifiee = (*RelayNotifiee)(nil) + +type RelayNotifiee Relay + +func (r *Relay) notifiee() inet.Notifiee { + return (*RelayNotifiee)(r) +} + +func (n *RelayNotifiee) Relay() *Relay { + return (*Relay)(n) +} + +func (n *RelayNotifiee) Listen(net inet.Network, a ma.Multiaddr) {} +func (n *RelayNotifiee) ListenClose(net inet.Network, a ma.Multiaddr) {} +func (n *RelayNotifiee) OpenedStream(net inet.Network, s inet.Stream) {} +func (n *RelayNotifiee) ClosedStream(net inet.Network, s inet.Stream) {} + +func (n *RelayNotifiee) Connected(s inet.Network, c inet.Conn) { + if n.Relay().Matches(c.RemoteMultiaddr()) { + return + } + + go func(id peer.ID) { + ctx, cancel := context.WithTimeout(n.ctx, time.Second) + defer cancel() + + canhop, err := n.Relay().CanHop(ctx, id) + if err != nil { + log.Debugf("Error testing relay hop: %s", err.Error()) + return + } + + if canhop { + log.Debugf("Discovered hop relay %s", id.Pretty()) + n.mx.Lock() + n.relays[id] = struct{}{} + n.mx.Unlock() + n.host.ConnManager().TagPeer(id, "relay-hop", 2) + } + }(c.RemotePeer()) +} + +func (n *RelayNotifiee) Disconnected(s inet.Network, c inet.Conn) {} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-circuit/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.pb.go b/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.pb.go new file mode 100644 index 00000000..ca165ee6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.pb.go @@ -0,0 +1,880 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: relay.proto + +package relay_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type CircuitRelay_Status int32 + +const ( + CircuitRelay_SUCCESS CircuitRelay_Status = 100 + CircuitRelay_HOP_SRC_ADDR_TOO_LONG CircuitRelay_Status = 220 + CircuitRelay_HOP_DST_ADDR_TOO_LONG CircuitRelay_Status = 221 + CircuitRelay_HOP_SRC_MULTIADDR_INVALID CircuitRelay_Status = 250 + CircuitRelay_HOP_DST_MULTIADDR_INVALID CircuitRelay_Status = 251 + CircuitRelay_HOP_NO_CONN_TO_DST CircuitRelay_Status = 260 + CircuitRelay_HOP_CANT_DIAL_DST CircuitRelay_Status = 261 + CircuitRelay_HOP_CANT_OPEN_DST_STREAM CircuitRelay_Status = 262 + CircuitRelay_HOP_CANT_SPEAK_RELAY CircuitRelay_Status = 270 + CircuitRelay_HOP_CANT_RELAY_TO_SELF CircuitRelay_Status = 280 + CircuitRelay_STOP_SRC_ADDR_TOO_LONG CircuitRelay_Status = 320 + CircuitRelay_STOP_DST_ADDR_TOO_LONG CircuitRelay_Status = 321 + CircuitRelay_STOP_SRC_MULTIADDR_INVALID CircuitRelay_Status = 350 + CircuitRelay_STOP_DST_MULTIADDR_INVALID CircuitRelay_Status = 351 + CircuitRelay_STOP_RELAY_REFUSED CircuitRelay_Status = 390 + CircuitRelay_MALFORMED_MESSAGE CircuitRelay_Status = 400 +) + +var CircuitRelay_Status_name = map[int32]string{ + 100: "SUCCESS", + 220: "HOP_SRC_ADDR_TOO_LONG", + 221: "HOP_DST_ADDR_TOO_LONG", + 250: "HOP_SRC_MULTIADDR_INVALID", + 251: "HOP_DST_MULTIADDR_INVALID", + 260: "HOP_NO_CONN_TO_DST", + 261: "HOP_CANT_DIAL_DST", + 262: "HOP_CANT_OPEN_DST_STREAM", + 270: "HOP_CANT_SPEAK_RELAY", + 280: "HOP_CANT_RELAY_TO_SELF", + 320: "STOP_SRC_ADDR_TOO_LONG", + 321: "STOP_DST_ADDR_TOO_LONG", + 350: "STOP_SRC_MULTIADDR_INVALID", + 351: "STOP_DST_MULTIADDR_INVALID", + 390: "STOP_RELAY_REFUSED", + 400: "MALFORMED_MESSAGE", +} + +var CircuitRelay_Status_value = map[string]int32{ + "SUCCESS": 100, + "HOP_SRC_ADDR_TOO_LONG": 220, + "HOP_DST_ADDR_TOO_LONG": 221, + "HOP_SRC_MULTIADDR_INVALID": 250, + "HOP_DST_MULTIADDR_INVALID": 251, + "HOP_NO_CONN_TO_DST": 260, + "HOP_CANT_DIAL_DST": 261, + "HOP_CANT_OPEN_DST_STREAM": 262, + "HOP_CANT_SPEAK_RELAY": 270, + "HOP_CANT_RELAY_TO_SELF": 280, + "STOP_SRC_ADDR_TOO_LONG": 320, + "STOP_DST_ADDR_TOO_LONG": 321, + "STOP_SRC_MULTIADDR_INVALID": 350, + "STOP_DST_MULTIADDR_INVALID": 351, + "STOP_RELAY_REFUSED": 390, + "MALFORMED_MESSAGE": 400, +} + +func (x CircuitRelay_Status) Enum() *CircuitRelay_Status { + p := new(CircuitRelay_Status) + *p = x + return p +} + +func (x CircuitRelay_Status) String() string { + return proto.EnumName(CircuitRelay_Status_name, int32(x)) +} + +func (x *CircuitRelay_Status) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(CircuitRelay_Status_value, data, "CircuitRelay_Status") + if err != nil { + return err + } + *x = CircuitRelay_Status(value) + return nil +} + +func (CircuitRelay_Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9f69a7d5a802d584, []int{0, 0} +} + +type CircuitRelay_Type int32 + +const ( + CircuitRelay_HOP CircuitRelay_Type = 1 + CircuitRelay_STOP CircuitRelay_Type = 2 + CircuitRelay_STATUS CircuitRelay_Type = 3 + CircuitRelay_CAN_HOP CircuitRelay_Type = 4 +) + +var CircuitRelay_Type_name = map[int32]string{ + 1: "HOP", + 2: "STOP", + 3: "STATUS", + 4: "CAN_HOP", +} + +var CircuitRelay_Type_value = map[string]int32{ + "HOP": 1, + "STOP": 2, + "STATUS": 3, + "CAN_HOP": 4, +} + +func (x CircuitRelay_Type) Enum() *CircuitRelay_Type { + p := new(CircuitRelay_Type) + *p = x + return p +} + +func (x CircuitRelay_Type) String() string { + return proto.EnumName(CircuitRelay_Type_name, int32(x)) +} + +func (x *CircuitRelay_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(CircuitRelay_Type_value, data, "CircuitRelay_Type") + if err != nil { + return err + } + *x = CircuitRelay_Type(value) + return nil +} + +func (CircuitRelay_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9f69a7d5a802d584, []int{0, 1} +} + +type CircuitRelay struct { + Type *CircuitRelay_Type `protobuf:"varint,1,opt,name=type,enum=relay.pb.CircuitRelay_Type" json:"type,omitempty"` + SrcPeer *CircuitRelay_Peer `protobuf:"bytes,2,opt,name=srcPeer" json:"srcPeer,omitempty"` + DstPeer *CircuitRelay_Peer `protobuf:"bytes,3,opt,name=dstPeer" json:"dstPeer,omitempty"` + Code *CircuitRelay_Status `protobuf:"varint,4,opt,name=code,enum=relay.pb.CircuitRelay_Status" json:"code,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CircuitRelay) Reset() { *m = CircuitRelay{} } +func (m *CircuitRelay) String() string { return proto.CompactTextString(m) } +func (*CircuitRelay) ProtoMessage() {} +func (*CircuitRelay) Descriptor() ([]byte, []int) { + return fileDescriptor_9f69a7d5a802d584, []int{0} +} +func (m *CircuitRelay) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CircuitRelay) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CircuitRelay.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CircuitRelay) XXX_Merge(src proto.Message) { + xxx_messageInfo_CircuitRelay.Merge(m, src) +} +func (m *CircuitRelay) XXX_Size() int { + return m.Size() +} +func (m *CircuitRelay) XXX_DiscardUnknown() { + xxx_messageInfo_CircuitRelay.DiscardUnknown(m) +} + +var xxx_messageInfo_CircuitRelay proto.InternalMessageInfo + +func (m *CircuitRelay) GetType() CircuitRelay_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return CircuitRelay_HOP +} + +func (m *CircuitRelay) GetSrcPeer() *CircuitRelay_Peer { + if m != nil { + return m.SrcPeer + } + return nil +} + +func (m *CircuitRelay) GetDstPeer() *CircuitRelay_Peer { + if m != nil { + return m.DstPeer + } + return nil +} + +func (m *CircuitRelay) GetCode() CircuitRelay_Status { + if m != nil && m.Code != nil { + return *m.Code + } + return CircuitRelay_SUCCESS +} + +type CircuitRelay_Peer struct { + Id []byte `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CircuitRelay_Peer) Reset() { *m = CircuitRelay_Peer{} } +func (m *CircuitRelay_Peer) String() string { return proto.CompactTextString(m) } +func (*CircuitRelay_Peer) ProtoMessage() {} +func (*CircuitRelay_Peer) Descriptor() ([]byte, []int) { + return fileDescriptor_9f69a7d5a802d584, []int{0, 0} +} +func (m *CircuitRelay_Peer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CircuitRelay_Peer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CircuitRelay_Peer.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CircuitRelay_Peer) XXX_Merge(src proto.Message) { + xxx_messageInfo_CircuitRelay_Peer.Merge(m, src) +} +func (m *CircuitRelay_Peer) XXX_Size() int { + return m.Size() +} +func (m *CircuitRelay_Peer) XXX_DiscardUnknown() { + xxx_messageInfo_CircuitRelay_Peer.DiscardUnknown(m) +} + +var xxx_messageInfo_CircuitRelay_Peer proto.InternalMessageInfo + +func (m *CircuitRelay_Peer) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *CircuitRelay_Peer) GetAddrs() [][]byte { + if m != nil { + return m.Addrs + } + return nil +} + +func init() { + proto.RegisterEnum("relay.pb.CircuitRelay_Status", CircuitRelay_Status_name, CircuitRelay_Status_value) + proto.RegisterEnum("relay.pb.CircuitRelay_Type", CircuitRelay_Type_name, CircuitRelay_Type_value) + proto.RegisterType((*CircuitRelay)(nil), "relay.pb.CircuitRelay") + proto.RegisterType((*CircuitRelay_Peer)(nil), "relay.pb.CircuitRelay.Peer") +} + +func init() { proto.RegisterFile("relay.proto", fileDescriptor_9f69a7d5a802d584) } + +var fileDescriptor_9f69a7d5a802d584 = []byte{ + // 473 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x6f, 0xd3, 0x3e, + 0x18, 0xc7, 0x65, 0x27, 0xbf, 0x76, 0x7a, 0x5a, 0x4d, 0xfe, 0x59, 0x63, 0x64, 0x9d, 0x56, 0xaa, + 0x9e, 0x7a, 0x40, 0x45, 0x4c, 0xe2, 0x05, 0x98, 0xc4, 0xdd, 0x2a, 0xd2, 0x38, 0xb2, 0x5d, 0x24, + 0x4e, 0x56, 0x69, 0x72, 0xa8, 0x84, 0xd4, 0x2a, 0xcd, 0x0e, 0xbd, 0xc3, 0xb8, 0x21, 0x8e, 0xbc, + 0x1c, 0xe0, 0xc4, 0x91, 0x17, 0xc0, 0x3f, 0xf5, 0x65, 0xc0, 0x05, 0xd9, 0x5d, 0x33, 0x44, 0x37, + 0x89, 0xa3, 0x9f, 0xef, 0xe7, 0xe3, 0x3c, 0xf9, 0x26, 0xd0, 0x28, 0xf2, 0x17, 0x93, 0x55, 0x7f, + 0x51, 0xcc, 0xcb, 0x39, 0xdd, 0xbb, 0x3a, 0x3c, 0xef, 0xbe, 0xae, 0x41, 0x33, 0x9c, 0x15, 0xd3, + 0x8b, 0x59, 0x29, 0xed, 0x8c, 0x3e, 0x00, 0xbf, 0x5c, 0x2d, 0xf2, 0x00, 0x75, 0x50, 0x6f, 0xff, + 0xf4, 0xb8, 0xbf, 0x25, 0xfb, 0x7f, 0x52, 0x7d, 0xbd, 0x5a, 0xe4, 0xd2, 0x81, 0xf4, 0x11, 0xd4, + 0x97, 0xc5, 0x34, 0xcd, 0xf3, 0x22, 0xc0, 0x1d, 0xd4, 0x6b, 0xdc, 0xea, 0x58, 0x44, 0x6e, 0x59, + 0xab, 0x65, 0xcb, 0xd2, 0x69, 0xde, 0x3f, 0x68, 0x57, 0x2c, 0x7d, 0x08, 0xfe, 0x74, 0x9e, 0xe5, + 0x81, 0xef, 0xd6, 0x3b, 0xb9, 0xc5, 0x51, 0xe5, 0xa4, 0xbc, 0x58, 0x4a, 0x87, 0xb6, 0xee, 0x83, + 0xef, 0xd4, 0x7d, 0xc0, 0xb3, 0x2c, 0x40, 0x1d, 0xdc, 0x6b, 0x4a, 0x3c, 0xcb, 0xe8, 0x01, 0xfc, + 0x37, 0xc9, 0xb2, 0x62, 0x19, 0xe0, 0x8e, 0xd7, 0x6b, 0xca, 0xcd, 0xa1, 0xfb, 0xd1, 0x83, 0xda, + 0x46, 0xa7, 0x0d, 0xa8, 0xab, 0x71, 0x18, 0x72, 0xa5, 0x48, 0x46, 0x5b, 0x70, 0xe7, 0x5c, 0xa4, + 0x46, 0xc9, 0xd0, 0xb0, 0x28, 0x92, 0x46, 0x0b, 0x61, 0x62, 0x91, 0x9c, 0x91, 0x2f, 0x68, 0x9b, + 0x45, 0x4a, 0xff, 0x95, 0x7d, 0x45, 0xb4, 0x0d, 0x47, 0x5b, 0x6f, 0x34, 0x8e, 0xf5, 0xd0, 0x01, + 0xc3, 0xe4, 0x29, 0x8b, 0x87, 0x11, 0xf9, 0x59, 0xe5, 0xd6, 0xdd, 0xcd, 0x7f, 0x21, 0x7a, 0x17, + 0xa8, 0xcd, 0x13, 0x61, 0x42, 0x91, 0x24, 0x46, 0x0b, 0x8b, 0x92, 0x97, 0x98, 0x1e, 0xc2, 0xff, + 0x36, 0x08, 0x59, 0xa2, 0x4d, 0x34, 0x64, 0xb1, 0x9b, 0xbf, 0xc2, 0xf4, 0x04, 0x82, 0x6a, 0x2e, + 0x52, 0x9e, 0xb8, 0xab, 0x95, 0x96, 0x9c, 0x8d, 0xc8, 0x25, 0xa6, 0x47, 0x70, 0x50, 0xc5, 0x2a, + 0xe5, 0xec, 0x89, 0x91, 0x3c, 0x66, 0xcf, 0xc8, 0x1b, 0x4c, 0x8f, 0xe1, 0xb0, 0x8a, 0xdc, 0xd0, + 0x3e, 0x4d, 0xf1, 0x78, 0x40, 0xde, 0xb9, 0x50, 0xe9, 0x1b, 0x0b, 0x78, 0x7f, 0x1d, 0xee, 0x36, + 0xf0, 0x01, 0xd3, 0x7b, 0xd0, 0xaa, 0xcc, 0xdd, 0x57, 0xfc, 0x76, 0x0d, 0xdc, 0xdc, 0xc1, 0x77, + 0x6c, 0x3b, 0x70, 0xc0, 0x66, 0x29, 0xc9, 0x07, 0x63, 0xc5, 0x23, 0x72, 0xe9, 0xd9, 0x0e, 0x46, + 0x2c, 0x1e, 0x08, 0x39, 0xe2, 0x91, 0x19, 0x71, 0xa5, 0xd8, 0x19, 0x27, 0x6f, 0xbd, 0xee, 0x29, + 0xf8, 0xf6, 0x0f, 0xa5, 0x75, 0xf0, 0xce, 0x45, 0x4a, 0x10, 0xdd, 0x03, 0xdf, 0xde, 0x40, 0x30, + 0x05, 0xa8, 0x29, 0xcd, 0xf4, 0x58, 0x11, 0xcf, 0x7e, 0xe0, 0x90, 0x25, 0xc6, 0x22, 0xfe, 0xe3, + 0xe6, 0xa7, 0x75, 0x1b, 0x7d, 0x5e, 0xb7, 0xd1, 0x8f, 0x75, 0x1b, 0xfd, 0x0e, 0x00, 0x00, 0xff, + 0xff, 0x6b, 0x22, 0x33, 0xbb, 0x2f, 0x03, 0x00, 0x00, +} + +func (m *CircuitRelay) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CircuitRelay) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type != nil { + dAtA[i] = 0x8 + i++ + i = encodeVarintRelay(dAtA, i, uint64(*m.Type)) + } + if m.SrcPeer != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRelay(dAtA, i, uint64(m.SrcPeer.Size())) + n1, err := m.SrcPeer.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.DstPeer != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintRelay(dAtA, i, uint64(m.DstPeer.Size())) + n2, err := m.DstPeer.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Code != nil { + dAtA[i] = 0x20 + i++ + i = encodeVarintRelay(dAtA, i, uint64(*m.Code)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *CircuitRelay_Peer) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CircuitRelay_Peer) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { + dAtA[i] = 0xa + i++ + i = encodeVarintRelay(dAtA, i, uint64(len(m.Id))) + i += copy(dAtA[i:], m.Id) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + dAtA[i] = 0x12 + i++ + i = encodeVarintRelay(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintRelay(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *CircuitRelay) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != nil { + n += 1 + sovRelay(uint64(*m.Type)) + } + if m.SrcPeer != nil { + l = m.SrcPeer.Size() + n += 1 + l + sovRelay(uint64(l)) + } + if m.DstPeer != nil { + l = m.DstPeer.Size() + n += 1 + l + sovRelay(uint64(l)) + } + if m.Code != nil { + n += 1 + sovRelay(uint64(*m.Code)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CircuitRelay_Peer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = len(m.Id) + n += 1 + l + sovRelay(uint64(l)) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + l = len(b) + n += 1 + l + sovRelay(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovRelay(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRelay(x uint64) (n int) { + return sovRelay(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *CircuitRelay) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CircuitRelay: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CircuitRelay: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v CircuitRelay_Type + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= CircuitRelay_Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SrcPeer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRelay + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRelay + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SrcPeer == nil { + m.SrcPeer = &CircuitRelay_Peer{} + } + if err := m.SrcPeer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DstPeer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRelay + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRelay + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DstPeer == nil { + m.DstPeer = &CircuitRelay_Peer{} + } + if err := m.DstPeer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + var v CircuitRelay_Status + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= CircuitRelay_Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Code = &v + default: + iNdEx = preIndex + skippy, err := skipRelay(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRelay + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRelay + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CircuitRelay_Peer) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Peer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Peer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRelay + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRelay + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRelay + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRelay + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRelay + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) + copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRelay(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRelay + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRelay + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRelay(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRelay + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRelay + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRelay + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthRelay + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthRelay + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRelay + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRelay(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthRelay + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRelay = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRelay = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.proto b/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.proto new file mode 100644 index 00000000..de3e637b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/pb/relay.proto @@ -0,0 +1,44 @@ +syntax = "proto2"; + +package relay.pb; + +message CircuitRelay { + + enum Status { + SUCCESS = 100; + HOP_SRC_ADDR_TOO_LONG = 220; + HOP_DST_ADDR_TOO_LONG = 221; + HOP_SRC_MULTIADDR_INVALID = 250; + HOP_DST_MULTIADDR_INVALID = 251; + HOP_NO_CONN_TO_DST = 260; + HOP_CANT_DIAL_DST = 261; + HOP_CANT_OPEN_DST_STREAM = 262; + HOP_CANT_SPEAK_RELAY = 270; + HOP_CANT_RELAY_TO_SELF = 280; + STOP_SRC_ADDR_TOO_LONG = 320; + STOP_DST_ADDR_TOO_LONG = 321; + STOP_SRC_MULTIADDR_INVALID = 350; + STOP_DST_MULTIADDR_INVALID = 351; + STOP_RELAY_REFUSED = 390; + MALFORMED_MESSAGE = 400; + } + + enum Type { // RPC identifier, either HOP, STOP or STATUS + HOP = 1; + STOP = 2; + STATUS = 3; + CAN_HOP = 4; + } + + message Peer { + required bytes id = 1; // peer id + repeated bytes addrs = 2; // peer's known addresses + } + + optional Type type = 1; // Type of the message + + optional Peer srcPeer = 2; // srcPeer and dstPeer are used when Type is HOP or STOP + optional Peer dstPeer = 3; + + optional Status code = 4; // Status code, used when Type is STATUS +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/relay.go b/vendor/github.com/libp2p/go-libp2p-circuit/relay.go new file mode 100644 index 00000000..1bb7cc0d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/relay.go @@ -0,0 +1,491 @@ +package relay + +import ( + "context" + "fmt" + "io" + "sync" + "sync/atomic" + "time" + + pb "github.com/libp2p/go-libp2p-circuit/pb" + + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + + pool "github.com/libp2p/go-buffer-pool" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + + logging "github.com/ipfs/go-log" + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("relay") + +const ProtoID = "/libp2p/circuit/relay/0.1.0" + +const maxMessageSize = 4096 + +var ( + RelayAcceptTimeout = 10 * time.Second + HopConnectTimeout = 30 * time.Second + StopHandshakeTimeout = 1 * time.Minute + + HopStreamBufferSize = 4096 + HopStreamLimit = 1 << 19 // 512K hops for 1M goroutines +) + +// Relay is the relay transport and service. +type Relay struct { + host host.Host + upgrader *tptu.Upgrader + ctx context.Context + self peer.ID + + active bool + hop bool + discovery bool + + incoming chan *Conn + + relays map[peer.ID]struct{} + mx sync.Mutex + + // atomic counters + streamCount int32 + liveHopCount int32 +} + +// RelayOpts are options for configuring the relay transport. +type RelayOpt int + +var ( + // OptActive configures the relay transport to actively establish + // outbound connections on behalf of clients. You probably don't want to + // enable this unless you know what you're doing. + OptActive = RelayOpt(0) + // OptHop configures the relay transport to accept requests to relay + // traffic on behalf of third-parties. Unless OptActive is specified, + // this will only relay traffic between peers already connected to this + // node. + OptHop = RelayOpt(1) + // OptDiscovery configures this relay transport to discover new relays + // by probing every new peer. You almost _certainly_ don't want to + // enable this. + OptDiscovery = RelayOpt(2) +) + +type RelayError struct { + Code pb.CircuitRelay_Status +} + +func (e RelayError) Error() string { + return fmt.Sprintf("error opening relay circuit: %s (%d)", pb.CircuitRelay_Status_name[int32(e.Code)], e.Code) +} + +// NewRelay constructs a new relay. +func NewRelay(ctx context.Context, h host.Host, upgrader *tptu.Upgrader, opts ...RelayOpt) (*Relay, error) { + r := &Relay{ + upgrader: upgrader, + host: h, + ctx: ctx, + self: h.ID(), + incoming: make(chan *Conn), + relays: make(map[peer.ID]struct{}), + } + + for _, opt := range opts { + switch opt { + case OptActive: + r.active = true + case OptHop: + r.hop = true + case OptDiscovery: + r.discovery = true + default: + return nil, fmt.Errorf("unrecognized option: %d", opt) + } + } + + h.SetStreamHandler(ProtoID, r.handleNewStream) + + if r.discovery { + h.Network().Notify(r.notifiee()) + } + + return r, nil +} + +// Increment the live hop count and increment the connection manager tags by 1 for the two +// sides of the hop stream. This ensures that connections with many hop streams will be protected +// from pruning, thus minimizing disruption from connection trimming in a relay node. +func (r *Relay) addLiveHop(from, to peer.ID) { + atomic.AddInt32(&r.liveHopCount, 1) + r.host.ConnManager().UpsertTag(from, "relay-hop-stream", incrementTag) + r.host.ConnManager().UpsertTag(to, "relay-hop-stream", incrementTag) +} + +// Decrement the live hpo count and decrement the connection manager tags for the two sides +// of the hop stream. +func (r *Relay) rmLiveHop(from, to peer.ID) { + atomic.AddInt32(&r.liveHopCount, -1) + r.host.ConnManager().UpsertTag(from, "relay-hop-stream", decrementTag) + r.host.ConnManager().UpsertTag(to, "relay-hop-stream", decrementTag) + +} + +func (r *Relay) GetActiveHops() int32 { + return atomic.LoadInt32(&r.liveHopCount) +} + +func (r *Relay) DialPeer(ctx context.Context, relay peer.AddrInfo, dest peer.AddrInfo) (*Conn, error) { + + log.Debugf("dialing peer %s through relay %s", dest.ID, relay.ID) + + if len(relay.Addrs) > 0 { + r.host.Peerstore().AddAddrs(relay.ID, relay.Addrs, peerstore.TempAddrTTL) + } + + s, err := r.host.NewStream(ctx, relay.ID, ProtoID) + if err != nil { + return nil, err + } + + rd := newDelimitedReader(s, maxMessageSize) + wr := newDelimitedWriter(s) + defer rd.Close() + + var msg pb.CircuitRelay + + msg.Type = pb.CircuitRelay_HOP.Enum() + msg.SrcPeer = peerInfoToPeer(r.host.Peerstore().PeerInfo(r.self)) + msg.DstPeer = peerInfoToPeer(dest) + + err = wr.WriteMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + + msg.Reset() + + err = rd.ReadMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + + if msg.GetType() != pb.CircuitRelay_STATUS { + s.Reset() + return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + } + + if msg.GetCode() != pb.CircuitRelay_SUCCESS { + s.Reset() + return nil, RelayError{msg.GetCode()} + } + + return &Conn{stream: s, remote: dest, host: r.host}, nil +} + +func (r *Relay) Matches(addr ma.Multiaddr) bool { + // TODO: Look at the prefix transport as well. + _, err := addr.ValueForProtocol(P_CIRCUIT) + return err == nil +} + +func (r *Relay) CanHop(ctx context.Context, id peer.ID) (bool, error) { + s, err := r.host.NewStream(ctx, id, ProtoID) + if err != nil { + return false, err + } + + rd := newDelimitedReader(s, maxMessageSize) + wr := newDelimitedWriter(s) + defer rd.Close() + + var msg pb.CircuitRelay + + msg.Type = pb.CircuitRelay_CAN_HOP.Enum() + + if err := wr.WriteMsg(&msg); err != nil { + s.Reset() + return false, err + } + + msg.Reset() + + if err := rd.ReadMsg(&msg); err != nil { + s.Reset() + return false, err + } + if err := helpers.FullClose(s); err != nil { + return false, err + } + + if msg.GetType() != pb.CircuitRelay_STATUS { + return false, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + } + + return msg.GetCode() == pb.CircuitRelay_SUCCESS, nil +} + +func (r *Relay) handleNewStream(s network.Stream) { + log.Infof("new relay stream from: %s", s.Conn().RemotePeer()) + + rd := newDelimitedReader(s, maxMessageSize) + defer rd.Close() + + var msg pb.CircuitRelay + + err := rd.ReadMsg(&msg) + if err != nil { + r.handleError(s, pb.CircuitRelay_MALFORMED_MESSAGE) + return + } + + switch msg.GetType() { + case pb.CircuitRelay_HOP: + r.handleHopStream(s, &msg) + case pb.CircuitRelay_STOP: + r.handleStopStream(s, &msg) + case pb.CircuitRelay_CAN_HOP: + r.handleCanHop(s, &msg) + default: + log.Warningf("unexpected relay handshake: %d", msg.GetType()) + r.handleError(s, pb.CircuitRelay_MALFORMED_MESSAGE) + } +} + +func (r *Relay) handleHopStream(s network.Stream, msg *pb.CircuitRelay) { + if !r.hop { + r.handleError(s, pb.CircuitRelay_HOP_CANT_SPEAK_RELAY) + return + } + + streamCount := atomic.AddInt32(&r.streamCount, 1) + liveHopCount := atomic.LoadInt32(&r.liveHopCount) + defer atomic.AddInt32(&r.streamCount, -1) + + if (streamCount + liveHopCount) > int32(HopStreamLimit) { + log.Warning("hop stream limit exceeded; resetting stream") + s.Reset() + return + } + + src, err := peerToPeerInfo(msg.GetSrcPeer()) + if err != nil { + r.handleError(s, pb.CircuitRelay_HOP_SRC_MULTIADDR_INVALID) + return + } + + if src.ID != s.Conn().RemotePeer() { + r.handleError(s, pb.CircuitRelay_HOP_SRC_MULTIADDR_INVALID) + return + } + + dst, err := peerToPeerInfo(msg.GetDstPeer()) + if err != nil { + r.handleError(s, pb.CircuitRelay_HOP_DST_MULTIADDR_INVALID) + return + } + + if dst.ID == r.self { + r.handleError(s, pb.CircuitRelay_HOP_CANT_RELAY_TO_SELF) + return + } + + // open stream + ctx, cancel := context.WithTimeout(r.ctx, HopConnectTimeout) + defer cancel() + + if !r.active { + ctx = network.WithNoDial(ctx, "relay hop") + } else if len(dst.Addrs) > 0 { + r.host.Peerstore().AddAddrs(dst.ID, dst.Addrs, peerstore.TempAddrTTL) + } + + bs, err := r.host.NewStream(ctx, dst.ID, ProtoID) + if err != nil { + log.Debugf("error opening relay stream to %s: %s", dst.ID.Pretty(), err.Error()) + if err == network.ErrNoConn { + r.handleError(s, pb.CircuitRelay_HOP_NO_CONN_TO_DST) + } else { + r.handleError(s, pb.CircuitRelay_HOP_CANT_DIAL_DST) + } + return + } + + // stop handshake + rd := newDelimitedReader(bs, maxMessageSize) + wr := newDelimitedWriter(bs) + defer rd.Close() + + // set handshake deadline + bs.SetDeadline(time.Now().Add(StopHandshakeTimeout)) + + msg.Type = pb.CircuitRelay_STOP.Enum() + + err = wr.WriteMsg(msg) + if err != nil { + log.Debugf("error writing stop handshake: %s", err.Error()) + bs.Reset() + r.handleError(s, pb.CircuitRelay_HOP_CANT_OPEN_DST_STREAM) + return + } + + msg.Reset() + + err = rd.ReadMsg(msg) + if err != nil { + log.Debugf("error reading stop response: %s", err.Error()) + bs.Reset() + r.handleError(s, pb.CircuitRelay_HOP_CANT_OPEN_DST_STREAM) + return + } + + if msg.GetType() != pb.CircuitRelay_STATUS { + log.Debugf("unexpected relay stop response: not a status message (%d)", msg.GetType()) + bs.Reset() + r.handleError(s, pb.CircuitRelay_HOP_CANT_OPEN_DST_STREAM) + return + } + + if msg.GetCode() != pb.CircuitRelay_SUCCESS { + log.Debugf("relay stop failure: %d", msg.GetCode()) + bs.Reset() + r.handleError(s, msg.GetCode()) + return + } + + err = r.writeResponse(s, pb.CircuitRelay_SUCCESS) + if err != nil { + log.Debugf("error writing relay response: %s", err.Error()) + bs.Reset() + s.Reset() + return + } + + // relay connection + log.Infof("relaying connection between %s and %s", src.ID.Pretty(), dst.ID.Pretty()) + + // reset deadline + bs.SetDeadline(time.Time{}) + + r.addLiveHop(src.ID, dst.ID) + + goroutines := new(int32) + *goroutines = 2 + done := func() { + if atomic.AddInt32(goroutines, -1) == 0 { + r.rmLiveHop(src.ID, dst.ID) + } + } + + // Don't reset streams after finishing or the other side will get an + // error, not an EOF. + go func() { + defer done() + + buf := pool.Get(HopStreamBufferSize) + defer pool.Put(buf) + + count, err := io.CopyBuffer(s, bs, buf) + if err != nil { + log.Debugf("relay copy error: %s", err) + // Reset both. + s.Reset() + bs.Reset() + } else { + // propagate the close + s.Close() + } + log.Debugf("relayed %d bytes from %s to %s", count, dst.ID.Pretty(), src.ID.Pretty()) + }() + + go func() { + defer done() + + buf := pool.Get(HopStreamBufferSize) + defer pool.Put(buf) + + count, err := io.CopyBuffer(bs, s, buf) + if err != nil { + log.Debugf("relay copy error: %s", err) + // Reset both. + bs.Reset() + s.Reset() + } else { + // propagate the close + bs.Close() + } + log.Debugf("relayed %d bytes from %s to %s", count, src.ID.Pretty(), dst.ID.Pretty()) + }() +} + +func (r *Relay) handleStopStream(s network.Stream, msg *pb.CircuitRelay) { + src, err := peerToPeerInfo(msg.GetSrcPeer()) + if err != nil { + r.handleError(s, pb.CircuitRelay_STOP_SRC_MULTIADDR_INVALID) + return + } + + dst, err := peerToPeerInfo(msg.GetDstPeer()) + if err != nil || dst.ID != r.self { + r.handleError(s, pb.CircuitRelay_STOP_DST_MULTIADDR_INVALID) + return + } + + log.Infof("relay connection from: %s", src.ID) + + if len(src.Addrs) > 0 { + r.host.Peerstore().AddAddrs(src.ID, src.Addrs, peerstore.TempAddrTTL) + } + + select { + case r.incoming <- &Conn{stream: s, remote: src, host: r.host}: + case <-time.After(RelayAcceptTimeout): + r.handleError(s, pb.CircuitRelay_STOP_RELAY_REFUSED) + } +} + +func (r *Relay) handleCanHop(s network.Stream, msg *pb.CircuitRelay) { + var err error + + if r.hop { + err = r.writeResponse(s, pb.CircuitRelay_SUCCESS) + } else { + err = r.writeResponse(s, pb.CircuitRelay_HOP_CANT_SPEAK_RELAY) + } + + if err != nil { + s.Reset() + log.Debugf("error writing relay response: %s", err.Error()) + } else { + helpers.FullClose(s) + } +} + +func (r *Relay) handleError(s network.Stream, code pb.CircuitRelay_Status) { + log.Warningf("relay error: %s (%d)", pb.CircuitRelay_Status_name[int32(code)], code) + err := r.writeResponse(s, code) + if err != nil { + s.Reset() + log.Debugf("error writing relay response: %s", err.Error()) + } else { + helpers.FullClose(s) + } +} + +func (r *Relay) writeResponse(s network.Stream, code pb.CircuitRelay_Status) error { + wr := newDelimitedWriter(s) + + var msg pb.CircuitRelay + msg.Type = pb.CircuitRelay_STATUS.Enum() + msg.Code = code.Enum() + + return wr.WriteMsg(&msg) +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/transport.go b/vendor/github.com/libp2p/go-libp2p-circuit/transport.go new file mode 100644 index 00000000..57a65779 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/transport.go @@ -0,0 +1,81 @@ +package relay + +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/transport" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + ma "github.com/multiformats/go-multiaddr" +) + +const P_CIRCUIT = 290 + +var Protocol = ma.Protocol{ + Code: P_CIRCUIT, + Size: 0, + Name: "p2p-circuit", + VCode: ma.CodeToVarint(P_CIRCUIT), +} + +func init() { + ma.AddProtocol(Protocol) +} + +var _ transport.Transport = (*RelayTransport)(nil) + +type RelayTransport Relay + +func (t *RelayTransport) Relay() *Relay { + return (*Relay)(t) +} + +func (r *Relay) Transport() *RelayTransport { + return (*RelayTransport)(r) +} + +func (t *RelayTransport) Listen(laddr ma.Multiaddr) (transport.Listener, error) { + // TODO: Ensure we have a connection to the relay, if specified. Also, + // make sure the multiaddr makes sense. + if !t.Relay().Matches(laddr) { + return nil, fmt.Errorf("%s is not a relay address", laddr) + } + return t.upgrader.UpgradeListener(t, t.Relay().Listener()), nil +} + +func (t *RelayTransport) CanDial(raddr ma.Multiaddr) bool { + return t.Relay().Matches(raddr) +} + +func (t *RelayTransport) Proxy() bool { + return true +} + +func (t *RelayTransport) Protocols() []int { + return []int{P_CIRCUIT} +} + +// AddRelayTransport constructs a relay and adds it as a transport to the host network. +func AddRelayTransport(ctx context.Context, h host.Host, upgrader *tptu.Upgrader, opts ...RelayOpt) error { + n, ok := h.Network().(transport.TransportNetwork) + if !ok { + return fmt.Errorf("%v is not a transport network", h.Network()) + } + + r, err := NewRelay(ctx, h, upgrader, opts...) + if err != nil { + return err + } + + // There's no nice way to handle these errors as we have no way to tear + // down the relay. + // TODO + if err := n.AddTransport(r.Transport()); err != nil { + log.Error("failed to add relay transport:", err) + } else if err := n.Listen(r.Listener().Multiaddr()); err != nil { + log.Error("failed to listen on relay transport:", err) + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-circuit/util.go b/vendor/github.com/libp2p/go-libp2p-circuit/util.go new file mode 100644 index 00000000..ca7a23f3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-circuit/util.go @@ -0,0 +1,117 @@ +package relay + +import ( + "encoding/binary" + "errors" + "io" + + pb "github.com/libp2p/go-libp2p-circuit/pb" + + "github.com/libp2p/go-libp2p-core/peer" + + ggio "github.com/gogo/protobuf/io" + proto "github.com/gogo/protobuf/proto" + pool "github.com/libp2p/go-buffer-pool" + ma "github.com/multiformats/go-multiaddr" +) + +func peerToPeerInfo(p *pb.CircuitRelay_Peer) (peer.AddrInfo, error) { + if p == nil { + return peer.AddrInfo{}, errors.New("nil peer") + } + + id, err := peer.IDFromBytes(p.Id) + if err != nil { + return peer.AddrInfo{}, err + } + + addrs := make([]ma.Multiaddr, 0, len(p.Addrs)) + for _, addrBytes := range p.Addrs { + a, err := ma.NewMultiaddrBytes(addrBytes) + if err == nil { + addrs = append(addrs, a) + } + } + + return peer.AddrInfo{ID: id, Addrs: addrs}, nil +} + +func peerInfoToPeer(pi peer.AddrInfo) *pb.CircuitRelay_Peer { + addrs := make([][]byte, len(pi.Addrs)) + for i, addr := range pi.Addrs { + addrs[i] = addr.Bytes() + } + + p := new(pb.CircuitRelay_Peer) + p.Id = []byte(pi.ID) + p.Addrs = addrs + + return p +} + +func incrementTag(v int) int { + return v + 1 +} + +func decrementTag(v int) int { + if v > 0 { + return v - 1 + } else { + return v + } +} + +type delimitedReader struct { + r io.Reader + buf []byte +} + +// The gogo protobuf NewDelimitedReader is buffered, which may eat up stream data. +// So we need to implement a compatible delimited reader that reads unbuffered. +// There is a slowdown from unbuffered reading: when reading the message +// it can take multiple single byte Reads to read the length and another Read +// to read the message payload. +// However, this is not critical performance degradation as +// - the reader is utilized to read one (dialer, stop) or two messages (hop) during +// the handshake, so it's a drop in the water for the connection lifetime. +// - messages are small (max 4k) and the length fits in a couple of bytes, +// so overall we have at most three reads per message. +func newDelimitedReader(r io.Reader, maxSize int) *delimitedReader { + return &delimitedReader{r: r, buf: pool.Get(maxSize)} +} + +func (d *delimitedReader) Close() { + if d.buf != nil { + pool.Put(d.buf) + d.buf = nil + } +} + +func (d *delimitedReader) ReadByte() (byte, error) { + buf := d.buf[:1] + _, err := d.r.Read(buf) + return buf[0], err +} + +func (d *delimitedReader) ReadMsg(msg proto.Message) error { + mlen, err := binary.ReadUvarint(d) + if err != nil { + return err + } + + if uint64(len(d.buf)) < mlen { + return errors.New("Message too large") + } + + buf := d.buf[:mlen] + _, err = io.ReadFull(d.r, buf) + if err != nil { + return err + } + + return proto.Unmarshal(buf, msg) +} + +func newDelimitedWriter(w io.Writer) ggio.WriteCloser { + return ggio.NewDelimitedWriter(w) +} diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/.travis.yml b/vendor/github.com/libp2p/go-libp2p-connmgr/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/LICENSE b/vendor/github.com/libp2p/go-libp2p-connmgr/LICENSE new file mode 100644 index 00000000..83f48ce5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Whyrusleeping + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/README.md b/vendor/github.com/libp2p/go-libp2p-connmgr/README.md new file mode 100644 index 00000000..3373fb26 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/README.md @@ -0,0 +1,38 @@ +go-libp2p-connmgr +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Travis CI](https://travis-ci.com/libp2p/go-libp2p-connmgr.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-connmgr) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + + +> A package to help manage connections in go-libp2p. + + +## Table of Contents + +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +go get github.com/libp2p/go-libp2p-connmgr +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Whyrusleeping + +--- + +The last gx published version of this module was: 0.3.34: QmSTKY2v62v9RjcfTMCFKMVAWvVjWGixkYWEi68iG7e1TT diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/codecov.yml b/vendor/github.com/libp2p/go-libp2p-connmgr/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/connmgr.go b/vendor/github.com/libp2p/go-libp2p-connmgr/connmgr.go new file mode 100644 index 00000000..0ee89017 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/connmgr.go @@ -0,0 +1,476 @@ +package connmgr + +import ( + "context" + "sort" + "sync" + "sync/atomic" + "time" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" + ma "github.com/multiformats/go-multiaddr" +) + +var SilencePeriod = 10 * time.Second + +var log = logging.Logger("connmgr") + +// BasicConnMgr is a ConnManager that trims connections whenever the count exceeds the +// high watermark. New connections are given a grace period before they're subject +// to trimming. Trims are automatically run on demand, only if the time from the +// previous trim is higher than 10 seconds. Furthermore, trims can be explicitly +// requested through the public interface of this struct (see TrimOpenConns). +// +// See configuration parameters in NewConnManager. +type BasicConnMgr struct { + highWater int + lowWater int + connCount int32 + gracePeriod time.Duration + segments segments + + plk sync.RWMutex + protected map[peer.ID]map[string]struct{} + + // channel-based semaphore that enforces only a single trim is in progress + trimRunningCh chan struct{} + lastTrim time.Time + silencePeriod time.Duration + + ctx context.Context + cancel func() +} + +var _ connmgr.ConnManager = (*BasicConnMgr)(nil) + +type segment struct { + sync.Mutex + peers map[peer.ID]*peerInfo +} + +type segments [256]*segment + +func (ss *segments) get(p peer.ID) *segment { + return ss[byte(p[len(p)-1])] +} + +func (ss *segments) countPeers() (count int) { + for _, seg := range ss { + seg.Lock() + count += len(seg.peers) + seg.Unlock() + } + return count +} + +func (s *segment) tagInfoFor(p peer.ID) *peerInfo { + pi, ok := s.peers[p] + if ok { + return pi + } + // create a temporary peer to buffer early tags before the Connected notification arrives. + pi = &peerInfo{ + id: p, + firstSeen: time.Now(), // this timestamp will be updated when the first Connected notification arrives. + temp: true, + tags: make(map[string]int), + conns: make(map[network.Conn]time.Time), + } + s.peers[p] = pi + return pi +} + +// NewConnManager creates a new BasicConnMgr with the provided params: +// * lo and hi are watermarks governing the number of connections that'll be maintained. +// When the peer count exceeds the 'high watermark', as many peers will be pruned (and +// their connections terminated) until 'low watermark' peers remain. +// * grace is the amount of time a newly opened connection is given before it becomes +// subject to pruning. +func NewConnManager(low, hi int, grace time.Duration) *BasicConnMgr { + ctx, cancel := context.WithCancel(context.Background()) + cm := &BasicConnMgr{ + highWater: hi, + lowWater: low, + gracePeriod: grace, + trimRunningCh: make(chan struct{}, 1), + protected: make(map[peer.ID]map[string]struct{}, 16), + silencePeriod: SilencePeriod, + ctx: ctx, + cancel: cancel, + segments: func() (ret segments) { + for i := range ret { + ret[i] = &segment{ + peers: make(map[peer.ID]*peerInfo), + } + } + return ret + }(), + } + + go cm.background() + return cm +} + +func (cm *BasicConnMgr) Close() error { + cm.cancel() + return nil +} + +func (cm *BasicConnMgr) Protect(id peer.ID, tag string) { + cm.plk.Lock() + defer cm.plk.Unlock() + + tags, ok := cm.protected[id] + if !ok { + tags = make(map[string]struct{}, 2) + cm.protected[id] = tags + } + tags[tag] = struct{}{} +} + +func (cm *BasicConnMgr) Unprotect(id peer.ID, tag string) (protected bool) { + cm.plk.Lock() + defer cm.plk.Unlock() + + tags, ok := cm.protected[id] + if !ok { + return false + } + if delete(tags, tag); len(tags) == 0 { + delete(cm.protected, id) + return false + } + return true +} + +// peerInfo stores metadata for a given peer. +type peerInfo struct { + id peer.ID + tags map[string]int // value for each tag + value int // cached sum of all tag values + temp bool // this is a temporary entry holding early tags, and awaiting connections + + conns map[network.Conn]time.Time // start time of each connection + + firstSeen time.Time // timestamp when we began tracking this peer. +} + +// TrimOpenConns closes the connections of as many peers as needed to make the peer count +// equal the low watermark. Peers are sorted in ascending order based on their total value, +// pruning those peers with the lowest scores first, as long as they are not within their +// grace period. +// +// TODO: error return value so we can cleanly signal we are aborting because: +// (a) there's another trim in progress, or (b) the silence period is in effect. +func (cm *BasicConnMgr) TrimOpenConns(ctx context.Context) { + select { + case cm.trimRunningCh <- struct{}{}: + default: + return + } + defer func() { <-cm.trimRunningCh }() + if time.Since(cm.lastTrim) < cm.silencePeriod { + // skip this attempt to trim as the last one just took place. + return + } + + defer log.EventBegin(ctx, "connCleanup").Done() + for _, c := range cm.getConnsToClose(ctx) { + log.Info("closing conn: ", c.RemotePeer()) + log.Event(ctx, "closeConn", c.RemotePeer()) + c.Close() + } + + cm.lastTrim = time.Now() +} + +func (cm *BasicConnMgr) background() { + ticker := time.NewTicker(time.Minute) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if atomic.LoadInt32(&cm.connCount) > int32(cm.highWater) { + cm.TrimOpenConns(cm.ctx) + } + + case <-cm.ctx.Done(): + return + } + } +} + +// getConnsToClose runs the heuristics described in TrimOpenConns and returns the +// connections to close. +func (cm *BasicConnMgr) getConnsToClose(ctx context.Context) []network.Conn { + if cm.lowWater == 0 || cm.highWater == 0 { + // disabled + return nil + } + now := time.Now() + nconns := int(atomic.LoadInt32(&cm.connCount)) + if nconns <= cm.lowWater { + log.Info("open connection count below limit") + return nil + } + + npeers := cm.segments.countPeers() + candidates := make([]*peerInfo, 0, npeers) + cm.plk.RLock() + for _, s := range cm.segments { + s.Lock() + for id, inf := range s.peers { + if _, ok := cm.protected[id]; ok { + // skip over protected peer. + continue + } + candidates = append(candidates, inf) + } + s.Unlock() + } + cm.plk.RUnlock() + + // Sort peers according to their value. + sort.Slice(candidates, func(i, j int) bool { + left, right := candidates[i], candidates[j] + // temporary peers are preferred for pruning. + if left.temp != right.temp { + return left.temp + } + // otherwise, compare by value. + return left.value < right.value + }) + + target := nconns - cm.lowWater + + // slightly overallocate because we may have more than one conns per peer + selected := make([]network.Conn, 0, target+10) + + for _, inf := range candidates { + if target <= 0 { + break + } + // TODO: should we be using firstSeen or the time associated with the connection itself? + if inf.firstSeen.Add(cm.gracePeriod).After(now) { + continue + } + + // lock this to protect from concurrent modifications from connect/disconnect events + s := cm.segments.get(inf.id) + s.Lock() + + if len(inf.conns) == 0 && inf.temp { + // handle temporary entries for early tags -- this entry has gone past the grace period + // and still holds no connections, so prune it. + delete(s.peers, inf.id) + } else { + for c := range inf.conns { + selected = append(selected, c) + } + } + target -= len(inf.conns) + s.Unlock() + } + + return selected +} + +// GetTagInfo is called to fetch the tag information associated with a given +// peer, nil is returned if p refers to an unknown peer. +func (cm *BasicConnMgr) GetTagInfo(p peer.ID) *connmgr.TagInfo { + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + pi, ok := s.peers[p] + if !ok { + return nil + } + + out := &connmgr.TagInfo{ + FirstSeen: pi.firstSeen, + Value: pi.value, + Tags: make(map[string]int), + Conns: make(map[string]time.Time), + } + + for t, v := range pi.tags { + out.Tags[t] = v + } + for c, t := range pi.conns { + out.Conns[c.RemoteMultiaddr().String()] = t + } + + return out +} + +// TagPeer is called to associate a string and integer with a given peer. +func (cm *BasicConnMgr) TagPeer(p peer.ID, tag string, val int) { + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + pi := s.tagInfoFor(p) + + // Update the total value of the peer. + pi.value += val - pi.tags[tag] + pi.tags[tag] = val +} + +// UntagPeer is called to disassociate a string and integer from a given peer. +func (cm *BasicConnMgr) UntagPeer(p peer.ID, tag string) { + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + pi, ok := s.peers[p] + if !ok { + log.Info("tried to remove tag from untracked peer: ", p) + return + } + + // Update the total value of the peer. + pi.value -= pi.tags[tag] + delete(pi.tags, tag) +} + +// UpsertTag is called to insert/update a peer tag +func (cm *BasicConnMgr) UpsertTag(p peer.ID, tag string, upsert func(int) int) { + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + pi := s.tagInfoFor(p) + + oldval := pi.tags[tag] + newval := upsert(oldval) + pi.value += newval - oldval + pi.tags[tag] = newval +} + +// CMInfo holds the configuration for BasicConnMgr, as well as status data. +type CMInfo struct { + // The low watermark, as described in NewConnManager. + LowWater int + + // The high watermark, as described in NewConnManager. + HighWater int + + // The timestamp when the last trim was triggered. + LastTrim time.Time + + // The configured grace period, as described in NewConnManager. + GracePeriod time.Duration + + // The current connection count. + ConnCount int +} + +// GetInfo returns the configuration and status data for this connection manager. +func (cm *BasicConnMgr) GetInfo() CMInfo { + return CMInfo{ + HighWater: cm.highWater, + LowWater: cm.lowWater, + LastTrim: cm.lastTrim, + GracePeriod: cm.gracePeriod, + ConnCount: int(atomic.LoadInt32(&cm.connCount)), + } +} + +// Notifee returns a sink through which Notifiers can inform the BasicConnMgr when +// events occur. Currently, the notifee only reacts upon connection events +// {Connected, Disconnected}. +func (cm *BasicConnMgr) Notifee() network.Notifiee { + return (*cmNotifee)(cm) +} + +type cmNotifee BasicConnMgr + +func (nn *cmNotifee) cm() *BasicConnMgr { + return (*BasicConnMgr)(nn) +} + +// Connected is called by notifiers to inform that a new connection has been established. +// The notifee updates the BasicConnMgr to start tracking the connection. If the new connection +// count exceeds the high watermark, a trim may be triggered. +func (nn *cmNotifee) Connected(n network.Network, c network.Conn) { + cm := nn.cm() + + p := c.RemotePeer() + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + id := c.RemotePeer() + pinfo, ok := s.peers[id] + if !ok { + pinfo = &peerInfo{ + id: id, + firstSeen: time.Now(), + tags: make(map[string]int), + conns: make(map[network.Conn]time.Time), + } + s.peers[id] = pinfo + } else if pinfo.temp { + // we had created a temporary entry for this peer to buffer early tags before the + // Connected notification arrived: flip the temporary flag, and update the firstSeen + // timestamp to the real one. + pinfo.temp = false + pinfo.firstSeen = time.Now() + } + + _, ok = pinfo.conns[c] + if ok { + log.Error("received connected notification for conn we are already tracking: ", p) + return + } + + pinfo.conns[c] = time.Now() + atomic.AddInt32(&cm.connCount, 1) +} + +// Disconnected is called by notifiers to inform that an existing connection has been closed or terminated. +// The notifee updates the BasicConnMgr accordingly to stop tracking the connection, and performs housekeeping. +func (nn *cmNotifee) Disconnected(n network.Network, c network.Conn) { + cm := nn.cm() + + p := c.RemotePeer() + s := cm.segments.get(p) + s.Lock() + defer s.Unlock() + + cinf, ok := s.peers[p] + if !ok { + log.Error("received disconnected notification for peer we are not tracking: ", p) + return + } + + _, ok = cinf.conns[c] + if !ok { + log.Error("received disconnected notification for conn we are not tracking: ", p) + return + } + + delete(cinf.conns, c) + if len(cinf.conns) == 0 { + delete(s.peers, p) + } + atomic.AddInt32(&cm.connCount, -1) +} + +// Listen is no-op in this implementation. +func (nn *cmNotifee) Listen(n network.Network, addr ma.Multiaddr) {} + +// ListenClose is no-op in this implementation. +func (nn *cmNotifee) ListenClose(n network.Network, addr ma.Multiaddr) {} + +// OpenedStream is no-op in this implementation. +func (nn *cmNotifee) OpenedStream(network.Network, network.Stream) {} + +// ClosedStream is no-op in this implementation. +func (nn *cmNotifee) ClosedStream(network.Network, network.Stream) {} diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/go.mod b/vendor/github.com/libp2p/go-libp2p-connmgr/go.mod new file mode 100644 index 00000000..227a85dc --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-libp2p-connmgr + +require ( + github.com/ipfs/go-detect-race v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multiaddr v0.0.2 +) diff --git a/vendor/github.com/libp2p/go-libp2p-connmgr/go.sum b/vendor/github.com/libp2p/go-libp2p-connmgr/go.sum new file mode 100644 index 00000000..663f0401 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-connmgr/go.sum @@ -0,0 +1,90 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/connmgr.go b/vendor/github.com/libp2p/go-libp2p-core/connmgr/connmgr.go new file mode 100644 index 00000000..98baf8b9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/connmgr/connmgr.go @@ -0,0 +1,78 @@ +// Package connmgr provides connection tracking and management interfaces for libp2p. +// +// The ConnManager interface exported from this package allows libp2p to enforce an +// upper bound on the total number of open connections. To avoid service disruptions, +// connections can be tagged with metadata and optionally "protected" to ensure that +// essential connections are not arbitrarily cut. +package connmgr + +import ( + "context" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" +) + +// ConnManager tracks connections to peers, and allows consumers to associate metadata +// with each peer. +// +// It enables connections to be trimmed based on implementation-defined heuristics. +// The ConnManager allows libp2p to enforce an upper bound on the total number of +// open connections. +type ConnManager interface { + + // TagPeer tags a peer with a string, associating a weight with the tag. + TagPeer(peer.ID, string, int) + + // Untag removes the tagged value from the peer. + UntagPeer(p peer.ID, tag string) + + // UpsertTag updates an existing tag or inserts a new one. + // + // The connection manager calls the upsert function supplying the current + // value of the tag (or zero if inexistent). The return value is used as + // the new value of the tag. + UpsertTag(p peer.ID, tag string, upsert func(int) int) + + // GetTagInfo returns the metadata associated with the peer, + // or nil if no metadata has been recorded for the peer. + GetTagInfo(p peer.ID) *TagInfo + + // TrimOpenConns terminates open connections based on an implementation-defined + // heuristic. + TrimOpenConns(ctx context.Context) + + // Notifee returns an implementation that can be called back to inform of + // opened and closed connections. + Notifee() network.Notifiee + + // Protect protects a peer from having its connection(s) pruned. + // + // Tagging allows different parts of the system to manage protections without interfering with one another. + // + // Calls to Protect() with the same tag are idempotent. They are not refcounted, so after multiple calls + // to Protect() with the same tag, a single Unprotect() call bearing the same tag will revoke the protection. + Protect(id peer.ID, tag string) + + // Unprotect removes a protection that may have been placed on a peer, under the specified tag. + // + // The return value indicates whether the peer continues to be protected after this call, by way of a different tag. + // See notes on Protect() for more info. + Unprotect(id peer.ID, tag string) (protected bool) + + // Close closes the connection manager and stops background processes + Close() error +} + +// TagInfo stores metadata associated with a peer. +type TagInfo struct { + FirstSeen time.Time + Value int + + // Tags maps tag ids to the numerical values. + Tags map[string]int + + // Conns maps connection ids (such as remote multiaddr) to their creation time. + Conns map[string]time.Time +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go b/vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go new file mode 100644 index 00000000..473af328 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go @@ -0,0 +1,23 @@ +package connmgr + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" +) + +// NullConnMgr is a ConnMgr that provides no functionality. +type NullConnMgr struct{} + +var _ ConnManager = (*NullConnMgr)(nil) + +func (_ NullConnMgr) TagPeer(peer.ID, string, int) {} +func (_ NullConnMgr) UntagPeer(peer.ID, string) {} +func (_ NullConnMgr) UpsertTag(peer.ID, string, func(int) int) {} +func (_ NullConnMgr) GetTagInfo(peer.ID) *TagInfo { return &TagInfo{} } +func (_ NullConnMgr) TrimOpenConns(ctx context.Context) {} +func (_ NullConnMgr) Notifee() network.Notifiee { return network.GlobalNoopNotifiee } +func (_ NullConnMgr) Protect(peer.ID, string) {} +func (_ NullConnMgr) Unprotect(peer.ID, string) bool { return false } +func (_ NullConnMgr) Close() error { return nil } diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go new file mode 100644 index 00000000..58e5d5f5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go @@ -0,0 +1,186 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "encoding/asn1" + "errors" + "io" + "math/big" + + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + sha256 "github.com/minio/sha256-simd" +) + +// ECDSAPrivateKey is an implementation of an ECDSA private key +type ECDSAPrivateKey struct { + priv *ecdsa.PrivateKey +} + +// ECDSAPublicKey is an implementation of an ECDSA public key +type ECDSAPublicKey struct { + pub *ecdsa.PublicKey +} + +// ECDSASig holds the r and s values of an ECDSA signature +type ECDSASig struct { + R, S *big.Int +} + +var ( + // ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key + ErrNotECDSAPubKey = errors.New("not an ecdsa public key") + // ErrNilSig is returned when the signature is nil + ErrNilSig = errors.New("sig is nil") + // ErrNilPrivateKey is returned when a nil private key is provided + ErrNilPrivateKey = errors.New("private key is nil") + // ECDSACurve is the default ecdsa curve used + ECDSACurve = elliptic.P256() +) + +// GenerateECDSAKeyPair generates a new ecdsa private and public key +func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) { + return GenerateECDSAKeyPairWithCurve(ECDSACurve, src) +} + +// GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a speicified curve +func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) { + priv, err := ecdsa.GenerateKey(curve, src) + if err != nil { + return nil, nil, err + } + + return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil +} + +// ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key +func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) { + if priv == nil { + return nil, nil, ErrNilPrivateKey + } + + return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil +} + +// MarshalECDSAPrivateKey returns x509 bytes from a private key +func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) ([]byte, error) { + return x509.MarshalECPrivateKey(ePriv.priv) +} + +// MarshalECDSAPublicKey returns x509 bytes from a public key +func MarshalECDSAPublicKey(ePub ECDSAPublicKey) ([]byte, error) { + return x509.MarshalPKIXPublicKey(ePub.pub) +} + +// UnmarshalECDSAPrivateKey returns a private key from x509 bytes +func UnmarshalECDSAPrivateKey(data []byte) (PrivKey, error) { + priv, err := x509.ParseECPrivateKey(data) + if err != nil { + return nil, err + } + + return &ECDSAPrivateKey{priv}, nil +} + +// UnmarshalECDSAPublicKey returns the public key from x509 bytes +func UnmarshalECDSAPublicKey(data []byte) (PubKey, error) { + pubIfc, err := x509.ParsePKIXPublicKey(data) + if err != nil { + return nil, err + } + + pub, ok := pubIfc.(*ecdsa.PublicKey) + if !ok { + return nil, ErrNotECDSAPubKey + } + + return &ECDSAPublicKey{pub}, nil +} + +// Bytes returns the private key as protobuf bytes +func (ePriv *ECDSAPrivateKey) Bytes() ([]byte, error) { + return MarshalPrivateKey(ePriv) +} + +// Type returns the key type +func (ePriv *ECDSAPrivateKey) Type() pb.KeyType { + return pb.KeyType_ECDSA +} + +// Raw returns x509 bytes from a private key +func (ePriv *ECDSAPrivateKey) Raw() ([]byte, error) { + return x509.MarshalECPrivateKey(ePriv.priv) +} + +// Equals compares to private keys +func (ePriv *ECDSAPrivateKey) Equals(o Key) bool { + oPriv, ok := o.(*ECDSAPrivateKey) + if !ok { + return false + } + + return ePriv.priv.D.Cmp(oPriv.priv.D) == 0 +} + +// Sign returns the signature of the input data +func (ePriv *ECDSAPrivateKey) Sign(data []byte) ([]byte, error) { + hash := sha256.Sum256(data) + r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:]) + if err != nil { + return nil, err + } + + return asn1.Marshal(ECDSASig{ + R: r, + S: s, + }) +} + +// GetPublic returns a public key +func (ePriv *ECDSAPrivateKey) GetPublic() PubKey { + return &ECDSAPublicKey{&ePriv.priv.PublicKey} +} + +// Bytes returns the public key as protobuf bytes +func (ePub *ECDSAPublicKey) Bytes() ([]byte, error) { + return MarshalPublicKey(ePub) +} + +// Type returns the key type +func (ePub *ECDSAPublicKey) Type() pb.KeyType { + return pb.KeyType_ECDSA +} + +// Raw returns x509 bytes from a public key +func (ePub ECDSAPublicKey) Raw() ([]byte, error) { + return x509.MarshalPKIXPublicKey(ePub.pub) +} + +// Equals compares to public keys +func (ePub *ECDSAPublicKey) Equals(o Key) bool { + oPub, ok := o.(*ECDSAPublicKey) + if !ok { + return false + } + + return ePub.pub.X != nil && ePub.pub.Y != nil && oPub.pub.X != nil && oPub.pub.Y != nil && + 0 == ePub.pub.X.Cmp(oPub.pub.X) && 0 == ePub.pub.Y.Cmp(oPub.pub.Y) +} + +// Verify compares data to a signature +func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (bool, error) { + sig := new(ECDSASig) + if _, err := asn1.Unmarshal(sigBytes, sig); err != nil { + return false, err + } + if sig == nil { + return false, ErrNilSig + } + + hash := sha256.Sum256(data) + + return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go new file mode 100644 index 00000000..b6e55314 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go @@ -0,0 +1,155 @@ +package crypto + +import ( + "bytes" + "errors" + "fmt" + "io" + + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + "golang.org/x/crypto/ed25519" +) + +// Ed25519PrivateKey is an ed25519 private key. +type Ed25519PrivateKey struct { + k ed25519.PrivateKey +} + +// Ed25519PublicKey is an ed25519 public key. +type Ed25519PublicKey struct { + k ed25519.PublicKey +} + +// GenerateEd25519Key generates a new ed25519 private and public key pair. +func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) { + pub, priv, err := ed25519.GenerateKey(src) + if err != nil { + return nil, nil, err + } + + return &Ed25519PrivateKey{ + k: priv, + }, + &Ed25519PublicKey{ + k: pub, + }, + nil +} + +// Type of the private key (Ed25519). +func (k *Ed25519PrivateKey) Type() pb.KeyType { + return pb.KeyType_Ed25519 +} + +// Bytes marshals an ed25519 private key to protobuf bytes. +func (k *Ed25519PrivateKey) Bytes() ([]byte, error) { + return MarshalPrivateKey(k) +} + +// Raw private key bytes. +func (k *Ed25519PrivateKey) Raw() ([]byte, error) { + // The Ed25519 private key contains two 32-bytes curve points, the private + // key and the public key. + // It makes it more efficient to get the public key without re-computing an + // elliptic curve multiplication. + buf := make([]byte, len(k.k)) + copy(buf, k.k) + + return buf, nil +} + +func (k *Ed25519PrivateKey) pubKeyBytes() []byte { + return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:] +} + +// Equals compares two ed25519 private keys. +func (k *Ed25519PrivateKey) Equals(o Key) bool { + edk, ok := o.(*Ed25519PrivateKey) + if !ok { + return false + } + + return bytes.Equal(k.k, edk.k) +} + +// GetPublic returns an ed25519 public key from a private key. +func (k *Ed25519PrivateKey) GetPublic() PubKey { + return &Ed25519PublicKey{k: k.pubKeyBytes()} +} + +// Sign returns a signature from an input message. +func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) { + return ed25519.Sign(k.k, msg), nil +} + +// Type of the public key (Ed25519). +func (k *Ed25519PublicKey) Type() pb.KeyType { + return pb.KeyType_Ed25519 +} + +// Bytes returns a ed25519 public key as protobuf bytes. +func (k *Ed25519PublicKey) Bytes() ([]byte, error) { + return MarshalPublicKey(k) +} + +// Raw public key bytes. +func (k *Ed25519PublicKey) Raw() ([]byte, error) { + return k.k, nil +} + +// Equals compares two ed25519 public keys. +func (k *Ed25519PublicKey) Equals(o Key) bool { + edk, ok := o.(*Ed25519PublicKey) + if !ok { + return false + } + + return bytes.Equal(k.k, edk.k) +} + +// Verify checks a signature agains the input data. +func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) { + return ed25519.Verify(k.k, data, sig), nil +} + +// UnmarshalEd25519PublicKey returns a public key from input bytes. +func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { + if len(data) != 32 { + return nil, errors.New("expect ed25519 public key data size to be 32") + } + + return &Ed25519PublicKey{ + k: ed25519.PublicKey(data), + }, nil +} + +// UnmarshalEd25519PrivateKey returns a private key from input bytes. +func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { + switch len(data) { + case ed25519.PrivateKeySize + ed25519.PublicKeySize: + // Remove the redundant public key. See issue #36. + redundantPk := data[ed25519.PrivateKeySize:] + pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize] + if !bytes.Equal(pk, redundantPk) { + return nil, errors.New("expected redundant ed25519 public key to be redundant") + } + + // No point in storing the extra data. + newKey := make([]byte, ed25519.PrivateKeySize) + copy(newKey, data[:ed25519.PrivateKeySize]) + data = newKey + case ed25519.PrivateKeySize: + default: + return nil, fmt.Errorf( + "expected ed25519 data size to be %d or %d, got %d", + ed25519.PrivateKeySize, + ed25519.PrivateKeySize+ed25519.PublicKeySize, + len(data), + ) + } + + return &Ed25519PrivateKey{ + k: ed25519.PrivateKey(data), + }, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/key.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/key.go new file mode 100644 index 00000000..50167dbe --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/key.go @@ -0,0 +1,351 @@ +// Package crypto implements various cryptographic utilities used by libp2p. +// This includes a Public and Private key interface and key implementations +// for supported key algorithms. +package crypto + +import ( + "bytes" + "crypto/elliptic" + "crypto/hmac" + "crypto/rand" + "crypto/sha1" + "crypto/sha512" + "encoding/base64" + "errors" + "fmt" + "hash" + "io" + + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + "github.com/gogo/protobuf/proto" + sha256 "github.com/minio/sha256-simd" +) + +const ( + // RSA is an enum for the supported RSA key type + RSA = iota + // Ed25519 is an enum for the supported Ed25519 key type + Ed25519 + // Secp256k1 is an enum for the supported Secp256k1 key type + Secp256k1 + // ECDSA is an enum for the supported ECDSA key type + ECDSA +) + +var ( + // ErrBadKeyType is returned when a key is not supported + ErrBadKeyType = errors.New("invalid or unsupported key type") + // KeyTypes is a list of supported keys + KeyTypes = []int{ + RSA, + Ed25519, + Secp256k1, + ECDSA, + } +) + +// PubKeyUnmarshaller is a func that creates a PubKey from a given slice of bytes +type PubKeyUnmarshaller func(data []byte) (PubKey, error) + +// PrivKeyUnmarshaller is a func that creates a PrivKey from a given slice of bytes +type PrivKeyUnmarshaller func(data []byte) (PrivKey, error) + +// PubKeyUnmarshallers is a map of unmarshallers by key type +var PubKeyUnmarshallers = map[pb.KeyType]PubKeyUnmarshaller{ + pb.KeyType_RSA: UnmarshalRsaPublicKey, + pb.KeyType_Ed25519: UnmarshalEd25519PublicKey, + pb.KeyType_Secp256k1: UnmarshalSecp256k1PublicKey, + pb.KeyType_ECDSA: UnmarshalECDSAPublicKey, +} + +// PrivKeyUnmarshallers is a map of unmarshallers by key type +var PrivKeyUnmarshallers = map[pb.KeyType]PrivKeyUnmarshaller{ + pb.KeyType_RSA: UnmarshalRsaPrivateKey, + pb.KeyType_Ed25519: UnmarshalEd25519PrivateKey, + pb.KeyType_Secp256k1: UnmarshalSecp256k1PrivateKey, + pb.KeyType_ECDSA: UnmarshalECDSAPrivateKey, +} + +// Key represents a crypto key that can be compared to another key +type Key interface { + // Bytes returns a serialized, storeable representation of this key + // DEPRECATED in favor of Marshal / Unmarshal + Bytes() ([]byte, error) + + // Equals checks whether two PubKeys are the same + Equals(Key) bool + + // Raw returns the raw bytes of the key (not wrapped in the + // libp2p-crypto protobuf). + // + // This function is the inverse of {Priv,Pub}KeyUnmarshaler. + Raw() ([]byte, error) + + // Type returns the protobof key type. + Type() pb.KeyType +} + +// PrivKey represents a private key that can be used to generate a public key and sign data +type PrivKey interface { + Key + + // Cryptographically sign the given bytes + Sign([]byte) ([]byte, error) + + // Return a public key paired with this private key + GetPublic() PubKey +} + +// PubKey is a public key that can be used to verifiy data signed with the corresponding private key +type PubKey interface { + Key + + // Verify that 'sig' is the signed hash of 'data' + Verify(data []byte, sig []byte) (bool, error) +} + +// GenSharedKey generates the shared key from a given private key +type GenSharedKey func([]byte) ([]byte, error) + +// GenerateKeyPair generates a private and public key +func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) { + return GenerateKeyPairWithReader(typ, bits, rand.Reader) +} + +// GenerateKeyPairWithReader returns a keypair of the given type and bitsize +func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) { + switch typ { + case RSA: + return GenerateRSAKeyPair(bits, src) + case Ed25519: + return GenerateEd25519Key(src) + case Secp256k1: + return GenerateSecp256k1Key(src) + case ECDSA: + return GenerateECDSAKeyPair(src) + default: + return nil, nil, ErrBadKeyType + } +} + +// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute +// the shared secret key. Used in the identify module. +// +// Focuses only on ECDH now, but can be made more general in the future. +func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) { + var curve elliptic.Curve + + switch curveName { + case "P-256": + curve = elliptic.P256() + case "P-384": + curve = elliptic.P384() + case "P-521": + curve = elliptic.P521() + } + + priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, nil, err + } + + pubKey := elliptic.Marshal(curve, x, y) + + done := func(theirPub []byte) ([]byte, error) { + // Verify and unpack node's public key. + x, y := elliptic.Unmarshal(curve, theirPub) + if x == nil { + return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub) + } + + if !curve.IsOnCurve(x, y) { + return nil, errors.New("invalid public key") + } + + // Generate shared secret. + secret, _ := curve.ScalarMult(x, y, priv) + + return secret.Bytes(), nil + } + + return pubKey, done, nil +} + +// StretchedKeys ... +type StretchedKeys struct { + IV []byte + MacKey []byte + CipherKey []byte +} + +// KeyStretcher returns a set of keys for each party by stretching the shared key. +// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey) +func KeyStretcher(cipherType string, hashType string, secret []byte) (StretchedKeys, StretchedKeys) { + var cipherKeySize int + var ivSize int + switch cipherType { + case "AES-128": + ivSize = 16 + cipherKeySize = 16 + case "AES-256": + ivSize = 16 + cipherKeySize = 32 + case "Blowfish": + ivSize = 8 + // Note: cypherKeySize arbitrarily selected, needs more thought + cipherKeySize = 32 + } + + hmacKeySize := 20 + + seed := []byte("key expansion") + + result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize)) + + var h func() hash.Hash + + switch hashType { + case "SHA1": + h = sha1.New + case "SHA256": + h = sha256.New + case "SHA512": + h = sha512.New + default: + panic("Unrecognized hash function, programmer error?") + } + + m := hmac.New(h, secret) + // note: guaranteed to never return an error + m.Write(seed) + + a := m.Sum(nil) + + j := 0 + for j < len(result) { + m.Reset() + + // note: guaranteed to never return an error. + m.Write(a) + m.Write(seed) + + b := m.Sum(nil) + + todo := len(b) + + if j+todo > len(result) { + todo = len(result) - j + } + + copy(result[j:j+todo], b) + + j += todo + + m.Reset() + + // note: guaranteed to never return an error. + m.Write(a) + + a = m.Sum(nil) + } + + half := len(result) / 2 + r1 := result[:half] + r2 := result[half:] + + var k1 StretchedKeys + var k2 StretchedKeys + + k1.IV = r1[0:ivSize] + k1.CipherKey = r1[ivSize : ivSize+cipherKeySize] + k1.MacKey = r1[ivSize+cipherKeySize:] + + k2.IV = r2[0:ivSize] + k2.CipherKey = r2[ivSize : ivSize+cipherKeySize] + k2.MacKey = r2[ivSize+cipherKeySize:] + + return k1, k2 +} + +// UnmarshalPublicKey converts a protobuf serialized public key into its +// representative object +func UnmarshalPublicKey(data []byte) (PubKey, error) { + pmes := new(pb.PublicKey) + err := proto.Unmarshal(data, pmes) + if err != nil { + return nil, err + } + + um, ok := PubKeyUnmarshallers[pmes.GetType()] + if !ok { + return nil, ErrBadKeyType + } + + return um(pmes.GetData()) +} + +// MarshalPublicKey converts a public key object into a protobuf serialized +// public key +func MarshalPublicKey(k PubKey) ([]byte, error) { + pbmes := new(pb.PublicKey) + pbmes.Type = k.Type() + data, err := k.Raw() + if err != nil { + return nil, err + } + pbmes.Data = data + + return proto.Marshal(pbmes) +} + +// UnmarshalPrivateKey converts a protobuf serialized private key into its +// representative object +func UnmarshalPrivateKey(data []byte) (PrivKey, error) { + pmes := new(pb.PrivateKey) + err := proto.Unmarshal(data, pmes) + if err != nil { + return nil, err + } + + um, ok := PrivKeyUnmarshallers[pmes.GetType()] + if !ok { + return nil, ErrBadKeyType + } + + return um(pmes.GetData()) +} + +// MarshalPrivateKey converts a key object into its protobuf serialized form. +func MarshalPrivateKey(k PrivKey) ([]byte, error) { + pbmes := new(pb.PrivateKey) + pbmes.Type = k.Type() + data, err := k.Raw() + if err != nil { + return nil, err + } + + pbmes.Data = data + return proto.Marshal(pbmes) +} + +// ConfigDecodeKey decodes from b64 (for config file), and unmarshals. +func ConfigDecodeKey(b string) ([]byte, error) { + return base64.StdEncoding.DecodeString(b) +} + +// ConfigEncodeKey encodes to b64 (for config file), and marshals. +func ConfigEncodeKey(b []byte) string { + return base64.StdEncoding.EncodeToString(b) +} + +// KeyEqual checks whether two Keys are equivalent (have identical byte representations). +func KeyEqual(k1, k2 Key) bool { + if k1 == k2 { + return true + } + + b1, err1 := k1.Bytes() + b2, err2 := k2.Bytes() + return bytes.Equal(b1, b2) && err1 == err2 +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go new file mode 100644 index 00000000..f235e75f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go @@ -0,0 +1,98 @@ +// +build openssl + +package crypto + +import ( + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + openssl "github.com/spacemonkeygo/openssl" +) + +// define these as separate types so we can add more key types later and reuse +// code. + +type opensslPublicKey struct { + key openssl.PublicKey +} + +type opensslPrivateKey struct { + key openssl.PrivateKey +} + +func unmarshalOpensslPrivateKey(b []byte) (opensslPrivateKey, error) { + sk, err := openssl.LoadPrivateKeyFromDER(b) + if err != nil { + return opensslPrivateKey{}, err + } + return opensslPrivateKey{sk}, nil +} + +func unmarshalOpensslPublicKey(b []byte) (opensslPublicKey, error) { + sk, err := openssl.LoadPublicKeyFromDER(b) + if err != nil { + return opensslPublicKey{}, err + } + return opensslPublicKey{sk}, nil +} + +// Verify compares a signature against input data +func (pk *opensslPublicKey) Verify(data, sig []byte) (bool, error) { + err := pk.key.VerifyPKCS1v15(openssl.SHA256_Method, data, sig) + return err == nil, err +} + +func (pk *opensslPublicKey) Type() pb.KeyType { + switch pk.key.KeyType() { + case openssl.KeyTypeRSA: + return pb.KeyType_RSA + default: + return -1 + } +} + +// Bytes returns protobuf bytes of a public key +func (pk *opensslPublicKey) Bytes() ([]byte, error) { + return MarshalPublicKey(pk) +} + +func (pk *opensslPublicKey) Raw() ([]byte, error) { + return pk.key.MarshalPKIXPublicKeyDER() +} + +// Equals checks whether this key is equal to another +func (pk *opensslPublicKey) Equals(k Key) bool { + return KeyEqual(pk, k) +} + +// Sign returns a signature of the input data +func (sk *opensslPrivateKey) Sign(message []byte) ([]byte, error) { + return sk.key.SignPKCS1v15(openssl.SHA256_Method, message) +} + +// GetPublic returns a public key +func (sk *opensslPrivateKey) GetPublic() PubKey { + return &opensslPublicKey{sk.key} +} + +func (sk *opensslPrivateKey) Type() pb.KeyType { + switch sk.key.KeyType() { + case openssl.KeyTypeRSA: + return pb.KeyType_RSA + default: + return -1 + } +} + +// Bytes returns protobuf bytes from a private key +func (sk *opensslPrivateKey) Bytes() ([]byte, error) { + return MarshalPrivateKey(sk) +} + +func (sk *opensslPrivateKey) Raw() ([]byte, error) { + return sk.key.MarshalPKCS1PrivateKeyDER() +} + +// Equals checks whether this key is equal to another +func (sk *opensslPrivateKey) Equals(k Key) bool { + return KeyEqual(sk, k) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/Makefile new file mode 100644 index 00000000..df34e54b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.pb.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.pb.go new file mode 100644 index 00000000..5fa7aec7 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.pb.go @@ -0,0 +1,643 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: crypto.proto + +package crypto_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type KeyType int32 + +const ( + KeyType_RSA KeyType = 0 + KeyType_Ed25519 KeyType = 1 + KeyType_Secp256k1 KeyType = 2 + KeyType_ECDSA KeyType = 3 +) + +var KeyType_name = map[int32]string{ + 0: "RSA", + 1: "Ed25519", + 2: "Secp256k1", + 3: "ECDSA", +} + +var KeyType_value = map[string]int32{ + "RSA": 0, + "Ed25519": 1, + "Secp256k1": 2, + "ECDSA": 3, +} + +func (x KeyType) Enum() *KeyType { + p := new(KeyType) + *p = x + return p +} + +func (x KeyType) String() string { + return proto.EnumName(KeyType_name, int32(x)) +} + +func (x *KeyType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(KeyType_value, data, "KeyType") + if err != nil { + return err + } + *x = KeyType(value) + return nil +} + +func (KeyType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{0} +} + +type PublicKey struct { + Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` + Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` +} + +func (m *PublicKey) Reset() { *m = PublicKey{} } +func (m *PublicKey) String() string { return proto.CompactTextString(m) } +func (*PublicKey) ProtoMessage() {} +func (*PublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{0} +} +func (m *PublicKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicKey.Merge(m, src) +} +func (m *PublicKey) XXX_Size() int { + return m.Size() +} +func (m *PublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_PublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PublicKey proto.InternalMessageInfo + +func (m *PublicKey) GetType() KeyType { + if m != nil { + return m.Type + } + return KeyType_RSA +} + +func (m *PublicKey) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +type PrivateKey struct { + Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` + Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` +} + +func (m *PrivateKey) Reset() { *m = PrivateKey{} } +func (m *PrivateKey) String() string { return proto.CompactTextString(m) } +func (*PrivateKey) ProtoMessage() {} +func (*PrivateKey) Descriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{1} +} +func (m *PrivateKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PrivateKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PrivateKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrivateKey.Merge(m, src) +} +func (m *PrivateKey) XXX_Size() int { + return m.Size() +} +func (m *PrivateKey) XXX_DiscardUnknown() { + xxx_messageInfo_PrivateKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PrivateKey proto.InternalMessageInfo + +func (m *PrivateKey) GetType() KeyType { + if m != nil { + return m.Type + } + return KeyType_RSA +} + +func (m *PrivateKey) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func init() { + proto.RegisterEnum("crypto.pb.KeyType", KeyType_name, KeyType_value) + proto.RegisterType((*PublicKey)(nil), "crypto.pb.PublicKey") + proto.RegisterType((*PrivateKey)(nil), "crypto.pb.PrivateKey") +} + +func init() { proto.RegisterFile("crypto.proto", fileDescriptor_527278fb02d03321) } + +var fileDescriptor_527278fb02d03321 = []byte{ + // 203 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c, + 0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x82, 0xb9, + 0x38, 0x03, 0x4a, 0x93, 0x72, 0x32, 0x93, 0xbd, 0x53, 0x2b, 0x85, 0x74, 0xb8, 0x58, 0x42, 0x2a, + 0x0b, 0x52, 0x25, 0x18, 0x15, 0x98, 0x34, 0xf8, 0x8c, 0x84, 0xf4, 0xe0, 0xca, 0xf4, 0xbc, 0x53, + 0x2b, 0x41, 0x32, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x81, 0x55, 0x09, 0x49, 0x70, 0xb1, + 0xb8, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x29, 0x30, 0x69, 0xf0, 0xc0, 0x64, 0x40, 0x22, 0x4a, 0x21, + 0x5c, 0x5c, 0x01, 0x45, 0x99, 0x65, 0x89, 0x25, 0xa9, 0x54, 0x34, 0x55, 0xcb, 0x92, 0x8b, 0x1d, + 0xaa, 0x41, 0x88, 0x9d, 0x8b, 0x39, 0x28, 0xd8, 0x51, 0x80, 0x41, 0x88, 0x9b, 0x8b, 0xdd, 0x35, + 0xc5, 0xc8, 0xd4, 0xd4, 0xd0, 0x52, 0x80, 0x51, 0x88, 0x97, 0x8b, 0x33, 0x38, 0x35, 0xb9, 0xc0, + 0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x80, 0x49, 0x88, 0x93, 0x8b, 0xd5, 0xd5, 0xd9, 0x25, 0xd8, 0x51, + 0x80, 0xd9, 0x49, 0xe2, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, + 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x13, 0xbe, 0xd4, 0xff, 0x19, 0x01, 0x00, 0x00, +} + +func (m *PublicKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0x8 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + if m.Data != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + +func (m *PrivateKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0x8 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + if m.Data != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + +func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *PublicKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovCrypto(uint64(m.Type)) + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func (m *PrivateKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovCrypto(uint64(m.Type)) + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func sovCrypto(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozCrypto(x uint64) (n int) { + return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PublicKey) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= KeyType(b&0x7F) << shift + if b < 0x80 { + break + } + } + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCrypto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PrivateKey) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= KeyType(b&0x7F) << shift + if b < 0x80 { + break + } + } + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCrypto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCrypto(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthCrypto + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthCrypto + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipCrypto(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthCrypto + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto new file mode 100644 index 00000000..cb5cee8a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto @@ -0,0 +1,20 @@ +syntax = "proto2"; + +package crypto.pb; + +enum KeyType { + RSA = 0; + Ed25519 = 1; + Secp256k1 = 2; + ECDSA = 3; +} + +message PublicKey { + required KeyType Type = 1; + required bytes Data = 2; +} + +message PrivateKey { + required KeyType Type = 1; + required bytes Data = 2; +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_common.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_common.go new file mode 100644 index 00000000..d50651f2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_common.go @@ -0,0 +1,10 @@ +package crypto + +import ( + "errors" +) + +// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key +// that's smaller than 512 bits. Keys need to be larger enough to sign a 256bit +// hash so this is a reasonable absolute minimum. +var ErrRsaKeyTooSmall = errors.New("rsa keys must be >= 512 bits to be useful") diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go new file mode 100644 index 00000000..e9813779 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go @@ -0,0 +1,125 @@ +// +build !openssl + +package crypto + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "errors" + "io" + + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + "github.com/minio/sha256-simd" +) + +// RsaPrivateKey is an rsa private key +type RsaPrivateKey struct { + sk rsa.PrivateKey +} + +// RsaPublicKey is an rsa public key +type RsaPublicKey struct { + k rsa.PublicKey +} + +// GenerateRSAKeyPair generates a new rsa private and public key +func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) { + if bits < 512 { + return nil, nil, ErrRsaKeyTooSmall + } + priv, err := rsa.GenerateKey(src, bits) + if err != nil { + return nil, nil, err + } + pk := priv.PublicKey + return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{pk}, nil +} + +// Verify compares a signature against input data +func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) { + hashed := sha256.Sum256(data) + err := rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig) + if err != nil { + return false, err + } + return true, nil +} + +func (pk *RsaPublicKey) Type() pb.KeyType { + return pb.KeyType_RSA +} + +// Bytes returns protobuf bytes of a public key +func (pk *RsaPublicKey) Bytes() ([]byte, error) { + return MarshalPublicKey(pk) +} + +func (pk *RsaPublicKey) Raw() ([]byte, error) { + return x509.MarshalPKIXPublicKey(&pk.k) +} + +// Equals checks whether this key is equal to another +func (pk *RsaPublicKey) Equals(k Key) bool { + return KeyEqual(pk, k) +} + +// Sign returns a signature of the input data +func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) { + hashed := sha256.Sum256(message) + return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:]) +} + +// GetPublic returns a public key +func (sk *RsaPrivateKey) GetPublic() PubKey { + return &RsaPublicKey{sk.sk.PublicKey} +} + +func (sk *RsaPrivateKey) Type() pb.KeyType { + return pb.KeyType_RSA +} + +// Bytes returns protobuf bytes from a private key +func (sk *RsaPrivateKey) Bytes() ([]byte, error) { + return MarshalPrivateKey(sk) +} + +func (sk *RsaPrivateKey) Raw() ([]byte, error) { + b := x509.MarshalPKCS1PrivateKey(&sk.sk) + return b, nil +} + +// Equals checks whether this key is equal to another +func (sk *RsaPrivateKey) Equals(k Key) bool { + return KeyEqual(sk, k) +} + +// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes +func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { + sk, err := x509.ParsePKCS1PrivateKey(b) + if err != nil { + return nil, err + } + if sk.N.BitLen() < 512 { + return nil, ErrRsaKeyTooSmall + } + return &RsaPrivateKey{sk: *sk}, nil +} + +// UnmarshalRsaPublicKey returns a public key from the input x509 bytes +func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { + pub, err := x509.ParsePKIXPublicKey(b) + if err != nil { + return nil, err + } + pk, ok := pub.(*rsa.PublicKey) + if !ok { + return nil, errors.New("not actually an rsa public key") + } + if pk.N.BitLen() < 512 { + return nil, ErrRsaKeyTooSmall + } + return &RsaPublicKey{*pk}, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_openssl.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_openssl.go new file mode 100644 index 00000000..96c55886 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_openssl.go @@ -0,0 +1,62 @@ +// +build openssl + +package crypto + +import ( + "errors" + "io" + + openssl "github.com/spacemonkeygo/openssl" +) + +// RsaPrivateKey is an rsa private key +type RsaPrivateKey struct { + opensslPrivateKey +} + +// RsaPublicKey is an rsa public key +type RsaPublicKey struct { + opensslPublicKey +} + +// GenerateRSAKeyPair generates a new rsa private and public key +func GenerateRSAKeyPair(bits int, _ io.Reader) (PrivKey, PubKey, error) { + if bits < 512 { + return nil, nil, ErrRsaKeyTooSmall + } + + key, err := openssl.GenerateRSAKey(bits) + if err != nil { + return nil, nil, err + } + return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key}}, nil +} + +// GetPublic returns a public key +func (sk *RsaPrivateKey) GetPublic() PubKey { + return &RsaPublicKey{opensslPublicKey{sk.opensslPrivateKey.key}} +} + +// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes +func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { + key, err := unmarshalOpensslPrivateKey(b) + if err != nil { + return nil, err + } + if key.Type() != RSA { + return nil, errors.New("not actually an rsa public key") + } + return &RsaPrivateKey{key}, nil +} + +// UnmarshalRsaPublicKey returns a public key from the input x509 bytes +func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { + key, err := unmarshalOpensslPublicKey(b) + if err != nil { + return nil, err + } + if key.Type() != RSA { + return nil, errors.New("not actually an rsa public key") + } + return &RsaPublicKey{key}, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go b/vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go new file mode 100644 index 00000000..d2ac74b9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go @@ -0,0 +1,125 @@ +package crypto + +import ( + "fmt" + "io" + + pb "github.com/libp2p/go-libp2p-core/crypto/pb" + + btcec "github.com/btcsuite/btcd/btcec" + sha256 "github.com/minio/sha256-simd" +) + +// Secp256k1PrivateKey is an Secp256k1 private key +type Secp256k1PrivateKey btcec.PrivateKey + +// Secp256k1PublicKey is an Secp256k1 public key +type Secp256k1PublicKey btcec.PublicKey + +// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair +func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { + privk, err := btcec.NewPrivateKey(btcec.S256()) + if err != nil { + return nil, nil, err + } + + k := (*Secp256k1PrivateKey)(privk) + return k, k.GetPublic(), nil +} + +// UnmarshalSecp256k1PrivateKey returns a private key from bytes +func UnmarshalSecp256k1PrivateKey(data []byte) (PrivKey, error) { + if len(data) != btcec.PrivKeyBytesLen { + return nil, fmt.Errorf("expected secp256k1 data size to be %d", btcec.PrivKeyBytesLen) + } + + privk, _ := btcec.PrivKeyFromBytes(btcec.S256(), data) + return (*Secp256k1PrivateKey)(privk), nil +} + +// UnmarshalSecp256k1PublicKey returns a public key from bytes +func UnmarshalSecp256k1PublicKey(data []byte) (PubKey, error) { + k, err := btcec.ParsePubKey(data, btcec.S256()) + if err != nil { + return nil, err + } + + return (*Secp256k1PublicKey)(k), nil +} + +// Bytes returns protobuf bytes from a private key +func (k *Secp256k1PrivateKey) Bytes() ([]byte, error) { + return MarshalPrivateKey(k) +} + +// Type returns the private key type +func (k *Secp256k1PrivateKey) Type() pb.KeyType { + return pb.KeyType_Secp256k1 +} + +// Raw returns the bytes of the key +func (k *Secp256k1PrivateKey) Raw() ([]byte, error) { + return (*btcec.PrivateKey)(k).Serialize(), nil +} + +// Equals compares two private keys +func (k *Secp256k1PrivateKey) Equals(o Key) bool { + sk, ok := o.(*Secp256k1PrivateKey) + if !ok { + return false + } + + return k.D.Cmp(sk.D) == 0 +} + +// Sign returns a signature from input data +func (k *Secp256k1PrivateKey) Sign(data []byte) ([]byte, error) { + hash := sha256.Sum256(data) + sig, err := (*btcec.PrivateKey)(k).Sign(hash[:]) + if err != nil { + return nil, err + } + + return sig.Serialize(), nil +} + +// GetPublic returns a public key +func (k *Secp256k1PrivateKey) GetPublic() PubKey { + return (*Secp256k1PublicKey)((*btcec.PrivateKey)(k).PubKey()) +} + +// Bytes returns protobuf bytes from a public key +func (k *Secp256k1PublicKey) Bytes() ([]byte, error) { + return MarshalPublicKey(k) +} + +// Type returns the public key type +func (k *Secp256k1PublicKey) Type() pb.KeyType { + return pb.KeyType_Secp256k1 +} + +// Raw returns the bytes of the key +func (k *Secp256k1PublicKey) Raw() ([]byte, error) { + return (*btcec.PublicKey)(k).SerializeCompressed(), nil +} + +// Equals compares two public keys +func (k *Secp256k1PublicKey) Equals(o Key) bool { + sk, ok := o.(*Secp256k1PublicKey) + if !ok { + return false + } + + return (*btcec.PublicKey)(k).IsEqual((*btcec.PublicKey)(sk)) +} + +// Verify compares a signature against the input data +func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (bool, error) { + sig, err := btcec.ParseDERSignature(sigStr, btcec.S256()) + if err != nil { + return false, err + } + + hash := sha256.Sum256(data) + return sig.Verify(hash[:], (*btcec.PublicKey)(k)), nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go b/vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go new file mode 100644 index 00000000..f463e0e8 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go @@ -0,0 +1,27 @@ +// Package discovery provides service advertisement and peer discovery interfaces for libp2p. +package discovery + +import ( + "context" + "time" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// Advertiser is an interface for advertising services +type Advertiser interface { + // Advertise advertises a service + Advertise(ctx context.Context, ns string, opts ...Option) (time.Duration, error) +} + +// Discoverer is an interface for peer discovery +type Discoverer interface { + // FindPeers discovers peers providing a service + FindPeers(ctx context.Context, ns string, opts ...Option) (<-chan peer.AddrInfo, error) +} + +// Discovery is an interface that combines service advertisement and peer discovery +type Discovery interface { + Advertiser + Discoverer +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/discovery/options.go b/vendor/github.com/libp2p/go-libp2p-core/discovery/options.go new file mode 100644 index 00000000..7b283052 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/discovery/options.go @@ -0,0 +1,41 @@ +package discovery + +import "time" + +// DiscoveryOpt is a single discovery option. +type Option func(opts *Options) error + +// DiscoveryOpts is a set of discovery options. +type Options struct { + Ttl time.Duration + Limit int + + // Other (implementation-specific) options + Other map[interface{}]interface{} +} + +// Apply applies the given options to this DiscoveryOpts +func (opts *Options) Apply(options ...Option) error { + for _, o := range options { + if err := o(opts); err != nil { + return err + } + } + return nil +} + +// TTL is an option that provides a hint for the duration of an advertisement +func TTL(ttl time.Duration) Option { + return func(opts *Options) error { + opts.Ttl = ttl + return nil + } +} + +// Limit is an option that provides an upper bound on the peer count for discovery +func Limit(limit int) Option { + return func(opts *Options) error { + opts.Limit = limit + return nil + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/helpers/match.go b/vendor/github.com/libp2p/go-libp2p-core/helpers/match.go new file mode 100644 index 00000000..2e246678 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/helpers/match.go @@ -0,0 +1,42 @@ +package helpers + +import ( + "strings" + + "github.com/coreos/go-semver/semver" + "github.com/libp2p/go-libp2p-core/protocol" +) + +// MultistreamSemverMatcher returns a matcher function for a given base protocol. +// The matcher function will return a boolean indicating whether a protocol ID +// matches the base protocol. A given protocol ID matches the base protocol if +// the IDs are the same and if the semantic version of the base protocol is the +// same or higher than that of the protocol ID provided. +// TODO +func MultistreamSemverMatcher(base protocol.ID) (func(string) bool, error) { + parts := strings.Split(string(base), "/") + vers, err := semver.NewVersion(parts[len(parts)-1]) + if err != nil { + return nil, err + } + + return func(check string) bool { + chparts := strings.Split(check, "/") + if len(chparts) != len(parts) { + return false + } + + for i, v := range chparts[:len(chparts)-1] { + if parts[i] != v { + return false + } + } + + chvers, err := semver.NewVersion(chparts[len(chparts)-1]) + if err != nil { + return false + } + + return vers.Major == chvers.Major && vers.Minor >= chvers.Minor + }, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/helpers/stream.go b/vendor/github.com/libp2p/go-libp2p-core/helpers/stream.go new file mode 100644 index 00000000..0b4c1f3e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/helpers/stream.go @@ -0,0 +1,56 @@ +package helpers + +import ( + "errors" + "io" + "time" + + "github.com/libp2p/go-libp2p-core/network" +) + +// EOFTimeout is the maximum amount of time to wait to successfully observe an +// EOF on the stream. Defaults to 60 seconds. +var EOFTimeout = time.Second * 60 + +// ErrExpectedEOF is returned when we read data while expecting an EOF. +var ErrExpectedEOF = errors.New("read data when expecting EOF") + +// FullClose closes the stream and waits to read an EOF from the other side. +// +// * If it reads any data *before* the EOF, it resets the stream. +// * If it doesn't read an EOF within EOFTimeout, it resets the stream. +// +// You'll likely want to invoke this as `go FullClose(stream)` to close the +// stream in the background. +func FullClose(s network.Stream) error { + if err := s.Close(); err != nil { + s.Reset() + return err + } + return AwaitEOF(s) +} + +// AwaitEOF waits for an EOF on the given stream, returning an error if that +// fails. It waits at most EOFTimeout (defaults to 1 minute) after which it +// resets the stream. +func AwaitEOF(s network.Stream) error { + // So we don't wait forever + s.SetDeadline(time.Now().Add(EOFTimeout)) + + // We *have* to observe the EOF. Otherwise, we leak the stream. + // Now, technically, we should do this *before* + // returning from SendMessage as the message + // hasn't really been sent yet until we see the + // EOF but we don't actually *know* what + // protocol the other side is speaking. + n, err := s.Read([]byte{0}) + if n > 0 || err == nil { + s.Reset() + return ErrExpectedEOF + } + if err != io.EOF { + s.Reset() + return err + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/host/helpers.go b/vendor/github.com/libp2p/go-libp2p-core/host/helpers.go new file mode 100644 index 00000000..a24beb1b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/host/helpers.go @@ -0,0 +1,11 @@ +package host + +import "github.com/libp2p/go-libp2p-core/peer" + +// InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs. +func InfoFromHost(h Host) *peer.AddrInfo { + return &peer.AddrInfo{ + ID: h.ID(), + Addrs: h.Addrs(), + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/host/host.go b/vendor/github.com/libp2p/go-libp2p-core/host/host.go new file mode 100644 index 00000000..d4b3c03f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/host/host.go @@ -0,0 +1,71 @@ +// Package host provides the core Host interface for libp2p. +// +// Host represents a single libp2p node in a peer-to-peer network. +package host + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/protocol" + + ma "github.com/multiformats/go-multiaddr" +) + +// Host is an object participating in a p2p network, which +// implements protocols or provides services. It handles +// requests like a Server, and issues requests like a Client. +// It is called Host because it is both Server and Client (and Peer +// may be confusing). +type Host interface { + // ID returns the (local) peer.ID associated with this Host + ID() peer.ID + + // Peerstore returns the Host's repository of Peer Addresses and Keys. + Peerstore() peerstore.Peerstore + + // Returns the listen addresses of the Host + Addrs() []ma.Multiaddr + + // Networks returns the Network interface of the Host + Network() network.Network + + // Mux returns the Mux multiplexing incoming streams to protocol handlers + Mux() protocol.Switch + + // Connect ensures there is a connection between this host and the peer with + // given peer.ID. Connect will absorb the addresses in pi into its internal + // peerstore. If there is not an active connection, Connect will issue a + // h.Network.Dial, and block until a connection is open, or an error is + // returned. // TODO: Relay + NAT. + Connect(ctx context.Context, pi peer.AddrInfo) error + + // SetStreamHandler sets the protocol handler on the Host's Mux. + // This is equivalent to: + // host.Mux().SetHandler(proto, handler) + // (Threadsafe) + SetStreamHandler(pid protocol.ID, handler network.StreamHandler) + + // SetStreamHandlerMatch sets the protocol handler on the Host's Mux + // using a matching function for protocol selection. + SetStreamHandlerMatch(protocol.ID, func(string) bool, network.StreamHandler) + + // RemoveStreamHandler removes a handler on the mux that was set by + // SetStreamHandler + RemoveStreamHandler(pid protocol.ID) + + // NewStream opens a new stream to given peer p, and writes a p2p/protocol + // header with given ProtocolID. If there is no connection to p, attempts + // to create one. If ProtocolID is "", writes no header. + // (Threadsafe) + NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error) + + // Close shuts down the host, its Network, and services. + Close() error + + // ConnManager returns this hosts connection manager + ConnManager() connmgr.ConnManager +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go b/vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go new file mode 100644 index 00000000..e2c8acf3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go @@ -0,0 +1,153 @@ +// Package metrics provides metrics collection and reporting interfaces for libp2p. +package metrics + +import ( + "github.com/libp2p/go-flow-metrics" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +// BandwidthCounter tracks incoming and outgoing data transferred by the local peer. +// Metrics are available for total bandwidth across all peers / protocols, as well +// as segmented by remote peer ID and protocol ID. +type BandwidthCounter struct { + totalIn flow.Meter + totalOut flow.Meter + + protocolIn flow.MeterRegistry + protocolOut flow.MeterRegistry + + peerIn flow.MeterRegistry + peerOut flow.MeterRegistry +} + +// NewBandwidthCounter creates a new BandwidthCounter. +func NewBandwidthCounter() *BandwidthCounter { + return new(BandwidthCounter) +} + +// LogSentMessage records the size of an outgoing message +// without associating the bandwidth to a specific peer or protocol. +func (bwc *BandwidthCounter) LogSentMessage(size int64) { + bwc.totalOut.Mark(uint64(size)) +} + +// LogRecvMessage records the size of an incoming message +// without associating the bandwith to a specific peer or protocol. +func (bwc *BandwidthCounter) LogRecvMessage(size int64) { + bwc.totalIn.Mark(uint64(size)) +} + +// LogSentMessageStream records the size of an outgoing message over a single logical stream. +// Bandwidth is associated with the given protocol.ID and peer.ID. +func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto protocol.ID, p peer.ID) { + bwc.protocolOut.Get(string(proto)).Mark(uint64(size)) + bwc.peerOut.Get(string(p)).Mark(uint64(size)) +} + +// LogRecvMessageStream records the size of an incoming message over a single logical stream. +// Bandwidth is associated with the given protocol.ID and peer.ID. +func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto protocol.ID, p peer.ID) { + bwc.protocolIn.Get(string(proto)).Mark(uint64(size)) + bwc.peerIn.Get(string(p)).Mark(uint64(size)) +} + +// GetBandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID. +// The metrics returned include all traffic sent / received for the peer, regardless of protocol. +func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) { + inSnap := bwc.peerIn.Get(string(p)).Snapshot() + outSnap := bwc.peerOut.Get(string(p)).Snapshot() + + return Stats{ + TotalIn: int64(inSnap.Total), + TotalOut: int64(outSnap.Total), + RateIn: inSnap.Rate, + RateOut: outSnap.Rate, + } +} + +// GetBandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given protocol.ID. +// The metrics returned include all traffic sent / recieved for the protocol, regardless of which peers were +// involved. +func (bwc *BandwidthCounter) GetBandwidthForProtocol(proto protocol.ID) (out Stats) { + inSnap := bwc.protocolIn.Get(string(proto)).Snapshot() + outSnap := bwc.protocolOut.Get(string(proto)).Snapshot() + + return Stats{ + TotalIn: int64(inSnap.Total), + TotalOut: int64(outSnap.Total), + RateIn: inSnap.Rate, + RateOut: outSnap.Rate, + } +} + +// GetBandwidthTotals returns a Stats struct with bandwidth metrics for all data sent / recieved by the +// local peer, regardless of protocol or remote peer IDs. +func (bwc *BandwidthCounter) GetBandwidthTotals() (out Stats) { + inSnap := bwc.totalIn.Snapshot() + outSnap := bwc.totalOut.Snapshot() + + return Stats{ + TotalIn: int64(inSnap.Total), + TotalOut: int64(outSnap.Total), + RateIn: inSnap.Rate, + RateOut: outSnap.Rate, + } +} + +// GetBandwidthByPeer returns a map of all remembered peers and the bandwidth +// metrics with respect to each. This method may be very expensive. +func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats { + peers := make(map[peer.ID]Stats) + + bwc.peerIn.ForEach(func(p string, meter *flow.Meter) { + id := peer.ID(p) + snap := meter.Snapshot() + + stat := peers[id] + stat.TotalIn = int64(snap.Total) + stat.RateIn = snap.Rate + peers[id] = stat + }) + + bwc.peerOut.ForEach(func(p string, meter *flow.Meter) { + id := peer.ID(p) + snap := meter.Snapshot() + + stat := peers[id] + stat.TotalOut = int64(snap.Total) + stat.RateOut = snap.Rate + peers[id] = stat + }) + + return peers +} + +// GetBandwidthByProtocol returns a map of all remembered protocols and +// the bandwidth metrics with respect to each. This method may be moderately +// expensive. +func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]Stats { + protocols := make(map[protocol.ID]Stats) + + bwc.protocolIn.ForEach(func(p string, meter *flow.Meter) { + id := protocol.ID(p) + snap := meter.Snapshot() + + stat := protocols[id] + stat.TotalIn = int64(snap.Total) + stat.RateIn = snap.Rate + protocols[id] = stat + }) + + bwc.protocolOut.ForEach(func(p string, meter *flow.Meter) { + id := protocol.ID(p) + snap := meter.Snapshot() + + stat := protocols[id] + stat.TotalOut = int64(snap.Total) + stat.RateOut = snap.Rate + protocols[id] = stat + }) + + return protocols +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go b/vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go new file mode 100644 index 00000000..860345d6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go @@ -0,0 +1,31 @@ +// Package metrics provides metrics collection and reporting interfaces for libp2p. +package metrics + +import ( + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +// Stats represents a point-in-time snapshot of bandwidth metrics. +// +// The TotalIn and TotalOut fields record cumulative bytes sent / received. +// The RateIn and RateOut fields record bytes sent / received per second. +type Stats struct { + TotalIn int64 + TotalOut int64 + RateIn float64 + RateOut float64 +} + +// Reporter provides methods for logging and retrieving metrics. +type Reporter interface { + LogSentMessage(int64) + LogRecvMessage(int64) + LogSentMessageStream(int64, protocol.ID, peer.ID) + LogRecvMessageStream(int64, protocol.ID, peer.ID) + GetBandwidthForPeer(peer.ID) Stats + GetBandwidthForProtocol(protocol.ID) Stats + GetBandwidthTotals() Stats + GetBandwidthByPeer() map[peer.ID]Stats + GetBandwidthByProtocol() map[protocol.ID]Stats +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/mux/mux.go b/vendor/github.com/libp2p/go-libp2p-core/mux/mux.go new file mode 100644 index 00000000..39f2e51c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/mux/mux.go @@ -0,0 +1,70 @@ +// Package mux provides stream multiplexing interfaces for libp2p. +// +// For a conceptual overview of stream multiplexing in libp2p, see +// https://docs.libp2p.io/concepts/stream-multiplexing/ +package mux + +import ( + "errors" + "io" + "net" + "time" +) + +// ErrReset is returned when reading or writing on a reset stream. +var ErrReset = errors.New("stream reset") + +// Stream is a bidirectional io pipe within a connection. +type MuxedStream interface { + io.Reader + io.Writer + + // Close closes the stream for writing. Reading will still work (that + // is, the remote side can still write). + io.Closer + + // Reset closes both ends of the stream. Use this to tell the remote + // side to hang up and go away. + Reset() error + + SetDeadline(time.Time) error + SetReadDeadline(time.Time) error + SetWriteDeadline(time.Time) error +} + +// NoopHandler do nothing. Resets streams as soon as they are opened. +var NoopHandler = func(s MuxedStream) { s.Reset() } + +// MuxedConn represents a connection to a remote peer that has been +// extended to support stream multiplexing. +// +// A MuxedConn allows a single net.Conn connection to carry many logically +// independent bidirectional streams of binary data. +// +// Together with network.ConnSecurity, MuxedConn is a component of the +// transport.CapableConn interface, which represents a "raw" network +// connection that has been "upgraded" to support the libp2p capabilities +// of secure communication and stream multiplexing. +type MuxedConn interface { + // Close closes the stream muxer and the the underlying net.Conn. + io.Closer + + // IsClosed returns whether a connection is fully closed, so it can + // be garbage collected. + IsClosed() bool + + // OpenStream creates a new stream. + OpenStream() (MuxedStream, error) + + // AcceptStream accepts a stream opened by the other side. + AcceptStream() (MuxedStream, error) +} + +// Multiplexer wraps a net.Conn with a stream multiplexing +// implementation and returns a MuxedConn that supports opening +// multiple streams over the underlying net.Conn +type Multiplexer interface { + + // NewConn constructs a new connection + NewConn(c net.Conn, isServer bool) (MuxedConn, error) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/conn.go b/vendor/github.com/libp2p/go-libp2p-core/network/conn.go new file mode 100644 index 00000000..e7844a0e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/conn.go @@ -0,0 +1,58 @@ +package network + +import ( + "io" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +// Conn is a connection to a remote peer. It multiplexes streams. +// Usually there is no need to use a Conn directly, but it may +// be useful to get information about the peer on the other side: +// stream.Conn().RemotePeer() +type Conn interface { + io.Closer + + ConnSecurity + ConnMultiaddrs + + // NewStream constructs a new Stream over this conn. + NewStream() (Stream, error) + + // GetStreams returns all open streams over this conn. + GetStreams() []Stream + + // Stat stores metadata pertaining to this conn. + Stat() Stat +} + +// ConnSecurity is the interface that one can mix into a connection interface to +// give it the security methods. +type ConnSecurity interface { + // LocalPeer returns our peer ID + LocalPeer() peer.ID + + // LocalPrivateKey returns our private key + LocalPrivateKey() ic.PrivKey + + // RemotePeer returns the peer ID of the remote peer. + RemotePeer() peer.ID + + // RemotePublicKey returns the public key of the remote peer. + RemotePublicKey() ic.PubKey +} + +// ConnMultiaddrs is an interface mixin for connection types that provide multiaddr +// addresses for the endpoints. +type ConnMultiaddrs interface { + // LocalMultiaddr returns the local Multiaddr associated + // with this connection + LocalMultiaddr() ma.Multiaddr + + // RemoteMultiaddr returns the remote Multiaddr associated + // with this connection + RemoteMultiaddr() ma.Multiaddr +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/context.go b/vendor/github.com/libp2p/go-libp2p-core/network/context.go new file mode 100644 index 00000000..9025f83a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/context.go @@ -0,0 +1,48 @@ +package network + +import ( + "context" + "time" +) + +// DialPeerTimeout is the default timeout for a single call to `DialPeer`. When +// there are multiple concurrent calls to `DialPeer`, this timeout will apply to +// each independently. +var DialPeerTimeout = 60 * time.Second + +type noDialCtxKey struct{} +type dialPeerTimeoutCtxKey struct{} + +var noDial = noDialCtxKey{} + +// WithNoDial constructs a new context with an option that instructs the network +// to not attempt a new dial when opening a stream. +func WithNoDial(ctx context.Context, reason string) context.Context { + return context.WithValue(ctx, noDial, reason) +} + +// GetNoDial returns true if the no dial option is set in the context. +func GetNoDial(ctx context.Context) (nodial bool, reason string) { + v := ctx.Value(noDial) + if v != nil { + return true, v.(string) + } + + return false, "" +} + +// GetDialPeerTimeout returns the current DialPeer timeout (or the default). +func GetDialPeerTimeout(ctx context.Context) time.Duration { + if to, ok := ctx.Value(dialPeerTimeoutCtxKey{}).(time.Duration); ok { + return to + } + return DialPeerTimeout +} + +// WithDialPeerTimeout returns a new context with the DialPeer timeout applied. +// +// This timeout overrides the default DialPeerTimeout and applies per-dial +// independently. +func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) context.Context { + return context.WithValue(ctx, dialPeerTimeoutCtxKey{}, timeout) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/errors.go b/vendor/github.com/libp2p/go-libp2p-core/network/errors.go new file mode 100644 index 00000000..f0cf7291 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/errors.go @@ -0,0 +1,10 @@ +package network + +import "errors" + +// ErrNoRemoteAddrs is returned when there are no addresses associated with a peer during a dial. +var ErrNoRemoteAddrs = errors.New("no remote addresses") + +// ErrNoConn is returned when attempting to open a stream to a peer with the NoDial +// option and no usable connection is available. +var ErrNoConn = errors.New("no usable connection to peer") diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/network.go b/vendor/github.com/libp2p/go-libp2p-core/network/network.go new file mode 100644 index 00000000..467109c4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/network.go @@ -0,0 +1,138 @@ +// Package network provides core networking abstractions for libp2p. +// +// The network package provides the high-level Network interface for interacting +// with other libp2p peers, which is the primary public API for initiating and +// accepting connections to remote peers. +package network + +import ( + "context" + "io" + + "github.com/jbenet/goprocess" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + + ma "github.com/multiformats/go-multiaddr" +) + +// MessageSizeMax is a soft (recommended) maximum for network messages. +// One can write more, as the interface is a stream. But it is useful +// to bunch it up into multiple read/writes when the whole message is +// a single, large serialized object. +const MessageSizeMax = 1 << 22 // 4 MB + +// Direction represents which peer in a stream initiated a connection. +type Direction int + +const ( + // DirUnknown is the default direction. + DirUnknown Direction = iota + // DirInbound is for when the remote peer initiated a connection. + DirInbound + // DirOutbound is for when the local peer initiated a connection. + DirOutbound +) + +// Connectedness signals the capacity for a connection with a given node. +// It is used to signal to services and other peers whether a node is reachable. +type Connectedness int + +const ( + // NotConnected means no connection to peer, and no extra information (default) + NotConnected Connectedness = iota + + // Connected means has an open, live connection to peer + Connected + + // CanConnect means recently connected to peer, terminated gracefully + CanConnect + + // CannotConnect means recently attempted connecting but failed to connect. + // (should signal "made effort, failed") + CannotConnect +) + +// Stat stores metadata pertaining to a given Stream/Conn. +type Stat struct { + Direction Direction + Extra map[interface{}]interface{} +} + +// StreamHandler is the type of function used to listen for +// streams opened by the remote side. +type StreamHandler func(Stream) + +// ConnHandler is the type of function used to listen for +// connections opened by the remote side. +type ConnHandler func(Conn) + +// Network is the interface used to connect to the outside world. +// It dials and listens for connections. it uses a Swarm to pool +// connections (see swarm pkg, and peerstream.Swarm). Connections +// are encrypted with a TLS-like protocol. +type Network interface { + Dialer + io.Closer + + // SetStreamHandler sets the handler for new streams opened by the + // remote side. This operation is threadsafe. + SetStreamHandler(StreamHandler) + + // SetConnHandler sets the handler for new connections opened by the + // remote side. This operation is threadsafe. + SetConnHandler(ConnHandler) + + // NewStream returns a new stream to given peer p. + // If there is no connection to p, attempts to create one. + NewStream(context.Context, peer.ID) (Stream, error) + + // Listen tells the network to start listening on given multiaddrs. + Listen(...ma.Multiaddr) error + + // ListenAddresses returns a list of addresses at which this network listens. + ListenAddresses() []ma.Multiaddr + + // InterfaceListenAddresses returns a list of addresses at which this network + // listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to + // use the known local interfaces. + InterfaceListenAddresses() ([]ma.Multiaddr, error) + + // Process returns the network's Process + Process() goprocess.Process +} + +// Dialer represents a service that can dial out to peers +// (this is usually just a Network, but other services may not need the whole +// stack, and thus it becomes easier to mock) +type Dialer interface { + // Peerstore returns the internal peerstore + // This is useful to tell the dialer about a new address for a peer. + // Or use one of the public keys found out over the network. + Peerstore() peerstore.Peerstore + + // LocalPeer returns the local peer associated with this network + LocalPeer() peer.ID + + // DialPeer establishes a connection to a given peer + DialPeer(context.Context, peer.ID) (Conn, error) + + // ClosePeer closes the connection to a given peer + ClosePeer(peer.ID) error + + // Connectedness returns a state signaling connection capabilities + Connectedness(peer.ID) Connectedness + + // Peers returns the peers connected + Peers() []peer.ID + + // Conns returns the connections in this Netowrk + Conns() []Conn + + // ConnsToPeer returns the connections in this Netowrk for given peer. + ConnsToPeer(p peer.ID) []Conn + + // Notify/StopNotify register and unregister a notifiee for signals + Notify(Notifiee) + StopNotify(Notifiee) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/notifee.go b/vendor/github.com/libp2p/go-libp2p-core/network/notifee.go new file mode 100644 index 00000000..10ef72f1 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/notifee.go @@ -0,0 +1,92 @@ +package network + +import ( + ma "github.com/multiformats/go-multiaddr" +) + +// Notifiee is an interface for an object wishing to receive +// notifications from a Network. +type Notifiee interface { + Listen(Network, ma.Multiaddr) // called when network starts listening on an addr + ListenClose(Network, ma.Multiaddr) // called when network stops listening on an addr + Connected(Network, Conn) // called when a connection opened + Disconnected(Network, Conn) // called when a connection closed + OpenedStream(Network, Stream) // called when a stream opened + ClosedStream(Network, Stream) // called when a stream closed + + // TODO + // PeerConnected(Network, peer.ID) // called when a peer connected + // PeerDisconnected(Network, peer.ID) // called when a peer disconnected +} + +// NotifyBundle implements Notifiee by calling any of the functions set on it, +// and nop'ing if they are unset. This is the easy way to register for +// notifications. +type NotifyBundle struct { + ListenF func(Network, ma.Multiaddr) + ListenCloseF func(Network, ma.Multiaddr) + + ConnectedF func(Network, Conn) + DisconnectedF func(Network, Conn) + + OpenedStreamF func(Network, Stream) + ClosedStreamF func(Network, Stream) +} + +var _ Notifiee = (*NotifyBundle)(nil) + +// Listen calls ListenF if it is not null. +func (nb *NotifyBundle) Listen(n Network, a ma.Multiaddr) { + if nb.ListenF != nil { + nb.ListenF(n, a) + } +} + +// ListenClose calls ListenCloseF if it is not null. +func (nb *NotifyBundle) ListenClose(n Network, a ma.Multiaddr) { + if nb.ListenCloseF != nil { + nb.ListenCloseF(n, a) + } +} + +// Connected calls ConnectedF if it is not null. +func (nb *NotifyBundle) Connected(n Network, c Conn) { + if nb.ConnectedF != nil { + nb.ConnectedF(n, c) + } +} + +// Disconnected calls DisconnectedF if it is not null. +func (nb *NotifyBundle) Disconnected(n Network, c Conn) { + if nb.DisconnectedF != nil { + nb.DisconnectedF(n, c) + } +} + +// OpenedStream calls OpenedStreamF if it is not null. +func (nb *NotifyBundle) OpenedStream(n Network, s Stream) { + if nb.OpenedStreamF != nil { + nb.OpenedStreamF(n, s) + } +} + +// ClosedStream calls ClosedStreamF if it is not null. +func (nb *NotifyBundle) ClosedStream(n Network, s Stream) { + if nb.ClosedStreamF != nil { + nb.ClosedStreamF(n, s) + } +} + +// Global noop notifiee. Do not change. +var GlobalNoopNotifiee = &NoopNotifiee{} + +type NoopNotifiee struct{} + +var _ Notifiee = (*NoopNotifiee)(nil) + +func (nn *NoopNotifiee) Connected(n Network, c Conn) {} +func (nn *NoopNotifiee) Disconnected(n Network, c Conn) {} +func (nn *NoopNotifiee) Listen(n Network, addr ma.Multiaddr) {} +func (nn *NoopNotifiee) ListenClose(n Network, addr ma.Multiaddr) {} +func (nn *NoopNotifiee) OpenedStream(Network, Stream) {} +func (nn *NoopNotifiee) ClosedStream(Network, Stream) {} diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/stream.go b/vendor/github.com/libp2p/go-libp2p-core/network/stream.go new file mode 100644 index 00000000..d13dc305 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/network/stream.go @@ -0,0 +1,24 @@ +package network + +import ( + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/protocol" +) + +// Stream represents a bidirectional channel between two agents in +// a libp2p network. "agent" is as granular as desired, potentially +// being a "request -> reply" pair, or whole protocols. +// +// Streams are backed by a multiplexer underneath the hood. +type Stream interface { + mux.MuxedStream + + Protocol() protocol.ID + SetProtocol(id protocol.ID) + + // Stat returns metadata pertaining to this stream. + Stat() Stat + + // Conn returns the connection this stream is part of. + Conn() Conn +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo.go b/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo.go new file mode 100644 index 00000000..6423d846 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo.go @@ -0,0 +1,98 @@ +package peer + +import ( + "fmt" + + ma "github.com/multiformats/go-multiaddr" +) + +// AddrInfo is a small struct used to pass around a peer with +// a set of addresses (and later, keys?). +type AddrInfo struct { + ID ID + Addrs []ma.Multiaddr +} + +var _ fmt.Stringer = AddrInfo{} + +func (pi AddrInfo) String() string { + return fmt.Sprintf("{%v: %v}", pi.ID, pi.Addrs) +} + +var ErrInvalidAddr = fmt.Errorf("invalid p2p multiaddr") + +// AddrInfosFromP2pAddrs converts a set of Multiaddrs to a set of AddrInfos. +func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) { + m := make(map[ID][]ma.Multiaddr) + for _, maddr := range maddrs { + transport, id := SplitAddr(maddr) + if id == "" { + return nil, ErrInvalidAddr + } + if transport == nil { + if _, ok := m[id]; !ok { + m[id] = nil + } + } else { + m[id] = append(m[id], transport) + } + } + ais := make([]AddrInfo, 0, len(m)) + for id, maddrs := range m { + ais = append(ais, AddrInfo{ID: id, Addrs: maddrs}) + } + return ais, nil +} + +// SplitAddr splits a p2p Multiaddr into a transport multiaddr and a peer ID. +// +// * Returns a nil transport if the address only contains a /p2p part. +// * Returns a empty peer ID if the address doesn't contain a /p2p part. +func SplitAddr(m ma.Multiaddr) (transport ma.Multiaddr, id ID) { + if m == nil { + return nil, "" + } + + transport, p2ppart := ma.SplitLast(m) + if p2ppart == nil || p2ppart.Protocol().Code != ma.P_P2P { + return m, "" + } + id = ID(p2ppart.RawValue()) // already validated by the multiaddr library. + return transport, id +} + +// AddrInfoFromP2pAddr converts a Multiaddr to an AddrInfo. +func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) { + transport, id := SplitAddr(m) + if id == "" { + return nil, ErrInvalidAddr + } + info := &AddrInfo{ID: id} + if transport != nil { + info.Addrs = []ma.Multiaddr{transport} + } + return info, nil +} + +// AddrInfoToP2pAddr converts an AddrInfo to a list of Multiaddrs. +func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) { + var addrs []ma.Multiaddr + p2ppart, err := ma.NewComponent("p2p", IDB58Encode(pi.ID)) + if err != nil { + return nil, err + } + if len(pi.Addrs) == 0 { + return []ma.Multiaddr{p2ppart}, nil + } + for _, addr := range pi.Addrs { + addrs = append(addrs, addr.Encapsulate(p2ppart)) + } + return addrs, nil +} + +func (pi *AddrInfo) Loggable() map[string]interface{} { + return map[string]interface{}{ + "peerID": pi.ID.Pretty(), + "addrs": pi.Addrs, + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go b/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go new file mode 100644 index 00000000..1df24e2b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go @@ -0,0 +1,38 @@ +package peer + +import ( + "encoding/json" + + ma "github.com/multiformats/go-multiaddr" +) + +func (pi AddrInfo) MarshalJSON() ([]byte, error) { + out := make(map[string]interface{}) + out["ID"] = pi.ID.Pretty() + var addrs []string + for _, a := range pi.Addrs { + addrs = append(addrs, a.String()) + } + out["Addrs"] = addrs + return json.Marshal(out) +} + +func (pi *AddrInfo) UnmarshalJSON(b []byte) error { + var data map[string]interface{} + err := json.Unmarshal(b, &data) + if err != nil { + return err + } + pid, err := IDB58Decode(data["ID"].(string)) + if err != nil { + return err + } + pi.ID = pid + addrs, ok := data["Addrs"].([]interface{}) + if ok { + for _, a := range addrs { + pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string))) + } + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/peer.go b/vendor/github.com/libp2p/go-libp2p-core/peer/peer.go new file mode 100644 index 00000000..db307ee1 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peer/peer.go @@ -0,0 +1,186 @@ +// Package peer implements an object used to represent peers in the libp2p network. +package peer + +import ( + "encoding/hex" + "errors" + "fmt" + + ic "github.com/libp2p/go-libp2p-core/crypto" + b58 "github.com/mr-tron/base58/base58" + mh "github.com/multiformats/go-multihash" +) + +var ( + // ErrEmptyPeerID is an error for empty peer ID. + ErrEmptyPeerID = errors.New("empty peer ID") + // ErrNoPublicKey is an error for peer IDs that don't embed public keys + ErrNoPublicKey = errors.New("public key is not embedded in peer ID") +) + +// AdvancedEnableInlining enables automatically inlining keys shorter than +// 42 bytes into the peer ID (using the "identity" multihash function). +// +// WARNING: This flag will likely be set to false in the future and eventually +// be removed in favor of using a hash function specified by the key itself. +// See: https://github.com/libp2p/specs/issues/138 +// +// DO NOT change this flag unless you know what you're doing. +// +// This currently defaults to true for backwards compatibility but will likely +// be set to false by default when an upgrade path is determined. +var AdvancedEnableInlining = true + +const maxInlineKeyLength = 42 + +// ID is a libp2p peer identity. +// +// Peer IDs are derived by hashing a peer's public key and encoding the +// hash output as a multihash. See IDFromPublicKey for details. +type ID string + +// Pretty returns a base58-encoded string representation of the ID. +func (id ID) Pretty() string { + return IDB58Encode(id) +} + +// Loggable returns a pretty peer ID string in loggable JSON format. +func (id ID) Loggable() map[string]interface{} { + return map[string]interface{}{ + "peerID": id.Pretty(), + } +} + +func (id ID) String() string { + return id.Pretty() +} + +// String prints out the peer ID. +// +// TODO(brian): ensure correctness at ID generation and +// enforce this by only exposing functions that generate +// IDs safely. Then any peer.ID type found in the +// codebase is known to be correct. +func (id ID) ShortString() string { + pid := id.Pretty() + if len(pid) <= 10 { + return fmt.Sprintf("", pid) + } + return fmt.Sprintf("", pid[:2], pid[len(pid)-6:]) +} + +// MatchesPrivateKey tests whether this ID was derived from the secret key sk. +func (id ID) MatchesPrivateKey(sk ic.PrivKey) bool { + return id.MatchesPublicKey(sk.GetPublic()) +} + +// MatchesPublicKey tests whether this ID was derived from the public key pk. +func (id ID) MatchesPublicKey(pk ic.PubKey) bool { + oid, err := IDFromPublicKey(pk) + if err != nil { + return false + } + return oid == id +} + +// ExtractPublicKey attempts to extract the public key from an ID +// +// This method returns ErrNoPublicKey if the peer ID looks valid but it can't extract +// the public key. +func (id ID) ExtractPublicKey() (ic.PubKey, error) { + decoded, err := mh.Decode([]byte(id)) + if err != nil { + return nil, err + } + if decoded.Code != mh.ID { + return nil, ErrNoPublicKey + } + pk, err := ic.UnmarshalPublicKey(decoded.Digest) + if err != nil { + return nil, err + } + return pk, nil +} + +// Validate checks if ID is empty or not. +func (id ID) Validate() error { + if id == ID("") { + return ErrEmptyPeerID + } + + return nil +} + +// IDFromString casts a string to the ID type, and validates +// the value to make sure it is a multihash. +func IDFromString(s string) (ID, error) { + if _, err := mh.Cast([]byte(s)); err != nil { + return ID(""), err + } + return ID(s), nil +} + +// IDFromBytes casts a byte slice to the ID type, and validates +// the value to make sure it is a multihash. +func IDFromBytes(b []byte) (ID, error) { + if _, err := mh.Cast(b); err != nil { + return ID(""), err + } + return ID(b), nil +} + +// IDB58Decode accepts a base58-encoded multihash representing a peer ID +// and returns the decoded ID if the input is valid. +func IDB58Decode(s string) (ID, error) { + m, err := mh.FromB58String(s) + if err != nil { + return "", err + } + return ID(m), err +} + +// IDB58Encode returns the base58-encoded multihash representation of the ID. +func IDB58Encode(id ID) string { + return b58.Encode([]byte(id)) +} + +// IDHexDecode accepts a hex-encoded multihash representing a peer ID +// and returns the decoded ID if the input is valid. +func IDHexDecode(s string) (ID, error) { + m, err := mh.FromHexString(s) + if err != nil { + return "", err + } + return ID(m), err +} + +// IDHexEncode returns the hex-encoded multihash representation of the ID. +func IDHexEncode(id ID) string { + return hex.EncodeToString([]byte(id)) +} + +// IDFromPublicKey returns the Peer ID corresponding to the public key pk. +func IDFromPublicKey(pk ic.PubKey) (ID, error) { + b, err := pk.Bytes() + if err != nil { + return "", err + } + var alg uint64 = mh.SHA2_256 + if AdvancedEnableInlining && len(b) <= maxInlineKeyLength { + alg = mh.ID + } + hash, _ := mh.Sum(b, alg, -1) + return ID(hash), nil +} + +// IDFromPrivateKey returns the Peer ID corresponding to the secret key sk. +func IDFromPrivateKey(sk ic.PrivKey) (ID, error) { + return IDFromPublicKey(sk.GetPublic()) +} + +// IDSlice for sorting peers +type IDSlice []ID + +func (es IDSlice) Len() int { return len(es) } +func (es IDSlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] } +func (es IDSlice) Less(i, j int) bool { return string(es[i]) < string(es[j]) } diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/peer_serde.go b/vendor/github.com/libp2p/go-libp2p-core/peer/peer_serde.go new file mode 100644 index 00000000..7f1b3e6a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peer/peer_serde.go @@ -0,0 +1,75 @@ +// This file contains Protobuf and JSON serialization/deserialization methods for peer IDs. +package peer + +import ( + "encoding" + "encoding/json" +) + +// Interface assertions commented out to avoid introducing hard dependencies to protobuf. +// var _ proto.Marshaler = (*ID)(nil) +// var _ proto.Unmarshaler = (*ID)(nil) +var _ json.Marshaler = (*ID)(nil) +var _ json.Unmarshaler = (*ID)(nil) + +var _ encoding.BinaryMarshaler = (*ID)(nil) +var _ encoding.BinaryUnmarshaler = (*ID)(nil) +var _ encoding.TextMarshaler = (*ID)(nil) +var _ encoding.TextUnmarshaler = (*ID)(nil) + +func (id ID) Marshal() ([]byte, error) { + return []byte(id), nil +} + +// BinaryMarshal returns the byte representation of the peer ID. +func (id ID) MarshalBinary() ([]byte, error) { + return id.Marshal() +} + +func (id ID) MarshalTo(data []byte) (n int, err error) { + return copy(data, []byte(id)), nil +} + +func (id *ID) Unmarshal(data []byte) (err error) { + *id, err = IDFromBytes(data) + return err +} + +// BinaryUnmarshal sets the ID from its binary representation. +func (id *ID) UnmarshalBinary(data []byte) error { + return id.Unmarshal(data) +} + +// Implements Gogo's proto.Sizer, but we omit the compile-time assertion to avoid introducing a hard +// dependency on gogo. +func (id ID) Size() int { + return len([]byte(id)) +} + +func (id ID) MarshalJSON() ([]byte, error) { + return json.Marshal(IDB58Encode(id)) +} + +func (id *ID) UnmarshalJSON(data []byte) (err error) { + var v string + if err = json.Unmarshal(data, &v); err != nil { + return err + } + *id, err = IDB58Decode(v) + return err +} + +// TextMarshal returns the text encoding of the ID. +func (id ID) MarshalText() ([]byte, error) { + return []byte(IDB58Encode(id)), nil +} + +// TextUnmarshal restores the ID from its text encoding. +func (id *ID) UnmarshalText(data []byte) error { + pid, err := IDB58Decode(string(data)) + if err != nil { + return err + } + *id = pid + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/set.go b/vendor/github.com/libp2p/go-libp2p-core/peer/set.go new file mode 100644 index 00000000..ea82ea80 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peer/set.go @@ -0,0 +1,71 @@ +package peer + +import ( + "sync" +) + +// PeerSet is a threadsafe set of peers +type Set struct { + lk sync.RWMutex + ps map[ID]struct{} + + size int +} + +func NewSet() *Set { + ps := new(Set) + ps.ps = make(map[ID]struct{}) + ps.size = -1 + return ps +} + +func NewLimitedSet(size int) *Set { + ps := new(Set) + ps.ps = make(map[ID]struct{}) + ps.size = size + return ps +} + +func (ps *Set) Add(p ID) { + ps.lk.Lock() + ps.ps[p] = struct{}{} + ps.lk.Unlock() +} + +func (ps *Set) Contains(p ID) bool { + ps.lk.RLock() + _, ok := ps.ps[p] + ps.lk.RUnlock() + return ok +} + +func (ps *Set) Size() int { + ps.lk.RLock() + defer ps.lk.RUnlock() + return len(ps.ps) +} + +// TryAdd Attempts to add the given peer into the set. +// This operation can fail for one of two reasons: +// 1) The given peer is already in the set +// 2) The number of peers in the set is equal to size +func (ps *Set) TryAdd(p ID) bool { + var success bool + ps.lk.Lock() + if _, ok := ps.ps[p]; !ok && (len(ps.ps) < ps.size || ps.size == -1) { + success = true + ps.ps[p] = struct{}{} + } + ps.lk.Unlock() + return success +} + +func (ps *Set) Peers() []ID { + ps.lk.Lock() + out := make([]ID, 0, len(ps.ps)) + for p, _ := range ps.ps { + out = append(out, p) + } + ps.lk.Unlock() + return out +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go b/vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go new file mode 100644 index 00000000..2e1b6449 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go @@ -0,0 +1,162 @@ +// Package peerstore provides types and interfaces for local storage of address information, +// metadata, and public key material about libp2p peers. +package peerstore + +import ( + "context" + "errors" + "io" + "math" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + + ic "github.com/libp2p/go-libp2p-core/crypto" + + ma "github.com/multiformats/go-multiaddr" +) + +var ErrNotFound = errors.New("item not found") + +var ( + // AddressTTL is the expiration time of addresses. + AddressTTL = time.Hour + + // TempAddrTTL is the ttl used for a short lived address + TempAddrTTL = time.Minute * 2 + + // ProviderAddrTTL is the TTL of an address we've received from a provider. + // This is also a temporary address, but lasts longer. After this expires, + // the records we return will require an extra lookup. + ProviderAddrTTL = time.Minute * 10 + + // RecentlyConnectedAddrTTL is used when we recently connected to a peer. + // It means that we are reasonably certain of the peer's address. + RecentlyConnectedAddrTTL = time.Minute * 10 + + // OwnObservedAddrTTL is used for our own external addresses observed by peers. + OwnObservedAddrTTL = time.Minute * 10 +) + +// Permanent TTLs (distinct so we can distinguish between them, constant as they +// are, in fact, permanent) +const ( + // PermanentAddrTTL is the ttl for a "permanent address" (e.g. bootstrap nodes). + PermanentAddrTTL = math.MaxInt64 - iota + + // ConnectedAddrTTL is the ttl used for the addresses of a peer to whom + // we're connected directly. This is basically permanent, as we will + // clear them + re-add under a TempAddrTTL after disconnecting. + ConnectedAddrTTL +) + +// Peerstore provides a threadsafe store of Peer related +// information. +type Peerstore interface { + io.Closer + + AddrBook + KeyBook + PeerMetadata + Metrics + ProtoBook + + // PeerInfo returns a peer.PeerInfo struct for given peer.ID. + // This is a small slice of the information Peerstore has on + // that peer, useful to other services. + PeerInfo(peer.ID) peer.AddrInfo + + // Peers returns all of the peer IDs stored across all inner stores. + Peers() peer.IDSlice +} + +// PeerMetadata can handle values of any type. Serializing values is +// up to the implementation. Dynamic type introspection may not be +// supported, in which case explicitly enlisting types in the +// serializer may be required. +// +// Refer to the docs of the underlying implementation for more +// information. +type PeerMetadata interface { + // Get/Put is a simple registry for other peer-related key/value pairs. + // if we find something we use often, it should become its own set of + // methods. this is a last resort. + Get(p peer.ID, key string) (interface{}, error) + Put(p peer.ID, key string, val interface{}) error +} + +// AddrBook holds the multiaddrs of peers. +type AddrBook interface { + + // AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl) + AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) + + // AddAddrs gives this AddrBook addresses to use, with a given ttl + // (time-to-live), after which the address is no longer valid. + // If the manager has a longer TTL, the operation is a no-op for that address + AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) + + // SetAddr calls mgr.SetAddrs(p, addr, ttl) + SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) + + // SetAddrs sets the ttl on addresses. This clears any TTL there previously. + // This is used when we receive the best estimate of the validity of an address. + SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) + + // UpdateAddrs updates the addresses associated with the given peer that have + // the given oldTTL to have the given newTTL. + UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration) + + // Addresses returns all known (and valid) addresses for a given peer + Addrs(p peer.ID) []ma.Multiaddr + + // AddrStream returns a channel that gets all addresses for a given + // peer sent on it. If new addresses are added after the call is made + // they will be sent along through the channel as well. + AddrStream(context.Context, peer.ID) <-chan ma.Multiaddr + + // ClearAddresses removes all previously stored addresses + ClearAddrs(p peer.ID) + + // PeersWithAddrs returns all of the peer IDs stored in the AddrBook + PeersWithAddrs() peer.IDSlice +} + +// KeyBook tracks the keys of Peers. +type KeyBook interface { + // PubKey stores the public key of a peer. + PubKey(peer.ID) ic.PubKey + + // AddPubKey stores the public key of a peer. + AddPubKey(peer.ID, ic.PubKey) error + + // PrivKey returns the private key of a peer, if known. Generally this might only be our own + // private key, see + // https://discuss.libp2p.io/t/what-is-the-purpose-of-having-map-peer-id-privatekey-in-peerstore/74. + PrivKey(peer.ID) ic.PrivKey + + // AddPrivKey stores the private key of a peer. + AddPrivKey(peer.ID, ic.PrivKey) error + + // PeersWithKeys returns all the peer IDs stored in the KeyBook + PeersWithKeys() peer.IDSlice +} + +// Metrics is just an object that tracks metrics +// across a set of peers. +type Metrics interface { + // RecordLatency records a new latency measurement + RecordLatency(peer.ID, time.Duration) + + // LatencyEWMA returns an exponentially-weighted moving avg. + // of all measurements of a peer's latency. + LatencyEWMA(peer.ID) time.Duration +} + +// ProtoBook tracks the protocols supported by peers +type ProtoBook interface { + GetProtocols(peer.ID) ([]string, error) + AddProtocols(peer.ID, ...string) error + SetProtocols(peer.ID, ...string) error + SupportsProtocols(peer.ID, ...string) ([]string, error) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/env.go b/vendor/github.com/libp2p/go-libp2p-core/pnet/env.go new file mode 100644 index 00000000..c8db5e3c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/pnet/env.go @@ -0,0 +1,19 @@ +package pnet + +import "os" + +// EnvKey defines environment variable name for forcing usage of PNet in libp2p +// When environment variable of this name is set to "1" the ForcePrivateNetwork +// variable will be set to true. +const EnvKey = "LIBP2P_FORCE_PNET" + +// ForcePrivateNetwork is boolean variable that forces usage of PNet in libp2p +// Setting this variable to true or setting LIBP2P_FORCE_PNET environment variable +// to true will make libp2p to require private network protector. +// If no network protector is provided and this variable is set to true libp2p will +// refuse to connect. +var ForcePrivateNetwork = false + +func init() { + ForcePrivateNetwork = os.Getenv(EnvKey) == "1" +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/error.go b/vendor/github.com/libp2p/go-libp2p-core/pnet/error.go new file mode 100644 index 00000000..184b71d6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/pnet/error.go @@ -0,0 +1,34 @@ +package pnet + +// ErrNotInPrivateNetwork is an error that should be returned by libp2p when it +// tries to dial with ForcePrivateNetwork set and no PNet Protector +var ErrNotInPrivateNetwork = NewError("private network was not configured but" + + " is enforced by the environment") + +// Error is error type for ease of detecting PNet errors +type Error interface { + IsPNetError() bool +} + +// NewError creates new Error +func NewError(err string) error { + return pnetErr("privnet: " + err) +} + +// IsPNetError checks if given error is PNet Error +func IsPNetError(err error) bool { + v, ok := err.(Error) + return ok && v.IsPNetError() +} + +type pnetErr string + +var _ Error = (*pnetErr)(nil) + +func (p pnetErr) Error() string { + return string(p) +} + +func (pnetErr) IsPNetError() bool { + return true +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/protector.go b/vendor/github.com/libp2p/go-libp2p-core/pnet/protector.go new file mode 100644 index 00000000..c443ee8f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/pnet/protector.go @@ -0,0 +1,15 @@ +// Package pnet provides interfaces for private networking in libp2p. +package pnet + +import "net" + +// Protector interface is a way for private network implementation to be transparent in +// libp2p. It is created by implementation and use by libp2p-conn to secure connections +// so they can be only established with selected number of peers. +type Protector interface { + // Wraps passed connection to protect it + Protect(net.Conn) (net.Conn, error) + + // Returns key fingerprint that is safe to expose + Fingerprint() []byte +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/protocol/id.go b/vendor/github.com/libp2p/go-libp2p-core/protocol/id.go new file mode 100644 index 00000000..f7e4a32b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/protocol/id.go @@ -0,0 +1,9 @@ +package protocol + +// ID is an identifier used to write protocol headers in streams. +type ID string + +// These are reserved protocol.IDs. +const ( + TestingID ID = "/p2p/_testing" +) diff --git a/vendor/github.com/libp2p/go-libp2p-core/protocol/switch.go b/vendor/github.com/libp2p/go-libp2p-core/protocol/switch.go new file mode 100644 index 00000000..f3ac369b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/protocol/switch.go @@ -0,0 +1,81 @@ +// Package protocol provides core interfaces for protocol routing and negotiation in libp2p. +package protocol + +import ( + "io" +) + +// HandlerFunc is a user-provided function used by the Router to +// handle a protocol/stream. +// +// Will be invoked with the protocol ID string as the first argument, +// which may differ from the ID used for registration if the handler +// was registered using a match function. +type HandlerFunc = func(protocol string, rwc io.ReadWriteCloser) error + +// Router is an interface that allows users to add and remove protocol handlers, +// which will be invoked when incoming stream requests for registered protocols +// are accepted. +// +// Upon receiving an incoming stream request, the Router will check all registered +// protocol handlers to determine which (if any) is capable of handling the stream. +// The handlers are checked in order of registration; if multiple handlers are +// eligible, only the first to be registered will be invoked. +type Router interface { + + // AddHandler registers the given handler to be invoked for + // an exact literal match of the given protocol ID string. + AddHandler(protocol string, handler HandlerFunc) + + // AddHandlerWithFunc registers the given handler to be invoked + // when the provided match function returns true. + // + // The match function will be invoked with an incoming protocol + // ID string, and should return true if the handler supports + // the protocol. Note that the protocol ID argument is not + // used for matching; if you want to match the protocol ID + // string exactly, you must check for it in your match function. + AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc) + + // RemoveHandler removes the registered handler (if any) for the + // given protocol ID string. + RemoveHandler(protocol string) + + // Protocols returns a list of all registered protocol ID strings. + // Note that the Router may be able to handle protocol IDs not + // included in this list if handlers were added with match functions + // using AddHandlerWithFunc. + Protocols() []string +} + +// Negotiator is a component capable of reaching agreement over what protocols +// to use for inbound streams of communication. +type Negotiator interface { + + // NegotiateLazy will return the registered protocol handler to use + // for a given inbound stream, returning as soon as the protocol has been + // determined. Returns an error if negotiation fails. + // + // NegotiateLazy may return before all protocol negotiation responses have been + // written to the stream. This is in contrast to Negotiate, which will block until + // the Negotiator is finished with the stream. + NegotiateLazy(rwc io.ReadWriteCloser) (io.ReadWriteCloser, string, HandlerFunc, error) + + // Negotiate will return the registered protocol handler to use for a given + // inbound stream, returning after the protocol has been determined and the + // Negotiator has finished using the stream for negotiation. Returns an + // error if negotiation fails. + Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error) + + // Handle calls Negotiate to determine which protocol handler to use for an + // inbound stream, then invokes the protocol handler function, passing it + // the protocol ID and the stream. Returns an error if negotiation fails. + Handle(rwc io.ReadWriteCloser) error +} + +// Switch is the component responsible for "dispatching" incoming stream requests to +// their corresponding stream handlers. It is both a Negotiator and a Router. +type Switch interface { + Router + Negotiator +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/options.go b/vendor/github.com/libp2p/go-libp2p-core/routing/options.go new file mode 100644 index 00000000..4b235cbf --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/routing/options.go @@ -0,0 +1,50 @@ +package routing + +// Option is a single routing option. +type Option func(opts *Options) error + +// Options is a set of routing options +type Options struct { + // Allow expired values. + Expired bool + Offline bool + // Other (ValueStore implementation specific) options. + Other map[interface{}]interface{} +} + +// Apply applies the given options to this Options +func (opts *Options) Apply(options ...Option) error { + for _, o := range options { + if err := o(opts); err != nil { + return err + } + } + return nil +} + +// ToOption converts this Options to a single Option. +func (opts *Options) ToOption() Option { + return func(nopts *Options) error { + *nopts = *opts + if opts.Other != nil { + nopts.Other = make(map[interface{}]interface{}, len(opts.Other)) + for k, v := range opts.Other { + nopts.Other[k] = v + } + } + return nil + } +} + +// Expired is an option that tells the routing system to return expired records +// when no newer records are known. +var Expired Option = func(opts *Options) error { + opts.Expired = true + return nil +} + +// Offline is an option that tells the routing system to operate offline (i.e., rely on cached/local data only). +var Offline Option = func(opts *Options) error { + opts.Offline = true + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/query.go b/vendor/github.com/libp2p/go-libp2p-core/routing/query.go new file mode 100644 index 00000000..3769d1c2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/routing/query.go @@ -0,0 +1,86 @@ +package routing + +import ( + "context" + "sync" + + "github.com/libp2p/go-libp2p-core/peer" +) + +type QueryEventType int + +// Number of events to buffer. +var QueryEventBufferSize = 16 + +const ( + SendingQuery QueryEventType = iota + PeerResponse + FinalPeer + QueryError + Provider + Value + AddingPeer + DialingPeer +) + +type QueryEvent struct { + ID peer.ID + Type QueryEventType + Responses []*peer.AddrInfo + Extra string +} + +type routingQueryKey struct{} +type eventChannel struct { + mu sync.Mutex + ctx context.Context + ch chan<- *QueryEvent +} + +// waitThenClose is spawned in a goroutine when the channel is registered. This +// safely cleans up the channel when the context has been canceled. +func (e *eventChannel) waitThenClose() { + <-e.ctx.Done() + e.mu.Lock() + close(e.ch) + // 1. Signals that we're done. + // 2. Frees memory (in case we end up hanging on to this for a while). + e.ch = nil + e.mu.Unlock() +} + +// send sends an event on the event channel, aborting if either the passed or +// the internal context expire. +func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) { + e.mu.Lock() + // Closed. + if e.ch == nil { + e.mu.Unlock() + return + } + // in case the passed context is unrelated, wait on both. + select { + case e.ch <- ev: + case <-e.ctx.Done(): + case <-ctx.Done(): + } + e.mu.Unlock() +} + +func RegisterForQueryEvents(ctx context.Context) (context.Context, <-chan *QueryEvent) { + ch := make(chan *QueryEvent, QueryEventBufferSize) + ech := &eventChannel{ch: ch, ctx: ctx} + go ech.waitThenClose() + return context.WithValue(ctx, routingQueryKey{}, ech), ch +} + +func PublishQueryEvent(ctx context.Context, ev *QueryEvent) { + ich := ctx.Value(routingQueryKey{}) + if ich == nil { + return + } + + // We *want* to panic here. + ech := ich.(*eventChannel) + ech.send(ctx, ev) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go b/vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go new file mode 100644 index 00000000..c7423ffe --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go @@ -0,0 +1,40 @@ +package routing + +import ( + "encoding/json" + + "github.com/libp2p/go-libp2p-core/peer" +) + +func (qe *QueryEvent) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "ID": peer.IDB58Encode(qe.ID), + "Type": int(qe.Type), + "Responses": qe.Responses, + "Extra": qe.Extra, + }) +} + +func (qe *QueryEvent) UnmarshalJSON(b []byte) error { + temp := struct { + ID string + Type int + Responses []*peer.AddrInfo + Extra string + }{} + err := json.Unmarshal(b, &temp) + if err != nil { + return err + } + if len(temp.ID) > 0 { + pid, err := peer.IDB58Decode(temp.ID) + if err != nil { + return err + } + qe.ID = pid + } + qe.Type = QueryEventType(temp.Type) + qe.Responses = temp.Responses + qe.Extra = temp.Extra + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/routing.go b/vendor/github.com/libp2p/go-libp2p-core/routing/routing.go new file mode 100644 index 00000000..c7078054 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/routing/routing.go @@ -0,0 +1,125 @@ +// Package routing provides interfaces for peer routing and content routing in libp2p. +package routing + +import ( + "context" + "errors" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + + cid "github.com/ipfs/go-cid" +) + +// ErrNotFound is returned when the router fails to find the requested record. +var ErrNotFound = errors.New("routing: not found") + +// ErrNotSupported is returned when the router doesn't support the given record +// type/operation. +var ErrNotSupported = errors.New("routing: operation or key not supported") + +// ContentRouting is a value provider layer of indirection. It is used to find +// information about who has what content. +// +// Content is identified by CID (content identifier), which encodes a hash +// of the identified content in a future-proof manner. +type ContentRouting interface { + // Provide adds the given cid to the content routing system. If 'true' is + // passed, it also announces it, otherwise it is just kept in the local + // accounting of which objects are being provided. + Provide(context.Context, cid.Cid, bool) error + + // Search for peers who are able to provide a given key + FindProvidersAsync(context.Context, cid.Cid, int) <-chan peer.AddrInfo +} + +// PeerRouting is a way to find address information about certain peers. +// This can be implemented by a simple lookup table, a tracking server, +// or even a DHT. +type PeerRouting interface { + // Find specific Peer + // FindPeer searches for a peer with given ID, returns a peer.AddrInfo + // with relevant addresses. + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) +} + +// ValueStore is a basic Put/Get interface. +type ValueStore interface { + + // PutValue adds value corresponding to given Key. + PutValue(context.Context, string, []byte, ...Option) error + + // GetValue searches for the value corresponding to given Key. + GetValue(context.Context, string, ...Option) ([]byte, error) + + // SearchValue searches for better and better values from this value + // store corresponding to the given Key. By default implementations must + // stop the search after a good value is found. A 'good' value is a value + // that would be returned from GetValue. + // + // Useful when you want a result *now* but still want to hear about + // better/newer results. + // + // Implementations of this methods won't return ErrNotFound. When a value + // couldn't be found, the channel will get closed without passing any results + SearchValue(context.Context, string, ...Option) (<-chan []byte, error) +} + +// Routing is the combination of different routing types supported by libp2p. +// It can be satisfied by a single item (such as a DHT) or multiple different +// pieces that are more optimized to each task. +type Routing interface { + ContentRouting + PeerRouting + ValueStore + + // Bootstrap allows callers to hint to the routing system to get into a + // Boostrapped state and remain there. It is not a synchronous call. + Bootstrap(context.Context) error + + // TODO expose io.Closer or plain-old Close error +} + +// PubKeyFetcher is an interfaces that should be implemented by value stores +// that can optimize retrieval of public keys. +// +// TODO(steb): Consider removing, see https://github.com/libp2p/go-libp2p-routing/issues/22. +type PubKeyFetcher interface { + // GetPublicKey returns the public key for the given peer. + GetPublicKey(context.Context, peer.ID) (ci.PubKey, error) +} + +// KeyForPublicKey returns the key used to retrieve public keys +// from a value store. +func KeyForPublicKey(id peer.ID) string { + return "/pk/" + string(id) +} + +// GetPublicKey retrieves the public key associated with the given peer ID from +// the value store. +// +// If the ValueStore is also a PubKeyFetcher, this method will call GetPublicKey +// (which may be better optimized) instead of GetValue. +func GetPublicKey(r ValueStore, ctx context.Context, p peer.ID) (ci.PubKey, error) { + switch k, err := p.ExtractPublicKey(); err { + case peer.ErrNoPublicKey: + // check the datastore + case nil: + return k, nil + default: + return nil, err + } + + if dht, ok := r.(PubKeyFetcher); ok { + // If we have a DHT as our routing system, use optimized fetcher + return dht.GetPublicKey(ctx, p) + } + key := KeyForPublicKey(p) + pkval, err := r.GetValue(ctx, key) + if err != nil { + return nil, err + } + + // get PublicKey from node.Data + return ci.UnmarshalPublicKey(pkval) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go b/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go new file mode 100644 index 00000000..801569cb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go @@ -0,0 +1,90 @@ +// Package insecure provides an insecure, unencrypted implementation of the the SecureConn and SecureTransport interfaces. +// +// Recommended only for testing and other non-production usage. +package insecure + +import ( + "context" + "net" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" + + ci "github.com/libp2p/go-libp2p-core/crypto" +) + +// ID is the multistream-select protocol ID that should be used when identifying +// this security transport. +const ID = "/plaintext/1.0.0" + +// Transport is a no-op stream security transport. It provides no +// security and simply mocks the security and identity methods to +// return peer IDs known ahead of time. +type Transport struct { + id peer.ID +} + +// New constructs a new insecure transport. +func New(id peer.ID) *Transport { + return &Transport{ + id: id, + } +} + +// LocalPeer returns the transports local peer ID. +func (t *Transport) LocalPeer() peer.ID { + return t.id +} + +// LocalPrivateKey returns nil. This transport is not secure. +func (t *Transport) LocalPrivateKey() ci.PrivKey { + return nil +} + +// SecureInbound *pretends to secure* an outbound connection to the given peer. +func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { + return &Conn{ + Conn: insecure, + local: t.id, + }, nil +} + +// SecureOutbound *pretends to secure* an outbound connection to the given peer. +func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + return &Conn{ + Conn: insecure, + local: t.id, + remote: p, + }, nil +} + +// Conn is the connection type returned by the insecure transport. +type Conn struct { + net.Conn + local peer.ID + remote peer.ID +} + +// LocalPeer returns the local peer ID. +func (ic *Conn) LocalPeer() peer.ID { + return ic.local +} + +// RemotePeer returns the remote peer ID if we initiated the dial. Otherwise, it +// returns "" (because this connection isn't actually secure). +func (ic *Conn) RemotePeer() peer.ID { + return ic.remote +} + +// RemotePublicKey returns nil. This connection is not secure +func (ic *Conn) RemotePublicKey() ci.PubKey { + return nil +} + +// LocalPrivateKey returns nil. This connection is not secure. +func (ic *Conn) LocalPrivateKey() ci.PrivKey { + return nil +} + +var _ sec.SecureTransport = (*Transport)(nil) +var _ sec.SecureConn = (*Conn)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/security.go b/vendor/github.com/libp2p/go-libp2p-core/sec/security.go new file mode 100644 index 00000000..95c8e6a6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/sec/security.go @@ -0,0 +1,26 @@ +// Package sec provides secure connection and transport interfaces for libp2p. +package sec + +import ( + "context" + "net" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" +) + +// SecureConn is an authenticated, encrypted connection. +type SecureConn interface { + net.Conn + network.ConnSecurity +} + +// A SecureTransport turns inbound and outbound unauthenticated, +// plain-text, native connections into authenticated, encrypted connections. +type SecureTransport interface { + // SecureInbound secures an inbound connection. + SecureInbound(ctx context.Context, insecure net.Conn) (SecureConn, error) + + // SecureOutbound secures an outbound connection. + SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (SecureConn, error) +} diff --git a/vendor/github.com/libp2p/go-libp2p-core/transport/transport.go b/vendor/github.com/libp2p/go-libp2p-core/transport/transport.go new file mode 100644 index 00000000..774b8d82 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-core/transport/transport.go @@ -0,0 +1,113 @@ +// Package transport provides the Transport interface, which represents +// the devices and network protocols used to send and recieve data. +package transport + +import ( + "context" + "net" + "time" + + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +// DialTimeout is the maximum duration a Dial is allowed to take. +// This includes the time between dialing the raw network connection, +// protocol selection as well the handshake, if applicable. +var DialTimeout = 60 * time.Second + +// AcceptTimeout is the maximum duration an Accept is allowed to take. +// This includes the time between accepting the raw network connection, +// protocol selection as well as the handshake, if applicable. +var AcceptTimeout = 60 * time.Second + +// A CapableConn represents a connection that has offers the basic +// capabilities required by libp2p: stream multiplexing, encryption and +// peer authentication. +// +// These capabilities may be natively provided by the transport, or they +// may be shimmed via the "connection upgrade" process, which converts a +// "raw" network connection into one that supports such capabilities by +// layering an encryption channel and a stream multiplexer. +// +// CapableConn provides accessors for the local and remote multiaddrs used to +// establish the connection and an accessor for the underlying Transport. +type CapableConn interface { + mux.MuxedConn + network.ConnSecurity + network.ConnMultiaddrs + + // Transport returns the transport to which this connection belongs. + Transport() Transport +} + +// Transport represents any device by which you can connect to and accept +// connections from other peers. +// +// The Transport interface allows you to open connections to other peers +// by dialing them, and also lets you listen for incoming connections. +// +// Connections returned by Dial and passed into Listeners are of type +// CapableConn, which means that they have been upgraded to support +// stream multiplexing and connection security (encryption and authentication). +// +// For a conceptual overview, see https://docs.libp2p.io/concepts/transport/ +type Transport interface { + // Dial dials a remote peer. It should try to reuse local listener + // addresses if possible but it may choose not to. + Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (CapableConn, error) + + // CanDial returns true if this transport knows how to dial the given + // multiaddr. + // + // Returning true does not guarantee that dialing this multiaddr will + // succeed. This function should *only* be used to preemptively filter + // out addresses that we can't dial. + CanDial(addr ma.Multiaddr) bool + + // Listen listens on the passed multiaddr. + Listen(laddr ma.Multiaddr) (Listener, error) + + // Protocol returns the set of protocols handled by this transport. + // + // See the Network interface for an explanation of how this is used. + Protocols() []int + + // Proxy returns true if this is a proxy transport. + // + // See the Network interface for an explanation of how this is used. + // TODO: Make this a part of the go-multiaddr protocol instead? + Proxy() bool +} + +// Listener is an interface closely resembling the net.Listener interface. The +// only real difference is that Accept() returns Conn's of the type in this +// package, and also exposes a Multiaddr method as opposed to a regular Addr +// method +type Listener interface { + Accept() (CapableConn, error) + Close() error + Addr() net.Addr + Multiaddr() ma.Multiaddr +} + +// Network is an inet.Network with methods for managing transports. +type TransportNetwork interface { + network.Network + + // AddTransport adds a transport to this Network. + // + // When dialing, this Network will iterate over the protocols in the + // remote multiaddr and pick the first protocol registered with a proxy + // transport, if any. Otherwise, it'll pick the transport registered to + // handle the last protocol in the multiaddr. + // + // When listening, this Network will iterate over the protocols in the + // local multiaddr and pick the *last* protocol registered with a proxy + // transport, if any. Otherwise, it'll pick the transport registered to + // handle the last protocol in the multiaddr. + AddTransport(t Transport) error +} diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/.gitignore b/vendor/github.com/libp2p/go-libp2p-crypto/.gitignore new file mode 100644 index 00000000..cc53fd51 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/.gitignore @@ -0,0 +1,7 @@ +.DS_Store + +# vim +.swp +*~ +*.swp +*.swo diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/.travis.yml b/vendor/github.com/libp2p/go-libp2p-crypto/.travis.yml new file mode 100644 index 00000000..97be2f5c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - BUILD_DEPTYPE=gomod + matrix: + - GOTFLAGS="-race" + - GOTFLAGS="-race -tags=openssl" + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/LICENSE b/vendor/github.com/libp2p/go-libp2p-crypto/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/README.md b/vendor/github.com/libp2p/go-libp2p-crypto/README.md new file mode 100644 index 00000000..1d61419b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/README.md @@ -0,0 +1,42 @@ +# go-libp2p-crypto +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-crypto?status.svg)](https://godoc.org/github.com/ipfs/go-libp2p-crypto) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-crypto.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-crypto) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> Various cryptographic utilities used by ipfs + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) + - [Want to hack on IPFS?](#want-to-hack-on-ipfs) +- [License](#license) + +## Install + +```sh +go get github.com/libp2p/go-libp2p-crypto +``` + +## Usage + +Go to https://godoc.org/github.com/libp2p/go-libp2p-crypto. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-crypto/issues)! + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to libp2p are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2016 Jeromy Johnson + +--- + +The last gx published version of this module was: 2.0.7: QmTW4SdgBWq9GjsBsHeUx8WuGxzhgzAf88UMH2w62PC8yK diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/codecov.yml b/vendor/github.com/libp2p/go-libp2p-crypto/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/ecdsa_deprecated.go b/vendor/github.com/libp2p/go-libp2p-crypto/ecdsa_deprecated.go new file mode 100644 index 00000000..f37d6618 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/ecdsa_deprecated.go @@ -0,0 +1,64 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAPrivateKey instead. +type ECDSAPrivateKey = core.ECDSAPrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAPublicKey instead. +type ECDSAPublicKey = core.ECDSAPublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSASig instead. +type ECDSASig = core.ECDSASig + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNotECDSAPubKey instead. + ErrNotECDSAPubKey = core.ErrNotECDSAPubKey + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNilSig instead. + ErrNilSig = core.ErrNilSig + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNilPrivateKey instead. + ErrNilPrivateKey = core.ErrNilPrivateKey + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSACurve instead. + ECDSACurve = core.ECDSACurve +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateECDSAKeyPair instead. +func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateECDSAKeyPair(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateECDSAKeyPairWithCurve instead. +func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateECDSAKeyPairWithCurve(curve, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAKeyPairFromKey instead. +func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) { + return core.ECDSAKeyPairFromKey(priv) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalECDSAPrivateKey instead. +func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) ([]byte, error) { + return core.MarshalECDSAPrivateKey(ePriv) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalECDSAPublicKey instead. +func MarshalECDSAPublicKey(ePub ECDSAPublicKey) ([]byte, error) { + return core.MarshalECDSAPublicKey(ePub) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalECDSAPrivateKey instead. +func UnmarshalECDSAPrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalECDSAPrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalECDSAPublicKey instead. +func UnmarshalECDSAPublicKey(data []byte) (PubKey, error) { + return core.UnmarshalECDSAPublicKey(data) +} diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/ed25519_deprecated.go b/vendor/github.com/libp2p/go-libp2p-crypto/ed25519_deprecated.go new file mode 100644 index 00000000..3d9a4b47 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/ed25519_deprecated.go @@ -0,0 +1,28 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519PrivateKey instead. +type Ed25519PrivateKey = core.Ed25519PrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519PublicKey instead. +type Ed25519PublicKey = core.Ed25519PublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateEd25519Key instead. +func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateEd25519Key(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalEd25519PublicKey instead. +func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { + return core.UnmarshalEd25519PublicKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalEd25519PrivateKey instead. +func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalEd25519PrivateKey(data) +} diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/go.mod b/vendor/github.com/libp2p/go-libp2p-crypto/go.mod new file mode 100644 index 00000000..38a007ab --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/go.mod @@ -0,0 +1,3 @@ +module github.com/libp2p/go-libp2p-crypto + +require github.com/libp2p/go-libp2p-core v0.0.1 diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/go.sum b/vendor/github.com/libp2p/go-libp2p-crypto/go.sum new file mode 100644 index 00000000..669c0351 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/go.sum @@ -0,0 +1,67 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/key_deprecated.go b/vendor/github.com/libp2p/go-libp2p-crypto/key_deprecated.go new file mode 100644 index 00000000..57342690 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/key_deprecated.go @@ -0,0 +1,108 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto instead. +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +const ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RSA instead. + RSA = core.RSA + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519 instead. + Ed25519 = core.Ed25519 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1 instead. + Secp256k1 = core.Secp256k1 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSA instead. + ECDSA = core.ECDSA +) + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrBadKeyType instead. + ErrBadKeyType = core.ErrBadKeyType + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyTypes instead. + KeyTypes = core.KeyTypes +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKeyUnmarshaller instead. +type PubKeyUnmarshaller = core.PubKeyUnmarshaller + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKeyUnmarshaller instead. +type PrivKeyUnmarshaller = core.PrivKeyUnmarshaller + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKeyUnmarshallers instead. +var PubKeyUnmarshallers = core.PubKeyUnmarshallers + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKeyUnmarshallers instead. +var PrivKeyUnmarshallers = core.PrivKeyUnmarshallers + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Key instead. +type Key = core.Key + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKey instead. +type PrivKey = core.PrivKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKey instead. +type PubKey = core.PubKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenSharedKey instead. +type GenSharedKey = core.GenSharedKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateKeyPair instead. +func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) { + return core.GenerateKeyPair(typ, bits) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateKeyPairWithReader instead. +func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateKeyPairWithReader(typ, bits, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateEKeyPair instead. +func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) { + return core.GenerateEKeyPair(curveName) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenSharedKey instead. +type StretchedKeys = core.StretchedKeys + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyStretcher instead. +func KeyStretcher(cipherType string, hashType string, secret []byte) (StretchedKeys, StretchedKeys) { + return core.KeyStretcher(cipherType, hashType, secret) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalPublicKey instead. +func UnmarshalPublicKey(data []byte) (PubKey, error) { + return core.UnmarshalPublicKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalPublicKey instead. +func MarshalPublicKey(k PubKey) ([]byte, error) { + return core.MarshalPublicKey(k) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalPrivateKey instead. +func UnmarshalPrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalPrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalPrivateKey instead. +func MarshalPrivateKey(k PrivKey) ([]byte, error) { + return core.MarshalPrivateKey(k) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ConfigDecodeKey instead. +func ConfigDecodeKey(b string) ([]byte, error) { + return core.ConfigDecodeKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ConfigEncodeKey instead. +func ConfigEncodeKey(b []byte) string { + return core.ConfigEncodeKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyEqual instead. +func KeyEqual(k1, k2 Key) bool { + return core.KeyEqual(k1, k2) +} diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/rsa_deprecated.go b/vendor/github.com/libp2p/go-libp2p-crypto/rsa_deprecated.go new file mode 100644 index 00000000..8c3e4c4c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/rsa_deprecated.go @@ -0,0 +1,31 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrRsaKeyTooSmall instead. +var ErrRsaKeyTooSmall = core.ErrRsaKeyTooSmall + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RsaPrivateKey instead. +type RsaPrivateKey = core.RsaPrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RsaPublicKey instead. +type RsaPublicKey = core.RsaPublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateRSAKeyPair instead. +func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateRSAKeyPair(bits, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalRsaPrivateKey instead. +func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { + return core.UnmarshalRsaPrivateKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalRsaPublicKey instead. +func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { + return core.UnmarshalRsaPublicKey(b) +} diff --git a/vendor/github.com/libp2p/go-libp2p-crypto/secp256k1_deprecated.go b/vendor/github.com/libp2p/go-libp2p-crypto/secp256k1_deprecated.go new file mode 100644 index 00000000..741321c2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-crypto/secp256k1_deprecated.go @@ -0,0 +1,28 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1PrivateKey instead. +type Secp256k1PrivateKey = core.Secp256k1PrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1PublicKey instead. +type Secp256k1PublicKey = core.Secp256k1PublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateSecp256k1Key instead. +func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateSecp256k1Key(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalSecp256k1PrivateKey instead. +func UnmarshalSecp256k1PrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalSecp256k1PrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalSecp256k1PublicKey instead. +func UnmarshalSecp256k1PublicKey(data []byte) (PubKey, error) { + return core.UnmarshalSecp256k1PublicKey(data) +} diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/.gitignore b/vendor/github.com/libp2p/go-libp2p-discovery/.gitignore new file mode 100644 index 00000000..f1c181ec --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/.travis.yml b/vendor/github.com/libp2p/go-libp2p-discovery/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/LICENSE b/vendor/github.com/libp2p/go-libp2p-discovery/LICENSE new file mode 100644 index 00000000..3f05397b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 libp2p + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/README.md b/vendor/github.com/libp2p/go-libp2p-discovery/README.md new file mode 100644 index 00000000..4ab7fe40 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/README.md @@ -0,0 +1,32 @@ +# go-libp2p-discovery + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> Interfaces for active peer discovery + +This package contains interfaces and utilities for active peer discovery. +Peers providing a service use the interface to advertise their presence in some namespace. +Vice versa, peers seeking a service use the interface to discover peers that have previously advertised +as service providers. +The package also includes a baseline implementation for discovery through [Content Routing](https://github.com/libp2p/go-libp2p-routing). + +## Documenation + +See https://godoc.org/github.com/libp2p/go-libp2p-discovery. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-discovery/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +## License + +MIT + +--- + +The last gx published version of this module was: 1.0.15: QmWA8k8apx6egshEjemkuxpKNJS7W7heCgzTnBhAvX9yoB diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/deprecated.go b/vendor/github.com/libp2p/go-libp2p-discovery/deprecated.go new file mode 100644 index 00000000..7ad4149e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/deprecated.go @@ -0,0 +1,32 @@ +package discovery + +import ( + "time" + + core "github.com/libp2p/go-libp2p-core/discovery" +) + +// Deprecated: use skel.Advertiser instead. +type Advertiser = core.Advertiser + +// Deprecated: use skel.Discoverer instead. +type Discoverer = core.Discoverer + +// Deprecated: use skel.Discovery instead. +type Discovery = core.Discovery + +// Deprecated: use github.com/libp2p/go-libp2p-core/discovery.Option instead. +type Option = core.Option + +// Deprecated: use github.com/libp2p/go-libp2p-core/discovery.Options instead. +type Options = core.Options + +// Deprecated: use github.com/libp2p/go-libp2p-core/discovery.TTL instead. +func TTL(ttl time.Duration) core.Option { + return core.TTL(ttl) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/discovery.Limit instead. +func Limit(limit int) core.Option { + return core.Limit(limit) +} diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/go.mod b/vendor/github.com/libp2p/go-libp2p-discovery/go.mod new file mode 100644 index 00000000..f8ea495a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/go.mod @@ -0,0 +1,10 @@ +module github.com/libp2p/go-libp2p-discovery + +require ( + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/multiformats/go-multihash v0.0.5 +) diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/go.sum b/vendor/github.com/libp2p/go-libp2p-discovery/go.sum new file mode 100644 index 00000000..eed16efc --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/go.sum @@ -0,0 +1,227 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/routing.go b/vendor/github.com/libp2p/go-libp2p-discovery/routing.go new file mode 100644 index 00000000..70e70870 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/routing.go @@ -0,0 +1,85 @@ +package discovery + +import ( + "context" + "time" + + cid "github.com/ipfs/go-cid" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + mh "github.com/multiformats/go-multihash" +) + +// RoutingDiscovery is an implementation of discovery using ContentRouting +// Namespaces are translated to Cids using the SHA256 hash. +type RoutingDiscovery struct { + routing.ContentRouting +} + +func NewRoutingDiscovery(router routing.ContentRouting) *RoutingDiscovery { + return &RoutingDiscovery{router} +} + +func (d *RoutingDiscovery) Advertise(ctx context.Context, ns string, opts ...Option) (time.Duration, error) { + var options Options + err := options.Apply(opts...) + if err != nil { + return 0, err + } + + ttl := options.Ttl + if ttl == 0 || ttl > 3*time.Hour { + // the DHT provider record validity is 24hrs, but it is recommnded to republish at least every 6hrs + // we go one step further and republish every 3hrs + ttl = 3 * time.Hour + } + + cid, err := nsToCid(ns) + if err != nil { + return 0, err + } + + // this context requires a timeout; it determines how long the DHT looks for + // closest peers to the key/CID before it goes on to provide the record to them. + // Not setting a timeout here will make the DHT wander forever. + pctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + + err = d.Provide(pctx, cid, true) + if err != nil { + return 0, err + } + + return ttl, nil +} + +func (d *RoutingDiscovery) FindPeers(ctx context.Context, ns string, opts ...Option) (<-chan peer.AddrInfo, error) { + var options Options + err := options.Apply(opts...) + if err != nil { + return nil, err + } + + limit := options.Limit + if limit == 0 { + limit = 100 // that's just arbitrary, but FindProvidersAsync needs a count + } + + cid, err := nsToCid(ns) + if err != nil { + return nil, err + } + + return d.FindProvidersAsync(ctx, cid, limit), nil +} + +func nsToCid(ns string) (cid.Cid, error) { + h, err := mh.Sum([]byte(ns), mh.SHA2_256, -1) + if err != nil { + return cid.Undef, err + } + + return cid.NewCidV1(cid.Raw, h), nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-discovery/util.go b/vendor/github.com/libp2p/go-libp2p-discovery/util.go new file mode 100644 index 00000000..f2f2d2b0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-discovery/util.go @@ -0,0 +1,57 @@ +package discovery + +import ( + "context" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("discovery") + +// FindPeers is a utility function that synchronously collects peers from a Discoverer. +func FindPeers(ctx context.Context, d Discoverer, ns string, opts ...Option) ([]peer.AddrInfo, error) { + var res []peer.AddrInfo + + ch, err := d.FindPeers(ctx, ns, opts...) + if err != nil { + return nil, err + } + + for pi := range ch { + res = append(res, pi) + } + + return res, nil +} + +// Advertise is a utility function that persistently advertises a service through an Advertiser. +func Advertise(ctx context.Context, a Advertiser, ns string, opts ...Option) { + go func() { + for { + ttl, err := a.Advertise(ctx, ns, opts...) + if err != nil { + log.Debugf("Error advertising %s: %s", ns, err.Error()) + if ctx.Err() != nil { + return + } + + select { + case <-time.After(2 * time.Minute): + continue + case <-ctx.Done(): + return + } + } + + wait := 7 * ttl / 8 + select { + case <-time.After(wait): + case <-ctx.Done(): + return + } + } + }() +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/.travis.yml b/vendor/github.com/libp2p/go-libp2p-kad-dht/.travis.yml new file mode 100644 index 00000000..ea3900d9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.12.x + +env: + global: + - GOTFLAGS="-race" + - IPFS_REUSEPORT=false + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/LICENSE b/vendor/github.com/libp2p/go-libp2p-kad-dht/LICENSE new file mode 100644 index 00000000..0e323020 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Protocol Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/README.md b/vendor/github.com/libp2p/go-libp2p-kad-dht/README.md new file mode 100644 index 00000000..c774998a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/README.md @@ -0,0 +1,43 @@ +# go-libp2p-kad-dht + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23yellow) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-kad-dht?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-kad-dht) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-kad-dht.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-kad-dht) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A Kademlia DHT implementation on go-libp2p + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +go get github.com/libp2p/go-libp2p-kad-dht +``` + +## Usage + +Go to https://godoc.org/github.com/libp2p/go-libp2p-kad-dht. + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/libp2p/go-libp2p-kad-dht/issues). + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to libp2p are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © Protocol Labs Inc. + +--- + +The last gx published version of this module was: 4.4.34: QmXuNFLZc6Nb5akB4sZsxK3doShsFKT1sZFvxLXJvZQwAW diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/codecov.yml b/vendor/github.com/libp2p/go-libp2p-kad-dht/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/dht.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht.go new file mode 100644 index 00000000..da3c5cc3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht.go @@ -0,0 +1,439 @@ +package dht + +import ( + "bytes" + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p-core/routing" + + "go.opencensus.io/tag" + "golang.org/x/xerrors" + + "github.com/libp2p/go-libp2p-kad-dht/metrics" + opts "github.com/libp2p/go-libp2p-kad-dht/opts" + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + providers "github.com/libp2p/go-libp2p-kad-dht/providers" + + proto "github.com/gogo/protobuf/proto" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" + goprocessctx "github.com/jbenet/goprocess/context" + kb "github.com/libp2p/go-libp2p-kbucket" + record "github.com/libp2p/go-libp2p-record" + recpb "github.com/libp2p/go-libp2p-record/pb" + base32 "github.com/whyrusleeping/base32" +) + +var logger = logging.Logger("dht") + +// NumBootstrapQueries defines the number of random dht queries to do to +// collect members of the routing table. +const NumBootstrapQueries = 5 + +// IpfsDHT is an implementation of Kademlia with S/Kademlia modifications. +// It is used to implement the base Routing module. +type IpfsDHT struct { + host host.Host // the network services we need + self peer.ID // Local peer (yourself) + peerstore peerstore.Peerstore // Peer Registry + + datastore ds.Datastore // Local data + + routingTable *kb.RoutingTable // Array of routing tables for differently distanced nodes + providers *providers.ProviderManager + + birth time.Time // When this peer started up + + Validator record.Validator + + ctx context.Context + proc goprocess.Process + + strmap map[peer.ID]*messageSender + smlk sync.Mutex + + plk sync.Mutex + + protocols []protocol.ID // DHT protocols +} + +// Assert that IPFS assumptions about interfaces aren't broken. These aren't a +// guarantee, but we can use them to aid refactoring. +var ( + _ routing.ContentRouting = (*IpfsDHT)(nil) + _ routing.Routing = (*IpfsDHT)(nil) + _ routing.PeerRouting = (*IpfsDHT)(nil) + _ routing.PubKeyFetcher = (*IpfsDHT)(nil) + _ routing.ValueStore = (*IpfsDHT)(nil) +) + +// New creates a new DHT with the specified host and options. +func New(ctx context.Context, h host.Host, options ...opts.Option) (*IpfsDHT, error) { + var cfg opts.Options + if err := cfg.Apply(append([]opts.Option{opts.Defaults}, options...)...); err != nil { + return nil, err + } + dht := makeDHT(ctx, h, cfg.Datastore, cfg.Protocols) + + // register for network notifs. + dht.host.Network().Notify((*netNotifiee)(dht)) + + dht.proc = goprocessctx.WithContextAndTeardown(ctx, func() error { + // remove ourselves from network notifs. + dht.host.Network().StopNotify((*netNotifiee)(dht)) + return nil + }) + + dht.proc.AddChild(dht.providers.Process()) + dht.Validator = cfg.Validator + + if !cfg.Client { + for _, p := range cfg.Protocols { + h.SetStreamHandler(p, dht.handleNewStream) + } + } + return dht, nil +} + +// NewDHT creates a new DHT object with the given peer as the 'local' host. +// IpfsDHT's initialized with this function will respond to DHT requests, +// whereas IpfsDHT's initialized with NewDHTClient will not. +func NewDHT(ctx context.Context, h host.Host, dstore ds.Batching) *IpfsDHT { + dht, err := New(ctx, h, opts.Datastore(dstore)) + if err != nil { + panic(err) + } + return dht +} + +// NewDHTClient creates a new DHT object with the given peer as the 'local' +// host. IpfsDHT clients initialized with this function will not respond to DHT +// requests. If you need a peer to respond to DHT requests, use NewDHT instead. +// NewDHTClient creates a new DHT object with the given peer as the 'local' host +func NewDHTClient(ctx context.Context, h host.Host, dstore ds.Batching) *IpfsDHT { + dht, err := New(ctx, h, opts.Datastore(dstore), opts.Client(true)) + if err != nil { + panic(err) + } + return dht +} + +func makeDHT(ctx context.Context, h host.Host, dstore ds.Batching, protocols []protocol.ID) *IpfsDHT { + rt := kb.NewRoutingTable(KValue, kb.ConvertPeerID(h.ID()), time.Minute, h.Peerstore()) + + cmgr := h.ConnManager() + rt.PeerAdded = func(p peer.ID) { + cmgr.TagPeer(p, "kbucket", 5) + } + rt.PeerRemoved = func(p peer.ID) { + cmgr.UntagPeer(p, "kbucket") + } + + dht := &IpfsDHT{ + datastore: dstore, + self: h.ID(), + peerstore: h.Peerstore(), + host: h, + strmap: make(map[peer.ID]*messageSender), + ctx: ctx, + providers: providers.NewProviderManager(ctx, h.ID(), dstore), + birth: time.Now(), + routingTable: rt, + protocols: protocols, + } + + dht.ctx = dht.newContextWithLocalTags(ctx) + + return dht +} + +// putValueToPeer stores the given key/value pair at the peer 'p' +func (dht *IpfsDHT) putValueToPeer(ctx context.Context, p peer.ID, rec *recpb.Record) error { + + pmes := pb.NewMessage(pb.Message_PUT_VALUE, rec.Key, 0) + pmes.Record = rec + rpmes, err := dht.sendRequest(ctx, p, pmes) + if err != nil { + logger.Debugf("putValueToPeer: %v. (peer: %s, key: %s)", err, p.Pretty(), loggableKey(string(rec.Key))) + return err + } + + if !bytes.Equal(rpmes.GetRecord().Value, pmes.GetRecord().Value) { + logger.Warningf("putValueToPeer: value not put correctly. (%v != %v)", pmes, rpmes) + return errors.New("value not put correctly") + } + + return nil +} + +var errInvalidRecord = errors.New("received invalid record") + +// getValueOrPeers queries a particular peer p for the value for +// key. It returns either the value or a list of closer peers. +// NOTE: It will update the dht's peerstore with any new addresses +// it finds for the given peer. +func (dht *IpfsDHT) getValueOrPeers(ctx context.Context, p peer.ID, key string) (*recpb.Record, []*peer.AddrInfo, error) { + + pmes, err := dht.getValueSingle(ctx, p, key) + if err != nil { + return nil, nil, err + } + + // Perhaps we were given closer peers + peers := pb.PBPeersToPeerInfos(pmes.GetCloserPeers()) + + if record := pmes.GetRecord(); record != nil { + // Success! We were given the value + logger.Debug("getValueOrPeers: got value") + + // make sure record is valid. + err = dht.Validator.Validate(string(record.GetKey()), record.GetValue()) + if err != nil { + logger.Info("Received invalid record! (discarded)") + // return a sentinal to signify an invalid record was received + err = errInvalidRecord + record = new(recpb.Record) + } + return record, peers, err + } + + if len(peers) > 0 { + logger.Debug("getValueOrPeers: peers") + return nil, peers, nil + } + + logger.Warning("getValueOrPeers: routing.ErrNotFound") + return nil, nil, routing.ErrNotFound +} + +// getValueSingle simply performs the get value RPC with the given parameters +func (dht *IpfsDHT) getValueSingle(ctx context.Context, p peer.ID, key string) (*pb.Message, error) { + meta := logging.LoggableMap{ + "key": key, + "peer": p, + } + + eip := logger.EventBegin(ctx, "getValueSingle", meta) + defer eip.Done() + + pmes := pb.NewMessage(pb.Message_GET_VALUE, []byte(key), 0) + resp, err := dht.sendRequest(ctx, p, pmes) + switch err { + case nil: + return resp, nil + case ErrReadTimeout: + logger.Warningf("getValueSingle: read timeout %s %s", p.Pretty(), key) + fallthrough + default: + eip.SetError(err) + return nil, err + } +} + +// getLocal attempts to retrieve the value from the datastore +func (dht *IpfsDHT) getLocal(key string) (*recpb.Record, error) { + logger.Debugf("getLocal %s", key) + rec, err := dht.getRecordFromDatastore(mkDsKey(key)) + if err != nil { + logger.Warningf("getLocal: %s", err) + return nil, err + } + + // Double check the key. Can't hurt. + if rec != nil && string(rec.GetKey()) != key { + logger.Errorf("BUG getLocal: found a DHT record that didn't match it's key: %s != %s", rec.GetKey(), key) + return nil, nil + + } + return rec, nil +} + +// putLocal stores the key value pair in the datastore +func (dht *IpfsDHT) putLocal(key string, rec *recpb.Record) error { + logger.Debugf("putLocal: %v %v", key, rec) + data, err := proto.Marshal(rec) + if err != nil { + logger.Warningf("putLocal: %s", err) + return err + } + + return dht.datastore.Put(mkDsKey(key), data) +} + +// Update signals the routingTable to Update its last-seen status +// on the given peer. +func (dht *IpfsDHT) Update(ctx context.Context, p peer.ID) { + logger.Event(ctx, "updatePeer", p) + dht.routingTable.Update(p) +} + +// FindLocal looks for a peer with a given ID connected to this dht and returns the peer and the table it was found in. +func (dht *IpfsDHT) FindLocal(id peer.ID) peer.AddrInfo { + switch dht.host.Network().Connectedness(id) { + case network.Connected, network.CanConnect: + return dht.peerstore.PeerInfo(id) + default: + return peer.AddrInfo{} + } +} + +// findPeerSingle asks peer 'p' if they know where the peer with id 'id' is +func (dht *IpfsDHT) findPeerSingle(ctx context.Context, p peer.ID, id peer.ID) (*pb.Message, error) { + eip := logger.EventBegin(ctx, "findPeerSingle", + logging.LoggableMap{ + "peer": p, + "target": id, + }) + defer eip.Done() + + pmes := pb.NewMessage(pb.Message_FIND_NODE, []byte(id), 0) + resp, err := dht.sendRequest(ctx, p, pmes) + switch err { + case nil: + return resp, nil + case ErrReadTimeout: + logger.Warningf("read timeout: %s %s", p.Pretty(), id) + fallthrough + default: + eip.SetError(err) + return nil, err + } +} + +func (dht *IpfsDHT) findProvidersSingle(ctx context.Context, p peer.ID, key cid.Cid) (*pb.Message, error) { + eip := logger.EventBegin(ctx, "findProvidersSingle", p, key) + defer eip.Done() + + pmes := pb.NewMessage(pb.Message_GET_PROVIDERS, key.Bytes(), 0) + resp, err := dht.sendRequest(ctx, p, pmes) + switch err { + case nil: + return resp, nil + case ErrReadTimeout: + logger.Warningf("read timeout: %s %s", p.Pretty(), key) + fallthrough + default: + eip.SetError(err) + return nil, err + } +} + +// nearestPeersToQuery returns the routing tables closest peers. +func (dht *IpfsDHT) nearestPeersToQuery(pmes *pb.Message, count int) []peer.ID { + closer := dht.routingTable.NearestPeers(kb.ConvertKey(string(pmes.GetKey())), count) + return closer +} + +// betterPeersToQuery returns nearestPeersToQuery, but if and only if closer than self. +func (dht *IpfsDHT) betterPeersToQuery(pmes *pb.Message, p peer.ID, count int) []peer.ID { + closer := dht.nearestPeersToQuery(pmes, count) + + // no node? nil + if closer == nil { + logger.Warning("betterPeersToQuery: no closer peers to send:", p) + return nil + } + + filtered := make([]peer.ID, 0, len(closer)) + for _, clp := range closer { + + // == to self? thats bad + if clp == dht.self { + logger.Error("BUG betterPeersToQuery: attempted to return self! this shouldn't happen...") + return nil + } + // Dont send a peer back themselves + if clp == p { + continue + } + + filtered = append(filtered, clp) + } + + // ok seems like closer nodes + return filtered +} + +// Context return dht's context +func (dht *IpfsDHT) Context() context.Context { + return dht.ctx +} + +// Process return dht's process +func (dht *IpfsDHT) Process() goprocess.Process { + return dht.proc +} + +// RoutingTable return dht's routingTable +func (dht *IpfsDHT) RoutingTable() *kb.RoutingTable { + return dht.routingTable +} + +// Close calls Process Close +func (dht *IpfsDHT) Close() error { + return dht.proc.Close() +} + +func (dht *IpfsDHT) protocolStrs() []string { + pstrs := make([]string, len(dht.protocols)) + for idx, proto := range dht.protocols { + pstrs[idx] = string(proto) + } + + return pstrs +} + +func mkDsKey(s string) ds.Key { + return ds.NewKey(base32.RawStdEncoding.EncodeToString([]byte(s))) +} + +func (dht *IpfsDHT) PeerID() peer.ID { + return dht.self +} + +func (dht *IpfsDHT) PeerKey() []byte { + return kb.ConvertPeerID(dht.self) +} + +func (dht *IpfsDHT) Host() host.Host { + return dht.host +} + +func (dht *IpfsDHT) Ping(ctx context.Context, p peer.ID) error { + req := pb.NewMessage(pb.Message_PING, nil, 0) + resp, err := dht.sendRequest(ctx, p, req) + if err != nil { + return xerrors.Errorf("sending request: %w", err) + } + if resp.Type != pb.Message_PING { + return xerrors.Errorf("got unexpected response type: %v", resp.Type) + } + return nil +} + +// newContextWithLocalTags returns a new context.Context with the InstanceID and +// PeerID keys populated. It will also take any extra tags that need adding to +// the context as tag.Mutators. +func (dht *IpfsDHT) newContextWithLocalTags(ctx context.Context, extraTags ...tag.Mutator) context.Context { + extraTags = append( + extraTags, + tag.Upsert(metrics.KeyPeerID, dht.self.Pretty()), + tag.Upsert(metrics.KeyInstanceID, fmt.Sprintf("%p", dht)), + ) + ctx, _ = tag.New( + ctx, + extraTags..., + ) // ignoring error as it is unrelated to the actual function of this code. + return ctx +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_bootstrap.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_bootstrap.go new file mode 100644 index 00000000..0dd18848 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_bootstrap.go @@ -0,0 +1,184 @@ +package dht + +import ( + "context" + "crypto/rand" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + u "github.com/ipfs/go-ipfs-util" + "github.com/multiformats/go-multiaddr" + _ "github.com/multiformats/go-multiaddr-dns" +) + +var DefaultBootstrapPeers []multiaddr.Multiaddr + +func init() { + for _, s := range []string{ + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", + "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io + "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", // pluto.i.ipfs.io + "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn.i.ipfs.io + "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", // venus.i.ipfs.io + "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", // earth.i.ipfs.io + "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", // pluto.i.ipfs.io + "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn.i.ipfs.io + "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", // venus.i.ipfs.io + "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", // earth.i.ipfs.io + } { + ma, err := multiaddr.NewMultiaddr(s) + if err != nil { + panic(err) + } + DefaultBootstrapPeers = append(DefaultBootstrapPeers, ma) + } +} + +// BootstrapConfig specifies parameters used bootstrapping the DHT. +// +// Note there is a tradeoff between the bootstrap period and the +// number of queries. We could support a higher period with less +// queries. +type BootstrapConfig struct { + Queries int // how many queries to run per period + Period time.Duration // how often to run periodic bootstrap. + Timeout time.Duration // how long to wait for a bootstrap query to run +} + +var DefaultBootstrapConfig = BootstrapConfig{ + // For now, this is set to 1 query. + // We are currently more interested in ensuring we have a properly formed + // DHT than making sure our dht minimizes traffic. Once we are more certain + // of our implementation's robustness, we should lower this down to 8 or 4. + Queries: 1, + + // For now, this is set to 5 minutes, which is a medium period. We are + // We are currently more interested in ensuring we have a properly formed + // DHT than making sure our dht minimizes traffic. + Period: time.Duration(5 * time.Minute), + + Timeout: time.Duration(10 * time.Second), +} + +// A method in the IpfsRouting interface. It calls BootstrapWithConfig with +// the default bootstrap config. +func (dht *IpfsDHT) Bootstrap(ctx context.Context) error { + return dht.BootstrapWithConfig(ctx, DefaultBootstrapConfig) +} + +// Runs cfg.Queries bootstrap queries every cfg.Period. +func (dht *IpfsDHT) BootstrapWithConfig(ctx context.Context, cfg BootstrapConfig) error { + // Because this method is not synchronous, we have to duplicate sanity + // checks on the config so that callers aren't oblivious. + if cfg.Queries <= 0 { + return fmt.Errorf("invalid number of queries: %d", cfg.Queries) + } + go func() { + for { + err := dht.runBootstrap(ctx, cfg) + if err != nil { + logger.Warningf("error bootstrapping: %s", err) + } + select { + case <-time.After(cfg.Period): + case <-ctx.Done(): + return + } + } + }() + return nil +} + +// This is a synchronous bootstrap. cfg.Queries queries will run each with a +// timeout of cfg.Timeout. cfg.Period is not used. +func (dht *IpfsDHT) BootstrapOnce(ctx context.Context, cfg BootstrapConfig) error { + if cfg.Queries <= 0 { + return fmt.Errorf("invalid number of queries: %d", cfg.Queries) + } + return dht.runBootstrap(ctx, cfg) +} + +func newRandomPeerId() peer.ID { + id := make([]byte, 32) // SHA256 is the default. TODO: Use a more canonical way to generate random IDs. + rand.Read(id) + id = u.Hash(id) // TODO: Feed this directly into the multihash instead of hashing it. + return peer.ID(id) +} + +// Traverse the DHT toward the given ID. +func (dht *IpfsDHT) walk(ctx context.Context, target peer.ID) (peer.AddrInfo, error) { + // TODO: Extract the query action (traversal logic?) inside FindPeer, + // don't actually call through the FindPeer machinery, which can return + // things out of the peer store etc. + return dht.FindPeer(ctx, target) +} + +// Traverse the DHT toward a random ID. +func (dht *IpfsDHT) randomWalk(ctx context.Context) error { + id := newRandomPeerId() + p, err := dht.walk(ctx, id) + switch err { + case routing.ErrNotFound: + return nil + case nil: + // We found a peer from a randomly generated ID. This should be very + // unlikely. + logger.Warningf("random walk toward %s actually found peer: %s", id, p) + return nil + default: + return err + } +} + +// Traverse the DHT toward the self ID +func (dht *IpfsDHT) selfWalk(ctx context.Context) error { + _, err := dht.walk(ctx, dht.self) + if err == routing.ErrNotFound { + return nil + } + return err +} + +// runBootstrap builds up list of peers by requesting random peer IDs +func (dht *IpfsDHT) runBootstrap(ctx context.Context, cfg BootstrapConfig) error { + doQuery := func(n int, target string, f func(context.Context) error) error { + logger.Infof("starting bootstrap query (%d/%d) to %s (routing table size was %d)", + n, cfg.Queries, target, dht.routingTable.Size()) + defer func() { + logger.Infof("finished bootstrap query (%d/%d) to %s (routing table size is now %d)", + n, cfg.Queries, target, dht.routingTable.Size()) + }() + queryCtx, cancel := context.WithTimeout(ctx, cfg.Timeout) + defer cancel() + err := f(queryCtx) + if err == context.DeadlineExceeded && queryCtx.Err() == context.DeadlineExceeded && ctx.Err() == nil { + return nil + } + return err + } + + // Do all but one of the bootstrap queries as random walks. + for i := 0; i < cfg.Queries; i++ { + err := doQuery(i, "random ID", dht.randomWalk) + if err != nil { + return err + } + } + + // Find self to distribute peer info to our neighbors. + return doQuery(cfg.Queries, fmt.Sprintf("self: %s", dht.self), dht.selfWalk) +} + +func (dht *IpfsDHT) BootstrapRandom(ctx context.Context) error { + return dht.randomWalk(ctx) +} + +func (dht *IpfsDHT) BootstrapSelf(ctx context.Context) error { + return dht.selfWalk(ctx) +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_net.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_net.go new file mode 100644 index 00000000..ce9e5de3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/dht_net.go @@ -0,0 +1,410 @@ +package dht + +import ( + "bufio" + "context" + "fmt" + "io" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + "github.com/libp2p/go-libp2p-kad-dht/metrics" + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + + ggio "github.com/gogo/protobuf/io" + + "go.opencensus.io/stats" + "go.opencensus.io/tag" +) + +var dhtReadMessageTimeout = time.Minute +var dhtStreamIdleTimeout = 10 * time.Minute +var ErrReadTimeout = fmt.Errorf("timed out reading response") + +// The Protobuf writer performs multiple small writes when writing a message. +// We need to buffer those writes, to make sure that we're not sending a new +// packet for every single write. +type bufferedDelimitedWriter struct { + *bufio.Writer + ggio.WriteCloser +} + +var writerPool = sync.Pool{ + New: func() interface{} { + w := bufio.NewWriter(nil) + return &bufferedDelimitedWriter{ + Writer: w, + WriteCloser: ggio.NewDelimitedWriter(w), + } + }, +} + +func writeMsg(w io.Writer, mes *pb.Message) error { + bw := writerPool.Get().(*bufferedDelimitedWriter) + bw.Reset(w) + err := bw.WriteMsg(mes) + if err == nil { + err = bw.Flush() + } + bw.Reset(nil) + writerPool.Put(bw) + return err +} + +func (w *bufferedDelimitedWriter) Flush() error { + return w.Writer.Flush() +} + +// handleNewStream implements the network.StreamHandler +func (dht *IpfsDHT) handleNewStream(s network.Stream) { + defer s.Reset() + if dht.handleNewMessage(s) { + // Gracefully close the stream for writes. + s.Close() + } +} + +// Returns true on orderly completion of writes (so we can Close the stream). +func (dht *IpfsDHT) handleNewMessage(s network.Stream) bool { + ctx := dht.ctx + r := ggio.NewDelimitedReader(s, network.MessageSizeMax) + + mPeer := s.Conn().RemotePeer() + + timer := time.AfterFunc(dhtStreamIdleTimeout, func() { s.Reset() }) + defer timer.Stop() + + for { + var req pb.Message + switch err := r.ReadMsg(&req); err { + case io.EOF: + return true + default: + // This string test is necessary because there isn't a single stream reset error + // instance in use. + if err.Error() != "stream reset" { + logger.Debugf("error reading message: %#v", err) + } + stats.RecordWithTags( + ctx, + []tag.Mutator{tag.Upsert(metrics.KeyMessageType, "UNKNOWN")}, + metrics.ReceivedMessageErrors.M(1), + ) + return false + case nil: + } + + timer.Reset(dhtStreamIdleTimeout) + + startTime := time.Now() + ctx, _ = tag.New( + ctx, + tag.Upsert(metrics.KeyMessageType, req.GetType().String()), + ) + + stats.Record( + ctx, + metrics.ReceivedMessages.M(1), + metrics.ReceivedBytes.M(int64(req.Size())), + ) + + handler := dht.handlerForMsgType(req.GetType()) + if handler == nil { + stats.Record(ctx, metrics.ReceivedMessageErrors.M(1)) + logger.Warningf("can't handle received message of type %v", req.GetType()) + return false + } + + resp, err := handler(ctx, mPeer, &req) + if err != nil { + stats.Record(ctx, metrics.ReceivedMessageErrors.M(1)) + logger.Debugf("error handling message: %v", err) + return false + } + + dht.updateFromMessage(ctx, mPeer, &req) + + if resp == nil { + continue + } + + // send out response msg + err = writeMsg(s, resp) + if err != nil { + stats.Record(ctx, metrics.ReceivedMessageErrors.M(1)) + logger.Debugf("error writing response: %v", err) + return false + } + + elapsedTime := time.Since(startTime) + latencyMillis := float64(elapsedTime) / float64(time.Millisecond) + stats.Record(ctx, metrics.InboundRequestLatency.M(latencyMillis)) + } +} + +// sendRequest sends out a request, but also makes sure to +// measure the RTT for latency measurements. +func (dht *IpfsDHT) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message) (*pb.Message, error) { + ctx, _ = tag.New(ctx, metrics.UpsertMessageType(pmes)) + + ms, err := dht.messageSenderForPeer(ctx, p) + if err != nil { + stats.Record(ctx, metrics.SentRequestErrors.M(1)) + return nil, err + } + + start := time.Now() + + rpmes, err := ms.SendRequest(ctx, pmes) + if err != nil { + stats.Record(ctx, metrics.SentRequestErrors.M(1)) + return nil, err + } + + // update the peer (on valid msgs only) + dht.updateFromMessage(ctx, p, rpmes) + + stats.Record( + ctx, + metrics.SentRequests.M(1), + metrics.SentBytes.M(int64(pmes.Size())), + metrics.OutboundRequestLatency.M( + float64(time.Since(start))/float64(time.Millisecond), + ), + ) + dht.peerstore.RecordLatency(p, time.Since(start)) + logger.Event(ctx, "dhtReceivedMessage", dht.self, p, rpmes) + return rpmes, nil +} + +// sendMessage sends out a message +func (dht *IpfsDHT) sendMessage(ctx context.Context, p peer.ID, pmes *pb.Message) error { + ctx, _ = tag.New(ctx, metrics.UpsertMessageType(pmes)) + + ms, err := dht.messageSenderForPeer(ctx, p) + if err != nil { + stats.Record(ctx, metrics.SentMessageErrors.M(1)) + return err + } + + if err := ms.SendMessage(ctx, pmes); err != nil { + stats.Record(ctx, metrics.SentMessageErrors.M(1)) + return err + } + + stats.Record( + ctx, + metrics.SentMessages.M(1), + metrics.SentBytes.M(int64(pmes.Size())), + ) + logger.Event(ctx, "dhtSentMessage", dht.self, p, pmes) + return nil +} + +func (dht *IpfsDHT) updateFromMessage(ctx context.Context, p peer.ID, mes *pb.Message) error { + // Make sure that this node is actually a DHT server, not just a client. + protos, err := dht.peerstore.SupportsProtocols(p, dht.protocolStrs()...) + if err == nil && len(protos) > 0 { + dht.Update(ctx, p) + } + return nil +} + +func (dht *IpfsDHT) messageSenderForPeer(ctx context.Context, p peer.ID) (*messageSender, error) { + dht.smlk.Lock() + ms, ok := dht.strmap[p] + if ok { + dht.smlk.Unlock() + return ms, nil + } + ms = &messageSender{p: p, dht: dht} + dht.strmap[p] = ms + dht.smlk.Unlock() + + if err := ms.prepOrInvalidate(ctx); err != nil { + dht.smlk.Lock() + defer dht.smlk.Unlock() + + if msCur, ok := dht.strmap[p]; ok { + // Changed. Use the new one, old one is invalid and + // not in the map so we can just throw it away. + if ms != msCur { + return msCur, nil + } + // Not changed, remove the now invalid stream from the + // map. + delete(dht.strmap, p) + } + // Invalid but not in map. Must have been removed by a disconnect. + return nil, err + } + // All ready to go. + return ms, nil +} + +type messageSender struct { + s network.Stream + r ggio.ReadCloser + lk sync.Mutex + p peer.ID + dht *IpfsDHT + + invalid bool + singleMes int +} + +// invalidate is called before this messageSender is removed from the strmap. +// It prevents the messageSender from being reused/reinitialized and then +// forgotten (leaving the stream open). +func (ms *messageSender) invalidate() { + ms.invalid = true + if ms.s != nil { + ms.s.Reset() + ms.s = nil + } +} + +func (ms *messageSender) prepOrInvalidate(ctx context.Context) error { + ms.lk.Lock() + defer ms.lk.Unlock() + if err := ms.prep(ctx); err != nil { + ms.invalidate() + return err + } + return nil +} + +func (ms *messageSender) prep(ctx context.Context) error { + if ms.invalid { + return fmt.Errorf("message sender has been invalidated") + } + if ms.s != nil { + return nil + } + + nstr, err := ms.dht.host.NewStream(ctx, ms.p, ms.dht.protocols...) + if err != nil { + return err + } + + ms.r = ggio.NewDelimitedReader(nstr, network.MessageSizeMax) + ms.s = nstr + + return nil +} + +// streamReuseTries is the number of times we will try to reuse a stream to a +// given peer before giving up and reverting to the old one-message-per-stream +// behaviour. +const streamReuseTries = 3 + +func (ms *messageSender) SendMessage(ctx context.Context, pmes *pb.Message) error { + ms.lk.Lock() + defer ms.lk.Unlock() + retry := false + for { + if err := ms.prep(ctx); err != nil { + return err + } + + if err := ms.writeMsg(pmes); err != nil { + ms.s.Reset() + ms.s = nil + + if retry { + logger.Info("error writing message, bailing: ", err) + return err + } + logger.Info("error writing message, trying again: ", err) + retry = true + continue + } + + logger.Event(ctx, "dhtSentMessage", ms.dht.self, ms.p, pmes) + + if ms.singleMes > streamReuseTries { + go helpers.FullClose(ms.s) + ms.s = nil + } else if retry { + ms.singleMes++ + } + + return nil + } +} + +func (ms *messageSender) SendRequest(ctx context.Context, pmes *pb.Message) (*pb.Message, error) { + ms.lk.Lock() + defer ms.lk.Unlock() + retry := false + for { + if err := ms.prep(ctx); err != nil { + return nil, err + } + + if err := ms.writeMsg(pmes); err != nil { + ms.s.Reset() + ms.s = nil + + if retry { + logger.Info("error writing message, bailing: ", err) + return nil, err + } + logger.Info("error writing message, trying again: ", err) + retry = true + continue + } + + mes := new(pb.Message) + if err := ms.ctxReadMsg(ctx, mes); err != nil { + ms.s.Reset() + ms.s = nil + + if retry { + logger.Info("error reading message, bailing: ", err) + return nil, err + } + logger.Info("error reading message, trying again: ", err) + retry = true + continue + } + + logger.Event(ctx, "dhtSentMessage", ms.dht.self, ms.p, pmes) + + if ms.singleMes > streamReuseTries { + go helpers.FullClose(ms.s) + ms.s = nil + } else if retry { + ms.singleMes++ + } + + return mes, nil + } +} + +func (ms *messageSender) writeMsg(pmes *pb.Message) error { + return writeMsg(ms.s, pmes) +} + +func (ms *messageSender) ctxReadMsg(ctx context.Context, mes *pb.Message) error { + errc := make(chan error, 1) + go func(r ggio.ReadCloser) { + errc <- r.ReadMsg(mes) + }(ms.r) + + t := time.NewTimer(dhtReadMessageTimeout) + defer t.Stop() + + select { + case err := <-errc: + return err + case <-ctx.Done(): + return ctx.Err() + case <-t.C: + return ErrReadTimeout + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/dial_queue.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/dial_queue.go new file mode 100644 index 00000000..23bd352d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/dial_queue.go @@ -0,0 +1,354 @@ +package dht + +import ( + "context" + "math" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + queue "github.com/libp2p/go-libp2p-peerstore/queue" +) + +const ( + // DefaultDialQueueMinParallelism is the default value for the minimum number of worker dial goroutines that will + // be alive at any time. + DefaultDialQueueMinParallelism = 6 + // DefaultDialQueueMaxParallelism is the default value for the maximum number of worker dial goroutines that can + // be alive at any time. + DefaultDialQueueMaxParallelism = 20 + // DefaultDialQueueMaxIdle is the default value for the period that a worker dial goroutine waits before signalling + // a worker pool downscaling. + DefaultDialQueueMaxIdle = 5 * time.Second + // DefaultDialQueueScalingMutePeriod is the default value for the amount of time to ignore further worker pool + // scaling events, after one is processed. Its role is to reduce jitter. + DefaultDialQueueScalingMutePeriod = 1 * time.Second + // DefaultDialQueueScalingFactor is the default factor by which the current number of workers will be multiplied + // or divided when upscaling and downscaling events occur, respectively. + DefaultDialQueueScalingFactor = 1.5 +) + +type dialQueue struct { + *dqParams + + nWorkers uint + out *queue.ChanQueue + startOnce sync.Once + + waitingCh chan waitingCh + dieCh chan struct{} + growCh chan struct{} + shrinkCh chan struct{} +} + +type dqParams struct { + ctx context.Context + target string + dialFn func(context.Context, peer.ID) error + in *queue.ChanQueue + config dqConfig +} + +type dqConfig struct { + // minParallelism is the minimum number of worker dial goroutines that will be alive at any time. + minParallelism uint + // maxParallelism is the maximum number of worker dial goroutines that can be alive at any time. + maxParallelism uint + // scalingFactor is the factor by which the current number of workers will be multiplied or divided when upscaling + // and downscaling events occur, respectively. + scalingFactor float64 + // mutePeriod is the amount of time to ignore further worker pool scaling events, after one is processed. + // Its role is to reduce jitter. + mutePeriod time.Duration + // maxIdle is the period that a worker dial goroutine waits before signalling a worker pool downscaling. + maxIdle time.Duration +} + +// dqDefaultConfig returns the default configuration for dial queues. See const documentation to learn the default values. +func dqDefaultConfig() dqConfig { + return dqConfig{ + minParallelism: DefaultDialQueueMinParallelism, + maxParallelism: DefaultDialQueueMaxParallelism, + scalingFactor: DefaultDialQueueScalingFactor, + maxIdle: DefaultDialQueueMaxIdle, + mutePeriod: DefaultDialQueueScalingMutePeriod, + } +} + +type waitingCh struct { + ch chan<- peer.ID + ts time.Time +} + +// newDialQueue returns an _unstarted_ adaptive dial queue that spawns a dynamically sized set of goroutines to +// preemptively stage dials for later handoff to the DHT protocol for RPC. It identifies backpressure on both +// ends (dial consumers and dial producers), and takes compensating action by adjusting the worker pool. To +// activate the dial queue, call Start(). +// +// Why? Dialing is expensive. It's orders of magnitude slower than running an RPC on an already-established +// connection, as it requires establishing a TCP connection, multistream handshake, crypto handshake, mux handshake, +// and protocol negotiation. +// +// We start with config.minParallelism number of workers, and scale up and down based on demand and supply of +// dialled peers. +// +// The following events trigger scaling: +// - we scale up when we can't immediately return a successful dial to a new consumer. +// - we scale down when we've been idle for a while waiting for new dial attempts. +// - we scale down when we complete a dial and realise nobody was waiting for it. +// +// Dialler throttling (e.g. FD limit exceeded) is a concern, as we can easily spin up more workers to compensate, and +// end up adding fuel to the fire. Since we have no deterministic way to detect this for now, we hard-limit concurrency +// to config.maxParallelism. +func newDialQueue(params *dqParams) (*dialQueue, error) { + dq := &dialQueue{ + dqParams: params, + out: queue.NewChanQueue(params.ctx, queue.NewXORDistancePQ(params.target)), + growCh: make(chan struct{}, 1), + shrinkCh: make(chan struct{}, 1), + waitingCh: make(chan waitingCh), + dieCh: make(chan struct{}, params.config.maxParallelism), + } + + return dq, nil +} + +// Start initiates action on this dial queue. It should only be called once; subsequent calls are ignored. +func (dq *dialQueue) Start() { + dq.startOnce.Do(func() { + go dq.control() + }) +} + +func (dq *dialQueue) control() { + var ( + dialled <-chan peer.ID + waiting []waitingCh + lastScalingEvt = time.Now() + ) + + defer func() { + for _, w := range waiting { + close(w.ch) + } + waiting = nil + }() + + // start workers + + tgt := int(dq.dqParams.config.minParallelism) + for i := 0; i < tgt; i++ { + go dq.worker() + } + dq.nWorkers = uint(tgt) + + // control workers + + for { + // First process any backlog of dial jobs and waiters -- making progress is the priority. + // This block is copied below; couldn't find a more concise way of doing this. + select { + case <-dq.ctx.Done(): + return + case w := <-dq.waitingCh: + waiting = append(waiting, w) + dialled = dq.out.DeqChan + continue // onto the top. + case p, ok := <-dialled: + if !ok { + return // we're done if the ChanQueue is closed, which happens when the context is closed. + } + w := waiting[0] + logger.Debugf("delivering dialled peer to DHT; took %dms.", time.Since(w.ts)/time.Millisecond) + w.ch <- p + close(w.ch) + waiting = waiting[1:] + if len(waiting) == 0 { + // no more waiters, so stop consuming dialled jobs. + dialled = nil + } + continue // onto the top. + default: + // there's nothing to process, so proceed onto the main select block. + } + + select { + case <-dq.ctx.Done(): + return + case w := <-dq.waitingCh: + waiting = append(waiting, w) + dialled = dq.out.DeqChan + case p, ok := <-dialled: + if !ok { + return // we're done if the ChanQueue is closed, which happens when the context is closed. + } + w := waiting[0] + logger.Debugf("delivering dialled peer to DHT; took %dms.", time.Since(w.ts)/time.Millisecond) + w.ch <- p + close(w.ch) + waiting = waiting[1:] + if len(waiting) == 0 { + // no more waiters, so stop consuming dialled jobs. + dialled = nil + } + case <-dq.growCh: + if time.Since(lastScalingEvt) < dq.config.mutePeriod { + continue + } + dq.grow() + lastScalingEvt = time.Now() + case <-dq.shrinkCh: + if time.Since(lastScalingEvt) < dq.config.mutePeriod { + continue + } + dq.shrink() + lastScalingEvt = time.Now() + } + } +} + +func (dq *dialQueue) Consume() <-chan peer.ID { + ch := make(chan peer.ID, 1) + + select { + case p, ok := <-dq.out.DeqChan: + // short circuit and return a dialled peer if it's immediately available, or abort if DeqChan is closed. + if ok { + ch <- p + } + close(ch) + return ch + case <-dq.ctx.Done(): + // return a closed channel with no value if we're done. + close(ch) + return ch + default: + } + + // we have no finished dials to return, trigger a scale up. + select { + case dq.growCh <- struct{}{}: + default: + } + + // park the channel until a dialled peer becomes available. + select { + case dq.waitingCh <- waitingCh{ch, time.Now()}: + // all good + case <-dq.ctx.Done(): + // return a closed channel with no value if we're done. + close(ch) + } + return ch +} + +func (dq *dialQueue) grow() { + // no mutex needed as this is only called from the (single-threaded) control loop. + defer func(prev uint) { + if prev == dq.nWorkers { + return + } + logger.Debugf("grew dial worker pool: %d => %d", prev, dq.nWorkers) + }(dq.nWorkers) + + if dq.nWorkers == dq.config.maxParallelism { + return + } + // choosing not to worry about uint wrapping beyond max value. + target := uint(math.Floor(float64(dq.nWorkers) * dq.config.scalingFactor)) + if target > dq.config.maxParallelism { + target = dq.config.maxParallelism + } + for ; dq.nWorkers < target; dq.nWorkers++ { + go dq.worker() + } +} + +func (dq *dialQueue) shrink() { + // no mutex needed as this is only called from the (single-threaded) control loop. + defer func(prev uint) { + if prev == dq.nWorkers { + return + } + logger.Debugf("shrunk dial worker pool: %d => %d", prev, dq.nWorkers) + }(dq.nWorkers) + + if dq.nWorkers == dq.config.minParallelism { + return + } + target := uint(math.Floor(float64(dq.nWorkers) / dq.config.scalingFactor)) + if target < dq.config.minParallelism { + target = dq.config.minParallelism + } + // send as many die signals as workers we have to prune. + for ; dq.nWorkers > target; dq.nWorkers-- { + select { + case dq.dieCh <- struct{}{}: + default: + logger.Debugf("too many die signals queued up.") + } + } +} + +func (dq *dialQueue) worker() { + // This idle timer tracks if the environment is slow. If we're waiting to long to acquire a peer to dial, + // it means that the DHT query is progressing slow and we should shrink the worker pool. + idleTimer := time.NewTimer(24 * time.Hour) // placeholder init value which will be overridden immediately. + for { + // trap exit signals first. + select { + case <-dq.ctx.Done(): + return + case <-dq.dieCh: + return + default: + } + + idleTimer.Stop() + select { + case <-idleTimer.C: + default: + } + idleTimer.Reset(dq.config.maxIdle) + + select { + case <-dq.dieCh: + return + case <-dq.ctx.Done(): + return + case <-idleTimer.C: + // no new dial requests during our idle period; time to scale down. + case p, ok := <-dq.in.DeqChan: + if !ok { + return + } + + t := time.Now() + if err := dq.dialFn(dq.ctx, p); err != nil { + logger.Debugf("discarding dialled peer because of error: %v", err) + continue + } + logger.Debugf("dialling %v took %dms (as observed by the dht subsystem).", p, time.Since(t)/time.Millisecond) + waiting := len(dq.waitingCh) + + // by the time we're done dialling, it's possible that the context is closed, in which case there will + // be nobody listening on dq.out.EnqChan and we could block forever. + select { + case dq.out.EnqChan <- p: + case <-dq.ctx.Done(): + return + } + if waiting > 0 { + // we have somebody to deliver this value to, so no need to shrink. + continue + } + } + + // scaling down; control only arrives here if the idle timer fires, or if there are no goroutines + // waiting for the value we just produced. + select { + case dq.shrinkCh <- struct{}{}: + default: + } + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/doc.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/doc.go new file mode 100644 index 00000000..acbb1814 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/doc.go @@ -0,0 +1,3 @@ +// Package dht implements a distributed hash table that satisfies the ipfs routing +// interface. This DHT is modeled after kademlia with S/Kademlia modifications. +package dht diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/go.mod b/vendor/github.com/libp2p/go-libp2p-kad-dht/go.mod new file mode 100644 index 00000000..a29d2756 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/go.mod @@ -0,0 +1,28 @@ +module github.com/libp2p/go-libp2p-kad-dht + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/hashicorp/golang-lru v0.5.1 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/ipfs/go-todocounter v0.0.1 + github.com/jbenet/goprocess v0.1.3 + github.com/libp2p/go-libp2p v0.1.0 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-kbucket v0.2.0 + github.com/libp2p/go-libp2p-peerstore v0.1.0 + github.com/libp2p/go-libp2p-record v0.1.0 + github.com/libp2p/go-libp2p-routing v0.1.0 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/libp2p/go-libp2p-testing v0.0.3 + github.com/mr-tron/base58 v1.1.2 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-dns v0.0.2 + github.com/multiformats/go-multistream v0.1.0 + github.com/stretchr/testify v1.3.0 + github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc + go.opencensus.io v0.21.0 + golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 +) diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/go.sum b/vendor/github.com/libp2p/go-libp2p-kad-dht/go.sum new file mode 100644 index 00000000..2a04aeb9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/go.sum @@ -0,0 +1,315 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-todocounter v0.0.1 h1:kITWA5ZcQZfrUnDNkRn04Xzh0YFaDFXsoO2A81Eb6Lw= +github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.0 h1:8VXadcPNni74ODoZ+7326LMAppFYmz1fRQOUuT5iZvQ= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-kbucket v0.2.0 h1:FB2a0VkOTNGTP5gu/I444u4WabNM9V1zCkQcWb7zajI= +github.com/libp2p/go-libp2p-kbucket v0.2.0/go.mod h1:JNymBToym3QXKBMKGy3m29+xprg0EVr/GJFHxFEdgh8= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-routing v0.1.0 h1:hFnj3WR3E2tOcKaGpyzfP4gvFZ3t8JkQmbapN0Ct+oU= +github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3 h1:YiMaevQcZtFU6DmKIF8xEO0vaui5kM5HJ1V1xkWQv14= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= +github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/handlers.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/handlers.go new file mode 100644 index 00000000..aaeef7ca --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/handlers.go @@ -0,0 +1,387 @@ +package dht + +import ( + "bytes" + "context" + "errors" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + pstore "github.com/libp2p/go-libp2p-peerstore" + + proto "github.com/gogo/protobuf/proto" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + u "github.com/ipfs/go-ipfs-util" + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + recpb "github.com/libp2p/go-libp2p-record/pb" + base32 "github.com/whyrusleeping/base32" +) + +// The number of closer peers to send on requests. +var CloserPeerCount = KValue + +// dhthandler specifies the signature of functions that handle DHT messages. +type dhtHandler func(context.Context, peer.ID, *pb.Message) (*pb.Message, error) + +func (dht *IpfsDHT) handlerForMsgType(t pb.Message_MessageType) dhtHandler { + switch t { + case pb.Message_GET_VALUE: + return dht.handleGetValue + case pb.Message_PUT_VALUE: + return dht.handlePutValue + case pb.Message_FIND_NODE: + return dht.handleFindPeer + case pb.Message_ADD_PROVIDER: + return dht.handleAddProvider + case pb.Message_GET_PROVIDERS: + return dht.handleGetProviders + case pb.Message_PING: + return dht.handlePing + default: + return nil + } +} + +func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Message) (_ *pb.Message, err error) { + ctx = logger.Start(ctx, "handleGetValue") + logger.SetTag(ctx, "peer", p) + defer func() { logger.FinishWithErr(ctx, err) }() + logger.Debugf("%s handleGetValue for key: %s", dht.self, pmes.GetKey()) + + // setup response + resp := pb.NewMessage(pmes.GetType(), pmes.GetKey(), pmes.GetClusterLevel()) + + // first, is there even a key? + k := pmes.GetKey() + if len(k) == 0 { + return nil, errors.New("handleGetValue but no key was provided") + // TODO: send back an error response? could be bad, but the other node's hanging. + } + + rec, err := dht.checkLocalDatastore(k) + if err != nil { + return nil, err + } + resp.Record = rec + + // Find closest peer on given cluster to desired key and reply with that info + closer := dht.betterPeersToQuery(pmes, p, CloserPeerCount) + if len(closer) > 0 { + // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos). + closerinfos := pstore.PeerInfos(dht.peerstore, closer) + for _, pi := range closerinfos { + logger.Debugf("handleGetValue returning closer peer: '%s'", pi.ID) + if len(pi.Addrs) < 1 { + logger.Warningf(`no addresses on peer being sent! + [local:%s] + [sending:%s] + [remote:%s]`, dht.self, pi.ID, p) + } + } + + resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), closerinfos) + } + + return resp, nil +} + +func (dht *IpfsDHT) checkLocalDatastore(k []byte) (*recpb.Record, error) { + logger.Debugf("%s handleGetValue looking into ds", dht.self) + dskey := convertToDsKey(k) + buf, err := dht.datastore.Get(dskey) + logger.Debugf("%s handleGetValue looking into ds GOT %v", dht.self, buf) + + if err == ds.ErrNotFound { + return nil, nil + } + + // if we got an unexpected error, bail. + if err != nil { + return nil, err + } + + // if we have the value, send it back + logger.Debugf("%s handleGetValue success!", dht.self) + + rec := new(recpb.Record) + err = proto.Unmarshal(buf, rec) + if err != nil { + logger.Debug("failed to unmarshal DHT record from datastore") + return nil, err + } + + var recordIsBad bool + recvtime, err := u.ParseRFC3339(rec.GetTimeReceived()) + if err != nil { + logger.Info("either no receive time set on record, or it was invalid: ", err) + recordIsBad = true + } + + if time.Since(recvtime) > MaxRecordAge { + logger.Debug("old record found, tossing.") + recordIsBad = true + } + + // NOTE: We do not verify the record here beyond checking these timestamps. + // we put the burden of checking the records on the requester as checking a record + // may be computationally expensive + + if recordIsBad { + err := dht.datastore.Delete(dskey) + if err != nil { + logger.Error("Failed to delete bad record from datastore: ", err) + } + + return nil, nil // can treat this as not having the record at all + } + + return rec, nil +} + +// Cleans the record (to avoid storing arbitrary data). +func cleanRecord(rec *recpb.Record) { + rec.TimeReceived = "" +} + +// Store a value in this peer local storage +func (dht *IpfsDHT) handlePutValue(ctx context.Context, p peer.ID, pmes *pb.Message) (_ *pb.Message, err error) { + ctx = logger.Start(ctx, "handlePutValue") + logger.SetTag(ctx, "peer", p) + defer func() { logger.FinishWithErr(ctx, err) }() + + rec := pmes.GetRecord() + if rec == nil { + logger.Infof("Got nil record from: %s", p.Pretty()) + return nil, errors.New("nil record") + } + + if !bytes.Equal(pmes.GetKey(), rec.GetKey()) { + return nil, errors.New("put key doesn't match record key") + } + + cleanRecord(rec) + + // Make sure the record is valid (not expired, valid signature etc) + if err = dht.Validator.Validate(string(rec.GetKey()), rec.GetValue()); err != nil { + logger.Warningf("Bad dht record in PUT from: %s. %s", p.Pretty(), err) + return nil, err + } + + dskey := convertToDsKey(rec.GetKey()) + + // Make sure the new record is "better" than the record we have locally. + // This prevents a record with for example a lower sequence number from + // overwriting a record with a higher sequence number. + existing, err := dht.getRecordFromDatastore(dskey) + if err != nil { + return nil, err + } + + if existing != nil { + recs := [][]byte{rec.GetValue(), existing.GetValue()} + i, err := dht.Validator.Select(string(rec.GetKey()), recs) + if err != nil { + logger.Warningf("Bad dht record in PUT from %s: %s", p.Pretty(), err) + return nil, err + } + if i != 0 { + logger.Infof("DHT record in PUT from %s is older than existing record. Ignoring", p.Pretty()) + return nil, errors.New("old record") + } + } + + // record the time we receive every record + rec.TimeReceived = u.FormatRFC3339(time.Now()) + + data, err := proto.Marshal(rec) + if err != nil { + return nil, err + } + + err = dht.datastore.Put(dskey, data) + logger.Debugf("%s handlePutValue %v", dht.self, dskey) + return pmes, err +} + +// returns nil, nil when either nothing is found or the value found doesn't properly validate. +// returns nil, some_error when there's a *datastore* error (i.e., something goes very wrong) +func (dht *IpfsDHT) getRecordFromDatastore(dskey ds.Key) (*recpb.Record, error) { + buf, err := dht.datastore.Get(dskey) + if err == ds.ErrNotFound { + return nil, nil + } + if err != nil { + logger.Errorf("Got error retrieving record with key %s from datastore: %s", dskey, err) + return nil, err + } + rec := new(recpb.Record) + err = proto.Unmarshal(buf, rec) + if err != nil { + // Bad data in datastore, log it but don't return an error, we'll just overwrite it + logger.Errorf("Bad record data stored in datastore with key %s: could not unmarshal record", dskey) + return nil, nil + } + + err = dht.Validator.Validate(string(rec.GetKey()), rec.GetValue()) + if err != nil { + // Invalid record in datastore, probably expired but don't return an error, + // we'll just overwrite it + logger.Debugf("Local record verify failed: %s (discarded)", err) + return nil, nil + } + + return rec, nil +} + +func (dht *IpfsDHT) handlePing(_ context.Context, p peer.ID, pmes *pb.Message) (*pb.Message, error) { + logger.Debugf("%s Responding to ping from %s!\n", dht.self, p) + return pmes, nil +} + +func (dht *IpfsDHT) handleFindPeer(ctx context.Context, p peer.ID, pmes *pb.Message) (_ *pb.Message, _err error) { + ctx = logger.Start(ctx, "handleFindPeer") + defer func() { logger.FinishWithErr(ctx, _err) }() + logger.SetTag(ctx, "peer", p) + resp := pb.NewMessage(pmes.GetType(), nil, pmes.GetClusterLevel()) + var closest []peer.ID + + // if looking for self... special case where we send it on CloserPeers. + targetPid := peer.ID(pmes.GetKey()) + if targetPid == dht.self { + closest = []peer.ID{dht.self} + } else { + closest = dht.betterPeersToQuery(pmes, p, CloserPeerCount) + + // Never tell a peer about itself. + if targetPid != p { + // If we're connected to the target peer, report their + // peer info. This makes FindPeer work even if the + // target peer isn't in our routing table. + // + // Alternatively, we could just check our peerstore. + // However, we don't want to return out of date + // information. We can change this in the future when we + // add a progressive, asynchronous `SearchPeer` function + // and improve peer routing in the host. + switch dht.host.Network().Connectedness(targetPid) { + case network.Connected, network.CanConnect: + closest = append(closest, targetPid) + } + } + } + + if closest == nil { + logger.Infof("%s handleFindPeer %s: could not find anything.", dht.self, p) + return resp, nil + } + + // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos). + closestinfos := pstore.PeerInfos(dht.peerstore, closest) + // possibly an over-allocation but this array is temporary anyways. + withAddresses := make([]peer.AddrInfo, 0, len(closestinfos)) + for _, pi := range closestinfos { + if len(pi.Addrs) > 0 { + withAddresses = append(withAddresses, pi) + } + } + + resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), withAddresses) + return resp, nil +} + +func (dht *IpfsDHT) handleGetProviders(ctx context.Context, p peer.ID, pmes *pb.Message) (_ *pb.Message, _err error) { + ctx = logger.Start(ctx, "handleGetProviders") + defer func() { logger.FinishWithErr(ctx, _err) }() + logger.SetTag(ctx, "peer", p) + + resp := pb.NewMessage(pmes.GetType(), pmes.GetKey(), pmes.GetClusterLevel()) + c, err := cid.Cast([]byte(pmes.GetKey())) + if err != nil { + return nil, err + } + logger.SetTag(ctx, "key", c) + + // debug logging niceness. + reqDesc := fmt.Sprintf("%s handleGetProviders(%s, %s): ", dht.self, p, c) + logger.Debugf("%s begin", reqDesc) + defer logger.Debugf("%s end", reqDesc) + + // check if we have this value, to add ourselves as provider. + has, err := dht.datastore.Has(convertToDsKey(c.Bytes())) + if err != nil && err != ds.ErrNotFound { + logger.Debugf("unexpected datastore error: %v\n", err) + has = false + } + + // setup providers + providers := dht.providers.GetProviders(ctx, c) + if has { + providers = append(providers, dht.self) + logger.Debugf("%s have the value. added self as provider", reqDesc) + } + + if len(providers) > 0 { + // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos). + infos := pstore.PeerInfos(dht.peerstore, providers) + resp.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), infos) + logger.Debugf("%s have %d providers: %s", reqDesc, len(providers), infos) + } + + // Also send closer peers. + closer := dht.betterPeersToQuery(pmes, p, CloserPeerCount) + if closer != nil { + // TODO: pstore.PeerInfos should move to core (=> peerstore.AddrInfos). + infos := pstore.PeerInfos(dht.peerstore, closer) + resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), infos) + logger.Debugf("%s have %d closer peers: %s", reqDesc, len(closer), infos) + } + + return resp, nil +} + +func (dht *IpfsDHT) handleAddProvider(ctx context.Context, p peer.ID, pmes *pb.Message) (_ *pb.Message, _err error) { + ctx = logger.Start(ctx, "handleAddProvider") + defer func() { logger.FinishWithErr(ctx, _err) }() + logger.SetTag(ctx, "peer", p) + + c, err := cid.Cast([]byte(pmes.GetKey())) + if err != nil { + return nil, err + } + logger.SetTag(ctx, "key", c) + + logger.Debugf("%s adding %s as a provider for '%s'\n", dht.self, p, c) + + // add provider should use the address given in the message + pinfos := pb.PBPeersToPeerInfos(pmes.GetProviderPeers()) + for _, pi := range pinfos { + if pi.ID != p { + // we should ignore this provider record! not from originator. + // (we should sign them and check signature later...) + logger.Debugf("handleAddProvider received provider %s from %s. Ignore.", pi.ID, p) + continue + } + + if len(pi.Addrs) < 1 { + logger.Debugf("%s got no valid addresses for provider %s. Ignore.", dht.self, p) + continue + } + + logger.Debugf("received provider %s for %s (addrs: %s)", p, c, pi.Addrs) + if pi.ID != dht.self { // don't add own addrs. + // add the received addresses to our peerstore. + dht.peerstore.AddAddrs(pi.ID, pi.Addrs, peerstore.ProviderAddrTTL) + } + dht.providers.AddProvider(ctx, c, p) + } + + return nil, nil +} + +func convertToDsKey(s []byte) ds.Key { + return ds.NewKey(base32.RawStdEncoding.EncodeToString(s)) +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/lookup.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/lookup.go new file mode 100644 index 00000000..ea5bb31a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/lookup.go @@ -0,0 +1,115 @@ +package dht + +import ( + "context" + "fmt" + "strings" + + "github.com/libp2p/go-libp2p-core/peer" + + cid "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log" + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + kb "github.com/libp2p/go-libp2p-kbucket" + notif "github.com/libp2p/go-libp2p-routing/notifications" +) + +func tryFormatLoggableKey(k string) (string, error) { + if len(k) == 0 { + return "", fmt.Errorf("loggableKey is empty") + } + var proto, cstr string + if k[0] == '/' { + // it's a path (probably) + protoEnd := strings.IndexByte(k[1:], '/') + if protoEnd < 0 { + return k, fmt.Errorf("loggableKey starts with '/' but is not a path: %x", k) + } + proto = k[1 : protoEnd+1] + cstr = k[protoEnd+2:] + } else { + proto = "provider" + cstr = k + } + + c, err := cid.Cast([]byte(cstr)) + if err != nil { + return "", fmt.Errorf("loggableKey could not cast key to a CID: %x %v", k, err) + } + return fmt.Sprintf("/%s/%s", proto, c.String()), nil +} + +func loggableKey(k string) logging.LoggableMap { + newKey, err := tryFormatLoggableKey(k) + if err != nil { + logger.Debug(err) + } else { + k = newKey + } + + return logging.LoggableMap{ + "key": k, + } +} + +// Kademlia 'node lookup' operation. Returns a channel of the K closest peers +// to the given key +func (dht *IpfsDHT) GetClosestPeers(ctx context.Context, key string) (<-chan peer.ID, error) { + e := logger.EventBegin(ctx, "getClosestPeers", loggableKey(key)) + tablepeers := dht.routingTable.NearestPeers(kb.ConvertKey(key), AlphaValue) + if len(tablepeers) == 0 { + return nil, kb.ErrLookupFailure + } + + out := make(chan peer.ID, KValue) + + // since the query doesnt actually pass our context down + // we have to hack this here. whyrusleeping isnt a huge fan of goprocess + parent := ctx + query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) { + // For DHT query command + notif.PublishQueryEvent(parent, ¬if.QueryEvent{ + Type: notif.SendingQuery, + ID: p, + }) + + pmes, err := dht.findPeerSingle(ctx, p, peer.ID(key)) + if err != nil { + logger.Debugf("error getting closer peers: %s", err) + return nil, err + } + peers := pb.PBPeersToPeerInfos(pmes.GetCloserPeers()) + + // For DHT query command + notif.PublishQueryEvent(parent, ¬if.QueryEvent{ + Type: notif.PeerResponse, + ID: p, + Responses: peers, + }) + + return &dhtQueryResult{closerPeers: peers}, nil + }) + + go func() { + defer close(out) + defer e.Done() + // run it! + res, err := query.Run(ctx, tablepeers) + if err != nil { + logger.Debugf("closestPeers query run error: %s", err) + } + + if res != nil && res.queriedSet != nil { + sorted := kb.SortClosestPeers(res.queriedSet.Peers(), kb.ConvertKey(key)) + if len(sorted) > KValue { + sorted = sorted[:KValue] + } + + for _, p := range sorted { + out <- p + } + } + }() + + return out, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/metrics/metrics.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/metrics/metrics.go new file mode 100644 index 00000000..bbe48015 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/metrics/metrics.go @@ -0,0 +1,95 @@ +package metrics + +import ( + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" +) + +var ( + defaultBytesDistribution = view.Distribution(1024, 2048, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296) + defaultMillisecondsDistribution = view.Distribution(0.01, 0.05, 0.1, 0.3, 0.6, 0.8, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000) +) + +// Keys +var ( + KeyMessageType, _ = tag.NewKey("message_type") + KeyPeerID, _ = tag.NewKey("peer_id") + // KeyInstanceID identifies a dht instance by the pointer address. + // Useful for differentiating between different dhts that have the same peer id. + KeyInstanceID, _ = tag.NewKey("instance_id") +) + +// UpsertMessageType is a convenience upserts the message type +// of a pb.Message into the KeyMessageType. +func UpsertMessageType(m *pb.Message) tag.Mutator { + return tag.Upsert(KeyMessageType, m.Type.String()) +} + +// Measures +var ( + ReceivedMessages = stats.Int64("libp2p.io/dht/kad/received_messages", "Total number of messages received per RPC", stats.UnitDimensionless) + ReceivedMessageErrors = stats.Int64("libp2p.io/dht/kad/received_message_errors", "Total number of errors for messages received per RPC", stats.UnitDimensionless) + ReceivedBytes = stats.Int64("libp2p.io/dht/kad/received_bytes", "Total received bytes per RPC", stats.UnitBytes) + InboundRequestLatency = stats.Float64("libp2p.io/dht/kad/inbound_request_latency", "Latency per RPC", stats.UnitMilliseconds) + OutboundRequestLatency = stats.Float64("libp2p.io/dht/kad/outbound_request_latency", "Latency per RPC", stats.UnitMilliseconds) + SentMessages = stats.Int64("libp2p.io/dht/kad/sent_messages", "Total number of messages sent per RPC", stats.UnitDimensionless) + SentMessageErrors = stats.Int64("libp2p.io/dht/kad/sent_message_errors", "Total number of errors for messages sent per RPC", stats.UnitDimensionless) + SentRequests = stats.Int64("libp2p.io/dht/kad/sent_requests", "Total number of requests sent per RPC", stats.UnitDimensionless) + SentRequestErrors = stats.Int64("libp2p.io/dht/kad/sent_request_errors", "Total number of errors for requests sent per RPC", stats.UnitDimensionless) + SentBytes = stats.Int64("libp2p.io/dht/kad/sent_bytes", "Total sent bytes per RPC", stats.UnitBytes) +) + +var DefaultViews = []*view.View{ + &view.View{ + Measure: ReceivedMessages, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: ReceivedMessageErrors, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: ReceivedBytes, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: defaultBytesDistribution, + }, + &view.View{ + Measure: InboundRequestLatency, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: defaultMillisecondsDistribution, + }, + &view.View{ + Measure: OutboundRequestLatency, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: defaultMillisecondsDistribution, + }, + &view.View{ + Measure: SentMessages, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: SentMessageErrors, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: SentRequests, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: SentRequestErrors, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: view.Count(), + }, + &view.View{ + Measure: SentBytes, + TagKeys: []tag.Key{KeyMessageType, KeyPeerID, KeyInstanceID}, + Aggregation: defaultBytesDistribution, + }, +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_posix.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_posix.go new file mode 100644 index 00000000..efd1b383 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_posix.go @@ -0,0 +1,12 @@ +// +build !windows,!wasm + +package dht + +import "syscall" + +func curFileLimit() uint64 { + var n syscall.Rlimit + syscall.Getrlimit(syscall.RLIMIT_NOFILE, &n) + // cast because some platforms use int64 (e.g., freebsd) + return uint64(n.Cur) +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_windows.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_windows.go new file mode 100644 index 00000000..888aec0c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/nofile_test_windows.go @@ -0,0 +1,5 @@ +package dht + +func curFileLimit() uint64 { + return 16 * 1024 * 1024 +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/notif.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/notif.go new file mode 100644 index 00000000..3af75849 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/notif.go @@ -0,0 +1,118 @@ +package dht + +import ( + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/network" + + ma "github.com/multiformats/go-multiaddr" + mstream "github.com/multiformats/go-multistream" +) + +// netNotifiee defines methods to be used with the IpfsDHT +type netNotifiee IpfsDHT + +func (nn *netNotifiee) DHT() *IpfsDHT { + return (*IpfsDHT)(nn) +} + +func (nn *netNotifiee) Connected(n network.Network, v network.Conn) { + dht := nn.DHT() + select { + case <-dht.Process().Closing(): + return + default: + } + + p := v.RemotePeer() + protos, err := dht.peerstore.SupportsProtocols(p, dht.protocolStrs()...) + if err == nil && len(protos) != 0 { + // We lock here for consistency with the lock in testConnection. + // This probably isn't necessary because (dis)connect + // notifications are serialized but it's nice to be consistent. + dht.plk.Lock() + defer dht.plk.Unlock() + if dht.host.Network().Connectedness(p) == network.Connected { + dht.Update(dht.Context(), p) + } + return + } + + // Note: Unfortunately, the peerstore may not yet know that this peer is + // a DHT server. So, if it didn't return a positive response above, test + // manually. + go nn.testConnection(v) +} + +func (nn *netNotifiee) testConnection(v network.Conn) { + dht := nn.DHT() + p := v.RemotePeer() + + // Forcibly use *this* connection. Otherwise, if we have two connections, we could: + // 1. Test it twice. + // 2. Have it closed from under us leaving the second (open) connection untested. + s, err := v.NewStream() + if err != nil { + // Connection error + return + } + defer helpers.FullClose(s) + + selected, err := mstream.SelectOneOf(dht.protocolStrs(), s) + if err != nil { + // Doesn't support the protocol + return + } + // Remember this choice (makes subsequent negotiations faster) + dht.peerstore.AddProtocols(p, selected) + + // We lock here as we race with disconnect. If we didn't lock, we could + // finish processing a connect after handling the associated disconnect + // event and add the peer to the routing table after removing it. + dht.plk.Lock() + defer dht.plk.Unlock() + if dht.host.Network().Connectedness(p) == network.Connected { + dht.Update(dht.Context(), p) + } +} + +func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) { + dht := nn.DHT() + select { + case <-dht.Process().Closing(): + return + default: + } + + p := v.RemotePeer() + + // Lock and check to see if we're still connected. We lock to make sure + // we don't concurrently process a connect event. + dht.plk.Lock() + defer dht.plk.Unlock() + if dht.host.Network().Connectedness(p) == network.Connected { + // We're still connected. + return + } + + dht.routingTable.Remove(p) + + dht.smlk.Lock() + defer dht.smlk.Unlock() + ms, ok := dht.strmap[p] + if !ok { + return + } + delete(dht.strmap, p) + + // Do this asynchronously as ms.lk can block for a while. + go func() { + ms.lk.Lock() + defer ms.lk.Unlock() + ms.invalidate() + }() +} + +func (nn *netNotifiee) OpenedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) ClosedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) Listen(n network.Network, a ma.Multiaddr) {} +func (nn *netNotifiee) ListenClose(n network.Network, a ma.Multiaddr) {} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/opts/options.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/opts/options.go new file mode 100644 index 00000000..93ce6c0d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/opts/options.go @@ -0,0 +1,109 @@ +package dhtopts + +import ( + "fmt" + + ds "github.com/ipfs/go-datastore" + dssync "github.com/ipfs/go-datastore/sync" + protocol "github.com/libp2p/go-libp2p-core/protocol" + record "github.com/libp2p/go-libp2p-record" +) + +// Deprecated: The old format did not support more than one message per stream, and is not supported +// or relevant with stream pooling. ProtocolDHT should be used instead. +const ProtocolDHTOld protocol.ID = "/ipfs/dht" + +var ( + ProtocolDHT protocol.ID = "/ipfs/kad/1.0.0" + DefaultProtocols = []protocol.ID{ProtocolDHT} +) + +// Options is a structure containing all the options that can be used when constructing a DHT. +type Options struct { + Datastore ds.Batching + Validator record.Validator + Client bool + Protocols []protocol.ID +} + +// Apply applies the given options to this Option +func (o *Options) Apply(opts ...Option) error { + for i, opt := range opts { + if err := opt(o); err != nil { + return fmt.Errorf("dht option %d failed: %s", i, err) + } + } + return nil +} + +// Option DHT option type. +type Option func(*Options) error + +// Defaults are the default DHT options. This option will be automatically +// prepended to any options you pass to the DHT constructor. +var Defaults = func(o *Options) error { + o.Validator = record.NamespacedValidator{ + "pk": record.PublicKeyValidator{}, + } + o.Datastore = dssync.MutexWrap(ds.NewMapDatastore()) + o.Protocols = DefaultProtocols + return nil +} + +// Datastore configures the DHT to use the specified datastore. +// +// Defaults to an in-memory (temporary) map. +func Datastore(ds ds.Batching) Option { + return func(o *Options) error { + o.Datastore = ds + return nil + } +} + +// Client configures whether or not the DHT operates in client-only mode. +// +// Defaults to false. +func Client(only bool) Option { + return func(o *Options) error { + o.Client = only + return nil + } +} + +// Validator configures the DHT to use the specified validator. +// +// Defaults to a namespaced validator that can only validate public keys. +func Validator(v record.Validator) Option { + return func(o *Options) error { + o.Validator = v + return nil + } +} + +// NamespacedValidator adds a validator namespaced under `ns`. This option fails +// if the DHT is not using a `record.NamespacedValidator` as it's validator (it +// uses one by default but this can be overridden with the `Validator` option). +// +// Example: Given a validator registered as `NamespacedValidator("ipns", +// myValidator)`, all records with keys starting with `/ipns/` will be validated +// with `myValidator`. +func NamespacedValidator(ns string, v record.Validator) Option { + return func(o *Options) error { + nsval, ok := o.Validator.(record.NamespacedValidator) + if !ok { + return fmt.Errorf("can only add namespaced validators to a NamespacedValidator") + } + nsval[ns] = v + return nil + } +} + +// Protocols sets the protocols for the DHT +// +// Defaults to dht.DefaultProtocols +func Protocols(protocols ...protocol.ID) Option { + return func(o *Options) error { + o.Protocols = protocols + return nil + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.pb.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.pb.go new file mode 100644 index 00000000..eb59b73c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.pb.go @@ -0,0 +1,976 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dht.proto + +package dht_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p-record/pb" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Message_MessageType int32 + +const ( + Message_PUT_VALUE Message_MessageType = 0 + Message_GET_VALUE Message_MessageType = 1 + Message_ADD_PROVIDER Message_MessageType = 2 + Message_GET_PROVIDERS Message_MessageType = 3 + Message_FIND_NODE Message_MessageType = 4 + Message_PING Message_MessageType = 5 +) + +var Message_MessageType_name = map[int32]string{ + 0: "PUT_VALUE", + 1: "GET_VALUE", + 2: "ADD_PROVIDER", + 3: "GET_PROVIDERS", + 4: "FIND_NODE", + 5: "PING", +} + +var Message_MessageType_value = map[string]int32{ + "PUT_VALUE": 0, + "GET_VALUE": 1, + "ADD_PROVIDER": 2, + "GET_PROVIDERS": 3, + "FIND_NODE": 4, + "PING": 5, +} + +func (x Message_MessageType) String() string { + return proto.EnumName(Message_MessageType_name, int32(x)) +} + +func (Message_MessageType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_616a434b24c97ff4, []int{0, 0} +} + +type Message_ConnectionType int32 + +const ( + // sender does not have a connection to peer, and no extra information (default) + Message_NOT_CONNECTED Message_ConnectionType = 0 + // sender has a live connection to peer + Message_CONNECTED Message_ConnectionType = 1 + // sender recently connected to peer + Message_CAN_CONNECT Message_ConnectionType = 2 + // sender recently tried to connect to peer repeatedly but failed to connect + // ("try" here is loose, but this should signal "made strong effort, failed") + Message_CANNOT_CONNECT Message_ConnectionType = 3 +) + +var Message_ConnectionType_name = map[int32]string{ + 0: "NOT_CONNECTED", + 1: "CONNECTED", + 2: "CAN_CONNECT", + 3: "CANNOT_CONNECT", +} + +var Message_ConnectionType_value = map[string]int32{ + "NOT_CONNECTED": 0, + "CONNECTED": 1, + "CAN_CONNECT": 2, + "CANNOT_CONNECT": 3, +} + +func (x Message_ConnectionType) String() string { + return proto.EnumName(Message_ConnectionType_name, int32(x)) +} + +func (Message_ConnectionType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_616a434b24c97ff4, []int{0, 1} +} + +type Message struct { + // defines what type of message it is. + Type Message_MessageType `protobuf:"varint,1,opt,name=type,proto3,enum=dht.pb.Message_MessageType" json:"type,omitempty"` + // defines what coral cluster level this query/response belongs to. + // in case we want to implement coral's cluster rings in the future. + ClusterLevelRaw int32 `protobuf:"varint,10,opt,name=clusterLevelRaw,proto3" json:"clusterLevelRaw,omitempty"` + // Used to specify the key associated with this message. + // PUT_VALUE, GET_VALUE, ADD_PROVIDER, GET_PROVIDERS + Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // Used to return a value + // PUT_VALUE, GET_VALUE + Record *pb.Record `protobuf:"bytes,3,opt,name=record,proto3" json:"record,omitempty"` + // Used to return peers closer to a key in a query + // GET_VALUE, GET_PROVIDERS, FIND_NODE + CloserPeers []*Message_Peer `protobuf:"bytes,8,rep,name=closerPeers,proto3" json:"closerPeers,omitempty"` + // Used to return Providers + // GET_VALUE, ADD_PROVIDER, GET_PROVIDERS + ProviderPeers []*Message_Peer `protobuf:"bytes,9,rep,name=providerPeers,proto3" json:"providerPeers,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_616a434b24c97ff4, []int{0} +} +func (m *Message) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) +} +func (m *Message) XXX_Size() int { + return m.Size() +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetType() Message_MessageType { + if m != nil { + return m.Type + } + return Message_PUT_VALUE +} + +func (m *Message) GetClusterLevelRaw() int32 { + if m != nil { + return m.ClusterLevelRaw + } + return 0 +} + +func (m *Message) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *Message) GetRecord() *pb.Record { + if m != nil { + return m.Record + } + return nil +} + +func (m *Message) GetCloserPeers() []*Message_Peer { + if m != nil { + return m.CloserPeers + } + return nil +} + +func (m *Message) GetProviderPeers() []*Message_Peer { + if m != nil { + return m.ProviderPeers + } + return nil +} + +type Message_Peer struct { + // ID of a given peer. + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // multiaddrs for a given peer + Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs,proto3" json:"addrs,omitempty"` + // used to signal the sender's connection capabilities to the peer + Connection Message_ConnectionType `protobuf:"varint,3,opt,name=connection,proto3,enum=dht.pb.Message_ConnectionType" json:"connection,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message_Peer) Reset() { *m = Message_Peer{} } +func (m *Message_Peer) String() string { return proto.CompactTextString(m) } +func (*Message_Peer) ProtoMessage() {} +func (*Message_Peer) Descriptor() ([]byte, []int) { + return fileDescriptor_616a434b24c97ff4, []int{0, 0} +} +func (m *Message_Peer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message_Peer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message_Peer.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message_Peer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message_Peer.Merge(m, src) +} +func (m *Message_Peer) XXX_Size() int { + return m.Size() +} +func (m *Message_Peer) XXX_DiscardUnknown() { + xxx_messageInfo_Message_Peer.DiscardUnknown(m) +} + +var xxx_messageInfo_Message_Peer proto.InternalMessageInfo + +func (m *Message_Peer) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Message_Peer) GetAddrs() [][]byte { + if m != nil { + return m.Addrs + } + return nil +} + +func (m *Message_Peer) GetConnection() Message_ConnectionType { + if m != nil { + return m.Connection + } + return Message_NOT_CONNECTED +} + +func init() { + proto.RegisterEnum("dht.pb.Message_MessageType", Message_MessageType_name, Message_MessageType_value) + proto.RegisterEnum("dht.pb.Message_ConnectionType", Message_ConnectionType_name, Message_ConnectionType_value) + proto.RegisterType((*Message)(nil), "dht.pb.Message") + proto.RegisterType((*Message_Peer)(nil), "dht.pb.Message.Peer") +} + +func init() { proto.RegisterFile("dht.proto", fileDescriptor_616a434b24c97ff4) } + +var fileDescriptor_616a434b24c97ff4 = []byte{ + // 428 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xc1, 0x6e, 0x9b, 0x40, + 0x10, 0xed, 0x02, 0x76, 0xe3, 0x01, 0x93, 0xcd, 0x28, 0x07, 0x94, 0x4a, 0x16, 0xf2, 0x89, 0x1e, + 0x02, 0x12, 0x95, 0x7a, 0xe8, 0xa1, 0x92, 0x0b, 0x34, 0xb2, 0x94, 0x62, 0x6b, 0xeb, 0xa4, 0x47, + 0xcb, 0xc0, 0xca, 0x41, 0xa5, 0x5e, 0x04, 0x24, 0x95, 0xbf, 0xb0, 0x3d, 0xf6, 0x13, 0x2a, 0x7f, + 0x49, 0x05, 0x84, 0x16, 0xfb, 0xd0, 0xd3, 0xbe, 0x37, 0xf3, 0xde, 0xce, 0xdb, 0xd1, 0xc2, 0x28, + 0x79, 0xa8, 0xec, 0xbc, 0x10, 0x95, 0xc0, 0x61, 0x03, 0xa3, 0x2b, 0x77, 0x9b, 0x56, 0x0f, 0x8f, + 0x91, 0x1d, 0x8b, 0x6f, 0x4e, 0x96, 0x46, 0xb9, 0x9b, 0x3b, 0x5b, 0x71, 0xdd, 0xa2, 0xeb, 0x82, + 0xc7, 0xa2, 0x48, 0x9c, 0x3c, 0x72, 0x5a, 0xd4, 0x7a, 0xa7, 0x3f, 0x14, 0x78, 0xf9, 0x89, 0x97, + 0xe5, 0x66, 0xcb, 0xd1, 0x01, 0xa5, 0xda, 0xe7, 0xdc, 0x20, 0x26, 0xb1, 0x74, 0xf7, 0x95, 0xdd, + 0x5e, 0x6b, 0x3f, 0xb7, 0xbb, 0x73, 0xb5, 0xcf, 0x39, 0x6b, 0x84, 0x68, 0xc1, 0x79, 0x9c, 0x3d, + 0x96, 0x15, 0x2f, 0x6e, 0xf9, 0x13, 0xcf, 0xd8, 0xe6, 0xbb, 0x01, 0x26, 0xb1, 0x06, 0xec, 0xb4, + 0x8c, 0x14, 0xe4, 0xaf, 0x7c, 0x6f, 0x48, 0x26, 0xb1, 0x34, 0x56, 0x43, 0x7c, 0x0d, 0xc3, 0x36, + 0x88, 0x21, 0x9b, 0xc4, 0x52, 0xdd, 0x0b, 0xbb, 0xcb, 0x15, 0xd9, 0xac, 0x41, 0xec, 0x59, 0x80, + 0x6f, 0x41, 0x8d, 0x33, 0x51, 0xf2, 0x62, 0xc9, 0x79, 0x51, 0x1a, 0x67, 0xa6, 0x6c, 0xa9, 0xee, + 0xe5, 0x69, 0xbc, 0xba, 0xc9, 0xfa, 0x42, 0x7c, 0x07, 0xe3, 0xbc, 0x10, 0x4f, 0x69, 0xd2, 0x39, + 0x47, 0xff, 0x71, 0x1e, 0x4b, 0xaf, 0x32, 0x50, 0x6a, 0x80, 0x3a, 0x48, 0x69, 0xd2, 0x6c, 0x44, + 0x63, 0x52, 0x9a, 0xe0, 0x25, 0x0c, 0x36, 0x49, 0x52, 0x94, 0x86, 0x64, 0xca, 0x96, 0xc6, 0x5a, + 0x82, 0xef, 0x01, 0x62, 0xb1, 0xdb, 0xf1, 0xb8, 0x4a, 0xc5, 0xae, 0x79, 0x90, 0xee, 0x4e, 0x4e, + 0xc7, 0x78, 0x7f, 0x15, 0xcd, 0x0a, 0x7b, 0x8e, 0x69, 0x0a, 0x6a, 0x6f, 0xbb, 0x38, 0x86, 0xd1, + 0xf2, 0x6e, 0xb5, 0xbe, 0x9f, 0xdd, 0xde, 0x05, 0xf4, 0x45, 0x4d, 0x6f, 0x82, 0x8e, 0x12, 0xa4, + 0xa0, 0xcd, 0x7c, 0x7f, 0xbd, 0x64, 0x8b, 0xfb, 0xb9, 0x1f, 0x30, 0x2a, 0xe1, 0x05, 0x8c, 0x6b, + 0x41, 0x57, 0xf9, 0x4c, 0xe5, 0xda, 0xf3, 0x71, 0x1e, 0xfa, 0xeb, 0x70, 0xe1, 0x07, 0x54, 0xc1, + 0x33, 0x50, 0x96, 0xf3, 0xf0, 0x86, 0x0e, 0xa6, 0x5f, 0x40, 0x3f, 0x0e, 0x52, 0xbb, 0xc3, 0xc5, + 0x6a, 0xed, 0x2d, 0xc2, 0x30, 0xf0, 0x56, 0x81, 0xdf, 0x4e, 0xfc, 0x47, 0x09, 0x9e, 0x83, 0xea, + 0xcd, 0xc2, 0x4e, 0x41, 0x25, 0x44, 0xd0, 0xbd, 0x59, 0xd8, 0x73, 0x51, 0xf9, 0x83, 0xf6, 0xf3, + 0x30, 0x21, 0xbf, 0x0e, 0x13, 0xf2, 0xfb, 0x30, 0x21, 0xd1, 0xb0, 0xf9, 0x5e, 0x6f, 0xfe, 0x04, + 0x00, 0x00, 0xff, 0xff, 0xf4, 0x3c, 0x3f, 0x3f, 0xa7, 0x02, 0x00, 0x00, +} + +func (m *Message) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintDht(dAtA, i, uint64(m.Type)) + } + if len(m.Key) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintDht(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) + } + if m.Record != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintDht(dAtA, i, uint64(m.Record.Size())) + n1, err := m.Record.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if len(m.CloserPeers) > 0 { + for _, msg := range m.CloserPeers { + dAtA[i] = 0x42 + i++ + i = encodeVarintDht(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.ProviderPeers) > 0 { + for _, msg := range m.ProviderPeers { + dAtA[i] = 0x4a + i++ + i = encodeVarintDht(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.ClusterLevelRaw != 0 { + dAtA[i] = 0x50 + i++ + i = encodeVarintDht(dAtA, i, uint64(m.ClusterLevelRaw)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Message_Peer) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message_Peer) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Id) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintDht(dAtA, i, uint64(len(m.Id))) + i += copy(dAtA[i:], m.Id) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + dAtA[i] = 0x12 + i++ + i = encodeVarintDht(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if m.Connection != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintDht(dAtA, i, uint64(m.Connection)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintDht(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Message) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != 0 { + n += 1 + sovDht(uint64(m.Type)) + } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovDht(uint64(l)) + } + if m.Record != nil { + l = m.Record.Size() + n += 1 + l + sovDht(uint64(l)) + } + if len(m.CloserPeers) > 0 { + for _, e := range m.CloserPeers { + l = e.Size() + n += 1 + l + sovDht(uint64(l)) + } + } + if len(m.ProviderPeers) > 0 { + for _, e := range m.ProviderPeers { + l = e.Size() + n += 1 + l + sovDht(uint64(l)) + } + } + if m.ClusterLevelRaw != 0 { + n += 1 + sovDht(uint64(m.ClusterLevelRaw)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Message_Peer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovDht(uint64(l)) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + l = len(b) + n += 1 + l + sovDht(uint64(l)) + } + } + if m.Connection != 0 { + n += 1 + sovDht(uint64(m.Connection)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovDht(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozDht(x uint64) (n int) { + return sovDht(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Message) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= Message_MessageType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Record", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Record == nil { + m.Record = &pb.Record{} + } + if err := m.Record.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CloserPeers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CloserPeers = append(m.CloserPeers, &Message_Peer{}) + if err := m.CloserPeers[len(m.CloserPeers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderPeers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderPeers = append(m.ProviderPeers, &Message_Peer{}) + if err := m.ProviderPeers[len(m.ProviderPeers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterLevelRaw", wireType) + } + m.ClusterLevelRaw = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ClusterLevelRaw |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDht(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDht + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDht + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message_Peer) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Peer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Peer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDht + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDht + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) + copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Connection", wireType) + } + m.Connection = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDht + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Connection |= Message_ConnectionType(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDht(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDht + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDht + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipDht(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDht + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDht + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDht + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthDht + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthDht + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowDht + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipDht(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthDht + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthDht = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowDht = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.proto b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.proto new file mode 100644 index 00000000..4d2d1fd2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/dht.proto @@ -0,0 +1,71 @@ +// In order to re-generate the golang packages for `Message` you will need... +// 1. Protobuf binary (tested with protoc 3.0.0). - https://github.com/gogo/protobuf/releases +// 2. Gogo Protobuf (tested with gogo 0.3). - https://github.com/gogo/protobuf +// 3. To have cloned `libp2p/go-libp2p-{record,kad-dht}` under the same directory. +// Now from `libp2p/go-libp2p-kad-dht/pb` you can run... +// `protoc --gogo_out=. --proto_path=../../go-libp2p-record/pb/ --proto_path=./ dht.proto` + +syntax = "proto3"; +package dht.pb; + +import "github.com/libp2p/go-libp2p-record/pb/record.proto"; + +message Message { + enum MessageType { + PUT_VALUE = 0; + GET_VALUE = 1; + ADD_PROVIDER = 2; + GET_PROVIDERS = 3; + FIND_NODE = 4; + PING = 5; + } + + enum ConnectionType { + // sender does not have a connection to peer, and no extra information (default) + NOT_CONNECTED = 0; + + // sender has a live connection to peer + CONNECTED = 1; + + // sender recently connected to peer + CAN_CONNECT = 2; + + // sender recently tried to connect to peer repeatedly but failed to connect + // ("try" here is loose, but this should signal "made strong effort, failed") + CANNOT_CONNECT = 3; + } + + message Peer { + // ID of a given peer. + bytes id = 1; + + // multiaddrs for a given peer + repeated bytes addrs = 2; + + // used to signal the sender's connection capabilities to the peer + ConnectionType connection = 3; + } + + // defines what type of message it is. + MessageType type = 1; + + // defines what coral cluster level this query/response belongs to. + // in case we want to implement coral's cluster rings in the future. + int32 clusterLevelRaw = 10; + + // Used to specify the key associated with this message. + // PUT_VALUE, GET_VALUE, ADD_PROVIDER, GET_PROVIDERS + bytes key = 2; + + // Used to return a value + // PUT_VALUE, GET_VALUE + record.pb.Record record = 3; + + // Used to return peers closer to a key in a query + // GET_VALUE, GET_PROVIDERS, FIND_NODE + repeated Peer closerPeers = 8; + + // Used to return Providers + // GET_VALUE, ADD_PROVIDER, GET_PROVIDERS + repeated Peer providerPeers = 9; +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/message.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/message.go new file mode 100644 index 00000000..d8fd2727 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/pb/message.go @@ -0,0 +1,183 @@ +package dht_pb + +import ( + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" + b58 "github.com/mr-tron/base58/base58" + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("dht.pb") + +type PeerRoutingInfo struct { + peer.AddrInfo + network.Connectedness +} + +// NewMessage constructs a new dht message with given type, key, and level +func NewMessage(typ Message_MessageType, key []byte, level int) *Message { + m := &Message{ + Type: typ, + Key: key, + } + m.SetClusterLevel(level) + return m +} + +func peerRoutingInfoToPBPeer(p PeerRoutingInfo) *Message_Peer { + pbp := new(Message_Peer) + + pbp.Addrs = make([][]byte, len(p.Addrs)) + for i, maddr := range p.Addrs { + pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed. + } + s := string(p.ID) + pbp.Id = []byte(s) + c := ConnectionType(p.Connectedness) + pbp.Connection = c + return pbp +} + +func peerInfoToPBPeer(p peer.AddrInfo) *Message_Peer { + pbp := new(Message_Peer) + + pbp.Addrs = make([][]byte, len(p.Addrs)) + for i, maddr := range p.Addrs { + pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed. + } + pbp.Id = []byte(p.ID) + return pbp +} + +// PBPeerToPeer turns a *Message_Peer into its peer.AddrInfo counterpart +func PBPeerToPeerInfo(pbp *Message_Peer) *peer.AddrInfo { + return &peer.AddrInfo{ + ID: peer.ID(pbp.GetId()), + Addrs: pbp.Addresses(), + } +} + +// RawPeerInfosToPBPeers converts a slice of Peers into a slice of *Message_Peers, +// ready to go out on the wire. +func RawPeerInfosToPBPeers(peers []peer.AddrInfo) []*Message_Peer { + pbpeers := make([]*Message_Peer, len(peers)) + for i, p := range peers { + pbpeers[i] = peerInfoToPBPeer(p) + } + return pbpeers +} + +// PeersToPBPeers converts given []peer.Peer into a set of []*Message_Peer, +// which can be written to a message and sent out. the key thing this function +// does (in addition to PeersToPBPeers) is set the ConnectionType with +// information from the given network.Network. +func PeerInfosToPBPeers(n network.Network, peers []peer.AddrInfo) []*Message_Peer { + pbps := RawPeerInfosToPBPeers(peers) + for i, pbp := range pbps { + c := ConnectionType(n.Connectedness(peers[i].ID)) + pbp.Connection = c + } + return pbps +} + +func PeerRoutingInfosToPBPeers(peers []PeerRoutingInfo) []*Message_Peer { + pbpeers := make([]*Message_Peer, len(peers)) + for i, p := range peers { + pbpeers[i] = peerRoutingInfoToPBPeer(p) + } + return pbpeers +} + +// PBPeersToPeerInfos converts given []*Message_Peer into []peer.AddrInfo +// Invalid addresses will be silently omitted. +func PBPeersToPeerInfos(pbps []*Message_Peer) []*peer.AddrInfo { + peers := make([]*peer.AddrInfo, 0, len(pbps)) + for _, pbp := range pbps { + peers = append(peers, PBPeerToPeerInfo(pbp)) + } + return peers +} + +// Addresses returns a multiaddr associated with the Message_Peer entry +func (m *Message_Peer) Addresses() []ma.Multiaddr { + if m == nil { + return nil + } + + maddrs := make([]ma.Multiaddr, 0, len(m.Addrs)) + for _, addr := range m.Addrs { + maddr, err := ma.NewMultiaddrBytes(addr) + if err != nil { + log.Warningf("error decoding Multiaddr for peer: %s", m.GetId()) + continue + } + + maddrs = append(maddrs, maddr) + } + return maddrs +} + +// GetClusterLevel gets and adjusts the cluster level on the message. +// a +/- 1 adjustment is needed to distinguish a valid first level (1) and +// default "no value" protobuf behavior (0) +func (m *Message) GetClusterLevel() int { + level := m.GetClusterLevelRaw() - 1 + if level < 0 { + return 0 + } + return int(level) +} + +// SetClusterLevel adjusts and sets the cluster level on the message. +// a +/- 1 adjustment is needed to distinguish a valid first level (1) and +// default "no value" protobuf behavior (0) +func (m *Message) SetClusterLevel(level int) { + lvl := int32(level) + m.ClusterLevelRaw = lvl +} + +// Loggable turns a Message into machine-readable log output +func (m *Message) Loggable() map[string]interface{} { + return map[string]interface{}{ + "message": map[string]string{ + "type": m.Type.String(), + "key": b58.Encode([]byte(m.GetKey())), + }, + } +} + +// ConnectionType returns a Message_ConnectionType associated with the +// network.Connectedness. +func ConnectionType(c network.Connectedness) Message_ConnectionType { + switch c { + default: + return Message_NOT_CONNECTED + case network.NotConnected: + return Message_NOT_CONNECTED + case network.Connected: + return Message_CONNECTED + case network.CanConnect: + return Message_CAN_CONNECT + case network.CannotConnect: + return Message_CANNOT_CONNECT + } +} + +// Connectedness returns an network.Connectedness associated with the +// Message_ConnectionType. +func Connectedness(c Message_ConnectionType) network.Connectedness { + switch c { + default: + return network.NotConnected + case Message_NOT_CONNECTED: + return network.NotConnected + case Message_CONNECTED: + return network.Connected + case Message_CAN_CONNECT: + return network.CanConnect + case Message_CANNOT_CONNECT: + return network.CannotConnect + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/providers/providers.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/providers/providers.go new file mode 100644 index 00000000..ec44cc51 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/providers/providers.go @@ -0,0 +1,351 @@ +package providers + +import ( + "context" + "encoding/binary" + "fmt" + "strings" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + + lru "github.com/hashicorp/golang-lru/simplelru" + cid "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + autobatch "github.com/ipfs/go-datastore/autobatch" + dsq "github.com/ipfs/go-datastore/query" + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" + goprocessctx "github.com/jbenet/goprocess/context" + base32 "github.com/whyrusleeping/base32" +) + +var batchBufferSize = 256 + +var log = logging.Logger("providers") + +var lruCacheSize = 256 +var ProvideValidity = time.Hour * 24 +var defaultCleanupInterval = time.Hour + +type ProviderManager struct { + // all non channel fields are meant to be accessed only within + // the run method + providers *lru.LRU + dstore *autobatch.Datastore + + newprovs chan *addProv + getprovs chan *getProv + proc goprocess.Process + + cleanupInterval time.Duration +} + +type providerSet struct { + providers []peer.ID + set map[peer.ID]time.Time +} + +type addProv struct { + k cid.Cid + val peer.ID +} + +type getProv struct { + k cid.Cid + resp chan []peer.ID +} + +func NewProviderManager(ctx context.Context, local peer.ID, dstore ds.Batching) *ProviderManager { + pm := new(ProviderManager) + pm.getprovs = make(chan *getProv) + pm.newprovs = make(chan *addProv) + pm.dstore = autobatch.NewAutoBatching(dstore, batchBufferSize) + cache, err := lru.NewLRU(lruCacheSize, nil) + if err != nil { + panic(err) //only happens if negative value is passed to lru constructor + } + pm.providers = cache + + pm.proc = goprocessctx.WithContext(ctx) + pm.cleanupInterval = defaultCleanupInterval + pm.proc.Go(pm.run) + + return pm +} + +const providersKeyPrefix = "/providers/" + +func mkProvKey(k cid.Cid) string { + return providersKeyPrefix + base32.RawStdEncoding.EncodeToString(k.Bytes()) +} + +func (pm *ProviderManager) Process() goprocess.Process { + return pm.proc +} + +func (pm *ProviderManager) providersForKey(k cid.Cid) ([]peer.ID, error) { + pset, err := pm.getProvSet(k) + if err != nil { + return nil, err + } + return pset.providers, nil +} + +func (pm *ProviderManager) getProvSet(k cid.Cid) (*providerSet, error) { + cached, ok := pm.providers.Get(k) + if ok { + return cached.(*providerSet), nil + } + + pset, err := loadProvSet(pm.dstore, k) + if err != nil { + return nil, err + } + + if len(pset.providers) > 0 { + pm.providers.Add(k, pset) + } + + return pset, nil +} + +func loadProvSet(dstore ds.Datastore, k cid.Cid) (*providerSet, error) { + res, err := dstore.Query(dsq.Query{Prefix: mkProvKey(k)}) + if err != nil { + return nil, err + } + defer res.Close() + + now := time.Now() + out := newProviderSet() + for { + e, ok := res.NextSync() + if !ok { + break + } + if e.Error != nil { + log.Error("got an error: ", e.Error) + continue + } + + // check expiration time + t, err := readTimeValue(e.Value) + switch { + case err != nil: + // couldn't parse the time + log.Warning("parsing providers record from disk: ", err) + fallthrough + case now.Sub(t) > ProvideValidity: + // or just expired + err = dstore.Delete(ds.RawKey(e.Key)) + if err != nil && err != ds.ErrNotFound { + log.Warning("failed to remove provider record from disk: ", err) + } + continue + } + + lix := strings.LastIndex(e.Key, "/") + + decstr, err := base32.RawStdEncoding.DecodeString(e.Key[lix+1:]) + if err != nil { + log.Error("base32 decoding error: ", err) + err = dstore.Delete(ds.RawKey(e.Key)) + if err != nil && err != ds.ErrNotFound { + log.Warning("failed to remove provider record from disk: ", err) + } + continue + } + + pid := peer.ID(decstr) + + out.setVal(pid, t) + } + + return out, nil +} + +func readTimeValue(data []byte) (time.Time, error) { + nsec, n := binary.Varint(data) + if n <= 0 { + return time.Time{}, fmt.Errorf("failed to parse time") + } + + return time.Unix(0, nsec), nil +} + +func (pm *ProviderManager) addProv(k cid.Cid, p peer.ID) error { + now := time.Now() + if provs, ok := pm.providers.Get(k); ok { + provs.(*providerSet).setVal(p, now) + } // else not cached, just write through + + return writeProviderEntry(pm.dstore, k, p, now) +} + +func mkProvKeyFor(k cid.Cid, p peer.ID) string { + return mkProvKey(k) + "/" + base32.RawStdEncoding.EncodeToString([]byte(p)) +} + +func writeProviderEntry(dstore ds.Datastore, k cid.Cid, p peer.ID, t time.Time) error { + dsk := mkProvKeyFor(k, p) + + buf := make([]byte, 16) + n := binary.PutVarint(buf, t.UnixNano()) + + return dstore.Put(ds.NewKey(dsk), buf[:n]) +} + +func (pm *ProviderManager) run(proc goprocess.Process) { + var ( + gcQuery dsq.Results + gcQueryRes <-chan dsq.Result + gcSkip map[string]struct{} + gcTime time.Time + gcTimer = time.NewTimer(pm.cleanupInterval) + ) + + defer func() { + gcTimer.Stop() + if gcQuery != nil { + // don't really care if this fails. + _ = gcQuery.Close() + } + if err := pm.dstore.Flush(); err != nil { + log.Error("failed to flush datastore: ", err) + } + }() + + for { + select { + case np := <-pm.newprovs: + err := pm.addProv(np.k, np.val) + if err != nil { + log.Error("error adding new providers: ", err) + continue + } + if gcSkip != nil { + // we have an gc, tell it to skip this provider + // as we've updated it since the GC started. + gcSkip[mkProvKeyFor(np.k, np.val)] = struct{}{} + } + case gp := <-pm.getprovs: + provs, err := pm.providersForKey(gp.k) + if err != nil && err != ds.ErrNotFound { + log.Error("error reading providers: ", err) + } + + // set the cap so the user can't append to this. + gp.resp <- provs[0:len(provs):len(provs)] + case res, ok := <-gcQueryRes: + if !ok { + if err := gcQuery.Close(); err != nil { + log.Error("failed to close provider GC query: ", err) + } + gcTimer.Reset(pm.cleanupInterval) + + // cleanup GC round + gcQueryRes = nil + gcSkip = nil + gcQuery = nil + continue + } + if res.Error != nil { + log.Error("got error from GC query: ", res.Error) + continue + } + if _, ok := gcSkip[res.Key]; ok { + // We've updated this record since starting the + // GC round, skip it. + continue + } + + // check expiration time + t, err := readTimeValue(res.Value) + switch { + case err != nil: + // couldn't parse the time + log.Warning("parsing providers record from disk: ", err) + fallthrough + case gcTime.Sub(t) > ProvideValidity: + // or expired + err = pm.dstore.Delete(ds.RawKey(res.Key)) + if err != nil && err != ds.ErrNotFound { + log.Warning("failed to remove provider record from disk: ", err) + } + } + + case gcTime = <-gcTimer.C: + // You know the wonderful thing about caches? You can + // drop them. + // + // Much faster than GCing. + pm.providers.Purge() + + // Now, kick off a GC of the datastore. + q, err := pm.dstore.Query(dsq.Query{ + Prefix: providersKeyPrefix, + }) + if err != nil { + log.Error("provider record GC query failed: ", err) + continue + } + gcQuery = q + gcQueryRes = q.Next() + gcSkip = make(map[string]struct{}) + case <-proc.Closing(): + return + } + } +} + +// AddProvider adds a provider. +func (pm *ProviderManager) AddProvider(ctx context.Context, k cid.Cid, val peer.ID) { + prov := &addProv{ + k: k, + val: val, + } + select { + case pm.newprovs <- prov: + case <-ctx.Done(): + } +} + +// GetProviders returns the set of providers for the given key. +// This method _does not_ copy the set. Do not modify it. +func (pm *ProviderManager) GetProviders(ctx context.Context, k cid.Cid) []peer.ID { + gp := &getProv{ + k: k, + resp: make(chan []peer.ID, 1), // buffered to prevent sender from blocking + } + select { + case <-ctx.Done(): + return nil + case pm.getprovs <- gp: + } + select { + case <-ctx.Done(): + return nil + case peers := <-gp.resp: + return peers + } +} + +func newProviderSet() *providerSet { + return &providerSet{ + set: make(map[peer.ID]time.Time), + } +} + +func (ps *providerSet) Add(p peer.ID) { + ps.setVal(p, time.Now()) +} + +func (ps *providerSet) setVal(p peer.ID, t time.Time) { + _, found := ps.set[p] + if !found { + ps.providers = append(ps.providers, p) + } + + ps.set[p] = t +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/query.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/query.go new file mode 100644 index 00000000..c0211a56 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/query.go @@ -0,0 +1,315 @@ +package dht + +import ( + "context" + "errors" + "sync" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" + todoctr "github.com/ipfs/go-todocounter" + process "github.com/jbenet/goprocess" + ctxproc "github.com/jbenet/goprocess/context" + kb "github.com/libp2p/go-libp2p-kbucket" + + pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/routing" + queue "github.com/libp2p/go-libp2p-peerstore/queue" + notif "github.com/libp2p/go-libp2p-routing/notifications" +) + +// ErrNoPeersQueried is returned when we failed to connect to any peers. +var ErrNoPeersQueried = errors.New("failed to query any peers") + +var maxQueryConcurrency = AlphaValue + +type dhtQuery struct { + dht *IpfsDHT + key string // the key we're querying for + qfunc queryFunc // the function to execute per peer + concurrency int // the concurrency parameter +} + +type dhtQueryResult struct { + peer *peer.AddrInfo // FindPeer + closerPeers []*peer.AddrInfo // * + success bool + + finalSet *peer.Set + queriedSet *peer.Set +} + +// constructs query +func (dht *IpfsDHT) newQuery(k string, f queryFunc) *dhtQuery { + return &dhtQuery{ + key: k, + dht: dht, + qfunc: f, + concurrency: maxQueryConcurrency, + } +} + +// QueryFunc is a function that runs a particular query with a given peer. +// It returns either: +// - the value +// - a list of peers potentially better able to serve the query +// - an error +type queryFunc func(context.Context, peer.ID) (*dhtQueryResult, error) + +// Run runs the query at hand. pass in a list of peers to use first. +func (q *dhtQuery) Run(ctx context.Context, peers []peer.ID) (*dhtQueryResult, error) { + if len(peers) == 0 { + logger.Warning("Running query with no peers!") + return nil, kb.ErrLookupFailure + } + + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + runner := newQueryRunner(q) + return runner.Run(ctx, peers) +} + +type dhtQueryRunner struct { + query *dhtQuery // query to run + peersSeen *peer.Set // all peers queried. prevent querying same peer 2x + peersQueried *peer.Set // peers successfully connected to and queried + peersDialed *dialQueue // peers we have dialed to + peersToQuery *queue.ChanQueue // peers remaining to be queried + peersRemaining todoctr.Counter // peersToQuery + currently processing + + result *dhtQueryResult // query result + + rateLimit chan struct{} // processing semaphore + log logging.EventLogger + + runCtx context.Context + + proc process.Process + sync.RWMutex +} + +func newQueryRunner(q *dhtQuery) *dhtQueryRunner { + proc := process.WithParent(process.Background()) + ctx := ctxproc.OnClosingContext(proc) + peersToQuery := queue.NewChanQueue(ctx, queue.NewXORDistancePQ(string(q.key))) + r := &dhtQueryRunner{ + query: q, + peersRemaining: todoctr.NewSyncCounter(), + peersSeen: peer.NewSet(), + peersQueried: peer.NewSet(), + rateLimit: make(chan struct{}, q.concurrency), + peersToQuery: peersToQuery, + proc: proc, + } + dq, err := newDialQueue(&dqParams{ + ctx: ctx, + target: q.key, + in: peersToQuery, + dialFn: r.dialPeer, + config: dqDefaultConfig(), + }) + if err != nil { + panic(err) + } + r.peersDialed = dq + return r +} + +func (r *dhtQueryRunner) Run(ctx context.Context, peers []peer.ID) (*dhtQueryResult, error) { + r.log = logger + r.runCtx = ctx + + // setup concurrency rate limiting + for i := 0; i < r.query.concurrency; i++ { + r.rateLimit <- struct{}{} + } + + // add all the peers we got first. + for _, p := range peers { + r.addPeerToQuery(p) + } + + // start the dial queue only after we've added the initial set of peers. + // this is to avoid race conditions that could cause the peersRemaining todoctr + // to be done too early if the initial dial fails before others make it into the queue. + r.peersDialed.Start() + + // go do this thing. + // do it as a child proc to make sure Run exits + // ONLY AFTER spawn workers has exited. + r.proc.Go(r.spawnWorkers) + + // wait until they're done. + var err error + + // now, if the context finishes, close the proc. + // we have to do it here because the logic before is setup, which + // should run without closing the proc. + ctxproc.CloseAfterContext(r.proc, ctx) + + select { + case <-r.peersRemaining.Done(): + r.proc.Close() + if r.peersQueried.Size() == 0 { + err = ErrNoPeersQueried + } else { + err = routing.ErrNotFound + } + + case <-r.proc.Closed(): + err = r.runCtx.Err() + } + + r.RLock() + defer r.RUnlock() + + if r.result != nil && r.result.success { + return r.result, nil + } + + return &dhtQueryResult{ + finalSet: r.peersSeen, + queriedSet: r.peersQueried, + }, err +} + +func (r *dhtQueryRunner) addPeerToQuery(next peer.ID) { + // if new peer is ourselves... + if next == r.query.dht.self { + r.log.Debug("addPeerToQuery skip self") + return + } + + if !r.peersSeen.TryAdd(next) { + return + } + + notif.PublishQueryEvent(r.runCtx, ¬if.QueryEvent{ + Type: notif.AddingPeer, + ID: next, + }) + + r.peersRemaining.Increment(1) + select { + case r.peersToQuery.EnqChan <- next: + case <-r.proc.Closing(): + } +} + +func (r *dhtQueryRunner) spawnWorkers(proc process.Process) { + for { + select { + case <-r.peersRemaining.Done(): + return + + case <-r.proc.Closing(): + return + + case <-r.rateLimit: + ch := r.peersDialed.Consume() + select { + case p, ok := <-ch: + if !ok { + // this signals context cancellation. + return + } + // do it as a child func to make sure Run exits + // ONLY AFTER spawn workers has exited. + proc.Go(func(proc process.Process) { + r.queryPeer(proc, p) + }) + case <-r.proc.Closing(): + return + case <-r.peersRemaining.Done(): + return + } + } + } +} + +func (r *dhtQueryRunner) dialPeer(ctx context.Context, p peer.ID) error { + // short-circuit if we're already connected. + if r.query.dht.host.Network().Connectedness(p) == network.Connected { + return nil + } + + logger.Debug("not connected. dialing.") + notif.PublishQueryEvent(r.runCtx, ¬if.QueryEvent{ + Type: notif.DialingPeer, + ID: p, + }) + + pi := peer.AddrInfo{ID: p} + if err := r.query.dht.host.Connect(ctx, pi); err != nil { + logger.Debugf("error connecting: %s", err) + notif.PublishQueryEvent(r.runCtx, ¬if.QueryEvent{ + Type: notif.QueryError, + Extra: err.Error(), + ID: p, + }) + + // This peer is dropping out of the race. + r.peersRemaining.Decrement(1) + return err + } + logger.Debugf("connected. dial success.") + return nil +} + +func (r *dhtQueryRunner) queryPeer(proc process.Process, p peer.ID) { + // ok let's do this! + + // create a context from our proc. + ctx := ctxproc.OnClosingContext(proc) + + // make sure we do this when we exit + defer func() { + // signal we're done processing peer p + r.peersRemaining.Decrement(1) + r.rateLimit <- struct{}{} + }() + + // finally, run the query against this peer + res, err := r.query.qfunc(ctx, p) + + r.peersQueried.Add(p) + + if err != nil { + logger.Debugf("ERROR worker for: %v %v", p, err) + } else if res.success { + logger.Debugf("SUCCESS worker for: %v %s", p, res) + r.Lock() + r.result = res + r.Unlock() + if res.peer != nil { + r.query.dht.peerstore.AddAddrs(res.peer.ID, res.peer.Addrs, pstore.TempAddrTTL) + } + go r.proc.Close() // signal to everyone that we're done. + // must be async, as we're one of the children, and Close blocks. + + } else if len(res.closerPeers) > 0 { + logger.Debugf("PEERS CLOSER -- worker for: %v (%d closer peers)", p, len(res.closerPeers)) + for _, next := range res.closerPeers { + if next.ID == r.query.dht.self { // don't add self. + logger.Debugf("PEERS CLOSER -- worker for: %v found self", p) + continue + } + + // add their addresses to the dialer's peerstore + r.query.dht.peerstore.AddAddrs(next.ID, next.Addrs, pstore.TempAddrTTL) + r.addPeerToQuery(next.ID) + logger.Debugf("PEERS CLOSER -- worker for: %v added %v (%v)", p, next.ID, next.Addrs) + } + } else { + logger.Debugf("QUERY worker for: %v - not found, and no closer peers.", p) + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/records.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/records.go new file mode 100644 index 00000000..5f641b05 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/records.go @@ -0,0 +1,137 @@ +package dht + +import ( + "context" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + ci "github.com/libp2p/go-libp2p-core/crypto" +) + +// MaxRecordAge specifies the maximum time that any node will hold onto a record +// from the time its received. This does not apply to any other forms of validity that +// the record may contain. +// For example, a record may contain an ipns entry with an EOL saying its valid +// until the year 2020 (a great time in the future). For that record to stick around +// it must be rebroadcasted more frequently than once every 'MaxRecordAge' +const MaxRecordAge = time.Hour * 36 + +type pubkrs struct { + pubk ci.PubKey + err error +} + +func (dht *IpfsDHT) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) { + logger.Debugf("getPublicKey for: %s", p) + + // Check locally. Will also try to extract the public key from the peer + // ID itself if possible (if inlined). + pk := dht.peerstore.PubKey(p) + if pk != nil { + return pk, nil + } + + // Try getting the public key both directly from the node it identifies + // and from the DHT, in parallel + ctx, cancel := context.WithCancel(ctx) + defer cancel() + resp := make(chan pubkrs, 2) + go func() { + pubk, err := dht.getPublicKeyFromNode(ctx, p) + resp <- pubkrs{pubk, err} + }() + + // Note that the number of open connections is capped by the dial + // limiter, so there is a chance that getPublicKeyFromDHT(), which + // potentially opens a lot of connections, will block + // getPublicKeyFromNode() from getting a connection. + // Currently this doesn't seem to cause an issue so leaving as is + // for now. + go func() { + pubk, err := dht.getPublicKeyFromDHT(ctx, p) + resp <- pubkrs{pubk, err} + }() + + // Wait for one of the two go routines to return + // a public key (or for both to error out) + var err error + for i := 0; i < 2; i++ { + r := <-resp + if r.err == nil { + // Found the public key + err := dht.peerstore.AddPubKey(p, r.pubk) + if err != nil { + logger.Warningf("Failed to add public key to peerstore for %v", p) + } + return r.pubk, nil + } + err = r.err + } + + // Both go routines failed to find a public key + return nil, err +} + +func (dht *IpfsDHT) getPublicKeyFromDHT(ctx context.Context, p peer.ID) (ci.PubKey, error) { + // Only retrieve one value, because the public key is immutable + // so there's no need to retrieve multiple versions + pkkey := routing.KeyForPublicKey(p) + val, err := dht.GetValue(ctx, pkkey, Quorum(1)) + if err != nil { + return nil, err + } + + pubk, err := ci.UnmarshalPublicKey(val) + if err != nil { + logger.Errorf("Could not unmarshall public key retrieved from DHT for %v", p) + return nil, err + } + + // Note: No need to check that public key hash matches peer ID + // because this is done by GetValues() + logger.Debugf("Got public key for %s from DHT", p) + return pubk, nil +} + +func (dht *IpfsDHT) getPublicKeyFromNode(ctx context.Context, p peer.ID) (ci.PubKey, error) { + // check locally, just in case... + pk := dht.peerstore.PubKey(p) + if pk != nil { + return pk, nil + } + + // Get the key from the node itself + pkkey := routing.KeyForPublicKey(p) + pmes, err := dht.getValueSingle(ctx, p, pkkey) + if err != nil { + return nil, err + } + + // node doesn't have key :( + record := pmes.GetRecord() + if record == nil { + return nil, fmt.Errorf("node %v not responding with its public key", p) + } + + pubk, err := ci.UnmarshalPublicKey(record.GetValue()) + if err != nil { + logger.Errorf("Could not unmarshall public key for %v", p) + return nil, err + } + + // Make sure the public key matches the peer ID + id, err := peer.IDFromPublicKey(pubk) + if err != nil { + logger.Errorf("Could not extract peer id from public key for %v", p) + return nil, err + } + if id != p { + return nil, fmt.Errorf("public key %v does not match peer %v", id, p) + } + + logger.Debugf("Got public key from node %v itself", p) + return pubk, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/routing.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/routing.go new file mode 100644 index 00000000..9050ef51 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/routing.go @@ -0,0 +1,717 @@ +package dht + +import ( + "bytes" + "context" + "fmt" + "runtime" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/routing" + + cid "github.com/ipfs/go-cid" + u "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" + pb "github.com/libp2p/go-libp2p-kad-dht/pb" + kb "github.com/libp2p/go-libp2p-kbucket" + record "github.com/libp2p/go-libp2p-record" +) + +// asyncQueryBuffer is the size of buffered channels in async queries. This +// buffer allows multiple queries to execute simultaneously, return their +// results and continue querying closer peers. Note that different query +// results will wait for the channel to drain. +var asyncQueryBuffer = 10 + +// This file implements the Routing interface for the IpfsDHT struct. + +// Basic Put/Get + +// PutValue adds value corresponding to given Key. +// This is the top level "Store" operation of the DHT +func (dht *IpfsDHT) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) (err error) { + eip := logger.EventBegin(ctx, "PutValue") + defer func() { + eip.Append(loggableKey(key)) + if err != nil { + eip.SetError(err) + } + eip.Done() + }() + logger.Debugf("PutValue %s", key) + + // don't even allow local users to put bad values. + if err := dht.Validator.Validate(key, value); err != nil { + return err + } + + old, err := dht.getLocal(key) + if err != nil { + // Means something is wrong with the datastore. + return err + } + + // Check if we have an old value that's not the same as the new one. + if old != nil && !bytes.Equal(old.GetValue(), value) { + // Check to see if the new one is better. + i, err := dht.Validator.Select(key, [][]byte{value, old.GetValue()}) + if err != nil { + return err + } + if i != 0 { + return fmt.Errorf("can't replace a newer value with an older value") + } + } + + rec := record.MakePutRecord(key, value) + rec.TimeReceived = u.FormatRFC3339(time.Now()) + err = dht.putLocal(key, rec) + if err != nil { + return err + } + + pchan, err := dht.GetClosestPeers(ctx, key) + if err != nil { + return err + } + + wg := sync.WaitGroup{} + for p := range pchan { + wg.Add(1) + go func(p peer.ID) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + defer wg.Done() + routing.PublishQueryEvent(ctx, &routing.QueryEvent{ + Type: routing.Value, + ID: p, + }) + + err := dht.putValueToPeer(ctx, p, rec) + if err != nil { + logger.Debugf("failed putting value to peer: %s", err) + } + }(p) + } + wg.Wait() + return nil +} + +// RecvdVal stores a value and the peer from which we got the value. +type RecvdVal struct { + Val []byte + From peer.ID +} + +// GetValue searches for the value corresponding to given Key. +func (dht *IpfsDHT) GetValue(ctx context.Context, key string, opts ...routing.Option) (_ []byte, err error) { + eip := logger.EventBegin(ctx, "GetValue") + defer func() { + eip.Append(loggableKey(key)) + if err != nil { + eip.SetError(err) + } + eip.Done() + }() + + // apply defaultQuorum if relevant + var cfg routing.Options + if err := cfg.Apply(opts...); err != nil { + return nil, err + } + opts = append(opts, Quorum(getQuorum(&cfg, defaultQuorum))) + + responses, err := dht.SearchValue(ctx, key, opts...) + if err != nil { + return nil, err + } + var best []byte + + for r := range responses { + best = r + } + + if ctx.Err() != nil { + return best, ctx.Err() + } + + if best == nil { + return nil, routing.ErrNotFound + } + logger.Debugf("GetValue %v %v", key, best) + return best, nil +} + +func (dht *IpfsDHT) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + var cfg routing.Options + if err := cfg.Apply(opts...); err != nil { + return nil, err + } + + responsesNeeded := 0 + if !cfg.Offline { + responsesNeeded = getQuorum(&cfg, -1) + } + + valCh, err := dht.getValues(ctx, key, responsesNeeded) + if err != nil { + return nil, err + } + + out := make(chan []byte) + go func() { + defer close(out) + + maxVals := responsesNeeded + if maxVals < 0 { + maxVals = defaultQuorum * 4 // we want some upper bound on how + // much correctional entries we will send + } + + // vals is used collect entries we got so far and send corrections to peers + // when we exit this function + vals := make([]RecvdVal, 0, maxVals) + var best *RecvdVal + + defer func() { + if len(vals) <= 1 || best == nil { + return + } + fixupRec := record.MakePutRecord(key, best.Val) + for _, v := range vals { + // if someone sent us a different 'less-valid' record, lets correct them + if !bytes.Equal(v.Val, best.Val) { + go func(v RecvdVal) { + if v.From == dht.self { + err := dht.putLocal(key, fixupRec) + if err != nil { + logger.Error("Error correcting local dht entry:", err) + } + return + } + ctx, cancel := context.WithTimeout(dht.Context(), time.Second*30) + defer cancel() + err := dht.putValueToPeer(ctx, v.From, fixupRec) + if err != nil { + logger.Debug("Error correcting DHT entry: ", err) + } + }(v) + } + } + }() + + for { + select { + case v, ok := <-valCh: + if !ok { + return + } + + if len(vals) < maxVals { + vals = append(vals, v) + } + + if v.Val == nil { + continue + } + // Select best value + if best != nil { + if bytes.Equal(best.Val, v.Val) { + continue + } + sel, err := dht.Validator.Select(key, [][]byte{best.Val, v.Val}) + if err != nil { + logger.Warning("Failed to select dht key: ", err) + continue + } + if sel != 1 { + continue + } + } + best = &v + select { + case out <- v.Val: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + + return out, nil +} + +// GetValues gets nvals values corresponding to the given key. +func (dht *IpfsDHT) GetValues(ctx context.Context, key string, nvals int) (_ []RecvdVal, err error) { + eip := logger.EventBegin(ctx, "GetValues") + + eip.Append(loggableKey(key)) + defer eip.Done() + + valCh, err := dht.getValues(ctx, key, nvals) + if err != nil { + eip.SetError(err) + return nil, err + } + + out := make([]RecvdVal, 0, nvals) + for val := range valCh { + out = append(out, val) + } + + return out, ctx.Err() +} + +func (dht *IpfsDHT) getValues(ctx context.Context, key string, nvals int) (<-chan RecvdVal, error) { + vals := make(chan RecvdVal, 1) + + done := func(err error) (<-chan RecvdVal, error) { + defer close(vals) + return vals, err + } + + // If we have it local, don't bother doing an RPC! + lrec, err := dht.getLocal(key) + if err != nil { + // something is wrong with the datastore. + return done(err) + } + if lrec != nil { + // TODO: this is tricky, we don't always want to trust our own value + // what if the authoritative source updated it? + logger.Debug("have it locally") + vals <- RecvdVal{ + Val: lrec.GetValue(), + From: dht.self, + } + + if nvals == 0 || nvals == 1 { + return done(nil) + } + + nvals-- + } else if nvals == 0 { + return done(routing.ErrNotFound) + } + + // get closest peers in the routing table + rtp := dht.routingTable.NearestPeers(kb.ConvertKey(key), AlphaValue) + logger.Debugf("peers in rt: %d %s", len(rtp), rtp) + if len(rtp) == 0 { + logger.Warning("No peers from routing table!") + return done(kb.ErrLookupFailure) + } + + var valslock sync.Mutex + var got int + + // setup the Query + parent := ctx + query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) { + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.SendingQuery, + ID: p, + }) + + rec, peers, err := dht.getValueOrPeers(ctx, p, key) + switch err { + case routing.ErrNotFound: + // in this case, they responded with nothing, + // still send a notification so listeners can know the + // request has completed 'successfully' + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.PeerResponse, + ID: p, + }) + return nil, err + default: + return nil, err + + case nil, errInvalidRecord: + // in either of these cases, we want to keep going + } + + res := &dhtQueryResult{closerPeers: peers} + + if rec.GetValue() != nil || err == errInvalidRecord { + rv := RecvdVal{ + Val: rec.GetValue(), + From: p, + } + valslock.Lock() + select { + case vals <- rv: + case <-ctx.Done(): + valslock.Unlock() + return nil, ctx.Err() + } + got++ + + // If we have collected enough records, we're done + if nvals == got { + res.success = true + } + valslock.Unlock() + } + + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.PeerResponse, + ID: p, + Responses: peers, + }) + + return res, nil + }) + + go func() { + reqCtx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + + _, err = query.Run(reqCtx, rtp) + + // We do have some values but we either ran out of peers to query or + // searched for a whole minute. + // + // We'll just call this a success. + if got > 0 && (err == routing.ErrNotFound || reqCtx.Err() == context.DeadlineExceeded) { + err = nil + } + done(err) + }() + + return vals, nil +} + +// Provider abstraction for indirect stores. +// Some DHTs store values directly, while an indirect store stores pointers to +// locations of the value, similarly to Coral and Mainline DHT. + +// Provide makes this node announce that it can provide a value for the given key +func (dht *IpfsDHT) Provide(ctx context.Context, key cid.Cid, brdcst bool) (err error) { + eip := logger.EventBegin(ctx, "Provide", key, logging.LoggableMap{"broadcast": brdcst}) + defer func() { + if err != nil { + eip.SetError(err) + } + eip.Done() + }() + + // add self locally + dht.providers.AddProvider(ctx, key, dht.self) + if !brdcst { + return nil + } + + peers, err := dht.GetClosestPeers(ctx, key.KeyString()) + if err != nil { + return err + } + + mes, err := dht.makeProvRecord(key) + if err != nil { + return err + } + + wg := sync.WaitGroup{} + for p := range peers { + wg.Add(1) + go func(p peer.ID) { + defer wg.Done() + logger.Debugf("putProvider(%s, %s)", key, p) + err := dht.sendMessage(ctx, p, mes) + if err != nil { + logger.Debug(err) + } + }(p) + } + wg.Wait() + return nil +} +func (dht *IpfsDHT) makeProvRecord(skey cid.Cid) (*pb.Message, error) { + pi := peer.AddrInfo{ + ID: dht.self, + Addrs: dht.host.Addrs(), + } + + // // only share WAN-friendly addresses ?? + // pi.Addrs = addrutil.WANShareableAddrs(pi.Addrs) + if len(pi.Addrs) < 1 { + return nil, fmt.Errorf("no known addresses for self. cannot put provider.") + } + + pmes := pb.NewMessage(pb.Message_ADD_PROVIDER, skey.Bytes(), 0) + pmes.ProviderPeers = pb.RawPeerInfosToPBPeers([]peer.AddrInfo{pi}) + return pmes, nil +} + +// FindProviders searches until the context expires. +func (dht *IpfsDHT) FindProviders(ctx context.Context, c cid.Cid) ([]peer.AddrInfo, error) { + var providers []peer.AddrInfo + for p := range dht.FindProvidersAsync(ctx, c, KValue) { + providers = append(providers, p) + } + return providers, nil +} + +// FindProvidersAsync is the same thing as FindProviders, but returns a channel. +// Peers will be returned on the channel as soon as they are found, even before +// the search query completes. +func (dht *IpfsDHT) FindProvidersAsync(ctx context.Context, key cid.Cid, count int) <-chan peer.AddrInfo { + logger.Event(ctx, "findProviders", key) + peerOut := make(chan peer.AddrInfo, count) + go dht.findProvidersAsyncRoutine(ctx, key, count, peerOut) + return peerOut +} + +func (dht *IpfsDHT) findProvidersAsyncRoutine(ctx context.Context, key cid.Cid, count int, peerOut chan peer.AddrInfo) { + defer logger.EventBegin(ctx, "findProvidersAsync", key).Done() + defer close(peerOut) + + ps := peer.NewLimitedSet(count) + provs := dht.providers.GetProviders(ctx, key) + for _, p := range provs { + // NOTE: Assuming that this list of peers is unique + if ps.TryAdd(p) { + pi := dht.peerstore.PeerInfo(p) + select { + case peerOut <- pi: + case <-ctx.Done(): + return + } + } + + // If we have enough peers locally, don't bother with remote RPC + // TODO: is this a DOS vector? + if ps.Size() >= count { + return + } + } + + peers := dht.routingTable.NearestPeers(kb.ConvertKey(key.KeyString()), AlphaValue) + if len(peers) == 0 { + routing.PublishQueryEvent(ctx, &routing.QueryEvent{ + Type: routing.QueryError, + Extra: kb.ErrLookupFailure.Error(), + }) + return + } + + // setup the Query + parent := ctx + query := dht.newQuery(key.KeyString(), func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) { + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.SendingQuery, + ID: p, + }) + pmes, err := dht.findProvidersSingle(ctx, p, key) + if err != nil { + return nil, err + } + + logger.Debugf("%d provider entries", len(pmes.GetProviderPeers())) + provs := pb.PBPeersToPeerInfos(pmes.GetProviderPeers()) + logger.Debugf("%d provider entries decoded", len(provs)) + + // Add unique providers from request, up to 'count' + for _, prov := range provs { + if prov.ID != dht.self { + dht.peerstore.AddAddrs(prov.ID, prov.Addrs, peerstore.TempAddrTTL) + } + logger.Debugf("got provider: %s", prov) + if ps.TryAdd(prov.ID) { + logger.Debugf("using provider: %s", prov) + select { + case peerOut <- *prov: + case <-ctx.Done(): + logger.Debug("context timed out sending more providers") + return nil, ctx.Err() + } + } + if ps.Size() >= count { + logger.Debugf("got enough providers (%d/%d)", ps.Size(), count) + return &dhtQueryResult{success: true}, nil + } + } + + // Give closer peers back to the query to be queried + closer := pmes.GetCloserPeers() + clpeers := pb.PBPeersToPeerInfos(closer) + logger.Debugf("got closer peers: %d %s", len(clpeers), clpeers) + + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.PeerResponse, + ID: p, + Responses: clpeers, + }) + return &dhtQueryResult{closerPeers: clpeers}, nil + }) + + _, err := query.Run(ctx, peers) + if err != nil { + logger.Debugf("Query error: %s", err) + // Special handling for issue: https://github.com/ipfs/go-ipfs/issues/3032 + if fmt.Sprint(err) == "" { + logger.Error("reproduced bug 3032:") + logger.Errorf("Errors type information: %#v", err) + logger.Errorf("go version: %s", runtime.Version()) + logger.Error("please report this information to: https://github.com/ipfs/go-ipfs/issues/3032") + + // replace problematic error with something that won't crash the daemon + err = fmt.Errorf("") + } + routing.PublishQueryEvent(ctx, &routing.QueryEvent{ + Type: routing.QueryError, + Extra: err.Error(), + }) + } +} + +// FindPeer searches for a peer with given ID. +func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (_ peer.AddrInfo, err error) { + eip := logger.EventBegin(ctx, "FindPeer", id) + defer func() { + if err != nil { + eip.SetError(err) + } + eip.Done() + }() + + // Check if were already connected to them + if pi := dht.FindLocal(id); pi.ID != "" { + return pi, nil + } + + peers := dht.routingTable.NearestPeers(kb.ConvertPeerID(id), AlphaValue) + if len(peers) == 0 { + return peer.AddrInfo{}, kb.ErrLookupFailure + } + + // Sanity... + for _, p := range peers { + if p == id { + logger.Debug("found target peer in list of closest peers...") + return dht.peerstore.PeerInfo(p), nil + } + } + + // setup the Query + parent := ctx + query := dht.newQuery(string(id), func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) { + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.SendingQuery, + ID: p, + }) + + pmes, err := dht.findPeerSingle(ctx, p, id) + if err != nil { + return nil, err + } + + closer := pmes.GetCloserPeers() + clpeerInfos := pb.PBPeersToPeerInfos(closer) + + // see if we got the peer here + for _, npi := range clpeerInfos { + if npi.ID == id { + return &dhtQueryResult{ + peer: npi, + success: true, + }, nil + } + } + + routing.PublishQueryEvent(parent, &routing.QueryEvent{ + Type: routing.PeerResponse, + ID: p, + Responses: clpeerInfos, + }) + + return &dhtQueryResult{closerPeers: clpeerInfos}, nil + }) + + // run it! + result, err := query.Run(ctx, peers) + if err != nil { + return peer.AddrInfo{}, err + } + + logger.Debugf("FindPeer %v %v", id, result.success) + if result.peer.ID == "" { + return peer.AddrInfo{}, routing.ErrNotFound + } + + return *result.peer, nil +} + +// FindPeersConnectedToPeer searches for peers directly connected to a given peer. +func (dht *IpfsDHT) FindPeersConnectedToPeer(ctx context.Context, id peer.ID) (<-chan *peer.AddrInfo, error) { + + peerchan := make(chan *peer.AddrInfo, asyncQueryBuffer) + peersSeen := make(map[peer.ID]struct{}) + var peersSeenMx sync.Mutex + + peers := dht.routingTable.NearestPeers(kb.ConvertPeerID(id), AlphaValue) + if len(peers) == 0 { + return nil, kb.ErrLookupFailure + } + + // setup the Query + query := dht.newQuery(string(id), func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) { + + pmes, err := dht.findPeerSingle(ctx, p, id) + if err != nil { + return nil, err + } + + var clpeers []*peer.AddrInfo + closer := pmes.GetCloserPeers() + for _, pbp := range closer { + pi := pb.PBPeerToPeerInfo(pbp) + + // skip peers already seen + peersSeenMx.Lock() + if _, found := peersSeen[pi.ID]; found { + peersSeenMx.Unlock() + continue + } + peersSeen[pi.ID] = struct{}{} + peersSeenMx.Unlock() + + // if peer is connected, send it to our client. + if pb.Connectedness(pbp.Connection) == network.Connected { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case peerchan <- pi: + } + } + + // if peer is the peer we're looking for, don't bother querying it. + // TODO maybe query it? + if pb.Connectedness(pbp.Connection) != network.Connected { + clpeers = append(clpeers, pi) + } + } + + return &dhtQueryResult{closerPeers: clpeers}, nil + }) + + // run it! run it asynchronously to gen peers as results are found. + // this does no error checking + go func() { + if _, err := query.Run(ctx, peers); err != nil { + logger.Debug(err) + } + + // close the peerchan channel when done. + close(peerchan) + }() + + return peerchan, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/routing_options.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/routing_options.go new file mode 100644 index 00000000..591ce54c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/routing_options.go @@ -0,0 +1,29 @@ +package dht + +import "github.com/libp2p/go-libp2p-core/routing" + +type quorumOptionKey struct{} + +const defaultQuorum = 16 + +// Quorum is a DHT option that tells the DHT how many peers it needs to get +// values from before returning the best one. +// +// Default: 16 +func Quorum(n int) routing.Option { + return func(opts *routing.Options) error { + if opts.Other == nil { + opts.Other = make(map[interface{}]interface{}, 1) + } + opts.Other[quorumOptionKey{}] = n + return nil + } +} + +func getQuorum(opts *routing.Options, ndefault int) int { + responsesNeeded, ok := opts.Other[quorumOptionKey{}].(int) + if !ok { + responsesNeeded = ndefault + } + return responsesNeeded +} diff --git a/vendor/github.com/libp2p/go-libp2p-kad-dht/util.go b/vendor/github.com/libp2p/go-libp2p-kad-dht/util.go new file mode 100644 index 00000000..6ab5c006 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kad-dht/util.go @@ -0,0 +1,10 @@ +package dht + +// Pool size is the number of nodes used for group find/set RPC calls +var PoolSize = 6 + +// K is the maximum number of requests to perform before returning failure. +var KValue = 20 + +// Alpha is the concurrency factor for asynchronous requests. +var AlphaValue = 3 diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/.travis.yml b/vendor/github.com/libp2p/go-libp2p-kbucket/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/LICENSE b/vendor/github.com/libp2p/go-libp2p-kbucket/LICENSE new file mode 100644 index 00000000..55a2d036 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/README.md b/vendor/github.com/libp2p/go-libp2p-kbucket/README.md new file mode 100644 index 00000000..6ce5db6f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/README.md @@ -0,0 +1,30 @@ +# go-libp2p-kbucket + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A kbucket implementation for use as a routing table in go-libp2p-kad-dht + +## Documenation + +See https://godoc.org/github.com/libp2p/go-libp2p-kbucket. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-key/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on libp2p? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 2.2.23: QmSNE1XryoCMnZCbRaj1D23k6YKCaTQ386eJciu1pAfu8M diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/bucket.go b/vendor/github.com/libp2p/go-libp2p-kbucket/bucket.go new file mode 100644 index 00000000..bf3f2ee6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/bucket.go @@ -0,0 +1,110 @@ +package kbucket + +import ( + "container/list" + "sync" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// Bucket holds a list of peers. +type Bucket struct { + lk sync.RWMutex + list *list.List +} + +func newBucket() *Bucket { + b := new(Bucket) + b.list = list.New() + return b +} + +func (b *Bucket) Peers() []peer.ID { + b.lk.RLock() + defer b.lk.RUnlock() + ps := make([]peer.ID, 0, b.list.Len()) + for e := b.list.Front(); e != nil; e = e.Next() { + id := e.Value.(peer.ID) + ps = append(ps, id) + } + return ps +} + +func (b *Bucket) Has(id peer.ID) bool { + b.lk.RLock() + defer b.lk.RUnlock() + for e := b.list.Front(); e != nil; e = e.Next() { + if e.Value.(peer.ID) == id { + return true + } + } + return false +} + +func (b *Bucket) Remove(id peer.ID) bool { + b.lk.Lock() + defer b.lk.Unlock() + for e := b.list.Front(); e != nil; e = e.Next() { + if e.Value.(peer.ID) == id { + b.list.Remove(e) + return true + } + } + return false +} + +func (b *Bucket) MoveToFront(id peer.ID) { + b.lk.Lock() + defer b.lk.Unlock() + for e := b.list.Front(); e != nil; e = e.Next() { + if e.Value.(peer.ID) == id { + b.list.MoveToFront(e) + } + } +} + +func (b *Bucket) PushFront(p peer.ID) { + b.lk.Lock() + b.list.PushFront(p) + b.lk.Unlock() +} + +func (b *Bucket) PopBack() peer.ID { + b.lk.Lock() + defer b.lk.Unlock() + last := b.list.Back() + b.list.Remove(last) + return last.Value.(peer.ID) +} + +func (b *Bucket) Len() int { + b.lk.RLock() + defer b.lk.RUnlock() + return b.list.Len() +} + +// Split splits a buckets peers into two buckets, the methods receiver will have +// peers with CPL equal to cpl, the returned bucket will have peers with CPL +// greater than cpl (returned bucket has closer peers) +func (b *Bucket) Split(cpl int, target ID) *Bucket { + b.lk.Lock() + defer b.lk.Unlock() + + out := list.New() + newbuck := newBucket() + newbuck.list = out + e := b.list.Front() + for e != nil { + peerID := ConvertPeerID(e.Value.(peer.ID)) + peerCPL := CommonPrefixLen(peerID, target) + if peerCPL > cpl { + cur := e + out.PushBack(e.Value) + e = e.Next() + b.list.Remove(cur) + continue + } + e = e.Next() + } + return newbuck +} diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/codecov.yml b/vendor/github.com/libp2p/go-libp2p-kbucket/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/go.mod b/vendor/github.com/libp2p/go-libp2p-kbucket/go.mod new file mode 100644 index 00000000..982ac344 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/go.mod @@ -0,0 +1,9 @@ +module github.com/libp2p/go-libp2p-kbucket + +require ( + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-peerstore v0.1.0 + github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 +) diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/go.sum b/vendor/github.com/libp2p/go-libp2p-kbucket/go.sum new file mode 100644 index 00000000..ac70a977 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/go.sum @@ -0,0 +1,121 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/keyspace.go b/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/keyspace.go new file mode 100644 index 00000000..e26a0e6d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/keyspace.go @@ -0,0 +1,97 @@ +package keyspace + +import ( + "sort" + + "math/big" +) + +// Key represents an identifier in a KeySpace. It holds a reference to the +// associated KeySpace, as well references to both the Original identifier, +// as well as the new, KeySpace Bytes one. +type Key struct { + + // Space is the KeySpace this Key is related to. + Space KeySpace + + // Original is the original value of the identifier + Original []byte + + // Bytes is the new value of the identifier, in the KeySpace. + Bytes []byte +} + +// Equal returns whether this key is equal to another. +func (k1 Key) Equal(k2 Key) bool { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Equal(k1, k2) +} + +// Less returns whether this key comes before another. +func (k1 Key) Less(k2 Key) bool { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Less(k1, k2) +} + +// Distance returns this key's distance to another +func (k1 Key) Distance(k2 Key) *big.Int { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Distance(k1, k2) +} + +// KeySpace is an object used to do math on identifiers. Each keyspace has its +// own properties and rules. See XorKeySpace. +type KeySpace interface { + + // Key converts an identifier into a Key in this space. + Key([]byte) Key + + // Equal returns whether keys are equal in this key space + Equal(Key, Key) bool + + // Distance returns the distance metric in this key space + Distance(Key, Key) *big.Int + + // Less returns whether the first key is smaller than the second. + Less(Key, Key) bool +} + +// byDistanceToCenter is a type used to sort Keys by proximity to a center. +type byDistanceToCenter struct { + Center Key + Keys []Key +} + +func (s byDistanceToCenter) Len() int { + return len(s.Keys) +} + +func (s byDistanceToCenter) Swap(i, j int) { + s.Keys[i], s.Keys[j] = s.Keys[j], s.Keys[i] +} + +func (s byDistanceToCenter) Less(i, j int) bool { + a := s.Center.Distance(s.Keys[i]) + b := s.Center.Distance(s.Keys[j]) + return a.Cmp(b) == -1 +} + +// SortByDistance takes a KeySpace, a center Key, and a list of Keys toSort. +// It returns a new list, where the Keys toSort have been sorted by their +// distance to the center Key. +func SortByDistance(sp KeySpace, center Key, toSort []Key) []Key { + toSortCopy := make([]Key, len(toSort)) + copy(toSortCopy, toSort) + bdtc := &byDistanceToCenter{ + Center: center, + Keys: toSortCopy, // copy + } + sort.Sort(bdtc) + return bdtc.Keys +} diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/xor.go b/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/xor.go new file mode 100644 index 00000000..6750b0bb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/keyspace/xor.go @@ -0,0 +1,59 @@ +package keyspace + +import ( + "bytes" + "math/big" + "math/bits" + + u "github.com/ipfs/go-ipfs-util" + sha256 "github.com/minio/sha256-simd" +) + +// XORKeySpace is a KeySpace which: +// - normalizes identifiers using a cryptographic hash (sha256) +// - measures distance by XORing keys together +var XORKeySpace = &xorKeySpace{} +var _ KeySpace = XORKeySpace // ensure it conforms + +type xorKeySpace struct{} + +// Key converts an identifier into a Key in this space. +func (s *xorKeySpace) Key(id []byte) Key { + hash := sha256.Sum256(id) + key := hash[:] + return Key{ + Space: s, + Original: id, + Bytes: key, + } +} + +// Equal returns whether keys are equal in this key space +func (s *xorKeySpace) Equal(k1, k2 Key) bool { + return bytes.Equal(k1.Bytes, k2.Bytes) +} + +// Distance returns the distance metric in this key space +func (s *xorKeySpace) Distance(k1, k2 Key) *big.Int { + // XOR the keys + k3 := u.XOR(k1.Bytes, k2.Bytes) + + // interpret it as an integer + dist := big.NewInt(0).SetBytes(k3) + return dist +} + +// Less returns whether the first key is smaller than the second. +func (s *xorKeySpace) Less(k1, k2 Key) bool { + return bytes.Compare(k1.Bytes, k2.Bytes) < 0 +} + +// ZeroPrefixLen returns the number of consecutive zeroes in a byte slice. +func ZeroPrefixLen(id []byte) int { + for i, b := range id { + if b != 0 { + return i*8 + bits.LeadingZeros8(uint8(b)) + } + } + return len(id) * 8 +} diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/sorting.go b/vendor/github.com/libp2p/go-libp2p-kbucket/sorting.go new file mode 100644 index 00000000..3b670723 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/sorting.go @@ -0,0 +1,62 @@ +package kbucket + +import ( + "container/list" + "sort" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// A helper struct to sort peers by their distance to the local node +type peerDistance struct { + p peer.ID + distance ID +} + +// peerDistanceSorter implements sort.Interface to sort peers by xor distance +type peerDistanceSorter struct { + peers []peerDistance + target ID +} + +func (pds *peerDistanceSorter) Len() int { return len(pds.peers) } +func (pds *peerDistanceSorter) Swap(a, b int) { pds.peers[a], pds.peers[b] = pds.peers[b], pds.peers[a] } +func (pds *peerDistanceSorter) Less(a, b int) bool { + return pds.peers[a].distance.less(pds.peers[b].distance) +} + +// Append the peer.ID to the sorter's slice. It may no longer be sorted. +func (pds *peerDistanceSorter) appendPeer(p peer.ID) { + pds.peers = append(pds.peers, peerDistance{ + p: p, + distance: xor(pds.target, ConvertPeerID(p)), + }) +} + +// Append the peer.ID values in the list to the sorter's slice. It may no longer be sorted. +func (pds *peerDistanceSorter) appendPeersFromList(l *list.List) { + for e := l.Front(); e != nil; e = e.Next() { + pds.appendPeer(e.Value.(peer.ID)) + } +} + +func (pds *peerDistanceSorter) sort() { + sort.Sort(pds) +} + +// Sort the given peers by their ascending distance from the target. A new slice is returned. +func SortClosestPeers(peers []peer.ID, target ID) []peer.ID { + sorter := peerDistanceSorter{ + peers: make([]peerDistance, 0, len(peers)), + target: target, + } + for _, p := range peers { + sorter.appendPeer(p) + } + sorter.sort() + out := make([]peer.ID, 0, sorter.Len()) + for _, p := range sorter.peers { + out = append(out, p.p) + } + return out +} diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/table.go b/vendor/github.com/libp2p/go-libp2p-kbucket/table.go new file mode 100644 index 00000000..ec8bfd0e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/table.go @@ -0,0 +1,253 @@ +// package kbucket implements a kademlia 'k-bucket' routing table. +package kbucket + +import ( + "errors" + "fmt" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("table") + +var ErrPeerRejectedHighLatency = errors.New("peer rejected; latency too high") +var ErrPeerRejectedNoCapacity = errors.New("peer rejected; insufficient capacity") + +// RoutingTable defines the routing table. +type RoutingTable struct { + + // ID of the local peer + local ID + + // Blanket lock, refine later for better performance + tabLock sync.RWMutex + + // latency metrics + metrics peerstore.Metrics + + // Maximum acceptable latency for peers in this cluster + maxLatency time.Duration + + // kBuckets define all the fingers to other nodes. + Buckets []*Bucket + bucketsize int + + // notification functions + PeerRemoved func(peer.ID) + PeerAdded func(peer.ID) +} + +// NewRoutingTable creates a new routing table with a given bucketsize, local ID, and latency tolerance. +func NewRoutingTable(bucketsize int, localID ID, latency time.Duration, m peerstore.Metrics) *RoutingTable { + rt := &RoutingTable{ + Buckets: []*Bucket{newBucket()}, + bucketsize: bucketsize, + local: localID, + maxLatency: latency, + metrics: m, + PeerRemoved: func(peer.ID) {}, + PeerAdded: func(peer.ID) {}, + } + + return rt +} + +// Update adds or moves the given peer to the front of its respective bucket +func (rt *RoutingTable) Update(p peer.ID) (evicted peer.ID, err error) { + peerID := ConvertPeerID(p) + cpl := CommonPrefixLen(peerID, rt.local) + + rt.tabLock.Lock() + defer rt.tabLock.Unlock() + bucketID := cpl + if bucketID >= len(rt.Buckets) { + bucketID = len(rt.Buckets) - 1 + } + + bucket := rt.Buckets[bucketID] + if bucket.Has(p) { + // If the peer is already in the table, move it to the front. + // This signifies that it it "more active" and the less active nodes + // Will as a result tend towards the back of the list + bucket.MoveToFront(p) + return "", nil + } + + if rt.metrics.LatencyEWMA(p) > rt.maxLatency { + // Connection doesnt meet requirements, skip! + return "", ErrPeerRejectedHighLatency + } + + // We have enough space in the bucket (whether spawned or grouped). + if bucket.Len() < rt.bucketsize { + bucket.PushFront(p) + rt.PeerAdded(p) + return "", nil + } + + if bucketID == len(rt.Buckets)-1 { + // if the bucket is too large and this is the last bucket (i.e. wildcard), unfold it. + rt.nextBucket() + // the structure of the table has changed, so let's recheck if the peer now has a dedicated bucket. + bucketID = cpl + if bucketID >= len(rt.Buckets) { + bucketID = len(rt.Buckets) - 1 + } + bucket = rt.Buckets[bucketID] + if bucket.Len() >= rt.bucketsize { + // if after all the unfolding, we're unable to find room for this peer, scrap it. + return "", ErrPeerRejectedNoCapacity + } + bucket.PushFront(p) + rt.PeerAdded(p) + return "", nil + } + + return "", ErrPeerRejectedNoCapacity +} + +// Remove deletes a peer from the routing table. This is to be used +// when we are sure a node has disconnected completely. +func (rt *RoutingTable) Remove(p peer.ID) { + peerID := ConvertPeerID(p) + cpl := CommonPrefixLen(peerID, rt.local) + + rt.tabLock.Lock() + defer rt.tabLock.Unlock() + + bucketID := cpl + if bucketID >= len(rt.Buckets) { + bucketID = len(rt.Buckets) - 1 + } + + bucket := rt.Buckets[bucketID] + if bucket.Remove(p) { + rt.PeerRemoved(p) + } +} + +func (rt *RoutingTable) nextBucket() { + // This is the last bucket, which allegedly is a mixed bag containing peers not belonging in dedicated (unfolded) buckets. + // _allegedly_ is used here to denote that *all* peers in the last bucket might feasibly belong to another bucket. + // This could happen if e.g. we've unfolded 4 buckets, and all peers in folded bucket 5 really belong in bucket 8. + bucket := rt.Buckets[len(rt.Buckets)-1] + newBucket := bucket.Split(len(rt.Buckets)-1, rt.local) + rt.Buckets = append(rt.Buckets, newBucket) + + // The newly formed bucket still contains too many peers. We probably just unfolded a empty bucket. + if newBucket.Len() >= rt.bucketsize { + // Keep unfolding the table until the last bucket is not overflowing. + rt.nextBucket() + } +} + +// Find a specific peer by ID or return nil +func (rt *RoutingTable) Find(id peer.ID) peer.ID { + srch := rt.NearestPeers(ConvertPeerID(id), 1) + if len(srch) == 0 || srch[0] != id { + return "" + } + return srch[0] +} + +// NearestPeer returns a single peer that is nearest to the given ID +func (rt *RoutingTable) NearestPeer(id ID) peer.ID { + peers := rt.NearestPeers(id, 1) + if len(peers) > 0 { + return peers[0] + } + + log.Debugf("NearestPeer: Returning nil, table size = %d", rt.Size()) + return "" +} + +// NearestPeers returns a list of the 'count' closest peers to the given ID +func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID { + cpl := CommonPrefixLen(id, rt.local) + + // It's assumed that this also protects the buckets. + rt.tabLock.RLock() + + // Get bucket at cpl index or last bucket + var bucket *Bucket + if cpl >= len(rt.Buckets) { + cpl = len(rt.Buckets) - 1 + } + bucket = rt.Buckets[cpl] + + pds := peerDistanceSorter{ + peers: make([]peerDistance, 0, 3*rt.bucketsize), + target: id, + } + pds.appendPeersFromList(bucket.list) + if pds.Len() < count { + // In the case of an unusual split, one bucket may be short or empty. + // if this happens, search both surrounding buckets for nearby peers + if cpl > 0 { + pds.appendPeersFromList(rt.Buckets[cpl-1].list) + } + if cpl < len(rt.Buckets)-1 { + pds.appendPeersFromList(rt.Buckets[cpl+1].list) + } + } + rt.tabLock.RUnlock() + + // Sort by distance to local peer + pds.sort() + + if count < pds.Len() { + pds.peers = pds.peers[:count] + } + + out := make([]peer.ID, 0, pds.Len()) + for _, p := range pds.peers { + out = append(out, p.p) + } + + return out +} + +// Size returns the total number of peers in the routing table +func (rt *RoutingTable) Size() int { + var tot int + rt.tabLock.RLock() + for _, buck := range rt.Buckets { + tot += buck.Len() + } + rt.tabLock.RUnlock() + return tot +} + +// ListPeers takes a RoutingTable and returns a list of all peers from all buckets in the table. +func (rt *RoutingTable) ListPeers() []peer.ID { + var peers []peer.ID + rt.tabLock.RLock() + for _, buck := range rt.Buckets { + peers = append(peers, buck.Peers()...) + } + rt.tabLock.RUnlock() + return peers +} + +// Print prints a descriptive statement about the provided RoutingTable +func (rt *RoutingTable) Print() { + fmt.Printf("Routing Table, bs = %d, Max latency = %d\n", rt.bucketsize, rt.maxLatency) + rt.tabLock.RLock() + + for i, b := range rt.Buckets { + fmt.Printf("\tbucket: %d\n", i) + + b.lk.RLock() + for e := b.list.Front(); e != nil; e = e.Next() { + p := e.Value.(peer.ID) + fmt.Printf("\t\t- %s %s\n", p.Pretty(), rt.metrics.LatencyEWMA(p).String()) + } + b.lk.RUnlock() + } + rt.tabLock.RUnlock() +} diff --git a/vendor/github.com/libp2p/go-libp2p-kbucket/util.go b/vendor/github.com/libp2p/go-libp2p-kbucket/util.go new file mode 100644 index 00000000..71d8709f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-kbucket/util.go @@ -0,0 +1,63 @@ +package kbucket + +import ( + "bytes" + "errors" + + "github.com/libp2p/go-libp2p-core/peer" + ks "github.com/libp2p/go-libp2p-kbucket/keyspace" + + u "github.com/ipfs/go-ipfs-util" + sha256 "github.com/minio/sha256-simd" +) + +// Returned if a routing table query returns no results. This is NOT expected +// behaviour +var ErrLookupFailure = errors.New("failed to find any peer in table") + +// ID for IpfsDHT is in the XORKeySpace +// +// The type dht.ID signifies that its contents have been hashed from either a +// peer.ID or a util.Key. This unifies the keyspace +type ID []byte + +func (id ID) equal(other ID) bool { + return bytes.Equal(id, other) +} + +func (id ID) less(other ID) bool { + a := ks.Key{Space: ks.XORKeySpace, Bytes: id} + b := ks.Key{Space: ks.XORKeySpace, Bytes: other} + return a.Less(b) +} + +func xor(a, b ID) ID { + return ID(u.XOR(a, b)) +} + +func CommonPrefixLen(a, b ID) int { + return ks.ZeroPrefixLen(u.XOR(a, b)) +} + +// ConvertPeerID creates a DHT ID by hashing a Peer ID (Multihash) +func ConvertPeerID(id peer.ID) ID { + hash := sha256.Sum256([]byte(id)) + return hash[:] +} + +// ConvertKey creates a DHT ID by hashing a local key (String) +func ConvertKey(id string) ID { + hash := sha256.Sum256([]byte(id)) + return hash[:] +} + +// Closer returns true if a is closer to key than b is +func Closer(a, b peer.ID, key string) bool { + aid := ConvertPeerID(a) + bid := ConvertPeerID(b) + tgt := ConvertKey(key) + adist := xor(aid, tgt) + bdist := xor(bid, tgt) + + return adist.less(bdist) +} diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/.travis.yml b/vendor/github.com/libp2p/go-libp2p-loggables/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/LICENSE b/vendor/github.com/libp2p/go-libp2p-loggables/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/README.md b/vendor/github.com/libp2p/go-libp2p-loggables/README.md new file mode 100644 index 00000000..3fce6e7b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/README.md @@ -0,0 +1,34 @@ +# go-libp2p-loggables + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellpw.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> logging helpers for go-libp2p + +## Install + +``` +go get github.com/libp2p/go-libp2p-loggables +``` + +## Usage + +See https://godoc.org/github.com/libp2p/go-libp2p-loggables. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-loggables/issues)! + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to libp2p are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2016 Jeromy Johnson. + +--- + +The last gx published version of this module was: 1.1.33: QmUbSLukzZYZvEYxynj9Dtd1WrGLxxg9R4U68vCMPWHmRU diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/codecov.yml b/vendor/github.com/libp2p/go-libp2p-loggables/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/go.mod b/vendor/github.com/libp2p/go-libp2p-loggables/go.mod new file mode 100644 index 00000000..56d6b8ff --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-libp2p-loggables + +require ( + github.com/google/uuid v1.1.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multiaddr v0.0.2 +) diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/go.sum b/vendor/github.com/libp2p/go-libp2p-loggables/go.sum new file mode 100644 index 00000000..8d11a7b3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/go.sum @@ -0,0 +1,88 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-loggables/loggables.go b/vendor/github.com/libp2p/go-libp2p-loggables/loggables.go new file mode 100644 index 00000000..30b2a3ab --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-loggables/loggables.go @@ -0,0 +1,80 @@ +// Package loggables includes a bunch of transaltor functions for commonplace/stdlib +// objects. This is boilerplate code that shouldn't change much, and not sprinkled +// all over the place (i.e. gather it here). +// +// Note: it may make sense to put all stdlib Loggable functions in the eventlog +// package. Putting it here for now in case we don't want to polute it. +package loggables + +import ( + "net" + + uuid "github.com/google/uuid" + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" +) + +// NetConn returns an eventlog.Metadata with the conn addresses +func NetConn(c net.Conn) logging.Loggable { + return logging.Metadata{ + "localAddr": c.LocalAddr(), + "remoteAddr": c.RemoteAddr(), + } +} + +// Error returns an eventlog.Metadata with an error +func Error(e error) logging.Loggable { + return logging.Metadata{ + "error": e.Error(), + } +} + +func Uuid(key string) logging.Metadata { + ids := "#UUID-ERROR#" + if id, err := uuid.NewRandom(); err == nil { + ids = id.String() + } + return logging.Metadata{ + key: ids, + } +} + +// Dial metadata is metadata for dial events +func Dial(sys string, lid, rid peer.ID, laddr, raddr ma.Multiaddr) DeferredMap { + m := DeferredMap{} + m["subsystem"] = sys + if lid != "" { + m["localPeer"] = func() interface{} { return lid.Pretty() } + } + if laddr != nil { + m["localAddr"] = func() interface{} { return laddr.String() } + } + if rid != "" { + m["remotePeer"] = func() interface{} { return rid.Pretty() } + } + if raddr != nil { + m["remoteAddr"] = func() interface{} { return raddr.String() } + } + return m +} + +// DeferredMap is a Loggable which may contain deferred values. +type DeferredMap map[string]interface{} + +// Loggable describes objects that can be marshalled into Metadata for logging +func (m DeferredMap) Loggable() map[string]interface{} { + m2 := map[string]interface{}{} + for k, v := range m { + + if vf, ok := v.(func() interface{}); ok { + // if it's a DeferredVal, call it. + m2[k] = vf() + + } else { + // else use the value as is. + m2[k] = v + } + } + return m2 +} diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/.gitignore b/vendor/github.com/libp2p/go-libp2p-mplex/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/.travis.yml b/vendor/github.com/libp2p/go-libp2p-mplex/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/LICENSE b/vendor/github.com/libp2p/go-libp2p-mplex/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/Makefile b/vendor/github.com/libp2p/go-libp2p-mplex/Makefile new file mode 100644 index 00000000..3907e857 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/Makefile @@ -0,0 +1,19 @@ +build: deps + go build ./... + +test: deps + go test ./... + +test_race: deps + go test -race ./... + +gx-bins: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx-bins + gx --verbose install --global + gx-go rewrite + +clean: gx-bins + gx-go rewrite --undo diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/README.md b/vendor/github.com/libp2p/go-libp2p-mplex/README.md new file mode 100644 index 00000000..fc3d7889 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/README.md @@ -0,0 +1,13 @@ +# go-libp2p-mplex - a go-stream-muxer shim for multiplex + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) ![](https://raw.githubusercontent.com/libp2p/go-stream-muxer/master/img/badge.png) + +This is an implementation of the [go-stream-muxer](https://github.com/libp2p/go-stream-muxer) interface for [multiplex](https://github.com/libp2p/go-mplex). For more information, see that repo. + +## Installation + +```sh +go get -d github.com/libp2p/go-libp2p-mplex +cd $GOPATH/src/github.com/libp2p/go-libp2p-mplex +make deps +``` diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/go.mod b/vendor/github.com/libp2p/go-libp2p-mplex/go.mod new file mode 100644 index 00000000..08091671 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/go.mod @@ -0,0 +1,9 @@ +module github.com/libp2p/go-libp2p-mplex + +go 1.12 + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-testing v0.0.3 + github.com/libp2p/go-mplex v0.1.0 +) diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/go.sum b/vendor/github.com/libp2p/go-libp2p-mplex/go.sum new file mode 100644 index 00000000..44811af3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/go.sum @@ -0,0 +1,81 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-mplex/multiplex.go b/vendor/github.com/libp2p/go-libp2p-mplex/multiplex.go new file mode 100644 index 00000000..bf53c9e7 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-mplex/multiplex.go @@ -0,0 +1,42 @@ +package peerstream_multiplex + +import ( + "net" + + "github.com/libp2p/go-libp2p-core/mux" + + mp "github.com/libp2p/go-mplex" +) + +type conn struct { + *mp.Multiplex +} + +func (c *conn) Close() error { + return c.Multiplex.Close() +} + +func (c *conn) IsClosed() bool { + return c.Multiplex.IsClosed() +} + +// OpenStream creates a new stream. +func (c *conn) OpenStream() (mux.MuxedStream, error) { + return c.Multiplex.NewStream() +} + +// AcceptStream accepts a stream opened by the other side. +func (c *conn) AcceptStream() (mux.MuxedStream, error) { + return c.Multiplex.Accept() +} + +// Transport is a go-peerstream transport that constructs +// multiplex-backed connections. +type Transport struct{} + +// DefaultTransport has default settings for multiplex +var DefaultTransport = &Transport{} + +func (t *Transport) NewConn(nc net.Conn, isServer bool) (mux.MuxedConn, error) { + return &conn{mp.NewMultiplex(nc, isServer)}, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-nat/.travis.yml b/vendor/github.com/libp2p/go-libp2p-nat/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-nat/LICENSE b/vendor/github.com/libp2p/go-libp2p-nat/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-nat/README.md b/vendor/github.com/libp2p/go-libp2p-nat/README.md new file mode 100644 index 00000000..5d1ac972 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/README.md @@ -0,0 +1,46 @@ +go-libp2p-nat +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-nat.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-nat) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> NAT port mapping library for go-libp2p. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Usage + +```sh +# TODO +``` + +## Contribute + +PRs are welcome! Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-libp2p-nat/issues)! + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to libp2p are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © Jeromy Johnson + +--- + +The last gx published version of this module was: 0.8.13: QmRbx7DYHgw3uNn2RuU2nv9Bdh96ZdtT65CG1CGPNRQcGZ diff --git a/vendor/github.com/libp2p/go-libp2p-nat/codecov.yml b/vendor/github.com/libp2p/go-libp2p-nat/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-nat/go.mod b/vendor/github.com/libp2p/go-libp2p-nat/go.mod new file mode 100644 index 00000000..e43298be --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/go.mod @@ -0,0 +1,9 @@ +module github.com/libp2p/go-libp2p-nat + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec // indirect + github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 + github.com/libp2p/go-nat v0.0.3 + github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f +) diff --git a/vendor/github.com/libp2p/go-libp2p-nat/go.sum b/vendor/github.com/libp2p/go-libp2p-nat/go.sum new file mode 100644 index 00000000..39da03d4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/go.sum @@ -0,0 +1,46 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec h1:DQqZhhDvrTrEQ3Qod5yfavcA064e53xlQ+xajiorXgM= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/libp2p/go-libp2p-nat/mapping.go b/vendor/github.com/libp2p/go-libp2p-nat/mapping.go new file mode 100644 index 00000000..33f25f61 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/mapping.go @@ -0,0 +1,122 @@ +package nat + +import ( + "fmt" + "net" + "sync" + "time" + + "github.com/jbenet/goprocess" +) + +// Mapping represents a port mapping in a NAT. +type Mapping interface { + // NAT returns the NAT object this Mapping belongs to. + NAT() *NAT + + // Protocol returns the protocol of this port mapping. This is either + // "tcp" or "udp" as no other protocols are likely to be NAT-supported. + Protocol() string + + // InternalPort returns the internal device port. Mapping will continue to + // try to map InternalPort() to an external facing port. + InternalPort() int + + // ExternalPort returns the external facing port. If the mapping is not + // established, port will be 0 + ExternalPort() int + + // ExternalAddr returns the external facing address. If the mapping is not + // established, addr will be nil, and and ErrNoMapping will be returned. + ExternalAddr() (addr net.Addr, err error) + + // Close closes the port mapping + Close() error +} + +// keeps republishing +type mapping struct { + sync.Mutex // guards all fields + + nat *NAT + proto string + intport int + extport int + permanent bool + proc goprocess.Process + + cached net.IP + cacheTime time.Time + cacheLk sync.Mutex +} + +func (m *mapping) NAT() *NAT { + m.Lock() + defer m.Unlock() + return m.nat +} + +func (m *mapping) Protocol() string { + m.Lock() + defer m.Unlock() + return m.proto +} + +func (m *mapping) InternalPort() int { + m.Lock() + defer m.Unlock() + return m.intport +} + +func (m *mapping) ExternalPort() int { + m.Lock() + defer m.Unlock() + return m.extport +} + +func (m *mapping) setExternalPort(p int) { + m.Lock() + defer m.Unlock() + m.extport = p +} + +func (m *mapping) ExternalAddr() (net.Addr, error) { + m.cacheLk.Lock() + defer m.cacheLk.Unlock() + oport := m.ExternalPort() + if oport == 0 { + // dont even try right now. + return nil, ErrNoMapping + } + + if time.Since(m.cacheTime) >= CacheTime { + m.nat.natmu.Lock() + cval, err := m.nat.nat.GetExternalAddress() + m.nat.natmu.Unlock() + + if err != nil { + return nil, err + } + + m.cached = cval + m.cacheTime = time.Now() + } + switch m.Protocol() { + case "tcp": + return &net.TCPAddr{ + IP: m.cached, + Port: oport, + }, nil + case "udp": + return &net.UDPAddr{ + IP: m.cached, + Port: oport, + }, nil + default: + panic(fmt.Sprintf("invalid protocol %q", m.Protocol())) + } +} + +func (m *mapping) Close() error { + return m.proc.Close() +} diff --git a/vendor/github.com/libp2p/go-libp2p-nat/nat.go b/vendor/github.com/libp2p/go-libp2p-nat/nat.go new file mode 100644 index 00000000..178f7d01 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/nat.go @@ -0,0 +1,210 @@ +package nat + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" + periodic "github.com/jbenet/goprocess/periodic" + nat "github.com/libp2p/go-nat" +) + +var ( + // ErrNoMapping signals no mapping exists for an address + ErrNoMapping = errors.New("mapping not established") +) + +var log = logging.Logger("nat") + +// MappingDuration is a default port mapping duration. +// Port mappings are renewed every (MappingDuration / 3) +const MappingDuration = time.Second * 60 + +// CacheTime is the time a mapping will cache an external address for +const CacheTime = time.Second * 15 + +// DiscoverNAT looks for a NAT device in the network and +// returns an object that can manage port mappings. +func DiscoverNAT(ctx context.Context) (*NAT, error) { + var ( + natInstance nat.NAT + err error + ) + + done := make(chan struct{}) + go func() { + defer close(done) + // This will abort in 10 seconds anyways. + natInstance, err = nat.DiscoverGateway() + }() + + select { + case <-done: + case <-ctx.Done(): + return nil, ctx.Err() + } + + if err != nil { + return nil, err + } + + // Log the device addr. + addr, err := natInstance.GetDeviceAddress() + if err != nil { + log.Debug("DiscoverGateway address error:", err) + } else { + log.Debug("DiscoverGateway address:", addr) + } + + return newNAT(natInstance), nil +} + +// NAT is an object that manages address port mappings in +// NATs (Network Address Translators). It is a long-running +// service that will periodically renew port mappings, +// and keep an up-to-date list of all the external addresses. +type NAT struct { + natmu sync.Mutex + nat nat.NAT + proc goprocess.Process + + mappingmu sync.RWMutex // guards mappings + mappings map[*mapping]struct{} + + Notifier +} + +func newNAT(realNAT nat.NAT) *NAT { + return &NAT{ + nat: realNAT, + proc: goprocess.WithParent(goprocess.Background()), + mappings: make(map[*mapping]struct{}), + } +} + +// Close shuts down all port mappings. NAT can no longer be used. +func (nat *NAT) Close() error { + return nat.proc.Close() +} + +// Process returns the nat's life-cycle manager, for making it listen +// to close signals. +func (nat *NAT) Process() goprocess.Process { + return nat.proc +} + +// Mappings returns a slice of all NAT mappings +func (nat *NAT) Mappings() []Mapping { + nat.mappingmu.Lock() + maps2 := make([]Mapping, 0, len(nat.mappings)) + for m := range nat.mappings { + maps2 = append(maps2, m) + } + nat.mappingmu.Unlock() + return maps2 +} + +func (nat *NAT) addMapping(m *mapping) { + // make mapping automatically close when nat is closed. + nat.proc.AddChild(m.proc) + + nat.mappingmu.Lock() + nat.mappings[m] = struct{}{} + nat.mappingmu.Unlock() +} + +func (nat *NAT) rmMapping(m *mapping) { + nat.mappingmu.Lock() + delete(nat.mappings, m) + nat.mappingmu.Unlock() +} + +// NewMapping attemps to construct a mapping on protocol and internal port +// It will also periodically renew the mapping until the returned Mapping +// -- or its parent NAT -- is Closed. +// +// May not succeed, and mappings may change over time; +// NAT devices may not respect our port requests, and even lie. +// Clients should not store the mapped results, but rather always +// poll our object for the latest mappings. +func (nat *NAT) NewMapping(protocol string, port int) (Mapping, error) { + if nat == nil { + return nil, fmt.Errorf("no nat available") + } + + switch protocol { + case "tcp", "udp": + default: + return nil, fmt.Errorf("invalid protocol: %s", protocol) + } + + m := &mapping{ + intport: port, + nat: nat, + proto: protocol, + } + + m.proc = goprocess.WithTeardown(func() error { + nat.rmMapping(m) + nat.natmu.Lock() + defer nat.natmu.Unlock() + nat.nat.DeletePortMapping(m.Protocol(), m.InternalPort()) + return nil + }) + + nat.addMapping(m) + + m.proc.AddChild(periodic.Every(MappingDuration/3, func(worker goprocess.Process) { + nat.establishMapping(m) + })) + + // do it once synchronously, so first mapping is done right away, and before exiting, + // allowing users -- in the optimistic case -- to use results right after. + nat.establishMapping(m) + return m, nil +} + +func (nat *NAT) establishMapping(m *mapping) { + oldport := m.ExternalPort() + + log.Debugf("Attempting port map: %s/%d", m.Protocol(), m.InternalPort()) + comment := "libp2p" + + nat.natmu.Lock() + newport, err := nat.nat.AddPortMapping(m.Protocol(), m.InternalPort(), comment, MappingDuration) + if err != nil { + // Some hardware does not support mappings with timeout, so try that + newport, err = nat.nat.AddPortMapping(m.Protocol(), m.InternalPort(), comment, 0) + } + nat.natmu.Unlock() + + if err != nil || newport == 0 { + m.setExternalPort(0) // clear mapping + // TODO: log.Event + log.Warningf("failed to establish port mapping: %s", err) + nat.Notifier.notifyAll(func(n Notifiee) { + n.MappingFailed(nat, m, oldport, err) + }) + + // we do not close if the mapping failed, + // because it may work again next time. + return + } + + m.setExternalPort(newport) + log.Debugf("NAT Mapping: %s --> %s (%s)", m.ExternalPort(), m.InternalPort(), m.Protocol()) + if oldport != 0 && newport != oldport { + log.Debugf("failed to renew same port mapping: ch %d -> %d", oldport, newport) + nat.Notifier.notifyAll(func(n Notifiee) { + n.MappingChanged(nat, m, oldport, newport) + }) + } + + nat.Notifier.notifyAll(func(n Notifiee) { + n.MappingSuccess(nat, m) + }) +} diff --git a/vendor/github.com/libp2p/go-libp2p-nat/notifier.go b/vendor/github.com/libp2p/go-libp2p-nat/notifier.go new file mode 100644 index 00000000..10fb6ac6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-nat/notifier.go @@ -0,0 +1,47 @@ +package nat + +import ( + notifier "github.com/whyrusleeping/go-notifier" +) + +// Notifier is an object that assists NAT in notifying listeners. +// It is implemented using thirdparty/notifier +type Notifier struct { + n notifier.Notifier +} + +func (n *Notifier) notifyAll(notify func(n Notifiee)) { + n.n.NotifyAll(func(n notifier.Notifiee) { + notify(n.(Notifiee)) + }) +} + +// Notify signs up notifiee to listen to NAT events. +func (n *Notifier) Notify(notifiee Notifiee) { + n.n.Notify(n) +} + +// StopNotify stops signaling events to notifiee. +func (n *Notifier) StopNotify(notifiee Notifiee) { + n.n.StopNotify(notifiee) +} + +// Notifiee is an interface objects must implement to listen to NAT events. +type Notifiee interface { + + // Called every time a successful mapping happens + // Warning: the port mapping may have changed. If that is the + // case, both MappingSuccess and MappingChanged are called. + MappingSuccess(nat *NAT, m Mapping) + + // Called when mapping a port succeeds, but the mapping is + // with a different port than an earlier success. + MappingChanged(nat *NAT, m Mapping, oldport, newport int) + + // Called when a port mapping fails. NAT will continue attempting after + // the next period. To stop trying, use: mapping.Close(). After this failure, + // mapping.ExternalPort() will be zero, and nat.ExternalAddrs() will not + // return the address for this mapping. With luck, the next attempt will + // succeed, without the client needing to do anything. + MappingFailed(nat *NAT, m Mapping, oldport int, err error) +} diff --git a/vendor/github.com/libp2p/go-libp2p-peer/.travis.yml b/vendor/github.com/libp2p/go-libp2p-peer/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-peer/LICENSE b/vendor/github.com/libp2p/go-libp2p-peer/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-peer/README.md b/vendor/github.com/libp2p/go-libp2p-peer/README.md new file mode 100644 index 00000000..ab9b684e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/README.md @@ -0,0 +1,37 @@ +# go-libp2p-peer + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23libp2p) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-peer?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-peer) +[![Coverage Status](https://codecov.io/gh/libp2p/go-libp2p-peer/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-peer/branch/master) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-peer.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-peer) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> PKI based identities for use in go-libp2p + +## Install + +TODO + +## Usage + +TODO + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-peer/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 3.1.2: QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h diff --git a/vendor/github.com/libp2p/go-libp2p-peer/codecov.yml b/vendor/github.com/libp2p/go-libp2p-peer/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-peer/deprecated.go b/vendor/github.com/libp2p/go-libp2p-peer/deprecated.go new file mode 100644 index 00000000..600b5ece --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/deprecated.go @@ -0,0 +1,65 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/peer instead. +package peer + +import ( + core "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p-crypto" +) + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/peer.ErrEmptyPeerID instead. + ErrEmptyPeerID = core.ErrEmptyPeerID + // Deprecated: use github.com/libp2p/go-libp2p-core/peer.ErrNoPublicKey instead. + ErrNoPublicKey = core.ErrNoPublicKey +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.AdvanceEnableInlining instead. +// Warning: this variable's type makes it impossible to alias by reference. +// Reads and writes from/to this variable may be inaccurate or not have the intended effect. +var AdvancedEnableInlining = core.AdvancedEnableInlining + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.ID instead. +type ID = core.ID + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDSlice instead. +type IDSlice = core.IDSlice + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDFromString instead. +func IDFromString(s string) (core.ID, error) { + return core.IDFromString(s) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDFromBytes instead. +func IDFromBytes(b []byte) (core.ID, error) { + return core.IDFromBytes(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDB58Decode instead. +func IDB58Decode(s string) (core.ID, error) { + return core.IDB58Decode(s) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDB58Encode instead. +func IDB58Encode(id ID) string { + return core.IDB58Encode(id) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDHexDecode instead. +func IDHexDecode(s string) (core.ID, error) { + return core.IDHexDecode(s) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDHexEncode instead. +func IDHexEncode(id ID) string { + return core.IDHexEncode(id) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDFromPublicKey instead. +func IDFromPublicKey(pk ic.PubKey) (core.ID, error) { + return core.IDFromPublicKey(pk) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.IDFromPrivateKey instead. +func IDFromPrivateKey(sk ic.PrivKey) (core.ID, error) { + return core.IDFromPrivateKey(sk) +} diff --git a/vendor/github.com/libp2p/go-libp2p-peer/go.mod b/vendor/github.com/libp2p/go-libp2p-peer/go.mod new file mode 100644 index 00000000..c2e26e78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/go.mod @@ -0,0 +1,7 @@ +module github.com/libp2p/go-libp2p-peer + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-crypto v0.1.0 + golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 // indirect +) diff --git a/vendor/github.com/libp2p/go-libp2p-peer/go.sum b/vendor/github.com/libp2p/go-libp2p-peer/go.sum new file mode 100644 index 00000000..e5bf65d5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peer/go.sum @@ -0,0 +1,70 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore b/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore new file mode 100644 index 00000000..bea702c0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore @@ -0,0 +1,2 @@ +*.swp +cover.out diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/.travis.yml b/vendor/github.com/libp2p/go-libp2p-peerstore/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE b/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/README.md b/vendor/github.com/libp2p/go-libp2p-peerstore/README.md new file mode 100644 index 00000000..0ad7cf97 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/README.md @@ -0,0 +1,37 @@ +# go-libp2p-peerstore +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-peerstore?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-peerstore) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-libp2p-peerstore/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-libp2p-peerstore?branch=master) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-peerstore.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-peerstore) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> An object to manage peers, their addresses, and other metadata about them. + +## Install + +```sh +go get github.com/libp2p/go-libp2p-peerstore +``` + +## Usage + +Check out the [GoDocs](https://godoc.org/github.com/libp2p/go-libp2p-peerstore). + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-libp2p-peerstore/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) + +## License +MIT + +--- + +The last gx published version of this module was: 2.0.19: QmaCTz9RkrU13bm9kMB54f7atgqM4qkjDZpRwRoJiWXEqs diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/addr/addrsrcs.go b/vendor/github.com/libp2p/go-libp2p-peerstore/addr/addrsrcs.go new file mode 100644 index 00000000..9be78d5c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/addr/addrsrcs.go @@ -0,0 +1,70 @@ +// Package addr provides utility functions to handle peer addresses. +package addr + +import ( + ma "github.com/multiformats/go-multiaddr" +) + +// AddrSource is a source of addresses. It allows clients to retrieve +// a set of addresses at a last possible moment in time. It is used +// to query a set of addresses that may change over time, as a result +// of the network changing interfaces or mappings. +type Source interface { + Addrs() []ma.Multiaddr +} + +// CombineSources returns a new AddrSource which is the +// concatenation of all input AddrSources: +// +// combined := CombinedSources(a, b) +// combined.Addrs() // append(a.Addrs(), b.Addrs()...) +// +func CombineSources(srcs ...Source) Source { + return combinedAS(srcs) +} + +type combinedAS []Source + +func (cas combinedAS) Addrs() []ma.Multiaddr { + var addrs []ma.Multiaddr + for _, s := range cas { + addrs = append(addrs, s.Addrs()...) + } + return addrs +} + +// UniqueSource returns a new AddrSource which omits duplicate +// addresses from the inputs: +// +// unique := UniqueSource(a, b) +// unique.Addrs() // append(a.Addrs(), b.Addrs()...) +// // but only adds each addr once. +// +func UniqueSource(srcs ...Source) Source { + return uniqueAS(srcs) +} + +type uniqueAS []Source + +func (uas uniqueAS) Addrs() []ma.Multiaddr { + seen := make(map[string]struct{}) + var addrs []ma.Multiaddr + for _, s := range uas { + for _, a := range s.Addrs() { + s := a.String() + if _, found := seen[s]; !found { + addrs = append(addrs, a) + seen[s] = struct{}{} + } + } + } + return addrs +} + +// Slice is a simple slice of addresses that implements +// the AddrSource interface. +type Slice []ma.Multiaddr + +func (as Slice) Addrs() []ma.Multiaddr { + return as +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/addr/sorting.go b/vendor/github.com/libp2p/go-libp2p-peerstore/addr/sorting.go new file mode 100644 index 00000000..f8a89150 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/addr/sorting.go @@ -0,0 +1,62 @@ +package addr + +import ( + "bytes" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" + mafmt "github.com/whyrusleeping/mafmt" +) + +func isFDCostlyTransport(a ma.Multiaddr) bool { + return mafmt.TCP.Matches(a) +} + +type AddrList []ma.Multiaddr + +func (al AddrList) Len() int { + return len(al) +} + +func (al AddrList) Swap(i, j int) { + al[i], al[j] = al[j], al[i] +} + +func (al AddrList) Less(i, j int) bool { + a := al[i] + b := al[j] + + // dial localhost addresses next, they should fail immediately + lba := manet.IsIPLoopback(a) + lbb := manet.IsIPLoopback(b) + if lba { + if !lbb { + return true + } + } + + // dial utp and similar 'non-fd-consuming' addresses first + fda := isFDCostlyTransport(a) + fdb := isFDCostlyTransport(b) + if !fda { + if fdb { + return true + } + + // if neither consume fd's, assume equal ordering + return false + } + + // if 'b' doesnt take a file descriptor + if !fdb { + return false + } + + // if 'b' is loopback and both take file descriptors + if lbb { + return false + } + + // for the rest, just sort by bytes + return bytes.Compare(a.Bytes(), b.Bytes()) > 0 +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml b/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml new file mode 100644 index 00000000..96dcfd78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml @@ -0,0 +1,5 @@ +coverage: + range: "50...100" +comment: off +ignore: + - "pb/*.pb.go" \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/go.mod b/vendor/github.com/libp2p/go-libp2p-peerstore/go.mod new file mode 100644 index 00000000..86338f38 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/go.mod @@ -0,0 +1,21 @@ +module github.com/libp2p/go-libp2p-peerstore + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/hashicorp/golang-lru v0.5.1 + github.com/ipfs/go-datastore v0.0.1 + github.com/ipfs/go-ds-badger v0.0.2 + github.com/ipfs/go-ds-leveldb v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-crypto v0.1.0 + github.com/libp2p/go-libp2p-peer v0.2.0 + github.com/multiformats/go-base32 v0.0.3 + github.com/multiformats/go-multiaddr v0.0.2 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/multiformats/go-multihash v0.0.1 + github.com/pkg/errors v0.8.1 + github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 + github.com/whyrusleeping/mafmt v1.2.8 +) diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/go.sum b/vendor/github.com/libp2p/go-libp2p-peerstore/go.sum new file mode 100644 index 00000000..6df7a493 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/go.sum @@ -0,0 +1,151 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo= +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f h1:6itBiEUtu+gOzXZWn46bM5/qm8LlV6/byR7Yflx/y6M= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f h1:dDxpBYafY/GYpcl+LS4Bn3ziLPuEdGRkRjYAbSlWxSA= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1 h1:AW/KZCScnBWlSb5JbnEnLKFWXL224LBEh/9KXXOrUms= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2 h1:7ToQt7QByBhOTuZF2USMv+PGlMcBC7FW7FdgQ4FCsoo= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1 h1:Z0lsTFciec9qYsyngAw1f/czhRU35qBLR2vhavPFgqA= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/interface.go b/vendor/github.com/libp2p/go-libp2p-peerstore/interface.go new file mode 100644 index 00000000..105dedc7 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/interface.go @@ -0,0 +1,46 @@ +package peerstore + +import core "github.com/libp2p/go-libp2p-core/peerstore" + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ErrNotFound instead. +var ErrNotFound = core.ErrNotFound + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.AddressTTL instead. + AddressTTL = core.AddressTTL + + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.TempAddrTTL instead. + TempAddrTTL = core.TempAddrTTL + + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ProviderAddrTTL instead. + ProviderAddrTTL = core.ProviderAddrTTL + + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.RecentlyConnectedAddrTTL instead. + RecentlyConnectedAddrTTL = core.RecentlyConnectedAddrTTL + + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.OwnObservedAddrTTL instead. + OwnObservedAddrTTL = core.OwnObservedAddrTTL +) + +const ( + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.PermanentAddrTTL instead. + PermanentAddrTTL = core.PermanentAddrTTL + + // Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ConnectedAddrTTL instead. + ConnectedAddrTTL = core.ConnectedAddrTTL +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.Peerstore instead. +type Peerstore = core.Peerstore + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.PeerMetadata instead. +type PeerMetadata = core.PeerMetadata + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.AddrBook instead. +type AddrBook = core.AddrBook + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.KeyBook instead. +type KeyBook = core.KeyBook + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ProtoBook instead. +type ProtoBook = core.ProtoBook diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go b/vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go new file mode 100644 index 00000000..f6d0ccb5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go @@ -0,0 +1,57 @@ +package peerstore + +import ( + "sync" + "time" + + moved "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-peer" +) + +// LatencyEWMASmooting governs the decay of the EWMA (the speed +// at which it changes). This must be a normalized (0-1) value. +// 1 is 100% change, 0 is no change. +var LatencyEWMASmoothing = 0.1 + +// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.Metrics instead. +type Metrics = moved.Metrics + +type metrics struct { + latmap map[peer.ID]time.Duration + latmu sync.RWMutex +} + +func NewMetrics() *metrics { + return &metrics{ + latmap: make(map[peer.ID]time.Duration), + } +} + +// RecordLatency records a new latency measurement +func (m *metrics) RecordLatency(p peer.ID, next time.Duration) { + nextf := float64(next) + s := LatencyEWMASmoothing + if s > 1 || s < 0 { + s = 0.1 // ignore the knob. it's broken. look, it jiggles. + } + + m.latmu.Lock() + ewma, found := m.latmap[p] + ewmaf := float64(ewma) + if !found { + m.latmap[p] = next // when no data, just take it as the mean. + } else { + nextf = ((1.0 - s) * ewmaf) + (s * nextf) + m.latmap[p] = time.Duration(nextf) + } + m.latmu.Unlock() +} + +// LatencyEWMA returns an exponentially-weighted moving avg. +// of all measurements of a peer's latency. +func (m *metrics) LatencyEWMA(p peer.ID) time.Duration { + m.latmu.RLock() + lat := m.latmap[p] + m.latmu.RUnlock() + return time.Duration(lat) +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/peerinfo.go b/vendor/github.com/libp2p/go-libp2p-peerstore/peerinfo.go new file mode 100644 index 00000000..24c8c31f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/peerinfo.go @@ -0,0 +1,22 @@ +package peerstore + +import ( + core "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.Info instead. +type PeerInfo = core.AddrInfo + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.ErrInvalidAddr instead. +var ErrInvalidAddr = core.ErrInvalidAddr + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.AddrInfoFromP2pAddr instead. +func InfoFromP2pAddr(m ma.Multiaddr) (*core.AddrInfo, error) { + return core.AddrInfoFromP2pAddr(m) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/peer.AddrInfoToP2pAddrs instead. +func InfoToP2pAddrs(pi *core.AddrInfo) ([]ma.Multiaddr, error) { + return core.AddrInfoToP2pAddrs(pi) +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go b/vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go new file mode 100644 index 00000000..ea29a17f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go @@ -0,0 +1,91 @@ +package peerstore + +import ( + "fmt" + "io" + + peer "github.com/libp2p/go-libp2p-peer" +) + +var _ Peerstore = (*peerstore)(nil) + +type peerstore struct { + Metrics + + KeyBook + AddrBook + ProtoBook + PeerMetadata +} + +// NewPeerstore creates a data structure that stores peer data, backed by the +// supplied implementations of KeyBook, AddrBook and PeerMetadata. +func NewPeerstore(kb KeyBook, ab AddrBook, pb ProtoBook, md PeerMetadata) Peerstore { + return &peerstore{ + KeyBook: kb, + AddrBook: ab, + ProtoBook: pb, + PeerMetadata: md, + Metrics: NewMetrics(), + } +} + +func (ps *peerstore) Close() (err error) { + var errs []error + weakClose := func(name string, c interface{}) { + if cl, ok := c.(io.Closer); ok { + if err = cl.Close(); err != nil { + errs = append(errs, fmt.Errorf("%s error: %s", name, err)) + } + } + } + + weakClose("keybook", ps.KeyBook) + weakClose("addressbook", ps.AddrBook) + weakClose("protobook", ps.ProtoBook) + weakClose("peermetadata", ps.PeerMetadata) + + if len(errs) > 0 { + return fmt.Errorf("failed while closing peerstore; err(s): %q", errs) + } + return nil +} + +func (ps *peerstore) Peers() peer.IDSlice { + set := map[peer.ID]struct{}{} + for _, p := range ps.PeersWithKeys() { + set[p] = struct{}{} + } + for _, p := range ps.PeersWithAddrs() { + set[p] = struct{}{} + } + + pps := make(peer.IDSlice, 0, len(set)) + for p := range set { + pps = append(pps, p) + } + return pps +} + +func (ps *peerstore) PeerInfo(p peer.ID) PeerInfo { + return PeerInfo{ + ID: p, + Addrs: ps.AddrBook.Addrs(p), + } +} + +func PeerInfos(ps Peerstore, peers peer.IDSlice) []PeerInfo { + pi := make([]PeerInfo, len(peers)) + for i, p := range peers { + pi[i] = ps.PeerInfo(p) + } + return pi +} + +func PeerInfoIDs(pis []PeerInfo) peer.IDSlice { + ps := make(peer.IDSlice, len(pis)) + for i, pi := range pis { + ps[i] = pi.ID + } + return ps +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go new file mode 100644 index 00000000..a497821d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go @@ -0,0 +1,401 @@ +package pstoremem + +import ( + "context" + "sort" + "sync" + "time" + + logging "github.com/ipfs/go-log" + peer "github.com/libp2p/go-libp2p-peer" + ma "github.com/multiformats/go-multiaddr" + + pstore "github.com/libp2p/go-libp2p-peerstore" + addr "github.com/libp2p/go-libp2p-peerstore/addr" +) + +var log = logging.Logger("peerstore") + +type expiringAddr struct { + Addr ma.Multiaddr + TTL time.Duration + Expires time.Time +} + +func (e *expiringAddr) ExpiredBy(t time.Time) bool { + return t.After(e.Expires) +} + +type addrSegments [256]*addrSegment + +type addrSegment struct { + sync.RWMutex + + // Use pointers to save memory. Maps always leave some fraction of their + // space unused. storing the *values* directly in the map will + // drastically increase the space waste. In our case, by 6x. + addrs map[peer.ID]map[string]*expiringAddr +} + +func (s *addrSegments) get(p peer.ID) *addrSegment { + return s[byte(p[len(p)-1])] +} + +// memoryAddrBook manages addresses. +type memoryAddrBook struct { + segments addrSegments + + ctx context.Context + cancel func() + + subManager *AddrSubManager +} + +var _ pstore.AddrBook = (*memoryAddrBook)(nil) + +func NewAddrBook() pstore.AddrBook { + ctx, cancel := context.WithCancel(context.Background()) + + ab := &memoryAddrBook{ + segments: func() (ret addrSegments) { + for i, _ := range ret { + ret[i] = &addrSegment{addrs: make(map[peer.ID]map[string]*expiringAddr)} + } + return ret + }(), + subManager: NewAddrSubManager(), + ctx: ctx, + cancel: cancel, + } + + go ab.background() + return ab +} + +// background periodically schedules a gc +func (mab *memoryAddrBook) background() { + ticker := time.NewTicker(1 * time.Hour) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + mab.gc() + + case <-mab.ctx.Done(): + return + } + } +} + +func (mab *memoryAddrBook) Close() error { + mab.cancel() + return nil +} + +// gc garbage collects the in-memory address book. +func (mab *memoryAddrBook) gc() { + now := time.Now() + for _, s := range mab.segments { + s.Lock() + for p, amap := range s.addrs { + for k, addr := range amap { + if addr.ExpiredBy(now) { + delete(amap, k) + } + } + if len(amap) == 0 { + delete(s.addrs, p) + } + } + s.Unlock() + } + +} + +func (mab *memoryAddrBook) PeersWithAddrs() peer.IDSlice { + var pids peer.IDSlice + for _, s := range mab.segments { + s.RLock() + for pid, _ := range s.addrs { + pids = append(pids, pid) + } + s.RUnlock() + } + return pids +} + +// AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl) +func (mab *memoryAddrBook) AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) { + mab.AddAddrs(p, []ma.Multiaddr{addr}, ttl) +} + +// AddAddrs gives memoryAddrBook addresses to use, with a given ttl +// (time-to-live), after which the address is no longer valid. +// If the manager has a longer TTL, the operation is a no-op for that address +func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) { + // if ttl is zero, exit. nothing to do. + if ttl <= 0 { + return + } + + s := mab.segments.get(p) + s.Lock() + defer s.Unlock() + + amap := s.addrs[p] + if amap == nil { + amap = make(map[string]*expiringAddr, len(addrs)) + s.addrs[p] = amap + } + exp := time.Now().Add(ttl) + for _, addr := range addrs { + if addr == nil { + log.Warningf("was passed nil multiaddr for %s", p) + continue + } + addrstr := string(addr.Bytes()) + a, found := amap[addrstr] + if !found || exp.After(a.Expires) { + amap[addrstr] = &expiringAddr{Addr: addr, Expires: exp, TTL: ttl} + + mab.subManager.BroadcastAddr(p, addr) + } + } +} + +// SetAddr calls mgr.SetAddrs(p, addr, ttl) +func (mab *memoryAddrBook) SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) { + mab.SetAddrs(p, []ma.Multiaddr{addr}, ttl) +} + +// SetAddrs sets the ttl on addresses. This clears any TTL there previously. +// This is used when we receive the best estimate of the validity of an address. +func (mab *memoryAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) { + s := mab.segments.get(p) + s.Lock() + defer s.Unlock() + + amap := s.addrs[p] + if amap == nil { + amap = make(map[string]*expiringAddr, len(addrs)) + s.addrs[p] = amap + } + + exp := time.Now().Add(ttl) + for _, addr := range addrs { + if addr == nil { + log.Warningf("was passed nil multiaddr for %s", p) + continue + } + // re-set all of them for new ttl. + addrstr := string(addr.Bytes()) + + if ttl > 0 { + amap[addrstr] = &expiringAddr{Addr: addr, Expires: exp, TTL: ttl} + mab.subManager.BroadcastAddr(p, addr) + } else { + delete(amap, addrstr) + } + } +} + +// UpdateAddrs updates the addresses associated with the given peer that have +// the given oldTTL to have the given newTTL. +func (mab *memoryAddrBook) UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration) { + s := mab.segments.get(p) + s.Lock() + defer s.Unlock() + + amap, found := s.addrs[p] + if !found { + return + } + + exp := time.Now().Add(newTTL) + for k, addr := range amap { + if oldTTL == addr.TTL { + addr.TTL = newTTL + addr.Expires = exp + amap[k] = addr + } + } +} + +// Addresses returns all known (and valid) addresses for a given +func (mab *memoryAddrBook) Addrs(p peer.ID) []ma.Multiaddr { + s := mab.segments.get(p) + s.RLock() + defer s.RUnlock() + + amap, found := s.addrs[p] + if !found { + return nil + } + + now := time.Now() + good := make([]ma.Multiaddr, 0, len(amap)) + for _, m := range amap { + if !m.ExpiredBy(now) { + good = append(good, m.Addr) + } + } + + return good +} + +// ClearAddrs removes all previously stored addresses +func (mab *memoryAddrBook) ClearAddrs(p peer.ID) { + s := mab.segments.get(p) + s.Lock() + defer s.Unlock() + + delete(s.addrs, p) +} + +// AddrStream returns a channel on which all new addresses discovered for a +// given peer ID will be published. +func (mab *memoryAddrBook) AddrStream(ctx context.Context, p peer.ID) <-chan ma.Multiaddr { + s := mab.segments.get(p) + s.RLock() + defer s.RUnlock() + + baseaddrslice := s.addrs[p] + initial := make([]ma.Multiaddr, 0, len(baseaddrslice)) + for _, a := range baseaddrslice { + initial = append(initial, a.Addr) + } + + return mab.subManager.AddrStream(ctx, p, initial) +} + +type addrSub struct { + pubch chan ma.Multiaddr + lk sync.Mutex + buffer []ma.Multiaddr + ctx context.Context +} + +func (s *addrSub) pubAddr(a ma.Multiaddr) { + select { + case s.pubch <- a: + case <-s.ctx.Done(): + } +} + +// An abstracted, pub-sub manager for address streams. Extracted from +// memoryAddrBook in order to support additional implementations. +type AddrSubManager struct { + mu sync.RWMutex + subs map[peer.ID][]*addrSub +} + +// NewAddrSubManager initializes an AddrSubManager. +func NewAddrSubManager() *AddrSubManager { + return &AddrSubManager{ + subs: make(map[peer.ID][]*addrSub), + } +} + +// Used internally by the address stream coroutine to remove a subscription +// from the manager. +func (mgr *AddrSubManager) removeSub(p peer.ID, s *addrSub) { + mgr.mu.Lock() + defer mgr.mu.Unlock() + + subs := mgr.subs[p] + if len(subs) == 1 { + if subs[0] != s { + return + } + delete(mgr.subs, p) + return + } + + for i, v := range subs { + if v == s { + subs[i] = subs[len(subs)-1] + subs[len(subs)-1] = nil + mgr.subs[p] = subs[:len(subs)-1] + return + } + } +} + +// BroadcastAddr broadcasts a new address to all subscribed streams. +func (mgr *AddrSubManager) BroadcastAddr(p peer.ID, addr ma.Multiaddr) { + mgr.mu.RLock() + defer mgr.mu.RUnlock() + + if subs, ok := mgr.subs[p]; ok { + for _, sub := range subs { + sub.pubAddr(addr) + } + } +} + +// AddrStream creates a new subscription for a given peer ID, pre-populating the +// channel with any addresses we might already have on file. +func (mgr *AddrSubManager) AddrStream(ctx context.Context, p peer.ID, initial []ma.Multiaddr) <-chan ma.Multiaddr { + sub := &addrSub{pubch: make(chan ma.Multiaddr), ctx: ctx} + out := make(chan ma.Multiaddr) + + mgr.mu.Lock() + if _, ok := mgr.subs[p]; ok { + mgr.subs[p] = append(mgr.subs[p], sub) + } else { + mgr.subs[p] = []*addrSub{sub} + } + mgr.mu.Unlock() + + sort.Sort(addr.AddrList(initial)) + + go func(buffer []ma.Multiaddr) { + defer close(out) + + sent := make(map[string]bool, len(buffer)) + var outch chan ma.Multiaddr + + for _, a := range buffer { + sent[string(a.Bytes())] = true + } + + var next ma.Multiaddr + if len(buffer) > 0 { + next = buffer[0] + buffer = buffer[1:] + outch = out + } + + for { + select { + case outch <- next: + if len(buffer) > 0 { + next = buffer[0] + buffer = buffer[1:] + } else { + outch = nil + next = nil + } + case naddr := <-sub.pubch: + if sent[string(naddr.Bytes())] { + continue + } + + sent[string(naddr.Bytes())] = true + if next == nil { + next = naddr + outch = out + } else { + buffer = append(buffer, naddr) + } + case <-ctx.Done(): + mgr.removeSub(p, sub) + return + } + } + + }(initial) + + return out +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go new file mode 100644 index 00000000..87baea24 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go @@ -0,0 +1,93 @@ +package pstoremem + +import ( + "errors" + "sync" + + ic "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" + + pstore "github.com/libp2p/go-libp2p-peerstore" +) + +type memoryKeyBook struct { + sync.RWMutex // same lock. wont happen a ton. + pks map[peer.ID]ic.PubKey + sks map[peer.ID]ic.PrivKey +} + +var _ pstore.KeyBook = (*memoryKeyBook)(nil) + +// noop new, but in the future we may want to do some init work. +func NewKeyBook() pstore.KeyBook { + return &memoryKeyBook{ + pks: map[peer.ID]ic.PubKey{}, + sks: map[peer.ID]ic.PrivKey{}, + } +} + +func (mkb *memoryKeyBook) PeersWithKeys() peer.IDSlice { + mkb.RLock() + ps := make(peer.IDSlice, 0, len(mkb.pks)+len(mkb.sks)) + for p := range mkb.pks { + ps = append(ps, p) + } + for p := range mkb.sks { + if _, found := mkb.pks[p]; !found { + ps = append(ps, p) + } + } + mkb.RUnlock() + return ps +} + +func (mkb *memoryKeyBook) PubKey(p peer.ID) ic.PubKey { + mkb.RLock() + pk := mkb.pks[p] + mkb.RUnlock() + if pk != nil { + return pk + } + pk, err := p.ExtractPublicKey() + if err == nil { + mkb.Lock() + mkb.pks[p] = pk + mkb.Unlock() + } + return pk +} + +func (mkb *memoryKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error { + // check it's correct first + if !p.MatchesPublicKey(pk) { + return errors.New("ID does not match PublicKey") + } + + mkb.Lock() + mkb.pks[p] = pk + mkb.Unlock() + return nil +} + +func (mkb *memoryKeyBook) PrivKey(p peer.ID) ic.PrivKey { + mkb.RLock() + sk := mkb.sks[p] + mkb.RUnlock() + return sk +} + +func (mkb *memoryKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error { + if sk == nil { + return errors.New("sk is nil (PrivKey)") + } + + // check it's correct first + if !p.MatchesPrivateKey(sk) { + return errors.New("ID does not match PrivateKey") + } + + mkb.Lock() + mkb.sks[p] = sk + mkb.Unlock() + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go new file mode 100644 index 00000000..162bee50 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go @@ -0,0 +1,45 @@ +package pstoremem + +import ( + "sync" + + peer "github.com/libp2p/go-libp2p-peer" + pstore "github.com/libp2p/go-libp2p-peerstore" +) + +type metakey struct { + id peer.ID + key string +} + +type memoryPeerMetadata struct { + // store other data, like versions + //ds ds.ThreadSafeDatastore + ds map[metakey]interface{} + dslock sync.RWMutex +} + +var _ pstore.PeerMetadata = (*memoryPeerMetadata)(nil) + +func NewPeerMetadata() pstore.PeerMetadata { + return &memoryPeerMetadata{ + ds: make(map[metakey]interface{}), + } +} + +func (ps *memoryPeerMetadata) Put(p peer.ID, key string, val interface{}) error { + ps.dslock.Lock() + defer ps.dslock.Unlock() + ps.ds[metakey{p, key}] = val + return nil +} + +func (ps *memoryPeerMetadata) Get(p peer.ID, key string) (interface{}, error) { + ps.dslock.RLock() + defer ps.dslock.RUnlock() + i, ok := ps.ds[metakey{p, key}] + if !ok { + return nil, pstore.ErrNotFound + } + return i, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go new file mode 100644 index 00000000..c7cbd672 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go @@ -0,0 +1,12 @@ +package pstoremem + +import pstore "github.com/libp2p/go-libp2p-peerstore" + +// NewPeerstore creates an in-memory threadsafe collection of peers. +func NewPeerstore() pstore.Peerstore { + return pstore.NewPeerstore( + NewKeyBook(), + NewAddrBook(), + NewProtoBook(), + NewPeerMetadata()) +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go new file mode 100644 index 00000000..04cd1459 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go @@ -0,0 +1,142 @@ +package pstoremem + +import ( + "sync" + + peer "github.com/libp2p/go-libp2p-peer" + + pstore "github.com/libp2p/go-libp2p-peerstore" +) + +const ( + maxInternedProtocols = 512 + maxInternedProtocolSize = 256 +) + +type protoSegment struct { + sync.RWMutex + protocols map[peer.ID]map[string]struct{} +} + +type protoSegments [256]*protoSegment + +func (s *protoSegments) get(p peer.ID) *protoSegment { + return s[byte(p[len(p)-1])] +} + +type memoryProtoBook struct { + segments protoSegments + + lk sync.RWMutex + interned map[string]string +} + +var _ pstore.ProtoBook = (*memoryProtoBook)(nil) + +func NewProtoBook() pstore.ProtoBook { + return &memoryProtoBook{ + interned: make(map[string]string, maxInternedProtocols), + segments: func() (ret protoSegments) { + for i := range ret { + ret[i] = &protoSegment{ + protocols: make(map[peer.ID]map[string]struct{}), + } + } + return ret + }(), + } +} + +func (pb *memoryProtoBook) internProtocol(proto string) string { + if len(proto) > maxInternedProtocolSize { + return proto + } + + // check if it is interned with the read lock + pb.lk.RLock() + interned, ok := pb.interned[proto] + pb.lk.RUnlock() + + if ok { + return interned + } + + // intern with the write lock + pb.lk.Lock() + defer pb.lk.Unlock() + + // check again in case it got interned in between locks + interned, ok = pb.interned[proto] + if ok { + return interned + } + + // if we've filled the table, throw it away and start over + if len(pb.interned) >= maxInternedProtocols { + pb.interned = make(map[string]string, maxInternedProtocols) + } + + pb.interned[proto] = proto + return proto +} + +func (pb *memoryProtoBook) SetProtocols(p peer.ID, protos ...string) error { + s := pb.segments.get(p) + s.Lock() + defer s.Unlock() + + newprotos := make(map[string]struct{}, len(protos)) + for _, proto := range protos { + newprotos[pb.internProtocol(proto)] = struct{}{} + } + + s.protocols[p] = newprotos + + return nil +} + +func (pb *memoryProtoBook) AddProtocols(p peer.ID, protos ...string) error { + s := pb.segments.get(p) + s.Lock() + defer s.Unlock() + + protomap, ok := s.protocols[p] + if !ok { + protomap = make(map[string]struct{}) + s.protocols[p] = protomap + } + + for _, proto := range protos { + protomap[pb.internProtocol(proto)] = struct{}{} + } + + return nil +} + +func (pb *memoryProtoBook) GetProtocols(p peer.ID) ([]string, error) { + s := pb.segments.get(p) + s.RLock() + defer s.RUnlock() + + out := make([]string, 0, len(s.protocols)) + for k := range s.protocols[p] { + out = append(out, k) + } + + return out, nil +} + +func (pb *memoryProtoBook) SupportsProtocols(p peer.ID, protos ...string) ([]string, error) { + s := pb.segments.get(p) + s.RLock() + defer s.RUnlock() + + out := make([]string, 0, len(protos)) + for _, proto := range protos { + if _, ok := s.protocols[p][proto]; ok { + out = append(out, proto) + } + } + + return out, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/queue/distance.go b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/distance.go new file mode 100644 index 00000000..9c3e026e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/distance.go @@ -0,0 +1,100 @@ +package queue + +import ( + "container/heap" + "math/big" + "sync" + + "github.com/libp2p/go-libp2p-peer" + ks "github.com/whyrusleeping/go-keyspace" +) + +// peerMetric tracks a peer and its distance to something else. +type peerMetric struct { + // the peer + peer peer.ID + + // big.Int for XOR metric + metric *big.Int +} + +// peerMetricHeap implements a heap of peerDistances +type peerMetricHeap []*peerMetric + +func (ph peerMetricHeap) Len() int { + return len(ph) +} + +func (ph peerMetricHeap) Less(i, j int) bool { + return -1 == ph[i].metric.Cmp(ph[j].metric) +} + +func (ph peerMetricHeap) Swap(i, j int) { + ph[i], ph[j] = ph[j], ph[i] +} + +func (ph *peerMetricHeap) Push(x interface{}) { + item := x.(*peerMetric) + *ph = append(*ph, item) +} + +func (ph *peerMetricHeap) Pop() interface{} { + old := *ph + n := len(old) + item := old[n-1] + *ph = old[0 : n-1] + return item +} + +// distancePQ implements heap.Interface and PeerQueue +type distancePQ struct { + // from is the Key this PQ measures against + from ks.Key + + // heap is a heap of peerDistance items + heap peerMetricHeap + + sync.RWMutex +} + +func (pq *distancePQ) Len() int { + pq.Lock() + defer pq.Unlock() + return len(pq.heap) +} + +func (pq *distancePQ) Enqueue(p peer.ID) { + pq.Lock() + defer pq.Unlock() + + distance := ks.XORKeySpace.Key([]byte(p)).Distance(pq.from) + + heap.Push(&pq.heap, &peerMetric{ + peer: p, + metric: distance, + }) +} + +func (pq *distancePQ) Dequeue() peer.ID { + pq.Lock() + defer pq.Unlock() + + if len(pq.heap) < 1 { + panic("called Dequeue on an empty PeerQueue") + // will panic internally anyway, but we can help debug here + } + + o := heap.Pop(&pq.heap) + p := o.(*peerMetric) + return p.peer +} + +// NewXORDistancePQ returns a PeerQueue which maintains its peers sorted +// in terms of their distances to each other in an XORKeySpace (i.e. using +// XOR as a metric of distance). +func NewXORDistancePQ(from string) PeerQueue { + return &distancePQ{ + from: ks.XORKeySpace.Key([]byte(from)), + heap: peerMetricHeap{}, + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/queue/interface.go b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/interface.go new file mode 100644 index 00000000..26e1d48b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/interface.go @@ -0,0 +1,18 @@ +package queue + +import "github.com/libp2p/go-libp2p-peer" + +// PeerQueue maintains a set of peers ordered according to a metric. +// Implementations of PeerQueue could order peers based on distances along +// a KeySpace, latency measurements, trustworthiness, reputation, etc. +type PeerQueue interface { + + // Len returns the number of items in PeerQueue + Len() int + + // Enqueue adds this node to the queue. + Enqueue(peer.ID) + + // Dequeue retrieves the highest (smallest int) priority node + Dequeue() peer.ID +} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/queue/sync.go b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/sync.go new file mode 100644 index 00000000..3815ec78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-peerstore/queue/sync.go @@ -0,0 +1,85 @@ +package queue + +import ( + "context" + + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p-peer" +) + +var log = logging.Logger("peerqueue") + +// ChanQueue makes any PeerQueue synchronizable through channels. +type ChanQueue struct { + Queue PeerQueue + EnqChan chan<- peer.ID + DeqChan <-chan peer.ID +} + +// NewChanQueue creates a ChanQueue by wrapping pq. +func NewChanQueue(ctx context.Context, pq PeerQueue) *ChanQueue { + cq := &ChanQueue{Queue: pq} + cq.process(ctx) + return cq +} + +func (cq *ChanQueue) process(ctx context.Context) { + // construct the channels here to be able to use them bidirectionally + enqChan := make(chan peer.ID) + deqChan := make(chan peer.ID) + + cq.EnqChan = enqChan + cq.DeqChan = deqChan + + go func() { + log.Debug("processing") + defer log.Debug("closed") + defer close(deqChan) + + var next peer.ID + var item peer.ID + var more bool + + for { + if cq.Queue.Len() == 0 { + // log.Debug("wait for enqueue") + select { + case next, more = <-enqChan: + if !more { + return + } + // log.Debug("got", next) + + case <-ctx.Done(): + return + } + + } else { + next = cq.Queue.Dequeue() + // log.Debug("peek", next) + } + + select { + case item, more = <-enqChan: + if !more { + if cq.Queue.Len() > 0 { + return // we're done done. + } + enqChan = nil // closed, so no use. + } + // log.Debug("got", item) + cq.Queue.Enqueue(item) + cq.Queue.Enqueue(next) // order may have changed. + next = "" + + case deqChan <- next: + // log.Debug("dequeued", next) + next = "" + + case <-ctx.Done(): + return + } + } + + }() +} diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/.travis.yml b/vendor/github.com/libp2p/go-libp2p-pnet/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/LICENSE b/vendor/github.com/libp2p/go-libp2p-pnet/LICENSE new file mode 100644 index 00000000..4ddb347c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jakub Sztandera + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/README.md b/vendor/github.com/libp2p/go-libp2p-pnet/README.md new file mode 100644 index 00000000..77ea2881 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/README.md @@ -0,0 +1,36 @@ +go-libp2p-pnet +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Travis CI](https://img.shields.io/travis/libp2p/go-libp2p-pnet.svg?style=flat-square&branch=master)](https://travis-ci.org/libp2p/go-libp2p-pnet) +[![codecov.io](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-pnet.svg?style=flat-square&branch=master)](https://codecov.io/github/libp2p/go-libp2p-pnet?branch=master) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> An implementation of go-libp2p-interface-pnet + + +## Table of Contents + +- [Usage](#usage) +- [Contribute](#contribute) +- [License](#license) + +## Usage + +See [Godocs](https://godoc.org/github.com/libp2p/go-libp2p-pnet) + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jakub Sztandera + +--- + +The last gx published version of this module was: 3.0.5: QmTwDsJUPioMKoiuXkAmiPxL1i4tjuG5vkxJgNpiHpXb3Y diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/codec.go b/vendor/github.com/libp2p/go-libp2p-pnet/codec.go new file mode 100644 index 00000000..19b929f6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/codec.go @@ -0,0 +1,66 @@ +package pnet + +import ( + "bufio" + "bytes" + "encoding/base64" + "encoding/hex" + "fmt" + "io" +) + +var ( + pathPSKv1 = []byte("/key/swarm/psk/1.0.0/") + pathBin = "/bin/" + pathBase16 = "/base16/" + pathBase64 = "/base64/" +) + +func readHeader(r *bufio.Reader) ([]byte, error) { + header, err := r.ReadBytes('\n') + if err != nil { + return nil, err + } + + return bytes.TrimRight(header, "\r\n"), nil +} + +func expectHeader(r *bufio.Reader, expected []byte) error { + header, err := readHeader(r) + if err != nil { + return err + } + if !bytes.Equal(header, expected) { + return fmt.Errorf("expected file header %s, got: %s", pathPSKv1, header) + } + return nil +} + +func decodeV1PSK(in io.Reader) (*[32]byte, error) { + reader := bufio.NewReader(in) + if err := expectHeader(reader, pathPSKv1); err != nil { + return nil, err + } + header, err := readHeader(reader) + if err != nil { + return nil, err + } + + var decoder io.Reader + switch string(header) { + case pathBase16: + decoder = hex.NewDecoder(reader) + case pathBase64: + decoder = base64.NewDecoder(base64.StdEncoding, reader) + case pathBin: + decoder = reader + default: + return nil, fmt.Errorf("unknown encoding: %s", header) + } + out := new([32]byte) + _, err = io.ReadFull(decoder, out[:]) + if err != nil { + return nil, err + } + return out, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/codecov.yml b/vendor/github.com/libp2p/go-libp2p-pnet/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/fingerprint.go b/vendor/github.com/libp2p/go-libp2p-pnet/fingerprint.go new file mode 100644 index 00000000..978a46b6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/fingerprint.go @@ -0,0 +1,24 @@ +package pnet + +import ( + "golang.org/x/crypto/salsa20" + "golang.org/x/crypto/sha3" +) + +var zero64 = make([]byte, 64) + +func fingerprint(psk *[32]byte) []byte { + enc := make([]byte, 64) + + // We encrypt data first so we don't feed PSK to hash function. + // Salsa20 function is not reversible thus increasing our security margin. + salsa20.XORKeyStream(enc, zero64, []byte("finprint"), psk) + + out := make([]byte, 16) + // Then do Shake-128 hash to reduce its length. + // This way if for some reason Shake is broken and Salsa20 preimage is possible, + // attacker has only half of the bytes necessary to recreate psk. + sha3.ShakeSum128(out, enc) + + return out +} diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/generate.go b/vendor/github.com/libp2p/go-libp2p-pnet/generate.go new file mode 100644 index 00000000..cf220ced --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/generate.go @@ -0,0 +1,38 @@ +package pnet + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "io" +) + +func newLine() io.Reader { + return bytes.NewReader([]byte("\n")) +} + +// GenerateV1PSK generates new PSK key that can be used with NewProtector +func GenerateV1PSK() (io.Reader, error) { + psk, err := GenerateV1Bytes() + if err != nil { + return nil, err + } + + hexPsk := make([]byte, len(psk)*2) + hex.Encode(hexPsk, psk[:]) + + // just a shortcut to NewReader + nr := func(b []byte) io.Reader { + return bytes.NewReader(b) + } + return io.MultiReader(nr(pathPSKv1), newLine(), nr([]byte("/base16/")), newLine(), nr(hexPsk)), nil +} + +func GenerateV1Bytes() (*[32]byte, error) { + psk := [32]byte{} + _, err := rand.Read(psk[:]) + if err != nil { + return nil, err + } + return &psk, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/go.mod b/vendor/github.com/libp2p/go-libp2p-pnet/go.mod new file mode 100644 index 00000000..6cd9a515 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-libp2p-pnet + +require ( + github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 + github.com/libp2p/go-buffer-pool v0.0.2 + github.com/libp2p/go-libp2p-core v0.0.1 + golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f +) diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/go.sum b/vendor/github.com/libp2p/go-libp2p-pnet/go.sum new file mode 100644 index 00000000..281a6348 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/go.sum @@ -0,0 +1,64 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 h1:6xT9KW8zLC5IlbaIF5Q7JNieBoACT7iW0YTxQHR0in0= +github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/protector.go b/vendor/github.com/libp2p/go-libp2p-pnet/protector.go new file mode 100644 index 00000000..8b8d2dd0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/protector.go @@ -0,0 +1,41 @@ +package pnet + +import ( + "fmt" + "io" + "net" + + ipnet "github.com/libp2p/go-libp2p-core/pnet" +) + +var _ ipnet.Protector = (*protector)(nil) + +// NewProtector creates ipnet.Protector instance from a io.Reader stream +// that should include Multicodec encoded V1 PSK. +func NewProtector(input io.Reader) (ipnet.Protector, error) { + psk, err := decodeV1PSK(input) + if err != nil { + return nil, fmt.Errorf("malformed private network key: %s", err) + } + return NewV1ProtectorFromBytes(psk) +} + +// NewV1ProtectorFromBytes creates ipnet.Protector of the V1 version. +func NewV1ProtectorFromBytes(psk *[32]byte) (ipnet.Protector, error) { + return &protector{ + psk: psk, + fingerprint: fingerprint(psk), + }, nil +} + +type protector struct { + psk *[32]byte + fingerprint []byte +} + +func (p protector) Protect(in net.Conn) (net.Conn, error) { + return newPSKConn(p.psk, in) +} +func (p protector) Fingerprint() []byte { + return p.fingerprint +} diff --git a/vendor/github.com/libp2p/go-libp2p-pnet/psk_conn.go b/vendor/github.com/libp2p/go-libp2p-pnet/psk_conn.go new file mode 100644 index 00000000..5d35d879 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pnet/psk_conn.go @@ -0,0 +1,83 @@ +package pnet + +import ( + "crypto/cipher" + "crypto/rand" + "io" + "net" + + "github.com/libp2p/go-libp2p-core/pnet" + + "github.com/davidlazar/go-crypto/salsa20" + pool "github.com/libp2p/go-buffer-pool" +) + +// we are using buffer pool as user needs their slice back +// so we can't do XOR cripter in place +var ( + errShortNonce = pnet.NewError("could not read full nonce") + errInsecureNil = pnet.NewError("insecure is nil") + errPSKNil = pnet.NewError("pre-shread key is nil") +) + +type pskConn struct { + net.Conn + psk *[32]byte + + writeS20 cipher.Stream + readS20 cipher.Stream +} + +func (c *pskConn) Read(out []byte) (int, error) { + if c.readS20 == nil { + nonce := make([]byte, 24) + _, err := io.ReadFull(c.Conn, nonce) + if err != nil { + return 0, errShortNonce + } + c.readS20 = salsa20.New(c.psk, nonce) + } + + n, err := c.Conn.Read(out) // read to in + if n > 0 { + c.readS20.XORKeyStream(out[:n], out[:n]) // decrypt to out buffer + } + return n, err +} + +func (c *pskConn) Write(in []byte) (int, error) { + if c.writeS20 == nil { + nonce := make([]byte, 24) + _, err := rand.Read(nonce) + if err != nil { + return 0, err + } + _, err = c.Conn.Write(nonce) + if err != nil { + return 0, err + } + + c.writeS20 = salsa20.New(c.psk, nonce) + } + out := pool.Get(len(in)) + defer pool.Put(out) + + c.writeS20.XORKeyStream(out, in) // encrypt + + return c.Conn.Write(out) // send +} + +var _ net.Conn = (*pskConn)(nil) + +func newPSKConn(psk *[32]byte, insecure net.Conn) (net.Conn, error) { + if insecure == nil { + return nil, errInsecureNil + } + if psk == nil { + return nil, errPSKNil + } + return &pskConn{ + Conn: insecure, + psk: psk, + }, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/.travis.yml b/vendor/github.com/libp2p/go-libp2p-pubsub-router/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/LICENSE b/vendor/github.com/libp2p/go-libp2p-pubsub-router/LICENSE new file mode 100644 index 00000000..6cccfc2b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/README.md b/vendor/github.com/libp2p/go-libp2p-pubsub-router/README.md new file mode 100644 index 00000000..00890fdd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/README.md @@ -0,0 +1,35 @@ +# go-libp2p-pubsub-router + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-pubsub-router?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-pubsub-router) +[![Coverage Status](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-pubsub-router.svg?style=flat-square&branch=master)](https://codecov.io/github/libp2p/go-libp2p-pubsub-router?branch=master) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-pubsub-router.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-pubsub-router) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A libp2p router that uses pubsub. + +We currently only use this for IPNS over PubSub. + +## Documenation + +See https://godoc.org/github.com/libp2p/go-libp2p-pubsub-router. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-pubsub-router/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 0.5.18: QmaHVH3EqQD6DsE1yPgwfCThvFCwfkJ396uyrRSo3Ku1kH diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.mod b/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.mod new file mode 100644 index 00000000..6b013d63 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.mod @@ -0,0 +1,15 @@ +module github.com/libp2p/go-libp2p-pubsub-router + +require ( + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs-ds-help v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-pubsub v0.1.0 + github.com/libp2p/go-libp2p-record v0.1.0 + github.com/libp2p/go-libp2p-routing-helpers v0.1.0 + github.com/libp2p/go-libp2p-swarm v0.1.0 +) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.sum b/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.sum new file mode 100644 index 00000000..6479b98a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/go.sum @@ -0,0 +1,231 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5 h1:q3OfiOZV5rlsK1H5V8benjeUApRfMGs4Mrhmr6NriQo= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-pubsub v0.1.0 h1:SmQeMa7IUv5vadh0fYgYsafWCBA1sCy5d/68kIYqGcU= +github.com/libp2p/go-libp2p-pubsub v0.1.0/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-routing-helpers v0.1.0 h1:BaFvpyv8TyhCN7TihawTiKuzeu8/Pyw7ZnMA4IvqIN8= +github.com/libp2p/go-libp2p-routing-helpers v0.1.0/go.mod h1:oUs0h39vNwYtYXnQWOTU5BaafbedSyWCCal3gqHuoOQ= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub-router/pubsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub-router/pubsub.go new file mode 100644 index 00000000..7023cb35 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub-router/pubsub.go @@ -0,0 +1,385 @@ +package namesys + +import ( + "bytes" + "context" + "encoding/base64" + "errors" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + pubsub "github.com/libp2p/go-libp2p-pubsub" + record "github.com/libp2p/go-libp2p-record" + + "github.com/ipfs/go-cid" + ds "github.com/ipfs/go-datastore" + dssync "github.com/ipfs/go-datastore/sync" + dshelp "github.com/ipfs/go-ipfs-ds-help" + u "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("pubsub-valuestore") + +type watchGroup struct { + // Note: this chan must be buffered, see notifyWatchers + listeners map[chan []byte]struct{} +} + +type PubsubValueStore struct { + ctx context.Context + ds ds.Datastore + host host.Host + cr routing.ContentRouting + ps *pubsub.PubSub + + // Map of keys to subscriptions. + // + // If a key is present but the subscription is nil, we've bootstrapped + // but haven't subscribed. + mx sync.Mutex + subs map[string]*pubsub.Subscription + + watchLk sync.Mutex + watching map[string]*watchGroup + + Validator record.Validator +} + +// KeyToTopic converts a binary record key to a pubsub topic key. +func KeyToTopic(key string) string { + // Record-store keys are arbitrary binary. However, pubsub requires UTF-8 string topic IDs. + // Encodes to "/record/base64url(key)" + return "/record/" + base64.RawURLEncoding.EncodeToString([]byte(key)) +} + +// NewPubsubPublisher constructs a new Publisher that publishes IPNS records through pubsub. +// The constructor interface is complicated by the need to bootstrap the pubsub topic. +// This could be greatly simplified if the pubsub implementation handled bootstrap itself +func NewPubsubValueStore(ctx context.Context, host host.Host, cr routing.ContentRouting, ps *pubsub.PubSub, validator record.Validator) *PubsubValueStore { + return &PubsubValueStore{ + ctx: ctx, + + ds: dssync.MutexWrap(ds.NewMapDatastore()), + host: host, // needed for pubsub bootstrap + cr: cr, // needed for pubsub bootstrap + ps: ps, + + subs: make(map[string]*pubsub.Subscription), + watching: make(map[string]*watchGroup), + + Validator: validator, + } +} + +// Publish publishes an IPNS record through pubsub with default TTL +func (p *PubsubValueStore) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error { + // Record-store keys are arbitrary binary. However, pubsub requires UTF-8 string topic IDs. + // Encode to "/record/base64url(key)" + topic := KeyToTopic(key) + + if err := p.Subscribe(key); err != nil { + return err + } + + log.Debugf("PubsubPublish: publish value for key", key) + return p.ps.Publish(topic, value) +} + +func (p *PubsubValueStore) isBetter(key string, val []byte) bool { + if p.Validator.Validate(key, val) != nil { + return false + } + + old, err := p.getLocal(key) + if err != nil { + // If the old one is invalid, the new one is *always* better. + return true + } + + // Same record. Possible DoS vector, should consider failing? + if bytes.Equal(old, val) { + return true + } + + i, err := p.Validator.Select(key, [][]byte{val, old}) + return err == nil && i == 0 +} + +func (p *PubsubValueStore) Subscribe(key string) error { + p.mx.Lock() + // see if we already have a pubsub subscription; if not, subscribe + sub := p.subs[key] + p.mx.Unlock() + + if sub != nil { + return nil + } + + topic := KeyToTopic(key) + + // Ignore the error. We have to check again anyways to make sure the + // record hasn't expired. + // + // Also, make sure to do this *before* subscribing. + p.ps.RegisterTopicValidator(topic, func(ctx context.Context, _ peer.ID, msg *pubsub.Message) bool { + return p.isBetter(key, msg.GetData()) + }) + + sub, err := p.ps.Subscribe(topic) + if err != nil { + p.mx.Unlock() + return err + } + + p.mx.Lock() + existingSub, bootstraped := p.subs[key] + if existingSub != nil { + p.mx.Unlock() + sub.Cancel() + return nil + } + + p.subs[key] = sub + ctx, cancel := context.WithCancel(p.ctx) + go p.handleSubscription(sub, key, cancel) + p.mx.Unlock() + + log.Debugf("PubsubResolve: subscribed to %s", key) + + if !bootstraped { + // TODO: Deal with publish then resolve case? Cancel behaviour changes. + go bootstrapPubsub(ctx, p.cr, p.host, topic) + } + return nil +} + +func (p *PubsubValueStore) getLocal(key string) ([]byte, error) { + val, err := p.ds.Get(dshelp.NewKeyFromBinary([]byte(key))) + if err != nil { + // Don't invalidate due to ds errors. + if err == ds.ErrNotFound { + err = routing.ErrNotFound + } + return nil, err + } + + // If the old one is invalid, the new one is *always* better. + if err := p.Validator.Validate(key, val); err != nil { + return nil, err + } + return val, nil +} + +func (p *PubsubValueStore) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + if err := p.Subscribe(key); err != nil { + return nil, err + } + + return p.getLocal(key) +} + +func (p *PubsubValueStore) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + if err := p.Subscribe(key); err != nil { + return nil, err + } + + p.watchLk.Lock() + defer p.watchLk.Unlock() + + out := make(chan []byte, 1) + lv, err := p.getLocal(key) + if err == nil { + out <- lv + close(out) + return out, nil + } + + wg, ok := p.watching[key] + if !ok { + wg = &watchGroup{ + listeners: map[chan []byte]struct{}{}, + } + p.watching[key] = wg + } + + proxy := make(chan []byte, 1) + + ctx, cancel := context.WithCancel(ctx) + wg.listeners[proxy] = struct{}{} + + go func() { + defer func() { + cancel() + + p.watchLk.Lock() + delete(wg.listeners, proxy) + + if _, ok := p.watching[key]; len(wg.listeners) == 0 && ok { + delete(p.watching, key) + } + p.watchLk.Unlock() + + close(out) + }() + + for { + select { + case val, ok := <-proxy: + if !ok { + return + } + + // outCh is buffered, so we just put the value or swap it for the newer one + select { + case out <- val: + case <-out: + out <- val + } + + // 1 is good enough + return + case <-ctx.Done(): + return + } + } + }() + + return out, nil +} + +// GetSubscriptions retrieves a list of active topic subscriptions +func (p *PubsubValueStore) GetSubscriptions() []string { + p.mx.Lock() + defer p.mx.Unlock() + + var res []string + for sub := range p.subs { + res = append(res, sub) + } + + return res +} + +// Cancel cancels a topic subscription; returns true if an active +// subscription was canceled +func (p *PubsubValueStore) Cancel(name string) (bool, error) { + p.mx.Lock() + defer p.mx.Unlock() + + p.watchLk.Lock() + if _, wok := p.watching[name]; wok { + p.watchLk.Unlock() + return false, errors.New("key has active subscriptions") + } + p.watchLk.Unlock() + + sub, ok := p.subs[name] + if ok { + sub.Cancel() + delete(p.subs, name) + } + + return ok, nil +} + +func (p *PubsubValueStore) handleSubscription(sub *pubsub.Subscription, key string, cancel func()) { + defer sub.Cancel() + defer cancel() + + for { + msg, err := sub.Next(p.ctx) + if err != nil { + if err != context.Canceled { + log.Warningf("PubsubResolve: subscription error in %s: %s", key, err.Error()) + } + return + } + if p.isBetter(key, msg.GetData()) { + err := p.ds.Put(dshelp.NewKeyFromBinary([]byte(key)), msg.GetData()) + if err != nil { + log.Warningf("PubsubResolve: error writing update for %s: %s", key, err) + } + p.notifyWatchers(key, msg.GetData()) + } + } +} + +func (p *PubsubValueStore) notifyWatchers(key string, data []byte) { + p.watchLk.Lock() + defer p.watchLk.Unlock() + sg, ok := p.watching[key] + if !ok { + return + } + + for watcher := range sg.listeners { + select { + case <-watcher: + watcher <- data + case watcher <- data: + } + } +} + +// rendezvous with peers in the name topic through provider records +// Note: rendezvous/boostrap should really be handled by the pubsub implementation itself! +func bootstrapPubsub(ctx context.Context, cr routing.ContentRouting, host host.Host, name string) { + // TODO: consider changing this to `pubsub:...` + topic := "floodsub:" + name + hash := u.Hash([]byte(topic)) + rz := cid.NewCidV1(cid.Raw, hash) + + go func() { + err := cr.Provide(ctx, rz, true) + if err != nil { + log.Warningf("bootstrapPubsub: error providing rendezvous for %s: %s", topic, err.Error()) + } + + for { + select { + case <-time.After(8 * time.Hour): + err := cr.Provide(ctx, rz, true) + if err != nil { + log.Warningf("bootstrapPubsub: error providing rendezvous for %s: %s", topic, err.Error()) + } + case <-ctx.Done(): + return + } + } + }() + + rzctx, cancel := context.WithTimeout(ctx, time.Second*10) + defer cancel() + + wg := &sync.WaitGroup{} + for pi := range cr.FindProvidersAsync(rzctx, rz, 10) { + if pi.ID == host.ID() { + continue + } + wg.Add(1) + go func(pi peer.AddrInfo) { + defer wg.Done() + + ctx, cancel := context.WithTimeout(ctx, time.Second*10) + defer cancel() + + err := host.Connect(ctx, pi) + if err != nil { + log.Debugf("Error connecting to pubsub peer %s: %s", pi.ID, err.Error()) + return + } + + // delay to let pubsub perform its handshake + time.Sleep(time.Millisecond * 250) + + log.Debugf("Connected to pubsub peer %s", pi.ID) + }(pi) + } + + wg.Wait() +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/.gitignore b/vendor/github.com/libp2p/go-libp2p-pubsub/.gitignore new file mode 100644 index 00000000..5b98de78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/.gitignore @@ -0,0 +1,3 @@ +cover.out +prof.out +go-floodsub.test diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/.travis.yml b/vendor/github.com/libp2p/go-libp2p-pubsub/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/LICENSE b/vendor/github.com/libp2p/go-libp2p-pubsub/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/README.md b/vendor/github.com/libp2p/go-libp2p-pubsub/README.md new file mode 100644 index 00000000..c571e7c4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/README.md @@ -0,0 +1,60 @@ +# go-libp2p-pubsub + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://github.com/libp2p/libp2p) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A pubsub system with flooding and gossiping variants. + +This is the canonical pubsub implementation for libp2p. + +We currently provide three implementations: +- floodsub, which is the baseline flooding protocol. +- gossipsub, which is a more advanced router with mesh formation and gossip propagation. + See [spec](https://github.com/libp2p/specs/tree/master/pubsub/gossipsub) and [implementation](https://github.com/libp2p/go-libp2p-pubsub/blob/master/gossipsub.go) for more details. +- randomsub, which is a simple probabilistic router that propagates to random subsets of peers. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Documentation](#documentation) +- [Contribute](#contribute) +- [License](#license) + +## Install + +``` +go get github.com/libp2p/go-libp2p-pubsub +``` + +## Usage + +To be used for messaging in p2p instrastructure (as part of libp2p) such as IPFS, Ethereum, other blockchains, etc. + +## Implementations + +See [libp2p/specs/pubsub#Implementations](https://github.com/libp2p/specs/tree/master/pubsub#Implementations). + +## Documentation + +See the [libp2p specs](https://github.com/libp2p/specs/tree/master/pubsub) for high level documentation +and [godoc](https://godoc.org/github.com/libp2p/go-libp2p-pubsub) for API documentation. + + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/libp2p/go-libp2p-pubsub/issues). + +Check out our [contributing document](https://github.com/libp2p/community/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © Jeromy Johnson + +--- + +The last gx published version of this module was: 0.11.16: QmfB4oDUTiaGEqT13P1JqCEhqW7cB1wpKtq3PP4BN8PhQd diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go b/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go new file mode 100644 index 00000000..ba747d81 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go @@ -0,0 +1,53 @@ +package pubsub + +import ( + lru "github.com/hashicorp/golang-lru" + "github.com/libp2p/go-libp2p-core/peer" +) + +// Blacklist is an interface for peer blacklisting. +type Blacklist interface { + Add(peer.ID) + Contains(peer.ID) bool +} + +// MapBlacklist is a blacklist implementation using a perfect map +type MapBlacklist map[peer.ID]struct{} + +// NewMapBlacklist creates a new MapBlacklist +func NewMapBlacklist() Blacklist { + return MapBlacklist(make(map[peer.ID]struct{})) +} + +func (b MapBlacklist) Add(p peer.ID) { + b[p] = struct{}{} +} + +func (b MapBlacklist) Contains(p peer.ID) bool { + _, ok := b[p] + return ok +} + +// LRUBlacklist is a blacklist implementation using an LRU cache +type LRUBlacklist struct { + lru *lru.Cache +} + +// NewLRUBlacklist creates a new LRUBlacklist with capacity cap +func NewLRUBlacklist(cap int) (Blacklist, error) { + c, err := lru.New(cap) + if err != nil { + return nil, err + } + + b := &LRUBlacklist{lru: c} + return b, nil +} + +func (b LRUBlacklist) Add(p peer.ID) { + b.lru.Add(p, nil) +} + +func (b LRUBlacklist) Contains(p peer.ID) bool { + return b.lru.Contains(p) +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/codecov.yml b/vendor/github.com/libp2p/go-libp2p-pubsub/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go b/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go new file mode 100644 index 00000000..d0d40da5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go @@ -0,0 +1,174 @@ +package pubsub + +import ( + "bufio" + "context" + "io" + + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + ggio "github.com/gogo/protobuf/io" + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + ms "github.com/multiformats/go-multistream" +) + +// get the initial RPC containing all of our subscriptions to send to new peers +func (p *PubSub) getHelloPacket() *RPC { + var rpc RPC + for t := range p.myTopics { + as := &pb.RPC_SubOpts{ + Topicid: proto.String(t), + Subscribe: proto.Bool(true), + } + rpc.Subscriptions = append(rpc.Subscriptions, as) + } + return &rpc +} + +func (p *PubSub) handleNewStream(s network.Stream) { + r := ggio.NewDelimitedReader(s, 1<<20) + for { + rpc := new(RPC) + err := r.ReadMsg(&rpc.RPC) + if err != nil { + if err != io.EOF { + s.Reset() + log.Infof("error reading rpc from %s: %s", s.Conn().RemotePeer(), err) + } else { + // Just be nice. They probably won't read this + // but it doesn't hurt to send it. + s.Close() + } + return + } + + rpc.from = s.Conn().RemotePeer() + select { + case p.incoming <- rpc: + case <-p.ctx.Done(): + // Close is useless because the other side isn't reading. + s.Reset() + return + } + } +} + +func (p *PubSub) handleNewPeer(ctx context.Context, pid peer.ID, outgoing <-chan *RPC) { + s, err := p.host.NewStream(p.ctx, pid, p.rt.Protocols()...) + if err != nil { + log.Warning("opening new stream to peer: ", err, pid) + + var ch chan peer.ID + if err == ms.ErrNotSupported { + ch = p.newPeerError + } else { + ch = p.peerDead + } + + select { + case ch <- pid: + case <-ctx.Done(): + } + return + } + + go p.handleSendingMessages(ctx, s, outgoing) + go p.handlePeerEOF(ctx, s) + select { + case p.newPeerStream <- s: + case <-ctx.Done(): + } +} + +func (p *PubSub) handlePeerEOF(ctx context.Context, s network.Stream) { + r := ggio.NewDelimitedReader(s, 1<<20) + rpc := new(RPC) + for { + err := r.ReadMsg(&rpc.RPC) + if err != nil { + select { + case p.peerDead <- s.Conn().RemotePeer(): + case <-ctx.Done(): + } + return + } + log.Warning("unexpected message from ", s.Conn().RemotePeer()) + } +} + +func (p *PubSub) handleSendingMessages(ctx context.Context, s network.Stream, outgoing <-chan *RPC) { + bufw := bufio.NewWriter(s) + wc := ggio.NewDelimitedWriter(bufw) + + writeMsg := func(msg proto.Message) error { + err := wc.WriteMsg(msg) + if err != nil { + return err + } + + return bufw.Flush() + } + + defer helpers.FullClose(s) + for { + select { + case rpc, ok := <-outgoing: + if !ok { + return + } + + err := writeMsg(&rpc.RPC) + if err != nil { + s.Reset() + log.Infof("writing message to %s: %s", s.Conn().RemotePeer(), err) + return + } + case <-ctx.Done(): + return + } + } +} + +func rpcWithSubs(subs ...*pb.RPC_SubOpts) *RPC { + return &RPC{ + RPC: pb.RPC{ + Subscriptions: subs, + }, + } +} + +func rpcWithMessages(msgs ...*pb.Message) *RPC { + return &RPC{RPC: pb.RPC{Publish: msgs}} +} + +func rpcWithControl(msgs []*pb.Message, + ihave []*pb.ControlIHave, + iwant []*pb.ControlIWant, + graft []*pb.ControlGraft, + prune []*pb.ControlPrune) *RPC { + return &RPC{ + RPC: pb.RPC{ + Publish: msgs, + Control: &pb.ControlMessage{ + Ihave: ihave, + Iwant: iwant, + Graft: graft, + Prune: prune, + }, + }, + } +} + +func copyRPC(rpc *RPC) *RPC { + res := new(RPC) + *res = *rpc + if rpc.Control != nil { + res.Control = new(pb.ControlMessage) + *res.Control = *rpc.Control + } + return res +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/doc.go b/vendor/github.com/libp2p/go-libp2p-pubsub/doc.go new file mode 100644 index 00000000..e8a5ac89 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/doc.go @@ -0,0 +1,27 @@ +// The pubsub package provides facilities for the Publish/Subscribe pattern of message +// propagation, also known as overlay multicast. +// The implementation provides topic-based pubsub, with pluggable routing algorithms. +// +// The main interface to the library is the PubSub object. +// You can construct this object with the following constructors: +// +// - NewFloodSub creates an instance that uses the floodsub routing algorithm. +// +// - NewGossipSub creates an instance that uses the gossipsub routing algorithm. +// +// - NewRandomSub creates an instance that uses the randomsub routing algorithm. +// +// In addition, there is a generic constructor that creates a pubsub instance with +// a custom PubSubRouter interface. This procedure is currently reserved for internal +// use within the package. +// +// Once you have constructed a PubSub instance, you need to establish some connections +// to your peers; the implementation relies on ambient peer discovery, leaving bootstrap +// and active peer discovery up to the client. +// +// To publish a message to some topic, use Publish; you don't need to be subscribed +// to the topic in order to publish. +// +// To subscribe to a topic, use Subscribe; this will give you a subscription interface +// from which new messages can be pumped. +package pubsub diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go new file mode 100644 index 00000000..0d57c991 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go @@ -0,0 +1,84 @@ +package pubsub + +import ( + "context" + + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +const ( + FloodSubID = protocol.ID("/floodsub/1.0.0") +) + +// NewFloodsubWithProtocols returns a new floodsub-enabled PubSub objecting using the protocols specified in ps. +func NewFloodsubWithProtocols(ctx context.Context, h host.Host, ps []protocol.ID, opts ...Option) (*PubSub, error) { + rt := &FloodSubRouter{ + protocols: ps, + } + return NewPubSub(ctx, h, rt, opts...) +} + +// NewFloodSub returns a new PubSub object using the FloodSubRouter. +func NewFloodSub(ctx context.Context, h host.Host, opts ...Option) (*PubSub, error) { + return NewFloodsubWithProtocols(ctx, h, []protocol.ID{FloodSubID}, opts...) +} + +type FloodSubRouter struct { + p *PubSub + protocols []protocol.ID +} + +func (fs *FloodSubRouter) Protocols() []protocol.ID { + return fs.protocols +} + +func (fs *FloodSubRouter) Attach(p *PubSub) { + fs.p = p +} + +func (fs *FloodSubRouter) AddPeer(peer.ID, protocol.ID) {} + +func (fs *FloodSubRouter) RemovePeer(peer.ID) {} + +func (fs *FloodSubRouter) HandleRPC(rpc *RPC) {} + +func (fs *FloodSubRouter) Publish(from peer.ID, msg *pb.Message) { + tosend := make(map[peer.ID]struct{}) + for _, topic := range msg.GetTopicIDs() { + tmap, ok := fs.p.topics[topic] + if !ok { + continue + } + + for p := range tmap { + tosend[p] = struct{}{} + } + } + + out := rpcWithMessages(msg) + for pid := range tosend { + if pid == from || pid == peer.ID(msg.GetFrom()) { + continue + } + + mch, ok := fs.p.peers[pid] + if !ok { + continue + } + + select { + case mch <- out: + default: + log.Infof("dropping message to peer %s: queue full", pid) + // Drop it. The peer is too slow. + } + } +} + +func (fs *FloodSubRouter) Join(topic string) {} + +func (fs *FloodSubRouter) Leave(topic string) {} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/go.mod b/vendor/github.com/libp2p/go-libp2p-pubsub/go.mod new file mode 100644 index 00000000..c22fa9b7 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/go.mod @@ -0,0 +1,13 @@ +module github.com/libp2p/go-libp2p-pubsub + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/hashicorp/golang-lru v0.5.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multistream v0.1.0 + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee +) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/go.sum b/vendor/github.com/libp2p/go-libp2p-pubsub/go.sum new file mode 100644 index 00000000..2352c3cd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/go.sum @@ -0,0 +1,219 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go new file mode 100644 index 00000000..3bb9eda1 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go @@ -0,0 +1,669 @@ +package pubsub + +import ( + "context" + "fmt" + "math/rand" + "time" + + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +const ( + GossipSubID = protocol.ID("/meshsub/1.0.0") +) + +var ( + // overlay parameters + GossipSubD = 6 + GossipSubDlo = 4 + GossipSubDhi = 12 + + // gossip parameters + GossipSubHistoryLength = 5 + GossipSubHistoryGossip = 3 + + // heartbeat interval + GossipSubHeartbeatInitialDelay = 100 * time.Millisecond + GossipSubHeartbeatInterval = 1 * time.Second + + // fanout ttl + GossipSubFanoutTTL = 60 * time.Second +) + +// NewGossipSub returns a new PubSub object using GossipSubRouter as the router. +func NewGossipSub(ctx context.Context, h host.Host, opts ...Option) (*PubSub, error) { + rt := &GossipSubRouter{ + peers: make(map[peer.ID]protocol.ID), + mesh: make(map[string]map[peer.ID]struct{}), + fanout: make(map[string]map[peer.ID]struct{}), + lastpub: make(map[string]int64), + gossip: make(map[peer.ID][]*pb.ControlIHave), + control: make(map[peer.ID]*pb.ControlMessage), + mcache: NewMessageCache(GossipSubHistoryGossip, GossipSubHistoryLength), + } + return NewPubSub(ctx, h, rt, opts...) +} + +// GossipSubRouter is a router that implements the gossipsub protocol. +// For each topic we have joined, we maintain an overlay through which +// messages flow; this is the mesh map. +// For each topic we publish to without joining, we maintain a list of peers +// to use for injecting our messages in the overlay with stable routes; this +// is the fanout map. Fanout peer lists are expired if we don't publish any +// messages to their topic for GossipSubFanoutTTL. +type GossipSubRouter struct { + p *PubSub + peers map[peer.ID]protocol.ID // peer protocols + mesh map[string]map[peer.ID]struct{} // topic meshes + fanout map[string]map[peer.ID]struct{} // topic fanout + lastpub map[string]int64 // last publish time for fanout topics + gossip map[peer.ID][]*pb.ControlIHave // pending gossip + control map[peer.ID]*pb.ControlMessage // pending control messages + mcache *MessageCache +} + +func (gs *GossipSubRouter) Protocols() []protocol.ID { + return []protocol.ID{GossipSubID, FloodSubID} +} + +func (gs *GossipSubRouter) Attach(p *PubSub) { + gs.p = p + go gs.heartbeatTimer() +} + +func (gs *GossipSubRouter) AddPeer(p peer.ID, proto protocol.ID) { + log.Debugf("PEERUP: Add new peer %s using %s", p, proto) + gs.peers[p] = proto +} + +func (gs *GossipSubRouter) RemovePeer(p peer.ID) { + log.Debugf("PEERDOWN: Remove disconnected peer %s", p) + delete(gs.peers, p) + for _, peers := range gs.mesh { + delete(peers, p) + } + for _, peers := range gs.fanout { + delete(peers, p) + } + delete(gs.gossip, p) + delete(gs.control, p) +} + +func (gs *GossipSubRouter) HandleRPC(rpc *RPC) { + ctl := rpc.GetControl() + if ctl == nil { + return + } + + iwant := gs.handleIHave(rpc.from, ctl) + ihave := gs.handleIWant(rpc.from, ctl) + prune := gs.handleGraft(rpc.from, ctl) + gs.handlePrune(rpc.from, ctl) + + if len(iwant) == 0 && len(ihave) == 0 && len(prune) == 0 { + return + } + + out := rpcWithControl(ihave, nil, iwant, nil, prune) + gs.sendRPC(rpc.from, out) +} + +func (gs *GossipSubRouter) handleIHave(p peer.ID, ctl *pb.ControlMessage) []*pb.ControlIWant { + iwant := make(map[string]struct{}) + + for _, ihave := range ctl.GetIhave() { + topic := ihave.GetTopicID() + _, ok := gs.mesh[topic] + if !ok { + continue + } + + for _, mid := range ihave.GetMessageIDs() { + if gs.p.seenMessage(mid) { + continue + } + iwant[mid] = struct{}{} + } + } + + if len(iwant) == 0 { + return nil + } + + log.Debugf("IHAVE: Asking for %d messages from %s", len(iwant), p) + + iwantlst := make([]string, 0, len(iwant)) + for mid := range iwant { + iwantlst = append(iwantlst, mid) + } + + return []*pb.ControlIWant{&pb.ControlIWant{MessageIDs: iwantlst}} +} + +func (gs *GossipSubRouter) handleIWant(p peer.ID, ctl *pb.ControlMessage) []*pb.Message { + ihave := make(map[string]*pb.Message) + for _, iwant := range ctl.GetIwant() { + for _, mid := range iwant.GetMessageIDs() { + msg, ok := gs.mcache.Get(mid) + if ok { + ihave[mid] = msg + } + } + } + + if len(ihave) == 0 { + return nil + } + + log.Debugf("IWANT: Sending %d messages to %s", len(ihave), p) + + msgs := make([]*pb.Message, 0, len(ihave)) + for _, msg := range ihave { + msgs = append(msgs, msg) + } + + return msgs +} + +func (gs *GossipSubRouter) handleGraft(p peer.ID, ctl *pb.ControlMessage) []*pb.ControlPrune { + var prune []string + for _, graft := range ctl.GetGraft() { + topic := graft.GetTopicID() + peers, ok := gs.mesh[topic] + if !ok { + prune = append(prune, topic) + } else { + log.Debugf("GRAFT: Add mesh link from %s in %s", p, topic) + peers[p] = struct{}{} + gs.tagPeer(p, topic) + } + } + + if len(prune) == 0 { + return nil + } + + cprune := make([]*pb.ControlPrune, 0, len(prune)) + for _, topic := range prune { + cprune = append(cprune, &pb.ControlPrune{TopicID: &topic}) + } + + return cprune +} + +func (gs *GossipSubRouter) handlePrune(p peer.ID, ctl *pb.ControlMessage) { + for _, prune := range ctl.GetPrune() { + topic := prune.GetTopicID() + peers, ok := gs.mesh[topic] + if ok { + log.Debugf("PRUNE: Remove mesh link to %s in %s", p, topic) + delete(peers, p) + gs.untagPeer(p, topic) + } + } +} + +func (gs *GossipSubRouter) Publish(from peer.ID, msg *pb.Message) { + gs.mcache.Put(msg) + + tosend := make(map[peer.ID]struct{}) + for _, topic := range msg.GetTopicIDs() { + // any peers in the topic? + tmap, ok := gs.p.topics[topic] + if !ok { + continue + } + + // floodsub peers + for p := range tmap { + if gs.peers[p] == FloodSubID { + tosend[p] = struct{}{} + } + } + + // gossipsub peers + gmap, ok := gs.mesh[topic] + if !ok { + // we are not in the mesh for topic, use fanout peers + gmap, ok = gs.fanout[topic] + if !ok { + // we don't have any, pick some + peers := gs.getPeers(topic, GossipSubD, func(peer.ID) bool { return true }) + + if len(peers) > 0 { + gmap = peerListToMap(peers) + gs.fanout[topic] = gmap + } + } + gs.lastpub[topic] = time.Now().UnixNano() + } + + for p := range gmap { + tosend[p] = struct{}{} + } + } + + out := rpcWithMessages(msg) + for pid := range tosend { + if pid == from || pid == peer.ID(msg.GetFrom()) { + continue + } + + gs.sendRPC(pid, out) + } +} + +func (gs *GossipSubRouter) Join(topic string) { + gmap, ok := gs.mesh[topic] + if ok { + return + } + + log.Debugf("JOIN %s", topic) + + gmap, ok = gs.fanout[topic] + if ok { + gs.mesh[topic] = gmap + delete(gs.fanout, topic) + delete(gs.lastpub, topic) + } else { + peers := gs.getPeers(topic, GossipSubD, func(peer.ID) bool { return true }) + gmap = peerListToMap(peers) + gs.mesh[topic] = gmap + } + + for p := range gmap { + log.Debugf("JOIN: Add mesh link to %s in %s", p, topic) + gs.sendGraft(p, topic) + gs.tagPeer(p, topic) + } +} + +func (gs *GossipSubRouter) Leave(topic string) { + gmap, ok := gs.mesh[topic] + if !ok { + return + } + + log.Debugf("LEAVE %s", topic) + + delete(gs.mesh, topic) + + for p := range gmap { + log.Debugf("LEAVE: Remove mesh link to %s in %s", p, topic) + gs.sendPrune(p, topic) + gs.untagPeer(p, topic) + } +} + +func (gs *GossipSubRouter) sendGraft(p peer.ID, topic string) { + graft := []*pb.ControlGraft{&pb.ControlGraft{TopicID: &topic}} + out := rpcWithControl(nil, nil, nil, graft, nil) + gs.sendRPC(p, out) +} + +func (gs *GossipSubRouter) sendPrune(p peer.ID, topic string) { + prune := []*pb.ControlPrune{&pb.ControlPrune{TopicID: &topic}} + out := rpcWithControl(nil, nil, nil, nil, prune) + gs.sendRPC(p, out) +} + +func (gs *GossipSubRouter) sendRPC(p peer.ID, out *RPC) { + // do we own the RPC? + own := false + + // piggyback control message retries + ctl, ok := gs.control[p] + if ok { + out = copyRPC(out) + own = true + gs.piggybackControl(p, out, ctl) + delete(gs.control, p) + } + + // piggyback gossip + ihave, ok := gs.gossip[p] + if ok { + if !own { + out = copyRPC(out) + own = true + } + gs.piggybackGossip(p, out, ihave) + delete(gs.gossip, p) + } + + mch, ok := gs.p.peers[p] + if !ok { + return + } + + select { + case mch <- out: + default: + log.Infof("dropping message to peer %s: queue full", p) + // push control messages that need to be retried + ctl := out.GetControl() + if ctl != nil { + gs.pushControl(p, ctl) + } + } +} + +func (gs *GossipSubRouter) heartbeatTimer() { + time.Sleep(GossipSubHeartbeatInitialDelay) + select { + case gs.p.eval <- gs.heartbeat: + case <-gs.p.ctx.Done(): + return + } + + ticker := time.NewTicker(GossipSubHeartbeatInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + select { + case gs.p.eval <- gs.heartbeat: + case <-gs.p.ctx.Done(): + return + } + case <-gs.p.ctx.Done(): + return + } + } +} + +func (gs *GossipSubRouter) heartbeat() { + defer log.EventBegin(gs.p.ctx, "heartbeat").Done() + + // flush pending control message from retries and gossip + // that hasn't been piggybacked since the last heartbeat + gs.flush() + + tograft := make(map[peer.ID][]string) + toprune := make(map[peer.ID][]string) + + // maintain the mesh for topics we have joined + for topic, peers := range gs.mesh { + + // do we have enough peers? + if len(peers) < GossipSubDlo { + ineed := GossipSubD - len(peers) + plst := gs.getPeers(topic, ineed, func(p peer.ID) bool { + // filter our current peers + _, ok := peers[p] + return !ok + }) + + for _, p := range plst { + log.Debugf("HEARTBEAT: Add mesh link to %s in %s", p, topic) + peers[p] = struct{}{} + gs.tagPeer(p, topic) + topics := tograft[p] + tograft[p] = append(topics, topic) + } + } + + // do we have too many peers? + if len(peers) > GossipSubDhi { + idontneed := len(peers) - GossipSubD + plst := peerMapToList(peers) + shufflePeers(plst) + + for _, p := range plst[:idontneed] { + log.Debugf("HEARTBEAT: Remove mesh link to %s in %s", p, topic) + delete(peers, p) + gs.untagPeer(p, topic) + topics := toprune[p] + toprune[p] = append(topics, topic) + } + } + + gs.emitGossip(topic, peers) + } + + // expire fanout for topics we haven't published to in a while + now := time.Now().UnixNano() + for topic, lastpub := range gs.lastpub { + if lastpub+int64(GossipSubFanoutTTL) < now { + delete(gs.fanout, topic) + delete(gs.lastpub, topic) + } + } + + // maintain our fanout for topics we are publishing but we have not joined + for topic, peers := range gs.fanout { + // check whether our peers are still in the topic + for p := range peers { + _, ok := gs.p.topics[topic][p] + if !ok { + delete(peers, p) + } + } + + // do we need more peers? + if len(peers) < GossipSubD { + ineed := GossipSubD - len(peers) + plst := gs.getPeers(topic, ineed, func(p peer.ID) bool { + // filter our current peers + _, ok := peers[p] + return !ok + }) + + for _, p := range plst { + peers[p] = struct{}{} + } + } + + gs.emitGossip(topic, peers) + } + + // send coalesced GRAFT/PRUNE messages (will piggyback gossip) + gs.sendGraftPrune(tograft, toprune) + + // advance the message history window + gs.mcache.Shift() +} + +func (gs *GossipSubRouter) sendGraftPrune(tograft, toprune map[peer.ID][]string) { + for p, topics := range tograft { + graft := make([]*pb.ControlGraft, 0, len(topics)) + for _, topic := range topics { + graft = append(graft, &pb.ControlGraft{TopicID: &topic}) + } + + var prune []*pb.ControlPrune + pruning, ok := toprune[p] + if ok { + delete(toprune, p) + prune = make([]*pb.ControlPrune, 0, len(pruning)) + for _, topic := range pruning { + prune = append(prune, &pb.ControlPrune{TopicID: &topic}) + } + } + + out := rpcWithControl(nil, nil, nil, graft, prune) + gs.sendRPC(p, out) + } + + for p, topics := range toprune { + prune := make([]*pb.ControlPrune, 0, len(topics)) + for _, topic := range topics { + prune = append(prune, &pb.ControlPrune{TopicID: &topic}) + } + + out := rpcWithControl(nil, nil, nil, nil, prune) + gs.sendRPC(p, out) + } + +} + +func (gs *GossipSubRouter) emitGossip(topic string, peers map[peer.ID]struct{}) { + mids := gs.mcache.GetGossipIDs(topic) + if len(mids) == 0 { + return + } + + gpeers := gs.getPeers(topic, GossipSubD, func(peer.ID) bool { return true }) + for _, p := range gpeers { + // skip mesh peers + _, ok := peers[p] + if !ok { + gs.pushGossip(p, &pb.ControlIHave{TopicID: &topic, MessageIDs: mids}) + } + } +} + +func (gs *GossipSubRouter) flush() { + // send gossip first, which will also piggyback control + for p, ihave := range gs.gossip { + delete(gs.gossip, p) + out := rpcWithControl(nil, ihave, nil, nil, nil) + gs.sendRPC(p, out) + } + + // send the remaining control messages + for p, ctl := range gs.control { + delete(gs.control, p) + out := rpcWithControl(nil, nil, nil, ctl.Graft, ctl.Prune) + gs.sendRPC(p, out) + } +} + +func (gs *GossipSubRouter) pushGossip(p peer.ID, ihave *pb.ControlIHave) { + gossip := gs.gossip[p] + gossip = append(gossip, ihave) + gs.gossip[p] = gossip +} + +func (gs *GossipSubRouter) piggybackGossip(p peer.ID, out *RPC, ihave []*pb.ControlIHave) { + ctl := out.GetControl() + if ctl == nil { + ctl = &pb.ControlMessage{} + out.Control = ctl + } + + ctl.Ihave = ihave +} + +func (gs *GossipSubRouter) pushControl(p peer.ID, ctl *pb.ControlMessage) { + // remove IHAVE/IWANT from control message, gossip is not retried + ctl.Ihave = nil + ctl.Iwant = nil + if ctl.Graft != nil || ctl.Prune != nil { + gs.control[p] = ctl + } +} + +func (gs *GossipSubRouter) piggybackControl(p peer.ID, out *RPC, ctl *pb.ControlMessage) { + // check control message for staleness first + var tograft []*pb.ControlGraft + var toprune []*pb.ControlPrune + + for _, graft := range ctl.GetGraft() { + topic := graft.GetTopicID() + peers, ok := gs.mesh[topic] + if !ok { + continue + } + _, ok = peers[p] + if ok { + tograft = append(tograft, graft) + } + } + + for _, prune := range ctl.GetPrune() { + topic := prune.GetTopicID() + peers, ok := gs.mesh[topic] + if !ok { + toprune = append(toprune, prune) + continue + } + _, ok = peers[p] + if !ok { + toprune = append(toprune, prune) + } + } + + if len(tograft) == 0 && len(toprune) == 0 { + return + } + + xctl := out.Control + if xctl == nil { + xctl = &pb.ControlMessage{} + out.Control = xctl + } + + if len(tograft) > 0 { + xctl.Graft = append(xctl.Graft, tograft...) + } + if len(toprune) > 0 { + xctl.Prune = append(xctl.Prune, toprune...) + } +} + +func (gs *GossipSubRouter) getPeers(topic string, count int, filter func(peer.ID) bool) []peer.ID { + tmap, ok := gs.p.topics[topic] + if !ok { + return nil + } + + peers := make([]peer.ID, 0, len(tmap)) + for p := range tmap { + if gs.peers[p] == GossipSubID && filter(p) { + peers = append(peers, p) + } + } + + shufflePeers(peers) + + if count > 0 && len(peers) > count { + peers = peers[:count] + } + + return peers +} + +func (gs *GossipSubRouter) tagPeer(p peer.ID, topic string) { + tag := topicTag(topic) + gs.p.host.ConnManager().TagPeer(p, tag, 2) +} + +func (gs *GossipSubRouter) untagPeer(p peer.ID, topic string) { + tag := topicTag(topic) + gs.p.host.ConnManager().UntagPeer(p, tag) +} + +func topicTag(topic string) string { + return fmt.Sprintf("pubsub:%s", topic) +} + +func peerListToMap(peers []peer.ID) map[peer.ID]struct{} { + pmap := make(map[peer.ID]struct{}) + for _, p := range peers { + pmap[p] = struct{}{} + } + return pmap +} + +func peerMapToList(peers map[peer.ID]struct{}) []peer.ID { + plst := make([]peer.ID, 0, len(peers)) + for p := range peers { + plst = append(plst, p) + } + return plst +} + +func shufflePeers(peers []peer.ID) { + for i := range peers { + j := rand.Intn(i + 1) + peers[i], peers[j] = peers[j], peers[i] + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go b/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go new file mode 100644 index 00000000..827987aa --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go @@ -0,0 +1,61 @@ +package pubsub + +import ( + pb "github.com/libp2p/go-libp2p-pubsub/pb" +) + +func NewMessageCache(gossip, history int) *MessageCache { + return &MessageCache{ + msgs: make(map[string]*pb.Message), + history: make([][]CacheEntry, history), + gossip: gossip, + } +} + +type MessageCache struct { + msgs map[string]*pb.Message + history [][]CacheEntry + gossip int +} + +type CacheEntry struct { + mid string + topics []string +} + +func (mc *MessageCache) Put(msg *pb.Message) { + mid := msgID(msg) + mc.msgs[mid] = msg + mc.history[0] = append(mc.history[0], CacheEntry{mid: mid, topics: msg.GetTopicIDs()}) +} + +func (mc *MessageCache) Get(mid string) (*pb.Message, bool) { + m, ok := mc.msgs[mid] + return m, ok +} + +func (mc *MessageCache) GetGossipIDs(topic string) []string { + var mids []string + for _, entries := range mc.history[:mc.gossip] { + for _, entry := range entries { + for _, t := range entry.topics { + if t == topic { + mids = append(mids, entry.mid) + break + } + } + } + } + return mids +} + +func (mc *MessageCache) Shift() { + last := mc.history[len(mc.history)-1] + for _, entry := range last { + delete(mc.msgs, entry.mid) + } + for i := len(mc.history) - 2; i >= 0; i-- { + mc.history[i+1] = mc.history[i] + } + mc.history[0] = nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go b/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go new file mode 100644 index 00000000..1067cb4e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go @@ -0,0 +1,34 @@ +package pubsub + +import ( + "github.com/libp2p/go-libp2p-core/network" + ma "github.com/multiformats/go-multiaddr" +) + +var _ network.Notifiee = (*PubSubNotif)(nil) + +type PubSubNotif PubSub + +func (p *PubSubNotif) OpenedStream(n network.Network, s network.Stream) { +} + +func (p *PubSubNotif) ClosedStream(n network.Network, s network.Stream) { +} + +func (p *PubSubNotif) Connected(n network.Network, c network.Conn) { + go func() { + select { + case p.newPeers <- c.RemotePeer(): + case <-p.ctx.Done(): + } + }() +} + +func (p *PubSubNotif) Disconnected(n network.Network, c network.Conn) { +} + +func (p *PubSubNotif) Listen(n network.Network, _ ma.Multiaddr) { +} + +func (p *PubSubNotif) ListenClose(n network.Network, _ ma.Multiaddr) { +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.pb.go b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.pb.go new file mode 100644 index 00000000..12bc805c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.pb.go @@ -0,0 +1,3141 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rpc.proto + +package pubsub_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type TopicDescriptor_AuthOpts_AuthMode int32 + +const ( + TopicDescriptor_AuthOpts_NONE TopicDescriptor_AuthOpts_AuthMode = 0 + TopicDescriptor_AuthOpts_KEY TopicDescriptor_AuthOpts_AuthMode = 1 + TopicDescriptor_AuthOpts_WOT TopicDescriptor_AuthOpts_AuthMode = 2 +) + +var TopicDescriptor_AuthOpts_AuthMode_name = map[int32]string{ + 0: "NONE", + 1: "KEY", + 2: "WOT", +} + +var TopicDescriptor_AuthOpts_AuthMode_value = map[string]int32{ + "NONE": 0, + "KEY": 1, + "WOT": 2, +} + +func (x TopicDescriptor_AuthOpts_AuthMode) Enum() *TopicDescriptor_AuthOpts_AuthMode { + p := new(TopicDescriptor_AuthOpts_AuthMode) + *p = x + return p +} + +func (x TopicDescriptor_AuthOpts_AuthMode) String() string { + return proto.EnumName(TopicDescriptor_AuthOpts_AuthMode_name, int32(x)) +} + +func (x *TopicDescriptor_AuthOpts_AuthMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(TopicDescriptor_AuthOpts_AuthMode_value, data, "TopicDescriptor_AuthOpts_AuthMode") + if err != nil { + return err + } + *x = TopicDescriptor_AuthOpts_AuthMode(value) + return nil +} + +func (TopicDescriptor_AuthOpts_AuthMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{7, 0, 0} +} + +type TopicDescriptor_EncOpts_EncMode int32 + +const ( + TopicDescriptor_EncOpts_NONE TopicDescriptor_EncOpts_EncMode = 0 + TopicDescriptor_EncOpts_SHAREDKEY TopicDescriptor_EncOpts_EncMode = 1 + TopicDescriptor_EncOpts_WOT TopicDescriptor_EncOpts_EncMode = 2 +) + +var TopicDescriptor_EncOpts_EncMode_name = map[int32]string{ + 0: "NONE", + 1: "SHAREDKEY", + 2: "WOT", +} + +var TopicDescriptor_EncOpts_EncMode_value = map[string]int32{ + "NONE": 0, + "SHAREDKEY": 1, + "WOT": 2, +} + +func (x TopicDescriptor_EncOpts_EncMode) Enum() *TopicDescriptor_EncOpts_EncMode { + p := new(TopicDescriptor_EncOpts_EncMode) + *p = x + return p +} + +func (x TopicDescriptor_EncOpts_EncMode) String() string { + return proto.EnumName(TopicDescriptor_EncOpts_EncMode_name, int32(x)) +} + +func (x *TopicDescriptor_EncOpts_EncMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(TopicDescriptor_EncOpts_EncMode_value, data, "TopicDescriptor_EncOpts_EncMode") + if err != nil { + return err + } + *x = TopicDescriptor_EncOpts_EncMode(value) + return nil +} + +func (TopicDescriptor_EncOpts_EncMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{7, 1, 0} +} + +type RPC struct { + Subscriptions []*RPC_SubOpts `protobuf:"bytes,1,rep,name=subscriptions" json:"subscriptions,omitempty"` + Publish []*Message `protobuf:"bytes,2,rep,name=publish" json:"publish,omitempty"` + Control *ControlMessage `protobuf:"bytes,3,opt,name=control" json:"control,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RPC) Reset() { *m = RPC{} } +func (m *RPC) String() string { return proto.CompactTextString(m) } +func (*RPC) ProtoMessage() {} +func (*RPC) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{0} +} +func (m *RPC) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RPC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RPC.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RPC) XXX_Merge(src proto.Message) { + xxx_messageInfo_RPC.Merge(m, src) +} +func (m *RPC) XXX_Size() int { + return m.Size() +} +func (m *RPC) XXX_DiscardUnknown() { + xxx_messageInfo_RPC.DiscardUnknown(m) +} + +var xxx_messageInfo_RPC proto.InternalMessageInfo + +func (m *RPC) GetSubscriptions() []*RPC_SubOpts { + if m != nil { + return m.Subscriptions + } + return nil +} + +func (m *RPC) GetPublish() []*Message { + if m != nil { + return m.Publish + } + return nil +} + +func (m *RPC) GetControl() *ControlMessage { + if m != nil { + return m.Control + } + return nil +} + +type RPC_SubOpts struct { + Subscribe *bool `protobuf:"varint,1,opt,name=subscribe" json:"subscribe,omitempty"` + Topicid *string `protobuf:"bytes,2,opt,name=topicid" json:"topicid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RPC_SubOpts) Reset() { *m = RPC_SubOpts{} } +func (m *RPC_SubOpts) String() string { return proto.CompactTextString(m) } +func (*RPC_SubOpts) ProtoMessage() {} +func (*RPC_SubOpts) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{0, 0} +} +func (m *RPC_SubOpts) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RPC_SubOpts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RPC_SubOpts.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RPC_SubOpts) XXX_Merge(src proto.Message) { + xxx_messageInfo_RPC_SubOpts.Merge(m, src) +} +func (m *RPC_SubOpts) XXX_Size() int { + return m.Size() +} +func (m *RPC_SubOpts) XXX_DiscardUnknown() { + xxx_messageInfo_RPC_SubOpts.DiscardUnknown(m) +} + +var xxx_messageInfo_RPC_SubOpts proto.InternalMessageInfo + +func (m *RPC_SubOpts) GetSubscribe() bool { + if m != nil && m.Subscribe != nil { + return *m.Subscribe + } + return false +} + +func (m *RPC_SubOpts) GetTopicid() string { + if m != nil && m.Topicid != nil { + return *m.Topicid + } + return "" +} + +type Message struct { + From []byte `protobuf:"bytes,1,opt,name=from" json:"from,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` + Seqno []byte `protobuf:"bytes,3,opt,name=seqno" json:"seqno,omitempty"` + TopicIDs []string `protobuf:"bytes,4,rep,name=topicIDs" json:"topicIDs,omitempty"` + Signature []byte `protobuf:"bytes,5,opt,name=signature" json:"signature,omitempty"` + Key []byte `protobuf:"bytes,6,opt,name=key" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{1} +} +func (m *Message) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) +} +func (m *Message) XXX_Size() int { + return m.Size() +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetFrom() []byte { + if m != nil { + return m.From + } + return nil +} + +func (m *Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Message) GetSeqno() []byte { + if m != nil { + return m.Seqno + } + return nil +} + +func (m *Message) GetTopicIDs() []string { + if m != nil { + return m.TopicIDs + } + return nil +} + +func (m *Message) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *Message) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +type ControlMessage struct { + Ihave []*ControlIHave `protobuf:"bytes,1,rep,name=ihave" json:"ihave,omitempty"` + Iwant []*ControlIWant `protobuf:"bytes,2,rep,name=iwant" json:"iwant,omitempty"` + Graft []*ControlGraft `protobuf:"bytes,3,rep,name=graft" json:"graft,omitempty"` + Prune []*ControlPrune `protobuf:"bytes,4,rep,name=prune" json:"prune,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ControlMessage) Reset() { *m = ControlMessage{} } +func (m *ControlMessage) String() string { return proto.CompactTextString(m) } +func (*ControlMessage) ProtoMessage() {} +func (*ControlMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{2} +} +func (m *ControlMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ControlMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ControlMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ControlMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_ControlMessage.Merge(m, src) +} +func (m *ControlMessage) XXX_Size() int { + return m.Size() +} +func (m *ControlMessage) XXX_DiscardUnknown() { + xxx_messageInfo_ControlMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_ControlMessage proto.InternalMessageInfo + +func (m *ControlMessage) GetIhave() []*ControlIHave { + if m != nil { + return m.Ihave + } + return nil +} + +func (m *ControlMessage) GetIwant() []*ControlIWant { + if m != nil { + return m.Iwant + } + return nil +} + +func (m *ControlMessage) GetGraft() []*ControlGraft { + if m != nil { + return m.Graft + } + return nil +} + +func (m *ControlMessage) GetPrune() []*ControlPrune { + if m != nil { + return m.Prune + } + return nil +} + +type ControlIHave struct { + TopicID *string `protobuf:"bytes,1,opt,name=topicID" json:"topicID,omitempty"` + MessageIDs []string `protobuf:"bytes,2,rep,name=messageIDs" json:"messageIDs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ControlIHave) Reset() { *m = ControlIHave{} } +func (m *ControlIHave) String() string { return proto.CompactTextString(m) } +func (*ControlIHave) ProtoMessage() {} +func (*ControlIHave) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{3} +} +func (m *ControlIHave) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ControlIHave) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ControlIHave.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ControlIHave) XXX_Merge(src proto.Message) { + xxx_messageInfo_ControlIHave.Merge(m, src) +} +func (m *ControlIHave) XXX_Size() int { + return m.Size() +} +func (m *ControlIHave) XXX_DiscardUnknown() { + xxx_messageInfo_ControlIHave.DiscardUnknown(m) +} + +var xxx_messageInfo_ControlIHave proto.InternalMessageInfo + +func (m *ControlIHave) GetTopicID() string { + if m != nil && m.TopicID != nil { + return *m.TopicID + } + return "" +} + +func (m *ControlIHave) GetMessageIDs() []string { + if m != nil { + return m.MessageIDs + } + return nil +} + +type ControlIWant struct { + MessageIDs []string `protobuf:"bytes,1,rep,name=messageIDs" json:"messageIDs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ControlIWant) Reset() { *m = ControlIWant{} } +func (m *ControlIWant) String() string { return proto.CompactTextString(m) } +func (*ControlIWant) ProtoMessage() {} +func (*ControlIWant) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{4} +} +func (m *ControlIWant) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ControlIWant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ControlIWant.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ControlIWant) XXX_Merge(src proto.Message) { + xxx_messageInfo_ControlIWant.Merge(m, src) +} +func (m *ControlIWant) XXX_Size() int { + return m.Size() +} +func (m *ControlIWant) XXX_DiscardUnknown() { + xxx_messageInfo_ControlIWant.DiscardUnknown(m) +} + +var xxx_messageInfo_ControlIWant proto.InternalMessageInfo + +func (m *ControlIWant) GetMessageIDs() []string { + if m != nil { + return m.MessageIDs + } + return nil +} + +type ControlGraft struct { + TopicID *string `protobuf:"bytes,1,opt,name=topicID" json:"topicID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ControlGraft) Reset() { *m = ControlGraft{} } +func (m *ControlGraft) String() string { return proto.CompactTextString(m) } +func (*ControlGraft) ProtoMessage() {} +func (*ControlGraft) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{5} +} +func (m *ControlGraft) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ControlGraft) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ControlGraft.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ControlGraft) XXX_Merge(src proto.Message) { + xxx_messageInfo_ControlGraft.Merge(m, src) +} +func (m *ControlGraft) XXX_Size() int { + return m.Size() +} +func (m *ControlGraft) XXX_DiscardUnknown() { + xxx_messageInfo_ControlGraft.DiscardUnknown(m) +} + +var xxx_messageInfo_ControlGraft proto.InternalMessageInfo + +func (m *ControlGraft) GetTopicID() string { + if m != nil && m.TopicID != nil { + return *m.TopicID + } + return "" +} + +type ControlPrune struct { + TopicID *string `protobuf:"bytes,1,opt,name=topicID" json:"topicID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ControlPrune) Reset() { *m = ControlPrune{} } +func (m *ControlPrune) String() string { return proto.CompactTextString(m) } +func (*ControlPrune) ProtoMessage() {} +func (*ControlPrune) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{6} +} +func (m *ControlPrune) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ControlPrune) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ControlPrune.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ControlPrune) XXX_Merge(src proto.Message) { + xxx_messageInfo_ControlPrune.Merge(m, src) +} +func (m *ControlPrune) XXX_Size() int { + return m.Size() +} +func (m *ControlPrune) XXX_DiscardUnknown() { + xxx_messageInfo_ControlPrune.DiscardUnknown(m) +} + +var xxx_messageInfo_ControlPrune proto.InternalMessageInfo + +func (m *ControlPrune) GetTopicID() string { + if m != nil && m.TopicID != nil { + return *m.TopicID + } + return "" +} + +type TopicDescriptor struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Auth *TopicDescriptor_AuthOpts `protobuf:"bytes,2,opt,name=auth" json:"auth,omitempty"` + Enc *TopicDescriptor_EncOpts `protobuf:"bytes,3,opt,name=enc" json:"enc,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TopicDescriptor) Reset() { *m = TopicDescriptor{} } +func (m *TopicDescriptor) String() string { return proto.CompactTextString(m) } +func (*TopicDescriptor) ProtoMessage() {} +func (*TopicDescriptor) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{7} +} +func (m *TopicDescriptor) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TopicDescriptor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TopicDescriptor.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TopicDescriptor) XXX_Merge(src proto.Message) { + xxx_messageInfo_TopicDescriptor.Merge(m, src) +} +func (m *TopicDescriptor) XXX_Size() int { + return m.Size() +} +func (m *TopicDescriptor) XXX_DiscardUnknown() { + xxx_messageInfo_TopicDescriptor.DiscardUnknown(m) +} + +var xxx_messageInfo_TopicDescriptor proto.InternalMessageInfo + +func (m *TopicDescriptor) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *TopicDescriptor) GetAuth() *TopicDescriptor_AuthOpts { + if m != nil { + return m.Auth + } + return nil +} + +func (m *TopicDescriptor) GetEnc() *TopicDescriptor_EncOpts { + if m != nil { + return m.Enc + } + return nil +} + +type TopicDescriptor_AuthOpts struct { + Mode *TopicDescriptor_AuthOpts_AuthMode `protobuf:"varint,1,opt,name=mode,enum=pubsub.pb.TopicDescriptor_AuthOpts_AuthMode" json:"mode,omitempty"` + Keys [][]byte `protobuf:"bytes,2,rep,name=keys" json:"keys,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TopicDescriptor_AuthOpts) Reset() { *m = TopicDescriptor_AuthOpts{} } +func (m *TopicDescriptor_AuthOpts) String() string { return proto.CompactTextString(m) } +func (*TopicDescriptor_AuthOpts) ProtoMessage() {} +func (*TopicDescriptor_AuthOpts) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{7, 0} +} +func (m *TopicDescriptor_AuthOpts) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TopicDescriptor_AuthOpts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TopicDescriptor_AuthOpts.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TopicDescriptor_AuthOpts) XXX_Merge(src proto.Message) { + xxx_messageInfo_TopicDescriptor_AuthOpts.Merge(m, src) +} +func (m *TopicDescriptor_AuthOpts) XXX_Size() int { + return m.Size() +} +func (m *TopicDescriptor_AuthOpts) XXX_DiscardUnknown() { + xxx_messageInfo_TopicDescriptor_AuthOpts.DiscardUnknown(m) +} + +var xxx_messageInfo_TopicDescriptor_AuthOpts proto.InternalMessageInfo + +func (m *TopicDescriptor_AuthOpts) GetMode() TopicDescriptor_AuthOpts_AuthMode { + if m != nil && m.Mode != nil { + return *m.Mode + } + return TopicDescriptor_AuthOpts_NONE +} + +func (m *TopicDescriptor_AuthOpts) GetKeys() [][]byte { + if m != nil { + return m.Keys + } + return nil +} + +type TopicDescriptor_EncOpts struct { + Mode *TopicDescriptor_EncOpts_EncMode `protobuf:"varint,1,opt,name=mode,enum=pubsub.pb.TopicDescriptor_EncOpts_EncMode" json:"mode,omitempty"` + KeyHashes [][]byte `protobuf:"bytes,2,rep,name=keyHashes" json:"keyHashes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TopicDescriptor_EncOpts) Reset() { *m = TopicDescriptor_EncOpts{} } +func (m *TopicDescriptor_EncOpts) String() string { return proto.CompactTextString(m) } +func (*TopicDescriptor_EncOpts) ProtoMessage() {} +func (*TopicDescriptor_EncOpts) Descriptor() ([]byte, []int) { + return fileDescriptor_77a6da22d6a3feb1, []int{7, 1} +} +func (m *TopicDescriptor_EncOpts) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TopicDescriptor_EncOpts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TopicDescriptor_EncOpts.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TopicDescriptor_EncOpts) XXX_Merge(src proto.Message) { + xxx_messageInfo_TopicDescriptor_EncOpts.Merge(m, src) +} +func (m *TopicDescriptor_EncOpts) XXX_Size() int { + return m.Size() +} +func (m *TopicDescriptor_EncOpts) XXX_DiscardUnknown() { + xxx_messageInfo_TopicDescriptor_EncOpts.DiscardUnknown(m) +} + +var xxx_messageInfo_TopicDescriptor_EncOpts proto.InternalMessageInfo + +func (m *TopicDescriptor_EncOpts) GetMode() TopicDescriptor_EncOpts_EncMode { + if m != nil && m.Mode != nil { + return *m.Mode + } + return TopicDescriptor_EncOpts_NONE +} + +func (m *TopicDescriptor_EncOpts) GetKeyHashes() [][]byte { + if m != nil { + return m.KeyHashes + } + return nil +} + +func init() { + proto.RegisterEnum("pubsub.pb.TopicDescriptor_AuthOpts_AuthMode", TopicDescriptor_AuthOpts_AuthMode_name, TopicDescriptor_AuthOpts_AuthMode_value) + proto.RegisterEnum("pubsub.pb.TopicDescriptor_EncOpts_EncMode", TopicDescriptor_EncOpts_EncMode_name, TopicDescriptor_EncOpts_EncMode_value) + proto.RegisterType((*RPC)(nil), "pubsub.pb.RPC") + proto.RegisterType((*RPC_SubOpts)(nil), "pubsub.pb.RPC.SubOpts") + proto.RegisterType((*Message)(nil), "pubsub.pb.Message") + proto.RegisterType((*ControlMessage)(nil), "pubsub.pb.ControlMessage") + proto.RegisterType((*ControlIHave)(nil), "pubsub.pb.ControlIHave") + proto.RegisterType((*ControlIWant)(nil), "pubsub.pb.ControlIWant") + proto.RegisterType((*ControlGraft)(nil), "pubsub.pb.ControlGraft") + proto.RegisterType((*ControlPrune)(nil), "pubsub.pb.ControlPrune") + proto.RegisterType((*TopicDescriptor)(nil), "pubsub.pb.TopicDescriptor") + proto.RegisterType((*TopicDescriptor_AuthOpts)(nil), "pubsub.pb.TopicDescriptor.AuthOpts") + proto.RegisterType((*TopicDescriptor_EncOpts)(nil), "pubsub.pb.TopicDescriptor.EncOpts") +} + +func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } + +var fileDescriptor_77a6da22d6a3feb1 = []byte{ + // 599 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xc7, 0xd9, 0x38, 0xc5, 0xf1, 0xd4, 0x2d, 0xd1, 0x0a, 0x81, 0x89, 0xaa, 0x28, 0x32, 0x12, + 0xb2, 0xa0, 0xf8, 0x10, 0x90, 0xb8, 0x20, 0x44, 0x69, 0x22, 0x12, 0xa1, 0x7e, 0x68, 0x5b, 0xa9, + 0xe2, 0xb8, 0x76, 0xb6, 0x89, 0x95, 0xc6, 0x36, 0xf6, 0xba, 0x28, 0x6f, 0xc0, 0x1d, 0x9e, 0x85, + 0x67, 0xe0, 0xc0, 0x81, 0x47, 0x40, 0xb9, 0xf1, 0x16, 0x68, 0xc7, 0x4e, 0xe2, 0xa4, 0x1f, 0x70, + 0xf2, 0xec, 0xec, 0xef, 0xbf, 0xf3, 0x9f, 0xd9, 0x35, 0x18, 0x49, 0xec, 0xbb, 0x71, 0x12, 0xc9, + 0x88, 0x1a, 0x71, 0xe6, 0xa5, 0x99, 0xe7, 0xc6, 0x9e, 0xfd, 0x87, 0x80, 0xc6, 0x8e, 0xf7, 0xe9, + 0x6b, 0xd8, 0x4a, 0x33, 0x2f, 0xf5, 0x93, 0x20, 0x96, 0x41, 0x14, 0xa6, 0x16, 0x69, 0x69, 0xce, + 0x66, 0xfb, 0x81, 0xbb, 0x40, 0x5d, 0x76, 0xbc, 0xef, 0x9e, 0x64, 0xde, 0x51, 0x2c, 0x53, 0xb6, + 0x0a, 0xd3, 0x5d, 0xd0, 0xe3, 0xcc, 0xbb, 0x08, 0xd2, 0x91, 0x55, 0x41, 0x1d, 0x2d, 0xe9, 0x0e, + 0x44, 0x9a, 0xf2, 0xa1, 0x60, 0x73, 0x84, 0xbe, 0x00, 0xdd, 0x8f, 0x42, 0x99, 0x44, 0x17, 0x96, + 0xd6, 0x22, 0xce, 0x66, 0xfb, 0x51, 0x89, 0xde, 0xcf, 0x77, 0x16, 0xa2, 0x82, 0x6c, 0xec, 0x81, + 0x5e, 0x14, 0xa7, 0x3b, 0x60, 0x14, 0xe5, 0x3d, 0x61, 0x91, 0x16, 0x71, 0x6a, 0x6c, 0x99, 0xa0, + 0x16, 0xe8, 0x32, 0x8a, 0x03, 0x3f, 0x18, 0x58, 0x95, 0x16, 0x71, 0x0c, 0x36, 0x5f, 0xda, 0x5f, + 0x09, 0xe8, 0xc5, 0xb9, 0x94, 0x42, 0xf5, 0x3c, 0x89, 0x26, 0x28, 0x37, 0x19, 0xc6, 0x2a, 0x37, + 0xe0, 0x92, 0xa3, 0xcc, 0x64, 0x18, 0xd3, 0xfb, 0xb0, 0x91, 0x8a, 0x4f, 0x61, 0x84, 0x4e, 0x4d, + 0x96, 0x2f, 0x68, 0x03, 0x6a, 0x78, 0x68, 0xbf, 0x93, 0x5a, 0xd5, 0x96, 0xe6, 0x18, 0x6c, 0xb1, + 0x46, 0x77, 0xc1, 0x30, 0xe4, 0x32, 0x4b, 0x84, 0xb5, 0x81, 0xaa, 0x65, 0x82, 0xd6, 0x41, 0x1b, + 0x8b, 0xa9, 0x75, 0x17, 0xf3, 0x2a, 0xb4, 0x7f, 0x12, 0xd8, 0x5e, 0x6d, 0x9a, 0x3e, 0x87, 0x8d, + 0x60, 0xc4, 0x2f, 0x45, 0x71, 0x09, 0x0f, 0xaf, 0x8e, 0xa7, 0xdf, 0xe3, 0x97, 0x82, 0xe5, 0x14, + 0xe2, 0x9f, 0x79, 0x28, 0x8b, 0xd9, 0x5f, 0x87, 0x9f, 0xf1, 0x50, 0xb2, 0x9c, 0x52, 0xf8, 0x30, + 0xe1, 0xe7, 0xd2, 0xd2, 0x6e, 0xc2, 0xdf, 0xab, 0x6d, 0x96, 0x53, 0x0a, 0x8f, 0x93, 0x2c, 0x14, + 0xd8, 0xe8, 0xb5, 0xf8, 0xb1, 0xda, 0x66, 0x39, 0x65, 0xf7, 0xc0, 0x2c, 0x7b, 0x5c, 0x5c, 0x47, + 0xbf, 0x83, 0xb3, 0x9e, 0x5f, 0x47, 0xbf, 0x43, 0x9b, 0x00, 0x93, 0xbc, 0x61, 0x35, 0xc6, 0x0a, + 0x8e, 0xb1, 0x94, 0xb1, 0xdd, 0xe5, 0x49, 0xca, 0xfe, 0x1a, 0x4f, 0xae, 0xf0, 0xce, 0x82, 0x47, + 0xff, 0x37, 0x57, 0x2e, 0x91, 0x68, 0xfd, 0x16, 0xf2, 0xbb, 0x06, 0xf7, 0x4e, 0x55, 0xdc, 0x11, + 0xf9, 0x73, 0x8f, 0x12, 0xf5, 0x4c, 0x42, 0x3e, 0x11, 0x05, 0x8a, 0x31, 0x7d, 0x05, 0x55, 0x9e, + 0xc9, 0x11, 0x3e, 0x9d, 0xcd, 0xf6, 0xe3, 0xd2, 0x8c, 0xd6, 0xd4, 0xee, 0x5e, 0x26, 0x47, 0xf8, + 0x0b, 0xa1, 0x80, 0xbe, 0x04, 0x4d, 0x84, 0x7e, 0xf1, 0x1f, 0xd8, 0xb7, 0xe8, 0xba, 0xa1, 0x8f, + 0x32, 0x85, 0x37, 0xbe, 0x10, 0xa8, 0xcd, 0x0f, 0xa2, 0x6f, 0xa1, 0x3a, 0x89, 0x06, 0xb9, 0x9f, + 0xed, 0xf6, 0xee, 0x7f, 0xd4, 0xc6, 0xe0, 0x20, 0x1a, 0x08, 0x86, 0x4a, 0xd5, 0xd1, 0x58, 0x4c, + 0xf3, 0x3b, 0x30, 0x19, 0xc6, 0xf6, 0x93, 0xbc, 0x82, 0xa2, 0x68, 0x0d, 0xaa, 0x87, 0x47, 0x87, + 0xdd, 0xfa, 0x1d, 0xaa, 0x83, 0xf6, 0xa1, 0xfb, 0xb1, 0x4e, 0x54, 0x70, 0x76, 0x74, 0x5a, 0xaf, + 0x34, 0xbe, 0x11, 0xd0, 0x0b, 0x6f, 0xf4, 0xcd, 0x8a, 0x93, 0xa7, 0xff, 0xee, 0x46, 0x7d, 0x4b, + 0x3e, 0x76, 0xc0, 0x18, 0x8b, 0x69, 0x8f, 0xa7, 0x23, 0x31, 0x37, 0xb3, 0x4c, 0xd8, 0xcf, 0xb0, + 0xd0, 0x9a, 0xa1, 0x2d, 0x30, 0x4e, 0x7a, 0x7b, 0xac, 0xdb, 0x59, 0xb5, 0xf5, 0xce, 0xfc, 0x31, + 0x6b, 0x92, 0x5f, 0xb3, 0x26, 0xf9, 0x3d, 0x6b, 0x92, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf8, + 0xb0, 0xae, 0x4e, 0xfc, 0x04, 0x00, 0x00, +} + +func (m *RPC) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RPC) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Subscriptions) > 0 { + for _, msg := range m.Subscriptions { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Publish) > 0 { + for _, msg := range m.Publish { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.Control != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Control.Size())) + n1, err := m.Control.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *RPC_SubOpts) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RPC_SubOpts) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Subscribe != nil { + dAtA[i] = 0x8 + i++ + if *m.Subscribe { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if m.Topicid != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(*m.Topicid))) + i += copy(dAtA[i:], *m.Topicid) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Message) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.From != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.From))) + i += copy(dAtA[i:], m.From) + } + if m.Data != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + if m.Seqno != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Seqno))) + i += copy(dAtA[i:], m.Seqno) + } + if len(m.TopicIDs) > 0 { + for _, s := range m.TopicIDs { + dAtA[i] = 0x22 + 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) + } + } + if m.Signature != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Signature))) + i += copy(dAtA[i:], m.Signature) + } + if m.Key != nil { + dAtA[i] = 0x32 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ControlMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ControlMessage) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Ihave) > 0 { + for _, msg := range m.Ihave { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Iwant) > 0 { + for _, msg := range m.Iwant { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Graft) > 0 { + for _, msg := range m.Graft { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Prune) > 0 { + for _, msg := range m.Prune { + dAtA[i] = 0x22 + i++ + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ControlIHave) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ControlIHave) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TopicID != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(*m.TopicID))) + i += copy(dAtA[i:], *m.TopicID) + } + if len(m.MessageIDs) > 0 { + for _, s := range m.MessageIDs { + dAtA[i] = 0x12 + 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) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ControlIWant) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ControlIWant) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.MessageIDs) > 0 { + for _, s := range m.MessageIDs { + dAtA[i] = 0xa + 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) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ControlGraft) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ControlGraft) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TopicID != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(*m.TopicID))) + i += copy(dAtA[i:], *m.TopicID) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *ControlPrune) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ControlPrune) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TopicID != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(*m.TopicID))) + i += copy(dAtA[i:], *m.TopicID) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *TopicDescriptor) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TopicDescriptor) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(*m.Name))) + i += copy(dAtA[i:], *m.Name) + } + if m.Auth != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Auth.Size())) + n2, err := m.Auth.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Enc != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Enc.Size())) + n3, err := m.Enc.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *TopicDescriptor_AuthOpts) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TopicDescriptor_AuthOpts) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Mode != nil { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(*m.Mode)) + } + if len(m.Keys) > 0 { + for _, b := range m.Keys { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *TopicDescriptor_EncOpts) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TopicDescriptor_EncOpts) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Mode != nil { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(*m.Mode)) + } + if len(m.KeyHashes) > 0 { + for _, b := range m.KeyHashes { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintRpc(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *RPC) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subscriptions) > 0 { + for _, e := range m.Subscriptions { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if len(m.Publish) > 0 { + for _, e := range m.Publish { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.Control != nil { + l = m.Control.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RPC_SubOpts) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Subscribe != nil { + n += 2 + } + if m.Topicid != nil { + l = len(*m.Topicid) + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Message) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.From != nil { + l = len(m.From) + n += 1 + l + sovRpc(uint64(l)) + } + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovRpc(uint64(l)) + } + if m.Seqno != nil { + l = len(m.Seqno) + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.TopicIDs) > 0 { + for _, s := range m.TopicIDs { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.Signature != nil { + l = len(m.Signature) + n += 1 + l + sovRpc(uint64(l)) + } + if m.Key != nil { + l = len(m.Key) + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ControlMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ihave) > 0 { + for _, e := range m.Ihave { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if len(m.Iwant) > 0 { + for _, e := range m.Iwant { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if len(m.Graft) > 0 { + for _, e := range m.Graft { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if len(m.Prune) > 0 { + for _, e := range m.Prune { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ControlIHave) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TopicID != nil { + l = len(*m.TopicID) + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.MessageIDs) > 0 { + for _, s := range m.MessageIDs { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ControlIWant) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.MessageIDs) > 0 { + for _, s := range m.MessageIDs { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ControlGraft) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TopicID != nil { + l = len(*m.TopicID) + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ControlPrune) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TopicID != nil { + l = len(*m.TopicID) + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TopicDescriptor) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovRpc(uint64(l)) + } + if m.Auth != nil { + l = m.Auth.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.Enc != nil { + l = m.Enc.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TopicDescriptor_AuthOpts) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Mode != nil { + n += 1 + sovRpc(uint64(*m.Mode)) + } + if len(m.Keys) > 0 { + for _, b := range m.Keys { + l = len(b) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TopicDescriptor_EncOpts) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Mode != nil { + n += 1 + sovRpc(uint64(*m.Mode)) + } + if len(m.KeyHashes) > 0 { + for _, b := range m.KeyHashes { + l = len(b) + n += 1 + l + sovRpc(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovRpc(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRpc(x uint64) (n int) { + return sovRpc(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RPC) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RPC: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RPC: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscriptions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subscriptions = append(m.Subscriptions, &RPC_SubOpts{}) + if err := m.Subscriptions[len(m.Subscriptions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publish", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Publish = append(m.Publish, &Message{}) + if err := m.Publish[len(m.Publish)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Control", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Control == nil { + m.Control = &ControlMessage{} + } + if err := m.Control.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RPC_SubOpts) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubOpts: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubOpts: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscribe", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Subscribe = &b + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Topicid", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Topicid = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = append(m.From[:0], dAtA[iNdEx:postIndex]...) + if m.From == nil { + m.From = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Seqno", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Seqno = append(m.Seqno[:0], dAtA[iNdEx:postIndex]...) + if m.Seqno == nil { + m.Seqno = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TopicIDs", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TopicIDs = append(m.TopicIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ControlMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ControlMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ControlMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ihave", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ihave = append(m.Ihave, &ControlIHave{}) + if err := m.Ihave[len(m.Ihave)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Iwant", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Iwant = append(m.Iwant, &ControlIWant{}) + if err := m.Iwant[len(m.Iwant)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Graft", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Graft = append(m.Graft, &ControlGraft{}) + if err := m.Graft[len(m.Graft)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prune", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prune = append(m.Prune, &ControlPrune{}) + if err := m.Prune[len(m.Prune)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ControlIHave) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ControlIHave: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ControlIHave: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TopicID", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.TopicID = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageIDs", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MessageIDs = append(m.MessageIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ControlIWant) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ControlIWant: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ControlIWant: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageIDs", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MessageIDs = append(m.MessageIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ControlGraft) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ControlGraft: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ControlGraft: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TopicID", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.TopicID = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ControlPrune) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ControlPrune: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ControlPrune: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TopicID", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.TopicID = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TopicDescriptor) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TopicDescriptor: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TopicDescriptor: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", 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 < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Auth", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Auth == nil { + m.Auth = &TopicDescriptor_AuthOpts{} + } + if err := m.Auth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Enc", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Enc == nil { + m.Enc = &TopicDescriptor_EncOpts{} + } + if err := m.Enc.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TopicDescriptor_AuthOpts) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuthOpts: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthOpts: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + var v TopicDescriptor_AuthOpts_AuthMode + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= TopicDescriptor_AuthOpts_AuthMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Mode = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx)) + copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TopicDescriptor_EncOpts) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EncOpts: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EncOpts: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + var v TopicDescriptor_EncOpts_EncMode + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= TopicDescriptor_EncOpts_EncMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Mode = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyHashes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyHashes = append(m.KeyHashes, make([]byte, postIndex-iNdEx)) + copy(m.KeyHashes[len(m.KeyHashes)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRpc(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthRpc + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthRpc + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpc + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRpc(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthRpc + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRpc = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRpc = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.proto b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.proto new file mode 100644 index 00000000..4a058288 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/pb/rpc.proto @@ -0,0 +1,76 @@ +syntax = "proto2"; + +package pubsub.pb; + +message RPC { + repeated SubOpts subscriptions = 1; + repeated Message publish = 2; + + message SubOpts { + optional bool subscribe = 1; // subscribe or unsubcribe + optional string topicid = 2; + } + + optional ControlMessage control = 3; +} + +message Message { + optional bytes from = 1; + optional bytes data = 2; + optional bytes seqno = 3; + repeated string topicIDs = 4; + optional bytes signature = 5; + optional bytes key = 6; +} + +message ControlMessage { + repeated ControlIHave ihave = 1; + repeated ControlIWant iwant = 2; + repeated ControlGraft graft = 3; + repeated ControlPrune prune = 4; +} + +message ControlIHave { + optional string topicID = 1; + repeated string messageIDs = 2; +} + +message ControlIWant { + repeated string messageIDs = 1; +} + +message ControlGraft { + optional string topicID = 1; +} + +message ControlPrune { + optional string topicID = 1; +} + +message TopicDescriptor { + optional string name = 1; + optional AuthOpts auth = 2; + optional EncOpts enc = 3; + + message AuthOpts { + optional AuthMode mode = 1; + repeated bytes keys = 2; // root keys to trust + + enum AuthMode { + NONE = 0; // no authentication, anyone can publish + KEY = 1; // only messages signed by keys in the topic descriptor are accepted + WOT = 2; // web of trust, certificates can allow publisher set to grow + } + } + + message EncOpts { + optional EncMode mode = 1; + repeated bytes keyHashes = 2; // the hashes of the shared keys used (salted) + + enum EncMode { + NONE = 0; // no encryption, anyone can read + SHAREDKEY = 1; // messages are encrypted with shared key + WOT = 2; // web of trust, certificates can allow publisher set to grow + } + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go new file mode 100644 index 00000000..6df169d8 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go @@ -0,0 +1,784 @@ +package pubsub + +import ( + "context" + "encoding/binary" + "fmt" + "math/rand" + "sync" + "sync/atomic" + "time" + + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + + logging "github.com/ipfs/go-log" + timecache "github.com/whyrusleeping/timecache" +) + +var ( + TimeCacheDuration = 120 * time.Second +) + +var log = logging.Logger("pubsub") + +// PubSub is the implementation of the pubsub system. +type PubSub struct { + // atomic counter for seqnos + // NOTE: Must be declared at the top of the struct as we perform atomic + // operations on this field. + // + // See: https://golang.org/pkg/sync/atomic/#pkg-note-BUG + counter uint64 + + host host.Host + + rt PubSubRouter + + val *validation + + // incoming messages from other peers + incoming chan *RPC + + // messages we are publishing out to our peers + publish chan *Message + + // addSub is a control channel for us to add and remove subscriptions + addSub chan *addSubReq + + // get list of topics we are subscribed to + getTopics chan *topicReq + + // get chan of peers we are connected to + getPeers chan *listPeerReq + + // send subscription here to cancel it + cancelCh chan *Subscription + + // a notification channel for new peer connections + newPeers chan peer.ID + + // a notification channel for new outoging peer streams + newPeerStream chan network.Stream + + // a notification channel for errors opening new peer streams + newPeerError chan peer.ID + + // a notification channel for when our peers die + peerDead chan peer.ID + + // The set of topics we are subscribed to + myTopics map[string]map[*Subscription]struct{} + + // topics tracks which topics each of our peers are subscribed to + topics map[string]map[peer.ID]struct{} + + // sendMsg handles messages that have been validated + sendMsg chan *sendReq + + // addVal handles validator registration requests + addVal chan *addValReq + + // rmVal handles validator unregistration requests + rmVal chan *rmValReq + + // eval thunk in event loop + eval chan func() + + // peer blacklist + blacklist Blacklist + blacklistPeer chan peer.ID + + peers map[peer.ID]chan *RPC + + seenMessagesMx sync.Mutex + seenMessages *timecache.TimeCache + + // key for signing messages; nil when signing is disabled (default for now) + signKey crypto.PrivKey + // source ID for signed messages; corresponds to signKey + signID peer.ID + // strict mode rejects all unsigned messages prior to validation + signStrict bool + + ctx context.Context +} + +// PubSubRouter is the message router component of PubSub. +type PubSubRouter interface { + // Protocols returns the list of protocols supported by the router. + Protocols() []protocol.ID + // Attach is invoked by the PubSub constructor to attach the router to a + // freshly initialized PubSub instance. + Attach(*PubSub) + // AddPeer notifies the router that a new peer has been connected. + AddPeer(peer.ID, protocol.ID) + // RemovePeer notifies the router that a peer has been disconnected. + RemovePeer(peer.ID) + // HandleRPC is invoked to process control messages in the RPC envelope. + // It is invoked after subscriptions and payload messages have been processed. + HandleRPC(*RPC) + // Publish is invoked to forward a new message that has been validated. + Publish(peer.ID, *pb.Message) + // Join notifies the router that we want to receive and forward messages in a topic. + // It is invoked after the subscription announcement. + Join(topic string) + // Leave notifies the router that we are no longer interested in a topic. + // It is invoked after the unsubscription announcement. + Leave(topic string) +} + +type Message struct { + *pb.Message +} + +func (m *Message) GetFrom() peer.ID { + return peer.ID(m.Message.GetFrom()) +} + +type RPC struct { + pb.RPC + + // unexported on purpose, not sending this over the wire + from peer.ID +} + +type Option func(*PubSub) error + +// NewPubSub returns a new PubSub management object. +func NewPubSub(ctx context.Context, h host.Host, rt PubSubRouter, opts ...Option) (*PubSub, error) { + ps := &PubSub{ + host: h, + ctx: ctx, + rt: rt, + val: newValidation(), + signID: h.ID(), + signKey: h.Peerstore().PrivKey(h.ID()), + signStrict: true, + incoming: make(chan *RPC, 32), + publish: make(chan *Message), + newPeers: make(chan peer.ID), + newPeerStream: make(chan network.Stream), + newPeerError: make(chan peer.ID), + peerDead: make(chan peer.ID), + cancelCh: make(chan *Subscription), + getPeers: make(chan *listPeerReq), + addSub: make(chan *addSubReq), + getTopics: make(chan *topicReq), + sendMsg: make(chan *sendReq, 32), + addVal: make(chan *addValReq), + rmVal: make(chan *rmValReq), + eval: make(chan func()), + myTopics: make(map[string]map[*Subscription]struct{}), + topics: make(map[string]map[peer.ID]struct{}), + peers: make(map[peer.ID]chan *RPC), + blacklist: NewMapBlacklist(), + blacklistPeer: make(chan peer.ID), + seenMessages: timecache.NewTimeCache(TimeCacheDuration), + counter: uint64(time.Now().UnixNano()), + } + + for _, opt := range opts { + err := opt(ps) + if err != nil { + return nil, err + } + } + + if ps.signStrict && ps.signKey == nil { + return nil, fmt.Errorf("strict signature verification enabled but message signing is disabled") + } + + rt.Attach(ps) + + for _, id := range rt.Protocols() { + h.SetStreamHandler(id, ps.handleNewStream) + } + h.Network().Notify((*PubSubNotif)(ps)) + + ps.val.Start(ps) + + go ps.processLoop(ctx) + + return ps, nil +} + +// WithMessageSigning enables or disables message signing (enabled by default). +func WithMessageSigning(enabled bool) Option { + return func(p *PubSub) error { + if enabled { + p.signKey = p.host.Peerstore().PrivKey(p.signID) + if p.signKey == nil { + return fmt.Errorf("can't sign for peer %s: no private key", p.signID) + } + } else { + p.signKey = nil + p.signStrict = false + } + return nil + } +} + +// WithMessageAuthor sets the author for outbound messages to the given peer ID +// (defaults to the host's ID). If message signing is enabled, the private key +// must be available in the host's peerstore. +func WithMessageAuthor(author peer.ID) Option { + return func(p *PubSub) error { + if author == "" { + author = p.host.ID() + } + if p.signKey != nil { + newSignKey := p.host.Peerstore().PrivKey(author) + if newSignKey == nil { + return fmt.Errorf("can't sign for peer %s: no private key", p.signID) + } + p.signKey = newSignKey + } + p.signID = author + return nil + } +} + +// WithStrictSignatureVerification is an option to enable or disable strict message signing. +// When enabled (which is the default), unsigned messages will be discarded. +func WithStrictSignatureVerification(required bool) Option { + return func(p *PubSub) error { + p.signStrict = required + return nil + } +} + +// WithBlacklist provides an implementation of the blacklist; the default is a +// MapBlacklist +func WithBlacklist(b Blacklist) Option { + return func(p *PubSub) error { + p.blacklist = b + return nil + } +} + +// processLoop handles all inputs arriving on the channels +func (p *PubSub) processLoop(ctx context.Context) { + defer func() { + // Clean up go routines. + for _, ch := range p.peers { + close(ch) + } + p.peers = nil + p.topics = nil + }() + + for { + select { + case pid := <-p.newPeers: + if _, ok := p.peers[pid]; ok { + log.Warning("already have connection to peer: ", pid) + continue + } + + if p.blacklist.Contains(pid) { + log.Warning("ignoring connection from blacklisted peer: ", pid) + continue + } + + messages := make(chan *RPC, 32) + messages <- p.getHelloPacket() + go p.handleNewPeer(ctx, pid, messages) + p.peers[pid] = messages + + case s := <-p.newPeerStream: + pid := s.Conn().RemotePeer() + + ch, ok := p.peers[pid] + if !ok { + log.Warning("new stream for unknown peer: ", pid) + s.Reset() + continue + } + + if p.blacklist.Contains(pid) { + log.Warning("closing stream for blacklisted peer: ", pid) + close(ch) + s.Reset() + continue + } + + p.rt.AddPeer(pid, s.Protocol()) + + case pid := <-p.newPeerError: + delete(p.peers, pid) + + case pid := <-p.peerDead: + ch, ok := p.peers[pid] + if !ok { + continue + } + + close(ch) + + if p.host.Network().Connectedness(pid) == network.Connected { + // still connected, must be a duplicate connection being closed. + // we respawn the writer as we need to ensure there is a stream active + log.Warning("peer declared dead but still connected; respawning writer: ", pid) + messages := make(chan *RPC, 32) + messages <- p.getHelloPacket() + go p.handleNewPeer(ctx, pid, messages) + p.peers[pid] = messages + continue + } + + delete(p.peers, pid) + for _, t := range p.topics { + delete(t, pid) + } + + p.rt.RemovePeer(pid) + + case treq := <-p.getTopics: + var out []string + for t := range p.myTopics { + out = append(out, t) + } + treq.resp <- out + case sub := <-p.cancelCh: + p.handleRemoveSubscription(sub) + case sub := <-p.addSub: + p.handleAddSubscription(sub) + case preq := <-p.getPeers: + tmap, ok := p.topics[preq.topic] + if preq.topic != "" && !ok { + preq.resp <- nil + continue + } + var peers []peer.ID + for p := range p.peers { + if preq.topic != "" { + _, ok := tmap[p] + if !ok { + continue + } + } + peers = append(peers, p) + } + preq.resp <- peers + case rpc := <-p.incoming: + p.handleIncomingRPC(rpc) + + case msg := <-p.publish: + p.pushMsg(p.host.ID(), msg) + + case req := <-p.sendMsg: + p.publishMessage(req.from, req.msg.Message) + + case req := <-p.addVal: + p.val.AddValidator(req) + + case req := <-p.rmVal: + p.val.RemoveValidator(req) + + case thunk := <-p.eval: + thunk() + + case pid := <-p.blacklistPeer: + log.Infof("Blacklisting peer %s", pid) + p.blacklist.Add(pid) + + ch, ok := p.peers[pid] + if ok { + close(ch) + delete(p.peers, pid) + for _, t := range p.topics { + delete(t, pid) + } + p.rt.RemovePeer(pid) + } + + case <-ctx.Done(): + log.Info("pubsub processloop shutting down") + return + } + } +} + +// handleRemoveSubscription removes Subscription sub from bookeeping. +// If this was the last Subscription for a given topic, it will also announce +// that this node is not subscribing to this topic anymore. +// Only called from processLoop. +func (p *PubSub) handleRemoveSubscription(sub *Subscription) { + subs := p.myTopics[sub.topic] + + if subs == nil { + return + } + + sub.err = fmt.Errorf("subscription cancelled by calling sub.Cancel()") + close(sub.ch) + delete(subs, sub) + + if len(subs) == 0 { + delete(p.myTopics, sub.topic) + p.announce(sub.topic, false) + p.rt.Leave(sub.topic) + } +} + +// handleAddSubscription adds a Subscription for a particular topic. If it is +// the first Subscription for the topic, it will announce that this node +// subscribes to the topic. +// Only called from processLoop. +func (p *PubSub) handleAddSubscription(req *addSubReq) { + sub := req.sub + subs := p.myTopics[sub.topic] + + // announce we want this topic + if len(subs) == 0 { + p.announce(sub.topic, true) + p.rt.Join(sub.topic) + } + + // make new if not there + if subs == nil { + p.myTopics[sub.topic] = make(map[*Subscription]struct{}) + subs = p.myTopics[sub.topic] + } + + sub.ch = make(chan *Message, 32) + sub.cancelCh = p.cancelCh + + p.myTopics[sub.topic][sub] = struct{}{} + + req.resp <- sub +} + +// announce announces whether or not this node is interested in a given topic +// Only called from processLoop. +func (p *PubSub) announce(topic string, sub bool) { + subopt := &pb.RPC_SubOpts{ + Topicid: &topic, + Subscribe: &sub, + } + + out := rpcWithSubs(subopt) + for pid, peer := range p.peers { + select { + case peer <- out: + default: + log.Infof("Can't send announce message to peer %s: queue full; scheduling retry", pid) + go p.announceRetry(pid, topic, sub) + } + } +} + +func (p *PubSub) announceRetry(pid peer.ID, topic string, sub bool) { + time.Sleep(time.Duration(1+rand.Intn(1000)) * time.Millisecond) + + retry := func() { + _, ok := p.myTopics[topic] + if (ok && sub) || (!ok && !sub) { + p.doAnnounceRetry(pid, topic, sub) + } + } + + select { + case p.eval <- retry: + case <-p.ctx.Done(): + } +} + +func (p *PubSub) doAnnounceRetry(pid peer.ID, topic string, sub bool) { + peer, ok := p.peers[pid] + if !ok { + return + } + + subopt := &pb.RPC_SubOpts{ + Topicid: &topic, + Subscribe: &sub, + } + + out := rpcWithSubs(subopt) + select { + case peer <- out: + default: + log.Infof("Can't send announce message to peer %s: queue full; scheduling retry", pid) + go p.announceRetry(pid, topic, sub) + } +} + +// notifySubs sends a given message to all corresponding subscribers. +// Only called from processLoop. +func (p *PubSub) notifySubs(msg *pb.Message) { + for _, topic := range msg.GetTopicIDs() { + subs := p.myTopics[topic] + for f := range subs { + select { + case f.ch <- &Message{msg}: + default: + log.Infof("Can't deliver message to subscription for topic %s; subscriber too slow", topic) + } + } + } +} + +// seenMessage returns whether we already saw this message before +func (p *PubSub) seenMessage(id string) bool { + p.seenMessagesMx.Lock() + defer p.seenMessagesMx.Unlock() + return p.seenMessages.Has(id) +} + +// markSeen marks a message as seen such that seenMessage returns `true' for the given id +// returns true if the message was freshly marked +func (p *PubSub) markSeen(id string) bool { + p.seenMessagesMx.Lock() + defer p.seenMessagesMx.Unlock() + if p.seenMessages.Has(id) { + return false + } + + p.seenMessages.Add(id) + return true +} + +// subscribedToMessage returns whether we are subscribed to one of the topics +// of a given message +func (p *PubSub) subscribedToMsg(msg *pb.Message) bool { + if len(p.myTopics) == 0 { + return false + } + + for _, t := range msg.GetTopicIDs() { + if _, ok := p.myTopics[t]; ok { + return true + } + } + return false +} + +func (p *PubSub) handleIncomingRPC(rpc *RPC) { + for _, subopt := range rpc.GetSubscriptions() { + t := subopt.GetTopicid() + if subopt.GetSubscribe() { + tmap, ok := p.topics[t] + if !ok { + tmap = make(map[peer.ID]struct{}) + p.topics[t] = tmap + } + + tmap[rpc.from] = struct{}{} + } else { + tmap, ok := p.topics[t] + if !ok { + continue + } + delete(tmap, rpc.from) + } + } + + for _, pmsg := range rpc.GetPublish() { + if !p.subscribedToMsg(pmsg) { + log.Warning("received message we didn't subscribe to. Dropping.") + continue + } + + msg := &Message{pmsg} + p.pushMsg(rpc.from, msg) + } + + p.rt.HandleRPC(rpc) +} + +// msgID returns a unique ID of the passed Message +func msgID(pmsg *pb.Message) string { + return string(pmsg.GetFrom()) + string(pmsg.GetSeqno()) +} + +// pushMsg pushes a message performing validation as necessary +func (p *PubSub) pushMsg(src peer.ID, msg *Message) { + // reject messages from blacklisted peers + if p.blacklist.Contains(src) { + log.Warningf("dropping message from blacklisted peer %s", src) + return + } + + // even if they are forwarded by good peers + if p.blacklist.Contains(msg.GetFrom()) { + log.Warningf("dropping message from blacklisted source %s", src) + return + } + + // reject unsigned messages when strict before we even process the id + if p.signStrict && msg.Signature == nil { + log.Debugf("dropping unsigned message from %s", src) + return + } + + // have we already seen and validated this message? + id := msgID(msg.Message) + if p.seenMessage(id) { + return + } + + if !p.val.Push(src, msg) { + return + } + + if p.markSeen(id) { + p.publishMessage(src, msg.Message) + } +} + +func (p *PubSub) publishMessage(from peer.ID, pmsg *pb.Message) { + p.notifySubs(pmsg) + p.rt.Publish(from, pmsg) +} + +type addSubReq struct { + sub *Subscription + resp chan *Subscription +} + +type SubOpt func(sub *Subscription) error + +// Subscribe returns a new Subscription for the given topic. +// Note that subscription is not an instanteneous operation. It may take some time +// before the subscription is processed by the pubsub main loop and propagated to our peers. +func (p *PubSub) Subscribe(topic string, opts ...SubOpt) (*Subscription, error) { + td := pb.TopicDescriptor{Name: &topic} + + return p.SubscribeByTopicDescriptor(&td, opts...) +} + +// SubscribeByTopicDescriptor lets you subscribe a topic using a pb.TopicDescriptor. +func (p *PubSub) SubscribeByTopicDescriptor(td *pb.TopicDescriptor, opts ...SubOpt) (*Subscription, error) { + if td.GetAuth().GetMode() != pb.TopicDescriptor_AuthOpts_NONE { + return nil, fmt.Errorf("auth mode not yet supported") + } + + if td.GetEnc().GetMode() != pb.TopicDescriptor_EncOpts_NONE { + return nil, fmt.Errorf("encryption mode not yet supported") + } + + sub := &Subscription{ + topic: td.GetName(), + } + + for _, opt := range opts { + err := opt(sub) + if err != nil { + return nil, err + } + } + + out := make(chan *Subscription, 1) + p.addSub <- &addSubReq{ + sub: sub, + resp: out, + } + + return <-out, nil +} + +type topicReq struct { + resp chan []string +} + +// GetTopics returns the topics this node is subscribed to. +func (p *PubSub) GetTopics() []string { + out := make(chan []string, 1) + p.getTopics <- &topicReq{resp: out} + return <-out +} + +// Publish publishes data to the given topic. +func (p *PubSub) Publish(topic string, data []byte) error { + seqno := p.nextSeqno() + m := &pb.Message{ + Data: data, + TopicIDs: []string{topic}, + From: []byte(p.host.ID()), + Seqno: seqno, + } + if p.signKey != nil { + m.From = []byte(p.signID) + err := signMessage(p.signID, p.signKey, m) + if err != nil { + return err + } + } + p.publish <- &Message{m} + return nil +} + +func (p *PubSub) nextSeqno() []byte { + seqno := make([]byte, 8) + counter := atomic.AddUint64(&p.counter, 1) + binary.BigEndian.PutUint64(seqno, counter) + return seqno +} + +type listPeerReq struct { + resp chan []peer.ID + topic string +} + +// sendReq is a request to call publishMessage. +// It is issued after message validation is done. +type sendReq struct { + from peer.ID + msg *Message +} + +// ListPeers returns a list of peers we are connected to in the given topic. +func (p *PubSub) ListPeers(topic string) []peer.ID { + out := make(chan []peer.ID) + p.getPeers <- &listPeerReq{ + resp: out, + topic: topic, + } + return <-out +} + +// BlacklistPeer blacklists a peer; all messages from this peer will be unconditionally dropped. +func (p *PubSub) BlacklistPeer(pid peer.ID) { + p.blacklistPeer <- pid +} + +// RegisterTopicValidator registers a validator for topic. +// By default validators are asynchronous, which means they will run in a separate goroutine. +// The number of active goroutines is controlled by global and per topic validator +// throttles; if it exceeds the throttle threshold, messages will be dropped. +func (p *PubSub) RegisterTopicValidator(topic string, val Validator, opts ...ValidatorOpt) error { + addVal := &addValReq{ + topic: topic, + validate: val, + resp: make(chan error, 1), + } + + for _, opt := range opts { + err := opt(addVal) + if err != nil { + return err + } + } + + p.addVal <- addVal + return <-addVal.resp +} + +// UnregisterTopicValidator removes a validator from a topic. +// Returns an error if there was no validator registered with the topic. +func (p *PubSub) UnregisterTopicValidator(topic string) error { + rmVal := &rmValReq{ + topic: topic, + resp: make(chan error, 1), + } + + p.rmVal <- rmVal + return <-rmVal.resp +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go new file mode 100644 index 00000000..e4304d23 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go @@ -0,0 +1,108 @@ +package pubsub + +import ( + "context" + + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" +) + +const ( + RandomSubID = protocol.ID("/randomsub/1.0.0") +) + +var ( + RandomSubD = 6 +) + +// NewRandomSub returns a new PubSub object using RandomSubRouter as the router. +func NewRandomSub(ctx context.Context, h host.Host, opts ...Option) (*PubSub, error) { + rt := &RandomSubRouter{ + peers: make(map[peer.ID]protocol.ID), + } + return NewPubSub(ctx, h, rt, opts...) +} + +// RandomSubRouter is a router that implements a random propagation strategy. +// For each message, it selects RandomSubD peers and forwards the message to them. +type RandomSubRouter struct { + p *PubSub + peers map[peer.ID]protocol.ID +} + +func (rs *RandomSubRouter) Protocols() []protocol.ID { + return []protocol.ID{RandomSubID, FloodSubID} +} + +func (rs *RandomSubRouter) Attach(p *PubSub) { + rs.p = p +} + +func (rs *RandomSubRouter) AddPeer(p peer.ID, proto protocol.ID) { + rs.peers[p] = proto +} + +func (rs *RandomSubRouter) RemovePeer(p peer.ID) { + delete(rs.peers, p) +} + +func (rs *RandomSubRouter) HandleRPC(rpc *RPC) {} + +func (rs *RandomSubRouter) Publish(from peer.ID, msg *pb.Message) { + tosend := make(map[peer.ID]struct{}) + rspeers := make(map[peer.ID]struct{}) + src := peer.ID(msg.GetFrom()) + + for _, topic := range msg.GetTopicIDs() { + tmap, ok := rs.p.topics[topic] + if !ok { + continue + } + + for p := range tmap { + if p == from || p == src { + continue + } + + if rs.peers[p] == FloodSubID { + tosend[p] = struct{}{} + } else { + rspeers[p] = struct{}{} + } + } + } + + if len(rspeers) > RandomSubD { + xpeers := peerMapToList(rspeers) + shufflePeers(xpeers) + xpeers = xpeers[:RandomSubD] + for _, p := range xpeers { + tosend[p] = struct{}{} + } + } else { + for p := range rspeers { + tosend[p] = struct{}{} + } + } + + out := rpcWithMessages(msg) + for p := range tosend { + mch, ok := rs.p.peers[p] + if !ok { + continue + } + + select { + case mch <- out: + default: + log.Infof("dropping message to peer %s: queue full", p) + } + } +} + +func (rs *RandomSubRouter) Join(topic string) {} + +func (rs *RandomSubRouter) Leave(topic string) {} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go b/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go new file mode 100644 index 00000000..ea76214e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go @@ -0,0 +1,103 @@ +package pubsub + +import ( + "fmt" + + pb "github.com/libp2p/go-libp2p-pubsub/pb" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +const SignPrefix = "libp2p-pubsub:" + +func verifyMessageSignature(m *pb.Message) error { + pubk, err := messagePubKey(m) + if err != nil { + return err + } + + xm := *m + xm.Signature = nil + xm.Key = nil + bytes, err := xm.Marshal() + if err != nil { + return err + } + + bytes = withSignPrefix(bytes) + + valid, err := pubk.Verify(bytes, m.Signature) + if err != nil { + return err + } + + if !valid { + return fmt.Errorf("invalid signature") + } + + return nil +} + +func messagePubKey(m *pb.Message) (crypto.PubKey, error) { + var pubk crypto.PubKey + + pid, err := peer.IDFromBytes(m.From) + if err != nil { + return nil, err + } + + if m.Key == nil { + // no attached key, it must be extractable from the source ID + pubk, err = pid.ExtractPublicKey() + if err != nil { + return nil, fmt.Errorf("cannot extract signing key: %s", err.Error()) + } + if pubk == nil { + return nil, fmt.Errorf("cannot extract signing key") + } + } else { + pubk, err = crypto.UnmarshalPublicKey(m.Key) + if err != nil { + return nil, fmt.Errorf("cannot unmarshal signing key: %s", err.Error()) + } + + // verify that the source ID matches the attached key + if !pid.MatchesPublicKey(pubk) { + return nil, fmt.Errorf("bad signing key; source ID %s doesn't match key", pid) + } + } + + return pubk, nil +} + +func signMessage(pid peer.ID, key crypto.PrivKey, m *pb.Message) error { + bytes, err := m.Marshal() + if err != nil { + return err + } + + bytes = withSignPrefix(bytes) + + sig, err := key.Sign(bytes) + if err != nil { + return err + } + + m.Signature = sig + + pk, _ := pid.ExtractPublicKey() + if pk == nil { + pubk, err := key.GetPublic().Bytes() + if err != nil { + return err + } + m.Key = pubk + } + + return nil +} + +func withSignPrefix(bytes []byte) []byte { + return append([]byte(SignPrefix), bytes...) +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/subscription.go b/vendor/github.com/libp2p/go-libp2p-pubsub/subscription.go new file mode 100644 index 00000000..66a9e513 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/subscription.go @@ -0,0 +1,33 @@ +package pubsub + +import ( + "context" +) + +type Subscription struct { + topic string + ch chan *Message + cancelCh chan<- *Subscription + err error +} + +func (sub *Subscription) Topic() string { + return sub.topic +} + +func (sub *Subscription) Next(ctx context.Context) (*Message, error) { + select { + case msg, ok := <-sub.ch: + if !ok { + return msg, sub.err + } + + return msg, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func (sub *Subscription) Cancel() { + sub.cancelCh <- sub +} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go b/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go new file mode 100644 index 00000000..b7e473d9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go @@ -0,0 +1,391 @@ +package pubsub + +import ( + "context" + "fmt" + "runtime" + "time" + + "github.com/libp2p/go-libp2p-core/peer" +) + +const ( + defaultValidateConcurrency = 1024 + defaultValidateThrottle = 8192 +) + +// Validator is a function that validates a message. +type Validator func(context.Context, peer.ID, *Message) bool + +// ValidatorOpt is an option for RegisterTopicValidator. +type ValidatorOpt func(addVal *addValReq) error + +// validation represents the validator pipeline. +// The validator pipeline performs signature validation and runs a +// sequence of user-configured validators per-topic. It is possible to +// adjust various concurrency parameters, such as the number of +// workers and the max number of simultaneous validations. The user +// can also attach inline validators that will be executed +// synchronously; this may be useful to prevent superfluous +// context-switching for lightweight tasks. +type validation struct { + p *PubSub + + // topicVals tracks per topic validators + topicVals map[string]*topicVal + + // validateQ is the front-end to the validation pipeline + validateQ chan *validateReq + + // validateThrottle limits the number of active validation goroutines + validateThrottle chan struct{} + + // this is the number of synchronous validation workers + validateWorkers int +} + +// validation requests +type validateReq struct { + vals []*topicVal + src peer.ID + msg *Message +} + +// representation of topic validators +type topicVal struct { + topic string + validate Validator + validateTimeout time.Duration + validateThrottle chan struct{} + validateInline bool +} + +// async request to add a topic validators +type addValReq struct { + topic string + validate Validator + timeout time.Duration + throttle int + inline bool + resp chan error +} + +// async request to remove a topic validator +type rmValReq struct { + topic string + resp chan error +} + +// newValidation creates a new validation pipeline +func newValidation() *validation { + return &validation{ + topicVals: make(map[string]*topicVal), + validateQ: make(chan *validateReq, 32), + validateThrottle: make(chan struct{}, defaultValidateThrottle), + validateWorkers: runtime.NumCPU(), + } +} + +// Start attaches the validation pipeline to a pubsub instance and starts background +// workers +func (v *validation) Start(p *PubSub) { + v.p = p + for i := 0; i < v.validateWorkers; i++ { + go v.validateWorker() + } +} + +// AddValidator adds a new validator +func (v *validation) AddValidator(req *addValReq) { + topic := req.topic + + _, ok := v.topicVals[topic] + if ok { + req.resp <- fmt.Errorf("Duplicate validator for topic %s", topic) + return + } + + val := &topicVal{ + topic: topic, + validate: req.validate, + validateTimeout: 0, + validateThrottle: make(chan struct{}, defaultValidateConcurrency), + validateInline: req.inline, + } + + if req.timeout > 0 { + val.validateTimeout = req.timeout + } + + if req.throttle > 0 { + val.validateThrottle = make(chan struct{}, req.throttle) + } + + v.topicVals[topic] = val + req.resp <- nil +} + +// RemoveValidator removes an existing validator +func (v *validation) RemoveValidator(req *rmValReq) { + topic := req.topic + + _, ok := v.topicVals[topic] + if ok { + delete(v.topicVals, topic) + req.resp <- nil + } else { + req.resp <- fmt.Errorf("No validator for topic %s", topic) + } +} + +// Push pushes a message into the validation pipeline. +// It returns true if the message can be forwarded immediately without validation. +func (v *validation) Push(src peer.ID, msg *Message) bool { + vals := v.getValidators(msg) + + if len(vals) > 0 || msg.Signature != nil { + select { + case v.validateQ <- &validateReq{vals, src, msg}: + default: + log.Warningf("message validation throttled; dropping message from %s", src) + } + return false + } + + return true +} + +// getValidators returns all validators that apply to a given message +func (v *validation) getValidators(msg *Message) []*topicVal { + var vals []*topicVal + + for _, topic := range msg.GetTopicIDs() { + val, ok := v.topicVals[topic] + if !ok { + continue + } + + vals = append(vals, val) + } + + return vals +} + +// validateWorker is an active goroutine performing inline validation +func (v *validation) validateWorker() { + for { + select { + case req := <-v.validateQ: + v.validate(req.vals, req.src, req.msg) + case <-v.p.ctx.Done(): + return + } + } +} + +// validate performs validation and only sends the message if all validators succeed +// signature validation is performed synchronously, while user validators are invoked +// asynchronously, throttled by the global validation throttle. +func (v *validation) validate(vals []*topicVal, src peer.ID, msg *Message) { + if msg.Signature != nil { + if !v.validateSignature(msg) { + log.Warningf("message signature validation failed; dropping message from %s", src) + return + } + } + + // we can mark the message as seen now that we have verified the signature + // and avoid invoking user validators more than once + id := msgID(msg.Message) + if !v.p.markSeen(id) { + return + } + + var inline, async []*topicVal + for _, val := range vals { + if val.validateInline { + inline = append(inline, val) + } else { + async = append(async, val) + } + } + + // apply inline (synchronous) validators + for _, val := range inline { + if !val.validateMsg(v.p.ctx, src, msg) { + log.Debugf("message validation failed; dropping message from %s", src) + return + } + } + + // apply async validators + if len(async) > 0 { + select { + case v.validateThrottle <- struct{}{}: + go func() { + v.doValidateTopic(async, src, msg) + <-v.validateThrottle + }() + default: + log.Warningf("message validation throttled; dropping message from %s", src) + } + return + } + + // no async validators, send the message + v.p.sendMsg <- &sendReq{ + from: src, + msg: msg, + } +} + +func (v *validation) validateSignature(msg *Message) bool { + err := verifyMessageSignature(msg.Message) + if err != nil { + log.Debugf("signature verification error: %s", err.Error()) + return false + } + + return true +} + +func (v *validation) doValidateTopic(vals []*topicVal, src peer.ID, msg *Message) { + if !v.validateTopic(vals, src, msg) { + log.Warningf("message validation failed; dropping message from %s", src) + return + } + + v.p.sendMsg <- &sendReq{ + from: src, + msg: msg, + } +} + +func (v *validation) validateTopic(vals []*topicVal, src peer.ID, msg *Message) bool { + if len(vals) == 1 { + return v.validateSingleTopic(vals[0], src, msg) + } + + ctx, cancel := context.WithCancel(v.p.ctx) + defer cancel() + + rch := make(chan bool, len(vals)) + rcount := 0 + throttle := false + +loop: + for _, val := range vals { + rcount++ + + select { + case val.validateThrottle <- struct{}{}: + go func(val *topicVal) { + rch <- val.validateMsg(ctx, src, msg) + <-val.validateThrottle + }(val) + + default: + log.Debugf("validation throttled for topic %s", val.topic) + throttle = true + break loop + } + } + + if throttle { + return false + } + + for i := 0; i < rcount; i++ { + valid := <-rch + if !valid { + return false + } + } + + return true +} + +// fast path for single topic validation that avoids the extra goroutine +func (v *validation) validateSingleTopic(val *topicVal, src peer.ID, msg *Message) bool { + select { + case val.validateThrottle <- struct{}{}: + res := val.validateMsg(v.p.ctx, src, msg) + <-val.validateThrottle + + return res + + default: + log.Debugf("validation throttled for topic %s", val.topic) + return false + } +} + +func (val *topicVal) validateMsg(ctx context.Context, src peer.ID, msg *Message) bool { + if val.validateTimeout > 0 { + var cancel func() + ctx, cancel = context.WithTimeout(ctx, val.validateTimeout) + defer cancel() + } + + valid := val.validate(ctx, src, msg) + if !valid { + log.Debugf("validation failed for topic %s", val.topic) + } + + return valid +} + +/// Options + +// WithValidateThrottle sets the upper bound on the number of active validation +// goroutines across all topics. The default is 8192. +func WithValidateThrottle(n int) Option { + return func(ps *PubSub) error { + ps.val.validateThrottle = make(chan struct{}, n) + return nil + } +} + +// WithValidateWorkers sets the number of synchronous validation worker goroutines. +// Defaults to NumCPU. +// +// The synchronous validation workers perform signature validation, apply inline +// user validators, and schedule asynchronous user validators. +// You can adjust this parameter to devote less cpu time to synchronous validation. +func WithValidateWorkers(n int) Option { + return func(ps *PubSub) error { + if n > 0 { + ps.val.validateWorkers = n + return nil + } + return fmt.Errorf("number of validation workers must be > 0") + } +} + +// WithValidatorTimeout is an option that sets a timeout for an (asynchronous) topic validator. +// By default there is no timeout in asynchronous validators. +func WithValidatorTimeout(timeout time.Duration) ValidatorOpt { + return func(addVal *addValReq) error { + addVal.timeout = timeout + return nil + } +} + +// WithValidatorConcurrency is an option that sets the topic validator throttle. +// This controls the number of active validation goroutines for the topic; the default is 1024. +func WithValidatorConcurrency(n int) ValidatorOpt { + return func(addVal *addValReq) error { + addVal.throttle = n + return nil + } +} + +// WithValidatorInline is an option that sets the validation disposition to synchronous: +// it will be executed inline in validation front-end, without spawning a new goroutine. +// This is suitable for simple or cpu-bound validators that do not block. +func WithValidatorInline(inline bool) ValidatorOpt { + return func(addVal *addValReq) error { + addVal.inline = inline + return nil + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/.travis.yml b/vendor/github.com/libp2p/go-libp2p-quic-transport/.travis.yml new file mode 100644 index 00000000..6188a488 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/.travis.yml @@ -0,0 +1,36 @@ +language: go + +go: + - "1.12.x" + +# first part of the GOARCH workaround +# setting the GOARCH directly doesn't work, since the value will be overwritten later +# so set it to a temporary environment variable first +env: + - TRAVIS_GOARCH=amd64 + - TRAVIS_GOARCH=386 + +# second part of the GOARCH workaround +# now actually set the GOARCH env variable to the value of the temporary variable set earlier +before_install: + - export GO111MODULE=on + - go get golang.org/x/tools/cmd/cover + - go get github.com/onsi/ginkgo/ginkgo + - go get github.com/onsi/gomega + - export GOARCH=$TRAVIS_GOARCH + - go env # for debugging + +# see https://github.com/travis-ci/travis-ci/issues/8361#issuecomment-350090030 +before_script: + - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + +script: + - ginkgo -r -v --cover --randomizeAllSpecs --randomizeSuites --trace --progress + +after_success: + - cat go-libp2p-quic-transport.coverprofile > coverage.txt + - cat */*.coverprofile >> coverage.txt + - bash <(curl -s https://codecov.io/bash) -f coverage.txt + +cache: + directories: diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/README.md b/vendor/github.com/libp2p/go-libp2p-quic-transport/README.md new file mode 100644 index 00000000..e480b1bd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/README.md @@ -0,0 +1,19 @@ +# go-quic-transport + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/libp2p/go-libp2p-quic-transport) +[![Linux Build Status](https://img.shields.io/travis/libp2p/go-libp2p-quic-transport/master.svg?style=flat-square&label=linux+build)](https://travis-ci.org/libp2p/go-libp2p-quic-transport) +[![Code Coverage](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-quic-transport/master.svg?style=flat-square)](https://codecov.io/gh/libp2p/go-libp2p-quic-transport/) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +This is an implementation of the [libp2p transport](https://github.com/libp2p/go-libp2p-transport/blob/master/transport.go) and the [libp2p stream muxer](https://github.com/libp2p/go-stream-muxer) using QUIC. + +## Known limitations + +* currently only works with RSA host keys + +--- + +The last gx published version of this module was: diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/codecov.yml b/vendor/github.com/libp2p/go-libp2p-quic-transport/codecov.yml new file mode 100644 index 00000000..21e0c484 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/codecov.yml @@ -0,0 +1,7 @@ +coverage: + round: nearest + status: + project: + default: + threshold: 0.5 + patch: false diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/conn.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/conn.go new file mode 100644 index 00000000..bf173458 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/conn.go @@ -0,0 +1,81 @@ +package libp2pquic + +import ( + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/peer" + tpt "github.com/libp2p/go-libp2p-core/transport" + + quic "github.com/lucas-clemente/quic-go" + ma "github.com/multiformats/go-multiaddr" +) + +type conn struct { + sess quic.Session + transport tpt.Transport + + localPeer peer.ID + privKey ic.PrivKey + localMultiaddr ma.Multiaddr + + remotePeerID peer.ID + remotePubKey ic.PubKey + remoteMultiaddr ma.Multiaddr +} + +var _ tpt.CapableConn = &conn{} + +func (c *conn) Close() error { + return c.sess.Close() +} + +// IsClosed returns whether a connection is fully closed. +func (c *conn) IsClosed() bool { + return c.sess.Context().Err() != nil +} + +// OpenStream creates a new stream. +func (c *conn) OpenStream() (mux.MuxedStream, error) { + qstr, err := c.sess.OpenStreamSync() + return &stream{Stream: qstr}, err +} + +// AcceptStream accepts a stream opened by the other side. +func (c *conn) AcceptStream() (mux.MuxedStream, error) { + qstr, err := c.sess.AcceptStream() + return &stream{Stream: qstr}, err +} + +// LocalPeer returns our peer ID +func (c *conn) LocalPeer() peer.ID { + return c.localPeer +} + +// LocalPrivateKey returns our private key +func (c *conn) LocalPrivateKey() ic.PrivKey { + return c.privKey +} + +// RemotePeer returns the peer ID of the remote peer. +func (c *conn) RemotePeer() peer.ID { + return c.remotePeerID +} + +// RemotePublicKey returns the public key of the remote peer. +func (c *conn) RemotePublicKey() ic.PubKey { + return c.remotePubKey +} + +// LocalMultiaddr returns the local Multiaddr associated +func (c *conn) LocalMultiaddr() ma.Multiaddr { + return c.localMultiaddr +} + +// RemoteMultiaddr returns the remote Multiaddr associated +func (c *conn) RemoteMultiaddr() ma.Multiaddr { + return c.remoteMultiaddr +} + +func (c *conn) Transport() tpt.Transport { + return c.transport +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/crypto.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/crypto.go new file mode 100644 index 00000000..68a30a62 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/crypto.go @@ -0,0 +1,120 @@ +package libp2pquic + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/tls" + "crypto/x509" + "errors" + "math/big" + "time" + + "github.com/gogo/protobuf/proto" + ic "github.com/libp2p/go-libp2p-core/crypto" + pb "github.com/libp2p/go-libp2p-core/crypto/pb" +) + +// mint certificate selection is broken. +const hostname = "quic.ipfs" + +const certValidityPeriod = 180 * 24 * time.Hour + +func generateConfig(privKey ic.PrivKey) (*tls.Config, error) { + key, hostCert, err := keyToCertificate(privKey) + if err != nil { + return nil, err + } + // The ephemeral key used just for a couple of connections (or a limited time). + ephemeralKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + // Sign the ephemeral key using the host key. + // This is the only time that the host's private key of the peer is needed. + // Note that this step could be done asynchronously, such that a running node doesn't need access its private key at all. + certTemplate := &x509.Certificate{ + DNSNames: []string{hostname}, + SerialNumber: big.NewInt(1), + NotBefore: time.Now().Add(-24 * time.Hour), + NotAfter: time.Now().Add(certValidityPeriod), + } + certDER, err := x509.CreateCertificate(rand.Reader, certTemplate, hostCert, ephemeralKey.Public(), key) + if err != nil { + return nil, err + } + cert, err := x509.ParseCertificate(certDER) + if err != nil { + return nil, err + } + return &tls.Config{ + ServerName: hostname, + InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves. + ClientAuth: tls.RequireAnyClientCert, + Certificates: []tls.Certificate{{ + Certificate: [][]byte{cert.Raw, hostCert.Raw}, + PrivateKey: ephemeralKey, + }}, + }, nil +} + +func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) { + if len(chain) != 2 { + return nil, errors.New("expected 2 certificates in the chain") + } + pool := x509.NewCertPool() + pool.AddCert(chain[1]) + if _, err := chain[0].Verify(x509.VerifyOptions{Roots: pool}); err != nil { + return nil, err + } + remotePubKey, err := x509.MarshalPKIXPublicKey(chain[1].PublicKey) + if err != nil { + return nil, err + } + return ic.UnmarshalRsaPublicKey(remotePubKey) +} + +func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) { + sn, err := rand.Int(rand.Reader, big.NewInt(1<<62)) + if err != nil { + return nil, nil, err + } + tmpl := &x509.Certificate{ + SerialNumber: sn, + NotBefore: time.Now().Add(-24 * time.Hour), + NotAfter: time.Now().Add(certValidityPeriod), + IsCA: true, + BasicConstraintsValid: true, + } + + var publicKey, privateKey interface{} + keyBytes, err := sk.Bytes() + if err != nil { + return nil, nil, err + } + pbmes := new(pb.PrivateKey) + if err := proto.Unmarshal(keyBytes, pbmes); err != nil { + return nil, nil, err + } + switch pbmes.GetType() { + case pb.KeyType_RSA: + k, err := x509.ParsePKCS1PrivateKey(pbmes.GetData()) + if err != nil { + return nil, nil, err + } + publicKey = &k.PublicKey + privateKey = k + // TODO: add support for ECDSA + default: + return nil, nil, errors.New("unsupported key type for TLS") + } + certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, publicKey, privateKey) + if err != nil { + return nil, nil, err + } + cert, err := x509.ParseCertificate(certDER) + if err != nil { + return nil, nil, err + } + return privateKey, cert, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/go.mod b/vendor/github.com/libp2p/go-libp2p-quic-transport/go.mod new file mode 100644 index 00000000..c5bdc64c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/go.mod @@ -0,0 +1,12 @@ +module github.com/libp2p/go-libp2p-quic-transport + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/lucas-clemente/quic-go v0.11.2 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/onsi/ginkgo v1.7.0 + github.com/onsi/gomega v1.4.3 + github.com/whyrusleeping/mafmt v1.2.8 +) diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/go.sum b/vendor/github.com/libp2p/go-libp2p-quic-transport/go.sum new file mode 100644 index 00000000..9018cdf2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/go.sum @@ -0,0 +1,103 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/lucas-clemente/quic-go v0.11.2 h1:Mop0ac3zALaBR3wGs6j8OYe/tcFvFsxTUFMkE/7yUOI= +github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= +github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= +github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/listener.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/listener.go new file mode 100644 index 00000000..327af2f4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/listener.go @@ -0,0 +1,114 @@ +package libp2pquic + +import ( + "crypto/tls" + "net" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + tpt "github.com/libp2p/go-libp2p-core/transport" + + quic "github.com/lucas-clemente/quic-go" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +var quicListenAddr = quic.ListenAddr + +// A listener listens for QUIC connections. +type listener struct { + quicListener quic.Listener + transport tpt.Transport + + privKey ic.PrivKey + localPeer peer.ID + localMultiaddr ma.Multiaddr +} + +var _ tpt.Listener = &listener{} + +func newListener(addr ma.Multiaddr, transport tpt.Transport, localPeer peer.ID, key ic.PrivKey, tlsConf *tls.Config) (tpt.Listener, error) { + lnet, host, err := manet.DialArgs(addr) + if err != nil { + return nil, err + } + laddr, err := net.ResolveUDPAddr(lnet, host) + if err != nil { + return nil, err + } + conn, err := net.ListenUDP(lnet, laddr) + if err != nil { + return nil, err + } + ln, err := quic.Listen(conn, tlsConf, quicConfig) + if err != nil { + return nil, err + } + localMultiaddr, err := toQuicMultiaddr(ln.Addr()) + if err != nil { + return nil, err + } + return &listener{ + quicListener: ln, + transport: transport, + privKey: key, + localPeer: localPeer, + localMultiaddr: localMultiaddr, + }, nil +} + +// Accept accepts new connections. +func (l *listener) Accept() (tpt.CapableConn, error) { + for { + sess, err := l.quicListener.Accept() + if err != nil { + return nil, err + } + conn, err := l.setupConn(sess) + if err != nil { + sess.CloseWithError(0, err) + continue + } + return conn, nil + } +} + +func (l *listener) setupConn(sess quic.Session) (tpt.CapableConn, error) { + remotePubKey, err := getRemotePubKey(sess.ConnectionState().PeerCertificates) + if err != nil { + return nil, err + } + remotePeerID, err := peer.IDFromPublicKey(remotePubKey) + if err != nil { + return nil, err + } + remoteMultiaddr, err := toQuicMultiaddr(sess.RemoteAddr()) + if err != nil { + return nil, err + } + return &conn{ + sess: sess, + transport: l.transport, + localPeer: l.localPeer, + localMultiaddr: l.localMultiaddr, + privKey: l.privKey, + remoteMultiaddr: remoteMultiaddr, + remotePeerID: remotePeerID, + remotePubKey: remotePubKey, + }, nil +} + +// Close closes the listener. +func (l *listener) Close() error { + return l.quicListener.Close() +} + +// Addr returns the address of this listener. +func (l *listener) Addr() net.Addr { + return l.quicListener.Addr() +} + +// Multiaddr returns the multiaddress of this listener. +func (l *listener) Multiaddr() ma.Multiaddr { + return l.localMultiaddr +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/quic_multiaddr.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/quic_multiaddr.go new file mode 100644 index 00000000..8b182b76 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/quic_multiaddr.go @@ -0,0 +1,30 @@ +package libp2pquic + +import ( + "net" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +var quicMA ma.Multiaddr + +func init() { + var err error + quicMA, err = ma.NewMultiaddr("/quic") + if err != nil { + panic(err) + } +} + +func toQuicMultiaddr(na net.Addr) (ma.Multiaddr, error) { + udpMA, err := manet.FromNetAddr(na) + if err != nil { + return nil, err + } + return udpMA.Encapsulate(quicMA), nil +} + +func fromQuicMultiaddr(addr ma.Multiaddr) (net.Addr, error) { + return manet.ToNetAddr(addr.Decapsulate(quicMA)) +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/stream.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/stream.go new file mode 100644 index 00000000..e757de20 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/stream.go @@ -0,0 +1,19 @@ +package libp2pquic + +import ( + "github.com/libp2p/go-libp2p-core/mux" + + quic "github.com/lucas-clemente/quic-go" +) + +type stream struct { + quic.Stream +} + +var _ mux.MuxedStream = &stream{} + +func (s *stream) Reset() error { + s.Stream.CancelRead(0) + s.Stream.CancelWrite(0) + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-quic-transport/transport.go b/vendor/github.com/libp2p/go-libp2p-quic-transport/transport.go new file mode 100644 index 00000000..c33b2417 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-quic-transport/transport.go @@ -0,0 +1,182 @@ +package libp2pquic + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net" + "sync" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + tpt "github.com/libp2p/go-libp2p-core/transport" + + quic "github.com/lucas-clemente/quic-go" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" + "github.com/whyrusleeping/mafmt" +) + +var quicConfig = &quic.Config{ + MaxIncomingStreams: 1000, + MaxIncomingUniStreams: -1, // disable unidirectional streams + MaxReceiveStreamFlowControlWindow: 3 * (1 << 20), // 3 MB + MaxReceiveConnectionFlowControlWindow: 4.5 * (1 << 20), // 4.5 MB + AcceptCookie: func(clientAddr net.Addr, cookie *quic.Cookie) bool { + // TODO(#6): require source address validation when under load + return true + }, + KeepAlive: true, +} + +type connManager struct { + mutex sync.Mutex + + connIPv4 net.PacketConn + connIPv6 net.PacketConn +} + +func (c *connManager) GetConnForAddr(network string) (net.PacketConn, error) { + c.mutex.Lock() + defer c.mutex.Unlock() + + switch network { + case "udp4": + if c.connIPv4 != nil { + return c.connIPv4, nil + } + var err error + c.connIPv4, err = c.createConn(network, "0.0.0.0:0") + return c.connIPv4, err + case "udp6": + if c.connIPv6 != nil { + return c.connIPv6, nil + } + var err error + c.connIPv6, err = c.createConn(network, ":0") + return c.connIPv6, err + default: + return nil, fmt.Errorf("unsupported network: %s", network) + } +} + +func (c *connManager) createConn(network, host string) (net.PacketConn, error) { + addr, err := net.ResolveUDPAddr(network, host) + if err != nil { + return nil, err + } + return net.ListenUDP(network, addr) +} + +// The Transport implements the tpt.Transport interface for QUIC connections. +type transport struct { + privKey ic.PrivKey + localPeer peer.ID + tlsConf *tls.Config + connManager *connManager +} + +var _ tpt.Transport = &transport{} + +// NewTransport creates a new QUIC transport +func NewTransport(key ic.PrivKey) (tpt.Transport, error) { + localPeer, err := peer.IDFromPrivateKey(key) + if err != nil { + return nil, err + } + tlsConf, err := generateConfig(key) + if err != nil { + return nil, err + } + + return &transport{ + privKey: key, + localPeer: localPeer, + tlsConf: tlsConf, + connManager: &connManager{}, + }, nil +} + +// Dial dials a new QUIC connection +func (t *transport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tpt.CapableConn, error) { + network, host, err := manet.DialArgs(raddr) + if err != nil { + return nil, err + } + pconn, err := t.connManager.GetConnForAddr(network) + if err != nil { + return nil, err + } + addr, err := fromQuicMultiaddr(raddr) + if err != nil { + return nil, err + } + var remotePubKey ic.PubKey + tlsConf := t.tlsConf.Clone() + // We need to check the peer ID in the VerifyPeerCertificate callback. + // The tls.Config it is also used for listening, and we might also have concurrent dials. + // Clone it so we can check for the specific peer ID we're dialing here. + tlsConf.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + chain := make([]*x509.Certificate, len(rawCerts)) + for i := 0; i < len(rawCerts); i++ { + cert, err := x509.ParseCertificate(rawCerts[i]) + if err != nil { + return err + } + chain[i] = cert + } + var err error + remotePubKey, err = getRemotePubKey(chain) + if err != nil { + return err + } + if !p.MatchesPublicKey(remotePubKey) { + return errors.New("peer IDs don't match") + } + return nil + } + sess, err := quic.DialContext(ctx, pconn, addr, host, tlsConf, quicConfig) + if err != nil { + return nil, err + } + localMultiaddr, err := toQuicMultiaddr(sess.LocalAddr()) + if err != nil { + return nil, err + } + return &conn{ + sess: sess, + transport: t, + privKey: t.privKey, + localPeer: t.localPeer, + localMultiaddr: localMultiaddr, + remotePubKey: remotePubKey, + remotePeerID: p, + remoteMultiaddr: raddr, + }, nil +} + +// CanDial determines if we can dial to an address +func (t *transport) CanDial(addr ma.Multiaddr) bool { + return mafmt.QUIC.Matches(addr) +} + +// Listen listens for new QUIC connections on the passed multiaddr. +func (t *transport) Listen(addr ma.Multiaddr) (tpt.Listener, error) { + return newListener(addr, t, t.localPeer, t.privKey, t.tlsConf) +} + +// Proxy returns true if this transport proxies. +func (t *transport) Proxy() bool { + return false +} + +// Protocols returns the set of protocols handled by this transport. +func (t *transport) Protocols() []int { + return []int{ma.P_QUIC} +} + +func (t *transport) String() string { + return "QUIC" +} diff --git a/vendor/github.com/libp2p/go-libp2p-record/.travis.yml b/vendor/github.com/libp2p/go-libp2p-record/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-record/LICENSE b/vendor/github.com/libp2p/go-libp2p-record/LICENSE new file mode 100644 index 00000000..808d2e01 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 libp2p + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-libp2p-record/README.md b/vendor/github.com/libp2p/go-libp2p-record/README.md new file mode 100644 index 00000000..63fe5011 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/README.md @@ -0,0 +1,30 @@ +# go-libp2p-record + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> signed records for use with routing systems + +## Documenation + +See https://godoc.org/github.com/libp2p/go-libp2p-record. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-key/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 4.1.15: QmbeHtaBy9nZsW4cHRcvgVY4CnDhXudE2Dr6qDxS7yg9rX diff --git a/vendor/github.com/libp2p/go-libp2p-record/codecov.yml b/vendor/github.com/libp2p/go-libp2p-record/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-record/go.mod b/vendor/github.com/libp2p/go-libp2p-record/go.mod new file mode 100644 index 00000000..3e24bfb4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/go.mod @@ -0,0 +1,9 @@ +module github.com/libp2p/go-libp2p-record + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multihash v0.0.5 +) diff --git a/vendor/github.com/libp2p/go-libp2p-record/go.sum b/vendor/github.com/libp2p/go-libp2p-record/go.sum new file mode 100644 index 00000000..fd61127d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/go.sum @@ -0,0 +1,90 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-record/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-record/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-record/pb/record.pb.go b/vendor/github.com/libp2p/go-libp2p-record/pb/record.pb.go new file mode 100644 index 00000000..e8b679b6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/pb/record.pb.go @@ -0,0 +1,458 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: record.proto + +package record_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// Record represents a dht record that contains a value +// for a key value pair +type Record struct { + // The key that references this record + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The actual value this record is storing + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Time the record was received, set by receiver + TimeReceived string `protobuf:"bytes,5,opt,name=timeReceived,proto3" json:"timeReceived,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Record) Reset() { *m = Record{} } +func (m *Record) String() string { return proto.CompactTextString(m) } +func (*Record) ProtoMessage() {} +func (*Record) Descriptor() ([]byte, []int) { + return fileDescriptor_bf94fd919e302a1d, []int{0} +} +func (m *Record) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Record) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Record.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Record) XXX_Merge(src proto.Message) { + xxx_messageInfo_Record.Merge(m, src) +} +func (m *Record) XXX_Size() int { + return m.Size() +} +func (m *Record) XXX_DiscardUnknown() { + xxx_messageInfo_Record.DiscardUnknown(m) +} + +var xxx_messageInfo_Record proto.InternalMessageInfo + +func (m *Record) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *Record) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *Record) GetTimeReceived() string { + if m != nil { + return m.TimeReceived + } + return "" +} + +func init() { + proto.RegisterType((*Record)(nil), "record.pb.Record") +} + +func init() { proto.RegisterFile("record.proto", fileDescriptor_bf94fd919e302a1d) } + +var fileDescriptor_bf94fd919e302a1d = []byte{ + // 125 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0x4d, 0xce, + 0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x42, 0xb8, + 0xd8, 0x82, 0xc0, 0x1c, 0x21, 0x01, 0x2e, 0xe6, 0xec, 0xd4, 0x4a, 0x09, 0x46, 0x05, 0x46, 0x0d, + 0x9e, 0x20, 0x10, 0x53, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, 0x34, 0x55, 0x82, 0x09, 0x2c, + 0x06, 0xe1, 0x08, 0x29, 0x71, 0xf1, 0x94, 0x64, 0xe6, 0xa6, 0x06, 0xa5, 0x26, 0xa7, 0x66, 0x96, + 0xa5, 0xa6, 0x48, 0xb0, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0xa1, 0x88, 0x39, 0xf1, 0x9c, 0x78, 0x24, + 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x49, 0x6c, 0x60, 0x5b, 0x8d, 0x01, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x64, 0x43, 0x08, 0x1c, 0x85, 0x00, 0x00, 0x00, +} + +func (m *Record) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Record) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Key) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRecord(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRecord(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + if len(m.TimeReceived) > 0 { + dAtA[i] = 0x2a + i++ + i = encodeVarintRecord(dAtA, i, uint64(len(m.TimeReceived))) + i += copy(dAtA[i:], m.TimeReceived) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintRecord(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Record) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRecord(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovRecord(uint64(l)) + } + l = len(m.TimeReceived) + if l > 0 { + n += 1 + l + sovRecord(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovRecord(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRecord(x uint64) (n int) { + return sovRecord(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Record) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Record: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeReceived", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRecord + } + 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 ErrInvalidLengthRecord + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TimeReceived = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRecord + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRecord(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthRecord + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthRecord + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRecord(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthRecord + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-record/pb/record.proto b/vendor/github.com/libp2p/go-libp2p-record/pb/record.proto new file mode 100644 index 00000000..0720c8bc --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/pb/record.proto @@ -0,0 +1,27 @@ +// In order to re-generate the golang packages for `Record` you will need... +// 1. Protobuf binary (tested with protoc 3.0.0). - https://github.com/gogo/protobuf/releases +// 2. Gogo Protobuf (tested with gogo 0.3). - https://github.com/gogo/protobuf +// Now from `libp2p/go-libp2p-record/pb` you can run... +// `protoc --gogo_out=. record.proto` + +syntax = "proto3"; +package record.pb; + +// Record represents a dht record that contains a value +// for a key value pair +message Record { + // The key that references this record + bytes key = 1; + + // The actual value this record is storing + bytes value = 2; + + // Note: These fields were removed from the Record message + // hash of the authors public key + //optional string author = 3; + // A PKI signature for the key+value+author + //optional bytes signature = 4; + + // Time the record was received, set by receiver + string timeReceived = 5; +} diff --git a/vendor/github.com/libp2p/go-libp2p-record/pubkey.go b/vendor/github.com/libp2p/go-libp2p-record/pubkey.go new file mode 100644 index 00000000..02fc88b0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/pubkey.go @@ -0,0 +1,47 @@ +package record + +import ( + "bytes" + "errors" + "fmt" + + u "github.com/ipfs/go-ipfs-util" + mh "github.com/multiformats/go-multihash" +) + +// PublicKeyValidator is a Validator that validates public keys. +type PublicKeyValidator struct{} + +// Validate conforms to the Validator interface. +// +// It verifies that the passed in record value is the PublicKey that matches the +// passed in key. +func (pkv PublicKeyValidator) Validate(key string, value []byte) error { + ns, key, err := SplitKey(key) + if err != nil { + return err + } + if ns != "pk" { + return errors.New("namespace not 'pk'") + } + + keyhash := []byte(key) + if _, err := mh.Cast(keyhash); err != nil { + return fmt.Errorf("key did not contain valid multihash: %s", err) + } + + pkh := u.Hash(value) + if !bytes.Equal(keyhash, pkh) { + return errors.New("public key does not match storage key") + } + return nil +} + +// Select conforms to the Validator interface. +// +// It always returns 0 as all public keys are equivalently valid. +func (pkv PublicKeyValidator) Select(k string, vals [][]byte) (int, error) { + return 0, nil +} + +var _ Validator = PublicKeyValidator{} diff --git a/vendor/github.com/libp2p/go-libp2p-record/record.go b/vendor/github.com/libp2p/go-libp2p-record/record.go new file mode 100644 index 00000000..86b16d09 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/record.go @@ -0,0 +1,13 @@ +package record + +import ( + pb "github.com/libp2p/go-libp2p-record/pb" +) + +// MakePutRecord creates a dht record for the given key/value pair +func MakePutRecord(key string, value []byte) *pb.Record { + record := new(pb.Record) + record.Key = []byte(key) + record.Value = value + return record +} diff --git a/vendor/github.com/libp2p/go-libp2p-record/util.go b/vendor/github.com/libp2p/go-libp2p-record/util.go new file mode 100644 index 00000000..3870600f --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/util.go @@ -0,0 +1,22 @@ +package record + +import ( + "strings" +) + +// SplitKey takes a key in the form `/$namespace/$path` and splits it into +// `$namespace` and `$path`. +func SplitKey(key string) (string, string, error) { + if len(key) == 0 || key[0] != '/' { + return "", "", ErrInvalidRecordType + } + + key = key[1:] + + i := strings.IndexByte(key, '/') + if i <= 0 { + return "", "", ErrInvalidRecordType + } + + return key[:i], key[i+1:], nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-record/validator.go b/vendor/github.com/libp2p/go-libp2p-record/validator.go new file mode 100644 index 00000000..ed0475f1 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-record/validator.go @@ -0,0 +1,63 @@ +package record + +import ( + "errors" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("routing/record") + +// ErrInvalidRecordType is returned if a DHTRecord keys prefix +// is not found in the Validator map of the DHT. +var ErrInvalidRecordType = errors.New("invalid record keytype") + +// Validator is an interface that should be implemented by record validators. +type Validator interface { + // Validate validates the given record, returning an error if it's + // invalid (e.g., expired, signed by the wrong key, etc.). + Validate(key string, value []byte) error + + // Select selects the best record from the set of records (e.g., the + // newest). + // + // Decisions made by select should be stable. + Select(key string, values [][]byte) (int, error) +} + +// NamespacedValidator is a validator that delegates to sub-validators by +// namespace. +type NamespacedValidator map[string]Validator + +// ValidatorByKey looks up the validator responsible for validating the given +// key. +func (v NamespacedValidator) ValidatorByKey(key string) Validator { + ns, _, err := SplitKey(key) + if err != nil { + return nil + } + return v[ns] +} + +// Validate conforms to the Validator interface. +func (v NamespacedValidator) Validate(key string, value []byte) error { + vi := v.ValidatorByKey(key) + if vi == nil { + return ErrInvalidRecordType + } + return vi.Validate(key, value) +} + +// Select conforms to the Validator interface. +func (v NamespacedValidator) Select(key string, values [][]byte) (int, error) { + if len(values) == 0 { + return 0, errors.New("can't select from no values") + } + vi := v.ValidatorByKey(key) + if vi == nil { + return 0, ErrInvalidRecordType + } + return vi.Select(key, values) +} + +var _ Validator = NamespacedValidator{} diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/.travis.yml b/vendor/github.com/libp2p/go-libp2p-routing-helpers/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/LICENSE b/vendor/github.com/libp2p/go-libp2p-routing-helpers/LICENSE new file mode 100644 index 00000000..6cccfc2b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/README.md b/vendor/github.com/libp2p/go-libp2p-routing-helpers/README.md new file mode 100644 index 00000000..9a551e7b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/README.md @@ -0,0 +1,33 @@ +# go-libp2p-routing-helpers + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-routing-helpers?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-routing-helpers) +[![Coverage Status](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-routing-helpers.svg?style=flat-square&branch=master)](https://codecov.io/github/libp2p/go-libp2p-routing-helpers?branch=master) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-routing-helpers.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-routing-helpers) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A collection of helper types for composing different types of routers. + +## Documenation + +See https://godoc.org/github.com/libp2p/go-libp2p-routing-helpers. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-routing-helpers/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 0.4.0: QmXwV9RskR8vpoYWu9bvKAeAWaBKyxEsEiM9yy6ezbpNBm diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/bootstrap.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/bootstrap.go new file mode 100644 index 00000000..e8bb5e8a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/bootstrap.go @@ -0,0 +1,14 @@ +package routinghelpers + +import ( + "context" +) + +// TODO: Consider moving this to the routing package? + +// Bootstrap is an interface that should be implemented by any routers wishing +// to be bootstrapped. +type Bootstrap interface { + // Bootstrap bootstraps the router. + Bootstrap(ctx context.Context) error +} diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/composed.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/composed.go new file mode 100644 index 00000000..5ffa0d02 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/composed.go @@ -0,0 +1,122 @@ +package routinghelpers + +import ( + "context" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + multierror "github.com/hashicorp/go-multierror" + cid "github.com/ipfs/go-cid" +) + +// Compose composes the components into a single router. Not specifying a +// component (leaving it nil) is equivalent to specifying the Null router. +// +// It also implements Bootstrap. All *distinct* components implementing +// Bootstrap will be bootstrapped in parallel. Identical components will not be +// bootstrapped twice. +type Compose struct { + ValueStore routing.ValueStore + PeerRouting routing.PeerRouting + ContentRouting routing.ContentRouting +} + +// note: we implement these methods explicitly to avoid having to manually +// specify the Null router everywhere we don't want to implement some +// functionality. + +// PutValue adds value corresponding to given Key. +func (cr *Compose) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error { + if cr.ValueStore == nil { + return routing.ErrNotSupported + } + return cr.ValueStore.PutValue(ctx, key, value, opts...) +} + +// GetValue searches for the value corresponding to given Key. +func (cr *Compose) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + if cr.ValueStore == nil { + return nil, routing.ErrNotFound + } + return cr.ValueStore.GetValue(ctx, key, opts...) +} + +// SearchValue searches for the value corresponding to given Key. +func (cr *Compose) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + if cr.ValueStore == nil { + out := make(chan []byte) + close(out) + return out, nil + } + return cr.ValueStore.SearchValue(ctx, key, opts...) +} + +// Provide adds the given cid to the content routing system. If 'true' is +// passed, it also announces it, otherwise it is just kept in the local +// accounting of which objects are being provided. +func (cr *Compose) Provide(ctx context.Context, c cid.Cid, local bool) error { + if cr.ContentRouting == nil { + return routing.ErrNotSupported + } + return cr.ContentRouting.Provide(ctx, c, local) +} + +// FindProvidersAsync searches for peers who are able to provide a given key +func (cr *Compose) FindProvidersAsync(ctx context.Context, c cid.Cid, count int) <-chan peer.AddrInfo { + if cr.ContentRouting == nil { + ch := make(chan peer.AddrInfo) + close(ch) + return ch + } + return cr.ContentRouting.FindProvidersAsync(ctx, c, count) +} + +// FindPeer searches for a peer with given ID, returns a peer.AddrInfo +// with relevant addresses. +func (cr *Compose) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + if cr.PeerRouting == nil { + return peer.AddrInfo{}, routing.ErrNotFound + } + return cr.PeerRouting.FindPeer(ctx, p) +} + +// GetPublicKey returns the public key for the given peer. +func (cr *Compose) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) { + if cr.ValueStore == nil { + return nil, routing.ErrNotFound + } + return routing.GetPublicKey(cr.ValueStore, ctx, p) +} + +// Bootstrap the router. +func (cr *Compose) Bootstrap(ctx context.Context) error { + // Deduplicate. Technically, calling bootstrap multiple times shouldn't + // be an issue but using the same router for multiple fields of Compose + // is common. + routers := make(map[Bootstrap]struct{}, 3) + for _, value := range [...]interface{}{ + cr.ValueStore, + cr.ContentRouting, + cr.PeerRouting, + } { + switch b := value.(type) { + case nil: + case Null: + case Bootstrap: + routers[b] = struct{}{} + } + } + + var me multierror.Error + for b := range routers { + if err := b.Bootstrap(ctx); err != nil { + me.Errors = append(me.Errors, err) + } + } + return me.ErrorOrNil() +} + +var _ routing.Routing = (*Compose)(nil) +var _ routing.PubKeyFetcher = (*Compose)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.mod b/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.mod new file mode 100644 index 00000000..43aeb8ce --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.mod @@ -0,0 +1,10 @@ +module github.com/libp2p/go-libp2p-routing-helpers + +require ( + github.com/hashicorp/errwrap v1.0.0 + github.com/hashicorp/go-multierror v1.0.0 + github.com/ipfs/go-cid v0.0.2 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-record v0.1.0 + github.com/multiformats/go-multihash v0.0.5 +) diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.sum b/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.sum new file mode 100644 index 00000000..2917e51e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/go.sum @@ -0,0 +1,118 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/limited.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/limited.go new file mode 100644 index 00000000..bc1187f5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/limited.go @@ -0,0 +1,81 @@ +package routinghelpers + +import ( + "context" + "strings" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" +) + +// LimitedValueStore limits the internal value store to the given namespaces. +type LimitedValueStore struct { + routing.ValueStore + Namespaces []string +} + +// GetPublicKey returns the public key for the given peer. +func (lvs *LimitedValueStore) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) { + for _, ns := range lvs.Namespaces { + if ns == "pk" { + return routing.GetPublicKey(lvs.ValueStore, ctx, p) + } + } + return nil, routing.ErrNotFound +} + +// PutValue returns ErrNotSupported +func (lvs *LimitedValueStore) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error { + if !lvs.KeySupported(key) { + return routing.ErrNotSupported + } + return lvs.ValueStore.PutValue(ctx, key, value, opts...) +} + +// KeySupported returns true if the passed key is supported by this value store. +func (lvs *LimitedValueStore) KeySupported(key string) bool { + if len(key) < 3 { + return false + } + if key[0] != '/' { + return false + } + key = key[1:] + for _, ns := range lvs.Namespaces { + if len(ns) < len(key) && strings.HasPrefix(key, ns) && key[len(ns)] == '/' { + return true + } + } + return false +} + +// GetValue returns routing.ErrNotFound if key isn't supported +func (lvs *LimitedValueStore) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + if !lvs.KeySupported(key) { + return nil, routing.ErrNotFound + } + return lvs.ValueStore.GetValue(ctx, key, opts...) +} + +// SearchValue returns empty channel if key isn't supported or calls SearchValue +// on the underlying ValueStore +func (lvs *LimitedValueStore) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + if !lvs.KeySupported(key) { + out := make(chan []byte) + close(out) + return out, nil + } + return lvs.ValueStore.SearchValue(ctx, key, opts...) +} + +func (lvs *LimitedValueStore) Bootstrap(ctx context.Context) error { + if bs, ok := lvs.ValueStore.(Bootstrap); ok { + return bs.Bootstrap(ctx) + } + return nil +} + +var _ routing.PubKeyFetcher = (*LimitedValueStore)(nil) +var _ routing.ValueStore = (*LimitedValueStore)(nil) +var _ Bootstrap = (*LimitedValueStore)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/null.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/null.go new file mode 100644 index 00000000..6a69d697 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/null.go @@ -0,0 +1,52 @@ +package routinghelpers + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + "github.com/ipfs/go-cid" +) + +// Null is a router that doesn't do anything. +type Null struct{} + +// PutValue always returns ErrNotSupported +func (nr Null) PutValue(context.Context, string, []byte, ...routing.Option) error { + return routing.ErrNotSupported +} + +// GetValue always returns ErrNotFound +func (nr Null) GetValue(context.Context, string, ...routing.Option) ([]byte, error) { + return nil, routing.ErrNotFound +} + +// SearchValue always returns ErrNotFound +func (nr Null) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + return nil, routing.ErrNotFound +} + +// Provide always returns ErrNotSupported +func (nr Null) Provide(context.Context, cid.Cid, bool) error { + return routing.ErrNotSupported +} + +// FindProvidersAsync always returns a closed channel +func (nr Null) FindProvidersAsync(context.Context, cid.Cid, int) <-chan peer.AddrInfo { + ch := make(chan peer.AddrInfo) + close(ch) + return ch +} + +// FindPeer always returns ErrNotFound +func (nr Null) FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) { + return peer.AddrInfo{}, routing.ErrNotFound +} + +// Bootstrap always succeeds instantly +func (nr Null) Bootstrap(context.Context) error { + return nil +} + +var _ routing.Routing = Null{} diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/parallel.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/parallel.go new file mode 100644 index 00000000..14e272a5 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/parallel.go @@ -0,0 +1,508 @@ +package routinghelpers + +import ( + "bytes" + "context" + "reflect" + "sync" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + multierror "github.com/hashicorp/go-multierror" + cid "github.com/ipfs/go-cid" + record "github.com/libp2p/go-libp2p-record" +) + +// Parallel operates on the slice of routers in parallel. +type Parallel struct { + Routers []routing.Routing + Validator record.Validator +} + +// Helper function that sees through router composition to avoid unnecessary +// go routines. +func supportsKey(vs routing.ValueStore, key string) bool { + switch vs := vs.(type) { + case Null: + return false + case *Compose: + return vs.ValueStore != nil && supportsKey(vs.ValueStore, key) + case Parallel: + for _, ri := range vs.Routers { + if supportsKey(ri, key) { + return true + } + } + return false + case Tiered: + for _, ri := range vs.Routers { + if supportsKey(ri, key) { + return true + } + } + return false + case *LimitedValueStore: + return vs.KeySupported(key) && supportsKey(vs.ValueStore, key) + default: + return true + } +} + +func supportsPeer(vs routing.PeerRouting) bool { + switch vs := vs.(type) { + case Null: + return false + case *Compose: + return vs.PeerRouting != nil && supportsPeer(vs.PeerRouting) + case Parallel: + for _, ri := range vs.Routers { + if supportsPeer(ri) { + return true + } + } + return false + case Tiered: + for _, ri := range vs.Routers { + if supportsPeer(ri) { + return true + } + } + return false + default: + return true + } +} + +func supportsContent(vs routing.ContentRouting) bool { + switch vs := vs.(type) { + case Null: + return false + case *Compose: + return vs.ContentRouting != nil && supportsContent(vs.ContentRouting) + case Parallel: + for _, ri := range vs.Routers { + if supportsContent(ri) { + return true + } + } + return false + case Tiered: + for _, ri := range vs.Routers { + if supportsContent(ri) { + return true + } + } + return false + default: + return true + } +} + +func (r Parallel) filter(filter func(routing.Routing) bool) Parallel { + cpy := make([]routing.Routing, 0, len(r.Routers)) + for _, ri := range r.Routers { + if filter(ri) { + cpy = append(cpy, ri) + } + } + return Parallel{Routers: cpy, Validator: r.Validator} +} + +func (r Parallel) put(do func(routing.Routing) error) error { + switch len(r.Routers) { + case 0: + return routing.ErrNotSupported + case 1: + return do(r.Routers[0]) + } + + var wg sync.WaitGroup + results := make([]error, len(r.Routers)) + wg.Add(len(r.Routers)) + for i, ri := range r.Routers { + go func(ri routing.Routing, i int) { + results[i] = do(ri) + wg.Done() + }(ri, i) + } + wg.Wait() + + var ( + errs []error + success bool + ) + for _, err := range results { + switch err { + case nil: + // at least one router supports this. + success = true + case routing.ErrNotSupported: + default: + errs = append(errs, err) + } + } + + switch len(errs) { + case 0: + if success { + // No errors and at least one router succeeded. + return nil + } + // No routers supported this operation. + return routing.ErrNotSupported + case 1: + return errs[0] + default: + return &multierror.Error{Errors: errs} + } +} + +func (r Parallel) search(ctx context.Context, do func(routing.Routing) (<-chan []byte, error)) (<-chan []byte, error) { + switch len(r.Routers) { + case 0: + return nil, routing.ErrNotFound + case 1: + return do(r.Routers[0]) + } + + ctx, cancel := context.WithCancel(ctx) + + out := make(chan []byte) + var errs []error + + var wg sync.WaitGroup + for _, ri := range r.Routers { + vchan, err := do(ri) + switch err { + case nil: + case routing.ErrNotFound, routing.ErrNotSupported: + continue + default: + errs = append(errs, err) + } + + wg.Add(1) + go func() { + var sent int + defer wg.Done() + + for { + select { + case v, ok := <-vchan: + if !ok { + if sent > 0 { + cancel() + } + return + } + + select { + case out <- v: + sent++ + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + } + + go func() { + wg.Wait() + close(out) + cancel() + }() + + return out, nil +} + +func (r Parallel) get(ctx context.Context, do func(routing.Routing) (interface{}, error)) (interface{}, error) { + switch len(r.Routers) { + case 0: + return nil, routing.ErrNotFound + case 1: + return do(r.Routers[0]) + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + results := make(chan struct { + val interface{} + err error + }) + for _, ri := range r.Routers { + go func(ri routing.Routing) { + value, err := do(ri) + select { + case results <- struct { + val interface{} + err error + }{ + val: value, + err: err, + }: + case <-ctx.Done(): + } + }(ri) + } + + var errs []error + for range r.Routers { + select { + case res := <-results: + switch res.err { + case nil: + return res.val, nil + case routing.ErrNotFound, routing.ErrNotSupported: + continue + } + // If the context has expired, just return that error + // and ignore the other errors. + if ctx.Err() != nil { + return nil, ctx.Err() + } + errs = append(errs, res.err) + case <-ctx.Done(): + return nil, ctx.Err() + } + } + + switch len(errs) { + case 0: + return nil, routing.ErrNotFound + case 1: + return nil, errs[0] + default: + return nil, &multierror.Error{Errors: errs} + } +} + +func (r Parallel) forKey(key string) Parallel { + return r.filter(func(ri routing.Routing) bool { + return supportsKey(ri, key) + }) +} + +func (r Parallel) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error { + return r.forKey(key).put(func(ri routing.Routing) error { + return ri.PutValue(ctx, key, value, opts...) + }) +} + +func (r Parallel) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + vInt, err := r.forKey(key).get(ctx, func(ri routing.Routing) (interface{}, error) { + return ri.GetValue(ctx, key, opts...) + }) + val, _ := vInt.([]byte) + return val, err +} + +func (r Parallel) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + resCh, err := r.forKey(key).search(ctx, func(ri routing.Routing) (<-chan []byte, error) { + return ri.SearchValue(ctx, key, opts...) + }) + if err != nil { + return nil, err + } + + valid := make(chan []byte) + var best []byte + go func() { + defer close(valid) + + for v := range resCh { + if best != nil { + n, err := r.Validator.Select(key, [][]byte{best, v}) + if err != nil { + continue + } + if n != 1 { + continue + } + } + if bytes.Equal(best, v) && len(v) != 0 { + continue + } + + best = v + select { + case valid <- v: + case <-ctx.Done(): + return + } + } + }() + + return valid, err +} + +func (r Parallel) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) { + vInt, err := r. + forKey(routing.KeyForPublicKey(p)). + get(ctx, func(ri routing.Routing) (interface{}, error) { + return routing.GetPublicKey(ri, ctx, p) + }) + val, _ := vInt.(ci.PubKey) + return val, err +} + +func (r Parallel) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + vInt, err := r.filter(func(ri routing.Routing) bool { + return supportsPeer(ri) + }).get(ctx, func(ri routing.Routing) (interface{}, error) { + return ri.FindPeer(ctx, p) + }) + pi, _ := vInt.(peer.AddrInfo) + return pi, err +} + +func (r Parallel) Provide(ctx context.Context, c cid.Cid, local bool) error { + return r.filter(func(ri routing.Routing) bool { + return supportsContent(ri) + }).put(func(ri routing.Routing) error { + return ri.Provide(ctx, c, local) + }) +} + +func (r Parallel) FindProvidersAsync(ctx context.Context, c cid.Cid, count int) <-chan peer.AddrInfo { + routers := r.filter(func(ri routing.Routing) bool { + return supportsContent(ri) + }) + + switch len(routers.Routers) { + case 0: + ch := make(chan peer.AddrInfo) + close(ch) + return ch + case 1: + return routers.Routers[0].FindProvidersAsync(ctx, c, count) + } + + out := make(chan peer.AddrInfo) + + ctx, cancel := context.WithCancel(ctx) + + providers := make([]<-chan peer.AddrInfo, len(routers.Routers)) + for i, ri := range routers.Routers { + providers[i] = ri.FindProvidersAsync(ctx, c, count) + } + + go func() { + defer cancel() + defer close(out) + if len(providers) > 8 { + manyProviders(ctx, out, providers, count) + } else { + fewProviders(ctx, out, providers, count) + } + }() + return out +} + +// Unoptimized many provider case. Doing this with reflection is a bit slow but +// definitely simpler. If we start having more than 8 peer routers running in +// parallel, we can revisit this. +func manyProviders(ctx context.Context, out chan<- peer.AddrInfo, in []<-chan peer.AddrInfo, count int) { + found := make(map[peer.ID]struct{}, count) + + selectCases := make([]reflect.SelectCase, len(in)) + for i, ch := range in { + selectCases[i] = reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(ch), + } + } + for count > 0 && len(selectCases) > 0 { + chosen, val, ok := reflect.Select(selectCases) + if !ok { + // Remove the channel + selectCases[chosen] = selectCases[len(selectCases)-1] + selectCases = selectCases[:len(selectCases)-1] + continue + } + + pi := val.Interface().(peer.AddrInfo) + if _, ok := found[pi.ID]; ok { + continue + } + + select { + case out <- pi: + found[pi.ID] = struct{}{} + count-- + case <-ctx.Done(): + return + } + } +} + +// Optimization for few providers (<=8). +func fewProviders(ctx context.Context, out chan<- peer.AddrInfo, in []<-chan peer.AddrInfo, count int) { + if len(in) > 8 { + panic("case only valid for combining fewer than 8 channels") + } + + found := make(map[peer.ID]struct{}, count) + + cases := make([]<-chan peer.AddrInfo, 8) + copy(cases, in) + + // Oh go, what would we do without you! + nch := len(in) + var pi peer.AddrInfo + for nch > 0 && count > 0 { + var ok bool + var selected int + select { + case pi, ok = <-cases[0]: + selected = 0 + case pi, ok = <-cases[1]: + selected = 1 + case pi, ok = <-cases[2]: + selected = 2 + case pi, ok = <-cases[3]: + selected = 3 + case pi, ok = <-cases[4]: + selected = 4 + case pi, ok = <-cases[5]: + selected = 5 + case pi, ok = <-cases[6]: + selected = 6 + case pi, ok = <-cases[7]: + selected = 7 + } + if !ok { + cases[selected] = nil + nch-- + continue + } + if _, ok = found[pi.ID]; ok { + continue + } + + select { + case out <- pi: + found[pi.ID] = struct{}{} + count-- + case <-ctx.Done(): + return + } + } +} + +func (r Parallel) Bootstrap(ctx context.Context) error { + var me multierror.Error + for _, b := range r.Routers { + if err := b.Bootstrap(ctx); err != nil { + me.Errors = append(me.Errors, err) + } + } + return me.ErrorOrNil() +} + +var _ routing.Routing = Parallel{} diff --git a/vendor/github.com/libp2p/go-libp2p-routing-helpers/tiered.go b/vendor/github.com/libp2p/go-libp2p-routing-helpers/tiered.go new file mode 100644 index 00000000..36fa6caf --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing-helpers/tiered.go @@ -0,0 +1,91 @@ +package routinghelpers + +import ( + "context" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + multierror "github.com/hashicorp/go-multierror" + cid "github.com/ipfs/go-cid" + record "github.com/libp2p/go-libp2p-record" +) + +// Tiered is like the Parallel except that GetValue and FindPeer +// are called in series. +type Tiered struct { + Routers []routing.Routing + Validator record.Validator +} + +func (r Tiered) PutValue(ctx context.Context, key string, value []byte, opts ...routing.Option) error { + return Parallel{Routers: r.Routers}.PutValue(ctx, key, value, opts...) +} + +func (r Tiered) get(ctx context.Context, do func(routing.Routing) (interface{}, error)) (interface{}, error) { + var errs []error + for _, ri := range r.Routers { + val, err := do(ri) + switch err { + case nil: + return val, nil + case routing.ErrNotFound, routing.ErrNotSupported: + continue + } + if ctx.Err() != nil { + return nil, ctx.Err() + } + errs = append(errs, err) + } + switch len(errs) { + case 0: + return nil, routing.ErrNotFound + case 1: + return nil, errs[0] + default: + return nil, &multierror.Error{Errors: errs} + } +} + +func (r Tiered) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { + valInt, err := r.get(ctx, func(ri routing.Routing) (interface{}, error) { + return ri.GetValue(ctx, key, opts...) + }) + val, _ := valInt.([]byte) + return val, err +} + +func (r Tiered) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { + return Parallel{Routers: r.Routers, Validator: r.Validator}.SearchValue(ctx, key, opts...) +} + +func (r Tiered) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) { + vInt, err := r.get(ctx, func(ri routing.Routing) (interface{}, error) { + return routing.GetPublicKey(ri, ctx, p) + }) + val, _ := vInt.(ci.PubKey) + return val, err +} + +func (r Tiered) Provide(ctx context.Context, c cid.Cid, local bool) error { + return Parallel{Routers: r.Routers}.Provide(ctx, c, local) +} + +func (r Tiered) FindProvidersAsync(ctx context.Context, c cid.Cid, count int) <-chan peer.AddrInfo { + return Parallel{Routers: r.Routers}.FindProvidersAsync(ctx, c, count) +} + +func (r Tiered) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + valInt, err := r.get(ctx, func(ri routing.Routing) (interface{}, error) { + return ri.FindPeer(ctx, p) + }) + val, _ := valInt.(peer.AddrInfo) + return val, err +} + +func (r Tiered) Bootstrap(ctx context.Context) error { + return Parallel{Routers: r.Routers}.Bootstrap(ctx) +} + +var _ routing.Routing = Tiered{} diff --git a/vendor/github.com/libp2p/go-libp2p-routing/LICENSE b/vendor/github.com/libp2p/go-libp2p-routing/LICENSE new file mode 100644 index 00000000..55a2d036 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-routing/notifications/deprecated.go b/vendor/github.com/libp2p/go-libp2p-routing/notifications/deprecated.go new file mode 100644 index 00000000..29e9e925 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-routing/notifications/deprecated.go @@ -0,0 +1,48 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/routing instead. +package notifications + +import ( + "context" + + core "github.com/libp2p/go-libp2p-core/routing" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/routing/QueryEventType instead. +type QueryEventType = core.QueryEventType + +// Deprecated: use github.com/libp2p/go-libp2p-core/routing/QueryEventBufferSize instead. +// Warning: it's impossible to alias a var in go, so reads and writes to this variable may be inaccurate +// or not have the intended effect. +var QueryEventBufferSize = core.QueryEventBufferSize + +const ( + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/SendingQuery instead. + SendingQuery = core.SendingQuery + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/PeerResponse instead. + PeerResponse = core.PeerResponse + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/FinalPeer instead. + FinalPeer = core.FinalPeer + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/QueryError instead. + QueryError = core.QueryError + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/Provider instead. + Provider = core.Provider + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/Value instead. + Value = core.Value + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/AddingPeer instead. + AddingPeer = core.AddingPeer + // Deprecated: use github.com/libp2p/go-libp2p-core/routing/DialingPeer instead. + DialingPeer = core.DialingPeer +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/routing/QueryEvent instead. +type QueryEvent = core.QueryEvent + +// Deprecated: use github.com/libp2p/go-libp2p-core/routing/RegisterForQueryEvents instead. +func RegisterForQueryEvents(ctx context.Context) (context.Context, <-chan *core.QueryEvent) { + return core.RegisterForQueryEvents(ctx) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/routing/PublishQueryEvent instead. +func PublishQueryEvent(ctx context.Context, ev *core.QueryEvent) { + core.PublishQueryEvent(ctx, ev) +} diff --git a/vendor/github.com/libp2p/go-libp2p-secio/.travis.yml b/vendor/github.com/libp2p/go-libp2p-secio/.travis.yml new file mode 100644 index 00000000..ab4bd3db --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.11.x + - 1.12.x + +env: + global: + - GOTFLAGS="-race -count 2" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-secio/LICENSE b/vendor/github.com/libp2p/go-libp2p-secio/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-secio/README.md b/vendor/github.com/libp2p/go-libp2p-secio/README.md new file mode 100644 index 00000000..ca84a4fd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/README.md @@ -0,0 +1,47 @@ +# go-libp2p-secio + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-secio?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-secio) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-secio.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-secio) + +> go-libp2p's secio encrypted transport + +Package `go-libp2p-secio` is a libp2p [stream security transport](https://github.com/libp2p/go-stream-security). Connections wrapped by `secio` use secure sessions provided by this package to encrypt all traffic. A TLS-like handshake is used to setup the communication channel. + +## Install + +`go-libp2p-secio` is a standard Go module which can be installed with: + +```sh +go get github.com/libp2p/go-libp2p-secio +``` + +This repo is [gomod](https://github.com/golang/go/wiki/Modules)-compatible, and users of +go 1.11 and later with modules enabled will automatically pull the latest tagged release +by referencing this package. Upgrades to future releases can be managed using `go get`, +or by editing your `go.mod` file as [described by the gomod documentation](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies). + +## Usage + +For more information about how `go-libp2p-secio` is used in the libp2p context, you can see the [go-libp2p-conn](https://github.com/libp2p/go-libp2p-conn) module. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-secio/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 2.0.30: QmSVaJe1aRjc78cZARTtf4pqvXERYwihyYhZWoVWceHnsK diff --git a/vendor/github.com/libp2p/go-libp2p-secio/al.go b/vendor/github.com/libp2p/go-libp2p-secio/al.go new file mode 100644 index 00000000..6423f3f2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/al.go @@ -0,0 +1,122 @@ +package secio + +import ( + "errors" + "fmt" + "strings" + + "crypto/aes" + "crypto/cipher" + "crypto/hmac" + "crypto/sha1" + "crypto/sha512" + "hash" + + ci "github.com/libp2p/go-libp2p-core/crypto" + sha256 "github.com/minio/sha256-simd" + bfish "golang.org/x/crypto/blowfish" +) + +// SupportedExchanges is the list of supported ECDH curves +var SupportedExchanges = DefaultSupportedExchanges + +const DefaultSupportedExchanges = "P-256,P-384,P-521" + +// SupportedCiphers is the list of supported Ciphers +var SupportedCiphers = DefaultSupportedCiphers + +const DefaultSupportedCiphers = "AES-256,AES-128,Blowfish" + +// SupportedHashes is the list of supported Hashes +var SupportedHashes = DefaultSupportedHashes + +const DefaultSupportedHashes = "SHA256,SHA512" + +// HMAC carries a hash and its size +type HMAC struct { + hash.Hash + size int +} + +// encParams represent encryption parameters +type encParams struct { + // keys + permanentPubKey ci.PubKey + ephemeralPubKey []byte + keys ci.StretchedKeys + + // selections + curveT string + cipherT string + hashT string + + // cipher + mac + cipher cipher.Stream + mac HMAC +} + +func (e *encParams) makeMacAndCipher() error { + m, err := newMac(e.hashT, e.keys.MacKey) + if err != nil { + return err + } + + bc, err := newBlockCipher(e.cipherT, e.keys.CipherKey) + if err != nil { + return err + } + + e.cipher = cipher.NewCTR(bc, e.keys.IV) + e.mac = m + return nil +} + +func newMac(hashType string, key []byte) (HMAC, error) { + switch hashType { + case "SHA1": + return HMAC{hmac.New(sha1.New, key), sha1.Size}, nil + case "SHA512": + return HMAC{hmac.New(sha512.New, key), sha512.Size}, nil + case "SHA256": + return HMAC{hmac.New(sha256.New, key), sha256.Size}, nil + default: + return HMAC{}, fmt.Errorf("Unrecognized hash type: %s", hashType) + } +} + +func newBlockCipher(cipherT string, key []byte) (cipher.Block, error) { + switch cipherT { + case "AES-128", "AES-256": + return aes.NewCipher(key) + case "Blowfish": + return bfish.NewCipher(key) + default: + return nil, fmt.Errorf("Unrecognized cipher type: %s", cipherT) + } +} + +// Determines which algorithm to use. Note: f(a, b) = f(b, a) +func selectBest(order int, p1, p2 string) (string, error) { + var f, s []string + switch { + case order < 0: + f = strings.Split(p2, ",") + s = strings.Split(p1, ",") + case order > 0: + f = strings.Split(p1, ",") + s = strings.Split(p2, ",") + default: // Exact same preferences. + p := strings.Split(p1, ",") + return p[0], nil + } + + for _, fc := range f { + for _, sc := range s { + if fc == sc { + return fc, nil + } + } + } + + return "", errors.New("No algorithms in common!") +} diff --git a/vendor/github.com/libp2p/go-libp2p-secio/codecov.yml b/vendor/github.com/libp2p/go-libp2p-secio/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-secio/go.mod b/vendor/github.com/libp2p/go-libp2p-secio/go.mod new file mode 100644 index 00000000..259f7549 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/go.mod @@ -0,0 +1,15 @@ +module github.com/libp2p/go-libp2p-secio + +go 1.12 + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.2 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-testing v0.0.2 + github.com/libp2p/go-msgio v0.0.2 + github.com/minio/sha256-simd v0.1.0 + github.com/multiformats/go-multihash v0.0.5 + golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f +) diff --git a/vendor/github.com/libp2p/go-libp2p-secio/go.sum b/vendor/github.com/libp2p/go-libp2p-secio/go.sum new file mode 100644 index 00000000..80a4d90c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/go.sum @@ -0,0 +1,159 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security v0.0.1 h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.0-20190422125857-3a54eb68d178 h1:+wsyafI3SBZy7fMT8bTdHyrzKnPJfDShnbfjxXM3uqk= +github.com/libp2p/go-libp2p-core v0.0.0-20190422125857-3a54eb68d178/go.mod h1:GYAqGjbAd2HxtkR5D6HsOp1ZPBrGvCD0eCLX8rQtNMw= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2-0.20190422130203-0dad27f616de/go.mod h1:WJ6wEfm4tBdTVrgE7Mle69TjHcAxZArSmhNasnU5HXg= +github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-peer v0.0.1 h1:0qwAOljzYewINrU+Kndoc+1jAL7vzY/oY2Go4DCGfyY= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-testing v0.0.2 h1:p9ySW7MFvGGs83hAAe0MPGnjy/tPjl5KyxpMkojdZ+g= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-secio/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-secio/pb/Makefile new file mode 100644 index 00000000..df34e54b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.pb.go b/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.pb.go new file mode 100644 index 00000000..0f3236e2 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.pb.go @@ -0,0 +1,757 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: spipe.proto + +package spipe_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Propose struct { + Rand []byte `protobuf:"bytes,1,opt,name=rand" json:"rand"` + Pubkey []byte `protobuf:"bytes,2,opt,name=pubkey" json:"pubkey"` + Exchanges string `protobuf:"bytes,3,opt,name=exchanges" json:"exchanges"` + Ciphers string `protobuf:"bytes,4,opt,name=ciphers" json:"ciphers"` + Hashes string `protobuf:"bytes,5,opt,name=hashes" json:"hashes"` +} + +func (m *Propose) Reset() { *m = Propose{} } +func (m *Propose) String() string { return proto.CompactTextString(m) } +func (*Propose) ProtoMessage() {} +func (*Propose) Descriptor() ([]byte, []int) { + return fileDescriptor_c474ec75f0379e64, []int{0} +} +func (m *Propose) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Propose) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Propose.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Propose) XXX_Merge(src proto.Message) { + xxx_messageInfo_Propose.Merge(m, src) +} +func (m *Propose) XXX_Size() int { + return m.Size() +} +func (m *Propose) XXX_DiscardUnknown() { + xxx_messageInfo_Propose.DiscardUnknown(m) +} + +var xxx_messageInfo_Propose proto.InternalMessageInfo + +func (m *Propose) GetRand() []byte { + if m != nil { + return m.Rand + } + return nil +} + +func (m *Propose) GetPubkey() []byte { + if m != nil { + return m.Pubkey + } + return nil +} + +func (m *Propose) GetExchanges() string { + if m != nil { + return m.Exchanges + } + return "" +} + +func (m *Propose) GetCiphers() string { + if m != nil { + return m.Ciphers + } + return "" +} + +func (m *Propose) GetHashes() string { + if m != nil { + return m.Hashes + } + return "" +} + +type Exchange struct { + Epubkey []byte `protobuf:"bytes,1,opt,name=epubkey" json:"epubkey"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature"` +} + +func (m *Exchange) Reset() { *m = Exchange{} } +func (m *Exchange) String() string { return proto.CompactTextString(m) } +func (*Exchange) ProtoMessage() {} +func (*Exchange) Descriptor() ([]byte, []int) { + return fileDescriptor_c474ec75f0379e64, []int{1} +} +func (m *Exchange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Exchange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Exchange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Exchange) XXX_Merge(src proto.Message) { + xxx_messageInfo_Exchange.Merge(m, src) +} +func (m *Exchange) XXX_Size() int { + return m.Size() +} +func (m *Exchange) XXX_DiscardUnknown() { + xxx_messageInfo_Exchange.DiscardUnknown(m) +} + +var xxx_messageInfo_Exchange proto.InternalMessageInfo + +func (m *Exchange) GetEpubkey() []byte { + if m != nil { + return m.Epubkey + } + return nil +} + +func (m *Exchange) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func init() { + proto.RegisterType((*Propose)(nil), "spipe.pb.Propose") + proto.RegisterType((*Exchange)(nil), "spipe.pb.Exchange") +} + +func init() { proto.RegisterFile("spipe.proto", fileDescriptor_c474ec75f0379e64) } + +var fileDescriptor_c474ec75f0379e64 = []byte{ + // 207 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0x2e, 0xc8, 0x2c, + 0x48, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x80, 0x72, 0x92, 0x94, 0x16, 0x33, 0x72, + 0xb1, 0x07, 0x14, 0xe5, 0x17, 0xe4, 0x17, 0xa7, 0x0a, 0x49, 0x70, 0xb1, 0x14, 0x25, 0xe6, 0xa5, + 0x48, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x38, 0xb1, 0x9c, 0xb8, 0x27, 0xcf, 0x10, 0x04, 0x16, 0x11, + 0x92, 0xe1, 0x62, 0x2b, 0x28, 0x4d, 0xca, 0x4e, 0xad, 0x94, 0x60, 0x42, 0x92, 0x83, 0x8a, 0x09, + 0x29, 0x71, 0x71, 0xa6, 0x56, 0x24, 0x67, 0x24, 0xe6, 0xa5, 0xa7, 0x16, 0x4b, 0x30, 0x2b, 0x30, + 0x6a, 0x70, 0x42, 0x15, 0x20, 0x84, 0x85, 0xe4, 0xb8, 0xd8, 0x93, 0x33, 0x0b, 0x32, 0x52, 0x8b, + 0x8a, 0x25, 0x58, 0x90, 0x54, 0xc0, 0x04, 0x41, 0x36, 0x64, 0x24, 0x16, 0x67, 0xa4, 0x16, 0x4b, + 0xb0, 0x22, 0x49, 0x43, 0xc5, 0x94, 0xfc, 0xb8, 0x38, 0x5c, 0xa1, 0x46, 0x81, 0x4c, 0x4a, 0x85, + 0x3a, 0x06, 0xd9, 0xa1, 0x30, 0x41, 0x90, 0x6b, 0x8a, 0x33, 0xd3, 0xf3, 0x12, 0x4b, 0x4a, 0x8b, + 0x52, 0x51, 0x9c, 0x8b, 0x10, 0x76, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, + 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, + 0x06, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x0d, 0xc4, 0xcb, 0x27, 0x01, 0x00, 0x00, +} + +func (m *Propose) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Propose) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Rand != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Rand))) + i += copy(dAtA[i:], m.Rand) + } + if m.Pubkey != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Pubkey))) + i += copy(dAtA[i:], m.Pubkey) + } + dAtA[i] = 0x1a + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Exchanges))) + i += copy(dAtA[i:], m.Exchanges) + dAtA[i] = 0x22 + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Ciphers))) + i += copy(dAtA[i:], m.Ciphers) + dAtA[i] = 0x2a + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Hashes))) + i += copy(dAtA[i:], m.Hashes) + return i, nil +} + +func (m *Exchange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Exchange) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Epubkey != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Epubkey))) + i += copy(dAtA[i:], m.Epubkey) + } + if m.Signature != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintSpipe(dAtA, i, uint64(len(m.Signature))) + i += copy(dAtA[i:], m.Signature) + } + return i, nil +} + +func encodeVarintSpipe(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Propose) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Rand != nil { + l = len(m.Rand) + n += 1 + l + sovSpipe(uint64(l)) + } + if m.Pubkey != nil { + l = len(m.Pubkey) + n += 1 + l + sovSpipe(uint64(l)) + } + l = len(m.Exchanges) + n += 1 + l + sovSpipe(uint64(l)) + l = len(m.Ciphers) + n += 1 + l + sovSpipe(uint64(l)) + l = len(m.Hashes) + n += 1 + l + sovSpipe(uint64(l)) + return n +} + +func (m *Exchange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Epubkey != nil { + l = len(m.Epubkey) + n += 1 + l + sovSpipe(uint64(l)) + } + if m.Signature != nil { + l = len(m.Signature) + n += 1 + l + sovSpipe(uint64(l)) + } + return n +} + +func sovSpipe(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozSpipe(x uint64) (n int) { + return sovSpipe(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Propose) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Propose: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Propose: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rand", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpipe + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rand = append(m.Rand[:0], dAtA[iNdEx:postIndex]...) + if m.Rand == nil { + m.Rand = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpipe + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pubkey = append(m.Pubkey[:0], dAtA[iNdEx:postIndex]...) + if m.Pubkey == nil { + m.Pubkey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exchanges", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + 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 ErrInvalidLengthSpipe + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Exchanges = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ciphers", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + 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 ErrInvalidLengthSpipe + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ciphers = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hashes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + 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 ErrInvalidLengthSpipe + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hashes = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpipe(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSpipe + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSpipe + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Exchange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Exchange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Exchange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epubkey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpipe + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epubkey = append(m.Epubkey[:0], dAtA[iNdEx:postIndex]...) + if m.Epubkey == nil { + m.Epubkey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpipe + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpipe + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSpipe + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpipe(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSpipe + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSpipe + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSpipe(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpipe + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpipe + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpipe + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSpipe + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthSpipe + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpipe + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipSpipe(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthSpipe + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthSpipe = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSpipe = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.proto b/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.proto new file mode 100644 index 00000000..ed5f3a78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/pb/spipe.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; + +package spipe.pb; + +message Propose { + optional bytes rand = 1; + optional bytes pubkey = 2; + optional string exchanges = 3; + optional string ciphers = 4; + optional string hashes = 5; +} + +message Exchange { + optional bytes epubkey = 1; + optional bytes signature = 2; +} diff --git a/vendor/github.com/libp2p/go-libp2p-secio/protocol.go b/vendor/github.com/libp2p/go-libp2p-secio/protocol.go new file mode 100644 index 00000000..40848ddd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/protocol.go @@ -0,0 +1,387 @@ +package secio + +import ( + "bytes" + "context" + "crypto/rand" + "errors" + "fmt" + "net" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" + + proto "github.com/gogo/protobuf/proto" + logging "github.com/ipfs/go-log" + ci "github.com/libp2p/go-libp2p-core/crypto" + pb "github.com/libp2p/go-libp2p-secio/pb" + msgio "github.com/libp2p/go-msgio" + mh "github.com/multiformats/go-multihash" +) + +var log = logging.Logger("secio") + +// ErrUnsupportedKeyType is returned when a private key cast/type switch fails. +var ErrUnsupportedKeyType = errors.New("unsupported key type") + +// ErrClosed signals the closing of a connection. +var ErrClosed = errors.New("connection closed") + +// ErrWrongPeer is returned when we attempt to handshake with the wrong peer. +var ErrWrongPeer = errors.New("connected to wrong peer") + +// ErrBadSig signals that the peer sent us a handshake packet with a bad signature. +var ErrBadSig = errors.New("bad signature") + +// ErrEcho is returned when we're attempting to handshake with the same keys and nonces. +var ErrEcho = errors.New("same keys and nonces. one side talking to self") + +// HandshakeTimeout governs how long the handshake will be allowed to take place for. +// Making this number large means there could be many bogus connections waiting to +// timeout in flight. Typical handshakes take ~3RTTs, so it should be completed within +// seconds across a typical planet in the solar system. +var HandshakeTimeout = time.Second * 30 + +// nonceSize is the size of our nonces (in bytes) +const nonceSize = 16 + +// secureSession encapsulates all the parameters needed for encrypting +// and decrypting traffic from an insecure channel. +type secureSession struct { + msgio.ReadWriteCloser + + insecure net.Conn + insecureM msgio.ReadWriter + + localKey ci.PrivKey + localPeer peer.ID + remotePeer peer.ID + + local encParams + remote encParams + + sharedSecret []byte +} + +var _ sec.SecureConn = &secureSession{} + +func (s *secureSession) Loggable() map[string]interface{} { + m := make(map[string]interface{}) + m["localPeer"] = s.localPeer.Pretty() + m["remotePeer"] = s.remotePeer.Pretty() + m["established"] = (s.ReadWriteCloser != nil) + return m +} + +func newSecureSession(ctx context.Context, local peer.ID, key ci.PrivKey, insecure net.Conn, remotePeer peer.ID) (*secureSession, error) { + s := &secureSession{localPeer: local, localKey: key} + + switch { + case s.localPeer == "": + return nil, errors.New("no local id provided") + case s.localKey == nil: + return nil, errors.New("no local private key provided") + case !s.localPeer.MatchesPrivateKey(s.localKey): + return nil, fmt.Errorf("peer.ID does not match PrivateKey") + case insecure == nil: + return nil, fmt.Errorf("insecure ReadWriter is nil") + } + + s.insecure = insecure + s.insecureM = msgio.NewReadWriter(insecure) + s.remotePeer = remotePeer + + handshakeCtx, cancel := context.WithTimeout(ctx, HandshakeTimeout) // remove + defer cancel() + if err := s.runHandshake(handshakeCtx); err != nil { + return nil, err + } + + return s, nil +} + +func hashSha256(data []byte) mh.Multihash { + h, err := mh.Sum(data, mh.SHA2_256, -1) + if err != nil { + // this error can be safely ignored (panic) because multihash only fails + // from the selection of hash function. If the fn + length are valid, it + // won't error. + panic("multihash failed to hash using SHA2_256.") + } + return h +} + +// runHandshake performs initial communication over insecure channel to share +// keys, IDs, and initiate communication, assigning all necessary params. +// requires the duplex channel to be a msgio.ReadWriter (for framed messaging) +func (s *secureSession) runHandshake(ctx context.Context) error { + defer log.EventBegin(ctx, "secureHandshake", s).Done() + + result := make(chan error, 1) + go func() { + // do *not* close the channel (will look like a success). + result <- s.runHandshakeSync() + }() + + var err error + select { + case <-ctx.Done(): + // State unknown. We *have* to close this. + s.insecure.Close() + err = ctx.Err() + case err = <-result: + } + return err +} + +func (s *secureSession) runHandshakeSync() error { + // ============================================================================= + // step 1. Propose -- propose cipher suite + send pubkeys + nonce + + // Generate and send Hello packet. + // Hello = (rand, PublicKey, Supported) + nonceOut := make([]byte, nonceSize) + _, err := rand.Read(nonceOut) + if err != nil { + return err + } + + s.local.permanentPubKey = s.localKey.GetPublic() + myPubKeyBytes, err := s.local.permanentPubKey.Bytes() + if err != nil { + return err + } + + proposeOut := new(pb.Propose) + proposeOut.Rand = nonceOut + proposeOut.Pubkey = myPubKeyBytes + proposeOut.Exchanges = SupportedExchanges + proposeOut.Ciphers = SupportedCiphers + proposeOut.Hashes = SupportedHashes + + // log.Debugf("1.0 Propose: nonce:%s exchanges:%s ciphers:%s hashes:%s", + // nonceOut, SupportedExchanges, SupportedCiphers, SupportedHashes) + + // Marshal our propose packet + proposeOutBytes, err := proto.Marshal(proposeOut) + if err != nil { + return err + } + + // Send Propose packet and Receive their Propose packet + proposeInBytes, err := readWriteMsg(s.insecureM, proposeOutBytes) + if err != nil { + return err + } + defer s.insecureM.ReleaseMsg(proposeInBytes) + + // Parse their propose packet + proposeIn := new(pb.Propose) + if err = proto.Unmarshal(proposeInBytes, proposeIn); err != nil { + return err + } + + // log.Debugf("1.0.1 Propose recv: nonce:%s exchanges:%s ciphers:%s hashes:%s", + // proposeIn.GetRand(), proposeIn.GetExchanges(), proposeIn.GetCiphers(), proposeIn.GetHashes()) + + // ============================================================================= + // step 1.1 Identify -- get identity from their key + + // get remote identity + s.remote.permanentPubKey, err = ci.UnmarshalPublicKey(proposeIn.GetPubkey()) + if err != nil { + return err + } + + // get peer id + actualRemotePeer, err := peer.IDFromPublicKey(s.remote.permanentPubKey) + if err != nil { + return err + } + switch s.remotePeer { + case actualRemotePeer: + // All good. + case "": + // No peer set. We're accepting a remote connection. + s.remotePeer = actualRemotePeer + default: + // Peer mismatch. Bail. + s.insecure.Close() + log.Debugf("expected peer %s, got peer %s", s.remotePeer, actualRemotePeer) + return ErrWrongPeer + } + + log.Debugf("1.1 Identify: %s Remote Peer Identified as %s", s.localPeer, s.remotePeer) + + // ============================================================================= + // step 1.2 Selection -- select/agree on best encryption parameters + + // to determine order, use cmp(H(remote_pubkey||local_rand), H(local_pubkey||remote_rand)). + oh1 := hashSha256(append(proposeIn.GetPubkey(), nonceOut...)) + oh2 := hashSha256(append(myPubKeyBytes, proposeIn.GetRand()...)) + order := bytes.Compare(oh1, oh2) + if order == 0 { + return ErrEcho // talking to self (same socket. must be reuseport + dialing self) + } + + s.local.curveT, err = selectBest(order, SupportedExchanges, proposeIn.GetExchanges()) + if err != nil { + return err + } + + s.local.cipherT, err = selectBest(order, SupportedCiphers, proposeIn.GetCiphers()) + if err != nil { + return err + } + + s.local.hashT, err = selectBest(order, SupportedHashes, proposeIn.GetHashes()) + if err != nil { + return err + } + + // we use the same params for both directions (must choose same curve) + // WARNING: if they dont SelectBest the same way, this won't work... + s.remote.curveT = s.local.curveT + s.remote.cipherT = s.local.cipherT + s.remote.hashT = s.local.hashT + + // log.Debugf("1.2 selection: exchange:%s cipher:%s hash:%s", + // s.local.curveT, s.local.cipherT, s.local.hashT) + + // ============================================================================= + // step 2. Exchange -- exchange (signed) ephemeral keys. verify signatures. + + // Generate EphemeralPubKey + var genSharedKey ci.GenSharedKey + s.local.ephemeralPubKey, genSharedKey, err = ci.GenerateEKeyPair(s.local.curveT) + if err != nil { + return err + } + + // Gather corpus to sign. + selectionOut := new(bytes.Buffer) + selectionOut.Write(proposeOutBytes) + selectionOut.Write(proposeInBytes) + selectionOut.Write(s.local.ephemeralPubKey) + selectionOutBytes := selectionOut.Bytes() + + // log.Debugf("2.0 exchange: %v", selectionOutBytes) + exchangeOut := new(pb.Exchange) + exchangeOut.Epubkey = s.local.ephemeralPubKey + exchangeOut.Signature, err = s.localKey.Sign(selectionOutBytes) + if err != nil { + return err + } + + // Marshal our exchange packet + exchangeOutBytes, err := proto.Marshal(exchangeOut) + if err != nil { + return err + } + + // Send Exchange packet and receive their Exchange packet + exchangeInBytes, err := readWriteMsg(s.insecureM, exchangeOutBytes) + if err != nil { + return err + } + defer s.insecureM.ReleaseMsg(exchangeInBytes) + + // Parse their Exchange packet. + exchangeIn := new(pb.Exchange) + if err = proto.Unmarshal(exchangeInBytes, exchangeIn); err != nil { + return err + } + + // ============================================================================= + // step 2.1. Verify -- verify their exchange packet is good. + + // get their ephemeral pub key + s.remote.ephemeralPubKey = exchangeIn.GetEpubkey() + + selectionIn := new(bytes.Buffer) + selectionIn.Write(proposeInBytes) + selectionIn.Write(proposeOutBytes) + selectionIn.Write(s.remote.ephemeralPubKey) + selectionInBytes := selectionIn.Bytes() + // log.Debugf("2.0.1 exchange recv: %v", selectionInBytes) + + // u.POut("Remote Peer Identified as %s\n", s.remote) + sigOK, err := s.remote.permanentPubKey.Verify(selectionInBytes, exchangeIn.GetSignature()) + if err != nil { + // log.Error("2.1 Verify: failed: %s", err) + return err + } + + if !sigOK { + // log.Error("2.1 Verify: failed: %s", ErrBadSig) + return ErrBadSig + } + // log.Debugf("2.1 Verify: signature verified.") + + // ============================================================================= + // step 2.2. Keys -- generate keys for mac + encryption + + // OK! seems like we're good to go. + s.sharedSecret, err = genSharedKey(exchangeIn.GetEpubkey()) + if err != nil { + return err + } + + // generate two sets of keys (stretching) + k1, k2 := ci.KeyStretcher(s.local.cipherT, s.local.hashT, s.sharedSecret) + + // use random nonces to decide order. + switch { + case order > 0: + // just break + case order < 0: + k1, k2 = k2, k1 // swap + default: + // we should've bailed before this. but if not, bail here. + return ErrEcho + } + s.local.keys = k1 + s.remote.keys = k2 + + // log.Debug("2.2 keys:\n\tshared: %v\n\tk1: %v\n\tk2: %v", + // s.sharedSecret, s.local.keys, s.remote.keys) + + // ============================================================================= + // step 2.3. MAC + Cipher -- prepare MAC + cipher + + if err := s.local.makeMacAndCipher(); err != nil { + return err + } + + if err := s.remote.makeMacAndCipher(); err != nil { + return err + } + + // log.Debug("2.3 mac + cipher.") + + // ============================================================================= + // step 3. Finish -- send expected message to verify encryption works (send local nonce) + + // setup ETM ReadWriter + w := NewETMWriter(s.insecure, s.local.cipher, s.local.mac) + r := NewETMReader(s.insecure, s.remote.cipher, s.remote.mac) + s.ReadWriteCloser = msgio.Combine(w, r).(msgio.ReadWriteCloser) + + // log.Debug("3.0 finish. sending: %v", proposeIn.GetRand()) + + // send their Nonce and receive ours + nonceOut2, err := readWriteMsg(s.ReadWriteCloser, proposeIn.GetRand()) + if err != nil { + return err + } + defer s.ReleaseMsg(nonceOut2) + + // log.Debug("3.0 finish.\n\texpect: %v\n\tactual: %v", nonceOut, nonceOut2) + if !bytes.Equal(nonceOut, nonceOut2) { + return fmt.Errorf("Failed to read our encrypted nonce: %s != %s", nonceOut2, nonceOut) + } + + // Whew! ok, that's all folks. + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-secio/rw.go b/vendor/github.com/libp2p/go-libp2p-secio/rw.go new file mode 100644 index 00000000..6a084023 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/rw.go @@ -0,0 +1,268 @@ +package secio + +import ( + "crypto/cipher" + "crypto/hmac" + "encoding/binary" + "errors" + "fmt" + "io" + "sync" + + pool "github.com/libp2p/go-buffer-pool" + msgio "github.com/libp2p/go-msgio" +) + +// ErrMACInvalid signals that a MAC verification failed +var ErrMACInvalid = errors.New("MAC verification failed") + +type etmWriter struct { + str cipher.Stream // the stream cipher to encrypt with + mac HMAC // the mac to authenticate data with + w io.Writer + + sync.Mutex +} + +// NewETMWriter Encrypt-Then-MAC +func NewETMWriter(w io.Writer, s cipher.Stream, mac HMAC) msgio.WriteCloser { + return &etmWriter{w: w, str: s, mac: mac} +} + +// Write writes passed in buffer as a single message. +func (w *etmWriter) Write(b []byte) (int, error) { + if err := w.WriteMsg(b); err != nil { + return 0, err + } + return len(b), nil +} + +// WriteMsg writes the msg in the passed in buffer. +func (w *etmWriter) WriteMsg(b []byte) error { + w.Lock() + defer w.Unlock() + + // encrypt. + buf := pool.Get(4 + len(b) + w.mac.Size()) + defer pool.Put(buf) + data := buf[4 : 4+len(b)] + w.str.XORKeyStream(data, b) + + // log.Debugf("ENC plaintext (%d): %s %v", len(b), b, b) + // log.Debugf("ENC ciphertext (%d): %s %v", len(data), data, data) + + // then, mac. + if _, err := w.mac.Write(data); err != nil { + return err + } + + // Sum appends. + data = w.mac.Sum(data) + w.mac.Reset() + binary.BigEndian.PutUint32(buf[:4], uint32(len(data))) + + _, err := w.w.Write(buf) + return err +} + +func (w *etmWriter) Close() error { + if c, ok := w.w.(io.Closer); ok { + return c.Close() + } + return nil +} + +type etmReader struct { + msgio.Reader + io.Closer + + // internal buffer returned from the msgio + buf []byte + + // low and high watermark for the buffered data + lowat int + hiwat int + + // params + msg msgio.ReadCloser // msgio for knowing where boundaries lie + str cipher.Stream // the stream cipher to encrypt with + mac HMAC // the mac to authenticate data with + + // internal buffer used for checking MACs, this saves us quite a few + // allocations and should be quite small. + macBuf []byte + + sync.Mutex +} + +// NewETMReader Encrypt-Then-MAC +func NewETMReader(r io.Reader, s cipher.Stream, mac HMAC) msgio.ReadCloser { + return &etmReader{msg: msgio.NewReader(r), str: s, mac: mac} +} + +func (r *etmReader) NextMsgLen() (int, error) { + return r.msg.NextMsgLen() +} + +func (r *etmReader) drain(buf []byte) int { + // Return zero if there is no data remaining in the internal buffer. + if r.lowat == r.hiwat { + return 0 + } + + // Copy data to the output buffer. + n := copy(buf, r.buf[r.lowat:r.hiwat]) + + // Update the low watermark. + r.lowat += n + + // Release the buffer and reset the watermarks if it has been fully read. + if r.lowat == r.hiwat { + r.msg.ReleaseMsg(r.buf) + r.buf = nil + r.lowat = 0 + r.hiwat = 0 + } + + return n +} + +func (r *etmReader) fill() error { + // Read a message from the underlying msgio. + msg, err := r.msg.ReadMsg() + if err != nil { + return err + } + + // Check the MAC. + n, err := r.macCheckThenDecrypt(msg) + if err != nil { + r.msg.ReleaseMsg(msg) + return err + } + + // Retain the buffer so it can be drained from and later released. + r.buf = msg + r.lowat = 0 + r.hiwat = n + + return nil +} + +func (r *etmReader) Read(buf []byte) (int, error) { + r.Lock() + defer r.Unlock() + + // Return buffered data without reading more, if possible. + copied := r.drain(buf) + if copied > 0 { + return copied, nil + } + + // Check the length of the next message. + fullLen, err := r.msg.NextMsgLen() + if err != nil { + return 0, err + } + + // If the destination buffer is too short, fill an internal buffer and then + // drain as much of that into the output buffer as will fit. + if len(buf) < fullLen { + err := r.fill() + if err != nil { + return 0, err + } + + copied := r.drain(buf) + return copied, nil + } + + // Otherwise, read directly into the destination buffer. + n, err := io.ReadFull(r.msg, buf[:fullLen]) + if err != nil { + return 0, err + } + + m, err := r.macCheckThenDecrypt(buf[:n]) + if err != nil { + return 0, err + } + + return m, nil +} + +func (r *etmReader) ReadMsg() ([]byte, error) { + r.Lock() + defer r.Unlock() + + msg, err := r.msg.ReadMsg() + if err != nil { + return nil, err + } + + n, err := r.macCheckThenDecrypt(msg) + if err != nil { + r.msg.ReleaseMsg(msg) + return nil, err + } + return msg[:n], nil +} + +func (r *etmReader) macCheckThenDecrypt(m []byte) (int, error) { + l := len(m) + if l < r.mac.size { + return 0, fmt.Errorf("buffer (%d) shorter than MAC size (%d)", l, r.mac.size) + } + + mark := l - r.mac.size + data := m[:mark] + macd := m[mark:] + + r.mac.Write(data) + r.macBuf = r.mac.Sum(r.macBuf[:0]) + r.mac.Reset() + + // check mac. if failed, return error. + if !hmac.Equal(macd, r.macBuf) { + log.Debug("MAC Invalid:", r.macBuf, "!=", macd) + return 0, ErrMACInvalid + } + + // ok seems good. decrypt. (can decrypt in place, yay!) + // log.Debugf("DEC ciphertext (%d): %s %v", len(data), data, data) + r.str.XORKeyStream(data, data) + // log.Debugf("DEC plaintext (%d): %s %v", len(data), data, data) + + return mark, nil +} + +func (r *etmReader) Close() error { + return r.msg.Close() +} + +// ReleaseMsg signals a buffer can be reused. +func (r *etmReader) ReleaseMsg(b []byte) { + r.msg.ReleaseMsg(b) +} + +// read and write a message at the same time. +func readWriteMsg(c msgio.ReadWriter, out []byte) ([]byte, error) { + wresult := make(chan error) + go func() { + wresult <- c.WriteMsg(out) + }() + + msg, err1 := c.ReadMsg() + + // Always wait for the read to finish. + err2 := <-wresult + + if err1 != nil { + return nil, err1 + } + if err2 != nil { + c.ReleaseMsg(msg) + return nil, err2 + } + return msg, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-secio/transport.go b/vendor/github.com/libp2p/go-libp2p-secio/transport.go new file mode 100644 index 00000000..edd6f8ef --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-secio/transport.go @@ -0,0 +1,81 @@ +// Package secio is used to encrypt `go-libp2p-conn` connections. Connections wrapped by secio use secure sessions provided by this package to encrypt all traffic. A TLS-like handshake is used to setup the communication channel. +package secio + +import ( + "context" + "net" + "time" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" +) + +// ID is secio's protocol ID (used when negotiating with multistream) +const ID = "/secio/1.0.0" + +// SessionGenerator constructs secure communication sessions for a peer. +type Transport struct { + LocalID peer.ID + PrivateKey ci.PrivKey +} + +func New(sk ci.PrivKey) (*Transport, error) { + id, err := peer.IDFromPrivateKey(sk) + if err != nil { + return nil, err + } + return &Transport{ + LocalID: id, + PrivateKey: sk, + }, nil +} + +var _ sec.SecureTransport = (*Transport)(nil) + +func (sg *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { + return newSecureSession(ctx, sg.LocalID, sg.PrivateKey, insecure, "") +} +func (sg *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + return newSecureSession(ctx, sg.LocalID, sg.PrivateKey, insecure, p) +} + +func (s *secureSession) SetReadDeadline(t time.Time) error { + return s.insecure.SetReadDeadline(t) +} + +func (s *secureSession) SetWriteDeadline(t time.Time) error { + return s.insecure.SetWriteDeadline(t) +} + +func (s *secureSession) SetDeadline(t time.Time) error { + return s.insecure.SetDeadline(t) +} + +func (s *secureSession) RemoteAddr() net.Addr { + return s.insecure.RemoteAddr() +} + +func (s *secureSession) LocalAddr() net.Addr { + return s.insecure.LocalAddr() +} + +// LocalPeer retrieves the local peer. +func (s *secureSession) LocalPeer() peer.ID { + return s.localPeer +} + +// LocalPrivateKey retrieves the local peer's PrivateKey +func (s *secureSession) LocalPrivateKey() ci.PrivKey { + return s.localKey +} + +// RemotePeer retrieves the remote peer. +func (s *secureSession) RemotePeer() peer.ID { + return s.remotePeer +} + +// RemotePublicKey retrieves the remote public key. +func (s *secureSession) RemotePublicKey() ci.PubKey { + return s.remote.permanentPubKey +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/.travis.yml b/vendor/github.com/libp2p/go-libp2p-swarm/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/LICENSE b/vendor/github.com/libp2p/go-libp2p-swarm/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/README.md b/vendor/github.com/libp2p/go-libp2p-swarm/README.md new file mode 100644 index 00000000..0675fc25 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/README.md @@ -0,0 +1,156 @@ +go-libp2p-swarm +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-libp2p-swarm/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-libp2p-swarm?branch=master) +[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-swarm.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-swarm) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> The libp2p swarm manages groups of connections to peers, and handles incoming and outgoing streams. + +The libp2p swarm is the 'low level' interface for working with a given libp2p +network. It gives you more fine grained control over various aspects of the +system. Most applications don't need this level of access, so the `Swarm` is +generally wrapped in a `Host` abstraction that provides a more friendly +interface. See [the host interface](https://github.com/libp2p/go-libp2p-host) +for more info on that. + +## Table of Contents + +- [Install](#install) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Usage + +### Creating a swarm +To construct a swarm, you'll be calling `NewSwarm`. That function looks like this: +```go +swarm, err := NewSwarm(ctx, laddrs, pid, pstore, bwc) +``` + +It takes five items to fully construct a swarm, the first is a go +`context.Context`. This controls the lifetime of the swarm, and all swarm +processes have their lifespan derived from the given context. You can just use +`context.Background()` if you're not concerned with that. + +The next argument is an array of multiaddrs that the swarm will open up +listeners for. Once started, the swarm will start accepting and handling +incoming connections on every given address. This argument is optional, you can +pass `nil` and the swarm will not listen for any incoming connections (but will +still be able to dial out to other peers). + +After that, you'll need to give the swarm an identity in the form of a peer.ID. +If you're not wanting to enable secio (libp2p's transport layer encryption), +then you can pick any string for this value. For example `peer.ID("FooBar123")` +would work. Note that passing a random string ID will result in your node not +being able to communicate with other peers that have correctly generated IDs. +To see how to generate a proper ID, see the below section on "Identity +Generation". + +The fourth argument is a peerstore. This is essentially a database that the +swarm will use to store peer IDs, addresses, public keys, protocol preferences +and more. You can construct one by importing +`github.com/libp2p/go-libp2p-peerstore` and calling `peerstore.NewPeerstore()`. + +The final argument is a bandwidth metrics collector, This is used to track +incoming and outgoing bandwidth on connections managed by this swarm. It is +optional, and passing `nil` will simply result in no metrics for connections +being available. + +#### Identity Generation +A proper libp2p identity is PKI based. We currently have support for RSA and ed25519 keys. To create a 'correct' ID, you'll need to either load or generate a new keypair. Here is an example of doing so: + +```go +import ( + "fmt" + "crypto/rand" + + ci "github.com/libp2p/go-libp2p-crypto" + pstore "github.com/libp2p/go-libp2p-peerstore" + peer "github.com/libp2p/go-libp2p-peer" +) + +func demo() { + // First, select a source of entropy. We're using the stdlib's crypto reader here + src := rand.Reader + + // Now create a 2048 bit RSA key using that + priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, 2048, src) + if err != nil { + panic(err) // oh no! + } + + // Now that we have a keypair, lets create our identity from it + pid, err := peer.IDFromPrivateKey(priv) + if err != nil { + panic(err) + } + + // Woo! Identity acquired! + fmt.Println("I am ", pid) + + // Now, for the purposes of building a swarm, lets add this all to a peerstore. + ps := pstore.NewPeerstore() + ps.AddPubKey(pid, pub) + ps.AddPrivKey(pid, priv) + + // Once you've got all that, creating a basic swarm can be as easy as + ctx := context.Background() + swarm, err := NewSwarm(ctx, nil, pid, ps, nil) + + // voila! A functioning swarm! +} +``` + +### Streams +The swarm is designed around using multiplexed streams to communicate with +other peers. When working with a swarm, you will want to set a function to +handle incoming streams from your peers: + +```go +swrm.SetStreamHandler(func(s inet.Stream) { + defer s.Close() + fmt.Println("Got a stream from: ", s.SwarmConn().RemotePeer()) + fmt.Fprintln(s, "Hello Friend!") +}) +``` + +Tip: Always make sure to close streams when you're done with them. + +Opening streams is also pretty simple: +```go +s, err := swrm.NewStreamWithPeer(ctx, rpid) +if err != nil { + panic(err) +} +defer s.Close() + +io.Copy(os.Stdout, s) // pipe the stream to stdout +``` + +Just pass a context and the ID of the peer you want a stream to, and you'll get +back a stream to read and write on. + + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson + +--- + +The last gx published version of this module was: 3.0.35: QmQVoMEL1CxrVusTSUdYsiJXVBnvSqNUpBsGybkwSfksEF diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/addrs.go b/vendor/github.com/libp2p/go-libp2p-swarm/addrs.go new file mode 100644 index 00000000..ed510f26 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/addrs.go @@ -0,0 +1,35 @@ +package swarm + +import ( + mafilter "github.com/libp2p/go-maddr-filter" + mamask "github.com/whyrusleeping/multiaddr-filter" +) + +// http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +var lowTimeoutFilters = mafilter.NewFilters() + +func init() { + for _, p := range []string{ + "/ip4/10.0.0.0/ipcidr/8", + "/ip4/100.64.0.0/ipcidr/10", + "/ip4/169.254.0.0/ipcidr/16", + "/ip4/172.16.0.0/ipcidr/12", + "/ip4/192.0.0.0/ipcidr/24", + "/ip4/192.0.0.0/ipcidr/29", + "/ip4/192.0.0.8/ipcidr/32", + "/ip4/192.0.0.170/ipcidr/32", + "/ip4/192.0.0.171/ipcidr/32", + "/ip4/192.0.2.0/ipcidr/24", + "/ip4/192.168.0.0/ipcidr/16", + "/ip4/198.18.0.0/ipcidr/15", + "/ip4/198.51.100.0/ipcidr/24", + "/ip4/203.0.113.0/ipcidr/24", + "/ip4/240.0.0.0/ipcidr/4", + } { + f, err := mamask.NewMask(p) + if err != nil { + panic("error in lowTimeoutFilters init: " + err.Error()) + } + lowTimeoutFilters.AddDialFilter(f) + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/codecov.yml b/vendor/github.com/libp2p/go-libp2p-swarm/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/dial_error.go b/vendor/github.com/libp2p/go-libp2p-swarm/dial_error.go new file mode 100644 index 00000000..d2179617 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/dial_error.go @@ -0,0 +1,70 @@ +package swarm + +import ( + "fmt" + "strings" + + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +// maxDialDialErrors is the maximum number of dial errors we record +const maxDialDialErrors = 16 + +// DialError is the error type returned when dialing. +type DialError struct { + Peer peer.ID + DialErrors []TransportError + Cause error + Skipped int +} + +func (e *DialError) recordErr(addr ma.Multiaddr, err error) { + if len(e.DialErrors) >= maxDialDialErrors { + e.Skipped++ + return + } + e.DialErrors = append(e.DialErrors, TransportError{ + Address: addr, + Cause: err, + }) +} + +func (e *DialError) Error() string { + var builder strings.Builder + fmt.Fprintf(&builder, "failed to dial %s:", e.Peer) + if e.Cause != nil { + fmt.Fprintf(&builder, " %s", e.Cause) + } + for _, te := range e.DialErrors { + fmt.Fprintf(&builder, "\n * [%s] %s", te.Address, te.Cause) + } + if e.Skipped > 0 { + fmt.Fprintf(&builder, "\n ... skipping %d errors ...", e.Skipped) + } + return builder.String() +} + +// Unwrap implements https://godoc.org/golang.org/x/xerrors#Wrapper. +func (e *DialError) Unwrap() error { + // If we have a context error, that's the "ultimate" error. + if e.Cause != nil { + return e.Cause + } + return nil +} + +var _ error = (*DialError)(nil) + +// TransportError is the error returned when dialing a specific address. +type TransportError struct { + Address ma.Multiaddr + Cause error +} + +func (e *TransportError) Error() string { + return fmt.Sprintf("failed to dial %s: %s", e.Address, e.Cause) +} + +var _ error = (*TransportError)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/dial_sync.go b/vendor/github.com/libp2p/go-libp2p-swarm/dial_sync.go new file mode 100644 index 00000000..f746b9a9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/dial_sync.go @@ -0,0 +1,122 @@ +package swarm + +import ( + "context" + "sync" + + "github.com/libp2p/go-libp2p-core/peer" +) + +// DialFunc is the type of function expected by DialSync. +type DialFunc func(context.Context, peer.ID) (*Conn, error) + +// NewDialSync constructs a new DialSync +func NewDialSync(dfn DialFunc) *DialSync { + return &DialSync{ + dials: make(map[peer.ID]*activeDial), + dialFunc: dfn, + } +} + +// DialSync is a dial synchronization helper that ensures that at most one dial +// to any given peer is active at any given time. +type DialSync struct { + dials map[peer.ID]*activeDial + dialsLk sync.Mutex + dialFunc DialFunc +} + +type activeDial struct { + id peer.ID + refCnt int + refCntLk sync.Mutex + cancel func() + + err error + conn *Conn + waitch chan struct{} + + ds *DialSync +} + +func (ad *activeDial) wait(ctx context.Context) (*Conn, error) { + defer ad.decref() + select { + case <-ad.waitch: + return ad.conn, ad.err + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func (ad *activeDial) incref() { + ad.refCntLk.Lock() + defer ad.refCntLk.Unlock() + ad.refCnt++ +} + +func (ad *activeDial) decref() { + ad.refCntLk.Lock() + ad.refCnt-- + maybeZero := (ad.refCnt <= 0) + ad.refCntLk.Unlock() + + // make sure to always take locks in correct order. + if maybeZero { + ad.ds.dialsLk.Lock() + ad.refCntLk.Lock() + // check again after lock swap drop to make sure nobody else called incref + // in between locks + if ad.refCnt <= 0 { + ad.cancel() + delete(ad.ds.dials, ad.id) + } + ad.refCntLk.Unlock() + ad.ds.dialsLk.Unlock() + } +} + +func (ad *activeDial) start(ctx context.Context) { + ad.conn, ad.err = ad.ds.dialFunc(ctx, ad.id) + close(ad.waitch) + ad.cancel() +} + +func (ds *DialSync) getActiveDial(p peer.ID) *activeDial { + ds.dialsLk.Lock() + defer ds.dialsLk.Unlock() + + actd, ok := ds.dials[p] + if !ok { + adctx, cancel := context.WithCancel(context.Background()) + actd = &activeDial{ + id: p, + cancel: cancel, + waitch: make(chan struct{}), + ds: ds, + } + ds.dials[p] = actd + + go actd.start(adctx) + } + + // increase ref count before dropping dialsLk + actd.incref() + + return actd +} + +// DialLock initiates a dial to the given peer if there are none in progress +// then waits for the dial to that peer to complete. +func (ds *DialSync) DialLock(ctx context.Context, p peer.ID) (*Conn, error) { + return ds.getActiveDial(p).wait(ctx) +} + +// CancelDial cancels all in-progress dials to the given peer. +func (ds *DialSync) CancelDial(p peer.ID) { + ds.dialsLk.Lock() + defer ds.dialsLk.Unlock() + if ad, ok := ds.dials[p]; ok { + ad.cancel() + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/go.mod b/vendor/github.com/libp2p/go-libp2p-swarm/go.mod new file mode 100644 index 00000000..6d3662d9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/go.mod @@ -0,0 +1,22 @@ +module github.com/libp2p/go-libp2p-swarm + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/goprocess v0.1.3 + github.com/libp2p/go-addr-util v0.0.1 + github.com/libp2p/go-conn-security-multistream v0.1.0 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-loggables v0.1.0 + github.com/libp2p/go-libp2p-peerstore v0.1.0 + github.com/libp2p/go-libp2p-secio v0.1.0 + github.com/libp2p/go-libp2p-testing v0.0.3 + github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 + github.com/libp2p/go-libp2p-yamux v0.2.0 + github.com/libp2p/go-maddr-filter v0.0.4 + github.com/libp2p/go-stream-muxer-multistream v0.2.0 + github.com/libp2p/go-tcp-transport v0.1.0 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/whyrusleeping/mafmt v1.2.8 + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 +) diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/go.sum b/vendor/github.com/libp2p/go-libp2p-swarm/go.sum new file mode 100644 index 00000000..256f3314 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/go.sum @@ -0,0 +1,202 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/limiter.go b/vendor/github.com/libp2p/go-libp2p-swarm/limiter.go new file mode 100644 index 00000000..6808dd71 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/limiter.go @@ -0,0 +1,226 @@ +package swarm + +import ( + "context" + "os" + "strconv" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + + addrutil "github.com/libp2p/go-addr-util" + ma "github.com/multiformats/go-multiaddr" +) + +type dialResult struct { + Conn transport.CapableConn + Addr ma.Multiaddr + Err error +} + +type dialJob struct { + addr ma.Multiaddr + peer peer.ID + ctx context.Context + resp chan dialResult +} + +func (dj *dialJob) cancelled() bool { + return dj.ctx.Err() != nil +} + +func (dj *dialJob) dialTimeout() time.Duration { + timeout := transport.DialTimeout + if lowTimeoutFilters.AddrBlocked(dj.addr) { + timeout = DialTimeoutLocal + } + + return timeout +} + +type dialLimiter struct { + lk sync.Mutex + + fdConsuming int + fdLimit int + waitingOnFd []*dialJob + + dialFunc dialfunc + + activePerPeer map[peer.ID]int + perPeerLimit int + waitingOnPeerLimit map[peer.ID][]*dialJob +} + +type dialfunc func(context.Context, peer.ID, ma.Multiaddr) (transport.CapableConn, error) + +func newDialLimiter(df dialfunc) *dialLimiter { + fd := ConcurrentFdDials + if env := os.Getenv("LIBP2P_SWARM_FD_LIMIT"); env != "" { + if n, err := strconv.ParseInt(env, 10, 32); err == nil { + fd = int(n) + } + } + return newDialLimiterWithParams(df, fd, DefaultPerPeerRateLimit) +} + +func newDialLimiterWithParams(df dialfunc, fdLimit, perPeerLimit int) *dialLimiter { + return &dialLimiter{ + fdLimit: fdLimit, + perPeerLimit: perPeerLimit, + waitingOnPeerLimit: make(map[peer.ID][]*dialJob), + activePerPeer: make(map[peer.ID]int), + dialFunc: df, + } +} + +// freeFDToken frees FD token and if there are any schedules another waiting dialJob +// in it's place +func (dl *dialLimiter) freeFDToken() { + log.Debugf("[limiter] freeing FD token; waiting: %d; consuming: %d", len(dl.waitingOnFd), dl.fdConsuming) + dl.fdConsuming-- + + for len(dl.waitingOnFd) > 0 { + next := dl.waitingOnFd[0] + dl.waitingOnFd[0] = nil // clear out memory + dl.waitingOnFd = dl.waitingOnFd[1:] + + if len(dl.waitingOnFd) == 0 { + // clear out memory. + dl.waitingOnFd = nil + } + + // Skip over canceled dials instead of queuing up a goroutine. + if next.cancelled() { + dl.freePeerToken(next) + continue + } + dl.fdConsuming++ + + // we already have activePerPeer token at this point so we can just dial + go dl.executeDial(next) + return + } +} + +func (dl *dialLimiter) freePeerToken(dj *dialJob) { + log.Debugf("[limiter] freeing peer token; peer %s; addr: %s; active for peer: %d; waiting on peer limit: %d", + dj.peer, dj.addr, dl.activePerPeer[dj.peer], len(dl.waitingOnPeerLimit[dj.peer])) + // release tokens in reverse order than we take them + dl.activePerPeer[dj.peer]-- + if dl.activePerPeer[dj.peer] == 0 { + delete(dl.activePerPeer, dj.peer) + } + + waitlist := dl.waitingOnPeerLimit[dj.peer] + for len(waitlist) > 0 { + next := waitlist[0] + waitlist[0] = nil // clear out memory + waitlist = waitlist[1:] + + if len(waitlist) == 0 { + delete(dl.waitingOnPeerLimit, next.peer) + } else { + dl.waitingOnPeerLimit[next.peer] = waitlist + } + + if next.cancelled() { + continue + } + + dl.activePerPeer[next.peer]++ // just kidding, we still want this token + + dl.addCheckFdLimit(next) + return + } +} + +func (dl *dialLimiter) finishedDial(dj *dialJob) { + dl.lk.Lock() + defer dl.lk.Unlock() + + if addrutil.IsFDCostlyTransport(dj.addr) { + dl.freeFDToken() + } + + dl.freePeerToken(dj) +} + +func (dl *dialLimiter) addCheckFdLimit(dj *dialJob) { + if addrutil.IsFDCostlyTransport(dj.addr) { + if dl.fdConsuming >= dl.fdLimit { + log.Debugf("[limiter] blocked dial waiting on FD token; peer: %s; addr: %s; consuming: %d; "+ + "limit: %d; waiting: %d", dj.peer, dj.addr, dl.fdConsuming, dl.fdLimit, len(dl.waitingOnFd)) + dl.waitingOnFd = append(dl.waitingOnFd, dj) + return + } + + log.Debugf("[limiter] taking FD token: peer: %s; addr: %s; prev consuming: %d", + dj.peer, dj.addr, dl.fdConsuming) + // take token + dl.fdConsuming++ + } + + log.Debugf("[limiter] executing dial; peer: %s; addr: %s; FD consuming: %d; waiting: %d", + dj.peer, dj.addr, dl.fdConsuming, len(dl.waitingOnFd)) + go dl.executeDial(dj) +} + +func (dl *dialLimiter) addCheckPeerLimit(dj *dialJob) { + if dl.activePerPeer[dj.peer] >= dl.perPeerLimit { + log.Debugf("[limiter] blocked dial waiting on peer limit; peer: %s; addr: %s; active: %d; "+ + "peer limit: %d; waiting: %d", dj.peer, dj.addr, dl.activePerPeer[dj.peer], dl.perPeerLimit, + len(dl.waitingOnPeerLimit[dj.peer])) + wlist := dl.waitingOnPeerLimit[dj.peer] + dl.waitingOnPeerLimit[dj.peer] = append(wlist, dj) + return + } + dl.activePerPeer[dj.peer]++ + + dl.addCheckFdLimit(dj) +} + +// AddDialJob tries to take the needed tokens for starting the given dial job. +// If it acquires all needed tokens, it immediately starts the dial, otherwise +// it will put it on the waitlist for the requested token. +func (dl *dialLimiter) AddDialJob(dj *dialJob) { + dl.lk.Lock() + defer dl.lk.Unlock() + + log.Debugf("[limiter] adding a dial job through limiter: %v", dj.addr) + dl.addCheckPeerLimit(dj) +} + +func (dl *dialLimiter) clearAllPeerDials(p peer.ID) { + dl.lk.Lock() + defer dl.lk.Unlock() + delete(dl.waitingOnPeerLimit, p) + log.Debugf("[limiter] clearing all peer dials: %v", p) + // NB: the waitingOnFd list doesn't need to be cleaned out here, we will + // remove them as we encounter them because they are 'cancelled' at this + // point +} + +// executeDial calls the dialFunc, and reports the result through the response +// channel when finished. Once the response is sent it also releases all tokens +// it held during the dial. +func (dl *dialLimiter) executeDial(j *dialJob) { + defer dl.finishedDial(j) + if j.cancelled() { + return + } + + dctx, cancel := context.WithTimeout(j.ctx, j.dialTimeout()) + defer cancel() + + con, err := dl.dialFunc(dctx, j.peer, j.addr) + select { + case j.resp <- dialResult{Conn: con, Addr: j.addr, Err: err}: + case <-j.ctx.Done(): + if err == nil { + con.Close() + } + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm.go new file mode 100644 index 00000000..b14e9cf0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm.go @@ -0,0 +1,506 @@ +package swarm + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/transport" + + logging "github.com/ipfs/go-log" + "github.com/jbenet/goprocess" + goprocessctx "github.com/jbenet/goprocess/context" + + filter "github.com/libp2p/go-maddr-filter" + mafilter "github.com/whyrusleeping/multiaddr-filter" +) + +// DialTimeoutLocal is the maximum duration a Dial to local network address +// is allowed to take. +// This includes the time between dialing the raw network connection, +// protocol selection as well the handshake, if applicable. +var DialTimeoutLocal = 5 * time.Second + +var log = logging.Logger("swarm2") + +// ErrSwarmClosed is returned when one attempts to operate on a closed swarm. +var ErrSwarmClosed = errors.New("swarm closed") + +// ErrAddrFiltered is returned when trying to register a connection to a +// filtered address. You shouldn't see this error unless some underlying +// transport is misbehaving. +var ErrAddrFiltered = errors.New("address filtered") + +// Swarm is a connection muxer, allowing connections to other peers to +// be opened and closed, while still using the same Chan for all +// communication. The Chan sends/receives Messages, which note the +// destination or source Peer. +type Swarm struct { + // Close refcount. This allows us to fully wait for the swarm to be torn + // down before continuing. + refs sync.WaitGroup + + local peer.ID + peers peerstore.Peerstore + + conns struct { + sync.RWMutex + m map[peer.ID][]*Conn + } + + listeners struct { + sync.RWMutex + m map[transport.Listener]struct{} + } + + notifs struct { + sync.RWMutex + m map[network.Notifiee]struct{} + } + + transports struct { + sync.RWMutex + m map[int]transport.Transport + } + + // new connection and stream handlers + connh atomic.Value + streamh atomic.Value + + // dialing helpers + dsync *DialSync + backf DialBackoff + limiter *dialLimiter + + // filters for addresses that shouldnt be dialed (or accepted) + Filters *filter.Filters + + proc goprocess.Process + ctx context.Context + bwc metrics.Reporter +} + +// NewSwarm constructs a Swarm +func NewSwarm(ctx context.Context, local peer.ID, peers peerstore.Peerstore, bwc metrics.Reporter) *Swarm { + s := &Swarm{ + local: local, + peers: peers, + bwc: bwc, + Filters: filter.NewFilters(), + } + + s.conns.m = make(map[peer.ID][]*Conn) + s.listeners.m = make(map[transport.Listener]struct{}) + s.transports.m = make(map[int]transport.Transport) + s.notifs.m = make(map[network.Notifiee]struct{}) + + s.dsync = NewDialSync(s.doDial) + s.limiter = newDialLimiter(s.dialAddr) + s.proc = goprocessctx.WithContextAndTeardown(ctx, s.teardown) + s.ctx = goprocessctx.OnClosingContext(s.proc) + + return s +} + +func (s *Swarm) teardown() error { + // Prevents new connections and/or listeners from being added to the swarm. + + s.listeners.Lock() + listeners := s.listeners.m + s.listeners.m = nil + s.listeners.Unlock() + + s.conns.Lock() + conns := s.conns.m + s.conns.m = nil + s.conns.Unlock() + + // Lots of goroutines but we might as well do this in parallel. We want to shut down as fast as + // possible. + + for l := range listeners { + go func(l transport.Listener) { + if err := l.Close(); err != nil { + log.Errorf("error when shutting down listener: %s", err) + } + }(l) + } + + for _, cs := range conns { + for _, c := range cs { + go func(c *Conn) { + if err := c.Close(); err != nil { + log.Errorf("error when shutting down connection: %s", err) + } + }(c) + } + } + + // Wait for everything to finish. + s.refs.Wait() + + return nil +} + +// AddAddrFilter adds a multiaddr filter to the set of filters the swarm will use to determine which +// addresses not to dial to. +func (s *Swarm) AddAddrFilter(f string) error { + m, err := mafilter.NewMask(f) + if err != nil { + return err + } + + s.Filters.AddDialFilter(m) + return nil +} + +// Process returns the Process of the swarm +func (s *Swarm) Process() goprocess.Process { + return s.proc +} + +func (s *Swarm) addConn(tc transport.CapableConn, dir network.Direction) (*Conn, error) { + // The underlying transport (or the dialer) *should* filter it's own + // connections but we should double check anyways. + raddr := tc.RemoteMultiaddr() + if s.Filters.AddrBlocked(raddr) { + tc.Close() + return nil, ErrAddrFiltered + } + + p := tc.RemotePeer() + + // Add the public key. + if pk := tc.RemotePublicKey(); pk != nil { + s.peers.AddPubKey(p, pk) + } + + // Clear any backoffs + s.backf.Clear(p) + + // Finally, add the peer. + s.conns.Lock() + // Check if we're still online + if s.conns.m == nil { + s.conns.Unlock() + tc.Close() + return nil, ErrSwarmClosed + } + + // Wrap and register the connection. + stat := network.Stat{Direction: dir} + c := &Conn{ + conn: tc, + swarm: s, + stat: stat, + } + c.streams.m = make(map[*Stream]struct{}) + s.conns.m[p] = append(s.conns.m[p], c) + + // Add two swarm refs: + // * One will be decremented after the close notifications fire in Conn.doClose + // * The other will be decremented when Conn.start exits. + s.refs.Add(2) + + // Take the notification lock before releasing the conns lock to block + // Disconnect notifications until after the Connect notifications done. + c.notifyLk.Lock() + s.conns.Unlock() + + // We have a connection now. Cancel all other in-progress dials. + // This should be fast, no reason to wait till later. + s.dsync.CancelDial(p) + + s.notifyAll(func(f network.Notifiee) { + f.Connected(s, c) + }) + c.notifyLk.Unlock() + + c.start() + + // TODO: Get rid of this. We use it for identify but that happen much + // earlier (really, inside the transport and, if not then, during the + // notifications). + if h := s.ConnHandler(); h != nil { + go h(c) + } + + return c, nil +} + +// Peerstore returns this swarms internal Peerstore. +func (s *Swarm) Peerstore() peerstore.Peerstore { + return s.peers +} + +// Context returns the context of the swarm +func (s *Swarm) Context() context.Context { + return s.ctx +} + +// Close stops the Swarm. +func (s *Swarm) Close() error { + return s.proc.Close() +} + +// TODO: We probably don't need the conn handlers. + +// SetConnHandler assigns the handler for new connections. +// You will rarely use this. See SetStreamHandler +func (s *Swarm) SetConnHandler(handler network.ConnHandler) { + s.connh.Store(handler) +} + +// ConnHandler gets the handler for new connections. +func (s *Swarm) ConnHandler() network.ConnHandler { + handler, _ := s.connh.Load().(network.ConnHandler) + return handler +} + +// SetStreamHandler assigns the handler for new streams. +func (s *Swarm) SetStreamHandler(handler network.StreamHandler) { + s.streamh.Store(handler) +} + +// StreamHandler gets the handler for new streams. +func (s *Swarm) StreamHandler() network.StreamHandler { + handler, _ := s.streamh.Load().(network.StreamHandler) + return handler +} + +// NewStream creates a new stream on any available connection to peer, dialing +// if necessary. +func (s *Swarm) NewStream(ctx context.Context, p peer.ID) (network.Stream, error) { + log.Debugf("[%s] opening stream to peer [%s]", s.local, p) + + // Algorithm: + // 1. Find the best connection, otherwise, dial. + // 2. Try opening a stream. + // 3. If the underlying connection is, in fact, closed, close the outer + // connection and try again. We do this in case we have a closed + // connection but don't notice it until we actually try to open a + // stream. + // + // Note: We only dial once. + // + // TODO: Try all connections even if we get an error opening a stream on + // a non-closed connection. + dials := 0 + for { + c := s.bestConnToPeer(p) + if c == nil { + if nodial, _ := network.GetNoDial(ctx); nodial { + return nil, network.ErrNoConn + } + + if dials >= DialAttempts { + return nil, errors.New("max dial attempts exceeded") + } + dials++ + + var err error + c, err = s.dialPeer(ctx, p) + if err != nil { + return nil, err + } + } + s, err := c.NewStream() + if err != nil { + if c.conn.IsClosed() { + continue + } + return nil, err + } + return s, nil + } +} + +// ConnsToPeer returns all the live connections to peer. +func (s *Swarm) ConnsToPeer(p peer.ID) []network.Conn { + // TODO: Consider sorting the connection list best to worst. Currently, + // it's sorted oldest to newest. + s.conns.RLock() + defer s.conns.RUnlock() + conns := s.conns.m[p] + output := make([]network.Conn, len(conns)) + for i, c := range conns { + output[i] = c + } + return output +} + +// bestConnToPeer returns the best connection to peer. +func (s *Swarm) bestConnToPeer(p peer.ID) *Conn { + // Selects the best connection we have to the peer. + // TODO: Prefer some transports over others. Currently, we just select + // the newest non-closed connection with the most streams. + s.conns.RLock() + defer s.conns.RUnlock() + + var best *Conn + bestLen := 0 + for _, c := range s.conns.m[p] { + if c.conn.IsClosed() { + // We *will* garbage collect this soon anyways. + continue + } + c.streams.Lock() + cLen := len(c.streams.m) + c.streams.Unlock() + + if cLen >= bestLen { + best = c + bestLen = cLen + } + + } + return best +} + +// Connectedness returns our "connectedness" state with the given peer. +// +// To check if we have an open connection, use `s.Connectedness(p) == +// network.Connected`. +func (s *Swarm) Connectedness(p peer.ID) network.Connectedness { + if s.bestConnToPeer(p) != nil { + return network.Connected + } + return network.NotConnected +} + +// Conns returns a slice of all connections. +func (s *Swarm) Conns() []network.Conn { + s.conns.RLock() + defer s.conns.RUnlock() + + conns := make([]network.Conn, 0, len(s.conns.m)) + for _, cs := range s.conns.m { + for _, c := range cs { + conns = append(conns, c) + } + } + return conns +} + +// ClosePeer closes all connections to the given peer. +func (s *Swarm) ClosePeer(p peer.ID) error { + conns := s.ConnsToPeer(p) + switch len(conns) { + case 0: + return nil + case 1: + return conns[0].Close() + default: + errCh := make(chan error) + for _, c := range conns { + go func(c network.Conn) { + errCh <- c.Close() + }(c) + } + + var errs []string + for _ = range conns { + err := <-errCh + if err != nil { + errs = append(errs, err.Error()) + } + } + if len(errs) > 0 { + return fmt.Errorf("when disconnecting from peer %s: %s", p, strings.Join(errs, ", ")) + } + return nil + } +} + +// Peers returns a copy of the set of peers swarm is connected to. +func (s *Swarm) Peers() []peer.ID { + s.conns.RLock() + defer s.conns.RUnlock() + peers := make([]peer.ID, 0, len(s.conns.m)) + for p := range s.conns.m { + peers = append(peers, p) + } + + return peers +} + +// LocalPeer returns the local peer swarm is associated to. +func (s *Swarm) LocalPeer() peer.ID { + return s.local +} + +// Backoff returns the DialBackoff object for this swarm. +func (s *Swarm) Backoff() *DialBackoff { + return &s.backf +} + +// notifyAll sends a signal to all Notifiees +func (s *Swarm) notifyAll(notify func(network.Notifiee)) { + var wg sync.WaitGroup + + s.notifs.RLock() + wg.Add(len(s.notifs.m)) + for f := range s.notifs.m { + go func(f network.Notifiee) { + defer wg.Done() + notify(f) + }(f) + } + + wg.Wait() + s.notifs.RUnlock() +} + +// Notify signs up Notifiee to receive signals when events happen +func (s *Swarm) Notify(f network.Notifiee) { + s.notifs.Lock() + s.notifs.m[f] = struct{}{} + s.notifs.Unlock() +} + +// StopNotify unregisters Notifiee fromr receiving signals +func (s *Swarm) StopNotify(f network.Notifiee) { + s.notifs.Lock() + delete(s.notifs.m, f) + s.notifs.Unlock() +} + +func (s *Swarm) removeConn(c *Conn) { + p := c.RemotePeer() + + s.conns.Lock() + defer s.conns.Unlock() + cs := s.conns.m[p] + for i, ci := range cs { + if ci == c { + if len(cs) == 1 { + delete(s.conns.m, p) + } else { + // NOTE: We're intentionally preserving order. + // This way, connections to a peer are always + // sorted oldest to newest. + copy(cs[i:], cs[i+1:]) + cs[len(cs)-1] = nil + s.conns.m[p] = cs[:len(cs)-1] + } + return + } + } +} + +// String returns a string representation of Network. +func (s *Swarm) String() string { + return fmt.Sprintf("", s.LocalPeer()) +} + +// Swarm is a Network. +var _ network.Network = (*Swarm)(nil) +var _ transport.TransportNetwork = (*Swarm)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_addr.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_addr.go new file mode 100644 index 00000000..c86d58bb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_addr.go @@ -0,0 +1,24 @@ +package swarm + +import ( + addrutil "github.com/libp2p/go-addr-util" + ma "github.com/multiformats/go-multiaddr" +) + +// ListenAddresses returns a list of addresses at which this swarm listens. +func (s *Swarm) ListenAddresses() []ma.Multiaddr { + s.listeners.RLock() + defer s.listeners.RUnlock() + addrs := make([]ma.Multiaddr, 0, len(s.listeners.m)) + for l := range s.listeners.m { + addrs = append(addrs, l.Multiaddr()) + } + return addrs +} + +// InterfaceListenAddresses returns a list of addresses at which this swarm +// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to +// use the known local interfaces. +func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) { + return addrutil.ResolveUnspecifiedAddresses(s.ListenAddresses(), nil) +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_conn.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_conn.go new file mode 100644 index 00000000..cdb9866a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_conn.go @@ -0,0 +1,223 @@ +package swarm + +import ( + "errors" + "fmt" + "sync" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + + ma "github.com/multiformats/go-multiaddr" +) + +// TODO: Put this elsewhere. + +// ErrConnClosed is returned when operating on a closed connection. +var ErrConnClosed = errors.New("connection closed") + +// Conn is the connection type used by swarm. In general, you won't use this +// type directly. +type Conn struct { + conn transport.CapableConn + swarm *Swarm + + closeOnce sync.Once + err error + + notifyLk sync.Mutex + + streams struct { + sync.Mutex + m map[*Stream]struct{} + } + + stat network.Stat +} + +// Close closes this connection. +// +// Note: This method won't wait for the close notifications to finish as that +// would create a deadlock when called from an open notification (because all +// open notifications must finish before we can fire off the close +// notifications). +func (c *Conn) Close() error { + c.closeOnce.Do(c.doClose) + return c.err +} + +func (c *Conn) doClose() { + c.swarm.removeConn(c) + + // Prevent new streams from opening. + c.streams.Lock() + streams := c.streams.m + c.streams.m = nil + c.streams.Unlock() + + c.err = c.conn.Close() + + // This is just for cleaning up state. The connection has already been closed. + // We *could* optimize this but it really isn't worth it. + for s := range streams { + s.Reset() + } + + // do this in a goroutine to avoid deadlocking if we call close in an open notification. + go func() { + // prevents us from issuing close notifications before finishing the open notifications + c.notifyLk.Lock() + defer c.notifyLk.Unlock() + + c.swarm.notifyAll(func(f network.Notifiee) { + f.Disconnected(c.swarm, c) + }) + c.swarm.refs.Done() // taken in Swarm.addConn + }() +} + +func (c *Conn) removeStream(s *Stream) { + c.streams.Lock() + delete(c.streams.m, s) + c.streams.Unlock() +} + +// listens for new streams. +// +// The caller must take a swarm ref before calling. This function decrements the +// swarm ref count. +func (c *Conn) start() { + go func() { + defer c.swarm.refs.Done() + defer c.Close() + + for { + ts, err := c.conn.AcceptStream() + if err != nil { + return + } + c.swarm.refs.Add(1) + go func() { + s, err := c.addStream(ts, network.DirInbound) + + // Don't defer this. We don't want to block + // swarm shutdown on the connection handler. + c.swarm.refs.Done() + + // We only get an error here when the swarm is closed or closing. + if err != nil { + return + } + + if h := c.swarm.StreamHandler(); h != nil { + h(s) + } + }() + } + }() +} + +func (c *Conn) String() string { + return fmt.Sprintf( + " %s (%s)>", + c.conn.Transport(), + c.conn.LocalMultiaddr(), + c.conn.LocalPeer().Pretty(), + c.conn.RemoteMultiaddr(), + c.conn.RemotePeer().Pretty(), + ) +} + +// LocalMultiaddr is the Multiaddr on this side +func (c *Conn) LocalMultiaddr() ma.Multiaddr { + return c.conn.LocalMultiaddr() +} + +// LocalPeer is the Peer on our side of the connection +func (c *Conn) LocalPeer() peer.ID { + return c.conn.LocalPeer() +} + +// RemoteMultiaddr is the Multiaddr on the remote side +func (c *Conn) RemoteMultiaddr() ma.Multiaddr { + return c.conn.RemoteMultiaddr() +} + +// RemotePeer is the Peer on the remote side +func (c *Conn) RemotePeer() peer.ID { + return c.conn.RemotePeer() +} + +// LocalPrivateKey is the public key of the peer on this side +func (c *Conn) LocalPrivateKey() ic.PrivKey { + return c.conn.LocalPrivateKey() +} + +// RemotePublicKey is the public key of the peer on the remote side +func (c *Conn) RemotePublicKey() ic.PubKey { + return c.conn.RemotePublicKey() +} + +// Stat returns metadata pertaining to this connection +func (c *Conn) Stat() network.Stat { + return c.stat +} + +// NewStream returns a new Stream from this connection +func (c *Conn) NewStream() (network.Stream, error) { + ts, err := c.conn.OpenStream() + if err != nil { + return nil, err + } + return c.addStream(ts, network.DirOutbound) +} + +func (c *Conn) addStream(ts mux.MuxedStream, dir network.Direction) (*Stream, error) { + c.streams.Lock() + // Are we still online? + if c.streams.m == nil { + c.streams.Unlock() + ts.Reset() + return nil, ErrConnClosed + } + + // Wrap and register the stream. + stat := network.Stat{Direction: dir} + s := &Stream{ + stream: ts, + conn: c, + stat: stat, + } + c.streams.m[s] = struct{}{} + + // Released once the stream disconnect notifications have finished + // firing (in Swarm.remove). + c.swarm.refs.Add(1) + + // Take the notification lock before releasing the streams lock to block + // StreamClose notifications until after the StreamOpen notifications + // done. + s.notifyLk.Lock() + c.streams.Unlock() + + c.swarm.notifyAll(func(f network.Notifiee) { + f.OpenedStream(c.swarm, s) + }) + s.notifyLk.Unlock() + + return s, nil +} + +// GetStreams returns the streams associated with this connection. +func (c *Conn) GetStreams() []network.Stream { + c.streams.Lock() + defer c.streams.Unlock() + streams := make([]network.Stream, 0, len(c.streams.m)) + for s := range c.streams.m { + streams = append(streams, s) + } + return streams +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_dial.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_dial.go new file mode 100644 index 00000000..40faad78 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_dial.go @@ -0,0 +1,477 @@ +package swarm + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + lgbl "github.com/libp2p/go-libp2p-loggables" + + logging "github.com/ipfs/go-log" + addrutil "github.com/libp2p/go-addr-util" + ma "github.com/multiformats/go-multiaddr" +) + +// Diagram of dial sync: +// +// many callers of Dial() synched w. dials many addrs results to callers +// ----------------------\ dialsync use earliest /-------------- +// -----------------------\ |----------\ /---------------- +// ------------------------>------------<------- >---------<----------------- +// -----------------------| \----x \---------------- +// ----------------------| \-----x \--------------- +// any may fail if no addr at end +// retry dialAttempt x + +var ( + // ErrDialBackoff is returned by the backoff code when a given peer has + // been dialed too frequently + ErrDialBackoff = errors.New("dial backoff") + + // ErrDialToSelf is returned if we attempt to dial our own peer + ErrDialToSelf = errors.New("dial to self attempted") + + // ErrNoTransport is returned when we don't know a transport for the + // given multiaddr. + ErrNoTransport = errors.New("no transport for protocol") + + // ErrAllDialsFailed is returned when connecting to a peer has ultimately failed + ErrAllDialsFailed = errors.New("all dials failed") + + // ErrNoAddresses is returned when we fail to find any addresses for a + // peer we're trying to dial. + ErrNoAddresses = errors.New("no addresses") + + // ErrNoAddresses is returned when we find addresses for a peer but + // can't use any of them. + ErrNoGoodAddresses = errors.New("no good addresses") +) + +// DialAttempts governs how many times a goroutine will try to dial a given peer. +// Note: this is down to one, as we have _too many dials_ atm. To add back in, +// add loop back in Dial(.) +const DialAttempts = 1 + +// ConcurrentFdDials is the number of concurrent outbound dials over transports +// that consume file descriptors +const ConcurrentFdDials = 160 + +// DefaultPerPeerRateLimit is the number of concurrent outbound dials to make +// per peer +const DefaultPerPeerRateLimit = 8 + +// dialbackoff is a struct used to avoid over-dialing the same, dead peers. +// Whenever we totally time out on a peer (all three attempts), we add them +// to dialbackoff. Then, whenevers goroutines would _wait_ (dialsync), they +// check dialbackoff. If it's there, they don't wait and exit promptly with +// an error. (the single goroutine that is actually dialing continues to +// dial). If a dial is successful, the peer is removed from backoff. +// Example: +// +// for { +// if ok, wait := dialsync.Lock(p); !ok { +// if backoff.Backoff(p) { +// return errDialFailed +// } +// <-wait +// continue +// } +// defer dialsync.Unlock(p) +// c, err := actuallyDial(p) +// if err != nil { +// dialbackoff.AddBackoff(p) +// continue +// } +// dialbackoff.Clear(p) +// } +// + +// DialBackoff is a type for tracking peer dial backoffs. +// +// * It's safe to use its zero value. +// * It's thread-safe. +// * It's *not* safe to move this type after using. +type DialBackoff struct { + entries map[peer.ID]*backoffPeer + lock sync.RWMutex +} + +type backoffPeer struct { + tries int + until time.Time +} + +func (db *DialBackoff) init() { + if db.entries == nil { + db.entries = make(map[peer.ID]*backoffPeer) + } +} + +// Backoff returns whether the client should backoff from dialing +// peer p +func (db *DialBackoff) Backoff(p peer.ID) (backoff bool) { + db.lock.Lock() + defer db.lock.Unlock() + db.init() + bp, found := db.entries[p] + if found && time.Now().Before(bp.until) { + return true + } + + return false +} + +// BackoffBase is the base amount of time to backoff (default: 5s). +var BackoffBase = time.Second * 5 + +// BackoffCoef is the backoff coefficient (default: 1s). +var BackoffCoef = time.Second + +// BackoffMax is the maximum backoff time (default: 5m). +var BackoffMax = time.Minute * 5 + +// AddBackoff lets other nodes know that we've entered backoff with +// peer p, so dialers should not wait unnecessarily. We still will +// attempt to dial with one goroutine, in case we get through. +// +// Backoff is not exponential, it's quadratic and computed according to the +// following formula: +// +// BackoffBase + BakoffCoef * PriorBackoffs^2 +// +// Where PriorBackoffs is the number of previous backoffs. +func (db *DialBackoff) AddBackoff(p peer.ID) { + db.lock.Lock() + defer db.lock.Unlock() + db.init() + bp, ok := db.entries[p] + if !ok { + db.entries[p] = &backoffPeer{ + tries: 1, + until: time.Now().Add(BackoffBase), + } + return + } + + backoffTime := BackoffBase + BackoffCoef*time.Duration(bp.tries*bp.tries) + if backoffTime > BackoffMax { + backoffTime = BackoffMax + } + bp.until = time.Now().Add(backoffTime) + bp.tries++ +} + +// Clear removes a backoff record. Clients should call this after a +// successful Dial. +func (db *DialBackoff) Clear(p peer.ID) { + db.lock.Lock() + defer db.lock.Unlock() + db.init() + delete(db.entries, p) +} + +// DialPeer connects to a peer. +// +// The idea is that the client of Swarm does not need to know what network +// the connection will happen over. Swarm can use whichever it choses. +// This allows us to use various transport protocols, do NAT traversal/relay, +// etc. to achieve connection. +func (s *Swarm) DialPeer(ctx context.Context, p peer.ID) (network.Conn, error) { + return s.dialPeer(ctx, p) +} + +// internal dial method that returns an unwrapped conn +// +// It is gated by the swarm's dial synchronization systems: dialsync and +// dialbackoff. +func (s *Swarm) dialPeer(ctx context.Context, p peer.ID) (*Conn, error) { + log.Debugf("[%s] swarm dialing peer [%s]", s.local, p) + var logdial = lgbl.Dial("swarm", s.LocalPeer(), p, nil, nil) + err := p.Validate() + if err != nil { + return nil, err + } + + if p == s.local { + log.Event(ctx, "swarmDialSelf", logdial) + return nil, ErrDialToSelf + } + + defer log.EventBegin(ctx, "swarmDialAttemptSync", p).Done() + + // check if we already have an open connection first + conn := s.bestConnToPeer(p) + if conn != nil { + return conn, nil + } + + // if this peer has been backed off, lets get out of here + if s.backf.Backoff(p) { + log.Event(ctx, "swarmDialBackoff", p) + return nil, ErrDialBackoff + } + + // apply the DialPeer timeout + ctx, cancel := context.WithTimeout(ctx, network.GetDialPeerTimeout(ctx)) + defer cancel() + + conn, err = s.dsync.DialLock(ctx, p) + if err != nil { + return nil, err + } + + log.Debugf("network for %s finished dialing %s", s.local, p) + return conn, err +} + +// doDial is an ugly shim method to retain all the logging and backoff logic +// of the old dialsync code +func (s *Swarm) doDial(ctx context.Context, p peer.ID) (*Conn, error) { + // Short circuit. + // By the time we take the dial lock, we may already *have* a connection + // to the peer. + c := s.bestConnToPeer(p) + if c != nil { + return c, nil + } + + logdial := lgbl.Dial("swarm", s.LocalPeer(), p, nil, nil) + + // ok, we have been charged to dial! let's do it. + // if it succeeds, dial will add the conn to the swarm itself. + defer log.EventBegin(ctx, "swarmDialAttemptStart", logdial).Done() + + conn, err := s.dial(ctx, p) + if err != nil { + conn = s.bestConnToPeer(p) + if conn != nil { + // Hm? What error? + // Could have canceled the dial because we received a + // connection or some other random reason. + // Just ignore the error and return the connection. + log.Debugf("ignoring dial error because we have a connection: %s", err) + return conn, nil + } + if err != context.Canceled { + log.Event(ctx, "swarmDialBackoffAdd", logdial) + s.backf.AddBackoff(p) // let others know to backoff + } + + // ok, we failed. + return nil, err + } + return conn, nil +} + +func (s *Swarm) canDial(addr ma.Multiaddr) bool { + t := s.TransportForDialing(addr) + return t != nil && t.CanDial(addr) +} + +// dial is the actual swarm's dial logic, gated by Dial. +func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) { + var logdial = lgbl.Dial("swarm", s.LocalPeer(), p, nil, nil) + if p == s.local { + log.Event(ctx, "swarmDialDoDialSelf", logdial) + return nil, ErrDialToSelf + } + defer log.EventBegin(ctx, "swarmDialDo", logdial).Done() + logdial["dial"] = "failure" // start off with failure. set to "success" at the end. + + sk := s.peers.PrivKey(s.local) + logdial["encrypted"] = sk != nil // log whether this will be an encrypted dial or not. + if sk == nil { + // fine for sk to be nil, just log. + log.Debug("Dial not given PrivateKey, so WILL NOT SECURE conn.") + } + + ////// + /* + This slice-to-chan code is temporary, the peerstore can currently provide + a channel as an interface for receiving addresses, but more thought + needs to be put into the execution. For now, this allows us to use + the improved rate limiter, while maintaining the outward behaviour + that we previously had (halting a dial when we run out of addrs) + */ + peerAddrs := s.peers.Addrs(p) + if len(peerAddrs) == 0 { + return nil, &DialError{Peer: p, Cause: ErrNoAddresses} + } + goodAddrs := s.filterKnownUndialables(peerAddrs) + if len(goodAddrs) == 0 { + return nil, &DialError{Peer: p, Cause: ErrNoGoodAddresses} + } + goodAddrsChan := make(chan ma.Multiaddr, len(goodAddrs)) + for _, a := range goodAddrs { + goodAddrsChan <- a + } + close(goodAddrsChan) + ///////// + + // try to get a connection to any addr + connC, dialErr := s.dialAddrs(ctx, p, goodAddrsChan) + if dialErr != nil { + logdial["error"] = dialErr.Cause.Error() + if dialErr.Cause == context.Canceled { + // always prefer the "context canceled" error. + // we rely on behing able to check `err == context.Canceled` + // + // Removing this will BREAK backoff (causing us to + // backoff when canceling dials). + return nil, context.Canceled + } + return nil, dialErr + } + logdial["conn"] = logging.Metadata{ + "localAddr": connC.LocalMultiaddr(), + "remoteAddr": connC.RemoteMultiaddr(), + } + swarmC, err := s.addConn(connC, network.DirOutbound) + if err != nil { + logdial["error"] = err.Error() + connC.Close() // close the connection. didn't work out :( + return nil, &DialError{Peer: p, Cause: err} + } + + logdial["dial"] = "success" + return swarmC, nil +} + +// filterKnownUndialables takes a list of multiaddrs, and removes those +// that we definitely don't want to dial: addresses configured to be blocked, +// IPv6 link-local addresses, addresses without a dial-capable transport, +// and addresses that we know to be our own. +// This is an optimization to avoid wasting time on dials that we know are going to fail. +func (s *Swarm) filterKnownUndialables(addrs []ma.Multiaddr) []ma.Multiaddr { + lisAddrs, _ := s.InterfaceListenAddresses() + var ourAddrs []ma.Multiaddr + for _, addr := range lisAddrs { + protos := addr.Protocols() + // we're only sure about filtering out /ip4 and /ip6 addresses, so far + if len(protos) == 2 && (protos[0].Code == ma.P_IP4 || protos[0].Code == ma.P_IP6) { + ourAddrs = append(ourAddrs, addr) + } + } + + return addrutil.FilterAddrs(addrs, + addrutil.SubtractFilter(ourAddrs...), + s.canDial, + // TODO: Consider allowing link-local addresses + addrutil.AddrOverNonLocalIP, + addrutil.FilterNeg(s.Filters.AddrBlocked), + ) +} + +func (s *Swarm) dialAddrs(ctx context.Context, p peer.ID, remoteAddrs <-chan ma.Multiaddr) (transport.CapableConn, *DialError) { + log.Debugf("%s swarm dialing %s", s.local, p) + + ctx, cancel := context.WithCancel(ctx) + defer cancel() // cancel work when we exit func + + // use a single response type instead of errs and conns, reduces complexity *a ton* + respch := make(chan dialResult) + err := new(DialError) + + defer s.limiter.clearAllPeerDials(p) + + var active int +dialLoop: + for remoteAddrs != nil || active > 0 { + // Check for context cancellations and/or responses first. + select { + case <-ctx.Done(): + break dialLoop + case resp := <-respch: + active-- + if resp.Err != nil { + // Errors are normal, lots of dials will fail + log.Infof("got error on dial: %s", resp.Err) + err.recordErr(resp.Addr, resp.Err) + } else if resp.Conn != nil { + return resp.Conn, nil + } + + // We got a result, try again from the top. + continue + default: + } + + // Now, attempt to dial. + select { + case addr, ok := <-remoteAddrs: + if !ok { + remoteAddrs = nil + continue + } + + s.limitedDial(ctx, p, addr, respch) + active++ + case <-ctx.Done(): + break dialLoop + case resp := <-respch: + active-- + if resp.Err != nil { + // Errors are normal, lots of dials will fail + log.Infof("got error on dial: %s", resp.Err) + err.recordErr(resp.Addr, resp.Err) + } else if resp.Conn != nil { + return resp.Conn, nil + } + } + } + + if ctxErr := ctx.Err(); ctxErr != nil { + err.Cause = ctxErr + } else if len(err.DialErrors) == 0 { + err.Cause = network.ErrNoRemoteAddrs + } else { + err.Cause = ErrAllDialsFailed + } + return nil, err +} + +// limitedDial will start a dial to the given peer when +// it is able, respecting the various different types of rate +// limiting that occur without using extra goroutines per addr +func (s *Swarm) limitedDial(ctx context.Context, p peer.ID, a ma.Multiaddr, resp chan dialResult) { + s.limiter.AddDialJob(&dialJob{ + addr: a, + peer: p, + resp: resp, + ctx: ctx, + }) +} + +func (s *Swarm) dialAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr) (transport.CapableConn, error) { + // Just to double check. Costs nothing. + if s.local == p { + return nil, ErrDialToSelf + } + log.Debugf("%s swarm dialing %s %s", s.local, p, addr) + + tpt := s.TransportForDialing(addr) + if tpt == nil { + return nil, ErrNoTransport + } + + connC, err := tpt.Dial(ctx, addr, p) + if err != nil { + return nil, err + } + + // Trust the transport? Yeah... right. + if connC.RemotePeer() != p { + connC.Close() + err = fmt.Errorf("BUG in transport %T: tried to dial %s, dialed %s", p, connC.RemotePeer(), tpt) + log.Error(err) + return nil, err + } + + // success! we got one! + return connC, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_listen.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_listen.go new file mode 100644 index 00000000..85060c4e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_listen.go @@ -0,0 +1,97 @@ +package swarm + +import ( + "fmt" + + "github.com/libp2p/go-libp2p-core/network" + + ma "github.com/multiformats/go-multiaddr" +) + +// Listen sets up listeners for all of the given addresses. +// It returns as long as we successfully listen on at least *one* address. +func (s *Swarm) Listen(addrs ...ma.Multiaddr) error { + errs := make([]error, len(addrs)) + var succeeded int + for i, a := range addrs { + if err := s.AddListenAddr(a); err != nil { + errs[i] = err + } else { + succeeded++ + } + } + + for i, e := range errs { + if e != nil { + log.Warningf("listen on %s failed: %s", addrs[i], errs[i]) + } + } + + if succeeded == 0 && len(addrs) > 0 { + return fmt.Errorf("failed to listen on any addresses: %s", errs) + } + + return nil +} + +// AddListenAddr tells the swarm to listen on a single address. Unlike Listen, +// this method does not attempt to filter out bad addresses. +func (s *Swarm) AddListenAddr(a ma.Multiaddr) error { + tpt := s.TransportForListening(a) + if tpt == nil { + return ErrNoTransport + } + + list, err := tpt.Listen(a) + if err != nil { + return err + } + + s.listeners.Lock() + if s.listeners.m == nil { + s.listeners.Unlock() + list.Close() + return ErrSwarmClosed + } + s.refs.Add(1) + s.listeners.m[list] = struct{}{} + s.listeners.Unlock() + + maddr := list.Multiaddr() + + // signal to our notifiees on successful conn. + s.notifyAll(func(n network.Notifiee) { + n.Listen(s, maddr) + }) + + go func() { + defer func() { + list.Close() + s.listeners.Lock() + delete(s.listeners.m, list) + s.listeners.Unlock() + s.refs.Done() + }() + for { + c, err := list.Accept() + if err != nil { + if s.ctx.Err() == nil { + log.Errorf("swarm listener accept error: %s", err) + } + return + } + log.Debugf("swarm listener accepted connection: %s", c) + s.refs.Add(1) + go func() { + defer s.refs.Done() + _, err := s.addConn(c, network.DirInbound) + if err != nil { + // Probably just means that the swarm has been closed. + log.Warningf("add conn failed: ", err) + return + } + }() + } + }() + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_stream.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_stream.go new file mode 100644 index 00000000..9dded2a9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_stream.go @@ -0,0 +1,177 @@ +package swarm + +import ( + "fmt" + "io" + "sync" + "sync/atomic" + "time" + + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/protocol" +) + +type streamState int + +const ( + streamOpen streamState = iota + streamCloseRead + streamCloseWrite + streamCloseBoth + streamReset +) + +// Validate Stream conforms to the go-libp2p-net Stream interface +var _ network.Stream = &Stream{} + +// Stream is the stream type used by swarm. In general, you won't use this type +// directly. +type Stream struct { + stream mux.MuxedStream + conn *Conn + + state struct { + sync.Mutex + v streamState + } + + notifyLk sync.Mutex + + protocol atomic.Value + + stat network.Stat +} + +func (s *Stream) String() string { + return fmt.Sprintf( + " %s (%s)>", + s.conn.conn.Transport(), + s.conn.LocalMultiaddr(), + s.conn.LocalPeer(), + s.conn.RemoteMultiaddr(), + s.conn.RemotePeer(), + ) +} + +// Conn returns the Conn associated with this stream, as an network.Conn +func (s *Stream) Conn() network.Conn { + return s.conn +} + +// Read reads bytes from a stream. +func (s *Stream) Read(p []byte) (int, error) { + n, err := s.stream.Read(p) + // TODO: push this down to a lower level for better accuracy. + if s.conn.swarm.bwc != nil { + s.conn.swarm.bwc.LogRecvMessage(int64(n)) + s.conn.swarm.bwc.LogRecvMessageStream(int64(n), s.Protocol(), s.Conn().RemotePeer()) + } + // If we observe an EOF, this stream is now closed for reading. + // If we're already closed for writing, this stream is now fully closed. + if err == io.EOF { + s.state.Lock() + switch s.state.v { + case streamCloseWrite: + s.state.v = streamCloseBoth + s.remove() + case streamOpen: + s.state.v = streamCloseRead + } + s.state.Unlock() + } + return n, err +} + +// Write writes bytes to a stream, flushing for each call. +func (s *Stream) Write(p []byte) (int, error) { + n, err := s.stream.Write(p) + // TODO: push this down to a lower level for better accuracy. + if s.conn.swarm.bwc != nil { + s.conn.swarm.bwc.LogSentMessage(int64(n)) + s.conn.swarm.bwc.LogSentMessageStream(int64(n), s.Protocol(), s.Conn().RemotePeer()) + } + return n, err +} + +// Close closes the stream, indicating this side is finished +// with the stream. +func (s *Stream) Close() error { + err := s.stream.Close() + + s.state.Lock() + switch s.state.v { + case streamCloseRead: + s.state.v = streamCloseBoth + s.remove() + case streamOpen: + s.state.v = streamCloseWrite + } + s.state.Unlock() + return err +} + +// Reset resets the stream, closing both ends. +func (s *Stream) Reset() error { + err := s.stream.Reset() + s.state.Lock() + switch s.state.v { + case streamOpen, streamCloseRead, streamCloseWrite: + s.state.v = streamReset + s.remove() + } + s.state.Unlock() + return err +} + +func (s *Stream) remove() { + s.conn.removeStream(s) + + // We *must* do this in a goroutine. This can be called during a + // an open notification and will block until that notification is done. + go func() { + s.notifyLk.Lock() + defer s.notifyLk.Unlock() + + s.conn.swarm.notifyAll(func(f network.Notifiee) { + f.ClosedStream(s.conn.swarm, s) + }) + s.conn.swarm.refs.Done() + }() +} + +// Protocol returns the protocol negotiated on this stream (if set). +func (s *Stream) Protocol() protocol.ID { + // Ignore type error. It means that the protocol is unset. + p, _ := s.protocol.Load().(protocol.ID) + return p +} + +// SetProtocol sets the protocol for this stream. +// +// This doesn't actually *do* anything other than record the fact that we're +// speaking the given protocol over this stream. It's still up to the user to +// negotiate the protocol. This is usually done by the Host. +func (s *Stream) SetProtocol(p protocol.ID) { + s.protocol.Store(p) +} + +// SetDeadline sets the read and write deadlines for this stream. +func (s *Stream) SetDeadline(t time.Time) error { + return s.stream.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline for this stream. +func (s *Stream) SetReadDeadline(t time.Time) error { + return s.stream.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline for this stream. +func (s *Stream) SetWriteDeadline(t time.Time) error { + return s.stream.SetWriteDeadline(t) +} + +// Stat returns metadata information for this stream. +func (s *Stream) Stat() network.Stat { + return s.stat +} diff --git a/vendor/github.com/libp2p/go-libp2p-swarm/swarm_transport.go b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_transport.go new file mode 100644 index 00000000..307bfe64 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-swarm/swarm_transport.go @@ -0,0 +1,102 @@ +package swarm + +import ( + "fmt" + "strings" + + "github.com/libp2p/go-libp2p-core/transport" + + ma "github.com/multiformats/go-multiaddr" +) + +// TransportForDialing retrieves the appropriate transport for dialing the given +// multiaddr. +func (s *Swarm) TransportForDialing(a ma.Multiaddr) transport.Transport { + protocols := a.Protocols() + if len(protocols) == 0 { + return nil + } + + s.transports.RLock() + defer s.transports.RUnlock() + if len(s.transports.m) == 0 { + log.Error("you have no transports configured") + return nil + } + + for _, p := range protocols { + transport, ok := s.transports.m[p.Code] + if !ok { + continue + } + if transport.Proxy() { + return transport + } + } + + return s.transports.m[protocols[len(protocols)-1].Code] +} + +// TransportForListening retrieves the appropriate transport for listening on +// the given multiaddr. +func (s *Swarm) TransportForListening(a ma.Multiaddr) transport.Transport { + protocols := a.Protocols() + if len(protocols) == 0 { + return nil + } + + s.transports.RLock() + defer s.transports.RUnlock() + if len(s.transports.m) == 0 { + log.Error("you have no transports configured") + return nil + } + + selected := s.transports.m[protocols[len(protocols)-1].Code] + for _, p := range protocols { + transport, ok := s.transports.m[p.Code] + if !ok { + continue + } + if transport.Proxy() { + selected = transport + } + } + return selected +} + +// AddTransport adds a transport to this swarm. +// +// Satisfies the Network interface from go-libp2p-transport. +func (s *Swarm) AddTransport(t transport.Transport) error { + protocols := t.Protocols() + + if len(protocols) == 0 { + return fmt.Errorf("useless transport handles no protocols: %T", t) + } + + s.transports.Lock() + defer s.transports.Unlock() + var registered []string + for _, p := range protocols { + if _, ok := s.transports.m[p]; ok { + proto := ma.ProtocolWithCode(p) + name := proto.Name + if name == "" { + name = fmt.Sprintf("unknown (%d)", p) + } + registered = append(registered, name) + } + } + if len(registered) > 0 { + return fmt.Errorf( + "transports already registered for protocol(s): %s", + strings.Join(registered, ", "), + ) + } + + for _, p := range protocols { + s.transports.m[p] = t + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-tls/.travis.yml b/vendor/github.com/libp2p/go-libp2p-tls/.travis.yml new file mode 100644 index 00000000..4f8a4d25 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/.travis.yml @@ -0,0 +1,36 @@ +language: go + +go: + - "1.12.x" + +# first part of the GOARCH workaround +# setting the GOARCH directly doesn't work, since the value will be overwritten later +# so set it to a temporary environment variable first +env: + - TRAVIS_GOARCH=amd64 + - TRAVIS_GOARCH=386 + +# second part of the GOARCH workaround +# now actually set the GOARCH env variable to the value of the temporary variable set earlier +before_install: + - | + export GO111MODULE=on; + go get golang.org/x/tools/cmd/cover; + go get github.com/onsi/ginkgo/ginkgo; + go get github.com/onsi/gomega; + - export GOARCH=$TRAVIS_GOARCH + - go env + +script: + # some tests are randomized. Run them a few times. + - for i in `seq 1 10`; do + ginkgo -r -v --cover --randomizeAllSpecs --randomizeSuites --trace --progress; + done + +after_success: + - cat go-libp2p-tls.coverprofile > coverage.txt + - cat */*.coverprofile >> coverage.txt + - bash <(curl -s https://codecov.io/bash) -f coverage.txt + +cache: + directories: diff --git a/vendor/github.com/libp2p/go-libp2p-tls/LICENSE.md b/vendor/github.com/libp2p/go-libp2p-tls/LICENSE.md new file mode 100644 index 00000000..a94e82cc --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2018 Marten Seemann + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-tls/README.md b/vendor/github.com/libp2p/go-libp2p-tls/README.md new file mode 100644 index 00000000..64390a04 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/README.md @@ -0,0 +1,44 @@ +# go-libp2p-tls + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-tls?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-tls) +[![Linux Build Status](https://img.shields.io/travis/libp2p/go-libp2p-tls/master.svg?style=flat-square&label=linux+build)](https://travis-ci.org/libp2p/go-libp2p-tls) +[![Code Coverage](https://img.shields.io/codecov/c/github/libp2p/go-libp2p-tls/master.svg?style=flat-square)](https://codecov.io/gh/libp2p/go-libp2p-tls/) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> go-libp2p's TLS encrypted transport + +Package `go-libp2p-tls` is a libp2p [conn security transport](https://github.com/libp2p/go-conn-security). It uses TLS to setup the communication channel. + +## Install + +`go-libp2p-tls` is a standard Go module which can be installed with: + +```sh +go get github.com/libp2p/go-libp2p-tls +``` + +This repo is [gomod](https://github.com/golang/go/wiki/Modules)-compatible, and users of +go 1.11 and later with modules enabled will automatically pull the latest tagged release +by referencing this package. Upgrades to future releases can be managed using `go get`, +or by editing your `go.mod` file as [described by the gomod documentation](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies). + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-tls/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 0.1.0: QmR4qpcxA1UoHg7SZ89hJHYCpfrxToPjH9xSCug1cQeH1M diff --git a/vendor/github.com/libp2p/go-libp2p-tls/codecov.yml b/vendor/github.com/libp2p/go-libp2p-tls/codecov.yml new file mode 100644 index 00000000..00064af3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/codecov.yml @@ -0,0 +1,7 @@ +coverage: + round: nearest + status: + project: + default: + threshold: 1 + patch: false diff --git a/vendor/github.com/libp2p/go-libp2p-tls/conn.go b/vendor/github.com/libp2p/go-libp2p-tls/conn.go new file mode 100644 index 00000000..cf32fa45 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/conn.go @@ -0,0 +1,37 @@ +package libp2ptls + +import ( + "crypto/tls" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" +) + +type conn struct { + *tls.Conn + + localPeer peer.ID + privKey ci.PrivKey + + remotePeer peer.ID + remotePubKey ci.PubKey +} + +var _ sec.SecureConn = &conn{} + +func (c *conn) LocalPeer() peer.ID { + return c.localPeer +} + +func (c *conn) LocalPrivateKey() ci.PrivKey { + return c.privKey +} + +func (c *conn) RemotePeer() peer.ID { + return c.remotePeer +} + +func (c *conn) RemotePublicKey() ci.PubKey { + return c.remotePubKey +} diff --git a/vendor/github.com/libp2p/go-libp2p-tls/crypto.go b/vendor/github.com/libp2p/go-libp2p-tls/crypto.go new file mode 100644 index 00000000..917c65a6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/crypto.go @@ -0,0 +1,223 @@ +package libp2ptls + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "errors" + "fmt" + "math/big" + "time" + + crypto "github.com/libp2p/go-libp2p-crypto" + "golang.org/x/sys/cpu" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +const certValidityPeriod = 100 * 365 * 24 * time.Hour // ~100 years +const certificatePrefix = "libp2p-tls-handshake:" + +var extensionID = getPrefixedExtensionID([]int{1, 1}) + +type signedKey struct { + PubKey []byte + Signature []byte +} + +// Identity is used to secure connections +type Identity struct { + config tls.Config +} + +// NewIdentity creates a new identity +func NewIdentity(privKey ic.PrivKey) (*Identity, error) { + cert, err := keyToCertificate(privKey) + if err != nil { + return nil, err + } + return &Identity{ + config: tls.Config{ + MinVersion: tls.VersionTLS13, + PreferServerCipherSuites: preferServerCipherSuites(), + InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves. + ClientAuth: tls.RequireAnyClientCert, + Certificates: []tls.Certificate{*cert}, + VerifyPeerCertificate: func(_ [][]byte, _ [][]*x509.Certificate) error { + panic("tls config not specialized for peer") + }, + SessionTicketsDisabled: true, + }, + }, nil +} + +// ConfigForAny is a short-hand for ConfigForPeer(""). +func (i *Identity) ConfigForAny() (*tls.Config, <-chan ic.PubKey) { + return i.ConfigForPeer("") +} + +// ConfigForPeer creates a new single-use tls.Config that verifies the peer's +// certificate chain and returns the peer's public key via the channel. If the +// peer ID is empty, the returned config will accept any peer. +// +// It should be used to create a new tls.Config before securing either an +// incoming or outgoing connection. +func (i *Identity) ConfigForPeer( + remote peer.ID, +) (*tls.Config, <-chan ic.PubKey) { + keyCh := make(chan ic.PubKey, 1) + // We need to check the peer ID in the VerifyPeerCertificate callback. + // The tls.Config it is also used for listening, and we might also have concurrent dials. + // Clone it so we can check for the specific peer ID we're dialing here. + conf := i.config.Clone() + // We're using InsecureSkipVerify, so the verifiedChains parameter will always be empty. + // We need to parse the certificates ourselves from the raw certs. + conf.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + defer close(keyCh) + + chain := make([]*x509.Certificate, len(rawCerts)) + for i := 0; i < len(rawCerts); i++ { + cert, err := x509.ParseCertificate(rawCerts[i]) + if err != nil { + return err + } + chain[i] = cert + } + + pubKey, err := getRemotePubKey(chain) + if err != nil { + return err + } + if remote != "" && !remote.MatchesPublicKey(pubKey) { + return errors.New("peer IDs don't match") + } + keyCh <- pubKey + return nil + } + return conf, keyCh +} + +// getRemotePubKey derives the remote's public key from the certificate chain. +func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) { + if len(chain) != 1 { + return nil, errors.New("expected one certificates in the chain") + } + cert := chain[0] + pool := x509.NewCertPool() + pool.AddCert(cert) + if _, err := cert.Verify(x509.VerifyOptions{Roots: pool}); err != nil { + // If we return an x509 error here, it will be sent on the wire. + // Wrap the error to avoid that. + return nil, fmt.Errorf("certificate verification failed: %s", err) + } + + var found bool + var keyExt pkix.Extension + // find the libp2p key extension, skipping all unknown extensions + for _, ext := range cert.Extensions { + if extensionIDEqual(ext.Id, extensionID) { + keyExt = ext + found = true + break + } + } + if !found { + return nil, errors.New("expected certificate to contain the key extension") + } + var sk signedKey + if _, err := asn1.Unmarshal(keyExt.Value, &sk); err != nil { + return nil, fmt.Errorf("unmarshalling signed certificate failed: %s", err) + } + pubKey, err := ic.UnmarshalPublicKey(sk.PubKey) + if err != nil { + return nil, fmt.Errorf("unmarshalling public key failed: %s", err) + } + certKeyPub, err := x509.MarshalPKIXPublicKey(cert.PublicKey) + if err != nil { + return nil, err + } + valid, err := pubKey.Verify(append([]byte(certificatePrefix), certKeyPub...), sk.Signature) + if err != nil { + return nil, fmt.Errorf("signature verification failed: %s", err) + } + if !valid { + return nil, errors.New("signature invalid") + } + return pubKey, nil +} + +func keyToCertificate(sk ic.PrivKey) (*tls.Certificate, error) { + certKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + + keyBytes, err := crypto.MarshalPublicKey(sk.GetPublic()) + if err != nil { + return nil, err + } + certKeyPub, err := x509.MarshalPKIXPublicKey(certKey.Public()) + if err != nil { + return nil, err + } + signature, err := sk.Sign(append([]byte(certificatePrefix), certKeyPub...)) + if err != nil { + return nil, err + } + value, err := asn1.Marshal(signedKey{ + PubKey: keyBytes, + Signature: signature, + }) + if err != nil { + return nil, err + } + + sn, err := rand.Int(rand.Reader, big.NewInt(1<<62)) + if err != nil { + return nil, err + } + tmpl := &x509.Certificate{ + SerialNumber: sn, + NotBefore: time.Time{}, + NotAfter: time.Now().Add(certValidityPeriod), + // after calling CreateCertificate, these will end up in Certificate.Extensions + ExtraExtensions: []pkix.Extension{ + {Id: extensionID, Value: value}, + }, + } + certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, certKey.Public(), certKey) + if err != nil { + return nil, err + } + return &tls.Certificate{ + Certificate: [][]byte{certDER}, + PrivateKey: certKey, + }, nil +} + +// We want nodes without AES hardware (e.g. ARM) support to always use ChaCha. +// Only if both nodes have AES hardware support (e.g. x86), AES should be used. +// x86->x86: AES, ARM->x86: ChaCha, x86->ARM: ChaCha and ARM->ARM: Chacha +// This function returns true if we don't have AES hardware support, and false otherwise. +// Thus, ARM servers will always use their own cipher suite preferences (ChaCha first), +// and x86 servers will aways use the client's cipher suite preferences. +func preferServerCipherSuites() bool { + // Copied from the Go TLS implementation. + + // Check the cpu flags for each platform that has optimized GCM implementations. + // Worst case, these variables will just all be false. + var ( + hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // Keep in sync with crypto/aes/cipher_s390x.go. + hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) + + hasGCMAsm = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X + ) + return !hasGCMAsm +} diff --git a/vendor/github.com/libp2p/go-libp2p-tls/extension.go b/vendor/github.com/libp2p/go-libp2p-tls/extension.go new file mode 100644 index 00000000..9472c77e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/extension.go @@ -0,0 +1,22 @@ +package libp2ptls + +var extensionPrefix = []int{1, 3, 6, 1, 4, 1, 53594} + +// getPrefixedExtensionID returns an Object Identifier +// that can be used in x509 Certificates. +func getPrefixedExtensionID(suffix []int) []int { + return append(extensionPrefix, suffix...) +} + +// extensionIDEqual compares two extension IDs. +func extensionIDEqual(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/vendor/github.com/libp2p/go-libp2p-tls/go.mod b/vendor/github.com/libp2p/go-libp2p-tls/go.mod new file mode 100644 index 00000000..f299848c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/go.mod @@ -0,0 +1,11 @@ +module github.com/libp2p/go-libp2p-tls + +go 1.12 + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-crypto v0.1.0 + github.com/onsi/ginkgo v1.7.0 + github.com/onsi/gomega v1.4.3 + golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09 +) diff --git a/vendor/github.com/libp2p/go-libp2p-tls/go.sum b/vendor/github.com/libp2p/go-libp2p-tls/go.sum new file mode 100644 index 00000000..508f4305 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/go.sum @@ -0,0 +1,83 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09 h1:IlD35wZE03o2qJy2o37WIskL33b7PT6cHdGnE8bieZs= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-tls/transport.go b/vendor/github.com/libp2p/go-libp2p-tls/transport.go new file mode 100644 index 00000000..2dc4257a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-tls/transport.go @@ -0,0 +1,136 @@ +package libp2ptls + +import ( + "context" + "crypto/tls" + "errors" + "net" + "os" + + ci "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" +) + +// TLS 1.3 is opt-in in Go 1.12 +// Activate it by setting the tls13 GODEBUG flag. +func init() { + os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1") +} + +// ID is the protocol ID (used when negotiating with multistream) +const ID = "/tls/1.0.0" + +// Transport constructs secure communication sessions for a peer. +type Transport struct { + identity *Identity + + localPeer peer.ID + privKey ci.PrivKey +} + +// New creates a TLS encrypted transport +func New(key ci.PrivKey) (*Transport, error) { + id, err := peer.IDFromPrivateKey(key) + if err != nil { + return nil, err + } + t := &Transport{ + localPeer: id, + privKey: key, + } + + identity, err := NewIdentity(key) + if err != nil { + return nil, err + } + t.identity = identity + return t, nil +} + +var _ sec.SecureTransport = &Transport{} + +// SecureInbound runs the TLS handshake as a server. +func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { + config, keyCh := t.identity.ConfigForAny() + return t.handshake(ctx, tls.Server(insecure, config), keyCh) +} + +// SecureOutbound runs the TLS handshake as a client. +// Note that SecureOutbound will not return an error if the server doesn't +// accept the certificate. This is due to the fact that in TLS 1.3, the client +// sends its certificate and the ClientFinished in the same flight, and can send +// application data immediately afterwards. +// If the handshake fails, the server will close the connection. The client will +// notice this after 1 RTT when calling Read. +func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + config, keyCh := t.identity.ConfigForPeer(p) + return t.handshake(ctx, tls.Client(insecure, config), keyCh) +} + +func (t *Transport) handshake( + ctx context.Context, + tlsConn *tls.Conn, + keyCh <-chan ci.PubKey, +) (sec.SecureConn, error) { + // There's no way to pass a context to tls.Conn.Handshake(). + // See https://github.com/golang/go/issues/18482. + // Close the connection instead. + select { + case <-ctx.Done(): + tlsConn.Close() + default: + } + done := make(chan struct{}) + defer close(done) + go func() { + select { + case <-done: + case <-ctx.Done(): + tlsConn.Close() + } + }() + + if err := tlsConn.Handshake(); err != nil { + // if the context was canceled, return the context error + if ctxErr := ctx.Err(); ctxErr != nil { + return nil, ctxErr + } + return nil, err + } + + // Should be ready by this point, don't block. + var remotePubKey ci.PubKey + select { + case remotePubKey = <-keyCh: + default: + } + + conn, err := t.setupConn(tlsConn, remotePubKey) + if err != nil { + // if the context was canceled, return the context error + if ctxErr := ctx.Err(); ctxErr != nil { + return nil, ctxErr + } + return nil, err + } + return conn, nil +} + +func (t *Transport) setupConn(tlsConn *tls.Conn, remotePubKey ci.PubKey) (sec.SecureConn, error) { + if remotePubKey == nil { + return nil, errors.New("go-libp2p-tls BUG: expected remote pub key to be set") + } + + remotePeerID, err := peer.IDFromPublicKey(remotePubKey) + if err != nil { + return nil, err + } + return &conn{ + Conn: tlsConn, + localPeer: t.localPeer, + privKey: t.privKey, + remotePeer: remotePeerID, + remotePubKey: remotePubKey, + }, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/.travis.yml b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/LICENSE b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/LICENSE new file mode 100644 index 00000000..6cccfc2b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Protocol Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/README.md b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/README.md new file mode 100644 index 00000000..ef143810 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/README.md @@ -0,0 +1,128 @@ +# go-libp2p-transport-upgrader + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-transport-upgrader?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-transport-upgrader) +[![Build Status](https://travis-ci.org/libp2p/go-libp2p-transport-upgrader.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-transport-upgrader) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> Stream connection to libp2p connection upgrader + +This package provides the necessary logic to upgrade [multiaddr-net][manet] connections listeners into full [libp2p-transport][tpt] connections and listeners. + +To use, construct a new `Upgrader` with: + +* An optional [pnet][pnet] `Protector`. +* An optional [multiaddr-net][manet] address `Filter`. +* A mandatory [stream security transport][ss]. +* A mandatory [stream multiplexer transport][smux]. + +[tpt]: https://github.com/libp2p/go-libp2p-transport +[manet]: https://github.com/multiformats/go-multiaddr-net +[ss]: https://github.com/libp2p/go-conn-security +[smux]: https://github.com/libp2p/go-stream-muxer +[pnet]: https://github.com/libp2p/go-libp2p-interface-pnet + +Note: This package largely replaces the functionality of [go-libp2p-conn](https://github.com/libp2p/go-libp2p-conn) but with half the code. + +## Install + +`go-libp2p-transport-upgrader` is a standard Go module which can be installed with: + +```sh +go get github.com/libp2p/go-libp2p-transport-upgrader +``` + +This repo is [gomod](https://github.com/golang/go/wiki/Modules)-compatible, and users of +go 1.11 and later with modules enabled will automatically pull the latest tagged release +by referencing this package. Upgrades to future releases can be managed using `go get`, +or by editing your `go.mod` file as [described by the gomod documentation](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies). + +## Usage + +## Example + +Below is a simplified TCP transport implementation using the transport upgrader. In practice, you'll want to use [go-tcp-transport](https://github.com/libp2p/go-tcp-transport) (which has reuseport support). + +```go +package tcptransport + +import ( + "context" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + + ma "github.com/multiformats/go-multiaddr" + mafmt "github.com/whyrusleeping/mafmt" + manet "github.com/multiformats/go-multiaddr-net" + tpt "github.com/libp2p/go-libp2p-transport" +) + +// TcpTransport is a simple TCP transport. +type TcpTransport struct { + // Connection upgrader for upgrading insecure stream connections to + // secure multiplex connections. + Upgrader *tptu.Upgrader +} + +var _ tpt.Transport = &TcpTransport{} + +// NewTCPTransport creates a new TCP transport instance. +func NewTCPTransport(upgrader *tptu.Upgrader) *TcpTransport { + return &TcpTransport{Upgrader: upgrader} +} + +// CanDial returns true if this transport believes it can dial the given +// multiaddr. +func (t *TcpTransport) CanDial(addr ma.Multiaddr) bool { + return mafmt.TCP.Matches(addr) +} + +// Dial dials the peer at the remote address. +func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tpt.Conn, error) { + var dialer manet.Dialer + conn, err := dialer.DialContext(ctx, raddr) + if err != nil { + return nil, err + } + return t.Upgrader.UpgradeOutbound(ctx, t, conn, p) +} + +// Listen listens on the given multiaddr. +func (t *TcpTransport) Listen(laddr ma.Multiaddr) (tpt.Listener, error) { + list, err := manet.Listen(laddr) + if err != nil { + return nil, err + } + return t.Upgrader.UpgradeListener(t, list), nil +} + +// Protocols returns the list of terminal protocols this transport can dial. +func (t *TcpTransport) Protocols() []int { + return []int{ma.P_TCP} +} + +// Proxy always returns false for the TCP transport. +func (t *TcpTransport) Proxy() bool { + return false +} +``` + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-libp2p-transport-upgrader/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 0.1.28: QmeqC5shQjEBRG9B8roZqQCJ9xb7Pq6AbWxJFMyLgqBBWh diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/codecov.yml b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/conn.go b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/conn.go new file mode 100644 index 00000000..2098b151 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/conn.go @@ -0,0 +1,35 @@ +package stream + +import ( + "fmt" + + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/transport" +) + +type transportConn struct { + mux.MuxedConn + network.ConnMultiaddrs + network.ConnSecurity + transport transport.Transport +} + +func (t *transportConn) Transport() transport.Transport { + return t.transport +} + +func (t *transportConn) String() string { + ts := "" + if s, ok := t.transport.(fmt.Stringer); ok { + ts = "[" + s.String() + "]" + } + return fmt.Sprintf( + " %s (%s)>", + ts, + t.LocalMultiaddr(), + t.LocalPeer(), + t.RemoteMultiaddr(), + t.RemotePeer(), + ) +} diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.mod b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.mod new file mode 100644 index 00000000..d7b59886 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.mod @@ -0,0 +1,13 @@ +module github.com/libp2p/go-libp2p-transport-upgrader + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-mplex v0.2.0 + github.com/libp2p/go-maddr-filter v0.0.4 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/onsi/ginkgo v1.8.0 + github.com/onsi/gomega v1.5.0 +) diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.sum b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.sum new file mode 100644 index 00000000..83358689 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/go.sum @@ -0,0 +1,120 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-mplex v0.2.0 h1:vnR+/fUnL5d2kTB1Lfce1KVSP+bCCy2aJIvqvb9cFqE= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3 h1:YiMaevQcZtFU6DmKIF8xEO0vaui5kM5HJ1V1xkWQv14= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/listener.go b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/listener.go new file mode 100644 index 00000000..f792c991 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/listener.go @@ -0,0 +1,160 @@ +package stream + +import ( + "context" + "fmt" + "sync" + + "github.com/libp2p/go-libp2p-core/transport" + + logging "github.com/ipfs/go-log" + tec "github.com/jbenet/go-temp-err-catcher" + manet "github.com/multiformats/go-multiaddr-net" +) + +var log = logging.Logger("stream-upgrader") + +type connErr struct { + conn transport.CapableConn + err error +} + +type listener struct { + manet.Listener + + transport transport.Transport + upgrader *Upgrader + + incoming chan transport.CapableConn + err error + + // Used for backpressure + threshold *threshold + + // Canceling this context isn't sufficient to tear down the listener. + // Call close. + ctx context.Context + cancel func() +} + +// Close closes the listener. +func (l *listener) Close() error { + // Do this first to try to get any relevent errors. + err := l.Listener.Close() + + l.cancel() + // Drain and wait. + for c := range l.incoming { + c.Close() + } + return err +} + +// handles inbound connections. +// +// This function does a few interesting things that should be noted: +// +// 1. It logs and discards temporary/transient errors (errors with a Temporary() +// function that returns true). +// 2. It stops accepting new connections once AcceptQueueLength connections have +// been fully negotiated but not accepted. This gives us a basic backpressure +// mechanism while still allowing us to negotiate connections in parallel. +func (l *listener) handleIncoming() { + var wg sync.WaitGroup + defer func() { + // make sure we're closed + l.Listener.Close() + if l.err == nil { + l.err = fmt.Errorf("listener closed") + } + + wg.Wait() + close(l.incoming) + }() + + var catcher tec.TempErrCatcher + for l.ctx.Err() == nil { + maconn, err := l.Listener.Accept() + if err != nil { + // Note: function may pause the accept loop. + if catcher.IsTemporary(err) { + log.Infof("temporary accept error: %s", err) + continue + } + l.err = err + return + } + + // The go routine below calls Release when the context is + // canceled so there's no need to wait on it here. + l.threshold.Wait() + + log.Debugf("listener %s got connection: %s <---> %s", + l, + maconn.LocalMultiaddr(), + maconn.RemoteMultiaddr()) + + wg.Add(1) + go func() { + defer wg.Done() + + ctx, cancel := context.WithTimeout(l.ctx, transport.AcceptTimeout) + defer cancel() + + conn, err := l.upgrader.UpgradeInbound(ctx, l.transport, maconn) + if err != nil { + // Don't bother bubbling this up. We just failed + // to completely negotiate the connection. + log.Debugf("accept upgrade error: %s (%s <--> %s)", + err, + maconn.LocalMultiaddr(), + maconn.RemoteMultiaddr()) + return + } + + log.Debugf("listener %s accepted connection: %s", l, conn) + + // This records the fact that the connection has been + // setup and is waiting to be accepted. This call + // *never* blocks, even if we go over the threshold. It + // simply ensures that calls to Wait block while we're + // over the threshold. + l.threshold.Acquire() + defer l.threshold.Release() + + select { + case l.incoming <- conn: + case <-ctx.Done(): + if l.ctx.Err() == nil { + // Listener *not* closed but the accept timeout expired. + log.Warningf("listener dropped connection due to slow accept") + } + // Wait on the context with a timeout. This way, + // if we stop accepting connections for some reason, + // we'll eventually close all the open ones + // instead of hanging onto them. + conn.Close() + } + }() + } +} + +// Accept accepts a connection. +func (l *listener) Accept() (transport.CapableConn, error) { + for c := range l.incoming { + // Could have been sitting there for a while. + if !c.IsClosed() { + return c, nil + } + } + return nil, l.err +} + +func (l *listener) String() string { + if s, ok := l.transport.(fmt.Stringer); ok { + return fmt.Sprintf("", s, l.Multiaddr()) + } + return fmt.Sprintf("", l.Multiaddr()) +} + +var _ transport.Listener = (*listener)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/threshold.go b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/threshold.go new file mode 100644 index 00000000..2c278bd3 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/threshold.go @@ -0,0 +1,50 @@ +package stream + +import ( + "sync" +) + +func newThreshold(cutoff int) *threshold { + t := &threshold{ + threshold: cutoff, + } + t.cond.L = &t.mu + return t +} + +type threshold struct { + mu sync.Mutex + cond sync.Cond + + count int + threshold int +} + +// Acquire increments the counter. It will not block. +func (t *threshold) Acquire() { + t.mu.Lock() + t.count++ + t.mu.Unlock() +} + +// Release decrements the counter. +func (t *threshold) Release() { + t.mu.Lock() + if t.count == 0 { + panic("negative count") + } + if t.threshold == t.count { + t.cond.Broadcast() + } + t.count-- + t.mu.Unlock() +} + +// Wait waits for the counter to drop below the threshold +func (t *threshold) Wait() { + t.mu.Lock() + for t.count >= t.threshold { + t.cond.Wait() + } + t.mu.Unlock() +} diff --git a/vendor/github.com/libp2p/go-libp2p-transport-upgrader/upgrader.go b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/upgrader.go new file mode 100644 index 00000000..5e3854b0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-transport-upgrader/upgrader.go @@ -0,0 +1,132 @@ +package stream + +import ( + "context" + "errors" + "fmt" + "net" + + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/pnet" + "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p-core/transport" + + filter "github.com/libp2p/go-maddr-filter" + manet "github.com/multiformats/go-multiaddr-net" +) + +// ErrNilPeer is returned when attempting to upgrade an outbound connection +// without specifying a peer ID. +var ErrNilPeer = errors.New("nil peer") + +// AcceptQueueLength is the number of connections to fully setup before not accepting any new connections +var AcceptQueueLength = 16 + +// Upgrader is a multistream upgrader that can upgrade an underlying connection +// to a full transport connection (secure and multiplexed). +type Upgrader struct { + Protector pnet.Protector + Secure sec.SecureTransport + Muxer mux.Multiplexer + Filters *filter.Filters +} + +// UpgradeListener upgrades the passed multiaddr-net listener into a full libp2p-transport listener. +func (u *Upgrader) UpgradeListener(t transport.Transport, list manet.Listener) transport.Listener { + ctx, cancel := context.WithCancel(context.Background()) + l := &listener{ + Listener: list, + upgrader: u, + transport: t, + threshold: newThreshold(AcceptQueueLength), + incoming: make(chan transport.CapableConn), + cancel: cancel, + ctx: ctx, + } + go l.handleIncoming() + return l +} + +// UpgradeOutbound upgrades the given outbound multiaddr-net connection into a +// full libp2p-transport connection. +func (u *Upgrader) UpgradeOutbound(ctx context.Context, t transport.Transport, maconn manet.Conn, p peer.ID) (transport.CapableConn, error) { + if p == "" { + return nil, ErrNilPeer + } + return u.upgrade(ctx, t, maconn, p) +} + +// UpgradeInbound upgrades the given inbound multiaddr-net connection into a +// full libp2p-transport connection. +func (u *Upgrader) UpgradeInbound(ctx context.Context, t transport.Transport, maconn manet.Conn) (transport.CapableConn, error) { + return u.upgrade(ctx, t, maconn, "") +} + +func (u *Upgrader) upgrade(ctx context.Context, t transport.Transport, maconn manet.Conn, p peer.ID) (transport.CapableConn, error) { + if u.Filters != nil && u.Filters.AddrBlocked(maconn.RemoteMultiaddr()) { + log.Debugf("blocked connection from %s", maconn.RemoteMultiaddr()) + maconn.Close() + return nil, fmt.Errorf("blocked connection from %s", maconn.RemoteMultiaddr()) + } + + var conn net.Conn = maconn + if u.Protector != nil { + pconn, err := u.Protector.Protect(conn) + if err != nil { + conn.Close() + return nil, fmt.Errorf("failed to setup private network protector: %s", err) + } + conn = pconn + } else if pnet.ForcePrivateNetwork { + log.Error("tried to dial with no Private Network Protector but usage" + + " of Private Networks is forced by the enviroment") + return nil, pnet.ErrNotInPrivateNetwork + } + sconn, err := u.setupSecurity(ctx, conn, p) + if err != nil { + conn.Close() + return nil, fmt.Errorf("failed to negotiate security protocol: %s", err) + } + smconn, err := u.setupMuxer(ctx, sconn, p) + if err != nil { + sconn.Close() + return nil, fmt.Errorf("failed to negotiate security stream multiplexer: %s", err) + } + return &transportConn{ + MuxedConn: smconn, + ConnMultiaddrs: maconn, + ConnSecurity: sconn, + transport: t, + }, nil +} + +func (u *Upgrader) setupSecurity(ctx context.Context, conn net.Conn, p peer.ID) (sec.SecureConn, error) { + if p == "" { + return u.Secure.SecureInbound(ctx, conn) + } + return u.Secure.SecureOutbound(ctx, conn, p) +} + +func (u *Upgrader) setupMuxer(ctx context.Context, conn net.Conn, p peer.ID) (mux.MuxedConn, error) { + // TODO: The muxer should take a context. + done := make(chan struct{}) + + var smconn mux.MuxedConn + var err error + go func() { + defer close(done) + smconn, err = u.Muxer.NewConn(conn, p == "") + }() + + select { + case <-done: + return smconn, err + case <-ctx.Done(): + // interrupt this process + conn.Close() + // wait to finish + <-done + return nil, ctx.Err() + } +} diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/.gitignore b/vendor/github.com/libp2p/go-libp2p-yamux/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/.travis.yml b/vendor/github.com/libp2p/go-libp2p-yamux/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/LICENSE b/vendor/github.com/libp2p/go-libp2p-yamux/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/Makefile b/vendor/github.com/libp2p/go-libp2p-yamux/Makefile new file mode 100644 index 00000000..3907e857 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/Makefile @@ -0,0 +1,19 @@ +build: deps + go build ./... + +test: deps + go test ./... + +test_race: deps + go test -race ./... + +gx-bins: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx-bins + gx --verbose install --global + gx-go rewrite + +clean: gx-bins + gx-go rewrite --undo diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/README.md b/vendor/github.com/libp2p/go-libp2p-yamux/README.md new file mode 100644 index 00000000..46165b7c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/README.md @@ -0,0 +1,25 @@ +# go-libp2p-yamux + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-yamux?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-yamux) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-libp2p-yamux/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-libp2p-yamux?branch=master) +[![Build Status](https://travis-ci.com/libp2p/go-libp2p-yamux.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-yamux) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> An adapter to integrate the yamux multiplexer into libp2p as a stream muxer. + +## Install + +```sh +go get github.com/libp2p/go-libp2p-yamux +``` + +## Usage + +Check out the [GoDocs](https://godoc.org/github.com/libp2p/go-libp2p-yamux). + +## License + +Dual-licensed under MIT and ASLv2, by way of the [Permissive License Stack](https://protocol.ai/blog/announcing-the-permissive-license-stack/). diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/go.mod b/vendor/github.com/libp2p/go-libp2p-yamux/go.mod new file mode 100644 index 00000000..d935b0b4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/go.mod @@ -0,0 +1,7 @@ +module github.com/libp2p/go-libp2p-yamux + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-testing v0.0.4 + github.com/libp2p/go-yamux v1.2.3 +) diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/go.sum b/vendor/github.com/libp2p/go-libp2p-yamux/go.sum new file mode 100644 index 00000000..d2bf1dea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/go.sum @@ -0,0 +1,59 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/package.json b/vendor/github.com/libp2p/go-libp2p-yamux/package.json new file mode 100644 index 00000000..72c6f64b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/go-smux-yamux" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/go-smux-yamux" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmUNMbRUsVYHi1D14annF7Rr7pQAX7TNLwpRCa975ojKnw", + "name": "yamux", + "version": "1.1.5" + }, + { + "author": "whyrusleeping", + "hash": "QmVtV1y2e8W4eQgzsP6qfSpCCZ6zWYE4m6NzJjB7iswwrT", + "name": "go-stream-muxer", + "version": "3.1.0" + } + ], + "gxVersion": "0.7.0", + "language": "go", + "license": "", + "name": "go-smux-yamux", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "2.0.10" +} + diff --git a/vendor/github.com/libp2p/go-libp2p-yamux/yamux.go b/vendor/github.com/libp2p/go-libp2p-yamux/yamux.go new file mode 100644 index 00000000..4875761c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p-yamux/yamux.go @@ -0,0 +1,77 @@ +package sm_yamux + +import ( + "io/ioutil" + "net" + + mux "github.com/libp2p/go-libp2p-core/mux" + yamux "github.com/libp2p/go-yamux" +) + +// Conn is a connection to a remote peer. +type conn yamux.Session + +func (c *conn) yamuxSession() *yamux.Session { + return (*yamux.Session)(c) +} + +func (c *conn) Close() error { + return c.yamuxSession().Close() +} + +func (c *conn) IsClosed() bool { + return c.yamuxSession().IsClosed() +} + +// OpenStream creates a new stream. +func (c *conn) OpenStream() (mux.MuxedStream, error) { + s, err := c.yamuxSession().OpenStream() + if err != nil { + return nil, err + } + + return s, nil +} + +// AcceptStream accepts a stream opened by the other side. +func (c *conn) AcceptStream() (mux.MuxedStream, error) { + s, err := c.yamuxSession().AcceptStream() + return s, err +} + +// Transport is a go-peerstream transport that constructs +// yamux-backed connections. +type Transport yamux.Config + +var DefaultTransport *Transport + +func init() { + config := yamux.DefaultConfig() + // We've bumped this to 16MiB as this critically limits throughput. + // + // 1MiB means a best case of 10MiB/s (83.89Mbps) on a connection with + // 100ms latency. The default gave us 2.4MiB *best case* which was + // totally unacceptable. + config.MaxStreamWindowSize = uint32(16 * 1024 * 1024) + // don't spam + config.LogOutput = ioutil.Discard + // We always run over a security transport that buffers internally + // (i.e., uses a block cipher). + config.ReadBufSize = 0 + DefaultTransport = (*Transport)(config) +} + +func (t *Transport) NewConn(nc net.Conn, isServer bool) (mux.MuxedConn, error) { + var s *yamux.Session + var err error + if isServer { + s, err = yamux.Server(nc, t.Config()) + } else { + s, err = yamux.Client(nc, t.Config()) + } + return (*conn)(s), err +} + +func (t *Transport) Config() *yamux.Config { + return (*yamux.Config)(t) +} diff --git a/vendor/github.com/libp2p/go-libp2p/.gitignore b/vendor/github.com/libp2p/go-libp2p/.gitignore new file mode 100644 index 00000000..895adf13 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/.gitignore @@ -0,0 +1,4 @@ +*.swp +examples/echo/echo +examples/multicodecs/multicodecs +.idea \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-libp2p/.travis.yml b/vendor/github.com/libp2p/go-libp2p/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-libp2p/LICENSE b/vendor/github.com/libp2p/go-libp2p/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p/NEWS.md b/vendor/github.com/libp2p/go-libp2p/NEWS.md new file mode 100644 index 00000000..ff497d72 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/NEWS.md @@ -0,0 +1,304 @@ +# go-libp2p release notes + +## 6.0.0 + +We're pleased to announce go-libp2p 6.0.0. This release includes a massive +refactor of go-libp2p that paves the way for new transports such as QUIC. +Unfortunately, as it is broad sweeping, there are some breaking changes, +*especially* for maintainers of custom transports. + +Below, we cover the changes you'll likely care about. For convenience, we've +broken this into a section for users and transport authors/maintainers. However, +transport maintainers should really read both sections. + +### For Users + +Libp2p users should be aware of a few major changes. + +* Guarantees and performance concerning connect/disconnect notification + processing have improved. +* Handling of half-closed streams has changed (READ THIS SECTION). +* Some constructors and method signatures have changed slightly. + +#### Dialing And Source Addresses + +We've improved the logic that selects the source address when dialing. In the +past, you may have run into an issue where you couldn't dial non-local nodes +when listening on 127.0.0.1 as opposed to 0.0.0.0. This happened because +go-libp2p would randomly pick the source address from the set of addresses on +which the node was listening. We did this to ensure that the other end could +dial us back at the same address. Unfortunately, one can't use 127.0.0.1 as a +source address when dialing any non-local address so outbound dials failed. + +go-libp2p now tries to be smarter about this and avoids picking source addresses +that have no route to the destination address. + +#### Bandwidth Metrics + +To start out on an unhappy note, bandwidth metrics are now less accurate. In the +past, transports returned "minimal" connections (e.g., a TCP connection) so we +could wrap these transport connections in "metrics" connections that counted +every byte sent and received. + +Unfortunately, now that we've moved encryption and multiplexing down into the +transport layer, the connection we're wrapping has significantly more +under-the-covers overhead. + +However, we do hope to improve this and get even *better* bandwidth metrics than +we did before. See [libp2p/go-libp2p-transport#31][] for details. + +[libp2p/go-libp2p-transport#31]: https://github.com/libp2p/go-libp2p-transport/issues/31 + +#### Notifications + +This release brings performance improvements and easy to reason about ordering +guarantees libp2p connect/disconnect events: + +1. For any given connection/stream, libp2p will wait for all connect/open event + handlers to finish exit before triggering a disconnect/close event for the + connection/stream. +2. When a user calls the Close (or `Reset`) method on a connection or stream, + go-libp2p will process the close event asynchronously (i.e., not block the + call to `Close`). Otherwise, a call to `Close` from within a connect event + handler would deadlock. +3. Unless otherwise noted, events will be handled in parallel. + +What does this mean for end users? Well: + +1. Reference counting connections to a peer using connect/disconnect events + should "just work" and should never go negative. +2. Under heavy connect/disconnect loads, connecting to new peers should be + faster (usually). + +For those interested in the history of this issue, ... + +In the past, (dis)connect and stream open/close notifications have been a bit of +a pain point. For a long time, they were fired off in parallel and one could, for +example, process a disconnect notification before a connect notification (we had +to support *negative* ref-counts in several places to account for this). + +After no end of trouble, we finally "fixed" this by synchronizing notification +delivery. We still delivered notifications to all notifiees in parallel, we just +processed the events in series. + +Unfortunately, under heavy connect/disconnect load, new connections could easily +get stuck on open behind a queue of connect events all being handled in series. +In theory, these events should have been handled quickly but in practice, it's +very hard to avoid locks *entirely* (bitswap's event handlers were especially +problematic). + +Worse, this serial delivery guarantee didn't actually provide us with an +*in-order* delivery guarantee as it was still possible for a disconnect to +happen before we even *started* to fire the connect event. The situation was +slightly better than before because the events couldn't overlap but still far +from optimal. + +However, this has all been resolved now. From now on, you'll never receive a +disconnect event before a connect event. + +#### Conn.GetStreams Signature Change + +The signature of the `GetStreams` method on `go-libp2p-net.Conn` has changed from: + +```go +GetStreams() ([]Stream, error) +``` + +To: + +```go +GetStreams() []Stream +``` + +Listing the streams on an open connection should never involve IO or do anything +that can fail so we removed this error to improve usability. + +#### Libp2p Constructor + +If you're not already doing so, you should be using the `libp2p.New` constructor +to make your libp2p nodes. This release brings quite a few new options to the +libp2p constructor so if it hasn't been flexible enough for you in the past, I +recommend that you try again. A simple example can be found in the +[echo][example:echo] example. + +Given this work and in an attempt to consolidate all of our configuration logic +in one place, we've removed all default transports from go-libp2p-swarm. + +TL;DR: Please use the libp2p constructor. + +#### Zombie Streams + +From this release on, when you're done with a stream, you must either call +`Reset` on it (in case of an error) or close it and read an EOF (or some other +error). Otherwise, libp2p can't determine if the stream is *actually* closed and +will hang onto it indefinitely. + +To make properly closing streams a bit easier, we've added two methods to +[go-libp2p-net][]: `AwaitEOF` and `FullClose`. + +* `AwaitEOF(stream)` tries to read a single byte from the stream. If `Read` +returns an EOF, `AwaitEOF` returns success. Otherwise, if `Read` either reads +some data or returns some other error, `AwaitEOF` resets the stream and returns +an error. To avoid waiting indefinitely, `AwaitEOF` resets the stream +unconditionally after 1 minute. +* `FullClose(stream)` is a convenience function that closes the stream and then +calls `AwaitEOF` on it. + +Like with libp2p notifications, this issue has a bit of history... + +In the beginning, libp2p assumed that calling `Close` on a stream would close +the stream for both reading and writing. Unfortunately, *none* of our stream +multiplexers actually behaved this way. In practice, `Close` always closed the +stream for writing. + +After realizing this, we made two changes: + +1. We accepted the fact that `Close` only closed the stream for writing. +2. We added a `Reset` method for killing the stream (closing it in both + directions, throwing away any buffered data). + +However, we ran into a bit of a snag because we try to track open streams and +need some way to tell when a stream has been closed. In the past this was easy: +when the user calls `Close` on the stream, stop tracking it. However, now that +`Close` only closes the stream for writing, we still *technically* needed to +track it until the *other* end closed the stream as well. Unfortunately, without +actually reading from the stream, we have no way of knowing about this. +Therefore, if the user calls `Close` on a stream and then walks away, we'd have +to hang onto the stream indefinitely. + +Our solution was to simply stop tracking streams once they were closed for +writing. This wasn't the *correct* behavior but it avoided leaking memory in the +common case: + +1. The user calls `Close` and drops all references to the stream. +2. The other end calls `Close` without writing any additional data. +3. The stream multiplexer observes both closes and drops *its* reference to the stream. +4. The garbage collector garbage collects the stream. + +However, this meant that: + +1. The list of "open" streams was technically incomplete. +2. If the other side either failed to call `Close` or tried to send data before + closing, the stream would remain "open" (until the connection was closed). + +In this release, we've changed this behavior. Now, when you `Close` a stream for +writing, libp2p *continues* to track it. We only stop tracking it when either: + +1. You call `Reset` (throwing away the stream). +2. You finish reading any data off of it and observe either an EOF or an error. + +This way, we never "forget" about open streams or leave them in a half-forgotten +state. + +In the future, I'd like to add a `CloseAndForget` method to streams that: + +1. Closes the stream (sends an EOF). +2. Tells the swarm to stop tracking the stream. +3. Tells the stream muxer to stop tracking the stream and throw away any data + the other side may send (possibly resetting the stream on unexpected data). + +However: + +1. This would likely require modifying our stream muxers which may not be + feasible. +2. Explicitly waiting for an EOF is still the correct thing to do unless you + really don't care if the operation succeeded. + +### For Transport Maintainers + +For transport maintainers, quite a bit has changed. Before this change, +transports created simple, unencrypted, stream connections and it was the job of +the libp2p Network (go-libp2p-swarm) to negotiate security, multiplexing, etc. + +However, when attempting to add support for the QUIC protocol, we realized that +this was going to be a problem: QUIC already handles authentication and +encryption (using TLS1.3) and multiplexing. After much debate, we inverted our +current architecture and made transports responsible for encrypting/multiplexing +their connections (before returning them). + +To make this palatable, we've also introduced a new ["upgrader" +library][go-libp2p-transport-upgrader] for upgrading go-multiaddr-net +connections/listeners to full libp2p transport connections/listeners. Transports +that don't support encryption/multiplexing out of the box can expect to have an +upgrader passed into the constructor. + +To get a feel for how this new transport system works, take a look at the TCP +and WebSocket transports and the transport interface documentation: + +* [TCP Transport][go-tcp-transport] +* [WebSocket Transport][go-ws-transport] +* [Transport Interface][doc:go-libp2p-transport] + +#### Deprecated Packages + +This release sees the deprecation of a few packages: + +* [go-peerstream][] has been deprecated and all functionality has been merged + into [go-libp2p-swarm][]. [go-peerstream][] was written as a general-purpose + (not libp2p specific) listener, connection, and stream manager. However, this + package caused more problems than it solved and was incompatible with the new + transport interface. +* [go-libp2p-interface-conn][] has been deprecated. These interfaces to bridge + the gap between transport-level connections and [go-libp2p-net][] connections + however, now that transport connections are fully multiplexed/encrypted, this + is no longer needed. +* [go-libp2p-conn][] has also been deprecated and most of the functionality has + been moved to [go-libp2p-transport-upgrader][]. This package used to provide + connection "upgrade" logic for upgrading transport-level connections to + [go-libp2p-interface-conn][] connections however, transport-level connections + now provide the required functionality out of the box. + +#### Testing + +We've moved `GenSwarmNetwork` in [go-libp2p-netutil][] to `GenSwarm` in +[go-libp2p-swarm/testing][] because: + +1. The swarm duplicated this exact function for its own tests. +2. The swarm couldn't depend on [go-libp2p-netutil][] because + [go-libp2p-netutil][] depends on [go-libp2p-swarm][]. + +We've also added a new transport test suit +[go-libp2p-transport/test][]. If you implement a new transport, please consider +testing against these suite. If you find a bug in an existing transport, please +consider adding a test to this suite. + +#### go-addr-util + +In go-addr-util, we've removed the `SupportedTransportStrings` and +`SupportedTransportProtocols` transport registries and the associated +`AddTransport` function. These registries were updated by `init` functions in +packages providing transports and were used to keep track of known transports. + +However, *importing* a transport doesn't mean any libp2p nodes have been +configured to actually *use* that transport. Therefore, in the new go-libp2p, +it's go-libp2p-swarm's job to keep track of which transports are supported +(i.e., which transports have been registered with the swarm). + +We've also removed the associated `AddrUsable`, `FilterUsableAddrs`, and +`AddrUsableFunc` functions. + +#### Pluggable Security Transports + +This release brings a new pluggable security transport framework. Implementing a +new security framework is now as simple as: + +1. Implement the interfaces defined in [go-conn-security][]. +2. Pass it into the libp2p constructor using the `Security` option. + +[go-conn-security]: https://github.com/libp2p/go-conn-security +[go-libp2p-conn]: https://github.com/libp2p/go-libp2p-conn +[go-libp2p-interface-conn]: https://github.com/libp2p/go-libp2p-interface-conn +[go-libp2p-net]: https://github.com/libp2p/go-libp2p-net +[go-libp2p-netutil]: https://github.com/libp2p/go-libp2p-netutil +[go-libp2p-swarm]: https://github.com/libp2p/go-libp2p-swarm +[go-libp2p-swarm/testing]: https://github.com/libp2p/go-libp2p-swarm/tree/master/testing +[go-libp2p-transport]: https://github.com/libp2p/go-libp2p-transport +[go-libp2p-transport/test]: https://github.com/libp2p/go-libp2p-transport/tree/master/test +[go-libp2p-transport-upgrader]: https://github.com/libp2p/go-libp2p-transport-upgrader +[go-peerstream]: https://github.com/libp2p/go-peerstream +[go-tcp-transport]: https://github.com/libp2p/go-tcp-transport +[go-ws-transport]: https://github.com/libp2p/go-ws-transport + +[example:echo]: https://github.com/libp2p/go-libp2p-examples/tree/master/echo + +[doc:go-libp2p-transport]: https://godoc.org/github.com/libp2p/go-libp2p-transport diff --git a/vendor/github.com/libp2p/go-libp2p/README.md b/vendor/github.com/libp2p/go-libp2p/README.md new file mode 100644 index 00000000..47ea441d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/README.md @@ -0,0 +1,214 @@ + +

+ libp2p hex logo +

+ +

The Go implementation of the libp2p Networking Stack.

+ +

+ + + + + +

+ +

+ +
+ + + +
+

+ +# Project status + +[![Throughput Graph](https://graphs.waffle.io/libp2p/go-libp2p/throughput.svg)](https://waffle.io/libp2p/go-libp2p/metrics/throughput) + +[**`Weekly Core Dev Calls`**](https://github.com/ipfs/pm/issues/674) + +# Table of Contents + +- [Background](#background) +- [Usage](#usage) + - [API](#api) + - [Examples](#examples) +- [Development](#development) + - [Using the libp2p Workspace](#using-the-libp2p-workspace) + - [About gx](#about-gx) + - [Tests](#tests) + - [Packages](#packages) +- [Contribute](#contribute) + +## Background + +[libp2p](https://github.com/libp2p/specs) is a networking stack and library modularized out of [The IPFS Project](https://github.com/ipfs/ipfs), and bundled separately for other tools to use. +> +libp2p is the product of a long, and arduous quest of understanding -- a deep dive into the internet's network stack, and plentiful peer-to-peer protocols from the past. Building large scale peer-to-peer systems has been complex and difficult in the last 15 years, and libp2p is a way to fix that. It is a "network stack" -- a protocol suite -- that cleanly separates concerns, and enables sophisticated applications to only use the protocols they absolutely need, without giving up interoperability and upgradeability. libp2p grew out of IPFS, but it is built so that lots of people can use it, for lots of different projects. +> +> We will be writing a set of docs, posts, tutorials, and talks to explain what p2p is, why it is tremendously useful, and how it can help your existing and new projects. But in the meantime, check out +> +> - [**Our developing collection of docs**](https://docs.libp2p.io) +> - [**Our community discussion forums**](https://discuss.libp2p.io) +> - [**The libp2p Specification**](https://github.com/libp2p/specs) +> - [**go-libp2p implementation**](https://github.com/libp2p/go-libp2p) +> - [**js-libp2p implementation**](https://github.com/libp2p/js-libp2p) +> - [**rust-libp2p implementation**](https://github.com/libp2p/rust-libp2p) + +## Usage + +This repository (`go-libp2p`) serves as the entrypoint to the universe of modules that compose the Go implementation of the libp2p stack. + +We mainly use [Go modules](https://github.com/golang/go/wiki/Modules) for our dependency and release management (and thus require go >= 1.11). In order to get the best developer experience, we recommend you do too. Otherwise, you may ocassionally encounter a breaking build as you'll be running off master (which, by definition, is not guaranteed to be stable). + +You can start using go-libp2p in your Go application simply by adding imports from our repos, e.g.: + +```go +import "github.com/libp2p/go-libp2p" +``` + +The next time you run `go get` or `go build`, the Go build tools will look for [available releases](https://github.com/libp2p/go-libp2p/releases), and will pick the highest available one. + +As new releases of go-libp2p are made available, you can upgrade your application by manually editing your `go.mod` file, or using the [Go tools](https://golang.org/cmd/go/#hdr-Maintaining_module_requirements) to maintain module requirements. + +### API + +[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p) + +### Examples + +Examples can be found in the [examples repo](https://github.com/libp2p/go-libp2p-examples). + +## Development + +### Using the libp2p Workspace + +While developing, you may need to make changes to several modules at once, or you may want changes made locally in one module to be available for import by another. + +The [go libp2p workspace](https://github.com/libp2p/workspace-go-libp2p) provides a developer-oriented view of the modules that comprise go-libp2p. + +Using the tooling in the workspace repository, you can checkout all of go-libp2p's module repos and enter "local mode", which adds [replace directives](https://github.com/golang/go/wiki/Modules#gomod) to the go.mod files in each local working copy. When you build locally, the libp2p depdendencies will be resolved from your local working copies. + +Once you've committed your changes, you can switch back to "remote mode", which removes the replace directives and pulls imports from the main go module cache. + +See the [workspace repo](https://github.com/libp2p/workspace-go-libp2p) for more information. + +### About gx + +Before adopting gomod, libp2p used [gx](https://github.com/whyrusleeping/gx) to manage dependencies using [IPFS](https://ipfs.io). + +Due to the difficulties in keeping both dependency management solutions up-to-date, gx support was ended in April 2019. + +Ending gx support does not mean that existing gx builds will break. Because gx references dependencies by their immutable IPFS hash, any currently working gx builds will continue to work for as long as the dependencies are resolvable in IPFS. + +However, new changes to go-libp2p will not be published via gx, and users are encouraged to adopt gomod to stay up-to-date. + +If you experience any issues migrating from gx to gomod, please [join the discussion at the libp2p forums](https://discuss.libp2p.io/t/gomod-and-go-libp2p/44). + +### Tests + +`go test ./...` will run all tests in the repo. + +### Packages + +> This table is generated using the module [`package-table`](https://github.com/ipfs-shipyard/package-table) with `package-table --data=package-list.json`. + +List of packages currently in existence for libp2p: + +| Name | CI | Coverage | Description | +| ---------|---------|---------|--------- | +| **Libp2p** | +| [`go-libp2p`](//github.com/libp2p/go-libp2p) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p) | go-libp2p entry point | +| [`go-libp2p-host`](//github.com/libp2p/go-libp2p-host) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-host.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-host) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-host/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-host) | libp2p "host" interface | +| [`go-libp2p-blankhost`](//github.com/libp2p/go-libp2p-blankhost) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-blankhost.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-blankhost) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-blankhost/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-blankhost) | minimal implementation of the "host" interface | +| **Network** | +| [`go-libp2p-net`](//github.com/libp2p/go-libp2p-net) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-net.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-net) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-net/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-net) | libp2p connection and "network" interfaces | +| [`go-libp2p-swarm`](//github.com/libp2p/go-libp2p-swarm) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-swarm.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-swarm) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-swarm/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-swarm) | reference implementation | +| **Transport** | +| [`go-libp2p-transport`](//github.com/libp2p/go-libp2p-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-transport) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-transport) | interfaces | +| [`go-ws-transport`](//github.com/libp2p/go-ws-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-ws-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-ws-transport) | [![codecov](https://codecov.io/gh/libp2p/go-ws-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-ws-transport) | WebSocket transport | +| [`go-tcp-transport`](//github.com/libp2p/go-tcp-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-tcp-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-tcp-transport) | [![codecov](https://codecov.io/gh/libp2p/go-tcp-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-tcp-transport) | TCP transport | +| [`go-libp2p-quic-transport`](//github.com/libp2p/go-libp2p-quic-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-quic-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-quic-transport) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-quic-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-quic-transport) | QUIC transport | +| [`go-udp-transport`](//github.com/libp2p/go-udp-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-udp-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-udp-transport) | [![codecov](https://codecov.io/gh/libp2p/go-udp-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-udp-transport) | UDP transport | +| [`go-utp-transport`](//github.com/libp2p/go-utp-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-utp-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-utp-transport) | [![codecov](https://codecov.io/gh/libp2p/go-utp-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-utp-transport) | uTorrent transport (UTP) | +| [`go-libp2p-circuit`](//github.com/libp2p/go-libp2p-circuit) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-circuit.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-circuit) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-circuit/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-circuit) | relay transport | +| [`go-libp2p-transport-upgrader`](//github.com/libp2p/go-libp2p-transport-upgrader) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-transport-upgrader.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-transport-upgrader) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-transport-upgrader/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-transport-upgrader) | upgrades multiaddr-net connections into full libp2p transports | +| [`go-libp2p-reuseport-transport`](//github.com/libp2p/go-libp2p-reuseport-transport) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-reuseport-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-reuseport-transport) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-reuseport-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-reuseport-transport) | partial transport for building transports that reuse ports | +| **Encrypted Channels** | +| [`go-conn-security`](//github.com/libp2p/go-conn-security) | [![Travis CI](https://travis-ci.com/libp2p/go-conn-security.svg?branch=master)](https://travis-ci.com/libp2p/go-conn-security) | [![codecov](https://codecov.io/gh/libp2p/go-conn-security/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-conn-security) | interfaces | +| [`go-libp2p-secio`](//github.com/libp2p/go-libp2p-secio) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-secio.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-secio) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-secio/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-secio) | SecIO crypto channel | +| [`go-conn-security-multistream`](//github.com/libp2p/go-conn-security-multistream) | [![Travis CI](https://travis-ci.com/libp2p/go-conn-security-multistream.svg?branch=master)](https://travis-ci.com/libp2p/go-conn-security-multistream) | [![codecov](https://codecov.io/gh/libp2p/go-conn-security-multistream/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-conn-security-multistream) | multistream multiplexed meta crypto channel | +| **Private Network** | +| [`go-libp2p-interface-pnet`](//github.com/libp2p/go-libp2p-interface-pnet) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-interface-pnet.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-interface-pnet) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-interface-pnet/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-interface-pnet) | interfaces | +| [`go-libp2p-pnet`](//github.com/libp2p/go-libp2p-pnet) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-pnet.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-pnet) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-pnet/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-pnet) | reference implementation | +| **Stream Muxers** | +| [`go-stream-muxer`](//github.com/libp2p/go-stream-muxer) | [![Travis CI](https://travis-ci.com/libp2p/go-stream-muxer.svg?branch=master)](https://travis-ci.com/libp2p/go-stream-muxer) | [![codecov](https://codecov.io/gh/libp2p/go-stream-muxer/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-stream-muxer) | interfaces | +| [`go-smux-yamux`](//github.com/whyrusleeping/go-smux-yamux) | [![Travis CI](https://travis-ci.com/whyrusleeping/go-smux-yamux.svg?branch=master)](https://travis-ci.com/whyrusleeping/go-smux-yamux) | [![codecov](https://codecov.io/gh/whyrusleeping/go-smux-yamux/branch/master/graph/badge.svg)](https://codecov.io/gh/whyrusleeping/go-smux-yamux) | YAMUX stream multiplexer | +| [`go-smux-multiplex`](//github.com/whyrusleeping/go-smux-multiplex) | [![Travis CI](https://travis-ci.com/whyrusleeping/go-smux-multiplex.svg?branch=master)](https://travis-ci.com/whyrusleeping/go-smux-multiplex) | [![codecov](https://codecov.io/gh/whyrusleeping/go-smux-multiplex/branch/master/graph/badge.svg)](https://codecov.io/gh/whyrusleeping/go-smux-multiplex) | MPLEX stream multiplexer | +| **NAT Traversal** | +| [`go-libp2p-nat`](//github.com/libp2p/go-libp2p-nat) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-nat.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-nat) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-nat/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-nat) | | +| **Peerstore** | +| [`go-libp2p-peerstore`](//github.com/libp2p/go-libp2p-peerstore) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-peerstore.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-peerstore) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-peerstore/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-peerstore) | interfaces and reference implementation | +| **Connection Manager** | +| [`go-libp2p-interface-connmgr`](//github.com/libp2p/go-libp2p-interface-connmgr) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-interface-connmgr.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-interface-connmgr) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-interface-connmgr/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-interface-connmgr) | interface | +| [`go-libp2p-connmgr`](//github.com/libp2p/go-libp2p-connmgr) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-connmgr.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-connmgr) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-connmgr/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-connmgr) | reference implementation | +| **Routing** | +| [`go-libp2p-routing`](//github.com/libp2p/go-libp2p-routing) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-routing.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-routing) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-routing) | routing interfaces | +| [`go-libp2p-record`](//github.com/libp2p/go-libp2p-record) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-record.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-record) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-record/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-record) | record type and validator logic | +| [`go-libp2p-routing-helpers`](//github.com/libp2p/go-libp2p-routing-helpers) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-routing-helpers.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-routing-helpers) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-routing-helpers/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-routing-helpers) | helpers for composing routers | +| [`go-libp2p-kad-dht`](//github.com/libp2p/go-libp2p-kad-dht) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-kad-dht.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-kad-dht) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-kad-dht/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-kad-dht) | Kademlia-like router | +| [`go-libp2p-pubsub-router`](//github.com/libp2p/go-libp2p-pubsub-router) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-pubsub-router.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-pubsub-router) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-pubsub-router/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-pubsub-router) | record-store over pubsub adapter | +| **Consensus** | +| [`go-libp2p-consensus`](//github.com/libp2p/go-libp2p-consensus) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-consensus.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-consensus) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-consensus/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-consensus) | consensus protocols interfaces | +| [`go-libp2p-raft`](//github.com/libp2p/go-libp2p-raft) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-raft.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-raft) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-raft/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-raft) | consensus implementation over raft | +| **Pubsub** | +| [`go-libp2p-pubsub`](//github.com/libp2p/go-libp2p-pubsub) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-pubsub.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-pubsub) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-pubsub/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-pubsub) | multiple pubsub over libp2p implementations | +| **RPC** | +| [`go-libp2p-gorpc`](//github.com/libp2p/go-libp2p-gorpc) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-gorpc.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-gorpc) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-gorpc/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-gorpc) | a simple RPC library for libp2p | +| **Metrics** | +| [`go-libp2p-metrics`](//github.com/libp2p/go-libp2p-metrics) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-metrics.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-metrics) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-metrics/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-metrics) | libp2p metrics interfaces/collectors | +| **Data Types** | +| [`go-libp2p-peer`](//github.com/libp2p/go-libp2p-peer) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-peer.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-peer) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-peer/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-peer) | libp2p peer-ID datatype | +| [`go-libp2p-crypto`](//github.com/libp2p/go-libp2p-crypto) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-crypto.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-crypto) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-crypto/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-crypto) | libp2p key types | +| [`go-libp2p-protocol`](//github.com/libp2p/go-libp2p-protocol) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-protocol.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-protocol) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-protocol/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-protocol) | libp2p protocol datatype | +| [`go-libp2p-kbucket`](//github.com/libp2p/go-libp2p-kbucket) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-kbucket.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-kbucket) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-kbucket/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-kbucket) | Kademlia routing table helper types | +| **Utilities/miscellaneous** | +| [`go-libp2p-loggables`](//github.com/libp2p/go-libp2p-loggables) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-loggables.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-loggables) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-loggables/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-loggables) | logging helpers | +| [`go-maddr-filter`](//github.com/libp2p/go-maddr-filter) | [![Travis CI](https://travis-ci.com/libp2p/go-maddr-filter.svg?branch=master)](https://travis-ci.com/libp2p/go-maddr-filter) | [![codecov](https://codecov.io/gh/libp2p/go-maddr-filter/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-maddr-filter) | multiaddr filtering helpers | +| [`go-libp2p-netutil`](//github.com/libp2p/go-libp2p-netutil) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-netutil.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-netutil) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-netutil/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-netutil) | misc utilities | +| [`go-msgio`](//github.com/libp2p/go-msgio) | [![Travis CI](https://travis-ci.com/libp2p/go-msgio.svg?branch=master)](https://travis-ci.com/libp2p/go-msgio) | [![codecov](https://codecov.io/gh/libp2p/go-msgio/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-msgio) | length prefixed data channel | +| [`go-addr-util`](//github.com/libp2p/go-addr-util) | [![Travis CI](https://travis-ci.com/libp2p/go-addr-util.svg?branch=master)](https://travis-ci.com/libp2p/go-addr-util) | [![codecov](https://codecov.io/gh/libp2p/go-addr-util/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-addr-util) | address utilities for libp2p swarm | +| [`go-buffer-pool`](//github.com/libp2p/go-buffer-pool) | [![Travis CI](https://travis-ci.com/libp2p/go-buffer-pool.svg?branch=master)](https://travis-ci.com/libp2p/go-buffer-pool) | [![codecov](https://codecov.io/gh/libp2p/go-buffer-pool/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-buffer-pool) | a variable size buffer pool for go | +| [`go-libp2p-routing-helpers`](//github.com/libp2p/go-libp2p-routing-helpers) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-routing-helpers.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-routing-helpers) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-routing-helpers/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-routing-helpers) | routing helpers | +| [`go-reuseport`](//github.com/libp2p/go-reuseport) | [![Travis CI](https://travis-ci.com/libp2p/go-reuseport.svg?branch=master)](https://travis-ci.com/libp2p/go-reuseport) | [![codecov](https://codecov.io/gh/libp2p/go-reuseport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-reuseport) | enables reuse of addresses | +| [`go-sockaddr`](//github.com/libp2p/go-sockaddr) | [![Travis CI](https://travis-ci.com/libp2p/go-sockaddr.svg?branch=master)](https://travis-ci.com/libp2p/go-sockaddr) | [![codecov](https://codecov.io/gh/libp2p/go-sockaddr/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-sockaddr) | utils for sockaddr conversions | +| [`go-flow-metrics`](//github.com/libp2p/go-flow-metrics) | [![Travis CI](https://travis-ci.com/libp2p/go-flow-metrics.svg?branch=master)](https://travis-ci.com/libp2p/go-flow-metrics) | [![codecov](https://codecov.io/gh/libp2p/go-flow-metrics/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-flow-metrics) | metrics library | +| **Testing and examples** | +| [`go-testutil`](//github.com/libp2p/go-testutil) | [![Travis CI](https://travis-ci.com/libp2p/go-testutil.svg?branch=master)](https://travis-ci.com/libp2p/go-testutil) | [![codecov](https://codecov.io/gh/libp2p/go-testutil/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-testutil) | a collection of testing utilities for ipfs and libp2p | +| [`go-libp2p-examples`](//github.com/libp2p/go-libp2p-examples) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-examples.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-examples) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-examples/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-examples) | go-libp2p examples and tutorials | +| [`go-libp2p-circuit-progs`](//github.com/libp2p/go-libp2p-circuit-progs) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-circuit-progs.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-circuit-progs) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-circuit-progs/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-circuit-progs) | testing programs for go-libp2p-circuit | + +# Contribute + +go-libp2p is part of [The IPFS Project](https://github.com/ipfs/ipfs), and is MIT licensed open source software. We welcome contributions big and small! Take a look at the [community contributing notes](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md). Please make sure to check the [issues](https://github.com/ipfs/go-libp2p/issues). Search the closed ones before reporting things, and help us with the open ones. + +Guidelines: + +- read the [libp2p spec](https://github.com/libp2p/specs) +- please make branches + pull-request, even if working on the main repository +- ask questions or talk about things in [Issues](https://github.com/libp2p/go-libp2p/issues), our [discussion forums](https://discuss.libp2p.io), or #libp2p or #ipfs on freenode. +- ensure you are able to contribute (no legal issues please-- we use the DCO) +- run `go fmt` before pushing any code +- run `golint` and `go vet` too -- some things (like protobuf files) are expected to fail. +- get in touch with @jbenet and @diasdavid about how best to contribute +- have fun! + +There's a few things you can do right now to help out: + - Go through the modules below and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrasture behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically. + - **Perform code reviews**. + - **Add tests**. There can never be enough tests. + +--- + +The last gx published version of this module was: 6.0.41: QmTRN7hRxvGkxKxDdeudty7sRet4L7ZKZCqKsXHa79wmAc diff --git a/vendor/github.com/libp2p/go-libp2p/codecov.yml b/vendor/github.com/libp2p/go-libp2p/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-libp2p/config/config.go b/vendor/github.com/libp2p/go-libp2p/config/config.go new file mode 100644 index 00000000..3bb51bf1 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/config.go @@ -0,0 +1,258 @@ +package config + +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/pnet" + "github.com/libp2p/go-libp2p-core/routing" + + bhost "github.com/libp2p/go-libp2p/p2p/host/basic" + relay "github.com/libp2p/go-libp2p/p2p/host/relay" + routed "github.com/libp2p/go-libp2p/p2p/host/routed" + + circuit "github.com/libp2p/go-libp2p-circuit" + discovery "github.com/libp2p/go-libp2p-discovery" + swarm "github.com/libp2p/go-libp2p-swarm" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + + logging "github.com/ipfs/go-log" + filter "github.com/libp2p/go-maddr-filter" + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("p2p-config") + +// AddrsFactory is a function that takes a set of multiaddrs we're listening on and +// returns the set of multiaddrs we should advertise to the network. +type AddrsFactory = bhost.AddrsFactory + +// NATManagerC is a NATManager constructor. +type NATManagerC func(network.Network) bhost.NATManager + +type RoutingC func(host.Host) (routing.PeerRouting, error) + +// Config describes a set of settings for a libp2p node +// +// This is *not* a stable interface. Use the options defined in the root +// package. +type Config struct { + PeerKey crypto.PrivKey + + Transports []TptC + Muxers []MsMuxC + SecurityTransports []MsSecC + Insecure bool + Protector pnet.Protector + + RelayCustom bool + Relay bool + RelayOpts []circuit.RelayOpt + + ListenAddrs []ma.Multiaddr + AddrsFactory bhost.AddrsFactory + Filters *filter.Filters + + ConnManager connmgr.ConnManager + NATManager NATManagerC + Peerstore peerstore.Peerstore + Reporter metrics.Reporter + + DisablePing bool + + Routing RoutingC + + EnableAutoRelay bool +} + +// NewNode constructs a new libp2p Host from the Config. +// +// This function consumes the config. Do not reuse it (really!). +func (cfg *Config) NewNode(ctx context.Context) (host.Host, error) { + // Check this early. Prevents us from even *starting* without verifying this. + if pnet.ForcePrivateNetwork && cfg.Protector == nil { + log.Error("tried to create a libp2p node with no Private" + + " Network Protector but usage of Private Networks" + + " is forced by the enviroment") + // Note: This is *also* checked the upgrader itself so it'll be + // enforced even *if* you don't use the libp2p constructor. + return nil, pnet.ErrNotInPrivateNetwork + } + + if cfg.PeerKey == nil { + return nil, fmt.Errorf("no peer key specified") + } + + // Obtain Peer ID from public key + pid, err := peer.IDFromPublicKey(cfg.PeerKey.GetPublic()) + if err != nil { + return nil, err + } + + if cfg.Peerstore == nil { + return nil, fmt.Errorf("no peerstore specified") + } + + if !cfg.Insecure { + if err := cfg.Peerstore.AddPrivKey(pid, cfg.PeerKey); err != nil { + return nil, err + } + if err := cfg.Peerstore.AddPubKey(pid, cfg.PeerKey.GetPublic()); err != nil { + return nil, err + } + } + + // TODO: Make the swarm implementation configurable. + swrm := swarm.NewSwarm(ctx, pid, cfg.Peerstore, cfg.Reporter) + if cfg.Filters != nil { + swrm.Filters = cfg.Filters + } + + h, err := bhost.NewHost(ctx, swrm, &bhost.HostOpts{ + ConnManager: cfg.ConnManager, + AddrsFactory: cfg.AddrsFactory, + NATManager: cfg.NATManager, + EnablePing: !cfg.DisablePing, + }) + + if err != nil { + swrm.Close() + return nil, err + } + + if cfg.Relay { + // If we've enabled the relay, we should filter out relay + // addresses by default. + // + // TODO: We shouldn't be doing this here. + oldFactory := h.AddrsFactory + h.AddrsFactory = func(addrs []ma.Multiaddr) []ma.Multiaddr { + return oldFactory(relay.Filter(addrs)) + } + } + + upgrader := new(tptu.Upgrader) + upgrader.Protector = cfg.Protector + upgrader.Filters = swrm.Filters + if cfg.Insecure { + upgrader.Secure = makeInsecureTransport(pid) + } else { + upgrader.Secure, err = makeSecurityTransport(h, cfg.SecurityTransports) + if err != nil { + h.Close() + return nil, err + } + } + + upgrader.Muxer, err = makeMuxer(h, cfg.Muxers) + if err != nil { + h.Close() + return nil, err + } + + tpts, err := makeTransports(h, upgrader, cfg.Transports) + if err != nil { + h.Close() + return nil, err + } + for _, t := range tpts { + err = swrm.AddTransport(t) + if err != nil { + h.Close() + return nil, err + } + } + + if cfg.Relay { + err := circuit.AddRelayTransport(swrm.Context(), h, upgrader, cfg.RelayOpts...) + if err != nil { + h.Close() + return nil, err + } + } + + // TODO: This method succeeds if listening on one address succeeds. We + // should probably fail if listening on *any* addr fails. + if err := h.Network().Listen(cfg.ListenAddrs...); err != nil { + h.Close() + return nil, err + } + + // Configure routing and autorelay + var router routing.PeerRouting + if cfg.Routing != nil { + router, err = cfg.Routing(h) + if err != nil { + h.Close() + return nil, err + } + } + + if cfg.EnableAutoRelay { + if !cfg.Relay { + h.Close() + return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled") + } + + if router == nil { + h.Close() + return nil, fmt.Errorf("cannot enable autorelay; no routing for discovery") + } + + crouter, ok := router.(routing.ContentRouting) + if !ok { + h.Close() + return nil, fmt.Errorf("cannot enable autorelay; no suitable routing for discovery") + } + + discovery := discovery.NewRoutingDiscovery(crouter) + + hop := false + for _, opt := range cfg.RelayOpts { + if opt == circuit.OptHop { + hop = true + break + } + } + + if hop { + // advertise ourselves + relay.Advertise(ctx, discovery) + } else { + _ = relay.NewAutoRelay(swrm.Context(), h, discovery, router) + } + } + + // start the host background tasks + h.Start() + + if router != nil { + return routed.Wrap(h, router), nil + } + return h, nil +} + +// Option is a libp2p config option that can be given to the libp2p constructor +// (`libp2p.New`). +type Option func(cfg *Config) error + +// Apply applies the given options to the config, returning the first error +// encountered (if any). +func (cfg *Config) Apply(opts ...Option) error { + for _, opt := range opts { + if opt == nil { + continue + } + if err := opt(cfg); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go b/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go new file mode 100644 index 00000000..6f58c266 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go @@ -0,0 +1,63 @@ +package config + +import ( + "fmt" + "reflect" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/pnet" + "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p-core/transport" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + filter "github.com/libp2p/go-maddr-filter" +) + +var ( + // interfaces + hostType = reflect.TypeOf((*host.Host)(nil)).Elem() + networkType = reflect.TypeOf((*network.Network)(nil)).Elem() + transportType = reflect.TypeOf((*transport.Transport)(nil)).Elem() + muxType = reflect.TypeOf((*mux.Multiplexer)(nil)).Elem() + securityType = reflect.TypeOf((*sec.SecureTransport)(nil)).Elem() + protectorType = reflect.TypeOf((*pnet.Protector)(nil)).Elem() + privKeyType = reflect.TypeOf((*crypto.PrivKey)(nil)).Elem() + pubKeyType = reflect.TypeOf((*crypto.PubKey)(nil)).Elem() + pstoreType = reflect.TypeOf((*peerstore.Peerstore)(nil)).Elem() + + // concrete types + peerIDType = reflect.TypeOf((peer.ID)("")) + filtersType = reflect.TypeOf((*filter.Filters)(nil)) + upgraderType = reflect.TypeOf((*tptu.Upgrader)(nil)) +) + +var argTypes = map[reflect.Type]constructor{ + upgraderType: func(h host.Host, u *tptu.Upgrader) interface{} { return u }, + hostType: func(h host.Host, u *tptu.Upgrader) interface{} { return h }, + networkType: func(h host.Host, u *tptu.Upgrader) interface{} { return h.Network() }, + muxType: func(h host.Host, u *tptu.Upgrader) interface{} { return u.Muxer }, + securityType: func(h host.Host, u *tptu.Upgrader) interface{} { return u.Secure }, + protectorType: func(h host.Host, u *tptu.Upgrader) interface{} { return u.Protector }, + filtersType: func(h host.Host, u *tptu.Upgrader) interface{} { return u.Filters }, + peerIDType: func(h host.Host, u *tptu.Upgrader) interface{} { return h.ID() }, + privKeyType: func(h host.Host, u *tptu.Upgrader) interface{} { return h.Peerstore().PrivKey(h.ID()) }, + pubKeyType: func(h host.Host, u *tptu.Upgrader) interface{} { return h.Peerstore().PubKey(h.ID()) }, + pstoreType: func(h host.Host, u *tptu.Upgrader) interface{} { return h.Peerstore() }, +} + +func newArgTypeSet(types ...reflect.Type) map[reflect.Type]constructor { + result := make(map[reflect.Type]constructor, len(types)) + for _, ty := range types { + c, ok := argTypes[ty] + if !ok { + panic(fmt.Sprintf("missing constructor for type %s", ty)) + } + result[ty] = c + } + return result +} diff --git a/vendor/github.com/libp2p/go-libp2p/config/muxer.go b/vendor/github.com/libp2p/go-libp2p/config/muxer.go new file mode 100644 index 00000000..6f99336c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/muxer.go @@ -0,0 +1,63 @@ +package config + +import ( + "fmt" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/mux" + msmux "github.com/libp2p/go-stream-muxer-multistream" +) + +// MuxC is a stream multiplex transport constructor +type MuxC func(h host.Host) (mux.Multiplexer, error) + +// MsMuxC is a tuple containing a multiplex transport constructor and a protocol +// ID. +type MsMuxC struct { + MuxC + ID string +} + +var muxArgTypes = newArgTypeSet(hostType, networkType, peerIDType, pstoreType) + +// MuxerConstructor creates a multiplex constructor from the passed parameter +// using reflection. +func MuxerConstructor(m interface{}) (MuxC, error) { + // Already constructed? + if t, ok := m.(mux.Multiplexer); ok { + return func(_ host.Host) (mux.Multiplexer, error) { + return t, nil + }, nil + } + + ctor, err := makeConstructor(m, muxType, muxArgTypes) + if err != nil { + return nil, err + } + return func(h host.Host) (mux.Multiplexer, error) { + t, err := ctor(h, nil) + if err != nil { + return nil, err + } + return t.(mux.Multiplexer), nil + }, nil +} + +func makeMuxer(h host.Host, tpts []MsMuxC) (mux.Multiplexer, error) { + muxMuxer := msmux.NewBlankTransport() + transportSet := make(map[string]struct{}, len(tpts)) + for _, tptC := range tpts { + if _, ok := transportSet[tptC.ID]; ok { + return nil, fmt.Errorf("duplicate muxer transport: %s", tptC.ID) + } + transportSet[tptC.ID] = struct{}{} + } + for _, tptC := range tpts { + tpt, err := tptC.MuxC(h) + if err != nil { + return nil, err + } + muxMuxer.AddTransport(tptC.ID, tpt) + } + return muxMuxer, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go b/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go new file mode 100644 index 00000000..b422cf71 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go @@ -0,0 +1,126 @@ +package config + +import ( + "fmt" + "reflect" + "runtime" + + "github.com/libp2p/go-libp2p-core/host" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" +) + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +// checks if a function returns either the specified type or the specified type +// and an error. +func checkReturnType(fnType, tptType reflect.Type) error { + switch fnType.NumOut() { + case 2: + if fnType.Out(1) != errorType { + return fmt.Errorf("expected (optional) second return value from transport constructor to be an error") + } + + fallthrough + case 1: + if !fnType.Out(0).Implements(tptType) { + return fmt.Errorf("transport constructor returns %s which doesn't implement %s", fnType.Out(0), tptType) + } + default: + return fmt.Errorf("expected transport constructor to return a transport and, optionally, an error") + } + return nil +} + +// Handles return values with optional errors. That is, return values of the +// form `(something, error)` or just `something`. +// +// Panics if the return value isn't of the correct form. +func handleReturnValue(out []reflect.Value) (interface{}, error) { + switch len(out) { + case 2: + err := out[1] + if err != (reflect.Value{}) && !err.IsNil() { + return nil, err.Interface().(error) + } + fallthrough + case 1: + tpt := out[0] + + // Check for nil value and nil error. + if tpt == (reflect.Value{}) { + return nil, fmt.Errorf("unspecified error") + } + switch tpt.Kind() { + case reflect.Ptr, reflect.Interface, reflect.Func: + if tpt.IsNil() { + return nil, fmt.Errorf("unspecified error") + } + } + + return tpt.Interface(), nil + default: + panic("expected 1 or 2 return values from transport constructor") + } +} + +// calls the transport constructor and annotates the error with the name of the constructor. +func callConstructor(c reflect.Value, args []reflect.Value) (interface{}, error) { + val, err := handleReturnValue(c.Call(args)) + if err != nil { + name := runtime.FuncForPC(c.Pointer()).Name() + if name != "" { + // makes debugging easier + return nil, fmt.Errorf("transport constructor %s failed: %s", name, err) + } + } + return val, err +} + +type constructor func(h host.Host, u *tptu.Upgrader) interface{} + +func makeArgumentConstructors(fnType reflect.Type, argTypes map[reflect.Type]constructor) ([]constructor, error) { + out := make([]constructor, fnType.NumIn()) + for i := range out { + argType := fnType.In(i) + c, ok := argTypes[argType] + if !ok { + return nil, fmt.Errorf("argument %d has an unexpected type %s", i, argType.Name()) + } + out[i] = c + } + return out, nil +} + +// makes a transport constructor. +func makeConstructor( + tpt interface{}, + tptType reflect.Type, + argTypes map[reflect.Type]constructor, +) (func(host.Host, *tptu.Upgrader) (interface{}, error), error) { + v := reflect.ValueOf(tpt) + // avoid panicing on nil/zero value. + if v == (reflect.Value{}) { + return nil, fmt.Errorf("expected a transport or transport constructor, got a %T", tpt) + } + t := v.Type() + if t.Kind() != reflect.Func { + return nil, fmt.Errorf("expected a transport or transport constructor, got a %T", tpt) + } + + if err := checkReturnType(t, tptType); err != nil { + return nil, err + } + + argConstructors, err := makeArgumentConstructors(t, argTypes) + if err != nil { + return nil, err + } + + return func(h host.Host, u *tptu.Upgrader) (interface{}, error) { + arguments := make([]reflect.Value, len(argConstructors)) + for i, makeArg := range argConstructors { + arguments[i] = reflect.ValueOf(makeArg(h, u)) + } + return callConstructor(v, arguments) + }, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/config/security.go b/vendor/github.com/libp2p/go-libp2p/config/security.go new file mode 100644 index 00000000..8e1c710c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/security.go @@ -0,0 +1,78 @@ +package config + +import ( + "fmt" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p-core/sec/insecure" + + csms "github.com/libp2p/go-conn-security-multistream" +) + +// SecC is a security transport constructor +type SecC func(h host.Host) (sec.SecureTransport, error) + +// MsSecC is a tuple containing a security transport constructor and a protocol +// ID. +type MsSecC struct { + SecC + ID string +} + +var securityArgTypes = newArgTypeSet( + hostType, networkType, peerIDType, + privKeyType, pubKeyType, pstoreType, +) + +// SecurityConstructor creates a security constructor from the passed parameter +// using reflection. +func SecurityConstructor(security interface{}) (SecC, error) { + // Already constructed? + if t, ok := security.(sec.SecureTransport); ok { + return func(_ host.Host) (sec.SecureTransport, error) { + return t, nil + }, nil + } + + ctor, err := makeConstructor(security, securityType, securityArgTypes) + if err != nil { + return nil, err + } + return func(h host.Host) (sec.SecureTransport, error) { + t, err := ctor(h, nil) + if err != nil { + return nil, err + } + return t.(sec.SecureTransport), nil + }, nil +} + +func makeInsecureTransport(id peer.ID) sec.SecureTransport { + secMuxer := new(csms.SSMuxer) + secMuxer.AddTransport(insecure.ID, insecure.New(id)) + return secMuxer +} + +func makeSecurityTransport(h host.Host, tpts []MsSecC) (sec.SecureTransport, error) { + secMuxer := new(csms.SSMuxer) + transportSet := make(map[string]struct{}, len(tpts)) + for _, tptC := range tpts { + if _, ok := transportSet[tptC.ID]; ok { + return nil, fmt.Errorf("duplicate security transport: %s", tptC.ID) + } + transportSet[tptC.ID] = struct{}{} + } + for _, tptC := range tpts { + tpt, err := tptC.SecC(h) + if err != nil { + return nil, err + } + if _, ok := tpt.(*insecure.Transport); ok { + return nil, fmt.Errorf("cannot construct libp2p with an insecure transport, set the Insecure config option instead") + } + secMuxer.AddTransport(tptC.ID, tpt) + } + return secMuxer, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/config/transport.go b/vendor/github.com/libp2p/go-libp2p/config/transport.go new file mode 100644 index 00000000..ac8f8ee7 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/config/transport.go @@ -0,0 +1,67 @@ +package config + +import ( + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/transport" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" +) + +// TptC is the type for libp2p transport constructors. You probably won't ever +// implement this function interface directly. Instead, pass your transport +// constructor to TransportConstructor. +type TptC func(h host.Host, u *tptu.Upgrader) (transport.Transport, error) + +var transportArgTypes = argTypes + +// TransportConstructor uses reflection to turn a function that constructs a +// transport into a TptC. +// +// You can pass either a constructed transport (something that implements +// `transport.Transport`) or a function that takes any of: +// +// * The local peer ID. +// * A transport connection upgrader. +// * A private key. +// * A public key. +// * A Host. +// * A Network. +// * A Peerstore. +// * An address filter. +// * A security transport. +// * A stream multiplexer transport. +// * A private network protector. +// +// And returns a type implementing transport.Transport and, optionally, an error +// (as the second argument). +func TransportConstructor(tpt interface{}) (TptC, error) { + // Already constructed? + if t, ok := tpt.(transport.Transport); ok { + return func(_ host.Host, _ *tptu.Upgrader) (transport.Transport, error) { + return t, nil + }, nil + } + ctor, err := makeConstructor(tpt, transportType, transportArgTypes) + if err != nil { + return nil, err + } + return func(h host.Host, u *tptu.Upgrader) (transport.Transport, error) { + t, err := ctor(h, u) + if err != nil { + return nil, err + } + return t.(transport.Transport), nil + }, nil +} + +func makeTransports(h host.Host, u *tptu.Upgrader, tpts []TptC) ([]transport.Transport, error) { + transports := make([]transport.Transport, len(tpts)) + for i, tC := range tpts { + t, err := tC(h, u) + if err != nil { + return nil, err + } + transports[i] = t + } + return transports, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/defaults.go b/vendor/github.com/libp2p/go-libp2p/defaults.go new file mode 100644 index 00000000..18de400d --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/defaults.go @@ -0,0 +1,140 @@ +package libp2p + +// This file contains all the default configuration options. + +import ( + "crypto/rand" + + crypto "github.com/libp2p/go-libp2p-core/crypto" + mplex "github.com/libp2p/go-libp2p-mplex" + pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" + secio "github.com/libp2p/go-libp2p-secio" + yamux "github.com/libp2p/go-libp2p-yamux" + tcp "github.com/libp2p/go-tcp-transport" + ws "github.com/libp2p/go-ws-transport" + multiaddr "github.com/multiformats/go-multiaddr" +) + +// DefaultSecurity is the default security option. +// +// Useful when you want to extend, but not replace, the supported transport +// security protocols. +var DefaultSecurity = Security(secio.ID, secio.New) + +// DefaultMuxers configures libp2p to use the stream connection multiplexers. +// +// Use this option when you want to *extend* the set of multiplexers used by +// libp2p instead of replacing them. +var DefaultMuxers = ChainOptions( + Muxer("/yamux/1.0.0", yamux.DefaultTransport), + Muxer("/mplex/6.7.0", mplex.DefaultTransport), +) + +// DefaultTransports are the default libp2p transports. +// +// Use this option when you want to *extend* the set of transports used by +// libp2p instead of replacing them. +var DefaultTransports = ChainOptions( + Transport(tcp.NewTCPTransport), + Transport(ws.New), +) + +// DefaultPeerstore configures libp2p to use the default peerstore. +var DefaultPeerstore Option = func(cfg *Config) error { + return cfg.Apply(Peerstore(pstoremem.NewPeerstore())) +} + +// RandomIdentity generates a random identity (default behaviour) +var RandomIdentity = func(cfg *Config) error { + priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, rand.Reader) + if err != nil { + return err + } + return cfg.Apply(Identity(priv)) +} + +// DefaultListenAddrs configures libp2p to use default listen address +var DefaultListenAddrs = func(cfg *Config) error { + defaultIP4ListenAddr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/0") + if err != nil { + return err + } + + defaultIP6ListenAddr, err := multiaddr.NewMultiaddr("/ip6/::/tcp/0") + if err != nil { + return err + } + return cfg.Apply(ListenAddrs( + defaultIP4ListenAddr, + defaultIP6ListenAddr, + )) +} + +// DefaultEnableRelay enables relay dialing and listening by default +var DefaultEnableRelay = func(cfg *Config) error { + return cfg.Apply(EnableRelay()) +} + +// Complete list of default options and when to fallback on them. +// +// Please *DON'T* specify default options any other way. Putting this all here +// makes tracking defaults *much* easier. +var defaults = []struct { + fallback func(cfg *Config) bool + opt Option +}{ + { + fallback: func(cfg *Config) bool { return cfg.Transports == nil && cfg.ListenAddrs == nil }, + opt: DefaultListenAddrs, + }, + { + fallback: func(cfg *Config) bool { return cfg.Transports == nil }, + opt: DefaultTransports, + }, + { + fallback: func(cfg *Config) bool { return cfg.Muxers == nil }, + opt: DefaultMuxers, + }, + { + fallback: func(cfg *Config) bool { return !cfg.Insecure && cfg.SecurityTransports == nil }, + opt: DefaultSecurity, + }, + { + fallback: func(cfg *Config) bool { return cfg.PeerKey == nil }, + opt: RandomIdentity, + }, + { + fallback: func(cfg *Config) bool { return cfg.Peerstore == nil }, + opt: DefaultPeerstore, + }, + { + fallback: func(cfg *Config) bool { return !cfg.RelayCustom }, + opt: DefaultEnableRelay, + }, +} + +// Defaults configures libp2p to use the default options. Can be combined with +// other options to *extend* the default options. +var Defaults Option = func(cfg *Config) error { + for _, def := range defaults { + if err := cfg.Apply(def.opt); err != nil { + return err + } + } + return nil +} + +// FallbackDefaults applies default options to the libp2p node if and only if no +// other relevent options have been applied. will be appended to the options +// passed into New. +var FallbackDefaults Option = func(cfg *Config) error { + for _, def := range defaults { + if !def.fallback(cfg) { + continue + } + if err := cfg.Apply(def.opt); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/error_util.go b/vendor/github.com/libp2p/go-libp2p/error_util.go new file mode 100644 index 00000000..86827f4e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/error_util.go @@ -0,0 +1,17 @@ +package libp2p + +import ( + "fmt" + "runtime" +) + +func traceError(err error, skip int) error { + if err == nil { + return nil + } + _, file, line, ok := runtime.Caller(skip + 1) + if !ok { + return err + } + return fmt.Errorf("%s:%d: %s", file, line, err) +} diff --git a/vendor/github.com/libp2p/go-libp2p/go.mod b/vendor/github.com/libp2p/go-libp2p/go.mod new file mode 100644 index 00000000..d951ad3a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/go.mod @@ -0,0 +1,37 @@ +module github.com/libp2p/go-libp2p + +require ( + github.com/gogo/protobuf v1.2.1 + github.com/ipfs/go-cid v0.0.2 + github.com/ipfs/go-detect-race v0.0.1 + github.com/ipfs/go-ipfs-util v0.0.1 + github.com/ipfs/go-log v0.0.1 + github.com/jbenet/go-cienv v0.1.0 + github.com/jbenet/goprocess v0.1.3 + github.com/libp2p/go-conn-security-multistream v0.1.0 + github.com/libp2p/go-libp2p-autonat v0.1.0 + github.com/libp2p/go-libp2p-blankhost v0.1.1 + github.com/libp2p/go-libp2p-circuit v0.1.0 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-discovery v0.1.0 + github.com/libp2p/go-libp2p-loggables v0.1.0 + github.com/libp2p/go-libp2p-mplex v0.2.1 + github.com/libp2p/go-libp2p-nat v0.0.4 + github.com/libp2p/go-libp2p-netutil v0.1.0 + github.com/libp2p/go-libp2p-peerstore v0.1.0 + github.com/libp2p/go-libp2p-secio v0.1.0 + github.com/libp2p/go-libp2p-swarm v0.1.0 + github.com/libp2p/go-libp2p-testing v0.0.4 + github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 + github.com/libp2p/go-libp2p-yamux v0.2.1 + github.com/libp2p/go-maddr-filter v0.0.4 + github.com/libp2p/go-stream-muxer-multistream v0.2.0 + github.com/libp2p/go-tcp-transport v0.1.0 + github.com/libp2p/go-ws-transport v0.1.0 + github.com/miekg/dns v1.1.12 // indirect + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-dns v0.0.2 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/multiformats/go-multistream v0.1.0 + github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30 +) diff --git a/vendor/github.com/libp2p/go-libp2p/go.sum b/vendor/github.com/libp2p/go-libp2p/go.sum new file mode 100644 index 00000000..47c9026c --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/go.sum @@ -0,0 +1,264 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0 h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0 h1:TSPZ5cMMz/wdoYsye/wU1TE4G3LDGMoeEN0xgnCKU/I= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12 h1:WMhc1ik4LNkTg8U9l3hI1LvxKmIL+f1+WV/SZtCbDDA= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30 h1:nMCC9Pwz1pxfC1Y6mYncdk+kq8d5aLx0Q+/gyZGE44M= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-libp2p/libp2p.go b/vendor/github.com/libp2p/go-libp2p/libp2p.go new file mode 100644 index 00000000..32fddbdb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/libp2p.go @@ -0,0 +1,72 @@ +package libp2p + +import ( + "context" + + config "github.com/libp2p/go-libp2p/config" + + "github.com/libp2p/go-libp2p-core/host" +) + +// Config describes a set of settings for a libp2p node +type Config = config.Config + +// Option is a libp2p config option that can be given to the libp2p constructor +// (`libp2p.New`). +type Option = config.Option + +// ChainOptions chains multiple options into a single option. +func ChainOptions(opts ...Option) Option { + return func(cfg *Config) error { + for _, opt := range opts { + if opt == nil { + continue + } + if err := opt(cfg); err != nil { + return err + } + } + return nil + } +} + +// New constructs a new libp2p node with the given options, falling back on +// reasonable defaults. The defaults are: +// +// - If no transport and listen addresses are provided, the node listens to +// the multiaddresses "/ip4/0.0.0.0/tcp/0" and "/ip6/::/tcp/0"; +// +// - If no transport options are provided, the node uses TCP and websocket +// transport protocols; +// +// - If no multiplexer configuration is provided, the node is configured by +// default to use the "yamux/1.0.0" and "mplux/6.7.0" stream connection +// multiplexers; +// +// - If no security transport is provided, the host uses the go-libp2p's secio +// encrypted transport to encrypt all traffic; +// +// - If no peer identity is provided, it generates a random RSA 2048 key-par +// and derives a new identity from it; +// +// - If no peerstore is provided, the host is initialized with an empty +// peerstore. +// +// Canceling the passed context will stop the returned libp2p node. +func New(ctx context.Context, opts ...Option) (host.Host, error) { + return NewWithoutDefaults(ctx, append(opts, FallbackDefaults)...) +} + +// NewWithoutDefaults constructs a new libp2p node with the given options but +// *without* falling back on reasonable defaults. +// +// Warning: This function should not be considered a stable interface. We may +// choose to add required services at any time and, by using this function, you +// opt-out of any defaults we may provide. +func NewWithoutDefaults(ctx context.Context, opts ...Option) (host.Host, error) { + var cfg Config + if err := cfg.Apply(opts...); err != nil { + return nil, err + } + return cfg.NewNode(ctx) +} diff --git a/vendor/github.com/libp2p/go-libp2p/options.go b/vendor/github.com/libp2p/go-libp2p/options.go new file mode 100644 index 00000000..6d310f1a --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/options.go @@ -0,0 +1,321 @@ +package libp2p + +// This file contains all libp2p configuration options (except the defaults, +// those are in defaults.go) + +import ( + "fmt" + "net" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/pnet" + + circuit "github.com/libp2p/go-libp2p-circuit" + config "github.com/libp2p/go-libp2p/config" + bhost "github.com/libp2p/go-libp2p/p2p/host/basic" + + filter "github.com/libp2p/go-maddr-filter" + ma "github.com/multiformats/go-multiaddr" +) + +// ListenAddrStrings configures libp2p to listen on the given (unparsed) +// addresses. +func ListenAddrStrings(s ...string) Option { + return func(cfg *Config) error { + for _, addrstr := range s { + a, err := ma.NewMultiaddr(addrstr) + if err != nil { + return err + } + cfg.ListenAddrs = append(cfg.ListenAddrs, a) + } + return nil + } +} + +// ListenAddrs configures libp2p to listen on the given addresses. +func ListenAddrs(addrs ...ma.Multiaddr) Option { + return func(cfg *Config) error { + cfg.ListenAddrs = append(cfg.ListenAddrs, addrs...) + return nil + } +} + +// Security configures libp2p to use the given security transport (or transport +// constructor). +// +// Name is the protocol name. +// +// The transport can be a constructed security.Transport or a function taking +// any subset of this libp2p node's: +// * Public key +// * Private key +// * Peer ID +// * Host +// * Network +// * Peerstore +func Security(name string, tpt interface{}) Option { + stpt, err := config.SecurityConstructor(tpt) + err = traceError(err, 1) + return func(cfg *Config) error { + if err != nil { + return err + } + if cfg.Insecure { + return fmt.Errorf("cannot use security transports with an insecure libp2p configuration") + } + cfg.SecurityTransports = append(cfg.SecurityTransports, config.MsSecC{SecC: stpt, ID: name}) + return nil + } +} + +// NoSecurity is an option that completely disables all transport security. +// It's incompatible with all other transport security protocols. +var NoSecurity Option = func(cfg *Config) error { + if len(cfg.SecurityTransports) > 0 { + return fmt.Errorf("cannot use security transports with an insecure libp2p configuration") + } + cfg.Insecure = true + return nil +} + +// Muxer configures libp2p to use the given stream multiplexer (or stream +// multiplexer constructor). +// +// Name is the protocol name. +// +// The transport can be a constructed mux.Transport or a function taking any +// subset of this libp2p node's: +// * Peer ID +// * Host +// * Network +// * Peerstore +func Muxer(name string, tpt interface{}) Option { + mtpt, err := config.MuxerConstructor(tpt) + err = traceError(err, 1) + return func(cfg *Config) error { + if err != nil { + return err + } + cfg.Muxers = append(cfg.Muxers, config.MsMuxC{MuxC: mtpt, ID: name}) + return nil + } +} + +// Transport configures libp2p to use the given transport (or transport +// constructor). +// +// The transport can be a constructed transport.Transport or a function taking +// any subset of this libp2p node's: +// * Transport Upgrader (*tptu.Upgrader) +// * Host +// * Stream muxer (muxer.Transport) +// * Security transport (security.Transport) +// * Private network protector (pnet.Protector) +// * Peer ID +// * Private Key +// * Public Key +// * Address filter (filter.Filter) +// * Peerstore +func Transport(tpt interface{}) Option { + tptc, err := config.TransportConstructor(tpt) + err = traceError(err, 1) + return func(cfg *Config) error { + if err != nil { + return err + } + cfg.Transports = append(cfg.Transports, tptc) + return nil + } +} + +// Peerstore configures libp2p to use the given peerstore. +func Peerstore(ps peerstore.Peerstore) Option { + return func(cfg *Config) error { + if cfg.Peerstore != nil { + return fmt.Errorf("cannot specify multiple peerstore options") + } + + cfg.Peerstore = ps + return nil + } +} + +// PrivateNetwork configures libp2p to use the given private network protector. +func PrivateNetwork(prot pnet.Protector) Option { + return func(cfg *Config) error { + if cfg.Protector != nil { + return fmt.Errorf("cannot specify multiple private network options") + } + + cfg.Protector = prot + return nil + } +} + +// BandwidthReporter configures libp2p to use the given bandwidth reporter. +func BandwidthReporter(rep metrics.Reporter) Option { + return func(cfg *Config) error { + if cfg.Reporter != nil { + return fmt.Errorf("cannot specify multiple bandwidth reporter options") + } + + cfg.Reporter = rep + return nil + } +} + +// Identity configures libp2p to use the given private key to identify itself. +func Identity(sk crypto.PrivKey) Option { + return func(cfg *Config) error { + if cfg.PeerKey != nil { + return fmt.Errorf("cannot specify multiple identities") + } + + cfg.PeerKey = sk + return nil + } +} + +// ConnectionManager configures libp2p to use the given connection manager. +func ConnectionManager(connman connmgr.ConnManager) Option { + return func(cfg *Config) error { + if cfg.ConnManager != nil { + return fmt.Errorf("cannot specify multiple connection managers") + } + cfg.ConnManager = connman + return nil + } +} + +// AddrsFactory configures libp2p to use the given address factory. +func AddrsFactory(factory config.AddrsFactory) Option { + return func(cfg *Config) error { + if cfg.AddrsFactory != nil { + return fmt.Errorf("cannot specify multiple address factories") + } + cfg.AddrsFactory = factory + return nil + } +} + +// EnableRelay configures libp2p to enable the relay transport with +// configuration options. By default, this option only configures libp2p to +// accept inbound connections from relays and make outbound connections +// _through_ relays when requested by the remote peer. (default: enabled) +// +// To _act_ as a relay, pass the circuit.OptHop option. +func EnableRelay(options ...circuit.RelayOpt) Option { + return func(cfg *Config) error { + cfg.RelayCustom = true + cfg.Relay = true + cfg.RelayOpts = options + return nil + } +} + +// DisableRelay configures libp2p to disable the relay transport. +func DisableRelay() Option { + return func(cfg *Config) error { + cfg.RelayCustom = true + cfg.Relay = false + return nil + } +} + +// EnableAutoRelay configures libp2p to enable the AutoRelay subsystem. It is an +// error to enable AutoRelay without enabling relay (enabled by default) and +// routing (not enabled by default). +// +// This subsystem performs two functions: +// +// 1. When this libp2p node is configured to act as a relay "hop" +// (circuit.OptHop is passed to EnableRelay), this node will advertise itself +// as a public relay using the provided routing system. +// 2. When this libp2p node is _not_ configured as a relay "hop", it will +// automatically detect if it is unreachable (e.g., behind a NAT). If so, it will +// find, configure, and announce a set of public relays. +func EnableAutoRelay() Option { + return func(cfg *Config) error { + cfg.EnableAutoRelay = true + return nil + } +} + +// FilterAddresses configures libp2p to never dial nor accept connections from +// the given addresses. +func FilterAddresses(addrs ...*net.IPNet) Option { + return func(cfg *Config) error { + if cfg.Filters == nil { + cfg.Filters = filter.NewFilters() + } + for _, addr := range addrs { + cfg.Filters.AddDialFilter(addr) + } + return nil + } +} + +// NATPortMap configures libp2p to use the default NATManager. The default +// NATManager will attempt to open a port in your network's firewall using UPnP. +func NATPortMap() Option { + return NATManager(bhost.NewNATManager) +} + +// NATManager will configure libp2p to use the requested NATManager. This +// function should be passed a NATManager *constructor* that takes a libp2p Network. +func NATManager(nm config.NATManagerC) Option { + return func(cfg *Config) error { + if cfg.NATManager != nil { + return fmt.Errorf("cannot specify multiple NATManagers") + } + cfg.NATManager = nm + return nil + } +} + +// Ping will configure libp2p to support the ping service; enable by default. +func Ping(enable bool) Option { + return func(cfg *Config) error { + cfg.DisablePing = !enable + return nil + } +} + +// Routing will configure libp2p to use routing. +func Routing(rt config.RoutingC) Option { + return func(cfg *Config) error { + if cfg.Routing != nil { + return fmt.Errorf("cannot specify multiple routing options") + } + cfg.Routing = rt + return nil + } +} + +// NoListenAddrs will configure libp2p to not listen by default. +// +// This will both clear any configured listen addrs and prevent libp2p from +// applying the default listen address option. It also disables relay, unless the +// user explicitly specifies with an option, as the transport creates an implicit +// listen address that would make the node dialable through any relay it was connected to. +var NoListenAddrs = func(cfg *Config) error { + cfg.ListenAddrs = []ma.Multiaddr{} + if !cfg.RelayCustom { + cfg.RelayCustom = true + cfg.Relay = false + } + return nil +} + +// NoTransports will configure libp2p to not enable any transports. +// +// This will both clear any configured transports (specified in prior libp2p +// options) and prevent libp2p from applying the default transports. +var NoTransports = func(cfg *Config) error { + cfg.Transports = []config.TptC{} + return nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/discovery/mdns.go b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/mdns.go new file mode 100644 index 00000000..3476e6eb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/mdns.go @@ -0,0 +1,207 @@ +package discovery + +import ( + "context" + "errors" + "io" + "net" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" + "github.com/whyrusleeping/mdns" +) + +func init() { + // don't let mdns use logging... + mdns.DisableLogging = true +} + +var log = logging.Logger("mdns") + +const ServiceTag = "_ipfs-discovery._udp" + +type Service interface { + io.Closer + RegisterNotifee(Notifee) + UnregisterNotifee(Notifee) +} + +type Notifee interface { + HandlePeerFound(peer.AddrInfo) +} + +type mdnsService struct { + server *mdns.Server + service *mdns.MDNSService + host host.Host + tag string + + lk sync.Mutex + notifees []Notifee + interval time.Duration +} + +func getDialableListenAddrs(ph host.Host) ([]*net.TCPAddr, error) { + var out []*net.TCPAddr + for _, addr := range ph.Addrs() { + na, err := manet.ToNetAddr(addr) + if err != nil { + continue + } + tcp, ok := na.(*net.TCPAddr) + if ok { + out = append(out, tcp) + } + } + if len(out) == 0 { + return nil, errors.New("failed to find good external addr from peerhost") + } + return out, nil +} + +func NewMdnsService(ctx context.Context, peerhost host.Host, interval time.Duration, serviceTag string) (Service, error) { + + var ipaddrs []net.IP + port := 4001 + + addrs, err := getDialableListenAddrs(peerhost) + if err != nil { + log.Warning(err) + } else { + port = addrs[0].Port + for _, a := range addrs { + ipaddrs = append(ipaddrs, a.IP) + } + } + + myid := peerhost.ID().Pretty() + + info := []string{myid} + if serviceTag == "" { + serviceTag = ServiceTag + } + service, err := mdns.NewMDNSService(myid, serviceTag, "", "", port, ipaddrs, info) + if err != nil { + return nil, err + } + + // Create the mDNS server, defer shutdown + server, err := mdns.NewServer(&mdns.Config{Zone: service}) + if err != nil { + return nil, err + } + + s := &mdnsService{ + server: server, + service: service, + host: peerhost, + interval: interval, + tag: serviceTag, + } + + go s.pollForEntries(ctx) + + return s, nil +} + +func (m *mdnsService) Close() error { + return m.server.Shutdown() +} + +func (m *mdnsService) pollForEntries(ctx context.Context) { + + ticker := time.NewTicker(m.interval) + for { + //execute mdns query right away at method call and then with every tick + entriesCh := make(chan *mdns.ServiceEntry, 16) + go func() { + for entry := range entriesCh { + m.handleEntry(entry) + } + }() + + log.Debug("starting mdns query") + qp := &mdns.QueryParam{ + Domain: "local", + Entries: entriesCh, + Service: m.tag, + Timeout: time.Second * 5, + } + + err := mdns.Query(qp) + if err != nil { + log.Error("mdns lookup error: ", err) + } + close(entriesCh) + log.Debug("mdns query complete") + + select { + case <-ticker.C: + continue + case <-ctx.Done(): + log.Debug("mdns service halting") + return + } + } +} + +func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) { + log.Debugf("Handling MDNS entry: %s:%d %s", e.AddrV4, e.Port, e.Info) + mpeer, err := peer.IDB58Decode(e.Info) + if err != nil { + log.Warning("Error parsing peer ID from mdns entry: ", err) + return + } + + if mpeer == m.host.ID() { + log.Debug("got our own mdns entry, skipping") + return + } + + maddr, err := manet.FromNetAddr(&net.TCPAddr{ + IP: e.AddrV4, + Port: e.Port, + }) + if err != nil { + log.Warning("Error parsing multiaddr from mdns entry: ", err) + return + } + + pi := peer.AddrInfo{ + ID: mpeer, + Addrs: []ma.Multiaddr{maddr}, + } + + m.lk.Lock() + for _, n := range m.notifees { + go n.HandlePeerFound(pi) + } + m.lk.Unlock() +} + +func (m *mdnsService) RegisterNotifee(n Notifee) { + m.lk.Lock() + m.notifees = append(m.notifees, n) + m.lk.Unlock() +} + +func (m *mdnsService) UnregisterNotifee(n Notifee) { + m.lk.Lock() + found := -1 + for i, notif := range m.notifees { + if notif == n { + found = i + break + } + } + if found != -1 { + m.notifees = append(m.notifees[:found], m.notifees[found+1:]...) + } + m.lk.Unlock() +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go new file mode 100644 index 00000000..b1d8cbcd --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go @@ -0,0 +1,743 @@ +package basichost + +import ( + "context" + "io" + "net" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/protocol" + + logging "github.com/ipfs/go-log" + goprocess "github.com/jbenet/goprocess" + goprocessctx "github.com/jbenet/goprocess/context" + + inat "github.com/libp2p/go-libp2p-nat" + + identify "github.com/libp2p/go-libp2p/p2p/protocol/identify" + ping "github.com/libp2p/go-libp2p/p2p/protocol/ping" + ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" + manet "github.com/multiformats/go-multiaddr-net" + msmux "github.com/multiformats/go-multistream" +) + +var log = logging.Logger("basichost") + +var ( + // DefaultNegotiationTimeout is the default value for HostOpts.NegotiationTimeout. + DefaultNegotiationTimeout = time.Second * 60 + + // DefaultAddrsFactory is the default value for HostOpts.AddrsFactory. + DefaultAddrsFactory = func(addrs []ma.Multiaddr) []ma.Multiaddr { return addrs } +) + +// AddrsFactory functions can be passed to New in order to override +// addresses returned by Addrs. +type AddrsFactory func([]ma.Multiaddr) []ma.Multiaddr + +// Option is a type used to pass in options to the host. +// +// Deprecated in favor of HostOpts and NewHost. +type Option int + +// NATPortMap makes the host attempt to open port-mapping in NAT devices +// for all its listeners. Pass in this option in the constructor to +// asynchronously a) find a gateway, b) open port mappings, c) republish +// port mappings periodically. The NATed addresses are included in the +// Host's Addrs() list. +// +// This option is deprecated in favor of HostOpts and NewHost. +const NATPortMap Option = iota + +// BasicHost is the basic implementation of the host.Host interface. This +// particular host implementation: +// * uses a protocol muxer to mux per-protocol streams +// * uses an identity service to send + receive node information +// * uses a nat service to establish NAT port mappings +type BasicHost struct { + network network.Network + mux *msmux.MultistreamMuxer + ids *identify.IDService + pings *ping.PingService + natmgr NATManager + maResolver *madns.Resolver + cmgr connmgr.ConnManager + + AddrsFactory AddrsFactory + + negtimeout time.Duration + + proc goprocess.Process + + ctx context.Context + cancel func() + mx sync.Mutex + lastAddrs []ma.Multiaddr +} + +var _ host.Host = (*BasicHost)(nil) + +// HostOpts holds options that can be passed to NewHost in order to +// customize construction of the *BasicHost. +type HostOpts struct { + + // MultistreamMuxer is essential for the *BasicHost and will use a sensible default value if omitted. + MultistreamMuxer *msmux.MultistreamMuxer + + // NegotiationTimeout determines the read and write timeouts on streams. + // If 0 or omitted, it will use DefaultNegotiationTimeout. + // If below 0, timeouts on streams will be deactivated. + NegotiationTimeout time.Duration + + // IdentifyService holds an implementation of the /ipfs/id/ protocol. + // If omitted, a new *identify.IDService will be used. + IdentifyService *identify.IDService + + // AddrsFactory holds a function which can be used to override or filter the result of Addrs. + // If omitted, there's no override or filtering, and the results of Addrs and AllAddrs are the same. + AddrsFactory AddrsFactory + + // MultiaddrResolves holds the go-multiaddr-dns.Resolver used for resolving + // /dns4, /dns6, and /dnsaddr addresses before trying to connect to a peer. + MultiaddrResolver *madns.Resolver + + // NATManager takes care of setting NAT port mappings, and discovering external addresses. + // If omitted, this will simply be disabled. + NATManager func(network.Network) NATManager + + // ConnManager is a libp2p connection manager + ConnManager connmgr.ConnManager + + // EnablePing indicates whether to instantiate the ping service + EnablePing bool +} + +// NewHost constructs a new *BasicHost and activates it by attaching its stream and connection handlers to the given inet.Network. +func NewHost(ctx context.Context, net network.Network, opts *HostOpts) (*BasicHost, error) { + bgctx, cancel := context.WithCancel(ctx) + + h := &BasicHost{ + network: net, + mux: msmux.NewMultistreamMuxer(), + negtimeout: DefaultNegotiationTimeout, + AddrsFactory: DefaultAddrsFactory, + maResolver: madns.DefaultResolver, + ctx: bgctx, + cancel: cancel, + } + + h.proc = goprocessctx.WithContextAndTeardown(ctx, func() error { + if h.natmgr != nil { + h.natmgr.Close() + } + return h.Network().Close() + }) + + if opts.MultistreamMuxer != nil { + h.mux = opts.MultistreamMuxer + } + + if opts.IdentifyService != nil { + h.ids = opts.IdentifyService + } else { + // we can't set this as a default above because it depends on the *BasicHost. + h.ids = identify.NewIDService(bgctx, h) + } + + if uint64(opts.NegotiationTimeout) != 0 { + h.negtimeout = opts.NegotiationTimeout + } + + if opts.AddrsFactory != nil { + h.AddrsFactory = opts.AddrsFactory + } + + if opts.NATManager != nil { + h.natmgr = opts.NATManager(net) + } + + if opts.MultiaddrResolver != nil { + h.maResolver = opts.MultiaddrResolver + } + + if opts.ConnManager == nil { + h.cmgr = &connmgr.NullConnMgr{} + } else { + h.cmgr = opts.ConnManager + net.Notify(h.cmgr.Notifee()) + } + + if opts.EnablePing { + h.pings = ping.NewPingService(h) + } + + net.SetConnHandler(h.newConnHandler) + net.SetStreamHandler(h.newStreamHandler) + + return h, nil +} + +// New constructs and sets up a new *BasicHost with given Network and options. +// The following options can be passed: +// * NATPortMap +// * AddrsFactory +// * connmgr.ConnManager +// * madns.Resolver +// +// This function is deprecated in favor of NewHost and HostOpts. +func New(net network.Network, opts ...interface{}) *BasicHost { + hostopts := &HostOpts{} + + for _, o := range opts { + switch o := o.(type) { + case Option: + switch o { + case NATPortMap: + hostopts.NATManager = NewNATManager + } + case AddrsFactory: + hostopts.AddrsFactory = AddrsFactory(o) + case connmgr.ConnManager: + hostopts.ConnManager = o + case *madns.Resolver: + hostopts.MultiaddrResolver = o + } + } + + h, err := NewHost(context.Background(), net, hostopts) + if err != nil { + // this cannot happen with legacy options + // plus we want to keep the (deprecated) legacy interface unchanged + panic(err) + } + + return h +} + +// Start starts background tasks in the host +func (h *BasicHost) Start() { + go h.background() +} + +// newConnHandler is the remote-opened conn handler for inet.Network +func (h *BasicHost) newConnHandler(c network.Conn) { + // Clear protocols on connecting to new peer to avoid issues caused + // by misremembering protocols between reconnects + h.Peerstore().SetProtocols(c.RemotePeer()) + h.ids.IdentifyConn(c) +} + +// newStreamHandler is the remote-opened stream handler for network.Network +// TODO: this feels a bit wonky +func (h *BasicHost) newStreamHandler(s network.Stream) { + before := time.Now() + + if h.negtimeout > 0 { + if err := s.SetDeadline(time.Now().Add(h.negtimeout)); err != nil { + log.Error("setting stream deadline: ", err) + s.Reset() + return + } + } + + lzc, protoID, handle, err := h.Mux().NegotiateLazy(s) + took := time.Now().Sub(before) + if err != nil { + if err == io.EOF { + logf := log.Debugf + if took > time.Second*10 { + logf = log.Warningf + } + logf("protocol EOF: %s (took %s)", s.Conn().RemotePeer(), took) + } else { + log.Debugf("protocol mux failed: %s (took %s)", err, took) + } + s.Reset() + return + } + + s = &streamWrapper{ + Stream: s, + rw: lzc, + } + + if h.negtimeout > 0 { + if err := s.SetDeadline(time.Time{}); err != nil { + log.Error("resetting stream deadline: ", err) + s.Reset() + return + } + } + + s.SetProtocol(protocol.ID(protoID)) + log.Debugf("protocol negotiation took %s", took) + + go handle(protoID, s) +} + +// PushIdentify pushes an identify update through the identify push protocol +// Warning: this interface is unstable and may disappear in the future. +func (h *BasicHost) PushIdentify() { + push := false + + h.mx.Lock() + addrs := h.Addrs() + if !sameAddrs(addrs, h.lastAddrs) { + push = true + h.lastAddrs = addrs + } + h.mx.Unlock() + + if push { + h.ids.Push() + } +} + +func (h *BasicHost) background() { + // periodically schedules an IdentifyPush to update our peers for changes + // in our address set (if needed) + ticker := time.NewTicker(1 * time.Minute) + defer ticker.Stop() + + // initialize lastAddrs + h.mx.Lock() + if h.lastAddrs == nil { + h.lastAddrs = h.Addrs() + } + h.mx.Unlock() + + for { + select { + case <-ticker.C: + h.PushIdentify() + + case <-h.ctx.Done(): + return + } + } +} + +func sameAddrs(a, b []ma.Multiaddr) bool { + if len(a) != len(b) { + return false + } + + bmap := make(map[string]struct{}, len(b)) + for _, addr := range b { + bmap[string(addr.Bytes())] = struct{}{} + } + + for _, addr := range a { + _, ok := bmap[string(addr.Bytes())] + if !ok { + return false + } + } + + return true +} + +// ID returns the (local) peer.ID associated with this Host +func (h *BasicHost) ID() peer.ID { + return h.Network().LocalPeer() +} + +// Peerstore returns the Host's repository of Peer Addresses and Keys. +func (h *BasicHost) Peerstore() peerstore.Peerstore { + return h.Network().Peerstore() +} + +// Network returns the Network interface of the Host +func (h *BasicHost) Network() network.Network { + return h.network +} + +// Mux returns the Mux multiplexing incoming streams to protocol handlers +func (h *BasicHost) Mux() protocol.Switch { + return h.mux +} + +// IDService returns +func (h *BasicHost) IDService() *identify.IDService { + return h.ids +} + +// SetStreamHandler sets the protocol handler on the Host's Mux. +// This is equivalent to: +// host.Mux().SetHandler(proto, handler) +// (Threadsafe) +func (h *BasicHost) SetStreamHandler(pid protocol.ID, handler network.StreamHandler) { + h.Mux().AddHandler(string(pid), func(p string, rwc io.ReadWriteCloser) error { + is := rwc.(network.Stream) + is.SetProtocol(protocol.ID(p)) + handler(is) + return nil + }) +} + +// SetStreamHandlerMatch sets the protocol handler on the Host's Mux +// using a matching function to do protocol comparisons +func (h *BasicHost) SetStreamHandlerMatch(pid protocol.ID, m func(string) bool, handler network.StreamHandler) { + h.Mux().AddHandlerWithFunc(string(pid), m, func(p string, rwc io.ReadWriteCloser) error { + is := rwc.(network.Stream) + is.SetProtocol(protocol.ID(p)) + handler(is) + return nil + }) +} + +// RemoveStreamHandler returns .. +func (h *BasicHost) RemoveStreamHandler(pid protocol.ID) { + h.Mux().RemoveHandler(string(pid)) +} + +// NewStream opens a new stream to given peer p, and writes a p2p/protocol +// header with given protocol.ID. If there is no connection to p, attempts +// to create one. If ProtocolID is "", writes no header. +// (Threadsafe) +func (h *BasicHost) NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error) { + pref, err := h.preferredProtocol(p, pids) + if err != nil { + return nil, err + } + + if pref != "" { + return h.newStream(ctx, p, pref) + } + + var protoStrs []string + for _, pid := range pids { + protoStrs = append(protoStrs, string(pid)) + } + + s, err := h.Network().NewStream(ctx, p) + if err != nil { + return nil, err + } + + selected, err := msmux.SelectOneOf(protoStrs, s) + if err != nil { + s.Reset() + return nil, err + } + selpid := protocol.ID(selected) + s.SetProtocol(selpid) + h.Peerstore().AddProtocols(p, selected) + + return s, nil +} + +func pidsToStrings(pids []protocol.ID) []string { + out := make([]string, len(pids)) + for i, p := range pids { + out[i] = string(p) + } + return out +} + +func (h *BasicHost) preferredProtocol(p peer.ID, pids []protocol.ID) (protocol.ID, error) { + pidstrs := pidsToStrings(pids) + supported, err := h.Peerstore().SupportsProtocols(p, pidstrs...) + if err != nil { + return "", err + } + + var out protocol.ID + if len(supported) > 0 { + out = protocol.ID(supported[0]) + } + return out, nil +} + +func (h *BasicHost) newStream(ctx context.Context, p peer.ID, pid protocol.ID) (network.Stream, error) { + s, err := h.Network().NewStream(ctx, p) + if err != nil { + return nil, err + } + + s.SetProtocol(pid) + + lzcon := msmux.NewMSSelect(s, string(pid)) + return &streamWrapper{ + Stream: s, + rw: lzcon, + }, nil +} + +// Connect ensures there is a connection between this host and the peer with +// given peer.ID. If there is not an active connection, Connect will issue a +// h.Network.Dial, and block until a connection is open, or an error is returned. +// Connect will absorb the addresses in pi into its internal peerstore. +// It will also resolve any /dns4, /dns6, and /dnsaddr addresses. +func (h *BasicHost) Connect(ctx context.Context, pi peer.AddrInfo) error { + // absorb addresses into peerstore + h.Peerstore().AddAddrs(pi.ID, pi.Addrs, peerstore.TempAddrTTL) + + if h.Network().Connectedness(pi.ID) == network.Connected { + return nil + } + + resolved, err := h.resolveAddrs(ctx, h.Peerstore().PeerInfo(pi.ID)) + if err != nil { + return err + } + h.Peerstore().AddAddrs(pi.ID, resolved, peerstore.TempAddrTTL) + + return h.dialPeer(ctx, pi.ID) +} + +func (h *BasicHost) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multiaddr, error) { + proto := ma.ProtocolWithCode(ma.P_P2P).Name + p2paddr, err := ma.NewMultiaddr("/" + proto + "/" + pi.ID.Pretty()) + if err != nil { + return nil, err + } + + var addrs []ma.Multiaddr + for _, addr := range pi.Addrs { + addrs = append(addrs, addr) + if !madns.Matches(addr) { + continue + } + + reqaddr := addr.Encapsulate(p2paddr) + resaddrs, err := h.maResolver.Resolve(ctx, reqaddr) + if err != nil { + log.Infof("error resolving %s: %s", reqaddr, err) + } + for _, res := range resaddrs { + pi, err := peer.AddrInfoFromP2pAddr(res) + if err != nil { + log.Infof("error parsing %s: %s", res, err) + } + addrs = append(addrs, pi.Addrs...) + } + } + + return addrs, nil +} + +// dialPeer opens a connection to peer, and makes sure to identify +// the connection once it has been opened. +func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error { + log.Debugf("host %s dialing %s", h.ID(), p) + c, err := h.Network().DialPeer(ctx, p) + if err != nil { + return err + } + + // Clear protocols on connecting to new peer to avoid issues caused + // by misremembering protocols between reconnects + h.Peerstore().SetProtocols(p) + + // identify the connection before returning. + done := make(chan struct{}) + go func() { + h.ids.IdentifyConn(c) + close(done) + }() + + // respect don contexteone + select { + case <-done: + case <-ctx.Done(): + return ctx.Err() + } + + log.Debugf("host %s finished dialing %s", h.ID(), p) + return nil +} + +func (h *BasicHost) ConnManager() connmgr.ConnManager { + return h.cmgr +} + +// Addrs returns listening addresses that are safe to announce to the network. +// The output is the same as AllAddrs, but processed by AddrsFactory. +func (h *BasicHost) Addrs() []ma.Multiaddr { + return h.AddrsFactory(h.AllAddrs()) +} + +// mergeAddrs merges input address lists, leave only unique addresses +func dedupAddrs(addrs []ma.Multiaddr) (uniqueAddrs []ma.Multiaddr) { + exists := make(map[string]bool) + for _, addr := range addrs { + k := string(addr.Bytes()) + if exists[k] { + continue + } + exists[k] = true + uniqueAddrs = append(uniqueAddrs, addr) + } + return uniqueAddrs +} + +// AllAddrs returns all the addresses of BasicHost at this moment in time. +// It's ok to not include addresses if they're not available to be used now. +func (h *BasicHost) AllAddrs() []ma.Multiaddr { + listenAddrs, err := h.Network().InterfaceListenAddresses() + if err != nil { + log.Debug("error retrieving network interface addrs") + } + var natMappings []inat.Mapping + + // natmgr is nil if we do not use nat option; + // h.natmgr.NAT() is nil if not ready, or no nat is available. + if h.natmgr != nil && h.natmgr.NAT() != nil { + natMappings = h.natmgr.NAT().Mappings() + } + + finalAddrs := listenAddrs + if len(natMappings) > 0 { + + // We have successfully mapped ports on our NAT. Use those + // instead of observed addresses (mostly). + + // First, generate a mapping table. + // protocol -> internal port -> external addr + ports := make(map[string]map[int]net.Addr) + for _, m := range natMappings { + addr, err := m.ExternalAddr() + if err != nil { + // mapping not ready yet. + continue + } + protoPorts, ok := ports[m.Protocol()] + if !ok { + protoPorts = make(map[int]net.Addr) + ports[m.Protocol()] = protoPorts + } + protoPorts[m.InternalPort()] = addr + } + + // Next, apply this mapping to our addresses. + for _, listen := range listenAddrs { + found := false + transport, rest := ma.SplitFunc(listen, func(c ma.Component) bool { + if found { + return true + } + switch c.Protocol().Code { + case ma.P_TCP, ma.P_UDP: + found = true + } + return false + }) + if !manet.IsThinWaist(transport) { + continue + } + + naddr, err := manet.ToNetAddr(transport) + if err != nil { + log.Error("error parsing net multiaddr %q: %s", transport, err) + continue + } + + var ( + ip net.IP + iport int + protocol string + ) + switch naddr := naddr.(type) { + case *net.TCPAddr: + ip = naddr.IP + iport = naddr.Port + protocol = "tcp" + case *net.UDPAddr: + ip = naddr.IP + iport = naddr.Port + protocol = "udp" + default: + continue + } + + if !ip.IsGlobalUnicast() { + // We only map global unicast ports. + continue + } + + mappedAddr, ok := ports[protocol][iport] + if !ok { + // Not mapped. + continue + } + + mappedMaddr, err := manet.FromNetAddr(mappedAddr) + if err != nil { + log.Errorf("mapped addr can't be turned into a multiaddr %q: %s", mappedAddr, err) + continue + } + + // Did the router give us a routable public addr? + if manet.IsPublicAddr(mappedMaddr) { + // Yes, use it. + extMaddr := mappedMaddr + if rest != nil { + extMaddr = ma.Join(extMaddr, rest) + } + + // Add in the mapped addr. + finalAddrs = append(finalAddrs, extMaddr) + continue + } + + // No. Ok, let's try our observed addresses. + + // Now, check if we have any observed addresses that + // differ from the one reported by the router. Routers + // don't always give the most accurate information. + observed := h.ids.ObservedAddrsFor(listen) + + if len(observed) == 0 { + continue + } + + // Drop the IP from the external maddr + _, extMaddrNoIP := ma.SplitFirst(mappedMaddr) + + for _, obsMaddr := range observed { + // Extract a public observed addr. + ip, _ := ma.SplitFirst(obsMaddr) + if ip == nil || !manet.IsPublicAddr(ip) { + continue + } + + finalAddrs = append(finalAddrs, ma.Join(ip, extMaddrNoIP)) + } + } + } else { + var observedAddrs []ma.Multiaddr + if h.ids != nil { + observedAddrs = h.ids.OwnObservedAddrs() + } + finalAddrs = append(finalAddrs, observedAddrs...) + } + return dedupAddrs(finalAddrs) +} + +// Close shuts down the Host's services (network, etc). +func (h *BasicHost) Close() error { + h.cancel() + h.cmgr.Close() + return h.proc.Close() +} + +type streamWrapper struct { + network.Stream + rw io.ReadWriter +} + +func (s *streamWrapper) Read(b []byte) (int, error) { + return s.rw.Read(b) +} + +func (s *streamWrapper) Write(b []byte) (int, error) { + return s.rw.Write(b) +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go new file mode 100644 index 00000000..c0bf96a8 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go @@ -0,0 +1,243 @@ +package basichost + +import ( + "net" + "strconv" + "sync" + + goprocess "github.com/jbenet/goprocess" + goprocessctx "github.com/jbenet/goprocess/context" + "github.com/libp2p/go-libp2p-core/network" + inat "github.com/libp2p/go-libp2p-nat" + ma "github.com/multiformats/go-multiaddr" +) + +// A simple interface to manage NAT devices. +type NATManager interface { + + // Get the NAT device managed by the NAT manager. + NAT() *inat.NAT + + // Receive a notification when the NAT device is ready for use. + Ready() <-chan struct{} + + // Close all resources associated with a NAT manager. + Close() error +} + +// Create a NAT manager. +func NewNATManager(net network.Network) NATManager { + return newNatManager(net) +} + +// natManager takes care of adding + removing port mappings to the nat. +// Initialized with the host if it has a NATPortMap option enabled. +// natManager receives signals from the network, and check on nat mappings: +// * natManager listens to the network and adds or closes port mappings +// as the network signals Listen() or ListenClose(). +// * closing the natManager closes the nat and its mappings. +type natManager struct { + net network.Network + natmu sync.RWMutex + nat *inat.NAT + + ready chan struct{} // closed once the nat is ready to process port mappings + + syncMu sync.Mutex + + proc goprocess.Process // natManager has a process + children. can be closed. +} + +func newNatManager(net network.Network) *natManager { + nmgr := &natManager{ + net: net, + ready: make(chan struct{}), + } + + nmgr.proc = goprocess.WithTeardown(func() error { + // on closing, unregister from network notifications. + net.StopNotify((*nmgrNetNotifiee)(nmgr)) + return nil + }) + + // discover the nat. + nmgr.discoverNAT() + return nmgr +} + +// Close closes the natManager, closing the underlying nat +// and unregistering from network events. +func (nmgr *natManager) Close() error { + return nmgr.proc.Close() +} + +// Ready returns a channel which will be closed when the NAT has been found +// and is ready to be used, or the search process is done. +func (nmgr *natManager) Ready() <-chan struct{} { + return nmgr.ready +} + +func (nmgr *natManager) discoverNAT() { + nmgr.proc.Go(func(worker goprocess.Process) { + // inat.DiscoverNAT blocks until the nat is found or a timeout + // is reached. we unfortunately cannot specify timeouts-- the + // library we're using just blocks. + // + // Note: on early shutdown, there may be a case where we're trying + // to close before DiscoverNAT() returns. Since we cant cancel it + // (library) we can choose to (1) drop the result and return early, + // or (2) wait until it times out to exit. For now we choose (2), + // to avoid leaking resources in a non-obvious way. the only case + // this affects is when the daemon is being started up and _immediately_ + // asked to close. other services are also starting up, so ok to wait. + + natInstance, err := inat.DiscoverNAT(goprocessctx.OnClosingContext(worker)) + if err != nil { + log.Info("DiscoverNAT error:", err) + close(nmgr.ready) + return + } + + nmgr.natmu.Lock() + nmgr.nat = natInstance + nmgr.natmu.Unlock() + close(nmgr.ready) + + // wire up the nat to close when nmgr closes. + // nmgr.proc is our parent, and waiting for us. + nmgr.proc.AddChild(nmgr.nat.Process()) + + // sign natManager up for network notifications + // we need to sign up here to avoid missing some notifs + // before the NAT has been found. + nmgr.net.Notify((*nmgrNetNotifiee)(nmgr)) + nmgr.sync() + }) +} + +// syncs the current NAT mappings, removing any outdated mappings and adding any +// new mappings. +func (nmgr *natManager) sync() { + nat := nmgr.NAT() + if nat == nil { + // Nothing to do. + return + } + + nmgr.proc.Go(func(_ goprocess.Process) { + nmgr.syncMu.Lock() + defer nmgr.syncMu.Unlock() + + ports := map[string]map[int]bool{ + "tcp": map[int]bool{}, + "udp": map[int]bool{}, + } + for _, maddr := range nmgr.net.ListenAddresses() { + // Strip the IP + maIP, rest := ma.SplitFirst(maddr) + if maIP == nil || rest == nil { + continue + } + + switch maIP.Protocol().Code { + case ma.P_IP6, ma.P_IP4: + default: + continue + } + + // Only bother if we're listening on a + // unicast/unspecified IP. + ip := net.IP(maIP.RawValue()) + if !(ip.IsGlobalUnicast() || ip.IsUnspecified()) { + continue + } + + // Extract the port/protocol + proto, _ := ma.SplitFirst(rest) + if proto == nil { + continue + } + + var protocol string + switch proto.Protocol().Code { + case ma.P_TCP: + protocol = "tcp" + case ma.P_UDP: + protocol = "udp" + default: + continue + } + + port, err := strconv.ParseUint(proto.Value(), 10, 16) + if err != nil { + // bug in multiaddr + panic(err) + } + ports[protocol][int(port)] = false + } + + var wg sync.WaitGroup + defer wg.Wait() + + // Close old mappings + for _, m := range nat.Mappings() { + mappedPort := m.InternalPort() + if _, ok := ports[m.Protocol()][mappedPort]; !ok { + // No longer need this mapping. + wg.Add(1) + go func(m inat.Mapping) { + defer wg.Done() + m.Close() + }(m) + } else { + // already mapped + ports[m.Protocol()][mappedPort] = true + } + } + + // Create new mappings. + for proto, pports := range ports { + for port, mapped := range pports { + if mapped { + continue + } + wg.Add(1) + go func(proto string, port int) { + defer wg.Done() + _, err := nat.NewMapping(proto, port) + if err != nil { + log.Errorf("failed to port-map %s port %d: %s", proto, port, err) + } + }(proto, port) + } + } + }) +} + +// NAT returns the natManager's nat object. this may be nil, if +// (a) the search process is still ongoing, or (b) the search process +// found no nat. Clients must check whether the return value is nil. +func (nmgr *natManager) NAT() *inat.NAT { + nmgr.natmu.Lock() + defer nmgr.natmu.Unlock() + return nmgr.nat +} + +type nmgrNetNotifiee natManager + +func (nn *nmgrNetNotifiee) natManager() *natManager { + return (*natManager)(nn) +} + +func (nn *nmgrNetNotifiee) Listen(n network.Network, addr ma.Multiaddr) { + nn.natManager().sync() +} + +func (nn *nmgrNetNotifiee) ListenClose(n network.Network, addr ma.Multiaddr) { + nn.natManager().sync() +} + +func (nn *nmgrNetNotifiee) Connected(network.Network, network.Conn) {} +func (nn *nmgrNetNotifiee) Disconnected(network.Network, network.Conn) {} +func (nn *nmgrNetNotifiee) OpenedStream(network.Network, network.Stream) {} +func (nn *nmgrNetNotifiee) ClosedStream(network.Network, network.Stream) {} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/addrsplosion.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/addrsplosion.go new file mode 100644 index 00000000..89965bca --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/addrsplosion.go @@ -0,0 +1,167 @@ +package relay + +import ( + "encoding/binary" + + circuit "github.com/libp2p/go-libp2p-circuit" + ma "github.com/multiformats/go-multiaddr" + dns "github.com/multiformats/go-multiaddr-dns" + manet "github.com/multiformats/go-multiaddr-net" +) + +// This function cleans up a relay's address set to remove private addresses and curtail +// addrsplosion. +func cleanupAddressSet(addrs []ma.Multiaddr) []ma.Multiaddr { + var public, private []ma.Multiaddr + + for _, a := range addrs { + if isRelayAddr(a) { + continue + } + + if manet.IsPublicAddr(a) || isDNSAddr(a) { + public = append(public, a) + continue + } + + // discard unroutable addrs + if manet.IsPrivateAddr(a) { + private = append(private, a) + } + } + + if !hasAddrsplosion(public) { + return public + } + + return sanitizeAddrsplodedSet(public, private) +} + +func isRelayAddr(a ma.Multiaddr) bool { + isRelay := false + + ma.ForEach(a, func(c ma.Component) bool { + switch c.Protocol().Code { + case circuit.P_CIRCUIT: + isRelay = true + return false + default: + return true + } + }) + + return isRelay +} + +func isDNSAddr(a ma.Multiaddr) bool { + if first, _ := ma.SplitFirst(a); first != nil { + switch first.Protocol().Code { + case dns.P_DNS4, dns.P_DNS6, dns.P_DNSADDR: + return true + } + } + return false +} + +// we have addrsplosion if for some protocol we advertise multiple ports on +// the same base address. +func hasAddrsplosion(addrs []ma.Multiaddr) bool { + aset := make(map[string]int) + + for _, a := range addrs { + key, port := addrKeyAndPort(a) + xport, ok := aset[key] + if ok && port != xport { + return true + } + aset[key] = port + } + + return false +} + +func addrKeyAndPort(a ma.Multiaddr) (string, int) { + var ( + key string + port int + ) + + ma.ForEach(a, func(c ma.Component) bool { + switch c.Protocol().Code { + case ma.P_TCP, ma.P_UDP: + port = int(binary.BigEndian.Uint16(c.RawValue())) + key += "/" + c.Protocol().Name + default: + val := c.Value() + if val == "" { + val = c.Protocol().Name + } + key += "/" + val + } + return true + }) + + return key, port +} + +// clean up addrsplosion +// the following heuristic is used: +// - for each base address/protocol combination, if there are multiple ports advertised then +// only accept the default port if present. +// - If the default port is not present, we check for non-standard ports by tracking +// private port bindings if present. +// - If there is no default or private port binding, then we can't infer the correct +// port and give up and return all addrs (for that base address) +func sanitizeAddrsplodedSet(public, private []ma.Multiaddr) []ma.Multiaddr { + type portAndAddr struct { + addr ma.Multiaddr + port int + } + + privports := make(map[int]struct{}) + pubaddrs := make(map[string][]portAndAddr) + + for _, a := range private { + _, port := addrKeyAndPort(a) + privports[port] = struct{}{} + } + + for _, a := range public { + key, port := addrKeyAndPort(a) + pubaddrs[key] = append(pubaddrs[key], portAndAddr{addr: a, port: port}) + } + + var result []ma.Multiaddr + for _, pas := range pubaddrs { + if len(pas) == 1 { + // it's not addrsploded + result = append(result, pas[0].addr) + continue + } + + haveAddr := false + for _, pa := range pas { + if _, ok := privports[pa.port]; ok { + // it matches a privately bound port, use it + result = append(result, pa.addr) + haveAddr = true + continue + } + + if pa.port == 4001 || pa.port == 4002 { + // it's a default port, use it + result = append(result, pa.addr) + haveAddr = true + } + } + + if !haveAddr { + // we weren't able to select a port; bite the bullet and use them all + for _, pa := range pas { + result = append(result, pa.addr) + } + } + } + + return result +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/autorelay.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/autorelay.go new file mode 100644 index 00000000..ac381ac6 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/autorelay.go @@ -0,0 +1,332 @@ +package relay + +import ( + "context" + "fmt" + "math/rand" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" + + autonat "github.com/libp2p/go-libp2p-autonat" + _ "github.com/libp2p/go-libp2p-circuit" + discovery "github.com/libp2p/go-libp2p-discovery" + basic "github.com/libp2p/go-libp2p/p2p/host/basic" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +const ( + RelayRendezvous = "/libp2p/relay" +) + +var ( + DesiredRelays = 3 + + BootDelay = 20 * time.Second +) + +// AutoRelay is a Host that uses relays for connectivity when a NAT is detected. +type AutoRelay struct { + host *basic.BasicHost + discover discovery.Discoverer + router routing.PeerRouting + autonat autonat.AutoNAT + addrsF basic.AddrsFactory + + disconnect chan struct{} + + mx sync.Mutex + relays map[peer.ID]struct{} + status autonat.NATStatus + + cachedAddrs []ma.Multiaddr + cachedAddrsExpiry time.Time +} + +func NewAutoRelay(ctx context.Context, bhost *basic.BasicHost, discover discovery.Discoverer, router routing.PeerRouting) *AutoRelay { + ar := &AutoRelay{ + host: bhost, + discover: discover, + router: router, + addrsF: bhost.AddrsFactory, + relays: make(map[peer.ID]struct{}), + disconnect: make(chan struct{}, 1), + status: autonat.NATStatusUnknown, + } + ar.autonat = autonat.NewAutoNAT(ctx, bhost, ar.baseAddrs) + bhost.AddrsFactory = ar.hostAddrs + bhost.Network().Notify(ar) + go ar.background(ctx) + return ar +} + +func (ar *AutoRelay) baseAddrs() []ma.Multiaddr { + return ar.addrsF(ar.host.AllAddrs()) +} + +func (ar *AutoRelay) hostAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { + return ar.relayAddrs(ar.addrsF(addrs)) +} + +func (ar *AutoRelay) background(ctx context.Context) { + select { + case <-time.After(autonat.AutoNATBootDelay + BootDelay): + case <-ctx.Done(): + return + } + + // when true, we need to identify push + push := false + + for { + wait := autonat.AutoNATRefreshInterval + switch ar.autonat.Status() { + case autonat.NATStatusUnknown: + ar.mx.Lock() + ar.status = autonat.NATStatusUnknown + ar.mx.Unlock() + wait = autonat.AutoNATRetryInterval + + case autonat.NATStatusPublic: + ar.mx.Lock() + if ar.status != autonat.NATStatusPublic { + push = true + } + ar.status = autonat.NATStatusPublic + ar.mx.Unlock() + + case autonat.NATStatusPrivate: + update := ar.findRelays(ctx) + ar.mx.Lock() + if update || ar.status != autonat.NATStatusPrivate { + push = true + } + ar.status = autonat.NATStatusPrivate + ar.mx.Unlock() + } + + if push { + ar.mx.Lock() + ar.cachedAddrs = nil + ar.mx.Unlock() + push = false + ar.host.PushIdentify() + } + + select { + case <-ar.disconnect: + push = true + case <-time.After(wait): + case <-ctx.Done(): + return + } + } +} + +func (ar *AutoRelay) findRelays(ctx context.Context) bool { + if ar.numRelays() >= DesiredRelays { + return false + } + + update := false + for retry := 0; retry < 5; retry++ { + if retry > 0 { + log.Debug("no relays connected; retrying in 30s") + select { + case <-time.After(30 * time.Second): + case <-ctx.Done(): + return update + } + } + + update = ar.findRelaysOnce(ctx) || update + if ar.numRelays() > 0 { + return update + } + } + return update +} + +func (ar *AutoRelay) findRelaysOnce(ctx context.Context) bool { + pis, err := ar.discoverRelays(ctx) + if err != nil { + log.Debugf("error discovering relays: %s", err) + return false + } + log.Debugf("discovered %d relays", len(pis)) + pis = ar.selectRelays(ctx, pis) + log.Debugf("selected %d relays", len(pis)) + + update := false + for _, pi := range pis { + update = ar.tryRelay(ctx, pi) || update + if ar.numRelays() >= DesiredRelays { + break + } + } + return update +} + +func (ar *AutoRelay) numRelays() int { + ar.mx.Lock() + defer ar.mx.Unlock() + return len(ar.relays) +} + +// usingRelay returns if we're currently using the given relay. +func (ar *AutoRelay) usingRelay(p peer.ID) bool { + ar.mx.Lock() + defer ar.mx.Unlock() + _, ok := ar.relays[p] + return ok +} + +// addRelay adds the given relay to our set of relays. +// returns true when we add a new relay +func (ar *AutoRelay) tryRelay(ctx context.Context, pi peer.AddrInfo) bool { + if ar.usingRelay(pi.ID) { + return false + } + + if !ar.connect(ctx, pi) { + return false + } + + ar.mx.Lock() + defer ar.mx.Unlock() + + // make sure we're still connected. + if ar.host.Network().Connectedness(pi.ID) != network.Connected { + return false + } + ar.relays[pi.ID] = struct{}{} + + return true +} + +func (ar *AutoRelay) connect(ctx context.Context, pi peer.AddrInfo) bool { + ctx, cancel := context.WithTimeout(ctx, 60*time.Second) + defer cancel() + + if len(pi.Addrs) == 0 { + var err error + pi, err = ar.router.FindPeer(ctx, pi.ID) + if err != nil { + log.Debugf("error finding relay peer %s: %s", pi.ID, err.Error()) + return false + } + } + + err := ar.host.Connect(ctx, pi) + if err != nil { + log.Debugf("error connecting to relay %s: %s", pi.ID, err.Error()) + return false + } + + // tag the connection as very important + ar.host.ConnManager().TagPeer(pi.ID, "relay", 42) + return true +} + +func (ar *AutoRelay) discoverRelays(ctx context.Context) ([]peer.AddrInfo, error) { + ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + return discovery.FindPeers(ctx, ar.discover, RelayRendezvous, discovery.Limit(1000)) +} + +func (ar *AutoRelay) selectRelays(ctx context.Context, pis []peer.AddrInfo) []peer.AddrInfo { + // TODO better relay selection strategy; this just selects random relays + // but we should probably use ping latency as the selection metric + + shuffleRelays(pis) + return pis +} + +// This function is computes the NATed relay addrs when our status is private: +// - The public addrs are removed from the address set. +// - The non-public addrs are included verbatim so that peers behind the same NAT/firewall +// can still dial us directly. +// - On top of those, we add the relay-specific addrs for the relays to which we are +// connected. For each non-private relay addr, we encapsulate the p2p-circuit addr +// through which we can be dialed. +func (ar *AutoRelay) relayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { + ar.mx.Lock() + defer ar.mx.Unlock() + + if ar.status != autonat.NATStatusPrivate { + return addrs + } + + if ar.cachedAddrs != nil && time.Now().Before(ar.cachedAddrsExpiry) { + return ar.cachedAddrs + } + + raddrs := make([]ma.Multiaddr, 0, 4*len(ar.relays)+4) + + // only keep private addrs from the original addr set + for _, addr := range addrs { + if manet.IsPrivateAddr(addr) { + raddrs = append(raddrs, addr) + } + } + + // add relay specific addrs to the list + for p := range ar.relays { + addrs := cleanupAddressSet(ar.host.Peerstore().Addrs(p)) + + circuit, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit", p.Pretty())) + if err != nil { + panic(err) + } + + for _, addr := range addrs { + pub := addr.Encapsulate(circuit) + raddrs = append(raddrs, pub) + } + } + + ar.cachedAddrs = raddrs + ar.cachedAddrsExpiry = time.Now().Add(30 * time.Second) + + return raddrs +} + +func shuffleRelays(pis []peer.AddrInfo) { + for i := range pis { + j := rand.Intn(i + 1) + pis[i], pis[j] = pis[j], pis[i] + } +} + +// Notifee +func (ar *AutoRelay) Listen(network.Network, ma.Multiaddr) {} +func (ar *AutoRelay) ListenClose(network.Network, ma.Multiaddr) {} +func (ar *AutoRelay) Connected(network.Network, network.Conn) {} + +func (ar *AutoRelay) Disconnected(net network.Network, c network.Conn) { + p := c.RemotePeer() + + ar.mx.Lock() + defer ar.mx.Unlock() + + if ar.host.Network().Connectedness(p) == network.Connected { + // We have a second connection. + return + } + + if _, ok := ar.relays[p]; ok { + delete(ar.relays, p) + select { + case ar.disconnect <- struct{}{}: + default: + } + } +} + +func (ar *AutoRelay) OpenedStream(network.Network, network.Stream) {} +func (ar *AutoRelay) ClosedStream(network.Network, network.Stream) {} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/doc.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/doc.go new file mode 100644 index 00000000..f7511ad9 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/doc.go @@ -0,0 +1,28 @@ +/* +The relay package contains the components necessary to implement the "autorelay" +feature. + +Warning: the internal interfaces are unstable. + +System Components: +- A discovery service to discover public relays. +- An AutoNAT client used to determine if the node is behind a NAT/firewall. +- One or more autonat services, instances of `AutoNATServices`. These are used + by the autonat client. +- One or more relays, instances of `RelayHost`. +- The AutoRelay service. This is the service that actually: + +AutoNATService: https://github.com/libp2p/go-libp2p-autonat-svc +AutoNAT: https://github.com/libp2p/go-libp2p-autonat + +How it works: +- `AutoNATService` instances are instantiated in the bootstrappers (or other + well known publicly reachable hosts) +- `AutoRelay`s are constructed with `libp2p.New(libp2p.Routing(makeDHT))` + They passively discover autonat service instances and test dialability of + their listen address set through them. When the presence of NAT is detected, + they discover relays through the DHT, connect to some of them and begin + advertising relay addresses. The new set of addresses is propagated to + connected peers through the `identify/push` protocol. +*/ +package relay diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/log.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/log.go new file mode 100644 index 00000000..eca0fa45 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/log.go @@ -0,0 +1,7 @@ +package relay + +import ( + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("autorelay") diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/relay.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/relay.go new file mode 100644 index 00000000..f72b74ff --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relay/relay.go @@ -0,0 +1,39 @@ +package relay + +import ( + "context" + "time" + + "github.com/libp2p/go-libp2p-discovery" + + ma "github.com/multiformats/go-multiaddr" +) + +var ( + // this is purposefully long to require some node stability before advertising as a relay + AdvertiseBootDelay = 15 * time.Minute + AdvertiseTTL = 30 * time.Minute +) + +// Advertise advertises this node as a libp2p relay. +func Advertise(ctx context.Context, advertise discovery.Advertiser) { + go func() { + select { + case <-time.After(AdvertiseBootDelay): + discovery.Advertise(ctx, advertise, RelayRendezvous, discovery.TTL(AdvertiseTTL)) + case <-ctx.Done(): + } + }() +} + +// Filter filters out all relay addresses. +func Filter(addrs []ma.Multiaddr) []ma.Multiaddr { + raddrs := make([]ma.Multiaddr, 0, len(addrs)) + for _, addr := range addrs { + if isRelayAddr(addr) { + continue + } + raddrs = append(raddrs, addr) + } + return raddrs +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go new file mode 100644 index 00000000..1282020b --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go @@ -0,0 +1,190 @@ +package routedhost + +import ( + "context" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/connmgr" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/protocol" + + logging "github.com/ipfs/go-log" + circuit "github.com/libp2p/go-libp2p-circuit" + lgbl "github.com/libp2p/go-libp2p-loggables" + + ma "github.com/multiformats/go-multiaddr" +) + +var log = logging.Logger("routedhost") + +// AddressTTL is the expiry time for our addresses. +// We expire them quickly. +const AddressTTL = time.Second * 10 + +// RoutedHost is a p2p Host that includes a routing system. +// This allows the Host to find the addresses for peers when +// it does not have them. +type RoutedHost struct { + host host.Host // embedded other host. + route Routing +} + +type Routing interface { + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) +} + +func Wrap(h host.Host, r Routing) *RoutedHost { + return &RoutedHost{h, r} +} + +// Connect ensures there is a connection between this host and the peer with +// given peer.ID. See (host.Host).Connect for more information. +// +// RoutedHost's Connect differs in that if the host has no addresses for a +// given peer, it will use its routing system to try to find some. +func (rh *RoutedHost) Connect(ctx context.Context, pi peer.AddrInfo) error { + // first, check if we're already connected. + if rh.Network().Connectedness(pi.ID) == network.Connected { + return nil + } + + // if we were given some addresses, keep + use them. + if len(pi.Addrs) > 0 { + rh.Peerstore().AddAddrs(pi.ID, pi.Addrs, peerstore.TempAddrTTL) + } + + // Check if we have some addresses in our recent memory. + addrs := rh.Peerstore().Addrs(pi.ID) + if len(addrs) < 1 { + // no addrs? find some with the routing system. + var err error + addrs, err = rh.findPeerAddrs(ctx, pi.ID) + if err != nil { + return err + } + } + + // Issue 448: if our address set includes routed specific relay addrs, + // we need to make sure the relay's addr itself is in the peerstore or else + // we wont be able to dial it. + for _, addr := range addrs { + _, err := addr.ValueForProtocol(circuit.P_CIRCUIT) + if err != nil { + // not a relay address + continue + } + + if addr.Protocols()[0].Code != ma.P_P2P { + // not a routed relay specific address + continue + } + + relay, _ := addr.ValueForProtocol(ma.P_P2P) + + relayID, err := peer.IDFromString(relay) + if err != nil { + log.Debugf("failed to parse relay ID in address %s: %s", relay, err) + continue + } + + if len(rh.Peerstore().Addrs(relayID)) > 0 { + // we already have addrs for this relay + continue + } + + relayAddrs, err := rh.findPeerAddrs(ctx, relayID) + if err != nil { + log.Debugf("failed to find relay %s: %s", relay, err) + continue + } + + rh.Peerstore().AddAddrs(relayID, relayAddrs, peerstore.TempAddrTTL) + } + + // if we're here, we got some addrs. let's use our wrapped host to connect. + pi.Addrs = addrs + return rh.host.Connect(ctx, pi) +} + +func (rh *RoutedHost) findPeerAddrs(ctx context.Context, id peer.ID) ([]ma.Multiaddr, error) { + pi, err := rh.route.FindPeer(ctx, id) + if err != nil { + return nil, err // couldnt find any :( + } + + if pi.ID != id { + err = fmt.Errorf("routing failure: provided addrs for different peer") + logRoutingErrDifferentPeers(ctx, id, pi.ID, err) + return nil, err + } + + return pi.Addrs, nil +} + +func logRoutingErrDifferentPeers(ctx context.Context, wanted, got peer.ID, err error) { + lm := make(lgbl.DeferredMap) + lm["error"] = err + lm["wantedPeer"] = func() interface{} { return wanted.Pretty() } + lm["gotPeer"] = func() interface{} { return got.Pretty() } + log.Event(ctx, "routingError", lm) +} + +func (rh *RoutedHost) ID() peer.ID { + return rh.host.ID() +} + +func (rh *RoutedHost) Peerstore() peerstore.Peerstore { + return rh.host.Peerstore() +} + +func (rh *RoutedHost) Addrs() []ma.Multiaddr { + return rh.host.Addrs() +} + +func (rh *RoutedHost) Network() network.Network { + return rh.host.Network() +} + +func (rh *RoutedHost) Mux() protocol.Switch { + return rh.host.Mux() +} + +func (rh *RoutedHost) SetStreamHandler(pid protocol.ID, handler network.StreamHandler) { + rh.host.SetStreamHandler(pid, handler) +} + +func (rh *RoutedHost) SetStreamHandlerMatch(pid protocol.ID, m func(string) bool, handler network.StreamHandler) { + rh.host.SetStreamHandlerMatch(pid, m, handler) +} + +func (rh *RoutedHost) RemoveStreamHandler(pid protocol.ID) { + rh.host.RemoveStreamHandler(pid) +} + +func (rh *RoutedHost) NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error) { + // Ensure we have a connection, with peer addresses resolved by the routing system (#207) + // It is not sufficient to let the underlying host connect, it will most likely not have + // any addresses for the peer without any prior connections. + // If the caller wants to prevent the host from dialing, it should use the NoDial option. + if nodial, _ := network.GetNoDial(ctx); !nodial { + err := rh.Connect(ctx, peer.AddrInfo{ID: p}) + if err != nil { + return nil, err + } + } + + return rh.host.NewStream(ctx, p, pids...) +} +func (rh *RoutedHost) Close() error { + // no need to close IpfsRouting. we dont own it. + return rh.host.Close() +} +func (rh *RoutedHost) ConnManager() connmgr.ConnManager { + return rh.host.ConnManager() +} + +var _ (host.Host) = (*RoutedHost)(nil) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go new file mode 100644 index 00000000..a3ddddaa --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go @@ -0,0 +1,519 @@ +package identify + +import ( + "context" + "sync" + "time" + + ic "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/helpers" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" + + pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" + + ggio "github.com/gogo/protobuf/io" + logging "github.com/ipfs/go-log" + + lgbl "github.com/libp2p/go-libp2p-loggables" + + ma "github.com/multiformats/go-multiaddr" + msmux "github.com/multiformats/go-multistream" +) + +var log = logging.Logger("net/identify") + +// ID is the protocol.ID of the Identify Service. +const ID = "/ipfs/id/1.0.0" + +// IDPush is the protocol.ID of the Identify push protocol +const IDPush = "/ipfs/id/push/1.0.0" + +// LibP2PVersion holds the current protocol version for a client running this code +// TODO(jbenet): fix the versioning mess. +const LibP2PVersion = "ipfs/0.1.0" + +var ClientVersion = "go-libp2p/3.3.4" + +// transientTTL is a short ttl for invalidated previously connected addrs +const transientTTL = 10 * time.Second + +// IDService is a structure that implements ProtocolIdentify. +// It is a trivial service that gives the other peer some +// useful information about the local peer. A sort of hello. +// +// The IDService sends: +// * Our IPFS Protocol Version +// * Our IPFS Agent Version +// * Our public Listen Addresses +type IDService struct { + Host host.Host + + ctx context.Context + + // connections undergoing identification + // for wait purposes + currid map[network.Conn]chan struct{} + currmu sync.RWMutex + + addrMu sync.Mutex + + // our own observed addresses. + // TODO: instead of expiring, remove these when we disconnect + observedAddrs *ObservedAddrSet +} + +// NewIDService constructs a new *IDService and activates it by +// attaching its stream handler to the given host.Host. +func NewIDService(ctx context.Context, h host.Host) *IDService { + s := &IDService{ + Host: h, + ctx: ctx, + currid: make(map[network.Conn]chan struct{}), + observedAddrs: NewObservedAddrSet(ctx), + } + h.SetStreamHandler(ID, s.requestHandler) + h.SetStreamHandler(IDPush, s.pushHandler) + h.Network().Notify((*netNotifiee)(s)) + return s +} + +// OwnObservedAddrs returns the addresses peers have reported we've dialed from +func (ids *IDService) OwnObservedAddrs() []ma.Multiaddr { + return ids.observedAddrs.Addrs() +} + +func (ids *IDService) ObservedAddrsFor(local ma.Multiaddr) []ma.Multiaddr { + return ids.observedAddrs.AddrsFor(local) +} + +func (ids *IDService) IdentifyConn(c network.Conn) { + ids.currmu.Lock() + if wait, found := ids.currid[c]; found { + ids.currmu.Unlock() + log.Debugf("IdentifyConn called twice on: %s", c) + <-wait // already identifying it. wait for it. + return + } + ch := make(chan struct{}) + ids.currid[c] = ch + ids.currmu.Unlock() + + defer func() { + close(ch) + ids.currmu.Lock() + delete(ids.currid, c) + ids.currmu.Unlock() + }() + + s, err := c.NewStream() + if err != nil { + log.Debugf("error opening initial stream for %s: %s", ID, err) + log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer()) + c.Close() + return + } + + s.SetProtocol(ID) + + // ok give the response to our handler. + if err := msmux.SelectProtoOrFail(ID, s); err != nil { + log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer(), logging.Metadata{"error": err}) + s.Reset() + return + } + + ids.responseHandler(s) +} + +func (ids *IDService) requestHandler(s network.Stream) { + defer helpers.FullClose(s) + c := s.Conn() + + w := ggio.NewDelimitedWriter(s) + mes := pb.Identify{} + ids.populateMessage(&mes, s.Conn()) + w.WriteMsg(&mes) + + log.Debugf("%s sent message to %s %s", ID, + c.RemotePeer(), c.RemoteMultiaddr()) +} + +func (ids *IDService) responseHandler(s network.Stream) { + c := s.Conn() + + r := ggio.NewDelimitedReader(s, 2048) + mes := pb.Identify{} + if err := r.ReadMsg(&mes); err != nil { + log.Warning("error reading identify message: ", err) + s.Reset() + return + } + ids.consumeMessage(&mes, c) + log.Debugf("%s received message from %s %s", ID, + c.RemotePeer(), c.RemoteMultiaddr()) + + go helpers.FullClose(s) +} + +func (ids *IDService) pushHandler(s network.Stream) { + ids.responseHandler(s) +} + +func (ids *IDService) Push() { + var wg sync.WaitGroup + + ctx, cancel := context.WithTimeout(ids.ctx, 30*time.Second) + ctx = network.WithNoDial(ctx, "identify push") + + for _, p := range ids.Host.Network().Peers() { + wg.Add(1) + go func(p peer.ID) { + defer wg.Done() + + s, err := ids.Host.NewStream(ctx, p, IDPush) + if err != nil { + log.Debugf("error opening push stream to %s: %s", p, err.Error()) + return + } + + rch := make(chan struct{}, 1) + go func() { + ids.requestHandler(s) + rch <- struct{}{} + }() + + select { + case <-rch: + case <-ctx.Done(): + // this is taking too long, abort! + s.Reset() + } + }(p) + } + + // this supervisory goroutine is necessary to cancel the context + go func() { + wg.Wait() + cancel() + }() +} + +func (ids *IDService) populateMessage(mes *pb.Identify, c network.Conn) { + + // set protocols this node is currently handling + protos := ids.Host.Mux().Protocols() + mes.Protocols = make([]string, len(protos)) + for i, p := range protos { + mes.Protocols[i] = string(p) + } + + // observed address so other side is informed of their + // "public" address, at least in relation to us. + mes.ObservedAddr = c.RemoteMultiaddr().Bytes() + + // set listen addrs, get our latest addrs from Host. + laddrs := ids.Host.Addrs() + mes.ListenAddrs = make([][]byte, len(laddrs)) + for i, addr := range laddrs { + mes.ListenAddrs[i] = addr.Bytes() + } + log.Debugf("%s sent listen addrs to %s: %s", c.LocalPeer(), c.RemotePeer(), laddrs) + + // set our public key + ownKey := ids.Host.Peerstore().PubKey(ids.Host.ID()) + + // check if we even have a public key. + if ownKey == nil { + // public key is nil. We are either using insecure transport or something erratic happened. + // check if we're even operating in "secure mode" + if ids.Host.Peerstore().PrivKey(ids.Host.ID()) != nil { + // private key is present. But NO public key. Something bad happened. + log.Errorf("did not have own public key in Peerstore") + } + // if neither of the key is present it is safe to assume that we are using an insecure transport. + } else { + // public key is present. Safe to proceed. + if kb, err := ownKey.Bytes(); err != nil { + log.Errorf("failed to convert key to bytes") + } else { + mes.PublicKey = kb + } + } + + // set protocol versions + pv := LibP2PVersion + av := ClientVersion + mes.ProtocolVersion = &pv + mes.AgentVersion = &av +} + +func (ids *IDService) consumeMessage(mes *pb.Identify, c network.Conn) { + p := c.RemotePeer() + + // mes.Protocols + ids.Host.Peerstore().SetProtocols(p, mes.Protocols...) + + // mes.ObservedAddr + ids.consumeObservedAddress(mes.GetObservedAddr(), c) + + // mes.ListenAddrs + laddrs := mes.GetListenAddrs() + lmaddrs := make([]ma.Multiaddr, 0, len(laddrs)) + for _, addr := range laddrs { + maddr, err := ma.NewMultiaddrBytes(addr) + if err != nil { + log.Debugf("%s failed to parse multiaddr from %s %s", ID, + p, c.RemoteMultiaddr()) + continue + } + lmaddrs = append(lmaddrs, maddr) + } + + // NOTE: Do not add `c.RemoteMultiaddr()` to the peerstore if the remote + // peer doesn't tell us to do so. Otherwise, we'll advertise it. + // + // This can cause an "addr-splosion" issue where the network will slowly + // gossip and collect observed but unadvertised addresses. Given a NAT + // that picks random source ports, this can cause DHT nodes to collect + // many undialable addresses for other peers. + + // Extend the TTLs on the known (probably) good addresses. + // Taking the lock ensures that we don't concurrently process a disconnect. + ids.addrMu.Lock() + switch ids.Host.Network().Connectedness(p) { + case network.Connected: + // invalidate previous addrs -- we use a transient ttl instead of 0 to ensure there + // is no period of having no good addrs whatsoever + ids.Host.Peerstore().UpdateAddrs(p, peerstore.ConnectedAddrTTL, transientTTL) + ids.Host.Peerstore().AddAddrs(p, lmaddrs, peerstore.ConnectedAddrTTL) + default: + ids.Host.Peerstore().UpdateAddrs(p, peerstore.ConnectedAddrTTL, transientTTL) + ids.Host.Peerstore().AddAddrs(p, lmaddrs, peerstore.RecentlyConnectedAddrTTL) + } + ids.addrMu.Unlock() + + log.Debugf("%s received listen addrs for %s: %s", c.LocalPeer(), c.RemotePeer(), lmaddrs) + + // get protocol versions + pv := mes.GetProtocolVersion() + av := mes.GetAgentVersion() + + ids.Host.Peerstore().Put(p, "ProtocolVersion", pv) + ids.Host.Peerstore().Put(p, "AgentVersion", av) + + // get the key from the other side. we may not have it (no-auth transport) + ids.consumeReceivedPubKey(c, mes.PublicKey) +} + +func (ids *IDService) consumeReceivedPubKey(c network.Conn, kb []byte) { + lp := c.LocalPeer() + rp := c.RemotePeer() + + if kb == nil { + log.Debugf("%s did not receive public key for remote peer: %s", lp, rp) + return + } + + newKey, err := ic.UnmarshalPublicKey(kb) + if err != nil { + log.Warningf("%s cannot unmarshal key from remote peer: %s, %s", lp, rp, err) + return + } + + // verify key matches peer.ID + np, err := peer.IDFromPublicKey(newKey) + if err != nil { + log.Debugf("%s cannot get peer.ID from key of remote peer: %s, %s", lp, rp, err) + return + } + + if np != rp { + // if the newKey's peer.ID does not match known peer.ID... + + if rp == "" && np != "" { + // if local peerid is empty, then use the new, sent key. + err := ids.Host.Peerstore().AddPubKey(rp, newKey) + if err != nil { + log.Debugf("%s could not add key for %s to peerstore: %s", lp, rp, err) + } + + } else { + // we have a local peer.ID and it does not match the sent key... error. + log.Errorf("%s received key for remote peer %s mismatch: %s", lp, rp, np) + } + return + } + + currKey := ids.Host.Peerstore().PubKey(rp) + if currKey == nil { + // no key? no auth transport. set this one. + err := ids.Host.Peerstore().AddPubKey(rp, newKey) + if err != nil { + log.Debugf("%s could not add key for %s to peerstore: %s", lp, rp, err) + } + return + } + + // ok, we have a local key, we should verify they match. + if currKey.Equals(newKey) { + return // ok great. we're done. + } + + // weird, got a different key... but the different key MATCHES the peer.ID. + // this odd. let's log error and investigate. this should basically never happen + // and it means we have something funky going on and possibly a bug. + log.Errorf("%s identify got a different key for: %s", lp, rp) + + // okay... does ours NOT match the remote peer.ID? + cp, err := peer.IDFromPublicKey(currKey) + if err != nil { + log.Errorf("%s cannot get peer.ID from local key of remote peer: %s, %s", lp, rp, err) + return + } + if cp != rp { + log.Errorf("%s local key for remote peer %s yields different peer.ID: %s", lp, rp, cp) + return + } + + // okay... curr key DOES NOT match new key. both match peer.ID. wat? + log.Errorf("%s local key and received key for %s do not match, but match peer.ID", lp, rp) +} + +// HasConsistentTransport returns true if the address 'a' shares a +// protocol set with any address in the green set. This is used +// to check if a given address might be one of the addresses a peer is +// listening on. +func HasConsistentTransport(a ma.Multiaddr, green []ma.Multiaddr) bool { + protosMatch := func(a, b []ma.Protocol) bool { + if len(a) != len(b) { + return false + } + + for i, p := range a { + if b[i].Code != p.Code { + return false + } + } + return true + } + + protos := a.Protocols() + + for _, ga := range green { + if protosMatch(protos, ga.Protocols()) { + return true + } + } + + return false +} + +// IdentifyWait returns a channel which will be closed once +// "ProtocolIdentify" (handshake3) finishes on given conn. +// This happens async so the connection can start to be used +// even if handshake3 knowledge is not necesary. +// Users **MUST** call IdentifyWait _after_ IdentifyConn +func (ids *IDService) IdentifyWait(c network.Conn) <-chan struct{} { + ids.currmu.Lock() + ch, found := ids.currid[c] + ids.currmu.Unlock() + if found { + return ch + } + + // if not found, it means we are already done identifying it, or + // haven't even started. either way, return a new channel closed. + ch = make(chan struct{}) + close(ch) + return ch +} + +func (ids *IDService) consumeObservedAddress(observed []byte, c network.Conn) { + if observed == nil { + return + } + + maddr, err := ma.NewMultiaddrBytes(observed) + if err != nil { + log.Debugf("error parsing received observed addr for %s: %s", c, err) + return + } + + // we should only use ObservedAddr when our connection's LocalAddr is one + // of our ListenAddrs. If we Dial out using an ephemeral addr, knowing that + // address's external mapping is not very useful because the port will not be + // the same as the listen addr. + ifaceaddrs, err := ids.Host.Network().InterfaceListenAddresses() + if err != nil { + log.Infof("failed to get interface listen addrs", err) + return + } + + log.Debugf("identify identifying observed multiaddr: %s %s", c.LocalMultiaddr(), ifaceaddrs) + if !addrInAddrs(c.LocalMultiaddr(), ifaceaddrs) && !addrInAddrs(c.LocalMultiaddr(), ids.Host.Network().ListenAddresses()) { + // not in our list + return + } + + if !HasConsistentTransport(maddr, ids.Host.Addrs()) { + log.Debugf("ignoring observed multiaddr that doesn't match the transports of any addresses we're announcing", c.RemoteMultiaddr()) + return + } + + // ok! we have the observed version of one of our ListenAddresses! + log.Debugf("added own observed listen addr: %s --> %s", c.LocalMultiaddr(), maddr) + ids.observedAddrs.Add(maddr, c.LocalMultiaddr(), c.RemoteMultiaddr(), + c.Stat().Direction) +} + +func addrInAddrs(a ma.Multiaddr, as []ma.Multiaddr) bool { + for _, b := range as { + if a.Equal(b) { + return true + } + } + return false +} + +// netNotifiee defines methods to be used with the IpfsDHT +type netNotifiee IDService + +func (nn *netNotifiee) IDService() *IDService { + return (*IDService)(nn) +} + +func (nn *netNotifiee) Connected(n network.Network, v network.Conn) { + // TODO: deprecate the setConnHandler hook, and kick off + // identification here. +} + +func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) { + // undo the setting of addresses to peer.ConnectedAddrTTL we did + ids := nn.IDService() + ids.addrMu.Lock() + defer ids.addrMu.Unlock() + + if ids.Host.Network().Connectedness(v.RemotePeer()) != network.Connected { + // Last disconnect. + ps := ids.Host.Peerstore() + ps.UpdateAddrs(v.RemotePeer(), peerstore.ConnectedAddrTTL, peerstore.RecentlyConnectedAddrTTL) + } +} + +func (nn *netNotifiee) OpenedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) ClosedStream(n network.Network, v network.Stream) {} +func (nn *netNotifiee) Listen(n network.Network, a ma.Multiaddr) {} +func (nn *netNotifiee) ListenClose(n network.Network, a ma.Multiaddr) {} + +func logProtocolMismatchDisconnect(c network.Conn, protocol, agent string) { + lm := make(lgbl.DeferredMap) + lm["remotePeer"] = func() interface{} { return c.RemotePeer().Pretty() } + lm["remoteAddr"] = func() interface{} { return c.RemoteMultiaddr().String() } + lm["protocolVersion"] = protocol + lm["agentVersion"] = agent + log.Event(context.TODO(), "IdentifyProtocolMismatch", lm) + log.Debugf("IdentifyProtocolMismatch %s %s %s (disconnected)", c.RemotePeer(), protocol, agent) +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go new file mode 100644 index 00000000..12e22860 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go @@ -0,0 +1,230 @@ +package identify + +import ( + "context" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peerstore" + + ma "github.com/multiformats/go-multiaddr" +) + +const ActivationThresh = 4 + +var GCInterval = 10 * time.Minute + +type observation struct { + seenTime time.Time + connDirection network.Direction +} + +// ObservedAddr is an entry for an address reported by our peers. +// We only use addresses that: +// - have been observed at least 4 times in last 1h. (counter symmetric nats) +// - have been observed at least once recently (1h), because our position in the +// network, or network port mapppings, may have changed. +type ObservedAddr struct { + Addr ma.Multiaddr + SeenBy map[string]observation // peer(observer) address -> observation info + LastSeen time.Time +} + +func (oa *ObservedAddr) activated(ttl time.Duration) bool { + // We only activate if in the TTL other peers observed the same address + // of ours at least 4 times. + return len(oa.SeenBy) >= ActivationThresh +} + +type newObservation struct { + observed, local, observer ma.Multiaddr + direction network.Direction +} + +// ObservedAddrSet keeps track of a set of ObservedAddrs +// the zero-value is ready to be used. +type ObservedAddrSet struct { + sync.RWMutex // guards whole datastruct. + + // local(internal) address -> list of observed(external) addresses + addrs map[string][]*ObservedAddr + ttl time.Duration + + // this is the worker channel + wch chan newObservation +} + +func NewObservedAddrSet(ctx context.Context) *ObservedAddrSet { + oas := &ObservedAddrSet{ + addrs: make(map[string][]*ObservedAddr), + ttl: peerstore.OwnObservedAddrTTL, + wch: make(chan newObservation, 16), + } + go oas.worker(ctx) + return oas +} + +// AddrsFor return all activated observed addresses associated with the given +// (resolved) listen address. +func (oas *ObservedAddrSet) AddrsFor(addr ma.Multiaddr) (addrs []ma.Multiaddr) { + oas.RLock() + defer oas.RUnlock() + + if len(oas.addrs) == 0 { + return nil + } + + key := string(addr.Bytes()) + observedAddrs, ok := oas.addrs[key] + if !ok { + return + } + + now := time.Now() + for _, a := range observedAddrs { + if now.Sub(a.LastSeen) <= oas.ttl && a.activated(oas.ttl) { + addrs = append(addrs, a.Addr) + } + } + + return addrs +} + +// Addrs return all activated observed addresses +func (oas *ObservedAddrSet) Addrs() (addrs []ma.Multiaddr) { + oas.RLock() + defer oas.RUnlock() + + if len(oas.addrs) == 0 { + return nil + } + + now := time.Now() + for _, observedAddrs := range oas.addrs { + for _, a := range observedAddrs { + if now.Sub(a.LastSeen) <= oas.ttl && a.activated(oas.ttl) { + addrs = append(addrs, a.Addr) + } + } + } + return addrs +} + +func (oas *ObservedAddrSet) Add(observed, local, observer ma.Multiaddr, + direction network.Direction) { + select { + case oas.wch <- newObservation{observed: observed, local: local, observer: observer, direction: direction}: + default: + log.Debugf("dropping address observation of %s; buffer full", observed) + } +} + +func (oas *ObservedAddrSet) worker(ctx context.Context) { + ticker := time.NewTicker(GCInterval) + defer ticker.Stop() + + for { + select { + case obs := <-oas.wch: + oas.doAdd(obs.observed, obs.local, obs.observer, obs.direction) + + case <-ticker.C: + oas.gc() + + case <-ctx.Done(): + return + } + } +} + +func (oas *ObservedAddrSet) gc() { + oas.Lock() + defer oas.Unlock() + + now := time.Now() + for local, observedAddrs := range oas.addrs { + // TODO we can do this without allocating by compacting the array in place + filteredAddrs := make([]*ObservedAddr, 0, len(observedAddrs)) + + for _, a := range observedAddrs { + // clean up SeenBy set + for k, ob := range a.SeenBy { + if now.Sub(ob.seenTime) > oas.ttl*ActivationThresh { + delete(a.SeenBy, k) + } + } + + // leave only alive observed addresses + if now.Sub(a.LastSeen) <= oas.ttl { + filteredAddrs = append(filteredAddrs, a) + } + } + if len(filteredAddrs) > 0 { + oas.addrs[local] = filteredAddrs + } else { + delete(oas.addrs, local) + } + } +} + +func (oas *ObservedAddrSet) doAdd(observed, local, observer ma.Multiaddr, + direction network.Direction) { + + now := time.Now() + observerString := observerGroup(observer) + localString := string(local.Bytes()) + ob := observation{ + seenTime: now, + connDirection: direction, + } + + oas.Lock() + defer oas.Unlock() + + observedAddrs := oas.addrs[localString] + // check if observed address seen yet, if so, update it + for i, previousObserved := range observedAddrs { + if previousObserved.Addr.Equal(observed) { + observedAddrs[i].SeenBy[observerString] = ob + observedAddrs[i].LastSeen = now + return + } + } + // observed address not seen yet, append it + oas.addrs[localString] = append(oas.addrs[localString], &ObservedAddr{ + Addr: observed, + SeenBy: map[string]observation{ + observerString: ob, + }, + LastSeen: now, + }) +} + +// observerGroup is a function that determines what part of +// a multiaddr counts as a different observer. for example, +// two ipfs nodes at the same IP/TCP transport would get +// the exact same NAT mapping; they would count as the +// same observer. This may protect against NATs who assign +// different ports to addresses at different IP hosts, but +// not TCP ports. +// +// Here, we use the root multiaddr address. This is mostly +// IP addresses. In practice, this is what we want. +func observerGroup(m ma.Multiaddr) string { + //TODO: If IPv6 rolls out we should mark /64 routing zones as one group + first, _ := ma.SplitFirst(m) + return string(first.Bytes()) +} + +func (oas *ObservedAddrSet) SetTTL(ttl time.Duration) { + oas.Lock() + defer oas.Unlock() + oas.ttl = ttl +} + +func (oas *ObservedAddrSet) TTL() time.Duration { + oas.RLock() + defer oas.RUnlock() + return oas.ttl +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/Makefile new file mode 100644 index 00000000..eb14b576 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go new file mode 100644 index 00000000..de1275ba --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go @@ -0,0 +1,635 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: identify.proto + +package identify_pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + 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. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Identify struct { + // protocolVersion determines compatibility between peers + ProtocolVersion *string `protobuf:"bytes,5,opt,name=protocolVersion" json:"protocolVersion,omitempty"` + // agentVersion is like a UserAgent string in browsers, or client version in bittorrent + // includes the client name and client. + AgentVersion *string `protobuf:"bytes,6,opt,name=agentVersion" json:"agentVersion,omitempty"` + // publicKey is this node's public key (which also gives its node.ID) + // - may not need to be sent, as secure channel implies it has been sent. + // - then again, if we change / disable secure channel, may still want it. + PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"` + // listenAddrs are the multiaddrs the sender node listens for open connections on + ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"` + // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives + // this is useful information to convey to the other side, as it helps the remote endpoint + // determine whether its connection to the local peer goes through NAT. + ObservedAddr []byte `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"` + // protocols are the services this node is running + Protocols []string `protobuf:"bytes,3,rep,name=protocols" json:"protocols,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Identify) Reset() { *m = Identify{} } +func (m *Identify) String() string { return proto.CompactTextString(m) } +func (*Identify) ProtoMessage() {} +func (*Identify) Descriptor() ([]byte, []int) { + return fileDescriptor_83f1e7e6b485409f, []int{0} +} +func (m *Identify) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Identify) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Identify.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Identify) XXX_Merge(src proto.Message) { + xxx_messageInfo_Identify.Merge(m, src) +} +func (m *Identify) XXX_Size() int { + return m.Size() +} +func (m *Identify) XXX_DiscardUnknown() { + xxx_messageInfo_Identify.DiscardUnknown(m) +} + +var xxx_messageInfo_Identify proto.InternalMessageInfo + +func (m *Identify) GetProtocolVersion() string { + if m != nil && m.ProtocolVersion != nil { + return *m.ProtocolVersion + } + return "" +} + +func (m *Identify) GetAgentVersion() string { + if m != nil && m.AgentVersion != nil { + return *m.AgentVersion + } + return "" +} + +func (m *Identify) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *Identify) GetListenAddrs() [][]byte { + if m != nil { + return m.ListenAddrs + } + return nil +} + +func (m *Identify) GetObservedAddr() []byte { + if m != nil { + return m.ObservedAddr + } + return nil +} + +func (m *Identify) GetProtocols() []string { + if m != nil { + return m.Protocols + } + return nil +} + +func init() { + proto.RegisterType((*Identify)(nil), "identify.pb.Identify") +} + +func init() { proto.RegisterFile("identify.proto", fileDescriptor_83f1e7e6b485409f) } + +var fileDescriptor_83f1e7e6b485409f = []byte{ + // 187 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0x4c, 0x49, 0xcd, + 0x2b, 0xc9, 0x4c, 0xab, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x46, 0xf0, 0x93, 0x94, + 0x6e, 0x31, 0x72, 0x71, 0x78, 0x42, 0xf9, 0x42, 0x1a, 0x5c, 0xfc, 0x60, 0x25, 0xc9, 0xf9, 0x39, + 0x61, 0xa9, 0x45, 0xc5, 0x99, 0xf9, 0x79, 0x12, 0xac, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0xe8, 0xc2, + 0x42, 0x4a, 0x5c, 0x3c, 0x89, 0xe9, 0xa9, 0x79, 0x25, 0x30, 0x65, 0x6c, 0x60, 0x65, 0x28, 0x62, + 0x42, 0x32, 0x5c, 0x9c, 0x05, 0xa5, 0x49, 0x39, 0x99, 0xc9, 0xde, 0xa9, 0x95, 0x12, 0x8c, 0x0a, + 0x8c, 0x1a, 0x3c, 0x41, 0x08, 0x01, 0x21, 0x05, 0x2e, 0xee, 0x9c, 0xcc, 0xe2, 0x92, 0xd4, 0x3c, + 0xc7, 0x94, 0x94, 0xa2, 0x62, 0x09, 0x26, 0x05, 0x66, 0x0d, 0x9e, 0x20, 0x64, 0x21, 0x90, 0x1d, + 0xf9, 0x49, 0xc5, 0xa9, 0x45, 0x65, 0xa9, 0x29, 0x20, 0x01, 0x09, 0x16, 0xb0, 0x11, 0x28, 0x62, + 0x60, 0x3b, 0xa0, 0x4e, 0x2b, 0x96, 0x60, 0x56, 0x60, 0xd6, 0xe0, 0x0c, 0x42, 0x08, 0x38, 0xf1, + 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x80, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xc2, 0x2c, 0x19, 0x46, 0x08, 0x01, 0x00, 0x00, +} + +func (m *Identify) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Identify) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.PublicKey != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintIdentify(dAtA, i, uint64(len(m.PublicKey))) + i += copy(dAtA[i:], m.PublicKey) + } + if len(m.ListenAddrs) > 0 { + for _, b := range m.ListenAddrs { + dAtA[i] = 0x12 + i++ + i = encodeVarintIdentify(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } + if len(m.Protocols) > 0 { + for _, s := range m.Protocols { + dAtA[i] = 0x1a + 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) + } + } + if m.ObservedAddr != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintIdentify(dAtA, i, uint64(len(m.ObservedAddr))) + i += copy(dAtA[i:], m.ObservedAddr) + } + if m.ProtocolVersion != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintIdentify(dAtA, i, uint64(len(*m.ProtocolVersion))) + i += copy(dAtA[i:], *m.ProtocolVersion) + } + if m.AgentVersion != nil { + dAtA[i] = 0x32 + i++ + i = encodeVarintIdentify(dAtA, i, uint64(len(*m.AgentVersion))) + i += copy(dAtA[i:], *m.AgentVersion) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintIdentify(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Identify) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PublicKey != nil { + l = len(m.PublicKey) + n += 1 + l + sovIdentify(uint64(l)) + } + if len(m.ListenAddrs) > 0 { + for _, b := range m.ListenAddrs { + l = len(b) + n += 1 + l + sovIdentify(uint64(l)) + } + } + if len(m.Protocols) > 0 { + for _, s := range m.Protocols { + l = len(s) + n += 1 + l + sovIdentify(uint64(l)) + } + } + if m.ObservedAddr != nil { + l = len(m.ObservedAddr) + n += 1 + l + sovIdentify(uint64(l)) + } + if m.ProtocolVersion != nil { + l = len(*m.ProtocolVersion) + n += 1 + l + sovIdentify(uint64(l)) + } + if m.AgentVersion != nil { + l = len(*m.AgentVersion) + n += 1 + l + sovIdentify(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovIdentify(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozIdentify(x uint64) (n int) { + return sovIdentify(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Identify) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Identify: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Identify: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIdentify + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListenAddrs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIdentify + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ListenAddrs = append(m.ListenAddrs, make([]byte, postIndex-iNdEx)) + copy(m.ListenAddrs[len(m.ListenAddrs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocols", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + 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 ErrInvalidLengthIdentify + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocols = append(m.Protocols, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedAddr", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIdentify + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObservedAddr = append(m.ObservedAddr[:0], dAtA[iNdEx:postIndex]...) + if m.ObservedAddr == nil { + m.ObservedAddr = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProtocolVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + 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 ErrInvalidLengthIdentify + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ProtocolVersion = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgentVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIdentify + } + 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 ErrInvalidLengthIdentify + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIdentify + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.AgentVersion = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIdentify(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIdentify + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIdentify + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIdentify(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIdentify + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIdentify + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIdentify + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthIdentify + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthIdentify + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIdentify + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipIdentify(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthIdentify + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthIdentify = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIdentify = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto new file mode 100644 index 00000000..5270c4cf --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto @@ -0,0 +1,29 @@ +syntax = "proto2"; + +package identify.pb; + +message Identify { + + // protocolVersion determines compatibility between peers + optional string protocolVersion = 5; // e.g. ipfs/1.0.0 + + // agentVersion is like a UserAgent string in browsers, or client version in bittorrent + // includes the client name and client. + optional string agentVersion = 6; // e.g. go-ipfs/0.1.0 + + // publicKey is this node's public key (which also gives its node.ID) + // - may not need to be sent, as secure channel implies it has been sent. + // - then again, if we change / disable secure channel, may still want it. + optional bytes publicKey = 1; + + // listenAddrs are the multiaddrs the sender node listens for open connections on + repeated bytes listenAddrs = 2; + + // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives + // this is useful information to convey to the other side, as it helps the remote endpoint + // determine whether its connection to the local peer goes through NAT. + optional bytes observedAddr = 4; + + // protocols are the services this node is running + repeated string protocols = 3; +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go new file mode 100644 index 00000000..9d9b571e --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go @@ -0,0 +1,153 @@ +package ping + +import ( + "bytes" + "context" + "errors" + "io" + "time" + + u "github.com/ipfs/go-ipfs-util" + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" +) + +var log = logging.Logger("ping") + +const PingSize = 32 + +const ID = "/ipfs/ping/1.0.0" + +const pingTimeout = time.Second * 60 + +type PingService struct { + Host host.Host +} + +func NewPingService(h host.Host) *PingService { + ps := &PingService{h} + h.SetStreamHandler(ID, ps.PingHandler) + return ps +} + +func (p *PingService) PingHandler(s network.Stream) { + buf := make([]byte, PingSize) + + errCh := make(chan error, 1) + defer close(errCh) + timer := time.NewTimer(pingTimeout) + defer timer.Stop() + + go func() { + select { + case <-timer.C: + log.Debug("ping timeout") + case err, ok := <-errCh: + if ok { + log.Debug(err) + } else { + log.Error("ping loop failed without error") + } + } + s.Reset() + }() + + for { + _, err := io.ReadFull(s, buf) + if err != nil { + errCh <- err + return + } + + _, err = s.Write(buf) + if err != nil { + errCh <- err + return + } + + timer.Reset(pingTimeout) + } +} + +// Result is a result of a ping attempt, either an RTT or an error. +type Result struct { + RTT time.Duration + Error error +} + +func (ps *PingService) Ping(ctx context.Context, p peer.ID) <-chan Result { + return Ping(ctx, ps.Host, p) +} + +// Ping pings the remote peer until the context is canceled, returning a stream +// of RTTs or errors. +func Ping(ctx context.Context, h host.Host, p peer.ID) <-chan Result { + s, err := h.NewStream(ctx, p, ID) + if err != nil { + ch := make(chan Result, 1) + ch <- Result{Error: err} + close(ch) + return ch + } + + ctx, cancel := context.WithCancel(ctx) + + out := make(chan Result) + go func() { + defer close(out) + defer cancel() + + for ctx.Err() == nil { + var res Result + res.RTT, res.Error = ping(s) + + // canceled, ignore everything. + if ctx.Err() != nil { + return + } + + // No error, record the RTT. + if res.Error == nil { + h.Peerstore().RecordLatency(p, res.RTT) + } + + select { + case out <- res: + case <-ctx.Done(): + return + } + } + }() + go func() { + // forces the ping to abort. + <-ctx.Done() + s.Reset() + }() + + return out +} + +func ping(s network.Stream) (time.Duration, error) { + buf := make([]byte, PingSize) + u.NewTimeSeededRand().Read(buf) + + before := time.Now() + _, err := s.Write(buf) + if err != nil { + return 0, err + } + + rbuf := make([]byte, PingSize) + _, err = io.ReadFull(s, rbuf) + if err != nil { + return 0, err + } + + if !bytes.Equal(buf, rbuf) { + return 0, errors.New("ping packet was incorrect!") + } + + return time.Since(before), nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/package-list.json b/vendor/github.com/libp2p/go-libp2p/package-list.json new file mode 100644 index 00000000..e29a7410 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/package-list.json @@ -0,0 +1,97 @@ +{ + "columns": [ + "Name", + "CI/Travis", + "Coverage", + "Description" + ], + "rows": [ + "Libp2p", + ["libp2p/go-libp2p", "go-libp2p", "go-libp2p entry point"], + ["libp2p/go-libp2p-host", "go-libp2p-host", "libp2p \"host\" interface"], + ["libp2p/go-libp2p-blankhost", "go-libp2p-blankhost", "minimal implementation of the \"host\" interface"], + + "Network", + ["libp2p/go-libp2p-net", "go-libp2p-net", "libp2p connection and \"network\" interfaces"], + ["libp2p/go-libp2p-swarm", "go-libp2p-swarm", "reference implementation"], + + "Transport", + ["libp2p/go-libp2p-transport", "go-libp2p-transport", "interfaces"], + ["libp2p/go-ws-transport", "go-ws-transport", "WebSocket transport"], + ["libp2p/go-tcp-transport", "go-tcp-transport", "TCP transport"], + ["libp2p/go-libp2p-quic-transport", "go-libp2p-quic-transport", "QUIC transport"], + ["libp2p/go-udp-transport", "go-udp-transport", "UDP transport"], + ["libp2p/go-utp-transport", "go-utp-transport", "uTorrent transport (UTP)"], + ["libp2p/go-libp2p-circuit", "go-libp2p-circuit", "relay transport"], + ["libp2p/go-libp2p-transport-upgrader", "go-libp2p-transport-upgrader", "upgrades multiaddr-net connections into full libp2p transports"], + ["libp2p/go-libp2p-reuseport-transport", "go-libp2p-reuseport-transport", "partial transport for building transports that reuse ports"], + + "Encrypted Channels", + ["libp2p/go-conn-security", "go-conn-security", "interfaces"], + ["libp2p/go-libp2p-secio", "go-libp2p-secio", "SecIO crypto channel"], + ["libp2p/go-conn-security-multistream", "go-conn-security-multistream", "multistream multiplexed meta crypto channel"], + + "Private Network", + ["libp2p/go-libp2p-interface-pnet", "go-libp2p-interface-pnet", "interfaces"], + ["libp2p/go-libp2p-pnet", "go-libp2p-pnet", "reference implementation"], + + "Stream Muxers", + ["libp2p/go-stream-muxer", "go-stream-muxer", "interfaces"], + ["whyrusleeping/go-smux-yamux", "go-smux-yamux", "YAMUX stream multiplexer"], + ["whyrusleeping/go-smux-mplex", "go-smux-mplex", "MPLEX stream multiplexer"], + + "NAT Traversal", + ["libp2p/go-libp2p-nat", "go-libp2p-nat"], + + "Peerstore", + ["libp2p/go-libp2p-peerstore", "go-libp2p-peerstore", "interfaces and reference implementation"], + + "Connection Manager", + ["libp2p/go-libp2p-interface-connmgr", "go-libp2p-interface-connmgr", "interface"], + ["libp2p/go-libp2p-connmgr", "go-libp2p-connmgr", "reference implementation"], + + "Routing", + ["libp2p/go-libp2p-routing", "go-libp2p-routing", "routing interfaces"], + ["libp2p/go-libp2p-record", "go-libp2p-record", "record type and validator logic"], + ["libp2p/go-libp2p-routing-helpers", "go-libp2p-routing-helpers", "helpers for composing routers"], + ["libp2p/go-libp2p-kad-dht", "go-libp2p-kad-dht", "Kademlia-like router"], + ["libp2p/go-libp2p-pubsub-router", "go-libp2p-pubsub-router", "record-store over pubsub adapter"], + + "Consensus", + ["libp2p/go-libp2p-consensus", "go-libp2p-consensus", "consensus protocols interfaces"], + ["libp2p/go-libp2p-raft", "go-libp2p-raft", "consensus implementation over raft"], + + "Pubsub", + ["libp2p/go-libp2p-pubsub", "go-libp2p-pubsub", "multiple pubsub over libp2p implementations"], + + "RPC", + ["libp2p/go-libp2p-gorpc", "go-libp2p-gorpc", "a simple RPC library for libp2p"], + + "Metrics", + ["libp2p/go-libp2p-metrics", "go-libp2p-metrics", "libp2p metrics interfaces/collectors"], + + "Data Types", + ["libp2p/go-libp2p-peer", "go-libp2p-peer", "libp2p peer-ID datatype"], + ["libp2p/go-libp2p-crypto", "go-libp2p-crypto", "libp2p key types"], + ["libp2p/go-libp2p-protocol", "go-libp2p-protocol", "libp2p protocol datatype"], + ["libp2p/go-libp2p-kbucket", "go-libp2p-kbucket", "Kademlia routing table helper types"], + + "Utilities/miscellaneous", + ["libp2p/go-libp2p-loggables", "go-libp2p-loggables", "logging helpers"], + ["libp2p/go-maddr-filter", "go-maddr-filter", "multiaddr filtering helpers"], + ["libp2p/go-libp2p-netutil", "go-libp2p-netutil", "misc utilities"], + ["libp2p/go-msgio", "go-msgio", "length prefixed data channel"], + ["libp2p/go-addr-util", "go-addr-util", "address utilities for libp2p swarm"], + ["libp2p/go-buffer-pool", "go-buffer-pool", "a variable size buffer pool for go"], + ["libp2p/go-libp2p-routing-helpers", "go-libp2p-routing-helpers", "routing helpers"], + ["libp2p/go-reuseport", "go-reuseport", "enables reuse of addresses"], + ["libp2p/go-sockaddr", "go-sockaddr", "utils for sockaddr conversions"], + ["libp2p/go-flow-metrics", "go-flow-metrics", "metrics library"], + + "Testing and examples", + ["libp2p/go-testutil", "go-testutil", "a collection of testing utilities for ipfs and libp2p"], + ["libp2p/go-libp2p-examples", "go-libp2p-examples", "go-libp2p examples and tutorials"], + ["libp2p/go-libp2p-circuit-progs", "go-libp2p-circuit-progs", "testing programs for go-libp2p-circuit"] + + ] +} diff --git a/vendor/github.com/libp2p/go-maddr-filter/.travis.yml b/vendor/github.com/libp2p/go-maddr-filter/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-maddr-filter/LICENSE b/vendor/github.com/libp2p/go-maddr-filter/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-maddr-filter/README.md b/vendor/github.com/libp2p/go-maddr-filter/README.md new file mode 100644 index 00000000..db9ba5e0 --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/README.md @@ -0,0 +1,64 @@ +go-maddr-filter +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-maddr-filter/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-maddr-filter?branch=master) +[![Travis CI](https://travis-ci.org/libp2p/go-maddr-filter.svg?branch=master)](https://travis-ci.org/libp2p/go-maddr-filter) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +> A library to perform filtering of [multiaddrs](https://github.com/multiformats/multiaddr). + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Examples + +```go +// make a new filterset +f := NewFilters() + +// filter out addresses on the 192.168 subnet +_, ipnet, _ := net.ParseCIDR("192.168.0.0/16") +f.AddFilter(ipnet, ActionDeny) + +// check if an address is blocked +lanaddr, _ := ma.NewMultiaddr("/ip4/192.168.0.17/tcp/4050") +fmt.Println(f.AddrBlocked(lanaddr)) + +// the default for a filter is accept, but we can change that +f.RemoveLiteral(ipnet) +f.DefaultAction = ActionDeny +fmt.Println(f.AddrBlocked(lanaddr)) + +// we can now allow the local LAN, denying everything else +f.AddFilter(ipnet, ActionAccept) +fmt.Println(f.AddrBlocked(lanaddr)) +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson + +--- + +The last gx published version of this module was: 1.1.13: QmT6C5ebDy92zyRzdmSNyda5q7zkNXy68X47RDJiHpvaxd diff --git a/vendor/github.com/libp2p/go-maddr-filter/codecov.yml b/vendor/github.com/libp2p/go-maddr-filter/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-maddr-filter/filter.go b/vendor/github.com/libp2p/go-maddr-filter/filter.go new file mode 100644 index 00000000..a555df51 --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/filter.go @@ -0,0 +1,174 @@ +package filter + +import ( + "net" + "sync" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +// Action is an enum modelling all possible filter actions. +type Action int32 + +const ( + ActionNone Action = iota // zero value. + ActionAccept + ActionDeny +) + +type filterEntry struct { + f net.IPNet + action Action +} + +// Filters is a structure representing a collection of accept/deny +// net.IPNet filters, together with the DefaultAction flag, which +// represents the default filter policy. +// +// Note that the last policy added to the Filters is authoritative. +type Filters struct { + DefaultAction Action + + mu sync.RWMutex + filters []*filterEntry +} + +// NewFilters constructs and returns a new set of net.IPNet filters. +// By default, the new filter accepts all addresses. +func NewFilters() *Filters { + return &Filters{ + DefaultAction: ActionAccept, + filters: make([]*filterEntry, 0), + } +} + +func (fs *Filters) find(ipnet net.IPNet) (int, *filterEntry) { + s := ipnet.String() + for idx, ft := range fs.filters { + if ft.f.String() == s { + return idx, ft + } + } + return -1, nil +} + +// AddDialFilter adds a deny rule to this Filters set. Hosts +// matching the given net.IPNet filter will be denied, unless +// another rule is added which states that they should be accepted. +// +// No effort is made to prevent duplication of filters, or to simplify +// the filters list. +// +// Deprecated: Use AddFilter(). +func (fs *Filters) AddDialFilter(f *net.IPNet) { + fs.AddFilter(*f, ActionDeny) +} + +// AddFilter adds a rule to the Filters set, enforcing the desired action for +// the provided IPNet mask. +func (fs *Filters) AddFilter(ipnet net.IPNet, action Action) { + fs.mu.Lock() + defer fs.mu.Unlock() + + if _, f := fs.find(ipnet); f != nil { + f.action = action + } else { + fs.filters = append(fs.filters, &filterEntry{ipnet, action}) + } +} + +// RemoveLiteral removes the first filter associated with the supplied IPNet, +// returning whether something was removed or not. It makes no distinction +// between whether the rule is an accept or a deny. +// +// Deprecated: use RemoveLiteral() instead. +func (fs *Filters) Remove(ipnet *net.IPNet) (removed bool) { + return fs.RemoveLiteral(*ipnet) +} + +// RemoveLiteral removes the first filter associated with the supplied IPNet, +// returning whether something was removed or not. It makes no distinction +// between whether the rule is an accept or a deny. +func (fs *Filters) RemoveLiteral(ipnet net.IPNet) (removed bool) { + fs.mu.Lock() + defer fs.mu.Unlock() + + if idx, _ := fs.find(ipnet); idx != -1 { + fs.filters = append(fs.filters[:idx], fs.filters[idx+1:]...) + return true + } + return false +} + +// AddrBlocked parses a ma.Multiaddr and, if a valid netip is found, it applies the +// Filter set rules, returning true if the given address should be denied, and false if +// the given address is accepted. +// +// If a parsing error occurs, or no filter matches, the Filters' +// default is returned. +// +// TODO: currently, the last filter to match wins always, but it shouldn't be that way. +// Instead, the highest-specific last filter should win; that way more specific filters +// override more general ones. +func (fs *Filters) AddrBlocked(a ma.Multiaddr) (deny bool) { + maddr := ma.Split(a) + if len(maddr) == 0 { + return fs.DefaultAction == ActionDeny + } + netaddr, err := manet.ToNetAddr(maddr[0]) + if err != nil { + // if we can't parse it, it's probably not blocked. + return fs.DefaultAction == ActionDeny + } + netip := net.ParseIP(netaddr.String()) + if netip == nil { + return fs.DefaultAction == ActionDeny + } + + fs.mu.RLock() + defer fs.mu.RUnlock() + + action := fs.DefaultAction + for _, ft := range fs.filters { + if ft.f.Contains(netip) { + action = ft.action + } + } + + return action == ActionDeny +} + +// Filters returns the list of DENY net.IPNet masks. For backwards compatibility. +// +// A copy of the filters is made prior to returning, so the inner state is not exposed. +// +// Deprecated: Use FiltersForAction(). +func (fs *Filters) Filters() (result []*net.IPNet) { + ffa := fs.FiltersForAction(ActionDeny) + for _, res := range ffa { + res := res // allocate a new copy + result = append(result, &res) + } + return result +} + +func (fs *Filters) ActionForFilter(ipnet net.IPNet) (action Action, ok bool) { + if _, f := fs.find(ipnet); f != nil { + return f.action, true + } + return ActionNone, false +} + +// FiltersForAction returns the filters associated with the indicated action. +func (fs *Filters) FiltersForAction(action Action) (result []net.IPNet) { + fs.mu.RLock() + defer fs.mu.RUnlock() + + for _, ff := range fs.filters { + if ff.action == action { + result = append(result, ff.f) + } + } + return result +} diff --git a/vendor/github.com/libp2p/go-maddr-filter/go.mod b/vendor/github.com/libp2p/go-maddr-filter/go.mod new file mode 100644 index 00000000..4adb057d --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/go.mod @@ -0,0 +1,6 @@ +module github.com/libp2p/go-maddr-filter + +require ( + github.com/multiformats/go-multiaddr v0.0.1 + github.com/multiformats/go-multiaddr-net v0.0.1 +) diff --git a/vendor/github.com/libp2p/go-maddr-filter/go.sum b/vendor/github.com/libp2p/go-maddr-filter/go.sum new file mode 100644 index 00000000..11cfae50 --- /dev/null +++ b/vendor/github.com/libp2p/go-maddr-filter/go.sum @@ -0,0 +1,22 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/libp2p/go-mplex/.travis.yml b/vendor/github.com/libp2p/go-mplex/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-mplex/LICENSE b/vendor/github.com/libp2p/go-mplex/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-mplex/README.md b/vendor/github.com/libp2p/go-mplex/README.md new file mode 100644 index 00000000..ff7cc708 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/README.md @@ -0,0 +1,26 @@ +# go-mplex + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +A super simple [stream muxing](https://docs.libp2p.io/concepts/stream-multiplexing/) library implementing [mplex](https://github.com/libp2p/specs/tree/master/mplex). + +## Usage + +```go +mplex := multiplex.NewMultiplex(mysocket) + +s, _ := mplex.NewStream() +s.Write([]byte("Hello World!")) +s.Close() + +os, _ := mplex.Accept() +// echo back everything received +io.Copy(os, os) +``` + +--- + +The last gx published version of this module was: 0.2.35: QmWGQQ6Tz8AdUpxktLf3zgnVN9Vy8fcWVezZJSU3ZmiANj diff --git a/vendor/github.com/libp2p/go-mplex/codecov.yml b/vendor/github.com/libp2p/go-mplex/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-mplex/deadline.go b/vendor/github.com/libp2p/go-mplex/deadline.go new file mode 100644 index 00000000..dd2dfaf9 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/deadline.go @@ -0,0 +1,80 @@ +// Copied from the go standard library. +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE-BSD file. + +package multiplex + +import ( + "sync" + "time" +) + +// pipeDeadline is an abstraction for handling timeouts. +type pipeDeadline struct { + mu sync.Mutex // Guards timer and cancel + timer *time.Timer + cancel chan struct{} // Must be non-nil +} + +func makePipeDeadline() pipeDeadline { + return pipeDeadline{cancel: make(chan struct{})} +} + +// set sets the point in time when the deadline will time out. +// A timeout event is signaled by closing the channel returned by waiter. +// Once a timeout has occurred, the deadline can be refreshed by specifying a +// t value in the future. +// +// A zero value for t prevents timeout. +func (d *pipeDeadline) set(t time.Time) { + d.mu.Lock() + defer d.mu.Unlock() + + if d.timer != nil && !d.timer.Stop() { + <-d.cancel // Wait for the timer callback to finish and close cancel + } + d.timer = nil + + // Time is zero, then there is no deadline. + closed := isClosedChan(d.cancel) + if t.IsZero() { + if closed { + d.cancel = make(chan struct{}) + } + return + } + + // Time in the future, setup a timer to cancel in the future. + if dur := time.Until(t); dur > 0 { + if closed { + d.cancel = make(chan struct{}) + } + d.timer = time.AfterFunc(dur, func() { + close(d.cancel) + }) + return + } + + // Time in the past, so close immediately. + if !closed { + close(d.cancel) + } +} + +// wait returns a channel that is closed when the deadline is exceeded. +func (d *pipeDeadline) wait() chan struct{} { + d.mu.Lock() + defer d.mu.Unlock() + return d.cancel +} + +func isClosedChan(c <-chan struct{}) bool { + select { + case <-c: + return true + default: + return false + } +} diff --git a/vendor/github.com/libp2p/go-mplex/go.mod b/vendor/github.com/libp2p/go-mplex/go.mod new file mode 100644 index 00000000..8f9939fc --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/go.mod @@ -0,0 +1,7 @@ +module github.com/libp2p/go-mplex + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 +) diff --git a/vendor/github.com/libp2p/go-mplex/go.sum b/vendor/github.com/libp2p/go-mplex/go.sum new file mode 100644 index 00000000..09699363 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/go.sum @@ -0,0 +1,77 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-mplex/multiplex.go b/vendor/github.com/libp2p/go-mplex/multiplex.go new file mode 100644 index 00000000..1c75baa7 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/multiplex.go @@ -0,0 +1,591 @@ +package multiplex + +import ( + "bufio" + "context" + "encoding/binary" + "errors" + "fmt" + "io" + "net" + "sync" + "time" + + logging "github.com/ipfs/go-log" + pool "github.com/libp2p/go-buffer-pool" +) + +var log = logging.Logger("mplex") + +var MaxMessageSize = 1 << 20 + +// Max time to block waiting for a slow reader to read from a stream before +// resetting it. Preferably, we'd have some form of back-pressure mechanism but +// we don't have that in this protocol. +var ReceiveTimeout = 5 * time.Second + +// ErrShutdown is returned when operating on a shutdown session +var ErrShutdown = errors.New("session shut down") + +// ErrTwoInitiators is returned when both sides think they're the initiator +var ErrTwoInitiators = errors.New("two initiators") + +// ErrInvalidState is returned when the other side does something it shouldn't. +// In this case, we close the connection to be safe. +var ErrInvalidState = errors.New("received an unexpected message from the peer") + +var errTimeout = timeout{} +var errStreamClosed = errors.New("stream closed") + +var ( + NewStreamTimeout = time.Minute + ResetStreamTimeout = 2 * time.Minute + + WriteCoalesceDelay = 100 * time.Microsecond +) + +type timeout struct{} + +func (_ timeout) Error() string { + return "i/o deadline exceeded" +} + +func (_ timeout) Temporary() bool { + return true +} + +func (_ timeout) Timeout() bool { + return true +} + +// +1 for initiator +const ( + newStreamTag = 0 + messageTag = 2 + closeTag = 4 + resetTag = 6 +) + +// Multiplex is a mplex session. +type Multiplex struct { + con net.Conn + buf *bufio.Reader + nextID uint64 + initiator bool + + closed chan struct{} + shutdown chan struct{} + shutdownErr error + shutdownLock sync.Mutex + + writeCh chan []byte + writeTimer *time.Timer + writeTimerFired bool + + nstreams chan *Stream + + channels map[streamID]*Stream + chLock sync.Mutex +} + +// NewMultiplex creates a new multiplexer session. +func NewMultiplex(con net.Conn, initiator bool) *Multiplex { + mp := &Multiplex{ + con: con, + initiator: initiator, + buf: bufio.NewReader(con), + channels: make(map[streamID]*Stream), + closed: make(chan struct{}), + shutdown: make(chan struct{}), + writeCh: make(chan []byte, 16), + writeTimer: time.NewTimer(0), + nstreams: make(chan *Stream, 16), + } + + go mp.handleIncoming() + go mp.handleOutgoing() + + return mp +} + +func (mp *Multiplex) newStream(id streamID, name string) (s *Stream) { + s = &Stream{ + id: id, + name: name, + dataIn: make(chan []byte, 8), + reset: make(chan struct{}), + rDeadline: makePipeDeadline(), + wDeadline: makePipeDeadline(), + mp: mp, + } + + s.closedLocal, s.doCloseLocal = context.WithCancel(context.Background()) + return +} + +// Accept accepts the next stream from the connection. +func (m *Multiplex) Accept() (*Stream, error) { + select { + case s, ok := <-m.nstreams: + if !ok { + return nil, errors.New("multiplex closed") + } + return s, nil + case <-m.closed: + return nil, m.shutdownErr + } +} + +// Close closes the session. +func (mp *Multiplex) Close() error { + mp.closeNoWait() + + // Wait for the receive loop to finish. + <-mp.closed + + return nil +} + +func (mp *Multiplex) closeNoWait() { + mp.shutdownLock.Lock() + select { + case <-mp.shutdown: + default: + mp.con.Close() + close(mp.shutdown) + } + mp.shutdownLock.Unlock() +} + +// IsClosed returns true if the session is closed. +func (mp *Multiplex) IsClosed() bool { + select { + case <-mp.closed: + return true + default: + return false + } +} + +func (mp *Multiplex) sendMsg(done <-chan struct{}, header uint64, data []byte) error { + buf := pool.Get(len(data) + 20) + + n := 0 + n += binary.PutUvarint(buf[n:], header) + n += binary.PutUvarint(buf[n:], uint64(len(data))) + n += copy(buf[n:], data) + + select { + case mp.writeCh <- buf[:n]: + return nil + case <-mp.shutdown: + return ErrShutdown + case <-done: + return errTimeout + } +} + +func (mp *Multiplex) handleOutgoing() { + for { + select { + case <-mp.shutdown: + return + + case data := <-mp.writeCh: + // FIXME: https://github.com/libp2p/go-libp2p/issues/644 + // write coalescing disabled until this can be fixed. + //err := mp.writeMsg(data) + err := mp.doWriteMsg(data) + pool.Put(data) + if err != nil { + // the connection is closed by this time + log.Warningf("error writing data: %s", err.Error()) + return + } + } + } +} + +func (mp *Multiplex) writeMsg(data []byte) error { + if len(data) >= 512 { + err := mp.doWriteMsg(data) + pool.Put(data) + return err + } + + buf := pool.Get(4096) + defer pool.Put(buf) + + n := copy(buf, data) + pool.Put(data) + + if !mp.writeTimerFired { + if !mp.writeTimer.Stop() { + <-mp.writeTimer.C + } + } + mp.writeTimer.Reset(WriteCoalesceDelay) + mp.writeTimerFired = false + + for { + select { + case data = <-mp.writeCh: + wr := copy(buf[n:], data) + if wr < len(data) { + // we filled the buffer, send it + err := mp.doWriteMsg(buf) + if err != nil { + pool.Put(data) + return err + } + + if len(data)-wr >= 512 { + // the remaining data is not a small write, send it + err := mp.doWriteMsg(data[wr:]) + pool.Put(data) + return err + } + + n = copy(buf, data[wr:]) + + // we've written some, reset the timer to coalesce the rest + if !mp.writeTimer.Stop() { + <-mp.writeTimer.C + } + mp.writeTimer.Reset(WriteCoalesceDelay) + } else { + n += wr + } + + pool.Put(data) + + case <-mp.writeTimer.C: + mp.writeTimerFired = true + return mp.doWriteMsg(buf[:n]) + + case <-mp.shutdown: + return ErrShutdown + } + } +} + +func (mp *Multiplex) doWriteMsg(data []byte) error { + if mp.isShutdown() { + return ErrShutdown + } + + _, err := mp.con.Write(data) + if err != nil { + mp.closeNoWait() + } + + return err +} + +func (mp *Multiplex) nextChanID() uint64 { + out := mp.nextID + mp.nextID++ + return out +} + +// NewStream creates a new stream. +func (mp *Multiplex) NewStream() (*Stream, error) { + return mp.NewNamedStream("") +} + +// NewNamedStream creates a new named stream. +func (mp *Multiplex) NewNamedStream(name string) (*Stream, error) { + mp.chLock.Lock() + + // We could call IsClosed but this is faster (given that we already have + // the lock). + if mp.channels == nil { + mp.chLock.Unlock() + return nil, ErrShutdown + } + + sid := mp.nextChanID() + header := (sid << 3) | newStreamTag + + if name == "" { + name = fmt.Sprint(sid) + } + s := mp.newStream(streamID{ + id: sid, + initiator: true, + }, name) + mp.channels[s.id] = s + mp.chLock.Unlock() + + ctx, cancel := context.WithTimeout(context.Background(), NewStreamTimeout) + defer cancel() + + err := mp.sendMsg(ctx.Done(), header, []byte(name)) + if err != nil { + return nil, err + } + + return s, nil +} + +func (mp *Multiplex) cleanup() { + mp.closeNoWait() + mp.chLock.Lock() + defer mp.chLock.Unlock() + for _, msch := range mp.channels { + msch.clLock.Lock() + if !msch.closedRemote { + msch.closedRemote = true + // Cancel readers + close(msch.reset) + } + + msch.doCloseLocal() + msch.clLock.Unlock() + } + // Don't remove this nil assignment. We check if this is nil to check if + // the connection is closed when we already have the lock (faster than + // checking if the stream is closed). + mp.channels = nil + if mp.shutdownErr == nil { + mp.shutdownErr = ErrShutdown + } + close(mp.closed) +} + +func (mp *Multiplex) handleIncoming() { + defer mp.cleanup() + + recvTimeout := time.NewTimer(0) + defer recvTimeout.Stop() + + if !recvTimeout.Stop() { + <-recvTimeout.C + } + + for { + chID, tag, err := mp.readNextHeader() + if err != nil { + mp.shutdownErr = err + return + } + + remoteIsInitiator := tag&1 == 0 + ch := streamID{ + // true if *I'm* the initiator. + initiator: !remoteIsInitiator, + id: chID, + } + // Rounds up the tag: + // 0 -> 0 + // 1 -> 2 + // 2 -> 2 + // 3 -> 4 + // etc... + tag += (tag & 1) + + b, err := mp.readNext() + if err != nil { + mp.shutdownErr = err + return + } + + mp.chLock.Lock() + msch, ok := mp.channels[ch] + mp.chLock.Unlock() + + switch tag { + case newStreamTag: + if ok { + log.Debugf("received NewStream message for existing stream: %d", ch) + mp.shutdownErr = ErrInvalidState + return + } + + name := string(b) + pool.Put(b) + + msch = mp.newStream(ch, name) + mp.chLock.Lock() + mp.channels[ch] = msch + mp.chLock.Unlock() + select { + case mp.nstreams <- msch: + case <-mp.shutdown: + return + } + + case resetTag: + if !ok { + // This is *ok*. We forget the stream on reset. + continue + } + msch.clLock.Lock() + + isClosed := msch.isClosed() + + if !msch.closedRemote { + close(msch.reset) + msch.closedRemote = true + } + + if !isClosed { + msch.doCloseLocal() + } + + msch.clLock.Unlock() + + msch.cancelDeadlines() + + mp.chLock.Lock() + delete(mp.channels, ch) + mp.chLock.Unlock() + case closeTag: + if !ok { + continue + } + + msch.clLock.Lock() + + if msch.closedRemote { + msch.clLock.Unlock() + // Technically a bug on the other side. We + // should consider killing the connection. + continue + } + + close(msch.dataIn) + msch.closedRemote = true + + cleanup := msch.isClosed() + + msch.clLock.Unlock() + + if cleanup { + msch.cancelDeadlines() + mp.chLock.Lock() + delete(mp.channels, ch) + mp.chLock.Unlock() + } + case messageTag: + if !ok { + // reset stream, return b + pool.Put(b) + + // This is a perfectly valid case when we reset + // and forget about the stream. + log.Debugf("message for non-existant stream, dropping data: %d", ch) + // go mp.sendResetMsg(ch.header(resetTag), false) + continue + } + + msch.clLock.Lock() + remoteClosed := msch.closedRemote + msch.clLock.Unlock() + if remoteClosed { + // closed stream, return b + pool.Put(b) + + log.Warningf("Received data from remote after stream was closed by them. (len = %d)", len(b)) + // go mp.sendResetMsg(msch.id.header(resetTag), false) + continue + } + + recvTimeout.Reset(ReceiveTimeout) + select { + case msch.dataIn <- b: + case <-msch.reset: + pool.Put(b) + case <-recvTimeout.C: + pool.Put(b) + log.Warningf("timed out receiving message into stream queue.") + // Do not do this asynchronously. Otherwise, we + // could drop a message, then receive a message, + // then reset. + msch.Reset() + continue + case <-mp.shutdown: + pool.Put(b) + return + } + if !recvTimeout.Stop() { + <-recvTimeout.C + } + default: + log.Debugf("message with unknown header on stream %s", ch) + if ok { + msch.Reset() + } + } + } +} + +func (mp *Multiplex) isShutdown() bool { + select { + case <-mp.shutdown: + return true + default: + return false + } +} + +func (mp *Multiplex) sendResetMsg(header uint64, hard bool) { + ctx, cancel := context.WithTimeout(context.Background(), ResetStreamTimeout) + defer cancel() + + err := mp.sendMsg(ctx.Done(), header, nil) + if err != nil && !mp.isShutdown() { + if hard { + log.Warningf("error sending reset message: %s; killing connection", err.Error()) + mp.Close() + } else { + log.Debugf("error sending reset message: %s", err.Error()) + } + } +} + +func (mp *Multiplex) readNextHeader() (uint64, uint64, error) { + h, err := binary.ReadUvarint(mp.buf) + if err != nil { + return 0, 0, err + } + + // get channel ID + ch := h >> 3 + + rem := h & 7 + + return ch, rem, nil +} + +func (mp *Multiplex) readNext() ([]byte, error) { + // get length + l, err := binary.ReadUvarint(mp.buf) + if err != nil { + return nil, err + } + + if l > uint64(MaxMessageSize) { + return nil, fmt.Errorf("message size too large!") + } + + if l == 0 { + return nil, nil + } + + buf := pool.Get(int(l)) + n, err := io.ReadFull(mp.buf, buf) + if err != nil { + return nil, err + } + + return buf[:n], nil +} + +func isFatalNetworkError(err error) bool { + nerr, ok := err.(net.Error) + if ok { + return !(nerr.Timeout() || nerr.Temporary()) + } + return false +} diff --git a/vendor/github.com/libp2p/go-mplex/stream.go b/vendor/github.com/libp2p/go-mplex/stream.go new file mode 100644 index 00000000..4004ed12 --- /dev/null +++ b/vendor/github.com/libp2p/go-mplex/stream.go @@ -0,0 +1,292 @@ +package multiplex + +import ( + "context" + "errors" + "io" + "sync" + "time" + + "github.com/libp2p/go-libp2p-core/mux" + + pool "github.com/libp2p/go-buffer-pool" +) + +// streamID is a convenience type for operating on stream IDs +type streamID struct { + id uint64 + initiator bool +} + +// header computes the header for the given tag +func (id *streamID) header(tag uint64) uint64 { + header := id.id<<3 | tag + if !id.initiator { + header-- + } + return header +} + +type Stream struct { + id streamID + name string + dataIn chan []byte + mp *Multiplex + + extra []byte + + // exbuf is for holding the reference to the beginning of the extra slice + // for later memory pool freeing + exbuf []byte + + rDeadline, wDeadline pipeDeadline + + clLock sync.Mutex + closedRemote bool + + // Closed when the connection is reset. + reset chan struct{} + + // Closed when the writer is closed (reset will also be closed) + closedLocal context.Context + doCloseLocal context.CancelFunc +} + +func (s *Stream) Name() string { + return s.name +} + +// tries to preload pending data +func (s *Stream) preloadData() { + select { + case read, ok := <-s.dataIn: + if !ok { + return + } + s.extra = read + s.exbuf = read + default: + } +} + +func (s *Stream) waitForData() error { + select { + case <-s.reset: + // This is the only place where it's safe to return these. + s.returnBuffers() + return mux.ErrReset + case read, ok := <-s.dataIn: + if !ok { + return io.EOF + } + s.extra = read + s.exbuf = read + return nil + case <-s.rDeadline.wait(): + return errTimeout + } +} + +func (s *Stream) returnBuffers() { + if s.exbuf != nil { + pool.Put(s.exbuf) + s.exbuf = nil + s.extra = nil + } + for { + select { + case read, ok := <-s.dataIn: + if !ok { + return + } + if read == nil { + continue + } + pool.Put(read) + default: + return + } + } +} + +func (s *Stream) Read(b []byte) (int, error) { + select { + case <-s.reset: + return 0, mux.ErrReset + default: + } + if s.extra == nil { + err := s.waitForData() + if err != nil { + return 0, err + } + } + n := 0 + for s.extra != nil && n < len(b) { + read := copy(b[n:], s.extra) + n += read + if read < len(s.extra) { + s.extra = s.extra[read:] + } else { + if s.exbuf != nil { + pool.Put(s.exbuf) + } + s.extra = nil + s.exbuf = nil + s.preloadData() + } + } + return n, nil +} + +func (s *Stream) Write(b []byte) (int, error) { + var written int + for written < len(b) { + wl := len(b) - written + if wl > MaxMessageSize { + wl = MaxMessageSize + } + + n, err := s.write(b[written : written+wl]) + if err != nil { + return written, err + } + + written += n + } + + return written, nil +} + +func (s *Stream) write(b []byte) (int, error) { + if s.isClosed() { + return 0, errors.New("cannot write to closed stream") + } + + err := s.mp.sendMsg(s.wDeadline.wait(), s.id.header(messageTag), b) + + if err != nil { + if err == context.Canceled { + err = errors.New("cannot write to closed stream") + } + return 0, err + } + + return len(b), nil +} + +func (s *Stream) isClosed() bool { + return s.closedLocal.Err() != nil +} + +func (s *Stream) Close() error { + ctx, cancel := context.WithTimeout(context.Background(), ResetStreamTimeout) + defer cancel() + + err := s.mp.sendMsg(ctx.Done(), s.id.header(closeTag), nil) + + if s.isClosed() { + return nil + } + + s.clLock.Lock() + remote := s.closedRemote + s.clLock.Unlock() + + s.doCloseLocal() + + if remote { + s.cancelDeadlines() + s.mp.chLock.Lock() + delete(s.mp.channels, s.id) + s.mp.chLock.Unlock() + } + + if err != nil && !s.mp.isShutdown() { + log.Warningf("Error closing stream: %s; killing connection", err.Error()) + s.mp.Close() + } + + return err +} + +func (s *Stream) Reset() error { + s.clLock.Lock() + + // Don't reset when fully closed. + if s.closedRemote && s.isClosed() { + s.clLock.Unlock() + return nil + } + + // Don't reset twice. + select { + case <-s.reset: + s.clLock.Unlock() + return nil + default: + } + + close(s.reset) + s.doCloseLocal() + s.closedRemote = true + s.cancelDeadlines() + + go s.mp.sendResetMsg(s.id.header(resetTag), true) + + s.clLock.Unlock() + + s.mp.chLock.Lock() + delete(s.mp.channels, s.id) + s.mp.chLock.Unlock() + + return nil +} + +func (s *Stream) cancelDeadlines() { + s.rDeadline.set(time.Time{}) + s.wDeadline.set(time.Time{}) +} + +func (s *Stream) SetDeadline(t time.Time) error { + s.clLock.Lock() + defer s.clLock.Unlock() + + if s.closedRemote && s.isClosed() { + return errStreamClosed + } + + if !s.closedRemote { + s.rDeadline.set(t) + } + + if !s.isClosed() { + s.wDeadline.set(t) + } + + return nil +} + +func (s *Stream) SetReadDeadline(t time.Time) error { + s.clLock.Lock() + defer s.clLock.Unlock() + + if s.closedRemote { + return errStreamClosed + } + + s.rDeadline.set(t) + return nil +} + +func (s *Stream) SetWriteDeadline(t time.Time) error { + s.clLock.Lock() + defer s.clLock.Unlock() + + if s.isClosed() { + return errStreamClosed + } + + s.wDeadline.set(t) + return nil +} diff --git a/vendor/github.com/libp2p/go-msgio/.gxignore b/vendor/github.com/libp2p/go-msgio/.gxignore new file mode 100644 index 00000000..39217cdd --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/.gxignore @@ -0,0 +1 @@ +Godeps/* \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-msgio/.travis.yml b/vendor/github.com/libp2p/go-msgio/.travis.yml new file mode 100644 index 00000000..b86c124d --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race -cpu=5" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-msgio/LICENSE b/vendor/github.com/libp2p/go-msgio/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-msgio/README.md b/vendor/github.com/libp2p/go-msgio/README.md new file mode 100644 index 00000000..c2196ec5 --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/README.md @@ -0,0 +1,89 @@ +# go-msgio - Message IO + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![codecov](https://codecov.io/gh/libp2p/go-libp2p-netutil/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-msgio) +[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-netutil.svg?branch=master)](https://travis-ci.org/libp2p/go-msgio) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) + +This is a simple package that helps read and write length-delimited slices. It's helpful for building wire protocols. + +## Usage + +### Reading + +```go +import "github.com/libp2p/go-msgio" +rdr := ... // some reader from a wire +mrdr := msgio.NewReader(rdr) + +for { + msg, err := mrdr.ReadMsg() + if err != nil { + return err + } + + doSomething(msg) +} +``` + +### Writing + +```go +import "github.com/libp2p/go-msgio" +wtr := genReader() +mwtr := msgio.NewWriter(wtr) + +for { + msg := genMessage() + err := mwtr.WriteMsg(msg) + if err != nil { + return err + } +} +``` + +### Duplex + +```go +import "github.com/libp2p/go-msgio" +rw := genReadWriter() +mrw := msgio.NewReadWriter(rw) + +for { + msg, err := mrdr.ReadMsg() + if err != nil { + return err + } + + // echo it back :) + err = mwtr.WriteMsg(msg) + if err != nil { + return err + } +} +``` + +### Channels + +```go +import "github.com/libp2p/go-msgio" +rw := genReadWriter() +rch := msgio.NewReadChannel(rw) +wch := msgio.NewWriteChannel(rw) + +for { + msg, err := <-rch + if err != nil { + return err + } + + // echo it back :) + wch<- rw +} +``` + +--- + +The last gx published version of this module was: 0.0.6: QmcxL9MDzSU5Mj1GcWZD8CXkAFuJXjdbjotZ93o371bKSf diff --git a/vendor/github.com/libp2p/go-msgio/chan.go b/vendor/github.com/libp2p/go-msgio/chan.go new file mode 100644 index 00000000..571393c1 --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/chan.go @@ -0,0 +1,109 @@ +package msgio + +import ( + "io" + + pool "github.com/libp2p/go-buffer-pool" +) + +// Chan is a msgio duplex channel. It is used to have a channel interface +// around a msgio.Reader or Writer. +type Chan struct { + MsgChan chan []byte + ErrChan chan error + CloseChan chan bool +} + +// NewChan constructs a Chan with a given buffer size. +func NewChan(chanSize int) *Chan { + return &Chan{ + MsgChan: make(chan []byte, chanSize), + ErrChan: make(chan error, 1), + CloseChan: make(chan bool, 2), + } +} + +// ReadFrom wraps the given io.Reader with a msgio.Reader, reads all +// messages, ands sends them down the channel. +func (s *Chan) ReadFrom(r io.Reader) { + s.readFrom(NewReader(r)) +} + +// ReadFromWithPool wraps the given io.Reader with a msgio.Reader, reads all +// messages, ands sends them down the channel. Uses given BufferPool. +func (s *Chan) ReadFromWithPool(r io.Reader, p *pool.BufferPool) { + s.readFrom(NewReaderWithPool(r, p)) +} + +// ReadFrom wraps the given io.Reader with a msgio.Reader, reads all +// messages, ands sends them down the channel. +func (s *Chan) readFrom(mr Reader) { +Loop: + for { + buf, err := mr.ReadMsg() + if err != nil { + if err == io.EOF { + break Loop // done + } + + // unexpected error. tell the client. + s.ErrChan <- err + break Loop + } + + select { + case <-s.CloseChan: + break Loop // told we're done + case s.MsgChan <- buf: + // ok seems fine. send it away + } + } + + close(s.MsgChan) + // signal we're done + s.CloseChan <- true +} + +// WriteTo wraps the given io.Writer with a msgio.Writer, listens on the +// channel and writes all messages to the writer. +func (s *Chan) WriteTo(w io.Writer) { + // new buffer per message + // if bottleneck, cycle around a set of buffers + mw := NewWriter(w) + +Loop: + for { + select { + case <-s.CloseChan: + break Loop // told we're done + + case msg, ok := <-s.MsgChan: + if !ok { // chan closed + break Loop + } + + if err := mw.WriteMsg(msg); err != nil { + if err != io.EOF { + // unexpected error. tell the client. + s.ErrChan <- err + } + + break Loop + } + } + } + + // signal we're done + s.CloseChan <- true +} + +// Close the Chan +func (s *Chan) Close() { + s.CloseChan <- true +} + +// nullLocker conforms to the sync.Locker interface but does nothing. +type nullLocker struct{} + +func (l *nullLocker) Lock() {} +func (l *nullLocker) Unlock() {} diff --git a/vendor/github.com/libp2p/go-msgio/codecov.yml b/vendor/github.com/libp2p/go-msgio/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-msgio/fuzz.go b/vendor/github.com/libp2p/go-msgio/fuzz.go new file mode 100644 index 00000000..055abdbb --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/fuzz.go @@ -0,0 +1,23 @@ +// +build gofuzz + +package msgio + +import "bytes" + +// get the go-fuzz tools and build a fuzzer +// $ go get -u github.com/dvyukov/go-fuzz/... +// $ go-fuzz-build github.com/libp2p/go-msgio + +// put a corpus of random (even better if actual, structured) data in a corpus directry +// $ go-fuzz -bin ./msgio-fuzz -corpus corpus -workdir=wdir -timeout=15 + +func Fuzz(data []byte) int { + rc := NewReader(bytes.NewReader(data)) + // rc := NewVarintReader(bytes.NewReader(data)) + + if _, err := rc.ReadMsg(); err != nil { + return 0 + } + + return 1 +} diff --git a/vendor/github.com/libp2p/go-msgio/go.mod b/vendor/github.com/libp2p/go-msgio/go.mod new file mode 100644 index 00000000..dff70980 --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/go.mod @@ -0,0 +1,3 @@ +module github.com/libp2p/go-msgio + +require github.com/libp2p/go-buffer-pool v0.0.1 diff --git a/vendor/github.com/libp2p/go-msgio/go.sum b/vendor/github.com/libp2p/go-msgio/go.sum new file mode 100644 index 00000000..f65bc04e --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/go.sum @@ -0,0 +1,2 @@ +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= diff --git a/vendor/github.com/libp2p/go-msgio/limit.go b/vendor/github.com/libp2p/go-msgio/limit.go new file mode 100644 index 00000000..bce33cff --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/limit.go @@ -0,0 +1,45 @@ +package msgio + +import ( + "bytes" + "io" + "sync" +) + +// LimitedReader wraps an io.Reader with a msgio framed reader. The LimitedReader +// will return a reader which will io.EOF when the msg length is done. +func LimitedReader(r io.Reader) (io.Reader, error) { + l, err := ReadLen(r, nil) + return io.LimitReader(r, int64(l)), err +} + +// LimitedWriter wraps an io.Writer with a msgio framed writer. It is the inverse +// of LimitedReader: it will buffer all writes until "Flush" is called. When Flush +// is called, it will write the size of the buffer first, flush the buffer, reset +// the buffer, and begin accept more incoming writes. +func NewLimitedWriter(w io.Writer) *LimitedWriter { + return &LimitedWriter{W: w} +} + +type LimitedWriter struct { + W io.Writer + B bytes.Buffer + M sync.Mutex +} + +func (w *LimitedWriter) Write(buf []byte) (n int, err error) { + w.M.Lock() + n, err = w.B.Write(buf) + w.M.Unlock() + return n, err +} + +func (w *LimitedWriter) Flush() error { + w.M.Lock() + defer w.M.Unlock() + if err := WriteLen(w.W, w.B.Len()); err != nil { + return err + } + _, err := w.B.WriteTo(w.W) + return err +} diff --git a/vendor/github.com/libp2p/go-msgio/msgio.go b/vendor/github.com/libp2p/go-msgio/msgio.go new file mode 100644 index 00000000..5e61142c --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/msgio.go @@ -0,0 +1,305 @@ +package msgio + +import ( + "errors" + "io" + "sync" + + pool "github.com/libp2p/go-buffer-pool" +) + +// ErrMsgTooLarge is returned when the message length is exessive +var ErrMsgTooLarge = errors.New("message too large") + +const ( + lengthSize = 4 + defaultMaxSize = 8 * 1024 * 1024 // 8mb +) + +// Writer is the msgio Writer interface. It writes len-framed messages. +type Writer interface { + + // Write writes passed in buffer as a single message. + Write([]byte) (int, error) + + // WriteMsg writes the msg in the passed in buffer. + WriteMsg([]byte) error +} + +// WriteCloser is a Writer + Closer interface. Like in `golang/pkg/io` +type WriteCloser interface { + Writer + io.Closer +} + +// Reader is the msgio Reader interface. It reads len-framed messages. +type Reader interface { + + // Read reads the next message from the Reader. + // The client must pass a buffer large enough, or io.ErrShortBuffer will be + // returned. + Read([]byte) (int, error) + + // ReadMsg reads the next message from the Reader. + // Uses a pool.BufferPool internally to reuse buffers. User may call + // ReleaseMsg(msg) to signal a buffer can be reused. + ReadMsg() ([]byte, error) + + // ReleaseMsg signals a buffer can be reused. + ReleaseMsg([]byte) + + // NextMsgLen returns the length of the next (peeked) message. Does + // not destroy the message or have other adverse effects + NextMsgLen() (int, error) +} + +// ReadCloser combines a Reader and Closer. +type ReadCloser interface { + Reader + io.Closer +} + +// ReadWriter combines a Reader and Writer. +type ReadWriter interface { + Reader + Writer +} + +// ReadWriteCloser combines a Reader, a Writer, and Closer. +type ReadWriteCloser interface { + Reader + Writer + io.Closer +} + +// writer is the underlying type that implements the Writer interface. +type writer struct { + W io.Writer + + pool *pool.BufferPool + lock sync.Mutex +} + +// NewWriter wraps an io.Writer with a msgio framed writer. The msgio.Writer +// will write the length prefix of every message written. +func NewWriter(w io.Writer) WriteCloser { + return NewWriterWithPool(w, pool.GlobalPool) +} + +// NewWriterWithPool is identical to NewWriter but allows the user to pass a +// custom buffer pool. +func NewWriterWithPool(w io.Writer, p *pool.BufferPool) WriteCloser { + return &writer{W: w, pool: p} +} + +func (s *writer) Write(msg []byte) (int, error) { + err := s.WriteMsg(msg) + if err != nil { + return 0, err + } + return len(msg), nil +} + +func (s *writer) WriteMsg(msg []byte) (err error) { + s.lock.Lock() + defer s.lock.Unlock() + + buf := s.pool.Get(len(msg) + lengthSize) + NBO.PutUint32(buf, uint32(len(msg))) + copy(buf[lengthSize:], msg) + _, err = s.W.Write(buf) + s.pool.Put(buf) + + return err +} + +func (s *writer) Close() error { + if c, ok := s.W.(io.Closer); ok { + return c.Close() + } + return nil +} + +// reader is the underlying type that implements the Reader interface. +type reader struct { + R io.Reader + + lbuf [lengthSize]byte + next int + pool *pool.BufferPool + lock sync.Mutex + max int // the maximal message size (in bytes) this reader handles +} + +// NewReader wraps an io.Reader with a msgio framed reader. The msgio.Reader +// will read whole messages at a time (using the length). Assumes an equivalent +// writer on the other side. +func NewReader(r io.Reader) ReadCloser { + return NewReaderWithPool(r, pool.GlobalPool) +} + +// NewReaderSize is equivalent to NewReader but allows one to +// specify a max message size. +func NewReaderSize(r io.Reader, maxMessageSize int) ReadCloser { + return NewReaderSizeWithPool(r, maxMessageSize, pool.GlobalPool) +} + +// NewReaderWithPool is the same as NewReader but allows one to specify a buffer +// pool. +func NewReaderWithPool(r io.Reader, p *pool.BufferPool) ReadCloser { + return NewReaderSizeWithPool(r, defaultMaxSize, p) +} + +// NewReaderWithPool is the same as NewReader but allows one to specify a buffer +// pool and a max message size. +func NewReaderSizeWithPool(r io.Reader, maxMessageSize int, p *pool.BufferPool) ReadCloser { + if p == nil { + panic("nil pool") + } + return &reader{ + R: r, + next: -1, + pool: p, + max: maxMessageSize, + } +} + +// NextMsgLen reads the length of the next msg into s.lbuf, and returns it. +// WARNING: like Read, NextMsgLen is destructive. It reads from the internal +// reader. +func (s *reader) NextMsgLen() (int, error) { + s.lock.Lock() + defer s.lock.Unlock() + return s.nextMsgLen() +} + +func (s *reader) nextMsgLen() (int, error) { + if s.next == -1 { + n, err := ReadLen(s.R, s.lbuf[:]) + if err != nil { + return 0, err + } + + s.next = n + } + return s.next, nil +} + +func (s *reader) Read(msg []byte) (int, error) { + s.lock.Lock() + defer s.lock.Unlock() + + length, err := s.nextMsgLen() + if err != nil { + return 0, err + } + + if length > len(msg) { + return 0, io.ErrShortBuffer + } + + read, err := io.ReadFull(s.R, msg[:length]) + if read < length { + s.next = length - read // we only partially consumed the message. + } else { + s.next = -1 // signal we've consumed this msg + } + return read, err +} + +func (s *reader) ReadMsg() ([]byte, error) { + s.lock.Lock() + defer s.lock.Unlock() + + length, err := s.nextMsgLen() + if err != nil { + return nil, err + } + + if length == 0 { + s.next = -1 + return nil, nil + } + + if length > s.max || length < 0 { + return nil, ErrMsgTooLarge + } + + msg := s.pool.Get(length) + read, err := io.ReadFull(s.R, msg) + if read < length { + s.next = length - read // we only partially consumed the message. + } else { + s.next = -1 // signal we've consumed this msg + } + return msg[:read], err +} + +func (s *reader) ReleaseMsg(msg []byte) { + s.pool.Put(msg) +} + +func (s *reader) Close() error { + if c, ok := s.R.(io.Closer); ok { + return c.Close() + } + return nil +} + +// readWriter is the underlying type that implements a ReadWriter. +type readWriter struct { + Reader + Writer +} + +// NewReadWriter wraps an io.ReadWriter with a msgio.ReadWriter. Writing +// and Reading will be appropriately framed. +func NewReadWriter(rw io.ReadWriter) ReadWriteCloser { + return &readWriter{ + Reader: NewReader(rw), + Writer: NewWriter(rw), + } +} + +// Combine wraps a pair of msgio.Writer and msgio.Reader with a msgio.ReadWriter. +func Combine(w Writer, r Reader) ReadWriteCloser { + return &readWriter{Reader: r, Writer: w} +} + +func (rw *readWriter) Close() error { + var errs []error + + if w, ok := rw.Writer.(WriteCloser); ok { + if err := w.Close(); err != nil { + errs = append(errs, err) + } + } + if r, ok := rw.Reader.(ReadCloser); ok { + if err := r.Close(); err != nil { + errs = append(errs, err) + } + } + + if len(errs) > 0 { + return multiErr(errs) + } + return nil +} + +// multiErr is a util to return multiple errors +type multiErr []error + +func (m multiErr) Error() string { + if len(m) == 0 { + return "no errors" + } + + s := "Multiple errors: " + for i, e := range m { + if i != 0 { + s += ", " + } + s += e.Error() + } + return s +} diff --git a/vendor/github.com/libp2p/go-msgio/num.go b/vendor/github.com/libp2p/go-msgio/num.go new file mode 100644 index 00000000..513c1994 --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/num.go @@ -0,0 +1,33 @@ +package msgio + +import ( + "encoding/binary" + "io" +) + +// NBO is NetworkByteOrder +var NBO = binary.BigEndian + +// WriteLen writes a length to the given writer. +func WriteLen(w io.Writer, l int) error { + ul := uint32(l) + return binary.Write(w, NBO, &ul) +} + +// ReadLen reads a length from the given reader. +// if buf is non-nil, it reuses the buffer. Ex: +// l, err := ReadLen(r, nil) +// _, err := ReadLen(r, buf) +func ReadLen(r io.Reader, buf []byte) (int, error) { + if len(buf) < 4 { + buf = make([]byte, 4) + } + buf = buf[:4] + + if _, err := io.ReadFull(r, buf); err != nil { + return 0, err + } + + n := int(NBO.Uint32(buf)) + return n, nil +} diff --git a/vendor/github.com/libp2p/go-msgio/varint.go b/vendor/github.com/libp2p/go-msgio/varint.go new file mode 100644 index 00000000..0872fc36 --- /dev/null +++ b/vendor/github.com/libp2p/go-msgio/varint.go @@ -0,0 +1,188 @@ +package msgio + +import ( + "encoding/binary" + "io" + "sync" + + pool "github.com/libp2p/go-buffer-pool" +) + +// varintWriter is the underlying type that implements the Writer interface. +type varintWriter struct { + W io.Writer + + pool *pool.BufferPool + lock sync.Mutex // for threadsafe writes +} + +// NewVarintWriter wraps an io.Writer with a varint msgio framed writer. +// The msgio.Writer will write the length prefix of every message written +// as a varint, using https://golang.org/pkg/encoding/binary/#PutUvarint +func NewVarintWriter(w io.Writer) WriteCloser { + return NewVarintWriterWithPool(w, pool.GlobalPool) +} + +func NewVarintWriterWithPool(w io.Writer, p *pool.BufferPool) WriteCloser { + return &varintWriter{ + pool: p, + W: w, + } +} + +func (s *varintWriter) Write(msg []byte) (int, error) { + err := s.WriteMsg(msg) + if err != nil { + return 0, err + } + return len(msg), nil +} + +func (s *varintWriter) WriteMsg(msg []byte) error { + s.lock.Lock() + defer s.lock.Unlock() + + buf := s.pool.Get(len(msg) + binary.MaxVarintLen64) + n := binary.PutUvarint(buf, uint64(len(msg))) + n += copy(buf[n:], msg) + _, err := s.W.Write(buf[:n]) + s.pool.Put(buf) + + return err +} + +func (s *varintWriter) Close() error { + if c, ok := s.W.(io.Closer); ok { + return c.Close() + } + return nil +} + +// varintReader is the underlying type that implements the Reader interface. +type varintReader struct { + R io.Reader + br io.ByteReader // for reading varints. + + next int + pool *pool.BufferPool + lock sync.Mutex + max int // the maximal message size (in bytes) this reader handles +} + +// NewVarintReader wraps an io.Reader with a varint msgio framed reader. +// The msgio.Reader will read whole messages at a time (using the length). +// Varints read according to https://golang.org/pkg/encoding/binary/#ReadUvarint +// Assumes an equivalent writer on the other side. +func NewVarintReader(r io.Reader) ReadCloser { + return NewVarintReaderSize(r, defaultMaxSize) +} + +// NewVarintReaderSize is equivalent to NewVarintReader but allows one to +// specify a max message size. +func NewVarintReaderSize(r io.Reader, maxMessageSize int) ReadCloser { + return NewVarintReaderSizeWithPool(r, maxMessageSize, pool.GlobalPool) +} + +// NewVarintReaderWithPool is the same as NewVarintReader but allows one to +// specify a buffer pool. +func NewVarintReaderWithPool(r io.Reader, p *pool.BufferPool) ReadCloser { + return NewVarintReaderSizeWithPool(r, defaultMaxSize, p) +} + +// NewVarintReaderWithPool is the same as NewVarintReader but allows one to +// specify a buffer pool and a max message size. +func NewVarintReaderSizeWithPool(r io.Reader, maxMessageSize int, p *pool.BufferPool) ReadCloser { + if p == nil { + panic("nil pool") + } + return &varintReader{ + R: r, + br: &simpleByteReader{R: r}, + next: -1, + pool: p, + max: maxMessageSize, + } +} + +// NextMsgLen reads the length of the next msg into s.lbuf, and returns it. +// WARNING: like Read, NextMsgLen is destructive. It reads from the internal +// reader. +func (s *varintReader) NextMsgLen() (int, error) { + s.lock.Lock() + defer s.lock.Unlock() + return s.nextMsgLen() +} + +func (s *varintReader) nextMsgLen() (int, error) { + if s.next == -1 { + length, err := binary.ReadUvarint(s.br) + if err != nil { + return 0, err + } + s.next = int(length) + } + return s.next, nil +} + +func (s *varintReader) Read(msg []byte) (int, error) { + s.lock.Lock() + defer s.lock.Unlock() + + length, err := s.nextMsgLen() + if err != nil { + return 0, err + } + + if length > len(msg) { + return 0, io.ErrShortBuffer + } + _, err = io.ReadFull(s.R, msg[:length]) + s.next = -1 // signal we've consumed this msg + return length, err +} + +func (s *varintReader) ReadMsg() ([]byte, error) { + s.lock.Lock() + defer s.lock.Unlock() + + length, err := s.nextMsgLen() + if err != nil { + return nil, err + } + if length == 0 { + s.next = -1 + return nil, nil + } + + if length > s.max { + return nil, ErrMsgTooLarge + } + + msg := s.pool.Get(length) + _, err = io.ReadFull(s.R, msg) + s.next = -1 // signal we've consumed this msg + return msg, err +} + +func (s *varintReader) ReleaseMsg(msg []byte) { + s.pool.Put(msg) +} + +func (s *varintReader) Close() error { + if c, ok := s.R.(io.Closer); ok { + return c.Close() + } + return nil +} + +type simpleByteReader struct { + R io.Reader + buf [1]byte +} + +func (r *simpleByteReader) ReadByte() (c byte, err error) { + if _, err := io.ReadFull(r.R, r.buf[:]); err != nil { + return 0, err + } + return r.buf[0], nil +} diff --git a/vendor/github.com/libp2p/go-nat/.travis.yml b/vendor/github.com/libp2p/go-nat/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-nat/LICENSE b/vendor/github.com/libp2p/go-nat/LICENSE new file mode 100644 index 00000000..37ec93a1 --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/libp2p/go-nat/README.md b/vendor/github.com/libp2p/go-nat/README.md new file mode 100644 index 00000000..61b5cc88 --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/README.md @@ -0,0 +1,9 @@ +# go-nat + +[![GoDoc](https://godoc.org/github.com/libp2p/go-nat?status.svg)](https://godoc.org/github.com/libp2p/go-nat) [![status](https://sourcegraph.com/api/repos/github.com/libp2p/go-nat/.badges/status.png)](https://sourcegraph.com/github.com/libp2p/go-nat) + +Forked from: [fd/go-nat](https://github.com/fd/go-nat). + +--- + +The last gx published version of this module was: 1.0.3: QmdwkZHamNNrj7k3G29rnurmW3mFzsDhnyXppNcgYsiBVz diff --git a/vendor/github.com/libp2p/go-nat/go.mod b/vendor/github.com/libp2p/go-nat/go.mod new file mode 100644 index 00000000..718fdbdf --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-nat + +require ( + github.com/huin/goupnp v1.0.0 + github.com/jackpal/gateway v1.0.5 + github.com/jackpal/go-nat-pmp v1.0.1 + github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b +) diff --git a/vendor/github.com/libp2p/go-nat/go.sum b/vendor/github.com/libp2p/go-nat/go.sum new file mode 100644 index 00000000..1a3a280e --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/go.sum @@ -0,0 +1,13 @@ +github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1 h1:Y/KGZSOdz/2r0WJ9Mkmz6NJBusp0kiNx1Cn82lzJQ6w= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/libp2p/go-nat/nat.go b/vendor/github.com/libp2p/go-nat/nat.go new file mode 100644 index 00000000..371fdb03 --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/nat.go @@ -0,0 +1,129 @@ +// Package nat implements NAT handling facilities +package nat + +import ( + "context" + "errors" + "math" + "math/rand" + "net" + "time" + + "github.com/jackpal/gateway" +) + +var ErrNoExternalAddress = errors.New("no external address") +var ErrNoInternalAddress = errors.New("no internal address") +var ErrNoNATFound = errors.New("no NAT found") + +// protocol is either "udp" or "tcp" +type NAT interface { + // Type returns the kind of NAT port mapping service that is used + Type() string + + // GetDeviceAddress returns the internal address of the gateway device. + GetDeviceAddress() (addr net.IP, err error) + + // GetExternalAddress returns the external address of the gateway device. + GetExternalAddress() (addr net.IP, err error) + + // GetInternalAddress returns the address of the local host. + GetInternalAddress() (addr net.IP, err error) + + // AddPortMapping maps a port on the local host to an external port. + AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (mappedExternalPort int, err error) + + // DeletePortMapping removes a port mapping. + DeletePortMapping(protocol string, internalPort int) (err error) +} + +// DiscoverNATs returns all NATs discovered in the network. +func DiscoverNATs(ctx context.Context) <-chan NAT { + nats := make(chan NAT) + + go func() { + defer close(nats) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + upnpIg1 := discoverUPNP_IG1(ctx) + upnpIg2 := discoverUPNP_IG2(ctx) + natpmp := discoverNATPMP(ctx) + upnpGenIGDev := discoverUPNP_GenIGDev(ctx) + for upnpIg1 != nil || upnpIg2 != nil || natpmp != nil || upnpGenIGDev != nil { + var ( + nat NAT + ok bool + ) + select { + case nat, ok = <-upnpIg1: + if !ok { + upnpIg1 = nil + } + case nat, ok = <-upnpIg2: + if !ok { + upnpIg2 = nil + } + case nat, ok = <-upnpGenIGDev: + if !ok { + upnpGenIGDev = nil + } + case nat, ok = <-natpmp: + if !ok { + natpmp = nil + } + } + if ok { + select { + case nats <- nat: + case <-ctx.Done(): + return + } + } + } + }() + return nats +} + +// DiscoverGateway attempts to find a gateway device. +func DiscoverGateway() (NAT, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + var nats []NAT + for nat := range DiscoverNATs(ctx) { + nats = append(nats, nat) + } + switch len(nats) { + case 0: + return nil, ErrNoNATFound + case 1: + return nats[0], nil + } + gw, _ := gateway.DiscoverGateway() + bestNAT := nats[0] + natGw, _ := bestNAT.GetDeviceAddress() + bestNATIsGw := gw != nil && natGw.Equal(gw) + // 1. Prefer gateways discovered _last_. This is an OK heuristic for + // discovering the most-upstream (furthest) NAT. + // 2. Prefer gateways that actually match our known gateway address. + // Some relays like to claim to be NATs even if they aren't. + for _, nat := range nats[1:] { + natGw, _ := nat.GetDeviceAddress() + natIsGw := gw != nil && natGw.Equal(gw) + + if bestNATIsGw && !natIsGw { + continue + } + + bestNATIsGw = natIsGw + bestNAT = nat + } + return bestNAT, nil +} + +func randomPort() int { + rand.Seed(time.Now().UnixNano()) + return rand.Intn(math.MaxUint16-10000) + 10000 +} diff --git a/vendor/github.com/libp2p/go-nat/natpmp.go b/vendor/github.com/libp2p/go-nat/natpmp.go new file mode 100644 index 00000000..a31a4999 --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/natpmp.go @@ -0,0 +1,133 @@ +package nat + +import ( + "context" + "net" + "time" + + "github.com/jackpal/gateway" + "github.com/jackpal/go-nat-pmp" +) + +var ( + _ NAT = (*natpmpNAT)(nil) +) + +func discoverNATPMP(ctx context.Context) <-chan NAT { + res := make(chan NAT, 1) + + ip, err := gateway.DiscoverGateway() + if err == nil { + go func() { + defer close(res) + // Unfortunately, we can't actually _stop_ the natpmp + // library. However, we can at least close _our_ channel + // and walk away. + select { + case client, ok := <-discoverNATPMPWithAddr(ip): + if ok { + res <- &natpmpNAT{client, ip, make(map[int]int)} + } + case <-ctx.Done(): + } + }() + } else { + close(res) + } + return res +} + +func discoverNATPMPWithAddr(ip net.IP) <-chan *natpmp.Client { + res := make(chan *natpmp.Client, 1) + go func() { + defer close(res) + client := natpmp.NewClient(ip) + _, err := client.GetExternalAddress() + if err != nil { + return + } + res <- client + }() + return res +} + +type natpmpNAT struct { + c *natpmp.Client + gateway net.IP + ports map[int]int +} + +func (n *natpmpNAT) GetDeviceAddress() (addr net.IP, err error) { + return n.gateway, nil +} + +func (n *natpmpNAT) GetInternalAddress() (addr net.IP, err error) { + ifaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + for _, iface := range ifaces { + addrs, err := iface.Addrs() + if err != nil { + return nil, err + } + + for _, addr := range addrs { + switch x := addr.(type) { + case *net.IPNet: + if x.Contains(n.gateway) { + return x.IP, nil + } + } + } + } + + return nil, ErrNoInternalAddress +} + +func (n *natpmpNAT) GetExternalAddress() (addr net.IP, err error) { + res, err := n.c.GetExternalAddress() + if err != nil { + return nil, err + } + + d := res.ExternalIPAddress + return net.IPv4(d[0], d[1], d[2], d[3]), nil +} + +func (n *natpmpNAT) AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (int, error) { + var ( + err error + ) + + timeoutInSeconds := int(timeout / time.Second) + + if externalPort := n.ports[internalPort]; externalPort > 0 { + _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds) + if err == nil { + n.ports[internalPort] = externalPort + return externalPort, nil + } + } + + for i := 0; i < 3; i++ { + externalPort := randomPort() + _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds) + if err == nil { + n.ports[internalPort] = externalPort + return externalPort, nil + } + } + + return 0, err +} + +func (n *natpmpNAT) DeletePortMapping(protocol string, internalPort int) (err error) { + delete(n.ports, internalPort) + return nil +} + +func (n *natpmpNAT) Type() string { + return "NAT-PMP" +} diff --git a/vendor/github.com/libp2p/go-nat/upnp.go b/vendor/github.com/libp2p/go-nat/upnp.go new file mode 100644 index 00000000..ccfeb14a --- /dev/null +++ b/vendor/github.com/libp2p/go-nat/upnp.go @@ -0,0 +1,327 @@ +package nat + +import ( + "context" + "net" + "net/url" + "strings" + "time" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/dcps/internetgateway1" + "github.com/huin/goupnp/dcps/internetgateway2" + + "github.com/koron/go-ssdp" +) + +var ( + _ NAT = (*upnp_NAT)(nil) +) + +func discoverUPNP_IG1(ctx context.Context) <-chan NAT { + res := make(chan NAT) + go func() { + defer close(res) + + // find devices + devs, err := goupnp.DiscoverDevices(internetgateway1.URN_WANConnectionDevice_1) + if err != nil { + return + } + + for _, dev := range devs { + if dev.Root == nil { + continue + } + + dev.Root.Device.VisitServices(func(srv *goupnp.Service) { + if ctx.Err() != nil { + return + } + switch srv.ServiceType { + case internetgateway1.URN_WANIPConnection_1: + client := &internetgateway1.WANIPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: dev.Root, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-IP1)", dev.Root}: + case <-ctx.Done(): + } + } + + case internetgateway1.URN_WANPPPConnection_1: + client := &internetgateway1.WANPPPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: dev.Root, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-PPP1)", dev.Root}: + case <-ctx.Done(): + } + } + + } + }) + } + + }() + return res +} + +func discoverUPNP_IG2(ctx context.Context) <-chan NAT { + res := make(chan NAT) + go func() { + defer close(res) + + // find devices + devs, err := goupnp.DiscoverDevices(internetgateway2.URN_WANConnectionDevice_2) + if err != nil { + return + } + + for _, dev := range devs { + if dev.Root == nil { + continue + } + + dev.Root.Device.VisitServices(func(srv *goupnp.Service) { + if ctx.Err() != nil { + return + } + switch srv.ServiceType { + case internetgateway2.URN_WANIPConnection_1: + client := &internetgateway2.WANIPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: dev.Root, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-IP1)", dev.Root}: + case <-ctx.Done(): + } + } + + case internetgateway2.URN_WANIPConnection_2: + client := &internetgateway2.WANIPConnection2{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: dev.Root, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-IP2)", dev.Root}: + case <-ctx.Done(): + } + } + + case internetgateway2.URN_WANPPPConnection_1: + client := &internetgateway2.WANPPPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: dev.Root, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-PPP1)", dev.Root}: + case <-ctx.Done(): + } + } + + } + }) + } + + }() + return res +} + +func discoverUPNP_GenIGDev(ctx context.Context) <-chan NAT { + res := make(chan NAT, 1) + go func() { + defer close(res) + + DeviceList, err := ssdp.Search(ssdp.All, 5, "") + if err != nil { + return + } + var gw ssdp.Service + for _, Service := range DeviceList { + if strings.Contains(Service.Type, "InternetGatewayDevice") { + gw = Service + break + } + } + + DeviceURL, err := url.Parse(gw.Location) + if err != nil { + return + } + RootDevice, err := goupnp.DeviceByURL(DeviceURL) + if err != nil { + return + } + + RootDevice.Device.VisitServices(func(srv *goupnp.Service) { + if ctx.Err() != nil { + return + } + switch srv.ServiceType { + case internetgateway1.URN_WANIPConnection_1: + client := &internetgateway1.WANIPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: RootDevice, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-IP1)", RootDevice}: + case <-ctx.Done(): + } + } + + case internetgateway1.URN_WANPPPConnection_1: + client := &internetgateway1.WANPPPConnection1{ServiceClient: goupnp.ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: RootDevice, + Service: srv, + }} + _, isNat, err := client.GetNATRSIPStatus() + if err == nil && isNat { + select { + case res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-PPP1)", RootDevice}: + case <-ctx.Done(): + } + } + + } + }) + }() + return res +} + +type upnp_NAT_Client interface { + GetExternalIPAddress() (string, error) + AddPortMapping(string, uint16, string, uint16, string, bool, string, uint32) error + DeletePortMapping(string, uint16, string) error +} + +type upnp_NAT struct { + c upnp_NAT_Client + ports map[int]int + typ string + rootDevice *goupnp.RootDevice +} + +func (u *upnp_NAT) GetExternalAddress() (addr net.IP, err error) { + ipString, err := u.c.GetExternalIPAddress() + if err != nil { + return nil, err + } + + ip := net.ParseIP(ipString) + if ip == nil { + return nil, ErrNoExternalAddress + } + + return ip, nil +} + +func mapProtocol(s string) string { + switch s { + case "udp": + return "UDP" + case "tcp": + return "TCP" + default: + panic("invalid protocol: " + s) + } +} + +func (u *upnp_NAT) AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (int, error) { + ip, err := u.GetInternalAddress() + if err != nil { + return 0, nil + } + + timeoutInSeconds := uint32(timeout / time.Second) + + if externalPort := u.ports[internalPort]; externalPort > 0 { + err = u.c.AddPortMapping("", uint16(externalPort), mapProtocol(protocol), uint16(internalPort), ip.String(), true, description, timeoutInSeconds) + if err == nil { + return externalPort, nil + } + } + + for i := 0; i < 3; i++ { + externalPort := randomPort() + err = u.c.AddPortMapping("", uint16(externalPort), mapProtocol(protocol), uint16(internalPort), ip.String(), true, description, timeoutInSeconds) + if err == nil { + u.ports[internalPort] = externalPort + return externalPort, nil + } + } + + return 0, err +} + +func (u *upnp_NAT) DeletePortMapping(protocol string, internalPort int) error { + if externalPort := u.ports[internalPort]; externalPort > 0 { + delete(u.ports, internalPort) + return u.c.DeletePortMapping("", uint16(externalPort), mapProtocol(protocol)) + } + + return nil +} + +func (u *upnp_NAT) GetDeviceAddress() (net.IP, error) { + addr, err := net.ResolveUDPAddr("udp4", u.rootDevice.URLBase.Host) + if err != nil { + return nil, err + } + + return addr.IP, nil +} + +func (u *upnp_NAT) GetInternalAddress() (net.IP, error) { + devAddr, err := u.GetDeviceAddress() + if err != nil { + return nil, err + } + + ifaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + for _, iface := range ifaces { + addrs, err := iface.Addrs() + if err != nil { + return nil, err + } + + for _, addr := range addrs { + switch x := addr.(type) { + case *net.IPNet: + if x.Contains(devAddr) { + return x.IP, nil + } + } + } + } + + return nil, ErrNoInternalAddress +} + +func (n *upnp_NAT) Type() string { return n.typ } diff --git a/vendor/github.com/libp2p/go-reuseport-transport/.travis.yml b/vendor/github.com/libp2p/go-reuseport-transport/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-reuseport-transport/LICENSE b/vendor/github.com/libp2p/go-reuseport-transport/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-reuseport-transport/Makefile b/vendor/github.com/libp2p/go-reuseport-transport/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/libp2p/go-reuseport-transport/README.md b/vendor/github.com/libp2p/go-reuseport-transport/README.md new file mode 100644 index 00000000..ff707568 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/README.md @@ -0,0 +1,62 @@ +# go-reuseport-transport + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) +[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/libp2p/go-reuseport-transport?status.svg)](https://godoc.org/github.com/libp2p/go-reuseport-transport) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-reuseport-transport/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-reuseport-transport?branch=master) +[![Build Status](https://travis-ci.org/libp2p/go-reuseport-transport.svg?branch=master)](https://travis-ci.org/libp2p/go-reuseport-transport) + +> Basic reuseport TCP transport + +This package provides a basic transport for automatically (and intelligently) reusing TCP ports. + +To use, construct a new `Transport` (the zero value is safe to use) and configure any listeners (`tr.Listen(...)`). + +Then, when dialing (`tr.Dial(...)`), the transport will attempt to reuse the ports it's currently listening on, choosing the best one depending on the destination address. + + +NOTE: Currently, we don't make any attempts to prevent two reusport transports from interfering with each other (reusing each other's ports). However, we reserve the right to fix this in the future. + +## Install + +`go-reuseport-transport` is a standard Go module which can be installed with: + +```sh +go get github.com/libp2p/go-reuseport-transport +``` + +Note that `go-reuseport-transport` is packaged with Gx, so it is recommended to use Gx to install and use it (see the Usage section). + +## Usage + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/libp2p/go-reuseport-transport +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +This package is *currently* used by the [go-tcp-transport](https://github.com/libp2p/go-tcp-transport) libp2p transport and will likely be used by more libp2p transports in the future. + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-reuseport-transport/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT diff --git a/vendor/github.com/libp2p/go-reuseport-transport/codecov.yml b/vendor/github.com/libp2p/go-reuseport-transport/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-reuseport-transport/dial.go b/vendor/github.com/libp2p/go-reuseport-transport/dial.go new file mode 100644 index 00000000..a16b5b2b --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/dial.go @@ -0,0 +1,113 @@ +package tcpreuse + +import ( + "context" + "net" + + reuseport "github.com/libp2p/go-reuseport" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +type dialer interface { + Dial(network, addr string) (net.Conn, error) + DialContext(ctx context.Context, network, addr string) (net.Conn, error) +} + +// Dial dials the given multiaddr, reusing ports we're currently listening on if +// possible. +// +// Dial attempts to be smart about choosing the source port. For example, If +// we're dialing a loopback address and we're listening on one or more loopback +// ports, Dial will randomly choose one of the loopback ports and addresses and +// reuse it. +func (t *Transport) Dial(raddr ma.Multiaddr) (manet.Conn, error) { + return t.DialContext(context.Background(), raddr) +} + +// DialContext is like Dial but takes a context. +func (t *Transport) DialContext(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) { + network, addr, err := manet.DialArgs(raddr) + if err != nil { + return nil, err + } + var d dialer + switch network { + case "tcp4": + d = t.v4.getDialer(network) + case "tcp6": + d = t.v6.getDialer(network) + default: + return nil, ErrWrongProto + } + conn, err := d.DialContext(ctx, network, addr) + if err != nil { + return nil, err + } + maconn, err := manet.WrapNetConn(conn) + if err != nil { + conn.Close() + return nil, err + } + return maconn, nil +} + +func (n *network) getDialer(network string) dialer { + n.mu.RLock() + d := n.dialer + n.mu.RUnlock() + if d == nil { + n.mu.Lock() + defer n.mu.Unlock() + + if n.dialer == nil { + n.dialer = n.makeDialer(network) + } + d = n.dialer + } + return d +} + +func (n *network) makeDialer(network string) dialer { + if !reuseport.Available() { + log.Debug("reuseport not available") + return &net.Dialer{} + } + + var unspec net.IP + switch network { + case "tcp4": + unspec = net.IPv4zero + case "tcp6": + unspec = net.IPv6unspecified + default: + panic("invalid network: must be either tcp4 or tcp6") + } + + // How many ports are we listening on. + var port = 0 + for l := range n.listeners { + newPort := l.Addr().(*net.TCPAddr).Port + switch { + case newPort == 0: // Any port, ignore (really, we shouldn't get this case...). + case port == 0: // Haven't selected a port yet, choose this one. + port = newPort + case newPort == port: // Same as the selected port, continue... + default: // Multiple ports, use the multi dialer + return newMultiDialer(unspec, n.listeners) + } + } + + // None. + if port == 0 { + return &net.Dialer{} + } + + // One. Always dial from the single port we're listening on. + laddr := &net.TCPAddr{ + IP: unspec, + Port: port, + } + + return (*singleDialer)(laddr) +} diff --git a/vendor/github.com/libp2p/go-reuseport-transport/go.mod b/vendor/github.com/libp2p/go-reuseport-transport/go.mod new file mode 100644 index 00000000..190ba681 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-reuseport-transport + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-reuseport v0.0.1 + github.com/multiformats/go-multiaddr v0.0.1 + github.com/multiformats/go-multiaddr-net v0.0.1 +) diff --git a/vendor/github.com/libp2p/go-reuseport-transport/go.sum b/vendor/github.com/libp2p/go-reuseport-transport/go.sum new file mode 100644 index 00000000..a7abc2e2 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/go.sum @@ -0,0 +1,52 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/vendor/github.com/libp2p/go-reuseport-transport/listen.go b/vendor/github.com/libp2p/go-reuseport-transport/listen.go new file mode 100644 index 00000000..7b2a4c39 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/listen.go @@ -0,0 +1,80 @@ +package tcpreuse + +import ( + "net" + + reuseport "github.com/libp2p/go-reuseport" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +type listener struct { + manet.Listener + network *network +} + +func (l *listener) Close() error { + l.network.mu.Lock() + delete(l.network.listeners, l) + l.network.dialer = nil + l.network.mu.Unlock() + return l.Listener.Close() +} + +// Listen listens on the given multiaddr. +// +// If reuseport is supported, it will be enabled for this listener and future +// dials from this transport may reuse the port. +// +// Note: You can listen on the same multiaddr as many times as you want +// (although only *one* listener will end up handling the inbound connection). +func (t *Transport) Listen(laddr ma.Multiaddr) (manet.Listener, error) { + nw, naddr, err := manet.DialArgs(laddr) + if err != nil { + return nil, err + } + var n *network + switch nw { + case "tcp4": + n = &t.v4 + case "tcp6": + n = &t.v6 + default: + return nil, ErrWrongProto + } + + if !reuseport.Available() { + return manet.Listen(laddr) + } + nl, err := reuseport.Listen(nw, naddr) + if err != nil { + return manet.Listen(laddr) + } + + if _, ok := nl.Addr().(*net.TCPAddr); !ok { + nl.Close() + return nil, ErrWrongProto + } + + malist, err := manet.WrapNetListener(nl) + if err != nil { + nl.Close() + return nil, err + } + + list := &listener{ + Listener: malist, + network: n, + } + + n.mu.Lock() + defer n.mu.Unlock() + + if n.listeners == nil { + n.listeners = make(map[*listener]struct{}) + } + n.listeners[list] = struct{}{} + n.dialer = nil + + return list, nil +} diff --git a/vendor/github.com/libp2p/go-reuseport-transport/multidialer.go b/vendor/github.com/libp2p/go-reuseport-transport/multidialer.go new file mode 100644 index 00000000..c7d388c1 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/multidialer.go @@ -0,0 +1,110 @@ +package tcpreuse + +import ( + "context" + "fmt" + "math/rand" + "net" +) + +type multiDialer struct { + loopback []*net.TCPAddr + unspecified []*net.TCPAddr + global *net.TCPAddr +} + +func (d *multiDialer) Dial(network, addr string) (net.Conn, error) { + return d.DialContext(context.Background(), network, addr) +} + +func randAddr(addrs []*net.TCPAddr) *net.TCPAddr { + if len(addrs) > 0 { + return addrs[rand.Intn(len(addrs))] + } + return nil +} + +func (d *multiDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + tcpAddr, err := net.ResolveTCPAddr(network, addr) + if err != nil { + return nil, err + } + + // We pick the source *port* based on the following algorithm. + // + // 1. If we're dialing loopback, choose a source-port in order of + // preference: + // 1. A port in-use by an explicit loopback listener. + // 2. A port in-use by a listener on an unspecified address (must + // also be listening on localhost). + // 3. A port in-use by a listener on a global address. We don't have + // any other better options (other than picking a random port). + // 2. If we're dialing a global address, choose a source-port in order + // of preference: + // 1. A port in-use by a listener on an unspecified address (the most + // general case). + // 2. A port in-use by a listener on the global address. + // 3. Fail on link-local dials (go-ipfs currently forbids this and I + // figured we could try lifting this restriction later). + // + // + // Note: We *always* dial from the unspecified address (regardless of + // the port we pick). In the future, we could use netlink (on Linux) to + // figure out the right source address but we're going to punt on that. + + ip := tcpAddr.IP + source := d.global + switch { + case ip.IsLoopback(): + switch { + case len(d.loopback) > 0: + source = randAddr(d.loopback) + case len(d.unspecified) > 0: + source = randAddr(d.unspecified) + } + case ip.IsGlobalUnicast(): + switch { + case len(d.unspecified) > 0: + source = randAddr(d.unspecified) + } + default: + return nil, fmt.Errorf("undialable IP: %s", tcpAddr.IP) + } + return reuseDial(ctx, source, network, addr) +} + +func newMultiDialer(unspec net.IP, listeners map[*listener]struct{}) dialer { + m := new(multiDialer) + for l := range listeners { + laddr := l.Addr().(*net.TCPAddr) + switch { + case laddr.IP.IsLoopback(): + m.loopback = append(m.loopback, laddr) + case laddr.IP.IsGlobalUnicast(): + // Different global ports? Crap. + // + // The *proper* way to deal with this is to, e.g., use + // netlink to figure out which source address we would + // normally use to dial a destination address and then + // pick one of the ports we're listening on on that + // source address. However, this is a pain in the ass. + // + // Instead, we're just going to always dial from the + // unspecified address with the first global port we + // find. + // + // TODO: Port priority? Addr priority? + if m.global == nil { + m.global = &net.TCPAddr{ + IP: unspec, + Port: laddr.Port, + } + } else { + log.Warning("listening on external interfaces on multiple ports, will dial from %d, not %s", m.global, laddr) + } + case laddr.IP.IsUnspecified(): + m.unspecified = append(m.unspecified, laddr) + } + } + return m +} diff --git a/vendor/github.com/libp2p/go-reuseport-transport/package.json b/vendor/github.com/libp2p/go-reuseport-transport/package.json new file mode 100644 index 00000000..a0b9189d --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/package.json @@ -0,0 +1,41 @@ +{ + "author": "stebalien", + "bugs": { + "url": "https://github.com/libp2p/go-reuseport-transport" + }, + "gx": { + "dvcsimport": "github.com/libp2p/go-reuseport-transport" + }, + "gxDependencies": [ + { + "hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF", + "name": "go-log", + "version": "1.5.9" + }, + { + "author": "multiformats", + "hash": "QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL", + "name": "go-multiaddr", + "version": "1.4.1" + }, + { + "author": "multiformats", + "hash": "Qmc85NSvmSG4Frn9Vb2cBc1rMyULH6D3TNVEfCzSKoUpip", + "name": "go-multiaddr-net", + "version": "1.7.2" + }, + { + "author": "whyrusleeping", + "hash": "Qme8kdM7thoCqLqd7GYCRqipoZJS64rhJo5MBcTpyWfsL9", + "name": "go-reuseport", + "version": "0.2.2" + } + ], + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "go-reuseport-transport", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.2.3" +} + diff --git a/vendor/github.com/libp2p/go-reuseport-transport/reuseport.go b/vendor/github.com/libp2p/go-reuseport-transport/reuseport.go new file mode 100644 index 00000000..82f9f37c --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/reuseport.go @@ -0,0 +1,64 @@ +package tcpreuse + +import ( + "context" + "net" + "syscall" + + reuseport "github.com/libp2p/go-reuseport" +) + +var fallbackDialer net.Dialer + +// reuseErrShouldRetry diagnoses whether to retry after a reuse error. +// if we failed to bind, we should retry. if bind worked and this is a +// real dial error (remote end didnt answer) then we should not retry. +func reuseErrShouldRetry(err error) bool { + if err == nil { + return false // hey, it worked! no need to retry. + } + + // if it's a network timeout error, it's a legitimate failure. + if nerr, ok := err.(net.Error); ok && nerr.Timeout() { + return false + } + + errno, ok := err.(syscall.Errno) + if !ok { // not an errno? who knows what this is. retry. + return true + } + + switch errno { + case syscall.EADDRINUSE, syscall.EADDRNOTAVAIL: + return true // failure to bind. retry. + case syscall.ECONNREFUSED: + return false // real dial error + default: + return true // optimistically default to retry. + } +} + +// Dials using reuseport and then redials normally if that fails. +func reuseDial(ctx context.Context, laddr *net.TCPAddr, network, raddr string) (con net.Conn, err error) { + if laddr == nil { + return fallbackDialer.DialContext(ctx, network, raddr) + } + + d := net.Dialer{ + LocalAddr: laddr, + Control: reuseport.Control, + } + + con, err = d.DialContext(ctx, network, raddr) + if err == nil { + return con, nil + } + + if reuseErrShouldRetry(err) && ctx.Err() == nil { + // We could have an existing socket open or we could have one + // stuck in TIME-WAIT. + log.Debugf("failed to reuse port, dialing with a random port: %s", err) + con, err = fallbackDialer.DialContext(ctx, network, raddr) + } + return con, err +} diff --git a/vendor/github.com/libp2p/go-reuseport-transport/singledialer.go b/vendor/github.com/libp2p/go-reuseport-transport/singledialer.go new file mode 100644 index 00000000..efb96eb1 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/singledialer.go @@ -0,0 +1,16 @@ +package tcpreuse + +import ( + "context" + "net" +) + +type singleDialer net.TCPAddr + +func (d *singleDialer) Dial(network, address string) (net.Conn, error) { + return d.DialContext(context.Background(), network, address) +} + +func (d *singleDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + return reuseDial(ctx, (*net.TCPAddr)(d), network, address) +} diff --git a/vendor/github.com/libp2p/go-reuseport-transport/transport.go b/vendor/github.com/libp2p/go-reuseport-transport/transport.go new file mode 100644 index 00000000..5f094d1a --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport-transport/transport.go @@ -0,0 +1,25 @@ +package tcpreuse + +import ( + "errors" + "sync" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("reuseport-transport") + +// ErrWrongProto is returned when dialing a protocol other than tcp. +var ErrWrongProto = errors.New("can only dial TCP over IPv4 or IPv6") + +// Transport is a TCP reuse transport that reuses listener ports. +type Transport struct { + v4 network + v6 network +} + +type network struct { + mu sync.RWMutex + listeners map[*listener]struct{} + dialer dialer +} diff --git a/vendor/github.com/libp2p/go-reuseport/.travis.yml b/vendor/github.com/libp2p/go-reuseport/.travis.yml new file mode 100644 index 00000000..4cfe98c2 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-reuseport/LICENSE b/vendor/github.com/libp2p/go-reuseport/LICENSE new file mode 100644 index 00000000..0d760cbb --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2013 Conformal Systems LLC. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-reuseport/Makefile b/vendor/github.com/libp2p/go-reuseport/Makefile new file mode 100644 index 00000000..601c56d0 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/Makefile @@ -0,0 +1,26 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + + +SUPPORTED_OS = windows linux darwin freebsd openbsd netbsd +SUPPORTED_ARCH = 386 arm amd64p32 arm64 amd64 +XBUILD_TARGETS=$(foreach os,$(SUPPORTED_OS),$(foreach arch,$(SUPPORTED_ARCH),test-xbuild-$(os)/$(arch))) + +$(XBUILD_TARGETS): PLATFORM = $(subst /, ,$(patsubst test-xbuild-%,%,$@)) +$(XBUILD_TARGETS): GOOS = $(word 1,$(PLATFORM)) +$(XBUILD_TARGETS): GOARCH = $(word 2,$(PLATFORM)) +$(XBUILD_TARGETS): + @ if GOOS=$(GOOS) GOARCH=$(GOARCH) go version >/dev/null 2>&1 ; then \ + echo "building $(GOOS)/$(GOARCH)"; \ + GOOS=$(GOOS) GOARCH=$(GOARCH) go build; \ + fi + +test-xbuild: $(XBUILD_TARGETS) diff --git a/vendor/github.com/libp2p/go-reuseport/README.md b/vendor/github.com/libp2p/go-reuseport/README.md new file mode 100644 index 00000000..4a4605ba --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/README.md @@ -0,0 +1,46 @@ +# go-reuseport + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-blue.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23libp2p) +[![codecov](https://codecov.io/gh/libp2p/go-reuseport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-reuseport) +[![Travis CI](https://travis-ci.org/libp2p/go-reuseport.svg?branch=master)](https://travis-ci.org/libp2p/go-reuseport) + +**NOTE:** This package REQUIRES go >= 1.11. + +This package enables listening and dialing from _the same_ TCP or UDP port. +This means that the following sockopts may be set: + +``` +SO_REUSEADDR +SO_REUSEPORT +``` + +- godoc: https://godoc.org/github.com/libp2p/go-reuseport + +This is a simple package to help with address reuse. This is particularly +important when attempting to do TCP NAT holepunching, which requires a process +to both Listen and Dial on the same TCP port. This package provides some +utilities around enabling this behaviour on various OS. + +## Examples + + +```Go +// listen on the same port. oh yeah. +l1, _ := reuse.Listen("tcp", "127.0.0.1:1234") +l2, _ := reuse.Listen("tcp", "127.0.0.1:1234") +``` + +```Go +// dial from the same port. oh yeah. +l1, _ := reuse.Listen("tcp", "127.0.0.1:1234") +l2, _ := reuse.Listen("tcp", "127.0.0.1:1235") +c, _ := reuse.Dial("tcp", "127.0.0.1:1234", "127.0.0.1:1235") +``` + +**Note: cant dial self because tcp/ip stacks use 4-tuples to identify connections, and doing so would clash.** + +## Tested + +Tested on `darwin`, `linux`, and `windows`. diff --git a/vendor/github.com/libp2p/go-reuseport/addr.go b/vendor/github.com/libp2p/go-reuseport/addr.go new file mode 100644 index 00000000..cfffc7c8 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/addr.go @@ -0,0 +1,20 @@ +package reuseport + +import ( + "net" +) + +func ResolveAddr(network, address string) (net.Addr, error) { + switch network { + default: + return nil, net.UnknownNetworkError(network) + case "ip", "ip4", "ip6": + return net.ResolveIPAddr(network, address) + case "tcp", "tcp4", "tcp6": + return net.ResolveTCPAddr(network, address) + case "udp", "udp4", "udp6": + return net.ResolveUDPAddr(network, address) + case "unix", "unixgram", "unixpacket": + return net.ResolveUnixAddr(network, address) + } +} diff --git a/vendor/github.com/libp2p/go-reuseport/codecov.yml b/vendor/github.com/libp2p/go-reuseport/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-reuseport/control_unix.go b/vendor/github.com/libp2p/go-reuseport/control_unix.go new file mode 100644 index 00000000..e75242a8 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/control_unix.go @@ -0,0 +1,25 @@ +// +build !windows,!wasm + +package reuseport + +import ( + "syscall" + + "golang.org/x/sys/unix" +) + +func Control(network, address string, c syscall.RawConn) error { + var err error + c.Control(func(fd uintptr) { + err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) + if err != nil { + return + } + + err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + if err != nil { + return + } + }) + return err +} diff --git a/vendor/github.com/libp2p/go-reuseport/control_wasm.go b/vendor/github.com/libp2p/go-reuseport/control_wasm.go new file mode 100644 index 00000000..d5d0a523 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/control_wasm.go @@ -0,0 +1,11 @@ +// +build wasm + +package reuseport + +import ( + "syscall" +) + +func Control(network, address string, c syscall.RawConn) error { + return nil +} diff --git a/vendor/github.com/libp2p/go-reuseport/control_windows.go b/vendor/github.com/libp2p/go-reuseport/control_windows.go new file mode 100644 index 00000000..840534c9 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/control_windows.go @@ -0,0 +1,13 @@ +package reuseport + +import ( + "syscall" + + "golang.org/x/sys/windows" +) + +func Control(network, address string, c syscall.RawConn) (err error) { + return c.Control(func(fd uintptr) { + err = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1) + }) +} diff --git a/vendor/github.com/libp2p/go-reuseport/go.mod b/vendor/github.com/libp2p/go-reuseport/go.mod new file mode 100644 index 00000000..f8053c7d --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/go.mod @@ -0,0 +1,7 @@ +module github.com/libp2p/go-reuseport + +require ( + github.com/pkg/errors v0.8.1 + github.com/stretchr/testify v1.3.0 + golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e +) diff --git a/vendor/github.com/libp2p/go-reuseport/go.sum b/vendor/github.com/libp2p/go-reuseport/go.sum new file mode 100644 index 00000000..af928c2c --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/libp2p/go-reuseport/interface.go b/vendor/github.com/libp2p/go-reuseport/interface.go new file mode 100644 index 00000000..64b48af8 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/interface.go @@ -0,0 +1,64 @@ +// Package reuseport provides Listen and Dial functions that set socket +// options in order to be able to reuse ports. You should only use this +// package if you know what SO_REUSEADDR and SO_REUSEPORT are. +// +// For example: +// +// // listen on the same port. oh yeah. +// l1, _ := reuse.Listen("tcp", "127.0.0.1:1234") +// l2, _ := reuse.Listen("tcp", "127.0.0.1:1234") +// +// // dial from the same port. oh yeah. +// l1, _ := reuse.Listen("tcp", "127.0.0.1:1234") +// l2, _ := reuse.Listen("tcp", "127.0.0.1:1235") +// c, _ := reuse.Dial("tcp", "127.0.0.1:1234", "127.0.0.1:1235") +// +// Note: cant dial self because tcp/ip stacks use 4-tuples to identify connections, +// and doing so would clash. +package reuseport + +import ( + "context" + "net" + + "github.com/pkg/errors" +) + +// Available returns whether or not SO_REUSEPORT or equivalent behaviour is +// available in the OS. +func Available() bool { + return true +} + +var listenConfig = net.ListenConfig{ + Control: Control, +} + +// Listen listens at the given network and address. see net.Listen +// Returns a net.Listener created from a file discriptor for a socket +// with SO_REUSEPORT and SO_REUSEADDR option set. +func Listen(network, address string) (net.Listener, error) { + return listenConfig.Listen(context.Background(), network, address) +} + +// ListenPacket listens at the given network and address. see net.ListenPacket +// Returns a net.Listener created from a file discriptor for a socket +// with SO_REUSEPORT and SO_REUSEADDR option set. +func ListenPacket(network, address string) (net.PacketConn, error) { + return listenConfig.ListenPacket(context.Background(), network, address) +} + +// Dial dials the given network and address. see net.Dialer.Dial +// Returns a net.Conn created from a file descriptor for a socket +// with SO_REUSEPORT and SO_REUSEADDR option set. +func Dial(network, laddr, raddr string) (net.Conn, error) { + nla, err := ResolveAddr(network, laddr) + if err != nil { + return nil, errors.Wrap(err, "resolving local addr") + } + d := net.Dialer{ + Control: Control, + LocalAddr: nla, + } + return d.Dial(network, raddr) +} diff --git a/vendor/github.com/libp2p/go-reuseport/package.json b/vendor/github.com/libp2p/go-reuseport/package.json new file mode 100644 index 00000000..391d13f0 --- /dev/null +++ b/vendor/github.com/libp2p/go-reuseport/package.json @@ -0,0 +1,36 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/libp2p/go-reuseport" + }, + "gx": { + "dvcsimport": "github.com/libp2p/go-reuseport" + }, + "gxDependencies": [ + { + "author": "The Go Authors", + "hash": "QmVGjyM9i2msKvLXwh9VosCTgP4mL91kC7hDmqnwTTx6Hu", + "name": "sys", + "version": "0.2.0" + }, + { + "author": "whyrusleeping", + "hash": "QmVmDhyTTUcQXFD1rRQ64fGLMSAoaQvNH3hwuaCFAPq2hy", + "name": "errors", + "version": "0.0.1" + }, + { + "author": "magik6k", + "hash": "QmPVkJMTeRC6iBByPWdrRkD3BE5UXsj5HPzb4kPqL186mS", + "name": "testify", + "version": "1.0.0" + } + ], + "gxVersion": "0.9.0", + "language": "go", + "license": "", + "name": "go-reuseport", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.2.2" +} + diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/.gitignore b/vendor/github.com/libp2p/go-stream-muxer-multistream/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/.travis.yml b/vendor/github.com/libp2p/go-stream-muxer-multistream/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/LICENSE b/vendor/github.com/libp2p/go-stream-muxer-multistream/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/Makefile b/vendor/github.com/libp2p/go-stream-muxer-multistream/Makefile new file mode 100644 index 00000000..3907e857 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/Makefile @@ -0,0 +1,19 @@ +build: deps + go build ./... + +test: deps + go test ./... + +test_race: deps + go test -race ./... + +gx-bins: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx-bins + gx --verbose install --global + gx-go rewrite + +clean: gx-bins + gx-go rewrite --undo diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/README.md b/vendor/github.com/libp2p/go-stream-muxer-multistream/README.md new file mode 100644 index 00000000..68bc2da6 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/README.md @@ -0,0 +1,13 @@ +# go-smux-multistream - a go-stream-muxer shim for multistream + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) ![](https://raw.githubusercontent.com/libp2p/go-stream-muxer/master/img/badge.png) + +This is an implementation of the [go-stream-muxer](https://github.com/libp2p/go-stream-muxer) interface for [multistream](https://github.com/whyrusleeping/go-multistream). For more information, see that repo. + +## Installation + +```sh +go get -d github.com/libp2p/go-stream-muxer-multistream +cd $GOPATH/src/github.com/libp2p/go-stream-muxer-multistream +make deps +``` diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/go.mod b/vendor/github.com/libp2p/go-stream-muxer-multistream/go.mod new file mode 100644 index 00000000..bce71707 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/go.mod @@ -0,0 +1,8 @@ +module github.com/libp2p/go-stream-muxer-multistream + +go 1.12 + +require ( + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/multiformats/go-multistream v0.1.0 +) diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/go.sum b/vendor/github.com/libp2p/go-stream-muxer-multistream/go.sum new file mode 100644 index 00000000..3c9d3258 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/go.sum @@ -0,0 +1,55 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-stream-muxer-multistream/multistream.go b/vendor/github.com/libp2p/go-stream-muxer-multistream/multistream.go new file mode 100644 index 00000000..c7b58879 --- /dev/null +++ b/vendor/github.com/libp2p/go-stream-muxer-multistream/multistream.go @@ -0,0 +1,75 @@ +// package multistream implements a peerstream transport using +// go-multistream to select the underlying stream muxer +package multistream + +import ( + "fmt" + "net" + "time" + + "github.com/libp2p/go-libp2p-core/mux" + + mss "github.com/multiformats/go-multistream" +) + +var DefaultNegotiateTimeout = time.Second * 60 + +type Transport struct { + mux *mss.MultistreamMuxer + + tpts map[string]mux.Multiplexer + + NegotiateTimeout time.Duration + + OrderPreference []string +} + +func NewBlankTransport() *Transport { + return &Transport{ + mux: mss.NewMultistreamMuxer(), + tpts: make(map[string]mux.Multiplexer), + NegotiateTimeout: DefaultNegotiateTimeout, + } +} + +func (t *Transport) AddTransport(path string, tpt mux.Multiplexer) { + t.mux.AddHandler(path, nil) + t.tpts[path] = tpt + t.OrderPreference = append(t.OrderPreference, path) +} + +func (t *Transport) NewConn(nc net.Conn, isServer bool) (mux.MuxedConn, error) { + if t.NegotiateTimeout != 0 { + if err := nc.SetDeadline(time.Now().Add(t.NegotiateTimeout)); err != nil { + return nil, err + } + } + + var proto string + if isServer { + selected, _, err := t.mux.Negotiate(nc) + if err != nil { + return nil, err + } + proto = selected + } else { + selected, err := mss.SelectOneOf(t.OrderPreference, nc) + if err != nil { + return nil, err + } + proto = selected + } + + if t.NegotiateTimeout != 0 { + if err := nc.SetDeadline(time.Time{}); err != nil { + return nil, err + } + } + + tpt, ok := t.tpts[proto] + if !ok { + return nil, fmt.Errorf("selected protocol we don't have a transport for") + } + + return tpt.NewConn(nc, isServer) +} diff --git a/vendor/github.com/libp2p/go-tcp-transport/.travis.yml b/vendor/github.com/libp2p/go-tcp-transport/.travis.yml new file mode 100644 index 00000000..cc4a155f --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + - TEST_STRESS_TIMEOUT_MS=180000 + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-tcp-transport/LICENSE b/vendor/github.com/libp2p/go-tcp-transport/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-tcp-transport/README.md b/vendor/github.com/libp2p/go-tcp-transport/README.md new file mode 100644 index 00000000..ce8ad967 --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/README.md @@ -0,0 +1,40 @@ +go-tcp-transport +================== + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-tcp-transport/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-tcp-transport?branch=master) +[![Travis CI](https://travis-ci.com/libp2p/go-tcp-transport.svg?branch=master)](https://travis-ci.com/libp2p/go-tcp-transport) + +> A libp2p transport implementation for tcp, including reuseport socket options. + + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +make install +``` + +## Contribute + +PRs are welcome! + +Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +MIT © Jeromy Johnson + +--- + +The last gx published version of this module was: 2.0.28: QmTGiDkw4eeKq31wwpQRk5GwWiReaxrcTQLuCCLWgfKo5M diff --git a/vendor/github.com/libp2p/go-tcp-transport/codecov.yml b/vendor/github.com/libp2p/go-tcp-transport/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-tcp-transport/go.mod b/vendor/github.com/libp2p/go-tcp-transport/go.mod new file mode 100644 index 00000000..acfb03f4 --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/go.mod @@ -0,0 +1,15 @@ +module github.com/libp2p/go-tcp-transport + +require ( + github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-mplex v0.2.1 + github.com/libp2p/go-libp2p-testing v0.0.3 + github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 + github.com/libp2p/go-reuseport v0.0.1 + github.com/libp2p/go-reuseport-transport v0.0.2 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-fmt v0.0.1 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/multiformats/go-multihash v0.0.5 // indirect +) diff --git a/vendor/github.com/libp2p/go-tcp-transport/go.sum b/vendor/github.com/libp2p/go-tcp-transport/go.sum new file mode 100644 index 00000000..b81940b2 --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/go.sum @@ -0,0 +1,158 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-mplex v0.2.0 h1:vnR+/fUnL5d2kTB1Lfce1KVSP+bCCy2aJIvqvb9cFqE= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-tcp-transport/reuseport.go b/vendor/github.com/libp2p/go-tcp-transport/reuseport.go new file mode 100644 index 00000000..e3b7e125 --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/reuseport.go @@ -0,0 +1,44 @@ +package tcp + +import ( + "os" + "strings" + + "github.com/libp2p/go-reuseport" +) + +// envReuseport is the env variable name used to turn off reuse port. +// It default to true. +const envReuseport = "LIBP2P_TCP_REUSEPORT" +const deprecatedEnvReuseport = "IPFS_REUSEPORT" + +// envReuseportVal stores the value of envReuseport. defaults to true. +var envReuseportVal = true + +func init() { + v := strings.ToLower(os.Getenv(envReuseport)) + if v == "false" || v == "f" || v == "0" { + envReuseportVal = false + log.Infof("REUSEPORT disabled (LIBP2P_TCP_REUSEPORT=%s)", v) + } + v, exist := os.LookupEnv(deprecatedEnvReuseport) + if exist { + log.Warning("IPFS_REUSEPORT is deprecated, use LIBP2P_TCP_REUSEPORT instead") + if v == "false" || v == "f" || v == "0" { + envReuseportVal = false + log.Infof("REUSEPORT disabled (IPFS_REUSEPORT=%s)", v) + } + } +} + +// reuseportIsAvailable returns whether reuseport is available to be used. This +// is here because we want to be able to turn reuseport on and off selectively. +// For now we use an ENV variable, as this handles our pressing need: +// +// LIBP2P_TCP_REUSEPORT=false ipfs daemon +// +// If this becomes a sought after feature, we could add this to the config. +// In the end, reuseport is a stop-gap. +func ReuseportIsAvailable() bool { + return envReuseportVal && reuseport.Available() +} diff --git a/vendor/github.com/libp2p/go-tcp-transport/tcp.go b/vendor/github.com/libp2p/go-tcp-transport/tcp.go new file mode 100644 index 00000000..1483d67e --- /dev/null +++ b/vendor/github.com/libp2p/go-tcp-transport/tcp.go @@ -0,0 +1,144 @@ +package tcp + +import ( + "context" + "net" + "time" + + logging "github.com/ipfs/go-log" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + rtpt "github.com/libp2p/go-reuseport-transport" + + ma "github.com/multiformats/go-multiaddr" + mafmt "github.com/multiformats/go-multiaddr-fmt" + manet "github.com/multiformats/go-multiaddr-net" +) + +// DefaultConnectTimeout is the (default) maximum amount of time the TCP +// transport will spend on the initial TCP connect before giving up. +var DefaultConnectTimeout = 5 * time.Second + +var log = logging.Logger("tcp-tpt") + +// try to set linger on the connection, if possible. +func tryLinger(conn net.Conn, sec int) { + type canLinger interface { + SetLinger(int) error + } + + if lingerConn, ok := conn.(canLinger); ok { + _ = lingerConn.SetLinger(sec) + } +} + +type lingerListener struct { + manet.Listener + sec int +} + +func (ll *lingerListener) Accept() (manet.Conn, error) { + c, err := ll.Listener.Accept() + if err != nil { + return nil, err + } + tryLinger(c, ll.sec) + return c, nil +} + +// TcpTransport is the TCP transport. +type TcpTransport struct { + // Connection upgrader for upgrading insecure stream connections to + // secure multiplex connections. + Upgrader *tptu.Upgrader + + // Explicitly disable reuseport. + DisableReuseport bool + + // TCP connect timeout + ConnectTimeout time.Duration + + reuse rtpt.Transport +} + +var _ transport.Transport = &TcpTransport{} + +// NewTCPTransport creates a tcp transport object that tracks dialers and listeners +// created. It represents an entire tcp stack (though it might not necessarily be) +func NewTCPTransport(upgrader *tptu.Upgrader) *TcpTransport { + return &TcpTransport{Upgrader: upgrader, ConnectTimeout: DefaultConnectTimeout} +} + +// CanDial returns true if this transport believes it can dial the given +// multiaddr. +func (t *TcpTransport) CanDial(addr ma.Multiaddr) bool { + return mafmt.TCP.Matches(addr) +} + +func (t *TcpTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) { + // Apply the deadline iff applicable + if t.ConnectTimeout > 0 { + deadline := time.Now().Add(t.ConnectTimeout) + if d, ok := ctx.Deadline(); !ok || deadline.Before(d) { + var cancel func() + ctx, cancel = context.WithDeadline(ctx, deadline) + defer cancel() + } + } + + if t.UseReuseport() { + return t.reuse.DialContext(ctx, raddr) + } + var d manet.Dialer + return d.DialContext(ctx, raddr) +} + +// Dial dials the peer at the remote address. +func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (transport.CapableConn, error) { + conn, err := t.maDial(ctx, raddr) + if err != nil { + return nil, err + } + // Set linger to 0 so we never get stuck in the TIME-WAIT state. When + // linger is 0, connections are _reset_ instead of closed with a FIN. + // This means we can immediately reuse the 5-tuple and reconnect. + tryLinger(conn, 0) + return t.Upgrader.UpgradeOutbound(ctx, t, conn, p) +} + +// UseReuseport returns true if reuseport is enabled and available. +func (t *TcpTransport) UseReuseport() bool { + return !t.DisableReuseport && ReuseportIsAvailable() +} + +func (t *TcpTransport) maListen(laddr ma.Multiaddr) (manet.Listener, error) { + if t.UseReuseport() { + return t.reuse.Listen(laddr) + } + return manet.Listen(laddr) +} + +// Listen listens on the given multiaddr. +func (t *TcpTransport) Listen(laddr ma.Multiaddr) (transport.Listener, error) { + list, err := t.maListen(laddr) + if err != nil { + return nil, err + } + list = &lingerListener{list, 0} + return t.Upgrader.UpgradeListener(t, list), nil +} + +// Protocols returns the list of terminal protocols this transport can dial. +func (t *TcpTransport) Protocols() []int { + return []int{ma.P_TCP} +} + +// Proxy always returns false for the TCP transport. +func (t *TcpTransport) Proxy() bool { + return false +} + +func (t *TcpTransport) String() string { + return "TCP" +} diff --git a/vendor/github.com/libp2p/go-ws-transport/.travis.yml b/vendor/github.com/libp2p/go-ws-transport/.travis.yml new file mode 100644 index 00000000..5163d693 --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - $HOME/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/libp2p/go-ws-transport/README.md b/vendor/github.com/libp2p/go-ws-transport/README.md new file mode 100644 index 00000000..e9c52a0d --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/README.md @@ -0,0 +1,43 @@ +# go-ws-transport + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) +[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) +[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) +[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) +[![GoDoc](https://godoc.org/github.com/libp2p/go-ws-transport?status.svg)](https://godoc.org/github.com/libp2p/go-ws-transport) +[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-ws-transport/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-ws-transport?branch=master) +[![Build Status](https://travis-ci.org/libp2p/go-ws-transport.svg?branch=master)](https://travis-ci.org/libp2p/go-ws-transport) + +> go-libp2p websocket transport + +## Install + +```sh +> go get github.com/libp2p/go-ws-transport +``` + +This repo is [gomod](https://github.com/golang/go/wiki/Modules)-compatible, and users of +go 1.11 and later with modules enabled will automatically pull the latest tagged release +by referencing this package. Upgrades to future releases can be managed using `go get`, +or by editing your `go.mod` file as [described by the gomod documentation](https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies). + +## Usage + + +## Contribute + +Feel free to join in. All welcome. Open an [issue](https://github.com/libp2p/go-ws-transport/issues)! + +This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +### Want to hack on IPFS? + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) + +## License + +MIT + +--- + +The last gx published version of this module was: 2.0.27: QmaSWc4ox6SZQF6DHZvDuM9sP1syNajkKuPXmKR1t5BAz5 diff --git a/vendor/github.com/libp2p/go-ws-transport/addrs.go b/vendor/github.com/libp2p/go-ws-transport/addrs.go new file mode 100644 index 00000000..e5dbc46e --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/addrs.go @@ -0,0 +1,73 @@ +package websocket + +import ( + "fmt" + "net" + "net/url" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +// Addr is an implementation of net.Addr for WebSocket. +type Addr struct { + *url.URL +} + +var _ net.Addr = (*Addr)(nil) + +// Network returns the network type for a WebSocket, "websocket". +func (addr *Addr) Network() string { + return "websocket" +} + +// NewAddr creates a new Addr using the given host string +func NewAddr(host string) *Addr { + return &Addr{ + URL: &url.URL{ + Host: host, + }, + } +} + +func ConvertWebsocketMultiaddrToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { + _, host, err := manet.DialArgs(maddr) + if err != nil { + return nil, err + } + + return NewAddr(host), nil +} + +func ParseWebsocketNetAddr(a net.Addr) (ma.Multiaddr, error) { + wsa, ok := a.(*Addr) + if !ok { + return nil, fmt.Errorf("not a websocket address") + } + + tcpaddr, err := net.ResolveTCPAddr("tcp", wsa.Host) + if err != nil { + return nil, err + } + + tcpma, err := manet.FromNetAddr(tcpaddr) + if err != nil { + return nil, err + } + + wsma, err := ma.NewMultiaddr("/ws") + if err != nil { + return nil, err + } + + return tcpma.Encapsulate(wsma), nil +} + +func parseMultiaddr(a ma.Multiaddr) (string, error) { + _, host, err := manet.DialArgs(a) + if err != nil { + return "", err + } + + return "ws://" + host, nil +} diff --git a/vendor/github.com/libp2p/go-ws-transport/codecov.yml b/vendor/github.com/libp2p/go-ws-transport/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/libp2p/go-ws-transport/conn.go b/vendor/github.com/libp2p/go-ws-transport/conn.go new file mode 100644 index 00000000..b63a28a9 --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/conn.go @@ -0,0 +1,129 @@ +package websocket + +import ( + "io" + "net" + "sync" + "time" + + ws "github.com/gorilla/websocket" +) + +// GracefulCloseTimeout is the time to wait trying to gracefully close a +// connection before simply cutting it. +var GracefulCloseTimeout = 100 * time.Millisecond + +var _ net.Conn = (*Conn)(nil) + +// Conn implements net.Conn interface for gorilla/websocket. +type Conn struct { + *ws.Conn + DefaultMessageType int + reader io.Reader + closeOnce sync.Once +} + +func (c *Conn) Read(b []byte) (int, error) { + if c.reader == nil { + if err := c.prepNextReader(); err != nil { + return 0, err + } + } + + for { + n, err := c.reader.Read(b) + switch err { + case io.EOF: + c.reader = nil + + if n > 0 { + return n, nil + } + + if err := c.prepNextReader(); err != nil { + return 0, err + } + + // explicitly looping + default: + return n, err + } + } +} + +func (c *Conn) prepNextReader() error { + t, r, err := c.Conn.NextReader() + if err != nil { + if wserr, ok := err.(*ws.CloseError); ok { + if wserr.Code == 1000 || wserr.Code == 1005 { + return io.EOF + } + } + return err + } + + if t == ws.CloseMessage { + return io.EOF + } + + c.reader = r + return nil +} + +func (c *Conn) Write(b []byte) (n int, err error) { + if err := c.Conn.WriteMessage(c.DefaultMessageType, b); err != nil { + return 0, err + } + + return len(b), nil +} + +// Close closes the connection. Only the first call to Close will receive the +// close error, subsequent and concurrent calls will return nil. +// This method is thread-safe. +func (c *Conn) Close() error { + var err error + c.closeOnce.Do(func() { + err1 := c.Conn.WriteControl(ws.CloseMessage, nil, time.Now().Add(GracefulCloseTimeout)) + err2 := c.Conn.Close() + switch { + case err1 != nil: + err = err1 + case err2 != nil: + err = err2 + } + }) + return err +} + +func (c *Conn) LocalAddr() net.Addr { + return NewAddr(c.Conn.LocalAddr().String()) +} + +func (c *Conn) RemoteAddr() net.Addr { + return NewAddr(c.Conn.RemoteAddr().String()) +} + +func (c *Conn) SetDeadline(t time.Time) error { + if err := c.SetReadDeadline(t); err != nil { + return err + } + + return c.SetWriteDeadline(t) +} + +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.Conn.SetReadDeadline(t) +} + +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.Conn.SetWriteDeadline(t) +} + +// NewConn creates a Conn given a regular gorilla/websocket Conn. +func NewConn(raw *ws.Conn) *Conn { + return &Conn{ + Conn: raw, + DefaultMessageType: ws.BinaryMessage, + } +} diff --git a/vendor/github.com/libp2p/go-ws-transport/go.mod b/vendor/github.com/libp2p/go-ws-transport/go.mod new file mode 100644 index 00000000..b25b7dff --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/go.mod @@ -0,0 +1,12 @@ +module github.com/libp2p/go-ws-transport + +require ( + github.com/gorilla/websocket v1.4.0 + github.com/libp2p/go-libp2p-core v0.0.1 + github.com/libp2p/go-libp2p-mplex v0.2.0 + github.com/libp2p/go-libp2p-testing v0.0.3 + github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 + github.com/multiformats/go-multiaddr v0.0.4 + github.com/multiformats/go-multiaddr-net v0.0.1 + github.com/whyrusleeping/mafmt v1.2.8 +) diff --git a/vendor/github.com/libp2p/go-ws-transport/go.sum b/vendor/github.com/libp2p/go-ws-transport/go.sum new file mode 100644 index 00000000..ad6d7b54 --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/go.sum @@ -0,0 +1,126 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2 h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-mplex v0.2.0 h1:vnR+/fUnL5d2kTB1Lfce1KVSP+bCCy2aJIvqvb9cFqE= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-testing v0.0.3 h1:bdij4bKaaND7tCsaXVjRfYkMpvoOeKj9AVQGJllA6jM= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3 h1:YiMaevQcZtFU6DmKIF8xEO0vaui5kM5HJ1V1xkWQv14= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4 h1:WgMSI84/eRLdbptXMkMWDXPjPq7SPLIgGUVm2eroyU4= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mafmt v1.2.8 h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/libp2p/go-ws-transport/listener.go b/vendor/github.com/libp2p/go-ws-transport/listener.go new file mode 100644 index 00000000..517c719a --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/listener.go @@ -0,0 +1,62 @@ +package websocket + +import ( + "fmt" + "net" + "net/http" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" +) + +type listener struct { + net.Listener + + laddr ma.Multiaddr + + closed chan struct{} + incoming chan *Conn +} + +func (l *listener) serve() { + defer close(l.closed) + _ = http.Serve(l.Listener, l) +} + +func (l *listener) ServeHTTP(w http.ResponseWriter, r *http.Request) { + c, err := upgrader.Upgrade(w, r, nil) + if err != nil { + // The upgrader writes a response for us. + return + } + + select { + case l.incoming <- NewConn(c): + case <-l.closed: + c.Close() + } + // The connection has been hijacked, it's safe to return. +} + +func (l *listener) Accept() (manet.Conn, error) { + select { + case c, ok := <-l.incoming: + if !ok { + return nil, fmt.Errorf("listener is closed") + } + + mnc, err := manet.WrapNetConn(c) + if err != nil { + c.Close() + return nil, err + } + + return mnc, nil + case <-l.closed: + return nil, fmt.Errorf("listener is closed") + } +} + +func (l *listener) Multiaddr() ma.Multiaddr { + return l.laddr +} diff --git a/vendor/github.com/libp2p/go-ws-transport/websocket.go b/vendor/github.com/libp2p/go-ws-transport/websocket.go new file mode 100644 index 00000000..972681a6 --- /dev/null +++ b/vendor/github.com/libp2p/go-ws-transport/websocket.go @@ -0,0 +1,160 @@ +// Package websocket implements a websocket based transport for go-libp2p. +package websocket + +import ( + "context" + "fmt" + "net" + "net/http" + "net/url" + + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + + ws "github.com/gorilla/websocket" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" + mafmt "github.com/whyrusleeping/mafmt" +) + +// WsProtocol is the multiaddr protocol definition for this transport. +var WsProtocol = ma.Protocol{ + Code: 477, + Name: "ws", + VCode: ma.CodeToVarint(477), +} + +// WsFmt is multiaddr formatter for WsProtocol +var WsFmt = mafmt.And(mafmt.TCP, mafmt.Base(WsProtocol.Code)) + +// WsCodec is the multiaddr-net codec definition for the websocket transport +var WsCodec = &manet.NetCodec{ + NetAddrNetworks: []string{"websocket"}, + ProtocolName: "ws", + ConvertMultiaddr: ConvertWebsocketMultiaddrToNetAddr, + ParseNetAddr: ParseWebsocketNetAddr, +} + +// Default gorilla upgrader +var upgrader = ws.Upgrader{ + // Allow requests from *all* origins. + CheckOrigin: func(r *http.Request) bool { + return true + }, +} + +func init() { + err := ma.AddProtocol(WsProtocol) + if err != nil { + panic(fmt.Errorf("error registering websocket protocol: %s", err)) + } + + manet.RegisterNetCodec(WsCodec) +} + +// WebsocketTransport is the actual go-libp2p transport +type WebsocketTransport struct { + Upgrader *tptu.Upgrader +} + +func New(u *tptu.Upgrader) *WebsocketTransport { + return &WebsocketTransport{u} +} + +var _ transport.Transport = (*WebsocketTransport)(nil) + +func (t *WebsocketTransport) CanDial(a ma.Multiaddr) bool { + return WsFmt.Matches(a) +} + +func (t *WebsocketTransport) Protocols() []int { + return []int{WsProtocol.Code} +} + +func (t *WebsocketTransport) Proxy() bool { + return false +} + +func (t *WebsocketTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (manet.Conn, error) { + wsurl, err := parseMultiaddr(raddr) + if err != nil { + return nil, err + } + + wscon, _, err := ws.DefaultDialer.Dial(wsurl, nil) + if err != nil { + return nil, err + } + + mnc, err := manet.WrapNetConn(NewConn(wscon)) + if err != nil { + wscon.Close() + return nil, err + } + return mnc, nil +} + +func (t *WebsocketTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (transport.CapableConn, error) { + macon, err := t.maDial(ctx, raddr) + if err != nil { + return nil, err + } + return t.Upgrader.UpgradeOutbound(ctx, t, macon, p) +} + +func (t *WebsocketTransport) maListen(a ma.Multiaddr) (manet.Listener, error) { + lnet, lnaddr, err := manet.DialArgs(a) + if err != nil { + return nil, err + } + + nl, err := net.Listen(lnet, lnaddr) + if err != nil { + return nil, err + } + + u, err := url.Parse("http://" + nl.Addr().String()) + if err != nil { + nl.Close() + return nil, err + } + + malist, err := t.wrapListener(nl, u) + if err != nil { + nl.Close() + return nil, err + } + + go malist.serve() + + return malist, nil +} + +func (t *WebsocketTransport) Listen(a ma.Multiaddr) (transport.Listener, error) { + malist, err := t.maListen(a) + if err != nil { + return nil, err + } + return t.Upgrader.UpgradeListener(t, malist), nil +} + +func (t *WebsocketTransport) wrapListener(l net.Listener, origin *url.URL) (*listener, error) { + laddr, err := manet.FromNetAddr(l.Addr()) + if err != nil { + return nil, err + } + wsma, err := ma.NewMultiaddr("/ws") + if err != nil { + return nil, err + } + laddr = laddr.Encapsulate(wsma) + + return &listener{ + laddr: laddr, + Listener: l, + incoming: make(chan *Conn), + closed: make(chan struct{}), + }, nil +} diff --git a/vendor/github.com/libp2p/go-yamux/.gitignore b/vendor/github.com/libp2p/go-yamux/.gitignore new file mode 100644 index 00000000..83656241 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/.gitignore @@ -0,0 +1,23 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test diff --git a/vendor/github.com/libp2p/go-yamux/LICENSE b/vendor/github.com/libp2p/go-yamux/LICENSE new file mode 100644 index 00000000..f0e5c79e --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/LICENSE @@ -0,0 +1,362 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-yamux/LICENSE-BSD b/vendor/github.com/libp2p/go-yamux/LICENSE-BSD new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/LICENSE-BSD @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +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. diff --git a/vendor/github.com/libp2p/go-yamux/README.md b/vendor/github.com/libp2p/go-yamux/README.md new file mode 100644 index 00000000..dabeec72 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/README.md @@ -0,0 +1,86 @@ +# Yamux + +Yamux (Yet another Multiplexer) is a multiplexing library for Golang. +It relies on an underlying connection to provide reliability +and ordering, such as TCP or Unix domain sockets, and provides +stream-oriented multiplexing. It is inspired by SPDY but is not +interoperable with it. + +Yamux features include: + +* Bi-directional streams + * Streams can be opened by either client or server + * Useful for NAT traversal + * Server-side push support +* Flow control + * Avoid starvation + * Back-pressure to prevent overwhelming a receiver +* Keep Alives + * Enables persistent connections over a load balancer +* Efficient + * Enables thousands of logical streams with low overhead + +## Documentation + +For complete documentation, see the associated [Godoc](http://godoc.org/github.com/libp2p/go-yamux). + +## Specification + +The full specification for Yamux is provided in the `spec.md` file. +It can be used as a guide to implementors of interoperable libraries. + +## Usage + +Using Yamux is remarkably simple: + +```go + +func client() { + // Get a TCP connection + conn, err := net.Dial(...) + if err != nil { + panic(err) + } + + // Setup client side of yamux + session, err := yamux.Client(conn, nil) + if err != nil { + panic(err) + } + + // Open a new stream + stream, err := session.Open() + if err != nil { + panic(err) + } + + // Stream implements net.Conn + stream.Write([]byte("ping")) +} + +func server() { + // Accept a TCP connection + conn, err := listener.Accept() + if err != nil { + panic(err) + } + + // Setup server side of yamux + session, err := yamux.Server(conn, nil) + if err != nil { + panic(err) + } + + // Accept a stream + stream, err := session.Accept() + if err != nil { + panic(err) + } + + // Listen for a message + buf := make([]byte, 4) + stream.Read(buf) +} + +``` + diff --git a/vendor/github.com/libp2p/go-yamux/addr.go b/vendor/github.com/libp2p/go-yamux/addr.go new file mode 100644 index 00000000..be6ebca9 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/addr.go @@ -0,0 +1,60 @@ +package yamux + +import ( + "fmt" + "net" +) + +// hasAddr is used to get the address from the underlying connection +type hasAddr interface { + LocalAddr() net.Addr + RemoteAddr() net.Addr +} + +// yamuxAddr is used when we cannot get the underlying address +type yamuxAddr struct { + Addr string +} + +func (*yamuxAddr) Network() string { + return "yamux" +} + +func (y *yamuxAddr) String() string { + return fmt.Sprintf("yamux:%s", y.Addr) +} + +// Addr is used to get the address of the listener. +func (s *Session) Addr() net.Addr { + return s.LocalAddr() +} + +// LocalAddr is used to get the local address of the +// underlying connection. +func (s *Session) LocalAddr() net.Addr { + addr, ok := s.conn.(hasAddr) + if !ok { + return &yamuxAddr{"local"} + } + return addr.LocalAddr() +} + +// RemoteAddr is used to get the address of remote end +// of the underlying connection +func (s *Session) RemoteAddr() net.Addr { + addr, ok := s.conn.(hasAddr) + if !ok { + return &yamuxAddr{"remote"} + } + return addr.RemoteAddr() +} + +// LocalAddr returns the local address +func (s *Stream) LocalAddr() net.Addr { + return s.session.LocalAddr() +} + +// LocalAddr returns the remote address +func (s *Stream) RemoteAddr() net.Addr { + return s.session.RemoteAddr() +} diff --git a/vendor/github.com/libp2p/go-yamux/const.go b/vendor/github.com/libp2p/go-yamux/const.go new file mode 100644 index 00000000..ca9c14cf --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/const.go @@ -0,0 +1,176 @@ +package yamux + +import ( + "encoding/binary" + "fmt" +) + +type YamuxError struct { + msg string + timeout, temporary bool +} + +func (ye YamuxError) Error() string { + return ye.msg +} + +func (ye YamuxError) Timeout() bool { + return ye.timeout +} + +func (ye YamuxError) Temporary() bool { + return ye.temporary +} + +var ( + // ErrInvalidVersion means we received a frame with an + // invalid version + ErrInvalidVersion = &YamuxError{msg: "invalid protocol version"} + + // ErrInvalidMsgType means we received a frame with an + // invalid message type + ErrInvalidMsgType = &YamuxError{msg: "invalid msg type"} + + // ErrSessionShutdown is used if there is a shutdown during + // an operation + ErrSessionShutdown = &YamuxError{msg: "session shutdown"} + + // ErrStreamsExhausted is returned if we have no more + // stream ids to issue + ErrStreamsExhausted = &YamuxError{msg: "streams exhausted"} + + // ErrDuplicateStream is used if a duplicate stream is + // opened inbound + ErrDuplicateStream = &YamuxError{msg: "duplicate stream initiated"} + + // ErrReceiveWindowExceeded indicates the window was exceeded + ErrRecvWindowExceeded = &YamuxError{msg: "recv window exceeded"} + + // ErrTimeout is used when we reach an IO deadline + ErrTimeout = &YamuxError{msg: "i/o deadline reached", timeout: true, temporary: true} + + // ErrStreamClosed is returned when using a closed stream + ErrStreamClosed = &YamuxError{msg: "stream closed"} + + // ErrUnexpectedFlag is set when we get an unexpected flag + ErrUnexpectedFlag = &YamuxError{msg: "unexpected flag"} + + // ErrRemoteGoAway is used when we get a go away from the other side + ErrRemoteGoAway = &YamuxError{msg: "remote end is not accepting connections"} + + // ErrConnectionReset is sent if a stream is reset. This can happen + // if the backlog is exceeded, or if there was a remote GoAway. + ErrConnectionReset = &YamuxError{msg: "stream reset"} + + // ErrConnectionWriteTimeout indicates that we hit the "safety valve" + // timeout writing to the underlying stream connection. + ErrConnectionWriteTimeout = &YamuxError{msg: "connection write timeout", timeout: true} + + // ErrKeepAliveTimeout is sent if a missed keepalive caused the stream close + ErrKeepAliveTimeout = &YamuxError{msg: "keepalive timeout", timeout: true} +) + +const ( + // protoVersion is the only version we support + protoVersion uint8 = 0 +) + +const ( + // Data is used for data frames. They are followed + // by length bytes worth of payload. + typeData uint8 = iota + + // WindowUpdate is used to change the window of + // a given stream. The length indicates the delta + // update to the window. + typeWindowUpdate + + // Ping is sent as a keep-alive or to measure + // the RTT. The StreamID and Length value are echoed + // back in the response. + typePing + + // GoAway is sent to terminate a session. The StreamID + // should be 0 and the length is an error code. + typeGoAway +) + +const ( + // SYN is sent to signal a new stream. May + // be sent with a data payload + flagSYN uint16 = 1 << iota + + // ACK is sent to acknowledge a new stream. May + // be sent with a data payload + flagACK + + // FIN is sent to half-close the given stream. + // May be sent with a data payload. + flagFIN + + // RST is used to hard close a given stream. + flagRST +) + +const ( + // initialStreamWindow is the initial stream window size + initialStreamWindow uint32 = 256 * 1024 +) + +const ( + // goAwayNormal is sent on a normal termination + goAwayNormal uint32 = iota + + // goAwayProtoErr sent on a protocol error + goAwayProtoErr + + // goAwayInternalErr sent on an internal error + goAwayInternalErr +) + +const ( + sizeOfVersion = 1 + sizeOfType = 1 + sizeOfFlags = 2 + sizeOfStreamID = 4 + sizeOfLength = 4 + headerSize = sizeOfVersion + sizeOfType + sizeOfFlags + + sizeOfStreamID + sizeOfLength +) + +type header [headerSize]byte + +func (h header) Version() uint8 { + return h[0] +} + +func (h header) MsgType() uint8 { + return h[1] +} + +func (h header) Flags() uint16 { + return binary.BigEndian.Uint16(h[2:4]) +} + +func (h header) StreamID() uint32 { + return binary.BigEndian.Uint32(h[4:8]) +} + +func (h header) Length() uint32 { + return binary.BigEndian.Uint32(h[8:12]) +} + +func (h header) String() string { + return fmt.Sprintf("Vsn:%d Type:%d Flags:%d StreamID:%d Length:%d", + h.Version(), h.MsgType(), h.Flags(), h.StreamID(), h.Length()) +} + +func encode(msgType uint8, flags uint16, streamID uint32, length uint32) header { + var h header + h[0] = protoVersion + h[1] = msgType + binary.BigEndian.PutUint16(h[2:4], flags) + binary.BigEndian.PutUint32(h[4:8], streamID) + binary.BigEndian.PutUint32(h[8:12], length) + return h +} diff --git a/vendor/github.com/libp2p/go-yamux/deadline.go b/vendor/github.com/libp2p/go-yamux/deadline.go new file mode 100644 index 00000000..16da56dd --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/deadline.go @@ -0,0 +1,80 @@ +// Copied from the go standard library. +// +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE-BSD file. + +package yamux + +import ( + "sync" + "time" +) + +// pipeDeadline is an abstraction for handling timeouts. +type pipeDeadline struct { + mu sync.Mutex // Guards timer and cancel + timer *time.Timer + cancel chan struct{} // Must be non-nil +} + +func makePipeDeadline() pipeDeadline { + return pipeDeadline{cancel: make(chan struct{})} +} + +// set sets the point in time when the deadline will time out. +// A timeout event is signaled by closing the channel returned by waiter. +// Once a timeout has occurred, the deadline can be refreshed by specifying a +// t value in the future. +// +// A zero value for t prevents timeout. +func (d *pipeDeadline) set(t time.Time) { + d.mu.Lock() + defer d.mu.Unlock() + + if d.timer != nil && !d.timer.Stop() { + <-d.cancel // Wait for the timer callback to finish and close cancel + } + d.timer = nil + + // Time is zero, then there is no deadline. + closed := isClosedChan(d.cancel) + if t.IsZero() { + if closed { + d.cancel = make(chan struct{}) + } + return + } + + // Time in the future, setup a timer to cancel in the future. + if dur := time.Until(t); dur > 0 { + if closed { + d.cancel = make(chan struct{}) + } + d.timer = time.AfterFunc(dur, func() { + close(d.cancel) + }) + return + } + + // Time in the past, so close immediately. + if !closed { + close(d.cancel) + } +} + +// wait returns a channel that is closed when the deadline is exceeded. +func (d *pipeDeadline) wait() chan struct{} { + d.mu.Lock() + defer d.mu.Unlock() + return d.cancel +} + +func isClosedChan(c <-chan struct{}) bool { + select { + case <-c: + return true + default: + return false + } +} diff --git a/vendor/github.com/libp2p/go-yamux/go.mod b/vendor/github.com/libp2p/go-yamux/go.mod new file mode 100644 index 00000000..0feb3c92 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/go.mod @@ -0,0 +1,5 @@ +module github.com/libp2p/go-yamux + +go 1.12 + +require github.com/libp2p/go-buffer-pool v0.0.2 diff --git a/vendor/github.com/libp2p/go-yamux/go.sum b/vendor/github.com/libp2p/go-yamux/go.sum new file mode 100644 index 00000000..012e1223 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/go.sum @@ -0,0 +1,2 @@ +github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= diff --git a/vendor/github.com/libp2p/go-yamux/mux.go b/vendor/github.com/libp2p/go-yamux/mux.go new file mode 100644 index 00000000..a8d7064a --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/mux.go @@ -0,0 +1,111 @@ +package yamux + +import ( + "fmt" + "io" + "net" + "os" + "time" +) + +// Config is used to tune the Yamux session +type Config struct { + // AcceptBacklog is used to limit how many streams may be + // waiting an accept. + AcceptBacklog int + + // EnableKeepalive is used to do a period keep alive + // messages using a ping. + EnableKeepAlive bool + + // KeepAliveInterval is how often to perform the keep alive + KeepAliveInterval time.Duration + + // ConnectionWriteTimeout is meant to be a "safety valve" timeout after + // we which will suspect a problem with the underlying connection and + // close it. This is only applied to writes, where's there's generally + // an expectation that things will move along quickly. + ConnectionWriteTimeout time.Duration + + // MaxStreamWindowSize is used to control the maximum + // window size that we allow for a stream. + MaxStreamWindowSize uint32 + + // LogOutput is used to control the log destination + LogOutput io.Writer + + // ReadBufSize controls the size of the read buffer. + // + // Set to 0 to disable it. + ReadBufSize int + + // WriteCoalesceDelay is the maximum amount of time we'll delay + // coalescing a packet before sending it. This should be on the order of + // micro-milliseconds. + WriteCoalesceDelay time.Duration + + // MaxMessageSize is the maximum size of a message that we'll send on a + // stream. This ensures that a single stream doesn't hog a connection. + MaxMessageSize uint32 +} + +// DefaultConfig is used to return a default configuration +func DefaultConfig() *Config { + return &Config{ + AcceptBacklog: 256, + EnableKeepAlive: true, + KeepAliveInterval: 30 * time.Second, + ConnectionWriteTimeout: 10 * time.Second, + MaxStreamWindowSize: initialStreamWindow, + LogOutput: os.Stderr, + ReadBufSize: 4096, + MaxMessageSize: 64 * 1024, // Means 64KiB/10s = 52kbps minimum speed. + WriteCoalesceDelay: 100 * time.Microsecond, + } +} + +// VerifyConfig is used to verify the sanity of configuration +func VerifyConfig(config *Config) error { + if config.AcceptBacklog <= 0 { + return fmt.Errorf("backlog must be positive") + } + if config.KeepAliveInterval == 0 { + return fmt.Errorf("keep-alive interval must be positive") + } + if config.MaxStreamWindowSize < initialStreamWindow { + return fmt.Errorf("MaxStreamWindowSize must be larger than %d", initialStreamWindow) + } + if config.MaxMessageSize < 1024 { + return fmt.Errorf("MaxMessageSize must be greater than a kilobyte") + } + if config.WriteCoalesceDelay < 0 { + return fmt.Errorf("WriteCoalesceDelay must be >= 0") + } + return nil +} + +// Server is used to initialize a new server-side connection. +// There must be at most one server-side connection. If a nil config is +// provided, the DefaultConfiguration will be used. +func Server(conn net.Conn, config *Config) (*Session, error) { + if config == nil { + config = DefaultConfig() + } + if err := VerifyConfig(config); err != nil { + return nil, err + } + return newSession(config, conn, false, config.ReadBufSize), nil +} + +// Client is used to initialize a new client-side connection. +// There must be at most one client-side connection. +func Client(conn net.Conn, config *Config) (*Session, error) { + if config == nil { + config = DefaultConfig() + } + + if err := VerifyConfig(config); err != nil { + return nil, err + } + return newSession(config, conn, true, config.ReadBufSize), nil +} diff --git a/vendor/github.com/libp2p/go-yamux/session.go b/vendor/github.com/libp2p/go-yamux/session.go new file mode 100644 index 00000000..4af4c055 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/session.go @@ -0,0 +1,704 @@ +package yamux + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "log" + "math" + "net" + "os" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/libp2p/go-buffer-pool" +) + +// Session is used to wrap a reliable ordered connection and to +// multiplex it into multiple streams. +type Session struct { + // remoteGoAway indicates the remote side does + // not want futher connections. Must be first for alignment. + remoteGoAway int32 + + // localGoAway indicates that we should stop + // accepting futher connections. Must be first for alignment. + localGoAway int32 + + // nextStreamID is the next stream we should + // send. This depends if we are a client/server. + nextStreamID uint32 + + // config holds our configuration + config *Config + + // logger is used for our logs + logger *log.Logger + + // conn is the underlying connection + conn net.Conn + + // reader is a buffered reader + reader io.Reader + + // pings is used to track inflight pings + pings map[uint32]chan struct{} + pingID uint32 + pingLock sync.Mutex + + // streams maps a stream id to a stream, and inflight has an entry + // for any outgoing stream that has not yet been established. Both are + // protected by streamLock. + streams map[uint32]*Stream + inflight map[uint32]struct{} + streamLock sync.Mutex + + // synCh acts like a semaphore. It is sized to the AcceptBacklog which + // is assumed to be symmetric between the client and server. This allows + // the client to avoid exceeding the backlog and instead blocks the open. + synCh chan struct{} + + // acceptCh is used to pass ready streams to the client + acceptCh chan *Stream + + // sendCh is used to send messages + sendCh chan []byte + + // recvDoneCh is closed when recv() exits to avoid a race + // between stream registration and stream shutdown + recvDoneCh chan struct{} + + // sendDoneCh is closed when send() exits to avoid a race + // between returning from a Stream.Write and exiting from the send loop + // (which may be reading a buffer on-load-from Stream.Write). + sendDoneCh chan struct{} + + // client is true if we're the client and our stream IDs should be odd. + client bool + + // shutdown is used to safely close a session + shutdown bool + shutdownErr error + shutdownCh chan struct{} + shutdownLock sync.Mutex + + // keepaliveTimer is a periodic timer for keepalive messages. It's nil + // when keepalives are disabled. + keepaliveLock sync.Mutex + keepaliveTimer *time.Timer +} + +const ( + stageInitial uint32 = iota + stageFinal +) + +// newSession is used to construct a new session +func newSession(config *Config, conn net.Conn, client bool, readBuf int) *Session { + var reader io.Reader = conn + if readBuf > 0 { + reader = bufio.NewReaderSize(reader, readBuf) + } + s := &Session{ + config: config, + client: client, + logger: log.New(config.LogOutput, "", log.LstdFlags), + conn: conn, + reader: reader, + pings: make(map[uint32]chan struct{}), + streams: make(map[uint32]*Stream), + inflight: make(map[uint32]struct{}), + synCh: make(chan struct{}, config.AcceptBacklog), + acceptCh: make(chan *Stream, config.AcceptBacklog), + sendCh: make(chan []byte, 64), + recvDoneCh: make(chan struct{}), + sendDoneCh: make(chan struct{}), + shutdownCh: make(chan struct{}), + } + if client { + s.nextStreamID = 1 + } else { + s.nextStreamID = 2 + } + if config.EnableKeepAlive { + s.startKeepalive() + } + go s.recv() + go s.send() + return s +} + +// IsClosed does a safe check to see if we have shutdown +func (s *Session) IsClosed() bool { + select { + case <-s.shutdownCh: + return true + default: + return false + } +} + +// CloseChan returns a read-only channel which is closed as +// soon as the session is closed. +func (s *Session) CloseChan() <-chan struct{} { + return s.shutdownCh +} + +// NumStreams returns the number of currently open streams +func (s *Session) NumStreams() int { + s.streamLock.Lock() + num := len(s.streams) + s.streamLock.Unlock() + return num +} + +// Open is used to create a new stream as a net.Conn +func (s *Session) Open() (net.Conn, error) { + conn, err := s.OpenStream() + if err != nil { + return nil, err + } + return conn, nil +} + +// OpenStream is used to create a new stream +func (s *Session) OpenStream() (*Stream, error) { + if s.IsClosed() { + return nil, s.shutdownErr + } + if atomic.LoadInt32(&s.remoteGoAway) == 1 { + return nil, ErrRemoteGoAway + } + + // Block if we have too many inflight SYNs + select { + case s.synCh <- struct{}{}: + case <-s.shutdownCh: + return nil, s.shutdownErr + } + +GET_ID: + // Get an ID, and check for stream exhaustion + id := atomic.LoadUint32(&s.nextStreamID) + if id >= math.MaxUint32-1 { + return nil, ErrStreamsExhausted + } + if !atomic.CompareAndSwapUint32(&s.nextStreamID, id, id+2) { + goto GET_ID + } + + // Register the stream + stream := newStream(s, id, streamInit) + s.streamLock.Lock() + s.streams[id] = stream + s.inflight[id] = struct{}{} + s.streamLock.Unlock() + + // Send the window update to create + if err := stream.sendWindowUpdate(); err != nil { + select { + case <-s.synCh: + default: + s.logger.Printf("[ERR] yamux: aborted stream open without inflight syn semaphore") + } + return nil, err + } + return stream, nil +} + +// Accept is used to block until the next available stream +// is ready to be accepted. +func (s *Session) Accept() (net.Conn, error) { + conn, err := s.AcceptStream() + if err != nil { + return nil, err + } + return conn, err +} + +// AcceptStream is used to block until the next available stream +// is ready to be accepted. +func (s *Session) AcceptStream() (*Stream, error) { + select { + case stream := <-s.acceptCh: + if err := stream.sendWindowUpdate(); err != nil { + return nil, err + } + return stream, nil + case <-s.shutdownCh: + return nil, s.shutdownErr + } +} + +// Close is used to close the session and all streams. +// Attempts to send a GoAway before closing the connection. +func (s *Session) Close() error { + s.shutdownLock.Lock() + defer s.shutdownLock.Unlock() + + if s.shutdown { + return nil + } + s.shutdown = true + if s.shutdownErr == nil { + s.shutdownErr = ErrSessionShutdown + } + close(s.shutdownCh) + s.conn.Close() + s.stopKeepalive() + <-s.recvDoneCh + <-s.sendDoneCh + + s.streamLock.Lock() + defer s.streamLock.Unlock() + for _, stream := range s.streams { + stream.forceClose() + } + return nil +} + +// exitErr is used to handle an error that is causing the +// session to terminate. +func (s *Session) exitErr(err error) { + s.shutdownLock.Lock() + if s.shutdownErr == nil { + s.shutdownErr = err + } + s.shutdownLock.Unlock() + s.Close() +} + +// GoAway can be used to prevent accepting further +// connections. It does not close the underlying conn. +func (s *Session) GoAway() error { + return s.sendMsg(s.goAway(goAwayNormal), nil, nil) +} + +// goAway is used to send a goAway message +func (s *Session) goAway(reason uint32) header { + atomic.SwapInt32(&s.localGoAway, 1) + hdr := encode(typeGoAway, 0, 0, reason) + return hdr +} + +// Ping is used to measure the RTT response time +func (s *Session) Ping() (time.Duration, error) { + // Get a channel for the ping + ch := make(chan struct{}) + + // Get a new ping id, mark as pending + s.pingLock.Lock() + id := s.pingID + s.pingID++ + s.pings[id] = ch + s.pingLock.Unlock() + + // Send the ping request + hdr := encode(typePing, flagSYN, 0, id) + if err := s.sendMsg(hdr, nil, nil); err != nil { + return 0, err + } + + // Wait for a response + start := time.Now() + select { + case <-ch: + case <-time.After(s.config.ConnectionWriteTimeout): + s.pingLock.Lock() + delete(s.pings, id) // Ignore it if a response comes later. + s.pingLock.Unlock() + return 0, ErrTimeout + case <-s.shutdownCh: + return 0, s.shutdownErr + } + + // Compute the RTT + return time.Now().Sub(start), nil +} + +// startKeepalive starts the keepalive process. +func (s *Session) startKeepalive() { + s.keepaliveLock.Lock() + defer s.keepaliveLock.Unlock() + s.keepaliveTimer = time.AfterFunc(s.config.KeepAliveInterval, func() { + s.keepaliveLock.Lock() + + if s.keepaliveTimer == nil { + s.keepaliveLock.Unlock() + // keepalives have been stopped. + return + } + _, err := s.Ping() + if err != nil { + // Make sure to unlock before exiting so we don't + // deadlock trying to shutdown keepalives. + s.keepaliveLock.Unlock() + s.logger.Printf("[ERR] yamux: keepalive failed: %v", err) + s.exitErr(ErrKeepAliveTimeout) + return + } + s.keepaliveTimer.Reset(s.config.KeepAliveInterval) + s.keepaliveLock.Unlock() + }) +} + +// stopKeepalive stops the keepalive process. +func (s *Session) stopKeepalive() { + s.keepaliveLock.Lock() + defer s.keepaliveLock.Unlock() + if s.keepaliveTimer != nil { + s.keepaliveTimer.Stop() + } +} + +// send sends the header and body. +func (s *Session) sendMsg(hdr header, body []byte, deadline <-chan struct{}) error { + select { + case <-s.shutdownCh: + return s.shutdownErr + default: + } + + // duplicate as we're sending this async. + buf := pool.Get(headerSize + len(body)) + copy(buf[:headerSize], hdr[:]) + copy(buf[headerSize:], body) + + select { + case <-s.shutdownCh: + pool.Put(buf) + return s.shutdownErr + case s.sendCh <- buf: + return nil + case <-deadline: + pool.Put(buf) + return ErrTimeout + } +} + +// send is a long running goroutine that sends data +func (s *Session) send() { + if err := s.sendLoop(); err != nil { + s.exitErr(err) + } +} + +func (s *Session) sendLoop() error { + defer close(s.sendDoneCh) + + // Extend the write deadline if we've passed the halfway point. This can + // be expensive so this ensures we only have to do this once every + // ConnectionWriteTimeout/2 (usually 5s). + var lastWriteDeadline time.Time + extendWriteDeadline := func() error { + now := time.Now() + // If over half of the deadline has elapsed, extend it. + if now.Add(s.config.ConnectionWriteTimeout / 2).After(lastWriteDeadline) { + lastWriteDeadline = now.Add(s.config.ConnectionWriteTimeout) + return s.conn.SetWriteDeadline(lastWriteDeadline) + } + return nil + } + + writer := s.conn + + // FIXME: https://github.com/libp2p/go-libp2p/issues/644 + // Write coalescing is disabled for now. + + //writer := pool.Writer{W: s.conn} + + //var writeTimeout *time.Timer + //var writeTimeoutCh <-chan time.Time + //if s.config.WriteCoalesceDelay > 0 { + // writeTimeout = time.NewTimer(s.config.WriteCoalesceDelay) + // defer writeTimeout.Stop() + + // writeTimeoutCh = writeTimeout.C + //} else { + // ch := make(chan time.Time) + // close(ch) + // writeTimeoutCh = ch + //} + + for { + // yield after processing the last message, if we've shutdown. + // s.sendCh is a buffered channel and Go doesn't guarantee select order. + select { + case <-s.shutdownCh: + return nil + default: + } + + // Flushes at least once every 100 microseconds unless we're + // constantly writing. + var buf []byte + select { + case buf = <-s.sendCh: + case <-s.shutdownCh: + return nil + //default: + // select { + // case buf = <-s.sendCh: + // case <-s.shutdownCh: + // return nil + // case <-writeTimeoutCh: + // if err := writer.Flush(); err != nil { + // if os.IsTimeout(err) { + // err = ErrConnectionWriteTimeout + // } + // return err + // } + + // select { + // case buf = <-s.sendCh: + // case <-s.shutdownCh: + // return nil + // } + + // if writeTimeout != nil { + // writeTimeout.Reset(s.config.WriteCoalesceDelay) + // } + // } + } + + if err := extendWriteDeadline(); err != nil { + pool.Put(buf) + return err + } + + _, err := writer.Write(buf) + pool.Put(buf) + + if err != nil { + if os.IsTimeout(err) { + err = ErrConnectionWriteTimeout + } + return err + } + } +} + +// recv is a long running goroutine that accepts new data +func (s *Session) recv() { + if err := s.recvLoop(); err != nil { + s.exitErr(err) + } +} + +// Ensure that the index of the handler (typeData/typeWindowUpdate/etc) matches the message type +var ( + handlers = []func(*Session, header) error{ + typeData: (*Session).handleStreamMessage, + typeWindowUpdate: (*Session).handleStreamMessage, + typePing: (*Session).handlePing, + typeGoAway: (*Session).handleGoAway, + } +) + +// recvLoop continues to receive data until a fatal error is encountered +func (s *Session) recvLoop() error { + defer close(s.recvDoneCh) + var hdr header + for { + // Read the header + if _, err := io.ReadFull(s.reader, hdr[:]); err != nil { + if err != io.EOF && !strings.Contains(err.Error(), "closed") && !strings.Contains(err.Error(), "reset by peer") { + s.logger.Printf("[ERR] yamux: Failed to read header: %v", err) + } + return err + } + + // Verify the version + if hdr.Version() != protoVersion { + s.logger.Printf("[ERR] yamux: Invalid protocol version: %d", hdr.Version()) + return ErrInvalidVersion + } + + mt := hdr.MsgType() + if mt < typeData || mt > typeGoAway { + return ErrInvalidMsgType + } + + if err := handlers[mt](s, hdr); err != nil { + return err + } + } +} + +// handleStreamMessage handles either a data or window update frame +func (s *Session) handleStreamMessage(hdr header) error { + // Check for a new stream creation + id := hdr.StreamID() + flags := hdr.Flags() + if flags&flagSYN == flagSYN { + if err := s.incomingStream(id); err != nil { + return err + } + } + + // Get the stream + s.streamLock.Lock() + stream := s.streams[id] + s.streamLock.Unlock() + + // If we do not have a stream, likely we sent a RST + if stream == nil { + // Drain any data on the wire + if hdr.MsgType() == typeData && hdr.Length() > 0 { + s.logger.Printf("[WARN] yamux: Discarding data for stream: %d", id) + if _, err := io.CopyN(ioutil.Discard, s.reader, int64(hdr.Length())); err != nil { + s.logger.Printf("[ERR] yamux: Failed to discard data: %v", err) + return nil + } + } else { + s.logger.Printf("[WARN] yamux: frame for missing stream: %v", hdr) + } + return nil + } + + // Check if this is a window update + if hdr.MsgType() == typeWindowUpdate { + if err := stream.incrSendWindow(hdr, flags); err != nil { + if sendErr := s.sendMsg(s.goAway(goAwayProtoErr), nil, nil); sendErr != nil { + s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr) + } + return err + } + return nil + } + + // Read the new data + if err := stream.readData(hdr, flags, s.reader); err != nil { + if sendErr := s.sendMsg(s.goAway(goAwayProtoErr), nil, nil); sendErr != nil { + s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr) + } + return err + } + return nil +} + +// handlePing is invokde for a typePing frame +func (s *Session) handlePing(hdr header) error { + flags := hdr.Flags() + pingID := hdr.Length() + + // Check if this is a query, respond back in a separate context so we + // don't interfere with the receiving thread blocking for the write. + if flags&flagSYN == flagSYN { + go func() { + hdr := encode(typePing, flagACK, 0, pingID) + if err := s.sendMsg(hdr, nil, nil); err != nil { + s.logger.Printf("[WARN] yamux: failed to send ping reply: %v", err) + } + }() + return nil + } + + // Handle a response + s.pingLock.Lock() + ch := s.pings[pingID] + if ch != nil { + delete(s.pings, pingID) + close(ch) + } + s.pingLock.Unlock() + return nil +} + +// handleGoAway is invokde for a typeGoAway frame +func (s *Session) handleGoAway(hdr header) error { + code := hdr.Length() + switch code { + case goAwayNormal: + atomic.SwapInt32(&s.remoteGoAway, 1) + case goAwayProtoErr: + s.logger.Printf("[ERR] yamux: received protocol error go away") + return fmt.Errorf("yamux protocol error") + case goAwayInternalErr: + s.logger.Printf("[ERR] yamux: received internal error go away") + return fmt.Errorf("remote yamux internal error") + default: + s.logger.Printf("[ERR] yamux: received unexpected go away") + return fmt.Errorf("unexpected go away received") + } + return nil +} + +// incomingStream is used to create a new incoming stream +func (s *Session) incomingStream(id uint32) error { + if s.client != (id%2 == 0) { + s.logger.Printf("[ERR] yamux: both endpoints are clients") + return fmt.Errorf("both yamux endpoints are clients") + } + // Reject immediately if we are doing a go away + if atomic.LoadInt32(&s.localGoAway) == 1 { + hdr := encode(typeWindowUpdate, flagRST, id, 0) + return s.sendMsg(hdr, nil, nil) + } + + // Allocate a new stream + stream := newStream(s, id, streamSYNReceived) + + s.streamLock.Lock() + defer s.streamLock.Unlock() + + // Check if stream already exists + if _, ok := s.streams[id]; ok { + s.logger.Printf("[ERR] yamux: duplicate stream declared") + if sendErr := s.sendMsg(s.goAway(goAwayProtoErr), nil, nil); sendErr != nil { + s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr) + } + return ErrDuplicateStream + } + + // Register the stream + s.streams[id] = stream + + // Check if we've exceeded the backlog + select { + case s.acceptCh <- stream: + return nil + default: + // Backlog exceeded! RST the stream + s.logger.Printf("[WARN] yamux: backlog exceeded, forcing connection reset") + delete(s.streams, id) + hdr := encode(typeWindowUpdate, flagRST, id, 0) + return s.sendMsg(hdr, nil, nil) + } +} + +// closeStream is used to close a stream once both sides have +// issued a close. If there was an in-flight SYN and the stream +// was not yet established, then this will give the credit back. +func (s *Session) closeStream(id uint32) { + s.streamLock.Lock() + if _, ok := s.inflight[id]; ok { + select { + case <-s.synCh: + default: + s.logger.Printf("[ERR] yamux: SYN tracking out of sync") + } + } + delete(s.streams, id) + s.streamLock.Unlock() +} + +// establishStream is used to mark a stream that was in the +// SYN Sent state as established. +func (s *Session) establishStream(id uint32) { + s.streamLock.Lock() + if _, ok := s.inflight[id]; ok { + delete(s.inflight, id) + } else { + s.logger.Printf("[ERR] yamux: established stream without inflight SYN (no tracking entry)") + } + select { + case <-s.synCh: + default: + s.logger.Printf("[ERR] yamux: established stream without inflight SYN (didn't have semaphore)") + } + s.streamLock.Unlock() +} diff --git a/vendor/github.com/libp2p/go-yamux/spec.md b/vendor/github.com/libp2p/go-yamux/spec.md new file mode 100644 index 00000000..183d797b --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/spec.md @@ -0,0 +1,140 @@ +# Specification + +We use this document to detail the internal specification of Yamux. +This is used both as a guide for implementing Yamux, but also for +alternative interoperable libraries to be built. + +# Framing + +Yamux uses a streaming connection underneath, but imposes a message +framing so that it can be shared between many logical streams. Each +frame contains a header like: + +* Version (8 bits) +* Type (8 bits) +* Flags (16 bits) +* StreamID (32 bits) +* Length (32 bits) + +This means that each header has a 12 byte overhead. +All fields are encoded in network order (big endian). +Each field is described below: + +## Version Field + +The version field is used for future backward compatibility. At the +current time, the field is always set to 0, to indicate the initial +version. + +## Type Field + +The type field is used to switch the frame message type. The following +message types are supported: + +* 0x0 Data - Used to transmit data. May transmit zero length payloads + depending on the flags. + +* 0x1 Window Update - Used to updated the senders receive window size. + This is used to implement per-session flow control. + +* 0x2 Ping - Used to measure RTT. It can also be used to heart-beat + and do keep-alives over TCP. + +* 0x3 Go Away - Used to close a session. + +## Flag Field + +The flags field is used to provide additional information related +to the message type. The following flags are supported: + +* 0x1 SYN - Signals the start of a new stream. May be sent with a data or + window update message. Also sent with a ping to indicate outbound. + +* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data + or window update message. Also sent with a ping to indicate response. + +* 0x4 FIN - Performs a half-close of a stream. May be sent with a data + message or window update. + +* 0x8 RST - Reset a stream immediately. May be sent with a data or + window update message. + +## StreamID Field + +The StreamID field is used to identify the logical stream the frame +is addressing. The client side should use odd ID's, and the server even. +This prevents any collisions. Additionally, the 0 ID is reserved to represent +the session. + +Both Ping and Go Away messages should always use the 0 StreamID. + +## Length Field + +The meaning of the length field depends on the message type: + +* Data - provides the length of bytes following the header +* Window update - provides a delta update to the window size +* Ping - Contains an opaque value, echoed back +* Go Away - Contains an error code + +# Message Flow + +There is no explicit connection setup, as Yamux relies on an underlying +transport to be provided. However, there is a distinction between client +and server side of the connection. + +## Opening a stream + +To open a stream, an initial data or window update frame is sent +with a new StreamID. The SYN flag should be set to signal a new stream. + +The receiver must then reply with either a data or window update frame +with the StreamID along with the ACK flag to accept the stream or with +the RST flag to reject the stream. + +Because we are relying on the reliable stream underneath, a connection +can begin sending data once the SYN flag is sent. The corresponding +ACK does not need to be received. This is particularly well suited +for an RPC system where a client wants to open a stream and immediately +fire a request without waiting for the RTT of the ACK. + +This does introduce the possibility of a connection being rejected +after data has been sent already. This is a slight semantic difference +from TCP, where the conection cannot be refused after it is opened. +Clients should be prepared to handle this by checking for an error +that indicates a RST was received. + +## Closing a stream + +To close a stream, either side sends a data or window update frame +along with the FIN flag. This does a half-close indicating the sender +will send no further data. + +Once both sides have closed the connection, the stream is closed. + +Alternatively, if an error occurs, the RST flag can be used to +hard close a stream immediately. + +## Flow Control + +When Yamux is initially starts each stream with a 256KB window size. +There is no window size for the session. + +To prevent the streams from stalling, window update frames should be +sent regularly. Yamux can be configured to provide a larger limit for +windows sizes. Both sides assume the initial 256KB window, but can +immediately send a window update as part of the SYN/ACK indicating a +larger window. + +Both sides should track the number of bytes sent in Data frames +only, as only they are tracked as part of the window size. + +## Session termination + +When a session is being terminated, the Go Away message should +be sent. The Length should be set to one of the following to +provide an error code: + +* 0x0 Normal termination +* 0x1 Protocol error +* 0x2 Internal error diff --git a/vendor/github.com/libp2p/go-yamux/stream.go b/vendor/github.com/libp2p/go-yamux/stream.go new file mode 100644 index 00000000..74ffe205 --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/stream.go @@ -0,0 +1,473 @@ +package yamux + +import ( + "io" + "sync" + "sync/atomic" + "time" + + "github.com/libp2p/go-buffer-pool" +) + +type streamState int + +const ( + streamInit streamState = iota + streamSYNSent + streamSYNReceived + streamEstablished + streamLocalClose + streamRemoteClose + streamClosed + streamReset +) + +// Stream is used to represent a logical stream +// within a session. +type Stream struct { + recvWindow uint32 + sendWindow uint32 + + id uint32 + session *Session + + state streamState + stateLock sync.Mutex + + recvLock sync.Mutex + recvBuf pool.Buffer + + sendLock sync.Mutex + + recvNotifyCh chan struct{} + sendNotifyCh chan struct{} + + readDeadline, writeDeadline pipeDeadline +} + +// newStream is used to construct a new stream within +// a given session for an ID +func newStream(session *Session, id uint32, state streamState) *Stream { + s := &Stream{ + id: id, + session: session, + state: state, + recvWindow: initialStreamWindow, + sendWindow: initialStreamWindow, + readDeadline: makePipeDeadline(), + writeDeadline: makePipeDeadline(), + recvNotifyCh: make(chan struct{}, 1), + sendNotifyCh: make(chan struct{}, 1), + } + return s +} + +// Session returns the associated stream session +func (s *Stream) Session() *Session { + return s.session +} + +// StreamID returns the ID of this stream +func (s *Stream) StreamID() uint32 { + return s.id +} + +// Read is used to read from the stream +func (s *Stream) Read(b []byte) (n int, err error) { + defer asyncNotify(s.recvNotifyCh) +START: + s.stateLock.Lock() + switch s.state { + case streamRemoteClose: + fallthrough + case streamClosed: + s.recvLock.Lock() + if s.recvBuf.Len() == 0 { + s.recvLock.Unlock() + s.stateLock.Unlock() + return 0, io.EOF + } + s.recvLock.Unlock() + case streamReset: + s.stateLock.Unlock() + return 0, ErrConnectionReset + } + s.stateLock.Unlock() + + // If there is no data available, block + s.recvLock.Lock() + if s.recvBuf.Len() == 0 { + s.recvLock.Unlock() + goto WAIT + } + + // Read any bytes + n, _ = s.recvBuf.Read(b) + s.recvLock.Unlock() + + // Send a window update potentially + err = s.sendWindowUpdate() + return n, err + +WAIT: + select { + case <-s.recvNotifyCh: + goto START + case <-s.readDeadline.wait(): + return 0, ErrTimeout + } +} + +// Write is used to write to the stream +func (s *Stream) Write(b []byte) (n int, err error) { + s.sendLock.Lock() + defer s.sendLock.Unlock() + total := 0 + + for total < len(b) { + n, err := s.write(b[total:]) + total += n + if err != nil { + return total, err + } + } + return total, nil +} + +// write is used to write to the stream, may return on +// a short write. +func (s *Stream) write(b []byte) (n int, err error) { + var flags uint16 + var max uint32 + var hdr header + +START: + s.stateLock.Lock() + switch s.state { + case streamLocalClose: + fallthrough + case streamClosed: + s.stateLock.Unlock() + return 0, ErrStreamClosed + case streamReset: + s.stateLock.Unlock() + return 0, ErrConnectionReset + } + s.stateLock.Unlock() + + // If there is no data available, block + window := atomic.LoadUint32(&s.sendWindow) + if window == 0 { + goto WAIT + } + + // Determine the flags if any + flags = s.sendFlags() + + // Send up to min(message, window + max = min(window, s.session.config.MaxMessageSize-headerSize, uint32(len(b))) + + // Send the header + hdr = encode(typeData, flags, s.id, max) + if err = s.session.sendMsg(hdr, b[:max], s.writeDeadline.wait()); err != nil { + return 0, err + } + + // Reduce our send window + atomic.AddUint32(&s.sendWindow, ^uint32(max-1)) + + // Unlock + return int(max), err + +WAIT: + select { + case <-s.sendNotifyCh: + goto START + case <-s.writeDeadline.wait(): + return 0, ErrTimeout + } +} + +// sendFlags determines any flags that are appropriate +// based on the current stream state +func (s *Stream) sendFlags() uint16 { + s.stateLock.Lock() + defer s.stateLock.Unlock() + var flags uint16 + switch s.state { + case streamInit: + flags |= flagSYN + s.state = streamSYNSent + case streamSYNReceived: + flags |= flagACK + s.state = streamEstablished + } + return flags +} + +// sendWindowUpdate potentially sends a window update enabling +// further writes to take place. Must be invoked with the lock. +func (s *Stream) sendWindowUpdate() error { + // Determine the delta update + max := s.session.config.MaxStreamWindowSize + s.recvLock.Lock() + delta := (max - uint32(s.recvBuf.Len())) - s.recvWindow + + // Determine the flags if any + flags := s.sendFlags() + + // Check if we can omit the update + if delta < (max/2) && flags == 0 { + s.recvLock.Unlock() + return nil + } + + // Update our window + s.recvWindow += delta + s.recvLock.Unlock() + + // Send the header + hdr := encode(typeWindowUpdate, flags, s.id, delta) + if err := s.session.sendMsg(hdr, nil, nil); err != nil { + return err + } + return nil +} + +// sendClose is used to send a FIN +func (s *Stream) sendClose() error { + flags := s.sendFlags() + flags |= flagFIN + hdr := encode(typeWindowUpdate, flags, s.id, 0) + return s.session.sendMsg(hdr, nil, nil) +} + +// sendReset is used to send a RST +func (s *Stream) sendReset() error { + hdr := encode(typeWindowUpdate, flagRST, s.id, 0) + return s.session.sendMsg(hdr, nil, nil) +} + +// Reset resets the stream (forcibly closes the stream) +func (s *Stream) Reset() error { + s.stateLock.Lock() + switch s.state { + case streamInit: + // No need to send anything. + s.state = streamReset + s.stateLock.Unlock() + return nil + case streamClosed, streamReset: + s.stateLock.Unlock() + return nil + case streamSYNSent, streamSYNReceived, streamEstablished: + case streamLocalClose, streamRemoteClose: + default: + panic("unhandled state") + } + s.state = streamReset + s.stateLock.Unlock() + + err := s.sendReset() + s.notifyWaiting() + s.cleanup() + + return err +} + +// Close is used to close the stream +func (s *Stream) Close() error { + closeStream := false + s.stateLock.Lock() + switch s.state { + case streamInit, streamSYNSent, streamSYNReceived, streamEstablished: + s.state = streamLocalClose + goto SEND_CLOSE + + case streamLocalClose: + case streamRemoteClose: + s.state = streamClosed + closeStream = true + goto SEND_CLOSE + + case streamClosed: + case streamReset: + default: + panic("unhandled state") + } + s.stateLock.Unlock() + return nil +SEND_CLOSE: + s.stateLock.Unlock() + err := s.sendClose() + s.notifyWaiting() + if closeStream { + s.cleanup() + } + return err +} + +// forceClose is used for when the session is exiting +func (s *Stream) forceClose() { + s.stateLock.Lock() + switch s.state { + case streamClosed: + // Already successfully closed. It just hasn't been removed from + // the list of streams yet. + default: + s.state = streamReset + } + s.stateLock.Unlock() + s.notifyWaiting() + + s.readDeadline.set(time.Time{}) + s.readDeadline.set(time.Time{}) +} + +// called when fully closed to release any system resources. +func (s *Stream) cleanup() { + s.session.closeStream(s.id) + s.readDeadline.set(time.Time{}) + s.readDeadline.set(time.Time{}) +} + +// processFlags is used to update the state of the stream +// based on set flags, if any. Lock must be held +func (s *Stream) processFlags(flags uint16) error { + // Close the stream without holding the state lock + closeStream := false + defer func() { + if closeStream { + s.cleanup() + } + }() + + s.stateLock.Lock() + defer s.stateLock.Unlock() + if flags&flagACK == flagACK { + if s.state == streamSYNSent { + s.state = streamEstablished + } + s.session.establishStream(s.id) + } + if flags&flagFIN == flagFIN { + switch s.state { + case streamSYNSent: + fallthrough + case streamSYNReceived: + fallthrough + case streamEstablished: + s.state = streamRemoteClose + s.notifyWaiting() + case streamLocalClose: + s.state = streamClosed + closeStream = true + s.notifyWaiting() + default: + s.session.logger.Printf("[ERR] yamux: unexpected FIN flag in state %d", s.state) + return ErrUnexpectedFlag + } + } + if flags&flagRST == flagRST { + s.state = streamReset + closeStream = true + s.notifyWaiting() + } + return nil +} + +// notifyWaiting notifies all the waiting channels +func (s *Stream) notifyWaiting() { + asyncNotify(s.recvNotifyCh) + asyncNotify(s.sendNotifyCh) +} + +// incrSendWindow updates the size of our send window +func (s *Stream) incrSendWindow(hdr header, flags uint16) error { + if err := s.processFlags(flags); err != nil { + return err + } + + // Increase window, unblock a sender + atomic.AddUint32(&s.sendWindow, hdr.Length()) + asyncNotify(s.sendNotifyCh) + return nil +} + +// readData is used to handle a data frame +func (s *Stream) readData(hdr header, flags uint16, conn io.Reader) error { + if err := s.processFlags(flags); err != nil { + return err + } + + // Check that our recv window is not exceeded + length := hdr.Length() + if length == 0 { + return nil + } + + // Wrap in a limited reader + conn = &io.LimitedReader{R: conn, N: int64(length)} + + // Copy into buffer + s.recvLock.Lock() + + if length > s.recvWindow { + s.session.logger.Printf("[ERR] yamux: receive window exceeded (stream: %d, remain: %d, recv: %d)", s.id, s.recvWindow, length) + return ErrRecvWindowExceeded + } + + s.recvBuf.Grow(int(length)) + if _, err := io.Copy(&s.recvBuf, conn); err != nil { + s.session.logger.Printf("[ERR] yamux: Failed to read stream data: %v", err) + s.recvLock.Unlock() + return err + } + + // Decrement the receive window + s.recvWindow -= length + s.recvLock.Unlock() + + // Unblock any readers + asyncNotify(s.recvNotifyCh) + return nil +} + +// SetDeadline sets the read and write deadlines +func (s *Stream) SetDeadline(t time.Time) error { + if err := s.SetReadDeadline(t); err != nil { + return err + } + if err := s.SetWriteDeadline(t); err != nil { + return err + } + return nil +} + +// SetReadDeadline sets the deadline for future Read calls. +func (s *Stream) SetReadDeadline(t time.Time) error { + s.stateLock.Lock() + defer s.stateLock.Unlock() + switch s.state { + case streamClosed, streamRemoteClose, streamReset: + return nil + } + s.readDeadline.set(t) + return nil +} + +// SetWriteDeadline sets the deadline for future Write calls +func (s *Stream) SetWriteDeadline(t time.Time) error { + s.stateLock.Lock() + defer s.stateLock.Unlock() + switch s.state { + case streamClosed, streamLocalClose, streamReset: + return nil + } + s.writeDeadline.set(t) + return nil +} + +// Shrink is a no-op. The internal buffer automatically shrinks itself. +func (s *Stream) Shrink() { +} diff --git a/vendor/github.com/libp2p/go-yamux/util.go b/vendor/github.com/libp2p/go-yamux/util.go new file mode 100644 index 00000000..b7e427fd --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/util.go @@ -0,0 +1,31 @@ +package yamux + +// asyncSendErr is used to try an async send of an error +func asyncSendErr(ch chan error, err error) { + if ch == nil { + return + } + select { + case ch <- err: + default: + } +} + +// asyncNotify is used to signal a waiting goroutine +func asyncNotify(ch chan struct{}) { + select { + case ch <- struct{}{}: + default: + } +} + +// min computes the minimum of a set of values +func min(values ...uint32) uint32 { + m := values[0] + for _, v := range values[1:] { + if v < m { + m = v + } + } + return m +} diff --git a/vendor/github.com/lucas-clemente/quic-go/.editorconfig b/vendor/github.com/lucas-clemente/quic-go/.editorconfig new file mode 100644 index 00000000..538ba2b2 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*] +indent_style = tab +indent_size = 2 diff --git a/vendor/github.com/lucas-clemente/quic-go/.gitignore b/vendor/github.com/lucas-clemente/quic-go/.gitignore new file mode 100644 index 00000000..040b55ac --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/.gitignore @@ -0,0 +1,3 @@ +debug +debug.test +main diff --git a/vendor/github.com/lucas-clemente/quic-go/.golangci.yml b/vendor/github.com/lucas-clemente/quic-go/.golangci.yml new file mode 100644 index 00000000..eb9de2f3 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/.golangci.yml @@ -0,0 +1,25 @@ +run: + skip-files: + - h2quic/response_writer_closenotifier.go + - internal/handshake/unsafe_test.go + +linters-settings: + misspell: + ignore-words: + - ect + +linters: + disable-all: true + enable: + - deadcode + - goconst + - goimports + - gosimple + - ineffassign + - misspell + - staticcheck + - structcheck + - unconvert + - unused + - varcheck + - vet diff --git a/vendor/github.com/lucas-clemente/quic-go/.travis.yml b/vendor/github.com/lucas-clemente/quic-go/.travis.yml new file mode 100644 index 00000000..a57287e6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/.travis.yml @@ -0,0 +1,39 @@ +dist: trusty +group: travis_latest + +language: go + +go: + - "1.12.x" + +# first part of the GOARCH workaround +# setting the GOARCH directly doesn't work, since the value will be overwritten later +# so set it to a temporary environment variable first +env: + global: + - TIMESCALE_FACTOR=20 + - GO111MODULE=on + matrix: + - TRAVIS_GOARCH=amd64 TESTMODE=lint + - TRAVIS_GOARCH=amd64 TESTMODE=unit + - TRAVIS_GOARCH=amd64 TESTMODE=integration + - TRAVIS_GOARCH=386 TESTMODE=unit + - TRAVIS_GOARCH=386 TESTMODE=integration + + +# second part of the GOARCH workaround +# now actually set the GOARCH env variable to the value of the temporary variable set earlier +before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/onsi/ginkgo/ginkgo + - go get github.com/onsi/gomega + - export GOARCH=$TRAVIS_GOARCH + - go env # for debugging + - "export DISPLAY=:99.0" + - "Xvfb $DISPLAY &> /dev/null &" + +script: + - .travis/script.sh + +after_success: + - .travis/after_success.sh diff --git a/vendor/github.com/lucas-clemente/quic-go/Changelog.md b/vendor/github.com/lucas-clemente/quic-go/Changelog.md new file mode 100644 index 00000000..47b115dc --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/Changelog.md @@ -0,0 +1,52 @@ +# Changelog + +## v0.11.0 (2019-04-05) + +- Drop support for gQUIC. For qQUIC support, please switch to the *gquic* branch. +- Implement QUIC WG draft-19. +- Use [qtls](https://github.com/marten-seemann/qtls) for TLS 1.3. +- Return a `tls.ConnectionState` from `quic.Session.ConnectionState()`. +- Remove the error return values from `quic.Stream.CancelRead()` and `quic.Stream.CancelWrite()` + +## v0.10.0 (2018-08-28) + +- Add support for QUIC 44, drop support for QUIC 42. + +## v0.9.0 (2018-08-15) + +- Add a `quic.Config` option for the length of the connection ID (for IETF QUIC). +- Split Session.Close into one method for regular closing and one for closing with an error. + +## v0.8.0 (2018-06-26) + +- Add support for unidirectional streams (for IETF QUIC). +- Add a `quic.Config` option for the maximum number of incoming streams. +- Add support for QUIC 42 and 43. +- Add dial functions that use a context. +- Multiplex clients on a net.PacketConn, when using Dial(conn). + +## v0.7.0 (2018-02-03) + +- The lower boundary for packets included in ACKs is now derived, and the value sent in STOP_WAITING frames is ignored. +- Remove `DialNonFWSecure` and `DialAddrNonFWSecure`. +- Expose the `ConnectionState` in the `Session` (experimental API). +- Implement packet pacing. + +## v0.6.0 (2017-12-12) + +- Add support for QUIC 39, drop support for QUIC 35 - 37 +- Added `quic.Config` options for maximal flow control windows +- Add a `quic.Config` option for QUIC versions +- Add a `quic.Config` option to request omission of the connection ID from a server +- Add a `quic.Config` option to configure the source address validation +- Add a `quic.Config` option to configure the handshake timeout +- Add a `quic.Config` option to configure the idle timeout +- Add a `quic.Config` option to configure keep-alive +- Rename the STK to Cookie +- Implement `net.Conn`-style deadlines for streams +- Remove the `tls.Config` from the `quic.Config`. The `tls.Config` must now be passed to the `Dial` and `Listen` functions as a separate parameter. See the [Godoc](https://godoc.org/github.com/lucas-clemente/quic-go) for details. +- Changed the log level environment variable to only accept strings ("DEBUG", "INFO", "ERROR"), see [the wiki](https://github.com/lucas-clemente/quic-go/wiki/Logging) for more details. +- Rename the `h2quic.QuicRoundTripper` to `h2quic.RoundTripper` +- Changed `h2quic.Server.Serve()` to accept a `net.PacketConn` +- Drop support for Go 1.7 and 1.8. +- Various bugfixes diff --git a/vendor/github.com/lucas-clemente/quic-go/LICENSE b/vendor/github.com/lucas-clemente/quic-go/LICENSE new file mode 100644 index 00000000..51378bef --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 the quic-go authors & Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/lucas-clemente/quic-go/README.md b/vendor/github.com/lucas-clemente/quic-go/README.md new file mode 100644 index 00000000..19f987a4 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/README.md @@ -0,0 +1,68 @@ +# A QUIC implementation in pure Go + + + +[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/lucas-clemente/quic-go) +[![Travis Build Status](https://img.shields.io/travis/lucas-clemente/quic-go/master.svg?style=flat-square&label=Travis+build)](https://travis-ci.org/lucas-clemente/quic-go) +[![CircleCI Build Status](https://img.shields.io/circleci/project/github/lucas-clemente/quic-go.svg?style=flat-square&label=CircleCI+build)](https://circleci.com/gh/lucas-clemente/quic-go) +[![Windows Build Status](https://img.shields.io/appveyor/ci/lucas-clemente/quic-go/master.svg?style=flat-square&label=windows+build)](https://ci.appveyor.com/project/lucas-clemente/quic-go/branch/master) +[![Code Coverage](https://img.shields.io/codecov/c/github/lucas-clemente/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/lucas-clemente/quic-go/) + +quic-go is an implementation of the [QUIC](https://en.wikipedia.org/wiki/QUIC) protocol in Go. It roughly implements the [IETF QUIC draft](https://github.com/quicwg/base-drafts), although we don't fully support any of the draft versions at the moment. + +## Version compatibility + +Since quic-go is under active development, there's no guarantee that two builds of different commits are interoperable. The QUIC version used in the *master* branch is just a placeholder, and should not be considered stable. + +If you want to use quic-go as a library in other projects, please consider using a [tagged release](https://github.com/lucas-clemente/quic-go/releases). These releases expose [experimental QUIC versions](https://github.com/quicwg/base-drafts/wiki/QUIC-Versions), which are guaranteed to be stable. + +## Google QUIC + +quic-go used to support both the QUIC versions supported by Google Chrome and QUIC as deployed on Google's servers, as well as IETF QUIC. Due to the divergence of the two protocols, we decided to not support both versions any more. + +The *master* branch **only** supports IETF QUIC. For Google QUIC support, please refer to the [gquic branch](https://github.com/lucas-clemente/quic-go/tree/gquic). + +## Guides + +We currently support Go 1.12+. + +Installing and updating dependencies: + + go get -t -u ./... + +Running tests: + + go test ./... + +### HTTP mapping + +We're currently not implementing the HTTP mapping as described in the [QUIC over HTTP draft](https://quicwg.org/base-drafts/draft-ietf-quic-http.html). The HTTP mapping here is a leftover from Google QUIC. + +### QUIC without HTTP/2 + +Take a look at [this echo example](example/echo/echo.go). + +## Usage + +### As a server + +See the [example server](example/main.go). Starting a QUIC server is very similar to the standard lib http in go: + +```go +http.Handle("/", http.FileServer(http.Dir(wwwDir))) +h2quic.ListenAndServeQUIC("localhost:4242", "/path/to/cert/chain.pem", "/path/to/privkey.pem", nil) +``` + +### As a client + +See the [example client](example/client/main.go). Use a `h2quic.RoundTripper` as a `Transport` in a `http.Client`. + +```go +http.Client{ + Transport: &h2quic.RoundTripper{}, +} +``` + +## Contributing + +We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with [help wanted](https://github.com/lucas-clemente/quic-go/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). If you have any questions, please feel free to reach out by opening an issue or leaving a comment. diff --git a/vendor/github.com/lucas-clemente/quic-go/appveyor.yml b/vendor/github.com/lucas-clemente/quic-go/appveyor.yml new file mode 100644 index 00000000..9ecd2d04 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/appveyor.yml @@ -0,0 +1,34 @@ +version: "{build}" + +os: Windows Server 2012 R2 + +environment: + GOPATH: c:\gopath + CGO_ENABLED: 0 + TIMESCALE_FACTOR: 20 + matrix: + - GOARCH: 386 + - GOARCH: amd64 + +clone_folder: c:\gopath\src\github.com\lucas-clemente\quic-go + +install: + - rmdir c:\go /s /q + - appveyor DownloadFile https://storage.googleapis.com/golang/go1.12.windows-amd64.zip + - 7z x go1.12.windows-amd64.zip -y -oC:\ > NUL + - set PATH=%PATH%;%GOPATH%\bin\windows_%GOARCH%;%GOPATH%\bin + - set GO111MODULE=on + - echo %PATH% + - echo %GOPATH% + - go get github.com/onsi/ginkgo/ginkgo + - go get github.com/onsi/gomega + - go version + - go env + +build_script: + - ginkgo -r -v -randomizeAllSpecs -randomizeSuites -trace -skipPackage benchmark,integrationtests + - ginkgo -randomizeAllSpecs -randomizeSuites -trace benchmark -- -samples=1 + +test: off + +deploy: off diff --git a/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go b/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go new file mode 100644 index 00000000..d6fb7673 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go @@ -0,0 +1,75 @@ +package quic + +import ( + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +type packetBuffer struct { + Slice []byte + + // refCount counts how many packets the Slice is used in. + // It doesn't support concurrent use. + // It is > 1 when used for coalesced packet. + refCount int +} + +// Split increases the refCount. +// It must be called when a packet buffer is used for more than one packet, +// e.g. when splitting coalesced packets. +func (b *packetBuffer) Split() { + b.refCount++ +} + +// Decrement decrements the reference counter. +// It doesn't put the buffer back into the pool. +func (b *packetBuffer) Decrement() { + b.refCount-- + if b.refCount < 0 { + panic("negative packetBuffer refCount") + } +} + +// MaybeRelease puts the packet buffer back into the pool, +// if the reference counter already reached 0. +func (b *packetBuffer) MaybeRelease() { + // only put the packetBuffer back if it's not used any more + if b.refCount == 0 { + b.putBack() + } +} + +// Release puts back the packet buffer into the pool. +// It should be called when processing is definitely finished. +func (b *packetBuffer) Release() { + b.Decrement() + if b.refCount != 0 { + panic("packetBuffer refCount not zero") + } + b.putBack() +} + +func (b *packetBuffer) putBack() { + if cap(b.Slice) != int(protocol.MaxReceivePacketSize) { + panic("putPacketBuffer called with packet of wrong size!") + } + bufferPool.Put(b) +} + +var bufferPool sync.Pool + +func getPacketBuffer() *packetBuffer { + buf := bufferPool.Get().(*packetBuffer) + buf.refCount = 1 + buf.Slice = buf.Slice[:protocol.MaxReceivePacketSize] + return buf +} + +func init() { + bufferPool.New = func() interface{} { + return &packetBuffer{ + Slice: make([]byte, 0, protocol.MaxReceivePacketSize), + } + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/client.go b/vendor/github.com/lucas-clemente/quic-go/client.go new file mode 100644 index 00000000..9ede391f --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/client.go @@ -0,0 +1,413 @@ +package quic + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "sync" + + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type client struct { + mutex sync.Mutex + + conn connection + // If the client is created with DialAddr, we create a packet conn. + // If it is started with Dial, we take a packet conn as a parameter. + createdPacketConn bool + + packetHandlers packetHandlerManager + + versionNegotiated utils.AtomicBool // has the server accepted our version + receivedVersionNegotiationPacket bool + negotiatedVersions []protocol.VersionNumber // the list of versions from the version negotiation packet + + tlsConf *tls.Config + config *Config + + srcConnID protocol.ConnectionID + destConnID protocol.ConnectionID + + initialPacketNumber protocol.PacketNumber + + initialVersion protocol.VersionNumber + version protocol.VersionNumber + + handshakeChan chan struct{} + + session quicSession + + logger utils.Logger +} + +var _ packetHandler = &client{} + +var ( + // make it possible to mock connection ID generation in the tests + generateConnectionID = protocol.GenerateConnectionID + generateConnectionIDForInitial = protocol.GenerateConnectionIDForInitial +) + +// DialAddr establishes a new QUIC connection to a server. +// It uses a new UDP connection and closes this connection when the QUIC session is closed. +// The hostname for SNI is taken from the given address. +func DialAddr( + addr string, + tlsConf *tls.Config, + config *Config, +) (Session, error) { + return DialAddrContext(context.Background(), addr, tlsConf, config) +} + +// DialAddrContext establishes a new QUIC connection to a server using the provided context. +// See DialAddr for details. +func DialAddrContext( + ctx context.Context, + addr string, + tlsConf *tls.Config, + config *Config, +) (Session, error) { + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, err + } + udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) + if err != nil { + return nil, err + } + return dialContext(ctx, udpConn, udpAddr, addr, tlsConf, config, true) +} + +// Dial establishes a new QUIC connection to a server using a net.PacketConn. +// The same PacketConn can be used for multiple calls to Dial and Listen, +// QUIC connection IDs are used for demultiplexing the different connections. +// The host parameter is used for SNI. +func Dial( + pconn net.PacketConn, + remoteAddr net.Addr, + host string, + tlsConf *tls.Config, + config *Config, +) (Session, error) { + return DialContext(context.Background(), pconn, remoteAddr, host, tlsConf, config) +} + +// DialContext establishes a new QUIC connection to a server using a net.PacketConn using the provided context. +// See Dial for details. +func DialContext( + ctx context.Context, + pconn net.PacketConn, + remoteAddr net.Addr, + host string, + tlsConf *tls.Config, + config *Config, +) (Session, error) { + return dialContext(ctx, pconn, remoteAddr, host, tlsConf, config, false) +} + +func dialContext( + ctx context.Context, + pconn net.PacketConn, + remoteAddr net.Addr, + host string, + tlsConf *tls.Config, + config *Config, + createdPacketConn bool, +) (Session, error) { + config = populateClientConfig(config, createdPacketConn) + packetHandlers, err := getMultiplexer().AddConn(pconn, config.ConnectionIDLength, config.StatelessResetKey) + if err != nil { + return nil, err + } + c, err := newClient(pconn, remoteAddr, config, tlsConf, host, createdPacketConn) + if err != nil { + return nil, err + } + c.packetHandlers = packetHandlers + if err := c.dial(ctx); err != nil { + return nil, err + } + return c.session, nil +} + +func newClient( + pconn net.PacketConn, + remoteAddr net.Addr, + config *Config, + tlsConf *tls.Config, + host string, + createdPacketConn bool, +) (*client, error) { + if tlsConf == nil { + tlsConf = &tls.Config{} + } + if tlsConf.ServerName == "" { + var err error + tlsConf.ServerName, _, err = net.SplitHostPort(host) + if err != nil { + return nil, err + } + } + + // check that all versions are actually supported + if config != nil { + for _, v := range config.Versions { + if !protocol.IsValidVersion(v) { + return nil, fmt.Errorf("%s is not a valid QUIC version", v) + } + } + } + + srcConnID, err := generateConnectionID(config.ConnectionIDLength) + if err != nil { + return nil, err + } + destConnID, err := generateConnectionIDForInitial() + if err != nil { + return nil, err + } + c := &client{ + srcConnID: srcConnID, + destConnID: destConnID, + conn: &conn{pconn: pconn, currentAddr: remoteAddr}, + createdPacketConn: createdPacketConn, + tlsConf: tlsConf, + config: config, + version: config.Versions[0], + handshakeChan: make(chan struct{}), + logger: utils.DefaultLogger.WithPrefix("client"), + } + return c, nil +} + +// populateClientConfig populates fields in the quic.Config with their default values, if none are set +// it may be called with nil +func populateClientConfig(config *Config, createdPacketConn bool) *Config { + if config == nil { + config = &Config{} + } + versions := config.Versions + if len(versions) == 0 { + versions = protocol.SupportedVersions + } + + handshakeTimeout := protocol.DefaultHandshakeTimeout + if config.HandshakeTimeout != 0 { + handshakeTimeout = config.HandshakeTimeout + } + idleTimeout := protocol.DefaultIdleTimeout + if config.IdleTimeout != 0 { + idleTimeout = config.IdleTimeout + } + + maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow + if maxReceiveStreamFlowControlWindow == 0 { + maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow + } + maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow + if maxReceiveConnectionFlowControlWindow == 0 { + maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow + } + maxIncomingStreams := config.MaxIncomingStreams + if maxIncomingStreams == 0 { + maxIncomingStreams = protocol.DefaultMaxIncomingStreams + } else if maxIncomingStreams < 0 { + maxIncomingStreams = 0 + } + maxIncomingUniStreams := config.MaxIncomingUniStreams + if maxIncomingUniStreams == 0 { + maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams + } else if maxIncomingUniStreams < 0 { + maxIncomingUniStreams = 0 + } + connIDLen := config.ConnectionIDLength + if connIDLen == 0 && !createdPacketConn { + connIDLen = protocol.DefaultConnectionIDLength + } + + return &Config{ + Versions: versions, + HandshakeTimeout: handshakeTimeout, + IdleTimeout: idleTimeout, + ConnectionIDLength: connIDLen, + MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, + MaxIncomingStreams: maxIncomingStreams, + MaxIncomingUniStreams: maxIncomingUniStreams, + KeepAlive: config.KeepAlive, + StatelessResetKey: config.StatelessResetKey, + } +} + +func (c *client) dial(ctx context.Context) error { + c.logger.Infof("Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s", c.tlsConf.ServerName, c.conn.LocalAddr(), c.conn.RemoteAddr(), c.srcConnID, c.destConnID, c.version) + + if err := c.createNewTLSSession(c.version); err != nil { + return err + } + err := c.establishSecureConnection(ctx) + if err == errCloseForRecreating { + return c.dial(ctx) + } + return err +} + +// establishSecureConnection runs the session, and tries to establish a secure connection +// It returns: +// - errCloseForRecreating when the server sends a version negotiation packet +// - any other error that might occur +// - when the connection is forward-secure +func (c *client) establishSecureConnection(ctx context.Context) error { + errorChan := make(chan error, 1) + + go func() { + err := c.session.run() // returns as soon as the session is closed + if err != errCloseForRecreating && c.createdPacketConn { + c.packetHandlers.Close() + } + errorChan <- err + }() + + select { + case <-ctx.Done(): + // The session will send a PeerGoingAway error to the server. + c.session.Close() + return ctx.Err() + case err := <-errorChan: + return err + case <-c.handshakeChan: + // handshake successfully completed + return nil + } +} + +func (c *client) handlePacket(p *receivedPacket) { + if wire.IsVersionNegotiationPacket(p.data) { + go c.handleVersionNegotiationPacket(p) + return + } + + // this is the first packet we are receiving + // since it is not a Version Negotiation Packet, this means the server supports the suggested version + if !c.versionNegotiated.Get() { + c.versionNegotiated.Set(true) + } + + c.session.handlePacket(p) +} + +func (c *client) handleVersionNegotiationPacket(p *receivedPacket) { + c.mutex.Lock() + defer c.mutex.Unlock() + + hdr, _, _, err := wire.ParsePacket(p.data, 0) + if err != nil { + c.logger.Debugf("Error parsing Version Negotiation packet: %s", err) + return + } + + // ignore delayed / duplicated version negotiation packets + if c.receivedVersionNegotiationPacket || c.versionNegotiated.Get() { + c.logger.Debugf("Received a delayed Version Negotiation packet.") + return + } + + for _, v := range hdr.SupportedVersions { + if v == c.version { + // The Version Negotiation packet contains the version that we offered. + // This might be a packet sent by an attacker (or by a terribly broken server implementation). + return + } + } + + c.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", hdr.SupportedVersions) + newVersion, ok := protocol.ChooseSupportedVersion(c.config.Versions, hdr.SupportedVersions) + if !ok { + c.session.destroy(fmt.Errorf("No compatible QUIC version found. We support %s, server offered %s", c.config.Versions, hdr.SupportedVersions)) + c.logger.Debugf("No compatible QUIC version found.") + return + } + c.receivedVersionNegotiationPacket = true + c.negotiatedVersions = hdr.SupportedVersions + + // switch to negotiated version + c.initialVersion = c.version + c.version = newVersion + + c.logger.Infof("Switching to QUIC version %s. New connection ID: %s", newVersion, c.destConnID) + c.initialPacketNumber = c.session.closeForRecreating() +} + +func (c *client) createNewTLSSession(version protocol.VersionNumber) error { + params := &handshake.TransportParameters{ + InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData, + InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData, + InitialMaxStreamDataUni: protocol.InitialMaxStreamData, + InitialMaxData: protocol.InitialMaxData, + IdleTimeout: c.config.IdleTimeout, + MaxBidiStreams: uint64(c.config.MaxIncomingStreams), + MaxUniStreams: uint64(c.config.MaxIncomingUniStreams), + AckDelayExponent: protocol.AckDelayExponent, + DisableMigration: true, + } + + c.mutex.Lock() + defer c.mutex.Unlock() + runner := &runner{ + packetHandlerManager: c.packetHandlers, + onHandshakeCompleteImpl: func(_ Session) { close(c.handshakeChan) }, + } + sess, err := newClientSession( + c.conn, + runner, + c.destConnID, + c.srcConnID, + c.config, + c.tlsConf, + c.initialPacketNumber, + params, + c.initialVersion, + c.logger, + c.version, + ) + if err != nil { + return err + } + c.session = sess + c.packetHandlers.Add(c.srcConnID, c) + return nil +} + +func (c *client) Close() error { + c.mutex.Lock() + defer c.mutex.Unlock() + if c.session == nil { + return nil + } + return c.session.Close() +} + +func (c *client) destroy(e error) { + c.mutex.Lock() + defer c.mutex.Unlock() + if c.session == nil { + return + } + c.session.destroy(e) +} + +func (c *client) GetVersion() protocol.VersionNumber { + c.mutex.Lock() + v := c.version + c.mutex.Unlock() + return v +} + +func (c *client) getPerspective() protocol.Perspective { + return protocol.PerspectiveClient +} diff --git a/vendor/github.com/lucas-clemente/quic-go/codecov.yml b/vendor/github.com/lucas-clemente/quic-go/codecov.yml new file mode 100644 index 00000000..f077c1ad --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/codecov.yml @@ -0,0 +1,18 @@ +coverage: + round: nearest + ignore: + - streams_map_incoming_bidi.go + - streams_map_incoming_uni.go + - streams_map_outgoing_bidi.go + - streams_map_outgoing_uni.go + - h2quic/gzipreader.go + - h2quic/response.go + - internal/ackhandler/packet_linkedlist.go + - internal/utils/byteinterval_linkedlist.go + - internal/utils/packetinterval_linkedlist.go + - internal/utils/linkedlist/linkedlist.go + status: + project: + default: + threshold: 0.5 + patch: false diff --git a/vendor/github.com/lucas-clemente/quic-go/conn.go b/vendor/github.com/lucas-clemente/quic-go/conn.go new file mode 100644 index 00000000..700c1471 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/conn.go @@ -0,0 +1,54 @@ +package quic + +import ( + "net" + "sync" +) + +type connection interface { + Write([]byte) error + Read([]byte) (int, net.Addr, error) + Close() error + LocalAddr() net.Addr + RemoteAddr() net.Addr + SetCurrentRemoteAddr(net.Addr) +} + +type conn struct { + mutex sync.RWMutex + + pconn net.PacketConn + currentAddr net.Addr +} + +var _ connection = &conn{} + +func (c *conn) Write(p []byte) error { + _, err := c.pconn.WriteTo(p, c.currentAddr) + return err +} + +func (c *conn) Read(p []byte) (int, net.Addr, error) { + return c.pconn.ReadFrom(p) +} + +func (c *conn) SetCurrentRemoteAddr(addr net.Addr) { + c.mutex.Lock() + c.currentAddr = addr + c.mutex.Unlock() +} + +func (c *conn) LocalAddr() net.Addr { + return c.pconn.LocalAddr() +} + +func (c *conn) RemoteAddr() net.Addr { + c.mutex.RLock() + addr := c.currentAddr + c.mutex.RUnlock() + return addr +} + +func (c *conn) Close() error { + return c.pconn.Close() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go b/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go new file mode 100644 index 00000000..095feb1d --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go @@ -0,0 +1,135 @@ +package quic + +import ( + "errors" + "fmt" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type cryptoStream interface { + // for receiving data + HandleCryptoFrame(*wire.CryptoFrame) error + GetCryptoData() []byte + Finish() error + // for sending data + io.Writer + HasData() bool + PopCryptoFrame(protocol.ByteCount) *wire.CryptoFrame +} + +type postHandshakeCryptoStream struct { + cryptoStream + + framer framer +} + +func newPostHandshakeCryptoStream(framer framer) cryptoStream { + return &postHandshakeCryptoStream{ + cryptoStream: newCryptoStream(), + framer: framer, + } +} + +// Write writes post-handshake messages. +// For simplicity, post-handshake crypto messages are treated as control frames. +// The framer functions as a stack (LIFO), so if there are multiple writes, +// they will be returned in the opposite order. +// This is acceptable, since post-handshake crypto messages are very rare. +func (s *postHandshakeCryptoStream) Write(p []byte) (int, error) { + n, err := s.cryptoStream.Write(p) + if err != nil { + return n, err + } + for s.cryptoStream.HasData() { + s.framer.QueueControlFrame(s.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize)) + } + return n, nil +} + +type cryptoStreamImpl struct { + queue *frameSorter + msgBuf []byte + + highestOffset protocol.ByteCount + finished bool + + writeOffset protocol.ByteCount + writeBuf []byte +} + +func newCryptoStream() cryptoStream { + return &cryptoStreamImpl{queue: newFrameSorter()} +} + +func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error { + highestOffset := f.Offset + protocol.ByteCount(len(f.Data)) + if maxOffset := highestOffset; maxOffset > protocol.MaxCryptoStreamOffset { + return fmt.Errorf("received invalid offset %d on crypto stream, maximum allowed %d", maxOffset, protocol.MaxCryptoStreamOffset) + } + if s.finished { + if highestOffset > s.highestOffset { + // reject crypto data received after this stream was already finished + return errors.New("received crypto data after change of encryption level") + } + // ignore data with a smaller offset than the highest received + // could e.g. be a retransmission + return nil + } + s.highestOffset = utils.MaxByteCount(s.highestOffset, highestOffset) + if err := s.queue.Push(f.Data, f.Offset); err != nil { + return err + } + for { + _, data := s.queue.Pop() + if data == nil { + return nil + } + s.msgBuf = append(s.msgBuf, data...) + } +} + +// GetCryptoData retrieves data that was received in CRYPTO frames +func (s *cryptoStreamImpl) GetCryptoData() []byte { + if len(s.msgBuf) < 4 { + return nil + } + msgLen := 4 + int(s.msgBuf[1])<<16 + int(s.msgBuf[2])<<8 + int(s.msgBuf[3]) + if len(s.msgBuf) < msgLen { + return nil + } + msg := make([]byte, msgLen) + copy(msg, s.msgBuf[:msgLen]) + s.msgBuf = s.msgBuf[msgLen:] + return msg +} + +func (s *cryptoStreamImpl) Finish() error { + if s.queue.HasMoreData() { + return errors.New("encryption level changed, but crypto stream has more data to read") + } + s.finished = true + return nil +} + +// Writes writes data that should be sent out in CRYPTO frames +func (s *cryptoStreamImpl) Write(p []byte) (int, error) { + s.writeBuf = append(s.writeBuf, p...) + return len(p), nil +} + +func (s *cryptoStreamImpl) HasData() bool { + return len(s.writeBuf) > 0 +} + +func (s *cryptoStreamImpl) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { + f := &wire.CryptoFrame{Offset: s.writeOffset} + n := utils.MinByteCount(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) + f.Data = s.writeBuf[:n] + s.writeBuf = s.writeBuf[n:] + s.writeOffset += n + return f +} diff --git a/vendor/github.com/lucas-clemente/quic-go/crypto_stream_manager.go b/vendor/github.com/lucas-clemente/quic-go/crypto_stream_manager.go new file mode 100644 index 00000000..489b306a --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/crypto_stream_manager.go @@ -0,0 +1,60 @@ +package quic + +import ( + "fmt" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type cryptoDataHandler interface { + HandleMessage([]byte, protocol.EncryptionLevel) bool +} + +type cryptoStreamManager struct { + cryptoHandler cryptoDataHandler + + initialStream cryptoStream + handshakeStream cryptoStream + oneRTTStream cryptoStream +} + +func newCryptoStreamManager( + cryptoHandler cryptoDataHandler, + initialStream cryptoStream, + handshakeStream cryptoStream, + oneRTTStream cryptoStream, +) *cryptoStreamManager { + return &cryptoStreamManager{ + cryptoHandler: cryptoHandler, + initialStream: initialStream, + handshakeStream: handshakeStream, + oneRTTStream: oneRTTStream, + } +} + +func (m *cryptoStreamManager) HandleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) (bool /* encryption level changed */, error) { + var str cryptoStream + switch encLevel { + case protocol.EncryptionInitial: + str = m.initialStream + case protocol.EncryptionHandshake: + str = m.handshakeStream + case protocol.Encryption1RTT: + str = m.oneRTTStream + default: + return false, fmt.Errorf("received CRYPTO frame with unexpected encryption level: %s", encLevel) + } + if err := str.HandleCryptoFrame(frame); err != nil { + return false, err + } + for { + data := str.GetCryptoData() + if data == nil { + return false, nil + } + if encLevelFinished := m.cryptoHandler.HandleMessage(data, encLevel); encLevelFinished { + return true, str.Finish() + } + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go b/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go new file mode 100644 index 00000000..609c35dd --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go @@ -0,0 +1,159 @@ +package quic + +import ( + "errors" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +type frameSorter struct { + queue map[protocol.ByteCount][]byte + readPos protocol.ByteCount + gaps *utils.ByteIntervalList +} + +var errDuplicateStreamData = errors.New("Duplicate Stream Data") + +func newFrameSorter() *frameSorter { + s := frameSorter{ + gaps: utils.NewByteIntervalList(), + queue: make(map[protocol.ByteCount][]byte), + } + s.gaps.PushFront(utils.ByteInterval{Start: 0, End: protocol.MaxByteCount}) + return &s +} + +func (s *frameSorter) Push(data []byte, offset protocol.ByteCount) error { + err := s.push(data, offset) + if err == errDuplicateStreamData { + return nil + } + return err +} + +func (s *frameSorter) push(data []byte, offset protocol.ByteCount) error { + if len(data) == 0 { + return nil + } + + var wasCut bool + if oldData, ok := s.queue[offset]; ok { + if len(data) <= len(oldData) { + return errDuplicateStreamData + } + data = data[len(oldData):] + offset += protocol.ByteCount(len(oldData)) + wasCut = true + } + + start := offset + end := offset + protocol.ByteCount(len(data)) + + // skip all gaps that are before this stream frame + var gap *utils.ByteIntervalElement + for gap = s.gaps.Front(); gap != nil; gap = gap.Next() { + // the frame is a duplicate. Ignore it + if end <= gap.Value.Start { + return errDuplicateStreamData + } + if end > gap.Value.Start && start <= gap.Value.End { + break + } + } + + if gap == nil { + return errors.New("StreamFrameSorter BUG: no gap found") + } + + if start < gap.Value.Start { + add := gap.Value.Start - start + offset += add + start += add + data = data[add:] + wasCut = true + } + + // find the highest gaps whose Start lies before the end of the frame + endGap := gap + for end >= endGap.Value.End { + nextEndGap := endGap.Next() + if nextEndGap == nil { + return errors.New("StreamFrameSorter BUG: no end gap found") + } + if endGap != gap { + s.gaps.Remove(endGap) + } + if end <= nextEndGap.Value.Start { + break + } + // delete queued frames completely covered by the current frame + delete(s.queue, endGap.Value.End) + endGap = nextEndGap + } + + if end > endGap.Value.End { + cutLen := end - endGap.Value.End + len := protocol.ByteCount(len(data)) - cutLen + end -= cutLen + data = data[:len] + wasCut = true + } + + if start == gap.Value.Start { + if end >= gap.Value.End { + // the frame completely fills this gap + // delete the gap + s.gaps.Remove(gap) + } + if end < endGap.Value.End { + // the frame covers the beginning of the gap + // adjust the Start value to shrink the gap + endGap.Value.Start = end + } + } else if end == endGap.Value.End { + // the frame covers the end of the gap + // adjust the End value to shrink the gap + gap.Value.End = start + } else { + if gap == endGap { + // the frame lies within the current gap, splitting it into two + // insert a new gap and adjust the current one + intv := utils.ByteInterval{Start: end, End: gap.Value.End} + s.gaps.InsertAfter(intv, gap) + gap.Value.End = start + } else { + gap.Value.End = start + endGap.Value.Start = end + } + } + + if s.gaps.Len() > protocol.MaxStreamFrameSorterGaps { + return errors.New("Too many gaps in received data") + } + + if wasCut { + newData := make([]byte, len(data)) + copy(newData, data) + data = newData + } + + s.queue[offset] = data + return nil +} + +func (s *frameSorter) Pop() (protocol.ByteCount, []byte) { + data, ok := s.queue[s.readPos] + if !ok { + return s.readPos, nil + } + delete(s.queue, s.readPos) + offset := s.readPos + s.readPos += protocol.ByteCount(len(data)) + return offset, data +} + +// HasMoreData says if there is any more data queued at *any* offset. +func (s *frameSorter) HasMoreData() bool { + return len(s.queue) > 0 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/framer.go b/vendor/github.com/lucas-clemente/quic-go/framer.go new file mode 100644 index 00000000..fbfe9bb7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/framer.go @@ -0,0 +1,109 @@ +package quic + +import ( + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type framer interface { + QueueControlFrame(wire.Frame) + AppendControlFrames([]wire.Frame, protocol.ByteCount) ([]wire.Frame, protocol.ByteCount) + + AddActiveStream(protocol.StreamID) + AppendStreamFrames([]wire.Frame, protocol.ByteCount) []wire.Frame +} + +type framerI struct { + mutex sync.Mutex + + streamGetter streamGetter + version protocol.VersionNumber + + activeStreams map[protocol.StreamID]struct{} + streamQueue []protocol.StreamID + + controlFrameMutex sync.Mutex + controlFrames []wire.Frame +} + +var _ framer = &framerI{} + +func newFramer( + streamGetter streamGetter, + v protocol.VersionNumber, +) framer { + return &framerI{ + streamGetter: streamGetter, + activeStreams: make(map[protocol.StreamID]struct{}), + version: v, + } +} + +func (f *framerI) QueueControlFrame(frame wire.Frame) { + f.controlFrameMutex.Lock() + f.controlFrames = append(f.controlFrames, frame) + f.controlFrameMutex.Unlock() +} + +func (f *framerI) AppendControlFrames(frames []wire.Frame, maxLen protocol.ByteCount) ([]wire.Frame, protocol.ByteCount) { + var length protocol.ByteCount + f.controlFrameMutex.Lock() + for len(f.controlFrames) > 0 { + frame := f.controlFrames[len(f.controlFrames)-1] + frameLen := frame.Length(f.version) + if length+frameLen > maxLen { + break + } + frames = append(frames, frame) + length += frameLen + f.controlFrames = f.controlFrames[:len(f.controlFrames)-1] + } + f.controlFrameMutex.Unlock() + return frames, length +} + +func (f *framerI) AddActiveStream(id protocol.StreamID) { + f.mutex.Lock() + if _, ok := f.activeStreams[id]; !ok { + f.streamQueue = append(f.streamQueue, id) + f.activeStreams[id] = struct{}{} + } + f.mutex.Unlock() +} + +func (f *framerI) AppendStreamFrames(frames []wire.Frame, maxLen protocol.ByteCount) []wire.Frame { + var length protocol.ByteCount + f.mutex.Lock() + // pop STREAM frames, until less than MinStreamFrameSize bytes are left in the packet + numActiveStreams := len(f.streamQueue) + for i := 0; i < numActiveStreams; i++ { + if maxLen-length < protocol.MinStreamFrameSize { + break + } + id := f.streamQueue[0] + f.streamQueue = f.streamQueue[1:] + // This should never return an error. Better check it anyway. + // The stream will only be in the streamQueue, if it enqueued itself there. + str, err := f.streamGetter.GetOrOpenSendStream(id) + // The stream can be nil if it completed after it said it had data. + if str == nil || err != nil { + delete(f.activeStreams, id) + continue + } + frame, hasMoreData := str.popStreamFrame(maxLen - length) + if hasMoreData { // put the stream back in the queue (at the end) + f.streamQueue = append(f.streamQueue, id) + } else { // no more data to send. Stream is not active any more + delete(f.activeStreams, id) + } + if frame == nil { // can happen if the receiveStream was canceled after it said it had data + continue + } + frames = append(frames, frame) + length += frame.Length(f.version) + } + f.mutex.Unlock() + return frames +} diff --git a/vendor/github.com/lucas-clemente/quic-go/go.mod b/vendor/github.com/lucas-clemente/quic-go/go.mod new file mode 100644 index 00000000..63d9d89b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/go.mod @@ -0,0 +1,13 @@ +module github.com/lucas-clemente/quic-go + +go 1.12 + +require ( + github.com/cheekybits/genny v1.0.0 + github.com/golang/mock v1.2.0 + github.com/marten-seemann/qtls v0.2.3 + github.com/onsi/ginkgo v1.7.0 + github.com/onsi/gomega v1.4.3 + golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 + golang.org/x/net v0.0.0-20180906233101-161cd47e91fd +) diff --git a/vendor/github.com/lucas-clemente/quic-go/go.sum b/vendor/github.com/lucas-clemente/quic-go/go.sum new file mode 100644 index 00000000..c5efe853 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/go.sum @@ -0,0 +1,37 @@ +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= +github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/lucas-clemente/quic-go/interface.go b/vendor/github.com/lucas-clemente/quic-go/interface.go new file mode 100644 index 00000000..a83d09b8 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/interface.go @@ -0,0 +1,224 @@ +package quic + +import ( + "context" + "crypto/tls" + "io" + "net" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// The StreamID is the ID of a QUIC stream. +type StreamID = protocol.StreamID + +// A VersionNumber is a QUIC version number. +type VersionNumber = protocol.VersionNumber + +// A Cookie can be used to verify the ownership of the client address. +type Cookie struct { + RemoteAddr string + SentTime time.Time +} + +// An ErrorCode is an application-defined error code. +type ErrorCode = protocol.ApplicationErrorCode + +// Stream is the interface implemented by QUIC streams +type Stream interface { + // StreamID returns the stream ID. + StreamID() StreamID + // Read reads data from the stream. + // Read can be made to time out and return a net.Error with Timeout() == true + // after a fixed time limit; see SetDeadline and SetReadDeadline. + // If the stream was canceled by the peer, the error implements the StreamError + // interface, and Canceled() == true. + // If the session was closed due to a timeout, the error satisfies + // the net.Error interface, and Timeout() will be true. + io.Reader + // Write writes data to the stream. + // Write can be made to time out and return a net.Error with Timeout() == true + // after a fixed time limit; see SetDeadline and SetWriteDeadline. + // If the stream was canceled by the peer, the error implements the StreamError + // interface, and Canceled() == true. + // If the session was closed due to a timeout, the error satisfies + // the net.Error interface, and Timeout() will be true. + io.Writer + // Close closes the write-direction of the stream. + // Future calls to Write are not permitted after calling Close. + // It must not be called concurrently with Write. + // It must not be called after calling CancelWrite. + io.Closer + // CancelWrite aborts sending on this stream. + // Data already written, but not yet delivered to the peer is not guaranteed to be delivered reliably. + // Write will unblock immediately, and future calls to Write will fail. + // When called multiple times or after closing the stream it is a no-op. + CancelWrite(ErrorCode) + // CancelRead aborts receiving on this stream. + // It will ask the peer to stop transmitting stream data. + // Read will unblock immediately, and future Read calls will fail. + // When called multiple times or after reading the io.EOF it is a no-op. + CancelRead(ErrorCode) + // The context is canceled as soon as the write-side of the stream is closed. + // This happens when Close() or CancelWrite() is called, or when the peer + // cancels the read-side of their stream. + // Warning: This API should not be considered stable and might change soon. + Context() context.Context + // SetReadDeadline sets the deadline for future Read calls and + // any currently-blocked Read call. + // A zero value for t means Read will not time out. + SetReadDeadline(t time.Time) error + // SetWriteDeadline sets the deadline for future Write calls + // and any currently-blocked Write call. + // Even if write times out, it may return n > 0, indicating that + // some of the data was successfully written. + // A zero value for t means Write will not time out. + SetWriteDeadline(t time.Time) error + // SetDeadline sets the read and write deadlines associated + // with the connection. It is equivalent to calling both + // SetReadDeadline and SetWriteDeadline. + SetDeadline(t time.Time) error +} + +// A ReceiveStream is a unidirectional Receive Stream. +type ReceiveStream interface { + // see Stream.StreamID + StreamID() StreamID + // see Stream.Read + io.Reader + // see Stream.CancelRead + CancelRead(ErrorCode) + // see Stream.SetReadDealine + SetReadDeadline(t time.Time) error +} + +// A SendStream is a unidirectional Send Stream. +type SendStream interface { + // see Stream.StreamID + StreamID() StreamID + // see Stream.Write + io.Writer + // see Stream.Close + io.Closer + // see Stream.CancelWrite + CancelWrite(ErrorCode) + // see Stream.Context + Context() context.Context + // see Stream.SetWriteDeadline + SetWriteDeadline(t time.Time) error +} + +// StreamError is returned by Read and Write when the peer cancels the stream. +type StreamError interface { + error + Canceled() bool + ErrorCode() ErrorCode +} + +// A Session is a QUIC connection between two peers. +type Session interface { + // AcceptStream returns the next stream opened by the peer, blocking until one is available. + // If the session was closed due to a timeout, the error satisfies + // the net.Error interface, and Timeout() will be true. + AcceptStream() (Stream, error) + // AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available. + // If the session was closed due to a timeout, the error satisfies + // the net.Error interface, and Timeout() will be true. + AcceptUniStream() (ReceiveStream, error) + // OpenStream opens a new bidirectional QUIC stream. + // There is no signaling to the peer about new streams: + // The peer can only accept the stream after data has been sent on the stream. + // If the error is non-nil, it satisfies the net.Error interface. + // When reaching the peer's stream limit, err.Temporary() will be true. + // If the session was closed due to a timeout, Timeout() will be true. + OpenStream() (Stream, error) + // OpenStreamSync opens a new bidirectional QUIC stream. + // It blocks until a new stream can be opened. + // If the error is non-nil, it satisfies the net.Error interface. + // If the session was closed due to a timeout, Timeout() will be true. + OpenStreamSync() (Stream, error) + // OpenUniStream opens a new outgoing unidirectional QUIC stream. + // If the error is non-nil, it satisfies the net.Error interface. + // When reaching the peer's stream limit, Temporary() will be true. + // If the session was closed due to a timeout, Timeout() will be true. + OpenUniStream() (SendStream, error) + // OpenUniStreamSync opens a new outgoing unidirectional QUIC stream. + // It blocks until a new stream can be opened. + // If the error is non-nil, it satisfies the net.Error interface. + // If the session was closed due to a timeout, Timeout() will be true. + OpenUniStreamSync() (SendStream, error) + // LocalAddr returns the local address. + LocalAddr() net.Addr + // RemoteAddr returns the address of the peer. + RemoteAddr() net.Addr + // Close the connection. + io.Closer + // Close the connection with an error. + // The error must not be nil. + CloseWithError(ErrorCode, error) error + // The context is cancelled when the session is closed. + // Warning: This API should not be considered stable and might change soon. + Context() context.Context + // ConnectionState returns basic details about the QUIC connection. + // Warning: This API should not be considered stable and might change soon. + ConnectionState() tls.ConnectionState +} + +// Config contains all configuration data needed for a QUIC server or client. +type Config struct { + // The QUIC versions that can be negotiated. + // If not set, it uses all versions available. + // Warning: This API should not be considered stable and will change soon. + Versions []VersionNumber + // The length of the connection ID in bytes. + // It can be 0, or any value between 4 and 18. + // If not set, the interpretation depends on where the Config is used: + // If used for dialing an address, a 0 byte connection ID will be used. + // If used for a server, or dialing on a packet conn, a 4 byte connection ID will be used. + // When dialing on a packet conn, the ConnectionIDLength value must be the same for every Dial call. + ConnectionIDLength int + // HandshakeTimeout is the maximum duration that the cryptographic handshake may take. + // If the timeout is exceeded, the connection is closed. + // If this value is zero, the timeout is set to 10 seconds. + HandshakeTimeout time.Duration + // IdleTimeout is the maximum duration that may pass without any incoming network activity. + // This value only applies after the handshake has completed. + // If the timeout is exceeded, the connection is closed. + // If this value is zero, the timeout is set to 30 seconds. + IdleTimeout time.Duration + // AcceptCookie determines if a Cookie is accepted. + // It is called with cookie = nil if the client didn't send an Cookie. + // If not set, it verifies that the address matches, and that the Cookie was issued within the last 24 hours. + // This option is only valid for the server. + AcceptCookie func(clientAddr net.Addr, cookie *Cookie) bool + // MaxReceiveStreamFlowControlWindow is the maximum stream-level flow control window for receiving data. + // If this value is zero, it will default to 1 MB for the server and 6 MB for the client. + MaxReceiveStreamFlowControlWindow uint64 + // MaxReceiveConnectionFlowControlWindow is the connection-level flow control window for receiving data. + // If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client. + MaxReceiveConnectionFlowControlWindow uint64 + // MaxIncomingStreams is the maximum number of concurrent bidirectional streams that a peer is allowed to open. + // If not set, it will default to 100. + // If set to a negative value, it doesn't allow any bidirectional streams. + MaxIncomingStreams int + // MaxIncomingUniStreams is the maximum number of concurrent unidirectional streams that a peer is allowed to open. + // If not set, it will default to 100. + // If set to a negative value, it doesn't allow any unidirectional streams. + MaxIncomingUniStreams int + // The StatelessResetKey is used to generate stateless reset tokens. + // If no key is configured, sending of stateless resets is disabled. + StatelessResetKey []byte + // KeepAlive defines whether this peer will periodically send a packet to keep the connection alive. + KeepAlive bool +} + +// A Listener for incoming QUIC connections +type Listener interface { + // Close the server. All active sessions will be closed. + Close() error + // Addr returns the local network addr that the server is listening on. + Addr() net.Addr + // Accept returns new sessions. It should be called in a loop. + Accept() (Session, error) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go new file mode 100644 index 00000000..32235f81 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go @@ -0,0 +1,3 @@ +package ackhandler + +//go:generate genny -pkg ackhandler -in ../utils/linkedlist/linkedlist.go -out packet_linkedlist.go gen Item=Packet diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go new file mode 100644 index 00000000..362b9fbe --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go @@ -0,0 +1,50 @@ +package ackhandler + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// SentPacketHandler handles ACKs received for outgoing packets +type SentPacketHandler interface { + // SentPacket may modify the packet + SentPacket(packet *Packet) + SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) + ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, recvTime time.Time) error + SetHandshakeComplete() + ResetForRetry() error + + // The SendMode determines if and what kind of packets can be sent. + SendMode() SendMode + // TimeUntilSend is the time when the next packet should be sent. + // It is used for pacing packets. + TimeUntilSend() time.Time + // ShouldSendNumPackets returns the number of packets that should be sent immediately. + // It always returns a number greater or equal than 1. + // A number greater than 1 is returned when the pacing delay is smaller than the minimum pacing delay. + // Note that the number of packets is only calculated based on the pacing algorithm. + // Before sending any packet, SendingAllowed() must be called to learn if we can actually send it. + ShouldSendNumPackets() int + + // only to be called once the handshake is complete + GetLowestPacketNotConfirmedAcked() protocol.PacketNumber + DequeuePacketForRetransmission() *Packet + DequeueProbePacket() (*Packet, error) + + PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) + PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber + + GetAlarmTimeout() time.Time + OnAlarm() error +} + +// ReceivedPacketHandler handles ACKs needed to send for incoming packets +type ReceivedPacketHandler interface { + ReceivedPacket(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time, shouldInstigateAck bool) error + IgnoreBelow(protocol.PacketNumber) + + GetAlarmTimeout() time.Time + GetAckFrame(protocol.EncryptionLevel) *wire.AckFrame +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet.go new file mode 100644 index 00000000..9673a85c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet.go @@ -0,0 +1,29 @@ +package ackhandler + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// A Packet is a packet +type Packet struct { + PacketNumber protocol.PacketNumber + PacketType protocol.PacketType + Frames []wire.Frame + Length protocol.ByteCount + EncryptionLevel protocol.EncryptionLevel + SendTime time.Time + + largestAcked protocol.PacketNumber // if the packet contains an ACK, the LargestAcked value of that ACK + + // There are two reasons why a packet cannot be retransmitted: + // * it was already retransmitted + // * this packet is a retransmission, and we already received an ACK for the original packet + canBeRetransmitted bool + includedInBytesInFlight bool + retransmittedAs []protocol.PacketNumber + isRetransmission bool // we need a separate bool here because 0 is a valid packet number + retransmissionOf protocol.PacketNumber +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go new file mode 100644 index 00000000..bb74f4ef --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go @@ -0,0 +1,217 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package ackhandler + +// Linked list implementation from the Go standard library. + +// PacketElement is an element of a linked list. +type PacketElement struct { + // Next and previous pointers in the doubly-linked list of elements. + // To simplify the implementation, internally a list l is implemented + // as a ring, such that &l.root is both the next element of the last + // list element (l.Back()) and the previous element of the first list + // element (l.Front()). + next, prev *PacketElement + + // The list to which this element belongs. + list *PacketList + + // The value stored with this element. + Value Packet +} + +// Next returns the next list element or nil. +func (e *PacketElement) Next() *PacketElement { + if p := e.next; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// Prev returns the previous list element or nil. +func (e *PacketElement) Prev() *PacketElement { + if p := e.prev; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// PacketList is a linked list of Packets. +type PacketList struct { + root PacketElement // sentinel list element, only &root, root.prev, and root.next are used + len int // current list length excluding (this) sentinel element +} + +// Init initializes or clears list l. +func (l *PacketList) Init() *PacketList { + l.root.next = &l.root + l.root.prev = &l.root + l.len = 0 + return l +} + +// NewPacketList returns an initialized list. +func NewPacketList() *PacketList { return new(PacketList).Init() } + +// Len returns the number of elements of list l. +// The complexity is O(1). +func (l *PacketList) Len() int { return l.len } + +// Front returns the first element of list l or nil if the list is empty. +func (l *PacketList) Front() *PacketElement { + if l.len == 0 { + return nil + } + return l.root.next +} + +// Back returns the last element of list l or nil if the list is empty. +func (l *PacketList) Back() *PacketElement { + if l.len == 0 { + return nil + } + return l.root.prev +} + +// lazyInit lazily initializes a zero List value. +func (l *PacketList) lazyInit() { + if l.root.next == nil { + l.Init() + } +} + +// insert inserts e after at, increments l.len, and returns e. +func (l *PacketList) insert(e, at *PacketElement) *PacketElement { + n := at.next + at.next = e + e.prev = at + e.next = n + n.prev = e + e.list = l + l.len++ + return e +} + +// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). +func (l *PacketList) insertValue(v Packet, at *PacketElement) *PacketElement { + return l.insert(&PacketElement{Value: v}, at) +} + +// remove removes e from its list, decrements l.len, and returns e. +func (l *PacketList) remove(e *PacketElement) *PacketElement { + e.prev.next = e.next + e.next.prev = e.prev + e.next = nil // avoid memory leaks + e.prev = nil // avoid memory leaks + e.list = nil + l.len-- + return e +} + +// Remove removes e from l if e is an element of list l. +// It returns the element value e.Value. +// The element must not be nil. +func (l *PacketList) Remove(e *PacketElement) Packet { + if e.list == l { + // if e.list == l, l must have been initialized when e was inserted + // in l or l == nil (e is a zero Element) and l.remove will crash + l.remove(e) + } + return e.Value +} + +// PushFront inserts a new element e with value v at the front of list l and returns e. +func (l *PacketList) PushFront(v Packet) *PacketElement { + l.lazyInit() + return l.insertValue(v, &l.root) +} + +// PushBack inserts a new element e with value v at the back of list l and returns e. +func (l *PacketList) PushBack(v Packet) *PacketElement { + l.lazyInit() + return l.insertValue(v, l.root.prev) +} + +// InsertBefore inserts a new element e with value v immediately before mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *PacketList) InsertBefore(v Packet, mark *PacketElement) *PacketElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark.prev) +} + +// InsertAfter inserts a new element e with value v immediately after mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *PacketList) InsertAfter(v Packet, mark *PacketElement) *PacketElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark) +} + +// MoveToFront moves element e to the front of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *PacketList) MoveToFront(e *PacketElement) { + if e.list != l || l.root.next == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), &l.root) +} + +// MoveToBack moves element e to the back of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *PacketList) MoveToBack(e *PacketElement) { + if e.list != l || l.root.prev == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), l.root.prev) +} + +// MoveBefore moves element e to its new position before mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *PacketList) MoveBefore(e, mark *PacketElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark.prev) +} + +// MoveAfter moves element e to its new position after mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *PacketList) MoveAfter(e, mark *PacketElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark) +} + +// PushBackList inserts a copy of an other list at the back of list l. +// The lists l and other may be the same. They must not be nil. +func (l *PacketList) PushBackList(other *PacketList) { + l.lazyInit() + for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { + l.insertValue(e.Value, l.root.prev) + } +} + +// PushFrontList inserts a copy of an other list at the front of list l. +// The lists l and other may be the same. They must not be nil. +func (l *PacketList) PushFrontList(other *PacketList) { + l.lazyInit() + for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { + l.insertValue(e.Value, &l.root) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go new file mode 100644 index 00000000..56fbf3d8 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go @@ -0,0 +1,78 @@ +package ackhandler + +import ( + "crypto/rand" + "math" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// The packetNumberGenerator generates the packet number for the next packet +// it randomly skips a packet number every averagePeriod packets (on average) +// it is guarantued to never skip two consecutive packet numbers +type packetNumberGenerator struct { + averagePeriod protocol.PacketNumber + + next protocol.PacketNumber + nextToSkip protocol.PacketNumber + + history []protocol.PacketNumber +} + +func newPacketNumberGenerator(initial, averagePeriod protocol.PacketNumber) *packetNumberGenerator { + g := &packetNumberGenerator{ + next: initial, + averagePeriod: averagePeriod, + } + g.generateNewSkip() + return g +} + +func (p *packetNumberGenerator) Peek() protocol.PacketNumber { + return p.next +} + +func (p *packetNumberGenerator) Pop() protocol.PacketNumber { + next := p.next + + // generate a new packet number for the next packet + p.next++ + + if p.next == p.nextToSkip { + if len(p.history)+1 > protocol.MaxTrackedSkippedPackets { + p.history = p.history[1:] + } + p.history = append(p.history, p.next) + p.next++ + p.generateNewSkip() + } + + return next +} + +func (p *packetNumberGenerator) generateNewSkip() { + num := p.getRandomNumber() + skip := protocol.PacketNumber(num) * (p.averagePeriod - 1) / (math.MaxUint16 / 2) + // make sure that there are never two consecutive packet numbers that are skipped + p.nextToSkip = p.next + 2 + skip +} + +// getRandomNumber() generates a cryptographically secure random number between 0 and MaxUint16 (= 65535) +// The expectation value is 65535/2 +func (p *packetNumberGenerator) getRandomNumber() uint16 { + b := make([]byte, 2) + rand.Read(b) // ignore the error here + + num := uint16(b[0])<<8 + uint16(b[1]) + return num +} + +func (p *packetNumberGenerator) Validate(ack *wire.AckFrame) bool { + for _, pn := range p.history { + if ack.AcksPacket(pn) { + return false + } + } + return true +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_handler.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_handler.go new file mode 100644 index 00000000..1df64ea8 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_handler.go @@ -0,0 +1,98 @@ +package ackhandler + +import ( + "fmt" + "time" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +const ( + // maximum delay that can be applied to an ACK for a retransmittable packet + ackSendDelay = 25 * time.Millisecond + // initial maximum number of retransmittable packets received before sending an ack. + initialRetransmittablePacketsBeforeAck = 2 + // number of retransmittable that an ACK is sent for + retransmittablePacketsBeforeAck = 10 + // 1/5 RTT delay when doing ack decimation + ackDecimationDelay = 1.0 / 4 + // 1/8 RTT delay when doing ack decimation + shortAckDecimationDelay = 1.0 / 8 + // Minimum number of packets received before ack decimation is enabled. + // This intends to avoid the beginning of slow start, when CWNDs may be + // rapidly increasing. + minReceivedBeforeAckDecimation = 100 + // Maximum number of packets to ack immediately after a missing packet for + // fast retransmission to kick in at the sender. This limit is created to + // reduce the number of acks sent that have no benefit for fast retransmission. + // Set to the number of nacks needed for fast retransmit plus one for protection + // against an ack loss + maxPacketsAfterNewMissing = 4 +) + +type receivedPacketHandler struct { + initialPackets *receivedPacketTracker + handshakePackets *receivedPacketTracker + oneRTTPackets *receivedPacketTracker +} + +var _ ReceivedPacketHandler = &receivedPacketHandler{} + +// NewReceivedPacketHandler creates a new receivedPacketHandler +func NewReceivedPacketHandler( + rttStats *congestion.RTTStats, + logger utils.Logger, + version protocol.VersionNumber, +) ReceivedPacketHandler { + return &receivedPacketHandler{ + initialPackets: newReceivedPacketTracker(rttStats, logger, version), + handshakePackets: newReceivedPacketTracker(rttStats, logger, version), + oneRTTPackets: newReceivedPacketTracker(rttStats, logger, version), + } +} + +func (h *receivedPacketHandler) ReceivedPacket( + pn protocol.PacketNumber, + encLevel protocol.EncryptionLevel, + rcvTime time.Time, + shouldInstigateAck bool, +) error { + switch encLevel { + case protocol.EncryptionInitial: + return h.initialPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) + case protocol.EncryptionHandshake: + return h.handshakePackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) + case protocol.Encryption1RTT: + return h.oneRTTPackets.ReceivedPacket(pn, rcvTime, shouldInstigateAck) + default: + return fmt.Errorf("received packet with unknown encryption level: %s", encLevel) + } +} + +// only to be used with 1-RTT packets +func (h *receivedPacketHandler) IgnoreBelow(pn protocol.PacketNumber) { + h.oneRTTPackets.IgnoreBelow(pn) +} + +func (h *receivedPacketHandler) GetAlarmTimeout() time.Time { + initialAlarm := h.initialPackets.GetAlarmTimeout() + handshakeAlarm := h.handshakePackets.GetAlarmTimeout() + oneRTTAlarm := h.oneRTTPackets.GetAlarmTimeout() + return utils.MinNonZeroTime(utils.MinNonZeroTime(initialAlarm, handshakeAlarm), oneRTTAlarm) +} + +func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel) *wire.AckFrame { + switch encLevel { + case protocol.EncryptionInitial: + return h.initialPackets.GetAckFrame() + case protocol.EncryptionHandshake: + return h.handshakePackets.GetAckFrame() + case protocol.Encryption1RTT: + return h.oneRTTPackets.GetAckFrame() + default: + return nil + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go new file mode 100644 index 00000000..0daba413 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go @@ -0,0 +1,122 @@ +package ackhandler + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// The receivedPacketHistory stores if a packet number has already been received. +// It generates ACK ranges which can be used to assemble an ACK frame. +// It does not store packet contents. +type receivedPacketHistory struct { + ranges *utils.PacketIntervalList + + lowestInReceivedPacketNumbers protocol.PacketNumber +} + +var errTooManyOutstandingReceivedAckRanges = qerr.Error(qerr.InternalError, "Too many outstanding received ACK ranges") + +// newReceivedPacketHistory creates a new received packet history +func newReceivedPacketHistory() *receivedPacketHistory { + return &receivedPacketHistory{ + ranges: utils.NewPacketIntervalList(), + } +} + +// ReceivedPacket registers a packet with PacketNumber p and updates the ranges +func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) error { + if h.ranges.Len() >= protocol.MaxTrackedReceivedAckRanges { + return errTooManyOutstandingReceivedAckRanges + } + + if h.ranges.Len() == 0 { + h.ranges.PushBack(utils.PacketInterval{Start: p, End: p}) + return nil + } + + for el := h.ranges.Back(); el != nil; el = el.Prev() { + // p already included in an existing range. Nothing to do here + if p >= el.Value.Start && p <= el.Value.End { + return nil + } + + var rangeExtended bool + if el.Value.End == p-1 { // extend a range at the end + rangeExtended = true + el.Value.End = p + } else if el.Value.Start == p+1 { // extend a range at the beginning + rangeExtended = true + el.Value.Start = p + } + + // if a range was extended (either at the beginning or at the end, maybe it is possible to merge two ranges into one) + if rangeExtended { + prev := el.Prev() + if prev != nil && prev.Value.End+1 == el.Value.Start { // merge two ranges + prev.Value.End = el.Value.End + h.ranges.Remove(el) + return nil + } + return nil // if the two ranges were not merge, we're done here + } + + // create a new range at the end + if p > el.Value.End { + h.ranges.InsertAfter(utils.PacketInterval{Start: p, End: p}, el) + return nil + } + } + + // create a new range at the beginning + h.ranges.InsertBefore(utils.PacketInterval{Start: p, End: p}, h.ranges.Front()) + + return nil +} + +// DeleteBelow deletes all entries below (but not including) p +func (h *receivedPacketHistory) DeleteBelow(p protocol.PacketNumber) { + if p <= h.lowestInReceivedPacketNumbers { + return + } + h.lowestInReceivedPacketNumbers = p + + nextEl := h.ranges.Front() + for el := h.ranges.Front(); nextEl != nil; el = nextEl { + nextEl = el.Next() + + if p > el.Value.Start && p <= el.Value.End { + el.Value.Start = p + } else if el.Value.End < p { // delete a whole range + h.ranges.Remove(el) + } else { // no ranges affected. Nothing to do + return + } + } +} + +// GetAckRanges gets a slice of all AckRanges that can be used in an AckFrame +func (h *receivedPacketHistory) GetAckRanges() []wire.AckRange { + if h.ranges.Len() == 0 { + return nil + } + + ackRanges := make([]wire.AckRange, h.ranges.Len()) + i := 0 + for el := h.ranges.Back(); el != nil; el = el.Prev() { + ackRanges[i] = wire.AckRange{Smallest: el.Value.Start, Largest: el.Value.End} + i++ + } + return ackRanges +} + +func (h *receivedPacketHistory) GetHighestAckRange() wire.AckRange { + ackRange := wire.AckRange{} + if h.ranges.Len() > 0 { + r := h.ranges.Back().Value + ackRange.Smallest = r.Start + ackRange.Largest = r.End + } + return ackRange +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go new file mode 100644 index 00000000..b7840490 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go @@ -0,0 +1,191 @@ +package ackhandler + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type receivedPacketTracker struct { + largestObserved protocol.PacketNumber + ignoreBelow protocol.PacketNumber + largestObservedReceivedTime time.Time + + packetHistory *receivedPacketHistory + + ackSendDelay time.Duration + rttStats *congestion.RTTStats + + packetsReceivedSinceLastAck int + retransmittablePacketsReceivedSinceLastAck int + ackQueued bool + ackAlarm time.Time + lastAck *wire.AckFrame + + logger utils.Logger + + version protocol.VersionNumber +} + +func newReceivedPacketTracker( + rttStats *congestion.RTTStats, + logger utils.Logger, + version protocol.VersionNumber, +) *receivedPacketTracker { + return &receivedPacketTracker{ + packetHistory: newReceivedPacketHistory(), + ackSendDelay: ackSendDelay, + rttStats: rttStats, + logger: logger, + version: version, + } +} + +func (h *receivedPacketTracker) ReceivedPacket(packetNumber protocol.PacketNumber, rcvTime time.Time, shouldInstigateAck bool) error { + if packetNumber < h.ignoreBelow { + return nil + } + + isMissing := h.isMissing(packetNumber) + if packetNumber >= h.largestObserved { + h.largestObserved = packetNumber + h.largestObservedReceivedTime = rcvTime + } + + if err := h.packetHistory.ReceivedPacket(packetNumber); err != nil { + return err + } + h.maybeQueueAck(packetNumber, rcvTime, shouldInstigateAck, isMissing) + return nil +} + +// IgnoreBelow sets a lower limit for acking packets. +// Packets with packet numbers smaller than p will not be acked. +func (h *receivedPacketTracker) IgnoreBelow(p protocol.PacketNumber) { + if p <= h.ignoreBelow { + return + } + h.ignoreBelow = p + h.packetHistory.DeleteBelow(p) + if h.logger.Debug() { + h.logger.Debugf("\tIgnoring all packets below %#x.", p) + } +} + +// isMissing says if a packet was reported missing in the last ACK. +func (h *receivedPacketTracker) isMissing(p protocol.PacketNumber) bool { + if h.lastAck == nil || p < h.ignoreBelow { + return false + } + return p < h.lastAck.LargestAcked() && !h.lastAck.AcksPacket(p) +} + +func (h *receivedPacketTracker) hasNewMissingPackets() bool { + if h.lastAck == nil { + return false + } + highestRange := h.packetHistory.GetHighestAckRange() + return highestRange.Smallest >= h.lastAck.LargestAcked() && highestRange.Len() <= maxPacketsAfterNewMissing +} + +// maybeQueueAck queues an ACK, if necessary. +// It is implemented analogously to Chrome's QuicConnection::MaybeQueueAck() +// in ACK_DECIMATION_WITH_REORDERING mode. +func (h *receivedPacketTracker) maybeQueueAck(packetNumber protocol.PacketNumber, rcvTime time.Time, shouldInstigateAck, wasMissing bool) { + h.packetsReceivedSinceLastAck++ + + // always ack the first packet + if h.lastAck == nil { + h.logger.Debugf("\tQueueing ACK because the first packet should be acknowledged.") + h.ackQueued = true + return + } + + // Send an ACK if this packet was reported missing in an ACK sent before. + // Ack decimation with reordering relies on the timer to send an ACK, but if + // missing packets we reported in the previous ack, send an ACK immediately. + if wasMissing { + if h.logger.Debug() { + h.logger.Debugf("\tQueueing ACK because packet %#x was missing before.", packetNumber) + } + h.ackQueued = true + } + + if !h.ackQueued && shouldInstigateAck { + h.retransmittablePacketsReceivedSinceLastAck++ + + if packetNumber > minReceivedBeforeAckDecimation { + // ack up to 10 packets at once + if h.retransmittablePacketsReceivedSinceLastAck >= retransmittablePacketsBeforeAck { + h.ackQueued = true + if h.logger.Debug() { + h.logger.Debugf("\tQueueing ACK because packet %d packets were received after the last ACK (using threshold: %d).", h.retransmittablePacketsReceivedSinceLastAck, retransmittablePacketsBeforeAck) + } + } else if h.ackAlarm.IsZero() { + // wait for the minimum of the ack decimation delay or the delayed ack time before sending an ack + ackDelay := utils.MinDuration(ackSendDelay, time.Duration(float64(h.rttStats.MinRTT())*float64(ackDecimationDelay))) + h.ackAlarm = rcvTime.Add(ackDelay) + if h.logger.Debug() { + h.logger.Debugf("\tSetting ACK timer to min(1/4 min-RTT, max ack delay): %s (%s from now)", ackDelay, time.Until(h.ackAlarm)) + } + } + } else { + // send an ACK every 2 retransmittable packets + if h.retransmittablePacketsReceivedSinceLastAck >= initialRetransmittablePacketsBeforeAck { + if h.logger.Debug() { + h.logger.Debugf("\tQueueing ACK because packet %d packets were received after the last ACK (using initial threshold: %d).", h.retransmittablePacketsReceivedSinceLastAck, initialRetransmittablePacketsBeforeAck) + } + h.ackQueued = true + } else if h.ackAlarm.IsZero() { + if h.logger.Debug() { + h.logger.Debugf("\tSetting ACK timer to max ack delay: %s", ackSendDelay) + } + h.ackAlarm = rcvTime.Add(ackSendDelay) + } + } + // If there are new missing packets to report, set a short timer to send an ACK. + if h.hasNewMissingPackets() { + // wait the minimum of 1/8 min RTT and the existing ack time + ackDelay := time.Duration(float64(h.rttStats.MinRTT()) * float64(shortAckDecimationDelay)) + ackTime := rcvTime.Add(ackDelay) + if h.ackAlarm.IsZero() || h.ackAlarm.After(ackTime) { + h.ackAlarm = ackTime + if h.logger.Debug() { + h.logger.Debugf("\tSetting ACK timer to 1/8 min-RTT: %s (%s from now)", ackDelay, time.Until(h.ackAlarm)) + } + } + } + } + + if h.ackQueued { + // cancel the ack alarm + h.ackAlarm = time.Time{} + } +} + +func (h *receivedPacketTracker) GetAckFrame() *wire.AckFrame { + now := time.Now() + if !h.ackQueued && (h.ackAlarm.IsZero() || h.ackAlarm.After(now)) { + return nil + } + if h.logger.Debug() && !h.ackQueued && !h.ackAlarm.IsZero() { + h.logger.Debugf("Sending ACK because the ACK timer expired.") + } + + ack := &wire.AckFrame{ + AckRanges: h.packetHistory.GetAckRanges(), + DelayTime: now.Sub(h.largestObservedReceivedTime), + } + + h.lastAck = ack + h.ackAlarm = time.Time{} + h.ackQueued = false + h.packetsReceivedSinceLastAck = 0 + h.retransmittablePacketsReceivedSinceLastAck = 0 + return ack +} + +func (h *receivedPacketTracker) GetAlarmTimeout() time.Time { return h.ackAlarm } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/retransmittable.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/retransmittable.go new file mode 100644 index 00000000..ae622afd --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/retransmittable.go @@ -0,0 +1,34 @@ +package ackhandler + +import "github.com/lucas-clemente/quic-go/internal/wire" + +// Returns a new slice with all non-retransmittable frames deleted. +func stripNonRetransmittableFrames(fs []wire.Frame) []wire.Frame { + res := make([]wire.Frame, 0, len(fs)) + for _, f := range fs { + if IsFrameRetransmittable(f) { + res = append(res, f) + } + } + return res +} + +// IsFrameRetransmittable returns true if the frame should be retransmitted. +func IsFrameRetransmittable(f wire.Frame) bool { + switch f.(type) { + case *wire.AckFrame: + return false + default: + return true + } +} + +// HasRetransmittableFrames returns true if at least one frame is retransmittable. +func HasRetransmittableFrames(fs []wire.Frame) bool { + for _, f := range fs { + if IsFrameRetransmittable(f) { + return true + } + } + return false +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/send_mode.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/send_mode.go new file mode 100644 index 00000000..8cdaa7e6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/send_mode.go @@ -0,0 +1,36 @@ +package ackhandler + +import "fmt" + +// The SendMode says what kind of packets can be sent. +type SendMode uint8 + +const ( + // SendNone means that no packets should be sent + SendNone SendMode = iota + // SendAck means an ACK-only packet should be sent + SendAck + // SendRetransmission means that retransmissions should be sent + SendRetransmission + // SendPTO means that a probe packet should be sent + SendPTO + // SendAny means that any packet should be sent + SendAny +) + +func (s SendMode) String() string { + switch s { + case SendNone: + return "none" + case SendAck: + return "ack" + case SendRetransmission: + return "retransmission" + case SendPTO: + return "pto" + case SendAny: + return "any" + default: + return fmt.Sprintf("invalid send mode: %d", s) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go new file mode 100644 index 00000000..51e28fc0 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go @@ -0,0 +1,647 @@ +package ackhandler + +import ( + "errors" + "fmt" + "math" + "time" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +const ( + // Maximum reordering in time space before time based loss detection considers a packet lost. + // In fraction of an RTT. + timeReorderingFraction = 1.0 / 8 + // Timer granularity. The timer will not be set to a value smaller than granularity. + granularity = time.Millisecond +) + +type packetNumberSpace struct { + history *sentPacketHistory + pns *packetNumberGenerator + + largestAcked protocol.PacketNumber + largestSent protocol.PacketNumber +} + +func newPacketNumberSpace(initialPN protocol.PacketNumber) *packetNumberSpace { + return &packetNumberSpace{ + history: newSentPacketHistory(), + pns: newPacketNumberGenerator(initialPN, protocol.SkipPacketAveragePeriodLength), + } +} + +type sentPacketHandler struct { + lastSentRetransmittablePacketTime time.Time // only applies to the application-data packet number space + lastSentCryptoPacketTime time.Time + + nextSendTime time.Time + + initialPackets *packetNumberSpace + handshakePackets *packetNumberSpace + oneRTTPackets *packetNumberSpace + + // lowestNotConfirmedAcked is the lowest packet number that we sent an ACK for, but haven't received confirmation, that this ACK actually arrived + // example: we send an ACK for packets 90-100 with packet number 20 + // once we receive an ACK from the peer for packet 20, the lowestNotConfirmedAcked is 101 + // Only applies to the application-data packet number space. + lowestNotConfirmedAcked protocol.PacketNumber + + retransmissionQueue []*Packet + + bytesInFlight protocol.ByteCount + + congestion congestion.SendAlgorithm + rttStats *congestion.RTTStats + + handshakeComplete bool + + // The number of times the crypto packets have been retransmitted without receiving an ack. + cryptoCount uint32 + // The number of times a PTO has been sent without receiving an ack. + ptoCount uint32 + // The number of PTO probe packets that should be sent. + // Only applies to the application-data packet number space. + numProbesToSend int + + // The time at which the next packet will be considered lost based on early transmit or exceeding the reordering window in time. + lossTime time.Time + + // The alarm timeout + alarm time.Time + + logger utils.Logger +} + +// NewSentPacketHandler creates a new sentPacketHandler +func NewSentPacketHandler( + initialPacketNumber protocol.PacketNumber, + rttStats *congestion.RTTStats, + logger utils.Logger, +) SentPacketHandler { + congestion := congestion.NewCubicSender( + congestion.DefaultClock{}, + rttStats, + false, /* don't use reno since chromium doesn't (why?) */ + protocol.InitialCongestionWindow, + protocol.DefaultMaxCongestionWindow, + ) + + return &sentPacketHandler{ + initialPackets: newPacketNumberSpace(initialPacketNumber), + handshakePackets: newPacketNumberSpace(0), + oneRTTPackets: newPacketNumberSpace(0), + rttStats: rttStats, + congestion: congestion, + logger: logger, + } +} + +func (h *sentPacketHandler) SetHandshakeComplete() { + h.logger.Debugf("Handshake complete. Discarding all outstanding crypto packets.") + var queue []*Packet + for _, packet := range h.retransmissionQueue { + if packet.EncryptionLevel == protocol.Encryption1RTT { + queue = append(queue, packet) + } + } + for _, pnSpace := range []*packetNumberSpace{h.initialPackets, h.handshakePackets} { + var cryptoPackets []*Packet + pnSpace.history.Iterate(func(p *Packet) (bool, error) { + cryptoPackets = append(cryptoPackets, p) + return true, nil + }) + for _, p := range cryptoPackets { + pnSpace.history.Remove(p.PacketNumber) + } + } + h.retransmissionQueue = queue + h.handshakeComplete = true +} + +func (h *sentPacketHandler) SentPacket(packet *Packet) { + if isRetransmittable := h.sentPacketImpl(packet); isRetransmittable { + h.getPacketNumberSpace(packet.EncryptionLevel).history.SentPacket(packet) + h.updateLossDetectionAlarm() + } +} + +func (h *sentPacketHandler) SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) { + var p []*Packet + for _, packet := range packets { + if isRetransmittable := h.sentPacketImpl(packet); isRetransmittable { + p = append(p, packet) + } + } + h.getPacketNumberSpace(p[0].EncryptionLevel).history.SentPacketsAsRetransmission(p, retransmissionOf) + h.updateLossDetectionAlarm() +} + +func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace { + switch encLevel { + case protocol.EncryptionInitial: + return h.initialPackets + case protocol.EncryptionHandshake: + return h.handshakePackets + case protocol.Encryption1RTT: + return h.oneRTTPackets + default: + panic("invalid packet number space") + } +} + +func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* isRetransmittable */ { + pnSpace := h.getPacketNumberSpace(packet.EncryptionLevel) + + if h.logger.Debug() && pnSpace.largestSent != 0 { + for p := pnSpace.largestSent + 1; p < packet.PacketNumber; p++ { + h.logger.Debugf("Skipping packet number %#x", p) + } + } + + pnSpace.largestSent = packet.PacketNumber + + if len(packet.Frames) > 0 { + if ackFrame, ok := packet.Frames[0].(*wire.AckFrame); ok { + packet.largestAcked = ackFrame.LargestAcked() + } + } + + packet.Frames = stripNonRetransmittableFrames(packet.Frames) + isRetransmittable := len(packet.Frames) != 0 + + if isRetransmittable { + if packet.EncryptionLevel != protocol.Encryption1RTT { + h.lastSentCryptoPacketTime = packet.SendTime + } + h.lastSentRetransmittablePacketTime = packet.SendTime + packet.includedInBytesInFlight = true + h.bytesInFlight += packet.Length + packet.canBeRetransmitted = true + if h.numProbesToSend > 0 { + h.numProbesToSend-- + } + } + h.congestion.OnPacketSent(packet.SendTime, h.bytesInFlight, packet.PacketNumber, packet.Length, isRetransmittable) + + h.nextSendTime = utils.MaxTime(h.nextSendTime, packet.SendTime).Add(h.congestion.TimeUntilSend(h.bytesInFlight)) + return isRetransmittable +} + +func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time) error { + pnSpace := h.getPacketNumberSpace(encLevel) + + largestAcked := ackFrame.LargestAcked() + if largestAcked > pnSpace.largestSent { + return qerr.Error(qerr.ProtocolViolation, "Received ACK for an unsent packet") + } + + pnSpace.largestAcked = utils.MaxPacketNumber(pnSpace.largestAcked, largestAcked) + + if !pnSpace.pns.Validate(ackFrame) { + return qerr.Error(qerr.ProtocolViolation, "Received an ACK for a skipped packet number") + } + + // maybe update the RTT + if p := pnSpace.history.GetPacket(ackFrame.LargestAcked()); p != nil { + h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackFrame.DelayTime, rcvTime) + if h.logger.Debug() { + h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) + } + h.congestion.MaybeExitSlowStart() + } + + ackedPackets, err := h.determineNewlyAckedPackets(ackFrame, encLevel) + if err != nil { + return err + } + if len(ackedPackets) == 0 { + return nil + } + + priorInFlight := h.bytesInFlight + for _, p := range ackedPackets { + // largestAcked == 0 either means that the packet didn't contain an ACK, or it just acked packet 0 + // It is safe to ignore the corner case of packets that just acked packet 0, because + // the lowestPacketNotConfirmedAcked is only used to limit the number of ACK ranges we will send. + if p.largestAcked != 0 && encLevel == protocol.Encryption1RTT { + h.lowestNotConfirmedAcked = utils.MaxPacketNumber(h.lowestNotConfirmedAcked, p.largestAcked+1) + } + if err := h.onPacketAcked(p, rcvTime); err != nil { + return err + } + if p.includedInBytesInFlight { + h.congestion.OnPacketAcked(p.PacketNumber, p.Length, priorInFlight, rcvTime) + } + } + + if err := h.detectLostPackets(rcvTime, encLevel, priorInFlight); err != nil { + return err + } + + h.ptoCount = 0 + h.cryptoCount = 0 + h.numProbesToSend = 0 + + h.updateLossDetectionAlarm() + return nil +} + +func (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber { + return h.lowestNotConfirmedAcked +} + +func (h *sentPacketHandler) determineNewlyAckedPackets( + ackFrame *wire.AckFrame, + encLevel protocol.EncryptionLevel, +) ([]*Packet, error) { + pnSpace := h.getPacketNumberSpace(encLevel) + var ackedPackets []*Packet + ackRangeIndex := 0 + lowestAcked := ackFrame.LowestAcked() + largestAcked := ackFrame.LargestAcked() + err := pnSpace.history.Iterate(func(p *Packet) (bool, error) { + // Ignore packets below the lowest acked + if p.PacketNumber < lowestAcked { + return true, nil + } + // Break after largest acked is reached + if p.PacketNumber > largestAcked { + return false, nil + } + + if ackFrame.HasMissingRanges() { + ackRange := ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex] + + for p.PacketNumber > ackRange.Largest && ackRangeIndex < len(ackFrame.AckRanges)-1 { + ackRangeIndex++ + ackRange = ackFrame.AckRanges[len(ackFrame.AckRanges)-1-ackRangeIndex] + } + + if p.PacketNumber >= ackRange.Smallest { // packet i contained in ACK range + if p.PacketNumber > ackRange.Largest { + return false, fmt.Errorf("BUG: ackhandler would have acked wrong packet 0x%x, while evaluating range 0x%x -> 0x%x", p.PacketNumber, ackRange.Smallest, ackRange.Largest) + } + ackedPackets = append(ackedPackets, p) + } + } else { + ackedPackets = append(ackedPackets, p) + } + return true, nil + }) + if h.logger.Debug() && len(ackedPackets) > 0 { + pns := make([]protocol.PacketNumber, len(ackedPackets)) + for i, p := range ackedPackets { + pns[i] = p.PacketNumber + } + h.logger.Debugf("\tnewly acked packets (%d): %#x", len(pns), pns) + } + return ackedPackets, err +} + +func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool { + return h.initialPackets.history.HasOutstandingPackets() || h.handshakePackets.history.HasOutstandingPackets() +} + +func (h *sentPacketHandler) hasOutstandingPackets() bool { + return h.oneRTTPackets.history.HasOutstandingPackets() || h.hasOutstandingCryptoPackets() +} + +func (h *sentPacketHandler) updateLossDetectionAlarm() { + // Cancel the alarm if no packets are outstanding + if !h.hasOutstandingPackets() { + h.alarm = time.Time{} + return + } + + if h.hasOutstandingCryptoPackets() { + h.alarm = h.lastSentCryptoPacketTime.Add(h.computeCryptoTimeout()) + } else if !h.lossTime.IsZero() { + // Early retransmit timer or time loss detection. + h.alarm = h.lossTime + } else { // PTO alarm + h.alarm = h.lastSentRetransmittablePacketTime.Add(h.computePTOTimeout()) + } +} + +func (h *sentPacketHandler) detectLostPackets( + now time.Time, + encLevel protocol.EncryptionLevel, + priorInFlight protocol.ByteCount, +) error { + if encLevel == protocol.Encryption1RTT { + h.lossTime = time.Time{} + } + pnSpace := h.getPacketNumberSpace(encLevel) + + maxRTT := float64(utils.MaxDuration(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) + delayUntilLost := time.Duration((1.0 + timeReorderingFraction) * maxRTT) + + var lostPackets []*Packet + pnSpace.history.Iterate(func(packet *Packet) (bool, error) { + if packet.PacketNumber > pnSpace.largestAcked { + return false, nil + } + + timeSinceSent := now.Sub(packet.SendTime) + if timeSinceSent > delayUntilLost { + lostPackets = append(lostPackets, packet) + } else if h.lossTime.IsZero() && encLevel == protocol.Encryption1RTT { + if h.logger.Debug() { + h.logger.Debugf("\tsetting loss timer for packet %#x to %s (in %s)", packet.PacketNumber, delayUntilLost, delayUntilLost-timeSinceSent) + } + // Note: This conditional is only entered once per call + h.lossTime = now.Add(delayUntilLost - timeSinceSent) + } + return true, nil + }) + + if h.logger.Debug() && len(lostPackets) > 0 { + pns := make([]protocol.PacketNumber, len(lostPackets)) + for i, p := range lostPackets { + pns[i] = p.PacketNumber + } + h.logger.Debugf("\tlost packets (%d): %#x", len(pns), pns) + } + + for _, p := range lostPackets { + // the bytes in flight need to be reduced no matter if this packet will be retransmitted + if p.includedInBytesInFlight { + h.bytesInFlight -= p.Length + h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight) + } + if p.canBeRetransmitted { + // queue the packet for retransmission, and report the loss to the congestion controller + if err := h.queuePacketForRetransmission(p, pnSpace); err != nil { + return err + } + } + pnSpace.history.Remove(p.PacketNumber) + } + return nil +} + +func (h *sentPacketHandler) OnAlarm() error { + // When all outstanding are acknowledged, the alarm is canceled in + // updateLossDetectionAlarm. This doesn't reset the timer in the session though. + // When OnAlarm is called, we therefore need to make sure that there are + // actually packets outstanding. + if h.hasOutstandingPackets() { + if err := h.onVerifiedAlarm(); err != nil { + return err + } + } + h.updateLossDetectionAlarm() + return nil +} + +func (h *sentPacketHandler) onVerifiedAlarm() error { + var err error + if h.hasOutstandingCryptoPackets() { + if h.logger.Debug() { + h.logger.Debugf("Loss detection alarm fired in crypto mode. Crypto count: %d", h.cryptoCount) + } + h.cryptoCount++ + err = h.queueCryptoPacketsForRetransmission() + } else if !h.lossTime.IsZero() { + if h.logger.Debug() { + h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", h.lossTime) + } + // Early retransmit or time loss detection + err = h.detectLostPackets(time.Now(), protocol.Encryption1RTT, h.bytesInFlight) + } else { // PTO + if h.logger.Debug() { + h.logger.Debugf("Loss detection alarm fired in PTO mode. PTO count: %d", h.ptoCount) + } + h.ptoCount++ + h.numProbesToSend += 2 + } + return err +} + +func (h *sentPacketHandler) GetAlarmTimeout() time.Time { + return h.alarm +} + +func (h *sentPacketHandler) onPacketAcked(p *Packet, rcvTime time.Time) error { + pnSpace := h.getPacketNumberSpace(p.EncryptionLevel) + // This happens if a packet and its retransmissions is acked in the same ACK. + // As soon as we process the first one, this will remove all the retransmissions, + // so we won't find the retransmitted packet number later. + if packet := pnSpace.history.GetPacket(p.PacketNumber); packet == nil { + return nil + } + + // only report the acking of this packet to the congestion controller if: + // * it is a retransmittable packet + // * this packet wasn't retransmitted yet + if p.isRetransmission { + // that the parent doesn't exist is expected to happen every time the original packet was already acked + if parent := pnSpace.history.GetPacket(p.retransmissionOf); parent != nil { + if len(parent.retransmittedAs) == 1 { + parent.retransmittedAs = nil + } else { + // remove this packet from the slice of retransmission + retransmittedAs := make([]protocol.PacketNumber, 0, len(parent.retransmittedAs)-1) + for _, pn := range parent.retransmittedAs { + if pn != p.PacketNumber { + retransmittedAs = append(retransmittedAs, pn) + } + } + parent.retransmittedAs = retransmittedAs + } + } + } + // this also applies to packets that have been retransmitted as probe packets + if p.includedInBytesInFlight { + h.bytesInFlight -= p.Length + } + if err := h.stopRetransmissionsFor(p, pnSpace); err != nil { + return err + } + return pnSpace.history.Remove(p.PacketNumber) +} + +func (h *sentPacketHandler) stopRetransmissionsFor(p *Packet, pnSpace *packetNumberSpace) error { + if err := pnSpace.history.MarkCannotBeRetransmitted(p.PacketNumber); err != nil { + return err + } + for _, r := range p.retransmittedAs { + packet := pnSpace.history.GetPacket(r) + if packet == nil { + return fmt.Errorf("sent packet handler BUG: marking packet as not retransmittable %d (retransmission of %d) not found in history", r, p.PacketNumber) + } + h.stopRetransmissionsFor(packet, pnSpace) + } + return nil +} + +func (h *sentPacketHandler) DequeuePacketForRetransmission() *Packet { + if len(h.retransmissionQueue) == 0 { + return nil + } + packet := h.retransmissionQueue[0] + // Shift the slice and don't retain anything that isn't needed. + copy(h.retransmissionQueue, h.retransmissionQueue[1:]) + h.retransmissionQueue[len(h.retransmissionQueue)-1] = nil + h.retransmissionQueue = h.retransmissionQueue[:len(h.retransmissionQueue)-1] + return packet +} + +func (h *sentPacketHandler) DequeueProbePacket() (*Packet, error) { + pnSpace := h.getPacketNumberSpace(protocol.Encryption1RTT) + if len(h.retransmissionQueue) == 0 { + p := pnSpace.history.FirstOutstanding() + if p == nil { + return nil, errors.New("cannot dequeue a probe packet. No outstanding packets") + } + if err := h.queuePacketForRetransmission(p, pnSpace); err != nil { + return nil, err + } + } + return h.DequeuePacketForRetransmission(), nil +} + +func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) { + pnSpace := h.getPacketNumberSpace(encLevel) + + var lowestUnacked protocol.PacketNumber + if p := pnSpace.history.FirstOutstanding(); p != nil { + lowestUnacked = p.PacketNumber + } else { + lowestUnacked = pnSpace.largestAcked + 1 + } + + pn := pnSpace.pns.Peek() + return pn, protocol.GetPacketNumberLengthForHeader(pn, lowestUnacked) +} + +func (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) protocol.PacketNumber { + return h.getPacketNumberSpace(encLevel).pns.Pop() +} + +func (h *sentPacketHandler) SendMode() SendMode { + numTrackedPackets := len(h.retransmissionQueue) + h.initialPackets.history.Len() + + h.handshakePackets.history.Len() + h.oneRTTPackets.history.Len() + + // Don't send any packets if we're keeping track of the maximum number of packets. + // Note that since MaxOutstandingSentPackets is smaller than MaxTrackedSentPackets, + // we will stop sending out new data when reaching MaxOutstandingSentPackets, + // but still allow sending of retransmissions and ACKs. + if numTrackedPackets >= protocol.MaxTrackedSentPackets { + if h.logger.Debug() { + h.logger.Debugf("Limited by the number of tracked packets: tracking %d packets, maximum %d", numTrackedPackets, protocol.MaxTrackedSentPackets) + } + return SendNone + } + if h.numProbesToSend > 0 { + return SendPTO + } + // Only send ACKs if we're congestion limited. + if cwnd := h.congestion.GetCongestionWindow(); h.bytesInFlight > cwnd { + if h.logger.Debug() { + h.logger.Debugf("Congestion limited: bytes in flight %d, window %d", h.bytesInFlight, cwnd) + } + return SendAck + } + // Send retransmissions first, if there are any. + if len(h.retransmissionQueue) > 0 { + return SendRetransmission + } + if numTrackedPackets >= protocol.MaxOutstandingSentPackets { + if h.logger.Debug() { + h.logger.Debugf("Max outstanding limited: tracking %d packets, maximum: %d", numTrackedPackets, protocol.MaxOutstandingSentPackets) + } + return SendAck + } + return SendAny +} + +func (h *sentPacketHandler) TimeUntilSend() time.Time { + return h.nextSendTime +} + +func (h *sentPacketHandler) ShouldSendNumPackets() int { + if h.numProbesToSend > 0 { + // RTO probes should not be paced, but must be sent immediately. + return h.numProbesToSend + } + delay := h.congestion.TimeUntilSend(h.bytesInFlight) + if delay == 0 || delay > protocol.MinPacingDelay { + return 1 + } + return int(math.Ceil(float64(protocol.MinPacingDelay) / float64(delay))) +} + +func (h *sentPacketHandler) queueCryptoPacketsForRetransmission() error { + if err := h.queueAllPacketsForRetransmission(protocol.EncryptionInitial); err != nil { + return err + } + return h.queueAllPacketsForRetransmission(protocol.EncryptionHandshake) +} + +func (h *sentPacketHandler) queueAllPacketsForRetransmission(encLevel protocol.EncryptionLevel) error { + var packets []*Packet + pnSpace := h.getPacketNumberSpace(encLevel) + pnSpace.history.Iterate(func(p *Packet) (bool, error) { + if p.canBeRetransmitted { + packets = append(packets, p) + } + return true, nil + }) + for _, p := range packets { + h.logger.Debugf("Queueing packet %#x (%s) as a crypto retransmission", p.PacketNumber, encLevel) + if err := h.queuePacketForRetransmission(p, pnSpace); err != nil { + return err + } + } + return nil +} + +func (h *sentPacketHandler) queuePacketForRetransmission(p *Packet, pnSpace *packetNumberSpace) error { + if !p.canBeRetransmitted { + return fmt.Errorf("sent packet handler BUG: packet %d already queued for retransmission", p.PacketNumber) + } + if err := pnSpace.history.MarkCannotBeRetransmitted(p.PacketNumber); err != nil { + return err + } + h.retransmissionQueue = append(h.retransmissionQueue, p) + return nil +} + +func (h *sentPacketHandler) computeCryptoTimeout() time.Duration { + duration := utils.MaxDuration(2*h.rttStats.SmoothedOrInitialRTT(), granularity) + // exponential backoff + // There's an implicit limit to this set by the crypto timeout. + return duration << h.cryptoCount +} + +func (h *sentPacketHandler) computePTOTimeout() time.Duration { + // TODO(#1236): include the max_ack_delay + duration := utils.MaxDuration(h.rttStats.SmoothedOrInitialRTT()+4*h.rttStats.MeanDeviation(), granularity) + return duration << h.ptoCount +} + +func (h *sentPacketHandler) ResetForRetry() error { + h.cryptoCount = 0 + h.bytesInFlight = 0 + var packets []*Packet + h.initialPackets.history.Iterate(func(p *Packet) (bool, error) { + if p.canBeRetransmitted { + packets = append(packets, p) + } + return true, nil + }) + for _, p := range packets { + h.logger.Debugf("Queueing packet %#x for retransmission.", p.PacketNumber) + h.retransmissionQueue = append(h.retransmissionQueue, p) + } + h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Pop()) + h.updateLossDetectionAlarm() + return nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go new file mode 100644 index 00000000..393ebba6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go @@ -0,0 +1,148 @@ +package ackhandler + +import ( + "fmt" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +type sentPacketHistory struct { + packetList *PacketList + packetMap map[protocol.PacketNumber]*PacketElement + + numOutstandingPackets int + + firstOutstanding *PacketElement +} + +func newSentPacketHistory() *sentPacketHistory { + return &sentPacketHistory{ + packetList: NewPacketList(), + packetMap: make(map[protocol.PacketNumber]*PacketElement), + } +} + +func (h *sentPacketHistory) SentPacket(p *Packet) { + h.sentPacketImpl(p) +} + +func (h *sentPacketHistory) sentPacketImpl(p *Packet) *PacketElement { + el := h.packetList.PushBack(*p) + h.packetMap[p.PacketNumber] = el + if h.firstOutstanding == nil { + h.firstOutstanding = el + } + if p.canBeRetransmitted { + h.numOutstandingPackets++ + } + return el +} + +func (h *sentPacketHistory) SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) { + retransmission, ok := h.packetMap[retransmissionOf] + // The retransmitted packet is not present anymore. + // This can happen if it was acked in between dequeueing of the retransmission and sending. + // Just treat the retransmissions as normal packets. + // TODO: This won't happen if we clear packets queued for retransmission on new ACKs. + if !ok { + for _, packet := range packets { + h.sentPacketImpl(packet) + } + return + } + retransmission.Value.retransmittedAs = make([]protocol.PacketNumber, len(packets)) + for i, packet := range packets { + retransmission.Value.retransmittedAs[i] = packet.PacketNumber + el := h.sentPacketImpl(packet) + el.Value.isRetransmission = true + el.Value.retransmissionOf = retransmissionOf + } +} + +func (h *sentPacketHistory) GetPacket(p protocol.PacketNumber) *Packet { + if el, ok := h.packetMap[p]; ok { + return &el.Value + } + return nil +} + +// Iterate iterates through all packets. +// The callback must not modify the history. +func (h *sentPacketHistory) Iterate(cb func(*Packet) (cont bool, err error)) error { + cont := true + for el := h.packetList.Front(); cont && el != nil; el = el.Next() { + var err error + cont, err = cb(&el.Value) + if err != nil { + return err + } + } + return nil +} + +// FirstOutStanding returns the first outstanding packet. +// It must not be modified (e.g. retransmitted). +// Use DequeueFirstPacketForRetransmission() to retransmit it. +func (h *sentPacketHistory) FirstOutstanding() *Packet { + if h.firstOutstanding == nil { + return nil + } + return &h.firstOutstanding.Value +} + +// QueuePacketForRetransmission marks a packet for retransmission. +// A packet can only be queued once. +func (h *sentPacketHistory) MarkCannotBeRetransmitted(pn protocol.PacketNumber) error { + el, ok := h.packetMap[pn] + if !ok { + return fmt.Errorf("sent packet history: packet %d not found", pn) + } + if el.Value.canBeRetransmitted { + h.numOutstandingPackets-- + if h.numOutstandingPackets < 0 { + panic("numOutstandingHandshakePackets negative") + } + } + el.Value.canBeRetransmitted = false + if el == h.firstOutstanding { + h.readjustFirstOutstanding() + } + return nil +} + +// readjustFirstOutstanding readjusts the pointer to the first outstanding packet. +// This is necessary every time the first outstanding packet is deleted or retransmitted. +func (h *sentPacketHistory) readjustFirstOutstanding() { + el := h.firstOutstanding.Next() + for el != nil && !el.Value.canBeRetransmitted { + el = el.Next() + } + h.firstOutstanding = el +} + +func (h *sentPacketHistory) Len() int { + return len(h.packetMap) +} + +func (h *sentPacketHistory) Remove(p protocol.PacketNumber) error { + el, ok := h.packetMap[p] + if !ok { + return fmt.Errorf("packet %d not found in sent packet history", p) + } + if el == h.firstOutstanding { + h.readjustFirstOutstanding() + } + if el.Value.canBeRetransmitted { + h.numOutstandingPackets-- + if h.numOutstandingPackets < 0 { + panic("numOutstandingHandshakePackets negative") + } + } + h.packetList.Remove(el) + delete(h.packetMap, p) + return nil +} + +func (h *sentPacketHistory) HasOutstandingPackets() bool { + return h.numOutstandingPackets > 0 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/bandwidth.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/bandwidth.go new file mode 100644 index 00000000..54269c56 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/bandwidth.go @@ -0,0 +1,22 @@ +package congestion + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// Bandwidth of a connection +type Bandwidth uint64 + +const ( + // BitsPerSecond is 1 bit per second + BitsPerSecond Bandwidth = 1 + // BytesPerSecond is 1 byte per second + BytesPerSecond = 8 * BitsPerSecond +) + +// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta +func BandwidthFromDelta(bytes protocol.ByteCount, delta time.Duration) Bandwidth { + return Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/clock.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/clock.go new file mode 100644 index 00000000..405fae70 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/clock.go @@ -0,0 +1,18 @@ +package congestion + +import "time" + +// A Clock returns the current time +type Clock interface { + Now() time.Time +} + +// DefaultClock implements the Clock interface using the Go stdlib clock. +type DefaultClock struct{} + +var _ Clock = DefaultClock{} + +// Now gets the current time +func (DefaultClock) Now() time.Time { + return time.Now() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go new file mode 100644 index 00000000..dcf91fc6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go @@ -0,0 +1,210 @@ +package congestion + +import ( + "math" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// This cubic implementation is based on the one found in Chromiums's QUIC +// implementation, in the files net/quic/congestion_control/cubic.{hh,cc}. + +// Constants based on TCP defaults. +// The following constants are in 2^10 fractions of a second instead of ms to +// allow a 10 shift right to divide. + +// 1024*1024^3 (first 1024 is from 0.100^3) +// where 0.100 is 100 ms which is the scaling round trip time. +const cubeScale = 40 +const cubeCongestionWindowScale = 410 +const cubeFactor protocol.ByteCount = 1 << cubeScale / cubeCongestionWindowScale / protocol.DefaultTCPMSS + +const defaultNumConnections = 2 + +// Default Cubic backoff factor +const beta float32 = 0.7 + +// Additional backoff factor when loss occurs in the concave part of the Cubic +// curve. This additional backoff factor is expected to give up bandwidth to +// new concurrent flows and speed up convergence. +const betaLastMax float32 = 0.85 + +// Cubic implements the cubic algorithm from TCP +type Cubic struct { + clock Clock + + // Number of connections to simulate. + numConnections int + + // Time when this cycle started, after last loss event. + epoch time.Time + + // Max congestion window used just before last loss event. + // Note: to improve fairness to other streams an additional back off is + // applied to this value if the new value is below our latest value. + lastMaxCongestionWindow protocol.ByteCount + + // Number of acked bytes since the cycle started (epoch). + ackedBytesCount protocol.ByteCount + + // TCP Reno equivalent congestion window in packets. + estimatedTCPcongestionWindow protocol.ByteCount + + // Origin point of cubic function. + originPointCongestionWindow protocol.ByteCount + + // Time to origin point of cubic function in 2^10 fractions of a second. + timeToOriginPoint uint32 + + // Last congestion window in packets computed by cubic function. + lastTargetCongestionWindow protocol.ByteCount +} + +// NewCubic returns a new Cubic instance +func NewCubic(clock Clock) *Cubic { + c := &Cubic{ + clock: clock, + numConnections: defaultNumConnections, + } + c.Reset() + return c +} + +// Reset is called after a timeout to reset the cubic state +func (c *Cubic) Reset() { + c.epoch = time.Time{} + c.lastMaxCongestionWindow = 0 + c.ackedBytesCount = 0 + c.estimatedTCPcongestionWindow = 0 + c.originPointCongestionWindow = 0 + c.timeToOriginPoint = 0 + c.lastTargetCongestionWindow = 0 +} + +func (c *Cubic) alpha() float32 { + // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that + // beta here is a cwnd multiplier, and is equal to 1-beta from the paper. + // We derive the equivalent alpha for an N-connection emulation as: + b := c.beta() + return 3 * float32(c.numConnections) * float32(c.numConnections) * (1 - b) / (1 + b) +} + +func (c *Cubic) beta() float32 { + // kNConnectionBeta is the backoff factor after loss for our N-connection + // emulation, which emulates the effective backoff of an ensemble of N + // TCP-Reno connections on a single loss event. The effective multiplier is + // computed as: + return (float32(c.numConnections) - 1 + beta) / float32(c.numConnections) +} + +func (c *Cubic) betaLastMax() float32 { + // betaLastMax is the additional backoff factor after loss for our + // N-connection emulation, which emulates the additional backoff of + // an ensemble of N TCP-Reno connections on a single loss event. The + // effective multiplier is computed as: + return (float32(c.numConnections) - 1 + betaLastMax) / float32(c.numConnections) +} + +// OnApplicationLimited is called on ack arrival when sender is unable to use +// the available congestion window. Resets Cubic state during quiescence. +func (c *Cubic) OnApplicationLimited() { + // When sender is not using the available congestion window, the window does + // not grow. But to be RTT-independent, Cubic assumes that the sender has been + // using the entire window during the time since the beginning of the current + // "epoch" (the end of the last loss recovery period). Since + // application-limited periods break this assumption, we reset the epoch when + // in such a period. This reset effectively freezes congestion window growth + // through application-limited periods and allows Cubic growth to continue + // when the entire window is being used. + c.epoch = time.Time{} +} + +// CongestionWindowAfterPacketLoss computes a new congestion window to use after +// a loss event. Returns the new congestion window in packets. The new +// congestion window is a multiplicative decrease of our current window. +func (c *Cubic) CongestionWindowAfterPacketLoss(currentCongestionWindow protocol.ByteCount) protocol.ByteCount { + if currentCongestionWindow+protocol.DefaultTCPMSS < c.lastMaxCongestionWindow { + // We never reached the old max, so assume we are competing with another + // flow. Use our extra back off factor to allow the other flow to go up. + c.lastMaxCongestionWindow = protocol.ByteCount(c.betaLastMax() * float32(currentCongestionWindow)) + } else { + c.lastMaxCongestionWindow = currentCongestionWindow + } + c.epoch = time.Time{} // Reset time. + return protocol.ByteCount(float32(currentCongestionWindow) * c.beta()) +} + +// CongestionWindowAfterAck computes a new congestion window to use after a received ACK. +// Returns the new congestion window in packets. The new congestion window +// follows a cubic function that depends on the time passed since last +// packet loss. +func (c *Cubic) CongestionWindowAfterAck( + ackedBytes protocol.ByteCount, + currentCongestionWindow protocol.ByteCount, + delayMin time.Duration, + eventTime time.Time, +) protocol.ByteCount { + c.ackedBytesCount += ackedBytes + + if c.epoch.IsZero() { + // First ACK after a loss event. + c.epoch = eventTime // Start of epoch. + c.ackedBytesCount = ackedBytes // Reset count. + // Reset estimated_tcp_congestion_window_ to be in sync with cubic. + c.estimatedTCPcongestionWindow = currentCongestionWindow + if c.lastMaxCongestionWindow <= currentCongestionWindow { + c.timeToOriginPoint = 0 + c.originPointCongestionWindow = currentCongestionWindow + } else { + c.timeToOriginPoint = uint32(math.Cbrt(float64(cubeFactor * (c.lastMaxCongestionWindow - currentCongestionWindow)))) + c.originPointCongestionWindow = c.lastMaxCongestionWindow + } + } + + // Change the time unit from microseconds to 2^10 fractions per second. Take + // the round trip time in account. This is done to allow us to use shift as a + // divide operator. + elapsedTime := int64(eventTime.Add(delayMin).Sub(c.epoch)/time.Microsecond) << 10 / (1000 * 1000) + + // Right-shifts of negative, signed numbers have implementation-dependent + // behavior, so force the offset to be positive, as is done in the kernel. + offset := int64(c.timeToOriginPoint) - elapsedTime + if offset < 0 { + offset = -offset + } + + deltaCongestionWindow := protocol.ByteCount(cubeCongestionWindowScale*offset*offset*offset) * protocol.DefaultTCPMSS >> cubeScale + var targetCongestionWindow protocol.ByteCount + if elapsedTime > int64(c.timeToOriginPoint) { + targetCongestionWindow = c.originPointCongestionWindow + deltaCongestionWindow + } else { + targetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow + } + // Limit the CWND increase to half the acked bytes. + targetCongestionWindow = utils.MinByteCount(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2) + + // Increase the window by approximately Alpha * 1 MSS of bytes every + // time we ack an estimated tcp window of bytes. For small + // congestion windows (less than 25), the formula below will + // increase slightly slower than linearly per estimated tcp window + // of bytes. + c.estimatedTCPcongestionWindow += protocol.ByteCount(float32(c.ackedBytesCount) * c.alpha() * float32(protocol.DefaultTCPMSS) / float32(c.estimatedTCPcongestionWindow)) + c.ackedBytesCount = 0 + + // We have a new cubic congestion window. + c.lastTargetCongestionWindow = targetCongestionWindow + + // Compute target congestion_window based on cubic target and estimated TCP + // congestion_window, use highest (fastest). + if targetCongestionWindow < c.estimatedTCPcongestionWindow { + targetCongestionWindow = c.estimatedTCPcongestionWindow + } + return targetCongestionWindow +} + +// SetNumConnections sets the number of emulated connections +func (c *Cubic) SetNumConnections(n int) { + c.numConnections = n +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go new file mode 100644 index 00000000..6f3d3289 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go @@ -0,0 +1,314 @@ +package congestion + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +const ( + maxBurstBytes = 3 * protocol.DefaultTCPMSS + renoBeta float32 = 0.7 // Reno backoff factor. + defaultMinimumCongestionWindow protocol.ByteCount = 2 * protocol.DefaultTCPMSS +) + +type cubicSender struct { + hybridSlowStart HybridSlowStart + prr PrrSender + rttStats *RTTStats + stats connectionStats + cubic *Cubic + + reno bool + + // Track the largest packet that has been sent. + largestSentPacketNumber protocol.PacketNumber + + // Track the largest packet that has been acked. + largestAckedPacketNumber protocol.PacketNumber + + // Track the largest packet number outstanding when a CWND cutback occurs. + largestSentAtLastCutback protocol.PacketNumber + + // Whether the last loss event caused us to exit slowstart. + // Used for stats collection of slowstartPacketsLost + lastCutbackExitedSlowstart bool + + // When true, exit slow start with large cutback of congestion window. + slowStartLargeReduction bool + + // Congestion window in packets. + congestionWindow protocol.ByteCount + + // Minimum congestion window in packets. + minCongestionWindow protocol.ByteCount + + // Maximum congestion window. + maxCongestionWindow protocol.ByteCount + + // Slow start congestion window in bytes, aka ssthresh. + slowstartThreshold protocol.ByteCount + + // Number of connections to simulate. + numConnections int + + // ACK counter for the Reno implementation. + numAckedPackets uint64 + + initialCongestionWindow protocol.ByteCount + initialMaxCongestionWindow protocol.ByteCount + + minSlowStartExitWindow protocol.ByteCount +} + +var _ SendAlgorithm = &cubicSender{} +var _ SendAlgorithmWithDebugInfo = &cubicSender{} + +// NewCubicSender makes a new cubic sender +func NewCubicSender(clock Clock, rttStats *RTTStats, reno bool, initialCongestionWindow, initialMaxCongestionWindow protocol.ByteCount) SendAlgorithmWithDebugInfo { + return &cubicSender{ + rttStats: rttStats, + initialCongestionWindow: initialCongestionWindow, + initialMaxCongestionWindow: initialMaxCongestionWindow, + congestionWindow: initialCongestionWindow, + minCongestionWindow: defaultMinimumCongestionWindow, + slowstartThreshold: initialMaxCongestionWindow, + maxCongestionWindow: initialMaxCongestionWindow, + numConnections: defaultNumConnections, + cubic: NewCubic(clock), + reno: reno, + } +} + +// TimeUntilSend returns when the next packet should be sent. +func (c *cubicSender) TimeUntilSend(bytesInFlight protocol.ByteCount) time.Duration { + if c.InRecovery() { + // PRR is used when in recovery. + if c.prr.CanSend(c.GetCongestionWindow(), bytesInFlight, c.GetSlowStartThreshold()) { + return 0 + } + } + return c.rttStats.SmoothedRTT() * time.Duration(protocol.DefaultTCPMSS) / time.Duration(2*c.GetCongestionWindow()) +} + +func (c *cubicSender) OnPacketSent( + sentTime time.Time, + bytesInFlight protocol.ByteCount, + packetNumber protocol.PacketNumber, + bytes protocol.ByteCount, + isRetransmittable bool, +) { + if !isRetransmittable { + return + } + if c.InRecovery() { + // PRR is used when in recovery. + c.prr.OnPacketSent(bytes) + } + c.largestSentPacketNumber = packetNumber + c.hybridSlowStart.OnPacketSent(packetNumber) +} + +func (c *cubicSender) InRecovery() bool { + return c.largestAckedPacketNumber <= c.largestSentAtLastCutback && c.largestAckedPacketNumber != 0 +} + +func (c *cubicSender) InSlowStart() bool { + return c.GetCongestionWindow() < c.GetSlowStartThreshold() +} + +func (c *cubicSender) GetCongestionWindow() protocol.ByteCount { + return c.congestionWindow +} + +func (c *cubicSender) GetSlowStartThreshold() protocol.ByteCount { + return c.slowstartThreshold +} + +func (c *cubicSender) ExitSlowstart() { + c.slowstartThreshold = c.congestionWindow +} + +func (c *cubicSender) SlowstartThreshold() protocol.ByteCount { + return c.slowstartThreshold +} + +func (c *cubicSender) MaybeExitSlowStart() { + if c.InSlowStart() && c.hybridSlowStart.ShouldExitSlowStart(c.rttStats.LatestRTT(), c.rttStats.MinRTT(), c.GetCongestionWindow()/protocol.DefaultTCPMSS) { + c.ExitSlowstart() + } +} + +func (c *cubicSender) OnPacketAcked( + ackedPacketNumber protocol.PacketNumber, + ackedBytes protocol.ByteCount, + priorInFlight protocol.ByteCount, + eventTime time.Time, +) { + c.largestAckedPacketNumber = utils.MaxPacketNumber(ackedPacketNumber, c.largestAckedPacketNumber) + if c.InRecovery() { + // PRR is used when in recovery. + c.prr.OnPacketAcked(ackedBytes) + return + } + c.maybeIncreaseCwnd(ackedPacketNumber, ackedBytes, priorInFlight, eventTime) + if c.InSlowStart() { + c.hybridSlowStart.OnPacketAcked(ackedPacketNumber) + } +} + +func (c *cubicSender) OnPacketLost( + packetNumber protocol.PacketNumber, + lostBytes protocol.ByteCount, + priorInFlight protocol.ByteCount, +) { + // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets + // already sent should be treated as a single loss event, since it's expected. + if packetNumber <= c.largestSentAtLastCutback { + if c.lastCutbackExitedSlowstart { + c.stats.slowstartPacketsLost++ + c.stats.slowstartBytesLost += lostBytes + if c.slowStartLargeReduction { + // Reduce congestion window by lost_bytes for every loss. + c.congestionWindow = utils.MaxByteCount(c.congestionWindow-lostBytes, c.minSlowStartExitWindow) + c.slowstartThreshold = c.congestionWindow + } + } + return + } + c.lastCutbackExitedSlowstart = c.InSlowStart() + if c.InSlowStart() { + c.stats.slowstartPacketsLost++ + } + + c.prr.OnPacketLost(priorInFlight) + + // TODO(chromium): Separate out all of slow start into a separate class. + if c.slowStartLargeReduction && c.InSlowStart() { + if c.congestionWindow >= 2*c.initialCongestionWindow { + c.minSlowStartExitWindow = c.congestionWindow / 2 + } + c.congestionWindow -= protocol.DefaultTCPMSS + } else if c.reno { + c.congestionWindow = protocol.ByteCount(float32(c.congestionWindow) * c.RenoBeta()) + } else { + c.congestionWindow = c.cubic.CongestionWindowAfterPacketLoss(c.congestionWindow) + } + if c.congestionWindow < c.minCongestionWindow { + c.congestionWindow = c.minCongestionWindow + } + c.slowstartThreshold = c.congestionWindow + c.largestSentAtLastCutback = c.largestSentPacketNumber + // reset packet count from congestion avoidance mode. We start + // counting again when we're out of recovery. + c.numAckedPackets = 0 +} + +func (c *cubicSender) RenoBeta() float32 { + // kNConnectionBeta is the backoff factor after loss for our N-connection + // emulation, which emulates the effective backoff of an ensemble of N + // TCP-Reno connections on a single loss event. The effective multiplier is + // computed as: + return (float32(c.numConnections) - 1. + renoBeta) / float32(c.numConnections) +} + +// Called when we receive an ack. Normal TCP tracks how many packets one ack +// represents, but quic has a separate ack for each packet. +func (c *cubicSender) maybeIncreaseCwnd( + ackedPacketNumber protocol.PacketNumber, + ackedBytes protocol.ByteCount, + priorInFlight protocol.ByteCount, + eventTime time.Time, +) { + // Do not increase the congestion window unless the sender is close to using + // the current window. + if !c.isCwndLimited(priorInFlight) { + c.cubic.OnApplicationLimited() + return + } + if c.congestionWindow >= c.maxCongestionWindow { + return + } + if c.InSlowStart() { + // TCP slow start, exponential growth, increase by one for each ACK. + c.congestionWindow += protocol.DefaultTCPMSS + return + } + // Congestion avoidance + if c.reno { + // Classic Reno congestion avoidance. + c.numAckedPackets++ + // Divide by num_connections to smoothly increase the CWND at a faster + // rate than conventional Reno. + if c.numAckedPackets*uint64(c.numConnections) >= uint64(c.congestionWindow)/uint64(protocol.DefaultTCPMSS) { + c.congestionWindow += protocol.DefaultTCPMSS + c.numAckedPackets = 0 + } + } else { + c.congestionWindow = utils.MinByteCount(c.maxCongestionWindow, c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) + } +} + +func (c *cubicSender) isCwndLimited(bytesInFlight protocol.ByteCount) bool { + congestionWindow := c.GetCongestionWindow() + if bytesInFlight >= congestionWindow { + return true + } + availableBytes := congestionWindow - bytesInFlight + slowStartLimited := c.InSlowStart() && bytesInFlight > congestionWindow/2 + return slowStartLimited || availableBytes <= maxBurstBytes +} + +// BandwidthEstimate returns the current bandwidth estimate +func (c *cubicSender) BandwidthEstimate() Bandwidth { + srtt := c.rttStats.SmoothedRTT() + if srtt == 0 { + // If we haven't measured an rtt, the bandwidth estimate is unknown. + return 0 + } + return BandwidthFromDelta(c.GetCongestionWindow(), srtt) +} + +// HybridSlowStart returns the hybrid slow start instance for testing +func (c *cubicSender) HybridSlowStart() *HybridSlowStart { + return &c.hybridSlowStart +} + +// SetNumEmulatedConnections sets the number of emulated connections +func (c *cubicSender) SetNumEmulatedConnections(n int) { + c.numConnections = utils.Max(n, 1) + c.cubic.SetNumConnections(c.numConnections) +} + +// OnRetransmissionTimeout is called on an retransmission timeout +func (c *cubicSender) OnRetransmissionTimeout(packetsRetransmitted bool) { + c.largestSentAtLastCutback = 0 + if !packetsRetransmitted { + return + } + c.hybridSlowStart.Restart() + c.cubic.Reset() + c.slowstartThreshold = c.congestionWindow / 2 + c.congestionWindow = c.minCongestionWindow +} + +// OnConnectionMigration is called when the connection is migrated (?) +func (c *cubicSender) OnConnectionMigration() { + c.hybridSlowStart.Restart() + c.prr = PrrSender{} + c.largestSentPacketNumber = 0 + c.largestAckedPacketNumber = 0 + c.largestSentAtLastCutback = 0 + c.lastCutbackExitedSlowstart = false + c.cubic.Reset() + c.numAckedPackets = 0 + c.congestionWindow = c.initialCongestionWindow + c.slowstartThreshold = c.initialMaxCongestionWindow + c.maxCongestionWindow = c.initialMaxCongestionWindow +} + +// SetSlowStartLargeReduction allows enabling the SSLR experiment +func (c *cubicSender) SetSlowStartLargeReduction(enabled bool) { + c.slowStartLargeReduction = enabled +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go new file mode 100644 index 00000000..f41c1e5c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go @@ -0,0 +1,111 @@ +package congestion + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// Note(pwestin): the magic clamping numbers come from the original code in +// tcp_cubic.c. +const hybridStartLowWindow = protocol.ByteCount(16) + +// Number of delay samples for detecting the increase of delay. +const hybridStartMinSamples = uint32(8) + +// Exit slow start if the min rtt has increased by more than 1/8th. +const hybridStartDelayFactorExp = 3 // 2^3 = 8 +// The original paper specifies 2 and 8ms, but those have changed over time. +const hybridStartDelayMinThresholdUs = int64(4000) +const hybridStartDelayMaxThresholdUs = int64(16000) + +// HybridSlowStart implements the TCP hybrid slow start algorithm +type HybridSlowStart struct { + endPacketNumber protocol.PacketNumber + lastSentPacketNumber protocol.PacketNumber + started bool + currentMinRTT time.Duration + rttSampleCount uint32 + hystartFound bool +} + +// StartReceiveRound is called for the start of each receive round (burst) in the slow start phase. +func (s *HybridSlowStart) StartReceiveRound(lastSent protocol.PacketNumber) { + s.endPacketNumber = lastSent + s.currentMinRTT = 0 + s.rttSampleCount = 0 + s.started = true +} + +// IsEndOfRound returns true if this ack is the last packet number of our current slow start round. +func (s *HybridSlowStart) IsEndOfRound(ack protocol.PacketNumber) bool { + return s.endPacketNumber < ack +} + +// ShouldExitSlowStart should be called on every new ack frame, since a new +// RTT measurement can be made then. +// rtt: the RTT for this ack packet. +// minRTT: is the lowest delay (RTT) we have seen during the session. +// congestionWindow: the congestion window in packets. +func (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT time.Duration, congestionWindow protocol.ByteCount) bool { + if !s.started { + // Time to start the hybrid slow start. + s.StartReceiveRound(s.lastSentPacketNumber) + } + if s.hystartFound { + return true + } + // Second detection parameter - delay increase detection. + // Compare the minimum delay (s.currentMinRTT) of the current + // burst of packets relative to the minimum delay during the session. + // Note: we only look at the first few(8) packets in each burst, since we + // only want to compare the lowest RTT of the burst relative to previous + // bursts. + s.rttSampleCount++ + if s.rttSampleCount <= hybridStartMinSamples { + if s.currentMinRTT == 0 || s.currentMinRTT > latestRTT { + s.currentMinRTT = latestRTT + } + } + // We only need to check this once per round. + if s.rttSampleCount == hybridStartMinSamples { + // Divide minRTT by 8 to get a rtt increase threshold for exiting. + minRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp) + // Ensure the rtt threshold is never less than 2ms or more than 16ms. + minRTTincreaseThresholdUs = utils.MinInt64(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs) + minRTTincreaseThreshold := time.Duration(utils.MaxInt64(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond + + if s.currentMinRTT > (minRTT + minRTTincreaseThreshold) { + s.hystartFound = true + } + } + // Exit from slow start if the cwnd is greater than 16 and + // increasing delay is found. + return congestionWindow >= hybridStartLowWindow && s.hystartFound +} + +// OnPacketSent is called when a packet was sent +func (s *HybridSlowStart) OnPacketSent(packetNumber protocol.PacketNumber) { + s.lastSentPacketNumber = packetNumber +} + +// OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end +// the round when the final packet of the burst is received and start it on +// the next incoming ack. +func (s *HybridSlowStart) OnPacketAcked(ackedPacketNumber protocol.PacketNumber) { + if s.IsEndOfRound(ackedPacketNumber) { + s.started = false + } +} + +// Started returns true if started +func (s *HybridSlowStart) Started() bool { + return s.started +} + +// Restart the slow start phase +func (s *HybridSlowStart) Restart() { + s.started = false + s.hystartFound = false +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/interface.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/interface.go new file mode 100644 index 00000000..7c27da64 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/interface.go @@ -0,0 +1,36 @@ +package congestion + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A SendAlgorithm performs congestion control and calculates the congestion window +type SendAlgorithm interface { + TimeUntilSend(bytesInFlight protocol.ByteCount) time.Duration + OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) + GetCongestionWindow() protocol.ByteCount + MaybeExitSlowStart() + OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime time.Time) + OnPacketLost(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount) + SetNumEmulatedConnections(n int) + OnRetransmissionTimeout(packetsRetransmitted bool) + OnConnectionMigration() + + // Experiments + SetSlowStartLargeReduction(enabled bool) +} + +// SendAlgorithmWithDebugInfo adds some debug functions to SendAlgorithm +type SendAlgorithmWithDebugInfo interface { + SendAlgorithm + BandwidthEstimate() Bandwidth + + // Stuff only used in testing + + HybridSlowStart() *HybridSlowStart + SlowstartThreshold() protocol.ByteCount + RenoBeta() float32 + InRecovery() bool +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/prr_sender.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/prr_sender.go new file mode 100644 index 00000000..5c807d19 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/prr_sender.go @@ -0,0 +1,54 @@ +package congestion + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// PrrSender implements the Proportional Rate Reduction (PRR) per RFC 6937 +type PrrSender struct { + bytesSentSinceLoss protocol.ByteCount + bytesDeliveredSinceLoss protocol.ByteCount + ackCountSinceLoss protocol.ByteCount + bytesInFlightBeforeLoss protocol.ByteCount +} + +// OnPacketSent should be called after a packet was sent +func (p *PrrSender) OnPacketSent(sentBytes protocol.ByteCount) { + p.bytesSentSinceLoss += sentBytes +} + +// OnPacketLost should be called on the first loss that triggers a recovery +// period and all other methods in this class should only be called when in +// recovery. +func (p *PrrSender) OnPacketLost(priorInFlight protocol.ByteCount) { + p.bytesSentSinceLoss = 0 + p.bytesInFlightBeforeLoss = priorInFlight + p.bytesDeliveredSinceLoss = 0 + p.ackCountSinceLoss = 0 +} + +// OnPacketAcked should be called after a packet was acked +func (p *PrrSender) OnPacketAcked(ackedBytes protocol.ByteCount) { + p.bytesDeliveredSinceLoss += ackedBytes + p.ackCountSinceLoss++ +} + +// CanSend returns if packets can be sent +func (p *PrrSender) CanSend(congestionWindow, bytesInFlight, slowstartThreshold protocol.ByteCount) bool { + // Return QuicTime::Zero In order to ensure limited transmit always works. + if p.bytesSentSinceLoss == 0 || bytesInFlight < protocol.DefaultTCPMSS { + return true + } + if congestionWindow > bytesInFlight { + // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead + // of sending the entire available window. This prevents burst retransmits + // when more packets are lost than the CWND reduction. + // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS + return p.bytesDeliveredSinceLoss+p.ackCountSinceLoss*protocol.DefaultTCPMSS > p.bytesSentSinceLoss + } + // Implement Proportional Rate Reduction (RFC6937). + // Checks a simplified version of the PRR formula that doesn't use division: + // AvailableSendWindow = + // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent + return p.bytesDeliveredSinceLoss*slowstartThreshold > p.bytesSentSinceLoss*p.bytesInFlightBeforeLoss +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/rtt_stats.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/rtt_stats.go new file mode 100644 index 00000000..f0ebbb23 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/rtt_stats.go @@ -0,0 +1,101 @@ +package congestion + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/utils" +) + +const ( + rttAlpha float32 = 0.125 + oneMinusAlpha float32 = (1 - rttAlpha) + rttBeta float32 = 0.25 + oneMinusBeta float32 = (1 - rttBeta) + // The default RTT used before an RTT sample is taken. + defaultInitialRTT = 100 * time.Millisecond +) + +// RTTStats provides round-trip statistics +type RTTStats struct { + minRTT time.Duration + latestRTT time.Duration + smoothedRTT time.Duration + meanDeviation time.Duration +} + +// NewRTTStats makes a properly initialized RTTStats object +func NewRTTStats() *RTTStats { + return &RTTStats{} +} + +// MinRTT Returns the minRTT for the entire connection. +// May return Zero if no valid updates have occurred. +func (r *RTTStats) MinRTT() time.Duration { return r.minRTT } + +// LatestRTT returns the most recent rtt measurement. +// May return Zero if no valid updates have occurred. +func (r *RTTStats) LatestRTT() time.Duration { return r.latestRTT } + +// SmoothedRTT returns the EWMA smoothed RTT for the connection. +// May return Zero if no valid updates have occurred. +func (r *RTTStats) SmoothedRTT() time.Duration { return r.smoothedRTT } + +// SmoothedOrInitialRTT returns the EWMA smoothed RTT for the connection. +// If no valid updates have occurred, it returns the initial RTT. +func (r *RTTStats) SmoothedOrInitialRTT() time.Duration { + if r.smoothedRTT != 0 { + return r.smoothedRTT + } + return defaultInitialRTT +} + +// MeanDeviation gets the mean deviation +func (r *RTTStats) MeanDeviation() time.Duration { return r.meanDeviation } + +// UpdateRTT updates the RTT based on a new sample. +func (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration, now time.Time) { + if sendDelta == utils.InfDuration || sendDelta <= 0 { + return + } + + // Update r.minRTT first. r.minRTT does not use an rttSample corrected for + // ackDelay but the raw observed sendDelta, since poor clock granularity at + // the client may cause a high ackDelay to result in underestimation of the + // r.minRTT. + if r.minRTT == 0 || r.minRTT > sendDelta { + r.minRTT = sendDelta + } + + // Correct for ackDelay if information received from the peer results in a + // an RTT sample at least as large as minRTT. Otherwise, only use the + // sendDelta. + sample := sendDelta + if sample-r.minRTT >= ackDelay { + sample -= ackDelay + } + r.latestRTT = sample + // First time call. + if r.smoothedRTT == 0 { + r.smoothedRTT = sample + r.meanDeviation = sample / 2 + } else { + r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32(utils.AbsDuration(r.smoothedRTT-sample)/time.Microsecond)) * time.Microsecond + r.smoothedRTT = time.Duration((float32(r.smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond + } +} + +// OnConnectionMigration is called when connection migrates and rtt measurement needs to be reset. +func (r *RTTStats) OnConnectionMigration() { + r.latestRTT = 0 + r.minRTT = 0 + r.smoothedRTT = 0 + r.meanDeviation = 0 +} + +// ExpireSmoothedMetrics causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt +// is larger. The mean deviation is increased to the most recent deviation if +// it's larger. +func (r *RTTStats) ExpireSmoothedMetrics() { + r.meanDeviation = utils.MaxDuration(r.meanDeviation, utils.AbsDuration(r.smoothedRTT-r.latestRTT)) + r.smoothedRTT = utils.MaxDuration(r.smoothedRTT, r.latestRTT) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/stats.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/stats.go new file mode 100644 index 00000000..ed669c14 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/stats.go @@ -0,0 +1,8 @@ +package congestion + +import "github.com/lucas-clemente/quic-go/internal/protocol" + +type connectionStats struct { + slowstartPacketsLost protocol.PacketNumber + slowstartBytesLost protocol.ByteCount +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go new file mode 100644 index 00000000..6a0aa3c5 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go @@ -0,0 +1,122 @@ +package flowcontrol + +import ( + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +type baseFlowController struct { + // for sending data + bytesSent protocol.ByteCount + sendWindow protocol.ByteCount + lastBlockedAt protocol.ByteCount + + // for receiving data + mutex sync.RWMutex + bytesRead protocol.ByteCount + highestReceived protocol.ByteCount + receiveWindow protocol.ByteCount + receiveWindowSize protocol.ByteCount + maxReceiveWindowSize protocol.ByteCount + + epochStartTime time.Time + epochStartOffset protocol.ByteCount + rttStats *congestion.RTTStats + + logger utils.Logger +} + +// IsNewlyBlocked says if it is newly blocked by flow control. +// For every offset, it only returns true once. +// If it is blocked, the offset is returned. +func (c *baseFlowController) IsNewlyBlocked() (bool, protocol.ByteCount) { + if c.sendWindowSize() != 0 || c.sendWindow == c.lastBlockedAt { + return false, 0 + } + c.lastBlockedAt = c.sendWindow + return true, c.sendWindow +} + +func (c *baseFlowController) AddBytesSent(n protocol.ByteCount) { + c.bytesSent += n +} + +// UpdateSendWindow should be called after receiving a WindowUpdateFrame +// it returns true if the window was actually updated +func (c *baseFlowController) UpdateSendWindow(offset protocol.ByteCount) { + if offset > c.sendWindow { + c.sendWindow = offset + } +} + +func (c *baseFlowController) sendWindowSize() protocol.ByteCount { + // this only happens during connection establishment, when data is sent before we receive the peer's transport parameters + if c.bytesSent > c.sendWindow { + return 0 + } + return c.sendWindow - c.bytesSent +} + +func (c *baseFlowController) AddBytesRead(n protocol.ByteCount) { + c.mutex.Lock() + defer c.mutex.Unlock() + + // pretend we sent a WindowUpdate when reading the first byte + // this way auto-tuning of the window size already works for the first WindowUpdate + if c.bytesRead == 0 { + c.startNewAutoTuningEpoch() + } + c.bytesRead += n +} + +func (c *baseFlowController) hasWindowUpdate() bool { + bytesRemaining := c.receiveWindow - c.bytesRead + // update the window when more than the threshold was consumed + return bytesRemaining <= protocol.ByteCount((float64(c.receiveWindowSize) * float64((1 - protocol.WindowUpdateThreshold)))) +} + +// getWindowUpdate updates the receive window, if necessary +// it returns the new offset +func (c *baseFlowController) getWindowUpdate() protocol.ByteCount { + if !c.hasWindowUpdate() { + return 0 + } + + c.maybeAdjustWindowSize() + c.receiveWindow = c.bytesRead + c.receiveWindowSize + return c.receiveWindow +} + +// maybeAdjustWindowSize increases the receiveWindowSize if we're sending updates too often. +// For details about auto-tuning, see https://docs.google.com/document/d/1SExkMmGiz8VYzV3s9E35JQlJ73vhzCekKkDi85F1qCE/edit?usp=sharing. +func (c *baseFlowController) maybeAdjustWindowSize() { + bytesReadInEpoch := c.bytesRead - c.epochStartOffset + // don't do anything if less than half the window has been consumed + if bytesReadInEpoch <= c.receiveWindowSize/2 { + return + } + rtt := c.rttStats.SmoothedRTT() + if rtt == 0 { + return + } + + fraction := float64(bytesReadInEpoch) / float64(c.receiveWindowSize) + if time.Since(c.epochStartTime) < time.Duration(4*fraction*float64(rtt)) { + // window is consumed too fast, try to increase the window size + c.receiveWindowSize = utils.MinByteCount(2*c.receiveWindowSize, c.maxReceiveWindowSize) + } + c.startNewAutoTuningEpoch() +} + +func (c *baseFlowController) startNewAutoTuningEpoch() { + c.epochStartTime = time.Now() + c.epochStartOffset = c.bytesRead +} + +func (c *baseFlowController) checkFlowControlViolation() bool { + return c.highestReceived > c.receiveWindow +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go new file mode 100644 index 00000000..1393335b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go @@ -0,0 +1,92 @@ +package flowcontrol + +import ( + "fmt" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +type connectionFlowController struct { + baseFlowController + + queueWindowUpdate func() +} + +var _ ConnectionFlowController = &connectionFlowController{} + +// NewConnectionFlowController gets a new flow controller for the connection +// It is created before we receive the peer's transport paramenters, thus it starts with a sendWindow of 0. +func NewConnectionFlowController( + receiveWindow protocol.ByteCount, + maxReceiveWindow protocol.ByteCount, + queueWindowUpdate func(), + rttStats *congestion.RTTStats, + logger utils.Logger, +) ConnectionFlowController { + return &connectionFlowController{ + baseFlowController: baseFlowController{ + rttStats: rttStats, + receiveWindow: receiveWindow, + receiveWindowSize: receiveWindow, + maxReceiveWindowSize: maxReceiveWindow, + logger: logger, + }, + queueWindowUpdate: queueWindowUpdate, + } +} + +func (c *connectionFlowController) SendWindowSize() protocol.ByteCount { + return c.baseFlowController.sendWindowSize() +} + +// IncrementHighestReceived adds an increment to the highestReceived value +func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount) error { + c.mutex.Lock() + defer c.mutex.Unlock() + + c.highestReceived += increment + if c.checkFlowControlViolation() { + return qerr.Error(qerr.FlowControlError, fmt.Sprintf("Received %d bytes for the connection, allowed %d bytes", c.highestReceived, c.receiveWindow)) + } + return nil +} + +func (c *connectionFlowController) AddBytesRead(n protocol.ByteCount) { + c.baseFlowController.AddBytesRead(n) + c.maybeQueueWindowUpdate() +} + +func (c *connectionFlowController) maybeQueueWindowUpdate() { + c.mutex.Lock() + hasWindowUpdate := c.hasWindowUpdate() + c.mutex.Unlock() + if hasWindowUpdate { + c.queueWindowUpdate() + } +} + +func (c *connectionFlowController) GetWindowUpdate() protocol.ByteCount { + c.mutex.Lock() + oldWindowSize := c.receiveWindowSize + offset := c.baseFlowController.getWindowUpdate() + if oldWindowSize < c.receiveWindowSize { + c.logger.Debugf("Increasing receive flow control window for the connection to %d kB", c.receiveWindowSize/(1<<10)) + } + c.mutex.Unlock() + return offset +} + +// EnsureMinimumWindowSize sets a minimum window size +// it should make sure that the connection-level window is increased when a stream-level window grows +func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount) { + c.mutex.Lock() + if inc > c.receiveWindowSize { + c.logger.Debugf("Increasing receive flow control window for the connection to %d kB, in response to stream flow control window increase", c.receiveWindowSize/(1<<10)) + c.receiveWindowSize = utils.MinByteCount(inc, c.maxReceiveWindowSize) + c.startNewAutoTuningEpoch() + } + c.mutex.Unlock() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/interface.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/interface.go new file mode 100644 index 00000000..a47e7cd7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/interface.go @@ -0,0 +1,41 @@ +package flowcontrol + +import "github.com/lucas-clemente/quic-go/internal/protocol" + +type flowController interface { + // for sending + SendWindowSize() protocol.ByteCount + UpdateSendWindow(protocol.ByteCount) + AddBytesSent(protocol.ByteCount) + // for receiving + AddBytesRead(protocol.ByteCount) + GetWindowUpdate() protocol.ByteCount // returns 0 if no update is necessary + IsNewlyBlocked() (bool, protocol.ByteCount) +} + +// A StreamFlowController is a flow controller for a QUIC stream. +type StreamFlowController interface { + flowController + // for receiving + // UpdateHighestReceived should be called when a new highest offset is received + // final has to be to true if this is the final offset of the stream, + // as contained in a STREAM frame with FIN bit, and the RESET_STREAM frame + UpdateHighestReceived(offset protocol.ByteCount, final bool) error + // Abandon should be called when reading from the stream is aborted early, + // and there won't be any further calls to AddBytesRead. + Abandon() +} + +// The ConnectionFlowController is the flow controller for the connection. +type ConnectionFlowController interface { + flowController +} + +type connectionFlowControllerI interface { + ConnectionFlowController + // The following two methods are not supposed to be called from outside this packet, but are needed internally + // for sending + EnsureMinimumWindowSize(protocol.ByteCount) + // for receiving + IncrementHighestReceived(protocol.ByteCount) error +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go new file mode 100644 index 00000000..bb22337d --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go @@ -0,0 +1,139 @@ +package flowcontrol + +import ( + "fmt" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +type streamFlowController struct { + baseFlowController + + streamID protocol.StreamID + + queueWindowUpdate func() + + connection connectionFlowControllerI + + receivedFinalOffset bool +} + +var _ StreamFlowController = &streamFlowController{} + +// NewStreamFlowController gets a new flow controller for a stream +func NewStreamFlowController( + streamID protocol.StreamID, + cfc ConnectionFlowController, + receiveWindow protocol.ByteCount, + maxReceiveWindow protocol.ByteCount, + initialSendWindow protocol.ByteCount, + queueWindowUpdate func(protocol.StreamID), + rttStats *congestion.RTTStats, + logger utils.Logger, +) StreamFlowController { + return &streamFlowController{ + streamID: streamID, + connection: cfc.(connectionFlowControllerI), + queueWindowUpdate: func() { queueWindowUpdate(streamID) }, + baseFlowController: baseFlowController{ + rttStats: rttStats, + receiveWindow: receiveWindow, + receiveWindowSize: receiveWindow, + maxReceiveWindowSize: maxReceiveWindow, + sendWindow: initialSendWindow, + logger: logger, + }, + } +} + +// UpdateHighestReceived updates the highestReceived value, if the offset is higher. +func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool) error { + c.mutex.Lock() + defer c.mutex.Unlock() + + // If the final offset for this stream is already known, check for consistency. + if c.receivedFinalOffset { + // If we receive another final offset, check that it's the same. + if final && offset != c.highestReceived { + return qerr.Error(qerr.FinalSizeError, fmt.Sprintf("Received inconsistent final offset for stream %d (old: %#x, new: %#x bytes)", c.streamID, c.highestReceived, offset)) + } + // Check that the offset is below the final offset. + if offset > c.highestReceived { + return qerr.Error(qerr.FinalSizeError, fmt.Sprintf("Received offset %#x for stream %d. Final offset was already received at %#x", offset, c.streamID, c.highestReceived)) + } + } + + if final { + c.receivedFinalOffset = true + } + if offset == c.highestReceived { + return nil + } + // A higher offset was received before. + // This can happen due to reordering. + if offset <= c.highestReceived { + if final { + return qerr.Error(qerr.FinalSizeError, fmt.Sprintf("Received final offset %#x for stream %d, but already received offset %#x before", offset, c.streamID, c.highestReceived)) + } + return nil + } + + increment := offset - c.highestReceived + c.highestReceived = offset + if c.checkFlowControlViolation() { + return qerr.Error(qerr.FlowControlError, fmt.Sprintf("Received %#x bytes on stream %d, allowed %#x bytes", offset, c.streamID, c.receiveWindow)) + } + return c.connection.IncrementHighestReceived(increment) +} + +func (c *streamFlowController) AddBytesRead(n protocol.ByteCount) { + c.baseFlowController.AddBytesRead(n) + c.maybeQueueWindowUpdate() + c.connection.AddBytesRead(n) +} + +func (c *streamFlowController) Abandon() { + if unread := c.highestReceived - c.bytesRead; unread > 0 { + c.connection.AddBytesRead(unread) + } +} + +func (c *streamFlowController) AddBytesSent(n protocol.ByteCount) { + c.baseFlowController.AddBytesSent(n) + c.connection.AddBytesSent(n) +} + +func (c *streamFlowController) SendWindowSize() protocol.ByteCount { + return utils.MinByteCount(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize()) +} + +func (c *streamFlowController) maybeQueueWindowUpdate() { + c.mutex.Lock() + hasWindowUpdate := !c.receivedFinalOffset && c.hasWindowUpdate() + c.mutex.Unlock() + if hasWindowUpdate { + c.queueWindowUpdate() + } +} + +func (c *streamFlowController) GetWindowUpdate() protocol.ByteCount { + // don't use defer for unlocking the mutex here, GetWindowUpdate() is called frequently and defer shows up in the profiler + c.mutex.Lock() + // if we already received the final offset for this stream, the peer won't need any additional flow control credit + if c.receivedFinalOffset { + c.mutex.Unlock() + return 0 + } + + oldWindowSize := c.receiveWindowSize + offset := c.baseFlowController.getWindowUpdate() + if c.receiveWindowSize > oldWindowSize { // auto-tuning enlarged the window size + c.logger.Debugf("Increasing receive flow control window for stream %d to %d kB", c.streamID, c.receiveWindowSize/(1<<10)) + c.connection.EnsureMinimumWindowSize(protocol.ByteCount(float64(c.receiveWindowSize) * protocol.ConnectionFlowControlMultiplier)) + } + c.mutex.Unlock() + return offset +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go new file mode 100644 index 00000000..07ce74f7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go @@ -0,0 +1,104 @@ +package handshake + +import ( + "crypto/cipher" + "encoding/binary" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +type sealer struct { + aead cipher.AEAD + hpEncrypter cipher.Block + + // use a single slice to avoid allocations + nonceBuf []byte + hpMask []byte + + // short headers protect 5 bits in the first byte, long headers only 4 + is1RTT bool +} + +var _ Sealer = &sealer{} + +func newSealer(aead cipher.AEAD, hpEncrypter cipher.Block, is1RTT bool) Sealer { + return &sealer{ + aead: aead, + nonceBuf: make([]byte, aead.NonceSize()), + is1RTT: is1RTT, + hpEncrypter: hpEncrypter, + hpMask: make([]byte, hpEncrypter.BlockSize()), + } +} + +func (s *sealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte { + binary.BigEndian.PutUint64(s.nonceBuf[len(s.nonceBuf)-8:], uint64(pn)) + // The AEAD we're using here will be the qtls.aeadAESGCM13. + // It uses the nonce provided here and XOR it with the IV. + return s.aead.Seal(dst, s.nonceBuf, src, ad) +} + +func (s *sealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { + if len(sample) != s.hpEncrypter.BlockSize() { + panic("invalid sample size") + } + s.hpEncrypter.Encrypt(s.hpMask, sample) + if s.is1RTT { + *firstByte ^= s.hpMask[0] & 0x1f + } else { + *firstByte ^= s.hpMask[0] & 0xf + } + for i := range pnBytes { + pnBytes[i] ^= s.hpMask[i+1] + } +} + +func (s *sealer) Overhead() int { + return s.aead.Overhead() +} + +type opener struct { + aead cipher.AEAD + pnDecrypter cipher.Block + + // use a single slice to avoid allocations + nonceBuf []byte + hpMask []byte + + // short headers protect 5 bits in the first byte, long headers only 4 + is1RTT bool +} + +var _ Opener = &opener{} + +func newOpener(aead cipher.AEAD, pnDecrypter cipher.Block, is1RTT bool) Opener { + return &opener{ + aead: aead, + nonceBuf: make([]byte, aead.NonceSize()), + is1RTT: is1RTT, + pnDecrypter: pnDecrypter, + hpMask: make([]byte, pnDecrypter.BlockSize()), + } +} + +func (o *opener) Open(dst, src []byte, pn protocol.PacketNumber, ad []byte) ([]byte, error) { + binary.BigEndian.PutUint64(o.nonceBuf[len(o.nonceBuf)-8:], uint64(pn)) + // The AEAD we're using here will be the qtls.aeadAESGCM13. + // It uses the nonce provided here and XOR it with the IV. + return o.aead.Open(dst, o.nonceBuf, src, ad) +} + +func (o *opener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { + if len(sample) != o.pnDecrypter.BlockSize() { + panic("invalid sample size") + } + o.pnDecrypter.Encrypt(o.hpMask, sample) + if o.is1RTT { + *firstByte ^= o.hpMask[0] & 0x1f + } else { + *firstByte ^= o.hpMask[0] & 0xf + } + for i := range pnBytes { + pnBytes[i] ^= o.hpMask[i+1] + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_generator.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_generator.go new file mode 100644 index 00000000..6d1288ed --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_generator.go @@ -0,0 +1,109 @@ +package handshake + +import ( + "encoding/asn1" + "fmt" + "net" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +const ( + cookiePrefixIP byte = iota + cookiePrefixString +) + +// A Cookie is derived from the client address and can be used to verify the ownership of this address. +type Cookie struct { + RemoteAddr string + OriginalDestConnectionID protocol.ConnectionID + // The time that the Cookie was issued (resolution 1 second) + SentTime time.Time +} + +// token is the struct that is used for ASN1 serialization and deserialization +type token struct { + RemoteAddr []byte + OriginalDestConnectionID []byte + + Timestamp int64 +} + +// A CookieGenerator generates Cookies +type CookieGenerator struct { + cookieProtector cookieProtector +} + +// NewCookieGenerator initializes a new CookieGenerator +func NewCookieGenerator() (*CookieGenerator, error) { + cookieProtector, err := newCookieProtector() + if err != nil { + return nil, err + } + return &CookieGenerator{ + cookieProtector: cookieProtector, + }, nil +} + +// NewToken generates a new Cookie for a given source address +func (g *CookieGenerator) NewToken(raddr net.Addr, origConnID protocol.ConnectionID) ([]byte, error) { + data, err := asn1.Marshal(token{ + RemoteAddr: encodeRemoteAddr(raddr), + OriginalDestConnectionID: origConnID, + Timestamp: time.Now().Unix(), + }) + if err != nil { + return nil, err + } + return g.cookieProtector.NewToken(data) +} + +// DecodeToken decodes a Cookie +func (g *CookieGenerator) DecodeToken(encrypted []byte) (*Cookie, error) { + // if the client didn't send any Cookie, DecodeToken will be called with a nil-slice + if len(encrypted) == 0 { + return nil, nil + } + + data, err := g.cookieProtector.DecodeToken(encrypted) + if err != nil { + return nil, err + } + t := &token{} + rest, err := asn1.Unmarshal(data, t) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, fmt.Errorf("rest when unpacking token: %d", len(rest)) + } + cookie := &Cookie{ + RemoteAddr: decodeRemoteAddr(t.RemoteAddr), + SentTime: time.Unix(t.Timestamp, 0), + } + if len(t.OriginalDestConnectionID) > 0 { + cookie.OriginalDestConnectionID = protocol.ConnectionID(t.OriginalDestConnectionID) + } + return cookie, nil +} + +// encodeRemoteAddr encodes a remote address such that it can be saved in the Cookie +func encodeRemoteAddr(remoteAddr net.Addr) []byte { + if udpAddr, ok := remoteAddr.(*net.UDPAddr); ok { + return append([]byte{cookiePrefixIP}, udpAddr.IP...) + } + return append([]byte{cookiePrefixString}, []byte(remoteAddr.String())...) +} + +// decodeRemoteAddr decodes the remote address saved in the Cookie +func decodeRemoteAddr(data []byte) string { + // data will never be empty for a Cookie that we generated. Check it to be on the safe side + if len(data) == 0 { + return "" + } + if data[0] == cookiePrefixIP { + return net.IP(data[1:]).String() + } + return string(data[1:]) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_protector.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_protector.go new file mode 100644 index 00000000..7ebdfa18 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/cookie_protector.go @@ -0,0 +1,86 @@ +package handshake + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "fmt" + "io" + + "golang.org/x/crypto/hkdf" +) + +// CookieProtector is used to create and verify a cookie +type cookieProtector interface { + // NewToken creates a new token + NewToken([]byte) ([]byte, error) + // DecodeToken decodes a token + DecodeToken([]byte) ([]byte, error) +} + +const ( + cookieSecretSize = 32 + cookieNonceSize = 32 +) + +// cookieProtector is used to create and verify a cookie +type cookieProtectorImpl struct { + secret []byte +} + +// newCookieProtector creates a source for source address tokens +func newCookieProtector() (cookieProtector, error) { + secret := make([]byte, cookieSecretSize) + if _, err := rand.Read(secret); err != nil { + return nil, err + } + return &cookieProtectorImpl{secret: secret}, nil +} + +// NewToken encodes data into a new token. +func (s *cookieProtectorImpl) NewToken(data []byte) ([]byte, error) { + nonce := make([]byte, cookieNonceSize) + if _, err := rand.Read(nonce); err != nil { + return nil, err + } + aead, aeadNonce, err := s.createAEAD(nonce) + if err != nil { + return nil, err + } + return append(nonce, aead.Seal(nil, aeadNonce, data, nil)...), nil +} + +// DecodeToken decodes a token. +func (s *cookieProtectorImpl) DecodeToken(p []byte) ([]byte, error) { + if len(p) < cookieNonceSize { + return nil, fmt.Errorf("Token too short: %d", len(p)) + } + nonce := p[:cookieNonceSize] + aead, aeadNonce, err := s.createAEAD(nonce) + if err != nil { + return nil, err + } + return aead.Open(nil, aeadNonce, p[cookieNonceSize:], nil) +} + +func (s *cookieProtectorImpl) createAEAD(nonce []byte) (cipher.AEAD, []byte, error) { + h := hkdf.New(sha256.New, s.secret, nonce, []byte("quic-go cookie source")) + key := make([]byte, 32) // use a 32 byte key, in order to select AES-256 + if _, err := io.ReadFull(h, key); err != nil { + return nil, nil, err + } + aeadNonce := make([]byte, 12) + if _, err := io.ReadFull(h, aeadNonce); err != nil { + return nil, nil, err + } + c, err := aes.NewCipher(key) + if err != nil { + return nil, nil, err + } + aead, err := cipher.NewGCM(c) + if err != nil { + return nil, nil, err + } + return aead, aeadNonce, nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/crypto_setup.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/crypto_setup.go new file mode 100644 index 00000000..f153750c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/crypto_setup.go @@ -0,0 +1,584 @@ +package handshake + +import ( + "crypto/aes" + "crypto/tls" + "errors" + "fmt" + "io" + "net" + "sync" + "unsafe" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/marten-seemann/qtls" +) + +// TLS unexpected_message alert +const alertUnexpectedMessage uint8 = 10 + +type messageType uint8 + +// TLS handshake message types. +const ( + typeClientHello messageType = 1 + typeServerHello messageType = 2 + typeNewSessionTicket messageType = 4 + typeEncryptedExtensions messageType = 8 + typeCertificate messageType = 11 + typeCertificateRequest messageType = 13 + typeCertificateVerify messageType = 15 + typeFinished messageType = 20 +) + +func (m messageType) String() string { + switch m { + case typeClientHello: + return "ClientHello" + case typeServerHello: + return "ServerHello" + case typeNewSessionTicket: + return "NewSessionTicket" + case typeEncryptedExtensions: + return "EncryptedExtensions" + case typeCertificate: + return "Certificate" + case typeCertificateRequest: + return "CertificateRequest" + case typeCertificateVerify: + return "CertificateVerify" + case typeFinished: + return "Finished" + default: + return fmt.Sprintf("unknown message type: %d", m) + } +} + +// ErrOpenerNotYetAvailable is returned when an opener is requested for an encryption level, +// but the corresponding opener has not yet been initialized +// This can happen when packets arrive out of order. +var ErrOpenerNotYetAvailable = errors.New("CryptoSetup: opener at this encryption level not yet available") + +type cryptoSetup struct { + tlsConf *qtls.Config + conn *qtls.Conn + + messageChan chan []byte + + paramsChan <-chan []byte + handleParamsCallback func([]byte) + + alertChan chan uint8 + // HandleData() sends errors on the messageErrChan + messageErrChan chan error + // handshakeDone is closed as soon as the go routine running qtls.Handshake() returns + handshakeDone chan struct{} + // is closed when Close() is called + closeChan chan struct{} + + clientHelloWritten bool + clientHelloWrittenChan chan struct{} + + receivedWriteKey chan struct{} + receivedReadKey chan struct{} + // WriteRecord does a non-blocking send on this channel. + // This way, handleMessage can see if qtls tries to write a message. + // This is necessary: + // for servers: to see if a HelloRetryRequest should be sent in response to a ClientHello + // for clients: to see if a ServerHello is a HelloRetryRequest + writeRecord chan struct{} + + logger utils.Logger + + perspective protocol.Perspective + + mutex sync.Mutex // protects all members below + + readEncLevel protocol.EncryptionLevel + writeEncLevel protocol.EncryptionLevel + + initialStream io.Writer + initialOpener Opener + initialSealer Sealer + + handshakeStream io.Writer + handshakeOpener Opener + handshakeSealer Sealer + + oneRTTStream io.Writer + opener Opener + sealer Sealer +} + +var _ qtls.RecordLayer = &cryptoSetup{} +var _ CryptoSetup = &cryptoSetup{} + +// NewCryptoSetupClient creates a new crypto setup for the client +func NewCryptoSetupClient( + initialStream io.Writer, + handshakeStream io.Writer, + oneRTTStream io.Writer, + connID protocol.ConnectionID, + remoteAddr net.Addr, + tp *TransportParameters, + handleParams func([]byte), + tlsConf *tls.Config, + logger utils.Logger, +) (CryptoSetup, <-chan struct{} /* ClientHello written */, error) { + cs, clientHelloWritten, err := newCryptoSetup( + initialStream, + handshakeStream, + oneRTTStream, + connID, + tp, + handleParams, + tlsConf, + logger, + protocol.PerspectiveClient, + ) + if err != nil { + return nil, nil, err + } + cs.conn = qtls.Client(newConn(remoteAddr), cs.tlsConf) + return cs, clientHelloWritten, nil +} + +// NewCryptoSetupServer creates a new crypto setup for the server +func NewCryptoSetupServer( + initialStream io.Writer, + handshakeStream io.Writer, + oneRTTStream io.Writer, + connID protocol.ConnectionID, + remoteAddr net.Addr, + tp *TransportParameters, + handleParams func([]byte), + tlsConf *tls.Config, + logger utils.Logger, +) (CryptoSetup, error) { + cs, _, err := newCryptoSetup( + initialStream, + handshakeStream, + oneRTTStream, + connID, + tp, + handleParams, + tlsConf, + logger, + protocol.PerspectiveServer, + ) + if err != nil { + return nil, err + } + cs.conn = qtls.Server(newConn(remoteAddr), cs.tlsConf) + return cs, nil +} + +func newCryptoSetup( + initialStream io.Writer, + handshakeStream io.Writer, + oneRTTStream io.Writer, + connID protocol.ConnectionID, + tp *TransportParameters, + handleParams func([]byte), + tlsConf *tls.Config, + logger utils.Logger, + perspective protocol.Perspective, +) (*cryptoSetup, <-chan struct{} /* ClientHello written */, error) { + initialSealer, initialOpener, err := NewInitialAEAD(connID, perspective) + if err != nil { + return nil, nil, err + } + extHandler := newExtensionHandler(tp.Marshal(), perspective) + cs := &cryptoSetup{ + initialStream: initialStream, + initialSealer: initialSealer, + initialOpener: initialOpener, + handshakeStream: handshakeStream, + oneRTTStream: oneRTTStream, + readEncLevel: protocol.EncryptionInitial, + writeEncLevel: protocol.EncryptionInitial, + handleParamsCallback: handleParams, + paramsChan: extHandler.TransportParameters(), + logger: logger, + perspective: perspective, + handshakeDone: make(chan struct{}), + alertChan: make(chan uint8), + messageErrChan: make(chan error, 1), + clientHelloWrittenChan: make(chan struct{}), + messageChan: make(chan []byte, 100), + receivedReadKey: make(chan struct{}), + receivedWriteKey: make(chan struct{}), + writeRecord: make(chan struct{}, 1), + closeChan: make(chan struct{}), + } + qtlsConf := tlsConfigToQtlsConfig(tlsConf, cs, extHandler) + cs.tlsConf = qtlsConf + return cs, cs.clientHelloWrittenChan, nil +} + +func (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) error { + initialSealer, initialOpener, err := NewInitialAEAD(id, h.perspective) + if err != nil { + return err + } + h.initialSealer = initialSealer + h.initialOpener = initialOpener + return nil +} + +func (h *cryptoSetup) RunHandshake() error { + // Handle errors that might occur when HandleData() is called. + handshakeComplete := make(chan struct{}) + handshakeErrChan := make(chan error, 1) + go func() { + defer close(h.handshakeDone) + if err := h.conn.Handshake(); err != nil { + handshakeErrChan <- err + return + } + close(handshakeComplete) + }() + + select { + case <-h.closeChan: + close(h.messageChan) + // wait until the Handshake() go routine has returned + return errors.New("Handshake aborted") + case <-handshakeComplete: // return when the handshake is done + return nil + case alert := <-h.alertChan: + err := <-handshakeErrChan + return qerr.CryptoError(alert, err.Error()) + case err := <-h.messageErrChan: + // If the handshake errored because of an error that occurred during HandleData(), + // that error message will be more useful than the error message generated by Handshake(). + // Close the message chan that qtls is receiving messages from. + // This will make qtls.Handshake() return. + // Thereby the go routine running qtls.Handshake() will return. + close(h.messageChan) + return err + } +} + +func (h *cryptoSetup) Close() error { + close(h.closeChan) + // wait until qtls.Handshake() actually returned + <-h.handshakeDone + return nil +} + +// handleMessage handles a TLS handshake message. +// It is called by the crypto streams when a new message is available. +// It returns if it is done with messages on the same encryption level. +func (h *cryptoSetup) HandleMessage(data []byte, encLevel protocol.EncryptionLevel) bool /* stream finished */ { + msgType := messageType(data[0]) + h.logger.Debugf("Received %s message (%d bytes, encryption level: %s)", msgType, len(data), encLevel) + if err := h.checkEncryptionLevel(msgType, encLevel); err != nil { + h.messageErrChan <- err + return false + } + h.messageChan <- data + switch h.perspective { + case protocol.PerspectiveClient: + return h.handleMessageForClient(msgType) + case protocol.PerspectiveServer: + return h.handleMessageForServer(msgType) + default: + panic("") + } +} + +func (h *cryptoSetup) checkEncryptionLevel(msgType messageType, encLevel protocol.EncryptionLevel) error { + var expected protocol.EncryptionLevel + switch msgType { + case typeClientHello, + typeServerHello: + expected = protocol.EncryptionInitial + case typeEncryptedExtensions, + typeCertificate, + typeCertificateRequest, + typeCertificateVerify, + typeFinished: + expected = protocol.EncryptionHandshake + case typeNewSessionTicket: + expected = protocol.Encryption1RTT + default: + return qerr.CryptoError(alertUnexpectedMessage, fmt.Sprintf("unexpected handshake message: %d", msgType)) + } + if encLevel != expected { + return qerr.CryptoError(alertUnexpectedMessage, fmt.Sprintf("expected handshake message %s to have encryption level %s, has %s", msgType, expected, encLevel)) + } + return nil +} + +func (h *cryptoSetup) handleMessageForServer(msgType messageType) bool { + switch msgType { + case typeClientHello: + select { + case <-h.writeRecord: + // If qtls sends a HelloRetryRequest, it will only write the record. + // If it accepts the ClientHello, it will first read the transport parameters. + h.logger.Debugf("Sending HelloRetryRequest") + return false + case data := <-h.paramsChan: + h.handleParamsCallback(data) + case <-h.handshakeDone: + return false + } + // get the handshake read key + select { + case <-h.receivedReadKey: + case <-h.handshakeDone: + return false + } + // get the handshake write key + select { + case <-h.receivedWriteKey: + case <-h.handshakeDone: + return false + } + // get the 1-RTT write key + select { + case <-h.receivedWriteKey: + case <-h.handshakeDone: + return false + } + return true + case typeCertificate, typeCertificateVerify: + // nothing to do + return false + case typeFinished: + // get the 1-RTT read key + select { + case <-h.receivedReadKey: + case <-h.handshakeDone: + return false + } + return true + default: + h.messageErrChan <- qerr.CryptoError(alertUnexpectedMessage, fmt.Sprintf("unexpected handshake message: %d", msgType)) + return false + } +} + +func (h *cryptoSetup) handleMessageForClient(msgType messageType) bool { + switch msgType { + case typeServerHello: + // get the handshake write key + select { + case <-h.writeRecord: + // If qtls writes in response to a ServerHello, this means that this ServerHello + // is a HelloRetryRequest. + // Otherwise, we'd just wait for the Certificate message. + h.logger.Debugf("ServerHello is a HelloRetryRequest") + return false + case <-h.receivedWriteKey: + case <-h.handshakeDone: + return false + } + // get the handshake read key + select { + case <-h.receivedReadKey: + case <-h.handshakeDone: + return false + } + return true + case typeEncryptedExtensions: + select { + case data := <-h.paramsChan: + h.handleParamsCallback(data) + case <-h.handshakeDone: + return false + } + return false + case typeCertificateRequest, typeCertificate, typeCertificateVerify: + // nothing to do + return false + case typeFinished: + // get the 1-RTT read key + select { + case <-h.receivedReadKey: + case <-h.handshakeDone: + return false + } + // get the handshake write key + select { + case <-h.receivedWriteKey: + case <-h.handshakeDone: + return false + } + return true + case typeNewSessionTicket: + <-h.handshakeDone // don't process session tickets before the handshake has completed + h.conn.HandlePostHandshakeMessage() + return false + default: + h.messageErrChan <- qerr.CryptoError(alertUnexpectedMessage, fmt.Sprintf("unexpected handshake message: %d", msgType)) + return false + } +} + +// ReadHandshakeMessage is called by TLS. +// It blocks until a new handshake message is available. +func (h *cryptoSetup) ReadHandshakeMessage() ([]byte, error) { + msg, ok := <-h.messageChan + if !ok { + return nil, errors.New("error while handling the handshake message") + } + return msg, nil +} + +func (h *cryptoSetup) SetReadKey(suite *qtls.CipherSuite, trafficSecret []byte) { + key := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic key", suite.KeyLen()) + iv := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic iv", suite.IVLen()) + hpKey := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic hp", suite.KeyLen()) + hpDecrypter, err := aes.NewCipher(hpKey) + if err != nil { + panic(fmt.Sprintf("error creating new AES cipher: %s", err)) + } + + h.mutex.Lock() + switch h.readEncLevel { + case protocol.EncryptionInitial: + h.readEncLevel = protocol.EncryptionHandshake + h.handshakeOpener = newOpener(suite.AEAD(key, iv), hpDecrypter, false) + h.logger.Debugf("Installed Handshake Read keys") + case protocol.EncryptionHandshake: + h.readEncLevel = protocol.Encryption1RTT + h.opener = newOpener(suite.AEAD(key, iv), hpDecrypter, true) + h.logger.Debugf("Installed 1-RTT Read keys") + default: + panic("unexpected read encryption level") + } + h.mutex.Unlock() + h.receivedReadKey <- struct{}{} +} + +func (h *cryptoSetup) SetWriteKey(suite *qtls.CipherSuite, trafficSecret []byte) { + key := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic key", suite.KeyLen()) + iv := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic iv", suite.IVLen()) + hpKey := qtls.HkdfExpandLabel(suite.Hash(), trafficSecret, []byte{}, "quic hp", suite.KeyLen()) + hpEncrypter, err := aes.NewCipher(hpKey) + if err != nil { + panic(fmt.Sprintf("error creating new AES cipher: %s", err)) + } + + h.mutex.Lock() + switch h.writeEncLevel { + case protocol.EncryptionInitial: + h.writeEncLevel = protocol.EncryptionHandshake + h.handshakeSealer = newSealer(suite.AEAD(key, iv), hpEncrypter, false) + h.logger.Debugf("Installed Handshake Write keys") + case protocol.EncryptionHandshake: + h.writeEncLevel = protocol.Encryption1RTT + h.sealer = newSealer(suite.AEAD(key, iv), hpEncrypter, true) + h.logger.Debugf("Installed 1-RTT Write keys") + default: + panic("unexpected write encryption level") + } + h.mutex.Unlock() + h.receivedWriteKey <- struct{}{} +} + +// WriteRecord is called when TLS writes data +func (h *cryptoSetup) WriteRecord(p []byte) (int, error) { + h.mutex.Lock() + defer h.mutex.Unlock() + + switch h.writeEncLevel { + case protocol.EncryptionInitial: + // assume that the first WriteRecord call contains the ClientHello + n, err := h.initialStream.Write(p) + if !h.clientHelloWritten && h.perspective == protocol.PerspectiveClient { + h.clientHelloWritten = true + close(h.clientHelloWrittenChan) + } else { + // We need additional signaling to properly detect HelloRetryRequests. + // For servers: when the ServerHello is written. + // For clients: when a reply is sent in response to a ServerHello. + h.writeRecord <- struct{}{} + } + return n, err + case protocol.EncryptionHandshake: + return h.handshakeStream.Write(p) + case protocol.Encryption1RTT: + return h.oneRTTStream.Write(p) + default: + panic(fmt.Sprintf("unexpected write encryption level: %s", h.writeEncLevel)) + } +} + +func (h *cryptoSetup) SendAlert(alert uint8) { + h.alertChan <- alert +} + +func (h *cryptoSetup) GetSealer() (protocol.EncryptionLevel, Sealer) { + h.mutex.Lock() + defer h.mutex.Unlock() + + if h.sealer != nil { + return protocol.Encryption1RTT, h.sealer + } + if h.handshakeSealer != nil { + return protocol.EncryptionHandshake, h.handshakeSealer + } + return protocol.EncryptionInitial, h.initialSealer +} + +func (h *cryptoSetup) GetSealerWithEncryptionLevel(level protocol.EncryptionLevel) (Sealer, error) { + errNoSealer := fmt.Errorf("CryptoSetup: no sealer with encryption level %s", level.String()) + + h.mutex.Lock() + defer h.mutex.Unlock() + + switch level { + case protocol.EncryptionInitial: + return h.initialSealer, nil + case protocol.EncryptionHandshake: + if h.handshakeSealer == nil { + return nil, errNoSealer + } + return h.handshakeSealer, nil + case protocol.Encryption1RTT: + if h.sealer == nil { + return nil, errNoSealer + } + return h.sealer, nil + default: + return nil, errNoSealer + } +} + +func (h *cryptoSetup) GetOpener(level protocol.EncryptionLevel) (Opener, error) { + h.mutex.Lock() + defer h.mutex.Unlock() + + switch level { + case protocol.EncryptionInitial: + return h.initialOpener, nil + case protocol.EncryptionHandshake: + if h.handshakeOpener == nil { + return nil, ErrOpenerNotYetAvailable + } + return h.handshakeOpener, nil + case protocol.Encryption1RTT: + if h.opener == nil { + return nil, ErrOpenerNotYetAvailable + } + return h.opener, nil + default: + return nil, fmt.Errorf("CryptoSetup: no opener with encryption level %s", level) + } +} + +func (h *cryptoSetup) ConnectionState() tls.ConnectionState { + cs := h.conn.ConnectionState() + // h.conn is a qtls.Conn, which returns a qtls.ConnectionState. + // qtls.ConnectionState is identical to the tls.ConnectionState. + // It contains an unexported field which is used ExportKeyingMaterial(). + // The only way to return a tls.ConnectionState is to use unsafe. + // In unsafe.go we check that the two objects are actually identical. + return *(*tls.ConnectionState)(unsafe.Pointer(&cs)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/initial_aead.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/initial_aead.go new file mode 100644 index 00000000..5d78bbe2 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/initial_aead.go @@ -0,0 +1,52 @@ +package handshake + +import ( + "crypto" + "crypto/aes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/marten-seemann/qtls" +) + +var quicVersion1Salt = []byte{0xef, 0x4f, 0xb0, 0xab, 0xb4, 0x74, 0x70, 0xc4, 0x1b, 0xef, 0xcf, 0x80, 0x31, 0x33, 0x4f, 0xae, 0x48, 0x5e, 0x09, 0xa0} + +// NewInitialAEAD creates a new AEAD for Initial encryption / decryption. +func NewInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective) (Sealer, Opener, error) { + clientSecret, serverSecret := computeSecrets(connID) + var mySecret, otherSecret []byte + if pers == protocol.PerspectiveClient { + mySecret = clientSecret + otherSecret = serverSecret + } else { + mySecret = serverSecret + otherSecret = clientSecret + } + myKey, myHPKey, myIV := computeInitialKeyAndIV(mySecret) + otherKey, otherHPKey, otherIV := computeInitialKeyAndIV(otherSecret) + + encrypter := qtls.AEADAESGCMTLS13(myKey, myIV) + hpEncrypter, err := aes.NewCipher(myHPKey) + if err != nil { + return nil, nil, err + } + decrypter := qtls.AEADAESGCMTLS13(otherKey, otherIV) + hpDecrypter, err := aes.NewCipher(otherHPKey) + if err != nil { + return nil, nil, err + } + return newSealer(encrypter, hpEncrypter, false), newOpener(decrypter, hpDecrypter, false), nil +} + +func computeSecrets(connID protocol.ConnectionID) (clientSecret, serverSecret []byte) { + initialSecret := qtls.HkdfExtract(crypto.SHA256, connID, quicVersion1Salt) + clientSecret = qtls.HkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "client in", crypto.SHA256.Size()) + serverSecret = qtls.HkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, "server in", crypto.SHA256.Size()) + return +} + +func computeInitialKeyAndIV(secret []byte) (key, hpKey, iv []byte) { + key = qtls.HkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic key", 16) + hpKey = qtls.HkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic hp", 16) + iv = qtls.HkdfExpandLabel(crypto.SHA256, secret, []byte{}, "quic iv", 12) + return +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/interface.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/interface.go new file mode 100644 index 00000000..22522513 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/interface.go @@ -0,0 +1,52 @@ +package handshake + +import ( + "crypto/tls" + "crypto/x509" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/marten-seemann/qtls" +) + +// Opener opens a packet +type Opener interface { + Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) + DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) +} + +// Sealer seals a packet +type Sealer interface { + Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte + EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) + Overhead() int +} + +// A tlsExtensionHandler sends and received the QUIC TLS extension. +type tlsExtensionHandler interface { + GetExtensions(msgType uint8) []qtls.Extension + ReceivedExtensions(msgType uint8, exts []qtls.Extension) + TransportParameters() <-chan []byte +} + +// CryptoSetup handles the handshake and protecting / unprotecting packets +type CryptoSetup interface { + RunHandshake() error + io.Closer + ChangeConnectionID(protocol.ConnectionID) error + + HandleMessage([]byte, protocol.EncryptionLevel) bool + ConnectionState() tls.ConnectionState + + GetSealer() (protocol.EncryptionLevel, Sealer) + GetSealerWithEncryptionLevel(protocol.EncryptionLevel) (Sealer, error) + GetOpener(protocol.EncryptionLevel) (Opener, error) +} + +// ConnectionState records basic details about the QUIC connection. +// Warning: This API should not be considered stable and might change soon. +type ConnectionState struct { + HandshakeComplete bool // handshake is complete + ServerName string // server name requested by client, if any (server side only) + PeerCertificates []*x509.Certificate // certificate chain presented by remote peer +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/qtls.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/qtls.go new file mode 100644 index 00000000..8880d9cb --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/qtls.go @@ -0,0 +1,132 @@ +package handshake + +import ( + "crypto/tls" + "net" + "time" + "unsafe" + + "github.com/marten-seemann/qtls" +) + +type conn struct { + remoteAddr net.Addr +} + +func newConn(remote net.Addr) net.Conn { + return &conn{remoteAddr: remote} +} + +var _ net.Conn = &conn{} + +func (c *conn) Read([]byte) (int, error) { return 0, nil } +func (c *conn) Write([]byte) (int, error) { return 0, nil } +func (c *conn) Close() error { return nil } +func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr } +func (c *conn) LocalAddr() net.Addr { return nil } +func (c *conn) SetReadDeadline(time.Time) error { return nil } +func (c *conn) SetWriteDeadline(time.Time) error { return nil } +func (c *conn) SetDeadline(time.Time) error { return nil } + +type clientSessionCache struct { + tls.ClientSessionCache +} + +var _ qtls.ClientSessionCache = &clientSessionCache{} + +func (c *clientSessionCache) Get(sessionKey string) (*qtls.ClientSessionState, bool) { + sess, ok := c.ClientSessionCache.Get(sessionKey) + if sess == nil { + return nil, ok + } + // qtls.ClientSessionState is identical to the tls.ClientSessionState. + // In order to allow users of quic-go to use a tls.Config, + // we need this workaround to use the ClientSessionCache. + // In unsafe.go we check that the two structs are actually identical. + usess := (*[unsafe.Sizeof(*sess)]byte)(unsafe.Pointer(sess))[:] + var session qtls.ClientSessionState + usession := (*[unsafe.Sizeof(session)]byte)(unsafe.Pointer(&session))[:] + copy(usession, usess) + return &session, ok +} + +func (c *clientSessionCache) Put(sessionKey string, cs *qtls.ClientSessionState) { + // qtls.ClientSessionState is identical to the tls.ClientSessionState. + // In order to allow users of quic-go to use a tls.Config, + // we need this workaround to use the ClientSessionCache. + // In unsafe.go we check that the two structs are actually identical. + usess := (*[unsafe.Sizeof(*cs)]byte)(unsafe.Pointer(cs))[:] + var session tls.ClientSessionState + usession := (*[unsafe.Sizeof(session)]byte)(unsafe.Pointer(&session))[:] + copy(usession, usess) + c.ClientSessionCache.Put(sessionKey, &session) +} + +func tlsConfigToQtlsConfig( + c *tls.Config, + recordLayer qtls.RecordLayer, + extHandler tlsExtensionHandler, +) *qtls.Config { + if c == nil { + c = &tls.Config{} + } + // Clone the config first. This executes the tls.Config.serverInit(). + // This sets the SessionTicketKey, if the user didn't supply one. + c = c.Clone() + // QUIC requires TLS 1.3 or newer + minVersion := c.MinVersion + if minVersion < qtls.VersionTLS13 { + minVersion = qtls.VersionTLS13 + } + maxVersion := c.MaxVersion + if maxVersion < qtls.VersionTLS13 { + maxVersion = qtls.VersionTLS13 + } + var getConfigForClient func(ch *tls.ClientHelloInfo) (*qtls.Config, error) + if c.GetConfigForClient != nil { + getConfigForClient = func(ch *tls.ClientHelloInfo) (*qtls.Config, error) { + tlsConf, err := c.GetConfigForClient(ch) + if err != nil { + return nil, err + } + if tlsConf == nil { + return nil, nil + } + return tlsConfigToQtlsConfig(tlsConf, recordLayer, extHandler), nil + } + } + var csc qtls.ClientSessionCache + if c.ClientSessionCache != nil { + csc = &clientSessionCache{c.ClientSessionCache} + } + return &qtls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + GetClientCertificate: c.GetClientCertificate, + GetConfigForClient: getConfigForClient, + VerifyPeerCertificate: c.VerifyPeerCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: csc, + MinVersion: minVersion, + MaxVersion: maxVersion, + CurvePreferences: c.CurvePreferences, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + // no need to copy Renegotiation, it's not supported by TLS 1.3 + KeyLogWriter: c.KeyLogWriter, + AlternativeRecordLayer: recordLayer, + GetExtensions: extHandler.GetExtensions, + ReceivedExtensions: extHandler.ReceivedExtensions, + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/tls_extension_handler.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/tls_extension_handler.go new file mode 100644 index 00000000..590aafd1 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/tls_extension_handler.go @@ -0,0 +1,58 @@ +package handshake + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/marten-seemann/qtls" +) + +const quicTLSExtensionType = 0xffa5 + +type extensionHandler struct { + ourParams []byte + paramsChan chan []byte + + perspective protocol.Perspective +} + +var _ tlsExtensionHandler = &extensionHandler{} + +// newExtensionHandler creates a new extension handler +func newExtensionHandler(params []byte, pers protocol.Perspective) tlsExtensionHandler { + return &extensionHandler{ + ourParams: params, + paramsChan: make(chan []byte), + perspective: pers, + } +} + +func (h *extensionHandler) GetExtensions(msgType uint8) []qtls.Extension { + if (h.perspective == protocol.PerspectiveClient && messageType(msgType) != typeClientHello) || + (h.perspective == protocol.PerspectiveServer && messageType(msgType) != typeEncryptedExtensions) { + return nil + } + return []qtls.Extension{{ + Type: quicTLSExtensionType, + Data: h.ourParams, + }} +} + +func (h *extensionHandler) ReceivedExtensions(msgType uint8, exts []qtls.Extension) { + if (h.perspective == protocol.PerspectiveClient && messageType(msgType) != typeEncryptedExtensions) || + (h.perspective == protocol.PerspectiveServer && messageType(msgType) != typeClientHello) { + return + } + + var data []byte + for _, ext := range exts { + if ext.Type == quicTLSExtensionType { + data = ext.Data + break + } + } + + h.paramsChan <- data +} + +func (h *extensionHandler) TransportParameters() <-chan []byte { + return h.paramsChan +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go new file mode 100644 index 00000000..6810cbc3 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/transport_parameters.go @@ -0,0 +1,260 @@ +package handshake + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "sort" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +type transportParameterID uint16 + +const ( + originalConnectionIDParameterID transportParameterID = 0x0 + idleTimeoutParameterID transportParameterID = 0x1 + statelessResetTokenParameterID transportParameterID = 0x2 + maxPacketSizeParameterID transportParameterID = 0x3 + initialMaxDataParameterID transportParameterID = 0x4 + initialMaxStreamDataBidiLocalParameterID transportParameterID = 0x5 + initialMaxStreamDataBidiRemoteParameterID transportParameterID = 0x6 + initialMaxStreamDataUniParameterID transportParameterID = 0x7 + initialMaxStreamsBidiParameterID transportParameterID = 0x8 + initialMaxStreamsUniParameterID transportParameterID = 0x9 + ackDelayExponentParameterID transportParameterID = 0xa + disableMigrationParameterID transportParameterID = 0xc +) + +// TransportParameters are parameters sent to the peer during the handshake +type TransportParameters struct { + InitialMaxStreamDataBidiLocal protocol.ByteCount + InitialMaxStreamDataBidiRemote protocol.ByteCount + InitialMaxStreamDataUni protocol.ByteCount + InitialMaxData protocol.ByteCount + + AckDelayExponent uint8 + + MaxPacketSize protocol.ByteCount + + MaxUniStreams uint64 + MaxBidiStreams uint64 + + IdleTimeout time.Duration + DisableMigration bool + + StatelessResetToken *[16]byte + OriginalConnectionID protocol.ConnectionID +} + +// Unmarshal the transport parameters +func (p *TransportParameters) Unmarshal(data []byte, sentBy protocol.Perspective) error { + if len(data) < 2 { + return errors.New("transport parameter data too short") + } + length := binary.BigEndian.Uint16(data[:2]) + if len(data)-2 < int(length) { + return fmt.Errorf("expected transport parameters to be %d bytes long, have %d", length, len(data)-2) + } + + // needed to check that every parameter is only sent at most once + var parameterIDs []transportParameterID + + var readAckDelayExponent bool + + r := bytes.NewReader(data[2:]) + for r.Len() >= 4 { + paramIDInt, _ := utils.BigEndian.ReadUint16(r) + paramID := transportParameterID(paramIDInt) + paramLen, _ := utils.BigEndian.ReadUint16(r) + parameterIDs = append(parameterIDs, paramID) + switch paramID { + case ackDelayExponentParameterID: + readAckDelayExponent = true + fallthrough + case initialMaxStreamDataBidiLocalParameterID, + initialMaxStreamDataBidiRemoteParameterID, + initialMaxStreamDataUniParameterID, + initialMaxDataParameterID, + initialMaxStreamsBidiParameterID, + initialMaxStreamsUniParameterID, + idleTimeoutParameterID, + maxPacketSizeParameterID: + if err := p.readNumericTransportParameter(r, paramID, int(paramLen)); err != nil { + return err + } + default: + if r.Len() < int(paramLen) { + return fmt.Errorf("remaining length (%d) smaller than parameter length (%d)", r.Len(), paramLen) + } + switch paramID { + case disableMigrationParameterID: + if paramLen != 0 { + return fmt.Errorf("wrong length for disable_migration: %d (expected empty)", paramLen) + } + p.DisableMigration = true + case statelessResetTokenParameterID: + if sentBy == protocol.PerspectiveClient { + return errors.New("client sent a stateless_reset_token") + } + if paramLen != 16 { + return fmt.Errorf("wrong length for stateless_reset_token: %d (expected 16)", paramLen) + } + var token [16]byte + r.Read(token[:]) + p.StatelessResetToken = &token + case originalConnectionIDParameterID: + if sentBy == protocol.PerspectiveClient { + return errors.New("client sent an original_connection_id") + } + p.OriginalConnectionID, _ = protocol.ReadConnectionID(r, int(paramLen)) + default: + r.Seek(int64(paramLen), io.SeekCurrent) + } + } + } + + if !readAckDelayExponent { + p.AckDelayExponent = protocol.DefaultAckDelayExponent + } + + // check that every transport parameter was sent at most once + sort.Slice(parameterIDs, func(i, j int) bool { return parameterIDs[i] < parameterIDs[j] }) + for i := 0; i < len(parameterIDs)-1; i++ { + if parameterIDs[i] == parameterIDs[i+1] { + return fmt.Errorf("received duplicate transport parameter %#x", parameterIDs[i]) + } + } + + if r.Len() != 0 { + return fmt.Errorf("should have read all data. Still have %d bytes", r.Len()) + } + return nil +} + +func (p *TransportParameters) readNumericTransportParameter( + r *bytes.Reader, + paramID transportParameterID, + expectedLen int, +) error { + remainingLen := r.Len() + val, err := utils.ReadVarInt(r) + if err != nil { + return fmt.Errorf("error while reading transport parameter %d: %s", paramID, err) + } + if remainingLen-r.Len() != expectedLen { + return fmt.Errorf("inconsistent transport parameter length for %d", paramID) + } + switch paramID { + case initialMaxStreamDataBidiLocalParameterID: + p.InitialMaxStreamDataBidiLocal = protocol.ByteCount(val) + case initialMaxStreamDataBidiRemoteParameterID: + p.InitialMaxStreamDataBidiRemote = protocol.ByteCount(val) + case initialMaxStreamDataUniParameterID: + p.InitialMaxStreamDataUni = protocol.ByteCount(val) + case initialMaxDataParameterID: + p.InitialMaxData = protocol.ByteCount(val) + case initialMaxStreamsBidiParameterID: + p.MaxBidiStreams = val + case initialMaxStreamsUniParameterID: + p.MaxUniStreams = val + case idleTimeoutParameterID: + p.IdleTimeout = utils.MaxDuration(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond) + case maxPacketSizeParameterID: + if val < 1200 { + return fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", val) + } + p.MaxPacketSize = protocol.ByteCount(val) + case ackDelayExponentParameterID: + if val > protocol.MaxAckDelayExponent { + return fmt.Errorf("invalid value for ack_delay_exponent: %d (maximum %d)", val, protocol.MaxAckDelayExponent) + } + p.AckDelayExponent = uint8(val) + default: + return fmt.Errorf("TransportParameter BUG: transport parameter %d not found", paramID) + } + return nil +} + +// Marshal the transport parameters +func (p *TransportParameters) Marshal() []byte { + b := &bytes.Buffer{} + b.Write([]byte{0, 0}) // length. Will be replaced later + + // initial_max_stream_data_bidi_local + utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamDataBidiLocalParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.InitialMaxStreamDataBidiLocal)))) + utils.WriteVarInt(b, uint64(p.InitialMaxStreamDataBidiLocal)) + // initial_max_stream_data_bidi_remote + utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamDataBidiRemoteParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.InitialMaxStreamDataBidiRemote)))) + utils.WriteVarInt(b, uint64(p.InitialMaxStreamDataBidiRemote)) + // initial_max_stream_data_uni + utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamDataUniParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.InitialMaxStreamDataUni)))) + utils.WriteVarInt(b, uint64(p.InitialMaxStreamDataUni)) + // initial_max_data + utils.BigEndian.WriteUint16(b, uint16(initialMaxDataParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.InitialMaxData)))) + utils.WriteVarInt(b, uint64(p.InitialMaxData)) + // initial_max_bidi_streams + utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamsBidiParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(p.MaxBidiStreams))) + utils.WriteVarInt(b, p.MaxBidiStreams) + // initial_max_uni_streams + utils.BigEndian.WriteUint16(b, uint16(initialMaxStreamsUniParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(p.MaxUniStreams))) + utils.WriteVarInt(b, p.MaxUniStreams) + // idle_timeout + idleTimeout := uint64(p.IdleTimeout / time.Millisecond) + utils.BigEndian.WriteUint16(b, uint16(idleTimeoutParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(idleTimeout))) + utils.WriteVarInt(b, idleTimeout) + // max_packet_size + utils.BigEndian.WriteUint16(b, uint16(maxPacketSizeParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(protocol.MaxReceivePacketSize)))) + utils.WriteVarInt(b, uint64(protocol.MaxReceivePacketSize)) + // ack_delay_exponent + // Only send it if is different from the default value. + if p.AckDelayExponent != protocol.DefaultAckDelayExponent { + utils.BigEndian.WriteUint16(b, uint16(ackDelayExponentParameterID)) + utils.BigEndian.WriteUint16(b, uint16(utils.VarIntLen(uint64(p.AckDelayExponent)))) + utils.WriteVarInt(b, uint64(p.AckDelayExponent)) + } + // disable_migration + if p.DisableMigration { + utils.BigEndian.WriteUint16(b, uint16(disableMigrationParameterID)) + utils.BigEndian.WriteUint16(b, 0) + } + if p.StatelessResetToken != nil { + utils.BigEndian.WriteUint16(b, uint16(statelessResetTokenParameterID)) + utils.BigEndian.WriteUint16(b, 16) + b.Write(p.StatelessResetToken[:]) + } + // original_connection_id + if p.OriginalConnectionID.Len() > 0 { + utils.BigEndian.WriteUint16(b, uint16(originalConnectionIDParameterID)) + utils.BigEndian.WriteUint16(b, uint16(p.OriginalConnectionID.Len())) + b.Write(p.OriginalConnectionID.Bytes()) + } + + data := b.Bytes() + binary.BigEndian.PutUint16(data[:2], uint16(b.Len()-2)) + return data +} + +// String returns a string representation, intended for logging. +func (p *TransportParameters) String() string { + logString := "&handshake.TransportParameters{OriginalConnectionID: %s, InitialMaxStreamDataBidiLocal: %#x, InitialMaxStreamDataBidiRemote: %#x, InitialMaxStreamDataUni: %#x, InitialMaxData: %#x, MaxBidiStreams: %d, MaxUniStreams: %d, IdleTimeout: %s, AckDelayExponent: %d" + logParams := []interface{}{p.OriginalConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreams, p.MaxUniStreams, p.IdleTimeout, p.AckDelayExponent} + if p.StatelessResetToken != nil { // the client never sends a stateless reset token + logString += ", StatelessResetToken: %#x" + logParams = append(logParams, *p.StatelessResetToken) + } + logString += "}" + return fmt.Sprintf(logString, logParams...) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/unsafe.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/unsafe.go new file mode 100644 index 00000000..fb051aeb --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/unsafe.go @@ -0,0 +1,38 @@ +package handshake + +// This package uses unsafe to convert between: +// * qtls.ConnectionState and tls.ConnectionState +// * qtls.ClientSessionState and tls.ClientSessionState +// We check in init() that this conversion actually is safe. + +import ( + "crypto/tls" + "reflect" + + "github.com/marten-seemann/qtls" +) + +func init() { + if !structsEqual(&tls.ConnectionState{}, &qtls.ConnectionState{}) { + panic("qtls.ConnectionState not compatible with tls.ConnectionState") + } + if !structsEqual(&tls.ClientSessionState{}, &qtls.ClientSessionState{}) { + panic("qtls.ClientSessionState not compatible with tls.ClientSessionState") + } +} + +func structsEqual(a, b interface{}) bool { + sa := reflect.ValueOf(a).Elem() + sb := reflect.ValueOf(b).Elem() + if sa.NumField() != sb.NumField() { + return false + } + for i := 0; i < sa.NumField(); i++ { + fa := sa.Type().Field(i) + fb := sb.Type().Field(i) + if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) { + return false + } + } + return true +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go new file mode 100644 index 00000000..f99461b2 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go @@ -0,0 +1,69 @@ +package protocol + +import ( + "bytes" + "crypto/rand" + "fmt" + "io" +) + +// A ConnectionID in QUIC +type ConnectionID []byte + +const maxConnectionIDLen = 18 + +// GenerateConnectionID generates a connection ID using cryptographic random +func GenerateConnectionID(len int) (ConnectionID, error) { + b := make([]byte, len) + if _, err := rand.Read(b); err != nil { + return nil, err + } + return ConnectionID(b), nil +} + +// GenerateConnectionIDForInitial generates a connection ID for the Initial packet. +// It uses a length randomly chosen between 8 and 18 bytes. +func GenerateConnectionIDForInitial() (ConnectionID, error) { + r := make([]byte, 1) + if _, err := rand.Read(r); err != nil { + return nil, err + } + len := MinConnectionIDLenInitial + int(r[0])%(maxConnectionIDLen-MinConnectionIDLenInitial+1) + return GenerateConnectionID(len) +} + +// ReadConnectionID reads a connection ID of length len from the given io.Reader. +// It returns io.EOF if there are not enough bytes to read. +func ReadConnectionID(r io.Reader, len int) (ConnectionID, error) { + if len == 0 { + return nil, nil + } + c := make(ConnectionID, len) + _, err := io.ReadFull(r, c) + if err == io.ErrUnexpectedEOF { + return nil, io.EOF + } + return c, err +} + +// Equal says if two connection IDs are equal +func (c ConnectionID) Equal(other ConnectionID) bool { + return bytes.Equal(c, other) +} + +// Len returns the length of the connection ID in bytes +func (c ConnectionID) Len() int { + return len(c) +} + +// Bytes returns the byte representation +func (c ConnectionID) Bytes() []byte { + return []byte(c) +} + +func (c ConnectionID) String() string { + if c.Len() == 0 { + return "(empty)" + } + return fmt.Sprintf("%#x", c.Bytes()) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/encryption_level.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/encryption_level.go new file mode 100644 index 00000000..4b059b3a --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/encryption_level.go @@ -0,0 +1,28 @@ +package protocol + +// EncryptionLevel is the encryption level +// Default value is Unencrypted +type EncryptionLevel int + +const ( + // EncryptionUnspecified is a not specified encryption level + EncryptionUnspecified EncryptionLevel = iota + // EncryptionInitial is the Initial encryption level + EncryptionInitial + // EncryptionHandshake is the Handshake encryption level + EncryptionHandshake + // Encryption1RTT is the 1-RTT encryption level + Encryption1RTT +) + +func (e EncryptionLevel) String() string { + switch e { + case EncryptionInitial: + return "Initial" + case EncryptionHandshake: + return "Handshake" + case Encryption1RTT: + return "1-RTT" + } + return "unknown" +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/packet_number.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/packet_number.go new file mode 100644 index 00000000..405a07ac --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/packet_number.go @@ -0,0 +1,85 @@ +package protocol + +// PacketNumberLen is the length of the packet number in bytes +type PacketNumberLen uint8 + +const ( + // PacketNumberLenInvalid is the default value and not a valid length for a packet number + PacketNumberLenInvalid PacketNumberLen = 0 + // PacketNumberLen1 is a packet number length of 1 byte + PacketNumberLen1 PacketNumberLen = 1 + // PacketNumberLen2 is a packet number length of 2 bytes + PacketNumberLen2 PacketNumberLen = 2 + // PacketNumberLen3 is a packet number length of 3 bytes + PacketNumberLen3 PacketNumberLen = 3 + // PacketNumberLen4 is a packet number length of 4 bytes + PacketNumberLen4 PacketNumberLen = 4 +) + +// DecodePacketNumber calculates the packet number based on the received packet number, its length and the last seen packet number +func DecodePacketNumber( + packetNumberLength PacketNumberLen, + lastPacketNumber PacketNumber, + wirePacketNumber PacketNumber, +) PacketNumber { + var epochDelta PacketNumber + switch packetNumberLength { + case PacketNumberLen1: + epochDelta = PacketNumber(1) << 8 + case PacketNumberLen2: + epochDelta = PacketNumber(1) << 16 + case PacketNumberLen3: + epochDelta = PacketNumber(1) << 24 + case PacketNumberLen4: + epochDelta = PacketNumber(1) << 32 + } + epoch := lastPacketNumber & ^(epochDelta - 1) + prevEpochBegin := epoch - epochDelta + nextEpochBegin := epoch + epochDelta + return closestTo( + lastPacketNumber+1, + epoch+wirePacketNumber, + closestTo(lastPacketNumber+1, prevEpochBegin+wirePacketNumber, nextEpochBegin+wirePacketNumber), + ) +} + +func closestTo(target, a, b PacketNumber) PacketNumber { + if delta(target, a) < delta(target, b) { + return a + } + return b +} + +func delta(a, b PacketNumber) PacketNumber { + if a < b { + return b - a + } + return a - b +} + +// GetPacketNumberLengthForHeader gets the length of the packet number for the public header +// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances +func GetPacketNumberLengthForHeader(packetNumber, leastUnacked PacketNumber) PacketNumberLen { + diff := uint64(packetNumber - leastUnacked) + if diff < (1 << (16 - 1)) { + return PacketNumberLen2 + } + if diff < (1 << (24 - 1)) { + return PacketNumberLen3 + } + return PacketNumberLen4 +} + +// GetPacketNumberLength gets the minimum length needed to fully represent the packet number +func GetPacketNumberLength(packetNumber PacketNumber) PacketNumberLen { + if packetNumber < (1 << (uint8(PacketNumberLen1) * 8)) { + return PacketNumberLen1 + } + if packetNumber < (1 << (uint8(PacketNumberLen2) * 8)) { + return PacketNumberLen2 + } + if packetNumber < (1 << (uint8(PacketNumberLen3) * 8)) { + return PacketNumberLen3 + } + return PacketNumberLen4 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/params.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/params.go new file mode 100644 index 00000000..88e0ae45 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/params.go @@ -0,0 +1,126 @@ +package protocol + +import "time" + +// MaxPacketSizeIPv4 is the maximum packet size that we use for sending IPv4 packets. +const MaxPacketSizeIPv4 = 1252 + +// MaxPacketSizeIPv6 is the maximum packet size that we use for sending IPv6 packets. +const MaxPacketSizeIPv6 = 1232 + +const defaultMaxCongestionWindowPackets = 1000 + +// DefaultMaxCongestionWindow is the default for the max congestion window +const DefaultMaxCongestionWindow ByteCount = defaultMaxCongestionWindowPackets * DefaultTCPMSS + +// InitialCongestionWindow is the initial congestion window in QUIC packets +const InitialCongestionWindow ByteCount = 32 * DefaultTCPMSS + +// MaxUndecryptablePackets limits the number of undecryptable packets that are queued in the session. +const MaxUndecryptablePackets = 10 + +// ConnectionFlowControlMultiplier determines how much larger the connection flow control windows needs to be relative to any stream's flow control window +// This is the value that Chromium is using +const ConnectionFlowControlMultiplier = 1.5 + +// InitialMaxStreamData is the stream-level flow control window for receiving data +const InitialMaxStreamData = (1 << 10) * 512 // 512 kb + +// InitialMaxData is the connection-level flow control window for receiving data +const InitialMaxData = ConnectionFlowControlMultiplier * InitialMaxStreamData + +// DefaultMaxReceiveStreamFlowControlWindow is the default maximum stream-level flow control window for receiving data, for the server +const DefaultMaxReceiveStreamFlowControlWindow = 6 * (1 << 20) // 6 MB + +// DefaultMaxReceiveConnectionFlowControlWindow is the default connection-level flow control window for receiving data, for the server +const DefaultMaxReceiveConnectionFlowControlWindow = 15 * (1 << 20) // 12 MB + +// WindowUpdateThreshold is the fraction of the receive window that has to be consumed before an higher offset is advertised to the client +const WindowUpdateThreshold = 0.25 + +// DefaultMaxIncomingStreams is the maximum number of streams that a peer may open +const DefaultMaxIncomingStreams = 100 + +// DefaultMaxIncomingUniStreams is the maximum number of unidirectional streams that a peer may open +const DefaultMaxIncomingUniStreams = 100 + +// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed. +const MaxSessionUnprocessedPackets = defaultMaxCongestionWindowPackets + +// SkipPacketAveragePeriodLength is the average period length in which one packet number is skipped to prevent an Optimistic ACK attack +const SkipPacketAveragePeriodLength PacketNumber = 500 + +// MaxTrackedSkippedPackets is the maximum number of skipped packet numbers the SentPacketHandler keep track of for Optimistic ACK attack mitigation +const MaxTrackedSkippedPackets = 10 + +// MaxAcceptQueueSize is the maximum number of sessions that the server queues for accepting. +// If the queue is full, new connection attempts will be rejected. +const MaxAcceptQueueSize = 32 + +// CookieExpiryTime is the valid time of a cookie +const CookieExpiryTime = 24 * time.Hour + +// MaxOutstandingSentPackets is maximum number of packets saved for retransmission. +// When reached, it imposes a soft limit on sending new packets: +// Sending ACKs and retransmission is still allowed, but now new regular packets can be sent. +const MaxOutstandingSentPackets = 2 * defaultMaxCongestionWindowPackets + +// MaxTrackedSentPackets is maximum number of sent packets saved for retransmission. +// When reached, no more packets will be sent. +// This value *must* be larger than MaxOutstandingSentPackets. +const MaxTrackedSentPackets = MaxOutstandingSentPackets * 5 / 4 + +// MaxTrackedReceivedAckRanges is the maximum number of ACK ranges tracked +const MaxTrackedReceivedAckRanges = defaultMaxCongestionWindowPackets + +// MaxNonRetransmittableAcks is the maximum number of packets containing an ACK, but no retransmittable frames, that we send in a row +const MaxNonRetransmittableAcks = 19 + +// MaxStreamFrameSorterGaps is the maximum number of gaps between received StreamFrames +// prevents DoS attacks against the streamFrameSorter +const MaxStreamFrameSorterGaps = 1000 + +// MaxCryptoStreamOffset is the maximum offset allowed on any of the crypto streams. +// This limits the size of the ClientHello and Certificates that can be received. +const MaxCryptoStreamOffset = 16 * (1 << 10) + +// MinRemoteIdleTimeout is the minimum value that we accept for the remote idle timeout +const MinRemoteIdleTimeout = 5 * time.Second + +// DefaultIdleTimeout is the default idle timeout +const DefaultIdleTimeout = 30 * time.Second + +// DefaultHandshakeTimeout is the default timeout for a connection until the crypto handshake succeeds. +const DefaultHandshakeTimeout = 10 * time.Second + +// RetiredConnectionIDDeleteTimeout is the time we keep closed sessions around in order to retransmit the CONNECTION_CLOSE. +// after this time all information about the old connection will be deleted +const RetiredConnectionIDDeleteTimeout = 5 * time.Second + +// MinStreamFrameSize is the minimum size that has to be left in a packet, so that we add another STREAM frame. +// This avoids splitting up STREAM frames into small pieces, which has 2 advantages: +// 1. it reduces the framing overhead +// 2. it reduces the head-of-line blocking, when a packet is lost +const MinStreamFrameSize ByteCount = 128 + +// MaxPostHandshakeCryptoFrameSize is the maximum size of CRYPTO frames +// we send after the handshake completes. +const MaxPostHandshakeCryptoFrameSize ByteCount = 1000 + +// MaxAckFrameSize is the maximum size for an ACK frame that we write +// Due to the varint encoding, ACK frames can grow (almost) indefinitely large. +// The MaxAckFrameSize should be large enough to encode many ACK range, +// but must ensure that a maximum size ACK frame fits into one packet. +const MaxAckFrameSize ByteCount = 1000 + +// MinPacingDelay is the minimum duration that is used for packet pacing +// If the packet packing frequency is higher, multiple packets might be sent at once. +// Example: For a packet pacing delay of 20 microseconds, we would send 5 packets at once, wait for 100 microseconds, and so forth. +const MinPacingDelay time.Duration = 100 * time.Microsecond + +// DefaultConnectionIDLength is the connection ID length that is used for multiplexed connections +// if no other value is configured. +const DefaultConnectionIDLength = 4 + +// AckDelayExponent is the ack delay exponent used when sending ACKs. +const AckDelayExponent = 3 diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/perspective.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/perspective.go new file mode 100644 index 00000000..43358fec --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/perspective.go @@ -0,0 +1,26 @@ +package protocol + +// Perspective determines if we're acting as a server or a client +type Perspective int + +// the perspectives +const ( + PerspectiveServer Perspective = 1 + PerspectiveClient Perspective = 2 +) + +// Opposite returns the perspective of the peer +func (p Perspective) Opposite() Perspective { + return 3 - p +} + +func (p Perspective) String() string { + switch p { + case PerspectiveServer: + return "Server" + case PerspectiveClient: + return "Client" + default: + return "invalid perspective" + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go new file mode 100644 index 00000000..6e59afcb --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "fmt" +) + +// A PacketNumber in QUIC +type PacketNumber uint64 + +// The PacketType is the Long Header Type +type PacketType uint8 + +const ( + // PacketTypeInitial is the packet type of an Initial packet + PacketTypeInitial PacketType = 1 + iota + // PacketTypeRetry is the packet type of a Retry packet + PacketTypeRetry + // PacketTypeHandshake is the packet type of a Handshake packet + PacketTypeHandshake + // PacketType0RTT is the packet type of a 0-RTT packet + PacketType0RTT +) + +func (t PacketType) String() string { + switch t { + case PacketTypeInitial: + return "Initial" + case PacketTypeRetry: + return "Retry" + case PacketTypeHandshake: + return "Handshake" + case PacketType0RTT: + return "0-RTT Protected" + default: + return fmt.Sprintf("unknown packet type: %d", t) + } +} + +// A ByteCount in QUIC +type ByteCount uint64 + +// MaxByteCount is the maximum value of a ByteCount +const MaxByteCount = ByteCount(1<<62 - 1) + +// An ApplicationErrorCode is an application-defined error code. +type ApplicationErrorCode uint16 + +// MaxReceivePacketSize maximum packet size of any QUIC packet, based on +// ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header, +// UDP adds an additional 8 bytes. This is a total overhead of 48 bytes. +// Ethernet's max packet size is 1500 bytes, 1500 - 48 = 1452. +const MaxReceivePacketSize ByteCount = 1452 + +// DefaultTCPMSS is the default maximum packet size used in the Linux TCP implementation. +// Used in QUIC for congestion window computations in bytes. +const DefaultTCPMSS ByteCount = 1460 + +// MinInitialPacketSize is the minimum size an Initial packet is required to have. +const MinInitialPacketSize = 1200 + +// MinStatelessResetSize is the minimum size of a stateless reset packet +const MinStatelessResetSize = 1 /* first byte */ + 22 /* random bytes */ + 16 /* token */ + +// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet. +const MinConnectionIDLenInitial = 8 + +// MaxStreamCount is the maximum stream count value that can be sent in MAX_STREAMS frames +// and as the stream count in the transport parameters +const MaxStreamCount = 1 << 60 + +// DefaultAckDelayExponent is the default ack delay exponent +const DefaultAckDelayExponent = 3 + +// MaxAckDelayExponent is the maximum ack delay exponent +const MaxAckDelayExponent = 20 diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/stream_id.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/stream_id.go new file mode 100644 index 00000000..b96e0c2b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/stream_id.go @@ -0,0 +1,67 @@ +package protocol + +// A StreamID in QUIC +type StreamID uint64 + +// StreamType encodes if this is a unidirectional or bidirectional stream +type StreamType uint8 + +const ( + // StreamTypeUni is a unidirectional stream + StreamTypeUni StreamType = iota + // StreamTypeBidi is a bidirectional stream + StreamTypeBidi +) + +// InitiatedBy says if the stream was initiated by the client or by the server +func (s StreamID) InitiatedBy() Perspective { + if s%2 == 0 { + return PerspectiveClient + } + return PerspectiveServer +} + +//Type says if this is a unidirectional or bidirectional stream +func (s StreamID) Type() StreamType { + if s%4 >= 2 { + return StreamTypeUni + } + return StreamTypeBidi +} + +// StreamNum returns how many streams in total are below this +// Example: for stream 9 it returns 3 (i.e. streams 1, 5 and 9) +func (s StreamID) StreamNum() uint64 { + return uint64(s/4) + 1 +} + +// MaxStreamID is the highest stream ID that a peer is allowed to open, +// when it is allowed to open numStreams. +func MaxStreamID(stype StreamType, numStreams uint64, pers Perspective) StreamID { + if numStreams == 0 { + return 0 + } + var first StreamID + switch stype { + case StreamTypeBidi: + switch pers { + case PerspectiveClient: + first = 0 + case PerspectiveServer: + first = 1 + } + case StreamTypeUni: + switch pers { + case PerspectiveClient: + first = 2 + case PerspectiveServer: + first = 3 + } + } + return first + 4*StreamID(numStreams-1) +} + +// FirstStream returns the first valid stream ID +func FirstStream(stype StreamType, pers Perspective) StreamID { + return MaxStreamID(stype, 1, pers) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go new file mode 100644 index 00000000..410028b2 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/version.go @@ -0,0 +1,119 @@ +package protocol + +import ( + "crypto/rand" + "encoding/binary" + "fmt" + "math" +) + +// VersionNumber is a version number as int +type VersionNumber uint32 + +// gQUIC version range as defined in the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions +const ( + gquicVersion0 = 0x51303030 + maxGquicVersion = 0x51303439 +) + +// The version numbers, making grepping easier +const ( + VersionTLS VersionNumber = VersionMilestone0_11_2 + VersionWhatever VersionNumber = 1 // for when the version doesn't matter + VersionUnknown VersionNumber = math.MaxUint32 + + VersionMilestone0_11_2 VersionNumber = 0xff000013 // QUIC WG draft-19 +) + +// SupportedVersions lists the versions that the server supports +// must be in sorted descending order +var SupportedVersions = []VersionNumber{VersionMilestone0_11_2} + +// IsValidVersion says if the version is known to quic-go +func IsValidVersion(v VersionNumber) bool { + return v == VersionTLS || IsSupportedVersion(SupportedVersions, v) +} + +func (vn VersionNumber) String() string { + switch vn { + case VersionWhatever: + return "whatever" + case VersionUnknown: + return "unknown" + case VersionMilestone0_11_2: + return "QUIC WG draft-19" + default: + if vn.isGQUIC() { + return fmt.Sprintf("gQUIC %d", vn.toGQUICVersion()) + } + return fmt.Sprintf("%#x", uint32(vn)) + } +} + +// ToAltSvc returns the representation of the version for the H2 Alt-Svc parameters +func (vn VersionNumber) ToAltSvc() string { + return fmt.Sprintf("%d", vn) +} + +func (vn VersionNumber) isGQUIC() bool { + return vn > gquicVersion0 && vn <= maxGquicVersion +} + +func (vn VersionNumber) toGQUICVersion() int { + return int(10*(vn-gquicVersion0)/0x100) + int(vn%0x10) +} + +// IsSupportedVersion returns true if the server supports this version +func IsSupportedVersion(supported []VersionNumber, v VersionNumber) bool { + for _, t := range supported { + if t == v { + return true + } + } + return false +} + +// ChooseSupportedVersion finds the best version in the overlap of ours and theirs +// ours is a slice of versions that we support, sorted by our preference (descending) +// theirs is a slice of versions offered by the peer. The order does not matter. +// The bool returned indicates if a matching version was found. +func ChooseSupportedVersion(ours, theirs []VersionNumber) (VersionNumber, bool) { + for _, ourVer := range ours { + for _, theirVer := range theirs { + if ourVer == theirVer { + return ourVer, true + } + } + } + return 0, false +} + +// generateReservedVersion generates a reserved version number (v & 0x0f0f0f0f == 0x0a0a0a0a) +func generateReservedVersion() VersionNumber { + b := make([]byte, 4) + _, _ = rand.Read(b) // ignore the error here. Failure to read random data doesn't break anything + return VersionNumber((binary.BigEndian.Uint32(b) | 0x0a0a0a0a) & 0xfafafafa) +} + +// GetGreasedVersions adds one reserved version number to a slice of version numbers, at a random position +func GetGreasedVersions(supported []VersionNumber) []VersionNumber { + b := make([]byte, 1) + _, _ = rand.Read(b) // ignore the error here. Failure to read random data doesn't break anything + randPos := int(b[0]) % (len(supported) + 1) + greased := make([]VersionNumber, len(supported)+1) + copy(greased, supported[:randPos]) + greased[randPos] = generateReservedVersion() + copy(greased[randPos+1:], supported[randPos:]) + return greased +} + +// StripGreasedVersions strips all greased versions from a slice of versions +func StripGreasedVersions(versions []VersionNumber) []VersionNumber { + realVersions := make([]VersionNumber, 0, len(versions)) + for _, v := range versions { + if v&0x0f0f0f0f != 0x0a0a0a0a { + realVersions = append(realVersions, v) + } + } + return realVersions +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qerr/error_codes.go b/vendor/github.com/lucas-clemente/quic-go/internal/qerr/error_codes.go new file mode 100644 index 00000000..091de1ca --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qerr/error_codes.go @@ -0,0 +1,71 @@ +package qerr + +import ( + "fmt" + + "github.com/marten-seemann/qtls" +) + +// ErrorCode can be used as a normal error without reason. +type ErrorCode uint16 + +// The error codes defined by QUIC +const ( + NoError ErrorCode = 0x0 + InternalError ErrorCode = 0x1 + ServerBusy ErrorCode = 0x2 + FlowControlError ErrorCode = 0x3 + StreamLimitError ErrorCode = 0x4 + StreamStateError ErrorCode = 0x5 + FinalSizeError ErrorCode = 0x6 + FrameEncodingError ErrorCode = 0x7 + TransportParameterError ErrorCode = 0x8 + VersionNegotiationError ErrorCode = 0x9 + ProtocolViolation ErrorCode = 0xa + InvalidMigration ErrorCode = 0xc +) + +func (e ErrorCode) isCryptoError() bool { + return e >= 0x100 && e < 0x200 +} + +func (e ErrorCode) Error() string { + if e.isCryptoError() { + return fmt.Sprintf("%s: %s", e.String(), qtls.Alert(e-0x100).Error()) + } + return e.String() +} + +func (e ErrorCode) String() string { + switch e { + case NoError: + return "NO_ERROR" + case InternalError: + return "INTERNAL_ERROR" + case ServerBusy: + return "SERVER_BUSY" + case FlowControlError: + return "FLOW_CONTROL_ERROR" + case StreamLimitError: + return "STREAM_LIMIT_ERROR" + case StreamStateError: + return "STREAM_STATE_ERROR" + case FinalSizeError: + return "FINAL_SIZE_ERROR" + case FrameEncodingError: + return "FRAME_ENCODING_ERROR" + case TransportParameterError: + return "TRANSPORT_PARAMETER_ERROR" + case VersionNegotiationError: + return "VERSION_NEGOTIATION_ERROR" + case ProtocolViolation: + return "PROTOCOL_VIOLATION" + case InvalidMigration: + return "INVALID_MIGRATION" + default: + if e.isCryptoError() { + return "CRYPTO_ERROR" + } + return fmt.Sprintf("unknown error code: %#x", uint16(e)) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qerr/quic_error.go b/vendor/github.com/lucas-clemente/quic-go/internal/qerr/quic_error.go new file mode 100644 index 00000000..3a1718b0 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qerr/quic_error.go @@ -0,0 +1,73 @@ +package qerr + +import ( + "fmt" + "net" +) + +// A QuicError consists of an error code plus a error reason +type QuicError struct { + ErrorCode ErrorCode + ErrorMessage string + isTimeout bool +} + +var _ net.Error = &QuicError{} + +// Error creates a new QuicError instance +func Error(errorCode ErrorCode, errorMessage string) *QuicError { + return &QuicError{ + ErrorCode: errorCode, + ErrorMessage: errorMessage, + } +} + +// TimeoutError creates a new QuicError instance for a timeout error +func TimeoutError(errorMessage string) *QuicError { + return &QuicError{ + ErrorMessage: errorMessage, + isTimeout: true, + } +} + +// CryptoError create a new QuicError instance for a crypto error +func CryptoError(tlsAlert uint8, errorMessage string) *QuicError { + return &QuicError{ + ErrorCode: 0x100 + ErrorCode(tlsAlert), + ErrorMessage: errorMessage, + } +} + +func (e *QuicError) Error() string { + if len(e.ErrorMessage) == 0 { + return e.ErrorCode.Error() + } + return fmt.Sprintf("%s: %s", e.ErrorCode.String(), e.ErrorMessage) +} + +// IsCryptoError says if this error is a crypto error +func (e *QuicError) IsCryptoError() bool { + return e.ErrorCode.isCryptoError() +} + +// Temporary says if the error is temporary. +func (e *QuicError) Temporary() bool { + return false +} + +// Timeout says if this error is a timeout. +func (e *QuicError) Timeout() bool { + return e.isTimeout +} + +// ToQuicError converts an arbitrary error to a QuicError. It leaves QuicErrors +// unchanged, and properly handles `ErrorCode`s. +func ToQuicError(err error) *QuicError { + switch e := err.(type) { + case *QuicError: + return e + case ErrorCode: + return Error(e, "") + } + return Error(InternalError, err.Error()) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/atomic_bool.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/atomic_bool.go new file mode 100644 index 00000000..cf464250 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/atomic_bool.go @@ -0,0 +1,22 @@ +package utils + +import "sync/atomic" + +// An AtomicBool is an atomic bool +type AtomicBool struct { + v int32 +} + +// Set sets the value +func (a *AtomicBool) Set(value bool) { + var n int32 + if value { + n = 1 + } + atomic.StoreInt32(&a.v, n) +} + +// Get gets the value +func (a *AtomicBool) Get() bool { + return atomic.LoadInt32(&a.v) != 0 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go new file mode 100644 index 00000000..096023ef --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go @@ -0,0 +1,217 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package utils + +// Linked list implementation from the Go standard library. + +// ByteIntervalElement is an element of a linked list. +type ByteIntervalElement struct { + // Next and previous pointers in the doubly-linked list of elements. + // To simplify the implementation, internally a list l is implemented + // as a ring, such that &l.root is both the next element of the last + // list element (l.Back()) and the previous element of the first list + // element (l.Front()). + next, prev *ByteIntervalElement + + // The list to which this element belongs. + list *ByteIntervalList + + // The value stored with this element. + Value ByteInterval +} + +// Next returns the next list element or nil. +func (e *ByteIntervalElement) Next() *ByteIntervalElement { + if p := e.next; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// Prev returns the previous list element or nil. +func (e *ByteIntervalElement) Prev() *ByteIntervalElement { + if p := e.prev; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// ByteIntervalList is a linked list of ByteIntervals. +type ByteIntervalList struct { + root ByteIntervalElement // sentinel list element, only &root, root.prev, and root.next are used + len int // current list length excluding (this) sentinel element +} + +// Init initializes or clears list l. +func (l *ByteIntervalList) Init() *ByteIntervalList { + l.root.next = &l.root + l.root.prev = &l.root + l.len = 0 + return l +} + +// NewByteIntervalList returns an initialized list. +func NewByteIntervalList() *ByteIntervalList { return new(ByteIntervalList).Init() } + +// Len returns the number of elements of list l. +// The complexity is O(1). +func (l *ByteIntervalList) Len() int { return l.len } + +// Front returns the first element of list l or nil if the list is empty. +func (l *ByteIntervalList) Front() *ByteIntervalElement { + if l.len == 0 { + return nil + } + return l.root.next +} + +// Back returns the last element of list l or nil if the list is empty. +func (l *ByteIntervalList) Back() *ByteIntervalElement { + if l.len == 0 { + return nil + } + return l.root.prev +} + +// lazyInit lazily initializes a zero List value. +func (l *ByteIntervalList) lazyInit() { + if l.root.next == nil { + l.Init() + } +} + +// insert inserts e after at, increments l.len, and returns e. +func (l *ByteIntervalList) insert(e, at *ByteIntervalElement) *ByteIntervalElement { + n := at.next + at.next = e + e.prev = at + e.next = n + n.prev = e + e.list = l + l.len++ + return e +} + +// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). +func (l *ByteIntervalList) insertValue(v ByteInterval, at *ByteIntervalElement) *ByteIntervalElement { + return l.insert(&ByteIntervalElement{Value: v}, at) +} + +// remove removes e from its list, decrements l.len, and returns e. +func (l *ByteIntervalList) remove(e *ByteIntervalElement) *ByteIntervalElement { + e.prev.next = e.next + e.next.prev = e.prev + e.next = nil // avoid memory leaks + e.prev = nil // avoid memory leaks + e.list = nil + l.len-- + return e +} + +// Remove removes e from l if e is an element of list l. +// It returns the element value e.Value. +// The element must not be nil. +func (l *ByteIntervalList) Remove(e *ByteIntervalElement) ByteInterval { + if e.list == l { + // if e.list == l, l must have been initialized when e was inserted + // in l or l == nil (e is a zero Element) and l.remove will crash + l.remove(e) + } + return e.Value +} + +// PushFront inserts a new element e with value v at the front of list l and returns e. +func (l *ByteIntervalList) PushFront(v ByteInterval) *ByteIntervalElement { + l.lazyInit() + return l.insertValue(v, &l.root) +} + +// PushBack inserts a new element e with value v at the back of list l and returns e. +func (l *ByteIntervalList) PushBack(v ByteInterval) *ByteIntervalElement { + l.lazyInit() + return l.insertValue(v, l.root.prev) +} + +// InsertBefore inserts a new element e with value v immediately before mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *ByteIntervalList) InsertBefore(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark.prev) +} + +// InsertAfter inserts a new element e with value v immediately after mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *ByteIntervalList) InsertAfter(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark) +} + +// MoveToFront moves element e to the front of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *ByteIntervalList) MoveToFront(e *ByteIntervalElement) { + if e.list != l || l.root.next == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), &l.root) +} + +// MoveToBack moves element e to the back of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *ByteIntervalList) MoveToBack(e *ByteIntervalElement) { + if e.list != l || l.root.prev == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), l.root.prev) +} + +// MoveBefore moves element e to its new position before mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *ByteIntervalList) MoveBefore(e, mark *ByteIntervalElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark.prev) +} + +// MoveAfter moves element e to its new position after mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *ByteIntervalList) MoveAfter(e, mark *ByteIntervalElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark) +} + +// PushBackList inserts a copy of an other list at the back of list l. +// The lists l and other may be the same. They must not be nil. +func (l *ByteIntervalList) PushBackList(other *ByteIntervalList) { + l.lazyInit() + for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { + l.insertValue(e.Value, l.root.prev) + } +} + +// PushFrontList inserts a copy of an other list at the front of list l. +// The lists l and other may be the same. They must not be nil. +func (l *ByteIntervalList) PushFrontList(other *ByteIntervalList) { + l.lazyInit() + for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { + l.insertValue(e.Value, &l.root) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder.go new file mode 100644 index 00000000..6b92cfa2 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder.go @@ -0,0 +1,17 @@ +package utils + +import ( + "bytes" + "io" +) + +// A ByteOrder specifies how to convert byte sequences into 16-, 32-, or 64-bit unsigned integers. +type ByteOrder interface { + ReadUintN(b io.ByteReader, length uint8) (uint64, error) + ReadUint32(io.ByteReader) (uint32, error) + ReadUint16(io.ByteReader) (uint16, error) + + WriteUintN(b *bytes.Buffer, length uint8, value uint64) + WriteUint32(*bytes.Buffer, uint32) + WriteUint16(*bytes.Buffer, uint16) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder_big_endian.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder_big_endian.go new file mode 100644 index 00000000..eede9cd7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteorder_big_endian.go @@ -0,0 +1,74 @@ +package utils + +import ( + "bytes" + "io" +) + +// BigEndian is the big-endian implementation of ByteOrder. +var BigEndian ByteOrder = bigEndian{} + +type bigEndian struct{} + +var _ ByteOrder = &bigEndian{} + +// ReadUintN reads N bytes +func (bigEndian) ReadUintN(b io.ByteReader, length uint8) (uint64, error) { + var res uint64 + for i := uint8(0); i < length; i++ { + bt, err := b.ReadByte() + if err != nil { + return 0, err + } + res ^= uint64(bt) << ((length - 1 - i) * 8) + } + return res, nil +} + +// ReadUint32 reads a uint32 +func (bigEndian) ReadUint32(b io.ByteReader) (uint32, error) { + var b1, b2, b3, b4 uint8 + var err error + if b4, err = b.ReadByte(); err != nil { + return 0, err + } + if b3, err = b.ReadByte(); err != nil { + return 0, err + } + if b2, err = b.ReadByte(); err != nil { + return 0, err + } + if b1, err = b.ReadByte(); err != nil { + return 0, err + } + return uint32(b1) + uint32(b2)<<8 + uint32(b3)<<16 + uint32(b4)<<24, nil +} + +// ReadUint16 reads a uint16 +func (bigEndian) ReadUint16(b io.ByteReader) (uint16, error) { + var b1, b2 uint8 + var err error + if b2, err = b.ReadByte(); err != nil { + return 0, err + } + if b1, err = b.ReadByte(); err != nil { + return 0, err + } + return uint16(b1) + uint16(b2)<<8, nil +} + +func (bigEndian) WriteUintN(b *bytes.Buffer, length uint8, i uint64) { + for j := length; j > 0; j-- { + b.WriteByte(uint8(i >> (8 * (j - 1)))) + } +} + +// WriteUint32 writes a uint32 +func (bigEndian) WriteUint32(b *bytes.Buffer, i uint32) { + b.Write([]byte{uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i)}) +} + +// WriteUint16 writes a uint16 +func (bigEndian) WriteUint16(b *bytes.Buffer, i uint16) { + b.Write([]byte{uint8(i >> 8), uint8(i)}) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go new file mode 100644 index 00000000..bb839be6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go @@ -0,0 +1,4 @@ +package utils + +//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out byteinterval_linkedlist.go gen Item=ByteInterval +//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out packetinterval_linkedlist.go gen Item=PacketInterval diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/host.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/host.go new file mode 100644 index 00000000..a1d6453b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/host.go @@ -0,0 +1,27 @@ +package utils + +import ( + "net/url" + "strings" +) + +// HostnameFromAddr determines the hostname in an address string +func HostnameFromAddr(addr string) (string, error) { + p, err := url.Parse(addr) + if err != nil { + return "", err + } + h := p.Host + + // copied from https://golang.org/src/net/http/transport.go + if hasPort(h) { + h = h[:strings.LastIndex(h, ":")] + } + + return h, nil +} + +// copied from https://golang.org/src/net/http/http.go +func hasPort(s string) bool { + return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/log.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/log.go new file mode 100644 index 00000000..e27f01b4 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/log.go @@ -0,0 +1,131 @@ +package utils + +import ( + "fmt" + "log" + "os" + "strings" + "time" +) + +// LogLevel of quic-go +type LogLevel uint8 + +const ( + // LogLevelNothing disables + LogLevelNothing LogLevel = iota + // LogLevelError enables err logs + LogLevelError + // LogLevelInfo enables info logs (e.g. packets) + LogLevelInfo + // LogLevelDebug enables debug logs (e.g. packet contents) + LogLevelDebug +) + +const logEnv = "QUIC_GO_LOG_LEVEL" + +// A Logger logs. +type Logger interface { + SetLogLevel(LogLevel) + SetLogTimeFormat(format string) + WithPrefix(prefix string) Logger + Debug() bool + + Errorf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Debugf(format string, args ...interface{}) +} + +// DefaultLogger is used by quic-go for logging. +var DefaultLogger Logger + +type defaultLogger struct { + prefix string + + logLevel LogLevel + timeFormat string +} + +var _ Logger = &defaultLogger{} + +// SetLogLevel sets the log level +func (l *defaultLogger) SetLogLevel(level LogLevel) { + l.logLevel = level +} + +// SetLogTimeFormat sets the format of the timestamp +// an empty string disables the logging of timestamps +func (l *defaultLogger) SetLogTimeFormat(format string) { + log.SetFlags(0) // disable timestamp logging done by the log package + l.timeFormat = format +} + +// Debugf logs something +func (l *defaultLogger) Debugf(format string, args ...interface{}) { + if l.logLevel == LogLevelDebug { + l.logMessage(format, args...) + } +} + +// Infof logs something +func (l *defaultLogger) Infof(format string, args ...interface{}) { + if l.logLevel >= LogLevelInfo { + l.logMessage(format, args...) + } +} + +// Errorf logs something +func (l *defaultLogger) Errorf(format string, args ...interface{}) { + if l.logLevel >= LogLevelError { + l.logMessage(format, args...) + } +} + +func (l *defaultLogger) logMessage(format string, args ...interface{}) { + var pre string + + if len(l.timeFormat) > 0 { + pre = time.Now().Format(l.timeFormat) + " " + } + if len(l.prefix) > 0 { + pre += l.prefix + " " + } + log.Printf(pre+format, args...) +} + +func (l *defaultLogger) WithPrefix(prefix string) Logger { + if len(l.prefix) > 0 { + prefix = l.prefix + " " + prefix + } + return &defaultLogger{ + logLevel: l.logLevel, + timeFormat: l.timeFormat, + prefix: prefix, + } +} + +// Debug returns true if the log level is LogLevelDebug +func (l *defaultLogger) Debug() bool { + return l.logLevel == LogLevelDebug +} + +func init() { + DefaultLogger = &defaultLogger{} + DefaultLogger.SetLogLevel(readLoggingEnv()) +} + +func readLoggingEnv() LogLevel { + switch strings.ToLower(os.Getenv(logEnv)) { + case "": + return LogLevelNothing + case "debug": + return LogLevelDebug + case "info": + return LogLevelInfo + case "error": + return LogLevelError + default: + fmt.Fprintln(os.Stderr, "invalid quic-go log level, see https://github.com/lucas-clemente/quic-go/wiki/Logging") + return LogLevelNothing + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go new file mode 100644 index 00000000..84cbec7b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go @@ -0,0 +1,159 @@ +package utils + +import ( + "math" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// InfDuration is a duration of infinite length +const InfDuration = time.Duration(math.MaxInt64) + +// Max returns the maximum of two Ints +func Max(a, b int) int { + if a < b { + return b + } + return a +} + +// MaxUint32 returns the maximum of two uint32 +func MaxUint32(a, b uint32) uint32 { + if a < b { + return b + } + return a +} + +// MaxUint64 returns the maximum of two uint64 +func MaxUint64(a, b uint64) uint64 { + if a < b { + return b + } + return a +} + +// MinUint64 returns the maximum of two uint64 +func MinUint64(a, b uint64) uint64 { + if a < b { + return a + } + return b +} + +// Min returns the minimum of two Ints +func Min(a, b int) int { + if a < b { + return a + } + return b +} + +// MinUint32 returns the maximum of two uint32 +func MinUint32(a, b uint32) uint32 { + if a < b { + return a + } + return b +} + +// MinInt64 returns the minimum of two int64 +func MinInt64(a, b int64) int64 { + if a < b { + return a + } + return b +} + +// MaxInt64 returns the minimum of two int64 +func MaxInt64(a, b int64) int64 { + if a > b { + return a + } + return b +} + +// MinByteCount returns the minimum of two ByteCounts +func MinByteCount(a, b protocol.ByteCount) protocol.ByteCount { + if a < b { + return a + } + return b +} + +// MaxByteCount returns the maximum of two ByteCounts +func MaxByteCount(a, b protocol.ByteCount) protocol.ByteCount { + if a < b { + return b + } + return a +} + +// MaxDuration returns the max duration +func MaxDuration(a, b time.Duration) time.Duration { + if a > b { + return a + } + return b +} + +// MinDuration returns the minimum duration +func MinDuration(a, b time.Duration) time.Duration { + if a > b { + return b + } + return a +} + +// AbsDuration returns the absolute value of a time duration +func AbsDuration(d time.Duration) time.Duration { + if d >= 0 { + return d + } + return -d +} + +// MinTime returns the earlier time +func MinTime(a, b time.Time) time.Time { + if a.After(b) { + return b + } + return a +} + +// MinNonZeroTime returns the earlist time that is not time.Time{} +// If both a and b are time.Time{}, it returns time.Time{} +func MinNonZeroTime(a, b time.Time) time.Time { + if a.IsZero() { + return b + } + if b.IsZero() { + return a + } + return MinTime(a, b) +} + +// MaxTime returns the later time +func MaxTime(a, b time.Time) time.Time { + if a.After(b) { + return a + } + return b +} + +// MaxPacketNumber returns the max packet number +func MaxPacketNumber(a, b protocol.PacketNumber) protocol.PacketNumber { + if a > b { + return a + } + return b +} + +// MinPacketNumber returns the min packet number +func MinPacketNumber(a, b protocol.PacketNumber) protocol.PacketNumber { + if a < b { + return a + } + return b +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go new file mode 100644 index 00000000..62cc8b9c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go @@ -0,0 +1,9 @@ +package utils + +import "github.com/lucas-clemente/quic-go/internal/protocol" + +// PacketInterval is an interval from one PacketNumber to the other +type PacketInterval struct { + Start protocol.PacketNumber + End protocol.PacketNumber +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go new file mode 100644 index 00000000..b461e85a --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go @@ -0,0 +1,217 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package utils + +// Linked list implementation from the Go standard library. + +// PacketIntervalElement is an element of a linked list. +type PacketIntervalElement struct { + // Next and previous pointers in the doubly-linked list of elements. + // To simplify the implementation, internally a list l is implemented + // as a ring, such that &l.root is both the next element of the last + // list element (l.Back()) and the previous element of the first list + // element (l.Front()). + next, prev *PacketIntervalElement + + // The list to which this element belongs. + list *PacketIntervalList + + // The value stored with this element. + Value PacketInterval +} + +// Next returns the next list element or nil. +func (e *PacketIntervalElement) Next() *PacketIntervalElement { + if p := e.next; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// Prev returns the previous list element or nil. +func (e *PacketIntervalElement) Prev() *PacketIntervalElement { + if p := e.prev; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +// PacketIntervalList is a linked list of PacketIntervals. +type PacketIntervalList struct { + root PacketIntervalElement // sentinel list element, only &root, root.prev, and root.next are used + len int // current list length excluding (this) sentinel element +} + +// Init initializes or clears list l. +func (l *PacketIntervalList) Init() *PacketIntervalList { + l.root.next = &l.root + l.root.prev = &l.root + l.len = 0 + return l +} + +// NewPacketIntervalList returns an initialized list. +func NewPacketIntervalList() *PacketIntervalList { return new(PacketIntervalList).Init() } + +// Len returns the number of elements of list l. +// The complexity is O(1). +func (l *PacketIntervalList) Len() int { return l.len } + +// Front returns the first element of list l or nil if the list is empty. +func (l *PacketIntervalList) Front() *PacketIntervalElement { + if l.len == 0 { + return nil + } + return l.root.next +} + +// Back returns the last element of list l or nil if the list is empty. +func (l *PacketIntervalList) Back() *PacketIntervalElement { + if l.len == 0 { + return nil + } + return l.root.prev +} + +// lazyInit lazily initializes a zero List value. +func (l *PacketIntervalList) lazyInit() { + if l.root.next == nil { + l.Init() + } +} + +// insert inserts e after at, increments l.len, and returns e. +func (l *PacketIntervalList) insert(e, at *PacketIntervalElement) *PacketIntervalElement { + n := at.next + at.next = e + e.prev = at + e.next = n + n.prev = e + e.list = l + l.len++ + return e +} + +// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). +func (l *PacketIntervalList) insertValue(v PacketInterval, at *PacketIntervalElement) *PacketIntervalElement { + return l.insert(&PacketIntervalElement{Value: v}, at) +} + +// remove removes e from its list, decrements l.len, and returns e. +func (l *PacketIntervalList) remove(e *PacketIntervalElement) *PacketIntervalElement { + e.prev.next = e.next + e.next.prev = e.prev + e.next = nil // avoid memory leaks + e.prev = nil // avoid memory leaks + e.list = nil + l.len-- + return e +} + +// Remove removes e from l if e is an element of list l. +// It returns the element value e.Value. +// The element must not be nil. +func (l *PacketIntervalList) Remove(e *PacketIntervalElement) PacketInterval { + if e.list == l { + // if e.list == l, l must have been initialized when e was inserted + // in l or l == nil (e is a zero Element) and l.remove will crash + l.remove(e) + } + return e.Value +} + +// PushFront inserts a new element e with value v at the front of list l and returns e. +func (l *PacketIntervalList) PushFront(v PacketInterval) *PacketIntervalElement { + l.lazyInit() + return l.insertValue(v, &l.root) +} + +// PushBack inserts a new element e with value v at the back of list l and returns e. +func (l *PacketIntervalList) PushBack(v PacketInterval) *PacketIntervalElement { + l.lazyInit() + return l.insertValue(v, l.root.prev) +} + +// InsertBefore inserts a new element e with value v immediately before mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *PacketIntervalList) InsertBefore(v PacketInterval, mark *PacketIntervalElement) *PacketIntervalElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark.prev) +} + +// InsertAfter inserts a new element e with value v immediately after mark and returns e. +// If mark is not an element of l, the list is not modified. +// The mark must not be nil. +func (l *PacketIntervalList) InsertAfter(v PacketInterval, mark *PacketIntervalElement) *PacketIntervalElement { + if mark.list != l { + return nil + } + // see comment in List.Remove about initialization of l + return l.insertValue(v, mark) +} + +// MoveToFront moves element e to the front of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *PacketIntervalList) MoveToFront(e *PacketIntervalElement) { + if e.list != l || l.root.next == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), &l.root) +} + +// MoveToBack moves element e to the back of list l. +// If e is not an element of l, the list is not modified. +// The element must not be nil. +func (l *PacketIntervalList) MoveToBack(e *PacketIntervalElement) { + if e.list != l || l.root.prev == e { + return + } + // see comment in List.Remove about initialization of l + l.insert(l.remove(e), l.root.prev) +} + +// MoveBefore moves element e to its new position before mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *PacketIntervalList) MoveBefore(e, mark *PacketIntervalElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark.prev) +} + +// MoveAfter moves element e to its new position after mark. +// If e or mark is not an element of l, or e == mark, the list is not modified. +// The element and mark must not be nil. +func (l *PacketIntervalList) MoveAfter(e, mark *PacketIntervalElement) { + if e.list != l || e == mark || mark.list != l { + return + } + l.insert(l.remove(e), mark) +} + +// PushBackList inserts a copy of an other list at the back of list l. +// The lists l and other may be the same. They must not be nil. +func (l *PacketIntervalList) PushBackList(other *PacketIntervalList) { + l.lazyInit() + for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { + l.insertValue(e.Value, l.root.prev) + } +} + +// PushFrontList inserts a copy of an other list at the front of list l. +// The lists l and other may be the same. They must not be nil. +func (l *PacketIntervalList) PushFrontList(other *PacketIntervalList) { + l.lazyInit() + for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { + l.insertValue(e.Value, &l.root) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go new file mode 100644 index 00000000..ec16d251 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go @@ -0,0 +1,9 @@ +package utils + +import "github.com/lucas-clemente/quic-go/internal/protocol" + +// ByteInterval is an interval from one ByteCount to the other +type ByteInterval struct { + Start protocol.ByteCount + End protocol.ByteCount +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go new file mode 100644 index 00000000..1fefc6ec --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/timer.go @@ -0,0 +1,48 @@ +package utils + +import ( + "math" + "time" +) + +// A Timer wrapper that behaves correctly when resetting +type Timer struct { + t *time.Timer + read bool + deadline time.Time +} + +// NewTimer creates a new timer that is not set +func NewTimer() *Timer { + return &Timer{t: time.NewTimer(time.Duration(math.MaxInt64))} +} + +// Chan returns the channel of the wrapped timer +func (t *Timer) Chan() <-chan time.Time { + return t.t.C +} + +// Reset the timer, no matter whether the value was read or not +func (t *Timer) Reset(deadline time.Time) { + if deadline.Equal(t.deadline) && !t.read { + // No need to reset the timer + return + } + + // We need to drain the timer if the value from its channel was not read yet. + // See https://groups.google.com/forum/#!topic/golang-dev/c9UUfASVPoU + if !t.t.Stop() && !t.read { + <-t.t.C + } + if !deadline.IsZero() { + t.t.Reset(time.Until(deadline)) + } + + t.read = false + t.deadline = deadline +} + +// SetRead should be called after the value from the chan was read +func (t *Timer) SetRead() { + t.read = true +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/varint.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/varint.go new file mode 100644 index 00000000..35e8674e --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/varint.go @@ -0,0 +1,101 @@ +package utils + +import ( + "bytes" + "fmt" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// taken from the QUIC draft +const ( + maxVarInt1 = 63 + maxVarInt2 = 16383 + maxVarInt4 = 1073741823 + maxVarInt8 = 4611686018427387903 +) + +// ReadVarInt reads a number in the QUIC varint format +func ReadVarInt(b io.ByteReader) (uint64, error) { + firstByte, err := b.ReadByte() + if err != nil { + return 0, err + } + // the first two bits of the first byte encode the length + len := 1 << ((firstByte & 0xc0) >> 6) + b1 := firstByte & (0xff - 0xc0) + if len == 1 { + return uint64(b1), nil + } + b2, err := b.ReadByte() + if err != nil { + return 0, err + } + if len == 2 { + return uint64(b2) + uint64(b1)<<8, nil + } + b3, err := b.ReadByte() + if err != nil { + return 0, err + } + b4, err := b.ReadByte() + if err != nil { + return 0, err + } + if len == 4 { + return uint64(b4) + uint64(b3)<<8 + uint64(b2)<<16 + uint64(b1)<<24, nil + } + b5, err := b.ReadByte() + if err != nil { + return 0, err + } + b6, err := b.ReadByte() + if err != nil { + return 0, err + } + b7, err := b.ReadByte() + if err != nil { + return 0, err + } + b8, err := b.ReadByte() + if err != nil { + return 0, err + } + return uint64(b8) + uint64(b7)<<8 + uint64(b6)<<16 + uint64(b5)<<24 + uint64(b4)<<32 + uint64(b3)<<40 + uint64(b2)<<48 + uint64(b1)<<56, nil +} + +// WriteVarInt writes a number in the QUIC varint format +func WriteVarInt(b *bytes.Buffer, i uint64) { + if i <= maxVarInt1 { + b.WriteByte(uint8(i)) + } else if i <= maxVarInt2 { + b.Write([]byte{uint8(i>>8) | 0x40, uint8(i)}) + } else if i <= maxVarInt4 { + b.Write([]byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)}) + } else if i <= maxVarInt8 { + b.Write([]byte{ + uint8(i>>56) | 0xc0, uint8(i >> 48), uint8(i >> 40), uint8(i >> 32), + uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i), + }) + } else { + panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i)) + } +} + +// VarIntLen determines the number of bytes that will be needed to write a number +func VarIntLen(i uint64) protocol.ByteCount { + if i <= maxVarInt1 { + return 1 + } + if i <= maxVarInt2 { + return 2 + } + if i <= maxVarInt4 { + return 4 + } + if i <= maxVarInt8 { + return 8 + } + panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame.go new file mode 100644 index 00000000..7909bffa --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame.go @@ -0,0 +1,226 @@ +package wire + +import ( + "bytes" + "errors" + "sort" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges") + +// An AckFrame is an ACK frame +type AckFrame struct { + AckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last + DelayTime time.Duration +} + +// parseAckFrame reads an ACK frame +func parseAckFrame(r *bytes.Reader, ackDelayExponent uint8, version protocol.VersionNumber) (*AckFrame, error) { + typeByte, err := r.ReadByte() + if err != nil { + return nil, err + } + ecn := typeByte&0x1 > 0 + + frame := &AckFrame{} + + la, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + largestAcked := protocol.PacketNumber(la) + delay, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + frame.DelayTime = time.Duration(delay*1< largestAcked { + return nil, errors.New("invalid first ACK range") + } + smallest := largestAcked - ackBlock + + // read all the other ACK ranges + frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked}) + for i := uint64(0); i < numBlocks; i++ { + g, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + gap := protocol.PacketNumber(g) + if smallest < gap+2 { + return nil, errInvalidAckRanges + } + largest := smallest - gap - 2 + + ab, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + ackBlock := protocol.PacketNumber(ab) + + if ackBlock > largest { + return nil, errInvalidAckRanges + } + smallest = largest - ackBlock + frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largest}) + } + + if !frame.validateAckRanges() { + return nil, errInvalidAckRanges + } + + // parse (and skip) the ECN section + if ecn { + for i := 0; i < 3; i++ { + if _, err := utils.ReadVarInt(r); err != nil { + return nil, err + } + } + } + + return frame, nil +} + +// Write writes an ACK frame. +func (f *AckFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x2) + utils.WriteVarInt(b, uint64(f.LargestAcked())) + utils.WriteVarInt(b, encodeAckDelay(f.DelayTime)) + + numRanges := f.numEncodableAckRanges() + utils.WriteVarInt(b, uint64(numRanges-1)) + + // write the first range + _, firstRange := f.encodeAckRange(0) + utils.WriteVarInt(b, firstRange) + + // write all the other range + for i := 1; i < numRanges; i++ { + gap, len := f.encodeAckRange(i) + utils.WriteVarInt(b, gap) + utils.WriteVarInt(b, len) + } + return nil +} + +// Length of a written frame +func (f *AckFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + largestAcked := f.AckRanges[0].Largest + numRanges := f.numEncodableAckRanges() + + length := 1 + utils.VarIntLen(uint64(largestAcked)) + utils.VarIntLen(encodeAckDelay(f.DelayTime)) + + length += utils.VarIntLen(uint64(numRanges - 1)) + lowestInFirstRange := f.AckRanges[0].Smallest + length += utils.VarIntLen(uint64(largestAcked - lowestInFirstRange)) + + for i := 1; i < numRanges; i++ { + gap, len := f.encodeAckRange(i) + length += utils.VarIntLen(gap) + length += utils.VarIntLen(len) + } + return length +} + +// gets the number of ACK ranges that can be encoded +// such that the resulting frame is smaller than the maximum ACK frame size +func (f *AckFrame) numEncodableAckRanges() int { + length := 1 + utils.VarIntLen(uint64(f.LargestAcked())) + utils.VarIntLen(encodeAckDelay(f.DelayTime)) + length += 2 // assume that the number of ranges will consume 2 bytes + for i := 1; i < len(f.AckRanges); i++ { + gap, len := f.encodeAckRange(i) + rangeLen := utils.VarIntLen(gap) + utils.VarIntLen(len) + if length+rangeLen > protocol.MaxAckFrameSize { + // Writing range i would exceed the MaxAckFrameSize. + // So encode one range less than that. + return i - 1 + } + length += rangeLen + } + return len(f.AckRanges) +} + +func (f *AckFrame) encodeAckRange(i int) (uint64 /* gap */, uint64 /* length */) { + if i == 0 { + return 0, uint64(f.AckRanges[0].Largest - f.AckRanges[0].Smallest) + } + return uint64(f.AckRanges[i-1].Smallest - f.AckRanges[i].Largest - 2), + uint64(f.AckRanges[i].Largest - f.AckRanges[i].Smallest) +} + +// HasMissingRanges returns if this frame reports any missing packets +func (f *AckFrame) HasMissingRanges() bool { + return len(f.AckRanges) > 1 +} + +func (f *AckFrame) validateAckRanges() bool { + if len(f.AckRanges) == 0 { + return false + } + + // check the validity of every single ACK range + for _, ackRange := range f.AckRanges { + if ackRange.Smallest > ackRange.Largest { + return false + } + } + + // check the consistency for ACK with multiple NACK ranges + for i, ackRange := range f.AckRanges { + if i == 0 { + continue + } + lastAckRange := f.AckRanges[i-1] + if lastAckRange.Smallest <= ackRange.Smallest { + return false + } + if lastAckRange.Smallest <= ackRange.Largest+1 { + return false + } + } + + return true +} + +// LargestAcked is the largest acked packet number +func (f *AckFrame) LargestAcked() protocol.PacketNumber { + return f.AckRanges[0].Largest +} + +// LowestAcked is the lowest acked packet number +func (f *AckFrame) LowestAcked() protocol.PacketNumber { + return f.AckRanges[len(f.AckRanges)-1].Smallest +} + +// AcksPacket determines if this ACK frame acks a certain packet number +func (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool { + if p < f.LowestAcked() || p > f.LargestAcked() { + return false + } + + i := sort.Search(len(f.AckRanges), func(i int) bool { + return p >= f.AckRanges[i].Smallest + }) + // i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked + return p <= f.AckRanges[i].Largest +} + +func encodeAckDelay(delay time.Duration) uint64 { + return uint64(delay.Nanoseconds() / (1000 * (1 << protocol.AckDelayExponent))) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_range.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_range.go new file mode 100644 index 00000000..0f418580 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_range.go @@ -0,0 +1,14 @@ +package wire + +import "github.com/lucas-clemente/quic-go/internal/protocol" + +// AckRange is an ACK range +type AckRange struct { + Smallest protocol.PacketNumber + Largest protocol.PacketNumber +} + +// Len returns the number of packets contained in this ACK range +func (r AckRange) Len() protocol.PacketNumber { + return r.Largest - r.Smallest + 1 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/connection_close_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/connection_close_frame.go new file mode 100644 index 00000000..60378a5d --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/connection_close_frame.go @@ -0,0 +1,81 @@ +package wire + +import ( + "bytes" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A ConnectionCloseFrame is a CONNECTION_CLOSE frame +type ConnectionCloseFrame struct { + IsApplicationError bool + ErrorCode qerr.ErrorCode + ReasonPhrase string +} + +func parseConnectionCloseFrame(r *bytes.Reader, version protocol.VersionNumber) (*ConnectionCloseFrame, error) { + typeByte, err := r.ReadByte() + if err != nil { + return nil, err + } + + f := &ConnectionCloseFrame{IsApplicationError: typeByte == 0x1d} + ec, err := utils.BigEndian.ReadUint16(r) + if err != nil { + return nil, err + } + f.ErrorCode = qerr.ErrorCode(ec) + // read the Frame Type, if this is not an application error + if !f.IsApplicationError { + if _, err := utils.ReadVarInt(r); err != nil { + return nil, err + } + } + var reasonPhraseLen uint64 + reasonPhraseLen, err = utils.ReadVarInt(r) + if err != nil { + return nil, err + } + // shortcut to prevent the unnecessary allocation of dataLen bytes + // if the dataLen is larger than the remaining length of the packet + // reading the whole reason phrase would result in EOF when attempting to READ + if int(reasonPhraseLen) > r.Len() { + return nil, io.EOF + } + + reasonPhrase := make([]byte, reasonPhraseLen) + if _, err := io.ReadFull(r, reasonPhrase); err != nil { + // this should never happen, since we already checked the reasonPhraseLen earlier + return nil, err + } + f.ReasonPhrase = string(reasonPhrase) + return f, nil +} + +// Length of a written frame +func (f *ConnectionCloseFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + length := 1 + 2 + utils.VarIntLen(uint64(len(f.ReasonPhrase))) + protocol.ByteCount(len(f.ReasonPhrase)) + if !f.IsApplicationError { + length++ // for the frame type + } + return length +} + +func (f *ConnectionCloseFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + if f.IsApplicationError { + b.WriteByte(0x1d) + } else { + b.WriteByte(0x1c) + } + + utils.BigEndian.WriteUint16(b, uint16(f.ErrorCode)) + if !f.IsApplicationError { + utils.WriteVarInt(b, 0) + } + utils.WriteVarInt(b, uint64(len(f.ReasonPhrase))) + b.WriteString(f.ReasonPhrase) + return nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/crypto_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/crypto_frame.go new file mode 100644 index 00000000..eeafea97 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/crypto_frame.go @@ -0,0 +1,71 @@ +package wire + +import ( + "bytes" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A CryptoFrame is a CRYPTO frame +type CryptoFrame struct { + Offset protocol.ByteCount + Data []byte +} + +func parseCryptoFrame(r *bytes.Reader, _ protocol.VersionNumber) (*CryptoFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + frame := &CryptoFrame{} + offset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + frame.Offset = protocol.ByteCount(offset) + dataLen, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + if dataLen > uint64(r.Len()) { + return nil, io.EOF + } + if dataLen != 0 { + frame.Data = make([]byte, dataLen) + if _, err := io.ReadFull(r, frame.Data); err != nil { + // this should never happen, since we already checked the dataLen earlier + return nil, err + } + } + return frame, nil +} + +func (f *CryptoFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x6) + utils.WriteVarInt(b, uint64(f.Offset)) + utils.WriteVarInt(b, uint64(len(f.Data))) + b.Write(f.Data) + return nil +} + +// Length of a written frame +func (f *CryptoFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.Offset)) + utils.VarIntLen(uint64(len(f.Data))) + protocol.ByteCount(len(f.Data)) +} + +// MaxDataLen returns the maximum data length +func (f *CryptoFrame) MaxDataLen(maxSize protocol.ByteCount) protocol.ByteCount { + // pretend that the data size will be 1 bytes + // if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards + headerLen := 1 + utils.VarIntLen(uint64(f.Offset)) + 1 + if headerLen > maxSize { + return 0 + } + maxDataLen := maxSize - headerLen + if utils.VarIntLen(uint64(maxDataLen)) != 1 { + maxDataLen-- + } + return maxDataLen +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/data_blocked_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/data_blocked_frame.go new file mode 100644 index 00000000..91c05ccf --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/data_blocked_frame.go @@ -0,0 +1,38 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A DataBlockedFrame is a DATA_BLOCKED frame +type DataBlockedFrame struct { + DataLimit protocol.ByteCount +} + +func parseDataBlockedFrame(r *bytes.Reader, _ protocol.VersionNumber) (*DataBlockedFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + offset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + return &DataBlockedFrame{ + DataLimit: protocol.ByteCount(offset), + }, nil +} + +func (f *DataBlockedFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + typeByte := uint8(0x14) + b.WriteByte(typeByte) + utils.WriteVarInt(b, uint64(f.DataLimit)) + return nil +} + +// Length of a written frame +func (f *DataBlockedFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.DataLimit)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/extended_header.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/extended_header.go new file mode 100644 index 00000000..19a0b064 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/extended_header.go @@ -0,0 +1,204 @@ +package wire + +import ( + "bytes" + "errors" + "fmt" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// ExtendedHeader is the header of a QUIC packet. +type ExtendedHeader struct { + Header + + typeByte byte + + PacketNumberLen protocol.PacketNumberLen + PacketNumber protocol.PacketNumber + + KeyPhase int +} + +func (h *ExtendedHeader) parse(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) { + // read the (now unencrypted) first byte + var err error + h.typeByte, err = b.ReadByte() + if err != nil { + return nil, err + } + if _, err := b.Seek(int64(h.ParsedLen())-1, io.SeekCurrent); err != nil { + return nil, err + } + if h.IsLongHeader { + return h.parseLongHeader(b, v) + } + return h.parseShortHeader(b, v) +} + +func (h *ExtendedHeader) parseLongHeader(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) { + if h.typeByte&0xc != 0 { + return nil, errors.New("5th and 6th bit must be 0") + } + if err := h.readPacketNumber(b); err != nil { + return nil, err + } + return h, nil +} + +func (h *ExtendedHeader) parseShortHeader(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) { + if h.typeByte&0x18 != 0 { + return nil, errors.New("4th and 5th bit must be 0") + } + + h.KeyPhase = int(h.typeByte&0x4) >> 2 + + if err := h.readPacketNumber(b); err != nil { + return nil, err + } + return h, nil +} + +func (h *ExtendedHeader) readPacketNumber(b *bytes.Reader) error { + h.PacketNumberLen = protocol.PacketNumberLen(h.typeByte&0x3) + 1 + pn, err := utils.BigEndian.ReadUintN(b, uint8(h.PacketNumberLen)) + if err != nil { + return err + } + h.PacketNumber = protocol.PacketNumber(pn) + return nil +} + +// Write writes the Header. +func (h *ExtendedHeader) Write(b *bytes.Buffer, ver protocol.VersionNumber) error { + if h.IsLongHeader { + return h.writeLongHeader(b, ver) + } + return h.writeShortHeader(b, ver) +} + +func (h *ExtendedHeader) writeLongHeader(b *bytes.Buffer, v protocol.VersionNumber) error { + var packetType uint8 + switch h.Type { + case protocol.PacketTypeInitial: + packetType = 0x0 + case protocol.PacketType0RTT: + packetType = 0x1 + case protocol.PacketTypeHandshake: + packetType = 0x2 + case protocol.PacketTypeRetry: + packetType = 0x3 + } + firstByte := 0xc0 | packetType<<4 + if h.Type == protocol.PacketTypeRetry { + odcil, err := encodeSingleConnIDLen(h.OrigDestConnectionID) + if err != nil { + return err + } + firstByte |= odcil + } else { // Retry packets don't have a packet number + firstByte |= uint8(h.PacketNumberLen - 1) + } + + b.WriteByte(firstByte) + utils.BigEndian.WriteUint32(b, uint32(h.Version)) + connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID) + if err != nil { + return err + } + b.WriteByte(connIDLen) + b.Write(h.DestConnectionID.Bytes()) + b.Write(h.SrcConnectionID.Bytes()) + + switch h.Type { + case protocol.PacketTypeRetry: + b.Write(h.OrigDestConnectionID.Bytes()) + b.Write(h.Token) + return nil + case protocol.PacketTypeInitial: + utils.WriteVarInt(b, uint64(len(h.Token))) + b.Write(h.Token) + } + + utils.WriteVarInt(b, uint64(h.Length)) + return h.writePacketNumber(b) +} + +// TODO: add support for the key phase +func (h *ExtendedHeader) writeShortHeader(b *bytes.Buffer, v protocol.VersionNumber) error { + typeByte := 0x40 | uint8(h.PacketNumberLen-1) + typeByte |= byte(h.KeyPhase << 2) + + b.WriteByte(typeByte) + b.Write(h.DestConnectionID.Bytes()) + return h.writePacketNumber(b) +} + +func (h *ExtendedHeader) writePacketNumber(b *bytes.Buffer) error { + if h.PacketNumberLen == protocol.PacketNumberLenInvalid || h.PacketNumberLen > protocol.PacketNumberLen4 { + return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen) + } + utils.BigEndian.WriteUintN(b, uint8(h.PacketNumberLen), uint64(h.PacketNumber)) + return nil +} + +// GetLength determines the length of the Header. +func (h *ExtendedHeader) GetLength(v protocol.VersionNumber) protocol.ByteCount { + if h.IsLongHeader { + length := 1 /* type byte */ + 4 /* version */ + 1 /* conn id len byte */ + protocol.ByteCount(h.DestConnectionID.Len()+h.SrcConnectionID.Len()) + protocol.ByteCount(h.PacketNumberLen) + utils.VarIntLen(uint64(h.Length)) + if h.Type == protocol.PacketTypeInitial { + length += utils.VarIntLen(uint64(len(h.Token))) + protocol.ByteCount(len(h.Token)) + } + return length + } + + length := protocol.ByteCount(1 /* type byte */ + h.DestConnectionID.Len()) + length += protocol.ByteCount(h.PacketNumberLen) + return length +} + +// Log logs the Header +func (h *ExtendedHeader) Log(logger utils.Logger) { + if h.IsLongHeader { + var token string + if h.Type == protocol.PacketTypeInitial || h.Type == protocol.PacketTypeRetry { + if len(h.Token) == 0 { + token = "Token: (empty), " + } else { + token = fmt.Sprintf("Token: %#x, ", h.Token) + } + if h.Type == protocol.PacketTypeRetry { + logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sOrigDestConnectionID: %s, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.OrigDestConnectionID, h.Version) + return + } + } + logger.Debugf("\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %#x, PacketNumberLen: %d, Length: %d, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.Length, h.Version) + } else { + logger.Debugf("\tShort Header{DestConnectionID: %s, PacketNumber: %#x, PacketNumberLen: %d, KeyPhase: %d}", h.DestConnectionID, h.PacketNumber, h.PacketNumberLen, h.KeyPhase) + } +} + +func encodeConnIDLen(dest, src protocol.ConnectionID) (byte, error) { + dcil, err := encodeSingleConnIDLen(dest) + if err != nil { + return 0, err + } + scil, err := encodeSingleConnIDLen(src) + if err != nil { + return 0, err + } + return scil | dcil<<4, nil +} + +func encodeSingleConnIDLen(id protocol.ConnectionID) (byte, error) { + len := id.Len() + if len == 0 { + return 0, nil + } + if len < 4 || len > 18 { + return 0, fmt.Errorf("invalid connection ID length: %d bytes", len) + } + return byte(len - 3), nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/frame_parser.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/frame_parser.go new file mode 100644 index 00000000..e9d3d6a5 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/frame_parser.go @@ -0,0 +1,97 @@ +package wire + +import ( + "bytes" + "fmt" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" +) + +type frameParser struct { + ackDelayExponent uint8 + + version protocol.VersionNumber +} + +// NewFrameParser creates a new frame parser. +func NewFrameParser(v protocol.VersionNumber) FrameParser { + return &frameParser{version: v} +} + +// ParseNextFrame parses the next frame +// It skips PADDING frames. +func (p *frameParser) ParseNext(r *bytes.Reader, encLevel protocol.EncryptionLevel) (Frame, error) { + for r.Len() != 0 { + typeByte, _ := r.ReadByte() + if typeByte == 0x0 { // PADDING frame + continue + } + r.UnreadByte() + + return p.parseFrame(r, typeByte, encLevel) + } + return nil, nil +} + +func (p *frameParser) parseFrame(r *bytes.Reader, typeByte byte, encLevel protocol.EncryptionLevel) (Frame, error) { + var frame Frame + var err error + if typeByte&0xf8 == 0x8 { + frame, err = parseStreamFrame(r, p.version) + if err != nil { + return nil, qerr.Error(qerr.FrameEncodingError, err.Error()) + } + return frame, nil + } + switch typeByte { + case 0x1: + frame, err = parsePingFrame(r, p.version) + case 0x2, 0x3: + ackDelayExponent := p.ackDelayExponent + if encLevel != protocol.Encryption1RTT { + ackDelayExponent = protocol.DefaultAckDelayExponent + } + frame, err = parseAckFrame(r, ackDelayExponent, p.version) + case 0x4: + frame, err = parseResetStreamFrame(r, p.version) + case 0x5: + frame, err = parseStopSendingFrame(r, p.version) + case 0x6: + frame, err = parseCryptoFrame(r, p.version) + case 0x7: + frame, err = parseNewTokenFrame(r, p.version) + case 0x10: + frame, err = parseMaxDataFrame(r, p.version) + case 0x11: + frame, err = parseMaxStreamDataFrame(r, p.version) + case 0x12, 0x13: + frame, err = parseMaxStreamsFrame(r, p.version) + case 0x14: + frame, err = parseDataBlockedFrame(r, p.version) + case 0x15: + frame, err = parseStreamDataBlockedFrame(r, p.version) + case 0x16, 0x17: + frame, err = parseStreamsBlockedFrame(r, p.version) + case 0x18: + frame, err = parseNewConnectionIDFrame(r, p.version) + case 0x19: + frame, err = parseRetireConnectionIDFrame(r, p.version) + case 0x1a: + frame, err = parsePathChallengeFrame(r, p.version) + case 0x1b: + frame, err = parsePathResponseFrame(r, p.version) + case 0x1c, 0x1d: + frame, err = parseConnectionCloseFrame(r, p.version) + default: + err = fmt.Errorf("unknown type byte 0x%x", typeByte) + } + if err != nil { + return nil, qerr.Error(qerr.FrameEncodingError, err.Error()) + } + return frame, nil +} + +func (p *frameParser) SetAckDelayExponent(exp uint8) { + p.ackDelayExponent = exp +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go new file mode 100644 index 00000000..21eb784c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go @@ -0,0 +1,251 @@ +package wire + +import ( + "bytes" + "errors" + "fmt" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// ParseConnectionID parses the destination connection ID of a packet. +// It uses the data slice for the connection ID. +// That means that the connection ID must not be used after the packet buffer is released. +func ParseConnectionID(data []byte, shortHeaderConnIDLen int) (protocol.ConnectionID, error) { + if len(data) == 0 { + return nil, io.EOF + } + isLongHeader := data[0]&0x80 > 0 + if !isLongHeader { + if len(data) < shortHeaderConnIDLen+1 { + return nil, io.EOF + } + return protocol.ConnectionID(data[1 : 1+shortHeaderConnIDLen]), nil + } + if len(data) < 6 { + return nil, io.EOF + } + destConnIDLen, _ := decodeConnIDLen(data[5]) + if len(data) < 6+destConnIDLen { + return nil, io.EOF + } + return protocol.ConnectionID(data[6 : 6+destConnIDLen]), nil +} + +// IsVersionNegotiationPacket says if this is a version negotiation packet +func IsVersionNegotiationPacket(b []byte) bool { + if len(b) < 5 { + return false + } + return b[0]&0x80 > 0 && b[1] == 0 && b[2] == 0 && b[3] == 0 && b[4] == 0 +} + +var errUnsupportedVersion = errors.New("unsupported version") + +// The Header is the version independent part of the header +type Header struct { + Version protocol.VersionNumber + SrcConnectionID protocol.ConnectionID + DestConnectionID protocol.ConnectionID + + IsLongHeader bool + Type protocol.PacketType + Length protocol.ByteCount + + Token []byte + SupportedVersions []protocol.VersionNumber // sent in a Version Negotiation Packet + OrigDestConnectionID protocol.ConnectionID // sent in the Retry packet + + typeByte byte + parsedLen protocol.ByteCount // how many bytes were read while parsing this header +} + +// ParsePacket parses a packet. +// If the packet has a long header, the packet is cut according to the length field. +// If we understand the version, the packet is header up unto the packet number. +// Otherwise, only the invariant part of the header is parsed. +func ParsePacket(data []byte, shortHeaderConnIDLen int) (*Header, []byte /* packet data */, []byte /* rest */, error) { + hdr, err := parseHeader(bytes.NewReader(data), shortHeaderConnIDLen) + if err != nil { + if err == errUnsupportedVersion { + return hdr, nil, nil, nil + } + return nil, nil, nil, err + } + var rest []byte + if hdr.IsLongHeader { + if protocol.ByteCount(len(data)) < hdr.ParsedLen()+hdr.Length { + return nil, nil, nil, fmt.Errorf("packet length (%d bytes) is smaller than the expected length (%d bytes)", len(data)-int(hdr.ParsedLen()), hdr.Length) + } + packetLen := int(hdr.ParsedLen() + hdr.Length) + rest = data[packetLen:] + data = data[:packetLen] + } + return hdr, data, rest, nil +} + +// ParseHeader parses the header. +// For short header packets: up to the packet number. +// For long header packets: +// * if we understand the version: up to the packet number +// * if not, only the invariant part of the header +func parseHeader(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error) { + startLen := b.Len() + h, err := parseHeaderImpl(b, shortHeaderConnIDLen) + if err != nil { + return h, err + } + h.parsedLen = protocol.ByteCount(startLen - b.Len()) + return h, err +} + +func parseHeaderImpl(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error) { + typeByte, err := b.ReadByte() + if err != nil { + return nil, err + } + + h := &Header{ + typeByte: typeByte, + IsLongHeader: typeByte&0x80 > 0, + } + + if !h.IsLongHeader { + if h.typeByte&0x40 == 0 { + return nil, errors.New("not a QUIC packet") + } + if err := h.parseShortHeader(b, shortHeaderConnIDLen); err != nil { + return nil, err + } + return h, nil + } + return h, h.parseLongHeader(b) +} + +func (h *Header) parseShortHeader(b *bytes.Reader, shortHeaderConnIDLen int) error { + var err error + h.DestConnectionID, err = protocol.ReadConnectionID(b, shortHeaderConnIDLen) + return err +} + +func (h *Header) parseLongHeader(b *bytes.Reader) error { + v, err := utils.BigEndian.ReadUint32(b) + if err != nil { + return err + } + h.Version = protocol.VersionNumber(v) + if h.Version != 0 && h.typeByte&0x40 == 0 { + return errors.New("not a QUIC packet") + } + connIDLenByte, err := b.ReadByte() + if err != nil { + return err + } + dcil, scil := decodeConnIDLen(connIDLenByte) + h.DestConnectionID, err = protocol.ReadConnectionID(b, dcil) + if err != nil { + return err + } + h.SrcConnectionID, err = protocol.ReadConnectionID(b, scil) + if err != nil { + return err + } + if h.Version == 0 { + return h.parseVersionNegotiationPacket(b) + } + // If we don't understand the version, we have no idea how to interpret the rest of the bytes + if !protocol.IsSupportedVersion(protocol.SupportedVersions, h.Version) { + return errUnsupportedVersion + } + + switch (h.typeByte & 0x30) >> 4 { + case 0x0: + h.Type = protocol.PacketTypeInitial + case 0x1: + h.Type = protocol.PacketType0RTT + case 0x2: + h.Type = protocol.PacketTypeHandshake + case 0x3: + h.Type = protocol.PacketTypeRetry + } + + if h.Type == protocol.PacketTypeRetry { + odcil := decodeSingleConnIDLen(h.typeByte & 0xf) + h.OrigDestConnectionID, err = protocol.ReadConnectionID(b, odcil) + if err != nil { + return err + } + h.Token = make([]byte, b.Len()) + if _, err := io.ReadFull(b, h.Token); err != nil { + return err + } + return nil + } + + if h.Type == protocol.PacketTypeInitial { + tokenLen, err := utils.ReadVarInt(b) + if err != nil { + return err + } + if tokenLen > uint64(b.Len()) { + return io.EOF + } + h.Token = make([]byte, tokenLen) + if _, err := io.ReadFull(b, h.Token); err != nil { + return err + } + } + + pl, err := utils.ReadVarInt(b) + if err != nil { + return err + } + h.Length = protocol.ByteCount(pl) + return nil +} + +func (h *Header) parseVersionNegotiationPacket(b *bytes.Reader) error { + if b.Len() == 0 { + return errors.New("Version Negoation packet has empty version list") + } + if b.Len()%4 != 0 { + return errors.New("Version Negotation packet has a version list with an invalid length") + } + h.SupportedVersions = make([]protocol.VersionNumber, b.Len()/4) + for i := 0; b.Len() > 0; i++ { + v, err := utils.BigEndian.ReadUint32(b) + if err != nil { + return err + } + h.SupportedVersions[i] = protocol.VersionNumber(v) + } + return nil +} + +// ParsedLen returns the number of bytes that were consumed when parsing the header +func (h *Header) ParsedLen() protocol.ByteCount { + return h.parsedLen +} + +// ParseExtended parses the version dependent part of the header. +// The Reader has to be set such that it points to the first byte of the header. +func (h *Header) ParseExtended(b *bytes.Reader, ver protocol.VersionNumber) (*ExtendedHeader, error) { + return h.toExtendedHeader().parse(b, ver) +} + +func (h *Header) toExtendedHeader() *ExtendedHeader { + return &ExtendedHeader{Header: *h} +} + +func decodeConnIDLen(enc byte) (int /*dest conn id len*/, int /*src conn id len*/) { + return decodeSingleConnIDLen(enc >> 4), decodeSingleConnIDLen(enc & 0xf) +} + +func decodeSingleConnIDLen(enc uint8) int { + if enc == 0 { + return 0 + } + return int(enc) + 3 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/interface.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/interface.go new file mode 100644 index 00000000..99fdc80f --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/interface.go @@ -0,0 +1,19 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A Frame in QUIC +type Frame interface { + Write(b *bytes.Buffer, version protocol.VersionNumber) error + Length(version protocol.VersionNumber) protocol.ByteCount +} + +// A FrameParser parses QUIC frames, one by one. +type FrameParser interface { + ParseNext(*bytes.Reader, protocol.EncryptionLevel) (Frame, error) + SetAckDelayExponent(uint8) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/log.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/log.go new file mode 100644 index 00000000..3c56ac45 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/log.go @@ -0,0 +1,43 @@ +package wire + +import ( + "fmt" + "strings" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// LogFrame logs a frame, either sent or received +func LogFrame(logger utils.Logger, frame Frame, sent bool) { + if !logger.Debug() { + return + } + dir := "<-" + if sent { + dir = "->" + } + switch f := frame.(type) { + case *CryptoFrame: + dataLen := protocol.ByteCount(len(f.Data)) + logger.Debugf("\t%s &wire.CryptoFrame{Offset: 0x%x, Data length: 0x%x, Offset + Data length: 0x%x}", dir, f.Offset, dataLen, f.Offset+dataLen) + case *StreamFrame: + logger.Debugf("\t%s &wire.StreamFrame{StreamID: %d, FinBit: %t, Offset: 0x%x, Data length: 0x%x, Offset + Data length: 0x%x}", dir, f.StreamID, f.FinBit, f.Offset, f.DataLen(), f.Offset+f.DataLen()) + case *AckFrame: + if len(f.AckRanges) > 1 { + ackRanges := make([]string, len(f.AckRanges)) + for i, r := range f.AckRanges { + ackRanges[i] = fmt.Sprintf("{Largest: %#x, Smallest: %#x}", r.Largest, r.Smallest) + } + logger.Debugf("\t%s &wire.AckFrame{LargestAcked: %#x, LowestAcked: %#x, AckRanges: {%s}, DelayTime: %s}", dir, f.LargestAcked(), f.LowestAcked(), strings.Join(ackRanges, ", "), f.DelayTime.String()) + } else { + logger.Debugf("\t%s &wire.AckFrame{LargestAcked: %#x, LowestAcked: %#x, DelayTime: %s}", dir, f.LargestAcked(), f.LowestAcked(), f.DelayTime.String()) + } + case *NewConnectionIDFrame: + logger.Debugf("\t%s &wire.NewConnectionIDFrame{SequenceNumber: %d, ConnectionID: %s, StatelessResetToken: %#x}", dir, f.SequenceNumber, f.ConnectionID, f.StatelessResetToken) + case *NewTokenFrame: + logger.Debugf("\t%s &wire.NewTokenFrame{Token: %#x}", dir, f.Token) + default: + logger.Debugf("\t%s %#v", dir, frame) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_data_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_data_frame.go new file mode 100644 index 00000000..c4a9be0d --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_data_frame.go @@ -0,0 +1,40 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A MaxDataFrame carries flow control information for the connection +type MaxDataFrame struct { + ByteOffset protocol.ByteCount +} + +// parseMaxDataFrame parses a MAX_DATA frame +func parseMaxDataFrame(r *bytes.Reader, version protocol.VersionNumber) (*MaxDataFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + frame := &MaxDataFrame{} + byteOffset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + frame.ByteOffset = protocol.ByteCount(byteOffset) + return frame, nil +} + +//Write writes a MAX_STREAM_DATA frame +func (f *MaxDataFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x10) + utils.WriteVarInt(b, uint64(f.ByteOffset)) + return nil +} + +// Length of a written frame +func (f *MaxDataFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.ByteOffset)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_stream_data_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_stream_data_frame.go new file mode 100644 index 00000000..2566f1c9 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_stream_data_frame.go @@ -0,0 +1,46 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A MaxStreamDataFrame is a MAX_STREAM_DATA frame +type MaxStreamDataFrame struct { + StreamID protocol.StreamID + ByteOffset protocol.ByteCount +} + +func parseMaxStreamDataFrame(r *bytes.Reader, version protocol.VersionNumber) (*MaxStreamDataFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + sid, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + offset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + + return &MaxStreamDataFrame{ + StreamID: protocol.StreamID(sid), + ByteOffset: protocol.ByteCount(offset), + }, nil +} + +func (f *MaxStreamDataFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x11) + utils.WriteVarInt(b, uint64(f.StreamID)) + utils.WriteVarInt(b, uint64(f.ByteOffset)) + return nil +} + +// Length of a written frame +func (f *MaxStreamDataFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.StreamID)) + utils.VarIntLen(uint64(f.ByteOffset)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_streams_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_streams_frame.go new file mode 100644 index 00000000..c7a3cd41 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/max_streams_frame.go @@ -0,0 +1,51 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A MaxStreamsFrame is a MAX_STREAMS frame +type MaxStreamsFrame struct { + Type protocol.StreamType + MaxStreams uint64 +} + +func parseMaxStreamsFrame(r *bytes.Reader, _ protocol.VersionNumber) (*MaxStreamsFrame, error) { + typeByte, err := r.ReadByte() + if err != nil { + return nil, err + } + + f := &MaxStreamsFrame{} + switch typeByte { + case 0x12: + f.Type = protocol.StreamTypeBidi + case 0x13: + f.Type = protocol.StreamTypeUni + } + streamID, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + f.MaxStreams = streamID + return f, nil +} + +func (f *MaxStreamsFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + switch f.Type { + case protocol.StreamTypeBidi: + b.WriteByte(0x12) + case protocol.StreamTypeUni: + b.WriteByte(0x13) + } + utils.WriteVarInt(b, f.MaxStreams) + return nil +} + +// Length of a written frame +func (f *MaxStreamsFrame) Length(protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(f.MaxStreams) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_connection_id_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_connection_id_frame.go new file mode 100644 index 00000000..9a612aa6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_connection_id_frame.go @@ -0,0 +1,70 @@ +package wire + +import ( + "bytes" + "fmt" + "io" + + "github.com/lucas-clemente/quic-go/internal/utils" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A NewConnectionIDFrame is a NEW_CONNECTION_ID frame +type NewConnectionIDFrame struct { + SequenceNumber uint64 + ConnectionID protocol.ConnectionID + StatelessResetToken [16]byte +} + +func parseNewConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewConnectionIDFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + seq, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + connIDLen, err := r.ReadByte() + if err != nil { + return nil, err + } + if connIDLen < 4 || connIDLen > 18 { + return nil, fmt.Errorf("invalid connection ID length: %d", connIDLen) + } + connID, err := protocol.ReadConnectionID(r, int(connIDLen)) + if err != nil { + return nil, err + } + frame := &NewConnectionIDFrame{ + SequenceNumber: seq, + ConnectionID: connID, + } + if _, err := io.ReadFull(r, frame.StatelessResetToken[:]); err != nil { + if err == io.ErrUnexpectedEOF { + return nil, io.EOF + } + return nil, err + } + + return frame, nil +} + +func (f *NewConnectionIDFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x18) + utils.WriteVarInt(b, f.SequenceNumber) + connIDLen := f.ConnectionID.Len() + if connIDLen < 4 || connIDLen > 18 { + return fmt.Errorf("invalid connection ID length: %d", connIDLen) + } + b.WriteByte(uint8(connIDLen)) + b.Write(f.ConnectionID.Bytes()) + b.Write(f.StatelessResetToken[:]) + return nil +} + +// Length of a written frame +func (f *NewConnectionIDFrame) Length(protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(f.SequenceNumber) + 1 /* connection ID length */ + protocol.ByteCount(f.ConnectionID.Len()) + 16 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_token_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_token_frame.go new file mode 100644 index 00000000..2cf6fce5 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/new_token_frame.go @@ -0,0 +1,44 @@ +package wire + +import ( + "bytes" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A NewTokenFrame is a NEW_TOKEN frame +type NewTokenFrame struct { + Token []byte +} + +func parseNewTokenFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewTokenFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + tokenLen, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + if uint64(r.Len()) < tokenLen { + return nil, io.EOF + } + token := make([]byte, int(tokenLen)) + if _, err := io.ReadFull(r, token); err != nil { + return nil, err + } + return &NewTokenFrame{Token: token}, nil +} + +func (f *NewTokenFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x7) + utils.WriteVarInt(b, uint64(len(f.Token))) + b.Write(f.Token) + return nil +} + +// Length of a written frame +func (f *NewTokenFrame) Length(protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(len(f.Token))) + protocol.ByteCount(len(f.Token)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_challenge_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_challenge_frame.go new file mode 100644 index 00000000..d35ee3b5 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_challenge_frame.go @@ -0,0 +1,38 @@ +package wire + +import ( + "bytes" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A PathChallengeFrame is a PATH_CHALLENGE frame +type PathChallengeFrame struct { + Data [8]byte +} + +func parsePathChallengeFrame(r *bytes.Reader, version protocol.VersionNumber) (*PathChallengeFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + frame := &PathChallengeFrame{} + if _, err := io.ReadFull(r, frame.Data[:]); err != nil { + if err == io.ErrUnexpectedEOF { + return nil, io.EOF + } + return nil, err + } + return frame, nil +} + +func (f *PathChallengeFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x1a) + b.Write(f.Data[:]) + return nil +} + +// Length of a written frame +func (f *PathChallengeFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { + return 1 + 8 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_response_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_response_frame.go new file mode 100644 index 00000000..20d8fd72 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/path_response_frame.go @@ -0,0 +1,38 @@ +package wire + +import ( + "bytes" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A PathResponseFrame is a PATH_RESPONSE frame +type PathResponseFrame struct { + Data [8]byte +} + +func parsePathResponseFrame(r *bytes.Reader, version protocol.VersionNumber) (*PathResponseFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + frame := &PathResponseFrame{} + if _, err := io.ReadFull(r, frame.Data[:]); err != nil { + if err == io.ErrUnexpectedEOF { + return nil, io.EOF + } + return nil, err + } + return frame, nil +} + +func (f *PathResponseFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x1b) + b.Write(f.Data[:]) + return nil +} + +// Length of a written frame +func (f *PathResponseFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { + return 1 + 8 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/ping_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ping_frame.go new file mode 100644 index 00000000..aed6857b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/ping_frame.go @@ -0,0 +1,27 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// A PingFrame is a PING frame +type PingFrame struct{} + +func parsePingFrame(r *bytes.Reader, version protocol.VersionNumber) (*PingFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + return &PingFrame{}, nil +} + +func (f *PingFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x1) + return nil +} + +// Length of a written frame +func (f *PingFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/reset_stream_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/reset_stream_frame.go new file mode 100644 index 00000000..d3a40dcf --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/reset_stream_frame.go @@ -0,0 +1,58 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A ResetStreamFrame is a RESET_STREAM frame in QUIC +type ResetStreamFrame struct { + StreamID protocol.StreamID + ErrorCode protocol.ApplicationErrorCode + ByteOffset protocol.ByteCount +} + +func parseResetStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*ResetStreamFrame, error) { + if _, err := r.ReadByte(); err != nil { // read the TypeByte + return nil, err + } + + var streamID protocol.StreamID + var errorCode uint16 + var byteOffset protocol.ByteCount + sid, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + streamID = protocol.StreamID(sid) + errorCode, err = utils.BigEndian.ReadUint16(r) + if err != nil { + return nil, err + } + bo, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + byteOffset = protocol.ByteCount(bo) + + return &ResetStreamFrame{ + StreamID: streamID, + ErrorCode: protocol.ApplicationErrorCode(errorCode), + ByteOffset: byteOffset, + }, nil +} + +func (f *ResetStreamFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x4) + utils.WriteVarInt(b, uint64(f.StreamID)) + utils.BigEndian.WriteUint16(b, uint16(f.ErrorCode)) + utils.WriteVarInt(b, uint64(f.ByteOffset)) + return nil +} + +// Length of a written frame +func (f *ResetStreamFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.StreamID)) + 2 + utils.VarIntLen(uint64(f.ByteOffset)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/retire_connection_id_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/retire_connection_id_frame.go new file mode 100644 index 00000000..9a715a4c --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/retire_connection_id_frame.go @@ -0,0 +1,36 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame +type RetireConnectionIDFrame struct { + SequenceNumber uint64 +} + +func parseRetireConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*RetireConnectionIDFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + seq, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + return &RetireConnectionIDFrame{SequenceNumber: seq}, nil +} + +func (f *RetireConnectionIDFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x19) + utils.WriteVarInt(b, f.SequenceNumber) + return nil +} + +// Length of a written frame +func (f *RetireConnectionIDFrame) Length(protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(f.SequenceNumber) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/stop_sending_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stop_sending_frame.go new file mode 100644 index 00000000..f9a5d60b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stop_sending_frame.go @@ -0,0 +1,47 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A StopSendingFrame is a STOP_SENDING frame +type StopSendingFrame struct { + StreamID protocol.StreamID + ErrorCode protocol.ApplicationErrorCode +} + +// parseStopSendingFrame parses a STOP_SENDING frame +func parseStopSendingFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StopSendingFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + streamID, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + errorCode, err := utils.BigEndian.ReadUint16(r) + if err != nil { + return nil, err + } + + return &StopSendingFrame{ + StreamID: protocol.StreamID(streamID), + ErrorCode: protocol.ApplicationErrorCode(errorCode), + }, nil +} + +// Length of a written frame +func (f *StopSendingFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.StreamID)) + 2 +} + +func (f *StopSendingFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + b.WriteByte(0x5) + utils.WriteVarInt(b, uint64(f.StreamID)) + utils.BigEndian.WriteUint16(b, uint16(f.ErrorCode)) + return nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_data_blocked_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_data_blocked_frame.go new file mode 100644 index 00000000..9f2e90be --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_data_blocked_frame.go @@ -0,0 +1,46 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A StreamDataBlockedFrame is a STREAM_DATA_BLOCKED frame +type StreamDataBlockedFrame struct { + StreamID protocol.StreamID + DataLimit protocol.ByteCount +} + +func parseStreamDataBlockedFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StreamDataBlockedFrame, error) { + if _, err := r.ReadByte(); err != nil { + return nil, err + } + + sid, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + offset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + + return &StreamDataBlockedFrame{ + StreamID: protocol.StreamID(sid), + DataLimit: protocol.ByteCount(offset), + }, nil +} + +func (f *StreamDataBlockedFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + b.WriteByte(0x15) + utils.WriteVarInt(b, uint64(f.StreamID)) + utils.WriteVarInt(b, uint64(f.DataLimit)) + return nil +} + +// Length of a written frame +func (f *StreamDataBlockedFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(uint64(f.StreamID)) + utils.VarIntLen(uint64(f.DataLimit)) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame.go new file mode 100644 index 00000000..dfc1d1ad --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/stream_frame.go @@ -0,0 +1,168 @@ +package wire + +import ( + "bytes" + "errors" + "io" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A StreamFrame of QUIC +type StreamFrame struct { + StreamID protocol.StreamID + FinBit bool + DataLenPresent bool + Offset protocol.ByteCount + Data []byte +} + +func parseStreamFrame(r *bytes.Reader, version protocol.VersionNumber) (*StreamFrame, error) { + typeByte, err := r.ReadByte() + if err != nil { + return nil, err + } + + hasOffset := typeByte&0x4 > 0 + frame := &StreamFrame{ + FinBit: typeByte&0x1 > 0, + DataLenPresent: typeByte&0x2 > 0, + } + + streamID, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + frame.StreamID = protocol.StreamID(streamID) + if hasOffset { + offset, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + frame.Offset = protocol.ByteCount(offset) + } + + var dataLen uint64 + if frame.DataLenPresent { + var err error + dataLen, err = utils.ReadVarInt(r) + if err != nil { + return nil, err + } + // shortcut to prevent the unnecessary allocation of dataLen bytes + // if the dataLen is larger than the remaining length of the packet + // reading the packet contents would result in EOF when attempting to READ + if dataLen > uint64(r.Len()) { + return nil, io.EOF + } + } else { + // The rest of the packet is data + dataLen = uint64(r.Len()) + } + if dataLen != 0 { + frame.Data = make([]byte, dataLen) + if _, err := io.ReadFull(r, frame.Data); err != nil { + // this should never happen, since we already checked the dataLen earlier + return nil, err + } + } + if frame.Offset+frame.DataLen() > protocol.MaxByteCount { + return nil, qerr.Error(qerr.FrameEncodingError, "stream data overflows maximum offset") + } + return frame, nil +} + +// Write writes a STREAM frame +func (f *StreamFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error { + if len(f.Data) == 0 && !f.FinBit { + return errors.New("StreamFrame: attempting to write empty frame without FIN") + } + + typeByte := byte(0x8) + if f.FinBit { + typeByte ^= 0x1 + } + hasOffset := f.Offset != 0 + if f.DataLenPresent { + typeByte ^= 0x2 + } + if hasOffset { + typeByte ^= 0x4 + } + b.WriteByte(typeByte) + utils.WriteVarInt(b, uint64(f.StreamID)) + if hasOffset { + utils.WriteVarInt(b, uint64(f.Offset)) + } + if f.DataLenPresent { + utils.WriteVarInt(b, uint64(f.DataLen())) + } + b.Write(f.Data) + return nil +} + +// Length returns the total length of the STREAM frame +func (f *StreamFrame) Length(version protocol.VersionNumber) protocol.ByteCount { + length := 1 + utils.VarIntLen(uint64(f.StreamID)) + if f.Offset != 0 { + length += utils.VarIntLen(uint64(f.Offset)) + } + if f.DataLenPresent { + length += utils.VarIntLen(uint64(f.DataLen())) + } + return length + f.DataLen() +} + +// DataLen gives the length of data in bytes +func (f *StreamFrame) DataLen() protocol.ByteCount { + return protocol.ByteCount(len(f.Data)) +} + +// MaxDataLen returns the maximum data length +// If 0 is returned, writing will fail (a STREAM frame must contain at least 1 byte of data). +func (f *StreamFrame) MaxDataLen(maxSize protocol.ByteCount, version protocol.VersionNumber) protocol.ByteCount { + headerLen := 1 + utils.VarIntLen(uint64(f.StreamID)) + if f.Offset != 0 { + headerLen += utils.VarIntLen(uint64(f.Offset)) + } + if f.DataLenPresent { + // pretend that the data size will be 1 bytes + // if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards + headerLen++ + } + if headerLen > maxSize { + return 0 + } + maxDataLen := maxSize - headerLen + if f.DataLenPresent && utils.VarIntLen(uint64(maxDataLen)) != 1 { + maxDataLen-- + } + return maxDataLen +} + +// MaybeSplitOffFrame splits a frame such that it is not bigger than n bytes. +// If n >= len(frame), nil is returned and nothing is modified. +func (f *StreamFrame) MaybeSplitOffFrame(maxSize protocol.ByteCount, version protocol.VersionNumber) (*StreamFrame, error) { + if maxSize >= f.Length(version) { + return nil, nil + } + + n := f.MaxDataLen(maxSize, version) + if n == 0 { + return nil, errors.New("too small") + } + newFrame := &StreamFrame{ + FinBit: false, + StreamID: f.StreamID, + Offset: f.Offset, + Data: f.Data[:n], + DataLenPresent: f.DataLenPresent, + } + + f.Data = f.Data[n:] + f.Offset += n + + return newFrame, nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/streams_blocked_frame.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/streams_blocked_frame.go new file mode 100644 index 00000000..b41d68f1 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/streams_blocked_frame.go @@ -0,0 +1,52 @@ +package wire + +import ( + "bytes" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// A StreamsBlockedFrame is a STREAMS_BLOCKED frame +type StreamsBlockedFrame struct { + Type protocol.StreamType + StreamLimit uint64 +} + +func parseStreamsBlockedFrame(r *bytes.Reader, _ protocol.VersionNumber) (*StreamsBlockedFrame, error) { + typeByte, err := r.ReadByte() + if err != nil { + return nil, err + } + + f := &StreamsBlockedFrame{} + switch typeByte { + case 0x16: + f.Type = protocol.StreamTypeBidi + case 0x17: + f.Type = protocol.StreamTypeUni + } + streamLimit, err := utils.ReadVarInt(r) + if err != nil { + return nil, err + } + f.StreamLimit = streamLimit + + return f, nil +} + +func (f *StreamsBlockedFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error { + switch f.Type { + case protocol.StreamTypeBidi: + b.WriteByte(0x16) + case protocol.StreamTypeUni: + b.WriteByte(0x17) + } + utils.WriteVarInt(b, f.StreamLimit) + return nil +} + +// Length of a written frame +func (f *StreamsBlockedFrame) Length(_ protocol.VersionNumber) protocol.ByteCount { + return 1 + utils.VarIntLen(f.StreamLimit) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/version_negotiation.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/version_negotiation.go new file mode 100644 index 00000000..bfc27af7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/version_negotiation.go @@ -0,0 +1,31 @@ +package wire + +import ( + "bytes" + "crypto/rand" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" +) + +// ComposeVersionNegotiation composes a Version Negotiation +func ComposeVersionNegotiation(destConnID, srcConnID protocol.ConnectionID, versions []protocol.VersionNumber) ([]byte, error) { + greasedVersions := protocol.GetGreasedVersions(versions) + expectedLen := 1 /* type byte */ + 4 /* version field */ + 1 /* connection ID length field */ + destConnID.Len() + srcConnID.Len() + len(greasedVersions)*4 + buf := bytes.NewBuffer(make([]byte, 0, expectedLen)) + r := make([]byte, 1) + _, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here. + buf.WriteByte(r[0] | 0xc0) + utils.BigEndian.WriteUint32(buf, 0) // version 0 + connIDLen, err := encodeConnIDLen(destConnID, srcConnID) + if err != nil { + return nil, err + } + buf.WriteByte(connIDLen) + buf.Write(destConnID) + buf.Write(srcConnID) + for _, v := range greasedVersions { + utils.BigEndian.WriteUint32(buf, uint32(v)) + } + return buf.Bytes(), nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/mockgen.go b/vendor/github.com/lucas-clemente/quic-go/mockgen.go new file mode 100644 index 00000000..1a882c35 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/mockgen.go @@ -0,0 +1,21 @@ +package quic + +//go:generate sh -c "./mockgen_private.sh quic mock_stream_internal_test.go github.com/lucas-clemente/quic-go streamI" +//go:generate sh -c "./mockgen_private.sh quic mock_crypto_stream_test.go github.com/lucas-clemente/quic-go cryptoStream" +//go:generate sh -c "./mockgen_private.sh quic mock_receive_stream_internal_test.go github.com/lucas-clemente/quic-go receiveStreamI" +//go:generate sh -c "./mockgen_private.sh quic mock_send_stream_internal_test.go github.com/lucas-clemente/quic-go sendStreamI" +//go:generate sh -c "./mockgen_private.sh quic mock_stream_sender_test.go github.com/lucas-clemente/quic-go streamSender" +//go:generate sh -c "./mockgen_private.sh quic mock_stream_getter_test.go github.com/lucas-clemente/quic-go streamGetter" +//go:generate sh -c "./mockgen_private.sh quic mock_crypto_data_handler_test.go github.com/lucas-clemente/quic-go cryptoDataHandler" +//go:generate sh -c "./mockgen_private.sh quic mock_frame_source_test.go github.com/lucas-clemente/quic-go frameSource" +//go:generate sh -c "./mockgen_private.sh quic mock_ack_frame_source_test.go github.com/lucas-clemente/quic-go ackFrameSource" +//go:generate sh -c "./mockgen_private.sh quic mock_stream_manager_test.go github.com/lucas-clemente/quic-go streamManager" +//go:generate sh -c "./mockgen_private.sh quic mock_sealing_manager_test.go github.com/lucas-clemente/quic-go sealingManager" +//go:generate sh -c "./mockgen_private.sh quic mock_unpacker_test.go github.com/lucas-clemente/quic-go unpacker" +//go:generate sh -c "./mockgen_private.sh quic mock_packer_test.go github.com/lucas-clemente/quic-go packer" +//go:generate sh -c "./mockgen_private.sh quic mock_session_runner_test.go github.com/lucas-clemente/quic-go sessionRunner" +//go:generate sh -c "./mockgen_private.sh quic mock_quic_session_test.go github.com/lucas-clemente/quic-go quicSession" +//go:generate sh -c "./mockgen_private.sh quic mock_packet_handler_test.go github.com/lucas-clemente/quic-go packetHandler" +//go:generate sh -c "./mockgen_private.sh quic mock_unknown_packet_handler_test.go github.com/lucas-clemente/quic-go unknownPacketHandler" +//go:generate sh -c "./mockgen_private.sh quic mock_packet_handler_manager_test.go github.com/lucas-clemente/quic-go packetHandlerManager" +//go:generate sh -c "./mockgen_private.sh quic mock_multiplexer_test.go github.com/lucas-clemente/quic-go multiplexer" diff --git a/vendor/github.com/lucas-clemente/quic-go/mockgen_private.sh b/vendor/github.com/lucas-clemente/quic-go/mockgen_private.sh new file mode 100755 index 00000000..0ba5f64e --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/mockgen_private.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Mockgen refuses to generate mocks private types. +# This script copies the quic package to a temporary directory, and adds an public alias for the private type. +# It then creates a mock for this public (alias) type. + +TEMP_DIR=$(mktemp -d) +mkdir -p $TEMP_DIR/src/github.com/lucas-clemente/quic-go/ + +# uppercase the name of the interface +INTERFACE_NAME="$(tr '[:lower:]' '[:upper:]' <<< ${4:0:1})${4:1}" + +# copy all .go files to a temporary directory +rsync -r --exclude 'vendor' --include='*.go' --include '*/' --exclude '*' $GOPATH/src/github.com/lucas-clemente/quic-go/ $TEMP_DIR/src/github.com/lucas-clemente/quic-go/ + +# create a public alias for the interface, so that mockgen can process it +echo -e "package $1\n" > $TEMP_DIR/src/github.com/lucas-clemente/quic-go/mockgen_interface.go +echo "type $INTERFACE_NAME = $4" >> $TEMP_DIR/src/github.com/lucas-clemente/quic-go/mockgen_interface.go + +export GOPATH="$TEMP_DIR:$GOPATH" + +mockgen -package $1 -self_package $1 -destination $2 $3 $INTERFACE_NAME + +# mockgen imports quic-go as 'import quic_go github.com/lucas_clemente/quic-go' +sed -i '' 's/quic_go.//g' $2 +goimports -w $2 + +rm -r "$TEMP_DIR" diff --git a/vendor/github.com/lucas-clemente/quic-go/multiplexer.go b/vendor/github.com/lucas-clemente/quic-go/multiplexer.go new file mode 100644 index 00000000..eeffca53 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/multiplexer.go @@ -0,0 +1,89 @@ +package quic + +import ( + "bytes" + "fmt" + "net" + "sync" + + "github.com/lucas-clemente/quic-go/internal/utils" +) + +var ( + connMuxerOnce sync.Once + connMuxer multiplexer +) + +type multiplexer interface { + AddConn(c net.PacketConn, connIDLen int, statelessResetKey []byte) (packetHandlerManager, error) + RemoveConn(net.PacketConn) error +} + +type connManager struct { + connIDLen int + statelessResetKey []byte + manager packetHandlerManager +} + +// The connMultiplexer listens on multiple net.PacketConns and dispatches +// incoming packets to the session handler. +type connMultiplexer struct { + mutex sync.Mutex + + conns map[net.PacketConn]connManager + newPacketHandlerManager func(net.PacketConn, int, []byte, utils.Logger) packetHandlerManager // so it can be replaced in the tests + + logger utils.Logger +} + +var _ multiplexer = &connMultiplexer{} + +func getMultiplexer() multiplexer { + connMuxerOnce.Do(func() { + connMuxer = &connMultiplexer{ + conns: make(map[net.PacketConn]connManager), + logger: utils.DefaultLogger.WithPrefix("muxer"), + newPacketHandlerManager: newPacketHandlerMap, + } + }) + return connMuxer +} + +func (m *connMultiplexer) AddConn( + c net.PacketConn, + connIDLen int, + statelessResetKey []byte, +) (packetHandlerManager, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + p, ok := m.conns[c] + if !ok { + manager := m.newPacketHandlerManager(c, connIDLen, statelessResetKey, m.logger) + p = connManager{ + connIDLen: connIDLen, + statelessResetKey: statelessResetKey, + manager: manager, + } + m.conns[c] = p + } + if p.connIDLen != connIDLen { + return nil, fmt.Errorf("cannot use %d byte connection IDs on a connection that is already using %d byte connction IDs", connIDLen, p.connIDLen) + } + if statelessResetKey != nil && !bytes.Equal(p.statelessResetKey, statelessResetKey) { + return nil, fmt.Errorf("cannot use different stateless reset keys on the same packet conn") + } + return p.manager, nil +} + +func (m *connMultiplexer) RemoveConn(c net.PacketConn) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + if _, ok := m.conns[c]; !ok { + return fmt.Errorf("cannote remove connection, connection is unknown") + } + + delete(m.conns, c) + return nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go b/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go new file mode 100644 index 00000000..0af6a407 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go @@ -0,0 +1,274 @@ +package quic + +import ( + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "errors" + "hash" + "net" + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// The packetHandlerMap stores packetHandlers, identified by connection ID. +// It is used: +// * by the server to store sessions +// * when multiplexing outgoing connections to store clients +type packetHandlerMap struct { + mutex sync.RWMutex + + conn net.PacketConn + connIDLen int + + handlers map[string] /* string(ConnectionID)*/ packetHandler + resetTokens map[[16]byte] /* stateless reset token */ packetHandler + server unknownPacketHandler + + listening chan struct{} // is closed when listen returns + closed bool + + deleteRetiredSessionsAfter time.Duration + + statelessResetEnabled bool + statelessResetHasher hash.Hash + + logger utils.Logger +} + +var _ packetHandlerManager = &packetHandlerMap{} + +func newPacketHandlerMap( + conn net.PacketConn, + connIDLen int, + statelessResetKey []byte, + logger utils.Logger, +) packetHandlerManager { + m := &packetHandlerMap{ + conn: conn, + connIDLen: connIDLen, + listening: make(chan struct{}), + handlers: make(map[string]packetHandler), + resetTokens: make(map[[16]byte]packetHandler), + deleteRetiredSessionsAfter: protocol.RetiredConnectionIDDeleteTimeout, + statelessResetEnabled: len(statelessResetKey) > 0, + statelessResetHasher: hmac.New(sha256.New, statelessResetKey), + logger: logger, + } + go m.listen() + return m +} + +func (h *packetHandlerMap) Add(id protocol.ConnectionID, handler packetHandler) { + h.mutex.Lock() + h.handlers[string(id)] = handler + h.mutex.Unlock() +} + +func (h *packetHandlerMap) Remove(id protocol.ConnectionID) { + h.removeByConnectionIDAsString(string(id)) +} + +func (h *packetHandlerMap) removeByConnectionIDAsString(id string) { + h.mutex.Lock() + delete(h.handlers, id) + h.mutex.Unlock() +} + +func (h *packetHandlerMap) Retire(id protocol.ConnectionID) { + h.retireByConnectionIDAsString(string(id)) +} + +func (h *packetHandlerMap) retireByConnectionIDAsString(id string) { + time.AfterFunc(h.deleteRetiredSessionsAfter, func() { + h.removeByConnectionIDAsString(id) + }) +} + +func (h *packetHandlerMap) AddResetToken(token [16]byte, handler packetHandler) { + h.mutex.Lock() + h.resetTokens[token] = handler + h.mutex.Unlock() +} + +func (h *packetHandlerMap) RemoveResetToken(token [16]byte) { + h.mutex.Lock() + delete(h.resetTokens, token) + h.mutex.Unlock() +} + +func (h *packetHandlerMap) SetServer(s unknownPacketHandler) { + h.mutex.Lock() + h.server = s + h.mutex.Unlock() +} + +func (h *packetHandlerMap) CloseServer() { + h.mutex.Lock() + h.server = nil + var wg sync.WaitGroup + for id, handler := range h.handlers { + if handler.getPerspective() == protocol.PerspectiveServer { + wg.Add(1) + go func(id string, handler packetHandler) { + // session.Close() blocks until the CONNECTION_CLOSE has been sent and the run-loop has stopped + _ = handler.Close() + h.retireByConnectionIDAsString(id) + wg.Done() + }(id, handler) + } + } + h.mutex.Unlock() + wg.Wait() +} + +// Close the underlying connection and wait until listen() has returned. +func (h *packetHandlerMap) Close() error { + if err := h.conn.Close(); err != nil { + return err + } + <-h.listening // wait until listening returns + return nil +} + +func (h *packetHandlerMap) close(e error) error { + h.mutex.Lock() + if h.closed { + h.mutex.Unlock() + return nil + } + h.closed = true + + var wg sync.WaitGroup + for _, handler := range h.handlers { + wg.Add(1) + go func(handler packetHandler) { + handler.destroy(e) + wg.Done() + }(handler) + } + + if h.server != nil { + h.server.closeWithError(e) + } + h.mutex.Unlock() + wg.Wait() + return getMultiplexer().RemoveConn(h.conn) +} + +func (h *packetHandlerMap) listen() { + defer close(h.listening) + for { + buffer := getPacketBuffer() + data := buffer.Slice + // The packet size should not exceed protocol.MaxReceivePacketSize bytes + // If it does, we only read a truncated packet, which will then end up undecryptable + n, addr, err := h.conn.ReadFrom(data) + if err != nil { + h.close(err) + return + } + h.handlePacket(addr, buffer, data[:n]) + } +} + +func (h *packetHandlerMap) handlePacket( + addr net.Addr, + buffer *packetBuffer, + data []byte, +) { + connID, err := wire.ParseConnectionID(data, h.connIDLen) + if err != nil { + h.logger.Debugf("error parsing connection ID on packet from %s: %s", addr, err) + return + } + rcvTime := time.Now() + + h.mutex.RLock() + defer h.mutex.RUnlock() + + if isStatelessReset := h.maybeHandleStatelessReset(data); isStatelessReset { + return + } + + handler, handlerFound := h.handlers[string(connID)] + + p := &receivedPacket{ + remoteAddr: addr, + rcvTime: rcvTime, + buffer: buffer, + data: data, + } + if handlerFound { // existing session + handler.handlePacket(p) + return + } + if data[0]&0x80 == 0 { + go h.maybeSendStatelessReset(p, connID) + return + } + if h.server == nil { // no server set + h.logger.Debugf("received a packet with an unexpected connection ID %s", connID) + return + } + h.server.handlePacket(p) +} + +func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { + // stateless resets are always short header packets + if data[0]&0x80 != 0 { + return false + } + if len(data) < protocol.MinStatelessResetSize { + return false + } + + var token [16]byte + copy(token[:], data[len(data)-16:]) + if sess, ok := h.resetTokens[token]; ok { + h.logger.Debugf("Received a stateless retry with token %#x. Closing session.", token) + go sess.destroy(errors.New("received a stateless reset")) + return true + } + return false +} + +func (h *packetHandlerMap) GetStatelessResetToken(connID protocol.ConnectionID) [16]byte { + var token [16]byte + if !h.statelessResetEnabled { + // Return a random stateless reset token. + // This token will be sent in the server's transport parameters. + // By using a random token, an off-path attacker won't be able to disrupt the connection. + rand.Read(token[:]) + return token + } + h.statelessResetHasher.Write(connID.Bytes()) + copy(token[:], h.statelessResetHasher.Sum(nil)) + h.statelessResetHasher.Reset() + return token +} + +func (h *packetHandlerMap) maybeSendStatelessReset(p *receivedPacket, connID protocol.ConnectionID) { + defer p.buffer.Release() + if !h.statelessResetEnabled { + return + } + // Don't send a stateless reset in response to very small packets. + // This includes packets that could be stateless resets. + if len(p.data) <= protocol.MinStatelessResetSize { + return + } + token := h.GetStatelessResetToken(connID) + h.logger.Debugf("Sending stateless reset to %s (connection ID: %s). Token: %#x", p.remoteAddr, connID, token) + data := make([]byte, 23) + rand.Read(data) + data[0] = (data[0] & 0x7f) | 0x40 + data = append(data, token[:]...) + if _, err := h.conn.WriteTo(data, p.remoteAddr); err != nil { + h.logger.Debugf("Error sending Stateless Reset: %s", err) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/packet_packer.go b/vendor/github.com/lucas-clemente/quic-go/packet_packer.go new file mode 100644 index 00000000..7fae340e --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/packet_packer.go @@ -0,0 +1,491 @@ +package quic + +import ( + "bytes" + "errors" + "fmt" + "net" + "time" + + "github.com/lucas-clemente/quic-go/internal/ackhandler" + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type packer interface { + PackPacket() (*packedPacket, error) + MaybePackAckPacket() (*packedPacket, error) + PackRetransmission(packet *ackhandler.Packet) ([]*packedPacket, error) + PackConnectionClose(*wire.ConnectionCloseFrame) (*packedPacket, error) + + HandleTransportParameters(*handshake.TransportParameters) + SetToken([]byte) + ChangeDestConnectionID(protocol.ConnectionID) +} + +type packedPacket struct { + header *wire.ExtendedHeader + raw []byte + frames []wire.Frame + + buffer *packetBuffer +} + +func (p *packedPacket) EncryptionLevel() protocol.EncryptionLevel { + if !p.header.IsLongHeader { + return protocol.Encryption1RTT + } + switch p.header.Type { + case protocol.PacketTypeInitial: + return protocol.EncryptionInitial + case protocol.PacketTypeHandshake: + return protocol.EncryptionHandshake + default: + return protocol.EncryptionUnspecified + } +} + +func (p *packedPacket) IsRetransmittable() bool { + return ackhandler.HasRetransmittableFrames(p.frames) +} + +func (p *packedPacket) ToAckHandlerPacket() *ackhandler.Packet { + return &ackhandler.Packet{ + PacketNumber: p.header.PacketNumber, + PacketType: p.header.Type, + Frames: p.frames, + Length: protocol.ByteCount(len(p.raw)), + EncryptionLevel: p.EncryptionLevel(), + SendTime: time.Now(), + } +} + +func getMaxPacketSize(addr net.Addr) protocol.ByteCount { + maxSize := protocol.ByteCount(protocol.MinInitialPacketSize) + // If this is not a UDP address, we don't know anything about the MTU. + // Use the minimum size of an Initial packet as the max packet size. + if udpAddr, ok := addr.(*net.UDPAddr); ok { + // If ip is not an IPv4 address, To4 returns nil. + // Note that there might be some corner cases, where this is not correct. + // See https://stackoverflow.com/questions/22751035/golang-distinguish-ipv4-ipv6. + if udpAddr.IP.To4() == nil { + maxSize = protocol.MaxPacketSizeIPv6 + } else { + maxSize = protocol.MaxPacketSizeIPv4 + } + } + return maxSize +} + +type packetNumberManager interface { + PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) + PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber +} + +type sealingManager interface { + GetSealer() (protocol.EncryptionLevel, handshake.Sealer) + GetSealerWithEncryptionLevel(protocol.EncryptionLevel) (handshake.Sealer, error) +} + +type frameSource interface { + AppendStreamFrames([]wire.Frame, protocol.ByteCount) []wire.Frame + AppendControlFrames([]wire.Frame, protocol.ByteCount) ([]wire.Frame, protocol.ByteCount) +} + +type ackFrameSource interface { + GetAckFrame(protocol.EncryptionLevel) *wire.AckFrame +} + +type packetPacker struct { + destConnID protocol.ConnectionID + srcConnID protocol.ConnectionID + + perspective protocol.Perspective + version protocol.VersionNumber + cryptoSetup sealingManager + + initialStream cryptoStream + handshakeStream cryptoStream + + token []byte + + pnManager packetNumberManager + framer frameSource + acks ackFrameSource + + maxPacketSize protocol.ByteCount + numNonRetransmittableAcks int +} + +var _ packer = &packetPacker{} + +func newPacketPacker( + destConnID protocol.ConnectionID, + srcConnID protocol.ConnectionID, + initialStream cryptoStream, + handshakeStream cryptoStream, + packetNumberManager packetNumberManager, + remoteAddr net.Addr, // only used for determining the max packet size + cryptoSetup sealingManager, + framer frameSource, + acks ackFrameSource, + perspective protocol.Perspective, + version protocol.VersionNumber, +) *packetPacker { + return &packetPacker{ + cryptoSetup: cryptoSetup, + destConnID: destConnID, + srcConnID: srcConnID, + initialStream: initialStream, + handshakeStream: handshakeStream, + perspective: perspective, + version: version, + framer: framer, + acks: acks, + pnManager: packetNumberManager, + maxPacketSize: getMaxPacketSize(remoteAddr), + } +} + +// PackConnectionClose packs a packet that ONLY contains a ConnectionCloseFrame +func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) { + frames := []wire.Frame{ccf} + encLevel, sealer := p.cryptoSetup.GetSealer() + header := p.getHeader(encLevel) + return p.writeAndSealPacket(header, frames, encLevel, sealer) +} + +func (p *packetPacker) MaybePackAckPacket() (*packedPacket, error) { + ack := p.acks.GetAckFrame(protocol.Encryption1RTT) + if ack == nil { + return nil, nil + } + // TODO(#1534): only pack ACKs with the right encryption level + encLevel, sealer := p.cryptoSetup.GetSealer() + header := p.getHeader(encLevel) + frames := []wire.Frame{ack} + return p.writeAndSealPacket(header, frames, encLevel, sealer) +} + +// PackRetransmission packs a retransmission +// For packets sent after completion of the handshake, it might happen that 2 packets have to be sent. +// This can happen e.g. when a longer packet number is used in the header. +func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedPacket, error) { + var controlFrames []wire.Frame + var streamFrames []*wire.StreamFrame + for _, f := range packet.Frames { + // CRYPTO frames are treated as control frames here. + // Since we're making sure that the header can never be larger for a retransmission, + // we never have to split CRYPTO frames. + if sf, ok := f.(*wire.StreamFrame); ok { + sf.DataLenPresent = true + streamFrames = append(streamFrames, sf) + } else { + controlFrames = append(controlFrames, f) + } + } + + var packets []*packedPacket + encLevel := packet.EncryptionLevel + sealer, err := p.cryptoSetup.GetSealerWithEncryptionLevel(encLevel) + if err != nil { + return nil, err + } + for len(controlFrames) > 0 || len(streamFrames) > 0 { + var frames []wire.Frame + var length protocol.ByteCount + + header := p.getHeader(encLevel) + headerLen := header.GetLength(p.version) + maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLen + + for len(controlFrames) > 0 { + frame := controlFrames[0] + frameLen := frame.Length(p.version) + if length+frameLen > maxSize { + break + } + length += frameLen + frames = append(frames, frame) + controlFrames = controlFrames[1:] + } + + for len(streamFrames) > 0 && length+protocol.MinStreamFrameSize < maxSize { + frame := streamFrames[0] + frame.DataLenPresent = false + frameToAdd := frame + + sf, err := frame.MaybeSplitOffFrame(maxSize-length, p.version) + if err != nil { + return nil, err + } + if sf != nil { + frameToAdd = sf + } else { + streamFrames = streamFrames[1:] + } + frame.DataLenPresent = true + length += frameToAdd.Length(p.version) + frames = append(frames, frameToAdd) + } + if sf, ok := frames[len(frames)-1].(*wire.StreamFrame); ok { + sf.DataLenPresent = false + } + p, err := p.writeAndSealPacket(header, frames, encLevel, sealer) + if err != nil { + return nil, err + } + packets = append(packets, p) + } + return packets, nil +} + +// PackPacket packs a new packet +// the other controlFrames are sent in the next packet, but might be queued and sent in the next packet if the packet would overflow MaxPacketSize otherwise +func (p *packetPacker) PackPacket() (*packedPacket, error) { + packet, err := p.maybePackCryptoPacket() + if err != nil { + return nil, err + } + if packet != nil { + return packet, nil + } + + encLevel, sealer := p.cryptoSetup.GetSealer() + header := p.getHeader(encLevel) + headerLen := header.GetLength(p.version) + if err != nil { + return nil, err + } + + maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLen + frames, err := p.composeNextPacket(maxSize) + if err != nil { + return nil, err + } + + // Check if we have enough frames to send + if len(frames) == 0 { + return nil, nil + } + // check if this packet only contains an ACK + if !ackhandler.HasRetransmittableFrames(frames) { + if p.numNonRetransmittableAcks >= protocol.MaxNonRetransmittableAcks { + frames = append(frames, &wire.PingFrame{}) + p.numNonRetransmittableAcks = 0 + } else { + p.numNonRetransmittableAcks++ + } + } else { + p.numNonRetransmittableAcks = 0 + } + + return p.writeAndSealPacket(header, frames, encLevel, sealer) +} + +func (p *packetPacker) maybePackCryptoPacket() (*packedPacket, error) { + var s cryptoStream + var encLevel protocol.EncryptionLevel + + hasData := p.initialStream.HasData() + ack := p.acks.GetAckFrame(protocol.EncryptionInitial) + if hasData || ack != nil { + s = p.initialStream + encLevel = protocol.EncryptionInitial + } else { + hasData = p.handshakeStream.HasData() + ack = p.acks.GetAckFrame(protocol.EncryptionHandshake) + if hasData || ack != nil { + s = p.handshakeStream + encLevel = protocol.EncryptionHandshake + } + } + if s == nil { + return nil, nil + } + sealer, err := p.cryptoSetup.GetSealerWithEncryptionLevel(encLevel) + if err != nil { + // The sealer + return nil, err + } + + hdr := p.getHeader(encLevel) + hdrLen := hdr.GetLength(p.version) + var length protocol.ByteCount + frames := make([]wire.Frame, 0, 2) + if ack != nil { + frames = append(frames, ack) + length += ack.Length(p.version) + } + if hasData { + cf := s.PopCryptoFrame(p.maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead()) - length) + frames = append(frames, cf) + } + return p.writeAndSealPacket(hdr, frames, encLevel, sealer) +} + +func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount) ([]wire.Frame, error) { + var length protocol.ByteCount + var frames []wire.Frame + + // ACKs need to go first, so that the sentPacketHandler will recognize them + if ack := p.acks.GetAckFrame(protocol.Encryption1RTT); ack != nil { + frames = append(frames, ack) + length += ack.Length(p.version) + } + + var lengthAdded protocol.ByteCount + frames, lengthAdded = p.framer.AppendControlFrames(frames, maxFrameSize-length) + length += lengthAdded + + // temporarily increase the maxFrameSize by the (minimum) length of the DataLen field + // this leads to a properly sized packet in all cases, since we do all the packet length calculations with STREAM frames that have the DataLen set + // however, for the last STREAM frame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size + // the length is encoded to either 1 or 2 bytes + maxFrameSize++ + + frames = p.framer.AppendStreamFrames(frames, maxFrameSize-length) + if len(frames) > 0 { + lastFrame := frames[len(frames)-1] + if sf, ok := lastFrame.(*wire.StreamFrame); ok { + sf.DataLenPresent = false + } + } + return frames, nil +} + +func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.ExtendedHeader { + pn, pnLen := p.pnManager.PeekPacketNumber(encLevel) + header := &wire.ExtendedHeader{} + header.PacketNumber = pn + header.PacketNumberLen = pnLen + header.Version = p.version + header.DestConnectionID = p.destConnID + + if encLevel != protocol.Encryption1RTT { + header.IsLongHeader = true + // Always send Initial and Handshake packets with the maximum packet number length. + // This simplifies retransmissions: Since the header can't get any larger, + // we don't need to split CRYPTO frames. + header.PacketNumberLen = protocol.PacketNumberLen4 + header.SrcConnectionID = p.srcConnID + // Set the length to the maximum packet size. + // Since it is encoded as a varint, this guarantees us that the header will end up at most as big as GetLength() returns. + header.Length = p.maxPacketSize + switch encLevel { + case protocol.EncryptionInitial: + header.Type = protocol.PacketTypeInitial + case protocol.EncryptionHandshake: + header.Type = protocol.PacketTypeHandshake + } + } + + return header +} + +func (p *packetPacker) writeAndSealPacket( + header *wire.ExtendedHeader, + frames []wire.Frame, + encLevel protocol.EncryptionLevel, + sealer handshake.Sealer, +) (*packedPacket, error) { + packetBuffer := getPacketBuffer() + buffer := bytes.NewBuffer(packetBuffer.Slice[:0]) + + addPaddingForInitial := p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial + + if header.IsLongHeader { + if p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial { + header.Token = p.token + } + if addPaddingForInitial { + headerLen := header.GetLength(p.version) + header.Length = protocol.ByteCount(header.PacketNumberLen) + protocol.MinInitialPacketSize - headerLen + } else { + // long header packets always use 4 byte packet number, so we never need to pad short payloads + length := protocol.ByteCount(sealer.Overhead()) + protocol.ByteCount(header.PacketNumberLen) + for _, frame := range frames { + length += frame.Length(p.version) + } + header.Length = length + } + } + + if err := header.Write(buffer, p.version); err != nil { + return nil, err + } + payloadOffset := buffer.Len() + + // write all frames but the last one + for _, frame := range frames[:len(frames)-1] { + if err := frame.Write(buffer, p.version); err != nil { + return nil, err + } + } + lastFrame := frames[len(frames)-1] + if addPaddingForInitial { + // when appending padding, we need to make sure that the last STREAM frames has the data length set + if sf, ok := lastFrame.(*wire.StreamFrame); ok { + sf.DataLenPresent = true + } + } else { + payloadLen := buffer.Len() - payloadOffset + int(lastFrame.Length(p.version)) + if paddingLen := 4 - int(header.PacketNumberLen) - payloadLen; paddingLen > 0 { + // Pad the packet such that packet number length + payload length is 4 bytes. + // This is needed to enable the peer to get a 16 byte sample for header protection. + buffer.Write(bytes.Repeat([]byte{0}, paddingLen)) + } + } + if err := lastFrame.Write(buffer, p.version); err != nil { + return nil, err + } + + if addPaddingForInitial { + paddingLen := protocol.MinInitialPacketSize - sealer.Overhead() - buffer.Len() + if paddingLen > 0 { + buffer.Write(bytes.Repeat([]byte{0}, paddingLen)) + } + } + + if size := protocol.ByteCount(buffer.Len() + sealer.Overhead()); size > p.maxPacketSize { + return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize) + } + + raw := buffer.Bytes() + _ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], header.PacketNumber, raw[:payloadOffset]) + raw = raw[0 : buffer.Len()+sealer.Overhead()] + + pnOffset := payloadOffset - int(header.PacketNumberLen) + sealer.EncryptHeader( + raw[pnOffset+4:pnOffset+4+16], + &raw[0], + raw[pnOffset:payloadOffset], + ) + + num := p.pnManager.PopPacketNumber(encLevel) + if num != header.PacketNumber { + return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match") + } + return &packedPacket{ + header: header, + raw: raw, + frames: frames, + buffer: packetBuffer, + }, nil +} + +func (p *packetPacker) ChangeDestConnectionID(connID protocol.ConnectionID) { + p.destConnID = connID +} + +func (p *packetPacker) SetToken(token []byte) { + p.token = token +} + +func (p *packetPacker) HandleTransportParameters(params *handshake.TransportParameters) { + if params.MaxPacketSize != 0 { + p.maxPacketSize = utils.MinByteCount(p.maxPacketSize, params.MaxPacketSize) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go b/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go new file mode 100644 index 00000000..f3b5a2f7 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go @@ -0,0 +1,102 @@ +package quic + +import ( + "bytes" + "fmt" + + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type unpackedPacket struct { + packetNumber protocol.PacketNumber // the decoded packet number + hdr *wire.ExtendedHeader + encryptionLevel protocol.EncryptionLevel + data []byte +} + +// The packetUnpacker unpacks QUIC packets. +type packetUnpacker struct { + cs handshake.CryptoSetup + + largestRcvdPacketNumber protocol.PacketNumber + + version protocol.VersionNumber +} + +var _ unpacker = &packetUnpacker{} + +func newPacketUnpacker(cs handshake.CryptoSetup, version protocol.VersionNumber) unpacker { + return &packetUnpacker{ + cs: cs, + version: version, + } +} + +func (u *packetUnpacker) Unpack(hdr *wire.Header, data []byte) (*unpackedPacket, error) { + r := bytes.NewReader(data) + + var encLevel protocol.EncryptionLevel + switch hdr.Type { + case protocol.PacketTypeInitial: + encLevel = protocol.EncryptionInitial + case protocol.PacketTypeHandshake: + encLevel = protocol.EncryptionHandshake + default: + if hdr.IsLongHeader { + return nil, fmt.Errorf("unknown packet type: %s", hdr.Type) + } + encLevel = protocol.Encryption1RTT + } + opener, err := u.cs.GetOpener(encLevel) + if err != nil { + return nil, err + } + hdrLen := int(hdr.ParsedLen()) + if len(data) < hdrLen+4+16 { + return nil, fmt.Errorf("Packet too small. Expected at least 20 bytes after the header, got %d", len(data)-hdrLen) + } + // The packet number can be up to 4 bytes long, but we won't know the length until we decrypt it. + // 1. save a copy of the 4 bytes + origPNBytes := make([]byte, 4) + copy(origPNBytes, data[hdrLen:hdrLen+4]) + // 2. decrypt the header, assuming a 4 byte packet number + opener.DecryptHeader( + data[hdrLen+4:hdrLen+4+16], + &data[0], + data[hdrLen:hdrLen+4], + ) + // 3. parse the header (and learn the actual length of the packet number) + extHdr, err := hdr.ParseExtended(r, u.version) + if err != nil { + return nil, fmt.Errorf("error parsing extended header: %s", err) + } + extHdrLen := hdrLen + int(extHdr.PacketNumberLen) + // 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier + if extHdr.PacketNumberLen != protocol.PacketNumberLen4 { + copy(data[extHdrLen:hdrLen+4], origPNBytes[int(extHdr.PacketNumberLen):]) + } + + pn := protocol.DecodePacketNumber( + extHdr.PacketNumberLen, + u.largestRcvdPacketNumber, + extHdr.PacketNumber, + ) + + decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], pn, data[:extHdrLen]) + if err != nil { + return nil, err + } + + // Only do this after decrypting, so we are sure the packet is not attacker-controlled + u.largestRcvdPacketNumber = utils.MaxPacketNumber(u.largestRcvdPacketNumber, pn) + + return &unpackedPacket{ + hdr: extHdr, + packetNumber: pn, + encryptionLevel: encLevel, + data: decrypted, + }, nil +} diff --git a/vendor/github.com/lucas-clemente/quic-go/receive_stream.go b/vendor/github.com/lucas-clemente/quic-go/receive_stream.go new file mode 100644 index 00000000..de76335e --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/receive_stream.go @@ -0,0 +1,324 @@ +package quic + +import ( + "fmt" + "io" + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type receiveStreamI interface { + ReceiveStream + + handleStreamFrame(*wire.StreamFrame) error + handleResetStreamFrame(*wire.ResetStreamFrame) error + closeForShutdown(error) + getWindowUpdate() protocol.ByteCount +} + +type receiveStream struct { + mutex sync.Mutex + + streamID protocol.StreamID + + sender streamSender + + frameQueue *frameSorter + readOffset protocol.ByteCount + finalOffset protocol.ByteCount + + currentFrame []byte + currentFrameIsLast bool // is the currentFrame the last frame on this stream + readPosInFrame int + + closeForShutdownErr error + cancelReadErr error + resetRemotelyErr StreamError + + closedForShutdown bool // set when CloseForShutdown() is called + finRead bool // set once we read a frame with a FinBit + canceledRead bool // set when CancelRead() is called + resetRemotely bool // set when HandleResetStreamFrame() is called + + readChan chan struct{} + deadline time.Time + + flowController flowcontrol.StreamFlowController + version protocol.VersionNumber +} + +var _ ReceiveStream = &receiveStream{} +var _ receiveStreamI = &receiveStream{} + +func newReceiveStream( + streamID protocol.StreamID, + sender streamSender, + flowController flowcontrol.StreamFlowController, + version protocol.VersionNumber, +) *receiveStream { + return &receiveStream{ + streamID: streamID, + sender: sender, + flowController: flowController, + frameQueue: newFrameSorter(), + readChan: make(chan struct{}, 1), + finalOffset: protocol.MaxByteCount, + version: version, + } +} + +func (s *receiveStream) StreamID() protocol.StreamID { + return s.streamID +} + +// Read implements io.Reader. It is not thread safe! +func (s *receiveStream) Read(p []byte) (int, error) { + s.mutex.Lock() + completed, n, err := s.readImpl(p) + s.mutex.Unlock() + + if completed { + s.streamCompleted() + } + return n, err +} + +func (s *receiveStream) readImpl(p []byte) (bool /*stream completed */, int, error) { + if s.finRead { + return false, 0, io.EOF + } + if s.canceledRead { + return false, 0, s.cancelReadErr + } + if s.resetRemotely { + return false, 0, s.resetRemotelyErr + } + if s.closedForShutdown { + return false, 0, s.closeForShutdownErr + } + + bytesRead := 0 + for bytesRead < len(p) { + if s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) { + s.dequeueNextFrame() + } + if s.currentFrame == nil && bytesRead > 0 { + return false, bytesRead, s.closeForShutdownErr + } + + var deadlineTimer *utils.Timer + for { + // Stop waiting on errors + if s.closedForShutdown { + return false, bytesRead, s.closeForShutdownErr + } + if s.canceledRead { + return false, bytesRead, s.cancelReadErr + } + if s.resetRemotely { + return false, bytesRead, s.resetRemotelyErr + } + + deadline := s.deadline + if !deadline.IsZero() { + if !time.Now().Before(deadline) { + return false, bytesRead, errDeadline + } + if deadlineTimer == nil { + deadlineTimer = utils.NewTimer() + } + deadlineTimer.Reset(deadline) + } + + if s.currentFrame != nil || s.currentFrameIsLast { + break + } + + s.mutex.Unlock() + if deadline.IsZero() { + <-s.readChan + } else { + select { + case <-s.readChan: + case <-deadlineTimer.Chan(): + deadlineTimer.SetRead() + } + } + s.mutex.Lock() + if s.currentFrame == nil { + s.dequeueNextFrame() + } + } + + if bytesRead > len(p) { + return false, bytesRead, fmt.Errorf("BUG: bytesRead (%d) > len(p) (%d) in stream.Read", bytesRead, len(p)) + } + if s.readPosInFrame > len(s.currentFrame) { + return false, bytesRead, fmt.Errorf("BUG: readPosInFrame (%d) > frame.DataLen (%d) in stream.Read", s.readPosInFrame, len(s.currentFrame)) + } + + s.mutex.Unlock() + + m := copy(p[bytesRead:], s.currentFrame[s.readPosInFrame:]) + s.readPosInFrame += m + bytesRead += m + s.readOffset += protocol.ByteCount(m) + + s.mutex.Lock() + // when a RESET_STREAM was received, the was already informed about the final byteOffset for this stream + if !s.resetRemotely { + s.flowController.AddBytesRead(protocol.ByteCount(m)) + } + + if s.readPosInFrame >= len(s.currentFrame) && s.currentFrameIsLast { + s.finRead = true + return true, bytesRead, io.EOF + } + } + return false, bytesRead, nil +} + +func (s *receiveStream) dequeueNextFrame() { + var offset protocol.ByteCount + offset, s.currentFrame = s.frameQueue.Pop() + s.currentFrameIsLast = offset+protocol.ByteCount(len(s.currentFrame)) >= s.finalOffset + s.readPosInFrame = 0 +} + +func (s *receiveStream) CancelRead(errorCode protocol.ApplicationErrorCode) { + s.mutex.Lock() + completed := s.cancelReadImpl(errorCode) + s.mutex.Unlock() + + if completed { + s.streamCompleted() + } +} + +func (s *receiveStream) cancelReadImpl(errorCode protocol.ApplicationErrorCode) bool /* completed */ { + if s.finRead || s.canceledRead || s.resetRemotely { + return false + } + s.canceledRead = true + s.cancelReadErr = fmt.Errorf("Read on stream %d canceled with error code %d", s.streamID, errorCode) + s.signalRead() + s.sender.queueControlFrame(&wire.StopSendingFrame{ + StreamID: s.streamID, + ErrorCode: errorCode, + }) + // We're done with this stream if the final offset was already received. + return s.finalOffset != protocol.MaxByteCount +} + +func (s *receiveStream) handleStreamFrame(frame *wire.StreamFrame) error { + s.mutex.Lock() + completed, err := s.handleStreamFrameImpl(frame) + s.mutex.Unlock() + + if completed { + s.streamCompleted() + } + return err +} + +func (s *receiveStream) handleStreamFrameImpl(frame *wire.StreamFrame) (bool /* completed */, error) { + maxOffset := frame.Offset + frame.DataLen() + if err := s.flowController.UpdateHighestReceived(maxOffset, frame.FinBit); err != nil { + return false, err + } + if frame.FinBit { + s.finalOffset = maxOffset + } + if s.canceledRead { + return frame.FinBit, nil + } + if err := s.frameQueue.Push(frame.Data, frame.Offset); err != nil { + return false, err + } + s.signalRead() + return false, nil +} + +func (s *receiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame) error { + s.mutex.Lock() + completed, err := s.handleResetStreamFrameImpl(frame) + s.mutex.Unlock() + + if completed { + s.streamCompleted() + } + return err +} + +func (s *receiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame) (bool /*completed */, error) { + if s.closedForShutdown { + return false, nil + } + if err := s.flowController.UpdateHighestReceived(frame.ByteOffset, true); err != nil { + return false, err + } + s.finalOffset = frame.ByteOffset + + // ignore duplicate RESET_STREAM frames for this stream (after checking their final offset) + if s.resetRemotely { + return false, nil + } + s.resetRemotely = true + s.resetRemotelyErr = streamCanceledError{ + errorCode: frame.ErrorCode, + error: fmt.Errorf("Stream %d was reset with error code %d", s.streamID, frame.ErrorCode), + } + s.signalRead() + return true, nil +} + +func (s *receiveStream) CloseRemote(offset protocol.ByteCount) { + s.handleStreamFrame(&wire.StreamFrame{FinBit: true, Offset: offset}) +} + +func (s *receiveStream) SetReadDeadline(t time.Time) error { + s.mutex.Lock() + s.deadline = t + s.mutex.Unlock() + s.signalRead() + return nil +} + +// CloseForShutdown closes a stream abruptly. +// It makes Read unblock (and return the error) immediately. +// The peer will NOT be informed about this: the stream is closed without sending a FIN or RESET. +func (s *receiveStream) closeForShutdown(err error) { + s.mutex.Lock() + s.closedForShutdown = true + s.closeForShutdownErr = err + s.mutex.Unlock() + s.signalRead() +} + +func (s *receiveStream) getWindowUpdate() protocol.ByteCount { + return s.flowController.GetWindowUpdate() +} + +func (s *receiveStream) streamCompleted() { + s.mutex.Lock() + finRead := s.finRead + s.mutex.Unlock() + + if !finRead { + s.flowController.Abandon() + } + s.sender.onStreamCompleted(s.streamID) +} + +// signalRead performs a non-blocking send on the readChan +func (s *receiveStream) signalRead() { + select { + case s.readChan <- struct{}{}: + default: + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/send_stream.go b/vendor/github.com/lucas-clemente/quic-go/send_stream.go new file mode 100644 index 00000000..46f24c4b --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/send_stream.go @@ -0,0 +1,332 @@ +package quic + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type sendStreamI interface { + SendStream + handleStopSendingFrame(*wire.StopSendingFrame) + hasData() bool + popStreamFrame(maxBytes protocol.ByteCount) (*wire.StreamFrame, bool) + closeForShutdown(error) + handleMaxStreamDataFrame(*wire.MaxStreamDataFrame) +} + +type sendStream struct { + mutex sync.Mutex + + ctx context.Context + ctxCancel context.CancelFunc + + streamID protocol.StreamID + sender streamSender + + writeOffset protocol.ByteCount + + cancelWriteErr error + closeForShutdownErr error + + closedForShutdown bool // set when CloseForShutdown() is called + finishedWriting bool // set once Close() is called + canceledWrite bool // set when CancelWrite() is called, or a STOP_SENDING frame is received + finSent bool // set when a STREAM_FRAME with FIN bit has b + + dataForWriting []byte + + writeChan chan struct{} + deadline time.Time + + flowController flowcontrol.StreamFlowController + + version protocol.VersionNumber +} + +var _ SendStream = &sendStream{} +var _ sendStreamI = &sendStream{} + +func newSendStream( + streamID protocol.StreamID, + sender streamSender, + flowController flowcontrol.StreamFlowController, + version protocol.VersionNumber, +) *sendStream { + s := &sendStream{ + streamID: streamID, + sender: sender, + flowController: flowController, + writeChan: make(chan struct{}, 1), + version: version, + } + s.ctx, s.ctxCancel = context.WithCancel(context.Background()) + return s +} + +func (s *sendStream) StreamID() protocol.StreamID { + return s.streamID // same for receiveStream and sendStream +} + +func (s *sendStream) Write(p []byte) (int, error) { + s.mutex.Lock() + defer s.mutex.Unlock() + + if s.finishedWriting { + return 0, fmt.Errorf("write on closed stream %d", s.streamID) + } + if s.canceledWrite { + return 0, s.cancelWriteErr + } + if s.closeForShutdownErr != nil { + return 0, s.closeForShutdownErr + } + if !s.deadline.IsZero() && !time.Now().Before(s.deadline) { + return 0, errDeadline + } + if len(p) == 0 { + return 0, nil + } + + s.dataForWriting = p + + var ( + deadlineTimer *utils.Timer + bytesWritten int + notifiedSender bool + ) + for { + bytesWritten = len(p) - len(s.dataForWriting) + deadline := s.deadline + if !deadline.IsZero() { + if !time.Now().Before(deadline) { + s.dataForWriting = nil + return bytesWritten, errDeadline + } + if deadlineTimer == nil { + deadlineTimer = utils.NewTimer() + } + deadlineTimer.Reset(deadline) + } + if s.dataForWriting == nil || s.canceledWrite || s.closedForShutdown { + break + } + + s.mutex.Unlock() + if !notifiedSender { + s.sender.onHasStreamData(s.streamID) // must be called without holding the mutex + notifiedSender = true + } + if deadline.IsZero() { + <-s.writeChan + } else { + select { + case <-s.writeChan: + case <-deadlineTimer.Chan(): + deadlineTimer.SetRead() + } + } + s.mutex.Lock() + } + + if s.closeForShutdownErr != nil { + return bytesWritten, s.closeForShutdownErr + } else if s.cancelWriteErr != nil { + return bytesWritten, s.cancelWriteErr + } + return bytesWritten, nil +} + +// popStreamFrame returns the next STREAM frame that is supposed to be sent on this stream +// maxBytes is the maximum length this frame (including frame header) will have. +func (s *sendStream) popStreamFrame(maxBytes protocol.ByteCount) (*wire.StreamFrame, bool /* has more data to send */) { + s.mutex.Lock() + completed, frame, hasMoreData := s.popStreamFrameImpl(maxBytes) + s.mutex.Unlock() + + if completed { + s.sender.onStreamCompleted(s.streamID) + } + return frame, hasMoreData +} + +func (s *sendStream) popStreamFrameImpl(maxBytes protocol.ByteCount) (bool /* completed */, *wire.StreamFrame, bool /* has more data to send */) { + if s.canceledWrite || s.closeForShutdownErr != nil { + return false, nil, false + } + + frame := &wire.StreamFrame{ + StreamID: s.streamID, + Offset: s.writeOffset, + DataLenPresent: true, + } + maxDataLen := frame.MaxDataLen(maxBytes, s.version) + if maxDataLen == 0 { // a STREAM frame must have at least one byte of data + return false, nil, s.dataForWriting != nil + } + frame.Data, frame.FinBit = s.getDataForWriting(maxDataLen) + if len(frame.Data) == 0 && !frame.FinBit { + // this can happen if: + // - popStreamFrame is called but there's no data for writing + // - there's data for writing, but the stream is stream-level flow control blocked + // - there's data for writing, but the stream is connection-level flow control blocked + if s.dataForWriting == nil { + return false, nil, false + } + if isBlocked, offset := s.flowController.IsNewlyBlocked(); isBlocked { + s.sender.queueControlFrame(&wire.StreamDataBlockedFrame{ + StreamID: s.streamID, + DataLimit: offset, + }) + return false, nil, false + } + return false, nil, true + } + if frame.FinBit { + s.finSent = true + } + return frame.FinBit, frame, s.dataForWriting != nil +} + +func (s *sendStream) hasData() bool { + s.mutex.Lock() + hasData := len(s.dataForWriting) > 0 + s.mutex.Unlock() + return hasData +} + +func (s *sendStream) getDataForWriting(maxBytes protocol.ByteCount) ([]byte, bool /* should send FIN */) { + if s.dataForWriting == nil { + return nil, s.finishedWriting && !s.finSent + } + + maxBytes = utils.MinByteCount(maxBytes, s.flowController.SendWindowSize()) + if maxBytes == 0 { + return nil, false + } + + var ret []byte + if protocol.ByteCount(len(s.dataForWriting)) > maxBytes { + ret = make([]byte, int(maxBytes)) + copy(ret, s.dataForWriting[:maxBytes]) + s.dataForWriting = s.dataForWriting[maxBytes:] + } else { + ret = make([]byte, len(s.dataForWriting)) + copy(ret, s.dataForWriting) + s.dataForWriting = nil + s.signalWrite() + } + s.writeOffset += protocol.ByteCount(len(ret)) + s.flowController.AddBytesSent(protocol.ByteCount(len(ret))) + return ret, s.finishedWriting && s.dataForWriting == nil && !s.finSent +} + +func (s *sendStream) Close() error { + s.mutex.Lock() + if s.canceledWrite { + s.mutex.Unlock() + return fmt.Errorf("Close called for canceled stream %d", s.streamID) + } + s.finishedWriting = true + s.mutex.Unlock() + + s.sender.onHasStreamData(s.streamID) // need to send the FIN, must be called without holding the mutex + s.ctxCancel() + return nil +} + +func (s *sendStream) CancelWrite(errorCode protocol.ApplicationErrorCode) { + s.mutex.Lock() + completed := s.cancelWriteImpl(errorCode, fmt.Errorf("Write on stream %d canceled with error code %d", s.streamID, errorCode)) + s.mutex.Unlock() + + if completed { + s.sender.onStreamCompleted(s.streamID) // must be called without holding the mutex + } +} + +// must be called after locking the mutex +func (s *sendStream) cancelWriteImpl(errorCode protocol.ApplicationErrorCode, writeErr error) bool /*completed */ { + if s.canceledWrite || s.finishedWriting { + return false + } + s.canceledWrite = true + s.cancelWriteErr = writeErr + s.signalWrite() + s.sender.queueControlFrame(&wire.ResetStreamFrame{ + StreamID: s.streamID, + ByteOffset: s.writeOffset, + ErrorCode: errorCode, + }) + // TODO(#991): cancel retransmissions for this stream + s.ctxCancel() + return true +} + +func (s *sendStream) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) { + s.mutex.Lock() + hasStreamData := s.dataForWriting != nil + s.mutex.Unlock() + + s.flowController.UpdateSendWindow(frame.ByteOffset) + if hasStreamData { + s.sender.onHasStreamData(s.streamID) + } +} + +func (s *sendStream) handleStopSendingFrame(frame *wire.StopSendingFrame) { + s.mutex.Lock() + completed := s.handleStopSendingFrameImpl(frame) + s.mutex.Unlock() + + if completed { + s.sender.onStreamCompleted(s.streamID) + } +} + +// must be called after locking the mutex +func (s *sendStream) handleStopSendingFrameImpl(frame *wire.StopSendingFrame) bool /*completed*/ { + writeErr := streamCanceledError{ + errorCode: frame.ErrorCode, + error: fmt.Errorf("Stream %d was reset with error code %d", s.streamID, frame.ErrorCode), + } + return s.cancelWriteImpl(errorCodeStopping, writeErr) +} + +func (s *sendStream) Context() context.Context { + return s.ctx +} + +func (s *sendStream) SetWriteDeadline(t time.Time) error { + s.mutex.Lock() + s.deadline = t + s.mutex.Unlock() + s.signalWrite() + return nil +} + +// CloseForShutdown closes a stream abruptly. +// It makes Write unblock (and return the error) immediately. +// The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. +func (s *sendStream) closeForShutdown(err error) { + s.mutex.Lock() + s.closedForShutdown = true + s.closeForShutdownErr = err + s.mutex.Unlock() + s.signalWrite() + s.ctxCancel() +} + +// signalWrite performs a non-blocking send on the writeChan +func (s *sendStream) signalWrite() { + select { + case s.writeChan <- struct{}{}: + default: + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/server.go b/vendor/github.com/lucas-clemente/quic-go/server.go new file mode 100644 index 00000000..fe2f9388 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/server.go @@ -0,0 +1,558 @@ +package quic + +import ( + "bytes" + "crypto/tls" + "errors" + "fmt" + "io" + "net" + "sync" + "sync/atomic" + "time" + + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// packetHandler handles packets +type packetHandler interface { + handlePacket(*receivedPacket) + io.Closer + destroy(error) + getPerspective() protocol.Perspective +} + +type unknownPacketHandler interface { + handlePacket(*receivedPacket) + closeWithError(error) error +} + +type packetHandlerManager interface { + io.Closer + Add(protocol.ConnectionID, packetHandler) + Retire(protocol.ConnectionID) + Remove(protocol.ConnectionID) + AddResetToken([16]byte, packetHandler) + RemoveResetToken([16]byte) + GetStatelessResetToken(protocol.ConnectionID) [16]byte + SetServer(unknownPacketHandler) + CloseServer() +} + +type quicSession interface { + Session + handlePacket(*receivedPacket) + GetVersion() protocol.VersionNumber + getPerspective() protocol.Perspective + run() error + destroy(error) + closeForRecreating() protocol.PacketNumber + closeRemote(error) +} + +type sessionRunner interface { + OnHandshakeComplete(Session) + Retire(protocol.ConnectionID) + Remove(protocol.ConnectionID) + AddResetToken([16]byte, packetHandler) + RemoveResetToken([16]byte) +} + +type runner struct { + packetHandlerManager + + onHandshakeCompleteImpl func(Session) +} + +func (r *runner) OnHandshakeComplete(s Session) { r.onHandshakeCompleteImpl(s) } + +var _ sessionRunner = &runner{} + +// A Listener of QUIC +type server struct { + mutex sync.Mutex + + tlsConf *tls.Config + config *Config + + conn net.PacketConn + // If the server is started with ListenAddr, we create a packet conn. + // If it is started with Listen, we take a packet conn as a parameter. + createdPacketConn bool + + cookieGenerator *handshake.CookieGenerator + + sessionHandler packetHandlerManager + + // set as a member, so they can be set in the tests + newSession func(connection, sessionRunner, protocol.ConnectionID /* original connection ID */, protocol.ConnectionID /* destination connection ID */, protocol.ConnectionID /* source connection ID */, *Config, *tls.Config, *handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error) + + serverError error + errorChan chan struct{} + closed bool + + sessionQueue chan Session + sessionQueueLen int32 // to be used as an atomic + + sessionRunner sessionRunner + + logger utils.Logger +} + +var _ Listener = &server{} +var _ unknownPacketHandler = &server{} + +// ListenAddr creates a QUIC server listening on a given address. +// The tls.Config must not be nil and must contain a certificate configuration. +// The quic.Config may be nil, in that case the default values will be used. +func ListenAddr(addr string, tlsConf *tls.Config, config *Config) (Listener, error) { + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, err + } + conn, err := net.ListenUDP("udp", udpAddr) + if err != nil { + return nil, err + } + serv, err := listen(conn, tlsConf, config) + if err != nil { + return nil, err + } + serv.createdPacketConn = true + return serv, nil +} + +// Listen listens for QUIC connections on a given net.PacketConn. +// A single PacketConn only be used for a single call to Listen. +// The PacketConn can be used for simultaneous calls to Dial. +// QUIC connection IDs are used for demultiplexing the different connections. +// The tls.Config must not be nil and must contain a certificate configuration. +// The quic.Config may be nil, in that case the default values will be used. +func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener, error) { + return listen(conn, tlsConf, config) +} + +func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*server, error) { + // TODO(#1655): only require that tls.Config.Certificates or tls.Config.GetCertificate is set + if tlsConf == nil || len(tlsConf.Certificates) == 0 { + return nil, errors.New("quic: Certificates not set in tls.Config") + } + config = populateServerConfig(config) + for _, v := range config.Versions { + if !protocol.IsValidVersion(v) { + return nil, fmt.Errorf("%s is not a valid QUIC version", v) + } + } + + sessionHandler, err := getMultiplexer().AddConn(conn, config.ConnectionIDLength, config.StatelessResetKey) + if err != nil { + return nil, err + } + s := &server{ + conn: conn, + tlsConf: tlsConf, + config: config, + sessionHandler: sessionHandler, + sessionQueue: make(chan Session), + errorChan: make(chan struct{}), + newSession: newSession, + logger: utils.DefaultLogger.WithPrefix("server"), + } + if err := s.setup(); err != nil { + return nil, err + } + sessionHandler.SetServer(s) + s.logger.Debugf("Listening for %s connections on %s", conn.LocalAddr().Network(), conn.LocalAddr().String()) + return s, nil +} + +func (s *server) setup() error { + s.sessionRunner = &runner{ + packetHandlerManager: s.sessionHandler, + onHandshakeCompleteImpl: func(sess Session) { + go func() { + atomic.AddInt32(&s.sessionQueueLen, 1) + defer atomic.AddInt32(&s.sessionQueueLen, -1) + select { + case s.sessionQueue <- sess: + // blocks until the session is accepted + case <-sess.Context().Done(): + // don't pass sessions that were already closed to Accept() + } + }() + }, + } + cookieGenerator, err := handshake.NewCookieGenerator() + if err != nil { + return err + } + s.cookieGenerator = cookieGenerator + return nil +} + +var defaultAcceptCookie = func(clientAddr net.Addr, cookie *Cookie) bool { + if cookie == nil { + return false + } + if time.Now().After(cookie.SentTime.Add(protocol.CookieExpiryTime)) { + return false + } + var sourceAddr string + if udpAddr, ok := clientAddr.(*net.UDPAddr); ok { + sourceAddr = udpAddr.IP.String() + } else { + sourceAddr = clientAddr.String() + } + return sourceAddr == cookie.RemoteAddr +} + +// populateServerConfig populates fields in the quic.Config with their default values, if none are set +// it may be called with nil +func populateServerConfig(config *Config) *Config { + if config == nil { + config = &Config{} + } + versions := config.Versions + if len(versions) == 0 { + versions = protocol.SupportedVersions + } + + vsa := defaultAcceptCookie + if config.AcceptCookie != nil { + vsa = config.AcceptCookie + } + + handshakeTimeout := protocol.DefaultHandshakeTimeout + if config.HandshakeTimeout != 0 { + handshakeTimeout = config.HandshakeTimeout + } + idleTimeout := protocol.DefaultIdleTimeout + if config.IdleTimeout != 0 { + idleTimeout = config.IdleTimeout + } + + maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow + if maxReceiveStreamFlowControlWindow == 0 { + maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow + } + maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow + if maxReceiveConnectionFlowControlWindow == 0 { + maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow + } + maxIncomingStreams := config.MaxIncomingStreams + if maxIncomingStreams == 0 { + maxIncomingStreams = protocol.DefaultMaxIncomingStreams + } else if maxIncomingStreams < 0 { + maxIncomingStreams = 0 + } + maxIncomingUniStreams := config.MaxIncomingUniStreams + if maxIncomingUniStreams == 0 { + maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams + } else if maxIncomingUniStreams < 0 { + maxIncomingUniStreams = 0 + } + connIDLen := config.ConnectionIDLength + if connIDLen == 0 { + connIDLen = protocol.DefaultConnectionIDLength + } + + return &Config{ + Versions: versions, + HandshakeTimeout: handshakeTimeout, + IdleTimeout: idleTimeout, + AcceptCookie: vsa, + KeepAlive: config.KeepAlive, + MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, + MaxIncomingStreams: maxIncomingStreams, + MaxIncomingUniStreams: maxIncomingUniStreams, + ConnectionIDLength: connIDLen, + StatelessResetKey: config.StatelessResetKey, + } +} + +// Accept returns newly openend sessions +func (s *server) Accept() (Session, error) { + var sess Session + select { + case sess = <-s.sessionQueue: + return sess, nil + case <-s.errorChan: + return nil, s.serverError + } +} + +// Close the server +func (s *server) Close() error { + s.mutex.Lock() + defer s.mutex.Unlock() + if s.closed { + return nil + } + return s.closeWithMutex() +} + +func (s *server) closeWithMutex() error { + s.sessionHandler.CloseServer() + if s.serverError == nil { + s.serverError = errors.New("server closed") + } + var err error + // If the server was started with ListenAddr, we created the packet conn. + // We need to close it in order to make the go routine reading from that conn return. + if s.createdPacketConn { + err = s.sessionHandler.Close() + } + s.closed = true + close(s.errorChan) + return err +} + +func (s *server) closeWithError(e error) error { + s.mutex.Lock() + defer s.mutex.Unlock() + if s.closed { + return nil + } + s.serverError = e + return s.closeWithMutex() +} + +// Addr returns the server's network address +func (s *server) Addr() net.Addr { + return s.conn.LocalAddr() +} + +func (s *server) handlePacket(p *receivedPacket) { + go func() { + if shouldReleaseBuffer := s.handlePacketImpl(p); !shouldReleaseBuffer { + p.buffer.Release() + } + }() +} + +func (s *server) handlePacketImpl(p *receivedPacket) bool /* was the packet passed on to a session */ { + if len(p.data) < protocol.MinInitialPacketSize { + s.logger.Debugf("Dropping a packet that is too small to be a valid Initial (%d bytes)", len(p.data)) + return false + } + // If we're creating a new session, the packet will be passed to the session. + // The header will then be parsed again. + hdr, _, _, err := wire.ParsePacket(p.data, s.config.ConnectionIDLength) + if err != nil { + s.logger.Debugf("Error parsing packet: %s", err) + return false + } + // Short header packets should never end up here in the first place + if !hdr.IsLongHeader { + return false + } + // send a Version Negotiation Packet if the client is speaking a different protocol version + if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) { + s.sendVersionNegotiationPacket(p, hdr) + return false + } + if hdr.IsLongHeader && hdr.Type != protocol.PacketTypeInitial { + // Drop long header packets. + // There's litte point in sending a Stateless Reset, since the client + // might not have received the token yet. + return false + } + + s.logger.Debugf("<- Received Initial packet.") + + sess, connID, err := s.handleInitialImpl(p, hdr) + if err != nil { + s.logger.Errorf("Error occurred handling initial packet: %s", err) + return false + } + if sess == nil { // a retry was done, or the connection attempt was rejected + return false + } + // Don't put the packet buffer back if a new session was created. + // The session will handle the packet and take of that. + s.sessionHandler.Add(connID, sess) + return true +} + +func (s *server) handleInitialImpl(p *receivedPacket, hdr *wire.Header) (quicSession, protocol.ConnectionID, error) { + if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { + return nil, nil, errors.New("too short connection ID") + } + + var cookie *Cookie + var origDestConnectionID protocol.ConnectionID + if len(hdr.Token) > 0 { + c, err := s.cookieGenerator.DecodeToken(hdr.Token) + if err == nil { + cookie = &Cookie{ + RemoteAddr: c.RemoteAddr, + SentTime: c.SentTime, + } + origDestConnectionID = c.OriginalDestConnectionID + } + } + if !s.config.AcceptCookie(p.remoteAddr, cookie) { + // Log the Initial packet now. + // If no Retry is sent, the packet will be logged by the session. + (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) + return nil, nil, s.sendRetry(p.remoteAddr, hdr) + } + + if queueLen := atomic.LoadInt32(&s.sessionQueueLen); queueLen >= protocol.MaxAcceptQueueSize { + s.logger.Debugf("Rejecting new connection. Server currently busy. Accept queue length: %d (max %d)", queueLen, protocol.MaxAcceptQueueSize) + return nil, nil, s.sendServerBusy(p.remoteAddr, hdr) + } + + connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) + if err != nil { + return nil, nil, err + } + s.logger.Debugf("Changing connection ID to %s.", connID) + sess, err := s.createNewSession( + p.remoteAddr, + origDestConnectionID, + hdr.DestConnectionID, + hdr.SrcConnectionID, + connID, + hdr.Version, + ) + if err != nil { + return nil, nil, err + } + sess.handlePacket(p) + return sess, connID, nil +} + +func (s *server) createNewSession( + remoteAddr net.Addr, + origDestConnID protocol.ConnectionID, + clientDestConnID protocol.ConnectionID, + destConnID protocol.ConnectionID, + srcConnID protocol.ConnectionID, + version protocol.VersionNumber, +) (quicSession, error) { + token := s.sessionHandler.GetStatelessResetToken(srcConnID) + params := &handshake.TransportParameters{ + InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData, + InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData, + InitialMaxStreamDataUni: protocol.InitialMaxStreamData, + InitialMaxData: protocol.InitialMaxData, + IdleTimeout: s.config.IdleTimeout, + MaxBidiStreams: uint64(s.config.MaxIncomingStreams), + MaxUniStreams: uint64(s.config.MaxIncomingUniStreams), + AckDelayExponent: protocol.AckDelayExponent, + DisableMigration: true, + StatelessResetToken: &token, + OriginalConnectionID: origDestConnID, + } + sess, err := s.newSession( + &conn{pconn: s.conn, currentAddr: remoteAddr}, + s.sessionRunner, + clientDestConnID, + destConnID, + srcConnID, + s.config, + s.tlsConf, + params, + s.logger, + version, + ) + if err != nil { + return nil, err + } + go sess.run() + return sess, nil +} + +func (s *server) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error { + token, err := s.cookieGenerator.NewToken(remoteAddr, hdr.DestConnectionID) + if err != nil { + return err + } + connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) + if err != nil { + return err + } + replyHdr := &wire.ExtendedHeader{} + replyHdr.IsLongHeader = true + replyHdr.Type = protocol.PacketTypeRetry + replyHdr.Version = hdr.Version + replyHdr.SrcConnectionID = connID + replyHdr.DestConnectionID = hdr.SrcConnectionID + replyHdr.OrigDestConnectionID = hdr.DestConnectionID + replyHdr.Token = token + s.logger.Debugf("Changing connection ID to %s.\n-> Sending Retry", connID) + replyHdr.Log(s.logger) + buf := &bytes.Buffer{} + if err := replyHdr.Write(buf, hdr.Version); err != nil { + return err + } + if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil { + s.logger.Debugf("Error sending Retry: %s", err) + } + return nil +} + +func (s *server) sendServerBusy(remoteAddr net.Addr, hdr *wire.Header) error { + sealer, _, err := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer) + if err != nil { + return err + } + packetBuffer := getPacketBuffer() + defer packetBuffer.Release() + buf := bytes.NewBuffer(packetBuffer.Slice[:0]) + + ccf := &wire.ConnectionCloseFrame{ErrorCode: qerr.ServerBusy} + + replyHdr := &wire.ExtendedHeader{} + replyHdr.IsLongHeader = true + replyHdr.Type = protocol.PacketTypeInitial + replyHdr.Version = hdr.Version + replyHdr.SrcConnectionID = hdr.DestConnectionID + replyHdr.DestConnectionID = hdr.SrcConnectionID + replyHdr.PacketNumberLen = protocol.PacketNumberLen4 + replyHdr.Length = 4 /* packet number len */ + ccf.Length(hdr.Version) + protocol.ByteCount(sealer.Overhead()) + if err := replyHdr.Write(buf, hdr.Version); err != nil { + return err + } + payloadOffset := buf.Len() + + if err := ccf.Write(buf, hdr.Version); err != nil { + return err + } + + raw := buf.Bytes() + _ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], replyHdr.PacketNumber, raw[:payloadOffset]) + raw = raw[0 : buf.Len()+sealer.Overhead()] + + pnOffset := payloadOffset - int(replyHdr.PacketNumberLen) + sealer.EncryptHeader( + raw[pnOffset+4:pnOffset+4+16], + &raw[0], + raw[pnOffset:payloadOffset], + ) + + replyHdr.Log(s.logger) + wire.LogFrame(s.logger, ccf, true) + if _, err := s.conn.WriteTo(raw, remoteAddr); err != nil { + s.logger.Debugf("Error rejecting connection: %s", err) + } + return nil +} + +func (s *server) sendVersionNegotiationPacket(p *receivedPacket, hdr *wire.Header) { + s.logger.Debugf("Client offered version %s, sending Version Negotiation", hdr.Version) + data, err := wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions) + if err != nil { + s.logger.Debugf("Error composing Version Negotiation: %s", err) + return + } + if _, err := s.conn.WriteTo(data, p.remoteAddr); err != nil { + s.logger.Debugf("Error sending Version Negotiation: %s", err) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/session.go b/vendor/github.com/lucas-clemente/quic-go/session.go new file mode 100644 index 00000000..ba1f5566 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/session.go @@ -0,0 +1,1287 @@ +package quic + +import ( + "bytes" + "context" + "crypto/tls" + "errors" + "fmt" + "io" + "net" + "reflect" + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/ackhandler" + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type unpacker interface { + Unpack(hdr *wire.Header, data []byte) (*unpackedPacket, error) +} + +type streamGetter interface { + GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error) + GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error) +} + +type streamManager interface { + GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error) + GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error) + OpenStream() (Stream, error) + OpenUniStream() (SendStream, error) + OpenStreamSync() (Stream, error) + OpenUniStreamSync() (SendStream, error) + AcceptStream() (Stream, error) + AcceptUniStream() (ReceiveStream, error) + DeleteStream(protocol.StreamID) error + UpdateLimits(*handshake.TransportParameters) error + HandleMaxStreamsFrame(*wire.MaxStreamsFrame) error + CloseWithError(error) +} + +type cryptoStreamHandler interface { + RunHandshake() error + ChangeConnectionID(protocol.ConnectionID) error + io.Closer + ConnectionState() tls.ConnectionState +} + +type receivedPacket struct { + remoteAddr net.Addr + rcvTime time.Time + data []byte + + buffer *packetBuffer +} + +func (p *receivedPacket) Clone() *receivedPacket { + return &receivedPacket{ + remoteAddr: p.remoteAddr, + rcvTime: p.rcvTime, + data: p.data, + buffer: p.buffer, + } +} + +type closeError struct { + err error + remote bool + sendClose bool +} + +var errCloseForRecreating = errors.New("closing session in order to recreate it") + +// A Session is a QUIC session +type session struct { + sessionRunner sessionRunner + + destConnID protocol.ConnectionID + origDestConnID protocol.ConnectionID // if the server sends a Retry, this is the connection ID we used initially + srcConnID protocol.ConnectionID + + perspective protocol.Perspective + initialVersion protocol.VersionNumber // if version negotiation is performed, this is the version we initially tried + version protocol.VersionNumber + config *Config + + conn connection + + streamsMap streamManager + + rttStats *congestion.RTTStats + + cryptoStreamManager *cryptoStreamManager + sentPacketHandler ackhandler.SentPacketHandler + receivedPacketHandler ackhandler.ReceivedPacketHandler + framer framer + windowUpdateQueue *windowUpdateQueue + connFlowController flowcontrol.ConnectionFlowController + + unpacker unpacker + frameParser wire.FrameParser + packer packer + + cryptoStreamHandler cryptoStreamHandler + + receivedPackets chan *receivedPacket + sendingScheduled chan struct{} + + closeOnce sync.Once + closed utils.AtomicBool + // closeChan is used to notify the run loop that it should terminate + closeChan chan closeError + connectionClosePacket *packedPacket + packetsReceivedAfterClose int + + ctx context.Context + ctxCancel context.CancelFunc + + undecryptablePackets []*receivedPacket + + clientHelloWritten <-chan struct{} + handshakeCompleteChan chan struct{} // is closed when the handshake completes + handshakeComplete bool + + receivedRetry bool + receivedFirstPacket bool + receivedFirstForwardSecurePacket bool + + sessionCreationTime time.Time + // The idle timeout is set based on the max of the time we received the last packet... + lastPacketReceivedTime time.Time + // ... and the time we sent a new retransmittable packet after receiving a packet. + firstRetransmittablePacketAfterIdleSentTime time.Time + // pacingDeadline is the time when the next packet should be sent + pacingDeadline time.Time + + peerParams *handshake.TransportParameters + + timer *utils.Timer + // keepAlivePingSent stores whether a Ping frame was sent to the peer or not + // it is reset as soon as we receive a packet from the peer + keepAlivePingSent bool + + logger utils.Logger +} + +var _ Session = &session{} +var _ streamSender = &session{} + +var newSession = func( + conn connection, + runner sessionRunner, + clientDestConnID protocol.ConnectionID, + destConnID protocol.ConnectionID, + srcConnID protocol.ConnectionID, + conf *Config, + tlsConf *tls.Config, + params *handshake.TransportParameters, + logger utils.Logger, + v protocol.VersionNumber, +) (quicSession, error) { + s := &session{ + conn: conn, + sessionRunner: runner, + config: conf, + srcConnID: srcConnID, + destConnID: destConnID, + perspective: protocol.PerspectiveServer, + handshakeCompleteChan: make(chan struct{}), + logger: logger, + version: v, + } + s.preSetup() + s.sentPacketHandler = ackhandler.NewSentPacketHandler(0, s.rttStats, s.logger) + s.streamsMap = newStreamsMap( + s, + s.newFlowController, + uint64(s.config.MaxIncomingStreams), + uint64(s.config.MaxIncomingUniStreams), + s.perspective, + s.version, + ) + s.framer = newFramer(s.streamsMap, s.version) + initialStream := newCryptoStream() + handshakeStream := newCryptoStream() + oneRTTStream := newPostHandshakeCryptoStream(s.framer) + cs, err := handshake.NewCryptoSetupServer( + initialStream, + handshakeStream, + oneRTTStream, + clientDestConnID, + conn.RemoteAddr(), + params, + s.processTransportParameters, + tlsConf, + logger, + ) + if err != nil { + return nil, err + } + s.cryptoStreamHandler = cs + s.packer = newPacketPacker( + s.destConnID, + s.srcConnID, + initialStream, + handshakeStream, + s.sentPacketHandler, + s.RemoteAddr(), + cs, + s.framer, + s.receivedPacketHandler, + s.perspective, + s.version, + ) + s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, oneRTTStream) + + if err := s.postSetup(); err != nil { + return nil, err + } + s.unpacker = newPacketUnpacker(cs, s.version) + return s, nil +} + +// declare this as a variable, such that we can it mock it in the tests +var newClientSession = func( + conn connection, + runner sessionRunner, + destConnID protocol.ConnectionID, + srcConnID protocol.ConnectionID, + conf *Config, + tlsConf *tls.Config, + initialPacketNumber protocol.PacketNumber, + params *handshake.TransportParameters, + initialVersion protocol.VersionNumber, + logger utils.Logger, + v protocol.VersionNumber, +) (quicSession, error) { + s := &session{ + conn: conn, + sessionRunner: runner, + config: conf, + srcConnID: srcConnID, + destConnID: destConnID, + perspective: protocol.PerspectiveClient, + handshakeCompleteChan: make(chan struct{}), + logger: logger, + initialVersion: initialVersion, + version: v, + } + s.preSetup() + s.sentPacketHandler = ackhandler.NewSentPacketHandler(initialPacketNumber, s.rttStats, s.logger) + initialStream := newCryptoStream() + handshakeStream := newCryptoStream() + oneRTTStream := newPostHandshakeCryptoStream(s.framer) + cs, clientHelloWritten, err := handshake.NewCryptoSetupClient( + initialStream, + handshakeStream, + oneRTTStream, + s.destConnID, + conn.RemoteAddr(), + params, + s.processTransportParameters, + tlsConf, + logger, + ) + if err != nil { + return nil, err + } + s.clientHelloWritten = clientHelloWritten + s.cryptoStreamHandler = cs + s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, oneRTTStream) + s.unpacker = newPacketUnpacker(cs, s.version) + s.streamsMap = newStreamsMap( + s, + s.newFlowController, + uint64(s.config.MaxIncomingStreams), + uint64(s.config.MaxIncomingUniStreams), + s.perspective, + s.version, + ) + s.framer = newFramer(s.streamsMap, s.version) + s.packer = newPacketPacker( + s.destConnID, + s.srcConnID, + initialStream, + handshakeStream, + s.sentPacketHandler, + s.RemoteAddr(), + cs, + s.framer, + s.receivedPacketHandler, + s.perspective, + s.version, + ) + return s, s.postSetup() +} + +func (s *session) preSetup() { + s.frameParser = wire.NewFrameParser(s.version) + s.rttStats = &congestion.RTTStats{} + s.receivedPacketHandler = ackhandler.NewReceivedPacketHandler(s.rttStats, s.logger, s.version) + s.connFlowController = flowcontrol.NewConnectionFlowController( + protocol.InitialMaxData, + protocol.ByteCount(s.config.MaxReceiveConnectionFlowControlWindow), + s.onHasConnectionWindowUpdate, + s.rttStats, + s.logger, + ) +} + +func (s *session) postSetup() error { + s.receivedPackets = make(chan *receivedPacket, protocol.MaxSessionUnprocessedPackets) + s.closeChan = make(chan closeError, 1) + s.sendingScheduled = make(chan struct{}, 1) + s.undecryptablePackets = make([]*receivedPacket, 0, protocol.MaxUndecryptablePackets) + s.ctx, s.ctxCancel = context.WithCancel(context.Background()) + + s.timer = utils.NewTimer() + now := time.Now() + s.lastPacketReceivedTime = now + s.sessionCreationTime = now + + s.windowUpdateQueue = newWindowUpdateQueue(s.streamsMap, s.connFlowController, s.framer.QueueControlFrame) + return nil +} + +// run the session main loop +func (s *session) run() error { + defer s.ctxCancel() + + go func() { + if err := s.cryptoStreamHandler.RunHandshake(); err != nil { + s.closeLocal(err) + return + } + close(s.handshakeCompleteChan) + }() + if s.perspective == protocol.PerspectiveClient { + select { + case <-s.clientHelloWritten: + s.scheduleSending() + case closeErr := <-s.closeChan: + // put the close error back into the channel, so that the run loop can receive it + s.closeChan <- closeErr + } + } + + var closeErr closeError + +runLoop: + for { + // Close immediately if requested + select { + case closeErr = <-s.closeChan: + break runLoop + case <-s.handshakeCompleteChan: + s.handleHandshakeComplete() + default: + } + + s.maybeResetTimer() + + select { + case closeErr = <-s.closeChan: + break runLoop + case <-s.timer.Chan(): + s.timer.SetRead() + // We do all the interesting stuff after the switch statement, so + // nothing to see here. + case <-s.sendingScheduled: + // We do all the interesting stuff after the switch statement, so + // nothing to see here. + case p := <-s.receivedPackets: + // Only reset the timers if this packet was actually processed. + // This avoids modifying any state when handling undecryptable packets, + // which could be injected by an attacker. + if wasProcessed := s.handlePacketImpl(p); !wasProcessed { + continue + } + case <-s.handshakeCompleteChan: + s.handleHandshakeComplete() + } + + now := time.Now() + if timeout := s.sentPacketHandler.GetAlarmTimeout(); !timeout.IsZero() && timeout.Before(now) { + // This could cause packets to be retransmitted. + // Check it before trying to send packets. + if err := s.sentPacketHandler.OnAlarm(); err != nil { + s.closeLocal(err) + } + } + + var pacingDeadline time.Time + if s.pacingDeadline.IsZero() { // the timer didn't have a pacing deadline set + pacingDeadline = s.sentPacketHandler.TimeUntilSend() + } + if s.config.KeepAlive && !s.keepAlivePingSent && s.handshakeComplete && s.firstRetransmittablePacketAfterIdleSentTime.IsZero() && time.Since(s.lastPacketReceivedTime) >= s.peerParams.IdleTimeout/2 { + // send a PING frame since there is no activity in the session + s.logger.Debugf("Sending a keep-alive ping to keep the connection alive.") + s.framer.QueueControlFrame(&wire.PingFrame{}) + s.keepAlivePingSent = true + } else if !pacingDeadline.IsZero() && now.Before(pacingDeadline) { + // If we get to this point before the pacing deadline, we should wait until that deadline. + // This can happen when scheduleSending is called, or a packet is received. + // Set the timer and restart the run loop. + s.pacingDeadline = pacingDeadline + continue + } + + if !s.handshakeComplete && now.Sub(s.sessionCreationTime) >= s.config.HandshakeTimeout { + s.destroy(qerr.TimeoutError("Handshake did not complete in time")) + continue + } + if s.handshakeComplete && now.Sub(s.idleTimeoutStartTime()) >= s.config.IdleTimeout { + s.destroy(qerr.TimeoutError("No recent network activity")) + continue + } + + if err := s.sendPackets(); err != nil { + s.closeLocal(err) + } + } + + s.handleCloseError(closeErr) + s.closed.Set(true) + s.logger.Infof("Connection %s closed.", s.srcConnID) + s.cryptoStreamHandler.Close() + return closeErr.err +} + +func (s *session) Context() context.Context { + return s.ctx +} + +func (s *session) ConnectionState() tls.ConnectionState { + return s.cryptoStreamHandler.ConnectionState() +} + +func (s *session) maybeResetTimer() { + var deadline time.Time + if s.config.KeepAlive && s.handshakeComplete && !s.keepAlivePingSent { + deadline = s.idleTimeoutStartTime().Add(s.peerParams.IdleTimeout / 2) + } else { + deadline = s.idleTimeoutStartTime().Add(s.config.IdleTimeout) + } + + if ackAlarm := s.receivedPacketHandler.GetAlarmTimeout(); !ackAlarm.IsZero() { + deadline = utils.MinTime(deadline, ackAlarm) + } + if lossTime := s.sentPacketHandler.GetAlarmTimeout(); !lossTime.IsZero() { + deadline = utils.MinTime(deadline, lossTime) + } + if !s.handshakeComplete { + handshakeDeadline := s.sessionCreationTime.Add(s.config.HandshakeTimeout) + deadline = utils.MinTime(deadline, handshakeDeadline) + } + if !s.pacingDeadline.IsZero() { + deadline = utils.MinTime(deadline, s.pacingDeadline) + } + + s.timer.Reset(deadline) +} + +func (s *session) idleTimeoutStartTime() time.Time { + return utils.MaxTime(s.lastPacketReceivedTime, s.firstRetransmittablePacketAfterIdleSentTime) +} + +func (s *session) handleHandshakeComplete() { + s.handshakeComplete = true + s.handshakeCompleteChan = nil // prevent this case from ever being selected again + s.sessionRunner.OnHandshakeComplete(s) + + // The client completes the handshake first (after sending the CFIN). + // We need to make sure they learn about the peer completing the handshake, + // in order to stop retransmitting handshake packets. + // They will stop retransmitting handshake packets when receiving the first forward-secure packet. + // We need to make sure that a retransmittable forward-secure packet is sent, + // independent from the application protocol. + if s.perspective == protocol.PerspectiveServer { + s.queueControlFrame(&wire.PingFrame{}) + s.sentPacketHandler.SetHandshakeComplete() + } +} + +func (s *session) handlePacketImpl(rp *receivedPacket) bool { + var counter uint8 + var lastConnID protocol.ConnectionID + var processed bool + data := rp.data + p := rp + for len(data) > 0 { + if counter > 0 { + p = p.Clone() + p.data = data + } + + hdr, packetData, rest, err := wire.ParsePacket(p.data, s.srcConnID.Len()) + if err != nil { + s.logger.Debugf("error parsing packet: %s", err) + break + } + + if counter > 0 && !hdr.DestConnectionID.Equal(lastConnID) { + s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", hdr.DestConnectionID, lastConnID) + break + } + lastConnID = hdr.DestConnectionID + + if counter > 0 { + p.buffer.Split() + } + counter++ + + // only log if this actually a coalesced packet + if s.logger.Debug() && (counter > 1 || len(rest) > 0) { + s.logger.Debugf("Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.", counter, len(packetData), len(rest)) + } + p.data = packetData + if wasProcessed := s.handleSinglePacket(p, hdr); wasProcessed { + processed = true + } + data = rest + } + p.buffer.MaybeRelease() + return processed +} + +func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool /* was the packet successfully processed */ { + var wasQueued bool + + defer func() { + // Put back the packet buffer if the packet wasn't queued for later decryption. + if !wasQueued { + p.buffer.Decrement() + } + }() + + if hdr.Type == protocol.PacketTypeRetry { + return s.handleRetryPacket(p, hdr) + } + + // The server can change the source connection ID with the first Handshake packet. + // After this, all packets with a different source connection have to be ignored. + if s.receivedFirstPacket && hdr.IsLongHeader && !hdr.SrcConnectionID.Equal(s.destConnID) { + s.logger.Debugf("Dropping packet with unexpected source connection ID: %s (expected %s)", hdr.SrcConnectionID, s.destConnID) + return false + } + // drop 0-RTT packets + if hdr.Type == protocol.PacketType0RTT { + return false + } + + packet, err := s.unpacker.Unpack(hdr, p.data) + if err != nil { + if err == handshake.ErrOpenerNotYetAvailable { + // Sealer for this encryption level not yet available. + // Try again later. + wasQueued = true + s.tryQueueingUndecryptablePacket(p) + return false + } + // This might be a packet injected by an attacker. + // Drop it. + s.logger.Debugf("Dropping packet that could not be unpacked. Unpack error: %s", err) + return false + } + + if s.logger.Debug() { + s.logger.Debugf("<- Reading packet %#x (%d bytes) for connection %s, %s", packet.packetNumber, len(p.data), hdr.DestConnectionID, packet.encryptionLevel) + packet.hdr.Log(s.logger) + } + + if err := s.handleUnpackedPacket(packet, p.rcvTime); err != nil { + s.closeLocal(err) + return false + } + return true +} + +func (s *session) handleRetryPacket(p *receivedPacket, hdr *wire.Header) bool /* was this a valid Retry */ { + if s.perspective == protocol.PerspectiveServer { + s.logger.Debugf("Ignoring Retry.") + return false + } + if s.receivedFirstPacket { + s.logger.Debugf("Ignoring Retry, since we already received a packet.") + return false + } + (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) + if !hdr.OrigDestConnectionID.Equal(s.destConnID) { + s.logger.Debugf("Ignoring spoofed Retry. Original Destination Connection ID: %s, expected: %s", hdr.OrigDestConnectionID, s.destConnID) + return false + } + if hdr.SrcConnectionID.Equal(s.destConnID) { + s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") + return false + } + // If a token is already set, this means that we already received a Retry from the server. + // Ignore this Retry packet. + if s.receivedRetry { + s.logger.Debugf("Ignoring Retry, since a Retry was already received.") + return false + } + s.logger.Debugf("<- Received Retry") + s.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID) + s.origDestConnID = s.destConnID + s.destConnID = hdr.SrcConnectionID + s.receivedRetry = true + if err := s.sentPacketHandler.ResetForRetry(); err != nil { + s.closeLocal(err) + return false + } + s.cryptoStreamHandler.ChangeConnectionID(s.destConnID) + s.packer.SetToken(hdr.Token) + s.packer.ChangeDestConnectionID(s.destConnID) + s.scheduleSending() + return true +} + +func (s *session) handleUnpackedPacket(packet *unpackedPacket, rcvTime time.Time) error { + if len(packet.data) == 0 { + return qerr.Error(qerr.ProtocolViolation, "empty packet") + } + + // The server can change the source connection ID with the first Handshake packet. + if s.perspective == protocol.PerspectiveClient && !s.receivedFirstPacket && packet.hdr.IsLongHeader && !packet.hdr.SrcConnectionID.Equal(s.destConnID) { + s.logger.Debugf("Received first packet. Switching destination connection ID to: %s", packet.hdr.SrcConnectionID) + s.destConnID = packet.hdr.SrcConnectionID + s.packer.ChangeDestConnectionID(s.destConnID) + } + + s.receivedFirstPacket = true + s.lastPacketReceivedTime = rcvTime + s.firstRetransmittablePacketAfterIdleSentTime = time.Time{} + s.keepAlivePingSent = false + + // The client completes the handshake first (after sending the CFIN). + // We know that the server completed the handshake as soon as we receive a forward-secure packet. + if s.perspective == protocol.PerspectiveClient { + if !s.receivedFirstForwardSecurePacket && packet.encryptionLevel == protocol.Encryption1RTT { + s.receivedFirstForwardSecurePacket = true + s.sentPacketHandler.SetHandshakeComplete() + } + } + + r := bytes.NewReader(packet.data) + var isRetransmittable bool + for { + frame, err := s.frameParser.ParseNext(r, packet.encryptionLevel) + if err != nil { + return err + } + if frame == nil { + break + } + if ackhandler.IsFrameRetransmittable(frame) { + isRetransmittable = true + } + if err := s.handleFrame(frame, packet.packetNumber, packet.encryptionLevel); err != nil { + return err + } + } + + if err := s.receivedPacketHandler.ReceivedPacket(packet.packetNumber, packet.encryptionLevel, rcvTime, isRetransmittable); err != nil { + return err + } + return nil +} + +func (s *session) handleFrame(f wire.Frame, pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) error { + var err error + wire.LogFrame(s.logger, f, false) + switch frame := f.(type) { + case *wire.CryptoFrame: + err = s.handleCryptoFrame(frame, encLevel) + case *wire.StreamFrame: + err = s.handleStreamFrame(frame, encLevel) + case *wire.AckFrame: + err = s.handleAckFrame(frame, pn, encLevel) + case *wire.ConnectionCloseFrame: + s.closeRemote(qerr.Error(frame.ErrorCode, frame.ReasonPhrase)) + case *wire.ResetStreamFrame: + err = s.handleResetStreamFrame(frame) + case *wire.MaxDataFrame: + s.handleMaxDataFrame(frame) + case *wire.MaxStreamDataFrame: + err = s.handleMaxStreamDataFrame(frame) + case *wire.MaxStreamsFrame: + err = s.handleMaxStreamsFrame(frame) + case *wire.DataBlockedFrame: + case *wire.StreamDataBlockedFrame: + case *wire.StreamsBlockedFrame: + case *wire.StopSendingFrame: + err = s.handleStopSendingFrame(frame) + case *wire.PingFrame: + case *wire.PathChallengeFrame: + s.handlePathChallengeFrame(frame) + case *wire.PathResponseFrame: + // since we don't send PATH_CHALLENGEs, we don't expect PATH_RESPONSEs + err = errors.New("unexpected PATH_RESPONSE frame") + case *wire.NewTokenFrame: + case *wire.NewConnectionIDFrame: + case *wire.RetireConnectionIDFrame: + // since we don't send new connection IDs, we don't expect retirements + err = errors.New("unexpected RETIRE_CONNECTION_ID frame") + default: + err = fmt.Errorf("unexpected frame type: %s", reflect.ValueOf(&frame).Elem().Type().Name()) + } + return err +} + +// handlePacket is called by the server with a new packet +func (s *session) handlePacket(p *receivedPacket) { + if s.closed.Get() { + s.handlePacketAfterClosed(p) + } + // Discard packets once the amount of queued packets is larger than + // the channel size, protocol.MaxSessionUnprocessedPackets + select { + case s.receivedPackets <- p: + default: + } +} + +func (s *session) handlePacketAfterClosed(p *receivedPacket) { + s.packetsReceivedAfterClose++ + if s.connectionClosePacket == nil { + return + } + // exponential backoff + // only send a CONNECTION_CLOSE for the 1st, 2nd, 4th, 8th, 16th, ... packet arriving + for n := s.packetsReceivedAfterClose; n > 1; n = n / 2 { + if n%2 != 0 { + return + } + } + s.logger.Debugf("Received %d packets after sending CONNECTION_CLOSE. Retransmitting.", s.packetsReceivedAfterClose) + if err := s.conn.Write(s.connectionClosePacket.raw); err != nil { + s.logger.Debugf("Error retransmitting CONNECTION_CLOSE: %s", err) + } +} + +func (s *session) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) error { + encLevelChanged, err := s.cryptoStreamManager.HandleCryptoFrame(frame, encLevel) + if err != nil { + return err + } + s.logger.Debugf("Handled crypto frame at level %s. encLevelChanged: %t", encLevel, encLevelChanged) + if encLevelChanged { + s.tryDecryptingQueuedPackets() + } + return nil +} + +func (s *session) handleStreamFrame(frame *wire.StreamFrame, encLevel protocol.EncryptionLevel) error { + // TODO(#1261): implement strict rules for frames types in unencrypted packets + if encLevel < protocol.Encryption1RTT { + return qerr.Error(qerr.ProtocolViolation, fmt.Sprintf("received unencrypted stream data on stream %d", frame.StreamID)) + } + str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) + if err != nil { + return err + } + if str == nil { + // Stream is closed and already garbage collected + // ignore this StreamFrame + return nil + } + return str.handleStreamFrame(frame) +} + +func (s *session) handleMaxDataFrame(frame *wire.MaxDataFrame) { + s.connFlowController.UpdateSendWindow(frame.ByteOffset) +} + +func (s *session) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) error { + str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) + if err != nil { + return err + } + if str == nil { + // stream is closed and already garbage collected + return nil + } + str.handleMaxStreamDataFrame(frame) + return nil +} + +func (s *session) handleMaxStreamsFrame(frame *wire.MaxStreamsFrame) error { + return s.streamsMap.HandleMaxStreamsFrame(frame) +} + +func (s *session) handleResetStreamFrame(frame *wire.ResetStreamFrame) error { + str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) + if err != nil { + return err + } + if str == nil { + // stream is closed and already garbage collected + return nil + } + return str.handleResetStreamFrame(frame) +} + +func (s *session) handleStopSendingFrame(frame *wire.StopSendingFrame) error { + str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) + if err != nil { + return err + } + if str == nil { + // stream is closed and already garbage collected + return nil + } + str.handleStopSendingFrame(frame) + return nil +} + +func (s *session) handlePathChallengeFrame(frame *wire.PathChallengeFrame) { + s.queueControlFrame(&wire.PathResponseFrame{Data: frame.Data}) +} + +func (s *session) handleAckFrame(frame *wire.AckFrame, pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) error { + if err := s.sentPacketHandler.ReceivedAck(frame, pn, encLevel, s.lastPacketReceivedTime); err != nil { + return err + } + if encLevel == protocol.Encryption1RTT { + s.receivedPacketHandler.IgnoreBelow(s.sentPacketHandler.GetLowestPacketNotConfirmedAcked()) + } + return nil +} + +// closeLocal closes the session and send a CONNECTION_CLOSE containing the error +func (s *session) closeLocal(e error) { + s.closeOnce.Do(func() { + if e == nil { + s.logger.Infof("Closing session.") + } else { + s.logger.Errorf("Closing session with error: %s", e) + } + s.sessionRunner.Retire(s.srcConnID) + s.closeChan <- closeError{err: e, sendClose: true, remote: false} + }) +} + +// destroy closes the session without sending the error on the wire +func (s *session) destroy(e error) { + s.closeOnce.Do(func() { + if nerr, ok := e.(net.Error); ok && nerr.Timeout() { + s.logger.Errorf("Destroying session %s: %s", s.destConnID, e) + } else { + s.logger.Errorf("Destroying session %s with error: %s", s.destConnID, e) + } + s.sessionRunner.Remove(s.srcConnID) + s.closeChan <- closeError{err: e, sendClose: false, remote: false} + }) +} + +// closeForRecreating closes the session in order to recreate it immediately afterwards +// It returns the first packet number that should be used in the new session. +func (s *session) closeForRecreating() protocol.PacketNumber { + s.destroy(errCloseForRecreating) + nextPN, _ := s.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial) + return nextPN +} + +func (s *session) closeRemote(e error) { + s.closeOnce.Do(func() { + s.logger.Errorf("Peer closed session with error: %s", e) + s.sessionRunner.Remove(s.srcConnID) + s.closeChan <- closeError{err: e, remote: true} + }) +} + +// Close the connection. It sends a qerr.NoError. +// It waits until the run loop has stopped before returning +func (s *session) Close() error { + s.closeLocal(nil) + <-s.ctx.Done() + return nil +} + +func (s *session) CloseWithError(code protocol.ApplicationErrorCode, e error) error { + s.closeLocal(qerr.Error(qerr.ErrorCode(code), e.Error())) + <-s.ctx.Done() + return nil +} + +func (s *session) handleCloseError(closeErr closeError) { + if closeErr.err == nil { + closeErr.err = qerr.NoError + } + + var quicErr *qerr.QuicError + var ok bool + if quicErr, ok = closeErr.err.(*qerr.QuicError); !ok { + quicErr = qerr.ToQuicError(closeErr.err) + } + + s.streamsMap.CloseWithError(quicErr) + + if !closeErr.sendClose { + return + } + // If this is a remote close we're done here + if closeErr.remote { + return + } + if err := s.sendConnectionClose(quicErr); err != nil { + s.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) + } +} + +func (s *session) processTransportParameters(data []byte) { + var params *handshake.TransportParameters + var err error + switch s.perspective { + case protocol.PerspectiveClient: + params, err = s.processTransportParametersForClient(data) + case protocol.PerspectiveServer: + params, err = s.processTransportParametersForServer(data) + } + if err != nil { + s.closeLocal(err) + return + } + s.logger.Debugf("Received Transport Parameters: %s", params) + s.peerParams = params + if err := s.streamsMap.UpdateLimits(params); err != nil { + s.closeLocal(err) + return + } + s.packer.HandleTransportParameters(params) + s.frameParser.SetAckDelayExponent(params.AckDelayExponent) + s.connFlowController.UpdateSendWindow(params.InitialMaxData) + if params.StatelessResetToken != nil { + s.sessionRunner.AddResetToken(*params.StatelessResetToken, s) + } +} + +func (s *session) processTransportParametersForClient(data []byte) (*handshake.TransportParameters, error) { + params := &handshake.TransportParameters{} + if err := params.Unmarshal(data, s.perspective.Opposite()); err != nil { + return nil, err + } + + // check the Retry token + if !params.OriginalConnectionID.Equal(s.origDestConnID) { + return nil, fmt.Errorf("expected original_connection_id to equal %s, is %s", s.origDestConnID, params.OriginalConnectionID) + } + + return params, nil +} + +func (s *session) processTransportParametersForServer(data []byte) (*handshake.TransportParameters, error) { + params := &handshake.TransportParameters{} + if err := params.Unmarshal(data, s.perspective.Opposite()); err != nil { + return nil, err + } + return params, nil +} + +func (s *session) sendPackets() error { + s.pacingDeadline = time.Time{} + + sendMode := s.sentPacketHandler.SendMode() + if sendMode == ackhandler.SendNone { // shortcut: return immediately if there's nothing to send + return nil + } + + numPackets := s.sentPacketHandler.ShouldSendNumPackets() + var numPacketsSent int +sendLoop: + for { + switch sendMode { + case ackhandler.SendNone: + break sendLoop + case ackhandler.SendAck: + // If we already sent packets, and the send mode switches to SendAck, + // we've just become congestion limited. + // There's no need to try to send an ACK at this moment. + if numPacketsSent > 0 { + return nil + } + // We can at most send a single ACK only packet. + // There will only be a new ACK after receiving new packets. + // SendAck is only returned when we're congestion limited, so we don't need to set the pacingt timer. + return s.maybeSendAckOnlyPacket() + case ackhandler.SendPTO: + if err := s.sendProbePacket(); err != nil { + return err + } + numPacketsSent++ + case ackhandler.SendRetransmission: + sentPacket, err := s.maybeSendRetransmission() + if err != nil { + return err + } + if sentPacket { + numPacketsSent++ + // This can happen if a retransmission queued, but it wasn't necessary to send it. + // e.g. when an Initial is queued, but we already received a packet from the server. + } + case ackhandler.SendAny: + sentPacket, err := s.sendPacket() + if err != nil { + return err + } + if !sentPacket { + break sendLoop + } + numPacketsSent++ + default: + return fmt.Errorf("BUG: invalid send mode %d", sendMode) + } + if numPacketsSent >= numPackets { + break + } + sendMode = s.sentPacketHandler.SendMode() + } + // Only start the pacing timer if we sent as many packets as we were allowed. + // There will probably be more to send when calling sendPacket again. + if numPacketsSent == numPackets { + s.pacingDeadline = s.sentPacketHandler.TimeUntilSend() + } + return nil +} + +func (s *session) maybeSendAckOnlyPacket() error { + packet, err := s.packer.MaybePackAckPacket() + if err != nil { + return err + } + if packet == nil { + return nil + } + s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket()) + return s.sendPackedPacket(packet) +} + +// maybeSendRetransmission sends retransmissions for at most one packet. +// It takes care that Initials aren't retransmitted, if a packet from the server was already received. +func (s *session) maybeSendRetransmission() (bool, error) { + retransmitPacket := s.sentPacketHandler.DequeuePacketForRetransmission() + if retransmitPacket == nil { + return false, nil + } + + s.logger.Debugf("Dequeueing retransmission for packet 0x%x (%s)", retransmitPacket.PacketNumber, retransmitPacket.EncryptionLevel) + packets, err := s.packer.PackRetransmission(retransmitPacket) + if err != nil { + return false, err + } + ackhandlerPackets := make([]*ackhandler.Packet, len(packets)) + for i, packet := range packets { + ackhandlerPackets[i] = packet.ToAckHandlerPacket() + } + s.sentPacketHandler.SentPacketsAsRetransmission(ackhandlerPackets, retransmitPacket.PacketNumber) + for _, packet := range packets { + if err := s.sendPackedPacket(packet); err != nil { + return false, err + } + } + return true, nil +} + +func (s *session) sendProbePacket() error { + p, err := s.sentPacketHandler.DequeueProbePacket() + if err != nil { + return err + } + s.logger.Debugf("Sending a retransmission for %#x as a probe packet.", p.PacketNumber) + + packets, err := s.packer.PackRetransmission(p) + if err != nil { + return err + } + ackhandlerPackets := make([]*ackhandler.Packet, len(packets)) + for i, packet := range packets { + ackhandlerPackets[i] = packet.ToAckHandlerPacket() + } + s.sentPacketHandler.SentPacketsAsRetransmission(ackhandlerPackets, p.PacketNumber) + for _, packet := range packets { + if err := s.sendPackedPacket(packet); err != nil { + return err + } + } + return nil +} + +func (s *session) sendPacket() (bool, error) { + if isBlocked, offset := s.connFlowController.IsNewlyBlocked(); isBlocked { + s.framer.QueueControlFrame(&wire.DataBlockedFrame{DataLimit: offset}) + } + s.windowUpdateQueue.QueueAll() + + packet, err := s.packer.PackPacket() + if err != nil || packet == nil { + return false, err + } + s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket()) + if err := s.sendPackedPacket(packet); err != nil { + return false, err + } + return true, nil +} + +func (s *session) sendPackedPacket(packet *packedPacket) error { + defer packet.buffer.Release() + if s.firstRetransmittablePacketAfterIdleSentTime.IsZero() && packet.IsRetransmittable() { + s.firstRetransmittablePacketAfterIdleSentTime = time.Now() + } + s.logPacket(packet) + return s.conn.Write(packet.raw) +} + +func (s *session) sendConnectionClose(quicErr *qerr.QuicError) error { + var reason string + // don't send details of crypto errors + if !quicErr.IsCryptoError() { + reason = quicErr.ErrorMessage + } + packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{ + ErrorCode: quicErr.ErrorCode, + ReasonPhrase: reason, + }) + if err != nil { + return err + } + s.connectionClosePacket = packet + s.logPacket(packet) + return s.conn.Write(packet.raw) +} + +func (s *session) logPacket(packet *packedPacket) { + if !s.logger.Debug() { + // We don't need to allocate the slices for calling the format functions + return + } + s.logger.Debugf("-> Sending packet 0x%x (%d bytes) for connection %s, %s", packet.header.PacketNumber, len(packet.raw), s.srcConnID, packet.EncryptionLevel()) + packet.header.Log(s.logger) + for _, frame := range packet.frames { + wire.LogFrame(s.logger, frame, true) + } +} + +// GetOrOpenStream either returns an existing stream, a newly opened stream, or nil if a stream with the provided ID is already closed. +// It is *only* needed for gQUIC's H2. +// It will be removed as soon as gQUIC moves towards the IETF H2/QUIC stream mapping. +func (s *session) GetOrOpenStream(id protocol.StreamID) (Stream, error) { + str, err := s.streamsMap.GetOrOpenSendStream(id) + if str != nil { + if bstr, ok := str.(Stream); ok { + return bstr, err + } + return nil, fmt.Errorf("Stream %d is not a bidirectional stream", id) + } + // make sure to return an actual nil value here, not an Stream with value nil + return nil, err +} + +// AcceptStream returns the next stream openend by the peer +func (s *session) AcceptStream() (Stream, error) { + return s.streamsMap.AcceptStream() +} + +func (s *session) AcceptUniStream() (ReceiveStream, error) { + return s.streamsMap.AcceptUniStream() +} + +// OpenStream opens a stream +func (s *session) OpenStream() (Stream, error) { + return s.streamsMap.OpenStream() +} + +func (s *session) OpenStreamSync() (Stream, error) { + return s.streamsMap.OpenStreamSync() +} + +func (s *session) OpenUniStream() (SendStream, error) { + return s.streamsMap.OpenUniStream() +} + +func (s *session) OpenUniStreamSync() (SendStream, error) { + return s.streamsMap.OpenUniStreamSync() +} + +func (s *session) newFlowController(id protocol.StreamID) flowcontrol.StreamFlowController { + var initialSendWindow protocol.ByteCount + if s.peerParams != nil { + if id.Type() == protocol.StreamTypeUni { + initialSendWindow = s.peerParams.InitialMaxStreamDataUni + } else { + if id.InitiatedBy() == s.perspective { + initialSendWindow = s.peerParams.InitialMaxStreamDataBidiRemote + } else { + initialSendWindow = s.peerParams.InitialMaxStreamDataBidiLocal + } + } + } + return flowcontrol.NewStreamFlowController( + id, + s.connFlowController, + protocol.InitialMaxStreamData, + protocol.ByteCount(s.config.MaxReceiveStreamFlowControlWindow), + initialSendWindow, + s.onHasStreamWindowUpdate, + s.rttStats, + s.logger, + ) +} + +// scheduleSending signals that we have data for sending +func (s *session) scheduleSending() { + select { + case s.sendingScheduled <- struct{}{}: + default: + } +} + +func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket) { + if s.handshakeComplete { + s.logger.Debugf("Received undecryptable packet from %s after the handshake (%d bytes)", p.remoteAddr.String(), len(p.data)) + return + } + if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { + s.logger.Infof("Dropping undecrytable packet (%d bytes). Undecryptable packet queue full.", len(p.data)) + return + } + s.logger.Infof("Queueing packet (%d bytes) for later decryption", len(p.data)) + s.undecryptablePackets = append(s.undecryptablePackets, p) +} + +func (s *session) tryDecryptingQueuedPackets() { + for _, p := range s.undecryptablePackets { + s.handlePacket(p) + } + s.undecryptablePackets = s.undecryptablePackets[:0] +} + +func (s *session) queueControlFrame(f wire.Frame) { + s.framer.QueueControlFrame(f) + s.scheduleSending() +} + +func (s *session) onHasStreamWindowUpdate(id protocol.StreamID) { + s.windowUpdateQueue.AddStream(id) + s.scheduleSending() +} + +func (s *session) onHasConnectionWindowUpdate() { + s.windowUpdateQueue.AddConnection() + s.scheduleSending() +} + +func (s *session) onHasStreamData(id protocol.StreamID) { + s.framer.AddActiveStream(id) + s.scheduleSending() +} + +func (s *session) onStreamCompleted(id protocol.StreamID) { + if err := s.streamsMap.DeleteStream(id); err != nil { + s.closeLocal(err) + } +} + +func (s *session) LocalAddr() net.Addr { + return s.conn.LocalAddr() +} + +func (s *session) RemoteAddr() net.Addr { + return s.conn.RemoteAddr() +} + +func (s *session) getPerspective() protocol.Perspective { + return s.perspective +} + +func (s *session) GetVersion() protocol.VersionNumber { + return s.version +} diff --git a/vendor/github.com/lucas-clemente/quic-go/stream.go b/vendor/github.com/lucas-clemente/quic-go/stream.go new file mode 100644 index 00000000..dfd0cc6a --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/stream.go @@ -0,0 +1,163 @@ +package quic + +import ( + "net" + "sync" + "time" + + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +const errorCodeStopping protocol.ApplicationErrorCode = 0 + +// The streamSender is notified by the stream about various events. +type streamSender interface { + queueControlFrame(wire.Frame) + onHasStreamData(protocol.StreamID) + // must be called without holding the mutex that is acquired by closeForShutdown + onStreamCompleted(protocol.StreamID) +} + +// Each of the both stream halves gets its own uniStreamSender. +// This is necessary in order to keep track when both halves have been completed. +type uniStreamSender struct { + streamSender + onStreamCompletedImpl func() +} + +func (s *uniStreamSender) queueControlFrame(f wire.Frame) { + s.streamSender.queueControlFrame(f) +} + +func (s *uniStreamSender) onHasStreamData(id protocol.StreamID) { + s.streamSender.onHasStreamData(id) +} + +func (s *uniStreamSender) onStreamCompleted(protocol.StreamID) { + s.onStreamCompletedImpl() +} + +var _ streamSender = &uniStreamSender{} + +type streamI interface { + Stream + closeForShutdown(error) + // for receiving + handleStreamFrame(*wire.StreamFrame) error + handleResetStreamFrame(*wire.ResetStreamFrame) error + getWindowUpdate() protocol.ByteCount + // for sending + hasData() bool + handleStopSendingFrame(*wire.StopSendingFrame) + popStreamFrame(maxBytes protocol.ByteCount) (*wire.StreamFrame, bool) + handleMaxStreamDataFrame(*wire.MaxStreamDataFrame) +} + +var _ receiveStreamI = (streamI)(nil) +var _ sendStreamI = (streamI)(nil) + +// A Stream assembles the data from StreamFrames and provides a super-convenient Read-Interface +// +// Read() and Write() may be called concurrently, but multiple calls to Read() or Write() individually must be synchronized manually. +type stream struct { + receiveStream + sendStream + + completedMutex sync.Mutex + sender streamSender + receiveStreamCompleted bool + sendStreamCompleted bool + + version protocol.VersionNumber +} + +var _ Stream = &stream{} + +type deadlineError struct{} + +func (deadlineError) Error() string { return "deadline exceeded" } +func (deadlineError) Temporary() bool { return true } +func (deadlineError) Timeout() bool { return true } + +var errDeadline net.Error = &deadlineError{} + +type streamCanceledError struct { + error + errorCode protocol.ApplicationErrorCode +} + +func (streamCanceledError) Canceled() bool { return true } +func (e streamCanceledError) ErrorCode() protocol.ApplicationErrorCode { return e.errorCode } + +var _ StreamError = &streamCanceledError{} + +// newStream creates a new Stream +func newStream(streamID protocol.StreamID, + sender streamSender, + flowController flowcontrol.StreamFlowController, + version protocol.VersionNumber, +) *stream { + s := &stream{sender: sender, version: version} + senderForSendStream := &uniStreamSender{ + streamSender: sender, + onStreamCompletedImpl: func() { + s.completedMutex.Lock() + s.sendStreamCompleted = true + s.checkIfCompleted() + s.completedMutex.Unlock() + }, + } + s.sendStream = *newSendStream(streamID, senderForSendStream, flowController, version) + senderForReceiveStream := &uniStreamSender{ + streamSender: sender, + onStreamCompletedImpl: func() { + s.completedMutex.Lock() + s.receiveStreamCompleted = true + s.checkIfCompleted() + s.completedMutex.Unlock() + }, + } + s.receiveStream = *newReceiveStream(streamID, senderForReceiveStream, flowController, version) + return s +} + +// need to define StreamID() here, since both receiveStream and readStream have a StreamID() +func (s *stream) StreamID() protocol.StreamID { + // the result is same for receiveStream and sendStream + return s.sendStream.StreamID() +} + +func (s *stream) Close() error { + if err := s.sendStream.Close(); err != nil { + return err + } + return nil +} + +func (s *stream) SetDeadline(t time.Time) error { + _ = s.SetReadDeadline(t) // SetReadDeadline never errors + _ = s.SetWriteDeadline(t) // SetWriteDeadline never errors + return nil +} + +// CloseForShutdown closes a stream abruptly. +// It makes Read and Write unblock (and return the error) immediately. +// The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. +func (s *stream) closeForShutdown(err error) { + s.sendStream.closeForShutdown(err) + s.receiveStream.closeForShutdown(err) +} + +func (s *stream) handleResetStreamFrame(frame *wire.ResetStreamFrame) error { + return s.receiveStream.handleResetStreamFrame(frame) +} + +// checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed. +// It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed. +func (s *stream) checkIfCompleted() { + if s.sendStreamCompleted && s.receiveStreamCompleted { + s.sender.onStreamCompleted(s.StreamID()) + } +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map.go b/vendor/github.com/lucas-clemente/quic-go/streams_map.go new file mode 100644 index 00000000..846ece00 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map.go @@ -0,0 +1,192 @@ +package quic + +import ( + "errors" + "fmt" + "net" + + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/handshake" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type streamOpenErr struct{ error } + +var _ net.Error = &streamOpenErr{} + +func (e streamOpenErr) Temporary() bool { return e.error == errTooManyOpenStreams } +func (streamOpenErr) Timeout() bool { return false } + +// errTooManyOpenStreams is used internally by the outgoing streams maps. +var errTooManyOpenStreams = errors.New("too many open streams") + +type streamsMap struct { + perspective protocol.Perspective + + sender streamSender + newFlowController func(protocol.StreamID) flowcontrol.StreamFlowController + + outgoingBidiStreams *outgoingBidiStreamsMap + outgoingUniStreams *outgoingUniStreamsMap + incomingBidiStreams *incomingBidiStreamsMap + incomingUniStreams *incomingUniStreamsMap +} + +var _ streamManager = &streamsMap{} + +func newStreamsMap( + sender streamSender, + newFlowController func(protocol.StreamID) flowcontrol.StreamFlowController, + maxIncomingStreams uint64, + maxIncomingUniStreams uint64, + perspective protocol.Perspective, + version protocol.VersionNumber, +) streamManager { + m := &streamsMap{ + perspective: perspective, + newFlowController: newFlowController, + sender: sender, + } + newBidiStream := func(id protocol.StreamID) streamI { + return newStream(id, m.sender, m.newFlowController(id), version) + } + newUniSendStream := func(id protocol.StreamID) sendStreamI { + return newSendStream(id, m.sender, m.newFlowController(id), version) + } + newUniReceiveStream := func(id protocol.StreamID) receiveStreamI { + return newReceiveStream(id, m.sender, m.newFlowController(id), version) + } + m.outgoingBidiStreams = newOutgoingBidiStreamsMap( + protocol.FirstStream(protocol.StreamTypeBidi, perspective), + newBidiStream, + sender.queueControlFrame, + ) + m.incomingBidiStreams = newIncomingBidiStreamsMap( + protocol.FirstStream(protocol.StreamTypeBidi, perspective.Opposite()), + protocol.MaxStreamID(protocol.StreamTypeBidi, maxIncomingStreams, perspective.Opposite()), + maxIncomingStreams, + sender.queueControlFrame, + newBidiStream, + ) + m.outgoingUniStreams = newOutgoingUniStreamsMap( + protocol.FirstStream(protocol.StreamTypeUni, perspective), + newUniSendStream, + sender.queueControlFrame, + ) + m.incomingUniStreams = newIncomingUniStreamsMap( + protocol.FirstStream(protocol.StreamTypeUni, perspective.Opposite()), + protocol.MaxStreamID(protocol.StreamTypeUni, maxIncomingUniStreams, perspective.Opposite()), + maxIncomingUniStreams, + sender.queueControlFrame, + newUniReceiveStream, + ) + return m +} + +func (m *streamsMap) OpenStream() (Stream, error) { + return m.outgoingBidiStreams.OpenStream() +} + +func (m *streamsMap) OpenStreamSync() (Stream, error) { + return m.outgoingBidiStreams.OpenStreamSync() +} + +func (m *streamsMap) OpenUniStream() (SendStream, error) { + return m.outgoingUniStreams.OpenStream() +} + +func (m *streamsMap) OpenUniStreamSync() (SendStream, error) { + return m.outgoingUniStreams.OpenStreamSync() +} + +func (m *streamsMap) AcceptStream() (Stream, error) { + return m.incomingBidiStreams.AcceptStream() +} + +func (m *streamsMap) AcceptUniStream() (ReceiveStream, error) { + return m.incomingUniStreams.AcceptStream() +} + +func (m *streamsMap) DeleteStream(id protocol.StreamID) error { + switch id.Type() { + case protocol.StreamTypeUni: + if id.InitiatedBy() == m.perspective { + return m.outgoingUniStreams.DeleteStream(id) + } + return m.incomingUniStreams.DeleteStream(id) + case protocol.StreamTypeBidi: + if id.InitiatedBy() == m.perspective { + return m.outgoingBidiStreams.DeleteStream(id) + } + return m.incomingBidiStreams.DeleteStream(id) + } + panic("") +} + +func (m *streamsMap) GetOrOpenReceiveStream(id protocol.StreamID) (receiveStreamI, error) { + switch id.Type() { + case protocol.StreamTypeUni: + if id.InitiatedBy() == m.perspective { + // an outgoing unidirectional stream is a send stream, not a receive stream + return nil, fmt.Errorf("peer attempted to open receive stream %d", id) + } + return m.incomingUniStreams.GetOrOpenStream(id) + case protocol.StreamTypeBidi: + if id.InitiatedBy() == m.perspective { + return m.outgoingBidiStreams.GetStream(id) + } + return m.incomingBidiStreams.GetOrOpenStream(id) + } + panic("") +} + +func (m *streamsMap) GetOrOpenSendStream(id protocol.StreamID) (sendStreamI, error) { + switch id.Type() { + case protocol.StreamTypeUni: + if id.InitiatedBy() == m.perspective { + return m.outgoingUniStreams.GetStream(id) + } + // an incoming unidirectional stream is a receive stream, not a send stream + return nil, fmt.Errorf("peer attempted to open send stream %d", id) + case protocol.StreamTypeBidi: + if id.InitiatedBy() == m.perspective { + return m.outgoingBidiStreams.GetStream(id) + } + return m.incomingBidiStreams.GetOrOpenStream(id) + } + panic("") +} + +func (m *streamsMap) HandleMaxStreamsFrame(f *wire.MaxStreamsFrame) error { + if f.MaxStreams > protocol.MaxStreamCount { + return qerr.StreamLimitError + } + id := protocol.MaxStreamID(f.Type, f.MaxStreams, m.perspective) + switch id.Type() { + case protocol.StreamTypeUni: + m.outgoingUniStreams.SetMaxStream(id) + case protocol.StreamTypeBidi: + fmt.Printf("") + m.outgoingBidiStreams.SetMaxStream(id) + } + return nil +} + +func (m *streamsMap) UpdateLimits(p *handshake.TransportParameters) error { + if p.MaxBidiStreams > protocol.MaxStreamCount || p.MaxUniStreams > protocol.MaxStreamCount { + return qerr.StreamLimitError + } + // Max{Uni,Bidi}StreamID returns the highest stream ID that the peer is allowed to open. + m.outgoingBidiStreams.SetMaxStream(protocol.MaxStreamID(protocol.StreamTypeBidi, p.MaxBidiStreams, m.perspective)) + m.outgoingUniStreams.SetMaxStream(protocol.MaxStreamID(protocol.StreamTypeUni, p.MaxUniStreams, m.perspective)) + return nil +} + +func (m *streamsMap) CloseWithError(err error) { + m.outgoingBidiStreams.CloseWithError(err) + m.outgoingUniStreams.CloseWithError(err) + m.incomingBidiStreams.CloseWithError(err) + m.incomingUniStreams.CloseWithError(err) +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go new file mode 100644 index 00000000..692f093e --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go @@ -0,0 +1,17 @@ +package quic + +import ( + "github.com/cheekybits/genny/generic" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// In the auto-generated streams maps, we need to be able to close the streams. +// Therefore, extend the generic.Type with the stream close method. +// This definition must be in a file that Genny doesn't process. +type item interface { + generic.Type + closeForShutdown(error) +} + +const streamTypeGeneric protocol.StreamType = protocol.StreamTypeUni diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go new file mode 100644 index 00000000..787c3d90 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go @@ -0,0 +1,162 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type incomingBidiStreamsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]streamI + // When a stream is deleted before it was accepted, we can't delete it immediately. + // We need to wait until the application accepts it, and delete it immediately then. + streamsToDelete map[protocol.StreamID]struct{} // used as a set + + nextStreamToAccept protocol.StreamID // the next stream that will be returned by AcceptStream() + nextStreamToOpen protocol.StreamID // the highest stream that the peer openend + maxStream protocol.StreamID // the highest stream that the peer is allowed to open + maxNumStreams uint64 // maximum number of streams + + newStream func(protocol.StreamID) streamI + queueMaxStreamID func(*wire.MaxStreamsFrame) + + closeErr error +} + +func newIncomingBidiStreamsMap( + nextStreamToAccept protocol.StreamID, + initialMaxStreamID protocol.StreamID, + maxNumStreams uint64, + queueControlFrame func(wire.Frame), + newStream func(protocol.StreamID) streamI, +) *incomingBidiStreamsMap { + m := &incomingBidiStreamsMap{ + streams: make(map[protocol.StreamID]streamI), + streamsToDelete: make(map[protocol.StreamID]struct{}), + nextStreamToAccept: nextStreamToAccept, + nextStreamToOpen: nextStreamToAccept, + maxStream: initialMaxStreamID, + maxNumStreams: maxNumStreams, + newStream: newStream, + queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *incomingBidiStreamsMap) AcceptStream() (streamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + var id protocol.StreamID + var str streamI + for { + id = m.nextStreamToAccept + var ok bool + if m.closeErr != nil { + return nil, m.closeErr + } + str, ok = m.streams[id] + if ok { + break + } + m.cond.Wait() + } + m.nextStreamToAccept += 4 + // If this stream was completed before being accepted, we can delete it now. + if _, ok := m.streamsToDelete[id]; ok { + delete(m.streamsToDelete, id) + if err := m.deleteStream(id); err != nil { + return nil, err + } + } + return str, nil +} + +func (m *incomingBidiStreamsMap) GetOrOpenStream(id protocol.StreamID) (streamI, error) { + m.mutex.RLock() + if id > m.maxStream { + m.mutex.RUnlock() + return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) + } + // if the id is smaller than the highest we accepted + // * this stream exists in the map, and we can return it, or + // * this stream was already closed, then we can return the nil + if id < m.nextStreamToOpen { + var s streamI + // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. + if _, ok := m.streamsToDelete[id]; !ok { + s = m.streams[id] + } + m.mutex.RUnlock() + return s, nil + } + m.mutex.RUnlock() + + m.mutex.Lock() + // no need to check the two error conditions from above again + // * maxStream can only increase, so if the id was valid before, it definitely is valid now + // * highestStream is only modified by this function + for newID := m.nextStreamToOpen; newID <= id; newID += 4 { + m.streams[newID] = m.newStream(newID) + m.cond.Signal() + } + m.nextStreamToOpen = id + 4 + s := m.streams[id] + m.mutex.Unlock() + return s, nil +} + +func (m *incomingBidiStreamsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + return m.deleteStream(id) +} + +func (m *incomingBidiStreamsMap) deleteStream(id protocol.StreamID) error { + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + + // Don't delete this stream yet, if it was not yet accepted. + // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. + if id >= m.nextStreamToAccept { + if _, ok := m.streamsToDelete[id]; ok { + return fmt.Errorf("Tried to delete stream %d multiple times", id) + } + m.streamsToDelete[id] = struct{}{} + return nil + } + + delete(m.streams, id) + // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream + if m.maxNumStreams > uint64(len(m.streams)) { + numNewStreams := m.maxNumStreams - uint64(len(m.streams)) + m.maxStream = m.nextStreamToOpen + protocol.StreamID((numNewStreams-1)*4) + m.queueMaxStreamID(&wire.MaxStreamsFrame{ + Type: protocol.StreamTypeBidi, + MaxStreams: m.maxStream.StreamNum(), + }) + } + return nil +} + +func (m *incomingBidiStreamsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.mutex.Unlock() + m.cond.Broadcast() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go new file mode 100644 index 00000000..503f0290 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go @@ -0,0 +1,160 @@ +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +//go:generate genny -in $GOFILE -out streams_map_incoming_bidi.go gen "item=streamI Item=BidiStream streamTypeGeneric=protocol.StreamTypeBidi" +//go:generate genny -in $GOFILE -out streams_map_incoming_uni.go gen "item=receiveStreamI Item=UniStream streamTypeGeneric=protocol.StreamTypeUni" +type incomingItemsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]item + // When a stream is deleted before it was accepted, we can't delete it immediately. + // We need to wait until the application accepts it, and delete it immediately then. + streamsToDelete map[protocol.StreamID]struct{} // used as a set + + nextStreamToAccept protocol.StreamID // the next stream that will be returned by AcceptStream() + nextStreamToOpen protocol.StreamID // the highest stream that the peer openend + maxStream protocol.StreamID // the highest stream that the peer is allowed to open + maxNumStreams uint64 // maximum number of streams + + newStream func(protocol.StreamID) item + queueMaxStreamID func(*wire.MaxStreamsFrame) + + closeErr error +} + +func newIncomingItemsMap( + nextStreamToAccept protocol.StreamID, + initialMaxStreamID protocol.StreamID, + maxNumStreams uint64, + queueControlFrame func(wire.Frame), + newStream func(protocol.StreamID) item, +) *incomingItemsMap { + m := &incomingItemsMap{ + streams: make(map[protocol.StreamID]item), + streamsToDelete: make(map[protocol.StreamID]struct{}), + nextStreamToAccept: nextStreamToAccept, + nextStreamToOpen: nextStreamToAccept, + maxStream: initialMaxStreamID, + maxNumStreams: maxNumStreams, + newStream: newStream, + queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *incomingItemsMap) AcceptStream() (item, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + var id protocol.StreamID + var str item + for { + id = m.nextStreamToAccept + var ok bool + if m.closeErr != nil { + return nil, m.closeErr + } + str, ok = m.streams[id] + if ok { + break + } + m.cond.Wait() + } + m.nextStreamToAccept += 4 + // If this stream was completed before being accepted, we can delete it now. + if _, ok := m.streamsToDelete[id]; ok { + delete(m.streamsToDelete, id) + if err := m.deleteStream(id); err != nil { + return nil, err + } + } + return str, nil +} + +func (m *incomingItemsMap) GetOrOpenStream(id protocol.StreamID) (item, error) { + m.mutex.RLock() + if id > m.maxStream { + m.mutex.RUnlock() + return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) + } + // if the id is smaller than the highest we accepted + // * this stream exists in the map, and we can return it, or + // * this stream was already closed, then we can return the nil + if id < m.nextStreamToOpen { + var s item + // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. + if _, ok := m.streamsToDelete[id]; !ok { + s = m.streams[id] + } + m.mutex.RUnlock() + return s, nil + } + m.mutex.RUnlock() + + m.mutex.Lock() + // no need to check the two error conditions from above again + // * maxStream can only increase, so if the id was valid before, it definitely is valid now + // * highestStream is only modified by this function + for newID := m.nextStreamToOpen; newID <= id; newID += 4 { + m.streams[newID] = m.newStream(newID) + m.cond.Signal() + } + m.nextStreamToOpen = id + 4 + s := m.streams[id] + m.mutex.Unlock() + return s, nil +} + +func (m *incomingItemsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + return m.deleteStream(id) +} + +func (m *incomingItemsMap) deleteStream(id protocol.StreamID) error { + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + + // Don't delete this stream yet, if it was not yet accepted. + // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. + if id >= m.nextStreamToAccept { + if _, ok := m.streamsToDelete[id]; ok { + return fmt.Errorf("Tried to delete stream %d multiple times", id) + } + m.streamsToDelete[id] = struct{}{} + return nil + } + + delete(m.streams, id) + // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream + if m.maxNumStreams > uint64(len(m.streams)) { + numNewStreams := m.maxNumStreams - uint64(len(m.streams)) + m.maxStream = m.nextStreamToOpen + protocol.StreamID((numNewStreams-1)*4) + m.queueMaxStreamID(&wire.MaxStreamsFrame{ + Type: streamTypeGeneric, + MaxStreams: m.maxStream.StreamNum(), + }) + } + return nil +} + +func (m *incomingItemsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.mutex.Unlock() + m.cond.Broadcast() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go new file mode 100644 index 00000000..f36fcee5 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go @@ -0,0 +1,162 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type incomingUniStreamsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]receiveStreamI + // When a stream is deleted before it was accepted, we can't delete it immediately. + // We need to wait until the application accepts it, and delete it immediately then. + streamsToDelete map[protocol.StreamID]struct{} // used as a set + + nextStreamToAccept protocol.StreamID // the next stream that will be returned by AcceptStream() + nextStreamToOpen protocol.StreamID // the highest stream that the peer openend + maxStream protocol.StreamID // the highest stream that the peer is allowed to open + maxNumStreams uint64 // maximum number of streams + + newStream func(protocol.StreamID) receiveStreamI + queueMaxStreamID func(*wire.MaxStreamsFrame) + + closeErr error +} + +func newIncomingUniStreamsMap( + nextStreamToAccept protocol.StreamID, + initialMaxStreamID protocol.StreamID, + maxNumStreams uint64, + queueControlFrame func(wire.Frame), + newStream func(protocol.StreamID) receiveStreamI, +) *incomingUniStreamsMap { + m := &incomingUniStreamsMap{ + streams: make(map[protocol.StreamID]receiveStreamI), + streamsToDelete: make(map[protocol.StreamID]struct{}), + nextStreamToAccept: nextStreamToAccept, + nextStreamToOpen: nextStreamToAccept, + maxStream: initialMaxStreamID, + maxNumStreams: maxNumStreams, + newStream: newStream, + queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *incomingUniStreamsMap) AcceptStream() (receiveStreamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + var id protocol.StreamID + var str receiveStreamI + for { + id = m.nextStreamToAccept + var ok bool + if m.closeErr != nil { + return nil, m.closeErr + } + str, ok = m.streams[id] + if ok { + break + } + m.cond.Wait() + } + m.nextStreamToAccept += 4 + // If this stream was completed before being accepted, we can delete it now. + if _, ok := m.streamsToDelete[id]; ok { + delete(m.streamsToDelete, id) + if err := m.deleteStream(id); err != nil { + return nil, err + } + } + return str, nil +} + +func (m *incomingUniStreamsMap) GetOrOpenStream(id protocol.StreamID) (receiveStreamI, error) { + m.mutex.RLock() + if id > m.maxStream { + m.mutex.RUnlock() + return nil, fmt.Errorf("peer tried to open stream %d (current limit: %d)", id, m.maxStream) + } + // if the id is smaller than the highest we accepted + // * this stream exists in the map, and we can return it, or + // * this stream was already closed, then we can return the nil + if id < m.nextStreamToOpen { + var s receiveStreamI + // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. + if _, ok := m.streamsToDelete[id]; !ok { + s = m.streams[id] + } + m.mutex.RUnlock() + return s, nil + } + m.mutex.RUnlock() + + m.mutex.Lock() + // no need to check the two error conditions from above again + // * maxStream can only increase, so if the id was valid before, it definitely is valid now + // * highestStream is only modified by this function + for newID := m.nextStreamToOpen; newID <= id; newID += 4 { + m.streams[newID] = m.newStream(newID) + m.cond.Signal() + } + m.nextStreamToOpen = id + 4 + s := m.streams[id] + m.mutex.Unlock() + return s, nil +} + +func (m *incomingUniStreamsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + return m.deleteStream(id) +} + +func (m *incomingUniStreamsMap) deleteStream(id protocol.StreamID) error { + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + + // Don't delete this stream yet, if it was not yet accepted. + // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. + if id >= m.nextStreamToAccept { + if _, ok := m.streamsToDelete[id]; ok { + return fmt.Errorf("Tried to delete stream %d multiple times", id) + } + m.streamsToDelete[id] = struct{}{} + return nil + } + + delete(m.streams, id) + // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream + if m.maxNumStreams > uint64(len(m.streams)) { + numNewStreams := m.maxNumStreams - uint64(len(m.streams)) + m.maxStream = m.nextStreamToOpen + protocol.StreamID((numNewStreams-1)*4) + m.queueMaxStreamID(&wire.MaxStreamsFrame{ + Type: protocol.StreamTypeUni, + MaxStreams: m.maxStream.StreamNum(), + }) + } + return nil +} + +func (m *incomingUniStreamsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.mutex.Unlock() + m.cond.Broadcast() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go new file mode 100644 index 00000000..a4457775 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go @@ -0,0 +1,147 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type outgoingBidiStreamsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]streamI + + nextStream protocol.StreamID // stream ID of the stream returned by OpenStream(Sync) + maxStream protocol.StreamID // the maximum stream ID we're allowed to open + maxStreamSet bool // was maxStream set. If not, it's not possible to any stream (also works for stream 0) + blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream + + newStream func(protocol.StreamID) streamI + queueStreamIDBlocked func(*wire.StreamsBlockedFrame) + + closeErr error +} + +func newOutgoingBidiStreamsMap( + nextStream protocol.StreamID, + newStream func(protocol.StreamID) streamI, + queueControlFrame func(wire.Frame), +) *outgoingBidiStreamsMap { + m := &outgoingBidiStreamsMap{ + streams: make(map[protocol.StreamID]streamI), + nextStream: nextStream, + newStream: newStream, + queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *outgoingBidiStreamsMap) OpenStream() (streamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + if m.closeErr != nil { + return nil, m.closeErr + } + + str, err := m.openStreamImpl() + if err != nil { + return nil, streamOpenErr{err} + } + return str, nil +} + +func (m *outgoingBidiStreamsMap) OpenStreamSync() (streamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + for { + if m.closeErr != nil { + return nil, m.closeErr + } + str, err := m.openStreamImpl() + if err == nil { + return str, nil + } + if err != nil && err != errTooManyOpenStreams { + return nil, streamOpenErr{err} + } + m.cond.Wait() + } +} + +func (m *outgoingBidiStreamsMap) openStreamImpl() (streamI, error) { + if !m.maxStreamSet || m.nextStream > m.maxStream { + if !m.blockedSent { + if m.maxStreamSet { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: protocol.StreamTypeBidi, + StreamLimit: m.maxStream.StreamNum(), + }) + } else { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: protocol.StreamTypeBidi, + StreamLimit: 0, + }) + } + m.blockedSent = true + } + return nil, errTooManyOpenStreams + } + s := m.newStream(m.nextStream) + m.streams[m.nextStream] = s + m.nextStream += 4 + return s, nil +} + +func (m *outgoingBidiStreamsMap) GetStream(id protocol.StreamID) (streamI, error) { + m.mutex.RLock() + if id >= m.nextStream { + m.mutex.RUnlock() + return nil, qerr.Error(qerr.StreamStateError, fmt.Sprintf("peer attempted to open stream %d", id)) + } + s := m.streams[id] + m.mutex.RUnlock() + return s, nil +} + +func (m *outgoingBidiStreamsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + delete(m.streams, id) + return nil +} + +func (m *outgoingBidiStreamsMap) SetMaxStream(id protocol.StreamID) { + m.mutex.Lock() + if !m.maxStreamSet || id > m.maxStream { + m.maxStream = id + m.maxStreamSet = true + m.blockedSent = false + m.cond.Broadcast() + } + m.mutex.Unlock() +} + +func (m *outgoingBidiStreamsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.cond.Broadcast() + m.mutex.Unlock() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go new file mode 100644 index 00000000..c0657b90 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go @@ -0,0 +1,145 @@ +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +//go:generate genny -in $GOFILE -out streams_map_outgoing_bidi.go gen "item=streamI Item=BidiStream streamTypeGeneric=protocol.StreamTypeBidi" +//go:generate genny -in $GOFILE -out streams_map_outgoing_uni.go gen "item=sendStreamI Item=UniStream streamTypeGeneric=protocol.StreamTypeUni" +type outgoingItemsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]item + + nextStream protocol.StreamID // stream ID of the stream returned by OpenStream(Sync) + maxStream protocol.StreamID // the maximum stream ID we're allowed to open + maxStreamSet bool // was maxStream set. If not, it's not possible to any stream (also works for stream 0) + blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream + + newStream func(protocol.StreamID) item + queueStreamIDBlocked func(*wire.StreamsBlockedFrame) + + closeErr error +} + +func newOutgoingItemsMap( + nextStream protocol.StreamID, + newStream func(protocol.StreamID) item, + queueControlFrame func(wire.Frame), +) *outgoingItemsMap { + m := &outgoingItemsMap{ + streams: make(map[protocol.StreamID]item), + nextStream: nextStream, + newStream: newStream, + queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *outgoingItemsMap) OpenStream() (item, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + if m.closeErr != nil { + return nil, m.closeErr + } + + str, err := m.openStreamImpl() + if err != nil { + return nil, streamOpenErr{err} + } + return str, nil +} + +func (m *outgoingItemsMap) OpenStreamSync() (item, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + for { + if m.closeErr != nil { + return nil, m.closeErr + } + str, err := m.openStreamImpl() + if err == nil { + return str, nil + } + if err != nil && err != errTooManyOpenStreams { + return nil, streamOpenErr{err} + } + m.cond.Wait() + } +} + +func (m *outgoingItemsMap) openStreamImpl() (item, error) { + if !m.maxStreamSet || m.nextStream > m.maxStream { + if !m.blockedSent { + if m.maxStreamSet { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: streamTypeGeneric, + StreamLimit: m.maxStream.StreamNum(), + }) + } else { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: streamTypeGeneric, + StreamLimit: 0, + }) + } + m.blockedSent = true + } + return nil, errTooManyOpenStreams + } + s := m.newStream(m.nextStream) + m.streams[m.nextStream] = s + m.nextStream += 4 + return s, nil +} + +func (m *outgoingItemsMap) GetStream(id protocol.StreamID) (item, error) { + m.mutex.RLock() + if id >= m.nextStream { + m.mutex.RUnlock() + return nil, qerr.Error(qerr.StreamStateError, fmt.Sprintf("peer attempted to open stream %d", id)) + } + s := m.streams[id] + m.mutex.RUnlock() + return s, nil +} + +func (m *outgoingItemsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + delete(m.streams, id) + return nil +} + +func (m *outgoingItemsMap) SetMaxStream(id protocol.StreamID) { + m.mutex.Lock() + if !m.maxStreamSet || id > m.maxStream { + m.maxStream = id + m.maxStreamSet = true + m.blockedSent = false + m.cond.Broadcast() + } + m.mutex.Unlock() +} + +func (m *outgoingItemsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.cond.Broadcast() + m.mutex.Unlock() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go new file mode 100644 index 00000000..a38240a6 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go @@ -0,0 +1,147 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package quic + +import ( + "fmt" + "sync" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type outgoingUniStreamsMap struct { + mutex sync.RWMutex + cond sync.Cond + + streams map[protocol.StreamID]sendStreamI + + nextStream protocol.StreamID // stream ID of the stream returned by OpenStream(Sync) + maxStream protocol.StreamID // the maximum stream ID we're allowed to open + maxStreamSet bool // was maxStream set. If not, it's not possible to any stream (also works for stream 0) + blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream + + newStream func(protocol.StreamID) sendStreamI + queueStreamIDBlocked func(*wire.StreamsBlockedFrame) + + closeErr error +} + +func newOutgoingUniStreamsMap( + nextStream protocol.StreamID, + newStream func(protocol.StreamID) sendStreamI, + queueControlFrame func(wire.Frame), +) *outgoingUniStreamsMap { + m := &outgoingUniStreamsMap{ + streams: make(map[protocol.StreamID]sendStreamI), + nextStream: nextStream, + newStream: newStream, + queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, + } + m.cond.L = &m.mutex + return m +} + +func (m *outgoingUniStreamsMap) OpenStream() (sendStreamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + if m.closeErr != nil { + return nil, m.closeErr + } + + str, err := m.openStreamImpl() + if err != nil { + return nil, streamOpenErr{err} + } + return str, nil +} + +func (m *outgoingUniStreamsMap) OpenStreamSync() (sendStreamI, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + for { + if m.closeErr != nil { + return nil, m.closeErr + } + str, err := m.openStreamImpl() + if err == nil { + return str, nil + } + if err != nil && err != errTooManyOpenStreams { + return nil, streamOpenErr{err} + } + m.cond.Wait() + } +} + +func (m *outgoingUniStreamsMap) openStreamImpl() (sendStreamI, error) { + if !m.maxStreamSet || m.nextStream > m.maxStream { + if !m.blockedSent { + if m.maxStreamSet { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: protocol.StreamTypeUni, + StreamLimit: m.maxStream.StreamNum(), + }) + } else { + m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ + Type: protocol.StreamTypeUni, + StreamLimit: 0, + }) + } + m.blockedSent = true + } + return nil, errTooManyOpenStreams + } + s := m.newStream(m.nextStream) + m.streams[m.nextStream] = s + m.nextStream += 4 + return s, nil +} + +func (m *outgoingUniStreamsMap) GetStream(id protocol.StreamID) (sendStreamI, error) { + m.mutex.RLock() + if id >= m.nextStream { + m.mutex.RUnlock() + return nil, qerr.Error(qerr.StreamStateError, fmt.Sprintf("peer attempted to open stream %d", id)) + } + s := m.streams[id] + m.mutex.RUnlock() + return s, nil +} + +func (m *outgoingUniStreamsMap) DeleteStream(id protocol.StreamID) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("Tried to delete unknown stream %d", id) + } + delete(m.streams, id) + return nil +} + +func (m *outgoingUniStreamsMap) SetMaxStream(id protocol.StreamID) { + m.mutex.Lock() + if !m.maxStreamSet || id > m.maxStream { + m.maxStream = id + m.maxStreamSet = true + m.blockedSent = false + m.cond.Broadcast() + } + m.mutex.Unlock() +} + +func (m *outgoingUniStreamsMap) CloseWithError(err error) { + m.mutex.Lock() + m.closeErr = err + for _, str := range m.streams { + str.closeForShutdown(err) + } + m.cond.Broadcast() + m.mutex.Unlock() +} diff --git a/vendor/github.com/lucas-clemente/quic-go/window_update_queue.go b/vendor/github.com/lucas-clemente/quic-go/window_update_queue.go new file mode 100644 index 00000000..64b912a3 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/window_update_queue.go @@ -0,0 +1,71 @@ +package quic + +import ( + "sync" + + "github.com/lucas-clemente/quic-go/internal/flowcontrol" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +type windowUpdateQueue struct { + mutex sync.Mutex + + queue map[protocol.StreamID]bool // used as a set + queuedConn bool // connection-level window update + + streamGetter streamGetter + connFlowController flowcontrol.ConnectionFlowController + callback func(wire.Frame) +} + +func newWindowUpdateQueue( + streamGetter streamGetter, + connFC flowcontrol.ConnectionFlowController, + cb func(wire.Frame), +) *windowUpdateQueue { + return &windowUpdateQueue{ + queue: make(map[protocol.StreamID]bool), + streamGetter: streamGetter, + connFlowController: connFC, + callback: cb, + } +} + +func (q *windowUpdateQueue) AddStream(id protocol.StreamID) { + q.mutex.Lock() + q.queue[id] = true + q.mutex.Unlock() +} + +func (q *windowUpdateQueue) AddConnection() { + q.mutex.Lock() + q.queuedConn = true + q.mutex.Unlock() +} + +func (q *windowUpdateQueue) QueueAll() { + q.mutex.Lock() + // queue a connection-level window update + if q.queuedConn { + q.callback(&wire.MaxDataFrame{ByteOffset: q.connFlowController.GetWindowUpdate()}) + q.queuedConn = false + } + // queue all stream-level window updates + for id := range q.queue { + str, err := q.streamGetter.GetOrOpenReceiveStream(id) + if err != nil || str == nil { // the stream can be nil if it was completed before dequeing the window update + continue + } + offset := str.getWindowUpdate() + if offset == 0 { // can happen if we received a final offset, right after queueing the window update + continue + } + q.callback(&wire.MaxStreamDataFrame{ + StreamID: id, + ByteOffset: offset, + }) + delete(q.queue, id) + } + q.mutex.Unlock() +} diff --git a/vendor/github.com/magiconair/properties/.travis.yml b/vendor/github.com/magiconair/properties/.travis.yml new file mode 100644 index 00000000..f07376f9 --- /dev/null +++ b/vendor/github.com/magiconair/properties/.travis.yml @@ -0,0 +1,12 @@ +language: go +go: + - 1.4.x + - 1.5.x + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - "1.10.x" + - "1.11.x" + - "1.12.x" + - tip diff --git a/vendor/github.com/magiconair/properties/CHANGELOG.md b/vendor/github.com/magiconair/properties/CHANGELOG.md new file mode 100644 index 00000000..176626a1 --- /dev/null +++ b/vendor/github.com/magiconair/properties/CHANGELOG.md @@ -0,0 +1,139 @@ +## Changelog + +### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019 + + * [PR #26](https://github.com/magiconair/properties/pull/35): Close body always after request + + This patch ensures that in `LoadURL` the response body is always closed. + + Thanks to [@liubog2008](https://github.com/liubog2008) for the patch. + +### [1.8](https://github.com/magiconair/properties/tree/v1.8) - 15 May 2018 + + * [PR #26](https://github.com/magiconair/properties/pull/26): Disable expansion during loading + + This adds the option to disable property expansion during loading. + + Thanks to [@kmala](https://github.com/kmala) for the patch. + +### [1.7.6](https://github.com/magiconair/properties/tree/v1.7.6) - 14 Feb 2018 + + * [PR #29](https://github.com/magiconair/properties/pull/29): Reworked expansion logic to handle more complex cases. + + See PR for an example. + + Thanks to [@yobert](https://github.com/yobert) for the fix. + +### [1.7.5](https://github.com/magiconair/properties/tree/v1.7.5) - 13 Feb 2018 + + * [PR #28](https://github.com/magiconair/properties/pull/28): Support duplicate expansions in the same value + + Values which expand the same key multiple times (e.g. `key=${a} ${a}`) will no longer fail + with a `circular reference error`. + + Thanks to [@yobert](https://github.com/yobert) for the fix. + +### [1.7.4](https://github.com/magiconair/properties/tree/v1.7.4) - 31 Oct 2017 + + * [Issue #23](https://github.com/magiconair/properties/issues/23): Ignore blank lines with whitespaces + + * [PR #24](https://github.com/magiconair/properties/pull/24): Update keys when DisableExpansion is enabled + + Thanks to [@mgurov](https://github.com/mgurov) for the fix. + +### [1.7.3](https://github.com/magiconair/properties/tree/v1.7.3) - 10 Jul 2017 + + * [Issue #17](https://github.com/magiconair/properties/issues/17): Add [SetValue()](http://godoc.org/github.com/magiconair/properties#Properties.SetValue) method to set values generically + * [Issue #22](https://github.com/magiconair/properties/issues/22): Add [LoadMap()](http://godoc.org/github.com/magiconair/properties#LoadMap) function to load properties from a string map + +### [1.7.2](https://github.com/magiconair/properties/tree/v1.7.2) - 20 Mar 2017 + + * [Issue #15](https://github.com/magiconair/properties/issues/15): Drop gocheck dependency + * [PR #21](https://github.com/magiconair/properties/pull/21): Add [Map()](http://godoc.org/github.com/magiconair/properties#Properties.Map) and [FilterFunc()](http://godoc.org/github.com/magiconair/properties#Properties.FilterFunc) + +### [1.7.1](https://github.com/magiconair/properties/tree/v1.7.1) - 13 Jan 2017 + + * [Issue #14](https://github.com/magiconair/properties/issues/14): Decouple TestLoadExpandedFile from `$USER` + * [PR #12](https://github.com/magiconair/properties/pull/12): Load from files and URLs + * [PR #16](https://github.com/magiconair/properties/pull/16): Keep gofmt happy + * [PR #18](https://github.com/magiconair/properties/pull/18): Fix Delete() function + +### [1.7.0](https://github.com/magiconair/properties/tree/v1.7.0) - 20 Mar 2016 + + * [Issue #10](https://github.com/magiconair/properties/issues/10): Add [LoadURL,LoadURLs,MustLoadURL,MustLoadURLs](http://godoc.org/github.com/magiconair/properties#LoadURL) method to load properties from a URL. + * [Issue #11](https://github.com/magiconair/properties/issues/11): Add [LoadString,MustLoadString](http://godoc.org/github.com/magiconair/properties#LoadString) method to load properties from an UTF8 string. + * [PR #8](https://github.com/magiconair/properties/pull/8): Add [MustFlag](http://godoc.org/github.com/magiconair/properties#Properties.MustFlag) method to provide overrides via command line flags. (@pascaldekloe) + +### [1.6.0](https://github.com/magiconair/properties/tree/v1.6.0) - 11 Dec 2015 + + * Add [Decode](http://godoc.org/github.com/magiconair/properties#Properties.Decode) method to populate struct from properties via tags. + +### [1.5.6](https://github.com/magiconair/properties/tree/v1.5.6) - 18 Oct 2015 + + * Vendored in gopkg.in/check.v1 + +### [1.5.5](https://github.com/magiconair/properties/tree/v1.5.5) - 31 Jul 2015 + + * [PR #6](https://github.com/magiconair/properties/pull/6): Add [Delete](http://godoc.org/github.com/magiconair/properties#Properties.Delete) method to remove keys including comments. (@gerbenjacobs) + +### [1.5.4](https://github.com/magiconair/properties/tree/v1.5.4) - 23 Jun 2015 + + * [Issue #5](https://github.com/magiconair/properties/issues/5): Allow disabling of property expansion [DisableExpansion](http://godoc.org/github.com/magiconair/properties#Properties.DisableExpansion). When property expansion is disabled Properties become a simple key/value store and don't check for circular references. + +### [1.5.3](https://github.com/magiconair/properties/tree/v1.5.3) - 02 Jun 2015 + + * [Issue #4](https://github.com/magiconair/properties/issues/4): Maintain key order in [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) and [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) + +### [1.5.2](https://github.com/magiconair/properties/tree/v1.5.2) - 10 Apr 2015 + + * [Issue #3](https://github.com/magiconair/properties/issues/3): Don't print comments in [WriteComment()](http://godoc.org/github.com/magiconair/properties#Properties.WriteComment) if they are all empty + * Add clickable links to README + +### [1.5.1](https://github.com/magiconair/properties/tree/v1.5.1) - 08 Dec 2014 + + * Added [GetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.GetParsedDuration) and [MustGetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.MustGetParsedDuration) for values specified compatible with + [time.ParseDuration()](http://golang.org/pkg/time/#ParseDuration). + +### [1.5.0](https://github.com/magiconair/properties/tree/v1.5.0) - 18 Nov 2014 + + * Added support for single and multi-line comments (reading, writing and updating) + * The order of keys is now preserved + * Calling [Set()](http://godoc.org/github.com/magiconair/properties#Properties.Set) with an empty key now silently ignores the call and does not create a new entry + * Added a [MustSet()](http://godoc.org/github.com/magiconair/properties#Properties.MustSet) method + * Migrated test library from launchpad.net/gocheck to [gopkg.in/check.v1](http://gopkg.in/check.v1) + +### [1.4.2](https://github.com/magiconair/properties/tree/v1.4.2) - 15 Nov 2014 + + * [Issue #2](https://github.com/magiconair/properties/issues/2): Fixed goroutine leak in parser which created two lexers but cleaned up only one + +### [1.4.1](https://github.com/magiconair/properties/tree/v1.4.1) - 13 Nov 2014 + + * [Issue #1](https://github.com/magiconair/properties/issues/1): Fixed bug in Keys() method which returned an empty string + +### [1.4.0](https://github.com/magiconair/properties/tree/v1.4.0) - 23 Sep 2014 + + * Added [Keys()](http://godoc.org/github.com/magiconair/properties#Properties.Keys) to get the keys + * Added [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) and [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) to get a subset of the properties + +### [1.3.0](https://github.com/magiconair/properties/tree/v1.3.0) - 18 Mar 2014 + +* Added support for time.Duration +* Made MustXXX() failure beha[ior configurable (log.Fatal, panic](https://github.com/magiconair/properties/tree/vior configurable (log.Fatal, panic) - custom) +* Changed default of MustXXX() failure from panic to log.Fatal + +### [1.2.0](https://github.com/magiconair/properties/tree/v1.2.0) - 05 Mar 2014 + +* Added MustGet... functions +* Added support for int and uint with range checks on 32 bit platforms + +### [1.1.0](https://github.com/magiconair/properties/tree/v1.1.0) - 20 Jan 2014 + +* Renamed from goproperties to properties +* Added support for expansion of environment vars in + filenames and value expressions +* Fixed bug where value expressions were not at the + start of the string + +### [1.0.0](https://github.com/magiconair/properties/tree/v1.0.0) - 7 Jan 2014 + +* Initial release diff --git a/vendor/github.com/magiconair/properties/README.md b/vendor/github.com/magiconair/properties/README.md new file mode 100644 index 00000000..42ed5c37 --- /dev/null +++ b/vendor/github.com/magiconair/properties/README.md @@ -0,0 +1,129 @@ +[![](https://img.shields.io/github/tag/magiconair/properties.svg?style=flat-square&label=release)](https://github.com/magiconair/properties/releases) +[![Travis CI Status](https://img.shields.io/travis/magiconair/properties.svg?branch=master&style=flat-square&label=travis)](https://travis-ci.org/magiconair/properties) +[![CircleCI Status](https://img.shields.io/circleci/project/github/magiconair/properties.svg?label=circle+ci&style=flat-square)](https://circleci.com/gh/magiconair/properties) +[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg?style=flat-square)](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE) +[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties) + +# Overview + +#### Please run `git pull --tags` to update the tags. See [below](#updated-git-tags) why. + +properties is a Go library for reading and writing properties files. + +It supports reading from multiple files or URLs and Spring style recursive +property expansion of expressions like `${key}` to their corresponding value. +Value expressions can refer to other keys like in `${key}` or to environment +variables like in `${USER}`. Filenames can also contain environment variables +like in `/home/${USER}/myapp.properties`. + +Properties can be decoded into structs, maps, arrays and values through +struct tags. + +Comments and the order of keys are preserved. Comments can be modified +and can be written to the output. + +The properties library supports both ISO-8859-1 and UTF-8 encoded data. + +Starting from version 1.3.0 the behavior of the MustXXX() functions is +configurable by providing a custom `ErrorHandler` function. The default has +changed from `panic` to `log.Fatal` but this is configurable and custom +error handling functions can be provided. See the package documentation for +details. + +Read the full documentation on [![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties) + +## Getting Started + +```go +import ( + "flag" + "github.com/magiconair/properties" +) + +func main() { + // init from a file + p := properties.MustLoadFile("${HOME}/config.properties", properties.UTF8) + + // or multiple files + p = properties.MustLoadFiles([]string{ + "${HOME}/config.properties", + "${HOME}/config-${USER}.properties", + }, properties.UTF8, true) + + // or from a map + p = properties.LoadMap(map[string]string{"key": "value", "abc": "def"}) + + // or from a string + p = properties.MustLoadString("key=value\nabc=def") + + // or from a URL + p = properties.MustLoadURL("http://host/path") + + // or from multiple URLs + p = properties.MustLoadURL([]string{ + "http://host/config", + "http://host/config-${USER}", + }, true) + + // or from flags + p.MustFlag(flag.CommandLine) + + // get values through getters + host := p.MustGetString("host") + port := p.GetInt("port", 8080) + + // or through Decode + type Config struct { + Host string `properties:"host"` + Port int `properties:"port,default=9000"` + Accept []string `properties:"accept,default=image/png;image;gif"` + Timeout time.Duration `properties:"timeout,default=5s"` + } + var cfg Config + if err := p.Decode(&cfg); err != nil { + log.Fatal(err) + } +} + +``` + +## Installation and Upgrade + +``` +$ go get -u github.com/magiconair/properties +``` + +## License + +2 clause BSD license. See [LICENSE](https://github.com/magiconair/properties/blob/master/LICENSE) file for details. + +## ToDo + +* Dump contents with passwords and secrets obscured + +## Updated Git tags + +#### 13 Feb 2018 + +I realized that all of the git tags I had pushed before v1.7.5 were lightweight tags +and I've only recently learned that this doesn't play well with `git describe` 😞 + +I have replaced all lightweight tags with signed tags using this script which should +retain the commit date, name and email address. Please run `git pull --tags` to update them. + +Worst case you have to reclone the repo. + +```shell +#!/bin/bash +tag=$1 +echo "Updating $tag" +date=$(git show ${tag}^0 --format=%aD | head -1) +email=$(git show ${tag}^0 --format=%aE | head -1) +name=$(git show ${tag}^0 --format=%aN | head -1) +GIT_COMMITTER_DATE="$date" GIT_COMMITTER_NAME="$name" GIT_COMMITTER_EMAIL="$email" git tag -s -f ${tag} ${tag}^0 -m ${tag} +``` + +I apologize for the inconvenience. + +Frank + diff --git a/vendor/github.com/magiconair/properties/go.mod b/vendor/github.com/magiconair/properties/go.mod new file mode 100644 index 00000000..02a6f865 --- /dev/null +++ b/vendor/github.com/magiconair/properties/go.mod @@ -0,0 +1 @@ +module github.com/magiconair/properties diff --git a/vendor/github.com/magiconair/properties/load.go b/vendor/github.com/magiconair/properties/load.go new file mode 100644 index 00000000..ab953253 --- /dev/null +++ b/vendor/github.com/magiconair/properties/load.go @@ -0,0 +1,292 @@ +// Copyright 2018 Frank Schroeder. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package properties + +import ( + "fmt" + "io/ioutil" + "net/http" + "os" + "strings" +) + +// Encoding specifies encoding of the input data. +type Encoding uint + +const ( + // utf8Default is a private placeholder for the zero value of Encoding to + // ensure that it has the correct meaning. UTF8 is the default encoding but + // was assigned a non-zero value which cannot be changed without breaking + // existing code. Clients should continue to use the public constants. + utf8Default Encoding = iota + + // UTF8 interprets the input data as UTF-8. + UTF8 + + // ISO_8859_1 interprets the input data as ISO-8859-1. + ISO_8859_1 +) + +type Loader struct { + // Encoding determines how the data from files and byte buffers + // is interpreted. For URLs the Content-Type header is used + // to determine the encoding of the data. + Encoding Encoding + + // DisableExpansion configures the property expansion of the + // returned property object. When set to true, the property values + // will not be expanded and the Property object will not be checked + // for invalid expansion expressions. + DisableExpansion bool + + // IgnoreMissing configures whether missing files or URLs which return + // 404 are reported as errors. When set to true, missing files and 404 + // status codes are not reported as errors. + IgnoreMissing bool +} + +// Load reads a buffer into a Properties struct. +func (l *Loader) LoadBytes(buf []byte) (*Properties, error) { + return l.loadBytes(buf, l.Encoding) +} + +// LoadAll reads the content of multiple URLs or files in the given order into +// a Properties struct. If IgnoreMissing is true then a 404 status code or +// missing file will not be reported as error. Encoding sets the encoding for +// files. For the URLs see LoadURL for the Content-Type header and the +// encoding. +func (l *Loader) LoadAll(names []string) (*Properties, error) { + all := NewProperties() + for _, name := range names { + n, err := expandName(name) + if err != nil { + return nil, err + } + + var p *Properties + switch { + case strings.HasPrefix(n, "http://"): + p, err = l.LoadURL(n) + case strings.HasPrefix(n, "https://"): + p, err = l.LoadURL(n) + default: + p, err = l.LoadFile(n) + } + if err != nil { + return nil, err + } + all.Merge(p) + } + + all.DisableExpansion = l.DisableExpansion + if all.DisableExpansion { + return all, nil + } + return all, all.check() +} + +// LoadFile reads a file into a Properties struct. +// If IgnoreMissing is true then a missing file will not be +// reported as error. +func (l *Loader) LoadFile(filename string) (*Properties, error) { + data, err := ioutil.ReadFile(filename) + if err != nil { + if l.IgnoreMissing && os.IsNotExist(err) { + LogPrintf("properties: %s not found. skipping", filename) + return NewProperties(), nil + } + return nil, err + } + return l.loadBytes(data, l.Encoding) +} + +// LoadURL reads the content of the URL into a Properties struct. +// +// The encoding is determined via the Content-Type header which +// should be set to 'text/plain'. If the 'charset' parameter is +// missing, 'iso-8859-1' or 'latin1' the encoding is set to +// ISO-8859-1. If the 'charset' parameter is set to 'utf-8' the +// encoding is set to UTF-8. A missing content type header is +// interpreted as 'text/plain; charset=utf-8'. +func (l *Loader) LoadURL(url string) (*Properties, error) { + resp, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("properties: error fetching %q. %s", url, err) + } + defer resp.Body.Close() + + if resp.StatusCode == 404 && l.IgnoreMissing { + LogPrintf("properties: %s returned %d. skipping", url, resp.StatusCode) + return NewProperties(), nil + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("properties: %s returned %d", url, resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("properties: %s error reading response. %s", url, err) + } + + ct := resp.Header.Get("Content-Type") + var enc Encoding + switch strings.ToLower(ct) { + case "text/plain", "text/plain; charset=iso-8859-1", "text/plain; charset=latin1": + enc = ISO_8859_1 + case "", "text/plain; charset=utf-8": + enc = UTF8 + default: + return nil, fmt.Errorf("properties: invalid content type %s", ct) + } + + return l.loadBytes(body, enc) +} + +func (l *Loader) loadBytes(buf []byte, enc Encoding) (*Properties, error) { + p, err := parse(convert(buf, enc)) + if err != nil { + return nil, err + } + p.DisableExpansion = l.DisableExpansion + if p.DisableExpansion { + return p, nil + } + return p, p.check() +} + +// Load reads a buffer into a Properties struct. +func Load(buf []byte, enc Encoding) (*Properties, error) { + l := &Loader{Encoding: enc} + return l.LoadBytes(buf) +} + +// LoadString reads an UTF8 string into a properties struct. +func LoadString(s string) (*Properties, error) { + l := &Loader{Encoding: UTF8} + return l.LoadBytes([]byte(s)) +} + +// LoadMap creates a new Properties struct from a string map. +func LoadMap(m map[string]string) *Properties { + p := NewProperties() + for k, v := range m { + p.Set(k, v) + } + return p +} + +// LoadFile reads a file into a Properties struct. +func LoadFile(filename string, enc Encoding) (*Properties, error) { + l := &Loader{Encoding: enc} + return l.LoadAll([]string{filename}) +} + +// LoadFiles reads multiple files in the given order into +// a Properties struct. If 'ignoreMissing' is true then +// non-existent files will not be reported as error. +func LoadFiles(filenames []string, enc Encoding, ignoreMissing bool) (*Properties, error) { + l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} + return l.LoadAll(filenames) +} + +// LoadURL reads the content of the URL into a Properties struct. +// See Loader#LoadURL for details. +func LoadURL(url string) (*Properties, error) { + l := &Loader{Encoding: UTF8} + return l.LoadAll([]string{url}) +} + +// LoadURLs reads the content of multiple URLs in the given order into a +// Properties struct. If IgnoreMissing is true then a 404 status code will +// not be reported as error. See Loader#LoadURL for the Content-Type header +// and the encoding. +func LoadURLs(urls []string, ignoreMissing bool) (*Properties, error) { + l := &Loader{Encoding: UTF8, IgnoreMissing: ignoreMissing} + return l.LoadAll(urls) +} + +// LoadAll reads the content of multiple URLs or files in the given order into a +// Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will +// not be reported as error. Encoding sets the encoding for files. For the URLs please see +// LoadURL for the Content-Type header and the encoding. +func LoadAll(names []string, enc Encoding, ignoreMissing bool) (*Properties, error) { + l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} + return l.LoadAll(names) +} + +// MustLoadString reads an UTF8 string into a Properties struct and +// panics on error. +func MustLoadString(s string) *Properties { + return must(LoadString(s)) +} + +// MustLoadFile reads a file into a Properties struct and +// panics on error. +func MustLoadFile(filename string, enc Encoding) *Properties { + return must(LoadFile(filename, enc)) +} + +// MustLoadFiles reads multiple files in the given order into +// a Properties struct and panics on error. If 'ignoreMissing' +// is true then non-existent files will not be reported as error. +func MustLoadFiles(filenames []string, enc Encoding, ignoreMissing bool) *Properties { + return must(LoadFiles(filenames, enc, ignoreMissing)) +} + +// MustLoadURL reads the content of a URL into a Properties struct and +// panics on error. +func MustLoadURL(url string) *Properties { + return must(LoadURL(url)) +} + +// MustLoadURLs reads the content of multiple URLs in the given order into a +// Properties struct and panics on error. If 'ignoreMissing' is true then a 404 +// status code will not be reported as error. +func MustLoadURLs(urls []string, ignoreMissing bool) *Properties { + return must(LoadURLs(urls, ignoreMissing)) +} + +// MustLoadAll reads the content of multiple URLs or files in the given order into a +// Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will +// not be reported as error. Encoding sets the encoding for files. For the URLs please see +// LoadURL for the Content-Type header and the encoding. It panics on error. +func MustLoadAll(names []string, enc Encoding, ignoreMissing bool) *Properties { + return must(LoadAll(names, enc, ignoreMissing)) +} + +func must(p *Properties, err error) *Properties { + if err != nil { + ErrorHandler(err) + } + return p +} + +// expandName expands ${ENV_VAR} expressions in a name. +// If the environment variable does not exist then it will be replaced +// with an empty string. Malformed expressions like "${ENV_VAR" will +// be reported as error. +func expandName(name string) (string, error) { + return expand(name, []string{}, "${", "}", make(map[string]string)) +} + +// Interprets a byte buffer either as an ISO-8859-1 or UTF-8 encoded string. +// For ISO-8859-1 we can convert each byte straight into a rune since the +// first 256 unicode code points cover ISO-8859-1. +func convert(buf []byte, enc Encoding) string { + switch enc { + case utf8Default, UTF8: + return string(buf) + case ISO_8859_1: + runes := make([]rune, len(buf)) + for i, b := range buf { + runes[i] = rune(b) + } + return string(runes) + default: + ErrorHandler(fmt.Errorf("unsupported encoding %v", enc)) + } + panic("ErrorHandler should exit") +} diff --git a/vendor/github.com/marten-seemann/qtls/.travis.yml b/vendor/github.com/marten-seemann/qtls/.travis.yml new file mode 100644 index 00000000..2179c96e --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/.travis.yml @@ -0,0 +1,28 @@ +dist: trusty +group: travis_latest + +language: go + +go: + - "1.12.x" + +# first part of the GOARCH workaround +# setting the GOARCH directly doesn't work, since the value will be overwritten later +# so set it to a temporary environment variable first +env: + global: + - GO111MODULE=on + matrix: + - TRAVIS_GOARCH=amd64 + - TRAVIS_GOARCH=386 + + +# second part of the GOARCH workaround +# now actually set the GOARCH env variable to the value of the temporary variable set earlier +before_install: + - export GOARCH=$TRAVIS_GOARCH + - go env # for debugging + +script: + - go test + - if [ ${TRAVIS_GOARCH} == 'amd64' ]; then go test -race; fi diff --git a/vendor/github.com/marten-seemann/qtls/LICENSE b/vendor/github.com/marten-seemann/qtls/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +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. diff --git a/vendor/github.com/marten-seemann/qtls/README.md b/vendor/github.com/marten-seemann/qtls/README.md new file mode 100644 index 00000000..f765e86f --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/README.md @@ -0,0 +1,6 @@ +# qtls + +[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/marten-seemann/qtls) +[![Travis Build Status](https://img.shields.io/travis/marten-seemann/qtls/master.svg?style=flat-square&label=Travis+build)](https://travis-ci.org/marten-seemann/qtls) + +This repository contains a modified version of the standard library's TLS implementation, modified for the QUIC protocol. It is used by [quic-go](https://github.com/lucas-clemente/quic-go). diff --git a/vendor/github.com/marten-seemann/qtls/alert.go b/vendor/github.com/marten-seemann/qtls/alert.go new file mode 100644 index 00000000..ba1c9ce3 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/alert.go @@ -0,0 +1,88 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import "strconv" + +type alert uint8 + +// Alert is a TLS alert +type Alert = alert + +const ( + // alert level + alertLevelWarning = 1 + alertLevelError = 2 +) + +const ( + alertCloseNotify alert = 0 + alertUnexpectedMessage alert = 10 + alertBadRecordMAC alert = 20 + alertDecryptionFailed alert = 21 + alertRecordOverflow alert = 22 + alertDecompressionFailure alert = 30 + alertHandshakeFailure alert = 40 + alertBadCertificate alert = 42 + alertUnsupportedCertificate alert = 43 + alertCertificateRevoked alert = 44 + alertCertificateExpired alert = 45 + alertCertificateUnknown alert = 46 + alertIllegalParameter alert = 47 + alertUnknownCA alert = 48 + alertAccessDenied alert = 49 + alertDecodeError alert = 50 + alertDecryptError alert = 51 + alertProtocolVersion alert = 70 + alertInsufficientSecurity alert = 71 + alertInternalError alert = 80 + alertInappropriateFallback alert = 86 + alertUserCanceled alert = 90 + alertNoRenegotiation alert = 100 + alertMissingExtension alert = 109 + alertUnsupportedExtension alert = 110 + alertNoApplicationProtocol alert = 120 +) + +var alertText = map[alert]string{ + alertCloseNotify: "close notify", + alertUnexpectedMessage: "unexpected message", + alertBadRecordMAC: "bad record MAC", + alertDecryptionFailed: "decryption failed", + alertRecordOverflow: "record overflow", + alertDecompressionFailure: "decompression failure", + alertHandshakeFailure: "handshake failure", + alertBadCertificate: "bad certificate", + alertUnsupportedCertificate: "unsupported certificate", + alertCertificateRevoked: "revoked certificate", + alertCertificateExpired: "expired certificate", + alertCertificateUnknown: "unknown certificate", + alertIllegalParameter: "illegal parameter", + alertUnknownCA: "unknown certificate authority", + alertAccessDenied: "access denied", + alertDecodeError: "error decoding message", + alertDecryptError: "error decrypting message", + alertProtocolVersion: "protocol version not supported", + alertInsufficientSecurity: "insufficient security level", + alertInternalError: "internal error", + alertInappropriateFallback: "inappropriate fallback", + alertUserCanceled: "user canceled", + alertNoRenegotiation: "no renegotiation", + alertMissingExtension: "missing extension", + alertUnsupportedExtension: "unsupported extension", + alertNoApplicationProtocol: "no application protocol", +} + +func (e alert) String() string { + s, ok := alertText[e] + if ok { + return "tls: " + s + } + return "tls: alert(" + strconv.Itoa(int(e)) + ")" +} + +func (e alert) Error() string { + return e.String() +} diff --git a/vendor/github.com/marten-seemann/qtls/auth.go b/vendor/github.com/marten-seemann/qtls/auth.go new file mode 100644 index 00000000..b8fd7f9b --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/auth.go @@ -0,0 +1,221 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rsa" + "encoding/asn1" + "errors" + "fmt" + "hash" + "io" +) + +// pickSignatureAlgorithm selects a signature algorithm that is compatible with +// the given public key and the list of algorithms from the peer and this side. +// The lists of signature algorithms (peerSigAlgs and ourSigAlgs) are ignored +// for tlsVersion < VersionTLS12. +// +// The returned SignatureScheme codepoint is only meaningful for TLS 1.2, +// previous TLS versions have a fixed hash function. +func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []SignatureScheme, tlsVersion uint16) (sigAlg SignatureScheme, sigType uint8, hashFunc crypto.Hash, err error) { + if tlsVersion < VersionTLS12 || len(peerSigAlgs) == 0 { + // For TLS 1.1 and before, the signature algorithm could not be + // negotiated and the hash is fixed based on the signature type. For TLS + // 1.2, if the client didn't send signature_algorithms extension then we + // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. + switch pubkey.(type) { + case *rsa.PublicKey: + if tlsVersion < VersionTLS12 { + return 0, signaturePKCS1v15, crypto.MD5SHA1, nil + } else { + return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil + } + case *ecdsa.PublicKey: + return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil + default: + return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) + } + } + for _, sigAlg := range peerSigAlgs { + if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) { + continue + } + hashAlg, err := hashFromSignatureScheme(sigAlg) + if err != nil { + panic("tls: supported signature algorithm has an unknown hash function") + } + sigType := signatureFromSignatureScheme(sigAlg) + switch pubkey.(type) { + case *rsa.PublicKey: + if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS { + return sigAlg, sigType, hashAlg, nil + } + case *ecdsa.PublicKey: + if sigType == signatureECDSA { + return sigAlg, sigType, hashAlg, nil + } + default: + return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) + } + } + return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms") +} + +// verifyHandshakeSignature verifies a signature against pre-hashed handshake +// contents. +func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error { + switch sigType { + case signatureECDSA: + pubKey, ok := pubkey.(*ecdsa.PublicKey) + if !ok { + return errors.New("tls: ECDSA signing requires a ECDSA public key") + } + ecdsaSig := new(ecdsaSignature) + if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { + return err + } + if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { + return errors.New("tls: ECDSA signature contained zero or negative values") + } + if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { + return errors.New("tls: ECDSA verification failure") + } + case signaturePKCS1v15: + pubKey, ok := pubkey.(*rsa.PublicKey) + if !ok { + return errors.New("tls: RSA signing requires a RSA public key") + } + if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { + return err + } + case signatureRSAPSS: + pubKey, ok := pubkey.(*rsa.PublicKey) + if !ok { + return errors.New("tls: RSA signing requires a RSA public key") + } + signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} + if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil { + return err + } + default: + return errors.New("tls: unknown signature algorithm") + } + return nil +} + +const ( + serverSignatureContext = "TLS 1.3, server CertificateVerify\x00" + clientSignatureContext = "TLS 1.3, client CertificateVerify\x00" +) + +var signaturePadding = []byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +} + +// writeSignedMessage writes the content to be signed by certificate keys in TLS +// 1.3 to sigHash. See RFC 8446, Section 4.4.3. +func writeSignedMessage(sigHash io.Writer, context string, transcript hash.Hash) { + sigHash.Write(signaturePadding) + io.WriteString(sigHash, context) + sigHash.Write(transcript.Sum(nil)) +} + +// signatureSchemesForCertificate returns the list of supported SignatureSchemes +// for a given certificate, based on the public key and the protocol version. It +// does not support the crypto.Decrypter interface, so shouldn't be used on the +// server side in TLS 1.2 and earlier. +func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { + priv, ok := cert.PrivateKey.(crypto.Signer) + if !ok { + return nil + } + + switch pub := priv.Public().(type) { + case *ecdsa.PublicKey: + if version != VersionTLS13 { + // In TLS 1.2 and earlier, ECDSA algorithms are not + // constrained to a single curve. + return []SignatureScheme{ + ECDSAWithP256AndSHA256, + ECDSAWithP384AndSHA384, + ECDSAWithP521AndSHA512, + ECDSAWithSHA1, + } + } + switch pub.Curve { + case elliptic.P256(): + return []SignatureScheme{ECDSAWithP256AndSHA256} + case elliptic.P384(): + return []SignatureScheme{ECDSAWithP384AndSHA384} + case elliptic.P521(): + return []SignatureScheme{ECDSAWithP521AndSHA512} + default: + return nil + } + case *rsa.PublicKey: + if version != VersionTLS13 { + return []SignatureScheme{ + PSSWithSHA256, + PSSWithSHA384, + PSSWithSHA512, + PKCS1WithSHA256, + PKCS1WithSHA384, + PKCS1WithSHA512, + PKCS1WithSHA1, + } + } + // RSA keys with RSA-PSS OID are not supported by crypto/x509. + return []SignatureScheme{ + PSSWithSHA256, + PSSWithSHA384, + PSSWithSHA512, + } + default: + return nil + } +} + +// unsupportedCertificateError returns a helpful error for certificates with +// an unsupported private key. +func unsupportedCertificateError(cert *Certificate) error { + switch cert.PrivateKey.(type) { + case rsa.PrivateKey, ecdsa.PrivateKey: + return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T", + cert.PrivateKey, cert.PrivateKey) + } + + signer, ok := cert.PrivateKey.(crypto.Signer) + if !ok { + return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer", + cert.PrivateKey) + } + + switch pub := signer.Public().(type) { + case *ecdsa.PublicKey: + switch pub.Curve { + case elliptic.P256(): + case elliptic.P384(): + case elliptic.P521(): + default: + return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) + } + case *rsa.PublicKey: + default: + return fmt.Errorf("tls: unsupported certificate key (%T)", pub) + } + + return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) +} diff --git a/vendor/github.com/marten-seemann/qtls/cipher_suites.go b/vendor/github.com/marten-seemann/qtls/cipher_suites.go new file mode 100644 index 00000000..e0b7e2f1 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/cipher_suites.go @@ -0,0 +1,487 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/aes" + "crypto/cipher" + "crypto/des" + "crypto/hmac" + "crypto/rc4" + "crypto/sha1" + "crypto/sha256" + "crypto/x509" + "hash" + + "golang.org/x/crypto/chacha20poly1305" +) + +// a keyAgreement implements the client and server side of a TLS key agreement +// protocol by generating and processing key exchange messages. +type keyAgreement interface { + // On the server side, the first two methods are called in order. + + // In the case that the key agreement protocol doesn't use a + // ServerKeyExchange message, generateServerKeyExchange can return nil, + // nil. + generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) + processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) + + // On the client side, the next two methods are called in order. + + // This method may not be called if the server doesn't send a + // ServerKeyExchange message. + processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error + generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) +} + +const ( + // suiteECDH indicates that the cipher suite involves elliptic curve + // Diffie-Hellman. This means that it should only be selected when the + // client indicates that it supports ECC with a curve and point format + // that we're happy with. + suiteECDHE = 1 << iota + // suiteECDSA indicates that the cipher suite involves an ECDSA + // signature and therefore may only be selected when the server's + // certificate is ECDSA. If this is not set then the cipher suite is + // RSA based. + suiteECDSA + // suiteTLS12 indicates that the cipher suite should only be advertised + // and accepted when using TLS 1.2. + suiteTLS12 + // suiteSHA384 indicates that the cipher suite uses SHA384 as the + // handshake hash. + suiteSHA384 + // suiteDefaultOff indicates that this cipher suite is not included by + // default. + suiteDefaultOff +) + +type CipherSuite struct { + *cipherSuiteTLS13 +} + +func (c *CipherSuite) Hash() crypto.Hash { return c.hash } +func (c *CipherSuite) KeyLen() int { return c.keyLen } +func (c *CipherSuite) IVLen() int { return aeadNonceLength } +func (c *CipherSuite) AEAD(key, fixedNonce []byte) cipher.AEAD { return c.aead(key, fixedNonce) } + +// A cipherSuite is a specific combination of key agreement, cipher and MAC function. +type cipherSuite struct { + id uint16 + // the lengths, in bytes, of the key material needed for each component. + keyLen int + macLen int + ivLen int + ka func(version uint16) keyAgreement + // flags is a bitmask of the suite* values, above. + flags int + cipher func(key, iv []byte, isRead bool) interface{} + mac func(version uint16, macKey []byte) macFunction + aead func(key, fixedNonce []byte) aead +} + +var cipherSuites = []*cipherSuite{ + // Ciphersuite order is chosen so that ECDHE comes before plain RSA and + // AEADs are the top preference. + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, + {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, + + // RC4-based cipher suites are disabled by default. + {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteDefaultOff, cipherRC4, macSHA1, nil}, +} + +// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash +// algorithm to be used with HKDF. See RFC 8446, Appendix B.4. +type cipherSuiteTLS13 struct { + id uint16 + keyLen int + aead func(key, fixedNonce []byte) aead + hash crypto.Hash +} + +var cipherSuitesTLS13 = []*cipherSuiteTLS13{ + {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256}, + {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256}, + {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384}, +} + +func cipherRC4(key, iv []byte, isRead bool) interface{} { + cipher, _ := rc4.NewCipher(key) + return cipher +} + +func cipher3DES(key, iv []byte, isRead bool) interface{} { + block, _ := des.NewTripleDESCipher(key) + if isRead { + return cipher.NewCBCDecrypter(block, iv) + } + return cipher.NewCBCEncrypter(block, iv) +} + +func cipherAES(key, iv []byte, isRead bool) interface{} { + block, _ := aes.NewCipher(key) + if isRead { + return cipher.NewCBCDecrypter(block, iv) + } + return cipher.NewCBCEncrypter(block, iv) +} + +// macSHA1 returns a macFunction for the given protocol version. +func macSHA1(version uint16, key []byte) macFunction { + if version == VersionSSL30 { + mac := ssl30MAC{ + h: sha1.New(), + key: make([]byte, len(key)), + } + copy(mac.key, key) + return mac + } + return tls10MAC{h: hmac.New(newConstantTimeHash(sha1.New), key)} +} + +// macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2 +// so the given version is ignored. +func macSHA256(version uint16, key []byte) macFunction { + return tls10MAC{h: hmac.New(sha256.New, key)} +} + +type macFunction interface { + // Size returns the length of the MAC. + Size() int + // MAC appends the MAC of (seq, header, data) to out. The extra data is fed + // into the MAC after obtaining the result to normalize timing. The result + // is only valid until the next invocation of MAC as the buffer is reused. + MAC(seq, header, data, extra []byte) []byte +} + +type aead interface { + cipher.AEAD + + // explicitNonceLen returns the number of bytes of explicit nonce + // included in each record. This is eight for older AEADs and + // zero for modern ones. + explicitNonceLen() int +} + +const ( + aeadNonceLength = 12 + noncePrefixLength = 4 +) + +// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to +// each call. +type prefixNonceAEAD struct { + // nonce contains the fixed part of the nonce in the first four bytes. + nonce [aeadNonceLength]byte + aead cipher.AEAD +} + +func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength } +func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() } +func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() } + +func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { + copy(f.nonce[4:], nonce) + return f.aead.Seal(out, f.nonce[:], plaintext, additionalData) +} + +func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { + copy(f.nonce[4:], nonce) + return f.aead.Open(out, f.nonce[:], ciphertext, additionalData) +} + +// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce +// before each call. +type xorNonceAEAD struct { + nonceMask [aeadNonceLength]byte + aead cipher.AEAD +} + +func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number +func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() } +func (f *xorNonceAEAD) explicitNonceLen() int { return 0 } + +func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { + for i, b := range nonce { + f.nonceMask[4+i] ^= b + } + result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData) + for i, b := range nonce { + f.nonceMask[4+i] ^= b + } + + return result +} + +func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { + for i, b := range nonce { + f.nonceMask[4+i] ^= b + } + result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData) + for i, b := range nonce { + f.nonceMask[4+i] ^= b + } + + return result, err +} + +func aeadAESGCM(key, noncePrefix []byte) aead { + if len(noncePrefix) != noncePrefixLength { + panic("tls: internal error: wrong nonce length") + } + aes, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + aead, err := cipher.NewGCM(aes) + if err != nil { + panic(err) + } + + ret := &prefixNonceAEAD{aead: aead} + copy(ret.nonce[:], noncePrefix) + return ret +} + +// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3 +func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD { + return aeadAESGCMTLS13(key, fixedNonce) +} + +func aeadAESGCMTLS13(key, nonceMask []byte) aead { + if len(nonceMask) != aeadNonceLength { + panic("tls: internal error: wrong nonce length") + } + aes, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + aead, err := cipher.NewGCM(aes) + if err != nil { + panic(err) + } + + ret := &xorNonceAEAD{aead: aead} + copy(ret.nonceMask[:], nonceMask) + return ret +} + +func aeadChaCha20Poly1305(key, nonceMask []byte) aead { + if len(nonceMask) != aeadNonceLength { + panic("tls: internal error: wrong nonce length") + } + aead, err := chacha20poly1305.New(key) + if err != nil { + panic(err) + } + + ret := &xorNonceAEAD{aead: aead} + copy(ret.nonceMask[:], nonceMask) + return ret +} + +// ssl30MAC implements the SSLv3 MAC function, as defined in +// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 +type ssl30MAC struct { + h hash.Hash + key []byte + buf []byte +} + +func (s ssl30MAC) Size() int { + return s.h.Size() +} + +var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36} + +var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} + +// MAC does not offer constant timing guarantees for SSL v3.0, since it's deemed +// useless considering the similar, protocol-level POODLE vulnerability. +func (s ssl30MAC) MAC(seq, header, data, extra []byte) []byte { + padLength := 48 + if s.h.Size() == 20 { + padLength = 40 + } + + s.h.Reset() + s.h.Write(s.key) + s.h.Write(ssl30Pad1[:padLength]) + s.h.Write(seq) + s.h.Write(header[:1]) + s.h.Write(header[3:5]) + s.h.Write(data) + s.buf = s.h.Sum(s.buf[:0]) + + s.h.Reset() + s.h.Write(s.key) + s.h.Write(ssl30Pad2[:padLength]) + s.h.Write(s.buf) + return s.h.Sum(s.buf[:0]) +} + +type constantTimeHash interface { + hash.Hash + ConstantTimeSum(b []byte) []byte +} + +// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces +// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC. +type cthWrapper struct { + h constantTimeHash +} + +func (c *cthWrapper) Size() int { return c.h.Size() } +func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() } +func (c *cthWrapper) Reset() { c.h.Reset() } +func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) } +func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) } + +func newConstantTimeHash(h func() hash.Hash) func() hash.Hash { + return func() hash.Hash { + return &cthWrapper{h().(constantTimeHash)} + } +} + +// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3. +type tls10MAC struct { + h hash.Hash + buf []byte +} + +func (s tls10MAC) Size() int { + return s.h.Size() +} + +// MAC is guaranteed to take constant time, as long as +// len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into +// the MAC, but is only provided to make the timing profile constant. +func (s tls10MAC) MAC(seq, header, data, extra []byte) []byte { + s.h.Reset() + s.h.Write(seq) + s.h.Write(header) + s.h.Write(data) + res := s.h.Sum(s.buf[:0]) + if extra != nil { + s.h.Write(extra) + } + return res +} + +func rsaKA(version uint16) keyAgreement { + return rsaKeyAgreement{} +} + +func ecdheECDSAKA(version uint16) keyAgreement { + return &ecdheKeyAgreement{ + isRSA: false, + version: version, + } +} + +func ecdheRSAKA(version uint16) keyAgreement { + return &ecdheKeyAgreement{ + isRSA: true, + version: version, + } +} + +// mutualCipherSuite returns a cipherSuite given a list of supported +// ciphersuites and the id requested by the peer. +func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { + for _, id := range have { + if id == want { + return cipherSuiteByID(id) + } + } + return nil +} + +func cipherSuiteByID(id uint16) *cipherSuite { + for _, cipherSuite := range cipherSuites { + if cipherSuite.id == id { + return cipherSuite + } + } + return nil +} + +func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 { + for _, id := range have { + if id == want { + return cipherSuiteTLS13ByID(id) + } + } + return nil +} + +func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 { + for _, cipherSuite := range cipherSuitesTLS13 { + if cipherSuite.id == id { + return cipherSuite + } + } + return nil +} + +// A list of cipher suite IDs that are, or have been, implemented by this +// package. +// +// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml +const ( + // TLS 1.0 - 1.2 cipher suites. + TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a + TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f + TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c + TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c + TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a + TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca8 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca9 + + // TLS 1.3 cipher suites. + TLS_AES_128_GCM_SHA256 uint16 = 0x1301 + TLS_AES_256_GCM_SHA384 uint16 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303 + + // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator + // that the client is doing version fallback. See RFC 7507. + TLS_FALLBACK_SCSV uint16 = 0x5600 +) diff --git a/vendor/github.com/marten-seemann/qtls/common.go b/vendor/github.com/marten-seemann/qtls/common.go new file mode 100644 index 00000000..2a6c64d8 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/common.go @@ -0,0 +1,1155 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "container/list" + "crypto/rand" + "crypto/sha512" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "io" + "math/big" + "os" + "strings" + "sync" + "time" + + "golang.org/x/sys/cpu" +) + +const ( + VersionSSL30 = 0x0300 + VersionTLS10 = 0x0301 + VersionTLS11 = 0x0302 + VersionTLS12 = 0x0303 + VersionTLS13 = 0x0304 +) + +const ( + maxPlaintext = 16384 // maximum plaintext payload length + maxCiphertext = 16384 + 2048 // maximum ciphertext payload length + maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3 + recordHeaderLen = 5 // record header length + maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) + maxUselessRecords = 16 // maximum number of consecutive non-advancing records +) + +// TLS record types. +type recordType uint8 + +const ( + recordTypeChangeCipherSpec recordType = 20 + recordTypeAlert recordType = 21 + recordTypeHandshake recordType = 22 + recordTypeApplicationData recordType = 23 +) + +// TLS handshake message types. +const ( + typeHelloRequest uint8 = 0 + typeClientHello uint8 = 1 + typeServerHello uint8 = 2 + typeNewSessionTicket uint8 = 4 + typeEndOfEarlyData uint8 = 5 + typeEncryptedExtensions uint8 = 8 + typeCertificate uint8 = 11 + typeServerKeyExchange uint8 = 12 + typeCertificateRequest uint8 = 13 + typeServerHelloDone uint8 = 14 + typeCertificateVerify uint8 = 15 + typeClientKeyExchange uint8 = 16 + typeFinished uint8 = 20 + typeCertificateStatus uint8 = 22 + typeKeyUpdate uint8 = 24 + typeNextProtocol uint8 = 67 // Not IANA assigned + typeMessageHash uint8 = 254 // synthetic message +) + +// TLS compression types. +const ( + compressionNone uint8 = 0 +) + +type Extension struct { + Type uint16 + Data []byte +} + +// TLS extension numbers +const ( + extensionServerName uint16 = 0 + extensionStatusRequest uint16 = 5 + extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7 + extensionSupportedPoints uint16 = 11 + extensionSignatureAlgorithms uint16 = 13 + extensionALPN uint16 = 16 + extensionSCT uint16 = 18 + extensionSessionTicket uint16 = 35 + extensionPreSharedKey uint16 = 41 + extensionEarlyData uint16 = 42 + extensionSupportedVersions uint16 = 43 + extensionCookie uint16 = 44 + extensionPSKModes uint16 = 45 + extensionCertificateAuthorities uint16 = 47 + extensionSignatureAlgorithmsCert uint16 = 50 + extensionKeyShare uint16 = 51 + extensionNextProtoNeg uint16 = 13172 // not IANA assigned + extensionRenegotiationInfo uint16 = 0xff01 +) + +// TLS signaling cipher suite values +const ( + scsvRenegotiation uint16 = 0x00ff +) + +// CurveID is a tls.CurveID +type CurveID = tls.CurveID + +const ( + CurveP256 CurveID = 23 + CurveP384 CurveID = 24 + CurveP521 CurveID = 25 + X25519 CurveID = 29 +) + +// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8. +type keyShare struct { + group CurveID + data []byte +} + +// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9. +const ( + pskModePlain uint8 = 0 + pskModeDHE uint8 = 1 +) + +// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved +// session. See RFC 8446, Section 4.2.11. +type pskIdentity struct { + label []byte + obfuscatedTicketAge uint32 +} + +// TLS Elliptic Curve Point Formats +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 +const ( + pointFormatUncompressed uint8 = 0 +) + +// TLS CertificateStatusType (RFC 3546) +const ( + statusTypeOCSP uint8 = 1 +) + +// Certificate types (for certificateRequestMsg) +const ( + certTypeRSASign = 1 + certTypeECDSASign = 64 // RFC 4492, Section 5.5 +) + +// Signature algorithms (for internal signaling use). Starting at 16 to avoid overlap with +// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do. +const ( + signaturePKCS1v15 uint8 = iota + 16 + signatureECDSA + signatureRSAPSS +) + +// supportedSignatureAlgorithms contains the signature and hash algorithms that +// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+ +// CertificateRequest. The two fields are merged to match with TLS 1.3. +// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc. +var supportedSignatureAlgorithms = []SignatureScheme{ + PSSWithSHA256, + PSSWithSHA384, + PSSWithSHA512, + PKCS1WithSHA256, + ECDSAWithP256AndSHA256, + PKCS1WithSHA384, + ECDSAWithP384AndSHA384, + PKCS1WithSHA512, + ECDSAWithP521AndSHA512, + PKCS1WithSHA1, + ECDSAWithSHA1, +} + +// RSA-PSS is disabled in TLS 1.2 for Go 1.12. See Issue 30055. +var supportedSignatureAlgorithmsTLS12 = supportedSignatureAlgorithms[3:] + +// helloRetryRequestRandom is set as the Random value of a ServerHello +// to signal that the message is actually a HelloRetryRequest. +var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3. + 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, + 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, + 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, + 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C, +} + +const ( + // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server + // random as a downgrade protection if the server would be capable of + // negotiating a higher version. See RFC 8446, Section 4.1.3. + downgradeCanaryTLS12 = "DOWNGRD\x01" + downgradeCanaryTLS11 = "DOWNGRD\x00" +) + +// ConnectionState records basic TLS details about the connection. +type ConnectionState struct { + Version uint16 // TLS version used by the connection (e.g. VersionTLS12) + HandshakeComplete bool // TLS handshake is complete + DidResume bool // connection resumes a previous TLS connection + CipherSuite uint16 // cipher suite in use (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ...) + NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos) + NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only) + ServerName string // server name requested by client, if any (server side only) + PeerCertificates []*x509.Certificate // certificate chain presented by remote peer + VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates + SignedCertificateTimestamps [][]byte // SCTs from the peer, if any + OCSPResponse []byte // stapled OCSP response from peer, if any + + // ekm is a closure exposed via ExportKeyingMaterial. + ekm func(label string, context []byte, length int) ([]byte, error) + + // TLSUnique contains the "tls-unique" channel binding value (see RFC + // 5929, section 3). For resumed sessions this value will be nil + // because resumption does not include enough context (see + // https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will + // change in future versions of Go once the TLS master-secret fix has + // been standardized and implemented. It is not defined in TLS 1.3. + TLSUnique []byte +} + +// ExportKeyingMaterial returns length bytes of exported key material in a new +// slice as defined in RFC 5705. If context is nil, it is not used as part of +// the seed. If the connection was set to allow renegotiation via +// Config.Renegotiation, this function will return an error. +func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) { + return cs.ekm(label, context, length) +} + +// ClientAuthType is tls.ClientAuthType +type ClientAuthType = tls.ClientAuthType + +const ( + NoClientCert ClientAuthType = iota + RequestClientCert + RequireAnyClientCert + VerifyClientCertIfGiven + RequireAndVerifyClientCert +) + +// requiresClientCert reports whether the ClientAuthType requires a client +// certificate to be provided. +func requiresClientCert(c ClientAuthType) bool { + switch c { + case RequireAnyClientCert, RequireAndVerifyClientCert: + return true + default: + return false + } +} + +// ClientSessionState contains the state needed by clients to resume TLS +// sessions. +type ClientSessionState struct { + sessionTicket []uint8 // Encrypted ticket used for session resumption with server + vers uint16 // SSL/TLS version negotiated for the session + cipherSuite uint16 // Ciphersuite negotiated for the session + masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret + serverCertificates []*x509.Certificate // Certificate chain presented by the server + verifiedChains [][]*x509.Certificate // Certificate chains we built for verification + receivedAt time.Time // When the session ticket was received from the server + + // TLS 1.3 fields. + nonce []byte // Ticket nonce sent by the server, to derive PSK + useBy time.Time // Expiration of the ticket lifetime as set by the server + ageAdd uint32 // Random obfuscation factor for sending the ticket age +} + +// ClientSessionCache is a cache of ClientSessionState objects that can be used +// by a client to resume a TLS session with a given server. ClientSessionCache +// implementations should expect to be called concurrently from different +// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not +// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which +// are supported via this interface. +type ClientSessionCache interface { + // Get searches for a ClientSessionState associated with the given key. + // On return, ok is true if one was found. + Get(sessionKey string) (session *ClientSessionState, ok bool) + + // Put adds the ClientSessionState to the cache with the given key. It might + // get called multiple times in a connection if a TLS 1.3 server provides + // more than one session ticket. If called with a nil *ClientSessionState, + // it should remove the cache entry. + Put(sessionKey string, cs *ClientSessionState) +} + +// SignatureScheme is a tls.SignatureScheme +type SignatureScheme = tls.SignatureScheme + +const ( + // RSASSA-PKCS1-v1_5 algorithms. + PKCS1WithSHA256 SignatureScheme = 0x0401 + PKCS1WithSHA384 SignatureScheme = 0x0501 + PKCS1WithSHA512 SignatureScheme = 0x0601 + + // RSASSA-PSS algorithms with public key OID rsaEncryption. + PSSWithSHA256 SignatureScheme = 0x0804 + PSSWithSHA384 SignatureScheme = 0x0805 + PSSWithSHA512 SignatureScheme = 0x0806 + + // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3. + ECDSAWithP256AndSHA256 SignatureScheme = 0x0403 + ECDSAWithP384AndSHA384 SignatureScheme = 0x0503 + ECDSAWithP521AndSHA512 SignatureScheme = 0x0603 + + // Legacy signature and hash algorithms for TLS 1.2. + PKCS1WithSHA1 SignatureScheme = 0x0201 + ECDSAWithSHA1 SignatureScheme = 0x0203 +) + +// A ClientHelloInfo is a tls.ClientHelloInfo +type ClientHelloInfo = tls.ClientHelloInfo + +// The CertificateRequestInfo is a tls.CertificateRequestInfo +type CertificateRequestInfo = tls.CertificateRequestInfo + +// RenegotiationSupport enumerates the different levels of support for TLS +// renegotiation. TLS renegotiation is the act of performing subsequent +// handshakes on a connection after the first. This significantly complicates +// the state machine and has been the source of numerous, subtle security +// issues. Initiating a renegotiation is not supported, but support for +// accepting renegotiation requests may be enabled. +// +// Even when enabled, the server may not change its identity between handshakes +// (i.e. the leaf certificate must be the same). Additionally, concurrent +// handshake and application data flow is not permitted so renegotiation can +// only be used with protocols that synchronise with the renegotiation, such as +// HTTPS. +// +// Renegotiation is not defined in TLS 1.3. +type RenegotiationSupport int + +const ( + // RenegotiateNever disables renegotiation. + RenegotiateNever RenegotiationSupport = iota + + // RenegotiateOnceAsClient allows a remote server to request + // renegotiation once per connection. + RenegotiateOnceAsClient + + // RenegotiateFreelyAsClient allows a remote server to repeatedly + // request renegotiation. + RenegotiateFreelyAsClient +) + +// A Config structure is used to configure a TLS client or server. +// After one has been passed to a TLS function it must not be +// modified. A Config may be reused; the tls package will also not +// modify it. +type Config struct { + // Rand provides the source of entropy for nonces and RSA blinding. + // If Rand is nil, TLS uses the cryptographic random reader in package + // crypto/rand. + // The Reader must be safe for use by multiple goroutines. + Rand io.Reader + + // Time returns the current time as the number of seconds since the epoch. + // If Time is nil, TLS uses time.Now. + Time func() time.Time + + // Certificates contains one or more certificate chains to present to + // the other side of the connection. Server configurations must include + // at least one certificate or else set GetCertificate. Clients doing + // client-authentication may set either Certificates or + // GetClientCertificate. + Certificates []Certificate + + // NameToCertificate maps from a certificate name to an element of + // Certificates. Note that a certificate name can be of the form + // '*.example.com' and so doesn't have to be a domain name as such. + // See Config.BuildNameToCertificate + // The nil value causes the first element of Certificates to be used + // for all connections. + NameToCertificate map[string]*Certificate + + // GetCertificate returns a Certificate based on the given + // ClientHelloInfo. It will only be called if the client supplies SNI + // information or if Certificates is empty. + // + // If GetCertificate is nil or returns nil, then the certificate is + // retrieved from NameToCertificate. If NameToCertificate is nil, the + // first element of Certificates will be used. + GetCertificate func(*ClientHelloInfo) (*Certificate, error) + + // GetClientCertificate, if not nil, is called when a server requests a + // certificate from a client. If set, the contents of Certificates will + // be ignored. + // + // If GetClientCertificate returns an error, the handshake will be + // aborted and that error will be returned. Otherwise + // GetClientCertificate must return a non-nil Certificate. If + // Certificate.Certificate is empty then no certificate will be sent to + // the server. If this is unacceptable to the server then it may abort + // the handshake. + // + // GetClientCertificate may be called multiple times for the same + // connection if renegotiation occurs or if TLS 1.3 is in use. + GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) + + // GetConfigForClient, if not nil, is called after a ClientHello is + // received from a client. It may return a non-nil Config in order to + // change the Config that will be used to handle this connection. If + // the returned Config is nil, the original Config will be used. The + // Config returned by this callback may not be subsequently modified. + // + // If GetConfigForClient is nil, the Config passed to Server() will be + // used for all connections. + // + // Uniquely for the fields in the returned Config, session ticket keys + // will be duplicated from the original Config if not set. + // Specifically, if SetSessionTicketKeys was called on the original + // config but not on the returned config then the ticket keys from the + // original config will be copied into the new config before use. + // Otherwise, if SessionTicketKey was set in the original config but + // not in the returned config then it will be copied into the returned + // config before use. If neither of those cases applies then the key + // material from the returned config will be used for session tickets. + GetConfigForClient func(*ClientHelloInfo) (*Config, error) + + // VerifyPeerCertificate, if not nil, is called after normal + // certificate verification by either a TLS client or server. It + // receives the raw ASN.1 certificates provided by the peer and also + // any verified chains that normal processing found. If it returns a + // non-nil error, the handshake is aborted and that error results. + // + // If normal verification fails then the handshake will abort before + // considering this callback. If normal verification is disabled by + // setting InsecureSkipVerify, or (for a server) when ClientAuth is + // RequestClientCert or RequireAnyClientCert, then this callback will + // be considered but the verifiedChains argument will always be nil. + VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error + + // RootCAs defines the set of root certificate authorities + // that clients use when verifying server certificates. + // If RootCAs is nil, TLS uses the host's root CA set. + RootCAs *x509.CertPool + + // NextProtos is a list of supported application level protocols, in + // order of preference. + NextProtos []string + + // ServerName is used to verify the hostname on the returned + // certificates unless InsecureSkipVerify is given. It is also included + // in the client's handshake to support virtual hosting unless it is + // an IP address. + ServerName string + + // ClientAuth determines the server's policy for + // TLS Client Authentication. The default is NoClientCert. + ClientAuth ClientAuthType + + // ClientCAs defines the set of root certificate authorities + // that servers use if required to verify a client certificate + // by the policy in ClientAuth. + ClientCAs *x509.CertPool + + // InsecureSkipVerify controls whether a client verifies the + // server's certificate chain and host name. + // If InsecureSkipVerify is true, TLS accepts any certificate + // presented by the server and any host name in that certificate. + // In this mode, TLS is susceptible to man-in-the-middle attacks. + // This should be used only for testing. + InsecureSkipVerify bool + + // CipherSuites is a list of supported cipher suites for TLS versions up to + // TLS 1.2. If CipherSuites is nil, a default list of secure cipher suites + // is used, with a preference order based on hardware performance. The + // default cipher suites might change over Go versions. Note that TLS 1.3 + // ciphersuites are not configurable. + CipherSuites []uint16 + + // PreferServerCipherSuites controls whether the server selects the + // client's most preferred ciphersuite, or the server's most preferred + // ciphersuite. If true then the server's preference, as expressed in + // the order of elements in CipherSuites, is used. + PreferServerCipherSuites bool + + // SessionTicketsDisabled may be set to true to disable session ticket and + // PSK (resumption) support. Note that on clients, session ticket support is + // also disabled if ClientSessionCache is nil. + SessionTicketsDisabled bool + + // SessionTicketKey is used by TLS servers to provide session resumption. + // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled + // with random data before the first server handshake. + // + // If multiple servers are terminating connections for the same host + // they should all have the same SessionTicketKey. If the + // SessionTicketKey leaks, previously recorded and future TLS + // connections using that key might be compromised. + SessionTicketKey [32]byte + + // ClientSessionCache is a cache of ClientSessionState entries for TLS + // session resumption. It is only used by clients. + ClientSessionCache ClientSessionCache + + // MinVersion contains the minimum SSL/TLS version that is acceptable. + // If zero, then TLS 1.0 is taken as the minimum. + MinVersion uint16 + + // MaxVersion contains the maximum SSL/TLS version that is acceptable. + // If zero, then the maximum version supported by this package is used, + // which is currently TLS 1.3. + MaxVersion uint16 + + // CurvePreferences contains the elliptic curves that will be used in + // an ECDHE handshake, in preference order. If empty, the default will + // be used. The client will use the first preference as the type for + // its key share in TLS 1.3. This may change in the future. + CurvePreferences []CurveID + + // DynamicRecordSizingDisabled disables adaptive sizing of TLS records. + // When true, the largest possible TLS record size is always used. When + // false, the size of TLS records may be adjusted in an attempt to + // improve latency. + DynamicRecordSizingDisabled bool + + // Renegotiation controls what types of renegotiation are supported. + // The default, none, is correct for the vast majority of applications. + Renegotiation RenegotiationSupport + + // KeyLogWriter optionally specifies a destination for TLS master secrets + // in NSS key log format that can be used to allow external programs + // such as Wireshark to decrypt TLS connections. + // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. + // Use of KeyLogWriter compromises security and should only be + // used for debugging. + KeyLogWriter io.Writer + + // GetExtensions, if not nil, is called before a message that allows + // sending of extensions is sent. + // Currently only implemented for the ClientHello message (for the client) + // and for the EncryptedExtensions message (for the server). + // Only valid for TLS 1.3. + GetExtensions func(handshakeMessageType uint8) []Extension + + // ReceivedExtensions, if not nil, is called when a message that allows the + // inclusion of extensions is received. + // It is called with an empty slice of extensions, if the message didn't + // contain any extensions. + // Currently only implemented for the ClientHello message (sent by the + // client) and for the EncryptedExtensions message (sent by the server). + // Only valid for TLS 1.3. + ReceivedExtensions func(handshakeMessageType uint8, exts []Extension) + + serverInitOnce sync.Once // guards calling (*Config).serverInit + + // mutex protects sessionTicketKeys. + mutex sync.RWMutex + // sessionTicketKeys contains zero or more ticket keys. If the length + // is zero, SessionTicketsDisabled must be true. The first key is used + // for new tickets and any subsequent keys can be used to decrypt old + // tickets. + sessionTicketKeys []ticketKey + + // AlternativeRecordLayer is used by QUIC + AlternativeRecordLayer RecordLayer + + // Enforce the selection of a supported application protocol. + // Only works for TLS 1.3. + // If enabled, client and server have to agree on an application protocol. + // Otherwise, connection establishment fails. + EnforceNextProtoSelection bool +} + +type RecordLayer interface { + SetReadKey(suite *CipherSuite, trafficSecret []byte) + SetWriteKey(suite *CipherSuite, trafficSecret []byte) + ReadHandshakeMessage() ([]byte, error) + WriteRecord([]byte) (int, error) + SendAlert(uint8) +} + +// ticketKeyNameLen is the number of bytes of identifier that is prepended to +// an encrypted session ticket in order to identify the key used to encrypt it. +const ticketKeyNameLen = 16 + +// ticketKey is the internal representation of a session ticket key. +type ticketKey struct { + // keyName is an opaque byte string that serves to identify the session + // ticket key. It's exposed as plaintext in every session ticket. + keyName [ticketKeyNameLen]byte + aesKey [16]byte + hmacKey [16]byte +} + +// ticketKeyFromBytes converts from the external representation of a session +// ticket key to a ticketKey. Externally, session ticket keys are 32 random +// bytes and this function expands that into sufficient name and key material. +func ticketKeyFromBytes(b [32]byte) (key ticketKey) { + hashed := sha512.Sum512(b[:]) + copy(key.keyName[:], hashed[:ticketKeyNameLen]) + copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16]) + copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32]) + return key +} + +// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session +// ticket, and the lifetime we set for tickets we send. +const maxSessionTicketLifetime = 7 * 24 * time.Hour + +// Clone returns a shallow clone of c. It is safe to clone a Config that is +// being used concurrently by a TLS client or server. +func (c *Config) Clone() *Config { + // Running serverInit ensures that it's safe to read + // SessionTicketsDisabled. + c.serverInitOnce.Do(func() { c.serverInit(nil) }) + + var sessionTicketKeys []ticketKey + c.mutex.RLock() + sessionTicketKeys = c.sessionTicketKeys + c.mutex.RUnlock() + + return &Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + GetClientCertificate: c.GetClientCertificate, + GetConfigForClient: c.GetConfigForClient, + VerifyPeerCertificate: c.VerifyPeerCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + Renegotiation: c.Renegotiation, + KeyLogWriter: c.KeyLogWriter, + GetExtensions: c.GetExtensions, + ReceivedExtensions: c.ReceivedExtensions, + sessionTicketKeys: sessionTicketKeys, + EnforceNextProtoSelection: c.EnforceNextProtoSelection, + } +} + +// serverInit is run under c.serverInitOnce to do initialization of c. If c was +// returned by a GetConfigForClient callback then the argument should be the +// Config that was passed to Server, otherwise it should be nil. +func (c *Config) serverInit(originalConfig *Config) { + if c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 { + return + } + + alreadySet := false + for _, b := range c.SessionTicketKey { + if b != 0 { + alreadySet = true + break + } + } + + if !alreadySet { + if originalConfig != nil { + copy(c.SessionTicketKey[:], originalConfig.SessionTicketKey[:]) + } else if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { + c.SessionTicketsDisabled = true + return + } + } + + if originalConfig != nil { + originalConfig.mutex.RLock() + c.sessionTicketKeys = originalConfig.sessionTicketKeys + originalConfig.mutex.RUnlock() + } else { + c.sessionTicketKeys = []ticketKey{ticketKeyFromBytes(c.SessionTicketKey)} + } +} + +func (c *Config) ticketKeys() []ticketKey { + c.mutex.RLock() + // c.sessionTicketKeys is constant once created. SetSessionTicketKeys + // will only update it by replacing it with a new value. + ret := c.sessionTicketKeys + c.mutex.RUnlock() + return ret +} + +// SetSessionTicketKeys updates the session ticket keys for a server. The first +// key will be used when creating new tickets, while all keys can be used for +// decrypting tickets. It is safe to call this function while the server is +// running in order to rotate the session ticket keys. The function will panic +// if keys is empty. +func (c *Config) SetSessionTicketKeys(keys [][32]byte) { + if len(keys) == 0 { + panic("tls: keys must have at least one key") + } + + newKeys := make([]ticketKey, len(keys)) + for i, bytes := range keys { + newKeys[i] = ticketKeyFromBytes(bytes) + } + + c.mutex.Lock() + c.sessionTicketKeys = newKeys + c.mutex.Unlock() +} + +func (c *Config) rand() io.Reader { + r := c.Rand + if r == nil { + return rand.Reader + } + return r +} + +func (c *Config) time() time.Time { + t := c.Time + if t == nil { + t = time.Now + } + return t() +} + +func (c *Config) cipherSuites() []uint16 { + s := c.CipherSuites + if s == nil { + s = defaultCipherSuites() + } + return s +} + +var supportedVersions = []uint16{ + VersionTLS13, + VersionTLS12, + VersionTLS11, + VersionTLS10, + VersionSSL30, +} + +func (c *Config) supportedVersions(isClient bool) []uint16 { + versions := make([]uint16, 0, len(supportedVersions)) + for _, v := range supportedVersions { + if c != nil && c.MinVersion != 0 && v < c.MinVersion { + continue + } + if c != nil && c.MaxVersion != 0 && v > c.MaxVersion { + continue + } + // TLS 1.0 is the minimum version supported as a client. + if isClient && v < VersionTLS10 { + continue + } + // TLS 1.3 is opt-in in Go 1.12. + if v == VersionTLS13 && !isTLS13Supported() { + continue + } + versions = append(versions, v) + } + return versions +} + +// tls13Support caches the result for isTLS13Supported. +var tls13Support struct { + sync.Once + cached bool +} + +// isTLS13Supported returns whether the program opted into TLS 1.3 via +// GODEBUG=tls13=1. It's cached after the first execution. +func isTLS13Supported() bool { + return true + tls13Support.Do(func() { + tls13Support.cached = goDebugString("tls13") == "1" + }) + return tls13Support.cached +} + +// goDebugString returns the value of the named GODEBUG key. +// GODEBUG is of the form "key=val,key2=val2". +func goDebugString(key string) string { + s := os.Getenv("GODEBUG") + for i := 0; i < len(s)-len(key)-1; i++ { + if i > 0 && s[i-1] != ',' { + continue + } + afterKey := s[i+len(key):] + if afterKey[0] != '=' || s[i:i+len(key)] != key { + continue + } + val := afterKey[1:] + for i, b := range val { + if b == ',' { + return val[:i] + } + } + return val + } + return "" +} + +func (c *Config) maxSupportedVersion(isClient bool) uint16 { + supportedVersions := c.supportedVersions(isClient) + if len(supportedVersions) == 0 { + return 0 + } + return supportedVersions[0] +} + +// supportedVersionsFromMax returns a list of supported versions derived from a +// legacy maximum version value. Note that only versions supported by this +// library are returned. Any newer peer will use supportedVersions anyway. +func supportedVersionsFromMax(maxVersion uint16) []uint16 { + versions := make([]uint16, 0, len(supportedVersions)) + for _, v := range supportedVersions { + if v > maxVersion { + continue + } + versions = append(versions, v) + } + return versions +} + +var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521} + +func (c *Config) curvePreferences() []CurveID { + if c == nil || len(c.CurvePreferences) == 0 { + return defaultCurvePreferences + } + return c.CurvePreferences +} + +// mutualVersion returns the protocol version to use given the advertised +// versions of the peer. Priority is given to the peer preference order. +func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) { + supportedVersions := c.supportedVersions(isClient) + for _, peerVersion := range peerVersions { + for _, v := range supportedVersions { + if v == peerVersion { + return v, true + } + } + } + return 0, false +} + +// getCertificate returns the best certificate for the given ClientHelloInfo, +// defaulting to the first element of c.Certificates. +func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { + if c.GetCertificate != nil && + (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) { + cert, err := c.GetCertificate(clientHello) + if cert != nil || err != nil { + return cert, err + } + } + + if len(c.Certificates) == 0 { + return nil, errors.New("tls: no certificates configured") + } + + if len(c.Certificates) == 1 || c.NameToCertificate == nil { + // There's only one choice, so no point doing any work. + return &c.Certificates[0], nil + } + + name := strings.ToLower(clientHello.ServerName) + for len(name) > 0 && name[len(name)-1] == '.' { + name = name[:len(name)-1] + } + + if cert, ok := c.NameToCertificate[name]; ok { + return cert, nil + } + + // try replacing labels in the name with wildcards until we get a + // match. + labels := strings.Split(name, ".") + for i := range labels { + labels[i] = "*" + candidate := strings.Join(labels, ".") + if cert, ok := c.NameToCertificate[candidate]; ok { + return cert, nil + } + } + + // If nothing matches, return the first certificate. + return &c.Certificates[0], nil +} + +// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate +// from the CommonName and SubjectAlternateName fields of each of the leaf +// certificates. +func (c *Config) BuildNameToCertificate() { + c.NameToCertificate = make(map[string]*Certificate) + for i := range c.Certificates { + cert := &c.Certificates[i] + x509Cert := cert.Leaf + if x509Cert == nil { + var err error + x509Cert, err = x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + continue + } + } + if len(x509Cert.Subject.CommonName) > 0 { + c.NameToCertificate[x509Cert.Subject.CommonName] = cert + } + for _, san := range x509Cert.DNSNames { + c.NameToCertificate[san] = cert + } + } +} + +const ( + keyLogLabelTLS12 = "CLIENT_RANDOM" + keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET" + keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET" + keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0" + keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0" +) + +func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error { + if c.KeyLogWriter == nil { + return nil + } + + logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)) + + writerMutex.Lock() + _, err := c.KeyLogWriter.Write(logLine) + writerMutex.Unlock() + + return err +} + +// writerMutex protects all KeyLogWriters globally. It is rarely enabled, +// and is only for debugging, so a global mutex saves space. +var writerMutex sync.Mutex + +// A Certificate is a tls.Certificate +type Certificate = tls.Certificate + +type handshakeMessage interface { + marshal() []byte + unmarshal([]byte) bool +} + +// lruSessionCache is a ClientSessionCache implementation that uses an LRU +// caching strategy. +type lruSessionCache struct { + sync.Mutex + + m map[string]*list.Element + q *list.List + capacity int +} + +type lruSessionCacheEntry struct { + sessionKey string + state *ClientSessionState +} + +// NewLRUClientSessionCache returns a ClientSessionCache with the given +// capacity that uses an LRU strategy. If capacity is < 1, a default capacity +// is used instead. +func NewLRUClientSessionCache(capacity int) ClientSessionCache { + const defaultSessionCacheCapacity = 64 + + if capacity < 1 { + capacity = defaultSessionCacheCapacity + } + return &lruSessionCache{ + m: make(map[string]*list.Element), + q: list.New(), + capacity: capacity, + } +} + +// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry +// corresponding to sessionKey is removed from the cache instead. +func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { + c.Lock() + defer c.Unlock() + + if elem, ok := c.m[sessionKey]; ok { + if cs == nil { + c.q.Remove(elem) + delete(c.m, sessionKey) + } else { + entry := elem.Value.(*lruSessionCacheEntry) + entry.state = cs + c.q.MoveToFront(elem) + } + return + } + + if c.q.Len() < c.capacity { + entry := &lruSessionCacheEntry{sessionKey, cs} + c.m[sessionKey] = c.q.PushFront(entry) + return + } + + elem := c.q.Back() + entry := elem.Value.(*lruSessionCacheEntry) + delete(c.m, entry.sessionKey) + entry.sessionKey = sessionKey + entry.state = cs + c.q.MoveToFront(elem) + c.m[sessionKey] = elem +} + +// Get returns the ClientSessionState value associated with a given key. It +// returns (nil, false) if no value is found. +func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { + c.Lock() + defer c.Unlock() + + if elem, ok := c.m[sessionKey]; ok { + c.q.MoveToFront(elem) + return elem.Value.(*lruSessionCacheEntry).state, true + } + return nil, false +} + +// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. +type dsaSignature struct { + R, S *big.Int +} + +type ecdsaSignature dsaSignature + +var emptyConfig Config + +func defaultConfig() *Config { + return &emptyConfig +} + +var ( + once sync.Once + varDefaultCipherSuites []uint16 + varDefaultCipherSuitesTLS13 []uint16 +) + +func defaultCipherSuites() []uint16 { + once.Do(initDefaultCipherSuites) + return varDefaultCipherSuites +} + +func defaultCipherSuitesTLS13() []uint16 { + once.Do(initDefaultCipherSuites) + return varDefaultCipherSuitesTLS13 +} + +func initDefaultCipherSuites() { + var topCipherSuites []uint16 + + // Check the cpu flags for each platform that has optimized GCM implementations. + // Worst case, these variables will just all be false. + var ( + hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // Keep in sync with crypto/aes/cipher_s390x.go. + // TODO: check for s390 + // hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) + hasGCMAsmS390X = false + + hasGCMAsm = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X + ) + + if hasGCMAsm { + // If AES-GCM hardware is provided then prioritise AES-GCM + // cipher suites. + topCipherSuites = []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + } + varDefaultCipherSuitesTLS13 = []uint16{ + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_256_GCM_SHA384, + } + } else { + // Without AES-GCM hardware, we put the ChaCha20-Poly1305 + // cipher suites first. + topCipherSuites = []uint16{ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + varDefaultCipherSuitesTLS13 = []uint16{ + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384, + } + } + + varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites)) + varDefaultCipherSuites = append(varDefaultCipherSuites, topCipherSuites...) + +NextCipherSuite: + for _, suite := range cipherSuites { + if suite.flags&suiteDefaultOff != 0 { + continue + } + for _, existing := range varDefaultCipherSuites { + if existing == suite.id { + continue NextCipherSuite + } + } + varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id) + } +} + +func unexpectedMessageError(wanted, got interface{}) error { + return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) +} + +func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool { + for _, s := range supportedSignatureAlgorithms { + if s == sigAlg { + return true + } + } + return false +} + +// signatureFromSignatureScheme maps a signature algorithm to the underlying +// signature method (without hash function). +func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 { + switch signatureAlgorithm { + case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: + return signaturePKCS1v15 + case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: + return signatureRSAPSS + case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: + return signatureECDSA + default: + return 0 + } +} diff --git a/vendor/github.com/marten-seemann/qtls/conn.go b/vendor/github.com/marten-seemann/qtls/conn.go new file mode 100644 index 00000000..bbb67e56 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/conn.go @@ -0,0 +1,1467 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// TLS low level connection and record layer + +package qtls + +import ( + "bytes" + "crypto/cipher" + "crypto/subtle" + "crypto/x509" + "errors" + "fmt" + "io" + "net" + "sync" + "sync/atomic" + "time" +) + +// A Conn represents a secured connection. +// It implements the net.Conn interface. +type Conn struct { + // constant + conn net.Conn + isClient bool + + // handshakeStatus is 1 if the connection is currently transferring + // application data (i.e. is not currently processing a handshake). + // This field is only to be accessed with sync/atomic. + handshakeStatus uint32 + // constant after handshake; protected by handshakeMutex + handshakeMutex sync.Mutex + handshakeErr error // error resulting from handshake + vers uint16 // TLS version + haveVers bool // version has been negotiated + config *Config // configuration passed to constructor + // handshakes counts the number of handshakes performed on the + // connection so far. If renegotiation is disabled then this is either + // zero or one. + handshakes int + didResume bool // whether this connection was a session resumption + cipherSuite uint16 + ocspResponse []byte // stapled OCSP response + scts [][]byte // signed certificate timestamps from server + peerCertificates []*x509.Certificate + // verifiedChains contains the certificate chains that we built, as + // opposed to the ones presented by the server. + verifiedChains [][]*x509.Certificate + // serverName contains the server name indicated by the client, if any. + serverName string + // secureRenegotiation is true if the server echoed the secure + // renegotiation extension. (This is meaningless as a server because + // renegotiation is not supported in that case.) + secureRenegotiation bool + // ekm is a closure for exporting keying material. + ekm func(label string, context []byte, length int) ([]byte, error) + // resumptionSecret is the resumption_master_secret for handling + // NewSessionTicket messages. nil if config.SessionTicketsDisabled. + resumptionSecret []byte + + // clientFinishedIsFirst is true if the client sent the first Finished + // message during the most recent handshake. This is recorded because + // the first transmitted Finished message is the tls-unique + // channel-binding value. + clientFinishedIsFirst bool + + // closeNotifyErr is any error from sending the alertCloseNotify record. + closeNotifyErr error + // closeNotifySent is true if the Conn attempted to send an + // alertCloseNotify record. + closeNotifySent bool + + // clientFinished and serverFinished contain the Finished message sent + // by the client or server in the most recent handshake. This is + // retained to support the renegotiation extension and tls-unique + // channel-binding. + clientFinished [12]byte + serverFinished [12]byte + + clientProtocol string + clientProtocolFallback bool + + // input/output + in, out halfConn + rawInput bytes.Buffer // raw input, starting with a record header + input bytes.Reader // application data waiting to be read, from rawInput.Next + hand bytes.Buffer // handshake data waiting to be read + outBuf []byte // scratch buffer used by out.encrypt + buffering bool // whether records are buffered in sendBuf + sendBuf []byte // a buffer of records waiting to be sent + + // bytesSent counts the bytes of application data sent. + // packetsSent counts packets. + bytesSent int64 + packetsSent int64 + + // retryCount counts the number of consecutive non-advancing records + // received by Conn.readRecord. That is, records that neither advance the + // handshake, nor deliver application data. Protected by in.Mutex. + retryCount int + + // activeCall is an atomic int32; the low bit is whether Close has + // been called. the rest of the bits are the number of goroutines + // in Conn.Write. + activeCall int32 + + tmp [16]byte +} + +// Access to net.Conn methods. +// Cannot just embed net.Conn because that would +// export the struct field too. + +// LocalAddr returns the local network address. +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +// RemoteAddr returns the remote network address. +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +// SetDeadline sets the read and write deadlines associated with the connection. +// A zero value for t means Read and Write will not time out. +// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. +func (c *Conn) SetDeadline(t time.Time) error { + return c.conn.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline on the underlying connection. +// A zero value for t means Read will not time out. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline on the underlying connection. +// A zero value for t means Write will not time out. +// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.conn.SetWriteDeadline(t) +} + +// A halfConn represents one direction of the record layer +// connection, either sending or receiving. +type halfConn struct { + sync.Mutex + + err error // first permanent error + version uint16 // protocol version + cipher interface{} // cipher algorithm + mac macFunction + seq [8]byte // 64-bit sequence number + additionalData [13]byte // to avoid allocs; interface method args escape + + nextCipher interface{} // next encryption state + nextMac macFunction // next MAC algorithm + + trafficSecret []byte // current TLS 1.3 traffic secret + + setKeyCallback func(suite *CipherSuite, trafficSecret []byte) +} + +func (hc *halfConn) setErrorLocked(err error) error { + hc.err = err + return err +} + +// prepareCipherSpec sets the encryption and MAC states +// that a subsequent changeCipherSpec will use. +func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) { + hc.version = version + hc.nextCipher = cipher + hc.nextMac = mac +} + +// changeCipherSpec changes the encryption and MAC states +// to the ones previously passed to prepareCipherSpec. +func (hc *halfConn) changeCipherSpec() error { + if hc.nextCipher == nil || hc.version == VersionTLS13 { + return alertInternalError + } + hc.cipher = hc.nextCipher + hc.mac = hc.nextMac + hc.nextCipher = nil + hc.nextMac = nil + for i := range hc.seq { + hc.seq[i] = 0 + } + return nil +} + +func (hc *halfConn) exportKey(suite *cipherSuiteTLS13, trafficSecret []byte) { + if hc.setKeyCallback != nil { + hc.setKeyCallback(&CipherSuite{suite}, trafficSecret) + } +} + +func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) { + hc.trafficSecret = secret + key, iv := suite.trafficKey(secret) + hc.cipher = suite.aead(key, iv) + for i := range hc.seq { + hc.seq[i] = 0 + } +} + +// incSeq increments the sequence number. +func (hc *halfConn) incSeq() { + for i := 7; i >= 0; i-- { + hc.seq[i]++ + if hc.seq[i] != 0 { + return + } + } + + // Not allowed to let sequence number wrap. + // Instead, must renegotiate before it does. + // Not likely enough to bother. + panic("TLS: sequence number wraparound") +} + +// explicitNonceLen returns the number of bytes of explicit nonce or IV included +// in each record. Explicit nonces are present only in CBC modes after TLS 1.0 +// and in certain AEAD modes in TLS 1.2. +func (hc *halfConn) explicitNonceLen() int { + if hc.cipher == nil { + return 0 + } + + switch c := hc.cipher.(type) { + case cipher.Stream: + return 0 + case aead: + return c.explicitNonceLen() + case cbcMode: + // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack. + if hc.version >= VersionTLS11 { + return c.BlockSize() + } + return 0 + default: + panic("unknown cipher type") + } +} + +// extractPadding returns, in constant time, the length of the padding to remove +// from the end of payload. It also returns a byte which is equal to 255 if the +// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2. +func extractPadding(payload []byte) (toRemove int, good byte) { + if len(payload) < 1 { + return 0, 0 + } + + paddingLen := payload[len(payload)-1] + t := uint(len(payload)-1) - uint(paddingLen) + // if len(payload) >= (paddingLen - 1) then the MSB of t is zero + good = byte(int32(^t) >> 31) + + // The maximum possible padding length plus the actual length field + toCheck := 256 + // The length of the padded data is public, so we can use an if here + if toCheck > len(payload) { + toCheck = len(payload) + } + + for i := 0; i < toCheck; i++ { + t := uint(paddingLen) - uint(i) + // if i <= paddingLen then the MSB of t is zero + mask := byte(int32(^t) >> 31) + b := payload[len(payload)-1-i] + good &^= mask&paddingLen ^ mask&b + } + + // We AND together the bits of good and replicate the result across + // all the bits. + good &= good << 4 + good &= good << 2 + good &= good << 1 + good = uint8(int8(good) >> 7) + + toRemove = int(paddingLen) + 1 + return +} + +// extractPaddingSSL30 is a replacement for extractPadding in the case that the +// protocol version is SSLv3. In this version, the contents of the padding +// are random and cannot be checked. +func extractPaddingSSL30(payload []byte) (toRemove int, good byte) { + if len(payload) < 1 { + return 0, 0 + } + + paddingLen := int(payload[len(payload)-1]) + 1 + if paddingLen > len(payload) { + return 0, 0 + } + + return paddingLen, 255 +} + +func roundUp(a, b int) int { + return a + (b-a%b)%b +} + +// cbcMode is an interface for block ciphers using cipher block chaining. +type cbcMode interface { + cipher.BlockMode + SetIV([]byte) +} + +// decrypt authenticates and decrypts the record if protection is active at +// this stage. The returned plaintext might overlap with the input. +func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { + var plaintext []byte + typ := recordType(record[0]) + payload := record[recordHeaderLen:] + + // In TLS 1.3, change_cipher_spec messages are to be ignored without being + // decrypted. See RFC 8446, Appendix D.4. + if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec { + return payload, typ, nil + } + + paddingGood := byte(255) + paddingLen := 0 + + explicitNonceLen := hc.explicitNonceLen() + + if hc.cipher != nil { + switch c := hc.cipher.(type) { + case cipher.Stream: + c.XORKeyStream(payload, payload) + case aead: + if len(payload) < explicitNonceLen { + return nil, 0, alertBadRecordMAC + } + nonce := payload[:explicitNonceLen] + if len(nonce) == 0 { + nonce = hc.seq[:] + } + payload = payload[explicitNonceLen:] + + additionalData := hc.additionalData[:] + if hc.version == VersionTLS13 { + additionalData = record[:recordHeaderLen] + } else { + copy(additionalData, hc.seq[:]) + copy(additionalData[8:], record[:3]) + n := len(payload) - c.Overhead() + additionalData[11] = byte(n >> 8) + additionalData[12] = byte(n) + } + + var err error + plaintext, err = c.Open(payload[:0], nonce, payload, additionalData) + if err != nil { + return nil, 0, alertBadRecordMAC + } + case cbcMode: + blockSize := c.BlockSize() + minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize) + if len(payload)%blockSize != 0 || len(payload) < minPayload { + return nil, 0, alertBadRecordMAC + } + + if explicitNonceLen > 0 { + c.SetIV(payload[:explicitNonceLen]) + payload = payload[explicitNonceLen:] + } + c.CryptBlocks(payload, payload) + + // In a limited attempt to protect against CBC padding oracles like + // Lucky13, the data past paddingLen (which is secret) is passed to + // the MAC function as extra data, to be fed into the HMAC after + // computing the digest. This makes the MAC roughly constant time as + // long as the digest computation is constant time and does not + // affect the subsequent write, modulo cache effects. + if hc.version == VersionSSL30 { + paddingLen, paddingGood = extractPaddingSSL30(payload) + } else { + paddingLen, paddingGood = extractPadding(payload) + } + default: + panic("unknown cipher type") + } + + if hc.version == VersionTLS13 { + if typ != recordTypeApplicationData { + return nil, 0, alertUnexpectedMessage + } + if len(plaintext) > maxPlaintext+1 { + return nil, 0, alertRecordOverflow + } + // Remove padding and find the ContentType scanning from the end. + for i := len(plaintext) - 1; i >= 0; i-- { + if plaintext[i] != 0 { + typ = recordType(plaintext[i]) + plaintext = plaintext[:i] + break + } + if i == 0 { + return nil, 0, alertUnexpectedMessage + } + } + } + } else { + plaintext = payload + } + + if hc.mac != nil { + macSize := hc.mac.Size() + if len(payload) < macSize { + return nil, 0, alertBadRecordMAC + } + + n := len(payload) - macSize - paddingLen + n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 } + record[3] = byte(n >> 8) + record[4] = byte(n) + remoteMAC := payload[n : n+macSize] + localMAC := hc.mac.MAC(hc.seq[0:], record[:recordHeaderLen], payload[:n], payload[n+macSize:]) + + if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { + return nil, 0, alertBadRecordMAC + } + + plaintext = payload[:n] + } + + hc.incSeq() + return plaintext, typ, nil +} + +func (c *Conn) setAlternativeRecordLayer() { + if c.config.AlternativeRecordLayer != nil { + c.in.setKeyCallback = c.config.AlternativeRecordLayer.SetReadKey + c.out.setKeyCallback = c.config.AlternativeRecordLayer.SetWriteKey + } +} + +// sliceForAppend extends the input slice by n bytes. head is the full extended +// slice, while tail is the appended part. If the original slice has sufficient +// capacity no allocation is performed. +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return +} + +// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and +// appends it to record, which contains the record header. +func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) { + if hc.cipher == nil { + return append(record, payload...), nil + } + + var explicitNonce []byte + if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 { + record, explicitNonce = sliceForAppend(record, explicitNonceLen) + if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 { + // The AES-GCM construction in TLS has an explicit nonce so that the + // nonce can be random. However, the nonce is only 8 bytes which is + // too small for a secure, random nonce. Therefore we use the + // sequence number as the nonce. The 3DES-CBC construction also has + // an 8 bytes nonce but its nonces must be unpredictable (see RFC + // 5246, Appendix F.3), forcing us to use randomness. That's not + // 3DES' biggest problem anyway because the birthday bound on block + // collision is reached first due to its simlarly small block size + // (see the Sweet32 attack). + copy(explicitNonce, hc.seq[:]) + } else { + if _, err := io.ReadFull(rand, explicitNonce); err != nil { + return nil, err + } + } + } + + var mac []byte + if hc.mac != nil { + mac = hc.mac.MAC(hc.seq[:], record[:recordHeaderLen], payload, nil) + } + + var dst []byte + switch c := hc.cipher.(type) { + case cipher.Stream: + record, dst = sliceForAppend(record, len(payload)+len(mac)) + c.XORKeyStream(dst[:len(payload)], payload) + c.XORKeyStream(dst[len(payload):], mac) + case aead: + nonce := explicitNonce + if len(nonce) == 0 { + nonce = hc.seq[:] + } + + if hc.version == VersionTLS13 { + record = append(record, payload...) + + // Encrypt the actual ContentType and replace the plaintext one. + record = append(record, record[0]) + record[0] = byte(recordTypeApplicationData) + + n := len(payload) + 1 + c.Overhead() + record[3] = byte(n >> 8) + record[4] = byte(n) + + record = c.Seal(record[:recordHeaderLen], + nonce, record[recordHeaderLen:], record[:recordHeaderLen]) + } else { + copy(hc.additionalData[:], hc.seq[:]) + copy(hc.additionalData[8:], record) + record = c.Seal(record, nonce, payload, hc.additionalData[:]) + } + case cbcMode: + blockSize := c.BlockSize() + plaintextLen := len(payload) + len(mac) + paddingLen := blockSize - plaintextLen%blockSize + record, dst = sliceForAppend(record, plaintextLen+paddingLen) + copy(dst, payload) + copy(dst[len(payload):], mac) + for i := plaintextLen; i < len(dst); i++ { + dst[i] = byte(paddingLen - 1) + } + if len(explicitNonce) > 0 { + c.SetIV(explicitNonce) + } + c.CryptBlocks(dst, dst) + default: + panic("unknown cipher type") + } + + // Update length to include nonce, MAC and any block padding needed. + n := len(record) - recordHeaderLen + record[3] = byte(n >> 8) + record[4] = byte(n) + hc.incSeq() + + return record, nil +} + +// RecordHeaderError is returned when a TLS record header is invalid. +type RecordHeaderError struct { + // Msg contains a human readable string that describes the error. + Msg string + // RecordHeader contains the five bytes of TLS record header that + // triggered the error. + RecordHeader [5]byte + // Conn provides the underlying net.Conn in the case that a client + // sent an initial handshake that didn't look like TLS. + // It is nil if there's already been a handshake or a TLS alert has + // been written to the connection. + Conn net.Conn +} + +func (e RecordHeaderError) Error() string { return "tls: " + e.Msg } + +func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) { + err.Msg = msg + err.Conn = conn + copy(err.RecordHeader[:], c.rawInput.Bytes()) + return err +} + +func (c *Conn) readRecord() error { + return c.readRecordOrCCS(false) +} + +func (c *Conn) readChangeCipherSpec() error { + return c.readRecordOrCCS(true) +} + +// readRecordOrCCS reads one or more TLS records from the connection and +// updates the record layer state. Some invariants: +// * c.in must be locked +// * c.input must be empty +// During the handshake one and only one of the following will happen: +// - c.hand grows +// - c.in.changeCipherSpec is called +// - an error is returned +// After the handshake one and only one of the following will happen: +// - c.hand grows +// - c.input is set +// - an error is returned +func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error { + if c.in.err != nil { + return c.in.err + } + handshakeComplete := c.handshakeComplete() + + // This function modifies c.rawInput, which owns the c.input memory. + if c.input.Len() != 0 { + return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data")) + } + c.input.Reset(nil) + + // Read header, payload. + if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil { + // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify + // is an error, but popular web sites seem to do this, so we accept it + // if and only if at the record boundary. + if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 { + err = io.EOF + } + if e, ok := err.(net.Error); !ok || !e.Temporary() { + c.in.setErrorLocked(err) + } + return err + } + hdr := c.rawInput.Bytes()[:recordHeaderLen] + typ := recordType(hdr[0]) + + // No valid TLS record has a type of 0x80, however SSLv2 handshakes + // start with a uint16 length where the MSB is set and the first record + // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests + // an SSLv2 client. + if !handshakeComplete && typ == 0x80 { + c.sendAlert(alertProtocolVersion) + return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received")) + } + + vers := uint16(hdr[1])<<8 | uint16(hdr[2]) + n := int(hdr[3])<<8 | int(hdr[4]) + if c.haveVers && c.vers != VersionTLS13 && vers != c.vers { + c.sendAlert(alertProtocolVersion) + msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers) + return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) + } + if !c.haveVers { + // First message, be extra suspicious: this might not be a TLS + // client. Bail out before reading a full 'body', if possible. + // The current max version is 3.3 so if the version is >= 16.0, + // it's probably not real. + if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 { + return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake")) + } + } + if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext { + c.sendAlert(alertRecordOverflow) + msg := fmt.Sprintf("oversized record received with length %d", n) + return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) + } + if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil { + if e, ok := err.(net.Error); !ok || !e.Temporary() { + c.in.setErrorLocked(err) + } + return err + } + + // Process message. + record := c.rawInput.Next(recordHeaderLen + n) + data, typ, err := c.in.decrypt(record) + if err != nil { + return c.in.setErrorLocked(c.sendAlert(err.(alert))) + } + if len(data) > maxPlaintext { + return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow)) + } + + // Application Data messages are always protected. + if c.in.cipher == nil && typ == recordTypeApplicationData { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + + if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 { + // This is a state-advancing message: reset the retry count. + c.retryCount = 0 + } + + // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3. + if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + + switch typ { + default: + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + + case recordTypeAlert: + if len(data) != 2 { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + if alert(data[1]) == alertCloseNotify { + return c.in.setErrorLocked(io.EOF) + } + if c.vers == VersionTLS13 { + return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) + } + switch data[0] { + case alertLevelWarning: + // Drop the record on the floor and retry. + return c.retryReadRecord(expectChangeCipherSpec) + case alertLevelError: + return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) + default: + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + + case recordTypeChangeCipherSpec: + if len(data) != 1 || data[0] != 1 { + return c.in.setErrorLocked(c.sendAlert(alertDecodeError)) + } + // Handshake messages are not allowed to fragment across the CCS. + if c.hand.Len() > 0 { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + // In TLS 1.3, change_cipher_spec records are ignored until the + // Finished. See RFC 8446, Appendix D.4. Note that according to Section + // 5, a server can send a ChangeCipherSpec before its ServerHello, when + // c.vers is still unset. That's not useful though and suspicious if the + // server then selects a lower protocol version, so don't allow that. + if c.vers == VersionTLS13 { + return c.retryReadRecord(expectChangeCipherSpec) + } + if !expectChangeCipherSpec { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + if err := c.in.changeCipherSpec(); err != nil { + return c.in.setErrorLocked(c.sendAlert(err.(alert))) + } + + case recordTypeApplicationData: + if !handshakeComplete || expectChangeCipherSpec { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + // Some OpenSSL servers send empty records in order to randomize the + // CBC IV. Ignore a limited number of empty records. + if len(data) == 0 { + return c.retryReadRecord(expectChangeCipherSpec) + } + // Note that data is owned by c.rawInput, following the Next call above, + // to avoid copying the plaintext. This is safe because c.rawInput is + // not read from or written to until c.input is drained. + c.input.Reset(data) + + case recordTypeHandshake: + if len(data) == 0 || expectChangeCipherSpec { + return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + c.hand.Write(data) + } + + return nil +} + +// retryReadRecord recurses into readRecordOrCCS to drop a non-advancing record, like +// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3. +func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error { + c.retryCount++ + if c.retryCount > maxUselessRecords { + c.sendAlert(alertUnexpectedMessage) + return c.in.setErrorLocked(errors.New("tls: too many ignored records")) + } + return c.readRecordOrCCS(expectChangeCipherSpec) +} + +// atLeastReader reads from R, stopping with EOF once at least N bytes have been +// read. It is different from an io.LimitedReader in that it doesn't cut short +// the last Read call, and in that it considers an early EOF an error. +type atLeastReader struct { + R io.Reader + N int64 +} + +func (r *atLeastReader) Read(p []byte) (int, error) { + if r.N <= 0 { + return 0, io.EOF + } + n, err := r.R.Read(p) + r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809 + if r.N > 0 && err == io.EOF { + return n, io.ErrUnexpectedEOF + } + if r.N <= 0 && err == nil { + return n, io.EOF + } + return n, err +} + +// readFromUntil reads from r into c.rawInput until c.rawInput contains +// at least n bytes or else returns an error. +func (c *Conn) readFromUntil(r io.Reader, n int) error { + if c.rawInput.Len() >= n { + return nil + } + needs := n - c.rawInput.Len() + // There might be extra input waiting on the wire. Make a best effort + // attempt to fetch it so that it can be used in (*Conn).Read to + // "predict" closeNotify alerts. + c.rawInput.Grow(needs + bytes.MinRead) + _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)}) + return err +} + +// sendAlert sends a TLS alert message. +func (c *Conn) sendAlertLocked(err alert) error { + switch err { + case alertNoRenegotiation, alertCloseNotify: + c.tmp[0] = alertLevelWarning + default: + c.tmp[0] = alertLevelError + } + c.tmp[1] = byte(err) + + _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2]) + if err == alertCloseNotify { + // closeNotify is a special case in that it isn't an error. + return writeErr + } + + return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err}) +} + +// sendAlert sends a TLS alert message. +func (c *Conn) sendAlert(err alert) error { + if c.config.AlternativeRecordLayer != nil { + c.config.AlternativeRecordLayer.SendAlert(uint8(err)) + return &net.OpError{Op: "local error", Err: err} + } + + c.out.Lock() + defer c.out.Unlock() + return c.sendAlertLocked(err) +} + +const ( + // tcpMSSEstimate is a conservative estimate of the TCP maximum segment + // size (MSS). A constant is used, rather than querying the kernel for + // the actual MSS, to avoid complexity. The value here is the IPv6 + // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40 + // bytes) and a TCP header with timestamps (32 bytes). + tcpMSSEstimate = 1208 + + // recordSizeBoostThreshold is the number of bytes of application data + // sent after which the TLS record size will be increased to the + // maximum. + recordSizeBoostThreshold = 128 * 1024 +) + +// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the +// next application data record. There is the following trade-off: +// +// - For latency-sensitive applications, such as web browsing, each TLS +// record should fit in one TCP segment. +// - For throughput-sensitive applications, such as large file transfers, +// larger TLS records better amortize framing and encryption overheads. +// +// A simple heuristic that works well in practice is to use small records for +// the first 1MB of data, then use larger records for subsequent data, and +// reset back to smaller records after the connection becomes idle. See "High +// Performance Web Networking", Chapter 4, or: +// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/ +// +// In the interests of simplicity and determinism, this code does not attempt +// to reset the record size once the connection is idle, however. +func (c *Conn) maxPayloadSizeForWrite(typ recordType) int { + if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData { + return maxPlaintext + } + + if c.bytesSent >= recordSizeBoostThreshold { + return maxPlaintext + } + + // Subtract TLS overheads to get the maximum payload size. + payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen() + if c.out.cipher != nil { + switch ciph := c.out.cipher.(type) { + case cipher.Stream: + payloadBytes -= c.out.mac.Size() + case cipher.AEAD: + payloadBytes -= ciph.Overhead() + case cbcMode: + blockSize := ciph.BlockSize() + // The payload must fit in a multiple of blockSize, with + // room for at least one padding byte. + payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1 + // The MAC is appended before padding so affects the + // payload size directly. + payloadBytes -= c.out.mac.Size() + default: + panic("unknown cipher type") + } + } + if c.vers == VersionTLS13 { + payloadBytes-- // encrypted ContentType + } + + // Allow packet growth in arithmetic progression up to max. + pkt := c.packetsSent + c.packetsSent++ + if pkt > 1000 { + return maxPlaintext // avoid overflow in multiply below + } + + n := payloadBytes * int(pkt+1) + if n > maxPlaintext { + n = maxPlaintext + } + return n +} + +func (c *Conn) write(data []byte) (int, error) { + if c.buffering { + c.sendBuf = append(c.sendBuf, data...) + return len(data), nil + } + + n, err := c.conn.Write(data) + c.bytesSent += int64(n) + return n, err +} + +func (c *Conn) flush() (int, error) { + if len(c.sendBuf) == 0 { + return 0, nil + } + + n, err := c.conn.Write(c.sendBuf) + c.bytesSent += int64(n) + c.sendBuf = nil + c.buffering = false + return n, err +} + +// writeRecordLocked writes a TLS record with the given type and payload to the +// connection and updates the record layer state. +func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { + var n int + for len(data) > 0 { + m := len(data) + if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload { + m = maxPayload + } + + _, c.outBuf = sliceForAppend(c.outBuf[:0], recordHeaderLen) + c.outBuf[0] = byte(typ) + vers := c.vers + if vers == 0 { + // Some TLS servers fail if the record version is + // greater than TLS 1.0 for the initial ClientHello. + vers = VersionTLS10 + } else if vers == VersionTLS13 { + // TLS 1.3 froze the record layer version to 1.2. + // See RFC 8446, Section 5.1. + vers = VersionTLS12 + } + c.outBuf[1] = byte(vers >> 8) + c.outBuf[2] = byte(vers) + c.outBuf[3] = byte(m >> 8) + c.outBuf[4] = byte(m) + + var err error + c.outBuf, err = c.out.encrypt(c.outBuf, data[:m], c.config.rand()) + if err != nil { + return n, err + } + if _, err := c.write(c.outBuf); err != nil { + return n, err + } + n += m + data = data[m:] + } + + if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 { + if err := c.out.changeCipherSpec(); err != nil { + return n, c.sendAlertLocked(err.(alert)) + } + } + + return n, nil +} + +// writeRecord writes a TLS record with the given type and payload to the +// connection and updates the record layer state. +func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) { + if c.config.AlternativeRecordLayer != nil { + if typ == recordTypeChangeCipherSpec { + return len(data), nil + } + return c.config.AlternativeRecordLayer.WriteRecord(data) + } + + c.out.Lock() + defer c.out.Unlock() + + return c.writeRecordLocked(typ, data) +} + +// readHandshake reads the next handshake message from +// the record layer. +func (c *Conn) readHandshake() (interface{}, error) { + var data []byte + if c.config.AlternativeRecordLayer != nil { + var err error + data, err = c.config.AlternativeRecordLayer.ReadHandshakeMessage() + if err != nil { + return nil, err + } + } else { + for c.hand.Len() < 4 { + if err := c.readRecord(); err != nil { + return nil, err + } + } + + data = c.hand.Bytes() + n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) + if n > maxHandshake { + c.sendAlertLocked(alertInternalError) + return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)) + } + for c.hand.Len() < 4+n { + if err := c.readRecord(); err != nil { + return nil, err + } + } + data = c.hand.Next(4 + n) + } + var m handshakeMessage + switch data[0] { + case typeHelloRequest: + m = new(helloRequestMsg) + case typeClientHello: + m = new(clientHelloMsg) + case typeServerHello: + m = new(serverHelloMsg) + case typeNewSessionTicket: + if c.vers == VersionTLS13 { + m = new(newSessionTicketMsgTLS13) + } else { + m = new(newSessionTicketMsg) + } + case typeCertificate: + if c.vers == VersionTLS13 { + m = new(certificateMsgTLS13) + } else { + m = new(certificateMsg) + } + case typeCertificateRequest: + if c.vers == VersionTLS13 { + m = new(certificateRequestMsgTLS13) + } else { + m = &certificateRequestMsg{ + hasSignatureAlgorithm: c.vers >= VersionTLS12, + } + } + case typeCertificateStatus: + m = new(certificateStatusMsg) + case typeServerKeyExchange: + m = new(serverKeyExchangeMsg) + case typeServerHelloDone: + m = new(serverHelloDoneMsg) + case typeClientKeyExchange: + m = new(clientKeyExchangeMsg) + case typeCertificateVerify: + m = &certificateVerifyMsg{ + hasSignatureAlgorithm: c.vers >= VersionTLS12, + } + case typeNextProtocol: + m = new(nextProtoMsg) + case typeFinished: + m = new(finishedMsg) + case typeEncryptedExtensions: + m = new(encryptedExtensionsMsg) + case typeEndOfEarlyData: + m = new(endOfEarlyDataMsg) + case typeKeyUpdate: + m = new(keyUpdateMsg) + default: + return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + + // The handshake message unmarshalers + // expect to be able to keep references to data, + // so pass in a fresh copy that won't be overwritten. + data = append([]byte(nil), data...) + + if !m.unmarshal(data) { + return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) + } + return m, nil +} + +var ( + errClosed = errors.New("tls: use of closed connection") + errShutdown = errors.New("tls: protocol is shutdown") +) + +// Write writes data to the connection. +func (c *Conn) Write(b []byte) (int, error) { + // interlock with Close below + for { + x := atomic.LoadInt32(&c.activeCall) + if x&1 != 0 { + return 0, errClosed + } + if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) { + defer atomic.AddInt32(&c.activeCall, -2) + break + } + } + + if err := c.Handshake(); err != nil { + return 0, err + } + + c.out.Lock() + defer c.out.Unlock() + + if err := c.out.err; err != nil { + return 0, err + } + + if !c.handshakeComplete() { + return 0, alertInternalError + } + + if c.closeNotifySent { + return 0, errShutdown + } + + // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext + // attack when using block mode ciphers due to predictable IVs. + // This can be prevented by splitting each Application Data + // record into two records, effectively randomizing the IV. + // + // https://www.openssl.org/~bodo/tls-cbc.txt + // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 + // https://www.imperialviolet.org/2012/01/15/beastfollowup.html + + var m int + if len(b) > 1 && c.vers <= VersionTLS10 { + if _, ok := c.out.cipher.(cipher.BlockMode); ok { + n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) + if err != nil { + return n, c.out.setErrorLocked(err) + } + m, b = 1, b[1:] + } + } + + n, err := c.writeRecordLocked(recordTypeApplicationData, b) + return n + m, c.out.setErrorLocked(err) +} + +// handleRenegotiation processes a HelloRequest handshake message. +func (c *Conn) handleRenegotiation() error { + if c.vers == VersionTLS13 { + return errors.New("tls: internal error: unexpected renegotiation") + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + helloReq, ok := msg.(*helloRequestMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(helloReq, msg) + } + + if !c.isClient { + return c.sendAlert(alertNoRenegotiation) + } + + switch c.config.Renegotiation { + case RenegotiateNever: + return c.sendAlert(alertNoRenegotiation) + case RenegotiateOnceAsClient: + if c.handshakes > 1 { + return c.sendAlert(alertNoRenegotiation) + } + case RenegotiateFreelyAsClient: + // Ok. + default: + c.sendAlert(alertInternalError) + return errors.New("tls: unknown Renegotiation value") + } + + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + + atomic.StoreUint32(&c.handshakeStatus, 0) + if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil { + c.handshakes++ + } + return c.handshakeErr +} + +func (c *Conn) HandlePostHandshakeMessage() error { + return c.handlePostHandshakeMessage() +} + +// handlePostHandshakeMessage processes a handshake message arrived after the +// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation. +func (c *Conn) handlePostHandshakeMessage() error { + if c.vers != VersionTLS13 { + return c.handleRenegotiation() + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + c.retryCount++ + if c.retryCount > maxUselessRecords { + c.sendAlert(alertUnexpectedMessage) + return c.in.setErrorLocked(errors.New("tls: too many non-advancing records")) + } + + switch msg := msg.(type) { + case *newSessionTicketMsgTLS13: + return c.handleNewSessionTicket(msg) + case *keyUpdateMsg: + return c.handleKeyUpdate(msg) + default: + c.sendAlert(alertUnexpectedMessage) + return fmt.Errorf("tls: received unexpected handshake message of type %T", msg) + } +} + +func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error { + cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) + if cipherSuite == nil { + return c.in.setErrorLocked(c.sendAlert(alertInternalError)) + } + + newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret) + c.in.setTrafficSecret(cipherSuite, newSecret) + + if keyUpdate.updateRequested { + c.out.Lock() + defer c.out.Unlock() + + msg := &keyUpdateMsg{} + _, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal()) + if err != nil { + // Surface the error at the next write. + c.out.setErrorLocked(err) + return nil + } + + newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret) + c.out.setTrafficSecret(cipherSuite, newSecret) + } + + return nil +} + +// Read can be made to time out and return a net.Error with Timeout() == true +// after a fixed time limit; see SetDeadline and SetReadDeadline. +func (c *Conn) Read(b []byte) (int, error) { + if err := c.Handshake(); err != nil { + return 0, err + } + if len(b) == 0 { + // Put this after Handshake, in case people were calling + // Read(nil) for the side effect of the Handshake. + return 0, nil + } + + c.in.Lock() + defer c.in.Unlock() + + for c.input.Len() == 0 { + if err := c.readRecord(); err != nil { + return 0, err + } + for c.hand.Len() > 0 { + if err := c.handlePostHandshakeMessage(); err != nil { + return 0, err + } + } + } + + n, _ := c.input.Read(b) + + // If a close-notify alert is waiting, read it so that we can return (n, + // EOF) instead of (n, nil), to signal to the HTTP response reading + // goroutine that the connection is now closed. This eliminates a race + // where the HTTP response reading goroutine would otherwise not observe + // the EOF until its next read, by which time a client goroutine might + // have already tried to reuse the HTTP connection for a new request. + // See https://golang.org/cl/76400046 and https://golang.org/issue/3514 + if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 && + recordType(c.rawInput.Bytes()[0]) == recordTypeAlert { + if err := c.readRecord(); err != nil { + return n, err // will be io.EOF on closeNotify + } + } + + return n, nil +} + +// Close closes the connection. +func (c *Conn) Close() error { + // Interlock with Conn.Write above. + var x int32 + for { + x = atomic.LoadInt32(&c.activeCall) + if x&1 != 0 { + return errClosed + } + if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) { + break + } + } + if x != 0 { + // io.Writer and io.Closer should not be used concurrently. + // If Close is called while a Write is currently in-flight, + // interpret that as a sign that this Close is really just + // being used to break the Write and/or clean up resources and + // avoid sending the alertCloseNotify, which may block + // waiting on handshakeMutex or the c.out mutex. + return c.conn.Close() + } + + var alertErr error + + if c.handshakeComplete() { + alertErr = c.closeNotify() + } + + if err := c.conn.Close(); err != nil { + return err + } + return alertErr +} + +var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete") + +// CloseWrite shuts down the writing side of the connection. It should only be +// called once the handshake has completed and does not call CloseWrite on the +// underlying connection. Most callers should just use Close. +func (c *Conn) CloseWrite() error { + if !c.handshakeComplete() { + return errEarlyCloseWrite + } + + return c.closeNotify() +} + +func (c *Conn) closeNotify() error { + c.out.Lock() + defer c.out.Unlock() + + if !c.closeNotifySent { + c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify) + c.closeNotifySent = true + } + return c.closeNotifyErr +} + +// Handshake runs the client or server handshake +// protocol if it has not yet been run. +// Most uses of this package need not call Handshake +// explicitly: the first Read or Write will call it automatically. +func (c *Conn) Handshake() error { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + + if err := c.handshakeErr; err != nil { + return err + } + if c.handshakeComplete() { + return nil + } + + c.in.Lock() + defer c.in.Unlock() + + if c.isClient { + c.handshakeErr = c.clientHandshake() + } else { + c.handshakeErr = c.serverHandshake() + } + if c.handshakeErr == nil { + c.handshakes++ + } else { + // If an error occurred during the hadshake try to flush the + // alert that might be left in the buffer. + c.flush() + } + + if c.handshakeErr == nil && !c.handshakeComplete() { + c.handshakeErr = errors.New("tls: internal error: handshake should have had a result") + } + + return c.handshakeErr +} + +// ConnectionState returns basic TLS details about the connection. +func (c *Conn) ConnectionState() ConnectionState { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + + var state ConnectionState + state.HandshakeComplete = c.handshakeComplete() + state.ServerName = c.serverName + + if state.HandshakeComplete { + state.Version = c.vers + state.NegotiatedProtocol = c.clientProtocol + state.DidResume = c.didResume + state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback + state.CipherSuite = c.cipherSuite + state.PeerCertificates = c.peerCertificates + state.VerifiedChains = c.verifiedChains + state.SignedCertificateTimestamps = c.scts + state.OCSPResponse = c.ocspResponse + if !c.didResume && c.vers != VersionTLS13 { + if c.clientFinishedIsFirst { + state.TLSUnique = c.clientFinished[:] + } else { + state.TLSUnique = c.serverFinished[:] + } + } + if c.config.Renegotiation != RenegotiateNever { + state.ekm = noExportedKeyingMaterial + } else { + state.ekm = c.ekm + } + } + + return state +} + +// OCSPResponse returns the stapled OCSP response from the TLS server, if +// any. (Only valid for client connections.) +func (c *Conn) OCSPResponse() []byte { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + + return c.ocspResponse +} + +// VerifyHostname checks that the peer certificate chain is valid for +// connecting to host. If so, it returns nil; if not, it returns an error +// describing the problem. +func (c *Conn) VerifyHostname(host string) error { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + if !c.isClient { + return errors.New("tls: VerifyHostname called on TLS server connection") + } + if !c.handshakeComplete() { + return errors.New("tls: handshake has not yet been performed") + } + if len(c.verifiedChains) == 0 { + return errors.New("tls: handshake did not verify certificate chain") + } + return c.peerCertificates[0].VerifyHostname(host) +} + +func (c *Conn) handshakeComplete() bool { + return atomic.LoadUint32(&c.handshakeStatus) == 1 +} diff --git a/vendor/github.com/marten-seemann/qtls/generate_cert.go b/vendor/github.com/marten-seemann/qtls/generate_cert.go new file mode 100644 index 00000000..8d012be7 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/generate_cert.go @@ -0,0 +1,169 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'cert.pem' and 'key.pem' and will overwrite existing files. + +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "flag" + "fmt" + "log" + "math/big" + "net" + "os" + "strings" + "time" +) + +var ( + host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") + validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") + validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") + isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") + rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") + ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521") +) + +func publicKey(priv interface{}) interface{} { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + default: + return nil + } +} + +func pemBlockForKey(priv interface{}) *pem.Block { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} + case *ecdsa.PrivateKey: + b, err := x509.MarshalECPrivateKey(k) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) + os.Exit(2) + } + return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} + default: + return nil + } +} + +func main() { + flag.Parse() + + if len(*host) == 0 { + log.Fatalf("Missing required --host parameter") + } + + var priv interface{} + var err error + switch *ecdsaCurve { + case "": + priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + default: + fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve) + os.Exit(1) + } + if err != nil { + log.Fatalf("failed to generate private key: %s", err) + } + + var notBefore time.Time + if len(*validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) + os.Exit(1) + } + } + + notAfter := notBefore.Add(*validFor) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Acme Co"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(*host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + if *isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalf("Failed to create certificate: %s", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("failed to open cert.pem for writing: %s", err) + } + if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { + log.Fatalf("failed to write data to cert.pem: %s", err) + } + if err := certOut.Close(); err != nil { + log.Fatalf("error closing cert.pem: %s", err) + } + log.Print("wrote cert.pem\n") + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Print("failed to open key.pem for writing:", err) + return + } + if err := pem.Encode(keyOut, pemBlockForKey(priv)); err != nil { + log.Fatalf("failed to write data to key.pem: %s", err) + } + if err := keyOut.Close(); err != nil { + log.Fatalf("error closing key.pem: %s", err) + } + log.Print("wrote key.pem\n") +} diff --git a/vendor/github.com/marten-seemann/qtls/go.mod b/vendor/github.com/marten-seemann/qtls/go.mod new file mode 100644 index 00000000..9cd2ced5 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/go.mod @@ -0,0 +1,8 @@ +module github.com/marten-seemann/qtls + +go 1.12 + +require ( + golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 + golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e +) diff --git a/vendor/github.com/marten-seemann/qtls/go.sum b/vendor/github.com/marten-seemann/qtls/go.sum new file mode 100644 index 00000000..a47aabd2 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/go.sum @@ -0,0 +1,5 @@ +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/marten-seemann/qtls/handshake_client.go b/vendor/github.com/marten-seemann/qtls/handshake_client.go new file mode 100644 index 00000000..1d2903d5 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/handshake_client.go @@ -0,0 +1,1023 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/subtle" + "crypto/x509" + "errors" + "fmt" + "io" + "net" + "strconv" + "strings" + "sync/atomic" + "time" +) + +type clientHandshakeState struct { + c *Conn + serverHello *serverHelloMsg + hello *clientHelloMsg + suite *cipherSuite + finishedHash finishedHash + masterSecret []byte + session *ClientSessionState +} + +func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { + config := c.config + if len(config.ServerName) == 0 && !config.InsecureSkipVerify { + return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") + } + + nextProtosLength := 0 + for _, proto := range config.NextProtos { + if l := len(proto); l == 0 || l > 255 { + return nil, nil, errors.New("tls: invalid NextProtos value") + } else { + nextProtosLength += 1 + l + } + } + if nextProtosLength > 0xffff { + return nil, nil, errors.New("tls: NextProtos values too large") + } + + supportedVersions := config.supportedVersions(true) + if len(supportedVersions) == 0 { + return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion") + } + + clientHelloVersion := supportedVersions[0] + // The version at the beginning of the ClientHello was capped at TLS 1.2 + // for compatibility reasons. The supported_versions extension is used + // to negotiate versions now. See RFC 8446, Section 4.2.1. + if clientHelloVersion > VersionTLS12 { + clientHelloVersion = VersionTLS12 + } + + hello := &clientHelloMsg{ + vers: clientHelloVersion, + compressionMethods: []uint8{compressionNone}, + random: make([]byte, 32), + sessionId: make([]byte, 32), + ocspStapling: true, + scts: true, + serverName: hostnameInSNI(config.ServerName), + supportedCurves: config.curvePreferences(), + supportedPoints: []uint8{pointFormatUncompressed}, + nextProtoNeg: len(config.NextProtos) > 0, + secureRenegotiationSupported: true, + alpnProtocols: config.NextProtos, + supportedVersions: supportedVersions, + } + + if c.handshakes > 0 { + hello.secureRenegotiation = c.clientFinished[:] + } + + possibleCipherSuites := config.cipherSuites() + hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) + +NextCipherSuite: + for _, suiteId := range possibleCipherSuites { + for _, suite := range cipherSuites { + if suite.id != suiteId { + continue + } + // Don't advertise TLS 1.2-only cipher suites unless + // we're attempting TLS 1.2. + if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { + continue + } + hello.cipherSuites = append(hello.cipherSuites, suiteId) + continue NextCipherSuite + } + } + + _, err := io.ReadFull(config.rand(), hello.random) + if err != nil { + return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) + } + + // A random session ID is used to detect when the server accepted a ticket + // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as + // a compatibility measure (see RFC 8446, Section 4.1.2). + if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil { + return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) + } + + if hello.vers >= VersionTLS12 { + hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms + } + + var params ecdheParameters + if hello.supportedVersions[0] == VersionTLS13 { + hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13()...) + + curveID := config.curvePreferences()[0] + if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { + return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve") + } + params, err = generateECDHEParameters(config.rand(), curveID) + if err != nil { + return nil, nil, err + } + hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} + } + + if hello.supportedVersions[0] == VersionTLS13 && config.GetExtensions != nil { + hello.additionalExtensions = config.GetExtensions(typeClientHello) + } + + return hello, params, nil +} + +func (c *Conn) clientHandshake() (err error) { + if c.config == nil { + c.config = defaultConfig() + } + c.setAlternativeRecordLayer() + + // This may be a renegotiation handshake, in which case some fields + // need to be reset. + c.didResume = false + + hello, ecdheParams, err := c.makeClientHello() + if err != nil { + return err + } + + cacheKey, session, earlySecret, binderKey := c.loadSession(hello) + if cacheKey != "" && session != nil { + defer func() { + // If we got a handshake failure when resuming a session, throw away + // the session ticket. See RFC 5077, Section 3.2. + // + // RFC 8446 makes no mention of dropping tickets on failure, but it + // does require servers to abort on invalid binders, so we need to + // delete tickets to recover from a corrupted PSK. + if err != nil { + c.config.ClientSessionCache.Put(cacheKey, nil) + } + }() + } + + if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil { + return err + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + serverHello, ok := msg.(*serverHelloMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(serverHello, msg) + } + + if err := c.pickTLSVersion(serverHello); err != nil { + return err + } + + if c.vers == VersionTLS13 { + hs := &clientHandshakeStateTLS13{ + c: c, + serverHello: serverHello, + hello: hello, + ecdheParams: ecdheParams, + session: session, + earlySecret: earlySecret, + binderKey: binderKey, + } + + // In TLS 1.3, session tickets are delivered after the handshake. + return hs.handshake() + } + + hs := &clientHandshakeState{ + c: c, + serverHello: serverHello, + hello: hello, + session: session, + } + + if err := hs.handshake(); err != nil { + return err + } + + // If we had a successful handshake and hs.session is different from + // the one already cached - cache a new one. + if cacheKey != "" && hs.session != nil && session != hs.session { + c.config.ClientSessionCache.Put(cacheKey, hs.session) + } + + return nil +} + +func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, + session *ClientSessionState, earlySecret, binderKey []byte) { + if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { + return "", nil, nil, nil + } + + hello.ticketSupported = true + + if hello.supportedVersions[0] == VersionTLS13 { + // Require DHE on resumption as it guarantees forward secrecy against + // compromise of the session ticket key. See RFC 8446, Section 4.2.9. + hello.pskModes = []uint8{pskModeDHE} + } + + // Session resumption is not allowed if renegotiating because + // renegotiation is primarily used to allow a client to send a client + // certificate, which would be skipped if session resumption occurred. + if c.handshakes != 0 { + return "", nil, nil, nil + } + + // Try to resume a previously negotiated TLS session, if available. + cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) + session, ok := c.config.ClientSessionCache.Get(cacheKey) + if !ok || session == nil { + return cacheKey, nil, nil, nil + } + + // Check that version used for the previous session is still valid. + versOk := false + for _, v := range hello.supportedVersions { + if v == session.vers { + versOk = true + break + } + } + if !versOk { + return cacheKey, nil, nil, nil + } + + // Check that the cached server certificate is not expired, and that it's + // valid for the ServerName. This should be ensured by the cache key, but + // protect the application from a faulty ClientSessionCache implementation. + if !c.config.InsecureSkipVerify { + if len(session.verifiedChains) == 0 { + // The original connection had InsecureSkipVerify, while this doesn't. + return cacheKey, nil, nil, nil + } + serverCert := session.serverCertificates[0] + if c.config.time().After(serverCert.NotAfter) { + // Expired certificate, delete the entry. + c.config.ClientSessionCache.Put(cacheKey, nil) + return cacheKey, nil, nil, nil + } + if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { + return cacheKey, nil, nil, nil + } + } + + if session.vers != VersionTLS13 { + // In TLS 1.2 the cipher suite must match the resumed session. Ensure we + // are still offering it. + if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil { + return cacheKey, nil, nil, nil + } + + hello.sessionTicket = session.sessionTicket + return + } + + // Check that the session ticket is not expired. + if c.config.time().After(session.useBy) { + c.config.ClientSessionCache.Put(cacheKey, nil) + return cacheKey, nil, nil, nil + } + + // In TLS 1.3 the KDF hash must match the resumed session. Ensure we + // offer at least one cipher suite with that hash. + cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite) + if cipherSuite == nil { + return cacheKey, nil, nil, nil + } + cipherSuiteOk := false + for _, offeredID := range hello.cipherSuites { + offeredSuite := cipherSuiteTLS13ByID(offeredID) + if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash { + cipherSuiteOk = true + break + } + } + if !cipherSuiteOk { + return cacheKey, nil, nil, nil + } + + // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1. + ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond) + identity := pskIdentity{ + label: session.sessionTicket, + obfuscatedTicketAge: ticketAge + session.ageAdd, + } + hello.pskIdentities = []pskIdentity{identity} + hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())} + + // Compute the PSK binders. See RFC 8446, Section 4.2.11.2. + psk := cipherSuite.expandLabel(session.masterSecret, "resumption", + session.nonce, cipherSuite.hash.Size()) + earlySecret = cipherSuite.extract(psk, nil) + binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil) + transcript := cipherSuite.hash.New() + transcript.Write(hello.marshalWithoutBinders()) + pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)} + hello.updateBinders(pskBinders) + + return +} + +func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error { + peerVersion := serverHello.vers + if serverHello.supportedVersion != 0 { + peerVersion = serverHello.supportedVersion + } + + vers, ok := c.config.mutualVersion(true, []uint16{peerVersion}) + if !ok { + c.sendAlert(alertProtocolVersion) + return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion) + } + + c.vers = vers + c.haveVers = true + c.in.version = vers + c.out.version = vers + + return nil +} + +// Does the handshake, either a full one or resumes old session. Requires hs.c, +// hs.hello, hs.serverHello, and, optionally, hs.session to be set. +func (hs *clientHandshakeState) handshake() error { + c := hs.c + + isResume, err := hs.processServerHello() + if err != nil { + return err + } + + hs.finishedHash = newFinishedHash(c.vers, hs.suite) + + // No signatures of the handshake are needed in a resumption. + // Otherwise, in a full handshake, if we don't have any certificates + // configured then we will never send a CertificateVerify message and + // thus no signatures are needed in that case either. + if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { + hs.finishedHash.discardHandshakeBuffer() + } + + hs.finishedHash.Write(hs.hello.marshal()) + hs.finishedHash.Write(hs.serverHello.marshal()) + + c.buffering = true + if isResume { + if err := hs.establishKeys(); err != nil { + return err + } + if err := hs.readSessionTicket(); err != nil { + return err + } + if err := hs.readFinished(c.serverFinished[:]); err != nil { + return err + } + c.clientFinishedIsFirst = false + if err := hs.sendFinished(c.clientFinished[:]); err != nil { + return err + } + if _, err := c.flush(); err != nil { + return err + } + } else { + if err := hs.doFullHandshake(); err != nil { + return err + } + if err := hs.establishKeys(); err != nil { + return err + } + if err := hs.sendFinished(c.clientFinished[:]); err != nil { + return err + } + if _, err := c.flush(); err != nil { + return err + } + c.clientFinishedIsFirst = true + if err := hs.readSessionTicket(); err != nil { + return err + } + if err := hs.readFinished(c.serverFinished[:]); err != nil { + return err + } + } + + c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random) + c.didResume = isResume + atomic.StoreUint32(&c.handshakeStatus, 1) + + return nil +} + +func (hs *clientHandshakeState) pickCipherSuite() error { + if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil { + hs.c.sendAlert(alertHandshakeFailure) + return errors.New("tls: server chose an unconfigured cipher suite") + } + + hs.c.cipherSuite = hs.suite.id + return nil +} + +func (hs *clientHandshakeState) doFullHandshake() error { + c := hs.c + + msg, err := c.readHandshake() + if err != nil { + return err + } + certMsg, ok := msg.(*certificateMsg) + if !ok || len(certMsg.certificates) == 0 { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } + hs.finishedHash.Write(certMsg.marshal()) + + if c.handshakes == 0 { + // If this is the first handshake on a connection, process and + // (optionally) verify the server's certificates. + if err := c.verifyServerCertificate(certMsg.certificates); err != nil { + return err + } + } else { + // This is a renegotiation handshake. We require that the + // server's identity (i.e. leaf certificate) is unchanged and + // thus any previous trust decision is still valid. + // + // See https://mitls.org/pages/attacks/3SHAKE for the + // motivation behind this requirement. + if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { + c.sendAlert(alertBadCertificate) + return errors.New("tls: server's identity changed during renegotiation") + } + } + + msg, err = c.readHandshake() + if err != nil { + return err + } + + cs, ok := msg.(*certificateStatusMsg) + if ok { + // RFC4366 on Certificate Status Request: + // The server MAY return a "certificate_status" message. + + if !hs.serverHello.ocspStapling { + // If a server returns a "CertificateStatus" message, then the + // server MUST have included an extension of type "status_request" + // with empty "extension_data" in the extended server hello. + + c.sendAlert(alertUnexpectedMessage) + return errors.New("tls: received unexpected CertificateStatus message") + } + hs.finishedHash.Write(cs.marshal()) + + c.ocspResponse = cs.response + + msg, err = c.readHandshake() + if err != nil { + return err + } + } + + keyAgreement := hs.suite.ka(c.vers) + + skx, ok := msg.(*serverKeyExchangeMsg) + if ok { + hs.finishedHash.Write(skx.marshal()) + err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) + if err != nil { + c.sendAlert(alertUnexpectedMessage) + return err + } + + msg, err = c.readHandshake() + if err != nil { + return err + } + } + + var chainToSend *Certificate + var certRequested bool + certReq, ok := msg.(*certificateRequestMsg) + if ok { + certRequested = true + hs.finishedHash.Write(certReq.marshal()) + + cri := certificateRequestInfoFromMsg(certReq) + if chainToSend, err = c.getClientCertificate(cri); err != nil { + c.sendAlert(alertInternalError) + return err + } + + msg, err = c.readHandshake() + if err != nil { + return err + } + } + + shd, ok := msg.(*serverHelloDoneMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(shd, msg) + } + hs.finishedHash.Write(shd.marshal()) + + // If the server requested a certificate then we have to send a + // Certificate message, even if it's empty because we don't have a + // certificate to send. + if certRequested { + certMsg = new(certificateMsg) + certMsg.certificates = chainToSend.Certificate + hs.finishedHash.Write(certMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { + return err + } + } + + preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0]) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + if ckx != nil { + hs.finishedHash.Write(ckx.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { + return err + } + } + + if chainToSend != nil && len(chainToSend.Certificate) > 0 { + certVerify := &certificateVerifyMsg{ + hasSignatureAlgorithm: c.vers >= VersionTLS12, + } + + key, ok := chainToSend.PrivateKey.(crypto.Signer) + if !ok { + c.sendAlert(alertInternalError) + return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) + } + + signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + // SignatureAndHashAlgorithm was introduced in TLS 1.2. + if certVerify.hasSignatureAlgorithm { + certVerify.signatureAlgorithm = signatureAlgorithm + } + digest, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + signOpts := crypto.SignerOpts(hashFunc) + if sigType == signatureRSAPSS { + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc} + } + certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + hs.finishedHash.Write(certVerify.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { + return err + } + } + + hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) + if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil { + c.sendAlert(alertInternalError) + return errors.New("tls: failed to write to key log: " + err.Error()) + } + + hs.finishedHash.discardHandshakeBuffer() + + return nil +} + +func (hs *clientHandshakeState) establishKeys() error { + c := hs.c + + clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) + var clientCipher, serverCipher interface{} + var clientHash, serverHash macFunction + if hs.suite.cipher != nil { + clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) + clientHash = hs.suite.mac(c.vers, clientMAC) + serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) + serverHash = hs.suite.mac(c.vers, serverMAC) + } else { + clientCipher = hs.suite.aead(clientKey, clientIV) + serverCipher = hs.suite.aead(serverKey, serverIV) + } + + c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) + c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) + return nil +} + +func (hs *clientHandshakeState) serverResumedSession() bool { + // If the server responded with the same sessionId then it means the + // sessionTicket is being used to resume a TLS session. + return hs.session != nil && hs.hello.sessionId != nil && + bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) +} + +func (hs *clientHandshakeState) processServerHello() (bool, error) { + c := hs.c + + if err := hs.pickCipherSuite(); err != nil { + return false, err + } + + if hs.serverHello.compressionMethod != compressionNone { + c.sendAlert(alertUnexpectedMessage) + return false, errors.New("tls: server selected unsupported compression format") + } + + if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { + c.secureRenegotiation = true + if len(hs.serverHello.secureRenegotiation) != 0 { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: initial handshake had non-empty renegotiation extension") + } + } + + if c.handshakes > 0 && c.secureRenegotiation { + var expectedSecureRenegotiation [24]byte + copy(expectedSecureRenegotiation[:], c.clientFinished[:]) + copy(expectedSecureRenegotiation[12:], c.serverFinished[:]) + if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: incorrect renegotiation extension contents") + } + } + + clientDidNPN := hs.hello.nextProtoNeg + clientDidALPN := len(hs.hello.alpnProtocols) > 0 + serverHasNPN := hs.serverHello.nextProtoNeg + serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 + + if !clientDidNPN && serverHasNPN { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server advertised unrequested NPN extension") + } + + if !clientDidALPN && serverHasALPN { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server advertised unrequested ALPN extension") + } + + if serverHasNPN && serverHasALPN { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server advertised both NPN and ALPN extensions") + } + + if serverHasALPN { + c.clientProtocol = hs.serverHello.alpnProtocol + c.clientProtocolFallback = false + } + c.scts = hs.serverHello.scts + + if !hs.serverResumedSession() { + return false, nil + } + + if hs.session.vers != c.vers { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server resumed a session with a different version") + } + + if hs.session.cipherSuite != hs.suite.id { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server resumed a session with a different cipher suite") + } + + // Restore masterSecret and peerCerts from previous state + hs.masterSecret = hs.session.masterSecret + c.peerCertificates = hs.session.serverCertificates + c.verifiedChains = hs.session.verifiedChains + return true, nil +} + +func (hs *clientHandshakeState) readFinished(out []byte) error { + c := hs.c + + if err := c.readChangeCipherSpec(); err != nil { + return err + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + serverFinished, ok := msg.(*finishedMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(serverFinished, msg) + } + + verify := hs.finishedHash.serverSum(hs.masterSecret) + if len(verify) != len(serverFinished.verifyData) || + subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: server's Finished message was incorrect") + } + hs.finishedHash.Write(serverFinished.marshal()) + copy(out, verify) + return nil +} + +func (hs *clientHandshakeState) readSessionTicket() error { + if !hs.serverHello.ticketSupported { + return nil + } + + c := hs.c + msg, err := c.readHandshake() + if err != nil { + return err + } + sessionTicketMsg, ok := msg.(*newSessionTicketMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(sessionTicketMsg, msg) + } + hs.finishedHash.Write(sessionTicketMsg.marshal()) + + hs.session = &ClientSessionState{ + sessionTicket: sessionTicketMsg.ticket, + vers: c.vers, + cipherSuite: hs.suite.id, + masterSecret: hs.masterSecret, + serverCertificates: c.peerCertificates, + verifiedChains: c.verifiedChains, + receivedAt: c.config.time(), + } + + return nil +} + +func (hs *clientHandshakeState) sendFinished(out []byte) error { + c := hs.c + + if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { + return err + } + if hs.serverHello.nextProtoNeg { + nextProto := new(nextProtoMsg) + proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos) + nextProto.proto = proto + c.clientProtocol = proto + c.clientProtocolFallback = fallback + + hs.finishedHash.Write(nextProto.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil { + return err + } + } + + finished := new(finishedMsg) + finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) + hs.finishedHash.Write(finished.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { + return err + } + copy(out, finished.verifyData) + return nil +} + +// verifyServerCertificate parses and verifies the provided chain, setting +// c.verifiedChains and c.peerCertificates or sending the appropriate alert. +func (c *Conn) verifyServerCertificate(certificates [][]byte) error { + certs := make([]*x509.Certificate, len(certificates)) + for i, asn1Data := range certificates { + cert, err := x509.ParseCertificate(asn1Data) + if err != nil { + c.sendAlert(alertBadCertificate) + return errors.New("tls: failed to parse certificate from server: " + err.Error()) + } + certs[i] = cert + } + + if !c.config.InsecureSkipVerify { + opts := x509.VerifyOptions{ + Roots: c.config.RootCAs, + CurrentTime: c.config.time(), + DNSName: c.config.ServerName, + Intermediates: x509.NewCertPool(), + } + + for i, cert := range certs { + if i == 0 { + continue + } + opts.Intermediates.AddCert(cert) + } + var err error + c.verifiedChains, err = certs[0].Verify(opts) + if err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + + if c.config.VerifyPeerCertificate != nil { + if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + + switch certs[0].PublicKey.(type) { + case *rsa.PublicKey, *ecdsa.PublicKey: + break + default: + c.sendAlert(alertUnsupportedCertificate) + return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) + } + + c.peerCertificates = certs + + return nil +} + +// tls11SignatureSchemes contains the signature schemes that we synthesise for +// a TLS <= 1.1 connection, based on the supported certificate types. +var ( + tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1} + tls11SignatureSchemesECDSA = tls11SignatureSchemes[:3] + tls11SignatureSchemesRSA = tls11SignatureSchemes[3:] +) + +// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS +// <= 1.2 CertificateRequest, making an effort to fill in missing information. +func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateRequestInfo { + var rsaAvail, ecdsaAvail bool + for _, certType := range certReq.certificateTypes { + switch certType { + case certTypeRSASign: + rsaAvail = true + case certTypeECDSASign: + ecdsaAvail = true + } + } + + cri := &CertificateRequestInfo{ + AcceptableCAs: certReq.certificateAuthorities, + } + + if !certReq.hasSignatureAlgorithm { + // Prior to TLS 1.2, the signature schemes were not + // included in the certificate request message. In this + // case we use a plausible list based on the acceptable + // certificate types. + switch { + case rsaAvail && ecdsaAvail: + cri.SignatureSchemes = tls11SignatureSchemes + case rsaAvail: + cri.SignatureSchemes = tls11SignatureSchemesRSA + case ecdsaAvail: + cri.SignatureSchemes = tls11SignatureSchemesECDSA + } + return cri + } + + // In TLS 1.2, the signature schemes apply to both the certificate chain and + // the leaf key, while the certificate types only apply to the leaf key. + // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated"). + // Filter the signature schemes based on the certificate type. + cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms)) + for _, sigScheme := range certReq.supportedSignatureAlgorithms { + switch signatureFromSignatureScheme(sigScheme) { + case signatureECDSA: + if ecdsaAvail { + cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) + } + case signatureRSAPSS, signaturePKCS1v15: + if rsaAvail { + cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) + } + } + } + + return cri +} + +func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) { + if c.config.GetClientCertificate != nil { + return c.config.GetClientCertificate(cri) + } + + // We need to search our list of client certs for one + // where SignatureAlgorithm is acceptable to the server and the + // Issuer is in AcceptableCAs. + for i, chain := range c.config.Certificates { + sigOK := false + for _, alg := range signatureSchemesForCertificate(c.vers, &chain) { + if isSupportedSignatureAlgorithm(alg, cri.SignatureSchemes) { + sigOK = true + break + } + } + if !sigOK { + continue + } + + if len(cri.AcceptableCAs) == 0 { + return &chain, nil + } + + for j, cert := range chain.Certificate { + x509Cert := chain.Leaf + // Parse the certificate if this isn't the leaf node, or if + // chain.Leaf was nil. + if j != 0 || x509Cert == nil { + var err error + if x509Cert, err = x509.ParseCertificate(cert); err != nil { + c.sendAlert(alertInternalError) + return nil, errors.New("tls: failed to parse configured certificate chain #" + strconv.Itoa(i) + ": " + err.Error()) + } + } + + for _, ca := range cri.AcceptableCAs { + if bytes.Equal(x509Cert.RawIssuer, ca) { + return &chain, nil + } + } + } + } + + // No acceptable certificate found. Don't send a certificate. + return new(Certificate), nil +} + +// clientSessionCacheKey returns a key used to cache sessionTickets that could +// be used to resume previously negotiated TLS sessions with a server. +func clientSessionCacheKey(serverAddr net.Addr, config *Config) string { + if len(config.ServerName) > 0 { + return config.ServerName + } + return serverAddr.String() +} + +// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol +// given list of possible protocols and a list of the preference order. The +// first list must not be empty. It returns the resulting protocol and flag +// indicating if the fallback case was reached. +func mutualProtocol(protos, preferenceProtos []string) (string, bool) { + for _, s := range preferenceProtos { + for _, c := range protos { + if s == c { + return s, false + } + } + } + + return protos[0], true +} + +// hostnameInSNI converts name into an approriate hostname for SNI. +// Literal IP addresses and absolute FQDNs are not permitted as SNI values. +// See RFC 6066, Section 3. +func hostnameInSNI(name string) string { + host := name + if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' { + host = host[1 : len(host)-1] + } + if i := strings.LastIndex(host, "%"); i > 0 { + host = host[:i] + } + if net.ParseIP(host) != nil { + return "" + } + for len(name) > 0 && name[len(name)-1] == '.' { + name = name[:len(name)-1] + } + return name +} diff --git a/vendor/github.com/marten-seemann/qtls/handshake_client_tls13.go b/vendor/github.com/marten-seemann/qtls/handshake_client_tls13.go new file mode 100644 index 00000000..f89830e0 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/handshake_client_tls13.go @@ -0,0 +1,692 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "bytes" + "crypto" + "crypto/hmac" + "crypto/rsa" + "errors" + "hash" + "sync/atomic" + "time" +) + +type clientHandshakeStateTLS13 struct { + c *Conn + serverHello *serverHelloMsg + hello *clientHelloMsg + ecdheParams ecdheParameters + + session *ClientSessionState + earlySecret []byte + binderKey []byte + + certReq *certificateRequestMsgTLS13 + usingPSK bool + sentDummyCCS bool + suite *cipherSuiteTLS13 + transcript hash.Hash + masterSecret []byte + trafficSecret []byte // client_application_traffic_secret_0 +} + +// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and, +// optionally, hs.session, hs.earlySecret and hs.binderKey to be set. +func (hs *clientHandshakeStateTLS13) handshake() error { + c := hs.c + + // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, + // sections 4.1.2 and 4.1.3. + if c.handshakes > 0 { + c.sendAlert(alertProtocolVersion) + return errors.New("tls: server selected TLS 1.3 in a renegotiation") + } + + // Consistency check on the presence of a keyShare and its parameters. + if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 { + return c.sendAlert(alertInternalError) + } + + if err := hs.checkServerHelloOrHRR(); err != nil { + return err + } + + hs.transcript = hs.suite.hash.New() + hs.transcript.Write(hs.hello.marshal()) + + if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { + if err := hs.sendDummyChangeCipherSpec(); err != nil { + return err + } + if err := hs.processHelloRetryRequest(); err != nil { + return err + } + } + + hs.transcript.Write(hs.serverHello.marshal()) + + c.buffering = true + if err := hs.processServerHello(); err != nil { + return err + } + if err := hs.sendDummyChangeCipherSpec(); err != nil { + return err + } + if err := hs.establishHandshakeKeys(); err != nil { + return err + } + if err := hs.readServerParameters(); err != nil { + return err + } + if err := hs.readServerCertificate(); err != nil { + return err + } + if err := hs.readServerFinished(); err != nil { + return err + } + if err := hs.sendClientCertificate(); err != nil { + return err + } + if err := hs.sendClientFinished(); err != nil { + return err + } + if _, err := c.flush(); err != nil { + return err + } + + atomic.StoreUint32(&c.handshakeStatus, 1) + + return nil +} + +// checkServerHelloOrHRR does validity checks that apply to both ServerHello and +// HelloRetryRequest messages. It sets hs.suite. +func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { + c := hs.c + + if hs.serverHello.supportedVersion == 0 { + c.sendAlert(alertMissingExtension) + return errors.New("tls: server selected TLS 1.3 using the legacy version field") + } + + if hs.serverHello.supportedVersion != VersionTLS13 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected an invalid version after a HelloRetryRequest") + } + + if hs.serverHello.vers != VersionTLS12 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server sent an incorrect legacy version") + } + + if hs.serverHello.nextProtoNeg || + len(hs.serverHello.nextProtos) != 0 || + hs.serverHello.ocspStapling || + hs.serverHello.ticketSupported || + hs.serverHello.secureRenegotiationSupported || + len(hs.serverHello.secureRenegotiation) != 0 || + len(hs.serverHello.alpnProtocol) != 0 || + len(hs.serverHello.scts) != 0 { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3") + } + + if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server did not echo the legacy session ID") + } + + if hs.serverHello.compressionMethod != compressionNone { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected unsupported compression format") + } + + selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) + if hs.suite != nil && selectedSuite != hs.suite { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server changed cipher suite after a HelloRetryRequest") + } + if selectedSuite == nil { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server chose an unconfigured cipher suite") + } + hs.suite = selectedSuite + c.cipherSuite = hs.suite.id + + return nil +} + +// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility +// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. +func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error { + if hs.sentDummyCCS { + return nil + } + hs.sentDummyCCS = true + + _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) + return err +} + +// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and +// resends hs.hello, and reads the new ServerHello into hs.serverHello. +func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { + c := hs.c + + // The first ClientHello gets double-hashed into the transcript upon a + // HelloRetryRequest. See RFC 8446, Section 4.4.1. + chHash := hs.transcript.Sum(nil) + hs.transcript.Reset() + hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) + hs.transcript.Write(chHash) + hs.transcript.Write(hs.serverHello.marshal()) + + if hs.serverHello.serverShare.group != 0 { + c.sendAlert(alertDecodeError) + return errors.New("tls: received malformed key_share extension") + } + + curveID := hs.serverHello.selectedGroup + if curveID == 0 { + c.sendAlert(alertMissingExtension) + return errors.New("tls: received HelloRetryRequest without selected group") + } + curveOK := false + for _, id := range hs.hello.supportedCurves { + if id == curveID { + curveOK = true + break + } + } + if !curveOK { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected unsupported group") + } + if hs.ecdheParams.CurveID() == curveID { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server sent an unnecessary HelloRetryRequest message") + } + if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { + c.sendAlert(alertInternalError) + return errors.New("tls: CurvePreferences includes unsupported curve") + } + params, err := generateECDHEParameters(c.config.rand(), curveID) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + hs.ecdheParams = params + hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} + + hs.hello.cookie = hs.serverHello.cookie + + hs.hello.raw = nil + if len(hs.hello.pskIdentities) > 0 { + pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) + if pskSuite == nil { + return c.sendAlert(alertInternalError) + } + if pskSuite.hash == hs.suite.hash { + // Update binders and obfuscated_ticket_age. + ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond) + hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd + + transcript := hs.suite.hash.New() + transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) + transcript.Write(chHash) + transcript.Write(hs.serverHello.marshal()) + transcript.Write(hs.hello.marshalWithoutBinders()) + pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} + hs.hello.updateBinders(pskBinders) + } else { + // Server selected a cipher suite incompatible with the PSK. + hs.hello.pskIdentities = nil + hs.hello.pskBinders = nil + } + } + + hs.transcript.Write(hs.hello.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { + return err + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + serverHello, ok := msg.(*serverHelloMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(serverHello, msg) + } + hs.serverHello = serverHello + + if err := hs.checkServerHelloOrHRR(); err != nil { + return err + } + + return nil +} + +func (hs *clientHandshakeStateTLS13) processServerHello() error { + c := hs.c + + if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { + c.sendAlert(alertUnexpectedMessage) + return errors.New("tls: server sent two HelloRetryRequest messages") + } + + if len(hs.serverHello.cookie) != 0 { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server sent a cookie in a normal ServerHello") + } + + if hs.serverHello.selectedGroup != 0 { + c.sendAlert(alertDecodeError) + return errors.New("tls: malformed key_share extension") + } + + if hs.serverHello.serverShare.group == 0 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server did not send a key share") + } + if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected unsupported group") + } + + if !hs.serverHello.selectedIdentityPresent { + return nil + } + + if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected an invalid PSK") + } + + if len(hs.hello.pskIdentities) != 1 || hs.session == nil { + return c.sendAlert(alertInternalError) + } + pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) + if pskSuite == nil { + return c.sendAlert(alertInternalError) + } + if pskSuite.hash != hs.suite.hash { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected an invalid PSK and cipher suite pair") + } + + hs.usingPSK = true + c.didResume = true + c.peerCertificates = hs.session.serverCertificates + c.verifiedChains = hs.session.verifiedChains + return nil +} + +func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error { + c := hs.c + + sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data) + if sharedKey == nil { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid server key share") + } + + earlySecret := hs.earlySecret + if !hs.usingPSK { + earlySecret = hs.suite.extract(nil, nil) + } + handshakeSecret := hs.suite.extract(sharedKey, + hs.suite.deriveSecret(earlySecret, "derived", nil)) + + clientSecret := hs.suite.deriveSecret(handshakeSecret, + clientHandshakeTrafficLabel, hs.transcript) + c.out.exportKey(hs.suite, clientSecret) + c.out.setTrafficSecret(hs.suite, clientSecret) + serverSecret := hs.suite.deriveSecret(handshakeSecret, + serverHandshakeTrafficLabel, hs.transcript) + c.in.exportKey(hs.suite, serverSecret) + c.in.setTrafficSecret(hs.suite, serverSecret) + + err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + hs.masterSecret = hs.suite.extract(nil, + hs.suite.deriveSecret(handshakeSecret, "derived", nil)) + + return nil +} + +func (hs *clientHandshakeStateTLS13) readServerParameters() error { + c := hs.c + + msg, err := c.readHandshake() + if err != nil { + return err + } + + encryptedExtensions, ok := msg.(*encryptedExtensionsMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(encryptedExtensions, msg) + } + if hs.c.config.ReceivedExtensions != nil { + hs.c.config.ReceivedExtensions(typeEncryptedExtensions, encryptedExtensions.additionalExtensions) + } + hs.transcript.Write(encryptedExtensions.marshal()) + + if len(encryptedExtensions.alpnProtocol) != 0 && len(hs.hello.alpnProtocols) == 0 { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server advertised unrequested ALPN extension") + } + if c.config.EnforceNextProtoSelection { + if len(encryptedExtensions.alpnProtocol) == 0 { + // the server didn't select an ALPN + c.sendAlert(alertNoApplicationProtocol) + return errors.New("ALPN negotiation failed") + } + if _, fallback := mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.c.config.NextProtos); fallback { + // the protocol selected by the server was not offered + c.sendAlert(alertNoApplicationProtocol) + return errors.New("ALPN negotiation failed") + } + } + c.clientProtocol = encryptedExtensions.alpnProtocol + + return nil +} + +func (hs *clientHandshakeStateTLS13) readServerCertificate() error { + c := hs.c + + // Either a PSK or a certificate is always used, but not both. + // See RFC 8446, Section 4.1.1. + if hs.usingPSK { + return nil + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + certReq, ok := msg.(*certificateRequestMsgTLS13) + if ok { + hs.transcript.Write(certReq.marshal()) + + hs.certReq = certReq + + msg, err = c.readHandshake() + if err != nil { + return err + } + } + + certMsg, ok := msg.(*certificateMsgTLS13) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } + if len(certMsg.certificate.Certificate) == 0 { + c.sendAlert(alertDecodeError) + return errors.New("tls: received empty certificates message") + } + hs.transcript.Write(certMsg.marshal()) + + c.scts = certMsg.certificate.SignedCertificateTimestamps + c.ocspResponse = certMsg.certificate.OCSPStaple + + if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil { + return err + } + + msg, err = c.readHandshake() + if err != nil { + return err + } + + certVerify, ok := msg.(*certificateVerifyMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certVerify, msg) + } + + // See RFC 8446, Section 4.4.3. + if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid certificate signature algorithm") + } + sigType := signatureFromSignatureScheme(certVerify.signatureAlgorithm) + sigHash, err := hashFromSignatureScheme(certVerify.signatureAlgorithm) + if sigType == 0 || err != nil { + c.sendAlert(alertInternalError) + return err + } + if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid certificate signature algorithm") + } + h := sigHash.New() + writeSignedMessage(h, serverSignatureContext, hs.transcript) + if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, + sigHash, h.Sum(nil), certVerify.signature); err != nil { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid certificate signature") + } + + hs.transcript.Write(certVerify.marshal()) + + return nil +} + +func (hs *clientHandshakeStateTLS13) readServerFinished() error { + c := hs.c + + msg, err := c.readHandshake() + if err != nil { + return err + } + + finished, ok := msg.(*finishedMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(finished, msg) + } + + expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) + if !hmac.Equal(expectedMAC, finished.verifyData) { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid server finished hash") + } + + hs.transcript.Write(finished.marshal()) + + // Derive secrets that take context through the server Finished. + + hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, + clientApplicationTrafficLabel, hs.transcript) + serverSecret := hs.suite.deriveSecret(hs.masterSecret, + serverApplicationTrafficLabel, hs.transcript) + c.in.exportKey(hs.suite, serverSecret) + c.in.setTrafficSecret(hs.suite, serverSecret) + + err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) + + return nil +} + +func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { + c := hs.c + + if hs.certReq == nil { + return nil + } + + cert, err := c.getClientCertificate(&CertificateRequestInfo{ + AcceptableCAs: hs.certReq.certificateAuthorities, + SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, + }) + if err != nil { + return err + } + + certMsg := new(certificateMsgTLS13) + + certMsg.certificate = *cert + certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 + certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 + + hs.transcript.Write(certMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { + return err + } + + // If we sent an empty certificate message, skip the CertificateVerify. + if len(cert.Certificate) == 0 { + return nil + } + + certVerifyMsg := new(certificateVerifyMsg) + certVerifyMsg.hasSignatureAlgorithm = true + + supportedAlgs := signatureSchemesForCertificate(c.vers, cert) + if supportedAlgs == nil { + c.sendAlert(alertInternalError) + return unsupportedCertificateError(cert) + } + // Pick signature scheme in server preference order, as the client + // preference order is not configurable. + for _, preferredAlg := range hs.certReq.supportedSignatureAlgorithms { + if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { + certVerifyMsg.signatureAlgorithm = preferredAlg + break + } + } + if certVerifyMsg.signatureAlgorithm == 0 { + // getClientCertificate returned a certificate incompatible with the + // CertificateRequestInfo supported signature algorithms. + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: server doesn't support selected certificate") + } + + sigType := signatureFromSignatureScheme(certVerifyMsg.signatureAlgorithm) + sigHash, err := hashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) + if sigType == 0 || err != nil { + return c.sendAlert(alertInternalError) + } + h := sigHash.New() + writeSignedMessage(h, clientSignatureContext, hs.transcript) + + signOpts := crypto.SignerOpts(sigHash) + if sigType == signatureRSAPSS { + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} + } + sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), h.Sum(nil), signOpts) + if err != nil { + c.sendAlert(alertInternalError) + return errors.New("tls: failed to sign handshake: " + err.Error()) + } + certVerifyMsg.signature = sig + + hs.transcript.Write(certVerifyMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { + return err + } + + return nil +} + +func (hs *clientHandshakeStateTLS13) sendClientFinished() error { + c := hs.c + + finished := &finishedMsg{ + verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), + } + + hs.transcript.Write(finished.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { + return err + } + + c.out.exportKey(hs.suite, hs.trafficSecret) + c.out.setTrafficSecret(hs.suite, hs.trafficSecret) + + if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil { + c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, + resumptionLabel, hs.transcript) + } + + return nil +} + +func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { + if !c.isClient { + c.sendAlert(alertUnexpectedMessage) + return errors.New("tls: received new session ticket from a client") + } + + if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { + return nil + } + + // See RFC 8446, Section 4.6.1. + if msg.lifetime == 0 { + return nil + } + lifetime := time.Duration(msg.lifetime) * time.Second + if lifetime > maxSessionTicketLifetime { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: received a session ticket with invalid lifetime") + } + + cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) + if cipherSuite == nil || c.resumptionSecret == nil { + return c.sendAlert(alertInternalError) + } + + // Save the resumption_master_secret and nonce instead of deriving the PSK + // to do the least amount of work on NewSessionTicket messages before we + // know if the ticket will be used. Forward secrecy of resumed connections + // is guaranteed by the requirement for pskModeDHE. + session := &ClientSessionState{ + sessionTicket: msg.label, + vers: c.vers, + cipherSuite: c.cipherSuite, + masterSecret: c.resumptionSecret, + serverCertificates: c.peerCertificates, + verifiedChains: c.verifiedChains, + receivedAt: c.config.time(), + nonce: msg.nonce, + useBy: c.config.time().Add(lifetime), + ageAdd: msg.ageAdd, + } + + cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) + c.config.ClientSessionCache.Put(cacheKey, session) + + return nil +} diff --git a/vendor/github.com/marten-seemann/qtls/handshake_messages.go b/vendor/github.com/marten-seemann/qtls/handshake_messages.go new file mode 100644 index 00000000..9c2ffa1d --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/handshake_messages.go @@ -0,0 +1,1900 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "fmt" + "strings" + + "golang.org/x/crypto/cryptobyte" +) + +// The marshalingFunction type is an adapter to allow the use of ordinary +// functions as cryptobyte.MarshalingValue. +type marshalingFunction func(b *cryptobyte.Builder) error + +func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error { + return f(b) +} + +// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If +// the length of the sequence is not the value specified, it produces an error. +func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) { + b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error { + if len(v) != n { + return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v)) + } + b.AddBytes(v) + return nil + })) +} + +// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder. +func addUint64(b *cryptobyte.Builder, v uint64) { + b.AddUint32(uint32(v >> 32)) + b.AddUint32(uint32(v)) +} + +// readUint64 decodes a big-endian, 64-bit value into out and advances over it. +// It reports whether the read was successful. +func readUint64(s *cryptobyte.String, out *uint64) bool { + var hi, lo uint32 + if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) { + return false + } + *out = uint64(hi)<<32 | uint64(lo) + return true +} + +// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a +// []byte instead of a cryptobyte.String. +func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { + return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out)) +} + +// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a +// []byte instead of a cryptobyte.String. +func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { + return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out)) +} + +// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a +// []byte instead of a cryptobyte.String. +func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { + return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out)) +} + +type clientHelloMsg struct { + raw []byte + vers uint16 + random []byte + sessionId []byte + cipherSuites []uint16 + compressionMethods []uint8 + nextProtoNeg bool + serverName string + ocspStapling bool + supportedCurves []CurveID + supportedPoints []uint8 + ticketSupported bool + sessionTicket []uint8 + supportedSignatureAlgorithms []SignatureScheme + supportedSignatureAlgorithmsCert []SignatureScheme + secureRenegotiationSupported bool + secureRenegotiation []byte + alpnProtocols []string + scts bool + supportedVersions []uint16 + cookie []byte + keyShares []keyShare + earlyData bool + pskModes []uint8 + pskIdentities []pskIdentity + pskBinders [][]byte + additionalExtensions []Extension +} + +func (m *clientHelloMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeClientHello) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(m.vers) + addBytesWithLength(b, m.random, 32) + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.sessionId) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, suite := range m.cipherSuites { + b.AddUint16(suite) + } + }) + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.compressionMethods) + }) + + // If extensions aren't present, omit them. + var extensionsPresent bool + bWithoutExtensions := *b + + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if m.nextProtoNeg { + // draft-agl-tls-nextprotoneg-04 + b.AddUint16(extensionNextProtoNeg) + b.AddUint16(0) // empty extension_data + } + if len(m.serverName) > 0 { + // RFC 6066, Section 3 + b.AddUint16(extensionServerName) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(0) // name_type = host_name + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(m.serverName)) + }) + }) + }) + } + if m.ocspStapling { + // RFC 4366, Section 3.6 + b.AddUint16(extensionStatusRequest) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(1) // status_type = ocsp + b.AddUint16(0) // empty responder_id_list + b.AddUint16(0) // empty request_extensions + }) + } + if len(m.supportedCurves) > 0 { + // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 + b.AddUint16(extensionSupportedCurves) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, curve := range m.supportedCurves { + b.AddUint16(uint16(curve)) + } + }) + }) + } + if len(m.supportedPoints) > 0 { + // RFC 4492, Section 5.1.2 + b.AddUint16(extensionSupportedPoints) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.supportedPoints) + }) + }) + } + if m.ticketSupported { + // RFC 5077, Section 3.2 + b.AddUint16(extensionSessionTicket) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.sessionTicket) + }) + } + if len(m.supportedSignatureAlgorithms) > 0 { + // RFC 5246, Section 7.4.1.4.1 + b.AddUint16(extensionSignatureAlgorithms) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sigAlgo := range m.supportedSignatureAlgorithms { + b.AddUint16(uint16(sigAlgo)) + } + }) + }) + } + if len(m.supportedSignatureAlgorithmsCert) > 0 { + // RFC 8446, Section 4.2.3 + b.AddUint16(extensionSignatureAlgorithmsCert) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { + b.AddUint16(uint16(sigAlgo)) + } + }) + }) + } + if m.secureRenegotiationSupported { + // RFC 5746, Section 3.2 + b.AddUint16(extensionRenegotiationInfo) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.secureRenegotiation) + }) + }) + } + if len(m.alpnProtocols) > 0 { + // RFC 7301, Section 3.1 + b.AddUint16(extensionALPN) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, proto := range m.alpnProtocols { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(proto)) + }) + } + }) + }) + } + if m.scts { + // RFC 6962, Section 3.3.1 + b.AddUint16(extensionSCT) + b.AddUint16(0) // empty extension_data + } + if len(m.supportedVersions) > 0 { + // RFC 8446, Section 4.2.1 + b.AddUint16(extensionSupportedVersions) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + for _, vers := range m.supportedVersions { + b.AddUint16(vers) + } + }) + }) + } + if len(m.cookie) > 0 { + // RFC 8446, Section 4.2.2 + b.AddUint16(extensionCookie) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.cookie) + }) + }) + } + if len(m.keyShares) > 0 { + // RFC 8446, Section 4.2.8 + b.AddUint16(extensionKeyShare) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, ks := range m.keyShares { + b.AddUint16(uint16(ks.group)) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(ks.data) + }) + } + }) + }) + } + if m.earlyData { + // RFC 8446, Section 4.2.10 + b.AddUint16(extensionEarlyData) + b.AddUint16(0) // empty extension_data + } + if len(m.pskModes) > 0 { + // RFC 8446, Section 4.2.9 + b.AddUint16(extensionPSKModes) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.pskModes) + }) + }) + } + for _, ext := range m.additionalExtensions { + b.AddUint16(ext.Type) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(ext.Data) + }) + } + if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension + // RFC 8446, Section 4.2.11 + b.AddUint16(extensionPreSharedKey) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, psk := range m.pskIdentities { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(psk.label) + }) + b.AddUint32(psk.obfuscatedTicketAge) + } + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, binder := range m.pskBinders { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(binder) + }) + } + }) + }) + } + + extensionsPresent = len(b.BytesOrPanic()) > 2 + }) + + if !extensionsPresent { + *b = bWithoutExtensions + } + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +// marshalWithoutBinders returns the ClientHello through the +// PreSharedKeyExtension.identities field, according to RFC 8446, Section +// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length. +func (m *clientHelloMsg) marshalWithoutBinders() []byte { + bindersLen := 2 // uint16 length prefix + for _, binder := range m.pskBinders { + bindersLen += 1 // uint8 length prefix + bindersLen += len(binder) + } + + fullMessage := m.marshal() + return fullMessage[:len(fullMessage)-bindersLen] +} + +// updateBinders updates the m.pskBinders field, if necessary updating the +// cached marshalled representation. The supplied binders must have the same +// length as the current m.pskBinders. +func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) { + if len(pskBinders) != len(m.pskBinders) { + panic("tls: internal error: pskBinders length mismatch") + } + for i := range m.pskBinders { + if len(pskBinders[i]) != len(m.pskBinders[i]) { + panic("tls: internal error: pskBinders length mismatch") + } + } + m.pskBinders = pskBinders + if m.raw != nil { + lenWithoutBinders := len(m.marshalWithoutBinders()) + // TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported. + b := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders]) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, binder := range m.pskBinders { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(binder) + }) + } + }) + if len(b.BytesOrPanic()) != len(m.raw) { + panic("tls: internal error: failed to update binders") + } + } +} + +func (m *clientHelloMsg) unmarshal(data []byte) bool { + *m = clientHelloMsg{raw: data} + s := cryptobyte.String(data) + + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || + !readUint8LengthPrefixed(&s, &m.sessionId) { + return false + } + + var cipherSuites cryptobyte.String + if !s.ReadUint16LengthPrefixed(&cipherSuites) { + return false + } + m.cipherSuites = []uint16{} + m.secureRenegotiationSupported = false + for !cipherSuites.Empty() { + var suite uint16 + if !cipherSuites.ReadUint16(&suite) { + return false + } + if suite == scsvRenegotiation { + m.secureRenegotiationSupported = true + } + m.cipherSuites = append(m.cipherSuites, suite) + } + + if !readUint8LengthPrefixed(&s, &m.compressionMethods) { + return false + } + + if s.Empty() { + // ClientHello is optionally followed by extension data + return true + } + + var extensions cryptobyte.String + if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { + return false + } + + for !extensions.Empty() { + var ext uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&ext) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + + switch ext { + case extensionServerName: + // RFC 6066, Section 3 + var nameList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() { + return false + } + for !nameList.Empty() { + var nameType uint8 + var serverName cryptobyte.String + if !nameList.ReadUint8(&nameType) || + !nameList.ReadUint16LengthPrefixed(&serverName) || + serverName.Empty() { + return false + } + if nameType != 0 { + continue + } + if len(m.serverName) != 0 { + // Multiple names of the same name_type are prohibited. + return false + } + m.serverName = string(serverName) + // An SNI value may not include a trailing dot. + if strings.HasSuffix(m.serverName, ".") { + return false + } + } + case extensionNextProtoNeg: + // draft-agl-tls-nextprotoneg-04 + m.nextProtoNeg = true + case extensionStatusRequest: + // RFC 4366, Section 3.6 + var statusType uint8 + var ignored cryptobyte.String + if !extData.ReadUint8(&statusType) || + !extData.ReadUint16LengthPrefixed(&ignored) || + !extData.ReadUint16LengthPrefixed(&ignored) { + return false + } + m.ocspStapling = statusType == statusTypeOCSP + case extensionSupportedCurves: + // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 + var curves cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() { + return false + } + for !curves.Empty() { + var curve uint16 + if !curves.ReadUint16(&curve) { + return false + } + m.supportedCurves = append(m.supportedCurves, CurveID(curve)) + } + case extensionSupportedPoints: + // RFC 4492, Section 5.1.2 + if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || + len(m.supportedPoints) == 0 { + return false + } + case extensionSessionTicket: + // RFC 5077, Section 3.2 + m.ticketSupported = true + extData.ReadBytes(&m.sessionTicket, len(extData)) + case extensionSignatureAlgorithms: + // RFC 5246, Section 7.4.1.4.1 + var sigAndAlgs cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { + return false + } + for !sigAndAlgs.Empty() { + var sigAndAlg uint16 + if !sigAndAlgs.ReadUint16(&sigAndAlg) { + return false + } + m.supportedSignatureAlgorithms = append( + m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) + } + case extensionSignatureAlgorithmsCert: + // RFC 8446, Section 4.2.3 + var sigAndAlgs cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { + return false + } + for !sigAndAlgs.Empty() { + var sigAndAlg uint16 + if !sigAndAlgs.ReadUint16(&sigAndAlg) { + return false + } + m.supportedSignatureAlgorithmsCert = append( + m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) + } + case extensionRenegotiationInfo: + // RFC 5746, Section 3.2 + if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { + return false + } + m.secureRenegotiationSupported = true + case extensionALPN: + // RFC 7301, Section 3.1 + var protoList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { + return false + } + for !protoList.Empty() { + var proto cryptobyte.String + if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() { + return false + } + m.alpnProtocols = append(m.alpnProtocols, string(proto)) + } + case extensionSCT: + // RFC 6962, Section 3.3.1 + m.scts = true + case extensionSupportedVersions: + // RFC 8446, Section 4.2.1 + var versList cryptobyte.String + if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() { + return false + } + for !versList.Empty() { + var vers uint16 + if !versList.ReadUint16(&vers) { + return false + } + m.supportedVersions = append(m.supportedVersions, vers) + } + case extensionCookie: + // RFC 8446, Section 4.2.2 + if !readUint16LengthPrefixed(&extData, &m.cookie) || + len(m.cookie) == 0 { + return false + } + case extensionKeyShare: + // RFC 8446, Section 4.2.8 + var clientShares cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&clientShares) { + return false + } + for !clientShares.Empty() { + var ks keyShare + if !clientShares.ReadUint16((*uint16)(&ks.group)) || + !readUint16LengthPrefixed(&clientShares, &ks.data) || + len(ks.data) == 0 { + return false + } + m.keyShares = append(m.keyShares, ks) + } + case extensionEarlyData: + // RFC 8446, Section 4.2.10 + m.earlyData = true + case extensionPSKModes: + // RFC 8446, Section 4.2.9 + if !readUint8LengthPrefixed(&extData, &m.pskModes) { + return false + } + case extensionPreSharedKey: + // RFC 8446, Section 4.2.11 + if !extensions.Empty() { + return false // pre_shared_key must be the last extension + } + var identities cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() { + return false + } + for !identities.Empty() { + var psk pskIdentity + if !readUint16LengthPrefixed(&identities, &psk.label) || + !identities.ReadUint32(&psk.obfuscatedTicketAge) || + len(psk.label) == 0 { + return false + } + m.pskIdentities = append(m.pskIdentities, psk) + } + var binders cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() { + return false + } + for !binders.Empty() { + var binder []byte + if !readUint8LengthPrefixed(&binders, &binder) || + len(binder) == 0 { + return false + } + m.pskBinders = append(m.pskBinders, binder) + } + default: + m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) + continue + } + + if !extData.Empty() { + return false + } + } + + return true +} + +type serverHelloMsg struct { + raw []byte + vers uint16 + random []byte + sessionId []byte + cipherSuite uint16 + compressionMethod uint8 + nextProtoNeg bool + nextProtos []string + ocspStapling bool + ticketSupported bool + secureRenegotiationSupported bool + secureRenegotiation []byte + alpnProtocol string + scts [][]byte + supportedVersion uint16 + serverShare keyShare + selectedIdentityPresent bool + selectedIdentity uint16 + + // HelloRetryRequest extensions + cookie []byte + selectedGroup CurveID +} + +func (m *serverHelloMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeServerHello) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(m.vers) + addBytesWithLength(b, m.random, 32) + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.sessionId) + }) + b.AddUint16(m.cipherSuite) + b.AddUint8(m.compressionMethod) + + // If extensions aren't present, omit them. + var extensionsPresent bool + bWithoutExtensions := *b + + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if m.nextProtoNeg { + b.AddUint16(extensionNextProtoNeg) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, proto := range m.nextProtos { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(proto)) + }) + } + }) + } + if m.ocspStapling { + b.AddUint16(extensionStatusRequest) + b.AddUint16(0) // empty extension_data + } + if m.ticketSupported { + b.AddUint16(extensionSessionTicket) + b.AddUint16(0) // empty extension_data + } + if m.secureRenegotiationSupported { + b.AddUint16(extensionRenegotiationInfo) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.secureRenegotiation) + }) + }) + } + if len(m.alpnProtocol) > 0 { + b.AddUint16(extensionALPN) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(m.alpnProtocol)) + }) + }) + }) + } + if len(m.scts) > 0 { + b.AddUint16(extensionSCT) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sct := range m.scts { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(sct) + }) + } + }) + }) + } + if m.supportedVersion != 0 { + b.AddUint16(extensionSupportedVersions) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(m.supportedVersion) + }) + } + if m.serverShare.group != 0 { + b.AddUint16(extensionKeyShare) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(uint16(m.serverShare.group)) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.serverShare.data) + }) + }) + } + if m.selectedIdentityPresent { + b.AddUint16(extensionPreSharedKey) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(m.selectedIdentity) + }) + } + + if len(m.cookie) > 0 { + b.AddUint16(extensionCookie) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.cookie) + }) + }) + } + if m.selectedGroup != 0 { + b.AddUint16(extensionKeyShare) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16(uint16(m.selectedGroup)) + }) + } + + extensionsPresent = len(b.BytesOrPanic()) > 2 + }) + + if !extensionsPresent { + *b = bWithoutExtensions + } + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *serverHelloMsg) unmarshal(data []byte) bool { + *m = serverHelloMsg{raw: data} + s := cryptobyte.String(data) + + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || + !readUint8LengthPrefixed(&s, &m.sessionId) || + !s.ReadUint16(&m.cipherSuite) || + !s.ReadUint8(&m.compressionMethod) { + return false + } + + if s.Empty() { + // ServerHello is optionally followed by extension data + return true + } + + var extensions cryptobyte.String + if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { + return false + } + + for !extensions.Empty() { + var extension uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&extension) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + + switch extension { + case extensionNextProtoNeg: + m.nextProtoNeg = true + for !extData.Empty() { + var proto cryptobyte.String + if !extData.ReadUint8LengthPrefixed(&proto) || + proto.Empty() { + return false + } + m.nextProtos = append(m.nextProtos, string(proto)) + } + case extensionStatusRequest: + m.ocspStapling = true + case extensionSessionTicket: + m.ticketSupported = true + case extensionRenegotiationInfo: + if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { + return false + } + m.secureRenegotiationSupported = true + case extensionALPN: + var protoList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { + return false + } + var proto cryptobyte.String + if !protoList.ReadUint8LengthPrefixed(&proto) || + proto.Empty() || !protoList.Empty() { + return false + } + m.alpnProtocol = string(proto) + case extensionSCT: + var sctList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { + return false + } + for !sctList.Empty() { + var sct []byte + if !readUint16LengthPrefixed(&sctList, &sct) || + len(sct) == 0 { + return false + } + m.scts = append(m.scts, sct) + } + case extensionSupportedVersions: + if !extData.ReadUint16(&m.supportedVersion) { + return false + } + case extensionCookie: + if !readUint16LengthPrefixed(&extData, &m.cookie) || + len(m.cookie) == 0 { + return false + } + case extensionKeyShare: + // This extension has different formats in SH and HRR, accept either + // and let the handshake logic decide. See RFC 8446, Section 4.2.8. + if len(extData) == 2 { + if !extData.ReadUint16((*uint16)(&m.selectedGroup)) { + return false + } + } else { + if !extData.ReadUint16((*uint16)(&m.serverShare.group)) || + !readUint16LengthPrefixed(&extData, &m.serverShare.data) { + return false + } + } + case extensionPreSharedKey: + m.selectedIdentityPresent = true + if !extData.ReadUint16(&m.selectedIdentity) { + return false + } + default: + // Ignore unknown extensions. + continue + } + + if !extData.Empty() { + return false + } + } + + return true +} + +type encryptedExtensionsMsg struct { + raw []byte + alpnProtocol string + + additionalExtensions []Extension +} + +func (m *encryptedExtensionsMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeEncryptedExtensions) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if len(m.alpnProtocol) > 0 { + b.AddUint16(extensionALPN) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(m.alpnProtocol)) + }) + }) + }) + } + for _, ext := range m.additionalExtensions { + b.AddUint16(ext.Type) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(ext.Data) + }) + } + }) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool { + *m = encryptedExtensionsMsg{raw: data} + s := cryptobyte.String(data) + + var extensions cryptobyte.String + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { + return false + } + + for !extensions.Empty() { + var ext uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&ext) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + + switch ext { + case extensionALPN: + var protoList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { + return false + } + var proto cryptobyte.String + if !protoList.ReadUint8LengthPrefixed(&proto) || + proto.Empty() || !protoList.Empty() { + return false + } + m.alpnProtocol = string(proto) + default: + m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) + continue + } + + if !extData.Empty() { + return false + } + } + + return true +} + +type endOfEarlyDataMsg struct{} + +func (m *endOfEarlyDataMsg) marshal() []byte { + x := make([]byte, 4) + x[0] = typeEndOfEarlyData + return x +} + +func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool { + return len(data) == 4 +} + +type keyUpdateMsg struct { + raw []byte + updateRequested bool +} + +func (m *keyUpdateMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeKeyUpdate) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + if m.updateRequested { + b.AddUint8(1) + } else { + b.AddUint8(0) + } + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *keyUpdateMsg) unmarshal(data []byte) bool { + m.raw = data + s := cryptobyte.String(data) + + var updateRequested uint8 + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint8(&updateRequested) || !s.Empty() { + return false + } + switch updateRequested { + case 0: + m.updateRequested = false + case 1: + m.updateRequested = true + default: + return false + } + return true +} + +type newSessionTicketMsgTLS13 struct { + raw []byte + lifetime uint32 + ageAdd uint32 + nonce []byte + label []byte + maxEarlyData uint32 +} + +func (m *newSessionTicketMsgTLS13) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeNewSessionTicket) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint32(m.lifetime) + b.AddUint32(m.ageAdd) + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.nonce) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.label) + }) + + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if m.maxEarlyData > 0 { + b.AddUint16(extensionEarlyData) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint32(m.maxEarlyData) + }) + } + }) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool { + *m = newSessionTicketMsgTLS13{raw: data} + s := cryptobyte.String(data) + + var extensions cryptobyte.String + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint32(&m.lifetime) || + !s.ReadUint32(&m.ageAdd) || + !readUint8LengthPrefixed(&s, &m.nonce) || + !readUint16LengthPrefixed(&s, &m.label) || + !s.ReadUint16LengthPrefixed(&extensions) || + !s.Empty() { + return false + } + + for !extensions.Empty() { + var extension uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&extension) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + + switch extension { + case extensionEarlyData: + if !extData.ReadUint32(&m.maxEarlyData) { + return false + } + default: + // Ignore unknown extensions. + continue + } + + if !extData.Empty() { + return false + } + } + + return true +} + +type certificateRequestMsgTLS13 struct { + raw []byte + ocspStapling bool + scts bool + supportedSignatureAlgorithms []SignatureScheme + supportedSignatureAlgorithmsCert []SignatureScheme + certificateAuthorities [][]byte +} + +func (m *certificateRequestMsgTLS13) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeCertificateRequest) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + // certificate_request_context (SHALL be zero length unless used for + // post-handshake authentication) + b.AddUint8(0) + + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if m.ocspStapling { + b.AddUint16(extensionStatusRequest) + b.AddUint16(0) // empty extension_data + } + if m.scts { + // RFC 8446, Section 4.4.2.1 makes no mention of + // signed_certificate_timestamp in CertificateRequest, but + // "Extensions in the Certificate message from the client MUST + // correspond to extensions in the CertificateRequest message + // from the server." and it appears in the table in Section 4.2. + b.AddUint16(extensionSCT) + b.AddUint16(0) // empty extension_data + } + if len(m.supportedSignatureAlgorithms) > 0 { + b.AddUint16(extensionSignatureAlgorithms) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sigAlgo := range m.supportedSignatureAlgorithms { + b.AddUint16(uint16(sigAlgo)) + } + }) + }) + } + if len(m.supportedSignatureAlgorithmsCert) > 0 { + b.AddUint16(extensionSignatureAlgorithmsCert) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { + b.AddUint16(uint16(sigAlgo)) + } + }) + }) + } + if len(m.certificateAuthorities) > 0 { + b.AddUint16(extensionCertificateAuthorities) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, ca := range m.certificateAuthorities { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(ca) + }) + } + }) + }) + } + }) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool { + *m = certificateRequestMsgTLS13{raw: data} + s := cryptobyte.String(data) + + var context, extensions cryptobyte.String + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || + !s.ReadUint16LengthPrefixed(&extensions) || + !s.Empty() { + return false + } + + for !extensions.Empty() { + var extension uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&extension) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + + switch extension { + case extensionStatusRequest: + m.ocspStapling = true + case extensionSCT: + m.scts = true + case extensionSignatureAlgorithms: + var sigAndAlgs cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { + return false + } + for !sigAndAlgs.Empty() { + var sigAndAlg uint16 + if !sigAndAlgs.ReadUint16(&sigAndAlg) { + return false + } + m.supportedSignatureAlgorithms = append( + m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) + } + case extensionSignatureAlgorithmsCert: + var sigAndAlgs cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { + return false + } + for !sigAndAlgs.Empty() { + var sigAndAlg uint16 + if !sigAndAlgs.ReadUint16(&sigAndAlg) { + return false + } + m.supportedSignatureAlgorithmsCert = append( + m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) + } + case extensionCertificateAuthorities: + var auths cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() { + return false + } + for !auths.Empty() { + var ca []byte + if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 { + return false + } + m.certificateAuthorities = append(m.certificateAuthorities, ca) + } + default: + // Ignore unknown extensions. + continue + } + + if !extData.Empty() { + return false + } + } + + return true +} + +type certificateMsg struct { + raw []byte + certificates [][]byte +} + +func (m *certificateMsg) marshal() (x []byte) { + if m.raw != nil { + return m.raw + } + + var i int + for _, slice := range m.certificates { + i += len(slice) + } + + length := 3 + 3*len(m.certificates) + i + x = make([]byte, 4+length) + x[0] = typeCertificate + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + + certificateOctets := length - 3 + x[4] = uint8(certificateOctets >> 16) + x[5] = uint8(certificateOctets >> 8) + x[6] = uint8(certificateOctets) + + y := x[7:] + for _, slice := range m.certificates { + y[0] = uint8(len(slice) >> 16) + y[1] = uint8(len(slice) >> 8) + y[2] = uint8(len(slice)) + copy(y[3:], slice) + y = y[3+len(slice):] + } + + m.raw = x + return +} + +func (m *certificateMsg) unmarshal(data []byte) bool { + if len(data) < 7 { + return false + } + + m.raw = data + certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]) + if uint32(len(data)) != certsLen+7 { + return false + } + + numCerts := 0 + d := data[7:] + for certsLen > 0 { + if len(d) < 4 { + return false + } + certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) + if uint32(len(d)) < 3+certLen { + return false + } + d = d[3+certLen:] + certsLen -= 3 + certLen + numCerts++ + } + + m.certificates = make([][]byte, numCerts) + d = data[7:] + for i := 0; i < numCerts; i++ { + certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) + m.certificates[i] = d[3 : 3+certLen] + d = d[3+certLen:] + } + + return true +} + +type certificateMsgTLS13 struct { + raw []byte + certificate Certificate + ocspStapling bool + scts bool +} + +func (m *certificateMsgTLS13) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeCertificate) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(0) // certificate_request_context + + certificate := m.certificate + if !m.ocspStapling { + certificate.OCSPStaple = nil + } + if !m.scts { + certificate.SignedCertificateTimestamps = nil + } + marshalCertificate(b, certificate) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) { + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + for i, cert := range certificate.Certificate { + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(cert) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + if i > 0 { + // This library only supports OCSP and SCT for leaf certificates. + return + } + if certificate.OCSPStaple != nil { + b.AddUint16(extensionStatusRequest) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(statusTypeOCSP) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(certificate.OCSPStaple) + }) + }) + } + if certificate.SignedCertificateTimestamps != nil { + b.AddUint16(extensionSCT) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + for _, sct := range certificate.SignedCertificateTimestamps { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(sct) + }) + } + }) + }) + } + }) + } + }) +} + +func (m *certificateMsgTLS13) unmarshal(data []byte) bool { + *m = certificateMsgTLS13{raw: data} + s := cryptobyte.String(data) + + var context cryptobyte.String + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || + !unmarshalCertificate(&s, &m.certificate) || + !s.Empty() { + return false + } + + m.scts = m.certificate.SignedCertificateTimestamps != nil + m.ocspStapling = m.certificate.OCSPStaple != nil + + return true +} + +func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool { + var certList cryptobyte.String + if !s.ReadUint24LengthPrefixed(&certList) { + return false + } + for !certList.Empty() { + var cert []byte + var extensions cryptobyte.String + if !readUint24LengthPrefixed(&certList, &cert) || + !certList.ReadUint16LengthPrefixed(&extensions) { + return false + } + certificate.Certificate = append(certificate.Certificate, cert) + for !extensions.Empty() { + var extension uint16 + var extData cryptobyte.String + if !extensions.ReadUint16(&extension) || + !extensions.ReadUint16LengthPrefixed(&extData) { + return false + } + if len(certificate.Certificate) > 1 { + // This library only supports OCSP and SCT for leaf certificates. + continue + } + + switch extension { + case extensionStatusRequest: + var statusType uint8 + if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP || + !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) || + len(certificate.OCSPStaple) == 0 { + return false + } + case extensionSCT: + var sctList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { + return false + } + for !sctList.Empty() { + var sct []byte + if !readUint16LengthPrefixed(&sctList, &sct) || + len(sct) == 0 { + return false + } + certificate.SignedCertificateTimestamps = append( + certificate.SignedCertificateTimestamps, sct) + } + default: + // Ignore unknown extensions. + continue + } + + if !extData.Empty() { + return false + } + } + } + return true +} + +type serverKeyExchangeMsg struct { + raw []byte + key []byte +} + +func (m *serverKeyExchangeMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + length := len(m.key) + x := make([]byte, length+4) + x[0] = typeServerKeyExchange + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + copy(x[4:], m.key) + + m.raw = x + return x +} + +func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { + m.raw = data + if len(data) < 4 { + return false + } + m.key = data[4:] + return true +} + +type certificateStatusMsg struct { + raw []byte + response []byte +} + +func (m *certificateStatusMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeCertificateStatus) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(statusTypeOCSP) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.response) + }) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *certificateStatusMsg) unmarshal(data []byte) bool { + m.raw = data + s := cryptobyte.String(data) + + var statusType uint8 + if !s.Skip(4) || // message type and uint24 length field + !s.ReadUint8(&statusType) || statusType != statusTypeOCSP || + !readUint24LengthPrefixed(&s, &m.response) || + len(m.response) == 0 || !s.Empty() { + return false + } + return true +} + +type serverHelloDoneMsg struct{} + +func (m *serverHelloDoneMsg) marshal() []byte { + x := make([]byte, 4) + x[0] = typeServerHelloDone + return x +} + +func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { + return len(data) == 4 +} + +type clientKeyExchangeMsg struct { + raw []byte + ciphertext []byte +} + +func (m *clientKeyExchangeMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + length := len(m.ciphertext) + x := make([]byte, length+4) + x[0] = typeClientKeyExchange + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + copy(x[4:], m.ciphertext) + + m.raw = x + return x +} + +func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { + m.raw = data + if len(data) < 4 { + return false + } + l := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) + if l != len(data)-4 { + return false + } + m.ciphertext = data[4:] + return true +} + +type finishedMsg struct { + raw []byte + verifyData []byte +} + +func (m *finishedMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeFinished) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.verifyData) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *finishedMsg) unmarshal(data []byte) bool { + m.raw = data + s := cryptobyte.String(data) + return s.Skip(1) && + readUint24LengthPrefixed(&s, &m.verifyData) && + s.Empty() +} + +type nextProtoMsg struct { + raw []byte + proto string +} + +func (m *nextProtoMsg) marshal() []byte { + if m.raw != nil { + return m.raw + } + l := len(m.proto) + if l > 255 { + l = 255 + } + + padding := 32 - (l+2)%32 + length := l + padding + 2 + x := make([]byte, length+4) + x[0] = typeNextProtocol + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + + y := x[4:] + y[0] = byte(l) + copy(y[1:], []byte(m.proto[0:l])) + y = y[1+l:] + y[0] = byte(padding) + + m.raw = x + + return x +} + +func (m *nextProtoMsg) unmarshal(data []byte) bool { + m.raw = data + + if len(data) < 5 { + return false + } + data = data[4:] + protoLen := int(data[0]) + data = data[1:] + if len(data) < protoLen { + return false + } + m.proto = string(data[0:protoLen]) + data = data[protoLen:] + + if len(data) < 1 { + return false + } + paddingLen := int(data[0]) + data = data[1:] + if len(data) != paddingLen { + return false + } + + return true +} + +type certificateRequestMsg struct { + raw []byte + // hasSignatureAlgorithm indicates whether this message includes a list of + // supported signature algorithms. This change was introduced with TLS 1.2. + hasSignatureAlgorithm bool + + certificateTypes []byte + supportedSignatureAlgorithms []SignatureScheme + certificateAuthorities [][]byte +} + +func (m *certificateRequestMsg) marshal() (x []byte) { + if m.raw != nil { + return m.raw + } + + // See RFC 4346, Section 7.4.4. + length := 1 + len(m.certificateTypes) + 2 + casLength := 0 + for _, ca := range m.certificateAuthorities { + casLength += 2 + len(ca) + } + length += casLength + + if m.hasSignatureAlgorithm { + length += 2 + 2*len(m.supportedSignatureAlgorithms) + } + + x = make([]byte, 4+length) + x[0] = typeCertificateRequest + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + + x[4] = uint8(len(m.certificateTypes)) + + copy(x[5:], m.certificateTypes) + y := x[5+len(m.certificateTypes):] + + if m.hasSignatureAlgorithm { + n := len(m.supportedSignatureAlgorithms) * 2 + y[0] = uint8(n >> 8) + y[1] = uint8(n) + y = y[2:] + for _, sigAlgo := range m.supportedSignatureAlgorithms { + y[0] = uint8(sigAlgo >> 8) + y[1] = uint8(sigAlgo) + y = y[2:] + } + } + + y[0] = uint8(casLength >> 8) + y[1] = uint8(casLength) + y = y[2:] + for _, ca := range m.certificateAuthorities { + y[0] = uint8(len(ca) >> 8) + y[1] = uint8(len(ca)) + y = y[2:] + copy(y, ca) + y = y[len(ca):] + } + + m.raw = x + return +} + +func (m *certificateRequestMsg) unmarshal(data []byte) bool { + m.raw = data + + if len(data) < 5 { + return false + } + + length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) + if uint32(len(data))-4 != length { + return false + } + + numCertTypes := int(data[4]) + data = data[5:] + if numCertTypes == 0 || len(data) <= numCertTypes { + return false + } + + m.certificateTypes = make([]byte, numCertTypes) + if copy(m.certificateTypes, data) != numCertTypes { + return false + } + + data = data[numCertTypes:] + + if m.hasSignatureAlgorithm { + if len(data) < 2 { + return false + } + sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) + data = data[2:] + if sigAndHashLen&1 != 0 { + return false + } + if len(data) < int(sigAndHashLen) { + return false + } + numSigAlgos := sigAndHashLen / 2 + m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos) + for i := range m.supportedSignatureAlgorithms { + m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1]) + data = data[2:] + } + } + + if len(data) < 2 { + return false + } + casLength := uint16(data[0])<<8 | uint16(data[1]) + data = data[2:] + if len(data) < int(casLength) { + return false + } + cas := make([]byte, casLength) + copy(cas, data) + data = data[casLength:] + + m.certificateAuthorities = nil + for len(cas) > 0 { + if len(cas) < 2 { + return false + } + caLen := uint16(cas[0])<<8 | uint16(cas[1]) + cas = cas[2:] + + if len(cas) < int(caLen) { + return false + } + + m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen]) + cas = cas[caLen:] + } + + return len(data) == 0 +} + +type certificateVerifyMsg struct { + raw []byte + hasSignatureAlgorithm bool // format change introduced in TLS 1.2 + signatureAlgorithm SignatureScheme + signature []byte +} + +func (m *certificateVerifyMsg) marshal() (x []byte) { + if m.raw != nil { + return m.raw + } + + var b cryptobyte.Builder + b.AddUint8(typeCertificateVerify) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + if m.hasSignatureAlgorithm { + b.AddUint16(uint16(m.signatureAlgorithm)) + } + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.signature) + }) + }) + + m.raw = b.BytesOrPanic() + return m.raw +} + +func (m *certificateVerifyMsg) unmarshal(data []byte) bool { + m.raw = data + s := cryptobyte.String(data) + + if !s.Skip(4) { // message type and uint24 length field + return false + } + if m.hasSignatureAlgorithm { + if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) { + return false + } + } + return readUint16LengthPrefixed(&s, &m.signature) && s.Empty() +} + +type newSessionTicketMsg struct { + raw []byte + ticket []byte +} + +func (m *newSessionTicketMsg) marshal() (x []byte) { + if m.raw != nil { + return m.raw + } + + // See RFC 5077, Section 3.3. + ticketLen := len(m.ticket) + length := 2 + 4 + ticketLen + x = make([]byte, 4+length) + x[0] = typeNewSessionTicket + x[1] = uint8(length >> 16) + x[2] = uint8(length >> 8) + x[3] = uint8(length) + x[8] = uint8(ticketLen >> 8) + x[9] = uint8(ticketLen) + copy(x[10:], m.ticket) + + m.raw = x + + return +} + +func (m *newSessionTicketMsg) unmarshal(data []byte) bool { + m.raw = data + + if len(data) < 10 { + return false + } + + length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) + if uint32(len(data))-4 != length { + return false + } + + ticketLen := int(data[8])<<8 + int(data[9]) + if len(data)-10 != ticketLen { + return false + } + + m.ticket = data[10:] + + return true +} + +type helloRequestMsg struct { +} + +func (*helloRequestMsg) marshal() []byte { + return []byte{typeHelloRequest, 0, 0, 0} +} + +func (*helloRequestMsg) unmarshal(data []byte) bool { + return len(data) == 4 +} diff --git a/vendor/github.com/marten-seemann/qtls/handshake_server.go b/vendor/github.com/marten-seemann/qtls/handshake_server.go new file mode 100644 index 00000000..2f3b4144 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/handshake_server.go @@ -0,0 +1,822 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/subtle" + "crypto/x509" + "errors" + "fmt" + "io" + "sync/atomic" +) + +// serverHandshakeState contains details of a server handshake in progress. +// It's discarded once the handshake has completed. +type serverHandshakeState struct { + c *Conn + clientHello *clientHelloMsg + hello *serverHelloMsg + suite *cipherSuite + ellipticOk bool + ecdsaOk bool + rsaDecryptOk bool + rsaSignOk bool + sessionState *sessionState + finishedHash finishedHash + masterSecret []byte + cert *Certificate +} + +// serverHandshake performs a TLS handshake as a server. +func (c *Conn) serverHandshake() error { + // If this is the first server handshake, we generate a random key to + // encrypt the tickets with. + c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) }) + c.setAlternativeRecordLayer() + + clientHello, err := c.readClientHello() + if err != nil { + return err + } + + if c.vers == VersionTLS13 { + hs := serverHandshakeStateTLS13{ + c: c, + clientHello: clientHello, + } + return hs.handshake() + } + + hs := serverHandshakeState{ + c: c, + clientHello: clientHello, + } + return hs.handshake() +} + +func (hs *serverHandshakeState) handshake() error { + c := hs.c + + if err := hs.processClientHello(); err != nil { + return err + } + + // For an overview of TLS handshaking, see RFC 5246, Section 7.3. + c.buffering = true + if hs.checkForResumption() { + // The client has included a session ticket and so we do an abbreviated handshake. + if err := hs.doResumeHandshake(); err != nil { + return err + } + if err := hs.establishKeys(); err != nil { + return err + } + // ticketSupported is set in a resumption handshake if the + // ticket from the client was encrypted with an old session + // ticket key and thus a refreshed ticket should be sent. + if hs.hello.ticketSupported { + if err := hs.sendSessionTicket(); err != nil { + return err + } + } + if err := hs.sendFinished(c.serverFinished[:]); err != nil { + return err + } + if _, err := c.flush(); err != nil { + return err + } + c.clientFinishedIsFirst = false + if err := hs.readFinished(nil); err != nil { + return err + } + c.didResume = true + } else { + // The client didn't include a session ticket, or it wasn't + // valid so we do a full handshake. + if err := hs.pickCipherSuite(); err != nil { + return err + } + if err := hs.doFullHandshake(); err != nil { + return err + } + if err := hs.establishKeys(); err != nil { + return err + } + if err := hs.readFinished(c.clientFinished[:]); err != nil { + return err + } + c.clientFinishedIsFirst = true + c.buffering = true + if err := hs.sendSessionTicket(); err != nil { + return err + } + if err := hs.sendFinished(nil); err != nil { + return err + } + if _, err := c.flush(); err != nil { + return err + } + } + + c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random) + atomic.StoreUint32(&c.handshakeStatus, 1) + + return nil +} + +// readClientHello reads a ClientHello message and selects the protocol version. +func (c *Conn) readClientHello() (*clientHelloMsg, error) { + msg, err := c.readHandshake() + if err != nil { + return nil, err + } + clientHello, ok := msg.(*clientHelloMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return nil, unexpectedMessageError(clientHello, msg) + } + + if c.config.GetConfigForClient != nil { + chi := clientHelloInfo(c, clientHello) + if newConfig, err := c.config.GetConfigForClient(chi); err != nil { + c.sendAlert(alertInternalError) + return nil, err + } else if newConfig != nil { + newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) }) + c.config = newConfig + } + } + + clientVersions := clientHello.supportedVersions + if len(clientHello.supportedVersions) == 0 { + clientVersions = supportedVersionsFromMax(clientHello.vers) + } + c.vers, ok = c.config.mutualVersion(false, clientVersions) + if !ok { + c.sendAlert(alertProtocolVersion) + return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions) + } + c.haveVers = true + c.in.version = c.vers + c.out.version = c.vers + + return clientHello, nil +} + +func (hs *serverHandshakeState) processClientHello() error { + c := hs.c + + hs.hello = new(serverHelloMsg) + hs.hello.vers = c.vers + + supportedCurve := false + preferredCurves := c.config.curvePreferences() +Curves: + for _, curve := range hs.clientHello.supportedCurves { + for _, supported := range preferredCurves { + if supported == curve { + supportedCurve = true + break Curves + } + } + } + + supportedPointFormat := false + for _, pointFormat := range hs.clientHello.supportedPoints { + if pointFormat == pointFormatUncompressed { + supportedPointFormat = true + break + } + } + hs.ellipticOk = supportedCurve && supportedPointFormat + + foundCompression := false + // We only support null compression, so check that the client offered it. + for _, compression := range hs.clientHello.compressionMethods { + if compression == compressionNone { + foundCompression = true + break + } + } + + if !foundCompression { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: client does not support uncompressed connections") + } + + hs.hello.random = make([]byte, 32) + serverRandom := hs.hello.random + // Downgrade protection canaries. See RFC 8446, Section 4.1.3. + maxVers := c.config.maxSupportedVersion(false) + if maxVers >= VersionTLS12 && c.vers < maxVers { + if c.vers == VersionTLS12 { + copy(serverRandom[24:], downgradeCanaryTLS12) + } else { + copy(serverRandom[24:], downgradeCanaryTLS11) + } + serverRandom = serverRandom[:24] + } + _, err := io.ReadFull(c.config.rand(), serverRandom) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + if len(hs.clientHello.secureRenegotiation) != 0 { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: initial handshake had non-empty renegotiation extension") + } + + hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported + hs.hello.compressionMethod = compressionNone + if len(hs.clientHello.serverName) > 0 { + c.serverName = hs.clientHello.serverName + } + + if len(hs.clientHello.alpnProtocols) > 0 { + if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { + hs.hello.alpnProtocol = selectedProto + c.clientProtocol = selectedProto + } + } else { + // Although sending an empty NPN extension is reasonable, Firefox has + // had a bug around this. Best to send nothing at all if + // c.config.NextProtos is empty. See + // https://golang.org/issue/5445. + if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 { + hs.hello.nextProtoNeg = true + hs.hello.nextProtos = c.config.NextProtos + } + } + + hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + if hs.clientHello.scts { + hs.hello.scts = hs.cert.SignedCertificateTimestamps + } + + if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { + switch priv.Public().(type) { + case *ecdsa.PublicKey: + hs.ecdsaOk = true + case *rsa.PublicKey: + hs.rsaSignOk = true + default: + c.sendAlert(alertInternalError) + return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public()) + } + } + if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok { + switch priv.Public().(type) { + case *rsa.PublicKey: + hs.rsaDecryptOk = true + default: + c.sendAlert(alertInternalError) + return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public()) + } + } + + return nil +} + +func (hs *serverHandshakeState) pickCipherSuite() error { + c := hs.c + + var preferenceList, supportedList []uint16 + if c.config.PreferServerCipherSuites { + preferenceList = c.config.cipherSuites() + supportedList = hs.clientHello.cipherSuites + } else { + preferenceList = hs.clientHello.cipherSuites + supportedList = c.config.cipherSuites() + } + + for _, id := range preferenceList { + if hs.setCipherSuite(id, supportedList, c.vers) { + break + } + } + + if hs.suite == nil { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: no cipher suite supported by both client and server") + } + + for _, id := range hs.clientHello.cipherSuites { + if id == TLS_FALLBACK_SCSV { + // The client is doing a fallback connection. See RFC 7507. + if hs.clientHello.vers < c.config.maxSupportedVersion(false) { + c.sendAlert(alertInappropriateFallback) + return errors.New("tls: client using inappropriate protocol fallback") + } + break + } + } + + return nil +} + +// checkForResumption reports whether we should perform resumption on this connection. +func (hs *serverHandshakeState) checkForResumption() bool { + c := hs.c + + if c.config.SessionTicketsDisabled { + return false + } + + plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket) + if plaintext == nil { + return false + } + hs.sessionState = &sessionState{usedOldKey: usedOldKey} + ok := hs.sessionState.unmarshal(plaintext) + if !ok { + return false + } + + // Never resume a session for a different TLS version. + if c.vers != hs.sessionState.vers { + return false + } + + cipherSuiteOk := false + // Check that the client is still offering the ciphersuite in the session. + for _, id := range hs.clientHello.cipherSuites { + if id == hs.sessionState.cipherSuite { + cipherSuiteOk = true + break + } + } + if !cipherSuiteOk { + return false + } + + // Check that we also support the ciphersuite from the session. + if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) { + return false + } + + sessionHasClientCerts := len(hs.sessionState.certificates) != 0 + needClientCerts := requiresClientCert(c.config.ClientAuth) + if needClientCerts && !sessionHasClientCerts { + return false + } + if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { + return false + } + + return true +} + +func (hs *serverHandshakeState) doResumeHandshake() error { + c := hs.c + + hs.hello.cipherSuite = hs.suite.id + // We echo the client's session ID in the ServerHello to let it know + // that we're doing a resumption. + hs.hello.sessionId = hs.clientHello.sessionId + hs.hello.ticketSupported = hs.sessionState.usedOldKey + hs.finishedHash = newFinishedHash(c.vers, hs.suite) + hs.finishedHash.discardHandshakeBuffer() + hs.finishedHash.Write(hs.clientHello.marshal()) + hs.finishedHash.Write(hs.hello.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { + return err + } + + if err := c.processCertsFromClient(Certificate{ + Certificate: hs.sessionState.certificates, + }); err != nil { + return err + } + + hs.masterSecret = hs.sessionState.masterSecret + + return nil +} + +func (hs *serverHandshakeState) doFullHandshake() error { + c := hs.c + + if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { + hs.hello.ocspStapling = true + } + + hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled + hs.hello.cipherSuite = hs.suite.id + + hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite) + if c.config.ClientAuth == NoClientCert { + // No need to keep a full record of the handshake if client + // certificates won't be used. + hs.finishedHash.discardHandshakeBuffer() + } + hs.finishedHash.Write(hs.clientHello.marshal()) + hs.finishedHash.Write(hs.hello.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { + return err + } + + certMsg := new(certificateMsg) + certMsg.certificates = hs.cert.Certificate + hs.finishedHash.Write(certMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { + return err + } + + if hs.hello.ocspStapling { + certStatus := new(certificateStatusMsg) + certStatus.response = hs.cert.OCSPStaple + hs.finishedHash.Write(certStatus.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { + return err + } + } + + keyAgreement := hs.suite.ka(c.vers) + skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello) + if err != nil { + c.sendAlert(alertHandshakeFailure) + return err + } + if skx != nil { + hs.finishedHash.Write(skx.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { + return err + } + } + + if c.config.ClientAuth >= RequestClientCert { + // Request a client certificate + certReq := new(certificateRequestMsg) + certReq.certificateTypes = []byte{ + byte(certTypeRSASign), + byte(certTypeECDSASign), + } + if c.vers >= VersionTLS12 { + certReq.hasSignatureAlgorithm = true + certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithmsTLS12 + } + + // An empty list of certificateAuthorities signals to + // the client that it may send any certificate in response + // to our request. When we know the CAs we trust, then + // we can send them down, so that the client can choose + // an appropriate certificate to give to us. + if c.config.ClientCAs != nil { + certReq.certificateAuthorities = c.config.ClientCAs.Subjects() + } + hs.finishedHash.Write(certReq.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { + return err + } + } + + helloDone := new(serverHelloDoneMsg) + hs.finishedHash.Write(helloDone.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { + return err + } + + if _, err := c.flush(); err != nil { + return err + } + + var pub crypto.PublicKey // public key for client auth, if any + + msg, err := c.readHandshake() + if err != nil { + return err + } + + // If we requested a client certificate, then the client must send a + // certificate message, even if it's empty. + if c.config.ClientAuth >= RequestClientCert { + certMsg, ok := msg.(*certificateMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } + hs.finishedHash.Write(certMsg.marshal()) + + if err := c.processCertsFromClient(Certificate{ + Certificate: certMsg.certificates, + }); err != nil { + return err + } + if len(certMsg.certificates) != 0 { + pub = c.peerCertificates[0].PublicKey + } + + msg, err = c.readHandshake() + if err != nil { + return err + } + } + + // Get client key exchange + ckx, ok := msg.(*clientKeyExchangeMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(ckx, msg) + } + hs.finishedHash.Write(ckx.marshal()) + + preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) + if err != nil { + c.sendAlert(alertHandshakeFailure) + return err + } + hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) + if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { + c.sendAlert(alertInternalError) + return err + } + + // If we received a client cert in response to our certificate request message, + // the client will send us a certificateVerifyMsg immediately after the + // clientKeyExchangeMsg. This message is a digest of all preceding + // handshake-layer messages that is signed using the private key corresponding + // to the client's certificate. This allows us to verify that the client is in + // possession of the private key of the certificate. + if len(c.peerCertificates) > 0 { + msg, err = c.readHandshake() + if err != nil { + return err + } + certVerify, ok := msg.(*certificateVerifyMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certVerify, msg) + } + + // Determine the signature type. + _, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithmsTLS12, c.vers) + if err != nil { + c.sendAlert(alertIllegalParameter) + return err + } + + var digest []byte + if digest, err = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret); err == nil { + err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature) + } + if err != nil { + c.sendAlert(alertBadCertificate) + return errors.New("tls: could not validate signature of connection nonces: " + err.Error()) + } + + hs.finishedHash.Write(certVerify.marshal()) + } + + hs.finishedHash.discardHandshakeBuffer() + + return nil +} + +func (hs *serverHandshakeState) establishKeys() error { + c := hs.c + + clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) + + var clientCipher, serverCipher interface{} + var clientHash, serverHash macFunction + + if hs.suite.aead == nil { + clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) + clientHash = hs.suite.mac(c.vers, clientMAC) + serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) + serverHash = hs.suite.mac(c.vers, serverMAC) + } else { + clientCipher = hs.suite.aead(clientKey, clientIV) + serverCipher = hs.suite.aead(serverKey, serverIV) + } + + c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) + c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) + + return nil +} + +func (hs *serverHandshakeState) readFinished(out []byte) error { + c := hs.c + + if err := c.readChangeCipherSpec(); err != nil { + return err + } + + if hs.hello.nextProtoNeg { + msg, err := c.readHandshake() + if err != nil { + return err + } + nextProto, ok := msg.(*nextProtoMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(nextProto, msg) + } + hs.finishedHash.Write(nextProto.marshal()) + c.clientProtocol = nextProto.proto + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + clientFinished, ok := msg.(*finishedMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(clientFinished, msg) + } + + verify := hs.finishedHash.clientSum(hs.masterSecret) + if len(verify) != len(clientFinished.verifyData) || + subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: client's Finished message is incorrect") + } + + hs.finishedHash.Write(clientFinished.marshal()) + copy(out, verify) + return nil +} + +func (hs *serverHandshakeState) sendSessionTicket() error { + if !hs.hello.ticketSupported { + return nil + } + + c := hs.c + m := new(newSessionTicketMsg) + + var certsFromClient [][]byte + for _, cert := range c.peerCertificates { + certsFromClient = append(certsFromClient, cert.Raw) + } + state := sessionState{ + vers: c.vers, + cipherSuite: hs.suite.id, + masterSecret: hs.masterSecret, + certificates: certsFromClient, + } + var err error + m.ticket, err = c.encryptTicket(state.marshal()) + if err != nil { + return err + } + + hs.finishedHash.Write(m.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { + return err + } + + return nil +} + +func (hs *serverHandshakeState) sendFinished(out []byte) error { + c := hs.c + + if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { + return err + } + + finished := new(finishedMsg) + finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) + hs.finishedHash.Write(finished.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { + return err + } + + c.cipherSuite = hs.suite.id + copy(out, finished.verifyData) + + return nil +} + +// processCertsFromClient takes a chain of client certificates either from a +// Certificates message or from a sessionState and verifies them. It returns +// the public key of the leaf certificate. +func (c *Conn) processCertsFromClient(certificate Certificate) error { + certificates := certificate.Certificate + certs := make([]*x509.Certificate, len(certificates)) + var err error + for i, asn1Data := range certificates { + if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { + c.sendAlert(alertBadCertificate) + return errors.New("tls: failed to parse client certificate: " + err.Error()) + } + } + + if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) { + c.sendAlert(alertBadCertificate) + return errors.New("tls: client didn't provide a certificate") + } + + if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { + opts := x509.VerifyOptions{ + Roots: c.config.ClientCAs, + CurrentTime: c.config.time(), + Intermediates: x509.NewCertPool(), + KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + } + + for _, cert := range certs[1:] { + opts.Intermediates.AddCert(cert) + } + + chains, err := certs[0].Verify(opts) + if err != nil { + c.sendAlert(alertBadCertificate) + return errors.New("tls: failed to verify client's certificate: " + err.Error()) + } + + c.verifiedChains = chains + } + + if c.config.VerifyPeerCertificate != nil { + if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + + if len(certs) == 0 { + return nil + } + + switch certs[0].PublicKey.(type) { + case *ecdsa.PublicKey, *rsa.PublicKey: + default: + c.sendAlert(alertUnsupportedCertificate) + return fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey) + } + + c.peerCertificates = certs + c.ocspResponse = certificate.OCSPStaple + c.scts = certificate.SignedCertificateTimestamps + return nil +} + +// setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState +// suite if that cipher suite is acceptable to use. +// It returns a bool indicating if the suite was set. +func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool { + for _, supported := range supportedCipherSuites { + if id == supported { + candidate := cipherSuiteByID(id) + if candidate == nil { + continue + } + // Don't select a ciphersuite which we can't + // support for this client. + if candidate.flags&suiteECDHE != 0 { + if !hs.ellipticOk { + continue + } + if candidate.flags&suiteECDSA != 0 { + if !hs.ecdsaOk { + continue + } + } else if !hs.rsaSignOk { + continue + } + } else if !hs.rsaDecryptOk { + continue + } + if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { + continue + } + hs.suite = candidate + return true + } + } + return false +} + +func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { + supportedVersions := clientHello.supportedVersions + if len(clientHello.supportedVersions) == 0 { + supportedVersions = supportedVersionsFromMax(clientHello.vers) + } + + return &ClientHelloInfo{ + CipherSuites: clientHello.cipherSuites, + ServerName: clientHello.serverName, + SupportedCurves: clientHello.supportedCurves, + SupportedPoints: clientHello.supportedPoints, + SignatureSchemes: clientHello.supportedSignatureAlgorithms, + SupportedProtos: clientHello.alpnProtocols, + SupportedVersions: supportedVersions, + Conn: c.conn, + } +} diff --git a/vendor/github.com/marten-seemann/qtls/handshake_server_tls13.go b/vendor/github.com/marten-seemann/qtls/handshake_server_tls13.go new file mode 100644 index 00000000..c7cce068 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/handshake_server_tls13.go @@ -0,0 +1,876 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "bytes" + "crypto" + "crypto/hmac" + "crypto/rsa" + "errors" + "hash" + "io" + "sync/atomic" + "time" +) + +// maxClientPSKIdentities is the number of client PSK identities the server will +// attempt to validate. It will ignore the rest not to let cheap ClientHello +// messages cause too much work in session ticket decryption attempts. +const maxClientPSKIdentities = 5 + +type serverHandshakeStateTLS13 struct { + c *Conn + clientHello *clientHelloMsg + hello *serverHelloMsg + sentDummyCCS bool + usingPSK bool + suite *cipherSuiteTLS13 + cert *Certificate + sigAlg SignatureScheme + earlySecret []byte + sharedKey []byte + handshakeSecret []byte + masterSecret []byte + trafficSecret []byte // client_application_traffic_secret_0 + transcript hash.Hash + clientFinished []byte +} + +func (hs *serverHandshakeStateTLS13) handshake() error { + c := hs.c + + // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. + if err := hs.processClientHello(); err != nil { + return err + } + if err := hs.checkForResumption(); err != nil { + return err + } + if err := hs.pickCertificate(); err != nil { + return err + } + c.buffering = true + if err := hs.sendServerParameters(); err != nil { + return err + } + if err := hs.sendServerCertificate(); err != nil { + return err + } + if err := hs.sendServerFinished(); err != nil { + return err + } + // Note that at this point we could start sending application data without + // waiting for the client's second flight, but the application might not + // expect the lack of replay protection of the ClientHello parameters. + if _, err := c.flush(); err != nil { + return err + } + if err := hs.readClientCertificate(); err != nil { + return err + } + if err := hs.readClientFinished(); err != nil { + return err + } + + atomic.StoreUint32(&c.handshakeStatus, 1) + + return nil +} + +func (hs *serverHandshakeStateTLS13) processClientHello() error { + c := hs.c + + hs.hello = new(serverHelloMsg) + + // TLS 1.3 froze the ServerHello.legacy_version field, and uses + // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. + hs.hello.vers = VersionTLS12 + hs.hello.supportedVersion = c.vers + + if len(hs.clientHello.supportedVersions) == 0 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: client used the legacy version field to negotiate TLS 1.3") + } + + // Abort if the client is doing a fallback and landing lower than what we + // support. See RFC 7507, which however does not specify the interaction + // with supported_versions. The only difference is that with + // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] + // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, + // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to + // TLS 1.2, because a TLS 1.3 server would abort here. The situation before + // supported_versions was not better because there was just no way to do a + // TLS 1.4 handshake without risking the server selecting TLS 1.3. + for _, id := range hs.clientHello.cipherSuites { + if id == TLS_FALLBACK_SCSV { + // Use c.vers instead of max(supported_versions) because an attacker + // could defeat this by adding an arbitrary high version otherwise. + if c.vers < c.config.maxSupportedVersion(false) { + c.sendAlert(alertInappropriateFallback) + return errors.New("tls: client using inappropriate protocol fallback") + } + break + } + } + + if len(hs.clientHello.compressionMethods) != 1 || + hs.clientHello.compressionMethods[0] != compressionNone { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: TLS 1.3 client supports illegal compression methods") + } + + hs.hello.random = make([]byte, 32) + if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { + c.sendAlert(alertInternalError) + return err + } + + if len(hs.clientHello.secureRenegotiation) != 0 { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: initial handshake had non-empty renegotiation extension") + } + + if hs.clientHello.earlyData { + // See RFC 8446, Section 4.2.10 for the complicated behavior required + // here. The scenario is that a different server at our address offered + // to accept early data in the past, which we can't handle. For now, all + // 0-RTT enabled session tickets need to expire before a Go server can + // replace a server or join a pool. That's the same requirement that + // applies to mixing or replacing with any TLS 1.2 server. + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: client sent unexpected early data") + } + + hs.hello.sessionId = hs.clientHello.sessionId + hs.hello.compressionMethod = compressionNone + + var preferenceList, supportedList []uint16 + if c.config.PreferServerCipherSuites { + preferenceList = defaultCipherSuitesTLS13() + supportedList = hs.clientHello.cipherSuites + } else { + preferenceList = hs.clientHello.cipherSuites + supportedList = defaultCipherSuitesTLS13() + } + for _, suiteID := range preferenceList { + hs.suite = mutualCipherSuiteTLS13(supportedList, suiteID) + if hs.suite != nil { + break + } + } + if hs.suite == nil { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: no cipher suite supported by both client and server") + } + c.cipherSuite = hs.suite.id + hs.hello.cipherSuite = hs.suite.id + hs.transcript = hs.suite.hash.New() + + // Pick the ECDHE group in server preference order, but give priority to + // groups with a key share, to avoid a HelloRetryRequest round-trip. + var selectedGroup CurveID + var clientKeyShare *keyShare +GroupSelection: + for _, preferredGroup := range c.config.curvePreferences() { + for _, ks := range hs.clientHello.keyShares { + if ks.group == preferredGroup { + selectedGroup = ks.group + clientKeyShare = &ks + break GroupSelection + } + } + if selectedGroup != 0 { + continue + } + for _, group := range hs.clientHello.supportedCurves { + if group == preferredGroup { + selectedGroup = group + break + } + } + } + if selectedGroup == 0 { + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: no ECDHE curve supported by both client and server") + } + if clientKeyShare == nil { + if err := hs.doHelloRetryRequest(selectedGroup); err != nil { + return err + } + clientKeyShare = &hs.clientHello.keyShares[0] + } + + if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok { + c.sendAlert(alertInternalError) + return errors.New("tls: CurvePreferences includes unsupported curve") + } + params, err := generateECDHEParameters(c.config.rand(), selectedGroup) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()} + hs.sharedKey = params.SharedKey(clientKeyShare.data) + if hs.sharedKey == nil { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid client key share") + } + + c.serverName = hs.clientHello.serverName + + if c.config.ReceivedExtensions != nil { + c.config.ReceivedExtensions(typeClientHello, hs.clientHello.additionalExtensions) + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) checkForResumption() error { + c := hs.c + + if c.config.SessionTicketsDisabled { + return nil + } + + modeOK := false + for _, mode := range hs.clientHello.pskModes { + if mode == pskModeDHE { + modeOK = true + break + } + } + if !modeOK { + return nil + } + + if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid or missing PSK binders") + } + if len(hs.clientHello.pskIdentities) == 0 { + return nil + } + + for i, identity := range hs.clientHello.pskIdentities { + if i >= maxClientPSKIdentities { + break + } + + plaintext, _ := c.decryptTicket(identity.label) + if plaintext == nil { + continue + } + sessionState := new(sessionStateTLS13) + if ok := sessionState.unmarshal(plaintext); !ok { + continue + } + + createdAt := time.Unix(int64(sessionState.createdAt), 0) + if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { + continue + } + + // We don't check the obfuscated ticket age because it's affected by + // clock skew and it's only a freshness signal useful for shrinking the + // window for replay attacks, which don't affect us as we don't do 0-RTT. + + pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) + if pskSuite == nil || pskSuite.hash != hs.suite.hash { + continue + } + + // PSK connections don't re-establish client certificates, but carry + // them over in the session ticket. Ensure the presence of client certs + // in the ticket is consistent with the configured requirements. + sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 + needClientCerts := requiresClientCert(c.config.ClientAuth) + if needClientCerts && !sessionHasClientCerts { + continue + } + if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { + continue + } + + psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption", + nil, hs.suite.hash.Size()) + hs.earlySecret = hs.suite.extract(psk, nil) + binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) + // Clone the transcript in case a HelloRetryRequest was recorded. + transcript := cloneHash(hs.transcript, hs.suite.hash) + if transcript == nil { + c.sendAlert(alertInternalError) + return errors.New("tls: internal error: failed to clone hash") + } + transcript.Write(hs.clientHello.marshalWithoutBinders()) + pskBinder := hs.suite.finishedHash(binderKey, transcript) + if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid PSK binder") + } + + if err := c.processCertsFromClient(sessionState.certificate); err != nil { + return err + } + + hs.hello.selectedIdentityPresent = true + hs.hello.selectedIdentity = uint16(i) + hs.usingPSK = true + c.didResume = true + return nil + } + + return nil +} + +// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler +// interfaces implemented by standard library hashes to clone the state of in +// to a new instance of h. It returns nil if the operation fails. +func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { + // Recreate the interface to avoid importing encoding. + type binaryMarshaler interface { + MarshalBinary() (data []byte, err error) + UnmarshalBinary(data []byte) error + } + marshaler, ok := in.(binaryMarshaler) + if !ok { + return nil + } + state, err := marshaler.MarshalBinary() + if err != nil { + return nil + } + out := h.New() + unmarshaler, ok := out.(binaryMarshaler) + if !ok { + return nil + } + if err := unmarshaler.UnmarshalBinary(state); err != nil { + return nil + } + return out +} + +func (hs *serverHandshakeStateTLS13) pickCertificate() error { + c := hs.c + + // Only one of PSK and certificates are used at a time. + if hs.usingPSK { + return nil + } + + // This implements a very simplistic certificate selection strategy for now: + // getCertificate delegates to the application Config.GetCertificate, or + // selects based on the server_name only. If the selected certificate's + // public key does not match the client signature_algorithms, the handshake + // is aborted. No attention is given to signature_algorithms_cert, and it is + // not passed to the application Config.GetCertificate. This will need to + // improve according to RFC 8446, sections 4.4.2.2 and 4.2.3. + certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + supportedAlgs := signatureSchemesForCertificate(c.vers, certificate) + if supportedAlgs == nil { + c.sendAlert(alertInternalError) + return unsupportedCertificateError(certificate) + } + // Pick signature scheme in client preference order, as the server + // preference order is not configurable. + for _, preferredAlg := range hs.clientHello.supportedSignatureAlgorithms { + if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { + hs.sigAlg = preferredAlg + break + } + } + if hs.sigAlg == 0 { + // getCertificate returned a certificate incompatible with the + // ClientHello supported signature algorithms. + c.sendAlert(alertHandshakeFailure) + return errors.New("tls: client doesn't support selected certificate") + } + hs.cert = certificate + + return nil +} + +// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility +// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. +func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { + if hs.sentDummyCCS { + return nil + } + hs.sentDummyCCS = true + + _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) + return err +} + +func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { + c := hs.c + + // The first ClientHello gets double-hashed into the transcript upon a + // HelloRetryRequest. See RFC 8446, Section 4.4.1. + hs.transcript.Write(hs.clientHello.marshal()) + chHash := hs.transcript.Sum(nil) + hs.transcript.Reset() + hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) + hs.transcript.Write(chHash) + + helloRetryRequest := &serverHelloMsg{ + vers: hs.hello.vers, + random: helloRetryRequestRandom, + sessionId: hs.hello.sessionId, + cipherSuite: hs.hello.cipherSuite, + compressionMethod: hs.hello.compressionMethod, + supportedVersion: hs.hello.supportedVersion, + selectedGroup: selectedGroup, + } + + hs.transcript.Write(helloRetryRequest.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { + return err + } + + if err := hs.sendDummyChangeCipherSpec(); err != nil { + return err + } + + msg, err := c.readHandshake() + if err != nil { + return err + } + + clientHello, ok := msg.(*clientHelloMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(clientHello, msg) + } + + if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: client sent invalid key share in second ClientHello") + } + + if clientHello.earlyData { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: client indicated early data in second ClientHello") + } + + if illegalClientHelloChange(clientHello, hs.clientHello) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: client illegally modified second ClientHello") + } + + hs.clientHello = clientHello + return nil +} + +// illegalClientHelloChange reports whether the two ClientHello messages are +// different, with the exception of the changes allowed before and after a +// HelloRetryRequest. See RFC 8446, Section 4.1.2. +func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { + if len(ch.supportedVersions) != len(ch1.supportedVersions) || + len(ch.cipherSuites) != len(ch1.cipherSuites) || + len(ch.supportedCurves) != len(ch1.supportedCurves) || + len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || + len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || + len(ch.alpnProtocols) != len(ch1.alpnProtocols) { + return true + } + for i := range ch.supportedVersions { + if ch.supportedVersions[i] != ch1.supportedVersions[i] { + return true + } + } + for i := range ch.cipherSuites { + if ch.cipherSuites[i] != ch1.cipherSuites[i] { + return true + } + } + for i := range ch.supportedCurves { + if ch.supportedCurves[i] != ch1.supportedCurves[i] { + return true + } + } + for i := range ch.supportedSignatureAlgorithms { + if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { + return true + } + } + for i := range ch.supportedSignatureAlgorithmsCert { + if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { + return true + } + } + for i := range ch.alpnProtocols { + if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { + return true + } + } + return ch.vers != ch1.vers || + !bytes.Equal(ch.random, ch1.random) || + !bytes.Equal(ch.sessionId, ch1.sessionId) || + !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || + ch.nextProtoNeg != ch1.nextProtoNeg || + ch.serverName != ch1.serverName || + ch.ocspStapling != ch1.ocspStapling || + !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || + ch.ticketSupported != ch1.ticketSupported || + !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || + ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || + !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || + ch.scts != ch1.scts || + !bytes.Equal(ch.cookie, ch1.cookie) || + !bytes.Equal(ch.pskModes, ch1.pskModes) +} + +func (hs *serverHandshakeStateTLS13) sendServerParameters() error { + c := hs.c + + hs.transcript.Write(hs.clientHello.marshal()) + hs.transcript.Write(hs.hello.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { + return err + } + + if err := hs.sendDummyChangeCipherSpec(); err != nil { + return err + } + + earlySecret := hs.earlySecret + if earlySecret == nil { + earlySecret = hs.suite.extract(nil, nil) + } + hs.handshakeSecret = hs.suite.extract(hs.sharedKey, + hs.suite.deriveSecret(earlySecret, "derived", nil)) + + clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, + clientHandshakeTrafficLabel, hs.transcript) + c.in.exportKey(hs.suite, clientSecret) + c.in.setTrafficSecret(hs.suite, clientSecret) + serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, + serverHandshakeTrafficLabel, hs.transcript) + c.out.exportKey(hs.suite, serverSecret) + c.out.setTrafficSecret(hs.suite, serverSecret) + + err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + encryptedExtensions := new(encryptedExtensionsMsg) + + if len(hs.clientHello.alpnProtocols) > 0 { + if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { + encryptedExtensions.alpnProtocol = selectedProto + c.clientProtocol = selectedProto + } + } + if c.config.EnforceNextProtoSelection && len(c.clientProtocol) == 0 { + c.sendAlert(alertNoApplicationProtocol) + return errors.New("ALPN negotiation failed") + } + if hs.c.config.GetExtensions != nil { + encryptedExtensions.additionalExtensions = hs.c.config.GetExtensions(typeEncryptedExtensions) + } + + hs.transcript.Write(encryptedExtensions.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil { + return err + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) requestClientCert() bool { + return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK +} + +func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { + c := hs.c + + // Only one of PSK and certificates are used at a time. + if hs.usingPSK { + return nil + } + + if hs.requestClientCert() { + // Request a client certificate + certReq := new(certificateRequestMsgTLS13) + certReq.ocspStapling = true + certReq.scts = true + certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms + if c.config.ClientCAs != nil { + certReq.certificateAuthorities = c.config.ClientCAs.Subjects() + } + + hs.transcript.Write(certReq.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { + return err + } + } + + certMsg := new(certificateMsgTLS13) + + certMsg.certificate = *hs.cert + certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 + certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 + + hs.transcript.Write(certMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { + return err + } + + certVerifyMsg := new(certificateVerifyMsg) + certVerifyMsg.hasSignatureAlgorithm = true + certVerifyMsg.signatureAlgorithm = hs.sigAlg + + sigType := signatureFromSignatureScheme(hs.sigAlg) + sigHash, err := hashFromSignatureScheme(hs.sigAlg) + if sigType == 0 || err != nil { + return c.sendAlert(alertInternalError) + } + h := sigHash.New() + writeSignedMessage(h, serverSignatureContext, hs.transcript) + + signOpts := crypto.SignerOpts(sigHash) + if sigType == signatureRSAPSS { + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} + } + sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), h.Sum(nil), signOpts) + if err != nil { + public := hs.cert.PrivateKey.(crypto.Signer).Public() + if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && + rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS + c.sendAlert(alertHandshakeFailure) + } else { + c.sendAlert(alertInternalError) + } + return errors.New("tls: failed to sign handshake: " + err.Error()) + } + certVerifyMsg.signature = sig + + hs.transcript.Write(certVerifyMsg.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { + return err + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) sendServerFinished() error { + c := hs.c + + finished := &finishedMsg{ + verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), + } + + hs.transcript.Write(finished.marshal()) + if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { + return err + } + + // Derive secrets that take context through the server Finished. + + hs.masterSecret = hs.suite.extract(nil, + hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) + + hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, + clientApplicationTrafficLabel, hs.transcript) + serverSecret := hs.suite.deriveSecret(hs.masterSecret, + serverApplicationTrafficLabel, hs.transcript) + c.out.exportKey(hs.suite, serverSecret) + c.out.setTrafficSecret(hs.suite, serverSecret) + + err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + + c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) + + // If we did not request client certificates, at this point we can + // precompute the client finished and roll the transcript forward to send + // session tickets in our first flight. + if !hs.requestClientCert() { + if err := hs.sendSessionTickets(); err != nil { + return err + } + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { + if hs.c.config.SessionTicketsDisabled { + return false + } + + // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. + for _, pskMode := range hs.clientHello.pskModes { + if pskMode == pskModeDHE { + return true + } + } + return false +} + +func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { + c := hs.c + + hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) + finishedMsg := &finishedMsg{ + verifyData: hs.clientFinished, + } + hs.transcript.Write(finishedMsg.marshal()) + + if !hs.shouldSendSessionTickets() { + return nil + } + + resumptionSecret := hs.suite.deriveSecret(hs.masterSecret, + resumptionLabel, hs.transcript) + + m := new(newSessionTicketMsgTLS13) + + var certsFromClient [][]byte + for _, cert := range c.peerCertificates { + certsFromClient = append(certsFromClient, cert.Raw) + } + state := sessionStateTLS13{ + cipherSuite: hs.suite.id, + createdAt: uint64(c.config.time().Unix()), + resumptionSecret: resumptionSecret, + certificate: Certificate{ + Certificate: certsFromClient, + OCSPStaple: c.ocspResponse, + SignedCertificateTimestamps: c.scts, + }, + } + var err error + m.label, err = c.encryptTicket(state.marshal()) + if err != nil { + return err + } + m.lifetime = uint32(maxSessionTicketLifetime / time.Second) + + if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { + return err + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) readClientCertificate() error { + c := hs.c + + if !hs.requestClientCert() { + return nil + } + + // If we requested a client certificate, then the client must send a + // certificate message. If it's empty, no CertificateVerify is sent. + + msg, err := c.readHandshake() + if err != nil { + return err + } + + certMsg, ok := msg.(*certificateMsgTLS13) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certMsg, msg) + } + hs.transcript.Write(certMsg.marshal()) + + if err := c.processCertsFromClient(certMsg.certificate); err != nil { + return err + } + + if len(certMsg.certificate.Certificate) != 0 { + msg, err = c.readHandshake() + if err != nil { + return err + } + + certVerify, ok := msg.(*certificateVerifyMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(certVerify, msg) + } + + // See RFC 8446, Section 4.4.3. + if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid certificate signature algorithm") + } + sigType := signatureFromSignatureScheme(certVerify.signatureAlgorithm) + sigHash, err := hashFromSignatureScheme(certVerify.signatureAlgorithm) + if sigType == 0 || err != nil { + c.sendAlert(alertInternalError) + return err + } + if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: invalid certificate signature algorithm") + } + h := sigHash.New() + writeSignedMessage(h, clientSignatureContext, hs.transcript) + if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, + sigHash, h.Sum(nil), certVerify.signature); err != nil { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid certificate signature") + } + + hs.transcript.Write(certVerify.marshal()) + } + + // If we waited until the client certificates to send session tickets, we + // are ready to do it now. + if err := hs.sendSessionTickets(); err != nil { + return err + } + + return nil +} + +func (hs *serverHandshakeStateTLS13) readClientFinished() error { + c := hs.c + + msg, err := c.readHandshake() + if err != nil { + return err + } + + finished, ok := msg.(*finishedMsg) + if !ok { + c.sendAlert(alertUnexpectedMessage) + return unexpectedMessageError(finished, msg) + } + + if !hmac.Equal(hs.clientFinished, finished.verifyData) { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid client finished hash") + } + + c.in.exportKey(hs.suite, hs.trafficSecret) + c.in.setTrafficSecret(hs.suite, hs.trafficSecret) + + return nil +} diff --git a/vendor/github.com/marten-seemann/qtls/key_agreement.go b/vendor/github.com/marten-seemann/qtls/key_agreement.go new file mode 100644 index 00000000..477aae4a --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/key_agreement.go @@ -0,0 +1,313 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/md5" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "errors" + "io" +) + +var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") +var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") + +// rsaKeyAgreement implements the standard TLS key agreement where the client +// encrypts the pre-master secret to the server's public key. +type rsaKeyAgreement struct{} + +func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { + return nil, nil +} + +func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { + if len(ckx.ciphertext) < 2 { + return nil, errClientKeyExchange + } + + ciphertext := ckx.ciphertext + if version != VersionSSL30 { + ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) + if ciphertextLen != len(ckx.ciphertext)-2 { + return nil, errClientKeyExchange + } + ciphertext = ckx.ciphertext[2:] + } + priv, ok := cert.PrivateKey.(crypto.Decrypter) + if !ok { + return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") + } + // Perform constant time RSA PKCS#1 v1.5 decryption + preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) + if err != nil { + return nil, err + } + // We don't check the version number in the premaster secret. For one, + // by checking it, we would leak information about the validity of the + // encrypted pre-master secret. Secondly, it provides only a small + // benefit against a downgrade attack and some implementations send the + // wrong version anyway. See the discussion at the end of section + // 7.4.7.1 of RFC 4346. + return preMasterSecret, nil +} + +func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { + return errors.New("tls: unexpected ServerKeyExchange") +} + +func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { + preMasterSecret := make([]byte, 48) + preMasterSecret[0] = byte(clientHello.vers >> 8) + preMasterSecret[1] = byte(clientHello.vers) + _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) + if err != nil { + return nil, nil, err + } + + encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) + if err != nil { + return nil, nil, err + } + ckx := new(clientKeyExchangeMsg) + ckx.ciphertext = make([]byte, len(encrypted)+2) + ckx.ciphertext[0] = byte(len(encrypted) >> 8) + ckx.ciphertext[1] = byte(len(encrypted)) + copy(ckx.ciphertext[2:], encrypted) + return preMasterSecret, ckx, nil +} + +// sha1Hash calculates a SHA1 hash over the given byte slices. +func sha1Hash(slices [][]byte) []byte { + hsha1 := sha1.New() + for _, slice := range slices { + hsha1.Write(slice) + } + return hsha1.Sum(nil) +} + +// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the +// concatenation of an MD5 and SHA1 hash. +func md5SHA1Hash(slices [][]byte) []byte { + md5sha1 := make([]byte, md5.Size+sha1.Size) + hmd5 := md5.New() + for _, slice := range slices { + hmd5.Write(slice) + } + copy(md5sha1, hmd5.Sum(nil)) + copy(md5sha1[md5.Size:], sha1Hash(slices)) + return md5sha1 +} + +// hashForServerKeyExchange hashes the given slices and returns their digest +// using the given hash function (for >= TLS 1.2) or using a default based on +// the sigType (for earlier TLS versions). +func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) ([]byte, error) { + if version >= VersionTLS12 { + h := hashFunc.New() + for _, slice := range slices { + h.Write(slice) + } + digest := h.Sum(nil) + return digest, nil + } + if sigType == signatureECDSA { + return sha1Hash(slices), nil + } + return md5SHA1Hash(slices), nil +} + +// ecdheKeyAgreement implements a TLS key agreement where the server +// generates an ephemeral EC public/private key pair and signs it. The +// pre-master secret is then calculated using ECDH. The signature may +// either be ECDSA or RSA. +type ecdheKeyAgreement struct { + version uint16 + isRSA bool + params ecdheParameters + + // ckx and preMasterSecret are generated in processServerKeyExchange + // and returned in generateClientKeyExchange. + ckx *clientKeyExchangeMsg + preMasterSecret []byte +} + +func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { + preferredCurves := config.curvePreferences() + + var curveID CurveID +NextCandidate: + for _, candidate := range preferredCurves { + for _, c := range clientHello.supportedCurves { + if candidate == c { + curveID = c + break NextCandidate + } + } + } + + if curveID == 0 { + return nil, errors.New("tls: no supported elliptic curves offered") + } + if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { + return nil, errors.New("tls: CurvePreferences includes unsupported curve") + } + + params, err := generateECDHEParameters(config.rand(), curveID) + if err != nil { + return nil, err + } + ka.params = params + + // See RFC 4492, Section 5.4. + ecdhePublic := params.PublicKey() + serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) + serverECDHParams[0] = 3 // named curve + serverECDHParams[1] = byte(curveID >> 8) + serverECDHParams[2] = byte(curveID) + serverECDHParams[3] = byte(len(ecdhePublic)) + copy(serverECDHParams[4:], ecdhePublic) + + priv, ok := cert.PrivateKey.(crypto.Signer) + if !ok { + return nil, errors.New("tls: certificate private key does not implement crypto.Signer") + } + + signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(priv.Public(), clientHello.supportedSignatureAlgorithms, supportedSignatureAlgorithmsTLS12, ka.version) + if err != nil { + return nil, err + } + if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { + return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") + } + + digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams) + if err != nil { + return nil, err + } + + signOpts := crypto.SignerOpts(hashFunc) + if sigType == signatureRSAPSS { + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc} + } + sig, err := priv.Sign(config.rand(), digest, signOpts) + if err != nil { + return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) + } + + skx := new(serverKeyExchangeMsg) + sigAndHashLen := 0 + if ka.version >= VersionTLS12 { + sigAndHashLen = 2 + } + skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) + copy(skx.key, serverECDHParams) + k := skx.key[len(serverECDHParams):] + if ka.version >= VersionTLS12 { + k[0] = byte(signatureAlgorithm >> 8) + k[1] = byte(signatureAlgorithm) + k = k[2:] + } + k[0] = byte(len(sig) >> 8) + k[1] = byte(len(sig)) + copy(k[2:], sig) + + return skx, nil +} + +func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { + if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { + return nil, errClientKeyExchange + } + + preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:]) + if preMasterSecret == nil { + return nil, errClientKeyExchange + } + + return preMasterSecret, nil +} + +func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { + if len(skx.key) < 4 { + return errServerKeyExchange + } + if skx.key[0] != 3 { // named curve + return errors.New("tls: server selected unsupported curve") + } + curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) + + publicLen := int(skx.key[3]) + if publicLen+4 > len(skx.key) { + return errServerKeyExchange + } + serverECDHParams := skx.key[:4+publicLen] + publicKey := serverECDHParams[4:] + + sig := skx.key[4+publicLen:] + if len(sig) < 2 { + return errServerKeyExchange + } + + if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { + return errors.New("tls: server selected unsupported curve") + } + + params, err := generateECDHEParameters(config.rand(), curveID) + if err != nil { + return err + } + ka.params = params + + ka.preMasterSecret = params.SharedKey(publicKey) + if ka.preMasterSecret == nil { + return errServerKeyExchange + } + + ourPublicKey := params.PublicKey() + ka.ckx = new(clientKeyExchangeMsg) + ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey)) + ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) + copy(ka.ckx.ciphertext[1:], ourPublicKey) + + var signatureAlgorithm SignatureScheme + if ka.version >= VersionTLS12 { + // handle SignatureAndHashAlgorithm + signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) + sig = sig[2:] + if len(sig) < 2 { + return errServerKeyExchange + } + } + _, sigType, hashFunc, err := pickSignatureAlgorithm(cert.PublicKey, []SignatureScheme{signatureAlgorithm}, clientHello.supportedSignatureAlgorithms, ka.version) + if err != nil { + return err + } + if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { + return errServerKeyExchange + } + + sigLen := int(sig[0])<<8 | int(sig[1]) + if sigLen+2 != len(sig) { + return errServerKeyExchange + } + sig = sig[2:] + + digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams) + if err != nil { + return err + } + return verifyHandshakeSignature(sigType, cert.PublicKey, hashFunc, digest, sig) +} + +func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { + if ka.ckx == nil { + return nil, nil, errors.New("tls: missing ServerKeyExchange message") + } + + return ka.preMasterSecret, ka.ckx, nil +} diff --git a/vendor/github.com/marten-seemann/qtls/key_schedule.go b/vendor/github.com/marten-seemann/qtls/key_schedule.go new file mode 100644 index 00000000..24bae2e6 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/key_schedule.go @@ -0,0 +1,216 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/elliptic" + "crypto/hmac" + "errors" + "hash" + "io" + "math/big" + + "golang.org/x/crypto/cryptobyte" + "golang.org/x/crypto/curve25519" + "golang.org/x/crypto/hkdf" +) + +// This file contains the functions necessary to compute the TLS 1.3 key +// schedule. See RFC 8446, Section 7. + +const ( + resumptionBinderLabel = "res binder" + clientHandshakeTrafficLabel = "c hs traffic" + serverHandshakeTrafficLabel = "s hs traffic" + clientApplicationTrafficLabel = "c ap traffic" + serverApplicationTrafficLabel = "s ap traffic" + exporterLabel = "exp master" + resumptionLabel = "res master" + trafficUpdateLabel = "traffic upd" +) + +// HkdfExtract generates a pseudorandom key for use with Expand from an input secret and an optional independent salt. +func HkdfExtract(hash crypto.Hash, newSecret, currentSecret []byte) []byte { + if newSecret == nil { + newSecret = make([]byte, hash.Size()) + } + return hkdf.Extract(hash.New, newSecret, currentSecret) +} + +// HkdfExpandLabel HKDF expands a label +func HkdfExpandLabel(hash crypto.Hash, secret, hashValue []byte, label string, L int) []byte { + return hkdfExpandLabel(hash, secret, hashValue, label, L) +} + +func hkdfExpandLabel(hash crypto.Hash, secret, context []byte, label string, length int) []byte { + var hkdfLabel cryptobyte.Builder + hkdfLabel.AddUint16(uint16(length)) + hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte("tls13 ")) + b.AddBytes([]byte(label)) + }) + hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(context) + }) + out := make([]byte, length) + n, err := hkdf.Expand(hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out) + if err != nil || n != length { + panic("tls: HKDF-Expand-Label invocation failed unexpectedly") + } + return out +} + +// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1. +func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte { + return hkdfExpandLabel(c.hash, secret, context, label, length) +} + +// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1. +func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte { + if transcript == nil { + transcript = c.hash.New() + } + return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size()) +} + +// extract implements HKDF-Extract with the cipher suite hash. +func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { + return HkdfExtract(c.hash, newSecret, currentSecret) +} + +// nextTrafficSecret generates the next traffic secret, given the current one, +// according to RFC 8446, Section 7.2. +func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte { + return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size()) +} + +// trafficKey generates traffic keys according to RFC 8446, Section 7.3. +func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { + key = c.expandLabel(trafficSecret, "key", nil, c.keyLen) + iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength) + return +} + +// finishedHash generates the Finished verify_data or PskBinderEntry according +// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey +// selection. +func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte { + finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size()) + verifyData := hmac.New(c.hash.New, finishedKey) + verifyData.Write(transcript.Sum(nil)) + return verifyData.Sum(nil) +} + +// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to +// RFC 8446, Section 7.5. +func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) { + expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript) + return func(label string, context []byte, length int) ([]byte, error) { + secret := c.deriveSecret(expMasterSecret, label, nil) + h := c.hash.New() + h.Write(context) + return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil + } +} + +// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519, +// according to RFC 8446, Section 4.2.8.2. +type ecdheParameters interface { + CurveID() CurveID + PublicKey() []byte + SharedKey(peerPublicKey []byte) []byte +} + +func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) { + if curveID == X25519 { + p := &x25519Parameters{} + if _, err := io.ReadFull(rand, p.privateKey[:]); err != nil { + return nil, err + } + curve25519.ScalarBaseMult(&p.publicKey, &p.privateKey) + return p, nil + } + + curve, ok := curveForCurveID(curveID) + if !ok { + return nil, errors.New("tls: internal error: unsupported curve") + } + + p := &nistParameters{curveID: curveID} + var err error + p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand) + if err != nil { + return nil, err + } + return p, nil +} + +func curveForCurveID(id CurveID) (elliptic.Curve, bool) { + switch id { + case CurveP256: + return elliptic.P256(), true + case CurveP384: + return elliptic.P384(), true + case CurveP521: + return elliptic.P521(), true + default: + return nil, false + } +} + +type nistParameters struct { + privateKey []byte + x, y *big.Int // public key + curveID CurveID +} + +func (p *nistParameters) CurveID() CurveID { + return p.curveID +} + +func (p *nistParameters) PublicKey() []byte { + curve, _ := curveForCurveID(p.curveID) + return elliptic.Marshal(curve, p.x, p.y) +} + +func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { + curve, _ := curveForCurveID(p.curveID) + // Unmarshal also checks whether the given point is on the curve. + x, y := elliptic.Unmarshal(curve, peerPublicKey) + if x == nil { + return nil + } + + xShared, _ := curve.ScalarMult(x, y, p.privateKey) + sharedKey := make([]byte, (curve.Params().BitSize+7)>>3) + xBytes := xShared.Bytes() + copy(sharedKey[len(sharedKey)-len(xBytes):], xBytes) + + return sharedKey +} + +type x25519Parameters struct { + privateKey [32]byte + publicKey [32]byte +} + +func (p *x25519Parameters) CurveID() CurveID { + return X25519 +} + +func (p *x25519Parameters) PublicKey() []byte { + return p.publicKey[:] +} + +func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte { + if len(peerPublicKey) != 32 { + return nil + } + var theirPublicKey, sharedKey [32]byte + copy(theirPublicKey[:], peerPublicKey) + curve25519.ScalarMult(&sharedKey, &p.privateKey, &theirPublicKey) + return sharedKey[:] +} diff --git a/vendor/github.com/marten-seemann/qtls/prf.go b/vendor/github.com/marten-seemann/qtls/prf.go new file mode 100644 index 00000000..a973d6ad --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/prf.go @@ -0,0 +1,385 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "crypto" + "crypto/hmac" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "errors" + "fmt" + "hash" +) + +// Split a premaster secret in two as specified in RFC 4346, Section 5. +func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { + s1 = secret[0 : (len(secret)+1)/2] + s2 = secret[len(secret)/2:] + return +} + +// pHash implements the P_hash function, as defined in RFC 4346, Section 5. +func pHash(result, secret, seed []byte, hash func() hash.Hash) { + h := hmac.New(hash, secret) + h.Write(seed) + a := h.Sum(nil) + + j := 0 + for j < len(result) { + h.Reset() + h.Write(a) + h.Write(seed) + b := h.Sum(nil) + copy(result[j:], b) + j += len(b) + + h.Reset() + h.Write(a) + a = h.Sum(nil) + } +} + +// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. +func prf10(result, secret, label, seed []byte) { + hashSHA1 := sha1.New + hashMD5 := md5.New + + labelAndSeed := make([]byte, len(label)+len(seed)) + copy(labelAndSeed, label) + copy(labelAndSeed[len(label):], seed) + + s1, s2 := splitPreMasterSecret(secret) + pHash(result, s1, labelAndSeed, hashMD5) + result2 := make([]byte, len(result)) + pHash(result2, s2, labelAndSeed, hashSHA1) + + for i, b := range result2 { + result[i] ^= b + } +} + +// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. +func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { + return func(result, secret, label, seed []byte) { + labelAndSeed := make([]byte, len(label)+len(seed)) + copy(labelAndSeed, label) + copy(labelAndSeed[len(label):], seed) + + pHash(result, secret, labelAndSeed, hashFunc) + } +} + +// prf30 implements the SSL 3.0 pseudo-random function, as defined in +// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. +func prf30(result, secret, label, seed []byte) { + hashSHA1 := sha1.New() + hashMD5 := md5.New() + + done := 0 + i := 0 + // RFC 5246 section 6.3 says that the largest PRF output needed is 128 + // bytes. Since no more ciphersuites will be added to SSLv3, this will + // remain true. Each iteration gives us 16 bytes so 10 iterations will + // be sufficient. + var b [11]byte + for done < len(result) { + for j := 0; j <= i; j++ { + b[j] = 'A' + byte(i) + } + + hashSHA1.Reset() + hashSHA1.Write(b[:i+1]) + hashSHA1.Write(secret) + hashSHA1.Write(seed) + digest := hashSHA1.Sum(nil) + + hashMD5.Reset() + hashMD5.Write(secret) + hashMD5.Write(digest) + + done += copy(result[done:], hashMD5.Sum(nil)) + i++ + } +} + +const ( + masterSecretLength = 48 // Length of a master secret in TLS 1.1. + finishedVerifyLength = 12 // Length of verify_data in a Finished message. +) + +var masterSecretLabel = []byte("master secret") +var keyExpansionLabel = []byte("key expansion") +var clientFinishedLabel = []byte("client finished") +var serverFinishedLabel = []byte("server finished") + +func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { + switch version { + case VersionSSL30: + return prf30, crypto.Hash(0) + case VersionTLS10, VersionTLS11: + return prf10, crypto.Hash(0) + case VersionTLS12: + if suite.flags&suiteSHA384 != 0 { + return prf12(sha512.New384), crypto.SHA384 + } + return prf12(sha256.New), crypto.SHA256 + default: + panic("unknown version") + } +} + +func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { + prf, _ := prfAndHashForVersion(version, suite) + return prf +} + +// masterFromPreMasterSecret generates the master secret from the pre-master +// secret. See RFC 5246, Section 8.1. +func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { + seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) + seed = append(seed, clientRandom...) + seed = append(seed, serverRandom...) + + masterSecret := make([]byte, masterSecretLength) + prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) + return masterSecret +} + +// keysFromMasterSecret generates the connection keys from the master +// secret, given the lengths of the MAC key, cipher key and IV, as defined in +// RFC 2246, Section 6.3. +func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { + seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) + seed = append(seed, serverRandom...) + seed = append(seed, clientRandom...) + + n := 2*macLen + 2*keyLen + 2*ivLen + keyMaterial := make([]byte, n) + prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) + clientMAC = keyMaterial[:macLen] + keyMaterial = keyMaterial[macLen:] + serverMAC = keyMaterial[:macLen] + keyMaterial = keyMaterial[macLen:] + clientKey = keyMaterial[:keyLen] + keyMaterial = keyMaterial[keyLen:] + serverKey = keyMaterial[:keyLen] + keyMaterial = keyMaterial[keyLen:] + clientIV = keyMaterial[:ivLen] + keyMaterial = keyMaterial[ivLen:] + serverIV = keyMaterial[:ivLen] + return +} + +// hashFromSignatureScheme returns the corresponding crypto.Hash for a given +// hash from a TLS SignatureScheme. +func hashFromSignatureScheme(signatureAlgorithm SignatureScheme) (crypto.Hash, error) { + switch signatureAlgorithm { + case PKCS1WithSHA1, ECDSAWithSHA1: + return crypto.SHA1, nil + case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: + return crypto.SHA256, nil + case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: + return crypto.SHA384, nil + case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: + return crypto.SHA512, nil + default: + return 0, fmt.Errorf("tls: unsupported signature algorithm: %#04x", signatureAlgorithm) + } +} + +func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { + var buffer []byte + if version == VersionSSL30 || version >= VersionTLS12 { + buffer = []byte{} + } + + prf, hash := prfAndHashForVersion(version, cipherSuite) + if hash != 0 { + return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf} + } + + return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf} +} + +// A finishedHash calculates the hash of a set of handshake messages suitable +// for including in a Finished message. +type finishedHash struct { + client hash.Hash + server hash.Hash + + // Prior to TLS 1.2, an additional MD5 hash is required. + clientMD5 hash.Hash + serverMD5 hash.Hash + + // In TLS 1.2, a full buffer is sadly required. + buffer []byte + + version uint16 + prf func(result, secret, label, seed []byte) +} + +func (h *finishedHash) Write(msg []byte) (n int, err error) { + h.client.Write(msg) + h.server.Write(msg) + + if h.version < VersionTLS12 { + h.clientMD5.Write(msg) + h.serverMD5.Write(msg) + } + + if h.buffer != nil { + h.buffer = append(h.buffer, msg...) + } + + return len(msg), nil +} + +func (h finishedHash) Sum() []byte { + if h.version >= VersionTLS12 { + return h.client.Sum(nil) + } + + out := make([]byte, 0, md5.Size+sha1.Size) + out = h.clientMD5.Sum(out) + return h.client.Sum(out) +} + +// finishedSum30 calculates the contents of the verify_data member of a SSLv3 +// Finished message given the MD5 and SHA1 hashes of a set of handshake +// messages. +func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic []byte) []byte { + md5.Write(magic) + md5.Write(masterSecret) + md5.Write(ssl30Pad1[:]) + md5Digest := md5.Sum(nil) + + md5.Reset() + md5.Write(masterSecret) + md5.Write(ssl30Pad2[:]) + md5.Write(md5Digest) + md5Digest = md5.Sum(nil) + + sha1.Write(magic) + sha1.Write(masterSecret) + sha1.Write(ssl30Pad1[:40]) + sha1Digest := sha1.Sum(nil) + + sha1.Reset() + sha1.Write(masterSecret) + sha1.Write(ssl30Pad2[:40]) + sha1.Write(sha1Digest) + sha1Digest = sha1.Sum(nil) + + ret := make([]byte, len(md5Digest)+len(sha1Digest)) + copy(ret, md5Digest) + copy(ret[len(md5Digest):], sha1Digest) + return ret +} + +var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54} +var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} + +// clientSum returns the contents of the verify_data member of a client's +// Finished message. +func (h finishedHash) clientSum(masterSecret []byte) []byte { + if h.version == VersionSSL30 { + return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic[:]) + } + + out := make([]byte, finishedVerifyLength) + h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) + return out +} + +// serverSum returns the contents of the verify_data member of a server's +// Finished message. +func (h finishedHash) serverSum(masterSecret []byte) []byte { + if h.version == VersionSSL30 { + return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic[:]) + } + + out := make([]byte, finishedVerifyLength) + h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) + return out +} + +// hashForClientCertificate returns a digest over the handshake messages so far, +// suitable for signing by a TLS client certificate. +func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) ([]byte, error) { + if (h.version == VersionSSL30 || h.version >= VersionTLS12) && h.buffer == nil { + panic("a handshake hash for a client-certificate was requested after discarding the handshake buffer") + } + + if h.version == VersionSSL30 { + if sigType != signaturePKCS1v15 { + return nil, errors.New("tls: unsupported signature type for client certificate") + } + + md5Hash := md5.New() + md5Hash.Write(h.buffer) + sha1Hash := sha1.New() + sha1Hash.Write(h.buffer) + return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), nil + } + if h.version >= VersionTLS12 { + hash := hashAlg.New() + hash.Write(h.buffer) + return hash.Sum(nil), nil + } + + if sigType == signatureECDSA { + return h.server.Sum(nil), nil + } + + return h.Sum(), nil +} + +// discardHandshakeBuffer is called when there is no more need to +// buffer the entirety of the handshake messages. +func (h *finishedHash) discardHandshakeBuffer() { + h.buffer = nil +} + +// noExportedKeyingMaterial is used as a value of +// ConnectionState.ekm when renegotation is enabled and thus +// we wish to fail all key-material export requests. +func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { + return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") +} + +// ekmFromMasterSecret generates exported keying material as defined in RFC 5705. +func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { + return func(label string, context []byte, length int) ([]byte, error) { + switch label { + case "client finished", "server finished", "master secret", "key expansion": + // These values are reserved and may not be used. + return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) + } + + seedLen := len(serverRandom) + len(clientRandom) + if context != nil { + seedLen += 2 + len(context) + } + seed := make([]byte, 0, seedLen) + + seed = append(seed, clientRandom...) + seed = append(seed, serverRandom...) + + if context != nil { + if len(context) >= 1<<16 { + return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") + } + seed = append(seed, byte(len(context)>>8), byte(len(context))) + seed = append(seed, context...) + } + + keyMaterial := make([]byte, length) + prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) + return keyMaterial, nil + } +} diff --git a/vendor/github.com/marten-seemann/qtls/ticket.go b/vendor/github.com/marten-seemann/qtls/ticket.go new file mode 100644 index 00000000..989c9787 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/ticket.go @@ -0,0 +1,215 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package qtls + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/hmac" + "crypto/sha256" + "crypto/subtle" + "errors" + "io" + + "golang.org/x/crypto/cryptobyte" +) + +// sessionState contains the information that is serialized into a session +// ticket in order to later resume a connection. +type sessionState struct { + vers uint16 + cipherSuite uint16 + masterSecret []byte + certificates [][]byte + // usedOldKey is true if the ticket from which this session came from + // was encrypted with an older key and thus should be refreshed. + usedOldKey bool +} + +func (s *sessionState) marshal() []byte { + length := 2 + 2 + 2 + len(s.masterSecret) + 2 + for _, cert := range s.certificates { + length += 4 + len(cert) + } + + ret := make([]byte, length) + x := ret + x[0] = byte(s.vers >> 8) + x[1] = byte(s.vers) + x[2] = byte(s.cipherSuite >> 8) + x[3] = byte(s.cipherSuite) + x[4] = byte(len(s.masterSecret) >> 8) + x[5] = byte(len(s.masterSecret)) + x = x[6:] + copy(x, s.masterSecret) + x = x[len(s.masterSecret):] + + x[0] = byte(len(s.certificates) >> 8) + x[1] = byte(len(s.certificates)) + x = x[2:] + + for _, cert := range s.certificates { + x[0] = byte(len(cert) >> 24) + x[1] = byte(len(cert) >> 16) + x[2] = byte(len(cert) >> 8) + x[3] = byte(len(cert)) + copy(x[4:], cert) + x = x[4+len(cert):] + } + + return ret +} + +func (s *sessionState) unmarshal(data []byte) bool { + if len(data) < 8 { + return false + } + + s.vers = uint16(data[0])<<8 | uint16(data[1]) + s.cipherSuite = uint16(data[2])<<8 | uint16(data[3]) + masterSecretLen := int(data[4])<<8 | int(data[5]) + data = data[6:] + if len(data) < masterSecretLen { + return false + } + + s.masterSecret = data[:masterSecretLen] + data = data[masterSecretLen:] + + if len(data) < 2 { + return false + } + + numCerts := int(data[0])<<8 | int(data[1]) + data = data[2:] + + s.certificates = make([][]byte, numCerts) + for i := range s.certificates { + if len(data) < 4 { + return false + } + certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3]) + data = data[4:] + if certLen < 0 { + return false + } + if len(data) < certLen { + return false + } + s.certificates[i] = data[:certLen] + data = data[certLen:] + } + + return len(data) == 0 +} + +// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first +// version (revision = 0) doesn't carry any of the information needed for 0-RTT +// validation and the nonce is always empty. +type sessionStateTLS13 struct { + // uint8 version = 0x0304; + // uint8 revision = 0; + cipherSuite uint16 + createdAt uint64 + resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>; + certificate Certificate // CertificateEntry certificate_list<0..2^24-1>; +} + +func (m *sessionStateTLS13) marshal() []byte { + var b cryptobyte.Builder + b.AddUint16(VersionTLS13) + b.AddUint8(0) // revision + b.AddUint16(m.cipherSuite) + addUint64(&b, m.createdAt) + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.resumptionSecret) + }) + marshalCertificate(&b, m.certificate) + return b.BytesOrPanic() +} + +func (m *sessionStateTLS13) unmarshal(data []byte) bool { + *m = sessionStateTLS13{} + s := cryptobyte.String(data) + var version uint16 + var revision uint8 + return s.ReadUint16(&version) && + version == VersionTLS13 && + s.ReadUint8(&revision) && + revision == 0 && + s.ReadUint16(&m.cipherSuite) && + readUint64(&s, &m.createdAt) && + readUint8LengthPrefixed(&s, &m.resumptionSecret) && + len(m.resumptionSecret) != 0 && + unmarshalCertificate(&s, &m.certificate) && + s.Empty() +} + +func (c *Conn) encryptTicket(state []byte) ([]byte, error) { + encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size) + keyName := encrypted[:ticketKeyNameLen] + iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] + macBytes := encrypted[len(encrypted)-sha256.Size:] + + if _, err := io.ReadFull(c.config.rand(), iv); err != nil { + return nil, err + } + key := c.config.ticketKeys()[0] + copy(keyName, key.keyName[:]) + block, err := aes.NewCipher(key.aesKey[:]) + if err != nil { + return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) + } + cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state) + + mac := hmac.New(sha256.New, key.hmacKey[:]) + mac.Write(encrypted[:len(encrypted)-sha256.Size]) + mac.Sum(macBytes[:0]) + + return encrypted, nil +} + +func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) { + if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size { + return nil, false + } + + keyName := encrypted[:ticketKeyNameLen] + iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] + macBytes := encrypted[len(encrypted)-sha256.Size:] + ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size] + + keys := c.config.ticketKeys() + keyIndex := -1 + for i, candidateKey := range keys { + if bytes.Equal(keyName, candidateKey.keyName[:]) { + keyIndex = i + break + } + } + + if keyIndex == -1 { + return nil, false + } + key := &keys[keyIndex] + + mac := hmac.New(sha256.New, key.hmacKey[:]) + mac.Write(encrypted[:len(encrypted)-sha256.Size]) + expected := mac.Sum(nil) + + if subtle.ConstantTimeCompare(macBytes, expected) != 1 { + return nil, false + } + + block, err := aes.NewCipher(key.aesKey[:]) + if err != nil { + return nil, false + } + plaintext = make([]byte, len(ciphertext)) + cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) + + return plaintext, keyIndex > 0 +} diff --git a/vendor/github.com/marten-seemann/qtls/tls.go b/vendor/github.com/marten-seemann/qtls/tls.go new file mode 100644 index 00000000..818997d3 --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls/tls.go @@ -0,0 +1,306 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// package qtls partially implements TLS 1.2, as specified in RFC 5246, +// and TLS 1.3, as specified in RFC 8446. +// +// TLS 1.3 is available only on an opt-in basis in Go 1.12. To enable +// it, set the GODEBUG environment variable (comma-separated key=value +// options) such that it includes "tls13=1". To enable it from within +// the process, set the environment variable before any use of TLS: +// +// func init() { +// os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1") +// } +package qtls + +// BUG(agl): The crypto/tls package only implements some countermeasures +// against Lucky13 attacks on CBC-mode encryption, and only on SHA1 +// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and +// https://www.imperialviolet.org/2013/02/04/luckythirteen.html. + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" + "io/ioutil" + "net" + "strings" + "time" +) + +// Server returns a new TLS server side connection +// using conn as the underlying transport. +// The configuration config must be non-nil and must include +// at least one certificate or else set GetCertificate. +func Server(conn net.Conn, config *Config) *Conn { + return &Conn{conn: conn, config: config} +} + +// Client returns a new TLS client side connection +// using conn as the underlying transport. +// The config cannot be nil: users must set either ServerName or +// InsecureSkipVerify in the config. +func Client(conn net.Conn, config *Config) *Conn { + return &Conn{conn: conn, config: config, isClient: true} +} + +// A listener implements a network listener (net.Listener) for TLS connections. +type listener struct { + net.Listener + config *Config +} + +// Accept waits for and returns the next incoming TLS connection. +// The returned connection is of type *Conn. +func (l *listener) Accept() (net.Conn, error) { + c, err := l.Listener.Accept() + if err != nil { + return nil, err + } + return Server(c, l.config), nil +} + +// NewListener creates a Listener which accepts connections from an inner +// Listener and wraps each connection with Server. +// The configuration config must be non-nil and must include +// at least one certificate or else set GetCertificate. +func NewListener(inner net.Listener, config *Config) net.Listener { + l := new(listener) + l.Listener = inner + l.config = config + return l +} + +// Listen creates a TLS listener accepting connections on the +// given network address using net.Listen. +// The configuration config must be non-nil and must include +// at least one certificate or else set GetCertificate. +func Listen(network, laddr string, config *Config) (net.Listener, error) { + if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) { + return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config") + } + l, err := net.Listen(network, laddr) + if err != nil { + return nil, err + } + return NewListener(l, config), nil +} + +type timeoutError struct{} + +func (timeoutError) Error() string { return "tls: DialWithDialer timed out" } +func (timeoutError) Timeout() bool { return true } +func (timeoutError) Temporary() bool { return true } + +// DialWithDialer connects to the given network address using dialer.Dial and +// then initiates a TLS handshake, returning the resulting TLS connection. Any +// timeout or deadline given in the dialer apply to connection and TLS +// handshake as a whole. +// +// DialWithDialer interprets a nil configuration as equivalent to the zero +// configuration; see the documentation of Config for the defaults. +func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { + // We want the Timeout and Deadline values from dialer to cover the + // whole process: TCP connection and TLS handshake. This means that we + // also need to start our own timers now. + timeout := dialer.Timeout + + if !dialer.Deadline.IsZero() { + deadlineTimeout := time.Until(dialer.Deadline) + if timeout == 0 || deadlineTimeout < timeout { + timeout = deadlineTimeout + } + } + + var errChannel chan error + + if timeout != 0 { + errChannel = make(chan error, 2) + time.AfterFunc(timeout, func() { + errChannel <- timeoutError{} + }) + } + + rawConn, err := dialer.Dial(network, addr) + if err != nil { + return nil, err + } + + colonPos := strings.LastIndex(addr, ":") + if colonPos == -1 { + colonPos = len(addr) + } + hostname := addr[:colonPos] + + if config == nil { + config = defaultConfig() + } + // If no ServerName is set, infer the ServerName + // from the hostname we're connecting to. + if config.ServerName == "" { + // Make a copy to avoid polluting argument or default. + c := config.Clone() + c.ServerName = hostname + config = c + } + + conn := Client(rawConn, config) + + if timeout == 0 { + err = conn.Handshake() + } else { + go func() { + errChannel <- conn.Handshake() + }() + + err = <-errChannel + } + + if err != nil { + rawConn.Close() + return nil, err + } + + return conn, nil +} + +// Dial connects to the given network address using net.Dial +// and then initiates a TLS handshake, returning the resulting +// TLS connection. +// Dial interprets a nil configuration as equivalent to +// the zero configuration; see the documentation of Config +// for the defaults. +func Dial(network, addr string, config *Config) (*Conn, error) { + return DialWithDialer(new(net.Dialer), network, addr, config) +} + +// LoadX509KeyPair reads and parses a public/private key pair from a pair +// of files. The files must contain PEM encoded data. The certificate file +// may contain intermediate certificates following the leaf certificate to +// form a certificate chain. On successful return, Certificate.Leaf will +// be nil because the parsed form of the certificate is not retained. +func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { + certPEMBlock, err := ioutil.ReadFile(certFile) + if err != nil { + return Certificate{}, err + } + keyPEMBlock, err := ioutil.ReadFile(keyFile) + if err != nil { + return Certificate{}, err + } + return X509KeyPair(certPEMBlock, keyPEMBlock) +} + +// X509KeyPair parses a public/private key pair from a pair of +// PEM encoded data. On successful return, Certificate.Leaf will be nil because +// the parsed form of the certificate is not retained. +func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { + fail := func(err error) (Certificate, error) { return Certificate{}, err } + + var cert Certificate + var skippedBlockTypes []string + for { + var certDERBlock *pem.Block + certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) + if certDERBlock == nil { + break + } + if certDERBlock.Type == "CERTIFICATE" { + cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) + } else { + skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) + } + } + + if len(cert.Certificate) == 0 { + if len(skippedBlockTypes) == 0 { + return fail(errors.New("tls: failed to find any PEM data in certificate input")) + } + if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { + return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) + } + return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) + } + + skippedBlockTypes = skippedBlockTypes[:0] + var keyDERBlock *pem.Block + for { + keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) + if keyDERBlock == nil { + if len(skippedBlockTypes) == 0 { + return fail(errors.New("tls: failed to find any PEM data in key input")) + } + if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { + return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) + } + return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) + } + if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { + break + } + skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) + } + + // We don't need to parse the public key for TLS, but we so do anyway + // to check that it looks sane and matches the private key. + x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return fail(err) + } + + cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) + if err != nil { + return fail(err) + } + + switch pub := x509Cert.PublicKey.(type) { + case *rsa.PublicKey: + priv, ok := cert.PrivateKey.(*rsa.PrivateKey) + if !ok { + return fail(errors.New("tls: private key type does not match public key type")) + } + if pub.N.Cmp(priv.N) != 0 { + return fail(errors.New("tls: private key does not match public key")) + } + case *ecdsa.PublicKey: + priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) + if !ok { + return fail(errors.New("tls: private key type does not match public key type")) + } + if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { + return fail(errors.New("tls: private key does not match public key")) + } + default: + return fail(errors.New("tls: unknown public key algorithm")) + } + + return cert, nil +} + +// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates +// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. +// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. +func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { + if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { + return key, nil + } + if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { + switch key := key.(type) { + case *rsa.PrivateKey, *ecdsa.PrivateKey: + return key, nil + default: + return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") + } + } + if key, err := x509.ParseECPrivateKey(der); err == nil { + return key, nil + } + + return nil, errors.New("tls: failed to parse private key") +} diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml new file mode 100644 index 00000000..98db8f06 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/.travis.yml @@ -0,0 +1,9 @@ +language: go +go: + - tip + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE new file mode 100644 index 00000000..91b5cef3 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md new file mode 100644 index 00000000..56729a92 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/README.md @@ -0,0 +1,48 @@ +# go-colorable + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + +Colorable writer for windows. + +For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) +This package is possible to handle escape sequence for ansi color on windows. + +## Too Bad! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) + + +## So Good! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) + +## Usage + +```go +logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +logrus.SetOutput(colorable.NewColorableStdout()) + +logrus.Info("succeeded") +logrus.Warn("not correct") +logrus.Error("something error") +logrus.Fatal("panic") +``` + +You can compile above code on non-windows OSs. + +## Installation + +``` +$ go get github.com/mattn/go-colorable +``` + +# License + +MIT + +# Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go new file mode 100644 index 00000000..1f28d773 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_appengine.go @@ -0,0 +1,29 @@ +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go new file mode 100644 index 00000000..887f203d --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -0,0 +1,30 @@ +// +build !windows +// +build !appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go new file mode 100644 index 00000000..404e10ca --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -0,0 +1,980 @@ +// +build windows +// +build !appengine + +package colorable + +import ( + "bytes" + "io" + "math" + "os" + "strconv" + "strings" + "syscall" + "unsafe" + + "github.com/mattn/go-isatty" +) + +const ( + foregroundBlue = 0x1 + foregroundGreen = 0x2 + foregroundRed = 0x4 + foregroundIntensity = 0x8 + foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) + backgroundBlue = 0x10 + backgroundGreen = 0x20 + backgroundRed = 0x40 + backgroundIntensity = 0x80 + backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) +) + +const ( + genericRead = 0x80000000 + genericWrite = 0x40000000 +) + +const ( + consoleTextmodeBuffer = 0x1 +) + +type wchar uint16 +type short int16 +type dword uint32 +type word uint16 + +type coord struct { + x short + y short +} + +type smallRect struct { + left short + top short + right short + bottom short +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord +} + +type consoleCursorInfo struct { + size dword + visible int32 +} + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") + procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") + procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") + procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") +) + +// Writer provide colorable Writer to the console +type Writer struct { + out io.Writer + handle syscall.Handle + althandle syscall.Handle + oldattr word + oldpos coord + rest bytes.Buffer +} + +// NewColorable return new instance of Writer which handle escape sequence from File. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + if isatty.IsTerminal(file.Fd()) { + var csbi consoleScreenBufferInfo + handle := syscall.Handle(file.Fd()) + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + } + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return NewColorable(os.Stdout) +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return NewColorable(os.Stderr) +} + +var color256 = map[int]int{ + 0: 0x000000, + 1: 0x800000, + 2: 0x008000, + 3: 0x808000, + 4: 0x000080, + 5: 0x800080, + 6: 0x008080, + 7: 0xc0c0c0, + 8: 0x808080, + 9: 0xff0000, + 10: 0x00ff00, + 11: 0xffff00, + 12: 0x0000ff, + 13: 0xff00ff, + 14: 0x00ffff, + 15: 0xffffff, + 16: 0x000000, + 17: 0x00005f, + 18: 0x000087, + 19: 0x0000af, + 20: 0x0000d7, + 21: 0x0000ff, + 22: 0x005f00, + 23: 0x005f5f, + 24: 0x005f87, + 25: 0x005faf, + 26: 0x005fd7, + 27: 0x005fff, + 28: 0x008700, + 29: 0x00875f, + 30: 0x008787, + 31: 0x0087af, + 32: 0x0087d7, + 33: 0x0087ff, + 34: 0x00af00, + 35: 0x00af5f, + 36: 0x00af87, + 37: 0x00afaf, + 38: 0x00afd7, + 39: 0x00afff, + 40: 0x00d700, + 41: 0x00d75f, + 42: 0x00d787, + 43: 0x00d7af, + 44: 0x00d7d7, + 45: 0x00d7ff, + 46: 0x00ff00, + 47: 0x00ff5f, + 48: 0x00ff87, + 49: 0x00ffaf, + 50: 0x00ffd7, + 51: 0x00ffff, + 52: 0x5f0000, + 53: 0x5f005f, + 54: 0x5f0087, + 55: 0x5f00af, + 56: 0x5f00d7, + 57: 0x5f00ff, + 58: 0x5f5f00, + 59: 0x5f5f5f, + 60: 0x5f5f87, + 61: 0x5f5faf, + 62: 0x5f5fd7, + 63: 0x5f5fff, + 64: 0x5f8700, + 65: 0x5f875f, + 66: 0x5f8787, + 67: 0x5f87af, + 68: 0x5f87d7, + 69: 0x5f87ff, + 70: 0x5faf00, + 71: 0x5faf5f, + 72: 0x5faf87, + 73: 0x5fafaf, + 74: 0x5fafd7, + 75: 0x5fafff, + 76: 0x5fd700, + 77: 0x5fd75f, + 78: 0x5fd787, + 79: 0x5fd7af, + 80: 0x5fd7d7, + 81: 0x5fd7ff, + 82: 0x5fff00, + 83: 0x5fff5f, + 84: 0x5fff87, + 85: 0x5fffaf, + 86: 0x5fffd7, + 87: 0x5fffff, + 88: 0x870000, + 89: 0x87005f, + 90: 0x870087, + 91: 0x8700af, + 92: 0x8700d7, + 93: 0x8700ff, + 94: 0x875f00, + 95: 0x875f5f, + 96: 0x875f87, + 97: 0x875faf, + 98: 0x875fd7, + 99: 0x875fff, + 100: 0x878700, + 101: 0x87875f, + 102: 0x878787, + 103: 0x8787af, + 104: 0x8787d7, + 105: 0x8787ff, + 106: 0x87af00, + 107: 0x87af5f, + 108: 0x87af87, + 109: 0x87afaf, + 110: 0x87afd7, + 111: 0x87afff, + 112: 0x87d700, + 113: 0x87d75f, + 114: 0x87d787, + 115: 0x87d7af, + 116: 0x87d7d7, + 117: 0x87d7ff, + 118: 0x87ff00, + 119: 0x87ff5f, + 120: 0x87ff87, + 121: 0x87ffaf, + 122: 0x87ffd7, + 123: 0x87ffff, + 124: 0xaf0000, + 125: 0xaf005f, + 126: 0xaf0087, + 127: 0xaf00af, + 128: 0xaf00d7, + 129: 0xaf00ff, + 130: 0xaf5f00, + 131: 0xaf5f5f, + 132: 0xaf5f87, + 133: 0xaf5faf, + 134: 0xaf5fd7, + 135: 0xaf5fff, + 136: 0xaf8700, + 137: 0xaf875f, + 138: 0xaf8787, + 139: 0xaf87af, + 140: 0xaf87d7, + 141: 0xaf87ff, + 142: 0xafaf00, + 143: 0xafaf5f, + 144: 0xafaf87, + 145: 0xafafaf, + 146: 0xafafd7, + 147: 0xafafff, + 148: 0xafd700, + 149: 0xafd75f, + 150: 0xafd787, + 151: 0xafd7af, + 152: 0xafd7d7, + 153: 0xafd7ff, + 154: 0xafff00, + 155: 0xafff5f, + 156: 0xafff87, + 157: 0xafffaf, + 158: 0xafffd7, + 159: 0xafffff, + 160: 0xd70000, + 161: 0xd7005f, + 162: 0xd70087, + 163: 0xd700af, + 164: 0xd700d7, + 165: 0xd700ff, + 166: 0xd75f00, + 167: 0xd75f5f, + 168: 0xd75f87, + 169: 0xd75faf, + 170: 0xd75fd7, + 171: 0xd75fff, + 172: 0xd78700, + 173: 0xd7875f, + 174: 0xd78787, + 175: 0xd787af, + 176: 0xd787d7, + 177: 0xd787ff, + 178: 0xd7af00, + 179: 0xd7af5f, + 180: 0xd7af87, + 181: 0xd7afaf, + 182: 0xd7afd7, + 183: 0xd7afff, + 184: 0xd7d700, + 185: 0xd7d75f, + 186: 0xd7d787, + 187: 0xd7d7af, + 188: 0xd7d7d7, + 189: 0xd7d7ff, + 190: 0xd7ff00, + 191: 0xd7ff5f, + 192: 0xd7ff87, + 193: 0xd7ffaf, + 194: 0xd7ffd7, + 195: 0xd7ffff, + 196: 0xff0000, + 197: 0xff005f, + 198: 0xff0087, + 199: 0xff00af, + 200: 0xff00d7, + 201: 0xff00ff, + 202: 0xff5f00, + 203: 0xff5f5f, + 204: 0xff5f87, + 205: 0xff5faf, + 206: 0xff5fd7, + 207: 0xff5fff, + 208: 0xff8700, + 209: 0xff875f, + 210: 0xff8787, + 211: 0xff87af, + 212: 0xff87d7, + 213: 0xff87ff, + 214: 0xffaf00, + 215: 0xffaf5f, + 216: 0xffaf87, + 217: 0xffafaf, + 218: 0xffafd7, + 219: 0xffafff, + 220: 0xffd700, + 221: 0xffd75f, + 222: 0xffd787, + 223: 0xffd7af, + 224: 0xffd7d7, + 225: 0xffd7ff, + 226: 0xffff00, + 227: 0xffff5f, + 228: 0xffff87, + 229: 0xffffaf, + 230: 0xffffd7, + 231: 0xffffff, + 232: 0x080808, + 233: 0x121212, + 234: 0x1c1c1c, + 235: 0x262626, + 236: 0x303030, + 237: 0x3a3a3a, + 238: 0x444444, + 239: 0x4e4e4e, + 240: 0x585858, + 241: 0x626262, + 242: 0x6c6c6c, + 243: 0x767676, + 244: 0x808080, + 245: 0x8a8a8a, + 246: 0x949494, + 247: 0x9e9e9e, + 248: 0xa8a8a8, + 249: 0xb2b2b2, + 250: 0xbcbcbc, + 251: 0xc6c6c6, + 252: 0xd0d0d0, + 253: 0xdadada, + 254: 0xe4e4e4, + 255: 0xeeeeee, +} + +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + +// Write write data on console +func (w *Writer) Write(data []byte) (n int, err error) { + var csbi consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + handle := w.handle + + var er *bytes.Reader + if w.rest.Len() > 0 { + var rest bytes.Buffer + w.rest.WriteTo(&rest) + w.rest.Reset() + rest.Write(data) + er = bytes.NewReader(rest.Bytes()) + } else { + er = bytes.NewReader(data) + } + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + + switch c2 { + case '>': + continue + case ']': + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 { + break loop + } + er = bytes.NewReader(w.rest.Bytes()[2:]) + err := doTitleSequence(er) + if err != nil { + break loop + } + w.rest.Reset() + continue + // https://github.com/mattn/go-colorable/issues/27 + case '7': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + continue + case '8': + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + continue + case 0x5b: + // execute part after switch + default: + continue + } + + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + + var buf bytes.Buffer + var m byte + for i, c := range w.rest.Bytes()[2:] { + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + m = c + er = bytes.NewReader(w.rest.Bytes()[2+i+1:]) + w.rest.Reset() + break + } + buf.Write([]byte(string(c))) + } + if m == 0 { + break loop + } + + switch m { + case 'A': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'B': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'C': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'D': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + if csbi.cursorPosition.x < 0 { + csbi.cursorPosition.x = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'E': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'F': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'G': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = short(n - 1) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'J': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + var count, written dword + var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'K': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var count, written dword + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} + count = dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'm': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + attr := csbi.attributes + cs := buf.String() + if cs == "" { + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) + continue + } + token := strings.Split(cs, ";") + for i := 0; i < len(token); i++ { + ns := token[i] + if n, err = strconv.Atoi(ns); err == nil { + switch { + case n == 0 || n == 100: + attr = w.oldattr + case 1 <= n && n <= 5: + attr |= foregroundIntensity + case n == 7: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case n == 22 || n == 25: + attr |= foregroundIntensity + case n == 27: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case 30 <= n && n <= 37: + attr &= backgroundMask + if (n-30)&1 != 0 { + attr |= foregroundRed + } + if (n-30)&2 != 0 { + attr |= foregroundGreen + } + if (n-30)&4 != 0 { + attr |= foregroundBlue + } + case n == 38: // set foreground color. + if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256foreAttr == nil { + n256setup() + } + attr &= backgroundMask + attr |= n256foreAttr[n256] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= foregroundRed + } + if g > 127 { + attr |= foregroundGreen + } + if b > 127 { + attr |= foregroundBlue + } + } else { + attr = attr & (w.oldattr & backgroundMask) + } + case n == 39: // reset foreground color. + attr &= backgroundMask + attr |= w.oldattr & foregroundMask + case 40 <= n && n <= 47: + attr &= foregroundMask + if (n-40)&1 != 0 { + attr |= backgroundRed + } + if (n-40)&2 != 0 { + attr |= backgroundGreen + } + if (n-40)&4 != 0 { + attr |= backgroundBlue + } + case n == 48: // set background color. + if i < len(token)-2 && token[i+1] == "5" { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256backAttr == nil { + n256setup() + } + attr &= foregroundMask + attr |= n256backAttr[n256] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= backgroundRed + } + if g > 127 { + attr |= backgroundGreen + } + if b > 127 { + attr |= backgroundBlue + } + } else { + attr = attr & (w.oldattr & foregroundMask) + } + case n == 49: // reset foreground color. + attr &= foregroundMask + attr |= w.oldattr & backgroundMask + case 90 <= n && n <= 97: + attr = (attr & backgroundMask) + attr |= foregroundIntensity + if (n-90)&1 != 0 { + attr |= foregroundRed + } + if (n-90)&2 != 0 { + attr |= foregroundGreen + } + if (n-90)&4 != 0 { + attr |= foregroundBlue + } + case 100 <= n && n <= 107: + attr = (attr & foregroundMask) + attr |= backgroundIntensity + if (n-100)&1 != 0 { + attr |= backgroundRed + } + if (n-100)&2 != 0 { + attr |= backgroundGreen + } + if (n-100)&4 != 0 { + attr |= backgroundBlue + } + } + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) + } + } + case 'h': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle == 0 { + h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0) + w.althandle = syscall.Handle(h) + if w.althandle != 0 { + handle = w.althandle + } + } + } + case 'l': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle != 0 { + syscall.CloseHandle(w.althandle) + w.althandle = 0 + handle = w.handle + } + } + case 's': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + case 'u': + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + } + } + + return len(data), nil +} + +type consoleColor struct { + rgb int + red bool + green bool + blue bool + intensity bool +} + +func (c consoleColor) foregroundAttr() (attr word) { + if c.red { + attr |= foregroundRed + } + if c.green { + attr |= foregroundGreen + } + if c.blue { + attr |= foregroundBlue + } + if c.intensity { + attr |= foregroundIntensity + } + return +} + +func (c consoleColor) backgroundAttr() (attr word) { + if c.red { + attr |= backgroundRed + } + if c.green { + attr |= backgroundGreen + } + if c.blue { + attr |= backgroundBlue + } + if c.intensity { + attr |= backgroundIntensity + } + return +} + +var color16 = []consoleColor{ + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, +} + +type hsv struct { + h, s, v float32 +} + +func (a hsv) dist(b hsv) float32 { + dh := a.h - b.h + switch { + case dh > 0.5: + dh = 1 - dh + case dh < -0.5: + dh = -1 - dh + } + ds := a.s - b.s + dv := a.v - b.v + return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) +} + +func toHSV(rgb int) hsv { + r, g, b := float32((rgb&0xFF0000)>>16)/256.0, + float32((rgb&0x00FF00)>>8)/256.0, + float32(rgb&0x0000FF)/256.0 + min, max := minmax3f(r, g, b) + h := max - min + if h > 0 { + if max == r { + h = (g - b) / h + if h < 0 { + h += 6 + } + } else if max == g { + h = 2 + (b-r)/h + } else { + h = 4 + (r-g)/h + } + } + h /= 6.0 + s := max - min + if max != 0 { + s /= max + } + v := max + return hsv{h: h, s: s, v: v} +} + +type hsvTable []hsv + +func toHSVTable(rgbTable []consoleColor) hsvTable { + t := make(hsvTable, len(rgbTable)) + for i, c := range rgbTable { + t[i] = toHSV(c.rgb) + } + return t +} + +func (t hsvTable) find(rgb int) consoleColor { + hsv := toHSV(rgb) + n := 7 + l := float32(5.0) + for i, p := range t { + d := hsv.dist(p) + if d < l { + l, n = d, i + } + } + return color16[n] +} + +func minmax3f(a, b, c float32) (min, max float32) { + if a < b { + if b < c { + return a, c + } else if a < c { + return a, b + } else { + return c, b + } + } else { + if a < c { + return b, c + } else if b < c { + return b, a + } else { + return c, a + } + } +} + +var n256foreAttr []word +var n256backAttr []word + +func n256setup() { + n256foreAttr = make([]word, 256) + n256backAttr = make([]word, 256) + t := toHSVTable(color16) + for i, rgb := range color256 { + c := t.find(rgb) + n256foreAttr[i] = c.foregroundAttr() + n256backAttr[i] = c.backgroundAttr() + } +} diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod new file mode 100644 index 00000000..ef3ca9d4 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/go.mod @@ -0,0 +1,3 @@ +module github.com/mattn/go-colorable + +require github.com/mattn/go-isatty v0.0.8 diff --git a/vendor/github.com/mattn/go-colorable/go.sum b/vendor/github.com/mattn/go-colorable/go.sum new file mode 100644 index 00000000..2c12960e --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/go.sum @@ -0,0 +1,4 @@ +github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go new file mode 100644 index 00000000..9721e16f --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -0,0 +1,55 @@ +package colorable + +import ( + "bytes" + "io" +) + +// NonColorable hold writer but remove escape sequence. +type NonColorable struct { + out io.Writer +} + +// NewNonColorable return new instance of Writer which remove escape sequence from Writer. +func NewNonColorable(w io.Writer) io.Writer { + return &NonColorable{out: w} +} + +// Write write data on console +func (w *NonColorable) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + buf.Write([]byte(string(c))) + } + } + + return len(data), nil +} diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml new file mode 100644 index 00000000..5597e026 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/.travis.yml @@ -0,0 +1,13 @@ +language: go +go: + - tip + +os: + - linux + - osx + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE new file mode 100644 index 00000000..65dc692b --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) Yasuhiro MATSUMOTO + +MIT License (Expat) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md new file mode 100644 index 00000000..1e69004b --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/README.md @@ -0,0 +1,50 @@ +# go-isatty + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) + +isatty for golang + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/mattn/go-isatty" + "os" +) + +func main() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} +``` + +## Installation + +``` +$ go get github.com/mattn/go-isatty +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) + +## Thanks + +* k-takata: base idea for IsCygwinTerminal + + https://github.com/k-takata/go-iscygpty diff --git a/vendor/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go new file mode 100644 index 00000000..17d4f90e --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/doc.go @@ -0,0 +1,2 @@ +// Package isatty implements interface to isatty +package isatty diff --git a/vendor/github.com/mattn/go-isatty/go.mod b/vendor/github.com/mattn/go-isatty/go.mod new file mode 100644 index 00000000..f310320c --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/go.mod @@ -0,0 +1,3 @@ +module github.com/mattn/go-isatty + +require golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 diff --git a/vendor/github.com/mattn/go-isatty/go.sum b/vendor/github.com/mattn/go-isatty/go.sum new file mode 100644 index 00000000..426c8973 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/mattn/go-isatty/isatty_android.go b/vendor/github.com/mattn/go-isatty/isatty_android.go new file mode 100644 index 00000000..d3567cb5 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_android.go @@ -0,0 +1,23 @@ +// +build android + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go new file mode 100644 index 00000000..07e93039 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -0,0 +1,24 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TIOCGETA + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go new file mode 100644 index 00000000..ff714a37 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -0,0 +1,15 @@ +// +build appengine js nacl + +package isatty + +// IsTerminal returns true if the file descriptor is terminal which +// is always false on js and appengine classic which is a sandboxed PaaS. +func IsTerminal(fd uintptr) bool { + return false +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go new file mode 100644 index 00000000..bdd5c79a --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go @@ -0,0 +1,22 @@ +// +build solaris +// +build !appengine + +package isatty + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +func IsTerminal(fd uintptr) bool { + var termio unix.Termio + err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + return err == nil +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go new file mode 100644 index 00000000..453b025d --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -0,0 +1,19 @@ +// +build linux aix +// +build !appengine +// +build !android + +package isatty + +import "golang.org/x/sys/unix" + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) + return err == nil +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go new file mode 100644 index 00000000..af51cbca --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -0,0 +1,94 @@ +// +build windows +// +build !appengine + +package isatty + +import ( + "strings" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + fileNameInfo uintptr = 2 + fileTypePipe = 3 +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = kernel32.NewProc("GetFileType") +) + +func init() { + // Check if GetFileInformationByHandleEx is available. + if procGetFileInformationByHandleEx.Find() != nil { + procGetFileInformationByHandleEx = nil + } +} + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// Check pipe name is used for cygwin/msys2 pty. +// Cygwin/MSYS2 PTY has a name like: +// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +func isCygwinPipeName(name string) bool { + token := strings.Split(name, "-") + if len(token) < 5 { + return false + } + + if token[0] != `\msys` && token[0] != `\cygwin` { + return false + } + + if token[1] == "" { + return false + } + + if !strings.HasPrefix(token[2], "pty") { + return false + } + + if token[3] != `from` && token[3] != `to` { + return false + } + + if token[4] != "master" { + return false + } + + return true +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. +func IsCygwinTerminal(fd uintptr) bool { + if procGetFileInformationByHandleEx == nil { + return false + } + + // Cygwin/msys's pty is a pipe. + ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) + if ft != fileTypePipe || e != 0 { + return false + } + + var buf [2 + syscall.MAX_PATH]uint16 + r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), + 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), + uintptr(len(buf)*2), 0, 0) + if r == 0 || e != 0 { + return false + } + + l := *(*uint32)(unsafe.Pointer(&buf)) + return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) +} diff --git a/vendor/github.com/mattn/go-runewidth/.travis.yml b/vendor/github.com/mattn/go-runewidth/.travis.yml new file mode 100644 index 00000000..5c9c2a30 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/.travis.yml @@ -0,0 +1,8 @@ +language: go +go: + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 00000000..91b5cef3 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd new file mode 100644 index 00000000..66663a94 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/README.mkd @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go new file mode 100644 index 00000000..3cb94106 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -0,0 +1,977 @@ +package runewidth + +import ( + "os" +) + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth bool + + // ZeroWidthJoiner is flag to set to use UTR#51 ZWJ + ZeroWidthJoiner bool + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{} +) + +func init() { + handleEnv() +} + +func handleEnv() { + env := os.Getenv("RUNEWIDTH_EASTASIAN") + if env == "" { + EastAsianWidth = IsEastAsian() + } else { + EastAsianWidth = env == "1" + } + // update DefaultCondition + DefaultCondition.EastAsianWidth = EastAsianWidth + DefaultCondition.ZeroWidthJoiner = ZeroWidthJoiner +} + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + // func (t table) IncludesRune(r rune) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) >> 1 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, + {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, + {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, + {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, + {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, + {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, + {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, + {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, + {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, + {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, + {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, + {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, + {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, + {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, + {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, + {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, + {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, + {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, + {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, + {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, + {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, + {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, + {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, + {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, + {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, + {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, + {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, + {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, + {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, + {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, + {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, + {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, + {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, + {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, + {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, + {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, + {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, + {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, + {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, + {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, + {0xE0100, 0xE01EF}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, + {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, + {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, + {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, + {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, + {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, + {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} + +var emoji = table{ + {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, + {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, + {0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF}, + {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2}, + {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0}, + {0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E}, + {0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618}, + {0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623}, + {0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F}, + {0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642}, + {0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663}, + {0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B}, + {0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699}, + {0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26AA, 0x26AB}, + {0x26B0, 0x26B1}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26C8, 0x26C8}, {0x26CE, 0x26CF}, {0x26D1, 0x26D1}, + {0x26D3, 0x26D4}, {0x26E9, 0x26EA}, {0x26F0, 0x26F5}, + {0x26F7, 0x26FA}, {0x26FD, 0x26FD}, {0x2702, 0x2702}, + {0x2705, 0x2705}, {0x2708, 0x270D}, {0x270F, 0x270F}, + {0x2712, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, + {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, + {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, + {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, + {0x2757, 0x2757}, {0x2763, 0x2764}, {0x2795, 0x2797}, + {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, + {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, + {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, + {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F170, 0x1F171}, + {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F202}, {0x1F21A, 0x1F21A}, + {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F250, 0x1F251}, + {0x1F300, 0x1F321}, {0x1F324, 0x1F393}, {0x1F396, 0x1F397}, + {0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0}, {0x1F3F3, 0x1F3F5}, + {0x1F3F7, 0x1F4FD}, {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E}, + {0x1F550, 0x1F567}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A}, + {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, + {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, + {0x1F5B1, 0x1F5B2}, {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, + {0x1F5D1, 0x1F5D3}, {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, + {0x1F5E3, 0x1F5E3}, {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, + {0x1F5F3, 0x1F5F3}, {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5}, + {0x1F6CB, 0x1F6D2}, {0x1F6E0, 0x1F6E5}, {0x1F6E9, 0x1F6E9}, + {0x1F6EB, 0x1F6EC}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F9}, + {0x1F910, 0x1F93A}, {0x1F93C, 0x1F93E}, {0x1F940, 0x1F945}, + {0x1F947, 0x1F970}, {0x1F973, 0x1F976}, {0x1F97A, 0x1F97A}, + {0x1F97C, 0x1F9A2}, {0x1F9B0, 0x1F9B9}, {0x1F9C0, 0x1F9C2}, + {0x1F9D0, 0x1F9FF}, +} + +var notassigned = table{ + {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, + {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, + {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, + {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, + {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, + {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, + {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, + {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, + {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, + {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, + {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, + {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, + {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, + {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, + {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, + {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, + {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, + {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, + {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, + {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, + {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, + {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, + {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, + {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, + {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, + {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, + {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, + {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, + {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, + {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, + {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, + {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, + {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, + {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, + {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, + {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, + {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, + {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, + {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, + {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, + {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, + {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, + {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, + {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, + {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, + {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, + {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, + {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, + {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, + {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, + {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, + {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, + {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, + {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, + {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, + {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, + {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, + {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, + {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, + {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, + {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, + {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, + {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, + {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, + {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, + {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, + {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, + {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, + {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, + {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, + {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, + {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, + {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, + {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, + {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, + {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, + {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, + {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, + {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, + {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, + {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, + {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, + {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, + {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, + {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, + {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, + {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, + {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, + {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, + {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, + {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, + {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, + {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, + {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, + {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, + {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, + {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, + {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, + {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, + {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, + {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, + {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, + {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, + {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, + {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, + {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, + {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, + {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, + {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, + {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, + {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, + {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, + {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, + {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, + {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, + {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, + {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, + {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, + {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, + {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, + {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, + {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, + {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, + {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, + {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, + {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, + {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, + {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, + {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, + {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, + {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, + {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, + {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, + {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, + {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, + {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, + {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, + {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, + {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, + {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, + {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, + {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, + {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, + {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, + {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, + {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, + {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, + {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, + {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, + {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, + {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, + {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, + {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, + {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, + {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, + {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, + {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, + {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, + {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, + {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, + {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, + {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, + {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, + {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, + {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, + {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, + {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, + {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, + {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, + {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, + {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, + {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, + {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, + {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, + {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, + {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, + {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, + {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, + {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, + {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, + {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, + {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, + {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, + {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, + {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, + {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, + {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, + {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, + {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, + {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, + {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, + {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, + {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, + {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, + {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, + {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, + {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, + {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, + {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, + {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, + {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, + {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, + {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, + {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, + {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, + {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, + {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, + {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, + {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, + {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, + {0xFFFFE, 0xFFFFF}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9}, + {0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, + {0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, + {0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, + {0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, + {0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, + {0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, + {0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, + {0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6}, + {0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, + {0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F}, + {0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390}, + {0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400}, + {0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F}, + {0x0531, 0x0556}, {0x0559, 0x055F}, {0x0561, 0x0587}, + {0x0589, 0x058A}, {0x058D, 0x058F}, {0x0591, 0x05C7}, + {0x05D0, 0x05EA}, {0x05F0, 0x05F4}, {0x0600, 0x061C}, + {0x061E, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1}, + {0x07C0, 0x07FA}, {0x0800, 0x082D}, {0x0830, 0x083E}, + {0x0840, 0x085B}, {0x085E, 0x085E}, {0x08A0, 0x08B4}, + {0x08B6, 0x08BD}, {0x08D4, 0x0983}, {0x0985, 0x098C}, + {0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0}, + {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, {0x09BC, 0x09C4}, + {0x09C7, 0x09C8}, {0x09CB, 0x09CE}, {0x09D7, 0x09D7}, + {0x09DC, 0x09DD}, {0x09DF, 0x09E3}, {0x09E6, 0x09FB}, + {0x0A01, 0x0A03}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, + {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, + {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, + {0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, + {0x0A51, 0x0A51}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, + {0x0A66, 0x0A75}, {0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, + {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, + {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, + {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, + {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AF9}, + {0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, + {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B35, 0x0B39}, {0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B5C, 0x0B5D}, + {0x0B5F, 0x0B63}, {0x0B66, 0x0B77}, {0x0B82, 0x0B83}, + {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, + {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, + {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, + {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, + {0x0C00, 0x0C03}, {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, + {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3D, 0x0C44}, + {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, + {0x0C58, 0x0C5A}, {0x0C60, 0x0C63}, {0x0C66, 0x0C6F}, + {0x0C78, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3}, + {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D01, 0x0D03}, + {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, + {0x0D3D, 0x0D44}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4F}, + {0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, {0x0D82, 0x0D83}, + {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, + {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, + {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, + {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, {0x0E01, 0x0E3A}, + {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, {0x0E84, 0x0E84}, + {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, {0x0E8D, 0x0E8D}, + {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, + {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, {0x0EAA, 0x0EAB}, + {0x0EAD, 0x0EB9}, {0x0EBB, 0x0EBD}, {0x0EC0, 0x0EC4}, + {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, + {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C}, + {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC}, + {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248}, + {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, + {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, + {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, + {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, + {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, + {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, + {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, + {0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736}, + {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9}, + {0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819}, + {0x1820, 0x1877}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, + {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, + {0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974}, + {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, + {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, + {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C}, + {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, + {0x1C4D, 0x1C88}, {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CF6}, + {0x1CF8, 0x1CF9}, {0x1D00, 0x1DF5}, {0x1DFB, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, + {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017}, + {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064}, + {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20F0}, + {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108}, + {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120}, + {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7}, + {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6}, + {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206}, + {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210}, + {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C}, + {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226}, + {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B}, + {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251}, + {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269}, + {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285}, + {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4}, + {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319}, + {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF}, + {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, {0x2400, 0x2426}, + {0x2440, 0x244A}, {0x24EA, 0x24EA}, {0x254C, 0x254F}, + {0x2574, 0x257F}, {0x2590, 0x2591}, {0x2596, 0x259F}, + {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, + {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, + {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, + {0x25E6, 0x25EE}, {0x25F0, 0x25FC}, {0x25FF, 0x2604}, + {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, + {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, + {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, + {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, + {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, + {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, + {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, + {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, + {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, + {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, + {0x2758, 0x2775}, {0x2780, 0x2794}, {0x2798, 0x27AF}, + {0x27B1, 0x27BE}, {0x27C0, 0x27E5}, {0x27EE, 0x2984}, + {0x2987, 0x2B1A}, {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, + {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, + {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, + {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2CF3}, + {0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, + {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, + {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, + {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, + {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E44}, + {0x303F, 0x303F}, {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B}, + {0xA640, 0xA6F7}, {0xA700, 0xA7AE}, {0xA7B0, 0xA7B7}, + {0xA7F7, 0xA82B}, {0xA830, 0xA839}, {0xA840, 0xA877}, + {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA8FD}, + {0xA900, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD}, + {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, + {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, + {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB65}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF}, + {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F}, + {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B}, + {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, + {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, + {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, + {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, + {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, + {0x10300, 0x10323}, {0x10330, 0x1034A}, {0x10350, 0x1037A}, + {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, + {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, + {0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7}, + {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06}, + {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A47}, {0x10A50, 0x10A58}, + {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, + {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x1104D}, + {0x11052, 0x1106F}, {0x1107F, 0x110C1}, {0x110D0, 0x110E8}, + {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11143}, + {0x11150, 0x11176}, {0x11180, 0x111CD}, {0x111D0, 0x111DF}, + {0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x1123E}, + {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, + {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, + {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C}, + {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, + {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133C, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, + {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C}, + {0x11370, 0x11374}, {0x11400, 0x11459}, {0x1145B, 0x1145B}, + {0x1145D, 0x1145D}, {0x11480, 0x114C7}, {0x114D0, 0x114D9}, + {0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644}, + {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B7}, + {0x116C0, 0x116C9}, {0x11700, 0x11719}, {0x1171D, 0x1172B}, + {0x11730, 0x1173F}, {0x118A0, 0x118F2}, {0x118FF, 0x118FF}, + {0x11AC0, 0x11AF8}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, + {0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, + {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x12000, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, + {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, + {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, + {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, + {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, {0x16F50, 0x16F7E}, + {0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, + {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, + {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, + {0x1D200, 0x1D245}, {0x1D300, 0x1D356}, {0x1D360, 0x1D371}, + {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, + {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, + {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, + {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, + {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, + {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, + {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, + {0x1E900, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, + {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, + {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, + {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, + {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, + {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, + {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, + {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, + {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, + {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, + {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, + {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, + {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, + {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, + {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, + {0xE0020, 0xE007F}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool + ZeroWidthJoiner bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{ + EastAsianWidth: EastAsianWidth, + ZeroWidthJoiner: ZeroWidthJoiner, + } +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || + inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || + inTables(r, doublewidth, emoji): + return 2 + default: + return 1 + } +} + +func (c *Condition) stringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +func (c *Condition) stringWidthZeroJoiner(s string) (width int) { + r1, r2 := rune(0), rune(0) + for _, r := range []rune(s) { + if r == 0xFE0E || r == 0xFE0F { + continue + } + w := c.RuneWidth(r) + if r2 == 0x200D && inTables(r, emoji) && inTables(r1, emoji) { + w = 0 + } + width += w + r1, r2 = r2, r + } + return width +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + if c.ZeroWidthJoiner { + return c.stringWidthZeroJoiner(s) + } + return c.stringWidth(s) +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go new file mode 100644 index 00000000..7d99f6e5 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go @@ -0,0 +1,8 @@ +// +build appengine + +package runewidth + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go new file mode 100644 index 00000000..c5fdf40b --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go @@ -0,0 +1,9 @@ +// +build js +// +build !appengine + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go new file mode 100644 index 00000000..66a58b5d --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -0,0 +1,79 @@ +// +build !windows +// +build !js +// +build !appengine + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go new file mode 100644 index 00000000..d6a61777 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -0,0 +1,28 @@ +// +build windows +// +build !appengine + +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} diff --git a/vendor/github.com/miekg/dns/.codecov.yml b/vendor/github.com/miekg/dns/.codecov.yml new file mode 100644 index 00000000..f91e5c1f --- /dev/null +++ b/vendor/github.com/miekg/dns/.codecov.yml @@ -0,0 +1,8 @@ +coverage: + status: + project: + default: + target: 40% + threshold: null + patch: false + changes: false diff --git a/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/miekg/dns/.gitignore new file mode 100644 index 00000000..776cd950 --- /dev/null +++ b/vendor/github.com/miekg/dns/.gitignore @@ -0,0 +1,4 @@ +*.6 +tags +test.out +a.out diff --git a/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/miekg/dns/.travis.yml new file mode 100644 index 00000000..013b5ae4 --- /dev/null +++ b/vendor/github.com/miekg/dns/.travis.yml @@ -0,0 +1,19 @@ +language: go +sudo: false + +go: + - 1.10.x + - 1.11.x + - 1.12.x + - tip + +before_install: + # don't use the miekg/dns when testing forks + - mkdir -p $GOPATH/src/github.com/miekg + - ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/miekg/ || true + +script: + - go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./... + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/miekg/dns/AUTHORS b/vendor/github.com/miekg/dns/AUTHORS new file mode 100644 index 00000000..19656835 --- /dev/null +++ b/vendor/github.com/miekg/dns/AUTHORS @@ -0,0 +1 @@ +Miek Gieben diff --git a/vendor/github.com/miekg/dns/CONTRIBUTORS b/vendor/github.com/miekg/dns/CONTRIBUTORS new file mode 100644 index 00000000..5903779d --- /dev/null +++ b/vendor/github.com/miekg/dns/CONTRIBUTORS @@ -0,0 +1,10 @@ +Alex A. Skinner +Andrew Tunnell-Jones +Ask Bjørn Hansen +Dave Cheney +Dusty Wilson +Marek Majkowski +Peter van Dijk +Omri Bahumi +Alex Sergeyev +James Hartig diff --git a/vendor/github.com/miekg/dns/COPYRIGHT b/vendor/github.com/miekg/dns/COPYRIGHT new file mode 100644 index 00000000..35702b10 --- /dev/null +++ b/vendor/github.com/miekg/dns/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright 2009 The Go Authors. All rights reserved. Use of this source code +is governed by a BSD-style license that can be found in the LICENSE file. +Extensions of the original work are copyright (c) 2011 Miek Gieben + +Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is +governed by a BSD-style license that can be found in the LICENSE file. + +Copyright 2014 CloudFlare. All rights reserved. Use of this source code is +governed by a BSD-style license that can be found in the LICENSE file. diff --git a/vendor/github.com/miekg/dns/Gopkg.lock b/vendor/github.com/miekg/dns/Gopkg.lock new file mode 100644 index 00000000..66be346a --- /dev/null +++ b/vendor/github.com/miekg/dns/Gopkg.lock @@ -0,0 +1,33 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["ed25519","ed25519/internal/edwards25519"] + revision = "20be4c3c3ed52bfccdb2d59a412ee1a936d175a7" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = ["bpf","internal/iana","internal/socket","ipv4","ipv6"] + revision = "60506f45cf65977eb3a9c6e30f995f54a721c271" + +[[projects]] + branch = "master" + name = "golang.org/x/sync" + packages = ["errgroup"] + revision = "112230192c580c3556b8cee6403af37a4fc5f28c" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix","windows"] + revision = "4c4f7f33c9ed00de01c4c741d2177abfcfe19307" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "fc70ece982d3660454fe1b9ccd5c91162a1cc080b58ad82aa065ad4a2ec93ce9" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/miekg/dns/Gopkg.toml b/vendor/github.com/miekg/dns/Gopkg.toml new file mode 100644 index 00000000..85e6ff31 --- /dev/null +++ b/vendor/github.com/miekg/dns/Gopkg.toml @@ -0,0 +1,38 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[constraint]] + branch = "master" + name = "golang.org/x/crypto" + +[[constraint]] + branch = "master" + name = "golang.org/x/net" + +[[constraint]] + branch = "master" + name = "golang.org/x/sys" + +[[constraint]] + branch = "master" + name = "golang.org/x/sync" diff --git a/vendor/github.com/miekg/dns/LICENSE b/vendor/github.com/miekg/dns/LICENSE new file mode 100644 index 00000000..5763fa7f --- /dev/null +++ b/vendor/github.com/miekg/dns/LICENSE @@ -0,0 +1,32 @@ +Extensions of the original work are copyright (c) 2011 Miek Gieben + +As this is fork of the official Go code the same license applies: + +Copyright (c) 2009 The Go Authors. All rights reserved. + +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. + diff --git a/vendor/github.com/miekg/dns/Makefile.fuzz b/vendor/github.com/miekg/dns/Makefile.fuzz new file mode 100644 index 00000000..dc158c4a --- /dev/null +++ b/vendor/github.com/miekg/dns/Makefile.fuzz @@ -0,0 +1,33 @@ +# Makefile for fuzzing +# +# Use go-fuzz and needs the tools installed. +# See https://blog.cloudflare.com/dns-parser-meet-go-fuzzer/ +# +# Installing go-fuzz: +# $ make -f Makefile.fuzz get +# Installs: +# * github.com/dvyukov/go-fuzz/go-fuzz +# * get github.com/dvyukov/go-fuzz/go-fuzz-build + +all: build + +.PHONY: build +build: + go-fuzz-build -tags fuzz github.com/miekg/dns + +.PHONY: build-newrr +build-newrr: + go-fuzz-build -func FuzzNewRR -tags fuzz github.com/miekg/dns + +.PHONY: fuzz +fuzz: + go-fuzz -bin=dns-fuzz.zip -workdir=fuzz + +.PHONY: get +get: + go get github.com/dvyukov/go-fuzz/go-fuzz + go get github.com/dvyukov/go-fuzz/go-fuzz-build + +.PHONY: clean +clean: + rm *-fuzz.zip diff --git a/vendor/github.com/miekg/dns/Makefile.release b/vendor/github.com/miekg/dns/Makefile.release new file mode 100644 index 00000000..8fb748e8 --- /dev/null +++ b/vendor/github.com/miekg/dns/Makefile.release @@ -0,0 +1,52 @@ +# Makefile for releasing. +# +# The release is controlled from version.go. The version found there is +# used to tag the git repo, we're not building any artifects so there is nothing +# to upload to github. +# +# * Up the version in version.go +# * Run: make -f Makefile.release release +# * will *commit* your change with 'Release $VERSION' +# * push to github +# + +define GO +//+build ignore + +package main + +import ( + "fmt" + + "github.com/miekg/dns" +) + +func main() { + fmt.Println(dns.Version.String()) +} +endef + +$(file > version_release.go,$(GO)) +VERSION:=$(shell go run version_release.go) +TAG="v$(VERSION)" + +all: + @echo Use the \'release\' target to start a release $(VERSION) + rm -f version_release.go + +.PHONY: release +release: commit push + @echo Released $(VERSION) + rm -f version_release.go + +.PHONY: commit +commit: + @echo Committing release $(VERSION) + git commit -am"Release $(VERSION)" + git tag $(TAG) + +.PHONY: push +push: + @echo Pushing release $(VERSION) to master + git push --tags + git push diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md new file mode 100644 index 00000000..de4afed6 --- /dev/null +++ b/vendor/github.com/miekg/dns/README.md @@ -0,0 +1,174 @@ +[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) +[![Code Coverage](https://img.shields.io/codecov/c/github/miekg/dns/master.svg)](https://codecov.io/github/miekg/dns?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/miekg/dns)](https://goreportcard.com/report/miekg/dns) +[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns) + +# Alternative (more granular) approach to a DNS library + +> Less is more. + +Complete and usable DNS library. All Resource Records are supported, including the DNSSEC types. +It follows a lean and mean philosophy. If there is stuff you should know as a DNS programmer there +isn't a convenience function for it. Server side and client side programming is supported, i.e. you +can build servers and resolvers with it. + +We try to keep the "master" branch as sane as possible and at the bleeding edge of standards, +avoiding breaking changes wherever reasonable. We support the last two versions of Go. + +# Goals + +* KISS; +* Fast; +* Small API. If it's easy to code in Go, don't make a function for it. + +# Users + +A not-so-up-to-date-list-that-may-be-actually-current: + +* https://github.com/coredns/coredns +* https://cloudflare.com +* https://github.com/abh/geodns +* http://www.statdns.com/ +* http://www.dnsinspect.com/ +* https://github.com/chuangbo/jianbing-dictionary-dns +* http://www.dns-lg.com/ +* https://github.com/fcambus/rrda +* https://github.com/kenshinx/godns +* https://github.com/skynetservices/skydns +* https://github.com/hashicorp/consul +* https://github.com/DevelopersPL/godnsagent +* https://github.com/duedil-ltd/discodns +* https://github.com/StalkR/dns-reverse-proxy +* https://github.com/tianon/rawdns +* https://mesosphere.github.io/mesos-dns/ +* https://pulse.turbobytes.com/ +* https://github.com/fcambus/statzone +* https://github.com/benschw/dns-clb-go +* https://github.com/corny/dnscheck for +* https://namesmith.io +* https://github.com/miekg/unbound +* https://github.com/miekg/exdns +* https://dnslookup.org +* https://github.com/looterz/grimd +* https://github.com/phamhongviet/serf-dns +* https://github.com/mehrdadrad/mylg +* https://github.com/bamarni/dockness +* https://github.com/fffaraz/microdns +* http://kelda.io +* https://github.com/ipdcode/hades +* https://github.com/StackExchange/dnscontrol/ +* https://www.dnsperf.com/ +* https://dnssectest.net/ +* https://dns.apebits.com +* https://github.com/oif/apex +* https://github.com/jedisct1/dnscrypt-proxy +* https://github.com/jedisct1/rpdns +* https://github.com/xor-gate/sshfp +* https://github.com/rs/dnstrace +* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss)) +* https://github.com/semihalev/sdns +* https://render.com +* https://github.com/peterzen/goresolver +* https://github.com/folbricht/routedns + +Send pull request if you want to be listed here. + +# Features + +* UDP/TCP queries, IPv4 and IPv6 +* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported +* Fast +* Server side programming (mimicking the net/http package) +* Client side programming +* DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA and Ed25519 +* EDNS0, NSID, Cookies +* AXFR/IXFR +* TSIG, SIG(0) +* DNS over TLS (DoT): encrypted connection between client and server over TCP +* DNS name compression + +Have fun! + +Miek Gieben - 2010-2012 - +DNS Authors 2012- + +# Building + +Building is done with the `go` tool. If you have setup your GOPATH correctly, the following should +work: + + go get github.com/miekg/dns + go build github.com/miekg/dns + +## Examples + +A short "how to use the API" is at the beginning of doc.go (this also will show when you call `godoc +github.com/miekg/dns`). + +Example programs can be found in the `github.com/miekg/exdns` repository. + +## Supported RFCs + +*all of them* + +* 103{4,5} - DNS standard +* 1348 - NSAP record (removed the record) +* 1982 - Serial Arithmetic +* 1876 - LOC record +* 1995 - IXFR +* 1996 - DNS notify +* 2136 - DNS Update (dynamic updates) +* 2181 - RRset definition - there is no RRset type though, just []RR +* 2537 - RSAMD5 DNS keys +* 2065 - DNSSEC (updated in later RFCs) +* 2671 - EDNS record +* 2782 - SRV record +* 2845 - TSIG record +* 2915 - NAPTR record +* 2929 - DNS IANA Considerations +* 3110 - RSASHA1 DNS keys +* 3225 - DO bit (DNSSEC OK) +* 340{1,2,3} - NAPTR record +* 3445 - Limiting the scope of (DNS)KEY +* 3597 - Unknown RRs +* 403{3,4,5} - DNSSEC + validation functions +* 4255 - SSHFP record +* 4343 - Case insensitivity +* 4408 - SPF record +* 4509 - SHA256 Hash in DS +* 4592 - Wildcards in the DNS +* 4635 - HMAC SHA TSIG +* 4701 - DHCID +* 4892 - id.server +* 5001 - NSID +* 5155 - NSEC3 record +* 5205 - HIP record +* 5702 - SHA2 in the DNS +* 5936 - AXFR +* 5966 - TCP implementation recommendations +* 6605 - ECDSA +* 6725 - IANA Registry Update +* 6742 - ILNP DNS +* 6840 - Clarifications and Implementation Notes for DNS Security +* 6844 - CAA record +* 6891 - EDNS0 update +* 6895 - DNS IANA considerations +* 6944 - DNSSEC DNSKEY Algorithm Status +* 6975 - Algorithm Understanding in DNSSEC +* 7043 - EUI48/EUI64 records +* 7314 - DNS (EDNS) EXPIRE Option +* 7477 - CSYNC RR +* 7828 - edns-tcp-keepalive EDNS0 Option +* 7553 - URI record +* 7858 - DNS over TLS: Initiation and Performance Considerations +* 7871 - EDNS0 Client Subnet +* 7873 - Domain Name System (DNS) Cookies +* 8080 - EdDSA for DNSSEC +* 8499 - DNS Terminology + +## Loosely Based Upon + +* ldns - +* NSD - +* Net::DNS - +* GRONG - diff --git a/vendor/github.com/miekg/dns/acceptfunc.go b/vendor/github.com/miekg/dns/acceptfunc.go new file mode 100644 index 00000000..94e7c9d9 --- /dev/null +++ b/vendor/github.com/miekg/dns/acceptfunc.go @@ -0,0 +1,53 @@ +package dns + +// MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError. +// It returns a MsgAcceptAction to indicate what should happen with the message. +type MsgAcceptFunc func(dh Header) MsgAcceptAction + +// DefaultMsgAcceptFunc checks the request and will reject if: +// +// * isn't a request (don't respond in that case). +// * opcode isn't OpcodeQuery or OpcodeNotify +// * Zero bit isn't zero +// * has more than 1 question in the question section +// * has more than 1 RR in the Answer section +// * has more than 0 RRs in the Authority section +// * has more than 2 RRs in the Additional section +var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc + +// MsgAcceptAction represents the action to be taken. +type MsgAcceptAction int + +const ( + MsgAccept MsgAcceptAction = iota // Accept the message + MsgReject // Reject the message with a RcodeFormatError + MsgIgnore // Ignore the error and send nothing back. +) + +func defaultMsgAcceptFunc(dh Header) MsgAcceptAction { + if isResponse := dh.Bits&_QR != 0; isResponse { + return MsgIgnore + } + + // Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs. + opcode := int(dh.Bits>>11) & 0xF + if opcode != OpcodeQuery && opcode != OpcodeNotify { + return MsgReject + } + + if dh.Qdcount != 1 { + return MsgReject + } + // NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11. + if dh.Ancount > 1 { + return MsgReject + } + // IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3. + if dh.Nscount > 1 { + return MsgReject + } + if dh.Arcount > 2 { + return MsgReject + } + return MsgAccept +} diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go new file mode 100644 index 00000000..db2761d4 --- /dev/null +++ b/vendor/github.com/miekg/dns/client.go @@ -0,0 +1,415 @@ +package dns + +// A client implementation. + +import ( + "context" + "crypto/tls" + "encoding/binary" + "fmt" + "io" + "net" + "strings" + "time" +) + +const ( + dnsTimeout time.Duration = 2 * time.Second + tcpIdleTimeout time.Duration = 8 * time.Second +) + +// A Conn represents a connection to a DNS server. +type Conn struct { + net.Conn // a net.Conn holding the connection + UDPSize uint16 // minimum receive buffer for UDP messages + TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) + tsigRequestMAC string +} + +// A Client defines parameters for a DNS client. +type Client struct { + Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP) + UDPSize uint16 // minimum receive buffer for UDP messages + TLSConfig *tls.Config // TLS connection configuration + Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more + // Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout, + // WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and + // Client.Dialer) or context.Context.Deadline (see the deprecated ExchangeContext) + Timeout time.Duration + DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero + ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero + WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero + TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) + SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass + group singleflight +} + +// Exchange performs a synchronous UDP query. It sends the message m to the address +// contained in a and waits for a reply. Exchange does not retry a failed query, nor +// will it fall back to TCP in case of truncation. +// See client.Exchange for more information on setting larger buffer sizes. +func Exchange(m *Msg, a string) (r *Msg, err error) { + client := Client{Net: "udp"} + r, _, err = client.Exchange(m, a) + return r, err +} + +func (c *Client) dialTimeout() time.Duration { + if c.Timeout != 0 { + return c.Timeout + } + if c.DialTimeout != 0 { + return c.DialTimeout + } + return dnsTimeout +} + +func (c *Client) readTimeout() time.Duration { + if c.ReadTimeout != 0 { + return c.ReadTimeout + } + return dnsTimeout +} + +func (c *Client) writeTimeout() time.Duration { + if c.WriteTimeout != 0 { + return c.WriteTimeout + } + return dnsTimeout +} + +// Dial connects to the address on the named network. +func (c *Client) Dial(address string) (conn *Conn, err error) { + // create a new dialer with the appropriate timeout + var d net.Dialer + if c.Dialer == nil { + d = net.Dialer{Timeout: c.getTimeoutForRequest(c.dialTimeout())} + } else { + d = *c.Dialer + } + + network := c.Net + if network == "" { + network = "udp" + } + + useTLS := strings.HasPrefix(network, "tcp") && strings.HasSuffix(network, "-tls") + + conn = new(Conn) + if useTLS { + network = strings.TrimSuffix(network, "-tls") + + conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig) + } else { + conn.Conn, err = d.Dial(network, address) + } + if err != nil { + return nil, err + } + + return conn, nil +} + +// Exchange performs a synchronous query. It sends the message m to the address +// contained in a and waits for a reply. Basic use pattern with a *dns.Client: +// +// c := new(dns.Client) +// in, rtt, err := c.Exchange(message, "127.0.0.1:53") +// +// Exchange does not retry a failed query, nor will it fall back to TCP in +// case of truncation. +// It is up to the caller to create a message that allows for larger responses to be +// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger +// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit +// of 512 bytes +// To specify a local address or a timeout, the caller has to set the `Client.Dialer` +// attribute appropriately +func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) { + if !c.SingleInflight { + return c.exchange(m, address) + } + + q := m.Question[0] + key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass) + r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) { + return c.exchange(m, address) + }) + if r != nil && shared { + r = r.Copy() + } + + return r, rtt, err +} + +func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { + var co *Conn + + co, err = c.Dial(a) + + if err != nil { + return nil, 0, err + } + defer co.Close() + + opt := m.IsEdns0() + // If EDNS0 is used use that for size. + if opt != nil && opt.UDPSize() >= MinMsgSize { + co.UDPSize = opt.UDPSize() + } + // Otherwise use the client's configured UDP size. + if opt == nil && c.UDPSize >= MinMsgSize { + co.UDPSize = c.UDPSize + } + + co.TsigSecret = c.TsigSecret + t := time.Now() + // write with the appropriate write timeout + co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout()))) + if err = co.WriteMsg(m); err != nil { + return nil, 0, err + } + + co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout()))) + r, err = co.ReadMsg() + if err == nil && r.Id != m.Id { + err = ErrId + } + rtt = time.Since(t) + return r, rtt, err +} + +// ReadMsg reads a message from the connection co. +// If the received message contains a TSIG record the transaction signature +// is verified. This method always tries to return the message, however if an +// error is returned there are no guarantees that the returned message is a +// valid representation of the packet read. +func (co *Conn) ReadMsg() (*Msg, error) { + p, err := co.ReadMsgHeader(nil) + if err != nil { + return nil, err + } + + m := new(Msg) + if err := m.Unpack(p); err != nil { + // If an error was returned, we still want to allow the user to use + // the message, but naively they can just check err if they don't want + // to use an erroneous message + return m, err + } + if t := m.IsTsig(); t != nil { + if _, ok := co.TsigSecret[t.Hdr.Name]; !ok { + return m, ErrSecret + } + // Need to work on the original message p, as that was used to calculate the tsig. + err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false) + } + return m, err +} + +// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil). +// Returns message as a byte slice to be parsed with Msg.Unpack later on. +// Note that error handling on the message body is not possible as only the header is parsed. +func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) { + var ( + p []byte + n int + err error + ) + + if _, ok := co.Conn.(net.PacketConn); ok { + if co.UDPSize > MinMsgSize { + p = make([]byte, co.UDPSize) + } else { + p = make([]byte, MinMsgSize) + } + n, err = co.Read(p) + } else { + var length uint16 + if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil { + return nil, err + } + + p = make([]byte, length) + n, err = io.ReadFull(co.Conn, p) + } + + if err != nil { + return nil, err + } else if n < headerSize { + return nil, ErrShortRead + } + + p = p[:n] + if hdr != nil { + dh, _, err := unpackMsgHdr(p, 0) + if err != nil { + return nil, err + } + *hdr = dh + } + return p, err +} + +// Read implements the net.Conn read method. +func (co *Conn) Read(p []byte) (n int, err error) { + if co.Conn == nil { + return 0, ErrConnEmpty + } + + if _, ok := co.Conn.(net.PacketConn); ok { + // UDP connection + return co.Conn.Read(p) + } + + var length uint16 + if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil { + return 0, err + } + if int(length) > len(p) { + return 0, io.ErrShortBuffer + } + + return io.ReadFull(co.Conn, p[:length]) +} + +// WriteMsg sends a message through the connection co. +// If the message m contains a TSIG record the transaction +// signature is calculated. +func (co *Conn) WriteMsg(m *Msg) (err error) { + var out []byte + if t := m.IsTsig(); t != nil { + mac := "" + if _, ok := co.TsigSecret[t.Hdr.Name]; !ok { + return ErrSecret + } + out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false) + // Set for the next read, although only used in zone transfers + co.tsigRequestMAC = mac + } else { + out, err = m.Pack() + } + if err != nil { + return err + } + _, err = co.Write(out) + return err +} + +// Write implements the net.Conn Write method. +func (co *Conn) Write(p []byte) (int, error) { + if len(p) > MaxMsgSize { + return 0, &Error{err: "message too large"} + } + + if _, ok := co.Conn.(net.PacketConn); ok { + return co.Conn.Write(p) + } + + l := make([]byte, 2) + binary.BigEndian.PutUint16(l, uint16(len(p))) + + n, err := (&net.Buffers{l, p}).WriteTo(co.Conn) + return int(n), err +} + +// Return the appropriate timeout for a specific request +func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration { + var requestTimeout time.Duration + if c.Timeout != 0 { + requestTimeout = c.Timeout + } else { + requestTimeout = timeout + } + // net.Dialer.Timeout has priority if smaller than the timeouts computed so + // far + if c.Dialer != nil && c.Dialer.Timeout != 0 { + if c.Dialer.Timeout < requestTimeout { + requestTimeout = c.Dialer.Timeout + } + } + return requestTimeout +} + +// Dial connects to the address on the named network. +func Dial(network, address string) (conn *Conn, err error) { + conn = new(Conn) + conn.Conn, err = net.Dial(network, address) + if err != nil { + return nil, err + } + return conn, nil +} + +// ExchangeContext performs a synchronous UDP query, like Exchange. It +// additionally obeys deadlines from the passed Context. +func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) { + client := Client{Net: "udp"} + r, _, err = client.ExchangeContext(ctx, m, a) + // ignorint rtt to leave the original ExchangeContext API unchanged, but + // this function will go away + return r, err +} + +// ExchangeConn performs a synchronous query. It sends the message m via the connection +// c and waits for a reply. The connection c is not closed by ExchangeConn. +// Deprecated: This function is going away, but can easily be mimicked: +// +// co := &dns.Conn{Conn: c} // c is your net.Conn +// co.WriteMsg(m) +// in, _ := co.ReadMsg() +// co.Close() +// +func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { + println("dns: ExchangeConn: this function is deprecated") + co := new(Conn) + co.Conn = c + if err = co.WriteMsg(m); err != nil { + return nil, err + } + r, err = co.ReadMsg() + if err == nil && r.Id != m.Id { + err = ErrId + } + return r, err +} + +// DialTimeout acts like Dial but takes a timeout. +func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) { + client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}} + return client.Dial(address) +} + +// DialWithTLS connects to the address on the named network with TLS. +func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) { + if !strings.HasSuffix(network, "-tls") { + network += "-tls" + } + client := Client{Net: network, TLSConfig: tlsConfig} + return client.Dial(address) +} + +// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout. +func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) { + if !strings.HasSuffix(network, "-tls") { + network += "-tls" + } + client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig} + return client.Dial(address) +} + +// ExchangeContext acts like Exchange, but honors the deadline on the provided +// context, if present. If there is both a context deadline and a configured +// timeout on the client, the earliest of the two takes effect. +func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) { + var timeout time.Duration + if deadline, ok := ctx.Deadline(); !ok { + timeout = 0 + } else { + timeout = time.Until(deadline) + } + // not passing the context to the underlying calls, as the API does not support + // context. For timeouts you should set up Client.Dialer and call Client.Exchange. + // TODO(tmthrgd,miekg): this is a race condition. + c.Dialer = &net.Dialer{Timeout: timeout} + return c.Exchange(m, a) +} diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go new file mode 100644 index 00000000..e11b630d --- /dev/null +++ b/vendor/github.com/miekg/dns/clientconfig.go @@ -0,0 +1,135 @@ +package dns + +import ( + "bufio" + "io" + "os" + "strconv" + "strings" +) + +// ClientConfig wraps the contents of the /etc/resolv.conf file. +type ClientConfig struct { + Servers []string // servers to use + Search []string // suffixes to append to local name + Port string // what port to use + Ndots int // number of dots in name to trigger absolute lookup + Timeout int // seconds before giving up on packet + Attempts int // lost packets before giving up on server, not used in the package dns +} + +// ClientConfigFromFile parses a resolv.conf(5) like file and returns +// a *ClientConfig. +func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { + file, err := os.Open(resolvconf) + if err != nil { + return nil, err + } + defer file.Close() + return ClientConfigFromReader(file) +} + +// ClientConfigFromReader works like ClientConfigFromFile but takes an io.Reader as argument +func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) { + c := new(ClientConfig) + scanner := bufio.NewScanner(resolvconf) + c.Servers = make([]string, 0) + c.Search = make([]string, 0) + c.Port = "53" + c.Ndots = 1 + c.Timeout = 5 + c.Attempts = 2 + + for scanner.Scan() { + if err := scanner.Err(); err != nil { + return nil, err + } + line := scanner.Text() + f := strings.Fields(line) + if len(f) < 1 { + continue + } + switch f[0] { + case "nameserver": // add one name server + if len(f) > 1 { + // One more check: make sure server name is + // just an IP address. Otherwise we need DNS + // to look it up. + name := f[1] + c.Servers = append(c.Servers, name) + } + + case "domain": // set search path to just this domain + if len(f) > 1 { + c.Search = make([]string, 1) + c.Search[0] = f[1] + } else { + c.Search = make([]string, 0) + } + + case "search": // set search path to given servers + c.Search = append([]string(nil), f[1:]...) + + case "options": // magic options + for _, s := range f[1:] { + switch { + case len(s) >= 6 && s[:6] == "ndots:": + n, _ := strconv.Atoi(s[6:]) + if n < 0 { + n = 0 + } else if n > 15 { + n = 15 + } + c.Ndots = n + case len(s) >= 8 && s[:8] == "timeout:": + n, _ := strconv.Atoi(s[8:]) + if n < 1 { + n = 1 + } + c.Timeout = n + case len(s) >= 9 && s[:9] == "attempts:": + n, _ := strconv.Atoi(s[9:]) + if n < 1 { + n = 1 + } + c.Attempts = n + case s == "rotate": + /* not imp */ + } + } + } + } + return c, nil +} + +// NameList returns all of the names that should be queried based on the +// config. It is based off of go's net/dns name building, but it does not +// check the length of the resulting names. +func (c *ClientConfig) NameList(name string) []string { + // if this domain is already fully qualified, no append needed. + if IsFqdn(name) { + return []string{name} + } + + // Check to see if the name has more labels than Ndots. Do this before making + // the domain fully qualified. + hasNdots := CountLabel(name) > c.Ndots + // Make the domain fully qualified. + name = Fqdn(name) + + // Make a list of names based off search. + names := []string{} + + // If name has enough dots, try that first. + if hasNdots { + names = append(names, name) + } + for _, s := range c.Search { + names = append(names, Fqdn(name+s)) + } + // If we didn't have enough dots, try after suffixes. + if !hasNdots { + names = append(names, name) + } + return names +} diff --git a/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/miekg/dns/dane.go new file mode 100644 index 00000000..8c4a14ef --- /dev/null +++ b/vendor/github.com/miekg/dns/dane.go @@ -0,0 +1,43 @@ +package dns + +import ( + "crypto/sha256" + "crypto/sha512" + "crypto/x509" + "encoding/hex" + "errors" +) + +// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records. +func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { + switch matchingType { + case 0: + switch selector { + case 0: + return hex.EncodeToString(cert.Raw), nil + case 1: + return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil + } + case 1: + h := sha256.New() + switch selector { + case 0: + h.Write(cert.Raw) + return hex.EncodeToString(h.Sum(nil)), nil + case 1: + h.Write(cert.RawSubjectPublicKeyInfo) + return hex.EncodeToString(h.Sum(nil)), nil + } + case 2: + h := sha512.New() + switch selector { + case 0: + h.Write(cert.Raw) + return hex.EncodeToString(h.Sum(nil)), nil + case 1: + h.Write(cert.RawSubjectPublicKeyInfo) + return hex.EncodeToString(h.Sum(nil)), nil + } + } + return "", errors.New("dns: bad MatchingType or Selector") +} diff --git a/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/miekg/dns/defaults.go new file mode 100644 index 00000000..b059f6fc --- /dev/null +++ b/vendor/github.com/miekg/dns/defaults.go @@ -0,0 +1,378 @@ +package dns + +import ( + "errors" + "net" + "strconv" + "strings" +) + +const hexDigit = "0123456789abcdef" + +// Everything is assumed in ClassINET. + +// SetReply creates a reply message from a request message. +func (dns *Msg) SetReply(request *Msg) *Msg { + dns.Id = request.Id + dns.Response = true + dns.Opcode = request.Opcode + if dns.Opcode == OpcodeQuery { + dns.RecursionDesired = request.RecursionDesired // Copy rd bit + dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit + } + dns.Rcode = RcodeSuccess + if len(request.Question) > 0 { + dns.Question = make([]Question, 1) + dns.Question[0] = request.Question[0] + } + return dns +} + +// SetQuestion creates a question message, it sets the Question +// section, generates an Id and sets the RecursionDesired (RD) +// bit to true. +func (dns *Msg) SetQuestion(z string, t uint16) *Msg { + dns.Id = Id() + dns.RecursionDesired = true + dns.Question = make([]Question, 1) + dns.Question[0] = Question{z, t, ClassINET} + return dns +} + +// SetNotify creates a notify message, it sets the Question +// section, generates an Id and sets the Authoritative (AA) +// bit to true. +func (dns *Msg) SetNotify(z string) *Msg { + dns.Opcode = OpcodeNotify + dns.Authoritative = true + dns.Id = Id() + dns.Question = make([]Question, 1) + dns.Question[0] = Question{z, TypeSOA, ClassINET} + return dns +} + +// SetRcode creates an error message suitable for the request. +func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg { + dns.SetReply(request) + dns.Rcode = rcode + return dns +} + +// SetRcodeFormatError creates a message with FormError set. +func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg { + dns.Rcode = RcodeFormatError + dns.Opcode = OpcodeQuery + dns.Response = true + dns.Authoritative = false + dns.Id = request.Id + return dns +} + +// SetUpdate makes the message a dynamic update message. It +// sets the ZONE section to: z, TypeSOA, ClassINET. +func (dns *Msg) SetUpdate(z string) *Msg { + dns.Id = Id() + dns.Response = false + dns.Opcode = OpcodeUpdate + dns.Compress = false // BIND9 cannot handle compression + dns.Question = make([]Question, 1) + dns.Question[0] = Question{z, TypeSOA, ClassINET} + return dns +} + +// SetIxfr creates message for requesting an IXFR. +func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg { + dns.Id = Id() + dns.Question = make([]Question, 1) + dns.Ns = make([]RR, 1) + s := new(SOA) + s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0} + s.Serial = serial + s.Ns = ns + s.Mbox = mbox + dns.Question[0] = Question{z, TypeIXFR, ClassINET} + dns.Ns[0] = s + return dns +} + +// SetAxfr creates message for requesting an AXFR. +func (dns *Msg) SetAxfr(z string) *Msg { + dns.Id = Id() + dns.Question = make([]Question, 1) + dns.Question[0] = Question{z, TypeAXFR, ClassINET} + return dns +} + +// SetTsig appends a TSIG RR to the message. +// This is only a skeleton TSIG RR that is added as the last RR in the +// additional section. The Tsig is calculated when the message is being send. +func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg { + t := new(TSIG) + t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0} + t.Algorithm = algo + t.Fudge = fudge + t.TimeSigned = uint64(timesigned) + t.OrigId = dns.Id + dns.Extra = append(dns.Extra, t) + return dns +} + +// SetEdns0 appends a EDNS0 OPT RR to the message. +// TSIG should always the last RR in a message. +func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg { + e := new(OPT) + e.Hdr.Name = "." + e.Hdr.Rrtype = TypeOPT + e.SetUDPSize(udpsize) + if do { + e.SetDo() + } + dns.Extra = append(dns.Extra, e) + return dns +} + +// IsTsig checks if the message has a TSIG record as the last record +// in the additional section. It returns the TSIG record found or nil. +func (dns *Msg) IsTsig() *TSIG { + if len(dns.Extra) > 0 { + if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG { + return dns.Extra[len(dns.Extra)-1].(*TSIG) + } + } + return nil +} + +// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0 +// record in the additional section will do. It returns the OPT record +// found or nil. +func (dns *Msg) IsEdns0() *OPT { + // RFC 6891, Section 6.1.1 allows the OPT record to appear + // anywhere in the additional record section, but it's usually at + // the end so start there. + for i := len(dns.Extra) - 1; i >= 0; i-- { + if dns.Extra[i].Header().Rrtype == TypeOPT { + return dns.Extra[i].(*OPT) + } + } + return nil +} + +// popEdns0 is like IsEdns0, but it removes the record from the message. +func (dns *Msg) popEdns0() *OPT { + // RFC 6891, Section 6.1.1 allows the OPT record to appear + // anywhere in the additional record section, but it's usually at + // the end so start there. + for i := len(dns.Extra) - 1; i >= 0; i-- { + if dns.Extra[i].Header().Rrtype == TypeOPT { + opt := dns.Extra[i].(*OPT) + dns.Extra = append(dns.Extra[:i], dns.Extra[i+1:]...) + return opt + } + } + return nil +} + +// IsDomainName checks if s is a valid domain name, it returns the number of +// labels and true, when a domain name is valid. Note that non fully qualified +// domain name is considered valid, in this case the last label is counted in +// the number of labels. When false is returned the number of labels is not +// defined. Also note that this function is extremely liberal; almost any +// string is a valid domain name as the DNS is 8 bit protocol. It checks if each +// label fits in 63 characters and that the entire name will fit into the 255 +// octet wire format limit. +func IsDomainName(s string) (labels int, ok bool) { + // XXX: The logic in this function was copied from packDomainName and + // should be kept in sync with that function. + + const lenmsg = 256 + + if len(s) == 0 { // Ok, for instance when dealing with update RR without any rdata. + return 0, false + } + + s = Fqdn(s) + + // Each dot ends a segment of the name. Except for escaped dots (\.), which + // are normal dots. + + var ( + off int + begin int + wasDot bool + ) + for i := 0; i < len(s); i++ { + switch s[i] { + case '\\': + if off+1 > lenmsg { + return labels, false + } + + // check for \DDD + if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) { + i += 3 + begin += 3 + } else { + i++ + begin++ + } + + wasDot = false + case '.': + if wasDot { + // two dots back to back is not legal + return labels, false + } + wasDot = true + + labelLen := i - begin + if labelLen >= 1<<6 { // top two bits of length must be clear + return labels, false + } + + // off can already (we're in a loop) be bigger than lenmsg + // this happens when a name isn't fully qualified + off += 1 + labelLen + if off > lenmsg { + return labels, false + } + + labels++ + begin = i + 1 + default: + wasDot = false + } + } + + return labels, true +} + +// IsSubDomain checks if child is indeed a child of the parent. If child and parent +// are the same domain true is returned as well. +func IsSubDomain(parent, child string) bool { + // Entire child is contained in parent + return CompareDomainName(parent, child) == CountLabel(parent) +} + +// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet. +// The checking is performed on the binary payload. +func IsMsg(buf []byte) error { + // Header + if len(buf) < headerSize { + return errors.New("dns: bad message header") + } + // Header: Opcode + // TODO(miek): more checks here, e.g. check all header bits. + return nil +} + +// IsFqdn checks if a domain name is fully qualified. +func IsFqdn(s string) bool { + s2 := strings.TrimSuffix(s, ".") + if s == s2 { + return false + } + + i := strings.LastIndexFunc(s2, func(r rune) bool { + return r != '\\' + }) + + // Test whether we have an even number of escape sequences before + // the dot or none. + return (len(s2)-i)%2 != 0 +} + +// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181. +// This means the RRs need to have the same type, name, and class. Returns true +// if the RR set is valid, otherwise false. +func IsRRset(rrset []RR) bool { + if len(rrset) == 0 { + return false + } + if len(rrset) == 1 { + return true + } + rrHeader := rrset[0].Header() + rrType := rrHeader.Rrtype + rrClass := rrHeader.Class + rrName := rrHeader.Name + + for _, rr := range rrset[1:] { + curRRHeader := rr.Header() + if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName { + // Mismatch between the records, so this is not a valid rrset for + //signing/verifying + return false + } + } + + return true +} + +// Fqdn return the fully qualified domain name from s. +// If s is already fully qualified, it behaves as the identity function. +func Fqdn(s string) string { + if IsFqdn(s) { + return s + } + return s + "." +} + +// Copied from the official Go code. + +// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP +// address suitable for reverse DNS (PTR) record lookups or an error if it fails +// to parse the IP address. +func ReverseAddr(addr string) (arpa string, err error) { + ip := net.ParseIP(addr) + if ip == nil { + return "", &Error{err: "unrecognized address: " + addr} + } + if v4 := ip.To4(); v4 != nil { + buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa.")) + // Add it, in reverse, to the buffer + for i := len(v4) - 1; i >= 0; i-- { + buf = strconv.AppendInt(buf, int64(v4[i]), 10) + buf = append(buf, '.') + } + // Append "in-addr.arpa." and return (buf already has the final .) + buf = append(buf, "in-addr.arpa."...) + return string(buf), nil + } + // Must be IPv6 + buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa.")) + // Add it, in reverse, to the buffer + for i := len(ip) - 1; i >= 0; i-- { + v := ip[i] + buf = append(buf, hexDigit[v&0xF]) + buf = append(buf, '.') + buf = append(buf, hexDigit[v>>4]) + buf = append(buf, '.') + } + // Append "ip6.arpa." and return (buf already has the final .) + buf = append(buf, "ip6.arpa."...) + return string(buf), nil +} + +// String returns the string representation for the type t. +func (t Type) String() string { + if t1, ok := TypeToString[uint16(t)]; ok { + return t1 + } + return "TYPE" + strconv.Itoa(int(t)) +} + +// String returns the string representation for the class c. +func (c Class) String() string { + if s, ok := ClassToString[uint16(c)]; ok { + // Only emit mnemonics when they are unambiguous, specically ANY is in both. + if _, ok := StringToType[s]; !ok { + return s + } + } + return "CLASS" + strconv.Itoa(int(c)) +} + +// String returns the string representation for the name n. +func (n Name) String() string { + return sprintName(string(n)) +} diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go new file mode 100644 index 00000000..ad83a27e --- /dev/null +++ b/vendor/github.com/miekg/dns/dns.go @@ -0,0 +1,134 @@ +package dns + +import "strconv" + +const ( + year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. + defaultTtl = 3600 // Default internal TTL. + + // DefaultMsgSize is the standard default for messages larger than 512 bytes. + DefaultMsgSize = 4096 + // MinMsgSize is the minimal size of a DNS packet. + MinMsgSize = 512 + // MaxMsgSize is the largest possible DNS packet. + MaxMsgSize = 65535 +) + +// Error represents a DNS error. +type Error struct{ err string } + +func (e *Error) Error() string { + if e == nil { + return "dns: " + } + return "dns: " + e.err +} + +// An RR represents a resource record. +type RR interface { + // Header returns the header of an resource record. The header contains + // everything up to the rdata. + Header() *RR_Header + // String returns the text representation of the resource record. + String() string + + // copy returns a copy of the RR + copy() RR + + // len returns the length (in octets) of the compressed or uncompressed RR in wire format. + // + // If compression is nil, the uncompressed size will be returned, otherwise the compressed + // size will be returned and domain names will be added to the map for future compression. + len(off int, compression map[string]struct{}) int + + // pack packs the records RDATA into wire format. The header will + // already have been packed into msg. + pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) + + // unpack unpacks an RR from wire format. + // + // This will only be called on a new and empty RR type with only the header populated. It + // will only be called if the record's RDATA is non-empty. + unpack(msg []byte, off int) (off1 int, err error) + + // parse parses an RR from zone file format. + // + // This will only be called on a new and empty RR type with only the header populated. + parse(c *zlexer, origin string) *ParseError + + // isDuplicate returns whether the two RRs are duplicates. + isDuplicate(r2 RR) bool +} + +// RR_Header is the header all DNS resource records share. +type RR_Header struct { + Name string `dns:"cdomain-name"` + Rrtype uint16 + Class uint16 + Ttl uint32 + Rdlength uint16 // Length of data after header. +} + +// Header returns itself. This is here to make RR_Header implements the RR interface. +func (h *RR_Header) Header() *RR_Header { return h } + +// Just to implement the RR interface. +func (h *RR_Header) copy() RR { return nil } + +func (h *RR_Header) String() string { + var s string + + if h.Rrtype == TypeOPT { + s = ";" + // and maybe other things + } + + s += sprintName(h.Name) + "\t" + s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" + s += Class(h.Class).String() + "\t" + s += Type(h.Rrtype).String() + "\t" + return s +} + +func (h *RR_Header) len(off int, compression map[string]struct{}) int { + l := domainNameLen(h.Name, off, compression, true) + l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2) + return l +} + +func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + // RR_Header has no RDATA to pack. + return off, nil +} + +func (h *RR_Header) unpack(msg []byte, off int) (int, error) { + panic("dns: internal error: unpack should never be called on RR_Header") +} + +func (h *RR_Header) parse(c *zlexer, origin string) *ParseError { + panic("dns: internal error: parse should never be called on RR_Header") +} + +// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. +func (rr *RFC3597) ToRFC3597(r RR) error { + buf := make([]byte, Len(r)*2) + headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false) + if err != nil { + return err + } + buf = buf[:off] + + *rr = RFC3597{Hdr: *r.Header()} + rr.Hdr.Rdlength = uint16(off - headerEnd) + + if noRdata(rr.Hdr) { + return nil + } + + _, err = rr.unpack(buf, headerEnd) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go new file mode 100644 index 00000000..12a693f9 --- /dev/null +++ b/vendor/github.com/miekg/dns/dnssec.go @@ -0,0 +1,794 @@ +package dns + +import ( + "bytes" + "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/elliptic" + _ "crypto/md5" + "crypto/rand" + "crypto/rsa" + _ "crypto/sha1" + _ "crypto/sha256" + _ "crypto/sha512" + "encoding/asn1" + "encoding/binary" + "encoding/hex" + "math/big" + "sort" + "strings" + "time" + + "golang.org/x/crypto/ed25519" +) + +// DNSSEC encryption algorithm codes. +const ( + _ uint8 = iota + RSAMD5 + DH + DSA + _ // Skip 4, RFC 6725, section 2.1 + RSASHA1 + DSANSEC3SHA1 + RSASHA1NSEC3SHA1 + RSASHA256 + _ // Skip 9, RFC 6725, section 2.1 + RSASHA512 + _ // Skip 11, RFC 6725, section 2.1 + ECCGOST + ECDSAP256SHA256 + ECDSAP384SHA384 + ED25519 + ED448 + INDIRECT uint8 = 252 + PRIVATEDNS uint8 = 253 // Private (experimental keys) + PRIVATEOID uint8 = 254 +) + +// AlgorithmToString is a map of algorithm IDs to algorithm names. +var AlgorithmToString = map[uint8]string{ + RSAMD5: "RSAMD5", + DH: "DH", + DSA: "DSA", + RSASHA1: "RSASHA1", + DSANSEC3SHA1: "DSA-NSEC3-SHA1", + RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1", + RSASHA256: "RSASHA256", + RSASHA512: "RSASHA512", + ECCGOST: "ECC-GOST", + ECDSAP256SHA256: "ECDSAP256SHA256", + ECDSAP384SHA384: "ECDSAP384SHA384", + ED25519: "ED25519", + ED448: "ED448", + INDIRECT: "INDIRECT", + PRIVATEDNS: "PRIVATEDNS", + PRIVATEOID: "PRIVATEOID", +} + +// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's. +var AlgorithmToHash = map[uint8]crypto.Hash{ + RSAMD5: crypto.MD5, // Deprecated in RFC 6725 + DSA: crypto.SHA1, + RSASHA1: crypto.SHA1, + RSASHA1NSEC3SHA1: crypto.SHA1, + RSASHA256: crypto.SHA256, + ECDSAP256SHA256: crypto.SHA256, + ECDSAP384SHA384: crypto.SHA384, + RSASHA512: crypto.SHA512, + ED25519: crypto.Hash(0), +} + +// DNSSEC hashing algorithm codes. +const ( + _ uint8 = iota + SHA1 // RFC 4034 + SHA256 // RFC 4509 + GOST94 // RFC 5933 + SHA384 // Experimental + SHA512 // Experimental +) + +// HashToString is a map of hash IDs to names. +var HashToString = map[uint8]string{ + SHA1: "SHA1", + SHA256: "SHA256", + GOST94: "GOST94", + SHA384: "SHA384", + SHA512: "SHA512", +} + +// DNSKEY flag values. +const ( + SEP = 1 + REVOKE = 1 << 7 + ZONE = 1 << 8 +) + +// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing. +type rrsigWireFmt struct { + TypeCovered uint16 + Algorithm uint8 + Labels uint8 + OrigTtl uint32 + Expiration uint32 + Inception uint32 + KeyTag uint16 + SignerName string `dns:"domain-name"` + /* No Signature */ +} + +// Used for converting DNSKEY's rdata to wirefmt. +type dnskeyWireFmt struct { + Flags uint16 + Protocol uint8 + Algorithm uint8 + PublicKey string `dns:"base64"` + /* Nothing is left out */ +} + +func divRoundUp(a, b int) int { + return (a + b - 1) / b +} + +// KeyTag calculates the keytag (or key-id) of the DNSKEY. +func (k *DNSKEY) KeyTag() uint16 { + if k == nil { + return 0 + } + var keytag int + switch k.Algorithm { + case RSAMD5: + // Look at the bottom two bytes of the modules, which the last + // item in the pubkey. + // This algorithm has been deprecated, but keep this key-tag calculation. + modulus, _ := fromBase64([]byte(k.PublicKey)) + if len(modulus) > 1 { + x := binary.BigEndian.Uint16(modulus[len(modulus)-2:]) + keytag = int(x) + } + default: + keywire := new(dnskeyWireFmt) + keywire.Flags = k.Flags + keywire.Protocol = k.Protocol + keywire.Algorithm = k.Algorithm + keywire.PublicKey = k.PublicKey + wire := make([]byte, DefaultMsgSize) + n, err := packKeyWire(keywire, wire) + if err != nil { + return 0 + } + wire = wire[:n] + for i, v := range wire { + if i&1 != 0 { + keytag += int(v) // must be larger than uint32 + } else { + keytag += int(v) << 8 + } + } + keytag += keytag >> 16 & 0xFFFF + keytag &= 0xFFFF + } + return uint16(keytag) +} + +// ToDS converts a DNSKEY record to a DS record. +func (k *DNSKEY) ToDS(h uint8) *DS { + if k == nil { + return nil + } + ds := new(DS) + ds.Hdr.Name = k.Hdr.Name + ds.Hdr.Class = k.Hdr.Class + ds.Hdr.Rrtype = TypeDS + ds.Hdr.Ttl = k.Hdr.Ttl + ds.Algorithm = k.Algorithm + ds.DigestType = h + ds.KeyTag = k.KeyTag() + + keywire := new(dnskeyWireFmt) + keywire.Flags = k.Flags + keywire.Protocol = k.Protocol + keywire.Algorithm = k.Algorithm + keywire.PublicKey = k.PublicKey + wire := make([]byte, DefaultMsgSize) + n, err := packKeyWire(keywire, wire) + if err != nil { + return nil + } + wire = wire[:n] + + owner := make([]byte, 255) + off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false) + if err1 != nil { + return nil + } + owner = owner[:off] + // RFC4034: + // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); + // "|" denotes concatenation + // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. + + var hash crypto.Hash + switch h { + case SHA1: + hash = crypto.SHA1 + case SHA256: + hash = crypto.SHA256 + case SHA384: + hash = crypto.SHA384 + case SHA512: + hash = crypto.SHA512 + default: + return nil + } + + s := hash.New() + s.Write(owner) + s.Write(wire) + ds.Digest = hex.EncodeToString(s.Sum(nil)) + return ds +} + +// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record. +func (k *DNSKEY) ToCDNSKEY() *CDNSKEY { + c := &CDNSKEY{DNSKEY: *k} + c.Hdr = k.Hdr + c.Hdr.Rrtype = TypeCDNSKEY + return c +} + +// ToCDS converts a DS record to a CDS record. +func (d *DS) ToCDS() *CDS { + c := &CDS{DS: *d} + c.Hdr = d.Hdr + c.Hdr.Rrtype = TypeCDS + return c +} + +// Sign signs an RRSet. The signature needs to be filled in with the values: +// Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied +// from the RRset. Sign returns a non-nill error when the signing went OK. +// There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non +// zero, it is used as-is, otherwise the TTL of the RRset is used as the +// OrigTTL. +func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { + if k == nil { + return ErrPrivKey + } + // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set + if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { + return ErrKey + } + + h0 := rrset[0].Header() + rr.Hdr.Rrtype = TypeRRSIG + rr.Hdr.Name = h0.Name + rr.Hdr.Class = h0.Class + if rr.OrigTtl == 0 { // If set don't override + rr.OrigTtl = h0.Ttl + } + rr.TypeCovered = h0.Rrtype + rr.Labels = uint8(CountLabel(h0.Name)) + + if strings.HasPrefix(h0.Name, "*") { + rr.Labels-- // wildcard, remove from label count + } + + sigwire := new(rrsigWireFmt) + sigwire.TypeCovered = rr.TypeCovered + sigwire.Algorithm = rr.Algorithm + sigwire.Labels = rr.Labels + sigwire.OrigTtl = rr.OrigTtl + sigwire.Expiration = rr.Expiration + sigwire.Inception = rr.Inception + sigwire.KeyTag = rr.KeyTag + // For signing, lowercase this name + sigwire.SignerName = strings.ToLower(rr.SignerName) + + // Create the desired binary blob + signdata := make([]byte, DefaultMsgSize) + n, err := packSigWire(sigwire, signdata) + if err != nil { + return err + } + signdata = signdata[:n] + wire, err := rawSignatureData(rrset, rr) + if err != nil { + return err + } + + hash, ok := AlgorithmToHash[rr.Algorithm] + if !ok { + return ErrAlg + } + + switch rr.Algorithm { + case ED25519: + // ed25519 signs the raw message and performs hashing internally. + // All other supported signature schemes operate over the pre-hashed + // message, and thus ed25519 must be handled separately here. + // + // The raw message is passed directly into sign and crypto.Hash(0) is + // used to signal to the crypto.Signer that the data has not been hashed. + signature, err := sign(k, append(signdata, wire...), crypto.Hash(0), rr.Algorithm) + if err != nil { + return err + } + + rr.Signature = toBase64(signature) + case RSAMD5, DSA, DSANSEC3SHA1: + // See RFC 6944. + return ErrAlg + default: + h := hash.New() + h.Write(signdata) + h.Write(wire) + + signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm) + if err != nil { + return err + } + + rr.Signature = toBase64(signature) + } + + return nil +} + +func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) { + signature, err := k.Sign(rand.Reader, hashed, hash) + if err != nil { + return nil, err + } + + switch alg { + case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: + return signature, nil + + case ECDSAP256SHA256, ECDSAP384SHA384: + ecdsaSignature := &struct { + R, S *big.Int + }{} + if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil { + return nil, err + } + + var intlen int + switch alg { + case ECDSAP256SHA256: + intlen = 32 + case ECDSAP384SHA384: + intlen = 48 + } + + signature := intToBytes(ecdsaSignature.R, intlen) + signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...) + return signature, nil + + // There is no defined interface for what a DSA backed crypto.Signer returns + case DSA, DSANSEC3SHA1: + // t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8) + // signature := []byte{byte(t)} + // signature = append(signature, intToBytes(r1, 20)...) + // signature = append(signature, intToBytes(s1, 20)...) + // rr.Signature = signature + + case ED25519: + return signature, nil + } + + return nil, ErrAlg +} + +// Verify validates an RRSet with the signature and key. This is only the +// cryptographic test, the signature validity period must be checked separately. +// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. +func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { + // First the easy checks + if !IsRRset(rrset) { + return ErrRRset + } + if rr.KeyTag != k.KeyTag() { + return ErrKey + } + if rr.Hdr.Class != k.Hdr.Class { + return ErrKey + } + if rr.Algorithm != k.Algorithm { + return ErrKey + } + if !strings.EqualFold(rr.SignerName, k.Hdr.Name) { + return ErrKey + } + if k.Protocol != 3 { + return ErrKey + } + + // IsRRset checked that we have at least one RR and that the RRs in + // the set have consistent type, class, and name. Also check that type and + // class matches the RRSIG record. + if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered { + return ErrRRset + } + + // RFC 4035 5.3.2. Reconstructing the Signed Data + // Copy the sig, except the rrsig data + sigwire := new(rrsigWireFmt) + sigwire.TypeCovered = rr.TypeCovered + sigwire.Algorithm = rr.Algorithm + sigwire.Labels = rr.Labels + sigwire.OrigTtl = rr.OrigTtl + sigwire.Expiration = rr.Expiration + sigwire.Inception = rr.Inception + sigwire.KeyTag = rr.KeyTag + sigwire.SignerName = strings.ToLower(rr.SignerName) + // Create the desired binary blob + signeddata := make([]byte, DefaultMsgSize) + n, err := packSigWire(sigwire, signeddata) + if err != nil { + return err + } + signeddata = signeddata[:n] + wire, err := rawSignatureData(rrset, rr) + if err != nil { + return err + } + + sigbuf := rr.sigBuf() // Get the binary signature data + if rr.Algorithm == PRIVATEDNS { // PRIVATEOID + // TODO(miek) + // remove the domain name and assume its ours? + } + + hash, ok := AlgorithmToHash[rr.Algorithm] + if !ok { + return ErrAlg + } + + switch rr.Algorithm { + case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5: + // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere?? + pubkey := k.publicKeyRSA() // Get the key + if pubkey == nil { + return ErrKey + } + + h := hash.New() + h.Write(signeddata) + h.Write(wire) + return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf) + + case ECDSAP256SHA256, ECDSAP384SHA384: + pubkey := k.publicKeyECDSA() + if pubkey == nil { + return ErrKey + } + + // Split sigbuf into the r and s coordinates + r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2]) + s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:]) + + h := hash.New() + h.Write(signeddata) + h.Write(wire) + if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { + return nil + } + return ErrSig + + case ED25519: + pubkey := k.publicKeyED25519() + if pubkey == nil { + return ErrKey + } + + if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) { + return nil + } + return ErrSig + + default: + return ErrAlg + } +} + +// ValidityPeriod uses RFC1982 serial arithmetic to calculate +// if a signature period is valid. If t is the zero time, the +// current time is taken other t is. Returns true if the signature +// is valid at the given time, otherwise returns false. +func (rr *RRSIG) ValidityPeriod(t time.Time) bool { + var utc int64 + if t.IsZero() { + utc = time.Now().UTC().Unix() + } else { + utc = t.UTC().Unix() + } + modi := (int64(rr.Inception) - utc) / year68 + mode := (int64(rr.Expiration) - utc) / year68 + ti := int64(rr.Inception) + modi*year68 + te := int64(rr.Expiration) + mode*year68 + return ti <= utc && utc <= te +} + +// Return the signatures base64 encodedig sigdata as a byte slice. +func (rr *RRSIG) sigBuf() []byte { + sigbuf, err := fromBase64([]byte(rr.Signature)) + if err != nil { + return nil + } + return sigbuf +} + +// publicKeyRSA returns the RSA public key from a DNSKEY record. +func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey { + keybuf, err := fromBase64([]byte(k.PublicKey)) + if err != nil { + return nil + } + + if len(keybuf) < 1+1+64 { + // Exponent must be at least 1 byte and modulus at least 64 + return nil + } + + // RFC 2537/3110, section 2. RSA Public KEY Resource Records + // Length is in the 0th byte, unless its zero, then it + // it in bytes 1 and 2 and its a 16 bit number + explen := uint16(keybuf[0]) + keyoff := 1 + if explen == 0 { + explen = uint16(keybuf[1])<<8 | uint16(keybuf[2]) + keyoff = 3 + } + + if explen > 4 || explen == 0 || keybuf[keyoff] == 0 { + // Exponent larger than supported by the crypto package, + // empty, or contains prohibited leading zero. + return nil + } + + modoff := keyoff + int(explen) + modlen := len(keybuf) - modoff + if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 { + // Modulus is too small, large, or contains prohibited leading zero. + return nil + } + + pubkey := new(rsa.PublicKey) + + var expo uint64 + // The exponent of length explen is between keyoff and modoff. + for _, v := range keybuf[keyoff:modoff] { + expo <<= 8 + expo |= uint64(v) + } + if expo > 1<<31-1 { + // Larger exponent than supported by the crypto package. + return nil + } + + pubkey.E = int(expo) + pubkey.N = new(big.Int).SetBytes(keybuf[modoff:]) + return pubkey +} + +// publicKeyECDSA returns the Curve public key from the DNSKEY record. +func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey { + keybuf, err := fromBase64([]byte(k.PublicKey)) + if err != nil { + return nil + } + pubkey := new(ecdsa.PublicKey) + switch k.Algorithm { + case ECDSAP256SHA256: + pubkey.Curve = elliptic.P256() + if len(keybuf) != 64 { + // wrongly encoded key + return nil + } + case ECDSAP384SHA384: + pubkey.Curve = elliptic.P384() + if len(keybuf) != 96 { + // Wrongly encoded key + return nil + } + } + pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2]) + pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:]) + return pubkey +} + +func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey { + keybuf, err := fromBase64([]byte(k.PublicKey)) + if err != nil { + return nil + } + if len(keybuf) < 22 { + return nil + } + t, keybuf := int(keybuf[0]), keybuf[1:] + size := 64 + t*8 + q, keybuf := keybuf[:20], keybuf[20:] + if len(keybuf) != 3*size { + return nil + } + p, keybuf := keybuf[:size], keybuf[size:] + g, y := keybuf[:size], keybuf[size:] + pubkey := new(dsa.PublicKey) + pubkey.Parameters.Q = new(big.Int).SetBytes(q) + pubkey.Parameters.P = new(big.Int).SetBytes(p) + pubkey.Parameters.G = new(big.Int).SetBytes(g) + pubkey.Y = new(big.Int).SetBytes(y) + return pubkey +} + +func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey { + keybuf, err := fromBase64([]byte(k.PublicKey)) + if err != nil { + return nil + } + if len(keybuf) != ed25519.PublicKeySize { + return nil + } + return keybuf +} + +type wireSlice [][]byte + +func (p wireSlice) Len() int { return len(p) } +func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p wireSlice) Less(i, j int) bool { + _, ioff, _ := UnpackDomainName(p[i], 0) + _, joff, _ := UnpackDomainName(p[j], 0) + return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0 +} + +// Return the raw signature data. +func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) { + wires := make(wireSlice, len(rrset)) + for i, r := range rrset { + r1 := r.copy() + h := r1.Header() + h.Ttl = s.OrigTtl + labels := SplitDomainName(h.Name) + // 6.2. Canonical RR Form. (4) - wildcards + if len(labels) > int(s.Labels) { + // Wildcard + h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "." + } + // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase + h.Name = strings.ToLower(h.Name) + // 6.2. Canonical RR Form. (3) - domain rdata to lowercase. + // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR, + // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX, + // SRV, DNAME, A6 + // + // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC): + // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record + // that needs conversion to lowercase, and twice at that. Since HINFO + // records contain no domain names, they are not subject to case + // conversion. + switch x := r1.(type) { + case *NS: + x.Ns = strings.ToLower(x.Ns) + case *MD: + x.Md = strings.ToLower(x.Md) + case *MF: + x.Mf = strings.ToLower(x.Mf) + case *CNAME: + x.Target = strings.ToLower(x.Target) + case *SOA: + x.Ns = strings.ToLower(x.Ns) + x.Mbox = strings.ToLower(x.Mbox) + case *MB: + x.Mb = strings.ToLower(x.Mb) + case *MG: + x.Mg = strings.ToLower(x.Mg) + case *MR: + x.Mr = strings.ToLower(x.Mr) + case *PTR: + x.Ptr = strings.ToLower(x.Ptr) + case *MINFO: + x.Rmail = strings.ToLower(x.Rmail) + x.Email = strings.ToLower(x.Email) + case *MX: + x.Mx = strings.ToLower(x.Mx) + case *RP: + x.Mbox = strings.ToLower(x.Mbox) + x.Txt = strings.ToLower(x.Txt) + case *AFSDB: + x.Hostname = strings.ToLower(x.Hostname) + case *RT: + x.Host = strings.ToLower(x.Host) + case *SIG: + x.SignerName = strings.ToLower(x.SignerName) + case *PX: + x.Map822 = strings.ToLower(x.Map822) + x.Mapx400 = strings.ToLower(x.Mapx400) + case *NAPTR: + x.Replacement = strings.ToLower(x.Replacement) + case *KX: + x.Exchanger = strings.ToLower(x.Exchanger) + case *SRV: + x.Target = strings.ToLower(x.Target) + case *DNAME: + x.Target = strings.ToLower(x.Target) + } + // 6.2. Canonical RR Form. (5) - origTTL + wire := make([]byte, Len(r1)+1) // +1 to be safe(r) + off, err1 := PackRR(r1, wire, 0, nil, false) + if err1 != nil { + return nil, err1 + } + wire = wire[:off] + wires[i] = wire + } + sort.Sort(wires) + for i, wire := range wires { + if i > 0 && bytes.Equal(wire, wires[i-1]) { + continue + } + buf = append(buf, wire...) + } + return buf, nil +} + +func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) { + // copied from zmsg.go RRSIG packing + off, err := packUint16(sw.TypeCovered, msg, 0) + if err != nil { + return off, err + } + off, err = packUint8(sw.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(sw.Labels, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(sw.OrigTtl, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(sw.Expiration, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(sw.Inception, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(sw.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = PackDomainName(sw.SignerName, msg, off, nil, false) + if err != nil { + return off, err + } + return off, nil +} + +func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) { + // copied from zmsg.go DNSKEY packing + off, err := packUint16(dw.Flags, msg, 0) + if err != nil { + return off, err + } + off, err = packUint8(dw.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(dw.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(dw.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go new file mode 100644 index 00000000..60737e5b --- /dev/null +++ b/vendor/github.com/miekg/dns/dnssec_keygen.go @@ -0,0 +1,140 @@ +package dns + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "math/big" + + "golang.org/x/crypto/ed25519" +) + +// Generate generates a DNSKEY of the given bit size. +// The public part is put inside the DNSKEY record. +// The Algorithm in the key must be set as this will define +// what kind of DNSKEY will be generated. +// The ECDSA algorithms imply a fixed keysize, in that case +// bits should be set to the size of the algorithm. +func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) { + switch k.Algorithm { + case RSAMD5, DSA, DSANSEC3SHA1: + return nil, ErrAlg + case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1: + if bits < 512 || bits > 4096 { + return nil, ErrKeySize + } + case RSASHA512: + if bits < 1024 || bits > 4096 { + return nil, ErrKeySize + } + case ECDSAP256SHA256: + if bits != 256 { + return nil, ErrKeySize + } + case ECDSAP384SHA384: + if bits != 384 { + return nil, ErrKeySize + } + case ED25519: + if bits != 256 { + return nil, ErrKeySize + } + } + + switch k.Algorithm { + case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1: + priv, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + return nil, err + } + k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N) + return priv, nil + case ECDSAP256SHA256, ECDSAP384SHA384: + var c elliptic.Curve + switch k.Algorithm { + case ECDSAP256SHA256: + c = elliptic.P256() + case ECDSAP384SHA384: + c = elliptic.P384() + } + priv, err := ecdsa.GenerateKey(c, rand.Reader) + if err != nil { + return nil, err + } + k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y) + return priv, nil + case ED25519: + pub, priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + k.setPublicKeyED25519(pub) + return priv, nil + default: + return nil, ErrAlg + } +} + +// Set the public key (the value E and N) +func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool { + if _E == 0 || _N == nil { + return false + } + buf := exponentToBuf(_E) + buf = append(buf, _N.Bytes()...) + k.PublicKey = toBase64(buf) + return true +} + +// Set the public key for Elliptic Curves +func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool { + if _X == nil || _Y == nil { + return false + } + var intlen int + switch k.Algorithm { + case ECDSAP256SHA256: + intlen = 32 + case ECDSAP384SHA384: + intlen = 48 + } + k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen)) + return true +} + +// Set the public key for Ed25519 +func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool { + if _K == nil { + return false + } + k.PublicKey = toBase64(_K) + return true +} + +// Set the public key (the values E and N) for RSA +// RFC 3110: Section 2. RSA Public KEY Resource Records +func exponentToBuf(_E int) []byte { + var buf []byte + i := big.NewInt(int64(_E)).Bytes() + if len(i) < 256 { + buf = make([]byte, 1, 1+len(i)) + buf[0] = uint8(len(i)) + } else { + buf = make([]byte, 3, 3+len(i)) + buf[0] = 0 + buf[1] = uint8(len(i) >> 8) + buf[2] = uint8(len(i)) + } + buf = append(buf, i...) + return buf +} + +// Set the public key for X and Y for Curve. The two +// values are just concatenated. +func curveToBuf(_X, _Y *big.Int, intlen int) []byte { + buf := intToBytes(_X, intlen) + buf = append(buf, intToBytes(_Y, intlen)...) + return buf +} diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go new file mode 100644 index 00000000..0e6f3201 --- /dev/null +++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go @@ -0,0 +1,322 @@ +package dns + +import ( + "bufio" + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "io" + "math/big" + "strconv" + "strings" + + "golang.org/x/crypto/ed25519" +) + +// NewPrivateKey returns a PrivateKey by parsing the string s. +// s should be in the same form of the BIND private key files. +func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { + if s == "" || s[len(s)-1] != '\n' { // We need a closing newline + return k.ReadPrivateKey(strings.NewReader(s+"\n"), "") + } + return k.ReadPrivateKey(strings.NewReader(s), "") +} + +// ReadPrivateKey reads a private key from the io.Reader q. The string file is +// only used in error reporting. +// The public key must be known, because some cryptographic algorithms embed +// the public inside the privatekey. +func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) { + m, err := parseKey(q, file) + if m == nil { + return nil, err + } + if _, ok := m["private-key-format"]; !ok { + return nil, ErrPrivKey + } + if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" { + return nil, ErrPrivKey + } + // TODO(mg): check if the pubkey matches the private key + algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8) + if err != nil { + return nil, ErrPrivKey + } + switch uint8(algo) { + case RSAMD5, DSA, DSANSEC3SHA1: + return nil, ErrAlg + case RSASHA1: + fallthrough + case RSASHA1NSEC3SHA1: + fallthrough + case RSASHA256: + fallthrough + case RSASHA512: + priv, err := readPrivateKeyRSA(m) + if err != nil { + return nil, err + } + pub := k.publicKeyRSA() + if pub == nil { + return nil, ErrKey + } + priv.PublicKey = *pub + return priv, nil + case ECCGOST: + return nil, ErrPrivKey + case ECDSAP256SHA256: + fallthrough + case ECDSAP384SHA384: + priv, err := readPrivateKeyECDSA(m) + if err != nil { + return nil, err + } + pub := k.publicKeyECDSA() + if pub == nil { + return nil, ErrKey + } + priv.PublicKey = *pub + return priv, nil + case ED25519: + return readPrivateKeyED25519(m) + default: + return nil, ErrPrivKey + } +} + +// Read a private key (file) string and create a public key. Return the private key. +func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) { + p := new(rsa.PrivateKey) + p.Primes = []*big.Int{nil, nil} + for k, v := range m { + switch k { + case "modulus", "publicexponent", "privateexponent", "prime1", "prime2": + v1, err := fromBase64([]byte(v)) + if err != nil { + return nil, err + } + switch k { + case "modulus": + p.PublicKey.N = new(big.Int).SetBytes(v1) + case "publicexponent": + i := new(big.Int).SetBytes(v1) + p.PublicKey.E = int(i.Int64()) // int64 should be large enough + case "privateexponent": + p.D = new(big.Int).SetBytes(v1) + case "prime1": + p.Primes[0] = new(big.Int).SetBytes(v1) + case "prime2": + p.Primes[1] = new(big.Int).SetBytes(v1) + } + case "exponent1", "exponent2", "coefficient": + // not used in Go (yet) + case "created", "publish", "activate": + // not used in Go (yet) + } + } + return p, nil +} + +func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) { + p := new(ecdsa.PrivateKey) + p.D = new(big.Int) + // TODO: validate that the required flags are present + for k, v := range m { + switch k { + case "privatekey": + v1, err := fromBase64([]byte(v)) + if err != nil { + return nil, err + } + p.D.SetBytes(v1) + case "created", "publish", "activate": + /* not used in Go (yet) */ + } + } + return p, nil +} + +func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) { + var p ed25519.PrivateKey + // TODO: validate that the required flags are present + for k, v := range m { + switch k { + case "privatekey": + p1, err := fromBase64([]byte(v)) + if err != nil { + return nil, err + } + if len(p1) != ed25519.SeedSize { + return nil, ErrPrivKey + } + p = ed25519.NewKeyFromSeed(p1) + case "created", "publish", "activate": + /* not used in Go (yet) */ + } + } + return p, nil +} + +// parseKey reads a private key from r. It returns a map[string]string, +// with the key-value pairs, or an error when the file is not correct. +func parseKey(r io.Reader, file string) (map[string]string, error) { + m := make(map[string]string) + var k string + + c := newKLexer(r) + + for l, ok := c.Next(); ok; l, ok = c.Next() { + // It should alternate + switch l.value { + case zKey: + k = l.token + case zValue: + if k == "" { + return nil, &ParseError{file, "no private key seen", l} + } + + m[strings.ToLower(k)] = l.token + k = "" + } + } + + // Surface any read errors from r. + if err := c.Err(); err != nil { + return nil, &ParseError{file: file, err: err.Error()} + } + + return m, nil +} + +type klexer struct { + br io.ByteReader + + readErr error + + line int + column int + + key bool + + eol bool // end-of-line +} + +func newKLexer(r io.Reader) *klexer { + br, ok := r.(io.ByteReader) + if !ok { + br = bufio.NewReaderSize(r, 1024) + } + + return &klexer{ + br: br, + + line: 1, + + key: true, + } +} + +func (kl *klexer) Err() error { + if kl.readErr == io.EOF { + return nil + } + + return kl.readErr +} + +// readByte returns the next byte from the input +func (kl *klexer) readByte() (byte, bool) { + if kl.readErr != nil { + return 0, false + } + + c, err := kl.br.ReadByte() + if err != nil { + kl.readErr = err + return 0, false + } + + // delay the newline handling until the next token is delivered, + // fixes off-by-one errors when reporting a parse error. + if kl.eol { + kl.line++ + kl.column = 0 + kl.eol = false + } + + if c == '\n' { + kl.eol = true + } else { + kl.column++ + } + + return c, true +} + +func (kl *klexer) Next() (lex, bool) { + var ( + l lex + + str strings.Builder + + commt bool + ) + + for x, ok := kl.readByte(); ok; x, ok = kl.readByte() { + l.line, l.column = kl.line, kl.column + + switch x { + case ':': + if commt || !kl.key { + break + } + + kl.key = false + + // Next token is a space, eat it + kl.readByte() + + l.value = zKey + l.token = str.String() + return l, true + case ';': + commt = true + case '\n': + if commt { + // Reset a comment + commt = false + } + + if kl.key && str.Len() == 0 { + // ignore empty lines + break + } + + kl.key = true + + l.value = zValue + l.token = str.String() + return l, true + default: + if commt { + break + } + + str.WriteByte(x) + } + } + + if kl.readErr != nil && kl.readErr != io.EOF { + // Don't return any tokens after a read error occurs. + return lex{value: zEOF}, false + } + + if str.Len() > 0 { + // Send remainder + l.value = zValue + l.token = str.String() + return l, true + } + + return lex{value: zEOF}, false +} diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go new file mode 100644 index 00000000..4493c9d5 --- /dev/null +++ b/vendor/github.com/miekg/dns/dnssec_privkey.go @@ -0,0 +1,94 @@ +package dns + +import ( + "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/rsa" + "math/big" + "strconv" + + "golang.org/x/crypto/ed25519" +) + +const format = "Private-key-format: v1.3\n" + +var bigIntOne = big.NewInt(1) + +// PrivateKeyString converts a PrivateKey to a string. This string has the same +// format as the private-key-file of BIND9 (Private-key-format: v1.3). +// It needs some info from the key (the algorithm), so its a method of the DNSKEY +// It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey +func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string { + algorithm := strconv.Itoa(int(r.Algorithm)) + algorithm += " (" + AlgorithmToString[r.Algorithm] + ")" + + switch p := p.(type) { + case *rsa.PrivateKey: + modulus := toBase64(p.PublicKey.N.Bytes()) + e := big.NewInt(int64(p.PublicKey.E)) + publicExponent := toBase64(e.Bytes()) + privateExponent := toBase64(p.D.Bytes()) + prime1 := toBase64(p.Primes[0].Bytes()) + prime2 := toBase64(p.Primes[1].Bytes()) + // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm + // and from: http://code.google.com/p/go/issues/detail?id=987 + p1 := new(big.Int).Sub(p.Primes[0], bigIntOne) + q1 := new(big.Int).Sub(p.Primes[1], bigIntOne) + exp1 := new(big.Int).Mod(p.D, p1) + exp2 := new(big.Int).Mod(p.D, q1) + coeff := new(big.Int).ModInverse(p.Primes[1], p.Primes[0]) + + exponent1 := toBase64(exp1.Bytes()) + exponent2 := toBase64(exp2.Bytes()) + coefficient := toBase64(coeff.Bytes()) + + return format + + "Algorithm: " + algorithm + "\n" + + "Modulus: " + modulus + "\n" + + "PublicExponent: " + publicExponent + "\n" + + "PrivateExponent: " + privateExponent + "\n" + + "Prime1: " + prime1 + "\n" + + "Prime2: " + prime2 + "\n" + + "Exponent1: " + exponent1 + "\n" + + "Exponent2: " + exponent2 + "\n" + + "Coefficient: " + coefficient + "\n" + + case *ecdsa.PrivateKey: + var intlen int + switch r.Algorithm { + case ECDSAP256SHA256: + intlen = 32 + case ECDSAP384SHA384: + intlen = 48 + } + private := toBase64(intToBytes(p.D, intlen)) + return format + + "Algorithm: " + algorithm + "\n" + + "PrivateKey: " + private + "\n" + + case *dsa.PrivateKey: + T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8) + prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8)) + subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20)) + base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8)) + priv := toBase64(intToBytes(p.X, 20)) + pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8)) + return format + + "Algorithm: " + algorithm + "\n" + + "Prime(p): " + prime + "\n" + + "Subprime(q): " + subprime + "\n" + + "Base(g): " + base + "\n" + + "Private_value(x): " + priv + "\n" + + "Public_value(y): " + pub + "\n" + + case ed25519.PrivateKey: + private := toBase64(p.Seed()) + return format + + "Algorithm: " + algorithm + "\n" + + "PrivateKey: " + private + "\n" + + default: + return "" + } +} diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go new file mode 100644 index 00000000..d3d7cec9 --- /dev/null +++ b/vendor/github.com/miekg/dns/doc.go @@ -0,0 +1,269 @@ +/* +Package dns implements a full featured interface to the Domain Name System. +Both server- and client-side programming is supported. The package allows +complete control over what is sent out to the DNS. The API follows the +less-is-more principle, by presenting a small, clean interface. + +It supports (asynchronous) querying/replying, incoming/outgoing zone transfers, +TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing. + +Note that domain names MUST be fully qualified before sending them, unqualified +names in a message will result in a packing failure. + +Resource records are native types. They are not stored in wire format. Basic +usage pattern for creating a new resource record: + + r := new(dns.MX) + r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600} + r.Preference = 10 + r.Mx = "mx.miek.nl." + +Or directly from a string: + + mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.") + +Or when the default origin (.) and TTL (3600) and class (IN) suit you: + + mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl") + +Or even: + + mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek") + +In the DNS messages are exchanged, these messages contain resource records +(sets). Use pattern for creating a message: + + m := new(dns.Msg) + m.SetQuestion("miek.nl.", dns.TypeMX) + +Or when not certain if the domain name is fully qualified: + + m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX) + +The message m is now a message with the question section set to ask the MX +records for the miek.nl. zone. + +The following is slightly more verbose, but more flexible: + + m1 := new(dns.Msg) + m1.Id = dns.Id() + m1.RecursionDesired = true + m1.Question = make([]dns.Question, 1) + m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET} + +After creating a message it can be sent. Basic use pattern for synchronous +querying the DNS at a server configured on 127.0.0.1 and port 53: + + c := new(dns.Client) + in, rtt, err := c.Exchange(m1, "127.0.0.1:53") + +Suppressing multiple outstanding queries (with the same question, type and +class) is as easy as setting: + + c.SingleInflight = true + +More advanced options are available using a net.Dialer and the corresponding API. +For example it is possible to set a timeout, or to specify a source IP address +and port to use for the connection: + + c := new(dns.Client) + laddr := net.UDPAddr{ + IP: net.ParseIP("[::1]"), + Port: 12345, + Zone: "", + } + c.Dialer := &net.Dialer{ + Timeout: 200 * time.Millisecond, + LocalAddr: &laddr, + } + in, rtt, err := c.Exchange(m1, "8.8.8.8:53") + +If these "advanced" features are not needed, a simple UDP query can be sent, +with: + + in, err := dns.Exchange(m1, "127.0.0.1:53") + +When this functions returns you will get dns message. A dns message consists +out of four sections. +The question section: in.Question, the answer section: in.Answer, +the authority section: in.Ns and the additional section: in.Extra. + +Each of these sections (except the Question section) contain a []RR. Basic +use pattern for accessing the rdata of a TXT RR as the first RR in +the Answer section: + + if t, ok := in.Answer[0].(*dns.TXT); ok { + // do something with t.Txt + } + +Domain Name and TXT Character String Representations + +Both domain names and TXT character strings are converted to presentation form +both when unpacked and when converted to strings. + +For TXT character strings, tabs, carriage returns and line feeds will be +converted to \t, \r and \n respectively. Back slashes and quotations marks will +be escaped. Bytes below 32 and above 127 will be converted to \DDD form. + +For domain names, in addition to the above rules brackets, periods, spaces, +semicolons and the at symbol are escaped. + +DNSSEC + +DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses +public key cryptography to sign resource records. The public keys are stored in +DNSKEY records and the signatures in RRSIG records. + +Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) +bit to a request. + + m := new(dns.Msg) + m.SetEdns0(4096, true) + +Signature generation, signature verification and key generation are all supported. + +DYNAMIC UPDATES + +Dynamic updates reuses the DNS message format, but renames three of the +sections. Question is Zone, Answer is Prerequisite, Authority is Update, only +the Additional is not renamed. See RFC 2136 for the gory details. + +You can set a rather complex set of rules for the existence of absence of +certain resource records or names in a zone to specify if resource records +should be added or removed. The table from RFC 2136 supplemented with the Go +DNS function shows which functions exist to specify the prerequisites. + + 3.2.4 - Table Of Metavalues Used In Prerequisite Section + + CLASS TYPE RDATA Meaning Function + -------------------------------------------------------------- + ANY ANY empty Name is in use dns.NameUsed + ANY rrset empty RRset exists (value indep) dns.RRsetUsed + NONE ANY empty Name is not in use dns.NameNotUsed + NONE rrset empty RRset does not exist dns.RRsetNotUsed + zone rrset rr RRset exists (value dep) dns.Used + +The prerequisite section can also be left empty. If you have decided on the +prerequisites you can tell what RRs should be added or deleted. The next table +shows the options you have and what functions to call. + + 3.4.2.6 - Table Of Metavalues Used In Update Section + + CLASS TYPE RDATA Meaning Function + --------------------------------------------------------------- + ANY ANY empty Delete all RRsets from name dns.RemoveName + ANY rrset empty Delete an RRset dns.RemoveRRset + NONE rrset rr Delete an RR from RRset dns.Remove + zone rrset rr Add to an RRset dns.Insert + +TRANSACTION SIGNATURE + +An TSIG or transaction signature adds a HMAC TSIG record to each message sent. +The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512. + +Basic use pattern when querying with a TSIG name "axfr." (note that these key names +must be fully qualified - as they are domain names) and the base64 secret +"so6ZGir4GPAqINNh9U5c3A==": + +If an incoming message contains a TSIG record it MUST be the last record in +the additional section (RFC2845 3.2). This means that you should make the +call to SetTsig last, right before executing the query. If you make any +changes to the RRset after calling SetTsig() the signature will be incorrect. + + c := new(dns.Client) + c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} + m := new(dns.Msg) + m.SetQuestion("miek.nl.", dns.TypeMX) + m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) + ... + // When sending the TSIG RR is calculated and filled in before sending + +When requesting an zone transfer (almost all TSIG usage is when requesting zone +transfers), with TSIG, this is the basic use pattern. In this example we +request an AXFR for miek.nl. with TSIG key named "axfr." and secret +"so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54: + + t := new(dns.Transfer) + m := new(dns.Msg) + t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} + m.SetAxfr("miek.nl.") + m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) + c, err := t.In(m, "176.58.119.54:53") + for r := range c { ... } + +You can now read the records from the transfer as they come in. Each envelope +is checked with TSIG. If something is not correct an error is returned. + +Basic use pattern validating and replying to a message that has TSIG set. + + server := &dns.Server{Addr: ":53", Net: "udp"} + server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} + go server.ListenAndServe() + dns.HandleFunc(".", handleRequest) + + func handleRequest(w dns.ResponseWriter, r *dns.Msg) { + m := new(dns.Msg) + m.SetReply(r) + if r.IsTsig() != nil { + if w.TsigStatus() == nil { + // *Msg r has an TSIG record and it was validated + m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) + } else { + // *Msg r has an TSIG records and it was not valided + } + } + w.WriteMsg(m) + } + +PRIVATE RRS + +RFC 6895 sets aside a range of type codes for private use. This range is 65,280 +- 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these +can be used, before requesting an official type code from IANA. + +See https://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more +information. + +EDNS0 + +EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by +RFC 6891. It defines an new RR type, the OPT RR, which is then completely +abused. + +Basic use pattern for creating an (empty) OPT RR: + + o := new(dns.OPT) + o.Hdr.Name = "." // MUST be the root zone, per definition. + o.Hdr.Rrtype = dns.TypeOPT + +The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces. +Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and +EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note that these options +may be combined in an OPT RR. Basic use pattern for a server to check if (and +which) options are set: + + // o is a dns.OPT + for _, s := range o.Option { + switch e := s.(type) { + case *dns.EDNS0_NSID: + // do stuff with e.Nsid + case *dns.EDNS0_SUBNET: + // access e.Family, e.Address, etc. + } + } + +SIG(0) + +From RFC 2931: + + SIG(0) provides protection for DNS transactions and requests .... + ... protection for glue records, DNS requests, protection for message headers + on requests and responses, and protection of the overall integrity of a response. + +It works like TSIG, except that SIG(0) uses public key cryptography, instead of +the shared secret approach in TSIG. Supported algorithms: DSA, ECDSAP256SHA256, +ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512. + +Signing subsequent messages in multi-message sessions is not implemented. +*/ +package dns diff --git a/vendor/github.com/miekg/dns/duplicate.go b/vendor/github.com/miekg/dns/duplicate.go new file mode 100644 index 00000000..00cda0aa --- /dev/null +++ b/vendor/github.com/miekg/dns/duplicate.go @@ -0,0 +1,38 @@ +package dns + +//go:generate go run duplicate_generate.go + +// IsDuplicate checks of r1 and r2 are duplicates of each other, excluding the TTL. +// So this means the header data is equal *and* the RDATA is the same. Return true +// is so, otherwise false. +// It's is a protocol violation to have identical RRs in a message. +func IsDuplicate(r1, r2 RR) bool { + // Check whether the record header is identical. + if !r1.Header().isDuplicate(r2.Header()) { + return false + } + + // Check whether the RDATA is identical. + return r1.isDuplicate(r2) +} + +func (r1 *RR_Header) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RR_Header) + if !ok { + return false + } + if r1.Class != r2.Class { + return false + } + if r1.Rrtype != r2.Rrtype { + return false + } + if !isDuplicateName(r1.Name, r2.Name) { + return false + } + // ignore TTL + return true +} + +// isDuplicateName checks if the domain names s1 and s2 are equal. +func isDuplicateName(s1, s2 string) bool { return equal(s1, s2) } diff --git a/vendor/github.com/miekg/dns/duplicate_generate.go b/vendor/github.com/miekg/dns/duplicate_generate.go new file mode 100644 index 00000000..9b7a71b1 --- /dev/null +++ b/vendor/github.com/miekg/dns/duplicate_generate.go @@ -0,0 +1,144 @@ +//+build ignore + +// types_generate.go is meant to run with go generate. It will use +// go/{importer,types} to track down all the RR struct types. Then for each type +// it will generate conversion tables (TypeToRR and TypeToString) and banal +// methods (len, Header, copy) based on the struct tags. The generated source is +// written to ztypes.go, and is meant to be checked into git. +package main + +import ( + "bytes" + "fmt" + "go/format" + "go/importer" + "go/types" + "log" + "os" +) + +var packageHdr = ` +// Code generated by "go run duplicate_generate.go"; DO NOT EDIT. + +package dns + +` + +func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { + st, ok := t.Underlying().(*types.Struct) + if !ok { + return nil, false + } + if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { + return st, false + } + if st.Field(0).Anonymous() { + st, _ := getTypeStruct(st.Field(0).Type(), scope) + return st, true + } + return nil, false +} + +func main() { + // Import and type-check the package + pkg, err := importer.Default().Import("github.com/miekg/dns") + fatalIfErr(err) + scope := pkg.Scope() + + // Collect actual types (*X) + var namedTypes []string + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + + if st, _ := getTypeStruct(o.Type(), scope); st == nil { + continue + } + + if name == "PrivateRR" || name == "OPT" { + continue + } + + namedTypes = append(namedTypes, o.Name()) + } + + b := &bytes.Buffer{} + b.WriteString(packageHdr) + + // Generate the duplicate check for each type. + fmt.Fprint(b, "// isDuplicate() functions\n\n") + for _, name := range namedTypes { + + o := scope.Lookup(name) + st, isEmbedded := getTypeStruct(o.Type(), scope) + if isEmbedded { + continue + } + fmt.Fprintf(b, "func (r1 *%s) isDuplicate(_r2 RR) bool {\n", name) + fmt.Fprintf(b, "r2, ok := _r2.(*%s)\n", name) + fmt.Fprint(b, "if !ok { return false }\n") + fmt.Fprint(b, "_ = r2\n") + for i := 1; i < st.NumFields(); i++ { + field := st.Field(i).Name() + o2 := func(s string) { fmt.Fprintf(b, s+"\n", field, field) } + o3 := func(s string) { fmt.Fprintf(b, s+"\n", field, field, field) } + + // For some reason, a and aaaa don't pop up as *types.Slice here (mostly like because the are + // *indirectly* defined as a slice in the net package). + if _, ok := st.Field(i).Type().(*types.Slice); ok { + o2("if len(r1.%s) != len(r2.%s) {\nreturn false\n}") + + if st.Tag(i) == `dns:"cdomain-name"` || st.Tag(i) == `dns:"domain-name"` { + o3(`for i := 0; i < len(r1.%s); i++ { + if !isDuplicateName(r1.%s[i], r2.%s[i]) { + return false + } + }`) + + continue + } + + o3(`for i := 0; i < len(r1.%s); i++ { + if r1.%s[i] != r2.%s[i] { + return false + } + }`) + + continue + } + + switch st.Tag(i) { + case `dns:"-"`: + // ignored + case `dns:"a"`, `dns:"aaaa"`: + o2("if !r1.%s.Equal(r2.%s) {\nreturn false\n}") + case `dns:"cdomain-name"`, `dns:"domain-name"`: + o2("if !isDuplicateName(r1.%s, r2.%s) {\nreturn false\n}") + default: + o2("if r1.%s != r2.%s {\nreturn false\n}") + } + } + fmt.Fprintf(b, "return true\n}\n\n") + } + + // gofmt + res, err := format.Source(b.Bytes()) + if err != nil { + b.WriteTo(os.Stderr) + log.Fatal(err) + } + + // write result + f, err := os.Create("zduplicate.go") + fatalIfErr(err) + defer f.Close() + f.Write(res) +} + +func fatalIfErr(err error) { + if err != nil { + log.Fatal(err) + } +} diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go new file mode 100644 index 00000000..8cdbfb0b --- /dev/null +++ b/vendor/github.com/miekg/dns/edns.go @@ -0,0 +1,659 @@ +package dns + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "net" + "strconv" +) + +// EDNS0 Option codes. +const ( + EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 + EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt + EDNS0NSID = 0x3 // nsid (See RFC 5001) + EDNS0DAU = 0x5 // DNSSEC Algorithm Understood + EDNS0DHU = 0x6 // DS Hash Understood + EDNS0N3U = 0x7 // NSEC3 Hash Understood + EDNS0SUBNET = 0x8 // client-subnet (See RFC 7871) + EDNS0EXPIRE = 0x9 // EDNS0 expire + EDNS0COOKIE = 0xa // EDNS0 Cookie + EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (See RFC 7828) + EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830) + EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (See RFC 6891) + EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (See RFC 6891) + _DO = 1 << 15 // DNSSEC OK +) + +// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. +// See RFC 6891. +type OPT struct { + Hdr RR_Header + Option []EDNS0 `dns:"opt"` +} + +func (rr *OPT) String() string { + s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; " + if rr.Do() { + s += "flags: do; " + } else { + s += "flags: ; " + } + s += "udp: " + strconv.Itoa(int(rr.UDPSize())) + + for _, o := range rr.Option { + switch o.(type) { + case *EDNS0_NSID: + s += "\n; NSID: " + o.String() + h, e := o.pack() + var r string + if e == nil { + for _, c := range h { + r += "(" + string(c) + ")" + } + s += " " + r + } + case *EDNS0_SUBNET: + s += "\n; SUBNET: " + o.String() + case *EDNS0_COOKIE: + s += "\n; COOKIE: " + o.String() + case *EDNS0_UL: + s += "\n; UPDATE LEASE: " + o.String() + case *EDNS0_LLQ: + s += "\n; LONG LIVED QUERIES: " + o.String() + case *EDNS0_DAU: + s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String() + case *EDNS0_DHU: + s += "\n; DS HASH UNDERSTOOD: " + o.String() + case *EDNS0_N3U: + s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String() + case *EDNS0_LOCAL: + s += "\n; LOCAL OPT: " + o.String() + case *EDNS0_PADDING: + s += "\n; PADDING: " + o.String() + } + } + return s +} + +func (rr *OPT) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + for _, o := range rr.Option { + l += 4 // Account for 2-byte option code and 2-byte option length. + lo, _ := o.pack() + l += len(lo) + } + return l +} + +func (rr *OPT) parse(c *zlexer, origin string) *ParseError { + panic("dns: internal error: parse should never be called on OPT") +} + +func (r1 *OPT) isDuplicate(r2 RR) bool { return false } + +// return the old value -> delete SetVersion? + +// Version returns the EDNS version used. Only zero is defined. +func (rr *OPT) Version() uint8 { + return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16) +} + +// SetVersion sets the version of EDNS. This is usually zero. +func (rr *OPT) SetVersion(v uint8) { + rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16 +} + +// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL). +func (rr *OPT) ExtendedRcode() int { + return int(rr.Hdr.Ttl&0xFF000000>>24) << 4 +} + +// SetExtendedRcode sets the EDNS extended RCODE field. +// +// If the RCODE is not an extended RCODE, will reset the extended RCODE field to 0. +func (rr *OPT) SetExtendedRcode(v uint16) { + rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v>>4)<<24 +} + +// UDPSize returns the UDP buffer size. +func (rr *OPT) UDPSize() uint16 { + return rr.Hdr.Class +} + +// SetUDPSize sets the UDP buffer size. +func (rr *OPT) SetUDPSize(size uint16) { + rr.Hdr.Class = size +} + +// Do returns the value of the DO (DNSSEC OK) bit. +func (rr *OPT) Do() bool { + return rr.Hdr.Ttl&_DO == _DO +} + +// SetDo sets the DO (DNSSEC OK) bit. +// If we pass an argument, set the DO bit to that value. +// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored. +func (rr *OPT) SetDo(do ...bool) { + if len(do) == 1 { + if do[0] { + rr.Hdr.Ttl |= _DO + } else { + rr.Hdr.Ttl &^= _DO + } + } else { + rr.Hdr.Ttl |= _DO + } +} + +// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it. +type EDNS0 interface { + // Option returns the option code for the option. + Option() uint16 + // pack returns the bytes of the option data. + pack() ([]byte, error) + // unpack sets the data as found in the buffer. Is also sets + // the length of the slice as the length of the option data. + unpack([]byte) error + // String returns the string representation of the option. + String() string + // copy returns a deep-copy of the option. + copy() EDNS0 +} + +// EDNS0_NSID option is used to retrieve a nameserver +// identifier. When sending a request Nsid must be set to the empty string +// The identifier is an opaque string encoded as hex. +// Basic use pattern for creating an nsid option: +// +// o := new(dns.OPT) +// o.Hdr.Name = "." +// o.Hdr.Rrtype = dns.TypeOPT +// e := new(dns.EDNS0_NSID) +// e.Code = dns.EDNS0NSID +// e.Nsid = "AA" +// o.Option = append(o.Option, e) +type EDNS0_NSID struct { + Code uint16 // Always EDNS0NSID + Nsid string // This string needs to be hex encoded +} + +func (e *EDNS0_NSID) pack() ([]byte, error) { + h, err := hex.DecodeString(e.Nsid) + if err != nil { + return nil, err + } + return h, nil +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code. +func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil } +func (e *EDNS0_NSID) String() string { return e.Nsid } +func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} } + +// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver +// an idea of where the client lives. See RFC 7871. It can then give back a different +// answer depending on the location or network topology. +// Basic use pattern for creating an subnet option: +// +// o := new(dns.OPT) +// o.Hdr.Name = "." +// o.Hdr.Rrtype = dns.TypeOPT +// e := new(dns.EDNS0_SUBNET) +// e.Code = dns.EDNS0SUBNET +// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 +// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6 +// e.SourceScope = 0 +// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 +// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 +// o.Option = append(o.Option, e) +// +// This code will parse all the available bits when unpacking (up to optlen). +// When packing it will apply SourceNetmask. If you need more advanced logic, +// patches welcome and good luck. +type EDNS0_SUBNET struct { + Code uint16 // Always EDNS0SUBNET + Family uint16 // 1 for IP, 2 for IP6 + SourceNetmask uint8 + SourceScope uint8 + Address net.IP +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET } + +func (e *EDNS0_SUBNET) pack() ([]byte, error) { + b := make([]byte, 4) + binary.BigEndian.PutUint16(b[0:], e.Family) + b[2] = e.SourceNetmask + b[3] = e.SourceScope + switch e.Family { + case 0: + // "dig" sets AddressFamily to 0 if SourceNetmask is also 0 + // We might don't need to complain either + if e.SourceNetmask != 0 { + return nil, errors.New("dns: bad address family") + } + case 1: + if e.SourceNetmask > net.IPv4len*8 { + return nil, errors.New("dns: bad netmask") + } + if len(e.Address.To4()) != net.IPv4len { + return nil, errors.New("dns: bad address") + } + ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8)) + needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up + b = append(b, ip[:needLength]...) + case 2: + if e.SourceNetmask > net.IPv6len*8 { + return nil, errors.New("dns: bad netmask") + } + if len(e.Address) != net.IPv6len { + return nil, errors.New("dns: bad address") + } + ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8)) + needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up + b = append(b, ip[:needLength]...) + default: + return nil, errors.New("dns: bad address family") + } + return b, nil +} + +func (e *EDNS0_SUBNET) unpack(b []byte) error { + if len(b) < 4 { + return ErrBuf + } + e.Family = binary.BigEndian.Uint16(b) + e.SourceNetmask = b[2] + e.SourceScope = b[3] + switch e.Family { + case 0: + // "dig" sets AddressFamily to 0 if SourceNetmask is also 0 + // It's okay to accept such a packet + if e.SourceNetmask != 0 { + return errors.New("dns: bad address family") + } + e.Address = net.IPv4(0, 0, 0, 0) + case 1: + if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 { + return errors.New("dns: bad netmask") + } + addr := make(net.IP, net.IPv4len) + copy(addr, b[4:]) + e.Address = addr.To16() + case 2: + if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 { + return errors.New("dns: bad netmask") + } + addr := make(net.IP, net.IPv6len) + copy(addr, b[4:]) + e.Address = addr + default: + return errors.New("dns: bad address family") + } + return nil +} + +func (e *EDNS0_SUBNET) String() (s string) { + if e.Address == nil { + s = "" + } else if e.Address.To4() != nil { + s = e.Address.String() + } else { + s = "[" + e.Address.String() + "]" + } + s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope)) + return +} + +func (e *EDNS0_SUBNET) copy() EDNS0 { + return &EDNS0_SUBNET{ + e.Code, + e.Family, + e.SourceNetmask, + e.SourceScope, + e.Address, + } +} + +// The EDNS0_COOKIE option is used to add a DNS Cookie to a message. +// +// o := new(dns.OPT) +// o.Hdr.Name = "." +// o.Hdr.Rrtype = dns.TypeOPT +// e := new(dns.EDNS0_COOKIE) +// e.Code = dns.EDNS0COOKIE +// e.Cookie = "24a5ac.." +// o.Option = append(o.Option, e) +// +// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is +// always 8 bytes. It may then optionally be followed by the server cookie. The server +// cookie is of variable length, 8 to a maximum of 32 bytes. In other words: +// +// cCookie := o.Cookie[:16] +// sCookie := o.Cookie[16:] +// +// There is no guarantee that the Cookie string has a specific length. +type EDNS0_COOKIE struct { + Code uint16 // Always EDNS0COOKIE + Cookie string // Hex-encoded cookie data +} + +func (e *EDNS0_COOKIE) pack() ([]byte, error) { + h, err := hex.DecodeString(e.Cookie) + if err != nil { + return nil, err + } + return h, nil +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE } +func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil } +func (e *EDNS0_COOKIE) String() string { return e.Cookie } +func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} } + +// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set +// an expiration on an update RR. This is helpful for clients that cannot clean +// up after themselves. This is a draft RFC and more information can be found at +// http://files.dns-sd.org/draft-sekar-dns-ul.txt +// +// o := new(dns.OPT) +// o.Hdr.Name = "." +// o.Hdr.Rrtype = dns.TypeOPT +// e := new(dns.EDNS0_UL) +// e.Code = dns.EDNS0UL +// e.Lease = 120 // in seconds +// o.Option = append(o.Option, e) +type EDNS0_UL struct { + Code uint16 // Always EDNS0UL + Lease uint32 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_UL) Option() uint16 { return EDNS0UL } +func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) } +func (e *EDNS0_UL) copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease} } + +// Copied: http://golang.org/src/pkg/net/dnsmsg.go +func (e *EDNS0_UL) pack() ([]byte, error) { + b := make([]byte, 4) + binary.BigEndian.PutUint32(b, e.Lease) + return b, nil +} + +func (e *EDNS0_UL) unpack(b []byte) error { + if len(b) < 4 { + return ErrBuf + } + e.Lease = binary.BigEndian.Uint32(b) + return nil +} + +// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 +// Implemented for completeness, as the EDNS0 type code is assigned. +type EDNS0_LLQ struct { + Code uint16 // Always EDNS0LLQ + Version uint16 + Opcode uint16 + Error uint16 + Id uint64 + LeaseLife uint32 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ } + +func (e *EDNS0_LLQ) pack() ([]byte, error) { + b := make([]byte, 18) + binary.BigEndian.PutUint16(b[0:], e.Version) + binary.BigEndian.PutUint16(b[2:], e.Opcode) + binary.BigEndian.PutUint16(b[4:], e.Error) + binary.BigEndian.PutUint64(b[6:], e.Id) + binary.BigEndian.PutUint32(b[14:], e.LeaseLife) + return b, nil +} + +func (e *EDNS0_LLQ) unpack(b []byte) error { + if len(b) < 18 { + return ErrBuf + } + e.Version = binary.BigEndian.Uint16(b[0:]) + e.Opcode = binary.BigEndian.Uint16(b[2:]) + e.Error = binary.BigEndian.Uint16(b[4:]) + e.Id = binary.BigEndian.Uint64(b[6:]) + e.LeaseLife = binary.BigEndian.Uint32(b[14:]) + return nil +} + +func (e *EDNS0_LLQ) String() string { + s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) + + " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) + + " " + strconv.FormatUint(uint64(e.LeaseLife), 10) + return s +} +func (e *EDNS0_LLQ) copy() EDNS0 { + return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife} +} + +// EDNS0_DUA implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975. +type EDNS0_DAU struct { + Code uint16 // Always EDNS0DAU + AlgCode []uint8 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU } +func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil } +func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil } + +func (e *EDNS0_DAU) String() string { + s := "" + for _, alg := range e.AlgCode { + if a, ok := AlgorithmToString[alg]; ok { + s += " " + a + } else { + s += " " + strconv.Itoa(int(alg)) + } + } + return s +} +func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} } + +// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975. +type EDNS0_DHU struct { + Code uint16 // Always EDNS0DHU + AlgCode []uint8 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU } +func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil } +func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil } + +func (e *EDNS0_DHU) String() string { + s := "" + for _, alg := range e.AlgCode { + if a, ok := HashToString[alg]; ok { + s += " " + a + } else { + s += " " + strconv.Itoa(int(alg)) + } + } + return s +} +func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} } + +// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975. +type EDNS0_N3U struct { + Code uint16 // Always EDNS0N3U + AlgCode []uint8 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U } +func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil } +func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil } + +func (e *EDNS0_N3U) String() string { + // Re-use the hash map + s := "" + for _, alg := range e.AlgCode { + if a, ok := HashToString[alg]; ok { + s += " " + a + } else { + s += " " + strconv.Itoa(int(alg)) + } + } + return s +} +func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} } + +// EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314. +type EDNS0_EXPIRE struct { + Code uint16 // Always EDNS0EXPIRE + Expire uint32 +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE } +func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) } +func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} } + +func (e *EDNS0_EXPIRE) pack() ([]byte, error) { + b := make([]byte, 4) + binary.BigEndian.PutUint32(b, e.Expire) + return b, nil +} + +func (e *EDNS0_EXPIRE) unpack(b []byte) error { + if len(b) < 4 { + return ErrBuf + } + e.Expire = binary.BigEndian.Uint32(b) + return nil +} + +// The EDNS0_LOCAL option is used for local/experimental purposes. The option +// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND] +// (RFC6891), although any unassigned code can actually be used. The content of +// the option is made available in Data, unaltered. +// Basic use pattern for creating a local option: +// +// o := new(dns.OPT) +// o.Hdr.Name = "." +// o.Hdr.Rrtype = dns.TypeOPT +// e := new(dns.EDNS0_LOCAL) +// e.Code = dns.EDNS0LOCALSTART +// e.Data = []byte{72, 82, 74} +// o.Option = append(o.Option, e) +type EDNS0_LOCAL struct { + Code uint16 + Data []byte +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_LOCAL) Option() uint16 { return e.Code } +func (e *EDNS0_LOCAL) String() string { + return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data) +} +func (e *EDNS0_LOCAL) copy() EDNS0 { + b := make([]byte, len(e.Data)) + copy(b, e.Data) + return &EDNS0_LOCAL{e.Code, b} +} + +func (e *EDNS0_LOCAL) pack() ([]byte, error) { + b := make([]byte, len(e.Data)) + copied := copy(b, e.Data) + if copied != len(e.Data) { + return nil, ErrBuf + } + return b, nil +} + +func (e *EDNS0_LOCAL) unpack(b []byte) error { + e.Data = make([]byte, len(b)) + copied := copy(e.Data, b) + if copied != len(b) { + return ErrBuf + } + return nil +} + +// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep +// the TCP connection alive. See RFC 7828. +type EDNS0_TCP_KEEPALIVE struct { + Code uint16 // Always EDNSTCPKEEPALIVE + Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present; + Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order. +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE } + +func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) { + if e.Timeout != 0 && e.Length != 2 { + return nil, errors.New("dns: timeout specified but length is not 2") + } + if e.Timeout == 0 && e.Length != 0 { + return nil, errors.New("dns: timeout not specified but length is not 0") + } + b := make([]byte, 4+e.Length) + binary.BigEndian.PutUint16(b[0:], e.Code) + binary.BigEndian.PutUint16(b[2:], e.Length) + if e.Length == 2 { + binary.BigEndian.PutUint16(b[4:], e.Timeout) + } + return b, nil +} + +func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error { + if len(b) < 4 { + return ErrBuf + } + e.Length = binary.BigEndian.Uint16(b[2:4]) + if e.Length != 0 && e.Length != 2 { + return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10)) + } + if e.Length == 2 { + if len(b) < 6 { + return ErrBuf + } + e.Timeout = binary.BigEndian.Uint16(b[4:6]) + } + return nil +} + +func (e *EDNS0_TCP_KEEPALIVE) String() (s string) { + s = "use tcp keep-alive" + if e.Length == 0 { + s += ", timeout omitted" + } else { + s += fmt.Sprintf(", timeout %dms", e.Timeout*100) + } + return +} +func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} } + +// EDNS0_PADDING option is used to add padding to a request/response. The default +// value of padding SHOULD be 0x0 but other values MAY be used, for instance if +// compression is applied before encryption which may break signatures. +type EDNS0_PADDING struct { + Padding []byte +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING } +func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil } +func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil } +func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) } +func (e *EDNS0_PADDING) copy() EDNS0 { + b := make([]byte, len(e.Padding)) + copy(b, e.Padding) + return &EDNS0_PADDING{b} +} diff --git a/vendor/github.com/miekg/dns/format.go b/vendor/github.com/miekg/dns/format.go new file mode 100644 index 00000000..0ec79f2f --- /dev/null +++ b/vendor/github.com/miekg/dns/format.go @@ -0,0 +1,93 @@ +package dns + +import ( + "net" + "reflect" + "strconv" +) + +// NumField returns the number of rdata fields r has. +func NumField(r RR) int { + return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header +} + +// Field returns the rdata field i as a string. Fields are indexed starting from 1. +// RR types that holds slice data, for instance the NSEC type bitmap will return a single +// string where the types are concatenated using a space. +// Accessing non existing fields will cause a panic. +func Field(r RR, i int) string { + if i == 0 { + return "" + } + d := reflect.ValueOf(r).Elem().Field(i) + switch d.Kind() { + case reflect.String: + return d.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(d.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return strconv.FormatUint(d.Uint(), 10) + case reflect.Slice: + switch reflect.ValueOf(r).Elem().Type().Field(i).Tag { + case `dns:"a"`: + // TODO(miek): Hmm store this as 16 bytes + if d.Len() < net.IPv4len { + return "" + } + if d.Len() < net.IPv6len { + return net.IPv4(byte(d.Index(0).Uint()), + byte(d.Index(1).Uint()), + byte(d.Index(2).Uint()), + byte(d.Index(3).Uint())).String() + } + return net.IPv4(byte(d.Index(12).Uint()), + byte(d.Index(13).Uint()), + byte(d.Index(14).Uint()), + byte(d.Index(15).Uint())).String() + case `dns:"aaaa"`: + if d.Len() < net.IPv6len { + return "" + } + return net.IP{ + byte(d.Index(0).Uint()), + byte(d.Index(1).Uint()), + byte(d.Index(2).Uint()), + byte(d.Index(3).Uint()), + byte(d.Index(4).Uint()), + byte(d.Index(5).Uint()), + byte(d.Index(6).Uint()), + byte(d.Index(7).Uint()), + byte(d.Index(8).Uint()), + byte(d.Index(9).Uint()), + byte(d.Index(10).Uint()), + byte(d.Index(11).Uint()), + byte(d.Index(12).Uint()), + byte(d.Index(13).Uint()), + byte(d.Index(14).Uint()), + byte(d.Index(15).Uint()), + }.String() + case `dns:"nsec"`: + if d.Len() == 0 { + return "" + } + s := Type(d.Index(0).Uint()).String() + for i := 1; i < d.Len(); i++ { + s += " " + Type(d.Index(i).Uint()).String() + } + return s + default: + // if it does not have a tag its a string slice + fallthrough + case `dns:"txt"`: + if d.Len() == 0 { + return "" + } + s := d.Index(0).String() + for i := 1; i < d.Len(); i++ { + s += " " + d.Index(i).String() + } + return s + } + } + return "" +} diff --git a/vendor/github.com/miekg/dns/fuzz.go b/vendor/github.com/miekg/dns/fuzz.go new file mode 100644 index 00000000..a8a09184 --- /dev/null +++ b/vendor/github.com/miekg/dns/fuzz.go @@ -0,0 +1,23 @@ +// +build fuzz + +package dns + +func Fuzz(data []byte) int { + msg := new(Msg) + + if err := msg.Unpack(data); err != nil { + return 0 + } + if _, err := msg.Pack(); err != nil { + return 0 + } + + return 1 +} + +func FuzzNewRR(data []byte) int { + if _, err := NewRR(string(data)); err != nil { + return 0 + } + return 1 +} diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go new file mode 100644 index 00000000..97bc39f5 --- /dev/null +++ b/vendor/github.com/miekg/dns/generate.go @@ -0,0 +1,242 @@ +package dns + +import ( + "bytes" + "fmt" + "io" + "strconv" + "strings" +) + +// Parse the $GENERATE statement as used in BIND9 zones. +// See http://www.zytrax.com/books/dns/ch8/generate.html for instance. +// We are called after '$GENERATE '. After which we expect: +// * the range (12-24/2) +// * lhs (ownername) +// * [[ttl][class]] +// * type +// * rhs (rdata) +// But we are lazy here, only the range is parsed *all* occurrences +// of $ after that are interpreted. +func (zp *ZoneParser) generate(l lex) (RR, bool) { + token := l.token + step := 1 + if i := strings.IndexByte(token, '/'); i >= 0 { + if i+1 == len(token) { + return zp.setParseError("bad step in $GENERATE range", l) + } + + s, err := strconv.Atoi(token[i+1:]) + if err != nil || s <= 0 { + return zp.setParseError("bad step in $GENERATE range", l) + } + + step = s + token = token[:i] + } + + sx := strings.SplitN(token, "-", 2) + if len(sx) != 2 { + return zp.setParseError("bad start-stop in $GENERATE range", l) + } + + start, err := strconv.Atoi(sx[0]) + if err != nil { + return zp.setParseError("bad start in $GENERATE range", l) + } + + end, err := strconv.Atoi(sx[1]) + if err != nil { + return zp.setParseError("bad stop in $GENERATE range", l) + } + if end < 0 || start < 0 || end < start { + return zp.setParseError("bad range in $GENERATE range", l) + } + + zp.c.Next() // _BLANK + + // Create a complete new string, which we then parse again. + var s string + for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() { + if l.err { + return zp.setParseError("bad data in $GENERATE directive", l) + } + if l.value == zNewline { + break + } + + s += l.token + } + + r := &generateReader{ + s: s, + + cur: start, + start: start, + end: end, + step: step, + + file: zp.file, + lex: &l, + } + zp.sub = NewZoneParser(r, zp.origin, zp.file) + zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed + zp.sub.SetDefaultTTL(defaultTtl) + return zp.subNext() +} + +type generateReader struct { + s string + si int + + cur int + start int + end int + step int + + mod bytes.Buffer + + escape bool + + eof bool + + file string + lex *lex +} + +func (r *generateReader) parseError(msg string, end int) *ParseError { + r.eof = true // Make errors sticky. + + l := *r.lex + l.token = r.s[r.si-1 : end] + l.column += r.si // l.column starts one zBLANK before r.s + + return &ParseError{r.file, msg, l} +} + +func (r *generateReader) Read(p []byte) (int, error) { + // NewZLexer, through NewZoneParser, should use ReadByte and + // not end up here. + + panic("not implemented") +} + +func (r *generateReader) ReadByte() (byte, error) { + if r.eof { + return 0, io.EOF + } + if r.mod.Len() > 0 { + return r.mod.ReadByte() + } + + if r.si >= len(r.s) { + r.si = 0 + r.cur += r.step + + r.eof = r.cur > r.end || r.cur < 0 + return '\n', nil + } + + si := r.si + r.si++ + + switch r.s[si] { + case '\\': + if r.escape { + r.escape = false + return '\\', nil + } + + r.escape = true + return r.ReadByte() + case '$': + if r.escape { + r.escape = false + return '$', nil + } + + mod := "%d" + + if si >= len(r.s)-1 { + // End of the string + fmt.Fprintf(&r.mod, mod, r.cur) + return r.mod.ReadByte() + } + + if r.s[si+1] == '$' { + r.si++ + return '$', nil + } + + var offset int + + // Search for { and } + if r.s[si+1] == '{' { + // Modifier block + sep := strings.Index(r.s[si+2:], "}") + if sep < 0 { + return 0, r.parseError("bad modifier in $GENERATE", len(r.s)) + } + + var errMsg string + mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep]) + if errMsg != "" { + return 0, r.parseError(errMsg, si+3+sep) + } + if r.start+offset < 0 || r.end+offset > 1<<31-1 { + return 0, r.parseError("bad offset in $GENERATE", si+3+sep) + } + + r.si += 2 + sep // Jump to it + } + + fmt.Fprintf(&r.mod, mod, r.cur+offset) + return r.mod.ReadByte() + default: + if r.escape { // Pretty useless here + r.escape = false + return r.ReadByte() + } + + return r.s[si], nil + } +} + +// Convert a $GENERATE modifier 0,0,d to something Printf can deal with. +func modToPrintf(s string) (string, int, string) { + // Modifier is { offset [ ,width [ ,base ] ] } - provide default + // values for optional width and type, if necessary. + var offStr, widthStr, base string + switch xs := strings.Split(s, ","); len(xs) { + case 1: + offStr, widthStr, base = xs[0], "0", "d" + case 2: + offStr, widthStr, base = xs[0], xs[1], "d" + case 3: + offStr, widthStr, base = xs[0], xs[1], xs[2] + default: + return "", 0, "bad modifier in $GENERATE" + } + + switch base { + case "o", "d", "x", "X": + default: + return "", 0, "bad base in $GENERATE" + } + + offset, err := strconv.Atoi(offStr) + if err != nil { + return "", 0, "bad offset in $GENERATE" + } + + width, err := strconv.Atoi(widthStr) + if err != nil || width < 0 || width > 255 { + return "", 0, "bad width in $GENERATE" + } + + if width == 0 { + return "%" + base, offset, "" + } + + return "%0" + widthStr + base, offset, "" +} diff --git a/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/miekg/dns/labels.go new file mode 100644 index 00000000..e32d2a1d --- /dev/null +++ b/vendor/github.com/miekg/dns/labels.go @@ -0,0 +1,188 @@ +package dns + +// Holds a bunch of helper functions for dealing with labels. + +// SplitDomainName splits a name string into it's labels. +// www.miek.nl. returns []string{"www", "miek", "nl"} +// .www.miek.nl. returns []string{"", "www", "miek", "nl"}, +// The root label (.) returns nil. Note that using +// strings.Split(s) will work in most cases, but does not handle +// escaped dots (\.) for instance. +// s must be a syntactically valid domain name, see IsDomainName. +func SplitDomainName(s string) (labels []string) { + if len(s) == 0 { + return nil + } + fqdnEnd := 0 // offset of the final '.' or the length of the name + idx := Split(s) + begin := 0 + if IsFqdn(s) { + fqdnEnd = len(s) - 1 + } else { + fqdnEnd = len(s) + } + + switch len(idx) { + case 0: + return nil + case 1: + // no-op + default: + for _, end := range idx[1:] { + labels = append(labels, s[begin:end-1]) + begin = end + } + } + + return append(labels, s[begin:fqdnEnd]) +} + +// CompareDomainName compares the names s1 and s2 and +// returns how many labels they have in common starting from the *right*. +// The comparison stops at the first inequality. The names are downcased +// before the comparison. +// +// www.miek.nl. and miek.nl. have two labels in common: miek and nl +// www.miek.nl. and www.bla.nl. have one label in common: nl +// +// s1 and s2 must be syntactically valid domain names. +func CompareDomainName(s1, s2 string) (n int) { + // the first check: root label + if s1 == "." || s2 == "." { + return 0 + } + + l1 := Split(s1) + l2 := Split(s2) + + j1 := len(l1) - 1 // end + i1 := len(l1) - 2 // start + j2 := len(l2) - 1 + i2 := len(l2) - 2 + // the second check can be done here: last/only label + // before we fall through into the for-loop below + if equal(s1[l1[j1]:], s2[l2[j2]:]) { + n++ + } else { + return + } + for { + if i1 < 0 || i2 < 0 { + break + } + if equal(s1[l1[i1]:l1[j1]], s2[l2[i2]:l2[j2]]) { + n++ + } else { + break + } + j1-- + i1-- + j2-- + i2-- + } + return +} + +// CountLabel counts the the number of labels in the string s. +// s must be a syntactically valid domain name. +func CountLabel(s string) (labels int) { + if s == "." { + return + } + off := 0 + end := false + for { + off, end = NextLabel(s, off) + labels++ + if end { + return + } + } +} + +// Split splits a name s into its label indexes. +// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}. +// The root name (.) returns nil. Also see SplitDomainName. +// s must be a syntactically valid domain name. +func Split(s string) []int { + if s == "." { + return nil + } + idx := make([]int, 1, 3) + off := 0 + end := false + + for { + off, end = NextLabel(s, off) + if end { + return idx + } + idx = append(idx, off) + } +} + +// NextLabel returns the index of the start of the next label in the +// string s starting at offset. +// The bool end is true when the end of the string has been reached. +// Also see PrevLabel. +func NextLabel(s string, offset int) (i int, end bool) { + quote := false + for i = offset; i < len(s)-1; i++ { + switch s[i] { + case '\\': + quote = !quote + default: + quote = false + case '.': + if quote { + quote = !quote + continue + } + return i + 1, false + } + } + return i + 1, true +} + +// PrevLabel returns the index of the label when starting from the right and +// jumping n labels to the left. +// The bool start is true when the start of the string has been overshot. +// Also see NextLabel. +func PrevLabel(s string, n int) (i int, start bool) { + if n == 0 { + return len(s), false + } + lab := Split(s) + if lab == nil { + return 0, true + } + if n > len(lab) { + return 0, true + } + return lab[len(lab)-n], false +} + +// equal compares a and b while ignoring case. It returns true when equal otherwise false. +func equal(a, b string) bool { + // might be lifted into API function. + la := len(a) + lb := len(b) + if la != lb { + return false + } + + for i := la - 1; i >= 0; i-- { + ai := a[i] + bi := b[i] + if ai >= 'A' && ai <= 'Z' { + ai |= 'a' - 'A' + } + if bi >= 'A' && bi <= 'Z' { + bi |= 'a' - 'A' + } + if ai != bi { + return false + } + } + return true +} diff --git a/vendor/github.com/miekg/dns/listen_go111.go b/vendor/github.com/miekg/dns/listen_go111.go new file mode 100644 index 00000000..fad195cf --- /dev/null +++ b/vendor/github.com/miekg/dns/listen_go111.go @@ -0,0 +1,44 @@ +// +build go1.11 +// +build aix darwin dragonfly freebsd linux netbsd openbsd + +package dns + +import ( + "context" + "net" + "syscall" + + "golang.org/x/sys/unix" +) + +const supportsReusePort = true + +func reuseportControl(network, address string, c syscall.RawConn) error { + var opErr error + err := c.Control(func(fd uintptr) { + opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + }) + if err != nil { + return err + } + + return opErr +} + +func listenTCP(network, addr string, reuseport bool) (net.Listener, error) { + var lc net.ListenConfig + if reuseport { + lc.Control = reuseportControl + } + + return lc.Listen(context.Background(), network, addr) +} + +func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) { + var lc net.ListenConfig + if reuseport { + lc.Control = reuseportControl + } + + return lc.ListenPacket(context.Background(), network, addr) +} diff --git a/vendor/github.com/miekg/dns/listen_go_not111.go b/vendor/github.com/miekg/dns/listen_go_not111.go new file mode 100644 index 00000000..b9201417 --- /dev/null +++ b/vendor/github.com/miekg/dns/listen_go_not111.go @@ -0,0 +1,23 @@ +// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd + +package dns + +import "net" + +const supportsReusePort = false + +func listenTCP(network, addr string, reuseport bool) (net.Listener, error) { + if reuseport { + // TODO(tmthrgd): return an error? + } + + return net.Listen(network, addr) +} + +func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) { + if reuseport { + // TODO(tmthrgd): return an error? + } + + return net.ListenPacket(network, addr) +} diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go new file mode 100644 index 00000000..e04fb5d7 --- /dev/null +++ b/vendor/github.com/miekg/dns/msg.go @@ -0,0 +1,1228 @@ +// DNS packet assembly, see RFC 1035. Converting from - Unpack() - +// and to - Pack() - wire format. +// All the packers and unpackers take a (msg []byte, off int) +// and return (off1 int, ok bool). If they return ok==false, they +// also return off1==len(msg), so that the next unpacker will +// also fail. This lets us avoid checks of ok until the end of a +// packing sequence. + +package dns + +//go:generate go run msg_generate.go + +import ( + crand "crypto/rand" + "encoding/binary" + "fmt" + "math/big" + "math/rand" + "strconv" + "strings" + "sync" +) + +const ( + maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer + maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4 + + // This is the maximum number of compression pointers that should occur in a + // semantically valid message. Each label in a domain name must be at least one + // octet and is separated by a period. The root label won't be represented by a + // compression pointer to a compression pointer, hence the -2 to exclude the + // smallest valid root label. + // + // It is possible to construct a valid message that has more compression pointers + // than this, and still doesn't loop, by pointing to a previous pointer. This is + // not something a well written implementation should ever do, so we leave them + // to trip the maximum compression pointer check. + maxCompressionPointers = (maxDomainNameWireOctets+1)/2 - 2 + + // This is the maximum length of a domain name in presentation format. The + // maximum wire length of a domain name is 255 octets (see above), with the + // maximum label length being 63. The wire format requires one extra byte over + // the presentation format, reducing the number of octets by 1. Each label in + // the name will be separated by a single period, with each octet in the label + // expanding to at most 4 bytes (\DDD). If all other labels are of the maximum + // length, then the final label can only be 61 octets long to not exceed the + // maximum allowed wire length. + maxDomainNamePresentationLength = 61*4 + 1 + 63*4 + 1 + 63*4 + 1 + 63*4 + 1 +) + +// Errors defined in this package. +var ( + ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm. + ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication. + ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message. + ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized. + ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ... + ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot. + ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID. + ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid. + ErrKey error = &Error{err: "bad key"} + ErrKeySize error = &Error{err: "bad key size"} + ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)} + ErrNoSig error = &Error{err: "no signature found"} + ErrPrivKey error = &Error{err: "bad private key"} + ErrRcode error = &Error{err: "bad rcode"} + ErrRdata error = &Error{err: "bad rdata"} + ErrRRset error = &Error{err: "bad rrset"} + ErrSecret error = &Error{err: "no secrets defined"} + ErrShortRead error = &Error{err: "short read"} + ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated. + ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers. + ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication. +) + +// Id by default, returns a 16 bits random number to be used as a +// message id. The random provided should be good enough. This being a +// variable the function can be reassigned to a custom function. +// For instance, to make it return a static value: +// +// dns.Id = func() uint16 { return 3 } +var Id = id + +var ( + idLock sync.Mutex + idRand *rand.Rand +) + +// id returns a 16 bits random number to be used as a +// message id. The random provided should be good enough. +func id() uint16 { + idLock.Lock() + + if idRand == nil { + // This (partially) works around + // https://github.com/golang/go/issues/11833 by only + // seeding idRand upon the first call to id. + + var seed int64 + var buf [8]byte + + if _, err := crand.Read(buf[:]); err == nil { + seed = int64(binary.LittleEndian.Uint64(buf[:])) + } else { + seed = rand.Int63() + } + + idRand = rand.New(rand.NewSource(seed)) + } + + // The call to idRand.Uint32 must be within the + // mutex lock because *rand.Rand is not safe for + // concurrent use. + // + // There is no added performance overhead to calling + // idRand.Uint32 inside a mutex lock over just + // calling rand.Uint32 as the global math/rand rng + // is internally protected by a sync.Mutex. + id := uint16(idRand.Uint32()) + + idLock.Unlock() + return id +} + +// MsgHdr is a a manually-unpacked version of (id, bits). +type MsgHdr struct { + Id uint16 + Response bool + Opcode int + Authoritative bool + Truncated bool + RecursionDesired bool + RecursionAvailable bool + Zero bool + AuthenticatedData bool + CheckingDisabled bool + Rcode int +} + +// Msg contains the layout of a DNS message. +type Msg struct { + MsgHdr + Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. + Question []Question // Holds the RR(s) of the question section. + Answer []RR // Holds the RR(s) of the answer section. + Ns []RR // Holds the RR(s) of the authority section. + Extra []RR // Holds the RR(s) of the additional section. +} + +// ClassToString is a maps Classes to strings for each CLASS wire type. +var ClassToString = map[uint16]string{ + ClassINET: "IN", + ClassCSNET: "CS", + ClassCHAOS: "CH", + ClassHESIOD: "HS", + ClassNONE: "NONE", + ClassANY: "ANY", +} + +// OpcodeToString maps Opcodes to strings. +var OpcodeToString = map[int]string{ + OpcodeQuery: "QUERY", + OpcodeIQuery: "IQUERY", + OpcodeStatus: "STATUS", + OpcodeNotify: "NOTIFY", + OpcodeUpdate: "UPDATE", +} + +// RcodeToString maps Rcodes to strings. +var RcodeToString = map[int]string{ + RcodeSuccess: "NOERROR", + RcodeFormatError: "FORMERR", + RcodeServerFailure: "SERVFAIL", + RcodeNameError: "NXDOMAIN", + RcodeNotImplemented: "NOTIMP", + RcodeRefused: "REFUSED", + RcodeYXDomain: "YXDOMAIN", // See RFC 2136 + RcodeYXRrset: "YXRRSET", + RcodeNXRrset: "NXRRSET", + RcodeNotAuth: "NOTAUTH", + RcodeNotZone: "NOTZONE", + RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891 + // RcodeBadVers: "BADVERS", + RcodeBadKey: "BADKEY", + RcodeBadTime: "BADTIME", + RcodeBadMode: "BADMODE", + RcodeBadName: "BADNAME", + RcodeBadAlg: "BADALG", + RcodeBadTrunc: "BADTRUNC", + RcodeBadCookie: "BADCOOKIE", +} + +// compressionMap is used to allow a more efficient compression map +// to be used for internal packDomainName calls without changing the +// signature or functionality of public API. +// +// In particular, map[string]uint16 uses 25% less per-entry memory +// than does map[string]int. +type compressionMap struct { + ext map[string]int // external callers + int map[string]uint16 // internal callers +} + +func (m compressionMap) valid() bool { + return m.int != nil || m.ext != nil +} + +func (m compressionMap) insert(s string, pos int) { + if m.ext != nil { + m.ext[s] = pos + } else { + m.int[s] = uint16(pos) + } +} + +func (m compressionMap) find(s string) (int, bool) { + if m.ext != nil { + pos, ok := m.ext[s] + return pos, ok + } + + pos, ok := m.int[s] + return int(pos), ok +} + +// Domain names are a sequence of counted strings +// split at the dots. They end with a zero-length string. + +// PackDomainName packs a domain name s into msg[off:]. +// If compression is wanted compress must be true and the compression +// map needs to hold a mapping between domain names and offsets +// pointing into msg. +func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { + return packDomainName(s, msg, off, compressionMap{ext: compression}, compress) +} + +func packDomainName(s string, msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + // XXX: A logical copy of this function exists in IsDomainName and + // should be kept in sync with this function. + + ls := len(s) + if ls == 0 { // Ok, for instance when dealing with update RR without any rdata. + return off, nil + } + + // If not fully qualified, error out. + if !IsFqdn(s) { + return len(msg), ErrFqdn + } + + // Each dot ends a segment of the name. + // We trade each dot byte for a length byte. + // Except for escaped dots (\.), which are normal dots. + // There is also a trailing zero. + + // Compression + pointer := -1 + + // Emit sequence of counted strings, chopping at dots. + var ( + begin int + compBegin int + compOff int + bs []byte + wasDot bool + ) +loop: + for i := 0; i < ls; i++ { + var c byte + if bs == nil { + c = s[i] + } else { + c = bs[i] + } + + switch c { + case '\\': + if off+1 > len(msg) { + return len(msg), ErrBuf + } + + if bs == nil { + bs = []byte(s) + } + + // check for \DDD + if i+3 < ls && isDigit(bs[i+1]) && isDigit(bs[i+2]) && isDigit(bs[i+3]) { + bs[i] = dddToByte(bs[i+1:]) + copy(bs[i+1:ls-3], bs[i+4:]) + ls -= 3 + compOff += 3 + } else { + copy(bs[i:ls-1], bs[i+1:]) + ls-- + compOff++ + } + + wasDot = false + case '.': + if wasDot { + // two dots back to back is not legal + return len(msg), ErrRdata + } + wasDot = true + + labelLen := i - begin + if labelLen >= 1<<6 { // top two bits of length must be clear + return len(msg), ErrRdata + } + + // off can already (we're in a loop) be bigger than len(msg) + // this happens when a name isn't fully qualified + if off+1+labelLen > len(msg) { + return len(msg), ErrBuf + } + + // Don't try to compress '.' + // We should only compress when compress is true, but we should also still pick + // up names that can be used for *future* compression(s). + if compression.valid() && !isRootLabel(s, bs, begin, ls) { + if p, ok := compression.find(s[compBegin:]); ok { + // The first hit is the longest matching dname + // keep the pointer offset we get back and store + // the offset of the current name, because that's + // where we need to insert the pointer later + + // If compress is true, we're allowed to compress this dname + if compress { + pointer = p // Where to point to + break loop + } + } else if off < maxCompressionOffset { + // Only offsets smaller than maxCompressionOffset can be used. + compression.insert(s[compBegin:], off) + } + } + + // The following is covered by the length check above. + msg[off] = byte(labelLen) + + if bs == nil { + copy(msg[off+1:], s[begin:i]) + } else { + copy(msg[off+1:], bs[begin:i]) + } + off += 1 + labelLen + + begin = i + 1 + compBegin = begin + compOff + default: + wasDot = false + } + } + + // Root label is special + if isRootLabel(s, bs, 0, ls) { + return off, nil + } + + // If we did compression and we find something add the pointer here + if pointer != -1 { + // We have two bytes (14 bits) to put the pointer in + binary.BigEndian.PutUint16(msg[off:], uint16(pointer^0xC000)) + return off + 2, nil + } + + if off < len(msg) { + msg[off] = 0 + } + + return off + 1, nil +} + +// isRootLabel returns whether s or bs, from off to end, is the root +// label ".". +// +// If bs is nil, s will be checked, otherwise bs will be checked. +func isRootLabel(s string, bs []byte, off, end int) bool { + if bs == nil { + return s[off:end] == "." + } + + return end-off == 1 && bs[off] == '.' +} + +// Unpack a domain name. +// In addition to the simple sequences of counted strings above, +// domain names are allowed to refer to strings elsewhere in the +// packet, to avoid repeating common suffixes when returning +// many entries in a single domain. The pointers are marked +// by a length byte with the top two bits set. Ignoring those +// two bits, that byte and the next give a 14 bit offset from msg[0] +// where we should pick up the trail. +// Note that if we jump elsewhere in the packet, +// we return off1 == the offset after the first pointer we found, +// which is where the next record will start. +// In theory, the pointers are only allowed to jump backward. +// We let them jump anywhere and stop jumping after a while. + +// UnpackDomainName unpacks a domain name into a string. It returns +// the name, the new offset into msg and any error that occurred. +// +// When an error is encountered, the unpacked name will be discarded +// and len(msg) will be returned as the offset. +func UnpackDomainName(msg []byte, off int) (string, int, error) { + s := make([]byte, 0, maxDomainNamePresentationLength) + off1 := 0 + lenmsg := len(msg) + budget := maxDomainNameWireOctets + ptr := 0 // number of pointers followed +Loop: + for { + if off >= lenmsg { + return "", lenmsg, ErrBuf + } + c := int(msg[off]) + off++ + switch c & 0xC0 { + case 0x00: + if c == 0x00 { + // end of name + break Loop + } + // literal string + if off+c > lenmsg { + return "", lenmsg, ErrBuf + } + budget -= c + 1 // +1 for the label separator + if budget <= 0 { + return "", lenmsg, ErrLongDomain + } + for _, b := range msg[off : off+c] { + switch b { + case '.', '(', ')', ';', ' ', '@': + fallthrough + case '"', '\\': + s = append(s, '\\', b) + default: + if b < ' ' || b > '~' { // unprintable, use \DDD + s = append(s, escapeByte(b)...) + } else { + s = append(s, b) + } + } + } + s = append(s, '.') + off += c + case 0xC0: + // pointer to somewhere else in msg. + // remember location after first ptr, + // since that's how many bytes we consumed. + // also, don't follow too many pointers -- + // maybe there's a loop. + if off >= lenmsg { + return "", lenmsg, ErrBuf + } + c1 := msg[off] + off++ + if ptr == 0 { + off1 = off + } + if ptr++; ptr > maxCompressionPointers { + return "", lenmsg, &Error{err: "too many compression pointers"} + } + // pointer should guarantee that it advances and points forwards at least + // but the condition on previous three lines guarantees that it's + // at least loop-free + off = (c^0xC0)<<8 | int(c1) + default: + // 0x80 and 0x40 are reserved + return "", lenmsg, ErrRdata + } + } + if ptr == 0 { + off1 = off + } + if len(s) == 0 { + return ".", off1, nil + } + return string(s), off1, nil +} + +func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) { + if len(txt) == 0 { + if offset >= len(msg) { + return offset, ErrBuf + } + msg[offset] = 0 + return offset, nil + } + var err error + for _, s := range txt { + if len(s) > len(tmp) { + return offset, ErrBuf + } + offset, err = packTxtString(s, msg, offset, tmp) + if err != nil { + return offset, err + } + } + return offset, nil +} + +func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) { + lenByteOffset := offset + if offset >= len(msg) || len(s) > len(tmp) { + return offset, ErrBuf + } + offset++ + bs := tmp[:len(s)] + copy(bs, s) + for i := 0; i < len(bs); i++ { + if len(msg) <= offset { + return offset, ErrBuf + } + if bs[i] == '\\' { + i++ + if i == len(bs) { + break + } + // check for \DDD + if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { + msg[offset] = dddToByte(bs[i:]) + i += 2 + } else { + msg[offset] = bs[i] + } + } else { + msg[offset] = bs[i] + } + offset++ + } + l := offset - lenByteOffset - 1 + if l > 255 { + return offset, &Error{err: "string exceeded 255 bytes in txt"} + } + msg[lenByteOffset] = byte(l) + return offset, nil +} + +func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) { + if offset >= len(msg) || len(s) > len(tmp) { + return offset, ErrBuf + } + bs := tmp[:len(s)] + copy(bs, s) + for i := 0; i < len(bs); i++ { + if len(msg) <= offset { + return offset, ErrBuf + } + if bs[i] == '\\' { + i++ + if i == len(bs) { + break + } + // check for \DDD + if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { + msg[offset] = dddToByte(bs[i:]) + i += 2 + } else { + msg[offset] = bs[i] + } + } else { + msg[offset] = bs[i] + } + offset++ + } + return offset, nil +} + +func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) { + off = off0 + var s string + for off < len(msg) && err == nil { + s, off, err = unpackString(msg, off) + if err == nil { + ss = append(ss, s) + } + } + return +} + +// Helpers for dealing with escaped bytes +func isDigit(b byte) bool { return b >= '0' && b <= '9' } + +func dddToByte(s []byte) byte { + _ = s[2] // bounds check hint to compiler; see golang.org/issue/14808 + return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) +} + +func dddStringToByte(s string) byte { + _ = s[2] // bounds check hint to compiler; see golang.org/issue/14808 + return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) +} + +// Helper function for packing and unpacking +func intToBytes(i *big.Int, length int) []byte { + buf := i.Bytes() + if len(buf) < length { + b := make([]byte, length) + copy(b[length-len(buf):], buf) + return b + } + return buf +} + +// PackRR packs a resource record rr into msg[off:]. +// See PackDomainName for documentation about the compression. +func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { + headerEnd, off1, err := packRR(rr, msg, off, compressionMap{ext: compression}, compress) + if err == nil { + // packRR no longer sets the Rdlength field on the rr, but + // callers might be expecting it so we set it here. + rr.Header().Rdlength = uint16(off1 - headerEnd) + } + return off1, err +} + +func packRR(rr RR, msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error) { + if rr == nil { + return len(msg), len(msg), &Error{err: "nil rr"} + } + + headerEnd, err = rr.Header().packHeader(msg, off, compression, compress) + if err != nil { + return headerEnd, len(msg), err + } + + off1, err = rr.pack(msg, headerEnd, compression, compress) + if err != nil { + return headerEnd, len(msg), err + } + + rdlength := off1 - headerEnd + if int(uint16(rdlength)) != rdlength { // overflow + return headerEnd, len(msg), ErrRdata + } + + // The RDLENGTH field is the last field in the header and we set it here. + binary.BigEndian.PutUint16(msg[headerEnd-2:], uint16(rdlength)) + return headerEnd, off1, nil +} + +// UnpackRR unpacks msg[off:] into an RR. +func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) { + h, off, msg, err := unpackHeader(msg, off) + if err != nil { + return nil, len(msg), err + } + + return UnpackRRWithHeader(h, msg, off) +} + +// UnpackRRWithHeader unpacks the record type specific payload given an existing +// RR_Header. +func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err error) { + if newFn, ok := TypeToRR[h.Rrtype]; ok { + rr = newFn() + *rr.Header() = h + } else { + rr = &RFC3597{Hdr: h} + } + + if noRdata(h) { + return rr, off, nil + } + + end := off + int(h.Rdlength) + + off, err = rr.unpack(msg, off) + if err != nil { + return nil, end, err + } + if off != end { + return &h, end, &Error{err: "bad rdlength"} + } + + return rr, off, nil +} + +// unpackRRslice unpacks msg[off:] into an []RR. +// If we cannot unpack the whole array, then it will return nil +func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) { + var r RR + // Don't pre-allocate, l may be under attacker control + var dst []RR + for i := 0; i < l; i++ { + off1 := off + r, off, err = UnpackRR(msg, off) + if err != nil { + off = len(msg) + break + } + // If offset does not increase anymore, l is a lie + if off1 == off { + l = i + break + } + dst = append(dst, r) + } + if err != nil && off == len(msg) { + dst = nil + } + return dst, off, err +} + +// Convert a MsgHdr to a string, with dig-like headers: +// +//;; opcode: QUERY, status: NOERROR, id: 48404 +// +//;; flags: qr aa rd ra; +func (h *MsgHdr) String() string { + if h == nil { + return " MsgHdr" + } + + s := ";; opcode: " + OpcodeToString[h.Opcode] + s += ", status: " + RcodeToString[h.Rcode] + s += ", id: " + strconv.Itoa(int(h.Id)) + "\n" + + s += ";; flags:" + if h.Response { + s += " qr" + } + if h.Authoritative { + s += " aa" + } + if h.Truncated { + s += " tc" + } + if h.RecursionDesired { + s += " rd" + } + if h.RecursionAvailable { + s += " ra" + } + if h.Zero { // Hmm + s += " z" + } + if h.AuthenticatedData { + s += " ad" + } + if h.CheckingDisabled { + s += " cd" + } + + s += ";" + return s +} + +// Pack packs a Msg: it is converted to to wire format. +// If the dns.Compress is true the message will be in compressed wire format. +func (dns *Msg) Pack() (msg []byte, err error) { + return dns.PackBuffer(nil) +} + +// PackBuffer packs a Msg, using the given buffer buf. If buf is too small a new buffer is allocated. +func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) { + // If this message can't be compressed, avoid filling the + // compression map and creating garbage. + if dns.Compress && dns.isCompressible() { + compression := make(map[string]uint16) // Compression pointer mappings. + return dns.packBufferWithCompressionMap(buf, compressionMap{int: compression}, true) + } + + return dns.packBufferWithCompressionMap(buf, compressionMap{}, false) +} + +// packBufferWithCompressionMap packs a Msg, using the given buffer buf. +func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression compressionMap, compress bool) (msg []byte, err error) { + if dns.Rcode < 0 || dns.Rcode > 0xFFF { + return nil, ErrRcode + } + + // Set extended rcode unconditionally if we have an opt, this will allow + // reseting the extended rcode bits if they need to. + if opt := dns.IsEdns0(); opt != nil { + opt.SetExtendedRcode(uint16(dns.Rcode)) + } else if dns.Rcode > 0xF { + // If Rcode is an extended one and opt is nil, error out. + return nil, ErrExtendedRcode + } + + // Convert convenient Msg into wire-like Header. + var dh Header + dh.Id = dns.Id + dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode&0xF) + if dns.Response { + dh.Bits |= _QR + } + if dns.Authoritative { + dh.Bits |= _AA + } + if dns.Truncated { + dh.Bits |= _TC + } + if dns.RecursionDesired { + dh.Bits |= _RD + } + if dns.RecursionAvailable { + dh.Bits |= _RA + } + if dns.Zero { + dh.Bits |= _Z + } + if dns.AuthenticatedData { + dh.Bits |= _AD + } + if dns.CheckingDisabled { + dh.Bits |= _CD + } + + dh.Qdcount = uint16(len(dns.Question)) + dh.Ancount = uint16(len(dns.Answer)) + dh.Nscount = uint16(len(dns.Ns)) + dh.Arcount = uint16(len(dns.Extra)) + + // We need the uncompressed length here, because we first pack it and then compress it. + msg = buf + uncompressedLen := msgLenWithCompressionMap(dns, nil) + if packLen := uncompressedLen + 1; len(msg) < packLen { + msg = make([]byte, packLen) + } + + // Pack it in: header and then the pieces. + off := 0 + off, err = dh.pack(msg, off, compression, compress) + if err != nil { + return nil, err + } + for _, r := range dns.Question { + off, err = r.pack(msg, off, compression, compress) + if err != nil { + return nil, err + } + } + for _, r := range dns.Answer { + _, off, err = packRR(r, msg, off, compression, compress) + if err != nil { + return nil, err + } + } + for _, r := range dns.Ns { + _, off, err = packRR(r, msg, off, compression, compress) + if err != nil { + return nil, err + } + } + for _, r := range dns.Extra { + _, off, err = packRR(r, msg, off, compression, compress) + if err != nil { + return nil, err + } + } + return msg[:off], nil +} + +func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) { + // If we are at the end of the message we should return *just* the + // header. This can still be useful to the caller. 9.9.9.9 sends these + // when responding with REFUSED for instance. + if off == len(msg) { + // reset sections before returning + dns.Question, dns.Answer, dns.Ns, dns.Extra = nil, nil, nil, nil + return nil + } + + // Qdcount, Ancount, Nscount, Arcount can't be trusted, as they are + // attacker controlled. This means we can't use them to pre-allocate + // slices. + dns.Question = nil + for i := 0; i < int(dh.Qdcount); i++ { + off1 := off + var q Question + q, off, err = unpackQuestion(msg, off) + if err != nil { + return err + } + if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie! + dh.Qdcount = uint16(i) + break + } + dns.Question = append(dns.Question, q) + } + + dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off) + // The header counts might have been wrong so we need to update it + dh.Ancount = uint16(len(dns.Answer)) + if err == nil { + dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off) + } + // The header counts might have been wrong so we need to update it + dh.Nscount = uint16(len(dns.Ns)) + if err == nil { + dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off) + } + // The header counts might have been wrong so we need to update it + dh.Arcount = uint16(len(dns.Extra)) + + // Set extended Rcode + if opt := dns.IsEdns0(); opt != nil { + dns.Rcode |= opt.ExtendedRcode() + } + + if off != len(msg) { + // TODO(miek) make this an error? + // use PackOpt to let people tell how detailed the error reporting should be? + // println("dns: extra bytes in dns packet", off, "<", len(msg)) + } + return err + +} + +// Unpack unpacks a binary message to a Msg structure. +func (dns *Msg) Unpack(msg []byte) (err error) { + dh, off, err := unpackMsgHdr(msg, 0) + if err != nil { + return err + } + + dns.setHdr(dh) + return dns.unpack(dh, msg, off) +} + +// Convert a complete message to a string with dig-like output. +func (dns *Msg) String() string { + if dns == nil { + return " MsgHdr" + } + s := dns.MsgHdr.String() + " " + s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", " + s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", " + s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", " + s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n" + if len(dns.Question) > 0 { + s += "\n;; QUESTION SECTION:\n" + for _, r := range dns.Question { + s += r.String() + "\n" + } + } + if len(dns.Answer) > 0 { + s += "\n;; ANSWER SECTION:\n" + for _, r := range dns.Answer { + if r != nil { + s += r.String() + "\n" + } + } + } + if len(dns.Ns) > 0 { + s += "\n;; AUTHORITY SECTION:\n" + for _, r := range dns.Ns { + if r != nil { + s += r.String() + "\n" + } + } + } + if len(dns.Extra) > 0 { + s += "\n;; ADDITIONAL SECTION:\n" + for _, r := range dns.Extra { + if r != nil { + s += r.String() + "\n" + } + } + } + return s +} + +// isCompressible returns whether the msg may be compressible. +func (dns *Msg) isCompressible() bool { + // If we only have one question, there is nothing we can ever compress. + return len(dns.Question) > 1 || len(dns.Answer) > 0 || + len(dns.Ns) > 0 || len(dns.Extra) > 0 +} + +// Len returns the message length when in (un)compressed wire format. +// If dns.Compress is true compression it is taken into account. Len() +// is provided to be a faster way to get the size of the resulting packet, +// than packing it, measuring the size and discarding the buffer. +func (dns *Msg) Len() int { + // If this message can't be compressed, avoid filling the + // compression map and creating garbage. + if dns.Compress && dns.isCompressible() { + compression := make(map[string]struct{}) + return msgLenWithCompressionMap(dns, compression) + } + + return msgLenWithCompressionMap(dns, nil) +} + +func msgLenWithCompressionMap(dns *Msg, compression map[string]struct{}) int { + l := headerSize + + for _, r := range dns.Question { + l += r.len(l, compression) + } + for _, r := range dns.Answer { + if r != nil { + l += r.len(l, compression) + } + } + for _, r := range dns.Ns { + if r != nil { + l += r.len(l, compression) + } + } + for _, r := range dns.Extra { + if r != nil { + l += r.len(l, compression) + } + } + + return l +} + +func domainNameLen(s string, off int, compression map[string]struct{}, compress bool) int { + if s == "" || s == "." { + return 1 + } + + escaped := strings.Contains(s, "\\") + + if compression != nil && (compress || off < maxCompressionOffset) { + // compressionLenSearch will insert the entry into the compression + // map if it doesn't contain it. + if l, ok := compressionLenSearch(compression, s, off); ok && compress { + if escaped { + return escapedNameLen(s[:l]) + 2 + } + + return l + 2 + } + } + + if escaped { + return escapedNameLen(s) + 1 + } + + return len(s) + 1 +} + +func escapedNameLen(s string) int { + nameLen := len(s) + for i := 0; i < len(s); i++ { + if s[i] != '\\' { + continue + } + + if i+3 < len(s) && isDigit(s[i+1]) && isDigit(s[i+2]) && isDigit(s[i+3]) { + nameLen -= 3 + i += 3 + } else { + nameLen-- + i++ + } + } + + return nameLen +} + +func compressionLenSearch(c map[string]struct{}, s string, msgOff int) (int, bool) { + for off, end := 0, false; !end; off, end = NextLabel(s, off) { + if _, ok := c[s[off:]]; ok { + return off, true + } + + if msgOff+off < maxCompressionOffset { + c[s[off:]] = struct{}{} + } + } + + return 0, false +} + +// Copy returns a new RR which is a deep-copy of r. +func Copy(r RR) RR { return r.copy() } + +// Len returns the length (in octets) of the uncompressed RR in wire format. +func Len(r RR) int { return r.len(0, nil) } + +// Copy returns a new *Msg which is a deep-copy of dns. +func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) } + +// CopyTo copies the contents to the provided message using a deep-copy and returns the copy. +func (dns *Msg) CopyTo(r1 *Msg) *Msg { + r1.MsgHdr = dns.MsgHdr + r1.Compress = dns.Compress + + if len(dns.Question) > 0 { + r1.Question = make([]Question, len(dns.Question)) + copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy + } + + rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra)) + r1.Answer, rrArr = rrArr[:0:len(dns.Answer)], rrArr[len(dns.Answer):] + r1.Ns, rrArr = rrArr[:0:len(dns.Ns)], rrArr[len(dns.Ns):] + r1.Extra = rrArr[:0:len(dns.Extra)] + + for _, r := range dns.Answer { + r1.Answer = append(r1.Answer, r.copy()) + } + + for _, r := range dns.Ns { + r1.Ns = append(r1.Ns, r.copy()) + } + + for _, r := range dns.Extra { + r1.Extra = append(r1.Extra, r.copy()) + } + + return r1 +} + +func (q *Question) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { + off, err := packDomainName(q.Name, msg, off, compression, compress) + if err != nil { + return off, err + } + off, err = packUint16(q.Qtype, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(q.Qclass, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func unpackQuestion(msg []byte, off int) (Question, int, error) { + var ( + q Question + err error + ) + q.Name, off, err = UnpackDomainName(msg, off) + if err != nil { + return q, off, err + } + if off == len(msg) { + return q, off, nil + } + q.Qtype, off, err = unpackUint16(msg, off) + if err != nil { + return q, off, err + } + if off == len(msg) { + return q, off, nil + } + q.Qclass, off, err = unpackUint16(msg, off) + if off == len(msg) { + return q, off, nil + } + return q, off, err +} + +func (dh *Header) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { + off, err := packUint16(dh.Id, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(dh.Bits, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(dh.Qdcount, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(dh.Ancount, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(dh.Nscount, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(dh.Arcount, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func unpackMsgHdr(msg []byte, off int) (Header, int, error) { + var ( + dh Header + err error + ) + dh.Id, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + dh.Bits, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + dh.Qdcount, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + dh.Ancount, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + dh.Nscount, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + dh.Arcount, off, err = unpackUint16(msg, off) + if err != nil { + return dh, off, err + } + return dh, off, nil +} + +// setHdr set the header in the dns using the binary data in dh. +func (dns *Msg) setHdr(dh Header) { + dns.Id = dh.Id + dns.Response = dh.Bits&_QR != 0 + dns.Opcode = int(dh.Bits>>11) & 0xF + dns.Authoritative = dh.Bits&_AA != 0 + dns.Truncated = dh.Bits&_TC != 0 + dns.RecursionDesired = dh.Bits&_RD != 0 + dns.RecursionAvailable = dh.Bits&_RA != 0 + dns.Zero = dh.Bits&_Z != 0 // _Z covers the zero bit, which should be zero; not sure why we set it to the opposite. + dns.AuthenticatedData = dh.Bits&_AD != 0 + dns.CheckingDisabled = dh.Bits&_CD != 0 + dns.Rcode = int(dh.Bits & 0xF) +} diff --git a/vendor/github.com/miekg/dns/msg_generate.go b/vendor/github.com/miekg/dns/msg_generate.go new file mode 100644 index 00000000..721a0fce --- /dev/null +++ b/vendor/github.com/miekg/dns/msg_generate.go @@ -0,0 +1,328 @@ +//+build ignore + +// msg_generate.go is meant to run with go generate. It will use +// go/{importer,types} to track down all the RR struct types. Then for each type +// it will generate pack/unpack methods based on the struct tags. The generated source is +// written to zmsg.go, and is meant to be checked into git. +package main + +import ( + "bytes" + "fmt" + "go/format" + "go/importer" + "go/types" + "log" + "os" + "strings" +) + +var packageHdr = ` +// Code generated by "go run msg_generate.go"; DO NOT EDIT. + +package dns + +` + +// getTypeStruct will take a type and the package scope, and return the +// (innermost) struct if the type is considered a RR type (currently defined as +// those structs beginning with a RR_Header, could be redefined as implementing +// the RR interface). The bool return value indicates if embedded structs were +// resolved. +func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { + st, ok := t.Underlying().(*types.Struct) + if !ok { + return nil, false + } + if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { + return st, false + } + if st.Field(0).Anonymous() { + st, _ := getTypeStruct(st.Field(0).Type(), scope) + return st, true + } + return nil, false +} + +func main() { + // Import and type-check the package + pkg, err := importer.Default().Import("github.com/miekg/dns") + fatalIfErr(err) + scope := pkg.Scope() + + // Collect actual types (*X) + var namedTypes []string + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + if st, _ := getTypeStruct(o.Type(), scope); st == nil { + continue + } + if name == "PrivateRR" { + continue + } + + // Check if corresponding TypeX exists + if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { + log.Fatalf("Constant Type%s does not exist.", o.Name()) + } + + namedTypes = append(namedTypes, o.Name()) + } + + b := &bytes.Buffer{} + b.WriteString(packageHdr) + + fmt.Fprint(b, "// pack*() functions\n\n") + for _, name := range namedTypes { + o := scope.Lookup(name) + st, _ := getTypeStruct(o.Type(), scope) + + fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {\n", name) + for i := 1; i < st.NumFields(); i++ { + o := func(s string) { + fmt.Fprintf(b, s, st.Field(i).Name()) + fmt.Fprint(b, `if err != nil { +return off, err +} +`) + } + + if _, ok := st.Field(i).Type().(*types.Slice); ok { + switch st.Tag(i) { + case `dns:"-"`: // ignored + case `dns:"txt"`: + o("off, err = packStringTxt(rr.%s, msg, off)\n") + case `dns:"opt"`: + o("off, err = packDataOpt(rr.%s, msg, off)\n") + case `dns:"nsec"`: + o("off, err = packDataNsec(rr.%s, msg, off)\n") + case `dns:"domain-name"`: + o("off, err = packDataDomainNames(rr.%s, msg, off, compression, false)\n") + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + continue + } + + switch { + case st.Tag(i) == `dns:"-"`: // ignored + case st.Tag(i) == `dns:"cdomain-name"`: + o("off, err = packDomainName(rr.%s, msg, off, compression, compress)\n") + case st.Tag(i) == `dns:"domain-name"`: + o("off, err = packDomainName(rr.%s, msg, off, compression, false)\n") + case st.Tag(i) == `dns:"a"`: + o("off, err = packDataA(rr.%s, msg, off)\n") + case st.Tag(i) == `dns:"aaaa"`: + o("off, err = packDataAAAA(rr.%s, msg, off)\n") + case st.Tag(i) == `dns:"uint48"`: + o("off, err = packUint48(rr.%s, msg, off)\n") + case st.Tag(i) == `dns:"txt"`: + o("off, err = packString(rr.%s, msg, off)\n") + + case strings.HasPrefix(st.Tag(i), `dns:"size-base32`): // size-base32 can be packed just like base32 + fallthrough + case st.Tag(i) == `dns:"base32"`: + o("off, err = packStringBase32(rr.%s, msg, off)\n") + + case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): // size-base64 can be packed just like base64 + fallthrough + case st.Tag(i) == `dns:"base64"`: + o("off, err = packStringBase64(rr.%s, msg, off)\n") + + case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`): + // directly write instead of using o() so we get the error check in the correct place + field := st.Field(i).Name() + fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty +if rr.%s != "-" { + off, err = packStringHex(rr.%s, msg, off) + if err != nil { + return off, err + } +} +`, field, field) + continue + case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex + fallthrough + case st.Tag(i) == `dns:"hex"`: + o("off, err = packStringHex(rr.%s, msg, off)\n") + case st.Tag(i) == `dns:"any"`: + o("off, err = packStringAny(rr.%s, msg, off)\n") + case st.Tag(i) == `dns:"octet"`: + o("off, err = packStringOctet(rr.%s, msg, off)\n") + case st.Tag(i) == "": + switch st.Field(i).Type().(*types.Basic).Kind() { + case types.Uint8: + o("off, err = packUint8(rr.%s, msg, off)\n") + case types.Uint16: + o("off, err = packUint16(rr.%s, msg, off)\n") + case types.Uint32: + o("off, err = packUint32(rr.%s, msg, off)\n") + case types.Uint64: + o("off, err = packUint64(rr.%s, msg, off)\n") + case types.String: + o("off, err = packString(rr.%s, msg, off)\n") + default: + log.Fatalln(name, st.Field(i).Name()) + } + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + } + fmt.Fprintln(b, "return off, nil }\n") + } + + fmt.Fprint(b, "// unpack*() functions\n\n") + for _, name := range namedTypes { + o := scope.Lookup(name) + st, _ := getTypeStruct(o.Type(), scope) + + fmt.Fprintf(b, "func (rr *%s) unpack(msg []byte, off int) (off1 int, err error) {\n", name) + fmt.Fprint(b, `rdStart := off +_ = rdStart + +`) + for i := 1; i < st.NumFields(); i++ { + o := func(s string) { + fmt.Fprintf(b, s, st.Field(i).Name()) + fmt.Fprint(b, `if err != nil { +return off, err +} +`) + } + + // size-* are special, because they reference a struct member we should use for the length. + if strings.HasPrefix(st.Tag(i), `dns:"size-`) { + structMember := structMember(st.Tag(i)) + structTag := structTag(st.Tag(i)) + switch structTag { + case "hex": + fmt.Fprintf(b, "rr.%s, off, err = unpackStringHex(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) + case "base32": + fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase32(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) + case "base64": + fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase64(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + fmt.Fprint(b, `if err != nil { +return off, err +} +`) + continue + } + + if _, ok := st.Field(i).Type().(*types.Slice); ok { + switch st.Tag(i) { + case `dns:"-"`: // ignored + case `dns:"txt"`: + o("rr.%s, off, err = unpackStringTxt(msg, off)\n") + case `dns:"opt"`: + o("rr.%s, off, err = unpackDataOpt(msg, off)\n") + case `dns:"nsec"`: + o("rr.%s, off, err = unpackDataNsec(msg, off)\n") + case `dns:"domain-name"`: + o("rr.%s, off, err = unpackDataDomainNames(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + continue + } + + switch st.Tag(i) { + case `dns:"-"`: // ignored + case `dns:"cdomain-name"`: + fallthrough + case `dns:"domain-name"`: + o("rr.%s, off, err = UnpackDomainName(msg, off)\n") + case `dns:"a"`: + o("rr.%s, off, err = unpackDataA(msg, off)\n") + case `dns:"aaaa"`: + o("rr.%s, off, err = unpackDataAAAA(msg, off)\n") + case `dns:"uint48"`: + o("rr.%s, off, err = unpackUint48(msg, off)\n") + case `dns:"txt"`: + o("rr.%s, off, err = unpackString(msg, off)\n") + case `dns:"base32"`: + o("rr.%s, off, err = unpackStringBase32(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"base64"`: + o("rr.%s, off, err = unpackStringBase64(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"hex"`: + o("rr.%s, off, err = unpackStringHex(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"any"`: + o("rr.%s, off, err = unpackStringAny(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") + case `dns:"octet"`: + o("rr.%s, off, err = unpackStringOctet(msg, off)\n") + case "": + switch st.Field(i).Type().(*types.Basic).Kind() { + case types.Uint8: + o("rr.%s, off, err = unpackUint8(msg, off)\n") + case types.Uint16: + o("rr.%s, off, err = unpackUint16(msg, off)\n") + case types.Uint32: + o("rr.%s, off, err = unpackUint32(msg, off)\n") + case types.Uint64: + o("rr.%s, off, err = unpackUint64(msg, off)\n") + case types.String: + o("rr.%s, off, err = unpackString(msg, off)\n") + default: + log.Fatalln(name, st.Field(i).Name()) + } + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + // If we've hit len(msg) we return without error. + if i < st.NumFields()-1 { + fmt.Fprintf(b, `if off == len(msg) { +return off, nil + } +`) + } + } + fmt.Fprintf(b, "return off, nil }\n\n") + } + + // gofmt + res, err := format.Source(b.Bytes()) + if err != nil { + b.WriteTo(os.Stderr) + log.Fatal(err) + } + + // write result + f, err := os.Create("zmsg.go") + fatalIfErr(err) + defer f.Close() + f.Write(res) +} + +// structMember will take a tag like dns:"size-base32:SaltLength" and return the last part of this string. +func structMember(s string) string { + fields := strings.Split(s, ":") + if len(fields) == 0 { + return "" + } + f := fields[len(fields)-1] + // f should have a closing " + if len(f) > 1 { + return f[:len(f)-1] + } + return f +} + +// structTag will take a tag like dns:"size-base32:SaltLength" and return base32. +func structTag(s string) string { + fields := strings.Split(s, ":") + if len(fields) < 2 { + return "" + } + return fields[1][len("\"size-"):] +} + +func fatalIfErr(err error) { + if err != nil { + log.Fatal(err) + } +} diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go new file mode 100644 index 00000000..cb4ae764 --- /dev/null +++ b/vendor/github.com/miekg/dns/msg_helpers.go @@ -0,0 +1,671 @@ +package dns + +import ( + "encoding/base32" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "net" + "strings" +) + +// helper functions called from the generated zmsg.go + +// These function are named after the tag to help pack/unpack, if there is no tag it is the name +// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or +// packDataDomainName. + +func unpackDataA(msg []byte, off int) (net.IP, int, error) { + if off+net.IPv4len > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking a"} + } + a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...) + off += net.IPv4len + return a, off, nil +} + +func packDataA(a net.IP, msg []byte, off int) (int, error) { + switch len(a) { + case net.IPv4len, net.IPv6len: + // It must be a slice of 4, even if it is 16, we encode only the first 4 + if off+net.IPv4len > len(msg) { + return len(msg), &Error{err: "overflow packing a"} + } + + copy(msg[off:], a.To4()) + off += net.IPv4len + case 0: + // Allowed, for dynamic updates. + default: + return len(msg), &Error{err: "overflow packing a"} + } + return off, nil +} + +func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) { + if off+net.IPv6len > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking aaaa"} + } + aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...) + off += net.IPv6len + return aaaa, off, nil +} + +func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) { + switch len(aaaa) { + case net.IPv6len: + if off+net.IPv6len > len(msg) { + return len(msg), &Error{err: "overflow packing aaaa"} + } + + copy(msg[off:], aaaa) + off += net.IPv6len + case 0: + // Allowed, dynamic updates. + default: + return len(msg), &Error{err: "overflow packing aaaa"} + } + return off, nil +} + +// unpackHeader unpacks an RR header, returning the offset to the end of the header and a +// re-sliced msg according to the expected length of the RR. +func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) { + hdr := RR_Header{} + if off == len(msg) { + return hdr, off, msg, nil + } + + hdr.Name, off, err = UnpackDomainName(msg, off) + if err != nil { + return hdr, len(msg), msg, err + } + hdr.Rrtype, off, err = unpackUint16(msg, off) + if err != nil { + return hdr, len(msg), msg, err + } + hdr.Class, off, err = unpackUint16(msg, off) + if err != nil { + return hdr, len(msg), msg, err + } + hdr.Ttl, off, err = unpackUint32(msg, off) + if err != nil { + return hdr, len(msg), msg, err + } + hdr.Rdlength, off, err = unpackUint16(msg, off) + if err != nil { + return hdr, len(msg), msg, err + } + msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength) + return hdr, off, msg, err +} + +// packHeader packs an RR header, returning the offset to the end of the header. +// See PackDomainName for documentation about the compression. +func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) { + if off == len(msg) { + return off, nil + } + + off, err := packDomainName(hdr.Name, msg, off, compression, compress) + if err != nil { + return len(msg), err + } + off, err = packUint16(hdr.Rrtype, msg, off) + if err != nil { + return len(msg), err + } + off, err = packUint16(hdr.Class, msg, off) + if err != nil { + return len(msg), err + } + off, err = packUint32(hdr.Ttl, msg, off) + if err != nil { + return len(msg), err + } + off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR. + if err != nil { + return len(msg), err + } + return off, nil +} + +// helper helper functions. + +// truncateMsgFromRdLength truncates msg to match the expected length of the RR. +// Returns an error if msg is smaller than the expected size. +func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) { + lenrd := off + int(rdlength) + if lenrd > len(msg) { + return msg, &Error{err: "overflowing header size"} + } + return msg[:lenrd], nil +} + +var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding) + +func fromBase32(s []byte) (buf []byte, err error) { + for i, b := range s { + if b >= 'a' && b <= 'z' { + s[i] = b - 32 + } + } + buflen := base32HexNoPadEncoding.DecodedLen(len(s)) + buf = make([]byte, buflen) + n, err := base32HexNoPadEncoding.Decode(buf, s) + buf = buf[:n] + return +} + +func toBase32(b []byte) string { + return base32HexNoPadEncoding.EncodeToString(b) +} + +func fromBase64(s []byte) (buf []byte, err error) { + buflen := base64.StdEncoding.DecodedLen(len(s)) + buf = make([]byte, buflen) + n, err := base64.StdEncoding.Decode(buf, s) + buf = buf[:n] + return +} + +func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } + +// dynamicUpdate returns true if the Rdlength is zero. +func noRdata(h RR_Header) bool { return h.Rdlength == 0 } + +func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) { + if off+1 > len(msg) { + return 0, len(msg), &Error{err: "overflow unpacking uint8"} + } + return msg[off], off + 1, nil +} + +func packUint8(i uint8, msg []byte, off int) (off1 int, err error) { + if off+1 > len(msg) { + return len(msg), &Error{err: "overflow packing uint8"} + } + msg[off] = i + return off + 1, nil +} + +func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) { + if off+2 > len(msg) { + return 0, len(msg), &Error{err: "overflow unpacking uint16"} + } + return binary.BigEndian.Uint16(msg[off:]), off + 2, nil +} + +func packUint16(i uint16, msg []byte, off int) (off1 int, err error) { + if off+2 > len(msg) { + return len(msg), &Error{err: "overflow packing uint16"} + } + binary.BigEndian.PutUint16(msg[off:], i) + return off + 2, nil +} + +func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) { + if off+4 > len(msg) { + return 0, len(msg), &Error{err: "overflow unpacking uint32"} + } + return binary.BigEndian.Uint32(msg[off:]), off + 4, nil +} + +func packUint32(i uint32, msg []byte, off int) (off1 int, err error) { + if off+4 > len(msg) { + return len(msg), &Error{err: "overflow packing uint32"} + } + binary.BigEndian.PutUint32(msg[off:], i) + return off + 4, nil +} + +func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) { + if off+6 > len(msg) { + return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"} + } + // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes) + i = uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 | + uint64(msg[off+4])<<8 | uint64(msg[off+5]) + off += 6 + return i, off, nil +} + +func packUint48(i uint64, msg []byte, off int) (off1 int, err error) { + if off+6 > len(msg) { + return len(msg), &Error{err: "overflow packing uint64 as uint48"} + } + msg[off] = byte(i >> 40) + msg[off+1] = byte(i >> 32) + msg[off+2] = byte(i >> 24) + msg[off+3] = byte(i >> 16) + msg[off+4] = byte(i >> 8) + msg[off+5] = byte(i) + off += 6 + return off, nil +} + +func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) { + if off+8 > len(msg) { + return 0, len(msg), &Error{err: "overflow unpacking uint64"} + } + return binary.BigEndian.Uint64(msg[off:]), off + 8, nil +} + +func packUint64(i uint64, msg []byte, off int) (off1 int, err error) { + if off+8 > len(msg) { + return len(msg), &Error{err: "overflow packing uint64"} + } + binary.BigEndian.PutUint64(msg[off:], i) + off += 8 + return off, nil +} + +func unpackString(msg []byte, off int) (string, int, error) { + if off+1 > len(msg) { + return "", off, &Error{err: "overflow unpacking txt"} + } + l := int(msg[off]) + if off+l+1 > len(msg) { + return "", off, &Error{err: "overflow unpacking txt"} + } + var s strings.Builder + s.Grow(l) + for _, b := range msg[off+1 : off+1+l] { + switch { + case b == '"' || b == '\\': + s.WriteByte('\\') + s.WriteByte(b) + case b < ' ' || b > '~': // unprintable + s.WriteString(escapeByte(b)) + default: + s.WriteByte(b) + } + } + off += 1 + l + return s.String(), off, nil +} + +func packString(s string, msg []byte, off int) (int, error) { + txtTmp := make([]byte, 256*4+1) + off, err := packTxtString(s, msg, off, txtTmp) + if err != nil { + return len(msg), err + } + return off, nil +} + +func unpackStringBase32(msg []byte, off, end int) (string, int, error) { + if end > len(msg) { + return "", len(msg), &Error{err: "overflow unpacking base32"} + } + s := toBase32(msg[off:end]) + return s, end, nil +} + +func packStringBase32(s string, msg []byte, off int) (int, error) { + b32, err := fromBase32([]byte(s)) + if err != nil { + return len(msg), err + } + if off+len(b32) > len(msg) { + return len(msg), &Error{err: "overflow packing base32"} + } + copy(msg[off:off+len(b32)], b32) + off += len(b32) + return off, nil +} + +func unpackStringBase64(msg []byte, off, end int) (string, int, error) { + // Rest of the RR is base64 encoded value, so we don't need an explicit length + // to be set. Thus far all RR's that have base64 encoded fields have those as their + // last one. What we do need is the end of the RR! + if end > len(msg) { + return "", len(msg), &Error{err: "overflow unpacking base64"} + } + s := toBase64(msg[off:end]) + return s, end, nil +} + +func packStringBase64(s string, msg []byte, off int) (int, error) { + b64, err := fromBase64([]byte(s)) + if err != nil { + return len(msg), err + } + if off+len(b64) > len(msg) { + return len(msg), &Error{err: "overflow packing base64"} + } + copy(msg[off:off+len(b64)], b64) + off += len(b64) + return off, nil +} + +func unpackStringHex(msg []byte, off, end int) (string, int, error) { + // Rest of the RR is hex encoded value, so we don't need an explicit length + // to be set. NSEC and TSIG have hex fields with a length field. + // What we do need is the end of the RR! + if end > len(msg) { + return "", len(msg), &Error{err: "overflow unpacking hex"} + } + + s := hex.EncodeToString(msg[off:end]) + return s, end, nil +} + +func packStringHex(s string, msg []byte, off int) (int, error) { + h, err := hex.DecodeString(s) + if err != nil { + return len(msg), err + } + if off+len(h) > len(msg) { + return len(msg), &Error{err: "overflow packing hex"} + } + copy(msg[off:off+len(h)], h) + off += len(h) + return off, nil +} + +func unpackStringAny(msg []byte, off, end int) (string, int, error) { + if end > len(msg) { + return "", len(msg), &Error{err: "overflow unpacking anything"} + } + return string(msg[off:end]), end, nil +} + +func packStringAny(s string, msg []byte, off int) (int, error) { + if off+len(s) > len(msg) { + return len(msg), &Error{err: "overflow packing anything"} + } + copy(msg[off:off+len(s)], s) + off += len(s) + return off, nil +} + +func unpackStringTxt(msg []byte, off int) ([]string, int, error) { + txt, off, err := unpackTxt(msg, off) + if err != nil { + return nil, len(msg), err + } + return txt, off, nil +} + +func packStringTxt(s []string, msg []byte, off int) (int, error) { + txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many. + off, err := packTxt(s, msg, off, txtTmp) + if err != nil { + return len(msg), err + } + return off, nil +} + +func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { + var edns []EDNS0 +Option: + var code uint16 + if off+4 > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking opt"} + } + code = binary.BigEndian.Uint16(msg[off:]) + off += 2 + optlen := binary.BigEndian.Uint16(msg[off:]) + off += 2 + if off+int(optlen) > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking opt"} + } + switch code { + case EDNS0NSID: + e := new(EDNS0_NSID) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0SUBNET: + e := new(EDNS0_SUBNET) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0COOKIE: + e := new(EDNS0_COOKIE) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0UL: + e := new(EDNS0_UL) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0LLQ: + e := new(EDNS0_LLQ) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0DAU: + e := new(EDNS0_DAU) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0DHU: + e := new(EDNS0_DHU) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0N3U: + e := new(EDNS0_N3U) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + case EDNS0PADDING: + e := new(EDNS0_PADDING) + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + default: + e := new(EDNS0_LOCAL) + e.Code = code + if err := e.unpack(msg[off : off+int(optlen)]); err != nil { + return nil, len(msg), err + } + edns = append(edns, e) + off += int(optlen) + } + + if off < len(msg) { + goto Option + } + + return edns, off, nil +} + +func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { + for _, el := range options { + b, err := el.pack() + if err != nil || off+4 > len(msg) { + return len(msg), &Error{err: "overflow packing opt"} + } + binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code + binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length + off += 4 + if off+len(b) > len(msg) { + copy(msg[off:], b) + off = len(msg) + continue + } + // Actual data + copy(msg[off:off+len(b)], b) + off += len(b) + } + return off, nil +} + +func unpackStringOctet(msg []byte, off int) (string, int, error) { + s := string(msg[off:]) + return s, len(msg), nil +} + +func packStringOctet(s string, msg []byte, off int) (int, error) { + txtTmp := make([]byte, 256*4+1) + off, err := packOctetString(s, msg, off, txtTmp) + if err != nil { + return len(msg), err + } + return off, nil +} + +func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { + var nsec []uint16 + length, window, lastwindow := 0, 0, -1 + for off < len(msg) { + if off+2 > len(msg) { + return nsec, len(msg), &Error{err: "overflow unpacking nsecx"} + } + window = int(msg[off]) + length = int(msg[off+1]) + off += 2 + if window <= lastwindow { + // RFC 4034: Blocks are present in the NSEC RR RDATA in + // increasing numerical order. + return nsec, len(msg), &Error{err: "out of order NSEC block"} + } + if length == 0 { + // RFC 4034: Blocks with no types present MUST NOT be included. + return nsec, len(msg), &Error{err: "empty NSEC block"} + } + if length > 32 { + return nsec, len(msg), &Error{err: "NSEC block too long"} + } + if off+length > len(msg) { + return nsec, len(msg), &Error{err: "overflowing NSEC block"} + } + + // Walk the bytes in the window and extract the type bits + for j, b := range msg[off : off+length] { + // Check the bits one by one, and set the type + if b&0x80 == 0x80 { + nsec = append(nsec, uint16(window*256+j*8+0)) + } + if b&0x40 == 0x40 { + nsec = append(nsec, uint16(window*256+j*8+1)) + } + if b&0x20 == 0x20 { + nsec = append(nsec, uint16(window*256+j*8+2)) + } + if b&0x10 == 0x10 { + nsec = append(nsec, uint16(window*256+j*8+3)) + } + if b&0x8 == 0x8 { + nsec = append(nsec, uint16(window*256+j*8+4)) + } + if b&0x4 == 0x4 { + nsec = append(nsec, uint16(window*256+j*8+5)) + } + if b&0x2 == 0x2 { + nsec = append(nsec, uint16(window*256+j*8+6)) + } + if b&0x1 == 0x1 { + nsec = append(nsec, uint16(window*256+j*8+7)) + } + } + off += length + lastwindow = window + } + return nsec, off, nil +} + +// typeBitMapLen is a helper function which computes the "maximum" length of +// a the NSEC Type BitMap field. +func typeBitMapLen(bitmap []uint16) int { + var l int + var lastwindow, lastlength uint16 + for _, t := range bitmap { + window := t / 256 + length := (t-window*256)/8 + 1 + if window > lastwindow && lastlength != 0 { // New window, jump to the new offset + l += int(lastlength) + 2 + lastlength = 0 + } + if window < lastwindow || length < lastlength { + // packDataNsec would return Error{err: "nsec bits out of order"} here, but + // when computing the length, we want do be liberal. + continue + } + lastwindow, lastlength = window, length + } + l += int(lastlength) + 2 + return l +} + +func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { + if len(bitmap) == 0 { + return off, nil + } + var lastwindow, lastlength uint16 + for _, t := range bitmap { + window := t / 256 + length := (t-window*256)/8 + 1 + if window > lastwindow && lastlength != 0 { // New window, jump to the new offset + off += int(lastlength) + 2 + lastlength = 0 + } + if window < lastwindow || length < lastlength { + return len(msg), &Error{err: "nsec bits out of order"} + } + if off+2+int(length) > len(msg) { + return len(msg), &Error{err: "overflow packing nsec"} + } + // Setting the window # + msg[off] = byte(window) + // Setting the octets length + msg[off+1] = byte(length) + // Setting the bit value for the type in the right octet + msg[off+1+int(length)] |= byte(1 << (7 - t%8)) + lastwindow, lastlength = window, length + } + off += int(lastlength) + 2 + return off, nil +} + +func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { + var ( + servers []string + s string + err error + ) + if end > len(msg) { + return nil, len(msg), &Error{err: "overflow unpacking domain names"} + } + for off < end { + s, off, err = UnpackDomainName(msg, off) + if err != nil { + return servers, len(msg), err + } + servers = append(servers, s) + } + return servers, off, nil +} + +func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) { + var err error + for _, name := range names { + off, err = packDomainName(name, msg, off, compression, compress) + if err != nil { + return len(msg), err + } + } + return off, nil +} diff --git a/vendor/github.com/miekg/dns/msg_truncate.go b/vendor/github.com/miekg/dns/msg_truncate.go new file mode 100644 index 00000000..83780af6 --- /dev/null +++ b/vendor/github.com/miekg/dns/msg_truncate.go @@ -0,0 +1,106 @@ +package dns + +// Truncate ensures the reply message will fit into the requested buffer +// size by removing records that exceed the requested size. +// +// It will first check if the reply fits without compression and then with +// compression. If it won't fit with compression, Truncate then walks the +// record adding as many records as possible without exceeding the +// requested buffer size. +// +// The TC bit will be set if any answer records were excluded from the +// message. This indicates to that the client should retry over TCP. +// +// The appropriate buffer size can be retrieved from the requests OPT +// record, if present, and is transport specific otherwise. dns.MinMsgSize +// should be used for UDP requests without an OPT record, and +// dns.MaxMsgSize for TCP requests without an OPT record. +func (dns *Msg) Truncate(size int) { + if dns.IsTsig() != nil { + // To simplify this implementation, we don't perform + // truncation on responses with a TSIG record. + return + } + + // RFC 6891 mandates that the payload size in an OPT record + // less than 512 bytes must be treated as equal to 512 bytes. + // + // For ease of use, we impose that restriction here. + if size < 512 { + size = 512 + } + + l := msgLenWithCompressionMap(dns, nil) // uncompressed length + if l <= size { + // Don't waste effort compressing this message. + dns.Compress = false + return + } + + dns.Compress = true + + edns0 := dns.popEdns0() + if edns0 != nil { + // Account for the OPT record that gets added at the end, + // by subtracting that length from our budget. + // + // The EDNS(0) OPT record must have the root domain and + // it's length is thus unaffected by compression. + size -= Len(edns0) + } + + compression := make(map[string]struct{}) + + l = headerSize + for _, r := range dns.Question { + l += r.len(l, compression) + } + + var numAnswer int + if l < size { + l, numAnswer = truncateLoop(dns.Answer, size, l, compression) + } + + var numNS int + if l < size { + l, numNS = truncateLoop(dns.Ns, size, l, compression) + } + + var numExtra int + if l < size { + l, numExtra = truncateLoop(dns.Extra, size, l, compression) + } + + // According to RFC 2181, the TC bit should only be set if not all + // of the answer RRs can be included in the response. + dns.Truncated = len(dns.Answer) > numAnswer + + dns.Answer = dns.Answer[:numAnswer] + dns.Ns = dns.Ns[:numNS] + dns.Extra = dns.Extra[:numExtra] + + if edns0 != nil { + // Add the OPT record back onto the additional section. + dns.Extra = append(dns.Extra, edns0) + } +} + +func truncateLoop(rrs []RR, size, l int, compression map[string]struct{}) (int, int) { + for i, r := range rrs { + if r == nil { + continue + } + + l += r.len(l, compression) + if l > size { + // Return size, rather than l prior to this record, + // to prevent any further records being added. + return size, i + } + if l == size { + return l, i + 1 + } + } + + return l, len(rrs) +} diff --git a/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/miekg/dns/nsecx.go new file mode 100644 index 00000000..8f071a47 --- /dev/null +++ b/vendor/github.com/miekg/dns/nsecx.go @@ -0,0 +1,95 @@ +package dns + +import ( + "crypto/sha1" + "encoding/hex" + "strings" +) + +// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase. +func HashName(label string, ha uint8, iter uint16, salt string) string { + if ha != SHA1 { + return "" + } + + wireSalt := make([]byte, hex.DecodedLen(len(salt))) + n, err := packStringHex(salt, wireSalt, 0) + if err != nil { + return "" + } + wireSalt = wireSalt[:n] + + name := make([]byte, 255) + off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false) + if err != nil { + return "" + } + name = name[:off] + + s := sha1.New() + // k = 0 + s.Write(name) + s.Write(wireSalt) + nsec3 := s.Sum(nil) + + // k > 0 + for k := uint16(0); k < iter; k++ { + s.Reset() + s.Write(nsec3) + s.Write(wireSalt) + nsec3 = s.Sum(nsec3[:0]) + } + + return toBase32(nsec3) +} + +// Cover returns true if a name is covered by the NSEC3 record +func (rr *NSEC3) Cover(name string) bool { + nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) + owner := strings.ToUpper(rr.Hdr.Name) + labelIndices := Split(owner) + if len(labelIndices) < 2 { + return false + } + ownerHash := owner[:labelIndices[1]-1] + ownerZone := owner[labelIndices[1]:] + if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone + return false + } + + nextHash := rr.NextDomain + + // if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash + if ownerHash == nextHash && nameHash != ownerHash { // empty interval + return true + } + if ownerHash > nextHash { // end of zone + if nameHash > ownerHash { // covered since there is nothing after ownerHash + return true + } + return nameHash < nextHash // if nameHash is before beginning of zone it is covered + } + if nameHash < ownerHash { // nameHash is before ownerHash, not covered + return false + } + return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash) +} + +// Match returns true if a name matches the NSEC3 record +func (rr *NSEC3) Match(name string) bool { + nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) + owner := strings.ToUpper(rr.Hdr.Name) + labelIndices := Split(owner) + if len(labelIndices) < 2 { + return false + } + ownerHash := owner[:labelIndices[1]-1] + ownerZone := owner[labelIndices[1]:] + if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone + return false + } + if ownerHash == nameHash { + return true + } + return false +} diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go new file mode 100644 index 00000000..e28f0663 --- /dev/null +++ b/vendor/github.com/miekg/dns/privaterr.go @@ -0,0 +1,114 @@ +package dns + +import "strings" + +// PrivateRdata is an interface used for implementing "Private Use" RR types, see +// RFC 6895. This allows one to experiment with new RR types, without requesting an +// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove. +type PrivateRdata interface { + // String returns the text presentaton of the Rdata of the Private RR. + String() string + // Parse parses the Rdata of the private RR. + Parse([]string) error + // Pack is used when packing a private RR into a buffer. + Pack([]byte) (int, error) + // Unpack is used when unpacking a private RR from a buffer. + // TODO(miek): diff. signature than Pack, see edns0.go for instance. + Unpack([]byte) (int, error) + // Copy copies the Rdata into the PrivateRdata argument. + Copy(PrivateRdata) error + // Len returns the length in octets of the Rdata. + Len() int +} + +// PrivateRR represents an RR that uses a PrivateRdata user-defined type. +// It mocks normal RRs and implements dns.RR interface. +type PrivateRR struct { + Hdr RR_Header + Data PrivateRdata + + generator func() PrivateRdata // for copy +} + +// Header return the RR header of r. +func (r *PrivateRR) Header() *RR_Header { return &r.Hdr } + +func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() } + +// Private len and copy parts to satisfy RR interface. +func (r *PrivateRR) len(off int, compression map[string]struct{}) int { + l := r.Hdr.len(off, compression) + l += r.Data.Len() + return l +} + +func (r *PrivateRR) copy() RR { + // make new RR like this: + rr := &PrivateRR{r.Hdr, r.generator(), r.generator} + + if err := r.Data.Copy(rr.Data); err != nil { + panic("dns: got value that could not be used to copy Private rdata: " + err.Error()) + } + + return rr +} + +func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { + n, err := r.Data.Pack(msg[off:]) + if err != nil { + return len(msg), err + } + off += n + return off, nil +} + +func (r *PrivateRR) unpack(msg []byte, off int) (int, error) { + off1, err := r.Data.Unpack(msg[off:]) + off += off1 + return off, err +} + +func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError { + var l lex + text := make([]string, 0, 2) // could be 0..N elements, median is probably 1 +Fetch: + for { + // TODO(miek): we could also be returning _QUOTE, this might or might not + // be an issue (basically parsing TXT becomes hard) + switch l, _ = c.Next(); l.value { + case zNewline, zEOF: + break Fetch + case zString: + text = append(text, l.token) + } + } + + err := r.Data.Parse(text) + if err != nil { + return &ParseError{"", err.Error(), l} + } + + return nil +} + +func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false } + +// PrivateHandle registers a private resource record type. It requires +// string and numeric representation of private RR type and generator function as argument. +func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) { + rtypestr = strings.ToUpper(rtypestr) + + TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} } + TypeToString[rtype] = rtypestr + StringToType[rtypestr] = rtype +} + +// PrivateHandleRemove removes definitions required to support private RR type. +func PrivateHandleRemove(rtype uint16) { + rtypestr, ok := TypeToString[rtype] + if ok { + delete(TypeToRR, rtype) + delete(TypeToString, rtype) + delete(StringToType, rtypestr) + } +} diff --git a/vendor/github.com/miekg/dns/reverse.go b/vendor/github.com/miekg/dns/reverse.go new file mode 100644 index 00000000..28151af8 --- /dev/null +++ b/vendor/github.com/miekg/dns/reverse.go @@ -0,0 +1,52 @@ +package dns + +// StringToType is the reverse of TypeToString, needed for string parsing. +var StringToType = reverseInt16(TypeToString) + +// StringToClass is the reverse of ClassToString, needed for string parsing. +var StringToClass = reverseInt16(ClassToString) + +// StringToOpcode is a map of opcodes to strings. +var StringToOpcode = reverseInt(OpcodeToString) + +// StringToRcode is a map of rcodes to strings. +var StringToRcode = reverseInt(RcodeToString) + +func init() { + // Preserve previous NOTIMP typo, see github.com/miekg/dns/issues/733. + StringToRcode["NOTIMPL"] = RcodeNotImplemented +} + +// StringToAlgorithm is the reverse of AlgorithmToString. +var StringToAlgorithm = reverseInt8(AlgorithmToString) + +// StringToHash is a map of names to hash IDs. +var StringToHash = reverseInt8(HashToString) + +// StringToCertType is the reverseof CertTypeToString. +var StringToCertType = reverseInt16(CertTypeToString) + +// Reverse a map +func reverseInt8(m map[uint8]string) map[string]uint8 { + n := make(map[string]uint8, len(m)) + for u, s := range m { + n[s] = u + } + return n +} + +func reverseInt16(m map[uint16]string) map[string]uint16 { + n := make(map[string]uint16, len(m)) + for u, s := range m { + n[s] = u + } + return n +} + +func reverseInt(m map[int]string) map[string]int { + n := make(map[string]int, len(m)) + for u, s := range m { + n[s] = u + } + return n +} diff --git a/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/miekg/dns/sanitize.go new file mode 100644 index 00000000..a638e862 --- /dev/null +++ b/vendor/github.com/miekg/dns/sanitize.go @@ -0,0 +1,86 @@ +package dns + +// Dedup removes identical RRs from rrs. It preserves the original ordering. +// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies +// rrs. +// m is used to store the RRs temporary. If it is nil a new map will be allocated. +func Dedup(rrs []RR, m map[string]RR) []RR { + + if m == nil { + m = make(map[string]RR) + } + // Save the keys, so we don't have to call normalizedString twice. + keys := make([]*string, 0, len(rrs)) + + for _, r := range rrs { + key := normalizedString(r) + keys = append(keys, &key) + if mr, ok := m[key]; ok { + // Shortest TTL wins. + rh, mrh := r.Header(), mr.Header() + if mrh.Ttl > rh.Ttl { + mrh.Ttl = rh.Ttl + } + continue + } + + m[key] = r + } + // If the length of the result map equals the amount of RRs we got, + // it means they were all different. We can then just return the original rrset. + if len(m) == len(rrs) { + return rrs + } + + j := 0 + for i, r := range rrs { + // If keys[i] lives in the map, we should copy and remove it. + if _, ok := m[*keys[i]]; ok { + delete(m, *keys[i]) + rrs[j] = r + j++ + } + + if len(m) == 0 { + break + } + } + + return rrs[:j] +} + +// normalizedString returns a normalized string from r. The TTL +// is removed and the domain name is lowercased. We go from this: +// DomainNameTTLCLASSTYPERDATA to: +// lowercasenameCLASSTYPE... +func normalizedString(r RR) string { + // A string Go DNS makes has: domainnameTTL... + b := []byte(r.String()) + + // find the first non-escaped tab, then another, so we capture where the TTL lives. + esc := false + ttlStart, ttlEnd := 0, 0 + for i := 0; i < len(b) && ttlEnd == 0; i++ { + switch { + case b[i] == '\\': + esc = !esc + case b[i] == '\t' && !esc: + if ttlStart == 0 { + ttlStart = i + continue + } + if ttlEnd == 0 { + ttlEnd = i + } + case b[i] >= 'A' && b[i] <= 'Z' && !esc: + b[i] += 32 + default: + esc = false + } + } + + // remove TTL. + copy(b[ttlStart:], b[ttlEnd:]) + cut := ttlEnd - ttlStart + return string(b[:len(b)-cut]) +} diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go new file mode 100644 index 00000000..7da14c88 --- /dev/null +++ b/vendor/github.com/miekg/dns/scan.go @@ -0,0 +1,1397 @@ +package dns + +import ( + "bufio" + "fmt" + "io" + "os" + "path/filepath" + "strconv" + "strings" +) + +const maxTok = 2048 // Largest token we can return. + +// The maximum depth of $INCLUDE directives supported by the +// ZoneParser API. +const maxIncludeDepth = 7 + +// Tokinize a RFC 1035 zone file. The tokenizer will normalize it: +// * Add ownernames if they are left blank; +// * Suppress sequences of spaces; +// * Make each RR fit on one line (_NEWLINE is send as last) +// * Handle comments: ; +// * Handle braces - anywhere. +const ( + // Zonefile + zEOF = iota + zString + zBlank + zQuote + zNewline + zRrtpe + zOwner + zClass + zDirOrigin // $ORIGIN + zDirTTL // $TTL + zDirInclude // $INCLUDE + zDirGenerate // $GENERATE + + // Privatekey file + zValue + zKey + + zExpectOwnerDir // Ownername + zExpectOwnerBl // Whitespace after the ownername + zExpectAny // Expect rrtype, ttl or class + zExpectAnyNoClass // Expect rrtype or ttl + zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS + zExpectAnyNoTTL // Expect rrtype or class + zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL + zExpectRrtype // Expect rrtype + zExpectRrtypeBl // Whitespace BEFORE rrtype + zExpectRdata // The first element of the rdata + zExpectDirTTLBl // Space after directive $TTL + zExpectDirTTL // Directive $TTL + zExpectDirOriginBl // Space after directive $ORIGIN + zExpectDirOrigin // Directive $ORIGIN + zExpectDirIncludeBl // Space after directive $INCLUDE + zExpectDirInclude // Directive $INCLUDE + zExpectDirGenerate // Directive $GENERATE + zExpectDirGenerateBl // Space after directive $GENERATE +) + +// ParseError is a parsing error. It contains the parse error and the location in the io.Reader +// where the error occurred. +type ParseError struct { + file string + err string + lex lex +} + +func (e *ParseError) Error() (s string) { + if e.file != "" { + s = e.file + ": " + } + s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " + + strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column) + return +} + +type lex struct { + token string // text of the token + err bool // when true, token text has lexer error + value uint8 // value: zString, _BLANK, etc. + torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar + line int // line in the file + column int // column in the file +} + +// Token holds the token that are returned when a zone file is parsed. +type Token struct { + // The scanned resource record when error is not nil. + RR + // When an error occurred, this has the error specifics. + Error *ParseError + // A potential comment positioned after the RR and on the same line. + Comment string +} + +// ttlState describes the state necessary to fill in an omitted RR TTL +type ttlState struct { + ttl uint32 // ttl is the current default TTL + isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive +} + +// NewRR reads the RR contained in the string s. Only the first RR is +// returned. If s contains no records, NewRR will return nil with no +// error. +// +// The class defaults to IN and TTL defaults to 3600. The full zone +// file syntax like $TTL, $ORIGIN, etc. is supported. +// +// All fields of the returned RR are set, except RR.Header().Rdlength +// which is set to 0. +func NewRR(s string) (RR, error) { + if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline + return ReadRR(strings.NewReader(s+"\n"), "") + } + return ReadRR(strings.NewReader(s), "") +} + +// ReadRR reads the RR contained in r. +// +// The string file is used in error reporting and to resolve relative +// $INCLUDE directives. +// +// See NewRR for more documentation. +func ReadRR(r io.Reader, file string) (RR, error) { + zp := NewZoneParser(r, ".", file) + zp.SetDefaultTTL(defaultTtl) + zp.SetIncludeAllowed(true) + rr, _ := zp.Next() + return rr, zp.Err() +} + +// ParseZone reads a RFC 1035 style zonefile from r. It returns +// *Tokens on the returned channel, each consisting of either a +// parsed RR and optional comment or a nil RR and an error. The +// channel is closed by ParseZone when the end of r is reached. +// +// The string file is used in error reporting and to resolve relative +// $INCLUDE directives. The string origin is used as the initial +// origin, as if the file would start with an $ORIGIN directive. +// +// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all +// supported. +// +// Basic usage pattern when reading from a string (z) containing the +// zone data: +// +// for x := range dns.ParseZone(strings.NewReader(z), "", "") { +// if x.Error != nil { +// // log.Println(x.Error) +// } else { +// // Do something with x.RR +// } +// } +// +// Comments specified after an RR (and on the same line!) are +// returned too: +// +// foo. IN A 10.0.0.1 ; this is a comment +// +// The text "; this is comment" is returned in Token.Comment. +// Comments inside the RR are returned concatenated along with the +// RR. Comments on a line by themselves are discarded. +// +// To prevent memory leaks it is important to always fully drain the +// returned channel. If an error occurs, it will always be the last +// Token sent on the channel. +// +// Deprecated: New users should prefer the ZoneParser API. +func ParseZone(r io.Reader, origin, file string) chan *Token { + t := make(chan *Token, 10000) + go parseZone(r, origin, file, t) + return t +} + +func parseZone(r io.Reader, origin, file string, t chan *Token) { + defer close(t) + + zp := NewZoneParser(r, origin, file) + zp.SetIncludeAllowed(true) + + for rr, ok := zp.Next(); ok; rr, ok = zp.Next() { + t <- &Token{RR: rr, Comment: zp.Comment()} + } + + if err := zp.Err(); err != nil { + pe, ok := err.(*ParseError) + if !ok { + pe = &ParseError{file: file, err: err.Error()} + } + + t <- &Token{Error: pe} + } +} + +// ZoneParser is a parser for an RFC 1035 style zonefile. +// +// Each parsed RR in the zone is returned sequentially from Next. An +// optional comment can be retrieved with Comment. +// +// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all +// supported. Although $INCLUDE is disabled by default. +// +// Basic usage pattern when reading from a string (z) containing the +// zone data: +// +// zp := NewZoneParser(strings.NewReader(z), "", "") +// +// for rr, ok := zp.Next(); ok; rr, ok = zp.Next() { +// // Do something with rr +// } +// +// if err := zp.Err(); err != nil { +// // log.Println(err) +// } +// +// Comments specified after an RR (and on the same line!) are +// returned too: +// +// foo. IN A 10.0.0.1 ; this is a comment +// +// The text "; this is comment" is returned from Comment. Comments inside +// the RR are returned concatenated along with the RR. Comments on a line +// by themselves are discarded. +type ZoneParser struct { + c *zlexer + + parseErr *ParseError + + origin string + file string + + defttl *ttlState + + h RR_Header + + // sub is used to parse $INCLUDE files and $GENERATE directives. + // Next, by calling subNext, forwards the resulting RRs from this + // sub parser to the calling code. + sub *ZoneParser + osFile *os.File + + includeDepth uint8 + + includeAllowed bool +} + +// NewZoneParser returns an RFC 1035 style zonefile parser that reads +// from r. +// +// The string file is used in error reporting and to resolve relative +// $INCLUDE directives. The string origin is used as the initial +// origin, as if the file would start with an $ORIGIN directive. +func NewZoneParser(r io.Reader, origin, file string) *ZoneParser { + var pe *ParseError + if origin != "" { + origin = Fqdn(origin) + if _, ok := IsDomainName(origin); !ok { + pe = &ParseError{file, "bad initial origin name", lex{}} + } + } + + return &ZoneParser{ + c: newZLexer(r), + + parseErr: pe, + + origin: origin, + file: file, + } +} + +// SetDefaultTTL sets the parsers default TTL to ttl. +func (zp *ZoneParser) SetDefaultTTL(ttl uint32) { + zp.defttl = &ttlState{ttl, false} +} + +// SetIncludeAllowed controls whether $INCLUDE directives are +// allowed. $INCLUDE directives are not supported by default. +// +// The $INCLUDE directive will open and read from a user controlled +// file on the system. Even if the file is not a valid zonefile, the +// contents of the file may be revealed in error messages, such as: +// +// /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31 +// /etc/shadow: dns: not a TTL: "root:$6$::0:99999:7:::" at line: 1:125 +func (zp *ZoneParser) SetIncludeAllowed(v bool) { + zp.includeAllowed = v +} + +// Err returns the first non-EOF error that was encountered by the +// ZoneParser. +func (zp *ZoneParser) Err() error { + if zp.parseErr != nil { + return zp.parseErr + } + + if zp.sub != nil { + if err := zp.sub.Err(); err != nil { + return err + } + } + + return zp.c.Err() +} + +func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) { + zp.parseErr = &ParseError{zp.file, err, l} + return nil, false +} + +// Comment returns an optional text comment that occurred alongside +// the RR. +func (zp *ZoneParser) Comment() string { + if zp.parseErr != nil { + return "" + } + + if zp.sub != nil { + return zp.sub.Comment() + } + + return zp.c.Comment() +} + +func (zp *ZoneParser) subNext() (RR, bool) { + if rr, ok := zp.sub.Next(); ok { + return rr, true + } + + if zp.sub.osFile != nil { + zp.sub.osFile.Close() + zp.sub.osFile = nil + } + + if zp.sub.Err() != nil { + // We have errors to surface. + return nil, false + } + + zp.sub = nil + return zp.Next() +} + +// Next advances the parser to the next RR in the zonefile and +// returns the (RR, true). It will return (nil, false) when the +// parsing stops, either by reaching the end of the input or an +// error. After Next returns (nil, false), the Err method will return +// any error that occurred during parsing. +func (zp *ZoneParser) Next() (RR, bool) { + if zp.parseErr != nil { + return nil, false + } + if zp.sub != nil { + return zp.subNext() + } + + // 6 possible beginnings of a line (_ is a space): + // + // 0. zRRTYPE -> all omitted until the rrtype + // 1. zOwner _ zRrtype -> class/ttl omitted + // 2. zOwner _ zString _ zRrtype -> class omitted + // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class + // 4. zOwner _ zClass _ zRrtype -> ttl omitted + // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed) + // + // After detecting these, we know the zRrtype so we can jump to functions + // handling the rdata for each of these types. + + st := zExpectOwnerDir // initial state + h := &zp.h + + for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() { + // zlexer spotted an error already + if l.err { + return zp.setParseError(l.token, l) + } + + switch st { + case zExpectOwnerDir: + // We can also expect a directive, like $TTL or $ORIGIN + if zp.defttl != nil { + h.Ttl = zp.defttl.ttl + } + + h.Class = ClassINET + + switch l.value { + case zNewline: + st = zExpectOwnerDir + case zOwner: + name, ok := toAbsoluteName(l.token, zp.origin) + if !ok { + return zp.setParseError("bad owner name", l) + } + + h.Name = name + + st = zExpectOwnerBl + case zDirTTL: + st = zExpectDirTTLBl + case zDirOrigin: + st = zExpectDirOriginBl + case zDirInclude: + st = zExpectDirIncludeBl + case zDirGenerate: + st = zExpectDirGenerateBl + case zRrtpe: + h.Rrtype = l.torc + + st = zExpectRdata + case zClass: + h.Class = l.torc + + st = zExpectAnyNoClassBl + case zBlank: + // Discard, can happen when there is nothing on the + // line except the RR type + case zString: + ttl, ok := stringToTTL(l.token) + if !ok { + return zp.setParseError("not a TTL", l) + } + + h.Ttl = ttl + + if zp.defttl == nil || !zp.defttl.isByDirective { + zp.defttl = &ttlState{ttl, false} + } + + st = zExpectAnyNoTTLBl + default: + return zp.setParseError("syntax error at beginning", l) + } + case zExpectDirIncludeBl: + if l.value != zBlank { + return zp.setParseError("no blank after $INCLUDE-directive", l) + } + + st = zExpectDirInclude + case zExpectDirInclude: + if l.value != zString { + return zp.setParseError("expecting $INCLUDE value, not this...", l) + } + + neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one + switch l, _ := zp.c.Next(); l.value { + case zBlank: + l, _ := zp.c.Next() + if l.value == zString { + name, ok := toAbsoluteName(l.token, zp.origin) + if !ok { + return zp.setParseError("bad origin name", l) + } + + neworigin = name + } + case zNewline, zEOF: + // Ok + default: + return zp.setParseError("garbage after $INCLUDE", l) + } + + if !zp.includeAllowed { + return zp.setParseError("$INCLUDE directive not allowed", l) + } + if zp.includeDepth >= maxIncludeDepth { + return zp.setParseError("too deeply nested $INCLUDE", l) + } + + // Start with the new file + includePath := l.token + if !filepath.IsAbs(includePath) { + includePath = filepath.Join(filepath.Dir(zp.file), includePath) + } + + r1, e1 := os.Open(includePath) + if e1 != nil { + var as string + if !filepath.IsAbs(l.token) { + as = fmt.Sprintf(" as `%s'", includePath) + } + + msg := fmt.Sprintf("failed to open `%s'%s: %v", l.token, as, e1) + return zp.setParseError(msg, l) + } + + zp.sub = NewZoneParser(r1, neworigin, includePath) + zp.sub.defttl, zp.sub.includeDepth, zp.sub.osFile = zp.defttl, zp.includeDepth+1, r1 + zp.sub.SetIncludeAllowed(true) + return zp.subNext() + case zExpectDirTTLBl: + if l.value != zBlank { + return zp.setParseError("no blank after $TTL-directive", l) + } + + st = zExpectDirTTL + case zExpectDirTTL: + if l.value != zString { + return zp.setParseError("expecting $TTL value, not this...", l) + } + + if err := slurpRemainder(zp.c); err != nil { + return zp.setParseError(err.err, err.lex) + } + + ttl, ok := stringToTTL(l.token) + if !ok { + return zp.setParseError("expecting $TTL value, not this...", l) + } + + zp.defttl = &ttlState{ttl, true} + + st = zExpectOwnerDir + case zExpectDirOriginBl: + if l.value != zBlank { + return zp.setParseError("no blank after $ORIGIN-directive", l) + } + + st = zExpectDirOrigin + case zExpectDirOrigin: + if l.value != zString { + return zp.setParseError("expecting $ORIGIN value, not this...", l) + } + + if err := slurpRemainder(zp.c); err != nil { + return zp.setParseError(err.err, err.lex) + } + + name, ok := toAbsoluteName(l.token, zp.origin) + if !ok { + return zp.setParseError("bad origin name", l) + } + + zp.origin = name + + st = zExpectOwnerDir + case zExpectDirGenerateBl: + if l.value != zBlank { + return zp.setParseError("no blank after $GENERATE-directive", l) + } + + st = zExpectDirGenerate + case zExpectDirGenerate: + if l.value != zString { + return zp.setParseError("expecting $GENERATE value, not this...", l) + } + + return zp.generate(l) + case zExpectOwnerBl: + if l.value != zBlank { + return zp.setParseError("no blank after owner", l) + } + + st = zExpectAny + case zExpectAny: + switch l.value { + case zRrtpe: + if zp.defttl == nil { + return zp.setParseError("missing TTL with no previous value", l) + } + + h.Rrtype = l.torc + + st = zExpectRdata + case zClass: + h.Class = l.torc + + st = zExpectAnyNoClassBl + case zString: + ttl, ok := stringToTTL(l.token) + if !ok { + return zp.setParseError("not a TTL", l) + } + + h.Ttl = ttl + + if zp.defttl == nil || !zp.defttl.isByDirective { + zp.defttl = &ttlState{ttl, false} + } + + st = zExpectAnyNoTTLBl + default: + return zp.setParseError("expecting RR type, TTL or class, not this...", l) + } + case zExpectAnyNoClassBl: + if l.value != zBlank { + return zp.setParseError("no blank before class", l) + } + + st = zExpectAnyNoClass + case zExpectAnyNoTTLBl: + if l.value != zBlank { + return zp.setParseError("no blank before TTL", l) + } + + st = zExpectAnyNoTTL + case zExpectAnyNoTTL: + switch l.value { + case zClass: + h.Class = l.torc + + st = zExpectRrtypeBl + case zRrtpe: + h.Rrtype = l.torc + + st = zExpectRdata + default: + return zp.setParseError("expecting RR type or class, not this...", l) + } + case zExpectAnyNoClass: + switch l.value { + case zString: + ttl, ok := stringToTTL(l.token) + if !ok { + return zp.setParseError("not a TTL", l) + } + + h.Ttl = ttl + + if zp.defttl == nil || !zp.defttl.isByDirective { + zp.defttl = &ttlState{ttl, false} + } + + st = zExpectRrtypeBl + case zRrtpe: + h.Rrtype = l.torc + + st = zExpectRdata + default: + return zp.setParseError("expecting RR type or TTL, not this...", l) + } + case zExpectRrtypeBl: + if l.value != zBlank { + return zp.setParseError("no blank before RR type", l) + } + + st = zExpectRrtype + case zExpectRrtype: + if l.value != zRrtpe { + return zp.setParseError("unknown RR type", l) + } + + h.Rrtype = l.torc + + st = zExpectRdata + case zExpectRdata: + var rr RR + if newFn, ok := TypeToRR[h.Rrtype]; ok && canParseAsRR(h.Rrtype) { + rr = newFn() + *rr.Header() = *h + } else { + rr = &RFC3597{Hdr: *h} + } + + _, isPrivate := rr.(*PrivateRR) + if !isPrivate && zp.c.Peek().token == "" { + // This is a dynamic update rr. + + // TODO(tmthrgd): Previously slurpRemainder was only called + // for certain RR types, which may have been important. + if err := slurpRemainder(zp.c); err != nil { + return zp.setParseError(err.err, err.lex) + } + + return rr, true + } else if l.value == zNewline { + return zp.setParseError("unexpected newline", l) + } + + if err := rr.parse(zp.c, zp.origin); err != nil { + // err is a concrete *ParseError without the file field set. + // The setParseError call below will construct a new + // *ParseError with file set to zp.file. + + // If err.lex is nil than we have encounter an unknown RR type + // in that case we substitute our current lex token. + if err.lex == (lex{}) { + return zp.setParseError(err.err, l) + } + + return zp.setParseError(err.err, err.lex) + } + + return rr, true + } + } + + // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this + // is not an error, because an empty zone file is still a zone file. + return nil, false +} + +// canParseAsRR returns true if the record type can be parsed as a +// concrete RR. It blacklists certain record types that must be parsed +// according to RFC 3597 because they lack a presentation format. +func canParseAsRR(rrtype uint16) bool { + switch rrtype { + case TypeANY, TypeNULL, TypeOPT, TypeTSIG: + return false + default: + return true + } +} + +type zlexer struct { + br io.ByteReader + + readErr error + + line int + column int + + comBuf string + comment string + + l lex + cachedL *lex + + brace int + quote bool + space bool + commt bool + rrtype bool + owner bool + + nextL bool + + eol bool // end-of-line +} + +func newZLexer(r io.Reader) *zlexer { + br, ok := r.(io.ByteReader) + if !ok { + br = bufio.NewReaderSize(r, 1024) + } + + return &zlexer{ + br: br, + + line: 1, + + owner: true, + } +} + +func (zl *zlexer) Err() error { + if zl.readErr == io.EOF { + return nil + } + + return zl.readErr +} + +// readByte returns the next byte from the input +func (zl *zlexer) readByte() (byte, bool) { + if zl.readErr != nil { + return 0, false + } + + c, err := zl.br.ReadByte() + if err != nil { + zl.readErr = err + return 0, false + } + + // delay the newline handling until the next token is delivered, + // fixes off-by-one errors when reporting a parse error. + if zl.eol { + zl.line++ + zl.column = 0 + zl.eol = false + } + + if c == '\n' { + zl.eol = true + } else { + zl.column++ + } + + return c, true +} + +func (zl *zlexer) Peek() lex { + if zl.nextL { + return zl.l + } + + l, ok := zl.Next() + if !ok { + return l + } + + if zl.nextL { + // Cache l. Next returns zl.cachedL then zl.l. + zl.cachedL = &l + } else { + // In this case l == zl.l, so we just tell Next to return zl.l. + zl.nextL = true + } + + return l +} + +func (zl *zlexer) Next() (lex, bool) { + l := &zl.l + switch { + case zl.cachedL != nil: + l, zl.cachedL = zl.cachedL, nil + return *l, true + case zl.nextL: + zl.nextL = false + return *l, true + case l.err: + // Parsing errors should be sticky. + return lex{value: zEOF}, false + } + + var ( + str [maxTok]byte // Hold string text + com [maxTok]byte // Hold comment text + + stri int // Offset in str (0 means empty) + comi int // Offset in com (0 means empty) + + escape bool + ) + + if zl.comBuf != "" { + comi = copy(com[:], zl.comBuf) + zl.comBuf = "" + } + + zl.comment = "" + + for x, ok := zl.readByte(); ok; x, ok = zl.readByte() { + l.line, l.column = zl.line, zl.column + + if stri >= len(str) { + l.token = "token length insufficient for parsing" + l.err = true + return *l, true + } + if comi >= len(com) { + l.token = "comment length insufficient for parsing" + l.err = true + return *l, true + } + + switch x { + case ' ', '\t': + if escape || zl.quote { + // Inside quotes or escaped this is legal. + str[stri] = x + stri++ + + escape = false + break + } + + if zl.commt { + com[comi] = x + comi++ + break + } + + var retL lex + if stri == 0 { + // Space directly in the beginning, handled in the grammar + } else if zl.owner { + // If we have a string and its the first, make it an owner + l.value = zOwner + l.token = string(str[:stri]) + + // escape $... start with a \ not a $, so this will work + switch strings.ToUpper(l.token) { + case "$TTL": + l.value = zDirTTL + case "$ORIGIN": + l.value = zDirOrigin + case "$INCLUDE": + l.value = zDirInclude + case "$GENERATE": + l.value = zDirGenerate + } + + retL = *l + } else { + l.value = zString + l.token = string(str[:stri]) + + if !zl.rrtype { + tokenUpper := strings.ToUpper(l.token) + if t, ok := StringToType[tokenUpper]; ok { + l.value = zRrtpe + l.torc = t + + zl.rrtype = true + } else if strings.HasPrefix(tokenUpper, "TYPE") { + t, ok := typeToInt(l.token) + if !ok { + l.token = "unknown RR type" + l.err = true + return *l, true + } + + l.value = zRrtpe + l.torc = t + + zl.rrtype = true + } + + if t, ok := StringToClass[tokenUpper]; ok { + l.value = zClass + l.torc = t + } else if strings.HasPrefix(tokenUpper, "CLASS") { + t, ok := classToInt(l.token) + if !ok { + l.token = "unknown class" + l.err = true + return *l, true + } + + l.value = zClass + l.torc = t + } + } + + retL = *l + } + + zl.owner = false + + if !zl.space { + zl.space = true + + l.value = zBlank + l.token = " " + + if retL == (lex{}) { + return *l, true + } + + zl.nextL = true + } + + if retL != (lex{}) { + return retL, true + } + case ';': + if escape || zl.quote { + // Inside quotes or escaped this is legal. + str[stri] = x + stri++ + + escape = false + break + } + + zl.commt = true + zl.comBuf = "" + + if comi > 1 { + // A newline was previously seen inside a comment that + // was inside braces and we delayed adding it until now. + com[comi] = ' ' // convert newline to space + comi++ + } + + com[comi] = ';' + comi++ + + if stri > 0 { + zl.comBuf = string(com[:comi]) + + l.value = zString + l.token = string(str[:stri]) + return *l, true + } + case '\r': + escape = false + + if zl.quote { + str[stri] = x + stri++ + } + + // discard if outside of quotes + case '\n': + escape = false + + // Escaped newline + if zl.quote { + str[stri] = x + stri++ + break + } + + if zl.commt { + // Reset a comment + zl.commt = false + zl.rrtype = false + + // If not in a brace this ends the comment AND the RR + if zl.brace == 0 { + zl.owner = true + + l.value = zNewline + l.token = "\n" + zl.comment = string(com[:comi]) + return *l, true + } + + zl.comBuf = string(com[:comi]) + break + } + + if zl.brace == 0 { + // If there is previous text, we should output it here + var retL lex + if stri != 0 { + l.value = zString + l.token = string(str[:stri]) + + if !zl.rrtype { + tokenUpper := strings.ToUpper(l.token) + if t, ok := StringToType[tokenUpper]; ok { + zl.rrtype = true + + l.value = zRrtpe + l.torc = t + } + } + + retL = *l + } + + l.value = zNewline + l.token = "\n" + + zl.comment = zl.comBuf + zl.comBuf = "" + zl.rrtype = false + zl.owner = true + + if retL != (lex{}) { + zl.nextL = true + return retL, true + } + + return *l, true + } + case '\\': + // comments do not get escaped chars, everything is copied + if zl.commt { + com[comi] = x + comi++ + break + } + + // something already escaped must be in string + if escape { + str[stri] = x + stri++ + + escape = false + break + } + + // something escaped outside of string gets added to string + str[stri] = x + stri++ + + escape = true + case '"': + if zl.commt { + com[comi] = x + comi++ + break + } + + if escape { + str[stri] = x + stri++ + + escape = false + break + } + + zl.space = false + + // send previous gathered text and the quote + var retL lex + if stri != 0 { + l.value = zString + l.token = string(str[:stri]) + + retL = *l + } + + // send quote itself as separate token + l.value = zQuote + l.token = "\"" + + zl.quote = !zl.quote + + if retL != (lex{}) { + zl.nextL = true + return retL, true + } + + return *l, true + case '(', ')': + if zl.commt { + com[comi] = x + comi++ + break + } + + if escape || zl.quote { + // Inside quotes or escaped this is legal. + str[stri] = x + stri++ + + escape = false + break + } + + switch x { + case ')': + zl.brace-- + + if zl.brace < 0 { + l.token = "extra closing brace" + l.err = true + return *l, true + } + case '(': + zl.brace++ + } + default: + escape = false + + if zl.commt { + com[comi] = x + comi++ + break + } + + str[stri] = x + stri++ + + zl.space = false + } + } + + if zl.readErr != nil && zl.readErr != io.EOF { + // Don't return any tokens after a read error occurs. + return lex{value: zEOF}, false + } + + var retL lex + if stri > 0 { + // Send remainder of str + l.value = zString + l.token = string(str[:stri]) + retL = *l + + if comi <= 0 { + return retL, true + } + } + + if comi > 0 { + // Send remainder of com + l.value = zNewline + l.token = "\n" + zl.comment = string(com[:comi]) + + if retL != (lex{}) { + zl.nextL = true + return retL, true + } + + return *l, true + } + + if zl.brace != 0 { + l.token = "unbalanced brace" + l.err = true + return *l, true + } + + return lex{value: zEOF}, false +} + +func (zl *zlexer) Comment() string { + if zl.l.err { + return "" + } + + return zl.comment +} + +// Extract the class number from CLASSxx +func classToInt(token string) (uint16, bool) { + offset := 5 + if len(token) < offset+1 { + return 0, false + } + class, err := strconv.ParseUint(token[offset:], 10, 16) + if err != nil { + return 0, false + } + return uint16(class), true +} + +// Extract the rr number from TYPExxx +func typeToInt(token string) (uint16, bool) { + offset := 4 + if len(token) < offset+1 { + return 0, false + } + typ, err := strconv.ParseUint(token[offset:], 10, 16) + if err != nil { + return 0, false + } + return uint16(typ), true +} + +// stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds. +func stringToTTL(token string) (uint32, bool) { + var s, i uint32 + for _, c := range token { + switch c { + case 's', 'S': + s += i + i = 0 + case 'm', 'M': + s += i * 60 + i = 0 + case 'h', 'H': + s += i * 60 * 60 + i = 0 + case 'd', 'D': + s += i * 60 * 60 * 24 + i = 0 + case 'w', 'W': + s += i * 60 * 60 * 24 * 7 + i = 0 + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i *= 10 + i += uint32(c) - '0' + default: + return 0, false + } + } + return s + i, true +} + +// Parse LOC records' [.][mM] into a +// mantissa exponent format. Token should contain the entire +// string (i.e. no spaces allowed) +func stringToCm(token string) (e, m uint8, ok bool) { + if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' { + token = token[0 : len(token)-1] + } + s := strings.SplitN(token, ".", 2) + var meters, cmeters, val int + var err error + switch len(s) { + case 2: + if cmeters, err = strconv.Atoi(s[1]); err != nil { + return + } + fallthrough + case 1: + if meters, err = strconv.Atoi(s[0]); err != nil { + return + } + case 0: + // huh? + return 0, 0, false + } + ok = true + if meters > 0 { + e = 2 + val = meters + } else { + e = 0 + val = cmeters + } + for val > 10 { + e++ + val /= 10 + } + if e > 9 { + ok = false + } + m = uint8(val) + return +} + +func toAbsoluteName(name, origin string) (absolute string, ok bool) { + // check for an explicit origin reference + if name == "@" { + // require a nonempty origin + if origin == "" { + return "", false + } + return origin, true + } + + // require a valid domain name + _, ok = IsDomainName(name) + if !ok || name == "" { + return "", false + } + + // check if name is already absolute + if IsFqdn(name) { + return name, true + } + + // require a nonempty origin + if origin == "" { + return "", false + } + return appendOrigin(name, origin), true +} + +func appendOrigin(name, origin string) string { + if origin == "." { + return name + origin + } + return name + "." + origin +} + +// LOC record helper function +func locCheckNorth(token string, latitude uint32) (uint32, bool) { + switch token { + case "n", "N": + return LOC_EQUATOR + latitude, true + case "s", "S": + return LOC_EQUATOR - latitude, true + } + return latitude, false +} + +// LOC record helper function +func locCheckEast(token string, longitude uint32) (uint32, bool) { + switch token { + case "e", "E": + return LOC_EQUATOR + longitude, true + case "w", "W": + return LOC_EQUATOR - longitude, true + } + return longitude, false +} + +// "Eat" the rest of the "line" +func slurpRemainder(c *zlexer) *ParseError { + l, _ := c.Next() + switch l.value { + case zBlank: + l, _ = c.Next() + if l.value != zNewline && l.value != zEOF { + return &ParseError{"", "garbage after rdata", l} + } + case zNewline: + case zEOF: + default: + return &ParseError{"", "garbage after rdata", l} + } + return nil +} + +// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64" +// Used for NID and L64 record. +func stringToNodeID(l lex) (uint64, *ParseError) { + if len(l.token) < 19 { + return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} + } + // There must be three colons at fixes postitions, if not its a parse error + if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' { + return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} + } + s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19] + u, err := strconv.ParseUint(s, 16, 64) + if err != nil { + return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} + } + return u, nil +} diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go new file mode 100644 index 00000000..93b24a69 --- /dev/null +++ b/vendor/github.com/miekg/dns/scan_rr.go @@ -0,0 +1,1698 @@ +package dns + +import ( + "encoding/base64" + "net" + "strconv" + "strings" +) + +// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces) +// or an error +func endingToString(c *zlexer, errstr string) (string, *ParseError) { + var s string + l, _ := c.Next() // zString + for l.value != zNewline && l.value != zEOF { + if l.err { + return s, &ParseError{"", errstr, l} + } + switch l.value { + case zString: + s += l.token + case zBlank: // Ok + default: + return "", &ParseError{"", errstr, l} + } + l, _ = c.Next() + } + + return s, nil +} + +// A remainder of the rdata with embedded spaces, split on unquoted whitespace +// and return the parsed string slice or an error +func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) { + // Get the remaining data until we see a zNewline + l, _ := c.Next() + if l.err { + return nil, &ParseError{"", errstr, l} + } + + // Build the slice + s := make([]string, 0) + quote := false + empty := false + for l.value != zNewline && l.value != zEOF { + if l.err { + return nil, &ParseError{"", errstr, l} + } + switch l.value { + case zString: + empty = false + if len(l.token) > 255 { + // split up tokens that are larger than 255 into 255-chunks + sx := []string{} + p, i := 0, 255 + for { + if i <= len(l.token) { + sx = append(sx, l.token[p:i]) + } else { + sx = append(sx, l.token[p:]) + break + + } + p, i = p+255, i+255 + } + s = append(s, sx...) + break + } + + s = append(s, l.token) + case zBlank: + if quote { + // zBlank can only be seen in between txt parts. + return nil, &ParseError{"", errstr, l} + } + case zQuote: + if empty && quote { + s = append(s, "") + } + quote = !quote + empty = true + default: + return nil, &ParseError{"", errstr, l} + } + l, _ = c.Next() + } + + if quote { + return nil, &ParseError{"", errstr, l} + } + + return s, nil +} + +func (rr *A) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + rr.A = net.ParseIP(l.token) + // IPv4 addresses cannot include ":". + // We do this rather than use net.IP's To4() because + // To4() treats IPv4-mapped IPv6 addresses as being + // IPv4. + isIPv4 := !strings.Contains(l.token, ":") + if rr.A == nil || !isIPv4 || l.err { + return &ParseError{"", "bad A A", l} + } + return slurpRemainder(c) +} + +func (rr *AAAA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + rr.AAAA = net.ParseIP(l.token) + // IPv6 addresses must include ":", and IPv4 + // addresses cannot include ":". + isIPv6 := strings.Contains(l.token, ":") + if rr.AAAA == nil || !isIPv6 || l.err { + return &ParseError{"", "bad AAAA AAAA", l} + } + return slurpRemainder(c) +} + +func (rr *NS) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad NS Ns", l} + } + rr.Ns = name + return slurpRemainder(c) +} + +func (rr *PTR) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad PTR Ptr", l} + } + rr.Ptr = name + return slurpRemainder(c) +} + +func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad NSAP-PTR Ptr", l} + } + rr.Ptr = name + return slurpRemainder(c) +} + +func (rr *RP) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + mbox, mboxOk := toAbsoluteName(l.token, o) + if l.err || !mboxOk { + return &ParseError{"", "bad RP Mbox", l} + } + rr.Mbox = mbox + + c.Next() // zBlank + l, _ = c.Next() + rr.Txt = l.token + + txt, txtOk := toAbsoluteName(l.token, o) + if l.err || !txtOk { + return &ParseError{"", "bad RP Txt", l} + } + rr.Txt = txt + + return slurpRemainder(c) +} + +func (rr *MR) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MR Mr", l} + } + rr.Mr = name + return slurpRemainder(c) +} + +func (rr *MB) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MB Mb", l} + } + rr.Mb = name + return slurpRemainder(c) +} + +func (rr *MG) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MG Mg", l} + } + rr.Mg = name + return slurpRemainder(c) +} + +func (rr *HINFO) parse(c *zlexer, o string) *ParseError { + chunks, e := endingToTxtSlice(c, "bad HINFO Fields") + if e != nil { + return e + } + + if ln := len(chunks); ln == 0 { + return nil + } else if ln == 1 { + // Can we split it? + if out := strings.Fields(chunks[0]); len(out) > 1 { + chunks = out + } else { + chunks = append(chunks, "") + } + } + + rr.Cpu = chunks[0] + rr.Os = strings.Join(chunks[1:], " ") + + return nil +} + +func (rr *MINFO) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + rmail, rmailOk := toAbsoluteName(l.token, o) + if l.err || !rmailOk { + return &ParseError{"", "bad MINFO Rmail", l} + } + rr.Rmail = rmail + + c.Next() // zBlank + l, _ = c.Next() + rr.Email = l.token + + email, emailOk := toAbsoluteName(l.token, o) + if l.err || !emailOk { + return &ParseError{"", "bad MINFO Email", l} + } + rr.Email = email + + return slurpRemainder(c) +} + +func (rr *MF) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MF Mf", l} + } + rr.Mf = name + return slurpRemainder(c) +} + +func (rr *MD) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MD Md", l} + } + rr.Md = name + return slurpRemainder(c) +} + +func (rr *MX) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad MX Pref", l} + } + rr.Preference = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Mx = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad MX Mx", l} + } + rr.Mx = name + + return slurpRemainder(c) +} + +func (rr *RT) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil { + return &ParseError{"", "bad RT Preference", l} + } + rr.Preference = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Host = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad RT Host", l} + } + rr.Host = name + + return slurpRemainder(c) +} + +func (rr *AFSDB) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad AFSDB Subtype", l} + } + rr.Subtype = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Hostname = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad AFSDB Hostname", l} + } + rr.Hostname = name + return slurpRemainder(c) +} + +func (rr *X25) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + if l.err { + return &ParseError{"", "bad X25 PSDNAddress", l} + } + rr.PSDNAddress = l.token + return slurpRemainder(c) +} + +func (rr *KX) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad KX Pref", l} + } + rr.Preference = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Exchanger = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad KX Exchanger", l} + } + rr.Exchanger = name + return slurpRemainder(c) +} + +func (rr *CNAME) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad CNAME Target", l} + } + rr.Target = name + return slurpRemainder(c) +} + +func (rr *DNAME) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad DNAME Target", l} + } + rr.Target = name + return slurpRemainder(c) +} + +func (rr *SOA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + ns, nsOk := toAbsoluteName(l.token, o) + if l.err || !nsOk { + return &ParseError{"", "bad SOA Ns", l} + } + rr.Ns = ns + + c.Next() // zBlank + l, _ = c.Next() + rr.Mbox = l.token + + mbox, mboxOk := toAbsoluteName(l.token, o) + if l.err || !mboxOk { + return &ParseError{"", "bad SOA Mbox", l} + } + rr.Mbox = mbox + + c.Next() // zBlank + + var ( + v uint32 + ok bool + ) + for i := 0; i < 5; i++ { + l, _ = c.Next() + if l.err { + return &ParseError{"", "bad SOA zone parameter", l} + } + if j, e := strconv.ParseUint(l.token, 10, 32); e != nil { + if i == 0 { + // Serial must be a number + return &ParseError{"", "bad SOA zone parameter", l} + } + // We allow other fields to be unitful duration strings + if v, ok = stringToTTL(l.token); !ok { + return &ParseError{"", "bad SOA zone parameter", l} + + } + } else { + v = uint32(j) + } + switch i { + case 0: + rr.Serial = v + c.Next() // zBlank + case 1: + rr.Refresh = v + c.Next() // zBlank + case 2: + rr.Retry = v + c.Next() // zBlank + case 3: + rr.Expire = v + c.Next() // zBlank + case 4: + rr.Minttl = v + } + } + return slurpRemainder(c) +} + +func (rr *SRV) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad SRV Priority", l} + } + rr.Priority = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad SRV Weight", l} + } + rr.Weight = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad SRV Port", l} + } + rr.Port = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Target = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad SRV Target", l} + } + rr.Target = name + return slurpRemainder(c) +} + +func (rr *NAPTR) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad NAPTR Order", l} + } + rr.Order = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad NAPTR Preference", l} + } + rr.Preference = uint16(i) + + // Flags + c.Next() // zBlank + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Flags", l} + } + l, _ = c.Next() // Either String or Quote + if l.value == zString { + rr.Flags = l.token + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Flags", l} + } + } else if l.value == zQuote { + rr.Flags = "" + } else { + return &ParseError{"", "bad NAPTR Flags", l} + } + + // Service + c.Next() // zBlank + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Service", l} + } + l, _ = c.Next() // Either String or Quote + if l.value == zString { + rr.Service = l.token + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Service", l} + } + } else if l.value == zQuote { + rr.Service = "" + } else { + return &ParseError{"", "bad NAPTR Service", l} + } + + // Regexp + c.Next() // zBlank + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Regexp", l} + } + l, _ = c.Next() // Either String or Quote + if l.value == zString { + rr.Regexp = l.token + l, _ = c.Next() // _QUOTE + if l.value != zQuote { + return &ParseError{"", "bad NAPTR Regexp", l} + } + } else if l.value == zQuote { + rr.Regexp = "" + } else { + return &ParseError{"", "bad NAPTR Regexp", l} + } + + // After quote no space?? + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Replacement = l.token + + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad NAPTR Replacement", l} + } + rr.Replacement = name + return slurpRemainder(c) +} + +func (rr *TALINK) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + previousName, previousNameOk := toAbsoluteName(l.token, o) + if l.err || !previousNameOk { + return &ParseError{"", "bad TALINK PreviousName", l} + } + rr.PreviousName = previousName + + c.Next() // zBlank + l, _ = c.Next() + rr.NextName = l.token + + nextName, nextNameOk := toAbsoluteName(l.token, o) + if l.err || !nextNameOk { + return &ParseError{"", "bad TALINK NextName", l} + } + rr.NextName = nextName + + return slurpRemainder(c) +} + +func (rr *LOC) parse(c *zlexer, o string) *ParseError { + // Non zero defaults for LOC record, see RFC 1876, Section 3. + rr.HorizPre = 165 // 10000 + rr.VertPre = 162 // 10 + rr.Size = 18 // 1 + ok := false + + // North + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 32) + if e != nil || l.err { + return &ParseError{"", "bad LOC Latitude", l} + } + rr.Latitude = 1000 * 60 * 60 * uint32(i) + + c.Next() // zBlank + // Either number, 'N' or 'S' + l, _ = c.Next() + if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { + goto East + } + i, e = strconv.ParseUint(l.token, 10, 32) + if e != nil || l.err { + return &ParseError{"", "bad LOC Latitude minutes", l} + } + rr.Latitude += 1000 * 60 * uint32(i) + + c.Next() // zBlank + l, _ = c.Next() + if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { + return &ParseError{"", "bad LOC Latitude seconds", l} + } else { + rr.Latitude += uint32(1000 * i) + } + c.Next() // zBlank + // Either number, 'N' or 'S' + l, _ = c.Next() + if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { + goto East + } + // If still alive, flag an error + return &ParseError{"", "bad LOC Latitude North/South", l} + +East: + // East + c.Next() // zBlank + l, _ = c.Next() + if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { + return &ParseError{"", "bad LOC Longitude", l} + } else { + rr.Longitude = 1000 * 60 * 60 * uint32(i) + } + c.Next() // zBlank + // Either number, 'E' or 'W' + l, _ = c.Next() + if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { + goto Altitude + } + if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { + return &ParseError{"", "bad LOC Longitude minutes", l} + } else { + rr.Longitude += 1000 * 60 * uint32(i) + } + c.Next() // zBlank + l, _ = c.Next() + if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { + return &ParseError{"", "bad LOC Longitude seconds", l} + } else { + rr.Longitude += uint32(1000 * i) + } + c.Next() // zBlank + // Either number, 'E' or 'W' + l, _ = c.Next() + if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { + goto Altitude + } + // If still alive, flag an error + return &ParseError{"", "bad LOC Longitude East/West", l} + +Altitude: + c.Next() // zBlank + l, _ = c.Next() + if len(l.token) == 0 || l.err { + return &ParseError{"", "bad LOC Altitude", l} + } + if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' { + l.token = l.token[0 : len(l.token)-1] + } + if i, e := strconv.ParseFloat(l.token, 32); e != nil { + return &ParseError{"", "bad LOC Altitude", l} + } else { + rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5) + } + + // And now optionally the other values + l, _ = c.Next() + count := 0 + for l.value != zNewline && l.value != zEOF { + switch l.value { + case zString: + switch count { + case 0: // Size + e, m, ok := stringToCm(l.token) + if !ok { + return &ParseError{"", "bad LOC Size", l} + } + rr.Size = e&0x0f | m<<4&0xf0 + case 1: // HorizPre + e, m, ok := stringToCm(l.token) + if !ok { + return &ParseError{"", "bad LOC HorizPre", l} + } + rr.HorizPre = e&0x0f | m<<4&0xf0 + case 2: // VertPre + e, m, ok := stringToCm(l.token) + if !ok { + return &ParseError{"", "bad LOC VertPre", l} + } + rr.VertPre = e&0x0f | m<<4&0xf0 + } + count++ + case zBlank: + // Ok + default: + return &ParseError{"", "bad LOC Size, HorizPre or VertPre", l} + } + l, _ = c.Next() + } + return nil +} + +func (rr *HIP) parse(c *zlexer, o string) *ParseError { + // HitLength is not represented + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad HIP PublicKeyAlgorithm", l} + } + rr.PublicKeyAlgorithm = uint8(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + if len(l.token) == 0 || l.err { + return &ParseError{"", "bad HIP Hit", l} + } + rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6. + rr.HitLength = uint8(len(rr.Hit)) / 2 + + c.Next() // zBlank + l, _ = c.Next() // zString + if len(l.token) == 0 || l.err { + return &ParseError{"", "bad HIP PublicKey", l} + } + rr.PublicKey = l.token // This cannot contain spaces + rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey))) + + // RendezvousServers (if any) + l, _ = c.Next() + var xs []string + for l.value != zNewline && l.value != zEOF { + switch l.value { + case zString: + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad HIP RendezvousServers", l} + } + xs = append(xs, name) + case zBlank: + // Ok + default: + return &ParseError{"", "bad HIP RendezvousServers", l} + } + l, _ = c.Next() + } + + rr.RendezvousServers = xs + return nil +} + +func (rr *CERT) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + if v, ok := StringToCertType[l.token]; ok { + rr.Type = v + } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil { + return &ParseError{"", "bad CERT Type", l} + } else { + rr.Type = uint16(i) + } + c.Next() // zBlank + l, _ = c.Next() // zString + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad CERT KeyTag", l} + } + rr.KeyTag = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + if v, ok := StringToAlgorithm[l.token]; ok { + rr.Algorithm = v + } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { + return &ParseError{"", "bad CERT Algorithm", l} + } else { + rr.Algorithm = uint8(i) + } + s, e1 := endingToString(c, "bad CERT Certificate") + if e1 != nil { + return e1 + } + rr.Certificate = s + return nil +} + +func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError { + s, e := endingToString(c, "bad OPENPGPKEY PublicKey") + if e != nil { + return e + } + rr.PublicKey = s + return nil +} + +func (rr *CSYNC) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + j, e := strconv.ParseUint(l.token, 10, 32) + if e != nil { + // Serial must be a number + return &ParseError{"", "bad CSYNC serial", l} + } + rr.Serial = uint32(j) + + c.Next() // zBlank + + l, _ = c.Next() + j, e = strconv.ParseUint(l.token, 10, 16) + if e != nil { + // Serial must be a number + return &ParseError{"", "bad CSYNC flags", l} + } + rr.Flags = uint16(j) + + rr.TypeBitMap = make([]uint16, 0) + var ( + k uint16 + ok bool + ) + l, _ = c.Next() + for l.value != zNewline && l.value != zEOF { + switch l.value { + case zBlank: + // Ok + case zString: + tokenUpper := strings.ToUpper(l.token) + if k, ok = StringToType[tokenUpper]; !ok { + if k, ok = typeToInt(l.token); !ok { + return &ParseError{"", "bad CSYNC TypeBitMap", l} + } + } + rr.TypeBitMap = append(rr.TypeBitMap, k) + default: + return &ParseError{"", "bad CSYNC TypeBitMap", l} + } + l, _ = c.Next() + } + return nil +} + +func (rr *SIG) parse(c *zlexer, o string) *ParseError { + return rr.RRSIG.parse(c, o) +} + +func (rr *RRSIG) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + tokenUpper := strings.ToUpper(l.token) + if t, ok := StringToType[tokenUpper]; !ok { + if strings.HasPrefix(tokenUpper, "TYPE") { + t, ok = typeToInt(l.token) + if !ok { + return &ParseError{"", "bad RRSIG Typecovered", l} + } + rr.TypeCovered = t + } else { + return &ParseError{"", "bad RRSIG Typecovered", l} + } + } else { + rr.TypeCovered = t + } + + c.Next() // zBlank + l, _ = c.Next() + i, err := strconv.ParseUint(l.token, 10, 8) + if err != nil || l.err { + return &ParseError{"", "bad RRSIG Algorithm", l} + } + rr.Algorithm = uint8(i) + + c.Next() // zBlank + l, _ = c.Next() + i, err = strconv.ParseUint(l.token, 10, 8) + if err != nil || l.err { + return &ParseError{"", "bad RRSIG Labels", l} + } + rr.Labels = uint8(i) + + c.Next() // zBlank + l, _ = c.Next() + i, err = strconv.ParseUint(l.token, 10, 32) + if err != nil || l.err { + return &ParseError{"", "bad RRSIG OrigTtl", l} + } + rr.OrigTtl = uint32(i) + + c.Next() // zBlank + l, _ = c.Next() + if i, err := StringToTime(l.token); err != nil { + // Try to see if all numeric and use it as epoch + if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { + // TODO(miek): error out on > MAX_UINT32, same below + rr.Expiration = uint32(i) + } else { + return &ParseError{"", "bad RRSIG Expiration", l} + } + } else { + rr.Expiration = i + } + + c.Next() // zBlank + l, _ = c.Next() + if i, err := StringToTime(l.token); err != nil { + if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { + rr.Inception = uint32(i) + } else { + return &ParseError{"", "bad RRSIG Inception", l} + } + } else { + rr.Inception = i + } + + c.Next() // zBlank + l, _ = c.Next() + i, err = strconv.ParseUint(l.token, 10, 16) + if err != nil || l.err { + return &ParseError{"", "bad RRSIG KeyTag", l} + } + rr.KeyTag = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() + rr.SignerName = l.token + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad RRSIG SignerName", l} + } + rr.SignerName = name + + s, e := endingToString(c, "bad RRSIG Signature") + if e != nil { + return e + } + rr.Signature = s + + return nil +} + +func (rr *NSEC) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad NSEC NextDomain", l} + } + rr.NextDomain = name + + rr.TypeBitMap = make([]uint16, 0) + var ( + k uint16 + ok bool + ) + l, _ = c.Next() + for l.value != zNewline && l.value != zEOF { + switch l.value { + case zBlank: + // Ok + case zString: + tokenUpper := strings.ToUpper(l.token) + if k, ok = StringToType[tokenUpper]; !ok { + if k, ok = typeToInt(l.token); !ok { + return &ParseError{"", "bad NSEC TypeBitMap", l} + } + } + rr.TypeBitMap = append(rr.TypeBitMap, k) + default: + return &ParseError{"", "bad NSEC TypeBitMap", l} + } + l, _ = c.Next() + } + return nil +} + +func (rr *NSEC3) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3 Hash", l} + } + rr.Hash = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3 Flags", l} + } + rr.Flags = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3 Iterations", l} + } + rr.Iterations = uint16(i) + c.Next() + l, _ = c.Next() + if len(l.token) == 0 || l.err { + return &ParseError{"", "bad NSEC3 Salt", l} + } + if l.token != "-" { + rr.SaltLength = uint8(len(l.token)) / 2 + rr.Salt = l.token + } + + c.Next() + l, _ = c.Next() + if len(l.token) == 0 || l.err { + return &ParseError{"", "bad NSEC3 NextDomain", l} + } + rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) + rr.NextDomain = l.token + + rr.TypeBitMap = make([]uint16, 0) + var ( + k uint16 + ok bool + ) + l, _ = c.Next() + for l.value != zNewline && l.value != zEOF { + switch l.value { + case zBlank: + // Ok + case zString: + tokenUpper := strings.ToUpper(l.token) + if k, ok = StringToType[tokenUpper]; !ok { + if k, ok = typeToInt(l.token); !ok { + return &ParseError{"", "bad NSEC3 TypeBitMap", l} + } + } + rr.TypeBitMap = append(rr.TypeBitMap, k) + default: + return &ParseError{"", "bad NSEC3 TypeBitMap", l} + } + l, _ = c.Next() + } + return nil +} + +func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3PARAM Hash", l} + } + rr.Hash = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3PARAM Flags", l} + } + rr.Flags = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad NSEC3PARAM Iterations", l} + } + rr.Iterations = uint16(i) + c.Next() + l, _ = c.Next() + if l.token != "-" { + rr.SaltLength = uint8(len(l.token)) + rr.Salt = l.token + } + return slurpRemainder(c) +} + +func (rr *EUI48) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + if len(l.token) != 17 || l.err { + return &ParseError{"", "bad EUI48 Address", l} + } + addr := make([]byte, 12) + dash := 0 + for i := 0; i < 10; i += 2 { + addr[i] = l.token[i+dash] + addr[i+1] = l.token[i+1+dash] + dash++ + if l.token[i+1+dash] != '-' { + return &ParseError{"", "bad EUI48 Address", l} + } + } + addr[10] = l.token[15] + addr[11] = l.token[16] + + i, e := strconv.ParseUint(string(addr), 16, 48) + if e != nil { + return &ParseError{"", "bad EUI48 Address", l} + } + rr.Address = i + return slurpRemainder(c) +} + +func (rr *EUI64) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + if len(l.token) != 23 || l.err { + return &ParseError{"", "bad EUI64 Address", l} + } + addr := make([]byte, 16) + dash := 0 + for i := 0; i < 14; i += 2 { + addr[i] = l.token[i+dash] + addr[i+1] = l.token[i+1+dash] + dash++ + if l.token[i+1+dash] != '-' { + return &ParseError{"", "bad EUI64 Address", l} + } + } + addr[14] = l.token[21] + addr[15] = l.token[22] + + i, e := strconv.ParseUint(string(addr), 16, 64) + if e != nil { + return &ParseError{"", "bad EUI68 Address", l} + } + rr.Address = i + return slurpRemainder(c) +} + +func (rr *SSHFP) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad SSHFP Algorithm", l} + } + rr.Algorithm = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad SSHFP Type", l} + } + rr.Type = uint8(i) + c.Next() // zBlank + s, e1 := endingToString(c, "bad SSHFP Fingerprint") + if e1 != nil { + return e1 + } + rr.FingerPrint = s + return nil +} + +func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad " + typ + " Flags", l} + } + rr.Flags = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad " + typ + " Protocol", l} + } + rr.Protocol = uint8(i) + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad " + typ + " Algorithm", l} + } + rr.Algorithm = uint8(i) + s, e1 := endingToString(c, "bad "+typ+" PublicKey") + if e1 != nil { + return e1 + } + rr.PublicKey = s + return nil +} + +func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError { + return rr.parseDNSKEY(c, o, "DNSKEY") +} + +func (rr *KEY) parse(c *zlexer, o string) *ParseError { + return rr.parseDNSKEY(c, o, "KEY") +} + +func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { + return rr.parseDNSKEY(c, o, "CDNSKEY") +} + +func (rr *RKEY) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad RKEY Flags", l} + } + rr.Flags = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad RKEY Protocol", l} + } + rr.Protocol = uint8(i) + c.Next() // zBlank + l, _ = c.Next() // zString + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad RKEY Algorithm", l} + } + rr.Algorithm = uint8(i) + s, e1 := endingToString(c, "bad RKEY PublicKey") + if e1 != nil { + return e1 + } + rr.PublicKey = s + return nil +} + +func (rr *EID) parse(c *zlexer, o string) *ParseError { + s, e := endingToString(c, "bad EID Endpoint") + if e != nil { + return e + } + rr.Endpoint = s + return nil +} + +func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError { + s, e := endingToString(c, "bad NIMLOC Locator") + if e != nil { + return e + } + rr.Locator = s + return nil +} + +func (rr *GPOS) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + _, e := strconv.ParseFloat(l.token, 64) + if e != nil || l.err { + return &ParseError{"", "bad GPOS Longitude", l} + } + rr.Longitude = l.token + c.Next() // zBlank + l, _ = c.Next() + _, e = strconv.ParseFloat(l.token, 64) + if e != nil || l.err { + return &ParseError{"", "bad GPOS Latitude", l} + } + rr.Latitude = l.token + c.Next() // zBlank + l, _ = c.Next() + _, e = strconv.ParseFloat(l.token, 64) + if e != nil || l.err { + return &ParseError{"", "bad GPOS Altitude", l} + } + rr.Altitude = l.token + return slurpRemainder(c) +} + +func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad " + typ + " KeyTag", l} + } + rr.KeyTag = uint16(i) + c.Next() // zBlank + l, _ = c.Next() + if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { + tokenUpper := strings.ToUpper(l.token) + i, ok := StringToAlgorithm[tokenUpper] + if !ok || l.err { + return &ParseError{"", "bad " + typ + " Algorithm", l} + } + rr.Algorithm = i + } else { + rr.Algorithm = uint8(i) + } + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad " + typ + " DigestType", l} + } + rr.DigestType = uint8(i) + s, e1 := endingToString(c, "bad "+typ+" Digest") + if e1 != nil { + return e1 + } + rr.Digest = s + return nil +} + +func (rr *DS) parse(c *zlexer, o string) *ParseError { + return rr.parseDS(c, o, "DS") +} + +func (rr *DLV) parse(c *zlexer, o string) *ParseError { + return rr.parseDS(c, o, "DLV") +} + +func (rr *CDS) parse(c *zlexer, o string) *ParseError { + return rr.parseDS(c, o, "CDS") +} + +func (rr *TA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad TA KeyTag", l} + } + rr.KeyTag = uint16(i) + c.Next() // zBlank + l, _ = c.Next() + if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { + tokenUpper := strings.ToUpper(l.token) + i, ok := StringToAlgorithm[tokenUpper] + if !ok || l.err { + return &ParseError{"", "bad TA Algorithm", l} + } + rr.Algorithm = i + } else { + rr.Algorithm = uint8(i) + } + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad TA DigestType", l} + } + rr.DigestType = uint8(i) + s, err := endingToString(c, "bad TA Digest") + if err != nil { + return err + } + rr.Digest = s + return nil +} + +func (rr *TLSA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad TLSA Usage", l} + } + rr.Usage = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad TLSA Selector", l} + } + rr.Selector = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad TLSA MatchingType", l} + } + rr.MatchingType = uint8(i) + // So this needs be e2 (i.e. different than e), because...??t + s, e2 := endingToString(c, "bad TLSA Certificate") + if e2 != nil { + return e2 + } + rr.Certificate = s + return nil +} + +func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad SMIMEA Usage", l} + } + rr.Usage = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad SMIMEA Selector", l} + } + rr.Selector = uint8(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return &ParseError{"", "bad SMIMEA MatchingType", l} + } + rr.MatchingType = uint8(i) + // So this needs be e2 (i.e. different than e), because...??t + s, e2 := endingToString(c, "bad SMIMEA Certificate") + if e2 != nil { + return e2 + } + rr.Certificate = s + return nil +} + +func (rr *RFC3597) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + if l.token != "\\#" { + return &ParseError{"", "bad RFC3597 Rdata", l} + } + + c.Next() // zBlank + l, _ = c.Next() + rdlength, e := strconv.Atoi(l.token) + if e != nil || l.err { + return &ParseError{"", "bad RFC3597 Rdata ", l} + } + + s, e1 := endingToString(c, "bad RFC3597 Rdata") + if e1 != nil { + return e1 + } + if rdlength*2 != len(s) { + return &ParseError{"", "bad RFC3597 Rdata", l} + } + rr.Rdata = s + return nil +} + +func (rr *SPF) parse(c *zlexer, o string) *ParseError { + s, e := endingToTxtSlice(c, "bad SPF Txt") + if e != nil { + return e + } + rr.Txt = s + return nil +} + +func (rr *AVC) parse(c *zlexer, o string) *ParseError { + s, e := endingToTxtSlice(c, "bad AVC Txt") + if e != nil { + return e + } + rr.Txt = s + return nil +} + +func (rr *TXT) parse(c *zlexer, o string) *ParseError { + // no zBlank reading here, because all this rdata is TXT + s, e := endingToTxtSlice(c, "bad TXT Txt") + if e != nil { + return e + } + rr.Txt = s + return nil +} + +// identical to setTXT +func (rr *NINFO) parse(c *zlexer, o string) *ParseError { + s, e := endingToTxtSlice(c, "bad NINFO ZSData") + if e != nil { + return e + } + rr.ZSData = s + return nil +} + +func (rr *URI) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad URI Priority", l} + } + rr.Priority = uint16(i) + c.Next() // zBlank + l, _ = c.Next() + i, e = strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad URI Weight", l} + } + rr.Weight = uint16(i) + + c.Next() // zBlank + s, err := endingToTxtSlice(c, "bad URI Target") + if err != nil { + return err + } + if len(s) != 1 { + return &ParseError{"", "bad URI Target", l} + } + rr.Target = s[0] + return nil +} + +func (rr *DHCID) parse(c *zlexer, o string) *ParseError { + // awesome record to parse! + s, e := endingToString(c, "bad DHCID Digest") + if e != nil { + return e + } + rr.Digest = s + return nil +} + +func (rr *NID) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad NID Preference", l} + } + rr.Preference = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + u, err := stringToNodeID(l) + if err != nil || l.err { + return err + } + rr.NodeID = u + return slurpRemainder(c) +} + +func (rr *L32) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad L32 Preference", l} + } + rr.Preference = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Locator32 = net.ParseIP(l.token) + if rr.Locator32 == nil || l.err { + return &ParseError{"", "bad L32 Locator", l} + } + return slurpRemainder(c) +} + +func (rr *LP) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad LP Preference", l} + } + rr.Preference = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Fqdn = l.token + name, nameOk := toAbsoluteName(l.token, o) + if l.err || !nameOk { + return &ParseError{"", "bad LP Fqdn", l} + } + rr.Fqdn = name + + return slurpRemainder(c) +} + +func (rr *L64) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad L64 Preference", l} + } + rr.Preference = uint16(i) + c.Next() // zBlank + l, _ = c.Next() // zString + u, err := stringToNodeID(l) + if err != nil || l.err { + return err + } + rr.Locator64 = u + return slurpRemainder(c) +} + +func (rr *UID) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 32) + if e != nil || l.err { + return &ParseError{"", "bad UID Uid", l} + } + rr.Uid = uint32(i) + return slurpRemainder(c) +} + +func (rr *GID) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 32) + if e != nil || l.err { + return &ParseError{"", "bad GID Gid", l} + } + rr.Gid = uint32(i) + return slurpRemainder(c) +} + +func (rr *UINFO) parse(c *zlexer, o string) *ParseError { + s, e := endingToTxtSlice(c, "bad UINFO Uinfo") + if e != nil { + return e + } + if ln := len(s); ln == 0 { + return nil + } + rr.Uinfo = s[0] // silently discard anything after the first character-string + return nil +} + +func (rr *PX) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, e := strconv.ParseUint(l.token, 10, 16) + if e != nil || l.err { + return &ParseError{"", "bad PX Preference", l} + } + rr.Preference = uint16(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Map822 = l.token + map822, map822Ok := toAbsoluteName(l.token, o) + if l.err || !map822Ok { + return &ParseError{"", "bad PX Map822", l} + } + rr.Map822 = map822 + + c.Next() // zBlank + l, _ = c.Next() // zString + rr.Mapx400 = l.token + mapx400, mapx400Ok := toAbsoluteName(l.token, o) + if l.err || !mapx400Ok { + return &ParseError{"", "bad PX Mapx400", l} + } + rr.Mapx400 = mapx400 + + return slurpRemainder(c) +} + +func (rr *CAA) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + i, err := strconv.ParseUint(l.token, 10, 8) + if err != nil || l.err { + return &ParseError{"", "bad CAA Flag", l} + } + rr.Flag = uint8(i) + + c.Next() // zBlank + l, _ = c.Next() // zString + if l.value != zString { + return &ParseError{"", "bad CAA Tag", l} + } + rr.Tag = l.token + + c.Next() // zBlank + s, e := endingToTxtSlice(c, "bad CAA Value") + if e != nil { + return e + } + if len(s) != 1 { + return &ParseError{"", "bad CAA Value", l} + } + rr.Value = s[0] + return nil +} + +func (rr *TKEY) parse(c *zlexer, o string) *ParseError { + l, _ := c.Next() + + // Algorithm + if l.value != zString { + return &ParseError{"", "bad TKEY algorithm", l} + } + rr.Algorithm = l.token + c.Next() // zBlank + + // Get the key length and key values + l, _ = c.Next() + i, err := strconv.ParseUint(l.token, 10, 8) + if err != nil || l.err { + return &ParseError{"", "bad TKEY key length", l} + } + rr.KeySize = uint16(i) + c.Next() // zBlank + l, _ = c.Next() + if l.value != zString { + return &ParseError{"", "bad TKEY key", l} + } + rr.Key = l.token + c.Next() // zBlank + + // Get the otherdata length and string data + l, _ = c.Next() + i, err = strconv.ParseUint(l.token, 10, 8) + if err != nil || l.err { + return &ParseError{"", "bad TKEY otherdata length", l} + } + rr.OtherLen = uint16(i) + c.Next() // zBlank + l, _ = c.Next() + if l.value != zString { + return &ParseError{"", "bad TKEY otherday", l} + } + rr.OtherData = l.token + + return nil +} diff --git a/vendor/github.com/miekg/dns/serve_mux.go b/vendor/github.com/miekg/dns/serve_mux.go new file mode 100644 index 00000000..ae304db5 --- /dev/null +++ b/vendor/github.com/miekg/dns/serve_mux.go @@ -0,0 +1,147 @@ +package dns + +import ( + "strings" + "sync" +) + +// ServeMux is an DNS request multiplexer. It matches the zone name of +// each incoming request against a list of registered patterns add calls +// the handler for the pattern that most closely matches the zone name. +// +// ServeMux is DNSSEC aware, meaning that queries for the DS record are +// redirected to the parent zone (if that is also registered), otherwise +// the child gets the query. +// +// ServeMux is also safe for concurrent access from multiple goroutines. +// +// The zero ServeMux is empty and ready for use. +type ServeMux struct { + z map[string]Handler + m sync.RWMutex +} + +// NewServeMux allocates and returns a new ServeMux. +func NewServeMux() *ServeMux { + return new(ServeMux) +} + +// DefaultServeMux is the default ServeMux used by Serve. +var DefaultServeMux = NewServeMux() + +func (mux *ServeMux) match(q string, t uint16) Handler { + mux.m.RLock() + defer mux.m.RUnlock() + if mux.z == nil { + return nil + } + + var handler Handler + + // TODO(tmthrgd): Once https://go-review.googlesource.com/c/go/+/137575 + // lands in a go release, replace the following with strings.ToLower. + var sb strings.Builder + for i := 0; i < len(q); i++ { + c := q[i] + if !(c >= 'A' && c <= 'Z') { + continue + } + + sb.Grow(len(q)) + sb.WriteString(q[:i]) + + for ; i < len(q); i++ { + c := q[i] + if c >= 'A' && c <= 'Z' { + c += 'a' - 'A' + } + + sb.WriteByte(c) + } + + q = sb.String() + break + } + + for off, end := 0, false; !end; off, end = NextLabel(q, off) { + if h, ok := mux.z[q[off:]]; ok { + if t != TypeDS { + return h + } + // Continue for DS to see if we have a parent too, if so delegate to the parent + handler = h + } + } + + // Wildcard match, if we have found nothing try the root zone as a last resort. + if h, ok := mux.z["."]; ok { + return h + } + + return handler +} + +// Handle adds a handler to the ServeMux for pattern. +func (mux *ServeMux) Handle(pattern string, handler Handler) { + if pattern == "" { + panic("dns: invalid pattern " + pattern) + } + mux.m.Lock() + if mux.z == nil { + mux.z = make(map[string]Handler) + } + mux.z[Fqdn(pattern)] = handler + mux.m.Unlock() +} + +// HandleFunc adds a handler function to the ServeMux for pattern. +func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { + mux.Handle(pattern, HandlerFunc(handler)) +} + +// HandleRemove deregisters the handler specific for pattern from the ServeMux. +func (mux *ServeMux) HandleRemove(pattern string) { + if pattern == "" { + panic("dns: invalid pattern " + pattern) + } + mux.m.Lock() + delete(mux.z, Fqdn(pattern)) + mux.m.Unlock() +} + +// ServeDNS dispatches the request to the handler whose pattern most +// closely matches the request message. +// +// ServeDNS is DNSSEC aware, meaning that queries for the DS record +// are redirected to the parent zone (if that is also registered), +// otherwise the child gets the query. +// +// If no handler is found, or there is no question, a standard SERVFAIL +// message is returned +func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) { + var h Handler + if len(req.Question) >= 1 { // allow more than one question + h = mux.match(req.Question[0].Name, req.Question[0].Qtype) + } + + if h != nil { + h.ServeDNS(w, req) + } else { + HandleFailed(w, req) + } +} + +// Handle registers the handler with the given pattern +// in the DefaultServeMux. The documentation for +// ServeMux explains how patterns are matched. +func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } + +// HandleRemove deregisters the handle with the given pattern +// in the DefaultServeMux. +func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) } + +// HandleFunc registers the handler function with the given pattern +// in the DefaultServeMux. +func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { + DefaultServeMux.HandleFunc(pattern, handler) +} diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go new file mode 100644 index 00000000..354f7712 --- /dev/null +++ b/vendor/github.com/miekg/dns/server.go @@ -0,0 +1,758 @@ +// DNS server implementation. + +package dns + +import ( + "context" + "crypto/tls" + "encoding/binary" + "errors" + "io" + "net" + "strings" + "sync" + "time" +) + +// Default maximum number of TCP queries before we close the socket. +const maxTCPQueries = 128 + +// aLongTimeAgo is a non-zero time, far in the past, used for +// immediate cancelation of network operations. +var aLongTimeAgo = time.Unix(1, 0) + +// Handler is implemented by any value that implements ServeDNS. +type Handler interface { + ServeDNS(w ResponseWriter, r *Msg) +} + +// The HandlerFunc type is an adapter to allow the use of +// ordinary functions as DNS handlers. If f is a function +// with the appropriate signature, HandlerFunc(f) is a +// Handler object that calls f. +type HandlerFunc func(ResponseWriter, *Msg) + +// ServeDNS calls f(w, r). +func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) { + f(w, r) +} + +// A ResponseWriter interface is used by an DNS handler to +// construct an DNS response. +type ResponseWriter interface { + // LocalAddr returns the net.Addr of the server + LocalAddr() net.Addr + // RemoteAddr returns the net.Addr of the client that sent the current request. + RemoteAddr() net.Addr + // WriteMsg writes a reply back to the client. + WriteMsg(*Msg) error + // Write writes a raw buffer back to the client. + Write([]byte) (int, error) + // Close closes the connection. + Close() error + // TsigStatus returns the status of the Tsig. + TsigStatus() error + // TsigTimersOnly sets the tsig timers only boolean. + TsigTimersOnly(bool) + // Hijack lets the caller take over the connection. + // After a call to Hijack(), the DNS package will not do anything with the connection. + Hijack() +} + +// A ConnectionStater interface is used by a DNS Handler to access TLS connection state +// when available. +type ConnectionStater interface { + ConnectionState() *tls.ConnectionState +} + +type response struct { + closed bool // connection has been closed + hijacked bool // connection has been hijacked by handler + tsigTimersOnly bool + tsigStatus error + tsigRequestMAC string + tsigSecret map[string]string // the tsig secrets + udp *net.UDPConn // i/o connection if UDP was used + tcp net.Conn // i/o connection if TCP was used + udpSession *SessionUDP // oob data to get egress interface right + writer Writer // writer to output the raw DNS bits +} + +// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets. +func HandleFailed(w ResponseWriter, r *Msg) { + m := new(Msg) + m.SetRcode(r, RcodeServerFailure) + // does not matter if this write fails + w.WriteMsg(m) +} + +// ListenAndServe Starts a server on address and network specified Invoke handler +// for incoming queries. +func ListenAndServe(addr string, network string, handler Handler) error { + server := &Server{Addr: addr, Net: network, Handler: handler} + return server.ListenAndServe() +} + +// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in +// http://golang.org/pkg/net/http/#ListenAndServeTLS +func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return err + } + + config := tls.Config{ + Certificates: []tls.Certificate{cert}, + } + + server := &Server{ + Addr: addr, + Net: "tcp-tls", + TLSConfig: &config, + Handler: handler, + } + + return server.ListenAndServe() +} + +// ActivateAndServe activates a server with a listener from systemd, +// l and p should not both be non-nil. +// If both l and p are not nil only p will be used. +// Invoke handler for incoming queries. +func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error { + server := &Server{Listener: l, PacketConn: p, Handler: handler} + return server.ActivateAndServe() +} + +// Writer writes raw DNS messages; each call to Write should send an entire message. +type Writer interface { + io.Writer +} + +// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message. +type Reader interface { + // ReadTCP reads a raw message from a TCP connection. Implementations may alter + // connection properties, for example the read-deadline. + ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) + // ReadUDP reads a raw message from a UDP connection. Implementations may alter + // connection properties, for example the read-deadline. + ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) +} + +// defaultReader is an adapter for the Server struct that implements the Reader interface +// using the readTCP and readUDP func of the embedded Server. +type defaultReader struct { + *Server +} + +func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { + return dr.readTCP(conn, timeout) +} + +func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { + return dr.readUDP(conn, timeout) +} + +// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader. +// Implementations should never return a nil Reader. +type DecorateReader func(Reader) Reader + +// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer. +// Implementations should never return a nil Writer. +type DecorateWriter func(Writer) Writer + +// A Server defines parameters for running an DNS server. +type Server struct { + // Address to listen on, ":dns" if empty. + Addr string + // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one + Net string + // TCP Listener to use, this is to aid in systemd's socket activation. + Listener net.Listener + // TLS connection configuration + TLSConfig *tls.Config + // UDP "Listener" to use, this is to aid in systemd's socket activation. + PacketConn net.PacketConn + // Handler to invoke, dns.DefaultServeMux if nil. + Handler Handler + // Default buffer size to use to read incoming UDP messages. If not set + // it defaults to MinMsgSize (512 B). + UDPSize int + // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second. + ReadTimeout time.Duration + // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second. + WriteTimeout time.Duration + // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966). + IdleTimeout func() time.Duration + // Secret(s) for Tsig map[]. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2). + TsigSecret map[string]string + // If NotifyStartedFunc is set it is called once the server has started listening. + NotifyStartedFunc func() + // DecorateReader is optional, allows customization of the process that reads raw DNS messages. + DecorateReader DecorateReader + // DecorateWriter is optional, allows customization of the process that writes raw DNS messages. + DecorateWriter DecorateWriter + // Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1). + MaxTCPQueries int + // Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address. + // It is only supported on go1.11+ and when using ListenAndServe. + ReusePort bool + // AcceptMsgFunc will check the incoming message and will reject it early in the process. + // By default DefaultMsgAcceptFunc will be used. + MsgAcceptFunc MsgAcceptFunc + + // Shutdown handling + lock sync.RWMutex + started bool + shutdown chan struct{} + conns map[net.Conn]struct{} + + // A pool for UDP message buffers. + udpPool sync.Pool +} + +func (srv *Server) isStarted() bool { + srv.lock.RLock() + started := srv.started + srv.lock.RUnlock() + return started +} + +func makeUDPBuffer(size int) func() interface{} { + return func() interface{} { + return make([]byte, size) + } +} + +func (srv *Server) init() { + srv.shutdown = make(chan struct{}) + srv.conns = make(map[net.Conn]struct{}) + + if srv.UDPSize == 0 { + srv.UDPSize = MinMsgSize + } + if srv.MsgAcceptFunc == nil { + srv.MsgAcceptFunc = DefaultMsgAcceptFunc + } + if srv.Handler == nil { + srv.Handler = DefaultServeMux + } + + srv.udpPool.New = makeUDPBuffer(srv.UDPSize) +} + +func unlockOnce(l sync.Locker) func() { + var once sync.Once + return func() { once.Do(l.Unlock) } +} + +// ListenAndServe starts a nameserver on the configured address in *Server. +func (srv *Server) ListenAndServe() error { + unlock := unlockOnce(&srv.lock) + srv.lock.Lock() + defer unlock() + + if srv.started { + return &Error{err: "server already started"} + } + + addr := srv.Addr + if addr == "" { + addr = ":domain" + } + + srv.init() + + switch srv.Net { + case "tcp", "tcp4", "tcp6": + l, err := listenTCP(srv.Net, addr, srv.ReusePort) + if err != nil { + return err + } + srv.Listener = l + srv.started = true + unlock() + return srv.serveTCP(l) + case "tcp-tls", "tcp4-tls", "tcp6-tls": + if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) { + return errors.New("dns: neither Certificates nor GetCertificate set in Config") + } + network := strings.TrimSuffix(srv.Net, "-tls") + l, err := listenTCP(network, addr, srv.ReusePort) + if err != nil { + return err + } + l = tls.NewListener(l, srv.TLSConfig) + srv.Listener = l + srv.started = true + unlock() + return srv.serveTCP(l) + case "udp", "udp4", "udp6": + l, err := listenUDP(srv.Net, addr, srv.ReusePort) + if err != nil { + return err + } + u := l.(*net.UDPConn) + if e := setUDPSocketOptions(u); e != nil { + return e + } + srv.PacketConn = l + srv.started = true + unlock() + return srv.serveUDP(u) + } + return &Error{err: "bad network"} +} + +// ActivateAndServe starts a nameserver with the PacketConn or Listener +// configured in *Server. Its main use is to start a server from systemd. +func (srv *Server) ActivateAndServe() error { + unlock := unlockOnce(&srv.lock) + srv.lock.Lock() + defer unlock() + + if srv.started { + return &Error{err: "server already started"} + } + + srv.init() + + pConn := srv.PacketConn + l := srv.Listener + if pConn != nil { + // Check PacketConn interface's type is valid and value + // is not nil + if t, ok := pConn.(*net.UDPConn); ok && t != nil { + if e := setUDPSocketOptions(t); e != nil { + return e + } + srv.started = true + unlock() + return srv.serveUDP(t) + } + } + if l != nil { + srv.started = true + unlock() + return srv.serveTCP(l) + } + return &Error{err: "bad listeners"} +} + +// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and +// ActivateAndServe will return. +func (srv *Server) Shutdown() error { + return srv.ShutdownContext(context.Background()) +} + +// ShutdownContext shuts down a server. After a call to ShutdownContext, +// ListenAndServe and ActivateAndServe will return. +// +// A context.Context may be passed to limit how long to wait for connections +// to terminate. +func (srv *Server) ShutdownContext(ctx context.Context) error { + srv.lock.Lock() + if !srv.started { + srv.lock.Unlock() + return &Error{err: "server not started"} + } + + srv.started = false + + if srv.PacketConn != nil { + srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads + } + + if srv.Listener != nil { + srv.Listener.Close() + } + + for rw := range srv.conns { + rw.SetReadDeadline(aLongTimeAgo) // Unblock reads + } + + srv.lock.Unlock() + + if testShutdownNotify != nil { + testShutdownNotify.Broadcast() + } + + var ctxErr error + select { + case <-srv.shutdown: + case <-ctx.Done(): + ctxErr = ctx.Err() + } + + if srv.PacketConn != nil { + srv.PacketConn.Close() + } + + return ctxErr +} + +var testShutdownNotify *sync.Cond + +// getReadTimeout is a helper func to use system timeout if server did not intend to change it. +func (srv *Server) getReadTimeout() time.Duration { + if srv.ReadTimeout != 0 { + return srv.ReadTimeout + } + return dnsTimeout +} + +// serveTCP starts a TCP listener for the server. +func (srv *Server) serveTCP(l net.Listener) error { + defer l.Close() + + if srv.NotifyStartedFunc != nil { + srv.NotifyStartedFunc() + } + + var wg sync.WaitGroup + defer func() { + wg.Wait() + close(srv.shutdown) + }() + + for srv.isStarted() { + rw, err := l.Accept() + if err != nil { + if !srv.isStarted() { + return nil + } + if neterr, ok := err.(net.Error); ok && neterr.Temporary() { + continue + } + return err + } + srv.lock.Lock() + // Track the connection to allow unblocking reads on shutdown. + srv.conns[rw] = struct{}{} + srv.lock.Unlock() + wg.Add(1) + go srv.serveTCPConn(&wg, rw) + } + + return nil +} + +// serveUDP starts a UDP listener for the server. +func (srv *Server) serveUDP(l *net.UDPConn) error { + defer l.Close() + + if srv.NotifyStartedFunc != nil { + srv.NotifyStartedFunc() + } + + reader := Reader(defaultReader{srv}) + if srv.DecorateReader != nil { + reader = srv.DecorateReader(reader) + } + + var wg sync.WaitGroup + defer func() { + wg.Wait() + close(srv.shutdown) + }() + + rtimeout := srv.getReadTimeout() + // deadline is not used here + for srv.isStarted() { + m, s, err := reader.ReadUDP(l, rtimeout) + if err != nil { + if !srv.isStarted() { + return nil + } + if netErr, ok := err.(net.Error); ok && netErr.Temporary() { + continue + } + return err + } + if len(m) < headerSize { + if cap(m) == srv.UDPSize { + srv.udpPool.Put(m[:srv.UDPSize]) + } + continue + } + wg.Add(1) + go srv.serveUDPPacket(&wg, m, l, s) + } + + return nil +} + +// Serve a new TCP connection. +func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) { + w := &response{tsigSecret: srv.TsigSecret, tcp: rw} + if srv.DecorateWriter != nil { + w.writer = srv.DecorateWriter(w) + } else { + w.writer = w + } + + reader := Reader(defaultReader{srv}) + if srv.DecorateReader != nil { + reader = srv.DecorateReader(reader) + } + + idleTimeout := tcpIdleTimeout + if srv.IdleTimeout != nil { + idleTimeout = srv.IdleTimeout() + } + + timeout := srv.getReadTimeout() + + limit := srv.MaxTCPQueries + if limit == 0 { + limit = maxTCPQueries + } + + for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ { + m, err := reader.ReadTCP(w.tcp, timeout) + if err != nil { + // TODO(tmthrgd): handle error + break + } + srv.serveDNS(m, w) + if w.closed { + break // Close() was called + } + if w.hijacked { + break // client will call Close() themselves + } + // The first read uses the read timeout, the rest use the + // idle timeout. + timeout = idleTimeout + } + + if !w.hijacked { + w.Close() + } + + srv.lock.Lock() + delete(srv.conns, w.tcp) + srv.lock.Unlock() + + wg.Done() +} + +// Serve a new UDP request. +func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u *net.UDPConn, s *SessionUDP) { + w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: s} + if srv.DecorateWriter != nil { + w.writer = srv.DecorateWriter(w) + } else { + w.writer = w + } + + srv.serveDNS(m, w) + wg.Done() +} + +func (srv *Server) serveDNS(m []byte, w *response) { + dh, off, err := unpackMsgHdr(m, 0) + if err != nil { + // Let client hang, they are sending crap; any reply can be used to amplify. + return + } + + req := new(Msg) + req.setHdr(dh) + + switch srv.MsgAcceptFunc(dh) { + case MsgAccept: + if req.unpack(dh, m, off) == nil { + break + } + + fallthrough + case MsgReject: + req.SetRcodeFormatError(req) + // Are we allowed to delete any OPT records here? + req.Ns, req.Answer, req.Extra = nil, nil, nil + req.Zero = false + + w.WriteMsg(req) + fallthrough + case MsgIgnore: + if w.udp != nil && cap(m) == srv.UDPSize { + srv.udpPool.Put(m[:srv.UDPSize]) + } + + return + } + + w.tsigStatus = nil + if w.tsigSecret != nil { + if t := req.IsTsig(); t != nil { + if secret, ok := w.tsigSecret[t.Hdr.Name]; ok { + w.tsigStatus = TsigVerify(m, secret, "", false) + } else { + w.tsigStatus = ErrSecret + } + w.tsigTimersOnly = false + w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC + } + } + + if w.udp != nil && cap(m) == srv.UDPSize { + srv.udpPool.Put(m[:srv.UDPSize]) + } + + srv.Handler.ServeDNS(w, req) // Writes back to the client +} + +func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { + // If we race with ShutdownContext, the read deadline may + // have been set in the distant past to unblock the read + // below. We must not override it, otherwise we may block + // ShutdownContext. + srv.lock.RLock() + if srv.started { + conn.SetReadDeadline(time.Now().Add(timeout)) + } + srv.lock.RUnlock() + + var length uint16 + if err := binary.Read(conn, binary.BigEndian, &length); err != nil { + return nil, err + } + + m := make([]byte, length) + if _, err := io.ReadFull(conn, m); err != nil { + return nil, err + } + + return m, nil +} + +func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { + srv.lock.RLock() + if srv.started { + // See the comment in readTCP above. + conn.SetReadDeadline(time.Now().Add(timeout)) + } + srv.lock.RUnlock() + + m := srv.udpPool.Get().([]byte) + n, s, err := ReadFromSessionUDP(conn, m) + if err != nil { + srv.udpPool.Put(m) + return nil, nil, err + } + m = m[:n] + return m, s, nil +} + +// WriteMsg implements the ResponseWriter.WriteMsg method. +func (w *response) WriteMsg(m *Msg) (err error) { + if w.closed { + return &Error{err: "WriteMsg called after Close"} + } + + var data []byte + if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check) + if t := m.IsTsig(); t != nil { + data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly) + if err != nil { + return err + } + _, err = w.writer.Write(data) + return err + } + } + data, err = m.Pack() + if err != nil { + return err + } + _, err = w.writer.Write(data) + return err +} + +// Write implements the ResponseWriter.Write method. +func (w *response) Write(m []byte) (int, error) { + if w.closed { + return 0, &Error{err: "Write called after Close"} + } + + switch { + case w.udp != nil: + return WriteToSessionUDP(w.udp, m, w.udpSession) + case w.tcp != nil: + if len(m) > MaxMsgSize { + return 0, &Error{err: "message too large"} + } + + l := make([]byte, 2) + binary.BigEndian.PutUint16(l, uint16(len(m))) + + n, err := (&net.Buffers{l, m}).WriteTo(w.tcp) + return int(n), err + default: + panic("dns: internal error: udp and tcp both nil") + } +} + +// LocalAddr implements the ResponseWriter.LocalAddr method. +func (w *response) LocalAddr() net.Addr { + switch { + case w.udp != nil: + return w.udp.LocalAddr() + case w.tcp != nil: + return w.tcp.LocalAddr() + default: + panic("dns: internal error: udp and tcp both nil") + } +} + +// RemoteAddr implements the ResponseWriter.RemoteAddr method. +func (w *response) RemoteAddr() net.Addr { + switch { + case w.udpSession != nil: + return w.udpSession.RemoteAddr() + case w.tcp != nil: + return w.tcp.RemoteAddr() + default: + panic("dns: internal error: udpSession and tcp both nil") + } +} + +// TsigStatus implements the ResponseWriter.TsigStatus method. +func (w *response) TsigStatus() error { return w.tsigStatus } + +// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method. +func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b } + +// Hijack implements the ResponseWriter.Hijack method. +func (w *response) Hijack() { w.hijacked = true } + +// Close implements the ResponseWriter.Close method +func (w *response) Close() error { + if w.closed { + return &Error{err: "connection already closed"} + } + w.closed = true + + switch { + case w.udp != nil: + // Can't close the udp conn, as that is actually the listener. + return nil + case w.tcp != nil: + return w.tcp.Close() + default: + panic("dns: internal error: udp and tcp both nil") + } +} + +// ConnectionState() implements the ConnectionStater.ConnectionState() interface. +func (w *response) ConnectionState() *tls.ConnectionState { + type tlsConnectionStater interface { + ConnectionState() tls.ConnectionState + } + if v, ok := w.tcp.(tlsConnectionStater); ok { + t := v.ConnectionState() + return &t + } + return nil +} diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go new file mode 100644 index 00000000..55cf1c38 --- /dev/null +++ b/vendor/github.com/miekg/dns/sig0.go @@ -0,0 +1,209 @@ +package dns + +import ( + "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/rsa" + "encoding/binary" + "math/big" + "strings" + "time" +) + +// Sign signs a dns.Msg. It fills the signature with the appropriate data. +// The SIG record should have the SignerName, KeyTag, Algorithm, Inception +// and Expiration set. +func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) { + if k == nil { + return nil, ErrPrivKey + } + if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { + return nil, ErrKey + } + + rr.Hdr = RR_Header{Name: ".", Rrtype: TypeSIG, Class: ClassANY, Ttl: 0} + rr.OrigTtl, rr.TypeCovered, rr.Labels = 0, 0, 0 + + buf := make([]byte, m.Len()+Len(rr)) + mbuf, err := m.PackBuffer(buf) + if err != nil { + return nil, err + } + if &buf[0] != &mbuf[0] { + return nil, ErrBuf + } + off, err := PackRR(rr, buf, len(mbuf), nil, false) + if err != nil { + return nil, err + } + buf = buf[:off:cap(buf)] + + hash, ok := AlgorithmToHash[rr.Algorithm] + if !ok { + return nil, ErrAlg + } + + hasher := hash.New() + // Write SIG rdata + hasher.Write(buf[len(mbuf)+1+2+2+4+2:]) + // Write message + hasher.Write(buf[:len(mbuf)]) + + signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm) + if err != nil { + return nil, err + } + + rr.Signature = toBase64(signature) + + buf = append(buf, signature...) + if len(buf) > int(^uint16(0)) { + return nil, ErrBuf + } + // Adjust sig data length + rdoff := len(mbuf) + 1 + 2 + 2 + 4 + rdlen := binary.BigEndian.Uint16(buf[rdoff:]) + rdlen += uint16(len(signature)) + binary.BigEndian.PutUint16(buf[rdoff:], rdlen) + // Adjust additional count + adc := binary.BigEndian.Uint16(buf[10:]) + adc++ + binary.BigEndian.PutUint16(buf[10:], adc) + return buf, nil +} + +// Verify validates the message buf using the key k. +// It's assumed that buf is a valid message from which rr was unpacked. +func (rr *SIG) Verify(k *KEY, buf []byte) error { + if k == nil { + return ErrKey + } + if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { + return ErrKey + } + + var hash crypto.Hash + switch rr.Algorithm { + case DSA, RSASHA1: + hash = crypto.SHA1 + case RSASHA256, ECDSAP256SHA256: + hash = crypto.SHA256 + case ECDSAP384SHA384: + hash = crypto.SHA384 + case RSASHA512: + hash = crypto.SHA512 + default: + return ErrAlg + } + hasher := hash.New() + + buflen := len(buf) + qdc := binary.BigEndian.Uint16(buf[4:]) + anc := binary.BigEndian.Uint16(buf[6:]) + auc := binary.BigEndian.Uint16(buf[8:]) + adc := binary.BigEndian.Uint16(buf[10:]) + offset := headerSize + var err error + for i := uint16(0); i < qdc && offset < buflen; i++ { + _, offset, err = UnpackDomainName(buf, offset) + if err != nil { + return err + } + // Skip past Type and Class + offset += 2 + 2 + } + for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ { + _, offset, err = UnpackDomainName(buf, offset) + if err != nil { + return err + } + // Skip past Type, Class and TTL + offset += 2 + 2 + 4 + if offset+1 >= buflen { + continue + } + rdlen := binary.BigEndian.Uint16(buf[offset:]) + offset += 2 + offset += int(rdlen) + } + if offset >= buflen { + return &Error{err: "overflowing unpacking signed message"} + } + + // offset should be just prior to SIG + bodyend := offset + // owner name SHOULD be root + _, offset, err = UnpackDomainName(buf, offset) + if err != nil { + return err + } + // Skip Type, Class, TTL, RDLen + offset += 2 + 2 + 4 + 2 + sigstart := offset + // Skip Type Covered, Algorithm, Labels, Original TTL + offset += 2 + 1 + 1 + 4 + if offset+4+4 >= buflen { + return &Error{err: "overflow unpacking signed message"} + } + expire := binary.BigEndian.Uint32(buf[offset:]) + offset += 4 + incept := binary.BigEndian.Uint32(buf[offset:]) + offset += 4 + now := uint32(time.Now().Unix()) + if now < incept || now > expire { + return ErrTime + } + // Skip key tag + offset += 2 + var signername string + signername, offset, err = UnpackDomainName(buf, offset) + if err != nil { + return err + } + // If key has come from the DNS name compression might + // have mangled the case of the name + if !strings.EqualFold(signername, k.Header().Name) { + return &Error{err: "signer name doesn't match key name"} + } + sigend := offset + hasher.Write(buf[sigstart:sigend]) + hasher.Write(buf[:10]) + hasher.Write([]byte{ + byte((adc - 1) << 8), + byte(adc - 1), + }) + hasher.Write(buf[12:bodyend]) + + hashed := hasher.Sum(nil) + sig := buf[sigend:] + switch k.Algorithm { + case DSA: + pk := k.publicKeyDSA() + sig = sig[1:] + r := new(big.Int).SetBytes(sig[:len(sig)/2]) + s := new(big.Int).SetBytes(sig[len(sig)/2:]) + if pk != nil { + if dsa.Verify(pk, hashed, r, s) { + return nil + } + return ErrSig + } + case RSASHA1, RSASHA256, RSASHA512: + pk := k.publicKeyRSA() + if pk != nil { + return rsa.VerifyPKCS1v15(pk, hash, hashed, sig) + } + case ECDSAP256SHA256, ECDSAP384SHA384: + pk := k.publicKeyECDSA() + r := new(big.Int).SetBytes(sig[:len(sig)/2]) + s := new(big.Int).SetBytes(sig[len(sig)/2:]) + if pk != nil { + if ecdsa.Verify(pk, hashed, r, s) { + return nil + } + return ErrSig + } + } + return ErrKeyAlg +} diff --git a/vendor/github.com/miekg/dns/singleinflight.go b/vendor/github.com/miekg/dns/singleinflight.go new file mode 100644 index 00000000..febcc300 --- /dev/null +++ b/vendor/github.com/miekg/dns/singleinflight.go @@ -0,0 +1,61 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Adapted for dns package usage by Miek Gieben. + +package dns + +import "sync" +import "time" + +// call is an in-flight or completed singleflight.Do call +type call struct { + wg sync.WaitGroup + val *Msg + rtt time.Duration + err error + dups int +} + +// singleflight represents a class of work and forms a namespace in +// which units of work can be executed with duplicate suppression. +type singleflight struct { + sync.Mutex // protects m + m map[string]*call // lazily initialized + + dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges +} + +// Do executes and returns the results of the given function, making +// sure that only one execution is in-flight for a given key at a +// time. If a duplicate comes in, the duplicate caller waits for the +// original to complete and receives the same results. +// The return value shared indicates whether v was given to multiple callers. +func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) { + g.Lock() + if g.m == nil { + g.m = make(map[string]*call) + } + if c, ok := g.m[key]; ok { + c.dups++ + g.Unlock() + c.wg.Wait() + return c.val, c.rtt, c.err, true + } + c := new(call) + c.wg.Add(1) + g.m[key] = c + g.Unlock() + + c.val, c.rtt, c.err = fn() + c.wg.Done() + + if !g.dontDeleteForTesting { + g.Lock() + delete(g.m, key) + g.Unlock() + } + + return c.val, c.rtt, c.err, c.dups > 0 +} diff --git a/vendor/github.com/miekg/dns/smimea.go b/vendor/github.com/miekg/dns/smimea.go new file mode 100644 index 00000000..89f09f0d --- /dev/null +++ b/vendor/github.com/miekg/dns/smimea.go @@ -0,0 +1,44 @@ +package dns + +import ( + "crypto/sha256" + "crypto/x509" + "encoding/hex" +) + +// Sign creates a SMIMEA record from an SSL certificate. +func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { + r.Hdr.Rrtype = TypeSMIMEA + r.Usage = uint8(usage) + r.Selector = uint8(selector) + r.MatchingType = uint8(matchingType) + + r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) + return err +} + +// Verify verifies a SMIMEA record against an SSL certificate. If it is OK +// a nil error is returned. +func (r *SMIMEA) Verify(cert *x509.Certificate) error { + c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) + if err != nil { + return err // Not also ErrSig? + } + if r.Certificate == c { + return nil + } + return ErrSig // ErrSig, really? +} + +// SMIMEAName returns the ownername of a SMIMEA resource record as per the +// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3 +func SMIMEAName(email, domain string) (string, error) { + hasher := sha256.New() + hasher.Write([]byte(email)) + + // RFC Section 3: "The local-part is hashed using the SHA2-256 + // algorithm with the hash truncated to 28 octets and + // represented in its hexadecimal representation to become the + // left-most label in the prepared domain name" + return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil +} diff --git a/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/miekg/dns/tlsa.go new file mode 100644 index 00000000..4e07983b --- /dev/null +++ b/vendor/github.com/miekg/dns/tlsa.go @@ -0,0 +1,44 @@ +package dns + +import ( + "crypto/x509" + "net" + "strconv" +) + +// Sign creates a TLSA record from an SSL certificate. +func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { + r.Hdr.Rrtype = TypeTLSA + r.Usage = uint8(usage) + r.Selector = uint8(selector) + r.MatchingType = uint8(matchingType) + + r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) + return err +} + +// Verify verifies a TLSA record against an SSL certificate. If it is OK +// a nil error is returned. +func (r *TLSA) Verify(cert *x509.Certificate) error { + c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) + if err != nil { + return err // Not also ErrSig? + } + if r.Certificate == c { + return nil + } + return ErrSig // ErrSig, really? +} + +// TLSAName returns the ownername of a TLSA resource record as per the +// rules specified in RFC 6698, Section 3. +func TLSAName(name, service, network string) (string, error) { + if !IsFqdn(name) { + return "", ErrFqdn + } + p, err := net.LookupPort(network, service) + if err != nil { + return "", err + } + return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil +} diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go new file mode 100644 index 00000000..2c4ef03b --- /dev/null +++ b/vendor/github.com/miekg/dns/tsig.go @@ -0,0 +1,389 @@ +package dns + +import ( + "crypto/hmac" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/binary" + "encoding/hex" + "hash" + "strconv" + "strings" + "time" +) + +// HMAC hashing codes. These are transmitted as domain names. +const ( + HmacMD5 = "hmac-md5.sig-alg.reg.int." + HmacSHA1 = "hmac-sha1." + HmacSHA256 = "hmac-sha256." + HmacSHA512 = "hmac-sha512." +) + +// TSIG is the RR the holds the transaction signature of a message. +// See RFC 2845 and RFC 4635. +type TSIG struct { + Hdr RR_Header + Algorithm string `dns:"domain-name"` + TimeSigned uint64 `dns:"uint48"` + Fudge uint16 + MACSize uint16 + MAC string `dns:"size-hex:MACSize"` + OrigId uint16 + Error uint16 + OtherLen uint16 + OtherData string `dns:"size-hex:OtherLen"` +} + +// TSIG has no official presentation format, but this will suffice. + +func (rr *TSIG) String() string { + s := "\n;; TSIG PSEUDOSECTION:\n" + s += rr.Hdr.String() + + " " + rr.Algorithm + + " " + tsigTimeToString(rr.TimeSigned) + + " " + strconv.Itoa(int(rr.Fudge)) + + " " + strconv.Itoa(int(rr.MACSize)) + + " " + strings.ToUpper(rr.MAC) + + " " + strconv.Itoa(int(rr.OrigId)) + + " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR + " " + strconv.Itoa(int(rr.OtherLen)) + + " " + rr.OtherData + return s +} + +func (rr *TSIG) parse(c *zlexer, origin string) *ParseError { + panic("dns: internal error: parse should never be called on TSIG") +} + +// The following values must be put in wireformat, so that the MAC can be calculated. +// RFC 2845, section 3.4.2. TSIG Variables. +type tsigWireFmt struct { + // From RR_Header + Name string `dns:"domain-name"` + Class uint16 + Ttl uint32 + // Rdata of the TSIG + Algorithm string `dns:"domain-name"` + TimeSigned uint64 `dns:"uint48"` + Fudge uint16 + // MACSize, MAC and OrigId excluded + Error uint16 + OtherLen uint16 + OtherData string `dns:"size-hex:OtherLen"` +} + +// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC +type macWireFmt struct { + MACSize uint16 + MAC string `dns:"size-hex:MACSize"` +} + +// 3.3. Time values used in TSIG calculations +type timerWireFmt struct { + TimeSigned uint64 `dns:"uint48"` + Fudge uint16 +} + +// TsigGenerate fills out the TSIG record attached to the message. +// The message should contain +// a "stub" TSIG RR with the algorithm, key name (owner name of the RR), +// time fudge (defaults to 300 seconds) and the current time +// The TSIG MAC is saved in that Tsig RR. +// When TsigGenerate is called for the first time requestMAC is set to the empty string and +// timersOnly is false. +// If something goes wrong an error is returned, otherwise it is nil. +func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { + if m.IsTsig() == nil { + panic("dns: TSIG not last RR in additional") + } + // If we barf here, the caller is to blame + rawsecret, err := fromBase64([]byte(secret)) + if err != nil { + return nil, "", err + } + + rr := m.Extra[len(m.Extra)-1].(*TSIG) + m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg + mbuf, err := m.Pack() + if err != nil { + return nil, "", err + } + buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly) + + t := new(TSIG) + var h hash.Hash + switch strings.ToLower(rr.Algorithm) { + case HmacMD5: + h = hmac.New(md5.New, rawsecret) + case HmacSHA1: + h = hmac.New(sha1.New, rawsecret) + case HmacSHA256: + h = hmac.New(sha256.New, rawsecret) + case HmacSHA512: + h = hmac.New(sha512.New, rawsecret) + default: + return nil, "", ErrKeyAlg + } + h.Write(buf) + t.MAC = hex.EncodeToString(h.Sum(nil)) + t.MACSize = uint16(len(t.MAC) / 2) // Size is half! + + t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0} + t.Fudge = rr.Fudge + t.TimeSigned = rr.TimeSigned + t.Algorithm = rr.Algorithm + t.OrigId = m.Id + + tbuf := make([]byte, Len(t)) + off, err := PackRR(t, tbuf, 0, nil, false) + if err != nil { + return nil, "", err + } + mbuf = append(mbuf, tbuf[:off]...) + // Update the ArCount directly in the buffer. + binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1)) + + return mbuf, t.MAC, nil +} + +// TsigVerify verifies the TSIG on a message. +// If the signature does not validate err contains the +// error, otherwise it is nil. +func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error { + rawsecret, err := fromBase64([]byte(secret)) + if err != nil { + return err + } + // Strip the TSIG from the incoming msg + stripped, tsig, err := stripTsig(msg) + if err != nil { + return err + } + + msgMAC, err := hex.DecodeString(tsig.MAC) + if err != nil { + return err + } + + buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly) + + // Fudge factor works both ways. A message can arrive before it was signed because + // of clock skew. + now := uint64(time.Now().Unix()) + ti := now - tsig.TimeSigned + if now < tsig.TimeSigned { + ti = tsig.TimeSigned - now + } + if uint64(tsig.Fudge) < ti { + return ErrTime + } + + var h hash.Hash + switch strings.ToLower(tsig.Algorithm) { + case HmacMD5: + h = hmac.New(md5.New, rawsecret) + case HmacSHA1: + h = hmac.New(sha1.New, rawsecret) + case HmacSHA256: + h = hmac.New(sha256.New, rawsecret) + case HmacSHA512: + h = hmac.New(sha512.New, rawsecret) + default: + return ErrKeyAlg + } + h.Write(buf) + if !hmac.Equal(h.Sum(nil), msgMAC) { + return ErrSig + } + return nil +} + +// Create a wiredata buffer for the MAC calculation. +func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte { + var buf []byte + if rr.TimeSigned == 0 { + rr.TimeSigned = uint64(time.Now().Unix()) + } + if rr.Fudge == 0 { + rr.Fudge = 300 // Standard (RFC) default. + } + + // Replace message ID in header with original ID from TSIG + binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId) + + if requestMAC != "" { + m := new(macWireFmt) + m.MACSize = uint16(len(requestMAC) / 2) + m.MAC = requestMAC + buf = make([]byte, len(requestMAC)) // long enough + n, _ := packMacWire(m, buf) + buf = buf[:n] + } + + tsigvar := make([]byte, DefaultMsgSize) + if timersOnly { + tsig := new(timerWireFmt) + tsig.TimeSigned = rr.TimeSigned + tsig.Fudge = rr.Fudge + n, _ := packTimerWire(tsig, tsigvar) + tsigvar = tsigvar[:n] + } else { + tsig := new(tsigWireFmt) + tsig.Name = strings.ToLower(rr.Hdr.Name) + tsig.Class = ClassANY + tsig.Ttl = rr.Hdr.Ttl + tsig.Algorithm = strings.ToLower(rr.Algorithm) + tsig.TimeSigned = rr.TimeSigned + tsig.Fudge = rr.Fudge + tsig.Error = rr.Error + tsig.OtherLen = rr.OtherLen + tsig.OtherData = rr.OtherData + n, _ := packTsigWire(tsig, tsigvar) + tsigvar = tsigvar[:n] + } + + if requestMAC != "" { + x := append(buf, msgbuf...) + buf = append(x, tsigvar...) + } else { + buf = append(msgbuf, tsigvar...) + } + return buf +} + +// Strip the TSIG from the raw message. +func stripTsig(msg []byte) ([]byte, *TSIG, error) { + // Copied from msg.go's Unpack() Header, but modified. + var ( + dh Header + err error + ) + off, tsigoff := 0, 0 + + if dh, off, err = unpackMsgHdr(msg, off); err != nil { + return nil, nil, err + } + if dh.Arcount == 0 { + return nil, nil, ErrNoSig + } + + // Rcode, see msg.go Unpack() + if int(dh.Bits&0xF) == RcodeNotAuth { + return nil, nil, ErrAuth + } + + for i := 0; i < int(dh.Qdcount); i++ { + _, off, err = unpackQuestion(msg, off) + if err != nil { + return nil, nil, err + } + } + + _, off, err = unpackRRslice(int(dh.Ancount), msg, off) + if err != nil { + return nil, nil, err + } + _, off, err = unpackRRslice(int(dh.Nscount), msg, off) + if err != nil { + return nil, nil, err + } + + rr := new(TSIG) + var extra RR + for i := 0; i < int(dh.Arcount); i++ { + tsigoff = off + extra, off, err = UnpackRR(msg, off) + if err != nil { + return nil, nil, err + } + if extra.Header().Rrtype == TypeTSIG { + rr = extra.(*TSIG) + // Adjust Arcount. + arcount := binary.BigEndian.Uint16(msg[10:]) + binary.BigEndian.PutUint16(msg[10:], arcount-1) + break + } + } + if rr == nil { + return nil, nil, ErrNoSig + } + return msg[:tsigoff], rr, nil +} + +// Translate the TSIG time signed into a date. There is no +// need for RFC1982 calculations as this date is 48 bits. +func tsigTimeToString(t uint64) string { + ti := time.Unix(int64(t), 0).UTC() + return ti.Format("20060102150405") +} + +func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) { + // copied from zmsg.go TSIG packing + // RR_Header + off, err := PackDomainName(tw.Name, msg, 0, nil, false) + if err != nil { + return off, err + } + off, err = packUint16(tw.Class, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(tw.Ttl, msg, off) + if err != nil { + return off, err + } + + off, err = PackDomainName(tw.Algorithm, msg, off, nil, false) + if err != nil { + return off, err + } + off, err = packUint48(tw.TimeSigned, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(tw.Fudge, msg, off) + if err != nil { + return off, err + } + + off, err = packUint16(tw.Error, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(tw.OtherLen, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(tw.OtherData, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func packMacWire(mw *macWireFmt, msg []byte) (int, error) { + off, err := packUint16(mw.MACSize, msg, 0) + if err != nil { + return off, err + } + off, err = packStringHex(mw.MAC, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) { + off, err := packUint48(tw.TimeSigned, msg, 0) + if err != nil { + return off, err + } + off, err = packUint16(tw.Fudge, msg, off) + if err != nil { + return off, err + } + return off, nil +} diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go new file mode 100644 index 00000000..6f79038b --- /dev/null +++ b/vendor/github.com/miekg/dns/types.go @@ -0,0 +1,1413 @@ +package dns + +import ( + "fmt" + "net" + "strconv" + "strings" + "time" +) + +type ( + // Type is a DNS type. + Type uint16 + // Class is a DNS class. + Class uint16 + // Name is a DNS domain name. + Name string +) + +// Packet formats + +// Wire constants and supported types. +const ( + // valid RR_Header.Rrtype and Question.qtype + + TypeNone uint16 = 0 + TypeA uint16 = 1 + TypeNS uint16 = 2 + TypeMD uint16 = 3 + TypeMF uint16 = 4 + TypeCNAME uint16 = 5 + TypeSOA uint16 = 6 + TypeMB uint16 = 7 + TypeMG uint16 = 8 + TypeMR uint16 = 9 + TypeNULL uint16 = 10 + TypePTR uint16 = 12 + TypeHINFO uint16 = 13 + TypeMINFO uint16 = 14 + TypeMX uint16 = 15 + TypeTXT uint16 = 16 + TypeRP uint16 = 17 + TypeAFSDB uint16 = 18 + TypeX25 uint16 = 19 + TypeISDN uint16 = 20 + TypeRT uint16 = 21 + TypeNSAPPTR uint16 = 23 + TypeSIG uint16 = 24 + TypeKEY uint16 = 25 + TypePX uint16 = 26 + TypeGPOS uint16 = 27 + TypeAAAA uint16 = 28 + TypeLOC uint16 = 29 + TypeNXT uint16 = 30 + TypeEID uint16 = 31 + TypeNIMLOC uint16 = 32 + TypeSRV uint16 = 33 + TypeATMA uint16 = 34 + TypeNAPTR uint16 = 35 + TypeKX uint16 = 36 + TypeCERT uint16 = 37 + TypeDNAME uint16 = 39 + TypeOPT uint16 = 41 // EDNS + TypeDS uint16 = 43 + TypeSSHFP uint16 = 44 + TypeRRSIG uint16 = 46 + TypeNSEC uint16 = 47 + TypeDNSKEY uint16 = 48 + TypeDHCID uint16 = 49 + TypeNSEC3 uint16 = 50 + TypeNSEC3PARAM uint16 = 51 + TypeTLSA uint16 = 52 + TypeSMIMEA uint16 = 53 + TypeHIP uint16 = 55 + TypeNINFO uint16 = 56 + TypeRKEY uint16 = 57 + TypeTALINK uint16 = 58 + TypeCDS uint16 = 59 + TypeCDNSKEY uint16 = 60 + TypeOPENPGPKEY uint16 = 61 + TypeCSYNC uint16 = 62 + TypeSPF uint16 = 99 + TypeUINFO uint16 = 100 + TypeUID uint16 = 101 + TypeGID uint16 = 102 + TypeUNSPEC uint16 = 103 + TypeNID uint16 = 104 + TypeL32 uint16 = 105 + TypeL64 uint16 = 106 + TypeLP uint16 = 107 + TypeEUI48 uint16 = 108 + TypeEUI64 uint16 = 109 + TypeURI uint16 = 256 + TypeCAA uint16 = 257 + TypeAVC uint16 = 258 + + TypeTKEY uint16 = 249 + TypeTSIG uint16 = 250 + + // valid Question.Qtype only + TypeIXFR uint16 = 251 + TypeAXFR uint16 = 252 + TypeMAILB uint16 = 253 + TypeMAILA uint16 = 254 + TypeANY uint16 = 255 + + TypeTA uint16 = 32768 + TypeDLV uint16 = 32769 + TypeReserved uint16 = 65535 + + // valid Question.Qclass + ClassINET = 1 + ClassCSNET = 2 + ClassCHAOS = 3 + ClassHESIOD = 4 + ClassNONE = 254 + ClassANY = 255 + + // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml + RcodeSuccess = 0 // NoError - No Error [DNS] + RcodeFormatError = 1 // FormErr - Format Error [DNS] + RcodeServerFailure = 2 // ServFail - Server Failure [DNS] + RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS] + RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS] + RcodeRefused = 5 // Refused - Query Refused [DNS] + RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update] + RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update] + RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update] + RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update] + RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG] + RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG] + RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0] + RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG] + RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG] + RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY] + RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY] + RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY] + RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG] + RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies] + + // Message Opcodes. There is no 3. + OpcodeQuery = 0 + OpcodeIQuery = 1 + OpcodeStatus = 2 + OpcodeNotify = 4 + OpcodeUpdate = 5 +) + +// Header is the wire format for the DNS packet header. +type Header struct { + Id uint16 + Bits uint16 + Qdcount, Ancount, Nscount, Arcount uint16 +} + +const ( + headerSize = 12 + + // Header.Bits + _QR = 1 << 15 // query/response (response=1) + _AA = 1 << 10 // authoritative + _TC = 1 << 9 // truncated + _RD = 1 << 8 // recursion desired + _RA = 1 << 7 // recursion available + _Z = 1 << 6 // Z + _AD = 1 << 5 // authticated data + _CD = 1 << 4 // checking disabled +) + +// Various constants used in the LOC RR, See RFC 1887. +const ( + LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2. + LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2. + LOC_HOURS = 60 * 1000 + LOC_DEGREES = 60 * LOC_HOURS + LOC_ALTITUDEBASE = 100000 +) + +// Different Certificate Types, see RFC 4398, Section 2.1 +const ( + CertPKIX = 1 + iota + CertSPKI + CertPGP + CertIPIX + CertISPKI + CertIPGP + CertACPKIX + CertIACPKIX + CertURI = 253 + CertOID = 254 +) + +// CertTypeToString converts the Cert Type to its string representation. +// See RFC 4398 and RFC 6944. +var CertTypeToString = map[uint16]string{ + CertPKIX: "PKIX", + CertSPKI: "SPKI", + CertPGP: "PGP", + CertIPIX: "IPIX", + CertISPKI: "ISPKI", + CertIPGP: "IPGP", + CertACPKIX: "ACPKIX", + CertIACPKIX: "IACPKIX", + CertURI: "URI", + CertOID: "OID", +} + +//go:generate go run types_generate.go + +// Question holds a DNS question. There can be multiple questions in the +// question section of a message. Usually there is just one. +type Question struct { + Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed) + Qtype uint16 + Qclass uint16 +} + +func (q *Question) len(off int, compression map[string]struct{}) int { + l := domainNameLen(q.Name, off, compression, true) + l += 2 + 2 + return l +} + +func (q *Question) String() (s string) { + // prefix with ; (as in dig) + s = ";" + sprintName(q.Name) + "\t" + s += Class(q.Qclass).String() + "\t" + s += " " + Type(q.Qtype).String() + return s +} + +// ANY is a wildcard record. See RFC 1035, Section 3.2.3. ANY +// is named "*" there. +type ANY struct { + Hdr RR_Header + // Does not have any rdata +} + +func (rr *ANY) String() string { return rr.Hdr.String() } + +func (rr *ANY) parse(c *zlexer, origin string) *ParseError { + panic("dns: internal error: parse should never be called on ANY") +} + +// NULL RR. See RFC 1035. +type NULL struct { + Hdr RR_Header + Data string `dns:"any"` +} + +func (rr *NULL) String() string { + // There is no presentation format; prefix string with a comment. + return ";" + rr.Hdr.String() + rr.Data +} + +func (rr *NULL) parse(c *zlexer, origin string) *ParseError { + panic("dns: internal error: parse should never be called on NULL") +} + +// CNAME RR. See RFC 1034. +type CNAME struct { + Hdr RR_Header + Target string `dns:"cdomain-name"` +} + +func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) } + +// HINFO RR. See RFC 1034. +type HINFO struct { + Hdr RR_Header + Cpu string + Os string +} + +func (rr *HINFO) String() string { + return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os}) +} + +// MB RR. See RFC 1035. +type MB struct { + Hdr RR_Header + Mb string `dns:"cdomain-name"` +} + +func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) } + +// MG RR. See RFC 1035. +type MG struct { + Hdr RR_Header + Mg string `dns:"cdomain-name"` +} + +func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) } + +// MINFO RR. See RFC 1035. +type MINFO struct { + Hdr RR_Header + Rmail string `dns:"cdomain-name"` + Email string `dns:"cdomain-name"` +} + +func (rr *MINFO) String() string { + return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email) +} + +// MR RR. See RFC 1035. +type MR struct { + Hdr RR_Header + Mr string `dns:"cdomain-name"` +} + +func (rr *MR) String() string { + return rr.Hdr.String() + sprintName(rr.Mr) +} + +// MF RR. See RFC 1035. +type MF struct { + Hdr RR_Header + Mf string `dns:"cdomain-name"` +} + +func (rr *MF) String() string { + return rr.Hdr.String() + sprintName(rr.Mf) +} + +// MD RR. See RFC 1035. +type MD struct { + Hdr RR_Header + Md string `dns:"cdomain-name"` +} + +func (rr *MD) String() string { + return rr.Hdr.String() + sprintName(rr.Md) +} + +// MX RR. See RFC 1035. +type MX struct { + Hdr RR_Header + Preference uint16 + Mx string `dns:"cdomain-name"` +} + +func (rr *MX) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx) +} + +// AFSDB RR. See RFC 1183. +type AFSDB struct { + Hdr RR_Header + Subtype uint16 + Hostname string `dns:"domain-name"` +} + +func (rr *AFSDB) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname) +} + +// X25 RR. See RFC 1183, Section 3.1. +type X25 struct { + Hdr RR_Header + PSDNAddress string +} + +func (rr *X25) String() string { + return rr.Hdr.String() + rr.PSDNAddress +} + +// RT RR. See RFC 1183, Section 3.3. +type RT struct { + Hdr RR_Header + Preference uint16 + Host string `dns:"domain-name"` // RFC 3597 prohibits compressing records not defined in RFC 1035. +} + +func (rr *RT) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host) +} + +// NS RR. See RFC 1035. +type NS struct { + Hdr RR_Header + Ns string `dns:"cdomain-name"` +} + +func (rr *NS) String() string { + return rr.Hdr.String() + sprintName(rr.Ns) +} + +// PTR RR. See RFC 1035. +type PTR struct { + Hdr RR_Header + Ptr string `dns:"cdomain-name"` +} + +func (rr *PTR) String() string { + return rr.Hdr.String() + sprintName(rr.Ptr) +} + +// RP RR. See RFC 1138, Section 2.2. +type RP struct { + Hdr RR_Header + Mbox string `dns:"domain-name"` + Txt string `dns:"domain-name"` +} + +func (rr *RP) String() string { + return rr.Hdr.String() + sprintName(rr.Mbox) + " " + sprintName(rr.Txt) +} + +// SOA RR. See RFC 1035. +type SOA struct { + Hdr RR_Header + Ns string `dns:"cdomain-name"` + Mbox string `dns:"cdomain-name"` + Serial uint32 + Refresh uint32 + Retry uint32 + Expire uint32 + Minttl uint32 +} + +func (rr *SOA) String() string { + return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) + + " " + strconv.FormatInt(int64(rr.Serial), 10) + + " " + strconv.FormatInt(int64(rr.Refresh), 10) + + " " + strconv.FormatInt(int64(rr.Retry), 10) + + " " + strconv.FormatInt(int64(rr.Expire), 10) + + " " + strconv.FormatInt(int64(rr.Minttl), 10) +} + +// TXT RR. See RFC 1035. +type TXT struct { + Hdr RR_Header + Txt []string `dns:"txt"` +} + +func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } + +func sprintName(s string) string { + var dst strings.Builder + dst.Grow(len(s)) + for i := 0; i < len(s); { + if i+1 < len(s) && s[i] == '\\' && s[i+1] == '.' { + dst.WriteString(s[i : i+2]) + i += 2 + continue + } + + b, n := nextByte(s, i) + switch { + case n == 0: + i++ // dangling back slash + case b == '.': + dst.WriteByte('.') + default: + writeDomainNameByte(&dst, b) + } + i += n + } + return dst.String() +} + +func sprintTxtOctet(s string) string { + var dst strings.Builder + dst.Grow(2 + len(s)) + dst.WriteByte('"') + for i := 0; i < len(s); { + if i+1 < len(s) && s[i] == '\\' && s[i+1] == '.' { + dst.WriteString(s[i : i+2]) + i += 2 + continue + } + + b, n := nextByte(s, i) + switch { + case n == 0: + i++ // dangling back slash + case b == '.': + dst.WriteByte('.') + case b < ' ' || b > '~': + dst.WriteString(escapeByte(b)) + default: + dst.WriteByte(b) + } + i += n + } + dst.WriteByte('"') + return dst.String() +} + +func sprintTxt(txt []string) string { + var out strings.Builder + for i, s := range txt { + out.Grow(3 + len(s)) + if i > 0 { + out.WriteString(` "`) + } else { + out.WriteByte('"') + } + for j := 0; j < len(s); { + b, n := nextByte(s, j) + if n == 0 { + break + } + writeTXTStringByte(&out, b) + j += n + } + out.WriteByte('"') + } + return out.String() +} + +func writeDomainNameByte(s *strings.Builder, b byte) { + switch b { + case '.', ' ', '\'', '@', ';', '(', ')': // additional chars to escape + s.WriteByte('\\') + s.WriteByte(b) + default: + writeTXTStringByte(s, b) + } +} + +func writeTXTStringByte(s *strings.Builder, b byte) { + switch { + case b == '"' || b == '\\': + s.WriteByte('\\') + s.WriteByte(b) + case b < ' ' || b > '~': + s.WriteString(escapeByte(b)) + default: + s.WriteByte(b) + } +} + +const ( + escapedByteSmall = "" + + `\000\001\002\003\004\005\006\007\008\009` + + `\010\011\012\013\014\015\016\017\018\019` + + `\020\021\022\023\024\025\026\027\028\029` + + `\030\031` + escapedByteLarge = `\127\128\129` + + `\130\131\132\133\134\135\136\137\138\139` + + `\140\141\142\143\144\145\146\147\148\149` + + `\150\151\152\153\154\155\156\157\158\159` + + `\160\161\162\163\164\165\166\167\168\169` + + `\170\171\172\173\174\175\176\177\178\179` + + `\180\181\182\183\184\185\186\187\188\189` + + `\190\191\192\193\194\195\196\197\198\199` + + `\200\201\202\203\204\205\206\207\208\209` + + `\210\211\212\213\214\215\216\217\218\219` + + `\220\221\222\223\224\225\226\227\228\229` + + `\230\231\232\233\234\235\236\237\238\239` + + `\240\241\242\243\244\245\246\247\248\249` + + `\250\251\252\253\254\255` +) + +// escapeByte returns the \DDD escaping of b which must +// satisfy b < ' ' || b > '~'. +func escapeByte(b byte) string { + if b < ' ' { + return escapedByteSmall[b*4 : b*4+4] + } + + b -= '~' + 1 + // The cast here is needed as b*4 may overflow byte. + return escapedByteLarge[int(b)*4 : int(b)*4+4] +} + +func nextByte(s string, offset int) (byte, int) { + if offset >= len(s) { + return 0, 0 + } + if s[offset] != '\\' { + // not an escape sequence + return s[offset], 1 + } + switch len(s) - offset { + case 1: // dangling escape + return 0, 0 + case 2, 3: // too short to be \ddd + default: // maybe \ddd + if isDigit(s[offset+1]) && isDigit(s[offset+2]) && isDigit(s[offset+3]) { + return dddStringToByte(s[offset+1:]), 4 + } + } + // not \ddd, just an RFC 1035 "quoted" character + return s[offset+1], 2 +} + +// SPF RR. See RFC 4408, Section 3.1.1. +type SPF struct { + Hdr RR_Header + Txt []string `dns:"txt"` +} + +func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } + +// AVC RR. See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template. +type AVC struct { + Hdr RR_Header + Txt []string `dns:"txt"` +} + +func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } + +// SRV RR. See RFC 2782. +type SRV struct { + Hdr RR_Header + Priority uint16 + Weight uint16 + Port uint16 + Target string `dns:"domain-name"` +} + +func (rr *SRV) String() string { + return rr.Hdr.String() + + strconv.Itoa(int(rr.Priority)) + " " + + strconv.Itoa(int(rr.Weight)) + " " + + strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target) +} + +// NAPTR RR. See RFC 2915. +type NAPTR struct { + Hdr RR_Header + Order uint16 + Preference uint16 + Flags string + Service string + Regexp string + Replacement string `dns:"domain-name"` +} + +func (rr *NAPTR) String() string { + return rr.Hdr.String() + + strconv.Itoa(int(rr.Order)) + " " + + strconv.Itoa(int(rr.Preference)) + " " + + "\"" + rr.Flags + "\" " + + "\"" + rr.Service + "\" " + + "\"" + rr.Regexp + "\" " + + rr.Replacement +} + +// CERT RR. See RFC 4398. +type CERT struct { + Hdr RR_Header + Type uint16 + KeyTag uint16 + Algorithm uint8 + Certificate string `dns:"base64"` +} + +func (rr *CERT) String() string { + var ( + ok bool + certtype, algorithm string + ) + if certtype, ok = CertTypeToString[rr.Type]; !ok { + certtype = strconv.Itoa(int(rr.Type)) + } + if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok { + algorithm = strconv.Itoa(int(rr.Algorithm)) + } + return rr.Hdr.String() + certtype + + " " + strconv.Itoa(int(rr.KeyTag)) + + " " + algorithm + + " " + rr.Certificate +} + +// DNAME RR. See RFC 2672. +type DNAME struct { + Hdr RR_Header + Target string `dns:"domain-name"` +} + +func (rr *DNAME) String() string { + return rr.Hdr.String() + sprintName(rr.Target) +} + +// A RR. See RFC 1035. +type A struct { + Hdr RR_Header + A net.IP `dns:"a"` +} + +func (rr *A) String() string { + if rr.A == nil { + return rr.Hdr.String() + } + return rr.Hdr.String() + rr.A.String() +} + +// AAAA RR. See RFC 3596. +type AAAA struct { + Hdr RR_Header + AAAA net.IP `dns:"aaaa"` +} + +func (rr *AAAA) String() string { + if rr.AAAA == nil { + return rr.Hdr.String() + } + return rr.Hdr.String() + rr.AAAA.String() +} + +// PX RR. See RFC 2163. +type PX struct { + Hdr RR_Header + Preference uint16 + Map822 string `dns:"domain-name"` + Mapx400 string `dns:"domain-name"` +} + +func (rr *PX) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400) +} + +// GPOS RR. See RFC 1712. +type GPOS struct { + Hdr RR_Header + Longitude string + Latitude string + Altitude string +} + +func (rr *GPOS) String() string { + return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude +} + +// LOC RR. See RFC RFC 1876. +type LOC struct { + Hdr RR_Header + Version uint8 + Size uint8 + HorizPre uint8 + VertPre uint8 + Latitude uint32 + Longitude uint32 + Altitude uint32 +} + +// cmToM takes a cm value expressed in RFC1876 SIZE mantissa/exponent +// format and returns a string in m (two decimals for the cm) +func cmToM(m, e uint8) string { + if e < 2 { + if e == 1 { + m *= 10 + } + + return fmt.Sprintf("0.%02d", m) + } + + s := fmt.Sprintf("%d", m) + for e > 2 { + s += "0" + e-- + } + return s +} + +func (rr *LOC) String() string { + s := rr.Hdr.String() + + lat := rr.Latitude + ns := "N" + if lat > LOC_EQUATOR { + lat = lat - LOC_EQUATOR + } else { + ns = "S" + lat = LOC_EQUATOR - lat + } + h := lat / LOC_DEGREES + lat = lat % LOC_DEGREES + m := lat / LOC_HOURS + lat = lat % LOC_HOURS + s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lat)/1000, ns) + + lon := rr.Longitude + ew := "E" + if lon > LOC_PRIMEMERIDIAN { + lon = lon - LOC_PRIMEMERIDIAN + } else { + ew = "W" + lon = LOC_PRIMEMERIDIAN - lon + } + h = lon / LOC_DEGREES + lon = lon % LOC_DEGREES + m = lon / LOC_HOURS + lon = lon % LOC_HOURS + s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lon)/1000, ew) + + var alt = float64(rr.Altitude) / 100 + alt -= LOC_ALTITUDEBASE + if rr.Altitude%100 != 0 { + s += fmt.Sprintf("%.2fm ", alt) + } else { + s += fmt.Sprintf("%.0fm ", alt) + } + + s += cmToM(rr.Size&0xf0>>4, rr.Size&0x0f) + "m " + s += cmToM(rr.HorizPre&0xf0>>4, rr.HorizPre&0x0f) + "m " + s += cmToM(rr.VertPre&0xf0>>4, rr.VertPre&0x0f) + "m" + + return s +} + +// SIG RR. See RFC 2535. The SIG RR is identical to RRSIG and nowadays only used for SIG(0), See RFC 2931. +type SIG struct { + RRSIG +} + +// RRSIG RR. See RFC 4034 and RFC 3755. +type RRSIG struct { + Hdr RR_Header + TypeCovered uint16 + Algorithm uint8 + Labels uint8 + OrigTtl uint32 + Expiration uint32 + Inception uint32 + KeyTag uint16 + SignerName string `dns:"domain-name"` + Signature string `dns:"base64"` +} + +func (rr *RRSIG) String() string { + s := rr.Hdr.String() + s += Type(rr.TypeCovered).String() + s += " " + strconv.Itoa(int(rr.Algorithm)) + + " " + strconv.Itoa(int(rr.Labels)) + + " " + strconv.FormatInt(int64(rr.OrigTtl), 10) + + " " + TimeToString(rr.Expiration) + + " " + TimeToString(rr.Inception) + + " " + strconv.Itoa(int(rr.KeyTag)) + + " " + sprintName(rr.SignerName) + + " " + rr.Signature + return s +} + +// NSEC RR. See RFC 4034 and RFC 3755. +type NSEC struct { + Hdr RR_Header + NextDomain string `dns:"domain-name"` + TypeBitMap []uint16 `dns:"nsec"` +} + +func (rr *NSEC) String() string { + s := rr.Hdr.String() + sprintName(rr.NextDomain) + for _, t := range rr.TypeBitMap { + s += " " + Type(t).String() + } + return s +} + +func (rr *NSEC) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.NextDomain, off+l, compression, false) + l += typeBitMapLen(rr.TypeBitMap) + return l +} + +// DLV RR. See RFC 4431. +type DLV struct{ DS } + +// CDS RR. See RFC 7344. +type CDS struct{ DS } + +// DS RR. See RFC 4034 and RFC 3658. +type DS struct { + Hdr RR_Header + KeyTag uint16 + Algorithm uint8 + DigestType uint8 + Digest string `dns:"hex"` +} + +func (rr *DS) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + + " " + strconv.Itoa(int(rr.Algorithm)) + + " " + strconv.Itoa(int(rr.DigestType)) + + " " + strings.ToUpper(rr.Digest) +} + +// KX RR. See RFC 2230. +type KX struct { + Hdr RR_Header + Preference uint16 + Exchanger string `dns:"domain-name"` +} + +func (rr *KX) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + + " " + sprintName(rr.Exchanger) +} + +// TA RR. See http://www.watson.org/~weiler/INI1999-19.pdf. +type TA struct { + Hdr RR_Header + KeyTag uint16 + Algorithm uint8 + DigestType uint8 + Digest string `dns:"hex"` +} + +func (rr *TA) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + + " " + strconv.Itoa(int(rr.Algorithm)) + + " " + strconv.Itoa(int(rr.DigestType)) + + " " + strings.ToUpper(rr.Digest) +} + +// TALINK RR. See https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template. +type TALINK struct { + Hdr RR_Header + PreviousName string `dns:"domain-name"` + NextName string `dns:"domain-name"` +} + +func (rr *TALINK) String() string { + return rr.Hdr.String() + + sprintName(rr.PreviousName) + " " + sprintName(rr.NextName) +} + +// SSHFP RR. See RFC RFC 4255. +type SSHFP struct { + Hdr RR_Header + Algorithm uint8 + Type uint8 + FingerPrint string `dns:"hex"` +} + +func (rr *SSHFP) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) + + " " + strconv.Itoa(int(rr.Type)) + + " " + strings.ToUpper(rr.FingerPrint) +} + +// KEY RR. See RFC RFC 2535. +type KEY struct { + DNSKEY +} + +// CDNSKEY RR. See RFC 7344. +type CDNSKEY struct { + DNSKEY +} + +// DNSKEY RR. See RFC 4034 and RFC 3755. +type DNSKEY struct { + Hdr RR_Header + Flags uint16 + Protocol uint8 + Algorithm uint8 + PublicKey string `dns:"base64"` +} + +func (rr *DNSKEY) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + + " " + strconv.Itoa(int(rr.Protocol)) + + " " + strconv.Itoa(int(rr.Algorithm)) + + " " + rr.PublicKey +} + +// RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template. +type RKEY struct { + Hdr RR_Header + Flags uint16 + Protocol uint8 + Algorithm uint8 + PublicKey string `dns:"base64"` +} + +func (rr *RKEY) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + + " " + strconv.Itoa(int(rr.Protocol)) + + " " + strconv.Itoa(int(rr.Algorithm)) + + " " + rr.PublicKey +} + +// NSAPPTR RR. See RFC 1348. +type NSAPPTR struct { + Hdr RR_Header + Ptr string `dns:"domain-name"` +} + +func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) } + +// NSEC3 RR. See RFC 5155. +type NSEC3 struct { + Hdr RR_Header + Hash uint8 + Flags uint8 + Iterations uint16 + SaltLength uint8 + Salt string `dns:"size-hex:SaltLength"` + HashLength uint8 + NextDomain string `dns:"size-base32:HashLength"` + TypeBitMap []uint16 `dns:"nsec"` +} + +func (rr *NSEC3) String() string { + s := rr.Hdr.String() + s += strconv.Itoa(int(rr.Hash)) + + " " + strconv.Itoa(int(rr.Flags)) + + " " + strconv.Itoa(int(rr.Iterations)) + + " " + saltToString(rr.Salt) + + " " + rr.NextDomain + for _, t := range rr.TypeBitMap { + s += " " + Type(t).String() + } + return s +} + +func (rr *NSEC3) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1 + l += typeBitMapLen(rr.TypeBitMap) + return l +} + +// NSEC3PARAM RR. See RFC 5155. +type NSEC3PARAM struct { + Hdr RR_Header + Hash uint8 + Flags uint8 + Iterations uint16 + SaltLength uint8 + Salt string `dns:"size-hex:SaltLength"` +} + +func (rr *NSEC3PARAM) String() string { + s := rr.Hdr.String() + s += strconv.Itoa(int(rr.Hash)) + + " " + strconv.Itoa(int(rr.Flags)) + + " " + strconv.Itoa(int(rr.Iterations)) + + " " + saltToString(rr.Salt) + return s +} + +// TKEY RR. See RFC 2930. +type TKEY struct { + Hdr RR_Header + Algorithm string `dns:"domain-name"` + Inception uint32 + Expiration uint32 + Mode uint16 + Error uint16 + KeySize uint16 + Key string `dns:"size-hex:KeySize"` + OtherLen uint16 + OtherData string `dns:"size-hex:OtherLen"` +} + +// TKEY has no official presentation format, but this will suffice. +func (rr *TKEY) String() string { + s := ";" + rr.Hdr.String() + + " " + rr.Algorithm + + " " + TimeToString(rr.Inception) + + " " + TimeToString(rr.Expiration) + + " " + strconv.Itoa(int(rr.Mode)) + + " " + strconv.Itoa(int(rr.Error)) + + " " + strconv.Itoa(int(rr.KeySize)) + + " " + rr.Key + + " " + strconv.Itoa(int(rr.OtherLen)) + + " " + rr.OtherData + return s +} + +// RFC3597 represents an unknown/generic RR. See RFC 3597. +type RFC3597 struct { + Hdr RR_Header + Rdata string `dns:"hex"` +} + +func (rr *RFC3597) String() string { + // Let's call it a hack + s := rfc3597Header(rr.Hdr) + + s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata + return s +} + +func rfc3597Header(h RR_Header) string { + var s string + + s += sprintName(h.Name) + "\t" + s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" + s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t" + s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t" + return s +} + +// URI RR. See RFC 7553. +type URI struct { + Hdr RR_Header + Priority uint16 + Weight uint16 + Target string `dns:"octet"` +} + +func (rr *URI) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) + + " " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target) +} + +// DHCID RR. See RFC 4701. +type DHCID struct { + Hdr RR_Header + Digest string `dns:"base64"` +} + +func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest } + +// TLSA RR. See RFC 6698. +type TLSA struct { + Hdr RR_Header + Usage uint8 + Selector uint8 + MatchingType uint8 + Certificate string `dns:"hex"` +} + +func (rr *TLSA) String() string { + return rr.Hdr.String() + + strconv.Itoa(int(rr.Usage)) + + " " + strconv.Itoa(int(rr.Selector)) + + " " + strconv.Itoa(int(rr.MatchingType)) + + " " + rr.Certificate +} + +// SMIMEA RR. See RFC 8162. +type SMIMEA struct { + Hdr RR_Header + Usage uint8 + Selector uint8 + MatchingType uint8 + Certificate string `dns:"hex"` +} + +func (rr *SMIMEA) String() string { + s := rr.Hdr.String() + + strconv.Itoa(int(rr.Usage)) + + " " + strconv.Itoa(int(rr.Selector)) + + " " + strconv.Itoa(int(rr.MatchingType)) + + // Every Nth char needs a space on this output. If we output + // this as one giant line, we can't read it can in because in some cases + // the cert length overflows scan.maxTok (2048). + sx := splitN(rr.Certificate, 1024) // conservative value here + s += " " + strings.Join(sx, " ") + return s +} + +// HIP RR. See RFC 8005. +type HIP struct { + Hdr RR_Header + HitLength uint8 + PublicKeyAlgorithm uint8 + PublicKeyLength uint16 + Hit string `dns:"size-hex:HitLength"` + PublicKey string `dns:"size-base64:PublicKeyLength"` + RendezvousServers []string `dns:"domain-name"` +} + +func (rr *HIP) String() string { + s := rr.Hdr.String() + + strconv.Itoa(int(rr.PublicKeyAlgorithm)) + + " " + rr.Hit + + " " + rr.PublicKey + for _, d := range rr.RendezvousServers { + s += " " + sprintName(d) + } + return s +} + +// NINFO RR. See https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template. +type NINFO struct { + Hdr RR_Header + ZSData []string `dns:"txt"` +} + +func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) } + +// NID RR. See RFC RFC 6742. +type NID struct { + Hdr RR_Header + Preference uint16 + NodeID uint64 +} + +func (rr *NID) String() string { + s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + node := fmt.Sprintf("%0.16x", rr.NodeID) + s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] + return s +} + +// L32 RR, See RFC 6742. +type L32 struct { + Hdr RR_Header + Preference uint16 + Locator32 net.IP `dns:"a"` +} + +func (rr *L32) String() string { + if rr.Locator32 == nil { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + } + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + + " " + rr.Locator32.String() +} + +// L64 RR, See RFC 6742. +type L64 struct { + Hdr RR_Header + Preference uint16 + Locator64 uint64 +} + +func (rr *L64) String() string { + s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + node := fmt.Sprintf("%0.16X", rr.Locator64) + s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] + return s +} + +// LP RR. See RFC 6742. +type LP struct { + Hdr RR_Header + Preference uint16 + Fqdn string `dns:"domain-name"` +} + +func (rr *LP) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn) +} + +// EUI48 RR. See RFC 7043. +type EUI48 struct { + Hdr RR_Header + Address uint64 `dns:"uint48"` +} + +func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) } + +// EUI64 RR. See RFC 7043. +type EUI64 struct { + Hdr RR_Header + Address uint64 +} + +func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) } + +// CAA RR. See RFC 6844. +type CAA struct { + Hdr RR_Header + Flag uint8 + Tag string + Value string `dns:"octet"` +} + +func (rr *CAA) String() string { + return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value) +} + +// UID RR. Deprecated, IANA-Reserved. +type UID struct { + Hdr RR_Header + Uid uint32 +} + +func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) } + +// GID RR. Deprecated, IANA-Reserved. +type GID struct { + Hdr RR_Header + Gid uint32 +} + +func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) } + +// UINFO RR. Deprecated, IANA-Reserved. +type UINFO struct { + Hdr RR_Header + Uinfo string +} + +func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) } + +// EID RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt. +type EID struct { + Hdr RR_Header + Endpoint string `dns:"hex"` +} + +func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) } + +// NIMLOC RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt. +type NIMLOC struct { + Hdr RR_Header + Locator string `dns:"hex"` +} + +func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) } + +// OPENPGPKEY RR. See RFC 7929. +type OPENPGPKEY struct { + Hdr RR_Header + PublicKey string `dns:"base64"` +} + +func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey } + +// CSYNC RR. See RFC 7477. +type CSYNC struct { + Hdr RR_Header + Serial uint32 + Flags uint16 + TypeBitMap []uint16 `dns:"nsec"` +} + +func (rr *CSYNC) String() string { + s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Serial), 10) + " " + strconv.Itoa(int(rr.Flags)) + + for _, t := range rr.TypeBitMap { + s += " " + Type(t).String() + } + return s +} + +func (rr *CSYNC) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 4 + 2 + l += typeBitMapLen(rr.TypeBitMap) + return l +} + +// TimeToString translates the RRSIG's incep. and expir. times to the +// string representation used when printing the record. +// It takes serial arithmetic (RFC 1982) into account. +func TimeToString(t uint32) string { + mod := (int64(t)-time.Now().Unix())/year68 - 1 + if mod < 0 { + mod = 0 + } + ti := time.Unix(int64(t)-mod*year68, 0).UTC() + return ti.Format("20060102150405") +} + +// StringToTime translates the RRSIG's incep. and expir. times from +// string values like "20110403154150" to an 32 bit integer. +// It takes serial arithmetic (RFC 1982) into account. +func StringToTime(s string) (uint32, error) { + t, err := time.Parse("20060102150405", s) + if err != nil { + return 0, err + } + mod := t.Unix()/year68 - 1 + if mod < 0 { + mod = 0 + } + return uint32(t.Unix() - mod*year68), nil +} + +// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty. +func saltToString(s string) string { + if len(s) == 0 { + return "-" + } + return strings.ToUpper(s) +} + +func euiToString(eui uint64, bits int) (hex string) { + switch bits { + case 64: + hex = fmt.Sprintf("%16.16x", eui) + hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + + "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16] + case 48: + hex = fmt.Sprintf("%12.12x", eui) + hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + + "-" + hex[8:10] + "-" + hex[10:12] + } + return +} + +// copyIP returns a copy of ip. +func copyIP(ip net.IP) net.IP { + p := make(net.IP, len(ip)) + copy(p, ip) + return p +} + +// SplitN splits a string into N sized string chunks. +// This might become an exported function once. +func splitN(s string, n int) []string { + if len(s) < n { + return []string{s} + } + sx := []string{} + p, i := 0, n + for { + if i <= len(s) { + sx = append(sx, s[p:i]) + } else { + sx = append(sx, s[p:]) + break + + } + p, i = p+n, i+n + } + + return sx +} diff --git a/vendor/github.com/miekg/dns/types_generate.go b/vendor/github.com/miekg/dns/types_generate.go new file mode 100644 index 00000000..8cda2a74 --- /dev/null +++ b/vendor/github.com/miekg/dns/types_generate.go @@ -0,0 +1,285 @@ +//+build ignore + +// types_generate.go is meant to run with go generate. It will use +// go/{importer,types} to track down all the RR struct types. Then for each type +// it will generate conversion tables (TypeToRR and TypeToString) and banal +// methods (len, Header, copy) based on the struct tags. The generated source is +// written to ztypes.go, and is meant to be checked into git. +package main + +import ( + "bytes" + "fmt" + "go/format" + "go/importer" + "go/types" + "log" + "os" + "strings" + "text/template" +) + +var skipLen = map[string]struct{}{ + "NSEC": {}, + "NSEC3": {}, + "OPT": {}, + "CSYNC": {}, +} + +var packageHdr = ` +// Code generated by "go run types_generate.go"; DO NOT EDIT. + +package dns + +import ( + "encoding/base64" + "net" +) + +` + +var TypeToRR = template.Must(template.New("TypeToRR").Parse(` +// TypeToRR is a map of constructors for each RR type. +var TypeToRR = map[uint16]func() RR{ +{{range .}}{{if ne . "RFC3597"}} Type{{.}}: func() RR { return new({{.}}) }, +{{end}}{{end}} } + +`)) + +var typeToString = template.Must(template.New("typeToString").Parse(` +// TypeToString is a map of strings for each RR type. +var TypeToString = map[uint16]string{ +{{range .}}{{if ne . "NSAPPTR"}} Type{{.}}: "{{.}}", +{{end}}{{end}} TypeNSAPPTR: "NSAP-PTR", +} + +`)) + +var headerFunc = template.Must(template.New("headerFunc").Parse(` +{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr } +{{end}} + +`)) + +// getTypeStruct will take a type and the package scope, and return the +// (innermost) struct if the type is considered a RR type (currently defined as +// those structs beginning with a RR_Header, could be redefined as implementing +// the RR interface). The bool return value indicates if embedded structs were +// resolved. +func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { + st, ok := t.Underlying().(*types.Struct) + if !ok { + return nil, false + } + if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { + return st, false + } + if st.Field(0).Anonymous() { + st, _ := getTypeStruct(st.Field(0).Type(), scope) + return st, true + } + return nil, false +} + +func main() { + // Import and type-check the package + pkg, err := importer.Default().Import("github.com/miekg/dns") + fatalIfErr(err) + scope := pkg.Scope() + + // Collect constants like TypeX + var numberedTypes []string + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + b, ok := o.Type().(*types.Basic) + if !ok || b.Kind() != types.Uint16 { + continue + } + if !strings.HasPrefix(o.Name(), "Type") { + continue + } + name := strings.TrimPrefix(o.Name(), "Type") + if name == "PrivateRR" { + continue + } + numberedTypes = append(numberedTypes, name) + } + + // Collect actual types (*X) + var namedTypes []string + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + if st, _ := getTypeStruct(o.Type(), scope); st == nil { + continue + } + if name == "PrivateRR" { + continue + } + + // Check if corresponding TypeX exists + if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { + log.Fatalf("Constant Type%s does not exist.", o.Name()) + } + + namedTypes = append(namedTypes, o.Name()) + } + + b := &bytes.Buffer{} + b.WriteString(packageHdr) + + // Generate TypeToRR + fatalIfErr(TypeToRR.Execute(b, namedTypes)) + + // Generate typeToString + fatalIfErr(typeToString.Execute(b, numberedTypes)) + + // Generate headerFunc + fatalIfErr(headerFunc.Execute(b, namedTypes)) + + // Generate len() + fmt.Fprint(b, "// len() functions\n") + for _, name := range namedTypes { + if _, ok := skipLen[name]; ok { + continue + } + o := scope.Lookup(name) + st, isEmbedded := getTypeStruct(o.Type(), scope) + if isEmbedded { + continue + } + fmt.Fprintf(b, "func (rr *%s) len(off int, compression map[string]struct{}) int {\n", name) + fmt.Fprintf(b, "l := rr.Hdr.len(off, compression)\n") + for i := 1; i < st.NumFields(); i++ { + o := func(s string) { fmt.Fprintf(b, s, st.Field(i).Name()) } + + if _, ok := st.Field(i).Type().(*types.Slice); ok { + switch st.Tag(i) { + case `dns:"-"`: + // ignored + case `dns:"cdomain-name"`: + o("for _, x := range rr.%s { l += domainNameLen(x, off+l, compression, true) }\n") + case `dns:"domain-name"`: + o("for _, x := range rr.%s { l += domainNameLen(x, off+l, compression, false) }\n") + case `dns:"txt"`: + o("for _, x := range rr.%s { l += len(x) + 1 }\n") + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + continue + } + + switch { + case st.Tag(i) == `dns:"-"`: + // ignored + case st.Tag(i) == `dns:"cdomain-name"`: + o("l += domainNameLen(rr.%s, off+l, compression, true)\n") + case st.Tag(i) == `dns:"domain-name"`: + o("l += domainNameLen(rr.%s, off+l, compression, false)\n") + case st.Tag(i) == `dns:"octet"`: + o("l += len(rr.%s)\n") + case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): + fallthrough + case st.Tag(i) == `dns:"base64"`: + o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n") + case strings.HasPrefix(st.Tag(i), `dns:"size-hex:`): // this has an extra field where the length is stored + o("l += len(rr.%s)/2\n") + case st.Tag(i) == `dns:"hex"`: + o("l += len(rr.%s)/2\n") + case st.Tag(i) == `dns:"any"`: + o("l += len(rr.%s)\n") + case st.Tag(i) == `dns:"a"`: + o("if len(rr.%s) != 0 { l += net.IPv4len }\n") + case st.Tag(i) == `dns:"aaaa"`: + o("if len(rr.%s) != 0 { l += net.IPv6len }\n") + case st.Tag(i) == `dns:"txt"`: + o("for _, t := range rr.%s { l += len(t) + 1 }\n") + case st.Tag(i) == `dns:"uint48"`: + o("l += 6 // %s\n") + case st.Tag(i) == "": + switch st.Field(i).Type().(*types.Basic).Kind() { + case types.Uint8: + o("l++ // %s\n") + case types.Uint16: + o("l += 2 // %s\n") + case types.Uint32: + o("l += 4 // %s\n") + case types.Uint64: + o("l += 8 // %s\n") + case types.String: + o("l += len(rr.%s) + 1\n") + default: + log.Fatalln(name, st.Field(i).Name()) + } + default: + log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) + } + } + fmt.Fprintf(b, "return l }\n") + } + + // Generate copy() + fmt.Fprint(b, "// copy() functions\n") + for _, name := range namedTypes { + o := scope.Lookup(name) + st, isEmbedded := getTypeStruct(o.Type(), scope) + if isEmbedded { + continue + } + fmt.Fprintf(b, "func (rr *%s) copy() RR {\n", name) + fields := []string{"rr.Hdr"} + for i := 1; i < st.NumFields(); i++ { + f := st.Field(i).Name() + if sl, ok := st.Field(i).Type().(*types.Slice); ok { + t := sl.Underlying().String() + t = strings.TrimPrefix(t, "[]") + if strings.Contains(t, ".") { + splits := strings.Split(t, ".") + t = splits[len(splits)-1] + } + // For the EDNS0 interface (used in the OPT RR), we need to call the copy method on each element. + if t == "EDNS0" { + fmt.Fprintf(b, "%s := make([]%s, len(rr.%s));\nfor i,e := range rr.%s {\n %s[i] = e.copy()\n}\n", + f, t, f, f, f) + fields = append(fields, f) + continue + } + fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n", + f, t, f, f, f) + fields = append(fields, f) + continue + } + if st.Field(i).Type().String() == "net.IP" { + fields = append(fields, "copyIP(rr."+f+")") + continue + } + fields = append(fields, "rr."+f) + } + fmt.Fprintf(b, "return &%s{%s}\n", name, strings.Join(fields, ",")) + fmt.Fprintf(b, "}\n") + } + + // gofmt + res, err := format.Source(b.Bytes()) + if err != nil { + b.WriteTo(os.Stderr) + log.Fatal(err) + } + + // write result + f, err := os.Create("ztypes.go") + fatalIfErr(err) + defer f.Close() + f.Write(res) +} + +func fatalIfErr(err error) { + if err != nil { + log.Fatal(err) + } +} diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go new file mode 100644 index 00000000..a4826ee2 --- /dev/null +++ b/vendor/github.com/miekg/dns/udp.go @@ -0,0 +1,102 @@ +// +build !windows + +package dns + +import ( + "net" + + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +// This is the required size of the OOB buffer to pass to ReadMsgUDP. +var udpOOBSize = func() int { + // We can't know whether we'll get an IPv4 control message or an + // IPv6 control message ahead of time. To get around this, we size + // the buffer equal to the largest of the two. + + oob4 := ipv4.NewControlMessage(ipv4.FlagDst | ipv4.FlagInterface) + oob6 := ipv6.NewControlMessage(ipv6.FlagDst | ipv6.FlagInterface) + + if len(oob4) > len(oob6) { + return len(oob4) + } + + return len(oob6) +}() + +// SessionUDP holds the remote address and the associated +// out-of-band data. +type SessionUDP struct { + raddr *net.UDPAddr + context []byte +} + +// RemoteAddr returns the remote network address. +func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } + +// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a +// net.UDPAddr. +func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { + oob := make([]byte, udpOOBSize) + n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) + if err != nil { + return n, nil, err + } + return n, &SessionUDP{raddr, oob[:oobn]}, err +} + +// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr. +func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { + oob := correctSource(session.context) + n, _, err := conn.WriteMsgUDP(b, oob, session.raddr) + return n, err +} + +func setUDPSocketOptions(conn *net.UDPConn) error { + // Try setting the flags for both families and ignore the errors unless they + // both error. + err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true) + err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true) + if err6 != nil && err4 != nil { + return err4 + } + return nil +} + +// parseDstFromOOB takes oob data and returns the destination IP. +func parseDstFromOOB(oob []byte) net.IP { + // Start with IPv6 and then fallback to IPv4 + // TODO(fastest963): Figure out a way to prefer one or the other. Looking at + // the lvl of the header for a 0 or 41 isn't cross-platform. + cm6 := new(ipv6.ControlMessage) + if cm6.Parse(oob) == nil && cm6.Dst != nil { + return cm6.Dst + } + cm4 := new(ipv4.ControlMessage) + if cm4.Parse(oob) == nil && cm4.Dst != nil { + return cm4.Dst + } + return nil +} + +// correctSource takes oob data and returns new oob data with the Src equal to the Dst +func correctSource(oob []byte) []byte { + dst := parseDstFromOOB(oob) + if dst == nil { + return nil + } + // If the dst is definitely an IPv6, then use ipv6's ControlMessage to + // respond otherwise use ipv4's because ipv6's marshal ignores ipv4 + // addresses. + if dst.To4() == nil { + cm := new(ipv6.ControlMessage) + cm.Src = dst + oob = cm.Marshal() + } else { + cm := new(ipv4.ControlMessage) + cm.Src = dst + oob = cm.Marshal() + } + return oob +} diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go new file mode 100644 index 00000000..e7dd8ca3 --- /dev/null +++ b/vendor/github.com/miekg/dns/udp_windows.go @@ -0,0 +1,35 @@ +// +build windows + +package dns + +import "net" + +// SessionUDP holds the remote address +type SessionUDP struct { + raddr *net.UDPAddr +} + +// RemoteAddr returns the remote network address. +func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } + +// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a +// net.UDPAddr. +// TODO(fastest963): Once go1.10 is released, use ReadMsgUDP. +func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { + n, raddr, err := conn.ReadFrom(b) + if err != nil { + return n, nil, err + } + return n, &SessionUDP{raddr.(*net.UDPAddr)}, err +} + +// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr. +// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP. +func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { + return conn.WriteTo(b, session.raddr) +} + +// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods +// use the standard method in udp.go for these. +func setUDPSocketOptions(*net.UDPConn) error { return nil } +func parseDstFromOOB([]byte, net.IP) net.IP { return nil } diff --git a/vendor/github.com/miekg/dns/update.go b/vendor/github.com/miekg/dns/update.go new file mode 100644 index 00000000..69dd3865 --- /dev/null +++ b/vendor/github.com/miekg/dns/update.go @@ -0,0 +1,110 @@ +package dns + +// NameUsed sets the RRs in the prereq section to +// "Name is in use" RRs. RFC 2136 section 2.4.4. +func (u *Msg) NameUsed(rr []RR) { + if u.Answer == nil { + u.Answer = make([]RR, 0, len(rr)) + } + for _, r := range rr { + u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) + } +} + +// NameNotUsed sets the RRs in the prereq section to +// "Name is in not use" RRs. RFC 2136 section 2.4.5. +func (u *Msg) NameNotUsed(rr []RR) { + if u.Answer == nil { + u.Answer = make([]RR, 0, len(rr)) + } + for _, r := range rr { + u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}}) + } +} + +// Used sets the RRs in the prereq section to +// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2. +func (u *Msg) Used(rr []RR) { + if len(u.Question) == 0 { + panic("dns: empty question section") + } + if u.Answer == nil { + u.Answer = make([]RR, 0, len(rr)) + } + for _, r := range rr { + r.Header().Class = u.Question[0].Qclass + u.Answer = append(u.Answer, r) + } +} + +// RRsetUsed sets the RRs in the prereq section to +// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1. +func (u *Msg) RRsetUsed(rr []RR) { + if u.Answer == nil { + u.Answer = make([]RR, 0, len(rr)) + } + for _, r := range rr { + h := r.Header() + u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}}) + } +} + +// RRsetNotUsed sets the RRs in the prereq section to +// "RRset does not exist" RRs. RFC 2136 section 2.4.3. +func (u *Msg) RRsetNotUsed(rr []RR) { + if u.Answer == nil { + u.Answer = make([]RR, 0, len(rr)) + } + for _, r := range rr { + h := r.Header() + u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}}) + } +} + +// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1. +func (u *Msg) Insert(rr []RR) { + if len(u.Question) == 0 { + panic("dns: empty question section") + } + if u.Ns == nil { + u.Ns = make([]RR, 0, len(rr)) + } + for _, r := range rr { + r.Header().Class = u.Question[0].Qclass + u.Ns = append(u.Ns, r) + } +} + +// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2. +func (u *Msg) RemoveRRset(rr []RR) { + if u.Ns == nil { + u.Ns = make([]RR, 0, len(rr)) + } + for _, r := range rr { + h := r.Header() + u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}}) + } +} + +// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3 +func (u *Msg) RemoveName(rr []RR) { + if u.Ns == nil { + u.Ns = make([]RR, 0, len(rr)) + } + for _, r := range rr { + u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) + } +} + +// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4 +func (u *Msg) Remove(rr []RR) { + if u.Ns == nil { + u.Ns = make([]RR, 0, len(rr)) + } + for _, r := range rr { + h := r.Header() + h.Class = ClassNONE + h.Ttl = 0 + u.Ns = append(u.Ns, r) + } +} diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go new file mode 100644 index 00000000..45f45e64 --- /dev/null +++ b/vendor/github.com/miekg/dns/version.go @@ -0,0 +1,15 @@ +package dns + +import "fmt" + +// Version is current version of this library. +var Version = V{1, 1, 14} + +// V holds the version of this library. +type V struct { + Major, Minor, Patch int +} + +func (v V) String() string { + return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) +} diff --git a/vendor/github.com/miekg/dns/xfr.go b/vendor/github.com/miekg/dns/xfr.go new file mode 100644 index 00000000..bb4ca3d8 --- /dev/null +++ b/vendor/github.com/miekg/dns/xfr.go @@ -0,0 +1,263 @@ +package dns + +import ( + "fmt" + "time" +) + +// Envelope is used when doing a zone transfer with a remote server. +type Envelope struct { + RR []RR // The set of RRs in the answer section of the xfr reply message. + Error error // If something went wrong, this contains the error. +} + +// A Transfer defines parameters that are used during a zone transfer. +type Transfer struct { + *Conn + DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds + ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds + WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds + TsigSecret map[string]string // Secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) + tsigTimersOnly bool +} + +// Think we need to away to stop the transfer + +// In performs an incoming transfer with the server in a. +// If you would like to set the source IP, or some other attribute +// of a Dialer for a Transfer, you can do so by specifying the attributes +// in the Transfer.Conn: +// +// d := net.Dialer{LocalAddr: transfer_source} +// con, err := d.Dial("tcp", master) +// dnscon := &dns.Conn{Conn:con} +// transfer = &dns.Transfer{Conn: dnscon} +// channel, err := transfer.In(message, master) +// +func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) { + switch q.Question[0].Qtype { + case TypeAXFR, TypeIXFR: + default: + return nil, &Error{"unsupported question type"} + } + + timeout := dnsTimeout + if t.DialTimeout != 0 { + timeout = t.DialTimeout + } + + if t.Conn == nil { + t.Conn, err = DialTimeout("tcp", a, timeout) + if err != nil { + return nil, err + } + } + + if err := t.WriteMsg(q); err != nil { + return nil, err + } + + env = make(chan *Envelope) + switch q.Question[0].Qtype { + case TypeAXFR: + go t.inAxfr(q, env) + case TypeIXFR: + go t.inIxfr(q, env) + } + + return env, nil +} + +func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) { + first := true + defer t.Close() + defer close(c) + timeout := dnsTimeout + if t.ReadTimeout != 0 { + timeout = t.ReadTimeout + } + for { + t.Conn.SetReadDeadline(time.Now().Add(timeout)) + in, err := t.ReadMsg() + if err != nil { + c <- &Envelope{nil, err} + return + } + if q.Id != in.Id { + c <- &Envelope{in.Answer, ErrId} + return + } + if first { + if in.Rcode != RcodeSuccess { + c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} + return + } + if !isSOAFirst(in) { + c <- &Envelope{in.Answer, ErrSoa} + return + } + first = !first + // only one answer that is SOA, receive more + if len(in.Answer) == 1 { + t.tsigTimersOnly = true + c <- &Envelope{in.Answer, nil} + continue + } + } + + if !first { + t.tsigTimersOnly = true // Subsequent envelopes use this. + if isSOALast(in) { + c <- &Envelope{in.Answer, nil} + return + } + c <- &Envelope{in.Answer, nil} + } + } +} + +func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) { + var serial uint32 // The first serial seen is the current server serial + axfr := true + n := 0 + qser := q.Ns[0].(*SOA).Serial + defer t.Close() + defer close(c) + timeout := dnsTimeout + if t.ReadTimeout != 0 { + timeout = t.ReadTimeout + } + for { + t.SetReadDeadline(time.Now().Add(timeout)) + in, err := t.ReadMsg() + if err != nil { + c <- &Envelope{nil, err} + return + } + if q.Id != in.Id { + c <- &Envelope{in.Answer, ErrId} + return + } + if in.Rcode != RcodeSuccess { + c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} + return + } + if n == 0 { + // Check if the returned answer is ok + if !isSOAFirst(in) { + c <- &Envelope{in.Answer, ErrSoa} + return + } + // This serial is important + serial = in.Answer[0].(*SOA).Serial + // Check if there are no changes in zone + if qser >= serial { + c <- &Envelope{in.Answer, nil} + return + } + } + // Now we need to check each message for SOA records, to see what we need to do + t.tsigTimersOnly = true + for _, rr := range in.Answer { + if v, ok := rr.(*SOA); ok { + if v.Serial == serial { + n++ + // quit if it's a full axfr or the the servers' SOA is repeated the third time + if axfr && n == 2 || n == 3 { + c <- &Envelope{in.Answer, nil} + return + } + } else if axfr { + // it's an ixfr + axfr = false + } + } + } + c <- &Envelope{in.Answer, nil} + } +} + +// Out performs an outgoing transfer with the client connecting in w. +// Basic use pattern: +// +// ch := make(chan *dns.Envelope) +// tr := new(dns.Transfer) +// go tr.Out(w, r, ch) +// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}} +// close(ch) +// w.Hijack() +// // w.Close() // Client closes connection +// +// The server is responsible for sending the correct sequence of RRs through the +// channel ch. +func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error { + for x := range ch { + r := new(Msg) + // Compress? + r.SetReply(q) + r.Authoritative = true + // assume it fits TODO(miek): fix + r.Answer = append(r.Answer, x.RR...) + if tsig := q.IsTsig(); tsig != nil && w.TsigStatus() == nil { + r.SetTsig(tsig.Hdr.Name, tsig.Algorithm, tsig.Fudge, time.Now().Unix()) + } + if err := w.WriteMsg(r); err != nil { + return err + } + w.TsigTimersOnly(true) + } + return nil +} + +// ReadMsg reads a message from the transfer connection t. +func (t *Transfer) ReadMsg() (*Msg, error) { + m := new(Msg) + p := make([]byte, MaxMsgSize) + n, err := t.Read(p) + if err != nil && n == 0 { + return nil, err + } + p = p[:n] + if err := m.Unpack(p); err != nil { + return nil, err + } + if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { + if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok { + return m, ErrSecret + } + // Need to work on the original message p, as that was used to calculate the tsig. + err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly) + t.tsigRequestMAC = ts.MAC + } + return m, err +} + +// WriteMsg writes a message through the transfer connection t. +func (t *Transfer) WriteMsg(m *Msg) (err error) { + var out []byte + if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { + if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok { + return ErrSecret + } + out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly) + } else { + out, err = m.Pack() + } + if err != nil { + return err + } + _, err = t.Write(out) + return err +} + +func isSOAFirst(in *Msg) bool { + return len(in.Answer) > 0 && + in.Answer[0].Header().Rrtype == TypeSOA +} + +func isSOALast(in *Msg) bool { + return len(in.Answer) > 0 && + in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA +} + +const errXFR = "bad xfr rcode: %d" diff --git a/vendor/github.com/miekg/dns/zduplicate.go b/vendor/github.com/miekg/dns/zduplicate.go new file mode 100644 index 00000000..74389162 --- /dev/null +++ b/vendor/github.com/miekg/dns/zduplicate.go @@ -0,0 +1,1140 @@ +// Code generated by "go run duplicate_generate.go"; DO NOT EDIT. + +package dns + +// isDuplicate() functions + +func (r1 *A) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*A) + if !ok { + return false + } + _ = r2 + if !r1.A.Equal(r2.A) { + return false + } + return true +} + +func (r1 *AAAA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*AAAA) + if !ok { + return false + } + _ = r2 + if !r1.AAAA.Equal(r2.AAAA) { + return false + } + return true +} + +func (r1 *AFSDB) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*AFSDB) + if !ok { + return false + } + _ = r2 + if r1.Subtype != r2.Subtype { + return false + } + if !isDuplicateName(r1.Hostname, r2.Hostname) { + return false + } + return true +} + +func (r1 *ANY) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*ANY) + if !ok { + return false + } + _ = r2 + return true +} + +func (r1 *AVC) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*AVC) + if !ok { + return false + } + _ = r2 + if len(r1.Txt) != len(r2.Txt) { + return false + } + for i := 0; i < len(r1.Txt); i++ { + if r1.Txt[i] != r2.Txt[i] { + return false + } + } + return true +} + +func (r1 *CAA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*CAA) + if !ok { + return false + } + _ = r2 + if r1.Flag != r2.Flag { + return false + } + if r1.Tag != r2.Tag { + return false + } + if r1.Value != r2.Value { + return false + } + return true +} + +func (r1 *CERT) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*CERT) + if !ok { + return false + } + _ = r2 + if r1.Type != r2.Type { + return false + } + if r1.KeyTag != r2.KeyTag { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.Certificate != r2.Certificate { + return false + } + return true +} + +func (r1 *CNAME) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*CNAME) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Target, r2.Target) { + return false + } + return true +} + +func (r1 *CSYNC) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*CSYNC) + if !ok { + return false + } + _ = r2 + if r1.Serial != r2.Serial { + return false + } + if r1.Flags != r2.Flags { + return false + } + if len(r1.TypeBitMap) != len(r2.TypeBitMap) { + return false + } + for i := 0; i < len(r1.TypeBitMap); i++ { + if r1.TypeBitMap[i] != r2.TypeBitMap[i] { + return false + } + } + return true +} + +func (r1 *DHCID) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*DHCID) + if !ok { + return false + } + _ = r2 + if r1.Digest != r2.Digest { + return false + } + return true +} + +func (r1 *DNAME) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*DNAME) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Target, r2.Target) { + return false + } + return true +} + +func (r1 *DNSKEY) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*DNSKEY) + if !ok { + return false + } + _ = r2 + if r1.Flags != r2.Flags { + return false + } + if r1.Protocol != r2.Protocol { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.PublicKey != r2.PublicKey { + return false + } + return true +} + +func (r1 *DS) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*DS) + if !ok { + return false + } + _ = r2 + if r1.KeyTag != r2.KeyTag { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.DigestType != r2.DigestType { + return false + } + if r1.Digest != r2.Digest { + return false + } + return true +} + +func (r1 *EID) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*EID) + if !ok { + return false + } + _ = r2 + if r1.Endpoint != r2.Endpoint { + return false + } + return true +} + +func (r1 *EUI48) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*EUI48) + if !ok { + return false + } + _ = r2 + if r1.Address != r2.Address { + return false + } + return true +} + +func (r1 *EUI64) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*EUI64) + if !ok { + return false + } + _ = r2 + if r1.Address != r2.Address { + return false + } + return true +} + +func (r1 *GID) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*GID) + if !ok { + return false + } + _ = r2 + if r1.Gid != r2.Gid { + return false + } + return true +} + +func (r1 *GPOS) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*GPOS) + if !ok { + return false + } + _ = r2 + if r1.Longitude != r2.Longitude { + return false + } + if r1.Latitude != r2.Latitude { + return false + } + if r1.Altitude != r2.Altitude { + return false + } + return true +} + +func (r1 *HINFO) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*HINFO) + if !ok { + return false + } + _ = r2 + if r1.Cpu != r2.Cpu { + return false + } + if r1.Os != r2.Os { + return false + } + return true +} + +func (r1 *HIP) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*HIP) + if !ok { + return false + } + _ = r2 + if r1.HitLength != r2.HitLength { + return false + } + if r1.PublicKeyAlgorithm != r2.PublicKeyAlgorithm { + return false + } + if r1.PublicKeyLength != r2.PublicKeyLength { + return false + } + if r1.Hit != r2.Hit { + return false + } + if r1.PublicKey != r2.PublicKey { + return false + } + if len(r1.RendezvousServers) != len(r2.RendezvousServers) { + return false + } + for i := 0; i < len(r1.RendezvousServers); i++ { + if !isDuplicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) { + return false + } + } + return true +} + +func (r1 *KX) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*KX) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !isDuplicateName(r1.Exchanger, r2.Exchanger) { + return false + } + return true +} + +func (r1 *L32) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*L32) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !r1.Locator32.Equal(r2.Locator32) { + return false + } + return true +} + +func (r1 *L64) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*L64) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if r1.Locator64 != r2.Locator64 { + return false + } + return true +} + +func (r1 *LOC) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*LOC) + if !ok { + return false + } + _ = r2 + if r1.Version != r2.Version { + return false + } + if r1.Size != r2.Size { + return false + } + if r1.HorizPre != r2.HorizPre { + return false + } + if r1.VertPre != r2.VertPre { + return false + } + if r1.Latitude != r2.Latitude { + return false + } + if r1.Longitude != r2.Longitude { + return false + } + if r1.Altitude != r2.Altitude { + return false + } + return true +} + +func (r1 *LP) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*LP) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !isDuplicateName(r1.Fqdn, r2.Fqdn) { + return false + } + return true +} + +func (r1 *MB) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MB) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Mb, r2.Mb) { + return false + } + return true +} + +func (r1 *MD) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MD) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Md, r2.Md) { + return false + } + return true +} + +func (r1 *MF) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MF) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Mf, r2.Mf) { + return false + } + return true +} + +func (r1 *MG) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MG) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Mg, r2.Mg) { + return false + } + return true +} + +func (r1 *MINFO) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MINFO) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Rmail, r2.Rmail) { + return false + } + if !isDuplicateName(r1.Email, r2.Email) { + return false + } + return true +} + +func (r1 *MR) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MR) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Mr, r2.Mr) { + return false + } + return true +} + +func (r1 *MX) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*MX) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !isDuplicateName(r1.Mx, r2.Mx) { + return false + } + return true +} + +func (r1 *NAPTR) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NAPTR) + if !ok { + return false + } + _ = r2 + if r1.Order != r2.Order { + return false + } + if r1.Preference != r2.Preference { + return false + } + if r1.Flags != r2.Flags { + return false + } + if r1.Service != r2.Service { + return false + } + if r1.Regexp != r2.Regexp { + return false + } + if !isDuplicateName(r1.Replacement, r2.Replacement) { + return false + } + return true +} + +func (r1 *NID) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NID) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if r1.NodeID != r2.NodeID { + return false + } + return true +} + +func (r1 *NIMLOC) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NIMLOC) + if !ok { + return false + } + _ = r2 + if r1.Locator != r2.Locator { + return false + } + return true +} + +func (r1 *NINFO) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NINFO) + if !ok { + return false + } + _ = r2 + if len(r1.ZSData) != len(r2.ZSData) { + return false + } + for i := 0; i < len(r1.ZSData); i++ { + if r1.ZSData[i] != r2.ZSData[i] { + return false + } + } + return true +} + +func (r1 *NS) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NS) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Ns, r2.Ns) { + return false + } + return true +} + +func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NSAPPTR) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Ptr, r2.Ptr) { + return false + } + return true +} + +func (r1 *NSEC) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NSEC) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.NextDomain, r2.NextDomain) { + return false + } + if len(r1.TypeBitMap) != len(r2.TypeBitMap) { + return false + } + for i := 0; i < len(r1.TypeBitMap); i++ { + if r1.TypeBitMap[i] != r2.TypeBitMap[i] { + return false + } + } + return true +} + +func (r1 *NSEC3) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NSEC3) + if !ok { + return false + } + _ = r2 + if r1.Hash != r2.Hash { + return false + } + if r1.Flags != r2.Flags { + return false + } + if r1.Iterations != r2.Iterations { + return false + } + if r1.SaltLength != r2.SaltLength { + return false + } + if r1.Salt != r2.Salt { + return false + } + if r1.HashLength != r2.HashLength { + return false + } + if r1.NextDomain != r2.NextDomain { + return false + } + if len(r1.TypeBitMap) != len(r2.TypeBitMap) { + return false + } + for i := 0; i < len(r1.TypeBitMap); i++ { + if r1.TypeBitMap[i] != r2.TypeBitMap[i] { + return false + } + } + return true +} + +func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NSEC3PARAM) + if !ok { + return false + } + _ = r2 + if r1.Hash != r2.Hash { + return false + } + if r1.Flags != r2.Flags { + return false + } + if r1.Iterations != r2.Iterations { + return false + } + if r1.SaltLength != r2.SaltLength { + return false + } + if r1.Salt != r2.Salt { + return false + } + return true +} + +func (r1 *NULL) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*NULL) + if !ok { + return false + } + _ = r2 + if r1.Data != r2.Data { + return false + } + return true +} + +func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*OPENPGPKEY) + if !ok { + return false + } + _ = r2 + if r1.PublicKey != r2.PublicKey { + return false + } + return true +} + +func (r1 *PTR) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*PTR) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Ptr, r2.Ptr) { + return false + } + return true +} + +func (r1 *PX) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*PX) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !isDuplicateName(r1.Map822, r2.Map822) { + return false + } + if !isDuplicateName(r1.Mapx400, r2.Mapx400) { + return false + } + return true +} + +func (r1 *RFC3597) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RFC3597) + if !ok { + return false + } + _ = r2 + if r1.Rdata != r2.Rdata { + return false + } + return true +} + +func (r1 *RKEY) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RKEY) + if !ok { + return false + } + _ = r2 + if r1.Flags != r2.Flags { + return false + } + if r1.Protocol != r2.Protocol { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.PublicKey != r2.PublicKey { + return false + } + return true +} + +func (r1 *RP) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RP) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Mbox, r2.Mbox) { + return false + } + if !isDuplicateName(r1.Txt, r2.Txt) { + return false + } + return true +} + +func (r1 *RRSIG) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RRSIG) + if !ok { + return false + } + _ = r2 + if r1.TypeCovered != r2.TypeCovered { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.Labels != r2.Labels { + return false + } + if r1.OrigTtl != r2.OrigTtl { + return false + } + if r1.Expiration != r2.Expiration { + return false + } + if r1.Inception != r2.Inception { + return false + } + if r1.KeyTag != r2.KeyTag { + return false + } + if !isDuplicateName(r1.SignerName, r2.SignerName) { + return false + } + if r1.Signature != r2.Signature { + return false + } + return true +} + +func (r1 *RT) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*RT) + if !ok { + return false + } + _ = r2 + if r1.Preference != r2.Preference { + return false + } + if !isDuplicateName(r1.Host, r2.Host) { + return false + } + return true +} + +func (r1 *SMIMEA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*SMIMEA) + if !ok { + return false + } + _ = r2 + if r1.Usage != r2.Usage { + return false + } + if r1.Selector != r2.Selector { + return false + } + if r1.MatchingType != r2.MatchingType { + return false + } + if r1.Certificate != r2.Certificate { + return false + } + return true +} + +func (r1 *SOA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*SOA) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Ns, r2.Ns) { + return false + } + if !isDuplicateName(r1.Mbox, r2.Mbox) { + return false + } + if r1.Serial != r2.Serial { + return false + } + if r1.Refresh != r2.Refresh { + return false + } + if r1.Retry != r2.Retry { + return false + } + if r1.Expire != r2.Expire { + return false + } + if r1.Minttl != r2.Minttl { + return false + } + return true +} + +func (r1 *SPF) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*SPF) + if !ok { + return false + } + _ = r2 + if len(r1.Txt) != len(r2.Txt) { + return false + } + for i := 0; i < len(r1.Txt); i++ { + if r1.Txt[i] != r2.Txt[i] { + return false + } + } + return true +} + +func (r1 *SRV) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*SRV) + if !ok { + return false + } + _ = r2 + if r1.Priority != r2.Priority { + return false + } + if r1.Weight != r2.Weight { + return false + } + if r1.Port != r2.Port { + return false + } + if !isDuplicateName(r1.Target, r2.Target) { + return false + } + return true +} + +func (r1 *SSHFP) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*SSHFP) + if !ok { + return false + } + _ = r2 + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.Type != r2.Type { + return false + } + if r1.FingerPrint != r2.FingerPrint { + return false + } + return true +} + +func (r1 *TA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TA) + if !ok { + return false + } + _ = r2 + if r1.KeyTag != r2.KeyTag { + return false + } + if r1.Algorithm != r2.Algorithm { + return false + } + if r1.DigestType != r2.DigestType { + return false + } + if r1.Digest != r2.Digest { + return false + } + return true +} + +func (r1 *TALINK) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TALINK) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.PreviousName, r2.PreviousName) { + return false + } + if !isDuplicateName(r1.NextName, r2.NextName) { + return false + } + return true +} + +func (r1 *TKEY) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TKEY) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Algorithm, r2.Algorithm) { + return false + } + if r1.Inception != r2.Inception { + return false + } + if r1.Expiration != r2.Expiration { + return false + } + if r1.Mode != r2.Mode { + return false + } + if r1.Error != r2.Error { + return false + } + if r1.KeySize != r2.KeySize { + return false + } + if r1.Key != r2.Key { + return false + } + if r1.OtherLen != r2.OtherLen { + return false + } + if r1.OtherData != r2.OtherData { + return false + } + return true +} + +func (r1 *TLSA) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TLSA) + if !ok { + return false + } + _ = r2 + if r1.Usage != r2.Usage { + return false + } + if r1.Selector != r2.Selector { + return false + } + if r1.MatchingType != r2.MatchingType { + return false + } + if r1.Certificate != r2.Certificate { + return false + } + return true +} + +func (r1 *TSIG) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TSIG) + if !ok { + return false + } + _ = r2 + if !isDuplicateName(r1.Algorithm, r2.Algorithm) { + return false + } + if r1.TimeSigned != r2.TimeSigned { + return false + } + if r1.Fudge != r2.Fudge { + return false + } + if r1.MACSize != r2.MACSize { + return false + } + if r1.MAC != r2.MAC { + return false + } + if r1.OrigId != r2.OrigId { + return false + } + if r1.Error != r2.Error { + return false + } + if r1.OtherLen != r2.OtherLen { + return false + } + if r1.OtherData != r2.OtherData { + return false + } + return true +} + +func (r1 *TXT) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*TXT) + if !ok { + return false + } + _ = r2 + if len(r1.Txt) != len(r2.Txt) { + return false + } + for i := 0; i < len(r1.Txt); i++ { + if r1.Txt[i] != r2.Txt[i] { + return false + } + } + return true +} + +func (r1 *UID) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*UID) + if !ok { + return false + } + _ = r2 + if r1.Uid != r2.Uid { + return false + } + return true +} + +func (r1 *UINFO) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*UINFO) + if !ok { + return false + } + _ = r2 + if r1.Uinfo != r2.Uinfo { + return false + } + return true +} + +func (r1 *URI) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*URI) + if !ok { + return false + } + _ = r2 + if r1.Priority != r2.Priority { + return false + } + if r1.Weight != r2.Weight { + return false + } + if r1.Target != r2.Target { + return false + } + return true +} + +func (r1 *X25) isDuplicate(_r2 RR) bool { + r2, ok := _r2.(*X25) + if !ok { + return false + } + _ = r2 + if r1.PSDNAddress != r2.PSDNAddress { + return false + } + return true +} diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go new file mode 100644 index 00000000..c4cf4757 --- /dev/null +++ b/vendor/github.com/miekg/dns/zmsg.go @@ -0,0 +1,2722 @@ +// Code generated by "go run msg_generate.go"; DO NOT EDIT. + +package dns + +// pack*() functions + +func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDataA(rr.A, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDataAAAA(rr.AAAA, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Subtype, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Hostname, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + return off, nil +} + +func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringTxt(rr.Txt, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Flag, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Tag, msg, off) + if err != nil { + return off, err + } + off, err = packStringOctet(rr.Value, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Type, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.Certificate, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Target, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint32(rr.Serial, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packDataNsec(rr.TypeBitMap, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringBase64(rr.Digest, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Target, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringHex(rr.Endpoint, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint48(rr.Address, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint64(rr.Address, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint32(rr.Gid, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packString(rr.Longitude, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Latitude, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Altitude, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packString(rr.Cpu, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Os, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.HitLength, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.PublicKeyAlgorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.PublicKeyLength, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Hit, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Exchanger, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDataA(rr.Locator32, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packUint64(rr.Locator64, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Version, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Size, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.HorizPre, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.VertPre, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Latitude, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Longitude, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Altitude, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Fqdn, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Mb, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Md, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Mf, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Mg, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Rmail, msg, off, compression, compress) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Email, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Mr, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Mx, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Order, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Service, msg, off) + if err != nil { + return off, err + } + off, err = packString(rr.Regexp, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Replacement, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packUint64(rr.NodeID, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringHex(rr.Locator, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringTxt(rr.ZSData, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Ns, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Ptr, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.NextDomain, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packDataNsec(rr.TypeBitMap, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Hash, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Iterations, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.SaltLength, msg, off) + if err != nil { + return off, err + } + // Only pack salt if value is not "-", i.e. empty + if rr.Salt != "-" { + off, err = packStringHex(rr.Salt, msg, off) + if err != nil { + return off, err + } + } + off, err = packUint8(rr.HashLength, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase32(rr.NextDomain, msg, off) + if err != nil { + return off, err + } + off, err = packDataNsec(rr.TypeBitMap, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Hash, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Iterations, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.SaltLength, msg, off) + if err != nil { + return off, err + } + // Only pack salt if value is not "-", i.e. empty + if rr.Salt != "-" { + off, err = packStringHex(rr.Salt, msg, off) + if err != nil { + return off, err + } + } + return off, nil +} + +func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringAny(rr.Data, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDataOpt(rr.Option, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *PTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Ptr, msg, off, compression, compress) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Map822, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Mapx400, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringHex(rr.Rdata, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Flags, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Protocol, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.PublicKey, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Mbox, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Txt, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.TypeCovered, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Labels, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.OrigTtl, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Expiration, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Inception, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.SignerName, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.Signature, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Preference, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Host, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.TypeCovered, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Labels, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.OrigTtl, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Expiration, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Inception, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.SignerName, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packStringBase64(rr.Signature, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Usage, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Selector, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.MatchingType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Certificate, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Ns, msg, off, compression, compress) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Mbox, msg, off, compression, compress) + if err != nil { + return off, err + } + off, err = packUint32(rr.Serial, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Refresh, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Retry, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Expire, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Minttl, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringTxt(rr.Txt, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SRV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Priority, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Weight, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Port, msg, off) + if err != nil { + return off, err + } + off, err = packDomainName(rr.Target, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Type, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.FingerPrint, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.KeyTag, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Algorithm, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.DigestType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Digest, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.PreviousName, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packDomainName(rr.NextName, msg, off, compression, false) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Algorithm, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packUint32(rr.Inception, msg, off) + if err != nil { + return off, err + } + off, err = packUint32(rr.Expiration, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Mode, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Error, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.KeySize, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Key, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.OtherLen, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.OtherData, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint8(rr.Usage, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Selector, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.MatchingType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Certificate, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packDomainName(rr.Algorithm, msg, off, compression, false) + if err != nil { + return off, err + } + off, err = packUint48(rr.TimeSigned, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Fudge, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.MACSize, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.MAC, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.OrigId, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Error, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.OtherLen, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.OtherData, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packStringTxt(rr.Txt, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint32(rr.Uid, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packString(rr.Uinfo, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *URI) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packUint16(rr.Priority, msg, off) + if err != nil { + return off, err + } + off, err = packUint16(rr.Weight, msg, off) + if err != nil { + return off, err + } + off, err = packStringOctet(rr.Target, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { + off, err = packString(rr.PSDNAddress, msg, off) + if err != nil { + return off, err + } + return off, nil +} + +// unpack*() functions + +func (rr *A) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.A, off, err = unpackDataA(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *AAAA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.AAAA, off, err = unpackDataAAAA(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Subtype, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Hostname, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + return off, nil +} + +func (rr *AVC) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Txt, off, err = unpackStringTxt(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CAA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Flag, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Tag, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Value, off, err = unpackStringOctet(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CDNSKEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CDS) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CERT) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Type, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CNAME) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Target, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *CSYNC) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Serial, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.TypeBitMap, off, err = unpackDataNsec(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DHCID) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DLV) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DNAME) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Target, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DNSKEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *DS) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EID) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EUI48) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Address, off, err = unpackUint48(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *EUI64) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Address, off, err = unpackUint64(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *GID) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Gid, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *GPOS) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Longitude, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Latitude, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Altitude, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *HINFO) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Cpu, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Os, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.HitLength, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKeyLength, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength)) + if err != nil { + return off, err + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength)) + if err != nil { + return off, err + } + rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *KX) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Exchanger, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *L32) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Locator32, off, err = unpackDataA(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *L64) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Locator64, off, err = unpackUint64(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *LOC) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Version, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Size, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.HorizPre, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.VertPre, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Latitude, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Longitude, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Altitude, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *LP) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Fqdn, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MB) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Mb, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MD) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Md, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MF) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Mf, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MG) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Mg, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MINFO) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Rmail, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Email, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MR) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Mr, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *MX) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Mx, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NAPTR) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Order, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Flags, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Service, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Regexp, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Replacement, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NID) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.NodeID, off, err = unpackUint64(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NIMLOC) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NINFO) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.ZSData, off, err = unpackStringTxt(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NS) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Ns, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSAPPTR) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Ptr, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.NextDomain, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.TypeBitMap, off, err = unpackDataNsec(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC3) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Hash, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Flags, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Iterations, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.SaltLength, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) + if err != nil { + return off, err + } + rr.HashLength, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength)) + if err != nil { + return off, err + } + rr.TypeBitMap, off, err = unpackDataNsec(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NSEC3PARAM) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Hash, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Flags, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Iterations, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.SaltLength, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Data, off, err = unpackStringAny(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *OPENPGPKEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *OPT) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Option, off, err = unpackDataOpt(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *PTR) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Ptr, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *PX) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Map822, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Mapx400, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RFC3597) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RKEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Flags, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Protocol, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RP) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Mbox, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Txt, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RRSIG) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.TypeCovered, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Labels, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.OrigTtl, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Expiration, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Inception, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.SignerName, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *RT) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Preference, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Host, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SIG) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.TypeCovered, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Labels, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.OrigTtl, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Expiration, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Inception, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.SignerName, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SMIMEA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Usage, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Selector, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.MatchingType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SOA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Ns, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Mbox, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Serial, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Refresh, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Retry, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Expire, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Minttl, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SPF) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Txt, off, err = unpackStringTxt(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SRV) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Priority, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Weight, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Port, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Target, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Type, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.KeyTag, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Algorithm, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.DigestType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TALINK) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.PreviousName, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.NextName, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TKEY) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Algorithm, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Inception, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Expiration, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Mode, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Error, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.KeySize, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Key, off, err = unpackStringHex(msg, off, off+int(rr.KeySize)) + if err != nil { + return off, err + } + rr.OtherLen, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TLSA) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Usage, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Selector, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.MatchingType, off, err = unpackUint8(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TSIG) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Algorithm, off, err = UnpackDomainName(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.TimeSigned, off, err = unpackUint48(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Fudge, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.MACSize, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize)) + if err != nil { + return off, err + } + rr.OrigId, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Error, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.OtherLen, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen)) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *TXT) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Txt, off, err = unpackStringTxt(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *UID) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Uid, off, err = unpackUint32(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *UINFO) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Uinfo, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *URI) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.Priority, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Weight, off, err = unpackUint16(msg, off) + if err != nil { + return off, err + } + if off == len(msg) { + return off, nil + } + rr.Target, off, err = unpackStringOctet(msg, off) + if err != nil { + return off, err + } + return off, nil +} + +func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) { + rdStart := off + _ = rdStart + + rr.PSDNAddress, off, err = unpackString(msg, off) + if err != nil { + return off, err + } + return off, nil +} diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go new file mode 100644 index 00000000..f7ec8352 --- /dev/null +++ b/vendor/github.com/miekg/dns/ztypes.go @@ -0,0 +1,881 @@ +// Code generated by "go run types_generate.go"; DO NOT EDIT. + +package dns + +import ( + "encoding/base64" + "net" +) + +// TypeToRR is a map of constructors for each RR type. +var TypeToRR = map[uint16]func() RR{ + TypeA: func() RR { return new(A) }, + TypeAAAA: func() RR { return new(AAAA) }, + TypeAFSDB: func() RR { return new(AFSDB) }, + TypeANY: func() RR { return new(ANY) }, + TypeAVC: func() RR { return new(AVC) }, + TypeCAA: func() RR { return new(CAA) }, + TypeCDNSKEY: func() RR { return new(CDNSKEY) }, + TypeCDS: func() RR { return new(CDS) }, + TypeCERT: func() RR { return new(CERT) }, + TypeCNAME: func() RR { return new(CNAME) }, + TypeCSYNC: func() RR { return new(CSYNC) }, + TypeDHCID: func() RR { return new(DHCID) }, + TypeDLV: func() RR { return new(DLV) }, + TypeDNAME: func() RR { return new(DNAME) }, + TypeDNSKEY: func() RR { return new(DNSKEY) }, + TypeDS: func() RR { return new(DS) }, + TypeEID: func() RR { return new(EID) }, + TypeEUI48: func() RR { return new(EUI48) }, + TypeEUI64: func() RR { return new(EUI64) }, + TypeGID: func() RR { return new(GID) }, + TypeGPOS: func() RR { return new(GPOS) }, + TypeHINFO: func() RR { return new(HINFO) }, + TypeHIP: func() RR { return new(HIP) }, + TypeKEY: func() RR { return new(KEY) }, + TypeKX: func() RR { return new(KX) }, + TypeL32: func() RR { return new(L32) }, + TypeL64: func() RR { return new(L64) }, + TypeLOC: func() RR { return new(LOC) }, + TypeLP: func() RR { return new(LP) }, + TypeMB: func() RR { return new(MB) }, + TypeMD: func() RR { return new(MD) }, + TypeMF: func() RR { return new(MF) }, + TypeMG: func() RR { return new(MG) }, + TypeMINFO: func() RR { return new(MINFO) }, + TypeMR: func() RR { return new(MR) }, + TypeMX: func() RR { return new(MX) }, + TypeNAPTR: func() RR { return new(NAPTR) }, + TypeNID: func() RR { return new(NID) }, + TypeNIMLOC: func() RR { return new(NIMLOC) }, + TypeNINFO: func() RR { return new(NINFO) }, + TypeNS: func() RR { return new(NS) }, + TypeNSAPPTR: func() RR { return new(NSAPPTR) }, + TypeNSEC: func() RR { return new(NSEC) }, + TypeNSEC3: func() RR { return new(NSEC3) }, + TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) }, + TypeNULL: func() RR { return new(NULL) }, + TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) }, + TypeOPT: func() RR { return new(OPT) }, + TypePTR: func() RR { return new(PTR) }, + TypePX: func() RR { return new(PX) }, + TypeRKEY: func() RR { return new(RKEY) }, + TypeRP: func() RR { return new(RP) }, + TypeRRSIG: func() RR { return new(RRSIG) }, + TypeRT: func() RR { return new(RT) }, + TypeSIG: func() RR { return new(SIG) }, + TypeSMIMEA: func() RR { return new(SMIMEA) }, + TypeSOA: func() RR { return new(SOA) }, + TypeSPF: func() RR { return new(SPF) }, + TypeSRV: func() RR { return new(SRV) }, + TypeSSHFP: func() RR { return new(SSHFP) }, + TypeTA: func() RR { return new(TA) }, + TypeTALINK: func() RR { return new(TALINK) }, + TypeTKEY: func() RR { return new(TKEY) }, + TypeTLSA: func() RR { return new(TLSA) }, + TypeTSIG: func() RR { return new(TSIG) }, + TypeTXT: func() RR { return new(TXT) }, + TypeUID: func() RR { return new(UID) }, + TypeUINFO: func() RR { return new(UINFO) }, + TypeURI: func() RR { return new(URI) }, + TypeX25: func() RR { return new(X25) }, +} + +// TypeToString is a map of strings for each RR type. +var TypeToString = map[uint16]string{ + TypeA: "A", + TypeAAAA: "AAAA", + TypeAFSDB: "AFSDB", + TypeANY: "ANY", + TypeATMA: "ATMA", + TypeAVC: "AVC", + TypeAXFR: "AXFR", + TypeCAA: "CAA", + TypeCDNSKEY: "CDNSKEY", + TypeCDS: "CDS", + TypeCERT: "CERT", + TypeCNAME: "CNAME", + TypeCSYNC: "CSYNC", + TypeDHCID: "DHCID", + TypeDLV: "DLV", + TypeDNAME: "DNAME", + TypeDNSKEY: "DNSKEY", + TypeDS: "DS", + TypeEID: "EID", + TypeEUI48: "EUI48", + TypeEUI64: "EUI64", + TypeGID: "GID", + TypeGPOS: "GPOS", + TypeHINFO: "HINFO", + TypeHIP: "HIP", + TypeISDN: "ISDN", + TypeIXFR: "IXFR", + TypeKEY: "KEY", + TypeKX: "KX", + TypeL32: "L32", + TypeL64: "L64", + TypeLOC: "LOC", + TypeLP: "LP", + TypeMAILA: "MAILA", + TypeMAILB: "MAILB", + TypeMB: "MB", + TypeMD: "MD", + TypeMF: "MF", + TypeMG: "MG", + TypeMINFO: "MINFO", + TypeMR: "MR", + TypeMX: "MX", + TypeNAPTR: "NAPTR", + TypeNID: "NID", + TypeNIMLOC: "NIMLOC", + TypeNINFO: "NINFO", + TypeNS: "NS", + TypeNSEC: "NSEC", + TypeNSEC3: "NSEC3", + TypeNSEC3PARAM: "NSEC3PARAM", + TypeNULL: "NULL", + TypeNXT: "NXT", + TypeNone: "None", + TypeOPENPGPKEY: "OPENPGPKEY", + TypeOPT: "OPT", + TypePTR: "PTR", + TypePX: "PX", + TypeRKEY: "RKEY", + TypeRP: "RP", + TypeRRSIG: "RRSIG", + TypeRT: "RT", + TypeReserved: "Reserved", + TypeSIG: "SIG", + TypeSMIMEA: "SMIMEA", + TypeSOA: "SOA", + TypeSPF: "SPF", + TypeSRV: "SRV", + TypeSSHFP: "SSHFP", + TypeTA: "TA", + TypeTALINK: "TALINK", + TypeTKEY: "TKEY", + TypeTLSA: "TLSA", + TypeTSIG: "TSIG", + TypeTXT: "TXT", + TypeUID: "UID", + TypeUINFO: "UINFO", + TypeUNSPEC: "UNSPEC", + TypeURI: "URI", + TypeX25: "X25", + TypeNSAPPTR: "NSAP-PTR", +} + +func (rr *A) Header() *RR_Header { return &rr.Hdr } +func (rr *AAAA) Header() *RR_Header { return &rr.Hdr } +func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr } +func (rr *ANY) Header() *RR_Header { return &rr.Hdr } +func (rr *AVC) Header() *RR_Header { return &rr.Hdr } +func (rr *CAA) Header() *RR_Header { return &rr.Hdr } +func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr } +func (rr *CDS) Header() *RR_Header { return &rr.Hdr } +func (rr *CERT) Header() *RR_Header { return &rr.Hdr } +func (rr *CNAME) Header() *RR_Header { return &rr.Hdr } +func (rr *CSYNC) Header() *RR_Header { return &rr.Hdr } +func (rr *DHCID) Header() *RR_Header { return &rr.Hdr } +func (rr *DLV) Header() *RR_Header { return &rr.Hdr } +func (rr *DNAME) Header() *RR_Header { return &rr.Hdr } +func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr } +func (rr *DS) Header() *RR_Header { return &rr.Hdr } +func (rr *EID) Header() *RR_Header { return &rr.Hdr } +func (rr *EUI48) Header() *RR_Header { return &rr.Hdr } +func (rr *EUI64) Header() *RR_Header { return &rr.Hdr } +func (rr *GID) Header() *RR_Header { return &rr.Hdr } +func (rr *GPOS) Header() *RR_Header { return &rr.Hdr } +func (rr *HINFO) Header() *RR_Header { return &rr.Hdr } +func (rr *HIP) Header() *RR_Header { return &rr.Hdr } +func (rr *KEY) Header() *RR_Header { return &rr.Hdr } +func (rr *KX) Header() *RR_Header { return &rr.Hdr } +func (rr *L32) Header() *RR_Header { return &rr.Hdr } +func (rr *L64) Header() *RR_Header { return &rr.Hdr } +func (rr *LOC) Header() *RR_Header { return &rr.Hdr } +func (rr *LP) Header() *RR_Header { return &rr.Hdr } +func (rr *MB) Header() *RR_Header { return &rr.Hdr } +func (rr *MD) Header() *RR_Header { return &rr.Hdr } +func (rr *MF) Header() *RR_Header { return &rr.Hdr } +func (rr *MG) Header() *RR_Header { return &rr.Hdr } +func (rr *MINFO) Header() *RR_Header { return &rr.Hdr } +func (rr *MR) Header() *RR_Header { return &rr.Hdr } +func (rr *MX) Header() *RR_Header { return &rr.Hdr } +func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr } +func (rr *NID) Header() *RR_Header { return &rr.Hdr } +func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr } +func (rr *NINFO) Header() *RR_Header { return &rr.Hdr } +func (rr *NS) Header() *RR_Header { return &rr.Hdr } +func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr } +func (rr *NSEC) Header() *RR_Header { return &rr.Hdr } +func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr } +func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr } +func (rr *NULL) Header() *RR_Header { return &rr.Hdr } +func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr } +func (rr *OPT) Header() *RR_Header { return &rr.Hdr } +func (rr *PTR) Header() *RR_Header { return &rr.Hdr } +func (rr *PX) Header() *RR_Header { return &rr.Hdr } +func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr } +func (rr *RKEY) Header() *RR_Header { return &rr.Hdr } +func (rr *RP) Header() *RR_Header { return &rr.Hdr } +func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr } +func (rr *RT) Header() *RR_Header { return &rr.Hdr } +func (rr *SIG) Header() *RR_Header { return &rr.Hdr } +func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr } +func (rr *SOA) Header() *RR_Header { return &rr.Hdr } +func (rr *SPF) Header() *RR_Header { return &rr.Hdr } +func (rr *SRV) Header() *RR_Header { return &rr.Hdr } +func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr } +func (rr *TA) Header() *RR_Header { return &rr.Hdr } +func (rr *TALINK) Header() *RR_Header { return &rr.Hdr } +func (rr *TKEY) Header() *RR_Header { return &rr.Hdr } +func (rr *TLSA) Header() *RR_Header { return &rr.Hdr } +func (rr *TSIG) Header() *RR_Header { return &rr.Hdr } +func (rr *TXT) Header() *RR_Header { return &rr.Hdr } +func (rr *UID) Header() *RR_Header { return &rr.Hdr } +func (rr *UINFO) Header() *RR_Header { return &rr.Hdr } +func (rr *URI) Header() *RR_Header { return &rr.Hdr } +func (rr *X25) Header() *RR_Header { return &rr.Hdr } + +// len() functions +func (rr *A) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + if len(rr.A) != 0 { + l += net.IPv4len + } + return l +} +func (rr *AAAA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + if len(rr.AAAA) != 0 { + l += net.IPv6len + } + return l +} +func (rr *AFSDB) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Subtype + l += domainNameLen(rr.Hostname, off+l, compression, false) + return l +} +func (rr *ANY) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + return l +} +func (rr *AVC) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + for _, x := range rr.Txt { + l += len(x) + 1 + } + return l +} +func (rr *CAA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Flag + l += len(rr.Tag) + 1 + l += len(rr.Value) + return l +} +func (rr *CERT) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Type + l += 2 // KeyTag + l++ // Algorithm + l += base64.StdEncoding.DecodedLen(len(rr.Certificate)) + return l +} +func (rr *CNAME) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Target, off+l, compression, true) + return l +} +func (rr *DHCID) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += base64.StdEncoding.DecodedLen(len(rr.Digest)) + return l +} +func (rr *DNAME) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Target, off+l, compression, false) + return l +} +func (rr *DNSKEY) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Flags + l++ // Protocol + l++ // Algorithm + l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) + return l +} +func (rr *DS) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // KeyTag + l++ // Algorithm + l++ // DigestType + l += len(rr.Digest) / 2 + return l +} +func (rr *EID) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Endpoint) / 2 + return l +} +func (rr *EUI48) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 6 // Address + return l +} +func (rr *EUI64) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 8 // Address + return l +} +func (rr *GID) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 4 // Gid + return l +} +func (rr *GPOS) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Longitude) + 1 + l += len(rr.Latitude) + 1 + l += len(rr.Altitude) + 1 + return l +} +func (rr *HINFO) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Cpu) + 1 + l += len(rr.Os) + 1 + return l +} +func (rr *HIP) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // HitLength + l++ // PublicKeyAlgorithm + l += 2 // PublicKeyLength + l += len(rr.Hit) / 2 + l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) + for _, x := range rr.RendezvousServers { + l += domainNameLen(x, off+l, compression, false) + } + return l +} +func (rr *KX) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += domainNameLen(rr.Exchanger, off+l, compression, false) + return l +} +func (rr *L32) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + if len(rr.Locator32) != 0 { + l += net.IPv4len + } + return l +} +func (rr *L64) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += 8 // Locator64 + return l +} +func (rr *LOC) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Version + l++ // Size + l++ // HorizPre + l++ // VertPre + l += 4 // Latitude + l += 4 // Longitude + l += 4 // Altitude + return l +} +func (rr *LP) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += domainNameLen(rr.Fqdn, off+l, compression, false) + return l +} +func (rr *MB) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Mb, off+l, compression, true) + return l +} +func (rr *MD) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Md, off+l, compression, true) + return l +} +func (rr *MF) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Mf, off+l, compression, true) + return l +} +func (rr *MG) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Mg, off+l, compression, true) + return l +} +func (rr *MINFO) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Rmail, off+l, compression, true) + l += domainNameLen(rr.Email, off+l, compression, true) + return l +} +func (rr *MR) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Mr, off+l, compression, true) + return l +} +func (rr *MX) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += domainNameLen(rr.Mx, off+l, compression, true) + return l +} +func (rr *NAPTR) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Order + l += 2 // Preference + l += len(rr.Flags) + 1 + l += len(rr.Service) + 1 + l += len(rr.Regexp) + 1 + l += domainNameLen(rr.Replacement, off+l, compression, false) + return l +} +func (rr *NID) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += 8 // NodeID + return l +} +func (rr *NIMLOC) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Locator) / 2 + return l +} +func (rr *NINFO) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + for _, x := range rr.ZSData { + l += len(x) + 1 + } + return l +} +func (rr *NS) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Ns, off+l, compression, true) + return l +} +func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Ptr, off+l, compression, false) + return l +} +func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Hash + l++ // Flags + l += 2 // Iterations + l++ // SaltLength + l += len(rr.Salt) / 2 + return l +} +func (rr *NULL) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Data) + return l +} +func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) + return l +} +func (rr *PTR) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Ptr, off+l, compression, true) + return l +} +func (rr *PX) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += domainNameLen(rr.Map822, off+l, compression, false) + l += domainNameLen(rr.Mapx400, off+l, compression, false) + return l +} +func (rr *RFC3597) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Rdata) / 2 + return l +} +func (rr *RKEY) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Flags + l++ // Protocol + l++ // Algorithm + l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) + return l +} +func (rr *RP) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Mbox, off+l, compression, false) + l += domainNameLen(rr.Txt, off+l, compression, false) + return l +} +func (rr *RRSIG) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // TypeCovered + l++ // Algorithm + l++ // Labels + l += 4 // OrigTtl + l += 4 // Expiration + l += 4 // Inception + l += 2 // KeyTag + l += domainNameLen(rr.SignerName, off+l, compression, false) + l += base64.StdEncoding.DecodedLen(len(rr.Signature)) + return l +} +func (rr *RT) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Preference + l += domainNameLen(rr.Host, off+l, compression, false) + return l +} +func (rr *SMIMEA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Usage + l++ // Selector + l++ // MatchingType + l += len(rr.Certificate) / 2 + return l +} +func (rr *SOA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Ns, off+l, compression, true) + l += domainNameLen(rr.Mbox, off+l, compression, true) + l += 4 // Serial + l += 4 // Refresh + l += 4 // Retry + l += 4 // Expire + l += 4 // Minttl + return l +} +func (rr *SPF) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + for _, x := range rr.Txt { + l += len(x) + 1 + } + return l +} +func (rr *SRV) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Priority + l += 2 // Weight + l += 2 // Port + l += domainNameLen(rr.Target, off+l, compression, false) + return l +} +func (rr *SSHFP) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Algorithm + l++ // Type + l += len(rr.FingerPrint) / 2 + return l +} +func (rr *TA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // KeyTag + l++ // Algorithm + l++ // DigestType + l += len(rr.Digest) / 2 + return l +} +func (rr *TALINK) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.PreviousName, off+l, compression, false) + l += domainNameLen(rr.NextName, off+l, compression, false) + return l +} +func (rr *TKEY) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Algorithm, off+l, compression, false) + l += 4 // Inception + l += 4 // Expiration + l += 2 // Mode + l += 2 // Error + l += 2 // KeySize + l += len(rr.Key) / 2 + l += 2 // OtherLen + l += len(rr.OtherData) / 2 + return l +} +func (rr *TLSA) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l++ // Usage + l++ // Selector + l++ // MatchingType + l += len(rr.Certificate) / 2 + return l +} +func (rr *TSIG) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += domainNameLen(rr.Algorithm, off+l, compression, false) + l += 6 // TimeSigned + l += 2 // Fudge + l += 2 // MACSize + l += len(rr.MAC) / 2 + l += 2 // OrigId + l += 2 // Error + l += 2 // OtherLen + l += len(rr.OtherData) / 2 + return l +} +func (rr *TXT) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + for _, x := range rr.Txt { + l += len(x) + 1 + } + return l +} +func (rr *UID) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 4 // Uid + return l +} +func (rr *UINFO) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.Uinfo) + 1 + return l +} +func (rr *URI) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += 2 // Priority + l += 2 // Weight + l += len(rr.Target) + return l +} +func (rr *X25) len(off int, compression map[string]struct{}) int { + l := rr.Hdr.len(off, compression) + l += len(rr.PSDNAddress) + 1 + return l +} + +// copy() functions +func (rr *A) copy() RR { + return &A{rr.Hdr, copyIP(rr.A)} +} +func (rr *AAAA) copy() RR { + return &AAAA{rr.Hdr, copyIP(rr.AAAA)} +} +func (rr *AFSDB) copy() RR { + return &AFSDB{rr.Hdr, rr.Subtype, rr.Hostname} +} +func (rr *ANY) copy() RR { + return &ANY{rr.Hdr} +} +func (rr *AVC) copy() RR { + Txt := make([]string, len(rr.Txt)) + copy(Txt, rr.Txt) + return &AVC{rr.Hdr, Txt} +} +func (rr *CAA) copy() RR { + return &CAA{rr.Hdr, rr.Flag, rr.Tag, rr.Value} +} +func (rr *CERT) copy() RR { + return &CERT{rr.Hdr, rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate} +} +func (rr *CNAME) copy() RR { + return &CNAME{rr.Hdr, rr.Target} +} +func (rr *CSYNC) copy() RR { + TypeBitMap := make([]uint16, len(rr.TypeBitMap)) + copy(TypeBitMap, rr.TypeBitMap) + return &CSYNC{rr.Hdr, rr.Serial, rr.Flags, TypeBitMap} +} +func (rr *DHCID) copy() RR { + return &DHCID{rr.Hdr, rr.Digest} +} +func (rr *DNAME) copy() RR { + return &DNAME{rr.Hdr, rr.Target} +} +func (rr *DNSKEY) copy() RR { + return &DNSKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey} +} +func (rr *DS) copy() RR { + return &DS{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest} +} +func (rr *EID) copy() RR { + return &EID{rr.Hdr, rr.Endpoint} +} +func (rr *EUI48) copy() RR { + return &EUI48{rr.Hdr, rr.Address} +} +func (rr *EUI64) copy() RR { + return &EUI64{rr.Hdr, rr.Address} +} +func (rr *GID) copy() RR { + return &GID{rr.Hdr, rr.Gid} +} +func (rr *GPOS) copy() RR { + return &GPOS{rr.Hdr, rr.Longitude, rr.Latitude, rr.Altitude} +} +func (rr *HINFO) copy() RR { + return &HINFO{rr.Hdr, rr.Cpu, rr.Os} +} +func (rr *HIP) copy() RR { + RendezvousServers := make([]string, len(rr.RendezvousServers)) + copy(RendezvousServers, rr.RendezvousServers) + return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers} +} +func (rr *KX) copy() RR { + return &KX{rr.Hdr, rr.Preference, rr.Exchanger} +} +func (rr *L32) copy() RR { + return &L32{rr.Hdr, rr.Preference, copyIP(rr.Locator32)} +} +func (rr *L64) copy() RR { + return &L64{rr.Hdr, rr.Preference, rr.Locator64} +} +func (rr *LOC) copy() RR { + return &LOC{rr.Hdr, rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude} +} +func (rr *LP) copy() RR { + return &LP{rr.Hdr, rr.Preference, rr.Fqdn} +} +func (rr *MB) copy() RR { + return &MB{rr.Hdr, rr.Mb} +} +func (rr *MD) copy() RR { + return &MD{rr.Hdr, rr.Md} +} +func (rr *MF) copy() RR { + return &MF{rr.Hdr, rr.Mf} +} +func (rr *MG) copy() RR { + return &MG{rr.Hdr, rr.Mg} +} +func (rr *MINFO) copy() RR { + return &MINFO{rr.Hdr, rr.Rmail, rr.Email} +} +func (rr *MR) copy() RR { + return &MR{rr.Hdr, rr.Mr} +} +func (rr *MX) copy() RR { + return &MX{rr.Hdr, rr.Preference, rr.Mx} +} +func (rr *NAPTR) copy() RR { + return &NAPTR{rr.Hdr, rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement} +} +func (rr *NID) copy() RR { + return &NID{rr.Hdr, rr.Preference, rr.NodeID} +} +func (rr *NIMLOC) copy() RR { + return &NIMLOC{rr.Hdr, rr.Locator} +} +func (rr *NINFO) copy() RR { + ZSData := make([]string, len(rr.ZSData)) + copy(ZSData, rr.ZSData) + return &NINFO{rr.Hdr, ZSData} +} +func (rr *NS) copy() RR { + return &NS{rr.Hdr, rr.Ns} +} +func (rr *NSAPPTR) copy() RR { + return &NSAPPTR{rr.Hdr, rr.Ptr} +} +func (rr *NSEC) copy() RR { + TypeBitMap := make([]uint16, len(rr.TypeBitMap)) + copy(TypeBitMap, rr.TypeBitMap) + return &NSEC{rr.Hdr, rr.NextDomain, TypeBitMap} +} +func (rr *NSEC3) copy() RR { + TypeBitMap := make([]uint16, len(rr.TypeBitMap)) + copy(TypeBitMap, rr.TypeBitMap) + return &NSEC3{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap} +} +func (rr *NSEC3PARAM) copy() RR { + return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt} +} +func (rr *NULL) copy() RR { + return &NULL{rr.Hdr, rr.Data} +} +func (rr *OPENPGPKEY) copy() RR { + return &OPENPGPKEY{rr.Hdr, rr.PublicKey} +} +func (rr *OPT) copy() RR { + Option := make([]EDNS0, len(rr.Option)) + for i, e := range rr.Option { + Option[i] = e.copy() + } + return &OPT{rr.Hdr, Option} +} +func (rr *PTR) copy() RR { + return &PTR{rr.Hdr, rr.Ptr} +} +func (rr *PX) copy() RR { + return &PX{rr.Hdr, rr.Preference, rr.Map822, rr.Mapx400} +} +func (rr *RFC3597) copy() RR { + return &RFC3597{rr.Hdr, rr.Rdata} +} +func (rr *RKEY) copy() RR { + return &RKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey} +} +func (rr *RP) copy() RR { + return &RP{rr.Hdr, rr.Mbox, rr.Txt} +} +func (rr *RRSIG) copy() RR { + return &RRSIG{rr.Hdr, rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature} +} +func (rr *RT) copy() RR { + return &RT{rr.Hdr, rr.Preference, rr.Host} +} +func (rr *SMIMEA) copy() RR { + return &SMIMEA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate} +} +func (rr *SOA) copy() RR { + return &SOA{rr.Hdr, rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl} +} +func (rr *SPF) copy() RR { + Txt := make([]string, len(rr.Txt)) + copy(Txt, rr.Txt) + return &SPF{rr.Hdr, Txt} +} +func (rr *SRV) copy() RR { + return &SRV{rr.Hdr, rr.Priority, rr.Weight, rr.Port, rr.Target} +} +func (rr *SSHFP) copy() RR { + return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint} +} +func (rr *TA) copy() RR { + return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest} +} +func (rr *TALINK) copy() RR { + return &TALINK{rr.Hdr, rr.PreviousName, rr.NextName} +} +func (rr *TKEY) copy() RR { + return &TKEY{rr.Hdr, rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData} +} +func (rr *TLSA) copy() RR { + return &TLSA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate} +} +func (rr *TSIG) copy() RR { + return &TSIG{rr.Hdr, rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData} +} +func (rr *TXT) copy() RR { + Txt := make([]string, len(rr.Txt)) + copy(Txt, rr.Txt) + return &TXT{rr.Hdr, Txt} +} +func (rr *UID) copy() RR { + return &UID{rr.Hdr, rr.Uid} +} +func (rr *UINFO) copy() RR { + return &UINFO{rr.Hdr, rr.Uinfo} +} +func (rr *URI) copy() RR { + return &URI{rr.Hdr, rr.Priority, rr.Weight, rr.Target} +} +func (rr *X25) copy() RR { + return &X25{rr.Hdr, rr.PSDNAddress} +} diff --git a/vendor/github.com/minio/blake2b-simd/.gitignore b/vendor/github.com/minio/blake2b-simd/.gitignore new file mode 100644 index 00000000..c56069fe --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/.gitignore @@ -0,0 +1 @@ +*.test \ No newline at end of file diff --git a/vendor/github.com/minio/blake2b-simd/.travis.yml b/vendor/github.com/minio/blake2b-simd/.travis.yml new file mode 100644 index 00000000..545066eb --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/.travis.yml @@ -0,0 +1,21 @@ +sudo: required +dist: trusty +language: go + +os: +- linux +- osx + +osx_image: xcode7.2 + +go: +- 1.6 +- 1.5 + +env: +- ARCH=x86_64 +- ARCH=i686 + +script: +- diff -au <(gofmt -d .) <(printf "") +- go test -race -v ./... diff --git a/vendor/github.com/minio/blake2b-simd/LICENSE b/vendor/github.com/minio/blake2b-simd/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/minio/blake2b-simd/README.md b/vendor/github.com/minio/blake2b-simd/README.md new file mode 100644 index 00000000..31fcbf74 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/README.md @@ -0,0 +1,144 @@ +BLAKE2b-SIMD +============ + +Pure Go implementation of BLAKE2b using SIMD optimizations. + +Introduction +------------ + +This package was initially based on the pure go [BLAKE2b](https://github.com/dchest/blake2b) implementation of Dmitry Chestnykh and merged with the (`cgo` dependent) AVX optimized [BLAKE2](https://github.com/codahale/blake2) implementation (which in turn is based on the [official implementation](https://github.com/BLAKE2/BLAKE2). It does so by using [Go's Assembler](https://golang.org/doc/asm) for amd64 architectures with a golang only fallback for other architectures. + +In addition to AVX there is also support for AVX2 as well as SSE. Best performance is obtained with AVX2 which gives roughly a **4X** performance increase approaching hashing speeds of **1GB/sec** on a single core. + +Benchmarks +---------- + +This is a summary of the performance improvements. Full details are shown below. + +| Technology | 128K | +| ---------- |:-----:| +| AVX2 | 3.94x | +| AVX | 3.28x | +| SSE | 2.85x | + +asm2plan9s +---------- + +In order to be able to work more easily with AVX2/AVX instructions, a separate tool was developed to convert AVX2/AVX instructions into the corresponding BYTE sequence as accepted by Go assembly. See [asm2plan9s](https://github.com/minio/asm2plan9s) for more information. + +bt2sum +------ + +[bt2sum](https://github.com/s3git/bt2sum) is a utility that takes advantages of the BLAKE2b SIMD optimizations to compute check sums using the BLAKE2 Tree hashing mode in so called 'unlimited fanout' mode. + +Technical details +----------------- + +BLAKE2b is a hashing algorithm that operates on 64-bit integer values. The AVX2 version uses the 256-bit wide YMM registers in order to essentially process four operations in parallel. AVX and SSE operate on 128-bit values simultaneously (two operations in parallel). Below are excerpts from `compressAvx2_amd64.s`, `compressAvx_amd64.s`, and `compress_generic.go` respectively. + +``` + VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ +``` + +``` + VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ + VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ +``` + +``` + v0 += v4 + v1 += v5 + v2 += v6 + v3 += v7 +``` + +Detailed benchmarks +------------------- + +Example performance metrics were generated on Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz - 6 physical cores, 12 logical cores running Ubuntu GNU/Linux with kernel version 4.4.0-24-generic (vanilla with no optimizations). + +### AVX2 + +``` +$ benchcmp go.txt avx2.txt +benchmark old ns/op new ns/op delta +BenchmarkHash64-12 1481 849 -42.67% +BenchmarkHash128-12 1428 746 -47.76% +BenchmarkHash1K-12 6379 2227 -65.09% +BenchmarkHash8K-12 37219 11714 -68.53% +BenchmarkHash32K-12 140716 35935 -74.46% +BenchmarkHash128K-12 561656 142634 -74.60% + +benchmark old MB/s new MB/s speedup +BenchmarkHash64-12 43.20 75.37 1.74x +BenchmarkHash128-12 89.64 171.35 1.91x +BenchmarkHash1K-12 160.52 459.69 2.86x +BenchmarkHash8K-12 220.10 699.32 3.18x +BenchmarkHash32K-12 232.87 911.85 3.92x +BenchmarkHash128K-12 233.37 918.93 3.94x +``` + +### AVX2: Comparison to other hashing techniques + +``` +$ go test -bench=Comparison +BenchmarkComparisonMD5-12 1000 1726121 ns/op 607.48 MB/s +BenchmarkComparisonSHA1-12 500 2005164 ns/op 522.94 MB/s +BenchmarkComparisonSHA256-12 300 5531036 ns/op 189.58 MB/s +BenchmarkComparisonSHA512-12 500 3423030 ns/op 306.33 MB/s +BenchmarkComparisonBlake2B-12 1000 1232690 ns/op 850.64 MB/s +``` + +Benchmarks below were generated on a MacBook Pro with a 2.7 GHz Intel Core i7. + +### AVX + +``` +$ benchcmp go.txt avx.txt +benchmark old ns/op new ns/op delta +BenchmarkHash64-8 813 458 -43.67% +BenchmarkHash128-8 766 401 -47.65% +BenchmarkHash1K-8 4881 1763 -63.88% +BenchmarkHash8K-8 36127 12273 -66.03% +BenchmarkHash32K-8 140582 43155 -69.30% +BenchmarkHash128K-8 567850 173246 -69.49% + +benchmark old MB/s new MB/s speedup +BenchmarkHash64-8 78.63 139.57 1.78x +BenchmarkHash128-8 166.98 318.73 1.91x +BenchmarkHash1K-8 209.76 580.68 2.77x +BenchmarkHash8K-8 226.76 667.46 2.94x +BenchmarkHash32K-8 233.09 759.29 3.26x +BenchmarkHash128K-8 230.82 756.56 3.28x +``` + +### SSE + +``` +$ benchcmp go.txt sse.txt +benchmark old ns/op new ns/op delta +BenchmarkHash64-8 813 478 -41.21% +BenchmarkHash128-8 766 411 -46.34% +BenchmarkHash1K-8 4881 1870 -61.69% +BenchmarkHash8K-8 36127 12427 -65.60% +BenchmarkHash32K-8 140582 49512 -64.78% +BenchmarkHash128K-8 567850 199040 -64.95% + +benchmark old MB/s new MB/s speedup +BenchmarkHash64-8 78.63 133.78 1.70x +BenchmarkHash128-8 166.98 311.23 1.86x +BenchmarkHash1K-8 209.76 547.37 2.61x +BenchmarkHash8K-8 226.76 659.20 2.91x +BenchmarkHash32K-8 233.09 661.81 2.84x +BenchmarkHash128K-8 230.82 658.52 2.85x +``` + +License +------- + +Released under the Apache License v2.0. You can find the complete text in the file LICENSE. + +Contributing +------------ + +Contributions are welcome, please send PRs for any enhancements. diff --git a/vendor/github.com/minio/blake2b-simd/appveyor.yml b/vendor/github.com/minio/blake2b-simd/appveyor.yml new file mode 100644 index 00000000..77595feb --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/appveyor.yml @@ -0,0 +1,32 @@ +# version format +version: "{build}" + +# Operating system (build VM template) +os: Windows Server 2012 R2 + +# Platform. +platform: x64 + +clone_folder: c:\gopath\src\github.com\minio\blake2b-simd + +# environment variables +environment: + GOPATH: c:\gopath + GO15VENDOREXPERIMENT: 1 + +# scripts that run after cloning repository +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version + - go env + +# to run your custom scripts instead of automatic MSBuild +build_script: + - go test . + - go test -race . + +# to disable automatic tests +test: off + +# to disable deployment +deploy: off diff --git a/vendor/github.com/minio/blake2b-simd/blake2b.go b/vendor/github.com/minio/blake2b-simd/blake2b.go new file mode 100644 index 00000000..538466a1 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/blake2b.go @@ -0,0 +1,301 @@ +// Written in 2012 by Dmitry Chestnykh. +// +// To the extent possible under law, the author have dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// http://creativecommons.org/publicdomain/zero/1.0/ + +// Package blake2b implements BLAKE2b cryptographic hash function. +package blake2b + +import ( + "encoding/binary" + "errors" + "hash" +) + +const ( + BlockSize = 128 // block size of algorithm + Size = 64 // maximum digest size + SaltSize = 16 // maximum salt size + PersonSize = 16 // maximum personalization string size + KeySize = 64 // maximum size of key +) + +type digest struct { + h [8]uint64 // current chain value + t [2]uint64 // message bytes counter + f [2]uint64 // finalization flags + x [BlockSize]byte // buffer for data not yet compressed + nx int // number of bytes in buffer + + ih [8]uint64 // initial chain value (after config) + paddedKey [BlockSize]byte // copy of key, padded with zeros + isKeyed bool // indicates whether hash was keyed + size uint8 // digest size in bytes + isLastNode bool // indicates processing of the last node in tree hashing +} + +// Initialization values. +var iv = [8]uint64{ + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, +} + +// Config is used to configure hash function parameters and keying. +// All parameters are optional. +type Config struct { + Size uint8 // digest size (if zero, default size of 64 bytes is used) + Key []byte // key for prefix-MAC + Salt []byte // salt (if < 16 bytes, padded with zeros) + Person []byte // personalization (if < 16 bytes, padded with zeros) + Tree *Tree // parameters for tree hashing +} + +// Tree represents parameters for tree hashing. +type Tree struct { + Fanout uint8 // fanout + MaxDepth uint8 // maximal depth + LeafSize uint32 // leaf maximal byte length (0 for unlimited) + NodeOffset uint64 // node offset (0 for first, leftmost or leaf) + NodeDepth uint8 // node depth (0 for leaves) + InnerHashSize uint8 // inner hash byte length + IsLastNode bool // indicates processing of the last node of layer +} + +var ( + defaultConfig = &Config{Size: Size} + config256 = &Config{Size: 32} +) + +func verifyConfig(c *Config) error { + if c.Size > Size { + return errors.New("digest size is too large") + } + if len(c.Key) > KeySize { + return errors.New("key is too large") + } + if len(c.Salt) > SaltSize { + // Smaller salt is okay: it will be padded with zeros. + return errors.New("salt is too large") + } + if len(c.Person) > PersonSize { + // Smaller personalization is okay: it will be padded with zeros. + return errors.New("personalization is too large") + } + if c.Tree != nil { + if c.Tree.Fanout == 1 { + return errors.New("fanout of 1 is not allowed in tree mode") + } + if c.Tree.MaxDepth < 2 { + return errors.New("incorrect tree depth") + } + if c.Tree.InnerHashSize < 1 || c.Tree.InnerHashSize > Size { + return errors.New("incorrect tree inner hash size") + } + } + return nil +} + +// New returns a new hash.Hash configured with the given Config. +// Config can be nil, in which case the default one is used, calculating 64-byte digest. +// Returns non-nil error if Config contains invalid parameters. +func New(c *Config) (hash.Hash, error) { + if c == nil { + c = defaultConfig + } else { + if c.Size == 0 { + // Set default size if it's zero. + c.Size = Size + } + if err := verifyConfig(c); err != nil { + return nil, err + } + } + d := new(digest) + d.initialize(c) + return d, nil +} + +// initialize initializes digest with the given +// config, which must be non-nil and verified. +func (d *digest) initialize(c *Config) { + // Create parameter block. + var p [BlockSize]byte + p[0] = c.Size + p[1] = uint8(len(c.Key)) + if c.Salt != nil { + copy(p[32:], c.Salt) + } + if c.Person != nil { + copy(p[48:], c.Person) + } + if c.Tree != nil { + p[2] = c.Tree.Fanout + p[3] = c.Tree.MaxDepth + binary.LittleEndian.PutUint32(p[4:], c.Tree.LeafSize) + binary.LittleEndian.PutUint64(p[8:], c.Tree.NodeOffset) + p[16] = c.Tree.NodeDepth + p[17] = c.Tree.InnerHashSize + } else { + p[2] = 1 + p[3] = 1 + } + + // Initialize. + d.size = c.Size + for i := 0; i < 8; i++ { + d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(p[i*8:]) + } + if c.Tree != nil && c.Tree.IsLastNode { + d.isLastNode = true + } + + // Process key. + if c.Key != nil { + copy(d.paddedKey[:], c.Key) + d.Write(d.paddedKey[:]) + d.isKeyed = true + } + // Save a copy of initialized state. + copy(d.ih[:], d.h[:]) +} + +// New512 returns a new hash.Hash computing the BLAKE2b 64-byte checksum. +func New512() hash.Hash { + d := new(digest) + d.initialize(defaultConfig) + return d +} + +// New256 returns a new hash.Hash computing the BLAKE2b 32-byte checksum. +func New256() hash.Hash { + d := new(digest) + d.initialize(config256) + return d +} + +// NewMAC returns a new hash.Hash computing BLAKE2b prefix- +// Message Authentication Code of the given size in bytes +// (up to 64) with the given key (up to 64 bytes in length). +func NewMAC(outBytes uint8, key []byte) hash.Hash { + d, err := New(&Config{Size: outBytes, Key: key}) + if err != nil { + panic(err.Error()) + } + return d +} + +// Reset resets the state of digest to the initial state +// after configuration and keying. +func (d *digest) Reset() { + copy(d.h[:], d.ih[:]) + d.t[0] = 0 + d.t[1] = 0 + d.f[0] = 0 + d.f[1] = 0 + d.nx = 0 + if d.isKeyed { + d.Write(d.paddedKey[:]) + } +} + +// Size returns the digest size in bytes. +func (d *digest) Size() int { return int(d.size) } + +// BlockSize returns the algorithm block size in bytes. +func (d *digest) BlockSize() int { return BlockSize } + +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + left := BlockSize - d.nx + if len(p) > left { + // Process buffer. + copy(d.x[d.nx:], p[:left]) + p = p[left:] + compress(d, d.x[:]) + d.nx = 0 + } + // Process full blocks except for the last one. + if len(p) > BlockSize { + n := len(p) &^ (BlockSize - 1) + if n == len(p) { + n -= BlockSize + } + compress(d, p[:n]) + p = p[n:] + } + // Fill buffer. + d.nx += copy(d.x[d.nx:], p) + return +} + +// Sum returns the calculated checksum. +func (d *digest) Sum(in []byte) []byte { + // Make a copy of d so that caller can keep writing and summing. + d0 := *d + hash := d0.checkSum() + return append(in, hash[:d0.size]...) +} + +func (d *digest) checkSum() [Size]byte { + // Do not create unnecessary copies of the key. + if d.isKeyed { + for i := 0; i < len(d.paddedKey); i++ { + d.paddedKey[i] = 0 + } + } + + dec := BlockSize - uint64(d.nx) + if d.t[0] < dec { + d.t[1]-- + } + d.t[0] -= dec + + // Pad buffer with zeros. + for i := d.nx; i < len(d.x); i++ { + d.x[i] = 0 + } + // Set last block flag. + d.f[0] = 0xffffffffffffffff + if d.isLastNode { + d.f[1] = 0xffffffffffffffff + } + // Compress last block. + compress(d, d.x[:]) + + var out [Size]byte + j := 0 + for _, s := range d.h[:(d.size-1)/8+1] { + out[j+0] = byte(s >> 0) + out[j+1] = byte(s >> 8) + out[j+2] = byte(s >> 16) + out[j+3] = byte(s >> 24) + out[j+4] = byte(s >> 32) + out[j+5] = byte(s >> 40) + out[j+6] = byte(s >> 48) + out[j+7] = byte(s >> 56) + j += 8 + } + return out +} + +// Sum512 returns a 64-byte BLAKE2b hash of data. +func Sum512(data []byte) [64]byte { + var d digest + d.initialize(defaultConfig) + d.Write(data) + return d.checkSum() +} + +// Sum256 returns a 32-byte BLAKE2b hash of data. +func Sum256(data []byte) (out [32]byte) { + var d digest + d.initialize(config256) + d.Write(data) + sum := d.checkSum() + copy(out[:], sum[:32]) + return +} diff --git a/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go b/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go new file mode 100644 index 00000000..ec53599f --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.go @@ -0,0 +1,47 @@ +//+build !noasm +//+build !appengine + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +//go:noescape +func compressAVX2Loop(p []uint8, in, iv, t, f, shffle, out []uint64) + +func compressAVX2(d *digest, p []uint8) { + var ( + in [8]uint64 + out [8]uint64 + shffle [8]uint64 + ) + + // vector for PSHUFB instruction + shffle[0] = 0x0201000706050403 + shffle[1] = 0x0a09080f0e0d0c0b + shffle[2] = 0x0201000706050403 + shffle[3] = 0x0a09080f0e0d0c0b + shffle[4] = 0x0100070605040302 + shffle[5] = 0x09080f0e0d0c0b0a + shffle[6] = 0x0100070605040302 + shffle[7] = 0x09080f0e0d0c0b0a + + in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] + + compressAVX2Loop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) + + d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] +} diff --git a/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s b/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s new file mode 100644 index 00000000..24df234b --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressAvx2_amd64.s @@ -0,0 +1,671 @@ +//+build !noasm !appengine + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// Based on AVX2 implementation from https://github.com/sneves/blake2-avx2/blob/master/blake2b-common.h +// +// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent +// +// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: +// #define ROUND(r) \ +// LOAD_MSG_ ##r ##_1(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_2(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ +// LOAD_MSG_ ##r ##_3(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_4(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); +// +// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go +// +// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) +// +// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and +// rounds 2 & 12 are identical) +// + +#define G1 \ + \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); + BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc4 \ // VPADDQ YMM0,YMM0,YMM4 /* v0 += m[0], v1 += m[2], v2 += m[4], v3 += m[6] */ + BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc1 \ // VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ + BYTE $0xc5; BYTE $0xe5; BYTE $0xef; BYTE $0xd8 \ // VPXOR YMM3,YMM3,YMM0 /* v12 ^= v0, v13 ^= v1, v14 ^= v2, v15 ^= v3 */ + BYTE $0xc5; BYTE $0xfd; BYTE $0x70; BYTE $0xdb; BYTE $0xb1 \ // VPSHUFD YMM3,YMM3,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = */ + BYTE $0xc5; BYTE $0xed; BYTE $0xd4; BYTE $0xd3 \ // VPADDQ YMM2,YMM2,YMM3 /* v8 += v12, v9 += v13, v10 += v14, v11 += v15 */ + BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xca \ // VPXOR YMM1,YMM1,YMM2 /* v4 ^= v8, v5 ^= v9, v6 ^= v10, v7 ^= v11 */ + BYTE $0xc4; BYTE $0xe2; BYTE $0x75; BYTE $0x00; BYTE $0xce // VPSHUFB YMM1,YMM1,YMM6 /* v4 = v4<<(64-24) | v4>>24, ..., ..., v7 = v7<<(64-24) | v7>>24 */ + +#define G2 \ + BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc5 \ // VPADDQ YMM0,YMM0,YMM5 /* v0 += m[1], v1 += m[3], v2 += m[5], v3 += m[7] */ + BYTE $0xc5; BYTE $0xfd; BYTE $0xd4; BYTE $0xc1 \ // VPADDQ YMM0,YMM0,YMM1 /* v0 += v4, v1 += v5, v2 += v6, v3 += v7 */ + BYTE $0xc5; BYTE $0xe5; BYTE $0xef; BYTE $0xd8 \ // VPXOR YMM3,YMM3,YMM0 /* v12 ^= v0, v13 ^= v1, v14 ^= v2, v15 ^= v3 */ + BYTE $0xc4; BYTE $0xe2; BYTE $0x65; BYTE $0x00; BYTE $0xdf \ // VPSHUFB YMM3,YMM3,YMM7 /* v12 = v12<<(64-16) | v12>>16, ..., ..., v15 = v15<<(64-16) | v15>>16 */ + BYTE $0xc5; BYTE $0xed; BYTE $0xd4; BYTE $0xd3 \ // VPADDQ YMM2,YMM2,YMM3 /* v8 += v12, v9 += v13, v10 += v14, v11 += v15 */ + BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xca \ // VPXOR YMM1,YMM1,YMM2 /* v4 ^= v8, v5 ^= v9, v6 ^= v10, v7 ^= v11 */ + BYTE $0xc5; BYTE $0x75; BYTE $0xd4; BYTE $0xf9 \ // VPADDQ YMM15,YMM1,YMM1 /* temp reg = reg*2 */ + BYTE $0xc5; BYTE $0xf5; BYTE $0x73; BYTE $0xd1; BYTE $0x3f \ // VPSRLQ YMM1,YMM1,0x3f /* reg = reg>>63 */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x75; BYTE $0xef; BYTE $0xcf // VPXOR YMM1,YMM1,YMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ + +#define DIAGONALIZE \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb \ // VPERMQ YMM3, YMM3, 0x93 + BYTE $0x93 \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2 \ // VPERMQ YMM2, YMM2, 0x4e + BYTE $0x4e \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 \ // VPERMQ YMM1, YMM1, 0x39 + BYTE $0x39 \ + // DO NOT DELETE -- macro delimiter (previous line extended) + +#define UNDIAGONALIZE \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb \ // VPERMQ YMM3, YMM3, 0x39 + BYTE $0x39 \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2 \ // VPERMQ YMM2, YMM2, 0x4e + BYTE $0x4e \ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 \ // VPERMQ YMM1, YMM1, 0x93 + BYTE $0x93 \ + // DO NOT DELETE -- macro delimiter (previous line extended) + +#define LOAD_SHUFFLE \ + MOVQ shffle+120(FP), SI \ // SI: &shuffle + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x36 \ // VMOVDQU YMM6, [rsi] + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x7e; BYTE $0x20 // VMOVDQU YMM7, 32[rsi] + +// func compressAVX2Loop(compressSSE(p []uint8, in, iv, t, f, shffle, out []uint64) +TEXT ·compressAVX2Loop(SB), 7, $0 + + // REGISTER USE + // Y0 - Y3: v0 - v15 + // Y4 - Y5: m[0] - m[7] + // Y6 - Y7: shuffle value + // Y8 - Y9: temp registers + // Y10 -Y13: copy of full message + // Y15: temp register + + // Load digest + MOVQ in+24(FP), SI // SI: &in + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x06 // VMOVDQU YMM0, [rsi] + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x4e; BYTE $0x20 // VMOVDQU YMM1, 32[rsi] + + // Already store digest into &out (so we can reload it later generically) + MOVQ out+144(FP), SI // SI: &out + BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x06 // VMOVDQU [rsi], YMM0 + BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x4e; BYTE $0x20 // VMOVDQU 32[rsi], YMM1 + + // Initialize message pointer and loop counter + MOVQ message+0(FP), DX // DX: &p (message) + MOVQ message_len+8(FP), R8 // R8: len(message) + SHRQ $7, R8 // len(message) / 128 + CMPQ R8, $0 + JEQ complete + +loop: + // Increment counter + MOVQ t+72(FP), SI // SI: &t + MOVQ 0(SI), R9 // + ADDQ $128, R9 // /* d.t[0] += BlockSize */ + MOVQ R9, 0(SI) // + CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ + JGE noincr // + MOVQ 8(SI), R9 // + ADDQ $1, R9 // /* d.t[1]++ */ + MOVQ R9, 8(SI) // +noincr: // /* } */ + + // Load initialization vector + MOVQ iv+48(FP), SI // SI: &iv + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x16 // VMOVDQU YMM2, [rsi] + BYTE $0xc5; BYTE $0xfe; BYTE $0x6f; BYTE $0x5e; BYTE $0x20 // VMOVDQU YMM3, 32[rsi] + MOVQ t+72(FP), SI // SI: &t + BYTE $0xc4; BYTE $0x63; BYTE $0x3d; BYTE $0x38; BYTE $0x06 // VINSERTI128 YMM8, YMM8, [rsi], 0 /* Y8 = t[0]+t[1] */ + BYTE $0x00 + MOVQ t+96(FP), SI // SI: &f + BYTE $0xc4; BYTE $0x63; BYTE $0x3d; BYTE $0x38; BYTE $0x06 // VINSERTI128 YMM8, YMM8, [rsi], 1 /* Y8 = t[0]+t[1]+f[0]+f[1] */ + BYTE $0x01 + BYTE $0xc4; BYTE $0xc1; BYTE $0x65; BYTE $0xef; BYTE $0xd8 // VPXOR YMM3,YMM3,YMM8 /* Y3 = Y3 ^ Y8 */ + + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x12 // VMOVDQU YMM10, [rdx] /* Y10 = m[0]+ m[1]+ m[2]+ m[3] */ + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x5a; BYTE $0x20 // VMOVDQU YMM11, 32[rdx] /* Y11 = m[4]+ m[5]+ m[6]+ m[7] */ + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x62; BYTE $0x40 // VMOVDQU YMM12, 64[rdx] /* Y12 = m[8]+ m[9]+m[10]+m[11] */ + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x6a; BYTE $0x60 // VMOVDQU YMM13, 96[rdx] /* Y13 = m[12]+m[13]+m[14]+m[15] */ + + LOAD_SHUFFLE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6c; BYTE $0xe3 // VPUNPCKLQDQ YMM4, YMM10, YMM11 /* m[0], m[4], m[2], m[6] */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6d; BYTE $0xeb // VPUNPCKHQDQ YMM5, YMM10, YMM11 /* m[1], m[5], m[3], m[7] */ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6c; BYTE $0xe5 // VPUNPCKLQDQ YMM4, YMM12, YMM13 /* m[8], m[12], m[10], m[14] */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6d; BYTE $0xed // VPUNPCKHQDQ YMM5, YMM12, YMM13 /* m[9], m[13], m[11], m[15] */ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 2 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 /* m[4], ____, ____, m[14] */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x03 /* m[14], m[4], ____, ____ */ /* xxxx 0011 = 0x03 */ + BYTE $0x03 + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM12, YMM13 /* m[9], m[13], ____, ____ */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[9], m[13], ____, ____ */ /* 0010 0000 = 0x20 */ + BYTE $0x20 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x02 /* m[10], m[8], ____, ____ */ /* xxxx 0010 = 0x02 */ + BYTE $0x02 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x30 /* ____, ____, m[15], ____ */ /* xx11 xxxx = 0x30 */ + BYTE $0x30 + BYTE $0xc4; BYTE $0x41; BYTE $0x35; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM9, YMM11 /* ____, ____, m[15], m[6] */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ + BYTE $0x30 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x01 /* m[1], m[0], ____, ____ */ /* xxxx 0001 = 0x01 */ + BYTE $0x01 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 /* m[5], ____, ____, m[11] */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x03 /* m[11], m[5], ____, ____ */ /* xxxx 0011 = 0x03 */ + BYTE $0x03 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[1], m[0], m[11], m[5] */ /* 0010 0000 = 0x20 */ + BYTE $0x20 + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM10, YMM13 /* ___, m[12], m[2], ____ */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x09 /* m[12], m[2], ____, ____ */ /* xxxx 1001 = 0x09 */ + BYTE $0x09 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 /* ____, ____, m[7], m[3] */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ + BYTE $0x30 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 3 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0x00 + BYTE $0x00 + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM11, YMM13 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 + BYTE $0x21 + + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc2 // VPUNPCKLQDQ YMM8, YMM12, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x55 + BYTE $0x55 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM10, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 + BYTE $0x30 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM12, YMM8 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 + BYTE $0x31 + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM13, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x00 + BYTE $0x00 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 + BYTE $0x21 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 4 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM11, YMM10 + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM13, YMM12 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 + BYTE $0x21 + + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM12, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x08 + BYTE $0x08 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 + BYTE $0x20 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0x55 + BYTE $0x55 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 + BYTE $0x21 + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc4 // VPUNPCKLQDQ YMM8, YMM11, YMM12 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 + BYTE $0x21 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 5 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM12, YMM11 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 + BYTE $0x30 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 + BYTE $0x20 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM13, YMM8 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM11, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 + BYTE $0x31 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0x00 + BYTE $0x00 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM10, YMM8 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x55 + BYTE $0x55 + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM12, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 + BYTE $0x20 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 6 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM10, YMM12 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x21 + BYTE $0x21 + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc4 // VPUNPCKLQDQ YMM8, YMM13, YMM12 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM12, YMM10 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 + BYTE $0x30 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM13, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 + BYTE $0x30 + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM13, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x55 + BYTE $0x55 + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM13, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 + BYTE $0x30 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 7 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x55 + BYTE $0x55 + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM13, YMM8 + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM13, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x30 + BYTE $0x30 + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc5 // VPUNPCKHQDQ YMM8, YMM11, YMM13 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xaa + BYTE $0xaa + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM13, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x20 + BYTE $0x20 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x01 + BYTE $0x01 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 + BYTE $0x20 + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc2 // VPUNPCKHQDQ YMM8, YMM11, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM10, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 + BYTE $0x31 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 8 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc3 // VPUNPCKHQDQ YMM8, YMM13, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xc9 // VPUNPCKLQDQ YMM9, YMM13, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 + BYTE $0x20 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0xaa + BYTE $0xaa + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM10, YMM12 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 + BYTE $0x21 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xc5 // VPUNPCKHQDQ YMM8, YMM11, YMM13 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6c; BYTE $0xca // VPUNPCKLQDQ YMM9, YMM12, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x0c + BYTE $0x0c + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 + BYTE $0x20 + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xcc // VPUNPCKLQDQ YMM9, YMM11, YMM12 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 + BYTE $0x30 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 9 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xca // VPERMQ YMM9, YMM10, 0x00 + BYTE $0x00 + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM12, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 + BYTE $0x31 + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc4 // VPUNPCKHQDQ YMM8, YMM13, YMM12 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0x00 + BYTE $0x00 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 + BYTE $0x31 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcc // VPERMQ YMM9, YMM12, 0xaa + BYTE $0xaa + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xc9 // VPUNPCKHQDQ YMM9, YMM10, YMM9 + BYTE $0xc4; BYTE $0xc3; BYTE $0x15; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM13, YMM9, 0x20 + BYTE $0x20 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc3 // VPERMQ YMM8, YMM11, 0xff + BYTE $0xff + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc0 // VPUNPCKLQDQ YMM8, YMM10, YMM8 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x04 + BYTE $0x04 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 + BYTE $0x21 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 10 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x20 + BYTE $0x20 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 + BYTE $0x31 + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc3 // VPUNPCKLQDQ YMM8, YMM10, YMM11 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcb // VPERMQ YMM9, YMM11, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x31 + BYTE $0x31 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6d; BYTE $0xc4 // VPUNPCKHQDQ YMM8, YMM13, YMM12 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM10, YMM13 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x60 + BYTE $0x60 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x31 + BYTE $0x31 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc5 // VPERMQ YMM8, YMM13, 0xaa + BYTE $0xaa + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xc0 // VPUNPCKHQDQ YMM8, YMM12, YMM8 + BYTE $0xc4; BYTE $0x41; BYTE $0x15; BYTE $0x6c; BYTE $0xca // VPUNPCKLQDQ YMM9, YMM13, YMM10 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x21 + BYTE $0x21 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 1 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6c; BYTE $0xe3 // VPUNPCKLQDQ YMM4, YMM10, YMM11 /* m[0], m[4], m[2], m[6] */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x2d; BYTE $0x6d; BYTE $0xeb // VPUNPCKHQDQ YMM5, YMM10, YMM11 /* m[1], m[5], m[3], m[7] */ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6c; BYTE $0xe5 // VPUNPCKLQDQ YMM4, YMM12, YMM13 /* m[8], m[12], m[10], m[14] */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x1d; BYTE $0x6d; BYTE $0xed // VPUNPCKHQDQ YMM5, YMM12, YMM13 /* m[9], m[13], m[11], m[15] */ + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xe4 // VPERMQ YMM4, YMM4, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xed // VPERMQ YMM5, YMM5, 0xd8 /* 0x1101 1000 = 0xd8 */ + BYTE $0xd8 + + G1 + G2 + + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 2 + /////////////////////////////////////////////////////////////////////////// + + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM11, YMM13 /* m[4], ____, ____, m[14] */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x03 /* m[14], m[4], ____, ____ */ /* xxxx 0011 = 0x03 */ + BYTE $0x03 + BYTE $0xc4; BYTE $0x41; BYTE $0x1d; BYTE $0x6d; BYTE $0xcd // VPUNPCKHQDQ YMM9, YMM12, YMM13 /* m[9], m[13], ____, ____ */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[9], m[13], ____, ____ */ /* 0010 0000 = 0x20 */ + BYTE $0x20 + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc4 // VPERMQ YMM8, YMM12, 0x02 /* m[10], m[8], ____, ____ */ /* xxxx 0010 = 0x02 */ + BYTE $0x02 + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xcd // VPERMQ YMM9, YMM13, 0x30 /* ____, ____, m[15], ____ */ /* xx11 xxxx = 0x30 */ + BYTE $0x30 + BYTE $0xc4; BYTE $0x41; BYTE $0x35; BYTE $0x6c; BYTE $0xcb // VPUNPCKLQDQ YMM9, YMM9, YMM11 /* ____, ____, m[15], m[6] */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ + BYTE $0x30 + + G1 + G2 + + DIAGONALIZE + + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc2 // VPERMQ YMM8, YMM10, 0x01 /* m[1], m[0], ____, ____ */ /* xxxx 0001 = 0x01 */ + BYTE $0x01 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xcc // VPUNPCKHQDQ YMM9, YMM11, YMM12 /* m[5], ____, ____, m[11] */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc9 // VPERMQ YMM9, YMM9, 0x03 /* m[11], m[5], ____, ____ */ /* xxxx 0011 = 0x03 */ + BYTE $0x03 + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe1 // VPERM2I128 YMM4, YMM8, YMM9, 0x20 /* m[1], m[0], m[11], m[5] */ /* 0010 0000 = 0x20 */ + BYTE $0x20 + + BYTE $0xc4; BYTE $0x41; BYTE $0x2d; BYTE $0x6c; BYTE $0xc5 // VPUNPCKLQDQ YMM8, YMM10, YMM13 /* ___, m[12], m[2], ____ */ + BYTE $0xc4; BYTE $0x43; BYTE $0xfd; BYTE $0x00; BYTE $0xc0 // VPERMQ YMM8, YMM8, 0x09 /* m[12], m[2], ____, ____ */ /* xxxx 1001 = 0x09 */ + BYTE $0x09 + BYTE $0xc4; BYTE $0x41; BYTE $0x25; BYTE $0x6d; BYTE $0xca // VPUNPCKHQDQ YMM9, YMM11, YMM10 /* ____, ____, m[7], m[3] */ + BYTE $0xc4; BYTE $0xc3; BYTE $0x3d; BYTE $0x46; BYTE $0xe9 // VPERM2I128 YMM5, YMM8, YMM9, 0x30 /* m[9], m[13], m[15], m[6] */ /* 0011 0000 = 0x30 */ + BYTE $0x30 + + G1 + G2 + + UNDIAGONALIZE + + // Reload digest (most current value store in &out) + MOVQ out+144(FP), SI // SI: &in + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x26 // VMOVDQU YMM12, [rsi] + BYTE $0xc5; BYTE $0x7e; BYTE $0x6f; BYTE $0x6e; BYTE $0x20 // VMOVDQU YMM13, 32[rsi] + + BYTE $0xc5; BYTE $0xfd; BYTE $0xef; BYTE $0xc2 // VPXOR YMM0,YMM0,YMM2 /* X0 = X0 ^ X4, X1 = X1 ^ X5 */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x7d; BYTE $0xef; BYTE $0xc4 // VPXOR YMM0,YMM0,YMM12 /* X0 = X0 ^ X12, X1 = X1 ^ X13 */ + BYTE $0xc5; BYTE $0xf5; BYTE $0xef; BYTE $0xcb // VPXOR YMM1,YMM1,YMM3 /* X2 = X2 ^ X6, X3 = X3 ^ X7 */ + BYTE $0xc4; BYTE $0xc1; BYTE $0x75; BYTE $0xef; BYTE $0xcd // VPXOR YMM1,YMM1,YMM13 /* X2 = X2 ^ X14, X3 = X3 ^ X15 */ + + // Store digest into &out + MOVQ out+144(FP), SI // SI: &out + BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x06 // VMOVDQU [rsi], YMM0 + BYTE $0xc5; BYTE $0xfe; BYTE $0x7f; BYTE $0x4e; BYTE $0x20 // VMOVDQU 32[rsi], YMM1 + + // Increment message pointer and check if there's more to do + ADDQ $128, DX // message += 128 + SUBQ $1, R8 + JNZ loop + +complete: + BYTE $0xc5; BYTE $0xf8; BYTE $0x77 // VZEROUPPER /* Prevent further context switches */ + RET + diff --git a/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go b/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go new file mode 100644 index 00000000..cfa12c04 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.go @@ -0,0 +1,41 @@ +//+build !noasm +//+build !appengine + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +//go:noescape +func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) + +func compressAVX(d *digest, p []uint8) { + var ( + in [8]uint64 + out [8]uint64 + shffle [2]uint64 + ) + + // vector for PSHUFB instruction + shffle[0] = 0x0201000706050403 + shffle[1] = 0x0a09080f0e0d0c0b + + in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] + + blockAVXLoop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) + + d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] +} diff --git a/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s b/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s new file mode 100644 index 00000000..f68e1739 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressAvx_amd64.s @@ -0,0 +1,682 @@ +//+build !noasm !appengine + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// Based on SSE implementation from https://github.com/BLAKE2/BLAKE2/blob/master/sse/blake2b.c +// +// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent +// +// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: +// #define ROUND(r) \ +// LOAD_MSG_ ##r ##_1(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_2(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ +// LOAD_MSG_ ##r ##_3(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_4(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); +// +// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go +// +// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) +// +// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and +// rounds 2 & 12 are identical) +// + +#define G1 \ + \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); + LONG $0xd479c1c4; BYTE $0xc0 \ // VPADDQ XMM0,XMM0,XMM8 /* v0 += m[0], v1 += m[2] */ + LONG $0xd471c1c4; BYTE $0xc9 \ // VPADDQ XMM1,XMM1,XMM9 /* v2 += m[4], v3 += m[6] */ + LONG $0xc2d4f9c5 \ // VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ + LONG $0xcbd4f1c5 \ // VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ + LONG $0xf0efc9c5 \ // VPXOR XMM6,XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ + LONG $0xf9efc1c5 \ // VPXOR XMM7,XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ + LONG $0xf670f9c5; BYTE $0xb1 \ // VPSHUFD XMM6,XMM6,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = v13<<(64-32) | v13>>32 */ + LONG $0xff70f9c5; BYTE $0xb1 \ // VPSHUFD XMM7,XMM7,0xb1 /* v14 = v14<<(64-32) | v14>>32, v15 = v15<<(64-32) | v15>>32 */ + LONG $0xe6d4d9c5 \ // VPADDQ XMM4,XMM4,XMM6 /* v8 += v12, v9 += v13 */ + LONG $0xefd4d1c5 \ // VPADDQ XMM5,XMM5,XMM7 /* v10 += v14, v11 += v15 */ + LONG $0xd4efe9c5 \ // VPXOR XMM2,XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ + LONG $0xddefe1c5 \ // VPXOR XMM3,XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ + LONG $0x0069c2c4; BYTE $0xd4 \ // VPSHUFB XMM2,XMM2,XMM12 /* v4 = v4<<(64-24) | v4>>24, v5 = v5<<(64-24) | v5>>24 */ + LONG $0x0061c2c4; BYTE $0xdc // VPSHUFB XMM3,XMM3,XMM12 /* v6 = v6<<(64-24) | v6>>24, v7 = v7<<(64-24) | v7>>24 */ + +#define G2 \ + \ // G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); + LONG $0xd479c1c4; BYTE $0xc2 \ // VPADDQ XMM0,XMM0,XMM10 /* v0 += m[1], v1 += m[3] */ + LONG $0xd471c1c4; BYTE $0xcb \ // VPADDQ XMM1,XMM1,XMM11 /* v2 += m[5], v3 += m[7] */ + LONG $0xc2d4f9c5 \ // VPADDQ XMM0,XMM0,XMM2 /* v0 += v4, v1 += v5 */ + LONG $0xcbd4f1c5 \ // VPADDQ XMM1,XMM1,XMM3 /* v2 += v6, v3 += v7 */ + LONG $0xf0efc9c5 \ // VPXOR XMM6,XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ + LONG $0xf9efc1c5 \ // VPXOR XMM7,XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ + LONG $0xf670fbc5; BYTE $0x39 \ // VPSHUFLW XMM6,XMM6,0x39 /* combined with next ... */ + LONG $0xf670fac5; BYTE $0x39 \ // VPSHUFHW XMM6,XMM6,0x39 /* v12 = v12<<(64-16) | v12>>16, v13 = v13<<(64-16) | v13>>16 */ + LONG $0xff70fbc5; BYTE $0x39 \ // VPSHUFLW XMM7,XMM7,0x39 /* combined with next ... */ + LONG $0xff70fac5; BYTE $0x39 \ // VPSHUFHW XMM7,XMM7,0x39 /* v14 = v14<<(64-16) | v14>>16, v15 = v15<<(64-16) | v15>>16 */ + LONG $0xe6d4d9c5 \ // VPADDQ XMM4,XMM4,XMM6 /* v8 += v12, v9 += v13 */ + LONG $0xefd4d1c5 \ // VPADDQ XMM5,XMM5,XMM7 /* v10 += v14, v11 += v15 */ + LONG $0xd4efe9c5 \ // VPXOR XMM2,XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ + LONG $0xddefe1c5 \ // VPXOR XMM3,XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ + LONG $0xfad469c5 \ // VPADDQ XMM15,XMM2,XMM2 /* temp reg = reg*2 */ + LONG $0xd273e9c5; BYTE $0x3f \ // VPSRLQ XMM2,XMM2,0x3f /* reg = reg>>63 */ + LONG $0xef69c1c4; BYTE $0xd7 \ // VPXOR XMM2,XMM2,XMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ + LONG $0xfbd461c5 \ // VPADDQ XMM15,XMM3,XMM3 /* temp reg = reg*2 */ + LONG $0xd373e1c5; BYTE $0x3f \ // VPSRLQ XMM3,XMM3,0x3f /* reg = reg>>63 */ + LONG $0xef61c1c4; BYTE $0xdf // VPXOR XMM3,XMM3,XMM15 /* ORed together: v6 = v6<<(64-63) | v6>>63, v7 = v7<<(64-63) | v7>>63 */ + +#define DIAGONALIZE \ + \ // DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + MOVOU X6, X13 \ /* t0 = row4l;\ */ + MOVOU X2, X14 \ /* t1 = row2l;\ */ + MOVOU X4, X6 \ /* row4l = row3l;\ */ + MOVOU X5, X4 \ /* row3l = row3h;\ */ + MOVOU X6, X5 \ /* row3h = row4l;\ */ + LONG $0x6c1141c4; BYTE $0xfd \ // VPUNPCKLQDQ XMM15, XMM13, XMM13 /* _mm_unpacklo_epi64(t0, t0) */ + LONG $0x6d41c1c4; BYTE $0xf7 \ // VPUNPCKHQDQ XMM6, XMM7, XMM15 /* row4l = _mm_unpackhi_epi64(row4h, ); \ */ + LONG $0xff6c41c5 \ // VPUNPCKLQDQ XMM15, XMM7, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ + LONG $0x6d11c1c4; BYTE $0xff \ // VPUNPCKHQDQ XMM7, XMM13, XMM15 /* row4h = _mm_unpackhi_epi64(t0, ); \ */ + LONG $0xfb6c61c5 \ // VPUNPCKLQDQ XMM15, XMM3, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ + LONG $0x6d69c1c4; BYTE $0xd7 \ // VPUNPCKHQDQ XMM2, XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2l, ); \ */ + LONG $0x6c0941c4; BYTE $0xfe \ // VPUNPCKLQDQ XMM15, XMM14, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ + LONG $0x6d61c1c4; BYTE $0xdf // VPUNPCKHQDQ XMM3, XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(row2h, ) */ + +#define UNDIAGONALIZE \ + \ // UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + MOVOU X4, X13 \ /* t0 = row3l;\ */ + MOVOU X5, X4 \ /* row3l = row3h;\ */ + MOVOU X13, X5 \ /* row3h = t0;\ */ + MOVOU X2, X13 \ /* t0 = row2l;\ */ + MOVOU X6, X14 \ /* t1 = row4l;\ */ + LONG $0xfa6c69c5 \ // VPUNPCKLQDQ XMM15, XMM2, XMM2 /* _mm_unpacklo_epi64(row2l, row2l) */ + LONG $0x6d61c1c4; BYTE $0xd7 \ // VPUNPCKHQDQ XMM2, XMM3, XMM15 /* row2l = _mm_unpackhi_epi64(row2h, ); \ */ + LONG $0xfb6c61c5 \ // VPUNPCKLQDQ XMM15, XMM3, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ + LONG $0x6d11c1c4; BYTE $0xdf \ // VPUNPCKHQDQ XMM3, XMM13, XMM15 /* row2h = _mm_unpackhi_epi64(t0, ); \ */ + LONG $0xff6c41c5 \ // VPUNPCKLQDQ XMM15, XMM7, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ + LONG $0x6d49c1c4; BYTE $0xf7 \ // VPUNPCKHQDQ XMM6, XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4l, ); \ */ + LONG $0x6c0941c4; BYTE $0xfe \ // VPUNPCKLQDQ XMM15, XMM14, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ + LONG $0x6d41c1c4; BYTE $0xff // VPUNPCKHQDQ XMM7, XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(row4h, ) */ + +#define LOAD_SHUFFLE \ + \ // Load shuffle value + MOVQ shffle+120(FP), SI \ // SI: &shuffle + MOVOU 0(SI), X12 // X12 = 03040506 07000102 0b0c0d0e 0f08090a + +// func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) +TEXT ·blockAVXLoop(SB), 7, $0 + // REGISTER USE + // R8: loop counter + // DX: message pointer + // SI: temp pointer for loading + // X0 - X7: v0 - v15 + // X8 - X11: m[0] - m[7] + // X12: shuffle value + // X13 - X15: temp registers + + // Load digest + MOVQ in+24(FP), SI // SI: &in + MOVOU 0(SI), X0 // X0 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ + MOVOU 16(SI), X1 // X1 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ + MOVOU 32(SI), X2 // X2 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ + MOVOU 48(SI), X3 // X3 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ + + // Already store digest into &out (so we can reload it later generically) + MOVQ out+144(FP), SI // SI: &out + MOVOU X0, 0(SI) // out[0]+out[1] = X0 + MOVOU X1, 16(SI) // out[2]+out[3] = X1 + MOVOU X2, 32(SI) // out[4]+out[5] = X2 + MOVOU X3, 48(SI) // out[6]+out[7] = X3 + + // Initialize message pointer and loop counter + MOVQ message+0(FP), DX // DX: &p (message) + MOVQ message_len+8(FP), R8 // R8: len(message) + SHRQ $7, R8 // len(message) / 128 + CMPQ R8, $0 + JEQ complete + +loop: + // Increment counter + MOVQ t+72(FP), SI // SI: &t + MOVQ 0(SI), R9 + ADDQ $128, R9 // /* d.t[0] += BlockSize */ + MOVQ R9, 0(SI) + CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ + JGE noincr + MOVQ 8(SI), R9 + ADDQ $1, R9 // /* d.t[1]++ */ + MOVQ R9, 8(SI) +noincr: // /* } */ + + // Load initialization vector + MOVQ iv+48(FP), SI // SI: &iv + MOVOU 0(SI), X4 // X4 = iv[0]+iv[1] /* row3l = LOAD( &blake2b_IV[0] ); */ + MOVOU 16(SI), X5 // X5 = iv[2]+iv[3] /* row3h = LOAD( &blake2b_IV[2] ); */ + MOVOU 32(SI), X6 // X6 = iv[4]+iv[5] /* LOAD( &blake2b_IV[4] ) */ + MOVOU 48(SI), X7 // X7 = iv[6]+iv[7] /* LOAD( &blake2b_IV[6] ) */ + MOVQ t+72(FP), SI // SI: &t + MOVOU 0(SI), X8 // X8 = t[0]+t[1] /* LOAD( &S->t[0] ) */ + PXOR X8, X6 // X6 = X6 ^ X8 /* row4l = _mm_xor_si128( , ); */ + MOVQ t+96(FP), SI // SI: &f + MOVOU 0(SI), X8 // X8 = f[0]+f[1] /* LOAD( &S->f[0] ) */ + PXOR X8, X7 // X7 = X7 ^ X8 /* row4h = _mm_xor_si128( , ); */ + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+m[1] + MOVOU 16(DX), X13 // X13 = m[2]+m[3] + MOVOU 32(DX), X14 // X14 = m[4]+m[5] + MOVOU 48(DX), X15 // X15 = m[6]+m[7] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[2] */ + LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[4], m[6] */ + LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[1], m[3] */ + LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[5], m[7] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[8],m[10] */ + LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[12],m[14] */ + LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[9],m[11] */ + LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[13],m[15] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 2 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 112(DX), X12 // X12 = m[14]+m[15] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[14], m[4] */ + LONG $0x6d0941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM14, XMM15 /* m[9], m[13] */ + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 48(DX), X15 // X15 = m[6]+ m[7] + LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[10], m[8] */ + LONG $0x0f0143c4; WORD $0x08dc // VPALIGNR XMM11, XMM15, XMM12, 0x8 /* m[15], m[6] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + LONG $0x0f1943c4; WORD $0x08c4 // VPALIGNR XMM8, XMM12, XMM12, 0x8 /* m[1], m[0] */ + LONG $0x6d0941c4; BYTE $0xcd // VPUNPCKHQDQ XMM9, XMM14, XMM13 /* m[11], m[5] */ + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[2] */ + LONG $0x6d1141c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM13, XMM12 /* m[7], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 3 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 32(DX), X12 // X12 = m[4]+ m[5] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x0f0943c4; WORD $0x08c5 // VPALIGNR XMM8, XMM14, XMM13, 0x8 /* m[11], m[12] */ + LONG $0x6d1941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM12, XMM15 /* m[5], m[15] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 64(DX), X15 // X15 = m[8]+ m[9] + LONG $0x6c0141c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM15, XMM12 /* m[8], m[0] */ + LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[13] */ + LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[2], ___ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6d1941c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM12, XMM12 /* ___, m[3] */ + LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[10], ___ */ + LONG $0x6d1141c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM13, XMM14 /* m[7], m[9] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X14 // X14 = m[4]+ m[5] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6c0141c4; BYTE $0xd5 // VPUNPCKLQDQ XMM10, XMM15, XMM13 /* m[14], m[6] */ + LONG $0x0f0943c4; WORD $0x08dc // VPALIGNR XMM11, XMM14, XMM12, 0x8 /* m[1], m[4] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 4 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + LONG $0x6d1141c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM13, XMM12 /* m[7], m[3] */ + LONG $0x6d0141c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM15, XMM14 /* m[13], m[11] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 112(DX), X14 // X14 = m[14]+m[15] + LONG $0x6d1141c4; BYTE $0xd4 // VPUNPCKHQDQ XMM10, XMM13, XMM12 /* m[9], m[1] */ + LONG $0x6c0141c4; BYTE $0xde // VPUNPCKLQDQ XMM11, XMM15, XMM14 /* m[12], m[14] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d1141c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM13, XMM13 /* ___, m[5] */ + LONG $0x6c1941c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM12, XMM8 /* m[2], ____ */ + LONG $0x6d0141c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM15, XMM15 /* ___, m[15] */ + LONG $0x6c1141c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM13, XMM9 /* m[4], ____ */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X15 // X15 = m[8]+ m[9] + LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[6], m[10] */ + LONG $0x6c1941c4; BYTE $0xdf // VPUNPCKLQDQ XMM11, XMM12, XMM15 /* m[0], m[8] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 5 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6d0941c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM14, XMM13 /* m[9], m[5] */ + LONG $0x6c1941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM12, XMM15 /* m[2], m[10] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0941c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM14, XMM14 /* ___, m[7] */ + LONG $0x6c1941c4; BYTE $0xd2 // VPUNPCKLQDQ XMM10, XMM12, XMM10 /* m[0], ____ */ + LONG $0x6d0141c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM15, XMM15 /* ___, m[15] */ + LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[4], ____ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0941c4; BYTE $0xc6 // VPUNPCKHQDQ XMM8, XMM14, XMM14 /* ___, m[11] */ + LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[14], ____ */ + LONG $0x6d1941c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM12, XMM12 /* ___, m[3] */ + LONG $0x6c1141c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM13, XMM9 /* m[6], ____ */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + LONG $0x0f0943c4; WORD $0x08d4 // VPALIGNR XMM10, XMM14, XMM12, 0x8 /* m[1], m[12] */ + LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[13] */ + LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[8], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 6 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 64(DX), X15 // X15 = m[8]+ m[9] + LONG $0x6c1141c4; BYTE $0xc6 // VPUNPCKLQDQ XMM8, XMM13, XMM14 /* m[2], m[6] */ + LONG $0x6c1941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM12, XMM15 /* m[0], m[8] */ + MOVOU 80(DX), X12 // X12 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[10] */ + LONG $0x6d1941c4; BYTE $0xdd // VPUNPCKHQDQ XMM11, XMM12, XMM13 /* m[11], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0941c4; BYTE $0xc6 // VPUNPCKHQDQ XMM8, XMM14, XMM14 /* ___, m[7] */ + LONG $0x6c1141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM13, XMM8 /* m[4], ____ */ + LONG $0x6d0141c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM15, XMM12 /* m[15], m[1] */ + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + LONG $0x6d0941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM14, XMM13 /* m[13], m[5] */ + LONG $0x6d1941c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM12, XMM12 /* ___, m[9] */ + LONG $0x6c0141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM15, XMM11 /* m[14], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 7 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d1941c4; BYTE $0xc4 // VPUNPCKHQDQ XMM8, XMM12, XMM12 /* ___, m[1] */ + LONG $0x6c0941c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM14, XMM8 /* m[12], ____ */ + LONG $0x6c0141c4; BYTE $0xcd // VPUNPCKLQDQ XMM9, XMM15, XMM13 /* m[14], m[4] */ + MOVOU 80(DX), X12 // X12 = m[10]+m[11] + LONG $0x6d1141c4; BYTE $0xd7 // VPUNPCKHQDQ XMM10, XMM13, XMM15 /* m[5], m[15] */ + LONG $0x0f1943c4; WORD $0x08de // VPALIGNR XMM11, XMM12, XMM14, 0x8 /* m[13], m[10] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[6] */ + LONG $0x0f0943c4; WORD $0x08ce // VPALIGNR XMM9, XMM14, XMM14, 0x8 /* m[9], m[8] */ + MOVOU 16(DX), X14 // X14 = m[2]+ m[3] + LONG $0x6d1141c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM13, XMM14 /* m[7], m[3] */ + LONG $0x6d0141c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM15, XMM15 /* ___, m[11] */ + LONG $0x6c0941c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM14, XMM11 /* m[2], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 8 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0941c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM14, XMM13 /* m[13], m[7] */ + LONG $0x6d1941c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM12, XMM12 /* ___, m[3] */ + LONG $0x6c0941c4; BYTE $0xc9 // VPUNPCKLQDQ XMM9, XMM14, XMM9 /* m[12], ____ */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + LONG $0x0f0143c4; WORD $0x08d6 // VPALIGNR XMM10, XMM15, XMM14, 0x8 /* m[11], m[14] */ + LONG $0x6d1941c4; BYTE $0xdd // VPUNPCKHQDQ XMM11, XMM12, XMM13 /* m[1], m[9] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d1141c4; BYTE $0xc7 // VPUNPCKHQDQ XMM8, XMM13, XMM15 /* m[5], m[15] */ + LONG $0x6c0941c4; BYTE $0xcc // VPUNPCKLQDQ XMM9, XMM14, XMM12 /* m[8], m[2] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6c1941c4; BYTE $0xd5 // VPUNPCKLQDQ XMM10, XMM12, XMM13 /* m[0], m[4] */ + LONG $0x6c0941c4; BYTE $0xdf // VPUNPCKLQDQ XMM11, XMM14, XMM15 /* m[6], m[10] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 9 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6c1141c4; BYTE $0xc7 // VPUNPCKLQDQ XMM8, XMM13, XMM15 /* m[6], m[14] */ + LONG $0x0f1943c4; WORD $0x08ce // VPALIGNR XMM9, XMM12, XMM14, 0x8 /* m[11], m[0] */ + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + LONG $0x6d0141c4; BYTE $0xd6 // VPUNPCKHQDQ XMM10, XMM15, XMM14 /* m[15], m[9] */ + LONG $0x0f0943c4; WORD $0x08dd // VPALIGNR XMM11, XMM14, XMM13, 0x8 /* m[3], m[8] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + LONG $0x6d0141c4; BYTE $0xc7 // VPUNPCKHQDQ XMM8, XMM15, XMM15 /* ___, m[13] */ + LONG $0x6c0141c4; BYTE $0xc0 // VPUNPCKLQDQ XMM8, XMM15, XMM8 /* m[12], ____ */ + LONG $0x0f0943c4; WORD $0x08cc // VPALIGNR XMM9, XMM14, XMM12, 0x8 /* m[1], m[10] */ + MOVOU 32(DX), X12 // X12 = m[4]+ m[5] + MOVOU 48(DX), X15 // X15 = m[6]+ m[7] + LONG $0x6d0141c4; BYTE $0xd7 // VPUNPCKHQDQ XMM10, XMM15, XMM15 /* ___, m[7] */ + LONG $0x6c1141c4; BYTE $0xd2 // VPUNPCKLQDQ XMM10, XMM13, XMM10 /* m[2], ____ */ + LONG $0x6d1941c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM12, XMM12 /* ___, m[5] */ + LONG $0x6c1941c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM12, XMM11 /* m[4], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 0 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6c0141c4; BYTE $0xc6 // VPUNPCKLQDQ XMM8, XMM15, XMM14 /* m[10], m[8] */ + LONG $0x6d1141c4; BYTE $0xcc // VPUNPCKHQDQ XMM9, XMM13, XMM12 /* m[7], m[1] */ + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X14 // X14 = m[4]+ m[5] + LONG $0x6c1941c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM12, XMM14 /* m[2], m[4] */ + LONG $0x6d0941c4; BYTE $0xde // VPUNPCKHQDQ XMM11, XMM14, XMM14 /* ___, m[5] */ + LONG $0x6c1141c4; BYTE $0xdb // VPUNPCKLQDQ XMM11, XMM13, XMM11 /* m[6], ____ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0141c4; BYTE $0xc5 // VPUNPCKHQDQ XMM8, XMM15, XMM13 /* m[15], m[9] */ + LONG $0x6d1941c4; BYTE $0xce // VPUNPCKHQDQ XMM9, XMM12, XMM14 /* m[3], m[13] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + LONG $0x0f0143c4; WORD $0x08d5 // VPALIGNR XMM10, XMM15, XMM13, 0x8 /* m[11], m[14] */ + LONG $0x6c0941c4; BYTE $0xdc // VPUNPCKLQDQ XMM11, XMM14, XMM12 /* m[12], m[0] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 1 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+m[1] + MOVOU 16(DX), X13 // X13 = m[2]+m[3] + MOVOU 32(DX), X14 // X14 = m[4]+m[5] + MOVOU 48(DX), X15 // X15 = m[6]+m[7] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[0], m[2] */ + LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[4], m[6] */ + LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[1], m[3] */ + LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[5], m[7] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[8],m[10] */ + LONG $0x6c0941c4; BYTE $0xcf // VPUNPCKLQDQ XMM9, XMM14, XMM15 /* m[12],m[14] */ + LONG $0x6d1941c4; BYTE $0xd5 // VPUNPCKHQDQ XMM10, XMM12, XMM13 /* m[9],m[11] */ + LONG $0x6d0941c4; BYTE $0xdf // VPUNPCKHQDQ XMM11, XMM14, XMM15 /* m[13],m[15] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 2 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 112(DX), X12 // X12 = m[14]+m[15] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + LONG $0x6c1941c4; BYTE $0xc5 // VPUNPCKLQDQ XMM8, XMM12, XMM13 /* m[14], m[4] */ + LONG $0x6d0941c4; BYTE $0xcf // VPUNPCKHQDQ XMM9, XMM14, XMM15 /* m[9], m[13] */ + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 48(DX), X15 // X15 = m[6]+ m[7] + LONG $0x6c1141c4; BYTE $0xd6 // VPUNPCKLQDQ XMM10, XMM13, XMM14 /* m[10], m[8] */ + LONG $0x0f0143c4; WORD $0x08dc // VPALIGNR XMM11, XMM15, XMM12, 0x8 /* m[15], m[6] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + LONG $0x0f1943c4; WORD $0x08c4 // VPALIGNR XMM8, XMM12, XMM12, 0x8 /* m[1], m[0] */ + LONG $0x6d0941c4; BYTE $0xcd // VPUNPCKHQDQ XMM9, XMM14, XMM13 /* m[11], m[5] */ + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + LONG $0x6c0941c4; BYTE $0xd4 // VPUNPCKLQDQ XMM10, XMM14, XMM12 /* m[12], m[2] */ + LONG $0x6d1141c4; BYTE $0xdc // VPUNPCKHQDQ XMM11, XMM13, XMM12 /* m[7], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + // Reload digest (most current value store in &out) + MOVQ out+144(FP), SI // SI: &in + MOVOU 0(SI), X12 // X12 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ + MOVOU 16(SI), X13 // X13 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ + MOVOU 32(SI), X14 // X14 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ + MOVOU 48(SI), X15 // X15 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ + + // Final computations and prepare for storing + PXOR X4, X0 // X0 = X0 ^ X4 /* row1l = _mm_xor_si128( row3l, row1l ); */ + PXOR X5, X1 // X1 = X1 ^ X5 /* row1h = _mm_xor_si128( row3h, row1h ); */ + PXOR X12, X0 // X0 = X0 ^ X12 /* STORE( &S->h[0], _mm_xor_si128( LOAD( &S->h[0] ), row1l ) ); */ + PXOR X13, X1 // X1 = X1 ^ X13 /* STORE( &S->h[2], _mm_xor_si128( LOAD( &S->h[2] ), row1h ) ); */ + PXOR X6, X2 // X2 = X2 ^ X6 /* row2l = _mm_xor_si128( row4l, row2l ); */ + PXOR X7, X3 // X3 = X3 ^ X7 /* row2h = _mm_xor_si128( row4h, row2h ); */ + PXOR X14, X2 // X2 = X2 ^ X14 /* STORE( &S->h[4], _mm_xor_si128( LOAD( &S->h[4] ), row2l ) ); */ + PXOR X15, X3 // X3 = X3 ^ X15 /* STORE( &S->h[6], _mm_xor_si128( LOAD( &S->h[6] ), row2h ) ); */ + + // Store digest into &out + MOVQ out+144(FP), SI // SI: &out + MOVOU X0, 0(SI) // out[0]+out[1] = X0 + MOVOU X1, 16(SI) // out[2]+out[3] = X1 + MOVOU X2, 32(SI) // out[4]+out[5] = X2 + MOVOU X3, 48(SI) // out[6]+out[7] = X3 + + // Increment message pointer and check if there's more to do + ADDQ $128, DX // message += 128 + SUBQ $1, R8 + JNZ loop + +complete: + RET diff --git a/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go b/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go new file mode 100644 index 00000000..d539a7ad --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressSse_amd64.go @@ -0,0 +1,41 @@ +//+build !noasm +//+build !appengine + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +//go:noescape +func blockSSELoop(p []uint8, in, iv, t, f, shffle, out []uint64) + +func compressSSE(d *digest, p []uint8) { + var ( + in [8]uint64 + out [8]uint64 + shffle [2]uint64 + ) + + // vector for PSHUFB instruction + shffle[0] = 0x0201000706050403 + shffle[1] = 0x0a09080f0e0d0c0b + + in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] + + blockSSELoop(p, in[:], iv[:], d.t[:], d.f[:], shffle[:], out[:]) + + d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] +} diff --git a/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s b/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s new file mode 100644 index 00000000..6f31c949 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compressSse_amd64.s @@ -0,0 +1,770 @@ +//+build !noasm !appengine + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// Based on SSE implementation from https://github.com/BLAKE2/BLAKE2/blob/master/sse/blake2b.c +// +// Use github.com/fwessels/asm2plan9s on this file to assemble instructions to their Plan9 equivalent +// +// Assembly code below essentially follows the ROUND macro (see blake2b-round.h) which is defined as: +// #define ROUND(r) \ +// LOAD_MSG_ ##r ##_1(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_2(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ +// LOAD_MSG_ ##r ##_3(b0, b1); \ +// G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// LOAD_MSG_ ##r ##_4(b0, b1); \ +// G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ +// UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); +// +// as well as the go equivalent in https://github.com/dchest/blake2b/blob/master/block.go +// +// As in the macro, G1/G2 in the 1st and 2nd half are identical (so literal copy of assembly) +// +// Rounds are also the same, except for the loading of the message (and rounds 1 & 11 and +// rounds 2 & 12 are identical) +// + +#define G1 \ + \ // G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); + LONG $0xd40f4166; BYTE $0xc0 \ // PADDQ XMM0,XMM8 /* v0 += m[0], v1 += m[2] */ + LONG $0xd40f4166; BYTE $0xc9 \ // PADDQ XMM1,XMM9 /* v2 += m[4], v3 += m[6] */ + LONG $0xc2d40f66 \ // PADDQ XMM0,XMM2 /* v0 += v4, v1 += v5 */ + LONG $0xcbd40f66 \ // PADDQ XMM1,XMM3 /* v2 += v6, v3 += v7 */ + LONG $0xf0ef0f66 \ // PXOR XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ + LONG $0xf9ef0f66 \ // PXOR XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ + LONG $0xf6700f66; BYTE $0xb1 \ // PSHUFD XMM6,XMM6,0xb1 /* v12 = v12<<(64-32) | v12>>32, v13 = v13<<(64-32) | v13>>32 */ + LONG $0xff700f66; BYTE $0xb1 \ // PSHUFD XMM7,XMM7,0xb1 /* v14 = v14<<(64-32) | v14>>32, v15 = v15<<(64-32) | v15>>32 */ + LONG $0xe6d40f66 \ // PADDQ XMM4,XMM6 /* v8 += v12, v9 += v13 */ + LONG $0xefd40f66 \ // PADDQ XMM5,XMM7 /* v10 += v14, v11 += v15 */ + LONG $0xd4ef0f66 \ // PXOR XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ + LONG $0xddef0f66 \ // PXOR XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ + LONG $0x380f4166; WORD $0xd400 \ // PSHUFB XMM2,XMM12 /* v4 = v4<<(64-24) | v4>>24, v5 = v5<<(64-24) | v5>>24 */ + LONG $0x380f4166; WORD $0xdc00 // PSHUFB XMM3,XMM12 /* v6 = v6<<(64-24) | v6>>24, v7 = v7<<(64-24) | v7>>24 */ + +#define G2 \ + \ // G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); + LONG $0xd40f4166; BYTE $0xc2 \ // PADDQ XMM0,XMM10 /* v0 += m[1], v1 += m[3] */ + LONG $0xd40f4166; BYTE $0xcb \ // PADDQ XMM1,XMM11 /* v2 += m[5], v3 += m[7] */ + LONG $0xc2d40f66 \ // PADDQ XMM0,XMM2 /* v0 += v4, v1 += v5 */ + LONG $0xcbd40f66 \ // PADDQ XMM1,XMM3 /* v2 += v6, v3 += v7 */ + LONG $0xf0ef0f66 \ // PXOR XMM6,XMM0 /* v12 ^= v0, v13 ^= v1 */ + LONG $0xf9ef0f66 \ // PXOR XMM7,XMM1 /* v14 ^= v2, v15 ^= v3 */ + LONG $0xf6700ff2; BYTE $0x39 \ // PSHUFLW XMM6,XMM6,0x39 /* combined with next ... */ + LONG $0xf6700ff3; BYTE $0x39 \ // PSHUFHW XMM6,XMM6,0x39 /* v12 = v12<<(64-16) | v12>>16, v13 = v13<<(64-16) | v13>>16 */ + LONG $0xff700ff2; BYTE $0x39 \ // PSHUFLW XMM7,XMM7,0x39 /* combined with next ... */ + LONG $0xff700ff3; BYTE $0x39 \ // PSHUFHW XMM7,XMM7,0x39 /* v14 = v14<<(64-16) | v14>>16, v15 = v15<<(64-16) | v15>>16 */ + LONG $0xe6d40f66 \ // PADDQ XMM4,XMM6 /* v8 += v12, v9 += v13 */ + LONG $0xefd40f66 \ // PADDQ XMM5,XMM7 /* v10 += v14, v11 += v15 */ + LONG $0xd4ef0f66 \ // PXOR XMM2,XMM4 /* v4 ^= v8, v5 ^= v9 */ + LONG $0xddef0f66 \ // PXOR XMM3,XMM5 /* v6 ^= v10, v7 ^= v11 */ + MOVOU X2, X15 \ + LONG $0xd40f4466; BYTE $0xfa \ // PADDQ XMM15,XMM2 /* temp reg = reg*2 */ + LONG $0xd2730f66; BYTE $0x3f \ // PSRLQ XMM2,0x3f /* reg = reg>>63 */ + LONG $0xef0f4166; BYTE $0xd7 \ // PXOR XMM2,XMM15 /* ORed together: v4 = v4<<(64-63) | v4>>63, v5 = v5<<(64-63) | v5>>63 */ + MOVOU X3, X15 \ + LONG $0xd40f4466; BYTE $0xfb \ // PADDQ XMM15,XMM3 /* temp reg = reg*2 */ + LONG $0xd3730f66; BYTE $0x3f \ // PSRLQ XMM3,0x3f /* reg = reg>>63 */ + LONG $0xef0f4166; BYTE $0xdf // PXOR XMM3,XMM15 /* ORed together: v6 = v6<<(64-63) | v6>>63, v7 = v7<<(64-63) | v7>>63 */ + +#define DIAGONALIZE \ + \ // DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + MOVOU X6, X13 \ /* t0 = row4l;\ */ + MOVOU X2, X14 \ /* t1 = row2l;\ */ + MOVOU X4, X6 \ /* row4l = row3l;\ */ + MOVOU X5, X4 \ /* row3l = row3h;\ */ + MOVOU X6, X5 \ /* row3h = row4l;\ */ + LONG $0x6c0f4566; BYTE $0xfd \ // PUNPCKLQDQ XMM15, XMM13 /* _mm_unpacklo_epi64(t0, t0) */ + MOVOU X7, X6 \ + LONG $0x6d0f4166; BYTE $0xf7 \ // PUNPCKHQDQ XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4h, ); \ */ + LONG $0x6c0f4466; BYTE $0xff \ // PUNPCKLQDQ XMM15, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ + MOVOU X13, X7 \ + LONG $0x6d0f4166; BYTE $0xff \ // PUNPCKHQDQ XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(t0, ); \ */ + LONG $0x6c0f4466; BYTE $0xfb \ // PUNPCKLQDQ XMM15, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ + LONG $0x6d0f4166; BYTE $0xd7 \ // PUNPCKHQDQ XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2l, ); \ */ + LONG $0x6c0f4566; BYTE $0xfe \ // PUNPCKLQDQ XMM15, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ + LONG $0x6d0f4166; BYTE $0xdf // PUNPCKHQDQ XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(row2h, ) */ + +#define UNDIAGONALIZE \ + \ // UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + MOVOU X4, X13 \ /* t0 = row3l;\ */ + MOVOU X5, X4 \ /* row3l = row3h;\ */ + MOVOU X13, X5 \ /* row3h = t0;\ */ + MOVOU X2, X13 \ /* t0 = row2l;\ */ + MOVOU X6, X14 \ /* t1 = row4l;\ */ + LONG $0x6c0f4466; BYTE $0xfa \ // PUNPCKLQDQ XMM15, XMM2 /* _mm_unpacklo_epi64(row2l, row2l) */ + MOVOU X3, X2 \ + LONG $0x6d0f4166; BYTE $0xd7 \ // PUNPCKHQDQ XMM2, XMM15 /* row2l = _mm_unpackhi_epi64(row2h, ); \ */ + LONG $0x6c0f4466; BYTE $0xfb \ // PUNPCKLQDQ XMM15, XMM3 /* _mm_unpacklo_epi64(row2h, row2h) */ + MOVOU X13, X3 \ + LONG $0x6d0f4166; BYTE $0xdf \ // PUNPCKHQDQ XMM3, XMM15 /* row2h = _mm_unpackhi_epi64(t0, ); \ */ + LONG $0x6c0f4466; BYTE $0xff \ // PUNPCKLQDQ XMM15, XMM7 /* _mm_unpacklo_epi64(row4h, row4h) */ + LONG $0x6d0f4166; BYTE $0xf7 \ // PUNPCKHQDQ XMM6, XMM15 /* row4l = _mm_unpackhi_epi64(row4l, ); \ */ + LONG $0x6c0f4566; BYTE $0xfe \ // PUNPCKLQDQ XMM15, XMM14 /* _mm_unpacklo_epi64(t1, t1) */ + LONG $0x6d0f4166; BYTE $0xff // PUNPCKHQDQ XMM7, XMM15 /* row4h = _mm_unpackhi_epi64(row4h, ) */ + +#define LOAD_SHUFFLE \ + \ // Load shuffle value + MOVQ shffle+120(FP), SI \ // SI: &shuffle + MOVOU 0(SI), X12 // X12 = 03040506 07000102 0b0c0d0e 0f08090a + +// func blockSSELoop(p []uint8, in, iv, t, f, shffle, out []uint64) +TEXT ·blockSSELoop(SB), 7, $0 + // REGISTER USE + // R8: loop counter + // DX: message pointer + // SI: temp pointer for loading + // X0 - X7: v0 - v15 + // X8 - X11: m[0] - m[7] + // X12: shuffle value + // X13 - X15: temp registers + + // Load digest + MOVQ in+24(FP), SI // SI: &in + MOVOU 0(SI), X0 // X0 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ + MOVOU 16(SI), X1 // X1 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ + MOVOU 32(SI), X2 // X2 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ + MOVOU 48(SI), X3 // X3 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ + + // Already store digest into &out (so we can reload it later generically) + MOVQ out+144(FP), SI // SI: &out + MOVOU X0, 0(SI) // out[0]+out[1] = X0 + MOVOU X1, 16(SI) // out[2]+out[3] = X1 + MOVOU X2, 32(SI) // out[4]+out[5] = X2 + MOVOU X3, 48(SI) // out[6]+out[7] = X3 + + // Initialize message pointer and loop counter + MOVQ message+0(FP), DX // DX: &p (message) + MOVQ message_len+8(FP), R8 // R8: len(message) + SHRQ $7, R8 // len(message) / 128 + CMPQ R8, $0 + JEQ complete + +loop: + // Increment counter + MOVQ t+72(FP), SI // SI: &t + MOVQ 0(SI), R9 + ADDQ $128, R9 // /* d.t[0] += BlockSize */ + MOVQ R9, 0(SI) + CMPQ R9, $128 // /* if d.t[0] < BlockSize { */ + JGE noincr + MOVQ 8(SI), R9 + ADDQ $1, R9 // /* d.t[1]++ */ + MOVQ R9, 8(SI) + +noincr: // /* } */ + + // Load initialization vector + MOVQ iv+48(FP), SI // SI: &iv + MOVOU 0(SI), X4 // X4 = iv[0]+iv[1] /* row3l = LOAD( &blake2b_IV[0] ); */ + MOVOU 16(SI), X5 // X5 = iv[2]+iv[3] /* row3h = LOAD( &blake2b_IV[2] ); */ + MOVOU 32(SI), X6 // X6 = iv[4]+iv[5] /* LOAD( &blake2b_IV[4] ) */ + MOVOU 48(SI), X7 // X7 = iv[6]+iv[7] /* LOAD( &blake2b_IV[6] ) */ + MOVQ t+72(FP), SI // SI: &t + MOVOU 0(SI), X8 // X8 = t[0]+t[1] /* LOAD( &S->t[0] ) */ + PXOR X8, X6 // X6 = X6 ^ X8 /* row4l = _mm_xor_si128( , ); */ + MOVQ t+96(FP), SI // SI: &f + MOVOU 0(SI), X8 // X8 = f[0]+f[1] /* LOAD( &S->f[0] ) */ + PXOR X8, X7 // X7 = X7 ^ X8 /* row4h = _mm_xor_si128( , ); */ + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+m[1] + MOVOU 16(DX), X13 // X13 = m[2]+m[3] + MOVOU 32(DX), X14 // X14 = m[4]+m[5] + MOVOU 48(DX), X15 // X15 = m[6]+m[7] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[2] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[4], m[6] */ + MOVOU X12, X10 + LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[1], m[3] */ + MOVOU X14, X11 + LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[5], m[7] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[8],m[10] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[12],m[14] */ + MOVOU X12, X10 + LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[9],m[11] */ + MOVOU X14, X11 + LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[13],m[15] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 2 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 112(DX), X12 // X12 = m[14]+m[15] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[14], m[4] */ + MOVOU X14, X9 + LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[9], m[13] */ + MOVOU 80(DX), X10 // X10 = m[10]+m[11] + MOVOU 48(DX), X11 // X11 = m[6]+ m[7] + LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[10], m[8] */ + LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[15], m[6] */; ; ; ; ; + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU X12, X8 + LONG $0x3a0f4566; WORD $0xc40f; BYTE $0x08 // PALIGNR XMM8, XMM12, 0x8 /* m[1], m[0] */ + MOVOU X14, X9 + LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* m[11], m[5] */ + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X11 // X11 = m[6]+ m[7] + MOVOU 96(DX), X10 // X10 = m[12]+m[13] + LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[2] */ + LONG $0x6d0f4566; BYTE $0xdc // PUNPCKHQDQ XMM11, XMM12 /* m[7], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 3 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 32(DX), X12 // X12 = m[4]+ m[5] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X14, X8 + LONG $0x3a0f4566; WORD $0xc50f; BYTE $0x08 // PALIGNR XMM8, XMM13, 0x8 /* m[11], m[12] */ + MOVOU X12, X9 + LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[5], m[15] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 64(DX), X10 // X10 = m[8]+ m[9] + LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[8], m[0] */ + LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[13] */ + MOVOU X13, X11 + LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[2], ___ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + MOVOU X12, X9 + LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* ___, m[3] */ + MOVOU X15, X8 + LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[10], ___ */ + MOVOU X13, X9 + LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[7], m[9] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X11 // X11 = m[4]+ m[5] + MOVOU 112(DX), X10 // X10 = m[14]+m[15] + LONG $0x6c0f4566; BYTE $0xd5 // PUNPCKLQDQ XMM10, XMM13 /* m[14], m[6] */ + LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[1], m[4] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 4 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + MOVOU X13, X8 + LONG $0x6d0f4566; BYTE $0xc4 // PUNPCKHQDQ XMM8, XMM12 /* m[7], m[3] */ + MOVOU X15, X9 + LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[13], m[11] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 64(DX), X10 // X10 = m[8]+ m[9] + MOVOU 112(DX), X14 // X14 = m[14]+m[15] + LONG $0x6d0f4566; BYTE $0xd4 // PUNPCKHQDQ XMM10, XMM12 /* m[9], m[1] */ + MOVOU X15, X11 + LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[12], m[14] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X13, X9 + LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* ___, m[5] */ + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[2], ____ */ + MOVOU X15, X10 + LONG $0x6d0f4566; BYTE $0xd7 // PUNPCKHQDQ XMM10, XMM15 /* ___, m[15] */ + MOVOU X13, X9 + LONG $0x6c0f4566; BYTE $0xca // PUNPCKLQDQ XMM9, XMM10 /* m[4], ____ */ + MOVOU 0(DX), X11 // X11 = m[0]+ m[1] + MOVOU 48(DX), X10 // X10 = m[6]+ m[7] + MOVOU 64(DX), X15 // X15 = m[8]+ m[9] + LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[6], m[10] */ + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[0], m[8] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 5 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + MOVOU X14, X8 + LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[9], m[5] */ + MOVOU X12, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[2], m[10] */ + MOVOU 0(DX), X10 // X10 = m[0]+ m[1] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[7] */ + LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[0], ____ */ + LONG $0x6d0f4566; BYTE $0xff // PUNPCKHQDQ XMM15, XMM15 /* ___, m[15] */ + MOVOU X13, X11 + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[4], ____ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[11] */ + MOVOU X15, X8 + LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[14], ____ */ + LONG $0x6d0f4566; BYTE $0xe4 // PUNPCKHQDQ XMM12, XMM12 /* ___, m[3] */ + MOVOU X13, X9 + LONG $0x6c0f4566; BYTE $0xcc // PUNPCKLQDQ XMM9, XMM12 /* m[6], ____ */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 64(DX), X11 // X11 = m[8]+ m[9] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU X14, X10 + LONG $0x3a0f4566; WORD $0xd40f; BYTE $0x08 // PALIGNR XMM10, XMM12, 0x8 /* m[1], m[12] */ + LONG $0x6d0f4566; BYTE $0xf6 // PUNPCKHQDQ XMM14, XMM14 /* ___, m[13] */ + LONG $0x6c0f4566; BYTE $0xde // PUNPCKLQDQ XMM11, XMM14 /* m[8], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 6 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 64(DX), X15 // X15 = m[8]+ m[9] + MOVOU X13, X8 + LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[2], m[6] */ + MOVOU X12, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[0], m[8] */ + MOVOU 80(DX), X12 // X12 = m[10]+m[11] + MOVOU 96(DX), X10 // X10 = m[12]+m[13] + LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[10] */ + MOVOU X12, X11 + LONG $0x6d0f4566; BYTE $0xdd // PUNPCKHQDQ XMM11, XMM13 /* m[11], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 48(DX), X14 // X14 = m[6]+ m[7] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X14, X9 + LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* ___, m[7] */ + MOVOU X13, X8 + LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[4], ____ */ + MOVOU X15, X9 + LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* m[15], m[1] */ + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 96(DX), X10 // X10 = m[12]+m[13] + LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[13], m[5] */ + LONG $0x6d0f4566; BYTE $0xe4 // PUNPCKHQDQ XMM12, XMM12 /* ___, m[9] */ + MOVOU X15, X11 + LONG $0x6c0f4566; BYTE $0xdc // PUNPCKLQDQ XMM11, XMM12 /* m[14], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 7 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X12, X9 + LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* ___, m[1] */ + MOVOU X14, X8 + LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[12], ____ */ + MOVOU X15, X9 + LONG $0x6c0f4566; BYTE $0xcd // PUNPCKLQDQ XMM9, XMM13 /* m[14], m[4] */ + MOVOU 80(DX), X11 // X11 = m[10]+m[11] + MOVOU X13, X10 + LONG $0x6d0f4566; BYTE $0xd7 // PUNPCKHQDQ XMM10, XMM15 /* m[5], m[15] */ + LONG $0x3a0f4566; WORD $0xde0f; BYTE $0x08 // PALIGNR XMM11, XMM14, 0x8 /* m[13], m[10] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[6] */ + MOVOU X14, X9 + LONG $0x3a0f4566; WORD $0xce0f; BYTE $0x08 // PALIGNR XMM9, XMM14, 0x8 /* m[9], m[8] */ + MOVOU 16(DX), X11 // X14 = m[2]+ m[3] + MOVOU X13, X10 + LONG $0x6d0f4566; BYTE $0xd3 // PUNPCKHQDQ XMM10, XMM11 /* m[7], m[3] */ + LONG $0x6d0f4566; BYTE $0xff // PUNPCKHQDQ XMM15, XMM15 /* ___, m[11] */ + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[2], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 8 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X14, X8 + LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[13], m[7] */ + MOVOU X12, X10 + LONG $0x6d0f4566; BYTE $0xd4 // PUNPCKHQDQ XMM10, XMM12 /* ___, m[3] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xca // PUNPCKLQDQ XMM9, XMM10 /* m[12], ____ */ + MOVOU 0(DX), X11 // X11 = m[0]+ m[1] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU X15, X10 + LONG $0x3a0f4566; WORD $0xd60f; BYTE $0x08 // PALIGNR XMM10, XMM14, 0x8 /* m[11], m[14] */ + LONG $0x6d0f4566; BYTE $0xdd // PUNPCKHQDQ XMM11, XMM13 /* m[1], m[9] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X13, X8 + LONG $0x6d0f4566; BYTE $0xc7 // PUNPCKHQDQ XMM8, XMM15 /* m[5], m[15] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xcc // PUNPCKLQDQ XMM9, XMM12 /* m[8], m[2] */ + MOVOU 0(DX), X10 // X10 = m[0]+ m[1] + MOVOU 48(DX), X11 // X11 = m[6]+ m[7] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + LONG $0x6c0f4566; BYTE $0xd5 // PUNPCKLQDQ XMM10, XMM13 /* m[0], m[4] */ + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[6], m[10] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 9 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X13, X8 + LONG $0x6c0f4566; BYTE $0xc7 // PUNPCKLQDQ XMM8, XMM15 /* m[6], m[14] */ + MOVOU X12, X9 + LONG $0x3a0f4566; WORD $0xce0f; BYTE $0x08 // PALIGNR XMM9, XMM14, 0x8 /* m[11], m[0] */ + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 64(DX), X11 // X11 = m[8]+ m[9] + MOVOU X15, X10 + LONG $0x6d0f4566; BYTE $0xd3 // PUNPCKHQDQ XMM10, XMM11 /* m[15], m[9] */ + LONG $0x3a0f4566; WORD $0xdd0f; BYTE $0x08 // PALIGNR XMM11, XMM13, 0x8 /* m[3], m[8] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 16(DX), X13 // X13 = m[2]+ m[3] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + MOVOU X15, X9 + LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* ___, m[13] */ + MOVOU X15, X8 + LONG $0x6c0f4566; BYTE $0xc1 // PUNPCKLQDQ XMM8, XMM9 /* m[12], ____ */ + MOVOU X14, X9 + LONG $0x3a0f4566; WORD $0xcc0f; BYTE $0x08 // PALIGNR XMM9, XMM12, 0x8 /* m[1], m[10] */ + MOVOU 32(DX), X12 // X12 = m[4]+ m[5] + MOVOU 48(DX), X15 // X15 = m[6]+ m[7] + MOVOU X15, X11 + LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* ___, m[7] */ + MOVOU X13, X10 + LONG $0x6c0f4566; BYTE $0xd3 // PUNPCKLQDQ XMM10, XMM11 /* m[2], ____ */ + MOVOU X12, X15 + LONG $0x6d0f4566; BYTE $0xfc // PUNPCKHQDQ XMM15, XMM12 /* ___, m[5] */ + MOVOU X12, X11 + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[4], ____ */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 0 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 48(DX), X13 // X13 = m[6]+ m[7] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 80(DX), X15 // X15 = m[10]+m[11] + MOVOU X15, X8 + LONG $0x6c0f4566; BYTE $0xc6 // PUNPCKLQDQ XMM8, XMM14 /* m[10], m[8] */ + MOVOU X13, X9 + LONG $0x6d0f4566; BYTE $0xcc // PUNPCKHQDQ XMM9, XMM12 /* m[7], m[1] */ + MOVOU 16(DX), X10 // X10 = m[2]+ m[3] + MOVOU 32(DX), X14 // X14 = m[4]+ m[5] + LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[2], m[4] */ + MOVOU X14, X15 + LONG $0x6d0f4566; BYTE $0xfe // PUNPCKHQDQ XMM15, XMM14 /* ___, m[5] */ + MOVOU X13, X11 + LONG $0x6c0f4566; BYTE $0xdf // PUNPCKLQDQ XMM11, XMM15 /* m[6], ____ */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 64(DX), X13 // X13 = m[8]+ m[9] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X15, X8 + LONG $0x6d0f4566; BYTE $0xc5 // PUNPCKHQDQ XMM8, XMM13 /* m[15], m[9] */ + MOVOU X12, X9 + LONG $0x6d0f4566; BYTE $0xce // PUNPCKHQDQ XMM9, XMM14 /* m[3], m[13] */ + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU X15, X10 + LONG $0x3a0f4566; WORD $0xd50f; BYTE $0x08 // PALIGNR XMM10, XMM13, 0x8 /* m[11], m[14] */ + MOVOU X14, X11 + LONG $0x6c0f4566; BYTE $0xdc // PUNPCKLQDQ XMM11, XMM12 /* m[12], m[0] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 1 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+m[1] + MOVOU 16(DX), X13 // X13 = m[2]+m[3] + MOVOU 32(DX), X14 // X14 = m[4]+m[5] + MOVOU 48(DX), X15 // X15 = m[6]+m[7] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[0], m[2] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[4], m[6] */ + MOVOU X12, X10 + LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[1], m[3] */ + MOVOU X14, X11 + LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[5], m[7] */ + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 64(DX), X12 // X12 = m[8]+ m[9] + MOVOU 80(DX), X13 // X13 = m[10]+m[11] + MOVOU 96(DX), X14 // X14 = m[12]+m[13] + MOVOU 112(DX), X15 // X15 = m[14]+m[15] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[8],m[10] */ + MOVOU X14, X9 + LONG $0x6c0f4566; BYTE $0xcf // PUNPCKLQDQ XMM9, XMM15 /* m[12],m[14] */ + MOVOU X12, X10 + LONG $0x6d0f4566; BYTE $0xd5 // PUNPCKHQDQ XMM10, XMM13 /* m[9],m[11] */ + MOVOU X14, X11 + LONG $0x6d0f4566; BYTE $0xdf // PUNPCKHQDQ XMM11, XMM15 /* m[13],m[15] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + /////////////////////////////////////////////////////////////////////////// + // R O U N D 1 2 + /////////////////////////////////////////////////////////////////////////// + + // LOAD_MSG_ ##r ##_1 / ##_2(b0, b1); (X12 is temp register) + MOVOU 112(DX), X12 // X12 = m[14]+m[15] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 64(DX), X14 // X14 = m[8]+ m[9] + MOVOU 96(DX), X15 // X15 = m[12]+m[13] + MOVOU X12, X8 + LONG $0x6c0f4566; BYTE $0xc5 // PUNPCKLQDQ XMM8, XMM13 /* m[14], m[4] */ + MOVOU X14, X9 + LONG $0x6d0f4566; BYTE $0xcf // PUNPCKHQDQ XMM9, XMM15 /* m[9], m[13] */ + MOVOU 80(DX), X10 // X10 = m[10]+m[11] + MOVOU 48(DX), X11 // X11 = m[6]+ m[7] + LONG $0x6c0f4566; BYTE $0xd6 // PUNPCKLQDQ XMM10, XMM14 /* m[10], m[8] */ + LONG $0x3a0f4566; WORD $0xdc0f; BYTE $0x08 // PALIGNR XMM11, XMM12, 0x8 /* m[15], m[6] */; ; ; ; ; + + LOAD_SHUFFLE + G1 + G2 + DIAGONALIZE + + // LOAD_MSG_ ##r ##_3 / ##_4(b0, b1); (X12 is temp register) + MOVOU 0(DX), X12 // X12 = m[0]+ m[1] + MOVOU 32(DX), X13 // X13 = m[4]+ m[5] + MOVOU 80(DX), X14 // X14 = m[10]+m[11] + MOVOU X12, X8 + LONG $0x3a0f4566; WORD $0xc40f; BYTE $0x08 // PALIGNR XMM8, XMM12, 0x8 /* m[1], m[0] */ + MOVOU X14, X9 + LONG $0x6d0f4566; BYTE $0xcd // PUNPCKHQDQ XMM9, XMM13 /* m[11], m[5] */ + MOVOU 16(DX), X12 // X12 = m[2]+ m[3] + MOVOU 48(DX), X11 // X11 = m[6]+ m[7] + MOVOU 96(DX), X10 // X10 = m[12]+m[13] + LONG $0x6c0f4566; BYTE $0xd4 // PUNPCKLQDQ XMM10, XMM12 /* m[12], m[2] */ + LONG $0x6d0f4566; BYTE $0xdc // PUNPCKHQDQ XMM11, XMM12 /* m[7], m[3] */ + + LOAD_SHUFFLE + G1 + G2 + UNDIAGONALIZE + + // Reload digest (most current value store in &out) + MOVQ out+144(FP), SI // SI: &in + MOVOU 0(SI), X12 // X12 = in[0]+in[1] /* row1l = LOAD( &S->h[0] ); */ + MOVOU 16(SI), X13 // X13 = in[2]+in[3] /* row1h = LOAD( &S->h[2] ); */ + MOVOU 32(SI), X14 // X14 = in[4]+in[5] /* row2l = LOAD( &S->h[4] ); */ + MOVOU 48(SI), X15 // X15 = in[6]+in[7] /* row2h = LOAD( &S->h[6] ); */ + + // Final computations and prepare for storing + PXOR X4, X0 // X0 = X0 ^ X4 /* row1l = _mm_xor_si128( row3l, row1l ); */ + PXOR X5, X1 // X1 = X1 ^ X5 /* row1h = _mm_xor_si128( row3h, row1h ); */ + PXOR X12, X0 // X0 = X0 ^ X12 /* STORE( &S->h[0], _mm_xor_si128( LOAD( &S->h[0] ), row1l ) ); */ + PXOR X13, X1 // X1 = X1 ^ X13 /* STORE( &S->h[2], _mm_xor_si128( LOAD( &S->h[2] ), row1h ) ); */ + PXOR X6, X2 // X2 = X2 ^ X6 /* row2l = _mm_xor_si128( row4l, row2l ); */ + PXOR X7, X3 // X3 = X3 ^ X7 /* row2h = _mm_xor_si128( row4h, row2h ); */ + PXOR X14, X2 // X2 = X2 ^ X14 /* STORE( &S->h[4], _mm_xor_si128( LOAD( &S->h[4] ), row2l ) ); */ + PXOR X15, X3 // X3 = X3 ^ X15 /* STORE( &S->h[6], _mm_xor_si128( LOAD( &S->h[6] ), row2h ) ); */ + + // Store digest into &out + MOVQ out+144(FP), SI // SI: &out + MOVOU X0, 0(SI) // out[0]+out[1] = X0 + MOVOU X1, 16(SI) // out[2]+out[3] = X1 + MOVOU X2, 32(SI) // out[4]+out[5] = X2 + MOVOU X3, 48(SI) // out[6]+out[7] = X3 + + // Increment message pointer and check if there's more to do + ADDQ $128, DX // message += 128 + SUBQ $1, R8 + JNZ loop + +complete: + RET diff --git a/vendor/github.com/minio/blake2b-simd/compress_amd64.go b/vendor/github.com/minio/blake2b-simd/compress_amd64.go new file mode 100644 index 00000000..4fc5e388 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compress_amd64.go @@ -0,0 +1,30 @@ +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +func compress(d *digest, p []uint8) { + // Verifies if AVX2 or AVX is available, use optimized code path. + if avx2 { + compressAVX2(d, p) + } else if avx { + compressAVX(d, p) + } else if ssse3 { + compressSSE(d, p) + } else { + compressGeneric(d, p) + } +} diff --git a/vendor/github.com/minio/blake2b-simd/compress_generic.go b/vendor/github.com/minio/blake2b-simd/compress_generic.go new file mode 100644 index 00000000..e9e16e8b --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compress_generic.go @@ -0,0 +1,1419 @@ +// Written in 2012 by Dmitry Chestnykh. +// +// To the extent possible under law, the author have dedicated all copyright +// and related and neighboring rights to this software to the public domain +// worldwide. This software is distributed without any warranty. +// http://creativecommons.org/publicdomain/zero/1.0/ + +package blake2b + +func compressGeneric(d *digest, p []uint8) { + h0, h1, h2, h3, h4, h5, h6, h7 := d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] + + for len(p) >= BlockSize { + // Increment counter. + d.t[0] += BlockSize + if d.t[0] < BlockSize { + d.t[1]++ + } + // Initialize compression function. + v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 + v8 := iv[0] + v9 := iv[1] + v10 := iv[2] + v11 := iv[3] + v12 := iv[4] ^ d.t[0] + v13 := iv[5] ^ d.t[1] + v14 := iv[6] ^ d.f[0] + v15 := iv[7] ^ d.f[1] + + j := 0 + var m [16]uint64 + for i := range m { + m[i] = uint64(p[j]) | uint64(p[j+1])<<8 | uint64(p[j+2])<<16 | + uint64(p[j+3])<<24 | uint64(p[j+4])<<32 | uint64(p[j+5])<<40 | + uint64(p[j+6])<<48 | uint64(p[j+7])<<56 + j += 8 + } + + // Round 1. + v0 += m[0] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[2] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[4] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[6] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[5] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[7] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[3] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[1] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[8] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[10] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[12] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[14] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[13] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[15] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[11] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[9] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 2. + v0 += m[14] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[4] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[9] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[13] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[15] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[6] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[8] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[10] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[1] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[0] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[11] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[5] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[7] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[3] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[2] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[12] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 3. + v0 += m[11] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[12] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[5] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[15] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[2] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[13] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[0] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[8] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[10] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[3] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[7] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[9] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[1] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[4] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[6] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[14] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 4. + v0 += m[7] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[3] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[13] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[11] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[12] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[14] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[1] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[9] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[2] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[5] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[4] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[15] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[0] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[8] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[10] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[6] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 5. + v0 += m[9] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[5] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[2] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[10] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[4] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[15] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[7] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[0] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[14] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[11] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[6] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[3] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[8] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[13] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[12] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[1] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 6. + v0 += m[2] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[6] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[0] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[8] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[11] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[3] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[10] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[12] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[4] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[7] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[15] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[1] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[14] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[9] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[5] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[13] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 7. + v0 += m[12] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[1] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[14] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[4] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[13] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[10] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[15] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[5] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[0] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[6] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[9] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[8] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[2] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[11] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[3] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[7] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 8. + v0 += m[13] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[7] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[12] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[3] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[1] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[9] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[14] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[11] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[5] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[15] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[8] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[2] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[6] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[10] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[4] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[0] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 9. + v0 += m[6] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[14] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[11] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[0] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[3] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[8] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[9] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[15] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[12] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[13] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[1] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[10] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[4] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[5] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[7] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[2] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 10. + v0 += m[10] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[8] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[7] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[1] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[6] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[5] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[4] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[2] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[15] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[9] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[3] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[13] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[12] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[0] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[14] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[11] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 11. + v0 += m[0] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[2] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[4] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[6] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[5] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[7] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[3] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[1] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[8] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[10] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[12] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[14] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[13] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[15] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[11] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[9] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + // Round 12. + v0 += m[14] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-32) | v12>>32 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-24) | v4>>24 + v1 += m[4] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-32) | v13>>32 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-24) | v5>>24 + v2 += m[9] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-32) | v14>>32 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-24) | v6>>24 + v3 += m[13] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-32) | v15>>32 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-24) | v7>>24 + v2 += m[15] + v2 += v6 + v14 ^= v2 + v14 = v14<<(64-16) | v14>>16 + v10 += v14 + v6 ^= v10 + v6 = v6<<(64-63) | v6>>63 + v3 += m[6] + v3 += v7 + v15 ^= v3 + v15 = v15<<(64-16) | v15>>16 + v11 += v15 + v7 ^= v11 + v7 = v7<<(64-63) | v7>>63 + v1 += m[8] + v1 += v5 + v13 ^= v1 + v13 = v13<<(64-16) | v13>>16 + v9 += v13 + v5 ^= v9 + v5 = v5<<(64-63) | v5>>63 + v0 += m[10] + v0 += v4 + v12 ^= v0 + v12 = v12<<(64-16) | v12>>16 + v8 += v12 + v4 ^= v8 + v4 = v4<<(64-63) | v4>>63 + v0 += m[1] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-32) | v15>>32 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-24) | v5>>24 + v1 += m[0] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-32) | v12>>32 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-24) | v6>>24 + v2 += m[11] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-32) | v13>>32 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-24) | v7>>24 + v3 += m[5] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-32) | v14>>32 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-24) | v4>>24 + v2 += m[7] + v2 += v7 + v13 ^= v2 + v13 = v13<<(64-16) | v13>>16 + v8 += v13 + v7 ^= v8 + v7 = v7<<(64-63) | v7>>63 + v3 += m[3] + v3 += v4 + v14 ^= v3 + v14 = v14<<(64-16) | v14>>16 + v9 += v14 + v4 ^= v9 + v4 = v4<<(64-63) | v4>>63 + v1 += m[2] + v1 += v6 + v12 ^= v1 + v12 = v12<<(64-16) | v12>>16 + v11 += v12 + v6 ^= v11 + v6 = v6<<(64-63) | v6>>63 + v0 += m[12] + v0 += v5 + v15 ^= v0 + v15 = v15<<(64-16) | v15>>16 + v10 += v15 + v5 ^= v10 + v5 = v5<<(64-63) | v5>>63 + + h0 ^= v0 ^ v8 + h1 ^= v1 ^ v9 + h2 ^= v2 ^ v10 + h3 ^= v3 ^ v11 + h4 ^= v4 ^ v12 + h5 ^= v5 ^ v13 + h6 ^= v6 ^ v14 + h7 ^= v7 ^ v15 + + p = p[BlockSize:] + } + d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 +} diff --git a/vendor/github.com/minio/blake2b-simd/compress_noasm.go b/vendor/github.com/minio/blake2b-simd/compress_noasm.go new file mode 100644 index 00000000..d3c67584 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/compress_noasm.go @@ -0,0 +1,23 @@ +//+build !amd64 noasm appengine + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +func compress(d *digest, p []uint8) { + compressGeneric(d, p) +} diff --git a/vendor/github.com/minio/blake2b-simd/cpuid.go b/vendor/github.com/minio/blake2b-simd/cpuid.go new file mode 100644 index 00000000..a9f95508 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/cpuid.go @@ -0,0 +1,60 @@ +// +build 386,!gccgo amd64,!gccgo + +// Copyright 2016 Frank Wessels +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package blake2b + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +func xgetbv(index uint32) (eax, edx uint32) + +// True when SIMD instructions are available. +var avx2 = haveAVX2() +var avx = haveAVX() +var ssse3 = haveSSSE3() + +// haveAVX returns true when there is AVX support +func haveAVX() bool { + _, _, c, _ := cpuid(1) + + // Check XGETBV, OXSAVE and AVX bits + if c&(1<<26) != 0 && c&(1<<27) != 0 && c&(1<<28) != 0 { + // Check for OS support + eax, _ := xgetbv(0) + return (eax & 0x6) == 0x6 + } + return false +} + +// haveAVX2 returns true when there is AVX2 support +func haveAVX2() bool { + mfi, _, _, _ := cpuid(0) + + // Check AVX2, AVX2 requires OS support, but BMI1/2 don't. + if mfi >= 7 && haveAVX() { + _, ebx, _, _ := cpuidex(7, 0) + return (ebx & 0x00000020) != 0 + } + return false +} + +// haveSSSE3 returns true when there is SSSE3 support +func haveSSSE3() bool { + + _, _, c, _ := cpuid(1) + + return (c & 0x00000200) != 0 +} diff --git a/vendor/github.com/minio/blake2b-simd/cpuid_386.s b/vendor/github.com/minio/blake2b-simd/cpuid_386.s new file mode 100644 index 00000000..fa38814e --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/cpuid_386.s @@ -0,0 +1,33 @@ +// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. + +// +build 386,!gccgo + +// func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid(SB), 7, $0 + XORL CX, CX + MOVL op+0(FP), AX + CPUID + MOVL AX, eax+4(FP) + MOVL BX, ebx+8(FP) + MOVL CX, ecx+12(FP) + MOVL DX, edx+16(FP) + RET + +// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuidex(SB), 7, $0 + MOVL op+0(FP), AX + MOVL op2+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func xgetbv(index uint32) (eax, edx uint32) +TEXT ·xgetbv(SB), 7, $0 + MOVL index+0(FP), CX + BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV + MOVL AX, eax+4(FP) + MOVL DX, edx+8(FP) + RET diff --git a/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s b/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s new file mode 100644 index 00000000..fb45a656 --- /dev/null +++ b/vendor/github.com/minio/blake2b-simd/cpuid_amd64.s @@ -0,0 +1,34 @@ +// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. + +// +build amd64,!gccgo + +// func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid(SB), 7, $0 + XORQ CX, CX + MOVL op+0(FP), AX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + + +// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuidex(SB), 7, $0 + MOVL op+0(FP), AX + MOVL op2+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func xgetbv(index uint32) (eax, edx uint32) +TEXT ·xgetbv(SB), 7, $0 + MOVL index+0(FP), CX + BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV + MOVL AX, eax+8(FP) + MOVL DX, edx+12(FP) + RET diff --git a/vendor/github.com/minio/sha256-simd/.gitignore b/vendor/github.com/minio/sha256-simd/.gitignore new file mode 100644 index 00000000..c56069fe --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/.gitignore @@ -0,0 +1 @@ +*.test \ No newline at end of file diff --git a/vendor/github.com/minio/sha256-simd/.travis.yml b/vendor/github.com/minio/sha256-simd/.travis.yml new file mode 100644 index 00000000..744e64cf --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/.travis.yml @@ -0,0 +1,24 @@ +sudo: required +dist: trusty +language: go + +os: +- linux + +go: +- tip +- 1.11.x + +env: +- ARCH=x86_64 +- ARCH=i686 + +matrix: + fast_finish: true + allow_failures: + - go: tip + +script: +- diff -au <(gofmt -d .) <(printf "") +- go test -race -v ./... +- go tool vet -asmdecl . diff --git a/vendor/github.com/minio/sha256-simd/LICENSE b/vendor/github.com/minio/sha256-simd/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/minio/sha256-simd/README.md b/vendor/github.com/minio/sha256-simd/README.md new file mode 100644 index 00000000..5282d83a --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/README.md @@ -0,0 +1,133 @@ +# sha256-simd + +Accelerate SHA256 computations in pure Go using AVX512, SHA Extensions and AVX2 for Intel and ARM64 for ARM. On AVX512 it provides an up to 8x improvement (over 3 GB/s per core) in comparison to AVX2. SHA Extensions give a performance boost of close to 4x over AVX2. + +## Introduction + +This package is designed as a replacement for `crypto/sha256`. For Intel CPUs it has two flavors for AVX512 and AVX2 (AVX/SSE are also supported). For ARM CPUs with the Cryptography Extensions, advantage is taken of the SHA2 instructions resulting in a massive performance improvement. + +This package uses Golang assembly. The AVX512 version is based on the Intel's "multi-buffer crypto library for IPSec" whereas the other Intel implementations are described in "Fast SHA-256 Implementations on Intel Architecture Processors" by J. Guilford et al. + +## New: Support for Intel SHA Extensions + +Support for the Intel SHA Extensions has been added by Kristofer Peterson (@svenski123), originally developed for spacemeshos [here](https://github.com/spacemeshos/POET/issues/23). On CPUs that support it (known thus far Intel Celeron J3455 and AMD Ryzen) it gives a significant boost in performance (with thanks to @AudriusButkevicius for reporting the results; full results [here](https://github.com/minio/sha256-simd/pull/37#issuecomment-451607827)). + +``` +$ benchcmp avx2.txt sha-ext.txt +benchmark AVX2 MB/s SHA Ext MB/s speedup +BenchmarkHash5M 514.40 1975.17 3.84x +``` + +Thanks to Kristofer Peterson, we also added additional performance changes such as optimized padding, endian conversions which sped up all implementations i.e. Intel SHA alone while doubled performance for small sizes, the other changes increased everything roughly 50%. + +## Support for AVX512 + +We have added support for AVX512 which results in an up to 8x performance improvement over AVX2 (3.0 GHz Xeon Platinum 8124M CPU): + +``` +$ benchcmp avx2.txt avx512.txt +benchmark AVX2 MB/s AVX512 MB/s speedup +BenchmarkHash5M 448.62 3498.20 7.80x +``` + +The original code was developed by Intel as part of the [multi-buffer crypto library](https://github.com/intel/intel-ipsec-mb) for IPSec or more specifically this [AVX512](https://github.com/intel/intel-ipsec-mb/blob/master/avx512/sha256_x16_avx512.asm) implementation. The key idea behind it is to process a total of 16 checksums in parallel by “transposing” 16 (independent) messages of 64 bytes between a total of 16 ZMM registers (each 64 bytes wide). + +Transposing the input messages means that in order to take full advantage of the speedup you need to have a (server) workload where multiple threads are doing SHA256 calculations in parallel. Unfortunately for this algorithm it is not possible for two message blocks processed in parallel to be dependent on one another — because then the (interim) result of the first part of the message has to be an input into the processing of the second part of the message. + +Whereas the original Intel C implementation requires some sort of explicit scheduling of messages to be processed in parallel, for Golang it makes sense to take advantage of channels in order to group messages together and use channels as well for sending back the results (thereby effectively decoupling the calculations). We have implemented a fairly simple scheduling mechanism that seems to work well in practice. + +Due to this different way of scheduling, we decided to use an explicit method to instantiate the AVX512 version. Essentially one or more AVX512 processing servers ([`Avx512Server`](https://github.com/minio/sha256-simd/blob/master/sha256blockAvx512_amd64.go#L294)) have to be created whereby each server can hash over 3 GB/s on a single core. An `hash.Hash` object ([`Avx512Digest`](https://github.com/minio/sha256-simd/blob/master/sha256blockAvx512_amd64.go#L45)) is then instantiated using one of these servers and used in the regular fashion: + +```go +import "github.com/minio/sha256-simd" + +func main() { + server := sha256.NewAvx512Server() + h512 := sha256.NewAvx512(server) + h512.Write(fileBlock) + digest := h512.Sum([]byte{}) +} +``` + +Note that, because of the scheduling overhead, for small messages (< 1 MB) you will be better off using the regular SHA256 hashing (but those are typically not performance critical anyway). Some other tips to get the best performance: +* Have many go routines doing SHA256 calculations in parallel. +* Try to Write() messages in multiples of 64 bytes. +* Try to keep the overall length of messages to a roughly similar size ie. 5 MB (this way all 16 ‘lanes’ in the AVX512 computations are contributing as much as possible). + +More detailed information can be found in this [blog](https://blog.minio.io/accelerate-sha256-up-to-8x-over-3-gb-s-per-core-with-avx512-a0b1d64f78f) post including scaling across cores. + +## Drop-In Replacement + +The following code snippet shows how you can use `github.com/minio/sha256-simd`. This will automatically select the fastest method for the architecture on which it will be executed. + +```go +import "github.com/minio/sha256-simd" + +func main() { + ... + shaWriter := sha256.New() + io.Copy(shaWriter, file) + ... +} +``` + +## Performance + +Below is the speed in MB/s for a single core (ranked fast to slow) for blocks larger than 1 MB. + +| Processor | SIMD | Speed (MB/s) | +| --------------------------------- | ------- | ------------:| +| 3.0 GHz Intel Xeon Platinum 8124M | AVX512 | 3498 | +| 3.7 GHz AMD Ryzen 7 2700X | SHA Ext | 1979 | +| 1.2 GHz ARM Cortex-A53 | ARM64 | 638 | +| 3.0 GHz Intel Xeon Platinum 8124M | AVX2 | 449 | +| 3.1 GHz Intel Core i7 | AVX | 362 | +| 3.1 GHz Intel Core i7 | SSE | 299 | + +## asm2plan9s + +In order to be able to work more easily with AVX512/AVX2 instructions, a separate tool was developed to convert SIMD instructions into the corresponding BYTE sequence as accepted by Go assembly. See [asm2plan9s](https://github.com/minio/asm2plan9s) for more information. + +## Why and benefits + +One of the most performance sensitive parts of the [Minio](https://github.com/minio/minio) object storage server is related to SHA256 hash sums calculations. For instance during multi part uploads each part that is uploaded needs to be verified for data integrity by the server. + +Other applications that can benefit from enhanced SHA256 performance are deduplication in storage systems, intrusion detection, version control systems, integrity checking, etc. + +## ARM SHA Extensions + +The 64-bit ARMv8 core has introduced new instructions for SHA1 and SHA2 acceleration as part of the [Cryptography Extensions](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0501f/CHDFJBCJ.html). Below you can see a small excerpt highlighting one of the rounds as is done for the SHA256 calculation process (for full code see [sha256block_arm64.s](https://github.com/minio/sha256-simd/blob/master/sha256block_arm64.s)). + + ``` + sha256h q2, q3, v9.4s + sha256h2 q3, q4, v9.4s + sha256su0 v5.4s, v6.4s + rev32 v8.16b, v8.16b + add v9.4s, v7.4s, v18.4s + mov v4.16b, v2.16b + sha256h q2, q3, v10.4s + sha256h2 q3, q4, v10.4s + sha256su0 v6.4s, v7.4s + sha256su1 v5.4s, v7.4s, v8.4s + ``` + +### Detailed benchmarks + +Benchmarks generated on a 1.2 Ghz Quad-Core ARM Cortex A53 equipped [Pine64](https://www.pine64.com/). + +``` +minio@minio-arm:$ benchcmp golang.txt arm64.txt +benchmark golang arm64 speedup +BenchmarkHash8Bytes-4 0.68 MB/s 5.70 MB/s 8.38x +BenchmarkHash1K-4 5.65 MB/s 326.30 MB/s 57.75x +BenchmarkHash8K-4 6.00 MB/s 570.63 MB/s 95.11x +BenchmarkHash1M-4 6.05 MB/s 638.23 MB/s 105.49x +``` + +## License + +Released under the Apache License v2.0. You can find the complete text in the file LICENSE. + +## Contributing + +Contributions are welcome, please send PRs for any enhancements. diff --git a/vendor/github.com/minio/sha256-simd/appveyor.yml b/vendor/github.com/minio/sha256-simd/appveyor.yml new file mode 100644 index 00000000..a66bfa9f --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/appveyor.yml @@ -0,0 +1,32 @@ +# version format +version: "{build}" + +# Operating system (build VM template) +os: Windows Server 2012 R2 + +# Platform. +platform: x64 + +clone_folder: c:\gopath\src\github.com\minio\sha256-simd + +# environment variables +environment: + GOPATH: c:\gopath + GO15VENDOREXPERIMENT: 1 + +# scripts that run after cloning repository +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version + - go env + +# to run your custom scripts instead of automatic MSBuild +build_script: + - go test . + - go test -race . + +# to disable automatic tests +test: off + +# to disable deployment +deploy: off diff --git a/vendor/github.com/minio/sha256-simd/cpuid.go b/vendor/github.com/minio/sha256-simd/cpuid.go new file mode 100644 index 00000000..878ad463 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid.go @@ -0,0 +1,119 @@ +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +// True when SIMD instructions are available. +var avx512 bool +var avx2 bool +var avx bool +var sse bool +var sse2 bool +var sse3 bool +var ssse3 bool +var sse41 bool +var sse42 bool +var popcnt bool +var sha bool +var armSha = haveArmSha() + +func init() { + var _xsave bool + var _osxsave bool + var _avx bool + var _avx2 bool + var _avx512f bool + var _avx512dq bool + // var _avx512pf bool + // var _avx512er bool + // var _avx512cd bool + var _avx512bw bool + var _avx512vl bool + var _sseState bool + var _avxState bool + var _opmaskState bool + var _zmmHI256State bool + var _hi16ZmmState bool + + mfi, _, _, _ := cpuid(0) + + if mfi >= 1 { + _, _, c, d := cpuid(1) + + sse = (d & (1 << 25)) != 0 + sse2 = (d & (1 << 26)) != 0 + sse3 = (c & (1 << 0)) != 0 + ssse3 = (c & (1 << 9)) != 0 + sse41 = (c & (1 << 19)) != 0 + sse42 = (c & (1 << 20)) != 0 + popcnt = (c & (1 << 23)) != 0 + _xsave = (c & (1 << 26)) != 0 + _osxsave = (c & (1 << 27)) != 0 + _avx = (c & (1 << 28)) != 0 + } + + if mfi >= 7 { + _, b, _, _ := cpuid(7) + + _avx2 = (b & (1 << 5)) != 0 + _avx512f = (b & (1 << 16)) != 0 + _avx512dq = (b & (1 << 17)) != 0 + // _avx512pf = (b & (1 << 26)) != 0 + // _avx512er = (b & (1 << 27)) != 0 + // _avx512cd = (b & (1 << 28)) != 0 + _avx512bw = (b & (1 << 30)) != 0 + _avx512vl = (b & (1 << 31)) != 0 + sha = (b & (1 << 29)) != 0 + } + + // Stop here if XSAVE unsupported or not enabled + if !_xsave || !_osxsave { + return + } + + if _xsave && _osxsave { + a, _ := xgetbv(0) + + _sseState = (a & (1 << 1)) != 0 + _avxState = (a & (1 << 2)) != 0 + _opmaskState = (a & (1 << 5)) != 0 + _zmmHI256State = (a & (1 << 6)) != 0 + _hi16ZmmState = (a & (1 << 7)) != 0 + } else { + _sseState = true + } + + // Very unlikely that OS would enable XSAVE and then disable SSE + if !_sseState { + sse = false + sse2 = false + sse3 = false + ssse3 = false + sse41 = false + sse42 = false + } + + if _avxState { + avx = _avx + avx2 = _avx2 + } + + if _opmaskState && _zmmHI256State && _hi16ZmmState { + avx512 = (_avx512f && + _avx512dq && + _avx512bw && + _avx512vl) + } +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_386.go b/vendor/github.com/minio/sha256-simd/cpuid_386.go new file mode 100644 index 00000000..c9890be4 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_386.go @@ -0,0 +1,24 @@ +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +func xgetbv(index uint32) (eax, edx uint32) + +func haveArmSha() bool { + return false +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_386.s b/vendor/github.com/minio/sha256-simd/cpuid_386.s new file mode 100644 index 00000000..1511cd6f --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_386.s @@ -0,0 +1,53 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Klaus Post +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// +build 386,!gccgo + +// func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid(SB), 7, $0 + XORL CX, CX + MOVL op+0(FP), AX + CPUID + MOVL AX, eax+4(FP) + MOVL BX, ebx+8(FP) + MOVL CX, ecx+12(FP) + MOVL DX, edx+16(FP) + RET + +// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuidex(SB), 7, $0 + MOVL op+0(FP), AX + MOVL op2+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func xgetbv(index uint32) (eax, edx uint32) +TEXT ·xgetbv(SB), 7, $0 + MOVL index+0(FP), CX + BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV + MOVL AX, eax+4(FP) + MOVL DX, edx+8(FP) + RET diff --git a/vendor/github.com/minio/sha256-simd/cpuid_amd64.go b/vendor/github.com/minio/sha256-simd/cpuid_amd64.go new file mode 100644 index 00000000..c9890be4 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_amd64.go @@ -0,0 +1,24 @@ +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +func xgetbv(index uint32) (eax, edx uint32) + +func haveArmSha() bool { + return false +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_amd64.s b/vendor/github.com/minio/sha256-simd/cpuid_amd64.s new file mode 100644 index 00000000..b0f41474 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_amd64.s @@ -0,0 +1,53 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Klaus Post +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// +build amd64,!gccgo + +// func cpuid(op uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid(SB), 7, $0 + XORQ CX, CX + MOVL op+0(FP), AX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuidex(SB), 7, $0 + MOVL op+0(FP), AX + MOVL op2+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func xgetbv(index uint32) (eax, edx uint32) +TEXT ·xgetbv(SB), 7, $0 + MOVL index+0(FP), CX + BYTE $0x0f; BYTE $0x01; BYTE $0xd0 // XGETBV + MOVL AX, eax+8(FP) + MOVL DX, edx+12(FP) + RET diff --git a/vendor/github.com/minio/sha256-simd/cpuid_arm.go b/vendor/github.com/minio/sha256-simd/cpuid_arm.go new file mode 100644 index 00000000..351dff4b --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_arm.go @@ -0,0 +1,32 @@ +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func xgetbv(index uint32) (eax, edx uint32) { + return 0, 0 +} + +func haveArmSha() bool { + return false +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go b/vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go new file mode 100644 index 00000000..e739996d --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_linux_arm64.go @@ -0,0 +1,49 @@ +// +build arm64,linux + +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +import ( + "bytes" + "io/ioutil" +) + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func xgetbv(index uint32) (eax, edx uint32) { + return 0, 0 +} + +// File to check for cpu capabilities. +const procCPUInfo = "/proc/cpuinfo" + +// Feature to check for. +const sha256Feature = "sha2" + +func haveArmSha() bool { + cpuInfo, err := ioutil.ReadFile(procCPUInfo) + if err != nil { + return false + } + return bytes.Contains(cpuInfo, []byte(sha256Feature)) +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_other.go b/vendor/github.com/minio/sha256-simd/cpuid_other.go new file mode 100644 index 00000000..04f26ce8 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_other.go @@ -0,0 +1,34 @@ +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build ppc64 ppc64le mips mipsle mips64 mips64le s390x wasm + +package sha256 + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func xgetbv(index uint32) (eax, edx uint32) { + return 0, 0 +} + +func haveArmSha() bool { + return false +} diff --git a/vendor/github.com/minio/sha256-simd/cpuid_others_arm64.go b/vendor/github.com/minio/sha256-simd/cpuid_others_arm64.go new file mode 100644 index 00000000..0fb4022f --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/cpuid_others_arm64.go @@ -0,0 +1,35 @@ +// +build arm64,!linux + +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package sha256 + +func cpuid(op uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func cpuidex(op, op2 uint32) (eax, ebx, ecx, edx uint32) { + return 0, 0, 0, 0 +} + +func xgetbv(index uint32) (eax, edx uint32) { + return 0, 0 +} + +// Check for sha2 instruction flag. +func haveArmSha() bool { + return false +} diff --git a/vendor/github.com/minio/sha256-simd/go.mod b/vendor/github.com/minio/sha256-simd/go.mod new file mode 100644 index 00000000..b68fb0a0 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/go.mod @@ -0,0 +1 @@ +module github.com/minio/sha256-simd diff --git a/vendor/github.com/minio/sha256-simd/sha256.go b/vendor/github.com/minio/sha256-simd/sha256.go new file mode 100644 index 00000000..4e1f6d2f --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256.go @@ -0,0 +1,409 @@ +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +import ( + "crypto/sha256" + "encoding/binary" + "hash" + "runtime" +) + +// Size - The size of a SHA256 checksum in bytes. +const Size = 32 + +// BlockSize - The blocksize of SHA256 in bytes. +const BlockSize = 64 + +const ( + chunk = BlockSize + init0 = 0x6A09E667 + init1 = 0xBB67AE85 + init2 = 0x3C6EF372 + init3 = 0xA54FF53A + init4 = 0x510E527F + init5 = 0x9B05688C + init6 = 0x1F83D9AB + init7 = 0x5BE0CD19 +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + h [8]uint32 + x [chunk]byte + nx int + len uint64 +} + +// Reset digest back to default +func (d *digest) Reset() { + d.h[0] = init0 + d.h[1] = init1 + d.h[2] = init2 + d.h[3] = init3 + d.h[4] = init4 + d.h[5] = init5 + d.h[6] = init6 + d.h[7] = init7 + d.nx = 0 + d.len = 0 +} + +type blockfuncType int + +const ( + blockfuncGeneric blockfuncType = iota + blockfuncAvx512 blockfuncType = iota + blockfuncAvx2 blockfuncType = iota + blockfuncAvx blockfuncType = iota + blockfuncSsse blockfuncType = iota + blockfuncSha blockfuncType = iota + blockfuncArm blockfuncType = iota +) + +var blockfunc blockfuncType + +func init() { + is386bit := runtime.GOARCH == "386" + isARM := runtime.GOARCH == "arm" + switch { + case is386bit || isARM: + blockfunc = blockfuncGeneric + case sha && ssse3 && sse41: + blockfunc = blockfuncSha + case avx2: + blockfunc = blockfuncAvx2 + case avx: + blockfunc = blockfuncAvx + case ssse3: + blockfunc = blockfuncSsse + case armSha: + blockfunc = blockfuncArm + default: + blockfunc = blockfuncGeneric + } +} + +// New returns a new hash.Hash computing the SHA256 checksum. +func New() hash.Hash { + if blockfunc != blockfuncGeneric { + d := new(digest) + d.Reset() + return d + } + // Fallback to the standard golang implementation + // if no features were found. + return sha256.New() +} + +// Sum256 - single caller sha256 helper +func Sum256(data []byte) (result [Size]byte) { + var d digest + d.Reset() + d.Write(data) + result = d.checkSum() + return +} + +// Return size of checksum +func (d *digest) Size() int { return Size } + +// Return blocksize of checksum +func (d *digest) BlockSize() int { return BlockSize } + +// Write to digest +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + d.len += uint64(nn) + if d.nx > 0 { + n := copy(d.x[d.nx:], p) + d.nx += n + if d.nx == chunk { + block(d, d.x[:]) + d.nx = 0 + } + p = p[n:] + } + if len(p) >= chunk { + n := len(p) &^ (chunk - 1) + block(d, p[:n]) + p = p[n:] + } + if len(p) > 0 { + d.nx = copy(d.x[:], p) + } + return +} + +// Return sha256 sum in bytes +func (d *digest) Sum(in []byte) []byte { + // Make a copy of d0 so that caller can keep writing and summing. + d0 := *d + hash := d0.checkSum() + return append(in, hash[:]...) +} + +// Intermediate checksum function +func (d *digest) checkSum() (digest [Size]byte) { + n := d.nx + + var k [64]byte + copy(k[:], d.x[:n]) + + k[n] = 0x80 + + if n >= 56 { + block(d, k[:]) + + // clear block buffer - go compiles this to optimal 1x xorps + 4x movups + // unfortunately expressing this more succinctly results in much worse code + k[0] = 0 + k[1] = 0 + k[2] = 0 + k[3] = 0 + k[4] = 0 + k[5] = 0 + k[6] = 0 + k[7] = 0 + k[8] = 0 + k[9] = 0 + k[10] = 0 + k[11] = 0 + k[12] = 0 + k[13] = 0 + k[14] = 0 + k[15] = 0 + k[16] = 0 + k[17] = 0 + k[18] = 0 + k[19] = 0 + k[20] = 0 + k[21] = 0 + k[22] = 0 + k[23] = 0 + k[24] = 0 + k[25] = 0 + k[26] = 0 + k[27] = 0 + k[28] = 0 + k[29] = 0 + k[30] = 0 + k[31] = 0 + k[32] = 0 + k[33] = 0 + k[34] = 0 + k[35] = 0 + k[36] = 0 + k[37] = 0 + k[38] = 0 + k[39] = 0 + k[40] = 0 + k[41] = 0 + k[42] = 0 + k[43] = 0 + k[44] = 0 + k[45] = 0 + k[46] = 0 + k[47] = 0 + k[48] = 0 + k[49] = 0 + k[50] = 0 + k[51] = 0 + k[52] = 0 + k[53] = 0 + k[54] = 0 + k[55] = 0 + k[56] = 0 + k[57] = 0 + k[58] = 0 + k[59] = 0 + k[60] = 0 + k[61] = 0 + k[62] = 0 + k[63] = 0 + } + binary.BigEndian.PutUint64(k[56:64], uint64(d.len)<<3) + block(d, k[:]) + + { + const i = 0 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 1 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 2 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 3 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 4 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 5 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 6 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + { + const i = 7 + binary.BigEndian.PutUint32(digest[i*4:i*4+4], d.h[i]) + } + + return +} + +func block(dig *digest, p []byte) { + if blockfunc == blockfuncSha { + blockShaGo(dig, p) + } else if blockfunc == blockfuncAvx2 { + blockAvx2Go(dig, p) + } else if blockfunc == blockfuncAvx { + blockAvxGo(dig, p) + } else if blockfunc == blockfuncSsse { + blockSsseGo(dig, p) + } else if blockfunc == blockfuncArm { + blockArmGo(dig, p) + } else if blockfunc == blockfuncGeneric { + blockGeneric(dig, p) + } +} + +func blockGeneric(dig *digest, p []byte) { + var w [64]uint32 + h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] + for len(p) >= chunk { + // Can interlace the computation of w with the + // rounds below if needed for speed. + for i := 0; i < 16; i++ { + j := i * 4 + w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3]) + } + for i := 16; i < 64; i++ { + v1 := w[i-2] + t1 := (v1>>17 | v1<<(32-17)) ^ (v1>>19 | v1<<(32-19)) ^ (v1 >> 10) + v2 := w[i-15] + t2 := (v2>>7 | v2<<(32-7)) ^ (v2>>18 | v2<<(32-18)) ^ (v2 >> 3) + w[i] = t1 + w[i-7] + t2 + w[i-16] + } + + a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7 + + for i := 0; i < 64; i++ { + t1 := h + ((e>>6 | e<<(32-6)) ^ (e>>11 | e<<(32-11)) ^ (e>>25 | e<<(32-25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i] + + t2 := ((a>>2 | a<<(32-2)) ^ (a>>13 | a<<(32-13)) ^ (a>>22 | a<<(32-22))) + ((a & b) ^ (a & c) ^ (b & c)) + + h = g + g = f + f = e + e = d + t1 + d = c + c = b + b = a + a = t1 + t2 + } + + h0 += a + h1 += b + h2 += c + h3 += d + h4 += e + h5 += f + h6 += g + h7 += h + + p = p[chunk:] + } + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 +} + +var _K = []uint32{ + 0x428a2f98, + 0x71374491, + 0xb5c0fbcf, + 0xe9b5dba5, + 0x3956c25b, + 0x59f111f1, + 0x923f82a4, + 0xab1c5ed5, + 0xd807aa98, + 0x12835b01, + 0x243185be, + 0x550c7dc3, + 0x72be5d74, + 0x80deb1fe, + 0x9bdc06a7, + 0xc19bf174, + 0xe49b69c1, + 0xefbe4786, + 0x0fc19dc6, + 0x240ca1cc, + 0x2de92c6f, + 0x4a7484aa, + 0x5cb0a9dc, + 0x76f988da, + 0x983e5152, + 0xa831c66d, + 0xb00327c8, + 0xbf597fc7, + 0xc6e00bf3, + 0xd5a79147, + 0x06ca6351, + 0x14292967, + 0x27b70a85, + 0x2e1b2138, + 0x4d2c6dfc, + 0x53380d13, + 0x650a7354, + 0x766a0abb, + 0x81c2c92e, + 0x92722c85, + 0xa2bfe8a1, + 0xa81a664b, + 0xc24b8b70, + 0xc76c51a3, + 0xd192e819, + 0xd6990624, + 0xf40e3585, + 0x106aa070, + 0x19a4c116, + 0x1e376c08, + 0x2748774c, + 0x34b0bcb5, + 0x391c0cb3, + 0x4ed8aa4a, + 0x5b9cca4f, + 0x682e6ff3, + 0x748f82ee, + 0x78a5636f, + 0x84c87814, + 0x8cc70208, + 0x90befffa, + 0xa4506ceb, + 0xbef9a3f7, + 0xc67178f2, +} diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go b/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go new file mode 100644 index 00000000..43ee7a94 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.go @@ -0,0 +1,22 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +//go:noescape +func blockAvx2(h []uint32, message []uint8) diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s b/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s new file mode 100644 index 00000000..80b0b739 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx2_amd64.s @@ -0,0 +1,1449 @@ +//+build !noasm,!appengine + +// SHA256 implementation for AVX2 + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// This code is based on an Intel White-Paper: +// "Fast SHA-256 Implementations on Intel Architecture Processors" +// +// together with the reference implementation from the following authors: +// James Guilford +// Kirk Yap +// Tim Chen +// +// For Golang it has been converted to Plan 9 assembly with the help of +// github.com/minio/asm2plan9s to assemble Intel instructions to their Plan9 +// equivalents +// + +DATA K256<>+0x000(SB)/8, $0x71374491428a2f98 +DATA K256<>+0x008(SB)/8, $0xe9b5dba5b5c0fbcf +DATA K256<>+0x010(SB)/8, $0x71374491428a2f98 +DATA K256<>+0x018(SB)/8, $0xe9b5dba5b5c0fbcf +DATA K256<>+0x020(SB)/8, $0x59f111f13956c25b +DATA K256<>+0x028(SB)/8, $0xab1c5ed5923f82a4 +DATA K256<>+0x030(SB)/8, $0x59f111f13956c25b +DATA K256<>+0x038(SB)/8, $0xab1c5ed5923f82a4 +DATA K256<>+0x040(SB)/8, $0x12835b01d807aa98 +DATA K256<>+0x048(SB)/8, $0x550c7dc3243185be +DATA K256<>+0x050(SB)/8, $0x12835b01d807aa98 +DATA K256<>+0x058(SB)/8, $0x550c7dc3243185be +DATA K256<>+0x060(SB)/8, $0x80deb1fe72be5d74 +DATA K256<>+0x068(SB)/8, $0xc19bf1749bdc06a7 +DATA K256<>+0x070(SB)/8, $0x80deb1fe72be5d74 +DATA K256<>+0x078(SB)/8, $0xc19bf1749bdc06a7 +DATA K256<>+0x080(SB)/8, $0xefbe4786e49b69c1 +DATA K256<>+0x088(SB)/8, $0x240ca1cc0fc19dc6 +DATA K256<>+0x090(SB)/8, $0xefbe4786e49b69c1 +DATA K256<>+0x098(SB)/8, $0x240ca1cc0fc19dc6 +DATA K256<>+0x0a0(SB)/8, $0x4a7484aa2de92c6f +DATA K256<>+0x0a8(SB)/8, $0x76f988da5cb0a9dc +DATA K256<>+0x0b0(SB)/8, $0x4a7484aa2de92c6f +DATA K256<>+0x0b8(SB)/8, $0x76f988da5cb0a9dc +DATA K256<>+0x0c0(SB)/8, $0xa831c66d983e5152 +DATA K256<>+0x0c8(SB)/8, $0xbf597fc7b00327c8 +DATA K256<>+0x0d0(SB)/8, $0xa831c66d983e5152 +DATA K256<>+0x0d8(SB)/8, $0xbf597fc7b00327c8 +DATA K256<>+0x0e0(SB)/8, $0xd5a79147c6e00bf3 +DATA K256<>+0x0e8(SB)/8, $0x1429296706ca6351 +DATA K256<>+0x0f0(SB)/8, $0xd5a79147c6e00bf3 +DATA K256<>+0x0f8(SB)/8, $0x1429296706ca6351 +DATA K256<>+0x100(SB)/8, $0x2e1b213827b70a85 +DATA K256<>+0x108(SB)/8, $0x53380d134d2c6dfc +DATA K256<>+0x110(SB)/8, $0x2e1b213827b70a85 +DATA K256<>+0x118(SB)/8, $0x53380d134d2c6dfc +DATA K256<>+0x120(SB)/8, $0x766a0abb650a7354 +DATA K256<>+0x128(SB)/8, $0x92722c8581c2c92e +DATA K256<>+0x130(SB)/8, $0x766a0abb650a7354 +DATA K256<>+0x138(SB)/8, $0x92722c8581c2c92e +DATA K256<>+0x140(SB)/8, $0xa81a664ba2bfe8a1 +DATA K256<>+0x148(SB)/8, $0xc76c51a3c24b8b70 +DATA K256<>+0x150(SB)/8, $0xa81a664ba2bfe8a1 +DATA K256<>+0x158(SB)/8, $0xc76c51a3c24b8b70 +DATA K256<>+0x160(SB)/8, $0xd6990624d192e819 +DATA K256<>+0x168(SB)/8, $0x106aa070f40e3585 +DATA K256<>+0x170(SB)/8, $0xd6990624d192e819 +DATA K256<>+0x178(SB)/8, $0x106aa070f40e3585 +DATA K256<>+0x180(SB)/8, $0x1e376c0819a4c116 +DATA K256<>+0x188(SB)/8, $0x34b0bcb52748774c +DATA K256<>+0x190(SB)/8, $0x1e376c0819a4c116 +DATA K256<>+0x198(SB)/8, $0x34b0bcb52748774c +DATA K256<>+0x1a0(SB)/8, $0x4ed8aa4a391c0cb3 +DATA K256<>+0x1a8(SB)/8, $0x682e6ff35b9cca4f +DATA K256<>+0x1b0(SB)/8, $0x4ed8aa4a391c0cb3 +DATA K256<>+0x1b8(SB)/8, $0x682e6ff35b9cca4f +DATA K256<>+0x1c0(SB)/8, $0x78a5636f748f82ee +DATA K256<>+0x1c8(SB)/8, $0x8cc7020884c87814 +DATA K256<>+0x1d0(SB)/8, $0x78a5636f748f82ee +DATA K256<>+0x1d8(SB)/8, $0x8cc7020884c87814 +DATA K256<>+0x1e0(SB)/8, $0xa4506ceb90befffa +DATA K256<>+0x1e8(SB)/8, $0xc67178f2bef9a3f7 +DATA K256<>+0x1f0(SB)/8, $0xa4506ceb90befffa +DATA K256<>+0x1f8(SB)/8, $0xc67178f2bef9a3f7 + +DATA K256<>+0x200(SB)/8, $0x0405060700010203 +DATA K256<>+0x208(SB)/8, $0x0c0d0e0f08090a0b +DATA K256<>+0x210(SB)/8, $0x0405060700010203 +DATA K256<>+0x218(SB)/8, $0x0c0d0e0f08090a0b +DATA K256<>+0x220(SB)/8, $0x0b0a090803020100 +DATA K256<>+0x228(SB)/8, $0xffffffffffffffff +DATA K256<>+0x230(SB)/8, $0x0b0a090803020100 +DATA K256<>+0x238(SB)/8, $0xffffffffffffffff +DATA K256<>+0x240(SB)/8, $0xffffffffffffffff +DATA K256<>+0x248(SB)/8, $0x0b0a090803020100 +DATA K256<>+0x250(SB)/8, $0xffffffffffffffff +DATA K256<>+0x258(SB)/8, $0x0b0a090803020100 + +GLOBL K256<>(SB), 8, $608 + +// We need 0x220 stack space aligned on a 512 boundary, so for the +// worstcase-aligned SP we need twice this amount, being 1088 (=0x440) +// +// SP aligned end-aligned stacksize +// 100013d0 10001400 10001620 592 +// 100013d8 10001400 10001620 584 +// 100013e0 10001600 10001820 1088 +// 100013e8 10001600 10001820 1080 + +// func blockAvx2(h []uint32, message []uint8) +TEXT ·blockAvx2(SB),$1088-48 + + MOVQ h+0(FP), DI // DI: &h + MOVQ message_base+24(FP), SI // SI: &message + MOVQ message_len+32(FP), DX // len(message) + ADDQ SI, DX // end pointer of input + MOVQ SP, R11 // copy stack pointer + ADDQ $0x220, SP // sp += 0x220 + ANDQ $0xfffffffffffffe00, SP // align stack frame + ADDQ $0x1c0, SP + MOVQ DI, 0x40(SP) // save ctx + MOVQ SI, 0x48(SP) // save input + MOVQ DX, 0x50(SP) // save end pointer + MOVQ R11, 0x58(SP) // save copy of stack pointer + + WORD $0xf8c5; BYTE $0x77 // vzeroupper + ADDQ $0x40, SI // input++ + MOVL (DI), AX + MOVQ SI, R12 // borrow $T1 + MOVL 4(DI), BX + CMPQ SI, DX // $_end + MOVL 8(DI), CX + LONG $0xe4440f4c // cmove r12,rsp /* next block or random data */ + MOVL 12(DI), DX + MOVL 16(DI), R8 + MOVL 20(DI), R9 + MOVL 24(DI), R10 + MOVL 28(DI), R11 + + LEAQ K256<>(SB), BP + LONG $0x856f7dc5; LONG $0x00000220 // VMOVDQA YMM8, 0x220[rbp] /* vmovdqa ymm8,YMMWORD PTR [rip+0x220] */ + LONG $0x8d6f7dc5; LONG $0x00000240 // VMOVDQA YMM9, 0x240[rbp] /* vmovdqa ymm9,YMMWORD PTR [rip+0x240] */ + LONG $0x956f7dc5; LONG $0x00000200 // VMOVDQA YMM10, 0x200[rbp] /* vmovdqa ymm7,YMMWORD PTR [rip+0x200] */ + +loop0: + LONG $0x6f7dc1c4; BYTE $0xfa // VMOVDQA YMM7, YMM10 + + // Load first 16 dwords from two blocks + MOVOU -64(SI), X0 // vmovdqu xmm0,XMMWORD PTR [rsi-0x40] + MOVOU -48(SI), X1 // vmovdqu xmm1,XMMWORD PTR [rsi-0x30] + MOVOU -32(SI), X2 // vmovdqu xmm2,XMMWORD PTR [rsi-0x20] + MOVOU -16(SI), X3 // vmovdqu xmm3,XMMWORD PTR [rsi-0x10] + + // Byte swap data and transpose data into high/low + LONG $0x387dc3c4; WORD $0x2404; BYTE $0x01 // vinserti128 ymm0,ymm0,[r12],0x1 + LONG $0x3875c3c4; LONG $0x0110244c // vinserti128 ymm1,ymm1,0x10[r12],0x1 + LONG $0x007de2c4; BYTE $0xc7 // vpshufb ymm0,ymm0,ymm7 + LONG $0x386dc3c4; LONG $0x01202454 // vinserti128 ymm2,ymm2,0x20[r12],0x1 + LONG $0x0075e2c4; BYTE $0xcf // vpshufb ymm1,ymm1,ymm7 + LONG $0x3865c3c4; LONG $0x0130245c // vinserti128 ymm3,ymm3,0x30[r12],0x1 + + LEAQ K256<>(SB), BP + LONG $0x006de2c4; BYTE $0xd7 // vpshufb ymm2,ymm2,ymm7 + LONG $0x65fefdc5; BYTE $0x00 // vpaddd ymm4,ymm0,[rbp] + LONG $0x0065e2c4; BYTE $0xdf // vpshufb ymm3,ymm3,ymm7 + LONG $0x6dfef5c5; BYTE $0x20 // vpaddd ymm5,ymm1,0x20[rbp] + LONG $0x75feedc5; BYTE $0x40 // vpaddd ymm6,ymm2,0x40[rbp] + LONG $0x7dfee5c5; BYTE $0x60 // vpaddd ymm7,ymm3,0x60[rbp] + + LONG $0x247ffdc5; BYTE $0x24 // vmovdqa [rsp],ymm4 + XORQ R14, R14 + LONG $0x6c7ffdc5; WORD $0x2024 // vmovdqa [rsp+0x20],ymm5 + + ADDQ $-0x40, SP + MOVQ BX, DI + LONG $0x347ffdc5; BYTE $0x24 // vmovdqa [rsp],ymm6 + XORQ CX, DI // magic + LONG $0x7c7ffdc5; WORD $0x2024 // vmovdqa [rsp+0x20],ymm7 + MOVQ R9, R12 + ADDQ $0x80, BP + +loop1: + // Schedule 48 input dwords, by doing 3 rounds of 12 each + // Note: SIMD instructions are interleaved with the SHA calculations + ADDQ $-0x40, SP + LONG $0x0f75e3c4; WORD $0x04e0 // vpalignr ymm4,ymm1,ymm0,0x4 + + // ROUND(AX, BX, CX, DX, R8, R9, R10, R11, R12, R13, R14, R15, DI, SP, 0x80) + LONG $0x249c0344; LONG $0x00000080 // add r11d,[rsp+0x80] + WORD $0x2145; BYTE $0xc4 // and r12d,r8d + LONG $0xf07b43c4; WORD $0x19e8 // rorx r13d,r8d,0x19 + LONG $0x0f65e3c4; WORD $0x04fa // vpalignr ymm7,ymm3,ymm2,0x4 + LONG $0xf07b43c4; WORD $0x0bf8 // rorx r15d,r8d,0xb + LONG $0x30048d42 // lea eax,[rax+r14*1] + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + LONG $0xd472cdc5; BYTE $0x07 // vpsrld ymm6,ymm4,0x7 + LONG $0xf23842c4; BYTE $0xe2 // andn r12d,r8d,r10d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f0 // rorx r14d,r8d,0x6 + LONG $0xc7fefdc5 // vpaddd ymm0,ymm0,ymm7 + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xc7 // mov r15d,eax + LONG $0xd472c5c5; BYTE $0x03 // vpsrld ymm7,ymm4,0x3 + LONG $0xf07b63c4; WORD $0x16e0 // rorx r12d,eax,0x16 + LONG $0x2b1c8d47 // lea r11d,[r11+r13*1] + WORD $0x3141; BYTE $0xdf // xor r15d,ebx + LONG $0xf472d5c5; BYTE $0x0e // vpslld ymm5,ymm4,0xe + LONG $0xf07b63c4; WORD $0x0df0 // rorx r14d,eax,0xd + LONG $0xf07b63c4; WORD $0x02e8 // rorx r13d,eax,0x2 + LONG $0x1a148d42 // lea edx,[rdx+r11*1] + LONG $0xe6efc5c5 // vpxor ymm4,ymm7,ymm6 + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xdf31 // xor edi,ebx + LONG $0xfb70fdc5; BYTE $0xfa // vpshufd ymm7,ymm3,0xfa + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3b1c8d45 // lea r11d,[r11+rdi*1] + WORD $0x8945; BYTE $0xc4 // mov r12d,r8d + LONG $0xd672cdc5; BYTE $0x0b // vpsrld ymm6,ymm6,0xb + + // ROUND(R11, AX, BX, CX, DX, R8, R9, R10, R12, R13, R14, DI, R15, SP, 0x84) + LONG $0x24940344; LONG $0x00000084 // add r10d,[rsp+0x84] + WORD $0x2141; BYTE $0xd4 // and r12d,edx + LONG $0xf07b63c4; WORD $0x19ea // rorx r13d,edx,0x19 + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07be3c4; WORD $0x0bfa // rorx edi,edx,0xb + LONG $0x331c8d47 // lea r11d,[r11+r14*1] + LONG $0x22148d47 // lea r10d,[r10+r12*1] + LONG $0xf572d5c5; BYTE $0x0b // vpslld ymm5,ymm5,0xb + LONG $0xf26842c4; BYTE $0xe1 // andn r12d,edx,r9d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f2 // rorx r14d,edx,0x6 + LONG $0xe6efddc5 // vpxor ymm4,ymm4,ymm6 + LONG $0x22148d47 // lea r10d,[r10+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xdf // mov edi,r11d + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + LONG $0xf07b43c4; WORD $0x16e3 // rorx r12d,r11d,0x16 + LONG $0x2a148d47 // lea r10d,[r10+r13*1] + WORD $0xc731 // xor edi,eax + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07b43c4; WORD $0x0df3 // rorx r14d,r11d,0xd + LONG $0xf07b43c4; WORD $0x02eb // rorx r13d,r11d,0x2 + LONG $0x110c8d42 // lea ecx,[rcx+r10*1] + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xc7 // xor r15d,eax + LONG $0xc4fefdc5 // vpaddd ymm0,ymm0,ymm4 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3a148d47 // lea r10d,[r10+r15*1] + WORD $0x8941; BYTE $0xd4 // mov r12d,edx + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(R10, R11, AX, BX, CX, DX, R8, R9, R12, R13, R14, R15, DI, SP, 0x88) + LONG $0x248c0344; LONG $0x00000088 // add r9d,[rsp+0x88] + WORD $0x2141; BYTE $0xcc // and r12d,ecx + LONG $0xf07b63c4; WORD $0x19e9 // rorx r13d,ecx,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07b63c4; WORD $0x0bf9 // rorx r15d,ecx,0xb + LONG $0x32148d47 // lea r10d,[r10+r14*1] + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf27042c4; BYTE $0xe0 // andn r12d,ecx,r8d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f1 // rorx r14d,ecx,0x6 + LONG $0x004dc2c4; BYTE $0xf0 // vpshufb ymm6,ymm6,ymm8 + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xd7 // mov r15d,r10d + LONG $0xc6fefdc5 // vpaddd ymm0,ymm0,ymm6 + LONG $0xf07b43c4; WORD $0x16e2 // rorx r12d,r10d,0x16 + LONG $0x290c8d47 // lea r9d,[r9+r13*1] + WORD $0x3145; BYTE $0xdf // xor r15d,r11d + LONG $0xf870fdc5; BYTE $0x50 // vpshufd ymm7,ymm0,0x50 + LONG $0xf07b43c4; WORD $0x0df2 // rorx r14d,r10d,0xd + LONG $0xf07b43c4; WORD $0x02ea // rorx r13d,r10d,0x2 + LONG $0x0b1c8d42 // lea ebx,[rbx+r9*1] + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xdf // xor edi,r11d + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d45 // lea r9d,[r9+rdi*1] + WORD $0x8941; BYTE $0xcc // mov r12d,ecx + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(R9, R10, R11, AX, BX, CX, DX, R8, R12, R13, R14, DI, R15, SP, 0x8c) + LONG $0x24840344; LONG $0x0000008c // add r8d,[rsp+0x8c] + WORD $0x2141; BYTE $0xdc // and r12d,ebx + LONG $0xf07b63c4; WORD $0x19eb // rorx r13d,ebx,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07be3c4; WORD $0x0bfb // rorx edi,ebx,0xb + LONG $0x310c8d47 // lea r9d,[r9+r14*1] + LONG $0x20048d47 // lea r8d,[r8+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf26062c4; BYTE $0xe2 // andn r12d,ebx,edx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f3 // rorx r14d,ebx,0x6 + LONG $0x004dc2c4; BYTE $0xf1 // vpshufb ymm6,ymm6,ymm9 + LONG $0x20048d47 // lea r8d,[r8+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xcf // mov edi,r9d + LONG $0xc6fefdc5 // vpaddd ymm0,ymm0,ymm6 + LONG $0xf07b43c4; WORD $0x16e1 // rorx r12d,r9d,0x16 + LONG $0x28048d47 // lea r8d,[r8+r13*1] + WORD $0x3144; BYTE $0xd7 // xor edi,r10d + LONG $0x75fefdc5; BYTE $0x00 // vpaddd ymm6,ymm0,[rbp+0x0] + LONG $0xf07b43c4; WORD $0x0df1 // rorx r14d,r9d,0xd + LONG $0xf07b43c4; WORD $0x02e9 // rorx r13d,r9d,0x2 + LONG $0x00048d42 // lea eax,[rax+r8*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xd7 // xor r15d,r10d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d47 // lea r8d,[r8+r15*1] + WORD $0x8941; BYTE $0xdc // mov r12d,ebx + + LONG $0x347ffdc5; BYTE $0x24 // vmovdqa [rsp],ymm6 + LONG $0x0f6de3c4; WORD $0x04e1 // vpalignr ymm4,ymm2,ymm1,0x4 + + // ROUND(R8, R9, R10, R11, AX, BX, CX, DX, R12, R13, R14, R15, DI, SP, 0xa0) + LONG $0xa0249403; WORD $0x0000; BYTE $0x00 // add edx,[rsp+0xa0] + WORD $0x2141; BYTE $0xc4 // and r12d,eax + LONG $0xf07b63c4; WORD $0x19e8 // rorx r13d,eax,0x19 + LONG $0x0f7de3c4; WORD $0x04fb // vpalignr ymm7,ymm0,ymm3,0x4 + LONG $0xf07b63c4; WORD $0x0bf8 // rorx r15d,eax,0xb + LONG $0x30048d47 // lea r8d,[r8+r14*1] + LONG $0x22148d42 // lea edx,[rdx+r12*1] + LONG $0xd472cdc5; BYTE $0x07 // vpsrld ymm6,ymm4,0x7 + LONG $0xf27862c4; BYTE $0xe1 // andn r12d,eax,ecx + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f0 // rorx r14d,eax,0x6 + LONG $0xcffef5c5 // vpaddd ymm1,ymm1,ymm7 + LONG $0x22148d42 // lea edx,[rdx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xc7 // mov r15d,r8d + LONG $0xd472c5c5; BYTE $0x03 // vpsrld ymm7,ymm4,0x3 + LONG $0xf07b43c4; WORD $0x16e0 // rorx r12d,r8d,0x16 + LONG $0x2a148d42 // lea edx,[rdx+r13*1] + WORD $0x3145; BYTE $0xcf // xor r15d,r9d + LONG $0xf472d5c5; BYTE $0x0e // vpslld ymm5,ymm4,0xe + LONG $0xf07b43c4; WORD $0x0df0 // rorx r14d,r8d,0xd + LONG $0xf07b43c4; WORD $0x02e8 // rorx r13d,r8d,0x2 + LONG $0x131c8d45 // lea r11d,[r11+rdx*1] + LONG $0xe6efc5c5 // vpxor ymm4,ymm7,ymm6 + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xcf // xor edi,r9d + LONG $0xf870fdc5; BYTE $0xfa // vpshufd ymm7,ymm0,0xfa + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x148d; BYTE $0x3a // lea edx,[rdx+rdi*1] + WORD $0x8941; BYTE $0xc4 // mov r12d,eax + LONG $0xd672cdc5; BYTE $0x0b // vpsrld ymm6,ymm6,0xb + + // ROUND(DX, R8, R9, R10, R11, AX, BX, CX, R12, R13, R14, DI, R15, SP, 0xa4) + LONG $0xa4248c03; WORD $0x0000; BYTE $0x00 // add ecx,[rsp+0xa4] + WORD $0x2145; BYTE $0xdc // and r12d,r11d + LONG $0xf07b43c4; WORD $0x19eb // rorx r13d,r11d,0x19 + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07bc3c4; WORD $0x0bfb // rorx edi,r11d,0xb + LONG $0x32148d42 // lea edx,[rdx+r14*1] + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + LONG $0xf572d5c5; BYTE $0x0b // vpslld ymm5,ymm5,0xb + LONG $0xf22062c4; BYTE $0xe3 // andn r12d,r11d,ebx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f3 // rorx r14d,r11d,0x6 + LONG $0xe6efddc5 // vpxor ymm4,ymm4,ymm6 + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xd789 // mov edi,edx + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + LONG $0xf07b63c4; WORD $0x16e2 // rorx r12d,edx,0x16 + LONG $0x290c8d42 // lea ecx,[rcx+r13*1] + WORD $0x3144; BYTE $0xc7 // xor edi,r8d + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07b63c4; WORD $0x0df2 // rorx r14d,edx,0xd + LONG $0xf07b63c4; WORD $0x02ea // rorx r13d,edx,0x2 + LONG $0x0a148d45 // lea r10d,[r10+rcx*1] + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xc7 // xor r15d,r8d + LONG $0xccfef5c5 // vpaddd ymm1,ymm1,ymm4 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d42 // lea ecx,[rcx+r15*1] + WORD $0x8945; BYTE $0xdc // mov r12d,r11d + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(CX, DX, R8, R9, R10, R11, AX, BX, R12, R13, R14, R15, DI, SP, 0xa8) + LONG $0xa8249c03; WORD $0x0000; BYTE $0x00 // add ebx,[rsp+0xa8] + WORD $0x2145; BYTE $0xd4 // and r12d,r10d + LONG $0xf07b43c4; WORD $0x19ea // rorx r13d,r10d,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07b43c4; WORD $0x0bfa // rorx r15d,r10d,0xb + LONG $0x310c8d42 // lea ecx,[rcx+r14*1] + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf22862c4; BYTE $0xe0 // andn r12d,r10d,eax + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f2 // rorx r14d,r10d,0x6 + LONG $0x004dc2c4; BYTE $0xf0 // vpshufb ymm6,ymm6,ymm8 + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xcf // mov r15d,ecx + LONG $0xcefef5c5 // vpaddd ymm1,ymm1,ymm6 + LONG $0xf07b63c4; WORD $0x16e1 // rorx r12d,ecx,0x16 + LONG $0x2b1c8d42 // lea ebx,[rbx+r13*1] + WORD $0x3141; BYTE $0xd7 // xor r15d,edx + LONG $0xf970fdc5; BYTE $0x50 // vpshufd ymm7,ymm1,0x50 + LONG $0xf07b63c4; WORD $0x0df1 // rorx r14d,ecx,0xd + LONG $0xf07b63c4; WORD $0x02e9 // rorx r13d,ecx,0x2 + LONG $0x190c8d45 // lea r9d,[r9+rbx*1] + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xd731 // xor edi,edx + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x1c8d; BYTE $0x3b // lea ebx,[rbx+rdi*1] + WORD $0x8945; BYTE $0xd4 // mov r12d,r10d + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(BX, CX, DX, R8, R9, R10, R11, AX, R12, R13, R14, DI, R15, SP, 0xac) + LONG $0xac248403; WORD $0x0000; BYTE $0x00 // add eax,[rsp+0xac] + WORD $0x2145; BYTE $0xcc // and r12d,r9d + LONG $0xf07b43c4; WORD $0x19e9 // rorx r13d,r9d,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07bc3c4; WORD $0x0bf9 // rorx edi,r9d,0xb + LONG $0x331c8d42 // lea ebx,[rbx+r14*1] + LONG $0x20048d42 // lea eax,[rax+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf23042c4; BYTE $0xe3 // andn r12d,r9d,r11d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f1 // rorx r14d,r9d,0x6 + LONG $0x004dc2c4; BYTE $0xf1 // vpshufb ymm6,ymm6,ymm9 + LONG $0x20048d42 // lea eax,[rax+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xdf89 // mov edi,ebx + LONG $0xcefef5c5 // vpaddd ymm1,ymm1,ymm6 + LONG $0xf07b63c4; WORD $0x16e3 // rorx r12d,ebx,0x16 + LONG $0x28048d42 // lea eax,[rax+r13*1] + WORD $0xcf31 // xor edi,ecx + LONG $0x75fef5c5; BYTE $0x20 // vpaddd ymm6,ymm1,[rbp+0x20] + LONG $0xf07b63c4; WORD $0x0df3 // rorx r14d,ebx,0xd + LONG $0xf07b63c4; WORD $0x02eb // rorx r13d,ebx,0x2 + LONG $0x00048d45 // lea r8d,[r8+rax*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xcf // xor r15d,ecx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d42 // lea eax,[rax+r15*1] + WORD $0x8945; BYTE $0xcc // mov r12d,r9d + + LONG $0x747ffdc5; WORD $0x2024 // vmovdqa [rsp+0x20],ymm6 + + LONG $0x24648d48; BYTE $0xc0 // lea rsp,[rsp-0x40] + LONG $0x0f65e3c4; WORD $0x04e2 // vpalignr ymm4,ymm3,ymm2,0x4 + + // ROUND(AX, BX, CX, DX, R8, R9, R10, R11, R12, R13, R14, R15, DI, SP, 0x80) + LONG $0x249c0344; LONG $0x00000080 // add r11d,[rsp+0x80] + WORD $0x2145; BYTE $0xc4 // and r12d,r8d + LONG $0xf07b43c4; WORD $0x19e8 // rorx r13d,r8d,0x19 + LONG $0x0f75e3c4; WORD $0x04f8 // vpalignr ymm7,ymm1,ymm0,0x4 + LONG $0xf07b43c4; WORD $0x0bf8 // rorx r15d,r8d,0xb + LONG $0x30048d42 // lea eax,[rax+r14*1] + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + LONG $0xd472cdc5; BYTE $0x07 // vpsrld ymm6,ymm4,0x7 + LONG $0xf23842c4; BYTE $0xe2 // andn r12d,r8d,r10d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f0 // rorx r14d,r8d,0x6 + LONG $0xd7feedc5 // vpaddd ymm2,ymm2,ymm7 + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xc7 // mov r15d,eax + LONG $0xd472c5c5; BYTE $0x03 // vpsrld ymm7,ymm4,0x3 + LONG $0xf07b63c4; WORD $0x16e0 // rorx r12d,eax,0x16 + LONG $0x2b1c8d47 // lea r11d,[r11+r13*1] + WORD $0x3141; BYTE $0xdf // xor r15d,ebx + LONG $0xf472d5c5; BYTE $0x0e // vpslld ymm5,ymm4,0xe + LONG $0xf07b63c4; WORD $0x0df0 // rorx r14d,eax,0xd + LONG $0xf07b63c4; WORD $0x02e8 // rorx r13d,eax,0x2 + LONG $0x1a148d42 // lea edx,[rdx+r11*1] + LONG $0xe6efc5c5 // vpxor ymm4,ymm7,ymm6 + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xdf31 // xor edi,ebx + LONG $0xf970fdc5; BYTE $0xfa // vpshufd ymm7,ymm1,0xfa + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3b1c8d45 // lea r11d,[r11+rdi*1] + WORD $0x8945; BYTE $0xc4 // mov r12d,r8d + LONG $0xd672cdc5; BYTE $0x0b // vpsrld ymm6,ymm6,0xb + + // ROUND(R11, AX, BX, CX, DX, R8, R9, R10, R12, R13, R14, DI, R15, SP, 0x84) + LONG $0x24940344; LONG $0x00000084 // add r10d,[rsp+0x84] + WORD $0x2141; BYTE $0xd4 // and r12d,edx + LONG $0xf07b63c4; WORD $0x19ea // rorx r13d,edx,0x19 + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07be3c4; WORD $0x0bfa // rorx edi,edx,0xb + LONG $0x331c8d47 // lea r11d,[r11+r14*1] + LONG $0x22148d47 // lea r10d,[r10+r12*1] + LONG $0xf572d5c5; BYTE $0x0b // vpslld ymm5,ymm5,0xb + LONG $0xf26842c4; BYTE $0xe1 // andn r12d,edx,r9d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f2 // rorx r14d,edx,0x6 + LONG $0xe6efddc5 // vpxor ymm4,ymm4,ymm6 + LONG $0x22148d47 // lea r10d,[r10+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xdf // mov edi,r11d + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + LONG $0xf07b43c4; WORD $0x16e3 // rorx r12d,r11d,0x16 + LONG $0x2a148d47 // lea r10d,[r10+r13*1] + WORD $0xc731 // xor edi,eax + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07b43c4; WORD $0x0df3 // rorx r14d,r11d,0xd + LONG $0xf07b43c4; WORD $0x02eb // rorx r13d,r11d,0x2 + LONG $0x110c8d42 // lea ecx,[rcx+r10*1] + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xc7 // xor r15d,eax + LONG $0xd4feedc5 // vpaddd ymm2,ymm2,ymm4 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3a148d47 // lea r10d,[r10+r15*1] + WORD $0x8941; BYTE $0xd4 // mov r12d,edx + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(R10, R11, AX, BX, CX, DX, R8, R9, R12, R13, R14, R15, DI, SP, 0x88) + LONG $0x248c0344; LONG $0x00000088 // add r9d,[rsp+0x88] + WORD $0x2141; BYTE $0xcc // and r12d,ecx + LONG $0xf07b63c4; WORD $0x19e9 // rorx r13d,ecx,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07b63c4; WORD $0x0bf9 // rorx r15d,ecx,0xb + LONG $0x32148d47 // lea r10d,[r10+r14*1] + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf27042c4; BYTE $0xe0 // andn r12d,ecx,r8d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f1 // rorx r14d,ecx,0x6 + LONG $0x004dc2c4; BYTE $0xf0 // vpshufb ymm6,ymm6,ymm8 + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xd7 // mov r15d,r10d + LONG $0xd6feedc5 // vpaddd ymm2,ymm2,ymm6 + LONG $0xf07b43c4; WORD $0x16e2 // rorx r12d,r10d,0x16 + LONG $0x290c8d47 // lea r9d,[r9+r13*1] + WORD $0x3145; BYTE $0xdf // xor r15d,r11d + LONG $0xfa70fdc5; BYTE $0x50 // vpshufd ymm7,ymm2,0x50 + LONG $0xf07b43c4; WORD $0x0df2 // rorx r14d,r10d,0xd + LONG $0xf07b43c4; WORD $0x02ea // rorx r13d,r10d,0x2 + LONG $0x0b1c8d42 // lea ebx,[rbx+r9*1] + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xdf // xor edi,r11d + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d45 // lea r9d,[r9+rdi*1] + WORD $0x8941; BYTE $0xcc // mov r12d,ecx + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(R9, R10, R11, AX, BX, CX, DX, R8, R12, R13, R14, DI, R15, SP, 0x8c) + LONG $0x24840344; LONG $0x0000008c // add r8d,[rsp+0x8c] + WORD $0x2141; BYTE $0xdc // and r12d,ebx + LONG $0xf07b63c4; WORD $0x19eb // rorx r13d,ebx,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07be3c4; WORD $0x0bfb // rorx edi,ebx,0xb + LONG $0x310c8d47 // lea r9d,[r9+r14*1] + LONG $0x20048d47 // lea r8d,[r8+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf26062c4; BYTE $0xe2 // andn r12d,ebx,edx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f3 // rorx r14d,ebx,0x6 + LONG $0x004dc2c4; BYTE $0xf1 // vpshufb ymm6,ymm6,ymm9 + LONG $0x20048d47 // lea r8d,[r8+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xcf // mov edi,r9d + LONG $0xd6feedc5 // vpaddd ymm2,ymm2,ymm6 + LONG $0xf07b43c4; WORD $0x16e1 // rorx r12d,r9d,0x16 + LONG $0x28048d47 // lea r8d,[r8+r13*1] + WORD $0x3144; BYTE $0xd7 // xor edi,r10d + LONG $0x75feedc5; BYTE $0x40 // vpaddd ymm6,ymm2,[rbp+0x40] + LONG $0xf07b43c4; WORD $0x0df1 // rorx r14d,r9d,0xd + LONG $0xf07b43c4; WORD $0x02e9 // rorx r13d,r9d,0x2 + LONG $0x00048d42 // lea eax,[rax+r8*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xd7 // xor r15d,r10d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d47 // lea r8d,[r8+r15*1] + WORD $0x8941; BYTE $0xdc // mov r12d,ebx + + LONG $0x347ffdc5; BYTE $0x24 // vmovdqa [rsp],ymm6 + LONG $0x0f7de3c4; WORD $0x04e3 // vpalignr ymm4,ymm0,ymm3,0x4 + + // ROUND(R8, R9, R10, R11, AX, BX, CX, DX, R12, R13, R14, R15, DI, SP, 0xa0) + LONG $0xa0249403; WORD $0x0000; BYTE $0x00 // add edx,[rsp+0xa0] + WORD $0x2141; BYTE $0xc4 // and r12d,eax + LONG $0xf07b63c4; WORD $0x19e8 // rorx r13d,eax,0x19 + LONG $0x0f6de3c4; WORD $0x04f9 // vpalignr ymm7,ymm2,ymm1,0x4 + LONG $0xf07b63c4; WORD $0x0bf8 // rorx r15d,eax,0xb + LONG $0x30048d47 // lea r8d,[r8+r14*1] + LONG $0x22148d42 // lea edx,[rdx+r12*1] + LONG $0xd472cdc5; BYTE $0x07 // vpsrld ymm6,ymm4,0x7 + LONG $0xf27862c4; BYTE $0xe1 // andn r12d,eax,ecx + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f0 // rorx r14d,eax,0x6 + LONG $0xdffee5c5 // vpaddd ymm3,ymm3,ymm7 + LONG $0x22148d42 // lea edx,[rdx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xc7 // mov r15d,r8d + LONG $0xd472c5c5; BYTE $0x03 // vpsrld ymm7,ymm4,0x3 + LONG $0xf07b43c4; WORD $0x16e0 // rorx r12d,r8d,0x16 + LONG $0x2a148d42 // lea edx,[rdx+r13*1] + WORD $0x3145; BYTE $0xcf // xor r15d,r9d + LONG $0xf472d5c5; BYTE $0x0e // vpslld ymm5,ymm4,0xe + LONG $0xf07b43c4; WORD $0x0df0 // rorx r14d,r8d,0xd + LONG $0xf07b43c4; WORD $0x02e8 // rorx r13d,r8d,0x2 + LONG $0x131c8d45 // lea r11d,[r11+rdx*1] + LONG $0xe6efc5c5 // vpxor ymm4,ymm7,ymm6 + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xcf // xor edi,r9d + LONG $0xfa70fdc5; BYTE $0xfa // vpshufd ymm7,ymm2,0xfa + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x148d; BYTE $0x3a // lea edx,[rdx+rdi*1] + WORD $0x8941; BYTE $0xc4 // mov r12d,eax + LONG $0xd672cdc5; BYTE $0x0b // vpsrld ymm6,ymm6,0xb + + // ROUND(DX, R8, R9, R10, R11, AX, BX, CX, R12, R13, R14, DI, R15, SP, 0xa4) + LONG $0xa4248c03; WORD $0x0000; BYTE $0x00 // add ecx,[rsp+0xa4] + WORD $0x2145; BYTE $0xdc // and r12d,r11d + LONG $0xf07b43c4; WORD $0x19eb // rorx r13d,r11d,0x19 + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07bc3c4; WORD $0x0bfb // rorx edi,r11d,0xb + LONG $0x32148d42 // lea edx,[rdx+r14*1] + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + LONG $0xf572d5c5; BYTE $0x0b // vpslld ymm5,ymm5,0xb + LONG $0xf22062c4; BYTE $0xe3 // andn r12d,r11d,ebx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f3 // rorx r14d,r11d,0x6 + LONG $0xe6efddc5 // vpxor ymm4,ymm4,ymm6 + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xd789 // mov edi,edx + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + LONG $0xf07b63c4; WORD $0x16e2 // rorx r12d,edx,0x16 + LONG $0x290c8d42 // lea ecx,[rcx+r13*1] + WORD $0x3144; BYTE $0xc7 // xor edi,r8d + LONG $0xe5efddc5 // vpxor ymm4,ymm4,ymm5 + LONG $0xf07b63c4; WORD $0x0df2 // rorx r14d,edx,0xd + LONG $0xf07b63c4; WORD $0x02ea // rorx r13d,edx,0x2 + LONG $0x0a148d45 // lea r10d,[r10+rcx*1] + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xc7 // xor r15d,r8d + LONG $0xdcfee5c5 // vpaddd ymm3,ymm3,ymm4 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d42 // lea ecx,[rcx+r15*1] + WORD $0x8945; BYTE $0xdc // mov r12d,r11d + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(CX, DX, R8, R9, R10, R11, AX, BX, R12, R13, R14, R15, DI, SP, 0xa8) + LONG $0xa8249c03; WORD $0x0000; BYTE $0x00 // add ebx,[rsp+0xa8] + WORD $0x2145; BYTE $0xd4 // and r12d,r10d + LONG $0xf07b43c4; WORD $0x19ea // rorx r13d,r10d,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07b43c4; WORD $0x0bfa // rorx r15d,r10d,0xb + LONG $0x310c8d42 // lea ecx,[rcx+r14*1] + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf22862c4; BYTE $0xe0 // andn r12d,r10d,eax + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f2 // rorx r14d,r10d,0x6 + LONG $0x004dc2c4; BYTE $0xf0 // vpshufb ymm6,ymm6,ymm8 + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xcf // mov r15d,ecx + LONG $0xdefee5c5 // vpaddd ymm3,ymm3,ymm6 + LONG $0xf07b63c4; WORD $0x16e1 // rorx r12d,ecx,0x16 + LONG $0x2b1c8d42 // lea ebx,[rbx+r13*1] + WORD $0x3141; BYTE $0xd7 // xor r15d,edx + LONG $0xfb70fdc5; BYTE $0x50 // vpshufd ymm7,ymm3,0x50 + LONG $0xf07b63c4; WORD $0x0df1 // rorx r14d,ecx,0xd + LONG $0xf07b63c4; WORD $0x02e9 // rorx r13d,ecx,0x2 + LONG $0x190c8d45 // lea r9d,[r9+rbx*1] + LONG $0xd772cdc5; BYTE $0x0a // vpsrld ymm6,ymm7,0xa + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xd731 // xor edi,edx + LONG $0xd773c5c5; BYTE $0x11 // vpsrlq ymm7,ymm7,0x11 + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x1c8d; BYTE $0x3b // lea ebx,[rbx+rdi*1] + WORD $0x8945; BYTE $0xd4 // mov r12d,r10d + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + + // ROUND(BX, CX, DX, R8, R9, R10, R11, AX, R12, R13, R14, DI, R15, SP, 0xac) + LONG $0xac248403; WORD $0x0000; BYTE $0x00 // add eax,[rsp+0xac] + WORD $0x2145; BYTE $0xcc // and r12d,r9d + LONG $0xf07b43c4; WORD $0x19e9 // rorx r13d,r9d,0x19 + LONG $0xd773c5c5; BYTE $0x02 // vpsrlq ymm7,ymm7,0x2 + LONG $0xf07bc3c4; WORD $0x0bf9 // rorx edi,r9d,0xb + LONG $0x331c8d42 // lea ebx,[rbx+r14*1] + LONG $0x20048d42 // lea eax,[rax+r12*1] + LONG $0xf7efcdc5 // vpxor ymm6,ymm6,ymm7 + LONG $0xf23042c4; BYTE $0xe3 // andn r12d,r9d,r11d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f1 // rorx r14d,r9d,0x6 + LONG $0x004dc2c4; BYTE $0xf1 // vpshufb ymm6,ymm6,ymm9 + LONG $0x20048d42 // lea eax,[rax+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xdf89 // mov edi,ebx + LONG $0xdefee5c5 // vpaddd ymm3,ymm3,ymm6 + LONG $0xf07b63c4; WORD $0x16e3 // rorx r12d,ebx,0x16 + LONG $0x28048d42 // lea eax,[rax+r13*1] + WORD $0xcf31 // xor edi,ecx + LONG $0x75fee5c5; BYTE $0x60 // vpaddd ymm6,ymm3,[rbp+0x60] + LONG $0xf07b63c4; WORD $0x0df3 // rorx r14d,ebx,0xd + LONG $0xf07b63c4; WORD $0x02eb // rorx r13d,ebx,0x2 + LONG $0x00048d45 // lea r8d,[r8+rax*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xcf // xor r15d,ecx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d42 // lea eax,[rax+r15*1] + WORD $0x8945; BYTE $0xcc // mov r12d,r9d + + LONG $0x747ffdc5; WORD $0x2024 // vmovdqa [rsp+0x20],ymm6 + ADDQ $0x80, BP + + CMPB 0x3(BP), $0x0 + JNE loop1 + + // ROUND(AX, BX, CX, DX, R8, R9, R10, R11, R12, R13, R14, R15, DI, SP, 0x40) + LONG $0x245c0344; BYTE $0x40 // add r11d,[rsp+0x40] + WORD $0x2145; BYTE $0xc4 // and r12d,r8d + LONG $0xf07b43c4; WORD $0x19e8 // rorx r13d,r8d,0x19 + LONG $0xf07b43c4; WORD $0x0bf8 // rorx r15d,r8d,0xb + LONG $0x30048d42 // lea eax,[rax+r14*1] + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + LONG $0xf23842c4; BYTE $0xe2 // andn r12d,r8d,r10d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f0 // rorx r14d,r8d,0x6 + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xc7 // mov r15d,eax + LONG $0xf07b63c4; WORD $0x16e0 // rorx r12d,eax,0x16 + LONG $0x2b1c8d47 // lea r11d,[r11+r13*1] + WORD $0x3141; BYTE $0xdf // xor r15d,ebx + LONG $0xf07b63c4; WORD $0x0df0 // rorx r14d,eax,0xd + LONG $0xf07b63c4; WORD $0x02e8 // rorx r13d,eax,0x2 + LONG $0x1a148d42 // lea edx,[rdx+r11*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xdf31 // xor edi,ebx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3b1c8d45 // lea r11d,[r11+rdi*1] + WORD $0x8945; BYTE $0xc4 // mov r12d,r8d + + // ROUND(R11, AX, BX, CX, DX, R8, R9, R10, R12, R13, R14, DI, R15, SP, 0x44) + LONG $0x24540344; BYTE $0x44 // add r10d,[rsp+0x44] + WORD $0x2141; BYTE $0xd4 // and r12d,edx + LONG $0xf07b63c4; WORD $0x19ea // rorx r13d,edx,0x19 + LONG $0xf07be3c4; WORD $0x0bfa // rorx edi,edx,0xb + LONG $0x331c8d47 // lea r11d,[r11+r14*1] + LONG $0x22148d47 // lea r10d,[r10+r12*1] + LONG $0xf26842c4; BYTE $0xe1 // andn r12d,edx,r9d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f2 // rorx r14d,edx,0x6 + LONG $0x22148d47 // lea r10d,[r10+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xdf // mov edi,r11d + LONG $0xf07b43c4; WORD $0x16e3 // rorx r12d,r11d,0x16 + LONG $0x2a148d47 // lea r10d,[r10+r13*1] + WORD $0xc731 // xor edi,eax + LONG $0xf07b43c4; WORD $0x0df3 // rorx r14d,r11d,0xd + LONG $0xf07b43c4; WORD $0x02eb // rorx r13d,r11d,0x2 + LONG $0x110c8d42 // lea ecx,[rcx+r10*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xc7 // xor r15d,eax + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3a148d47 // lea r10d,[r10+r15*1] + WORD $0x8941; BYTE $0xd4 // mov r12d,edx + + // ROUND(R10, R11, AX, BX, CX, DX, R8, R9, R12, R13, R14, R15, DI, SP, 0x48) + LONG $0x244c0344; BYTE $0x48 // add r9d,[rsp+0x48] + WORD $0x2141; BYTE $0xcc // and r12d,ecx + LONG $0xf07b63c4; WORD $0x19e9 // rorx r13d,ecx,0x19 + LONG $0xf07b63c4; WORD $0x0bf9 // rorx r15d,ecx,0xb + LONG $0x32148d47 // lea r10d,[r10+r14*1] + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + LONG $0xf27042c4; BYTE $0xe0 // andn r12d,ecx,r8d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f1 // rorx r14d,ecx,0x6 + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xd7 // mov r15d,r10d + LONG $0xf07b43c4; WORD $0x16e2 // rorx r12d,r10d,0x16 + LONG $0x290c8d47 // lea r9d,[r9+r13*1] + WORD $0x3145; BYTE $0xdf // xor r15d,r11d + LONG $0xf07b43c4; WORD $0x0df2 // rorx r14d,r10d,0xd + LONG $0xf07b43c4; WORD $0x02ea // rorx r13d,r10d,0x2 + LONG $0x0b1c8d42 // lea ebx,[rbx+r9*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xdf // xor edi,r11d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d45 // lea r9d,[r9+rdi*1] + WORD $0x8941; BYTE $0xcc // mov r12d,ecx + + // ROUND(R9, R10, R11, AX, BX, CX, DX, R8, R12, R13, R14, DI, R15, SP, 0x4c) + LONG $0x24440344; BYTE $0x4c // add r8d,[rsp+0x4c] + WORD $0x2141; BYTE $0xdc // and r12d,ebx + LONG $0xf07b63c4; WORD $0x19eb // rorx r13d,ebx,0x19 + LONG $0xf07be3c4; WORD $0x0bfb // rorx edi,ebx,0xb + LONG $0x310c8d47 // lea r9d,[r9+r14*1] + LONG $0x20048d47 // lea r8d,[r8+r12*1] + LONG $0xf26062c4; BYTE $0xe2 // andn r12d,ebx,edx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f3 // rorx r14d,ebx,0x6 + LONG $0x20048d47 // lea r8d,[r8+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xcf // mov edi,r9d + LONG $0xf07b43c4; WORD $0x16e1 // rorx r12d,r9d,0x16 + LONG $0x28048d47 // lea r8d,[r8+r13*1] + WORD $0x3144; BYTE $0xd7 // xor edi,r10d + LONG $0xf07b43c4; WORD $0x0df1 // rorx r14d,r9d,0xd + LONG $0xf07b43c4; WORD $0x02e9 // rorx r13d,r9d,0x2 + LONG $0x00048d42 // lea eax,[rax+r8*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xd7 // xor r15d,r10d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d47 // lea r8d,[r8+r15*1] + WORD $0x8941; BYTE $0xdc // mov r12d,ebx + + // ROUND(R8, R9, R10, R11, AX, BX, CX, DX, R12, R13, R14, R15, DI, SP, 0x60) + LONG $0x60245403 // add edx,[rsp+0x60] + WORD $0x2141; BYTE $0xc4 // and r12d,eax + LONG $0xf07b63c4; WORD $0x19e8 // rorx r13d,eax,0x19 + LONG $0xf07b63c4; WORD $0x0bf8 // rorx r15d,eax,0xb + LONG $0x30048d47 // lea r8d,[r8+r14*1] + LONG $0x22148d42 // lea edx,[rdx+r12*1] + LONG $0xf27862c4; BYTE $0xe1 // andn r12d,eax,ecx + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f0 // rorx r14d,eax,0x6 + LONG $0x22148d42 // lea edx,[rdx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xc7 // mov r15d,r8d + LONG $0xf07b43c4; WORD $0x16e0 // rorx r12d,r8d,0x16 + LONG $0x2a148d42 // lea edx,[rdx+r13*1] + WORD $0x3145; BYTE $0xcf // xor r15d,r9d + LONG $0xf07b43c4; WORD $0x0df0 // rorx r14d,r8d,0xd + LONG $0xf07b43c4; WORD $0x02e8 // rorx r13d,r8d,0x2 + LONG $0x131c8d45 // lea r11d,[r11+rdx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xcf // xor edi,r9d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x148d; BYTE $0x3a // lea edx,[rdx+rdi*1] + WORD $0x8941; BYTE $0xc4 // mov r12d,eax + + // ROUND(DX, R8, R9, R10, R11, AX, BX, CX, R12, R13, R14, DI, R15, SP, 0x64) + LONG $0x64244c03 // add ecx,[rsp+0x64] + WORD $0x2145; BYTE $0xdc // and r12d,r11d + LONG $0xf07b43c4; WORD $0x19eb // rorx r13d,r11d,0x19 + LONG $0xf07bc3c4; WORD $0x0bfb // rorx edi,r11d,0xb + LONG $0x32148d42 // lea edx,[rdx+r14*1] + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + LONG $0xf22062c4; BYTE $0xe3 // andn r12d,r11d,ebx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f3 // rorx r14d,r11d,0x6 + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xd789 // mov edi,edx + LONG $0xf07b63c4; WORD $0x16e2 // rorx r12d,edx,0x16 + LONG $0x290c8d42 // lea ecx,[rcx+r13*1] + WORD $0x3144; BYTE $0xc7 // xor edi,r8d + LONG $0xf07b63c4; WORD $0x0df2 // rorx r14d,edx,0xd + LONG $0xf07b63c4; WORD $0x02ea // rorx r13d,edx,0x2 + LONG $0x0a148d45 // lea r10d,[r10+rcx*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xc7 // xor r15d,r8d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d42 // lea ecx,[rcx+r15*1] + WORD $0x8945; BYTE $0xdc // mov r12d,r11d + + // ROUND(CX, DX, R8, R9, R10, R11, AX, BX, R12, R13, R14, R15, DI, SP, 0x68) + LONG $0x68245c03 // add ebx,[rsp+0x68] + WORD $0x2145; BYTE $0xd4 // and r12d,r10d + LONG $0xf07b43c4; WORD $0x19ea // rorx r13d,r10d,0x19 + LONG $0xf07b43c4; WORD $0x0bfa // rorx r15d,r10d,0xb + LONG $0x310c8d42 // lea ecx,[rcx+r14*1] + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + LONG $0xf22862c4; BYTE $0xe0 // andn r12d,r10d,eax + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f2 // rorx r14d,r10d,0x6 + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xcf // mov r15d,ecx + LONG $0xf07b63c4; WORD $0x16e1 // rorx r12d,ecx,0x16 + LONG $0x2b1c8d42 // lea ebx,[rbx+r13*1] + WORD $0x3141; BYTE $0xd7 // xor r15d,edx + LONG $0xf07b63c4; WORD $0x0df1 // rorx r14d,ecx,0xd + LONG $0xf07b63c4; WORD $0x02e9 // rorx r13d,ecx,0x2 + LONG $0x190c8d45 // lea r9d,[r9+rbx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xd731 // xor edi,edx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x1c8d; BYTE $0x3b // lea ebx,[rbx+rdi*1] + WORD $0x8945; BYTE $0xd4 // mov r12d,r10d + + // ROUND(BX, CX, DX, R8, R9, R10, R11, AX, R12, R13, R14, DI, R15, SP, 0x6c) + LONG $0x6c244403 // add eax,[rsp+0x6c] + WORD $0x2145; BYTE $0xcc // and r12d,r9d + LONG $0xf07b43c4; WORD $0x19e9 // rorx r13d,r9d,0x19 + LONG $0xf07bc3c4; WORD $0x0bf9 // rorx edi,r9d,0xb + LONG $0x331c8d42 // lea ebx,[rbx+r14*1] + LONG $0x20048d42 // lea eax,[rax+r12*1] + LONG $0xf23042c4; BYTE $0xe3 // andn r12d,r9d,r11d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f1 // rorx r14d,r9d,0x6 + LONG $0x20048d42 // lea eax,[rax+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xdf89 // mov edi,ebx + LONG $0xf07b63c4; WORD $0x16e3 // rorx r12d,ebx,0x16 + LONG $0x28048d42 // lea eax,[rax+r13*1] + WORD $0xcf31 // xor edi,ecx + LONG $0xf07b63c4; WORD $0x0df3 // rorx r14d,ebx,0xd + LONG $0xf07b63c4; WORD $0x02eb // rorx r13d,ebx,0x2 + LONG $0x00048d45 // lea r8d,[r8+rax*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xcf // xor r15d,ecx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d42 // lea eax,[rax+r15*1] + WORD $0x8945; BYTE $0xcc // mov r12d,r9d + + // ROUND(AX, BX, CX, DX, R8, R9, R10, R11, R12, R13, R14, R15, DI, SP, 0x00) + LONG $0x241c0344 // add r11d,[rsp] + WORD $0x2145; BYTE $0xc4 // and r12d,r8d + LONG $0xf07b43c4; WORD $0x19e8 // rorx r13d,r8d,0x19 + LONG $0xf07b43c4; WORD $0x0bf8 // rorx r15d,r8d,0xb + LONG $0x30048d42 // lea eax,[rax+r14*1] + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + LONG $0xf23842c4; BYTE $0xe2 // andn r12d,r8d,r10d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f0 // rorx r14d,r8d,0x6 + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xc7 // mov r15d,eax + LONG $0xf07b63c4; WORD $0x16e0 // rorx r12d,eax,0x16 + LONG $0x2b1c8d47 // lea r11d,[r11+r13*1] + WORD $0x3141; BYTE $0xdf // xor r15d,ebx + LONG $0xf07b63c4; WORD $0x0df0 // rorx r14d,eax,0xd + LONG $0xf07b63c4; WORD $0x02e8 // rorx r13d,eax,0x2 + LONG $0x1a148d42 // lea edx,[rdx+r11*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xdf31 // xor edi,ebx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3b1c8d45 // lea r11d,[r11+rdi*1] + WORD $0x8945; BYTE $0xc4 // mov r12d,r8d + + // ROUND(R11, AX, BX, CX, DX, R8, R9, R10, R12, R13, R14, DI, R15, SP, 0x04) + LONG $0x24540344; BYTE $0x04 // add r10d,[rsp+0x4] + WORD $0x2141; BYTE $0xd4 // and r12d,edx + LONG $0xf07b63c4; WORD $0x19ea // rorx r13d,edx,0x19 + LONG $0xf07be3c4; WORD $0x0bfa // rorx edi,edx,0xb + LONG $0x331c8d47 // lea r11d,[r11+r14*1] + LONG $0x22148d47 // lea r10d,[r10+r12*1] + LONG $0xf26842c4; BYTE $0xe1 // andn r12d,edx,r9d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f2 // rorx r14d,edx,0x6 + LONG $0x22148d47 // lea r10d,[r10+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xdf // mov edi,r11d + LONG $0xf07b43c4; WORD $0x16e3 // rorx r12d,r11d,0x16 + LONG $0x2a148d47 // lea r10d,[r10+r13*1] + WORD $0xc731 // xor edi,eax + LONG $0xf07b43c4; WORD $0x0df3 // rorx r14d,r11d,0xd + LONG $0xf07b43c4; WORD $0x02eb // rorx r13d,r11d,0x2 + LONG $0x110c8d42 // lea ecx,[rcx+r10*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xc7 // xor r15d,eax + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3a148d47 // lea r10d,[r10+r15*1] + WORD $0x8941; BYTE $0xd4 // mov r12d,edx + + // ROUND(R10, R11, AX, BX, CX, DX, R8, R9, R12, R13, R14, R15, DI, SP, 0x08) + LONG $0x244c0344; BYTE $0x08 // add r9d,[rsp+0x8] + WORD $0x2141; BYTE $0xcc // and r12d,ecx + LONG $0xf07b63c4; WORD $0x19e9 // rorx r13d,ecx,0x19 + LONG $0xf07b63c4; WORD $0x0bf9 // rorx r15d,ecx,0xb + LONG $0x32148d47 // lea r10d,[r10+r14*1] + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + LONG $0xf27042c4; BYTE $0xe0 // andn r12d,ecx,r8d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f1 // rorx r14d,ecx,0x6 + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xd7 // mov r15d,r10d + LONG $0xf07b43c4; WORD $0x16e2 // rorx r12d,r10d,0x16 + LONG $0x290c8d47 // lea r9d,[r9+r13*1] + WORD $0x3145; BYTE $0xdf // xor r15d,r11d + LONG $0xf07b43c4; WORD $0x0df2 // rorx r14d,r10d,0xd + LONG $0xf07b43c4; WORD $0x02ea // rorx r13d,r10d,0x2 + LONG $0x0b1c8d42 // lea ebx,[rbx+r9*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xdf // xor edi,r11d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d45 // lea r9d,[r9+rdi*1] + WORD $0x8941; BYTE $0xcc // mov r12d,ecx + + // ROUND(R9, R10, R11, AX, BX, CX, DX, R8, R12, R13, R14, DI, R15, SP, 0x0c) + LONG $0x24440344; BYTE $0x0c // add r8d,[rsp+0xc] + WORD $0x2141; BYTE $0xdc // and r12d,ebx + LONG $0xf07b63c4; WORD $0x19eb // rorx r13d,ebx,0x19 + LONG $0xf07be3c4; WORD $0x0bfb // rorx edi,ebx,0xb + LONG $0x310c8d47 // lea r9d,[r9+r14*1] + LONG $0x20048d47 // lea r8d,[r8+r12*1] + LONG $0xf26062c4; BYTE $0xe2 // andn r12d,ebx,edx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f3 // rorx r14d,ebx,0x6 + LONG $0x20048d47 // lea r8d,[r8+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xcf // mov edi,r9d + LONG $0xf07b43c4; WORD $0x16e1 // rorx r12d,r9d,0x16 + LONG $0x28048d47 // lea r8d,[r8+r13*1] + WORD $0x3144; BYTE $0xd7 // xor edi,r10d + LONG $0xf07b43c4; WORD $0x0df1 // rorx r14d,r9d,0xd + LONG $0xf07b43c4; WORD $0x02e9 // rorx r13d,r9d,0x2 + LONG $0x00048d42 // lea eax,[rax+r8*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xd7 // xor r15d,r10d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d47 // lea r8d,[r8+r15*1] + WORD $0x8941; BYTE $0xdc // mov r12d,ebx + + // ROUND(R8, R9, R10, R11, AX, BX, CX, DX, R12, R13, R14, R15, DI, SP, 0x20) + LONG $0x20245403 // add edx,[rsp+0x20] + WORD $0x2141; BYTE $0xc4 // and r12d,eax + LONG $0xf07b63c4; WORD $0x19e8 // rorx r13d,eax,0x19 + LONG $0xf07b63c4; WORD $0x0bf8 // rorx r15d,eax,0xb + LONG $0x30048d47 // lea r8d,[r8+r14*1] + LONG $0x22148d42 // lea edx,[rdx+r12*1] + LONG $0xf27862c4; BYTE $0xe1 // andn r12d,eax,ecx + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f0 // rorx r14d,eax,0x6 + LONG $0x22148d42 // lea edx,[rdx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xc7 // mov r15d,r8d + LONG $0xf07b43c4; WORD $0x16e0 // rorx r12d,r8d,0x16 + LONG $0x2a148d42 // lea edx,[rdx+r13*1] + WORD $0x3145; BYTE $0xcf // xor r15d,r9d + LONG $0xf07b43c4; WORD $0x0df0 // rorx r14d,r8d,0xd + LONG $0xf07b43c4; WORD $0x02e8 // rorx r13d,r8d,0x2 + LONG $0x131c8d45 // lea r11d,[r11+rdx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xcf // xor edi,r9d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x148d; BYTE $0x3a // lea edx,[rdx+rdi*1] + WORD $0x8941; BYTE $0xc4 // mov r12d,eax + + // ROUND(DX, R8, R9, R10, R11, AX, BX, CX, R12, R13, R14, DI, R15, SP, 0x24) + LONG $0x24244c03 // add ecx,[rsp+0x24] + WORD $0x2145; BYTE $0xdc // and r12d,r11d + LONG $0xf07b43c4; WORD $0x19eb // rorx r13d,r11d,0x19 + LONG $0xf07bc3c4; WORD $0x0bfb // rorx edi,r11d,0xb + LONG $0x32148d42 // lea edx,[rdx+r14*1] + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + LONG $0xf22062c4; BYTE $0xe3 // andn r12d,r11d,ebx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f3 // rorx r14d,r11d,0x6 + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xd789 // mov edi,edx + LONG $0xf07b63c4; WORD $0x16e2 // rorx r12d,edx,0x16 + LONG $0x290c8d42 // lea ecx,[rcx+r13*1] + WORD $0x3144; BYTE $0xc7 // xor edi,r8d + LONG $0xf07b63c4; WORD $0x0df2 // rorx r14d,edx,0xd + LONG $0xf07b63c4; WORD $0x02ea // rorx r13d,edx,0x2 + LONG $0x0a148d45 // lea r10d,[r10+rcx*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xc7 // xor r15d,r8d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d42 // lea ecx,[rcx+r15*1] + WORD $0x8945; BYTE $0xdc // mov r12d,r11d + + // ROUND(CX, DX, R8, R9, R10, R11, AX, BX, R12, R13, R14, R15, DI, SP, 0x28) + LONG $0x28245c03 // add ebx,[rsp+0x28] + WORD $0x2145; BYTE $0xd4 // and r12d,r10d + LONG $0xf07b43c4; WORD $0x19ea // rorx r13d,r10d,0x19 + LONG $0xf07b43c4; WORD $0x0bfa // rorx r15d,r10d,0xb + LONG $0x310c8d42 // lea ecx,[rcx+r14*1] + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + LONG $0xf22862c4; BYTE $0xe0 // andn r12d,r10d,eax + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f2 // rorx r14d,r10d,0x6 + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xcf // mov r15d,ecx + LONG $0xf07b63c4; WORD $0x16e1 // rorx r12d,ecx,0x16 + LONG $0x2b1c8d42 // lea ebx,[rbx+r13*1] + WORD $0x3141; BYTE $0xd7 // xor r15d,edx + LONG $0xf07b63c4; WORD $0x0df1 // rorx r14d,ecx,0xd + LONG $0xf07b63c4; WORD $0x02e9 // rorx r13d,ecx,0x2 + LONG $0x190c8d45 // lea r9d,[r9+rbx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xd731 // xor edi,edx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x1c8d; BYTE $0x3b // lea ebx,[rbx+rdi*1] + WORD $0x8945; BYTE $0xd4 // mov r12d,r10d + + // ROUND(BX, CX, DX, R8, R9, R10, R11, AX, R12, R13, R14, DI, R15, SP, 0x2c) + LONG $0x2c244403 // add eax,[rsp+0x2c] + WORD $0x2145; BYTE $0xcc // and r12d,r9d + LONG $0xf07b43c4; WORD $0x19e9 // rorx r13d,r9d,0x19 + LONG $0xf07bc3c4; WORD $0x0bf9 // rorx edi,r9d,0xb + LONG $0x331c8d42 // lea ebx,[rbx+r14*1] + LONG $0x20048d42 // lea eax,[rax+r12*1] + LONG $0xf23042c4; BYTE $0xe3 // andn r12d,r9d,r11d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f1 // rorx r14d,r9d,0x6 + LONG $0x20048d42 // lea eax,[rax+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xdf89 // mov edi,ebx + LONG $0xf07b63c4; WORD $0x16e3 // rorx r12d,ebx,0x16 + LONG $0x28048d42 // lea eax,[rax+r13*1] + WORD $0xcf31 // xor edi,ecx + LONG $0xf07b63c4; WORD $0x0df3 // rorx r14d,ebx,0xd + LONG $0xf07b63c4; WORD $0x02eb // rorx r13d,ebx,0x2 + LONG $0x00048d45 // lea r8d,[r8+rax*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xcf // xor r15d,ecx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d42 // lea eax,[rax+r15*1] + WORD $0x8945; BYTE $0xcc // mov r12d,r9d + + MOVQ 0x200(SP), DI // $_ctx + ADDQ R14, AX + + LEAQ 0x1c0(SP), BP + + ADDL (DI), AX + ADDL 4(DI), BX + ADDL 8(DI), CX + ADDL 12(DI), DX + ADDL 16(DI), R8 + ADDL 20(DI), R9 + ADDL 24(DI), R10 + ADDL 28(DI), R11 + + MOVL AX, (DI) + MOVL BX, 4(DI) + MOVL CX, 8(DI) + MOVL DX, 12(DI) + MOVL R8, 16(DI) + MOVL R9, 20(DI) + MOVL R10, 24(DI) + MOVL R11, 28(DI) + + CMPQ SI, 0x50(BP) // $_end + JE done + + XORQ R14, R14 + MOVQ BX, DI + XORQ CX, DI // magic + MOVQ R9, R12 + +loop2: + // ROUND(AX, BX, CX, DX, R8, R9, R10, R11, R12, R13, R14, R15, DI, BP, 0x10) + LONG $0x105d0344 // add r11d,[rbp+0x10] + WORD $0x2145; BYTE $0xc4 // and r12d,r8d + LONG $0xf07b43c4; WORD $0x19e8 // rorx r13d,r8d,0x19 + LONG $0xf07b43c4; WORD $0x0bf8 // rorx r15d,r8d,0xb + LONG $0x30048d42 // lea eax,[rax+r14*1] + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + LONG $0xf23842c4; BYTE $0xe2 // andn r12d,r8d,r10d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f0 // rorx r14d,r8d,0x6 + LONG $0x231c8d47 // lea r11d,[r11+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xc7 // mov r15d,eax + LONG $0xf07b63c4; WORD $0x16e0 // rorx r12d,eax,0x16 + LONG $0x2b1c8d47 // lea r11d,[r11+r13*1] + WORD $0x3141; BYTE $0xdf // xor r15d,ebx + LONG $0xf07b63c4; WORD $0x0df0 // rorx r14d,eax,0xd + LONG $0xf07b63c4; WORD $0x02e8 // rorx r13d,eax,0x2 + LONG $0x1a148d42 // lea edx,[rdx+r11*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xdf31 // xor edi,ebx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3b1c8d45 // lea r11d,[r11+rdi*1] + WORD $0x8945; BYTE $0xc4 // mov r12d,r8d + + // ROUND(R11, AX, BX, CX, DX, R8, R9, R10, R12, R13, R14, DI, R15, BP, 0x14) + LONG $0x14550344 // add r10d,[rbp+0x14] + WORD $0x2141; BYTE $0xd4 // and r12d,edx + LONG $0xf07b63c4; WORD $0x19ea // rorx r13d,edx,0x19 + LONG $0xf07be3c4; WORD $0x0bfa // rorx edi,edx,0xb + LONG $0x331c8d47 // lea r11d,[r11+r14*1] + LONG $0x22148d47 // lea r10d,[r10+r12*1] + LONG $0xf26842c4; BYTE $0xe1 // andn r12d,edx,r9d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f2 // rorx r14d,edx,0x6 + LONG $0x22148d47 // lea r10d,[r10+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xdf // mov edi,r11d + LONG $0xf07b43c4; WORD $0x16e3 // rorx r12d,r11d,0x16 + LONG $0x2a148d47 // lea r10d,[r10+r13*1] + WORD $0xc731 // xor edi,eax + LONG $0xf07b43c4; WORD $0x0df3 // rorx r14d,r11d,0xd + LONG $0xf07b43c4; WORD $0x02eb // rorx r13d,r11d,0x2 + LONG $0x110c8d42 // lea ecx,[rcx+r10*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xc7 // xor r15d,eax + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x3a148d47 // lea r10d,[r10+r15*1] + WORD $0x8941; BYTE $0xd4 // mov r12d,edx + + // ROUND(R10, R11, AX, BX, CX, DX, R8, R9, R12, R13, R14, R15, DI, BP, 0x18) + LONG $0x184d0344 // add r9d,[rbp+0x18] + WORD $0x2141; BYTE $0xcc // and r12d,ecx + LONG $0xf07b63c4; WORD $0x19e9 // rorx r13d,ecx,0x19 + LONG $0xf07b63c4; WORD $0x0bf9 // rorx r15d,ecx,0xb + LONG $0x32148d47 // lea r10d,[r10+r14*1] + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + LONG $0xf27042c4; BYTE $0xe0 // andn r12d,ecx,r8d + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f1 // rorx r14d,ecx,0x6 + LONG $0x210c8d47 // lea r9d,[r9+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xd7 // mov r15d,r10d + LONG $0xf07b43c4; WORD $0x16e2 // rorx r12d,r10d,0x16 + LONG $0x290c8d47 // lea r9d,[r9+r13*1] + WORD $0x3145; BYTE $0xdf // xor r15d,r11d + LONG $0xf07b43c4; WORD $0x0df2 // rorx r14d,r10d,0xd + LONG $0xf07b43c4; WORD $0x02ea // rorx r13d,r10d,0x2 + LONG $0x0b1c8d42 // lea ebx,[rbx+r9*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xdf // xor edi,r11d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d45 // lea r9d,[r9+rdi*1] + WORD $0x8941; BYTE $0xcc // mov r12d,ecx + + // ROUND(R9, R10, R11, AX, BX, CX, DX, R8, R12, R13, R14, DI, R15, BP, 0x1c) + LONG $0x1c450344 // add r8d,[rbp+0x1c] + WORD $0x2141; BYTE $0xdc // and r12d,ebx + LONG $0xf07b63c4; WORD $0x19eb // rorx r13d,ebx,0x19 + LONG $0xf07be3c4; WORD $0x0bfb // rorx edi,ebx,0xb + LONG $0x310c8d47 // lea r9d,[r9+r14*1] + LONG $0x20048d47 // lea r8d,[r8+r12*1] + LONG $0xf26062c4; BYTE $0xe2 // andn r12d,ebx,edx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b63c4; WORD $0x06f3 // rorx r14d,ebx,0x6 + LONG $0x20048d47 // lea r8d,[r8+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8944; BYTE $0xcf // mov edi,r9d + LONG $0xf07b43c4; WORD $0x16e1 // rorx r12d,r9d,0x16 + LONG $0x28048d47 // lea r8d,[r8+r13*1] + WORD $0x3144; BYTE $0xd7 // xor edi,r10d + LONG $0xf07b43c4; WORD $0x0df1 // rorx r14d,r9d,0xd + LONG $0xf07b43c4; WORD $0x02e9 // rorx r13d,r9d,0x2 + LONG $0x00048d42 // lea eax,[rax+r8*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xd7 // xor r15d,r10d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d47 // lea r8d,[r8+r15*1] + WORD $0x8941; BYTE $0xdc // mov r12d,ebx + + // ROUND(R8, R9, R10, R11, AX, BX, CX, DX, R12, R13, R14, R15, DI, BP, 0x30) + WORD $0x5503; BYTE $0x30 // add edx,[rbp+0x30] + WORD $0x2141; BYTE $0xc4 // and r12d,eax + LONG $0xf07b63c4; WORD $0x19e8 // rorx r13d,eax,0x19 + LONG $0xf07b63c4; WORD $0x0bf8 // rorx r15d,eax,0xb + LONG $0x30048d47 // lea r8d,[r8+r14*1] + LONG $0x22148d42 // lea edx,[rdx+r12*1] + LONG $0xf27862c4; BYTE $0xe1 // andn r12d,eax,ecx + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b63c4; WORD $0x06f0 // rorx r14d,eax,0x6 + LONG $0x22148d42 // lea edx,[rdx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8945; BYTE $0xc7 // mov r15d,r8d + LONG $0xf07b43c4; WORD $0x16e0 // rorx r12d,r8d,0x16 + LONG $0x2a148d42 // lea edx,[rdx+r13*1] + WORD $0x3145; BYTE $0xcf // xor r15d,r9d + LONG $0xf07b43c4; WORD $0x0df0 // rorx r14d,r8d,0xd + LONG $0xf07b43c4; WORD $0x02e8 // rorx r13d,r8d,0x2 + LONG $0x131c8d45 // lea r11d,[r11+rdx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3144; BYTE $0xcf // xor edi,r9d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x148d; BYTE $0x3a // lea edx,[rdx+rdi*1] + WORD $0x8941; BYTE $0xc4 // mov r12d,eax + + // ROUND(DX, R8, R9, R10, R11, AX, BX, CX, R12, R13, R14, DI, R15, BP, 0x34) + WORD $0x4d03; BYTE $0x34 // add ecx,[rbp+0x34] + WORD $0x2145; BYTE $0xdc // and r12d,r11d + LONG $0xf07b43c4; WORD $0x19eb // rorx r13d,r11d,0x19 + LONG $0xf07bc3c4; WORD $0x0bfb // rorx edi,r11d,0xb + LONG $0x32148d42 // lea edx,[rdx+r14*1] + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + LONG $0xf22062c4; BYTE $0xe3 // andn r12d,r11d,ebx + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f3 // rorx r14d,r11d,0x6 + LONG $0x210c8d42 // lea ecx,[rcx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xd789 // mov edi,edx + LONG $0xf07b63c4; WORD $0x16e2 // rorx r12d,edx,0x16 + LONG $0x290c8d42 // lea ecx,[rcx+r13*1] + WORD $0x3144; BYTE $0xc7 // xor edi,r8d + LONG $0xf07b63c4; WORD $0x0df2 // rorx r14d,edx,0xd + LONG $0xf07b63c4; WORD $0x02ea // rorx r13d,edx,0x2 + LONG $0x0a148d45 // lea r10d,[r10+rcx*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3145; BYTE $0xc7 // xor r15d,r8d + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x390c8d42 // lea ecx,[rcx+r15*1] + WORD $0x8945; BYTE $0xdc // mov r12d,r11d + + // ROUND(CX, DX, R8, R9, R10, R11, AX, BX, R12, R13, R14, R15, DI, BP, 0x38) + WORD $0x5d03; BYTE $0x38 // add ebx,[rbp+0x38] + WORD $0x2145; BYTE $0xd4 // and r12d,r10d + LONG $0xf07b43c4; WORD $0x19ea // rorx r13d,r10d,0x19 + LONG $0xf07b43c4; WORD $0x0bfa // rorx r15d,r10d,0xb + LONG $0x310c8d42 // lea ecx,[rcx+r14*1] + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + LONG $0xf22862c4; BYTE $0xe0 // andn r12d,r10d,eax + WORD $0x3145; BYTE $0xfd // xor r13d,r15d + LONG $0xf07b43c4; WORD $0x06f2 // rorx r14d,r10d,0x6 + LONG $0x231c8d42 // lea ebx,[rbx+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0x8941; BYTE $0xcf // mov r15d,ecx + LONG $0xf07b63c4; WORD $0x16e1 // rorx r12d,ecx,0x16 + LONG $0x2b1c8d42 // lea ebx,[rbx+r13*1] + WORD $0x3141; BYTE $0xd7 // xor r15d,edx + LONG $0xf07b63c4; WORD $0x0df1 // rorx r14d,ecx,0xd + LONG $0xf07b63c4; WORD $0x02e9 // rorx r13d,ecx,0x2 + LONG $0x190c8d45 // lea r9d,[r9+rbx*1] + WORD $0x2144; BYTE $0xff // and edi,r15d + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0xd731 // xor edi,edx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + WORD $0x1c8d; BYTE $0x3b // lea ebx,[rbx+rdi*1] + WORD $0x8945; BYTE $0xd4 // mov r12d,r10d + + // ROUND(BX, CX, DX, R8, R9, R10, R11, AX, R12, R13, R14, DI, R15, BP, 0x3c) + WORD $0x4503; BYTE $0x3c // add eax,[rbp+0x3c] + WORD $0x2145; BYTE $0xcc // and r12d,r9d + LONG $0xf07b43c4; WORD $0x19e9 // rorx r13d,r9d,0x19 + LONG $0xf07bc3c4; WORD $0x0bf9 // rorx edi,r9d,0xb + LONG $0x331c8d42 // lea ebx,[rbx+r14*1] + LONG $0x20048d42 // lea eax,[rax+r12*1] + LONG $0xf23042c4; BYTE $0xe3 // andn r12d,r9d,r11d + WORD $0x3141; BYTE $0xfd // xor r13d,edi + LONG $0xf07b43c4; WORD $0x06f1 // rorx r14d,r9d,0x6 + LONG $0x20048d42 // lea eax,[rax+r12*1] + WORD $0x3145; BYTE $0xf5 // xor r13d,r14d + WORD $0xdf89 // mov edi,ebx + LONG $0xf07b63c4; WORD $0x16e3 // rorx r12d,ebx,0x16 + LONG $0x28048d42 // lea eax,[rax+r13*1] + WORD $0xcf31 // xor edi,ecx + LONG $0xf07b63c4; WORD $0x0df3 // rorx r14d,ebx,0xd + LONG $0xf07b63c4; WORD $0x02eb // rorx r13d,ebx,0x2 + LONG $0x00048d45 // lea r8d,[r8+rax*1] + WORD $0x2141; BYTE $0xff // and r15d,edi + WORD $0x3145; BYTE $0xe6 // xor r14d,r12d + WORD $0x3141; BYTE $0xcf // xor r15d,ecx + WORD $0x3145; BYTE $0xee // xor r14d,r13d + LONG $0x38048d42 // lea eax,[rax+r15*1] + WORD $0x8945; BYTE $0xcc // mov r12d,r9d + + ADDQ $-0x40, BP + CMPQ BP, SP + JAE loop2 + + MOVQ 0x200(SP), DI // $_ctx + ADDQ R14, AX + + ADDQ $0x1c0, SP + + ADDL (DI), AX + ADDL 4(DI), BX + ADDL 8(DI), CX + ADDL 12(DI), DX + ADDL 16(DI), R8 + ADDL 20(DI), R9 + + ADDQ $0x80, SI // input += 2 + ADDL 24(DI), R10 + MOVQ SI, R12 + ADDL 28(DI), R11 + CMPQ SI, 0x50(SP) // input == _end + + MOVL AX, (DI) + LONG $0xe4440f4c // cmove r12,rsp /* next block or stale data */ + MOVL AX, (DI) + MOVL BX, 4(DI) + MOVL CX, 8(DI) + MOVL DX, 12(DI) + MOVL R8, 16(DI) + MOVL R9, 20(DI) + MOVL R10, 24(DI) + MOVL R11, 28(DI) + + JBE loop0 + LEAQ (SP), BP + +done: + MOVQ BP, SP + MOVQ 0x58(SP), SP // restore saved stack pointer + WORD $0xf8c5; BYTE $0x77 // vzeroupper + + RET + diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm new file mode 100644 index 00000000..c959b1aa --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.asm @@ -0,0 +1,686 @@ + +// 16x Parallel implementation of SHA256 for AVX512 + +// +// Minio Cloud Storage, (C) 2017 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// This code is based on the Intel Multi-Buffer Crypto for IPSec library +// and more specifically the following implementation: +// https://github.com/intel/intel-ipsec-mb/blob/master/avx512/sha256_x16_avx512.asm +// +// For Golang it has been converted into Plan 9 assembly with the help of +// github.com/minio/asm2plan9s to assemble the AVX512 instructions +// + +// Copyright (c) 2017, Intel Corporation +// +// 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 Intel Corporation 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. + +#define SHA256_DIGEST_ROW_SIZE 64 + +// arg1 +#define STATE rdi +#define STATE_P9 DI +// arg2 +#define INP_SIZE rsi +#define INP_SIZE_P9 SI + +#define IDX rcx +#define TBL rdx +#define TBL_P9 DX + +#define INPUT rax +#define INPUT_P9 AX + +#define inp0 r9 +#define SCRATCH_P9 R12 +#define SCRATCH r12 +#define maskp r13 +#define MASKP_P9 R13 +#define mask r14 +#define MASK_P9 R14 + +#define A zmm0 +#define B zmm1 +#define C zmm2 +#define D zmm3 +#define E zmm4 +#define F zmm5 +#define G zmm6 +#define H zmm7 +#define T1 zmm8 +#define TMP0 zmm9 +#define TMP1 zmm10 +#define TMP2 zmm11 +#define TMP3 zmm12 +#define TMP4 zmm13 +#define TMP5 zmm14 +#define TMP6 zmm15 + +#define W0 zmm16 +#define W1 zmm17 +#define W2 zmm18 +#define W3 zmm19 +#define W4 zmm20 +#define W5 zmm21 +#define W6 zmm22 +#define W7 zmm23 +#define W8 zmm24 +#define W9 zmm25 +#define W10 zmm26 +#define W11 zmm27 +#define W12 zmm28 +#define W13 zmm29 +#define W14 zmm30 +#define W15 zmm31 + + +#define TRANSPOSE16(_r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7, _r8, _r9, _r10, _r11, _r12, _r13, _r14, _r15, _t0, _t1) \ + \ + \ // input r0 = {a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0} + \ // r1 = {b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0} + \ // r2 = {c15 c14 c13 c12 c11 c10 c9 c8 c7 c6 c5 c4 c3 c2 c1 c0} + \ // r3 = {d15 d14 d13 d12 d11 d10 d9 d8 d7 d6 d5 d4 d3 d2 d1 d0} + \ // r4 = {e15 e14 e13 e12 e11 e10 e9 e8 e7 e6 e5 e4 e3 e2 e1 e0} + \ // r5 = {f15 f14 f13 f12 f11 f10 f9 f8 f7 f6 f5 f4 f3 f2 f1 f0} + \ // r6 = {g15 g14 g13 g12 g11 g10 g9 g8 g7 g6 g5 g4 g3 g2 g1 g0} + \ // r7 = {h15 h14 h13 h12 h11 h10 h9 h8 h7 h6 h5 h4 h3 h2 h1 h0} + \ // r8 = {i15 i14 i13 i12 i11 i10 i9 i8 i7 i6 i5 i4 i3 i2 i1 i0} + \ // r9 = {j15 j14 j13 j12 j11 j10 j9 j8 j7 j6 j5 j4 j3 j2 j1 j0} + \ // r10 = {k15 k14 k13 k12 k11 k10 k9 k8 k7 k6 k5 k4 k3 k2 k1 k0} + \ // r11 = {l15 l14 l13 l12 l11 l10 l9 l8 l7 l6 l5 l4 l3 l2 l1 l0} + \ // r12 = {m15 m14 m13 m12 m11 m10 m9 m8 m7 m6 m5 m4 m3 m2 m1 m0} + \ // r13 = {n15 n14 n13 n12 n11 n10 n9 n8 n7 n6 n5 n4 n3 n2 n1 n0} + \ // r14 = {o15 o14 o13 o12 o11 o10 o9 o8 o7 o6 o5 o4 o3 o2 o1 o0} + \ // r15 = {p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0} + \ + \ // output r0 = { p0 o0 n0 m0 l0 k0 j0 i0 h0 g0 f0 e0 d0 c0 b0 a0} + \ // r1 = { p1 o1 n1 m1 l1 k1 j1 i1 h1 g1 f1 e1 d1 c1 b1 a1} + \ // r2 = { p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2} + \ // r3 = { p3 o3 n3 m3 l3 k3 j3 i3 h3 g3 f3 e3 d3 c3 b3 a3} + \ // r4 = { p4 o4 n4 m4 l4 k4 j4 i4 h4 g4 f4 e4 d4 c4 b4 a4} + \ // r5 = { p5 o5 n5 m5 l5 k5 j5 i5 h5 g5 f5 e5 d5 c5 b5 a5} + \ // r6 = { p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6} + \ // r7 = { p7 o7 n7 m7 l7 k7 j7 i7 h7 g7 f7 e7 d7 c7 b7 a7} + \ // r8 = { p8 o8 n8 m8 l8 k8 j8 i8 h8 g8 f8 e8 d8 c8 b8 a8} + \ // r9 = { p9 o9 n9 m9 l9 k9 j9 i9 h9 g9 f9 e9 d9 c9 b9 a9} + \ // r10 = {p10 o10 n10 m10 l10 k10 j10 i10 h10 g10 f10 e10 d10 c10 b10 a10} + \ // r11 = {p11 o11 n11 m11 l11 k11 j11 i11 h11 g11 f11 e11 d11 c11 b11 a11} + \ // r12 = {p12 o12 n12 m12 l12 k12 j12 i12 h12 g12 f12 e12 d12 c12 b12 a12} + \ // r13 = {p13 o13 n13 m13 l13 k13 j13 i13 h13 g13 f13 e13 d13 c13 b13 a13} + \ // r14 = {p14 o14 n14 m14 l14 k14 j14 i14 h14 g14 f14 e14 d14 c14 b14 a14} + \ // r15 = {p15 o15 n15 m15 l15 k15 j15 i15 h15 g15 f15 e15 d15 c15 b15 a15} + \ + \ // process top half + vshufps _t0, _r0, _r1, 0x44 \ // t0 = {b13 b12 a13 a12 b9 b8 a9 a8 b5 b4 a5 a4 b1 b0 a1 a0} + vshufps _r0, _r0, _r1, 0xEE \ // r0 = {b15 b14 a15 a14 b11 b10 a11 a10 b7 b6 a7 a6 b3 b2 a3 a2} + vshufps _t1, _r2, _r3, 0x44 \ // t1 = {d13 d12 c13 c12 d9 d8 c9 c8 d5 d4 c5 c4 d1 d0 c1 c0} + vshufps _r2, _r2, _r3, 0xEE \ // r2 = {d15 d14 c15 c14 d11 d10 c11 c10 d7 d6 c7 c6 d3 d2 c3 c2} + \ + vshufps _r3, _t0, _t1, 0xDD \ // r3 = {d13 c13 b13 a13 d9 c9 b9 a9 d5 c5 b5 a5 d1 c1 b1 a1} + vshufps _r1, _r0, _r2, 0x88 \ // r1 = {d14 c14 b14 a14 d10 c10 b10 a10 d6 c6 b6 a6 d2 c2 b2 a2} + vshufps _r0, _r0, _r2, 0xDD \ // r0 = {d15 c15 b15 a15 d11 c11 b11 a11 d7 c7 b7 a7 d3 c3 b3 a3} + vshufps _t0, _t0, _t1, 0x88 \ // t0 = {d12 c12 b12 a12 d8 c8 b8 a8 d4 c4 b4 a4 d0 c0 b0 a0} + \ + \ // use r2 in place of t0 + vshufps _r2, _r4, _r5, 0x44 \ // r2 = {f13 f12 e13 e12 f9 f8 e9 e8 f5 f4 e5 e4 f1 f0 e1 e0} + vshufps _r4, _r4, _r5, 0xEE \ // r4 = {f15 f14 e15 e14 f11 f10 e11 e10 f7 f6 e7 e6 f3 f2 e3 e2} + vshufps _t1, _r6, _r7, 0x44 \ // t1 = {h13 h12 g13 g12 h9 h8 g9 g8 h5 h4 g5 g4 h1 h0 g1 g0} + vshufps _r6, _r6, _r7, 0xEE \ // r6 = {h15 h14 g15 g14 h11 h10 g11 g10 h7 h6 g7 g6 h3 h2 g3 g2} + \ + vshufps _r7, _r2, _t1, 0xDD \ // r7 = {h13 g13 f13 e13 h9 g9 f9 e9 h5 g5 f5 e5 h1 g1 f1 e1} + vshufps _r5, _r4, _r6, 0x88 \ // r5 = {h14 g14 f14 e14 h10 g10 f10 e10 h6 g6 f6 e6 h2 g2 f2 e2} + vshufps _r4, _r4, _r6, 0xDD \ // r4 = {h15 g15 f15 e15 h11 g11 f11 e11 h7 g7 f7 e7 h3 g3 f3 e3} + vshufps _r2, _r2, _t1, 0x88 \ // r2 = {h12 g12 f12 e12 h8 g8 f8 e8 h4 g4 f4 e4 h0 g0 f0 e0} + \ + \ // use r6 in place of t0 + vshufps _r6, _r8, _r9, 0x44 \ // r6 = {j13 j12 i13 i12 j9 j8 i9 i8 j5 j4 i5 i4 j1 j0 i1 i0} + vshufps _r8, _r8, _r9, 0xEE \ // r8 = {j15 j14 i15 i14 j11 j10 i11 i10 j7 j6 i7 i6 j3 j2 i3 i2} + vshufps _t1, _r10, _r11, 0x44 \ // t1 = {l13 l12 k13 k12 l9 l8 k9 k8 l5 l4 k5 k4 l1 l0 k1 k0} + vshufps _r10, _r10, _r11, 0xEE \ // r10 = {l15 l14 k15 k14 l11 l10 k11 k10 l7 l6 k7 k6 l3 l2 k3 k2} + \ + vshufps _r11, _r6, _t1, 0xDD \ // r11 = {l13 k13 j13 113 l9 k9 j9 i9 l5 k5 j5 i5 l1 k1 j1 i1} + vshufps _r9, _r8, _r10, 0x88 \ // r9 = {l14 k14 j14 114 l10 k10 j10 i10 l6 k6 j6 i6 l2 k2 j2 i2} + vshufps _r8, _r8, _r10, 0xDD \ // r8 = {l15 k15 j15 115 l11 k11 j11 i11 l7 k7 j7 i7 l3 k3 j3 i3} + vshufps _r6, _r6, _t1, 0x88 \ // r6 = {l12 k12 j12 112 l8 k8 j8 i8 l4 k4 j4 i4 l0 k0 j0 i0} + \ + \ // use r10 in place of t0 + vshufps _r10, _r12, _r13, 0x44 \ // r10 = {n13 n12 m13 m12 n9 n8 m9 m8 n5 n4 m5 m4 n1 n0 a1 m0} + vshufps _r12, _r12, _r13, 0xEE \ // r12 = {n15 n14 m15 m14 n11 n10 m11 m10 n7 n6 m7 m6 n3 n2 a3 m2} + vshufps _t1, _r14, _r15, 0x44 \ // t1 = {p13 p12 013 012 p9 p8 09 08 p5 p4 05 04 p1 p0 01 00} + vshufps _r14, _r14, _r15, 0xEE \ // r14 = {p15 p14 015 014 p11 p10 011 010 p7 p6 07 06 p3 p2 03 02} + \ + vshufps _r15, _r10, _t1, 0xDD \ // r15 = {p13 013 n13 m13 p9 09 n9 m9 p5 05 n5 m5 p1 01 n1 m1} + vshufps _r13, _r12, _r14, 0x88 \ // r13 = {p14 014 n14 m14 p10 010 n10 m10 p6 06 n6 m6 p2 02 n2 m2} + vshufps _r12, _r12, _r14, 0xDD \ // r12 = {p15 015 n15 m15 p11 011 n11 m11 p7 07 n7 m7 p3 03 n3 m3} + vshufps _r10, _r10, _t1, 0x88 \ // r10 = {p12 012 n12 m12 p8 08 n8 m8 p4 04 n4 m4 p0 00 n0 m0} + \ + \ // At this point, the registers that contain interesting data are: + \ // t0, r3, r1, r0, r2, r7, r5, r4, r6, r11, r9, r8, r10, r15, r13, r12 + \ // Can use t1 and r14 as scratch registers + LEAQ PSHUFFLE_TRANSPOSE16_MASK1<>(SB), BX \ + LEAQ PSHUFFLE_TRANSPOSE16_MASK2<>(SB), R8 \ + \ + vmovdqu32 _r14, [rbx] \ + vpermi2q _r14, _t0, _r2 \ // r14 = {h8 g8 f8 e8 d8 c8 b8 a8 h0 g0 f0 e0 d0 c0 b0 a0} + vmovdqu32 _t1, [r8] \ + vpermi2q _t1, _t0, _r2 \ // t1 = {h12 g12 f12 e12 d12 c12 b12 a12 h4 g4 f4 e4 d4 c4 b4 a4} + \ + vmovdqu32 _r2, [rbx] \ + vpermi2q _r2, _r3, _r7 \ // r2 = {h9 g9 f9 e9 d9 c9 b9 a9 h1 g1 f1 e1 d1 c1 b1 a1} + vmovdqu32 _t0, [r8] \ + vpermi2q _t0, _r3, _r7 \ // t0 = {h13 g13 f13 e13 d13 c13 b13 a13 h5 g5 f5 e5 d5 c5 b5 a5} + \ + vmovdqu32 _r3, [rbx] \ + vpermi2q _r3, _r1, _r5 \ // r3 = {h10 g10 f10 e10 d10 c10 b10 a10 h2 g2 f2 e2 d2 c2 b2 a2} + vmovdqu32 _r7, [r8] \ + vpermi2q _r7, _r1, _r5 \ // r7 = {h14 g14 f14 e14 d14 c14 b14 a14 h6 g6 f6 e6 d6 c6 b6 a6} + \ + vmovdqu32 _r1, [rbx] \ + vpermi2q _r1, _r0, _r4 \ // r1 = {h11 g11 f11 e11 d11 c11 b11 a11 h3 g3 f3 e3 d3 c3 b3 a3} + vmovdqu32 _r5, [r8] \ + vpermi2q _r5, _r0, _r4 \ // r5 = {h15 g15 f15 e15 d15 c15 b15 a15 h7 g7 f7 e7 d7 c7 b7 a7} + \ + vmovdqu32 _r0, [rbx] \ + vpermi2q _r0, _r6, _r10 \ // r0 = {p8 o8 n8 m8 l8 k8 j8 i8 p0 o0 n0 m0 l0 k0 j0 i0} + vmovdqu32 _r4, [r8] \ + vpermi2q _r4, _r6, _r10 \ // r4 = {p12 o12 n12 m12 l12 k12 j12 i12 p4 o4 n4 m4 l4 k4 j4 i4} + \ + vmovdqu32 _r6, [rbx] \ + vpermi2q _r6, _r11, _r15 \ // r6 = {p9 o9 n9 m9 l9 k9 j9 i9 p1 o1 n1 m1 l1 k1 j1 i1} + vmovdqu32 _r10, [r8] \ + vpermi2q _r10, _r11, _r15 \ // r10 = {p13 o13 n13 m13 l13 k13 j13 i13 p5 o5 n5 m5 l5 k5 j5 i5} + \ + vmovdqu32 _r11, [rbx] \ + vpermi2q _r11, _r9, _r13 \ // r11 = {p10 o10 n10 m10 l10 k10 j10 i10 p2 o2 n2 m2 l2 k2 j2 i2} + vmovdqu32 _r15, [r8] \ + vpermi2q _r15, _r9, _r13 \ // r15 = {p14 o14 n14 m14 l14 k14 j14 i14 p6 o6 n6 m6 l6 k6 j6 i6} + \ + vmovdqu32 _r9, [rbx] \ + vpermi2q _r9, _r8, _r12 \ // r9 = {p11 o11 n11 m11 l11 k11 j11 i11 p3 o3 n3 m3 l3 k3 j3 i3} + vmovdqu32 _r13, [r8] \ + vpermi2q _r13, _r8, _r12 \ // r13 = {p15 o15 n15 m15 l15 k15 j15 i15 p7 o7 n7 m7 l7 k7 j7 i7} + \ + \ // At this point r8 and r12 can be used as scratch registers + vshuff64x2 _r8, _r14, _r0, 0xEE \ // r8 = {p8 o8 n8 m8 l8 k8 j8 i8 h8 g8 f8 e8 d8 c8 b8 a8} + vshuff64x2 _r0, _r14, _r0, 0x44 \ // r0 = {p0 o0 n0 m0 l0 k0 j0 i0 h0 g0 f0 e0 d0 c0 b0 a0} + \ + vshuff64x2 _r12, _t1, _r4, 0xEE \ // r12 = {p12 o12 n12 m12 l12 k12 j12 i12 h12 g12 f12 e12 d12 c12 b12 a12} + vshuff64x2 _r4, _t1, _r4, 0x44 \ // r4 = {p4 o4 n4 m4 l4 k4 j4 i4 h4 g4 f4 e4 d4 c4 b4 a4} + \ + vshuff64x2 _r14, _r7, _r15, 0xEE \ // r14 = {p14 o14 n14 m14 l14 k14 j14 i14 h14 g14 f14 e14 d14 c14 b14 a14} + vshuff64x2 _t1, _r7, _r15, 0x44 \ // t1 = {p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6} + \ + vshuff64x2 _r15, _r5, _r13, 0xEE \ // r15 = {p15 o15 n15 m15 l15 k15 j15 i15 h15 g15 f15 e15 d15 c15 b15 a15} + vshuff64x2 _r7, _r5, _r13, 0x44 \ // r7 = {p7 o7 n7 m7 l7 k7 j7 i7 h7 g7 f7 e7 d7 c7 b7 a7} + \ + vshuff64x2 _r13, _t0, _r10, 0xEE \ // r13 = {p13 o13 n13 m13 l13 k13 j13 i13 h13 g13 f13 e13 d13 c13 b13 a13} + vshuff64x2 _r5, _t0, _r10, 0x44 \ // r5 = {p5 o5 n5 m5 l5 k5 j5 i5 h5 g5 f5 e5 d5 c5 b5 a5} + \ + vshuff64x2 _r10, _r3, _r11, 0xEE \ // r10 = {p10 o10 n10 m10 l10 k10 j10 i10 h10 g10 f10 e10 d10 c10 b10 a10} + vshuff64x2 _t0, _r3, _r11, 0x44 \ // t0 = {p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2} + \ + vshuff64x2 _r11, _r1, _r9, 0xEE \ // r11 = {p11 o11 n11 m11 l11 k11 j11 i11 h11 g11 f11 e11 d11 c11 b11 a11} + vshuff64x2 _r3, _r1, _r9, 0x44 \ // r3 = {p3 o3 n3 m3 l3 k3 j3 i3 h3 g3 f3 e3 d3 c3 b3 a3} + \ + vshuff64x2 _r9, _r2, _r6, 0xEE \ // r9 = {p9 o9 n9 m9 l9 k9 j9 i9 h9 g9 f9 e9 d9 c9 b9 a9} + vshuff64x2 _r1, _r2, _r6, 0x44 \ // r1 = {p1 o1 n1 m1 l1 k1 j1 i1 h1 g1 f1 e1 d1 c1 b1 a1} + \ + vmovdqu32 _r2, _t0 \ // r2 = {p2 o2 n2 m2 l2 k2 j2 i2 h2 g2 f2 e2 d2 c2 b2 a2} + vmovdqu32 _r6, _t1 \ // r6 = {p6 o6 n6 m6 l6 k6 j6 i6 h6 g6 f6 e6 d6 c6 b6 a6} + + +// CH(A, B, C) = (A&B) ^ (~A&C) +// MAJ(E, F, G) = (E&F) ^ (E&G) ^ (F&G) +// SIGMA0 = ROR_2 ^ ROR_13 ^ ROR_22 +// SIGMA1 = ROR_6 ^ ROR_11 ^ ROR_25 +// sigma0 = ROR_7 ^ ROR_18 ^ SHR_3 +// sigma1 = ROR_17 ^ ROR_19 ^ SHR_10 + +// Main processing loop per round +#define PROCESS_LOOP(_WT, _ROUND, _A, _B, _C, _D, _E, _F, _G, _H) \ + \ // T1 = H + SIGMA1(E) + CH(E, F, G) + Kt + Wt + \ // T2 = SIGMA0(A) + MAJ(A, B, C) + \ // H=G, G=F, F=E, E=D+T1, D=C, C=B, B=A, A=T1+T2 + \ + \ // H becomes T2, then add T1 for A + \ // D becomes D + T1 for E + \ + vpaddd T1, _H, TMP3 \ // T1 = H + Kt + vmovdqu32 TMP0, _E \ + vprord TMP1, _E, 6 \ // ROR_6(E) + vprord TMP2, _E, 11 \ // ROR_11(E) + vprord TMP3, _E, 25 \ // ROR_25(E) + vpternlogd TMP0, _F, _G, 0xCA \ // TMP0 = CH(E,F,G) + vpaddd T1, T1, _WT \ // T1 = T1 + Wt + vpternlogd TMP1, TMP2, TMP3, 0x96 \ // TMP1 = SIGMA1(E) + vpaddd T1, T1, TMP0 \ // T1 = T1 + CH(E,F,G) + vpaddd T1, T1, TMP1 \ // T1 = T1 + SIGMA1(E) + vpaddd _D, _D, T1 \ // D = D + T1 + \ + vprord _H, _A, 2 \ // ROR_2(A) + vprord TMP2, _A, 13 \ // ROR_13(A) + vprord TMP3, _A, 22 \ // ROR_22(A) + vmovdqu32 TMP0, _A \ + vpternlogd TMP0, _B, _C, 0xE8 \ // TMP0 = MAJ(A,B,C) + vpternlogd _H, TMP2, TMP3, 0x96 \ // H(T2) = SIGMA0(A) + vpaddd _H, _H, TMP0 \ // H(T2) = SIGMA0(A) + MAJ(A,B,C) + vpaddd _H, _H, T1 \ // H(A) = H(T2) + T1 + \ + vmovdqu32 TMP3, [TBL + ((_ROUND+1)*64)] \ // Next Kt + + +#define MSG_SCHED_ROUND_16_63(_WT, _WTp1, _WTp9, _WTp14) \ + vprord TMP4, _WTp14, 17 \ // ROR_17(Wt-2) + vprord TMP5, _WTp14, 19 \ // ROR_19(Wt-2) + vpsrld TMP6, _WTp14, 10 \ // SHR_10(Wt-2) + vpternlogd TMP4, TMP5, TMP6, 0x96 \ // TMP4 = sigma1(Wt-2) + \ + vpaddd _WT, _WT, TMP4 \ // Wt = Wt-16 + sigma1(Wt-2) + vpaddd _WT, _WT, _WTp9 \ // Wt = Wt-16 + sigma1(Wt-2) + Wt-7 + \ + vprord TMP4, _WTp1, 7 \ // ROR_7(Wt-15) + vprord TMP5, _WTp1, 18 \ // ROR_18(Wt-15) + vpsrld TMP6, _WTp1, 3 \ // SHR_3(Wt-15) + vpternlogd TMP4, TMP5, TMP6, 0x96 \ // TMP4 = sigma0(Wt-15) + \ + vpaddd _WT, _WT, TMP4 \ // Wt = Wt-16 + sigma1(Wt-2) + + \ // Wt-7 + sigma0(Wt-15) + + + +// Note this is reading in a block of data for one lane +// When all 16 are read, the data must be transposed to build msg schedule +#define MSG_SCHED_ROUND_00_15(_WT, OFFSET, LABEL) \ + TESTQ $(1<(SB), TBL_P9 + vmovdqu32 TMP2, [TBL] + + // Get first K from table + MOVQ table+16(FP), TBL_P9 + vmovdqu32 TMP3, [TBL] + + // Save digests for later addition + vmovdqu32 [SCRATCH + 64*0], A + vmovdqu32 [SCRATCH + 64*1], B + vmovdqu32 [SCRATCH + 64*2], C + vmovdqu32 [SCRATCH + 64*3], D + vmovdqu32 [SCRATCH + 64*4], E + vmovdqu32 [SCRATCH + 64*5], F + vmovdqu32 [SCRATCH + 64*6], G + vmovdqu32 [SCRATCH + 64*7], H + + add IDX, 64 + + // Transpose input data + TRANSPOSE16(W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, TMP0, TMP1) + + vpshufb W0, W0, TMP2 + vpshufb W1, W1, TMP2 + vpshufb W2, W2, TMP2 + vpshufb W3, W3, TMP2 + vpshufb W4, W4, TMP2 + vpshufb W5, W5, TMP2 + vpshufb W6, W6, TMP2 + vpshufb W7, W7, TMP2 + vpshufb W8, W8, TMP2 + vpshufb W9, W9, TMP2 + vpshufb W10, W10, TMP2 + vpshufb W11, W11, TMP2 + vpshufb W12, W12, TMP2 + vpshufb W13, W13, TMP2 + vpshufb W14, W14, TMP2 + vpshufb W15, W15, TMP2 + + // MSG Schedule for W0-W15 is now complete in registers + // Process first 48 rounds + // Calculate next Wt+16 after processing is complete and Wt is unneeded + + PROCESS_LOOP( W0, 0, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W0, W1, W9, W14) + PROCESS_LOOP( W1, 1, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W1, W2, W10, W15) + PROCESS_LOOP( W2, 2, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63( W2, W3, W11, W0) + PROCESS_LOOP( W3, 3, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63( W3, W4, W12, W1) + PROCESS_LOOP( W4, 4, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63( W4, W5, W13, W2) + PROCESS_LOOP( W5, 5, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63( W5, W6, W14, W3) + PROCESS_LOOP( W6, 6, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63( W6, W7, W15, W4) + PROCESS_LOOP( W7, 7, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63( W7, W8, W0, W5) + PROCESS_LOOP( W8, 8, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W8, W9, W1, W6) + PROCESS_LOOP( W9, 9, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W9, W10, W2, W7) + PROCESS_LOOP(W10, 10, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63(W10, W11, W3, W8) + PROCESS_LOOP(W11, 11, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63(W11, W12, W4, W9) + PROCESS_LOOP(W12, 12, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63(W12, W13, W5, W10) + PROCESS_LOOP(W13, 13, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63(W13, W14, W6, W11) + PROCESS_LOOP(W14, 14, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63(W14, W15, W7, W12) + PROCESS_LOOP(W15, 15, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63(W15, W0, W8, W13) + PROCESS_LOOP( W0, 16, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W0, W1, W9, W14) + PROCESS_LOOP( W1, 17, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W1, W2, W10, W15) + PROCESS_LOOP( W2, 18, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63( W2, W3, W11, W0) + PROCESS_LOOP( W3, 19, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63( W3, W4, W12, W1) + PROCESS_LOOP( W4, 20, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63( W4, W5, W13, W2) + PROCESS_LOOP( W5, 21, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63( W5, W6, W14, W3) + PROCESS_LOOP( W6, 22, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63( W6, W7, W15, W4) + PROCESS_LOOP( W7, 23, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63( W7, W8, W0, W5) + PROCESS_LOOP( W8, 24, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W8, W9, W1, W6) + PROCESS_LOOP( W9, 25, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W9, W10, W2, W7) + PROCESS_LOOP(W10, 26, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63(W10, W11, W3, W8) + PROCESS_LOOP(W11, 27, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63(W11, W12, W4, W9) + PROCESS_LOOP(W12, 28, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63(W12, W13, W5, W10) + PROCESS_LOOP(W13, 29, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63(W13, W14, W6, W11) + PROCESS_LOOP(W14, 30, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63(W14, W15, W7, W12) + PROCESS_LOOP(W15, 31, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63(W15, W0, W8, W13) + PROCESS_LOOP( W0, 32, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W0, W1, W9, W14) + PROCESS_LOOP( W1, 33, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W1, W2, W10, W15) + PROCESS_LOOP( W2, 34, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63( W2, W3, W11, W0) + PROCESS_LOOP( W3, 35, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63( W3, W4, W12, W1) + PROCESS_LOOP( W4, 36, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63( W4, W5, W13, W2) + PROCESS_LOOP( W5, 37, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63( W5, W6, W14, W3) + PROCESS_LOOP( W6, 38, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63( W6, W7, W15, W4) + PROCESS_LOOP( W7, 39, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63( W7, W8, W0, W5) + PROCESS_LOOP( W8, 40, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_16_63( W8, W9, W1, W6) + PROCESS_LOOP( W9, 41, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_16_63( W9, W10, W2, W7) + PROCESS_LOOP(W10, 42, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_16_63(W10, W11, W3, W8) + PROCESS_LOOP(W11, 43, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_16_63(W11, W12, W4, W9) + PROCESS_LOOP(W12, 44, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_16_63(W12, W13, W5, W10) + PROCESS_LOOP(W13, 45, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_16_63(W13, W14, W6, W11) + PROCESS_LOOP(W14, 46, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_16_63(W14, W15, W7, W12) + PROCESS_LOOP(W15, 47, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_16_63(W15, W0, W8, W13) + + // Check if this is the last block + sub INP_SIZE, 1 + JE lastLoop + + // Load next mask for inputs + ADDQ $8, MASKP_P9 + MOVQ (MASKP_P9), MASK_P9 + + // Process last 16 rounds + // Read in next block msg data for use in first 16 words of msg sched + + PROCESS_LOOP( W0, 48, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_00_15( W0, 0, skipNext0) + PROCESS_LOOP( W1, 49, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_00_15( W1, 1, skipNext1) + PROCESS_LOOP( W2, 50, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_00_15( W2, 2, skipNext2) + PROCESS_LOOP( W3, 51, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_00_15( W3, 3, skipNext3) + PROCESS_LOOP( W4, 52, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_00_15( W4, 4, skipNext4) + PROCESS_LOOP( W5, 53, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_00_15( W5, 5, skipNext5) + PROCESS_LOOP( W6, 54, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_00_15( W6, 6, skipNext6) + PROCESS_LOOP( W7, 55, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_00_15( W7, 7, skipNext7) + PROCESS_LOOP( W8, 56, A, B, C, D, E, F, G, H) + MSG_SCHED_ROUND_00_15( W8, 8, skipNext8) + PROCESS_LOOP( W9, 57, H, A, B, C, D, E, F, G) + MSG_SCHED_ROUND_00_15( W9, 9, skipNext9) + PROCESS_LOOP(W10, 58, G, H, A, B, C, D, E, F) + MSG_SCHED_ROUND_00_15(W10, 10, skipNext10) + PROCESS_LOOP(W11, 59, F, G, H, A, B, C, D, E) + MSG_SCHED_ROUND_00_15(W11, 11, skipNext11) + PROCESS_LOOP(W12, 60, E, F, G, H, A, B, C, D) + MSG_SCHED_ROUND_00_15(W12, 12, skipNext12) + PROCESS_LOOP(W13, 61, D, E, F, G, H, A, B, C) + MSG_SCHED_ROUND_00_15(W13, 13, skipNext13) + PROCESS_LOOP(W14, 62, C, D, E, F, G, H, A, B) + MSG_SCHED_ROUND_00_15(W14, 14, skipNext14) + PROCESS_LOOP(W15, 63, B, C, D, E, F, G, H, A) + MSG_SCHED_ROUND_00_15(W15, 15, skipNext15) + + // Add old digest + vmovdqu32 TMP2, A + vmovdqu32 A, [SCRATCH + 64*0] + vpaddd A{k1}, A, TMP2 + vmovdqu32 TMP2, B + vmovdqu32 B, [SCRATCH + 64*1] + vpaddd B{k1}, B, TMP2 + vmovdqu32 TMP2, C + vmovdqu32 C, [SCRATCH + 64*2] + vpaddd C{k1}, C, TMP2 + vmovdqu32 TMP2, D + vmovdqu32 D, [SCRATCH + 64*3] + vpaddd D{k1}, D, TMP2 + vmovdqu32 TMP2, E + vmovdqu32 E, [SCRATCH + 64*4] + vpaddd E{k1}, E, TMP2 + vmovdqu32 TMP2, F + vmovdqu32 F, [SCRATCH + 64*5] + vpaddd F{k1}, F, TMP2 + vmovdqu32 TMP2, G + vmovdqu32 G, [SCRATCH + 64*6] + vpaddd G{k1}, G, TMP2 + vmovdqu32 TMP2, H + vmovdqu32 H, [SCRATCH + 64*7] + vpaddd H{k1}, H, TMP2 + + kmovq k1, mask + JMP lloop + +lastLoop: + // Process last 16 rounds + PROCESS_LOOP( W0, 48, A, B, C, D, E, F, G, H) + PROCESS_LOOP( W1, 49, H, A, B, C, D, E, F, G) + PROCESS_LOOP( W2, 50, G, H, A, B, C, D, E, F) + PROCESS_LOOP( W3, 51, F, G, H, A, B, C, D, E) + PROCESS_LOOP( W4, 52, E, F, G, H, A, B, C, D) + PROCESS_LOOP( W5, 53, D, E, F, G, H, A, B, C) + PROCESS_LOOP( W6, 54, C, D, E, F, G, H, A, B) + PROCESS_LOOP( W7, 55, B, C, D, E, F, G, H, A) + PROCESS_LOOP( W8, 56, A, B, C, D, E, F, G, H) + PROCESS_LOOP( W9, 57, H, A, B, C, D, E, F, G) + PROCESS_LOOP(W10, 58, G, H, A, B, C, D, E, F) + PROCESS_LOOP(W11, 59, F, G, H, A, B, C, D, E) + PROCESS_LOOP(W12, 60, E, F, G, H, A, B, C, D) + PROCESS_LOOP(W13, 61, D, E, F, G, H, A, B, C) + PROCESS_LOOP(W14, 62, C, D, E, F, G, H, A, B) + PROCESS_LOOP(W15, 63, B, C, D, E, F, G, H, A) + + // Add old digest + vmovdqu32 TMP2, A + vmovdqu32 A, [SCRATCH + 64*0] + vpaddd A{k1}, A, TMP2 + vmovdqu32 TMP2, B + vmovdqu32 B, [SCRATCH + 64*1] + vpaddd B{k1}, B, TMP2 + vmovdqu32 TMP2, C + vmovdqu32 C, [SCRATCH + 64*2] + vpaddd C{k1}, C, TMP2 + vmovdqu32 TMP2, D + vmovdqu32 D, [SCRATCH + 64*3] + vpaddd D{k1}, D, TMP2 + vmovdqu32 TMP2, E + vmovdqu32 E, [SCRATCH + 64*4] + vpaddd E{k1}, E, TMP2 + vmovdqu32 TMP2, F + vmovdqu32 F, [SCRATCH + 64*5] + vpaddd F{k1}, F, TMP2 + vmovdqu32 TMP2, G + vmovdqu32 G, [SCRATCH + 64*6] + vpaddd G{k1}, G, TMP2 + vmovdqu32 TMP2, H + vmovdqu32 H, [SCRATCH + 64*7] + vpaddd H{k1}, H, TMP2 + + // Write out digest + vmovdqu32 [STATE + 0*SHA256_DIGEST_ROW_SIZE], A + vmovdqu32 [STATE + 1*SHA256_DIGEST_ROW_SIZE], B + vmovdqu32 [STATE + 2*SHA256_DIGEST_ROW_SIZE], C + vmovdqu32 [STATE + 3*SHA256_DIGEST_ROW_SIZE], D + vmovdqu32 [STATE + 4*SHA256_DIGEST_ROW_SIZE], E + vmovdqu32 [STATE + 5*SHA256_DIGEST_ROW_SIZE], F + vmovdqu32 [STATE + 6*SHA256_DIGEST_ROW_SIZE], G + vmovdqu32 [STATE + 7*SHA256_DIGEST_ROW_SIZE], H + + VZEROUPPER + RET + +// +// Tables +// + +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x000(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x008(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x010(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x018(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x020(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x028(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x030(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x038(SB)/8, $0x0c0d0e0f08090a0b +GLOBL PSHUFFLE_BYTE_FLIP_MASK<>(SB), 8, $64 + +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x000(SB)/8, $0x0000000000000000 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x008(SB)/8, $0x0000000000000001 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x010(SB)/8, $0x0000000000000008 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x018(SB)/8, $0x0000000000000009 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x020(SB)/8, $0x0000000000000004 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x028(SB)/8, $0x0000000000000005 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x030(SB)/8, $0x000000000000000C +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x038(SB)/8, $0x000000000000000D +GLOBL PSHUFFLE_TRANSPOSE16_MASK1<>(SB), 8, $64 + +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x000(SB)/8, $0x0000000000000002 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x008(SB)/8, $0x0000000000000003 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x010(SB)/8, $0x000000000000000A +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x018(SB)/8, $0x000000000000000B +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x020(SB)/8, $0x0000000000000006 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x028(SB)/8, $0x0000000000000007 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x030(SB)/8, $0x000000000000000E +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x038(SB)/8, $0x000000000000000F +GLOBL PSHUFFLE_TRANSPOSE16_MASK2<>(SB), 8, $64 diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go new file mode 100644 index 00000000..e6bd455d --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.go @@ -0,0 +1,500 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +import ( + "encoding/binary" + "errors" + "hash" + "sort" + "sync/atomic" + "time" +) + +//go:noescape +func sha256X16Avx512(digests *[512]byte, scratch *[512]byte, table *[512]uint64, mask []uint64, inputs [16][]byte) + +// Avx512ServerUID - Do not start at 0 but next multiple of 16 so as to be able to +// differentiate with default initialiation value of 0 +const Avx512ServerUID = 16 + +var uidCounter uint64 + +// NewAvx512 - initialize sha256 Avx512 implementation. +func NewAvx512(a512srv *Avx512Server) hash.Hash { + uid := atomic.AddUint64(&uidCounter, 1) + return &Avx512Digest{uid: uid, a512srv: a512srv} +} + +// Avx512Digest - Type for computing SHA256 using Avx512 +type Avx512Digest struct { + uid uint64 + a512srv *Avx512Server + x [chunk]byte + nx int + len uint64 + final bool + result [Size]byte +} + +// Size - Return size of checksum +func (d *Avx512Digest) Size() int { return Size } + +// BlockSize - Return blocksize of checksum +func (d Avx512Digest) BlockSize() int { return BlockSize } + +// Reset - reset sha digest to its initial values +func (d *Avx512Digest) Reset() { + d.a512srv.blocksCh <- blockInput{uid: d.uid, reset: true} + d.nx = 0 + d.len = 0 + d.final = false +} + +// Write to digest +func (d *Avx512Digest) Write(p []byte) (nn int, err error) { + + if d.final { + return 0, errors.New("Avx512Digest already finalized. Reset first before writing again") + } + + nn = len(p) + d.len += uint64(nn) + if d.nx > 0 { + n := copy(d.x[d.nx:], p) + d.nx += n + if d.nx == chunk { + d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: d.x[:]} + d.nx = 0 + } + p = p[n:] + } + if len(p) >= chunk { + n := len(p) &^ (chunk - 1) + d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: p[:n]} + p = p[n:] + } + if len(p) > 0 { + d.nx = copy(d.x[:], p) + } + return +} + +// Sum - Return sha256 sum in bytes +func (d *Avx512Digest) Sum(in []byte) (result []byte) { + + if d.final { + return append(in, d.result[:]...) + } + + trail := make([]byte, 0, 128) + + len := d.len + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. + var tmp [64]byte + tmp[0] = 0x80 + if len%64 < 56 { + trail = append(d.x[:d.nx], tmp[0:56-len%64]...) + } else { + trail = append(d.x[:d.nx], tmp[0:64+56-len%64]...) + } + d.nx = 0 + + // Length in bits. + len <<= 3 + for i := uint(0); i < 8; i++ { + tmp[i] = byte(len >> (56 - 8*i)) + } + trail = append(trail, tmp[0:8]...) + + sumCh := make(chan [Size]byte) + d.a512srv.blocksCh <- blockInput{uid: d.uid, msg: trail, final: true, sumCh: sumCh} + d.result = <-sumCh + d.final = true + return append(in, d.result[:]...) +} + +var table = [512]uint64{ + 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, + 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, 0x428a2f98428a2f98, + 0x7137449171374491, 0x7137449171374491, 0x7137449171374491, 0x7137449171374491, + 0x7137449171374491, 0x7137449171374491, 0x7137449171374491, 0x7137449171374491, + 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, + 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, 0xb5c0fbcfb5c0fbcf, + 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, + 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, 0xe9b5dba5e9b5dba5, + 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, + 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, 0x3956c25b3956c25b, + 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, + 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, 0x59f111f159f111f1, + 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, + 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, 0x923f82a4923f82a4, + 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, + 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, 0xab1c5ed5ab1c5ed5, + 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, + 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, 0xd807aa98d807aa98, + 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, + 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, 0x12835b0112835b01, + 0x243185be243185be, 0x243185be243185be, 0x243185be243185be, 0x243185be243185be, + 0x243185be243185be, 0x243185be243185be, 0x243185be243185be, 0x243185be243185be, + 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, + 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, 0x550c7dc3550c7dc3, + 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, + 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, 0x72be5d7472be5d74, + 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, + 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, 0x80deb1fe80deb1fe, + 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, + 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, 0x9bdc06a79bdc06a7, + 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, + 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, 0xc19bf174c19bf174, + 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, + 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, 0xe49b69c1e49b69c1, + 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, + 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, 0xefbe4786efbe4786, + 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, + 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, 0x0fc19dc60fc19dc6, + 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, + 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, 0x240ca1cc240ca1cc, + 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, + 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, 0x2de92c6f2de92c6f, + 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, + 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, 0x4a7484aa4a7484aa, + 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, + 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, 0x5cb0a9dc5cb0a9dc, + 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, + 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, 0x76f988da76f988da, + 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, + 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, 0x983e5152983e5152, + 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, + 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, 0xa831c66da831c66d, + 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, + 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, 0xb00327c8b00327c8, + 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, + 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, 0xbf597fc7bf597fc7, + 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, + 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, 0xc6e00bf3c6e00bf3, + 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, + 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, 0xd5a79147d5a79147, + 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, + 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, 0x06ca635106ca6351, + 0x1429296714292967, 0x1429296714292967, 0x1429296714292967, 0x1429296714292967, + 0x1429296714292967, 0x1429296714292967, 0x1429296714292967, 0x1429296714292967, + 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, + 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, 0x27b70a8527b70a85, + 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, + 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, 0x2e1b21382e1b2138, + 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, + 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, 0x4d2c6dfc4d2c6dfc, + 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, + 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, 0x53380d1353380d13, + 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, + 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, 0x650a7354650a7354, + 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, + 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, 0x766a0abb766a0abb, + 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, + 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, 0x81c2c92e81c2c92e, + 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, + 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, 0x92722c8592722c85, + 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, + 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, 0xa2bfe8a1a2bfe8a1, + 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, + 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, 0xa81a664ba81a664b, + 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, + 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, 0xc24b8b70c24b8b70, + 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, + 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, 0xc76c51a3c76c51a3, + 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, + 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, 0xd192e819d192e819, + 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, + 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, 0xd6990624d6990624, + 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, + 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, 0xf40e3585f40e3585, + 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, + 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, 0x106aa070106aa070, + 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, + 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, 0x19a4c11619a4c116, + 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, + 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, 0x1e376c081e376c08, + 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, + 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, 0x2748774c2748774c, + 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, + 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, 0x34b0bcb534b0bcb5, + 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, + 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, 0x391c0cb3391c0cb3, + 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, + 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, 0x4ed8aa4a4ed8aa4a, + 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, + 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, 0x5b9cca4f5b9cca4f, + 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, + 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, 0x682e6ff3682e6ff3, + 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, + 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, 0x748f82ee748f82ee, + 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, + 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, 0x78a5636f78a5636f, + 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, + 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, 0x84c8781484c87814, + 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, + 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, 0x8cc702088cc70208, + 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, + 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, 0x90befffa90befffa, + 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, + 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, 0xa4506ceba4506ceb, + 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, + 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, 0xbef9a3f7bef9a3f7, + 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2, + 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2, 0xc67178f2c67178f2} + +// Interface function to assembly ode +func blockAvx512(digests *[512]byte, input [16][]byte, mask []uint64) [16][Size]byte { + + scratch := [512]byte{} + sha256X16Avx512(digests, &scratch, &table, mask, input) + + output := [16][Size]byte{} + for i := 0; i < 16; i++ { + output[i] = getDigest(i, digests[:]) + } + + return output +} + +func getDigest(index int, state []byte) (sum [Size]byte) { + for j := 0; j < 16; j += 2 { + for i := index*4 + j*Size; i < index*4+(j+1)*Size; i += Size { + binary.BigEndian.PutUint32(sum[j*2:], binary.LittleEndian.Uint32(state[i:i+4])) + } + } + return +} + +// Message to send across input channel +type blockInput struct { + uid uint64 + msg []byte + reset bool + final bool + sumCh chan [Size]byte +} + +// Avx512Server - Type to implement 16x parallel handling of SHA256 invocations +type Avx512Server struct { + blocksCh chan blockInput // Input channel + totalIn int // Total number of inputs waiting to be processed + lanes [16]Avx512LaneInfo // Array with info per lane (out of 16) + digests map[uint64][Size]byte // Map of uids to (interim) digest results +} + +// Avx512LaneInfo - Info for each lane +type Avx512LaneInfo struct { + uid uint64 // unique identification for this SHA processing + block []byte // input block to be processed + outputCh chan [Size]byte // channel for output result +} + +// NewAvx512Server - Create new object for parallel processing handling +func NewAvx512Server() *Avx512Server { + a512srv := &Avx512Server{} + a512srv.digests = make(map[uint64][Size]byte) + a512srv.blocksCh = make(chan blockInput) + + // Start a single thread for reading from the input channel + go a512srv.Process() + return a512srv +} + +// Process - Sole handler for reading from the input channel +func (a512srv *Avx512Server) Process() { + for { + select { + case block := <-a512srv.blocksCh: + if block.reset { + a512srv.reset(block.uid) + continue + } + index := block.uid & 0xf + // fmt.Println("Adding message:", block.uid, index) + + if a512srv.lanes[index].block != nil { // If slot is already filled, process all inputs + //fmt.Println("Invoking Blocks()") + a512srv.blocks() + } + a512srv.totalIn++ + a512srv.lanes[index] = Avx512LaneInfo{uid: block.uid, block: block.msg} + if block.final { + a512srv.lanes[index].outputCh = block.sumCh + } + if a512srv.totalIn == len(a512srv.lanes) { + // fmt.Println("Invoking Blocks() while FULL: ") + a512srv.blocks() + } + + // TODO: test with larger timeout + case <-time.After(1 * time.Microsecond): + for _, lane := range a512srv.lanes { + if lane.block != nil { // check if there is any input to process + // fmt.Println("Invoking Blocks() on TIMEOUT: ") + a512srv.blocks() + break // we are done + } + } + } + } +} + +// Do a reset for this calculation +func (a512srv *Avx512Server) reset(uid uint64) { + + // Check if there is a message still waiting to be processed (and remove if so) + for i, lane := range a512srv.lanes { + if lane.uid == uid { + if lane.block != nil { + a512srv.lanes[i] = Avx512LaneInfo{} // clear message + a512srv.totalIn-- + } + } + } + + // Delete entry from hash map + delete(a512srv.digests, uid) +} + +// Invoke assembly and send results back +func (a512srv *Avx512Server) blocks() (err error) { + + inputs := [16][]byte{} + for i := range inputs { + inputs[i] = a512srv.lanes[i].block + } + + mask := expandMask(genMask(inputs)) + outputs := blockAvx512(a512srv.getDigests(), inputs, mask) + + a512srv.totalIn = 0 + for i := 0; i < len(outputs); i++ { + uid, outputCh := a512srv.lanes[i].uid, a512srv.lanes[i].outputCh + a512srv.digests[uid] = outputs[i] + a512srv.lanes[i] = Avx512LaneInfo{} + + if outputCh != nil { + // Send back result + outputCh <- outputs[i] + delete(a512srv.digests, uid) // Delete entry from hashmap + } + } + return +} + +func (a512srv *Avx512Server) Write(uid uint64, p []byte) (nn int, err error) { + a512srv.blocksCh <- blockInput{uid: uid, msg: p} + return len(p), nil +} + +// Sum - return sha256 sum in bytes for a given sum id. +func (a512srv *Avx512Server) Sum(uid uint64, p []byte) [32]byte { + sumCh := make(chan [32]byte) + a512srv.blocksCh <- blockInput{uid: uid, msg: p, final: true, sumCh: sumCh} + return <-sumCh +} + +func (a512srv *Avx512Server) getDigests() *[512]byte { + digests := [512]byte{} + for i, lane := range a512srv.lanes { + a, ok := a512srv.digests[lane.uid] + if ok { + binary.BigEndian.PutUint32(digests[(i+0*16)*4:], binary.LittleEndian.Uint32(a[0:4])) + binary.BigEndian.PutUint32(digests[(i+1*16)*4:], binary.LittleEndian.Uint32(a[4:8])) + binary.BigEndian.PutUint32(digests[(i+2*16)*4:], binary.LittleEndian.Uint32(a[8:12])) + binary.BigEndian.PutUint32(digests[(i+3*16)*4:], binary.LittleEndian.Uint32(a[12:16])) + binary.BigEndian.PutUint32(digests[(i+4*16)*4:], binary.LittleEndian.Uint32(a[16:20])) + binary.BigEndian.PutUint32(digests[(i+5*16)*4:], binary.LittleEndian.Uint32(a[20:24])) + binary.BigEndian.PutUint32(digests[(i+6*16)*4:], binary.LittleEndian.Uint32(a[24:28])) + binary.BigEndian.PutUint32(digests[(i+7*16)*4:], binary.LittleEndian.Uint32(a[28:32])) + } else { + binary.LittleEndian.PutUint32(digests[(i+0*16)*4:], init0) + binary.LittleEndian.PutUint32(digests[(i+1*16)*4:], init1) + binary.LittleEndian.PutUint32(digests[(i+2*16)*4:], init2) + binary.LittleEndian.PutUint32(digests[(i+3*16)*4:], init3) + binary.LittleEndian.PutUint32(digests[(i+4*16)*4:], init4) + binary.LittleEndian.PutUint32(digests[(i+5*16)*4:], init5) + binary.LittleEndian.PutUint32(digests[(i+6*16)*4:], init6) + binary.LittleEndian.PutUint32(digests[(i+7*16)*4:], init7) + } + } + return &digests +} + +// Helper struct for sorting blocks based on length +type lane struct { + len uint + pos uint +} + +type lanes []lane + +func (lns lanes) Len() int { return len(lns) } +func (lns lanes) Swap(i, j int) { lns[i], lns[j] = lns[j], lns[i] } +func (lns lanes) Less(i, j int) bool { return lns[i].len < lns[j].len } + +// Helper struct for +type maskRounds struct { + mask uint64 + rounds uint64 +} + +func genMask(input [16][]byte) [16]maskRounds { + + // Sort on blocks length small to large + var sorted [16]lane + for c, inpt := range input { + sorted[c] = lane{uint(len(inpt)), uint(c)} + } + sort.Sort(lanes(sorted[:])) + + // Create mask array including 'rounds' between masks + m, round, index := uint64(0xffff), uint64(0), 0 + var mr [16]maskRounds + for _, s := range sorted { + if s.len > 0 { + if uint64(s.len)>>6 > round { + mr[index] = maskRounds{m, (uint64(s.len) >> 6) - round} + index++ + } + round = uint64(s.len) >> 6 + } + m = m & ^(1 << uint(s.pos)) + } + + return mr +} + +// TODO: remove function +func expandMask(mr [16]maskRounds) []uint64 { + size := uint64(0) + for _, r := range mr { + size += r.rounds + } + result, index := make([]uint64, size), 0 + for _, r := range mr { + for j := uint64(0); j < r.rounds; j++ { + result[index] = r.mask + index++ + } + } + return result +} diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s new file mode 100644 index 00000000..275bcacb --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx512_amd64.s @@ -0,0 +1,267 @@ +//+build !noasm,!appengine + +TEXT ·sha256X16Avx512(SB), 7, $0 + MOVQ digests+0(FP), DI + MOVQ scratch+8(FP), R12 + MOVQ mask_len+32(FP), SI + MOVQ mask_base+24(FP), R13 + MOVQ (R13), R14 + LONG $0x92fbc1c4; BYTE $0xce + LEAQ inputs+48(FP), AX + QUAD $0xf162076f487ef162; QUAD $0x7ef162014f6f487e; QUAD $0x487ef16202576f48; QUAD $0x6f487ef162035f6f; QUAD $0x6f6f487ef1620467; QUAD $0x06776f487ef16205; LONG $0x487ef162; WORD $0x7f6f; BYTE $0x07 + MOVQ table+16(FP), DX + WORD $0x3148; BYTE $0xc9 + TESTQ $(1<<0), R14 + JE skipInput0 + MOVQ 0*24(AX), R9 + LONG $0x487cc162; WORD $0x0410; BYTE $0x09 + +skipInput0: + TESTQ $(1<<1), R14 + JE skipInput1 + MOVQ 1*24(AX), R9 + LONG $0x487cc162; WORD $0x0c10; BYTE $0x09 + +skipInput1: + TESTQ $(1<<2), R14 + JE skipInput2 + MOVQ 2*24(AX), R9 + LONG $0x487cc162; WORD $0x1410; BYTE $0x09 + +skipInput2: + TESTQ $(1<<3), R14 + JE skipInput3 + MOVQ 3*24(AX), R9 + LONG $0x487cc162; WORD $0x1c10; BYTE $0x09 + +skipInput3: + TESTQ $(1<<4), R14 + JE skipInput4 + MOVQ 4*24(AX), R9 + LONG $0x487cc162; WORD $0x2410; BYTE $0x09 + +skipInput4: + TESTQ $(1<<5), R14 + JE skipInput5 + MOVQ 5*24(AX), R9 + LONG $0x487cc162; WORD $0x2c10; BYTE $0x09 + +skipInput5: + TESTQ $(1<<6), R14 + JE skipInput6 + MOVQ 6*24(AX), R9 + LONG $0x487cc162; WORD $0x3410; BYTE $0x09 + +skipInput6: + TESTQ $(1<<7), R14 + JE skipInput7 + MOVQ 7*24(AX), R9 + LONG $0x487cc162; WORD $0x3c10; BYTE $0x09 + +skipInput7: + TESTQ $(1<<8), R14 + JE skipInput8 + MOVQ 8*24(AX), R9 + LONG $0x487c4162; WORD $0x0410; BYTE $0x09 + +skipInput8: + TESTQ $(1<<9), R14 + JE skipInput9 + MOVQ 9*24(AX), R9 + LONG $0x487c4162; WORD $0x0c10; BYTE $0x09 + +skipInput9: + TESTQ $(1<<10), R14 + JE skipInput10 + MOVQ 10*24(AX), R9 + LONG $0x487c4162; WORD $0x1410; BYTE $0x09 + +skipInput10: + TESTQ $(1<<11), R14 + JE skipInput11 + MOVQ 11*24(AX), R9 + LONG $0x487c4162; WORD $0x1c10; BYTE $0x09 + +skipInput11: + TESTQ $(1<<12), R14 + JE skipInput12 + MOVQ 12*24(AX), R9 + LONG $0x487c4162; WORD $0x2410; BYTE $0x09 + +skipInput12: + TESTQ $(1<<13), R14 + JE skipInput13 + MOVQ 13*24(AX), R9 + LONG $0x487c4162; WORD $0x2c10; BYTE $0x09 + +skipInput13: + TESTQ $(1<<14), R14 + JE skipInput14 + MOVQ 14*24(AX), R9 + LONG $0x487c4162; WORD $0x3410; BYTE $0x09 + +skipInput14: + TESTQ $(1<<15), R14 + JE skipInput15 + MOVQ 15*24(AX), R9 + LONG $0x487c4162; WORD $0x3c10; BYTE $0x09 + +skipInput15: +lloop: + LEAQ PSHUFFLE_BYTE_FLIP_MASK<>(SB), DX + LONG $0x487e7162; WORD $0x1a6f + MOVQ table+16(FP), DX + QUAD $0xd162226f487e7162; QUAD $0x7ed16224047f487e; QUAD $0x7ed16201244c7f48; QUAD $0x7ed1620224547f48; QUAD $0x7ed16203245c7f48; QUAD $0x7ed1620424647f48; QUAD $0x7ed16205246c7f48; QUAD $0x7ed1620624747f48; QUAD $0xc1834807247c7f48; QUAD $0x44c9c6407c316240; QUAD $0x62eec1c6407ca162; QUAD $0xa16244d3c6406c31; QUAD $0x34c162eed3c6406c; QUAD $0x407ca162dddac648; QUAD $0xc6407ca16288cac6; QUAD $0xcac648345162ddc2; QUAD $0x44d5c6405ca16288; QUAD $0x62eee5c6405ca162; QUAD $0xa16244d7c6404c31; QUAD $0x6cc162eef7c6404c; QUAD $0x405ca162ddfac640; QUAD $0xc6405ca16288eec6; QUAD $0xd2c6406cc162dde6; QUAD $0x44f1c6403c816288; QUAD $0x62eec1c6403c0162; QUAD $0x016244d3c6402c11; QUAD $0x4c4162eed3c6402c; QUAD $0x403c0162dddac640; QUAD $0xc6403c016288cac6; QUAD $0xf2c6404cc162ddc2; QUAD $0x44d5c6401c016288; QUAD $0x62eee5c6401c0162; QUAD $0x016244d7c6400c11; QUAD $0x2c4162eef7c6400c; QUAD $0x401c0162ddfac640; QUAD $0xc6401c016288eec6; QUAD $0xd2c6402c4162dde6; BYTE $0x88 + LEAQ PSHUFFLE_TRANSPOSE16_MASK1<>(SB), BX + LEAQ PSHUFFLE_TRANSPOSE16_MASK2<>(SB), R8 + QUAD $0x2262336f487e6162; QUAD $0x487e5162f27648b5; QUAD $0xd27648b53262106f; QUAD $0xa262136f487ee162; QUAD $0x487e5162d77640e5; QUAD $0xcf7640e53262086f; QUAD $0xa2621b6f487ee162; QUAD $0x487ec162dd7640f5; QUAD $0xfd7640f5a262386f; QUAD $0xa2620b6f487ee162; QUAD $0x487ec162cc7640fd; QUAD $0xec7640fda262286f; QUAD $0x8262036f487ee162; QUAD $0x487ec162c27640cd; QUAD $0xe27640cd8262206f; QUAD $0x8262336f487ee162; QUAD $0x487e4162f77640a5; QUAD $0xd77640a50262106f; QUAD $0x02621b6f487e6162; QUAD $0x487e4162dd7640b5; QUAD $0xfd7640b50262386f; QUAD $0x02620b6f487e6162; QUAD $0x487e4162cc7640bd; QUAD $0xec7640bd0262286f; QUAD $0x62eec023408d2362; QUAD $0x236244c023408da3; QUAD $0xada362eee42348ad; QUAD $0x40c5036244e42348; QUAD $0x2340c51362eef723; QUAD $0xfd2340d5036244d7; QUAD $0x44fd2340d58362ee; QUAD $0x62eeea2348b50362; QUAD $0x036244ea2348b583; QUAD $0xe51362eed32340e5; QUAD $0x40f5036244cb2340; QUAD $0x2340f58362eed923; QUAD $0xce2340ed236244d9; QUAD $0x44ce2340eda362ee; QUAD $0xc162d16f487ec162; QUAD $0x407dc262f26f487e; QUAD $0xcb004075c262c300; QUAD $0xc262d300406dc262; QUAD $0x405dc262db004065; QUAD $0xeb004055c262e300; QUAD $0xc262f300404dc262; QUAD $0x403d4262fb004045; QUAD $0xcb0040354262c300; QUAD $0x4262d300402d4262; QUAD $0x401d4262db004025; QUAD $0xeb0040154262e300; QUAD $0x4262f300400d4262; QUAD $0x48455162fb004005; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d3162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6201626f487e7162; QUAD $0x916211c672481591; QUAD $0x05916213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe407dc16296ef25; QUAD $0x62c1fe407d8162c5; QUAD $0xb16207c1724815b1; QUAD $0x05b16212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe407dc16296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d3162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815916202626f48; QUAD $0x72480d916211c772; QUAD $0xd7724805916213c7; QUAD $0x96ef25480d53620a; QUAD $0x8162cdfe4075c162; QUAD $0x4815b162cafe4075; QUAD $0x72480db16207c272; QUAD $0xd2724805b16212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe4075c162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x3162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c0724815b16203; QUAD $0x6213c072480db162; QUAD $0x53620ad0724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe406d8162d5fe40; QUAD $0x07c3724815b162d3; QUAD $0x6212c372480db162; QUAD $0x536203d3724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d3162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0xb16204626f487e71; QUAD $0x0db16211c1724815; QUAD $0x4805b16213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4065c16296ef; QUAD $0xb162dcfe40658162; QUAD $0x0db16207c4724815; QUAD $0x4805b16212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4065c16296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x724815b16205626f; QUAD $0xc272480db16211c2; QUAD $0x0ad2724805b16213; QUAD $0x6296ef25480d5362; QUAD $0x5d8162e5fe405dc1; QUAD $0x724815b162e5fe40; QUAD $0xc572480db16207c5; QUAD $0x03d5724805b16212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe405dc1; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d3162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x06626f487e7162d0; QUAD $0x6211c3724815b162; QUAD $0xb16213c372480db1; QUAD $0x0d53620ad3724805; QUAD $0x4055c16296ef2548; QUAD $0xeefe40558162edfe; QUAD $0x6207c6724815b162; QUAD $0xb16212c672480db1; QUAD $0x0d536203d6724805; QUAD $0x4055c16296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d3162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x15b16207626f487e; QUAD $0x480db16211c47248; QUAD $0x724805b16213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe404dc16296; QUAD $0x15b162f7fe404d81; QUAD $0x480db16207c77248; QUAD $0x724805b16212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe404dc16296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d31; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc5724815b1620862; QUAD $0x13c572480db16211; QUAD $0x620ad5724805b162; QUAD $0xc16296ef25480d53; QUAD $0x4045a162fdfe4045; QUAD $0xc07248159162f8fe; QUAD $0x12c072480d916207; QUAD $0x6203d07248059162; QUAD $0xc16296ef25480d53; QUAD $0x48455162fdfe4045; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d1162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6209626f487e7162; QUAD $0xb16211c6724815b1; QUAD $0x05b16213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe403d416296ef25; QUAD $0x62c1fe403d2162c5; QUAD $0x916207c172481591; QUAD $0x05916212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe403d416296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d1162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815b1620a626f48; QUAD $0x72480db16211c772; QUAD $0xd7724805b16213c7; QUAD $0x96ef25480d53620a; QUAD $0x2162cdfe40354162; QUAD $0x48159162cafe4035; QUAD $0x72480d916207c272; QUAD $0xd2724805916212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe40354162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x1162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c072481591620b; QUAD $0x6213c072480d9162; QUAD $0x53620ad072480591; QUAD $0x2d416296ef25480d; QUAD $0xfe402d2162d5fe40; QUAD $0x07c37248159162d3; QUAD $0x6212c372480d9162; QUAD $0x536203d372480591; QUAD $0x2d416296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d1162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0x91620c626f487e71; QUAD $0x0d916211c1724815; QUAD $0x4805916213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4025416296ef; QUAD $0x9162dcfe40252162; QUAD $0x0d916207c4724815; QUAD $0x4805916212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4025416296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x72481591620d626f; QUAD $0xc272480d916211c2; QUAD $0x0ad2724805916213; QUAD $0x6296ef25480d5362; QUAD $0x1d2162e5fe401d41; QUAD $0x7248159162e5fe40; QUAD $0xc572480d916207c5; QUAD $0x03d5724805916212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe401d41; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d1162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x0e626f487e7162d0; QUAD $0x6211c37248159162; QUAD $0x916213c372480d91; QUAD $0x0d53620ad3724805; QUAD $0x4015416296ef2548; QUAD $0xeefe40152162edfe; QUAD $0x6207c67248159162; QUAD $0x916212c672480d91; QUAD $0x0d536203d6724805; QUAD $0x4015416296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d1162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x1591620f626f487e; QUAD $0x480d916211c47248; QUAD $0x724805916213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe400d416296; QUAD $0x159162f7fe400d21; QUAD $0x480d916207c77248; QUAD $0x724805916212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe400d416296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d11; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc572481591621062; QUAD $0x13c572480d916211; QUAD $0x620ad57248059162; QUAD $0x416296ef25480d53; QUAD $0x40050162fdfe4005; QUAD $0xc0724815b162f8fe; QUAD $0x12c072480db16207; QUAD $0x6203d0724805b162; QUAD $0x416296ef25480d53; QUAD $0x48455162fdfe4005; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d3162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6211626f487e7162; QUAD $0x916211c672481591; QUAD $0x05916213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe407dc16296ef25; QUAD $0x62c1fe407d8162c5; QUAD $0xb16207c1724815b1; QUAD $0x05b16212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe407dc16296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d3162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815916212626f48; QUAD $0x72480d916211c772; QUAD $0xd7724805916213c7; QUAD $0x96ef25480d53620a; QUAD $0x8162cdfe4075c162; QUAD $0x4815b162cafe4075; QUAD $0x72480db16207c272; QUAD $0xd2724805b16212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe4075c162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x3162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c0724815b16213; QUAD $0x6213c072480db162; QUAD $0x53620ad0724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe406d8162d5fe40; QUAD $0x07c3724815b162d3; QUAD $0x6212c372480db162; QUAD $0x536203d3724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d3162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0xb16214626f487e71; QUAD $0x0db16211c1724815; QUAD $0x4805b16213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4065c16296ef; QUAD $0xb162dcfe40658162; QUAD $0x0db16207c4724815; QUAD $0x4805b16212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4065c16296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x724815b16215626f; QUAD $0xc272480db16211c2; QUAD $0x0ad2724805b16213; QUAD $0x6296ef25480d5362; QUAD $0x5d8162e5fe405dc1; QUAD $0x724815b162e5fe40; QUAD $0xc572480db16207c5; QUAD $0x03d5724805b16212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe405dc1; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d3162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x16626f487e7162d0; QUAD $0x6211c3724815b162; QUAD $0xb16213c372480db1; QUAD $0x0d53620ad3724805; QUAD $0x4055c16296ef2548; QUAD $0xeefe40558162edfe; QUAD $0x6207c6724815b162; QUAD $0xb16212c672480db1; QUAD $0x0d536203d6724805; QUAD $0x4055c16296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d3162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x15b16217626f487e; QUAD $0x480db16211c47248; QUAD $0x724805b16213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe404dc16296; QUAD $0x15b162f7fe404d81; QUAD $0x480db16207c77248; QUAD $0x724805b16212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe404dc16296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d31; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc5724815b1621862; QUAD $0x13c572480db16211; QUAD $0x620ad5724805b162; QUAD $0xc16296ef25480d53; QUAD $0x4045a162fdfe4045; QUAD $0xc07248159162f8fe; QUAD $0x12c072480d916207; QUAD $0x6203d07248059162; QUAD $0xc16296ef25480d53; QUAD $0x48455162fdfe4045; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d1162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6219626f487e7162; QUAD $0xb16211c6724815b1; QUAD $0x05b16213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe403d416296ef25; QUAD $0x62c1fe403d2162c5; QUAD $0x916207c172481591; QUAD $0x05916212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe403d416296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d1162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815b1621a626f48; QUAD $0x72480db16211c772; QUAD $0xd7724805b16213c7; QUAD $0x96ef25480d53620a; QUAD $0x2162cdfe40354162; QUAD $0x48159162cafe4035; QUAD $0x72480d916207c272; QUAD $0xd2724805916212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe40354162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x1162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c072481591621b; QUAD $0x6213c072480d9162; QUAD $0x53620ad072480591; QUAD $0x2d416296ef25480d; QUAD $0xfe402d2162d5fe40; QUAD $0x07c37248159162d3; QUAD $0x6212c372480d9162; QUAD $0x536203d372480591; QUAD $0x2d416296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d1162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0x91621c626f487e71; QUAD $0x0d916211c1724815; QUAD $0x4805916213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4025416296ef; QUAD $0x9162dcfe40252162; QUAD $0x0d916207c4724815; QUAD $0x4805916212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4025416296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x72481591621d626f; QUAD $0xc272480d916211c2; QUAD $0x0ad2724805916213; QUAD $0x6296ef25480d5362; QUAD $0x1d2162e5fe401d41; QUAD $0x7248159162e5fe40; QUAD $0xc572480d916207c5; QUAD $0x03d5724805916212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe401d41; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d1162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x1e626f487e7162d0; QUAD $0x6211c37248159162; QUAD $0x916213c372480d91; QUAD $0x0d53620ad3724805; QUAD $0x4015416296ef2548; QUAD $0xeefe40152162edfe; QUAD $0x6207c67248159162; QUAD $0x916212c672480d91; QUAD $0x0d536203d6724805; QUAD $0x4015416296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d1162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x1591621f626f487e; QUAD $0x480d916211c47248; QUAD $0x724805916213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe400d416296; QUAD $0x159162f7fe400d21; QUAD $0x480d916207c77248; QUAD $0x724805916212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe400d416296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d11; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc572481591622062; QUAD $0x13c572480d916211; QUAD $0x620ad57248059162; QUAD $0x416296ef25480d53; QUAD $0x40050162fdfe4005; QUAD $0xc0724815b162f8fe; QUAD $0x12c072480db16207; QUAD $0x6203d0724805b162; QUAD $0x416296ef25480d53; QUAD $0x48455162fdfe4005; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d3162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6221626f487e7162; QUAD $0x916211c672481591; QUAD $0x05916213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe407dc16296ef25; QUAD $0x62c1fe407d8162c5; QUAD $0xb16207c1724815b1; QUAD $0x05b16212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe407dc16296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d3162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815916222626f48; QUAD $0x72480d916211c772; QUAD $0xd7724805916213c7; QUAD $0x96ef25480d53620a; QUAD $0x8162cdfe4075c162; QUAD $0x4815b162cafe4075; QUAD $0x72480db16207c272; QUAD $0xd2724805b16212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe4075c162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x3162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c0724815b16223; QUAD $0x6213c072480db162; QUAD $0x53620ad0724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe406d8162d5fe40; QUAD $0x07c3724815b162d3; QUAD $0x6212c372480db162; QUAD $0x536203d3724805b1; QUAD $0x6dc16296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d3162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0xb16224626f487e71; QUAD $0x0db16211c1724815; QUAD $0x4805b16213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4065c16296ef; QUAD $0xb162dcfe40658162; QUAD $0x0db16207c4724815; QUAD $0x4805b16212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4065c16296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x724815b16225626f; QUAD $0xc272480db16211c2; QUAD $0x0ad2724805b16213; QUAD $0x6296ef25480d5362; QUAD $0x5d8162e5fe405dc1; QUAD $0x724815b162e5fe40; QUAD $0xc572480db16207c5; QUAD $0x03d5724805b16212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe405dc1; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d3162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x26626f487e7162d0; QUAD $0x6211c3724815b162; QUAD $0xb16213c372480db1; QUAD $0x0d53620ad3724805; QUAD $0x4055c16296ef2548; QUAD $0xeefe40558162edfe; QUAD $0x6207c6724815b162; QUAD $0xb16212c672480db1; QUAD $0x0d536203d6724805; QUAD $0x4055c16296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d3162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x15b16227626f487e; QUAD $0x480db16211c47248; QUAD $0x724805b16213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe404dc16296; QUAD $0x15b162f7fe404d81; QUAD $0x480db16207c77248; QUAD $0x724805b16212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe404dc16296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d31; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc5724815b1622862; QUAD $0x13c572480db16211; QUAD $0x620ad5724805b162; QUAD $0xc16296ef25480d53; QUAD $0x4045a162fdfe4045; QUAD $0xc07248159162f8fe; QUAD $0x12c072480d916207; QUAD $0x6203d07248059162; QUAD $0xc16296ef25480d53; QUAD $0x48455162fdfe4045; QUAD $0xcc6f487e7162c4fe; QUAD $0x6206c472482df162; QUAD $0xf1620bc4724825f1; QUAD $0x55736219c472481d; QUAD $0x483d1162cace2548; QUAD $0xd42548255362c0fe; QUAD $0x62c1fe483d516296; QUAD $0x65d162c2fe483d51; QUAD $0x724845f162d8fe48; QUAD $0xc0724825f16202c0; QUAD $0x16c072481df1620d; QUAD $0x7362c86f487e7162; QUAD $0x25d362e8ca254875; QUAD $0x4845d16296fc2548; QUAD $0xf8fe4845d162f9fe; QUAD $0x6229626f487e7162; QUAD $0xb16211c6724815b1; QUAD $0x05b16213c672480d; QUAD $0x480d53620ad67248; QUAD $0xfe403d416296ef25; QUAD $0x62c1fe403d2162c5; QUAD $0x916207c172481591; QUAD $0x05916212c172480d; QUAD $0x480d536203d17248; QUAD $0xfe403d416296ef25; QUAD $0x62c4fe484d5162c5; QUAD $0x2df162cb6f487e71; QUAD $0x4825f16206c37248; QUAD $0x72481df1620bc372; QUAD $0xcd25485d736219c3; QUAD $0x62c1fe483d1162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xd0fe486dd162c2fe; QUAD $0x6202c772484df162; QUAD $0xf1620dc7724825f1; QUAD $0x7e716216c772481d; QUAD $0x25487d7362cf6f48; QUAD $0xf4254825d362e8c9; QUAD $0x62f1fe484dd16296; QUAD $0x7e7162f0fe484dd1; QUAD $0x4815b1622a626f48; QUAD $0x72480db16211c772; QUAD $0xd7724805b16213c7; QUAD $0x96ef25480d53620a; QUAD $0x2162cdfe40354162; QUAD $0x48159162cafe4035; QUAD $0x72480d916207c272; QUAD $0xd2724805916212c2; QUAD $0x96ef25480d536203; QUAD $0x5162cdfe40354162; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x1162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x11c072481591622b; QUAD $0x6213c072480d9162; QUAD $0x53620ad072480591; QUAD $0x2d416296ef25480d; QUAD $0xfe402d2162d5fe40; QUAD $0x07c37248159162d3; QUAD $0x6212c372480d9162; QUAD $0x536203d372480591; QUAD $0x2d416296ef25480d; QUAD $0xfe485d5162d5fe40; QUAD $0x62c96f487e7162c4; QUAD $0xf16206c172482df1; QUAD $0x1df1620bc1724825; QUAD $0x486d736219c17248; QUAD $0xfe483d1162cacb25; QUAD $0x96d42548255362c3; QUAD $0x5162c1fe483d5162; QUAD $0x487dd162c2fe483d; QUAD $0xc572485df162c0fe; QUAD $0x0dc5724825f16202; QUAD $0x6216c572481df162; QUAD $0x4d7362cd6f487e71; QUAD $0x4825d362e8cf2548; QUAD $0xfe485dd16296e425; QUAD $0x62e0fe485dd162e1; QUAD $0x91622c626f487e71; QUAD $0x0d916211c1724815; QUAD $0x4805916213c17248; QUAD $0x25480d53620ad172; QUAD $0xddfe4025416296ef; QUAD $0x9162dcfe40252162; QUAD $0x0d916207c4724815; QUAD $0x4805916212c47248; QUAD $0x25480d536203d472; QUAD $0xddfe4025416296ef; QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; QUAD $0x72481591622d626f; QUAD $0xc272480d916211c2; QUAD $0x0ad2724805916213; QUAD $0x6296ef25480d5362; QUAD $0x1d2162e5fe401d41; QUAD $0x7248159162e5fe40; QUAD $0xc572480d916207c5; QUAD $0x03d5724805916212; QUAD $0x6296ef25480d5362; QUAD $0x6d5162e5fe401d41; QUAD $0x6f487e7162c4fe48; QUAD $0x06c772482df162cf; QUAD $0x620bc7724825f162; QUAD $0x736219c772481df1; QUAD $0x3d1162cac925487d; QUAD $0x2548255362c5fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x486df162f0fe484d; QUAD $0x724825f16202c372; QUAD $0xc372481df1620dc3; QUAD $0x62cb6f487e716216; QUAD $0xd362e8cd25485d73; QUAD $0x6dd16296d4254825; QUAD $0xfe486dd162d1fe48; QUAD $0x2e626f487e7162d0; QUAD $0x6211c37248159162; QUAD $0x916213c372480d91; QUAD $0x0d53620ad3724805; QUAD $0x4015416296ef2548; QUAD $0xeefe40152162edfe; QUAD $0x6207c67248159162; QUAD $0x916212c672480d91; QUAD $0x0d536203d6724805; QUAD $0x4015416296ef2548; QUAD $0xc4fe48755162edfe; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d1162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x1591622f626f487e; QUAD $0x480d916211c47248; QUAD $0x724805916213c472; QUAD $0xef25480d53620ad4; QUAD $0x62f5fe400d416296; QUAD $0x159162f7fe400d21; QUAD $0x480d916207c77248; QUAD $0x724805916212c772; QUAD $0xef25480d536203d7; QUAD $0x62f5fe400d416296; QUAD $0x7e7162c4fe487d51; QUAD $0x72482df162cd6f48; QUAD $0xc5724825f16206c5; QUAD $0x19c572481df1620b; QUAD $0x62cacf25484d7362; QUAD $0x255362c7fe483d11; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162e0fe485dd162; QUAD $0x25f16202c172487d; QUAD $0x481df1620dc17248; QUAD $0x6f487e716216c172; QUAD $0xe8cb25486d7362c9; QUAD $0x6296c4254825d362; QUAD $0x7dd162c1fe487dd1; QUAD $0x6f487e7162c0fe48; QUAD $0xc572481591623062; QUAD $0x13c572480d916211; QUAD $0x620ad57248059162; QUAD $0x416296ef25480d53; QUAD $0x40050162fdfe4005; QUAD $0xc0724815b162f8fe; QUAD $0x12c072480db16207; QUAD $0x6203d0724805b162; QUAD $0x416296ef25480d53; QUAD $0x01ee8348fdfe4005 + JE lastLoop + ADDQ $8, R13 + MOVQ (R13), R14 + QUAD $0x7162c4fe48455162; QUAD $0x482df162cc6f487e; QUAD $0x724825f16206c472; QUAD $0xc472481df1620bc4; QUAD $0xcace254855736219; QUAD $0x5362c0fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d8fe4865d162c2; QUAD $0xf16202c0724845f1; QUAD $0x1df1620dc0724825; QUAD $0x487e716216c07248; QUAD $0xca2548757362c86f; QUAD $0x96fc254825d362e8; QUAD $0xd162f9fe4845d162; QUAD $0x487e7162f8fe4845; WORD $0x626f; BYTE $0x31 + TESTQ $(1<<0), R14 + JE skipNext0 + MOVQ 0*24(AX), R9 + LONG $0x487cc162; WORD $0x0410; BYTE $0x09 + +skipNext0: + QUAD $0x7162c4fe484d5162; QUAD $0x482df162cb6f487e; QUAD $0x724825f16206c372; QUAD $0xc372481df1620bc3; QUAD $0xcacd25485d736219; QUAD $0x5362c1fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d0fe486dd162c2; QUAD $0xf16202c772484df1; QUAD $0x1df1620dc7724825; QUAD $0x487e716216c77248; QUAD $0xc925487d7362cf6f; QUAD $0x96f4254825d362e8; QUAD $0xd162f1fe484dd162; QUAD $0x487e7162f0fe484d; WORD $0x626f; BYTE $0x32 + TESTQ $(1<<1), R14 + JE skipNext1 + MOVQ 1*24(AX), R9 + LONG $0x487cc162; WORD $0x0c10; BYTE $0x09 + +skipNext1: + QUAD $0x7162c4fe48555162; QUAD $0x482df162ca6f487e; QUAD $0x724825f16206c272; QUAD $0xc272481df1620bc2; QUAD $0xcacc254865736219; QUAD $0x5362c2fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62c8fe4875d162c2; QUAD $0xf16202c6724855f1; QUAD $0x1df1620dc6724825; QUAD $0x487e716216c67248; QUAD $0xc82548457362ce6f; QUAD $0x96ec254825d362e8; QUAD $0xd162e9fe4855d162; QUAD $0x487e7162e8fe4855; WORD $0x626f; BYTE $0x33 + TESTQ $(1<<2), R14 + JE skipNext2 + MOVQ 2*24(AX), R9 + LONG $0x487cc162; WORD $0x1410; BYTE $0x09 + +skipNext2: + QUAD $0x7162c4fe485d5162; QUAD $0x482df162c96f487e; QUAD $0x724825f16206c172; QUAD $0xc172481df1620bc1; QUAD $0xcacb25486d736219; QUAD $0x5362c3fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62c0fe487dd162c2; QUAD $0xf16202c572485df1; QUAD $0x1df1620dc5724825; QUAD $0x487e716216c57248; QUAD $0xcf25484d7362cd6f; QUAD $0x96e4254825d362e8; QUAD $0xd162e1fe485dd162; QUAD $0x487e7162e0fe485d; WORD $0x626f; BYTE $0x34 + TESTQ $(1<<3), R14 + JE skipNext3 + MOVQ 3*24(AX), R9 + LONG $0x487cc162; WORD $0x1c10; BYTE $0x09 + +skipNext3: + QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; WORD $0x626f; BYTE $0x35 + TESTQ $(1<<4), R14 + JE skipNext4 + MOVQ 4*24(AX), R9 + LONG $0x487cc162; WORD $0x2410; BYTE $0x09 + +skipNext4: + QUAD $0x7162c4fe486d5162; QUAD $0x482df162cf6f487e; QUAD $0x724825f16206c772; QUAD $0xc772481df1620bc7; QUAD $0xcac925487d736219; QUAD $0x5362c5fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f0fe484dd162c2; QUAD $0xf16202c372486df1; QUAD $0x1df1620dc3724825; QUAD $0x487e716216c37248; QUAD $0xcd25485d7362cb6f; QUAD $0x96d4254825d362e8; QUAD $0xd162d1fe486dd162; QUAD $0x487e7162d0fe486d; WORD $0x626f; BYTE $0x36 + TESTQ $(1<<5), R14 + JE skipNext5 + MOVQ 5*24(AX), R9 + LONG $0x487cc162; WORD $0x2c10; BYTE $0x09 + +skipNext5: + QUAD $0x7162c4fe48755162; QUAD $0x482df162ce6f487e; QUAD $0x724825f16206c672; QUAD $0xc672481df1620bc6; QUAD $0xcac8254845736219; QUAD $0x5362c6fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62e8fe4855d162c2; QUAD $0xf16202c2724875f1; QUAD $0x1df1620dc2724825; QUAD $0x487e716216c27248; QUAD $0xcc2548657362ca6f; QUAD $0x96cc254825d362e8; QUAD $0xd162c9fe4875d162; QUAD $0x487e7162c8fe4875; WORD $0x626f; BYTE $0x37 + TESTQ $(1<<6), R14 + JE skipNext6 + MOVQ 6*24(AX), R9 + LONG $0x487cc162; WORD $0x3410; BYTE $0x09 + +skipNext6: + QUAD $0x7162c4fe487d5162; QUAD $0x482df162cd6f487e; QUAD $0x724825f16206c572; QUAD $0xc572481df1620bc5; QUAD $0xcacf25484d736219; QUAD $0x5362c7fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62e0fe485dd162c2; QUAD $0xf16202c172487df1; QUAD $0x1df1620dc1724825; QUAD $0x487e716216c17248; QUAD $0xcb25486d7362c96f; QUAD $0x96c4254825d362e8; QUAD $0xd162c1fe487dd162; QUAD $0x487e7162c0fe487d; WORD $0x626f; BYTE $0x38 + TESTQ $(1<<7), R14 + JE skipNext7 + MOVQ 7*24(AX), R9 + LONG $0x487cc162; WORD $0x3c10; BYTE $0x09 + +skipNext7: + QUAD $0x7162c4fe48455162; QUAD $0x482df162cc6f487e; QUAD $0x724825f16206c472; QUAD $0xc472481df1620bc4; QUAD $0xcace254855736219; QUAD $0x5362c0fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d8fe4865d162c2; QUAD $0xf16202c0724845f1; QUAD $0x1df1620dc0724825; QUAD $0x487e716216c07248; QUAD $0xca2548757362c86f; QUAD $0x96fc254825d362e8; QUAD $0xd162f9fe4845d162; QUAD $0x487e7162f8fe4845; WORD $0x626f; BYTE $0x39 + TESTQ $(1<<8), R14 + JE skipNext8 + MOVQ 8*24(AX), R9 + LONG $0x487c4162; WORD $0x0410; BYTE $0x09 + +skipNext8: + QUAD $0x7162c4fe484d5162; QUAD $0x482df162cb6f487e; QUAD $0x724825f16206c372; QUAD $0xc372481df1620bc3; QUAD $0xcacd25485d736219; QUAD $0x5362c1fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d0fe486dd162c2; QUAD $0xf16202c772484df1; QUAD $0x1df1620dc7724825; QUAD $0x487e716216c77248; QUAD $0xc925487d7362cf6f; QUAD $0x96f4254825d362e8; QUAD $0xd162f1fe484dd162; QUAD $0x487e7162f0fe484d; WORD $0x626f; BYTE $0x3a + TESTQ $(1<<9), R14 + JE skipNext9 + MOVQ 9*24(AX), R9 + LONG $0x487c4162; WORD $0x0c10; BYTE $0x09 + +skipNext9: + QUAD $0x7162c4fe48555162; QUAD $0x482df162ca6f487e; QUAD $0x724825f16206c272; QUAD $0xc272481df1620bc2; QUAD $0xcacc254865736219; QUAD $0x5362c2fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62c8fe4875d162c2; QUAD $0xf16202c6724855f1; QUAD $0x1df1620dc6724825; QUAD $0x487e716216c67248; QUAD $0xc82548457362ce6f; QUAD $0x96ec254825d362e8; QUAD $0xd162e9fe4855d162; QUAD $0x487e7162e8fe4855; WORD $0x626f; BYTE $0x3b + TESTQ $(1<<10), R14 + JE skipNext10 + MOVQ 10*24(AX), R9 + LONG $0x487c4162; WORD $0x1410; BYTE $0x09 + +skipNext10: + QUAD $0x7162c4fe485d5162; QUAD $0x482df162c96f487e; QUAD $0x724825f16206c172; QUAD $0xc172481df1620bc1; QUAD $0xcacb25486d736219; QUAD $0x5362c3fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62c0fe487dd162c2; QUAD $0xf16202c572485df1; QUAD $0x1df1620dc5724825; QUAD $0x487e716216c57248; QUAD $0xcf25484d7362cd6f; QUAD $0x96e4254825d362e8; QUAD $0xd162e1fe485dd162; QUAD $0x487e7162e0fe485d; WORD $0x626f; BYTE $0x3c + TESTQ $(1<<11), R14 + JE skipNext11 + MOVQ 11*24(AX), R9 + LONG $0x487c4162; WORD $0x1c10; BYTE $0x09 + +skipNext11: + QUAD $0x7162c4fe48655162; QUAD $0x482df162c86f487e; QUAD $0x724825f16206c072; QUAD $0xc072481df1620bc0; QUAD $0xcaca254875736219; QUAD $0x5362c4fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f8fe4845d162c2; QUAD $0xf16202c4724865f1; QUAD $0x1df1620dc4724825; QUAD $0x487e716216c47248; QUAD $0xce2548557362cc6f; QUAD $0x96dc254825d362e8; QUAD $0xd162d9fe4865d162; QUAD $0x487e7162d8fe4865; WORD $0x626f; BYTE $0x3d + TESTQ $(1<<12), R14 + JE skipNext12 + MOVQ 12*24(AX), R9 + LONG $0x487c4162; WORD $0x2410; BYTE $0x09 + +skipNext12: + QUAD $0x7162c4fe486d5162; QUAD $0x482df162cf6f487e; QUAD $0x724825f16206c772; QUAD $0xc772481df1620bc7; QUAD $0xcac925487d736219; QUAD $0x5362c5fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62f0fe484dd162c2; QUAD $0xf16202c372486df1; QUAD $0x1df1620dc3724825; QUAD $0x487e716216c37248; QUAD $0xcd25485d7362cb6f; QUAD $0x96d4254825d362e8; QUAD $0xd162d1fe486dd162; QUAD $0x487e7162d0fe486d; WORD $0x626f; BYTE $0x3e + TESTQ $(1<<13), R14 + JE skipNext13 + MOVQ 13*24(AX), R9 + LONG $0x487c4162; WORD $0x2c10; BYTE $0x09 + +skipNext13: + QUAD $0x7162c4fe48755162; QUAD $0x482df162ce6f487e; QUAD $0x724825f16206c672; QUAD $0xc672481df1620bc6; QUAD $0xcac8254845736219; QUAD $0x5362c6fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62e8fe4855d162c2; QUAD $0xf16202c2724875f1; QUAD $0x1df1620dc2724825; QUAD $0x487e716216c27248; QUAD $0xcc2548657362ca6f; QUAD $0x96cc254825d362e8; QUAD $0xd162c9fe4875d162; QUAD $0x487e7162c8fe4875; WORD $0x626f; BYTE $0x3f + TESTQ $(1<<14), R14 + JE skipNext14 + MOVQ 14*24(AX), R9 + LONG $0x487c4162; WORD $0x3410; BYTE $0x09 + +skipNext14: + QUAD $0x7162c4fe487d5162; QUAD $0x482df162cd6f487e; QUAD $0x724825f16206c572; QUAD $0xc572481df1620bc5; QUAD $0xcacf25484d736219; QUAD $0x5362c7fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62e0fe485dd162c2; QUAD $0xf16202c172487df1; QUAD $0x1df1620dc1724825; QUAD $0x487e716216c17248; QUAD $0xcb25486d7362c96f; QUAD $0x96c4254825d362e8; QUAD $0xd162c1fe487dd162; QUAD $0x487e7162c0fe487d; WORD $0x626f; BYTE $0x40 + TESTQ $(1<<15), R14 + JE skipNext15 + MOVQ 15*24(AX), R9 + LONG $0x487c4162; WORD $0x3c10; BYTE $0x09 + +skipNext15: + QUAD $0xd162d86f487e7162; QUAD $0x7dd16224046f487e; QUAD $0x6f487e7162c3fe49; QUAD $0x244c6f487ed162d9; QUAD $0x62cbfe4975d16201; QUAD $0x7ed162da6f487e71; QUAD $0x6dd1620224546f48; QUAD $0x6f487e7162d3fe49; QUAD $0x245c6f487ed162db; QUAD $0x62dbfe4965d16203; QUAD $0x7ed162dc6f487e71; QUAD $0x5dd1620424646f48; QUAD $0x6f487e7162e3fe49; QUAD $0x246c6f487ed162dd; QUAD $0x62ebfe4955d16205; QUAD $0x7ed162de6f487e71; QUAD $0x4dd1620624746f48; QUAD $0x6f487e7162f3fe49; QUAD $0x247c6f487ed162df; QUAD $0xc4fbfe4945d16207; LONG $0xce92fbc1 + JMP lloop + +lastLoop: + QUAD $0x7162c4fe48455162; QUAD $0x482df162cc6f487e; QUAD $0x724825f16206c472; QUAD $0xc472481df1620bc4; QUAD $0xcace254855736219; QUAD $0x5362c0fe483d3162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d8fe4865d162c2; QUAD $0xf16202c0724845f1; QUAD $0x1df1620dc0724825; QUAD $0x487e716216c07248; QUAD $0xca2548757362c86f; QUAD $0x96fc254825d362e8; QUAD $0xd162f9fe4845d162; QUAD $0x487e7162f8fe4845; QUAD $0xfe484d516231626f; QUAD $0x62cb6f487e7162c4; QUAD $0xf16206c372482df1; QUAD $0x1df1620bc3724825; QUAD $0x485d736219c37248; QUAD $0xfe483d3162cacd25; QUAD $0x96d42548255362c1; QUAD $0x5162c1fe483d5162; QUAD $0x486dd162c2fe483d; QUAD $0xc772484df162d0fe; QUAD $0x0dc7724825f16202; QUAD $0x6216c772481df162; QUAD $0x7d7362cf6f487e71; QUAD $0x4825d362e8c92548; QUAD $0xfe484dd16296f425; QUAD $0x62f0fe484dd162f1; QUAD $0x516232626f487e71; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x3162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x62c4fe485d516233; QUAD $0x2df162c96f487e71; QUAD $0x4825f16206c17248; QUAD $0x72481df1620bc172; QUAD $0xcb25486d736219c1; QUAD $0x62c3fe483d3162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xc0fe487dd162c2fe; QUAD $0x6202c572485df162; QUAD $0xf1620dc5724825f1; QUAD $0x7e716216c572481d; QUAD $0x25484d7362cd6f48; QUAD $0xe4254825d362e8cf; QUAD $0x62e1fe485dd16296; QUAD $0x7e7162e0fe485dd1; QUAD $0x4865516234626f48; QUAD $0xc86f487e7162c4fe; QUAD $0x6206c072482df162; QUAD $0xf1620bc0724825f1; QUAD $0x75736219c072481d; QUAD $0x483d3162caca2548; QUAD $0xd42548255362c4fe; QUAD $0x62c1fe483d516296; QUAD $0x45d162c2fe483d51; QUAD $0x724865f162f8fe48; QUAD $0xc4724825f16202c4; QUAD $0x16c472481df1620d; QUAD $0x7362cc6f487e7162; QUAD $0x25d362e8ce254855; QUAD $0x4865d16296dc2548; QUAD $0xd8fe4865d162d9fe; QUAD $0x6235626f487e7162; QUAD $0x7e7162c4fe486d51; QUAD $0x72482df162cf6f48; QUAD $0xc7724825f16206c7; QUAD $0x19c772481df1620b; QUAD $0x62cac925487d7362; QUAD $0x255362c5fe483d31; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162f0fe484dd162; QUAD $0x25f16202c372486d; QUAD $0x481df1620dc37248; QUAD $0x6f487e716216c372; QUAD $0xe8cd25485d7362cb; QUAD $0x6296d4254825d362; QUAD $0x6dd162d1fe486dd1; QUAD $0x6f487e7162d0fe48; QUAD $0xc4fe487551623662; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d3162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x7d516237626f487e; QUAD $0x6f487e7162c4fe48; QUAD $0x06c572482df162cd; QUAD $0x620bc5724825f162; QUAD $0x736219c572481df1; QUAD $0x3d3162cacf25484d; QUAD $0x2548255362c7fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x487df162e0fe485d; QUAD $0x724825f16202c172; QUAD $0xc172481df1620dc1; QUAD $0x62c96f487e716216; QUAD $0xd362e8cb25486d73; QUAD $0x7dd16296c4254825; QUAD $0xfe487dd162c1fe48; QUAD $0x38626f487e7162c0; QUAD $0x7162c4fe48455162; QUAD $0x482df162cc6f487e; QUAD $0x724825f16206c472; QUAD $0xc472481df1620bc4; QUAD $0xcace254855736219; QUAD $0x5362c0fe483d1162; QUAD $0x3d516296d4254825; QUAD $0xfe483d5162c1fe48; QUAD $0x62d8fe4865d162c2; QUAD $0xf16202c0724845f1; QUAD $0x1df1620dc0724825; QUAD $0x487e716216c07248; QUAD $0xca2548757362c86f; QUAD $0x96fc254825d362e8; QUAD $0xd162f9fe4845d162; QUAD $0x487e7162f8fe4845; QUAD $0xfe484d516239626f; QUAD $0x62cb6f487e7162c4; QUAD $0xf16206c372482df1; QUAD $0x1df1620bc3724825; QUAD $0x485d736219c37248; QUAD $0xfe483d1162cacd25; QUAD $0x96d42548255362c1; QUAD $0x5162c1fe483d5162; QUAD $0x486dd162c2fe483d; QUAD $0xc772484df162d0fe; QUAD $0x0dc7724825f16202; QUAD $0x6216c772481df162; QUAD $0x7d7362cf6f487e71; QUAD $0x4825d362e8c92548; QUAD $0xfe484dd16296f425; QUAD $0x62f0fe484dd162f1; QUAD $0x51623a626f487e71; QUAD $0x487e7162c4fe4855; QUAD $0xc272482df162ca6f; QUAD $0x0bc2724825f16206; QUAD $0x6219c272481df162; QUAD $0x1162cacc25486573; QUAD $0x48255362c2fe483d; QUAD $0xfe483d516296d425; QUAD $0x62c2fe483d5162c1; QUAD $0x55f162c8fe4875d1; QUAD $0x4825f16202c67248; QUAD $0x72481df1620dc672; QUAD $0xce6f487e716216c6; QUAD $0x62e8c82548457362; QUAD $0xd16296ec254825d3; QUAD $0x4855d162e9fe4855; QUAD $0x626f487e7162e8fe; QUAD $0x62c4fe485d51623b; QUAD $0x2df162c96f487e71; QUAD $0x4825f16206c17248; QUAD $0x72481df1620bc172; QUAD $0xcb25486d736219c1; QUAD $0x62c3fe483d1162ca; QUAD $0x516296d425482553; QUAD $0x483d5162c1fe483d; QUAD $0xc0fe487dd162c2fe; QUAD $0x6202c572485df162; QUAD $0xf1620dc5724825f1; QUAD $0x7e716216c572481d; QUAD $0x25484d7362cd6f48; QUAD $0xe4254825d362e8cf; QUAD $0x62e1fe485dd16296; QUAD $0x7e7162e0fe485dd1; QUAD $0x486551623c626f48; QUAD $0xc86f487e7162c4fe; QUAD $0x6206c072482df162; QUAD $0xf1620bc0724825f1; QUAD $0x75736219c072481d; QUAD $0x483d1162caca2548; QUAD $0xd42548255362c4fe; QUAD $0x62c1fe483d516296; QUAD $0x45d162c2fe483d51; QUAD $0x724865f162f8fe48; QUAD $0xc4724825f16202c4; QUAD $0x16c472481df1620d; QUAD $0x7362cc6f487e7162; QUAD $0x25d362e8ce254855; QUAD $0x4865d16296dc2548; QUAD $0xd8fe4865d162d9fe; QUAD $0x623d626f487e7162; QUAD $0x7e7162c4fe486d51; QUAD $0x72482df162cf6f48; QUAD $0xc7724825f16206c7; QUAD $0x19c772481df1620b; QUAD $0x62cac925487d7362; QUAD $0x255362c5fe483d11; QUAD $0x483d516296d42548; QUAD $0xc2fe483d5162c1fe; QUAD $0xf162f0fe484dd162; QUAD $0x25f16202c372486d; QUAD $0x481df1620dc37248; QUAD $0x6f487e716216c372; QUAD $0xe8cd25485d7362cb; QUAD $0x6296d4254825d362; QUAD $0x6dd162d1fe486dd1; QUAD $0x6f487e7162d0fe48; QUAD $0xc4fe487551623e62; QUAD $0xf162ce6f487e7162; QUAD $0x25f16206c672482d; QUAD $0x481df1620bc67248; QUAD $0x254845736219c672; QUAD $0xc6fe483d1162cac8; QUAD $0x6296d42548255362; QUAD $0x3d5162c1fe483d51; QUAD $0xfe4855d162c2fe48; QUAD $0x02c2724875f162e8; QUAD $0x620dc2724825f162; QUAD $0x716216c272481df1; QUAD $0x48657362ca6f487e; QUAD $0x254825d362e8cc25; QUAD $0xc9fe4875d16296cc; QUAD $0x7162c8fe4875d162; QUAD $0x7d51623f626f487e; QUAD $0x6f487e7162c4fe48; QUAD $0x06c572482df162cd; QUAD $0x620bc5724825f162; QUAD $0x736219c572481df1; QUAD $0x3d1162cacf25484d; QUAD $0x2548255362c7fe48; QUAD $0xc1fe483d516296d4; QUAD $0xd162c2fe483d5162; QUAD $0x487df162e0fe485d; QUAD $0x724825f16202c172; QUAD $0xc172481df1620dc1; QUAD $0x62c96f487e716216; QUAD $0xd362e8cb25486d73; QUAD $0x7dd16296c4254825; QUAD $0xfe487dd162c1fe48; QUAD $0x40626f487e7162c0; QUAD $0xd162d86f487e7162; QUAD $0x7dd16224046f487e; QUAD $0x6f487e7162c3fe49; QUAD $0x244c6f487ed162d9; QUAD $0x62cbfe4975d16201; QUAD $0x7ed162da6f487e71; QUAD $0x6dd1620224546f48; QUAD $0x6f487e7162d3fe49; QUAD $0x245c6f487ed162db; QUAD $0x62dbfe4965d16203; QUAD $0x7ed162dc6f487e71; QUAD $0x5dd1620424646f48; QUAD $0x6f487e7162e3fe49; QUAD $0x246c6f487ed162dd; QUAD $0x62ebfe4955d16205; QUAD $0x7ed162de6f487e71; QUAD $0x4dd1620624746f48; QUAD $0x6f487e7162f3fe49; QUAD $0x247c6f487ed162df; QUAD $0x62fbfe4945d16207; QUAD $0x7ef162077f487ef1; QUAD $0x487ef162014f7f48; QUAD $0x7f487ef16202577f; QUAD $0x677f487ef162035f; QUAD $0x056f7f487ef16204; QUAD $0x6206777f487ef162; LONG $0x7f487ef1; WORD $0x077f + VZEROUPPER + RET + +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x000(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x008(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x010(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x018(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x020(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x028(SB)/8, $0x0c0d0e0f08090a0b +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x030(SB)/8, $0x0405060700010203 +DATA PSHUFFLE_BYTE_FLIP_MASK<>+0x038(SB)/8, $0x0c0d0e0f08090a0b +GLOBL PSHUFFLE_BYTE_FLIP_MASK<>(SB), 8, $64 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x000(SB)/8, $0x0000000000000000 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x008(SB)/8, $0x0000000000000001 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x010(SB)/8, $0x0000000000000008 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x018(SB)/8, $0x0000000000000009 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x020(SB)/8, $0x0000000000000004 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x028(SB)/8, $0x0000000000000005 +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x030(SB)/8, $0x000000000000000C +DATA PSHUFFLE_TRANSPOSE16_MASK1<>+0x038(SB)/8, $0x000000000000000D +GLOBL PSHUFFLE_TRANSPOSE16_MASK1<>(SB), 8, $64 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x000(SB)/8, $0x0000000000000002 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x008(SB)/8, $0x0000000000000003 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x010(SB)/8, $0x000000000000000A +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x018(SB)/8, $0x000000000000000B +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x020(SB)/8, $0x0000000000000006 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x028(SB)/8, $0x0000000000000007 +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x030(SB)/8, $0x000000000000000E +DATA PSHUFFLE_TRANSPOSE16_MASK2<>+0x038(SB)/8, $0x000000000000000F +GLOBL PSHUFFLE_TRANSPOSE16_MASK2<>(SB), 8, $64 diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go b/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go new file mode 100644 index 00000000..eb8a0ff0 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.go @@ -0,0 +1,22 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +//go:noescape +func blockAvx(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64) diff --git a/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s b/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s new file mode 100644 index 00000000..9f444d49 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockAvx_amd64.s @@ -0,0 +1,408 @@ +//+build !noasm,!appengine + +// SHA256 implementation for AVX + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// This code is based on an Intel White-Paper: +// "Fast SHA-256 Implementations on Intel Architecture Processors" +// +// together with the reference implementation from the following authors: +// James Guilford +// Kirk Yap +// Tim Chen +// +// For Golang it has been converted to Plan 9 assembly with the help of +// github.com/minio/asm2plan9s to assemble Intel instructions to their Plan9 +// equivalents +// + +#include "textflag.h" + +#define ROTATE_XS \ + MOVOU X4, X15 \ + MOVOU X5, X4 \ + MOVOU X6, X5 \ + MOVOU X7, X6 \ + MOVOU X15, X7 + +// compute s0 four at a time and s1 two at a time +// compute W[-16] + W[-7] 4 at a time +#define FOUR_ROUNDS_AND_SCHED(a, b, c, d, e, f, g, h) \ + MOVL e, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL a, R14 \ // y1 = a + LONG $0x0f41e3c4; WORD $0x04c6 \ // VPALIGNR XMM0,XMM7,XMM6,0x4 /* XTMP0 = W[-7] */ + ROLL $23, R14 \ // y1 = a >> (22-13) + XORL e, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL f, R15 \ // y2 = f + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL a, R14 \ // y1 = a ^ (a >> (22-13) + XORL g, R15 \ // y2 = f^g + LONG $0xc4fef9c5 \ // VPADDD XMM0,XMM0,XMM4 /* XTMP0 = W[-7] + W[-16] */ + XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6) ) + ANDL e, R15 \ // y2 = (f^g)&e + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + \ + \ // compute s0 + \ + LONG $0x0f51e3c4; WORD $0x04cc \ // VPALIGNR XMM1,XMM5,XMM4,0x4 /* XTMP1 = W[-15] */ + XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL g, R15 \ // y2 = CH = ((f^g)&e)^g + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+48(FP), R15 \ // y2 = k + w + S1 + CH + MOVL a, R13 \ // y0 = a + ADDL R15, h \ // h = h + S1 + CH + k + w + \ // ROTATE_ARGS + MOVL a, R15 \ // y2 = a + LONG $0xd172e9c5; BYTE $0x07 \ // VPSRLD XMM2,XMM1,0x7 /* */ + ORL c, R13 \ // y0 = a|c + ADDL h, d \ // d = d + h + S1 + CH + k + w + ANDL c, R15 \ // y2 = a&c + LONG $0xf172e1c5; BYTE $0x19 \ // VPSLLD XMM3,XMM1,0x19 /* */ + ANDL b, R13 \ // y0 = (a|c)&b + ADDL R14, h \ // h = h + S1 + CH + k + w + S0 + LONG $0xdaebe1c5 \ // VPOR XMM3,XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, h \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL d, R13 \ // y0 = e + MOVL h, R14 \ // y1 = a + ROLL $18, R13 \ // y0 = e >> (25-11) + XORL d, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL e, R15 \ // y2 = f + ROLL $23, R14 \ // y1 = a >> (22-13) + LONG $0xd172e9c5; BYTE $0x12 \ // VPSRLD XMM2,XMM1,0x12 /* */ + XORL h, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL f, R15 \ // y2 = f^g + LONG $0xd172b9c5; BYTE $0x03 \ // VPSRLD XMM8,XMM1,0x3 /* XTMP4 = W[-15] >> 3 */ + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + XORL d, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL d, R15 \ // y2 = (f^g)&e + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + LONG $0xf172f1c5; BYTE $0x0e \ // VPSLLD XMM1,XMM1,0xe /* */ + XORL h, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + XORL f, R15 \ // y2 = CH = ((f^g)&e)^g + LONG $0xd9efe1c5 \ // VPXOR XMM3,XMM3,XMM1 /* */ + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+52(FP), R15 \ // y2 = k + w + S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + LONG $0xdaefe1c5 \ // VPXOR XMM3,XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR */ + MOVL h, R13 \ // y0 = a + ADDL R15, g \ // h = h + S1 + CH + k + w + MOVL h, R15 \ // y2 = a + LONG $0xef61c1c4; BYTE $0xc8 \ // VPXOR XMM1,XMM3,XMM8 /* XTMP1 = s0 */ + ORL b, R13 \ // y0 = a|c + ADDL g, c \ // d = d + h + S1 + CH + k + w + ANDL b, R15 \ // y2 = a&c + \ + \ // compute low s1 + \ + LONG $0xd770f9c5; BYTE $0xfa \ // VPSHUFD XMM2,XMM7,0xfa /* XTMP2 = W[-2] {BBAA} */ + ANDL a, R13 \ // y0 = (a|c)&b + ADDL R14, g \ // h = h + S1 + CH + k + w + S0 + LONG $0xc1fef9c5 \ // VPADDD XMM0,XMM0,XMM1 /* XTMP0 = W[-16] + W[-7] + s0 */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, g \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL c, R13 \ // y0 = e + MOVL g, R14 \ // y1 = a + ROLL $18, R13 \ // y0 = e >> (25-11) + XORL c, R13 \ // y0 = e ^ (e >> (25-11)) + ROLL $23, R14 \ // y1 = a >> (22-13) + MOVL d, R15 \ // y2 = f + XORL g, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + LONG $0xd272b9c5; BYTE $0x0a \ // VPSRLD XMM8,XMM2,0xa /* XTMP4 = W[-2] >> 10 {BBAA} */ + XORL e, R15 \ // y2 = f^g + LONG $0xd273e1c5; BYTE $0x13 \ // VPSRLQ XMM3,XMM2,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */ + XORL c, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL c, R15 \ // y2 = (f^g)&e + LONG $0xd273e9c5; BYTE $0x11 \ // VPSRLQ XMM2,XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */ + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + XORL g, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + XORL e, R15 \ // y2 = CH = ((f^g)&e)^g + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + LONG $0xd3efe9c5 \ // VPXOR XMM2,XMM2,XMM3 /* */ + ADDL R13, R15 \ // y2 = S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL _xfer+56(FP), R15 \ // y2 = k + w + S1 + CH + LONG $0xc2ef39c5 \ // VPXOR XMM8,XMM8,XMM2 /* XTMP4 = s1 {xBxA} */ + MOVL g, R13 \ // y0 = a + ADDL R15, f \ // h = h + S1 + CH + k + w + MOVL g, R15 \ // y2 = a + LONG $0x003942c4; BYTE $0xc2 \ // VPSHUFB XMM8,XMM8,XMM10 /* XTMP4 = s1 {00BA} */ + ORL a, R13 \ // y0 = a|c + ADDL f, b \ // d = d + h + S1 + CH + k + w + ANDL a, R15 \ // y2 = a&c + LONG $0xfe79c1c4; BYTE $0xc0 \ // VPADDD XMM0,XMM0,XMM8 /* XTMP0 = {..., ..., W[1], W[0]} */ + ANDL h, R13 \ // y0 = (a|c)&b + ADDL R14, f \ // h = h + S1 + CH + k + w + S0 + \ + \ // compute high s1 + \ + LONG $0xd070f9c5; BYTE $0x50 \ // VPSHUFD XMM2,XMM0,0x50 /* XTMP2 = W[-2] {DDCC} */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, f \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL b, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL f, R14 \ // y1 = a + ROLL $23, R14 \ // y1 = a >> (22-13) + XORL b, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL c, R15 \ // y2 = f + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + LONG $0xd272a1c5; BYTE $0x0a \ // VPSRLD XMM11,XMM2,0xa /* XTMP5 = W[-2] >> 10 {DDCC} */ + XORL f, R14 \ // y1 = a ^ (a >> (22-13) + XORL d, R15 \ // y2 = f^g + LONG $0xd273e1c5; BYTE $0x13 \ // VPSRLQ XMM3,XMM2,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */ + XORL b, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL b, R15 \ // y2 = (f^g)&e + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + LONG $0xd273e9c5; BYTE $0x11 \ // VPSRLQ XMM2,XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */ + XORL f, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL d, R15 \ // y2 = CH = ((f^g)&e)^g + LONG $0xd3efe9c5 \ // VPXOR XMM2,XMM2,XMM3 /* */ + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+60(FP), R15 \ // y2 = k + w + S1 + CH + LONG $0xdaef21c5 \ // VPXOR XMM11,XMM11,XMM2 /* XTMP5 = s1 {xDxC} */ + MOVL f, R13 \ // y0 = a + ADDL R15, e \ // h = h + S1 + CH + k + w + MOVL f, R15 \ // y2 = a + LONG $0x002142c4; BYTE $0xdc \ // VPSHUFB XMM11,XMM11,XMM12 /* XTMP5 = s1 {DC00} */ + ORL h, R13 \ // y0 = a|c + ADDL e, a \ // d = d + h + S1 + CH + k + w + ANDL h, R15 \ // y2 = a&c + LONG $0xe0fea1c5 \ // VPADDD XMM4,XMM11,XMM0 /* X0 = {W[3], W[2], W[1], W[0]} */ + ANDL g, R13 \ // y0 = (a|c)&b + ADDL R14, e \ // h = h + S1 + CH + k + w + S0 + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, e \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + ROTATE_XS + +#define DO_ROUND(a, b, c, d, e, f, g, h, offset) \ + MOVL e, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL a, R14 \ // y1 = a + XORL e, R13 \ // y0 = e ^ (e >> (25-11)) + ROLL $23, R14 \ // y1 = a >> (22-13) + MOVL f, R15 \ // y2 = f + XORL a, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL g, R15 \ // y2 = f^g + XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + ANDL e, R15 \ // y2 = (f^g)&e + XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL g, R15 \ // y2 = CH = ((f^g)&e)^g + ADDL R13, R15 \ // y2 = S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL _xfer+offset(FP), R15 \ // y2 = k + w + S1 + CH + MOVL a, R13 \ // y0 = a + ADDL R15, h \ // h = h + S1 + CH + k + w + MOVL a, R15 \ // y2 = a + ORL c, R13 \ // y0 = a|c + ADDL h, d \ // d = d + h + S1 + CH + k + w + ANDL c, R15 \ // y2 = a&c + ANDL b, R13 \ // y0 = (a|c)&b + ADDL R14, h \ // h = h + S1 + CH + k + w + S0 + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, h // h = h + S1 + CH + k + w + S0 + MAJ + +// func blockAvx(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64) +TEXT ·blockAvx(SB), 7, $0-80 + + MOVQ h+0(FP), SI // SI: &h + MOVQ message_base+24(FP), R8 // &message + MOVQ message_len+32(FP), R9 // length of message + CMPQ R9, $0 + JEQ done_hash + ADDQ R8, R9 + MOVQ R9, reserved2+64(FP) // store end of message + + // Register definition + // a --> eax + // b --> ebx + // c --> ecx + // d --> r8d + // e --> edx + // f --> r9d + // g --> r10d + // h --> r11d + // + // y0 --> r13d + // y1 --> r14d + // y2 --> r15d + + MOVL (0*4)(SI), AX // a = H0 + MOVL (1*4)(SI), BX // b = H1 + MOVL (2*4)(SI), CX // c = H2 + MOVL (3*4)(SI), R8 // d = H3 + MOVL (4*4)(SI), DX // e = H4 + MOVL (5*4)(SI), R9 // f = H5 + MOVL (6*4)(SI), R10 // g = H6 + MOVL (7*4)(SI), R11 // h = H7 + + MOVOU bflipMask<>(SB), X13 + MOVOU shuf00BA<>(SB), X10 // shuffle xBxA -> 00BA + MOVOU shufDC00<>(SB), X12 // shuffle xDxC -> DC00 + + MOVQ message_base+24(FP), SI // SI: &message + +loop0: + LEAQ constants<>(SB), BP + + // byte swap first 16 dwords + MOVOU 0*16(SI), X4 + LONG $0x0059c2c4; BYTE $0xe5 // VPSHUFB XMM4, XMM4, XMM13 + MOVOU 1*16(SI), X5 + LONG $0x0051c2c4; BYTE $0xed // VPSHUFB XMM5, XMM5, XMM13 + MOVOU 2*16(SI), X6 + LONG $0x0049c2c4; BYTE $0xf5 // VPSHUFB XMM6, XMM6, XMM13 + MOVOU 3*16(SI), X7 + LONG $0x0041c2c4; BYTE $0xfd // VPSHUFB XMM7, XMM7, XMM13 + + MOVQ SI, reserved3+72(FP) + MOVD $0x3, DI + + // schedule 48 input dwords, by doing 3 rounds of 16 each +loop1: + LONG $0x4dfe59c5; BYTE $0x00 // VPADDD XMM9, XMM4, 0[RBP] /* Add 1st constant to first part of message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11) + + LONG $0x4dfe59c5; BYTE $0x10 // VPADDD XMM9, XMM4, 16[RBP] /* Add 2nd constant to message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8) + + LONG $0x4dfe59c5; BYTE $0x20 // VPADDD XMM9, XMM4, 32[RBP] /* Add 3rd constant to message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11) + + LONG $0x4dfe59c5; BYTE $0x30 // VPADDD XMM9, XMM4, 48[RBP] /* Add 4th constant to message */ + MOVOU X9, reserved0+48(FP) + ADDQ $64, BP + FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8) + + SUBQ $1, DI + JNE loop1 + + MOVD $0x2, DI + +loop2: + LONG $0x4dfe59c5; BYTE $0x00 // VPADDD XMM9, XMM4, 0[RBP] /* Add 1st constant to first part of message */ + MOVOU X9, reserved0+48(FP) + DO_ROUND( AX, BX, CX, R8, DX, R9, R10, R11, 48) + DO_ROUND(R11, AX, BX, CX, R8, DX, R9, R10, 52) + DO_ROUND(R10, R11, AX, BX, CX, R8, DX, R9, 56) + DO_ROUND( R9, R10, R11, AX, BX, CX, R8, DX, 60) + + LONG $0x4dfe51c5; BYTE $0x10 // VPADDD XMM9, XMM5, 16[RBP] /* Add 2nd constant to message */ + MOVOU X9, reserved0+48(FP) + ADDQ $32, BP + DO_ROUND( DX, R9, R10, R11, AX, BX, CX, R8, 48) + DO_ROUND( R8, DX, R9, R10, R11, AX, BX, CX, 52) + DO_ROUND( CX, R8, DX, R9, R10, R11, AX, BX, 56) + DO_ROUND( BX, CX, R8, DX, R9, R10, R11, AX, 60) + + MOVOU X6, X4 + MOVOU X7, X5 + + SUBQ $1, DI + JNE loop2 + + MOVQ h+0(FP), SI // SI: &h + ADDL (0*4)(SI), AX // H0 = a + H0 + MOVL AX, (0*4)(SI) + ADDL (1*4)(SI), BX // H1 = b + H1 + MOVL BX, (1*4)(SI) + ADDL (2*4)(SI), CX // H2 = c + H2 + MOVL CX, (2*4)(SI) + ADDL (3*4)(SI), R8 // H3 = d + H3 + MOVL R8, (3*4)(SI) + ADDL (4*4)(SI), DX // H4 = e + H4 + MOVL DX, (4*4)(SI) + ADDL (5*4)(SI), R9 // H5 = f + H5 + MOVL R9, (5*4)(SI) + ADDL (6*4)(SI), R10 // H6 = g + H6 + MOVL R10, (6*4)(SI) + ADDL (7*4)(SI), R11 // H7 = h + H7 + MOVL R11, (7*4)(SI) + + MOVQ reserved3+72(FP), SI + ADDQ $64, SI + CMPQ reserved2+64(FP), SI + JNE loop0 + +done_hash: + RET + +// Constants table +DATA constants<>+0x0(SB)/8, $0x71374491428a2f98 +DATA constants<>+0x8(SB)/8, $0xe9b5dba5b5c0fbcf +DATA constants<>+0x10(SB)/8, $0x59f111f13956c25b +DATA constants<>+0x18(SB)/8, $0xab1c5ed5923f82a4 +DATA constants<>+0x20(SB)/8, $0x12835b01d807aa98 +DATA constants<>+0x28(SB)/8, $0x550c7dc3243185be +DATA constants<>+0x30(SB)/8, $0x80deb1fe72be5d74 +DATA constants<>+0x38(SB)/8, $0xc19bf1749bdc06a7 +DATA constants<>+0x40(SB)/8, $0xefbe4786e49b69c1 +DATA constants<>+0x48(SB)/8, $0x240ca1cc0fc19dc6 +DATA constants<>+0x50(SB)/8, $0x4a7484aa2de92c6f +DATA constants<>+0x58(SB)/8, $0x76f988da5cb0a9dc +DATA constants<>+0x60(SB)/8, $0xa831c66d983e5152 +DATA constants<>+0x68(SB)/8, $0xbf597fc7b00327c8 +DATA constants<>+0x70(SB)/8, $0xd5a79147c6e00bf3 +DATA constants<>+0x78(SB)/8, $0x1429296706ca6351 +DATA constants<>+0x80(SB)/8, $0x2e1b213827b70a85 +DATA constants<>+0x88(SB)/8, $0x53380d134d2c6dfc +DATA constants<>+0x90(SB)/8, $0x766a0abb650a7354 +DATA constants<>+0x98(SB)/8, $0x92722c8581c2c92e +DATA constants<>+0xa0(SB)/8, $0xa81a664ba2bfe8a1 +DATA constants<>+0xa8(SB)/8, $0xc76c51a3c24b8b70 +DATA constants<>+0xb0(SB)/8, $0xd6990624d192e819 +DATA constants<>+0xb8(SB)/8, $0x106aa070f40e3585 +DATA constants<>+0xc0(SB)/8, $0x1e376c0819a4c116 +DATA constants<>+0xc8(SB)/8, $0x34b0bcb52748774c +DATA constants<>+0xd0(SB)/8, $0x4ed8aa4a391c0cb3 +DATA constants<>+0xd8(SB)/8, $0x682e6ff35b9cca4f +DATA constants<>+0xe0(SB)/8, $0x78a5636f748f82ee +DATA constants<>+0xe8(SB)/8, $0x8cc7020884c87814 +DATA constants<>+0xf0(SB)/8, $0xa4506ceb90befffa +DATA constants<>+0xf8(SB)/8, $0xc67178f2bef9a3f7 + +DATA bflipMask<>+0x00(SB)/8, $0x0405060700010203 +DATA bflipMask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b + +DATA shuf00BA<>+0x00(SB)/8, $0x0b0a090803020100 +DATA shuf00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF + +DATA shufDC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF +DATA shufDC00<>+0x08(SB)/8, $0x0b0a090803020100 + +GLOBL constants<>(SB), 8, $256 +GLOBL bflipMask<>(SB), (NOPTR+RODATA), $16 +GLOBL shuf00BA<>(SB), (NOPTR+RODATA), $16 +GLOBL shufDC00<>(SB), (NOPTR+RODATA), $16 diff --git a/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go b/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go new file mode 100644 index 00000000..383189c8 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.go @@ -0,0 +1,6 @@ +//+build !noasm + +package sha256 + +//go:noescape +func blockSha(h *[8]uint32, message []uint8) diff --git a/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s b/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s new file mode 100644 index 00000000..909fc0ef --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockSha_amd64.s @@ -0,0 +1,266 @@ +//+build !noasm,!appengine + +// SHA intrinsic version of SHA256 + +// Kristofer Peterson, (C) 2018. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "textflag.h" + +DATA K<>+0x00(SB)/4, $0x428a2f98 +DATA K<>+0x04(SB)/4, $0x71374491 +DATA K<>+0x08(SB)/4, $0xb5c0fbcf +DATA K<>+0x0c(SB)/4, $0xe9b5dba5 +DATA K<>+0x10(SB)/4, $0x3956c25b +DATA K<>+0x14(SB)/4, $0x59f111f1 +DATA K<>+0x18(SB)/4, $0x923f82a4 +DATA K<>+0x1c(SB)/4, $0xab1c5ed5 +DATA K<>+0x20(SB)/4, $0xd807aa98 +DATA K<>+0x24(SB)/4, $0x12835b01 +DATA K<>+0x28(SB)/4, $0x243185be +DATA K<>+0x2c(SB)/4, $0x550c7dc3 +DATA K<>+0x30(SB)/4, $0x72be5d74 +DATA K<>+0x34(SB)/4, $0x80deb1fe +DATA K<>+0x38(SB)/4, $0x9bdc06a7 +DATA K<>+0x3c(SB)/4, $0xc19bf174 +DATA K<>+0x40(SB)/4, $0xe49b69c1 +DATA K<>+0x44(SB)/4, $0xefbe4786 +DATA K<>+0x48(SB)/4, $0x0fc19dc6 +DATA K<>+0x4c(SB)/4, $0x240ca1cc +DATA K<>+0x50(SB)/4, $0x2de92c6f +DATA K<>+0x54(SB)/4, $0x4a7484aa +DATA K<>+0x58(SB)/4, $0x5cb0a9dc +DATA K<>+0x5c(SB)/4, $0x76f988da +DATA K<>+0x60(SB)/4, $0x983e5152 +DATA K<>+0x64(SB)/4, $0xa831c66d +DATA K<>+0x68(SB)/4, $0xb00327c8 +DATA K<>+0x6c(SB)/4, $0xbf597fc7 +DATA K<>+0x70(SB)/4, $0xc6e00bf3 +DATA K<>+0x74(SB)/4, $0xd5a79147 +DATA K<>+0x78(SB)/4, $0x06ca6351 +DATA K<>+0x7c(SB)/4, $0x14292967 +DATA K<>+0x80(SB)/4, $0x27b70a85 +DATA K<>+0x84(SB)/4, $0x2e1b2138 +DATA K<>+0x88(SB)/4, $0x4d2c6dfc +DATA K<>+0x8c(SB)/4, $0x53380d13 +DATA K<>+0x90(SB)/4, $0x650a7354 +DATA K<>+0x94(SB)/4, $0x766a0abb +DATA K<>+0x98(SB)/4, $0x81c2c92e +DATA K<>+0x9c(SB)/4, $0x92722c85 +DATA K<>+0xa0(SB)/4, $0xa2bfe8a1 +DATA K<>+0xa4(SB)/4, $0xa81a664b +DATA K<>+0xa8(SB)/4, $0xc24b8b70 +DATA K<>+0xac(SB)/4, $0xc76c51a3 +DATA K<>+0xb0(SB)/4, $0xd192e819 +DATA K<>+0xb4(SB)/4, $0xd6990624 +DATA K<>+0xb8(SB)/4, $0xf40e3585 +DATA K<>+0xbc(SB)/4, $0x106aa070 +DATA K<>+0xc0(SB)/4, $0x19a4c116 +DATA K<>+0xc4(SB)/4, $0x1e376c08 +DATA K<>+0xc8(SB)/4, $0x2748774c +DATA K<>+0xcc(SB)/4, $0x34b0bcb5 +DATA K<>+0xd0(SB)/4, $0x391c0cb3 +DATA K<>+0xd4(SB)/4, $0x4ed8aa4a +DATA K<>+0xd8(SB)/4, $0x5b9cca4f +DATA K<>+0xdc(SB)/4, $0x682e6ff3 +DATA K<>+0xe0(SB)/4, $0x748f82ee +DATA K<>+0xe4(SB)/4, $0x78a5636f +DATA K<>+0xe8(SB)/4, $0x84c87814 +DATA K<>+0xec(SB)/4, $0x8cc70208 +DATA K<>+0xf0(SB)/4, $0x90befffa +DATA K<>+0xf4(SB)/4, $0xa4506ceb +DATA K<>+0xf8(SB)/4, $0xbef9a3f7 +DATA K<>+0xfc(SB)/4, $0xc67178f2 +GLOBL K<>(SB), RODATA|NOPTR, $256 + +DATA SHUF_MASK<>+0x00(SB)/8, $0x0405060700010203 +DATA SHUF_MASK<>+0x08(SB)/8, $0x0c0d0e0f08090a0b +GLOBL SHUF_MASK<>(SB), RODATA|NOPTR, $16 + +// Register Usage +// BX base address of constant table (constant) +// DX hash_state (constant) +// SI hash_data.data +// DI hash_data.data + hash_data.length - 64 (constant) +// X0 scratch +// X1 scratch +// X2 working hash state // ABEF +// X3 working hash state // CDGH +// X4 first 16 bytes of block +// X5 second 16 bytes of block +// X6 third 16 bytes of block +// X7 fourth 16 bytes of block +// X12 saved hash state // ABEF +// X13 saved hash state // CDGH +// X15 data shuffle mask (constant) + +TEXT ·blockSha(SB), NOSPLIT, $0-32 + MOVQ h+0(FP), DX + MOVQ message_base+8(FP), SI + MOVQ message_len+16(FP), DI + LEAQ -64(SI)(DI*1), DI + MOVOU (DX), X2 + MOVOU 16(DX), X1 + MOVO X2, X3 + PUNPCKLLQ X1, X2 + PUNPCKHLQ X1, X3 + PSHUFD $0x27, X2, X2 + PSHUFD $0x27, X3, X3 + MOVO SHUF_MASK<>(SB), X15 + LEAQ K<>(SB), BX + + JMP TEST + +LOOP: + MOVO X2, X12 + MOVO X3, X13 + + // load block and shuffle + MOVOU (SI), X4 + MOVOU 16(SI), X5 + MOVOU 32(SI), X6 + MOVOU 48(SI), X7 + PSHUFB X15, X4 + PSHUFB X15, X5 + PSHUFB X15, X6 + PSHUFB X15, X7 + +#define ROUND456 \ + PADDL X5, X0 \ + LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2 + MOVO X5, X1 \ + LONG $0x0f3a0f66; WORD $0x04cc \ // PALIGNR XMM1, XMM4, 4 + PADDL X1, X6 \ + LONG $0xf5cd380f \ // SHA256MSG2 XMM6, XMM5 + PSHUFD $0x4e, X0, X0 \ + LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3 + LONG $0xe5cc380f // SHA256MSG1 XMM4, XMM5 + +#define ROUND567 \ + PADDL X6, X0 \ + LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2 + MOVO X6, X1 \ + LONG $0x0f3a0f66; WORD $0x04cd \ // PALIGNR XMM1, XMM5, 4 + PADDL X1, X7 \ + LONG $0xfecd380f \ // SHA256MSG2 XMM7, XMM6 + PSHUFD $0x4e, X0, X0 \ + LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3 + LONG $0xeecc380f // SHA256MSG1 XMM5, XMM6 + +#define ROUND674 \ + PADDL X7, X0 \ + LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2 + MOVO X7, X1 \ + LONG $0x0f3a0f66; WORD $0x04ce \ // PALIGNR XMM1, XMM6, 4 + PADDL X1, X4 \ + LONG $0xe7cd380f \ // SHA256MSG2 XMM4, XMM7 + PSHUFD $0x4e, X0, X0 \ + LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3 + LONG $0xf7cc380f // SHA256MSG1 XMM6, XMM7 + +#define ROUND745 \ + PADDL X4, X0 \ + LONG $0xdacb380f \ // SHA256RNDS2 XMM3, XMM2 + MOVO X4, X1 \ + LONG $0x0f3a0f66; WORD $0x04cf \ // PALIGNR XMM1, XMM7, 4 + PADDL X1, X5 \ + LONG $0xeccd380f \ // SHA256MSG2 XMM5, XMM4 + PSHUFD $0x4e, X0, X0 \ + LONG $0xd3cb380f \ // SHA256RNDS2 XMM2, XMM3 + LONG $0xfccc380f // SHA256MSG1 XMM7, XMM4 + + // rounds 0-3 + MOVO (BX), X0 + PADDL X4, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + + // rounds 4-7 + MOVO 1*16(BX), X0 + PADDL X5, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + LONG $0xe5cc380f // SHA256MSG1 XMM4, XMM5 + + // rounds 8-11 + MOVO 2*16(BX), X0 + PADDL X6, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + LONG $0xeecc380f // SHA256MSG1 XMM5, XMM6 + + MOVO 3*16(BX), X0; ROUND674 // rounds 12-15 + MOVO 4*16(BX), X0; ROUND745 // rounds 16-19 + MOVO 5*16(BX), X0; ROUND456 // rounds 20-23 + MOVO 6*16(BX), X0; ROUND567 // rounds 24-27 + MOVO 7*16(BX), X0; ROUND674 // rounds 28-31 + MOVO 8*16(BX), X0; ROUND745 // rounds 32-35 + MOVO 9*16(BX), X0; ROUND456 // rounds 36-39 + MOVO 10*16(BX), X0; ROUND567 // rounds 40-43 + MOVO 11*16(BX), X0; ROUND674 // rounds 44-47 + MOVO 12*16(BX), X0; ROUND745 // rounds 48-51 + + // rounds 52-55 + MOVO 13*16(BX), X0 + PADDL X5, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + MOVO X5, X1 + LONG $0x0f3a0f66; WORD $0x04cc // PALIGNR XMM1, XMM4, 4 + PADDL X1, X6 + LONG $0xf5cd380f // SHA256MSG2 XMM6, XMM5 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + + // rounds 56-59 + MOVO 14*16(BX), X0 + PADDL X6, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + MOVO X6, X1 + LONG $0x0f3a0f66; WORD $0x04cd // PALIGNR XMM1, XMM5, 4 + PADDL X1, X7 + LONG $0xfecd380f // SHA256MSG2 XMM7, XMM6 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + + // rounds 60-63 + MOVO 15*16(BX), X0 + PADDL X7, X0 + LONG $0xdacb380f // SHA256RNDS2 XMM3, XMM2 + PSHUFD $0x4e, X0, X0 + LONG $0xd3cb380f // SHA256RNDS2 XMM2, XMM3 + + PADDL X12, X2 + PADDL X13, X3 + + ADDQ $64, SI + +TEST: + CMPQ SI, DI + JBE LOOP + + PSHUFD $0x4e, X3, X0 + LONG $0x0e3a0f66; WORD $0xf0c2 // PBLENDW XMM0, XMM2, 0xf0 + PSHUFD $0x4e, X2, X1 + LONG $0x0e3a0f66; WORD $0x0fcb // PBLENDW XMM1, XMM3, 0x0f + PSHUFD $0x1b, X0, X0 + PSHUFD $0x1b, X1, X1 + + MOVOU X0, (DX) + MOVOU X1, 16(DX) + + RET diff --git a/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go b/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go new file mode 100644 index 00000000..54abbb0f --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.go @@ -0,0 +1,22 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +//go:noescape +func blockSsse(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64) diff --git a/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s b/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s new file mode 100644 index 00000000..7afb45c8 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256blockSsse_amd64.s @@ -0,0 +1,429 @@ +//+build !noasm,!appengine + +// SHA256 implementation for SSSE3 + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// This code is based on an Intel White-Paper: +// "Fast SHA-256 Implementations on Intel Architecture Processors" +// +// together with the reference implementation from the following authors: +// James Guilford +// Kirk Yap +// Tim Chen +// +// For Golang it has been converted to Plan 9 assembly with the help of +// github.com/minio/asm2plan9s to assemble Intel instructions to their Plan9 +// equivalents +// + +#include "textflag.h" + +#define ROTATE_XS \ + MOVOU X4, X15 \ + MOVOU X5, X4 \ + MOVOU X6, X5 \ + MOVOU X7, X6 \ + MOVOU X15, X7 + +// compute s0 four at a time and s1 two at a time +// compute W[-16] + W[-7] 4 at a time +#define FOUR_ROUNDS_AND_SCHED(a, b, c, d, e, f, g, h) \ + MOVL e, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL a, R14 \ // y1 = a + MOVOU X7, X0 \ + LONG $0x0f3a0f66; WORD $0x04c6 \ // PALIGNR XMM0,XMM6,0x4 /* XTMP0 = W[-7] */ + ROLL $23, R14 \ // y1 = a >> (22-13) + XORL e, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL f, R15 \ // y2 = f + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL a, R14 \ // y1 = a ^ (a >> (22-13) + XORL g, R15 \ // y2 = f^g + LONG $0xc4fe0f66 \ // PADDD XMM0,XMM4 /* XTMP0 = W[-7] + W[-16] */ + XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6) ) + ANDL e, R15 \ // y2 = (f^g)&e + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + \ + \ // compute s0 + \ + MOVOU X5, X1 \ + LONG $0x0f3a0f66; WORD $0x04cc \ // PALIGNR XMM1,XMM4,0x4 /* XTMP1 = W[-15] */ + XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL g, R15 \ // y2 = CH = ((f^g)&e)^g + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+48(FP), R15 \ // y2 = k + w + S1 + CH + MOVL a, R13 \ // y0 = a + ADDL R15, h \ // h = h + S1 + CH + k + w + \ // ROTATE_ARGS + MOVL a, R15 \ // y2 = a + MOVOU X1, X2 \ + LONG $0xd2720f66; BYTE $0x07 \ // PSRLD XMM2,0x7 /* */ + ORL c, R13 \ // y0 = a|c + ADDL h, d \ // d = d + h + S1 + CH + k + w + ANDL c, R15 \ // y2 = a&c + MOVOU X1, X3 \ + LONG $0xf3720f66; BYTE $0x19 \ // PSLLD XMM3,0x19 /* */ + ANDL b, R13 \ // y0 = (a|c)&b + ADDL R14, h \ // h = h + S1 + CH + k + w + S0 + LONG $0xdaeb0f66 \ // POR XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, h \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL d, R13 \ // y0 = e + MOVL h, R14 \ // y1 = a + ROLL $18, R13 \ // y0 = e >> (25-11) + XORL d, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL e, R15 \ // y2 = f + ROLL $23, R14 \ // y1 = a >> (22-13) + MOVOU X1, X2 \ + LONG $0xd2720f66; BYTE $0x12 \ // PSRLD XMM2,0x12 /* */ + XORL h, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL f, R15 \ // y2 = f^g + MOVOU X1, X8 \ + LONG $0x720f4166; WORD $0x03d0 \ // PSRLD XMM8,0x3 /* XTMP4 = W[-15] >> 3 */ + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + XORL d, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL d, R15 \ // y2 = (f^g)&e + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + LONG $0xf1720f66; BYTE $0x0e \ // PSLLD XMM1,0xe /* */ + XORL h, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + XORL f, R15 \ // y2 = CH = ((f^g)&e)^g + LONG $0xd9ef0f66 \ // PXOR XMM3,XMM1 /* */ + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+52(FP), R15 \ // y2 = k + w + S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + LONG $0xdaef0f66 \ // PXOR XMM3,XMM2 /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR */ + MOVL h, R13 \ // y0 = a + ADDL R15, g \ // h = h + S1 + CH + k + w + MOVL h, R15 \ // y2 = a + MOVOU X3, X1 \ + LONG $0xef0f4166; BYTE $0xc8 \ // PXOR XMM1,XMM8 /* XTMP1 = s0 */ + ORL b, R13 \ // y0 = a|c + ADDL g, c \ // d = d + h + S1 + CH + k + w + ANDL b, R15 \ // y2 = a&c + \ + \ // compute low s1 + \ + LONG $0xd7700f66; BYTE $0xfa \ // PSHUFD XMM2,XMM7,0xfa /* XTMP2 = W[-2] {BBAA} */ + ANDL a, R13 \ // y0 = (a|c)&b + ADDL R14, g \ // h = h + S1 + CH + k + w + S0 + LONG $0xc1fe0f66 \ // PADDD XMM0,XMM1 /* XTMP0 = W[-16] + W[-7] + s0 */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, g \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL c, R13 \ // y0 = e + MOVL g, R14 \ // y1 = a + ROLL $18, R13 \ // y0 = e >> (25-11) + XORL c, R13 \ // y0 = e ^ (e >> (25-11)) + ROLL $23, R14 \ // y1 = a >> (22-13) + MOVL d, R15 \ // y2 = f + XORL g, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + MOVOU X2, X8 \ + LONG $0x720f4166; WORD $0x0ad0 \ // PSRLD XMM8,0xa /* XTMP4 = W[-2] >> 10 {BBAA} */ + XORL e, R15 \ // y2 = f^g + MOVOU X2, X3 \ + LONG $0xd3730f66; BYTE $0x13 \ // PSRLQ XMM3,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */ + XORL c, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL c, R15 \ // y2 = (f^g)&e + LONG $0xd2730f66; BYTE $0x11 \ // PSRLQ XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */ + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + XORL g, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + XORL e, R15 \ // y2 = CH = ((f^g)&e)^g + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + LONG $0xd3ef0f66 \ // PXOR XMM2,XMM3 /* */ + ADDL R13, R15 \ // y2 = S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL _xfer+56(FP), R15 \ // y2 = k + w + S1 + CH + LONG $0xef0f4466; BYTE $0xc2 \ // PXOR XMM8,XMM2 /* XTMP4 = s1 {xBxA} */ + MOVL g, R13 \ // y0 = a + ADDL R15, f \ // h = h + S1 + CH + k + w + MOVL g, R15 \ // y2 = a + LONG $0x380f4566; WORD $0xc200 \ // PSHUFB XMM8,XMM10 /* XTMP4 = s1 {00BA} */ + ORL a, R13 \ // y0 = a|c + ADDL f, b \ // d = d + h + S1 + CH + k + w + ANDL a, R15 \ // y2 = a&c + LONG $0xfe0f4166; BYTE $0xc0 \ // PADDD XMM0,XMM8 /* XTMP0 = {..., ..., W[1], W[0]} */ + ANDL h, R13 \ // y0 = (a|c)&b + ADDL R14, f \ // h = h + S1 + CH + k + w + S0 + \ + \ // compute high s1 + \ + LONG $0xd0700f66; BYTE $0x50 \ // PSHUFD XMM2,XMM0,0x50 /* XTMP2 = W[-2] {DDCC} */ + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, f \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + MOVL b, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL f, R14 \ // y1 = a + ROLL $23, R14 \ // y1 = a >> (22-13) + XORL b, R13 \ // y0 = e ^ (e >> (25-11)) + MOVL c, R15 \ // y2 = f + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + MOVOU X2, X11 \ + LONG $0x720f4166; WORD $0x0ad3 \ // PSRLD XMM11,0xa /* XTMP5 = W[-2] >> 10 {DDCC} */ + XORL f, R14 \ // y1 = a ^ (a >> (22-13) + XORL d, R15 \ // y2 = f^g + MOVOU X2, X3 \ + LONG $0xd3730f66; BYTE $0x13 \ // PSRLQ XMM3,0x13 /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */ + XORL b, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ANDL b, R15 \ // y2 = (f^g)&e + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + LONG $0xd2730f66; BYTE $0x11 \ // PSRLQ XMM2,0x11 /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */ + XORL f, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL d, R15 \ // y2 = CH = ((f^g)&e)^g + LONG $0xd3ef0f66 \ // PXOR XMM2,XMM3 /* */ + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL R13, R15 \ // y2 = S1 + CH + ADDL _xfer+60(FP), R15 \ // y2 = k + w + S1 + CH + LONG $0xef0f4466; BYTE $0xda \ // PXOR XMM11,XMM2 /* XTMP5 = s1 {xDxC} */ + MOVL f, R13 \ // y0 = a + ADDL R15, e \ // h = h + S1 + CH + k + w + MOVL f, R15 \ // y2 = a + LONG $0x380f4566; WORD $0xdc00 \ // PSHUFB XMM11,XMM12 /* XTMP5 = s1 {DC00} */ + ORL h, R13 \ // y0 = a|c + ADDL e, a \ // d = d + h + S1 + CH + k + w + ANDL h, R15 \ // y2 = a&c + MOVOU X11, X4 \ + LONG $0xe0fe0f66 \ // PADDD XMM4,XMM0 /* X0 = {W[3], W[2], W[1], W[0]} */ + ANDL g, R13 \ // y0 = (a|c)&b + ADDL R14, e \ // h = h + S1 + CH + k + w + S0 + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, e \ // h = h + S1 + CH + k + w + S0 + MAJ + \ // ROTATE_ARGS + ROTATE_XS + +#define DO_ROUND(a, b, c, d, e, f, g, h, offset) \ + MOVL e, R13 \ // y0 = e + ROLL $18, R13 \ // y0 = e >> (25-11) + MOVL a, R14 \ // y1 = a + XORL e, R13 \ // y0 = e ^ (e >> (25-11)) + ROLL $23, R14 \ // y1 = a >> (22-13) + MOVL f, R15 \ // y2 = f + XORL a, R14 \ // y1 = a ^ (a >> (22-13) + ROLL $27, R13 \ // y0 = (e >> (11-6)) ^ (e >> (25-6)) + XORL g, R15 \ // y2 = f^g + XORL e, R13 \ // y0 = e ^ (e >> (11-6)) ^ (e >> (25-6)) + ROLL $21, R14 \ // y1 = (a >> (13-2)) ^ (a >> (22-2)) + ANDL e, R15 \ // y2 = (f^g)&e + XORL a, R14 \ // y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) + ROLL $26, R13 \ // y0 = S1 = (e>>6) & (e>>11) ^ (e>>25) + XORL g, R15 \ // y2 = CH = ((f^g)&e)^g + ADDL R13, R15 \ // y2 = S1 + CH + ROLL $30, R14 \ // y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22) + ADDL _xfer+offset(FP), R15 \ // y2 = k + w + S1 + CH + MOVL a, R13 \ // y0 = a + ADDL R15, h \ // h = h + S1 + CH + k + w + MOVL a, R15 \ // y2 = a + ORL c, R13 \ // y0 = a|c + ADDL h, d \ // d = d + h + S1 + CH + k + w + ANDL c, R15 \ // y2 = a&c + ANDL b, R13 \ // y0 = (a|c)&b + ADDL R14, h \ // h = h + S1 + CH + k + w + S0 + ORL R15, R13 \ // y0 = MAJ = (a|c)&b)|(a&c) + ADDL R13, h // h = h + S1 + CH + k + w + S0 + MAJ + +// func blockSsse(h []uint32, message []uint8, reserved0, reserved1, reserved2, reserved3 uint64) +TEXT ·blockSsse(SB), 7, $0-80 + + MOVQ h+0(FP), SI // SI: &h + MOVQ message_base+24(FP), R8 // &message + MOVQ message_len+32(FP), R9 // length of message + CMPQ R9, $0 + JEQ done_hash + ADDQ R8, R9 + MOVQ R9, reserved2+64(FP) // store end of message + + // Register definition + // a --> eax + // b --> ebx + // c --> ecx + // d --> r8d + // e --> edx + // f --> r9d + // g --> r10d + // h --> r11d + // + // y0 --> r13d + // y1 --> r14d + // y2 --> r15d + + MOVL (0*4)(SI), AX // a = H0 + MOVL (1*4)(SI), BX // b = H1 + MOVL (2*4)(SI), CX // c = H2 + MOVL (3*4)(SI), R8 // d = H3 + MOVL (4*4)(SI), DX // e = H4 + MOVL (5*4)(SI), R9 // f = H5 + MOVL (6*4)(SI), R10 // g = H6 + MOVL (7*4)(SI), R11 // h = H7 + + MOVOU bflipMask<>(SB), X13 + MOVOU shuf00BA<>(SB), X10 // shuffle xBxA -> 00BA + MOVOU shufDC00<>(SB), X12 // shuffle xDxC -> DC00 + + MOVQ message_base+24(FP), SI // SI: &message + +loop0: + LEAQ constants<>(SB), BP + + // byte swap first 16 dwords + MOVOU 0*16(SI), X4 + LONG $0x380f4166; WORD $0xe500 // PSHUFB XMM4, XMM13 + MOVOU 1*16(SI), X5 + LONG $0x380f4166; WORD $0xed00 // PSHUFB XMM5, XMM13 + MOVOU 2*16(SI), X6 + LONG $0x380f4166; WORD $0xf500 // PSHUFB XMM6, XMM13 + MOVOU 3*16(SI), X7 + LONG $0x380f4166; WORD $0xfd00 // PSHUFB XMM7, XMM13 + + MOVQ SI, reserved3+72(FP) + MOVD $0x3, DI + + // Align + // nop WORD PTR [rax+rax*1+0x0] + + // schedule 48 input dwords, by doing 3 rounds of 16 each +loop1: + MOVOU X4, X9 + LONG $0xfe0f4466; WORD $0x004d // PADDD XMM9, 0[RBP] /* Add 1st constant to first part of message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11) + + MOVOU X4, X9 + LONG $0xfe0f4466; WORD $0x104d // PADDD XMM9, 16[RBP] /* Add 2nd constant to message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8) + + MOVOU X4, X9 + LONG $0xfe0f4466; WORD $0x204d // PADDD XMM9, 32[RBP] /* Add 3rd constant to message */ + MOVOU X9, reserved0+48(FP) + FOUR_ROUNDS_AND_SCHED(AX, BX, CX, R8, DX, R9, R10, R11) + + MOVOU X4, X9 + LONG $0xfe0f4466; WORD $0x304d // PADDD XMM9, 48[RBP] /* Add 4th constant to message */ + MOVOU X9, reserved0+48(FP) + ADDQ $64, BP + FOUR_ROUNDS_AND_SCHED(DX, R9, R10, R11, AX, BX, CX, R8) + + SUBQ $1, DI + JNE loop1 + + MOVD $0x2, DI + +loop2: + MOVOU X4, X9 + LONG $0xfe0f4466; WORD $0x004d // PADDD XMM9, 0[RBP] /* Add 1st constant to first part of message */ + MOVOU X9, reserved0+48(FP) + DO_ROUND( AX, BX, CX, R8, DX, R9, R10, R11, 48) + DO_ROUND(R11, AX, BX, CX, R8, DX, R9, R10, 52) + DO_ROUND(R10, R11, AX, BX, CX, R8, DX, R9, 56) + DO_ROUND( R9, R10, R11, AX, BX, CX, R8, DX, 60) + + MOVOU X5, X9 + LONG $0xfe0f4466; WORD $0x104d // PADDD XMM9, 16[RBP] /* Add 2nd constant to message */ + MOVOU X9, reserved0+48(FP) + ADDQ $32, BP + DO_ROUND( DX, R9, R10, R11, AX, BX, CX, R8, 48) + DO_ROUND( R8, DX, R9, R10, R11, AX, BX, CX, 52) + DO_ROUND( CX, R8, DX, R9, R10, R11, AX, BX, 56) + DO_ROUND( BX, CX, R8, DX, R9, R10, R11, AX, 60) + + MOVOU X6, X4 + MOVOU X7, X5 + + SUBQ $1, DI + JNE loop2 + + MOVQ h+0(FP), SI // SI: &h + ADDL (0*4)(SI), AX // H0 = a + H0 + MOVL AX, (0*4)(SI) + ADDL (1*4)(SI), BX // H1 = b + H1 + MOVL BX, (1*4)(SI) + ADDL (2*4)(SI), CX // H2 = c + H2 + MOVL CX, (2*4)(SI) + ADDL (3*4)(SI), R8 // H3 = d + H3 + MOVL R8, (3*4)(SI) + ADDL (4*4)(SI), DX // H4 = e + H4 + MOVL DX, (4*4)(SI) + ADDL (5*4)(SI), R9 // H5 = f + H5 + MOVL R9, (5*4)(SI) + ADDL (6*4)(SI), R10 // H6 = g + H6 + MOVL R10, (6*4)(SI) + ADDL (7*4)(SI), R11 // H7 = h + H7 + MOVL R11, (7*4)(SI) + + MOVQ reserved3+72(FP), SI + ADDQ $64, SI + CMPQ reserved2+64(FP), SI + JNE loop0 + +done_hash: + RET + +// Constants table +DATA constants<>+0x0(SB)/8, $0x71374491428a2f98 +DATA constants<>+0x8(SB)/8, $0xe9b5dba5b5c0fbcf +DATA constants<>+0x10(SB)/8, $0x59f111f13956c25b +DATA constants<>+0x18(SB)/8, $0xab1c5ed5923f82a4 +DATA constants<>+0x20(SB)/8, $0x12835b01d807aa98 +DATA constants<>+0x28(SB)/8, $0x550c7dc3243185be +DATA constants<>+0x30(SB)/8, $0x80deb1fe72be5d74 +DATA constants<>+0x38(SB)/8, $0xc19bf1749bdc06a7 +DATA constants<>+0x40(SB)/8, $0xefbe4786e49b69c1 +DATA constants<>+0x48(SB)/8, $0x240ca1cc0fc19dc6 +DATA constants<>+0x50(SB)/8, $0x4a7484aa2de92c6f +DATA constants<>+0x58(SB)/8, $0x76f988da5cb0a9dc +DATA constants<>+0x60(SB)/8, $0xa831c66d983e5152 +DATA constants<>+0x68(SB)/8, $0xbf597fc7b00327c8 +DATA constants<>+0x70(SB)/8, $0xd5a79147c6e00bf3 +DATA constants<>+0x78(SB)/8, $0x1429296706ca6351 +DATA constants<>+0x80(SB)/8, $0x2e1b213827b70a85 +DATA constants<>+0x88(SB)/8, $0x53380d134d2c6dfc +DATA constants<>+0x90(SB)/8, $0x766a0abb650a7354 +DATA constants<>+0x98(SB)/8, $0x92722c8581c2c92e +DATA constants<>+0xa0(SB)/8, $0xa81a664ba2bfe8a1 +DATA constants<>+0xa8(SB)/8, $0xc76c51a3c24b8b70 +DATA constants<>+0xb0(SB)/8, $0xd6990624d192e819 +DATA constants<>+0xb8(SB)/8, $0x106aa070f40e3585 +DATA constants<>+0xc0(SB)/8, $0x1e376c0819a4c116 +DATA constants<>+0xc8(SB)/8, $0x34b0bcb52748774c +DATA constants<>+0xd0(SB)/8, $0x4ed8aa4a391c0cb3 +DATA constants<>+0xd8(SB)/8, $0x682e6ff35b9cca4f +DATA constants<>+0xe0(SB)/8, $0x78a5636f748f82ee +DATA constants<>+0xe8(SB)/8, $0x8cc7020884c87814 +DATA constants<>+0xf0(SB)/8, $0xa4506ceb90befffa +DATA constants<>+0xf8(SB)/8, $0xc67178f2bef9a3f7 + +DATA bflipMask<>+0x00(SB)/8, $0x0405060700010203 +DATA bflipMask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b + +DATA shuf00BA<>+0x00(SB)/8, $0x0b0a090803020100 +DATA shuf00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF + +DATA shufDC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF +DATA shufDC00<>+0x08(SB)/8, $0x0b0a090803020100 + +GLOBL constants<>(SB), 8, $256 +GLOBL bflipMask<>(SB), (NOPTR+RODATA), $16 +GLOBL shuf00BA<>(SB), (NOPTR+RODATA), $16 +GLOBL shufDC00<>(SB), (NOPTR+RODATA), $16 diff --git a/vendor/github.com/minio/sha256-simd/sha256block_386.go b/vendor/github.com/minio/sha256-simd/sha256block_386.go new file mode 100644 index 00000000..a4153b91 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_386.go @@ -0,0 +1,25 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +func blockArmGo(dig *digest, p []byte) {} +func blockAvx2Go(dig *digest, p []byte) {} +func blockAvxGo(dig *digest, p []byte) {} +func blockSsseGo(dig *digest, p []byte) {} +func blockShaGo(dig *digest, p []byte) {} diff --git a/vendor/github.com/minio/sha256-simd/sha256block_amd64.go b/vendor/github.com/minio/sha256-simd/sha256block_amd64.go new file mode 100644 index 00000000..8d341fcf --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_amd64.go @@ -0,0 +1,53 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +func blockArmGo(dig *digest, p []byte) {} + +func blockAvxGo(dig *digest, p []byte) { + + h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]} + + blockAvx(h[:], p[:], 0, 0, 0, 0) + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] +} + +func blockAvx2Go(dig *digest, p []byte) { + + h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]} + + blockAvx2(h[:], p[:]) + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] +} + +func blockSsseGo(dig *digest, p []byte) { + + h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]} + + blockSsse(h[:], p[:], 0, 0, 0, 0) + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] +} + +func blockShaGo(dig *digest, p []byte) { + + blockSha(&dig.h, p) +} diff --git a/vendor/github.com/minio/sha256-simd/sha256block_arm.go b/vendor/github.com/minio/sha256-simd/sha256block_arm.go new file mode 100644 index 00000000..1191c086 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_arm.go @@ -0,0 +1,25 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +func blockAvx2Go(dig *digest, p []byte) {} +func blockAvxGo(dig *digest, p []byte) {} +func blockSsseGo(dig *digest, p []byte) {} +func blockShaGo(dig *digest, p []byte) {} +func blockArmGo(dig *digest, p []byte) {} diff --git a/vendor/github.com/minio/sha256-simd/sha256block_arm64.go b/vendor/github.com/minio/sha256-simd/sha256block_arm64.go new file mode 100644 index 00000000..4441b0c2 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_arm64.go @@ -0,0 +1,37 @@ +//+build !noasm + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +func blockAvx2Go(dig *digest, p []byte) {} +func blockAvxGo(dig *digest, p []byte) {} +func blockSsseGo(dig *digest, p []byte) {} +func blockShaGo(dig *digest, p []byte) {} + +//go:noescape +func blockArm(h []uint32, message []uint8) + +func blockArmGo(dig *digest, p []byte) { + + h := []uint32{dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]} + + blockArm(h[:], p[:]) + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h[0], h[1], h[2], h[3], h[4], + h[5], h[6], h[7] +} diff --git a/vendor/github.com/minio/sha256-simd/sha256block_arm64.s b/vendor/github.com/minio/sha256-simd/sha256block_arm64.s new file mode 100644 index 00000000..db816ac6 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_arm64.s @@ -0,0 +1,192 @@ +//+build !noasm !appengine + +// ARM64 version of SHA256 + +// +// Minio Cloud Storage, (C) 2016 Minio, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// Based on implementation as found in https://github.com/jocover/sha256-armv8 +// +// Use github.com/minio/asm2plan9s on this file to assemble ARM instructions to +// their Plan9 equivalents +// + +TEXT ·blockArm(SB), 7, $0 + MOVD h+0(FP), R0 + MOVD message+24(FP), R1 + MOVD lenmessage+32(FP), R2 // length of message + SUBS $64, R2 + BMI complete + + // Load constants table pointer + MOVD $·constants(SB), R3 + + // Cache constants table in registers v16 - v31 + WORD $0x4cdf2870 // ld1 {v16.4s-v19.4s}, [x3], #64 + WORD $0x4cdf7800 // ld1 {v0.4s}, [x0], #16 + WORD $0x4cdf2874 // ld1 {v20.4s-v23.4s}, [x3], #64 + + WORD $0x4c407801 // ld1 {v1.4s}, [x0] + WORD $0x4cdf2878 // ld1 {v24.4s-v27.4s}, [x3], #64 + WORD $0xd1004000 // sub x0, x0, #0x10 + WORD $0x4cdf287c // ld1 {v28.4s-v31.4s}, [x3], #64 + +loop: + // Main loop + WORD $0x4cdf2025 // ld1 {v5.16b-v8.16b}, [x1], #64 + WORD $0x4ea01c02 // mov v2.16b, v0.16b + WORD $0x4ea11c23 // mov v3.16b, v1.16b + WORD $0x6e2008a5 // rev32 v5.16b, v5.16b + WORD $0x6e2008c6 // rev32 v6.16b, v6.16b + WORD $0x4eb084a9 // add v9.4s, v5.4s, v16.4s + WORD $0x6e2008e7 // rev32 v7.16b, v7.16b + WORD $0x4eb184ca // add v10.4s, v6.4s, v17.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s + WORD $0x6e200908 // rev32 v8.16b, v8.16b + WORD $0x4eb284e9 // add v9.4s, v7.4s, v18.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s + WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s + WORD $0x4eb3850a // add v10.4s, v8.4s, v19.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e282907 // sha256su0 v7.4s, v8.4s + WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s + WORD $0x4eb484a9 // add v9.4s, v5.4s, v20.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s + WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s + WORD $0x4eb584ca // add v10.4s, v6.4s, v21.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s + WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s + WORD $0x4eb684e9 // add v9.4s, v7.4s, v22.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s + WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s + WORD $0x4eb7850a // add v10.4s, v8.4s, v23.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e282907 // sha256su0 v7.4s, v8.4s + WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s + WORD $0x4eb884a9 // add v9.4s, v5.4s, v24.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s + WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s + WORD $0x4eb984ca // add v10.4s, v6.4s, v25.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e2828c5 // sha256su0 v5.4s, v6.4s + WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s + WORD $0x4eba84e9 // add v9.4s, v7.4s, v26.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828e6 // sha256su0 v6.4s, v7.4s + WORD $0x5e0860e5 // sha256su1 v5.4s, v7.4s, v8.4s + WORD $0x4ebb850a // add v10.4s, v8.4s, v27.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e282907 // sha256su0 v7.4s, v8.4s + WORD $0x5e056106 // sha256su1 v6.4s, v8.4s, v5.4s + WORD $0x4ebc84a9 // add v9.4s, v5.4s, v28.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x5e2828a8 // sha256su0 v8.4s, v5.4s + WORD $0x5e0660a7 // sha256su1 v7.4s, v5.4s, v6.4s + WORD $0x4ebd84ca // add v10.4s, v6.4s, v29.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x5e0760c8 // sha256su1 v8.4s, v6.4s, v7.4s + WORD $0x4ebe84e9 // add v9.4s, v7.4s, v30.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x4ebf850a // add v10.4s, v8.4s, v31.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e094062 // sha256h q2, q3, v9.4s + WORD $0x5e095083 // sha256h2 q3, q4, v9.4s + WORD $0x4ea21c44 // mov v4.16b, v2.16b + WORD $0x5e0a4062 // sha256h q2, q3, v10.4s + WORD $0x5e0a5083 // sha256h2 q3, q4, v10.4s + WORD $0x4ea38421 // add v1.4s, v1.4s, v3.4s + WORD $0x4ea28400 // add v0.4s, v0.4s, v2.4s + + SUBS $64, R2 + BPL loop + + // Store result + WORD $0x4c00a800 // st1 {v0.4s, v1.4s}, [x0] + +complete: + RET + +// Constants table +DATA ·constants+0x0(SB)/8, $0x71374491428a2f98 +DATA ·constants+0x8(SB)/8, $0xe9b5dba5b5c0fbcf +DATA ·constants+0x10(SB)/8, $0x59f111f13956c25b +DATA ·constants+0x18(SB)/8, $0xab1c5ed5923f82a4 +DATA ·constants+0x20(SB)/8, $0x12835b01d807aa98 +DATA ·constants+0x28(SB)/8, $0x550c7dc3243185be +DATA ·constants+0x30(SB)/8, $0x80deb1fe72be5d74 +DATA ·constants+0x38(SB)/8, $0xc19bf1749bdc06a7 +DATA ·constants+0x40(SB)/8, $0xefbe4786e49b69c1 +DATA ·constants+0x48(SB)/8, $0x240ca1cc0fc19dc6 +DATA ·constants+0x50(SB)/8, $0x4a7484aa2de92c6f +DATA ·constants+0x58(SB)/8, $0x76f988da5cb0a9dc +DATA ·constants+0x60(SB)/8, $0xa831c66d983e5152 +DATA ·constants+0x68(SB)/8, $0xbf597fc7b00327c8 +DATA ·constants+0x70(SB)/8, $0xd5a79147c6e00bf3 +DATA ·constants+0x78(SB)/8, $0x1429296706ca6351 +DATA ·constants+0x80(SB)/8, $0x2e1b213827b70a85 +DATA ·constants+0x88(SB)/8, $0x53380d134d2c6dfc +DATA ·constants+0x90(SB)/8, $0x766a0abb650a7354 +DATA ·constants+0x98(SB)/8, $0x92722c8581c2c92e +DATA ·constants+0xa0(SB)/8, $0xa81a664ba2bfe8a1 +DATA ·constants+0xa8(SB)/8, $0xc76c51a3c24b8b70 +DATA ·constants+0xb0(SB)/8, $0xd6990624d192e819 +DATA ·constants+0xb8(SB)/8, $0x106aa070f40e3585 +DATA ·constants+0xc0(SB)/8, $0x1e376c0819a4c116 +DATA ·constants+0xc8(SB)/8, $0x34b0bcb52748774c +DATA ·constants+0xd0(SB)/8, $0x4ed8aa4a391c0cb3 +DATA ·constants+0xd8(SB)/8, $0x682e6ff35b9cca4f +DATA ·constants+0xe0(SB)/8, $0x78a5636f748f82ee +DATA ·constants+0xe8(SB)/8, $0x8cc7020884c87814 +DATA ·constants+0xf0(SB)/8, $0xa4506ceb90befffa +DATA ·constants+0xf8(SB)/8, $0xc67178f2bef9a3f7 + +GLOBL ·constants(SB), 8, $256 + diff --git a/vendor/github.com/minio/sha256-simd/sha256block_other.go b/vendor/github.com/minio/sha256-simd/sha256block_other.go new file mode 100644 index 00000000..0930d2a2 --- /dev/null +++ b/vendor/github.com/minio/sha256-simd/sha256block_other.go @@ -0,0 +1,25 @@ +//+build noasm appengine ppc64 ppc64le mips mipsle mips64 mips64le s390x wasm + +/* + * Minio Cloud Storage, (C) 2019 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sha256 + +func blockAvx2Go(dig *digest, p []byte) {} +func blockAvxGo(dig *digest, p []byte) {} +func blockSsseGo(dig *digest, p []byte) {} +func blockShaGo(dig *digest, p []byte) {} +func blockArmGo(dig *digest, p []byte) {} diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go new file mode 100644 index 00000000..25378537 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/homedir.go @@ -0,0 +1,167 @@ +package homedir + +import ( + "bytes" + "errors" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" +) + +// DisableCache will disable caching of the home directory. Caching is enabled +// by default. +var DisableCache bool + +var homedirCache string +var cacheLock sync.RWMutex + +// Dir returns the home directory for the executing user. +// +// This uses an OS-specific method for discovering the home directory. +// An error is returned if a home directory cannot be detected. +func Dir() (string, error) { + if !DisableCache { + cacheLock.RLock() + cached := homedirCache + cacheLock.RUnlock() + if cached != "" { + return cached, nil + } + } + + cacheLock.Lock() + defer cacheLock.Unlock() + + var result string + var err error + if runtime.GOOS == "windows" { + result, err = dirWindows() + } else { + // Unix-like system, so just assume Unix + result, err = dirUnix() + } + + if err != nil { + return "", err + } + homedirCache = result + return result, nil +} + +// Expand expands the path to include the home directory if the path +// is prefixed with `~`. If it isn't prefixed with `~`, the path is +// returned as-is. +func Expand(path string) (string, error) { + if len(path) == 0 { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' && path[1] != '\\' { + return "", errors.New("cannot expand user-specific home dir") + } + + dir, err := Dir() + if err != nil { + return "", err + } + + return filepath.Join(dir, path[1:]), nil +} + +// Reset clears the cache, forcing the next call to Dir to re-detect +// the home directory. This generally never has to be called, but can be +// useful in tests if you're modifying the home directory via the HOME +// env var or something. +func Reset() { + cacheLock.Lock() + defer cacheLock.Unlock() + homedirCache = "" +} + +func dirUnix() (string, error) { + homeEnv := "HOME" + if runtime.GOOS == "plan9" { + // On plan9, env vars are lowercase. + homeEnv = "home" + } + + // First prefer the HOME environmental variable + if home := os.Getenv(homeEnv); home != "" { + return home, nil + } + + var stdout bytes.Buffer + + // If that fails, try OS specific commands + if runtime.GOOS == "darwin" { + cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`) + cmd.Stdout = &stdout + if err := cmd.Run(); err == nil { + result := strings.TrimSpace(stdout.String()) + if result != "" { + return result, nil + } + } + } else { + cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + // If the error is ErrNotFound, we ignore it. Otherwise, return it. + if err != exec.ErrNotFound { + return "", err + } + } else { + if passwd := strings.TrimSpace(stdout.String()); passwd != "" { + // username:password:uid:gid:gecos:home:shell + passwdParts := strings.SplitN(passwd, ":", 7) + if len(passwdParts) > 5 { + return passwdParts[5], nil + } + } + } + } + + // If all else fails, try the shell + stdout.Reset() + cmd := exec.Command("sh", "-c", "cd && pwd") + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return "", err + } + + result := strings.TrimSpace(stdout.String()) + if result == "" { + return "", errors.New("blank output when reading home directory") + } + + return result, nil +} + +func dirWindows() (string, error) { + // First prefer the HOME environmental variable + if home := os.Getenv("HOME"); home != "" { + return home, nil + } + + // Prefer standard environment variable USERPROFILE + if home := os.Getenv("USERPROFILE"); home != "" { + return home, nil + } + + drive := os.Getenv("HOMEDRIVE") + path := os.Getenv("HOMEPATH") + home := drive + path + if drive == "" || path == "" { + return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank") + } + + return home, nil +} diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml new file mode 100644 index 00000000..1689c7d7 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - "1.11.x" + - tip + +script: + - go test diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md new file mode 100644 index 00000000..3b3cb723 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md @@ -0,0 +1,21 @@ +## 1.1.2 + +* Fix error when decode hook decodes interface implementation into interface + type. [GH-140] + +## 1.1.1 + +* Fix panic that can happen in `decodePtr` + +## 1.1.0 + +* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] +* Support struct to struct decoding [GH-137] +* If source map value is nil, then destination map value is nil (instead of empty) +* If source slice value is nil, then destination slice value is nil (instead of empty) +* If source pointer is nil, then destination pointer is set to nil (instead of + allocated zero value of type) + +## 1.0.0 + +* Initial tagged stable release. diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go new file mode 100644 index 00000000..1f0abc65 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -0,0 +1,217 @@ +package mapstructure + +import ( + "errors" + "fmt" + "net" + "reflect" + "strconv" + "strings" + "time" +) + +// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns +// it into the proper DecodeHookFunc type, such as DecodeHookFuncType. +func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { + // Create variables here so we can reference them with the reflect pkg + var f1 DecodeHookFuncType + var f2 DecodeHookFuncKind + + // Fill in the variables into this interface and the rest is done + // automatically using the reflect package. + potential := []interface{}{f1, f2} + + v := reflect.ValueOf(h) + vt := v.Type() + for _, raw := range potential { + pt := reflect.ValueOf(raw).Type() + if vt.ConvertibleTo(pt) { + return v.Convert(pt).Interface() + } + } + + return nil +} + +// DecodeHookExec executes the given decode hook. This should be used +// since it'll naturally degrade to the older backwards compatible DecodeHookFunc +// that took reflect.Kind instead of reflect.Type. +func DecodeHookExec( + raw DecodeHookFunc, + from reflect.Type, to reflect.Type, + data interface{}) (interface{}, error) { + switch f := typedDecodeHook(raw).(type) { + case DecodeHookFuncType: + return f(from, to, data) + case DecodeHookFuncKind: + return f(from.Kind(), to.Kind(), data) + default: + return nil, errors.New("invalid decode hook signature") + } +} + +// ComposeDecodeHookFunc creates a single DecodeHookFunc that +// automatically composes multiple DecodeHookFuncs. +// +// The composed funcs are called in order, with the result of the +// previous transformation. +func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + var err error + for _, f1 := range fs { + data, err = DecodeHookExec(f1, f, t, data) + if err != nil { + return nil, err + } + + // Modify the from kind to be correct with the new data + f = nil + if val := reflect.ValueOf(data); val.IsValid() { + f = val.Type() + } + } + + return data, nil + } +} + +// StringToSliceHookFunc returns a DecodeHookFunc that converts +// string to []string by splitting on the given sep. +func StringToSliceHookFunc(sep string) DecodeHookFunc { + return func( + f reflect.Kind, + t reflect.Kind, + data interface{}) (interface{}, error) { + if f != reflect.String || t != reflect.Slice { + return data, nil + } + + raw := data.(string) + if raw == "" { + return []string{}, nil + } + + return strings.Split(raw, sep), nil + } +} + +// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts +// strings to time.Duration. +func StringToTimeDurationHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(time.Duration(5)) { + return data, nil + } + + // Convert it by parsing + return time.ParseDuration(data.(string)) + } +} + +// StringToIPHookFunc returns a DecodeHookFunc that converts +// strings to net.IP +func StringToIPHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(net.IP{}) { + return data, nil + } + + // Convert it by parsing + ip := net.ParseIP(data.(string)) + if ip == nil { + return net.IP{}, fmt.Errorf("failed parsing ip %v", data) + } + + return ip, nil + } +} + +// StringToIPNetHookFunc returns a DecodeHookFunc that converts +// strings to net.IPNet +func StringToIPNetHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(net.IPNet{}) { + return data, nil + } + + // Convert it by parsing + _, net, err := net.ParseCIDR(data.(string)) + return net, err + } +} + +// StringToTimeHookFunc returns a DecodeHookFunc that converts +// strings to time.Time. +func StringToTimeHookFunc(layout string) DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(time.Time{}) { + return data, nil + } + + // Convert it by parsing + return time.Parse(layout, data.(string)) + } +} + +// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to +// the decoder. +// +// Note that this is significantly different from the WeaklyTypedInput option +// of the DecoderConfig. +func WeaklyTypedHook( + f reflect.Kind, + t reflect.Kind, + data interface{}) (interface{}, error) { + dataVal := reflect.ValueOf(data) + switch t { + case reflect.String: + switch f { + case reflect.Bool: + if dataVal.Bool() { + return "1", nil + } + return "0", nil + case reflect.Float32: + return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil + case reflect.Int: + return strconv.FormatInt(dataVal.Int(), 10), nil + case reflect.Slice: + dataType := dataVal.Type() + elemKind := dataType.Elem().Kind() + if elemKind == reflect.Uint8 { + return string(dataVal.Interface().([]uint8)), nil + } + case reflect.Uint: + return strconv.FormatUint(dataVal.Uint(), 10), nil + } + } + + return data, nil +} diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go new file mode 100644 index 00000000..256ee63f --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -0,0 +1,1149 @@ +// Package mapstructure exposes functionality to convert an arbitrary +// map[string]interface{} into a native Go structure. +// +// The Go structure can be arbitrarily complex, containing slices, +// other structs, etc. and the decoder will properly decode nested +// maps and so on into the proper structures in the native Go struct. +// See the examples to see what the decoder is capable of. +package mapstructure + +import ( + "encoding/json" + "errors" + "fmt" + "reflect" + "sort" + "strconv" + "strings" +) + +// DecodeHookFunc is the callback function that can be used for +// data transformations. See "DecodeHook" in the DecoderConfig +// struct. +// +// The type should be DecodeHookFuncType or DecodeHookFuncKind. +// Either is accepted. Types are a superset of Kinds (Types can return +// Kinds) and are generally a richer thing to use, but Kinds are simpler +// if you only need those. +// +// The reason DecodeHookFunc is multi-typed is for backwards compatibility: +// we started with Kinds and then realized Types were the better solution, +// but have a promise to not break backwards compat so we now support +// both. +type DecodeHookFunc interface{} + +// DecodeHookFuncType is a DecodeHookFunc which has complete information about +// the source and target types. +type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) + +// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the +// source and target types. +type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) + +// DecoderConfig is the configuration that is used to create a new decoder +// and allows customization of various aspects of decoding. +type DecoderConfig struct { + // DecodeHook, if set, will be called before any decoding and any + // type conversion (if WeaklyTypedInput is on). This lets you modify + // the values before they're set down onto the resulting struct. + // + // If an error is returned, the entire decode will fail with that + // error. + DecodeHook DecodeHookFunc + + // If ErrorUnused is true, then it is an error for there to exist + // keys in the original map that were unused in the decoding process + // (extra keys). + ErrorUnused bool + + // ZeroFields, if set to true, will zero fields before writing them. + // For example, a map will be emptied before decoded values are put in + // it. If this is false, a map will be merged. + ZeroFields bool + + // If WeaklyTypedInput is true, the decoder will make the following + // "weak" conversions: + // + // - bools to string (true = "1", false = "0") + // - numbers to string (base 10) + // - bools to int/uint (true = 1, false = 0) + // - strings to int/uint (base implied by prefix) + // - int to bool (true if value != 0) + // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, + // FALSE, false, False. Anything else is an error) + // - empty array = empty map and vice versa + // - negative numbers to overflowed uint values (base 10) + // - slice of maps to a merged map + // - single values are converted to slices if required. Each + // element is weakly decoded. For example: "4" can become []int{4} + // if the target type is an int slice. + // + WeaklyTypedInput bool + + // Metadata is the struct that will contain extra metadata about + // the decoding. If this is nil, then no metadata will be tracked. + Metadata *Metadata + + // Result is a pointer to the struct that will contain the decoded + // value. + Result interface{} + + // The tag name that mapstructure reads for field names. This + // defaults to "mapstructure" + TagName string +} + +// A Decoder takes a raw interface value and turns it into structured +// data, keeping track of rich error information along the way in case +// anything goes wrong. Unlike the basic top-level Decode method, you can +// more finely control how the Decoder behaves using the DecoderConfig +// structure. The top-level Decode method is just a convenience that sets +// up the most basic Decoder. +type Decoder struct { + config *DecoderConfig +} + +// Metadata contains information about decoding a structure that +// is tedious or difficult to get otherwise. +type Metadata struct { + // Keys are the keys of the structure which were successfully decoded + Keys []string + + // Unused is a slice of keys that were found in the raw value but + // weren't decoded since there was no matching field in the result interface + Unused []string +} + +// Decode takes an input structure and uses reflection to translate it to +// the output structure. output must be a pointer to a map or struct. +func Decode(input interface{}, output interface{}) error { + config := &DecoderConfig{ + Metadata: nil, + Result: output, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// WeakDecode is the same as Decode but is shorthand to enable +// WeaklyTypedInput. See DecoderConfig for more info. +func WeakDecode(input, output interface{}) error { + config := &DecoderConfig{ + Metadata: nil, + Result: output, + WeaklyTypedInput: true, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// DecodeMetadata is the same as Decode, but is shorthand to +// enable metadata collection. See DecoderConfig for more info. +func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { + config := &DecoderConfig{ + Metadata: metadata, + Result: output, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// WeakDecodeMetadata is the same as Decode, but is shorthand to +// enable both WeaklyTypedInput and metadata collection. See +// DecoderConfig for more info. +func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { + config := &DecoderConfig{ + Metadata: metadata, + Result: output, + WeaklyTypedInput: true, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// NewDecoder returns a new decoder for the given configuration. Once +// a decoder has been returned, the same configuration must not be used +// again. +func NewDecoder(config *DecoderConfig) (*Decoder, error) { + val := reflect.ValueOf(config.Result) + if val.Kind() != reflect.Ptr { + return nil, errors.New("result must be a pointer") + } + + val = val.Elem() + if !val.CanAddr() { + return nil, errors.New("result must be addressable (a pointer)") + } + + if config.Metadata != nil { + if config.Metadata.Keys == nil { + config.Metadata.Keys = make([]string, 0) + } + + if config.Metadata.Unused == nil { + config.Metadata.Unused = make([]string, 0) + } + } + + if config.TagName == "" { + config.TagName = "mapstructure" + } + + result := &Decoder{ + config: config, + } + + return result, nil +} + +// Decode decodes the given raw interface to the target pointer specified +// by the configuration. +func (d *Decoder) Decode(input interface{}) error { + return d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) +} + +// Decodes an unknown data type into a specific reflection value. +func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { + var inputVal reflect.Value + if input != nil { + inputVal = reflect.ValueOf(input) + + // We need to check here if input is a typed nil. Typed nils won't + // match the "input == nil" below so we check that here. + if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() { + input = nil + } + } + + if input == nil { + // If the data is nil, then we don't set anything, unless ZeroFields is set + // to true. + if d.config.ZeroFields { + outVal.Set(reflect.Zero(outVal.Type())) + + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + } + return nil + } + + if !inputVal.IsValid() { + // If the input value is invalid, then we just set the value + // to be the zero value. + outVal.Set(reflect.Zero(outVal.Type())) + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + return nil + } + + if d.config.DecodeHook != nil { + // We have a DecodeHook, so let's pre-process the input. + var err error + input, err = DecodeHookExec( + d.config.DecodeHook, + inputVal.Type(), outVal.Type(), input) + if err != nil { + return fmt.Errorf("error decoding '%s': %s", name, err) + } + } + + var err error + outputKind := getKind(outVal) + switch outputKind { + case reflect.Bool: + err = d.decodeBool(name, input, outVal) + case reflect.Interface: + err = d.decodeBasic(name, input, outVal) + case reflect.String: + err = d.decodeString(name, input, outVal) + case reflect.Int: + err = d.decodeInt(name, input, outVal) + case reflect.Uint: + err = d.decodeUint(name, input, outVal) + case reflect.Float32: + err = d.decodeFloat(name, input, outVal) + case reflect.Struct: + err = d.decodeStruct(name, input, outVal) + case reflect.Map: + err = d.decodeMap(name, input, outVal) + case reflect.Ptr: + err = d.decodePtr(name, input, outVal) + case reflect.Slice: + err = d.decodeSlice(name, input, outVal) + case reflect.Array: + err = d.decodeArray(name, input, outVal) + case reflect.Func: + err = d.decodeFunc(name, input, outVal) + default: + // If we reached this point then we weren't able to decode it + return fmt.Errorf("%s: unsupported type: %s", name, outputKind) + } + + // If we reached here, then we successfully decoded SOMETHING, so + // mark the key as used if we're tracking metainput. + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + + return err +} + +// This decodes a basic type (bool, int, string, etc.) and sets the +// value to "data" of that type. +func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { + if val.IsValid() && val.Elem().IsValid() { + return d.decode(name, data, val.Elem()) + } + + dataVal := reflect.ValueOf(data) + + // If the input data is a pointer, and the assigned type is the dereference + // of that exact pointer, then indirect it so that we can assign it. + // Example: *string to string + if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() { + dataVal = reflect.Indirect(dataVal) + } + + if !dataVal.IsValid() { + dataVal = reflect.Zero(val.Type()) + } + + dataValType := dataVal.Type() + if !dataValType.AssignableTo(val.Type()) { + return fmt.Errorf( + "'%s' expected type '%s', got '%s'", + name, val.Type(), dataValType) + } + + val.Set(dataVal) + return nil +} + +func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + converted := true + switch { + case dataKind == reflect.String: + val.SetString(dataVal.String()) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetString("1") + } else { + val.SetString("0") + } + case dataKind == reflect.Int && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatInt(dataVal.Int(), 10)) + case dataKind == reflect.Uint && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) + case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) + case dataKind == reflect.Slice && d.config.WeaklyTypedInput, + dataKind == reflect.Array && d.config.WeaklyTypedInput: + dataType := dataVal.Type() + elemKind := dataType.Elem().Kind() + switch elemKind { + case reflect.Uint8: + var uints []uint8 + if dataKind == reflect.Array { + uints = make([]uint8, dataVal.Len(), dataVal.Len()) + for i := range uints { + uints[i] = dataVal.Index(i).Interface().(uint8) + } + } else { + uints = dataVal.Interface().([]uint8) + } + val.SetString(string(uints)) + default: + converted = false + } + default: + converted = false + } + + if !converted { + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + dataType := dataVal.Type() + + switch { + case dataKind == reflect.Int: + val.SetInt(dataVal.Int()) + case dataKind == reflect.Uint: + val.SetInt(int64(dataVal.Uint())) + case dataKind == reflect.Float32: + val.SetInt(int64(dataVal.Float())) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetInt(1) + } else { + val.SetInt(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) + if err == nil { + val.SetInt(i) + } else { + return fmt.Errorf("cannot parse '%s' as int: %s", name, err) + } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Int64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetInt(i) + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + switch { + case dataKind == reflect.Int: + i := dataVal.Int() + if i < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %d overflows uint", + name, i) + } + val.SetUint(uint64(i)) + case dataKind == reflect.Uint: + val.SetUint(dataVal.Uint()) + case dataKind == reflect.Float32: + f := dataVal.Float() + if f < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %f overflows uint", + name, f) + } + val.SetUint(uint64(f)) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetUint(1) + } else { + val.SetUint(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) + if err == nil { + val.SetUint(i) + } else { + return fmt.Errorf("cannot parse '%s' as uint: %s", name, err) + } + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + switch { + case dataKind == reflect.Bool: + val.SetBool(dataVal.Bool()) + case dataKind == reflect.Int && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Int() != 0) + case dataKind == reflect.Uint && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Uint() != 0) + case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Float() != 0) + case dataKind == reflect.String && d.config.WeaklyTypedInput: + b, err := strconv.ParseBool(dataVal.String()) + if err == nil { + val.SetBool(b) + } else if dataVal.String() == "" { + val.SetBool(false) + } else { + return fmt.Errorf("cannot parse '%s' as bool: %s", name, err) + } + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + dataType := dataVal.Type() + + switch { + case dataKind == reflect.Int: + val.SetFloat(float64(dataVal.Int())) + case dataKind == reflect.Uint: + val.SetFloat(float64(dataVal.Uint())) + case dataKind == reflect.Float32: + val.SetFloat(dataVal.Float()) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetFloat(1) + } else { + val.SetFloat(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) + if err == nil { + val.SetFloat(f) + } else { + return fmt.Errorf("cannot parse '%s' as float: %s", name, err) + } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Float64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetFloat(i) + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { + valType := val.Type() + valKeyType := valType.Key() + valElemType := valType.Elem() + + // By default we overwrite keys in the current map + valMap := val + + // If the map is nil or we're purposely zeroing fields, make a new map + if valMap.IsNil() || d.config.ZeroFields { + // Make a new map to hold our result + mapType := reflect.MapOf(valKeyType, valElemType) + valMap = reflect.MakeMap(mapType) + } + + // Check input type and based on the input type jump to the proper func + dataVal := reflect.Indirect(reflect.ValueOf(data)) + switch dataVal.Kind() { + case reflect.Map: + return d.decodeMapFromMap(name, dataVal, val, valMap) + + case reflect.Struct: + return d.decodeMapFromStruct(name, dataVal, val, valMap) + + case reflect.Array, reflect.Slice: + if d.config.WeaklyTypedInput { + return d.decodeMapFromSlice(name, dataVal, val, valMap) + } + + fallthrough + + default: + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + } +} + +func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + // Special case for BC reasons (covered by tests) + if dataVal.Len() == 0 { + val.Set(valMap) + return nil + } + + for i := 0; i < dataVal.Len(); i++ { + err := d.decode( + fmt.Sprintf("%s[%d]", name, i), + dataVal.Index(i).Interface(), val) + if err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + valType := val.Type() + valKeyType := valType.Key() + valElemType := valType.Elem() + + // Accumulate errors + errors := make([]string, 0) + + // If the input data is empty, then we just match what the input data is. + if dataVal.Len() == 0 { + if dataVal.IsNil() { + if !val.IsNil() { + val.Set(dataVal) + } + } else { + // Set to empty allocated value + val.Set(valMap) + } + + return nil + } + + for _, k := range dataVal.MapKeys() { + fieldName := fmt.Sprintf("%s[%s]", name, k) + + // First decode the key into the proper type + currentKey := reflect.Indirect(reflect.New(valKeyType)) + if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { + errors = appendErrors(errors, err) + continue + } + + // Next decode the data into the proper type + v := dataVal.MapIndex(k).Interface() + currentVal := reflect.Indirect(reflect.New(valElemType)) + if err := d.decode(fieldName, v, currentVal); err != nil { + errors = appendErrors(errors, err) + continue + } + + valMap.SetMapIndex(currentKey, currentVal) + } + + // Set the built up map to the value + val.Set(valMap) + + // If we had errors, return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + typ := dataVal.Type() + for i := 0; i < typ.NumField(); i++ { + // Get the StructField first since this is a cheap operation. If the + // field is unexported, then ignore it. + f := typ.Field(i) + if f.PkgPath != "" { + continue + } + + // Next get the actual value of this field and verify it is assignable + // to the map value. + v := dataVal.Field(i) + if !v.Type().AssignableTo(valMap.Type().Elem()) { + return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem()) + } + + tagValue := f.Tag.Get(d.config.TagName) + tagParts := strings.Split(tagValue, ",") + + // Determine the name of the key in the map + keyName := f.Name + if tagParts[0] != "" { + if tagParts[0] == "-" { + continue + } + keyName = tagParts[0] + } + + // If "squash" is specified in the tag, we squash the field down. + squash := false + for _, tag := range tagParts[1:] { + if tag == "squash" { + squash = true + break + } + } + if squash && v.Kind() != reflect.Struct { + return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) + } + + switch v.Kind() { + // this is an embedded struct, so handle it differently + case reflect.Struct: + x := reflect.New(v.Type()) + x.Elem().Set(v) + + vType := valMap.Type() + vKeyType := vType.Key() + vElemType := vType.Elem() + mType := reflect.MapOf(vKeyType, vElemType) + vMap := reflect.MakeMap(mType) + + err := d.decode(keyName, x.Interface(), vMap) + if err != nil { + return err + } + + if squash { + for _, k := range vMap.MapKeys() { + valMap.SetMapIndex(k, vMap.MapIndex(k)) + } + } else { + valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) + } + + default: + valMap.SetMapIndex(reflect.ValueOf(keyName), v) + } + } + + if val.CanAddr() { + val.Set(valMap) + } + + return nil +} + +func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { + // If the input data is nil, then we want to just set the output + // pointer to be nil as well. + isNil := data == nil + if !isNil { + switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() { + case reflect.Chan, + reflect.Func, + reflect.Interface, + reflect.Map, + reflect.Ptr, + reflect.Slice: + isNil = v.IsNil() + } + } + if isNil { + if !val.IsNil() && val.CanSet() { + nilValue := reflect.New(val.Type()).Elem() + val.Set(nilValue) + } + + return nil + } + + // Create an element of the concrete (non pointer) type and decode + // into that. Then set the value of the pointer to this type. + valType := val.Type() + valElemType := valType.Elem() + if val.CanSet() { + realVal := val + if realVal.IsNil() || d.config.ZeroFields { + realVal = reflect.New(valElemType) + } + + if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { + return err + } + + val.Set(realVal) + } else { + if err := d.decode(name, data, reflect.Indirect(val)); err != nil { + return err + } + } + return nil +} + +func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { + // Create an element of the concrete (non pointer) type and decode + // into that. Then set the value of the pointer to this type. + dataVal := reflect.Indirect(reflect.ValueOf(data)) + if val.Type() != dataVal.Type() { + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + val.Set(dataVal) + return nil +} + +func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataValKind := dataVal.Kind() + valType := val.Type() + valElemType := valType.Elem() + sliceType := reflect.SliceOf(valElemType) + + valSlice := val + if valSlice.IsNil() || d.config.ZeroFields { + if d.config.WeaklyTypedInput { + switch { + // Slice and array we use the normal logic + case dataValKind == reflect.Slice, dataValKind == reflect.Array: + break + + // Empty maps turn into empty slices + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.MakeSlice(sliceType, 0, 0)) + return nil + } + // Create slice of maps of other sizes + return d.decodeSlice(name, []interface{}{data}, val) + + case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: + return d.decodeSlice(name, []byte(dataVal.String()), val) + + // All other types we try to convert to the slice type + // and "lift" it into it. i.e. a string becomes a string slice. + default: + // Just re-try this function with data as a slice. + return d.decodeSlice(name, []interface{}{data}, val) + } + } + + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + return fmt.Errorf( + "'%s': source data must be an array or slice, got %s", name, dataValKind) + + } + + // If the input value is empty, then don't allocate since non-nil != nil + if dataVal.Len() == 0 { + return nil + } + + // Make a new slice to hold our result, same size as the original data. + valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + } + + // Accumulate any errors + errors := make([]string, 0) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + for valSlice.Len() <= i { + valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) + } + currentField := valSlice.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := d.decode(fieldName, currentData, currentField); err != nil { + errors = appendErrors(errors, err) + } + } + + // Finally, set the value to the slice we built up + val.Set(valSlice) + + // If there were errors, we return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataValKind := dataVal.Kind() + valType := val.Type() + valElemType := valType.Elem() + arrayType := reflect.ArrayOf(valType.Len(), valElemType) + + valArray := val + + if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + if d.config.WeaklyTypedInput { + switch { + // Empty maps turn into empty arrays + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.Zero(arrayType)) + return nil + } + + // All other types we try to convert to the array type + // and "lift" it into it. i.e. a string becomes a string array. + default: + // Just re-try this function with data as a slice. + return d.decodeArray(name, []interface{}{data}, val) + } + } + + return fmt.Errorf( + "'%s': source data must be an array or slice, got %s", name, dataValKind) + + } + if dataVal.Len() > arrayType.Len() { + return fmt.Errorf( + "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) + + } + + // Make a new array to hold our result, same size as the original data. + valArray = reflect.New(arrayType).Elem() + } + + // Accumulate any errors + errors := make([]string, 0) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + currentField := valArray.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := d.decode(fieldName, currentData, currentField); err != nil { + errors = appendErrors(errors, err) + } + } + + // Finally, set the value to the array we built up + val.Set(valArray) + + // If there were errors, we return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + + // If the type of the value to write to and the data match directly, + // then we just set it directly instead of recursing into the structure. + if dataVal.Type() == val.Type() { + val.Set(dataVal) + return nil + } + + dataValKind := dataVal.Kind() + switch dataValKind { + case reflect.Map: + return d.decodeStructFromMap(name, dataVal, val) + + case reflect.Struct: + // Not the most efficient way to do this but we can optimize later if + // we want to. To convert from struct to struct we go to map first + // as an intermediary. + m := make(map[string]interface{}) + mval := reflect.Indirect(reflect.ValueOf(&m)) + if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil { + return err + } + + result := d.decodeStructFromMap(name, mval, val) + return result + + default: + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + } +} + +func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error { + dataValType := dataVal.Type() + if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { + return fmt.Errorf( + "'%s' needs a map with string keys, has '%s' keys", + name, dataValType.Key().Kind()) + } + + dataValKeys := make(map[reflect.Value]struct{}) + dataValKeysUnused := make(map[interface{}]struct{}) + for _, dataValKey := range dataVal.MapKeys() { + dataValKeys[dataValKey] = struct{}{} + dataValKeysUnused[dataValKey.Interface()] = struct{}{} + } + + errors := make([]string, 0) + + // This slice will keep track of all the structs we'll be decoding. + // There can be more than one struct if there are embedded structs + // that are squashed. + structs := make([]reflect.Value, 1, 5) + structs[0] = val + + // Compile the list of all the fields that we're going to be decoding + // from all the structs. + type field struct { + field reflect.StructField + val reflect.Value + } + fields := []field{} + for len(structs) > 0 { + structVal := structs[0] + structs = structs[1:] + + structType := structVal.Type() + + for i := 0; i < structType.NumField(); i++ { + fieldType := structType.Field(i) + fieldKind := fieldType.Type.Kind() + + // If "squash" is specified in the tag, we squash the field down. + squash := false + tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") + for _, tag := range tagParts[1:] { + if tag == "squash" { + squash = true + break + } + } + + if squash { + if fieldKind != reflect.Struct { + errors = appendErrors(errors, + fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) + } else { + structs = append(structs, structVal.FieldByName(fieldType.Name)) + } + continue + } + + // Normal struct field, store it away + fields = append(fields, field{fieldType, structVal.Field(i)}) + } + } + + // for fieldType, field := range fields { + for _, f := range fields { + field, fieldValue := f.field, f.val + fieldName := field.Name + + tagValue := field.Tag.Get(d.config.TagName) + tagValue = strings.SplitN(tagValue, ",", 2)[0] + if tagValue != "" { + fieldName = tagValue + } + + rawMapKey := reflect.ValueOf(fieldName) + rawMapVal := dataVal.MapIndex(rawMapKey) + if !rawMapVal.IsValid() { + // Do a slower search by iterating over each key and + // doing case-insensitive search. + for dataValKey := range dataValKeys { + mK, ok := dataValKey.Interface().(string) + if !ok { + // Not a string key + continue + } + + if strings.EqualFold(mK, fieldName) { + rawMapKey = dataValKey + rawMapVal = dataVal.MapIndex(dataValKey) + break + } + } + + if !rawMapVal.IsValid() { + // There was no matching key in the map for the value in + // the struct. Just ignore. + continue + } + } + + // Delete the key we're using from the unused map so we stop tracking + delete(dataValKeysUnused, rawMapKey.Interface()) + + if !fieldValue.IsValid() { + // This should never happen + panic("field is not valid") + } + + // If we can't set the field, then it is unexported or something, + // and we just continue onwards. + if !fieldValue.CanSet() { + continue + } + + // If the name is empty string, then we're at the root, and we + // don't dot-join the fields. + if name != "" { + fieldName = fmt.Sprintf("%s.%s", name, fieldName) + } + + if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { + errors = appendErrors(errors, err) + } + } + + if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { + keys := make([]string, 0, len(dataValKeysUnused)) + for rawKey := range dataValKeysUnused { + keys = append(keys, rawKey.(string)) + } + sort.Strings(keys) + + err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) + errors = appendErrors(errors, err) + } + + if len(errors) > 0 { + return &Error{errors} + } + + // Add the unused keys to the list of unused keys if we're tracking metadata + if d.config.Metadata != nil { + for rawKey := range dataValKeysUnused { + key := rawKey.(string) + if name != "" { + key = fmt.Sprintf("%s.%s", name, key) + } + + d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) + } + } + + return nil +} + +func getKind(val reflect.Value) reflect.Kind { + kind := val.Kind() + + switch { + case kind >= reflect.Int && kind <= reflect.Int64: + return reflect.Int + case kind >= reflect.Uint && kind <= reflect.Uint64: + return reflect.Uint + case kind >= reflect.Float32 && kind <= reflect.Float64: + return reflect.Float32 + default: + return kind + } +} diff --git a/vendor/github.com/mmcloughlin/avo/LICENSE b/vendor/github.com/mmcloughlin/avo/LICENSE new file mode 100644 index 00000000..c986d807 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Michael McLoughlin +All rights reserved. + +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 the copyright holder 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 HOLDER 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. diff --git a/vendor/github.com/mmcloughlin/avo/attr/attr.go b/vendor/github.com/mmcloughlin/avo/attr/attr.go new file mode 100644 index 00000000..9173773f --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/attr/attr.go @@ -0,0 +1,97 @@ +// Package attr provides attributes for text and data sections. +package attr + +import ( + "fmt" + "math/bits" + "strings" +) + +// Attribute represents TEXT or DATA flags. +type Attribute uint16 + +// Reference: https://github.com/golang/go/blob/35f4ec152b44ae5fc83aaf68e2eb3aa1a778e5cd/src/runtime/textflag.h#L11-L34 +// +// // Don't profile the marked routine. This flag is deprecated. +// #define NOPROF 1 +// // It is ok for the linker to get multiple of these symbols. It will +// // pick one of the duplicates to use. +// #define DUPOK 2 +// // Don't insert stack check preamble. +// #define NOSPLIT 4 +// // Put this data in a read-only section. +// #define RODATA 8 +// // This data contains no pointers. +// #define NOPTR 16 +// // This is a wrapper function and should not count as disabling 'recover'. +// #define WRAPPER 32 +// // This function uses its incoming context register. +// #define NEEDCTXT 64 +// // Allocate a word of thread local storage and store the offset from the +// // thread local base to the thread local storage in this variable. +// #define TLSBSS 256 +// // Do not insert instructions to allocate a stack frame for this function. +// // Only valid on functions that declare a frame size of 0. +// // TODO(mwhudson): only implemented for ppc64x at present. +// #define NOFRAME 512 +// // Function can call reflect.Type.Method or reflect.Type.MethodByName. +// #define REFLECTMETHOD 1024 +// +const ( + NOPROF Attribute = 1 << iota + DUPOK + NOSPLIT + RODATA + NOPTR + WRAPPER + NEEDCTXT + _ + TLSBSS + NOFRAME + REFLECTMETHOD +) + +// Asm returns a representation of the attributes in assembly syntax. This may use macros from "textflags.h"; see ContainsTextFlags() to determine if this header is required. +func (a Attribute) Asm() string { + parts, rest := a.split() + if len(parts) == 0 || rest != 0 { + parts = append(parts, fmt.Sprintf("%d", rest)) + } + return strings.Join(parts, "|") +} + +// ContainsTextFlags returns whether the Asm() representation requires macros in "textflags.h". +func (a Attribute) ContainsTextFlags() bool { + flags, _ := a.split() + return len(flags) > 0 +} + +// split splits a into known flags and any remaining bits. +func (a Attribute) split() ([]string, Attribute) { + var flags []string + var rest Attribute + for a != 0 { + i := uint(bits.TrailingZeros16(uint16(a))) + bit := Attribute(1) << i + if flag := attrname[bit]; flag != "" { + flags = append(flags, flag) + } else { + rest |= bit + } + a ^= bit + } + return flags, rest +} + +var attrname = map[Attribute]string{ + NOPROF: "NOPROF", + DUPOK: "DUPOK", + NOSPLIT: "NOSPLIT", + RODATA: "RODATA", + NOPTR: "NOPTR", + WRAPPER: "WRAPPER", + NEEDCTXT: "NEEDCTXT", + TLSBSS: "TLSBSS", + NOFRAME: "NOFRAME", + // REFLECTMETHOD excluded due to https://golang.org/issue/29487 +} diff --git a/vendor/github.com/mmcloughlin/avo/build/attr.go b/vendor/github.com/mmcloughlin/avo/build/attr.go new file mode 100644 index 00000000..d337537c --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/attr.go @@ -0,0 +1,17 @@ +package build + +import "github.com/mmcloughlin/avo/attr" + +// TEXT and DATA attribute values included for convenience. +const ( + NOPROF = attr.NOPROF + DUPOK = attr.DUPOK + NOSPLIT = attr.NOSPLIT + RODATA = attr.RODATA + NOPTR = attr.NOPTR + WRAPPER = attr.WRAPPER + NEEDCTXT = attr.NEEDCTXT + TLSBSS = attr.TLSBSS + NOFRAME = attr.NOFRAME + REFLECTMETHOD = attr.REFLECTMETHOD +) diff --git a/vendor/github.com/mmcloughlin/avo/build/cli.go b/vendor/github.com/mmcloughlin/avo/build/cli.go new file mode 100644 index 00000000..7474cbca --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/cli.go @@ -0,0 +1,165 @@ +package build + +import ( + "flag" + "io" + "log" + "os" + "runtime/pprof" + + "github.com/mmcloughlin/avo/pass" + "github.com/mmcloughlin/avo/printer" +) + +// Config contains options for an avo main function. +type Config struct { + ErrOut io.Writer + MaxErrors int // max errors to report; 0 means unlimited + CPUProfile io.WriteCloser + Passes []pass.Interface +} + +// Main is the standard main function for an avo program. This extracts the +// result from the build Context (logging and exiting on error), and performs +// configured passes. +func Main(cfg *Config, context *Context) int { + diag := log.New(cfg.ErrOut, "", 0) + + if cfg.CPUProfile != nil { + defer cfg.CPUProfile.Close() + if err := pprof.StartCPUProfile(cfg.CPUProfile); err != nil { + diag.Println("could not start CPU profile: ", err) + return 1 + } + defer pprof.StopCPUProfile() + } + + f, err := context.Result() + if err != nil { + LogError(diag, err, cfg.MaxErrors) + return 1 + } + + p := pass.Concat(cfg.Passes...) + if err := p.Execute(f); err != nil { + diag.Println(err) + return 1 + } + + return 0 +} + +// Flags represents CLI flags for an avo program. +type Flags struct { + errout *outputValue + allerrors bool + cpuprof *outputValue + printers []*printerValue +} + +// NewFlags initializes avo flags for the given FlagSet. +func NewFlags(fs *flag.FlagSet) *Flags { + f := &Flags{} + + f.errout = newOutputValue(os.Stderr) + fs.Var(f.errout, "log", "diagnostics output") + + fs.BoolVar(&f.allerrors, "e", false, "no limit on number of errors reported") + + f.cpuprof = newOutputValue(nil) + fs.Var(f.cpuprof, "cpuprofile", "write cpu profile to `file`") + + goasm := newPrinterValue(printer.NewGoAsm, os.Stdout) + fs.Var(goasm, "out", "assembly output") + f.printers = append(f.printers, goasm) + + stubs := newPrinterValue(printer.NewStubs, nil) + fs.Var(stubs, "stubs", "go stub file") + f.printers = append(f.printers, stubs) + + return f +} + +// Config builds a configuration object based on flag values. +func (f *Flags) Config() *Config { + pc := printer.NewGoRunConfig() + passes := []pass.Interface{pass.Compile} + for _, pv := range f.printers { + p := pv.Build(pc) + if p != nil { + passes = append(passes, p) + } + } + + cfg := &Config{ + ErrOut: f.errout.w, + MaxErrors: 10, + CPUProfile: f.cpuprof.w, + Passes: passes, + } + + if f.allerrors { + cfg.MaxErrors = 0 + } + + return cfg +} + +type outputValue struct { + w io.WriteCloser + filename string +} + +func newOutputValue(dflt io.WriteCloser) *outputValue { + return &outputValue{w: dflt} +} + +func (o *outputValue) String() string { + if o == nil { + return "" + } + return o.filename +} + +func (o *outputValue) Set(s string) error { + o.filename = s + if s == "-" { + o.w = nopwritecloser{os.Stdout} + return nil + } + f, err := os.Create(s) + if err != nil { + return err + } + o.w = f + return nil +} + +type printerValue struct { + *outputValue + Builder printer.Builder +} + +func newPrinterValue(b printer.Builder, dflt io.WriteCloser) *printerValue { + return &printerValue{ + outputValue: newOutputValue(dflt), + Builder: b, + } +} + +func (p *printerValue) Build(cfg printer.Config) pass.Interface { + if p.outputValue.w == nil { + return nil + } + return &pass.Output{ + Writer: p.outputValue.w, + Printer: p.Builder(cfg), + } +} + +// nopwritecloser wraps a Writer and provides a null implementation of Close(). +type nopwritecloser struct { + io.Writer +} + +func (nopwritecloser) Close() error { return nil } diff --git a/vendor/github.com/mmcloughlin/avo/build/context.go b/vendor/github.com/mmcloughlin/avo/build/context.go new file mode 100644 index 00000000..d1a1ec51 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/context.go @@ -0,0 +1,217 @@ +package build + +import ( + "errors" + "fmt" + "go/types" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" + "golang.org/x/tools/go/packages" +) + +// Context maintains state for incrementally building an avo File. +type Context struct { + pkg *packages.Package + file *ir.File + function *ir.Function + global *ir.Global + errs ErrorList + reg.Collection +} + +// NewContext initializes an empty build Context. +func NewContext() *Context { + return &Context{ + file: ir.NewFile(), + Collection: *reg.NewCollection(), + } +} + +// Package sets the package the generated file will belong to. Required to be able to reference types in the package. +func (c *Context) Package(path string) { + cfg := &packages.Config{ + Mode: packages.NeedTypes | packages.NeedDeps, + } + pkgs, err := packages.Load(cfg, path) + if err != nil { + c.adderror(err) + return + } + pkg := pkgs[0] + if len(pkg.Errors) > 0 { + for _, err := range pkg.Errors { + c.adderror(err) + } + return + } + c.pkg = pkg +} + +// Constraints sets build constraints for the file. +func (c *Context) Constraints(t buildtags.ConstraintsConvertable) { + cs := t.ToConstraints() + if err := cs.Validate(); err != nil { + c.adderror(err) + return + } + c.file.Constraints = cs +} + +// Constraint appends a constraint to the file's build constraints. +func (c *Context) Constraint(t buildtags.ConstraintConvertable) { + c.Constraints(append(c.file.Constraints, t.ToConstraint())) +} + +// ConstraintExpr appends a constraint to the file's build constraints. The +// constraint to add is parsed from the given expression. The expression should +// look the same as the content following "// +build " in regular build +// constraint comments. +func (c *Context) ConstraintExpr(expr string) { + constraint, err := buildtags.ParseConstraint(expr) + if err != nil { + c.adderror(err) + return + } + c.Constraint(constraint) +} + +// Function starts building a new function with the given name. +func (c *Context) Function(name string) { + c.function = ir.NewFunction(name) + c.file.AddSection(c.function) +} + +// Doc sets documentation comment lines for the currently active function. +func (c *Context) Doc(lines ...string) { + c.activefunc().Doc = lines +} + +// Attributes sets function attributes for the currently active function. +func (c *Context) Attributes(a attr.Attribute) { + c.activefunc().Attributes = a +} + +// Signature sets the signature for the currently active function. +func (c *Context) Signature(s *gotypes.Signature) { + c.activefunc().SetSignature(s) +} + +// SignatureExpr parses the signature expression and sets it as the active function's signature. +func (c *Context) SignatureExpr(expr string) { + s, err := gotypes.ParseSignatureInPackage(c.types(), expr) + if err != nil { + c.adderror(err) + return + } + c.Signature(s) +} + +// Implement starts building a function of the given name, whose type is +// specified by a stub in the containing package. +func (c *Context) Implement(name string) { + pkg := c.types() + if pkg == nil { + c.adderrormessage("no package specified") + return + } + s, err := gotypes.LookupSignature(pkg, name) + if err != nil { + c.adderror(err) + return + } + c.Function(name) + c.Signature(s) +} + +func (c *Context) types() *types.Package { + if c.pkg == nil { + return nil + } + return c.pkg.Types +} + +// AllocLocal allocates size bytes in the stack of the currently active function. +// Returns a reference to the base pointer for the newly allocated region. +func (c *Context) AllocLocal(size int) operand.Mem { + return c.activefunc().AllocLocal(size) +} + +// Instruction adds an instruction to the active function. +func (c *Context) Instruction(i *ir.Instruction) { + c.activefunc().AddInstruction(i) +} + +// Label adds a label to the active function. +func (c *Context) Label(name string) { + c.activefunc().AddLabel(ir.Label(name)) +} + +// Comment adds comment lines to the active function. +func (c *Context) Comment(lines ...string) { + c.activefunc().AddComment(lines...) +} + +// Commentf adds a formtted comment line. +func (c *Context) Commentf(format string, a ...interface{}) { + c.Comment(fmt.Sprintf(format, a...)) +} + +func (c *Context) activefunc() *ir.Function { + if c.function == nil { + c.adderrormessage("no active function") + return ir.NewFunction("") + } + return c.function +} + +//go:generate avogen -output zinstructions.go build + +// StaticGlobal adds a new static data section to the file and returns a pointer to it. +func (c *Context) StaticGlobal(name string) operand.Mem { + c.global = ir.NewStaticGlobal(name) + c.file.AddSection(c.global) + return c.global.Base() +} + +// DataAttributes sets the attributes on the current active global data section. +func (c *Context) DataAttributes(a attr.Attribute) { + c.activeglobal().Attributes = a +} + +// AddDatum adds constant v at offset to the current active global data section. +func (c *Context) AddDatum(offset int, v operand.Constant) { + if err := c.activeglobal().AddDatum(ir.NewDatum(offset, v)); err != nil { + c.adderror(err) + } +} + +// AppendDatum appends a constant to the current active global data section. +func (c *Context) AppendDatum(v operand.Constant) { + c.activeglobal().Append(v) +} + +func (c *Context) activeglobal() *ir.Global { + if c.global == nil { + c.adderrormessage("no active global") + return ir.NewStaticGlobal("") + } + return c.global +} + +func (c *Context) adderror(err error) { + c.errs.addext(err) +} + +func (c *Context) adderrormessage(msg string) { + c.adderror(errors.New(msg)) +} + +// Result returns the built file and any accumulated errors. +func (c *Context) Result() (*ir.File, error) { + return c.file, c.errs.Err() +} diff --git a/vendor/github.com/mmcloughlin/avo/build/doc.go b/vendor/github.com/mmcloughlin/avo/build/doc.go new file mode 100644 index 00000000..8b9a6047 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/doc.go @@ -0,0 +1,2 @@ +// Package build provides an assembly-like interface for incremental building of avo Files. +package build diff --git a/vendor/github.com/mmcloughlin/avo/build/error.go b/vendor/github.com/mmcloughlin/avo/build/error.go new file mode 100644 index 00000000..1da00cbf --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/error.go @@ -0,0 +1,88 @@ +package build + +import ( + "fmt" + "log" + + "github.com/mmcloughlin/avo/internal/stack" + "github.com/mmcloughlin/avo/src" +) + +// Error represents an error during building, optionally tagged with the position at which it happened. +type Error struct { + Position src.Position + Err error +} + +// exterr constructs an Error with position derived from the first frame in the +// call stack outside this package. +func exterr(err error) Error { + e := Error{Err: err} + if f := stack.ExternalCaller(); f != nil { + e.Position = src.FramePosition(*f).Relwd() + } + return e +} + +func (e Error) Error() string { + msg := e.Err.Error() + if e.Position.IsValid() { + return e.Position.String() + ": " + msg + } + return msg +} + +// ErrorList is a collection of errors for a source file. +type ErrorList []Error + +// Add appends an error to the list. +func (e *ErrorList) Add(err Error) { + *e = append(*e, err) +} + +// AddAt appends an error at position p. +func (e *ErrorList) AddAt(p src.Position, err error) { + e.Add(Error{p, err}) +} + +// addext appends an error to the list, tagged with the +func (e *ErrorList) addext(err error) { + e.Add(exterr(err)) +} + +// Err returns an error equivalent to this error list. +// If the list is empty, Err returns nil. +func (e ErrorList) Err() error { + if len(e) == 0 { + return nil + } + return e +} + +// An ErrorList implements the error interface. +func (e ErrorList) Error() string { + switch len(e) { + case 0: + return "no errors" + case 1: + return e[0].Error() + } + return fmt.Sprintf("%s (and %d more errors)", e[0], len(e)-1) +} + +// LogError logs a list of errors, one error per line, if the err parameter is +// an ErrorList. Otherwise it just logs the err string. Reports at most max +// errors, or unlimited if max is 0. +func LogError(l *log.Logger, err error, max int) { + if list, ok := err.(ErrorList); ok { + for i, e := range list { + if max > 0 && i == max { + l.Print("too many errors") + return + } + l.Printf("%s\n", e) + } + } else if err != nil { + l.Printf("%s\n", err) + } +} diff --git a/vendor/github.com/mmcloughlin/avo/build/global.go b/vendor/github.com/mmcloughlin/avo/build/global.go new file mode 100644 index 00000000..148b90cf --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/global.go @@ -0,0 +1,142 @@ +package build + +import ( + "flag" + "os" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/operand" + + "github.com/mmcloughlin/avo/reg" +) + +// ctx provides a global build context. +var ctx = NewContext() + +// TEXT starts building a new function called name, with attributes a, and sets its signature (see SignatureExpr). +func TEXT(name string, a attr.Attribute, signature string) { + ctx.Function(name) + ctx.Attributes(a) + ctx.SignatureExpr(signature) +} + +// GLOBL declares a new static global data section with the given attributes. +func GLOBL(name string, a attr.Attribute) operand.Mem { + // TODO(mbm): should this be static? + g := ctx.StaticGlobal(name) + ctx.DataAttributes(a) + return g +} + +// DATA adds a data value to the active data section. +func DATA(offset int, v operand.Constant) { + ctx.AddDatum(offset, v) +} + +var flags = NewFlags(flag.CommandLine) + +// Generate builds and compiles the avo file built with the global context. This +// should be the final line of any avo program. Configuration is determined from command-line flags. +func Generate() { + if !flag.Parsed() { + flag.Parse() + } + cfg := flags.Config() + + status := Main(cfg, ctx) + + // To record coverage of integration tests we wrap main() functions in a test + // functions. In this case we need the main function to terminate, therefore we + // only exit for failure status codes. + if status != 0 { + os.Exit(status) + } +} + +// Package sets the package the generated file will belong to. Required to be able to reference types in the package. +func Package(path string) { ctx.Package(path) } + +// Constraints sets build constraints for the file. +func Constraints(t buildtags.ConstraintsConvertable) { ctx.Constraints(t) } + +// Constraint appends a constraint to the file's build constraints. +func Constraint(t buildtags.ConstraintConvertable) { ctx.Constraint(t) } + +// ConstraintExpr appends a constraint to the file's build constraints. The +// constraint to add is parsed from the given expression. The expression should +// look the same as the content following "// +build " in regular build +// constraint comments. +func ConstraintExpr(expr string) { ctx.ConstraintExpr(expr) } + +// GP8 allocates and returns a general-purpose 8-bit register. +func GP8() reg.GPVirtual { return ctx.GP8() } + +// GP16 allocates and returns a general-purpose 16-bit register. +func GP16() reg.GPVirtual { return ctx.GP16() } + +// GP32 allocates and returns a general-purpose 32-bit register. +func GP32() reg.GPVirtual { return ctx.GP32() } + +// GP64 allocates and returns a general-purpose 64-bit register. +func GP64() reg.GPVirtual { return ctx.GP64() } + +// XMM allocates and returns a 128-bit vector register. +func XMM() reg.VecVirtual { return ctx.XMM() } + +// YMM allocates and returns a 256-bit vector register. +func YMM() reg.VecVirtual { return ctx.YMM() } + +// ZMM allocates and returns a 512-bit vector register. +func ZMM() reg.VecVirtual { return ctx.ZMM() } + +// Param returns a the named argument of the active function. +func Param(name string) gotypes.Component { return ctx.Param(name) } + +// ParamIndex returns the ith argument of the active function. +func ParamIndex(i int) gotypes.Component { return ctx.ParamIndex(i) } + +// Return returns a the named return value of the active function. +func Return(name string) gotypes.Component { return ctx.Return(name) } + +// ReturnIndex returns the ith argument of the active function. +func ReturnIndex(i int) gotypes.Component { return ctx.ReturnIndex(i) } + +// Load the function argument src into register dst. Returns the destination +// register. This is syntactic sugar: it will attempt to select the right MOV +// instruction based on the types involved. +func Load(src gotypes.Component, dst reg.Register) reg.Register { return ctx.Load(src, dst) } + +// Store register src into return value dst. This is syntactic sugar: it will +// attempt to select the right MOV instruction based on the types involved. +func Store(src reg.Register, dst gotypes.Component) { ctx.Store(src, dst) } + +// Dereference loads a pointer and returns its element type. +func Dereference(ptr gotypes.Component) gotypes.Component { return ctx.Dereference(ptr) } + +// Doc sets documentation comment lines for the currently active function. +func Doc(lines ...string) { ctx.Doc(lines...) } + +// Attributes sets function attributes for the currently active function. +func Attributes(a attr.Attribute) { ctx.Attributes(a) } + +// Implement starts building a function of the given name, whose type is +// specified by a stub in the containing package. +func Implement(name string) { ctx.Implement(name) } + +// AllocLocal allocates size bytes in the stack of the currently active function. +// Returns a reference to the base pointer for the newly allocated region. +func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) } + +// Label adds a label to the active function. +func Label(name string) { ctx.Label(name) } + +// Comment adds comment lines to the active function. +func Comment(lines ...string) { ctx.Comment(lines...) } + +// Commentf adds a formtted comment line. +func Commentf(format string, a ...interface{}) { ctx.Commentf(format, a...) } + +// ConstData builds a static data section containing just the given constant. +func ConstData(name string, v operand.Constant) operand.Mem { return ctx.ConstData(name, v) } diff --git a/vendor/github.com/mmcloughlin/avo/build/pseudo.go b/vendor/github.com/mmcloughlin/avo/build/pseudo.go new file mode 100644 index 00000000..83a570e4 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/pseudo.go @@ -0,0 +1,70 @@ +package build + +import ( + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" + + "github.com/mmcloughlin/avo/gotypes" +) + +//go:generate avogen -output zmov.go mov + +// Param returns a the named argument of the active function. +func (c *Context) Param(name string) gotypes.Component { + return c.activefunc().Signature.Params().Lookup(name) +} + +// ParamIndex returns the ith argument of the active function. +func (c *Context) ParamIndex(i int) gotypes.Component { + return c.activefunc().Signature.Params().At(i) +} + +// Return returns a the named return value of the active function. +func (c *Context) Return(name string) gotypes.Component { + return c.activefunc().Signature.Results().Lookup(name) +} + +// ReturnIndex returns the ith argument of the active function. +func (c *Context) ReturnIndex(i int) gotypes.Component { + return c.activefunc().Signature.Results().At(i) +} + +// Load the function argument src into register dst. Returns the destination +// register. This is syntactic sugar: it will attempt to select the right MOV +// instruction based on the types involved. +func (c *Context) Load(src gotypes.Component, dst reg.Register) reg.Register { + b, err := src.Resolve() + if err != nil { + c.adderror(err) + return dst + } + c.mov(b.Addr, dst, int(gotypes.Sizes.Sizeof(b.Type)), int(dst.Size()), b.Type) + return dst +} + +// Store register src into return value dst. This is syntactic sugar: it will +// attempt to select the right MOV instruction based on the types involved. +func (c *Context) Store(src reg.Register, dst gotypes.Component) { + b, err := dst.Resolve() + if err != nil { + c.adderror(err) + return + } + c.mov(src, b.Addr, int(src.Size()), int(gotypes.Sizes.Sizeof(b.Type)), b.Type) +} + +// Dereference loads a pointer and returns its element type. +func (c *Context) Dereference(ptr gotypes.Component) gotypes.Component { + r := c.GP64() + c.Load(ptr, r) + return ptr.Dereference(r) +} + +// ConstData builds a static data section containing just the given constant. +func (c *Context) ConstData(name string, v operand.Constant) operand.Mem { + g := c.StaticGlobal(name) + c.DataAttributes(attr.RODATA | attr.NOPTR) + c.AppendDatum(v) + return g +} diff --git a/vendor/github.com/mmcloughlin/avo/build/zinstructions.go b/vendor/github.com/mmcloughlin/avo/build/zinstructions.go new file mode 100644 index 00000000..33c2085e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/zinstructions.go @@ -0,0 +1,26315 @@ +// Code generated by command: avogen -output zinstructions.go build. DO NOT EDIT. + +package build + +import ( + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/x86" +) + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +// Construct and append a ADCB instruction to the active function. +func (c *Context) ADCB(imr, amr operand.Op) { + if inst, err := x86.ADCB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +// Construct and append a ADCB instruction to the active function. +// Operates on the global context. +func ADCB(imr, amr operand.Op) { ctx.ADCB(imr, amr) } + +// ADCL: Add with Carry. +// +// Forms: +// +// ADCL imm32 eax +// ADCL imm8 r32 +// ADCL imm32 r32 +// ADCL r32 r32 +// ADCL m32 r32 +// ADCL imm8 m32 +// ADCL imm32 m32 +// ADCL r32 m32 +// Construct and append a ADCL instruction to the active function. +func (c *Context) ADCL(imr, emr operand.Op) { + if inst, err := x86.ADCL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCL: Add with Carry. +// +// Forms: +// +// ADCL imm32 eax +// ADCL imm8 r32 +// ADCL imm32 r32 +// ADCL r32 r32 +// ADCL m32 r32 +// ADCL imm8 m32 +// ADCL imm32 m32 +// ADCL r32 m32 +// Construct and append a ADCL instruction to the active function. +// Operates on the global context. +func ADCL(imr, emr operand.Op) { ctx.ADCL(imr, emr) } + +// ADCQ: Add with Carry. +// +// Forms: +// +// ADCQ imm32 rax +// ADCQ imm8 r64 +// ADCQ imm32 r64 +// ADCQ r64 r64 +// ADCQ m64 r64 +// ADCQ imm8 m64 +// ADCQ imm32 m64 +// ADCQ r64 m64 +// Construct and append a ADCQ instruction to the active function. +func (c *Context) ADCQ(imr, mr operand.Op) { + if inst, err := x86.ADCQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCQ: Add with Carry. +// +// Forms: +// +// ADCQ imm32 rax +// ADCQ imm8 r64 +// ADCQ imm32 r64 +// ADCQ r64 r64 +// ADCQ m64 r64 +// ADCQ imm8 m64 +// ADCQ imm32 m64 +// ADCQ r64 m64 +// Construct and append a ADCQ instruction to the active function. +// Operates on the global context. +func ADCQ(imr, mr operand.Op) { ctx.ADCQ(imr, mr) } + +// ADCW: Add with Carry. +// +// Forms: +// +// ADCW imm16 ax +// ADCW imm8 r16 +// ADCW imm16 r16 +// ADCW r16 r16 +// ADCW m16 r16 +// ADCW imm8 m16 +// ADCW imm16 m16 +// ADCW r16 m16 +// Construct and append a ADCW instruction to the active function. +func (c *Context) ADCW(imr, amr operand.Op) { + if inst, err := x86.ADCW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCW: Add with Carry. +// +// Forms: +// +// ADCW imm16 ax +// ADCW imm8 r16 +// ADCW imm16 r16 +// ADCW r16 r16 +// ADCW m16 r16 +// ADCW imm8 m16 +// ADCW imm16 m16 +// ADCW r16 m16 +// Construct and append a ADCW instruction to the active function. +// Operates on the global context. +func ADCW(imr, amr operand.Op) { ctx.ADCW(imr, amr) } + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +// Construct and append a ADCXL instruction to the active function. +func (c *Context) ADCXL(mr, r operand.Op) { + if inst, err := x86.ADCXL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +// Construct and append a ADCXL instruction to the active function. +// Operates on the global context. +func ADCXL(mr, r operand.Op) { ctx.ADCXL(mr, r) } + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +// Construct and append a ADCXQ instruction to the active function. +func (c *Context) ADCXQ(mr, r operand.Op) { + if inst, err := x86.ADCXQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +// Construct and append a ADCXQ instruction to the active function. +// Operates on the global context. +func ADCXQ(mr, r operand.Op) { ctx.ADCXQ(mr, r) } + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +// Construct and append a ADDB instruction to the active function. +func (c *Context) ADDB(imr, amr operand.Op) { + if inst, err := x86.ADDB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +// Construct and append a ADDB instruction to the active function. +// Operates on the global context. +func ADDB(imr, amr operand.Op) { ctx.ADDB(imr, amr) } + +// ADDL: Add. +// +// Forms: +// +// ADDL imm32 eax +// ADDL imm8 r32 +// ADDL imm32 r32 +// ADDL r32 r32 +// ADDL m32 r32 +// ADDL imm8 m32 +// ADDL imm32 m32 +// ADDL r32 m32 +// Construct and append a ADDL instruction to the active function. +func (c *Context) ADDL(imr, emr operand.Op) { + if inst, err := x86.ADDL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDL: Add. +// +// Forms: +// +// ADDL imm32 eax +// ADDL imm8 r32 +// ADDL imm32 r32 +// ADDL r32 r32 +// ADDL m32 r32 +// ADDL imm8 m32 +// ADDL imm32 m32 +// ADDL r32 m32 +// Construct and append a ADDL instruction to the active function. +// Operates on the global context. +func ADDL(imr, emr operand.Op) { ctx.ADDL(imr, emr) } + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +// Construct and append a ADDPD instruction to the active function. +func (c *Context) ADDPD(mx, x operand.Op) { + if inst, err := x86.ADDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +// Construct and append a ADDPD instruction to the active function. +// Operates on the global context. +func ADDPD(mx, x operand.Op) { ctx.ADDPD(mx, x) } + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +// Construct and append a ADDPS instruction to the active function. +func (c *Context) ADDPS(mx, x operand.Op) { + if inst, err := x86.ADDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +// Construct and append a ADDPS instruction to the active function. +// Operates on the global context. +func ADDPS(mx, x operand.Op) { ctx.ADDPS(mx, x) } + +// ADDQ: Add. +// +// Forms: +// +// ADDQ imm32 rax +// ADDQ imm8 r64 +// ADDQ imm32 r64 +// ADDQ r64 r64 +// ADDQ m64 r64 +// ADDQ imm8 m64 +// ADDQ imm32 m64 +// ADDQ r64 m64 +// Construct and append a ADDQ instruction to the active function. +func (c *Context) ADDQ(imr, mr operand.Op) { + if inst, err := x86.ADDQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDQ: Add. +// +// Forms: +// +// ADDQ imm32 rax +// ADDQ imm8 r64 +// ADDQ imm32 r64 +// ADDQ r64 r64 +// ADDQ m64 r64 +// ADDQ imm8 m64 +// ADDQ imm32 m64 +// ADDQ r64 m64 +// Construct and append a ADDQ instruction to the active function. +// Operates on the global context. +func ADDQ(imr, mr operand.Op) { ctx.ADDQ(imr, mr) } + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +// Construct and append a ADDSD instruction to the active function. +func (c *Context) ADDSD(mx, x operand.Op) { + if inst, err := x86.ADDSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +// Construct and append a ADDSD instruction to the active function. +// Operates on the global context. +func ADDSD(mx, x operand.Op) { ctx.ADDSD(mx, x) } + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +// Construct and append a ADDSS instruction to the active function. +func (c *Context) ADDSS(mx, x operand.Op) { + if inst, err := x86.ADDSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +// Construct and append a ADDSS instruction to the active function. +// Operates on the global context. +func ADDSS(mx, x operand.Op) { ctx.ADDSS(mx, x) } + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +// Construct and append a ADDSUBPD instruction to the active function. +func (c *Context) ADDSUBPD(mx, x operand.Op) { + if inst, err := x86.ADDSUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +// Construct and append a ADDSUBPD instruction to the active function. +// Operates on the global context. +func ADDSUBPD(mx, x operand.Op) { ctx.ADDSUBPD(mx, x) } + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +// Construct and append a ADDSUBPS instruction to the active function. +func (c *Context) ADDSUBPS(mx, x operand.Op) { + if inst, err := x86.ADDSUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +// Construct and append a ADDSUBPS instruction to the active function. +// Operates on the global context. +func ADDSUBPS(mx, x operand.Op) { ctx.ADDSUBPS(mx, x) } + +// ADDW: Add. +// +// Forms: +// +// ADDW imm16 ax +// ADDW imm8 r16 +// ADDW imm16 r16 +// ADDW r16 r16 +// ADDW m16 r16 +// ADDW imm8 m16 +// ADDW imm16 m16 +// ADDW r16 m16 +// Construct and append a ADDW instruction to the active function. +func (c *Context) ADDW(imr, amr operand.Op) { + if inst, err := x86.ADDW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADDW: Add. +// +// Forms: +// +// ADDW imm16 ax +// ADDW imm8 r16 +// ADDW imm16 r16 +// ADDW r16 r16 +// ADDW m16 r16 +// ADDW imm8 m16 +// ADDW imm16 m16 +// ADDW r16 m16 +// Construct and append a ADDW instruction to the active function. +// Operates on the global context. +func ADDW(imr, amr operand.Op) { ctx.ADDW(imr, amr) } + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +// Construct and append a ADOXL instruction to the active function. +func (c *Context) ADOXL(mr, r operand.Op) { + if inst, err := x86.ADOXL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +// Construct and append a ADOXL instruction to the active function. +// Operates on the global context. +func ADOXL(mr, r operand.Op) { ctx.ADOXL(mr, r) } + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +// Construct and append a ADOXQ instruction to the active function. +func (c *Context) ADOXQ(mr, r operand.Op) { + if inst, err := x86.ADOXQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +// Construct and append a ADOXQ instruction to the active function. +// Operates on the global context. +func ADOXQ(mr, r operand.Op) { ctx.ADOXQ(mr, r) } + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +// Construct and append a AESDEC instruction to the active function. +func (c *Context) AESDEC(mx, x operand.Op) { + if inst, err := x86.AESDEC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +// Construct and append a AESDEC instruction to the active function. +// Operates on the global context. +func AESDEC(mx, x operand.Op) { ctx.AESDEC(mx, x) } + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +// Construct and append a AESDECLAST instruction to the active function. +func (c *Context) AESDECLAST(mx, x operand.Op) { + if inst, err := x86.AESDECLAST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +// Construct and append a AESDECLAST instruction to the active function. +// Operates on the global context. +func AESDECLAST(mx, x operand.Op) { ctx.AESDECLAST(mx, x) } + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +// Construct and append a AESENC instruction to the active function. +func (c *Context) AESENC(mx, x operand.Op) { + if inst, err := x86.AESENC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +// Construct and append a AESENC instruction to the active function. +// Operates on the global context. +func AESENC(mx, x operand.Op) { ctx.AESENC(mx, x) } + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +// Construct and append a AESENCLAST instruction to the active function. +func (c *Context) AESENCLAST(mx, x operand.Op) { + if inst, err := x86.AESENCLAST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +// Construct and append a AESENCLAST instruction to the active function. +// Operates on the global context. +func AESENCLAST(mx, x operand.Op) { ctx.AESENCLAST(mx, x) } + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +// Construct and append a AESIMC instruction to the active function. +func (c *Context) AESIMC(mx, x operand.Op) { + if inst, err := x86.AESIMC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +// Construct and append a AESIMC instruction to the active function. +// Operates on the global context. +func AESIMC(mx, x operand.Op) { ctx.AESIMC(mx, x) } + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +// Construct and append a AESKEYGENASSIST instruction to the active function. +func (c *Context) AESKEYGENASSIST(i, mx, x operand.Op) { + if inst, err := x86.AESKEYGENASSIST(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +// Construct and append a AESKEYGENASSIST instruction to the active function. +// Operates on the global context. +func AESKEYGENASSIST(i, mx, x operand.Op) { ctx.AESKEYGENASSIST(i, mx, x) } + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +// Construct and append a ANDB instruction to the active function. +func (c *Context) ANDB(imr, amr operand.Op) { + if inst, err := x86.ANDB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +// Construct and append a ANDB instruction to the active function. +// Operates on the global context. +func ANDB(imr, amr operand.Op) { ctx.ANDB(imr, amr) } + +// ANDL: Logical AND. +// +// Forms: +// +// ANDL imm32 eax +// ANDL imm8 r32 +// ANDL imm32 r32 +// ANDL r32 r32 +// ANDL m32 r32 +// ANDL imm8 m32 +// ANDL imm32 m32 +// ANDL r32 m32 +// Construct and append a ANDL instruction to the active function. +func (c *Context) ANDL(imr, emr operand.Op) { + if inst, err := x86.ANDL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDL: Logical AND. +// +// Forms: +// +// ANDL imm32 eax +// ANDL imm8 r32 +// ANDL imm32 r32 +// ANDL r32 r32 +// ANDL m32 r32 +// ANDL imm8 m32 +// ANDL imm32 m32 +// ANDL r32 m32 +// Construct and append a ANDL instruction to the active function. +// Operates on the global context. +func ANDL(imr, emr operand.Op) { ctx.ANDL(imr, emr) } + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +// Construct and append a ANDNL instruction to the active function. +func (c *Context) ANDNL(mr, r, r1 operand.Op) { + if inst, err := x86.ANDNL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +// Construct and append a ANDNL instruction to the active function. +// Operates on the global context. +func ANDNL(mr, r, r1 operand.Op) { ctx.ANDNL(mr, r, r1) } + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +// Construct and append a ANDNPD instruction to the active function. +func (c *Context) ANDNPD(mx, x operand.Op) { + if inst, err := x86.ANDNPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +// Construct and append a ANDNPD instruction to the active function. +// Operates on the global context. +func ANDNPD(mx, x operand.Op) { ctx.ANDNPD(mx, x) } + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +// Construct and append a ANDNPS instruction to the active function. +func (c *Context) ANDNPS(mx, x operand.Op) { + if inst, err := x86.ANDNPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +// Construct and append a ANDNPS instruction to the active function. +// Operates on the global context. +func ANDNPS(mx, x operand.Op) { ctx.ANDNPS(mx, x) } + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +// Construct and append a ANDNQ instruction to the active function. +func (c *Context) ANDNQ(mr, r, r1 operand.Op) { + if inst, err := x86.ANDNQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +// Construct and append a ANDNQ instruction to the active function. +// Operates on the global context. +func ANDNQ(mr, r, r1 operand.Op) { ctx.ANDNQ(mr, r, r1) } + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +// Construct and append a ANDPD instruction to the active function. +func (c *Context) ANDPD(mx, x operand.Op) { + if inst, err := x86.ANDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +// Construct and append a ANDPD instruction to the active function. +// Operates on the global context. +func ANDPD(mx, x operand.Op) { ctx.ANDPD(mx, x) } + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +// Construct and append a ANDPS instruction to the active function. +func (c *Context) ANDPS(mx, x operand.Op) { + if inst, err := x86.ANDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +// Construct and append a ANDPS instruction to the active function. +// Operates on the global context. +func ANDPS(mx, x operand.Op) { ctx.ANDPS(mx, x) } + +// ANDQ: Logical AND. +// +// Forms: +// +// ANDQ imm32 rax +// ANDQ imm8 r64 +// ANDQ imm32 r64 +// ANDQ r64 r64 +// ANDQ m64 r64 +// ANDQ imm8 m64 +// ANDQ imm32 m64 +// ANDQ r64 m64 +// Construct and append a ANDQ instruction to the active function. +func (c *Context) ANDQ(imr, mr operand.Op) { + if inst, err := x86.ANDQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDQ: Logical AND. +// +// Forms: +// +// ANDQ imm32 rax +// ANDQ imm8 r64 +// ANDQ imm32 r64 +// ANDQ r64 r64 +// ANDQ m64 r64 +// ANDQ imm8 m64 +// ANDQ imm32 m64 +// ANDQ r64 m64 +// Construct and append a ANDQ instruction to the active function. +// Operates on the global context. +func ANDQ(imr, mr operand.Op) { ctx.ANDQ(imr, mr) } + +// ANDW: Logical AND. +// +// Forms: +// +// ANDW imm16 ax +// ANDW imm8 r16 +// ANDW imm16 r16 +// ANDW r16 r16 +// ANDW m16 r16 +// ANDW imm8 m16 +// ANDW imm16 m16 +// ANDW r16 m16 +// Construct and append a ANDW instruction to the active function. +func (c *Context) ANDW(imr, amr operand.Op) { + if inst, err := x86.ANDW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ANDW: Logical AND. +// +// Forms: +// +// ANDW imm16 ax +// ANDW imm8 r16 +// ANDW imm16 r16 +// ANDW r16 r16 +// ANDW m16 r16 +// ANDW imm8 m16 +// ANDW imm16 m16 +// ANDW r16 m16 +// Construct and append a ANDW instruction to the active function. +// Operates on the global context. +func ANDW(imr, amr operand.Op) { ctx.ANDW(imr, amr) } + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +// Construct and append a BEXTRL instruction to the active function. +func (c *Context) BEXTRL(r, mr, r1 operand.Op) { + if inst, err := x86.BEXTRL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +// Construct and append a BEXTRL instruction to the active function. +// Operates on the global context. +func BEXTRL(r, mr, r1 operand.Op) { ctx.BEXTRL(r, mr, r1) } + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +// Construct and append a BEXTRQ instruction to the active function. +func (c *Context) BEXTRQ(r, mr, r1 operand.Op) { + if inst, err := x86.BEXTRQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +// Construct and append a BEXTRQ instruction to the active function. +// Operates on the global context. +func BEXTRQ(r, mr, r1 operand.Op) { ctx.BEXTRQ(r, mr, r1) } + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +// Construct and append a BLENDPD instruction to the active function. +func (c *Context) BLENDPD(i, mx, x operand.Op) { + if inst, err := x86.BLENDPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +// Construct and append a BLENDPD instruction to the active function. +// Operates on the global context. +func BLENDPD(i, mx, x operand.Op) { ctx.BLENDPD(i, mx, x) } + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +// Construct and append a BLENDPS instruction to the active function. +func (c *Context) BLENDPS(i, mx, x operand.Op) { + if inst, err := x86.BLENDPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +// Construct and append a BLENDPS instruction to the active function. +// Operates on the global context. +func BLENDPS(i, mx, x operand.Op) { ctx.BLENDPS(i, mx, x) } + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +// Construct and append a BLENDVPD instruction to the active function. +func (c *Context) BLENDVPD(x, mx, x1 operand.Op) { + if inst, err := x86.BLENDVPD(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +// Construct and append a BLENDVPD instruction to the active function. +// Operates on the global context. +func BLENDVPD(x, mx, x1 operand.Op) { ctx.BLENDVPD(x, mx, x1) } + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +// Construct and append a BLENDVPS instruction to the active function. +func (c *Context) BLENDVPS(x, mx, x1 operand.Op) { + if inst, err := x86.BLENDVPS(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +// Construct and append a BLENDVPS instruction to the active function. +// Operates on the global context. +func BLENDVPS(x, mx, x1 operand.Op) { ctx.BLENDVPS(x, mx, x1) } + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +// Construct and append a BLSIL instruction to the active function. +func (c *Context) BLSIL(mr, r operand.Op) { + if inst, err := x86.BLSIL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +// Construct and append a BLSIL instruction to the active function. +// Operates on the global context. +func BLSIL(mr, r operand.Op) { ctx.BLSIL(mr, r) } + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +// Construct and append a BLSIQ instruction to the active function. +func (c *Context) BLSIQ(mr, r operand.Op) { + if inst, err := x86.BLSIQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +// Construct and append a BLSIQ instruction to the active function. +// Operates on the global context. +func BLSIQ(mr, r operand.Op) { ctx.BLSIQ(mr, r) } + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +// Construct and append a BLSMSKL instruction to the active function. +func (c *Context) BLSMSKL(mr, r operand.Op) { + if inst, err := x86.BLSMSKL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +// Construct and append a BLSMSKL instruction to the active function. +// Operates on the global context. +func BLSMSKL(mr, r operand.Op) { ctx.BLSMSKL(mr, r) } + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +// Construct and append a BLSMSKQ instruction to the active function. +func (c *Context) BLSMSKQ(mr, r operand.Op) { + if inst, err := x86.BLSMSKQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +// Construct and append a BLSMSKQ instruction to the active function. +// Operates on the global context. +func BLSMSKQ(mr, r operand.Op) { ctx.BLSMSKQ(mr, r) } + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +// Construct and append a BLSRL instruction to the active function. +func (c *Context) BLSRL(mr, r operand.Op) { + if inst, err := x86.BLSRL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +// Construct and append a BLSRL instruction to the active function. +// Operates on the global context. +func BLSRL(mr, r operand.Op) { ctx.BLSRL(mr, r) } + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +// Construct and append a BLSRQ instruction to the active function. +func (c *Context) BLSRQ(mr, r operand.Op) { + if inst, err := x86.BLSRQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +// Construct and append a BLSRQ instruction to the active function. +// Operates on the global context. +func BLSRQ(mr, r operand.Op) { ctx.BLSRQ(mr, r) } + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +// Construct and append a BSFL instruction to the active function. +func (c *Context) BSFL(mr, r operand.Op) { + if inst, err := x86.BSFL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +// Construct and append a BSFL instruction to the active function. +// Operates on the global context. +func BSFL(mr, r operand.Op) { ctx.BSFL(mr, r) } + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +// Construct and append a BSFQ instruction to the active function. +func (c *Context) BSFQ(mr, r operand.Op) { + if inst, err := x86.BSFQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +// Construct and append a BSFQ instruction to the active function. +// Operates on the global context. +func BSFQ(mr, r operand.Op) { ctx.BSFQ(mr, r) } + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +// Construct and append a BSFW instruction to the active function. +func (c *Context) BSFW(mr, r operand.Op) { + if inst, err := x86.BSFW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +// Construct and append a BSFW instruction to the active function. +// Operates on the global context. +func BSFW(mr, r operand.Op) { ctx.BSFW(mr, r) } + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +// Construct and append a BSRL instruction to the active function. +func (c *Context) BSRL(mr, r operand.Op) { + if inst, err := x86.BSRL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +// Construct and append a BSRL instruction to the active function. +// Operates on the global context. +func BSRL(mr, r operand.Op) { ctx.BSRL(mr, r) } + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +// Construct and append a BSRQ instruction to the active function. +func (c *Context) BSRQ(mr, r operand.Op) { + if inst, err := x86.BSRQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +// Construct and append a BSRQ instruction to the active function. +// Operates on the global context. +func BSRQ(mr, r operand.Op) { ctx.BSRQ(mr, r) } + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +// Construct and append a BSRW instruction to the active function. +func (c *Context) BSRW(mr, r operand.Op) { + if inst, err := x86.BSRW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +// Construct and append a BSRW instruction to the active function. +// Operates on the global context. +func BSRW(mr, r operand.Op) { ctx.BSRW(mr, r) } + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +// Construct and append a BSWAPL instruction to the active function. +func (c *Context) BSWAPL(r operand.Op) { + if inst, err := x86.BSWAPL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +// Construct and append a BSWAPL instruction to the active function. +// Operates on the global context. +func BSWAPL(r operand.Op) { ctx.BSWAPL(r) } + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +// Construct and append a BSWAPQ instruction to the active function. +func (c *Context) BSWAPQ(r operand.Op) { + if inst, err := x86.BSWAPQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +// Construct and append a BSWAPQ instruction to the active function. +// Operates on the global context. +func BSWAPQ(r operand.Op) { ctx.BSWAPQ(r) } + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +// Construct and append a BTCL instruction to the active function. +func (c *Context) BTCL(ir, mr operand.Op) { + if inst, err := x86.BTCL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +// Construct and append a BTCL instruction to the active function. +// Operates on the global context. +func BTCL(ir, mr operand.Op) { ctx.BTCL(ir, mr) } + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +// Construct and append a BTCQ instruction to the active function. +func (c *Context) BTCQ(ir, mr operand.Op) { + if inst, err := x86.BTCQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +// Construct and append a BTCQ instruction to the active function. +// Operates on the global context. +func BTCQ(ir, mr operand.Op) { ctx.BTCQ(ir, mr) } + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +// Construct and append a BTCW instruction to the active function. +func (c *Context) BTCW(ir, mr operand.Op) { + if inst, err := x86.BTCW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +// Construct and append a BTCW instruction to the active function. +// Operates on the global context. +func BTCW(ir, mr operand.Op) { ctx.BTCW(ir, mr) } + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +// Construct and append a BTL instruction to the active function. +func (c *Context) BTL(ir, mr operand.Op) { + if inst, err := x86.BTL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +// Construct and append a BTL instruction to the active function. +// Operates on the global context. +func BTL(ir, mr operand.Op) { ctx.BTL(ir, mr) } + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +// Construct and append a BTQ instruction to the active function. +func (c *Context) BTQ(ir, mr operand.Op) { + if inst, err := x86.BTQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +// Construct and append a BTQ instruction to the active function. +// Operates on the global context. +func BTQ(ir, mr operand.Op) { ctx.BTQ(ir, mr) } + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +// Construct and append a BTRL instruction to the active function. +func (c *Context) BTRL(ir, mr operand.Op) { + if inst, err := x86.BTRL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +// Construct and append a BTRL instruction to the active function. +// Operates on the global context. +func BTRL(ir, mr operand.Op) { ctx.BTRL(ir, mr) } + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +// Construct and append a BTRQ instruction to the active function. +func (c *Context) BTRQ(ir, mr operand.Op) { + if inst, err := x86.BTRQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +// Construct and append a BTRQ instruction to the active function. +// Operates on the global context. +func BTRQ(ir, mr operand.Op) { ctx.BTRQ(ir, mr) } + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +// Construct and append a BTRW instruction to the active function. +func (c *Context) BTRW(ir, mr operand.Op) { + if inst, err := x86.BTRW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +// Construct and append a BTRW instruction to the active function. +// Operates on the global context. +func BTRW(ir, mr operand.Op) { ctx.BTRW(ir, mr) } + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +// Construct and append a BTSL instruction to the active function. +func (c *Context) BTSL(ir, mr operand.Op) { + if inst, err := x86.BTSL(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +// Construct and append a BTSL instruction to the active function. +// Operates on the global context. +func BTSL(ir, mr operand.Op) { ctx.BTSL(ir, mr) } + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +// Construct and append a BTSQ instruction to the active function. +func (c *Context) BTSQ(ir, mr operand.Op) { + if inst, err := x86.BTSQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +// Construct and append a BTSQ instruction to the active function. +// Operates on the global context. +func BTSQ(ir, mr operand.Op) { ctx.BTSQ(ir, mr) } + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +// Construct and append a BTSW instruction to the active function. +func (c *Context) BTSW(ir, mr operand.Op) { + if inst, err := x86.BTSW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +// Construct and append a BTSW instruction to the active function. +// Operates on the global context. +func BTSW(ir, mr operand.Op) { ctx.BTSW(ir, mr) } + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +// Construct and append a BTW instruction to the active function. +func (c *Context) BTW(ir, mr operand.Op) { + if inst, err := x86.BTW(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +// Construct and append a BTW instruction to the active function. +// Operates on the global context. +func BTW(ir, mr operand.Op) { ctx.BTW(ir, mr) } + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +// Construct and append a BZHIL instruction to the active function. +func (c *Context) BZHIL(r, mr, r1 operand.Op) { + if inst, err := x86.BZHIL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +// Construct and append a BZHIL instruction to the active function. +// Operates on the global context. +func BZHIL(r, mr, r1 operand.Op) { ctx.BZHIL(r, mr, r1) } + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +// Construct and append a BZHIQ instruction to the active function. +func (c *Context) BZHIQ(r, mr, r1 operand.Op) { + if inst, err := x86.BZHIQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +// Construct and append a BZHIQ instruction to the active function. +// Operates on the global context. +func BZHIQ(r, mr, r1 operand.Op) { ctx.BZHIQ(r, mr, r1) } + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +// Construct and append a CALL instruction to the active function. +func (c *Context) CALL(r operand.Op) { + if inst, err := x86.CALL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +// Construct and append a CALL instruction to the active function. +// Operates on the global context. +func CALL(r operand.Op) { ctx.CALL(r) } + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +// Construct and append a CBW instruction to the active function. +func (c *Context) CBW() { + if inst, err := x86.CBW(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +// Construct and append a CBW instruction to the active function. +// Operates on the global context. +func CBW() { ctx.CBW() } + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +// Construct and append a CDQ instruction to the active function. +func (c *Context) CDQ() { + if inst, err := x86.CDQ(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +// Construct and append a CDQ instruction to the active function. +// Operates on the global context. +func CDQ() { ctx.CDQ() } + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +// Construct and append a CDQE instruction to the active function. +func (c *Context) CDQE() { + if inst, err := x86.CDQE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +// Construct and append a CDQE instruction to the active function. +// Operates on the global context. +func CDQE() { ctx.CDQE() } + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +// Construct and append a CLC instruction to the active function. +func (c *Context) CLC() { + if inst, err := x86.CLC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +// Construct and append a CLC instruction to the active function. +// Operates on the global context. +func CLC() { ctx.CLC() } + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +// Construct and append a CLD instruction to the active function. +func (c *Context) CLD() { + if inst, err := x86.CLD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +// Construct and append a CLD instruction to the active function. +// Operates on the global context. +func CLD() { ctx.CLD() } + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +// Construct and append a CLFLUSH instruction to the active function. +func (c *Context) CLFLUSH(m operand.Op) { + if inst, err := x86.CLFLUSH(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +// Construct and append a CLFLUSH instruction to the active function. +// Operates on the global context. +func CLFLUSH(m operand.Op) { ctx.CLFLUSH(m) } + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +// Construct and append a CLFLUSHOPT instruction to the active function. +func (c *Context) CLFLUSHOPT(m operand.Op) { + if inst, err := x86.CLFLUSHOPT(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +// Construct and append a CLFLUSHOPT instruction to the active function. +// Operates on the global context. +func CLFLUSHOPT(m operand.Op) { ctx.CLFLUSHOPT(m) } + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +// Construct and append a CMC instruction to the active function. +func (c *Context) CMC() { + if inst, err := x86.CMC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +// Construct and append a CMC instruction to the active function. +// Operates on the global context. +func CMC() { ctx.CMC() } + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +// Construct and append a CMOVLCC instruction to the active function. +func (c *Context) CMOVLCC(mr, r operand.Op) { + if inst, err := x86.CMOVLCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +// Construct and append a CMOVLCC instruction to the active function. +// Operates on the global context. +func CMOVLCC(mr, r operand.Op) { ctx.CMOVLCC(mr, r) } + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +// Construct and append a CMOVLCS instruction to the active function. +func (c *Context) CMOVLCS(mr, r operand.Op) { + if inst, err := x86.CMOVLCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +// Construct and append a CMOVLCS instruction to the active function. +// Operates on the global context. +func CMOVLCS(mr, r operand.Op) { ctx.CMOVLCS(mr, r) } + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +// Construct and append a CMOVLEQ instruction to the active function. +func (c *Context) CMOVLEQ(mr, r operand.Op) { + if inst, err := x86.CMOVLEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +// Construct and append a CMOVLEQ instruction to the active function. +// Operates on the global context. +func CMOVLEQ(mr, r operand.Op) { ctx.CMOVLEQ(mr, r) } + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +// Construct and append a CMOVLGE instruction to the active function. +func (c *Context) CMOVLGE(mr, r operand.Op) { + if inst, err := x86.CMOVLGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +// Construct and append a CMOVLGE instruction to the active function. +// Operates on the global context. +func CMOVLGE(mr, r operand.Op) { ctx.CMOVLGE(mr, r) } + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +// Construct and append a CMOVLGT instruction to the active function. +func (c *Context) CMOVLGT(mr, r operand.Op) { + if inst, err := x86.CMOVLGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +// Construct and append a CMOVLGT instruction to the active function. +// Operates on the global context. +func CMOVLGT(mr, r operand.Op) { ctx.CMOVLGT(mr, r) } + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +// Construct and append a CMOVLHI instruction to the active function. +func (c *Context) CMOVLHI(mr, r operand.Op) { + if inst, err := x86.CMOVLHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +// Construct and append a CMOVLHI instruction to the active function. +// Operates on the global context. +func CMOVLHI(mr, r operand.Op) { ctx.CMOVLHI(mr, r) } + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +// Construct and append a CMOVLLE instruction to the active function. +func (c *Context) CMOVLLE(mr, r operand.Op) { + if inst, err := x86.CMOVLLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +// Construct and append a CMOVLLE instruction to the active function. +// Operates on the global context. +func CMOVLLE(mr, r operand.Op) { ctx.CMOVLLE(mr, r) } + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +// Construct and append a CMOVLLS instruction to the active function. +func (c *Context) CMOVLLS(mr, r operand.Op) { + if inst, err := x86.CMOVLLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +// Construct and append a CMOVLLS instruction to the active function. +// Operates on the global context. +func CMOVLLS(mr, r operand.Op) { ctx.CMOVLLS(mr, r) } + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +// Construct and append a CMOVLLT instruction to the active function. +func (c *Context) CMOVLLT(mr, r operand.Op) { + if inst, err := x86.CMOVLLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +// Construct and append a CMOVLLT instruction to the active function. +// Operates on the global context. +func CMOVLLT(mr, r operand.Op) { ctx.CMOVLLT(mr, r) } + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +// Construct and append a CMOVLMI instruction to the active function. +func (c *Context) CMOVLMI(mr, r operand.Op) { + if inst, err := x86.CMOVLMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +// Construct and append a CMOVLMI instruction to the active function. +// Operates on the global context. +func CMOVLMI(mr, r operand.Op) { ctx.CMOVLMI(mr, r) } + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +// Construct and append a CMOVLNE instruction to the active function. +func (c *Context) CMOVLNE(mr, r operand.Op) { + if inst, err := x86.CMOVLNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +// Construct and append a CMOVLNE instruction to the active function. +// Operates on the global context. +func CMOVLNE(mr, r operand.Op) { ctx.CMOVLNE(mr, r) } + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +// Construct and append a CMOVLOC instruction to the active function. +func (c *Context) CMOVLOC(mr, r operand.Op) { + if inst, err := x86.CMOVLOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +// Construct and append a CMOVLOC instruction to the active function. +// Operates on the global context. +func CMOVLOC(mr, r operand.Op) { ctx.CMOVLOC(mr, r) } + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +// Construct and append a CMOVLOS instruction to the active function. +func (c *Context) CMOVLOS(mr, r operand.Op) { + if inst, err := x86.CMOVLOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +// Construct and append a CMOVLOS instruction to the active function. +// Operates on the global context. +func CMOVLOS(mr, r operand.Op) { ctx.CMOVLOS(mr, r) } + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +// Construct and append a CMOVLPC instruction to the active function. +func (c *Context) CMOVLPC(mr, r operand.Op) { + if inst, err := x86.CMOVLPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +// Construct and append a CMOVLPC instruction to the active function. +// Operates on the global context. +func CMOVLPC(mr, r operand.Op) { ctx.CMOVLPC(mr, r) } + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +// Construct and append a CMOVLPL instruction to the active function. +func (c *Context) CMOVLPL(mr, r operand.Op) { + if inst, err := x86.CMOVLPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +// Construct and append a CMOVLPL instruction to the active function. +// Operates on the global context. +func CMOVLPL(mr, r operand.Op) { ctx.CMOVLPL(mr, r) } + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +// Construct and append a CMOVLPS instruction to the active function. +func (c *Context) CMOVLPS(mr, r operand.Op) { + if inst, err := x86.CMOVLPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +// Construct and append a CMOVLPS instruction to the active function. +// Operates on the global context. +func CMOVLPS(mr, r operand.Op) { ctx.CMOVLPS(mr, r) } + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +// Construct and append a CMOVQCC instruction to the active function. +func (c *Context) CMOVQCC(mr, r operand.Op) { + if inst, err := x86.CMOVQCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +// Construct and append a CMOVQCC instruction to the active function. +// Operates on the global context. +func CMOVQCC(mr, r operand.Op) { ctx.CMOVQCC(mr, r) } + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +// Construct and append a CMOVQCS instruction to the active function. +func (c *Context) CMOVQCS(mr, r operand.Op) { + if inst, err := x86.CMOVQCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +// Construct and append a CMOVQCS instruction to the active function. +// Operates on the global context. +func CMOVQCS(mr, r operand.Op) { ctx.CMOVQCS(mr, r) } + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +// Construct and append a CMOVQEQ instruction to the active function. +func (c *Context) CMOVQEQ(mr, r operand.Op) { + if inst, err := x86.CMOVQEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +// Construct and append a CMOVQEQ instruction to the active function. +// Operates on the global context. +func CMOVQEQ(mr, r operand.Op) { ctx.CMOVQEQ(mr, r) } + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +// Construct and append a CMOVQGE instruction to the active function. +func (c *Context) CMOVQGE(mr, r operand.Op) { + if inst, err := x86.CMOVQGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +// Construct and append a CMOVQGE instruction to the active function. +// Operates on the global context. +func CMOVQGE(mr, r operand.Op) { ctx.CMOVQGE(mr, r) } + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +// Construct and append a CMOVQGT instruction to the active function. +func (c *Context) CMOVQGT(mr, r operand.Op) { + if inst, err := x86.CMOVQGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +// Construct and append a CMOVQGT instruction to the active function. +// Operates on the global context. +func CMOVQGT(mr, r operand.Op) { ctx.CMOVQGT(mr, r) } + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +// Construct and append a CMOVQHI instruction to the active function. +func (c *Context) CMOVQHI(mr, r operand.Op) { + if inst, err := x86.CMOVQHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +// Construct and append a CMOVQHI instruction to the active function. +// Operates on the global context. +func CMOVQHI(mr, r operand.Op) { ctx.CMOVQHI(mr, r) } + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +// Construct and append a CMOVQLE instruction to the active function. +func (c *Context) CMOVQLE(mr, r operand.Op) { + if inst, err := x86.CMOVQLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +// Construct and append a CMOVQLE instruction to the active function. +// Operates on the global context. +func CMOVQLE(mr, r operand.Op) { ctx.CMOVQLE(mr, r) } + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +// Construct and append a CMOVQLS instruction to the active function. +func (c *Context) CMOVQLS(mr, r operand.Op) { + if inst, err := x86.CMOVQLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +// Construct and append a CMOVQLS instruction to the active function. +// Operates on the global context. +func CMOVQLS(mr, r operand.Op) { ctx.CMOVQLS(mr, r) } + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +// Construct and append a CMOVQLT instruction to the active function. +func (c *Context) CMOVQLT(mr, r operand.Op) { + if inst, err := x86.CMOVQLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +// Construct and append a CMOVQLT instruction to the active function. +// Operates on the global context. +func CMOVQLT(mr, r operand.Op) { ctx.CMOVQLT(mr, r) } + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +// Construct and append a CMOVQMI instruction to the active function. +func (c *Context) CMOVQMI(mr, r operand.Op) { + if inst, err := x86.CMOVQMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +// Construct and append a CMOVQMI instruction to the active function. +// Operates on the global context. +func CMOVQMI(mr, r operand.Op) { ctx.CMOVQMI(mr, r) } + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +// Construct and append a CMOVQNE instruction to the active function. +func (c *Context) CMOVQNE(mr, r operand.Op) { + if inst, err := x86.CMOVQNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +// Construct and append a CMOVQNE instruction to the active function. +// Operates on the global context. +func CMOVQNE(mr, r operand.Op) { ctx.CMOVQNE(mr, r) } + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +// Construct and append a CMOVQOC instruction to the active function. +func (c *Context) CMOVQOC(mr, r operand.Op) { + if inst, err := x86.CMOVQOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +// Construct and append a CMOVQOC instruction to the active function. +// Operates on the global context. +func CMOVQOC(mr, r operand.Op) { ctx.CMOVQOC(mr, r) } + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +// Construct and append a CMOVQOS instruction to the active function. +func (c *Context) CMOVQOS(mr, r operand.Op) { + if inst, err := x86.CMOVQOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +// Construct and append a CMOVQOS instruction to the active function. +// Operates on the global context. +func CMOVQOS(mr, r operand.Op) { ctx.CMOVQOS(mr, r) } + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +// Construct and append a CMOVQPC instruction to the active function. +func (c *Context) CMOVQPC(mr, r operand.Op) { + if inst, err := x86.CMOVQPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +// Construct and append a CMOVQPC instruction to the active function. +// Operates on the global context. +func CMOVQPC(mr, r operand.Op) { ctx.CMOVQPC(mr, r) } + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +// Construct and append a CMOVQPL instruction to the active function. +func (c *Context) CMOVQPL(mr, r operand.Op) { + if inst, err := x86.CMOVQPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +// Construct and append a CMOVQPL instruction to the active function. +// Operates on the global context. +func CMOVQPL(mr, r operand.Op) { ctx.CMOVQPL(mr, r) } + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +// Construct and append a CMOVQPS instruction to the active function. +func (c *Context) CMOVQPS(mr, r operand.Op) { + if inst, err := x86.CMOVQPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +// Construct and append a CMOVQPS instruction to the active function. +// Operates on the global context. +func CMOVQPS(mr, r operand.Op) { ctx.CMOVQPS(mr, r) } + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +// Construct and append a CMOVWCC instruction to the active function. +func (c *Context) CMOVWCC(mr, r operand.Op) { + if inst, err := x86.CMOVWCC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +// Construct and append a CMOVWCC instruction to the active function. +// Operates on the global context. +func CMOVWCC(mr, r operand.Op) { ctx.CMOVWCC(mr, r) } + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +// Construct and append a CMOVWCS instruction to the active function. +func (c *Context) CMOVWCS(mr, r operand.Op) { + if inst, err := x86.CMOVWCS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +// Construct and append a CMOVWCS instruction to the active function. +// Operates on the global context. +func CMOVWCS(mr, r operand.Op) { ctx.CMOVWCS(mr, r) } + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +// Construct and append a CMOVWEQ instruction to the active function. +func (c *Context) CMOVWEQ(mr, r operand.Op) { + if inst, err := x86.CMOVWEQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +// Construct and append a CMOVWEQ instruction to the active function. +// Operates on the global context. +func CMOVWEQ(mr, r operand.Op) { ctx.CMOVWEQ(mr, r) } + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +// Construct and append a CMOVWGE instruction to the active function. +func (c *Context) CMOVWGE(mr, r operand.Op) { + if inst, err := x86.CMOVWGE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +// Construct and append a CMOVWGE instruction to the active function. +// Operates on the global context. +func CMOVWGE(mr, r operand.Op) { ctx.CMOVWGE(mr, r) } + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +// Construct and append a CMOVWGT instruction to the active function. +func (c *Context) CMOVWGT(mr, r operand.Op) { + if inst, err := x86.CMOVWGT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +// Construct and append a CMOVWGT instruction to the active function. +// Operates on the global context. +func CMOVWGT(mr, r operand.Op) { ctx.CMOVWGT(mr, r) } + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +// Construct and append a CMOVWHI instruction to the active function. +func (c *Context) CMOVWHI(mr, r operand.Op) { + if inst, err := x86.CMOVWHI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +// Construct and append a CMOVWHI instruction to the active function. +// Operates on the global context. +func CMOVWHI(mr, r operand.Op) { ctx.CMOVWHI(mr, r) } + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +// Construct and append a CMOVWLE instruction to the active function. +func (c *Context) CMOVWLE(mr, r operand.Op) { + if inst, err := x86.CMOVWLE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +// Construct and append a CMOVWLE instruction to the active function. +// Operates on the global context. +func CMOVWLE(mr, r operand.Op) { ctx.CMOVWLE(mr, r) } + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +// Construct and append a CMOVWLS instruction to the active function. +func (c *Context) CMOVWLS(mr, r operand.Op) { + if inst, err := x86.CMOVWLS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +// Construct and append a CMOVWLS instruction to the active function. +// Operates on the global context. +func CMOVWLS(mr, r operand.Op) { ctx.CMOVWLS(mr, r) } + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +// Construct and append a CMOVWLT instruction to the active function. +func (c *Context) CMOVWLT(mr, r operand.Op) { + if inst, err := x86.CMOVWLT(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +// Construct and append a CMOVWLT instruction to the active function. +// Operates on the global context. +func CMOVWLT(mr, r operand.Op) { ctx.CMOVWLT(mr, r) } + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +// Construct and append a CMOVWMI instruction to the active function. +func (c *Context) CMOVWMI(mr, r operand.Op) { + if inst, err := x86.CMOVWMI(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +// Construct and append a CMOVWMI instruction to the active function. +// Operates on the global context. +func CMOVWMI(mr, r operand.Op) { ctx.CMOVWMI(mr, r) } + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +// Construct and append a CMOVWNE instruction to the active function. +func (c *Context) CMOVWNE(mr, r operand.Op) { + if inst, err := x86.CMOVWNE(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +// Construct and append a CMOVWNE instruction to the active function. +// Operates on the global context. +func CMOVWNE(mr, r operand.Op) { ctx.CMOVWNE(mr, r) } + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +// Construct and append a CMOVWOC instruction to the active function. +func (c *Context) CMOVWOC(mr, r operand.Op) { + if inst, err := x86.CMOVWOC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +// Construct and append a CMOVWOC instruction to the active function. +// Operates on the global context. +func CMOVWOC(mr, r operand.Op) { ctx.CMOVWOC(mr, r) } + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +// Construct and append a CMOVWOS instruction to the active function. +func (c *Context) CMOVWOS(mr, r operand.Op) { + if inst, err := x86.CMOVWOS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +// Construct and append a CMOVWOS instruction to the active function. +// Operates on the global context. +func CMOVWOS(mr, r operand.Op) { ctx.CMOVWOS(mr, r) } + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +// Construct and append a CMOVWPC instruction to the active function. +func (c *Context) CMOVWPC(mr, r operand.Op) { + if inst, err := x86.CMOVWPC(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +// Construct and append a CMOVWPC instruction to the active function. +// Operates on the global context. +func CMOVWPC(mr, r operand.Op) { ctx.CMOVWPC(mr, r) } + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +// Construct and append a CMOVWPL instruction to the active function. +func (c *Context) CMOVWPL(mr, r operand.Op) { + if inst, err := x86.CMOVWPL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +// Construct and append a CMOVWPL instruction to the active function. +// Operates on the global context. +func CMOVWPL(mr, r operand.Op) { ctx.CMOVWPL(mr, r) } + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +// Construct and append a CMOVWPS instruction to the active function. +func (c *Context) CMOVWPS(mr, r operand.Op) { + if inst, err := x86.CMOVWPS(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +// Construct and append a CMOVWPS instruction to the active function. +// Operates on the global context. +func CMOVWPS(mr, r operand.Op) { ctx.CMOVWPS(mr, r) } + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +// Construct and append a CMPB instruction to the active function. +func (c *Context) CMPB(amr, imr operand.Op) { + if inst, err := x86.CMPB(amr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +// Construct and append a CMPB instruction to the active function. +// Operates on the global context. +func CMPB(amr, imr operand.Op) { ctx.CMPB(amr, imr) } + +// CMPL: Compare Two Operands. +// +// Forms: +// +// CMPL eax imm32 +// CMPL r32 imm8 +// CMPL r32 imm32 +// CMPL r32 r32 +// CMPL r32 m32 +// CMPL m32 imm8 +// CMPL m32 imm32 +// CMPL m32 r32 +// Construct and append a CMPL instruction to the active function. +func (c *Context) CMPL(emr, imr operand.Op) { + if inst, err := x86.CMPL(emr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPL: Compare Two Operands. +// +// Forms: +// +// CMPL eax imm32 +// CMPL r32 imm8 +// CMPL r32 imm32 +// CMPL r32 r32 +// CMPL r32 m32 +// CMPL m32 imm8 +// CMPL m32 imm32 +// CMPL m32 r32 +// Construct and append a CMPL instruction to the active function. +// Operates on the global context. +func CMPL(emr, imr operand.Op) { ctx.CMPL(emr, imr) } + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +// Construct and append a CMPPD instruction to the active function. +func (c *Context) CMPPD(mx, x, i operand.Op) { + if inst, err := x86.CMPPD(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +// Construct and append a CMPPD instruction to the active function. +// Operates on the global context. +func CMPPD(mx, x, i operand.Op) { ctx.CMPPD(mx, x, i) } + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +// Construct and append a CMPPS instruction to the active function. +func (c *Context) CMPPS(mx, x, i operand.Op) { + if inst, err := x86.CMPPS(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +// Construct and append a CMPPS instruction to the active function. +// Operates on the global context. +func CMPPS(mx, x, i operand.Op) { ctx.CMPPS(mx, x, i) } + +// CMPQ: Compare Two Operands. +// +// Forms: +// +// CMPQ rax imm32 +// CMPQ r64 imm8 +// CMPQ r64 imm32 +// CMPQ r64 r64 +// CMPQ r64 m64 +// CMPQ m64 imm8 +// CMPQ m64 imm32 +// CMPQ m64 r64 +// Construct and append a CMPQ instruction to the active function. +func (c *Context) CMPQ(mr, imr operand.Op) { + if inst, err := x86.CMPQ(mr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPQ: Compare Two Operands. +// +// Forms: +// +// CMPQ rax imm32 +// CMPQ r64 imm8 +// CMPQ r64 imm32 +// CMPQ r64 r64 +// CMPQ r64 m64 +// CMPQ m64 imm8 +// CMPQ m64 imm32 +// CMPQ m64 r64 +// Construct and append a CMPQ instruction to the active function. +// Operates on the global context. +func CMPQ(mr, imr operand.Op) { ctx.CMPQ(mr, imr) } + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +// Construct and append a CMPSD instruction to the active function. +func (c *Context) CMPSD(mx, x, i operand.Op) { + if inst, err := x86.CMPSD(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +// Construct and append a CMPSD instruction to the active function. +// Operates on the global context. +func CMPSD(mx, x, i operand.Op) { ctx.CMPSD(mx, x, i) } + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +// Construct and append a CMPSS instruction to the active function. +func (c *Context) CMPSS(mx, x, i operand.Op) { + if inst, err := x86.CMPSS(mx, x, i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +// Construct and append a CMPSS instruction to the active function. +// Operates on the global context. +func CMPSS(mx, x, i operand.Op) { ctx.CMPSS(mx, x, i) } + +// CMPW: Compare Two Operands. +// +// Forms: +// +// CMPW ax imm16 +// CMPW r16 imm8 +// CMPW r16 imm16 +// CMPW r16 r16 +// CMPW r16 m16 +// CMPW m16 imm8 +// CMPW m16 imm16 +// CMPW m16 r16 +// Construct and append a CMPW instruction to the active function. +func (c *Context) CMPW(amr, imr operand.Op) { + if inst, err := x86.CMPW(amr, imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPW: Compare Two Operands. +// +// Forms: +// +// CMPW ax imm16 +// CMPW r16 imm8 +// CMPW r16 imm16 +// CMPW r16 r16 +// CMPW r16 m16 +// CMPW m16 imm8 +// CMPW m16 imm16 +// CMPW m16 r16 +// Construct and append a CMPW instruction to the active function. +// Operates on the global context. +func CMPW(amr, imr operand.Op) { ctx.CMPW(amr, imr) } + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +// Construct and append a CMPXCHG16B instruction to the active function. +func (c *Context) CMPXCHG16B(m operand.Op) { + if inst, err := x86.CMPXCHG16B(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +// Construct and append a CMPXCHG16B instruction to the active function. +// Operates on the global context. +func CMPXCHG16B(m operand.Op) { ctx.CMPXCHG16B(m) } + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +// Construct and append a CMPXCHG8B instruction to the active function. +func (c *Context) CMPXCHG8B(m operand.Op) { + if inst, err := x86.CMPXCHG8B(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +// Construct and append a CMPXCHG8B instruction to the active function. +// Operates on the global context. +func CMPXCHG8B(m operand.Op) { ctx.CMPXCHG8B(m) } + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +// Construct and append a CMPXCHGB instruction to the active function. +func (c *Context) CMPXCHGB(r, mr operand.Op) { + if inst, err := x86.CMPXCHGB(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +// Construct and append a CMPXCHGB instruction to the active function. +// Operates on the global context. +func CMPXCHGB(r, mr operand.Op) { ctx.CMPXCHGB(r, mr) } + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +// Construct and append a CMPXCHGL instruction to the active function. +func (c *Context) CMPXCHGL(r, mr operand.Op) { + if inst, err := x86.CMPXCHGL(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +// Construct and append a CMPXCHGL instruction to the active function. +// Operates on the global context. +func CMPXCHGL(r, mr operand.Op) { ctx.CMPXCHGL(r, mr) } + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +// Construct and append a CMPXCHGQ instruction to the active function. +func (c *Context) CMPXCHGQ(r, mr operand.Op) { + if inst, err := x86.CMPXCHGQ(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +// Construct and append a CMPXCHGQ instruction to the active function. +// Operates on the global context. +func CMPXCHGQ(r, mr operand.Op) { ctx.CMPXCHGQ(r, mr) } + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +// Construct and append a CMPXCHGW instruction to the active function. +func (c *Context) CMPXCHGW(r, mr operand.Op) { + if inst, err := x86.CMPXCHGW(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +// Construct and append a CMPXCHGW instruction to the active function. +// Operates on the global context. +func CMPXCHGW(r, mr operand.Op) { ctx.CMPXCHGW(r, mr) } + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +// Construct and append a COMISD instruction to the active function. +func (c *Context) COMISD(mx, x operand.Op) { + if inst, err := x86.COMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +// Construct and append a COMISD instruction to the active function. +// Operates on the global context. +func COMISD(mx, x operand.Op) { ctx.COMISD(mx, x) } + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +// Construct and append a COMISS instruction to the active function. +func (c *Context) COMISS(mx, x operand.Op) { + if inst, err := x86.COMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +// Construct and append a COMISS instruction to the active function. +// Operates on the global context. +func COMISS(mx, x operand.Op) { ctx.COMISS(mx, x) } + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +// Construct and append a CPUID instruction to the active function. +func (c *Context) CPUID() { + if inst, err := x86.CPUID(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +// Construct and append a CPUID instruction to the active function. +// Operates on the global context. +func CPUID() { ctx.CPUID() } + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +// Construct and append a CQO instruction to the active function. +func (c *Context) CQO() { + if inst, err := x86.CQO(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +// Construct and append a CQO instruction to the active function. +// Operates on the global context. +func CQO() { ctx.CQO() } + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +// Construct and append a CRC32B instruction to the active function. +func (c *Context) CRC32B(mr, r operand.Op) { + if inst, err := x86.CRC32B(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +// Construct and append a CRC32B instruction to the active function. +// Operates on the global context. +func CRC32B(mr, r operand.Op) { ctx.CRC32B(mr, r) } + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +// Construct and append a CRC32L instruction to the active function. +func (c *Context) CRC32L(mr, r operand.Op) { + if inst, err := x86.CRC32L(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +// Construct and append a CRC32L instruction to the active function. +// Operates on the global context. +func CRC32L(mr, r operand.Op) { ctx.CRC32L(mr, r) } + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +// Construct and append a CRC32Q instruction to the active function. +func (c *Context) CRC32Q(mr, r operand.Op) { + if inst, err := x86.CRC32Q(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +// Construct and append a CRC32Q instruction to the active function. +// Operates on the global context. +func CRC32Q(mr, r operand.Op) { ctx.CRC32Q(mr, r) } + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +// Construct and append a CRC32W instruction to the active function. +func (c *Context) CRC32W(mr, r operand.Op) { + if inst, err := x86.CRC32W(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +// Construct and append a CRC32W instruction to the active function. +// Operates on the global context. +func CRC32W(mr, r operand.Op) { ctx.CRC32W(mr, r) } + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +// Construct and append a CVTPD2PL instruction to the active function. +func (c *Context) CVTPD2PL(mx, x operand.Op) { + if inst, err := x86.CVTPD2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +// Construct and append a CVTPD2PL instruction to the active function. +// Operates on the global context. +func CVTPD2PL(mx, x operand.Op) { ctx.CVTPD2PL(mx, x) } + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +// Construct and append a CVTPD2PS instruction to the active function. +func (c *Context) CVTPD2PS(mx, x operand.Op) { + if inst, err := x86.CVTPD2PS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +// Construct and append a CVTPD2PS instruction to the active function. +// Operates on the global context. +func CVTPD2PS(mx, x operand.Op) { ctx.CVTPD2PS(mx, x) } + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +// Construct and append a CVTPL2PD instruction to the active function. +func (c *Context) CVTPL2PD(mx, x operand.Op) { + if inst, err := x86.CVTPL2PD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +// Construct and append a CVTPL2PD instruction to the active function. +// Operates on the global context. +func CVTPL2PD(mx, x operand.Op) { ctx.CVTPL2PD(mx, x) } + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +// Construct and append a CVTPL2PS instruction to the active function. +func (c *Context) CVTPL2PS(mx, x operand.Op) { + if inst, err := x86.CVTPL2PS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +// Construct and append a CVTPL2PS instruction to the active function. +// Operates on the global context. +func CVTPL2PS(mx, x operand.Op) { ctx.CVTPL2PS(mx, x) } + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +// Construct and append a CVTPS2PD instruction to the active function. +func (c *Context) CVTPS2PD(mx, x operand.Op) { + if inst, err := x86.CVTPS2PD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +// Construct and append a CVTPS2PD instruction to the active function. +// Operates on the global context. +func CVTPS2PD(mx, x operand.Op) { ctx.CVTPS2PD(mx, x) } + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +// Construct and append a CVTPS2PL instruction to the active function. +func (c *Context) CVTPS2PL(mx, x operand.Op) { + if inst, err := x86.CVTPS2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +// Construct and append a CVTPS2PL instruction to the active function. +// Operates on the global context. +func CVTPS2PL(mx, x operand.Op) { ctx.CVTPS2PL(mx, x) } + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +// Construct and append a CVTSD2SL instruction to the active function. +func (c *Context) CVTSD2SL(mx, r operand.Op) { + if inst, err := x86.CVTSD2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +// Construct and append a CVTSD2SL instruction to the active function. +// Operates on the global context. +func CVTSD2SL(mx, r operand.Op) { ctx.CVTSD2SL(mx, r) } + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +// Construct and append a CVTSD2SS instruction to the active function. +func (c *Context) CVTSD2SS(mx, x operand.Op) { + if inst, err := x86.CVTSD2SS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +// Construct and append a CVTSD2SS instruction to the active function. +// Operates on the global context. +func CVTSD2SS(mx, x operand.Op) { ctx.CVTSD2SS(mx, x) } + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +// Construct and append a CVTSL2SD instruction to the active function. +func (c *Context) CVTSL2SD(mr, x operand.Op) { + if inst, err := x86.CVTSL2SD(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +// Construct and append a CVTSL2SD instruction to the active function. +// Operates on the global context. +func CVTSL2SD(mr, x operand.Op) { ctx.CVTSL2SD(mr, x) } + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +// Construct and append a CVTSL2SS instruction to the active function. +func (c *Context) CVTSL2SS(mr, x operand.Op) { + if inst, err := x86.CVTSL2SS(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +// Construct and append a CVTSL2SS instruction to the active function. +// Operates on the global context. +func CVTSL2SS(mr, x operand.Op) { ctx.CVTSL2SS(mr, x) } + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +// Construct and append a CVTSQ2SD instruction to the active function. +func (c *Context) CVTSQ2SD(mr, x operand.Op) { + if inst, err := x86.CVTSQ2SD(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +// Construct and append a CVTSQ2SD instruction to the active function. +// Operates on the global context. +func CVTSQ2SD(mr, x operand.Op) { ctx.CVTSQ2SD(mr, x) } + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +// Construct and append a CVTSQ2SS instruction to the active function. +func (c *Context) CVTSQ2SS(mr, x operand.Op) { + if inst, err := x86.CVTSQ2SS(mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +// Construct and append a CVTSQ2SS instruction to the active function. +// Operates on the global context. +func CVTSQ2SS(mr, x operand.Op) { ctx.CVTSQ2SS(mr, x) } + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +// Construct and append a CVTSS2SD instruction to the active function. +func (c *Context) CVTSS2SD(mx, x operand.Op) { + if inst, err := x86.CVTSS2SD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +// Construct and append a CVTSS2SD instruction to the active function. +// Operates on the global context. +func CVTSS2SD(mx, x operand.Op) { ctx.CVTSS2SD(mx, x) } + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +// Construct and append a CVTSS2SL instruction to the active function. +func (c *Context) CVTSS2SL(mx, r operand.Op) { + if inst, err := x86.CVTSS2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +// Construct and append a CVTSS2SL instruction to the active function. +// Operates on the global context. +func CVTSS2SL(mx, r operand.Op) { ctx.CVTSS2SL(mx, r) } + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +// Construct and append a CVTTPD2PL instruction to the active function. +func (c *Context) CVTTPD2PL(mx, x operand.Op) { + if inst, err := x86.CVTTPD2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +// Construct and append a CVTTPD2PL instruction to the active function. +// Operates on the global context. +func CVTTPD2PL(mx, x operand.Op) { ctx.CVTTPD2PL(mx, x) } + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +// Construct and append a CVTTPS2PL instruction to the active function. +func (c *Context) CVTTPS2PL(mx, x operand.Op) { + if inst, err := x86.CVTTPS2PL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +// Construct and append a CVTTPS2PL instruction to the active function. +// Operates on the global context. +func CVTTPS2PL(mx, x operand.Op) { ctx.CVTTPS2PL(mx, x) } + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +// Construct and append a CVTTSD2SL instruction to the active function. +func (c *Context) CVTTSD2SL(mx, r operand.Op) { + if inst, err := x86.CVTTSD2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +// Construct and append a CVTTSD2SL instruction to the active function. +// Operates on the global context. +func CVTTSD2SL(mx, r operand.Op) { ctx.CVTTSD2SL(mx, r) } + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +// Construct and append a CVTTSD2SQ instruction to the active function. +func (c *Context) CVTTSD2SQ(mx, r operand.Op) { + if inst, err := x86.CVTTSD2SQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +// Construct and append a CVTTSD2SQ instruction to the active function. +// Operates on the global context. +func CVTTSD2SQ(mx, r operand.Op) { ctx.CVTTSD2SQ(mx, r) } + +// CVTTSS2SL: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTTSS2SL xmm r32 +// CVTTSS2SL m32 r32 +// CVTTSS2SL xmm r64 +// CVTTSS2SL m32 r64 +// Construct and append a CVTTSS2SL instruction to the active function. +func (c *Context) CVTTSS2SL(mx, r operand.Op) { + if inst, err := x86.CVTTSS2SL(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CVTTSS2SL: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTTSS2SL xmm r32 +// CVTTSS2SL m32 r32 +// CVTTSS2SL xmm r64 +// CVTTSS2SL m32 r64 +// Construct and append a CVTTSS2SL instruction to the active function. +// Operates on the global context. +func CVTTSS2SL(mx, r operand.Op) { ctx.CVTTSS2SL(mx, r) } + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +// Construct and append a CWD instruction to the active function. +func (c *Context) CWD() { + if inst, err := x86.CWD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +// Construct and append a CWD instruction to the active function. +// Operates on the global context. +func CWD() { ctx.CWD() } + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +// Construct and append a CWDE instruction to the active function. +func (c *Context) CWDE() { + if inst, err := x86.CWDE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +// Construct and append a CWDE instruction to the active function. +// Operates on the global context. +func CWDE() { ctx.CWDE() } + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +// Construct and append a DECB instruction to the active function. +func (c *Context) DECB(mr operand.Op) { + if inst, err := x86.DECB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +// Construct and append a DECB instruction to the active function. +// Operates on the global context. +func DECB(mr operand.Op) { ctx.DECB(mr) } + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +// Construct and append a DECL instruction to the active function. +func (c *Context) DECL(mr operand.Op) { + if inst, err := x86.DECL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +// Construct and append a DECL instruction to the active function. +// Operates on the global context. +func DECL(mr operand.Op) { ctx.DECL(mr) } + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +// Construct and append a DECQ instruction to the active function. +func (c *Context) DECQ(mr operand.Op) { + if inst, err := x86.DECQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +// Construct and append a DECQ instruction to the active function. +// Operates on the global context. +func DECQ(mr operand.Op) { ctx.DECQ(mr) } + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +// Construct and append a DECW instruction to the active function. +func (c *Context) DECW(mr operand.Op) { + if inst, err := x86.DECW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +// Construct and append a DECW instruction to the active function. +// Operates on the global context. +func DECW(mr operand.Op) { ctx.DECW(mr) } + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +// Construct and append a DIVB instruction to the active function. +func (c *Context) DIVB(mr operand.Op) { + if inst, err := x86.DIVB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +// Construct and append a DIVB instruction to the active function. +// Operates on the global context. +func DIVB(mr operand.Op) { ctx.DIVB(mr) } + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +// Construct and append a DIVL instruction to the active function. +func (c *Context) DIVL(mr operand.Op) { + if inst, err := x86.DIVL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +// Construct and append a DIVL instruction to the active function. +// Operates on the global context. +func DIVL(mr operand.Op) { ctx.DIVL(mr) } + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +// Construct and append a DIVPD instruction to the active function. +func (c *Context) DIVPD(mx, x operand.Op) { + if inst, err := x86.DIVPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +// Construct and append a DIVPD instruction to the active function. +// Operates on the global context. +func DIVPD(mx, x operand.Op) { ctx.DIVPD(mx, x) } + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +// Construct and append a DIVPS instruction to the active function. +func (c *Context) DIVPS(mx, x operand.Op) { + if inst, err := x86.DIVPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +// Construct and append a DIVPS instruction to the active function. +// Operates on the global context. +func DIVPS(mx, x operand.Op) { ctx.DIVPS(mx, x) } + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +// Construct and append a DIVQ instruction to the active function. +func (c *Context) DIVQ(mr operand.Op) { + if inst, err := x86.DIVQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +// Construct and append a DIVQ instruction to the active function. +// Operates on the global context. +func DIVQ(mr operand.Op) { ctx.DIVQ(mr) } + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +// Construct and append a DIVSD instruction to the active function. +func (c *Context) DIVSD(mx, x operand.Op) { + if inst, err := x86.DIVSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +// Construct and append a DIVSD instruction to the active function. +// Operates on the global context. +func DIVSD(mx, x operand.Op) { ctx.DIVSD(mx, x) } + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +// Construct and append a DIVSS instruction to the active function. +func (c *Context) DIVSS(mx, x operand.Op) { + if inst, err := x86.DIVSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +// Construct and append a DIVSS instruction to the active function. +// Operates on the global context. +func DIVSS(mx, x operand.Op) { ctx.DIVSS(mx, x) } + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +// Construct and append a DIVW instruction to the active function. +func (c *Context) DIVW(mr operand.Op) { + if inst, err := x86.DIVW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +// Construct and append a DIVW instruction to the active function. +// Operates on the global context. +func DIVW(mr operand.Op) { ctx.DIVW(mr) } + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +// Construct and append a DPPD instruction to the active function. +func (c *Context) DPPD(i, mx, x operand.Op) { + if inst, err := x86.DPPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +// Construct and append a DPPD instruction to the active function. +// Operates on the global context. +func DPPD(i, mx, x operand.Op) { ctx.DPPD(i, mx, x) } + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +// Construct and append a DPPS instruction to the active function. +func (c *Context) DPPS(i, mx, x operand.Op) { + if inst, err := x86.DPPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +// Construct and append a DPPS instruction to the active function. +// Operates on the global context. +func DPPS(i, mx, x operand.Op) { ctx.DPPS(i, mx, x) } + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +// Construct and append a EXTRACTPS instruction to the active function. +func (c *Context) EXTRACTPS(i, x, mr operand.Op) { + if inst, err := x86.EXTRACTPS(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +// Construct and append a EXTRACTPS instruction to the active function. +// Operates on the global context. +func EXTRACTPS(i, x, mr operand.Op) { ctx.EXTRACTPS(i, x, mr) } + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +// Construct and append a HADDPD instruction to the active function. +func (c *Context) HADDPD(mx, x operand.Op) { + if inst, err := x86.HADDPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +// Construct and append a HADDPD instruction to the active function. +// Operates on the global context. +func HADDPD(mx, x operand.Op) { ctx.HADDPD(mx, x) } + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +// Construct and append a HADDPS instruction to the active function. +func (c *Context) HADDPS(mx, x operand.Op) { + if inst, err := x86.HADDPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +// Construct and append a HADDPS instruction to the active function. +// Operates on the global context. +func HADDPS(mx, x operand.Op) { ctx.HADDPS(mx, x) } + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +// Construct and append a HSUBPD instruction to the active function. +func (c *Context) HSUBPD(mx, x operand.Op) { + if inst, err := x86.HSUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +// Construct and append a HSUBPD instruction to the active function. +// Operates on the global context. +func HSUBPD(mx, x operand.Op) { ctx.HSUBPD(mx, x) } + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +// Construct and append a HSUBPS instruction to the active function. +func (c *Context) HSUBPS(mx, x operand.Op) { + if inst, err := x86.HSUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +// Construct and append a HSUBPS instruction to the active function. +// Operates on the global context. +func HSUBPS(mx, x operand.Op) { ctx.HSUBPS(mx, x) } + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +// Construct and append a IDIVB instruction to the active function. +func (c *Context) IDIVB(mr operand.Op) { + if inst, err := x86.IDIVB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +// Construct and append a IDIVB instruction to the active function. +// Operates on the global context. +func IDIVB(mr operand.Op) { ctx.IDIVB(mr) } + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +// Construct and append a IDIVL instruction to the active function. +func (c *Context) IDIVL(mr operand.Op) { + if inst, err := x86.IDIVL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +// Construct and append a IDIVL instruction to the active function. +// Operates on the global context. +func IDIVL(mr operand.Op) { ctx.IDIVL(mr) } + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +// Construct and append a IDIVQ instruction to the active function. +func (c *Context) IDIVQ(mr operand.Op) { + if inst, err := x86.IDIVQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +// Construct and append a IDIVQ instruction to the active function. +// Operates on the global context. +func IDIVQ(mr operand.Op) { ctx.IDIVQ(mr) } + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +// Construct and append a IDIVW instruction to the active function. +func (c *Context) IDIVW(mr operand.Op) { + if inst, err := x86.IDIVW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +// Construct and append a IDIVW instruction to the active function. +// Operates on the global context. +func IDIVW(mr operand.Op) { ctx.IDIVW(mr) } + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +// Construct and append a IMUL3L instruction to the active function. +func (c *Context) IMUL3L(i, mr, r operand.Op) { + if inst, err := x86.IMUL3L(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +// Construct and append a IMUL3L instruction to the active function. +// Operates on the global context. +func IMUL3L(i, mr, r operand.Op) { ctx.IMUL3L(i, mr, r) } + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +// Construct and append a IMUL3Q instruction to the active function. +func (c *Context) IMUL3Q(i, mr, r operand.Op) { + if inst, err := x86.IMUL3Q(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +// Construct and append a IMUL3Q instruction to the active function. +// Operates on the global context. +func IMUL3Q(i, mr, r operand.Op) { ctx.IMUL3Q(i, mr, r) } + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +// Construct and append a IMUL3W instruction to the active function. +func (c *Context) IMUL3W(i, mr, r operand.Op) { + if inst, err := x86.IMUL3W(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +// Construct and append a IMUL3W instruction to the active function. +// Operates on the global context. +func IMUL3W(i, mr, r operand.Op) { ctx.IMUL3W(i, mr, r) } + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +// Construct and append a IMULB instruction to the active function. +func (c *Context) IMULB(mr operand.Op) { + if inst, err := x86.IMULB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +// Construct and append a IMULB instruction to the active function. +// Operates on the global context. +func IMULB(mr operand.Op) { ctx.IMULB(mr) } + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +// Construct and append a IMULL instruction to the active function. +func (c *Context) IMULL(ops ...operand.Op) { + if inst, err := x86.IMULL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +// Construct and append a IMULL instruction to the active function. +// Operates on the global context. +func IMULL(ops ...operand.Op) { ctx.IMULL(ops...) } + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +// Construct and append a IMULQ instruction to the active function. +func (c *Context) IMULQ(ops ...operand.Op) { + if inst, err := x86.IMULQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +// Construct and append a IMULQ instruction to the active function. +// Operates on the global context. +func IMULQ(ops ...operand.Op) { ctx.IMULQ(ops...) } + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +// Construct and append a IMULW instruction to the active function. +func (c *Context) IMULW(ops ...operand.Op) { + if inst, err := x86.IMULW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +// Construct and append a IMULW instruction to the active function. +// Operates on the global context. +func IMULW(ops ...operand.Op) { ctx.IMULW(ops...) } + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +// Construct and append a INCB instruction to the active function. +func (c *Context) INCB(mr operand.Op) { + if inst, err := x86.INCB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +// Construct and append a INCB instruction to the active function. +// Operates on the global context. +func INCB(mr operand.Op) { ctx.INCB(mr) } + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +// Construct and append a INCL instruction to the active function. +func (c *Context) INCL(mr operand.Op) { + if inst, err := x86.INCL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +// Construct and append a INCL instruction to the active function. +// Operates on the global context. +func INCL(mr operand.Op) { ctx.INCL(mr) } + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +// Construct and append a INCQ instruction to the active function. +func (c *Context) INCQ(mr operand.Op) { + if inst, err := x86.INCQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +// Construct and append a INCQ instruction to the active function. +// Operates on the global context. +func INCQ(mr operand.Op) { ctx.INCQ(mr) } + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +// Construct and append a INCW instruction to the active function. +func (c *Context) INCW(mr operand.Op) { + if inst, err := x86.INCW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +// Construct and append a INCW instruction to the active function. +// Operates on the global context. +func INCW(mr operand.Op) { ctx.INCW(mr) } + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +// Construct and append a INSERTPS instruction to the active function. +func (c *Context) INSERTPS(i, mx, x operand.Op) { + if inst, err := x86.INSERTPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +// Construct and append a INSERTPS instruction to the active function. +// Operates on the global context. +func INSERTPS(i, mx, x operand.Op) { ctx.INSERTPS(i, mx, x) } + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +// Construct and append a INT instruction to the active function. +func (c *Context) INT(i operand.Op) { + if inst, err := x86.INT(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +// Construct and append a INT instruction to the active function. +// Operates on the global context. +func INT(i operand.Op) { ctx.INT(i) } + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +// Construct and append a JA instruction to the active function. +func (c *Context) JA(r operand.Op) { + if inst, err := x86.JA(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +// Construct and append a JA instruction to the active function. +// Operates on the global context. +func JA(r operand.Op) { ctx.JA(r) } + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +// Construct and append a JAE instruction to the active function. +func (c *Context) JAE(r operand.Op) { + if inst, err := x86.JAE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +// Construct and append a JAE instruction to the active function. +// Operates on the global context. +func JAE(r operand.Op) { ctx.JAE(r) } + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +// Construct and append a JB instruction to the active function. +func (c *Context) JB(r operand.Op) { + if inst, err := x86.JB(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +// Construct and append a JB instruction to the active function. +// Operates on the global context. +func JB(r operand.Op) { ctx.JB(r) } + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +// Construct and append a JBE instruction to the active function. +func (c *Context) JBE(r operand.Op) { + if inst, err := x86.JBE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +// Construct and append a JBE instruction to the active function. +// Operates on the global context. +func JBE(r operand.Op) { ctx.JBE(r) } + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +// Construct and append a JC instruction to the active function. +func (c *Context) JC(r operand.Op) { + if inst, err := x86.JC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +// Construct and append a JC instruction to the active function. +// Operates on the global context. +func JC(r operand.Op) { ctx.JC(r) } + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +// Construct and append a JCC instruction to the active function. +func (c *Context) JCC(r operand.Op) { + if inst, err := x86.JCC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +// Construct and append a JCC instruction to the active function. +// Operates on the global context. +func JCC(r operand.Op) { ctx.JCC(r) } + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +// Construct and append a JCS instruction to the active function. +func (c *Context) JCS(r operand.Op) { + if inst, err := x86.JCS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +// Construct and append a JCS instruction to the active function. +// Operates on the global context. +func JCS(r operand.Op) { ctx.JCS(r) } + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +// Construct and append a JCXZL instruction to the active function. +func (c *Context) JCXZL(r operand.Op) { + if inst, err := x86.JCXZL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +// Construct and append a JCXZL instruction to the active function. +// Operates on the global context. +func JCXZL(r operand.Op) { ctx.JCXZL(r) } + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +// Construct and append a JCXZQ instruction to the active function. +func (c *Context) JCXZQ(r operand.Op) { + if inst, err := x86.JCXZQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +// Construct and append a JCXZQ instruction to the active function. +// Operates on the global context. +func JCXZQ(r operand.Op) { ctx.JCXZQ(r) } + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +// Construct and append a JE instruction to the active function. +func (c *Context) JE(r operand.Op) { + if inst, err := x86.JE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +// Construct and append a JE instruction to the active function. +// Operates on the global context. +func JE(r operand.Op) { ctx.JE(r) } + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +// Construct and append a JEQ instruction to the active function. +func (c *Context) JEQ(r operand.Op) { + if inst, err := x86.JEQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +// Construct and append a JEQ instruction to the active function. +// Operates on the global context. +func JEQ(r operand.Op) { ctx.JEQ(r) } + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +// Construct and append a JG instruction to the active function. +func (c *Context) JG(r operand.Op) { + if inst, err := x86.JG(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +// Construct and append a JG instruction to the active function. +// Operates on the global context. +func JG(r operand.Op) { ctx.JG(r) } + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +// Construct and append a JGE instruction to the active function. +func (c *Context) JGE(r operand.Op) { + if inst, err := x86.JGE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +// Construct and append a JGE instruction to the active function. +// Operates on the global context. +func JGE(r operand.Op) { ctx.JGE(r) } + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +// Construct and append a JGT instruction to the active function. +func (c *Context) JGT(r operand.Op) { + if inst, err := x86.JGT(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +// Construct and append a JGT instruction to the active function. +// Operates on the global context. +func JGT(r operand.Op) { ctx.JGT(r) } + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +// Construct and append a JHI instruction to the active function. +func (c *Context) JHI(r operand.Op) { + if inst, err := x86.JHI(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +// Construct and append a JHI instruction to the active function. +// Operates on the global context. +func JHI(r operand.Op) { ctx.JHI(r) } + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +// Construct and append a JHS instruction to the active function. +func (c *Context) JHS(r operand.Op) { + if inst, err := x86.JHS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +// Construct and append a JHS instruction to the active function. +// Operates on the global context. +func JHS(r operand.Op) { ctx.JHS(r) } + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +// Construct and append a JL instruction to the active function. +func (c *Context) JL(r operand.Op) { + if inst, err := x86.JL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +// Construct and append a JL instruction to the active function. +// Operates on the global context. +func JL(r operand.Op) { ctx.JL(r) } + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +// Construct and append a JLE instruction to the active function. +func (c *Context) JLE(r operand.Op) { + if inst, err := x86.JLE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +// Construct and append a JLE instruction to the active function. +// Operates on the global context. +func JLE(r operand.Op) { ctx.JLE(r) } + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +// Construct and append a JLO instruction to the active function. +func (c *Context) JLO(r operand.Op) { + if inst, err := x86.JLO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +// Construct and append a JLO instruction to the active function. +// Operates on the global context. +func JLO(r operand.Op) { ctx.JLO(r) } + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +// Construct and append a JLS instruction to the active function. +func (c *Context) JLS(r operand.Op) { + if inst, err := x86.JLS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +// Construct and append a JLS instruction to the active function. +// Operates on the global context. +func JLS(r operand.Op) { ctx.JLS(r) } + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +// Construct and append a JLT instruction to the active function. +func (c *Context) JLT(r operand.Op) { + if inst, err := x86.JLT(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +// Construct and append a JLT instruction to the active function. +// Operates on the global context. +func JLT(r operand.Op) { ctx.JLT(r) } + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +// Construct and append a JMI instruction to the active function. +func (c *Context) JMI(r operand.Op) { + if inst, err := x86.JMI(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +// Construct and append a JMI instruction to the active function. +// Operates on the global context. +func JMI(r operand.Op) { ctx.JMI(r) } + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +// Construct and append a JMP instruction to the active function. +func (c *Context) JMP(mr operand.Op) { + if inst, err := x86.JMP(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +// Construct and append a JMP instruction to the active function. +// Operates on the global context. +func JMP(mr operand.Op) { ctx.JMP(mr) } + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +// Construct and append a JNA instruction to the active function. +func (c *Context) JNA(r operand.Op) { + if inst, err := x86.JNA(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +// Construct and append a JNA instruction to the active function. +// Operates on the global context. +func JNA(r operand.Op) { ctx.JNA(r) } + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +// Construct and append a JNAE instruction to the active function. +func (c *Context) JNAE(r operand.Op) { + if inst, err := x86.JNAE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +// Construct and append a JNAE instruction to the active function. +// Operates on the global context. +func JNAE(r operand.Op) { ctx.JNAE(r) } + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +// Construct and append a JNB instruction to the active function. +func (c *Context) JNB(r operand.Op) { + if inst, err := x86.JNB(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +// Construct and append a JNB instruction to the active function. +// Operates on the global context. +func JNB(r operand.Op) { ctx.JNB(r) } + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +// Construct and append a JNBE instruction to the active function. +func (c *Context) JNBE(r operand.Op) { + if inst, err := x86.JNBE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +// Construct and append a JNBE instruction to the active function. +// Operates on the global context. +func JNBE(r operand.Op) { ctx.JNBE(r) } + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +// Construct and append a JNC instruction to the active function. +func (c *Context) JNC(r operand.Op) { + if inst, err := x86.JNC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +// Construct and append a JNC instruction to the active function. +// Operates on the global context. +func JNC(r operand.Op) { ctx.JNC(r) } + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +// Construct and append a JNE instruction to the active function. +func (c *Context) JNE(r operand.Op) { + if inst, err := x86.JNE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +// Construct and append a JNE instruction to the active function. +// Operates on the global context. +func JNE(r operand.Op) { ctx.JNE(r) } + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +// Construct and append a JNG instruction to the active function. +func (c *Context) JNG(r operand.Op) { + if inst, err := x86.JNG(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +// Construct and append a JNG instruction to the active function. +// Operates on the global context. +func JNG(r operand.Op) { ctx.JNG(r) } + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +// Construct and append a JNGE instruction to the active function. +func (c *Context) JNGE(r operand.Op) { + if inst, err := x86.JNGE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +// Construct and append a JNGE instruction to the active function. +// Operates on the global context. +func JNGE(r operand.Op) { ctx.JNGE(r) } + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +// Construct and append a JNL instruction to the active function. +func (c *Context) JNL(r operand.Op) { + if inst, err := x86.JNL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +// Construct and append a JNL instruction to the active function. +// Operates on the global context. +func JNL(r operand.Op) { ctx.JNL(r) } + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +// Construct and append a JNLE instruction to the active function. +func (c *Context) JNLE(r operand.Op) { + if inst, err := x86.JNLE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +// Construct and append a JNLE instruction to the active function. +// Operates on the global context. +func JNLE(r operand.Op) { ctx.JNLE(r) } + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +// Construct and append a JNO instruction to the active function. +func (c *Context) JNO(r operand.Op) { + if inst, err := x86.JNO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +// Construct and append a JNO instruction to the active function. +// Operates on the global context. +func JNO(r operand.Op) { ctx.JNO(r) } + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +// Construct and append a JNP instruction to the active function. +func (c *Context) JNP(r operand.Op) { + if inst, err := x86.JNP(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +// Construct and append a JNP instruction to the active function. +// Operates on the global context. +func JNP(r operand.Op) { ctx.JNP(r) } + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +// Construct and append a JNS instruction to the active function. +func (c *Context) JNS(r operand.Op) { + if inst, err := x86.JNS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +// Construct and append a JNS instruction to the active function. +// Operates on the global context. +func JNS(r operand.Op) { ctx.JNS(r) } + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +// Construct and append a JNZ instruction to the active function. +func (c *Context) JNZ(r operand.Op) { + if inst, err := x86.JNZ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +// Construct and append a JNZ instruction to the active function. +// Operates on the global context. +func JNZ(r operand.Op) { ctx.JNZ(r) } + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +// Construct and append a JO instruction to the active function. +func (c *Context) JO(r operand.Op) { + if inst, err := x86.JO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +// Construct and append a JO instruction to the active function. +// Operates on the global context. +func JO(r operand.Op) { ctx.JO(r) } + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +// Construct and append a JOC instruction to the active function. +func (c *Context) JOC(r operand.Op) { + if inst, err := x86.JOC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +// Construct and append a JOC instruction to the active function. +// Operates on the global context. +func JOC(r operand.Op) { ctx.JOC(r) } + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +// Construct and append a JOS instruction to the active function. +func (c *Context) JOS(r operand.Op) { + if inst, err := x86.JOS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +// Construct and append a JOS instruction to the active function. +// Operates on the global context. +func JOS(r operand.Op) { ctx.JOS(r) } + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +// Construct and append a JP instruction to the active function. +func (c *Context) JP(r operand.Op) { + if inst, err := x86.JP(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +// Construct and append a JP instruction to the active function. +// Operates on the global context. +func JP(r operand.Op) { ctx.JP(r) } + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +// Construct and append a JPC instruction to the active function. +func (c *Context) JPC(r operand.Op) { + if inst, err := x86.JPC(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +// Construct and append a JPC instruction to the active function. +// Operates on the global context. +func JPC(r operand.Op) { ctx.JPC(r) } + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +// Construct and append a JPE instruction to the active function. +func (c *Context) JPE(r operand.Op) { + if inst, err := x86.JPE(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +// Construct and append a JPE instruction to the active function. +// Operates on the global context. +func JPE(r operand.Op) { ctx.JPE(r) } + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +// Construct and append a JPL instruction to the active function. +func (c *Context) JPL(r operand.Op) { + if inst, err := x86.JPL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +// Construct and append a JPL instruction to the active function. +// Operates on the global context. +func JPL(r operand.Op) { ctx.JPL(r) } + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +// Construct and append a JPO instruction to the active function. +func (c *Context) JPO(r operand.Op) { + if inst, err := x86.JPO(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +// Construct and append a JPO instruction to the active function. +// Operates on the global context. +func JPO(r operand.Op) { ctx.JPO(r) } + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +// Construct and append a JPS instruction to the active function. +func (c *Context) JPS(r operand.Op) { + if inst, err := x86.JPS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +// Construct and append a JPS instruction to the active function. +// Operates on the global context. +func JPS(r operand.Op) { ctx.JPS(r) } + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +// Construct and append a JS instruction to the active function. +func (c *Context) JS(r operand.Op) { + if inst, err := x86.JS(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +// Construct and append a JS instruction to the active function. +// Operates on the global context. +func JS(r operand.Op) { ctx.JS(r) } + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +// Construct and append a JZ instruction to the active function. +func (c *Context) JZ(r operand.Op) { + if inst, err := x86.JZ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +// Construct and append a JZ instruction to the active function. +// Operates on the global context. +func JZ(r operand.Op) { ctx.JZ(r) } + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +// Construct and append a LDDQU instruction to the active function. +func (c *Context) LDDQU(m, x operand.Op) { + if inst, err := x86.LDDQU(m, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +// Construct and append a LDDQU instruction to the active function. +// Operates on the global context. +func LDDQU(m, x operand.Op) { ctx.LDDQU(m, x) } + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +// Construct and append a LDMXCSR instruction to the active function. +func (c *Context) LDMXCSR(m operand.Op) { + if inst, err := x86.LDMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +// Construct and append a LDMXCSR instruction to the active function. +// Operates on the global context. +func LDMXCSR(m operand.Op) { ctx.LDMXCSR(m) } + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +// Construct and append a LEAL instruction to the active function. +func (c *Context) LEAL(m, r operand.Op) { + if inst, err := x86.LEAL(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +// Construct and append a LEAL instruction to the active function. +// Operates on the global context. +func LEAL(m, r operand.Op) { ctx.LEAL(m, r) } + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +// Construct and append a LEAQ instruction to the active function. +func (c *Context) LEAQ(m, r operand.Op) { + if inst, err := x86.LEAQ(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +// Construct and append a LEAQ instruction to the active function. +// Operates on the global context. +func LEAQ(m, r operand.Op) { ctx.LEAQ(m, r) } + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +// Construct and append a LEAW instruction to the active function. +func (c *Context) LEAW(m, r operand.Op) { + if inst, err := x86.LEAW(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +// Construct and append a LEAW instruction to the active function. +// Operates on the global context. +func LEAW(m, r operand.Op) { ctx.LEAW(m, r) } + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +// Construct and append a LFENCE instruction to the active function. +func (c *Context) LFENCE() { + if inst, err := x86.LFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +// Construct and append a LFENCE instruction to the active function. +// Operates on the global context. +func LFENCE() { ctx.LFENCE() } + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +// Construct and append a LZCNTL instruction to the active function. +func (c *Context) LZCNTL(mr, r operand.Op) { + if inst, err := x86.LZCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +// Construct and append a LZCNTL instruction to the active function. +// Operates on the global context. +func LZCNTL(mr, r operand.Op) { ctx.LZCNTL(mr, r) } + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +// Construct and append a LZCNTQ instruction to the active function. +func (c *Context) LZCNTQ(mr, r operand.Op) { + if inst, err := x86.LZCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +// Construct and append a LZCNTQ instruction to the active function. +// Operates on the global context. +func LZCNTQ(mr, r operand.Op) { ctx.LZCNTQ(mr, r) } + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +// Construct and append a LZCNTW instruction to the active function. +func (c *Context) LZCNTW(mr, r operand.Op) { + if inst, err := x86.LZCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +// Construct and append a LZCNTW instruction to the active function. +// Operates on the global context. +func LZCNTW(mr, r operand.Op) { ctx.LZCNTW(mr, r) } + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +// Construct and append a MASKMOVDQU instruction to the active function. +func (c *Context) MASKMOVDQU(x, x1 operand.Op) { + if inst, err := x86.MASKMOVDQU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +// Construct and append a MASKMOVDQU instruction to the active function. +// Operates on the global context. +func MASKMOVDQU(x, x1 operand.Op) { ctx.MASKMOVDQU(x, x1) } + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +// Construct and append a MASKMOVOU instruction to the active function. +func (c *Context) MASKMOVOU(x, x1 operand.Op) { + if inst, err := x86.MASKMOVOU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +// Construct and append a MASKMOVOU instruction to the active function. +// Operates on the global context. +func MASKMOVOU(x, x1 operand.Op) { ctx.MASKMOVOU(x, x1) } + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +// Construct and append a MAXPD instruction to the active function. +func (c *Context) MAXPD(mx, x operand.Op) { + if inst, err := x86.MAXPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +// Construct and append a MAXPD instruction to the active function. +// Operates on the global context. +func MAXPD(mx, x operand.Op) { ctx.MAXPD(mx, x) } + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +// Construct and append a MAXPS instruction to the active function. +func (c *Context) MAXPS(mx, x operand.Op) { + if inst, err := x86.MAXPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +// Construct and append a MAXPS instruction to the active function. +// Operates on the global context. +func MAXPS(mx, x operand.Op) { ctx.MAXPS(mx, x) } + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +// Construct and append a MAXSD instruction to the active function. +func (c *Context) MAXSD(mx, x operand.Op) { + if inst, err := x86.MAXSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +// Construct and append a MAXSD instruction to the active function. +// Operates on the global context. +func MAXSD(mx, x operand.Op) { ctx.MAXSD(mx, x) } + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +// Construct and append a MAXSS instruction to the active function. +func (c *Context) MAXSS(mx, x operand.Op) { + if inst, err := x86.MAXSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +// Construct and append a MAXSS instruction to the active function. +// Operates on the global context. +func MAXSS(mx, x operand.Op) { ctx.MAXSS(mx, x) } + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +// Construct and append a MFENCE instruction to the active function. +func (c *Context) MFENCE() { + if inst, err := x86.MFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +// Construct and append a MFENCE instruction to the active function. +// Operates on the global context. +func MFENCE() { ctx.MFENCE() } + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +// Construct and append a MINPD instruction to the active function. +func (c *Context) MINPD(mx, x operand.Op) { + if inst, err := x86.MINPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +// Construct and append a MINPD instruction to the active function. +// Operates on the global context. +func MINPD(mx, x operand.Op) { ctx.MINPD(mx, x) } + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +// Construct and append a MINPS instruction to the active function. +func (c *Context) MINPS(mx, x operand.Op) { + if inst, err := x86.MINPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +// Construct and append a MINPS instruction to the active function. +// Operates on the global context. +func MINPS(mx, x operand.Op) { ctx.MINPS(mx, x) } + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +// Construct and append a MINSD instruction to the active function. +func (c *Context) MINSD(mx, x operand.Op) { + if inst, err := x86.MINSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +// Construct and append a MINSD instruction to the active function. +// Operates on the global context. +func MINSD(mx, x operand.Op) { ctx.MINSD(mx, x) } + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +// Construct and append a MINSS instruction to the active function. +func (c *Context) MINSS(mx, x operand.Op) { + if inst, err := x86.MINSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +// Construct and append a MINSS instruction to the active function. +// Operates on the global context. +func MINSS(mx, x operand.Op) { ctx.MINSS(mx, x) } + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +// Construct and append a MONITOR instruction to the active function. +func (c *Context) MONITOR() { + if inst, err := x86.MONITOR(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +// Construct and append a MONITOR instruction to the active function. +// Operates on the global context. +func MONITOR() { ctx.MONITOR() } + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +// Construct and append a MOVAPD instruction to the active function. +func (c *Context) MOVAPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVAPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +// Construct and append a MOVAPD instruction to the active function. +// Operates on the global context. +func MOVAPD(mx, mx1 operand.Op) { ctx.MOVAPD(mx, mx1) } + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +// Construct and append a MOVAPS instruction to the active function. +func (c *Context) MOVAPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVAPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +// Construct and append a MOVAPS instruction to the active function. +// Operates on the global context. +func MOVAPS(mx, mx1 operand.Op) { ctx.MOVAPS(mx, mx1) } + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +// Construct and append a MOVB instruction to the active function. +func (c *Context) MOVB(imr, mr operand.Op) { + if inst, err := x86.MOVB(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +// Construct and append a MOVB instruction to the active function. +// Operates on the global context. +func MOVB(imr, mr operand.Op) { ctx.MOVB(imr, mr) } + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +// Construct and append a MOVBELL instruction to the active function. +func (c *Context) MOVBELL(mr, mr1 operand.Op) { + if inst, err := x86.MOVBELL(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +// Construct and append a MOVBELL instruction to the active function. +// Operates on the global context. +func MOVBELL(mr, mr1 operand.Op) { ctx.MOVBELL(mr, mr1) } + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +// Construct and append a MOVBEQQ instruction to the active function. +func (c *Context) MOVBEQQ(mr, mr1 operand.Op) { + if inst, err := x86.MOVBEQQ(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +// Construct and append a MOVBEQQ instruction to the active function. +// Operates on the global context. +func MOVBEQQ(mr, mr1 operand.Op) { ctx.MOVBEQQ(mr, mr1) } + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +// Construct and append a MOVBEWW instruction to the active function. +func (c *Context) MOVBEWW(mr, mr1 operand.Op) { + if inst, err := x86.MOVBEWW(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +// Construct and append a MOVBEWW instruction to the active function. +// Operates on the global context. +func MOVBEWW(mr, mr1 operand.Op) { ctx.MOVBEWW(mr, mr1) } + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +// Construct and append a MOVBLSX instruction to the active function. +func (c *Context) MOVBLSX(mr, r operand.Op) { + if inst, err := x86.MOVBLSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +// Construct and append a MOVBLSX instruction to the active function. +// Operates on the global context. +func MOVBLSX(mr, r operand.Op) { ctx.MOVBLSX(mr, r) } + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +// Construct and append a MOVBLZX instruction to the active function. +func (c *Context) MOVBLZX(mr, r operand.Op) { + if inst, err := x86.MOVBLZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +// Construct and append a MOVBLZX instruction to the active function. +// Operates on the global context. +func MOVBLZX(mr, r operand.Op) { ctx.MOVBLZX(mr, r) } + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +// Construct and append a MOVBQSX instruction to the active function. +func (c *Context) MOVBQSX(mr, r operand.Op) { + if inst, err := x86.MOVBQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +// Construct and append a MOVBQSX instruction to the active function. +// Operates on the global context. +func MOVBQSX(mr, r operand.Op) { ctx.MOVBQSX(mr, r) } + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +// Construct and append a MOVBQZX instruction to the active function. +func (c *Context) MOVBQZX(mr, r operand.Op) { + if inst, err := x86.MOVBQZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +// Construct and append a MOVBQZX instruction to the active function. +// Operates on the global context. +func MOVBQZX(mr, r operand.Op) { ctx.MOVBQZX(mr, r) } + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +// Construct and append a MOVBWSX instruction to the active function. +func (c *Context) MOVBWSX(mr, r operand.Op) { + if inst, err := x86.MOVBWSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +// Construct and append a MOVBWSX instruction to the active function. +// Operates on the global context. +func MOVBWSX(mr, r operand.Op) { ctx.MOVBWSX(mr, r) } + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +// Construct and append a MOVBWZX instruction to the active function. +func (c *Context) MOVBWZX(mr, r operand.Op) { + if inst, err := x86.MOVBWZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +// Construct and append a MOVBWZX instruction to the active function. +// Operates on the global context. +func MOVBWZX(mr, r operand.Op) { ctx.MOVBWZX(mr, r) } + +// MOVD: Move. +// +// Forms: +// +// MOVD imm32 r64 +// MOVD imm64 r64 +// MOVD r64 r64 +// MOVD m64 r64 +// MOVD imm32 m64 +// MOVD r64 m64 +// MOVD xmm r64 +// MOVD r64 xmm +// MOVD xmm xmm +// MOVD m64 xmm +// MOVD xmm m64 +// MOVD xmm r32 +// MOVD r32 xmm +// MOVD m32 xmm +// MOVD xmm m32 +// Construct and append a MOVD instruction to the active function. +func (c *Context) MOVD(imrx, mrx operand.Op) { + if inst, err := x86.MOVD(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVD: Move. +// +// Forms: +// +// MOVD imm32 r64 +// MOVD imm64 r64 +// MOVD r64 r64 +// MOVD m64 r64 +// MOVD imm32 m64 +// MOVD r64 m64 +// MOVD xmm r64 +// MOVD r64 xmm +// MOVD xmm xmm +// MOVD m64 xmm +// MOVD xmm m64 +// MOVD xmm r32 +// MOVD r32 xmm +// MOVD m32 xmm +// MOVD xmm m32 +// Construct and append a MOVD instruction to the active function. +// Operates on the global context. +func MOVD(imrx, mrx operand.Op) { ctx.MOVD(imrx, mrx) } + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +// Construct and append a MOVDDUP instruction to the active function. +func (c *Context) MOVDDUP(mx, x operand.Op) { + if inst, err := x86.MOVDDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +// Construct and append a MOVDDUP instruction to the active function. +// Operates on the global context. +func MOVDDUP(mx, x operand.Op) { ctx.MOVDDUP(mx, x) } + +// MOVDQ2Q: Move. +// +// Forms: +// +// MOVDQ2Q imm32 r64 +// MOVDQ2Q imm64 r64 +// MOVDQ2Q r64 r64 +// MOVDQ2Q m64 r64 +// MOVDQ2Q imm32 m64 +// MOVDQ2Q r64 m64 +// MOVDQ2Q xmm r64 +// MOVDQ2Q r64 xmm +// MOVDQ2Q xmm xmm +// MOVDQ2Q m64 xmm +// MOVDQ2Q xmm m64 +// MOVDQ2Q xmm r32 +// MOVDQ2Q r32 xmm +// MOVDQ2Q m32 xmm +// MOVDQ2Q xmm m32 +// Construct and append a MOVDQ2Q instruction to the active function. +func (c *Context) MOVDQ2Q(imrx, mrx operand.Op) { + if inst, err := x86.MOVDQ2Q(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVDQ2Q: Move. +// +// Forms: +// +// MOVDQ2Q imm32 r64 +// MOVDQ2Q imm64 r64 +// MOVDQ2Q r64 r64 +// MOVDQ2Q m64 r64 +// MOVDQ2Q imm32 m64 +// MOVDQ2Q r64 m64 +// MOVDQ2Q xmm r64 +// MOVDQ2Q r64 xmm +// MOVDQ2Q xmm xmm +// MOVDQ2Q m64 xmm +// MOVDQ2Q xmm m64 +// MOVDQ2Q xmm r32 +// MOVDQ2Q r32 xmm +// MOVDQ2Q m32 xmm +// MOVDQ2Q xmm m32 +// Construct and append a MOVDQ2Q instruction to the active function. +// Operates on the global context. +func MOVDQ2Q(imrx, mrx operand.Op) { ctx.MOVDQ2Q(imrx, mrx) } + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +// Construct and append a MOVHLPS instruction to the active function. +func (c *Context) MOVHLPS(x, x1 operand.Op) { + if inst, err := x86.MOVHLPS(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +// Construct and append a MOVHLPS instruction to the active function. +// Operates on the global context. +func MOVHLPS(x, x1 operand.Op) { ctx.MOVHLPS(x, x1) } + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +// Construct and append a MOVHPD instruction to the active function. +func (c *Context) MOVHPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVHPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +// Construct and append a MOVHPD instruction to the active function. +// Operates on the global context. +func MOVHPD(mx, mx1 operand.Op) { ctx.MOVHPD(mx, mx1) } + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +// Construct and append a MOVHPS instruction to the active function. +func (c *Context) MOVHPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVHPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +// Construct and append a MOVHPS instruction to the active function. +// Operates on the global context. +func MOVHPS(mx, mx1 operand.Op) { ctx.MOVHPS(mx, mx1) } + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +// Construct and append a MOVL instruction to the active function. +func (c *Context) MOVL(imr, mr operand.Op) { + if inst, err := x86.MOVL(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +// Construct and append a MOVL instruction to the active function. +// Operates on the global context. +func MOVL(imr, mr operand.Op) { ctx.MOVL(imr, mr) } + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +// Construct and append a MOVLHPS instruction to the active function. +func (c *Context) MOVLHPS(x, x1 operand.Op) { + if inst, err := x86.MOVLHPS(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +// Construct and append a MOVLHPS instruction to the active function. +// Operates on the global context. +func MOVLHPS(x, x1 operand.Op) { ctx.MOVLHPS(x, x1) } + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +// Construct and append a MOVLPD instruction to the active function. +func (c *Context) MOVLPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVLPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +// Construct and append a MOVLPD instruction to the active function. +// Operates on the global context. +func MOVLPD(mx, mx1 operand.Op) { ctx.MOVLPD(mx, mx1) } + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +// Construct and append a MOVLPS instruction to the active function. +func (c *Context) MOVLPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVLPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +// Construct and append a MOVLPS instruction to the active function. +// Operates on the global context. +func MOVLPS(mx, mx1 operand.Op) { ctx.MOVLPS(mx, mx1) } + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +// Construct and append a MOVLQSX instruction to the active function. +func (c *Context) MOVLQSX(mr, r operand.Op) { + if inst, err := x86.MOVLQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +// Construct and append a MOVLQSX instruction to the active function. +// Operates on the global context. +func MOVLQSX(mr, r operand.Op) { ctx.MOVLQSX(mr, r) } + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +// Construct and append a MOVLQZX instruction to the active function. +func (c *Context) MOVLQZX(m, r operand.Op) { + if inst, err := x86.MOVLQZX(m, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +// Construct and append a MOVLQZX instruction to the active function. +// Operates on the global context. +func MOVLQZX(m, r operand.Op) { ctx.MOVLQZX(m, r) } + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +// Construct and append a MOVMSKPD instruction to the active function. +func (c *Context) MOVMSKPD(x, r operand.Op) { + if inst, err := x86.MOVMSKPD(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +// Construct and append a MOVMSKPD instruction to the active function. +// Operates on the global context. +func MOVMSKPD(x, r operand.Op) { ctx.MOVMSKPD(x, r) } + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +// Construct and append a MOVMSKPS instruction to the active function. +func (c *Context) MOVMSKPS(x, r operand.Op) { + if inst, err := x86.MOVMSKPS(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +// Construct and append a MOVMSKPS instruction to the active function. +// Operates on the global context. +func MOVMSKPS(x, r operand.Op) { ctx.MOVMSKPS(x, r) } + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +// Construct and append a MOVNTDQ instruction to the active function. +func (c *Context) MOVNTDQ(x, m operand.Op) { + if inst, err := x86.MOVNTDQ(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +// Construct and append a MOVNTDQ instruction to the active function. +// Operates on the global context. +func MOVNTDQ(x, m operand.Op) { ctx.MOVNTDQ(x, m) } + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +// Construct and append a MOVNTDQA instruction to the active function. +func (c *Context) MOVNTDQA(m, x operand.Op) { + if inst, err := x86.MOVNTDQA(m, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +// Construct and append a MOVNTDQA instruction to the active function. +// Operates on the global context. +func MOVNTDQA(m, x operand.Op) { ctx.MOVNTDQA(m, x) } + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +// Construct and append a MOVNTIL instruction to the active function. +func (c *Context) MOVNTIL(r, m operand.Op) { + if inst, err := x86.MOVNTIL(r, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +// Construct and append a MOVNTIL instruction to the active function. +// Operates on the global context. +func MOVNTIL(r, m operand.Op) { ctx.MOVNTIL(r, m) } + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +// Construct and append a MOVNTIQ instruction to the active function. +func (c *Context) MOVNTIQ(r, m operand.Op) { + if inst, err := x86.MOVNTIQ(r, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +// Construct and append a MOVNTIQ instruction to the active function. +// Operates on the global context. +func MOVNTIQ(r, m operand.Op) { ctx.MOVNTIQ(r, m) } + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +// Construct and append a MOVNTO instruction to the active function. +func (c *Context) MOVNTO(x, m operand.Op) { + if inst, err := x86.MOVNTO(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +// Construct and append a MOVNTO instruction to the active function. +// Operates on the global context. +func MOVNTO(x, m operand.Op) { ctx.MOVNTO(x, m) } + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +// Construct and append a MOVNTPD instruction to the active function. +func (c *Context) MOVNTPD(x, m operand.Op) { + if inst, err := x86.MOVNTPD(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +// Construct and append a MOVNTPD instruction to the active function. +// Operates on the global context. +func MOVNTPD(x, m operand.Op) { ctx.MOVNTPD(x, m) } + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +// Construct and append a MOVNTPS instruction to the active function. +func (c *Context) MOVNTPS(x, m operand.Op) { + if inst, err := x86.MOVNTPS(x, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +// Construct and append a MOVNTPS instruction to the active function. +// Operates on the global context. +func MOVNTPS(x, m operand.Op) { ctx.MOVNTPS(x, m) } + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +// Construct and append a MOVO instruction to the active function. +func (c *Context) MOVO(mx, mx1 operand.Op) { + if inst, err := x86.MOVO(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +// Construct and append a MOVO instruction to the active function. +// Operates on the global context. +func MOVO(mx, mx1 operand.Op) { ctx.MOVO(mx, mx1) } + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +// Construct and append a MOVOA instruction to the active function. +func (c *Context) MOVOA(mx, mx1 operand.Op) { + if inst, err := x86.MOVOA(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +// Construct and append a MOVOA instruction to the active function. +// Operates on the global context. +func MOVOA(mx, mx1 operand.Op) { ctx.MOVOA(mx, mx1) } + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +// Construct and append a MOVOU instruction to the active function. +func (c *Context) MOVOU(mx, mx1 operand.Op) { + if inst, err := x86.MOVOU(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +// Construct and append a MOVOU instruction to the active function. +// Operates on the global context. +func MOVOU(mx, mx1 operand.Op) { ctx.MOVOU(mx, mx1) } + +// MOVQ: Move. +// +// Forms: +// +// MOVQ imm32 r64 +// MOVQ imm64 r64 +// MOVQ r64 r64 +// MOVQ m64 r64 +// MOVQ imm32 m64 +// MOVQ r64 m64 +// MOVQ xmm r64 +// MOVQ r64 xmm +// MOVQ xmm xmm +// MOVQ m64 xmm +// MOVQ xmm m64 +// MOVQ xmm r32 +// MOVQ r32 xmm +// MOVQ m32 xmm +// MOVQ xmm m32 +// Construct and append a MOVQ instruction to the active function. +func (c *Context) MOVQ(imrx, mrx operand.Op) { + if inst, err := x86.MOVQ(imrx, mrx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVQ: Move. +// +// Forms: +// +// MOVQ imm32 r64 +// MOVQ imm64 r64 +// MOVQ r64 r64 +// MOVQ m64 r64 +// MOVQ imm32 m64 +// MOVQ r64 m64 +// MOVQ xmm r64 +// MOVQ r64 xmm +// MOVQ xmm xmm +// MOVQ m64 xmm +// MOVQ xmm m64 +// MOVQ xmm r32 +// MOVQ r32 xmm +// MOVQ m32 xmm +// MOVQ xmm m32 +// Construct and append a MOVQ instruction to the active function. +// Operates on the global context. +func MOVQ(imrx, mrx operand.Op) { ctx.MOVQ(imrx, mrx) } + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +// Construct and append a MOVSD instruction to the active function. +func (c *Context) MOVSD(mx, mx1 operand.Op) { + if inst, err := x86.MOVSD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +// Construct and append a MOVSD instruction to the active function. +// Operates on the global context. +func MOVSD(mx, mx1 operand.Op) { ctx.MOVSD(mx, mx1) } + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +// Construct and append a MOVSHDUP instruction to the active function. +func (c *Context) MOVSHDUP(mx, x operand.Op) { + if inst, err := x86.MOVSHDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +// Construct and append a MOVSHDUP instruction to the active function. +// Operates on the global context. +func MOVSHDUP(mx, x operand.Op) { ctx.MOVSHDUP(mx, x) } + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +// Construct and append a MOVSLDUP instruction to the active function. +func (c *Context) MOVSLDUP(mx, x operand.Op) { + if inst, err := x86.MOVSLDUP(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +// Construct and append a MOVSLDUP instruction to the active function. +// Operates on the global context. +func MOVSLDUP(mx, x operand.Op) { ctx.MOVSLDUP(mx, x) } + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +// Construct and append a MOVSS instruction to the active function. +func (c *Context) MOVSS(mx, mx1 operand.Op) { + if inst, err := x86.MOVSS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +// Construct and append a MOVSS instruction to the active function. +// Operates on the global context. +func MOVSS(mx, mx1 operand.Op) { ctx.MOVSS(mx, mx1) } + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +// Construct and append a MOVUPD instruction to the active function. +func (c *Context) MOVUPD(mx, mx1 operand.Op) { + if inst, err := x86.MOVUPD(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +// Construct and append a MOVUPD instruction to the active function. +// Operates on the global context. +func MOVUPD(mx, mx1 operand.Op) { ctx.MOVUPD(mx, mx1) } + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +// Construct and append a MOVUPS instruction to the active function. +func (c *Context) MOVUPS(mx, mx1 operand.Op) { + if inst, err := x86.MOVUPS(mx, mx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +// Construct and append a MOVUPS instruction to the active function. +// Operates on the global context. +func MOVUPS(mx, mx1 operand.Op) { ctx.MOVUPS(mx, mx1) } + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +// Construct and append a MOVW instruction to the active function. +func (c *Context) MOVW(imr, mr operand.Op) { + if inst, err := x86.MOVW(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +// Construct and append a MOVW instruction to the active function. +// Operates on the global context. +func MOVW(imr, mr operand.Op) { ctx.MOVW(imr, mr) } + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +// Construct and append a MOVWLSX instruction to the active function. +func (c *Context) MOVWLSX(mr, r operand.Op) { + if inst, err := x86.MOVWLSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +// Construct and append a MOVWLSX instruction to the active function. +// Operates on the global context. +func MOVWLSX(mr, r operand.Op) { ctx.MOVWLSX(mr, r) } + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +// Construct and append a MOVWLZX instruction to the active function. +func (c *Context) MOVWLZX(mr, r operand.Op) { + if inst, err := x86.MOVWLZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +// Construct and append a MOVWLZX instruction to the active function. +// Operates on the global context. +func MOVWLZX(mr, r operand.Op) { ctx.MOVWLZX(mr, r) } + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +// Construct and append a MOVWQSX instruction to the active function. +func (c *Context) MOVWQSX(mr, r operand.Op) { + if inst, err := x86.MOVWQSX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +// Construct and append a MOVWQSX instruction to the active function. +// Operates on the global context. +func MOVWQSX(mr, r operand.Op) { ctx.MOVWQSX(mr, r) } + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +// Construct and append a MOVWQZX instruction to the active function. +func (c *Context) MOVWQZX(mr, r operand.Op) { + if inst, err := x86.MOVWQZX(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +// Construct and append a MOVWQZX instruction to the active function. +// Operates on the global context. +func MOVWQZX(mr, r operand.Op) { ctx.MOVWQZX(mr, r) } + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +// Construct and append a MPSADBW instruction to the active function. +func (c *Context) MPSADBW(i, mx, x operand.Op) { + if inst, err := x86.MPSADBW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +// Construct and append a MPSADBW instruction to the active function. +// Operates on the global context. +func MPSADBW(i, mx, x operand.Op) { ctx.MPSADBW(i, mx, x) } + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +// Construct and append a MULB instruction to the active function. +func (c *Context) MULB(mr operand.Op) { + if inst, err := x86.MULB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +// Construct and append a MULB instruction to the active function. +// Operates on the global context. +func MULB(mr operand.Op) { ctx.MULB(mr) } + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +// Construct and append a MULL instruction to the active function. +func (c *Context) MULL(mr operand.Op) { + if inst, err := x86.MULL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +// Construct and append a MULL instruction to the active function. +// Operates on the global context. +func MULL(mr operand.Op) { ctx.MULL(mr) } + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +// Construct and append a MULPD instruction to the active function. +func (c *Context) MULPD(mx, x operand.Op) { + if inst, err := x86.MULPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +// Construct and append a MULPD instruction to the active function. +// Operates on the global context. +func MULPD(mx, x operand.Op) { ctx.MULPD(mx, x) } + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +// Construct and append a MULPS instruction to the active function. +func (c *Context) MULPS(mx, x operand.Op) { + if inst, err := x86.MULPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +// Construct and append a MULPS instruction to the active function. +// Operates on the global context. +func MULPS(mx, x operand.Op) { ctx.MULPS(mx, x) } + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +// Construct and append a MULQ instruction to the active function. +func (c *Context) MULQ(mr operand.Op) { + if inst, err := x86.MULQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +// Construct and append a MULQ instruction to the active function. +// Operates on the global context. +func MULQ(mr operand.Op) { ctx.MULQ(mr) } + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +// Construct and append a MULSD instruction to the active function. +func (c *Context) MULSD(mx, x operand.Op) { + if inst, err := x86.MULSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +// Construct and append a MULSD instruction to the active function. +// Operates on the global context. +func MULSD(mx, x operand.Op) { ctx.MULSD(mx, x) } + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +// Construct and append a MULSS instruction to the active function. +func (c *Context) MULSS(mx, x operand.Op) { + if inst, err := x86.MULSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +// Construct and append a MULSS instruction to the active function. +// Operates on the global context. +func MULSS(mx, x operand.Op) { ctx.MULSS(mx, x) } + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +// Construct and append a MULW instruction to the active function. +func (c *Context) MULW(mr operand.Op) { + if inst, err := x86.MULW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +// Construct and append a MULW instruction to the active function. +// Operates on the global context. +func MULW(mr operand.Op) { ctx.MULW(mr) } + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +// Construct and append a MULXL instruction to the active function. +func (c *Context) MULXL(mr, r, r1 operand.Op) { + if inst, err := x86.MULXL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +// Construct and append a MULXL instruction to the active function. +// Operates on the global context. +func MULXL(mr, r, r1 operand.Op) { ctx.MULXL(mr, r, r1) } + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +// Construct and append a MULXQ instruction to the active function. +func (c *Context) MULXQ(mr, r, r1 operand.Op) { + if inst, err := x86.MULXQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +// Construct and append a MULXQ instruction to the active function. +// Operates on the global context. +func MULXQ(mr, r, r1 operand.Op) { ctx.MULXQ(mr, r, r1) } + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +// Construct and append a MWAIT instruction to the active function. +func (c *Context) MWAIT() { + if inst, err := x86.MWAIT(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +// Construct and append a MWAIT instruction to the active function. +// Operates on the global context. +func MWAIT() { ctx.MWAIT() } + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +// Construct and append a NEGB instruction to the active function. +func (c *Context) NEGB(mr operand.Op) { + if inst, err := x86.NEGB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +// Construct and append a NEGB instruction to the active function. +// Operates on the global context. +func NEGB(mr operand.Op) { ctx.NEGB(mr) } + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +// Construct and append a NEGL instruction to the active function. +func (c *Context) NEGL(mr operand.Op) { + if inst, err := x86.NEGL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +// Construct and append a NEGL instruction to the active function. +// Operates on the global context. +func NEGL(mr operand.Op) { ctx.NEGL(mr) } + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +// Construct and append a NEGQ instruction to the active function. +func (c *Context) NEGQ(mr operand.Op) { + if inst, err := x86.NEGQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +// Construct and append a NEGQ instruction to the active function. +// Operates on the global context. +func NEGQ(mr operand.Op) { ctx.NEGQ(mr) } + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +// Construct and append a NEGW instruction to the active function. +func (c *Context) NEGW(mr operand.Op) { + if inst, err := x86.NEGW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +// Construct and append a NEGW instruction to the active function. +// Operates on the global context. +func NEGW(mr operand.Op) { ctx.NEGW(mr) } + +// NOP: No Operation. +// +// Forms: +// +// NOP +// Construct and append a NOP instruction to the active function. +func (c *Context) NOP() { + if inst, err := x86.NOP(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOP: No Operation. +// +// Forms: +// +// NOP +// Construct and append a NOP instruction to the active function. +// Operates on the global context. +func NOP() { ctx.NOP() } + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +// Construct and append a NOTB instruction to the active function. +func (c *Context) NOTB(mr operand.Op) { + if inst, err := x86.NOTB(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +// Construct and append a NOTB instruction to the active function. +// Operates on the global context. +func NOTB(mr operand.Op) { ctx.NOTB(mr) } + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +// Construct and append a NOTL instruction to the active function. +func (c *Context) NOTL(mr operand.Op) { + if inst, err := x86.NOTL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +// Construct and append a NOTL instruction to the active function. +// Operates on the global context. +func NOTL(mr operand.Op) { ctx.NOTL(mr) } + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +// Construct and append a NOTQ instruction to the active function. +func (c *Context) NOTQ(mr operand.Op) { + if inst, err := x86.NOTQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +// Construct and append a NOTQ instruction to the active function. +// Operates on the global context. +func NOTQ(mr operand.Op) { ctx.NOTQ(mr) } + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +// Construct and append a NOTW instruction to the active function. +func (c *Context) NOTW(mr operand.Op) { + if inst, err := x86.NOTW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +// Construct and append a NOTW instruction to the active function. +// Operates on the global context. +func NOTW(mr operand.Op) { ctx.NOTW(mr) } + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +// Construct and append a ORB instruction to the active function. +func (c *Context) ORB(imr, amr operand.Op) { + if inst, err := x86.ORB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +// Construct and append a ORB instruction to the active function. +// Operates on the global context. +func ORB(imr, amr operand.Op) { ctx.ORB(imr, amr) } + +// ORL: Logical Inclusive OR. +// +// Forms: +// +// ORL imm32 eax +// ORL imm8 r32 +// ORL imm32 r32 +// ORL r32 r32 +// ORL m32 r32 +// ORL imm8 m32 +// ORL imm32 m32 +// ORL r32 m32 +// Construct and append a ORL instruction to the active function. +func (c *Context) ORL(imr, emr operand.Op) { + if inst, err := x86.ORL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORL: Logical Inclusive OR. +// +// Forms: +// +// ORL imm32 eax +// ORL imm8 r32 +// ORL imm32 r32 +// ORL r32 r32 +// ORL m32 r32 +// ORL imm8 m32 +// ORL imm32 m32 +// ORL r32 m32 +// Construct and append a ORL instruction to the active function. +// Operates on the global context. +func ORL(imr, emr operand.Op) { ctx.ORL(imr, emr) } + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +// Construct and append a ORPD instruction to the active function. +func (c *Context) ORPD(mx, x operand.Op) { + if inst, err := x86.ORPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +// Construct and append a ORPD instruction to the active function. +// Operates on the global context. +func ORPD(mx, x operand.Op) { ctx.ORPD(mx, x) } + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +// Construct and append a ORPS instruction to the active function. +func (c *Context) ORPS(mx, x operand.Op) { + if inst, err := x86.ORPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +// Construct and append a ORPS instruction to the active function. +// Operates on the global context. +func ORPS(mx, x operand.Op) { ctx.ORPS(mx, x) } + +// ORQ: Logical Inclusive OR. +// +// Forms: +// +// ORQ imm32 rax +// ORQ imm8 r64 +// ORQ imm32 r64 +// ORQ r64 r64 +// ORQ m64 r64 +// ORQ imm8 m64 +// ORQ imm32 m64 +// ORQ r64 m64 +// Construct and append a ORQ instruction to the active function. +func (c *Context) ORQ(imr, mr operand.Op) { + if inst, err := x86.ORQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORQ: Logical Inclusive OR. +// +// Forms: +// +// ORQ imm32 rax +// ORQ imm8 r64 +// ORQ imm32 r64 +// ORQ r64 r64 +// ORQ m64 r64 +// ORQ imm8 m64 +// ORQ imm32 m64 +// ORQ r64 m64 +// Construct and append a ORQ instruction to the active function. +// Operates on the global context. +func ORQ(imr, mr operand.Op) { ctx.ORQ(imr, mr) } + +// ORW: Logical Inclusive OR. +// +// Forms: +// +// ORW imm16 ax +// ORW imm8 r16 +// ORW imm16 r16 +// ORW r16 r16 +// ORW m16 r16 +// ORW imm8 m16 +// ORW imm16 m16 +// ORW r16 m16 +// Construct and append a ORW instruction to the active function. +func (c *Context) ORW(imr, amr operand.Op) { + if inst, err := x86.ORW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ORW: Logical Inclusive OR. +// +// Forms: +// +// ORW imm16 ax +// ORW imm8 r16 +// ORW imm16 r16 +// ORW r16 r16 +// ORW m16 r16 +// ORW imm8 m16 +// ORW imm16 m16 +// ORW r16 m16 +// Construct and append a ORW instruction to the active function. +// Operates on the global context. +func ORW(imr, amr operand.Op) { ctx.ORW(imr, amr) } + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +// Construct and append a PABSB instruction to the active function. +func (c *Context) PABSB(mx, x operand.Op) { + if inst, err := x86.PABSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +// Construct and append a PABSB instruction to the active function. +// Operates on the global context. +func PABSB(mx, x operand.Op) { ctx.PABSB(mx, x) } + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +// Construct and append a PABSD instruction to the active function. +func (c *Context) PABSD(mx, x operand.Op) { + if inst, err := x86.PABSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +// Construct and append a PABSD instruction to the active function. +// Operates on the global context. +func PABSD(mx, x operand.Op) { ctx.PABSD(mx, x) } + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +// Construct and append a PABSW instruction to the active function. +func (c *Context) PABSW(mx, x operand.Op) { + if inst, err := x86.PABSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +// Construct and append a PABSW instruction to the active function. +// Operates on the global context. +func PABSW(mx, x operand.Op) { ctx.PABSW(mx, x) } + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +// Construct and append a PACKSSLW instruction to the active function. +func (c *Context) PACKSSLW(mx, x operand.Op) { + if inst, err := x86.PACKSSLW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +// Construct and append a PACKSSLW instruction to the active function. +// Operates on the global context. +func PACKSSLW(mx, x operand.Op) { ctx.PACKSSLW(mx, x) } + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +// Construct and append a PACKSSWB instruction to the active function. +func (c *Context) PACKSSWB(mx, x operand.Op) { + if inst, err := x86.PACKSSWB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +// Construct and append a PACKSSWB instruction to the active function. +// Operates on the global context. +func PACKSSWB(mx, x operand.Op) { ctx.PACKSSWB(mx, x) } + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +// Construct and append a PACKUSDW instruction to the active function. +func (c *Context) PACKUSDW(mx, x operand.Op) { + if inst, err := x86.PACKUSDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +// Construct and append a PACKUSDW instruction to the active function. +// Operates on the global context. +func PACKUSDW(mx, x operand.Op) { ctx.PACKUSDW(mx, x) } + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +// Construct and append a PACKUSWB instruction to the active function. +func (c *Context) PACKUSWB(mx, x operand.Op) { + if inst, err := x86.PACKUSWB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +// Construct and append a PACKUSWB instruction to the active function. +// Operates on the global context. +func PACKUSWB(mx, x operand.Op) { ctx.PACKUSWB(mx, x) } + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +// Construct and append a PADDB instruction to the active function. +func (c *Context) PADDB(mx, x operand.Op) { + if inst, err := x86.PADDB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +// Construct and append a PADDB instruction to the active function. +// Operates on the global context. +func PADDB(mx, x operand.Op) { ctx.PADDB(mx, x) } + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +// Construct and append a PADDD instruction to the active function. +func (c *Context) PADDD(mx, x operand.Op) { + if inst, err := x86.PADDD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +// Construct and append a PADDD instruction to the active function. +// Operates on the global context. +func PADDD(mx, x operand.Op) { ctx.PADDD(mx, x) } + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +// Construct and append a PADDL instruction to the active function. +func (c *Context) PADDL(mx, x operand.Op) { + if inst, err := x86.PADDL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +// Construct and append a PADDL instruction to the active function. +// Operates on the global context. +func PADDL(mx, x operand.Op) { ctx.PADDL(mx, x) } + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +// Construct and append a PADDQ instruction to the active function. +func (c *Context) PADDQ(mx, x operand.Op) { + if inst, err := x86.PADDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +// Construct and append a PADDQ instruction to the active function. +// Operates on the global context. +func PADDQ(mx, x operand.Op) { ctx.PADDQ(mx, x) } + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +// Construct and append a PADDSB instruction to the active function. +func (c *Context) PADDSB(mx, x operand.Op) { + if inst, err := x86.PADDSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +// Construct and append a PADDSB instruction to the active function. +// Operates on the global context. +func PADDSB(mx, x operand.Op) { ctx.PADDSB(mx, x) } + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +// Construct and append a PADDSW instruction to the active function. +func (c *Context) PADDSW(mx, x operand.Op) { + if inst, err := x86.PADDSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +// Construct and append a PADDSW instruction to the active function. +// Operates on the global context. +func PADDSW(mx, x operand.Op) { ctx.PADDSW(mx, x) } + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +// Construct and append a PADDUSB instruction to the active function. +func (c *Context) PADDUSB(mx, x operand.Op) { + if inst, err := x86.PADDUSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +// Construct and append a PADDUSB instruction to the active function. +// Operates on the global context. +func PADDUSB(mx, x operand.Op) { ctx.PADDUSB(mx, x) } + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +// Construct and append a PADDUSW instruction to the active function. +func (c *Context) PADDUSW(mx, x operand.Op) { + if inst, err := x86.PADDUSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +// Construct and append a PADDUSW instruction to the active function. +// Operates on the global context. +func PADDUSW(mx, x operand.Op) { ctx.PADDUSW(mx, x) } + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +// Construct and append a PADDW instruction to the active function. +func (c *Context) PADDW(mx, x operand.Op) { + if inst, err := x86.PADDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +// Construct and append a PADDW instruction to the active function. +// Operates on the global context. +func PADDW(mx, x operand.Op) { ctx.PADDW(mx, x) } + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +// Construct and append a PALIGNR instruction to the active function. +func (c *Context) PALIGNR(i, mx, x operand.Op) { + if inst, err := x86.PALIGNR(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +// Construct and append a PALIGNR instruction to the active function. +// Operates on the global context. +func PALIGNR(i, mx, x operand.Op) { ctx.PALIGNR(i, mx, x) } + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +// Construct and append a PAND instruction to the active function. +func (c *Context) PAND(mx, x operand.Op) { + if inst, err := x86.PAND(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +// Construct and append a PAND instruction to the active function. +// Operates on the global context. +func PAND(mx, x operand.Op) { ctx.PAND(mx, x) } + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +// Construct and append a PANDN instruction to the active function. +func (c *Context) PANDN(mx, x operand.Op) { + if inst, err := x86.PANDN(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +// Construct and append a PANDN instruction to the active function. +// Operates on the global context. +func PANDN(mx, x operand.Op) { ctx.PANDN(mx, x) } + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +// Construct and append a PAUSE instruction to the active function. +func (c *Context) PAUSE() { + if inst, err := x86.PAUSE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +// Construct and append a PAUSE instruction to the active function. +// Operates on the global context. +func PAUSE() { ctx.PAUSE() } + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +// Construct and append a PAVGB instruction to the active function. +func (c *Context) PAVGB(mx, x operand.Op) { + if inst, err := x86.PAVGB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +// Construct and append a PAVGB instruction to the active function. +// Operates on the global context. +func PAVGB(mx, x operand.Op) { ctx.PAVGB(mx, x) } + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +// Construct and append a PAVGW instruction to the active function. +func (c *Context) PAVGW(mx, x operand.Op) { + if inst, err := x86.PAVGW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +// Construct and append a PAVGW instruction to the active function. +// Operates on the global context. +func PAVGW(mx, x operand.Op) { ctx.PAVGW(mx, x) } + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +// Construct and append a PBLENDVB instruction to the active function. +func (c *Context) PBLENDVB(x, mx, x1 operand.Op) { + if inst, err := x86.PBLENDVB(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +// Construct and append a PBLENDVB instruction to the active function. +// Operates on the global context. +func PBLENDVB(x, mx, x1 operand.Op) { ctx.PBLENDVB(x, mx, x1) } + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +// Construct and append a PBLENDW instruction to the active function. +func (c *Context) PBLENDW(i, mx, x operand.Op) { + if inst, err := x86.PBLENDW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +// Construct and append a PBLENDW instruction to the active function. +// Operates on the global context. +func PBLENDW(i, mx, x operand.Op) { ctx.PBLENDW(i, mx, x) } + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +// Construct and append a PCLMULQDQ instruction to the active function. +func (c *Context) PCLMULQDQ(i, mx, x operand.Op) { + if inst, err := x86.PCLMULQDQ(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +// Construct and append a PCLMULQDQ instruction to the active function. +// Operates on the global context. +func PCLMULQDQ(i, mx, x operand.Op) { ctx.PCLMULQDQ(i, mx, x) } + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +// Construct and append a PCMPEQB instruction to the active function. +func (c *Context) PCMPEQB(mx, x operand.Op) { + if inst, err := x86.PCMPEQB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +// Construct and append a PCMPEQB instruction to the active function. +// Operates on the global context. +func PCMPEQB(mx, x operand.Op) { ctx.PCMPEQB(mx, x) } + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +// Construct and append a PCMPEQL instruction to the active function. +func (c *Context) PCMPEQL(mx, x operand.Op) { + if inst, err := x86.PCMPEQL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +// Construct and append a PCMPEQL instruction to the active function. +// Operates on the global context. +func PCMPEQL(mx, x operand.Op) { ctx.PCMPEQL(mx, x) } + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +// Construct and append a PCMPEQQ instruction to the active function. +func (c *Context) PCMPEQQ(mx, x operand.Op) { + if inst, err := x86.PCMPEQQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +// Construct and append a PCMPEQQ instruction to the active function. +// Operates on the global context. +func PCMPEQQ(mx, x operand.Op) { ctx.PCMPEQQ(mx, x) } + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +// Construct and append a PCMPEQW instruction to the active function. +func (c *Context) PCMPEQW(mx, x operand.Op) { + if inst, err := x86.PCMPEQW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +// Construct and append a PCMPEQW instruction to the active function. +// Operates on the global context. +func PCMPEQW(mx, x operand.Op) { ctx.PCMPEQW(mx, x) } + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +// Construct and append a PCMPESTRI instruction to the active function. +func (c *Context) PCMPESTRI(i, mx, x operand.Op) { + if inst, err := x86.PCMPESTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +// Construct and append a PCMPESTRI instruction to the active function. +// Operates on the global context. +func PCMPESTRI(i, mx, x operand.Op) { ctx.PCMPESTRI(i, mx, x) } + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +// Construct and append a PCMPESTRM instruction to the active function. +func (c *Context) PCMPESTRM(i, mx, x operand.Op) { + if inst, err := x86.PCMPESTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +// Construct and append a PCMPESTRM instruction to the active function. +// Operates on the global context. +func PCMPESTRM(i, mx, x operand.Op) { ctx.PCMPESTRM(i, mx, x) } + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +// Construct and append a PCMPGTB instruction to the active function. +func (c *Context) PCMPGTB(mx, x operand.Op) { + if inst, err := x86.PCMPGTB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +// Construct and append a PCMPGTB instruction to the active function. +// Operates on the global context. +func PCMPGTB(mx, x operand.Op) { ctx.PCMPGTB(mx, x) } + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +// Construct and append a PCMPGTL instruction to the active function. +func (c *Context) PCMPGTL(mx, x operand.Op) { + if inst, err := x86.PCMPGTL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +// Construct and append a PCMPGTL instruction to the active function. +// Operates on the global context. +func PCMPGTL(mx, x operand.Op) { ctx.PCMPGTL(mx, x) } + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +// Construct and append a PCMPGTQ instruction to the active function. +func (c *Context) PCMPGTQ(mx, x operand.Op) { + if inst, err := x86.PCMPGTQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +// Construct and append a PCMPGTQ instruction to the active function. +// Operates on the global context. +func PCMPGTQ(mx, x operand.Op) { ctx.PCMPGTQ(mx, x) } + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +// Construct and append a PCMPGTW instruction to the active function. +func (c *Context) PCMPGTW(mx, x operand.Op) { + if inst, err := x86.PCMPGTW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +// Construct and append a PCMPGTW instruction to the active function. +// Operates on the global context. +func PCMPGTW(mx, x operand.Op) { ctx.PCMPGTW(mx, x) } + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +// Construct and append a PCMPISTRI instruction to the active function. +func (c *Context) PCMPISTRI(i, mx, x operand.Op) { + if inst, err := x86.PCMPISTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +// Construct and append a PCMPISTRI instruction to the active function. +// Operates on the global context. +func PCMPISTRI(i, mx, x operand.Op) { ctx.PCMPISTRI(i, mx, x) } + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +// Construct and append a PCMPISTRM instruction to the active function. +func (c *Context) PCMPISTRM(i, mx, x operand.Op) { + if inst, err := x86.PCMPISTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +// Construct and append a PCMPISTRM instruction to the active function. +// Operates on the global context. +func PCMPISTRM(i, mx, x operand.Op) { ctx.PCMPISTRM(i, mx, x) } + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +// Construct and append a PDEPL instruction to the active function. +func (c *Context) PDEPL(mr, r, r1 operand.Op) { + if inst, err := x86.PDEPL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +// Construct and append a PDEPL instruction to the active function. +// Operates on the global context. +func PDEPL(mr, r, r1 operand.Op) { ctx.PDEPL(mr, r, r1) } + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +// Construct and append a PDEPQ instruction to the active function. +func (c *Context) PDEPQ(mr, r, r1 operand.Op) { + if inst, err := x86.PDEPQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +// Construct and append a PDEPQ instruction to the active function. +// Operates on the global context. +func PDEPQ(mr, r, r1 operand.Op) { ctx.PDEPQ(mr, r, r1) } + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +// Construct and append a PEXTL instruction to the active function. +func (c *Context) PEXTL(mr, r, r1 operand.Op) { + if inst, err := x86.PEXTL(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +// Construct and append a PEXTL instruction to the active function. +// Operates on the global context. +func PEXTL(mr, r, r1 operand.Op) { ctx.PEXTL(mr, r, r1) } + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +// Construct and append a PEXTQ instruction to the active function. +func (c *Context) PEXTQ(mr, r, r1 operand.Op) { + if inst, err := x86.PEXTQ(mr, r, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +// Construct and append a PEXTQ instruction to the active function. +// Operates on the global context. +func PEXTQ(mr, r, r1 operand.Op) { ctx.PEXTQ(mr, r, r1) } + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +// Construct and append a PEXTRB instruction to the active function. +func (c *Context) PEXTRB(i, x, mr operand.Op) { + if inst, err := x86.PEXTRB(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +// Construct and append a PEXTRB instruction to the active function. +// Operates on the global context. +func PEXTRB(i, x, mr operand.Op) { ctx.PEXTRB(i, x, mr) } + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +// Construct and append a PEXTRD instruction to the active function. +func (c *Context) PEXTRD(i, x, mr operand.Op) { + if inst, err := x86.PEXTRD(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +// Construct and append a PEXTRD instruction to the active function. +// Operates on the global context. +func PEXTRD(i, x, mr operand.Op) { ctx.PEXTRD(i, x, mr) } + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +// Construct and append a PEXTRQ instruction to the active function. +func (c *Context) PEXTRQ(i, x, mr operand.Op) { + if inst, err := x86.PEXTRQ(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +// Construct and append a PEXTRQ instruction to the active function. +// Operates on the global context. +func PEXTRQ(i, x, mr operand.Op) { ctx.PEXTRQ(i, x, mr) } + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +// Construct and append a PEXTRW instruction to the active function. +func (c *Context) PEXTRW(i, x, mr operand.Op) { + if inst, err := x86.PEXTRW(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +// Construct and append a PEXTRW instruction to the active function. +// Operates on the global context. +func PEXTRW(i, x, mr operand.Op) { ctx.PEXTRW(i, x, mr) } + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +// Construct and append a PHADDD instruction to the active function. +func (c *Context) PHADDD(mx, x operand.Op) { + if inst, err := x86.PHADDD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +// Construct and append a PHADDD instruction to the active function. +// Operates on the global context. +func PHADDD(mx, x operand.Op) { ctx.PHADDD(mx, x) } + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +// Construct and append a PHADDSW instruction to the active function. +func (c *Context) PHADDSW(mx, x operand.Op) { + if inst, err := x86.PHADDSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +// Construct and append a PHADDSW instruction to the active function. +// Operates on the global context. +func PHADDSW(mx, x operand.Op) { ctx.PHADDSW(mx, x) } + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +// Construct and append a PHADDW instruction to the active function. +func (c *Context) PHADDW(mx, x operand.Op) { + if inst, err := x86.PHADDW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +// Construct and append a PHADDW instruction to the active function. +// Operates on the global context. +func PHADDW(mx, x operand.Op) { ctx.PHADDW(mx, x) } + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +// Construct and append a PHMINPOSUW instruction to the active function. +func (c *Context) PHMINPOSUW(mx, x operand.Op) { + if inst, err := x86.PHMINPOSUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +// Construct and append a PHMINPOSUW instruction to the active function. +// Operates on the global context. +func PHMINPOSUW(mx, x operand.Op) { ctx.PHMINPOSUW(mx, x) } + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +// Construct and append a PHSUBD instruction to the active function. +func (c *Context) PHSUBD(mx, x operand.Op) { + if inst, err := x86.PHSUBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +// Construct and append a PHSUBD instruction to the active function. +// Operates on the global context. +func PHSUBD(mx, x operand.Op) { ctx.PHSUBD(mx, x) } + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +// Construct and append a PHSUBSW instruction to the active function. +func (c *Context) PHSUBSW(mx, x operand.Op) { + if inst, err := x86.PHSUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +// Construct and append a PHSUBSW instruction to the active function. +// Operates on the global context. +func PHSUBSW(mx, x operand.Op) { ctx.PHSUBSW(mx, x) } + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +// Construct and append a PHSUBW instruction to the active function. +func (c *Context) PHSUBW(mx, x operand.Op) { + if inst, err := x86.PHSUBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +// Construct and append a PHSUBW instruction to the active function. +// Operates on the global context. +func PHSUBW(mx, x operand.Op) { ctx.PHSUBW(mx, x) } + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +// Construct and append a PINSRB instruction to the active function. +func (c *Context) PINSRB(i, mr, x operand.Op) { + if inst, err := x86.PINSRB(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +// Construct and append a PINSRB instruction to the active function. +// Operates on the global context. +func PINSRB(i, mr, x operand.Op) { ctx.PINSRB(i, mr, x) } + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +// Construct and append a PINSRD instruction to the active function. +func (c *Context) PINSRD(i, mr, x operand.Op) { + if inst, err := x86.PINSRD(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +// Construct and append a PINSRD instruction to the active function. +// Operates on the global context. +func PINSRD(i, mr, x operand.Op) { ctx.PINSRD(i, mr, x) } + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +// Construct and append a PINSRQ instruction to the active function. +func (c *Context) PINSRQ(i, mr, x operand.Op) { + if inst, err := x86.PINSRQ(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +// Construct and append a PINSRQ instruction to the active function. +// Operates on the global context. +func PINSRQ(i, mr, x operand.Op) { ctx.PINSRQ(i, mr, x) } + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +// Construct and append a PINSRW instruction to the active function. +func (c *Context) PINSRW(i, mr, x operand.Op) { + if inst, err := x86.PINSRW(i, mr, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +// Construct and append a PINSRW instruction to the active function. +// Operates on the global context. +func PINSRW(i, mr, x operand.Op) { ctx.PINSRW(i, mr, x) } + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +// Construct and append a PMADDUBSW instruction to the active function. +func (c *Context) PMADDUBSW(mx, x operand.Op) { + if inst, err := x86.PMADDUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +// Construct and append a PMADDUBSW instruction to the active function. +// Operates on the global context. +func PMADDUBSW(mx, x operand.Op) { ctx.PMADDUBSW(mx, x) } + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +// Construct and append a PMADDWL instruction to the active function. +func (c *Context) PMADDWL(mx, x operand.Op) { + if inst, err := x86.PMADDWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +// Construct and append a PMADDWL instruction to the active function. +// Operates on the global context. +func PMADDWL(mx, x operand.Op) { ctx.PMADDWL(mx, x) } + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +// Construct and append a PMAXSB instruction to the active function. +func (c *Context) PMAXSB(mx, x operand.Op) { + if inst, err := x86.PMAXSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +// Construct and append a PMAXSB instruction to the active function. +// Operates on the global context. +func PMAXSB(mx, x operand.Op) { ctx.PMAXSB(mx, x) } + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +// Construct and append a PMAXSD instruction to the active function. +func (c *Context) PMAXSD(mx, x operand.Op) { + if inst, err := x86.PMAXSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +// Construct and append a PMAXSD instruction to the active function. +// Operates on the global context. +func PMAXSD(mx, x operand.Op) { ctx.PMAXSD(mx, x) } + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +// Construct and append a PMAXSW instruction to the active function. +func (c *Context) PMAXSW(mx, x operand.Op) { + if inst, err := x86.PMAXSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +// Construct and append a PMAXSW instruction to the active function. +// Operates on the global context. +func PMAXSW(mx, x operand.Op) { ctx.PMAXSW(mx, x) } + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +// Construct and append a PMAXUB instruction to the active function. +func (c *Context) PMAXUB(mx, x operand.Op) { + if inst, err := x86.PMAXUB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +// Construct and append a PMAXUB instruction to the active function. +// Operates on the global context. +func PMAXUB(mx, x operand.Op) { ctx.PMAXUB(mx, x) } + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +// Construct and append a PMAXUD instruction to the active function. +func (c *Context) PMAXUD(mx, x operand.Op) { + if inst, err := x86.PMAXUD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +// Construct and append a PMAXUD instruction to the active function. +// Operates on the global context. +func PMAXUD(mx, x operand.Op) { ctx.PMAXUD(mx, x) } + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +// Construct and append a PMAXUW instruction to the active function. +func (c *Context) PMAXUW(mx, x operand.Op) { + if inst, err := x86.PMAXUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +// Construct and append a PMAXUW instruction to the active function. +// Operates on the global context. +func PMAXUW(mx, x operand.Op) { ctx.PMAXUW(mx, x) } + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +// Construct and append a PMINSB instruction to the active function. +func (c *Context) PMINSB(mx, x operand.Op) { + if inst, err := x86.PMINSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +// Construct and append a PMINSB instruction to the active function. +// Operates on the global context. +func PMINSB(mx, x operand.Op) { ctx.PMINSB(mx, x) } + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +// Construct and append a PMINSD instruction to the active function. +func (c *Context) PMINSD(mx, x operand.Op) { + if inst, err := x86.PMINSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +// Construct and append a PMINSD instruction to the active function. +// Operates on the global context. +func PMINSD(mx, x operand.Op) { ctx.PMINSD(mx, x) } + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +// Construct and append a PMINSW instruction to the active function. +func (c *Context) PMINSW(mx, x operand.Op) { + if inst, err := x86.PMINSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +// Construct and append a PMINSW instruction to the active function. +// Operates on the global context. +func PMINSW(mx, x operand.Op) { ctx.PMINSW(mx, x) } + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +// Construct and append a PMINUB instruction to the active function. +func (c *Context) PMINUB(mx, x operand.Op) { + if inst, err := x86.PMINUB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +// Construct and append a PMINUB instruction to the active function. +// Operates on the global context. +func PMINUB(mx, x operand.Op) { ctx.PMINUB(mx, x) } + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +// Construct and append a PMINUD instruction to the active function. +func (c *Context) PMINUD(mx, x operand.Op) { + if inst, err := x86.PMINUD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +// Construct and append a PMINUD instruction to the active function. +// Operates on the global context. +func PMINUD(mx, x operand.Op) { ctx.PMINUD(mx, x) } + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +// Construct and append a PMINUW instruction to the active function. +func (c *Context) PMINUW(mx, x operand.Op) { + if inst, err := x86.PMINUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +// Construct and append a PMINUW instruction to the active function. +// Operates on the global context. +func PMINUW(mx, x operand.Op) { ctx.PMINUW(mx, x) } + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +// Construct and append a PMOVMSKB instruction to the active function. +func (c *Context) PMOVMSKB(x, r operand.Op) { + if inst, err := x86.PMOVMSKB(x, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +// Construct and append a PMOVMSKB instruction to the active function. +// Operates on the global context. +func PMOVMSKB(x, r operand.Op) { ctx.PMOVMSKB(x, r) } + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +// Construct and append a PMOVSXBD instruction to the active function. +func (c *Context) PMOVSXBD(mx, x operand.Op) { + if inst, err := x86.PMOVSXBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +// Construct and append a PMOVSXBD instruction to the active function. +// Operates on the global context. +func PMOVSXBD(mx, x operand.Op) { ctx.PMOVSXBD(mx, x) } + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +// Construct and append a PMOVSXBQ instruction to the active function. +func (c *Context) PMOVSXBQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +// Construct and append a PMOVSXBQ instruction to the active function. +// Operates on the global context. +func PMOVSXBQ(mx, x operand.Op) { ctx.PMOVSXBQ(mx, x) } + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +// Construct and append a PMOVSXBW instruction to the active function. +func (c *Context) PMOVSXBW(mx, x operand.Op) { + if inst, err := x86.PMOVSXBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +// Construct and append a PMOVSXBW instruction to the active function. +// Operates on the global context. +func PMOVSXBW(mx, x operand.Op) { ctx.PMOVSXBW(mx, x) } + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +// Construct and append a PMOVSXDQ instruction to the active function. +func (c *Context) PMOVSXDQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +// Construct and append a PMOVSXDQ instruction to the active function. +// Operates on the global context. +func PMOVSXDQ(mx, x operand.Op) { ctx.PMOVSXDQ(mx, x) } + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +// Construct and append a PMOVSXWD instruction to the active function. +func (c *Context) PMOVSXWD(mx, x operand.Op) { + if inst, err := x86.PMOVSXWD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +// Construct and append a PMOVSXWD instruction to the active function. +// Operates on the global context. +func PMOVSXWD(mx, x operand.Op) { ctx.PMOVSXWD(mx, x) } + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +// Construct and append a PMOVSXWQ instruction to the active function. +func (c *Context) PMOVSXWQ(mx, x operand.Op) { + if inst, err := x86.PMOVSXWQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +// Construct and append a PMOVSXWQ instruction to the active function. +// Operates on the global context. +func PMOVSXWQ(mx, x operand.Op) { ctx.PMOVSXWQ(mx, x) } + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +// Construct and append a PMOVZXBD instruction to the active function. +func (c *Context) PMOVZXBD(mx, x operand.Op) { + if inst, err := x86.PMOVZXBD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +// Construct and append a PMOVZXBD instruction to the active function. +// Operates on the global context. +func PMOVZXBD(mx, x operand.Op) { ctx.PMOVZXBD(mx, x) } + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +// Construct and append a PMOVZXBQ instruction to the active function. +func (c *Context) PMOVZXBQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +// Construct and append a PMOVZXBQ instruction to the active function. +// Operates on the global context. +func PMOVZXBQ(mx, x operand.Op) { ctx.PMOVZXBQ(mx, x) } + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +// Construct and append a PMOVZXBW instruction to the active function. +func (c *Context) PMOVZXBW(mx, x operand.Op) { + if inst, err := x86.PMOVZXBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +// Construct and append a PMOVZXBW instruction to the active function. +// Operates on the global context. +func PMOVZXBW(mx, x operand.Op) { ctx.PMOVZXBW(mx, x) } + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +// Construct and append a PMOVZXDQ instruction to the active function. +func (c *Context) PMOVZXDQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +// Construct and append a PMOVZXDQ instruction to the active function. +// Operates on the global context. +func PMOVZXDQ(mx, x operand.Op) { ctx.PMOVZXDQ(mx, x) } + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +// Construct and append a PMOVZXWD instruction to the active function. +func (c *Context) PMOVZXWD(mx, x operand.Op) { + if inst, err := x86.PMOVZXWD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +// Construct and append a PMOVZXWD instruction to the active function. +// Operates on the global context. +func PMOVZXWD(mx, x operand.Op) { ctx.PMOVZXWD(mx, x) } + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +// Construct and append a PMOVZXWQ instruction to the active function. +func (c *Context) PMOVZXWQ(mx, x operand.Op) { + if inst, err := x86.PMOVZXWQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +// Construct and append a PMOVZXWQ instruction to the active function. +// Operates on the global context. +func PMOVZXWQ(mx, x operand.Op) { ctx.PMOVZXWQ(mx, x) } + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +// Construct and append a PMULDQ instruction to the active function. +func (c *Context) PMULDQ(mx, x operand.Op) { + if inst, err := x86.PMULDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +// Construct and append a PMULDQ instruction to the active function. +// Operates on the global context. +func PMULDQ(mx, x operand.Op) { ctx.PMULDQ(mx, x) } + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +// Construct and append a PMULHRSW instruction to the active function. +func (c *Context) PMULHRSW(mx, x operand.Op) { + if inst, err := x86.PMULHRSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +// Construct and append a PMULHRSW instruction to the active function. +// Operates on the global context. +func PMULHRSW(mx, x operand.Op) { ctx.PMULHRSW(mx, x) } + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +// Construct and append a PMULHUW instruction to the active function. +func (c *Context) PMULHUW(mx, x operand.Op) { + if inst, err := x86.PMULHUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +// Construct and append a PMULHUW instruction to the active function. +// Operates on the global context. +func PMULHUW(mx, x operand.Op) { ctx.PMULHUW(mx, x) } + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +// Construct and append a PMULHW instruction to the active function. +func (c *Context) PMULHW(mx, x operand.Op) { + if inst, err := x86.PMULHW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +// Construct and append a PMULHW instruction to the active function. +// Operates on the global context. +func PMULHW(mx, x operand.Op) { ctx.PMULHW(mx, x) } + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +// Construct and append a PMULLD instruction to the active function. +func (c *Context) PMULLD(mx, x operand.Op) { + if inst, err := x86.PMULLD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +// Construct and append a PMULLD instruction to the active function. +// Operates on the global context. +func PMULLD(mx, x operand.Op) { ctx.PMULLD(mx, x) } + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +// Construct and append a PMULLW instruction to the active function. +func (c *Context) PMULLW(mx, x operand.Op) { + if inst, err := x86.PMULLW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +// Construct and append a PMULLW instruction to the active function. +// Operates on the global context. +func PMULLW(mx, x operand.Op) { ctx.PMULLW(mx, x) } + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +// Construct and append a PMULULQ instruction to the active function. +func (c *Context) PMULULQ(mx, x operand.Op) { + if inst, err := x86.PMULULQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +// Construct and append a PMULULQ instruction to the active function. +// Operates on the global context. +func PMULULQ(mx, x operand.Op) { ctx.PMULULQ(mx, x) } + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +// Construct and append a POPCNTL instruction to the active function. +func (c *Context) POPCNTL(mr, r operand.Op) { + if inst, err := x86.POPCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +// Construct and append a POPCNTL instruction to the active function. +// Operates on the global context. +func POPCNTL(mr, r operand.Op) { ctx.POPCNTL(mr, r) } + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +// Construct and append a POPCNTQ instruction to the active function. +func (c *Context) POPCNTQ(mr, r operand.Op) { + if inst, err := x86.POPCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +// Construct and append a POPCNTQ instruction to the active function. +// Operates on the global context. +func POPCNTQ(mr, r operand.Op) { ctx.POPCNTQ(mr, r) } + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +// Construct and append a POPCNTW instruction to the active function. +func (c *Context) POPCNTW(mr, r operand.Op) { + if inst, err := x86.POPCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +// Construct and append a POPCNTW instruction to the active function. +// Operates on the global context. +func POPCNTW(mr, r operand.Op) { ctx.POPCNTW(mr, r) } + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +// Construct and append a POPQ instruction to the active function. +func (c *Context) POPQ(mr operand.Op) { + if inst, err := x86.POPQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +// Construct and append a POPQ instruction to the active function. +// Operates on the global context. +func POPQ(mr operand.Op) { ctx.POPQ(mr) } + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +// Construct and append a POPW instruction to the active function. +func (c *Context) POPW(mr operand.Op) { + if inst, err := x86.POPW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +// Construct and append a POPW instruction to the active function. +// Operates on the global context. +func POPW(mr operand.Op) { ctx.POPW(mr) } + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +// Construct and append a POR instruction to the active function. +func (c *Context) POR(mx, x operand.Op) { + if inst, err := x86.POR(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +// Construct and append a POR instruction to the active function. +// Operates on the global context. +func POR(mx, x operand.Op) { ctx.POR(mx, x) } + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +// Construct and append a PREFETCHNTA instruction to the active function. +func (c *Context) PREFETCHNTA(m operand.Op) { + if inst, err := x86.PREFETCHNTA(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +// Construct and append a PREFETCHNTA instruction to the active function. +// Operates on the global context. +func PREFETCHNTA(m operand.Op) { ctx.PREFETCHNTA(m) } + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +// Construct and append a PREFETCHT0 instruction to the active function. +func (c *Context) PREFETCHT0(m operand.Op) { + if inst, err := x86.PREFETCHT0(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +// Construct and append a PREFETCHT0 instruction to the active function. +// Operates on the global context. +func PREFETCHT0(m operand.Op) { ctx.PREFETCHT0(m) } + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +// Construct and append a PREFETCHT1 instruction to the active function. +func (c *Context) PREFETCHT1(m operand.Op) { + if inst, err := x86.PREFETCHT1(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +// Construct and append a PREFETCHT1 instruction to the active function. +// Operates on the global context. +func PREFETCHT1(m operand.Op) { ctx.PREFETCHT1(m) } + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +// Construct and append a PREFETCHT2 instruction to the active function. +func (c *Context) PREFETCHT2(m operand.Op) { + if inst, err := x86.PREFETCHT2(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +// Construct and append a PREFETCHT2 instruction to the active function. +// Operates on the global context. +func PREFETCHT2(m operand.Op) { ctx.PREFETCHT2(m) } + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +// Construct and append a PSADBW instruction to the active function. +func (c *Context) PSADBW(mx, x operand.Op) { + if inst, err := x86.PSADBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +// Construct and append a PSADBW instruction to the active function. +// Operates on the global context. +func PSADBW(mx, x operand.Op) { ctx.PSADBW(mx, x) } + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +// Construct and append a PSHUFB instruction to the active function. +func (c *Context) PSHUFB(mx, x operand.Op) { + if inst, err := x86.PSHUFB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +// Construct and append a PSHUFB instruction to the active function. +// Operates on the global context. +func PSHUFB(mx, x operand.Op) { ctx.PSHUFB(mx, x) } + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +// Construct and append a PSHUFD instruction to the active function. +func (c *Context) PSHUFD(i, mx, x operand.Op) { + if inst, err := x86.PSHUFD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +// Construct and append a PSHUFD instruction to the active function. +// Operates on the global context. +func PSHUFD(i, mx, x operand.Op) { ctx.PSHUFD(i, mx, x) } + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +// Construct and append a PSHUFHW instruction to the active function. +func (c *Context) PSHUFHW(i, mx, x operand.Op) { + if inst, err := x86.PSHUFHW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +// Construct and append a PSHUFHW instruction to the active function. +// Operates on the global context. +func PSHUFHW(i, mx, x operand.Op) { ctx.PSHUFHW(i, mx, x) } + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +// Construct and append a PSHUFL instruction to the active function. +func (c *Context) PSHUFL(i, mx, x operand.Op) { + if inst, err := x86.PSHUFL(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +// Construct and append a PSHUFL instruction to the active function. +// Operates on the global context. +func PSHUFL(i, mx, x operand.Op) { ctx.PSHUFL(i, mx, x) } + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +// Construct and append a PSHUFLW instruction to the active function. +func (c *Context) PSHUFLW(i, mx, x operand.Op) { + if inst, err := x86.PSHUFLW(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +// Construct and append a PSHUFLW instruction to the active function. +// Operates on the global context. +func PSHUFLW(i, mx, x operand.Op) { ctx.PSHUFLW(i, mx, x) } + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +// Construct and append a PSIGNB instruction to the active function. +func (c *Context) PSIGNB(mx, x operand.Op) { + if inst, err := x86.PSIGNB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +// Construct and append a PSIGNB instruction to the active function. +// Operates on the global context. +func PSIGNB(mx, x operand.Op) { ctx.PSIGNB(mx, x) } + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +// Construct and append a PSIGND instruction to the active function. +func (c *Context) PSIGND(mx, x operand.Op) { + if inst, err := x86.PSIGND(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +// Construct and append a PSIGND instruction to the active function. +// Operates on the global context. +func PSIGND(mx, x operand.Op) { ctx.PSIGND(mx, x) } + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +// Construct and append a PSIGNW instruction to the active function. +func (c *Context) PSIGNW(mx, x operand.Op) { + if inst, err := x86.PSIGNW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +// Construct and append a PSIGNW instruction to the active function. +// Operates on the global context. +func PSIGNW(mx, x operand.Op) { ctx.PSIGNW(mx, x) } + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +// Construct and append a PSLLDQ instruction to the active function. +func (c *Context) PSLLDQ(i, x operand.Op) { + if inst, err := x86.PSLLDQ(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +// Construct and append a PSLLDQ instruction to the active function. +// Operates on the global context. +func PSLLDQ(i, x operand.Op) { ctx.PSLLDQ(i, x) } + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +// Construct and append a PSLLL instruction to the active function. +func (c *Context) PSLLL(imx, x operand.Op) { + if inst, err := x86.PSLLL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +// Construct and append a PSLLL instruction to the active function. +// Operates on the global context. +func PSLLL(imx, x operand.Op) { ctx.PSLLL(imx, x) } + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +// Construct and append a PSLLO instruction to the active function. +func (c *Context) PSLLO(i, x operand.Op) { + if inst, err := x86.PSLLO(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +// Construct and append a PSLLO instruction to the active function. +// Operates on the global context. +func PSLLO(i, x operand.Op) { ctx.PSLLO(i, x) } + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +// Construct and append a PSLLQ instruction to the active function. +func (c *Context) PSLLQ(imx, x operand.Op) { + if inst, err := x86.PSLLQ(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +// Construct and append a PSLLQ instruction to the active function. +// Operates on the global context. +func PSLLQ(imx, x operand.Op) { ctx.PSLLQ(imx, x) } + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +// Construct and append a PSLLW instruction to the active function. +func (c *Context) PSLLW(imx, x operand.Op) { + if inst, err := x86.PSLLW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +// Construct and append a PSLLW instruction to the active function. +// Operates on the global context. +func PSLLW(imx, x operand.Op) { ctx.PSLLW(imx, x) } + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +// Construct and append a PSRAL instruction to the active function. +func (c *Context) PSRAL(imx, x operand.Op) { + if inst, err := x86.PSRAL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +// Construct and append a PSRAL instruction to the active function. +// Operates on the global context. +func PSRAL(imx, x operand.Op) { ctx.PSRAL(imx, x) } + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +// Construct and append a PSRAW instruction to the active function. +func (c *Context) PSRAW(imx, x operand.Op) { + if inst, err := x86.PSRAW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +// Construct and append a PSRAW instruction to the active function. +// Operates on the global context. +func PSRAW(imx, x operand.Op) { ctx.PSRAW(imx, x) } + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +// Construct and append a PSRLDQ instruction to the active function. +func (c *Context) PSRLDQ(i, x operand.Op) { + if inst, err := x86.PSRLDQ(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +// Construct and append a PSRLDQ instruction to the active function. +// Operates on the global context. +func PSRLDQ(i, x operand.Op) { ctx.PSRLDQ(i, x) } + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +// Construct and append a PSRLL instruction to the active function. +func (c *Context) PSRLL(imx, x operand.Op) { + if inst, err := x86.PSRLL(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +// Construct and append a PSRLL instruction to the active function. +// Operates on the global context. +func PSRLL(imx, x operand.Op) { ctx.PSRLL(imx, x) } + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +// Construct and append a PSRLO instruction to the active function. +func (c *Context) PSRLO(i, x operand.Op) { + if inst, err := x86.PSRLO(i, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +// Construct and append a PSRLO instruction to the active function. +// Operates on the global context. +func PSRLO(i, x operand.Op) { ctx.PSRLO(i, x) } + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +// Construct and append a PSRLQ instruction to the active function. +func (c *Context) PSRLQ(imx, x operand.Op) { + if inst, err := x86.PSRLQ(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +// Construct and append a PSRLQ instruction to the active function. +// Operates on the global context. +func PSRLQ(imx, x operand.Op) { ctx.PSRLQ(imx, x) } + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +// Construct and append a PSRLW instruction to the active function. +func (c *Context) PSRLW(imx, x operand.Op) { + if inst, err := x86.PSRLW(imx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +// Construct and append a PSRLW instruction to the active function. +// Operates on the global context. +func PSRLW(imx, x operand.Op) { ctx.PSRLW(imx, x) } + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +// Construct and append a PSUBB instruction to the active function. +func (c *Context) PSUBB(mx, x operand.Op) { + if inst, err := x86.PSUBB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +// Construct and append a PSUBB instruction to the active function. +// Operates on the global context. +func PSUBB(mx, x operand.Op) { ctx.PSUBB(mx, x) } + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +// Construct and append a PSUBL instruction to the active function. +func (c *Context) PSUBL(mx, x operand.Op) { + if inst, err := x86.PSUBL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +// Construct and append a PSUBL instruction to the active function. +// Operates on the global context. +func PSUBL(mx, x operand.Op) { ctx.PSUBL(mx, x) } + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +// Construct and append a PSUBQ instruction to the active function. +func (c *Context) PSUBQ(mx, x operand.Op) { + if inst, err := x86.PSUBQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +// Construct and append a PSUBQ instruction to the active function. +// Operates on the global context. +func PSUBQ(mx, x operand.Op) { ctx.PSUBQ(mx, x) } + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +// Construct and append a PSUBSB instruction to the active function. +func (c *Context) PSUBSB(mx, x operand.Op) { + if inst, err := x86.PSUBSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +// Construct and append a PSUBSB instruction to the active function. +// Operates on the global context. +func PSUBSB(mx, x operand.Op) { ctx.PSUBSB(mx, x) } + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +// Construct and append a PSUBSW instruction to the active function. +func (c *Context) PSUBSW(mx, x operand.Op) { + if inst, err := x86.PSUBSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +// Construct and append a PSUBSW instruction to the active function. +// Operates on the global context. +func PSUBSW(mx, x operand.Op) { ctx.PSUBSW(mx, x) } + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +// Construct and append a PSUBUSB instruction to the active function. +func (c *Context) PSUBUSB(mx, x operand.Op) { + if inst, err := x86.PSUBUSB(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +// Construct and append a PSUBUSB instruction to the active function. +// Operates on the global context. +func PSUBUSB(mx, x operand.Op) { ctx.PSUBUSB(mx, x) } + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +// Construct and append a PSUBUSW instruction to the active function. +func (c *Context) PSUBUSW(mx, x operand.Op) { + if inst, err := x86.PSUBUSW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +// Construct and append a PSUBUSW instruction to the active function. +// Operates on the global context. +func PSUBUSW(mx, x operand.Op) { ctx.PSUBUSW(mx, x) } + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +// Construct and append a PSUBW instruction to the active function. +func (c *Context) PSUBW(mx, x operand.Op) { + if inst, err := x86.PSUBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +// Construct and append a PSUBW instruction to the active function. +// Operates on the global context. +func PSUBW(mx, x operand.Op) { ctx.PSUBW(mx, x) } + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +// Construct and append a PTEST instruction to the active function. +func (c *Context) PTEST(mx, x operand.Op) { + if inst, err := x86.PTEST(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +// Construct and append a PTEST instruction to the active function. +// Operates on the global context. +func PTEST(mx, x operand.Op) { ctx.PTEST(mx, x) } + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +// Construct and append a PUNPCKHBW instruction to the active function. +func (c *Context) PUNPCKHBW(mx, x operand.Op) { + if inst, err := x86.PUNPCKHBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +// Construct and append a PUNPCKHBW instruction to the active function. +// Operates on the global context. +func PUNPCKHBW(mx, x operand.Op) { ctx.PUNPCKHBW(mx, x) } + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +// Construct and append a PUNPCKHLQ instruction to the active function. +func (c *Context) PUNPCKHLQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKHLQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +// Construct and append a PUNPCKHLQ instruction to the active function. +// Operates on the global context. +func PUNPCKHLQ(mx, x operand.Op) { ctx.PUNPCKHLQ(mx, x) } + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +// Construct and append a PUNPCKHQDQ instruction to the active function. +func (c *Context) PUNPCKHQDQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKHQDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +// Construct and append a PUNPCKHQDQ instruction to the active function. +// Operates on the global context. +func PUNPCKHQDQ(mx, x operand.Op) { ctx.PUNPCKHQDQ(mx, x) } + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +// Construct and append a PUNPCKHWL instruction to the active function. +func (c *Context) PUNPCKHWL(mx, x operand.Op) { + if inst, err := x86.PUNPCKHWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +// Construct and append a PUNPCKHWL instruction to the active function. +// Operates on the global context. +func PUNPCKHWL(mx, x operand.Op) { ctx.PUNPCKHWL(mx, x) } + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +// Construct and append a PUNPCKLBW instruction to the active function. +func (c *Context) PUNPCKLBW(mx, x operand.Op) { + if inst, err := x86.PUNPCKLBW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +// Construct and append a PUNPCKLBW instruction to the active function. +// Operates on the global context. +func PUNPCKLBW(mx, x operand.Op) { ctx.PUNPCKLBW(mx, x) } + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +// Construct and append a PUNPCKLLQ instruction to the active function. +func (c *Context) PUNPCKLLQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKLLQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +// Construct and append a PUNPCKLLQ instruction to the active function. +// Operates on the global context. +func PUNPCKLLQ(mx, x operand.Op) { ctx.PUNPCKLLQ(mx, x) } + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +// Construct and append a PUNPCKLQDQ instruction to the active function. +func (c *Context) PUNPCKLQDQ(mx, x operand.Op) { + if inst, err := x86.PUNPCKLQDQ(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +// Construct and append a PUNPCKLQDQ instruction to the active function. +// Operates on the global context. +func PUNPCKLQDQ(mx, x operand.Op) { ctx.PUNPCKLQDQ(mx, x) } + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +// Construct and append a PUNPCKLWL instruction to the active function. +func (c *Context) PUNPCKLWL(mx, x operand.Op) { + if inst, err := x86.PUNPCKLWL(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +// Construct and append a PUNPCKLWL instruction to the active function. +// Operates on the global context. +func PUNPCKLWL(mx, x operand.Op) { ctx.PUNPCKLWL(mx, x) } + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +// Construct and append a PUSHQ instruction to the active function. +func (c *Context) PUSHQ(imr operand.Op) { + if inst, err := x86.PUSHQ(imr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +// Construct and append a PUSHQ instruction to the active function. +// Operates on the global context. +func PUSHQ(imr operand.Op) { ctx.PUSHQ(imr) } + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +// Construct and append a PUSHW instruction to the active function. +func (c *Context) PUSHW(mr operand.Op) { + if inst, err := x86.PUSHW(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +// Construct and append a PUSHW instruction to the active function. +// Operates on the global context. +func PUSHW(mr operand.Op) { ctx.PUSHW(mr) } + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +// Construct and append a PXOR instruction to the active function. +func (c *Context) PXOR(mx, x operand.Op) { + if inst, err := x86.PXOR(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +// Construct and append a PXOR instruction to the active function. +// Operates on the global context. +func PXOR(mx, x operand.Op) { ctx.PXOR(mx, x) } + +// RCLB: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLB 1 r8 +// RCLB imm8 r8 +// RCLB cl r8 +// RCLB 1 m8 +// RCLB imm8 m8 +// RCLB cl m8 +// Construct and append a RCLB instruction to the active function. +func (c *Context) RCLB(ci, mr operand.Op) { + if inst, err := x86.RCLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCLB: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLB 1 r8 +// RCLB imm8 r8 +// RCLB cl r8 +// RCLB 1 m8 +// RCLB imm8 m8 +// RCLB cl m8 +// Construct and append a RCLB instruction to the active function. +// Operates on the global context. +func RCLB(ci, mr operand.Op) { ctx.RCLB(ci, mr) } + +// RCLL: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLL 1 r32 +// RCLL imm8 r32 +// RCLL cl r32 +// RCLL 1 m32 +// RCLL imm8 m32 +// RCLL cl m32 +// Construct and append a RCLL instruction to the active function. +func (c *Context) RCLL(ci, mr operand.Op) { + if inst, err := x86.RCLL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCLL: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLL 1 r32 +// RCLL imm8 r32 +// RCLL cl r32 +// RCLL 1 m32 +// RCLL imm8 m32 +// RCLL cl m32 +// Construct and append a RCLL instruction to the active function. +// Operates on the global context. +func RCLL(ci, mr operand.Op) { ctx.RCLL(ci, mr) } + +// RCLQ: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLQ 1 r64 +// RCLQ imm8 r64 +// RCLQ cl r64 +// RCLQ 1 m64 +// RCLQ imm8 m64 +// RCLQ cl m64 +// Construct and append a RCLQ instruction to the active function. +func (c *Context) RCLQ(ci, mr operand.Op) { + if inst, err := x86.RCLQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCLQ: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLQ 1 r64 +// RCLQ imm8 r64 +// RCLQ cl r64 +// RCLQ 1 m64 +// RCLQ imm8 m64 +// RCLQ cl m64 +// Construct and append a RCLQ instruction to the active function. +// Operates on the global context. +func RCLQ(ci, mr operand.Op) { ctx.RCLQ(ci, mr) } + +// RCLW: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLW 1 r16 +// RCLW imm8 r16 +// RCLW cl r16 +// RCLW 1 m16 +// RCLW imm8 m16 +// RCLW cl m16 +// Construct and append a RCLW instruction to the active function. +func (c *Context) RCLW(ci, mr operand.Op) { + if inst, err := x86.RCLW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCLW: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLW 1 r16 +// RCLW imm8 r16 +// RCLW cl r16 +// RCLW 1 m16 +// RCLW imm8 m16 +// RCLW cl m16 +// Construct and append a RCLW instruction to the active function. +// Operates on the global context. +func RCLW(ci, mr operand.Op) { ctx.RCLW(ci, mr) } + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +// Construct and append a RCPPS instruction to the active function. +func (c *Context) RCPPS(mx, x operand.Op) { + if inst, err := x86.RCPPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +// Construct and append a RCPPS instruction to the active function. +// Operates on the global context. +func RCPPS(mx, x operand.Op) { ctx.RCPPS(mx, x) } + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +// Construct and append a RCPSS instruction to the active function. +func (c *Context) RCPSS(mx, x operand.Op) { + if inst, err := x86.RCPSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +// Construct and append a RCPSS instruction to the active function. +// Operates on the global context. +func RCPSS(mx, x operand.Op) { ctx.RCPSS(mx, x) } + +// RCRB: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRB 1 r8 +// RCRB imm8 r8 +// RCRB cl r8 +// RCRB 1 m8 +// RCRB imm8 m8 +// RCRB cl m8 +// Construct and append a RCRB instruction to the active function. +func (c *Context) RCRB(ci, mr operand.Op) { + if inst, err := x86.RCRB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCRB: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRB 1 r8 +// RCRB imm8 r8 +// RCRB cl r8 +// RCRB 1 m8 +// RCRB imm8 m8 +// RCRB cl m8 +// Construct and append a RCRB instruction to the active function. +// Operates on the global context. +func RCRB(ci, mr operand.Op) { ctx.RCRB(ci, mr) } + +// RCRL: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRL 1 r32 +// RCRL imm8 r32 +// RCRL cl r32 +// RCRL 1 m32 +// RCRL imm8 m32 +// RCRL cl m32 +// Construct and append a RCRL instruction to the active function. +func (c *Context) RCRL(ci, mr operand.Op) { + if inst, err := x86.RCRL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCRL: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRL 1 r32 +// RCRL imm8 r32 +// RCRL cl r32 +// RCRL 1 m32 +// RCRL imm8 m32 +// RCRL cl m32 +// Construct and append a RCRL instruction to the active function. +// Operates on the global context. +func RCRL(ci, mr operand.Op) { ctx.RCRL(ci, mr) } + +// RCRQ: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRQ 1 r64 +// RCRQ imm8 r64 +// RCRQ cl r64 +// RCRQ 1 m64 +// RCRQ imm8 m64 +// RCRQ cl m64 +// Construct and append a RCRQ instruction to the active function. +func (c *Context) RCRQ(ci, mr operand.Op) { + if inst, err := x86.RCRQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCRQ: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRQ 1 r64 +// RCRQ imm8 r64 +// RCRQ cl r64 +// RCRQ 1 m64 +// RCRQ imm8 m64 +// RCRQ cl m64 +// Construct and append a RCRQ instruction to the active function. +// Operates on the global context. +func RCRQ(ci, mr operand.Op) { ctx.RCRQ(ci, mr) } + +// RCRW: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRW 1 r16 +// RCRW imm8 r16 +// RCRW cl r16 +// RCRW 1 m16 +// RCRW imm8 m16 +// RCRW cl m16 +// Construct and append a RCRW instruction to the active function. +func (c *Context) RCRW(ci, mr operand.Op) { + if inst, err := x86.RCRW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RCRW: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRW 1 r16 +// RCRW imm8 r16 +// RCRW cl r16 +// RCRW 1 m16 +// RCRW imm8 m16 +// RCRW cl m16 +// Construct and append a RCRW instruction to the active function. +// Operates on the global context. +func RCRW(ci, mr operand.Op) { ctx.RCRW(ci, mr) } + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +// Construct and append a RDRANDL instruction to the active function. +func (c *Context) RDRANDL(r operand.Op) { + if inst, err := x86.RDRANDL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +// Construct and append a RDRANDL instruction to the active function. +// Operates on the global context. +func RDRANDL(r operand.Op) { ctx.RDRANDL(r) } + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +// Construct and append a RDRANDQ instruction to the active function. +func (c *Context) RDRANDQ(r operand.Op) { + if inst, err := x86.RDRANDQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +// Construct and append a RDRANDQ instruction to the active function. +// Operates on the global context. +func RDRANDQ(r operand.Op) { ctx.RDRANDQ(r) } + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +// Construct and append a RDRANDW instruction to the active function. +func (c *Context) RDRANDW(r operand.Op) { + if inst, err := x86.RDRANDW(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +// Construct and append a RDRANDW instruction to the active function. +// Operates on the global context. +func RDRANDW(r operand.Op) { ctx.RDRANDW(r) } + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +// Construct and append a RDSEEDL instruction to the active function. +func (c *Context) RDSEEDL(r operand.Op) { + if inst, err := x86.RDSEEDL(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +// Construct and append a RDSEEDL instruction to the active function. +// Operates on the global context. +func RDSEEDL(r operand.Op) { ctx.RDSEEDL(r) } + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +// Construct and append a RDSEEDQ instruction to the active function. +func (c *Context) RDSEEDQ(r operand.Op) { + if inst, err := x86.RDSEEDQ(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +// Construct and append a RDSEEDQ instruction to the active function. +// Operates on the global context. +func RDSEEDQ(r operand.Op) { ctx.RDSEEDQ(r) } + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +// Construct and append a RDSEEDW instruction to the active function. +func (c *Context) RDSEEDW(r operand.Op) { + if inst, err := x86.RDSEEDW(r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +// Construct and append a RDSEEDW instruction to the active function. +// Operates on the global context. +func RDSEEDW(r operand.Op) { ctx.RDSEEDW(r) } + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +// Construct and append a RDTSC instruction to the active function. +func (c *Context) RDTSC() { + if inst, err := x86.RDTSC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +// Construct and append a RDTSC instruction to the active function. +// Operates on the global context. +func RDTSC() { ctx.RDTSC() } + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +// Construct and append a RDTSCP instruction to the active function. +func (c *Context) RDTSCP() { + if inst, err := x86.RDTSCP(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +// Construct and append a RDTSCP instruction to the active function. +// Operates on the global context. +func RDTSCP() { ctx.RDTSCP() } + +// RET: Return from Procedure. +// +// Forms: +// +// RET +// Construct and append a RET instruction to the active function. +func (c *Context) RET() { + if inst, err := x86.RET(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RET: Return from Procedure. +// +// Forms: +// +// RET +// Construct and append a RET instruction to the active function. +// Operates on the global context. +func RET() { ctx.RET() } + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +// Construct and append a RETFL instruction to the active function. +func (c *Context) RETFL(i operand.Op) { + if inst, err := x86.RETFL(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +// Construct and append a RETFL instruction to the active function. +// Operates on the global context. +func RETFL(i operand.Op) { ctx.RETFL(i) } + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +// Construct and append a RETFQ instruction to the active function. +func (c *Context) RETFQ(i operand.Op) { + if inst, err := x86.RETFQ(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +// Construct and append a RETFQ instruction to the active function. +// Operates on the global context. +func RETFQ(i operand.Op) { ctx.RETFQ(i) } + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +// Construct and append a RETFW instruction to the active function. +func (c *Context) RETFW(i operand.Op) { + if inst, err := x86.RETFW(i); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +// Construct and append a RETFW instruction to the active function. +// Operates on the global context. +func RETFW(i operand.Op) { ctx.RETFW(i) } + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +// Construct and append a ROLB instruction to the active function. +func (c *Context) ROLB(ci, mr operand.Op) { + if inst, err := x86.ROLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +// Construct and append a ROLB instruction to the active function. +// Operates on the global context. +func ROLB(ci, mr operand.Op) { ctx.ROLB(ci, mr) } + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +// Construct and append a ROLL instruction to the active function. +func (c *Context) ROLL(ci, mr operand.Op) { + if inst, err := x86.ROLL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +// Construct and append a ROLL instruction to the active function. +// Operates on the global context. +func ROLL(ci, mr operand.Op) { ctx.ROLL(ci, mr) } + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +// Construct and append a ROLQ instruction to the active function. +func (c *Context) ROLQ(ci, mr operand.Op) { + if inst, err := x86.ROLQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +// Construct and append a ROLQ instruction to the active function. +// Operates on the global context. +func ROLQ(ci, mr operand.Op) { ctx.ROLQ(ci, mr) } + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +// Construct and append a ROLW instruction to the active function. +func (c *Context) ROLW(ci, mr operand.Op) { + if inst, err := x86.ROLW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +// Construct and append a ROLW instruction to the active function. +// Operates on the global context. +func ROLW(ci, mr operand.Op) { ctx.ROLW(ci, mr) } + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +// Construct and append a RORB instruction to the active function. +func (c *Context) RORB(ci, mr operand.Op) { + if inst, err := x86.RORB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +// Construct and append a RORB instruction to the active function. +// Operates on the global context. +func RORB(ci, mr operand.Op) { ctx.RORB(ci, mr) } + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +// Construct and append a RORL instruction to the active function. +func (c *Context) RORL(ci, mr operand.Op) { + if inst, err := x86.RORL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +// Construct and append a RORL instruction to the active function. +// Operates on the global context. +func RORL(ci, mr operand.Op) { ctx.RORL(ci, mr) } + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +// Construct and append a RORQ instruction to the active function. +func (c *Context) RORQ(ci, mr operand.Op) { + if inst, err := x86.RORQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +// Construct and append a RORQ instruction to the active function. +// Operates on the global context. +func RORQ(ci, mr operand.Op) { ctx.RORQ(ci, mr) } + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +// Construct and append a RORW instruction to the active function. +func (c *Context) RORW(ci, mr operand.Op) { + if inst, err := x86.RORW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +// Construct and append a RORW instruction to the active function. +// Operates on the global context. +func RORW(ci, mr operand.Op) { ctx.RORW(ci, mr) } + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +// Construct and append a RORXL instruction to the active function. +func (c *Context) RORXL(i, mr, r operand.Op) { + if inst, err := x86.RORXL(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +// Construct and append a RORXL instruction to the active function. +// Operates on the global context. +func RORXL(i, mr, r operand.Op) { ctx.RORXL(i, mr, r) } + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +// Construct and append a RORXQ instruction to the active function. +func (c *Context) RORXQ(i, mr, r operand.Op) { + if inst, err := x86.RORXQ(i, mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +// Construct and append a RORXQ instruction to the active function. +// Operates on the global context. +func RORXQ(i, mr, r operand.Op) { ctx.RORXQ(i, mr, r) } + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +// Construct and append a ROUNDPD instruction to the active function. +func (c *Context) ROUNDPD(i, mx, x operand.Op) { + if inst, err := x86.ROUNDPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +// Construct and append a ROUNDPD instruction to the active function. +// Operates on the global context. +func ROUNDPD(i, mx, x operand.Op) { ctx.ROUNDPD(i, mx, x) } + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +// Construct and append a ROUNDPS instruction to the active function. +func (c *Context) ROUNDPS(i, mx, x operand.Op) { + if inst, err := x86.ROUNDPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +// Construct and append a ROUNDPS instruction to the active function. +// Operates on the global context. +func ROUNDPS(i, mx, x operand.Op) { ctx.ROUNDPS(i, mx, x) } + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +// Construct and append a ROUNDSD instruction to the active function. +func (c *Context) ROUNDSD(i, mx, x operand.Op) { + if inst, err := x86.ROUNDSD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +// Construct and append a ROUNDSD instruction to the active function. +// Operates on the global context. +func ROUNDSD(i, mx, x operand.Op) { ctx.ROUNDSD(i, mx, x) } + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +// Construct and append a ROUNDSS instruction to the active function. +func (c *Context) ROUNDSS(i, mx, x operand.Op) { + if inst, err := x86.ROUNDSS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +// Construct and append a ROUNDSS instruction to the active function. +// Operates on the global context. +func ROUNDSS(i, mx, x operand.Op) { ctx.ROUNDSS(i, mx, x) } + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +// Construct and append a RSQRTPS instruction to the active function. +func (c *Context) RSQRTPS(mx, x operand.Op) { + if inst, err := x86.RSQRTPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +// Construct and append a RSQRTPS instruction to the active function. +// Operates on the global context. +func RSQRTPS(mx, x operand.Op) { ctx.RSQRTPS(mx, x) } + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +// Construct and append a RSQRTSS instruction to the active function. +func (c *Context) RSQRTSS(mx, x operand.Op) { + if inst, err := x86.RSQRTSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +// Construct and append a RSQRTSS instruction to the active function. +// Operates on the global context. +func RSQRTSS(mx, x operand.Op) { ctx.RSQRTSS(mx, x) } + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +// Construct and append a SALB instruction to the active function. +func (c *Context) SALB(ci, mr operand.Op) { + if inst, err := x86.SALB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +// Construct and append a SALB instruction to the active function. +// Operates on the global context. +func SALB(ci, mr operand.Op) { ctx.SALB(ci, mr) } + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +// Construct and append a SALL instruction to the active function. +func (c *Context) SALL(ci, mr operand.Op) { + if inst, err := x86.SALL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +// Construct and append a SALL instruction to the active function. +// Operates on the global context. +func SALL(ci, mr operand.Op) { ctx.SALL(ci, mr) } + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +// Construct and append a SALQ instruction to the active function. +func (c *Context) SALQ(ci, mr operand.Op) { + if inst, err := x86.SALQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +// Construct and append a SALQ instruction to the active function. +// Operates on the global context. +func SALQ(ci, mr operand.Op) { ctx.SALQ(ci, mr) } + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +// Construct and append a SALW instruction to the active function. +func (c *Context) SALW(ci, mr operand.Op) { + if inst, err := x86.SALW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +// Construct and append a SALW instruction to the active function. +// Operates on the global context. +func SALW(ci, mr operand.Op) { ctx.SALW(ci, mr) } + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +// Construct and append a SARB instruction to the active function. +func (c *Context) SARB(ci, mr operand.Op) { + if inst, err := x86.SARB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +// Construct and append a SARB instruction to the active function. +// Operates on the global context. +func SARB(ci, mr operand.Op) { ctx.SARB(ci, mr) } + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +// Construct and append a SARL instruction to the active function. +func (c *Context) SARL(ci, mr operand.Op) { + if inst, err := x86.SARL(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +// Construct and append a SARL instruction to the active function. +// Operates on the global context. +func SARL(ci, mr operand.Op) { ctx.SARL(ci, mr) } + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +// Construct and append a SARQ instruction to the active function. +func (c *Context) SARQ(ci, mr operand.Op) { + if inst, err := x86.SARQ(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +// Construct and append a SARQ instruction to the active function. +// Operates on the global context. +func SARQ(ci, mr operand.Op) { ctx.SARQ(ci, mr) } + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +// Construct and append a SARW instruction to the active function. +func (c *Context) SARW(ci, mr operand.Op) { + if inst, err := x86.SARW(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +// Construct and append a SARW instruction to the active function. +// Operates on the global context. +func SARW(ci, mr operand.Op) { ctx.SARW(ci, mr) } + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +// Construct and append a SARXL instruction to the active function. +func (c *Context) SARXL(r, mr, r1 operand.Op) { + if inst, err := x86.SARXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +// Construct and append a SARXL instruction to the active function. +// Operates on the global context. +func SARXL(r, mr, r1 operand.Op) { ctx.SARXL(r, mr, r1) } + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +// Construct and append a SARXQ instruction to the active function. +func (c *Context) SARXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SARXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +// Construct and append a SARXQ instruction to the active function. +// Operates on the global context. +func SARXQ(r, mr, r1 operand.Op) { ctx.SARXQ(r, mr, r1) } + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +// Construct and append a SBBB instruction to the active function. +func (c *Context) SBBB(imr, amr operand.Op) { + if inst, err := x86.SBBB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +// Construct and append a SBBB instruction to the active function. +// Operates on the global context. +func SBBB(imr, amr operand.Op) { ctx.SBBB(imr, amr) } + +// SBBL: Subtract with Borrow. +// +// Forms: +// +// SBBL imm32 eax +// SBBL imm8 r32 +// SBBL imm32 r32 +// SBBL r32 r32 +// SBBL m32 r32 +// SBBL imm8 m32 +// SBBL imm32 m32 +// SBBL r32 m32 +// Construct and append a SBBL instruction to the active function. +func (c *Context) SBBL(imr, emr operand.Op) { + if inst, err := x86.SBBL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SBBL: Subtract with Borrow. +// +// Forms: +// +// SBBL imm32 eax +// SBBL imm8 r32 +// SBBL imm32 r32 +// SBBL r32 r32 +// SBBL m32 r32 +// SBBL imm8 m32 +// SBBL imm32 m32 +// SBBL r32 m32 +// Construct and append a SBBL instruction to the active function. +// Operates on the global context. +func SBBL(imr, emr operand.Op) { ctx.SBBL(imr, emr) } + +// SBBQ: Subtract with Borrow. +// +// Forms: +// +// SBBQ imm32 rax +// SBBQ imm8 r64 +// SBBQ imm32 r64 +// SBBQ r64 r64 +// SBBQ m64 r64 +// SBBQ imm8 m64 +// SBBQ imm32 m64 +// SBBQ r64 m64 +// Construct and append a SBBQ instruction to the active function. +func (c *Context) SBBQ(imr, mr operand.Op) { + if inst, err := x86.SBBQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SBBQ: Subtract with Borrow. +// +// Forms: +// +// SBBQ imm32 rax +// SBBQ imm8 r64 +// SBBQ imm32 r64 +// SBBQ r64 r64 +// SBBQ m64 r64 +// SBBQ imm8 m64 +// SBBQ imm32 m64 +// SBBQ r64 m64 +// Construct and append a SBBQ instruction to the active function. +// Operates on the global context. +func SBBQ(imr, mr operand.Op) { ctx.SBBQ(imr, mr) } + +// SBBW: Subtract with Borrow. +// +// Forms: +// +// SBBW imm16 ax +// SBBW imm8 r16 +// SBBW imm16 r16 +// SBBW r16 r16 +// SBBW m16 r16 +// SBBW imm8 m16 +// SBBW imm16 m16 +// SBBW r16 m16 +// Construct and append a SBBW instruction to the active function. +func (c *Context) SBBW(imr, amr operand.Op) { + if inst, err := x86.SBBW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SBBW: Subtract with Borrow. +// +// Forms: +// +// SBBW imm16 ax +// SBBW imm8 r16 +// SBBW imm16 r16 +// SBBW r16 r16 +// SBBW m16 r16 +// SBBW imm8 m16 +// SBBW imm16 m16 +// SBBW r16 m16 +// Construct and append a SBBW instruction to the active function. +// Operates on the global context. +func SBBW(imr, amr operand.Op) { ctx.SBBW(imr, amr) } + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +// Construct and append a SETCC instruction to the active function. +func (c *Context) SETCC(mr operand.Op) { + if inst, err := x86.SETCC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +// Construct and append a SETCC instruction to the active function. +// Operates on the global context. +func SETCC(mr operand.Op) { ctx.SETCC(mr) } + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +// Construct and append a SETCS instruction to the active function. +func (c *Context) SETCS(mr operand.Op) { + if inst, err := x86.SETCS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +// Construct and append a SETCS instruction to the active function. +// Operates on the global context. +func SETCS(mr operand.Op) { ctx.SETCS(mr) } + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +// Construct and append a SETEQ instruction to the active function. +func (c *Context) SETEQ(mr operand.Op) { + if inst, err := x86.SETEQ(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +// Construct and append a SETEQ instruction to the active function. +// Operates on the global context. +func SETEQ(mr operand.Op) { ctx.SETEQ(mr) } + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +// Construct and append a SETGE instruction to the active function. +func (c *Context) SETGE(mr operand.Op) { + if inst, err := x86.SETGE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +// Construct and append a SETGE instruction to the active function. +// Operates on the global context. +func SETGE(mr operand.Op) { ctx.SETGE(mr) } + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +// Construct and append a SETGT instruction to the active function. +func (c *Context) SETGT(mr operand.Op) { + if inst, err := x86.SETGT(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +// Construct and append a SETGT instruction to the active function. +// Operates on the global context. +func SETGT(mr operand.Op) { ctx.SETGT(mr) } + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +// Construct and append a SETHI instruction to the active function. +func (c *Context) SETHI(mr operand.Op) { + if inst, err := x86.SETHI(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +// Construct and append a SETHI instruction to the active function. +// Operates on the global context. +func SETHI(mr operand.Op) { ctx.SETHI(mr) } + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +// Construct and append a SETLE instruction to the active function. +func (c *Context) SETLE(mr operand.Op) { + if inst, err := x86.SETLE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +// Construct and append a SETLE instruction to the active function. +// Operates on the global context. +func SETLE(mr operand.Op) { ctx.SETLE(mr) } + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +// Construct and append a SETLS instruction to the active function. +func (c *Context) SETLS(mr operand.Op) { + if inst, err := x86.SETLS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +// Construct and append a SETLS instruction to the active function. +// Operates on the global context. +func SETLS(mr operand.Op) { ctx.SETLS(mr) } + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +// Construct and append a SETLT instruction to the active function. +func (c *Context) SETLT(mr operand.Op) { + if inst, err := x86.SETLT(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +// Construct and append a SETLT instruction to the active function. +// Operates on the global context. +func SETLT(mr operand.Op) { ctx.SETLT(mr) } + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +// Construct and append a SETMI instruction to the active function. +func (c *Context) SETMI(mr operand.Op) { + if inst, err := x86.SETMI(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +// Construct and append a SETMI instruction to the active function. +// Operates on the global context. +func SETMI(mr operand.Op) { ctx.SETMI(mr) } + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +// Construct and append a SETNE instruction to the active function. +func (c *Context) SETNE(mr operand.Op) { + if inst, err := x86.SETNE(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +// Construct and append a SETNE instruction to the active function. +// Operates on the global context. +func SETNE(mr operand.Op) { ctx.SETNE(mr) } + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +// Construct and append a SETOC instruction to the active function. +func (c *Context) SETOC(mr operand.Op) { + if inst, err := x86.SETOC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +// Construct and append a SETOC instruction to the active function. +// Operates on the global context. +func SETOC(mr operand.Op) { ctx.SETOC(mr) } + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +// Construct and append a SETOS instruction to the active function. +func (c *Context) SETOS(mr operand.Op) { + if inst, err := x86.SETOS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +// Construct and append a SETOS instruction to the active function. +// Operates on the global context. +func SETOS(mr operand.Op) { ctx.SETOS(mr) } + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +// Construct and append a SETPC instruction to the active function. +func (c *Context) SETPC(mr operand.Op) { + if inst, err := x86.SETPC(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +// Construct and append a SETPC instruction to the active function. +// Operates on the global context. +func SETPC(mr operand.Op) { ctx.SETPC(mr) } + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +// Construct and append a SETPL instruction to the active function. +func (c *Context) SETPL(mr operand.Op) { + if inst, err := x86.SETPL(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +// Construct and append a SETPL instruction to the active function. +// Operates on the global context. +func SETPL(mr operand.Op) { ctx.SETPL(mr) } + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +// Construct and append a SETPS instruction to the active function. +func (c *Context) SETPS(mr operand.Op) { + if inst, err := x86.SETPS(mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +// Construct and append a SETPS instruction to the active function. +// Operates on the global context. +func SETPS(mr operand.Op) { ctx.SETPS(mr) } + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +// Construct and append a SFENCE instruction to the active function. +func (c *Context) SFENCE() { + if inst, err := x86.SFENCE(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +// Construct and append a SFENCE instruction to the active function. +// Operates on the global context. +func SFENCE() { ctx.SFENCE() } + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +// Construct and append a SHA1MSG1 instruction to the active function. +func (c *Context) SHA1MSG1(mx, x operand.Op) { + if inst, err := x86.SHA1MSG1(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +// Construct and append a SHA1MSG1 instruction to the active function. +// Operates on the global context. +func SHA1MSG1(mx, x operand.Op) { ctx.SHA1MSG1(mx, x) } + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +// Construct and append a SHA1MSG2 instruction to the active function. +func (c *Context) SHA1MSG2(mx, x operand.Op) { + if inst, err := x86.SHA1MSG2(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +// Construct and append a SHA1MSG2 instruction to the active function. +// Operates on the global context. +func SHA1MSG2(mx, x operand.Op) { ctx.SHA1MSG2(mx, x) } + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +// Construct and append a SHA1NEXTE instruction to the active function. +func (c *Context) SHA1NEXTE(mx, x operand.Op) { + if inst, err := x86.SHA1NEXTE(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +// Construct and append a SHA1NEXTE instruction to the active function. +// Operates on the global context. +func SHA1NEXTE(mx, x operand.Op) { ctx.SHA1NEXTE(mx, x) } + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +// Construct and append a SHA1RNDS4 instruction to the active function. +func (c *Context) SHA1RNDS4(i, mx, x operand.Op) { + if inst, err := x86.SHA1RNDS4(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +// Construct and append a SHA1RNDS4 instruction to the active function. +// Operates on the global context. +func SHA1RNDS4(i, mx, x operand.Op) { ctx.SHA1RNDS4(i, mx, x) } + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +// Construct and append a SHA256MSG1 instruction to the active function. +func (c *Context) SHA256MSG1(mx, x operand.Op) { + if inst, err := x86.SHA256MSG1(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +// Construct and append a SHA256MSG1 instruction to the active function. +// Operates on the global context. +func SHA256MSG1(mx, x operand.Op) { ctx.SHA256MSG1(mx, x) } + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +// Construct and append a SHA256MSG2 instruction to the active function. +func (c *Context) SHA256MSG2(mx, x operand.Op) { + if inst, err := x86.SHA256MSG2(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +// Construct and append a SHA256MSG2 instruction to the active function. +// Operates on the global context. +func SHA256MSG2(mx, x operand.Op) { ctx.SHA256MSG2(mx, x) } + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +// Construct and append a SHA256RNDS2 instruction to the active function. +func (c *Context) SHA256RNDS2(x, mx, x1 operand.Op) { + if inst, err := x86.SHA256RNDS2(x, mx, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +// Construct and append a SHA256RNDS2 instruction to the active function. +// Operates on the global context. +func SHA256RNDS2(x, mx, x1 operand.Op) { ctx.SHA256RNDS2(x, mx, x1) } + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +// Construct and append a SHLB instruction to the active function. +func (c *Context) SHLB(ci, mr operand.Op) { + if inst, err := x86.SHLB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +// Construct and append a SHLB instruction to the active function. +// Operates on the global context. +func SHLB(ci, mr operand.Op) { ctx.SHLB(ci, mr) } + +// SHLL: Logical Shift Left. +// +// Forms: +// +// SHLL 1 r32 +// SHLL imm8 r32 +// SHLL cl r32 +// SHLL 1 m32 +// SHLL imm8 m32 +// SHLL cl m32 +// SHLL imm8 r32 r32 +// SHLL cl r32 r32 +// SHLL imm8 r32 m32 +// SHLL cl r32 m32 +// Construct and append a SHLL instruction to the active function. +func (c *Context) SHLL(ops ...operand.Op) { + if inst, err := x86.SHLL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLL: Logical Shift Left. +// +// Forms: +// +// SHLL 1 r32 +// SHLL imm8 r32 +// SHLL cl r32 +// SHLL 1 m32 +// SHLL imm8 m32 +// SHLL cl m32 +// SHLL imm8 r32 r32 +// SHLL cl r32 r32 +// SHLL imm8 r32 m32 +// SHLL cl r32 m32 +// Construct and append a SHLL instruction to the active function. +// Operates on the global context. +func SHLL(ops ...operand.Op) { ctx.SHLL(ops...) } + +// SHLQ: Logical Shift Left. +// +// Forms: +// +// SHLQ 1 r64 +// SHLQ imm8 r64 +// SHLQ cl r64 +// SHLQ 1 m64 +// SHLQ imm8 m64 +// SHLQ cl m64 +// SHLQ imm8 r64 r64 +// SHLQ cl r64 r64 +// SHLQ imm8 r64 m64 +// SHLQ cl r64 m64 +// Construct and append a SHLQ instruction to the active function. +func (c *Context) SHLQ(ops ...operand.Op) { + if inst, err := x86.SHLQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLQ: Logical Shift Left. +// +// Forms: +// +// SHLQ 1 r64 +// SHLQ imm8 r64 +// SHLQ cl r64 +// SHLQ 1 m64 +// SHLQ imm8 m64 +// SHLQ cl m64 +// SHLQ imm8 r64 r64 +// SHLQ cl r64 r64 +// SHLQ imm8 r64 m64 +// SHLQ cl r64 m64 +// Construct and append a SHLQ instruction to the active function. +// Operates on the global context. +func SHLQ(ops ...operand.Op) { ctx.SHLQ(ops...) } + +// SHLW: Logical Shift Left. +// +// Forms: +// +// SHLW 1 r16 +// SHLW imm8 r16 +// SHLW cl r16 +// SHLW 1 m16 +// SHLW imm8 m16 +// SHLW cl m16 +// SHLW imm8 r16 r16 +// SHLW cl r16 r16 +// SHLW imm8 r16 m16 +// SHLW cl r16 m16 +// Construct and append a SHLW instruction to the active function. +func (c *Context) SHLW(ops ...operand.Op) { + if inst, err := x86.SHLW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLW: Logical Shift Left. +// +// Forms: +// +// SHLW 1 r16 +// SHLW imm8 r16 +// SHLW cl r16 +// SHLW 1 m16 +// SHLW imm8 m16 +// SHLW cl m16 +// SHLW imm8 r16 r16 +// SHLW cl r16 r16 +// SHLW imm8 r16 m16 +// SHLW cl r16 m16 +// Construct and append a SHLW instruction to the active function. +// Operates on the global context. +func SHLW(ops ...operand.Op) { ctx.SHLW(ops...) } + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +// Construct and append a SHLXL instruction to the active function. +func (c *Context) SHLXL(r, mr, r1 operand.Op) { + if inst, err := x86.SHLXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +// Construct and append a SHLXL instruction to the active function. +// Operates on the global context. +func SHLXL(r, mr, r1 operand.Op) { ctx.SHLXL(r, mr, r1) } + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +// Construct and append a SHLXQ instruction to the active function. +func (c *Context) SHLXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SHLXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +// Construct and append a SHLXQ instruction to the active function. +// Operates on the global context. +func SHLXQ(r, mr, r1 operand.Op) { ctx.SHLXQ(r, mr, r1) } + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +// Construct and append a SHRB instruction to the active function. +func (c *Context) SHRB(ci, mr operand.Op) { + if inst, err := x86.SHRB(ci, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +// Construct and append a SHRB instruction to the active function. +// Operates on the global context. +func SHRB(ci, mr operand.Op) { ctx.SHRB(ci, mr) } + +// SHRL: Logical Shift Right. +// +// Forms: +// +// SHRL 1 r32 +// SHRL imm8 r32 +// SHRL cl r32 +// SHRL 1 m32 +// SHRL imm8 m32 +// SHRL cl m32 +// SHRL imm8 r32 r32 +// SHRL cl r32 r32 +// SHRL imm8 r32 m32 +// SHRL cl r32 m32 +// Construct and append a SHRL instruction to the active function. +func (c *Context) SHRL(ops ...operand.Op) { + if inst, err := x86.SHRL(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRL: Logical Shift Right. +// +// Forms: +// +// SHRL 1 r32 +// SHRL imm8 r32 +// SHRL cl r32 +// SHRL 1 m32 +// SHRL imm8 m32 +// SHRL cl m32 +// SHRL imm8 r32 r32 +// SHRL cl r32 r32 +// SHRL imm8 r32 m32 +// SHRL cl r32 m32 +// Construct and append a SHRL instruction to the active function. +// Operates on the global context. +func SHRL(ops ...operand.Op) { ctx.SHRL(ops...) } + +// SHRQ: Logical Shift Right. +// +// Forms: +// +// SHRQ 1 r64 +// SHRQ imm8 r64 +// SHRQ cl r64 +// SHRQ 1 m64 +// SHRQ imm8 m64 +// SHRQ cl m64 +// SHRQ imm8 r64 r64 +// SHRQ cl r64 r64 +// SHRQ imm8 r64 m64 +// SHRQ cl r64 m64 +// Construct and append a SHRQ instruction to the active function. +func (c *Context) SHRQ(ops ...operand.Op) { + if inst, err := x86.SHRQ(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRQ: Logical Shift Right. +// +// Forms: +// +// SHRQ 1 r64 +// SHRQ imm8 r64 +// SHRQ cl r64 +// SHRQ 1 m64 +// SHRQ imm8 m64 +// SHRQ cl m64 +// SHRQ imm8 r64 r64 +// SHRQ cl r64 r64 +// SHRQ imm8 r64 m64 +// SHRQ cl r64 m64 +// Construct and append a SHRQ instruction to the active function. +// Operates on the global context. +func SHRQ(ops ...operand.Op) { ctx.SHRQ(ops...) } + +// SHRW: Logical Shift Right. +// +// Forms: +// +// SHRW 1 r16 +// SHRW imm8 r16 +// SHRW cl r16 +// SHRW 1 m16 +// SHRW imm8 m16 +// SHRW cl m16 +// SHRW imm8 r16 r16 +// SHRW cl r16 r16 +// SHRW imm8 r16 m16 +// SHRW cl r16 m16 +// Construct and append a SHRW instruction to the active function. +func (c *Context) SHRW(ops ...operand.Op) { + if inst, err := x86.SHRW(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRW: Logical Shift Right. +// +// Forms: +// +// SHRW 1 r16 +// SHRW imm8 r16 +// SHRW cl r16 +// SHRW 1 m16 +// SHRW imm8 m16 +// SHRW cl m16 +// SHRW imm8 r16 r16 +// SHRW cl r16 r16 +// SHRW imm8 r16 m16 +// SHRW cl r16 m16 +// Construct and append a SHRW instruction to the active function. +// Operates on the global context. +func SHRW(ops ...operand.Op) { ctx.SHRW(ops...) } + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +// Construct and append a SHRXL instruction to the active function. +func (c *Context) SHRXL(r, mr, r1 operand.Op) { + if inst, err := x86.SHRXL(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +// Construct and append a SHRXL instruction to the active function. +// Operates on the global context. +func SHRXL(r, mr, r1 operand.Op) { ctx.SHRXL(r, mr, r1) } + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +// Construct and append a SHRXQ instruction to the active function. +func (c *Context) SHRXQ(r, mr, r1 operand.Op) { + if inst, err := x86.SHRXQ(r, mr, r1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +// Construct and append a SHRXQ instruction to the active function. +// Operates on the global context. +func SHRXQ(r, mr, r1 operand.Op) { ctx.SHRXQ(r, mr, r1) } + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +// Construct and append a SHUFPD instruction to the active function. +func (c *Context) SHUFPD(i, mx, x operand.Op) { + if inst, err := x86.SHUFPD(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +// Construct and append a SHUFPD instruction to the active function. +// Operates on the global context. +func SHUFPD(i, mx, x operand.Op) { ctx.SHUFPD(i, mx, x) } + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +// Construct and append a SHUFPS instruction to the active function. +func (c *Context) SHUFPS(i, mx, x operand.Op) { + if inst, err := x86.SHUFPS(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +// Construct and append a SHUFPS instruction to the active function. +// Operates on the global context. +func SHUFPS(i, mx, x operand.Op) { ctx.SHUFPS(i, mx, x) } + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +// Construct and append a SQRTPD instruction to the active function. +func (c *Context) SQRTPD(mx, x operand.Op) { + if inst, err := x86.SQRTPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +// Construct and append a SQRTPD instruction to the active function. +// Operates on the global context. +func SQRTPD(mx, x operand.Op) { ctx.SQRTPD(mx, x) } + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +// Construct and append a SQRTPS instruction to the active function. +func (c *Context) SQRTPS(mx, x operand.Op) { + if inst, err := x86.SQRTPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +// Construct and append a SQRTPS instruction to the active function. +// Operates on the global context. +func SQRTPS(mx, x operand.Op) { ctx.SQRTPS(mx, x) } + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +// Construct and append a SQRTSD instruction to the active function. +func (c *Context) SQRTSD(mx, x operand.Op) { + if inst, err := x86.SQRTSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +// Construct and append a SQRTSD instruction to the active function. +// Operates on the global context. +func SQRTSD(mx, x operand.Op) { ctx.SQRTSD(mx, x) } + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +// Construct and append a SQRTSS instruction to the active function. +func (c *Context) SQRTSS(mx, x operand.Op) { + if inst, err := x86.SQRTSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +// Construct and append a SQRTSS instruction to the active function. +// Operates on the global context. +func SQRTSS(mx, x operand.Op) { ctx.SQRTSS(mx, x) } + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +// Construct and append a STC instruction to the active function. +func (c *Context) STC() { + if inst, err := x86.STC(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +// Construct and append a STC instruction to the active function. +// Operates on the global context. +func STC() { ctx.STC() } + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +// Construct and append a STD instruction to the active function. +func (c *Context) STD() { + if inst, err := x86.STD(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +// Construct and append a STD instruction to the active function. +// Operates on the global context. +func STD() { ctx.STD() } + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +// Construct and append a STMXCSR instruction to the active function. +func (c *Context) STMXCSR(m operand.Op) { + if inst, err := x86.STMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +// Construct and append a STMXCSR instruction to the active function. +// Operates on the global context. +func STMXCSR(m operand.Op) { ctx.STMXCSR(m) } + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +// Construct and append a SUBB instruction to the active function. +func (c *Context) SUBB(imr, amr operand.Op) { + if inst, err := x86.SUBB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +// Construct and append a SUBB instruction to the active function. +// Operates on the global context. +func SUBB(imr, amr operand.Op) { ctx.SUBB(imr, amr) } + +// SUBL: Subtract. +// +// Forms: +// +// SUBL imm32 eax +// SUBL imm8 r32 +// SUBL imm32 r32 +// SUBL r32 r32 +// SUBL m32 r32 +// SUBL imm8 m32 +// SUBL imm32 m32 +// SUBL r32 m32 +// Construct and append a SUBL instruction to the active function. +func (c *Context) SUBL(imr, emr operand.Op) { + if inst, err := x86.SUBL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBL: Subtract. +// +// Forms: +// +// SUBL imm32 eax +// SUBL imm8 r32 +// SUBL imm32 r32 +// SUBL r32 r32 +// SUBL m32 r32 +// SUBL imm8 m32 +// SUBL imm32 m32 +// SUBL r32 m32 +// Construct and append a SUBL instruction to the active function. +// Operates on the global context. +func SUBL(imr, emr operand.Op) { ctx.SUBL(imr, emr) } + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +// Construct and append a SUBPD instruction to the active function. +func (c *Context) SUBPD(mx, x operand.Op) { + if inst, err := x86.SUBPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +// Construct and append a SUBPD instruction to the active function. +// Operates on the global context. +func SUBPD(mx, x operand.Op) { ctx.SUBPD(mx, x) } + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +// Construct and append a SUBPS instruction to the active function. +func (c *Context) SUBPS(mx, x operand.Op) { + if inst, err := x86.SUBPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +// Construct and append a SUBPS instruction to the active function. +// Operates on the global context. +func SUBPS(mx, x operand.Op) { ctx.SUBPS(mx, x) } + +// SUBQ: Subtract. +// +// Forms: +// +// SUBQ imm32 rax +// SUBQ imm8 r64 +// SUBQ imm32 r64 +// SUBQ r64 r64 +// SUBQ m64 r64 +// SUBQ imm8 m64 +// SUBQ imm32 m64 +// SUBQ r64 m64 +// Construct and append a SUBQ instruction to the active function. +func (c *Context) SUBQ(imr, mr operand.Op) { + if inst, err := x86.SUBQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBQ: Subtract. +// +// Forms: +// +// SUBQ imm32 rax +// SUBQ imm8 r64 +// SUBQ imm32 r64 +// SUBQ r64 r64 +// SUBQ m64 r64 +// SUBQ imm8 m64 +// SUBQ imm32 m64 +// SUBQ r64 m64 +// Construct and append a SUBQ instruction to the active function. +// Operates on the global context. +func SUBQ(imr, mr operand.Op) { ctx.SUBQ(imr, mr) } + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +// Construct and append a SUBSD instruction to the active function. +func (c *Context) SUBSD(mx, x operand.Op) { + if inst, err := x86.SUBSD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +// Construct and append a SUBSD instruction to the active function. +// Operates on the global context. +func SUBSD(mx, x operand.Op) { ctx.SUBSD(mx, x) } + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +// Construct and append a SUBSS instruction to the active function. +func (c *Context) SUBSS(mx, x operand.Op) { + if inst, err := x86.SUBSS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +// Construct and append a SUBSS instruction to the active function. +// Operates on the global context. +func SUBSS(mx, x operand.Op) { ctx.SUBSS(mx, x) } + +// SUBW: Subtract. +// +// Forms: +// +// SUBW imm16 ax +// SUBW imm8 r16 +// SUBW imm16 r16 +// SUBW r16 r16 +// SUBW m16 r16 +// SUBW imm8 m16 +// SUBW imm16 m16 +// SUBW r16 m16 +// Construct and append a SUBW instruction to the active function. +func (c *Context) SUBW(imr, amr operand.Op) { + if inst, err := x86.SUBW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SUBW: Subtract. +// +// Forms: +// +// SUBW imm16 ax +// SUBW imm8 r16 +// SUBW imm16 r16 +// SUBW r16 r16 +// SUBW m16 r16 +// SUBW imm8 m16 +// SUBW imm16 m16 +// SUBW r16 m16 +// Construct and append a SUBW instruction to the active function. +// Operates on the global context. +func SUBW(imr, amr operand.Op) { ctx.SUBW(imr, amr) } + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +// Construct and append a SYSCALL instruction to the active function. +func (c *Context) SYSCALL() { + if inst, err := x86.SYSCALL(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +// Construct and append a SYSCALL instruction to the active function. +// Operates on the global context. +func SYSCALL() { ctx.SYSCALL() } + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +// Construct and append a TESTB instruction to the active function. +func (c *Context) TESTB(ir, amr operand.Op) { + if inst, err := x86.TESTB(ir, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +// Construct and append a TESTB instruction to the active function. +// Operates on the global context. +func TESTB(ir, amr operand.Op) { ctx.TESTB(ir, amr) } + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +// Construct and append a TESTL instruction to the active function. +func (c *Context) TESTL(ir, emr operand.Op) { + if inst, err := x86.TESTL(ir, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +// Construct and append a TESTL instruction to the active function. +// Operates on the global context. +func TESTL(ir, emr operand.Op) { ctx.TESTL(ir, emr) } + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +// Construct and append a TESTQ instruction to the active function. +func (c *Context) TESTQ(ir, mr operand.Op) { + if inst, err := x86.TESTQ(ir, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +// Construct and append a TESTQ instruction to the active function. +// Operates on the global context. +func TESTQ(ir, mr operand.Op) { ctx.TESTQ(ir, mr) } + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +// Construct and append a TESTW instruction to the active function. +func (c *Context) TESTW(ir, amr operand.Op) { + if inst, err := x86.TESTW(ir, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +// Construct and append a TESTW instruction to the active function. +// Operates on the global context. +func TESTW(ir, amr operand.Op) { ctx.TESTW(ir, amr) } + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +// Construct and append a TZCNTL instruction to the active function. +func (c *Context) TZCNTL(mr, r operand.Op) { + if inst, err := x86.TZCNTL(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +// Construct and append a TZCNTL instruction to the active function. +// Operates on the global context. +func TZCNTL(mr, r operand.Op) { ctx.TZCNTL(mr, r) } + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +// Construct and append a TZCNTQ instruction to the active function. +func (c *Context) TZCNTQ(mr, r operand.Op) { + if inst, err := x86.TZCNTQ(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +// Construct and append a TZCNTQ instruction to the active function. +// Operates on the global context. +func TZCNTQ(mr, r operand.Op) { ctx.TZCNTQ(mr, r) } + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +// Construct and append a TZCNTW instruction to the active function. +func (c *Context) TZCNTW(mr, r operand.Op) { + if inst, err := x86.TZCNTW(mr, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +// Construct and append a TZCNTW instruction to the active function. +// Operates on the global context. +func TZCNTW(mr, r operand.Op) { ctx.TZCNTW(mr, r) } + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +// Construct and append a UCOMISD instruction to the active function. +func (c *Context) UCOMISD(mx, x operand.Op) { + if inst, err := x86.UCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +// Construct and append a UCOMISD instruction to the active function. +// Operates on the global context. +func UCOMISD(mx, x operand.Op) { ctx.UCOMISD(mx, x) } + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +// Construct and append a UCOMISS instruction to the active function. +func (c *Context) UCOMISS(mx, x operand.Op) { + if inst, err := x86.UCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +// Construct and append a UCOMISS instruction to the active function. +// Operates on the global context. +func UCOMISS(mx, x operand.Op) { ctx.UCOMISS(mx, x) } + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +// Construct and append a UD2 instruction to the active function. +func (c *Context) UD2() { + if inst, err := x86.UD2(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +// Construct and append a UD2 instruction to the active function. +// Operates on the global context. +func UD2() { ctx.UD2() } + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +// Construct and append a UNPCKHPD instruction to the active function. +func (c *Context) UNPCKHPD(mx, x operand.Op) { + if inst, err := x86.UNPCKHPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +// Construct and append a UNPCKHPD instruction to the active function. +// Operates on the global context. +func UNPCKHPD(mx, x operand.Op) { ctx.UNPCKHPD(mx, x) } + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +// Construct and append a UNPCKHPS instruction to the active function. +func (c *Context) UNPCKHPS(mx, x operand.Op) { + if inst, err := x86.UNPCKHPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +// Construct and append a UNPCKHPS instruction to the active function. +// Operates on the global context. +func UNPCKHPS(mx, x operand.Op) { ctx.UNPCKHPS(mx, x) } + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +// Construct and append a UNPCKLPD instruction to the active function. +func (c *Context) UNPCKLPD(mx, x operand.Op) { + if inst, err := x86.UNPCKLPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +// Construct and append a UNPCKLPD instruction to the active function. +// Operates on the global context. +func UNPCKLPD(mx, x operand.Op) { ctx.UNPCKLPD(mx, x) } + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +// Construct and append a UNPCKLPS instruction to the active function. +func (c *Context) UNPCKLPS(mx, x operand.Op) { + if inst, err := x86.UNPCKLPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +// Construct and append a UNPCKLPS instruction to the active function. +// Operates on the global context. +func UNPCKLPS(mx, x operand.Op) { ctx.UNPCKLPS(mx, x) } + +// VADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDPD xmm xmm xmm +// VADDPD m128 xmm xmm +// VADDPD ymm ymm ymm +// VADDPD m256 ymm ymm +// Construct and append a VADDPD instruction to the active function. +func (c *Context) VADDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDPD xmm xmm xmm +// VADDPD m128 xmm xmm +// VADDPD ymm ymm ymm +// VADDPD m256 ymm ymm +// Construct and append a VADDPD instruction to the active function. +// Operates on the global context. +func VADDPD(mxy, xy, xy1 operand.Op) { ctx.VADDPD(mxy, xy, xy1) } + +// VADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDPS xmm xmm xmm +// VADDPS m128 xmm xmm +// VADDPS ymm ymm ymm +// VADDPS m256 ymm ymm +// Construct and append a VADDPS instruction to the active function. +func (c *Context) VADDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDPS xmm xmm xmm +// VADDPS m128 xmm xmm +// VADDPS ymm ymm ymm +// VADDPS m256 ymm ymm +// Construct and append a VADDPS instruction to the active function. +// Operates on the global context. +func VADDPS(mxy, xy, xy1 operand.Op) { ctx.VADDPS(mxy, xy, xy1) } + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +// Construct and append a VADDSD instruction to the active function. +func (c *Context) VADDSD(mx, x, x1 operand.Op) { + if inst, err := x86.VADDSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +// Construct and append a VADDSD instruction to the active function. +// Operates on the global context. +func VADDSD(mx, x, x1 operand.Op) { ctx.VADDSD(mx, x, x1) } + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +// Construct and append a VADDSS instruction to the active function. +func (c *Context) VADDSS(mx, x, x1 operand.Op) { + if inst, err := x86.VADDSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +// Construct and append a VADDSS instruction to the active function. +// Operates on the global context. +func VADDSS(mx, x, x1 operand.Op) { ctx.VADDSS(mx, x, x1) } + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +// Construct and append a VADDSUBPD instruction to the active function. +func (c *Context) VADDSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +// Construct and append a VADDSUBPD instruction to the active function. +// Operates on the global context. +func VADDSUBPD(mxy, xy, xy1 operand.Op) { ctx.VADDSUBPD(mxy, xy, xy1) } + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +// Construct and append a VADDSUBPS instruction to the active function. +func (c *Context) VADDSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VADDSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +// Construct and append a VADDSUBPS instruction to the active function. +// Operates on the global context. +func VADDSUBPS(mxy, xy, xy1 operand.Op) { ctx.VADDSUBPS(mxy, xy, xy1) } + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +// Construct and append a VAESDEC instruction to the active function. +func (c *Context) VAESDEC(mx, x, x1 operand.Op) { + if inst, err := x86.VAESDEC(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +// Construct and append a VAESDEC instruction to the active function. +// Operates on the global context. +func VAESDEC(mx, x, x1 operand.Op) { ctx.VAESDEC(mx, x, x1) } + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +// Construct and append a VAESDECLAST instruction to the active function. +func (c *Context) VAESDECLAST(mx, x, x1 operand.Op) { + if inst, err := x86.VAESDECLAST(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +// Construct and append a VAESDECLAST instruction to the active function. +// Operates on the global context. +func VAESDECLAST(mx, x, x1 operand.Op) { ctx.VAESDECLAST(mx, x, x1) } + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +// Construct and append a VAESENC instruction to the active function. +func (c *Context) VAESENC(mx, x, x1 operand.Op) { + if inst, err := x86.VAESENC(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +// Construct and append a VAESENC instruction to the active function. +// Operates on the global context. +func VAESENC(mx, x, x1 operand.Op) { ctx.VAESENC(mx, x, x1) } + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +// Construct and append a VAESENCLAST instruction to the active function. +func (c *Context) VAESENCLAST(mx, x, x1 operand.Op) { + if inst, err := x86.VAESENCLAST(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +// Construct and append a VAESENCLAST instruction to the active function. +// Operates on the global context. +func VAESENCLAST(mx, x, x1 operand.Op) { ctx.VAESENCLAST(mx, x, x1) } + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +// Construct and append a VAESIMC instruction to the active function. +func (c *Context) VAESIMC(mx, x operand.Op) { + if inst, err := x86.VAESIMC(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +// Construct and append a VAESIMC instruction to the active function. +// Operates on the global context. +func VAESIMC(mx, x operand.Op) { ctx.VAESIMC(mx, x) } + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +// Construct and append a VAESKEYGENASSIST instruction to the active function. +func (c *Context) VAESKEYGENASSIST(i, mx, x operand.Op) { + if inst, err := x86.VAESKEYGENASSIST(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +// Construct and append a VAESKEYGENASSIST instruction to the active function. +// Operates on the global context. +func VAESKEYGENASSIST(i, mx, x operand.Op) { ctx.VAESKEYGENASSIST(i, mx, x) } + +// VANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPD xmm xmm xmm +// VANDNPD m128 xmm xmm +// VANDNPD ymm ymm ymm +// VANDNPD m256 ymm ymm +// Construct and append a VANDNPD instruction to the active function. +func (c *Context) VANDNPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDNPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPD xmm xmm xmm +// VANDNPD m128 xmm xmm +// VANDNPD ymm ymm ymm +// VANDNPD m256 ymm ymm +// Construct and append a VANDNPD instruction to the active function. +// Operates on the global context. +func VANDNPD(mxy, xy, xy1 operand.Op) { ctx.VANDNPD(mxy, xy, xy1) } + +// VANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPS xmm xmm xmm +// VANDNPS m128 xmm xmm +// VANDNPS ymm ymm ymm +// VANDNPS m256 ymm ymm +// Construct and append a VANDNPS instruction to the active function. +func (c *Context) VANDNPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDNPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPS xmm xmm xmm +// VANDNPS m128 xmm xmm +// VANDNPS ymm ymm ymm +// VANDNPS m256 ymm ymm +// Construct and append a VANDNPS instruction to the active function. +// Operates on the global context. +func VANDNPS(mxy, xy, xy1 operand.Op) { ctx.VANDNPS(mxy, xy, xy1) } + +// VANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDPD xmm xmm xmm +// VANDPD m128 xmm xmm +// VANDPD ymm ymm ymm +// VANDPD m256 ymm ymm +// Construct and append a VANDPD instruction to the active function. +func (c *Context) VANDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDPD xmm xmm xmm +// VANDPD m128 xmm xmm +// VANDPD ymm ymm ymm +// VANDPD m256 ymm ymm +// Construct and append a VANDPD instruction to the active function. +// Operates on the global context. +func VANDPD(mxy, xy, xy1 operand.Op) { ctx.VANDPD(mxy, xy, xy1) } + +// VANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDPS xmm xmm xmm +// VANDPS m128 xmm xmm +// VANDPS ymm ymm ymm +// VANDPS m256 ymm ymm +// Construct and append a VANDPS instruction to the active function. +func (c *Context) VANDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VANDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDPS xmm xmm xmm +// VANDPS m128 xmm xmm +// VANDPS ymm ymm ymm +// VANDPS m256 ymm ymm +// Construct and append a VANDPS instruction to the active function. +// Operates on the global context. +func VANDPS(mxy, xy, xy1 operand.Op) { ctx.VANDPS(mxy, xy, xy1) } + +// VBLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPD imm8 xmm xmm xmm +// VBLENDPD imm8 m128 xmm xmm +// VBLENDPD imm8 ymm ymm ymm +// VBLENDPD imm8 m256 ymm ymm +// Construct and append a VBLENDPD instruction to the active function. +func (c *Context) VBLENDPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VBLENDPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPD imm8 xmm xmm xmm +// VBLENDPD imm8 m128 xmm xmm +// VBLENDPD imm8 ymm ymm ymm +// VBLENDPD imm8 m256 ymm ymm +// Construct and append a VBLENDPD instruction to the active function. +// Operates on the global context. +func VBLENDPD(i, mxy, xy, xy1 operand.Op) { ctx.VBLENDPD(i, mxy, xy, xy1) } + +// VBLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPS imm8 xmm xmm xmm +// VBLENDPS imm8 m128 xmm xmm +// VBLENDPS imm8 ymm ymm ymm +// VBLENDPS imm8 m256 ymm ymm +// Construct and append a VBLENDPS instruction to the active function. +func (c *Context) VBLENDPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VBLENDPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPS imm8 xmm xmm xmm +// VBLENDPS imm8 m128 xmm xmm +// VBLENDPS imm8 ymm ymm ymm +// VBLENDPS imm8 m256 ymm ymm +// Construct and append a VBLENDPS instruction to the active function. +// Operates on the global context. +func VBLENDPS(i, mxy, xy, xy1 operand.Op) { ctx.VBLENDPS(i, mxy, xy, xy1) } + +// VBLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPD xmm xmm xmm xmm +// VBLENDVPD xmm m128 xmm xmm +// VBLENDVPD ymm ymm ymm ymm +// VBLENDVPD ymm m256 ymm ymm +// Construct and append a VBLENDVPD instruction to the active function. +func (c *Context) VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VBLENDVPD(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPD xmm xmm xmm xmm +// VBLENDVPD xmm m128 xmm xmm +// VBLENDVPD ymm ymm ymm ymm +// VBLENDVPD ymm m256 ymm ymm +// Construct and append a VBLENDVPD instruction to the active function. +// Operates on the global context. +func VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) { ctx.VBLENDVPD(xy, mxy, xy1, xy2) } + +// VBLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPS xmm xmm xmm xmm +// VBLENDVPS xmm m128 xmm xmm +// VBLENDVPS ymm ymm ymm ymm +// VBLENDVPS ymm m256 ymm ymm +// Construct and append a VBLENDVPS instruction to the active function. +func (c *Context) VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VBLENDVPS(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPS xmm xmm xmm xmm +// VBLENDVPS xmm m128 xmm xmm +// VBLENDVPS ymm ymm ymm ymm +// VBLENDVPS ymm m256 ymm ymm +// Construct and append a VBLENDVPS instruction to the active function. +// Operates on the global context. +func VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) { ctx.VBLENDVPS(xy, mxy, xy1, xy2) } + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +// Construct and append a VBROADCASTF128 instruction to the active function. +func (c *Context) VBROADCASTF128(m, y operand.Op) { + if inst, err := x86.VBROADCASTF128(m, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +// Construct and append a VBROADCASTF128 instruction to the active function. +// Operates on the global context. +func VBROADCASTF128(m, y operand.Op) { ctx.VBROADCASTF128(m, y) } + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +// Construct and append a VBROADCASTI128 instruction to the active function. +func (c *Context) VBROADCASTI128(m, y operand.Op) { + if inst, err := x86.VBROADCASTI128(m, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +// Construct and append a VBROADCASTI128 instruction to the active function. +// Operates on the global context. +func VBROADCASTI128(m, y operand.Op) { ctx.VBROADCASTI128(m, y) } + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +// Construct and append a VBROADCASTSD instruction to the active function. +func (c *Context) VBROADCASTSD(mx, y operand.Op) { + if inst, err := x86.VBROADCASTSD(mx, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +// Construct and append a VBROADCASTSD instruction to the active function. +// Operates on the global context. +func VBROADCASTSD(mx, y operand.Op) { ctx.VBROADCASTSD(mx, y) } + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +// Construct and append a VBROADCASTSS instruction to the active function. +func (c *Context) VBROADCASTSS(mx, xy operand.Op) { + if inst, err := x86.VBROADCASTSS(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +// Construct and append a VBROADCASTSS instruction to the active function. +// Operates on the global context. +func VBROADCASTSS(mx, xy operand.Op) { ctx.VBROADCASTSS(mx, xy) } + +// VCMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPD imm8 xmm xmm xmm +// VCMPPD imm8 m128 xmm xmm +// VCMPPD imm8 ymm ymm ymm +// VCMPPD imm8 m256 ymm ymm +// Construct and append a VCMPPD instruction to the active function. +func (c *Context) VCMPPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VCMPPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPD imm8 xmm xmm xmm +// VCMPPD imm8 m128 xmm xmm +// VCMPPD imm8 ymm ymm ymm +// VCMPPD imm8 m256 ymm ymm +// Construct and append a VCMPPD instruction to the active function. +// Operates on the global context. +func VCMPPD(i, mxy, xy, xy1 operand.Op) { ctx.VCMPPD(i, mxy, xy, xy1) } + +// VCMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPS imm8 xmm xmm xmm +// VCMPPS imm8 m128 xmm xmm +// VCMPPS imm8 ymm ymm ymm +// VCMPPS imm8 m256 ymm ymm +// Construct and append a VCMPPS instruction to the active function. +func (c *Context) VCMPPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VCMPPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPS imm8 xmm xmm xmm +// VCMPPS imm8 m128 xmm xmm +// VCMPPS imm8 ymm ymm ymm +// VCMPPS imm8 m256 ymm ymm +// Construct and append a VCMPPS instruction to the active function. +// Operates on the global context. +func VCMPPS(i, mxy, xy, xy1 operand.Op) { ctx.VCMPPS(i, mxy, xy, xy1) } + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +// Construct and append a VCMPSD instruction to the active function. +func (c *Context) VCMPSD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VCMPSD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +// Construct and append a VCMPSD instruction to the active function. +// Operates on the global context. +func VCMPSD(i, mx, x, x1 operand.Op) { ctx.VCMPSD(i, mx, x, x1) } + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +// Construct and append a VCMPSS instruction to the active function. +func (c *Context) VCMPSS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VCMPSS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +// Construct and append a VCMPSS instruction to the active function. +// Operates on the global context. +func VCMPSS(i, mx, x, x1 operand.Op) { ctx.VCMPSS(i, mx, x, x1) } + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +// Construct and append a VCOMISD instruction to the active function. +func (c *Context) VCOMISD(mx, x operand.Op) { + if inst, err := x86.VCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +// Construct and append a VCOMISD instruction to the active function. +// Operates on the global context. +func VCOMISD(mx, x operand.Op) { ctx.VCOMISD(mx, x) } + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +// Construct and append a VCOMISS instruction to the active function. +func (c *Context) VCOMISS(mx, x operand.Op) { + if inst, err := x86.VCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +// Construct and append a VCOMISS instruction to the active function. +// Operates on the global context. +func VCOMISS(mx, x operand.Op) { ctx.VCOMISS(mx, x) } + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +// Construct and append a VCVTDQ2PD instruction to the active function. +func (c *Context) VCVTDQ2PD(mx, xy operand.Op) { + if inst, err := x86.VCVTDQ2PD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +// Construct and append a VCVTDQ2PD instruction to the active function. +// Operates on the global context. +func VCVTDQ2PD(mx, xy operand.Op) { ctx.VCVTDQ2PD(mx, xy) } + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +// Construct and append a VCVTDQ2PS instruction to the active function. +func (c *Context) VCVTDQ2PS(mxy, xy operand.Op) { + if inst, err := x86.VCVTDQ2PS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +// Construct and append a VCVTDQ2PS instruction to the active function. +// Operates on the global context. +func VCVTDQ2PS(mxy, xy operand.Op) { ctx.VCVTDQ2PS(mxy, xy) } + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +// Construct and append a VCVTPD2DQX instruction to the active function. +func (c *Context) VCVTPD2DQX(mx, x operand.Op) { + if inst, err := x86.VCVTPD2DQX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +// Construct and append a VCVTPD2DQX instruction to the active function. +// Operates on the global context. +func VCVTPD2DQX(mx, x operand.Op) { ctx.VCVTPD2DQX(mx, x) } + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +// Construct and append a VCVTPD2DQY instruction to the active function. +func (c *Context) VCVTPD2DQY(my, x operand.Op) { + if inst, err := x86.VCVTPD2DQY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +// Construct and append a VCVTPD2DQY instruction to the active function. +// Operates on the global context. +func VCVTPD2DQY(my, x operand.Op) { ctx.VCVTPD2DQY(my, x) } + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +// Construct and append a VCVTPD2PSX instruction to the active function. +func (c *Context) VCVTPD2PSX(mx, x operand.Op) { + if inst, err := x86.VCVTPD2PSX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +// Construct and append a VCVTPD2PSX instruction to the active function. +// Operates on the global context. +func VCVTPD2PSX(mx, x operand.Op) { ctx.VCVTPD2PSX(mx, x) } + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +// Construct and append a VCVTPD2PSY instruction to the active function. +func (c *Context) VCVTPD2PSY(my, x operand.Op) { + if inst, err := x86.VCVTPD2PSY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +// Construct and append a VCVTPD2PSY instruction to the active function. +// Operates on the global context. +func VCVTPD2PSY(my, x operand.Op) { ctx.VCVTPD2PSY(my, x) } + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +// Construct and append a VCVTPH2PS instruction to the active function. +func (c *Context) VCVTPH2PS(mx, xy operand.Op) { + if inst, err := x86.VCVTPH2PS(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +// Construct and append a VCVTPH2PS instruction to the active function. +// Operates on the global context. +func VCVTPH2PS(mx, xy operand.Op) { ctx.VCVTPH2PS(mx, xy) } + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +// Construct and append a VCVTPS2DQ instruction to the active function. +func (c *Context) VCVTPS2DQ(mxy, xy operand.Op) { + if inst, err := x86.VCVTPS2DQ(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +// Construct and append a VCVTPS2DQ instruction to the active function. +// Operates on the global context. +func VCVTPS2DQ(mxy, xy operand.Op) { ctx.VCVTPS2DQ(mxy, xy) } + +// VCVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTPS2PD xmm xmm +// VCVTPS2PD m64 xmm +// VCVTPS2PD xmm ymm +// VCVTPS2PD m128 ymm +// Construct and append a VCVTPS2PD instruction to the active function. +func (c *Context) VCVTPS2PD(mx, xy operand.Op) { + if inst, err := x86.VCVTPS2PD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTPS2PD xmm xmm +// VCVTPS2PD m64 xmm +// VCVTPS2PD xmm ymm +// VCVTPS2PD m128 ymm +// Construct and append a VCVTPS2PD instruction to the active function. +// Operates on the global context. +func VCVTPS2PD(mx, xy operand.Op) { ctx.VCVTPS2PD(mx, xy) } + +// VCVTPS2PH: Convert Single-Precision FP value to Half-Precision FP value. +// +// Forms: +// +// VCVTPS2PH imm8 xmm xmm +// VCVTPS2PH imm8 ymm xmm +// VCVTPS2PH imm8 xmm m64 +// VCVTPS2PH imm8 ymm m128 +// Construct and append a VCVTPS2PH instruction to the active function. +func (c *Context) VCVTPS2PH(i, xy, mx operand.Op) { + if inst, err := x86.VCVTPS2PH(i, xy, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTPS2PH: Convert Single-Precision FP value to Half-Precision FP value. +// +// Forms: +// +// VCVTPS2PH imm8 xmm xmm +// VCVTPS2PH imm8 ymm xmm +// VCVTPS2PH imm8 xmm m64 +// VCVTPS2PH imm8 ymm m128 +// Construct and append a VCVTPS2PH instruction to the active function. +// Operates on the global context. +func VCVTPS2PH(i, xy, mx operand.Op) { ctx.VCVTPS2PH(i, xy, mx) } + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +// Construct and append a VCVTSD2SI instruction to the active function. +func (c *Context) VCVTSD2SI(mx, r operand.Op) { + if inst, err := x86.VCVTSD2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +// Construct and append a VCVTSD2SI instruction to the active function. +// Operates on the global context. +func VCVTSD2SI(mx, r operand.Op) { ctx.VCVTSD2SI(mx, r) } + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +// Construct and append a VCVTSD2SIQ instruction to the active function. +func (c *Context) VCVTSD2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTSD2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +// Construct and append a VCVTSD2SIQ instruction to the active function. +// Operates on the global context. +func VCVTSD2SIQ(mx, r operand.Op) { ctx.VCVTSD2SIQ(mx, r) } + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +// Construct and append a VCVTSD2SS instruction to the active function. +func (c *Context) VCVTSD2SS(mx, x, x1 operand.Op) { + if inst, err := x86.VCVTSD2SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +// Construct and append a VCVTSD2SS instruction to the active function. +// Operates on the global context. +func VCVTSD2SS(mx, x, x1 operand.Op) { ctx.VCVTSD2SS(mx, x, x1) } + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +// Construct and append a VCVTSI2SDL instruction to the active function. +func (c *Context) VCVTSI2SDL(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SDL(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +// Construct and append a VCVTSI2SDL instruction to the active function. +// Operates on the global context. +func VCVTSI2SDL(mr, x, x1 operand.Op) { ctx.VCVTSI2SDL(mr, x, x1) } + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +// Construct and append a VCVTSI2SDQ instruction to the active function. +func (c *Context) VCVTSI2SDQ(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SDQ(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +// Construct and append a VCVTSI2SDQ instruction to the active function. +// Operates on the global context. +func VCVTSI2SDQ(mr, x, x1 operand.Op) { ctx.VCVTSI2SDQ(mr, x, x1) } + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +// Construct and append a VCVTSI2SSL instruction to the active function. +func (c *Context) VCVTSI2SSL(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SSL(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +// Construct and append a VCVTSI2SSL instruction to the active function. +// Operates on the global context. +func VCVTSI2SSL(mr, x, x1 operand.Op) { ctx.VCVTSI2SSL(mr, x, x1) } + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +// Construct and append a VCVTSI2SSQ instruction to the active function. +func (c *Context) VCVTSI2SSQ(mr, x, x1 operand.Op) { + if inst, err := x86.VCVTSI2SSQ(mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +// Construct and append a VCVTSI2SSQ instruction to the active function. +// Operates on the global context. +func VCVTSI2SSQ(mr, x, x1 operand.Op) { ctx.VCVTSI2SSQ(mr, x, x1) } + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +// Construct and append a VCVTSS2SD instruction to the active function. +func (c *Context) VCVTSS2SD(mx, x, x1 operand.Op) { + if inst, err := x86.VCVTSS2SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +// Construct and append a VCVTSS2SD instruction to the active function. +// Operates on the global context. +func VCVTSS2SD(mx, x, x1 operand.Op) { ctx.VCVTSS2SD(mx, x, x1) } + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +// Construct and append a VCVTSS2SI instruction to the active function. +func (c *Context) VCVTSS2SI(mx, r operand.Op) { + if inst, err := x86.VCVTSS2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +// Construct and append a VCVTSS2SI instruction to the active function. +// Operates on the global context. +func VCVTSS2SI(mx, r operand.Op) { ctx.VCVTSS2SI(mx, r) } + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +// Construct and append a VCVTSS2SIQ instruction to the active function. +func (c *Context) VCVTSS2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTSS2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +// Construct and append a VCVTSS2SIQ instruction to the active function. +// Operates on the global context. +func VCVTSS2SIQ(mx, r operand.Op) { ctx.VCVTSS2SIQ(mx, r) } + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +// Construct and append a VCVTTPD2DQX instruction to the active function. +func (c *Context) VCVTTPD2DQX(mx, x operand.Op) { + if inst, err := x86.VCVTTPD2DQX(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +// Construct and append a VCVTTPD2DQX instruction to the active function. +// Operates on the global context. +func VCVTTPD2DQX(mx, x operand.Op) { ctx.VCVTTPD2DQX(mx, x) } + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +// Construct and append a VCVTTPD2DQY instruction to the active function. +func (c *Context) VCVTTPD2DQY(my, x operand.Op) { + if inst, err := x86.VCVTTPD2DQY(my, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +// Construct and append a VCVTTPD2DQY instruction to the active function. +// Operates on the global context. +func VCVTTPD2DQY(my, x operand.Op) { ctx.VCVTTPD2DQY(my, x) } + +// VCVTTPS2DQ: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPS2DQ xmm xmm +// VCVTTPS2DQ m128 xmm +// VCVTTPS2DQ ymm ymm +// VCVTTPS2DQ m256 ymm +// Construct and append a VCVTTPS2DQ instruction to the active function. +func (c *Context) VCVTTPS2DQ(mxy, xy operand.Op) { + if inst, err := x86.VCVTTPS2DQ(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTPS2DQ: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPS2DQ xmm xmm +// VCVTTPS2DQ m128 xmm +// VCVTTPS2DQ ymm ymm +// VCVTTPS2DQ m256 ymm +// Construct and append a VCVTTPS2DQ instruction to the active function. +// Operates on the global context. +func VCVTTPS2DQ(mxy, xy operand.Op) { ctx.VCVTTPS2DQ(mxy, xy) } + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +// Construct and append a VCVTTSD2SI instruction to the active function. +func (c *Context) VCVTTSD2SI(mx, r operand.Op) { + if inst, err := x86.VCVTTSD2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +// Construct and append a VCVTTSD2SI instruction to the active function. +// Operates on the global context. +func VCVTTSD2SI(mx, r operand.Op) { ctx.VCVTTSD2SI(mx, r) } + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +// Construct and append a VCVTTSD2SIQ instruction to the active function. +func (c *Context) VCVTTSD2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTTSD2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +// Construct and append a VCVTTSD2SIQ instruction to the active function. +// Operates on the global context. +func VCVTTSD2SIQ(mx, r operand.Op) { ctx.VCVTTSD2SIQ(mx, r) } + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +// Construct and append a VCVTTSS2SI instruction to the active function. +func (c *Context) VCVTTSS2SI(mx, r operand.Op) { + if inst, err := x86.VCVTTSS2SI(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +// Construct and append a VCVTTSS2SI instruction to the active function. +// Operates on the global context. +func VCVTTSS2SI(mx, r operand.Op) { ctx.VCVTTSS2SI(mx, r) } + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +// Construct and append a VCVTTSS2SIQ instruction to the active function. +func (c *Context) VCVTTSS2SIQ(mx, r operand.Op) { + if inst, err := x86.VCVTTSS2SIQ(mx, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +// Construct and append a VCVTTSS2SIQ instruction to the active function. +// Operates on the global context. +func VCVTTSS2SIQ(mx, r operand.Op) { ctx.VCVTTSS2SIQ(mx, r) } + +// VDIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPD xmm xmm xmm +// VDIVPD m128 xmm xmm +// VDIVPD ymm ymm ymm +// VDIVPD m256 ymm ymm +// Construct and append a VDIVPD instruction to the active function. +func (c *Context) VDIVPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDIVPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPD xmm xmm xmm +// VDIVPD m128 xmm xmm +// VDIVPD ymm ymm ymm +// VDIVPD m256 ymm ymm +// Construct and append a VDIVPD instruction to the active function. +// Operates on the global context. +func VDIVPD(mxy, xy, xy1 operand.Op) { ctx.VDIVPD(mxy, xy, xy1) } + +// VDIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPS xmm xmm xmm +// VDIVPS m128 xmm xmm +// VDIVPS ymm ymm ymm +// VDIVPS m256 ymm ymm +// Construct and append a VDIVPS instruction to the active function. +func (c *Context) VDIVPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDIVPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPS xmm xmm xmm +// VDIVPS m128 xmm xmm +// VDIVPS ymm ymm ymm +// VDIVPS m256 ymm ymm +// Construct and append a VDIVPS instruction to the active function. +// Operates on the global context. +func VDIVPS(mxy, xy, xy1 operand.Op) { ctx.VDIVPS(mxy, xy, xy1) } + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +// Construct and append a VDIVSD instruction to the active function. +func (c *Context) VDIVSD(mx, x, x1 operand.Op) { + if inst, err := x86.VDIVSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +// Construct and append a VDIVSD instruction to the active function. +// Operates on the global context. +func VDIVSD(mx, x, x1 operand.Op) { ctx.VDIVSD(mx, x, x1) } + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +// Construct and append a VDIVSS instruction to the active function. +func (c *Context) VDIVSS(mx, x, x1 operand.Op) { + if inst, err := x86.VDIVSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +// Construct and append a VDIVSS instruction to the active function. +// Operates on the global context. +func VDIVSS(mx, x, x1 operand.Op) { ctx.VDIVSS(mx, x, x1) } + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +// Construct and append a VDPPD instruction to the active function. +func (c *Context) VDPPD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VDPPD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +// Construct and append a VDPPD instruction to the active function. +// Operates on the global context. +func VDPPD(i, mx, x, x1 operand.Op) { ctx.VDPPD(i, mx, x, x1) } + +// VDPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VDPPS imm8 xmm xmm xmm +// VDPPS imm8 m128 xmm xmm +// VDPPS imm8 ymm ymm ymm +// VDPPS imm8 m256 ymm ymm +// Construct and append a VDPPS instruction to the active function. +func (c *Context) VDPPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VDPPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VDPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VDPPS imm8 xmm xmm xmm +// VDPPS imm8 m128 xmm xmm +// VDPPS imm8 ymm ymm ymm +// VDPPS imm8 m256 ymm ymm +// Construct and append a VDPPS instruction to the active function. +// Operates on the global context. +func VDPPS(i, mxy, xy, xy1 operand.Op) { ctx.VDPPS(i, mxy, xy, xy1) } + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +// Construct and append a VEXTRACTF128 instruction to the active function. +func (c *Context) VEXTRACTF128(i, y, mx operand.Op) { + if inst, err := x86.VEXTRACTF128(i, y, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +// Construct and append a VEXTRACTF128 instruction to the active function. +// Operates on the global context. +func VEXTRACTF128(i, y, mx operand.Op) { ctx.VEXTRACTF128(i, y, mx) } + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +// Construct and append a VEXTRACTI128 instruction to the active function. +func (c *Context) VEXTRACTI128(i, y, mx operand.Op) { + if inst, err := x86.VEXTRACTI128(i, y, mx); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +// Construct and append a VEXTRACTI128 instruction to the active function. +// Operates on the global context. +func VEXTRACTI128(i, y, mx operand.Op) { ctx.VEXTRACTI128(i, y, mx) } + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +// Construct and append a VEXTRACTPS instruction to the active function. +func (c *Context) VEXTRACTPS(i, x, mr operand.Op) { + if inst, err := x86.VEXTRACTPS(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +// Construct and append a VEXTRACTPS instruction to the active function. +// Operates on the global context. +func VEXTRACTPS(i, x, mr operand.Op) { ctx.VEXTRACTPS(i, x, mr) } + +// VFMADD132PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PD xmm xmm xmm +// VFMADD132PD m128 xmm xmm +// VFMADD132PD ymm ymm ymm +// VFMADD132PD m256 ymm ymm +// Construct and append a VFMADD132PD instruction to the active function. +func (c *Context) VFMADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PD xmm xmm xmm +// VFMADD132PD m128 xmm xmm +// VFMADD132PD ymm ymm ymm +// VFMADD132PD m256 ymm ymm +// Construct and append a VFMADD132PD instruction to the active function. +// Operates on the global context. +func VFMADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD132PD(mxy, xy, xy1) } + +// VFMADD132PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PS xmm xmm xmm +// VFMADD132PS m128 xmm xmm +// VFMADD132PS ymm ymm ymm +// VFMADD132PS m256 ymm ymm +// Construct and append a VFMADD132PS instruction to the active function. +func (c *Context) VFMADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PS xmm xmm xmm +// VFMADD132PS m128 xmm xmm +// VFMADD132PS ymm ymm ymm +// VFMADD132PS m256 ymm ymm +// Construct and append a VFMADD132PS instruction to the active function. +// Operates on the global context. +func VFMADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD132PS(mxy, xy, xy1) } + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +// Construct and append a VFMADD132SD instruction to the active function. +func (c *Context) VFMADD132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +// Construct and append a VFMADD132SD instruction to the active function. +// Operates on the global context. +func VFMADD132SD(mx, x, x1 operand.Op) { ctx.VFMADD132SD(mx, x, x1) } + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +// Construct and append a VFMADD132SS instruction to the active function. +func (c *Context) VFMADD132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +// Construct and append a VFMADD132SS instruction to the active function. +// Operates on the global context. +func VFMADD132SS(mx, x, x1 operand.Op) { ctx.VFMADD132SS(mx, x, x1) } + +// VFMADD213PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PD xmm xmm xmm +// VFMADD213PD m128 xmm xmm +// VFMADD213PD ymm ymm ymm +// VFMADD213PD m256 ymm ymm +// Construct and append a VFMADD213PD instruction to the active function. +func (c *Context) VFMADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PD xmm xmm xmm +// VFMADD213PD m128 xmm xmm +// VFMADD213PD ymm ymm ymm +// VFMADD213PD m256 ymm ymm +// Construct and append a VFMADD213PD instruction to the active function. +// Operates on the global context. +func VFMADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD213PD(mxy, xy, xy1) } + +// VFMADD213PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PS xmm xmm xmm +// VFMADD213PS m128 xmm xmm +// VFMADD213PS ymm ymm ymm +// VFMADD213PS m256 ymm ymm +// Construct and append a VFMADD213PS instruction to the active function. +func (c *Context) VFMADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PS xmm xmm xmm +// VFMADD213PS m128 xmm xmm +// VFMADD213PS ymm ymm ymm +// VFMADD213PS m256 ymm ymm +// Construct and append a VFMADD213PS instruction to the active function. +// Operates on the global context. +func VFMADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD213PS(mxy, xy, xy1) } + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +// Construct and append a VFMADD213SD instruction to the active function. +func (c *Context) VFMADD213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +// Construct and append a VFMADD213SD instruction to the active function. +// Operates on the global context. +func VFMADD213SD(mx, x, x1 operand.Op) { ctx.VFMADD213SD(mx, x, x1) } + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +// Construct and append a VFMADD213SS instruction to the active function. +func (c *Context) VFMADD213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +// Construct and append a VFMADD213SS instruction to the active function. +// Operates on the global context. +func VFMADD213SS(mx, x, x1 operand.Op) { ctx.VFMADD213SS(mx, x, x1) } + +// VFMADD231PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PD xmm xmm xmm +// VFMADD231PD m128 xmm xmm +// VFMADD231PD ymm ymm ymm +// VFMADD231PD m256 ymm ymm +// Construct and append a VFMADD231PD instruction to the active function. +func (c *Context) VFMADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PD xmm xmm xmm +// VFMADD231PD m128 xmm xmm +// VFMADD231PD ymm ymm ymm +// VFMADD231PD m256 ymm ymm +// Construct and append a VFMADD231PD instruction to the active function. +// Operates on the global context. +func VFMADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFMADD231PD(mxy, xy, xy1) } + +// VFMADD231PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PS xmm xmm xmm +// VFMADD231PS m128 xmm xmm +// VFMADD231PS ymm ymm ymm +// VFMADD231PS m256 ymm ymm +// Construct and append a VFMADD231PS instruction to the active function. +func (c *Context) VFMADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PS xmm xmm xmm +// VFMADD231PS m128 xmm xmm +// VFMADD231PS ymm ymm ymm +// VFMADD231PS m256 ymm ymm +// Construct and append a VFMADD231PS instruction to the active function. +// Operates on the global context. +func VFMADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFMADD231PS(mxy, xy, xy1) } + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +// Construct and append a VFMADD231SD instruction to the active function. +func (c *Context) VFMADD231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +// Construct and append a VFMADD231SD instruction to the active function. +// Operates on the global context. +func VFMADD231SD(mx, x, x1 operand.Op) { ctx.VFMADD231SD(mx, x, x1) } + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +// Construct and append a VFMADD231SS instruction to the active function. +func (c *Context) VFMADD231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMADD231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +// Construct and append a VFMADD231SS instruction to the active function. +// Operates on the global context. +func VFMADD231SS(mx, x, x1 operand.Op) { ctx.VFMADD231SS(mx, x, x1) } + +// VFMADDSUB132PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PD xmm xmm xmm +// VFMADDSUB132PD m128 xmm xmm +// VFMADDSUB132PD ymm ymm ymm +// VFMADDSUB132PD m256 ymm ymm +// Construct and append a VFMADDSUB132PD instruction to the active function. +func (c *Context) VFMADDSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB132PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PD xmm xmm xmm +// VFMADDSUB132PD m128 xmm xmm +// VFMADDSUB132PD ymm ymm ymm +// VFMADDSUB132PD m256 ymm ymm +// Construct and append a VFMADDSUB132PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB132PD(mxy, xy, xy1) } + +// VFMADDSUB132PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PS xmm xmm xmm +// VFMADDSUB132PS m128 xmm xmm +// VFMADDSUB132PS ymm ymm ymm +// VFMADDSUB132PS m256 ymm ymm +// Construct and append a VFMADDSUB132PS instruction to the active function. +func (c *Context) VFMADDSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB132PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PS xmm xmm xmm +// VFMADDSUB132PS m128 xmm xmm +// VFMADDSUB132PS ymm ymm ymm +// VFMADDSUB132PS m256 ymm ymm +// Construct and append a VFMADDSUB132PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB132PS(mxy, xy, xy1) } + +// VFMADDSUB213PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PD xmm xmm xmm +// VFMADDSUB213PD m128 xmm xmm +// VFMADDSUB213PD ymm ymm ymm +// VFMADDSUB213PD m256 ymm ymm +// Construct and append a VFMADDSUB213PD instruction to the active function. +func (c *Context) VFMADDSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB213PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PD xmm xmm xmm +// VFMADDSUB213PD m128 xmm xmm +// VFMADDSUB213PD ymm ymm ymm +// VFMADDSUB213PD m256 ymm ymm +// Construct and append a VFMADDSUB213PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB213PD(mxy, xy, xy1) } + +// VFMADDSUB213PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PS xmm xmm xmm +// VFMADDSUB213PS m128 xmm xmm +// VFMADDSUB213PS ymm ymm ymm +// VFMADDSUB213PS m256 ymm ymm +// Construct and append a VFMADDSUB213PS instruction to the active function. +func (c *Context) VFMADDSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB213PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PS xmm xmm xmm +// VFMADDSUB213PS m128 xmm xmm +// VFMADDSUB213PS ymm ymm ymm +// VFMADDSUB213PS m256 ymm ymm +// Construct and append a VFMADDSUB213PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB213PS(mxy, xy, xy1) } + +// VFMADDSUB231PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PD xmm xmm xmm +// VFMADDSUB231PD m128 xmm xmm +// VFMADDSUB231PD ymm ymm ymm +// VFMADDSUB231PD m256 ymm ymm +// Construct and append a VFMADDSUB231PD instruction to the active function. +func (c *Context) VFMADDSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB231PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PD xmm xmm xmm +// VFMADDSUB231PD m128 xmm xmm +// VFMADDSUB231PD ymm ymm ymm +// VFMADDSUB231PD m256 ymm ymm +// Construct and append a VFMADDSUB231PD instruction to the active function. +// Operates on the global context. +func VFMADDSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB231PD(mxy, xy, xy1) } + +// VFMADDSUB231PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PS xmm xmm xmm +// VFMADDSUB231PS m128 xmm xmm +// VFMADDSUB231PS ymm ymm ymm +// VFMADDSUB231PS m256 ymm ymm +// Construct and append a VFMADDSUB231PS instruction to the active function. +func (c *Context) VFMADDSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMADDSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMADDSUB231PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PS xmm xmm xmm +// VFMADDSUB231PS m128 xmm xmm +// VFMADDSUB231PS ymm ymm ymm +// VFMADDSUB231PS m256 ymm ymm +// Construct and append a VFMADDSUB231PS instruction to the active function. +// Operates on the global context. +func VFMADDSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFMADDSUB231PS(mxy, xy, xy1) } + +// VFMSUB132PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PD xmm xmm xmm +// VFMSUB132PD m128 xmm xmm +// VFMSUB132PD ymm ymm ymm +// VFMSUB132PD m256 ymm ymm +// Construct and append a VFMSUB132PD instruction to the active function. +func (c *Context) VFMSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PD xmm xmm xmm +// VFMSUB132PD m128 xmm xmm +// VFMSUB132PD ymm ymm ymm +// VFMSUB132PD m256 ymm ymm +// Construct and append a VFMSUB132PD instruction to the active function. +// Operates on the global context. +func VFMSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB132PD(mxy, xy, xy1) } + +// VFMSUB132PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PS xmm xmm xmm +// VFMSUB132PS m128 xmm xmm +// VFMSUB132PS ymm ymm ymm +// VFMSUB132PS m256 ymm ymm +// Construct and append a VFMSUB132PS instruction to the active function. +func (c *Context) VFMSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PS xmm xmm xmm +// VFMSUB132PS m128 xmm xmm +// VFMSUB132PS ymm ymm ymm +// VFMSUB132PS m256 ymm ymm +// Construct and append a VFMSUB132PS instruction to the active function. +// Operates on the global context. +func VFMSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB132PS(mxy, xy, xy1) } + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +// Construct and append a VFMSUB132SD instruction to the active function. +func (c *Context) VFMSUB132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +// Construct and append a VFMSUB132SD instruction to the active function. +// Operates on the global context. +func VFMSUB132SD(mx, x, x1 operand.Op) { ctx.VFMSUB132SD(mx, x, x1) } + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +// Construct and append a VFMSUB132SS instruction to the active function. +func (c *Context) VFMSUB132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +// Construct and append a VFMSUB132SS instruction to the active function. +// Operates on the global context. +func VFMSUB132SS(mx, x, x1 operand.Op) { ctx.VFMSUB132SS(mx, x, x1) } + +// VFMSUB213PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PD xmm xmm xmm +// VFMSUB213PD m128 xmm xmm +// VFMSUB213PD ymm ymm ymm +// VFMSUB213PD m256 ymm ymm +// Construct and append a VFMSUB213PD instruction to the active function. +func (c *Context) VFMSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PD xmm xmm xmm +// VFMSUB213PD m128 xmm xmm +// VFMSUB213PD ymm ymm ymm +// VFMSUB213PD m256 ymm ymm +// Construct and append a VFMSUB213PD instruction to the active function. +// Operates on the global context. +func VFMSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB213PD(mxy, xy, xy1) } + +// VFMSUB213PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PS xmm xmm xmm +// VFMSUB213PS m128 xmm xmm +// VFMSUB213PS ymm ymm ymm +// VFMSUB213PS m256 ymm ymm +// Construct and append a VFMSUB213PS instruction to the active function. +func (c *Context) VFMSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PS xmm xmm xmm +// VFMSUB213PS m128 xmm xmm +// VFMSUB213PS ymm ymm ymm +// VFMSUB213PS m256 ymm ymm +// Construct and append a VFMSUB213PS instruction to the active function. +// Operates on the global context. +func VFMSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB213PS(mxy, xy, xy1) } + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +// Construct and append a VFMSUB213SD instruction to the active function. +func (c *Context) VFMSUB213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +// Construct and append a VFMSUB213SD instruction to the active function. +// Operates on the global context. +func VFMSUB213SD(mx, x, x1 operand.Op) { ctx.VFMSUB213SD(mx, x, x1) } + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +// Construct and append a VFMSUB213SS instruction to the active function. +func (c *Context) VFMSUB213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +// Construct and append a VFMSUB213SS instruction to the active function. +// Operates on the global context. +func VFMSUB213SS(mx, x, x1 operand.Op) { ctx.VFMSUB213SS(mx, x, x1) } + +// VFMSUB231PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PD xmm xmm xmm +// VFMSUB231PD m128 xmm xmm +// VFMSUB231PD ymm ymm ymm +// VFMSUB231PD m256 ymm ymm +// Construct and append a VFMSUB231PD instruction to the active function. +func (c *Context) VFMSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PD xmm xmm xmm +// VFMSUB231PD m128 xmm xmm +// VFMSUB231PD ymm ymm ymm +// VFMSUB231PD m256 ymm ymm +// Construct and append a VFMSUB231PD instruction to the active function. +// Operates on the global context. +func VFMSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUB231PD(mxy, xy, xy1) } + +// VFMSUB231PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PS xmm xmm xmm +// VFMSUB231PS m128 xmm xmm +// VFMSUB231PS ymm ymm ymm +// VFMSUB231PS m256 ymm ymm +// Construct and append a VFMSUB231PS instruction to the active function. +func (c *Context) VFMSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PS xmm xmm xmm +// VFMSUB231PS m128 xmm xmm +// VFMSUB231PS ymm ymm ymm +// VFMSUB231PS m256 ymm ymm +// Construct and append a VFMSUB231PS instruction to the active function. +// Operates on the global context. +func VFMSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUB231PS(mxy, xy, xy1) } + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +// Construct and append a VFMSUB231SD instruction to the active function. +func (c *Context) VFMSUB231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +// Construct and append a VFMSUB231SD instruction to the active function. +// Operates on the global context. +func VFMSUB231SD(mx, x, x1 operand.Op) { ctx.VFMSUB231SD(mx, x, x1) } + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +// Construct and append a VFMSUB231SS instruction to the active function. +func (c *Context) VFMSUB231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFMSUB231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +// Construct and append a VFMSUB231SS instruction to the active function. +// Operates on the global context. +func VFMSUB231SS(mx, x, x1 operand.Op) { ctx.VFMSUB231SS(mx, x, x1) } + +// VFMSUBADD132PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PD xmm xmm xmm +// VFMSUBADD132PD m128 xmm xmm +// VFMSUBADD132PD ymm ymm ymm +// VFMSUBADD132PD m256 ymm ymm +// Construct and append a VFMSUBADD132PD instruction to the active function. +func (c *Context) VFMSUBADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD132PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PD xmm xmm xmm +// VFMSUBADD132PD m128 xmm xmm +// VFMSUBADD132PD ymm ymm ymm +// VFMSUBADD132PD m256 ymm ymm +// Construct and append a VFMSUBADD132PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD132PD(mxy, xy, xy1) } + +// VFMSUBADD132PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PS xmm xmm xmm +// VFMSUBADD132PS m128 xmm xmm +// VFMSUBADD132PS ymm ymm ymm +// VFMSUBADD132PS m256 ymm ymm +// Construct and append a VFMSUBADD132PS instruction to the active function. +func (c *Context) VFMSUBADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD132PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PS xmm xmm xmm +// VFMSUBADD132PS m128 xmm xmm +// VFMSUBADD132PS ymm ymm ymm +// VFMSUBADD132PS m256 ymm ymm +// Construct and append a VFMSUBADD132PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD132PS(mxy, xy, xy1) } + +// VFMSUBADD213PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PD xmm xmm xmm +// VFMSUBADD213PD m128 xmm xmm +// VFMSUBADD213PD ymm ymm ymm +// VFMSUBADD213PD m256 ymm ymm +// Construct and append a VFMSUBADD213PD instruction to the active function. +func (c *Context) VFMSUBADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD213PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PD xmm xmm xmm +// VFMSUBADD213PD m128 xmm xmm +// VFMSUBADD213PD ymm ymm ymm +// VFMSUBADD213PD m256 ymm ymm +// Construct and append a VFMSUBADD213PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD213PD(mxy, xy, xy1) } + +// VFMSUBADD213PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PS xmm xmm xmm +// VFMSUBADD213PS m128 xmm xmm +// VFMSUBADD213PS ymm ymm ymm +// VFMSUBADD213PS m256 ymm ymm +// Construct and append a VFMSUBADD213PS instruction to the active function. +func (c *Context) VFMSUBADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD213PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PS xmm xmm xmm +// VFMSUBADD213PS m128 xmm xmm +// VFMSUBADD213PS ymm ymm ymm +// VFMSUBADD213PS m256 ymm ymm +// Construct and append a VFMSUBADD213PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD213PS(mxy, xy, xy1) } + +// VFMSUBADD231PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PD xmm xmm xmm +// VFMSUBADD231PD m128 xmm xmm +// VFMSUBADD231PD ymm ymm ymm +// VFMSUBADD231PD m256 ymm ymm +// Construct and append a VFMSUBADD231PD instruction to the active function. +func (c *Context) VFMSUBADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD231PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PD xmm xmm xmm +// VFMSUBADD231PD m128 xmm xmm +// VFMSUBADD231PD ymm ymm ymm +// VFMSUBADD231PD m256 ymm ymm +// Construct and append a VFMSUBADD231PD instruction to the active function. +// Operates on the global context. +func VFMSUBADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD231PD(mxy, xy, xy1) } + +// VFMSUBADD231PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PS xmm xmm xmm +// VFMSUBADD231PS m128 xmm xmm +// VFMSUBADD231PS ymm ymm ymm +// VFMSUBADD231PS m256 ymm ymm +// Construct and append a VFMSUBADD231PS instruction to the active function. +func (c *Context) VFMSUBADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFMSUBADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFMSUBADD231PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PS xmm xmm xmm +// VFMSUBADD231PS m128 xmm xmm +// VFMSUBADD231PS ymm ymm ymm +// VFMSUBADD231PS m256 ymm ymm +// Construct and append a VFMSUBADD231PS instruction to the active function. +// Operates on the global context. +func VFMSUBADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFMSUBADD231PS(mxy, xy, xy1) } + +// VFNMADD132PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PD xmm xmm xmm +// VFNMADD132PD m128 xmm xmm +// VFNMADD132PD ymm ymm ymm +// VFNMADD132PD m256 ymm ymm +// Construct and append a VFNMADD132PD instruction to the active function. +func (c *Context) VFNMADD132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PD xmm xmm xmm +// VFNMADD132PD m128 xmm xmm +// VFNMADD132PD ymm ymm ymm +// VFNMADD132PD m256 ymm ymm +// Construct and append a VFNMADD132PD instruction to the active function. +// Operates on the global context. +func VFNMADD132PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD132PD(mxy, xy, xy1) } + +// VFNMADD132PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PS xmm xmm xmm +// VFNMADD132PS m128 xmm xmm +// VFNMADD132PS ymm ymm ymm +// VFNMADD132PS m256 ymm ymm +// Construct and append a VFNMADD132PS instruction to the active function. +func (c *Context) VFNMADD132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PS xmm xmm xmm +// VFNMADD132PS m128 xmm xmm +// VFNMADD132PS ymm ymm ymm +// VFNMADD132PS m256 ymm ymm +// Construct and append a VFNMADD132PS instruction to the active function. +// Operates on the global context. +func VFNMADD132PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD132PS(mxy, xy, xy1) } + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +// Construct and append a VFNMADD132SD instruction to the active function. +func (c *Context) VFNMADD132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +// Construct and append a VFNMADD132SD instruction to the active function. +// Operates on the global context. +func VFNMADD132SD(mx, x, x1 operand.Op) { ctx.VFNMADD132SD(mx, x, x1) } + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +// Construct and append a VFNMADD132SS instruction to the active function. +func (c *Context) VFNMADD132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +// Construct and append a VFNMADD132SS instruction to the active function. +// Operates on the global context. +func VFNMADD132SS(mx, x, x1 operand.Op) { ctx.VFNMADD132SS(mx, x, x1) } + +// VFNMADD213PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PD xmm xmm xmm +// VFNMADD213PD m128 xmm xmm +// VFNMADD213PD ymm ymm ymm +// VFNMADD213PD m256 ymm ymm +// Construct and append a VFNMADD213PD instruction to the active function. +func (c *Context) VFNMADD213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PD xmm xmm xmm +// VFNMADD213PD m128 xmm xmm +// VFNMADD213PD ymm ymm ymm +// VFNMADD213PD m256 ymm ymm +// Construct and append a VFNMADD213PD instruction to the active function. +// Operates on the global context. +func VFNMADD213PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD213PD(mxy, xy, xy1) } + +// VFNMADD213PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PS xmm xmm xmm +// VFNMADD213PS m128 xmm xmm +// VFNMADD213PS ymm ymm ymm +// VFNMADD213PS m256 ymm ymm +// Construct and append a VFNMADD213PS instruction to the active function. +func (c *Context) VFNMADD213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PS xmm xmm xmm +// VFNMADD213PS m128 xmm xmm +// VFNMADD213PS ymm ymm ymm +// VFNMADD213PS m256 ymm ymm +// Construct and append a VFNMADD213PS instruction to the active function. +// Operates on the global context. +func VFNMADD213PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD213PS(mxy, xy, xy1) } + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +// Construct and append a VFNMADD213SD instruction to the active function. +func (c *Context) VFNMADD213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +// Construct and append a VFNMADD213SD instruction to the active function. +// Operates on the global context. +func VFNMADD213SD(mx, x, x1 operand.Op) { ctx.VFNMADD213SD(mx, x, x1) } + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +// Construct and append a VFNMADD213SS instruction to the active function. +func (c *Context) VFNMADD213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +// Construct and append a VFNMADD213SS instruction to the active function. +// Operates on the global context. +func VFNMADD213SS(mx, x, x1 operand.Op) { ctx.VFNMADD213SS(mx, x, x1) } + +// VFNMADD231PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PD xmm xmm xmm +// VFNMADD231PD m128 xmm xmm +// VFNMADD231PD ymm ymm ymm +// VFNMADD231PD m256 ymm ymm +// Construct and append a VFNMADD231PD instruction to the active function. +func (c *Context) VFNMADD231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PD xmm xmm xmm +// VFNMADD231PD m128 xmm xmm +// VFNMADD231PD ymm ymm ymm +// VFNMADD231PD m256 ymm ymm +// Construct and append a VFNMADD231PD instruction to the active function. +// Operates on the global context. +func VFNMADD231PD(mxy, xy, xy1 operand.Op) { ctx.VFNMADD231PD(mxy, xy, xy1) } + +// VFNMADD231PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PS xmm xmm xmm +// VFNMADD231PS m128 xmm xmm +// VFNMADD231PS ymm ymm ymm +// VFNMADD231PS m256 ymm ymm +// Construct and append a VFNMADD231PS instruction to the active function. +func (c *Context) VFNMADD231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMADD231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PS xmm xmm xmm +// VFNMADD231PS m128 xmm xmm +// VFNMADD231PS ymm ymm ymm +// VFNMADD231PS m256 ymm ymm +// Construct and append a VFNMADD231PS instruction to the active function. +// Operates on the global context. +func VFNMADD231PS(mxy, xy, xy1 operand.Op) { ctx.VFNMADD231PS(mxy, xy, xy1) } + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +// Construct and append a VFNMADD231SD instruction to the active function. +func (c *Context) VFNMADD231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +// Construct and append a VFNMADD231SD instruction to the active function. +// Operates on the global context. +func VFNMADD231SD(mx, x, x1 operand.Op) { ctx.VFNMADD231SD(mx, x, x1) } + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +// Construct and append a VFNMADD231SS instruction to the active function. +func (c *Context) VFNMADD231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMADD231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +// Construct and append a VFNMADD231SS instruction to the active function. +// Operates on the global context. +func VFNMADD231SS(mx, x, x1 operand.Op) { ctx.VFNMADD231SS(mx, x, x1) } + +// VFNMSUB132PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PD xmm xmm xmm +// VFNMSUB132PD m128 xmm xmm +// VFNMSUB132PD ymm ymm ymm +// VFNMSUB132PD m256 ymm ymm +// Construct and append a VFNMSUB132PD instruction to the active function. +func (c *Context) VFNMSUB132PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB132PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PD xmm xmm xmm +// VFNMSUB132PD m128 xmm xmm +// VFNMSUB132PD ymm ymm ymm +// VFNMSUB132PD m256 ymm ymm +// Construct and append a VFNMSUB132PD instruction to the active function. +// Operates on the global context. +func VFNMSUB132PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB132PD(mxy, xy, xy1) } + +// VFNMSUB132PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PS xmm xmm xmm +// VFNMSUB132PS m128 xmm xmm +// VFNMSUB132PS ymm ymm ymm +// VFNMSUB132PS m256 ymm ymm +// Construct and append a VFNMSUB132PS instruction to the active function. +func (c *Context) VFNMSUB132PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB132PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PS xmm xmm xmm +// VFNMSUB132PS m128 xmm xmm +// VFNMSUB132PS ymm ymm ymm +// VFNMSUB132PS m256 ymm ymm +// Construct and append a VFNMSUB132PS instruction to the active function. +// Operates on the global context. +func VFNMSUB132PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB132PS(mxy, xy, xy1) } + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +// Construct and append a VFNMSUB132SD instruction to the active function. +func (c *Context) VFNMSUB132SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB132SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +// Construct and append a VFNMSUB132SD instruction to the active function. +// Operates on the global context. +func VFNMSUB132SD(mx, x, x1 operand.Op) { ctx.VFNMSUB132SD(mx, x, x1) } + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +// Construct and append a VFNMSUB132SS instruction to the active function. +func (c *Context) VFNMSUB132SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB132SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +// Construct and append a VFNMSUB132SS instruction to the active function. +// Operates on the global context. +func VFNMSUB132SS(mx, x, x1 operand.Op) { ctx.VFNMSUB132SS(mx, x, x1) } + +// VFNMSUB213PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PD xmm xmm xmm +// VFNMSUB213PD m128 xmm xmm +// VFNMSUB213PD ymm ymm ymm +// VFNMSUB213PD m256 ymm ymm +// Construct and append a VFNMSUB213PD instruction to the active function. +func (c *Context) VFNMSUB213PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB213PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PD xmm xmm xmm +// VFNMSUB213PD m128 xmm xmm +// VFNMSUB213PD ymm ymm ymm +// VFNMSUB213PD m256 ymm ymm +// Construct and append a VFNMSUB213PD instruction to the active function. +// Operates on the global context. +func VFNMSUB213PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB213PD(mxy, xy, xy1) } + +// VFNMSUB213PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PS xmm xmm xmm +// VFNMSUB213PS m128 xmm xmm +// VFNMSUB213PS ymm ymm ymm +// VFNMSUB213PS m256 ymm ymm +// Construct and append a VFNMSUB213PS instruction to the active function. +func (c *Context) VFNMSUB213PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB213PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PS xmm xmm xmm +// VFNMSUB213PS m128 xmm xmm +// VFNMSUB213PS ymm ymm ymm +// VFNMSUB213PS m256 ymm ymm +// Construct and append a VFNMSUB213PS instruction to the active function. +// Operates on the global context. +func VFNMSUB213PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB213PS(mxy, xy, xy1) } + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +// Construct and append a VFNMSUB213SD instruction to the active function. +func (c *Context) VFNMSUB213SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB213SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +// Construct and append a VFNMSUB213SD instruction to the active function. +// Operates on the global context. +func VFNMSUB213SD(mx, x, x1 operand.Op) { ctx.VFNMSUB213SD(mx, x, x1) } + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +// Construct and append a VFNMSUB213SS instruction to the active function. +func (c *Context) VFNMSUB213SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB213SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +// Construct and append a VFNMSUB213SS instruction to the active function. +// Operates on the global context. +func VFNMSUB213SS(mx, x, x1 operand.Op) { ctx.VFNMSUB213SS(mx, x, x1) } + +// VFNMSUB231PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PD xmm xmm xmm +// VFNMSUB231PD m128 xmm xmm +// VFNMSUB231PD ymm ymm ymm +// VFNMSUB231PD m256 ymm ymm +// Construct and append a VFNMSUB231PD instruction to the active function. +func (c *Context) VFNMSUB231PD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB231PD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PD xmm xmm xmm +// VFNMSUB231PD m128 xmm xmm +// VFNMSUB231PD ymm ymm ymm +// VFNMSUB231PD m256 ymm ymm +// Construct and append a VFNMSUB231PD instruction to the active function. +// Operates on the global context. +func VFNMSUB231PD(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB231PD(mxy, xy, xy1) } + +// VFNMSUB231PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PS xmm xmm xmm +// VFNMSUB231PS m128 xmm xmm +// VFNMSUB231PS ymm ymm ymm +// VFNMSUB231PS m256 ymm ymm +// Construct and append a VFNMSUB231PS instruction to the active function. +func (c *Context) VFNMSUB231PS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VFNMSUB231PS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PS xmm xmm xmm +// VFNMSUB231PS m128 xmm xmm +// VFNMSUB231PS ymm ymm ymm +// VFNMSUB231PS m256 ymm ymm +// Construct and append a VFNMSUB231PS instruction to the active function. +// Operates on the global context. +func VFNMSUB231PS(mxy, xy, xy1 operand.Op) { ctx.VFNMSUB231PS(mxy, xy, xy1) } + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +// Construct and append a VFNMSUB231SD instruction to the active function. +func (c *Context) VFNMSUB231SD(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB231SD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +// Construct and append a VFNMSUB231SD instruction to the active function. +// Operates on the global context. +func VFNMSUB231SD(mx, x, x1 operand.Op) { ctx.VFNMSUB231SD(mx, x, x1) } + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +// Construct and append a VFNMSUB231SS instruction to the active function. +func (c *Context) VFNMSUB231SS(mx, x, x1 operand.Op) { + if inst, err := x86.VFNMSUB231SS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +// Construct and append a VFNMSUB231SS instruction to the active function. +// Operates on the global context. +func VFNMSUB231SS(mx, x, x1 operand.Op) { ctx.VFNMSUB231SS(mx, x, x1) } + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +// Construct and append a VGATHERDPD instruction to the active function. +func (c *Context) VGATHERDPD(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERDPD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +// Construct and append a VGATHERDPD instruction to the active function. +// Operates on the global context. +func VGATHERDPD(xy, v, xy1 operand.Op) { ctx.VGATHERDPD(xy, v, xy1) } + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +// Construct and append a VGATHERDPS instruction to the active function. +func (c *Context) VGATHERDPS(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERDPS(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +// Construct and append a VGATHERDPS instruction to the active function. +// Operates on the global context. +func VGATHERDPS(xy, v, xy1 operand.Op) { ctx.VGATHERDPS(xy, v, xy1) } + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +// Construct and append a VGATHERQPD instruction to the active function. +func (c *Context) VGATHERQPD(xy, v, xy1 operand.Op) { + if inst, err := x86.VGATHERQPD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +// Construct and append a VGATHERQPD instruction to the active function. +// Operates on the global context. +func VGATHERQPD(xy, v, xy1 operand.Op) { ctx.VGATHERQPD(xy, v, xy1) } + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +// Construct and append a VGATHERQPS instruction to the active function. +func (c *Context) VGATHERQPS(x, v, x1 operand.Op) { + if inst, err := x86.VGATHERQPS(x, v, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +// Construct and append a VGATHERQPS instruction to the active function. +// Operates on the global context. +func VGATHERQPS(x, v, x1 operand.Op) { ctx.VGATHERQPS(x, v, x1) } + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +// Construct and append a VHADDPD instruction to the active function. +func (c *Context) VHADDPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHADDPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +// Construct and append a VHADDPD instruction to the active function. +// Operates on the global context. +func VHADDPD(mxy, xy, xy1 operand.Op) { ctx.VHADDPD(mxy, xy, xy1) } + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +// Construct and append a VHADDPS instruction to the active function. +func (c *Context) VHADDPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHADDPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +// Construct and append a VHADDPS instruction to the active function. +// Operates on the global context. +func VHADDPS(mxy, xy, xy1 operand.Op) { ctx.VHADDPS(mxy, xy, xy1) } + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +// Construct and append a VHSUBPD instruction to the active function. +func (c *Context) VHSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +// Construct and append a VHSUBPD instruction to the active function. +// Operates on the global context. +func VHSUBPD(mxy, xy, xy1 operand.Op) { ctx.VHSUBPD(mxy, xy, xy1) } + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +// Construct and append a VHSUBPS instruction to the active function. +func (c *Context) VHSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VHSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +// Construct and append a VHSUBPS instruction to the active function. +// Operates on the global context. +func VHSUBPS(mxy, xy, xy1 operand.Op) { ctx.VHSUBPS(mxy, xy, xy1) } + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +// Construct and append a VINSERTF128 instruction to the active function. +func (c *Context) VINSERTF128(i, mx, y, y1 operand.Op) { + if inst, err := x86.VINSERTF128(i, mx, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +// Construct and append a VINSERTF128 instruction to the active function. +// Operates on the global context. +func VINSERTF128(i, mx, y, y1 operand.Op) { ctx.VINSERTF128(i, mx, y, y1) } + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +// Construct and append a VINSERTI128 instruction to the active function. +func (c *Context) VINSERTI128(i, mx, y, y1 operand.Op) { + if inst, err := x86.VINSERTI128(i, mx, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +// Construct and append a VINSERTI128 instruction to the active function. +// Operates on the global context. +func VINSERTI128(i, mx, y, y1 operand.Op) { ctx.VINSERTI128(i, mx, y, y1) } + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +// Construct and append a VINSERTPS instruction to the active function. +func (c *Context) VINSERTPS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VINSERTPS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +// Construct and append a VINSERTPS instruction to the active function. +// Operates on the global context. +func VINSERTPS(i, mx, x, x1 operand.Op) { ctx.VINSERTPS(i, mx, x, x1) } + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +// Construct and append a VLDDQU instruction to the active function. +func (c *Context) VLDDQU(m, xy operand.Op) { + if inst, err := x86.VLDDQU(m, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +// Construct and append a VLDDQU instruction to the active function. +// Operates on the global context. +func VLDDQU(m, xy operand.Op) { ctx.VLDDQU(m, xy) } + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +// Construct and append a VLDMXCSR instruction to the active function. +func (c *Context) VLDMXCSR(m operand.Op) { + if inst, err := x86.VLDMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +// Construct and append a VLDMXCSR instruction to the active function. +// Operates on the global context. +func VLDMXCSR(m operand.Op) { ctx.VLDMXCSR(m) } + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +// Construct and append a VMASKMOVDQU instruction to the active function. +func (c *Context) VMASKMOVDQU(x, x1 operand.Op) { + if inst, err := x86.VMASKMOVDQU(x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +// Construct and append a VMASKMOVDQU instruction to the active function. +// Operates on the global context. +func VMASKMOVDQU(x, x1 operand.Op) { ctx.VMASKMOVDQU(x, x1) } + +// VMASKMOVPD: Conditional Move Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPD m128 xmm xmm +// VMASKMOVPD m256 ymm ymm +// VMASKMOVPD xmm xmm m128 +// VMASKMOVPD ymm ymm m256 +// Construct and append a VMASKMOVPD instruction to the active function. +func (c *Context) VMASKMOVPD(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VMASKMOVPD(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMASKMOVPD: Conditional Move Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPD m128 xmm xmm +// VMASKMOVPD m256 ymm ymm +// VMASKMOVPD xmm xmm m128 +// VMASKMOVPD ymm ymm m256 +// Construct and append a VMASKMOVPD instruction to the active function. +// Operates on the global context. +func VMASKMOVPD(mxy, xy, mxy1 operand.Op) { ctx.VMASKMOVPD(mxy, xy, mxy1) } + +// VMASKMOVPS: Conditional Move Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPS m128 xmm xmm +// VMASKMOVPS m256 ymm ymm +// VMASKMOVPS xmm xmm m128 +// VMASKMOVPS ymm ymm m256 +// Construct and append a VMASKMOVPS instruction to the active function. +func (c *Context) VMASKMOVPS(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VMASKMOVPS(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMASKMOVPS: Conditional Move Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPS m128 xmm xmm +// VMASKMOVPS m256 ymm ymm +// VMASKMOVPS xmm xmm m128 +// VMASKMOVPS ymm ymm m256 +// Construct and append a VMASKMOVPS instruction to the active function. +// Operates on the global context. +func VMASKMOVPS(mxy, xy, mxy1 operand.Op) { ctx.VMASKMOVPS(mxy, xy, mxy1) } + +// VMAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPD xmm xmm xmm +// VMAXPD m128 xmm xmm +// VMAXPD ymm ymm ymm +// VMAXPD m256 ymm ymm +// Construct and append a VMAXPD instruction to the active function. +func (c *Context) VMAXPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMAXPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPD xmm xmm xmm +// VMAXPD m128 xmm xmm +// VMAXPD ymm ymm ymm +// VMAXPD m256 ymm ymm +// Construct and append a VMAXPD instruction to the active function. +// Operates on the global context. +func VMAXPD(mxy, xy, xy1 operand.Op) { ctx.VMAXPD(mxy, xy, xy1) } + +// VMAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPS xmm xmm xmm +// VMAXPS m128 xmm xmm +// VMAXPS ymm ymm ymm +// VMAXPS m256 ymm ymm +// Construct and append a VMAXPS instruction to the active function. +func (c *Context) VMAXPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMAXPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPS xmm xmm xmm +// VMAXPS m128 xmm xmm +// VMAXPS ymm ymm ymm +// VMAXPS m256 ymm ymm +// Construct and append a VMAXPS instruction to the active function. +// Operates on the global context. +func VMAXPS(mxy, xy, xy1 operand.Op) { ctx.VMAXPS(mxy, xy, xy1) } + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +// Construct and append a VMAXSD instruction to the active function. +func (c *Context) VMAXSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMAXSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +// Construct and append a VMAXSD instruction to the active function. +// Operates on the global context. +func VMAXSD(mx, x, x1 operand.Op) { ctx.VMAXSD(mx, x, x1) } + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +// Construct and append a VMAXSS instruction to the active function. +func (c *Context) VMAXSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMAXSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +// Construct and append a VMAXSS instruction to the active function. +// Operates on the global context. +func VMAXSS(mx, x, x1 operand.Op) { ctx.VMAXSS(mx, x, x1) } + +// VMINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMINPD xmm xmm xmm +// VMINPD m128 xmm xmm +// VMINPD ymm ymm ymm +// VMINPD m256 ymm ymm +// Construct and append a VMINPD instruction to the active function. +func (c *Context) VMINPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMINPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMINPD xmm xmm xmm +// VMINPD m128 xmm xmm +// VMINPD ymm ymm ymm +// VMINPD m256 ymm ymm +// Construct and append a VMINPD instruction to the active function. +// Operates on the global context. +func VMINPD(mxy, xy, xy1 operand.Op) { ctx.VMINPD(mxy, xy, xy1) } + +// VMINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMINPS xmm xmm xmm +// VMINPS m128 xmm xmm +// VMINPS ymm ymm ymm +// VMINPS m256 ymm ymm +// Construct and append a VMINPS instruction to the active function. +func (c *Context) VMINPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMINPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMINPS xmm xmm xmm +// VMINPS m128 xmm xmm +// VMINPS ymm ymm ymm +// VMINPS m256 ymm ymm +// Construct and append a VMINPS instruction to the active function. +// Operates on the global context. +func VMINPS(mxy, xy, xy1 operand.Op) { ctx.VMINPS(mxy, xy, xy1) } + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +// Construct and append a VMINSD instruction to the active function. +func (c *Context) VMINSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMINSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +// Construct and append a VMINSD instruction to the active function. +// Operates on the global context. +func VMINSD(mx, x, x1 operand.Op) { ctx.VMINSD(mx, x, x1) } + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +// Construct and append a VMINSS instruction to the active function. +func (c *Context) VMINSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMINSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +// Construct and append a VMINSS instruction to the active function. +// Operates on the global context. +func VMINSS(mx, x, x1 operand.Op) { ctx.VMINSS(mx, x, x1) } + +// VMOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPD xmm xmm +// VMOVAPD m128 xmm +// VMOVAPD ymm ymm +// VMOVAPD m256 ymm +// VMOVAPD xmm m128 +// VMOVAPD ymm m256 +// Construct and append a VMOVAPD instruction to the active function. +func (c *Context) VMOVAPD(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVAPD(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPD xmm xmm +// VMOVAPD m128 xmm +// VMOVAPD ymm ymm +// VMOVAPD m256 ymm +// VMOVAPD xmm m128 +// VMOVAPD ymm m256 +// Construct and append a VMOVAPD instruction to the active function. +// Operates on the global context. +func VMOVAPD(mxy, mxy1 operand.Op) { ctx.VMOVAPD(mxy, mxy1) } + +// VMOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPS xmm xmm +// VMOVAPS m128 xmm +// VMOVAPS ymm ymm +// VMOVAPS m256 ymm +// VMOVAPS xmm m128 +// VMOVAPS ymm m256 +// Construct and append a VMOVAPS instruction to the active function. +func (c *Context) VMOVAPS(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVAPS(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPS xmm xmm +// VMOVAPS m128 xmm +// VMOVAPS ymm ymm +// VMOVAPS m256 ymm +// VMOVAPS xmm m128 +// VMOVAPS ymm m256 +// Construct and append a VMOVAPS instruction to the active function. +// Operates on the global context. +func VMOVAPS(mxy, mxy1 operand.Op) { ctx.VMOVAPS(mxy, mxy1) } + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +// Construct and append a VMOVD instruction to the active function. +func (c *Context) VMOVD(mrx, mrx1 operand.Op) { + if inst, err := x86.VMOVD(mrx, mrx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +// Construct and append a VMOVD instruction to the active function. +// Operates on the global context. +func VMOVD(mrx, mrx1 operand.Op) { ctx.VMOVD(mrx, mrx1) } + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +// Construct and append a VMOVDDUP instruction to the active function. +func (c *Context) VMOVDDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVDDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +// Construct and append a VMOVDDUP instruction to the active function. +// Operates on the global context. +func VMOVDDUP(mxy, xy operand.Op) { ctx.VMOVDDUP(mxy, xy) } + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +// Construct and append a VMOVDQA instruction to the active function. +func (c *Context) VMOVDQA(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVDQA(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +// Construct and append a VMOVDQA instruction to the active function. +// Operates on the global context. +func VMOVDQA(mxy, mxy1 operand.Op) { ctx.VMOVDQA(mxy, mxy1) } + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +// Construct and append a VMOVDQU instruction to the active function. +func (c *Context) VMOVDQU(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVDQU(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +// Construct and append a VMOVDQU instruction to the active function. +// Operates on the global context. +func VMOVDQU(mxy, mxy1 operand.Op) { ctx.VMOVDQU(mxy, mxy1) } + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +// Construct and append a VMOVHLPS instruction to the active function. +func (c *Context) VMOVHLPS(x, x1, x2 operand.Op) { + if inst, err := x86.VMOVHLPS(x, x1, x2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +// Construct and append a VMOVHLPS instruction to the active function. +// Operates on the global context. +func VMOVHLPS(x, x1, x2 operand.Op) { ctx.VMOVHLPS(x, x1, x2) } + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +// Construct and append a VMOVHPD instruction to the active function. +func (c *Context) VMOVHPD(ops ...operand.Op) { + if inst, err := x86.VMOVHPD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +// Construct and append a VMOVHPD instruction to the active function. +// Operates on the global context. +func VMOVHPD(ops ...operand.Op) { ctx.VMOVHPD(ops...) } + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +// Construct and append a VMOVHPS instruction to the active function. +func (c *Context) VMOVHPS(ops ...operand.Op) { + if inst, err := x86.VMOVHPS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +// Construct and append a VMOVHPS instruction to the active function. +// Operates on the global context. +func VMOVHPS(ops ...operand.Op) { ctx.VMOVHPS(ops...) } + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +// Construct and append a VMOVLHPS instruction to the active function. +func (c *Context) VMOVLHPS(x, x1, x2 operand.Op) { + if inst, err := x86.VMOVLHPS(x, x1, x2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +// Construct and append a VMOVLHPS instruction to the active function. +// Operates on the global context. +func VMOVLHPS(x, x1, x2 operand.Op) { ctx.VMOVLHPS(x, x1, x2) } + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +// Construct and append a VMOVLPD instruction to the active function. +func (c *Context) VMOVLPD(ops ...operand.Op) { + if inst, err := x86.VMOVLPD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +// Construct and append a VMOVLPD instruction to the active function. +// Operates on the global context. +func VMOVLPD(ops ...operand.Op) { ctx.VMOVLPD(ops...) } + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +// Construct and append a VMOVLPS instruction to the active function. +func (c *Context) VMOVLPS(ops ...operand.Op) { + if inst, err := x86.VMOVLPS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +// Construct and append a VMOVLPS instruction to the active function. +// Operates on the global context. +func VMOVLPS(ops ...operand.Op) { ctx.VMOVLPS(ops...) } + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +// Construct and append a VMOVMSKPD instruction to the active function. +func (c *Context) VMOVMSKPD(xy, r operand.Op) { + if inst, err := x86.VMOVMSKPD(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +// Construct and append a VMOVMSKPD instruction to the active function. +// Operates on the global context. +func VMOVMSKPD(xy, r operand.Op) { ctx.VMOVMSKPD(xy, r) } + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +// Construct and append a VMOVMSKPS instruction to the active function. +func (c *Context) VMOVMSKPS(xy, r operand.Op) { + if inst, err := x86.VMOVMSKPS(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +// Construct and append a VMOVMSKPS instruction to the active function. +// Operates on the global context. +func VMOVMSKPS(xy, r operand.Op) { ctx.VMOVMSKPS(xy, r) } + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +// Construct and append a VMOVNTDQ instruction to the active function. +func (c *Context) VMOVNTDQ(xy, m operand.Op) { + if inst, err := x86.VMOVNTDQ(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +// Construct and append a VMOVNTDQ instruction to the active function. +// Operates on the global context. +func VMOVNTDQ(xy, m operand.Op) { ctx.VMOVNTDQ(xy, m) } + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +// Construct and append a VMOVNTDQA instruction to the active function. +func (c *Context) VMOVNTDQA(m, xy operand.Op) { + if inst, err := x86.VMOVNTDQA(m, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +// Construct and append a VMOVNTDQA instruction to the active function. +// Operates on the global context. +func VMOVNTDQA(m, xy operand.Op) { ctx.VMOVNTDQA(m, xy) } + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +// Construct and append a VMOVNTPD instruction to the active function. +func (c *Context) VMOVNTPD(xy, m operand.Op) { + if inst, err := x86.VMOVNTPD(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +// Construct and append a VMOVNTPD instruction to the active function. +// Operates on the global context. +func VMOVNTPD(xy, m operand.Op) { ctx.VMOVNTPD(xy, m) } + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +// Construct and append a VMOVNTPS instruction to the active function. +func (c *Context) VMOVNTPS(xy, m operand.Op) { + if inst, err := x86.VMOVNTPS(xy, m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +// Construct and append a VMOVNTPS instruction to the active function. +// Operates on the global context. +func VMOVNTPS(xy, m operand.Op) { ctx.VMOVNTPS(xy, m) } + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +// Construct and append a VMOVQ instruction to the active function. +func (c *Context) VMOVQ(mrx, mrx1 operand.Op) { + if inst, err := x86.VMOVQ(mrx, mrx1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +// Construct and append a VMOVQ instruction to the active function. +// Operates on the global context. +func VMOVQ(mrx, mrx1 operand.Op) { ctx.VMOVQ(mrx, mrx1) } + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +// Construct and append a VMOVSD instruction to the active function. +func (c *Context) VMOVSD(ops ...operand.Op) { + if inst, err := x86.VMOVSD(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +// Construct and append a VMOVSD instruction to the active function. +// Operates on the global context. +func VMOVSD(ops ...operand.Op) { ctx.VMOVSD(ops...) } + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +// Construct and append a VMOVSHDUP instruction to the active function. +func (c *Context) VMOVSHDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVSHDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +// Construct and append a VMOVSHDUP instruction to the active function. +// Operates on the global context. +func VMOVSHDUP(mxy, xy operand.Op) { ctx.VMOVSHDUP(mxy, xy) } + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +// Construct and append a VMOVSLDUP instruction to the active function. +func (c *Context) VMOVSLDUP(mxy, xy operand.Op) { + if inst, err := x86.VMOVSLDUP(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +// Construct and append a VMOVSLDUP instruction to the active function. +// Operates on the global context. +func VMOVSLDUP(mxy, xy operand.Op) { ctx.VMOVSLDUP(mxy, xy) } + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +// Construct and append a VMOVSS instruction to the active function. +func (c *Context) VMOVSS(ops ...operand.Op) { + if inst, err := x86.VMOVSS(ops...); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +// Construct and append a VMOVSS instruction to the active function. +// Operates on the global context. +func VMOVSS(ops ...operand.Op) { ctx.VMOVSS(ops...) } + +// VMOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPD xmm xmm +// VMOVUPD m128 xmm +// VMOVUPD ymm ymm +// VMOVUPD m256 ymm +// VMOVUPD xmm m128 +// VMOVUPD ymm m256 +// Construct and append a VMOVUPD instruction to the active function. +func (c *Context) VMOVUPD(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVUPD(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPD xmm xmm +// VMOVUPD m128 xmm +// VMOVUPD ymm ymm +// VMOVUPD m256 ymm +// VMOVUPD xmm m128 +// VMOVUPD ymm m256 +// Construct and append a VMOVUPD instruction to the active function. +// Operates on the global context. +func VMOVUPD(mxy, mxy1 operand.Op) { ctx.VMOVUPD(mxy, mxy1) } + +// VMOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPS xmm xmm +// VMOVUPS m128 xmm +// VMOVUPS ymm ymm +// VMOVUPS m256 ymm +// VMOVUPS xmm m128 +// VMOVUPS ymm m256 +// Construct and append a VMOVUPS instruction to the active function. +func (c *Context) VMOVUPS(mxy, mxy1 operand.Op) { + if inst, err := x86.VMOVUPS(mxy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPS xmm xmm +// VMOVUPS m128 xmm +// VMOVUPS ymm ymm +// VMOVUPS m256 ymm +// VMOVUPS xmm m128 +// VMOVUPS ymm m256 +// Construct and append a VMOVUPS instruction to the active function. +// Operates on the global context. +func VMOVUPS(mxy, mxy1 operand.Op) { ctx.VMOVUPS(mxy, mxy1) } + +// VMPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// VMPSADBW imm8 xmm xmm xmm +// VMPSADBW imm8 m128 xmm xmm +// VMPSADBW imm8 ymm ymm ymm +// VMPSADBW imm8 m256 ymm ymm +// Construct and append a VMPSADBW instruction to the active function. +func (c *Context) VMPSADBW(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMPSADBW(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// VMPSADBW imm8 xmm xmm xmm +// VMPSADBW imm8 m128 xmm xmm +// VMPSADBW imm8 ymm ymm ymm +// VMPSADBW imm8 m256 ymm ymm +// Construct and append a VMPSADBW instruction to the active function. +// Operates on the global context. +func VMPSADBW(i, mxy, xy, xy1 operand.Op) { ctx.VMPSADBW(i, mxy, xy, xy1) } + +// VMULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULPD xmm xmm xmm +// VMULPD m128 xmm xmm +// VMULPD ymm ymm ymm +// VMULPD m256 ymm ymm +// Construct and append a VMULPD instruction to the active function. +func (c *Context) VMULPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMULPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULPD xmm xmm xmm +// VMULPD m128 xmm xmm +// VMULPD ymm ymm ymm +// VMULPD m256 ymm ymm +// Construct and append a VMULPD instruction to the active function. +// Operates on the global context. +func VMULPD(mxy, xy, xy1 operand.Op) { ctx.VMULPD(mxy, xy, xy1) } + +// VMULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULPS xmm xmm xmm +// VMULPS m128 xmm xmm +// VMULPS ymm ymm ymm +// VMULPS m256 ymm ymm +// Construct and append a VMULPS instruction to the active function. +func (c *Context) VMULPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VMULPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULPS xmm xmm xmm +// VMULPS m128 xmm xmm +// VMULPS ymm ymm ymm +// VMULPS m256 ymm ymm +// Construct and append a VMULPS instruction to the active function. +// Operates on the global context. +func VMULPS(mxy, xy, xy1 operand.Op) { ctx.VMULPS(mxy, xy, xy1) } + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +// Construct and append a VMULSD instruction to the active function. +func (c *Context) VMULSD(mx, x, x1 operand.Op) { + if inst, err := x86.VMULSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +// Construct and append a VMULSD instruction to the active function. +// Operates on the global context. +func VMULSD(mx, x, x1 operand.Op) { ctx.VMULSD(mx, x, x1) } + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +// Construct and append a VMULSS instruction to the active function. +func (c *Context) VMULSS(mx, x, x1 operand.Op) { + if inst, err := x86.VMULSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +// Construct and append a VMULSS instruction to the active function. +// Operates on the global context. +func VMULSS(mx, x, x1 operand.Op) { ctx.VMULSS(mx, x, x1) } + +// VORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// VORPD xmm xmm xmm +// VORPD m128 xmm xmm +// VORPD ymm ymm ymm +// VORPD m256 ymm ymm +// Construct and append a VORPD instruction to the active function. +func (c *Context) VORPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VORPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// VORPD xmm xmm xmm +// VORPD m128 xmm xmm +// VORPD ymm ymm ymm +// VORPD m256 ymm ymm +// Construct and append a VORPD instruction to the active function. +// Operates on the global context. +func VORPD(mxy, xy, xy1 operand.Op) { ctx.VORPD(mxy, xy, xy1) } + +// VORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// VORPS xmm xmm xmm +// VORPS m128 xmm xmm +// VORPS ymm ymm ymm +// VORPS m256 ymm ymm +// Construct and append a VORPS instruction to the active function. +func (c *Context) VORPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VORPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// VORPS xmm xmm xmm +// VORPS m128 xmm xmm +// VORPS ymm ymm ymm +// VORPS m256 ymm ymm +// Construct and append a VORPS instruction to the active function. +// Operates on the global context. +func VORPS(mxy, xy, xy1 operand.Op) { ctx.VORPS(mxy, xy, xy1) } + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +// Construct and append a VPABSB instruction to the active function. +func (c *Context) VPABSB(mxy, xy operand.Op) { + if inst, err := x86.VPABSB(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +// Construct and append a VPABSB instruction to the active function. +// Operates on the global context. +func VPABSB(mxy, xy operand.Op) { ctx.VPABSB(mxy, xy) } + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +// Construct and append a VPABSD instruction to the active function. +func (c *Context) VPABSD(mxy, xy operand.Op) { + if inst, err := x86.VPABSD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +// Construct and append a VPABSD instruction to the active function. +// Operates on the global context. +func VPABSD(mxy, xy operand.Op) { ctx.VPABSD(mxy, xy) } + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +// Construct and append a VPABSW instruction to the active function. +func (c *Context) VPABSW(mxy, xy operand.Op) { + if inst, err := x86.VPABSW(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +// Construct and append a VPABSW instruction to the active function. +// Operates on the global context. +func VPABSW(mxy, xy operand.Op) { ctx.VPABSW(mxy, xy) } + +// VPACKSSDW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// VPACKSSDW xmm xmm xmm +// VPACKSSDW m128 xmm xmm +// VPACKSSDW ymm ymm ymm +// VPACKSSDW m256 ymm ymm +// Construct and append a VPACKSSDW instruction to the active function. +func (c *Context) VPACKSSDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKSSDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPACKSSDW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// VPACKSSDW xmm xmm xmm +// VPACKSSDW m128 xmm xmm +// VPACKSSDW ymm ymm ymm +// VPACKSSDW m256 ymm ymm +// Construct and append a VPACKSSDW instruction to the active function. +// Operates on the global context. +func VPACKSSDW(mxy, xy, xy1 operand.Op) { ctx.VPACKSSDW(mxy, xy, xy1) } + +// VPACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// VPACKSSWB xmm xmm xmm +// VPACKSSWB m128 xmm xmm +// VPACKSSWB ymm ymm ymm +// VPACKSSWB m256 ymm ymm +// Construct and append a VPACKSSWB instruction to the active function. +func (c *Context) VPACKSSWB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKSSWB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// VPACKSSWB xmm xmm xmm +// VPACKSSWB m128 xmm xmm +// VPACKSSWB ymm ymm ymm +// VPACKSSWB m256 ymm ymm +// Construct and append a VPACKSSWB instruction to the active function. +// Operates on the global context. +func VPACKSSWB(mxy, xy, xy1 operand.Op) { ctx.VPACKSSWB(mxy, xy, xy1) } + +// VPACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// VPACKUSDW xmm xmm xmm +// VPACKUSDW m128 xmm xmm +// VPACKUSDW ymm ymm ymm +// VPACKUSDW m256 ymm ymm +// Construct and append a VPACKUSDW instruction to the active function. +func (c *Context) VPACKUSDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKUSDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// VPACKUSDW xmm xmm xmm +// VPACKUSDW m128 xmm xmm +// VPACKUSDW ymm ymm ymm +// VPACKUSDW m256 ymm ymm +// Construct and append a VPACKUSDW instruction to the active function. +// Operates on the global context. +func VPACKUSDW(mxy, xy, xy1 operand.Op) { ctx.VPACKUSDW(mxy, xy, xy1) } + +// VPACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// VPACKUSWB xmm xmm xmm +// VPACKUSWB m128 xmm xmm +// VPACKUSWB ymm ymm ymm +// VPACKUSWB m256 ymm ymm +// Construct and append a VPACKUSWB instruction to the active function. +func (c *Context) VPACKUSWB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPACKUSWB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// VPACKUSWB xmm xmm xmm +// VPACKUSWB m128 xmm xmm +// VPACKUSWB ymm ymm ymm +// VPACKUSWB m256 ymm ymm +// Construct and append a VPACKUSWB instruction to the active function. +// Operates on the global context. +func VPACKUSWB(mxy, xy, xy1 operand.Op) { ctx.VPACKUSWB(mxy, xy, xy1) } + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +// Construct and append a VPADDB instruction to the active function. +func (c *Context) VPADDB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +// Construct and append a VPADDB instruction to the active function. +// Operates on the global context. +func VPADDB(mxy, xy, xy1 operand.Op) { ctx.VPADDB(mxy, xy, xy1) } + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +// Construct and append a VPADDD instruction to the active function. +func (c *Context) VPADDD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +// Construct and append a VPADDD instruction to the active function. +// Operates on the global context. +func VPADDD(mxy, xy, xy1 operand.Op) { ctx.VPADDD(mxy, xy, xy1) } + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +// Construct and append a VPADDQ instruction to the active function. +func (c *Context) VPADDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +// Construct and append a VPADDQ instruction to the active function. +// Operates on the global context. +func VPADDQ(mxy, xy, xy1 operand.Op) { ctx.VPADDQ(mxy, xy, xy1) } + +// VPADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPADDSB xmm xmm xmm +// VPADDSB m128 xmm xmm +// VPADDSB ymm ymm ymm +// VPADDSB m256 ymm ymm +// Construct and append a VPADDSB instruction to the active function. +func (c *Context) VPADDSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPADDSB xmm xmm xmm +// VPADDSB m128 xmm xmm +// VPADDSB ymm ymm ymm +// VPADDSB m256 ymm ymm +// Construct and append a VPADDSB instruction to the active function. +// Operates on the global context. +func VPADDSB(mxy, xy, xy1 operand.Op) { ctx.VPADDSB(mxy, xy, xy1) } + +// VPADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPADDSW xmm xmm xmm +// VPADDSW m128 xmm xmm +// VPADDSW ymm ymm ymm +// VPADDSW m256 ymm ymm +// Construct and append a VPADDSW instruction to the active function. +func (c *Context) VPADDSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPADDSW xmm xmm xmm +// VPADDSW m128 xmm xmm +// VPADDSW ymm ymm ymm +// VPADDSW m256 ymm ymm +// Construct and append a VPADDSW instruction to the active function. +// Operates on the global context. +func VPADDSW(mxy, xy, xy1 operand.Op) { ctx.VPADDSW(mxy, xy, xy1) } + +// VPADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSB xmm xmm xmm +// VPADDUSB m128 xmm xmm +// VPADDUSB ymm ymm ymm +// VPADDUSB m256 ymm ymm +// Construct and append a VPADDUSB instruction to the active function. +func (c *Context) VPADDUSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDUSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSB xmm xmm xmm +// VPADDUSB m128 xmm xmm +// VPADDUSB ymm ymm ymm +// VPADDUSB m256 ymm ymm +// Construct and append a VPADDUSB instruction to the active function. +// Operates on the global context. +func VPADDUSB(mxy, xy, xy1 operand.Op) { ctx.VPADDUSB(mxy, xy, xy1) } + +// VPADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSW xmm xmm xmm +// VPADDUSW m128 xmm xmm +// VPADDUSW ymm ymm ymm +// VPADDUSW m256 ymm ymm +// Construct and append a VPADDUSW instruction to the active function. +func (c *Context) VPADDUSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDUSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSW xmm xmm xmm +// VPADDUSW m128 xmm xmm +// VPADDUSW ymm ymm ymm +// VPADDUSW m256 ymm ymm +// Construct and append a VPADDUSW instruction to the active function. +// Operates on the global context. +func VPADDUSW(mxy, xy, xy1 operand.Op) { ctx.VPADDUSW(mxy, xy, xy1) } + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +// Construct and append a VPADDW instruction to the active function. +func (c *Context) VPADDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPADDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +// Construct and append a VPADDW instruction to the active function. +// Operates on the global context. +func VPADDW(mxy, xy, xy1 operand.Op) { ctx.VPADDW(mxy, xy, xy1) } + +// VPALIGNR: Packed Align Right. +// +// Forms: +// +// VPALIGNR imm8 xmm xmm xmm +// VPALIGNR imm8 m128 xmm xmm +// VPALIGNR imm8 ymm ymm ymm +// VPALIGNR imm8 m256 ymm ymm +// Construct and append a VPALIGNR instruction to the active function. +func (c *Context) VPALIGNR(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPALIGNR(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPALIGNR: Packed Align Right. +// +// Forms: +// +// VPALIGNR imm8 xmm xmm xmm +// VPALIGNR imm8 m128 xmm xmm +// VPALIGNR imm8 ymm ymm ymm +// VPALIGNR imm8 m256 ymm ymm +// Construct and append a VPALIGNR instruction to the active function. +// Operates on the global context. +func VPALIGNR(i, mxy, xy, xy1 operand.Op) { ctx.VPALIGNR(i, mxy, xy, xy1) } + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +// Construct and append a VPAND instruction to the active function. +func (c *Context) VPAND(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAND(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +// Construct and append a VPAND instruction to the active function. +// Operates on the global context. +func VPAND(mxy, xy, xy1 operand.Op) { ctx.VPAND(mxy, xy, xy1) } + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +// Construct and append a VPANDN instruction to the active function. +func (c *Context) VPANDN(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPANDN(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +// Construct and append a VPANDN instruction to the active function. +// Operates on the global context. +func VPANDN(mxy, xy, xy1 operand.Op) { ctx.VPANDN(mxy, xy, xy1) } + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +// Construct and append a VPAVGB instruction to the active function. +func (c *Context) VPAVGB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAVGB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +// Construct and append a VPAVGB instruction to the active function. +// Operates on the global context. +func VPAVGB(mxy, xy, xy1 operand.Op) { ctx.VPAVGB(mxy, xy, xy1) } + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +// Construct and append a VPAVGW instruction to the active function. +func (c *Context) VPAVGW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPAVGW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +// Construct and append a VPAVGW instruction to the active function. +// Operates on the global context. +func VPAVGW(mxy, xy, xy1 operand.Op) { ctx.VPAVGW(mxy, xy, xy1) } + +// VPBLENDD: Blend Packed Doublewords. +// +// Forms: +// +// VPBLENDD imm8 xmm xmm xmm +// VPBLENDD imm8 m128 xmm xmm +// VPBLENDD imm8 ymm ymm ymm +// VPBLENDD imm8 m256 ymm ymm +// Construct and append a VPBLENDD instruction to the active function. +func (c *Context) VPBLENDD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPBLENDD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBLENDD: Blend Packed Doublewords. +// +// Forms: +// +// VPBLENDD imm8 xmm xmm xmm +// VPBLENDD imm8 m128 xmm xmm +// VPBLENDD imm8 ymm ymm ymm +// VPBLENDD imm8 m256 ymm ymm +// Construct and append a VPBLENDD instruction to the active function. +// Operates on the global context. +func VPBLENDD(i, mxy, xy, xy1 operand.Op) { ctx.VPBLENDD(i, mxy, xy, xy1) } + +// VPBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// VPBLENDVB xmm xmm xmm xmm +// VPBLENDVB xmm m128 xmm xmm +// VPBLENDVB ymm ymm ymm ymm +// VPBLENDVB ymm m256 ymm ymm +// Construct and append a VPBLENDVB instruction to the active function. +func (c *Context) VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) { + if inst, err := x86.VPBLENDVB(xy, mxy, xy1, xy2); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// VPBLENDVB xmm xmm xmm xmm +// VPBLENDVB xmm m128 xmm xmm +// VPBLENDVB ymm ymm ymm ymm +// VPBLENDVB ymm m256 ymm ymm +// Construct and append a VPBLENDVB instruction to the active function. +// Operates on the global context. +func VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) { ctx.VPBLENDVB(xy, mxy, xy1, xy2) } + +// VPBLENDW: Blend Packed Words. +// +// Forms: +// +// VPBLENDW imm8 xmm xmm xmm +// VPBLENDW imm8 m128 xmm xmm +// VPBLENDW imm8 ymm ymm ymm +// VPBLENDW imm8 m256 ymm ymm +// Construct and append a VPBLENDW instruction to the active function. +func (c *Context) VPBLENDW(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPBLENDW(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBLENDW: Blend Packed Words. +// +// Forms: +// +// VPBLENDW imm8 xmm xmm xmm +// VPBLENDW imm8 m128 xmm xmm +// VPBLENDW imm8 ymm ymm ymm +// VPBLENDW imm8 m256 ymm ymm +// Construct and append a VPBLENDW instruction to the active function. +// Operates on the global context. +func VPBLENDW(i, mxy, xy, xy1 operand.Op) { ctx.VPBLENDW(i, mxy, xy, xy1) } + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +// Construct and append a VPBROADCASTB instruction to the active function. +func (c *Context) VPBROADCASTB(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTB(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +// Construct and append a VPBROADCASTB instruction to the active function. +// Operates on the global context. +func VPBROADCASTB(mx, xy operand.Op) { ctx.VPBROADCASTB(mx, xy) } + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +// Construct and append a VPBROADCASTD instruction to the active function. +func (c *Context) VPBROADCASTD(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +// Construct and append a VPBROADCASTD instruction to the active function. +// Operates on the global context. +func VPBROADCASTD(mx, xy operand.Op) { ctx.VPBROADCASTD(mx, xy) } + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +// Construct and append a VPBROADCASTQ instruction to the active function. +func (c *Context) VPBROADCASTQ(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +// Construct and append a VPBROADCASTQ instruction to the active function. +// Operates on the global context. +func VPBROADCASTQ(mx, xy operand.Op) { ctx.VPBROADCASTQ(mx, xy) } + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +// Construct and append a VPBROADCASTW instruction to the active function. +func (c *Context) VPBROADCASTW(mx, xy operand.Op) { + if inst, err := x86.VPBROADCASTW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +// Construct and append a VPBROADCASTW instruction to the active function. +// Operates on the global context. +func VPBROADCASTW(mx, xy operand.Op) { ctx.VPBROADCASTW(mx, xy) } + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +// Construct and append a VPCLMULQDQ instruction to the active function. +func (c *Context) VPCLMULQDQ(i, mx, x, x1 operand.Op) { + if inst, err := x86.VPCLMULQDQ(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +// Construct and append a VPCLMULQDQ instruction to the active function. +// Operates on the global context. +func VPCLMULQDQ(i, mx, x, x1 operand.Op) { ctx.VPCLMULQDQ(i, mx, x, x1) } + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +// Construct and append a VPCMPEQB instruction to the active function. +func (c *Context) VPCMPEQB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +// Construct and append a VPCMPEQB instruction to the active function. +// Operates on the global context. +func VPCMPEQB(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQB(mxy, xy, xy1) } + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +// Construct and append a VPCMPEQD instruction to the active function. +func (c *Context) VPCMPEQD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +// Construct and append a VPCMPEQD instruction to the active function. +// Operates on the global context. +func VPCMPEQD(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQD(mxy, xy, xy1) } + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +// Construct and append a VPCMPEQQ instruction to the active function. +func (c *Context) VPCMPEQQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +// Construct and append a VPCMPEQQ instruction to the active function. +// Operates on the global context. +func VPCMPEQQ(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQQ(mxy, xy, xy1) } + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +// Construct and append a VPCMPEQW instruction to the active function. +func (c *Context) VPCMPEQW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPEQW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +// Construct and append a VPCMPEQW instruction to the active function. +// Operates on the global context. +func VPCMPEQW(mxy, xy, xy1 operand.Op) { ctx.VPCMPEQW(mxy, xy, xy1) } + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +// Construct and append a VPCMPESTRI instruction to the active function. +func (c *Context) VPCMPESTRI(i, mx, x operand.Op) { + if inst, err := x86.VPCMPESTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +// Construct and append a VPCMPESTRI instruction to the active function. +// Operates on the global context. +func VPCMPESTRI(i, mx, x operand.Op) { ctx.VPCMPESTRI(i, mx, x) } + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +// Construct and append a VPCMPESTRM instruction to the active function. +func (c *Context) VPCMPESTRM(i, mx, x operand.Op) { + if inst, err := x86.VPCMPESTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +// Construct and append a VPCMPESTRM instruction to the active function. +// Operates on the global context. +func VPCMPESTRM(i, mx, x operand.Op) { ctx.VPCMPESTRM(i, mx, x) } + +// VPCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// VPCMPGTB xmm xmm xmm +// VPCMPGTB m128 xmm xmm +// VPCMPGTB ymm ymm ymm +// VPCMPGTB m256 ymm ymm +// Construct and append a VPCMPGTB instruction to the active function. +func (c *Context) VPCMPGTB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// VPCMPGTB xmm xmm xmm +// VPCMPGTB m128 xmm xmm +// VPCMPGTB ymm ymm ymm +// VPCMPGTB m256 ymm ymm +// Construct and append a VPCMPGTB instruction to the active function. +// Operates on the global context. +func VPCMPGTB(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTB(mxy, xy, xy1) } + +// VPCMPGTD: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// VPCMPGTD xmm xmm xmm +// VPCMPGTD m128 xmm xmm +// VPCMPGTD ymm ymm ymm +// VPCMPGTD m256 ymm ymm +// Construct and append a VPCMPGTD instruction to the active function. +func (c *Context) VPCMPGTD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPGTD: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// VPCMPGTD xmm xmm xmm +// VPCMPGTD m128 xmm xmm +// VPCMPGTD ymm ymm ymm +// VPCMPGTD m256 ymm ymm +// Construct and append a VPCMPGTD instruction to the active function. +// Operates on the global context. +func VPCMPGTD(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTD(mxy, xy, xy1) } + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +// Construct and append a VPCMPGTQ instruction to the active function. +func (c *Context) VPCMPGTQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +// Construct and append a VPCMPGTQ instruction to the active function. +// Operates on the global context. +func VPCMPGTQ(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTQ(mxy, xy, xy1) } + +// VPCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// VPCMPGTW xmm xmm xmm +// VPCMPGTW m128 xmm xmm +// VPCMPGTW ymm ymm ymm +// VPCMPGTW m256 ymm ymm +// Construct and append a VPCMPGTW instruction to the active function. +func (c *Context) VPCMPGTW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPCMPGTW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// VPCMPGTW xmm xmm xmm +// VPCMPGTW m128 xmm xmm +// VPCMPGTW ymm ymm ymm +// VPCMPGTW m256 ymm ymm +// Construct and append a VPCMPGTW instruction to the active function. +// Operates on the global context. +func VPCMPGTW(mxy, xy, xy1 operand.Op) { ctx.VPCMPGTW(mxy, xy, xy1) } + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +// Construct and append a VPCMPISTRI instruction to the active function. +func (c *Context) VPCMPISTRI(i, mx, x operand.Op) { + if inst, err := x86.VPCMPISTRI(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +// Construct and append a VPCMPISTRI instruction to the active function. +// Operates on the global context. +func VPCMPISTRI(i, mx, x operand.Op) { ctx.VPCMPISTRI(i, mx, x) } + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +// Construct and append a VPCMPISTRM instruction to the active function. +func (c *Context) VPCMPISTRM(i, mx, x operand.Op) { + if inst, err := x86.VPCMPISTRM(i, mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +// Construct and append a VPCMPISTRM instruction to the active function. +// Operates on the global context. +func VPCMPISTRM(i, mx, x operand.Op) { ctx.VPCMPISTRM(i, mx, x) } + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +// Construct and append a VPERM2F128 instruction to the active function. +func (c *Context) VPERM2F128(i, my, y, y1 operand.Op) { + if inst, err := x86.VPERM2F128(i, my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +// Construct and append a VPERM2F128 instruction to the active function. +// Operates on the global context. +func VPERM2F128(i, my, y, y1 operand.Op) { ctx.VPERM2F128(i, my, y, y1) } + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +// Construct and append a VPERM2I128 instruction to the active function. +func (c *Context) VPERM2I128(i, my, y, y1 operand.Op) { + if inst, err := x86.VPERM2I128(i, my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +// Construct and append a VPERM2I128 instruction to the active function. +// Operates on the global context. +func VPERM2I128(i, my, y, y1 operand.Op) { ctx.VPERM2I128(i, my, y, y1) } + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +// Construct and append a VPERMD instruction to the active function. +func (c *Context) VPERMD(my, y, y1 operand.Op) { + if inst, err := x86.VPERMD(my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +// Construct and append a VPERMD instruction to the active function. +// Operates on the global context. +func VPERMD(my, y, y1 operand.Op) { ctx.VPERMD(my, y, y1) } + +// VPERMILPD: Permute Double-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPD imm8 xmm xmm +// VPERMILPD xmm xmm xmm +// VPERMILPD m128 xmm xmm +// VPERMILPD imm8 m128 xmm +// VPERMILPD imm8 ymm ymm +// VPERMILPD ymm ymm ymm +// VPERMILPD m256 ymm ymm +// VPERMILPD imm8 m256 ymm +// Construct and append a VPERMILPD instruction to the active function. +func (c *Context) VPERMILPD(imxy, mxy, xy operand.Op) { + if inst, err := x86.VPERMILPD(imxy, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMILPD: Permute Double-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPD imm8 xmm xmm +// VPERMILPD xmm xmm xmm +// VPERMILPD m128 xmm xmm +// VPERMILPD imm8 m128 xmm +// VPERMILPD imm8 ymm ymm +// VPERMILPD ymm ymm ymm +// VPERMILPD m256 ymm ymm +// VPERMILPD imm8 m256 ymm +// Construct and append a VPERMILPD instruction to the active function. +// Operates on the global context. +func VPERMILPD(imxy, mxy, xy operand.Op) { ctx.VPERMILPD(imxy, mxy, xy) } + +// VPERMILPS: Permute Single-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPS imm8 xmm xmm +// VPERMILPS xmm xmm xmm +// VPERMILPS m128 xmm xmm +// VPERMILPS imm8 m128 xmm +// VPERMILPS imm8 ymm ymm +// VPERMILPS ymm ymm ymm +// VPERMILPS m256 ymm ymm +// VPERMILPS imm8 m256 ymm +// Construct and append a VPERMILPS instruction to the active function. +func (c *Context) VPERMILPS(imxy, mxy, xy operand.Op) { + if inst, err := x86.VPERMILPS(imxy, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMILPS: Permute Single-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPS imm8 xmm xmm +// VPERMILPS xmm xmm xmm +// VPERMILPS m128 xmm xmm +// VPERMILPS imm8 m128 xmm +// VPERMILPS imm8 ymm ymm +// VPERMILPS ymm ymm ymm +// VPERMILPS m256 ymm ymm +// VPERMILPS imm8 m256 ymm +// Construct and append a VPERMILPS instruction to the active function. +// Operates on the global context. +func VPERMILPS(imxy, mxy, xy operand.Op) { ctx.VPERMILPS(imxy, mxy, xy) } + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +// Construct and append a VPERMPD instruction to the active function. +func (c *Context) VPERMPD(i, my, y operand.Op) { + if inst, err := x86.VPERMPD(i, my, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +// Construct and append a VPERMPD instruction to the active function. +// Operates on the global context. +func VPERMPD(i, my, y operand.Op) { ctx.VPERMPD(i, my, y) } + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +// Construct and append a VPERMPS instruction to the active function. +func (c *Context) VPERMPS(my, y, y1 operand.Op) { + if inst, err := x86.VPERMPS(my, y, y1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +// Construct and append a VPERMPS instruction to the active function. +// Operates on the global context. +func VPERMPS(my, y, y1 operand.Op) { ctx.VPERMPS(my, y, y1) } + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +// Construct and append a VPERMQ instruction to the active function. +func (c *Context) VPERMQ(i, my, y operand.Op) { + if inst, err := x86.VPERMQ(i, my, y); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +// Construct and append a VPERMQ instruction to the active function. +// Operates on the global context. +func VPERMQ(i, my, y operand.Op) { ctx.VPERMQ(i, my, y) } + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +// Construct and append a VPEXTRB instruction to the active function. +func (c *Context) VPEXTRB(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRB(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +// Construct and append a VPEXTRB instruction to the active function. +// Operates on the global context. +func VPEXTRB(i, x, mr operand.Op) { ctx.VPEXTRB(i, x, mr) } + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +// Construct and append a VPEXTRD instruction to the active function. +func (c *Context) VPEXTRD(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRD(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +// Construct and append a VPEXTRD instruction to the active function. +// Operates on the global context. +func VPEXTRD(i, x, mr operand.Op) { ctx.VPEXTRD(i, x, mr) } + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +// Construct and append a VPEXTRQ instruction to the active function. +func (c *Context) VPEXTRQ(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRQ(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +// Construct and append a VPEXTRQ instruction to the active function. +// Operates on the global context. +func VPEXTRQ(i, x, mr operand.Op) { ctx.VPEXTRQ(i, x, mr) } + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +// Construct and append a VPEXTRW instruction to the active function. +func (c *Context) VPEXTRW(i, x, mr operand.Op) { + if inst, err := x86.VPEXTRW(i, x, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +// Construct and append a VPEXTRW instruction to the active function. +// Operates on the global context. +func VPEXTRW(i, x, mr operand.Op) { ctx.VPEXTRW(i, x, mr) } + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +// Construct and append a VPGATHERDD instruction to the active function. +func (c *Context) VPGATHERDD(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERDD(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +// Construct and append a VPGATHERDD instruction to the active function. +// Operates on the global context. +func VPGATHERDD(xy, v, xy1 operand.Op) { ctx.VPGATHERDD(xy, v, xy1) } + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +// Construct and append a VPGATHERDQ instruction to the active function. +func (c *Context) VPGATHERDQ(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERDQ(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +// Construct and append a VPGATHERDQ instruction to the active function. +// Operates on the global context. +func VPGATHERDQ(xy, v, xy1 operand.Op) { ctx.VPGATHERDQ(xy, v, xy1) } + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +// Construct and append a VPGATHERQD instruction to the active function. +func (c *Context) VPGATHERQD(x, v, x1 operand.Op) { + if inst, err := x86.VPGATHERQD(x, v, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +// Construct and append a VPGATHERQD instruction to the active function. +// Operates on the global context. +func VPGATHERQD(x, v, x1 operand.Op) { ctx.VPGATHERQD(x, v, x1) } + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +// Construct and append a VPGATHERQQ instruction to the active function. +func (c *Context) VPGATHERQQ(xy, v, xy1 operand.Op) { + if inst, err := x86.VPGATHERQQ(xy, v, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +// Construct and append a VPGATHERQQ instruction to the active function. +// Operates on the global context. +func VPGATHERQQ(xy, v, xy1 operand.Op) { ctx.VPGATHERQQ(xy, v, xy1) } + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +// Construct and append a VPHADDD instruction to the active function. +func (c *Context) VPHADDD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +// Construct and append a VPHADDD instruction to the active function. +// Operates on the global context. +func VPHADDD(mxy, xy, xy1 operand.Op) { ctx.VPHADDD(mxy, xy, xy1) } + +// VPHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHADDSW xmm xmm xmm +// VPHADDSW m128 xmm xmm +// VPHADDSW ymm ymm ymm +// VPHADDSW m256 ymm ymm +// Construct and append a VPHADDSW instruction to the active function. +func (c *Context) VPHADDSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHADDSW xmm xmm xmm +// VPHADDSW m128 xmm xmm +// VPHADDSW ymm ymm ymm +// VPHADDSW m256 ymm ymm +// Construct and append a VPHADDSW instruction to the active function. +// Operates on the global context. +func VPHADDSW(mxy, xy, xy1 operand.Op) { ctx.VPHADDSW(mxy, xy, xy1) } + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +// Construct and append a VPHADDW instruction to the active function. +func (c *Context) VPHADDW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHADDW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +// Construct and append a VPHADDW instruction to the active function. +// Operates on the global context. +func VPHADDW(mxy, xy, xy1 operand.Op) { ctx.VPHADDW(mxy, xy, xy1) } + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +// Construct and append a VPHMINPOSUW instruction to the active function. +func (c *Context) VPHMINPOSUW(mx, x operand.Op) { + if inst, err := x86.VPHMINPOSUW(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +// Construct and append a VPHMINPOSUW instruction to the active function. +// Operates on the global context. +func VPHMINPOSUW(mx, x operand.Op) { ctx.VPHMINPOSUW(mx, x) } + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +// Construct and append a VPHSUBD instruction to the active function. +func (c *Context) VPHSUBD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +// Construct and append a VPHSUBD instruction to the active function. +// Operates on the global context. +func VPHSUBD(mxy, xy, xy1 operand.Op) { ctx.VPHSUBD(mxy, xy, xy1) } + +// VPHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHSUBSW xmm xmm xmm +// VPHSUBSW m128 xmm xmm +// VPHSUBSW ymm ymm ymm +// VPHSUBSW m256 ymm ymm +// Construct and append a VPHSUBSW instruction to the active function. +func (c *Context) VPHSUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHSUBSW xmm xmm xmm +// VPHSUBSW m128 xmm xmm +// VPHSUBSW ymm ymm ymm +// VPHSUBSW m256 ymm ymm +// Construct and append a VPHSUBSW instruction to the active function. +// Operates on the global context. +func VPHSUBSW(mxy, xy, xy1 operand.Op) { ctx.VPHSUBSW(mxy, xy, xy1) } + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +// Construct and append a VPHSUBW instruction to the active function. +func (c *Context) VPHSUBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPHSUBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +// Construct and append a VPHSUBW instruction to the active function. +// Operates on the global context. +func VPHSUBW(mxy, xy, xy1 operand.Op) { ctx.VPHSUBW(mxy, xy, xy1) } + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +// Construct and append a VPINSRB instruction to the active function. +func (c *Context) VPINSRB(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRB(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +// Construct and append a VPINSRB instruction to the active function. +// Operates on the global context. +func VPINSRB(i, mr, x, x1 operand.Op) { ctx.VPINSRB(i, mr, x, x1) } + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +// Construct and append a VPINSRD instruction to the active function. +func (c *Context) VPINSRD(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRD(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +// Construct and append a VPINSRD instruction to the active function. +// Operates on the global context. +func VPINSRD(i, mr, x, x1 operand.Op) { ctx.VPINSRD(i, mr, x, x1) } + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +// Construct and append a VPINSRQ instruction to the active function. +func (c *Context) VPINSRQ(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRQ(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +// Construct and append a VPINSRQ instruction to the active function. +// Operates on the global context. +func VPINSRQ(i, mr, x, x1 operand.Op) { ctx.VPINSRQ(i, mr, x, x1) } + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +// Construct and append a VPINSRW instruction to the active function. +func (c *Context) VPINSRW(i, mr, x, x1 operand.Op) { + if inst, err := x86.VPINSRW(i, mr, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +// Construct and append a VPINSRW instruction to the active function. +// Operates on the global context. +func VPINSRW(i, mr, x, x1 operand.Op) { ctx.VPINSRW(i, mr, x, x1) } + +// VPMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// VPMADDUBSW xmm xmm xmm +// VPMADDUBSW m128 xmm xmm +// VPMADDUBSW ymm ymm ymm +// VPMADDUBSW m256 ymm ymm +// Construct and append a VPMADDUBSW instruction to the active function. +func (c *Context) VPMADDUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMADDUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// VPMADDUBSW xmm xmm xmm +// VPMADDUBSW m128 xmm xmm +// VPMADDUBSW ymm ymm ymm +// VPMADDUBSW m256 ymm ymm +// Construct and append a VPMADDUBSW instruction to the active function. +// Operates on the global context. +func VPMADDUBSW(mxy, xy, xy1 operand.Op) { ctx.VPMADDUBSW(mxy, xy, xy1) } + +// VPMADDWD: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// VPMADDWD xmm xmm xmm +// VPMADDWD m128 xmm xmm +// VPMADDWD ymm ymm ymm +// VPMADDWD m256 ymm ymm +// Construct and append a VPMADDWD instruction to the active function. +func (c *Context) VPMADDWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMADDWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMADDWD: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// VPMADDWD xmm xmm xmm +// VPMADDWD m128 xmm xmm +// VPMADDWD ymm ymm ymm +// VPMADDWD m256 ymm ymm +// Construct and append a VPMADDWD instruction to the active function. +// Operates on the global context. +func VPMADDWD(mxy, xy, xy1 operand.Op) { ctx.VPMADDWD(mxy, xy, xy1) } + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +// Construct and append a VPMASKMOVD instruction to the active function. +func (c *Context) VPMASKMOVD(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VPMASKMOVD(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +// Construct and append a VPMASKMOVD instruction to the active function. +// Operates on the global context. +func VPMASKMOVD(mxy, xy, mxy1 operand.Op) { ctx.VPMASKMOVD(mxy, xy, mxy1) } + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +// Construct and append a VPMASKMOVQ instruction to the active function. +func (c *Context) VPMASKMOVQ(mxy, xy, mxy1 operand.Op) { + if inst, err := x86.VPMASKMOVQ(mxy, xy, mxy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +// Construct and append a VPMASKMOVQ instruction to the active function. +// Operates on the global context. +func VPMASKMOVQ(mxy, xy, mxy1 operand.Op) { ctx.VPMASKMOVQ(mxy, xy, mxy1) } + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +// Construct and append a VPMAXSB instruction to the active function. +func (c *Context) VPMAXSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +// Construct and append a VPMAXSB instruction to the active function. +// Operates on the global context. +func VPMAXSB(mxy, xy, xy1 operand.Op) { ctx.VPMAXSB(mxy, xy, xy1) } + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +// Construct and append a VPMAXSD instruction to the active function. +func (c *Context) VPMAXSD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +// Construct and append a VPMAXSD instruction to the active function. +// Operates on the global context. +func VPMAXSD(mxy, xy, xy1 operand.Op) { ctx.VPMAXSD(mxy, xy, xy1) } + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +// Construct and append a VPMAXSW instruction to the active function. +func (c *Context) VPMAXSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +// Construct and append a VPMAXSW instruction to the active function. +// Operates on the global context. +func VPMAXSW(mxy, xy, xy1 operand.Op) { ctx.VPMAXSW(mxy, xy, xy1) } + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +// Construct and append a VPMAXUB instruction to the active function. +func (c *Context) VPMAXUB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +// Construct and append a VPMAXUB instruction to the active function. +// Operates on the global context. +func VPMAXUB(mxy, xy, xy1 operand.Op) { ctx.VPMAXUB(mxy, xy, xy1) } + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +// Construct and append a VPMAXUD instruction to the active function. +func (c *Context) VPMAXUD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +// Construct and append a VPMAXUD instruction to the active function. +// Operates on the global context. +func VPMAXUD(mxy, xy, xy1 operand.Op) { ctx.VPMAXUD(mxy, xy, xy1) } + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +// Construct and append a VPMAXUW instruction to the active function. +func (c *Context) VPMAXUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMAXUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +// Construct and append a VPMAXUW instruction to the active function. +// Operates on the global context. +func VPMAXUW(mxy, xy, xy1 operand.Op) { ctx.VPMAXUW(mxy, xy, xy1) } + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +// Construct and append a VPMINSB instruction to the active function. +func (c *Context) VPMINSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +// Construct and append a VPMINSB instruction to the active function. +// Operates on the global context. +func VPMINSB(mxy, xy, xy1 operand.Op) { ctx.VPMINSB(mxy, xy, xy1) } + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +// Construct and append a VPMINSD instruction to the active function. +func (c *Context) VPMINSD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +// Construct and append a VPMINSD instruction to the active function. +// Operates on the global context. +func VPMINSD(mxy, xy, xy1 operand.Op) { ctx.VPMINSD(mxy, xy, xy1) } + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +// Construct and append a VPMINSW instruction to the active function. +func (c *Context) VPMINSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +// Construct and append a VPMINSW instruction to the active function. +// Operates on the global context. +func VPMINSW(mxy, xy, xy1 operand.Op) { ctx.VPMINSW(mxy, xy, xy1) } + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +// Construct and append a VPMINUB instruction to the active function. +func (c *Context) VPMINUB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +// Construct and append a VPMINUB instruction to the active function. +// Operates on the global context. +func VPMINUB(mxy, xy, xy1 operand.Op) { ctx.VPMINUB(mxy, xy, xy1) } + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +// Construct and append a VPMINUD instruction to the active function. +func (c *Context) VPMINUD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +// Construct and append a VPMINUD instruction to the active function. +// Operates on the global context. +func VPMINUD(mxy, xy, xy1 operand.Op) { ctx.VPMINUD(mxy, xy, xy1) } + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +// Construct and append a VPMINUW instruction to the active function. +func (c *Context) VPMINUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMINUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +// Construct and append a VPMINUW instruction to the active function. +// Operates on the global context. +func VPMINUW(mxy, xy, xy1 operand.Op) { ctx.VPMINUW(mxy, xy, xy1) } + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +// Construct and append a VPMOVMSKB instruction to the active function. +func (c *Context) VPMOVMSKB(xy, r operand.Op) { + if inst, err := x86.VPMOVMSKB(xy, r); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +// Construct and append a VPMOVMSKB instruction to the active function. +// Operates on the global context. +func VPMOVMSKB(xy, r operand.Op) { ctx.VPMOVMSKB(xy, r) } + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +// Construct and append a VPMOVSXBD instruction to the active function. +func (c *Context) VPMOVSXBD(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +// Construct and append a VPMOVSXBD instruction to the active function. +// Operates on the global context. +func VPMOVSXBD(mx, xy operand.Op) { ctx.VPMOVSXBD(mx, xy) } + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +// Construct and append a VPMOVSXBQ instruction to the active function. +func (c *Context) VPMOVSXBQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +// Construct and append a VPMOVSXBQ instruction to the active function. +// Operates on the global context. +func VPMOVSXBQ(mx, xy operand.Op) { ctx.VPMOVSXBQ(mx, xy) } + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +// Construct and append a VPMOVSXBW instruction to the active function. +func (c *Context) VPMOVSXBW(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXBW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +// Construct and append a VPMOVSXBW instruction to the active function. +// Operates on the global context. +func VPMOVSXBW(mx, xy operand.Op) { ctx.VPMOVSXBW(mx, xy) } + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +// Construct and append a VPMOVSXDQ instruction to the active function. +func (c *Context) VPMOVSXDQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXDQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +// Construct and append a VPMOVSXDQ instruction to the active function. +// Operates on the global context. +func VPMOVSXDQ(mx, xy operand.Op) { ctx.VPMOVSXDQ(mx, xy) } + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +// Construct and append a VPMOVSXWD instruction to the active function. +func (c *Context) VPMOVSXWD(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXWD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +// Construct and append a VPMOVSXWD instruction to the active function. +// Operates on the global context. +func VPMOVSXWD(mx, xy operand.Op) { ctx.VPMOVSXWD(mx, xy) } + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +// Construct and append a VPMOVSXWQ instruction to the active function. +func (c *Context) VPMOVSXWQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVSXWQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +// Construct and append a VPMOVSXWQ instruction to the active function. +// Operates on the global context. +func VPMOVSXWQ(mx, xy operand.Op) { ctx.VPMOVSXWQ(mx, xy) } + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +// Construct and append a VPMOVZXBD instruction to the active function. +func (c *Context) VPMOVZXBD(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +// Construct and append a VPMOVZXBD instruction to the active function. +// Operates on the global context. +func VPMOVZXBD(mx, xy operand.Op) { ctx.VPMOVZXBD(mx, xy) } + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +// Construct and append a VPMOVZXBQ instruction to the active function. +func (c *Context) VPMOVZXBQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +// Construct and append a VPMOVZXBQ instruction to the active function. +// Operates on the global context. +func VPMOVZXBQ(mx, xy operand.Op) { ctx.VPMOVZXBQ(mx, xy) } + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +// Construct and append a VPMOVZXBW instruction to the active function. +func (c *Context) VPMOVZXBW(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXBW(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +// Construct and append a VPMOVZXBW instruction to the active function. +// Operates on the global context. +func VPMOVZXBW(mx, xy operand.Op) { ctx.VPMOVZXBW(mx, xy) } + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +// Construct and append a VPMOVZXDQ instruction to the active function. +func (c *Context) VPMOVZXDQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXDQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +// Construct and append a VPMOVZXDQ instruction to the active function. +// Operates on the global context. +func VPMOVZXDQ(mx, xy operand.Op) { ctx.VPMOVZXDQ(mx, xy) } + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +// Construct and append a VPMOVZXWD instruction to the active function. +func (c *Context) VPMOVZXWD(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXWD(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +// Construct and append a VPMOVZXWD instruction to the active function. +// Operates on the global context. +func VPMOVZXWD(mx, xy operand.Op) { ctx.VPMOVZXWD(mx, xy) } + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +// Construct and append a VPMOVZXWQ instruction to the active function. +func (c *Context) VPMOVZXWQ(mx, xy operand.Op) { + if inst, err := x86.VPMOVZXWQ(mx, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +// Construct and append a VPMOVZXWQ instruction to the active function. +// Operates on the global context. +func VPMOVZXWQ(mx, xy operand.Op) { ctx.VPMOVZXWQ(mx, xy) } + +// VPMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// VPMULDQ xmm xmm xmm +// VPMULDQ m128 xmm xmm +// VPMULDQ ymm ymm ymm +// VPMULDQ m256 ymm ymm +// Construct and append a VPMULDQ instruction to the active function. +func (c *Context) VPMULDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// VPMULDQ xmm xmm xmm +// VPMULDQ m128 xmm xmm +// VPMULDQ ymm ymm ymm +// VPMULDQ m256 ymm ymm +// Construct and append a VPMULDQ instruction to the active function. +// Operates on the global context. +func VPMULDQ(mxy, xy, xy1 operand.Op) { ctx.VPMULDQ(mxy, xy, xy1) } + +// VPMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// VPMULHRSW xmm xmm xmm +// VPMULHRSW m128 xmm xmm +// VPMULHRSW ymm ymm ymm +// VPMULHRSW m256 ymm ymm +// Construct and append a VPMULHRSW instruction to the active function. +func (c *Context) VPMULHRSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHRSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// VPMULHRSW xmm xmm xmm +// VPMULHRSW m128 xmm xmm +// VPMULHRSW ymm ymm ymm +// VPMULHRSW m256 ymm ymm +// Construct and append a VPMULHRSW instruction to the active function. +// Operates on the global context. +func VPMULHRSW(mxy, xy, xy1 operand.Op) { ctx.VPMULHRSW(mxy, xy, xy1) } + +// VPMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// VPMULHUW xmm xmm xmm +// VPMULHUW m128 xmm xmm +// VPMULHUW ymm ymm ymm +// VPMULHUW m256 ymm ymm +// Construct and append a VPMULHUW instruction to the active function. +func (c *Context) VPMULHUW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHUW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// VPMULHUW xmm xmm xmm +// VPMULHUW m128 xmm xmm +// VPMULHUW ymm ymm ymm +// VPMULHUW m256 ymm ymm +// Construct and append a VPMULHUW instruction to the active function. +// Operates on the global context. +func VPMULHUW(mxy, xy, xy1 operand.Op) { ctx.VPMULHUW(mxy, xy, xy1) } + +// VPMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// VPMULHW xmm xmm xmm +// VPMULHW m128 xmm xmm +// VPMULHW ymm ymm ymm +// VPMULHW m256 ymm ymm +// Construct and append a VPMULHW instruction to the active function. +func (c *Context) VPMULHW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULHW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// VPMULHW xmm xmm xmm +// VPMULHW m128 xmm xmm +// VPMULHW ymm ymm ymm +// VPMULHW m256 ymm ymm +// Construct and append a VPMULHW instruction to the active function. +// Operates on the global context. +func VPMULHW(mxy, xy, xy1 operand.Op) { ctx.VPMULHW(mxy, xy, xy1) } + +// VPMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// VPMULLD xmm xmm xmm +// VPMULLD m128 xmm xmm +// VPMULLD ymm ymm ymm +// VPMULLD m256 ymm ymm +// Construct and append a VPMULLD instruction to the active function. +func (c *Context) VPMULLD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULLD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// VPMULLD xmm xmm xmm +// VPMULLD m128 xmm xmm +// VPMULLD ymm ymm ymm +// VPMULLD m256 ymm ymm +// Construct and append a VPMULLD instruction to the active function. +// Operates on the global context. +func VPMULLD(mxy, xy, xy1 operand.Op) { ctx.VPMULLD(mxy, xy, xy1) } + +// VPMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// VPMULLW xmm xmm xmm +// VPMULLW m128 xmm xmm +// VPMULLW ymm ymm ymm +// VPMULLW m256 ymm ymm +// Construct and append a VPMULLW instruction to the active function. +func (c *Context) VPMULLW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULLW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// VPMULLW xmm xmm xmm +// VPMULLW m128 xmm xmm +// VPMULLW ymm ymm ymm +// VPMULLW m256 ymm ymm +// Construct and append a VPMULLW instruction to the active function. +// Operates on the global context. +func VPMULLW(mxy, xy, xy1 operand.Op) { ctx.VPMULLW(mxy, xy, xy1) } + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +// Construct and append a VPMULUDQ instruction to the active function. +func (c *Context) VPMULUDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPMULUDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +// Construct and append a VPMULUDQ instruction to the active function. +// Operates on the global context. +func VPMULUDQ(mxy, xy, xy1 operand.Op) { ctx.VPMULUDQ(mxy, xy, xy1) } + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +// Construct and append a VPOR instruction to the active function. +func (c *Context) VPOR(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPOR(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +// Construct and append a VPOR instruction to the active function. +// Operates on the global context. +func VPOR(mxy, xy, xy1 operand.Op) { ctx.VPOR(mxy, xy, xy1) } + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +// Construct and append a VPSADBW instruction to the active function. +func (c *Context) VPSADBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSADBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +// Construct and append a VPSADBW instruction to the active function. +// Operates on the global context. +func VPSADBW(mxy, xy, xy1 operand.Op) { ctx.VPSADBW(mxy, xy, xy1) } + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +// Construct and append a VPSHUFB instruction to the active function. +func (c *Context) VPSHUFB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSHUFB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +// Construct and append a VPSHUFB instruction to the active function. +// Operates on the global context. +func VPSHUFB(mxy, xy, xy1 operand.Op) { ctx.VPSHUFB(mxy, xy, xy1) } + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +// Construct and append a VPSHUFD instruction to the active function. +func (c *Context) VPSHUFD(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFD(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +// Construct and append a VPSHUFD instruction to the active function. +// Operates on the global context. +func VPSHUFD(i, mxy, xy operand.Op) { ctx.VPSHUFD(i, mxy, xy) } + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +// Construct and append a VPSHUFHW instruction to the active function. +func (c *Context) VPSHUFHW(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFHW(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +// Construct and append a VPSHUFHW instruction to the active function. +// Operates on the global context. +func VPSHUFHW(i, mxy, xy operand.Op) { ctx.VPSHUFHW(i, mxy, xy) } + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +// Construct and append a VPSHUFLW instruction to the active function. +func (c *Context) VPSHUFLW(i, mxy, xy operand.Op) { + if inst, err := x86.VPSHUFLW(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +// Construct and append a VPSHUFLW instruction to the active function. +// Operates on the global context. +func VPSHUFLW(i, mxy, xy operand.Op) { ctx.VPSHUFLW(i, mxy, xy) } + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +// Construct and append a VPSIGNB instruction to the active function. +func (c *Context) VPSIGNB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGNB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +// Construct and append a VPSIGNB instruction to the active function. +// Operates on the global context. +func VPSIGNB(mxy, xy, xy1 operand.Op) { ctx.VPSIGNB(mxy, xy, xy1) } + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +// Construct and append a VPSIGND instruction to the active function. +func (c *Context) VPSIGND(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGND(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +// Construct and append a VPSIGND instruction to the active function. +// Operates on the global context. +func VPSIGND(mxy, xy, xy1 operand.Op) { ctx.VPSIGND(mxy, xy, xy1) } + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +// Construct and append a VPSIGNW instruction to the active function. +func (c *Context) VPSIGNW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSIGNW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +// Construct and append a VPSIGNW instruction to the active function. +// Operates on the global context. +func VPSIGNW(mxy, xy, xy1 operand.Op) { ctx.VPSIGNW(mxy, xy, xy1) } + +// VPSLLD: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLD imm8 xmm xmm +// VPSLLD xmm xmm xmm +// VPSLLD m128 xmm xmm +// VPSLLD imm8 ymm ymm +// VPSLLD xmm ymm ymm +// VPSLLD m128 ymm ymm +// Construct and append a VPSLLD instruction to the active function. +func (c *Context) VPSLLD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLD: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLD imm8 xmm xmm +// VPSLLD xmm xmm xmm +// VPSLLD m128 xmm xmm +// VPSLLD imm8 ymm ymm +// VPSLLD xmm ymm ymm +// VPSLLD m128 ymm ymm +// Construct and append a VPSLLD instruction to the active function. +// Operates on the global context. +func VPSLLD(imx, xy, xy1 operand.Op) { ctx.VPSLLD(imx, xy, xy1) } + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +// Construct and append a VPSLLDQ instruction to the active function. +func (c *Context) VPSLLDQ(i, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLDQ(i, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +// Construct and append a VPSLLDQ instruction to the active function. +// Operates on the global context. +func VPSLLDQ(i, xy, xy1 operand.Op) { ctx.VPSLLDQ(i, xy, xy1) } + +// VPSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLQ imm8 xmm xmm +// VPSLLQ xmm xmm xmm +// VPSLLQ m128 xmm xmm +// VPSLLQ imm8 ymm ymm +// VPSLLQ xmm ymm ymm +// VPSLLQ m128 ymm ymm +// Construct and append a VPSLLQ instruction to the active function. +func (c *Context) VPSLLQ(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLQ(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLQ imm8 xmm xmm +// VPSLLQ xmm xmm xmm +// VPSLLQ m128 xmm xmm +// VPSLLQ imm8 ymm ymm +// VPSLLQ xmm ymm ymm +// VPSLLQ m128 ymm ymm +// Construct and append a VPSLLQ instruction to the active function. +// Operates on the global context. +func VPSLLQ(imx, xy, xy1 operand.Op) { ctx.VPSLLQ(imx, xy, xy1) } + +// VPSLLVD: Variable Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLVD xmm xmm xmm +// VPSLLVD m128 xmm xmm +// VPSLLVD ymm ymm ymm +// VPSLLVD m256 ymm ymm +// Construct and append a VPSLLVD instruction to the active function. +func (c *Context) VPSLLVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLVD: Variable Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLVD xmm xmm xmm +// VPSLLVD m128 xmm xmm +// VPSLLVD ymm ymm ymm +// VPSLLVD m256 ymm ymm +// Construct and append a VPSLLVD instruction to the active function. +// Operates on the global context. +func VPSLLVD(mxy, xy, xy1 operand.Op) { ctx.VPSLLVD(mxy, xy, xy1) } + +// VPSLLVQ: Variable Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLVQ xmm xmm xmm +// VPSLLVQ m128 xmm xmm +// VPSLLVQ ymm ymm ymm +// VPSLLVQ m256 ymm ymm +// Construct and append a VPSLLVQ instruction to the active function. +func (c *Context) VPSLLVQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLVQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLVQ: Variable Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLVQ xmm xmm xmm +// VPSLLVQ m128 xmm xmm +// VPSLLVQ ymm ymm ymm +// VPSLLVQ m256 ymm ymm +// Construct and append a VPSLLVQ instruction to the active function. +// Operates on the global context. +func VPSLLVQ(mxy, xy, xy1 operand.Op) { ctx.VPSLLVQ(mxy, xy, xy1) } + +// VPSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// VPSLLW imm8 xmm xmm +// VPSLLW xmm xmm xmm +// VPSLLW m128 xmm xmm +// VPSLLW imm8 ymm ymm +// VPSLLW xmm ymm ymm +// VPSLLW m128 ymm ymm +// Construct and append a VPSLLW instruction to the active function. +func (c *Context) VPSLLW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSLLW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// VPSLLW imm8 xmm xmm +// VPSLLW xmm xmm xmm +// VPSLLW m128 xmm xmm +// VPSLLW imm8 ymm ymm +// VPSLLW xmm ymm ymm +// VPSLLW m128 ymm ymm +// Construct and append a VPSLLW instruction to the active function. +// Operates on the global context. +func VPSLLW(imx, xy, xy1 operand.Op) { ctx.VPSLLW(imx, xy, xy1) } + +// VPSRAD: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAD imm8 xmm xmm +// VPSRAD xmm xmm xmm +// VPSRAD m128 xmm xmm +// VPSRAD imm8 ymm ymm +// VPSRAD xmm ymm ymm +// VPSRAD m128 ymm ymm +// Construct and append a VPSRAD instruction to the active function. +func (c *Context) VPSRAD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRAD: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAD imm8 xmm xmm +// VPSRAD xmm xmm xmm +// VPSRAD m128 xmm xmm +// VPSRAD imm8 ymm ymm +// VPSRAD xmm ymm ymm +// VPSRAD m128 ymm ymm +// Construct and append a VPSRAD instruction to the active function. +// Operates on the global context. +func VPSRAD(imx, xy, xy1 operand.Op) { ctx.VPSRAD(imx, xy, xy1) } + +// VPSRAVD: Variable Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAVD xmm xmm xmm +// VPSRAVD m128 xmm xmm +// VPSRAVD ymm ymm ymm +// VPSRAVD m256 ymm ymm +// Construct and append a VPSRAVD instruction to the active function. +func (c *Context) VPSRAVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRAVD: Variable Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAVD xmm xmm xmm +// VPSRAVD m128 xmm xmm +// VPSRAVD ymm ymm ymm +// VPSRAVD m256 ymm ymm +// Construct and append a VPSRAVD instruction to the active function. +// Operates on the global context. +func VPSRAVD(mxy, xy, xy1 operand.Op) { ctx.VPSRAVD(mxy, xy, xy1) } + +// VPSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// VPSRAW imm8 xmm xmm +// VPSRAW xmm xmm xmm +// VPSRAW m128 xmm xmm +// VPSRAW imm8 ymm ymm +// VPSRAW xmm ymm ymm +// VPSRAW m128 ymm ymm +// Construct and append a VPSRAW instruction to the active function. +func (c *Context) VPSRAW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRAW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// VPSRAW imm8 xmm xmm +// VPSRAW xmm xmm xmm +// VPSRAW m128 xmm xmm +// VPSRAW imm8 ymm ymm +// VPSRAW xmm ymm ymm +// VPSRAW m128 ymm ymm +// Construct and append a VPSRAW instruction to the active function. +// Operates on the global context. +func VPSRAW(imx, xy, xy1 operand.Op) { ctx.VPSRAW(imx, xy, xy1) } + +// VPSRLD: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLD imm8 xmm xmm +// VPSRLD xmm xmm xmm +// VPSRLD m128 xmm xmm +// VPSRLD imm8 ymm ymm +// VPSRLD xmm ymm ymm +// VPSRLD m128 ymm ymm +// Construct and append a VPSRLD instruction to the active function. +func (c *Context) VPSRLD(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLD(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLD: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLD imm8 xmm xmm +// VPSRLD xmm xmm xmm +// VPSRLD m128 xmm xmm +// VPSRLD imm8 ymm ymm +// VPSRLD xmm ymm ymm +// VPSRLD m128 ymm ymm +// Construct and append a VPSRLD instruction to the active function. +// Operates on the global context. +func VPSRLD(imx, xy, xy1 operand.Op) { ctx.VPSRLD(imx, xy, xy1) } + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +// Construct and append a VPSRLDQ instruction to the active function. +func (c *Context) VPSRLDQ(i, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLDQ(i, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +// Construct and append a VPSRLDQ instruction to the active function. +// Operates on the global context. +func VPSRLDQ(i, xy, xy1 operand.Op) { ctx.VPSRLDQ(i, xy, xy1) } + +// VPSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLQ imm8 xmm xmm +// VPSRLQ xmm xmm xmm +// VPSRLQ m128 xmm xmm +// VPSRLQ imm8 ymm ymm +// VPSRLQ xmm ymm ymm +// VPSRLQ m128 ymm ymm +// Construct and append a VPSRLQ instruction to the active function. +func (c *Context) VPSRLQ(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLQ(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLQ imm8 xmm xmm +// VPSRLQ xmm xmm xmm +// VPSRLQ m128 xmm xmm +// VPSRLQ imm8 ymm ymm +// VPSRLQ xmm ymm ymm +// VPSRLQ m128 ymm ymm +// Construct and append a VPSRLQ instruction to the active function. +// Operates on the global context. +func VPSRLQ(imx, xy, xy1 operand.Op) { ctx.VPSRLQ(imx, xy, xy1) } + +// VPSRLVD: Variable Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLVD xmm xmm xmm +// VPSRLVD m128 xmm xmm +// VPSRLVD ymm ymm ymm +// VPSRLVD m256 ymm ymm +// Construct and append a VPSRLVD instruction to the active function. +func (c *Context) VPSRLVD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLVD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLVD: Variable Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLVD xmm xmm xmm +// VPSRLVD m128 xmm xmm +// VPSRLVD ymm ymm ymm +// VPSRLVD m256 ymm ymm +// Construct and append a VPSRLVD instruction to the active function. +// Operates on the global context. +func VPSRLVD(mxy, xy, xy1 operand.Op) { ctx.VPSRLVD(mxy, xy, xy1) } + +// VPSRLVQ: Variable Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLVQ xmm xmm xmm +// VPSRLVQ m128 xmm xmm +// VPSRLVQ ymm ymm ymm +// VPSRLVQ m256 ymm ymm +// Construct and append a VPSRLVQ instruction to the active function. +func (c *Context) VPSRLVQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLVQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLVQ: Variable Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLVQ xmm xmm xmm +// VPSRLVQ m128 xmm xmm +// VPSRLVQ ymm ymm ymm +// VPSRLVQ m256 ymm ymm +// Construct and append a VPSRLVQ instruction to the active function. +// Operates on the global context. +func VPSRLVQ(mxy, xy, xy1 operand.Op) { ctx.VPSRLVQ(mxy, xy, xy1) } + +// VPSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// VPSRLW imm8 xmm xmm +// VPSRLW xmm xmm xmm +// VPSRLW m128 xmm xmm +// VPSRLW imm8 ymm ymm +// VPSRLW xmm ymm ymm +// VPSRLW m128 ymm ymm +// Construct and append a VPSRLW instruction to the active function. +func (c *Context) VPSRLW(imx, xy, xy1 operand.Op) { + if inst, err := x86.VPSRLW(imx, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// VPSRLW imm8 xmm xmm +// VPSRLW xmm xmm xmm +// VPSRLW m128 xmm xmm +// VPSRLW imm8 ymm ymm +// VPSRLW xmm ymm ymm +// VPSRLW m128 ymm ymm +// Construct and append a VPSRLW instruction to the active function. +// Operates on the global context. +func VPSRLW(imx, xy, xy1 operand.Op) { ctx.VPSRLW(imx, xy, xy1) } + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +// Construct and append a VPSUBB instruction to the active function. +func (c *Context) VPSUBB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +// Construct and append a VPSUBB instruction to the active function. +// Operates on the global context. +func VPSUBB(mxy, xy, xy1 operand.Op) { ctx.VPSUBB(mxy, xy, xy1) } + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +// Construct and append a VPSUBD instruction to the active function. +func (c *Context) VPSUBD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +// Construct and append a VPSUBD instruction to the active function. +// Operates on the global context. +func VPSUBD(mxy, xy, xy1 operand.Op) { ctx.VPSUBD(mxy, xy, xy1) } + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +// Construct and append a VPSUBQ instruction to the active function. +func (c *Context) VPSUBQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +// Construct and append a VPSUBQ instruction to the active function. +// Operates on the global context. +func VPSUBQ(mxy, xy, xy1 operand.Op) { ctx.VPSUBQ(mxy, xy, xy1) } + +// VPSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSB xmm xmm xmm +// VPSUBSB m128 xmm xmm +// VPSUBSB ymm ymm ymm +// VPSUBSB m256 ymm ymm +// Construct and append a VPSUBSB instruction to the active function. +func (c *Context) VPSUBSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSB xmm xmm xmm +// VPSUBSB m128 xmm xmm +// VPSUBSB ymm ymm ymm +// VPSUBSB m256 ymm ymm +// Construct and append a VPSUBSB instruction to the active function. +// Operates on the global context. +func VPSUBSB(mxy, xy, xy1 operand.Op) { ctx.VPSUBSB(mxy, xy, xy1) } + +// VPSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSW xmm xmm xmm +// VPSUBSW m128 xmm xmm +// VPSUBSW ymm ymm ymm +// VPSUBSW m256 ymm ymm +// Construct and append a VPSUBSW instruction to the active function. +func (c *Context) VPSUBSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSW xmm xmm xmm +// VPSUBSW m128 xmm xmm +// VPSUBSW ymm ymm ymm +// VPSUBSW m256 ymm ymm +// Construct and append a VPSUBSW instruction to the active function. +// Operates on the global context. +func VPSUBSW(mxy, xy, xy1 operand.Op) { ctx.VPSUBSW(mxy, xy, xy1) } + +// VPSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSB xmm xmm xmm +// VPSUBUSB m128 xmm xmm +// VPSUBUSB ymm ymm ymm +// VPSUBUSB m256 ymm ymm +// Construct and append a VPSUBUSB instruction to the active function. +func (c *Context) VPSUBUSB(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBUSB(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSB xmm xmm xmm +// VPSUBUSB m128 xmm xmm +// VPSUBUSB ymm ymm ymm +// VPSUBUSB m256 ymm ymm +// Construct and append a VPSUBUSB instruction to the active function. +// Operates on the global context. +func VPSUBUSB(mxy, xy, xy1 operand.Op) { ctx.VPSUBUSB(mxy, xy, xy1) } + +// VPSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSW xmm xmm xmm +// VPSUBUSW m128 xmm xmm +// VPSUBUSW ymm ymm ymm +// VPSUBUSW m256 ymm ymm +// Construct and append a VPSUBUSW instruction to the active function. +func (c *Context) VPSUBUSW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBUSW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSW xmm xmm xmm +// VPSUBUSW m128 xmm xmm +// VPSUBUSW ymm ymm ymm +// VPSUBUSW m256 ymm ymm +// Construct and append a VPSUBUSW instruction to the active function. +// Operates on the global context. +func VPSUBUSW(mxy, xy, xy1 operand.Op) { ctx.VPSUBUSW(mxy, xy, xy1) } + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +// Construct and append a VPSUBW instruction to the active function. +func (c *Context) VPSUBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPSUBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +// Construct and append a VPSUBW instruction to the active function. +// Operates on the global context. +func VPSUBW(mxy, xy, xy1 operand.Op) { ctx.VPSUBW(mxy, xy, xy1) } + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +// Construct and append a VPTEST instruction to the active function. +func (c *Context) VPTEST(mxy, xy operand.Op) { + if inst, err := x86.VPTEST(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +// Construct and append a VPTEST instruction to the active function. +// Operates on the global context. +func VPTEST(mxy, xy operand.Op) { ctx.VPTEST(mxy, xy) } + +// VPUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKHBW xmm xmm xmm +// VPUNPCKHBW m128 xmm xmm +// VPUNPCKHBW ymm ymm ymm +// VPUNPCKHBW m256 ymm ymm +// Construct and append a VPUNPCKHBW instruction to the active function. +func (c *Context) VPUNPCKHBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKHBW xmm xmm xmm +// VPUNPCKHBW m128 xmm xmm +// VPUNPCKHBW ymm ymm ymm +// VPUNPCKHBW m256 ymm ymm +// Construct and append a VPUNPCKHBW instruction to the active function. +// Operates on the global context. +func VPUNPCKHBW(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHBW(mxy, xy, xy1) } + +// VPUNPCKHDQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKHDQ xmm xmm xmm +// VPUNPCKHDQ m128 xmm xmm +// VPUNPCKHDQ ymm ymm ymm +// VPUNPCKHDQ m256 ymm ymm +// Construct and append a VPUNPCKHDQ instruction to the active function. +func (c *Context) VPUNPCKHDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKHDQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKHDQ xmm xmm xmm +// VPUNPCKHDQ m128 xmm xmm +// VPUNPCKHDQ ymm ymm ymm +// VPUNPCKHDQ m256 ymm ymm +// Construct and append a VPUNPCKHDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKHDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHDQ(mxy, xy, xy1) } + +// VPUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKHQDQ xmm xmm xmm +// VPUNPCKHQDQ m128 xmm xmm +// VPUNPCKHQDQ ymm ymm ymm +// VPUNPCKHQDQ m256 ymm ymm +// Construct and append a VPUNPCKHQDQ instruction to the active function. +func (c *Context) VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHQDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKHQDQ xmm xmm xmm +// VPUNPCKHQDQ m128 xmm xmm +// VPUNPCKHQDQ ymm ymm ymm +// VPUNPCKHQDQ m256 ymm ymm +// Construct and append a VPUNPCKHQDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHQDQ(mxy, xy, xy1) } + +// VPUNPCKHWD: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKHWD xmm xmm xmm +// VPUNPCKHWD m128 xmm xmm +// VPUNPCKHWD ymm ymm ymm +// VPUNPCKHWD m256 ymm ymm +// Construct and append a VPUNPCKHWD instruction to the active function. +func (c *Context) VPUNPCKHWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKHWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKHWD: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKHWD xmm xmm xmm +// VPUNPCKHWD m128 xmm xmm +// VPUNPCKHWD ymm ymm ymm +// VPUNPCKHWD m256 ymm ymm +// Construct and append a VPUNPCKHWD instruction to the active function. +// Operates on the global context. +func VPUNPCKHWD(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKHWD(mxy, xy, xy1) } + +// VPUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKLBW xmm xmm xmm +// VPUNPCKLBW m128 xmm xmm +// VPUNPCKLBW ymm ymm ymm +// VPUNPCKLBW m256 ymm ymm +// Construct and append a VPUNPCKLBW instruction to the active function. +func (c *Context) VPUNPCKLBW(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLBW(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKLBW xmm xmm xmm +// VPUNPCKLBW m128 xmm xmm +// VPUNPCKLBW ymm ymm ymm +// VPUNPCKLBW m256 ymm ymm +// Construct and append a VPUNPCKLBW instruction to the active function. +// Operates on the global context. +func VPUNPCKLBW(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLBW(mxy, xy, xy1) } + +// VPUNPCKLDQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKLDQ xmm xmm xmm +// VPUNPCKLDQ m128 xmm xmm +// VPUNPCKLDQ ymm ymm ymm +// VPUNPCKLDQ m256 ymm ymm +// Construct and append a VPUNPCKLDQ instruction to the active function. +func (c *Context) VPUNPCKLDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKLDQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKLDQ xmm xmm xmm +// VPUNPCKLDQ m128 xmm xmm +// VPUNPCKLDQ ymm ymm ymm +// VPUNPCKLDQ m256 ymm ymm +// Construct and append a VPUNPCKLDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKLDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLDQ(mxy, xy, xy1) } + +// VPUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKLQDQ xmm xmm xmm +// VPUNPCKLQDQ m128 xmm xmm +// VPUNPCKLQDQ ymm ymm ymm +// VPUNPCKLQDQ m256 ymm ymm +// Construct and append a VPUNPCKLQDQ instruction to the active function. +func (c *Context) VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLQDQ(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKLQDQ xmm xmm xmm +// VPUNPCKLQDQ m128 xmm xmm +// VPUNPCKLQDQ ymm ymm ymm +// VPUNPCKLQDQ m256 ymm ymm +// Construct and append a VPUNPCKLQDQ instruction to the active function. +// Operates on the global context. +func VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLQDQ(mxy, xy, xy1) } + +// VPUNPCKLWD: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKLWD xmm xmm xmm +// VPUNPCKLWD m128 xmm xmm +// VPUNPCKLWD ymm ymm ymm +// VPUNPCKLWD m256 ymm ymm +// Construct and append a VPUNPCKLWD instruction to the active function. +func (c *Context) VPUNPCKLWD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPUNPCKLWD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPUNPCKLWD: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKLWD xmm xmm xmm +// VPUNPCKLWD m128 xmm xmm +// VPUNPCKLWD ymm ymm ymm +// VPUNPCKLWD m256 ymm ymm +// Construct and append a VPUNPCKLWD instruction to the active function. +// Operates on the global context. +func VPUNPCKLWD(mxy, xy, xy1 operand.Op) { ctx.VPUNPCKLWD(mxy, xy, xy1) } + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +// Construct and append a VPXOR instruction to the active function. +func (c *Context) VPXOR(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VPXOR(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +// Construct and append a VPXOR instruction to the active function. +// Operates on the global context. +func VPXOR(mxy, xy, xy1 operand.Op) { ctx.VPXOR(mxy, xy, xy1) } + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +// Construct and append a VRCPPS instruction to the active function. +func (c *Context) VRCPPS(mxy, xy operand.Op) { + if inst, err := x86.VRCPPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +// Construct and append a VRCPPS instruction to the active function. +// Operates on the global context. +func VRCPPS(mxy, xy operand.Op) { ctx.VRCPPS(mxy, xy) } + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +// Construct and append a VRCPSS instruction to the active function. +func (c *Context) VRCPSS(mx, x, x1 operand.Op) { + if inst, err := x86.VRCPSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +// Construct and append a VRCPSS instruction to the active function. +// Operates on the global context. +func VRCPSS(mx, x, x1 operand.Op) { ctx.VRCPSS(mx, x, x1) } + +// VROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPD imm8 xmm xmm +// VROUNDPD imm8 m128 xmm +// VROUNDPD imm8 ymm ymm +// VROUNDPD imm8 m256 ymm +// Construct and append a VROUNDPD instruction to the active function. +func (c *Context) VROUNDPD(i, mxy, xy operand.Op) { + if inst, err := x86.VROUNDPD(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPD imm8 xmm xmm +// VROUNDPD imm8 m128 xmm +// VROUNDPD imm8 ymm ymm +// VROUNDPD imm8 m256 ymm +// Construct and append a VROUNDPD instruction to the active function. +// Operates on the global context. +func VROUNDPD(i, mxy, xy operand.Op) { ctx.VROUNDPD(i, mxy, xy) } + +// VROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPS imm8 xmm xmm +// VROUNDPS imm8 m128 xmm +// VROUNDPS imm8 ymm ymm +// VROUNDPS imm8 m256 ymm +// Construct and append a VROUNDPS instruction to the active function. +func (c *Context) VROUNDPS(i, mxy, xy operand.Op) { + if inst, err := x86.VROUNDPS(i, mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPS imm8 xmm xmm +// VROUNDPS imm8 m128 xmm +// VROUNDPS imm8 ymm ymm +// VROUNDPS imm8 m256 ymm +// Construct and append a VROUNDPS instruction to the active function. +// Operates on the global context. +func VROUNDPS(i, mxy, xy operand.Op) { ctx.VROUNDPS(i, mxy, xy) } + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +// Construct and append a VROUNDSD instruction to the active function. +func (c *Context) VROUNDSD(i, mx, x, x1 operand.Op) { + if inst, err := x86.VROUNDSD(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +// Construct and append a VROUNDSD instruction to the active function. +// Operates on the global context. +func VROUNDSD(i, mx, x, x1 operand.Op) { ctx.VROUNDSD(i, mx, x, x1) } + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +// Construct and append a VROUNDSS instruction to the active function. +func (c *Context) VROUNDSS(i, mx, x, x1 operand.Op) { + if inst, err := x86.VROUNDSS(i, mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +// Construct and append a VROUNDSS instruction to the active function. +// Operates on the global context. +func VROUNDSS(i, mx, x, x1 operand.Op) { ctx.VROUNDSS(i, mx, x, x1) } + +// VRSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRSQRTPS xmm xmm +// VRSQRTPS m128 xmm +// VRSQRTPS ymm ymm +// VRSQRTPS m256 ymm +// Construct and append a VRSQRTPS instruction to the active function. +func (c *Context) VRSQRTPS(mxy, xy operand.Op) { + if inst, err := x86.VRSQRTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRSQRTPS xmm xmm +// VRSQRTPS m128 xmm +// VRSQRTPS ymm ymm +// VRSQRTPS m256 ymm +// Construct and append a VRSQRTPS instruction to the active function. +// Operates on the global context. +func VRSQRTPS(mxy, xy operand.Op) { ctx.VRSQRTPS(mxy, xy) } + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +// Construct and append a VRSQRTSS instruction to the active function. +func (c *Context) VRSQRTSS(mx, x, x1 operand.Op) { + if inst, err := x86.VRSQRTSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +// Construct and append a VRSQRTSS instruction to the active function. +// Operates on the global context. +func VRSQRTSS(mx, x, x1 operand.Op) { ctx.VRSQRTSS(mx, x, x1) } + +// VSHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPD imm8 xmm xmm xmm +// VSHUFPD imm8 m128 xmm xmm +// VSHUFPD imm8 ymm ymm ymm +// VSHUFPD imm8 m256 ymm ymm +// Construct and append a VSHUFPD instruction to the active function. +func (c *Context) VSHUFPD(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSHUFPD(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPD imm8 xmm xmm xmm +// VSHUFPD imm8 m128 xmm xmm +// VSHUFPD imm8 ymm ymm ymm +// VSHUFPD imm8 m256 ymm ymm +// Construct and append a VSHUFPD instruction to the active function. +// Operates on the global context. +func VSHUFPD(i, mxy, xy, xy1 operand.Op) { ctx.VSHUFPD(i, mxy, xy, xy1) } + +// VSHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPS imm8 xmm xmm xmm +// VSHUFPS imm8 m128 xmm xmm +// VSHUFPS imm8 ymm ymm ymm +// VSHUFPS imm8 m256 ymm ymm +// Construct and append a VSHUFPS instruction to the active function. +func (c *Context) VSHUFPS(i, mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSHUFPS(i, mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPS imm8 xmm xmm xmm +// VSHUFPS imm8 m128 xmm xmm +// VSHUFPS imm8 ymm ymm ymm +// VSHUFPS imm8 m256 ymm ymm +// Construct and append a VSHUFPS instruction to the active function. +// Operates on the global context. +func VSHUFPS(i, mxy, xy, xy1 operand.Op) { ctx.VSHUFPS(i, mxy, xy, xy1) } + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +// Construct and append a VSQRTPD instruction to the active function. +func (c *Context) VSQRTPD(mxy, xy operand.Op) { + if inst, err := x86.VSQRTPD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +// Construct and append a VSQRTPD instruction to the active function. +// Operates on the global context. +func VSQRTPD(mxy, xy operand.Op) { ctx.VSQRTPD(mxy, xy) } + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +// Construct and append a VSQRTPS instruction to the active function. +func (c *Context) VSQRTPS(mxy, xy operand.Op) { + if inst, err := x86.VSQRTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +// Construct and append a VSQRTPS instruction to the active function. +// Operates on the global context. +func VSQRTPS(mxy, xy operand.Op) { ctx.VSQRTPS(mxy, xy) } + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +// Construct and append a VSQRTSD instruction to the active function. +func (c *Context) VSQRTSD(mx, x, x1 operand.Op) { + if inst, err := x86.VSQRTSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +// Construct and append a VSQRTSD instruction to the active function. +// Operates on the global context. +func VSQRTSD(mx, x, x1 operand.Op) { ctx.VSQRTSD(mx, x, x1) } + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +// Construct and append a VSQRTSS instruction to the active function. +func (c *Context) VSQRTSS(mx, x, x1 operand.Op) { + if inst, err := x86.VSQRTSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +// Construct and append a VSQRTSS instruction to the active function. +// Operates on the global context. +func VSQRTSS(mx, x, x1 operand.Op) { ctx.VSQRTSS(mx, x, x1) } + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +// Construct and append a VSTMXCSR instruction to the active function. +func (c *Context) VSTMXCSR(m operand.Op) { + if inst, err := x86.VSTMXCSR(m); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +// Construct and append a VSTMXCSR instruction to the active function. +// Operates on the global context. +func VSTMXCSR(m operand.Op) { ctx.VSTMXCSR(m) } + +// VSUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPD xmm xmm xmm +// VSUBPD m128 xmm xmm +// VSUBPD ymm ymm ymm +// VSUBPD m256 ymm ymm +// Construct and append a VSUBPD instruction to the active function. +func (c *Context) VSUBPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSUBPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPD xmm xmm xmm +// VSUBPD m128 xmm xmm +// VSUBPD ymm ymm ymm +// VSUBPD m256 ymm ymm +// Construct and append a VSUBPD instruction to the active function. +// Operates on the global context. +func VSUBPD(mxy, xy, xy1 operand.Op) { ctx.VSUBPD(mxy, xy, xy1) } + +// VSUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPS xmm xmm xmm +// VSUBPS m128 xmm xmm +// VSUBPS ymm ymm ymm +// VSUBPS m256 ymm ymm +// Construct and append a VSUBPS instruction to the active function. +func (c *Context) VSUBPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VSUBPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPS xmm xmm xmm +// VSUBPS m128 xmm xmm +// VSUBPS ymm ymm ymm +// VSUBPS m256 ymm ymm +// Construct and append a VSUBPS instruction to the active function. +// Operates on the global context. +func VSUBPS(mxy, xy, xy1 operand.Op) { ctx.VSUBPS(mxy, xy, xy1) } + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +// Construct and append a VSUBSD instruction to the active function. +func (c *Context) VSUBSD(mx, x, x1 operand.Op) { + if inst, err := x86.VSUBSD(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +// Construct and append a VSUBSD instruction to the active function. +// Operates on the global context. +func VSUBSD(mx, x, x1 operand.Op) { ctx.VSUBSD(mx, x, x1) } + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +// Construct and append a VSUBSS instruction to the active function. +func (c *Context) VSUBSS(mx, x, x1 operand.Op) { + if inst, err := x86.VSUBSS(mx, x, x1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +// Construct and append a VSUBSS instruction to the active function. +// Operates on the global context. +func VSUBSS(mx, x, x1 operand.Op) { ctx.VSUBSS(mx, x, x1) } + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +// Construct and append a VTESTPD instruction to the active function. +func (c *Context) VTESTPD(mxy, xy operand.Op) { + if inst, err := x86.VTESTPD(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +// Construct and append a VTESTPD instruction to the active function. +// Operates on the global context. +func VTESTPD(mxy, xy operand.Op) { ctx.VTESTPD(mxy, xy) } + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +// Construct and append a VTESTPS instruction to the active function. +func (c *Context) VTESTPS(mxy, xy operand.Op) { + if inst, err := x86.VTESTPS(mxy, xy); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +// Construct and append a VTESTPS instruction to the active function. +// Operates on the global context. +func VTESTPS(mxy, xy operand.Op) { ctx.VTESTPS(mxy, xy) } + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +// Construct and append a VUCOMISD instruction to the active function. +func (c *Context) VUCOMISD(mx, x operand.Op) { + if inst, err := x86.VUCOMISD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +// Construct and append a VUCOMISD instruction to the active function. +// Operates on the global context. +func VUCOMISD(mx, x operand.Op) { ctx.VUCOMISD(mx, x) } + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +// Construct and append a VUCOMISS instruction to the active function. +func (c *Context) VUCOMISS(mx, x operand.Op) { + if inst, err := x86.VUCOMISS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +// Construct and append a VUCOMISS instruction to the active function. +// Operates on the global context. +func VUCOMISS(mx, x operand.Op) { ctx.VUCOMISS(mx, x) } + +// VUNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPD xmm xmm xmm +// VUNPCKHPD m128 xmm xmm +// VUNPCKHPD ymm ymm ymm +// VUNPCKHPD m256 ymm ymm +// Construct and append a VUNPCKHPD instruction to the active function. +func (c *Context) VUNPCKHPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKHPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPD xmm xmm xmm +// VUNPCKHPD m128 xmm xmm +// VUNPCKHPD ymm ymm ymm +// VUNPCKHPD m256 ymm ymm +// Construct and append a VUNPCKHPD instruction to the active function. +// Operates on the global context. +func VUNPCKHPD(mxy, xy, xy1 operand.Op) { ctx.VUNPCKHPD(mxy, xy, xy1) } + +// VUNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPS xmm xmm xmm +// VUNPCKHPS m128 xmm xmm +// VUNPCKHPS ymm ymm ymm +// VUNPCKHPS m256 ymm ymm +// Construct and append a VUNPCKHPS instruction to the active function. +func (c *Context) VUNPCKHPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKHPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPS xmm xmm xmm +// VUNPCKHPS m128 xmm xmm +// VUNPCKHPS ymm ymm ymm +// VUNPCKHPS m256 ymm ymm +// Construct and append a VUNPCKHPS instruction to the active function. +// Operates on the global context. +func VUNPCKHPS(mxy, xy, xy1 operand.Op) { ctx.VUNPCKHPS(mxy, xy, xy1) } + +// VUNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPD xmm xmm xmm +// VUNPCKLPD m128 xmm xmm +// VUNPCKLPD ymm ymm ymm +// VUNPCKLPD m256 ymm ymm +// Construct and append a VUNPCKLPD instruction to the active function. +func (c *Context) VUNPCKLPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKLPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPD xmm xmm xmm +// VUNPCKLPD m128 xmm xmm +// VUNPCKLPD ymm ymm ymm +// VUNPCKLPD m256 ymm ymm +// Construct and append a VUNPCKLPD instruction to the active function. +// Operates on the global context. +func VUNPCKLPD(mxy, xy, xy1 operand.Op) { ctx.VUNPCKLPD(mxy, xy, xy1) } + +// VUNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPS xmm xmm xmm +// VUNPCKLPS m128 xmm xmm +// VUNPCKLPS ymm ymm ymm +// VUNPCKLPS m256 ymm ymm +// Construct and append a VUNPCKLPS instruction to the active function. +func (c *Context) VUNPCKLPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VUNPCKLPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VUNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPS xmm xmm xmm +// VUNPCKLPS m128 xmm xmm +// VUNPCKLPS ymm ymm ymm +// VUNPCKLPS m256 ymm ymm +// Construct and append a VUNPCKLPS instruction to the active function. +// Operates on the global context. +func VUNPCKLPS(mxy, xy, xy1 operand.Op) { ctx.VUNPCKLPS(mxy, xy, xy1) } + +// VXORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// VXORPD xmm xmm xmm +// VXORPD m128 xmm xmm +// VXORPD ymm ymm ymm +// VXORPD m256 ymm ymm +// Construct and append a VXORPD instruction to the active function. +func (c *Context) VXORPD(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VXORPD(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VXORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// VXORPD xmm xmm xmm +// VXORPD m128 xmm xmm +// VXORPD ymm ymm ymm +// VXORPD m256 ymm ymm +// Construct and append a VXORPD instruction to the active function. +// Operates on the global context. +func VXORPD(mxy, xy, xy1 operand.Op) { ctx.VXORPD(mxy, xy, xy1) } + +// VXORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// VXORPS xmm xmm xmm +// VXORPS m128 xmm xmm +// VXORPS ymm ymm ymm +// VXORPS m256 ymm ymm +// Construct and append a VXORPS instruction to the active function. +func (c *Context) VXORPS(mxy, xy, xy1 operand.Op) { + if inst, err := x86.VXORPS(mxy, xy, xy1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VXORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// VXORPS xmm xmm xmm +// VXORPS m128 xmm xmm +// VXORPS ymm ymm ymm +// VXORPS m256 ymm ymm +// Construct and append a VXORPS instruction to the active function. +// Operates on the global context. +func VXORPS(mxy, xy, xy1 operand.Op) { ctx.VXORPS(mxy, xy, xy1) } + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +// Construct and append a VZEROALL instruction to the active function. +func (c *Context) VZEROALL() { + if inst, err := x86.VZEROALL(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +// Construct and append a VZEROALL instruction to the active function. +// Operates on the global context. +func VZEROALL() { ctx.VZEROALL() } + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +// Construct and append a VZEROUPPER instruction to the active function. +func (c *Context) VZEROUPPER() { + if inst, err := x86.VZEROUPPER(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +// Construct and append a VZEROUPPER instruction to the active function. +// Operates on the global context. +func VZEROUPPER() { ctx.VZEROUPPER() } + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +// Construct and append a XADDB instruction to the active function. +func (c *Context) XADDB(r, mr operand.Op) { + if inst, err := x86.XADDB(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +// Construct and append a XADDB instruction to the active function. +// Operates on the global context. +func XADDB(r, mr operand.Op) { ctx.XADDB(r, mr) } + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +// Construct and append a XADDL instruction to the active function. +func (c *Context) XADDL(r, mr operand.Op) { + if inst, err := x86.XADDL(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +// Construct and append a XADDL instruction to the active function. +// Operates on the global context. +func XADDL(r, mr operand.Op) { ctx.XADDL(r, mr) } + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +// Construct and append a XADDQ instruction to the active function. +func (c *Context) XADDQ(r, mr operand.Op) { + if inst, err := x86.XADDQ(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +// Construct and append a XADDQ instruction to the active function. +// Operates on the global context. +func XADDQ(r, mr operand.Op) { ctx.XADDQ(r, mr) } + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +// Construct and append a XADDW instruction to the active function. +func (c *Context) XADDW(r, mr operand.Op) { + if inst, err := x86.XADDW(r, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +// Construct and append a XADDW instruction to the active function. +// Operates on the global context. +func XADDW(r, mr operand.Op) { ctx.XADDW(r, mr) } + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +// Construct and append a XCHGB instruction to the active function. +func (c *Context) XCHGB(mr, mr1 operand.Op) { + if inst, err := x86.XCHGB(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +// Construct and append a XCHGB instruction to the active function. +// Operates on the global context. +func XCHGB(mr, mr1 operand.Op) { ctx.XCHGB(mr, mr1) } + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +// Construct and append a XCHGL instruction to the active function. +func (c *Context) XCHGL(emr, emr1 operand.Op) { + if inst, err := x86.XCHGL(emr, emr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +// Construct and append a XCHGL instruction to the active function. +// Operates on the global context. +func XCHGL(emr, emr1 operand.Op) { ctx.XCHGL(emr, emr1) } + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +// Construct and append a XCHGQ instruction to the active function. +func (c *Context) XCHGQ(mr, mr1 operand.Op) { + if inst, err := x86.XCHGQ(mr, mr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +// Construct and append a XCHGQ instruction to the active function. +// Operates on the global context. +func XCHGQ(mr, mr1 operand.Op) { ctx.XCHGQ(mr, mr1) } + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +// Construct and append a XCHGW instruction to the active function. +func (c *Context) XCHGW(amr, amr1 operand.Op) { + if inst, err := x86.XCHGW(amr, amr1); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +// Construct and append a XCHGW instruction to the active function. +// Operates on the global context. +func XCHGW(amr, amr1 operand.Op) { ctx.XCHGW(amr, amr1) } + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +// Construct and append a XGETBV instruction to the active function. +func (c *Context) XGETBV() { + if inst, err := x86.XGETBV(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +// Construct and append a XGETBV instruction to the active function. +// Operates on the global context. +func XGETBV() { ctx.XGETBV() } + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +// Construct and append a XLAT instruction to the active function. +func (c *Context) XLAT() { + if inst, err := x86.XLAT(); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +// Construct and append a XLAT instruction to the active function. +// Operates on the global context. +func XLAT() { ctx.XLAT() } + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +// Construct and append a XORB instruction to the active function. +func (c *Context) XORB(imr, amr operand.Op) { + if inst, err := x86.XORB(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +// Construct and append a XORB instruction to the active function. +// Operates on the global context. +func XORB(imr, amr operand.Op) { ctx.XORB(imr, amr) } + +// XORL: Logical Exclusive OR. +// +// Forms: +// +// XORL imm32 eax +// XORL imm8 r32 +// XORL imm32 r32 +// XORL r32 r32 +// XORL m32 r32 +// XORL imm8 m32 +// XORL imm32 m32 +// XORL r32 m32 +// Construct and append a XORL instruction to the active function. +func (c *Context) XORL(imr, emr operand.Op) { + if inst, err := x86.XORL(imr, emr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORL: Logical Exclusive OR. +// +// Forms: +// +// XORL imm32 eax +// XORL imm8 r32 +// XORL imm32 r32 +// XORL r32 r32 +// XORL m32 r32 +// XORL imm8 m32 +// XORL imm32 m32 +// XORL r32 m32 +// Construct and append a XORL instruction to the active function. +// Operates on the global context. +func XORL(imr, emr operand.Op) { ctx.XORL(imr, emr) } + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +// Construct and append a XORPD instruction to the active function. +func (c *Context) XORPD(mx, x operand.Op) { + if inst, err := x86.XORPD(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +// Construct and append a XORPD instruction to the active function. +// Operates on the global context. +func XORPD(mx, x operand.Op) { ctx.XORPD(mx, x) } + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +// Construct and append a XORPS instruction to the active function. +func (c *Context) XORPS(mx, x operand.Op) { + if inst, err := x86.XORPS(mx, x); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +// Construct and append a XORPS instruction to the active function. +// Operates on the global context. +func XORPS(mx, x operand.Op) { ctx.XORPS(mx, x) } + +// XORQ: Logical Exclusive OR. +// +// Forms: +// +// XORQ imm32 rax +// XORQ imm8 r64 +// XORQ imm32 r64 +// XORQ r64 r64 +// XORQ m64 r64 +// XORQ imm8 m64 +// XORQ imm32 m64 +// XORQ r64 m64 +// Construct and append a XORQ instruction to the active function. +func (c *Context) XORQ(imr, mr operand.Op) { + if inst, err := x86.XORQ(imr, mr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORQ: Logical Exclusive OR. +// +// Forms: +// +// XORQ imm32 rax +// XORQ imm8 r64 +// XORQ imm32 r64 +// XORQ r64 r64 +// XORQ m64 r64 +// XORQ imm8 m64 +// XORQ imm32 m64 +// XORQ r64 m64 +// Construct and append a XORQ instruction to the active function. +// Operates on the global context. +func XORQ(imr, mr operand.Op) { ctx.XORQ(imr, mr) } + +// XORW: Logical Exclusive OR. +// +// Forms: +// +// XORW imm16 ax +// XORW imm8 r16 +// XORW imm16 r16 +// XORW r16 r16 +// XORW m16 r16 +// XORW imm8 m16 +// XORW imm16 m16 +// XORW r16 m16 +// Construct and append a XORW instruction to the active function. +func (c *Context) XORW(imr, amr operand.Op) { + if inst, err := x86.XORW(imr, amr); err == nil { + c.Instruction(inst) + } else { + c.adderror(err) + } +} + +// XORW: Logical Exclusive OR. +// +// Forms: +// +// XORW imm16 ax +// XORW imm8 r16 +// XORW imm16 r16 +// XORW r16 r16 +// XORW m16 r16 +// XORW imm8 m16 +// XORW imm16 m16 +// XORW r16 m16 +// Construct and append a XORW instruction to the active function. +// Operates on the global context. +func XORW(imr, amr operand.Op) { ctx.XORW(imr, amr) } diff --git a/vendor/github.com/mmcloughlin/avo/build/zmov.go b/vendor/github.com/mmcloughlin/avo/build/zmov.go new file mode 100644 index 00000000..bfd9b081 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/build/zmov.go @@ -0,0 +1,71 @@ +// Code generated by command: avogen -output zmov.go mov. DO NOT EDIT. + +package build + +import ( + "github.com/mmcloughlin/avo/operand" + "go/types" +) + +func (c *Context) mov(a, b operand.Op, an, bn int, t *types.Basic) { + switch { + case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 1: + c.MOVB(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 4: + c.MOVBLSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 4: + c.MOVBLZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 8: + c.MOVBQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 8: + c.MOVBQZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 2: + c.MOVBWSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 2: + c.MOVBWZX(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 4: + c.MOVL(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 4 && bn == 8: + c.MOVLQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 4 && bn == 8: + c.MOVLQZX(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16: + c.MOVOU(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8: + c.MOVQ(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16: + c.MOVQ(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 8 && bn == 16: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 8: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16: + c.MOVSD(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 4 && bn == 16: + c.MOVSS(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 4: + c.MOVSS(a, b) + case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16: + c.MOVSS(a, b) + case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 2: + c.MOVW(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 4: + c.MOVWLSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 4: + c.MOVWLZX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 8: + c.MOVWQSX(a, b) + case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 8: + c.MOVWQZX(a, b) + default: + c.adderrormessage("could not deduce mov instruction") + } +} diff --git a/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go b/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go new file mode 100644 index 00000000..8fd61e10 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/buildtags/buildtags.go @@ -0,0 +1,312 @@ +// Package buildtags provides types for representing and manipulating build constraints. +// +// In Go, build constraints are represented as comments in source code together with file naming conventions. For example +// +// // +build linux,386 darwin,!cgo +// // +build !purego +// +// Any terms provided in the filename can be thought of as an implicit extra +// constraint comment line. Collectively, these are referred to as +// ``constraints''. Each line is a ``constraint''. Within each constraint the +// space-separated terms are ``options'', and within that the comma-separated +// items are ``terms'' which may be negated with at most one exclaimation mark. +// +// These represent a boolean formulae. The constraints are evaluated as the AND +// of constraint lines; a constraint is evaluated as the OR of its options and +// an option is evaluated as the AND of its terms. Overall build constraints are +// a boolean formula that is an AND of ORs of ANDs. +// +// This level of complexity is rarely used in Go programs. Therefore this +// package aims to provide access to all these layers of nesting if required, +// but make it easy to forget about for basic use cases too. +package buildtags + +import ( + "errors" + "fmt" + "strings" + "unicode" +) + +// Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/go/build/doc.go#L73-L92 +// +// // A build constraint is evaluated as the OR of space-separated options; +// // each option evaluates as the AND of its comma-separated terms; +// // and each term is an alphanumeric word or, preceded by !, its negation. +// // That is, the build constraint: +// // +// // // +build linux,386 darwin,!cgo +// // +// // corresponds to the boolean formula: +// // +// // (linux AND 386) OR (darwin AND (NOT cgo)) +// // +// // A file may have multiple build constraints. The overall constraint is the AND +// // of the individual constraints. That is, the build constraints: +// // +// // // +build linux darwin +// // // +build 386 +// // +// // corresponds to the boolean formula: +// // +// // (linux OR darwin) AND 386 +// + +// Interface represents a build constraint. +type Interface interface { + ConstraintsConvertable + fmt.GoStringer + Evaluate(v map[string]bool) bool + Validate() error +} + +// ConstraintsConvertable can be converted to a Constraints object. +type ConstraintsConvertable interface { + ToConstraints() Constraints +} + +// ConstraintConvertable can be converted to a Constraint. +type ConstraintConvertable interface { + ToConstraint() Constraint +} + +// OptionConvertable can be converted to an Option. +type OptionConvertable interface { + ToOption() Option +} + +// Constraints represents the AND of a list of Constraint lines. +type Constraints []Constraint + +// And builds Constraints that will be true if all of its constraints are true. +func And(cs ...ConstraintConvertable) Constraints { + constraints := Constraints{} + for _, c := range cs { + constraints = append(constraints, c.ToConstraint()) + } + return constraints +} + +// ToConstraints returns cs. +func (cs Constraints) ToConstraints() Constraints { return cs } + +// Validate validates the constraints set. +func (cs Constraints) Validate() error { + for _, c := range cs { + if err := c.Validate(); err != nil { + return err + } + } + return nil +} + +// Evaluate the boolean formula represented by cs under the given assignment of +// tag values. This is the AND of the values of the constituent Constraints. +func (cs Constraints) Evaluate(v map[string]bool) bool { + r := true + for _, c := range cs { + r = r && c.Evaluate(v) + } + return r +} + +// GoString represents Constraints as +build comment lines. +func (cs Constraints) GoString() string { + s := "" + for _, c := range cs { + s += c.GoString() + } + return s +} + +// Constraint represents the OR of a list of Options. +type Constraint []Option + +// Any builds a Constraint that will be true if any of its options are true. +func Any(opts ...OptionConvertable) Constraint { + c := Constraint{} + for _, opt := range opts { + c = append(c, opt.ToOption()) + } + return c +} + +// ParseConstraint parses a space-separated list of options. +func ParseConstraint(expr string) (Constraint, error) { + c := Constraint{} + for _, field := range strings.Fields(expr) { + opt, err := ParseOption(field) + if err != nil { + return c, err + } + c = append(c, opt) + } + return c, nil +} + +// ToConstraints returns the list of constraints containing just c. +func (c Constraint) ToConstraints() Constraints { return Constraints{c} } + +// ToConstraint returns c. +func (c Constraint) ToConstraint() Constraint { return c } + +// Validate validates the constraint. +func (c Constraint) Validate() error { + for _, o := range c { + if err := o.Validate(); err != nil { + return err + } + } + return nil +} + +// Evaluate the boolean formula represented by c under the given assignment of +// tag values. This is the OR of the values of the constituent Options. +func (c Constraint) Evaluate(v map[string]bool) bool { + r := false + for _, o := range c { + r = r || o.Evaluate(v) + } + return r +} + +// GoString represents the Constraint as one +build comment line. +func (c Constraint) GoString() string { + s := "// +build" + for _, o := range c { + s += " " + o.GoString() + } + return s + "\n" +} + +// Option represents the AND of a list of Terms. +type Option []Term + +// Opt builds an Option from the list of Terms. +func Opt(terms ...Term) Option { + return Option(terms) +} + +// ParseOption parses a comma-separated list of terms. +func ParseOption(expr string) (Option, error) { + opt := Option{} + for _, t := range strings.Split(expr, ",") { + opt = append(opt, Term(t)) + } + return opt, opt.Validate() +} + +// ToConstraints returns Constraints containing just this option. +func (o Option) ToConstraints() Constraints { return o.ToConstraint().ToConstraints() } + +// ToConstraint returns a Constraint containing just this option. +func (o Option) ToConstraint() Constraint { return Constraint{o} } + +// ToOption returns o. +func (o Option) ToOption() Option { return o } + +// Validate validates o. +func (o Option) Validate() error { + for _, t := range o { + if err := t.Validate(); err != nil { + return fmt.Errorf("invalid term \"%s\": %s", t, err) + } + } + return nil +} + +// Evaluate the boolean formula represented by o under the given assignment of +// tag values. This is the AND of the values of the constituent Terms. +func (o Option) Evaluate(v map[string]bool) bool { + r := true + for _, t := range o { + r = r && t.Evaluate(v) + } + return r +} + +// GoString represents the Option as a comma-separated list of terms. +func (o Option) GoString() string { + var ts []string + for _, t := range o { + ts = append(ts, t.GoString()) + } + return strings.Join(ts, ",") +} + +// Term is an atomic term in a build constraint: an identifier or its negation. +type Term string + +// Not returns a term for the negation of ident. +func Not(ident string) Term { + return Term("!" + ident) +} + +// ToConstraints returns Constraints containing just this term. +func (t Term) ToConstraints() Constraints { return t.ToOption().ToConstraints() } + +// ToConstraint returns a Constraint containing just this term. +func (t Term) ToConstraint() Constraint { return t.ToOption().ToConstraint() } + +// ToOption returns an Option containing just this term. +func (t Term) ToOption() Option { return Option{t} } + +// IsNegated reports whether t is the negation of an identifier. +func (t Term) IsNegated() bool { return strings.HasPrefix(string(t), "!") } + +// Name returns the identifier for this term. +func (t Term) Name() string { + return strings.TrimPrefix(string(t), "!") +} + +// Validate the term. +func (t Term) Validate() error { + // Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/cmd/go/internal/imports/build.go#L110-L112 + // + // if strings.HasPrefix(name, "!!") { // bad syntax, reject always + // return false + // } + // + if strings.HasPrefix(string(t), "!!") { + return errors.New("at most one '!' allowed") + } + + if len(t.Name()) == 0 { + return errors.New("empty tag name") + } + + // Reference: https://github.com/golang/go/blob/204a8f55dc2e0ac8d27a781dab0da609b98560da/src/cmd/go/internal/imports/build.go#L121-L127 + // + // // Tags must be letters, digits, underscores or dots. + // // Unlike in Go identifiers, all digits are fine (e.g., "386"). + // for _, c := range name { + // if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { + // return false + // } + // } + // + for _, c := range t.Name() { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' { + return fmt.Errorf("character '%c' disallowed in tags", c) + } + } + + return nil +} + +// Evaluate the term under the given set of identifier values. +func (t Term) Evaluate(v map[string]bool) bool { + return (t.Validate() == nil) && (v[t.Name()] == !t.IsNegated()) +} + +// GoString returns t. +func (t Term) GoString() string { return string(t) } + +// SetTags builds a set where the given list of identifiers are true. +func SetTags(idents ...string) map[string]bool { + v := map[string]bool{} + for _, ident := range idents { + v[ident] = true + } + return v +} diff --git a/vendor/github.com/mmcloughlin/avo/examples/stadtx/LICENSE b/vendor/github.com/mmcloughlin/avo/examples/stadtx/LICENSE new file mode 100644 index 00000000..bd92ca27 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/examples/stadtx/LICENSE @@ -0,0 +1,167 @@ +// Code generated by downloading from https://raw.githubusercontent.com/demerphq/BeagleHash/5f8620b953230e5b16171b745155fc3b0ef8f75e/LICENSE. DO NOT EDIT. + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/components.go b/vendor/github.com/mmcloughlin/avo/gotypes/components.go new file mode 100644 index 00000000..2206afa6 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/components.go @@ -0,0 +1,253 @@ +package gotypes + +import ( + "errors" + "fmt" + "go/token" + "go/types" + "strconv" + + "github.com/mmcloughlin/avo/reg" + + "github.com/mmcloughlin/avo/operand" +) + +// Sizes provides type sizes used by the standard Go compiler on amd64. +var Sizes = types.SizesFor("gc", "amd64") + +// Basic represents a primitive/basic type at a given memory address. +type Basic struct { + Addr operand.Mem + Type *types.Basic +} + +// Component provides access to sub-components of a Go type. +type Component interface { + // When the component has no further sub-components, Resolve will return a + // reference to the components type and memory address. If there was an error + // during any previous calls to Component methods, they will be returned at + // resolution time. + Resolve() (*Basic, error) + + Dereference(r reg.Register) Component // dereference a pointer + Base() Component // base pointer of a string or slice + Len() Component // length of a string or slice + Cap() Component // capacity of a slice + Real() Component // real part of a complex value + Imag() Component // imaginary part of a complex value + Index(int) Component // index into an array + Field(string) Component // access a struct field +} + +// componenterr is an error that also provides a null implementation of the +// Component interface. This enables us to return an error from Component +// methods whilst also allowing method chaining to continue. +type componenterr string + +func errorf(format string, args ...interface{}) Component { + return componenterr(fmt.Sprintf(format, args...)) +} + +func (c componenterr) Error() string { return string(c) } +func (c componenterr) Resolve() (*Basic, error) { return nil, c } +func (c componenterr) Dereference(r reg.Register) Component { return c } +func (c componenterr) Base() Component { return c } +func (c componenterr) Len() Component { return c } +func (c componenterr) Cap() Component { return c } +func (c componenterr) Real() Component { return c } +func (c componenterr) Imag() Component { return c } +func (c componenterr) Index(int) Component { return c } +func (c componenterr) Field(string) Component { return c } + +type component struct { + typ types.Type + addr operand.Mem +} + +// NewComponent builds a component for the named type at the given address. +func NewComponent(t types.Type, addr operand.Mem) Component { + return &component{ + typ: t, + addr: addr, + } +} + +func (c *component) Resolve() (*Basic, error) { + b := toprimitive(c.typ) + if b == nil { + return nil, errors.New("component is not primitive") + } + return &Basic{ + Addr: c.addr, + Type: b, + }, nil +} + +func (c *component) Dereference(r reg.Register) Component { + p, ok := c.typ.Underlying().(*types.Pointer) + if !ok { + return errorf("not pointer type") + } + return NewComponent(p.Elem(), operand.Mem{Base: r}) +} + +// Reference: https://github.com/golang/go/blob/50bd1c4d4eb4fac8ddeb5f063c099daccfb71b26/src/reflect/value.go#L1800-L1804 +// +// type SliceHeader struct { +// Data uintptr +// Len int +// Cap int +// } +// +var slicehdroffsets = Sizes.Offsetsof([]*types.Var{ + types.NewField(token.NoPos, nil, "Data", types.Typ[types.Uintptr], false), + types.NewField(token.NoPos, nil, "Len", types.Typ[types.Int], false), + types.NewField(token.NoPos, nil, "Cap", types.Typ[types.Int], false), +}) + +func (c *component) Base() Component { + if !isslice(c.typ) && !isstring(c.typ) { + return errorf("only slices and strings have base pointers") + } + return c.sub("_base", int(slicehdroffsets[0]), types.Typ[types.Uintptr]) +} + +func (c *component) Len() Component { + if !isslice(c.typ) && !isstring(c.typ) { + return errorf("only slices and strings have length fields") + } + return c.sub("_len", int(slicehdroffsets[1]), types.Typ[types.Int]) +} + +func (c *component) Cap() Component { + if !isslice(c.typ) { + return errorf("only slices have capacity fields") + } + return c.sub("_cap", int(slicehdroffsets[2]), types.Typ[types.Int]) +} + +func (c *component) Real() Component { + if !iscomplex(c.typ) { + return errorf("only complex types have real values") + } + f := complextofloat(c.typ) + return c.sub("_real", 0, f) +} + +func (c *component) Imag() Component { + if !iscomplex(c.typ) { + return errorf("only complex types have imaginary values") + } + f := complextofloat(c.typ) + return c.sub("_imag", int(Sizes.Sizeof(f)), f) +} + +func (c *component) Index(i int) Component { + a, ok := c.typ.Underlying().(*types.Array) + if !ok { + return errorf("not array type") + } + if int64(i) >= a.Len() { + return errorf("array index out of bounds") + } + // Reference: https://github.com/golang/tools/blob/bcd4e47d02889ebbc25c9f4bf3d27e4124b0bf9d/go/analysis/passes/asmdecl/asmdecl.go#L482-L494 + // + // case asmArray: + // tu := t.Underlying().(*types.Array) + // elem := tu.Elem() + // // Calculate offset of each element array. + // fields := []*types.Var{ + // types.NewVar(token.NoPos, nil, "fake0", elem), + // types.NewVar(token.NoPos, nil, "fake1", elem), + // } + // offsets := arch.sizes.Offsetsof(fields) + // elemoff := int(offsets[1]) + // for i := 0; i < int(tu.Len()); i++ { + // cc = appendComponentsRecursive(arch, elem, cc, suffix+"_"+strconv.Itoa(i), i*elemoff) + // } + // + elem := a.Elem() + elemsize := int(Sizes.Sizeof(types.NewArray(elem, 2)) - Sizes.Sizeof(types.NewArray(elem, 1))) + return c.sub("_"+strconv.Itoa(i), i*elemsize, elem) +} + +func (c *component) Field(n string) Component { + s, ok := c.typ.Underlying().(*types.Struct) + if !ok { + return errorf("not struct type") + } + // Reference: https://github.com/golang/tools/blob/13ba8ad772dfbf0f451b5dd0679e9c5605afc05d/go/analysis/passes/asmdecl/asmdecl.go#L471-L480 + // + // case asmStruct: + // tu := t.Underlying().(*types.Struct) + // fields := make([]*types.Var, tu.NumFields()) + // for i := 0; i < tu.NumFields(); i++ { + // fields[i] = tu.Field(i) + // } + // offsets := arch.sizes.Offsetsof(fields) + // for i, f := range fields { + // cc = appendComponentsRecursive(arch, f.Type(), cc, suffix+"_"+f.Name(), off+int(offsets[i])) + // } + // + fields := make([]*types.Var, s.NumFields()) + for i := 0; i < s.NumFields(); i++ { + fields[i] = s.Field(i) + } + offsets := Sizes.Offsetsof(fields) + for i, f := range fields { + if f.Name() == n { + return c.sub("_"+n, int(offsets[i]), f.Type()) + } + } + return errorf("struct does not have field '%s'", n) +} + +func (c *component) sub(suffix string, offset int, t types.Type) *component { + s := *c + if s.addr.Symbol.Name != "" { + s.addr.Symbol.Name += suffix + } + s.addr = s.addr.Offset(offset) + s.typ = t + return &s +} + +func isslice(t types.Type) bool { + _, ok := t.Underlying().(*types.Slice) + return ok +} + +func isstring(t types.Type) bool { + b, ok := t.Underlying().(*types.Basic) + return ok && b.Kind() == types.String +} + +func iscomplex(t types.Type) bool { + b, ok := t.Underlying().(*types.Basic) + return ok && (b.Info()&types.IsComplex) != 0 +} + +func complextofloat(t types.Type) types.Type { + switch Sizes.Sizeof(t) { + case 16: + return types.Typ[types.Float64] + case 8: + return types.Typ[types.Float32] + } + panic("bad") +} + +// toprimitive determines whether t is primitive (cannot be reduced into +// components). If it is, it returns the basic type for t, otherwise returns +// nil. +func toprimitive(t types.Type) *types.Basic { + switch b := t.(type) { + case *types.Basic: + if (b.Info() & (types.IsString | types.IsComplex)) == 0 { + return b + } + case *types.Pointer: + return types.Typ[types.Uintptr] + } + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/doc.go b/vendor/github.com/mmcloughlin/avo/gotypes/doc.go new file mode 100644 index 00000000..fa8f0783 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/doc.go @@ -0,0 +1,2 @@ +// Package gotypes provides helpers for interacting with Go types within avo functions. +package gotypes diff --git a/vendor/github.com/mmcloughlin/avo/gotypes/signature.go b/vendor/github.com/mmcloughlin/avo/gotypes/signature.go new file mode 100644 index 00000000..e0000203 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/gotypes/signature.go @@ -0,0 +1,177 @@ +package gotypes + +import ( + "bytes" + "errors" + "fmt" + "go/token" + "go/types" + "strconv" + + "github.com/mmcloughlin/avo/operand" +) + +// Signature represents a Go function signature. +type Signature struct { + pkg *types.Package + sig *types.Signature + params *Tuple + results *Tuple +} + +// NewSignature constructs a Signature. +func NewSignature(pkg *types.Package, sig *types.Signature) *Signature { + s := &Signature{ + pkg: pkg, + sig: sig, + } + s.init() + return s +} + +// NewSignatureVoid builds the void signature "func()". +func NewSignatureVoid() *Signature { + return NewSignature(nil, types.NewSignature(nil, nil, nil, false)) +} + +// LookupSignature returns the signature of the named function in the provided package. +func LookupSignature(pkg *types.Package, name string) (*Signature, error) { + scope := pkg.Scope() + obj := scope.Lookup(name) + if obj == nil { + return nil, fmt.Errorf("could not find function \"%s\"", name) + } + s, ok := obj.Type().(*types.Signature) + if !ok { + return nil, fmt.Errorf("object \"%s\" does not have signature type", name) + } + return NewSignature(pkg, s), nil +} + +// ParseSignature builds a Signature by parsing a Go function type expression. +// The function type must reference builtin types only; see +// ParseSignatureInPackage if custom types are required. +func ParseSignature(expr string) (*Signature, error) { + return ParseSignatureInPackage(nil, expr) +} + +// ParseSignatureInPackage builds a Signature by parsing a Go function type +// expression. The expression may reference types in the provided package. +func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error) { + tv, err := types.Eval(token.NewFileSet(), pkg, token.NoPos, expr) + if err != nil { + return nil, err + } + if tv.Value != nil { + return nil, errors.New("signature expression should have nil value") + } + s, ok := tv.Type.(*types.Signature) + if !ok { + return nil, errors.New("provided type is not a function signature") + } + return NewSignature(pkg, s), nil +} + +// Params returns the function signature argument types. +func (s *Signature) Params() *Tuple { return s.params } + +// Results returns the function return types. +func (s *Signature) Results() *Tuple { return s.results } + +// Bytes returns the total size of the function arguments and return values. +func (s *Signature) Bytes() int { return s.Params().Bytes() + s.Results().Bytes() } + +// String writes Signature as a string. This does not include the "func" keyword. +func (s *Signature) String() string { + var buf bytes.Buffer + types.WriteSignature(&buf, s.sig, func(pkg *types.Package) string { + if pkg == s.pkg { + return "" + } + return pkg.Name() + }) + return buf.String() +} + +func (s *Signature) init() { + p := s.sig.Params() + r := s.sig.Results() + + // Compute parameter offsets. + vs := tuplevars(p) + vs = append(vs, types.NewParam(token.NoPos, nil, "sentinel", types.Typ[types.Uint64])) + paramsoffsets := Sizes.Offsetsof(vs) + paramssize := paramsoffsets[p.Len()] + s.params = newTuple(p, paramsoffsets, paramssize, "arg") + + // Result offsets. + vs = tuplevars(r) + resultsoffsets := Sizes.Offsetsof(vs) + var resultssize int64 + if n := len(vs); n > 0 { + resultssize = resultsoffsets[n-1] + Sizes.Sizeof(vs[n-1].Type()) + } + for i := range resultsoffsets { + resultsoffsets[i] += paramssize + } + s.results = newTuple(r, resultsoffsets, resultssize, "ret") +} + +// Tuple represents a tuple of variables, such as function arguments or results. +type Tuple struct { + components []Component + byname map[string]Component + size int +} + +func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string) *Tuple { + tuple := &Tuple{ + byname: map[string]Component{}, + size: int(size), + } + for i := 0; i < t.Len(); i++ { + v := t.At(i) + name := v.Name() + if name == "" { + name = defaultprefix + if i > 0 { + name += strconv.Itoa(i) + } + } + addr := operand.NewParamAddr(name, int(offsets[i])) + c := NewComponent(v.Type(), addr) + tuple.components = append(tuple.components, c) + if v.Name() != "" { + tuple.byname[v.Name()] = c + } + } + return tuple +} + +// Lookup returns the variable with the given name. +func (t *Tuple) Lookup(name string) Component { + e := t.byname[name] + if e == nil { + return errorf("unknown variable \"%s\"", name) + } + return e +} + +// At returns the variable at index i. +func (t *Tuple) At(i int) Component { + if i >= len(t.components) { + return errorf("index out of range") + } + return t.components[i] +} + +// Bytes returns the size of the Tuple. This may include additional padding. +func (t *Tuple) Bytes() int { return t.size } + +func tuplevars(t *types.Tuple) []*types.Var { + vs := make([]*types.Var, t.Len()) + for i := 0; i < t.Len(); i++ { + vs[i] = t.At(i) + } + return vs +} diff --git a/vendor/github.com/mmcloughlin/avo/internal/data/LICENSE b/vendor/github.com/mmcloughlin/avo/internal/data/LICENSE new file mode 100644 index 00000000..baf24bb5 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/data/LICENSE @@ -0,0 +1,52 @@ +----------------------------------------------------------------------------- +golang/arch license +----------------------------------------------------------------------------- + +Copyright (c) 2015 The Go Authors. All rights reserved. + +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. + +----------------------------------------------------------------------------- +Maratyszcza/Opcodes license +----------------------------------------------------------------------------- + +======================================= +Opcodes Database license (2-clause BSD) +======================================= + +Copyright (c) 2017 Facebook Inc. +Copyright (c) 2014-2017, Georgia Institute of Technology +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. 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. + +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 HOLDER 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. + diff --git a/vendor/github.com/mmcloughlin/avo/internal/load/testdata b/vendor/github.com/mmcloughlin/avo/internal/load/testdata new file mode 120000 index 00000000..4909e06e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/load/testdata @@ -0,0 +1 @@ +../data \ No newline at end of file diff --git a/vendor/github.com/mmcloughlin/avo/internal/opcodescsv/testdata b/vendor/github.com/mmcloughlin/avo/internal/opcodescsv/testdata new file mode 120000 index 00000000..4909e06e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/opcodescsv/testdata @@ -0,0 +1 @@ +../data \ No newline at end of file diff --git a/vendor/github.com/mmcloughlin/avo/internal/opcodesxml/testdata/x86_64.xml b/vendor/github.com/mmcloughlin/avo/internal/opcodesxml/testdata/x86_64.xml new file mode 120000 index 00000000..eb6040a0 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/opcodesxml/testdata/x86_64.xml @@ -0,0 +1 @@ +../../data/x86_64.xml \ No newline at end of file diff --git a/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go b/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go new file mode 100644 index 00000000..2239946f --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/prnt/printer.go @@ -0,0 +1,58 @@ +// Package prnt provides common functionality for code generators. +package prnt + +import ( + "bytes" + "fmt" + "io" +) + +// Generator provides convenience methods for code generators. In particular it +// provides fmt-like methods which print to an internal buffer. It also allows +// any errors to be stored so they can be checked at the end, rather than having +// error checks obscuring the code generation. +type Generator struct { + buf bytes.Buffer + err error +} + +// Raw provides direct access to the underlying output stream. +func (g *Generator) Raw() io.Writer { + return &g.buf +} + +// Printf prints to the internal buffer. +func (g *Generator) Printf(format string, args ...interface{}) { + if g.err != nil { + return + } + _, err := fmt.Fprintf(&g.buf, format, args...) + g.AddError(err) +} + +// NL prints a new line. +func (g *Generator) NL() { + g.Printf("\n") +} + +// Comment writes comment lines prefixed with "// ". +func (g *Generator) Comment(lines ...string) { + for _, line := range lines { + g.Printf("// %s\n", line) + } +} + +// AddError records an error in code generation. The first non-nil error will +// prevent printing operations from writing anything else, and the error will be +// returned from Result(). +func (g *Generator) AddError(err error) { + if err != nil && g.err == nil { + g.err = err + } +} + +// Result returns the printed bytes. If any error was recorded with AddError +// during code generation, the first such error will be returned here. +func (g *Generator) Result() ([]byte, error) { + return g.buf.Bytes(), g.err +} diff --git a/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go b/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go new file mode 100644 index 00000000..1d327d9d --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/internal/stack/stack.go @@ -0,0 +1,73 @@ +// Package stack provides helpers for querying the callstack. +package stack + +import ( + "path" + "runtime" + "strings" +) + +// Frames returns at most max callstack Frames, starting with its caller and +// skipping skip Frames. +func Frames(skip, max int) []runtime.Frame { + pc := make([]uintptr, max) + n := runtime.Callers(skip+2, pc) + if n == 0 { + return nil + } + pc = pc[:n] + frames := runtime.CallersFrames(pc) + var fs []runtime.Frame + for { + f, more := frames.Next() + fs = append(fs, f) + if !more { + break + } + } + return fs +} + +// Match returns the first stack frame for which the predicate function returns +// true. Returns nil if no match is found. Starts matching after skip frames, +// starting with its caller. +func Match(skip int, predicate func(runtime.Frame) bool) *runtime.Frame { + i, n := skip+1, 16 + for { + fs := Frames(i, n) + for j, f := range fs { + if predicate(f) { + return &fs[j] + } + } + if len(fs) < n { + break + } + i += n + } + return nil +} + +// Main returns the main() function Frame. +func Main() *runtime.Frame { + return Match(1, func(f runtime.Frame) bool { + return f.Function == "main.main" + }) +} + +// ExternalCaller returns the first frame outside the callers package. +func ExternalCaller() *runtime.Frame { + var first *runtime.Frame + return Match(1, func(f runtime.Frame) bool { + if first == nil { + first = &f + } + return pkg(first.Function) != pkg(f.Function) + }) +} + +func pkg(ident string) string { + dir, name := path.Split(ident) + parts := strings.Split(name, ".") + return dir + parts[0] +} diff --git a/vendor/github.com/mmcloughlin/avo/ir/doc.go b/vendor/github.com/mmcloughlin/avo/ir/doc.go new file mode 100644 index 00000000..de02f464 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/ir/doc.go @@ -0,0 +1,2 @@ +// Package ir provides the intermediate representation of avo programs. +package ir diff --git a/vendor/github.com/mmcloughlin/avo/ir/ir.go b/vendor/github.com/mmcloughlin/avo/ir/ir.go new file mode 100644 index 00000000..8cf8e8e4 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/ir/ir.go @@ -0,0 +1,325 @@ +package ir + +import ( + "errors" + + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/buildtags" + "github.com/mmcloughlin/avo/gotypes" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// Node is a part of a Function. +type Node interface { + node() +} + +// Label within a function. +type Label string + +func (l Label) node() {} + +// Comment represents a multi-line comment. +type Comment struct { + Lines []string +} + +func (c *Comment) node() {} + +// NewComment builds a Comment consisting of the provided lines. +func NewComment(lines ...string) *Comment { + return &Comment{ + Lines: lines, + } +} + +// Instruction is a single instruction in a function. +type Instruction struct { + Opcode string + Operands []operand.Op + + Inputs []operand.Op + Outputs []operand.Op + + IsTerminal bool + IsBranch bool + IsConditional bool + + // CFG. + Pred []*Instruction + Succ []*Instruction + + // LiveIn/LiveOut are sets of live register IDs pre/post execution. + LiveIn reg.Set + LiveOut reg.Set +} + +func (i *Instruction) node() {} + +// TargetLabel returns the label referenced by this instruction. Returns nil if +// no label is referenced. +func (i Instruction) TargetLabel() *Label { + if !i.IsBranch { + return nil + } + if len(i.Operands) == 0 { + return nil + } + if ref, ok := i.Operands[0].(operand.LabelRef); ok { + lbl := Label(ref) + return &lbl + } + return nil +} + +// Registers returns all registers involved in the instruction. +func (i Instruction) Registers() []reg.Register { + var rs []reg.Register + for _, op := range i.Operands { + rs = append(rs, operand.Registers(op)...) + } + return rs +} + +// InputRegisters returns all registers read by this instruction. +func (i Instruction) InputRegisters() []reg.Register { + var rs []reg.Register + for _, op := range i.Inputs { + rs = append(rs, operand.Registers(op)...) + } + for _, op := range i.Outputs { + if operand.IsMem(op) { + rs = append(rs, operand.Registers(op)...) + } + } + return rs +} + +// OutputRegisters returns all registers written by this instruction. +func (i Instruction) OutputRegisters() []reg.Register { + var rs []reg.Register + for _, op := range i.Outputs { + if r, ok := op.(reg.Register); ok { + rs = append(rs, r) + } + } + return rs +} + +// Section is a part of a file. +type Section interface { + section() +} + +// File represents an assembly file. +type File struct { + Constraints buildtags.Constraints + Includes []string + Sections []Section +} + +// NewFile initializes an empty file. +func NewFile() *File { + return &File{} +} + +// AddSection appends a Section to the file. +func (f *File) AddSection(s Section) { + f.Sections = append(f.Sections, s) +} + +// Functions returns all functions in the file. +func (f *File) Functions() []*Function { + var fns []*Function + for _, s := range f.Sections { + if fn, ok := s.(*Function); ok { + fns = append(fns, fn) + } + } + return fns +} + +// Function represents an assembly function. +type Function struct { + Name string + Attributes attr.Attribute + Doc []string + Signature *gotypes.Signature + LocalSize int + + Nodes []Node + + // LabelTarget maps from label name to the following instruction. + LabelTarget map[Label]*Instruction + + // Register allocation. + Allocation reg.Allocation +} + +func (f *Function) section() {} + +// NewFunction builds an empty function of the given name. +func NewFunction(name string) *Function { + return &Function{ + Name: name, + Signature: gotypes.NewSignatureVoid(), + } +} + +// SetSignature sets the function signature. +func (f *Function) SetSignature(s *gotypes.Signature) { + f.Signature = s +} + +// AllocLocal allocates size bytes in this function's stack. +// Returns a reference to the base pointer for the newly allocated region. +func (f *Function) AllocLocal(size int) operand.Mem { + ptr := operand.NewStackAddr(f.LocalSize) + f.LocalSize += size + return ptr +} + +// AddInstruction appends an instruction to f. +func (f *Function) AddInstruction(i *Instruction) { + f.AddNode(i) +} + +// AddLabel appends a label to f. +func (f *Function) AddLabel(l Label) { + f.AddNode(l) +} + +// AddComment adds comment lines to f. +func (f *Function) AddComment(lines ...string) { + f.AddNode(NewComment(lines...)) +} + +// AddNode appends a Node to f. +func (f *Function) AddNode(n Node) { + f.Nodes = append(f.Nodes, n) +} + +// Instructions returns just the list of instruction nodes. +func (f *Function) Instructions() []*Instruction { + var is []*Instruction + for _, n := range f.Nodes { + i, ok := n.(*Instruction) + if ok { + is = append(is, i) + } + } + return is +} + +// Labels returns just the list of label nodes. +func (f *Function) Labels() []Label { + var lbls []Label + for _, n := range f.Nodes { + lbl, ok := n.(Label) + if ok { + lbls = append(lbls, lbl) + } + } + return lbls +} + +// Stub returns the Go function declaration. +func (f *Function) Stub() string { + return "func " + f.Name + f.Signature.String() +} + +// FrameBytes returns the size of the stack frame in bytes. +func (f *Function) FrameBytes() int { + return f.LocalSize +} + +// ArgumentBytes returns the size of the arguments in bytes. +func (f *Function) ArgumentBytes() int { + return f.Signature.Bytes() +} + +// Datum represents a data element at a particular offset of a data section. +type Datum struct { + Offset int + Value operand.Constant +} + +// NewDatum builds a Datum from the given constant. +func NewDatum(offset int, v operand.Constant) Datum { + return Datum{ + Offset: offset, + Value: v, + } +} + +// Interval returns the range of bytes this datum will occupy within its section. +func (d Datum) Interval() (int, int) { + return d.Offset, d.Offset + d.Value.Bytes() +} + +// Overlaps returns true +func (d Datum) Overlaps(other Datum) bool { + s, e := d.Interval() + so, eo := other.Interval() + return !(eo <= s || e <= so) +} + +// Global represents a DATA section. +type Global struct { + Symbol operand.Symbol + Attributes attr.Attribute + Data []Datum + Size int +} + +// NewGlobal constructs an empty DATA section. +func NewGlobal(sym operand.Symbol) *Global { + return &Global{ + Symbol: sym, + } +} + +// NewStaticGlobal is a convenience for building a static DATA section. +func NewStaticGlobal(name string) *Global { + return NewGlobal(operand.NewStaticSymbol(name)) +} + +func (g *Global) section() {} + +// Base returns a pointer to the start of the data section. +func (g *Global) Base() operand.Mem { + return operand.NewDataAddr(g.Symbol, 0) +} + +// Grow ensures that the data section has at least the given size. +func (g *Global) Grow(size int) { + if g.Size < size { + g.Size = size + } +} + +// AddDatum adds d to this data section, growing it if necessary. Errors if the datum overlaps with existing data. +func (g *Global) AddDatum(d Datum) error { + for _, other := range g.Data { + if d.Overlaps(other) { + return errors.New("overlaps existing datum") + } + } + g.add(d) + return nil +} + +// Append the constant to the end of the data section. +func (g *Global) Append(v operand.Constant) { + g.add(Datum{ + Offset: g.Size, + Value: v, + }) +} + +func (g *Global) add(d Datum) { + _, end := d.Interval() + g.Grow(end) + g.Data = append(g.Data, d) +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/checks.go b/vendor/github.com/mmcloughlin/avo/operand/checks.go new file mode 100644 index 00000000..2585479d --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/checks.go @@ -0,0 +1,247 @@ +package operand + +import "github.com/mmcloughlin/avo/reg" + +// Pure type assertion checks: + +// IsRegister returns whether op has type reg.Register. +func IsRegister(op Op) bool { _, ok := op.(reg.Register); return ok } + +// IsMem returns whether op has type Mem. +func IsMem(op Op) bool { _, ok := op.(Mem); return ok } + +// IsRel returns whether op has type Rel. +func IsRel(op Op) bool { _, ok := op.(Rel); return ok } + +// Checks corresponding to specific operand types in the Intel Manual: + +// Is1 returns true if op is the immediate constant 1. +func Is1(op Op) bool { + i, ok := op.(U8) + return ok && i == 1 +} + +// Is3 returns true if op is the immediate constant 3. +func Is3(op Op) bool { + i, ok := op.(U8) + return ok && i == 3 +} + +// IsIMM2U returns true if op is a 2-bit unsigned immediate (less than 4). +func IsIMM2U(op Op) bool { + i, ok := op.(U8) + return ok && i < 4 +} + +// IsIMM8 returns true is op is an 8-bit immediate. +func IsIMM8(op Op) bool { + _, ok := op.(U8) + return ok +} + +// IsIMM16 returns true is op is a 16-bit immediate. +func IsIMM16(op Op) bool { + _, ok := op.(U16) + return ok +} + +// IsIMM32 returns true is op is a 32-bit immediate. +func IsIMM32(op Op) bool { + _, ok := op.(U32) + return ok +} + +// IsIMM64 returns true is op is a 64-bit immediate. +func IsIMM64(op Op) bool { + _, ok := op.(U64) + return ok +} + +// IsAL returns true if op is the AL register. +func IsAL(op Op) bool { + return op == reg.AL +} + +// IsCL returns true if op is the CL register. +func IsCL(op Op) bool { + return op == reg.CL +} + +// IsAX returns true if op is the 16-bit AX register. +func IsAX(op Op) bool { + return op == reg.AX +} + +// IsEAX returns true if op is the 32-bit EAX register. +func IsEAX(op Op) bool { + return op == reg.EAX +} + +// IsRAX returns true if op is the 64-bit RAX register. +func IsRAX(op Op) bool { + return op == reg.RAX +} + +// IsR8 returns true if op is an 8-bit general-purpose register. +func IsR8(op Op) bool { + return IsGP(op, 1) +} + +// IsR16 returns true if op is a 16-bit general-purpose register. +func IsR16(op Op) bool { + return IsGP(op, 2) +} + +// IsR32 returns true if op is a 32-bit general-purpose register. +func IsR32(op Op) bool { + return IsGP(op, 4) +} + +// IsR64 returns true if op is a 64-bit general-purpose register. +func IsR64(op Op) bool { + return IsGP(op, 8) +} + +// IsPseudo returns true if op is a pseudo register. +func IsPseudo(op Op) bool { + return IsRegisterKind(op, reg.KindPseudo) +} + +// IsGP returns true if op is a general-purpose register of size n bytes. +func IsGP(op Op, n uint) bool { + return IsRegisterKindSize(op, reg.KindGP, n) +} + +// IsXMM0 returns true if op is the X0 register. +func IsXMM0(op Op) bool { + return op == reg.X0 +} + +// IsXMM returns true if op is a 128-bit XMM register. +func IsXMM(op Op) bool { + return IsRegisterKindSize(op, reg.KindVector, 16) +} + +// IsYMM returns true if op is a 256-bit YMM register. +func IsYMM(op Op) bool { + return IsRegisterKindSize(op, reg.KindVector, 32) +} + +// IsRegisterKindSize returns true if op is a register of the given kind and size in bytes. +func IsRegisterKindSize(op Op, k reg.Kind, n uint) bool { + r, ok := op.(reg.Register) + return ok && r.Kind() == k && r.Size() == n +} + +// IsRegisterKind returns true if op is a register of the given kind. +func IsRegisterKind(op Op, k reg.Kind) bool { + r, ok := op.(reg.Register) + return ok && r.Kind() == k +} + +// IsM returns true if op is a 16-, 32- or 64-bit memory operand. +func IsM(op Op) bool { + // TODO(mbm): confirm "m" check is defined correctly + // Intel manual: "A 16-, 32- or 64-bit operand in memory." + return IsM16(op) || IsM32(op) || IsM64(op) +} + +// IsM8 returns true if op is an 8-bit memory operand. +func IsM8(op Op) bool { + // TODO(mbm): confirm "m8" check is defined correctly + // Intel manual: "A byte operand in memory, usually expressed as a variable or + // array name, but pointed to by the DS:(E)SI or ES:(E)DI registers. In 64-bit + // mode, it is pointed to by the RSI or RDI registers." + return IsMSize(op, 1) +} + +// IsM16 returns true if op is a 16-bit memory operand. +func IsM16(op Op) bool { + return IsMSize(op, 2) +} + +// IsM32 returns true if op is a 16-bit memory operand. +func IsM32(op Op) bool { + return IsMSize(op, 4) +} + +// IsM64 returns true if op is a 64-bit memory operand. +func IsM64(op Op) bool { + return IsMSize(op, 8) +} + +// IsMSize returns true if op is a memory operand using general-purpose address +// registers of the given size in bytes. +func IsMSize(op Op, n uint) bool { + // TODO(mbm): should memory operands have a size attribute as well? + // TODO(mbm): m8,m16,m32,m64 checks do not actually check size + m, ok := op.(Mem) + return ok && IsMReg(m.Base) && (m.Index == nil || IsMReg(m.Index)) +} + +// IsMReg returns true if op is a register that can be used in a memory operand. +func IsMReg(op Op) bool { + return IsPseudo(op) || IsRegisterKind(op, reg.KindGP) +} + +// IsM128 returns true if op is a 128-bit memory operand. +func IsM128(op Op) bool { + // TODO(mbm): should "m128" be the same as "m64"? + return IsM64(op) +} + +// IsM256 returns true if op is a 256-bit memory operand. +func IsM256(op Op) bool { + // TODO(mbm): should "m256" be the same as "m64"? + return IsM64(op) +} + +// IsVM32X returns true if op is a vector memory operand with 32-bit XMM index. +func IsVM32X(op Op) bool { + return IsVmx(op) +} + +// IsVM64X returns true if op is a vector memory operand with 64-bit XMM index. +func IsVM64X(op Op) bool { + return IsVmx(op) +} + +// IsVmx returns true if op is a vector memory operand with XMM index. +func IsVmx(op Op) bool { + return isvm(op, IsXMM) +} + +// IsVM32Y returns true if op is a vector memory operand with 32-bit YMM index. +func IsVM32Y(op Op) bool { + return IsVmy(op) +} + +// IsVM64Y returns true if op is a vector memory operand with 64-bit YMM index. +func IsVM64Y(op Op) bool { + return IsVmy(op) +} + +// IsVmy returns true if op is a vector memory operand with YMM index. +func IsVmy(op Op) bool { + return isvm(op, IsYMM) +} + +func isvm(op Op, idx func(Op) bool) bool { + m, ok := op.(Mem) + return ok && IsR64(m.Base) && idx(m.Index) +} + +// IsREL8 returns true if op is an 8-bit offset relative to instruction pointer. +func IsREL8(op Op) bool { + r, ok := op.(Rel) + return ok && r == Rel(int8(r)) +} + +// IsREL32 returns true if op is an offset relative to instruction pointer, or a +// label reference. +func IsREL32(op Op) bool { + // TODO(mbm): should labels be considered separately? + _, rel := op.(Rel) + _, label := op.(LabelRef) + return rel || label +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/const.go b/vendor/github.com/mmcloughlin/avo/operand/const.go new file mode 100644 index 00000000..b2c6a6f7 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/const.go @@ -0,0 +1,36 @@ +package operand + +import "fmt" + +// Constant represents a constant literal. +type Constant interface { + Op + Bytes() int + constant() +} + +//go:generate go run make_const.go -output zconst.go + +// String is a string constant. +type String string + +// Asm returns an assembly syntax representation of the string s. +func (s String) Asm() string { return fmt.Sprintf("$%q", s) } + +// Bytes returns the length of s. +func (s String) Bytes() int { return len(s) } + +func (s String) constant() {} + +// Imm returns an unsigned integer constant with size guessed from x. +func Imm(x uint64) Constant { + switch { + case uint64(uint8(x)) == x: + return U8(x) + case uint64(uint16(x)) == x: + return U16(x) + case uint64(uint32(x)) == x: + return U32(x) + } + return U64(x) +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/doc.go b/vendor/github.com/mmcloughlin/avo/operand/doc.go new file mode 100644 index 00000000..51c44dfb --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/doc.go @@ -0,0 +1,2 @@ +// Package operand provides types for instruction operands. +package operand diff --git a/vendor/github.com/mmcloughlin/avo/operand/make_const.go b/vendor/github.com/mmcloughlin/avo/operand/make_const.go new file mode 100644 index 00000000..42262c73 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/make_const.go @@ -0,0 +1,73 @@ +// +build ignore + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "io" + "log" + "os" + "path/filepath" + "runtime" + "strconv" +) + +var output = flag.String("output", "", "path to output file (default stdout)") + +func PrintConstType(w io.Writer, name, typ, format string, size int, doc string) { + r := typ[0] + fmt.Fprintf(w, "// %s\n", doc) + fmt.Fprintf(w, "type %s %s\n", name, typ) + fmt.Fprintf(w, "\n") + fmt.Fprintf(w, "func (%c %s) Asm() string { return fmt.Sprintf(\"$%s\", %c) }\n", r, name, format, r) + fmt.Fprintf(w, "func (%c %s) Bytes() int { return %d }\n", r, name, size) + fmt.Fprintf(w, "func (%c %s) constant() {}\n", r, name) + fmt.Fprintf(w, "\n") +} + +func PrintConstTypes(w io.Writer) { + _, self, _, _ := runtime.Caller(0) + fmt.Fprintf(w, "// Code generated by %s. DO NOT EDIT.\n\n", filepath.Base(self)) + fmt.Fprintf(w, "package operand\n\n") + fmt.Fprintf(w, "import \"fmt\"\n\n") + for n := 1; n <= 8; n *= 2 { + bits := n * 8 + bs := strconv.Itoa(bits) + + if n >= 4 { + PrintConstType(w, "F"+bs, "float"+bs, "(%#v)", n, fmt.Sprintf("F%d is a %d-bit floating point constant.", bits, bits)) + } + PrintConstType(w, "I"+bs, "int"+bs, "%+d", n, fmt.Sprintf("I%d is a %d-bit signed integer constant.", bits, bits)) + PrintConstType(w, "U"+bs, "uint"+bs, "%#0"+strconv.Itoa(2*n)+"x", n, fmt.Sprintf("U%d is a %d-bit unsigned integer constant.", bits, bits)) + } +} + +func main() { + flag.Parse() + + w := os.Stdout + if *output != "" { + f, err := os.Create(*output) + if err != nil { + log.Fatal(err) + } + defer f.Close() + w = f + } + + buf := bytes.NewBuffer(nil) + PrintConstTypes(buf) + + src, err := format.Source(buf.Bytes()) + if err != nil { + log.Fatal(err) + } + + _, err = w.Write(src) + if err != nil { + log.Fatal(err) + } +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/types.go b/vendor/github.com/mmcloughlin/avo/operand/types.go new file mode 100644 index 00000000..3ca07e4b --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/types.go @@ -0,0 +1,151 @@ +package operand + +import ( + "fmt" + + "github.com/mmcloughlin/avo/reg" +) + +// Op is an operand. +type Op interface { + Asm() string +} + +// Symbol represents a symbol name. +type Symbol struct { + Name string + Static bool // only visible in current source file +} + +// NewStaticSymbol builds a static Symbol. Static symbols are only visible in the current source file. +func NewStaticSymbol(name string) Symbol { + return Symbol{Name: name, Static: true} +} + +func (s Symbol) String() string { + n := s.Name + if s.Static { + n += "<>" + } + return n +} + +// Mem represents a memory reference. +type Mem struct { + Symbol Symbol + Disp int + Base reg.Register + Index reg.Register + Scale uint8 +} + +// NewParamAddr is a convenience to build a Mem operand pointing to a function +// parameter, which is a named offset from the frame pointer pseudo register. +func NewParamAddr(name string, offset int) Mem { + return Mem{ + Symbol: Symbol{ + Name: name, + Static: false, + }, + Disp: offset, + Base: reg.FramePointer, + } +} + +// NewStackAddr returns a memory reference relative to the stack pointer. +func NewStackAddr(offset int) Mem { + return Mem{ + Disp: offset, + Base: reg.StackPointer, + } +} + +// NewDataAddr returns a memory reference relative to the named data symbol. +func NewDataAddr(sym Symbol, offset int) Mem { + return Mem{ + Symbol: sym, + Disp: offset, + Base: reg.StaticBase, + } +} + +// Offset returns a reference to m plus idx bytes. +func (m Mem) Offset(idx int) Mem { + a := m + a.Disp += idx + return a +} + +// Idx returns a new memory reference with (Index, Scale) set to (r, s). +func (m Mem) Idx(r reg.Register, s uint8) Mem { + a := m + a.Index = r + a.Scale = s + return a +} + +// Asm returns an assembly syntax representation of m. +func (m Mem) Asm() string { + a := m.Symbol.String() + if a != "" { + a += fmt.Sprintf("%+d", m.Disp) + } else if m.Disp != 0 { + a += fmt.Sprintf("%d", m.Disp) + } + if m.Base != nil { + a += fmt.Sprintf("(%s)", m.Base.Asm()) + } + if m.Index != nil && m.Scale != 0 { + a += fmt.Sprintf("(%s*%d)", m.Index.Asm(), m.Scale) + } + return a +} + +// Rel is an offset relative to the instruction pointer. +type Rel int32 + +// Asm returns an assembly syntax representation of r. +func (r Rel) Asm() string { + return fmt.Sprintf(".%+d", r) +} + +// LabelRef is a reference to a label. +type LabelRef string + +// Asm returns an assembly syntax representation of l. +func (l LabelRef) Asm() string { + return string(l) +} + +// Registers returns the list of all operands involved in the given operand. +func Registers(op Op) []reg.Register { + switch op := op.(type) { + case reg.Register: + return []reg.Register{op} + case Mem: + var r []reg.Register + if op.Base != nil { + r = append(r, op.Base) + } + if op.Index != nil { + r = append(r, op.Index) + } + return r + case Constant, Rel, LabelRef: + return nil + } + panic("unknown operand type") +} + +// ApplyAllocation returns an operand with allocated registers replaced. Registers missing from the allocation are left alone. +func ApplyAllocation(op Op, a reg.Allocation) Op { + switch op := op.(type) { + case reg.Register: + return a.LookupDefault(op) + case Mem: + op.Base = a.LookupDefault(op.Base) + op.Index = a.LookupDefault(op.Index) + return op + } + return op +} diff --git a/vendor/github.com/mmcloughlin/avo/operand/zconst.go b/vendor/github.com/mmcloughlin/avo/operand/zconst.go new file mode 100644 index 00000000..324b4a96 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/operand/zconst.go @@ -0,0 +1,75 @@ +// Code generated by make_const.go. DO NOT EDIT. + +package operand + +import "fmt" + +// I8 is a 8-bit signed integer constant. +type I8 int8 + +func (i I8) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I8) Bytes() int { return 1 } +func (i I8) constant() {} + +// U8 is a 8-bit unsigned integer constant. +type U8 uint8 + +func (u U8) Asm() string { return fmt.Sprintf("$%#02x", u) } +func (u U8) Bytes() int { return 1 } +func (u U8) constant() {} + +// I16 is a 16-bit signed integer constant. +type I16 int16 + +func (i I16) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I16) Bytes() int { return 2 } +func (i I16) constant() {} + +// U16 is a 16-bit unsigned integer constant. +type U16 uint16 + +func (u U16) Asm() string { return fmt.Sprintf("$%#04x", u) } +func (u U16) Bytes() int { return 2 } +func (u U16) constant() {} + +// F32 is a 32-bit floating point constant. +type F32 float32 + +func (f F32) Asm() string { return fmt.Sprintf("$(%#v)", f) } +func (f F32) Bytes() int { return 4 } +func (f F32) constant() {} + +// I32 is a 32-bit signed integer constant. +type I32 int32 + +func (i I32) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I32) Bytes() int { return 4 } +func (i I32) constant() {} + +// U32 is a 32-bit unsigned integer constant. +type U32 uint32 + +func (u U32) Asm() string { return fmt.Sprintf("$%#08x", u) } +func (u U32) Bytes() int { return 4 } +func (u U32) constant() {} + +// F64 is a 64-bit floating point constant. +type F64 float64 + +func (f F64) Asm() string { return fmt.Sprintf("$(%#v)", f) } +func (f F64) Bytes() int { return 8 } +func (f F64) constant() {} + +// I64 is a 64-bit signed integer constant. +type I64 int64 + +func (i I64) Asm() string { return fmt.Sprintf("$%+d", i) } +func (i I64) Bytes() int { return 8 } +func (i I64) constant() {} + +// U64 is a 64-bit unsigned integer constant. +type U64 uint64 + +func (u U64) Asm() string { return fmt.Sprintf("$%#016x", u) } +func (u U64) Bytes() int { return 8 } +func (u U64) constant() {} diff --git a/vendor/github.com/mmcloughlin/avo/pass/alloc.go b/vendor/github.com/mmcloughlin/avo/pass/alloc.go new file mode 100644 index 00000000..c67a211c --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/alloc.go @@ -0,0 +1,188 @@ +package pass + +import ( + "errors" + "math" + + "github.com/mmcloughlin/avo/reg" +) + +// edge is an edge of the interference graph, indicating that registers X and Y +// must be in non-conflicting registers. +type edge struct { + X, Y reg.Register +} + +// Allocator is a graph-coloring register allocator. +type Allocator struct { + registers []reg.Physical + allocation reg.Allocation + edges []*edge + possible map[reg.Virtual][]reg.Physical + vidtopid map[reg.VID]reg.PID +} + +// NewAllocator builds an allocator for the given physical registers. +func NewAllocator(rs []reg.Physical) (*Allocator, error) { + if len(rs) == 0 { + return nil, errors.New("no registers") + } + return &Allocator{ + registers: rs, + allocation: reg.NewEmptyAllocation(), + possible: map[reg.Virtual][]reg.Physical{}, + vidtopid: map[reg.VID]reg.PID{}, + }, nil +} + +// NewAllocatorForKind builds an allocator for the given kind of registers. +func NewAllocatorForKind(k reg.Kind) (*Allocator, error) { + f := reg.FamilyOfKind(k) + if f == nil { + return nil, errors.New("unknown register family") + } + return NewAllocator(f.Registers()) +} + +// AddInterferenceSet records that r interferes with every register in s. Convenience wrapper around AddInterference. +func (a *Allocator) AddInterferenceSet(r reg.Register, s reg.Set) { + for y := range s { + a.AddInterference(r, y) + } +} + +// AddInterference records that x and y must be assigned to non-conflicting physical registers. +func (a *Allocator) AddInterference(x, y reg.Register) { + a.Add(x) + a.Add(y) + a.edges = append(a.edges, &edge{X: x, Y: y}) +} + +// Add adds a register to be allocated. Does nothing if the register has already been added. +func (a *Allocator) Add(r reg.Register) { + v, ok := r.(reg.Virtual) + if !ok { + return + } + if _, found := a.possible[v]; found { + return + } + a.possible[v] = a.possibleregisters(v) +} + +// Allocate allocates physical registers. +func (a *Allocator) Allocate() (reg.Allocation, error) { + for { + if err := a.update(); err != nil { + return nil, err + } + + if a.remaining() == 0 { + break + } + + v := a.mostrestricted() + if err := a.alloc(v); err != nil { + return nil, err + } + } + return a.allocation, nil +} + +// update possible allocations based on edges. +func (a *Allocator) update() error { + for v := range a.possible { + pid, found := a.vidtopid[v.VirtualID()] + if !found { + continue + } + a.possible[v] = filterregisters(a.possible[v], func(r reg.Physical) bool { + return r.PhysicalID() == pid + }) + } + + var rem []*edge + for _, e := range a.edges { + e.X, e.Y = a.allocation.LookupDefault(e.X), a.allocation.LookupDefault(e.Y) + + px, py := reg.ToPhysical(e.X), reg.ToPhysical(e.Y) + vx, vy := reg.ToVirtual(e.X), reg.ToVirtual(e.Y) + + switch { + case vx != nil && vy != nil: + rem = append(rem, e) + continue + case px != nil && py != nil: + if reg.AreConflicting(px, py) { + return errors.New("impossible register allocation") + } + case px != nil && vy != nil: + a.discardconflicting(vy, px) + case vx != nil && py != nil: + a.discardconflicting(vx, py) + default: + panic("unreachable") + } + } + a.edges = rem + + return nil +} + +// mostrestricted returns the virtual register with the least possibilities. +func (a *Allocator) mostrestricted() reg.Virtual { + n := int(math.MaxInt32) + var v reg.Virtual + for r, p := range a.possible { + if len(p) < n || (len(p) == n && v != nil && r.VirtualID() < v.VirtualID()) { + n = len(p) + v = r + } + } + return v +} + +// discardconflicting removes registers from vs possible list that conflict with p. +func (a *Allocator) discardconflicting(v reg.Virtual, p reg.Physical) { + a.possible[v] = filterregisters(a.possible[v], func(r reg.Physical) bool { + if pid, found := a.vidtopid[v.VirtualID()]; found && pid == p.PhysicalID() { + return true + } + return !reg.AreConflicting(r, p) + }) +} + +// alloc attempts to allocate a register to v. +func (a *Allocator) alloc(v reg.Virtual) error { + ps := a.possible[v] + if len(ps) == 0 { + return errors.New("failed to allocate registers") + } + p := ps[0] + a.allocation[v] = p + delete(a.possible, v) + a.vidtopid[v.VirtualID()] = p.PhysicalID() + return nil +} + +// remaining returns the number of unallocated registers. +func (a *Allocator) remaining() int { + return len(a.possible) +} + +// possibleregisters returns all allocate-able registers for the given virtual. +func (a *Allocator) possibleregisters(v reg.Virtual) []reg.Physical { + return filterregisters(a.registers, func(r reg.Physical) bool { + return v.SatisfiedBy(r) && (r.Info()®.Restricted) == 0 + }) +} + +func filterregisters(in []reg.Physical, predicate func(reg.Physical) bool) []reg.Physical { + var rs []reg.Physical + for _, r := range in { + if predicate(r) { + rs = append(rs, r) + } + } + return rs +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/cfg.go b/vendor/github.com/mmcloughlin/avo/pass/cfg.go new file mode 100644 index 00000000..198208de --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/cfg.go @@ -0,0 +1,85 @@ +package pass + +import ( + "errors" + "fmt" + + "github.com/mmcloughlin/avo/ir" +) + +// LabelTarget populates the LabelTarget of the given function. This maps from +// label name to the following instruction. +func LabelTarget(fn *ir.Function) error { + target := map[ir.Label]*ir.Instruction{} + var empty ir.Label + pending := empty + for _, node := range fn.Nodes { + switch n := node.(type) { + case ir.Label: + if pending != empty { + return errors.New("instruction should follow a label") + } + pending = n + if _, found := target[pending]; found { + return fmt.Errorf("duplicate label \"%s\"", pending) + } + case *ir.Instruction: + if pending != empty { + target[pending] = n + pending = empty + } + } + } + if pending != empty { + return errors.New("function ends with label") + } + fn.LabelTarget = target + return nil +} + +// CFG constructs the call-flow-graph for the function. +func CFG(fn *ir.Function) error { + is := fn.Instructions() + n := len(is) + + // Populate successors. + for i := 0; i < n; i++ { + cur := is[i] + var nxt *ir.Instruction + if i+1 < n { + nxt = is[i+1] + } + + // If it's a branch, locate the target. + if cur.IsBranch { + lbl := cur.TargetLabel() + if lbl == nil { + return errors.New("no label for branch instruction") + } + target, found := fn.LabelTarget[*lbl] + if !found { + return fmt.Errorf("unknown label %q", *lbl) + } + cur.Succ = append(cur.Succ, target) + } + + // Otherwise, could continue to the following instruction. + switch { + case cur.IsTerminal: + case cur.IsBranch && !cur.IsConditional: + default: + cur.Succ = append(cur.Succ, nxt) + } + } + + // Populate predecessors. + for _, i := range is { + for _, s := range i.Succ { + if s != nil { + s.Pred = append(s.Pred, i) + } + } + } + + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/cleanup.go b/vendor/github.com/mmcloughlin/avo/pass/cleanup.go new file mode 100644 index 00000000..d91250f3 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/cleanup.go @@ -0,0 +1,123 @@ +package pass + +import ( + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" +) + +// PruneJumpToFollowingLabel removes jump instructions that target an +// immediately following label. +func PruneJumpToFollowingLabel(fn *ir.Function) error { + for i := 0; i+1 < len(fn.Nodes); i++ { + node := fn.Nodes[i] + next := fn.Nodes[i+1] + + // This node is an unconditional jump. + inst, ok := node.(*ir.Instruction) + if !ok || !inst.IsBranch || inst.IsConditional { + continue + } + + target := inst.TargetLabel() + if target == nil { + continue + } + + // And the jump target is the immediately following node. + lbl, ok := next.(ir.Label) + if !ok || lbl != *target { + continue + } + + // Then the jump is unnecessary and can be removed. + fn.Nodes = deletenode(fn.Nodes, i) + i-- + } + + return nil +} + +// PruneDanglingLabels removes labels that are not referenced by any branches. +func PruneDanglingLabels(fn *ir.Function) error { + // Count label references. + count := map[ir.Label]int{} + for _, n := range fn.Nodes { + i, ok := n.(*ir.Instruction) + if !ok || !i.IsBranch { + continue + } + + target := i.TargetLabel() + if target == nil { + continue + } + + count[*target]++ + } + + // Look for labels with no references. + for i := 0; i < len(fn.Nodes); i++ { + node := fn.Nodes[i] + lbl, ok := node.(ir.Label) + if !ok { + continue + } + + if count[lbl] == 0 { + fn.Nodes = deletenode(fn.Nodes, i) + i-- + } + } + + return nil +} + +// PruneSelfMoves removes move instructions from one register to itself. +func PruneSelfMoves(fn *ir.Function) error { + return removeinstructions(fn, func(i *ir.Instruction) bool { + switch i.Opcode { + case "MOVB", "MOVW", "MOVL", "MOVQ": + default: + return false + } + + return operand.IsRegister(i.Operands[0]) && operand.IsRegister(i.Operands[1]) && i.Operands[0] == i.Operands[1] + }) +} + +// removeinstructions deletes instructions from the given function which match predicate. +func removeinstructions(fn *ir.Function, predicate func(*ir.Instruction) bool) error { + // Removal of instructions has the potential to invalidate CFG structures. + // Clear them to prevent accidental use of stale structures after this pass. + invalidatecfg(fn) + + for i := 0; i < len(fn.Nodes); i++ { + n := fn.Nodes[i] + + inst, ok := n.(*ir.Instruction) + if !ok || !predicate(inst) { + continue + } + + fn.Nodes = deletenode(fn.Nodes, i) + } + + return nil +} + +// deletenode deletes node i from nodes and returns the resulting slice. +func deletenode(nodes []ir.Node, i int) []ir.Node { + n := len(nodes) + copy(nodes[i:], nodes[i+1:]) + nodes[n-1] = nil + return nodes[:n-1] +} + +// invalidatecfg clears CFG structures. +func invalidatecfg(fn *ir.Function) { + fn.LabelTarget = nil + for _, i := range fn.Instructions() { + i.Pred = nil + i.Succ = nil + } +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/pass.go b/vendor/github.com/mmcloughlin/avo/pass/pass.go new file mode 100644 index 00000000..6b99e717 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/pass.go @@ -0,0 +1,81 @@ +// Package pass implements processing passes on avo Files. +package pass + +import ( + "io" + + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/printer" +) + +// Compile pass compiles an avo file. Upon successful completion the avo file +// may be printed to Go assembly. +var Compile = Concat( + FunctionPass(PruneJumpToFollowingLabel), + FunctionPass(PruneDanglingLabels), + FunctionPass(LabelTarget), + FunctionPass(CFG), + FunctionPass(Liveness), + FunctionPass(AllocateRegisters), + FunctionPass(BindRegisters), + FunctionPass(VerifyAllocation), + Func(IncludeTextFlagHeader), + FunctionPass(PruneSelfMoves), +) + +// Interface for a processing pass. +type Interface interface { + Execute(*ir.File) error +} + +// Func adapts a function to the pass Interface. +type Func func(*ir.File) error + +// Execute calls p. +func (p Func) Execute(f *ir.File) error { + return p(f) +} + +// FunctionPass is a convenience for implementing a full file pass with a +// function that operates on each avo Function independently. +type FunctionPass func(*ir.Function) error + +// Execute calls p on every function in the file. Exits on the first error. +func (p FunctionPass) Execute(f *ir.File) error { + for _, fn := range f.Functions() { + if err := p(fn); err != nil { + return err + } + } + return nil +} + +// Concat returns a pass that executes the given passes in order, stopping on the first error. +func Concat(passes ...Interface) Interface { + return Func(func(f *ir.File) error { + for _, p := range passes { + if err := p.Execute(f); err != nil { + return err + } + } + return nil + }) +} + +// Output pass prints a file. +type Output struct { + Writer io.WriteCloser + Printer printer.Printer +} + +// Execute prints f with the configured Printer and writes output to Writer. +func (o *Output) Execute(f *ir.File) error { + b, err := o.Printer.Print(f) + if err != nil { + return err + } + if _, err = o.Writer.Write(b); err != nil { + return err + } + return o.Writer.Close() +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/reg.go b/vendor/github.com/mmcloughlin/avo/pass/reg.go new file mode 100644 index 00000000..6d6e2153 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/reg.go @@ -0,0 +1,134 @@ +package pass + +import ( + "errors" + + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// Liveness computes register liveness. +func Liveness(fn *ir.Function) error { + // Note this implementation is initially naive so as to be "obviously correct". + // There are a well-known optimizations we can apply if necessary. + + is := fn.Instructions() + + // Process instructions in reverse: poor approximation to topological sort. + // TODO(mbm): process instructions in topological sort order + for l, r := 0, len(is)-1; l < r; l, r = l+1, r-1 { + is[l], is[r] = is[r], is[l] + } + + // Initialize. + for _, i := range is { + i.LiveIn = reg.NewSetFromSlice(i.InputRegisters()) + i.LiveOut = reg.NewEmptySet() + } + + // Iterative dataflow analysis. + for { + changes := false + + for _, i := range is { + // out[n] = UNION[s IN succ[n]] in[s] + nout := len(i.LiveOut) + for _, s := range i.Succ { + if s == nil { + continue + } + i.LiveOut.Update(s.LiveIn) + } + if len(i.LiveOut) != nout { + changes = true + } + + // in[n] = use[n] UNION (out[n] - def[n]) + nin := len(i.LiveIn) + def := reg.NewSetFromSlice(i.OutputRegisters()) + i.LiveIn.Update(i.LiveOut.Difference(def)) + for r := range i.LiveOut { + if _, found := def[r]; !found { + i.LiveIn.Add(r) + } + } + if len(i.LiveIn) != nin { + changes = true + } + } + + if !changes { + break + } + } + + return nil +} + +// AllocateRegisters performs register allocation. +func AllocateRegisters(fn *ir.Function) error { + // Populate allocators (one per kind). + as := map[reg.Kind]*Allocator{} + for _, i := range fn.Instructions() { + for _, r := range i.Registers() { + k := r.Kind() + if _, found := as[k]; !found { + a, err := NewAllocatorForKind(k) + if err != nil { + return err + } + as[k] = a + } + as[k].Add(r) + } + } + + // Record register interferences. + for _, i := range fn.Instructions() { + for _, d := range i.OutputRegisters() { + k := d.Kind() + out := i.LiveOut.OfKind(k) + out.Discard(d) + as[k].AddInterferenceSet(d, out) + } + } + + // Execute register allocation. + fn.Allocation = reg.NewEmptyAllocation() + for _, a := range as { + al, err := a.Allocate() + if err != nil { + return err + } + if err := fn.Allocation.Merge(al); err != nil { + return err + } + } + + return nil +} + +// BindRegisters applies the result of register allocation, replacing all virtual registers with their assigned physical registers. +func BindRegisters(fn *ir.Function) error { + for _, i := range fn.Instructions() { + for idx := range i.Operands { + i.Operands[idx] = operand.ApplyAllocation(i.Operands[idx], fn.Allocation) + } + } + return nil +} + +// VerifyAllocation performs sanity checks following register allocation. +func VerifyAllocation(fn *ir.Function) error { + // All registers should be physical. + for _, i := range fn.Instructions() { + for _, r := range i.Registers() { + if reg.ToPhysical(r) == nil { + return errors.New("non physical register found") + } + } + } + + return nil +} diff --git a/vendor/github.com/mmcloughlin/avo/pass/textflag.go b/vendor/github.com/mmcloughlin/avo/pass/textflag.go new file mode 100644 index 00000000..35a848b8 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/pass/textflag.go @@ -0,0 +1,42 @@ +package pass + +import ( + "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/ir" +) + +// IncludeTextFlagHeader includes textflag.h if necessary. +func IncludeTextFlagHeader(f *ir.File) error { + const textflagheader = "textflag.h" + + // Check if we already have it. + for _, path := range f.Includes { + if path == textflagheader { + return nil + } + } + + // Add it if necessary. + if requirestextflags(f) { + f.Includes = append(f.Includes, textflagheader) + } + + return nil +} + +// requirestextflags returns whether the file uses flags in the textflags.h header. +func requirestextflags(f *ir.File) bool { + for _, s := range f.Sections { + var a attr.Attribute + switch s := s.(type) { + case *ir.Function: + a = s.Attributes + case *ir.Global: + a = s.Attributes + } + if a.ContainsTextFlags() { + return true + } + } + return false +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/goasm.go b/vendor/github.com/mmcloughlin/avo/printer/goasm.go new file mode 100644 index 00000000..66522a55 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/goasm.go @@ -0,0 +1,157 @@ +package printer + +import ( + "fmt" + "strconv" + "strings" + "text/tabwriter" + + "github.com/mmcloughlin/avo/internal/prnt" + "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" +) + +// dot is the pesky unicode dot used in Go assembly. +const dot = "\u00b7" + +type goasm struct { + cfg Config + prnt.Generator +} + +// NewGoAsm constructs a printer for writing Go assembly files. +func NewGoAsm(cfg Config) Printer { + return &goasm{cfg: cfg} +} + +func (p *goasm) Print(f *ir.File) ([]byte, error) { + p.header(f) + for _, s := range f.Sections { + switch s := s.(type) { + case *ir.Function: + p.function(s) + case *ir.Global: + p.global(s) + default: + panic("unknown section type") + } + } + return p.Result() +} + +func (p *goasm) header(f *ir.File) { + p.Comment(p.cfg.GeneratedWarning()) + + if len(f.Constraints) > 0 { + p.NL() + p.Printf(f.Constraints.GoString()) + } + + if len(f.Includes) > 0 { + p.NL() + p.includes(f.Includes) + } +} + +func (p *goasm) includes(paths []string) { + for _, path := range paths { + p.Printf("#include \"%s\"\n", path) + } +} + +func (p *goasm) function(f *ir.Function) { + p.NL() + p.Comment(f.Stub()) + + // Reference: https://github.com/golang/go/blob/b115207baf6c2decc3820ada4574ef4e5ad940ec/src/cmd/internal/obj/util.go#L166-L176 + // + // if p.As == ATEXT { + // // If there are attributes, print them. Otherwise, skip the comma. + // // In short, print one of these two: + // // TEXT foo(SB), DUPOK|NOSPLIT, $0 + // // TEXT foo(SB), $0 + // s := p.From.Sym.Attribute.TextAttrString() + // if s != "" { + // fmt.Fprintf(&buf, "%s%s", sep, s) + // sep = ", " + // } + // } + // + p.Printf("TEXT %s%s(SB)", dot, f.Name) + if f.Attributes != 0 { + p.Printf(", %s", f.Attributes.Asm()) + } + p.Printf(", %s\n", textsize(f)) + + w := p.tabwriter() + clear := true + flush := func() { + w.Flush() + w = p.tabwriter() + if !clear { + p.NL() + clear = true + } + } + for _, node := range f.Nodes { + switch n := node.(type) { + case *ir.Instruction: + leader := []byte{tabwriter.Escape, '\t', tabwriter.Escape} + fmt.Fprint(w, string(leader)+n.Opcode) + if len(n.Operands) > 0 { + fmt.Fprintf(w, "\t%s", joinOperands(n.Operands)) + } + fmt.Fprint(w, "\n") + clear = false + case ir.Label: + flush() + p.Printf("%s:\n", n) + case *ir.Comment: + flush() + for _, line := range n.Lines { + p.Printf("\t// %s\n", line) + } + default: + panic("unexpected node type") + } + } + w.Flush() +} + +func (p *goasm) tabwriter() *tabwriter.Writer { + return tabwriter.NewWriter(p.Raw(), 4, 4, 1, ' ', tabwriter.StripEscape) +} + +func (p *goasm) global(g *ir.Global) { + p.NL() + for _, d := range g.Data { + a := operand.NewDataAddr(g.Symbol, d.Offset) + p.Printf("DATA %s/%d, %s\n", a.Asm(), d.Value.Bytes(), d.Value.Asm()) + } + p.Printf("GLOBL %s(SB), %s, $%d\n", g.Symbol, g.Attributes.Asm(), g.Size) +} + +func textsize(f *ir.Function) string { + // Reference: https://github.com/golang/go/blob/b115207baf6c2decc3820ada4574ef4e5ad940ec/src/cmd/internal/obj/util.go#L260-L265 + // + // case TYPE_TEXTSIZE: + // if a.Val.(int32) == objabi.ArgsSizeUnknown { + // str = fmt.Sprintf("$%d", a.Offset) + // } else { + // str = fmt.Sprintf("$%d-%d", a.Offset, a.Val.(int32)) + // } + // + s := "$" + strconv.Itoa(f.FrameBytes()) + if argsize := f.ArgumentBytes(); argsize > 0 { + return s + "-" + strconv.Itoa(argsize) + } + return s +} + +func joinOperands(operands []operand.Op) string { + asm := make([]string, len(operands)) + for i, op := range operands { + asm[i] = op.Asm() + } + return strings.Join(asm, ", ") +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/printer.go b/vendor/github.com/mmcloughlin/avo/printer/printer.go new file mode 100644 index 00000000..b562c74e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/printer.go @@ -0,0 +1,98 @@ +// Package printer implements printing of avo files in various formats. +package printer + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/mmcloughlin/avo/internal/stack" + "github.com/mmcloughlin/avo/ir" +) + +// Printer can produce output for an avo File. +type Printer interface { + Print(*ir.File) ([]byte, error) +} + +// Builder can construct a printer. +type Builder func(Config) Printer + +// Config represents general printing configuration. +type Config struct { + // Command-line arguments passed to the generator. If provided, this will be + // included in a code generation warning. + Argv []string + + // Name of the code generator. + Name string + + // Name of Go package the generated code will belong to. + Pkg string +} + +// NewDefaultConfig produces a config with Name "avo". +// The package name is guessed from the current directory. +func NewDefaultConfig() Config { + return Config{ + Name: "avo", + Pkg: pkg(), + } +} + +// NewArgvConfig constructs a Config from os.Args. +// The package name is guessed from the current directory. +func NewArgvConfig() Config { + return Config{ + Argv: os.Args, + Pkg: pkg(), + } +} + +// NewGoRunConfig produces a Config for a generator that's expected to be +// executed via "go run ...". +func NewGoRunConfig() Config { + path := mainfile() + if path == "" { + return NewDefaultConfig() + } + argv := []string{"go", "run", filepath.Base(path)} + if len(os.Args) > 1 { + argv = append(argv, os.Args[1:]...) + } + return Config{ + Argv: argv, + Pkg: pkg(), + } +} + +// GeneratedBy returns a description of the code generator. +func (c Config) GeneratedBy() string { + if c.Argv == nil { + return c.Name + } + return fmt.Sprintf("command: %s", strings.Join(c.Argv, " ")) +} + +// GeneratedWarning returns text for a code generation warning. Conforms to https://golang.org/s/generatedcode. +func (c Config) GeneratedWarning() string { + return fmt.Sprintf("Code generated by %s. DO NOT EDIT.", c.GeneratedBy()) +} + +// mainfile attempts to determine the file path of the main function by +// inspecting the stack. Returns empty string on failure. +func mainfile() string { + if m := stack.Main(); m != nil { + return m.File + } + return "" +} + +// pkg guesses the name of the package from the working directory. +func pkg() string { + if cwd, err := os.Getwd(); err == nil { + return filepath.Base(cwd) + } + return "" +} diff --git a/vendor/github.com/mmcloughlin/avo/printer/stubs.go b/vendor/github.com/mmcloughlin/avo/printer/stubs.go new file mode 100644 index 00000000..1aedcf07 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/printer/stubs.go @@ -0,0 +1,34 @@ +package printer + +import ( + "github.com/mmcloughlin/avo/internal/prnt" + "github.com/mmcloughlin/avo/ir" +) + +type stubs struct { + cfg Config + prnt.Generator +} + +// NewStubs constructs a printer for writing stub function declarations. +func NewStubs(cfg Config) Printer { + return &stubs{cfg: cfg} +} + +func (s *stubs) Print(f *ir.File) ([]byte, error) { + s.Comment(s.cfg.GeneratedWarning()) + + if len(f.Constraints) > 0 { + s.NL() + s.Printf(f.Constraints.GoString()) + } + + s.NL() + s.Printf("package %s\n", s.cfg.Pkg) + for _, fn := range f.Functions() { + s.NL() + s.Comment(fn.Doc...) + s.Printf("%s\n", fn.Stub()) + } + return s.Result() +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/collection.go b/vendor/github.com/mmcloughlin/avo/reg/collection.go new file mode 100644 index 00000000..5c85104e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/collection.go @@ -0,0 +1,48 @@ +package reg + +// Collection represents a collection of virtual registers. This is primarily +// useful for allocating virtual registers with distinct IDs. +type Collection struct { + vid map[Kind]VID +} + +// NewCollection builds an empty register collection. +func NewCollection() *Collection { + return &Collection{ + vid: map[Kind]VID{}, + } +} + +// VirtualRegister allocates and returns a new virtual register of the given kind and width. +func (c *Collection) VirtualRegister(k Kind, w Width) Virtual { + vid := c.vid[k] + c.vid[k]++ + return NewVirtual(vid, k, w) +} + +// GP8 allocates and returns a general-purpose 8-bit register. +func (c *Collection) GP8() GPVirtual { return c.GP(B8) } + +// GP16 allocates and returns a general-purpose 16-bit register. +func (c *Collection) GP16() GPVirtual { return c.GP(B16) } + +// GP32 allocates and returns a general-purpose 32-bit register. +func (c *Collection) GP32() GPVirtual { return c.GP(B32) } + +// GP64 allocates and returns a general-purpose 64-bit register. +func (c *Collection) GP64() GPVirtual { return c.GP(B64) } + +// GP allocates and returns a general-purpose register of the given width. +func (c *Collection) GP(w Width) GPVirtual { return newgpv(c.VirtualRegister(KindGP, w)) } + +// XMM allocates and returns a 128-bit vector register. +func (c *Collection) XMM() VecVirtual { return c.Vec(B128) } + +// YMM allocates and returns a 256-bit vector register. +func (c *Collection) YMM() VecVirtual { return c.Vec(B256) } + +// ZMM allocates and returns a 512-bit vector register. +func (c *Collection) ZMM() VecVirtual { return c.Vec(B512) } + +// Vec allocates and returns a vector register of the given width. +func (c *Collection) Vec(w Width) VecVirtual { return newvecv(c.VirtualRegister(KindVector, w)) } diff --git a/vendor/github.com/mmcloughlin/avo/reg/doc.go b/vendor/github.com/mmcloughlin/avo/reg/doc.go new file mode 100644 index 00000000..1c0aee37 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/doc.go @@ -0,0 +1,2 @@ +// Package reg provides types for physical and virtual registers, and definitions of x86-64 register families. +package reg diff --git a/vendor/github.com/mmcloughlin/avo/reg/set.go b/vendor/github.com/mmcloughlin/avo/reg/set.go new file mode 100644 index 00000000..fd1ddf3a --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/set.go @@ -0,0 +1,82 @@ +package reg + +// Set is a set of registers. +type Set map[Register]bool + +// NewEmptySet builds an empty register set. +func NewEmptySet() Set { + return Set{} +} + +// NewSetFromSlice forms a set from the given register list. +func NewSetFromSlice(rs []Register) Set { + s := NewEmptySet() + for _, r := range rs { + s.Add(r) + } + return s +} + +// Clone returns a copy of s. +func (s Set) Clone() Set { + c := NewEmptySet() + for r := range s { + c.Add(r) + } + return c +} + +// Add r to s. +func (s Set) Add(r Register) { + s[r] = true +} + +// Discard removes r from s, if present. +func (s Set) Discard(r Register) { + delete(s, r) +} + +// Update adds every register in t to s. +func (s Set) Update(t Set) { + for r := range t { + s.Add(r) + } +} + +// Difference returns the set of registers in s but not t. +func (s Set) Difference(t Set) Set { + d := s.Clone() + d.DifferenceUpdate(t) + return d +} + +// DifferenceUpdate removes every element of t from s. +func (s Set) DifferenceUpdate(t Set) { + for r := range t { + s.Discard(r) + } +} + +// Equals returns true if s and t contain the same registers. +func (s Set) Equals(t Set) bool { + if len(s) != len(t) { + return false + } + for r := range s { + if _, found := t[r]; !found { + return false + } + } + return true +} + +// OfKind returns the set of elements of s with kind k. +func (s Set) OfKind(k Kind) Set { + t := NewEmptySet() + for r := range s { + if r.Kind() == k { + t.Add(r) + } + } + return t +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/types.go b/vendor/github.com/mmcloughlin/avo/reg/types.go new file mode 100644 index 00000000..cd9f32ac --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/types.go @@ -0,0 +1,269 @@ +package reg + +import ( + "errors" + "fmt" +) + +// Width is a register width. +type Width uint + +// Typical register width values. +const ( + B8 Width = 1 << iota + B16 + B32 + B64 + B128 + B256 + B512 +) + +// Size returns the register width in bytes. +func (w Width) Size() uint { return uint(w) } + +// Kind is a class of registers. +type Kind uint8 + +// Family is a collection of Physical registers of a common kind. +type Family struct { + Kind Kind + registers []Physical +} + +// define builds a register and adds it to the Family. +func (f *Family) define(s Spec, id PID, name string, flags ...Info) Physical { + r := newregister(f, s, id, name, flags...) + f.add(r) + return r +} + +// add r to the family. +func (f *Family) add(r Physical) { + if r.Kind() != f.Kind { + panic("bad kind") + } + f.registers = append(f.registers, r) +} + +// Virtual returns a virtual register from this family's kind. +func (f *Family) Virtual(id VID, w Width) Virtual { + return NewVirtual(id, f.Kind, w) +} + +// Registers returns the registers in this family. +func (f *Family) Registers() []Physical { + return append([]Physical(nil), f.registers...) +} + +// Set returns the set of registers in the family. +func (f *Family) Set() Set { + s := NewEmptySet() + for _, r := range f.registers { + s.Add(r) + } + return s +} + +// Lookup returns the register with given physical ID and spec. Returns nil if no such register exists. +func (f *Family) Lookup(id PID, s Spec) Physical { + for _, r := range f.registers { + if r.PhysicalID() == id && r.Mask() == s.Mask() { + return r + } + } + return nil +} + +// Register represents a virtual or physical register. +type Register interface { + Kind() Kind + Size() uint + Asm() string + as(Spec) Register + register() +} + +// VID is a virtual register ID. +type VID uint16 + +// Virtual is a register of a given type and size, not yet allocated to a physical register. +type Virtual interface { + VirtualID() VID + SatisfiedBy(Physical) bool + Register +} + +// ToVirtual converts r to Virtual if possible, otherwise returns nil. +func ToVirtual(r Register) Virtual { + if v, ok := r.(Virtual); ok { + return v + } + return nil +} + +type virtual struct { + id VID + kind Kind + Width + mask uint16 +} + +// NewVirtual builds a Virtual register. +func NewVirtual(id VID, k Kind, w Width) Virtual { + return virtual{ + id: id, + kind: k, + Width: w, + } +} + +func (v virtual) VirtualID() VID { return v.id } +func (v virtual) Kind() Kind { return v.kind } + +func (v virtual) Asm() string { + // TODO(mbm): decide on virtual register syntax + return fmt.Sprintf("", v.id, v.Kind(), v.Size()) +} + +func (v virtual) SatisfiedBy(p Physical) bool { + return v.Kind() == p.Kind() && v.Size() == p.Size() && (v.mask == 0 || v.mask == p.Mask()) +} + +func (v virtual) as(s Spec) Register { + return virtual{ + id: v.id, + kind: v.kind, + Width: Width(s.Size()), + mask: s.Mask(), + } +} + +func (v virtual) register() {} + +// Info is a bitmask of register properties. +type Info uint8 + +// Defined register Info flags. +const ( + None Info = 0 + Restricted Info = 1 << iota +) + +// PID is a physical register ID. +type PID uint16 + +// Physical is a concrete register. +type Physical interface { + PhysicalID() PID + Mask() uint16 + Info() Info + Register +} + +// ToPhysical converts r to Physical if possible, otherwise returns nil. +func ToPhysical(r Register) Physical { + if p, ok := r.(Physical); ok { + return p + } + return nil +} + +// register implements Physical. +type register struct { + family *Family + id PID + name string + info Info + Spec +} + +func newregister(f *Family, s Spec, id PID, name string, flags ...Info) register { + r := register{ + family: f, + id: id, + name: name, + info: None, + Spec: s, + } + for _, flag := range flags { + r.info |= flag + } + return r +} + +func (r register) PhysicalID() PID { return r.id } +func (r register) Kind() Kind { return r.family.Kind } +func (r register) Asm() string { return r.name } +func (r register) Info() Info { return r.info } + +func (r register) as(s Spec) Register { + return r.family.Lookup(r.PhysicalID(), s) +} + +func (r register) register() {} + +// Spec defines the size of a register as well as the bit ranges it occupies in +// an underlying physical register. +type Spec uint16 + +// Spec values required for x86-64. +const ( + S0 Spec = 0x0 // zero value reserved for pseudo registers + S8L Spec = 0x1 + S8H Spec = 0x2 + S8 = S8L + S16 Spec = 0x3 + S32 Spec = 0x7 + S64 Spec = 0xf + S128 Spec = 0x1f + S256 Spec = 0x3f + S512 Spec = 0x7f +) + +// Mask returns a mask representing which bytes of an underlying register are +// used by this register. This is almost always the low bytes, except for the +// case of the high-byte registers. If bit n of the mask is set, this means +// bytes 2^(n-1) to 2^n-1 are used. +func (s Spec) Mask() uint16 { + return uint16(s) +} + +// Size returns the register width in bytes. +func (s Spec) Size() uint { + x := uint(s) + return (x >> 1) + (x & 1) +} + +// AreConflicting returns whether registers conflict with each other. +func AreConflicting(x, y Physical) bool { + return x.Kind() == y.Kind() && x.PhysicalID() == y.PhysicalID() && (x.Mask()&y.Mask()) != 0 +} + +// Allocation records a register allocation. +type Allocation map[Register]Physical + +// NewEmptyAllocation builds an empty register allocation. +func NewEmptyAllocation() Allocation { + return Allocation{} +} + +// Merge allocations from b into a. Errors if there is disagreement on a common +// register. +func (a Allocation) Merge(b Allocation) error { + for r, p := range b { + if alt, found := a[r]; found && alt != p { + return errors.New("disagreement on overlapping register") + } + a[r] = p + } + return nil +} + +// LookupDefault returns the register assigned to r, or r itself if there is none. +func (a Allocation) LookupDefault(r Register) Register { + if p, found := a[r]; found { + return p + } + return r +} diff --git a/vendor/github.com/mmcloughlin/avo/reg/x86.go b/vendor/github.com/mmcloughlin/avo/reg/x86.go new file mode 100644 index 00000000..96316bd5 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/reg/x86.go @@ -0,0 +1,330 @@ +package reg + +// Register kinds. +const ( + KindPseudo Kind = iota + KindGP + KindVector +) + +// Declare register families. +var ( + Pseudo = &Family{Kind: KindPseudo} + GeneralPurpose = &Family{Kind: KindGP} + Vector = &Family{Kind: KindVector} + + Families = []*Family{ + Pseudo, + GeneralPurpose, + Vector, + } +) + +var familiesByKind = map[Kind]*Family{} + +func init() { + for _, f := range Families { + familiesByKind[f.Kind] = f + } +} + +// FamilyOfKind returns the Family of registers of the given kind. +func FamilyOfKind(k Kind) *Family { + return familiesByKind[k] +} + +// Pseudo registers. +var ( + FramePointer = Pseudo.define(S0, 0, "FP") + ProgramCounter = Pseudo.define(S0, 0, "PC") + StaticBase = Pseudo.define(S0, 0, "SB") + StackPointer = Pseudo.define(S0, 0, "SP") +) + +// GP provides additional methods for general purpose registers. +type GP interface { + As8() Register + As8L() Register + As8H() Register + As16() Register + As32() Register + As64() Register +} + +type gpcasts struct { + Register +} + +func (c gpcasts) As8() Register { return c.as(S8) } +func (c gpcasts) As8L() Register { return c.as(S8L) } +func (c gpcasts) As8H() Register { return c.as(S8H) } +func (c gpcasts) As16() Register { return c.as(S16) } +func (c gpcasts) As32() Register { return c.as(S32) } +func (c gpcasts) As64() Register { return c.as(S64) } + +// GPPhysical is a general-purpose physical register. +type GPPhysical interface { + Physical + GP +} + +type gpp struct { + Physical + GP +} + +func newgpp(r Physical) GPPhysical { return gpp{Physical: r, GP: gpcasts{r}} } + +// GPVirtual is a general-purpose virtual register. +type GPVirtual interface { + Virtual + GP +} + +type gpv struct { + Virtual + GP +} + +func newgpv(v Virtual) GPVirtual { return gpv{Virtual: v, GP: gpcasts{v}} } + +func gp(s Spec, id PID, name string, flags ...Info) GPPhysical { + r := newgpp(newregister(GeneralPurpose, s, id, name, flags...)) + GeneralPurpose.add(r) + return r +} + +// General purpose registers. +var ( + // Low byte + AL = gp(S8L, 0, "AL") + CL = gp(S8L, 1, "CL") + DL = gp(S8L, 2, "DL") + BL = gp(S8L, 3, "BL") + + // High byte + AH = gp(S8H, 0, "AH") + CH = gp(S8H, 1, "CH") + DH = gp(S8H, 2, "DH") + BH = gp(S8H, 3, "BH") + + // 8-bit + SPB = gp(S8, 4, "SP", Restricted) + BPB = gp(S8, 5, "BP") + SIB = gp(S8, 6, "SI") + DIB = gp(S8, 7, "DI") + R8B = gp(S8, 8, "R8") + R9B = gp(S8, 9, "R9") + R10B = gp(S8, 10, "R10") + R11B = gp(S8, 11, "R11") + R12B = gp(S8, 12, "R12") + R13B = gp(S8, 13, "R13") + R14B = gp(S8, 14, "R14") + R15B = gp(S8, 15, "R15") + + // 16-bit + AX = gp(S16, 0, "AX") + CX = gp(S16, 1, "CX") + DX = gp(S16, 2, "DX") + BX = gp(S16, 3, "BX") + SP = gp(S16, 4, "SP", Restricted) + BP = gp(S16, 5, "BP") + SI = gp(S16, 6, "SI") + DI = gp(S16, 7, "DI") + R8W = gp(S16, 8, "R8") + R9W = gp(S16, 9, "R9") + R10W = gp(S16, 10, "R10") + R11W = gp(S16, 11, "R11") + R12W = gp(S16, 12, "R12") + R13W = gp(S16, 13, "R13") + R14W = gp(S16, 14, "R14") + R15W = gp(S16, 15, "R15") + + // 32-bit + EAX = gp(S32, 0, "AX") + ECX = gp(S32, 1, "CX") + EDX = gp(S32, 2, "DX") + EBX = gp(S32, 3, "BX") + ESP = gp(S32, 4, "SP", Restricted) + EBP = gp(S32, 5, "BP") + ESI = gp(S32, 6, "SI") + EDI = gp(S32, 7, "DI") + R8L = gp(S32, 8, "R8") + R9L = gp(S32, 9, "R9") + R10L = gp(S32, 10, "R10") + R11L = gp(S32, 11, "R11") + R12L = gp(S32, 12, "R12") + R13L = gp(S32, 13, "R13") + R14L = gp(S32, 14, "R14") + R15L = gp(S32, 15, "R15") + + // 64-bit + RAX = gp(S64, 0, "AX") + RCX = gp(S64, 1, "CX") + RDX = gp(S64, 2, "DX") + RBX = gp(S64, 3, "BX") + RSP = gp(S64, 4, "SP", Restricted) + RBP = gp(S64, 5, "BP") + RSI = gp(S64, 6, "SI") + RDI = gp(S64, 7, "DI") + R8 = gp(S64, 8, "R8") + R9 = gp(S64, 9, "R9") + R10 = gp(S64, 10, "R10") + R11 = gp(S64, 11, "R11") + R12 = gp(S64, 12, "R12") + R13 = gp(S64, 13, "R13") + R14 = gp(S64, 14, "R14") + R15 = gp(S64, 15, "R15") +) + +// Vec provides methods for vector registers. +type Vec interface { + AsX() Register + AsY() Register + AsZ() Register +} + +type veccasts struct { + Register +} + +func (c veccasts) AsX() Register { return c.as(S128) } +func (c veccasts) AsY() Register { return c.as(S256) } +func (c veccasts) AsZ() Register { return c.as(S512) } + +// VecPhysical is a physical vector register. +type VecPhysical interface { + Physical + Vec +} + +type vecp struct { + Physical + Vec +} + +func newvecp(r Physical) VecPhysical { return vecp{Physical: r, Vec: veccasts{r}} } + +// VecVirtual is a virtual vector register. +type VecVirtual interface { + Virtual + Vec +} + +type vecv struct { + Virtual + Vec +} + +func newvecv(v Virtual) VecVirtual { return vecv{Virtual: v, Vec: veccasts{v}} } + +func vec(s Spec, id PID, name string, flags ...Info) VecPhysical { + r := newvecp(newregister(Vector, s, id, name, flags...)) + Vector.add(r) + return r +} + +// Vector registers. +var ( + // 128-bit + X0 = vec(S128, 0, "X0") + X1 = vec(S128, 1, "X1") + X2 = vec(S128, 2, "X2") + X3 = vec(S128, 3, "X3") + X4 = vec(S128, 4, "X4") + X5 = vec(S128, 5, "X5") + X6 = vec(S128, 6, "X6") + X7 = vec(S128, 7, "X7") + X8 = vec(S128, 8, "X8") + X9 = vec(S128, 9, "X9") + X10 = vec(S128, 10, "X10") + X11 = vec(S128, 11, "X11") + X12 = vec(S128, 12, "X12") + X13 = vec(S128, 13, "X13") + X14 = vec(S128, 14, "X14") + X15 = vec(S128, 15, "X15") + X16 = vec(S128, 16, "X16") + X17 = vec(S128, 17, "X17") + X18 = vec(S128, 18, "X18") + X19 = vec(S128, 19, "X19") + X20 = vec(S128, 20, "X20") + X21 = vec(S128, 21, "X21") + X22 = vec(S128, 22, "X22") + X23 = vec(S128, 23, "X23") + X24 = vec(S128, 24, "X24") + X25 = vec(S128, 25, "X25") + X26 = vec(S128, 26, "X26") + X27 = vec(S128, 27, "X27") + X28 = vec(S128, 28, "X28") + X29 = vec(S128, 29, "X29") + X30 = vec(S128, 30, "X30") + X31 = vec(S128, 31, "X31") + + // 256-bit + Y0 = vec(S256, 0, "Y0") + Y1 = vec(S256, 1, "Y1") + Y2 = vec(S256, 2, "Y2") + Y3 = vec(S256, 3, "Y3") + Y4 = vec(S256, 4, "Y4") + Y5 = vec(S256, 5, "Y5") + Y6 = vec(S256, 6, "Y6") + Y7 = vec(S256, 7, "Y7") + Y8 = vec(S256, 8, "Y8") + Y9 = vec(S256, 9, "Y9") + Y10 = vec(S256, 10, "Y10") + Y11 = vec(S256, 11, "Y11") + Y12 = vec(S256, 12, "Y12") + Y13 = vec(S256, 13, "Y13") + Y14 = vec(S256, 14, "Y14") + Y15 = vec(S256, 15, "Y15") + Y16 = vec(S256, 16, "Y16") + Y17 = vec(S256, 17, "Y17") + Y18 = vec(S256, 18, "Y18") + Y19 = vec(S256, 19, "Y19") + Y20 = vec(S256, 20, "Y20") + Y21 = vec(S256, 21, "Y21") + Y22 = vec(S256, 22, "Y22") + Y23 = vec(S256, 23, "Y23") + Y24 = vec(S256, 24, "Y24") + Y25 = vec(S256, 25, "Y25") + Y26 = vec(S256, 26, "Y26") + Y27 = vec(S256, 27, "Y27") + Y28 = vec(S256, 28, "Y28") + Y29 = vec(S256, 29, "Y29") + Y30 = vec(S256, 30, "Y30") + Y31 = vec(S256, 31, "Y31") + + // 512-bit + Z0 = vec(S512, 0, "Z0") + Z1 = vec(S512, 1, "Z1") + Z2 = vec(S512, 2, "Z2") + Z3 = vec(S512, 3, "Z3") + Z4 = vec(S512, 4, "Z4") + Z5 = vec(S512, 5, "Z5") + Z6 = vec(S512, 6, "Z6") + Z7 = vec(S512, 7, "Z7") + Z8 = vec(S512, 8, "Z8") + Z9 = vec(S512, 9, "Z9") + Z10 = vec(S512, 10, "Z10") + Z11 = vec(S512, 11, "Z11") + Z12 = vec(S512, 12, "Z12") + Z13 = vec(S512, 13, "Z13") + Z14 = vec(S512, 14, "Z14") + Z15 = vec(S512, 15, "Z15") + Z16 = vec(S512, 16, "Z16") + Z17 = vec(S512, 17, "Z17") + Z18 = vec(S512, 18, "Z18") + Z19 = vec(S512, 19, "Z19") + Z20 = vec(S512, 20, "Z20") + Z21 = vec(S512, 21, "Z21") + Z22 = vec(S512, 22, "Z22") + Z23 = vec(S512, 23, "Z23") + Z24 = vec(S512, 24, "Z24") + Z25 = vec(S512, 25, "Z25") + Z26 = vec(S512, 26, "Z26") + Z27 = vec(S512, 27, "Z27") + Z28 = vec(S512, 28, "Z28") + Z29 = vec(S512, 29, "Z29") + Z30 = vec(S512, 30, "Z30") + Z31 = vec(S512, 31, "Z31") +) diff --git a/vendor/github.com/mmcloughlin/avo/src/src.go b/vendor/github.com/mmcloughlin/avo/src/src.go new file mode 100644 index 00000000..3a47886e --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/src/src.go @@ -0,0 +1,62 @@ +// Package src provides types for working with source files. +package src + +import ( + "os" + "path/filepath" + "runtime" + "strconv" +) + +// Position represents a position in a source file. +type Position struct { + Filename string + Line int // 1-up +} + +// FramePosition returns the Position of the given stack frame. +func FramePosition(f runtime.Frame) Position { + return Position{ + Filename: f.File, + Line: f.Line, + } +} + +// IsValid reports whether the position is valid: Line must be positive, but +// Filename may be empty. +func (p Position) IsValid() bool { + return p.Line > 0 +} + +// String represents Position as a string. +func (p Position) String() string { + if !p.IsValid() { + return "-" + } + var s string + if p.Filename != "" { + s += p.Filename + ":" + } + s += strconv.Itoa(p.Line) + return s +} + +// Rel returns Position relative to basepath. If the given filename cannot be +// expressed relative to basepath the position will be returned unchanged. +func (p Position) Rel(basepath string) Position { + q := p + if rel, err := filepath.Rel(basepath, q.Filename); err == nil { + q.Filename = rel + } + return q +} + +// Relwd returns Position relative to the current working directory. Returns p +// unchanged if the working directory cannot be determined, or the filename +// cannot be expressed relative to the working directory. +func (p Position) Relwd() Position { + if wd, err := os.Getwd(); err == nil { + return p.Rel(wd) + } + return p +} diff --git a/vendor/github.com/mmcloughlin/avo/x86/doc.go b/vendor/github.com/mmcloughlin/avo/x86/doc.go new file mode 100644 index 00000000..6e4c8ee8 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/doc.go @@ -0,0 +1,2 @@ +// Package x86 provides constructors for all x86-64 instructions. +package x86 diff --git a/vendor/github.com/mmcloughlin/avo/x86/gen.go b/vendor/github.com/mmcloughlin/avo/x86/gen.go new file mode 100644 index 00000000..25d15fa6 --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/gen.go @@ -0,0 +1,4 @@ +package x86 + +//go:generate avogen -output zctors.go ctors +//go:generate avogen -output zctors_test.go ctorstest diff --git a/vendor/github.com/mmcloughlin/avo/x86/zctors.go b/vendor/github.com/mmcloughlin/avo/x86/zctors.go new file mode 100644 index 00000000..3ef1d2fd --- /dev/null +++ b/vendor/github.com/mmcloughlin/avo/x86/zctors.go @@ -0,0 +1,32576 @@ +// Code generated by command: avogen -output zctors.go ctors. DO NOT EDIT. + +package x86 + +import ( + "errors" + intrep "github.com/mmcloughlin/avo/ir" + "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" +) + +// ADCB: Add with Carry. +// +// Forms: +// +// ADCB imm8 al +// ADCB imm8 r8 +// ADCB r8 r8 +// ADCB m8 r8 +// ADCB imm8 m8 +// ADCB r8 m8 +func ADCB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADCB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADCB: bad operands") +} + +// ADCL: Add with Carry. +// +// Forms: +// +// ADCL imm32 eax +// ADCL imm8 r32 +// ADCL imm32 r32 +// ADCL r32 r32 +// ADCL m32 r32 +// ADCL imm8 m32 +// ADCL imm32 m32 +// ADCL r32 m32 +func ADCL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADCL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ADCL: bad operands") +} + +// ADCQ: Add with Carry. +// +// Forms: +// +// ADCQ imm32 rax +// ADCQ imm8 r64 +// ADCQ imm32 r64 +// ADCQ r64 r64 +// ADCQ m64 r64 +// ADCQ imm8 m64 +// ADCQ imm32 m64 +// ADCQ r64 m64 +func ADCQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADCQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ADCQ: bad operands") +} + +// ADCW: Add with Carry. +// +// Forms: +// +// ADCW imm16 ax +// ADCW imm8 r16 +// ADCW imm16 r16 +// ADCW r16 r16 +// ADCW m16 r16 +// ADCW imm8 m16 +// ADCW imm16 m16 +// ADCW r16 m16 +func ADCW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADCW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADCW: bad operands") +} + +// ADCXL: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXL r32 r32 +// ADCXL m32 r32 +func ADCXL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADCXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADCXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("ADCXL: bad operands") +} + +// ADCXQ: Unsigned Integer Addition of Two Operands with Carry Flag. +// +// Forms: +// +// ADCXQ r64 r64 +// ADCXQ m64 r64 +func ADCXQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADCXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADCXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("ADCXQ: bad operands") +} + +// ADDB: Add. +// +// Forms: +// +// ADDB imm8 al +// ADDB imm8 r8 +// ADDB r8 r8 +// ADDB m8 r8 +// ADDB imm8 m8 +// ADDB r8 m8 +func ADDB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ADDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADDB: bad operands") +} + +// ADDL: Add. +// +// Forms: +// +// ADDL imm32 eax +// ADDL imm8 r32 +// ADDL imm32 r32 +// ADDL r32 r32 +// ADDL m32 r32 +// ADDL imm8 m32 +// ADDL imm32 m32 +// ADDL r32 m32 +func ADDL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ADDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ADDL: bad operands") +} + +// ADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDPD xmm xmm +// ADDPD m128 xmm +func ADDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDPD: bad operands") +} + +// ADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDPS xmm xmm +// ADDPS m128 xmm +func ADDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDPS: bad operands") +} + +// ADDQ: Add. +// +// Forms: +// +// ADDQ imm32 rax +// ADDQ imm8 r64 +// ADDQ imm32 r64 +// ADDQ r64 r64 +// ADDQ m64 r64 +// ADDQ imm8 m64 +// ADDQ imm32 m64 +// ADDQ r64 m64 +func ADDQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ADDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ADDQ: bad operands") +} + +// ADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// ADDSD xmm xmm +// ADDSD m64 xmm +func ADDSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDSD: bad operands") +} + +// ADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// ADDSS xmm xmm +// ADDSS m32 xmm +func ADDSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDSS: bad operands") +} + +// ADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPD xmm xmm +// ADDSUBPD m128 xmm +func ADDSUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDSUBPD: bad operands") +} + +// ADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// ADDSUBPS xmm xmm +// ADDSUBPS m128 xmm +func ADDSUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ADDSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ADDSUBPS: bad operands") +} + +// ADDW: Add. +// +// Forms: +// +// ADDW imm16 ax +// ADDW imm8 r16 +// ADDW imm16 r16 +// ADDW r16 r16 +// ADDW m16 r16 +// ADDW imm8 m16 +// ADDW imm16 m16 +// ADDW r16 m16 +func ADDW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ADDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ADDW: bad operands") +} + +// ADOXL: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXL r32 r32 +// ADOXL m32 r32 +func ADOXL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADOXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "ADOXL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("ADOXL: bad operands") +} + +// ADOXQ: Unsigned Integer Addition of Two Operands with Overflow Flag. +// +// Forms: +// +// ADOXQ r64 r64 +// ADOXQ m64 r64 +func ADOXQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADOXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "ADOXQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("ADOXQ: bad operands") +} + +// AESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// AESDEC xmm xmm +// AESDEC m128 xmm +func AESDEC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDEC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDEC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESDEC: bad operands") +} + +// AESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// AESDECLAST xmm xmm +// AESDECLAST m128 xmm +func AESDECLAST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDECLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESDECLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESDECLAST: bad operands") +} + +// AESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// AESENC xmm xmm +// AESENC m128 xmm +func AESENC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESENC: bad operands") +} + +// AESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// AESENCLAST xmm xmm +// AESENCLAST m128 xmm +func AESENCLAST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENCLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESENCLAST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESENCLAST: bad operands") +} + +// AESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// AESIMC xmm xmm +// AESIMC m128 xmm +func AESIMC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESIMC: bad operands") +} + +// AESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// AESKEYGENASSIST imm8 xmm xmm +// AESKEYGENASSIST imm8 m128 xmm +func AESKEYGENASSIST(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "AESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("AESKEYGENASSIST: bad operands") +} + +// ANDB: Logical AND. +// +// Forms: +// +// ANDB imm8 al +// ANDB imm8 r8 +// ANDB r8 r8 +// ANDB m8 r8 +// ANDB imm8 m8 +// ANDB r8 m8 +func ANDB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ANDB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ANDB: bad operands") +} + +// ANDL: Logical AND. +// +// Forms: +// +// ANDL imm32 eax +// ANDL imm8 r32 +// ANDL imm32 r32 +// ANDL r32 r32 +// ANDL m32 r32 +// ANDL imm8 m32 +// ANDL imm32 m32 +// ANDL r32 m32 +func ANDL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ANDL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ANDL: bad operands") +} + +// ANDNL: Logical AND NOT. +// +// Forms: +// +// ANDNL r32 r32 r32 +// ANDNL m32 r32 r32 +func ANDNL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "ANDNL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "ANDNL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("ANDNL: bad operands") +} + +// ANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPD xmm xmm +// ANDNPD m128 xmm +func ANDNPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ANDNPD: bad operands") +} + +// ANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDNPS xmm xmm +// ANDNPS m128 xmm +func ANDNPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDNPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ANDNPS: bad operands") +} + +// ANDNQ: Logical AND NOT. +// +// Forms: +// +// ANDNQ r64 r64 r64 +// ANDNQ m64 r64 r64 +func ANDNQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "ANDNQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "ANDNQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("ANDNQ: bad operands") +} + +// ANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// ANDPD xmm xmm +// ANDPD m128 xmm +func ANDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ANDPD: bad operands") +} + +// ANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// ANDPS xmm xmm +// ANDPS m128 xmm +func ANDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ANDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ANDPS: bad operands") +} + +// ANDQ: Logical AND. +// +// Forms: +// +// ANDQ imm32 rax +// ANDQ imm8 r64 +// ANDQ imm32 r64 +// ANDQ r64 r64 +// ANDQ m64 r64 +// ANDQ imm8 m64 +// ANDQ imm32 m64 +// ANDQ r64 m64 +func ANDQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ANDQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ANDQ: bad operands") +} + +// ANDW: Logical AND. +// +// Forms: +// +// ANDW imm16 ax +// ANDW imm8 r16 +// ANDW imm16 r16 +// ANDW r16 r16 +// ANDW m16 r16 +// ANDW imm8 m16 +// ANDW imm16 m16 +// ANDW r16 m16 +func ANDW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ANDW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ANDW: bad operands") +} + +// BEXTRL: Bit Field Extract. +// +// Forms: +// +// BEXTRL r32 r32 r32 +// BEXTRL r32 m32 r32 +func BEXTRL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BEXTRL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BEXTRL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("BEXTRL: bad operands") +} + +// BEXTRQ: Bit Field Extract. +// +// Forms: +// +// BEXTRQ r64 r64 r64 +// BEXTRQ r64 m64 r64 +func BEXTRQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BEXTRQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BEXTRQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("BEXTRQ: bad operands") +} + +// BLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDPD imm8 xmm xmm +// BLENDPD imm8 m128 xmm +func BLENDPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("BLENDPD: bad operands") +} + +// BLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDPS imm8 xmm xmm +// BLENDPS imm8 m128 xmm +func BLENDPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "BLENDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("BLENDPS: bad operands") +} + +// BLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPD xmm0 xmm xmm +// BLENDVPD xmm0 m128 xmm +func BLENDVPD(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPD", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPD", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("BLENDVPD: bad operands") +} + +// BLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// BLENDVPS xmm0 xmm xmm +// BLENDVPS xmm0 m128 xmm +func BLENDVPS(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPS", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "BLENDVPS", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("BLENDVPS: bad operands") +} + +// BLSIL: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIL r32 r32 +// BLSIL m32 r32 +func BLSIL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSIL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSIL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSIL: bad operands") +} + +// BLSIQ: Isolate Lowest Set Bit. +// +// Forms: +// +// BLSIQ r64 r64 +// BLSIQ m64 r64 +func BLSIQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSIQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSIQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSIQ: bad operands") +} + +// BLSMSKL: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKL r32 r32 +// BLSMSKL m32 r32 +func BLSMSKL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSMSKL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSMSKL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSMSKL: bad operands") +} + +// BLSMSKQ: Mask From Lowest Set Bit. +// +// Forms: +// +// BLSMSKQ r64 r64 +// BLSMSKQ m64 r64 +func BLSMSKQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSMSKQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSMSKQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSMSKQ: bad operands") +} + +// BLSRL: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRL r32 r32 +// BLSRL m32 r32 +func BLSRL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BLSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSRL: bad operands") +} + +// BLSRQ: Reset Lowest Set Bit. +// +// Forms: +// +// BLSRQ r64 r64 +// BLSRQ m64 r64 +func BLSRQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BLSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BLSRQ: bad operands") +} + +// BSFL: Bit Scan Forward. +// +// Forms: +// +// BSFL r32 r32 +// BSFL m32 r32 +func BSFL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSFL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSFL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFL: bad operands") +} + +// BSFQ: Bit Scan Forward. +// +// Forms: +// +// BSFQ r64 r64 +// BSFQ m64 r64 +func BSFQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSFQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSFQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFQ: bad operands") +} + +// BSFW: Bit Scan Forward. +// +// Forms: +// +// BSFW r16 r16 +// BSFW m16 r16 +func BSFW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSFW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSFW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSFW: bad operands") +} + +// BSRL: Bit Scan Reverse. +// +// Forms: +// +// BSRL r32 r32 +// BSRL m32 r32 +func BSRL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSRL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRL: bad operands") +} + +// BSRQ: Bit Scan Reverse. +// +// Forms: +// +// BSRQ r64 r64 +// BSRQ m64 r64 +func BSRQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSRQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRQ: bad operands") +} + +// BSRW: Bit Scan Reverse. +// +// Forms: +// +// BSRW r16 r16 +// BSRW m16 r16 +func BSRW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSRW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "BSRW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSRW: bad operands") +} + +// BSWAPL: Byte Swap. +// +// Forms: +// +// BSWAPL r32 +func BSWAPL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "BSWAPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSWAPL: bad operands") +} + +// BSWAPQ: Byte Swap. +// +// Forms: +// +// BSWAPQ r64 +func BSWAPQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "BSWAPQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("BSWAPQ: bad operands") +} + +// BTCL: Bit Test and Complement. +// +// Forms: +// +// BTCL imm8 r32 +// BTCL r32 r32 +// BTCL imm8 m32 +// BTCL r32 m32 +func BTCL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTCL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCL: bad operands") +} + +// BTCQ: Bit Test and Complement. +// +// Forms: +// +// BTCQ imm8 r64 +// BTCQ r64 r64 +// BTCQ imm8 m64 +// BTCQ r64 m64 +func BTCQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTCQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCQ: bad operands") +} + +// BTCW: Bit Test and Complement. +// +// Forms: +// +// BTCW imm8 r16 +// BTCW r16 r16 +// BTCW imm8 m16 +// BTCW r16 m16 +func BTCW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTCW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTCW: bad operands") +} + +// BTL: Bit Test. +// +// Forms: +// +// BTL imm8 r32 +// BTL r32 r32 +// BTL imm8 m32 +// BTL r32 m32 +func BTL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTL: bad operands") +} + +// BTQ: Bit Test. +// +// Forms: +// +// BTQ imm8 r64 +// BTQ r64 r64 +// BTQ imm8 m64 +// BTQ r64 m64 +func BTQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTQ: bad operands") +} + +// BTRL: Bit Test and Reset. +// +// Forms: +// +// BTRL imm8 r32 +// BTRL r32 r32 +// BTRL imm8 m32 +// BTRL r32 m32 +func BTRL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTRL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRL: bad operands") +} + +// BTRQ: Bit Test and Reset. +// +// Forms: +// +// BTRQ imm8 r64 +// BTRQ r64 r64 +// BTRQ imm8 m64 +// BTRQ r64 m64 +func BTRQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTRQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRQ: bad operands") +} + +// BTRW: Bit Test and Reset. +// +// Forms: +// +// BTRW imm8 r16 +// BTRW r16 r16 +// BTRW imm8 m16 +// BTRW r16 m16 +func BTRW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTRW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTRW: bad operands") +} + +// BTSL: Bit Test and Set. +// +// Forms: +// +// BTSL imm8 r32 +// BTSL r32 r32 +// BTSL imm8 m32 +// BTSL r32 m32 +func BTSL(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(ir) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "BTSL", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSL: bad operands") +} + +// BTSQ: Bit Test and Set. +// +// Forms: +// +// BTSQ imm8 r64 +// BTSQ r64 r64 +// BTSQ imm8 m64 +// BTSQ r64 m64 +func BTSQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "BTSQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSQ: bad operands") +} + +// BTSW: Bit Test and Set. +// +// Forms: +// +// BTSW imm8 r16 +// BTSW r16 r16 +// BTSW imm8 m16 +// BTSW r16 m16 +func BTSW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTSW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("BTSW: bad operands") +} + +// BTW: Bit Test. +// +// Forms: +// +// BTW imm8 r16 +// BTW r16 r16 +// BTW imm8 m16 +// BTW r16 m16 +func BTW(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "BTW", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("BTW: bad operands") +} + +// BZHIL: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIL r32 r32 r32 +// BZHIL r32 m32 r32 +func BZHIL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BZHIL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "BZHIL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("BZHIL: bad operands") +} + +// BZHIQ: Zero High Bits Starting with Specified Bit Position. +// +// Forms: +// +// BZHIQ r64 r64 r64 +// BZHIQ r64 m64 r64 +func BZHIQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BZHIQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "BZHIQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("BZHIQ: bad operands") +} + +// CALL: Call Procedure. +// +// Forms: +// +// CALL rel32 +func CALL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "CALL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CALL: bad operands") +} + +// CBW: Convert Byte to Word. +// +// Forms: +// +// CBW +func CBW() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CBW", + Operands: nil, + Inputs: []operand.Op{reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil +} + +// CDQ: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQ +func CDQ() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CDQ", + Operands: nil, + Inputs: []operand.Op{reg.EAX}, + Outputs: []operand.Op{reg.EDX}, + }, nil +} + +// CDQE: Convert Doubleword to Quadword. +// +// Forms: +// +// CDQE +func CDQE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CDQE", + Operands: nil, + Inputs: []operand.Op{reg.EAX}, + Outputs: []operand.Op{reg.RAX}, + }, nil +} + +// CLC: Clear Carry Flag. +// +// Forms: +// +// CLC +func CLC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CLC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CLD: Clear Direction Flag. +// +// Forms: +// +// CLD +func CLD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CLD", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CLFLUSH: Flush Cache Line. +// +// Forms: +// +// CLFLUSH m8 +func CLFLUSH(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "CLFLUSH", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CLFLUSH: bad operands") +} + +// CLFLUSHOPT: Flush Cache Line Optimized. +// +// Forms: +// +// CLFLUSHOPT m8 +func CLFLUSHOPT(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "CLFLUSHOPT", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CLFLUSHOPT: bad operands") +} + +// CMC: Complement Carry Flag. +// +// Forms: +// +// CMC +func CMC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CMC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// CMOVLCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVLCC r32 r32 +// CMOVLCC m32 r32 +func CMOVLCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLCC: bad operands") +} + +// CMOVLCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVLCS r32 r32 +// CMOVLCS m32 r32 +func CMOVLCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLCS: bad operands") +} + +// CMOVLEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVLEQ r32 r32 +// CMOVLEQ m32 r32 +func CMOVLEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLEQ: bad operands") +} + +// CMOVLGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVLGE r32 r32 +// CMOVLGE m32 r32 +func CMOVLGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLGE: bad operands") +} + +// CMOVLGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVLGT r32 r32 +// CMOVLGT m32 r32 +func CMOVLGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLGT: bad operands") +} + +// CMOVLHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVLHI r32 r32 +// CMOVLHI m32 r32 +func CMOVLHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLHI: bad operands") +} + +// CMOVLLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVLLE r32 r32 +// CMOVLLE m32 r32 +func CMOVLLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLLE: bad operands") +} + +// CMOVLLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVLLS r32 r32 +// CMOVLLS m32 r32 +func CMOVLLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLLS: bad operands") +} + +// CMOVLLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVLLT r32 r32 +// CMOVLLT m32 r32 +func CMOVLLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLLT: bad operands") +} + +// CMOVLMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVLMI r32 r32 +// CMOVLMI m32 r32 +func CMOVLMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLMI: bad operands") +} + +// CMOVLNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVLNE r32 r32 +// CMOVLNE m32 r32 +func CMOVLNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLNE: bad operands") +} + +// CMOVLOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVLOC r32 r32 +// CMOVLOC m32 r32 +func CMOVLOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLOC: bad operands") +} + +// CMOVLOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVLOS r32 r32 +// CMOVLOS m32 r32 +func CMOVLOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLOS: bad operands") +} + +// CMOVLPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVLPC r32 r32 +// CMOVLPC m32 r32 +func CMOVLPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLPC: bad operands") +} + +// CMOVLPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVLPL r32 r32 +// CMOVLPL m32 r32 +func CMOVLPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLPL: bad operands") +} + +// CMOVLPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVLPS r32 r32 +// CMOVLPS m32 r32 +func CMOVLPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CMOVLPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVLPS: bad operands") +} + +// CMOVQCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVQCC r64 r64 +// CMOVQCC m64 r64 +func CMOVQCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQCC: bad operands") +} + +// CMOVQCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVQCS r64 r64 +// CMOVQCS m64 r64 +func CMOVQCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQCS: bad operands") +} + +// CMOVQEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVQEQ r64 r64 +// CMOVQEQ m64 r64 +func CMOVQEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQEQ: bad operands") +} + +// CMOVQGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVQGE r64 r64 +// CMOVQGE m64 r64 +func CMOVQGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQGE: bad operands") +} + +// CMOVQGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVQGT r64 r64 +// CMOVQGT m64 r64 +func CMOVQGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQGT: bad operands") +} + +// CMOVQHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVQHI r64 r64 +// CMOVQHI m64 r64 +func CMOVQHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQHI: bad operands") +} + +// CMOVQLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVQLE r64 r64 +// CMOVQLE m64 r64 +func CMOVQLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQLE: bad operands") +} + +// CMOVQLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVQLS r64 r64 +// CMOVQLS m64 r64 +func CMOVQLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQLS: bad operands") +} + +// CMOVQLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVQLT r64 r64 +// CMOVQLT m64 r64 +func CMOVQLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQLT: bad operands") +} + +// CMOVQMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVQMI r64 r64 +// CMOVQMI m64 r64 +func CMOVQMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQMI: bad operands") +} + +// CMOVQNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVQNE r64 r64 +// CMOVQNE m64 r64 +func CMOVQNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQNE: bad operands") +} + +// CMOVQOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVQOC r64 r64 +// CMOVQOC m64 r64 +func CMOVQOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQOC: bad operands") +} + +// CMOVQOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVQOS r64 r64 +// CMOVQOS m64 r64 +func CMOVQOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQOS: bad operands") +} + +// CMOVQPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVQPC r64 r64 +// CMOVQPC m64 r64 +func CMOVQPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQPC: bad operands") +} + +// CMOVQPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVQPL r64 r64 +// CMOVQPL m64 r64 +func CMOVQPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQPL: bad operands") +} + +// CMOVQPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVQPS r64 r64 +// CMOVQPS m64 r64 +func CMOVQPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CMOVQPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVQPS: bad operands") +} + +// CMOVWCC: Move if above or equal (CF == 0). +// +// Forms: +// +// CMOVWCC r16 r16 +// CMOVWCC m16 r16 +func CMOVWCC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWCC: bad operands") +} + +// CMOVWCS: Move if below (CF == 1). +// +// Forms: +// +// CMOVWCS r16 r16 +// CMOVWCS m16 r16 +func CMOVWCS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWCS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWCS: bad operands") +} + +// CMOVWEQ: Move if equal (ZF == 1). +// +// Forms: +// +// CMOVWEQ r16 r16 +// CMOVWEQ m16 r16 +func CMOVWEQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWEQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWEQ: bad operands") +} + +// CMOVWGE: Move if greater or equal (SF == OF). +// +// Forms: +// +// CMOVWGE r16 r16 +// CMOVWGE m16 r16 +func CMOVWGE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWGE: bad operands") +} + +// CMOVWGT: Move if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// CMOVWGT r16 r16 +// CMOVWGT m16 r16 +func CMOVWGT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWGT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWGT: bad operands") +} + +// CMOVWHI: Move if above (CF == 0 and ZF == 0). +// +// Forms: +// +// CMOVWHI r16 r16 +// CMOVWHI m16 r16 +func CMOVWHI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWHI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWHI: bad operands") +} + +// CMOVWLE: Move if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// CMOVWLE r16 r16 +// CMOVWLE m16 r16 +func CMOVWLE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWLE: bad operands") +} + +// CMOVWLS: Move if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// CMOVWLS r16 r16 +// CMOVWLS m16 r16 +func CMOVWLS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWLS: bad operands") +} + +// CMOVWLT: Move if less (SF != OF). +// +// Forms: +// +// CMOVWLT r16 r16 +// CMOVWLT m16 r16 +func CMOVWLT(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWLT", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWLT: bad operands") +} + +// CMOVWMI: Move if sign (SF == 1). +// +// Forms: +// +// CMOVWMI r16 r16 +// CMOVWMI m16 r16 +func CMOVWMI(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWMI", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWMI: bad operands") +} + +// CMOVWNE: Move if not equal (ZF == 0). +// +// Forms: +// +// CMOVWNE r16 r16 +// CMOVWNE m16 r16 +func CMOVWNE(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWNE", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWNE: bad operands") +} + +// CMOVWOC: Move if not overflow (OF == 0). +// +// Forms: +// +// CMOVWOC r16 r16 +// CMOVWOC m16 r16 +func CMOVWOC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWOC: bad operands") +} + +// CMOVWOS: Move if overflow (OF == 1). +// +// Forms: +// +// CMOVWOS r16 r16 +// CMOVWOS m16 r16 +func CMOVWOS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWOS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWOS: bad operands") +} + +// CMOVWPC: Move if not parity (PF == 0). +// +// Forms: +// +// CMOVWPC r16 r16 +// CMOVWPC m16 r16 +func CMOVWPC(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPC", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWPC: bad operands") +} + +// CMOVWPL: Move if not sign (SF == 0). +// +// Forms: +// +// CMOVWPL r16 r16 +// CMOVWPL m16 r16 +func CMOVWPL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWPL: bad operands") +} + +// CMOVWPS: Move if parity (PF == 1). +// +// Forms: +// +// CMOVWPS r16 r16 +// CMOVWPS m16 r16 +func CMOVWPS(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "CMOVWPS", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CMOVWPS: bad operands") +} + +// CMPB: Compare Two Operands. +// +// Forms: +// +// CMPB al imm8 +// CMPB r8 imm8 +// CMPB r8 r8 +// CMPB r8 m8 +// CMPB m8 imm8 +// CMPB m8 r8 +func CMPB(amr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsAL(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(amr) && operand.IsR8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(amr) && operand.IsM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM8(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM8(amr) && operand.IsR8(imr): + return &intrep.Instruction{ + Opcode: "CMPB", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPB: bad operands") +} + +// CMPL: Compare Two Operands. +// +// Forms: +// +// CMPL eax imm32 +// CMPL r32 imm8 +// CMPL r32 imm32 +// CMPL r32 r32 +// CMPL r32 m32 +// CMPL m32 imm8 +// CMPL m32 imm32 +// CMPL m32 r32 +func CMPL(emr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsEAX(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsR32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(emr) && operand.IsM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(emr) && operand.IsR32(imr): + return &intrep.Instruction{ + Opcode: "CMPL", + Operands: []operand.Op{emr, imr}, + Inputs: []operand.Op{emr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPL: bad operands") +} + +// CMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPPD xmm xmm imm8 +// CMPPD m128 xmm imm8 +func CMPPD(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CMPPD: bad operands") +} + +// CMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPPS xmm xmm imm8 +// CMPPS m128 xmm imm8 +func CMPPS(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPPS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CMPPS: bad operands") +} + +// CMPQ: Compare Two Operands. +// +// Forms: +// +// CMPQ rax imm32 +// CMPQ r64 imm8 +// CMPQ r64 imm32 +// CMPQ r64 r64 +// CMPQ r64 m64 +// CMPQ m64 imm8 +// CMPQ m64 imm32 +// CMPQ m64 r64 +func CMPQ(mr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsRAX(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(mr) && operand.IsM64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mr) && operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "CMPQ", + Operands: []operand.Op{mr, imr}, + Inputs: []operand.Op{mr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPQ: bad operands") +} + +// CMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// CMPSD xmm xmm imm8 +// CMPSD m64 xmm imm8 +func CMPSD(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSD", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CMPSD: bad operands") +} + +// CMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// CMPSS xmm xmm imm8 +// CMPSS m32 xmm imm8 +func CMPSS(mx, x, i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "CMPSS", + Operands: []operand.Op{mx, x, i}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CMPSS: bad operands") +} + +// CMPW: Compare Two Operands. +// +// Forms: +// +// CMPW ax imm16 +// CMPW r16 imm8 +// CMPW r16 imm16 +// CMPW r16 r16 +// CMPW r16 m16 +// CMPW m16 imm8 +// CMPW m16 imm16 +// CMPW m16 r16 +func CMPW(amr, imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsAX(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsR16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(amr) && operand.IsM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsIMM16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(amr) && operand.IsR16(imr): + return &intrep.Instruction{ + Opcode: "CMPW", + Operands: []operand.Op{amr, imr}, + Inputs: []operand.Op{amr, imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("CMPW: bad operands") +} + +// CMPXCHG16B: Compare and Exchange 16 Bytes. +// +// Forms: +// +// CMPXCHG16B m128 +func CMPXCHG16B(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "CMPXCHG16B", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m, reg.RAX, reg.RBX, reg.RCX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("CMPXCHG16B: bad operands") +} + +// CMPXCHG8B: Compare and Exchange 8 Bytes. +// +// Forms: +// +// CMPXCHG8B m64 +func CMPXCHG8B(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(m): + return &intrep.Instruction{ + Opcode: "CMPXCHG8B", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m, reg.EAX, reg.EBX, reg.ECX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("CMPXCHG8B: bad operands") +} + +// CMPXCHGB: Compare and Exchange. +// +// Forms: +// +// CMPXCHGB r8 r8 +// CMPXCHGB r8 m8 +func CMPXCHGB(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(r) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(r) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGB: bad operands") +} + +// CMPXCHGL: Compare and Exchange. +// +// Forms: +// +// CMPXCHGL r32 r32 +// CMPXCHGL r32 m32 +func CMPXCHGL(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGL: bad operands") +} + +// CMPXCHGQ: Compare and Exchange. +// +// Forms: +// +// CMPXCHGQ r64 r64 +// CMPXCHGQ r64 m64 +func CMPXCHGQ(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGQ: bad operands") +} + +// CMPXCHGW: Compare and Exchange. +// +// Forms: +// +// CMPXCHGW r16 r16 +// CMPXCHGW r16 m16 +func CMPXCHGW(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(r) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "CMPXCHGW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("CMPXCHGW: bad operands") +} + +// COMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISD xmm xmm +// COMISD m64 xmm +func COMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("COMISD: bad operands") +} + +// COMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// COMISS xmm xmm +// COMISS m32 xmm +func COMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "COMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("COMISS: bad operands") +} + +// CPUID: CPU Identification. +// +// Forms: +// +// CPUID +func CPUID() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CPUID", + Operands: nil, + Inputs: []operand.Op{reg.EAX, reg.ECX}, + Outputs: []operand.Op{reg.EAX, reg.EBX, reg.ECX, reg.EDX}, + }, nil +} + +// CQO: Convert Quadword to Octaword. +// +// Forms: +// +// CQO +func CQO() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CQO", + Operands: nil, + Inputs: []operand.Op{reg.RAX}, + Outputs: []operand.Op{reg.RDX}, + }, nil +} + +// CRC32B: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32B r8 r32 +// CRC32B m8 r32 +// CRC32B r8 r64 +// CRC32B m8 r64 +func CRC32B(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32B", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CRC32B: bad operands") +} + +// CRC32L: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32L r32 r32 +// CRC32L m32 r32 +func CRC32L(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32L", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32L", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CRC32L: bad operands") +} + +// CRC32Q: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32Q r64 r64 +// CRC32Q m64 r64 +func CRC32Q(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32Q", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CRC32Q", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CRC32Q: bad operands") +} + +// CRC32W: Accumulate CRC32 Value. +// +// Forms: +// +// CRC32W r16 r32 +// CRC32W m16 r32 +func CRC32W(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32W", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CRC32W", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CRC32W: bad operands") +} + +// CVTPD2PL: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPD2PL xmm xmm +// CVTPD2PL m128 xmm +func CVTPD2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPD2PL: bad operands") +} + +// CVTPD2PS: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPD2PS xmm xmm +// CVTPD2PS m128 xmm +func CVTPD2PS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPD2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPD2PS: bad operands") +} + +// CVTPL2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPL2PD xmm xmm +// CVTPL2PD m64 xmm +func CVTPL2PD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPL2PD: bad operands") +} + +// CVTPL2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// CVTPL2PS xmm xmm +// CVTPL2PS m128 xmm +func CVTPL2PS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPL2PS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPL2PS: bad operands") +} + +// CVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// CVTPS2PD xmm xmm +// CVTPS2PD m64 xmm +func CVTPS2PD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPS2PD: bad operands") +} + +// CVTPS2PL: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTPS2PL xmm xmm +// CVTPS2PL m128 xmm +func CVTPS2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTPS2PL: bad operands") +} + +// CVTSD2SL: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// CVTSD2SL xmm r32 +// CVTSD2SL m64 r32 +// CVTSD2SL xmm r64 +// CVTSD2SL m64 r64 +func CVTSD2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CVTSD2SL: bad operands") +} + +// CVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSD2SS xmm xmm +// CVTSD2SS m64 xmm +func CVTSD2SS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSD2SS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSD2SS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSD2SS: bad operands") +} + +// CVTSL2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSL2SD r32 xmm +// CVTSL2SD m32 xmm +func CVTSL2SD(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSL2SD: bad operands") +} + +// CVTSL2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSL2SS r32 xmm +// CVTSL2SS m32 xmm +func CVTSL2SS(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSL2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSL2SS: bad operands") +} + +// CVTSQ2SD: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSQ2SD r64 xmm +// CVTSQ2SD m64 xmm +func CVTSQ2SD(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SD", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSQ2SD: bad operands") +} + +// CVTSQ2SS: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// CVTSQ2SS r64 xmm +// CVTSQ2SS m64 xmm +func CVTSQ2SS(mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSQ2SS", + Operands: []operand.Op{mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSQ2SS: bad operands") +} + +// CVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// CVTSS2SD xmm xmm +// CVTSS2SD m32 xmm +func CVTSS2SD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSS2SD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTSS2SD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTSS2SD: bad operands") +} + +// CVTSS2SL: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTSS2SL xmm r32 +// CVTSS2SL m32 r32 +// CVTSS2SL xmm r64 +// CVTSS2SL m32 r64 +func CVTSS2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CVTSS2SL: bad operands") +} + +// CVTTPD2PL: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPD2PL xmm xmm +// CVTTPD2PL m128 xmm +func CVTTPD2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPD2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTTPD2PL: bad operands") +} + +// CVTTPS2PL: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// CVTTPS2PL xmm xmm +// CVTTPS2PL m128 xmm +func CVTTPS2PL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "CVTTPS2PL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("CVTTPS2PL: bad operands") +} + +// CVTTSD2SL: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SL xmm r32 +// CVTTSD2SL m64 r32 +func CVTTSD2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CVTTSD2SL: bad operands") +} + +// CVTTSD2SQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// CVTTSD2SQ xmm r64 +// CVTTSD2SQ m64 r64 +func CVTTSD2SQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSD2SQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CVTTSD2SQ: bad operands") +} + +// CVTTSS2SL: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// CVTTSS2SL xmm r32 +// CVTTSS2SL m32 r32 +// CVTTSS2SL xmm r64 +// CVTTSS2SL m32 r64 +func CVTTSS2SL(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "CVTTSS2SL", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("CVTTSS2SL: bad operands") +} + +// CWD: Convert Word to Doubleword. +// +// Forms: +// +// CWD +func CWD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CWD", + Operands: nil, + Inputs: []operand.Op{reg.AX}, + Outputs: []operand.Op{reg.DX}, + }, nil +} + +// CWDE: Convert Word to Doubleword. +// +// Forms: +// +// CWDE +func CWDE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "CWDE", + Operands: nil, + Inputs: []operand.Op{reg.AX}, + Outputs: []operand.Op{reg.EAX}, + }, nil +} + +// DECB: Decrement by 1. +// +// Forms: +// +// DECB r8 +// DECB m8 +func DECB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "DECB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "DECB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECB: bad operands") +} + +// DECL: Decrement by 1. +// +// Forms: +// +// DECL r32 +// DECL m32 +func DECL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "DECL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "DECL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECL: bad operands") +} + +// DECQ: Decrement by 1. +// +// Forms: +// +// DECQ r64 +// DECQ m64 +func DECQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "DECQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "DECQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECQ: bad operands") +} + +// DECW: Decrement by 1. +// +// Forms: +// +// DECW r16 +// DECW m16 +func DECW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "DECW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "DECW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("DECW: bad operands") +} + +// DIVB: Unsigned Divide. +// +// Forms: +// +// DIVB r8 +// DIVB m8 +func DIVB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "DIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "DIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("DIVB: bad operands") +} + +// DIVL: Unsigned Divide. +// +// Forms: +// +// DIVL r32 +// DIVL m32 +func DIVL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "DIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "DIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("DIVL: bad operands") +} + +// DIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVPD xmm xmm +// DIVPD m128 xmm +func DIVPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DIVPD: bad operands") +} + +// DIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVPS xmm xmm +// DIVPS m128 xmm +func DIVPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DIVPS: bad operands") +} + +// DIVQ: Unsigned Divide. +// +// Forms: +// +// DIVQ r64 +// DIVQ m64 +func DIVQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "DIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "DIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("DIVQ: bad operands") +} + +// DIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// DIVSD xmm xmm +// DIVSD m64 xmm +func DIVSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DIVSD: bad operands") +} + +// DIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// DIVSS xmm xmm +// DIVSS m32 xmm +func DIVSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DIVSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DIVSS: bad operands") +} + +// DIVW: Unsigned Divide. +// +// Forms: +// +// DIVW r16 +// DIVW m16 +func DIVW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "DIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "DIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("DIVW: bad operands") +} + +// DPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// DPPD imm8 xmm xmm +// DPPD imm8 m128 xmm +func DPPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DPPD: bad operands") +} + +// DPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// DPPS imm8 xmm xmm +// DPPS imm8 m128 xmm +func DPPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "DPPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("DPPS: bad operands") +} + +// EXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// EXTRACTPS imm2u xmm r32 +// EXTRACTPS imm2u xmm m32 +func EXTRACTPS(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM2U(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "EXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM2U(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "EXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("EXTRACTPS: bad operands") +} + +// HADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// HADDPD xmm xmm +// HADDPD m128 xmm +func HADDPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("HADDPD: bad operands") +} + +// HADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// HADDPS xmm xmm +// HADDPS m128 xmm +func HADDPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HADDPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("HADDPS: bad operands") +} + +// HSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPD xmm xmm +// HSUBPD m128 xmm +func HSUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("HSUBPD: bad operands") +} + +// HSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// HSUBPS xmm xmm +// HSUBPS m128 xmm +func HSUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "HSUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("HSUBPS: bad operands") +} + +// IDIVB: Signed Divide. +// +// Forms: +// +// IDIVB r8 +// IDIVB m8 +func IDIVB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "IDIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "IDIVB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("IDIVB: bad operands") +} + +// IDIVL: Signed Divide. +// +// Forms: +// +// IDIVL r32 +// IDIVL m32 +func IDIVL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "IDIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "IDIVL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("IDIVL: bad operands") +} + +// IDIVQ: Signed Divide. +// +// Forms: +// +// IDIVQ r64 +// IDIVQ m64 +func IDIVQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "IDIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "IDIVQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX, reg.RDX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("IDIVQ: bad operands") +} + +// IDIVW: Signed Divide. +// +// Forms: +// +// IDIVW r16 +// IDIVW m16 +func IDIVW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "IDIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "IDIVW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX, reg.DX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("IDIVW: bad operands") +} + +// IMUL3L: Signed Multiply. +// +// Forms: +// +// IMUL3L imm8 r32 r32 +// IMUL3L imm32 r32 r32 +// IMUL3L imm8 m32 r32 +// IMUL3L imm32 m32 r32 +func IMUL3L(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "IMUL3L", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3L: bad operands") +} + +// IMUL3Q: Signed Multiply. +// +// Forms: +// +// IMUL3Q imm8 r64 r64 +// IMUL3Q imm32 r64 r64 +// IMUL3Q imm8 m64 r64 +// IMUL3Q imm32 m64 r64 +func IMUL3Q(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM32(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "IMUL3Q", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3Q: bad operands") +} + +// IMUL3W: Signed Multiply. +// +// Forms: +// +// IMUL3W imm8 r16 r16 +// IMUL3W imm16 r16 r16 +// IMUL3W imm8 m16 r16 +// IMUL3W imm16 m16 r16 +func IMUL3W(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM16(i) && operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM16(i) && operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "IMUL3W", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("IMUL3W: bad operands") +} + +// IMULB: Signed Multiply. +// +// Forms: +// +// IMULB r8 +// IMULB m8 +func IMULB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "IMULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "IMULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("IMULB: bad operands") +} + +// IMULL: Signed Multiply. +// +// Forms: +// +// IMULL r32 +// IMULL m32 +// IMULL r32 r32 +// IMULL m32 r32 +func IMULL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR32(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case len(ops) == 1 && operand.IsM32(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case len(ops) == 2 && operand.IsR32(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM32(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULL: bad operands") +} + +// IMULQ: Signed Multiply. +// +// Forms: +// +// IMULQ r64 +// IMULQ m64 +// IMULQ r64 r64 +// IMULQ m64 r64 +func IMULQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR64(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case len(ops) == 1 && operand.IsM64(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case len(ops) == 2 && operand.IsR64(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM64(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULQ: bad operands") +} + +// IMULW: Signed Multiply. +// +// Forms: +// +// IMULW r16 +// IMULW m16 +// IMULW r16 r16 +// IMULW m16 r16 +func IMULW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 1 && operand.IsR16(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case len(ops) == 1 && operand.IsM16(ops[0]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case len(ops) == 2 && operand.IsR16(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsM16(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "IMULW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + } + return nil, errors.New("IMULW: bad operands") +} + +// INCB: Increment by 1. +// +// Forms: +// +// INCB r8 +// INCB m8 +func INCB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "INCB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "INCB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCB: bad operands") +} + +// INCL: Increment by 1. +// +// Forms: +// +// INCL r32 +// INCL m32 +func INCL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "INCL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "INCL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCL: bad operands") +} + +// INCQ: Increment by 1. +// +// Forms: +// +// INCQ r64 +// INCQ m64 +func INCQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "INCQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "INCQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCQ: bad operands") +} + +// INCW: Increment by 1. +// +// Forms: +// +// INCW r16 +// INCW m16 +func INCW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "INCW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "INCW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("INCW: bad operands") +} + +// INSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// INSERTPS imm8 xmm xmm +// INSERTPS imm8 m32 xmm +func INSERTPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "INSERTPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "INSERTPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("INSERTPS: bad operands") +} + +// INT: Call to Interrupt Procedure. +// +// Forms: +// +// INT 3 +// INT imm8 +func INT(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is3(i): + return &intrep.Instruction{ + Opcode: "INT", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(i): + return &intrep.Instruction{ + Opcode: "INT", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("INT: bad operands") +} + +// JA: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JA rel8 +// JA rel32 +func JA(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JA: bad operands") +} + +// JAE: Jump if above or equal (CF == 0). +// +// Forms: +// +// JAE rel8 +// JAE rel32 +func JAE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JAE: bad operands") +} + +// JB: Jump if below (CF == 1). +// +// Forms: +// +// JB rel8 +// JB rel32 +func JB(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JB: bad operands") +} + +// JBE: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JBE rel8 +// JBE rel32 +func JBE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JBE: bad operands") +} + +// JC: Jump if below (CF == 1). +// +// Forms: +// +// JC rel8 +// JC rel32 +func JC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JC: bad operands") +} + +// JCC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JCC rel8 +// JCC rel32 +func JCC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JCC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCC: bad operands") +} + +// JCS: Jump if below (CF == 1). +// +// Forms: +// +// JCS rel8 +// JCS rel32 +func JCS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JCS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCS: bad operands") +} + +// JCXZL: Jump if ECX register is 0. +// +// Forms: +// +// JCXZL rel8 +func JCXZL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCXZL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{reg.ECX}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCXZL: bad operands") +} + +// JCXZQ: Jump if RCX register is 0. +// +// Forms: +// +// JCXZQ rel8 +func JCXZQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JCXZQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{reg.RCX}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JCXZQ: bad operands") +} + +// JE: Jump if equal (ZF == 1). +// +// Forms: +// +// JE rel8 +// JE rel32 +func JE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JE: bad operands") +} + +// JEQ: Jump if equal (ZF == 1). +// +// Forms: +// +// JEQ rel8 +// JEQ rel32 +func JEQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JEQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JEQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JEQ: bad operands") +} + +// JG: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JG rel8 +// JG rel32 +func JG(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JG: bad operands") +} + +// JGE: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JGE rel8 +// JGE rel32 +func JGE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JGE: bad operands") +} + +// JGT: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JGT rel8 +// JGT rel32 +func JGT(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JGT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JGT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JGT: bad operands") +} + +// JHI: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JHI rel8 +// JHI rel32 +func JHI(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JHI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JHI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JHI: bad operands") +} + +// JHS: Jump if above or equal (CF == 0). +// +// Forms: +// +// JHS rel8 +// JHS rel32 +func JHS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JHS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JHS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JHS: bad operands") +} + +// JL: Jump if less (SF != OF). +// +// Forms: +// +// JL rel8 +// JL rel32 +func JL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JL: bad operands") +} + +// JLE: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JLE rel8 +// JLE rel32 +func JLE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLE: bad operands") +} + +// JLO: Jump if below (CF == 1). +// +// Forms: +// +// JLO rel8 +// JLO rel32 +func JLO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLO: bad operands") +} + +// JLS: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JLS rel8 +// JLS rel32 +func JLS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLS: bad operands") +} + +// JLT: Jump if less (SF != OF). +// +// Forms: +// +// JLT rel8 +// JLT rel32 +func JLT(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JLT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JLT", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JLT: bad operands") +} + +// JMI: Jump if sign (SF == 1). +// +// Forms: +// +// JMI rel8 +// JMI rel32 +func JMI(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JMI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JMI", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JMI: bad operands") +} + +// JMP: Jump Unconditionally. +// +// Forms: +// +// JMP rel8 +// JMP rel32 +// JMP r64 +// JMP m64 +func JMP(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsREL32(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "JMP", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: false, + }, nil + } + return nil, errors.New("JMP: bad operands") +} + +// JNA: Jump if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// JNA rel8 +// JNA rel32 +func JNA(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNA", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNA: bad operands") +} + +// JNAE: Jump if below (CF == 1). +// +// Forms: +// +// JNAE rel8 +// JNAE rel32 +func JNAE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNAE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNAE: bad operands") +} + +// JNB: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNB rel8 +// JNB rel32 +func JNB(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNB", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNB: bad operands") +} + +// JNBE: Jump if above (CF == 0 and ZF == 0). +// +// Forms: +// +// JNBE rel8 +// JNBE rel32 +func JNBE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNBE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNBE: bad operands") +} + +// JNC: Jump if above or equal (CF == 0). +// +// Forms: +// +// JNC rel8 +// JNC rel32 +func JNC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNC: bad operands") +} + +// JNE: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNE rel8 +// JNE rel32 +func JNE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNE: bad operands") +} + +// JNG: Jump if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// JNG rel8 +// JNG rel32 +func JNG(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNG", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNG: bad operands") +} + +// JNGE: Jump if less (SF != OF). +// +// Forms: +// +// JNGE rel8 +// JNGE rel32 +func JNGE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNGE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNGE: bad operands") +} + +// JNL: Jump if greater or equal (SF == OF). +// +// Forms: +// +// JNL rel8 +// JNL rel32 +func JNL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNL: bad operands") +} + +// JNLE: Jump if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// JNLE rel8 +// JNLE rel32 +func JNLE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNLE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNLE: bad operands") +} + +// JNO: Jump if not overflow (OF == 0). +// +// Forms: +// +// JNO rel8 +// JNO rel32 +func JNO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNO: bad operands") +} + +// JNP: Jump if not parity (PF == 0). +// +// Forms: +// +// JNP rel8 +// JNP rel32 +func JNP(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNP: bad operands") +} + +// JNS: Jump if not sign (SF == 0). +// +// Forms: +// +// JNS rel8 +// JNS rel32 +func JNS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNS: bad operands") +} + +// JNZ: Jump if not equal (ZF == 0). +// +// Forms: +// +// JNZ rel8 +// JNZ rel32 +func JNZ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JNZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JNZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JNZ: bad operands") +} + +// JO: Jump if overflow (OF == 1). +// +// Forms: +// +// JO rel8 +// JO rel32 +func JO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JO: bad operands") +} + +// JOC: Jump if not overflow (OF == 0). +// +// Forms: +// +// JOC rel8 +// JOC rel32 +func JOC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JOC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JOC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JOC: bad operands") +} + +// JOS: Jump if overflow (OF == 1). +// +// Forms: +// +// JOS rel8 +// JOS rel32 +func JOS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JOS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JOS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JOS: bad operands") +} + +// JP: Jump if parity (PF == 1). +// +// Forms: +// +// JP rel8 +// JP rel32 +func JP(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JP", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JP: bad operands") +} + +// JPC: Jump if not parity (PF == 0). +// +// Forms: +// +// JPC rel8 +// JPC rel32 +func JPC(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPC", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPC: bad operands") +} + +// JPE: Jump if parity (PF == 1). +// +// Forms: +// +// JPE rel8 +// JPE rel32 +func JPE(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPE", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPE: bad operands") +} + +// JPL: Jump if not sign (SF == 0). +// +// Forms: +// +// JPL rel8 +// JPL rel32 +func JPL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPL: bad operands") +} + +// JPO: Jump if not parity (PF == 0). +// +// Forms: +// +// JPO rel8 +// JPO rel32 +func JPO(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPO", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPO: bad operands") +} + +// JPS: Jump if parity (PF == 1). +// +// Forms: +// +// JPS rel8 +// JPS rel32 +func JPS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JPS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JPS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JPS: bad operands") +} + +// JS: Jump if sign (SF == 1). +// +// Forms: +// +// JS rel8 +// JS rel32 +func JS(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JS", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JS: bad operands") +} + +// JZ: Jump if equal (ZF == 1). +// +// Forms: +// +// JZ rel8 +// JZ rel32 +func JZ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsREL8(r): + return &intrep.Instruction{ + Opcode: "JZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + case operand.IsREL32(r): + return &intrep.Instruction{ + Opcode: "JZ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + IsBranch: true, + IsConditional: true, + }, nil + } + return nil, errors.New("JZ: bad operands") +} + +// LDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// LDDQU m128 xmm +func LDDQU(m, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "LDDQU", + Operands: []operand.Op{m, x}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("LDDQU: bad operands") +} + +// LDMXCSR: Load MXCSR Register. +// +// Forms: +// +// LDMXCSR m32 +func LDMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "LDMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("LDMXCSR: bad operands") +} + +// LEAL: Load Effective Address. +// +// Forms: +// +// LEAL m r32 +func LEAL(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LEAL", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAL: bad operands") +} + +// LEAQ: Load Effective Address. +// +// Forms: +// +// LEAQ m r64 +func LEAQ(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LEAQ", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAQ: bad operands") +} + +// LEAW: Load Effective Address. +// +// Forms: +// +// LEAW m r16 +func LEAW(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM(m) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LEAW", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LEAW: bad operands") +} + +// LFENCE: Load Fence. +// +// Forms: +// +// LFENCE +func LFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "LFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// LZCNTL: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTL r32 r32 +// LZCNTL m32 r32 +func LZCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "LZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LZCNTL: bad operands") +} + +// LZCNTQ: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTQ r64 r64 +// LZCNTQ m64 r64 +func LZCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "LZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LZCNTQ: bad operands") +} + +// LZCNTW: Count the Number of Leading Zero Bits. +// +// Forms: +// +// LZCNTW r16 r16 +// LZCNTW m16 r16 +func LZCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "LZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("LZCNTW: bad operands") +} + +// MASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVDQU xmm xmm +func MASKMOVDQU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MASKMOVDQU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("MASKMOVDQU: bad operands") +} + +// MASKMOVOU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// MASKMOVOU xmm xmm +func MASKMOVOU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MASKMOVOU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("MASKMOVOU: bad operands") +} + +// MAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MAXPD xmm xmm +// MAXPD m128 xmm +func MAXPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MAXPD: bad operands") +} + +// MAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MAXPS xmm xmm +// MAXPS m128 xmm +func MAXPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MAXPS: bad operands") +} + +// MAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MAXSD xmm xmm +// MAXSD m64 xmm +func MAXSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MAXSD: bad operands") +} + +// MAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MAXSS xmm xmm +// MAXSS m32 xmm +func MAXSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MAXSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MAXSS: bad operands") +} + +// MFENCE: Memory Fence. +// +// Forms: +// +// MFENCE +func MFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// MINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MINPD xmm xmm +// MINPD m128 xmm +func MINPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MINPD: bad operands") +} + +// MINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MINPS xmm xmm +// MINPS m128 xmm +func MINPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MINPS: bad operands") +} + +// MINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MINSD xmm xmm +// MINSD m64 xmm +func MINSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MINSD: bad operands") +} + +// MINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// MINSS xmm xmm +// MINSS m32 xmm +func MINSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MINSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MINSS: bad operands") +} + +// MONITOR: Monitor a Linear Address Range. +// +// Forms: +// +// MONITOR +func MONITOR() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MONITOR", + Operands: nil, + Inputs: []operand.Op{reg.RAX, reg.ECX, reg.EDX}, + Outputs: []operand.Op{}, + }, nil +} + +// MOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPD xmm xmm +// MOVAPD m128 xmm +// MOVAPD xmm m128 +func MOVAPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVAPD: bad operands") +} + +// MOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVAPS xmm xmm +// MOVAPS m128 xmm +// MOVAPS xmm m128 +func MOVAPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVAPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVAPS: bad operands") +} + +// MOVB: Move. +// +// Forms: +// +// MOVB imm8 r8 +// MOVB r8 r8 +// MOVB m8 r8 +// MOVB imm8 m8 +// MOVB r8 m8 +func MOVB(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MOVB", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVB: bad operands") +} + +// MOVBELL: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBELL m32 r32 +// MOVBELL r32 m32 +func MOVBELL(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(mr) && operand.IsR32(mr1): + return &intrep.Instruction{ + Opcode: "MOVBELL", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + case operand.IsR32(mr) && operand.IsM32(mr1): + return &intrep.Instruction{ + Opcode: "MOVBELL", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + } + return nil, errors.New("MOVBELL: bad operands") +} + +// MOVBEQQ: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEQQ m64 r64 +// MOVBEQQ r64 m64 +func MOVBEQQ(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEQQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + case operand.IsR64(mr) && operand.IsM64(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEQQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + } + return nil, errors.New("MOVBEQQ: bad operands") +} + +// MOVBEWW: Move Data After Swapping Bytes. +// +// Forms: +// +// MOVBEWW m16 r16 +// MOVBEWW r16 m16 +func MOVBEWW(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM16(mr) && operand.IsR16(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEWW", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + case operand.IsR16(mr) && operand.IsM16(mr1): + return &intrep.Instruction{ + Opcode: "MOVBEWW", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr1}, + }, nil + } + return nil, errors.New("MOVBEWW: bad operands") +} + +// MOVBLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBLSX r8 r32 +// MOVBLSX m8 r32 +func MOVBLSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBLSX: bad operands") +} + +// MOVBLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBLZX r8 r32 +// MOVBLZX m8 r32 +func MOVBLZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVBLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBLZX: bad operands") +} + +// MOVBQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBQSX r8 r64 +// MOVBQSX m8 r64 +func MOVBQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBQSX: bad operands") +} + +// MOVBQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBQZX r8 r64 +// MOVBQZX m8 r64 +func MOVBQZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVBQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBQZX: bad operands") +} + +// MOVBWSX: Move with Sign-Extension. +// +// Forms: +// +// MOVBWSX r8 r16 +// MOVBWSX m8 r16 +func MOVBWSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBWSX: bad operands") +} + +// MOVBWZX: Move with Zero-Extend. +// +// Forms: +// +// MOVBWZX r8 r16 +// MOVBWZX m8 r16 +func MOVBWZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM8(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "MOVBWZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVBWZX: bad operands") +} + +// MOVD: Move. +// +// Forms: +// +// MOVD imm32 r64 +// MOVD imm64 r64 +// MOVD r64 r64 +// MOVD m64 r64 +// MOVD imm32 m64 +// MOVD r64 m64 +// MOVD xmm r64 +// MOVD r64 xmm +// MOVD xmm xmm +// MOVD m64 xmm +// MOVD xmm m64 +// MOVD xmm r32 +// MOVD r32 xmm +// MOVD m32 xmm +// MOVD xmm m32 +func MOVD(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVD", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + } + return nil, errors.New("MOVD: bad operands") +} + +// MOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// MOVDDUP xmm xmm +// MOVDDUP m64 xmm +func MOVDDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVDDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVDDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MOVDDUP: bad operands") +} + +// MOVDQ2Q: Move. +// +// Forms: +// +// MOVDQ2Q imm32 r64 +// MOVDQ2Q imm64 r64 +// MOVDQ2Q r64 r64 +// MOVDQ2Q m64 r64 +// MOVDQ2Q imm32 m64 +// MOVDQ2Q r64 m64 +// MOVDQ2Q xmm r64 +// MOVDQ2Q r64 xmm +// MOVDQ2Q xmm xmm +// MOVDQ2Q m64 xmm +// MOVDQ2Q xmm m64 +// MOVDQ2Q xmm r32 +// MOVDQ2Q r32 xmm +// MOVDQ2Q m32 xmm +// MOVDQ2Q xmm m32 +func MOVDQ2Q(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVDQ2Q", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + } + return nil, errors.New("MOVDQ2Q: bad operands") +} + +// MOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// MOVHLPS xmm xmm +func MOVHLPS(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MOVHLPS", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("MOVHLPS: bad operands") +} + +// MOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVHPD m64 xmm +// MOVHPD xmm m64 +func MOVHPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVHPD: bad operands") +} + +// MOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVHPS m64 xmm +// MOVHPS xmm m64 +func MOVHPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVHPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVHPS: bad operands") +} + +// MOVL: Move. +// +// Forms: +// +// MOVL imm32 r32 +// MOVL r32 r32 +// MOVL m32 r32 +// MOVL imm32 m32 +// MOVL r32 m32 +func MOVL(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MOVL", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVL: bad operands") +} + +// MOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// MOVLHPS xmm xmm +func MOVLHPS(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "MOVLHPS", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("MOVLHPS: bad operands") +} + +// MOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVLPD m64 xmm +// MOVLPD xmm m64 +func MOVLPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVLPD: bad operands") +} + +// MOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVLPS m64 xmm +// MOVLPS xmm m64 +func MOVLPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVLPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVLPS: bad operands") +} + +// MOVLQSX: Move Doubleword to Quadword with Sign-Extension. +// +// Forms: +// +// MOVLQSX r32 r64 +// MOVLQSX m32 r64 +func MOVLQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVLQSX: bad operands") +} + +// MOVLQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVLQZX m32 r64 +func MOVLQZX(m, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVLQZX", + Operands: []operand.Op{m, r}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVLQZX: bad operands") +} + +// MOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPD xmm r32 +func MOVMSKPD(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVMSKPD", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVMSKPD: bad operands") +} + +// MOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// MOVMSKPS xmm r32 +func MOVMSKPS(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVMSKPS", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVMSKPS: bad operands") +} + +// MOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTDQ xmm m128 +func MOVNTDQ(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTDQ", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTDQ: bad operands") +} + +// MOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// MOVNTDQA m128 xmm +func MOVNTDQA(m, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVNTDQA", + Operands: []operand.Op{m, x}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MOVNTDQA: bad operands") +} + +// MOVNTIL: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIL r32 m32 +func MOVNTIL(r, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "MOVNTIL", + Operands: []operand.Op{r, m}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTIL: bad operands") +} + +// MOVNTIQ: Store Doubleword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTIQ r64 m64 +func MOVNTIQ(r, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsM64(m): + return &intrep.Instruction{ + Opcode: "MOVNTIQ", + Operands: []operand.Op{r, m}, + Inputs: []operand.Op{r}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTIQ: bad operands") +} + +// MOVNTO: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTO xmm m128 +func MOVNTO(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTO", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTO: bad operands") +} + +// MOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPD xmm m128 +func MOVNTPD(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTPD", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTPD: bad operands") +} + +// MOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// MOVNTPS xmm m128 +func MOVNTPS(x, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "MOVNTPS", + Operands: []operand.Op{x, m}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("MOVNTPS: bad operands") +} + +// MOVO: Move Aligned Double Quadword. +// +// Forms: +// +// MOVO xmm xmm +// MOVO m128 xmm +// MOVO xmm m128 +func MOVO(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVO", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVO: bad operands") +} + +// MOVOA: Move Aligned Double Quadword. +// +// Forms: +// +// MOVOA xmm xmm +// MOVOA m128 xmm +// MOVOA xmm m128 +func MOVOA(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVOA", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVOA: bad operands") +} + +// MOVOU: Move Unaligned Double Quadword. +// +// Forms: +// +// MOVOU xmm xmm +// MOVOU m128 xmm +// MOVOU xmm m128 +func MOVOU(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVOU", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVOU: bad operands") +} + +// MOVQ: Move. +// +// Forms: +// +// MOVQ imm32 r64 +// MOVQ imm64 r64 +// MOVQ r64 r64 +// MOVQ m64 r64 +// MOVQ imm32 m64 +// MOVQ r64 m64 +// MOVQ xmm r64 +// MOVQ r64 xmm +// MOVQ xmm xmm +// MOVQ m64 xmm +// MOVQ xmm m64 +// MOVQ xmm r32 +// MOVQ r32 xmm +// MOVQ m32 xmm +// MOVQ xmm m32 +func MOVQ(imrx, mrx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsIMM32(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM64(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM64(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsR32(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsR32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsM32(imrx) && operand.IsXMM(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + case operand.IsXMM(imrx) && operand.IsM32(mrx): + return &intrep.Instruction{ + Opcode: "MOVQ", + Operands: []operand.Op{imrx, mrx}, + Inputs: []operand.Op{imrx}, + Outputs: []operand.Op{mrx}, + }, nil + } + return nil, errors.New("MOVQ: bad operands") +} + +// MOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// MOVSD xmm xmm +// MOVSD m64 xmm +// MOVSD xmm m64 +func MOVSD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM64(mx1): + return &intrep.Instruction{ + Opcode: "MOVSD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVSD: bad operands") +} + +// MOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// MOVSHDUP xmm xmm +// MOVSHDUP m128 xmm +func MOVSHDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSHDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSHDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MOVSHDUP: bad operands") +} + +// MOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// MOVSLDUP xmm xmm +// MOVSLDUP m128 xmm +func MOVSLDUP(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSLDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MOVSLDUP", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MOVSLDUP: bad operands") +} + +// MOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVSS xmm xmm +// MOVSS m32 xmm +// MOVSS xmm m32 +func MOVSS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx, mx1}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM32(mx1): + return &intrep.Instruction{ + Opcode: "MOVSS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVSS: bad operands") +} + +// MOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPD xmm xmm +// MOVUPD m128 xmm +// MOVUPD xmm m128 +func MOVUPD(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPD", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVUPD: bad operands") +} + +// MOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MOVUPS xmm xmm +// MOVUPS m128 xmm +// MOVUPS xmm m128 +func MOVUPS(mx, mx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + case operand.IsXMM(mx) && operand.IsM128(mx1): + return &intrep.Instruction{ + Opcode: "MOVUPS", + Operands: []operand.Op{mx, mx1}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{mx1}, + }, nil + } + return nil, errors.New("MOVUPS: bad operands") +} + +// MOVW: Move. +// +// Forms: +// +// MOVW imm16 r16 +// MOVW r16 r16 +// MOVW m16 r16 +// MOVW imm16 m16 +// MOVW r16 m16 +func MOVW(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MOVW", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("MOVW: bad operands") +} + +// MOVWLSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWLSX r16 r32 +// MOVWLSX m16 r32 +func MOVWLSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWLSX: bad operands") +} + +// MOVWLZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWLZX r16 r32 +// MOVWLZX m16 r32 +func MOVWLZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "MOVWLZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWLZX: bad operands") +} + +// MOVWQSX: Move with Sign-Extension. +// +// Forms: +// +// MOVWQSX r16 r64 +// MOVWQSX m16 r64 +func MOVWQSX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQSX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWQSX: bad operands") +} + +// MOVWQZX: Move with Zero-Extend. +// +// Forms: +// +// MOVWQZX r16 r64 +// MOVWQZX m16 r64 +func MOVWQZX(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "MOVWQZX", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("MOVWQZX: bad operands") +} + +// MPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// MPSADBW imm8 xmm xmm +// MPSADBW imm8 m128 xmm +func MPSADBW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MPSADBW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MPSADBW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MPSADBW: bad operands") +} + +// MULB: Unsigned Multiply. +// +// Forms: +// +// MULB r8 +// MULB m8 +func MULB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "MULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "MULB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AL}, + Outputs: []operand.Op{reg.AX}, + }, nil + } + return nil, errors.New("MULB: bad operands") +} + +// MULL: Unsigned Multiply. +// +// Forms: +// +// MULL r32 +// MULL m32 +func MULL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "MULL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "MULL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.EAX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil + } + return nil, errors.New("MULL: bad operands") +} + +// MULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// MULPD xmm xmm +// MULPD m128 xmm +func MULPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MULPD: bad operands") +} + +// MULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// MULPS xmm xmm +// MULPS m128 xmm +func MULPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MULPS: bad operands") +} + +// MULQ: Unsigned Multiply. +// +// Forms: +// +// MULQ r64 +// MULQ m64 +func MULQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "MULQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "MULQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.RAX}, + Outputs: []operand.Op{reg.RAX, reg.RDX}, + }, nil + } + return nil, errors.New("MULQ: bad operands") +} + +// MULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// MULSD xmm xmm +// MULSD m64 xmm +func MULSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MULSD: bad operands") +} + +// MULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// MULSS xmm xmm +// MULSS m32 xmm +func MULSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "MULSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("MULSS: bad operands") +} + +// MULW: Unsigned Multiply. +// +// Forms: +// +// MULW r16 +// MULW m16 +func MULW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "MULW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "MULW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr, reg.AX}, + Outputs: []operand.Op{reg.AX, reg.DX}, + }, nil + } + return nil, errors.New("MULW: bad operands") +} + +// MULXL: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXL r32 r32 r32 +// MULXL m32 r32 r32 +func MULXL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "MULXL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.EDX}, + Outputs: []operand.Op{r, r1}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "MULXL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.EDX}, + Outputs: []operand.Op{r, r1}, + }, nil + } + return nil, errors.New("MULXL: bad operands") +} + +// MULXQ: Unsigned Multiply Without Affecting Flags. +// +// Forms: +// +// MULXQ r64 r64 r64 +// MULXQ m64 r64 r64 +func MULXQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "MULXQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.RDX}, + Outputs: []operand.Op{r, r1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "MULXQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, reg.RDX}, + Outputs: []operand.Op{r, r1}, + }, nil + } + return nil, errors.New("MULXQ: bad operands") +} + +// MWAIT: Monitor Wait. +// +// Forms: +// +// MWAIT +func MWAIT() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "MWAIT", + Operands: nil, + Inputs: []operand.Op{reg.EAX, reg.ECX}, + Outputs: []operand.Op{}, + }, nil +} + +// NEGB: Two's Complement Negation. +// +// Forms: +// +// NEGB r8 +// NEGB m8 +func NEGB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "NEGB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "NEGB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGB: bad operands") +} + +// NEGL: Two's Complement Negation. +// +// Forms: +// +// NEGL r32 +// NEGL m32 +func NEGL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "NEGL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "NEGL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGL: bad operands") +} + +// NEGQ: Two's Complement Negation. +// +// Forms: +// +// NEGQ r64 +// NEGQ m64 +func NEGQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "NEGQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "NEGQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGQ: bad operands") +} + +// NEGW: Two's Complement Negation. +// +// Forms: +// +// NEGW r16 +// NEGW m16 +func NEGW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "NEGW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "NEGW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NEGW: bad operands") +} + +// NOP: No Operation. +// +// Forms: +// +// NOP +func NOP() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "NOP", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// NOTB: One's Complement Negation. +// +// Forms: +// +// NOTB r8 +// NOTB m8 +func NOTB(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "NOTB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "NOTB", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTB: bad operands") +} + +// NOTL: One's Complement Negation. +// +// Forms: +// +// NOTL r32 +// NOTL m32 +func NOTL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "NOTL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "NOTL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTL: bad operands") +} + +// NOTQ: One's Complement Negation. +// +// Forms: +// +// NOTQ r64 +// NOTQ m64 +func NOTQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "NOTQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "NOTQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTQ: bad operands") +} + +// NOTW: One's Complement Negation. +// +// Forms: +// +// NOTW r16 +// NOTW m16 +func NOTW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "NOTW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "NOTW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("NOTW: bad operands") +} + +// ORB: Logical Inclusive OR. +// +// Forms: +// +// ORB imm8 al +// ORB imm8 r8 +// ORB r8 r8 +// ORB m8 r8 +// ORB imm8 m8 +// ORB r8 m8 +func ORB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "ORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ORB: bad operands") +} + +// ORL: Logical Inclusive OR. +// +// Forms: +// +// ORL imm32 eax +// ORL imm8 r32 +// ORL imm32 r32 +// ORL r32 r32 +// ORL m32 r32 +// ORL imm8 m32 +// ORL imm32 m32 +// ORL r32 m32 +func ORL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "ORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("ORL: bad operands") +} + +// ORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// ORPD xmm xmm +// ORPD m128 xmm +func ORPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ORPD: bad operands") +} + +// ORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// ORPS xmm xmm +// ORPS m128 xmm +func ORPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ORPS: bad operands") +} + +// ORQ: Logical Inclusive OR. +// +// Forms: +// +// ORQ imm32 rax +// ORQ imm8 r64 +// ORQ imm32 r64 +// ORQ r64 r64 +// ORQ m64 r64 +// ORQ imm8 m64 +// ORQ imm32 m64 +// ORQ r64 m64 +func ORQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ORQ: bad operands") +} + +// ORW: Logical Inclusive OR. +// +// Forms: +// +// ORW imm16 ax +// ORW imm8 r16 +// ORW imm16 r16 +// ORW r16 r16 +// ORW m16 r16 +// ORW imm8 m16 +// ORW imm16 m16 +// ORW r16 m16 +func ORW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "ORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("ORW: bad operands") +} + +// PABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// PABSB xmm xmm +// PABSB m128 xmm +func PABSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PABSB: bad operands") +} + +// PABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// PABSD xmm xmm +// PABSD m128 xmm +func PABSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PABSD: bad operands") +} + +// PABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// PABSW xmm xmm +// PABSW m128 xmm +func PABSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PABSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PABSW: bad operands") +} + +// PACKSSLW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// PACKSSLW xmm xmm +// PACKSSLW m128 xmm +func PACKSSLW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PACKSSLW: bad operands") +} + +// PACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// PACKSSWB xmm xmm +// PACKSSWB m128 xmm +func PACKSSWB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKSSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PACKSSWB: bad operands") +} + +// PACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// PACKUSDW xmm xmm +// PACKUSDW m128 xmm +func PACKUSDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PACKUSDW: bad operands") +} + +// PACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// PACKUSWB xmm xmm +// PACKUSWB m128 xmm +func PACKUSWB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PACKUSWB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PACKUSWB: bad operands") +} + +// PADDB: Add Packed Byte Integers. +// +// Forms: +// +// PADDB xmm xmm +// PADDB m128 xmm +func PADDB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDB: bad operands") +} + +// PADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDD xmm xmm +// PADDD m128 xmm +func PADDD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDD: bad operands") +} + +// PADDL: Add Packed Doubleword Integers. +// +// Forms: +// +// PADDL xmm xmm +// PADDL m128 xmm +func PADDL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDL: bad operands") +} + +// PADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// PADDQ xmm xmm +// PADDQ m128 xmm +func PADDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDQ: bad operands") +} + +// PADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PADDSB xmm xmm +// PADDSB m128 xmm +func PADDSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDSB: bad operands") +} + +// PADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PADDSW xmm xmm +// PADDSW m128 xmm +func PADDSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDSW: bad operands") +} + +// PADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSB xmm xmm +// PADDUSB m128 xmm +func PADDUSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDUSB: bad operands") +} + +// PADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PADDUSW xmm xmm +// PADDUSW m128 xmm +func PADDUSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDUSW: bad operands") +} + +// PADDW: Add Packed Word Integers. +// +// Forms: +// +// PADDW xmm xmm +// PADDW m128 xmm +func PADDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PADDW: bad operands") +} + +// PALIGNR: Packed Align Right. +// +// Forms: +// +// PALIGNR imm8 xmm xmm +// PALIGNR imm8 m128 xmm +func PALIGNR(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PALIGNR", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PALIGNR", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PALIGNR: bad operands") +} + +// PAND: Packed Bitwise Logical AND. +// +// Forms: +// +// PAND xmm xmm +// PAND m128 xmm +func PAND(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PAND: bad operands") +} + +// PANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// PANDN xmm xmm +// PANDN m128 xmm +func PANDN(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PANDN", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PANDN", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PANDN: bad operands") +} + +// PAUSE: Spin Loop Hint. +// +// Forms: +// +// PAUSE +func PAUSE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "PAUSE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// PAVGB: Average Packed Byte Integers. +// +// Forms: +// +// PAVGB xmm xmm +// PAVGB m128 xmm +func PAVGB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PAVGB: bad operands") +} + +// PAVGW: Average Packed Word Integers. +// +// Forms: +// +// PAVGW xmm xmm +// PAVGW m128 xmm +func PAVGW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PAVGW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PAVGW: bad operands") +} + +// PBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// PBLENDVB xmm0 xmm xmm +// PBLENDVB xmm0 m128 xmm +func PBLENDVB(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "PBLENDVB", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "PBLENDVB", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("PBLENDVB: bad operands") +} + +// PBLENDW: Blend Packed Words. +// +// Forms: +// +// PBLENDW imm8 xmm xmm +// PBLENDW imm8 m128 xmm +func PBLENDW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PBLENDW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PBLENDW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PBLENDW: bad operands") +} + +// PCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// PCLMULQDQ imm8 xmm xmm +// PCLMULQDQ imm8 m128 xmm +func PCLMULQDQ(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCLMULQDQ", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCLMULQDQ", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCLMULQDQ: bad operands") +} + +// PCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// PCMPEQB xmm xmm +// PCMPEQB m128 xmm +func PCMPEQB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPEQB: bad operands") +} + +// PCMPEQL: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// PCMPEQL xmm xmm +// PCMPEQL m128 xmm +func PCMPEQL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPEQL: bad operands") +} + +// PCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// PCMPEQQ xmm xmm +// PCMPEQQ m128 xmm +func PCMPEQQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPEQQ: bad operands") +} + +// PCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// PCMPEQW xmm xmm +// PCMPEQW m128 xmm +func PCMPEQW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPEQW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPEQW: bad operands") +} + +// PCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// PCMPESTRI imm8 xmm xmm +// PCMPESTRI imm8 m128 xmm +func PCMPESTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + }, nil + } + return nil, errors.New("PCMPESTRI: bad operands") +} + +// PCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPESTRM imm8 xmm xmm +// PCMPESTRM imm8 m128 xmm +func PCMPESTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + }, nil + } + return nil, errors.New("PCMPESTRM: bad operands") +} + +// PCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// PCMPGTB xmm xmm +// PCMPGTB m128 xmm +func PCMPGTB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPGTB: bad operands") +} + +// PCMPGTL: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// PCMPGTL xmm xmm +// PCMPGTL m128 xmm +func PCMPGTL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPGTL: bad operands") +} + +// PCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// PCMPGTQ xmm xmm +// PCMPGTQ m128 xmm +func PCMPGTQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPGTQ: bad operands") +} + +// PCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// PCMPGTW xmm xmm +// PCMPGTW m128 xmm +func PCMPGTW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPGTW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PCMPGTW: bad operands") +} + +// PCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// PCMPISTRI imm8 xmm xmm +// PCMPISTRI imm8 m128 xmm +func PCMPISTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + }, nil + } + return nil, errors.New("PCMPISTRI: bad operands") +} + +// PCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// PCMPISTRM imm8 xmm xmm +// PCMPISTRM imm8 m128 xmm +func PCMPISTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + }, nil + } + return nil, errors.New("PCMPISTRM: bad operands") +} + +// PDEPL: Parallel Bits Deposit. +// +// Forms: +// +// PDEPL r32 r32 r32 +// PDEPL m32 r32 r32 +func PDEPL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PDEPL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PDEPL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("PDEPL: bad operands") +} + +// PDEPQ: Parallel Bits Deposit. +// +// Forms: +// +// PDEPQ r64 r64 r64 +// PDEPQ m64 r64 r64 +func PDEPQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PDEPQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PDEPQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("PDEPQ: bad operands") +} + +// PEXTL: Parallel Bits Extract. +// +// Forms: +// +// PEXTL r32 r32 r32 +// PEXTL m32 r32 r32 +func PEXTL(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PEXTL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "PEXTL", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("PEXTL: bad operands") +} + +// PEXTQ: Parallel Bits Extract. +// +// Forms: +// +// PEXTQ r64 r64 r64 +// PEXTQ m64 r64 r64 +func PEXTQ(mr, r, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PEXTQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "PEXTQ", + Operands: []operand.Op{mr, r, r1}, + Inputs: []operand.Op{mr, r}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("PEXTQ: bad operands") +} + +// PEXTRB: Extract Byte. +// +// Forms: +// +// PEXTRB imm8 xmm r32 +// PEXTRB imm8 xmm m8 +func PEXTRB(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "PEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("PEXTRB: bad operands") +} + +// PEXTRD: Extract Doubleword. +// +// Forms: +// +// PEXTRD imm8 xmm r32 +// PEXTRD imm8 xmm m32 +func PEXTRD(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("PEXTRD: bad operands") +} + +// PEXTRQ: Extract Quadword. +// +// Forms: +// +// PEXTRQ imm8 xmm r64 +// PEXTRQ imm8 xmm m64 +func PEXTRQ(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "PEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "PEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("PEXTRQ: bad operands") +} + +// PEXTRW: Extract Word. +// +// Forms: +// +// PEXTRW imm8 xmm r32 +// PEXTRW imm8 xmm m16 +func PEXTRW(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "PEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "PEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("PEXTRW: bad operands") +} + +// PHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// PHADDD xmm xmm +// PHADDD m128 xmm +func PHADDD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHADDD: bad operands") +} + +// PHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHADDSW xmm xmm +// PHADDSW m128 xmm +func PHADDSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHADDSW: bad operands") +} + +// PHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// PHADDW xmm xmm +// PHADDW m128 xmm +func PHADDW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHADDW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHADDW: bad operands") +} + +// PHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// PHMINPOSUW xmm xmm +// PHMINPOSUW m128 xmm +func PHMINPOSUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHMINPOSUW: bad operands") +} + +// PHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// PHSUBD xmm xmm +// PHSUBD m128 xmm +func PHSUBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHSUBD: bad operands") +} + +// PHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PHSUBSW xmm xmm +// PHSUBSW m128 xmm +func PHSUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHSUBSW: bad operands") +} + +// PHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// PHSUBW xmm xmm +// PHSUBW m128 xmm +func PHSUBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PHSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PHSUBW: bad operands") +} + +// PINSRB: Insert Byte. +// +// Forms: +// +// PINSRB imm8 r32 xmm +// PINSRB imm8 m8 xmm +func PINSRB(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRB", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM8(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRB", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PINSRB: bad operands") +} + +// PINSRD: Insert Doubleword. +// +// Forms: +// +// PINSRD imm8 r32 xmm +// PINSRD imm8 m32 xmm +func PINSRD(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRD", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRD", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PINSRD: bad operands") +} + +// PINSRQ: Insert Quadword. +// +// Forms: +// +// PINSRQ imm8 r64 xmm +// PINSRQ imm8 m64 xmm +func PINSRQ(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRQ", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRQ", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PINSRQ: bad operands") +} + +// PINSRW: Insert Word. +// +// Forms: +// +// PINSRW imm8 r32 xmm +// PINSRW imm8 m16 xmm +func PINSRW(i, mr, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRW", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PINSRW", + Operands: []operand.Op{i, mr, x}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PINSRW: bad operands") +} + +// PMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// PMADDUBSW xmm xmm +// PMADDUBSW m128 xmm +func PMADDUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMADDUBSW: bad operands") +} + +// PMADDWL: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// PMADDWL xmm xmm +// PMADDWL m128 xmm +func PMADDWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMADDWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMADDWL: bad operands") +} + +// PMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// PMAXSB xmm xmm +// PMAXSB m128 xmm +func PMAXSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXSB: bad operands") +} + +// PMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMAXSD xmm xmm +// PMAXSD m128 xmm +func PMAXSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXSD: bad operands") +} + +// PMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// PMAXSW xmm xmm +// PMAXSW m128 xmm +func PMAXSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXSW: bad operands") +} + +// PMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMAXUB xmm xmm +// PMAXUB m128 xmm +func PMAXUB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXUB: bad operands") +} + +// PMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMAXUD xmm xmm +// PMAXUD m128 xmm +func PMAXUD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXUD: bad operands") +} + +// PMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMAXUW xmm xmm +// PMAXUW m128 xmm +func PMAXUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMAXUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMAXUW: bad operands") +} + +// PMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// PMINSB xmm xmm +// PMINSB m128 xmm +func PMINSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINSB: bad operands") +} + +// PMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// PMINSD xmm xmm +// PMINSD m128 xmm +func PMINSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINSD: bad operands") +} + +// PMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// PMINSW xmm xmm +// PMINSW m128 xmm +func PMINSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINSW: bad operands") +} + +// PMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// PMINUB xmm xmm +// PMINUB m128 xmm +func PMINUB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINUB: bad operands") +} + +// PMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMINUD xmm xmm +// PMINUD m128 xmm +func PMINUD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINUD: bad operands") +} + +// PMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// PMINUW xmm xmm +// PMINUW m128 xmm +func PMINUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMINUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMINUW: bad operands") +} + +// PMOVMSKB: Move Byte Mask. +// +// Forms: +// +// PMOVMSKB xmm r32 +func PMOVMSKB(x, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "PMOVMSKB", + Operands: []operand.Op{x, r}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("PMOVMSKB: bad operands") +} + +// PMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBD xmm xmm +// PMOVSXBD m32 xmm +func PMOVSXBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXBD: bad operands") +} + +// PMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBQ xmm xmm +// PMOVSXBQ m16 xmm +func PMOVSXBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXBQ: bad operands") +} + +// PMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// PMOVSXBW xmm xmm +// PMOVSXBW m64 xmm +func PMOVSXBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXBW: bad operands") +} + +// PMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXDQ xmm xmm +// PMOVSXDQ m64 xmm +func PMOVSXDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXDQ: bad operands") +} + +// PMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWD xmm xmm +// PMOVSXWD m64 xmm +func PMOVSXWD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXWD: bad operands") +} + +// PMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// PMOVSXWQ xmm xmm +// PMOVSXWQ m32 xmm +func PMOVSXWQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVSXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVSXWQ: bad operands") +} + +// PMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBD xmm xmm +// PMOVZXBD m32 xmm +func PMOVZXBD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXBD: bad operands") +} + +// PMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBQ xmm xmm +// PMOVZXBQ m16 xmm +func PMOVZXBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXBQ: bad operands") +} + +// PMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// PMOVZXBW xmm xmm +// PMOVZXBW m64 xmm +func PMOVZXBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXBW: bad operands") +} + +// PMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXDQ xmm xmm +// PMOVZXDQ m64 xmm +func PMOVZXDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXDQ: bad operands") +} + +// PMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWD xmm xmm +// PMOVZXWD m64 xmm +func PMOVZXWD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXWD: bad operands") +} + +// PMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// PMOVZXWQ xmm xmm +// PMOVZXWQ m32 xmm +func PMOVZXWQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMOVZXWQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMOVZXWQ: bad operands") +} + +// PMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// PMULDQ xmm xmm +// PMULDQ m128 xmm +func PMULDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULDQ: bad operands") +} + +// PMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// PMULHRSW xmm xmm +// PMULHRSW m128 xmm +func PMULHRSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHRSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHRSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULHRSW: bad operands") +} + +// PMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// PMULHUW xmm xmm +// PMULHUW m128 xmm +func PMULHUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULHUW: bad operands") +} + +// PMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// PMULHW xmm xmm +// PMULHW m128 xmm +func PMULHW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULHW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULHW: bad operands") +} + +// PMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// PMULLD xmm xmm +// PMULLD m128 xmm +func PMULLD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULLD: bad operands") +} + +// PMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// PMULLW xmm xmm +// PMULLW m128 xmm +func PMULLW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULLW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULLW: bad operands") +} + +// PMULULQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// PMULULQ xmm xmm +// PMULULQ m128 xmm +func PMULULQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULULQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PMULULQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PMULULQ: bad operands") +} + +// POPCNTL: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTL r32 r32 +// POPCNTL m32 r32 +func POPCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "POPCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "POPCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("POPCNTL: bad operands") +} + +// POPCNTQ: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTQ r64 r64 +// POPCNTQ m64 r64 +func POPCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "POPCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "POPCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("POPCNTQ: bad operands") +} + +// POPCNTW: Count of Number of Bits Set to 1. +// +// Forms: +// +// POPCNTW r16 r16 +// POPCNTW m16 r16 +func POPCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "POPCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "POPCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("POPCNTW: bad operands") +} + +// POPQ: Pop a Value from the Stack. +// +// Forms: +// +// POPQ r64 +// POPQ m64 +func POPQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "POPQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "POPQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("POPQ: bad operands") +} + +// POPW: Pop a Value from the Stack. +// +// Forms: +// +// POPW r16 +// POPW m16 +func POPW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "POPW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "POPW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("POPW: bad operands") +} + +// POR: Packed Bitwise Logical OR. +// +// Forms: +// +// POR xmm xmm +// POR m128 xmm +func POR(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "POR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "POR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("POR: bad operands") +} + +// PREFETCHNTA: Prefetch Data Into Caches using NTA Hint. +// +// Forms: +// +// PREFETCHNTA m8 +func PREFETCHNTA(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHNTA", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PREFETCHNTA: bad operands") +} + +// PREFETCHT0: Prefetch Data Into Caches using T0 Hint. +// +// Forms: +// +// PREFETCHT0 m8 +func PREFETCHT0(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT0", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PREFETCHT0: bad operands") +} + +// PREFETCHT1: Prefetch Data Into Caches using T1 Hint. +// +// Forms: +// +// PREFETCHT1 m8 +func PREFETCHT1(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT1", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PREFETCHT1: bad operands") +} + +// PREFETCHT2: Prefetch Data Into Caches using T2 Hint. +// +// Forms: +// +// PREFETCHT2 m8 +func PREFETCHT2(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM8(m): + return &intrep.Instruction{ + Opcode: "PREFETCHT2", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PREFETCHT2: bad operands") +} + +// PSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// PSADBW xmm xmm +// PSADBW m128 xmm +func PSADBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSADBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSADBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSADBW: bad operands") +} + +// PSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// PSHUFB xmm xmm +// PSHUFB m128 xmm +func PSHUFB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSHUFB: bad operands") +} + +// PSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFD imm8 xmm xmm +// PSHUFD imm8 m128 xmm +func PSHUFD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSHUFD: bad operands") +} + +// PSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// PSHUFHW imm8 xmm xmm +// PSHUFHW imm8 m128 xmm +func PSHUFHW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFHW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFHW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSHUFHW: bad operands") +} + +// PSHUFL: Shuffle Packed Doublewords. +// +// Forms: +// +// PSHUFL imm8 xmm xmm +// PSHUFL imm8 m128 xmm +func PSHUFL(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFL", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFL", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSHUFL: bad operands") +} + +// PSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// PSHUFLW imm8 xmm xmm +// PSHUFLW imm8 m128 xmm +func PSHUFLW(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFLW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSHUFLW", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSHUFLW: bad operands") +} + +// PSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// PSIGNB xmm xmm +// PSIGNB m128 xmm +func PSIGNB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSIGNB: bad operands") +} + +// PSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// PSIGND xmm xmm +// PSIGND m128 xmm +func PSIGND(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGND", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSIGND: bad operands") +} + +// PSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// PSIGNW xmm xmm +// PSIGNW m128 xmm +func PSIGNW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSIGNW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSIGNW: bad operands") +} + +// PSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLDQ imm8 xmm +func PSLLDQ(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLDQ", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSLLDQ: bad operands") +} + +// PSLLL: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// PSLLL imm8 xmm +// PSLLL xmm xmm +// PSLLL m128 xmm +func PSLLL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSLLL: bad operands") +} + +// PSLLO: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// PSLLO imm8 xmm +func PSLLO(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLO", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSLLO: bad operands") +} + +// PSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// PSLLQ imm8 xmm +// PSLLQ xmm xmm +// PSLLQ m128 xmm +func PSLLQ(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSLLQ: bad operands") +} + +// PSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// PSLLW imm8 xmm +// PSLLW xmm xmm +// PSLLW m128 xmm +func PSLLW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSLLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSLLW: bad operands") +} + +// PSRAL: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// PSRAL imm8 xmm +// PSRAL xmm xmm +// PSRAL m128 xmm +func PSRAL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRAL: bad operands") +} + +// PSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// PSRAW imm8 xmm +// PSRAW xmm xmm +// PSRAW m128 xmm +func PSRAW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRAW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRAW: bad operands") +} + +// PSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLDQ imm8 xmm +func PSRLDQ(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLDQ", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRLDQ: bad operands") +} + +// PSRLL: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// PSRLL imm8 xmm +// PSRLL xmm xmm +// PSRLL m128 xmm +func PSRLL(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLL", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRLL: bad operands") +} + +// PSRLO: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// PSRLO imm8 xmm +func PSRLO(i, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLO", + Operands: []operand.Op{i, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRLO: bad operands") +} + +// PSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// PSRLQ imm8 xmm +// PSRLQ xmm xmm +// PSRLQ m128 xmm +func PSRLQ(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLQ", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRLQ: bad operands") +} + +// PSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// PSRLW imm8 xmm +// PSRLW xmm xmm +// PSRLW m128 xmm +func PSRLW(imx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSRLW", + Operands: []operand.Op{imx, x}, + Inputs: []operand.Op{imx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSRLW: bad operands") +} + +// PSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// PSUBB xmm xmm +// PSUBB m128 xmm +func PSUBB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBB: bad operands") +} + +// PSUBL: Subtract Packed Doubleword Integers. +// +// Forms: +// +// PSUBL xmm xmm +// PSUBL m128 xmm +func PSUBL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBL: bad operands") +} + +// PSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// PSUBQ xmm xmm +// PSUBQ m128 xmm +func PSUBQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBQ: bad operands") +} + +// PSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// PSUBSB xmm xmm +// PSUBSB m128 xmm +func PSUBSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBSB: bad operands") +} + +// PSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// PSUBSW xmm xmm +// PSUBSW m128 xmm +func PSUBSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBSW: bad operands") +} + +// PSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSB xmm xmm +// PSUBUSB m128 xmm +func PSUBUSB(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSB", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBUSB: bad operands") +} + +// PSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// PSUBUSW xmm xmm +// PSUBUSW m128 xmm +func PSUBUSW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBUSW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBUSW: bad operands") +} + +// PSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// PSUBW xmm xmm +// PSUBW m128 xmm +func PSUBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PSUBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PSUBW: bad operands") +} + +// PTEST: Packed Logical Compare. +// +// Forms: +// +// PTEST xmm xmm +// PTEST m128 xmm +func PTEST(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PTEST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PTEST", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PTEST: bad operands") +} + +// PUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// PUNPCKHBW xmm xmm +// PUNPCKHBW m128 xmm +func PUNPCKHBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKHBW: bad operands") +} + +// PUNPCKHLQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKHLQ xmm xmm +// PUNPCKHLQ m128 xmm +func PUNPCKHLQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKHLQ: bad operands") +} + +// PUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKHQDQ xmm xmm +// PUNPCKHQDQ m128 xmm +func PUNPCKHQDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKHQDQ: bad operands") +} + +// PUNPCKHWL: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKHWL xmm xmm +// PUNPCKHWL m128 xmm +func PUNPCKHWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKHWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKHWL: bad operands") +} + +// PUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// PUNPCKLBW xmm xmm +// PUNPCKLBW m128 xmm +func PUNPCKLBW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLBW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKLBW: bad operands") +} + +// PUNPCKLLQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// PUNPCKLLQ xmm xmm +// PUNPCKLLQ m128 xmm +func PUNPCKLLQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLLQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKLLQ: bad operands") +} + +// PUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// PUNPCKLQDQ xmm xmm +// PUNPCKLQDQ m128 xmm +func PUNPCKLQDQ(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLQDQ", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKLQDQ: bad operands") +} + +// PUNPCKLWL: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// PUNPCKLWL xmm xmm +// PUNPCKLWL m128 xmm +func PUNPCKLWL(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PUNPCKLWL", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PUNPCKLWL: bad operands") +} + +// PUSHQ: Push Value Onto the Stack. +// +// Forms: +// +// PUSHQ imm8 +// PUSHQ imm32 +// PUSHQ r64 +// PUSHQ m64 +func PUSHQ(imr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(imr): + return &intrep.Instruction{ + Opcode: "PUSHQ", + Operands: []operand.Op{imr}, + Inputs: []operand.Op{imr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PUSHQ: bad operands") +} + +// PUSHW: Push Value Onto the Stack. +// +// Forms: +// +// PUSHW r16 +// PUSHW m16 +func PUSHW(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "PUSHW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "PUSHW", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("PUSHW: bad operands") +} + +// PXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// PXOR xmm xmm +// PXOR m128 xmm +func PXOR(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PXOR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "PXOR", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("PXOR: bad operands") +} + +// RCLB: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLB 1 r8 +// RCLB imm8 r8 +// RCLB cl r8 +// RCLB 1 m8 +// RCLB imm8 m8 +// RCLB cl m8 +func RCLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLB: bad operands") +} + +// RCLL: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLL 1 r32 +// RCLL imm8 r32 +// RCLL cl r32 +// RCLL 1 m32 +// RCLL imm8 m32 +// RCLL cl m32 +func RCLL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLL: bad operands") +} + +// RCLQ: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLQ 1 r64 +// RCLQ imm8 r64 +// RCLQ cl r64 +// RCLQ 1 m64 +// RCLQ imm8 m64 +// RCLQ cl m64 +func RCLQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLQ: bad operands") +} + +// RCLW: Rotate Left through Carry Flag. +// +// Forms: +// +// RCLW 1 r16 +// RCLW imm8 r16 +// RCLW cl r16 +// RCLW 1 m16 +// RCLW imm8 m16 +// RCLW cl m16 +func RCLW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCLW: bad operands") +} + +// RCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPPS xmm xmm +// RCPPS m128 xmm +func RCPPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("RCPPS: bad operands") +} + +// RCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// RCPSS xmm xmm +// RCPSS m32 xmm +func RCPSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RCPSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("RCPSS: bad operands") +} + +// RCRB: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRB 1 r8 +// RCRB imm8 r8 +// RCRB cl r8 +// RCRB 1 m8 +// RCRB imm8 m8 +// RCRB cl m8 +func RCRB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RCRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRB: bad operands") +} + +// RCRL: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRL 1 r32 +// RCRL imm8 r32 +// RCRL cl r32 +// RCRL 1 m32 +// RCRL imm8 m32 +// RCRL cl m32 +func RCRL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RCRL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRL: bad operands") +} + +// RCRQ: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRQ 1 r64 +// RCRQ imm8 r64 +// RCRQ cl r64 +// RCRQ 1 m64 +// RCRQ imm8 m64 +// RCRQ cl m64 +func RCRQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RCRQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRQ: bad operands") +} + +// RCRW: Rotate Right through Carry Flag. +// +// Forms: +// +// RCRW 1 r16 +// RCRW imm8 r16 +// RCRW cl r16 +// RCRW 1 m16 +// RCRW imm8 m16 +// RCRW cl m16 +func RCRW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RCRW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RCRW: bad operands") +} + +// RDRANDL: Read Random Number. +// +// Forms: +// +// RDRANDL r32 +func RDRANDL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RDRANDL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDRANDL: bad operands") +} + +// RDRANDQ: Read Random Number. +// +// Forms: +// +// RDRANDQ r64 +func RDRANDQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RDRANDQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDRANDQ: bad operands") +} + +// RDRANDW: Read Random Number. +// +// Forms: +// +// RDRANDW r16 +func RDRANDW(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "RDRANDW", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDRANDW: bad operands") +} + +// RDSEEDL: Read Random SEED. +// +// Forms: +// +// RDSEEDL r32 +func RDSEEDL(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RDSEEDL", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDSEEDL: bad operands") +} + +// RDSEEDQ: Read Random SEED. +// +// Forms: +// +// RDSEEDQ r64 +func RDSEEDQ(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RDSEEDQ", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDSEEDQ: bad operands") +} + +// RDSEEDW: Read Random SEED. +// +// Forms: +// +// RDSEEDW r16 +func RDSEEDW(r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "RDSEEDW", + Operands: []operand.Op{r}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RDSEEDW: bad operands") +} + +// RDTSC: Read Time-Stamp Counter. +// +// Forms: +// +// RDTSC +func RDTSC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RDTSC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil +} + +// RDTSCP: Read Time-Stamp Counter and Processor ID. +// +// Forms: +// +// RDTSCP +func RDTSCP() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RDTSCP", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.EAX, reg.ECX, reg.EDX}, + }, nil +} + +// RET: Return from Procedure. +// +// Forms: +// +// RET +func RET() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "RET", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// RETFL: Return from Procedure. +// +// Forms: +// +// RETFL imm16 +func RETFL(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFL", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFL: bad operands") +} + +// RETFQ: Return from Procedure. +// +// Forms: +// +// RETFQ imm16 +func RETFQ(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFQ", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFQ: bad operands") +} + +// RETFW: Return from Procedure. +// +// Forms: +// +// RETFW imm16 +func RETFW(i operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(i): + return &intrep.Instruction{ + Opcode: "RETFW", + Operands: []operand.Op{i}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("RETFW: bad operands") +} + +// ROLB: Rotate Left. +// +// Forms: +// +// ROLB 1 r8 +// ROLB imm8 r8 +// ROLB cl r8 +// ROLB 1 m8 +// ROLB imm8 m8 +// ROLB cl m8 +func ROLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "ROLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLB: bad operands") +} + +// ROLL: Rotate Left. +// +// Forms: +// +// ROLL 1 r32 +// ROLL imm8 r32 +// ROLL cl r32 +// ROLL 1 m32 +// ROLL imm8 m32 +// ROLL cl m32 +func ROLL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "ROLL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLL: bad operands") +} + +// ROLQ: Rotate Left. +// +// Forms: +// +// ROLQ 1 r64 +// ROLQ imm8 r64 +// ROLQ cl r64 +// ROLQ 1 m64 +// ROLQ imm8 m64 +// ROLQ cl m64 +func ROLQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "ROLQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLQ: bad operands") +} + +// ROLW: Rotate Left. +// +// Forms: +// +// ROLW 1 r16 +// ROLW imm8 r16 +// ROLW cl r16 +// ROLW 1 m16 +// ROLW imm8 m16 +// ROLW cl m16 +func ROLW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "ROLW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("ROLW: bad operands") +} + +// RORB: Rotate Right. +// +// Forms: +// +// RORB 1 r8 +// RORB imm8 r8 +// RORB cl r8 +// RORB 1 m8 +// RORB imm8 m8 +// RORB cl m8 +func RORB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "RORB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORB: bad operands") +} + +// RORL: Rotate Right. +// +// Forms: +// +// RORL 1 r32 +// RORL imm8 r32 +// RORL cl r32 +// RORL 1 m32 +// RORL imm8 m32 +// RORL cl m32 +func RORL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "RORL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORL: bad operands") +} + +// RORQ: Rotate Right. +// +// Forms: +// +// RORQ 1 r64 +// RORQ imm8 r64 +// RORQ cl r64 +// RORQ 1 m64 +// RORQ imm8 m64 +// RORQ cl m64 +func RORQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "RORQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORQ: bad operands") +} + +// RORW: Rotate Right. +// +// Forms: +// +// RORW 1 r16 +// RORW imm8 r16 +// RORW cl r16 +// RORW 1 m16 +// RORW imm8 m16 +// RORW cl m16 +func RORW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "RORW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("RORW: bad operands") +} + +// RORXL: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXL imm8 r32 r32 +// RORXL imm8 m32 r32 +func RORXL(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RORXL", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "RORXL", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RORXL: bad operands") +} + +// RORXQ: Rotate Right Logical Without Affecting Flags. +// +// Forms: +// +// RORXQ imm8 r64 r64 +// RORXQ imm8 m64 r64 +func RORXQ(i, mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RORXQ", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "RORXQ", + Operands: []operand.Op{i, mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("RORXQ: bad operands") +} + +// ROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPD imm8 xmm xmm +// ROUNDPD imm8 m128 xmm +func ROUNDPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ROUNDPD: bad operands") +} + +// ROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDPS imm8 xmm xmm +// ROUNDPS imm8 m128 xmm +func ROUNDPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ROUNDPS: bad operands") +} + +// ROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSD imm8 xmm xmm +// ROUNDSD imm8 m64 xmm +func ROUNDSD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ROUNDSD: bad operands") +} + +// ROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// ROUNDSS imm8 xmm xmm +// ROUNDSS imm8 m32 xmm +func ROUNDSS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "ROUNDSS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("ROUNDSS: bad operands") +} + +// RSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// RSQRTPS xmm xmm +// RSQRTPS m128 xmm +func RSQRTPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("RSQRTPS: bad operands") +} + +// RSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// RSQRTSS xmm xmm +// RSQRTSS m32 xmm +func RSQRTSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "RSQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("RSQRTSS: bad operands") +} + +// SALB: Arithmetic Shift Left. +// +// Forms: +// +// SALB 1 r8 +// SALB imm8 r8 +// SALB cl r8 +// SALB 1 m8 +// SALB imm8 m8 +// SALB cl m8 +func SALB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SALB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALB: bad operands") +} + +// SALL: Arithmetic Shift Left. +// +// Forms: +// +// SALL 1 r32 +// SALL imm8 r32 +// SALL cl r32 +// SALL 1 m32 +// SALL imm8 m32 +// SALL cl m32 +func SALL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SALL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALL: bad operands") +} + +// SALQ: Arithmetic Shift Left. +// +// Forms: +// +// SALQ 1 r64 +// SALQ imm8 r64 +// SALQ cl r64 +// SALQ 1 m64 +// SALQ imm8 m64 +// SALQ cl m64 +func SALQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SALQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALQ: bad operands") +} + +// SALW: Arithmetic Shift Left. +// +// Forms: +// +// SALW 1 r16 +// SALW imm8 r16 +// SALW cl r16 +// SALW 1 m16 +// SALW imm8 m16 +// SALW cl m16 +func SALW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SALW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SALW: bad operands") +} + +// SARB: Arithmetic Shift Right. +// +// Forms: +// +// SARB 1 r8 +// SARB imm8 r8 +// SARB cl r8 +// SARB 1 m8 +// SARB imm8 m8 +// SARB cl m8 +func SARB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SARB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARB: bad operands") +} + +// SARL: Arithmetic Shift Right. +// +// Forms: +// +// SARL 1 r32 +// SARL imm8 r32 +// SARL cl r32 +// SARL 1 m32 +// SARL imm8 m32 +// SARL cl m32 +func SARL(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "SARL", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARL: bad operands") +} + +// SARQ: Arithmetic Shift Right. +// +// Forms: +// +// SARQ 1 r64 +// SARQ imm8 r64 +// SARQ cl r64 +// SARQ 1 m64 +// SARQ imm8 m64 +// SARQ cl m64 +func SARQ(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SARQ", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARQ: bad operands") +} + +// SARW: Arithmetic Shift Right. +// +// Forms: +// +// SARW 1 r16 +// SARW imm8 r16 +// SARW cl r16 +// SARW 1 m16 +// SARW imm8 m16 +// SARW cl m16 +func SARW(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "SARW", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SARW: bad operands") +} + +// SARXL: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXL r32 r32 r32 +// SARXL r32 m32 r32 +func SARXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SARXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SARXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SARXL: bad operands") +} + +// SARXQ: Arithmetic Shift Right Without Affecting Flags. +// +// Forms: +// +// SARXQ r64 r64 r64 +// SARXQ r64 m64 r64 +func SARXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SARXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SARXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SARXQ: bad operands") +} + +// SBBB: Subtract with Borrow. +// +// Forms: +// +// SBBB imm8 al +// SBBB imm8 r8 +// SBBB r8 r8 +// SBBB m8 r8 +// SBBB imm8 m8 +// SBBB r8 m8 +func SBBB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SBBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SBBB: bad operands") +} + +// SBBL: Subtract with Borrow. +// +// Forms: +// +// SBBL imm32 eax +// SBBL imm8 r32 +// SBBL imm32 r32 +// SBBL r32 r32 +// SBBL m32 r32 +// SBBL imm8 m32 +// SBBL imm32 m32 +// SBBL r32 m32 +func SBBL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SBBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("SBBL: bad operands") +} + +// SBBQ: Subtract with Borrow. +// +// Forms: +// +// SBBQ imm32 rax +// SBBQ imm8 r64 +// SBBQ imm32 r64 +// SBBQ r64 r64 +// SBBQ m64 r64 +// SBBQ imm8 m64 +// SBBQ imm32 m64 +// SBBQ r64 m64 +func SBBQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SBBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SBBQ: bad operands") +} + +// SBBW: Subtract with Borrow. +// +// Forms: +// +// SBBW imm16 ax +// SBBW imm8 r16 +// SBBW imm16 r16 +// SBBW r16 r16 +// SBBW m16 r16 +// SBBW imm8 m16 +// SBBW imm16 m16 +// SBBW r16 m16 +func SBBW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SBBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SBBW: bad operands") +} + +// SETCC: Set byte if above or equal (CF == 0). +// +// Forms: +// +// SETCC r8 +// SETCC m8 +func SETCC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETCC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETCC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETCC: bad operands") +} + +// SETCS: Set byte if below (CF == 1). +// +// Forms: +// +// SETCS r8 +// SETCS m8 +func SETCS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETCS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETCS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETCS: bad operands") +} + +// SETEQ: Set byte if equal (ZF == 1). +// +// Forms: +// +// SETEQ r8 +// SETEQ m8 +func SETEQ(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETEQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETEQ", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETEQ: bad operands") +} + +// SETGE: Set byte if greater or equal (SF == OF). +// +// Forms: +// +// SETGE r8 +// SETGE m8 +func SETGE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETGE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETGE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETGE: bad operands") +} + +// SETGT: Set byte if greater (ZF == 0 and SF == OF). +// +// Forms: +// +// SETGT r8 +// SETGT m8 +func SETGT(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETGT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETGT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETGT: bad operands") +} + +// SETHI: Set byte if above (CF == 0 and ZF == 0). +// +// Forms: +// +// SETHI r8 +// SETHI m8 +func SETHI(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETHI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETHI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETHI: bad operands") +} + +// SETLE: Set byte if less or equal (ZF == 1 or SF != OF). +// +// Forms: +// +// SETLE r8 +// SETLE m8 +func SETLE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLE: bad operands") +} + +// SETLS: Set byte if below or equal (CF == 1 or ZF == 1). +// +// Forms: +// +// SETLS r8 +// SETLS m8 +func SETLS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLS: bad operands") +} + +// SETLT: Set byte if less (SF != OF). +// +// Forms: +// +// SETLT r8 +// SETLT m8 +func SETLT(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETLT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETLT", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETLT: bad operands") +} + +// SETMI: Set byte if sign (SF == 1). +// +// Forms: +// +// SETMI r8 +// SETMI m8 +func SETMI(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETMI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETMI", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETMI: bad operands") +} + +// SETNE: Set byte if not equal (ZF == 0). +// +// Forms: +// +// SETNE r8 +// SETNE m8 +func SETNE(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETNE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETNE", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETNE: bad operands") +} + +// SETOC: Set byte if not overflow (OF == 0). +// +// Forms: +// +// SETOC r8 +// SETOC m8 +func SETOC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETOC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETOC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETOC: bad operands") +} + +// SETOS: Set byte if overflow (OF == 1). +// +// Forms: +// +// SETOS r8 +// SETOS m8 +func SETOS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETOS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETOS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETOS: bad operands") +} + +// SETPC: Set byte if not parity (PF == 0). +// +// Forms: +// +// SETPC r8 +// SETPC m8 +func SETPC(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPC", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPC: bad operands") +} + +// SETPL: Set byte if not sign (SF == 0). +// +// Forms: +// +// SETPL r8 +// SETPL m8 +func SETPL(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPL", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPL: bad operands") +} + +// SETPS: Set byte if parity (PF == 1). +// +// Forms: +// +// SETPS r8 +// SETPS m8 +func SETPS(mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SETPS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SETPS", + Operands: []operand.Op{mr}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SETPS: bad operands") +} + +// SFENCE: Store Fence. +// +// Forms: +// +// SFENCE +func SFENCE() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "SFENCE", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// SHA1MSG1: Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG1 xmm xmm +// SHA1MSG1 m128 xmm +func SHA1MSG1(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA1MSG1: bad operands") +} + +// SHA1MSG2: Perform a Final Calculation for the Next Four SHA1 Message Doublewords. +// +// Forms: +// +// SHA1MSG2 xmm xmm +// SHA1MSG2 m128 xmm +func SHA1MSG2(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA1MSG2: bad operands") +} + +// SHA1NEXTE: Calculate SHA1 State Variable E after Four Rounds. +// +// Forms: +// +// SHA1NEXTE xmm xmm +// SHA1NEXTE m128 xmm +func SHA1NEXTE(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1NEXTE", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1NEXTE", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA1NEXTE: bad operands") +} + +// SHA1RNDS4: Perform Four Rounds of SHA1 Operation. +// +// Forms: +// +// SHA1RNDS4 imm2u xmm xmm +// SHA1RNDS4 imm2u m128 xmm +func SHA1RNDS4(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM2U(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1RNDS4", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM2U(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA1RNDS4", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA1RNDS4: bad operands") +} + +// SHA256MSG1: Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG1 xmm xmm +// SHA256MSG1 m128 xmm +func SHA256MSG1(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG1", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA256MSG1: bad operands") +} + +// SHA256MSG2: Perform a Final Calculation for the Next Four SHA256 Message Doublewords. +// +// Forms: +// +// SHA256MSG2 xmm xmm +// SHA256MSG2 m128 xmm +func SHA256MSG2(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHA256MSG2", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHA256MSG2: bad operands") +} + +// SHA256RNDS2: Perform Two Rounds of SHA256 Operation. +// +// Forms: +// +// SHA256RNDS2 xmm0 xmm xmm +// SHA256RNDS2 xmm0 m128 xmm +func SHA256RNDS2(x, mx, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM0(x) && operand.IsXMM(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "SHA256RNDS2", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsXMM0(x) && operand.IsM128(mx) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "SHA256RNDS2", + Operands: []operand.Op{x, mx, x1}, + Inputs: []operand.Op{x, mx, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("SHA256RNDS2: bad operands") +} + +// SHLB: Logical Shift Left. +// +// Forms: +// +// SHLB 1 r8 +// SHLB imm8 r8 +// SHLB cl r8 +// SHLB 1 m8 +// SHLB imm8 m8 +// SHLB cl m8 +func SHLB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHLB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SHLB: bad operands") +} + +// SHLL: Logical Shift Left. +// +// Forms: +// +// SHLL 1 r32 +// SHLL imm8 r32 +// SHLL cl r32 +// SHLL 1 m32 +// SHLL imm8 m32 +// SHLL cl m32 +// SHLL imm8 r32 r32 +// SHLL cl r32 r32 +// SHLL imm8 r32 m32 +// SHLL cl r32 m32 +func SHLL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLL: bad operands") +} + +// SHLQ: Logical Shift Left. +// +// Forms: +// +// SHLQ 1 r64 +// SHLQ imm8 r64 +// SHLQ cl r64 +// SHLQ 1 m64 +// SHLQ imm8 m64 +// SHLQ cl m64 +// SHLQ imm8 r64 r64 +// SHLQ cl r64 r64 +// SHLQ imm8 r64 m64 +// SHLQ cl r64 m64 +func SHLQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLQ: bad operands") +} + +// SHLW: Logical Shift Left. +// +// Forms: +// +// SHLW 1 r16 +// SHLW imm8 r16 +// SHLW cl r16 +// SHLW 1 m16 +// SHLW imm8 m16 +// SHLW cl m16 +// SHLW imm8 r16 r16 +// SHLW cl r16 r16 +// SHLW imm8 r16 m16 +// SHLW cl r16 m16 +func SHLW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHLW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHLW: bad operands") +} + +// SHLXL: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXL r32 r32 r32 +// SHLXL r32 m32 r32 +func SHLXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHLXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHLXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SHLXL: bad operands") +} + +// SHLXQ: Logical Shift Left Without Affecting Flags. +// +// Forms: +// +// SHLXQ r64 r64 r64 +// SHLXQ r64 m64 r64 +func SHLXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHLXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHLXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SHLXQ: bad operands") +} + +// SHRB: Logical Shift Right. +// +// Forms: +// +// SHRB 1 r8 +// SHRB imm8 r8 +// SHRB cl r8 +// SHRB 1 m8 +// SHRB imm8 m8 +// SHRB cl m8 +func SHRB(ci, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.Is1(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.Is1(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsCL(ci) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "SHRB", + Operands: []operand.Op{ci, mr}, + Inputs: []operand.Op{ci, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SHRB: bad operands") +} + +// SHRL: Logical Shift Right. +// +// Forms: +// +// SHRL 1 r32 +// SHRL imm8 r32 +// SHRL cl r32 +// SHRL 1 m32 +// SHRL imm8 m32 +// SHRL cl m32 +// SHRL imm8 r32 r32 +// SHRL cl r32 r32 +// SHRL imm8 r32 m32 +// SHRL cl r32 m32 +func SHRL(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsR32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR32(ops[1]) && operand.IsM32(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRL", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRL: bad operands") +} + +// SHRQ: Logical Shift Right. +// +// Forms: +// +// SHRQ 1 r64 +// SHRQ imm8 r64 +// SHRQ cl r64 +// SHRQ 1 m64 +// SHRQ imm8 m64 +// SHRQ cl m64 +// SHRQ imm8 r64 r64 +// SHRQ cl r64 r64 +// SHRQ imm8 r64 m64 +// SHRQ cl r64 m64 +func SHRQ(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsR64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR64(ops[1]) && operand.IsM64(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRQ", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRQ: bad operands") +} + +// SHRW: Logical Shift Right. +// +// Forms: +// +// SHRW 1 r16 +// SHRW imm8 r16 +// SHRW cl r16 +// SHRW 1 m16 +// SHRW imm8 m16 +// SHRW cl m16 +// SHRW imm8 r16 r16 +// SHRW cl r16 r16 +// SHRW imm8 r16 m16 +// SHRW cl r16 m16 +func SHRW(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.Is1(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsIMM8(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsCL(ops[0]) && operand.IsM16(ops[1]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsR16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsIMM8(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + case len(ops) == 3 && operand.IsCL(ops[0]) && operand.IsR16(ops[1]) && operand.IsM16(ops[2]): + return &intrep.Instruction{ + Opcode: "SHRW", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1], ops[2]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("SHRW: bad operands") +} + +// SHRXL: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXL r32 r32 r32 +// SHRXL r32 m32 r32 +func SHRXL(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHRXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr) && operand.IsR32(r1): + return &intrep.Instruction{ + Opcode: "SHRXL", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SHRXL: bad operands") +} + +// SHRXQ: Logical Shift Right Without Affecting Flags. +// +// Forms: +// +// SHRXQ r64 r64 r64 +// SHRXQ r64 m64 r64 +func SHRXQ(r, mr, r1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHRXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr) && operand.IsR64(r1): + return &intrep.Instruction{ + Opcode: "SHRXQ", + Operands: []operand.Op{r, mr, r1}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r1}, + }, nil + } + return nil, errors.New("SHRXQ: bad operands") +} + +// SHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPD imm8 xmm xmm +// SHUFPD imm8 m128 xmm +func SHUFPD(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPD", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHUFPD: bad operands") +} + +// SHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SHUFPS imm8 xmm xmm +// SHUFPS imm8 m128 xmm +func SHUFPS(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SHUFPS", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SHUFPS: bad operands") +} + +// SQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPD xmm xmm +// SQRTPD m128 xmm +func SQRTPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SQRTPD: bad operands") +} + +// SQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SQRTPS xmm xmm +// SQRTPS m128 xmm +func SQRTPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SQRTPS: bad operands") +} + +// SQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSD xmm xmm +// SQRTSD m64 xmm +func SQRTSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SQRTSD: bad operands") +} + +// SQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// SQRTSS xmm xmm +// SQRTSS m32 xmm +func SQRTSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SQRTSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SQRTSS: bad operands") +} + +// STC: Set Carry Flag. +// +// Forms: +// +// STC +func STC() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "STC", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// STD: Set Direction Flag. +// +// Forms: +// +// STD +func STD() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "STD", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// STMXCSR: Store MXCSR Register State. +// +// Forms: +// +// STMXCSR m32 +func STMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "STMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("STMXCSR: bad operands") +} + +// SUBB: Subtract. +// +// Forms: +// +// SUBB imm8 al +// SUBB imm8 r8 +// SUBB r8 r8 +// SUBB m8 r8 +// SUBB imm8 m8 +// SUBB r8 m8 +func SUBB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "SUBB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SUBB: bad operands") +} + +// SUBL: Subtract. +// +// Forms: +// +// SUBL imm32 eax +// SUBL imm8 r32 +// SUBL imm32 r32 +// SUBL r32 r32 +// SUBL m32 r32 +// SUBL imm8 m32 +// SUBL imm32 m32 +// SUBL r32 m32 +func SUBL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "SUBL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("SUBL: bad operands") +} + +// SUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBPD xmm xmm +// SUBPD m128 xmm +func SUBPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SUBPD: bad operands") +} + +// SUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBPS xmm xmm +// SUBPS m128 xmm +func SUBPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SUBPS: bad operands") +} + +// SUBQ: Subtract. +// +// Forms: +// +// SUBQ imm32 rax +// SUBQ imm8 r64 +// SUBQ imm32 r64 +// SUBQ r64 r64 +// SUBQ m64 r64 +// SUBQ imm8 m64 +// SUBQ imm32 m64 +// SUBQ r64 m64 +func SUBQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "SUBQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("SUBQ: bad operands") +} + +// SUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// SUBSD xmm xmm +// SUBSD m64 xmm +func SUBSD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SUBSD: bad operands") +} + +// SUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// SUBSS xmm xmm +// SUBSS m32 xmm +func SUBSS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "SUBSS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("SUBSS: bad operands") +} + +// SUBW: Subtract. +// +// Forms: +// +// SUBW imm16 ax +// SUBW imm8 r16 +// SUBW imm16 r16 +// SUBW r16 r16 +// SUBW m16 r16 +// SUBW imm8 m16 +// SUBW imm16 m16 +// SUBW r16 m16 +func SUBW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "SUBW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("SUBW: bad operands") +} + +// SYSCALL: Fast System Call. +// +// Forms: +// +// SYSCALL +func SYSCALL() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "SYSCALL", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{reg.R11, reg.RCX}, + }, nil +} + +// TESTB: Logical Compare. +// +// Forms: +// +// TESTB imm8 al +// TESTB imm8 r8 +// TESTB r8 r8 +// TESTB imm8 m8 +// TESTB r8 m8 +func TESTB(ir, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(ir) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(ir) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM8(ir) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR8(ir) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "TESTB", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTB: bad operands") +} + +// TESTL: Logical Compare. +// +// Forms: +// +// TESTL imm32 eax +// TESTL imm32 r32 +// TESTL r32 r32 +// TESTL imm32 m32 +// TESTL r32 m32 +func TESTL(ir, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(ir) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{ir, emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR32(ir) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "TESTL", + Operands: []operand.Op{ir, emr}, + Inputs: []operand.Op{ir, emr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTL: bad operands") +} + +// TESTQ: Logical Compare. +// +// Forms: +// +// TESTQ imm32 rax +// TESTQ imm32 r64 +// TESTQ r64 r64 +// TESTQ imm32 m64 +// TESTQ r64 m64 +func TESTQ(ir, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(ir) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM32(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR64(ir) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "TESTQ", + Operands: []operand.Op{ir, mr}, + Inputs: []operand.Op{ir, mr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTQ: bad operands") +} + +// TESTW: Logical Compare. +// +// Forms: +// +// TESTW imm16 ax +// TESTW imm16 r16 +// TESTW r16 r16 +// TESTW imm16 m16 +// TESTW r16 m16 +func TESTW(ir, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(ir) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM16(ir) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsIMM16(ir) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{}, + }, nil + case operand.IsR16(ir) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "TESTW", + Operands: []operand.Op{ir, amr}, + Inputs: []operand.Op{ir, amr}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("TESTW: bad operands") +} + +// TZCNTL: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTL r32 r32 +// TZCNTL m32 r32 +func TZCNTL(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "TZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mr) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "TZCNTL", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("TZCNTL: bad operands") +} + +// TZCNTQ: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTQ r64 r64 +// TZCNTQ m64 r64 +func TZCNTQ(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "TZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mr) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "TZCNTQ", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("TZCNTQ: bad operands") +} + +// TZCNTW: Count the Number of Trailing Zero Bits. +// +// Forms: +// +// TZCNTW r16 r16 +// TZCNTW m16 r16 +func TZCNTW(mr, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "TZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM16(mr) && operand.IsR16(r): + return &intrep.Instruction{ + Opcode: "TZCNTW", + Operands: []operand.Op{mr, r}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("TZCNTW: bad operands") +} + +// UCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISD xmm xmm +// UCOMISD m64 xmm +func UCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("UCOMISD: bad operands") +} + +// UCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// UCOMISS xmm xmm +// UCOMISS m32 xmm +func UCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("UCOMISS: bad operands") +} + +// UD2: Undefined Instruction. +// +// Forms: +// +// UD2 +func UD2() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "UD2", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// UNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPD xmm xmm +// UNPCKHPD m128 xmm +func UNPCKHPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("UNPCKHPD: bad operands") +} + +// UNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKHPS xmm xmm +// UNPCKHPS m128 xmm +func UNPCKHPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKHPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("UNPCKHPS: bad operands") +} + +// UNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPD xmm xmm +// UNPCKLPD m128 xmm +func UNPCKLPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("UNPCKLPD: bad operands") +} + +// UNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// UNPCKLPS xmm xmm +// UNPCKLPS m128 xmm +func UNPCKLPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "UNPCKLPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("UNPCKLPS: bad operands") +} + +// VADDPD: Add Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDPD xmm xmm xmm +// VADDPD m128 xmm xmm +// VADDPD ymm ymm ymm +// VADDPD m256 ymm ymm +func VADDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VADDPD: bad operands") +} + +// VADDPS: Add Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDPS xmm xmm xmm +// VADDPS m128 xmm xmm +// VADDPS ymm ymm ymm +// VADDPS m256 ymm ymm +func VADDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VADDPS: bad operands") +} + +// VADDSD: Add Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VADDSD xmm xmm xmm +// VADDSD m64 xmm xmm +func VADDSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VADDSD: bad operands") +} + +// VADDSS: Add Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VADDSS xmm xmm xmm +// VADDSS m32 xmm xmm +func VADDSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VADDSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VADDSS: bad operands") +} + +// VADDSUBPD: Packed Double-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPD xmm xmm xmm +// VADDSUBPD m128 xmm xmm +// VADDSUBPD ymm ymm ymm +// VADDSUBPD m256 ymm ymm +func VADDSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VADDSUBPD: bad operands") +} + +// VADDSUBPS: Packed Single-FP Add/Subtract. +// +// Forms: +// +// VADDSUBPS xmm xmm xmm +// VADDSUBPS m128 xmm xmm +// VADDSUBPS ymm ymm ymm +// VADDSUBPS m256 ymm ymm +func VADDSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VADDSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VADDSUBPS: bad operands") +} + +// VAESDEC: Perform One Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDEC xmm xmm xmm +// VAESDEC m128 xmm xmm +func VAESDEC(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDEC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDEC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VAESDEC: bad operands") +} + +// VAESDECLAST: Perform Last Round of an AES Decryption Flow. +// +// Forms: +// +// VAESDECLAST xmm xmm xmm +// VAESDECLAST m128 xmm xmm +func VAESDECLAST(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDECLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESDECLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VAESDECLAST: bad operands") +} + +// VAESENC: Perform One Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENC xmm xmm xmm +// VAESENC m128 xmm xmm +func VAESENC(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENC", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VAESENC: bad operands") +} + +// VAESENCLAST: Perform Last Round of an AES Encryption Flow. +// +// Forms: +// +// VAESENCLAST xmm xmm xmm +// VAESENCLAST m128 xmm xmm +func VAESENCLAST(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENCLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VAESENCLAST", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VAESENCLAST: bad operands") +} + +// VAESIMC: Perform the AES InvMixColumn Transformation. +// +// Forms: +// +// VAESIMC xmm xmm +// VAESIMC m128 xmm +func VAESIMC(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESIMC", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VAESIMC: bad operands") +} + +// VAESKEYGENASSIST: AES Round Key Generation Assist. +// +// Forms: +// +// VAESKEYGENASSIST imm8 xmm xmm +// VAESKEYGENASSIST imm8 m128 xmm +func VAESKEYGENASSIST(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VAESKEYGENASSIST", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VAESKEYGENASSIST: bad operands") +} + +// VANDNPD: Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPD xmm xmm xmm +// VANDNPD m128 xmm xmm +// VANDNPD ymm ymm ymm +// VANDNPD m256 ymm ymm +func VANDNPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VANDNPD: bad operands") +} + +// VANDNPS: Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDNPS xmm xmm xmm +// VANDNPS m128 xmm xmm +// VANDNPS ymm ymm ymm +// VANDNPS m256 ymm ymm +func VANDNPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDNPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VANDNPS: bad operands") +} + +// VANDPD: Bitwise Logical AND of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VANDPD xmm xmm xmm +// VANDPD m128 xmm xmm +// VANDPD ymm ymm ymm +// VANDPD m256 ymm ymm +func VANDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VANDPD: bad operands") +} + +// VANDPS: Bitwise Logical AND of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VANDPS xmm xmm xmm +// VANDPS m128 xmm xmm +// VANDPS ymm ymm ymm +// VANDPS m256 ymm ymm +func VANDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VANDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VANDPS: bad operands") +} + +// VBLENDPD: Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPD imm8 xmm xmm xmm +// VBLENDPD imm8 m128 xmm xmm +// VBLENDPD imm8 ymm ymm ymm +// VBLENDPD imm8 m256 ymm ymm +func VBLENDPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VBLENDPD: bad operands") +} + +// VBLENDPS: Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDPS imm8 xmm xmm xmm +// VBLENDPS imm8 m128 xmm xmm +// VBLENDPS imm8 ymm ymm ymm +// VBLENDPS imm8 m256 ymm ymm +func VBLENDPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VBLENDPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VBLENDPS: bad operands") +} + +// VBLENDVPD: Variable Blend Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPD xmm xmm xmm xmm +// VBLENDVPD xmm m128 xmm xmm +// VBLENDVPD ymm ymm ymm ymm +// VBLENDVPD ymm m256 ymm ymm +func VBLENDVPD(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPD", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + } + return nil, errors.New("VBLENDVPD: bad operands") +} + +// VBLENDVPS: Variable Blend Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VBLENDVPS xmm xmm xmm xmm +// VBLENDVPS xmm m128 xmm xmm +// VBLENDVPS ymm ymm ymm ymm +// VBLENDVPS ymm m256 ymm ymm +func VBLENDVPS(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VBLENDVPS", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + } + return nil, errors.New("VBLENDVPS: bad operands") +} + +// VBROADCASTF128: Broadcast 128 Bit of Floating-Point Data. +// +// Forms: +// +// VBROADCASTF128 m128 ymm +func VBROADCASTF128(m, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTF128", + Operands: []operand.Op{m, y}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{y}, + }, nil + } + return nil, errors.New("VBROADCASTF128: bad operands") +} + +// VBROADCASTI128: Broadcast 128 Bits of Integer Data. +// +// Forms: +// +// VBROADCASTI128 m128 ymm +func VBROADCASTI128(m, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTI128", + Operands: []operand.Op{m, y}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{y}, + }, nil + } + return nil, errors.New("VBROADCASTI128: bad operands") +} + +// VBROADCASTSD: Broadcast Double-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSD xmm ymm +// VBROADCASTSD m64 ymm +func VBROADCASTSD(mx, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTSD", + Operands: []operand.Op{mx, y}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{y}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VBROADCASTSD", + Operands: []operand.Op{mx, y}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{y}, + }, nil + } + return nil, errors.New("VBROADCASTSD: bad operands") +} + +// VBROADCASTSS: Broadcast Single-Precision Floating-Point Element. +// +// Forms: +// +// VBROADCASTSS xmm xmm +// VBROADCASTSS m32 xmm +// VBROADCASTSS xmm ymm +// VBROADCASTSS m32 ymm +func VBROADCASTSS(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VBROADCASTSS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VBROADCASTSS: bad operands") +} + +// VCMPPD: Compare Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPD imm8 xmm xmm xmm +// VCMPPD imm8 m128 xmm xmm +// VCMPPD imm8 ymm ymm ymm +// VCMPPD imm8 m256 ymm ymm +func VCMPPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VCMPPD: bad operands") +} + +// VCMPPS: Compare Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPPS imm8 xmm xmm xmm +// VCMPPS imm8 m128 xmm xmm +// VCMPPS imm8 ymm ymm ymm +// VCMPPS imm8 m256 ymm ymm +func VCMPPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VCMPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VCMPPS: bad operands") +} + +// VCMPSD: Compare Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSD imm8 xmm xmm xmm +// VCMPSD imm8 m64 xmm xmm +func VCMPSD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCMPSD: bad operands") +} + +// VCMPSS: Compare Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VCMPSS imm8 xmm xmm xmm +// VCMPSS imm8 m32 xmm xmm +func VCMPSS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCMPSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCMPSS: bad operands") +} + +// VCOMISD: Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISD xmm xmm +// VCOMISD m64 xmm +func VCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VCOMISD: bad operands") +} + +// VCOMISS: Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VCOMISS xmm xmm +// VCOMISS m32 xmm +func VCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VCOMISS: bad operands") +} + +// VCVTDQ2PD: Convert Packed Dword Integers to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PD xmm xmm +// VCVTDQ2PD m64 xmm +// VCVTDQ2PD xmm ymm +// VCVTDQ2PD m128 ymm +func VCVTDQ2PD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTDQ2PD: bad operands") +} + +// VCVTDQ2PS: Convert Packed Dword Integers to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTDQ2PS xmm xmm +// VCVTDQ2PS m128 xmm +// VCVTDQ2PS ymm ymm +// VCVTDQ2PS m256 ymm +func VCVTDQ2PS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTDQ2PS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTDQ2PS: bad operands") +} + +// VCVTPD2DQX: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQX xmm xmm +// VCVTPD2DQX m128 xmm +func VCVTPD2DQX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTPD2DQX: bad operands") +} + +// VCVTPD2DQY: Convert Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPD2DQY ymm xmm +// VCVTPD2DQY m256 xmm +func VCVTPD2DQY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTPD2DQY: bad operands") +} + +// VCVTPD2PSX: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSX xmm xmm +// VCVTPD2PSX m128 xmm +func VCVTPD2PSX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTPD2PSX: bad operands") +} + +// VCVTPD2PSY: Convert Packed Double-Precision FP Values to Packed Single-Precision FP Values. +// +// Forms: +// +// VCVTPD2PSY ymm xmm +// VCVTPD2PSY m256 xmm +func VCVTPD2PSY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTPD2PSY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTPD2PSY: bad operands") +} + +// VCVTPH2PS: Convert Half-Precision FP Values to Single-Precision FP Values. +// +// Forms: +// +// VCVTPH2PS xmm xmm +// VCVTPH2PS m64 xmm +// VCVTPH2PS xmm ymm +// VCVTPH2PS m128 ymm +func VCVTPH2PS(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPH2PS", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTPH2PS: bad operands") +} + +// VCVTPS2DQ: Convert Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTPS2DQ xmm xmm +// VCVTPS2DQ m128 xmm +// VCVTPS2DQ ymm ymm +// VCVTPS2DQ m256 ymm +func VCVTPS2DQ(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTPS2DQ: bad operands") +} + +// VCVTPS2PD: Convert Packed Single-Precision FP Values to Packed Double-Precision FP Values. +// +// Forms: +// +// VCVTPS2PD xmm xmm +// VCVTPS2PD m64 xmm +// VCVTPS2PD xmm ymm +// VCVTPS2PD m128 ymm +func VCVTPS2PD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTPS2PD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTPS2PD: bad operands") +} + +// VCVTPS2PH: Convert Single-Precision FP value to Half-Precision FP value. +// +// Forms: +// +// VCVTPS2PH imm8 xmm xmm +// VCVTPS2PH imm8 ymm xmm +// VCVTPS2PH imm8 xmm m64 +// VCVTPS2PH imm8 ymm m128 +func VCVTPS2PH(i, xy, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsM64(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VCVTPS2PH", + Operands: []operand.Op{i, xy, mx}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{mx}, + }, nil + } + return nil, errors.New("VCVTPS2PH: bad operands") +} + +// VCVTSD2SI: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SI xmm r32 +// VCVTSD2SI m64 r32 +func VCVTSD2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTSD2SI: bad operands") +} + +// VCVTSD2SIQ: Convert Scalar Double-Precision FP Value to Integer. +// +// Forms: +// +// VCVTSD2SIQ xmm r64 +// VCVTSD2SIQ m64 r64 +func VCVTSD2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTSD2SIQ: bad operands") +} + +// VCVTSD2SS: Convert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSD2SS xmm xmm xmm +// VCVTSD2SS m64 xmm xmm +func VCVTSD2SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSD2SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSD2SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSD2SS: bad operands") +} + +// VCVTSI2SDL: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDL r32 xmm xmm +// VCVTSI2SDL m32 xmm xmm +func VCVTSI2SDL(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSI2SDL: bad operands") +} + +// VCVTSI2SDQ: Convert Dword Integer to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSI2SDQ r64 xmm xmm +// VCVTSI2SDQ m64 xmm xmm +func VCVTSI2SDQ(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SDQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSI2SDQ: bad operands") +} + +// VCVTSI2SSL: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSL r32 xmm xmm +// VCVTSI2SSL m32 xmm xmm +func VCVTSI2SSL(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSL", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSI2SSL: bad operands") +} + +// VCVTSI2SSQ: Convert Dword Integer to Scalar Single-Precision FP Value. +// +// Forms: +// +// VCVTSI2SSQ r64 xmm xmm +// VCVTSI2SSQ m64 xmm xmm +func VCVTSI2SSQ(mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSI2SSQ", + Operands: []operand.Op{mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSI2SSQ: bad operands") +} + +// VCVTSS2SD: Convert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value. +// +// Forms: +// +// VCVTSS2SD xmm xmm xmm +// VCVTSS2SD m32 xmm xmm +func VCVTSS2SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSS2SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VCVTSS2SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VCVTSS2SD: bad operands") +} + +// VCVTSS2SI: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SI xmm r32 +// VCVTSS2SI m32 r32 +func VCVTSS2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTSS2SI: bad operands") +} + +// VCVTSS2SIQ: Convert Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTSS2SIQ xmm r64 +// VCVTSS2SIQ m32 r64 +func VCVTSS2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTSS2SIQ: bad operands") +} + +// VCVTTPD2DQX: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQX xmm xmm +// VCVTTPD2DQX m128 xmm +func VCVTTPD2DQX(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQX", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTTPD2DQX: bad operands") +} + +// VCVTTPD2DQY: Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPD2DQY ymm xmm +// VCVTTPD2DQY m256 xmm +func VCVTTPD2DQY(my, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM256(my) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VCVTTPD2DQY", + Operands: []operand.Op{my, x}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VCVTTPD2DQY: bad operands") +} + +// VCVTTPS2DQ: Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers. +// +// Forms: +// +// VCVTTPS2DQ xmm xmm +// VCVTTPS2DQ m128 xmm +// VCVTTPS2DQ ymm ymm +// VCVTTPS2DQ m256 ymm +func VCVTTPS2DQ(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VCVTTPS2DQ", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VCVTTPS2DQ: bad operands") +} + +// VCVTTSD2SI: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SI xmm r32 +// VCVTTSD2SI m64 r32 +func VCVTTSD2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTTSD2SI: bad operands") +} + +// VCVTTSD2SIQ: Convert with Truncation Scalar Double-Precision FP Value to Signed Integer. +// +// Forms: +// +// VCVTTSD2SIQ xmm r64 +// VCVTTSD2SIQ m64 r64 +func VCVTTSD2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM64(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSD2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTTSD2SIQ: bad operands") +} + +// VCVTTSS2SI: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SI xmm r32 +// VCVTTSS2SI m32 r32 +func VCVTTSS2SI(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SI", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTTSS2SI: bad operands") +} + +// VCVTTSS2SIQ: Convert with Truncation Scalar Single-Precision FP Value to Dword Integer. +// +// Forms: +// +// VCVTTSS2SIQ xmm r64 +// VCVTTSS2SIQ m32 r64 +func VCVTTSS2SIQ(mx, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsM32(mx) && operand.IsR64(r): + return &intrep.Instruction{ + Opcode: "VCVTTSS2SIQ", + Operands: []operand.Op{mx, r}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VCVTTSS2SIQ: bad operands") +} + +// VDIVPD: Divide Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPD xmm xmm xmm +// VDIVPD m128 xmm xmm +// VDIVPD ymm ymm ymm +// VDIVPD m256 ymm ymm +func VDIVPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VDIVPD: bad operands") +} + +// VDIVPS: Divide Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVPS xmm xmm xmm +// VDIVPS m128 xmm xmm +// VDIVPS ymm ymm ymm +// VDIVPS m256 ymm ymm +func VDIVPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDIVPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VDIVPS: bad operands") +} + +// VDIVSD: Divide Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSD xmm xmm xmm +// VDIVSD m64 xmm xmm +func VDIVSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VDIVSD: bad operands") +} + +// VDIVSS: Divide Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VDIVSS xmm xmm xmm +// VDIVSS m32 xmm xmm +func VDIVSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDIVSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VDIVSS: bad operands") +} + +// VDPPD: Dot Product of Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VDPPD imm8 xmm xmm xmm +// VDPPD imm8 m128 xmm xmm +func VDPPD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDPPD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VDPPD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VDPPD: bad operands") +} + +// VDPPS: Dot Product of Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VDPPS imm8 xmm xmm xmm +// VDPPS imm8 m128 xmm xmm +// VDPPS imm8 ymm ymm ymm +// VDPPS imm8 m256 ymm ymm +func VDPPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VDPPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VDPPS: bad operands") +} + +// VEXTRACTF128: Extract Packed Floating-Point Values. +// +// Forms: +// +// VEXTRACTF128 imm8 ymm xmm +// VEXTRACTF128 imm8 ymm m128 +func VEXTRACTF128(i, y, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTF128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTF128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + }, nil + } + return nil, errors.New("VEXTRACTF128: bad operands") +} + +// VEXTRACTI128: Extract Packed Integer Values. +// +// Forms: +// +// VEXTRACTI128 imm8 ymm xmm +// VEXTRACTI128 imm8 ymm m128 +func VEXTRACTI128(i, y, mx operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsXMM(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTI128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(y) && operand.IsM128(mx): + return &intrep.Instruction{ + Opcode: "VEXTRACTI128", + Operands: []operand.Op{i, y, mx}, + Inputs: []operand.Op{y}, + Outputs: []operand.Op{mx}, + }, nil + } + return nil, errors.New("VEXTRACTI128: bad operands") +} + +// VEXTRACTPS: Extract Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VEXTRACTPS imm8 xmm r32 +// VEXTRACTPS imm8 xmm m32 +func VEXTRACTPS(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VEXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "VEXTRACTPS", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("VEXTRACTPS: bad operands") +} + +// VFMADD132PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PD xmm xmm xmm +// VFMADD132PD m128 xmm xmm +// VFMADD132PD ymm ymm ymm +// VFMADD132PD m256 ymm ymm +func VFMADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD132PD: bad operands") +} + +// VFMADD132PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132PS xmm xmm xmm +// VFMADD132PS m128 xmm xmm +// VFMADD132PS ymm ymm ymm +// VFMADD132PS m256 ymm ymm +func VFMADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD132PS: bad operands") +} + +// VFMADD132SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SD xmm xmm xmm +// VFMADD132SD m64 xmm xmm +func VFMADD132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD132SD: bad operands") +} + +// VFMADD132SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD132SS xmm xmm xmm +// VFMADD132SS m32 xmm xmm +func VFMADD132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD132SS: bad operands") +} + +// VFMADD213PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PD xmm xmm xmm +// VFMADD213PD m128 xmm xmm +// VFMADD213PD ymm ymm ymm +// VFMADD213PD m256 ymm ymm +func VFMADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD213PD: bad operands") +} + +// VFMADD213PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213PS xmm xmm xmm +// VFMADD213PS m128 xmm xmm +// VFMADD213PS ymm ymm ymm +// VFMADD213PS m256 ymm ymm +func VFMADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD213PS: bad operands") +} + +// VFMADD213SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SD xmm xmm xmm +// VFMADD213SD m64 xmm xmm +func VFMADD213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD213SD: bad operands") +} + +// VFMADD213SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD213SS xmm xmm xmm +// VFMADD213SS m32 xmm xmm +func VFMADD213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD213SS: bad operands") +} + +// VFMADD231PD: Fused Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PD xmm xmm xmm +// VFMADD231PD m128 xmm xmm +// VFMADD231PD ymm ymm ymm +// VFMADD231PD m256 ymm ymm +func VFMADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD231PD: bad operands") +} + +// VFMADD231PS: Fused Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231PS xmm xmm xmm +// VFMADD231PS m128 xmm xmm +// VFMADD231PS ymm ymm ymm +// VFMADD231PS m256 ymm ymm +func VFMADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADD231PS: bad operands") +} + +// VFMADD231SD: Fused Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SD xmm xmm xmm +// VFMADD231SD m64 xmm xmm +func VFMADD231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD231SD: bad operands") +} + +// VFMADD231SS: Fused Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADD231SS xmm xmm xmm +// VFMADD231SS m32 xmm xmm +func VFMADD231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMADD231SS: bad operands") +} + +// VFMADDSUB132PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PD xmm xmm xmm +// VFMADDSUB132PD m128 xmm xmm +// VFMADDSUB132PD ymm ymm ymm +// VFMADDSUB132PD m256 ymm ymm +func VFMADDSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB132PD: bad operands") +} + +// VFMADDSUB132PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB132PS xmm xmm xmm +// VFMADDSUB132PS m128 xmm xmm +// VFMADDSUB132PS ymm ymm ymm +// VFMADDSUB132PS m256 ymm ymm +func VFMADDSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB132PS: bad operands") +} + +// VFMADDSUB213PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PD xmm xmm xmm +// VFMADDSUB213PD m128 xmm xmm +// VFMADDSUB213PD ymm ymm ymm +// VFMADDSUB213PD m256 ymm ymm +func VFMADDSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB213PD: bad operands") +} + +// VFMADDSUB213PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB213PS xmm xmm xmm +// VFMADDSUB213PS m128 xmm xmm +// VFMADDSUB213PS ymm ymm ymm +// VFMADDSUB213PS m256 ymm ymm +func VFMADDSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB213PS: bad operands") +} + +// VFMADDSUB231PD: Fused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PD xmm xmm xmm +// VFMADDSUB231PD m128 xmm xmm +// VFMADDSUB231PD ymm ymm ymm +// VFMADDSUB231PD m256 ymm ymm +func VFMADDSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB231PD: bad operands") +} + +// VFMADDSUB231PS: Fused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMADDSUB231PS xmm xmm xmm +// VFMADDSUB231PS m128 xmm xmm +// VFMADDSUB231PS ymm ymm ymm +// VFMADDSUB231PS m256 ymm ymm +func VFMADDSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMADDSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMADDSUB231PS: bad operands") +} + +// VFMSUB132PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PD xmm xmm xmm +// VFMSUB132PD m128 xmm xmm +// VFMSUB132PD ymm ymm ymm +// VFMSUB132PD m256 ymm ymm +func VFMSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB132PD: bad operands") +} + +// VFMSUB132PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132PS xmm xmm xmm +// VFMSUB132PS m128 xmm xmm +// VFMSUB132PS ymm ymm ymm +// VFMSUB132PS m256 ymm ymm +func VFMSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB132PS: bad operands") +} + +// VFMSUB132SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SD xmm xmm xmm +// VFMSUB132SD m64 xmm xmm +func VFMSUB132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB132SD: bad operands") +} + +// VFMSUB132SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB132SS xmm xmm xmm +// VFMSUB132SS m32 xmm xmm +func VFMSUB132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB132SS: bad operands") +} + +// VFMSUB213PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PD xmm xmm xmm +// VFMSUB213PD m128 xmm xmm +// VFMSUB213PD ymm ymm ymm +// VFMSUB213PD m256 ymm ymm +func VFMSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB213PD: bad operands") +} + +// VFMSUB213PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213PS xmm xmm xmm +// VFMSUB213PS m128 xmm xmm +// VFMSUB213PS ymm ymm ymm +// VFMSUB213PS m256 ymm ymm +func VFMSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB213PS: bad operands") +} + +// VFMSUB213SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SD xmm xmm xmm +// VFMSUB213SD m64 xmm xmm +func VFMSUB213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB213SD: bad operands") +} + +// VFMSUB213SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB213SS xmm xmm xmm +// VFMSUB213SS m32 xmm xmm +func VFMSUB213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB213SS: bad operands") +} + +// VFMSUB231PD: Fused Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PD xmm xmm xmm +// VFMSUB231PD m128 xmm xmm +// VFMSUB231PD ymm ymm ymm +// VFMSUB231PD m256 ymm ymm +func VFMSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB231PD: bad operands") +} + +// VFMSUB231PS: Fused Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231PS xmm xmm xmm +// VFMSUB231PS m128 xmm xmm +// VFMSUB231PS ymm ymm ymm +// VFMSUB231PS m256 ymm ymm +func VFMSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUB231PS: bad operands") +} + +// VFMSUB231SD: Fused Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SD xmm xmm xmm +// VFMSUB231SD m64 xmm xmm +func VFMSUB231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB231SD: bad operands") +} + +// VFMSUB231SS: Fused Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUB231SS xmm xmm xmm +// VFMSUB231SS m32 xmm xmm +func VFMSUB231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFMSUB231SS: bad operands") +} + +// VFMSUBADD132PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PD xmm xmm xmm +// VFMSUBADD132PD m128 xmm xmm +// VFMSUBADD132PD ymm ymm ymm +// VFMSUBADD132PD m256 ymm ymm +func VFMSUBADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD132PD: bad operands") +} + +// VFMSUBADD132PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD132PS xmm xmm xmm +// VFMSUBADD132PS m128 xmm xmm +// VFMSUBADD132PS ymm ymm ymm +// VFMSUBADD132PS m256 ymm ymm +func VFMSUBADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD132PS: bad operands") +} + +// VFMSUBADD213PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PD xmm xmm xmm +// VFMSUBADD213PD m128 xmm xmm +// VFMSUBADD213PD ymm ymm ymm +// VFMSUBADD213PD m256 ymm ymm +func VFMSUBADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD213PD: bad operands") +} + +// VFMSUBADD213PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD213PS xmm xmm xmm +// VFMSUBADD213PS m128 xmm xmm +// VFMSUBADD213PS ymm ymm ymm +// VFMSUBADD213PS m256 ymm ymm +func VFMSUBADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD213PS: bad operands") +} + +// VFMSUBADD231PD: Fused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PD xmm xmm xmm +// VFMSUBADD231PD m128 xmm xmm +// VFMSUBADD231PD ymm ymm ymm +// VFMSUBADD231PD m256 ymm ymm +func VFMSUBADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD231PD: bad operands") +} + +// VFMSUBADD231PS: Fused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFMSUBADD231PS xmm xmm xmm +// VFMSUBADD231PS m128 xmm xmm +// VFMSUBADD231PS ymm ymm ymm +// VFMSUBADD231PS m256 ymm ymm +func VFMSUBADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFMSUBADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFMSUBADD231PS: bad operands") +} + +// VFNMADD132PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PD xmm xmm xmm +// VFNMADD132PD m128 xmm xmm +// VFNMADD132PD ymm ymm ymm +// VFNMADD132PD m256 ymm ymm +func VFNMADD132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD132PD: bad operands") +} + +// VFNMADD132PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132PS xmm xmm xmm +// VFNMADD132PS m128 xmm xmm +// VFNMADD132PS ymm ymm ymm +// VFNMADD132PS m256 ymm ymm +func VFNMADD132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD132PS: bad operands") +} + +// VFNMADD132SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SD xmm xmm xmm +// VFNMADD132SD m64 xmm xmm +func VFNMADD132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD132SD: bad operands") +} + +// VFNMADD132SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD132SS xmm xmm xmm +// VFNMADD132SS m32 xmm xmm +func VFNMADD132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD132SS: bad operands") +} + +// VFNMADD213PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PD xmm xmm xmm +// VFNMADD213PD m128 xmm xmm +// VFNMADD213PD ymm ymm ymm +// VFNMADD213PD m256 ymm ymm +func VFNMADD213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD213PD: bad operands") +} + +// VFNMADD213PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213PS xmm xmm xmm +// VFNMADD213PS m128 xmm xmm +// VFNMADD213PS ymm ymm ymm +// VFNMADD213PS m256 ymm ymm +func VFNMADD213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD213PS: bad operands") +} + +// VFNMADD213SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SD xmm xmm xmm +// VFNMADD213SD m64 xmm xmm +func VFNMADD213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD213SD: bad operands") +} + +// VFNMADD213SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD213SS xmm xmm xmm +// VFNMADD213SS m32 xmm xmm +func VFNMADD213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD213SS: bad operands") +} + +// VFNMADD231PD: Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PD xmm xmm xmm +// VFNMADD231PD m128 xmm xmm +// VFNMADD231PD ymm ymm ymm +// VFNMADD231PD m256 ymm ymm +func VFNMADD231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD231PD: bad operands") +} + +// VFNMADD231PS: Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231PS xmm xmm xmm +// VFNMADD231PS m128 xmm xmm +// VFNMADD231PS ymm ymm ymm +// VFNMADD231PS m256 ymm ymm +func VFNMADD231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMADD231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMADD231PS: bad operands") +} + +// VFNMADD231SD: Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SD xmm xmm xmm +// VFNMADD231SD m64 xmm xmm +func VFNMADD231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD231SD: bad operands") +} + +// VFNMADD231SS: Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMADD231SS xmm xmm xmm +// VFNMADD231SS m32 xmm xmm +func VFNMADD231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMADD231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMADD231SS: bad operands") +} + +// VFNMSUB132PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PD xmm xmm xmm +// VFNMSUB132PD m128 xmm xmm +// VFNMSUB132PD ymm ymm ymm +// VFNMSUB132PD m256 ymm ymm +func VFNMSUB132PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB132PD: bad operands") +} + +// VFNMSUB132PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132PS xmm xmm xmm +// VFNMSUB132PS m128 xmm xmm +// VFNMSUB132PS ymm ymm ymm +// VFNMSUB132PS m256 ymm ymm +func VFNMSUB132PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB132PS: bad operands") +} + +// VFNMSUB132SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SD xmm xmm xmm +// VFNMSUB132SD m64 xmm xmm +func VFNMSUB132SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB132SD: bad operands") +} + +// VFNMSUB132SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB132SS xmm xmm xmm +// VFNMSUB132SS m32 xmm xmm +func VFNMSUB132SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB132SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB132SS: bad operands") +} + +// VFNMSUB213PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PD xmm xmm xmm +// VFNMSUB213PD m128 xmm xmm +// VFNMSUB213PD ymm ymm ymm +// VFNMSUB213PD m256 ymm ymm +func VFNMSUB213PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB213PD: bad operands") +} + +// VFNMSUB213PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213PS xmm xmm xmm +// VFNMSUB213PS m128 xmm xmm +// VFNMSUB213PS ymm ymm ymm +// VFNMSUB213PS m256 ymm ymm +func VFNMSUB213PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB213PS: bad operands") +} + +// VFNMSUB213SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SD xmm xmm xmm +// VFNMSUB213SD m64 xmm xmm +func VFNMSUB213SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB213SD: bad operands") +} + +// VFNMSUB213SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB213SS xmm xmm xmm +// VFNMSUB213SS m32 xmm xmm +func VFNMSUB213SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB213SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB213SS: bad operands") +} + +// VFNMSUB231PD: Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PD xmm xmm xmm +// VFNMSUB231PD m128 xmm xmm +// VFNMSUB231PD ymm ymm ymm +// VFNMSUB231PD m256 ymm ymm +func VFNMSUB231PD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB231PD: bad operands") +} + +// VFNMSUB231PS: Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231PS xmm xmm xmm +// VFNMSUB231PS m128 xmm xmm +// VFNMSUB231PS ymm ymm ymm +// VFNMSUB231PS m256 ymm ymm +func VFNMSUB231PS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231PS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy, xy1}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VFNMSUB231PS: bad operands") +} + +// VFNMSUB231SD: Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SD xmm xmm xmm +// VFNMSUB231SD m64 xmm xmm +func VFNMSUB231SD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB231SD: bad operands") +} + +// VFNMSUB231SS: Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VFNMSUB231SS xmm xmm xmm +// VFNMSUB231SS m32 xmm xmm +func VFNMSUB231SS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VFNMSUB231SS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x, x1}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VFNMSUB231SS: bad operands") +} + +// VGATHERDPD: Gather Packed Double-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPD xmm vm32x xmm +// VGATHERDPD ymm vm32x ymm +func VGATHERDPD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32X(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VGATHERDPD: bad operands") +} + +// VGATHERDPS: Gather Packed Single-Precision Floating-Point Values Using Signed Doubleword Indices. +// +// Forms: +// +// VGATHERDPS xmm vm32x xmm +// VGATHERDPS ymm vm32y ymm +func VGATHERDPS(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPS", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERDPS", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VGATHERDPS: bad operands") +} + +// VGATHERQPD: Gather Packed Double-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPD xmm vm64x xmm +// VGATHERQPD ymm vm64y ymm +func VGATHERQPD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM64X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERQPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM64Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VGATHERQPD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VGATHERQPD: bad operands") +} + +// VGATHERQPS: Gather Packed Single-Precision Floating-Point Values Using Signed Quadword Indices. +// +// Forms: +// +// VGATHERQPS xmm vm64x xmm +// VGATHERQPS xmm vm64y xmm +func VGATHERQPS(x, v, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsVM64X(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VGATHERQPS", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + }, nil + case operand.IsXMM(x) && operand.IsVM64Y(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VGATHERQPS", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + }, nil + } + return nil, errors.New("VGATHERQPS: bad operands") +} + +// VHADDPD: Packed Double-FP Horizontal Add. +// +// Forms: +// +// VHADDPD xmm xmm xmm +// VHADDPD m128 xmm xmm +// VHADDPD ymm ymm ymm +// VHADDPD m256 ymm ymm +func VHADDPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VHADDPD: bad operands") +} + +// VHADDPS: Packed Single-FP Horizontal Add. +// +// Forms: +// +// VHADDPS xmm xmm xmm +// VHADDPS m128 xmm xmm +// VHADDPS ymm ymm ymm +// VHADDPS m256 ymm ymm +func VHADDPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHADDPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VHADDPS: bad operands") +} + +// VHSUBPD: Packed Double-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPD xmm xmm xmm +// VHSUBPD m128 xmm xmm +// VHSUBPD ymm ymm ymm +// VHSUBPD m256 ymm ymm +func VHSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VHSUBPD: bad operands") +} + +// VHSUBPS: Packed Single-FP Horizontal Subtract. +// +// Forms: +// +// VHSUBPS xmm xmm xmm +// VHSUBPS m128 xmm xmm +// VHSUBPS ymm ymm ymm +// VHSUBPS m256 ymm ymm +func VHSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VHSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VHSUBPS: bad operands") +} + +// VINSERTF128: Insert Packed Floating-Point Values. +// +// Forms: +// +// VINSERTF128 imm8 xmm ymm ymm +// VINSERTF128 imm8 m128 ymm ymm +func VINSERTF128(i, mx, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTF128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTF128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VINSERTF128: bad operands") +} + +// VINSERTI128: Insert Packed Integer Values. +// +// Forms: +// +// VINSERTI128 imm8 xmm ymm ymm +// VINSERTI128 imm8 m128 ymm ymm +func VINSERTI128(i, mx, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTI128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VINSERTI128", + Operands: []operand.Op{i, mx, y, y1}, + Inputs: []operand.Op{mx, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VINSERTI128: bad operands") +} + +// VINSERTPS: Insert Packed Single Precision Floating-Point Value. +// +// Forms: +// +// VINSERTPS imm8 xmm xmm xmm +// VINSERTPS imm8 m32 xmm xmm +func VINSERTPS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VINSERTPS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VINSERTPS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VINSERTPS: bad operands") +} + +// VLDDQU: Load Unaligned Integer 128 Bits. +// +// Forms: +// +// VLDDQU m128 xmm +// VLDDQU m256 ymm +func VLDDQU(m, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VLDDQU", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(m) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VLDDQU", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VLDDQU: bad operands") +} + +// VLDMXCSR: Load MXCSR Register. +// +// Forms: +// +// VLDMXCSR m32 +func VLDMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "VLDMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VLDMXCSR: bad operands") +} + +// VMASKMOVDQU: Store Selected Bytes of Double Quadword. +// +// Forms: +// +// VMASKMOVDQU xmm xmm +func VMASKMOVDQU(x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMASKMOVDQU", + Operands: []operand.Op{x, x1}, + Inputs: []operand.Op{x, x1, reg.RDI}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VMASKMOVDQU: bad operands") +} + +// VMASKMOVPD: Conditional Move Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPD m128 xmm xmm +// VMASKMOVPD m256 ymm ymm +// VMASKMOVPD xmm xmm m128 +// VMASKMOVPD ymm ymm m256 +func VMASKMOVPD(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMASKMOVPD: bad operands") +} + +// VMASKMOVPS: Conditional Move Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMASKMOVPS m128 xmm xmm +// VMASKMOVPS m256 ymm ymm +// VMASKMOVPS xmm xmm m128 +// VMASKMOVPS ymm ymm m256 +func VMASKMOVPS(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMASKMOVPS", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMASKMOVPS: bad operands") +} + +// VMAXPD: Return Maximum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPD xmm xmm xmm +// VMAXPD m128 xmm xmm +// VMAXPD ymm ymm ymm +// VMAXPD m256 ymm ymm +func VMAXPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMAXPD: bad operands") +} + +// VMAXPS: Return Maximum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMAXPS xmm xmm xmm +// VMAXPS m128 xmm xmm +// VMAXPS ymm ymm ymm +// VMAXPS m256 ymm ymm +func VMAXPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMAXPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMAXPS: bad operands") +} + +// VMAXSD: Return Maximum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSD xmm xmm xmm +// VMAXSD m64 xmm xmm +func VMAXSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMAXSD: bad operands") +} + +// VMAXSS: Return Maximum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMAXSS xmm xmm xmm +// VMAXSS m32 xmm xmm +func VMAXSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMAXSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMAXSS: bad operands") +} + +// VMINPD: Return Minimum Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMINPD xmm xmm xmm +// VMINPD m128 xmm xmm +// VMINPD ymm ymm ymm +// VMINPD m256 ymm ymm +func VMINPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMINPD: bad operands") +} + +// VMINPS: Return Minimum Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMINPS xmm xmm xmm +// VMINPS m128 xmm xmm +// VMINPS ymm ymm ymm +// VMINPS m256 ymm ymm +func VMINPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMINPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMINPS: bad operands") +} + +// VMINSD: Return Minimum Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMINSD xmm xmm xmm +// VMINSD m64 xmm xmm +func VMINSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMINSD: bad operands") +} + +// VMINSS: Return Minimum Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VMINSS xmm xmm xmm +// VMINSS m32 xmm xmm +func VMINSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMINSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMINSS: bad operands") +} + +// VMOVAPD: Move Aligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPD xmm xmm +// VMOVAPD m128 xmm +// VMOVAPD ymm ymm +// VMOVAPD m256 ymm +// VMOVAPD xmm m128 +// VMOVAPD ymm m256 +func VMOVAPD(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVAPD: bad operands") +} + +// VMOVAPS: Move Aligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVAPS xmm xmm +// VMOVAPS m128 xmm +// VMOVAPS ymm ymm +// VMOVAPS m256 ymm +// VMOVAPS xmm m128 +// VMOVAPS ymm m256 +func VMOVAPS(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVAPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVAPS: bad operands") +} + +// VMOVD: Move Doubleword. +// +// Forms: +// +// VMOVD xmm r32 +// VMOVD r32 xmm +// VMOVD m32 xmm +// VMOVD xmm m32 +func VMOVD(mrx, mrx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mrx) && operand.IsR32(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsR32(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsM32(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsXMM(mrx) && operand.IsM32(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVD", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + } + return nil, errors.New("VMOVD: bad operands") +} + +// VMOVDDUP: Move One Double-FP and Duplicate. +// +// Forms: +// +// VMOVDDUP xmm xmm +// VMOVDDUP m64 xmm +// VMOVDDUP ymm ymm +// VMOVDDUP m256 ymm +func VMOVDDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVDDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VMOVDDUP: bad operands") +} + +// VMOVDQA: Move Aligned Double Quadword. +// +// Forms: +// +// VMOVDQA xmm xmm +// VMOVDQA m128 xmm +// VMOVDQA ymm ymm +// VMOVDQA m256 ymm +// VMOVDQA xmm m128 +// VMOVDQA ymm m256 +func VMOVDQA(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQA", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVDQA: bad operands") +} + +// VMOVDQU: Move Unaligned Double Quadword. +// +// Forms: +// +// VMOVDQU xmm xmm +// VMOVDQU m128 xmm +// VMOVDQU ymm ymm +// VMOVDQU m256 ymm +// VMOVDQU xmm m128 +// VMOVDQU ymm m256 +func VMOVDQU(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVDQU", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVDQU: bad operands") +} + +// VMOVHLPS: Move Packed Single-Precision Floating-Point Values High to Low. +// +// Forms: +// +// VMOVHLPS xmm xmm xmm +func VMOVHLPS(x, x1, x2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1) && operand.IsXMM(x2): + return &intrep.Instruction{ + Opcode: "VMOVHLPS", + Operands: []operand.Op{x, x1, x2}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x2}, + }, nil + } + return nil, errors.New("VMOVHLPS: bad operands") +} + +// VMOVHPD: Move High Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVHPD xmm m64 +// VMOVHPD m64 xmm xmm +func VMOVHPD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVHPD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVHPD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVHPD: bad operands") +} + +// VMOVHPS: Move High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVHPS xmm m64 +// VMOVHPS m64 xmm xmm +func VMOVHPS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVHPS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVHPS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVHPS: bad operands") +} + +// VMOVLHPS: Move Packed Single-Precision Floating-Point Values Low to High. +// +// Forms: +// +// VMOVLHPS xmm xmm xmm +func VMOVLHPS(x, x1, x2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsXMM(x1) && operand.IsXMM(x2): + return &intrep.Instruction{ + Opcode: "VMOVLHPS", + Operands: []operand.Op{x, x1, x2}, + Inputs: []operand.Op{x, x1}, + Outputs: []operand.Op{x2}, + }, nil + } + return nil, errors.New("VMOVLHPS: bad operands") +} + +// VMOVLPD: Move Low Packed Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVLPD xmm m64 +// VMOVLPD m64 xmm xmm +func VMOVLPD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVLPD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVLPD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVLPD: bad operands") +} + +// VMOVLPS: Move Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVLPS xmm m64 +// VMOVLPS m64 xmm xmm +func VMOVLPS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVLPS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVLPS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVLPS: bad operands") +} + +// VMOVMSKPD: Extract Packed Double-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPD xmm r32 +// VMOVMSKPD ymm r32 +func VMOVMSKPD(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPD", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPD", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VMOVMSKPD: bad operands") +} + +// VMOVMSKPS: Extract Packed Single-Precision Floating-Point Sign Mask. +// +// Forms: +// +// VMOVMSKPS xmm r32 +// VMOVMSKPS ymm r32 +func VMOVMSKPS(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPS", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VMOVMSKPS", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VMOVMSKPS: bad operands") +} + +// VMOVNTDQ: Store Double Quadword Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTDQ xmm m128 +// VMOVNTDQ ymm m256 +func VMOVNTDQ(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTDQ", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTDQ", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("VMOVNTDQ: bad operands") +} + +// VMOVNTDQA: Load Double Quadword Non-Temporal Aligned Hint. +// +// Forms: +// +// VMOVNTDQA m128 xmm +// VMOVNTDQA m256 ymm +func VMOVNTDQA(m, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(m) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVNTDQA", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(m) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVNTDQA", + Operands: []operand.Op{m, xy}, + Inputs: []operand.Op{m}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VMOVNTDQA: bad operands") +} + +// VMOVNTPD: Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPD xmm m128 +// VMOVNTPD ymm m256 +func VMOVNTPD(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPD", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPD", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("VMOVNTPD: bad operands") +} + +// VMOVNTPS: Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint. +// +// Forms: +// +// VMOVNTPS xmm m128 +// VMOVNTPS ymm m256 +func VMOVNTPS(xy, m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsM128(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPS", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(m): + return &intrep.Instruction{ + Opcode: "VMOVNTPS", + Operands: []operand.Op{xy, m}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("VMOVNTPS: bad operands") +} + +// VMOVQ: Move Quadword. +// +// Forms: +// +// VMOVQ xmm r64 +// VMOVQ r64 xmm +// VMOVQ xmm xmm +// VMOVQ m64 xmm +// VMOVQ xmm m64 +func VMOVQ(mrx, mrx1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mrx) && operand.IsR64(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsR64(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsXMM(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsM64(mrx) && operand.IsXMM(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + case operand.IsXMM(mrx) && operand.IsM64(mrx1): + return &intrep.Instruction{ + Opcode: "VMOVQ", + Operands: []operand.Op{mrx, mrx1}, + Inputs: []operand.Op{mrx}, + Outputs: []operand.Op{mrx1}, + }, nil + } + return nil, errors.New("VMOVQ: bad operands") +} + +// VMOVSD: Move Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VMOVSD m64 xmm +// VMOVSD xmm m64 +// VMOVSD xmm xmm xmm +func VMOVSD(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsM64(ops[0]) && operand.IsXMM(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM64(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsXMM(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVSD", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVSD: bad operands") +} + +// VMOVSHDUP: Move Packed Single-FP High and Duplicate. +// +// Forms: +// +// VMOVSHDUP xmm xmm +// VMOVSHDUP m128 xmm +// VMOVSHDUP ymm ymm +// VMOVSHDUP m256 ymm +func VMOVSHDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSHDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VMOVSHDUP: bad operands") +} + +// VMOVSLDUP: Move Packed Single-FP Low and Duplicate. +// +// Forms: +// +// VMOVSLDUP xmm xmm +// VMOVSLDUP m128 xmm +// VMOVSLDUP ymm ymm +// VMOVSLDUP m256 ymm +func VMOVSLDUP(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VMOVSLDUP", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VMOVSLDUP: bad operands") +} + +// VMOVSS: Move Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVSS m32 xmm +// VMOVSS xmm m32 +// VMOVSS xmm xmm xmm +func VMOVSS(ops ...operand.Op) (*intrep.Instruction, error) { + switch { + case len(ops) == 2 && operand.IsM32(ops[0]) && operand.IsXMM(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 2 && operand.IsXMM(ops[0]) && operand.IsM32(ops[1]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0]}, + Outputs: []operand.Op{ops[1]}, + }, nil + case len(ops) == 3 && operand.IsXMM(ops[0]) && operand.IsXMM(ops[1]) && operand.IsXMM(ops[2]): + return &intrep.Instruction{ + Opcode: "VMOVSS", + Operands: ops, + Inputs: []operand.Op{ops[0], ops[1]}, + Outputs: []operand.Op{ops[2]}, + }, nil + } + return nil, errors.New("VMOVSS: bad operands") +} + +// VMOVUPD: Move Unaligned Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPD xmm xmm +// VMOVUPD m128 xmm +// VMOVUPD ymm ymm +// VMOVUPD m256 ymm +// VMOVUPD xmm m128 +// VMOVUPD ymm m256 +func VMOVUPD(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPD", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVUPD: bad operands") +} + +// VMOVUPS: Move Unaligned Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMOVUPS xmm xmm +// VMOVUPS m128 xmm +// VMOVUPS ymm ymm +// VMOVUPS m256 ymm +// VMOVUPS xmm m128 +// VMOVUPS ymm m256 +func VMOVUPS(mxy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VMOVUPS", + Operands: []operand.Op{mxy, mxy1}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VMOVUPS: bad operands") +} + +// VMPSADBW: Compute Multiple Packed Sums of Absolute Difference. +// +// Forms: +// +// VMPSADBW imm8 xmm xmm xmm +// VMPSADBW imm8 m128 xmm xmm +// VMPSADBW imm8 ymm ymm ymm +// VMPSADBW imm8 m256 ymm ymm +func VMPSADBW(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMPSADBW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMPSADBW: bad operands") +} + +// VMULPD: Multiply Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULPD xmm xmm xmm +// VMULPD m128 xmm xmm +// VMULPD ymm ymm ymm +// VMULPD m256 ymm ymm +func VMULPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMULPD: bad operands") +} + +// VMULPS: Multiply Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULPS xmm xmm xmm +// VMULPS m128 xmm xmm +// VMULPS ymm ymm ymm +// VMULPS m256 ymm ymm +func VMULPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VMULPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VMULPS: bad operands") +} + +// VMULSD: Multiply Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VMULSD xmm xmm xmm +// VMULSD m64 xmm xmm +func VMULSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMULSD: bad operands") +} + +// VMULSS: Multiply Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VMULSS xmm xmm xmm +// VMULSS m32 xmm xmm +func VMULSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VMULSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VMULSS: bad operands") +} + +// VORPD: Bitwise Logical OR of Double-Precision Floating-Point Values. +// +// Forms: +// +// VORPD xmm xmm xmm +// VORPD m128 xmm xmm +// VORPD ymm ymm ymm +// VORPD m256 ymm ymm +func VORPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VORPD: bad operands") +} + +// VORPS: Bitwise Logical OR of Single-Precision Floating-Point Values. +// +// Forms: +// +// VORPS xmm xmm xmm +// VORPS m128 xmm xmm +// VORPS ymm ymm ymm +// VORPS m256 ymm ymm +func VORPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VORPS: bad operands") +} + +// VPABSB: Packed Absolute Value of Byte Integers. +// +// Forms: +// +// VPABSB xmm xmm +// VPABSB m128 xmm +// VPABSB ymm ymm +// VPABSB m256 ymm +func VPABSB(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSB", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPABSB: bad operands") +} + +// VPABSD: Packed Absolute Value of Doubleword Integers. +// +// Forms: +// +// VPABSD xmm xmm +// VPABSD m128 xmm +// VPABSD ymm ymm +// VPABSD m256 ymm +func VPABSD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPABSD: bad operands") +} + +// VPABSW: Packed Absolute Value of Word Integers. +// +// Forms: +// +// VPABSW xmm xmm +// VPABSW m128 xmm +// VPABSW ymm ymm +// VPABSW m256 ymm +func VPABSW(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPABSW", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPABSW: bad operands") +} + +// VPACKSSDW: Pack Doublewords into Words with Signed Saturation. +// +// Forms: +// +// VPACKSSDW xmm xmm xmm +// VPACKSSDW m128 xmm xmm +// VPACKSSDW ymm ymm ymm +// VPACKSSDW m256 ymm ymm +func VPACKSSDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPACKSSDW: bad operands") +} + +// VPACKSSWB: Pack Words into Bytes with Signed Saturation. +// +// Forms: +// +// VPACKSSWB xmm xmm xmm +// VPACKSSWB m128 xmm xmm +// VPACKSSWB ymm ymm ymm +// VPACKSSWB m256 ymm ymm +func VPACKSSWB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKSSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPACKSSWB: bad operands") +} + +// VPACKUSDW: Pack Doublewords into Words with Unsigned Saturation. +// +// Forms: +// +// VPACKUSDW xmm xmm xmm +// VPACKUSDW m128 xmm xmm +// VPACKUSDW ymm ymm ymm +// VPACKUSDW m256 ymm ymm +func VPACKUSDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPACKUSDW: bad operands") +} + +// VPACKUSWB: Pack Words into Bytes with Unsigned Saturation. +// +// Forms: +// +// VPACKUSWB xmm xmm xmm +// VPACKUSWB m128 xmm xmm +// VPACKUSWB ymm ymm ymm +// VPACKUSWB m256 ymm ymm +func VPACKUSWB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPACKUSWB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPACKUSWB: bad operands") +} + +// VPADDB: Add Packed Byte Integers. +// +// Forms: +// +// VPADDB xmm xmm xmm +// VPADDB m128 xmm xmm +// VPADDB ymm ymm ymm +// VPADDB m256 ymm ymm +func VPADDB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDB: bad operands") +} + +// VPADDD: Add Packed Doubleword Integers. +// +// Forms: +// +// VPADDD xmm xmm xmm +// VPADDD m128 xmm xmm +// VPADDD ymm ymm ymm +// VPADDD m256 ymm ymm +func VPADDD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDD: bad operands") +} + +// VPADDQ: Add Packed Quadword Integers. +// +// Forms: +// +// VPADDQ xmm xmm xmm +// VPADDQ m128 xmm xmm +// VPADDQ ymm ymm ymm +// VPADDQ m256 ymm ymm +func VPADDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDQ: bad operands") +} + +// VPADDSB: Add Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPADDSB xmm xmm xmm +// VPADDSB m128 xmm xmm +// VPADDSB ymm ymm ymm +// VPADDSB m256 ymm ymm +func VPADDSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDSB: bad operands") +} + +// VPADDSW: Add Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPADDSW xmm xmm xmm +// VPADDSW m128 xmm xmm +// VPADDSW ymm ymm ymm +// VPADDSW m256 ymm ymm +func VPADDSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDSW: bad operands") +} + +// VPADDUSB: Add Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSB xmm xmm xmm +// VPADDUSB m128 xmm xmm +// VPADDUSB ymm ymm ymm +// VPADDUSB m256 ymm ymm +func VPADDUSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDUSB: bad operands") +} + +// VPADDUSW: Add Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPADDUSW xmm xmm xmm +// VPADDUSW m128 xmm xmm +// VPADDUSW ymm ymm ymm +// VPADDUSW m256 ymm ymm +func VPADDUSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDUSW: bad operands") +} + +// VPADDW: Add Packed Word Integers. +// +// Forms: +// +// VPADDW xmm xmm xmm +// VPADDW m128 xmm xmm +// VPADDW ymm ymm ymm +// VPADDW m256 ymm ymm +func VPADDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPADDW: bad operands") +} + +// VPALIGNR: Packed Align Right. +// +// Forms: +// +// VPALIGNR imm8 xmm xmm xmm +// VPALIGNR imm8 m128 xmm xmm +// VPALIGNR imm8 ymm ymm ymm +// VPALIGNR imm8 m256 ymm ymm +func VPALIGNR(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPALIGNR", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPALIGNR: bad operands") +} + +// VPAND: Packed Bitwise Logical AND. +// +// Forms: +// +// VPAND xmm xmm xmm +// VPAND m128 xmm xmm +// VPAND ymm ymm ymm +// VPAND m256 ymm ymm +func VPAND(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPAND: bad operands") +} + +// VPANDN: Packed Bitwise Logical AND NOT. +// +// Forms: +// +// VPANDN xmm xmm xmm +// VPANDN m128 xmm xmm +// VPANDN ymm ymm ymm +// VPANDN m256 ymm ymm +func VPANDN(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPANDN", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPANDN: bad operands") +} + +// VPAVGB: Average Packed Byte Integers. +// +// Forms: +// +// VPAVGB xmm xmm xmm +// VPAVGB m128 xmm xmm +// VPAVGB ymm ymm ymm +// VPAVGB m256 ymm ymm +func VPAVGB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPAVGB: bad operands") +} + +// VPAVGW: Average Packed Word Integers. +// +// Forms: +// +// VPAVGW xmm xmm xmm +// VPAVGW m128 xmm xmm +// VPAVGW ymm ymm ymm +// VPAVGW m256 ymm ymm +func VPAVGW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPAVGW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPAVGW: bad operands") +} + +// VPBLENDD: Blend Packed Doublewords. +// +// Forms: +// +// VPBLENDD imm8 xmm xmm xmm +// VPBLENDD imm8 m128 xmm xmm +// VPBLENDD imm8 ymm ymm ymm +// VPBLENDD imm8 m256 ymm ymm +func VPBLENDD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPBLENDD: bad operands") +} + +// VPBLENDVB: Variable Blend Packed Bytes. +// +// Forms: +// +// VPBLENDVB xmm xmm xmm xmm +// VPBLENDVB xmm m128 xmm xmm +// VPBLENDVB ymm ymm ymm ymm +// VPBLENDVB ymm m256 ymm ymm +func VPBLENDVB(xy, mxy, xy1, xy2 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsXMM(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsXMM(xy) && operand.IsM128(mxy) && operand.IsXMM(xy1) && operand.IsXMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsYMM(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + case operand.IsYMM(xy) && operand.IsM256(mxy) && operand.IsYMM(xy1) && operand.IsYMM(xy2): + return &intrep.Instruction{ + Opcode: "VPBLENDVB", + Operands: []operand.Op{xy, mxy, xy1, xy2}, + Inputs: []operand.Op{xy, mxy, xy1}, + Outputs: []operand.Op{xy2}, + }, nil + } + return nil, errors.New("VPBLENDVB: bad operands") +} + +// VPBLENDW: Blend Packed Words. +// +// Forms: +// +// VPBLENDW imm8 xmm xmm xmm +// VPBLENDW imm8 m128 xmm xmm +// VPBLENDW imm8 ymm ymm ymm +// VPBLENDW imm8 m256 ymm ymm +func VPBLENDW(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPBLENDW", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPBLENDW: bad operands") +} + +// VPBROADCASTB: Broadcast Byte Integer. +// +// Forms: +// +// VPBROADCASTB xmm xmm +// VPBROADCASTB m8 xmm +// VPBROADCASTB xmm ymm +// VPBROADCASTB m8 ymm +func VPBROADCASTB(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM8(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM8(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTB", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPBROADCASTB: bad operands") +} + +// VPBROADCASTD: Broadcast Doubleword Integer. +// +// Forms: +// +// VPBROADCASTD xmm xmm +// VPBROADCASTD m32 xmm +// VPBROADCASTD xmm ymm +// VPBROADCASTD m32 ymm +func VPBROADCASTD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPBROADCASTD: bad operands") +} + +// VPBROADCASTQ: Broadcast Quadword Integer. +// +// Forms: +// +// VPBROADCASTQ xmm xmm +// VPBROADCASTQ m64 xmm +// VPBROADCASTQ xmm ymm +// VPBROADCASTQ m64 ymm +func VPBROADCASTQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPBROADCASTQ: bad operands") +} + +// VPBROADCASTW: Broadcast Word Integer. +// +// Forms: +// +// VPBROADCASTW xmm xmm +// VPBROADCASTW m16 xmm +// VPBROADCASTW xmm ymm +// VPBROADCASTW m16 ymm +func VPBROADCASTW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM16(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPBROADCASTW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPBROADCASTW: bad operands") +} + +// VPCLMULQDQ: Carry-Less Quadword Multiplication. +// +// Forms: +// +// VPCLMULQDQ imm8 xmm xmm xmm +// VPCLMULQDQ imm8 m128 xmm xmm +func VPCLMULQDQ(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPCLMULQDQ", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPCLMULQDQ", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VPCLMULQDQ: bad operands") +} + +// VPCMPEQB: Compare Packed Byte Data for Equality. +// +// Forms: +// +// VPCMPEQB xmm xmm xmm +// VPCMPEQB m128 xmm xmm +// VPCMPEQB ymm ymm ymm +// VPCMPEQB m256 ymm ymm +func VPCMPEQB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPEQB: bad operands") +} + +// VPCMPEQD: Compare Packed Doubleword Data for Equality. +// +// Forms: +// +// VPCMPEQD xmm xmm xmm +// VPCMPEQD m128 xmm xmm +// VPCMPEQD ymm ymm ymm +// VPCMPEQD m256 ymm ymm +func VPCMPEQD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPEQD: bad operands") +} + +// VPCMPEQQ: Compare Packed Quadword Data for Equality. +// +// Forms: +// +// VPCMPEQQ xmm xmm xmm +// VPCMPEQQ m128 xmm xmm +// VPCMPEQQ ymm ymm ymm +// VPCMPEQQ m256 ymm ymm +func VPCMPEQQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPEQQ: bad operands") +} + +// VPCMPEQW: Compare Packed Word Data for Equality. +// +// Forms: +// +// VPCMPEQW xmm xmm xmm +// VPCMPEQW m128 xmm xmm +// VPCMPEQW ymm ymm ymm +// VPCMPEQW m256 ymm ymm +func VPCMPEQW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPEQW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPEQW: bad operands") +} + +// VPCMPESTRI: Packed Compare Explicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPESTRI imm8 xmm xmm +// VPCMPESTRI imm8 m128 xmm +func VPCMPESTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.ECX}, + }, nil + } + return nil, errors.New("VPCMPESTRI: bad operands") +} + +// VPCMPESTRM: Packed Compare Explicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPESTRM imm8 xmm xmm +// VPCMPESTRM imm8 m128 xmm +func VPCMPESTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPESTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x, reg.EAX, reg.EDX}, + Outputs: []operand.Op{reg.X0}, + }, nil + } + return nil, errors.New("VPCMPESTRM: bad operands") +} + +// VPCMPGTB: Compare Packed Signed Byte Integers for Greater Than. +// +// Forms: +// +// VPCMPGTB xmm xmm xmm +// VPCMPGTB m128 xmm xmm +// VPCMPGTB ymm ymm ymm +// VPCMPGTB m256 ymm ymm +func VPCMPGTB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPGTB: bad operands") +} + +// VPCMPGTD: Compare Packed Signed Doubleword Integers for Greater Than. +// +// Forms: +// +// VPCMPGTD xmm xmm xmm +// VPCMPGTD m128 xmm xmm +// VPCMPGTD ymm ymm ymm +// VPCMPGTD m256 ymm ymm +func VPCMPGTD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPGTD: bad operands") +} + +// VPCMPGTQ: Compare Packed Data for Greater Than. +// +// Forms: +// +// VPCMPGTQ xmm xmm xmm +// VPCMPGTQ m128 xmm xmm +// VPCMPGTQ ymm ymm ymm +// VPCMPGTQ m256 ymm ymm +func VPCMPGTQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPGTQ: bad operands") +} + +// VPCMPGTW: Compare Packed Signed Word Integers for Greater Than. +// +// Forms: +// +// VPCMPGTW xmm xmm xmm +// VPCMPGTW m128 xmm xmm +// VPCMPGTW ymm ymm ymm +// VPCMPGTW m256 ymm ymm +func VPCMPGTW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPCMPGTW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPCMPGTW: bad operands") +} + +// VPCMPISTRI: Packed Compare Implicit Length Strings, Return Index. +// +// Forms: +// +// VPCMPISTRI imm8 xmm xmm +// VPCMPISTRI imm8 m128 xmm +func VPCMPISTRI(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRI", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.ECX}, + }, nil + } + return nil, errors.New("VPCMPISTRI: bad operands") +} + +// VPCMPISTRM: Packed Compare Implicit Length Strings, Return Mask. +// +// Forms: +// +// VPCMPISTRM imm8 xmm xmm +// VPCMPISTRM imm8 m128 xmm +func VPCMPISTRM(i, mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPCMPISTRM", + Operands: []operand.Op{i, mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{reg.X0}, + }, nil + } + return nil, errors.New("VPCMPISTRM: bad operands") +} + +// VPERM2F128: Permute Floating-Point Values. +// +// Forms: +// +// VPERM2F128 imm8 ymm ymm ymm +// VPERM2F128 imm8 m256 ymm ymm +func VPERM2F128(i, my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2F128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2F128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VPERM2F128: bad operands") +} + +// VPERM2I128: Permute 128-Bit Integer Values. +// +// Forms: +// +// VPERM2I128 imm8 ymm ymm ymm +// VPERM2I128 imm8 m256 ymm ymm +func VPERM2I128(i, my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2I128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERM2I128", + Operands: []operand.Op{i, my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VPERM2I128: bad operands") +} + +// VPERMD: Permute Doubleword Integers. +// +// Forms: +// +// VPERMD ymm ymm ymm +// VPERMD m256 ymm ymm +func VPERMD(my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMD", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMD", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VPERMD: bad operands") +} + +// VPERMILPD: Permute Double-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPD imm8 xmm xmm +// VPERMILPD xmm xmm xmm +// VPERMILPD m128 xmm xmm +// VPERMILPD imm8 m128 xmm +// VPERMILPD imm8 ymm ymm +// VPERMILPD ymm ymm ymm +// VPERMILPD m256 ymm ymm +// VPERMILPD imm8 m256 ymm +func VPERMILPD(imxy, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPD", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPERMILPD: bad operands") +} + +// VPERMILPS: Permute Single-Precision Floating-Point Values. +// +// Forms: +// +// VPERMILPS imm8 xmm xmm +// VPERMILPS xmm xmm xmm +// VPERMILPS m128 xmm xmm +// VPERMILPS imm8 m128 xmm +// VPERMILPS imm8 ymm ymm +// VPERMILPS ymm ymm ymm +// VPERMILPS m256 ymm ymm +// VPERMILPS imm8 m256 ymm +func VPERMILPS(imxy, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(imxy) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(imxy) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{imxy, mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(imxy) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPERMILPS", + Operands: []operand.Op{imxy, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPERMILPS: bad operands") +} + +// VPERMPD: Permute Double-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPD imm8 ymm ymm +// VPERMPD imm8 m256 ymm +func VPERMPD(i, my, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMPD", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMPD", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + }, nil + } + return nil, errors.New("VPERMPD: bad operands") +} + +// VPERMPS: Permute Single-Precision Floating-Point Elements. +// +// Forms: +// +// VPERMPS ymm ymm ymm +// VPERMPS m256 ymm ymm +func VPERMPS(my, y, y1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsYMM(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMPS", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + case operand.IsM256(my) && operand.IsYMM(y) && operand.IsYMM(y1): + return &intrep.Instruction{ + Opcode: "VPERMPS", + Operands: []operand.Op{my, y, y1}, + Inputs: []operand.Op{my, y}, + Outputs: []operand.Op{y1}, + }, nil + } + return nil, errors.New("VPERMPS: bad operands") +} + +// VPERMQ: Permute Quadword Integers. +// +// Forms: +// +// VPERMQ imm8 ymm ymm +// VPERMQ imm8 m256 ymm +func VPERMQ(i, my, y operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsYMM(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMQ", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(my) && operand.IsYMM(y): + return &intrep.Instruction{ + Opcode: "VPERMQ", + Operands: []operand.Op{i, my, y}, + Inputs: []operand.Op{my}, + Outputs: []operand.Op{y}, + }, nil + } + return nil, errors.New("VPERMQ: bad operands") +} + +// VPEXTRB: Extract Byte. +// +// Forms: +// +// VPEXTRB imm8 xmm r32 +// VPEXTRB imm8 xmm m8 +func VPEXTRB(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRB", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("VPEXTRB: bad operands") +} + +// VPEXTRD: Extract Doubleword. +// +// Forms: +// +// VPEXTRD imm8 xmm r32 +// VPEXTRD imm8 xmm m32 +func VPEXTRD(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRD", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("VPEXTRD: bad operands") +} + +// VPEXTRQ: Extract Quadword. +// +// Forms: +// +// VPEXTRQ imm8 xmm r64 +// VPEXTRQ imm8 xmm m64 +func VPEXTRQ(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRQ", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("VPEXTRQ: bad operands") +} + +// VPEXTRW: Extract Word. +// +// Forms: +// +// VPEXTRW imm8 xmm r32 +// VPEXTRW imm8 xmm m16 +func VPEXTRW(i, x, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(i) && operand.IsXMM(x) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "VPEXTRW", + Operands: []operand.Op{i, x, mr}, + Inputs: []operand.Op{x}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("VPEXTRW: bad operands") +} + +// VPGATHERDD: Gather Packed Doubleword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDD xmm vm32x xmm +// VPGATHERDD ymm vm32y ymm +func VPGATHERDD(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDD", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VPGATHERDD: bad operands") +} + +// VPGATHERDQ: Gather Packed Quadword Values Using Signed Doubleword Indices. +// +// Forms: +// +// VPGATHERDQ xmm vm32x xmm +// VPGATHERDQ ymm vm32x ymm +func VPGATHERDQ(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM32X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM32X(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERDQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VPGATHERDQ: bad operands") +} + +// VPGATHERQD: Gather Packed Doubleword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQD xmm vm64x xmm +// VPGATHERQD xmm vm64y xmm +func VPGATHERQD(x, v, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(x) && operand.IsVM64X(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPGATHERQD", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + }, nil + case operand.IsXMM(x) && operand.IsVM64Y(v) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPGATHERQD", + Operands: []operand.Op{x, v, x1}, + Inputs: []operand.Op{x, v, x1}, + Outputs: []operand.Op{x, x1}, + }, nil + } + return nil, errors.New("VPGATHERQD: bad operands") +} + +// VPGATHERQQ: Gather Packed Quadword Values Using Signed Quadword Indices. +// +// Forms: +// +// VPGATHERQQ xmm vm64x xmm +// VPGATHERQQ ymm vm64y ymm +func VPGATHERQQ(xy, v, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsVM64X(v) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERQQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + case operand.IsYMM(xy) && operand.IsVM64Y(v) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPGATHERQQ", + Operands: []operand.Op{xy, v, xy1}, + Inputs: []operand.Op{xy, v, xy1}, + Outputs: []operand.Op{xy, xy1}, + }, nil + } + return nil, errors.New("VPGATHERQQ: bad operands") +} + +// VPHADDD: Packed Horizontal Add Doubleword Integer. +// +// Forms: +// +// VPHADDD xmm xmm xmm +// VPHADDD m128 xmm xmm +// VPHADDD ymm ymm ymm +// VPHADDD m256 ymm ymm +func VPHADDD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHADDD: bad operands") +} + +// VPHADDSW: Packed Horizontal Add Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHADDSW xmm xmm xmm +// VPHADDSW m128 xmm xmm +// VPHADDSW ymm ymm ymm +// VPHADDSW m256 ymm ymm +func VPHADDSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHADDSW: bad operands") +} + +// VPHADDW: Packed Horizontal Add Word Integers. +// +// Forms: +// +// VPHADDW xmm xmm xmm +// VPHADDW m128 xmm xmm +// VPHADDW ymm ymm ymm +// VPHADDW m256 ymm ymm +func VPHADDW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHADDW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHADDW: bad operands") +} + +// VPHMINPOSUW: Packed Horizontal Minimum of Unsigned Word Integers. +// +// Forms: +// +// VPHMINPOSUW xmm xmm +// VPHMINPOSUW m128 xmm +func VPHMINPOSUW(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VPHMINPOSUW", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("VPHMINPOSUW: bad operands") +} + +// VPHSUBD: Packed Horizontal Subtract Doubleword Integers. +// +// Forms: +// +// VPHSUBD xmm xmm xmm +// VPHSUBD m128 xmm xmm +// VPHSUBD ymm ymm ymm +// VPHSUBD m256 ymm ymm +func VPHSUBD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHSUBD: bad operands") +} + +// VPHSUBSW: Packed Horizontal Subtract Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPHSUBSW xmm xmm xmm +// VPHSUBSW m128 xmm xmm +// VPHSUBSW ymm ymm ymm +// VPHSUBSW m256 ymm ymm +func VPHSUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHSUBSW: bad operands") +} + +// VPHSUBW: Packed Horizontal Subtract Word Integers. +// +// Forms: +// +// VPHSUBW xmm xmm xmm +// VPHSUBW m128 xmm xmm +// VPHSUBW ymm ymm ymm +// VPHSUBW m256 ymm ymm +func VPHSUBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPHSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPHSUBW: bad operands") +} + +// VPINSRB: Insert Byte. +// +// Forms: +// +// VPINSRB imm8 r32 xmm xmm +// VPINSRB imm8 m8 xmm xmm +func VPINSRB(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRB", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM8(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRB", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VPINSRB: bad operands") +} + +// VPINSRD: Insert Doubleword. +// +// Forms: +// +// VPINSRD imm8 r32 xmm xmm +// VPINSRD imm8 m32 xmm xmm +func VPINSRD(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRD", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRD", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VPINSRD: bad operands") +} + +// VPINSRQ: Insert Quadword. +// +// Forms: +// +// VPINSRQ imm8 r64 xmm xmm +// VPINSRQ imm8 m64 xmm xmm +func VPINSRQ(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRQ", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRQ", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VPINSRQ: bad operands") +} + +// VPINSRW: Insert Word. +// +// Forms: +// +// VPINSRW imm8 r32 xmm xmm +// VPINSRW imm8 m16 xmm xmm +func VPINSRW(i, mr, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsR32(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRW", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM16(mr) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VPINSRW", + Operands: []operand.Op{i, mr, x, x1}, + Inputs: []operand.Op{mr, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VPINSRW: bad operands") +} + +// VPMADDUBSW: Multiply and Add Packed Signed and Unsigned Byte Integers. +// +// Forms: +// +// VPMADDUBSW xmm xmm xmm +// VPMADDUBSW m128 xmm xmm +// VPMADDUBSW ymm ymm ymm +// VPMADDUBSW m256 ymm ymm +func VPMADDUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMADDUBSW: bad operands") +} + +// VPMADDWD: Multiply and Add Packed Signed Word Integers. +// +// Forms: +// +// VPMADDWD xmm xmm xmm +// VPMADDWD m128 xmm xmm +// VPMADDWD ymm ymm ymm +// VPMADDWD m256 ymm ymm +func VPMADDWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMADDWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMADDWD: bad operands") +} + +// VPMASKMOVD: Conditional Move Packed Doubleword Integers. +// +// Forms: +// +// VPMASKMOVD m128 xmm xmm +// VPMASKMOVD m256 ymm ymm +// VPMASKMOVD xmm xmm m128 +// VPMASKMOVD ymm ymm m256 +func VPMASKMOVD(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVD", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VPMASKMOVD: bad operands") +} + +// VPMASKMOVQ: Conditional Move Packed Quadword Integers. +// +// Forms: +// +// VPMASKMOVQ m128 xmm xmm +// VPMASKMOVQ m256 ymm ymm +// VPMASKMOVQ xmm xmm m128 +// VPMASKMOVQ ymm ymm m256 +func VPMASKMOVQ(mxy, xy, mxy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsM128(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsM256(mxy1): + return &intrep.Instruction{ + Opcode: "VPMASKMOVQ", + Operands: []operand.Op{mxy, xy, mxy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{mxy1}, + }, nil + } + return nil, errors.New("VPMASKMOVQ: bad operands") +} + +// VPMAXSB: Maximum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMAXSB xmm xmm xmm +// VPMAXSB m128 xmm xmm +// VPMAXSB ymm ymm ymm +// VPMAXSB m256 ymm ymm +func VPMAXSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXSB: bad operands") +} + +// VPMAXSD: Maximum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMAXSD xmm xmm xmm +// VPMAXSD m128 xmm xmm +// VPMAXSD ymm ymm ymm +// VPMAXSD m256 ymm ymm +func VPMAXSD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXSD: bad operands") +} + +// VPMAXSW: Maximum of Packed Signed Word Integers. +// +// Forms: +// +// VPMAXSW xmm xmm xmm +// VPMAXSW m128 xmm xmm +// VPMAXSW ymm ymm ymm +// VPMAXSW m256 ymm ymm +func VPMAXSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXSW: bad operands") +} + +// VPMAXUB: Maximum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMAXUB xmm xmm xmm +// VPMAXUB m128 xmm xmm +// VPMAXUB ymm ymm ymm +// VPMAXUB m256 ymm ymm +func VPMAXUB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXUB: bad operands") +} + +// VPMAXUD: Maximum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMAXUD xmm xmm xmm +// VPMAXUD m128 xmm xmm +// VPMAXUD ymm ymm ymm +// VPMAXUD m256 ymm ymm +func VPMAXUD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXUD: bad operands") +} + +// VPMAXUW: Maximum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMAXUW xmm xmm xmm +// VPMAXUW m128 xmm xmm +// VPMAXUW ymm ymm ymm +// VPMAXUW m256 ymm ymm +func VPMAXUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMAXUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMAXUW: bad operands") +} + +// VPMINSB: Minimum of Packed Signed Byte Integers. +// +// Forms: +// +// VPMINSB xmm xmm xmm +// VPMINSB m128 xmm xmm +// VPMINSB ymm ymm ymm +// VPMINSB m256 ymm ymm +func VPMINSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINSB: bad operands") +} + +// VPMINSD: Minimum of Packed Signed Doubleword Integers. +// +// Forms: +// +// VPMINSD xmm xmm xmm +// VPMINSD m128 xmm xmm +// VPMINSD ymm ymm ymm +// VPMINSD m256 ymm ymm +func VPMINSD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINSD: bad operands") +} + +// VPMINSW: Minimum of Packed Signed Word Integers. +// +// Forms: +// +// VPMINSW xmm xmm xmm +// VPMINSW m128 xmm xmm +// VPMINSW ymm ymm ymm +// VPMINSW m256 ymm ymm +func VPMINSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINSW: bad operands") +} + +// VPMINUB: Minimum of Packed Unsigned Byte Integers. +// +// Forms: +// +// VPMINUB xmm xmm xmm +// VPMINUB m128 xmm xmm +// VPMINUB ymm ymm ymm +// VPMINUB m256 ymm ymm +func VPMINUB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINUB: bad operands") +} + +// VPMINUD: Minimum of Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMINUD xmm xmm xmm +// VPMINUD m128 xmm xmm +// VPMINUD ymm ymm ymm +// VPMINUD m256 ymm ymm +func VPMINUD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINUD: bad operands") +} + +// VPMINUW: Minimum of Packed Unsigned Word Integers. +// +// Forms: +// +// VPMINUW xmm xmm xmm +// VPMINUW m128 xmm xmm +// VPMINUW ymm ymm ymm +// VPMINUW m256 ymm ymm +func VPMINUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMINUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMINUW: bad operands") +} + +// VPMOVMSKB: Move Byte Mask. +// +// Forms: +// +// VPMOVMSKB xmm r32 +// VPMOVMSKB ymm r32 +func VPMOVMSKB(xy, r operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VPMOVMSKB", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + case operand.IsYMM(xy) && operand.IsR32(r): + return &intrep.Instruction{ + Opcode: "VPMOVMSKB", + Operands: []operand.Op{xy, r}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{r}, + }, nil + } + return nil, errors.New("VPMOVMSKB: bad operands") +} + +// VPMOVSXBD: Move Packed Byte Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBD xmm xmm +// VPMOVSXBD m32 xmm +// VPMOVSXBD xmm ymm +// VPMOVSXBD m64 ymm +func VPMOVSXBD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXBD: bad operands") +} + +// VPMOVSXBQ: Move Packed Byte Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBQ xmm xmm +// VPMOVSXBQ m16 xmm +// VPMOVSXBQ xmm ymm +// VPMOVSXBQ m32 ymm +func VPMOVSXBQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXBQ: bad operands") +} + +// VPMOVSXBW: Move Packed Byte Integers to Word Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXBW xmm xmm +// VPMOVSXBW m64 xmm +// VPMOVSXBW xmm ymm +// VPMOVSXBW m128 ymm +func VPMOVSXBW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXBW: bad operands") +} + +// VPMOVSXDQ: Move Packed Doubleword Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXDQ xmm xmm +// VPMOVSXDQ m64 xmm +// VPMOVSXDQ xmm ymm +// VPMOVSXDQ m128 ymm +func VPMOVSXDQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXDQ: bad operands") +} + +// VPMOVSXWD: Move Packed Word Integers to Doubleword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWD xmm xmm +// VPMOVSXWD m64 xmm +// VPMOVSXWD xmm ymm +// VPMOVSXWD m128 ymm +func VPMOVSXWD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXWD: bad operands") +} + +// VPMOVSXWQ: Move Packed Word Integers to Quadword Integers with Sign Extension. +// +// Forms: +// +// VPMOVSXWQ xmm xmm +// VPMOVSXWQ m32 xmm +// VPMOVSXWQ xmm ymm +// VPMOVSXWQ m64 ymm +func VPMOVSXWQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVSXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVSXWQ: bad operands") +} + +// VPMOVZXBD: Move Packed Byte Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBD xmm xmm +// VPMOVZXBD m32 xmm +// VPMOVZXBD xmm ymm +// VPMOVZXBD m64 ymm +func VPMOVZXBD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXBD: bad operands") +} + +// VPMOVZXBQ: Move Packed Byte Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBQ xmm xmm +// VPMOVZXBQ m16 xmm +// VPMOVZXBQ xmm ymm +// VPMOVZXBQ m32 ymm +func VPMOVZXBQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM16(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXBQ: bad operands") +} + +// VPMOVZXBW: Move Packed Byte Integers to Word Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXBW xmm xmm +// VPMOVZXBW m64 xmm +// VPMOVZXBW xmm ymm +// VPMOVZXBW m128 ymm +func VPMOVZXBW(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXBW", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXBW: bad operands") +} + +// VPMOVZXDQ: Move Packed Doubleword Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXDQ xmm xmm +// VPMOVZXDQ m64 xmm +// VPMOVZXDQ xmm ymm +// VPMOVZXDQ m128 ymm +func VPMOVZXDQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXDQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXDQ: bad operands") +} + +// VPMOVZXWD: Move Packed Word Integers to Doubleword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWD xmm xmm +// VPMOVZXWD m64 xmm +// VPMOVZXWD xmm ymm +// VPMOVZXWD m128 ymm +func VPMOVZXWD(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWD", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXWD: bad operands") +} + +// VPMOVZXWQ: Move Packed Word Integers to Quadword Integers with Zero Extension. +// +// Forms: +// +// VPMOVZXWQ xmm xmm +// VPMOVZXWQ m32 xmm +// VPMOVZXWQ xmm ymm +// VPMOVZXWQ m64 ymm +func VPMOVZXWQ(mx, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsXMM(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM64(mx) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPMOVZXWQ", + Operands: []operand.Op{mx, xy}, + Inputs: []operand.Op{mx}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPMOVZXWQ: bad operands") +} + +// VPMULDQ: Multiply Packed Signed Doubleword Integers and Store Quadword Result. +// +// Forms: +// +// VPMULDQ xmm xmm xmm +// VPMULDQ m128 xmm xmm +// VPMULDQ ymm ymm ymm +// VPMULDQ m256 ymm ymm +func VPMULDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULDQ: bad operands") +} + +// VPMULHRSW: Packed Multiply Signed Word Integers and Store High Result with Round and Scale. +// +// Forms: +// +// VPMULHRSW xmm xmm xmm +// VPMULHRSW m128 xmm xmm +// VPMULHRSW ymm ymm ymm +// VPMULHRSW m256 ymm ymm +func VPMULHRSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHRSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULHRSW: bad operands") +} + +// VPMULHUW: Multiply Packed Unsigned Word Integers and Store High Result. +// +// Forms: +// +// VPMULHUW xmm xmm xmm +// VPMULHUW m128 xmm xmm +// VPMULHUW ymm ymm ymm +// VPMULHUW m256 ymm ymm +func VPMULHUW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHUW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULHUW: bad operands") +} + +// VPMULHW: Multiply Packed Signed Word Integers and Store High Result. +// +// Forms: +// +// VPMULHW xmm xmm xmm +// VPMULHW m128 xmm xmm +// VPMULHW ymm ymm ymm +// VPMULHW m256 ymm ymm +func VPMULHW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULHW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULHW: bad operands") +} + +// VPMULLD: Multiply Packed Signed Doubleword Integers and Store Low Result. +// +// Forms: +// +// VPMULLD xmm xmm xmm +// VPMULLD m128 xmm xmm +// VPMULLD ymm ymm ymm +// VPMULLD m256 ymm ymm +func VPMULLD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULLD: bad operands") +} + +// VPMULLW: Multiply Packed Signed Word Integers and Store Low Result. +// +// Forms: +// +// VPMULLW xmm xmm xmm +// VPMULLW m128 xmm xmm +// VPMULLW ymm ymm ymm +// VPMULLW m256 ymm ymm +func VPMULLW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULLW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULLW: bad operands") +} + +// VPMULUDQ: Multiply Packed Unsigned Doubleword Integers. +// +// Forms: +// +// VPMULUDQ xmm xmm xmm +// VPMULUDQ m128 xmm xmm +// VPMULUDQ ymm ymm ymm +// VPMULUDQ m256 ymm ymm +func VPMULUDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPMULUDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPMULUDQ: bad operands") +} + +// VPOR: Packed Bitwise Logical OR. +// +// Forms: +// +// VPOR xmm xmm xmm +// VPOR m128 xmm xmm +// VPOR ymm ymm ymm +// VPOR m256 ymm ymm +func VPOR(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPOR: bad operands") +} + +// VPSADBW: Compute Sum of Absolute Differences. +// +// Forms: +// +// VPSADBW xmm xmm xmm +// VPSADBW m128 xmm xmm +// VPSADBW ymm ymm ymm +// VPSADBW m256 ymm ymm +func VPSADBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSADBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSADBW: bad operands") +} + +// VPSHUFB: Packed Shuffle Bytes. +// +// Forms: +// +// VPSHUFB xmm xmm xmm +// VPSHUFB m128 xmm xmm +// VPSHUFB ymm ymm ymm +// VPSHUFB m256 ymm ymm +func VPSHUFB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSHUFB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSHUFB: bad operands") +} + +// VPSHUFD: Shuffle Packed Doublewords. +// +// Forms: +// +// VPSHUFD imm8 xmm xmm +// VPSHUFD imm8 m128 xmm +// VPSHUFD imm8 ymm ymm +// VPSHUFD imm8 m256 ymm +func VPSHUFD(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPSHUFD: bad operands") +} + +// VPSHUFHW: Shuffle Packed High Words. +// +// Forms: +// +// VPSHUFHW imm8 xmm xmm +// VPSHUFHW imm8 m128 xmm +// VPSHUFHW imm8 ymm ymm +// VPSHUFHW imm8 m256 ymm +func VPSHUFHW(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFHW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPSHUFHW: bad operands") +} + +// VPSHUFLW: Shuffle Packed Low Words. +// +// Forms: +// +// VPSHUFLW imm8 xmm xmm +// VPSHUFLW imm8 m128 xmm +// VPSHUFLW imm8 ymm ymm +// VPSHUFLW imm8 m256 ymm +func VPSHUFLW(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPSHUFLW", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VPSHUFLW: bad operands") +} + +// VPSIGNB: Packed Sign of Byte Integers. +// +// Forms: +// +// VPSIGNB xmm xmm xmm +// VPSIGNB m128 xmm xmm +// VPSIGNB ymm ymm ymm +// VPSIGNB m256 ymm ymm +func VPSIGNB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSIGNB: bad operands") +} + +// VPSIGND: Packed Sign of Doubleword Integers. +// +// Forms: +// +// VPSIGND xmm xmm xmm +// VPSIGND m128 xmm xmm +// VPSIGND ymm ymm ymm +// VPSIGND m256 ymm ymm +func VPSIGND(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGND", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSIGND: bad operands") +} + +// VPSIGNW: Packed Sign of Word Integers. +// +// Forms: +// +// VPSIGNW xmm xmm xmm +// VPSIGNW m128 xmm xmm +// VPSIGNW ymm ymm ymm +// VPSIGNW m256 ymm ymm +func VPSIGNW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSIGNW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSIGNW: bad operands") +} + +// VPSLLD: Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLD imm8 xmm xmm +// VPSLLD xmm xmm xmm +// VPSLLD m128 xmm xmm +// VPSLLD imm8 ymm ymm +// VPSLLD xmm ymm ymm +// VPSLLD m128 ymm ymm +func VPSLLD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLD: bad operands") +} + +// VPSLLDQ: Shift Packed Double Quadword Left Logical. +// +// Forms: +// +// VPSLLDQ imm8 xmm xmm +// VPSLLDQ imm8 ymm ymm +func VPSLLDQ(i, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLDQ: bad operands") +} + +// VPSLLQ: Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLQ imm8 xmm xmm +// VPSLLQ xmm xmm xmm +// VPSLLQ m128 xmm xmm +// VPSLLQ imm8 ymm ymm +// VPSLLQ xmm ymm ymm +// VPSLLQ m128 ymm ymm +func VPSLLQ(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLQ: bad operands") +} + +// VPSLLVD: Variable Shift Packed Doubleword Data Left Logical. +// +// Forms: +// +// VPSLLVD xmm xmm xmm +// VPSLLVD m128 xmm xmm +// VPSLLVD ymm ymm ymm +// VPSLLVD m256 ymm ymm +func VPSLLVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLVD: bad operands") +} + +// VPSLLVQ: Variable Shift Packed Quadword Data Left Logical. +// +// Forms: +// +// VPSLLVQ xmm xmm xmm +// VPSLLVQ m128 xmm xmm +// VPSLLVQ ymm ymm ymm +// VPSLLVQ m256 ymm ymm +func VPSLLVQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLVQ: bad operands") +} + +// VPSLLW: Shift Packed Word Data Left Logical. +// +// Forms: +// +// VPSLLW imm8 xmm xmm +// VPSLLW xmm xmm xmm +// VPSLLW m128 xmm xmm +// VPSLLW imm8 ymm ymm +// VPSLLW xmm ymm ymm +// VPSLLW m128 ymm ymm +func VPSLLW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSLLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSLLW: bad operands") +} + +// VPSRAD: Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAD imm8 xmm xmm +// VPSRAD xmm xmm xmm +// VPSRAD m128 xmm xmm +// VPSRAD imm8 ymm ymm +// VPSRAD xmm ymm ymm +// VPSRAD m128 ymm ymm +func VPSRAD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRAD: bad operands") +} + +// VPSRAVD: Variable Shift Packed Doubleword Data Right Arithmetic. +// +// Forms: +// +// VPSRAVD xmm xmm xmm +// VPSRAVD m128 xmm xmm +// VPSRAVD ymm ymm ymm +// VPSRAVD m256 ymm ymm +func VPSRAVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRAVD: bad operands") +} + +// VPSRAW: Shift Packed Word Data Right Arithmetic. +// +// Forms: +// +// VPSRAW imm8 xmm xmm +// VPSRAW xmm xmm xmm +// VPSRAW m128 xmm xmm +// VPSRAW imm8 ymm ymm +// VPSRAW xmm ymm ymm +// VPSRAW m128 ymm ymm +func VPSRAW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRAW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRAW: bad operands") +} + +// VPSRLD: Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLD imm8 xmm xmm +// VPSRLD xmm xmm xmm +// VPSRLD m128 xmm xmm +// VPSRLD imm8 ymm ymm +// VPSRLD xmm ymm ymm +// VPSRLD m128 ymm ymm +func VPSRLD(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLD", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLD: bad operands") +} + +// VPSRLDQ: Shift Packed Double Quadword Right Logical. +// +// Forms: +// +// VPSRLDQ imm8 xmm xmm +// VPSRLDQ imm8 ymm ymm +func VPSRLDQ(i, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLDQ", + Operands: []operand.Op{i, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLDQ: bad operands") +} + +// VPSRLQ: Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLQ imm8 xmm xmm +// VPSRLQ xmm xmm xmm +// VPSRLQ m128 xmm xmm +// VPSRLQ imm8 ymm ymm +// VPSRLQ xmm ymm ymm +// VPSRLQ m128 ymm ymm +func VPSRLQ(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLQ", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLQ: bad operands") +} + +// VPSRLVD: Variable Shift Packed Doubleword Data Right Logical. +// +// Forms: +// +// VPSRLVD xmm xmm xmm +// VPSRLVD m128 xmm xmm +// VPSRLVD ymm ymm ymm +// VPSRLVD m256 ymm ymm +func VPSRLVD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLVD: bad operands") +} + +// VPSRLVQ: Variable Shift Packed Quadword Data Right Logical. +// +// Forms: +// +// VPSRLVQ xmm xmm xmm +// VPSRLVQ m128 xmm xmm +// VPSRLVQ ymm ymm ymm +// VPSRLVQ m256 ymm ymm +func VPSRLVQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLVQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLVQ: bad operands") +} + +// VPSRLW: Shift Packed Word Data Right Logical. +// +// Forms: +// +// VPSRLW imm8 xmm xmm +// VPSRLW xmm xmm xmm +// VPSRLW m128 xmm xmm +// VPSRLW imm8 ymm ymm +// VPSRLW xmm ymm ymm +// VPSRLW m128 ymm ymm +func VPSRLW(imx, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsXMM(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(imx) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSRLW", + Operands: []operand.Op{imx, xy, xy1}, + Inputs: []operand.Op{imx, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSRLW: bad operands") +} + +// VPSUBB: Subtract Packed Byte Integers. +// +// Forms: +// +// VPSUBB xmm xmm xmm +// VPSUBB m128 xmm xmm +// VPSUBB ymm ymm ymm +// VPSUBB m256 ymm ymm +func VPSUBB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBB: bad operands") +} + +// VPSUBD: Subtract Packed Doubleword Integers. +// +// Forms: +// +// VPSUBD xmm xmm xmm +// VPSUBD m128 xmm xmm +// VPSUBD ymm ymm ymm +// VPSUBD m256 ymm ymm +func VPSUBD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBD: bad operands") +} + +// VPSUBQ: Subtract Packed Quadword Integers. +// +// Forms: +// +// VPSUBQ xmm xmm xmm +// VPSUBQ m128 xmm xmm +// VPSUBQ ymm ymm ymm +// VPSUBQ m256 ymm ymm +func VPSUBQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBQ: bad operands") +} + +// VPSUBSB: Subtract Packed Signed Byte Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSB xmm xmm xmm +// VPSUBSB m128 xmm xmm +// VPSUBSB ymm ymm ymm +// VPSUBSB m256 ymm ymm +func VPSUBSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBSB: bad operands") +} + +// VPSUBSW: Subtract Packed Signed Word Integers with Signed Saturation. +// +// Forms: +// +// VPSUBSW xmm xmm xmm +// VPSUBSW m128 xmm xmm +// VPSUBSW ymm ymm ymm +// VPSUBSW m256 ymm ymm +func VPSUBSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBSW: bad operands") +} + +// VPSUBUSB: Subtract Packed Unsigned Byte Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSB xmm xmm xmm +// VPSUBUSB m128 xmm xmm +// VPSUBUSB ymm ymm ymm +// VPSUBUSB m256 ymm ymm +func VPSUBUSB(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSB", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBUSB: bad operands") +} + +// VPSUBUSW: Subtract Packed Unsigned Word Integers with Unsigned Saturation. +// +// Forms: +// +// VPSUBUSW xmm xmm xmm +// VPSUBUSW m128 xmm xmm +// VPSUBUSW ymm ymm ymm +// VPSUBUSW m256 ymm ymm +func VPSUBUSW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBUSW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBUSW: bad operands") +} + +// VPSUBW: Subtract Packed Word Integers. +// +// Forms: +// +// VPSUBW xmm xmm xmm +// VPSUBW m128 xmm xmm +// VPSUBW ymm ymm ymm +// VPSUBW m256 ymm ymm +func VPSUBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPSUBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPSUBW: bad operands") +} + +// VPTEST: Packed Logical Compare. +// +// Forms: +// +// VPTEST xmm xmm +// VPTEST m128 xmm +// VPTEST ymm ymm +// VPTEST m256 ymm +func VPTEST(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VPTEST", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VPTEST: bad operands") +} + +// VPUNPCKHBW: Unpack and Interleave High-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKHBW xmm xmm xmm +// VPUNPCKHBW m128 xmm xmm +// VPUNPCKHBW ymm ymm ymm +// VPUNPCKHBW m256 ymm ymm +func VPUNPCKHBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKHBW: bad operands") +} + +// VPUNPCKHDQ: Unpack and Interleave High-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKHDQ xmm xmm xmm +// VPUNPCKHDQ m128 xmm xmm +// VPUNPCKHDQ ymm ymm ymm +// VPUNPCKHDQ m256 ymm ymm +func VPUNPCKHDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKHDQ: bad operands") +} + +// VPUNPCKHQDQ: Unpack and Interleave High-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKHQDQ xmm xmm xmm +// VPUNPCKHQDQ m128 xmm xmm +// VPUNPCKHQDQ ymm ymm ymm +// VPUNPCKHQDQ m256 ymm ymm +func VPUNPCKHQDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKHQDQ: bad operands") +} + +// VPUNPCKHWD: Unpack and Interleave High-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKHWD xmm xmm xmm +// VPUNPCKHWD m128 xmm xmm +// VPUNPCKHWD ymm ymm ymm +// VPUNPCKHWD m256 ymm ymm +func VPUNPCKHWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKHWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKHWD: bad operands") +} + +// VPUNPCKLBW: Unpack and Interleave Low-Order Bytes into Words. +// +// Forms: +// +// VPUNPCKLBW xmm xmm xmm +// VPUNPCKLBW m128 xmm xmm +// VPUNPCKLBW ymm ymm ymm +// VPUNPCKLBW m256 ymm ymm +func VPUNPCKLBW(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLBW", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKLBW: bad operands") +} + +// VPUNPCKLDQ: Unpack and Interleave Low-Order Doublewords into Quadwords. +// +// Forms: +// +// VPUNPCKLDQ xmm xmm xmm +// VPUNPCKLDQ m128 xmm xmm +// VPUNPCKLDQ ymm ymm ymm +// VPUNPCKLDQ m256 ymm ymm +func VPUNPCKLDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKLDQ: bad operands") +} + +// VPUNPCKLQDQ: Unpack and Interleave Low-Order Quadwords into Double Quadwords. +// +// Forms: +// +// VPUNPCKLQDQ xmm xmm xmm +// VPUNPCKLQDQ m128 xmm xmm +// VPUNPCKLQDQ ymm ymm ymm +// VPUNPCKLQDQ m256 ymm ymm +func VPUNPCKLQDQ(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLQDQ", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKLQDQ: bad operands") +} + +// VPUNPCKLWD: Unpack and Interleave Low-Order Words into Doublewords. +// +// Forms: +// +// VPUNPCKLWD xmm xmm xmm +// VPUNPCKLWD m128 xmm xmm +// VPUNPCKLWD ymm ymm ymm +// VPUNPCKLWD m256 ymm ymm +func VPUNPCKLWD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPUNPCKLWD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPUNPCKLWD: bad operands") +} + +// VPXOR: Packed Bitwise Logical Exclusive OR. +// +// Forms: +// +// VPXOR xmm xmm xmm +// VPXOR m128 xmm xmm +// VPXOR ymm ymm ymm +// VPXOR m256 ymm ymm +func VPXOR(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VPXOR", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VPXOR: bad operands") +} + +// VRCPPS: Compute Approximate Reciprocals of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPPS xmm xmm +// VRCPPS m128 xmm +// VRCPPS ymm ymm +// VRCPPS m256 ymm +func VRCPPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRCPPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VRCPPS: bad operands") +} + +// VRCPSS: Compute Approximate Reciprocal of Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VRCPSS xmm xmm xmm +// VRCPSS m32 xmm xmm +func VRCPSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRCPSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRCPSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VRCPSS: bad operands") +} + +// VROUNDPD: Round Packed Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPD imm8 xmm xmm +// VROUNDPD imm8 m128 xmm +// VROUNDPD imm8 ymm ymm +// VROUNDPD imm8 m256 ymm +func VROUNDPD(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPD", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VROUNDPD: bad operands") +} + +// VROUNDPS: Round Packed Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDPS imm8 xmm xmm +// VROUNDPS imm8 m128 xmm +// VROUNDPS imm8 ymm ymm +// VROUNDPS imm8 m256 ymm +func VROUNDPS(i, mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VROUNDPS", + Operands: []operand.Op{i, mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VROUNDPS: bad operands") +} + +// VROUNDSD: Round Scalar Double Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSD imm8 xmm xmm xmm +// VROUNDSD imm8 m64 xmm xmm +func VROUNDSD(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSD", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VROUNDSD: bad operands") +} + +// VROUNDSS: Round Scalar Single Precision Floating-Point Values. +// +// Forms: +// +// VROUNDSS imm8 xmm xmm xmm +// VROUNDSS imm8 m32 xmm xmm +func VROUNDSS(i, mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsIMM8(i) && operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VROUNDSS", + Operands: []operand.Op{i, mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VROUNDSS: bad operands") +} + +// VRSQRTPS: Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VRSQRTPS xmm xmm +// VRSQRTPS m128 xmm +// VRSQRTPS ymm ymm +// VRSQRTPS m256 ymm +func VRSQRTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VRSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VRSQRTPS: bad operands") +} + +// VRSQRTSS: Compute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VRSQRTSS xmm xmm xmm +// VRSQRTSS m32 xmm xmm +func VRSQRTSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VRSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VRSQRTSS: bad operands") +} + +// VSHUFPD: Shuffle Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPD imm8 xmm xmm xmm +// VSHUFPD imm8 m128 xmm xmm +// VSHUFPD imm8 ymm ymm ymm +// VSHUFPD imm8 m256 ymm ymm +func VSHUFPD(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPD", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VSHUFPD: bad operands") +} + +// VSHUFPS: Shuffle Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSHUFPS imm8 xmm xmm xmm +// VSHUFPS imm8 m128 xmm xmm +// VSHUFPS imm8 ymm ymm ymm +// VSHUFPS imm8 m256 ymm ymm +func VSHUFPS(i, mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(i) && operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsIMM8(i) && operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSHUFPS", + Operands: []operand.Op{i, mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VSHUFPS: bad operands") +} + +// VSQRTPD: Compute Square Roots of Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPD xmm xmm +// VSQRTPD m128 xmm +// VSQRTPD ymm ymm +// VSQRTPD m256 ymm +func VSQRTPD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VSQRTPD: bad operands") +} + +// VSQRTPS: Compute Square Roots of Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSQRTPS xmm xmm +// VSQRTPS m128 xmm +// VSQRTPS ymm ymm +// VSQRTPS m256 ymm +func VSQRTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VSQRTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy}, + Outputs: []operand.Op{xy}, + }, nil + } + return nil, errors.New("VSQRTPS: bad operands") +} + +// VSQRTSD: Compute Square Root of Scalar Double-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSD xmm xmm xmm +// VSQRTSD m64 xmm xmm +func VSQRTSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VSQRTSD: bad operands") +} + +// VSQRTSS: Compute Square Root of Scalar Single-Precision Floating-Point Value. +// +// Forms: +// +// VSQRTSS xmm xmm xmm +// VSQRTSS m32 xmm xmm +func VSQRTSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSQRTSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VSQRTSS: bad operands") +} + +// VSTMXCSR: Store MXCSR Register State. +// +// Forms: +// +// VSTMXCSR m32 +func VSTMXCSR(m operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsM32(m): + return &intrep.Instruction{ + Opcode: "VSTMXCSR", + Operands: []operand.Op{m}, + Inputs: []operand.Op{}, + Outputs: []operand.Op{m}, + }, nil + } + return nil, errors.New("VSTMXCSR: bad operands") +} + +// VSUBPD: Subtract Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPD xmm xmm xmm +// VSUBPD m128 xmm xmm +// VSUBPD ymm ymm ymm +// VSUBPD m256 ymm ymm +func VSUBPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VSUBPD: bad operands") +} + +// VSUBPS: Subtract Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBPS xmm xmm xmm +// VSUBPS m128 xmm xmm +// VSUBPS ymm ymm ymm +// VSUBPS m256 ymm ymm +func VSUBPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VSUBPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VSUBPS: bad operands") +} + +// VSUBSD: Subtract Scalar Double-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSD xmm xmm xmm +// VSUBSD m64 xmm xmm +func VSUBSD(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSD", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VSUBSD: bad operands") +} + +// VSUBSS: Subtract Scalar Single-Precision Floating-Point Values. +// +// Forms: +// +// VSUBSS xmm xmm xmm +// VSUBSS m32 xmm xmm +func VSUBSS(mx, x, x1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x) && operand.IsXMM(x1): + return &intrep.Instruction{ + Opcode: "VSUBSS", + Operands: []operand.Op{mx, x, x1}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x1}, + }, nil + } + return nil, errors.New("VSUBSS: bad operands") +} + +// VTESTPD: Packed Double-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPD xmm xmm +// VTESTPD m128 xmm +// VTESTPD ymm ymm +// VTESTPD m256 ymm +func VTESTPD(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPD", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VTESTPD: bad operands") +} + +// VTESTPS: Packed Single-Precision Floating-Point Bit Test. +// +// Forms: +// +// VTESTPS xmm xmm +// VTESTPS m128 xmm +// VTESTPS ymm ymm +// VTESTPS m256 ymm +func VTESTPS(mxy, xy operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy): + return &intrep.Instruction{ + Opcode: "VTESTPS", + Operands: []operand.Op{mxy, xy}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VTESTPS: bad operands") +} + +// VUCOMISD: Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISD xmm xmm +// VUCOMISD m64 xmm +func VUCOMISD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM64(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VUCOMISD: bad operands") +} + +// VUCOMISS: Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS. +// +// Forms: +// +// VUCOMISS xmm xmm +// VUCOMISS m32 xmm +func VUCOMISS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + case operand.IsM32(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "VUCOMISS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{}, + }, nil + } + return nil, errors.New("VUCOMISS: bad operands") +} + +// VUNPCKHPD: Unpack and Interleave High Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPD xmm xmm xmm +// VUNPCKHPD m128 xmm xmm +// VUNPCKHPD ymm ymm ymm +// VUNPCKHPD m256 ymm ymm +func VUNPCKHPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VUNPCKHPD: bad operands") +} + +// VUNPCKHPS: Unpack and Interleave High Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKHPS xmm xmm xmm +// VUNPCKHPS m128 xmm xmm +// VUNPCKHPS ymm ymm ymm +// VUNPCKHPS m256 ymm ymm +func VUNPCKHPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKHPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VUNPCKHPS: bad operands") +} + +// VUNPCKLPD: Unpack and Interleave Low Packed Double-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPD xmm xmm xmm +// VUNPCKLPD m128 xmm xmm +// VUNPCKLPD ymm ymm ymm +// VUNPCKLPD m256 ymm ymm +func VUNPCKLPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VUNPCKLPD: bad operands") +} + +// VUNPCKLPS: Unpack and Interleave Low Packed Single-Precision Floating-Point Values. +// +// Forms: +// +// VUNPCKLPS xmm xmm xmm +// VUNPCKLPS m128 xmm xmm +// VUNPCKLPS ymm ymm ymm +// VUNPCKLPS m256 ymm ymm +func VUNPCKLPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VUNPCKLPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VUNPCKLPS: bad operands") +} + +// VXORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// VXORPD xmm xmm xmm +// VXORPD m128 xmm xmm +// VXORPD ymm ymm ymm +// VXORPD m256 ymm ymm +func VXORPD(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPD", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VXORPD: bad operands") +} + +// VXORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// VXORPS xmm xmm xmm +// VXORPS m128 xmm xmm +// VXORPS ymm ymm ymm +// VXORPS m256 ymm ymm +func VXORPS(mxy, xy, xy1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM128(mxy) && operand.IsXMM(xy) && operand.IsXMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsYMM(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + case operand.IsM256(mxy) && operand.IsYMM(xy) && operand.IsYMM(xy1): + return &intrep.Instruction{ + Opcode: "VXORPS", + Operands: []operand.Op{mxy, xy, xy1}, + Inputs: []operand.Op{mxy, xy}, + Outputs: []operand.Op{xy1}, + }, nil + } + return nil, errors.New("VXORPS: bad operands") +} + +// VZEROALL: Zero All YMM Registers. +// +// Forms: +// +// VZEROALL +func VZEROALL() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "VZEROALL", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// VZEROUPPER: Zero Upper Bits of YMM Registers. +// +// Forms: +// +// VZEROUPPER +func VZEROUPPER() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "VZEROUPPER", + Operands: nil, + Inputs: []operand.Op{}, + Outputs: []operand.Op{}, + }, nil +} + +// XADDB: Exchange and Add. +// +// Forms: +// +// XADDB r8 r8 +// XADDB r8 m8 +func XADDB(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(r) && operand.IsR8(mr): + return &intrep.Instruction{ + Opcode: "XADDB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR8(r) && operand.IsM8(mr): + return &intrep.Instruction{ + Opcode: "XADDB", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDB: bad operands") +} + +// XADDL: Exchange and Add. +// +// Forms: +// +// XADDL r32 r32 +// XADDL r32 m32 +func XADDL(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(r) && operand.IsR32(mr): + return &intrep.Instruction{ + Opcode: "XADDL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR32(r) && operand.IsM32(mr): + return &intrep.Instruction{ + Opcode: "XADDL", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDL: bad operands") +} + +// XADDQ: Exchange and Add. +// +// Forms: +// +// XADDQ r64 r64 +// XADDQ r64 m64 +func XADDQ(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(r) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XADDQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR64(r) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XADDQ", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDQ: bad operands") +} + +// XADDW: Exchange and Add. +// +// Forms: +// +// XADDW r16 r16 +// XADDW r16 m16 +func XADDW(r, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(r) && operand.IsR16(mr): + return &intrep.Instruction{ + Opcode: "XADDW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + case operand.IsR16(r) && operand.IsM16(mr): + return &intrep.Instruction{ + Opcode: "XADDW", + Operands: []operand.Op{r, mr}, + Inputs: []operand.Op{r, mr}, + Outputs: []operand.Op{r, mr}, + }, nil + } + return nil, errors.New("XADDW: bad operands") +} + +// XCHGB: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGB r8 r8 +// XCHGB m8 r8 +// XCHGB r8 m8 +func XCHGB(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR8(mr) && operand.IsR8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsM8(mr) && operand.IsR8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR8(mr) && operand.IsM8(mr1): + return &intrep.Instruction{ + Opcode: "XCHGB", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + } + return nil, errors.New("XCHGB: bad operands") +} + +// XCHGL: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGL r32 eax +// XCHGL eax r32 +// XCHGL r32 r32 +// XCHGL m32 r32 +// XCHGL r32 m32 +func XCHGL(emr, emr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR32(emr) && operand.IsEAX(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsEAX(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsR32(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsM32(emr) && operand.IsR32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + case operand.IsR32(emr) && operand.IsM32(emr1): + return &intrep.Instruction{ + Opcode: "XCHGL", + Operands: []operand.Op{emr, emr1}, + Inputs: []operand.Op{emr, emr1}, + Outputs: []operand.Op{emr, emr1}, + }, nil + } + return nil, errors.New("XCHGL: bad operands") +} + +// XCHGQ: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGQ r64 rax +// XCHGQ rax r64 +// XCHGQ r64 r64 +// XCHGQ m64 r64 +// XCHGQ r64 m64 +func XCHGQ(mr, mr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR64(mr) && operand.IsRAX(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsRAX(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsM64(mr) && operand.IsR64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + case operand.IsR64(mr) && operand.IsM64(mr1): + return &intrep.Instruction{ + Opcode: "XCHGQ", + Operands: []operand.Op{mr, mr1}, + Inputs: []operand.Op{mr, mr1}, + Outputs: []operand.Op{mr, mr1}, + }, nil + } + return nil, errors.New("XCHGQ: bad operands") +} + +// XCHGW: Exchange Register/Memory with Register. +// +// Forms: +// +// XCHGW r16 ax +// XCHGW ax r16 +// XCHGW r16 r16 +// XCHGW m16 r16 +// XCHGW r16 m16 +func XCHGW(amr, amr1 operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsR16(amr) && operand.IsAX(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsAX(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsR16(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsM16(amr) && operand.IsR16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + case operand.IsR16(amr) && operand.IsM16(amr1): + return &intrep.Instruction{ + Opcode: "XCHGW", + Operands: []operand.Op{amr, amr1}, + Inputs: []operand.Op{amr, amr1}, + Outputs: []operand.Op{amr, amr1}, + }, nil + } + return nil, errors.New("XCHGW: bad operands") +} + +// XGETBV: Get Value of Extended Control Register. +// +// Forms: +// +// XGETBV +func XGETBV() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "XGETBV", + Operands: nil, + Inputs: []operand.Op{reg.ECX}, + Outputs: []operand.Op{reg.EAX, reg.EDX}, + }, nil +} + +// XLAT: Table Look-up Translation. +// +// Forms: +// +// XLAT +func XLAT() (*intrep.Instruction, error) { + return &intrep.Instruction{ + Opcode: "XLAT", + Operands: nil, + Inputs: []operand.Op{reg.AL, reg.EBX}, + Outputs: []operand.Op{reg.AL}, + }, nil +} + +// XORB: Logical Exclusive OR. +// +// Forms: +// +// XORB imm8 al +// XORB imm8 r8 +// XORB r8 r8 +// XORB m8 r8 +// XORB imm8 m8 +// XORB r8 m8 +func XORB(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM8(imr) && operand.IsAL(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM8(imr) && operand.IsR8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR8(imr) && operand.IsM8(amr): + return &intrep.Instruction{ + Opcode: "XORB", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("XORB: bad operands") +} + +// XORL: Logical Exclusive OR. +// +// Forms: +// +// XORL imm32 eax +// XORL imm8 r32 +// XORL imm32 r32 +// XORL r32 r32 +// XORL m32 r32 +// XORL imm8 m32 +// XORL imm32 m32 +// XORL r32 m32 +func XORL(imr, emr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsEAX(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsM32(imr) && operand.IsR32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{emr}, + Outputs: []operand.Op{emr}, + }, nil + case operand.IsR32(imr) && operand.IsM32(emr): + return &intrep.Instruction{ + Opcode: "XORL", + Operands: []operand.Op{imr, emr}, + Inputs: []operand.Op{imr, emr}, + Outputs: []operand.Op{emr}, + }, nil + } + return nil, errors.New("XORL: bad operands") +} + +// XORPD: Bitwise Logical XOR for Double-Precision Floating-Point Values. +// +// Forms: +// +// XORPD xmm xmm +// XORPD m128 xmm +func XORPD(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPD", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("XORPD: bad operands") +} + +// XORPS: Bitwise Logical XOR for Single-Precision Floating-Point Values. +// +// Forms: +// +// XORPS xmm xmm +// XORPS m128 xmm +func XORPS(mx, x operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsXMM(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + case operand.IsM128(mx) && operand.IsXMM(x): + return &intrep.Instruction{ + Opcode: "XORPS", + Operands: []operand.Op{mx, x}, + Inputs: []operand.Op{mx, x}, + Outputs: []operand.Op{x}, + }, nil + } + return nil, errors.New("XORPS: bad operands") +} + +// XORQ: Logical Exclusive OR. +// +// Forms: +// +// XORQ imm32 rax +// XORQ imm8 r64 +// XORQ imm32 r64 +// XORQ r64 r64 +// XORQ m64 r64 +// XORQ imm8 m64 +// XORQ imm32 m64 +// XORQ r64 m64 +func XORQ(imr, mr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM32(imr) && operand.IsRAX(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsM64(imr) && operand.IsR64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsIMM32(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{mr}, + Outputs: []operand.Op{mr}, + }, nil + case operand.IsR64(imr) && operand.IsM64(mr): + return &intrep.Instruction{ + Opcode: "XORQ", + Operands: []operand.Op{imr, mr}, + Inputs: []operand.Op{imr, mr}, + Outputs: []operand.Op{mr}, + }, nil + } + return nil, errors.New("XORQ: bad operands") +} + +// XORW: Logical Exclusive OR. +// +// Forms: +// +// XORW imm16 ax +// XORW imm8 r16 +// XORW imm16 r16 +// XORW r16 r16 +// XORW m16 r16 +// XORW imm8 m16 +// XORW imm16 m16 +// XORW r16 m16 +func XORW(imr, amr operand.Op) (*intrep.Instruction, error) { + switch { + case operand.IsIMM16(imr) && operand.IsAX(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsM16(imr) && operand.IsR16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM8(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsIMM16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{amr}, + Outputs: []operand.Op{amr}, + }, nil + case operand.IsR16(imr) && operand.IsM16(amr): + return &intrep.Instruction{ + Opcode: "XORW", + Operands: []operand.Op{imr, amr}, + Inputs: []operand.Op{imr, amr}, + Outputs: []operand.Op{amr}, + }, nil + } + return nil, errors.New("XORW: bad operands") +} diff --git a/vendor/github.com/mr-tron/base58/LICENSE b/vendor/github.com/mr-tron/base58/LICENSE new file mode 100644 index 00000000..cb7829a2 --- /dev/null +++ b/vendor/github.com/mr-tron/base58/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2017 Denis Subbotin +Copyright (c) 2017 Nika Jones +Copyright (c) 2017 Philip Schlump + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mr-tron/base58/base58/DEPRECATED.md b/vendor/github.com/mr-tron/base58/base58/DEPRECATED.md new file mode 100644 index 00000000..0cc7ec72 --- /dev/null +++ b/vendor/github.com/mr-tron/base58/base58/DEPRECATED.md @@ -0,0 +1,4 @@ +Files from this directory was copied to level up directory +========================================================== + +Now all development will be on top level \ No newline at end of file diff --git a/vendor/github.com/mr-tron/base58/base58/alphabet.go b/vendor/github.com/mr-tron/base58/base58/alphabet.go new file mode 100644 index 00000000..a0f88783 --- /dev/null +++ b/vendor/github.com/mr-tron/base58/base58/alphabet.go @@ -0,0 +1,31 @@ +package base58 + +// Alphabet is a a b58 alphabet. +type Alphabet struct { + decode [128]int8 + encode [58]byte +} + +// NewAlphabet creates a new alphabet from the passed string. +// +// It panics if the passed string is not 58 bytes long or isn't valid ASCII. +func NewAlphabet(s string) *Alphabet { + if len(s) != 58 { + panic("base58 alphabets must be 58 bytes long") + } + ret := new(Alphabet) + copy(ret.encode[:], s) + for i := range ret.decode { + ret.decode[i] = -1 + } + for i, b := range ret.encode { + ret.decode[b] = int8(i) + } + return ret +} + +// BTCAlphabet is the bitcoin base58 alphabet. +var BTCAlphabet = NewAlphabet("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") + +// FlickrAlphabet is the flickr base58 alphabet. +var FlickrAlphabet = NewAlphabet("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") diff --git a/vendor/github.com/mr-tron/base58/base58/base58.go b/vendor/github.com/mr-tron/base58/base58/base58.go new file mode 100644 index 00000000..0bbdfc0b --- /dev/null +++ b/vendor/github.com/mr-tron/base58/base58/base58.go @@ -0,0 +1,261 @@ +package base58 + +import ( + "fmt" + "math/big" +) + +var ( + bn0 = big.NewInt(0) + bn58 = big.NewInt(58) +) + +// Encode encodes the passed bytes into a base58 encoded string. +func Encode(bin []byte) string { + return FastBase58Encoding(bin) +} + +// EncodeAlphabet encodes the passed bytes into a base58 encoded string with the +// passed alphabet. +func EncodeAlphabet(bin []byte, alphabet *Alphabet) string { + return FastBase58EncodingAlphabet(bin, alphabet) +} + +// FastBase58Encoding encodes the passed bytes into a base58 encoded string. +func FastBase58Encoding(bin []byte) string { + return FastBase58EncodingAlphabet(bin, BTCAlphabet) +} + +// FastBase58EncodingAlphabet encodes the passed bytes into a base58 encoded +// string with the passed alphabet. +func FastBase58EncodingAlphabet(bin []byte, alphabet *Alphabet) string { + zero := alphabet.encode[0] + + binsz := len(bin) + var i, j, zcount, high int + var carry uint32 + + for zcount < binsz && bin[zcount] == 0 { + zcount++ + } + + size := ((binsz-zcount)*138/100 + 1) + + // allocate one big buffer up front + buf := make([]byte, size*2+zcount) + + // use the second half for the temporary buffer + tmp := buf[size+zcount:] + + high = size - 1 + for i = zcount; i < binsz; i++ { + j = size - 1 + for carry = uint32(bin[i]); j > high || carry != 0; j-- { + carry = carry + 256*uint32(tmp[j]) + tmp[j] = byte(carry % 58) + carry /= 58 + } + high = j + } + + for j = 0; j < size && tmp[j] == 0; j++ { + } + + // Use the first half for the result + b58 := buf[:size-j+zcount] + + if zcount != 0 { + for i = 0; i < zcount; i++ { + b58[i] = zero + } + } + + for i = zcount; j < size; i++ { + b58[i] = alphabet.encode[tmp[j]] + j++ + } + + return string(b58) +} + +// TrivialBase58Encoding encodes the passed bytes into a base58 encoded string +// (inefficiently). +func TrivialBase58Encoding(a []byte) string { + return TrivialBase58EncodingAlphabet(a, BTCAlphabet) +} + +// TrivialBase58EncodingAlphabet encodes the passed bytes into a base58 encoded +// string (inefficiently) with the passed alphabet. +func TrivialBase58EncodingAlphabet(a []byte, alphabet *Alphabet) string { + zero := alphabet.encode[0] + idx := len(a)*138/100 + 1 + buf := make([]byte, idx) + bn := new(big.Int).SetBytes(a) + var mo *big.Int + for bn.Cmp(bn0) != 0 { + bn, mo = bn.DivMod(bn, bn58, new(big.Int)) + idx-- + buf[idx] = alphabet.encode[mo.Int64()] + } + for i := range a { + if a[i] != 0 { + break + } + idx-- + buf[idx] = zero + } + return string(buf[idx:]) +} + +// Decode decodes the base58 encoded bytes. +func Decode(str string) ([]byte, error) { + return FastBase58Decoding(str) +} + +// DecodeAlphabet decodes the base58 encoded bytes using the given b58 alphabet. +func DecodeAlphabet(str string, alphabet *Alphabet) ([]byte, error) { + return FastBase58DecodingAlphabet(str, alphabet) +} + +// FastBase58Decoding decodes the base58 encoded bytes. +func FastBase58Decoding(str string) ([]byte, error) { + return FastBase58DecodingAlphabet(str, BTCAlphabet) +} + +// FastBase58DecodingAlphabet decodes the base58 encoded bytes using the given +// b58 alphabet. +func FastBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { + if len(str) == 0 { + return nil, fmt.Errorf("zero length string") + } + + var ( + t uint64 + zmask, c uint32 + zcount int + + b58u = []rune(str) + b58sz = len(b58u) + + outisz = (b58sz + 3) / 4 // check to see if we need to change this buffer size to optimize + binu = make([]byte, (b58sz+3)*3) + bytesleft = b58sz % 4 + + zero = rune(alphabet.encode[0]) + ) + + if bytesleft > 0 { + zmask = (0xffffffff << uint32(bytesleft*8)) + } else { + bytesleft = 4 + } + + var outi = make([]uint32, outisz) + + for i := 0; i < b58sz && b58u[i] == zero; i++ { + zcount++ + } + + for _, r := range b58u { + if r > 127 { + return nil, fmt.Errorf("High-bit set on invalid digit") + } + if alphabet.decode[r] == -1 { + return nil, fmt.Errorf("Invalid base58 digit (%q)", r) + } + + c = uint32(alphabet.decode[r]) + + for j := (outisz - 1); j >= 0; j-- { + t = uint64(outi[j])*58 + uint64(c) + c = uint32(t>>32) & 0x3f + outi[j] = uint32(t & 0xffffffff) + } + + if c > 0 { + return nil, fmt.Errorf("Output number too big (carry to the next int32)") + } + + if outi[0]&zmask != 0 { + return nil, fmt.Errorf("Output number too big (last int32 filled too far)") + } + } + + // the nested for-loop below is the same as the original code: + // switch (bytesleft) { + // case 3: + // *(binu++) = (outi[0] & 0xff0000) >> 16; + // //-fallthrough + // case 2: + // *(binu++) = (outi[0] & 0xff00) >> 8; + // //-fallthrough + // case 1: + // *(binu++) = (outi[0] & 0xff); + // ++j; + // //-fallthrough + // default: + // break; + // } + // + // for (; j < outisz; ++j) + // { + // *(binu++) = (outi[j] >> 0x18) & 0xff; + // *(binu++) = (outi[j] >> 0x10) & 0xff; + // *(binu++) = (outi[j] >> 8) & 0xff; + // *(binu++) = (outi[j] >> 0) & 0xff; + // } + var j, cnt int + for j, cnt = 0, 0; j < outisz; j++ { + for mask := byte(bytesleft-1) * 8; mask <= 0x18; mask, cnt = mask-8, cnt+1 { + binu[cnt] = byte(outi[j] >> mask) + } + if j == 0 { + bytesleft = 4 // because it could be less than 4 the first time through + } + } + + for n, v := range binu { + if v > 0 { + start := n - zcount + if start < 0 { + start = 0 + } + return binu[start:cnt], nil + } + } + return binu[:cnt], nil +} + +// TrivialBase58Decoding decodes the base58 encoded bytes (inefficiently). +func TrivialBase58Decoding(str string) ([]byte, error) { + return TrivialBase58DecodingAlphabet(str, BTCAlphabet) +} + +// TrivialBase58DecodingAlphabet decodes the base58 encoded bytes +// (inefficiently) using the given b58 alphabet. +func TrivialBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { + zero := alphabet.encode[0] + + var zcount int + for i := 0; i < len(str) && str[i] == zero; i++ { + zcount++ + } + leading := make([]byte, zcount) + + var padChar rune = -1 + src := []byte(str) + j := 0 + for ; j < len(src) && src[j] == byte(padChar); j++ { + } + + n := new(big.Int) + for i := range src[j:] { + c := alphabet.decode[src[i]] + if c == -1 { + return nil, fmt.Errorf("illegal base58 data at input index: %d", i) + } + n.Mul(n, bn58) + n.Add(n, big.NewInt(int64(c))) + } + return append(leading, n.Bytes()...), nil +} diff --git a/vendor/github.com/multiformats/go-base32/LICENSE b/vendor/github.com/multiformats/go-base32/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/github.com/multiformats/go-base32/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +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. diff --git a/vendor/github.com/multiformats/go-base32/base32.go b/vendor/github.com/multiformats/go-base32/base32.go new file mode 100644 index 00000000..768a2350 --- /dev/null +++ b/vendor/github.com/multiformats/go-base32/base32.go @@ -0,0 +1,505 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package base32 implements base32 encoding as specified by RFC 4648. +package base32 + +import ( + "io" + "strconv" +) + +/* + * Encodings + */ + +// An Encoding is a radix 32 encoding/decoding scheme, defined by a +// 32-character alphabet. The most common is the "base32" encoding +// introduced for SASL GSSAPI and standardized in RFC 4648. +// The alternate "base32hex" encoding is used in DNSSEC. +type Encoding struct { + encode string + decodeMap [256]byte + padChar rune +} + +// Alphabet returns the Base32 alphabet used +func (enc *Encoding) Alphabet() string { + return enc.encode +} + +const ( + StdPadding rune = '=' + NoPadding rune = -1 +) + +const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" +const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV" + +// NewEncoding returns a new Encoding defined by the given alphabet, +// which must be a 32-byte string. +func NewEncoding(encoder string) *Encoding { + e := new(Encoding) + e.padChar = StdPadding + e.encode = encoder + for i := 0; i < len(e.decodeMap); i++ { + e.decodeMap[i] = 0xFF + } + for i := 0; i < len(encoder); i++ { + e.decodeMap[encoder[i]] = byte(i) + } + return e +} + +// NewEncoding returns a new case insensitive Encoding defined by the +// given alphabet, which must be a 32-byte string. +func NewEncodingCI(encoder string) *Encoding { + e := new(Encoding) + e.padChar = StdPadding + e.encode = encoder + for i := 0; i < len(e.decodeMap); i++ { + e.decodeMap[i] = 0xFF + } + for i := 0; i < len(encoder); i++ { + e.decodeMap[asciiToLower(encoder[i])] = byte(i) + e.decodeMap[asciiToUpper(encoder[i])] = byte(i) + } + return e +} + +func asciiToLower(c byte) byte { + if c >= 'A' && c <= 'Z' { + return c + 32 + } + return c +} + +func asciiToUpper(c byte) byte { + if c >= 'a' && c <= 'z' { + return c - 32 + } + return c +} + +// WithPadding creates a new encoding identical to enc except +// with a specified padding character, or NoPadding to disable padding. +func (enc Encoding) WithPadding(padding rune) *Encoding { + enc.padChar = padding + return &enc +} + +// StdEncoding is the standard base32 encoding, as defined in +// RFC 4648. +var StdEncoding = NewEncodingCI(encodeStd) + +// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648. +// It is typically used in DNS. +var HexEncoding = NewEncodingCI(encodeHex) + +var RawStdEncoding = NewEncodingCI(encodeStd).WithPadding(NoPadding) +var RawHexEncoding = NewEncodingCI(encodeHex).WithPadding(NoPadding) + +/* + * Encoder + */ + +// Encode encodes src using the encoding enc, writing +// EncodedLen(len(src)) bytes to dst. +// +// The encoding pads the output to a multiple of 8 bytes, +// so Encode is not appropriate for use on individual blocks +// of a large data stream. Use NewEncoder() instead. +func (enc *Encoding) Encode(dst, src []byte) { + if len(src) == 0 { + return + } + + for len(src) > 0 { + var carry byte + + // Unpack 8x 5-bit source blocks into a 5 byte + // destination quantum + switch len(src) { + default: + dst[7] = enc.encode[src[4]&0x1F] + carry = src[4] >> 5 + fallthrough + case 4: + dst[6] = enc.encode[carry|(src[3]<<3)&0x1F] + dst[5] = enc.encode[(src[3]>>2)&0x1F] + carry = src[3] >> 7 + fallthrough + case 3: + dst[4] = enc.encode[carry|(src[2]<<1)&0x1F] + carry = (src[2] >> 4) & 0x1F + fallthrough + case 2: + dst[3] = enc.encode[carry|(src[1]<<4)&0x1F] + dst[2] = enc.encode[(src[1]>>1)&0x1F] + carry = (src[1] >> 6) & 0x1F + fallthrough + case 1: + dst[1] = enc.encode[carry|(src[0]<<2)&0x1F] + dst[0] = enc.encode[src[0]>>3] + } + + // Pad the final quantum + if len(src) < 5 { + if enc.padChar != NoPadding { + dst[7] = byte(enc.padChar) + if len(src) < 4 { + dst[6] = byte(enc.padChar) + dst[5] = byte(enc.padChar) + if len(src) < 3 { + dst[4] = byte(enc.padChar) + if len(src) < 2 { + dst[3] = byte(enc.padChar) + dst[2] = byte(enc.padChar) + } + } + } + } + break + } + src = src[5:] + dst = dst[8:] + } +} + +// EncodeToString returns the base32 encoding of src. +func (enc *Encoding) EncodeToString(src []byte) string { + buf := make([]byte, enc.EncodedLen(len(src))) + enc.Encode(buf, src) + return string(buf) +} + +type encoder struct { + err error + enc *Encoding + w io.Writer + buf [5]byte // buffered data waiting to be encoded + nbuf int // number of bytes in buf + out [1024]byte // output buffer +} + +func (e *encoder) Write(p []byte) (n int, err error) { + if e.err != nil { + return 0, e.err + } + + // Leading fringe. + if e.nbuf > 0 { + var i int + for i = 0; i < len(p) && e.nbuf < 5; i++ { + e.buf[e.nbuf] = p[i] + e.nbuf++ + } + n += i + p = p[i:] + if e.nbuf < 5 { + return + } + e.enc.Encode(e.out[0:], e.buf[0:]) + if _, e.err = e.w.Write(e.out[0:8]); e.err != nil { + return n, e.err + } + e.nbuf = 0 + } + + // Large interior chunks. + for len(p) >= 5 { + nn := len(e.out) / 8 * 5 + if nn > len(p) { + nn = len(p) + nn -= nn % 5 + } + e.enc.Encode(e.out[0:], p[0:nn]) + if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil { + return n, e.err + } + n += nn + p = p[nn:] + } + + // Trailing fringe. + for i := 0; i < len(p); i++ { + e.buf[i] = p[i] + } + e.nbuf = len(p) + n += len(p) + return +} + +// Close flushes any pending output from the encoder. +// It is an error to call Write after calling Close. +func (e *encoder) Close() error { + // If there's anything left in the buffer, flush it out + if e.err == nil && e.nbuf > 0 { + e.enc.Encode(e.out[0:], e.buf[0:e.nbuf]) + e.nbuf = 0 + _, e.err = e.w.Write(e.out[0:8]) + } + return e.err +} + +// NewEncoder returns a new base32 stream encoder. Data written to +// the returned writer will be encoded using enc and then written to w. +// Base32 encodings operate in 5-byte blocks; when finished +// writing, the caller must Close the returned encoder to flush any +// partially written blocks. +func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser { + return &encoder{enc: enc, w: w} +} + +// EncodedLen returns the length in bytes of the base32 encoding +// of an input buffer of length n. +func (enc *Encoding) EncodedLen(n int) int { + if enc.padChar == NoPadding { + return (n*8 + 4) / 5 // minimum # chars at 5 bits per char + } + return (n + 4) / 5 * 8 +} + +/* + * Decoder + */ + +type CorruptInputError int64 + +func (e CorruptInputError) Error() string { + return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10) +} + +// decode is like Decode but returns an additional 'end' value, which +// indicates if end-of-message padding was encountered and thus any +// additional data is an error. This method assumes that src has been +// stripped of all supported whitespace ('\r' and '\n'). +func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { + olen := len(src) + for len(src) > 0 && !end { + // Decode quantum using the base32 alphabet + var dbuf [8]byte + dlen := 8 + + for j := 0; j < 8; { + if len(src) == 0 { + if enc.padChar != NoPadding { + return n, false, CorruptInputError(olen - len(src) - j) + } + dlen = j + break + } + in := src[0] + src = src[1:] + if in == byte(enc.padChar) && j >= 2 && len(src) < 8 { + if enc.padChar == NoPadding { + return n, false, CorruptInputError(olen) + } + + // We've reached the end and there's padding + if len(src)+j < 8-1 { + // not enough padding + return n, false, CorruptInputError(olen) + } + for k := 0; k < 8-1-j; k++ { + if len(src) > k && src[k] != byte(enc.padChar) { + // incorrect padding + return n, false, CorruptInputError(olen - len(src) + k - 1) + } + } + dlen, end = j, true + // 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not + // valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing + // the five valid padding lengths, and Section 9 "Illustrations and + // Examples" for an illustration for how the 1st, 3rd and 6th base32 + // src bytes do not yield enough information to decode a dst byte. + if dlen == 1 || dlen == 3 || dlen == 6 { + return n, false, CorruptInputError(olen - len(src) - 1) + } + break + } + dbuf[j] = enc.decodeMap[in] + if dbuf[j] == 0xFF { + return n, false, CorruptInputError(olen - len(src) - 1) + } + j++ + } + + // Pack 8x 5-bit source blocks into 5 byte destination + // quantum + switch dlen { + case 8: + dst[4] = dbuf[6]<<5 | dbuf[7] + fallthrough + case 7: + dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3 + fallthrough + case 5: + dst[2] = dbuf[3]<<4 | dbuf[4]>>1 + fallthrough + case 4: + dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4 + fallthrough + case 2: + dst[0] = dbuf[0]<<3 | dbuf[1]>>2 + } + + if len(dst) > 5 { + dst = dst[5:] + } + + switch dlen { + case 2: + n += 1 + case 4: + n += 2 + case 5: + n += 3 + case 7: + n += 4 + case 8: + n += 5 + } + } + return n, end, nil +} + +// Decode decodes src using the encoding enc. It writes at most +// DecodedLen(len(src)) bytes to dst and returns the number of bytes +// written. If src contains invalid base32 data, it will return the +// number of bytes successfully written and CorruptInputError. +// New line characters (\r and \n) are ignored. +func (enc *Encoding) Decode(dst, s []byte) (n int, err error) { + // FIXME: if dst is the same as s use decodeInPlace + stripped := make([]byte, 0, len(s)) + for _, c := range s { + if c != '\r' && c != '\n' { + stripped = append(stripped, c) + } + } + n, _, err = enc.decode(dst, stripped) + return +} + +func (enc *Encoding) decodeInPlace(strb []byte) (n int, err error) { + off := 0 + for _, b := range strb { + if b == '\n' || b == '\r' { + continue + } + strb[off] = b + off++ + } + n, _, err = enc.decode(strb, strb[:off]) + return +} + +// DecodeString returns the bytes represented by the base32 string s. +func (enc *Encoding) DecodeString(s string) ([]byte, error) { + strb := []byte(s) + n, err := enc.decodeInPlace(strb) + if err != nil { + return nil, err + } + return strb[:n], nil +} + +type decoder struct { + err error + enc *Encoding + r io.Reader + end bool // saw end of message + buf [1024]byte // leftover input + nbuf int + out []byte // leftover decoded output + outbuf [1024 / 8 * 5]byte +} + +func (d *decoder) Read(p []byte) (n int, err error) { + if d.err != nil { + return 0, d.err + } + + // Use leftover decoded output from last read. + if len(d.out) > 0 { + n = copy(p, d.out) + d.out = d.out[n:] + return n, nil + } + + // Read a chunk. + nn := len(p) / 5 * 8 + if nn < 8 { + nn = 8 + } + if nn > len(d.buf) { + nn = len(d.buf) + } + nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf) + d.nbuf += nn + if d.nbuf < 8 { + return 0, d.err + } + + // Decode chunk into p, or d.out and then p if p is too small. + nr := d.nbuf / 8 * 8 + nw := d.nbuf / 8 * 5 + if nw > len(p) { + nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr]) + d.out = d.outbuf[0:nw] + n = copy(p, d.out) + d.out = d.out[n:] + } else { + n, d.end, d.err = d.enc.decode(p, d.buf[0:nr]) + } + d.nbuf -= nr + for i := 0; i < d.nbuf; i++ { + d.buf[i] = d.buf[i+nr] + } + + if d.err == nil { + d.err = err + } + return n, d.err +} + +type newlineFilteringReader struct { + wrapped io.Reader +} + +func (r *newlineFilteringReader) Read(p []byte) (int, error) { + n, err := r.wrapped.Read(p) + for n > 0 { + offset := 0 + for i, b := range p[0:n] { + if b != '\r' && b != '\n' { + if i != offset { + p[offset] = b + } + offset++ + } + } + if offset > 0 { + return offset, err + } + // Previous buffer entirely whitespace, read again + n, err = r.wrapped.Read(p) + } + return n, err +} + +// NewDecoder constructs a new base32 stream decoder. +func NewDecoder(enc *Encoding, r io.Reader) io.Reader { + return &decoder{enc: enc, r: &newlineFilteringReader{r}} +} + +// DecodedLen returns the maximum length in bytes of the decoded data +// corresponding to n bytes of base32-encoded data. +func (enc *Encoding) DecodedLen(n int) int { + if enc.padChar == NoPadding { + return (n*5 + 7) / 8 + } + + return n / 8 * 5 +} diff --git a/vendor/github.com/multiformats/go-base32/go.mod b/vendor/github.com/multiformats/go-base32/go.mod new file mode 100644 index 00000000..fcc446fe --- /dev/null +++ b/vendor/github.com/multiformats/go-base32/go.mod @@ -0,0 +1 @@ +module github.com/multiformats/go-base32 diff --git a/vendor/github.com/multiformats/go-base32/package.json b/vendor/github.com/multiformats/go-base32/package.json new file mode 100644 index 00000000..04a9970d --- /dev/null +++ b/vendor/github.com/multiformats/go-base32/package.json @@ -0,0 +1,15 @@ +{ + "author": "Golang", + "bugs": { + "url": "https://github.com/multiformats/go-base32" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-base32" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "BSD-3", + "name": "base32", + "version": "0.0.3" +} + diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/.gitignore b/vendor/github.com/multiformats/go-multiaddr-dns/.gitignore new file mode 100644 index 00000000..4621ab73 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/.gitignore @@ -0,0 +1 @@ +/madns/madns diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/.travis.yml b/vendor/github.com/multiformats/go-multiaddr-dns/.travis.yml new file mode 100644 index 00000000..18f4287d --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/LICENSE b/vendor/github.com/multiformats/go-multiaddr-dns/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/README.md b/vendor/github.com/multiformats/go-multiaddr-dns/README.md new file mode 100644 index 00000000..a1ac5447 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/README.md @@ -0,0 +1,57 @@ +# go-multiaddr-dns + +> Resolve /dns4, /dns6, and /dnsaddr multiaddrs. + +```sh +> madns /dnsaddr/ipfs.io/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +/ip6/2604:a880:1:20::1d9:6001/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +/ip6/fc3d:9a4e:3c96:2fd2:1afa:18fe:8dd2:b602/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +/dns4/jupiter.i.ipfs.io/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +/dns6/jupiter.i.ipfs.io/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx +``` + + +In more detail: + +```sh +> madns /dns6/example.net +/ip6/2001:db8::a3 +/ip6/2001:db8::a4 +... + +> madns /dns4/example.net/tcp/443/wss +/ip4/192.0.2.1/tcp/443/wss +/ip4/192.0.2.2/tcp/443/wss + +# No-op if it's not a dns-ish address. + +> madns /ip4/127.0.0.1/tcp/8080 +/ip4/127.0.0.1/tcp/8080 + +# /dnsaddr resolves by looking up TXT records. + +> dig +short TXT _dnsaddr.example.net +"dnsaddr=/ip6/2001:db8::a3/tcp/443/wss/ipfs/Qmfoo" +"dnsaddr=/ip6/2001:db8::a4/tcp/443/wss/ipfs/Qmbar" +"dnsaddr=/ip4/192.0.2.1/tcp/443/wss/ipfs/Qmfoo" +"dnsaddr=/ip4/192.0.2.2/tcp/443/wss/ipfs/Qmbar" +... + +# /dnsaddr returns addrs which encapsulate whatever /dnsaddr encapsulates too. + +> madns example.net/ipfs/Qmfoo +info: changing query to /dnsaddr/example.net/ipfs/Qmfoo +/ip6/2001:db8::a3/tcp/443/wss/ipfs/Qmfoo +/ip4/192.0.2.1/tcp/443/wss/ipfs/Qmfoo + +# TODO -p filters by protocol stacks. + +> madns -p /ip6/tcp/wss /dnsaddr/example.net +/ip6/2001:db8::a3/tcp/443/wss/ipfs/Qmfoo +/ip6/2001:db8::a4/tcp/443/wss/ipfs/Qmbar + +# TOOD -c filters by CIDR +> madns -c /ip4/104.236.76.0/ipcidr/24 /dnsaddr/example.net +/ip4/192.0.2.2/tcp/443/wss/ipfs/Qmbar +``` diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/dns.go b/vendor/github.com/multiformats/go-multiaddr-dns/dns.go new file mode 100644 index 00000000..53c82dfd --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/dns.go @@ -0,0 +1,69 @@ +package madns + +import ( + "bytes" + "fmt" + + ma "github.com/multiformats/go-multiaddr" +) + +// Extracted from source of truth for multicodec codes: https://github.com/multiformats/multicodec +const ( + P_DNS4 = 0x0036 + P_DNS6 = 0x0037 + P_DNSADDR = 0x0038 +) + +var Dns4Protocol = ma.Protocol{ + Code: P_DNS4, + Size: ma.LengthPrefixedVarSize, + Name: "dns4", + VCode: ma.CodeToVarint(P_DNS4), + Transcoder: DnsTranscoder, +} +var Dns6Protocol = ma.Protocol{ + Code: P_DNS6, + Size: ma.LengthPrefixedVarSize, + Name: "dns6", + VCode: ma.CodeToVarint(P_DNS6), + Transcoder: DnsTranscoder, +} +var DnsaddrProtocol = ma.Protocol{ + Code: P_DNSADDR, + Size: ma.LengthPrefixedVarSize, + Name: "dnsaddr", + VCode: ma.CodeToVarint(P_DNSADDR), + Transcoder: DnsTranscoder, +} + +func init() { + err := ma.AddProtocol(Dns4Protocol) + if err != nil { + panic(fmt.Errorf("error registering dns4 protocol: %s", err)) + } + err = ma.AddProtocol(Dns6Protocol) + if err != nil { + panic(fmt.Errorf("error registering dns6 protocol: %s", err)) + } + err = ma.AddProtocol(DnsaddrProtocol) + if err != nil { + panic(fmt.Errorf("error registering dnsaddr protocol: %s", err)) + } +} + +var DnsTranscoder = ma.NewTranscoderFromFunctions(dnsStB, dnsBtS, dnsVal) + +func dnsVal(b []byte) error { + if bytes.IndexByte(b, '/') >= 0 { + return fmt.Errorf("domain name %q contains a slash", string(b)) + } + return nil +} + +func dnsStB(s string) ([]byte, error) { + return []byte(s), nil +} + +func dnsBtS(b []byte) (string, error) { + return string(b), nil +} diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/go.mod b/vendor/github.com/multiformats/go-multiaddr-dns/go.mod new file mode 100644 index 00000000..fb228c60 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/go.mod @@ -0,0 +1,3 @@ +module github.com/multiformats/go-multiaddr-dns + +require github.com/multiformats/go-multiaddr v0.0.1 diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/go.sum b/vendor/github.com/multiformats/go-multiaddr-dns/go.sum new file mode 100644 index 00000000..cbf49eb4 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/go.sum @@ -0,0 +1,18 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/package.json b/vendor/github.com/multiformats/go-multiaddr-dns/package.json new file mode 100644 index 00000000..81fb932c --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/package.json @@ -0,0 +1,24 @@ +{ + "author": "lgierth", + "bugs": { + "url": "https://github.com/multiformats/go-multiaddr-dns/issues" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-multiaddr-dns" + }, + "gxDependencies": [ + { + "author": "multiformats", + "hash": "QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL", + "name": "go-multiaddr", + "version": "1.4.1" + } + ], + "gxVersion": "0.10.0", + "language": "go", + "license": "MIT", + "name": "go-multiaddr-dns", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.3.2" +} + diff --git a/vendor/github.com/multiformats/go-multiaddr-dns/resolve.go b/vendor/github.com/multiformats/go-multiaddr-dns/resolve.go new file mode 100644 index 00000000..9c81c2f5 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-dns/resolve.go @@ -0,0 +1,181 @@ +package madns + +import ( + "context" + "fmt" + "net" + "strings" + + ma "github.com/multiformats/go-multiaddr" +) + +var ResolvableProtocols = []ma.Protocol{DnsaddrProtocol, Dns4Protocol, Dns6Protocol} +var DefaultResolver = &Resolver{Backend: net.DefaultResolver} + +type backend interface { + LookupIPAddr(context.Context, string) ([]net.IPAddr, error) + LookupTXT(context.Context, string) ([]string, error) +} + +type Resolver struct { + Backend backend +} + +type MockBackend struct { + IP map[string][]net.IPAddr + TXT map[string][]string +} + +func (r *MockBackend) LookupIPAddr(ctx context.Context, name string) ([]net.IPAddr, error) { + results, ok := r.IP[name] + if ok { + return results, nil + } else { + return []net.IPAddr{}, nil + } +} + +func (r *MockBackend) LookupTXT(ctx context.Context, name string) ([]string, error) { + results, ok := r.TXT[name] + if ok { + return results, nil + } else { + return []string{}, nil + } +} + +func Matches(maddr ma.Multiaddr) bool { + protos := maddr.Protocols() + if len(protos) == 0 { + return false + } + + for _, p := range ResolvableProtocols { + if protos[0].Code == p.Code { + return true + } + } + + return false +} + +func Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + return DefaultResolver.Resolve(ctx, maddr) +} + +func (r *Resolver) Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + if !Matches(maddr) { + return []ma.Multiaddr{maddr}, nil + } + + protos := maddr.Protocols() + if protos[0].Code == Dns4Protocol.Code { + return r.resolveDns4(ctx, maddr) + } + if protos[0].Code == Dns6Protocol.Code { + return r.resolveDns6(ctx, maddr) + } + if protos[0].Code == DnsaddrProtocol.Code { + return r.resolveDnsaddr(ctx, maddr) + } + + panic("unreachable") +} + +func (r *Resolver) resolveDns4(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + value, err := maddr.ValueForProtocol(Dns4Protocol.Code) + if err != nil { + return nil, fmt.Errorf("error resolving %s: %s", maddr.String(), err) + } + + encap := ma.Split(maddr)[1:] + + result := []ma.Multiaddr{} + records, err := r.Backend.LookupIPAddr(ctx, value) + if err != nil { + return result, err + } + + for _, r := range records { + ip4 := r.IP.To4() + if ip4 == nil { + continue + } + ip4maddr, err := ma.NewMultiaddr("/ip4/" + ip4.String()) + if err != nil { + return result, err + } + parts := append([]ma.Multiaddr{ip4maddr}, encap...) + result = append(result, ma.Join(parts...)) + } + return result, nil +} + +func (r *Resolver) resolveDns6(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + value, err := maddr.ValueForProtocol(Dns6Protocol.Code) + if err != nil { + return nil, fmt.Errorf("error resolving %s: %s", maddr.String(), err) + } + + encap := ma.Split(maddr)[1:] + + result := []ma.Multiaddr{} + records, err := r.Backend.LookupIPAddr(ctx, value) + if err != nil { + return result, err + } + + for _, r := range records { + if r.IP.To4() != nil { + continue + } + ip6maddr, err := ma.NewMultiaddr("/ip6/" + r.IP.To16().String()) + if err != nil { + return result, err + } + parts := append([]ma.Multiaddr{ip6maddr}, encap...) + result = append(result, ma.Join(parts...)) + } + return result, nil +} + +func (r *Resolver) resolveDnsaddr(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + value, err := maddr.ValueForProtocol(DnsaddrProtocol.Code) + if err != nil { + return nil, fmt.Errorf("error resolving %s: %s", maddr.String(), err) + } + + trailer := ma.Split(maddr)[1:] + + result := []ma.Multiaddr{} + records, err := r.Backend.LookupTXT(ctx, "_dnsaddr."+value) + if err != nil { + return result, err + } + + for _, r := range records { + rv := strings.Split(r, "dnsaddr=") + if len(rv) != 2 { + continue + } + + rmaddr, err := ma.NewMultiaddr(rv[1]) + if err != nil { + return result, err + } + + if matchDnsaddr(rmaddr, trailer) { + result = append(result, rmaddr) + } + } + return result, nil +} + +// XXX probably insecure +func matchDnsaddr(maddr ma.Multiaddr, trailer []ma.Multiaddr) bool { + parts := ma.Split(maddr) + if ma.Join(parts[len(parts)-len(trailer):]...).Equal(ma.Join(trailer...)) { + return true + } + return false +} diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/.travis.yml b/vendor/github.com/multiformats/go-multiaddr-fmt/.travis.yml new file mode 100644 index 00000000..e4b63473 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/.travis.yml @@ -0,0 +1,33 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + - IPFS_REUSEPORT=false + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/LICENSE b/vendor/github.com/multiformats/go-multiaddr-fmt/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/README.md b/vendor/github.com/multiformats/go-multiaddr-fmt/README.md new file mode 100644 index 00000000..9fdc5389 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/README.md @@ -0,0 +1,34 @@ +# multiaddr format +A validation checker for multiaddrs. Some basic validators for common address +types are provided, but creating your own combinations is easy. + +Usage: +```go +a, _ := ma.NewMultiaddr("/ip4/5.2.67.3/tcp/1708") +TCP.Matches(a) // returns true +``` + +Making your own validators is easy, for example, the `Reliable` multiaddr is +defined as follows: + +```go +// Define IP as either ipv4 or ipv6 +var IP = Or(Base(ma.P_IP4), Base(ma.P_IP6)) + +// Define TCP as 'tcp' on top of either ipv4 or ipv6 +var TCP = And(IP, Base(ma.P_TCP)) + +// Define UDP as 'udp' on top of either ipv4 or ipv6 +var UDP = And(IP, Base(ma.P_UDP)) + +// Define UTP as 'utp' on top of udp (on top of ipv4 or ipv6) +var UTP = And(UDP, Base(ma.P_UTP)) + +// Now define a Reliable transport as either tcp or utp +var Reliable = Or(TCP, UTP) + +// From here, we can easily define multiaddrs for protocols that can run on top +// of any 'reliable' transport (such as ipfs) +``` + +NOTE: the above patterns are already implemented in package diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/go.mod b/vendor/github.com/multiformats/go-multiaddr-fmt/go.mod new file mode 100644 index 00000000..db40536c --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/go.mod @@ -0,0 +1,6 @@ +module github.com/multiformats/go-multiaddr-fmt + +require ( + github.com/multiformats/go-multiaddr v0.0.1 + github.com/multiformats/go-multiaddr-dns v0.0.2 +) diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/go.sum b/vendor/github.com/multiformats/go-multiaddr-fmt/go.sum new file mode 100644 index 00000000..e6220da6 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/go.sum @@ -0,0 +1,20 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/package.json b/vendor/github.com/multiformats/go-multiaddr-fmt/package.json new file mode 100644 index 00000000..8303f9c8 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/multiformats/go-multiaddr-fmt" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL", + "name": "go-multiaddr", + "version": "1.4.1" + }, + { + "author": "lgierth", + "hash": "QmR1T4gAM6XCHQugKnPZgZVPzo8WkuvSpL57EKQFgFbwfd", + "name": "go-multiaddr-dns", + "version": "0.3.2" + } + ], + "gxVersion": "0.6.0", + "gx_version": "0.4.0", + "issues_url": "https://github.com/multiformats/go-multiaddr-fmt", + "language": "go", + "license": "", + "name": "go-multiaddr-fmt", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.2.11" +} + diff --git a/vendor/github.com/multiformats/go-multiaddr-fmt/patterns.go b/vendor/github.com/multiformats/go-multiaddr-fmt/patterns.go new file mode 100644 index 00000000..62c45414 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-fmt/patterns.go @@ -0,0 +1,172 @@ +package mafmt + +import ( + "strings" + + ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" +) + +// Define a dns4 format multiaddr +var DNS4 = Base(madns.P_DNS4) + +// Define a dns6 format multiaddr +var DNS6 = Base(madns.P_DNS6) + +// Define a dnsaddr, dns4 or dns6 format multiaddr +var DNS = Or( + Base(madns.P_DNSADDR), + DNS4, + DNS6, +) + +// Define IP as either ipv4 or ipv6 +var IP = Or(Base(ma.P_IP4), Base(ma.P_IP6)) + +// Define TCP as 'tcp' on top of either ipv4 or ipv6, or dns equivalents. +var TCP = Or( + And(DNS, Base(ma.P_TCP)), + And(IP, Base(ma.P_TCP)), +) + +// Define UDP as 'udp' on top of either ipv4 or ipv6, or dns equivalents. +var UDP = Or( + And(DNS, Base(ma.P_UDP)), + And(IP, Base(ma.P_UDP)), +) + +// Define UTP as 'utp' on top of udp (on top of ipv4 or ipv6). +var UTP = And(UDP, Base(ma.P_UTP)) + +// Define QUIC as 'quic' on top of udp (on top of ipv4 or ipv6) +var QUIC = And(UDP, Base(ma.P_QUIC)) + +// Define unreliable transport as udp +var Unreliable = Or(UDP) + +// Now define a Reliable transport as either tcp or utp or quic +var Reliable = Or(TCP, UTP, QUIC) + +// IPFS can run over any reliable underlying transport protocol +var IPFS = And(Reliable, Base(ma.P_IPFS)) + +// Define http over TCP or DNS or http over DNS format multiaddr +var HTTP = Or( + And(TCP, Base(ma.P_HTTP)), + And(IP, Base(ma.P_HTTP)), + And(DNS, Base(ma.P_HTTP)), +) + +// Define https over TCP or DNS or https over DNS format multiaddr +var HTTPS = Or( + And(TCP, Base(ma.P_HTTPS)), + And(IP, Base(ma.P_HTTPS)), + And(DNS, Base(ma.P_HTTPS)), +) + +// Define p2p-webrtc-direct over HTTP or p2p-webrtc-direct over HTTPS format multiaddr +var WebRTCDirect = Or( + And(HTTP, Base(ma.P_P2P_WEBRTC_DIRECT)), + And(HTTPS, Base(ma.P_P2P_WEBRTC_DIRECT))) + +const ( + or = iota + and = iota +) + +func And(ps ...Pattern) Pattern { + return &pattern{ + Op: and, + Args: ps, + } +} + +func Or(ps ...Pattern) Pattern { + return &pattern{ + Op: or, + Args: ps, + } +} + +type Pattern interface { + Matches(ma.Multiaddr) bool + partialMatch([]ma.Protocol) (bool, []ma.Protocol) + String() string +} + +type pattern struct { + Args []Pattern + Op int +} + +func (ptrn *pattern) Matches(a ma.Multiaddr) bool { + ok, rem := ptrn.partialMatch(a.Protocols()) + return ok && len(rem) == 0 +} + +func (ptrn *pattern) partialMatch(pcs []ma.Protocol) (bool, []ma.Protocol) { + switch ptrn.Op { + case or: + for _, a := range ptrn.Args { + ok, rem := a.partialMatch(pcs) + if ok { + return true, rem + } + } + return false, nil + case and: + if len(pcs) < len(ptrn.Args) { + return false, nil + } + + for i := 0; i < len(ptrn.Args); i++ { + ok, rem := ptrn.Args[i].partialMatch(pcs) + if !ok { + return false, nil + } + + pcs = rem + } + + return true, pcs + default: + panic("unrecognized pattern operand") + } +} + +func (ptrn *pattern) String() string { + var sub []string + for _, a := range ptrn.Args { + sub = append(sub, a.String()) + } + + switch ptrn.Op { + case and: + return strings.Join(sub, "/") + case or: + return "{" + strings.Join(sub, "|") + "}" + default: + panic("unrecognized pattern op!") + } +} + +type Base int + +func (p Base) Matches(a ma.Multiaddr) bool { + pcs := a.Protocols() + return pcs[0].Code == int(p) && len(pcs) == 1 +} + +func (p Base) partialMatch(pcs []ma.Protocol) (bool, []ma.Protocol) { + if len(pcs) == 0 { + return false, nil + } + if pcs[0].Code == int(p) { + return true, pcs[1:] + } + return false, nil +} + +func (p Base) String() string { + return ma.ProtocolWithCode(int(p)).Name +} diff --git a/vendor/github.com/multiformats/go-multiaddr-net/.gitignore b/vendor/github.com/multiformats/go-multiaddr-net/.gitignore new file mode 100644 index 00000000..a186a0e4 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/.gitignore @@ -0,0 +1,2 @@ +bin/gx* +*.swp diff --git a/vendor/github.com/multiformats/go-multiaddr-net/.travis.yml b/vendor/github.com/multiformats/go-multiaddr-net/.travis.yml new file mode 100644 index 00000000..18f4287d --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multiaddr-net/LICENSE b/vendor/github.com/multiformats/go-multiaddr-net/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multiaddr-net/Makefile b/vendor/github.com/multiformats/go-multiaddr-net/Makefile new file mode 100644 index 00000000..54152565 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/Makefile @@ -0,0 +1,9 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite diff --git a/vendor/github.com/multiformats/go-multiaddr-net/README.md b/vendor/github.com/multiformats/go-multiaddr-net/README.md new file mode 100644 index 00000000..c13d248f --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/README.md @@ -0,0 +1,67 @@ +# go-multiaddr-net + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/multiformats/go-multiaddr-net?status.svg)](https://godoc.org/github.com/multiformats/go-multiaddr-net) +[![Travis CI](https://img.shields.io/travis/multiformats/go-multiaddr-net.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multiaddr-net) + + + +> Multiaddress net tools + +This package provides [Multiaddr](https://github.com/multiformats/go-multiaddr) specific versions of common functions in [stdlib](https://github.com/golang/go/tree/master/src)'s `net` package. This means wrappers of standard net symbols like `net.Dial` and `net.Listen`, as well +as conversion to and from `net.Addr`. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Maintainers](#maintainers) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-multiaddr-net` is a standard Go module which can be installed with: + +```sh +go get github.com/multiformats/go-multiaddr-net +``` + +Note that `go-multiaddr-net` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section). + + +## Usage + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project do: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/multiformats/go-multiaddr-net +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +For further usage, see the docs: + +- `multiaddr/net`: https://godoc.org/github.com/multiformats/go-multiaddr-net +- `multiaddr`: https://godoc.org/github.com/multiformats/go-multiaddr + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multiaddr-net/issues). + +Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2014 Juan Batiz-Benet diff --git a/vendor/github.com/multiformats/go-multiaddr-net/convert.go b/vendor/github.com/multiformats/go-multiaddr-net/convert.go new file mode 100644 index 00000000..061f1c48 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/convert.go @@ -0,0 +1,269 @@ +package manet + +import ( + "fmt" + "net" + "path/filepath" + + ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" +) + +var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion") + +// FromNetAddr converts a net.Addr type to a Multiaddr. +func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { + return defaultCodecs.FromNetAddr(a) +} + +// FromNetAddr converts a net.Addr to Multiaddress. +func (cm *CodecMap) FromNetAddr(a net.Addr) (ma.Multiaddr, error) { + if a == nil { + return nil, fmt.Errorf("nil multiaddr") + } + p, err := cm.getAddrParser(a.Network()) + if err != nil { + return nil, err + } + + return p(a) +} + +// ToNetAddr converts a Multiaddr to a net.Addr +// Must be ThinWaist. acceptable protocol stacks are: +// /ip{4,6}/{tcp, udp} +func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { + return defaultCodecs.ToNetAddr(maddr) +} + +// ToNetAddr converts a Multiaddress to a standard net.Addr. +func (cm *CodecMap) ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) { + protos := maddr.Protocols() + final := protos[len(protos)-1] + + p, err := cm.getMaddrParser(final.Name) + if err != nil { + return nil, err + } + + return p(maddr) +} + +func parseBasicNetMaddr(maddr ma.Multiaddr) (net.Addr, error) { + network, host, err := DialArgs(maddr) + if err != nil { + return nil, err + } + + switch network { + case "tcp", "tcp4", "tcp6": + return net.ResolveTCPAddr(network, host) + case "udp", "udp4", "udp6": + return net.ResolveUDPAddr(network, host) + case "ip", "ip4", "ip6": + return net.ResolveIPAddr(network, host) + case "unix": + return net.ResolveUnixAddr(network, host) + } + + return nil, fmt.Errorf("network not supported: %s", network) +} + +func FromIPAndZone(ip net.IP, zone string) (ma.Multiaddr, error) { + switch { + case ip.To4() != nil: + return ma.NewComponent("ip4", ip.String()) + case ip.To16() != nil: + ip6, err := ma.NewComponent("ip6", ip.String()) + if err != nil { + return nil, err + } + if zone == "" { + return ip6, nil + } else { + zone, err := ma.NewComponent("ip6zone", zone) + if err != nil { + return nil, err + } + return zone.Encapsulate(ip6), nil + } + default: + return nil, errIncorrectNetAddr + } +} + +// FromIP converts a net.IP type to a Multiaddr. +func FromIP(ip net.IP) (ma.Multiaddr, error) { + return FromIPAndZone(ip, "") +} + +// DialArgs is a convenience function that returns network and address as +// expected by net.Dial. See https://godoc.org/net#Dial for an overview of +// possible return values (we do not support the unixpacket ones yet). Unix +// addresses do not, at present, compose. +func DialArgs(m ma.Multiaddr) (string, string, error) { + var ( + zone, network, ip, port string + err error + hostname bool + ) + + ma.ForEach(m, func(c ma.Component) bool { + switch network { + case "": + switch c.Protocol().Code { + case ma.P_IP6ZONE: + if zone != "" { + err = fmt.Errorf("%s has multiple zones", m) + return false + } + zone = c.Value() + return true + case ma.P_IP6: + network = "ip6" + ip = c.Value() + return true + case ma.P_IP4: + if zone != "" { + err = fmt.Errorf("%s has ip4 with zone", m) + return false + } + network = "ip4" + ip = c.Value() + return true + case madns.Dns4Protocol.Code: + network = "ip4" + hostname = true + ip = c.Value() + return true + case madns.Dns6Protocol.Code: + network = "ip6" + hostname = true + ip = c.Value() + return true + case ma.P_UNIX: + network = "unix" + ip = c.Value() + return false + } + case "ip4": + switch c.Protocol().Code { + case ma.P_UDP: + network = "udp4" + case ma.P_TCP: + network = "tcp4" + default: + return false + } + port = c.Value() + case "ip6": + switch c.Protocol().Code { + case ma.P_UDP: + network = "udp6" + case ma.P_TCP: + network = "tcp6" + default: + return false + } + port = c.Value() + } + // Done. + return false + }) + if err != nil { + return "", "", err + } + + switch network { + case "ip6": + if zone != "" { + ip += "%" + zone + } + fallthrough + case "ip4": + return network, ip, nil + case "tcp4", "udp4": + return network, ip + ":" + port, nil + case "tcp6", "udp6": + if zone != "" { + ip += "%" + zone + } + if hostname { + return network, ip + ":" + port, nil + } + return network, "[" + ip + "]" + ":" + port, nil + case "unix": + return network, ip, nil + default: + return "", "", fmt.Errorf("%s is not a 'thin waist' address", m) + } +} + +func parseTCPNetAddr(a net.Addr) (ma.Multiaddr, error) { + ac, ok := a.(*net.TCPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get IP Addr + ipm, err := FromIPAndZone(ac.IP, ac.Zone) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Get TCP Addr + tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port)) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Encapsulate + return ipm.Encapsulate(tcpm), nil +} + +func parseUDPNetAddr(a net.Addr) (ma.Multiaddr, error) { + ac, ok := a.(*net.UDPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + + // Get IP Addr + ipm, err := FromIPAndZone(ac.IP, ac.Zone) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Get UDP Addr + udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port)) + if err != nil { + return nil, errIncorrectNetAddr + } + + // Encapsulate + return ipm.Encapsulate(udpm), nil +} + +func parseIPNetAddr(a net.Addr) (ma.Multiaddr, error) { + ac, ok := a.(*net.IPAddr) + if !ok { + return nil, errIncorrectNetAddr + } + return FromIPAndZone(ac.IP, ac.Zone) +} + +func parseIPPlusNetAddr(a net.Addr) (ma.Multiaddr, error) { + ac, ok := a.(*net.IPNet) + if !ok { + return nil, errIncorrectNetAddr + } + return FromIP(ac.IP) +} + +func parseUnixNetAddr(a net.Addr) (ma.Multiaddr, error) { + ac, ok := a.(*net.UnixAddr) + if !ok { + return nil, errIncorrectNetAddr + } + cleaned := filepath.Clean(ac.Name) + return ma.NewComponent("unix", cleaned) +} diff --git a/vendor/github.com/multiformats/go-multiaddr-net/doc.go b/vendor/github.com/multiformats/go-multiaddr-net/doc.go new file mode 100644 index 00000000..040ad3f0 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/doc.go @@ -0,0 +1,5 @@ +// Package manet provides Multiaddr specific versions of common +// functions in stdlib's net package. This means wrappers of +// standard net symbols like net.Dial and net.Listen, as well +// as conversion to/from net.Addr. +package manet diff --git a/vendor/github.com/multiformats/go-multiaddr-net/go.mod b/vendor/github.com/multiformats/go-multiaddr-net/go.mod new file mode 100644 index 00000000..57c28274 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/go.mod @@ -0,0 +1,6 @@ +module github.com/multiformats/go-multiaddr-net + +require ( + github.com/multiformats/go-multiaddr v0.0.1 + github.com/multiformats/go-multiaddr-dns v0.0.1 +) diff --git a/vendor/github.com/multiformats/go-multiaddr-net/go.sum b/vendor/github.com/multiformats/go-multiaddr-net/go.sum new file mode 100644 index 00000000..fc801cab --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/go.sum @@ -0,0 +1,20 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multiaddr v0.0.1 h1:/QUV3VBMDI6pi6xfiw7lr6xhDWWvQKn9udPn68kLSdY= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1 h1:jQt9c6tDSdQLIlBo4tXYx7QUHCPjxsB1zXcag/2S7zc= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/multiformats/go-multiaddr-net/ip.go b/vendor/github.com/multiformats/go-multiaddr-net/ip.go new file mode 100644 index 00000000..1cf9a775 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/ip.go @@ -0,0 +1,118 @@ +package manet + +import ( + "net" + + ma "github.com/multiformats/go-multiaddr" +) + +// Loopback Addresses +var ( + // IP4Loopback is the ip4 loopback multiaddr + IP4Loopback = ma.StringCast("/ip4/127.0.0.1") + + // IP6Loopback is the ip6 loopback multiaddr + IP6Loopback = ma.StringCast("/ip6/::1") + + // IP4MappedIP6Loopback is the IPv4 Mapped IPv6 loopback address. + IP4MappedIP6Loopback = ma.StringCast("/ip6/::ffff:127.0.0.1") +) + +// Unspecified Addresses (used for ) +var ( + IP4Unspecified = ma.StringCast("/ip4/0.0.0.0") + IP6Unspecified = ma.StringCast("/ip6/::") +) + +// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols. +// This means: /{IP4, IP6}[/{TCP, UDP}] +func IsThinWaist(m ma.Multiaddr) bool { + m = zoneless(m) + if m == nil { + return false + } + p := m.Protocols() + + // nothing? not even a waist. + if len(p) == 0 { + return false + } + + if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 { + return false + } + + // only IP? still counts. + if len(p) == 1 { + return true + } + + switch p[1].Code { + case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6: + return true + default: + return false + } +} + +// IsIPLoopback returns whether a Multiaddr starts with a "Loopback" IP address +// This means either /ip4/127.*.*.*/*, /ip6/::1/*, or /ip6/::ffff:127.*.*.*.*/*, +// or /ip6zone//ip6//* +func IsIPLoopback(m ma.Multiaddr) bool { + m = zoneless(m) + c, _ := ma.SplitFirst(m) + if c == nil { + return false + } + switch c.Protocol().Code { + case ma.P_IP4, ma.P_IP6: + return net.IP(c.RawValue()).IsLoopback() + } + return false +} + +// IsIP6LinkLocal returns whether a Multiaddr starts with an IPv6 link-local +// multiaddress (with zero or one leading zone). These addresses are non +// routable. +func IsIP6LinkLocal(m ma.Multiaddr) bool { + m = zoneless(m) + c, _ := ma.SplitFirst(m) + if c == nil || c.Protocol().Code != ma.P_IP6 { + return false + } + ip := net.IP(c.RawValue()) + return ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() +} + +// IsIPUnspecified returns whether a Multiaddr starts with an Unspecified IP address +// This means either /ip4/0.0.0.0/* or /ip6/::/* +func IsIPUnspecified(m ma.Multiaddr) bool { + m = zoneless(m) + if m == nil { + return false + } + c, _ := ma.SplitFirst(m) + return net.IP(c.RawValue()).IsUnspecified() +} + +// If m matches [zone,ip6,...], return [ip6,...] +// else if m matches [], [zone], or [zone,...], return nil +// else return m +func zoneless(m ma.Multiaddr) ma.Multiaddr { + head, tail := ma.SplitFirst(m) + if head == nil { + return nil + } + if head.Protocol().Code == ma.P_IP6ZONE { + if tail == nil { + return nil + } + tailhead, _ := ma.SplitFirst(tail) + if tailhead.Protocol().Code != ma.P_IP6 { + return nil + } + return tail + } else { + return m + } +} diff --git a/vendor/github.com/multiformats/go-multiaddr-net/net.go b/vendor/github.com/multiformats/go-multiaddr-net/net.go new file mode 100644 index 00000000..ac35530d --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/net.go @@ -0,0 +1,427 @@ +// Package manet provides Multiaddr +// (https://github.com/multiformats/go-multiaddr) specific versions of common +// functions in Go's standard `net` package. This means wrappers of standard +// net symbols like `net.Dial` and `net.Listen`, as well as conversion to +// and from `net.Addr`. +package manet + +import ( + "context" + "fmt" + "net" + + ma "github.com/multiformats/go-multiaddr" +) + +// Conn is the equivalent of a net.Conn object. It is the +// result of calling the Dial or Listen functions in this +// package, with associated local and remote Multiaddrs. +type Conn interface { + net.Conn + + // LocalMultiaddr returns the local Multiaddr associated + // with this connection + LocalMultiaddr() ma.Multiaddr + + // RemoteMultiaddr returns the remote Multiaddr associated + // with this connection + RemoteMultiaddr() ma.Multiaddr +} + +type halfOpen interface { + net.Conn + CloseRead() error + CloseWrite() error +} + +func wrap(nconn net.Conn, laddr, raddr ma.Multiaddr) Conn { + endpts := maEndpoints{ + laddr: laddr, + raddr: raddr, + } + // This sucks. However, it's the only way to reliably expose the + // underlying methods. This way, users that need access to, e.g., + // CloseRead and CloseWrite, can do so via type assertions. + switch nconn := nconn.(type) { + case *net.TCPConn: + return &struct { + *net.TCPConn + maEndpoints + }{nconn, endpts} + case *net.UDPConn: + return &struct { + *net.UDPConn + maEndpoints + }{nconn, endpts} + case *net.IPConn: + return &struct { + *net.IPConn + maEndpoints + }{nconn, endpts} + case *net.UnixConn: + return &struct { + *net.UnixConn + maEndpoints + }{nconn, endpts} + case halfOpen: + return &struct { + halfOpen + maEndpoints + }{nconn, endpts} + default: + return &struct { + net.Conn + maEndpoints + }{nconn, endpts} + } +} + +// WrapNetConn wraps a net.Conn object with a Multiaddr friendly Conn. +// +// This function does it's best to avoid "hiding" methods exposed by the wrapped +// type. Guarantees: +// +// * If the wrapped connection exposes the "half-open" closer methods +// (CloseWrite, CloseRead), these will be available on the wrapped connection +// via type assertions. +// * If the wrapped connection is a UnixConn, IPConn, TCPConn, or UDPConn, all +// methods on these wrapped connections will be available via type assertions. +func WrapNetConn(nconn net.Conn) (Conn, error) { + if nconn == nil { + return nil, fmt.Errorf("failed to convert nconn.LocalAddr: nil") + } + + laddr, err := FromNetAddr(nconn.LocalAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err) + } + + raddr, err := FromNetAddr(nconn.RemoteAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err) + } + + return wrap(nconn, laddr, raddr), nil +} + +type maEndpoints struct { + laddr ma.Multiaddr + raddr ma.Multiaddr +} + +// LocalMultiaddr returns the local address associated with +// this connection +func (c *maEndpoints) LocalMultiaddr() ma.Multiaddr { + return c.laddr +} + +// RemoteMultiaddr returns the remote address associated with +// this connection +func (c *maEndpoints) RemoteMultiaddr() ma.Multiaddr { + return c.raddr +} + +// Dialer contains options for connecting to an address. It +// is effectively the same as net.Dialer, but its LocalAddr +// and RemoteAddr options are Multiaddrs, instead of net.Addrs. +type Dialer struct { + + // Dialer is just an embedded net.Dialer, with all its options. + net.Dialer + + // LocalAddr is the local address to use when dialing an + // address. The address must be of a compatible type for the + // network being dialed. + // If nil, a local address is automatically chosen. + LocalAddr ma.Multiaddr +} + +// Dial connects to a remote address, using the options of the +// Dialer. Dialer uses an underlying net.Dialer to Dial a +// net.Conn, then wraps that in a Conn object (with local and +// remote Multiaddrs). +func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) { + return d.DialContext(context.Background(), remote) +} + +// DialContext allows to provide a custom context to Dial(). +func (d *Dialer) DialContext(ctx context.Context, remote ma.Multiaddr) (Conn, error) { + // if a LocalAddr is specified, use it on the embedded dialer. + if d.LocalAddr != nil { + // convert our multiaddr to net.Addr friendly + naddr, err := ToNetAddr(d.LocalAddr) + if err != nil { + return nil, err + } + + // set the dialer's LocalAddr as naddr + d.Dialer.LocalAddr = naddr + } + + // get the net.Dial friendly arguments from the remote addr + rnet, rnaddr, err := DialArgs(remote) + if err != nil { + return nil, err + } + + // ok, Dial! + var nconn net.Conn + switch rnet { + case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "unix": + nconn, err = d.Dialer.DialContext(ctx, rnet, rnaddr) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unrecognized network: %s", rnet) + } + + // get local address (pre-specified or assigned within net.Conn) + local := d.LocalAddr + // This block helps us avoid parsing addresses in transports (such as unix + // sockets) that don't have local addresses when dialing out. + if local == nil && nconn.LocalAddr().String() != "" { + local, err = FromNetAddr(nconn.LocalAddr()) + if err != nil { + return nil, err + } + } + return wrap(nconn, local, remote), nil +} + +// Dial connects to a remote address. It uses an underlying net.Conn, +// then wraps it in a Conn object (with local and remote Multiaddrs). +func Dial(remote ma.Multiaddr) (Conn, error) { + return (&Dialer{}).Dial(remote) +} + +// A Listener is a generic network listener for stream-oriented protocols. +// it uses an embedded net.Listener, overriding net.Listener.Accept to +// return a Conn and providing Multiaddr. +type Listener interface { + // Accept waits for and returns the next connection to the listener. + // Returns a Multiaddr friendly Conn + Accept() (Conn, error) + + // Close closes the listener. + // Any blocked Accept operations will be unblocked and return errors. + Close() error + + // Multiaddr returns the listener's (local) Multiaddr. + Multiaddr() ma.Multiaddr + + // Addr returns the net.Listener's network address. + Addr() net.Addr +} + +type netListenerAdapter struct { + Listener +} + +func (nla *netListenerAdapter) Accept() (net.Conn, error) { + return nla.Listener.Accept() +} + +// NetListener turns this Listener into a net.Listener. +// +// * Connections returned from Accept implement multiaddr-net Conn. +// * Calling WrapNetListener on the net.Listener returned by this function will +// return the original (underlying) multiaddr-net Listener. +func NetListener(l Listener) net.Listener { + return &netListenerAdapter{l} +} + +// maListener implements Listener +type maListener struct { + net.Listener + laddr ma.Multiaddr +} + +// Accept waits for and returns the next connection to the listener. +// Returns a Multiaddr friendly Conn +func (l *maListener) Accept() (Conn, error) { + nconn, err := l.Listener.Accept() + if err != nil { + return nil, err + } + + var raddr ma.Multiaddr + // This block protects us in transports (i.e. unix sockets) that don't have + // remote addresses for inbound connections. + if nconn.RemoteAddr().String() != "" { + raddr, err = FromNetAddr(nconn.RemoteAddr()) + if err != nil { + return nil, fmt.Errorf("failed to convert conn.RemoteAddr: %s", err) + } + } + + return wrap(nconn, l.laddr, raddr), nil +} + +// Multiaddr returns the listener's (local) Multiaddr. +func (l *maListener) Multiaddr() ma.Multiaddr { + return l.laddr +} + +// Addr returns the listener's network address. +func (l *maListener) Addr() net.Addr { + return l.Listener.Addr() +} + +// Listen announces on the local network address laddr. +// The Multiaddr must be a "ThinWaist" stream-oriented network: +// ip4/tcp, ip6/tcp, (TODO: unix, unixpacket) +// See Dial for the syntax of laddr. +func Listen(laddr ma.Multiaddr) (Listener, error) { + + // get the net.Listen friendly arguments from the remote addr + lnet, lnaddr, err := DialArgs(laddr) + if err != nil { + return nil, err + } + + nl, err := net.Listen(lnet, lnaddr) + if err != nil { + return nil, err + } + + // we want to fetch the new multiaddr from the listener, as it may + // have resolved to some other value. WrapNetListener does it for us. + return WrapNetListener(nl) +} + +// WrapNetListener wraps a net.Listener with a manet.Listener. +func WrapNetListener(nl net.Listener) (Listener, error) { + if nla, ok := nl.(*netListenerAdapter); ok { + return nla.Listener, nil + } + + laddr, err := FromNetAddr(nl.Addr()) + if err != nil { + return nil, err + } + + return &maListener{ + Listener: nl, + laddr: laddr, + }, nil +} + +// A PacketConn is a generic packet oriented network connection which uses an +// underlying net.PacketConn, wrapped with the locally bound Multiaddr. +type PacketConn interface { + Connection() net.PacketConn + + Multiaddr() ma.Multiaddr + + ReadFrom(b []byte) (int, ma.Multiaddr, error) + WriteTo(b []byte, maddr ma.Multiaddr) (int, error) + + Close() error +} + +// maPacketConn implements PacketConn +type maPacketConn struct { + net.PacketConn + laddr ma.Multiaddr +} + +// Connection returns the embedded net.PacketConn. +func (l *maPacketConn) Connection() net.PacketConn { + return l.PacketConn +} + +// Multiaddr returns the bound local Multiaddr. +func (l *maPacketConn) Multiaddr() ma.Multiaddr { + return l.laddr +} + +func (l *maPacketConn) ReadFrom(b []byte) (int, ma.Multiaddr, error) { + n, addr, err := l.PacketConn.ReadFrom(b) + maddr, _ := FromNetAddr(addr) + return n, maddr, err +} + +func (l *maPacketConn) WriteTo(b []byte, maddr ma.Multiaddr) (int, error) { + addr, err := ToNetAddr(maddr) + if err != nil { + return 0, err + } + return l.PacketConn.WriteTo(b, addr) +} + +// ListenPacket announces on the local network address laddr. +// The Multiaddr must be a packet driven network, like udp4 or udp6. +// See Dial for the syntax of laddr. +func ListenPacket(laddr ma.Multiaddr) (PacketConn, error) { + lnet, lnaddr, err := DialArgs(laddr) + if err != nil { + return nil, err + } + + pc, err := net.ListenPacket(lnet, lnaddr) + if err != nil { + return nil, err + } + + // We want to fetch the new multiaddr from the listener, as it may + // have resolved to some other value. WrapPacketConn does this. + return WrapPacketConn(pc) +} + +// WrapPacketConn wraps a net.PacketConn with a manet.PacketConn. +func WrapPacketConn(pc net.PacketConn) (PacketConn, error) { + laddr, err := FromNetAddr(pc.LocalAddr()) + if err != nil { + return nil, err + } + + return &maPacketConn{ + PacketConn: pc, + laddr: laddr, + }, nil +} + +// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs +func InterfaceMultiaddrs() ([]ma.Multiaddr, error) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return nil, err + } + + maddrs := make([]ma.Multiaddr, len(addrs)) + for i, a := range addrs { + maddrs[i], err = FromNetAddr(a) + if err != nil { + return nil, err + } + } + return maddrs, nil +} + +// AddrMatch returns the Multiaddrs that match the protocol stack on addr +func AddrMatch(match ma.Multiaddr, addrs []ma.Multiaddr) []ma.Multiaddr { + + // we should match transports entirely. + p1s := match.Protocols() + + out := make([]ma.Multiaddr, 0, len(addrs)) + for _, a := range addrs { + p2s := a.Protocols() + if len(p1s) != len(p2s) { + continue + } + + match := true + for i, p2 := range p2s { + if p1s[i].Code != p2.Code { + match = false + break + } + } + if match { + out = append(out, a) + } + } + return out +} diff --git a/vendor/github.com/multiformats/go-multiaddr-net/package.json b/vendor/github.com/multiformats/go-multiaddr-net/package.json new file mode 100644 index 00000000..cdad09ea --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/package.json @@ -0,0 +1,30 @@ +{ + "author": "multiformats", + "bugs": { + "url": "https://github.com/multiformats/go-multiaddr-net" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-multiaddr-net" + }, + "gxDependencies": [ + { + "author": "multiformats", + "hash": "QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL", + "name": "go-multiaddr", + "version": "1.4.1" + }, + { + "author": "lgierth", + "hash": "QmU98UaAEh4WJAcir2qjfztU77JQ14kAwHNFkjUXHZA3Vy", + "name": "go-multiaddr-dns", + "version": "0.3.1" + } + ], + "gxVersion": "0.6.0", + "language": "go", + "license": "", + "name": "go-multiaddr-net", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.7.2" +} + diff --git a/vendor/github.com/multiformats/go-multiaddr-net/private.go b/vendor/github.com/multiformats/go-multiaddr-net/private.go new file mode 100644 index 00000000..26e547ce --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/private.go @@ -0,0 +1,116 @@ +package manet + +import ( + "net" + + ma "github.com/multiformats/go-multiaddr" +) + +// Private4 and Private6 are well-known private networks +var Private4, Private6 []*net.IPNet +var privateCIDR4 = []string{ + // localhost + "127.0.0.0/8", + // private networks + "10.0.0.0/8", + "100.64.0.0/10", + "172.16.0.0/12", + "192.168.0.0/16", + // link local + "169.254.0.0/16", +} +var privateCIDR6 = []string{ + // localhost + "::1/128", + // ULA reserved + "fc00::/7", + // link local + "fe80::/10", +} + +// Unroutable4 and Unroutable6 are well known unroutable address ranges +var Unroutable4, Unroutable6 []*net.IPNet +var unroutableCIDR4 = []string{ + "0.0.0.0/8", + "192.0.0.0/26", + "192.0.2.0/24", + "192.88.99.0/24", + "198.18.0.0/15", + "198.51.100.0/24", + "203.0.113.0/24", + "224.0.0.0/4", + "240.0.0.0/4", + "255.255.255.255/32", +} +var unroutableCIDR6 = []string{ + "ff00::/8", +} + +func init() { + Private4 = parseCIDR(privateCIDR4) + Private6 = parseCIDR(privateCIDR6) + Unroutable4 = parseCIDR(unroutableCIDR4) + Unroutable6 = parseCIDR(unroutableCIDR6) +} + +func parseCIDR(cidrs []string) []*net.IPNet { + ipnets := make([]*net.IPNet, len(cidrs)) + for i, cidr := range cidrs { + _, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + panic(err) + } + ipnets[i] = ipnet + } + return ipnets +} + +// IsPublicAddr retruns true if the IP part of the multiaddr is a publicly routable address +func IsPublicAddr(a ma.Multiaddr) bool { + isPublic := false + ma.ForEach(a, func(c ma.Component) bool { + switch c.Protocol().Code { + case ma.P_IP6ZONE: + return true + default: + return false + case ma.P_IP4: + ip := net.IP(c.RawValue()) + isPublic = !inAddrRange(ip, Private4) && !inAddrRange(ip, Unroutable4) + case ma.P_IP6: + ip := net.IP(c.RawValue()) + isPublic = !inAddrRange(ip, Private6) && !inAddrRange(ip, Unroutable6) + } + return false + }) + return isPublic +} + +// IsPrivateAddr returns true if the IP part of the mutiaddr is in a private network +func IsPrivateAddr(a ma.Multiaddr) bool { + isPrivate := false + ma.ForEach(a, func(c ma.Component) bool { + switch c.Protocol().Code { + case ma.P_IP6ZONE: + return true + default: + return false + case ma.P_IP4: + isPrivate = inAddrRange(net.IP(c.RawValue()), Private4) + case ma.P_IP6: + isPrivate = inAddrRange(net.IP(c.RawValue()), Private6) + } + return false + }) + return isPrivate +} + +func inAddrRange(ip net.IP, ipnets []*net.IPNet) bool { + for _, ipnet := range ipnets { + if ipnet.Contains(ip) { + return true + } + } + + return false +} diff --git a/vendor/github.com/multiformats/go-multiaddr-net/registry.go b/vendor/github.com/multiformats/go-multiaddr-net/registry.go new file mode 100644 index 00000000..fc6561cb --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr-net/registry.go @@ -0,0 +1,133 @@ +package manet + +import ( + "fmt" + "net" + "sync" + + ma "github.com/multiformats/go-multiaddr" +) + +// FromNetAddrFunc is a generic function which converts a net.Addr to Multiaddress +type FromNetAddrFunc func(a net.Addr) (ma.Multiaddr, error) + +// ToNetAddrFunc is a generic function which converts a Multiaddress to net.Addr +type ToNetAddrFunc func(ma ma.Multiaddr) (net.Addr, error) + +var defaultCodecs = NewCodecMap() + +func init() { + defaultCodecs.RegisterFromNetAddr(parseTCPNetAddr, "tcp", "tcp4", "tcp6") + defaultCodecs.RegisterFromNetAddr(parseUDPNetAddr, "udp", "udp4", "udp6") + defaultCodecs.RegisterFromNetAddr(parseIPNetAddr, "ip", "ip4", "ip6") + defaultCodecs.RegisterFromNetAddr(parseIPPlusNetAddr, "ip+net") + defaultCodecs.RegisterFromNetAddr(parseUnixNetAddr, "unix") + + defaultCodecs.RegisterToNetAddr(parseBasicNetMaddr, "tcp", "udp", "ip6", "ip4", "unix") +} + +// CodecMap holds a map of NetCodecs indexed by their Protocol ID +// along with parsers for the addresses they use. +// It is used to keep a list of supported network address codecs (protocols +// which addresses can be converted to and from multiaddresses). +type CodecMap struct { + codecs map[string]*NetCodec + addrParsers map[string]FromNetAddrFunc + maddrParsers map[string]ToNetAddrFunc + lk sync.Mutex +} + +// NewCodecMap initializes and returns a CodecMap object. +func NewCodecMap() *CodecMap { + return &CodecMap{ + addrParsers: make(map[string]FromNetAddrFunc), + maddrParsers: make(map[string]ToNetAddrFunc), + } +} + +// NetCodec is used to identify a network codec, that is, a network type for +// which we are able to translate multiaddresses into standard Go net.Addr +// and back. +// +// Deprecated: Unfortunately, these mappings aren't one to one. This abstraction +// assumes that multiple "networks" can map to a single multiaddr protocol but +// not the reverse. For example, this abstraction supports `tcp6, tcp4, tcp -> +// /tcp/` really well but doesn't support `ip -> {/ip4/, /ip6/}`. +// +// Please use `RegisterFromNetAddr` and `RegisterToNetAddr` directly. +type NetCodec struct { + // NetAddrNetworks is an array of strings that may be returned + // by net.Addr.Network() calls on addresses belonging to this type + NetAddrNetworks []string + + // ProtocolName is the string value for Multiaddr address keys + ProtocolName string + + // ParseNetAddr parses a net.Addr belonging to this type into a multiaddr + ParseNetAddr FromNetAddrFunc + + // ConvertMultiaddr converts a multiaddr of this type back into a net.Addr + ConvertMultiaddr ToNetAddrFunc + + // Protocol returns the multiaddr protocol struct for this type + Protocol ma.Protocol +} + +// RegisterNetCodec adds a new NetCodec to the default codecs. +func RegisterNetCodec(a *NetCodec) { + defaultCodecs.RegisterNetCodec(a) +} + +// RegisterNetCodec adds a new NetCodec to the CodecMap. This function is +// thread safe. +func (cm *CodecMap) RegisterNetCodec(a *NetCodec) { + cm.lk.Lock() + defer cm.lk.Unlock() + for _, n := range a.NetAddrNetworks { + cm.addrParsers[n] = a.ParseNetAddr + } + + cm.maddrParsers[a.ProtocolName] = a.ConvertMultiaddr +} + +// RegisterFromNetAddr registers a conversion from net.Addr instances to multiaddrs +func (cm *CodecMap) RegisterFromNetAddr(from FromNetAddrFunc, networks ...string) { + cm.lk.Lock() + defer cm.lk.Unlock() + + for _, n := range networks { + cm.addrParsers[n] = from + } +} + +// RegisterToNetAddr registers a conversion from multiaddrs to net.Addr instances +func (cm *CodecMap) RegisterToNetAddr(to ToNetAddrFunc, protocols ...string) { + cm.lk.Lock() + defer cm.lk.Unlock() + + for _, p := range protocols { + cm.maddrParsers[p] = to + } +} + +func (cm *CodecMap) getAddrParser(net string) (FromNetAddrFunc, error) { + cm.lk.Lock() + defer cm.lk.Unlock() + + parser, ok := cm.addrParsers[net] + if !ok { + return nil, fmt.Errorf("unknown network %v", net) + } + return parser, nil +} + +func (cm *CodecMap) getMaddrParser(name string) (ToNetAddrFunc, error) { + cm.lk.Lock() + defer cm.lk.Unlock() + p, ok := cm.maddrParsers[name] + if !ok { + return nil, fmt.Errorf("network not supported: %s", name) + } + + return p, nil +} diff --git a/vendor/github.com/multiformats/go-multiaddr/.gitignore b/vendor/github.com/multiformats/go-multiaddr/.gitignore new file mode 100644 index 00000000..699d271b --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/.gitignore @@ -0,0 +1,3 @@ +.vscode/ +multiaddr/multiaddr +tmp/ diff --git a/vendor/github.com/multiformats/go-multiaddr/.travis.yml b/vendor/github.com/multiformats/go-multiaddr/.travis.yml new file mode 100644 index 00000000..95e4daaa --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/.travis.yml @@ -0,0 +1,31 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + - GO111MODULE=on + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + - make conformance + +cache: + directories: + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multiaddr/LICENSE b/vendor/github.com/multiformats/go-multiaddr/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multiaddr/Makefile b/vendor/github.com/multiformats/go-multiaddr/Makefile new file mode 100644 index 00000000..4de9c30e --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/Makefile @@ -0,0 +1,26 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +covertools: + go get golang.org/x/tools/cmd/cover + +deps: gx covertools + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + +conformance: tmp/multiaddr + go build -o tmp/multiaddr/test/go-multiaddr ./multiaddr + cd tmp/multiaddr/test && MULTIADDR_BIN="./go-multiaddr" go test -v + +tmp/multiaddr: + mkdir -p tmp/ + git clone https://github.com/multiformats/multiaddr tmp/multiaddr/ + +clean: + rm -rf tmp/ + +.PHONY: gx covertools deps publish conformance clean diff --git a/vendor/github.com/multiformats/go-multiaddr/README.md b/vendor/github.com/multiformats/go-multiaddr/README.md new file mode 100644 index 00000000..df2766aa --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/README.md @@ -0,0 +1,117 @@ +# go-multiaddr + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/multiformats/go-multiaddr?status.svg)](https://godoc.org/github.com/multiformats/go-multiaddr) +[![Travis CI](https://img.shields.io/travis/multiformats/go-multiaddr.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multiaddr) +[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multiaddr.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multiaddr?branch=master) + +> [multiaddr](https://github.com/multiformats/multiaddr) implementation in go + +Multiaddr is a standard way to represent addresses that: + +- Support any standard network protocols. +- Self-describe (include protocols). +- Have a binary packed format. +- Have a nice string representation. +- Encapsulate well. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) + - [Example](#example) + - [Simple](#simple) + - [Protocols](#protocols) + - [En/decapsulate](#endecapsulate) + - [Tunneling](#tunneling) +- [Maintainers](#maintainers) +- [Contribute](#contribute) +- [License](#license) + +## Install + +```sh +go get github.com/multiformats/go-multiaddr +``` + +## Usage + +### Example + +#### Simple + +```go +import ma "github.com/multiformats/go-multiaddr" + +// construct from a string (err signals parse failure) +m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + +// construct from bytes (err signals parse failure) +m2, err := ma.NewMultiaddrBytes(m1.Bytes()) + +// true +strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") +strings.Equal(m1.String(), m2.String()) +bytes.Equal(m1.Bytes(), m2.Bytes()) +m1.Equal(m2) +m2.Equal(m1) +``` + +#### Protocols + +```go +// get the multiaddr protocol description objects +m1.Protocols() +// []Protocol{ +// Protocol{ Code: 4, Name: 'ip4', Size: 32}, +// Protocol{ Code: 17, Name: 'udp', Size: 16}, +// } +``` + +#### En/decapsulate + +```go +import ma "github.com/multiformats/go-multiaddr" + +m, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") +// + +sctpMA, err := ma.NewMultiaddr("/sctp/5678") + +m.Encapsulate(sctpMA) +// + +udpMA, err := ma.NewMultiaddr("/udp/1234") + +m.Decapsulate(udpMA) // up to + inc last occurrence of subaddr +// +``` + +#### Tunneling + +Multiaddr allows expressing tunnels very nicely. + +```js +printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") +proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") +printerOverProxy := proxy.Encapsulate(printer) +// /ip4/10.20.30.40/tcp/443/ip4/192.168.0.13/tcp/80 + +proxyAgain := printerOverProxy.Decapsulate(printer) +// /ip4/10.20.30.40/tcp/443 +``` + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multiaddr/issues). + +Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2014 Juan Batiz-Benet diff --git a/vendor/github.com/multiformats/go-multiaddr/codec.go b/vendor/github.com/multiformats/go-multiaddr/codec.go new file mode 100644 index 00000000..35b50c14 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/codec.go @@ -0,0 +1,202 @@ +package multiaddr + +import ( + "bytes" + "fmt" + "strings" +) + +func stringToBytes(s string) ([]byte, error) { + // consume trailing slashes + s = strings.TrimRight(s, "/") + + var b bytes.Buffer + sp := strings.Split(s, "/") + + if sp[0] != "" { + return nil, fmt.Errorf("failed to parse multiaddr %q: must begin with /", s) + } + + // consume first empty elem + sp = sp[1:] + + if len(sp) == 0 { + return nil, fmt.Errorf("failed to parse multiaddr %q: empty multiaddr", s) + } + + for len(sp) > 0 { + name := sp[0] + p := ProtocolWithName(name) + if p.Code == 0 { + return nil, fmt.Errorf("failed to parse multiaddr %q: unknown protocol %s", s, sp[0]) + } + _, _ = b.Write(CodeToVarint(p.Code)) + sp = sp[1:] + + if p.Size == 0 { // no length. + continue + } + + if len(sp) < 1 { + return nil, fmt.Errorf("failed to parse multiaddr %q: unexpected end of multiaddr", s) + } + + if p.Path { + // it's a path protocol (terminal). + // consume the rest of the address as the next component. + sp = []string{"/" + strings.Join(sp, "/")} + } + + a, err := p.Transcoder.StringToBytes(sp[0]) + if err != nil { + return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", s, sp[0], p.Name, err) + } + if p.Size < 0 { // varint size. + _, _ = b.Write(CodeToVarint(len(a))) + } + b.Write(a) + sp = sp[1:] + } + + return b.Bytes(), nil +} + +func validateBytes(b []byte) (err error) { + if len(b) == 0 { + return fmt.Errorf("empty multiaddr") + } + for len(b) > 0 { + code, n, err := ReadVarintCode(b) + if err != nil { + return err + } + + b = b[n:] + p := ProtocolWithCode(code) + if p.Code == 0 { + return fmt.Errorf("no protocol with code %d", code) + } + + if p.Size == 0 { + continue + } + + n, size, err := sizeForAddr(p, b) + if err != nil { + return err + } + + b = b[n:] + + if len(b) < size || size < 0 { + return fmt.Errorf("invalid value for size %d", len(b)) + } + + err = p.Transcoder.ValidateBytes(b[:size]) + if err != nil { + return err + } + + b = b[size:] + } + + return nil +} + +func readComponent(b []byte) (int, Component, error) { + var offset int + code, n, err := ReadVarintCode(b) + if err != nil { + return 0, Component{}, err + } + offset += n + + p := ProtocolWithCode(code) + if p.Code == 0 { + return 0, Component{}, fmt.Errorf("no protocol with code %d", code) + } + + if p.Size == 0 { + return offset, Component{ + bytes: b[:offset], + offset: offset, + protocol: p, + }, nil + } + + n, size, err := sizeForAddr(p, b[offset:]) + if err != nil { + return 0, Component{}, err + } + + offset += n + + if len(b[offset:]) < size || size < 0 { + return 0, Component{}, fmt.Errorf("invalid value for size %d", len(b[offset:])) + } + + return offset + size, Component{ + bytes: b[:offset+size], + protocol: p, + offset: offset, + }, nil +} + +func bytesToString(b []byte) (ret string, err error) { + if len(b) == 0 { + return "", fmt.Errorf("empty multiaddr") + } + var buf strings.Builder + + for len(b) > 0 { + n, c, err := readComponent(b) + if err != nil { + return "", err + } + b = b[n:] + c.writeTo(&buf) + } + + return buf.String(), nil +} + +func sizeForAddr(p Protocol, b []byte) (skip, size int, err error) { + switch { + case p.Size > 0: + return 0, (p.Size / 8), nil + case p.Size == 0: + return 0, 0, nil + default: + size, n, err := ReadVarintCode(b) + if err != nil { + return 0, 0, err + } + return n, size, nil + } +} + +func bytesSplit(b []byte) ([][]byte, error) { + var ret [][]byte + for len(b) > 0 { + code, n, err := ReadVarintCode(b) + if err != nil { + return nil, err + } + + p := ProtocolWithCode(code) + if p.Code == 0 { + return nil, fmt.Errorf("no protocol with code %d", b[0]) + } + + n2, size, err := sizeForAddr(p, b[n:]) + if err != nil { + return nil, err + } + + length := n + n2 + size + ret = append(ret, b[:length]) + b = b[length:] + } + + return ret, nil +} diff --git a/vendor/github.com/multiformats/go-multiaddr/codecov.yml b/vendor/github.com/multiformats/go-multiaddr/codecov.yml new file mode 100644 index 00000000..ca8100ab --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/codecov.yml @@ -0,0 +1,2 @@ +ignore: + - "multiaddr" diff --git a/vendor/github.com/multiformats/go-multiaddr/component.go b/vendor/github.com/multiformats/go-multiaddr/component.go new file mode 100644 index 00000000..69baf7a1 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/component.go @@ -0,0 +1,181 @@ +package multiaddr + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "fmt" + "strings" +) + +// Component is a single multiaddr Component. +type Component struct { + bytes []byte + protocol Protocol + offset int +} + +func (c *Component) Bytes() []byte { + return c.bytes +} + +func (c *Component) MarshalBinary() ([]byte, error) { + return c.Bytes(), nil +} + +func (c *Component) UnmarshalBinary(data []byte) error { + _, comp, err := readComponent(data) + if err != nil { + return err + } + *c = comp + return nil +} + +func (c *Component) MarshalText() ([]byte, error) { + return []byte(c.String()), nil +} + +func (c *Component) UnmarshalText(data []byte) error { + bytes, err := stringToBytes(string(data)) + if err != nil { + return err + } + _, comp, err := readComponent(bytes) + if err != nil { + return err + } + *c = comp + return nil +} + +func (c *Component) MarshalJSON() ([]byte, error) { + txt, err := c.MarshalText() + if err != nil { + return nil, err + } + + return json.Marshal(string(txt)) +} + +func (m *Component) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + return m.UnmarshalText([]byte(v)) +} + +func (c *Component) Equal(o Multiaddr) bool { + return bytes.Equal(c.bytes, o.Bytes()) +} + +func (c *Component) Protocols() []Protocol { + return []Protocol{c.protocol} +} + +func (c *Component) Decapsulate(o Multiaddr) Multiaddr { + if c.Equal(o) { + return nil + } + return c +} + +func (c *Component) Encapsulate(o Multiaddr) Multiaddr { + m := &multiaddr{bytes: c.bytes} + return m.Encapsulate(o) +} + +func (c *Component) ValueForProtocol(code int) (string, error) { + if c.protocol.Code != code { + return "", ErrProtocolNotFound + } + return c.Value(), nil +} + +func (c *Component) Protocol() Protocol { + return c.protocol +} + +func (c *Component) RawValue() []byte { + return c.bytes[c.offset:] +} + +func (c *Component) Value() string { + if c.protocol.Transcoder == nil { + return "" + } + value, err := c.protocol.Transcoder.BytesToString(c.bytes[c.offset:]) + if err != nil { + // This Component must have been checked. + panic(err) + } + return value +} + +func (c *Component) String() string { + var b strings.Builder + c.writeTo(&b) + return b.String() +} + +// writeTo is an efficient, private function for string-formatting a multiaddr. +// Trust me, we tend to allocate a lot when doing this. +func (c *Component) writeTo(b *strings.Builder) { + b.WriteByte('/') + b.WriteString(c.protocol.Name) + value := c.Value() + if len(value) == 0 { + return + } + if !(c.protocol.Path && value[0] == '/') { + b.WriteByte('/') + } + b.WriteString(value) +} + +// NewComponent constructs a new multiaddr component +func NewComponent(protocol, value string) (*Component, error) { + p := ProtocolWithName(protocol) + if p.Code == 0 { + return nil, fmt.Errorf("unsupported protocol: %s", protocol) + } + if p.Transcoder != nil { + bts, err := p.Transcoder.StringToBytes(value) + if err != nil { + return nil, err + } + return newComponent(p, bts), nil + } else if value != "" { + return nil, fmt.Errorf("protocol %s doesn't take a value", p.Name) + } + return newComponent(p, nil), nil + // TODO: handle path /? +} + +func newComponent(protocol Protocol, bvalue []byte) *Component { + size := len(bvalue) + size += len(protocol.VCode) + if protocol.Size < 0 { + size += VarintSize(len(bvalue)) + } + maddr := make([]byte, size) + var offset int + offset += copy(maddr[offset:], protocol.VCode) + if protocol.Size < 0 { + offset += binary.PutUvarint(maddr[offset:], uint64(len(bvalue))) + } + copy(maddr[offset:], bvalue) + + // For debugging + if len(maddr) != offset+len(bvalue) { + panic("incorrect length") + } + + return &Component{ + bytes: maddr, + protocol: protocol, + offset: offset, + } +} diff --git a/vendor/github.com/multiformats/go-multiaddr/doc.go b/vendor/github.com/multiformats/go-multiaddr/doc.go new file mode 100644 index 00000000..d8c37b26 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/doc.go @@ -0,0 +1,36 @@ +/* +Package multiaddr provides an implementation of the Multiaddr network +address format. Multiaddr emphasizes explicitness, self-description, and +portability. It allows applications to treat addresses as opaque tokens, +and to avoid making assumptions about the address representation (e.g. length). +Learn more at https://github.com/multiformats/multiaddr + +Basic Use: + + import ( + "bytes" + "strings" + ma "github.com/multiformats/go-multiaddr" + ) + + // construct from a string (err signals parse failure) + m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + + // construct from bytes (err signals parse failure) + m2, err := ma.NewMultiaddrBytes(m1.Bytes()) + + // true + strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") + strings.Equal(m1.String(), m2.String()) + bytes.Equal(m1.Bytes(), m2.Bytes()) + m1.Equal(m2) + m2.Equal(m1) + + // tunneling (en/decap) + printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") + proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") + printerOverProxy := proxy.Encapsulate(printer) + proxyAgain := printerOverProxy.Decapsulate(printer) + +*/ +package multiaddr diff --git a/vendor/github.com/multiformats/go-multiaddr/go.mod b/vendor/github.com/multiformats/go-multiaddr/go.mod new file mode 100644 index 00000000..debcf3c5 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/go.mod @@ -0,0 +1,3 @@ +module github.com/multiformats/go-multiaddr + +require github.com/multiformats/go-multihash v0.0.1 diff --git a/vendor/github.com/multiformats/go-multiaddr/go.sum b/vendor/github.com/multiformats/go-multiaddr/go.sum new file mode 100644 index 00000000..faa395ab --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/go.sum @@ -0,0 +1,18 @@ +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v1.0.10 h1:KUnC6rT8Vyw0gx4qXUS6VN1QHKrgmvdDCaURVQ7+miM= +github.com/multiformats/go-multihash v1.0.10/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/multiformats/go-multiaddr/interface.go b/vendor/github.com/multiformats/go-multiaddr/interface.go new file mode 100644 index 00000000..82cc7640 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/interface.go @@ -0,0 +1,62 @@ +package multiaddr + +import ( + "encoding" + "encoding/json" +) + +/* +Multiaddr is a cross-protocol, cross-platform format for representing +internet addresses. It emphasizes explicitness and self-description. +Learn more here: https://github.com/multiformats/multiaddr + +Multiaddrs have both a binary and string representation. + + import ma "github.com/multiformats/go-multiaddr" + + addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80") + // err non-nil when parsing failed. + +*/ +type Multiaddr interface { + json.Marshaler + json.Unmarshaler + encoding.TextMarshaler + encoding.TextUnmarshaler + encoding.BinaryMarshaler + encoding.BinaryUnmarshaler + + // Equal returns whether two Multiaddrs are exactly equal + Equal(Multiaddr) bool + + // Bytes returns the []byte representation of this Multiaddr + // + // This function may expose immutable, internal state. Do not modify. + Bytes() []byte + + // String returns the string representation of this Multiaddr + // (may panic if internal state is corrupted) + String() string + + // Protocols returns the list of Protocols this Multiaddr includes + // will panic if protocol code incorrect (and bytes accessed incorrectly) + Protocols() []Protocol + + // Encapsulate wraps this Multiaddr around another. For example: + // + // /ip4/1.2.3.4 encapsulate /tcp/80 = /ip4/1.2.3.4/tcp/80 + // + Encapsulate(Multiaddr) Multiaddr + + // Decapsultate removes a Multiaddr wrapping. For example: + // + // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 + // + Decapsulate(Multiaddr) Multiaddr + + // ValueForProtocol returns the value (if any) following the specified protocol + // + // Note: protocols can appear multiple times in a single multiaddr. + // Consider using `ForEach` to walk over the addr manually. + ValueForProtocol(code int) (string, error) +} diff --git a/vendor/github.com/multiformats/go-multiaddr/multiaddr.go b/vendor/github.com/multiformats/go-multiaddr/multiaddr.go new file mode 100644 index 00000000..58fe8cec --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/multiaddr.go @@ -0,0 +1,186 @@ +package multiaddr + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "strings" +) + +// multiaddr is the data structure representing a Multiaddr +type multiaddr struct { + bytes []byte +} + +// NewMultiaddr parses and validates an input string, returning a *Multiaddr +func NewMultiaddr(s string) (a Multiaddr, err error) { + defer func() { + if e := recover(); e != nil { + log.Printf("Panic in NewMultiaddr on input %q: %s", s, e) + err = fmt.Errorf("%v", e) + } + }() + b, err := stringToBytes(s) + if err != nil { + return nil, err + } + return &multiaddr{bytes: b}, nil +} + +// NewMultiaddrBytes initializes a Multiaddr from a byte representation. +// It validates it as an input string. +func NewMultiaddrBytes(b []byte) (a Multiaddr, err error) { + defer func() { + if e := recover(); e != nil { + log.Printf("Panic in NewMultiaddrBytes on input %q: %s", b, e) + err = fmt.Errorf("%v", e) + } + }() + + if err := validateBytes(b); err != nil { + return nil, err + } + + return &multiaddr{bytes: b}, nil +} + +// Equal tests whether two multiaddrs are equal +func (m *multiaddr) Equal(m2 Multiaddr) bool { + return bytes.Equal(m.bytes, m2.Bytes()) +} + +// Bytes returns the []byte representation of this Multiaddr +// +// Do not modify the returned buffer, it may be shared. +func (m *multiaddr) Bytes() []byte { + return m.bytes +} + +// String returns the string representation of a Multiaddr +func (m *multiaddr) String() string { + s, err := bytesToString(m.bytes) + if err != nil { + panic(fmt.Errorf("multiaddr failed to convert back to string. corrupted? %s", err)) + } + return s +} + +func (m *multiaddr) MarshalBinary() ([]byte, error) { + return m.Bytes(), nil +} + +func (m *multiaddr) UnmarshalBinary(data []byte) error { + new, err := NewMultiaddrBytes(data) + if err != nil { + return err + } + *m = *(new.(*multiaddr)) + return nil +} + +func (m *multiaddr) MarshalText() ([]byte, error) { + return []byte(m.String()), nil +} + +func (m *multiaddr) UnmarshalText(data []byte) error { + new, err := NewMultiaddr(string(data)) + if err != nil { + return err + } + *m = *(new.(*multiaddr)) + return nil +} + +func (m *multiaddr) MarshalJSON() ([]byte, error) { + return json.Marshal(m.String()) +} + +func (m *multiaddr) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + new, err := NewMultiaddr(v) + *m = *(new.(*multiaddr)) + return err +} + +// Protocols returns the list of protocols this Multiaddr has. +// will panic in case we access bytes incorrectly. +func (m *multiaddr) Protocols() []Protocol { + ps := make([]Protocol, 0, 8) + b := m.bytes + for len(b) > 0 { + code, n, err := ReadVarintCode(b) + if err != nil { + panic(err) + } + + p := ProtocolWithCode(code) + if p.Code == 0 { + // this is a panic (and not returning err) because this should've been + // caught on constructing the Multiaddr + panic(fmt.Errorf("no protocol with code %d", b[0])) + } + ps = append(ps, p) + b = b[n:] + + n, size, err := sizeForAddr(p, b) + if err != nil { + panic(err) + } + + b = b[n+size:] + } + return ps +} + +// Encapsulate wraps a given Multiaddr, returning the resulting joined Multiaddr +func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr { + mb := m.bytes + ob := o.Bytes() + + b := make([]byte, len(mb)+len(ob)) + copy(b, mb) + copy(b[len(mb):], ob) + return &multiaddr{bytes: b} +} + +// Decapsulate unwraps Multiaddr up until the given Multiaddr is found. +func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { + s1 := m.String() + s2 := o.String() + i := strings.LastIndex(s1, s2) + if i < 0 { + // if multiaddr not contained, returns a copy. + cpy := make([]byte, len(m.bytes)) + copy(cpy, m.bytes) + return &multiaddr{bytes: cpy} + } + + if i == 0 { + return nil + } + + ma, err := NewMultiaddr(s1[:i]) + if err != nil { + panic("Multiaddr.Decapsulate incorrect byte boundaries.") + } + return ma +} + +var ErrProtocolNotFound = fmt.Errorf("protocol not found in multiaddr") + +func (m *multiaddr) ValueForProtocol(code int) (value string, err error) { + err = ErrProtocolNotFound + ForEach(m, func(c Component) bool { + if c.Protocol().Code == code { + value = c.Value() + err = nil + return false + } + return true + }) + return +} diff --git a/vendor/github.com/multiformats/go-multiaddr/package.json b/vendor/github.com/multiformats/go-multiaddr/package.json new file mode 100644 index 00000000..c493b27e --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/package.json @@ -0,0 +1,23 @@ +{ + "author": "multiformats", + "bugs": { + "url": "https://github.com/multiformats/go-multiaddr/issues" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-multiaddr" + }, + "gxDependencies": [ + { + "hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW", + "name": "go-multihash", + "version": "1.0.9" + } + ], + "gxVersion": "0.9.0", + "language": "go", + "license": "MIT", + "name": "go-multiaddr", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.4.1" +} + diff --git a/vendor/github.com/multiformats/go-multiaddr/protocol.go b/vendor/github.com/multiformats/go-multiaddr/protocol.go new file mode 100644 index 00000000..f9d70363 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/protocol.go @@ -0,0 +1,129 @@ +package multiaddr + +import ( + "fmt" + "strings" +) + +// These are special sizes +const ( + LengthPrefixedVarSize = -1 +) + +// Protocol is a Multiaddr protocol description structure. +type Protocol struct { + // Name is the string representation of the protocol code. E.g., ip4, + // ip6, tcp, udp, etc. + Name string + + // Code is the protocol's multicodec (a normal, non-varint number). + Code int + + // VCode is a precomputed varint encoded version of Code. + VCode []byte + + // Size is the size of the argument to this protocol. + // + // * Size == 0 means this protocol takes no argument. + // * Size > 0 means this protocol takes a constant sized argument. + // * Size < 0 means this protocol takes a variable length, varint + // prefixed argument. + Size int // a size of -1 indicates a length-prefixed variable size + + // Path indicates a path protocol (e.g., unix). When parsing multiaddr + // strings, path protocols consume the remainder of the address instead + // of stopping at the next forward slash. + // + // Size must be LengthPrefixedVarSize. + Path bool + + // Transcoder converts between the byte representation and the string + // representation of this protocol's argument (if any). + // + // This should only be non-nil if Size != 0 + Transcoder Transcoder +} + +var protocolsByName = map[string]Protocol{} +var protocolsByCode = map[int]Protocol{} + +// Protocols is the list of multiaddr protocols supported by this module. +var Protocols = []Protocol{} + +// SwapToP2pMultiaddrs is a function to make the transition from /ipfs/... +// multiaddrs to /p2p/... multiaddrs easier +// The first stage of the rollout is to ship this package to all users so +// that all users of multiaddr can parse both /ipfs/ and /p2p/ multiaddrs +// as the same code (P_P2P). During this stage of the rollout, all addresses +// with P_P2P will continue printing as /ipfs/, so that older clients without +// the new parsing code won't break. +// Once the network has adopted the new parsing code broadly enough, users of +// multiaddr can add a call to this method to an init function in their codebase. +// This will cause any P_P2P multiaddr to print out as /p2p/ instead of /ipfs/. +// Note that the binary serialization of this multiaddr does not change at any +// point. This means that this code is not a breaking network change at any point +func SwapToP2pMultiaddrs() { + for i := range Protocols { + if Protocols[i].Code == P_P2P { + Protocols[i].Name = "p2p" + break + } + } + + protoP2P.Name = "p2p" + + protocolsByName["ipfs"] = protoP2P + protocolsByName["p2p"] = protoP2P + protocolsByCode[protoP2P.Code] = protoP2P +} + +func AddProtocol(p Protocol) error { + if _, ok := protocolsByName[p.Name]; ok { + return fmt.Errorf("protocol by the name %q already exists", p.Name) + } + + if _, ok := protocolsByCode[p.Code]; ok { + return fmt.Errorf("protocol code %d already taken by %q", p.Code, p.Code) + } + + if p.Size != 0 && p.Transcoder == nil { + return fmt.Errorf("protocols with arguments must define transcoders") + } + if p.Path && p.Size >= 0 { + return fmt.Errorf("path protocols must have variable-length sizes") + } + + Protocols = append(Protocols, p) + protocolsByName[p.Name] = p + protocolsByCode[p.Code] = p + return nil +} + +// ProtocolWithName returns the Protocol description with given string name. +func ProtocolWithName(s string) Protocol { + return protocolsByName[s] +} + +// ProtocolWithCode returns the Protocol description with given protocol code. +func ProtocolWithCode(c int) Protocol { + return protocolsByCode[c] +} + +// ProtocolsWithString returns a slice of protocols matching given string. +func ProtocolsWithString(s string) ([]Protocol, error) { + s = strings.Trim(s, "/") + sp := strings.Split(s, "/") + if len(sp) == 0 { + return nil, nil + } + + t := make([]Protocol, len(sp)) + for i, name := range sp { + p := ProtocolWithName(name) + if p.Code == 0 { + return nil, fmt.Errorf("no protocol with name: %s", name) + } + t[i] = p + } + return t, nil +} diff --git a/vendor/github.com/multiformats/go-multiaddr/protocols.go b/vendor/github.com/multiformats/go-multiaddr/protocols.go new file mode 100644 index 00000000..cb38a70e --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/protocols.go @@ -0,0 +1,189 @@ +package multiaddr + +// You **MUST** register your multicodecs with +// https://github.com/multiformats/multicodec before adding them here. +const ( + P_IP4 = 0x0004 + P_TCP = 0x0006 + P_UDP = 0x0111 + P_DCCP = 0x0021 + P_IP6 = 0x0029 + P_IP6ZONE = 0x002A + P_QUIC = 0x01CC + P_SCTP = 0x0084 + P_UDT = 0x012D + P_UTP = 0x012E + P_UNIX = 0x0190 + P_P2P = 0x01A5 + P_IPFS = 0x01A5 // alias for backwards compatability + P_HTTP = 0x01E0 + P_HTTPS = 0x01BB + P_ONION = 0x01BC // also for backwards compatibility + P_ONION3 = 0x01BD + P_GARLIC64 = 0x01BE + P_GARLIC32 = 0x01BF + P_P2P_WEBRTC_DIRECT = 0x0114 +) + +var ( + protoIP4 = Protocol{ + Name: "ip4", + Code: P_IP4, + VCode: CodeToVarint(P_IP4), + Size: 32, + Path: false, + Transcoder: TranscoderIP4, + } + protoTCP = Protocol{ + Name: "tcp", + Code: P_TCP, + VCode: CodeToVarint(P_TCP), + Size: 16, + Path: false, + Transcoder: TranscoderPort, + } + protoUDP = Protocol{ + Name: "udp", + Code: P_UDP, + VCode: CodeToVarint(P_UDP), + Size: 16, + Path: false, + Transcoder: TranscoderPort, + } + protoDCCP = Protocol{ + Name: "dccp", + Code: P_DCCP, + VCode: CodeToVarint(P_DCCP), + Size: 16, + Path: false, + Transcoder: TranscoderPort, + } + protoIP6 = Protocol{ + Name: "ip6", + Code: P_IP6, + VCode: CodeToVarint(P_IP6), + Size: 128, + Transcoder: TranscoderIP6, + } + // these require varint + protoIP6ZONE = Protocol{ + Name: "ip6zone", + Code: P_IP6ZONE, + VCode: CodeToVarint(P_IP6ZONE), + Size: LengthPrefixedVarSize, + Path: false, + Transcoder: TranscoderIP6Zone, + } + protoSCTP = Protocol{ + Name: "sctp", + Code: P_SCTP, + VCode: CodeToVarint(P_SCTP), + Size: 16, + Transcoder: TranscoderPort, + } + protoONION2 = Protocol{ + Name: "onion", + Code: P_ONION, + VCode: CodeToVarint(P_ONION), + Size: 96, + Transcoder: TranscoderOnion, + } + protoONION3 = Protocol{ + Name: "onion3", + Code: P_ONION3, + VCode: CodeToVarint(P_ONION3), + Size: 296, + Transcoder: TranscoderOnion3, + } + protoGARLIC64 = Protocol{ + Name: "garlic64", + Code: P_GARLIC64, + VCode: CodeToVarint(P_GARLIC64), + Size: LengthPrefixedVarSize, + Transcoder: TranscoderGarlic64, + } + protoGARLIC32 = Protocol{ + Name: "garlic32", + Code: P_GARLIC32, + VCode: CodeToVarint(P_GARLIC32), + Size: LengthPrefixedVarSize, + Transcoder: TranscoderGarlic32, + } + protoUTP = Protocol{ + Name: "utp", + Code: P_UTP, + VCode: CodeToVarint(P_UTP), + } + protoUDT = Protocol{ + Name: "udt", + Code: P_UDT, + VCode: CodeToVarint(P_UDT), + } + protoQUIC = Protocol{ + Name: "quic", + Code: P_QUIC, + VCode: CodeToVarint(P_QUIC), + } + protoHTTP = Protocol{ + Name: "http", + Code: P_HTTP, + VCode: CodeToVarint(P_HTTP), + } + protoHTTPS = Protocol{ + Name: "https", + Code: P_HTTPS, + VCode: CodeToVarint(P_HTTPS), + } + protoP2P = Protocol{ + Name: "ipfs", + Code: P_P2P, + VCode: CodeToVarint(P_P2P), + Size: LengthPrefixedVarSize, + Transcoder: TranscoderP2P, + } + protoUNIX = Protocol{ + Name: "unix", + Code: P_UNIX, + VCode: CodeToVarint(P_UNIX), + Size: LengthPrefixedVarSize, + Path: true, + Transcoder: TranscoderUnix, + } + protoP2P_WEBRTC_DIRECT = Protocol{ + Name: "p2p-webrtc-direct", + Code: P_P2P_WEBRTC_DIRECT, + VCode: CodeToVarint(P_P2P_WEBRTC_DIRECT), + } +) + +func init() { + for _, p := range []Protocol{ + protoIP4, + protoTCP, + protoUDP, + protoDCCP, + protoIP6, + protoIP6ZONE, + protoSCTP, + protoONION2, + protoONION3, + protoGARLIC64, + protoGARLIC32, + protoUTP, + protoUDT, + protoQUIC, + protoHTTP, + protoHTTPS, + protoP2P, + protoUNIX, + protoP2P_WEBRTC_DIRECT, + } { + if err := AddProtocol(p); err != nil { + panic(err) + } + } + + // explicitly set both of these + protocolsByName["p2p"] = protoP2P + protocolsByName["ipfs"] = protoP2P +} diff --git a/vendor/github.com/multiformats/go-multiaddr/transcoders.go b/vendor/github.com/multiformats/go-multiaddr/transcoders.go new file mode 100644 index 00000000..77908b70 --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/transcoders.go @@ -0,0 +1,319 @@ +package multiaddr + +import ( + "bytes" + "encoding/base32" + "encoding/base64" + "encoding/binary" + "fmt" + "net" + "strconv" + "strings" + + mh "github.com/multiformats/go-multihash" +) + +type Transcoder interface { + StringToBytes(string) ([]byte, error) + BytesToString([]byte) (string, error) + ValidateBytes([]byte) error +} + +func NewTranscoderFromFunctions( + s2b func(string) ([]byte, error), + b2s func([]byte) (string, error), + val func([]byte) error, +) Transcoder { + return twrp{s2b, b2s, val} +} + +type twrp struct { + strtobyte func(string) ([]byte, error) + bytetostr func([]byte) (string, error) + validbyte func([]byte) error +} + +func (t twrp) StringToBytes(s string) ([]byte, error) { + return t.strtobyte(s) +} +func (t twrp) BytesToString(b []byte) (string, error) { + return t.bytetostr(b) +} + +func (t twrp) ValidateBytes(b []byte) error { + if t.validbyte == nil { + return nil + } + return t.validbyte(b) +} + +var TranscoderIP4 = NewTranscoderFromFunctions(ip4StB, ip4BtS, nil) +var TranscoderIP6 = NewTranscoderFromFunctions(ip6StB, ip6BtS, nil) +var TranscoderIP6Zone = NewTranscoderFromFunctions(ip6zoneStB, ip6zoneBtS, ip6zoneVal) + +func ip4StB(s string) ([]byte, error) { + i := net.ParseIP(s).To4() + if i == nil { + return nil, fmt.Errorf("failed to parse ip4 addr: %s", s) + } + return i, nil +} + +func ip6zoneStB(s string) ([]byte, error) { + if len(s) == 0 { + return nil, fmt.Errorf("empty ip6zone") + } + return []byte(s), nil +} + +func ip6zoneBtS(b []byte) (string, error) { + if len(b) == 0 { + return "", fmt.Errorf("invalid length (should be > 0)") + } + return string(b), nil +} + +func ip6zoneVal(b []byte) error { + if len(b) == 0 { + return fmt.Errorf("invalid length (should be > 0)") + } + // Not supported as this would break multiaddrs. + if bytes.IndexByte(b, '/') >= 0 { + return fmt.Errorf("IPv6 zone ID contains '/': %s", string(b)) + } + return nil +} + +func ip6StB(s string) ([]byte, error) { + i := net.ParseIP(s).To16() + if i == nil { + return nil, fmt.Errorf("failed to parse ip6 addr: %s", s) + } + return i, nil +} + +func ip6BtS(b []byte) (string, error) { + ip := net.IP(b) + if ip4 := ip.To4(); ip4 != nil { + // Go fails to prepend the `::ffff:` part. + return "::ffff:" + ip4.String(), nil + } + return ip.String(), nil +} + +func ip4BtS(b []byte) (string, error) { + return net.IP(b).String(), nil +} + +var TranscoderPort = NewTranscoderFromFunctions(portStB, portBtS, nil) + +func portStB(s string) ([]byte, error) { + i, err := strconv.Atoi(s) + if err != nil { + return nil, fmt.Errorf("failed to parse port addr: %s", err) + } + if i >= 65536 { + return nil, fmt.Errorf("failed to parse port addr: %s", "greater than 65536") + } + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, uint16(i)) + return b, nil +} + +func portBtS(b []byte) (string, error) { + i := binary.BigEndian.Uint16(b) + return strconv.Itoa(int(i)), nil +} + +var TranscoderOnion = NewTranscoderFromFunctions(onionStB, onionBtS, nil) + +func onionStB(s string) ([]byte, error) { + addr := strings.Split(s, ":") + if len(addr) != 2 { + return nil, fmt.Errorf("failed to parse onion addr: %s does not contain a port number.", s) + } + + // onion address without the ".onion" substring + if len(addr[0]) != 16 { + return nil, fmt.Errorf("failed to parse onion addr: %s not a Tor onion address.", s) + } + onionHostBytes, err := base32.StdEncoding.DecodeString(strings.ToUpper(addr[0])) + if err != nil { + return nil, fmt.Errorf("failed to decode base32 onion addr: %s %s", s, err) + } + + // onion port number + i, err := strconv.Atoi(addr[1]) + if err != nil { + return nil, fmt.Errorf("failed to parse onion addr: %s", err) + } + if i >= 65536 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536") + } + if i < 1 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1") + } + + onionPortBytes := make([]byte, 2) + binary.BigEndian.PutUint16(onionPortBytes, uint16(i)) + bytes := []byte{} + bytes = append(bytes, onionHostBytes...) + bytes = append(bytes, onionPortBytes...) + return bytes, nil +} + +func onionBtS(b []byte) (string, error) { + addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:10])) + port := binary.BigEndian.Uint16(b[10:12]) + return addr + ":" + strconv.Itoa(int(port)), nil +} + +var TranscoderOnion3 = NewTranscoderFromFunctions(onion3StB, onion3BtS, nil) + +func onion3StB(s string) ([]byte, error) { + addr := strings.Split(s, ":") + if len(addr) != 2 { + return nil, fmt.Errorf("failed to parse onion addr: %s does not contain a port number.", s) + } + + // onion address without the ".onion" substring + if len(addr[0]) != 56 { + return nil, fmt.Errorf("failed to parse onion addr: %s not a Tor onionv3 address. len == %d", s, len(addr[0])) + } + onionHostBytes, err := base32.StdEncoding.DecodeString(strings.ToUpper(addr[0])) + if err != nil { + return nil, fmt.Errorf("failed to decode base32 onion addr: %s %s", s, err) + } + + // onion port number + i, err := strconv.Atoi(addr[1]) + if err != nil { + return nil, fmt.Errorf("failed to parse onion addr: %s", err) + } + if i >= 65536 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536") + } + if i < 1 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1") + } + + onionPortBytes := make([]byte, 2) + binary.BigEndian.PutUint16(onionPortBytes, uint16(i)) + bytes := []byte{} + bytes = append(bytes, onionHostBytes[0:35]...) + bytes = append(bytes, onionPortBytes...) + return bytes, nil +} + +func onion3BtS(b []byte) (string, error) { + addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:35])) + port := binary.BigEndian.Uint16(b[35:37]) + str := addr + ":" + strconv.Itoa(int(port)) + return str, nil +} + +var TranscoderGarlic64 = NewTranscoderFromFunctions(garlic64StB, garlic64BtS, garlic64Validate) + +// i2p uses an alternate character set for base64 addresses. This returns an appropriate encoder. +var garlicBase64Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~") + +func garlic64StB(s string) ([]byte, error) { + // i2p base64 address will be between 516 and 616 characters long, depending on + // certificate type + if len(s) < 516 || len(s) > 616 { + return nil, fmt.Errorf("failed to parse garlic addr: %s not an i2p base64 address. len: %d\n", s, len(s)) + } + garlicHostBytes, err := garlicBase64Encoding.DecodeString(s) + if err != nil { + return nil, fmt.Errorf("failed to decode base64 i2p addr: %s %s", s, err) + } + + return garlicHostBytes, nil +} + +func garlic64BtS(b []byte) (string, error) { + if err := garlic64Validate(b); err != nil { + return "", err + } + addr := garlicBase64Encoding.EncodeToString(b) + return addr, nil +} + +func garlic64Validate(b []byte) error { + // A garlic64 address will always be greater than 386 bytes long when encoded. + if len(b) < 386 { + return fmt.Errorf("failed to validate garlic addr: %s not an i2p base64 address. len: %d\n", b, len(b)) + } + return nil +} + +var TranscoderGarlic32 = NewTranscoderFromFunctions(garlic32StB, garlic32BtS, garlic32Validate) + +var garlicBase32Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567") + +func garlic32StB(s string) ([]byte, error) { + // an i2p base32 address with a length of greater than 55 characters is + // using an Encrypted Leaseset v2. all other base32 addresses will always be + // exactly 52 characters + if len(s) < 55 && len(s) != 52 { + return nil, fmt.Errorf("failed to parse garlic addr: %s not a i2p base32 address. len: %d", s, len(s)) + } + for len(s)%8 != 0 { + s += "=" + } + garlicHostBytes, err := garlicBase32Encoding.DecodeString(s) + if err != nil { + return nil, fmt.Errorf("failed to decode base32 garlic addr: %s, err: %v len: %v", s, err, len(s)) + } + return garlicHostBytes, nil +} + +func garlic32BtS(b []byte) (string, error) { + if err := garlic32Validate(b); err != nil { + return "", err + } + return strings.TrimRight(garlicBase32Encoding.EncodeToString(b), "="), nil +} + +func garlic32Validate(b []byte) error { + // an i2p base64 for an Encrypted Leaseset v2 will be at least 35 bytes + // long other than that, they will be exactly 32 bytes + if len(b) < 35 && len(b) != 32 { + return fmt.Errorf("failed to validate garlic addr: %s not an i2p base32 address. len: %d\n", b, len(b)) + } + return nil +} + +var TranscoderP2P = NewTranscoderFromFunctions(p2pStB, p2pBtS, p2pVal) + +func p2pStB(s string) ([]byte, error) { + // the address is a varint prefixed multihash string representation + m, err := mh.FromB58String(s) + if err != nil { + return nil, fmt.Errorf("failed to parse p2p addr: %s %s", s, err) + } + return m, nil +} + +func p2pVal(b []byte) error { + _, err := mh.Cast(b) + return err +} + +func p2pBtS(b []byte) (string, error) { + m, err := mh.Cast(b) + if err != nil { + return "", err + } + return m.B58String(), nil +} + +var TranscoderUnix = NewTranscoderFromFunctions(unixStB, unixBtS, nil) + +func unixStB(s string) ([]byte, error) { + return []byte(s), nil +} + +func unixBtS(b []byte) (string, error) { + return string(b), nil +} diff --git a/vendor/github.com/multiformats/go-multiaddr/util.go b/vendor/github.com/multiformats/go-multiaddr/util.go new file mode 100644 index 00000000..cf4469af --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/util.go @@ -0,0 +1,180 @@ +package multiaddr + +import "fmt" + +// Split returns the sub-address portions of a multiaddr. +func Split(m Multiaddr) []Multiaddr { + if _, ok := m.(*Component); ok { + return []Multiaddr{m} + } + var addrs []Multiaddr + ForEach(m, func(c Component) bool { + addrs = append(addrs, &c) + return true + }) + return addrs +} + +// Join returns a combination of addresses. +func Join(ms ...Multiaddr) Multiaddr { + switch len(ms) { + case 0: + // empty multiaddr, unfortunately, we have callers that rely on + // this contract. + return &multiaddr{} + case 1: + return ms[0] + } + + length := 0 + bs := make([][]byte, len(ms)) + for i, m := range ms { + bs[i] = m.Bytes() + length += len(bs[i]) + } + + bidx := 0 + b := make([]byte, length) + for _, mb := range bs { + bidx += copy(b[bidx:], mb) + } + return &multiaddr{bytes: b} +} + +// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse. +func Cast(b []byte) Multiaddr { + m, err := NewMultiaddrBytes(b) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return m +} + +// StringCast like Cast, but parses a string. Will also panic if it fails to parse. +func StringCast(s string) Multiaddr { + m, err := NewMultiaddr(s) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return m +} + +// SplitFirst returns the first component and the rest of the multiaddr. +func SplitFirst(m Multiaddr) (*Component, Multiaddr) { + // Shortcut if we already have a component + if c, ok := m.(*Component); ok { + return c, nil + } + + b := m.Bytes() + if len(b) == 0 { + return nil, nil + } + n, c, err := readComponent(b) + if err != nil { + panic(err) + } + if len(b) == n { + return &c, nil + } + return &c, &multiaddr{b[n:]} +} + +// SplitLast returns the rest of the multiaddr and the last component. +func SplitLast(m Multiaddr) (Multiaddr, *Component) { + // Shortcut if we already have a component + if c, ok := m.(*Component); ok { + return nil, c + } + + b := m.Bytes() + if len(b) == 0 { + return nil, nil + } + + var ( + c Component + err error + offset int + ) + for { + var n int + n, c, err = readComponent(b[offset:]) + if err != nil { + panic(err) + } + if len(b) == n+offset { + // Reached end + if offset == 0 { + // Only one component + return nil, &c + } + return &multiaddr{b[:offset]}, &c + } + offset += n + } +} + +// SplitFunc splits the multiaddr when the callback first returns true. The +// component on which the callback first returns will be included in the +// *second* multiaddr. +func SplitFunc(m Multiaddr, cb func(Component) bool) (Multiaddr, Multiaddr) { + // Shortcut if we already have a component + if c, ok := m.(*Component); ok { + if cb(*c) { + return nil, m + } + return m, nil + } + b := m.Bytes() + if len(b) == 0 { + return nil, nil + } + var ( + c Component + err error + offset int + ) + for offset < len(b) { + var n int + n, c, err = readComponent(b[offset:]) + if err != nil { + panic(err) + } + if cb(c) { + break + } + offset += n + } + switch offset { + case 0: + return nil, m + case len(b): + return m, nil + default: + return &multiaddr{b[:offset]}, &multiaddr{b[offset:]} + } +} + +// ForEach walks over the multiaddr, component by component. +// +// This function iterates over components *by value* to avoid allocating. +func ForEach(m Multiaddr, cb func(c Component) bool) { + // Shortcut if we already have a component + if c, ok := m.(*Component); ok { + cb(*c) + return + } + + b := m.Bytes() + for len(b) > 0 { + n, c, err := readComponent(b) + if err != nil { + panic(err) + } + if !cb(c) { + return + } + b = b[n:] + } +} diff --git a/vendor/github.com/multiformats/go-multiaddr/varint.go b/vendor/github.com/multiformats/go-multiaddr/varint.go new file mode 100644 index 00000000..b8b1507b --- /dev/null +++ b/vendor/github.com/multiformats/go-multiaddr/varint.go @@ -0,0 +1,44 @@ +package multiaddr + +import ( + "encoding/binary" + "fmt" + "math/bits" +) + +// VarintSize returns the size (in bytes) of `num` encoded as a varint. +func VarintSize(num int) int { + bits := bits.Len(uint(num)) + q, r := bits/7, bits%7 + size := q + if r > 0 || size == 0 { + size++ + } + return size +} + +// CodeToVarint converts an integer to a varint-encoded []byte +func CodeToVarint(num int) []byte { + buf := make([]byte, VarintSize(num)) + n := binary.PutUvarint(buf, uint64(num)) + return buf[:n] +} + +// VarintToCode converts a varint-encoded []byte to an integer protocol code +func VarintToCode(buf []byte) int { + num, _, err := ReadVarintCode(buf) + if err != nil { + panic(err) + } + return num +} + +// ReadVarintCode reads a varint code from the beginning of buf. +// returns the code, and the number of bytes read. +func ReadVarintCode(buf []byte) (int, int, error) { + num, n := binary.Uvarint(buf) + if n < 0 { + return 0, 0, fmt.Errorf("varints larger than uint64 not yet supported") + } + return int(num), n, nil +} diff --git a/vendor/github.com/multiformats/go-multibase/.codecov.yml b/vendor/github.com/multiformats/go-multibase/.codecov.yml new file mode 100644 index 00000000..db247200 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/.codecov.yml @@ -0,0 +1 @@ +comment: off diff --git a/vendor/github.com/multiformats/go-multibase/.gitignore b/vendor/github.com/multiformats/go-multibase/.gitignore new file mode 100644 index 00000000..175b2916 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/.gitignore @@ -0,0 +1,3 @@ +*.swp + +multibase-conv/multibase-conv diff --git a/vendor/github.com/multiformats/go-multibase/.gitmodules b/vendor/github.com/multiformats/go-multibase/.gitmodules new file mode 100644 index 00000000..74c037fa --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/.gitmodules @@ -0,0 +1,3 @@ +[submodule "spec"] + path = spec + url = https://github.com/multiformats/multibase.git diff --git a/vendor/github.com/multiformats/go-multibase/.gxignore b/vendor/github.com/multiformats/go-multibase/.gxignore new file mode 100644 index 00000000..c1d28ba5 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/.gxignore @@ -0,0 +1,2 @@ +/spec/ +*_test.go diff --git a/vendor/github.com/multiformats/go-multibase/.travis.yml b/vendor/github.com/multiformats/go-multibase/.travis.yml new file mode 100644 index 00000000..18f4287d --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multibase/LICENSE b/vendor/github.com/multiformats/go-multibase/LICENSE new file mode 100644 index 00000000..f64ffb04 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Protocol Labs Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multibase/Makefile b/vendor/github.com/multiformats/go-multibase/Makefile new file mode 100644 index 00000000..411b4a88 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/Makefile @@ -0,0 +1,13 @@ +test: deps + go test -race -v ./... + +export IPFS_API ?= v04x.ipfs.io + +gx: + go get -u github.com/whyrusleeping/gx + go get -u github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + go get -t ./... diff --git a/vendor/github.com/multiformats/go-multibase/README.md b/vendor/github.com/multiformats/go-multibase/README.md new file mode 100644 index 00000000..3c745445 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/README.md @@ -0,0 +1,49 @@ +# go-multibase + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![Travis CI](https://img.shields.io/travis/multiformats/go-multibase.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multibase) +[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multibase.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multibase?branch=master) + +> Implementation of [multibase](https://github.com/multiformats/multibase) -self identifying base encodings- in Go. + + +## Install + +`go-multibase` is a standard Go module which can be installed with: + +```sh +go get github.com/multiformats/go-multibase +``` + +Note that `go-multibase` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section). + +## Usage + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/multiformats/go-multibase +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multibase/issues). + +Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2016 Protocol Labs Inc. diff --git a/vendor/github.com/multiformats/go-multibase/base16.go b/vendor/github.com/multiformats/go-multibase/base16.go new file mode 100644 index 00000000..6b879419 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/base16.go @@ -0,0 +1,21 @@ +package multibase + +func hexEncodeToStringUpper(src []byte) string { + dst := make([]byte, len(src)*2) + hexEncodeUpper(dst, src) + return string(dst) +} + +var hexTableUppers = [16]byte{ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', +} + +func hexEncodeUpper(dst, src []byte) int { + for i, v := range src { + dst[i*2] = hexTableUppers[v>>4] + dst[i*2+1] = hexTableUppers[v&0x0f] + } + + return len(src) * 2 +} diff --git a/vendor/github.com/multiformats/go-multibase/base2.go b/vendor/github.com/multiformats/go-multibase/base2.go new file mode 100644 index 00000000..6e3f0cff --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/base2.go @@ -0,0 +1,52 @@ +package multibase + +import ( + "fmt" + "strconv" + "strings" +) + +// binaryEncodeToString takes an array of bytes and returns +// multibase binary representation +func binaryEncodeToString(src []byte) string { + dst := make([]byte, len(src)*8) + encodeBinary(dst, src) + return string(dst) +} + +// encodeBinary takes the src and dst bytes and converts each +// byte to their binary rep using power reduction method +func encodeBinary(dst []byte, src []byte) { + for i, b := range src { + for j := 0; j < 8; j++ { + if b&(1<>3) + + for i, dstIndex := 0, 0; i < len(s); i = i + 8 { + value, err := strconv.ParseInt(s[i:i+8], 2, 0) + if err != nil { + return nil, fmt.Errorf("error while conversion: %s", err) + } + + data[dstIndex] = byte(value) + dstIndex++ + } + + return data, nil +} diff --git a/vendor/github.com/multiformats/go-multibase/base32.go b/vendor/github.com/multiformats/go-multibase/base32.go new file mode 100644 index 00000000..a6fe8eb0 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/base32.go @@ -0,0 +1,17 @@ +package multibase + +import ( + b32 "github.com/multiformats/go-base32" +) + +var base32StdLowerPad = b32.NewEncodingCI("abcdefghijklmnopqrstuvwxyz234567") +var base32StdLowerNoPad = base32StdLowerPad.WithPadding(b32.NoPadding) + +var base32StdUpperPad = b32.NewEncodingCI("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567") +var base32StdUpperNoPad = base32StdUpperPad.WithPadding(b32.NoPadding) + +var base32HexLowerPad = b32.NewEncodingCI("0123456789abcdefghijklmnopqrstuv") +var base32HexLowerNoPad = base32HexLowerPad.WithPadding(b32.NoPadding) + +var base32HexUpperPad = b32.NewEncodingCI("0123456789ABCDEFGHIJKLMNOPQRSTUV") +var base32HexUpperNoPad = base32HexUpperPad.WithPadding(b32.NoPadding) diff --git a/vendor/github.com/multiformats/go-multibase/encoder.go b/vendor/github.com/multiformats/go-multibase/encoder.go new file mode 100644 index 00000000..42e753f5 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/encoder.go @@ -0,0 +1,63 @@ +package multibase + +import ( + "fmt" +) + +// Encoder is a multibase encoding that is verified to be supported and +// supports an Encode method that does not return an error +type Encoder struct { + enc Encoding +} + +// NewEncoder create a new Encoder from an Encoding +func NewEncoder(base Encoding) (Encoder, error) { + _, ok := EncodingToStr[base] + if !ok { + return Encoder{-1}, fmt.Errorf("Unsupported multibase encoding: %d", base) + } + return Encoder{base}, nil +} + +// MustNewEncoder is like NewEncoder but will panic if the encoding is +// invalid. +func MustNewEncoder(base Encoding) Encoder { + _, ok := EncodingToStr[base] + if !ok { + panic("Unsupported multibase encoding") + } + return Encoder{base} +} + +// EncoderByName creates an encoder from a string, the string can +// either be the multibase name or single character multibase prefix +func EncoderByName(str string) (Encoder, error) { + var base Encoding + ok := true + if len(str) == 0 { + return Encoder{-1}, fmt.Errorf("Empty multibase encoding") + } else if len(str) == 1 { + base = Encoding(str[0]) + _, ok = EncodingToStr[base] + } else { + base, ok = Encodings[str] + } + if !ok { + return Encoder{-1}, fmt.Errorf("Unsupported multibase encoding: %s", str) + } + return Encoder{base}, nil +} + +func (p Encoder) Encoding() Encoding { + return p.enc +} + +// Encode encodes the multibase using the given Encoder. +func (p Encoder) Encode(data []byte) string { + str, err := Encode(p.enc, data) + if err != nil { + // should not happen + panic(err) + } + return str +} diff --git a/vendor/github.com/multiformats/go-multibase/go.mod b/vendor/github.com/multiformats/go-multibase/go.mod new file mode 100644 index 00000000..28d6eb12 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/go.mod @@ -0,0 +1,6 @@ +module github.com/multiformats/go-multibase + +require ( + github.com/mr-tron/base58 v1.1.0 + github.com/multiformats/go-base32 v0.0.3 +) diff --git a/vendor/github.com/multiformats/go-multibase/go.sum b/vendor/github.com/multiformats/go-multibase/go.sum new file mode 100644 index 00000000..510e3dcd --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/go.sum @@ -0,0 +1,4 @@ +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= diff --git a/vendor/github.com/multiformats/go-multibase/multibase.go b/vendor/github.com/multiformats/go-multibase/multibase.go new file mode 100644 index 00000000..0f9b3961 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/multibase.go @@ -0,0 +1,187 @@ +package multibase + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + + b58 "github.com/mr-tron/base58/base58" + b32 "github.com/multiformats/go-base32" +) + +// Encoding identifies the type of base-encoding that a multibase is carrying. +type Encoding int + +// These are the encodings specified in the standard, not are all +// supported yet +const ( + Identity = 0x00 + Base1 = '1' + Base2 = '0' + Base8 = '7' + Base10 = '9' + Base16 = 'f' + Base16Upper = 'F' + Base32 = 'b' + Base32Upper = 'B' + Base32pad = 'c' + Base32padUpper = 'C' + Base32hex = 'v' + Base32hexUpper = 'V' + Base32hexPad = 't' + Base32hexPadUpper = 'T' + Base58Flickr = 'Z' + Base58BTC = 'z' + Base64 = 'm' + Base64url = 'u' + Base64pad = 'M' + Base64urlPad = 'U' +) + +// Encodings is a map of the supported encoding, unsupported encoding +// specified in standard are left out +var Encodings = map[string]Encoding{ + "identity": 0x00, + "base2": '0', + "base16": 'f', + "base16upper": 'F', + "base32": 'b', + "base32upper": 'B', + "base32pad": 'c', + "base32padupper": 'C', + "base32hex": 'v', + "base32hexupper": 'V', + "base32hexpad": 't', + "base32hexpadupper": 'T', + "base58flickr": 'Z', + "base58btc": 'z', + "base64": 'm', + "base64url": 'u', + "base64pad": 'M', + "base64urlpad": 'U', +} + +var EncodingToStr = map[Encoding]string{ + 0x00: "identity", + '0': "base2", + 'f': "base16", + 'F': "base16upper", + 'b': "base32", + 'B': "base32upper", + 'c': "base32pad", + 'C': "base32padupper", + 'v': "base32hex", + 'V': "base32hexupper", + 't': "base32hexpad", + 'T': "base32hexpadupper", + 'Z': "base58flickr", + 'z': "base58btc", + 'm': "base64", + 'u': "base64url", + 'M': "base64pad", + 'U': "base64urlpad", +} + +// ErrUnsupportedEncoding is returned when the selected encoding is not known or +// implemented. +var ErrUnsupportedEncoding = fmt.Errorf("selected encoding not supported") + +// Encode encodes a given byte slice with the selected encoding and returns a +// multibase string (). It will return +// an error if the selected base is not known. +func Encode(base Encoding, data []byte) (string, error) { + switch base { + case Identity: + // 0x00 inside a string is OK in golang and causes no problems with the length calculation. + return string(Identity) + string(data), nil + case Base2: + return string(Base2) + binaryEncodeToString(data), nil + case Base16: + return string(Base16) + hex.EncodeToString(data), nil + case Base16Upper: + return string(Base16Upper) + hexEncodeToStringUpper(data), nil + case Base32: + return string(Base32) + base32StdLowerNoPad.EncodeToString(data), nil + case Base32Upper: + return string(Base32Upper) + base32StdUpperNoPad.EncodeToString(data), nil + case Base32hex: + return string(Base32hex) + base32HexLowerNoPad.EncodeToString(data), nil + case Base32hexUpper: + return string(Base32hexUpper) + base32HexUpperNoPad.EncodeToString(data), nil + case Base32pad: + return string(Base32pad) + base32StdLowerPad.EncodeToString(data), nil + case Base32padUpper: + return string(Base32padUpper) + base32StdUpperPad.EncodeToString(data), nil + case Base32hexPad: + return string(Base32hexPad) + base32HexLowerPad.EncodeToString(data), nil + case Base32hexPadUpper: + return string(Base32hexPadUpper) + base32HexUpperPad.EncodeToString(data), nil + case Base58BTC: + return string(Base58BTC) + b58.EncodeAlphabet(data, b58.BTCAlphabet), nil + case Base58Flickr: + return string(Base58Flickr) + b58.EncodeAlphabet(data, b58.FlickrAlphabet), nil + case Base64pad: + return string(Base64pad) + base64.StdEncoding.EncodeToString(data), nil + case Base64urlPad: + return string(Base64urlPad) + base64.URLEncoding.EncodeToString(data), nil + case Base64url: + return string(Base64url) + base64.RawURLEncoding.EncodeToString(data), nil + case Base64: + return string(Base64) + base64.RawStdEncoding.EncodeToString(data), nil + default: + return "", ErrUnsupportedEncoding + } +} + +// Decode takes a multibase string and decodes into a bytes buffer. +// It will return an error if the selected base is not known. +func Decode(data string) (Encoding, []byte, error) { + if len(data) == 0 { + return 0, nil, fmt.Errorf("cannot decode multibase for zero length string") + } + + enc := Encoding(data[0]) + + switch enc { + case Identity: + return Identity, []byte(data[1:]), nil + case Base2: + bytes, err := decodeBinaryString(data[1:]) + return enc, bytes, err + case Base16, Base16Upper: + bytes, err := hex.DecodeString(data[1:]) + return enc, bytes, err + case Base32, Base32Upper: + bytes, err := b32.RawStdEncoding.DecodeString(data[1:]) + return enc, bytes, err + case Base32hex, Base32hexUpper: + bytes, err := b32.RawHexEncoding.DecodeString(data[1:]) + return enc, bytes, err + case Base32pad, Base32padUpper: + bytes, err := b32.StdEncoding.DecodeString(data[1:]) + return enc, bytes, err + case Base32hexPad, Base32hexPadUpper: + bytes, err := b32.HexEncoding.DecodeString(data[1:]) + return enc, bytes, err + case Base58BTC: + bytes, err := b58.DecodeAlphabet(data[1:], b58.BTCAlphabet) + return Base58BTC, bytes, err + case Base58Flickr: + bytes, err := b58.DecodeAlphabet(data[1:], b58.FlickrAlphabet) + return Base58Flickr, bytes, err + case Base64pad: + bytes, err := base64.StdEncoding.DecodeString(data[1:]) + return Base64pad, bytes, err + case Base64urlPad: + bytes, err := base64.URLEncoding.DecodeString(data[1:]) + return Base64urlPad, bytes, err + case Base64: + bytes, err := base64.RawStdEncoding.DecodeString(data[1:]) + return Base64, bytes, err + case Base64url: + bytes, err := base64.RawURLEncoding.DecodeString(data[1:]) + return Base64url, bytes, err + default: + return -1, nil, ErrUnsupportedEncoding + } +} diff --git a/vendor/github.com/multiformats/go-multibase/package.json b/vendor/github.com/multiformats/go-multibase/package.json new file mode 100644 index 00000000..75f742e6 --- /dev/null +++ b/vendor/github.com/multiformats/go-multibase/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/multiformats/go-multibase" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-multibase" + }, + "gxDependencies": [ + { + "author": "mr-tron", + "hash": "QmWFAMPqsEyUX7gDUsRVmMWz59FxSpJ1b2v6bJ1yYzo7jY", + "name": "go-base58-fast", + "version": "0.1.1" + }, + { + "author": "Golang", + "hash": "QmPbbYin7KBd1Y1BfUe15vHzwJiioyi3wtKQTtXWWf8SC5", + "name": "base32", + "version": "0.0.3" + } + ], + "gxVersion": "0.8.0", + "language": "go", + "license": "", + "name": "go-multibase", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.3.0" +} + diff --git a/vendor/github.com/multiformats/go-multihash/.gitignore b/vendor/github.com/multiformats/go-multihash/.gitignore new file mode 100644 index 00000000..1d74e219 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/vendor/github.com/multiformats/go-multihash/.travis.yml b/vendor/github.com/multiformats/go-multihash/.travis.yml new file mode 100644 index 00000000..09f9a4cc --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/.travis.yml @@ -0,0 +1,30 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multihash/LICENSE b/vendor/github.com/multiformats/go-multihash/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multihash/Makefile b/vendor/github.com/multiformats/go-multihash/Makefile new file mode 100644 index 00000000..20619413 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/Makefile @@ -0,0 +1,11 @@ +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/multiformats/go-multihash/README.md b/vendor/github.com/multiformats/go-multihash/README.md new file mode 100644 index 00000000..dd7f2386 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/README.md @@ -0,0 +1,90 @@ +# go-multihash + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/multiformats/go-multihash?status.svg)](https://godoc.org/github.com/multiformats/go-multihash) +[![Travis CI](https://img.shields.io/travis/multiformats/go-multihash.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multihash) +[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multihash.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multihash?branch=master) + +> [multihash](https://github.com/multiformats/multihash) implementation in Go + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Maintainers](#maintainers) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-multihash` is a standard Go module which can be installed with: + +```sh +go get github.com/multiformats/go-multihash +``` + +## Usage + + +### Example + +This example takes a standard hex-encoded data and uses `EncodeName` to calculate the SHA1 multihash value for the buffer. + +The resulting hex-encoded data corresponds to: ``, which could be re-parsed +with `Multihash.FromHexString()`. + + +```go +package main + +import ( + "encoding/hex" + "fmt" + + "github.com/multiformats/go-multihash" +) + +func main() { + // ignores errors for simplicity. + // don't do that at home. + // Decode a SHA1 hash to a binary buffer + buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") + + // Create a new multihash with it. + mHashBuf, _ := multihash.EncodeName(buf, "sha1") + // Print the multihash as hex string + fmt.Printf("hex: %s\n", hex.EncodeToString(mHashBuf)) + + // Parse the binary multihash to a DecodedMultihash + mHash, _ := multihash.Decode(mHashBuf) + // Convert the sha1 value to hex string + sha1hex := hex.EncodeToString(mHash.Digest) + // Print all the information in the multihash + fmt.Printf("obj: %v 0x%x %d %s\n", mHash.Name, mHash.Code, mHash.Length, sha1hex) +} +``` + +To run, copy to [example/foo.go](example/foo.go) and: + +``` +> cd example/ +> go build +> ./example +hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +``` + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multihash/issues). + +Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2014 Juan Batiz-Benet diff --git a/vendor/github.com/multiformats/go-multihash/codecov.yml b/vendor/github.com/multiformats/go-multihash/codecov.yml new file mode 100644 index 00000000..5f88a9ea --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/codecov.yml @@ -0,0 +1,3 @@ +coverage: + range: "50...100" +comment: off diff --git a/vendor/github.com/multiformats/go-multihash/go.mod b/vendor/github.com/multiformats/go-multihash/go.mod new file mode 100644 index 00000000..27de256a --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/go.mod @@ -0,0 +1,9 @@ +module github.com/multiformats/go-multihash + +require ( + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 + github.com/minio/sha256-simd v0.1.0 + github.com/mr-tron/base58 v1.1.2 + github.com/spaolacci/murmur3 v1.1.0 + golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 +) diff --git a/vendor/github.com/multiformats/go-multihash/go.sum b/vendor/github.com/multiformats/go-multihash/go.sum new file mode 100644 index 00000000..c599c83a --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/go.sum @@ -0,0 +1,16 @@ +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/multiformats/go-multihash/io.go b/vendor/github.com/multiformats/go-multihash/io.go new file mode 100644 index 00000000..46290168 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/io.go @@ -0,0 +1,103 @@ +package multihash + +import ( + "encoding/binary" + "errors" + "io" + "math" +) + +// Reader is an io.Reader wrapper that exposes a function +// to read a whole multihash, parse it, and return it. +type Reader interface { + io.Reader + + ReadMultihash() (Multihash, error) +} + +// Writer is an io.Writer wrapper that exposes a function +// to write a whole multihash. +type Writer interface { + io.Writer + + WriteMultihash(Multihash) error +} + +// NewReader wraps an io.Reader with a multihash.Reader +func NewReader(r io.Reader) Reader { + return &mhReader{r} +} + +// NewWriter wraps an io.Writer with a multihash.Writer +func NewWriter(w io.Writer) Writer { + return &mhWriter{w} +} + +type mhReader struct { + r io.Reader +} + +func (r *mhReader) Read(buf []byte) (n int, err error) { + return r.r.Read(buf) +} + +func (r *mhReader) ReadByte() (byte, error) { + if br, ok := r.r.(io.ByteReader); ok { + return br.ReadByte() + } + var b [1]byte + n, err := r.r.Read(b[:]) + if n == 1 { + return b[0], nil + } + if err == nil { + if n != 0 { + panic("reader returned an invalid length") + } + err = io.ErrNoProgress + } + return 0, err +} + +func (r *mhReader) ReadMultihash() (Multihash, error) { + code, err := binary.ReadUvarint(r) + if err != nil { + return nil, err + } + + length, err := binary.ReadUvarint(r) + if err != nil { + return nil, err + } + if length > math.MaxInt32 { + return nil, errors.New("digest too long, supporting only <= 2^31-1") + } + + pre := make([]byte, 2*binary.MaxVarintLen64) + spot := pre + n := binary.PutUvarint(spot, code) + spot = pre[n:] + n += binary.PutUvarint(spot, length) + + buf := make([]byte, int(length)+n) + copy(buf, pre[:n]) + + if _, err := io.ReadFull(r.r, buf[n:]); err != nil { + return nil, err + } + + return Cast(buf) +} + +type mhWriter struct { + w io.Writer +} + +func (w *mhWriter) Write(buf []byte) (n int, err error) { + return w.w.Write(buf) +} + +func (w *mhWriter) WriteMultihash(m Multihash) error { + _, err := w.w.Write([]byte(m)) + return err +} diff --git a/vendor/github.com/multiformats/go-multihash/multihash.go b/vendor/github.com/multiformats/go-multihash/multihash.go new file mode 100644 index 00000000..ccfea831 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/multihash.go @@ -0,0 +1,298 @@ +// Package multihash is the Go implementation of +// https://github.com/multiformats/multihash, or self-describing +// hashes. +package multihash + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "math" + + b58 "github.com/mr-tron/base58/base58" +) + +// errors +var ( + ErrUnknownCode = errors.New("unknown multihash code") + ErrTooShort = errors.New("multihash too short. must be >= 2 bytes") + ErrTooLong = errors.New("multihash too long. must be < 129 bytes") + ErrLenNotSupported = errors.New("multihash does not yet support digests longer than 127 bytes") + ErrInvalidMultihash = errors.New("input isn't valid multihash") + + ErrVarintBufferShort = errors.New("uvarint: buffer too small") + ErrVarintTooLong = errors.New("uvarint: varint too big (max 64bit)") +) + +// ErrInconsistentLen is returned when a decoded multihash has an inconsistent length +type ErrInconsistentLen struct { + dm *DecodedMultihash +} + +func (e ErrInconsistentLen) Error() string { + return fmt.Sprintf("multihash length inconsistent: expected %d, got %d", e.dm.Length, len(e.dm.Digest)) +} + +// constants +const ( + ID = 0x00 + SHA1 = 0x11 + SHA2_256 = 0x12 + SHA2_512 = 0x13 + SHA3_224 = 0x17 + SHA3_256 = 0x16 + SHA3_384 = 0x15 + SHA3_512 = 0x14 + SHA3 = SHA3_512 + KECCAK_224 = 0x1A + KECCAK_256 = 0x1B + KECCAK_384 = 0x1C + KECCAK_512 = 0x1D + + SHAKE_128 = 0x18 + SHAKE_256 = 0x19 + + BLAKE2B_MIN = 0xb201 + BLAKE2B_MAX = 0xb240 + BLAKE2S_MIN = 0xb241 + BLAKE2S_MAX = 0xb260 + + MD5 = 0xd5 + + DBL_SHA2_256 = 0x56 + + MURMUR3 = 0x22 + + X11 = 0x1100 +) + +func init() { + // Add blake2b (64 codes) + for c := uint64(BLAKE2B_MIN); c <= BLAKE2B_MAX; c++ { + n := c - BLAKE2B_MIN + 1 + name := fmt.Sprintf("blake2b-%d", n*8) + Names[name] = c + Codes[c] = name + DefaultLengths[c] = int(n) + } + + // Add blake2s (32 codes) + for c := uint64(BLAKE2S_MIN); c <= BLAKE2S_MAX; c++ { + n := c - BLAKE2S_MIN + 1 + name := fmt.Sprintf("blake2s-%d", n*8) + Names[name] = c + Codes[c] = name + DefaultLengths[c] = int(n) + } +} + +// Names maps the name of a hash to the code +var Names = map[string]uint64{ + "id": ID, + "sha1": SHA1, + "sha2-256": SHA2_256, + "sha2-512": SHA2_512, + "sha3": SHA3_512, + "sha3-224": SHA3_224, + "sha3-256": SHA3_256, + "sha3-384": SHA3_384, + "sha3-512": SHA3_512, + "dbl-sha2-256": DBL_SHA2_256, + "murmur3": MURMUR3, + "keccak-224": KECCAK_224, + "keccak-256": KECCAK_256, + "keccak-384": KECCAK_384, + "keccak-512": KECCAK_512, + "shake-128": SHAKE_128, + "shake-256": SHAKE_256, + "x11": X11, + "md5": MD5, +} + +// Codes maps a hash code to it's name +var Codes = map[uint64]string{ + ID: "id", + SHA1: "sha1", + SHA2_256: "sha2-256", + SHA2_512: "sha2-512", + SHA3_224: "sha3-224", + SHA3_256: "sha3-256", + SHA3_384: "sha3-384", + SHA3_512: "sha3-512", + DBL_SHA2_256: "dbl-sha2-256", + MURMUR3: "murmur3", + KECCAK_224: "keccak-224", + KECCAK_256: "keccak-256", + KECCAK_384: "keccak-384", + KECCAK_512: "keccak-512", + SHAKE_128: "shake-128", + SHAKE_256: "shake-256", + X11: "x11", + MD5: "md5", +} + +// DefaultLengths maps a hash code to it's default length +var DefaultLengths = map[uint64]int{ + ID: -1, + SHA1: 20, + SHA2_256: 32, + SHA2_512: 64, + SHA3_224: 28, + SHA3_256: 32, + SHA3_384: 48, + SHA3_512: 64, + DBL_SHA2_256: 32, + KECCAK_224: 28, + KECCAK_256: 32, + MURMUR3: 4, + KECCAK_384: 48, + KECCAK_512: 64, + SHAKE_128: 32, + SHAKE_256: 64, + X11: 64, + MD5: 16, +} + +func uvarint(buf []byte) (uint64, []byte, error) { + n, c := binary.Uvarint(buf) + + if c == 0 { + return n, buf, ErrVarintBufferShort + } else if c < 0 { + return n, buf[-c:], ErrVarintTooLong + } else { + return n, buf[c:], nil + } +} + +// DecodedMultihash represents a parsed multihash and allows +// easy access to the different parts of a multihash. +type DecodedMultihash struct { + Code uint64 + Name string + Length int // Length is just int as it is type of len() opearator + Digest []byte // Digest holds the raw multihash bytes +} + +// Multihash is byte slice with the following form: +// . +// See the spec for more information. +type Multihash []byte + +// HexString returns the hex-encoded representation of a multihash. +func (m *Multihash) HexString() string { + return hex.EncodeToString([]byte(*m)) +} + +// String is an alias to HexString(). +func (m *Multihash) String() string { + return m.HexString() +} + +// FromHexString parses a hex-encoded multihash. +func FromHexString(s string) (Multihash, error) { + b, err := hex.DecodeString(s) + if err != nil { + return Multihash{}, err + } + + return Cast(b) +} + +// B58String returns the B58-encoded representation of a multihash. +func (m Multihash) B58String() string { + return b58.Encode([]byte(m)) +} + +// FromB58String parses a B58-encoded multihash. +func FromB58String(s string) (m Multihash, err error) { + b, err := b58.Decode(s) + if err != nil { + return Multihash{}, ErrInvalidMultihash + } + + return Cast(b) +} + +// Cast casts a buffer onto a multihash, and returns an error +// if it does not work. +func Cast(buf []byte) (Multihash, error) { + dm, err := Decode(buf) + if err != nil { + return Multihash{}, err + } + + if !ValidCode(dm.Code) { + return Multihash{}, ErrUnknownCode + } + + return Multihash(buf), nil +} + +// Decode parses multihash bytes into a DecodedMultihash. +func Decode(buf []byte) (*DecodedMultihash, error) { + + if len(buf) < 2 { + return nil, ErrTooShort + } + + var err error + var code, length uint64 + + code, buf, err = uvarint(buf) + if err != nil { + return nil, err + } + + length, buf, err = uvarint(buf) + if err != nil { + return nil, err + } + + if length > math.MaxInt32 { + return nil, errors.New("digest too long, supporting only <= 2^31-1") + } + + dm := &DecodedMultihash{ + Code: code, + Name: Codes[code], + Length: int(length), + Digest: buf, + } + + if len(dm.Digest) != dm.Length { + return nil, ErrInconsistentLen{dm} + } + + return dm, nil +} + +// Encode a hash digest along with the specified function code. +// Note: the length is derived from the length of the digest itself. +func Encode(buf []byte, code uint64) ([]byte, error) { + + if !ValidCode(code) { + return nil, ErrUnknownCode + } + + start := make([]byte, 2*binary.MaxVarintLen64, 2*binary.MaxVarintLen64+len(buf)) + spot := start + n := binary.PutUvarint(spot, code) + spot = start[n:] + n += binary.PutUvarint(spot, uint64(len(buf))) + + return append(start[:n], buf...), nil +} + +// EncodeName is like Encode() but providing a string name +// instead of a numeric code. See Names for allowed values. +func EncodeName(buf []byte, name string) ([]byte, error) { + return Encode(buf, Names[name]) +} + +// ValidCode checks whether a multihash code is valid. +func ValidCode(code uint64) bool { + _, ok := Codes[code] + return ok +} diff --git a/vendor/github.com/multiformats/go-multihash/multihash/LICENSE b/vendor/github.com/multiformats/go-multihash/multihash/LICENSE new file mode 100644 index 00000000..c7386b3c --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/multihash/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multihash/sum.go b/vendor/github.com/multiformats/go-multihash/sum.go new file mode 100644 index 00000000..249cb757 --- /dev/null +++ b/vendor/github.com/multiformats/go-multihash/sum.go @@ -0,0 +1,230 @@ +package multihash + +import ( + "crypto/md5" + "crypto/sha1" + "crypto/sha512" + "errors" + "fmt" + + blake2b "github.com/minio/blake2b-simd" + sha256 "github.com/minio/sha256-simd" + murmur3 "github.com/spaolacci/murmur3" + blake2s "golang.org/x/crypto/blake2s" + sha3 "golang.org/x/crypto/sha3" +) + +// ErrSumNotSupported is returned when the Sum function code is not implemented +var ErrSumNotSupported = errors.New("Function not implemented. Complain to lib maintainer.") + +// HashFunc is a hash function that hashes data into digest. +// +// The length is the size the digest will be truncated to. While the hash +// function isn't responsible for truncating the digest, it may want to error if +// the length is invalid for the hash function (e.g., truncation would make the +// hash useless). +type HashFunc func(data []byte, length int) (digest []byte, err error) + +// funcTable maps multicodec values to hash functions. +var funcTable = make(map[uint64]HashFunc) + +// Sum obtains the cryptographic sum of a given buffer. The length parameter +// indicates the length of the resulting digest and passing a negative value +// use default length values for the selected hash function. +func Sum(data []byte, code uint64, length int) (Multihash, error) { + if !ValidCode(code) { + return nil, fmt.Errorf("invalid multihash code %d", code) + } + + if length < 0 { + var ok bool + length, ok = DefaultLengths[code] + if !ok { + return nil, fmt.Errorf("no default length for code %d", code) + } + } + + hashFunc, ok := funcTable[code] + if !ok { + return nil, ErrSumNotSupported + } + + d, err := hashFunc(data, length) + if err != nil { + return nil, err + } + if length >= 0 { + d = d[:length] + } + return Encode(d, code) +} + +func sumBlake2s(data []byte, size int) ([]byte, error) { + if size != 32 { + return nil, fmt.Errorf("unsupported length for blake2s: %d", size) + } + d := blake2s.Sum256(data) + return d[:], nil +} +func sumBlake2b(data []byte, size int) ([]byte, error) { + hasher, err := blake2b.New(&blake2b.Config{Size: uint8(size)}) + if err != nil { + return nil, err + } + + if _, err := hasher.Write(data); err != nil { + return nil, err + } + + return hasher.Sum(nil)[:], nil +} + +func sumID(data []byte, length int) ([]byte, error) { + if length >= 0 && length != len(data) { + return nil, fmt.Errorf("the length of the identity hash (%d) must be equal to the length of the data (%d)", + length, len(data)) + + } + return data, nil +} + +func sumSHA1(data []byte, length int) ([]byte, error) { + a := sha1.Sum(data) + return a[0:20], nil +} + +func sumSHA256(data []byte, length int) ([]byte, error) { + a := sha256.Sum256(data) + return a[0:32], nil +} + +func sumMD5(data []byte, length int) ([]byte, error) { + a := md5.Sum(data) + return a[0:md5.Size], nil +} + +func sumDoubleSHA256(data []byte, length int) ([]byte, error) { + val, _ := sumSHA256(data, len(data)) + return sumSHA256(val, len(val)) +} + +func sumSHA512(data []byte, length int) ([]byte, error) { + a := sha512.Sum512(data) + return a[0:64], nil +} +func sumKeccak256(data []byte, length int) ([]byte, error) { + h := sha3.NewLegacyKeccak256() + h.Write(data) + return h.Sum(nil), nil +} + +func sumKeccak512(data []byte, length int) ([]byte, error) { + h := sha3.NewLegacyKeccak512() + h.Write(data) + return h.Sum(nil), nil +} + +func sumSHA3_512(data []byte, length int) ([]byte, error) { + a := sha3.Sum512(data) + return a[:], nil +} + +func sumMURMUR3(data []byte, length int) ([]byte, error) { + number := murmur3.Sum32(data) + bytes := make([]byte, 4) + for i := range bytes { + bytes[i] = byte(number & 0xff) + number >>= 8 + } + return bytes, nil +} + +func sumSHAKE128(data []byte, length int) ([]byte, error) { + bytes := make([]byte, 32) + sha3.ShakeSum128(bytes, data) + return bytes, nil +} + +func sumSHAKE256(data []byte, length int) ([]byte, error) { + bytes := make([]byte, 64) + sha3.ShakeSum256(bytes, data) + return bytes, nil +} + +func sumSHA3_384(data []byte, length int) ([]byte, error) { + a := sha3.Sum384(data) + return a[:], nil +} + +func sumSHA3_256(data []byte, length int) ([]byte, error) { + a := sha3.Sum256(data) + return a[:], nil +} + +func sumSHA3_224(data []byte, length int) ([]byte, error) { + a := sha3.Sum224(data) + return a[:], nil +} + +func registerStdlibHashFuncs() { + RegisterHashFunc(ID, sumID) + RegisterHashFunc(SHA1, sumSHA1) + RegisterHashFunc(SHA2_512, sumSHA512) + RegisterHashFunc(MD5, sumMD5) +} + +func registerNonStdlibHashFuncs() { + RegisterHashFunc(SHA2_256, sumSHA256) + RegisterHashFunc(DBL_SHA2_256, sumDoubleSHA256) + + RegisterHashFunc(KECCAK_256, sumKeccak256) + RegisterHashFunc(KECCAK_512, sumKeccak512) + + RegisterHashFunc(SHA3_224, sumSHA3_224) + RegisterHashFunc(SHA3_256, sumSHA3_256) + RegisterHashFunc(SHA3_384, sumSHA3_384) + RegisterHashFunc(SHA3_512, sumSHA3_512) + + RegisterHashFunc(MURMUR3, sumMURMUR3) + + RegisterHashFunc(SHAKE_128, sumSHAKE128) + RegisterHashFunc(SHAKE_256, sumSHAKE256) + + // Blake family of hash functions + // BLAKE2S + for c := uint64(BLAKE2S_MIN); c <= BLAKE2S_MAX; c++ { + size := int(c - BLAKE2S_MIN + 1) + RegisterHashFunc(c, func(buf []byte, _ int) ([]byte, error) { + return sumBlake2s(buf, size) + }) + } + // BLAKE2B + for c := uint64(BLAKE2B_MIN); c <= BLAKE2B_MAX; c++ { + size := int(c - BLAKE2B_MIN + 1) + RegisterHashFunc(c, func(buf []byte, _ int) ([]byte, error) { + return sumBlake2b(buf, size) + }) + } +} + +func init() { + registerStdlibHashFuncs() + registerNonStdlibHashFuncs() +} + +// RegisterHashFunc adds an entry to the package-level code -> hash func map. +// The hash function must return at least the requested number of bytes. If it +// returns more, the hash will be truncated. +func RegisterHashFunc(code uint64, hashFunc HashFunc) error { + if !ValidCode(code) { + return fmt.Errorf("code %v not valid", code) + } + + _, ok := funcTable[code] + if ok { + return fmt.Errorf("hash func for code %v already registered", code) + } + + funcTable[code] = hashFunc + return nil +} diff --git a/vendor/github.com/multiformats/go-multistream/.travis.yml b/vendor/github.com/multiformats/go-multistream/.travis.yml new file mode 100644 index 00000000..18f4287d --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/.travis.yml @@ -0,0 +1,32 @@ +os: + - linux + +language: go + +go: + - 1.11.x + +env: + global: + - GOTFLAGS="-race" + matrix: + - BUILD_DEPTYPE=gx + - BUILD_DEPTYPE=gomod + + +# disable travis install +install: + - true + +script: + - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) + + +cache: + directories: + - $GOPATH/src/gx + - $GOPATH/pkg/mod + - /home/travis/.cache/go-build + +notifications: + email: false diff --git a/vendor/github.com/multiformats/go-multistream/LICENSE b/vendor/github.com/multiformats/go-multistream/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/multiformats/go-multistream/Makefile b/vendor/github.com/multiformats/go-multistream/Makefile new file mode 100644 index 00000000..4f5206e4 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/Makefile @@ -0,0 +1,13 @@ +export IPFS_API ?= v04x.ipfs.io + +gx: + go get github.com/whyrusleeping/gx + go get github.com/whyrusleeping/gx-go + +deps: gx + gx --verbose install --global + gx-go rewrite + +publish: + gx-go rewrite --undo + diff --git a/vendor/github.com/multiformats/go-multistream/README.md b/vendor/github.com/multiformats/go-multistream/README.md new file mode 100644 index 00000000..0111fe61 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/README.md @@ -0,0 +1,148 @@ +# go-multistream + +[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) +[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats) +[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs) +[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![GoDoc](https://godoc.org/github.com/multiformats/go-multistream?status.svg)](https://godoc.org/github.com/multiformats/go-multistream) +[![Travis CI](https://img.shields.io/travis/multiformats/go-multistream.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multistream) +[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multistream.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multistream?branch=master) + +> an implementation of the multistream protocol in go + +This package implements a simple stream router for the multistream-select protocol. +The protocol is defined [here](https://github.com/multiformats/multistream-select). + +## Table of Contents + + +- [Install](#install) +- [Usage](#usage) +- [Maintainers](#maintainers) +- [Contribute](#contribute) +- [License](#license) + +## Install + +`go-multistream` is a standard Go module which can be installed with: + +```sh +go get github.com/multiformats/go-multistream +``` + +Note that `go-multistream` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section). + + +## Usage + +### Using Gx and Gx-go + +This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project do: + +```sh +go get -u github.com/whyrusleeping/gx +go get -u github.com/whyrusleeping/gx-go +cd +gx init +gx import github.com/multiformats/go-multistream +gx install --global +gx-go --rewrite +``` + +Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information. + +### Example + + +This example shows how to use a multistream muxer. A muxer uses user-added handlers to handle different "protocols". The first step when interacting with a connection handler by the muxer is to select the protocol (the example uses `SelectProtoOrFail`). This will then let the muxer use the right handler. + + +```go +package main + +import ( + "fmt" + "io" + "io/ioutil" + "net" + + ms "github.com/multiformats/go-multistream" +) + +// This example creates a multistream muxer, adds handlers for the protocols +// "/cats" and "/dogs" and exposes it on a localhost:8765. It then opens connections +// to that port, selects the protocols and tests that the handlers are working. +func main() { + mux := ms.NewMultistreamMuxer() + mux.AddHandler("/cats", func(proto string, rwc io.ReadWriteCloser) error { + fmt.Fprintln(rwc, proto, ": HELLO I LIKE CATS") + return rwc.Close() + }) + mux.AddHandler("/dogs", func(proto string, rwc io.ReadWriteCloser) error { + fmt.Fprintln(rwc, proto, ": HELLO I LIKE DOGS") + return rwc.Close() + }) + + list, err := net.Listen("tcp", ":8765") + if err != nil { + panic(err) + } + + go func() { + for { + con, err := list.Accept() + if err != nil { + panic(err) + } + + go mux.Handle(con) + } + }() + + // The Muxer is ready, let's test it + conn, err := net.Dial("tcp", ":8765") + if err != nil { + panic(err) + } + + // Create a new multistream to talk to the muxer + // which will negotiate that we want to talk with /cats + mstream := ms.NewMSSelect(conn, "/cats") + cats, err := ioutil.ReadAll(mstream) + if err != nil { + panic(err) + } + fmt.Printf("%s", cats) + mstream.Close() + + // A different way of talking to the muxer + // is to manually selecting the protocol ourselves + conn, err = net.Dial("tcp", ":8765") + if err != nil { + panic(err) + } + defer conn.Close() + err = ms.SelectProtoOrFail("/dogs", conn) + if err != nil { + panic(err) + } + dogs, err := ioutil.ReadAll(conn) + if err != nil { + panic(err) + } + fmt.Printf("%s", dogs) + conn.Close() +} +``` + +## Contribute + +Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multistream/issues). + +Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. + +## License + +[MIT](LICENSE) © 2016 Jeromy Johnson diff --git a/vendor/github.com/multiformats/go-multistream/client.go b/vendor/github.com/multiformats/go-multistream/client.go new file mode 100644 index 00000000..9a8f15e8 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/client.go @@ -0,0 +1,123 @@ +package multistream + +import ( + "bytes" + "errors" + "io" +) + +// ErrNotSupported is the error returned when the muxer does not support +// the protocol specified for the handshake. +var ErrNotSupported = errors.New("protocol not supported") + +// ErrNoProtocols is the error returned when the no protocols have been +// specified. +var ErrNoProtocols = errors.New("no protocols specified") + +// SelectProtoOrFail performs the initial multistream handshake +// to inform the muxer of the protocol that will be used to communicate +// on this ReadWriteCloser. It returns an error if, for example, +// the muxer does not know how to handle this protocol. +func SelectProtoOrFail(proto string, rwc io.ReadWriteCloser) error { + errCh := make(chan error, 1) + go func() { + var buf bytes.Buffer + delimWrite(&buf, []byte(ProtocolID)) + delimWrite(&buf, []byte(proto)) + _, err := io.Copy(rwc, &buf) + errCh <- err + }() + // We have to read *both* errors. + err1 := readMultistreamHeader(rwc) + err2 := readProto(proto, rwc) + if werr := <-errCh; werr != nil { + return werr + } + if err1 != nil { + return err1 + } + if err2 != nil { + return err2 + } + return nil +} + +// SelectOneOf will perform handshakes with the protocols on the given slice +// until it finds one which is supported by the muxer. +func SelectOneOf(protos []string, rwc io.ReadWriteCloser) (string, error) { + if len(protos) == 0 { + return "", ErrNoProtocols + } + + // Use SelectProtoOrFail to pipeline the /multistream/1.0.0 handshake + // with an attempt to negotiate the first protocol. If that fails, we + // can continue negotiating the rest of the protocols normally. + // + // This saves us a round trip. + switch err := SelectProtoOrFail(protos[0], rwc); err { + case nil: + return protos[0], nil + case ErrNotSupported: // try others + default: + return "", err + } + for _, p := range protos[1:] { + err := trySelect(p, rwc) + switch err { + case nil: + return p, nil + case ErrNotSupported: + default: + return "", err + } + } + return "", ErrNotSupported +} + +func handshake(rwc io.ReadWriteCloser) error { + errCh := make(chan error, 1) + go func() { + errCh <- delimWriteBuffered(rwc, []byte(ProtocolID)) + }() + + if err := readMultistreamHeader(rwc); err != nil { + return err + } + return <-errCh +} + +func readMultistreamHeader(r io.ReadWriter) error { + tok, err := ReadNextToken(r) + if err != nil { + return err + } + + if tok != ProtocolID { + return errors.New("received mismatch in protocol id") + } + return nil +} + +func trySelect(proto string, rwc io.ReadWriteCloser) error { + err := delimWriteBuffered(rwc, []byte(proto)) + if err != nil { + return err + } + return readProto(proto, rwc) +} + +func readProto(proto string, rw io.ReadWriter) error { + tok, err := ReadNextToken(rw) + if err != nil { + return err + } + + switch tok { + case proto: + return nil + case "na": + return ErrNotSupported + default: + return errors.New("unrecognized response: " + tok) + } +} diff --git a/vendor/github.com/multiformats/go-multistream/go.mod b/vendor/github.com/multiformats/go-multistream/go.mod new file mode 100644 index 00000000..560ed671 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/go.mod @@ -0,0 +1 @@ +module github.com/multiformats/go-multistream diff --git a/vendor/github.com/multiformats/go-multistream/lazyClient.go b/vendor/github.com/multiformats/go-multistream/lazyClient.go new file mode 100644 index 00000000..f8d90018 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/lazyClient.go @@ -0,0 +1,143 @@ +package multistream + +import ( + "fmt" + "io" + "sync" +) + +// Multistream represents in essense a ReadWriteCloser, or a single +// communication wire which supports multiple streams on it. Each +// stream is identified by a protocol tag. +type Multistream interface { + io.ReadWriteCloser +} + +// NewMSSelect returns a new Multistream which is able to perform +// protocol selection with a MultistreamMuxer. +func NewMSSelect(c io.ReadWriteCloser, proto string) Multistream { + return &lazyClientConn{ + protos: []string{ProtocolID, proto}, + con: c, + } +} + +// NewMultistream returns a multistream for the given protocol. This will not +// perform any protocol selection. If you are using a MultistreamMuxer, use +// NewMSSelect. +func NewMultistream(c io.ReadWriteCloser, proto string) Multistream { + return &lazyClientConn{ + protos: []string{proto}, + con: c, + } +} + +// lazyClientConn is a ReadWriteCloser adapter that lazily negotiates a protocol +// using multistream-select on first use. +// +// It *does not* block writes waiting for the other end to respond. Instead, it +// simply assumes the negotiation went successfully and starts writing data. +// See: https://github.com/multiformats/go-multistream/issues/20 +type lazyClientConn struct { + // Used to ensure we only trigger the write half of the handshake once. + rhandshakeOnce sync.Once + rerr error + + // Used to ensure we only trigger the read half of the handshake once. + whandshakeOnce sync.Once + werr error + + // The sequence of protocols to negotiate. + protos []string + + // The inner connection. + con io.ReadWriteCloser +} + +// Read reads data from the io.ReadWriteCloser. +// +// If the protocol hasn't yet been negotiated, this method triggers the write +// half of the handshake and then waits for the read half to complete. +// +// It returns an error if the read half of the handshake fails. +func (l *lazyClientConn) Read(b []byte) (int, error) { + l.rhandshakeOnce.Do(func() { + go l.whandshakeOnce.Do(l.doWriteHandshake) + l.doReadHandshake() + }) + if l.rerr != nil { + return 0, l.rerr + } + if len(b) == 0 { + return 0, nil + } + + return l.con.Read(b) +} + +func (l *lazyClientConn) doReadHandshake() { + for _, proto := range l.protos { + // read protocol + tok, err := ReadNextToken(l.con) + if err != nil { + l.rerr = err + return + } + + if tok != proto { + l.rerr = fmt.Errorf("protocol mismatch in lazy handshake ( %s != %s )", tok, proto) + return + } + } +} + +func (l *lazyClientConn) doWriteHandshake() { + l.doWriteHandshakeWithData(nil) +} + +// Perform the write handshake but *also* write some extra data. +func (l *lazyClientConn) doWriteHandshakeWithData(extra []byte) int { + buf := getWriter(l.con) + defer putWriter(buf) + + for _, proto := range l.protos { + l.werr = delimWrite(buf, []byte(proto)) + if l.werr != nil { + return 0 + } + } + + n := 0 + if len(extra) > 0 { + n, l.werr = buf.Write(extra) + if l.werr != nil { + return n + } + } + l.werr = buf.Flush() + return n +} + +// Write writes the given buffer to the underlying connection. +// +// If the protocol has not yet been negotiated, write waits for the write half +// of the handshake to complete triggers (but does not wait for) the read half. +// +// Write *also* ignores errors from the read half of the handshake (in case the +// stream is actually write only). +func (l *lazyClientConn) Write(b []byte) (int, error) { + n := 0 + l.whandshakeOnce.Do(func() { + go l.rhandshakeOnce.Do(l.doReadHandshake) + n = l.doWriteHandshakeWithData(b) + }) + if l.werr != nil || n > 0 { + return n, l.werr + } + return l.con.Write(b) +} + +// Close closes the underlying io.ReadWriteCloser +func (l *lazyClientConn) Close() error { + return l.con.Close() +} diff --git a/vendor/github.com/multiformats/go-multistream/lazyServer.go b/vendor/github.com/multiformats/go-multistream/lazyServer.go new file mode 100644 index 00000000..d7501fac --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/lazyServer.go @@ -0,0 +1,37 @@ +package multistream + +import ( + "io" + "sync" +) + +// lazyServerConn is an io.ReadWriteCloser adapter used for negotiating inbound +// streams (see NegotiateLazy). +// +// This is "lazy" because it doesn't wait for the write half to succeed before +// allowing us to read from the stream. +type lazyServerConn struct { + waitForHandshake sync.Once + werr error + + con io.ReadWriteCloser +} + +func (l *lazyServerConn) Write(b []byte) (int, error) { + l.waitForHandshake.Do(func() { panic("didn't initiate handshake") }) + if l.werr != nil { + return 0, l.werr + } + return l.con.Write(b) +} + +func (l *lazyServerConn) Read(b []byte) (int, error) { + if len(b) == 0 { + return 0, nil + } + return l.con.Read(b) +} + +func (l *lazyServerConn) Close() error { + return l.con.Close() +} diff --git a/vendor/github.com/multiformats/go-multistream/multistream-fuzz.zip b/vendor/github.com/multiformats/go-multistream/multistream-fuzz.zip new file mode 100644 index 00000000..c4158f48 Binary files /dev/null and b/vendor/github.com/multiformats/go-multistream/multistream-fuzz.zip differ diff --git a/vendor/github.com/multiformats/go-multistream/multistream.go b/vendor/github.com/multiformats/go-multistream/multistream.go new file mode 100644 index 00000000..86d6bc2f --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/multistream.go @@ -0,0 +1,464 @@ +// Package multistream implements a simple stream router for the +// multistream-select protocoli. The protocol is defined at +// https://github.com/multiformats/multistream-select +package multistream + +import ( + "bufio" + "bytes" + "encoding/binary" + "errors" + "io" + "sync" +) + +// ErrTooLarge is an error to signal that an incoming message was too large +var ErrTooLarge = errors.New("incoming message was too large") + +// ProtocolID identifies the multistream protocol itself and makes sure +// the multistream muxers on both sides of a channel can work with each other. +const ProtocolID = "/multistream/1.0.0" + +var writerPool = sync.Pool{ + New: func() interface{} { + return bufio.NewWriter(nil) + }, +} + +// HandlerFunc is a user-provided function used by the MultistreamMuxer to +// handle a protocol/stream. +type HandlerFunc = func(protocol string, rwc io.ReadWriteCloser) error + +// Handler is a wrapper to HandlerFunc which attaches a name (protocol) and a +// match function which can optionally be used to select a handler by other +// means than the name. +type Handler struct { + MatchFunc func(string) bool + Handle HandlerFunc + AddName string +} + +// MultistreamMuxer is a muxer for multistream. Depending on the stream +// protocol tag it will select the right handler and hand the stream off to it. +type MultistreamMuxer struct { + handlerlock sync.RWMutex + handlers []Handler +} + +// NewMultistreamMuxer creates a muxer. +func NewMultistreamMuxer() *MultistreamMuxer { + return new(MultistreamMuxer) +} + +func writeUvarint(w io.Writer, i uint64) error { + varintbuf := make([]byte, 16) + n := binary.PutUvarint(varintbuf, i) + _, err := w.Write(varintbuf[:n]) + if err != nil { + return err + } + return nil +} + +func delimWriteBuffered(w io.Writer, mes []byte) error { + bw := getWriter(w) + defer putWriter(bw) + + err := delimWrite(bw, mes) + if err != nil { + return err + } + + return bw.Flush() +} + +func delimWrite(w io.Writer, mes []byte) error { + err := writeUvarint(w, uint64(len(mes)+1)) + if err != nil { + return err + } + + _, err = w.Write(mes) + if err != nil { + return err + } + + _, err = w.Write([]byte{'\n'}) + if err != nil { + return err + } + return nil +} + +// Ls is a Multistream muxer command which returns the list of handler names +// available on a muxer. +func Ls(rw io.ReadWriter) ([]string, error) { + err := delimWriteBuffered(rw, []byte("ls")) + if err != nil { + return nil, err + } + + n, err := binary.ReadUvarint(&byteReader{rw}) + if err != nil { + return nil, err + } + + var out []string + for i := uint64(0); i < n; i++ { + val, err := lpReadBuf(rw) + if err != nil { + return nil, err + } + out = append(out, string(val)) + } + + return out, nil +} + +func fulltextMatch(s string) func(string) bool { + return func(a string) bool { + return a == s + } +} + +// AddHandler attaches a new protocol handler to the muxer. +func (msm *MultistreamMuxer) AddHandler(protocol string, handler HandlerFunc) { + msm.AddHandlerWithFunc(protocol, fulltextMatch(protocol), handler) +} + +// AddHandlerWithFunc attaches a new protocol handler to the muxer with a match. +// If the match function returns true for a given protocol tag, the protocol +// will be selected even if the handler name and protocol tags are different. +func (msm *MultistreamMuxer) AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc) { + msm.handlerlock.Lock() + defer msm.handlerlock.Unlock() + + msm.removeHandler(protocol) + msm.handlers = append(msm.handlers, Handler{ + MatchFunc: match, + Handle: handler, + AddName: protocol, + }) +} + +// RemoveHandler removes the handler with the given name from the muxer. +func (msm *MultistreamMuxer) RemoveHandler(protocol string) { + msm.handlerlock.Lock() + defer msm.handlerlock.Unlock() + + msm.removeHandler(protocol) +} + +func (msm *MultistreamMuxer) removeHandler(protocol string) { + for i, h := range msm.handlers { + if h.AddName == protocol { + msm.handlers = append(msm.handlers[:i], msm.handlers[i+1:]...) + return + } + } +} + +// Protocols returns the list of handler-names added to this this muxer. +func (msm *MultistreamMuxer) Protocols() []string { + msm.handlerlock.RLock() + defer msm.handlerlock.RUnlock() + + var out []string + for _, h := range msm.handlers { + out = append(out, h.AddName) + } + + return out +} + +// ErrIncorrectVersion is an error reported when the muxer protocol negotiation +// fails because of a ProtocolID mismatch. +var ErrIncorrectVersion = errors.New("client connected with incorrect version") + +func (msm *MultistreamMuxer) findHandler(proto string) *Handler { + msm.handlerlock.RLock() + defer msm.handlerlock.RUnlock() + + for _, h := range msm.handlers { + if h.MatchFunc(proto) { + return &h + } + } + + return nil +} + +// NegotiateLazy performs protocol selection and returns +// a multistream, the protocol used, the handler and an error. It is lazy +// because the write-handshake is performed on a subroutine, allowing this +// to return before that handshake is completed. +func (msm *MultistreamMuxer) NegotiateLazy(rwc io.ReadWriteCloser) (io.ReadWriteCloser, string, HandlerFunc, error) { + pval := make(chan string, 1) + writeErr := make(chan error, 1) + defer close(pval) + + lzc := &lazyServerConn{ + con: rwc, + } + + started := make(chan struct{}) + go lzc.waitForHandshake.Do(func() { + close(started) + + defer close(writeErr) + + if err := delimWriteBuffered(rwc, []byte(ProtocolID)); err != nil { + lzc.werr = err + writeErr <- err + return + } + + for proto := range pval { + if err := delimWriteBuffered(rwc, []byte(proto)); err != nil { + lzc.werr = err + writeErr <- err + return + } + } + }) + <-started + + line, err := ReadNextToken(rwc) + if err != nil { + return nil, "", nil, err + } + + if line != ProtocolID { + rwc.Close() + return nil, "", nil, ErrIncorrectVersion + } + +loop: + for { + // Now read and respond to commands until they send a valid protocol id + tok, err := ReadNextToken(rwc) + if err != nil { + rwc.Close() + return nil, "", nil, err + } + + switch tok { + case "ls": + select { + case pval <- "ls": + case err := <-writeErr: + rwc.Close() + return nil, "", nil, err + } + default: + h := msm.findHandler(tok) + if h == nil { + select { + case pval <- "na": + case err := <-writeErr: + rwc.Close() + return nil, "", nil, err + } + continue loop + } + + select { + case pval <- tok: + case <-writeErr: + // explicitly ignore this error. It will be returned to any + // writers and if we don't plan on writing anything, we still + // want to complete the handshake + } + + // hand off processing to the sub-protocol handler + return lzc, tok, h.Handle, nil + } + } +} + +// Negotiate performs protocol selection and returns the protocol name and +// the matching handler function for it (or an error). +func (msm *MultistreamMuxer) Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error) { + // Send our protocol ID + err := delimWriteBuffered(rwc, []byte(ProtocolID)) + if err != nil { + return "", nil, err + } + + line, err := ReadNextToken(rwc) + if err != nil { + return "", nil, err + } + + if line != ProtocolID { + rwc.Close() + return "", nil, ErrIncorrectVersion + } + +loop: + for { + // Now read and respond to commands until they send a valid protocol id + tok, err := ReadNextToken(rwc) + if err != nil { + return "", nil, err + } + + switch tok { + case "ls": + err := msm.Ls(rwc) + if err != nil { + return "", nil, err + } + default: + h := msm.findHandler(tok) + if h == nil { + err := delimWriteBuffered(rwc, []byte("na")) + if err != nil { + return "", nil, err + } + continue loop + } + + err := delimWriteBuffered(rwc, []byte(tok)) + if err != nil { + return "", nil, err + } + + // hand off processing to the sub-protocol handler + return tok, h.Handle, nil + } + } + +} + +// Ls implements the "ls" command which writes the list of +// supported protocols to the given Writer. +func (msm *MultistreamMuxer) Ls(w io.Writer) error { + buf := new(bytes.Buffer) + + msm.handlerlock.RLock() + err := writeUvarint(buf, uint64(len(msm.handlers))) + if err != nil { + return err + } + + for _, h := range msm.handlers { + err := delimWrite(buf, []byte(h.AddName)) + if err != nil { + msm.handlerlock.RUnlock() + return err + } + } + msm.handlerlock.RUnlock() + + ll := make([]byte, 16) + nw := binary.PutUvarint(ll, uint64(buf.Len())) + + r := io.MultiReader(bytes.NewReader(ll[:nw]), buf) + + _, err = io.Copy(w, r) + return err +} + +// Handle performs protocol negotiation on a ReadWriteCloser +// (i.e. a connection). It will find a matching handler for the +// incoming protocol and pass the ReadWriteCloser to it. +func (msm *MultistreamMuxer) Handle(rwc io.ReadWriteCloser) error { + p, h, err := msm.Negotiate(rwc) + if err != nil { + return err + } + return h(p, rwc) +} + +// ReadNextToken extracts a token from a ReadWriter. It is used during +// protocol negotiation and returns a string. +func ReadNextToken(rw io.ReadWriter) (string, error) { + tok, err := ReadNextTokenBytes(rw) + if err != nil { + return "", err + } + + return string(tok), nil +} + +// ReadNextTokenBytes extracts a token from a ReadWriter. It is used +// during protocol negotiation and returns a byte slice. +func ReadNextTokenBytes(rw io.ReadWriter) ([]byte, error) { + data, err := lpReadBuf(rw) + switch err { + case nil: + return data, nil + case ErrTooLarge: + err := delimWriteBuffered(rw, []byte("messages over 64k are not allowed")) + if err != nil { + return nil, err + } + return nil, ErrTooLarge + default: + return nil, err + } +} + +func lpReadBuf(r io.Reader) ([]byte, error) { + br, ok := r.(io.ByteReader) + if !ok { + br = &byteReader{r} + } + + length, err := binary.ReadUvarint(br) + if err != nil { + return nil, err + } + + if length > 64*1024 { + return nil, ErrTooLarge + } + + buf := make([]byte, length) + _, err = io.ReadFull(r, buf) + if err != nil { + return nil, err + } + + if len(buf) == 0 || buf[length-1] != '\n' { + return nil, errors.New("message did not have trailing newline") + } + + // slice off the trailing newline + buf = buf[:length-1] + + return buf, nil + +} + +// byteReader implements the ByteReader interface that ReadUVarint requires +type byteReader struct { + io.Reader +} + +func (br *byteReader) ReadByte() (byte, error) { + var b [1]byte + n, err := br.Read(b[:]) + if n == 1 { + return b[0], nil + } + if err == nil { + if n != 0 { + panic("read more bytes than buffer size") + } + err = io.ErrNoProgress + } + return 0, err +} + +func getWriter(w io.Writer) *bufio.Writer { + bw := writerPool.Get().(*bufio.Writer) + bw.Reset(w) + return bw +} + +func putWriter(bw *bufio.Writer) { + bw.Reset(nil) + writerPool.Put(bw) +} diff --git a/vendor/github.com/multiformats/go-multistream/multistream_fuzz.go b/vendor/github.com/multiformats/go-multistream/multistream_fuzz.go new file mode 100644 index 00000000..602bbb58 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/multistream_fuzz.go @@ -0,0 +1,28 @@ +// +build gofuzz + +package multistream + +import "bytes" + +type rwc struct { + *bytes.Reader +} + +func (*rwc) Write(b []byte) (int, error) { + return len(b), nil +} + +func (*rwc) Close() error { + return nil +} + +func Fuzz(b []byte) int { + readStream := bytes.NewReader(b) + input := &rwc{readStream} + + mux := NewMultistreamMuxer() + mux.AddHandler("/a", nil) + mux.AddHandler("/b", nil) + _ = mux.Handle(input) + return 1 +} diff --git a/vendor/github.com/multiformats/go-multistream/package.json b/vendor/github.com/multiformats/go-multistream/package.json new file mode 100644 index 00000000..c5001ef4 --- /dev/null +++ b/vendor/github.com/multiformats/go-multistream/package.json @@ -0,0 +1,16 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/multiformats/go-multistream" + }, + "gx": { + "dvcsimport": "github.com/multiformats/go-multistream" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "", + "name": "go-multistream", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.3.9" +} + diff --git a/vendor/github.com/olekukonko/tablewriter/.gitignore b/vendor/github.com/olekukonko/tablewriter/.gitignore new file mode 100644 index 00000000..b66cec63 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/.gitignore @@ -0,0 +1,15 @@ +# Created by .ignore support plugin (hsz.mobi) +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + diff --git a/vendor/github.com/olekukonko/tablewriter/.travis.yml b/vendor/github.com/olekukonko/tablewriter/.travis.yml new file mode 100644 index 00000000..9c64270e --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - 1.7 + - 1.8 + - 1.9 + - "1.10" + - tip diff --git a/vendor/github.com/olekukonko/tablewriter/LICENSE.md b/vendor/github.com/olekukonko/tablewriter/LICENSE.md new file mode 100644 index 00000000..a0769b5c --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 by Oleku Konko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/olekukonko/tablewriter/README.md b/vendor/github.com/olekukonko/tablewriter/README.md new file mode 100644 index 00000000..9c2b139b --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/README.md @@ -0,0 +1,277 @@ +ASCII Table Writer +========= + +[![Build Status](https://travis-ci.org/olekukonko/tablewriter.png?branch=master)](https://travis-ci.org/olekukonko/tablewriter) +[![Total views](https://img.shields.io/sourcegraph/rrc/github.com/olekukonko/tablewriter.svg)](https://sourcegraph.com/github.com/olekukonko/tablewriter) +[![Godoc](https://godoc.org/github.com/olekukonko/tablewriter?status.svg)](https://godoc.org/github.com/olekukonko/tablewriter) + +Generate ASCII table on the fly ... Installation is simple as + + go get github.com/olekukonko/tablewriter + + +#### Features +- Automatic Padding +- Support Multiple Lines +- Supports Alignment +- Support Custom Separators +- Automatic Alignment of numbers & percentage +- Write directly to http , file etc via `io.Writer` +- Read directly from CSV file +- Optional row line via `SetRowLine` +- Normalise table header +- Make CSV Headers optional +- Enable or disable table border +- Set custom footer support +- Optional identical cells merging +- Set custom caption +- Optional reflowing of paragrpahs in multi-line cells. + +#### Example 1 - Basic +```go +data := [][]string{ + []string{"A", "The Good", "500"}, + []string{"B", "The Very very Bad Man", "288"}, + []string{"C", "The Ugly", "120"}, + []string{"D", "The Gopher", "800"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Name", "Sign", "Rating"}) + +for _, v := range data { + table.Append(v) +} +table.Render() // Send output +``` + +##### Output 1 +``` ++------+-----------------------+--------+ +| NAME | SIGN | RATING | ++------+-----------------------+--------+ +| A | The Good | 500 | +| B | The Very very Bad Man | 288 | +| C | The Ugly | 120 | +| D | The Gopher | 800 | ++------+-----------------------+--------+ +``` + +#### Example 2 - Without Border / Footer / Bulk Append +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer +table.SetBorder(false) // Set Border to false +table.AppendBulk(data) // Add Bulk Data +table.Render() +``` + +##### Output 2 +``` + + DATE | DESCRIPTION | CV2 | AMOUNT ++----------+--------------------------+-------+---------+ + 1/1/2014 | Domain name | 2233 | $10.98 + 1/1/2014 | January Hosting | 2233 | $54.95 + 1/4/2014 | February Hosting | 2233 | $51.00 + 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 ++----------+--------------------------+-------+---------+ + TOTAL | $146 93 + +-------+---------+ + +``` + + +#### Example 3 - CSV +```go +table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test_info.csv", true) +table.SetAlignment(tablewriter.ALIGN_LEFT) // Set Alignment +table.Render() +``` + +##### Output 3 +``` ++----------+--------------+------+-----+---------+----------------+ +| FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA | ++----------+--------------+------+-----+---------+----------------+ +| user_id | smallint(5) | NO | PRI | NULL | auto_increment | +| username | varchar(10) | NO | | NULL | | +| password | varchar(100) | NO | | NULL | | ++----------+--------------+------+-----+---------+----------------+ +``` + +#### Example 4 - Custom Separator +```go +table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test.csv", true) +table.SetRowLine(true) // Enable row line + +// Change table lines +table.SetCenterSeparator("*") +table.SetColumnSeparator("╪") +table.SetRowSeparator("-") + +table.SetAlignment(tablewriter.ALIGN_LEFT) +table.Render() +``` + +##### Output 4 +``` +*------------*-----------*---------* +╪ FIRST NAME ╪ LAST NAME ╪ SSN ╪ +*------------*-----------*---------* +╪ John ╪ Barry ╪ 123456 ╪ +*------------*-----------*---------* +╪ Kathy ╪ Smith ╪ 687987 ╪ +*------------*-----------*---------* +╪ Bob ╪ McCornick ╪ 3979870 ╪ +*------------*-----------*---------* +``` + +#### Example 5 - Markdown Format +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) +table.SetCenterSeparator("|") +table.AppendBulk(data) // Add Bulk Data +table.Render() +``` + +##### Output 5 +``` +| DATE | DESCRIPTION | CV2 | AMOUNT | +|----------|--------------------------|------|--------| +| 1/1/2014 | Domain name | 2233 | $10.98 | +| 1/1/2014 | January Hosting | 2233 | $54.95 | +| 1/4/2014 | February Hosting | 2233 | $51.00 | +| 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 | +``` + +#### Example 6 - Identical cells merging +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "1234", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2345", "$54.95"}, + []string{"1/4/2014", "February Hosting", "3456", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "4567", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) +table.SetAutoMergeCells(true) +table.SetRowLine(true) +table.AppendBulk(data) +table.Render() +``` + +##### Output 6 +``` ++----------+--------------------------+-------+---------+ +| DATE | DESCRIPTION | CV2 | AMOUNT | ++----------+--------------------------+-------+---------+ +| 1/1/2014 | Domain name | 1234 | $10.98 | ++ +--------------------------+-------+---------+ +| | January Hosting | 2345 | $54.95 | ++----------+--------------------------+-------+---------+ +| 1/4/2014 | February Hosting | 3456 | $51.00 | ++ +--------------------------+-------+---------+ +| | February Extra Bandwidth | 4567 | $30.00 | ++----------+--------------------------+-------+---------+ +| TOTAL | $146 93 | ++----------+--------------------------+-------+---------+ +``` + + +#### Table with color +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer +table.SetBorder(false) // Set Border to false + +table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor}, + tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor}, + tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor}, + tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor}) + +table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor}) + +table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{}, + tablewriter.Colors{tablewriter.Bold}, + tablewriter.Colors{tablewriter.FgHiRedColor}) + +table.AppendBulk(data) +table.Render() +``` + +#### Table with color Output +![Table with Color](https://cloud.githubusercontent.com/assets/6460392/21101956/bbc7b356-c0a1-11e6-9f36-dba694746efc.png) + +#### Example 6 - Set table caption +```go +data := [][]string{ + []string{"A", "The Good", "500"}, + []string{"B", "The Very very Bad Man", "288"}, + []string{"C", "The Ugly", "120"}, + []string{"D", "The Gopher", "800"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Name", "Sign", "Rating"}) +table.SetCaption(true, "Movie ratings.") + +for _, v := range data { + table.Append(v) +} +table.Render() // Send output +``` + +Note: Caption text will wrap with total width of rendered table. + +##### Output 6 +``` ++------+-----------------------+--------+ +| NAME | SIGN | RATING | ++------+-----------------------+--------+ +| A | The Good | 500 | +| B | The Very very Bad Man | 288 | +| C | The Ugly | 120 | +| D | The Gopher | 800 | ++------+-----------------------+--------+ +Movie ratings. +``` + +#### TODO +- ~~Import Directly from CSV~~ - `done` +- ~~Support for `SetFooter`~~ - `done` +- ~~Support for `SetBorder`~~ - `done` +- ~~Support table with uneven rows~~ - `done` +- ~~Support custom alignment~~ +- General Improvement & Optimisation +- `NewHTML` Parse table from HTML diff --git a/vendor/github.com/olekukonko/tablewriter/csv.go b/vendor/github.com/olekukonko/tablewriter/csv.go new file mode 100644 index 00000000..98878303 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/csv.go @@ -0,0 +1,52 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "encoding/csv" + "io" + "os" +) + +// Start A new table by importing from a CSV file +// Takes io.Writer and csv File name +func NewCSV(writer io.Writer, fileName string, hasHeader bool) (*Table, error) { + file, err := os.Open(fileName) + if err != nil { + return &Table{}, err + } + defer file.Close() + csvReader := csv.NewReader(file) + t, err := NewCSVReader(writer, csvReader, hasHeader) + return t, err +} + +// Start a New Table Writer with csv.Reader +// This enables customisation such as reader.Comma = ';' +// See http://golang.org/src/pkg/encoding/csv/reader.go?s=3213:3671#L94 +func NewCSVReader(writer io.Writer, csvReader *csv.Reader, hasHeader bool) (*Table, error) { + t := NewWriter(writer) + if hasHeader { + // Read the first row + headers, err := csvReader.Read() + if err != nil { + return &Table{}, err + } + t.SetHeader(headers) + } + for { + record, err := csvReader.Read() + if err == io.EOF { + break + } else if err != nil { + return &Table{}, err + } + t.Append(record) + } + return t, nil +} diff --git a/vendor/github.com/olekukonko/tablewriter/table.go b/vendor/github.com/olekukonko/tablewriter/table.go new file mode 100644 index 00000000..dec0385f --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/table.go @@ -0,0 +1,839 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +// Create & Generate text based table +package tablewriter + +import ( + "bytes" + "fmt" + "io" + "regexp" + "strings" +) + +const ( + MAX_ROW_WIDTH = 30 +) + +const ( + CENTER = "+" + ROW = "-" + COLUMN = "|" + SPACE = " " + NEWLINE = "\n" +) + +const ( + ALIGN_DEFAULT = iota + ALIGN_CENTER + ALIGN_RIGHT + ALIGN_LEFT +) + +var ( + decimal = regexp.MustCompile(`^-?(?:\d{1,3}(?:,\d{3})*|\d+)(?:\.\d+)?$`) + percent = regexp.MustCompile(`^-?\d+\.?\d*$%$`) +) + +type Border struct { + Left bool + Right bool + Top bool + Bottom bool +} + +type Table struct { + out io.Writer + rows [][]string + lines [][][]string + cs map[int]int + rs map[int]int + headers [][]string + footers [][]string + caption bool + captionText string + autoFmt bool + autoWrap bool + reflowText bool + mW int + pCenter string + pRow string + pColumn string + tColumn int + tRow int + hAlign int + fAlign int + align int + newLine string + rowLine bool + autoMergeCells bool + hdrLine bool + borders Border + colSize int + headerParams []string + columnsParams []string + footerParams []string + columnsAlign []int +} + +// Start New Table +// Take io.Writer Directly +func NewWriter(writer io.Writer) *Table { + t := &Table{ + out: writer, + rows: [][]string{}, + lines: [][][]string{}, + cs: make(map[int]int), + rs: make(map[int]int), + headers: [][]string{}, + footers: [][]string{}, + caption: false, + captionText: "Table caption.", + autoFmt: true, + autoWrap: true, + reflowText: true, + mW: MAX_ROW_WIDTH, + pCenter: CENTER, + pRow: ROW, + pColumn: COLUMN, + tColumn: -1, + tRow: -1, + hAlign: ALIGN_DEFAULT, + fAlign: ALIGN_DEFAULT, + align: ALIGN_DEFAULT, + newLine: NEWLINE, + rowLine: false, + hdrLine: true, + borders: Border{Left: true, Right: true, Bottom: true, Top: true}, + colSize: -1, + headerParams: []string{}, + columnsParams: []string{}, + footerParams: []string{}, + columnsAlign: []int{}} + return t +} + +// Render table output +func (t *Table) Render() { + if t.borders.Top { + t.printLine(true) + } + t.printHeading() + if t.autoMergeCells { + t.printRowsMergeCells() + } else { + t.printRows() + } + if !t.rowLine && t.borders.Bottom { + t.printLine(true) + } + t.printFooter() + + if t.caption { + t.printCaption() + } +} + +const ( + headerRowIdx = -1 + footerRowIdx = -2 +) + +// Set table header +func (t *Table) SetHeader(keys []string) { + t.colSize = len(keys) + for i, v := range keys { + lines := t.parseDimension(v, i, headerRowIdx) + t.headers = append(t.headers, lines) + } +} + +// Set table Footer +func (t *Table) SetFooter(keys []string) { + //t.colSize = len(keys) + for i, v := range keys { + lines := t.parseDimension(v, i, footerRowIdx) + t.footers = append(t.footers, lines) + } +} + +// Set table Caption +func (t *Table) SetCaption(caption bool, captionText ...string) { + t.caption = caption + if len(captionText) == 1 { + t.captionText = captionText[0] + } +} + +// Turn header autoformatting on/off. Default is on (true). +func (t *Table) SetAutoFormatHeaders(auto bool) { + t.autoFmt = auto +} + +// Turn automatic multiline text adjustment on/off. Default is on (true). +func (t *Table) SetAutoWrapText(auto bool) { + t.autoWrap = auto +} + +// Turn automatic reflowing of multiline text when rewrapping. Default is on (true). +func (t *Table) SetReflowDuringAutoWrap(auto bool) { + t.reflowText = auto +} + +// Set the Default column width +func (t *Table) SetColWidth(width int) { + t.mW = width +} + +// Set the minimal width for a column +func (t *Table) SetColMinWidth(column int, width int) { + t.cs[column] = width +} + +// Set the Column Separator +func (t *Table) SetColumnSeparator(sep string) { + t.pColumn = sep +} + +// Set the Row Separator +func (t *Table) SetRowSeparator(sep string) { + t.pRow = sep +} + +// Set the center Separator +func (t *Table) SetCenterSeparator(sep string) { + t.pCenter = sep +} + +// Set Header Alignment +func (t *Table) SetHeaderAlignment(hAlign int) { + t.hAlign = hAlign +} + +// Set Footer Alignment +func (t *Table) SetFooterAlignment(fAlign int) { + t.fAlign = fAlign +} + +// Set Table Alignment +func (t *Table) SetAlignment(align int) { + t.align = align +} + +func (t *Table) SetColumnAlignment(keys []int) { + for _, v := range keys { + switch v { + case ALIGN_CENTER: + break + case ALIGN_LEFT: + break + case ALIGN_RIGHT: + break + default: + v = ALIGN_DEFAULT + } + t.columnsAlign = append(t.columnsAlign, v) + } +} + +// Set New Line +func (t *Table) SetNewLine(nl string) { + t.newLine = nl +} + +// Set Header Line +// This would enable / disable a line after the header +func (t *Table) SetHeaderLine(line bool) { + t.hdrLine = line +} + +// Set Row Line +// This would enable / disable a line on each row of the table +func (t *Table) SetRowLine(line bool) { + t.rowLine = line +} + +// Set Auto Merge Cells +// This would enable / disable the merge of cells with identical values +func (t *Table) SetAutoMergeCells(auto bool) { + t.autoMergeCells = auto +} + +// Set Table Border +// This would enable / disable line around the table +func (t *Table) SetBorder(border bool) { + t.SetBorders(Border{border, border, border, border}) +} + +func (t *Table) SetBorders(border Border) { + t.borders = border +} + +// Append row to table +func (t *Table) Append(row []string) { + rowSize := len(t.headers) + if rowSize > t.colSize { + t.colSize = rowSize + } + + n := len(t.lines) + line := [][]string{} + for i, v := range row { + + // Detect string width + // Detect String height + // Break strings into words + out := t.parseDimension(v, i, n) + + // Append broken words + line = append(line, out) + } + t.lines = append(t.lines, line) +} + +// Allow Support for Bulk Append +// Eliminates repeated for loops +func (t *Table) AppendBulk(rows [][]string) { + for _, row := range rows { + t.Append(row) + } +} + +// NumLines to get the number of lines +func (t *Table) NumLines() int { + return len(t.lines) +} + +// Clear rows +func (t *Table) ClearRows() { + t.lines = [][][]string{} +} + +// Clear footer +func (t *Table) ClearFooter() { + t.footers = [][]string{} +} + +// Print line based on row width +func (t *Table) printLine(nl bool) { + fmt.Fprint(t.out, t.pCenter) + for i := 0; i < len(t.cs); i++ { + v := t.cs[i] + fmt.Fprintf(t.out, "%s%s%s%s", + t.pRow, + strings.Repeat(string(t.pRow), v), + t.pRow, + t.pCenter) + } + if nl { + fmt.Fprint(t.out, t.newLine) + } +} + +// Print line based on row width with our without cell separator +func (t *Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) { + fmt.Fprint(t.out, t.pCenter) + for i := 0; i < len(t.cs); i++ { + v := t.cs[i] + if i > len(displayCellSeparator) || displayCellSeparator[i] { + // Display the cell separator + fmt.Fprintf(t.out, "%s%s%s%s", + t.pRow, + strings.Repeat(string(t.pRow), v), + t.pRow, + t.pCenter) + } else { + // Don't display the cell separator for this cell + fmt.Fprintf(t.out, "%s%s", + strings.Repeat(" ", v+2), + t.pCenter) + } + } + if nl { + fmt.Fprint(t.out, t.newLine) + } +} + +// Return the PadRight function if align is left, PadLeft if align is right, +// and Pad by default +func pad(align int) func(string, string, int) string { + padFunc := Pad + switch align { + case ALIGN_LEFT: + padFunc = PadRight + case ALIGN_RIGHT: + padFunc = PadLeft + } + return padFunc +} + +// Print heading information +func (t *Table) printHeading() { + // Check if headers is available + if len(t.headers) < 1 { + return + } + + // Identify last column + end := len(t.cs) - 1 + + // Get pad function + padFunc := pad(t.hAlign) + + // Checking for ANSI escape sequences for header + is_esc_seq := false + if len(t.headerParams) > 0 { + is_esc_seq = true + } + + // Maximum height. + max := t.rs[headerRowIdx] + + // Print Heading + for x := 0; x < max; x++ { + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) + + for y := 0; y <= end; y++ { + v := t.cs[y] + h := "" + if y < len(t.headers) && x < len(t.headers[y]) { + h = t.headers[y][x] + } + if t.autoFmt { + h = Title(h) + } + pad := ConditionString((y == end && !t.borders.Left), SPACE, t.pColumn) + + if is_esc_seq { + fmt.Fprintf(t.out, " %s %s", + format(padFunc(h, SPACE, v), + t.headerParams[y]), pad) + } else { + fmt.Fprintf(t.out, " %s %s", + padFunc(h, SPACE, v), + pad) + } + } + // Next line + fmt.Fprint(t.out, t.newLine) + } + if t.hdrLine { + t.printLine(true) + } +} + +// Print heading information +func (t *Table) printFooter() { + // Check if headers is available + if len(t.footers) < 1 { + return + } + + // Only print line if border is not set + if !t.borders.Bottom { + t.printLine(true) + } + + // Identify last column + end := len(t.cs) - 1 + + // Get pad function + padFunc := pad(t.fAlign) + + // Checking for ANSI escape sequences for header + is_esc_seq := false + if len(t.footerParams) > 0 { + is_esc_seq = true + } + + // Maximum height. + max := t.rs[footerRowIdx] + + // Print Footer + erasePad := make([]bool, len(t.footers)) + for x := 0; x < max; x++ { + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE)) + + for y := 0; y <= end; y++ { + v := t.cs[y] + f := "" + if y < len(t.footers) && x < len(t.footers[y]) { + f = t.footers[y][x] + } + if t.autoFmt { + f = Title(f) + } + pad := ConditionString((y == end && !t.borders.Top), SPACE, t.pColumn) + + if erasePad[y] || (x == 0 && len(f) == 0) { + pad = SPACE + erasePad[y] = true + } + + if is_esc_seq { + fmt.Fprintf(t.out, " %s %s", + format(padFunc(f, SPACE, v), + t.footerParams[y]), pad) + } else { + fmt.Fprintf(t.out, " %s %s", + padFunc(f, SPACE, v), + pad) + } + + //fmt.Fprintf(t.out, " %s %s", + // padFunc(f, SPACE, v), + // pad) + } + // Next line + fmt.Fprint(t.out, t.newLine) + //t.printLine(true) + } + + hasPrinted := false + + for i := 0; i <= end; i++ { + v := t.cs[i] + pad := t.pRow + center := t.pCenter + length := len(t.footers[i][0]) + + if length > 0 { + hasPrinted = true + } + + // Set center to be space if length is 0 + if length == 0 && !t.borders.Right { + center = SPACE + } + + // Print first junction + if i == 0 { + fmt.Fprint(t.out, center) + } + + // Pad With space of length is 0 + if length == 0 { + pad = SPACE + } + // Ignore left space of it has printed before + if hasPrinted || t.borders.Left { + pad = t.pRow + center = t.pCenter + } + + // Change Center start position + if center == SPACE { + if i < end && len(t.footers[i+1][0]) != 0 { + center = t.pCenter + } + } + + // Print the footer + fmt.Fprintf(t.out, "%s%s%s%s", + pad, + strings.Repeat(string(pad), v), + pad, + center) + + } + + fmt.Fprint(t.out, t.newLine) +} + +// Print caption text +func (t Table) printCaption() { + width := t.getTableWidth() + paragraph, _ := WrapString(t.captionText, width) + for linecount := 0; linecount < len(paragraph); linecount++ { + fmt.Fprintln(t.out, paragraph[linecount]) + } +} + +// Calculate the total number of characters in a row +func (t Table) getTableWidth() int { + var chars int + for _, v := range t.cs { + chars += v + } + + // Add chars, spaces, seperators to calculate the total width of the table. + // ncols := t.colSize + // spaces := ncols * 2 + // seps := ncols + 1 + + return (chars + (3 * t.colSize) + 2) +} + +func (t Table) printRows() { + for i, lines := range t.lines { + t.printRow(lines, i) + } +} + +func (t *Table) fillAlignment(num int) { + if len(t.columnsAlign) < num { + t.columnsAlign = make([]int, num) + for i := range t.columnsAlign { + t.columnsAlign[i] = t.align + } + } +} + +// Print Row Information +// Adjust column alignment based on type + +func (t *Table) printRow(columns [][]string, rowIdx int) { + // Get Maximum Height + max := t.rs[rowIdx] + total := len(columns) + + // TODO Fix uneven col size + // if total < t.colSize { + // for n := t.colSize - total; n < t.colSize ; n++ { + // columns = append(columns, []string{SPACE}) + // t.cs[n] = t.mW + // } + //} + + // Pad Each Height + pads := []int{} + + // Checking for ANSI escape sequences for columns + is_esc_seq := false + if len(t.columnsParams) > 0 { + is_esc_seq = true + } + t.fillAlignment(total) + + for i, line := range columns { + length := len(line) + pad := max - length + pads = append(pads, pad) + for n := 0; n < pad; n++ { + columns[i] = append(columns[i], " ") + } + } + //fmt.Println(max, "\n") + for x := 0; x < max; x++ { + for y := 0; y < total; y++ { + + // Check if border is set + fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) + + fmt.Fprintf(t.out, SPACE) + str := columns[y][x] + + // Embedding escape sequence with column value + if is_esc_seq { + str = format(str, t.columnsParams[y]) + } + + // This would print alignment + // Default alignment would use multiple configuration + switch t.columnsAlign[y] { + case ALIGN_CENTER: // + fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y])) + case ALIGN_RIGHT: + fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y])) + case ALIGN_LEFT: + fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + default: + if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) { + fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y])) + } else { + fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + + // TODO Custom alignment per column + //if max == 1 || pads[y] > 0 { + // fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y])) + //} else { + // fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + //} + + } + } + fmt.Fprintf(t.out, SPACE) + } + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) + fmt.Fprint(t.out, t.newLine) + } + + if t.rowLine { + t.printLine(true) + } +} + +// Print the rows of the table and merge the cells that are identical +func (t *Table) printRowsMergeCells() { + var previousLine []string + var displayCellBorder []bool + var tmpWriter bytes.Buffer + for i, lines := range t.lines { + // We store the display of the current line in a tmp writer, as we need to know which border needs to be print above + previousLine, displayCellBorder = t.printRowMergeCells(&tmpWriter, lines, i, previousLine) + if i > 0 { //We don't need to print borders above first line + if t.rowLine { + t.printLineOptionalCellSeparators(true, displayCellBorder) + } + } + tmpWriter.WriteTo(t.out) + } + //Print the end of the table + if t.rowLine { + t.printLine(true) + } +} + +// Print Row Information to a writer and merge identical cells. +// Adjust column alignment based on type + +func (t *Table) printRowMergeCells(writer io.Writer, columns [][]string, rowIdx int, previousLine []string) ([]string, []bool) { + // Get Maximum Height + max := t.rs[rowIdx] + total := len(columns) + + // Pad Each Height + pads := []int{} + + for i, line := range columns { + length := len(line) + pad := max - length + pads = append(pads, pad) + for n := 0; n < pad; n++ { + columns[i] = append(columns[i], " ") + } + } + + var displayCellBorder []bool + t.fillAlignment(total) + for x := 0; x < max; x++ { + for y := 0; y < total; y++ { + + // Check if border is set + fmt.Fprint(writer, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) + + fmt.Fprintf(writer, SPACE) + + str := columns[y][x] + + if t.autoMergeCells { + //Store the full line to merge mutli-lines cells + fullLine := strings.Join(columns[y], " ") + if len(previousLine) > y && fullLine == previousLine[y] && fullLine != "" { + // If this cell is identical to the one above but not empty, we don't display the border and keep the cell empty. + displayCellBorder = append(displayCellBorder, false) + str = "" + } else { + // First line or different content, keep the content and print the cell border + displayCellBorder = append(displayCellBorder, true) + } + } + + // This would print alignment + // Default alignment would use multiple configuration + switch t.columnsAlign[y] { + case ALIGN_CENTER: // + fmt.Fprintf(writer, "%s", Pad(str, SPACE, t.cs[y])) + case ALIGN_RIGHT: + fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) + case ALIGN_LEFT: + fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) + default: + if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) { + fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) + } else { + fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) + } + } + fmt.Fprintf(writer, SPACE) + } + // Check if border is set + // Replace with space if not set + fmt.Fprint(writer, ConditionString(t.borders.Left, t.pColumn, SPACE)) + fmt.Fprint(writer, t.newLine) + } + + //The new previous line is the current one + previousLine = make([]string, total) + for y := 0; y < total; y++ { + previousLine[y] = strings.Join(columns[y], " ") //Store the full line for multi-lines cells + } + //Returns the newly added line and wether or not a border should be displayed above. + return previousLine, displayCellBorder +} + +func (t *Table) parseDimension(str string, colKey, rowKey int) []string { + var ( + raw []string + maxWidth int + ) + + raw = getLines(str) + maxWidth = 0 + for _, line := range raw { + if w := DisplayWidth(line); w > maxWidth { + maxWidth = w + } + } + + // If wrapping, ensure that all paragraphs in the cell fit in the + // specified width. + if t.autoWrap { + // If there's a maximum allowed width for wrapping, use that. + if maxWidth > t.mW { + maxWidth = t.mW + } + + // In the process of doing so, we need to recompute maxWidth. This + // is because perhaps a word in the cell is longer than the + // allowed maximum width in t.mW. + newMaxWidth := maxWidth + newRaw := make([]string, 0, len(raw)) + + if t.reflowText { + // Make a single paragraph of everything. + raw = []string{strings.Join(raw, " ")} + } + for i, para := range raw { + paraLines, _ := WrapString(para, maxWidth) + for _, line := range paraLines { + if w := DisplayWidth(line); w > newMaxWidth { + newMaxWidth = w + } + } + if i > 0 { + newRaw = append(newRaw, " ") + } + newRaw = append(newRaw, paraLines...) + } + raw = newRaw + maxWidth = newMaxWidth + } + + // Store the new known maximum width. + v, ok := t.cs[colKey] + if !ok || v < maxWidth || v == 0 { + t.cs[colKey] = maxWidth + } + + // Remember the number of lines for the row printer. + h := len(raw) + v, ok = t.rs[rowKey] + + if !ok || v < h || v == 0 { + t.rs[rowKey] = h + } + //fmt.Printf("Raw %+v %d\n", raw, len(raw)) + return raw +} diff --git a/vendor/github.com/olekukonko/tablewriter/table_with_color.go b/vendor/github.com/olekukonko/tablewriter/table_with_color.go new file mode 100644 index 00000000..5a4a53ec --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/table_with_color.go @@ -0,0 +1,134 @@ +package tablewriter + +import ( + "fmt" + "strconv" + "strings" +) + +const ESC = "\033" +const SEP = ";" + +const ( + BgBlackColor int = iota + 40 + BgRedColor + BgGreenColor + BgYellowColor + BgBlueColor + BgMagentaColor + BgCyanColor + BgWhiteColor +) + +const ( + FgBlackColor int = iota + 30 + FgRedColor + FgGreenColor + FgYellowColor + FgBlueColor + FgMagentaColor + FgCyanColor + FgWhiteColor +) + +const ( + BgHiBlackColor int = iota + 100 + BgHiRedColor + BgHiGreenColor + BgHiYellowColor + BgHiBlueColor + BgHiMagentaColor + BgHiCyanColor + BgHiWhiteColor +) + +const ( + FgHiBlackColor int = iota + 90 + FgHiRedColor + FgHiGreenColor + FgHiYellowColor + FgHiBlueColor + FgHiMagentaColor + FgHiCyanColor + FgHiWhiteColor +) + +const ( + Normal = 0 + Bold = 1 + UnderlineSingle = 4 + Italic +) + +type Colors []int + +func startFormat(seq string) string { + return fmt.Sprintf("%s[%sm", ESC, seq) +} + +func stopFormat() string { + return fmt.Sprintf("%s[%dm", ESC, Normal) +} + +// Making the SGR (Select Graphic Rendition) sequence. +func makeSequence(codes []int) string { + codesInString := []string{} + for _, code := range codes { + codesInString = append(codesInString, strconv.Itoa(code)) + } + return strings.Join(codesInString, SEP) +} + +// Adding ANSI escape sequences before and after string +func format(s string, codes interface{}) string { + var seq string + + switch v := codes.(type) { + + case string: + seq = v + case []int: + seq = makeSequence(v) + default: + return s + } + + if len(seq) == 0 { + return s + } + return startFormat(seq) + s + stopFormat() +} + +// Adding header colors (ANSI codes) +func (t *Table) SetHeaderColor(colors ...Colors) { + if t.colSize != len(colors) { + panic("Number of header colors must be equal to number of headers.") + } + for i := 0; i < len(colors); i++ { + t.headerParams = append(t.headerParams, makeSequence(colors[i])) + } +} + +// Adding column colors (ANSI codes) +func (t *Table) SetColumnColor(colors ...Colors) { + if t.colSize != len(colors) { + panic("Number of column colors must be equal to number of headers.") + } + for i := 0; i < len(colors); i++ { + t.columnsParams = append(t.columnsParams, makeSequence(colors[i])) + } +} + +// Adding column colors (ANSI codes) +func (t *Table) SetFooterColor(colors ...Colors) { + if len(t.footers) != len(colors) { + panic("Number of footer colors must be equal to number of footer.") + } + for i := 0; i < len(colors); i++ { + t.footerParams = append(t.footerParams, makeSequence(colors[i])) + } +} + +func Color(colors ...int) []int { + return colors +} diff --git a/vendor/github.com/olekukonko/tablewriter/util.go b/vendor/github.com/olekukonko/tablewriter/util.go new file mode 100644 index 00000000..9e8f0cbb --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/util.go @@ -0,0 +1,93 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "math" + "regexp" + "strings" + + "github.com/mattn/go-runewidth" +) + +var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]") + +func DisplayWidth(str string) int { + return runewidth.StringWidth(ansi.ReplaceAllLiteralString(str, "")) +} + +// Simple Condition for string +// Returns value based on condition +func ConditionString(cond bool, valid, inValid string) string { + if cond { + return valid + } + return inValid +} + +func isNumOrSpace(r rune) bool { + return ('0' <= r && r <= '9') || r == ' ' +} + +// Format Table Header +// Replace _ , . and spaces +func Title(name string) string { + origLen := len(name) + rs := []rune(name) + for i, r := range rs { + switch r { + case '_': + rs[i] = ' ' + case '.': + // ignore floating number 0.0 + if (i != 0 && !isNumOrSpace(rs[i-1])) || (i != len(rs)-1 && !isNumOrSpace(rs[i+1])) { + rs[i] = ' ' + } + } + } + name = string(rs) + name = strings.TrimSpace(name) + if len(name) == 0 && origLen > 0 { + // Keep at least one character. This is important to preserve + // empty lines in multi-line headers/footers. + name = " " + } + return strings.ToUpper(name) +} + +// Pad String +// Attempts to play string in the center +func Pad(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + gapLeft := int(math.Ceil(float64(gap / 2))) + gapRight := gap - gapLeft + return strings.Repeat(string(pad), gapLeft) + s + strings.Repeat(string(pad), gapRight) + } + return s +} + +// Pad String Right position +// This would pace string at the left side fo the screen +func PadRight(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + return s + strings.Repeat(string(pad), gap) + } + return s +} + +// Pad String Left position +// This would pace string at the right side fo the screen +func PadLeft(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + return strings.Repeat(string(pad), gap) + s + } + return s +} diff --git a/vendor/github.com/olekukonko/tablewriter/wrap.go b/vendor/github.com/olekukonko/tablewriter/wrap.go new file mode 100644 index 00000000..a092ee1f --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/wrap.go @@ -0,0 +1,99 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "math" + "strings" + + "github.com/mattn/go-runewidth" +) + +var ( + nl = "\n" + sp = " " +) + +const defaultPenalty = 1e5 + +// Wrap wraps s into a paragraph of lines of length lim, with minimal +// raggedness. +func WrapString(s string, lim int) ([]string, int) { + words := strings.Split(strings.Replace(s, nl, sp, -1), sp) + var lines []string + max := 0 + for _, v := range words { + max = runewidth.StringWidth(v) + if max > lim { + lim = max + } + } + for _, line := range WrapWords(words, 1, lim, defaultPenalty) { + lines = append(lines, strings.Join(line, sp)) + } + return lines, lim +} + +// WrapWords is the low-level line-breaking algorithm, useful if you need more +// control over the details of the text wrapping process. For most uses, +// WrapString will be sufficient and more convenient. +// +// WrapWords splits a list of words into lines with minimal "raggedness", +// treating each rune as one unit, accounting for spc units between adjacent +// words on each line, and attempting to limit lines to lim units. Raggedness +// is the total error over all lines, where error is the square of the +// difference of the length of the line and lim. Too-long lines (which only +// happen when a single word is longer than lim units) have pen penalty units +// added to the error. +func WrapWords(words []string, spc, lim, pen int) [][]string { + n := len(words) + + length := make([][]int, n) + for i := 0; i < n; i++ { + length[i] = make([]int, n) + length[i][i] = runewidth.StringWidth(words[i]) + for j := i + 1; j < n; j++ { + length[i][j] = length[i][j-1] + spc + runewidth.StringWidth(words[j]) + } + } + nbrk := make([]int, n) + cost := make([]int, n) + for i := range cost { + cost[i] = math.MaxInt32 + } + for i := n - 1; i >= 0; i-- { + if length[i][n-1] <= lim { + cost[i] = 0 + nbrk[i] = n + } else { + for j := i + 1; j < n; j++ { + d := lim - length[i][j-1] + c := d*d + cost[j] + if length[i][j-1] > lim { + c += pen // too-long lines get a worse penalty + } + if c < cost[i] { + cost[i] = c + nbrk[i] = j + } + } + } + } + var lines [][]string + i := 0 + for i < n { + lines = append(lines, words[i:nbrk[i]]) + i = nbrk[i] + } + return lines +} + +// getLines decomposes a multiline string into a slice of strings. +func getLines(s string) []string { + return strings.Split(s, nl) +} diff --git a/vendor/github.com/onsi/ginkgo/.gitignore b/vendor/github.com/onsi/ginkgo/.gitignore new file mode 100644 index 00000000..b9f9659d --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +TODO +tmp/**/* +*.coverprofile +.vscode +.idea/ +*.log diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml new file mode 100644 index 00000000..72e8ccf0 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/.travis.yml @@ -0,0 +1,15 @@ +language: go +go: + - 1.10.x + - 1.11.x + - 1.12.x + - tip + +install: + - go get -v -t ./... + - go get golang.org/x/tools/cmd/cover + - go get github.com/onsi/gomega + - go install github.com/onsi/ginkgo/ginkgo + - export PATH=$PATH:$HOME/gopath/bin + +script: $HOME/gopath/bin/ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace && go vet diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md new file mode 100644 index 00000000..4920406a --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md @@ -0,0 +1,218 @@ +## 1.8.0 + +### New Features +- allow config of the vet flag for `go test` (#562) [3cd45fa] +- Support projects using go modules [d56ee76] + +### Fixes and Minor Improvements +- chore(godoc): fixes typos in Measurement funcs [dbaca8e] +- Optimize focus to avoid allocations [f493786] +- Ensure generated test file names are underscored [505cc35] + +## 1.7.0 + +### New Features +- Add JustAfterEach (#484) [0d4f080] + +### Fixes +- Correctly round suite time in junit reporter [2445fc1] +- Avoid using -i argument to go test for Golang 1.10+ [46bbc26] + +## 1.6.0 + +### New Features +- add --debug flag to emit node output to files (#499) [39febac] + +### Fixes +- fix: for `go vet` to pass [69338ec] +- docs: fix for contributing instructions [7004cb1] +- consolidate and streamline contribution docs (#494) [d848015] +- Make generated Junit file compatable with "Maven Surefire" (#488) [e51bee6] +- all: gofmt [000d317] +- Increase eventually timeout to 30s [c73579c] +- Clarify asynchronous test behaviour [294d8f4] +- Travis badge should only show master [26d2143] + +## 1.5.0 5/10/2018 + +### New Features +- Supports go v1.10 (#443, #446, #451) [e873237, 468e89e, e37dbfe, a37f4c0, c0b857d, bca5260, 4177ca8] +- Add a When() synonym for Context() (#386) [747514b, 7484dad, 7354a07, dd826c8] +- Re-add noisySkippings flag [652e15c] +- Allow coverage to be displayed for focused specs (#367) [11459a8] +- Handle -outputdir flag (#364) [228e3a8] +- Handle -coverprofile flag (#355) [43392d5] + +### Fixes +- When using custom reporters register the custom reporters *before* the default reporter. This allows users to see the output of any print statements in their customer reporters. (#365) [8382b23] +- When running a test and calculating the coverage using the `-coverprofile` and `-outputdir` flags, Ginkgo fails with an error if the directory does not exist. This is due to an [issue in go 1.10](https://github.com/golang/go/issues/24588) (#446) [b36a6e0] +- `unfocus` command ignores vendor folder (#459) [e5e551c, c556e43, a3b6351, 9a820dd] +- Ignore packages whose tests are all ignored by go (#456) [7430ca7, 6d8be98] +- Increase the threshold when checking time measuments (#455) [2f714bf, 68f622c] +- Fix race condition in coverage tests (#423) [a5a8ff7, ab9c08b] +- Add an extra new line after reporting spec run completion for test2json [874520d] +- added name name field to junit reported testsuite [ae61c63] +- Do not set the run time of a spec when the dryRun flag is used (#438) [457e2d9, ba8e856] +- Process FWhen and FSpecify when unfocusing (#434) [9008c7b, ee65bd, df87dfe] +- Synchronise the access to the state of specs to avoid race conditions (#430) [7d481bc, ae6829d] +- Added Duration on GinkgoTestDescription (#383) [5f49dad, 528417e, 0747408, 329d7ed] +- Fix Ginkgo stack trace on failure for Specify (#415) [b977ede, 65ca40e, 6c46eb8] +- Update README with Go 1.6+, Golang -> Go (#409) [17f6b97, bc14b66, 20d1598] +- Use fmt.Errorf instead of errors.New(fmt.Sprintf (#401) [a299f56, 44e2eaa] +- Imports in generated code should follow conventions (#398) [0bec0b0, e8536d8] +- Prevent data race error when Recording a benchmark value from multiple go routines (#390) [c0c4881, 7a241e9] +- Replace GOPATH in Environment [4b883f0] + + +## 1.4.0 7/16/2017 + +- `ginkgo` now provides a hint if you accidentally forget to run `ginkgo bootstrap` to generate a `*_suite_test.go` file that actually invokes the Ginkgo test runner. [#345](https://github.com/onsi/ginkgo/pull/345) +- thanks to improvements in `go test -c` `ginkgo` no longer needs to fix Go's compilation output to ensure compilation errors are expressed relative to the CWD. [#357] +- `ginkgo watch -watchRegExp=...` allows you to specify a custom regular expression to watch. Only files matching the regular expression are watched for changes (the default is `\.go$`) [#356] +- `ginkgo` now always emits compilation output. Previously, only failed compilation output was printed out. [#277] +- `ginkgo -requireSuite` now fails the test run if there are `*_test.go` files but `go test` fails to detect any tests. Typically this means you forgot to run `ginkgo bootstrap` to generate a suite file. [#344] +- `ginkgo -timeout=DURATION` allows you to adjust the timeout for the entire test suite (default is 24 hours) [#248] + +## 1.3.0 3/28/2017 + +Improvements: + +- Significantly improved parallel test distribution. Now instead of pre-sharding test cases across workers (which can result in idle workers and poor test performance) Ginkgo uses a shared queue to keep all workers busy until all tests are complete. This improves test-time performance and consistency. +- `Skip(message)` can be used to skip the current test. +- Added `extensions/table` - a Ginkgo DSL for [Table Driven Tests](http://onsi.github.io/ginkgo/#table-driven-tests) +- Add `GinkgoRandomSeed()` - shorthand for `config.GinkgoConfig.RandomSeed` +- Support for retrying flaky tests with `--flakeAttempts` +- `ginkgo ./...` now recurses as you'd expect +- Added `Specify` a synonym for `It` +- Support colorise on Windows +- Broader support for various go compilation flags in the `ginkgo` CLI + +Bug Fixes: + +- Ginkgo tests now fail when you `panic(nil)` (#167) + +## 1.2.0 5/31/2015 + +Improvements + +- `ginkgo -coverpkg` calls down to `go test -coverpkg` (#160) +- `ginkgo -afterSuiteHook COMMAND` invokes the passed-in `COMMAND` after a test suite completes (#152) +- Relaxed requirement for Go 1.4+. `ginkgo` now works with Go v1.3+ (#166) + +## 1.2.0-beta + +Ginkgo now requires Go 1.4+ + +Improvements: + +- Call reporters in reverse order when announcing spec completion -- allows custom reporters to emit output before the default reporter does. +- Improved focus behavior. Now, this: + + ```golang + FDescribe("Some describe", func() { + It("A", func() {}) + + FIt("B", func() {}) + }) + ``` + + will run `B` but *not* `A`. This tends to be a common usage pattern when in the thick of writing and debugging tests. +- When `SIGINT` is received, Ginkgo will emit the contents of the `GinkgoWriter` before running the `AfterSuite`. Useful for debugging stuck tests. +- When `--progress` is set, Ginkgo will write test progress (in particular, Ginkgo will say when it is about to run a BeforeEach, AfterEach, It, etc...) to the `GinkgoWriter`. This is useful for debugging stuck tests and tests that generate many logs. +- Improved output when an error occurs in a setup or teardown block. +- When `--dryRun` is set, Ginkgo will walk the spec tree and emit to its reporter *without* actually running anything. Best paired with `-v` to understand which specs will run in which order. +- Add `By` to help document long `It`s. `By` simply writes to the `GinkgoWriter`. +- Add support for precompiled tests: + - `ginkgo build ` will now compile the package, producing a file named `package.test` + - The compiled `package.test` file can be run directly. This runs the tests in series. + - To run precompiled tests in parallel, you can run: `ginkgo -p package.test` +- Support `bootstrap`ping and `generate`ing [Agouti](http://agouti.org) specs. +- `ginkgo generate` and `ginkgo bootstrap` now honor the package name already defined in a given directory +- The `ginkgo` CLI ignores `SIGQUIT`. Prevents its stack dump from interlacing with the underlying test suite's stack dump. +- The `ginkgo` CLI now compiles tests into a temporary directory instead of the package directory. This necessitates upgrading to Go v1.4+. +- `ginkgo -notify` now works on Linux + +Bug Fixes: + +- If --skipPackages is used and all packages are skipped, Ginkgo should exit 0. +- Fix tempfile leak when running in parallel +- Fix incorrect failure message when a panic occurs during a parallel test run +- Fixed an issue where a pending test within a focused context (or a focused test within a pending context) would skip all other tests. +- Be more consistent about handling SIGTERM as well as SIGINT +- When interupted while concurrently compiling test suites in the background, Ginkgo now cleans up the compiled artifacts. +- Fixed a long standing bug where `ginkgo -p` would hang if a process spawned by one of the Ginkgo parallel nodes does not exit. (Hooray!) + +## 1.1.0 (8/2/2014) + +No changes, just dropping the beta. + +## 1.1.0-beta (7/22/2014) +New Features: + +- `ginkgo watch` now monitors packages *and their dependencies* for changes. The depth of the dependency tree can be modified with the `-depth` flag. +- Test suites with a programmatic focus (`FIt`, `FDescribe`, etc...) exit with non-zero status code, even when they pass. This allows CI systems to detect accidental commits of focused test suites. +- `ginkgo -p` runs the testsuite in parallel with an auto-detected number of nodes. +- `ginkgo -tags=TAG_LIST` passes a list of tags down to the `go build` command. +- `ginkgo --failFast` aborts the test suite after the first failure. +- `ginkgo generate file_1 file_2` can take multiple file arguments. +- Ginkgo now summarizes any spec failures that occured at the end of the test run. +- `ginkgo --randomizeSuites` will run tests *suites* in random order using the generated/passed-in seed. + +Improvements: + +- `ginkgo -skipPackage` now takes a comma-separated list of strings. If the *relative path* to a package matches one of the entries in the comma-separated list, that package is skipped. +- `ginkgo --untilItFails` no longer recompiles between attempts. +- Ginkgo now panics when a runnable node (`It`, `BeforeEach`, `JustBeforeEach`, `AfterEach`, `Measure`) is nested within another runnable node. This is always a mistake. Any test suites that panic because of this change should be fixed. + +Bug Fixes: + +- `ginkgo boostrap` and `ginkgo generate` no longer fail when dealing with `hyphen-separated-packages`. +- parallel specs are now better distributed across nodes - fixed a crashing bug where (for example) distributing 11 tests across 7 nodes would panic + +## 1.0.0 (5/24/2014) +New Features: + +- Add `GinkgoParallelNode()` - shorthand for `config.GinkgoConfig.ParallelNode` + +Improvements: + +- When compilation fails, the compilation output is rewritten to present a correct *relative* path. Allows ⌘-clicking in iTerm open the file in your text editor. +- `--untilItFails` and `ginkgo watch` now generate new random seeds between test runs, unless a particular random seed is specified. + +Bug Fixes: + +- `-cover` now generates a correctly combined coverprofile when running with in parallel with multiple `-node`s. +- Print out the contents of the `GinkgoWriter` when `BeforeSuite` or `AfterSuite` fail. +- Fix all remaining race conditions in Ginkgo's test suite. + +## 1.0.0-beta (4/14/2014) +Breaking changes: + +- `thirdparty/gomocktestreporter` is gone. Use `GinkgoT()` instead +- Modified the Reporter interface +- `watch` is now a subcommand, not a flag. + +DSL changes: + +- `BeforeSuite` and `AfterSuite` for setting up and tearing down test suites. +- `AfterSuite` is triggered on interrupt (`^C`) as well as exit. +- `SynchronizedBeforeSuite` and `SynchronizedAfterSuite` for setting up and tearing down singleton resources across parallel nodes. + +CLI changes: + +- `watch` is now a subcommand, not a flag +- `--nodot` flag can be passed to `ginkgo generate` and `ginkgo bootstrap` to avoid dot imports. This explicitly imports all exported identifiers in Ginkgo and Gomega. Refreshing this list can be done by running `ginkgo nodot` +- Additional arguments can be passed to specs. Pass them after the `--` separator +- `--skipPackage` flag takes a regexp and ignores any packages with package names passing said regexp. +- `--trace` flag prints out full stack traces when errors occur, not just the line at which the error occurs. + +Misc: + +- Start using semantic versioning +- Start maintaining changelog + +Major refactor: + +- Pull out Ginkgo's internal to `internal` +- Rename `example` everywhere to `spec` +- Much more! diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go new file mode 100644 index 00000000..dab2a247 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/config/config.go @@ -0,0 +1,200 @@ +/* +Ginkgo accepts a number of configuration options. + +These are documented [here](http://onsi.github.io/ginkgo/#the_ginkgo_cli) + +You can also learn more via + + ginkgo help + +or (I kid you not): + + go test -asdf +*/ +package config + +import ( + "flag" + "time" + + "fmt" +) + +const VERSION = "1.8.0" + +type GinkgoConfigType struct { + RandomSeed int64 + RandomizeAllSpecs bool + RegexScansFilePath bool + FocusString string + SkipString string + SkipMeasurements bool + FailOnPending bool + FailFast bool + FlakeAttempts int + EmitSpecProgress bool + DryRun bool + DebugParallel bool + + ParallelNode int + ParallelTotal int + SyncHost string + StreamHost string +} + +var GinkgoConfig = GinkgoConfigType{} + +type DefaultReporterConfigType struct { + NoColor bool + SlowSpecThreshold float64 + NoisyPendings bool + NoisySkippings bool + Succinct bool + Verbose bool + FullTrace bool +} + +var DefaultReporterConfig = DefaultReporterConfigType{} + +func processPrefix(prefix string) string { + if prefix != "" { + prefix = prefix + "." + } + return prefix +} + +func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) { + prefix = processPrefix(prefix) + flagSet.Int64Var(&(GinkgoConfig.RandomSeed), prefix+"seed", time.Now().Unix(), "The seed used to randomize the spec suite.") + flagSet.BoolVar(&(GinkgoConfig.RandomizeAllSpecs), prefix+"randomizeAllSpecs", false, "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When groups.") + flagSet.BoolVar(&(GinkgoConfig.SkipMeasurements), prefix+"skipMeasurements", false, "If set, ginkgo will skip any measurement specs.") + flagSet.BoolVar(&(GinkgoConfig.FailOnPending), prefix+"failOnPending", false, "If set, ginkgo will mark the test suite as failed if any specs are pending.") + flagSet.BoolVar(&(GinkgoConfig.FailFast), prefix+"failFast", false, "If set, ginkgo will stop running a test suite after a failure occurs.") + + flagSet.BoolVar(&(GinkgoConfig.DryRun), prefix+"dryRun", false, "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v.") + + flagSet.StringVar(&(GinkgoConfig.FocusString), prefix+"focus", "", "If set, ginkgo will only run specs that match this regular expression.") + flagSet.StringVar(&(GinkgoConfig.SkipString), prefix+"skip", "", "If set, ginkgo will only run specs that do not match this regular expression.") + + flagSet.BoolVar(&(GinkgoConfig.RegexScansFilePath), prefix+"regexScansFilePath", false, "If set, ginkgo regex matching also will look at the file path (code location).") + + flagSet.IntVar(&(GinkgoConfig.FlakeAttempts), prefix+"flakeAttempts", 1, "Make up to this many attempts to run each spec. Please note that if any of the attempts succeed, the suite will not be failed. But any failures will still be recorded.") + + flagSet.BoolVar(&(GinkgoConfig.EmitSpecProgress), prefix+"progress", false, "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter.") + + flagSet.BoolVar(&(GinkgoConfig.DebugParallel), prefix+"debug", false, "If set, ginkgo will emit node output to files when running in parallel.") + + if includeParallelFlags { + flagSet.IntVar(&(GinkgoConfig.ParallelNode), prefix+"parallel.node", 1, "This worker node's (one-indexed) node number. For running specs in parallel.") + flagSet.IntVar(&(GinkgoConfig.ParallelTotal), prefix+"parallel.total", 1, "The total number of worker nodes. For running specs in parallel.") + flagSet.StringVar(&(GinkgoConfig.SyncHost), prefix+"parallel.synchost", "", "The address for the server that will synchronize the running nodes.") + flagSet.StringVar(&(GinkgoConfig.StreamHost), prefix+"parallel.streamhost", "", "The address for the server that the running nodes should stream data to.") + } + + flagSet.BoolVar(&(DefaultReporterConfig.NoColor), prefix+"noColor", false, "If set, suppress color output in default reporter.") + flagSet.Float64Var(&(DefaultReporterConfig.SlowSpecThreshold), prefix+"slowSpecThreshold", 5.0, "(in seconds) Specs that take longer to run than this threshold are flagged as slow by the default reporter.") + flagSet.BoolVar(&(DefaultReporterConfig.NoisyPendings), prefix+"noisyPendings", true, "If set, default reporter will shout about pending tests.") + flagSet.BoolVar(&(DefaultReporterConfig.NoisySkippings), prefix+"noisySkippings", true, "If set, default reporter will shout about skipping tests.") + flagSet.BoolVar(&(DefaultReporterConfig.Verbose), prefix+"v", false, "If set, default reporter print out all specs as they begin.") + flagSet.BoolVar(&(DefaultReporterConfig.Succinct), prefix+"succinct", false, "If set, default reporter prints out a very succinct report") + flagSet.BoolVar(&(DefaultReporterConfig.FullTrace), prefix+"trace", false, "If set, default reporter prints out the full stack trace when a failure occurs") +} + +func BuildFlagArgs(prefix string, ginkgo GinkgoConfigType, reporter DefaultReporterConfigType) []string { + prefix = processPrefix(prefix) + result := make([]string, 0) + + if ginkgo.RandomSeed > 0 { + result = append(result, fmt.Sprintf("--%sseed=%d", prefix, ginkgo.RandomSeed)) + } + + if ginkgo.RandomizeAllSpecs { + result = append(result, fmt.Sprintf("--%srandomizeAllSpecs", prefix)) + } + + if ginkgo.SkipMeasurements { + result = append(result, fmt.Sprintf("--%sskipMeasurements", prefix)) + } + + if ginkgo.FailOnPending { + result = append(result, fmt.Sprintf("--%sfailOnPending", prefix)) + } + + if ginkgo.FailFast { + result = append(result, fmt.Sprintf("--%sfailFast", prefix)) + } + + if ginkgo.DryRun { + result = append(result, fmt.Sprintf("--%sdryRun", prefix)) + } + + if ginkgo.FocusString != "" { + result = append(result, fmt.Sprintf("--%sfocus=%s", prefix, ginkgo.FocusString)) + } + + if ginkgo.SkipString != "" { + result = append(result, fmt.Sprintf("--%sskip=%s", prefix, ginkgo.SkipString)) + } + + if ginkgo.FlakeAttempts > 1 { + result = append(result, fmt.Sprintf("--%sflakeAttempts=%d", prefix, ginkgo.FlakeAttempts)) + } + + if ginkgo.EmitSpecProgress { + result = append(result, fmt.Sprintf("--%sprogress", prefix)) + } + + if ginkgo.DebugParallel { + result = append(result, fmt.Sprintf("--%sdebug", prefix)) + } + + if ginkgo.ParallelNode != 0 { + result = append(result, fmt.Sprintf("--%sparallel.node=%d", prefix, ginkgo.ParallelNode)) + } + + if ginkgo.ParallelTotal != 0 { + result = append(result, fmt.Sprintf("--%sparallel.total=%d", prefix, ginkgo.ParallelTotal)) + } + + if ginkgo.StreamHost != "" { + result = append(result, fmt.Sprintf("--%sparallel.streamhost=%s", prefix, ginkgo.StreamHost)) + } + + if ginkgo.SyncHost != "" { + result = append(result, fmt.Sprintf("--%sparallel.synchost=%s", prefix, ginkgo.SyncHost)) + } + + if ginkgo.RegexScansFilePath { + result = append(result, fmt.Sprintf("--%sregexScansFilePath", prefix)) + } + + if reporter.NoColor { + result = append(result, fmt.Sprintf("--%snoColor", prefix)) + } + + if reporter.SlowSpecThreshold > 0 { + result = append(result, fmt.Sprintf("--%sslowSpecThreshold=%.5f", prefix, reporter.SlowSpecThreshold)) + } + + if !reporter.NoisyPendings { + result = append(result, fmt.Sprintf("--%snoisyPendings=false", prefix)) + } + + if !reporter.NoisySkippings { + result = append(result, fmt.Sprintf("--%snoisySkippings=false", prefix)) + } + + if reporter.Verbose { + result = append(result, fmt.Sprintf("--%sv", prefix)) + } + + if reporter.Succinct { + result = append(result, fmt.Sprintf("--%ssuccinct", prefix)) + } + + if reporter.FullTrace { + result = append(result, fmt.Sprintf("--%strace", prefix)) + } + + return result +} diff --git a/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go new file mode 100644 index 00000000..a6b96d88 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go @@ -0,0 +1,619 @@ +/* +Ginkgo is a BDD-style testing framework for Golang + +The godoc documentation describes Ginkgo's API. More comprehensive documentation (with examples!) is available at http://onsi.github.io/ginkgo/ + +Ginkgo's preferred matcher library is [Gomega](http://github.com/onsi/gomega) + +Ginkgo on Github: http://github.com/onsi/ginkgo + +Ginkgo is MIT-Licensed +*/ +package ginkgo + +import ( + "flag" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" + + "github.com/onsi/ginkgo/config" + "github.com/onsi/ginkgo/internal/codelocation" + "github.com/onsi/ginkgo/internal/failer" + "github.com/onsi/ginkgo/internal/remote" + "github.com/onsi/ginkgo/internal/suite" + "github.com/onsi/ginkgo/internal/testingtproxy" + "github.com/onsi/ginkgo/internal/writer" + "github.com/onsi/ginkgo/reporters" + "github.com/onsi/ginkgo/reporters/stenographer" + colorable "github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable" + "github.com/onsi/ginkgo/types" +) + +const GINKGO_VERSION = config.VERSION +const GINKGO_PANIC = ` +Your test failed. +Ginkgo panics to prevent subsequent assertions from running. +Normally Ginkgo rescues this panic so you shouldn't see it. + +But, if you make an assertion in a goroutine, Ginkgo can't capture the panic. +To circumvent this, you should call + + defer GinkgoRecover() + +at the top of the goroutine that caused this panic. +` +const defaultTimeout = 1 + +var globalSuite *suite.Suite +var globalFailer *failer.Failer + +func init() { + config.Flags(flag.CommandLine, "ginkgo", true) + GinkgoWriter = writer.New(os.Stdout) + globalFailer = failer.New() + globalSuite = suite.New(globalFailer) +} + +//GinkgoWriter implements an io.Writer +//When running in verbose mode any writes to GinkgoWriter will be immediately printed +//to stdout. Otherwise, GinkgoWriter will buffer any writes produced during the current test and flush them to screen +//only if the current test fails. +var GinkgoWriter io.Writer + +//The interface by which Ginkgo receives *testing.T +type GinkgoTestingT interface { + Fail() +} + +//GinkgoRandomSeed returns the seed used to randomize spec execution order. It is +//useful for seeding your own pseudorandom number generators (PRNGs) to ensure +//consistent executions from run to run, where your tests contain variability (for +//example, when selecting random test data). +func GinkgoRandomSeed() int64 { + return config.GinkgoConfig.RandomSeed +} + +//GinkgoParallelNode returns the parallel node number for the current ginkgo process +//The node number is 1-indexed +func GinkgoParallelNode() int { + return config.GinkgoConfig.ParallelNode +} + +//Some matcher libraries or legacy codebases require a *testing.T +//GinkgoT implements an interface analogous to *testing.T and can be used if +//the library in question accepts *testing.T through an interface +// +// For example, with testify: +// assert.Equal(GinkgoT(), 123, 123, "they should be equal") +// +// Or with gomock: +// gomock.NewController(GinkgoT()) +// +// GinkgoT() takes an optional offset argument that can be used to get the +// correct line number associated with the failure. +func GinkgoT(optionalOffset ...int) GinkgoTInterface { + offset := 3 + if len(optionalOffset) > 0 { + offset = optionalOffset[0] + } + return testingtproxy.New(GinkgoWriter, Fail, offset) +} + +//The interface returned by GinkgoT(). This covers most of the methods +//in the testing package's T. +type GinkgoTInterface interface { + Fail() + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + FailNow() + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Log(args ...interface{}) + Logf(format string, args ...interface{}) + Failed() bool + Parallel() + Skip(args ...interface{}) + Skipf(format string, args ...interface{}) + SkipNow() + Skipped() bool +} + +//Custom Ginkgo test reporters must implement the Reporter interface. +// +//The custom reporter is passed in a SuiteSummary when the suite begins and ends, +//and a SpecSummary just before a spec begins and just after a spec ends +type Reporter reporters.Reporter + +//Asynchronous specs are given a channel of the Done type. You must close or write to the channel +//to tell Ginkgo that your async test is done. +type Done chan<- interface{} + +//GinkgoTestDescription represents the information about the current running test returned by CurrentGinkgoTestDescription +// FullTestText: a concatenation of ComponentTexts and the TestText +// ComponentTexts: a list of all texts for the Describes & Contexts leading up to the current test +// TestText: the text in the actual It or Measure node +// IsMeasurement: true if the current test is a measurement +// FileName: the name of the file containing the current test +// LineNumber: the line number for the current test +// Failed: if the current test has failed, this will be true (useful in an AfterEach) +type GinkgoTestDescription struct { + FullTestText string + ComponentTexts []string + TestText string + + IsMeasurement bool + + FileName string + LineNumber int + + Failed bool + Duration time.Duration +} + +//CurrentGinkgoTestDescripton returns information about the current running test. +func CurrentGinkgoTestDescription() GinkgoTestDescription { + summary, ok := globalSuite.CurrentRunningSpecSummary() + if !ok { + return GinkgoTestDescription{} + } + + subjectCodeLocation := summary.ComponentCodeLocations[len(summary.ComponentCodeLocations)-1] + + return GinkgoTestDescription{ + ComponentTexts: summary.ComponentTexts[1:], + FullTestText: strings.Join(summary.ComponentTexts[1:], " "), + TestText: summary.ComponentTexts[len(summary.ComponentTexts)-1], + IsMeasurement: summary.IsMeasurement, + FileName: subjectCodeLocation.FileName, + LineNumber: subjectCodeLocation.LineNumber, + Failed: summary.HasFailureState(), + Duration: summary.RunTime, + } +} + +//Measurement tests receive a Benchmarker. +// +//You use the Time() function to time how long the passed in body function takes to run +//You use the RecordValue() function to track arbitrary numerical measurements. +//The RecordValueWithPrecision() function can be used alternatively to provide the unit +//and resolution of the numeric measurement. +//The optional info argument is passed to the test reporter and can be used to +// provide the measurement data to a custom reporter with context. +// +//See http://onsi.github.io/ginkgo/#benchmark_tests for more details +type Benchmarker interface { + Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration) + RecordValue(name string, value float64, info ...interface{}) + RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{}) +} + +//RunSpecs is the entry point for the Ginkgo test runner. +//You must call this within a Golang testing TestX(t *testing.T) function. +// +//To bootstrap a test suite you can use the Ginkgo CLI: +// +// ginkgo bootstrap +func RunSpecs(t GinkgoTestingT, description string) bool { + specReporters := []Reporter{buildDefaultReporter()} + return RunSpecsWithCustomReporters(t, description, specReporters) +} + +//To run your tests with Ginkgo's default reporter and your custom reporter(s), replace +//RunSpecs() with this method. +func RunSpecsWithDefaultAndCustomReporters(t GinkgoTestingT, description string, specReporters []Reporter) bool { + specReporters = append(specReporters, buildDefaultReporter()) + return RunSpecsWithCustomReporters(t, description, specReporters) +} + +//To run your tests with your custom reporter(s) (and *not* Ginkgo's default reporter), replace +//RunSpecs() with this method. Note that parallel tests will not work correctly without the default reporter +func RunSpecsWithCustomReporters(t GinkgoTestingT, description string, specReporters []Reporter) bool { + writer := GinkgoWriter.(*writer.Writer) + writer.SetStream(config.DefaultReporterConfig.Verbose) + reporters := make([]reporters.Reporter, len(specReporters)) + for i, reporter := range specReporters { + reporters[i] = reporter + } + passed, hasFocusedTests := globalSuite.Run(t, description, reporters, writer, config.GinkgoConfig) + if passed && hasFocusedTests && strings.TrimSpace(os.Getenv("GINKGO_EDITOR_INTEGRATION")) == "" { + fmt.Println("PASS | FOCUSED") + os.Exit(types.GINKGO_FOCUS_EXIT_CODE) + } + return passed +} + +func buildDefaultReporter() Reporter { + remoteReportingServer := config.GinkgoConfig.StreamHost + if remoteReportingServer == "" { + stenographer := stenographer.New(!config.DefaultReporterConfig.NoColor, config.GinkgoConfig.FlakeAttempts > 1, colorable.NewColorableStdout()) + return reporters.NewDefaultReporter(config.DefaultReporterConfig, stenographer) + } else { + debugFile := "" + if config.GinkgoConfig.DebugParallel { + debugFile = fmt.Sprintf("ginkgo-node-%d.log", config.GinkgoConfig.ParallelNode) + } + return remote.NewForwardingReporter(config.DefaultReporterConfig, remoteReportingServer, &http.Client{}, remote.NewOutputInterceptor(), GinkgoWriter.(*writer.Writer), debugFile) + } +} + +//Skip notifies Ginkgo that the current spec was skipped. +func Skip(message string, callerSkip ...int) { + skip := 0 + if len(callerSkip) > 0 { + skip = callerSkip[0] + } + + globalFailer.Skip(message, codelocation.New(skip+1)) + panic(GINKGO_PANIC) +} + +//Fail notifies Ginkgo that the current spec has failed. (Gomega will call Fail for you automatically when an assertion fails.) +func Fail(message string, callerSkip ...int) { + skip := 0 + if len(callerSkip) > 0 { + skip = callerSkip[0] + } + + globalFailer.Fail(message, codelocation.New(skip+1)) + panic(GINKGO_PANIC) +} + +//GinkgoRecover should be deferred at the top of any spawned goroutine that (may) call `Fail` +//Since Gomega assertions call fail, you should throw a `defer GinkgoRecover()` at the top of any goroutine that +//calls out to Gomega +// +//Here's why: Ginkgo's `Fail` method records the failure and then panics to prevent +//further assertions from running. This panic must be recovered. Ginkgo does this for you +//if the panic originates in a Ginkgo node (an It, BeforeEach, etc...) +// +//Unfortunately, if a panic originates on a goroutine *launched* from one of these nodes there's no +//way for Ginkgo to rescue the panic. To do this, you must remember to `defer GinkgoRecover()` at the top of such a goroutine. +func GinkgoRecover() { + e := recover() + if e != nil { + globalFailer.Panic(codelocation.New(1), e) + } +} + +//Describe blocks allow you to organize your specs. A Describe block can contain any number of +//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. +// +//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally +//equivalent. The difference is purely semantic -- you typical Describe the behavior of an object +//or method and, within that Describe, outline a number of Contexts and Whens. +func Describe(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypeNone, codelocation.New(1)) + return true +} + +//You can focus the tests within a describe block using FDescribe +func FDescribe(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypeFocused, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using PDescribe +func PDescribe(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using XDescribe +func XDescribe(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//Context blocks allow you to organize your specs. A Context block can contain any number of +//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. +// +//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally +//equivalent. The difference is purely semantic -- you typical Describe the behavior of an object +//or method and, within that Describe, outline a number of Contexts and Whens. +func Context(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypeNone, codelocation.New(1)) + return true +} + +//You can focus the tests within a describe block using FContext +func FContext(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypeFocused, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using PContext +func PContext(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using XContext +func XContext(text string, body func()) bool { + globalSuite.PushContainerNode(text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//When blocks allow you to organize your specs. A When block can contain any number of +//BeforeEach, AfterEach, JustBeforeEach, It, and Measurement blocks. +// +//In addition you can nest Describe, Context and When blocks. Describe, Context and When blocks are functionally +//equivalent. The difference is purely semantic -- you typical Describe the behavior of an object +//or method and, within that Describe, outline a number of Contexts and Whens. +func When(text string, body func()) bool { + globalSuite.PushContainerNode("when "+text, body, types.FlagTypeNone, codelocation.New(1)) + return true +} + +//You can focus the tests within a describe block using FWhen +func FWhen(text string, body func()) bool { + globalSuite.PushContainerNode("when "+text, body, types.FlagTypeFocused, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using PWhen +func PWhen(text string, body func()) bool { + globalSuite.PushContainerNode("when "+text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//You can mark the tests within a describe block as pending using XWhen +func XWhen(text string, body func()) bool { + globalSuite.PushContainerNode("when "+text, body, types.FlagTypePending, codelocation.New(1)) + return true +} + +//It blocks contain your test code and assertions. You cannot nest any other Ginkgo blocks +//within an It block. +// +//Ginkgo will normally run It blocks synchronously. To perform asynchronous tests, pass a +//function that accepts a Done channel. When you do this, you can also provide an optional timeout. +func It(text string, body interface{}, timeout ...float64) bool { + globalSuite.PushItNode(text, body, types.FlagTypeNone, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//You can focus individual Its using FIt +func FIt(text string, body interface{}, timeout ...float64) bool { + globalSuite.PushItNode(text, body, types.FlagTypeFocused, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//You can mark Its as pending using PIt +func PIt(text string, _ ...interface{}) bool { + globalSuite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//You can mark Its as pending using XIt +func XIt(text string, _ ...interface{}) bool { + globalSuite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//Specify blocks are aliases for It blocks and allow for more natural wording in situations +//which "It" does not fit into a natural sentence flow. All the same protocols apply for Specify blocks +//which apply to It blocks. +func Specify(text string, body interface{}, timeout ...float64) bool { + globalSuite.PushItNode(text, body, types.FlagTypeNone, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//You can focus individual Specifys using FSpecify +func FSpecify(text string, body interface{}, timeout ...float64) bool { + globalSuite.PushItNode(text, body, types.FlagTypeFocused, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//You can mark Specifys as pending using PSpecify +func PSpecify(text string, is ...interface{}) bool { + globalSuite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//You can mark Specifys as pending using XSpecify +func XSpecify(text string, is ...interface{}) bool { + globalSuite.PushItNode(text, func() {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//By allows you to better document large Its. +// +//Generally you should try to keep your Its short and to the point. This is not always possible, however, +//especially in the context of integration tests that capture a particular workflow. +// +//By allows you to document such flows. By must be called within a runnable node (It, BeforeEach, Measure, etc...) +//By will simply log the passed in text to the GinkgoWriter. If By is handed a function it will immediately run the function. +func By(text string, callbacks ...func()) { + preamble := "\x1b[1mSTEP\x1b[0m" + if config.DefaultReporterConfig.NoColor { + preamble = "STEP" + } + fmt.Fprintln(GinkgoWriter, preamble+": "+text) + if len(callbacks) == 1 { + callbacks[0]() + } + if len(callbacks) > 1 { + panic("just one callback per By, please") + } +} + +//Measure blocks run the passed in body function repeatedly (determined by the samples argument) +//and accumulate metrics provided to the Benchmarker by the body function. +// +//The body function must have the signature: +// func(b Benchmarker) +func Measure(text string, body interface{}, samples int) bool { + globalSuite.PushMeasureNode(text, body, types.FlagTypeNone, codelocation.New(1), samples) + return true +} + +//You can focus individual Measures using FMeasure +func FMeasure(text string, body interface{}, samples int) bool { + globalSuite.PushMeasureNode(text, body, types.FlagTypeFocused, codelocation.New(1), samples) + return true +} + +//You can mark Measurements as pending using PMeasure +func PMeasure(text string, _ ...interface{}) bool { + globalSuite.PushMeasureNode(text, func(b Benchmarker) {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//You can mark Measurements as pending using XMeasure +func XMeasure(text string, _ ...interface{}) bool { + globalSuite.PushMeasureNode(text, func(b Benchmarker) {}, types.FlagTypePending, codelocation.New(1), 0) + return true +} + +//BeforeSuite blocks are run just once before any specs are run. When running in parallel, each +//parallel node process will call BeforeSuite. +// +//BeforeSuite blocks can be made asynchronous by providing a body function that accepts a Done channel +// +//You may only register *one* BeforeSuite handler per test suite. You typically do so in your bootstrap file at the top level. +func BeforeSuite(body interface{}, timeout ...float64) bool { + globalSuite.SetBeforeSuiteNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//AfterSuite blocks are *always* run after all the specs regardless of whether specs have passed or failed. +//Moreover, if Ginkgo receives an interrupt signal (^C) it will attempt to run the AfterSuite before exiting. +// +//When running in parallel, each parallel node process will call AfterSuite. +// +//AfterSuite blocks can be made asynchronous by providing a body function that accepts a Done channel +// +//You may only register *one* AfterSuite handler per test suite. You typically do so in your bootstrap file at the top level. +func AfterSuite(body interface{}, timeout ...float64) bool { + globalSuite.SetAfterSuiteNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//SynchronizedBeforeSuite blocks are primarily meant to solve the problem of setting up singleton external resources shared across +//nodes when running tests in parallel. For example, say you have a shared database that you can only start one instance of that +//must be used in your tests. When running in parallel, only one node should set up the database and all other nodes should wait +//until that node is done before running. +// +//SynchronizedBeforeSuite accomplishes this by taking *two* function arguments. The first is only run on parallel node #1. The second is +//run on all nodes, but *only* after the first function completes succesfully. Ginkgo also makes it possible to send data from the first function (on Node 1) +//to the second function (on all the other nodes). +// +//The functions have the following signatures. The first function (which only runs on node 1) has the signature: +// +// func() []byte +// +//or, to run asynchronously: +// +// func(done Done) []byte +// +//The byte array returned by the first function is then passed to the second function, which has the signature: +// +// func(data []byte) +// +//or, to run asynchronously: +// +// func(data []byte, done Done) +// +//Here's a simple pseudo-code example that starts a shared database on Node 1 and shares the database's address with the other nodes: +// +// var dbClient db.Client +// var dbRunner db.Runner +// +// var _ = SynchronizedBeforeSuite(func() []byte { +// dbRunner = db.NewRunner() +// err := dbRunner.Start() +// Ω(err).ShouldNot(HaveOccurred()) +// return []byte(dbRunner.URL) +// }, func(data []byte) { +// dbClient = db.NewClient() +// err := dbClient.Connect(string(data)) +// Ω(err).ShouldNot(HaveOccurred()) +// }) +func SynchronizedBeforeSuite(node1Body interface{}, allNodesBody interface{}, timeout ...float64) bool { + globalSuite.SetSynchronizedBeforeSuiteNode( + node1Body, + allNodesBody, + codelocation.New(1), + parseTimeout(timeout...), + ) + return true +} + +//SynchronizedAfterSuite blocks complement the SynchronizedBeforeSuite blocks in solving the problem of setting up +//external singleton resources shared across nodes when running tests in parallel. +// +//SynchronizedAfterSuite accomplishes this by taking *two* function arguments. The first runs on all nodes. The second runs only on parallel node #1 +//and *only* after all other nodes have finished and exited. This ensures that node 1, and any resources it is running, remain alive until +//all other nodes are finished. +// +//Both functions have the same signature: either func() or func(done Done) to run asynchronously. +// +//Here's a pseudo-code example that complements that given in SynchronizedBeforeSuite. Here, SynchronizedAfterSuite is used to tear down the shared database +//only after all nodes have finished: +// +// var _ = SynchronizedAfterSuite(func() { +// dbClient.Cleanup() +// }, func() { +// dbRunner.Stop() +// }) +func SynchronizedAfterSuite(allNodesBody interface{}, node1Body interface{}, timeout ...float64) bool { + globalSuite.SetSynchronizedAfterSuiteNode( + allNodesBody, + node1Body, + codelocation.New(1), + parseTimeout(timeout...), + ) + return true +} + +//BeforeEach blocks are run before It blocks. When multiple BeforeEach blocks are defined in nested +//Describe and Context blocks the outermost BeforeEach blocks are run first. +// +//Like It blocks, BeforeEach blocks can be made asynchronous by providing a body function that accepts +//a Done channel +func BeforeEach(body interface{}, timeout ...float64) bool { + globalSuite.PushBeforeEachNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//JustBeforeEach blocks are run before It blocks but *after* all BeforeEach blocks. For more details, +//read the [documentation](http://onsi.github.io/ginkgo/#separating_creation_and_configuration_) +// +//Like It blocks, BeforeEach blocks can be made asynchronous by providing a body function that accepts +//a Done channel +func JustBeforeEach(body interface{}, timeout ...float64) bool { + globalSuite.PushJustBeforeEachNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//JustAfterEach blocks are run after It blocks but *before* all AfterEach blocks. For more details, +//read the [documentation](http://onsi.github.io/ginkgo/#separating_creation_and_configuration_) +// +//Like It blocks, JustAfterEach blocks can be made asynchronous by providing a body function that accepts +//a Done channel +func JustAfterEach(body interface{}, timeout ...float64) bool { + globalSuite.PushJustAfterEachNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +//AfterEach blocks are run after It blocks. When multiple AfterEach blocks are defined in nested +//Describe and Context blocks the innermost AfterEach blocks are run first. +// +//Like It blocks, AfterEach blocks can be made asynchronous by providing a body function that accepts +//a Done channel +func AfterEach(body interface{}, timeout ...float64) bool { + globalSuite.PushAfterEachNode(body, codelocation.New(1), parseTimeout(timeout...)) + return true +} + +func parseTimeout(timeout ...float64) time.Duration { + if len(timeout) == 0 { + return time.Duration(defaultTimeout * int64(time.Second)) + } else { + return time.Duration(timeout[0] * float64(time.Second)) + } +} diff --git a/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go b/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go new file mode 100644 index 00000000..e3e9cb7c --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go @@ -0,0 +1,48 @@ +package leafnodes + +import ( + "time" + + "github.com/onsi/ginkgo/internal/failer" + "github.com/onsi/ginkgo/types" +) + +type SetupNode struct { + runner *runner +} + +func (node *SetupNode) Run() (outcome types.SpecState, failure types.SpecFailure) { + return node.runner.run() +} + +func (node *SetupNode) Type() types.SpecComponentType { + return node.runner.nodeType +} + +func (node *SetupNode) CodeLocation() types.CodeLocation { + return node.runner.codeLocation +} + +func NewBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { + return &SetupNode{ + runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeBeforeEach, componentIndex), + } +} + +func NewAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { + return &SetupNode{ + runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeAfterEach, componentIndex), + } +} + +func NewJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { + return &SetupNode{ + runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustBeforeEach, componentIndex), + } +} + +func NewJustAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer, componentIndex int) *SetupNode { + return &SetupNode{ + runner: newRunner(body, codeLocation, timeout, failer, types.SpecComponentTypeJustAfterEach, componentIndex), + } +} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/spec.go b/vendor/github.com/onsi/ginkgo/internal/spec/spec.go new file mode 100644 index 00000000..7fd68ee8 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/internal/spec/spec.go @@ -0,0 +1,247 @@ +package spec + +import ( + "fmt" + "io" + "time" + + "sync" + + "github.com/onsi/ginkgo/internal/containernode" + "github.com/onsi/ginkgo/internal/leafnodes" + "github.com/onsi/ginkgo/types" +) + +type Spec struct { + subject leafnodes.SubjectNode + focused bool + announceProgress bool + + containers []*containernode.ContainerNode + + state types.SpecState + runTime time.Duration + startTime time.Time + failure types.SpecFailure + previousFailures bool + + stateMutex *sync.Mutex +} + +func New(subject leafnodes.SubjectNode, containers []*containernode.ContainerNode, announceProgress bool) *Spec { + spec := &Spec{ + subject: subject, + containers: containers, + focused: subject.Flag() == types.FlagTypeFocused, + announceProgress: announceProgress, + stateMutex: &sync.Mutex{}, + } + + spec.processFlag(subject.Flag()) + for i := len(containers) - 1; i >= 0; i-- { + spec.processFlag(containers[i].Flag()) + } + + return spec +} + +func (spec *Spec) processFlag(flag types.FlagType) { + if flag == types.FlagTypeFocused { + spec.focused = true + } else if flag == types.FlagTypePending { + spec.setState(types.SpecStatePending) + } +} + +func (spec *Spec) Skip() { + spec.setState(types.SpecStateSkipped) +} + +func (spec *Spec) Failed() bool { + return spec.getState() == types.SpecStateFailed || spec.getState() == types.SpecStatePanicked || spec.getState() == types.SpecStateTimedOut +} + +func (spec *Spec) Passed() bool { + return spec.getState() == types.SpecStatePassed +} + +func (spec *Spec) Flaked() bool { + return spec.getState() == types.SpecStatePassed && spec.previousFailures +} + +func (spec *Spec) Pending() bool { + return spec.getState() == types.SpecStatePending +} + +func (spec *Spec) Skipped() bool { + return spec.getState() == types.SpecStateSkipped +} + +func (spec *Spec) Focused() bool { + return spec.focused +} + +func (spec *Spec) IsMeasurement() bool { + return spec.subject.Type() == types.SpecComponentTypeMeasure +} + +func (spec *Spec) Summary(suiteID string) *types.SpecSummary { + componentTexts := make([]string, len(spec.containers)+1) + componentCodeLocations := make([]types.CodeLocation, len(spec.containers)+1) + + for i, container := range spec.containers { + componentTexts[i] = container.Text() + componentCodeLocations[i] = container.CodeLocation() + } + + componentTexts[len(spec.containers)] = spec.subject.Text() + componentCodeLocations[len(spec.containers)] = spec.subject.CodeLocation() + + runTime := spec.runTime + if runTime == 0 && !spec.startTime.IsZero() { + runTime = time.Since(spec.startTime) + } + + return &types.SpecSummary{ + IsMeasurement: spec.IsMeasurement(), + NumberOfSamples: spec.subject.Samples(), + ComponentTexts: componentTexts, + ComponentCodeLocations: componentCodeLocations, + State: spec.getState(), + RunTime: runTime, + Failure: spec.failure, + Measurements: spec.measurementsReport(), + SuiteID: suiteID, + } +} + +func (spec *Spec) ConcatenatedString() string { + s := "" + for _, container := range spec.containers { + s += container.Text() + " " + } + + return s + spec.subject.Text() +} + +func (spec *Spec) Run(writer io.Writer) { + if spec.getState() == types.SpecStateFailed { + spec.previousFailures = true + } + + spec.startTime = time.Now() + defer func() { + spec.runTime = time.Since(spec.startTime) + }() + + for sample := 0; sample < spec.subject.Samples(); sample++ { + spec.runSample(sample, writer) + + if spec.getState() != types.SpecStatePassed { + return + } + } +} + +func (spec *Spec) getState() types.SpecState { + spec.stateMutex.Lock() + defer spec.stateMutex.Unlock() + return spec.state +} + +func (spec *Spec) setState(state types.SpecState) { + spec.stateMutex.Lock() + defer spec.stateMutex.Unlock() + spec.state = state +} + +func (spec *Spec) runSample(sample int, writer io.Writer) { + spec.setState(types.SpecStatePassed) + spec.failure = types.SpecFailure{} + innerMostContainerIndexToUnwind := -1 + + defer func() { + for i := innerMostContainerIndexToUnwind; i >= 0; i-- { + container := spec.containers[i] + for _, justAfterEach := range container.SetupNodesOfType(types.SpecComponentTypeJustAfterEach) { + spec.announceSetupNode(writer, "JustAfterEach", container, justAfterEach) + justAfterEachState, justAfterEachFailure := justAfterEach.Run() + if justAfterEachState != types.SpecStatePassed && spec.state == types.SpecStatePassed { + spec.state = justAfterEachState + spec.failure = justAfterEachFailure + } + } + } + + for i := innerMostContainerIndexToUnwind; i >= 0; i-- { + container := spec.containers[i] + for _, afterEach := range container.SetupNodesOfType(types.SpecComponentTypeAfterEach) { + spec.announceSetupNode(writer, "AfterEach", container, afterEach) + afterEachState, afterEachFailure := afterEach.Run() + if afterEachState != types.SpecStatePassed && spec.getState() == types.SpecStatePassed { + spec.setState(afterEachState) + spec.failure = afterEachFailure + } + } + } + }() + + for i, container := range spec.containers { + innerMostContainerIndexToUnwind = i + for _, beforeEach := range container.SetupNodesOfType(types.SpecComponentTypeBeforeEach) { + spec.announceSetupNode(writer, "BeforeEach", container, beforeEach) + s, f := beforeEach.Run() + spec.failure = f + spec.setState(s) + if spec.getState() != types.SpecStatePassed { + return + } + } + } + + for _, container := range spec.containers { + for _, justBeforeEach := range container.SetupNodesOfType(types.SpecComponentTypeJustBeforeEach) { + spec.announceSetupNode(writer, "JustBeforeEach", container, justBeforeEach) + s, f := justBeforeEach.Run() + spec.failure = f + spec.setState(s) + if spec.getState() != types.SpecStatePassed { + return + } + } + } + + spec.announceSubject(writer, spec.subject) + s, f := spec.subject.Run() + spec.failure = f + spec.setState(s) +} + +func (spec *Spec) announceSetupNode(writer io.Writer, nodeType string, container *containernode.ContainerNode, setupNode leafnodes.BasicNode) { + if spec.announceProgress { + s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, container.Text(), setupNode.CodeLocation().String()) + writer.Write([]byte(s)) + } +} + +func (spec *Spec) announceSubject(writer io.Writer, subject leafnodes.SubjectNode) { + if spec.announceProgress { + nodeType := "" + switch subject.Type() { + case types.SpecComponentTypeIt: + nodeType = "It" + case types.SpecComponentTypeMeasure: + nodeType = "Measure" + } + s := fmt.Sprintf("[%s] %s\n %s\n", nodeType, subject.Text(), subject.CodeLocation().String()) + writer.Write([]byte(s)) + } +} + +func (spec *Spec) measurementsReport() map[string]*types.SpecMeasurement { + if !spec.IsMeasurement() || spec.Failed() { + return map[string]*types.SpecMeasurement{} + } + + return spec.subject.(*leafnodes.MeasureNode).MeasurementsReport() +} diff --git a/vendor/github.com/onsi/ginkgo/internal/spec/specs.go b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go new file mode 100644 index 00000000..27c0d1d6 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/internal/spec/specs.go @@ -0,0 +1,144 @@ +package spec + +import ( + "math/rand" + "regexp" + "sort" +) + +type Specs struct { + specs []*Spec + names []string + + hasProgrammaticFocus bool + RegexScansFilePath bool +} + +func NewSpecs(specs []*Spec) *Specs { + names := make([]string, len(specs)) + for i, spec := range specs { + names[i] = spec.ConcatenatedString() + } + return &Specs{ + specs: specs, + names: names, + } +} + +func (e *Specs) Specs() []*Spec { + return e.specs +} + +func (e *Specs) HasProgrammaticFocus() bool { + return e.hasProgrammaticFocus +} + +func (e *Specs) Shuffle(r *rand.Rand) { + sort.Sort(e) + permutation := r.Perm(len(e.specs)) + shuffledSpecs := make([]*Spec, len(e.specs)) + names := make([]string, len(e.specs)) + for i, j := range permutation { + shuffledSpecs[i] = e.specs[j] + names[i] = e.names[j] + } + e.specs = shuffledSpecs + e.names = names +} + +func (e *Specs) ApplyFocus(description string, focusString string, skipString string) { + if focusString == "" && skipString == "" { + e.applyProgrammaticFocus() + } else { + e.applyRegExpFocusAndSkip(description, focusString, skipString) + } +} + +func (e *Specs) applyProgrammaticFocus() { + e.hasProgrammaticFocus = false + for _, spec := range e.specs { + if spec.Focused() && !spec.Pending() { + e.hasProgrammaticFocus = true + break + } + } + + if e.hasProgrammaticFocus { + for _, spec := range e.specs { + if !spec.Focused() { + spec.Skip() + } + } + } +} + +// toMatch returns a byte[] to be used by regex matchers. When adding new behaviours to the matching function, +// this is the place which we append to. +func (e *Specs) toMatch(description string, i int) []byte { + if i > len(e.names) { + return nil + } + if e.RegexScansFilePath { + return []byte( + description + " " + + e.names[i] + " " + + e.specs[i].subject.CodeLocation().FileName) + } else { + return []byte( + description + " " + + e.names[i]) + } +} + +func (e *Specs) applyRegExpFocusAndSkip(description string, focusString string, skipString string) { + var focusFilter *regexp.Regexp + if focusString != "" { + focusFilter = regexp.MustCompile(focusString) + } + var skipFilter *regexp.Regexp + if skipString != "" { + skipFilter = regexp.MustCompile(skipString) + } + + for i, spec := range e.specs { + matchesFocus := true + matchesSkip := false + + toMatch := e.toMatch(description, i) + + if focusFilter != nil { + matchesFocus = focusFilter.Match([]byte(toMatch)) + } + + if skipFilter != nil { + matchesSkip = skipFilter.Match([]byte(toMatch)) + } + + if !matchesFocus || matchesSkip { + spec.Skip() + } + } +} + +func (e *Specs) SkipMeasurements() { + for _, spec := range e.specs { + if spec.IsMeasurement() { + spec.Skip() + } + } +} + +//sort.Interface + +func (e *Specs) Len() int { + return len(e.specs) +} + +func (e *Specs) Less(i, j int) bool { + return e.names[i] < e.names[j] +} + +func (e *Specs) Swap(i, j int) { + e.names[i], e.names[j] = e.names[j], e.names[i] + e.specs[i], e.specs[j] = e.specs[j], e.specs[i] +} diff --git a/vendor/github.com/onsi/ginkgo/internal/suite/suite.go b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go new file mode 100644 index 00000000..3104bbc8 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/internal/suite/suite.go @@ -0,0 +1,190 @@ +package suite + +import ( + "math/rand" + "net/http" + "time" + + "github.com/onsi/ginkgo/internal/spec_iterator" + + "github.com/onsi/ginkgo/config" + "github.com/onsi/ginkgo/internal/containernode" + "github.com/onsi/ginkgo/internal/failer" + "github.com/onsi/ginkgo/internal/leafnodes" + "github.com/onsi/ginkgo/internal/spec" + "github.com/onsi/ginkgo/internal/specrunner" + "github.com/onsi/ginkgo/internal/writer" + "github.com/onsi/ginkgo/reporters" + "github.com/onsi/ginkgo/types" +) + +type ginkgoTestingT interface { + Fail() +} + +type Suite struct { + topLevelContainer *containernode.ContainerNode + currentContainer *containernode.ContainerNode + containerIndex int + beforeSuiteNode leafnodes.SuiteNode + afterSuiteNode leafnodes.SuiteNode + runner *specrunner.SpecRunner + failer *failer.Failer + running bool +} + +func New(failer *failer.Failer) *Suite { + topLevelContainer := containernode.New("[Top Level]", types.FlagTypeNone, types.CodeLocation{}) + + return &Suite{ + topLevelContainer: topLevelContainer, + currentContainer: topLevelContainer, + failer: failer, + containerIndex: 1, + } +} + +func (suite *Suite) Run(t ginkgoTestingT, description string, reporters []reporters.Reporter, writer writer.WriterInterface, config config.GinkgoConfigType) (bool, bool) { + if config.ParallelTotal < 1 { + panic("ginkgo.parallel.total must be >= 1") + } + + if config.ParallelNode > config.ParallelTotal || config.ParallelNode < 1 { + panic("ginkgo.parallel.node is one-indexed and must be <= ginkgo.parallel.total") + } + + r := rand.New(rand.NewSource(config.RandomSeed)) + suite.topLevelContainer.Shuffle(r) + iterator, hasProgrammaticFocus := suite.generateSpecsIterator(description, config) + suite.runner = specrunner.New(description, suite.beforeSuiteNode, iterator, suite.afterSuiteNode, reporters, writer, config) + + suite.running = true + success := suite.runner.Run() + if !success { + t.Fail() + } + return success, hasProgrammaticFocus +} + +func (suite *Suite) generateSpecsIterator(description string, config config.GinkgoConfigType) (spec_iterator.SpecIterator, bool) { + specsSlice := []*spec.Spec{} + suite.topLevelContainer.BackPropagateProgrammaticFocus() + for _, collatedNodes := range suite.topLevelContainer.Collate() { + specsSlice = append(specsSlice, spec.New(collatedNodes.Subject, collatedNodes.Containers, config.EmitSpecProgress)) + } + + specs := spec.NewSpecs(specsSlice) + specs.RegexScansFilePath = config.RegexScansFilePath + + if config.RandomizeAllSpecs { + specs.Shuffle(rand.New(rand.NewSource(config.RandomSeed))) + } + + specs.ApplyFocus(description, config.FocusString, config.SkipString) + + if config.SkipMeasurements { + specs.SkipMeasurements() + } + + var iterator spec_iterator.SpecIterator + + if config.ParallelTotal > 1 { + iterator = spec_iterator.NewParallelIterator(specs.Specs(), config.SyncHost) + resp, err := http.Get(config.SyncHost + "/has-counter") + if err != nil || resp.StatusCode != http.StatusOK { + iterator = spec_iterator.NewShardedParallelIterator(specs.Specs(), config.ParallelTotal, config.ParallelNode) + } + } else { + iterator = spec_iterator.NewSerialIterator(specs.Specs()) + } + + return iterator, specs.HasProgrammaticFocus() +} + +func (suite *Suite) CurrentRunningSpecSummary() (*types.SpecSummary, bool) { + return suite.runner.CurrentSpecSummary() +} + +func (suite *Suite) SetBeforeSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.beforeSuiteNode != nil { + panic("You may only call BeforeSuite once!") + } + suite.beforeSuiteNode = leafnodes.NewBeforeSuiteNode(body, codeLocation, timeout, suite.failer) +} + +func (suite *Suite) SetAfterSuiteNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.afterSuiteNode != nil { + panic("You may only call AfterSuite once!") + } + suite.afterSuiteNode = leafnodes.NewAfterSuiteNode(body, codeLocation, timeout, suite.failer) +} + +func (suite *Suite) SetSynchronizedBeforeSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.beforeSuiteNode != nil { + panic("You may only call BeforeSuite once!") + } + suite.beforeSuiteNode = leafnodes.NewSynchronizedBeforeSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer) +} + +func (suite *Suite) SetSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.afterSuiteNode != nil { + panic("You may only call AfterSuite once!") + } + suite.afterSuiteNode = leafnodes.NewSynchronizedAfterSuiteNode(bodyA, bodyB, codeLocation, timeout, suite.failer) +} + +func (suite *Suite) PushContainerNode(text string, body func(), flag types.FlagType, codeLocation types.CodeLocation) { + container := containernode.New(text, flag, codeLocation) + suite.currentContainer.PushContainerNode(container) + + previousContainer := suite.currentContainer + suite.currentContainer = container + suite.containerIndex++ + + body() + + suite.containerIndex-- + suite.currentContainer = previousContainer +} + +func (suite *Suite) PushItNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.running { + suite.failer.Fail("You may only call It from within a Describe, Context or When", codeLocation) + } + suite.currentContainer.PushSubjectNode(leafnodes.NewItNode(text, body, flag, codeLocation, timeout, suite.failer, suite.containerIndex)) +} + +func (suite *Suite) PushMeasureNode(text string, body interface{}, flag types.FlagType, codeLocation types.CodeLocation, samples int) { + if suite.running { + suite.failer.Fail("You may only call Measure from within a Describe, Context or When", codeLocation) + } + suite.currentContainer.PushSubjectNode(leafnodes.NewMeasureNode(text, body, flag, codeLocation, samples, suite.failer, suite.containerIndex)) +} + +func (suite *Suite) PushBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.running { + suite.failer.Fail("You may only call BeforeEach from within a Describe, Context or When", codeLocation) + } + suite.currentContainer.PushSetupNode(leafnodes.NewBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) +} + +func (suite *Suite) PushJustBeforeEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.running { + suite.failer.Fail("You may only call JustBeforeEach from within a Describe, Context or When", codeLocation) + } + suite.currentContainer.PushSetupNode(leafnodes.NewJustBeforeEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) +} + +func (suite *Suite) PushJustAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.running { + suite.failer.Fail("You may only call JustAfterEach from within a Describe or Context", codeLocation) + } + suite.currentContainer.PushSetupNode(leafnodes.NewJustAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) +} + +func (suite *Suite) PushAfterEachNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) { + if suite.running { + suite.failer.Fail("You may only call AfterEach from within a Describe, Context or When", codeLocation) + } + suite.currentContainer.PushSetupNode(leafnodes.NewAfterEachNode(body, codeLocation, timeout, suite.failer, suite.containerIndex)) +} diff --git a/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go new file mode 100644 index 00000000..2c9f3c79 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go @@ -0,0 +1,152 @@ +/* + +JUnit XML Reporter for Ginkgo + +For usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output + +*/ + +package reporters + +import ( + "encoding/xml" + "fmt" + "math" + "os" + "strings" + + "github.com/onsi/ginkgo/config" + "github.com/onsi/ginkgo/types" +) + +type JUnitTestSuite struct { + XMLName xml.Name `xml:"testsuite"` + TestCases []JUnitTestCase `xml:"testcase"` + Name string `xml:"name,attr"` + Tests int `xml:"tests,attr"` + Failures int `xml:"failures,attr"` + Errors int `xml:"errors,attr"` + Time float64 `xml:"time,attr"` +} + +type JUnitTestCase struct { + Name string `xml:"name,attr"` + ClassName string `xml:"classname,attr"` + FailureMessage *JUnitFailureMessage `xml:"failure,omitempty"` + Skipped *JUnitSkipped `xml:"skipped,omitempty"` + Time float64 `xml:"time,attr"` + SystemOut string `xml:"system-out,omitempty"` +} + +type JUnitFailureMessage struct { + Type string `xml:"type,attr"` + Message string `xml:",chardata"` +} + +type JUnitSkipped struct { + XMLName xml.Name `xml:"skipped"` +} + +type JUnitReporter struct { + suite JUnitTestSuite + filename string + testSuiteName string +} + +//NewJUnitReporter creates a new JUnit XML reporter. The XML will be stored in the passed in filename. +func NewJUnitReporter(filename string) *JUnitReporter { + return &JUnitReporter{ + filename: filename, + } +} + +func (reporter *JUnitReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) { + reporter.suite = JUnitTestSuite{ + Name: summary.SuiteDescription, + TestCases: []JUnitTestCase{}, + } + reporter.testSuiteName = summary.SuiteDescription +} + +func (reporter *JUnitReporter) SpecWillRun(specSummary *types.SpecSummary) { +} + +func (reporter *JUnitReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) { + reporter.handleSetupSummary("BeforeSuite", setupSummary) +} + +func (reporter *JUnitReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) { + reporter.handleSetupSummary("AfterSuite", setupSummary) +} + +func failureMessage(failure types.SpecFailure) string { + return fmt.Sprintf("%s\n%s\n%s", failure.ComponentCodeLocation.String(), failure.Message, failure.Location.String()) +} + +func (reporter *JUnitReporter) handleSetupSummary(name string, setupSummary *types.SetupSummary) { + if setupSummary.State != types.SpecStatePassed { + testCase := JUnitTestCase{ + Name: name, + ClassName: reporter.testSuiteName, + } + + testCase.FailureMessage = &JUnitFailureMessage{ + Type: reporter.failureTypeForState(setupSummary.State), + Message: failureMessage(setupSummary.Failure), + } + testCase.SystemOut = setupSummary.CapturedOutput + testCase.Time = setupSummary.RunTime.Seconds() + reporter.suite.TestCases = append(reporter.suite.TestCases, testCase) + } +} + +func (reporter *JUnitReporter) SpecDidComplete(specSummary *types.SpecSummary) { + testCase := JUnitTestCase{ + Name: strings.Join(specSummary.ComponentTexts[1:], " "), + ClassName: reporter.testSuiteName, + } + if specSummary.State == types.SpecStateFailed || specSummary.State == types.SpecStateTimedOut || specSummary.State == types.SpecStatePanicked { + testCase.FailureMessage = &JUnitFailureMessage{ + Type: reporter.failureTypeForState(specSummary.State), + Message: failureMessage(specSummary.Failure), + } + testCase.SystemOut = specSummary.CapturedOutput + } + if specSummary.State == types.SpecStateSkipped || specSummary.State == types.SpecStatePending { + testCase.Skipped = &JUnitSkipped{} + } + testCase.Time = specSummary.RunTime.Seconds() + reporter.suite.TestCases = append(reporter.suite.TestCases, testCase) +} + +func (reporter *JUnitReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { + reporter.suite.Tests = summary.NumberOfSpecsThatWillBeRun + reporter.suite.Time = math.Trunc(summary.RunTime.Seconds()*1000) / 1000 + reporter.suite.Failures = summary.NumberOfFailedSpecs + reporter.suite.Errors = 0 + file, err := os.Create(reporter.filename) + if err != nil { + fmt.Printf("Failed to create JUnit report file: %s\n\t%s", reporter.filename, err.Error()) + } + defer file.Close() + file.WriteString(xml.Header) + encoder := xml.NewEncoder(file) + encoder.Indent(" ", " ") + err = encoder.Encode(reporter.suite) + if err != nil { + fmt.Printf("Failed to generate JUnit report\n\t%s", err.Error()) + } +} + +func (reporter *JUnitReporter) failureTypeForState(state types.SpecState) string { + switch state { + case types.SpecStateFailed: + return "Failure" + case types.SpecStateTimedOut: + return "Timeout" + case types.SpecStatePanicked: + return "Panic" + default: + return "" + } +} diff --git a/vendor/github.com/onsi/ginkgo/types/types.go b/vendor/github.com/onsi/ginkgo/types/types.go new file mode 100644 index 00000000..0e89521b --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/types/types.go @@ -0,0 +1,174 @@ +package types + +import ( + "strconv" + "time" +) + +const GINKGO_FOCUS_EXIT_CODE = 197 + +/* +SuiteSummary represents the a summary of the test suite and is passed to both +Reporter.SpecSuiteWillBegin +Reporter.SpecSuiteDidEnd + +this is unfortunate as these two methods should receive different objects. When running in parallel +each node does not deterministically know how many specs it will end up running. + +Unfortunately making such a change would break backward compatibility. + +Until Ginkgo 2.0 comes out we will continue to reuse this struct but populate unkown fields +with -1. +*/ +type SuiteSummary struct { + SuiteDescription string + SuiteSucceeded bool + SuiteID string + + NumberOfSpecsBeforeParallelization int + NumberOfTotalSpecs int + NumberOfSpecsThatWillBeRun int + NumberOfPendingSpecs int + NumberOfSkippedSpecs int + NumberOfPassedSpecs int + NumberOfFailedSpecs int + // Flaked specs are those that failed initially, but then passed on a + // subsequent try. + NumberOfFlakedSpecs int + RunTime time.Duration +} + +type SpecSummary struct { + ComponentTexts []string + ComponentCodeLocations []CodeLocation + + State SpecState + RunTime time.Duration + Failure SpecFailure + IsMeasurement bool + NumberOfSamples int + Measurements map[string]*SpecMeasurement + + CapturedOutput string + SuiteID string +} + +func (s SpecSummary) HasFailureState() bool { + return s.State.IsFailure() +} + +func (s SpecSummary) TimedOut() bool { + return s.State == SpecStateTimedOut +} + +func (s SpecSummary) Panicked() bool { + return s.State == SpecStatePanicked +} + +func (s SpecSummary) Failed() bool { + return s.State == SpecStateFailed +} + +func (s SpecSummary) Passed() bool { + return s.State == SpecStatePassed +} + +func (s SpecSummary) Skipped() bool { + return s.State == SpecStateSkipped +} + +func (s SpecSummary) Pending() bool { + return s.State == SpecStatePending +} + +type SetupSummary struct { + ComponentType SpecComponentType + CodeLocation CodeLocation + + State SpecState + RunTime time.Duration + Failure SpecFailure + + CapturedOutput string + SuiteID string +} + +type SpecFailure struct { + Message string + Location CodeLocation + ForwardedPanic string + + ComponentIndex int + ComponentType SpecComponentType + ComponentCodeLocation CodeLocation +} + +type SpecMeasurement struct { + Name string + Info interface{} + Order int + + Results []float64 + + Smallest float64 + Largest float64 + Average float64 + StdDeviation float64 + + SmallestLabel string + LargestLabel string + AverageLabel string + Units string + Precision int +} + +func (s SpecMeasurement) PrecisionFmt() string { + if s.Precision == 0 { + return "%f" + } + + str := strconv.Itoa(s.Precision) + + return "%." + str + "f" +} + +type SpecState uint + +const ( + SpecStateInvalid SpecState = iota + + SpecStatePending + SpecStateSkipped + SpecStatePassed + SpecStateFailed + SpecStatePanicked + SpecStateTimedOut +) + +func (state SpecState) IsFailure() bool { + return state == SpecStateTimedOut || state == SpecStatePanicked || state == SpecStateFailed +} + +type SpecComponentType uint + +const ( + SpecComponentTypeInvalid SpecComponentType = iota + + SpecComponentTypeContainer + SpecComponentTypeBeforeSuite + SpecComponentTypeAfterSuite + SpecComponentTypeBeforeEach + SpecComponentTypeJustBeforeEach + SpecComponentTypeJustAfterEach + SpecComponentTypeAfterEach + SpecComponentTypeIt + SpecComponentTypeMeasure +) + +type FlagType uint + +const ( + FlagTypeNone FlagType = iota + FlagTypeFocused + FlagTypePending +) diff --git a/vendor/github.com/onsi/gomega/.travis.yml b/vendor/github.com/onsi/gomega/.travis.yml new file mode 100644 index 00000000..2420a5d0 --- /dev/null +++ b/vendor/github.com/onsi/gomega/.travis.yml @@ -0,0 +1,17 @@ +language: go + +go: + - 1.10.x + - 1.11.x + - 1.12.x + +env: + - GO111MODULE=on + +install: + - go get -v ./... + - go build ./... + - go get github.com/onsi/ginkgo + - go install github.com/onsi/ginkgo/ginkgo + +script: make test diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md new file mode 100644 index 00000000..5d1eda83 --- /dev/null +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -0,0 +1,136 @@ +## 1.5.0 + +### Features + +- Added MatchKeys matchers [8b909fc] + +### Fixes and Minor Improvements + +- Add type aliases to remove stuttering [03b0461] +- Don't run session_test.go on windows (#324) [5533ce8] + +## 1.4.3 + +### Fixes: + +- ensure file name and line numbers are correctly reported for XUnit [6fff58f] +- Fixed matcher for content-type (#305) [69d9b43] + +## 1.4.2 + +### Fixes: + +- Add go.mod and go.sum files to define the gomega go module [f3de367, a085d30] +- Work around go vet issue with Go v1.11 (#300) [40dd6ad] +- Better output when using with go XUnit-style tests, fixes #255 (#297) [29a4b97] +- Fix MatchJSON fail to parse json.RawMessage (#298) [ae19f1b] +- show threshold in failure message of BeNumericallyMatcher (#293) [4bbecc8] + +## 1.4.1 + +### Fixes: + +- Update documentation formatting and examples (#289) [9be8410] +- allow 'Receive' matcher to be used with concrete types (#286) [41673fd] +- Fix data race in ghttp server (#283) [7ac6b01] +- Travis badge should only show master [cc102ab] + +## 1.4.0 + +### Features +- Make string pretty diff user configurable (#273) [eb112ce, 649b44d] + +### Fixes +- Use httputil.DumpRequest to pretty-print unhandled requests (#278) [a4ff0fc, b7d1a52] +- fix typo floa32 > float32 (#272) [041ae3b, 6e33911] +- Fix link to documentation on adding your own matchers (#270) [bb2c830, fcebc62] +- Use setters and getters to avoid race condition (#262) [13057c3, a9c79f1] +- Avoid sending a signal if the process is not alive (#259) [b8043e5, 4fc1762] +- Improve message from AssignableToTypeOf when expected value is nil (#281) [9c1fb20] + +## 1.3.0 + +Improvements: + +- The `Equal` matcher matches byte slices more performantly. +- Improved how `MatchError` matches error strings. +- `MatchXML` ignores the order of xml node attributes. +- Improve support for XUnit style golang tests. ([#254](https://github.com/onsi/gomega/issues/254)) + +Bug Fixes: + +- Diff generation now handles multi-byte sequences correctly. +- Multiple goroutines can now call `gexec.Build` concurrently. + +## 1.2.0 + +Improvements: + +- Added `BeSent` which attempts to send a value down a channel and fails if the attempt blocks. Can be paired with `Eventually` to safely send a value down a channel with a timeout. +- `Ω`, `Expect`, `Eventually`, and `Consistently` now immediately `panic` if there is no registered fail handler. This is always a mistake that can hide failing tests. +- `Receive()` no longer errors when passed a closed channel, it's perfectly fine to attempt to read from a closed channel so Ω(c).Should(Receive()) always fails and Ω(c).ShoudlNot(Receive()) always passes with a closed channel. +- Added `HavePrefix` and `HaveSuffix` matchers. +- `ghttp` can now handle concurrent requests. +- Added `Succeed` which allows one to write `Ω(MyFunction()).Should(Succeed())`. +- Improved `ghttp`'s behavior around failing assertions and panics: + - If a registered handler makes a failing assertion `ghttp` will return `500`. + - If a registered handler panics, `ghttp` will return `500` *and* fail the test. This is new behavior that may cause existing code to break. This code is almost certainly incorrect and creating a false positive. +- `ghttp` servers can take an `io.Writer`. `ghttp` will write a line to the writer when each request arrives. +- Added `WithTransform` matcher to allow munging input data before feeding into the relevant matcher +- Added boolean `And`, `Or`, and `Not` matchers to allow creating composite matchers +- Added `gbytes.TimeoutCloser`, `gbytes.TimeoutReader`, and `gbytes.TimeoutWriter` - these are convenience wrappers that timeout if the underlying Closer/Reader/Writer does not return within the alloted time. +- Added `gbytes.BufferReader` - this constructs a `gbytes.Buffer` that asynchronously reads the passed-in `io.Reader` into its buffer. + +Bug Fixes: +- gexec: `session.Wait` now uses `EventuallyWithOffset` to get the right line number in the failure. +- `ContainElement` no longer bails if a passed-in matcher errors. + +## 1.0 (8/2/2014) + +No changes. Dropping "beta" from the version number. + +## 1.0.0-beta (7/8/2014) +Breaking Changes: + +- Changed OmegaMatcher interface. Instead of having `Match` return failure messages, two new methods `FailureMessage` and `NegatedFailureMessage` are called instead. +- Moved and renamed OmegaFailHandler to types.GomegaFailHandler and OmegaMatcher to types.GomegaMatcher. Any references to OmegaMatcher in any custom matchers will need to be changed to point to types.GomegaMatcher + +New Test-Support Features: + +- `ghttp`: supports testing http clients + - Provides a flexible fake http server + - Provides a collection of chainable http handlers that perform assertions. +- `gbytes`: supports making ordered assertions against streams of data + - Provides a `gbytes.Buffer` + - Provides a `Say` matcher to perform ordered assertions against output data +- `gexec`: supports testing external processes + - Provides support for building Go binaries + - Wraps and starts `exec.Cmd` commands + - Makes it easy to assert against stdout and stderr + - Makes it easy to send signals and wait for processes to exit + - Provides an `Exit` matcher to assert against exit code. + +DSL Changes: + +- `Eventually` and `Consistently` can accept `time.Duration` interval and polling inputs. +- The default timeouts for `Eventually` and `Consistently` are now configurable. + +New Matchers: + +- `ConsistOf`: order-independent assertion against the elements of an array/slice or keys of a map. +- `BeTemporally`: like `BeNumerically` but for `time.Time` +- `HaveKeyWithValue`: asserts a map has a given key with the given value. + +Updated Matchers: + +- `Receive` matcher can take a matcher as an argument and passes only if the channel under test receives an objet that satisfies the passed-in matcher. +- Matchers that implement `MatchMayChangeInTheFuture(actual interface{}) bool` can inform `Eventually` and/or `Consistently` when a match has no chance of changing status in the future. For example, `Receive` returns `false` when a channel is closed. + +Misc: + +- Start using semantic versioning +- Start maintaining changelog + +Major refactor: + +- Pull out Gomega's internal to `internal` diff --git a/vendor/github.com/onsi/gomega/Makefile b/vendor/github.com/onsi/gomega/Makefile new file mode 100644 index 00000000..c92cd56e --- /dev/null +++ b/vendor/github.com/onsi/gomega/Makefile @@ -0,0 +1,6 @@ +test: + [ -z "`gofmt -s -w -l -e .`" ] + go vet + ginkgo -p -r --randomizeAllSpecs --failOnPending --randomizeSuites --race + +.PHONY: test diff --git a/vendor/github.com/onsi/gomega/ghttp/handlers.go b/vendor/github.com/onsi/gomega/ghttp/handlers.go new file mode 100644 index 00000000..894eae6d --- /dev/null +++ b/vendor/github.com/onsi/gomega/ghttp/handlers.go @@ -0,0 +1,322 @@ +package ghttp + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/types" +) + +//CombineHandler takes variadic list of handlers and produces one handler +//that calls each handler in order. +func CombineHandlers(handlers ...http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + for _, handler := range handlers { + handler(w, req) + } + } +} + +//VerifyRequest returns a handler that verifies that a request uses the specified method to connect to the specified path +//You may also pass in an optional rawQuery string which is tested against the request's `req.URL.RawQuery` +// +//For path, you may pass in a string, in which case strict equality will be applied +//Alternatively you can pass in a matcher (ContainSubstring("/foo") and MatchRegexp("/foo/[a-f0-9]+") for example) +func VerifyRequest(method string, path interface{}, rawQuery ...string) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + Expect(req.Method).Should(Equal(method), "Method mismatch") + switch p := path.(type) { + case types.GomegaMatcher: + Expect(req.URL.Path).Should(p, "Path mismatch") + default: + Expect(req.URL.Path).Should(Equal(path), "Path mismatch") + } + if len(rawQuery) > 0 { + values, err := url.ParseQuery(rawQuery[0]) + Expect(err).ShouldNot(HaveOccurred(), "Expected RawQuery is malformed") + + Expect(req.URL.Query()).Should(Equal(values), "RawQuery mismatch") + } + } +} + +//VerifyContentType returns a handler that verifies that a request has a Content-Type header set to the +//specified value +func VerifyContentType(contentType string) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + Expect(req.Header.Get("Content-Type")).Should(Equal(contentType)) + } +} + +//VerifyMimeType returns a handler that verifies that a request has a specified mime type set +//in Content-Type header +func VerifyMimeType(mimeType string) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + Expect(strings.Split(req.Header.Get("Content-Type"), ";")[0]).Should(Equal(mimeType)) + } +} + +//VerifyBasicAuth returns a handler that verifies the request contains a BasicAuth Authorization header +//matching the passed in username and password +func VerifyBasicAuth(username string, password string) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + auth := req.Header.Get("Authorization") + Expect(auth).ShouldNot(Equal(""), "Authorization header must be specified") + + decoded, err := base64.StdEncoding.DecodeString(auth[6:]) + Expect(err).ShouldNot(HaveOccurred()) + + Expect(string(decoded)).Should(Equal(fmt.Sprintf("%s:%s", username, password)), "Authorization mismatch") + } +} + +//VerifyHeader returns a handler that verifies the request contains the passed in headers. +//The passed in header keys are first canonicalized via http.CanonicalHeaderKey. +// +//The request must contain *all* the passed in headers, but it is allowed to have additional headers +//beyond the passed in set. +func VerifyHeader(header http.Header) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + for key, values := range header { + key = http.CanonicalHeaderKey(key) + Expect(req.Header[key]).Should(Equal(values), "Header mismatch for key: %s", key) + } + } +} + +//VerifyHeaderKV returns a handler that verifies the request contains a header matching the passed in key and values +//(recall that a `http.Header` is a mapping from string (key) to []string (values)) +//It is a convenience wrapper around `VerifyHeader` that allows you to avoid having to create an `http.Header` object. +func VerifyHeaderKV(key string, values ...string) http.HandlerFunc { + return VerifyHeader(http.Header{key: values}) +} + +//VerifyBody returns a handler that verifies that the body of the request matches the passed in byte array. +//It does this using Equal(). +func VerifyBody(expectedBody []byte) http.HandlerFunc { + return CombineHandlers( + func(w http.ResponseWriter, req *http.Request) { + body, err := ioutil.ReadAll(req.Body) + req.Body.Close() + Expect(err).ShouldNot(HaveOccurred()) + Expect(body).Should(Equal(expectedBody), "Body Mismatch") + }, + ) +} + +//VerifyJSON returns a handler that verifies that the body of the request is a valid JSON representation +//matching the passed in JSON string. It does this using Gomega's MatchJSON method +// +//VerifyJSON also verifies that the request's content type is application/json +func VerifyJSON(expectedJSON string) http.HandlerFunc { + return CombineHandlers( + VerifyMimeType("application/json"), + func(w http.ResponseWriter, req *http.Request) { + body, err := ioutil.ReadAll(req.Body) + req.Body.Close() + Expect(err).ShouldNot(HaveOccurred()) + Expect(body).Should(MatchJSON(expectedJSON), "JSON Mismatch") + }, + ) +} + +//VerifyJSONRepresenting is similar to VerifyJSON. Instead of taking a JSON string, however, it +//takes an arbitrary JSON-encodable object and verifies that the requests's body is a JSON representation +//that matches the object +func VerifyJSONRepresenting(object interface{}) http.HandlerFunc { + data, err := json.Marshal(object) + Expect(err).ShouldNot(HaveOccurred()) + return CombineHandlers( + VerifyContentType("application/json"), + VerifyJSON(string(data)), + ) +} + +//VerifyForm returns a handler that verifies a request contains the specified form values. +// +//The request must contain *all* of the specified values, but it is allowed to have additional +//form values beyond the passed in set. +func VerifyForm(values url.Values) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + err := r.ParseForm() + Expect(err).ShouldNot(HaveOccurred()) + for key, vals := range values { + Expect(r.Form[key]).Should(Equal(vals), "Form mismatch for key: %s", key) + } + } +} + +//VerifyFormKV returns a handler that verifies a request contains a form key with the specified values. +// +//It is a convenience wrapper around `VerifyForm` that lets you avoid having to create a `url.Values` object. +func VerifyFormKV(key string, values ...string) http.HandlerFunc { + return VerifyForm(url.Values{key: values}) +} + +//VerifyProtoRepresenting returns a handler that verifies that the body of the request is a valid protobuf +//representation of the passed message. +// +//VerifyProtoRepresenting also verifies that the request's content type is application/x-protobuf +func VerifyProtoRepresenting(expected proto.Message) http.HandlerFunc { + return CombineHandlers( + VerifyContentType("application/x-protobuf"), + func(w http.ResponseWriter, req *http.Request) { + body, err := ioutil.ReadAll(req.Body) + Expect(err).ShouldNot(HaveOccurred()) + req.Body.Close() + + expectedType := reflect.TypeOf(expected) + actualValuePtr := reflect.New(expectedType.Elem()) + + actual, ok := actualValuePtr.Interface().(proto.Message) + Expect(ok).Should(BeTrue(), "Message value is not a proto.Message") + + err = proto.Unmarshal(body, actual) + Expect(err).ShouldNot(HaveOccurred(), "Failed to unmarshal protobuf") + + Expect(actual).Should(Equal(expected), "ProtoBuf Mismatch") + }, + ) +} + +func copyHeader(src http.Header, dst http.Header) { + for key, value := range src { + dst[key] = value + } +} + +/* +RespondWith returns a handler that responds to a request with the specified status code and body + +Body may be a string or []byte + +Also, RespondWith can be given an optional http.Header. The headers defined therein will be added to the response headers. +*/ +func RespondWith(statusCode int, body interface{}, optionalHeader ...http.Header) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + if len(optionalHeader) == 1 { + copyHeader(optionalHeader[0], w.Header()) + } + w.WriteHeader(statusCode) + switch x := body.(type) { + case string: + w.Write([]byte(x)) + case []byte: + w.Write(x) + default: + Expect(body).Should(BeNil(), "Invalid type for body. Should be string or []byte.") + } + } +} + +/* +RespondWithPtr returns a handler that responds to a request with the specified status code and body + +Unlike RespondWith, you pass RepondWithPtr a pointer to the status code and body allowing different tests +to share the same setup but specify different status codes and bodies. + +Also, RespondWithPtr can be given an optional http.Header. The headers defined therein will be added to the response headers. +Since the http.Header can be mutated after the fact you don't need to pass in a pointer. +*/ +func RespondWithPtr(statusCode *int, body interface{}, optionalHeader ...http.Header) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + if len(optionalHeader) == 1 { + copyHeader(optionalHeader[0], w.Header()) + } + w.WriteHeader(*statusCode) + if body != nil { + switch x := (body).(type) { + case *string: + w.Write([]byte(*x)) + case *[]byte: + w.Write(*x) + default: + Expect(body).Should(BeNil(), "Invalid type for body. Should be string or []byte.") + } + } + } +} + +/* +RespondWithJSONEncoded returns a handler that responds to a request with the specified status code and a body +containing the JSON-encoding of the passed in object + +Also, RespondWithJSONEncoded can be given an optional http.Header. The headers defined therein will be added to the response headers. +*/ +func RespondWithJSONEncoded(statusCode int, object interface{}, optionalHeader ...http.Header) http.HandlerFunc { + data, err := json.Marshal(object) + Expect(err).ShouldNot(HaveOccurred()) + + var headers http.Header + if len(optionalHeader) == 1 { + headers = optionalHeader[0] + } else { + headers = make(http.Header) + } + if _, found := headers["Content-Type"]; !found { + headers["Content-Type"] = []string{"application/json"} + } + return RespondWith(statusCode, string(data), headers) +} + +/* +RespondWithJSONEncodedPtr behaves like RespondWithJSONEncoded but takes a pointer +to a status code and object. + +This allows different tests to share the same setup but specify different status codes and JSON-encoded +objects. + +Also, RespondWithJSONEncodedPtr can be given an optional http.Header. The headers defined therein will be added to the response headers. +Since the http.Header can be mutated after the fact you don't need to pass in a pointer. +*/ +func RespondWithJSONEncodedPtr(statusCode *int, object interface{}, optionalHeader ...http.Header) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + data, err := json.Marshal(object) + Expect(err).ShouldNot(HaveOccurred()) + var headers http.Header + if len(optionalHeader) == 1 { + headers = optionalHeader[0] + } else { + headers = make(http.Header) + } + if _, found := headers["Content-Type"]; !found { + headers["Content-Type"] = []string{"application/json"} + } + copyHeader(headers, w.Header()) + w.WriteHeader(*statusCode) + w.Write(data) + } +} + +//RespondWithProto returns a handler that responds to a request with the specified status code and a body +//containing the protobuf serialization of the provided message. +// +//Also, RespondWithProto can be given an optional http.Header. The headers defined therein will be added to the response headers. +func RespondWithProto(statusCode int, message proto.Message, optionalHeader ...http.Header) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + data, err := proto.Marshal(message) + Expect(err).ShouldNot(HaveOccurred()) + + var headers http.Header + if len(optionalHeader) == 1 { + headers = optionalHeader[0] + } else { + headers = make(http.Header) + } + if _, found := headers["Content-Type"]; !found { + headers["Content-Type"] = []string{"application/x-protobuf"} + } + copyHeader(headers, w.Header()) + + w.WriteHeader(statusCode) + w.Write(data) + } +} diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go new file mode 100644 index 00000000..448d595d --- /dev/null +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -0,0 +1,429 @@ +/* +Gomega is the Ginkgo BDD-style testing framework's preferred matcher library. + +The godoc documentation describes Gomega's API. More comprehensive documentation (with examples!) is available at http://onsi.github.io/gomega/ + +Gomega on Github: http://github.com/onsi/gomega + +Learn more about Ginkgo online: http://onsi.github.io/ginkgo + +Ginkgo on Github: http://github.com/onsi/ginkgo + +Gomega is MIT-Licensed +*/ +package gomega + +import ( + "fmt" + "reflect" + "time" + + "github.com/onsi/gomega/internal/assertion" + "github.com/onsi/gomega/internal/asyncassertion" + "github.com/onsi/gomega/internal/testingtsupport" + "github.com/onsi/gomega/types" +) + +const GOMEGA_VERSION = "1.5.0" + +const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil. +If you're using Ginkgo then you probably forgot to put your assertion in an It(). +Alternatively, you may have forgotten to register a fail handler with RegisterFailHandler() or RegisterTestingT(). +Depending on your vendoring solution you may be inadvertently importing gomega and subpackages (e.g. ghhtp, gexec,...) from different locations. +` + +var globalFailWrapper *types.GomegaFailWrapper + +var defaultEventuallyTimeout = time.Second +var defaultEventuallyPollingInterval = 10 * time.Millisecond +var defaultConsistentlyDuration = 100 * time.Millisecond +var defaultConsistentlyPollingInterval = 10 * time.Millisecond + +// RegisterFailHandler connects Ginkgo to Gomega. When a matcher fails +// the fail handler passed into RegisterFailHandler is called. +func RegisterFailHandler(handler types.GomegaFailHandler) { + RegisterFailHandlerWithT(testingtsupport.EmptyTWithHelper{}, handler) +} + +// RegisterFailHandlerWithT ensures that the given types.TWithHelper and fail handler +// are used globally. +func RegisterFailHandlerWithT(t types.TWithHelper, handler types.GomegaFailHandler) { + if handler == nil { + globalFailWrapper = nil + return + } + + globalFailWrapper = &types.GomegaFailWrapper{ + Fail: handler, + TWithHelper: t, + } +} + +// RegisterTestingT connects Gomega to Golang's XUnit style +// Testing.T tests. It is now deprecated and you should use NewWithT() instead. +// +// Legacy Documentation: +// +// You'll need to call this at the top of each XUnit style test: +// +// func TestFarmHasCow(t *testing.T) { +// RegisterTestingT(t) +// +// f := farm.New([]string{"Cow", "Horse"}) +// Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") +// } +// +// Note that this *testing.T is registered *globally* by Gomega (this is why you don't have to +// pass `t` down to the matcher itself). This means that you cannot run the XUnit style tests +// in parallel as the global fail handler cannot point to more than one testing.T at a time. +// +// NewWithT() does not have this limitation +// +// (As an aside: Ginkgo gets around this limitation by running parallel tests in different *processes*). +func RegisterTestingT(t types.GomegaTestingT) { + tWithHelper, hasHelper := t.(types.TWithHelper) + if !hasHelper { + RegisterFailHandler(testingtsupport.BuildTestingTGomegaFailWrapper(t).Fail) + return + } + RegisterFailHandlerWithT(tWithHelper, testingtsupport.BuildTestingTGomegaFailWrapper(t).Fail) +} + +// InterceptGomegaFailures runs a given callback and returns an array of +// failure messages generated by any Gomega assertions within the callback. +// +// This is accomplished by temporarily replacing the *global* fail handler +// with a fail handler that simply annotates failures. The original fail handler +// is reset when InterceptGomegaFailures returns. +// +// This is most useful when testing custom matchers, but can also be used to check +// on a value using a Gomega assertion without causing a test failure. +func InterceptGomegaFailures(f func()) []string { + originalHandler := globalFailWrapper.Fail + failures := []string{} + RegisterFailHandler(func(message string, callerSkip ...int) { + failures = append(failures, message) + }) + f() + RegisterFailHandler(originalHandler) + return failures +} + +// Ω wraps an actual value allowing assertions to be made on it: +// Ω("foo").Should(Equal("foo")) +// +// If Ω is passed more than one argument it will pass the *first* argument to the matcher. +// All subsequent arguments will be required to be nil/zero. +// +// This is convenient if you want to make an assertion on a method/function that returns +// a value and an error - a common patter in Go. +// +// For example, given a function with signature: +// func MyAmazingThing() (int, error) +// +// Then: +// Ω(MyAmazingThing()).Should(Equal(3)) +// Will succeed only if `MyAmazingThing()` returns `(3, nil)` +// +// Ω and Expect are identical +func Ω(actual interface{}, extra ...interface{}) Assertion { + return ExpectWithOffset(0, actual, extra...) +} + +// Expect wraps an actual value allowing assertions to be made on it: +// Expect("foo").To(Equal("foo")) +// +// If Expect is passed more than one argument it will pass the *first* argument to the matcher. +// All subsequent arguments will be required to be nil/zero. +// +// This is convenient if you want to make an assertion on a method/function that returns +// a value and an error - a common patter in Go. +// +// For example, given a function with signature: +// func MyAmazingThing() (int, error) +// +// Then: +// Expect(MyAmazingThing()).Should(Equal(3)) +// Will succeed only if `MyAmazingThing()` returns `(3, nil)` +// +// Expect and Ω are identical +func Expect(actual interface{}, extra ...interface{}) Assertion { + return ExpectWithOffset(0, actual, extra...) +} + +// ExpectWithOffset wraps an actual value allowing assertions to be made on it: +// ExpectWithOffset(1, "foo").To(Equal("foo")) +// +// Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument +// this is used to modify the call-stack offset when computing line numbers. +// +// This is most useful in helper functions that make assertions. If you want Gomega's +// error message to refer to the calling line in the test (as opposed to the line in the helper function) +// set the first argument of `ExpectWithOffset` appropriately. +func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Assertion { + if globalFailWrapper == nil { + panic(nilFailHandlerPanic) + } + return assertion.New(actual, globalFailWrapper, offset, extra...) +} + +// Eventually wraps an actual value allowing assertions to be made on it. +// The assertion is tried periodically until it passes or a timeout occurs. +// +// Both the timeout and polling interval are configurable as optional arguments: +// The first optional argument is the timeout +// The second optional argument is the polling interval +// +// Both intervals can either be specified as time.Duration, parsable duration strings or as floats/integers. In the +// last case they are interpreted as seconds. +// +// If Eventually is passed an actual that is a function taking no arguments and returning at least one value, +// then Eventually will call the function periodically and try the matcher against the function's first return value. +// +// Example: +// +// Eventually(func() int { +// return thingImPolling.Count() +// }).Should(BeNumerically(">=", 17)) +// +// Note that this example could be rewritten: +// +// Eventually(thingImPolling.Count).Should(BeNumerically(">=", 17)) +// +// If the function returns more than one value, then Eventually will pass the first value to the matcher and +// assert that all other values are nil/zero. +// This allows you to pass Eventually a function that returns a value and an error - a common pattern in Go. +// +// For example, consider a method that returns a value and an error: +// func FetchFromDB() (string, error) +// +// Then +// Eventually(FetchFromDB).Should(Equal("hasselhoff")) +// +// Will pass only if the the returned error is nil and the returned string passes the matcher. +// +// Eventually's default timeout is 1 second, and its default polling interval is 10ms +func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { + return EventuallyWithOffset(0, actual, intervals...) +} + +// EventuallyWithOffset operates like Eventually but takes an additional +// initial argument to indicate an offset in the call stack. This is useful when building helper +// functions that contain matchers. To learn more, read about `ExpectWithOffset`. +func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { + if globalFailWrapper == nil { + panic(nilFailHandlerPanic) + } + timeoutInterval := defaultEventuallyTimeout + pollingInterval := defaultEventuallyPollingInterval + if len(intervals) > 0 { + timeoutInterval = toDuration(intervals[0]) + } + if len(intervals) > 1 { + pollingInterval = toDuration(intervals[1]) + } + return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, globalFailWrapper, timeoutInterval, pollingInterval, offset) +} + +// Consistently wraps an actual value allowing assertions to be made on it. +// The assertion is tried periodically and is required to pass for a period of time. +// +// Both the total time and polling interval are configurable as optional arguments: +// The first optional argument is the duration that Consistently will run for +// The second optional argument is the polling interval +// +// Both intervals can either be specified as time.Duration, parsable duration strings or as floats/integers. In the +// last case they are interpreted as seconds. +// +// If Consistently is passed an actual that is a function taking no arguments and returning at least one value, +// then Consistently will call the function periodically and try the matcher against the function's first return value. +// +// If the function returns more than one value, then Consistently will pass the first value to the matcher and +// assert that all other values are nil/zero. +// This allows you to pass Consistently a function that returns a value and an error - a common pattern in Go. +// +// Consistently is useful in cases where you want to assert that something *does not happen* over a period of tiem. +// For example, you want to assert that a goroutine does *not* send data down a channel. In this case, you could: +// +// Consistently(channel).ShouldNot(Receive()) +// +// Consistently's default duration is 100ms, and its default polling interval is 10ms +func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { + return ConsistentlyWithOffset(0, actual, intervals...) +} + +// ConsistentlyWithOffset operates like Consistnetly but takes an additional +// initial argument to indicate an offset in the call stack. This is useful when building helper +// functions that contain matchers. To learn more, read about `ExpectWithOffset`. +func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { + if globalFailWrapper == nil { + panic(nilFailHandlerPanic) + } + timeoutInterval := defaultConsistentlyDuration + pollingInterval := defaultConsistentlyPollingInterval + if len(intervals) > 0 { + timeoutInterval = toDuration(intervals[0]) + } + if len(intervals) > 1 { + pollingInterval = toDuration(intervals[1]) + } + return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, globalFailWrapper, timeoutInterval, pollingInterval, offset) +} + +// SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses. +func SetDefaultEventuallyTimeout(t time.Duration) { + defaultEventuallyTimeout = t +} + +// SetDefaultEventuallyPollingInterval sets the default polling interval for Eventually. +func SetDefaultEventuallyPollingInterval(t time.Duration) { + defaultEventuallyPollingInterval = t +} + +// SetDefaultConsistentlyDuration sets the default duration for Consistently. Consistently will verify that your condition is satsified for this long. +func SetDefaultConsistentlyDuration(t time.Duration) { + defaultConsistentlyDuration = t +} + +// SetDefaultConsistentlyPollingInterval sets the default polling interval for Consistently. +func SetDefaultConsistentlyPollingInterval(t time.Duration) { + defaultConsistentlyPollingInterval = t +} + +// AsyncAssertion is returned by Eventually and Consistently and polls the actual value passed into Eventually against +// the matcher passed to the Should and ShouldNot methods. +// +// Both Should and ShouldNot take a variadic optionalDescription argument. This is passed on to +// fmt.Sprintf() and is used to annotate failure messages. This allows you to make your failure messages more +// descriptive. +// +// Both Should and ShouldNot return a boolean that is true if the assertion passed and false if it failed. +// +// Example: +// +// Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.") +// Consistently(myChannel).ShouldNot(Receive(), "Nothing should have come down the pipe.") +type AsyncAssertion interface { + Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool + ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool +} + +// GomegaAsyncAssertion is deprecated in favor of AsyncAssertion, which does not stutter. +type GomegaAsyncAssertion = AsyncAssertion + +// Assertion is returned by Ω and Expect and compares the actual value to the matcher +// passed to the Should/ShouldNot and To/ToNot/NotTo methods. +// +// Typically Should/ShouldNot are used with Ω and To/ToNot/NotTo are used with Expect +// though this is not enforced. +// +// All methods take a variadic optionalDescription argument. This is passed on to fmt.Sprintf() +// and is used to annotate failure messages. +// +// All methods return a bool that is true if hte assertion passed and false if it failed. +// +// Example: +// +// Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm) +type Assertion interface { + Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool + ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool + + To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool + ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool + NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool +} + +// GomegaAssertion is deprecated in favor of Assertion, which does not stutter. +type GomegaAssertion = Assertion + +// OmegaMatcher is deprecated in favor of the better-named and better-organized types.GomegaMatcher but sticks around to support existing code that uses it +type OmegaMatcher types.GomegaMatcher + +// WithT wraps a *testing.T and provides `Expect`, `Eventually`, and `Consistently` methods. This allows you to leverage +// Gomega's rich ecosystem of matchers in standard `testing` test suites. +// +// Use `NewWithT` to instantiate a `WithT` +type WithT struct { + t types.GomegaTestingT +} + +// GomegaWithT is deprecated in favor of gomega.WithT, which does not stutter. +type GomegaWithT = WithT + +// NewWithT takes a *testing.T and returngs a `gomega.WithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with +// Gomega's rich ecosystem of matchers in standard `testing` test suits. +// +// func TestFarmHasCow(t *testing.T) { +// g := gomega.NewWithT(t) +// +// f := farm.New([]string{"Cow", "Horse"}) +// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow") +// } +func NewWithT(t types.GomegaTestingT) *WithT { + return &WithT{ + t: t, + } +} + +// NewGomegaWithT is deprecated in favor of gomega.NewWithT, which does not stutter. +func NewGomegaWithT(t types.GomegaTestingT) *GomegaWithT { + return NewWithT(t) +} + +// Expect is used to make assertions. See documentation for Expect. +func (g *WithT) Expect(actual interface{}, extra ...interface{}) Assertion { + return assertion.New(actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), 0, extra...) +} + +// Eventually is used to make asynchronous assertions. See documentation for Eventually. +func (g *WithT) Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { + timeoutInterval := defaultEventuallyTimeout + pollingInterval := defaultEventuallyPollingInterval + if len(intervals) > 0 { + timeoutInterval = toDuration(intervals[0]) + } + if len(intervals) > 1 { + pollingInterval = toDuration(intervals[1]) + } + return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, 0) +} + +// Consistently is used to make asynchronous assertions. See documentation for Consistently. +func (g *WithT) Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { + timeoutInterval := defaultConsistentlyDuration + pollingInterval := defaultConsistentlyPollingInterval + if len(intervals) > 0 { + timeoutInterval = toDuration(intervals[0]) + } + if len(intervals) > 1 { + pollingInterval = toDuration(intervals[1]) + } + return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, testingtsupport.BuildTestingTGomegaFailWrapper(g.t), timeoutInterval, pollingInterval, 0) +} + +func toDuration(input interface{}) time.Duration { + duration, ok := input.(time.Duration) + if ok { + return duration + } + + value := reflect.ValueOf(input) + kind := reflect.TypeOf(input).Kind() + + if reflect.Int <= kind && kind <= reflect.Int64 { + return time.Duration(value.Int()) * time.Second + } else if reflect.Uint <= kind && kind <= reflect.Uint64 { + return time.Duration(value.Uint()) * time.Second + } else if reflect.Float32 <= kind && kind <= reflect.Float64 { + return time.Duration(value.Float() * float64(time.Second)) + } else if reflect.String == kind { + duration, err := time.ParseDuration(value.String()) + if err != nil { + panic(fmt.Sprintf("%#v is not a valid parsable duration string.", input)) + } + return duration + } + + panic(fmt.Sprintf("%v is not a valid interval. Must be time.Duration, parsable duration string or a number.", input)) +} diff --git a/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go new file mode 100644 index 00000000..80c9c8bb --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go @@ -0,0 +1,46 @@ +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type BeClosedMatcher struct { +} + +func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) { + if !isChan(actual) { + return false, fmt.Errorf("BeClosed matcher expects a channel. Got:\n%s", format.Object(actual, 1)) + } + + channelType := reflect.TypeOf(actual) + channelValue := reflect.ValueOf(actual) + + if channelType.ChanDir() == reflect.SendDir { + return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open. Got:\n%s", format.Object(actual, 1)) + } + + winnerIndex, _, open := reflect.Select([]reflect.SelectCase{ + {Dir: reflect.SelectRecv, Chan: channelValue}, + {Dir: reflect.SelectDefault}, + }) + + var closed bool + if winnerIndex == 0 { + closed = !open + } else if winnerIndex == 1 { + closed = false + } + + return closed, nil +} + +func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) { + return format.Message(actual, "to be closed") +} + +func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "to be open") +} diff --git a/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go new file mode 100644 index 00000000..302dd1a0 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go @@ -0,0 +1,71 @@ +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type BeSentMatcher struct { + Arg interface{} + channelClosed bool +} + +func (matcher *BeSentMatcher) Match(actual interface{}) (success bool, err error) { + if !isChan(actual) { + return false, fmt.Errorf("BeSent expects a channel. Got:\n%s", format.Object(actual, 1)) + } + + channelType := reflect.TypeOf(actual) + channelValue := reflect.ValueOf(actual) + + if channelType.ChanDir() == reflect.RecvDir { + return false, fmt.Errorf("BeSent matcher cannot be passed a receive-only channel. Got:\n%s", format.Object(actual, 1)) + } + + argType := reflect.TypeOf(matcher.Arg) + assignable := argType.AssignableTo(channelType.Elem()) + + if !assignable { + return false, fmt.Errorf("Cannot pass:\n%s to the channel:\n%s\nThe types don't match.", format.Object(matcher.Arg, 1), format.Object(actual, 1)) + } + + argValue := reflect.ValueOf(matcher.Arg) + + defer func() { + if e := recover(); e != nil { + success = false + err = fmt.Errorf("Cannot send to a closed channel") + matcher.channelClosed = true + } + }() + + winnerIndex, _, _ := reflect.Select([]reflect.SelectCase{ + {Dir: reflect.SelectSend, Chan: channelValue, Send: argValue}, + {Dir: reflect.SelectDefault}, + }) + + var didSend bool + if winnerIndex == 0 { + didSend = true + } + + return didSend, nil +} + +func (matcher *BeSentMatcher) FailureMessage(actual interface{}) (message string) { + return format.Message(actual, "to send:", matcher.Arg) +} + +func (matcher *BeSentMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return format.Message(actual, "not to send:", matcher.Arg) +} + +func (matcher *BeSentMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { + if !isChan(actual) { + return false + } + + return !matcher.channelClosed +} diff --git a/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go new file mode 100644 index 00000000..bef00ae2 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go @@ -0,0 +1,33 @@ +package matchers + +import ( + "fmt" + + "github.com/onsi/gomega/format" +) + +type HaveOccurredMatcher struct { +} + +func (matcher *HaveOccurredMatcher) Match(actual interface{}) (success bool, err error) { + // is purely nil? + if actual == nil { + return false, nil + } + + // must be an 'error' type + if !isError(actual) { + return false, fmt.Errorf("Expected an error-type. Got:\n%s", format.Object(actual, 1)) + } + + // must be non-nil (or a pointer to a non-nil) + return !isNil(actual), nil +} + +func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Expected an error to have occurred. Got:\n%s", format.Object(actual, 1)) +} + +func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) { + return fmt.Sprintf("Unexpected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "occurred") +} diff --git a/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go new file mode 100644 index 00000000..5c815f5a --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go @@ -0,0 +1,134 @@ +package matchers + +import ( + "bytes" + "encoding/xml" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strings" + + "github.com/onsi/gomega/format" + "golang.org/x/net/html/charset" +) + +type MatchXMLMatcher struct { + XMLToMatch interface{} +} + +func (matcher *MatchXMLMatcher) Match(actual interface{}) (success bool, err error) { + actualString, expectedString, err := matcher.formattedPrint(actual) + if err != nil { + return false, err + } + + aval, err := parseXmlContent(actualString) + if err != nil { + return false, fmt.Errorf("Actual '%s' should be valid XML, but it is not.\nUnderlying error:%s", actualString, err) + } + + eval, err := parseXmlContent(expectedString) + if err != nil { + return false, fmt.Errorf("Expected '%s' should be valid XML, but it is not.\nUnderlying error:%s", expectedString, err) + } + + return reflect.DeepEqual(aval, eval), nil +} + +func (matcher *MatchXMLMatcher) FailureMessage(actual interface{}) (message string) { + actualString, expectedString, _ := matcher.formattedPrint(actual) + return fmt.Sprintf("Expected\n%s\nto match XML of\n%s", actualString, expectedString) +} + +func (matcher *MatchXMLMatcher) NegatedFailureMessage(actual interface{}) (message string) { + actualString, expectedString, _ := matcher.formattedPrint(actual) + return fmt.Sprintf("Expected\n%s\nnot to match XML of\n%s", actualString, expectedString) +} + +func (matcher *MatchXMLMatcher) formattedPrint(actual interface{}) (actualString, expectedString string, err error) { + var ok bool + actualString, ok = toString(actual) + if !ok { + return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte. Got actual:\n%s", format.Object(actual, 1)) + } + expectedString, ok = toString(matcher.XMLToMatch) + if !ok { + return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte. Got expected:\n%s", format.Object(matcher.XMLToMatch, 1)) + } + return actualString, expectedString, nil +} + +func parseXmlContent(content string) (*xmlNode, error) { + allNodes := []*xmlNode{} + + dec := newXmlDecoder(strings.NewReader(content)) + for { + tok, err := dec.Token() + if err != nil { + if err == io.EOF { + break + } + return nil, fmt.Errorf("failed to decode next token: %v", err) // untested section + } + + lastNodeIndex := len(allNodes) - 1 + var lastNode *xmlNode + if len(allNodes) > 0 { + lastNode = allNodes[lastNodeIndex] + } else { + lastNode = &xmlNode{} + } + + switch tok := tok.(type) { + case xml.StartElement: + attrs := attributesSlice(tok.Attr) + sort.Sort(attrs) + allNodes = append(allNodes, &xmlNode{XMLName: tok.Name, XMLAttr: tok.Attr}) + case xml.EndElement: + if len(allNodes) > 1 { + allNodes[lastNodeIndex-1].Nodes = append(allNodes[lastNodeIndex-1].Nodes, lastNode) + allNodes = allNodes[:lastNodeIndex] + } + case xml.CharData: + lastNode.Content = append(lastNode.Content, tok.Copy()...) + case xml.Comment: + lastNode.Comments = append(lastNode.Comments, tok.Copy()) // untested section + case xml.ProcInst: + lastNode.ProcInsts = append(lastNode.ProcInsts, tok.Copy()) + } + } + + if len(allNodes) == 0 { + return nil, errors.New("found no nodes") + } + firstNode := allNodes[0] + trimParentNodesContentSpaces(firstNode) + + return firstNode, nil +} + +func newXmlDecoder(reader io.Reader) *xml.Decoder { + dec := xml.NewDecoder(reader) + dec.CharsetReader = charset.NewReaderLabel + return dec +} + +func trimParentNodesContentSpaces(node *xmlNode) { + if len(node.Nodes) > 0 { + node.Content = bytes.TrimSpace(node.Content) + for _, childNode := range node.Nodes { + trimParentNodesContentSpaces(childNode) + } + } +} + +type xmlNode struct { + XMLName xml.Name + Comments []xml.Comment + ProcInsts []xml.ProcInst + XMLAttr []xml.Attr + Content []byte + Nodes []*xmlNode +} diff --git a/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go new file mode 100644 index 00000000..0c83c2b6 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go @@ -0,0 +1,76 @@ +package matchers + +import ( + "fmt" + "strings" + + "github.com/onsi/gomega/format" + "gopkg.in/yaml.v2" +) + +type MatchYAMLMatcher struct { + YAMLToMatch interface{} + firstFailurePath []interface{} +} + +func (matcher *MatchYAMLMatcher) Match(actual interface{}) (success bool, err error) { + actualString, expectedString, err := matcher.toStrings(actual) + if err != nil { + return false, err + } + + var aval interface{} + var eval interface{} + + if err := yaml.Unmarshal([]byte(actualString), &aval); err != nil { + return false, fmt.Errorf("Actual '%s' should be valid YAML, but it is not.\nUnderlying error:%s", actualString, err) + } + if err := yaml.Unmarshal([]byte(expectedString), &eval); err != nil { + return false, fmt.Errorf("Expected '%s' should be valid YAML, but it is not.\nUnderlying error:%s", expectedString, err) + } + + var equal bool + equal, matcher.firstFailurePath = deepEqual(aval, eval) + return equal, nil +} + +func (matcher *MatchYAMLMatcher) FailureMessage(actual interface{}) (message string) { + actualString, expectedString, _ := matcher.toNormalisedStrings(actual) + return formattedMessage(format.Message(actualString, "to match YAML of", expectedString), matcher.firstFailurePath) +} + +func (matcher *MatchYAMLMatcher) NegatedFailureMessage(actual interface{}) (message string) { + actualString, expectedString, _ := matcher.toNormalisedStrings(actual) + return formattedMessage(format.Message(actualString, "not to match YAML of", expectedString), matcher.firstFailurePath) +} + +func (matcher *MatchYAMLMatcher) toNormalisedStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) { + actualString, expectedString, err := matcher.toStrings(actual) + return normalise(actualString), normalise(expectedString), err +} + +func normalise(input string) string { + var val interface{} + err := yaml.Unmarshal([]byte(input), &val) + if err != nil { + panic(err) // unreachable since Match already calls Unmarshal + } + output, err := yaml.Marshal(val) + if err != nil { + panic(err) // untested section, unreachable since we Unmarshal above + } + return strings.TrimSpace(string(output)) +} + +func (matcher *MatchYAMLMatcher) toStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) { + actualString, ok := toString(actual) + if !ok { + return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte. Got actual:\n%s", format.Object(actual, 1)) + } + expectedString, ok := toString(matcher.YAMLToMatch) + if !ok { + return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte. Got expected:\n%s", format.Object(matcher.YAMLToMatch, 1)) + } + + return actualString, expectedString, nil +} diff --git a/vendor/github.com/onsi/gomega/matchers/receive_matcher.go b/vendor/github.com/onsi/gomega/matchers/receive_matcher.go new file mode 100644 index 00000000..2018a612 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/receive_matcher.go @@ -0,0 +1,128 @@ +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type ReceiveMatcher struct { + Arg interface{} + receivedValue reflect.Value + channelClosed bool +} + +func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) { + if !isChan(actual) { + return false, fmt.Errorf("ReceiveMatcher expects a channel. Got:\n%s", format.Object(actual, 1)) + } + + channelType := reflect.TypeOf(actual) + channelValue := reflect.ValueOf(actual) + + if channelType.ChanDir() == reflect.SendDir { + return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel. Got:\n%s", format.Object(actual, 1)) + } + + var subMatcher omegaMatcher + var hasSubMatcher bool + + if matcher.Arg != nil { + subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher) + if !hasSubMatcher { + argType := reflect.TypeOf(matcher.Arg) + if argType.Kind() != reflect.Ptr { + return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1)) + } + } + } + + winnerIndex, value, open := reflect.Select([]reflect.SelectCase{ + {Dir: reflect.SelectRecv, Chan: channelValue}, + {Dir: reflect.SelectDefault}, + }) + + var closed bool + var didReceive bool + if winnerIndex == 0 { + closed = !open + didReceive = open + } + matcher.channelClosed = closed + + if closed { + return false, nil + } + + if hasSubMatcher { + if didReceive { + matcher.receivedValue = value + return subMatcher.Match(matcher.receivedValue.Interface()) + } + return false, nil + } + + if didReceive { + if matcher.Arg != nil { + outValue := reflect.ValueOf(matcher.Arg) + + if value.Type().AssignableTo(outValue.Elem().Type()) { + outValue.Elem().Set(value) + return true, nil + } + if value.Type().Kind() == reflect.Interface && value.Elem().Type().AssignableTo(outValue.Elem().Type()) { + outValue.Elem().Set(value.Elem()) + return true, nil + } else { + return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nType:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(value.Interface(), 1), format.Object(matcher.Arg, 1)) + } + + } + + return true, nil + } + return false, nil +} + +func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) { + subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) + + closedAddendum := "" + if matcher.channelClosed { + closedAddendum = " The channel is closed." + } + + if hasSubMatcher { + if matcher.receivedValue.IsValid() { + return subMatcher.FailureMessage(matcher.receivedValue.Interface()) + } + return "When passed a matcher, ReceiveMatcher's channel *must* receive something." + } + return format.Message(actual, "to receive something."+closedAddendum) +} + +func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) { + subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) + + closedAddendum := "" + if matcher.channelClosed { + closedAddendum = " The channel is closed." + } + + if hasSubMatcher { + if matcher.receivedValue.IsValid() { + return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface()) + } + return "When passed a matcher, ReceiveMatcher's channel *must* receive something." + } + return format.Message(actual, "not to receive anything."+closedAddendum) +} + +func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool { + if !isChan(actual) { + return false + } + + return !matcher.channelClosed +} diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go new file mode 100644 index 00000000..8aaf8759 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go @@ -0,0 +1,41 @@ +package bipartitegraph + +import "errors" +import "fmt" + +import . "github.com/onsi/gomega/matchers/support/goraph/node" +import . "github.com/onsi/gomega/matchers/support/goraph/edge" + +type BipartiteGraph struct { + Left NodeOrderedSet + Right NodeOrderedSet + Edges EdgeSet +} + +func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) { + left := NodeOrderedSet{} + for i := range leftValues { + left = append(left, Node{Id: i}) + } + + right := NodeOrderedSet{} + for j := range rightValues { + right = append(right, Node{Id: j + len(left)}) + } + + edges := EdgeSet{} + for i, leftValue := range leftValues { + for j, rightValue := range rightValues { + neighbours, err := neighbours(leftValue, rightValue) + if err != nil { + return nil, errors.New(fmt.Sprintf("error determining adjacency for %v and %v: %s", leftValue, rightValue, err.Error())) + } + + if neighbours { + edges = append(edges, Edge{Node1: left[i], Node2: right[j]}) + } + } + } + + return &BipartiteGraph{left, right, edges}, nil +} diff --git a/vendor/github.com/opentracing/opentracing-go/.gitignore b/vendor/github.com/opentracing/opentracing-go/.gitignore new file mode 100644 index 00000000..c57100a5 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/.gitignore @@ -0,0 +1 @@ +coverage.txt diff --git a/vendor/github.com/opentracing/opentracing-go/.travis.yml b/vendor/github.com/opentracing/opentracing-go/.travis.yml new file mode 100644 index 00000000..8d5b75e4 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/.travis.yml @@ -0,0 +1,20 @@ +language: go + +matrix: + include: + - go: "1.11.x" + - go: "1.12.x" + - go: "tip" + env: + - LINT=true + - COVERAGE=true + +install: + - if [ "$LINT" == true ]; then go get -u golang.org/x/lint/golint/... ; else echo 'skipping lint'; fi + - go get -u github.com/stretchr/testify/... + +script: + - make test + - go build ./... + - if [ "$LINT" == true ]; then make lint ; else echo 'skipping lint'; fi + - if [ "$COVERAGE" == true ]; then make cover && bash <(curl -s https://codecov.io/bash) ; else echo 'skipping coverage'; fi diff --git a/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md b/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md new file mode 100644 index 00000000..7c14febe --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md @@ -0,0 +1,46 @@ +Changes by Version +================== + +1.1.0 (2019-03-23) +------------------- + +Notable changes: +- The library is now released under Apache 2.0 license +- Use Set() instead of Add() in HTTPHeadersCarrier is functionally a breaking change (fixes issue [#159](https://github.com/opentracing/opentracing-go/issues/159)) +- 'golang.org/x/net/context' is replaced with 'context' from the standard library + +List of all changes: + +- Export StartSpanFromContextWithTracer (#214) +- Add IsGlobalTracerRegistered() to indicate if a tracer has been registered (#201) +- Use Set() instead of Add() in HTTPHeadersCarrier (#191) +- Update license to Apache 2.0 (#181) +- Replace 'golang.org/x/net/context' with 'context' (#176) +- Port of Python opentracing/harness/api_check.py to Go (#146) +- Fix race condition in MockSpan.Context() (#170) +- Add PeerHostIPv4.SetString() (#155) +- Add a Noop log field type to log to allow for optional fields (#150) + + +1.0.2 (2017-04-26) +------------------- + +- Add more semantic tags (#139) + + +1.0.1 (2017-02-06) +------------------- + +- Correct spelling in comments +- Address race in nextMockID() (#123) +- log: avoid panic marshaling nil error (#131) +- Deprecate InitGlobalTracer in favor of SetGlobalTracer (#128) +- Drop Go 1.5 that fails in Travis (#129) +- Add convenience methods Key() and Value() to log.Field +- Add convenience methods to log.Field (2 years, 6 months ago) + +1.0.0 (2016-09-26) +------------------- + +- This release implements OpenTracing Specification 1.0 (https://opentracing.io/spec) + diff --git a/vendor/github.com/opentracing/opentracing-go/LICENSE b/vendor/github.com/opentracing/opentracing-go/LICENSE new file mode 100644 index 00000000..f0027349 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The OpenTracing Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/opentracing/opentracing-go/Makefile b/vendor/github.com/opentracing/opentracing-go/Makefile new file mode 100644 index 00000000..62abb63f --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/Makefile @@ -0,0 +1,20 @@ +.DEFAULT_GOAL := test-and-lint + +.PHONY: test-and-lint +test-and-lint: test lint + +.PHONY: test +test: + go test -v -cover -race ./... + +.PHONY: cover +cover: + go test -v -coverprofile=coverage.txt -covermode=atomic -race ./... + +.PHONY: lint +lint: + go fmt ./... + golint ./... + @# Run again with magic to exit non-zero if golint outputs anything. + @! (golint ./... | read dummy) + go vet ./... diff --git a/vendor/github.com/opentracing/opentracing-go/README.md b/vendor/github.com/opentracing/opentracing-go/README.md new file mode 100644 index 00000000..6ef1d7c9 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/README.md @@ -0,0 +1,171 @@ +[![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/opentracing/public) [![Build Status](https://travis-ci.org/opentracing/opentracing-go.svg?branch=master)](https://travis-ci.org/opentracing/opentracing-go) [![GoDoc](https://godoc.org/github.com/opentracing/opentracing-go?status.svg)](http://godoc.org/github.com/opentracing/opentracing-go) +[![Sourcegraph Badge](https://sourcegraph.com/github.com/opentracing/opentracing-go/-/badge.svg)](https://sourcegraph.com/github.com/opentracing/opentracing-go?badge) + +# OpenTracing API for Go + +This package is a Go platform API for OpenTracing. + +## Required Reading + +In order to understand the Go platform API, one must first be familiar with the +[OpenTracing project](https://opentracing.io) and +[terminology](https://opentracing.io/specification/) more specifically. + +## API overview for those adding instrumentation + +Everyday consumers of this `opentracing` package really only need to worry +about a couple of key abstractions: the `StartSpan` function, the `Span` +interface, and binding a `Tracer` at `main()`-time. Here are code snippets +demonstrating some important use cases. + +#### Singleton initialization + +The simplest starting point is `./default_tracer.go`. As early as possible, call + +```go + import "github.com/opentracing/opentracing-go" + import ".../some_tracing_impl" + + func main() { + opentracing.SetGlobalTracer( + // tracing impl specific: + some_tracing_impl.New(...), + ) + ... + } +``` + +#### Non-Singleton initialization + +If you prefer direct control to singletons, manage ownership of the +`opentracing.Tracer` implementation explicitly. + +#### Creating a Span given an existing Go `context.Context` + +If you use `context.Context` in your application, OpenTracing's Go library will +happily rely on it for `Span` propagation. To start a new (blocking child) +`Span`, you can use `StartSpanFromContext`. + +```go + func xyz(ctx context.Context, ...) { + ... + span, ctx := opentracing.StartSpanFromContext(ctx, "operation_name") + defer span.Finish() + span.LogFields( + log.String("event", "soft error"), + log.String("type", "cache timeout"), + log.Int("waited.millis", 1500)) + ... + } +``` + +#### Starting an empty trace by creating a "root span" + +It's always possible to create a "root" `Span` with no parent or other causal +reference. + +```go + func xyz() { + ... + sp := opentracing.StartSpan("operation_name") + defer sp.Finish() + ... + } +``` + +#### Creating a (child) Span given an existing (parent) Span + +```go + func xyz(parentSpan opentracing.Span, ...) { + ... + sp := opentracing.StartSpan( + "operation_name", + opentracing.ChildOf(parentSpan.Context())) + defer sp.Finish() + ... + } +``` + +#### Serializing to the wire + +```go + func makeSomeRequest(ctx context.Context) ... { + if span := opentracing.SpanFromContext(ctx); span != nil { + httpClient := &http.Client{} + httpReq, _ := http.NewRequest("GET", "http://myservice/", nil) + + // Transmit the span's TraceContext as HTTP headers on our + // outbound request. + opentracing.GlobalTracer().Inject( + span.Context(), + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(httpReq.Header)) + + resp, err := httpClient.Do(httpReq) + ... + } + ... + } +``` + +#### Deserializing from the wire + +```go + http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + var serverSpan opentracing.Span + appSpecificOperationName := ... + wireContext, err := opentracing.GlobalTracer().Extract( + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(req.Header)) + if err != nil { + // Optionally record something about err here + } + + // Create the span referring to the RPC client if available. + // If wireContext == nil, a root span will be created. + serverSpan = opentracing.StartSpan( + appSpecificOperationName, + ext.RPCServerOption(wireContext)) + + defer serverSpan.Finish() + + ctx := opentracing.ContextWithSpan(context.Background(), serverSpan) + ... + } +``` + +#### Conditionally capture a field using `log.Noop` + +In some situations, you may want to dynamically decide whether or not +to log a field. For example, you may want to capture additional data, +such as a customer ID, in non-production environments: + +```go + func Customer(order *Order) log.Field { + if os.Getenv("ENVIRONMENT") == "dev" { + return log.String("customer", order.Customer.ID) + } + return log.Noop() + } +``` + +#### Goroutine-safety + +The entire public API is goroutine-safe and does not require external +synchronization. + +## API pointers for those implementing a tracing system + +Tracing system implementors may be able to reuse or copy-paste-modify the `basictracer` package, found [here](https://github.com/opentracing/basictracer-go). In particular, see `basictracer.New(...)`. + +## API compatibility + +For the time being, "mild" backwards-incompatible changes may be made without changing the major version number. As OpenTracing and `opentracing-go` mature, backwards compatibility will become more of a priority. + +## Tracer test suite + +A test suite is available in the [harness](https://godoc.org/github.com/opentracing/opentracing-go/harness) package that can assist Tracer implementors to assert that their Tracer is working correctly. + +## Licensing + +[Apache 2.0 License](./LICENSE). diff --git a/vendor/github.com/opentracing/opentracing-go/ext/tags.go b/vendor/github.com/opentracing/opentracing-go/ext/tags.go new file mode 100644 index 00000000..52e88958 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/ext/tags.go @@ -0,0 +1,210 @@ +package ext + +import "github.com/opentracing/opentracing-go" + +// These constants define common tag names recommended for better portability across +// tracing systems and languages/platforms. +// +// The tag names are defined as typed strings, so that in addition to the usual use +// +// span.setTag(TagName, value) +// +// they also support value type validation via this additional syntax: +// +// TagName.Set(span, value) +// +var ( + ////////////////////////////////////////////////////////////////////// + // SpanKind (client/server or producer/consumer) + ////////////////////////////////////////////////////////////////////// + + // SpanKind hints at relationship between spans, e.g. client/server + SpanKind = spanKindTagName("span.kind") + + // SpanKindRPCClient marks a span representing the client-side of an RPC + // or other remote call + SpanKindRPCClientEnum = SpanKindEnum("client") + SpanKindRPCClient = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCClientEnum} + + // SpanKindRPCServer marks a span representing the server-side of an RPC + // or other remote call + SpanKindRPCServerEnum = SpanKindEnum("server") + SpanKindRPCServer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCServerEnum} + + // SpanKindProducer marks a span representing the producer-side of a + // message bus + SpanKindProducerEnum = SpanKindEnum("producer") + SpanKindProducer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindProducerEnum} + + // SpanKindConsumer marks a span representing the consumer-side of a + // message bus + SpanKindConsumerEnum = SpanKindEnum("consumer") + SpanKindConsumer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindConsumerEnum} + + ////////////////////////////////////////////////////////////////////// + // Component name + ////////////////////////////////////////////////////////////////////// + + // Component is a low-cardinality identifier of the module, library, + // or package that is generating a span. + Component = stringTagName("component") + + ////////////////////////////////////////////////////////////////////// + // Sampling hint + ////////////////////////////////////////////////////////////////////// + + // SamplingPriority determines the priority of sampling this Span. + SamplingPriority = uint16TagName("sampling.priority") + + ////////////////////////////////////////////////////////////////////// + // Peer tags. These tags can be emitted by either client-side of + // server-side to describe the other side/service in a peer-to-peer + // communications, like an RPC call. + ////////////////////////////////////////////////////////////////////// + + // PeerService records the service name of the peer. + PeerService = stringTagName("peer.service") + + // PeerAddress records the address name of the peer. This may be a "ip:port", + // a bare "hostname", a FQDN or even a database DSN substring + // like "mysql://username@127.0.0.1:3306/dbname" + PeerAddress = stringTagName("peer.address") + + // PeerHostname records the host name of the peer + PeerHostname = stringTagName("peer.hostname") + + // PeerHostIPv4 records IP v4 host address of the peer + PeerHostIPv4 = ipv4Tag("peer.ipv4") + + // PeerHostIPv6 records IP v6 host address of the peer + PeerHostIPv6 = stringTagName("peer.ipv6") + + // PeerPort records port number of the peer + PeerPort = uint16TagName("peer.port") + + ////////////////////////////////////////////////////////////////////// + // HTTP Tags + ////////////////////////////////////////////////////////////////////// + + // HTTPUrl should be the URL of the request being handled in this segment + // of the trace, in standard URI format. The protocol is optional. + HTTPUrl = stringTagName("http.url") + + // HTTPMethod is the HTTP method of the request, and is case-insensitive. + HTTPMethod = stringTagName("http.method") + + // HTTPStatusCode is the numeric HTTP status code (200, 404, etc) of the + // HTTP response. + HTTPStatusCode = uint16TagName("http.status_code") + + ////////////////////////////////////////////////////////////////////// + // DB Tags + ////////////////////////////////////////////////////////////////////// + + // DBInstance is database instance name. + DBInstance = stringTagName("db.instance") + + // DBStatement is a database statement for the given database type. + // It can be a query or a prepared statement (i.e., before substitution). + DBStatement = stringTagName("db.statement") + + // DBType is a database type. For any SQL database, "sql". + // For others, the lower-case database category, e.g. "redis" + DBType = stringTagName("db.type") + + // DBUser is a username for accessing database. + DBUser = stringTagName("db.user") + + ////////////////////////////////////////////////////////////////////// + // Message Bus Tag + ////////////////////////////////////////////////////////////////////// + + // MessageBusDestination is an address at which messages can be exchanged + MessageBusDestination = stringTagName("message_bus.destination") + + ////////////////////////////////////////////////////////////////////// + // Error Tag + ////////////////////////////////////////////////////////////////////// + + // Error indicates that operation represented by the span resulted in an error. + Error = boolTagName("error") +) + +// --- + +// SpanKindEnum represents common span types +type SpanKindEnum string + +type spanKindTagName string + +// Set adds a string tag to the `span` +func (tag spanKindTagName) Set(span opentracing.Span, value SpanKindEnum) { + span.SetTag(string(tag), value) +} + +type rpcServerOption struct { + clientContext opentracing.SpanContext +} + +func (r rpcServerOption) Apply(o *opentracing.StartSpanOptions) { + if r.clientContext != nil { + opentracing.ChildOf(r.clientContext).Apply(o) + } + SpanKindRPCServer.Apply(o) +} + +// RPCServerOption returns a StartSpanOption appropriate for an RPC server span +// with `client` representing the metadata for the remote peer Span if available. +// In case client == nil, due to the client not being instrumented, this RPC +// server span will be a root span. +func RPCServerOption(client opentracing.SpanContext) opentracing.StartSpanOption { + return rpcServerOption{client} +} + +// --- + +type stringTagName string + +// Set adds a string tag to the `span` +func (tag stringTagName) Set(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} + +// --- + +type uint32TagName string + +// Set adds a uint32 tag to the `span` +func (tag uint32TagName) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// --- + +type uint16TagName string + +// Set adds a uint16 tag to the `span` +func (tag uint16TagName) Set(span opentracing.Span, value uint16) { + span.SetTag(string(tag), value) +} + +// --- + +type boolTagName string + +// Add adds a bool tag to the `span` +func (tag boolTagName) Set(span opentracing.Span, value bool) { + span.SetTag(string(tag), value) +} + +type ipv4Tag string + +// Set adds IP v4 host address of the peer as an uint32 value to the `span`, keep this for backward and zipkin compatibility +func (tag ipv4Tag) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// SetString records IP v4 host address of the peer as a .-separated tuple to the `span`. E.g., "127.0.0.1" +func (tag ipv4Tag) SetString(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} diff --git a/vendor/github.com/opentracing/opentracing-go/globaltracer.go b/vendor/github.com/opentracing/opentracing-go/globaltracer.go new file mode 100644 index 00000000..4f7066a9 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/globaltracer.go @@ -0,0 +1,42 @@ +package opentracing + +type registeredTracer struct { + tracer Tracer + isRegistered bool +} + +var ( + globalTracer = registeredTracer{NoopTracer{}, false} +) + +// SetGlobalTracer sets the [singleton] opentracing.Tracer returned by +// GlobalTracer(). Those who use GlobalTracer (rather than directly manage an +// opentracing.Tracer instance) should call SetGlobalTracer as early as +// possible in main(), prior to calling the `StartSpan` global func below. +// Prior to calling `SetGlobalTracer`, any Spans started via the `StartSpan` +// (etc) globals are noops. +func SetGlobalTracer(tracer Tracer) { + globalTracer = registeredTracer{tracer, true} +} + +// GlobalTracer returns the global singleton `Tracer` implementation. +// Before `SetGlobalTracer()` is called, the `GlobalTracer()` is a noop +// implementation that drops all data handed to it. +func GlobalTracer() Tracer { + return globalTracer.tracer +} + +// StartSpan defers to `Tracer.StartSpan`. See `GlobalTracer()`. +func StartSpan(operationName string, opts ...StartSpanOption) Span { + return globalTracer.tracer.StartSpan(operationName, opts...) +} + +// InitGlobalTracer is deprecated. Please use SetGlobalTracer. +func InitGlobalTracer(tracer Tracer) { + SetGlobalTracer(tracer) +} + +// IsGlobalTracerRegistered returns a `bool` to indicate if a tracer has been globally registered +func IsGlobalTracerRegistered() bool { + return globalTracer.isRegistered +} diff --git a/vendor/github.com/opentracing/opentracing-go/gocontext.go b/vendor/github.com/opentracing/opentracing-go/gocontext.go new file mode 100644 index 00000000..08c00c04 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/gocontext.go @@ -0,0 +1,60 @@ +package opentracing + +import "context" + +type contextKey struct{} + +var activeSpanKey = contextKey{} + +// ContextWithSpan returns a new `context.Context` that holds a reference to +// `span`'s SpanContext. +func ContextWithSpan(ctx context.Context, span Span) context.Context { + return context.WithValue(ctx, activeSpanKey, span) +} + +// SpanFromContext returns the `Span` previously associated with `ctx`, or +// `nil` if no such `Span` could be found. +// +// NOTE: context.Context != SpanContext: the former is Go's intra-process +// context propagation mechanism, and the latter houses OpenTracing's per-Span +// identity and baggage information. +func SpanFromContext(ctx context.Context) Span { + val := ctx.Value(activeSpanKey) + if sp, ok := val.(Span); ok { + return sp + } + return nil +} + +// StartSpanFromContext starts and returns a Span with `operationName`, using +// any Span found within `ctx` as a ChildOfRef. If no such parent could be +// found, StartSpanFromContext creates a root (parentless) Span. +// +// The second return value is a context.Context object built around the +// returned Span. +// +// Example usage: +// +// SomeFunction(ctx context.Context, ...) { +// sp, ctx := opentracing.StartSpanFromContext(ctx, "SomeFunction") +// defer sp.Finish() +// ... +// } +func StartSpanFromContext(ctx context.Context, operationName string, opts ...StartSpanOption) (Span, context.Context) { + return StartSpanFromContextWithTracer(ctx, GlobalTracer(), operationName, opts...) +} + +// StartSpanFromContextWithTracer starts and returns a span with `operationName` +// using a span found within the context as a ChildOfRef. If that doesn't exist +// it creates a root span. It also returns a context.Context object built +// around the returned span. +// +// It's behavior is identical to StartSpanFromContext except that it takes an explicit +// tracer as opposed to using the global tracer. +func StartSpanFromContextWithTracer(ctx context.Context, tracer Tracer, operationName string, opts ...StartSpanOption) (Span, context.Context) { + if parentSpan := SpanFromContext(ctx); parentSpan != nil { + opts = append(opts, ChildOf(parentSpan.Context())) + } + span := tracer.StartSpan(operationName, opts...) + return span, ContextWithSpan(ctx, span) +} diff --git a/vendor/github.com/opentracing/opentracing-go/log/field.go b/vendor/github.com/opentracing/opentracing-go/log/field.go new file mode 100644 index 00000000..50feea34 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/log/field.go @@ -0,0 +1,269 @@ +package log + +import ( + "fmt" + "math" +) + +type fieldType int + +const ( + stringType fieldType = iota + boolType + intType + int32Type + uint32Type + int64Type + uint64Type + float32Type + float64Type + errorType + objectType + lazyLoggerType + noopType +) + +// Field instances are constructed via LogBool, LogString, and so on. +// Tracing implementations may then handle them via the Field.Marshal +// method. +// +// "heavily influenced by" (i.e., partially stolen from) +// https://github.com/uber-go/zap +type Field struct { + key string + fieldType fieldType + numericVal int64 + stringVal string + interfaceVal interface{} +} + +// String adds a string-valued key:value pair to a Span.LogFields() record +func String(key, val string) Field { + return Field{ + key: key, + fieldType: stringType, + stringVal: val, + } +} + +// Bool adds a bool-valued key:value pair to a Span.LogFields() record +func Bool(key string, val bool) Field { + var numericVal int64 + if val { + numericVal = 1 + } + return Field{ + key: key, + fieldType: boolType, + numericVal: numericVal, + } +} + +// Int adds an int-valued key:value pair to a Span.LogFields() record +func Int(key string, val int) Field { + return Field{ + key: key, + fieldType: intType, + numericVal: int64(val), + } +} + +// Int32 adds an int32-valued key:value pair to a Span.LogFields() record +func Int32(key string, val int32) Field { + return Field{ + key: key, + fieldType: int32Type, + numericVal: int64(val), + } +} + +// Int64 adds an int64-valued key:value pair to a Span.LogFields() record +func Int64(key string, val int64) Field { + return Field{ + key: key, + fieldType: int64Type, + numericVal: val, + } +} + +// Uint32 adds a uint32-valued key:value pair to a Span.LogFields() record +func Uint32(key string, val uint32) Field { + return Field{ + key: key, + fieldType: uint32Type, + numericVal: int64(val), + } +} + +// Uint64 adds a uint64-valued key:value pair to a Span.LogFields() record +func Uint64(key string, val uint64) Field { + return Field{ + key: key, + fieldType: uint64Type, + numericVal: int64(val), + } +} + +// Float32 adds a float32-valued key:value pair to a Span.LogFields() record +func Float32(key string, val float32) Field { + return Field{ + key: key, + fieldType: float32Type, + numericVal: int64(math.Float32bits(val)), + } +} + +// Float64 adds a float64-valued key:value pair to a Span.LogFields() record +func Float64(key string, val float64) Field { + return Field{ + key: key, + fieldType: float64Type, + numericVal: int64(math.Float64bits(val)), + } +} + +// Error adds an error with the key "error" to a Span.LogFields() record +func Error(err error) Field { + return Field{ + key: "error", + fieldType: errorType, + interfaceVal: err, + } +} + +// Object adds an object-valued key:value pair to a Span.LogFields() record +func Object(key string, obj interface{}) Field { + return Field{ + key: key, + fieldType: objectType, + interfaceVal: obj, + } +} + +// LazyLogger allows for user-defined, late-bound logging of arbitrary data +type LazyLogger func(fv Encoder) + +// Lazy adds a LazyLogger to a Span.LogFields() record; the tracing +// implementation will call the LazyLogger function at an indefinite time in +// the future (after Lazy() returns). +func Lazy(ll LazyLogger) Field { + return Field{ + fieldType: lazyLoggerType, + interfaceVal: ll, + } +} + +// Noop creates a no-op log field that should be ignored by the tracer. +// It can be used to capture optional fields, for example those that should +// only be logged in non-production environment: +// +// func customerField(order *Order) log.Field { +// if os.Getenv("ENVIRONMENT") == "dev" { +// return log.String("customer", order.Customer.ID) +// } +// return log.Noop() +// } +// +// span.LogFields(log.String("event", "purchase"), customerField(order)) +// +func Noop() Field { + return Field{ + fieldType: noopType, + } +} + +// Encoder allows access to the contents of a Field (via a call to +// Field.Marshal). +// +// Tracer implementations typically provide an implementation of Encoder; +// OpenTracing callers typically do not need to concern themselves with it. +type Encoder interface { + EmitString(key, value string) + EmitBool(key string, value bool) + EmitInt(key string, value int) + EmitInt32(key string, value int32) + EmitInt64(key string, value int64) + EmitUint32(key string, value uint32) + EmitUint64(key string, value uint64) + EmitFloat32(key string, value float32) + EmitFloat64(key string, value float64) + EmitObject(key string, value interface{}) + EmitLazyLogger(value LazyLogger) +} + +// Marshal passes a Field instance through to the appropriate +// field-type-specific method of an Encoder. +func (lf Field) Marshal(visitor Encoder) { + switch lf.fieldType { + case stringType: + visitor.EmitString(lf.key, lf.stringVal) + case boolType: + visitor.EmitBool(lf.key, lf.numericVal != 0) + case intType: + visitor.EmitInt(lf.key, int(lf.numericVal)) + case int32Type: + visitor.EmitInt32(lf.key, int32(lf.numericVal)) + case int64Type: + visitor.EmitInt64(lf.key, int64(lf.numericVal)) + case uint32Type: + visitor.EmitUint32(lf.key, uint32(lf.numericVal)) + case uint64Type: + visitor.EmitUint64(lf.key, uint64(lf.numericVal)) + case float32Type: + visitor.EmitFloat32(lf.key, math.Float32frombits(uint32(lf.numericVal))) + case float64Type: + visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal))) + case errorType: + if err, ok := lf.interfaceVal.(error); ok { + visitor.EmitString(lf.key, err.Error()) + } else { + visitor.EmitString(lf.key, "") + } + case objectType: + visitor.EmitObject(lf.key, lf.interfaceVal) + case lazyLoggerType: + visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger)) + case noopType: + // intentionally left blank + } +} + +// Key returns the field's key. +func (lf Field) Key() string { + return lf.key +} + +// Value returns the field's value as interface{}. +func (lf Field) Value() interface{} { + switch lf.fieldType { + case stringType: + return lf.stringVal + case boolType: + return lf.numericVal != 0 + case intType: + return int(lf.numericVal) + case int32Type: + return int32(lf.numericVal) + case int64Type: + return int64(lf.numericVal) + case uint32Type: + return uint32(lf.numericVal) + case uint64Type: + return uint64(lf.numericVal) + case float32Type: + return math.Float32frombits(uint32(lf.numericVal)) + case float64Type: + return math.Float64frombits(uint64(lf.numericVal)) + case errorType, objectType, lazyLoggerType: + return lf.interfaceVal + case noopType: + return nil + default: + return nil + } +} + +// String returns a string representation of the key and value. +func (lf Field) String() string { + return fmt.Sprint(lf.key, ":", lf.Value()) +} diff --git a/vendor/github.com/opentracing/opentracing-go/log/util.go b/vendor/github.com/opentracing/opentracing-go/log/util.go new file mode 100644 index 00000000..3832feb5 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/log/util.go @@ -0,0 +1,54 @@ +package log + +import "fmt" + +// InterleavedKVToFields converts keyValues a la Span.LogKV() to a Field slice +// a la Span.LogFields(). +func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) { + if len(keyValues)%2 != 0 { + return nil, fmt.Errorf("non-even keyValues len: %d", len(keyValues)) + } + fields := make([]Field, len(keyValues)/2) + for i := 0; i*2 < len(keyValues); i++ { + key, ok := keyValues[i*2].(string) + if !ok { + return nil, fmt.Errorf( + "non-string key (pair #%d): %T", + i, keyValues[i*2]) + } + switch typedVal := keyValues[i*2+1].(type) { + case bool: + fields[i] = Bool(key, typedVal) + case string: + fields[i] = String(key, typedVal) + case int: + fields[i] = Int(key, typedVal) + case int8: + fields[i] = Int32(key, int32(typedVal)) + case int16: + fields[i] = Int32(key, int32(typedVal)) + case int32: + fields[i] = Int32(key, typedVal) + case int64: + fields[i] = Int64(key, typedVal) + case uint: + fields[i] = Uint64(key, uint64(typedVal)) + case uint64: + fields[i] = Uint64(key, typedVal) + case uint8: + fields[i] = Uint32(key, uint32(typedVal)) + case uint16: + fields[i] = Uint32(key, uint32(typedVal)) + case uint32: + fields[i] = Uint32(key, typedVal) + case float32: + fields[i] = Float32(key, typedVal) + case float64: + fields[i] = Float64(key, typedVal) + default: + // When in doubt, coerce to a string + fields[i] = String(key, fmt.Sprint(typedVal)) + } + } + return fields, nil +} diff --git a/vendor/github.com/opentracing/opentracing-go/noop.go b/vendor/github.com/opentracing/opentracing-go/noop.go new file mode 100644 index 00000000..0d32f692 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/noop.go @@ -0,0 +1,64 @@ +package opentracing + +import "github.com/opentracing/opentracing-go/log" + +// A NoopTracer is a trivial, minimum overhead implementation of Tracer +// for which all operations are no-ops. +// +// The primary use of this implementation is in libraries, such as RPC +// frameworks, that make tracing an optional feature controlled by the +// end user. A no-op implementation allows said libraries to use it +// as the default Tracer and to write instrumentation that does +// not need to keep checking if the tracer instance is nil. +// +// For the same reason, the NoopTracer is the default "global" tracer +// (see GlobalTracer and SetGlobalTracer functions). +// +// WARNING: NoopTracer does not support baggage propagation. +type NoopTracer struct{} + +type noopSpan struct{} +type noopSpanContext struct{} + +var ( + defaultNoopSpanContext = noopSpanContext{} + defaultNoopSpan = noopSpan{} + defaultNoopTracer = NoopTracer{} +) + +const ( + emptyString = "" +) + +// noopSpanContext: +func (n noopSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {} + +// noopSpan: +func (n noopSpan) Context() SpanContext { return defaultNoopSpanContext } +func (n noopSpan) SetBaggageItem(key, val string) Span { return defaultNoopSpan } +func (n noopSpan) BaggageItem(key string) string { return emptyString } +func (n noopSpan) SetTag(key string, value interface{}) Span { return n } +func (n noopSpan) LogFields(fields ...log.Field) {} +func (n noopSpan) LogKV(keyVals ...interface{}) {} +func (n noopSpan) Finish() {} +func (n noopSpan) FinishWithOptions(opts FinishOptions) {} +func (n noopSpan) SetOperationName(operationName string) Span { return n } +func (n noopSpan) Tracer() Tracer { return defaultNoopTracer } +func (n noopSpan) LogEvent(event string) {} +func (n noopSpan) LogEventWithPayload(event string, payload interface{}) {} +func (n noopSpan) Log(data LogData) {} + +// StartSpan belongs to the Tracer interface. +func (n NoopTracer) StartSpan(operationName string, opts ...StartSpanOption) Span { + return defaultNoopSpan +} + +// Inject belongs to the Tracer interface. +func (n NoopTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error { + return nil +} + +// Extract belongs to the Tracer interface. +func (n NoopTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) { + return nil, ErrSpanContextNotFound +} diff --git a/vendor/github.com/opentracing/opentracing-go/propagation.go b/vendor/github.com/opentracing/opentracing-go/propagation.go new file mode 100644 index 00000000..b0c275eb --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/propagation.go @@ -0,0 +1,176 @@ +package opentracing + +import ( + "errors" + "net/http" +) + +/////////////////////////////////////////////////////////////////////////////// +// CORE PROPAGATION INTERFACES: +/////////////////////////////////////////////////////////////////////////////// + +var ( + // ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or + // Tracer.Extract() is not recognized by the Tracer implementation. + ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Extract format") + + // ErrSpanContextNotFound occurs when the `carrier` passed to + // Tracer.Extract() is valid and uncorrupted but has insufficient + // information to extract a SpanContext. + ErrSpanContextNotFound = errors.New("opentracing: SpanContext not found in Extract carrier") + + // ErrInvalidSpanContext errors occur when Tracer.Inject() is asked to + // operate on a SpanContext which it is not prepared to handle (for + // example, since it was created by a different tracer implementation). + ErrInvalidSpanContext = errors.New("opentracing: SpanContext type incompatible with tracer") + + // ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Extract() + // implementations expect a different type of `carrier` than they are + // given. + ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Extract carrier") + + // ErrSpanContextCorrupted occurs when the `carrier` passed to + // Tracer.Extract() is of the expected type but is corrupted. + ErrSpanContextCorrupted = errors.New("opentracing: SpanContext data corrupted in Extract carrier") +) + +/////////////////////////////////////////////////////////////////////////////// +// BUILTIN PROPAGATION FORMATS: +/////////////////////////////////////////////////////////////////////////////// + +// BuiltinFormat is used to demarcate the values within package `opentracing` +// that are intended for use with the Tracer.Inject() and Tracer.Extract() +// methods. +type BuiltinFormat byte + +const ( + // Binary represents SpanContexts as opaque binary data. + // + // For Tracer.Inject(): the carrier must be an `io.Writer`. + // + // For Tracer.Extract(): the carrier must be an `io.Reader`. + Binary BuiltinFormat = iota + + // TextMap represents SpanContexts as key:value string pairs. + // + // Unlike HTTPHeaders, the TextMap format does not restrict the key or + // value character sets in any way. + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + TextMap + + // HTTPHeaders represents SpanContexts as HTTP header string pairs. + // + // Unlike TextMap, the HTTPHeaders format requires that the keys and values + // be valid as HTTP headers as-is (i.e., character casing may be unstable + // and special characters are disallowed in keys, values should be + // URL-escaped, etc). + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + // + // See HTTPHeadersCarrier for an implementation of both TextMapWriter + // and TextMapReader that defers to an http.Header instance for storage. + // For example, Inject(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := span.Tracer().Inject( + // span.Context(), opentracing.HTTPHeaders, carrier) + // + // Or Extract(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract( + // opentracing.HTTPHeaders, carrier) + // + HTTPHeaders +) + +// TextMapWriter is the Inject() carrier for the TextMap builtin format. With +// it, the caller can encode a SpanContext for propagation as entries in a map +// of unicode strings. +type TextMapWriter interface { + // Set a key:value pair to the carrier. Multiple calls to Set() for the + // same key leads to undefined behavior. + // + // NOTE: The backing store for the TextMapWriter may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + Set(key, val string) +} + +// TextMapReader is the Extract() carrier for the TextMap builtin format. With it, +// the caller can decode a propagated SpanContext as entries in a map of +// unicode strings. +type TextMapReader interface { + // ForeachKey returns TextMap contents via repeated calls to the `handler` + // function. If any call to `handler` returns a non-nil error, ForeachKey + // terminates and returns that error. + // + // NOTE: The backing store for the TextMapReader may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + // + // The "foreach" callback pattern reduces unnecessary copying in some cases + // and also allows implementations to hold locks while the map is read. + ForeachKey(handler func(key, val string) error) error +} + +// TextMapCarrier allows the use of regular map[string]string +// as both TextMapWriter and TextMapReader. +type TextMapCarrier map[string]string + +// ForeachKey conforms to the TextMapReader interface. +func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error { + for k, v := range c { + if err := handler(k, v); err != nil { + return err + } + } + return nil +} + +// Set implements Set() of opentracing.TextMapWriter +func (c TextMapCarrier) Set(key, val string) { + c[key] = val +} + +// HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader. +// +// Example usage for server side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) +// +// Example usage for client side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// err := tracer.Inject( +// span.Context(), +// opentracing.HTTPHeaders, +// carrier) +// +type HTTPHeadersCarrier http.Header + +// Set conforms to the TextMapWriter interface. +func (c HTTPHeadersCarrier) Set(key, val string) { + h := http.Header(c) + h.Set(key, val) +} + +// ForeachKey conforms to the TextMapReader interface. +func (c HTTPHeadersCarrier) ForeachKey(handler func(key, val string) error) error { + for k, vals := range c { + for _, v := range vals { + if err := handler(k, v); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/opentracing/opentracing-go/span.go b/vendor/github.com/opentracing/opentracing-go/span.go new file mode 100644 index 00000000..0d3fb534 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/span.go @@ -0,0 +1,189 @@ +package opentracing + +import ( + "time" + + "github.com/opentracing/opentracing-go/log" +) + +// SpanContext represents Span state that must propagate to descendant Spans and across process +// boundaries (e.g., a tuple). +type SpanContext interface { + // ForeachBaggageItem grants access to all baggage items stored in the + // SpanContext. + // The handler function will be called for each baggage key/value pair. + // The ordering of items is not guaranteed. + // + // The bool return value indicates if the handler wants to continue iterating + // through the rest of the baggage items; for example if the handler is trying to + // find some baggage item by pattern matching the name, it can return false + // as soon as the item is found to stop further iterations. + ForeachBaggageItem(handler func(k, v string) bool) +} + +// Span represents an active, un-finished span in the OpenTracing system. +// +// Spans are created by the Tracer interface. +type Span interface { + // Sets the end timestamp and finalizes Span state. + // + // With the exception of calls to Context() (which are always allowed), + // Finish() must be the last call made to any span instance, and to do + // otherwise leads to undefined behavior. + Finish() + // FinishWithOptions is like Finish() but with explicit control over + // timestamps and log data. + FinishWithOptions(opts FinishOptions) + + // Context() yields the SpanContext for this Span. Note that the return + // value of Context() is still valid after a call to Span.Finish(), as is + // a call to Span.Context() after a call to Span.Finish(). + Context() SpanContext + + // Sets or changes the operation name. + // + // Returns a reference to this Span for chaining. + SetOperationName(operationName string) Span + + // Adds a tag to the span. + // + // If there is a pre-existing tag set for `key`, it is overwritten. + // + // Tag values can be numeric types, strings, or bools. The behavior of + // other tag value types is undefined at the OpenTracing level. If a + // tracing system does not know how to handle a particular value type, it + // may ignore the tag, but shall not panic. + // + // Returns a reference to this Span for chaining. + SetTag(key string, value interface{}) Span + + // LogFields is an efficient and type-checked way to record key:value + // logging data about a Span, though the programming interface is a little + // more verbose than LogKV(). Here's an example: + // + // span.LogFields( + // log.String("event", "soft error"), + // log.String("type", "cache timeout"), + // log.Int("waited.millis", 1500)) + // + // Also see Span.FinishWithOptions() and FinishOptions.BulkLogData. + LogFields(fields ...log.Field) + + // LogKV is a concise, readable way to record key:value logging data about + // a Span, though unfortunately this also makes it less efficient and less + // type-safe than LogFields(). Here's an example: + // + // span.LogKV( + // "event", "soft error", + // "type", "cache timeout", + // "waited.millis", 1500) + // + // For LogKV (as opposed to LogFields()), the parameters must appear as + // key-value pairs, like + // + // span.LogKV(key1, val1, key2, val2, key3, val3, ...) + // + // The keys must all be strings. The values may be strings, numeric types, + // bools, Go error instances, or arbitrary structs. + // + // (Note to implementors: consider the log.InterleavedKVToFields() helper) + LogKV(alternatingKeyValues ...interface{}) + + // SetBaggageItem sets a key:value pair on this Span and its SpanContext + // that also propagates to descendants of this Span. + // + // SetBaggageItem() enables powerful functionality given a full-stack + // opentracing integration (e.g., arbitrary application data from a mobile + // app can make it, transparently, all the way into the depths of a storage + // system), and with it some powerful costs: use this feature with care. + // + // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to + // *future* causal descendants of the associated Span. + // + // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and + // value is copied into every local *and remote* child of the associated + // Span, and that can add up to a lot of network and cpu overhead. + // + // Returns a reference to this Span for chaining. + SetBaggageItem(restrictedKey, value string) Span + + // Gets the value for a baggage item given its key. Returns the empty string + // if the value isn't found in this Span. + BaggageItem(restrictedKey string) string + + // Provides access to the Tracer that created this Span. + Tracer() Tracer + + // Deprecated: use LogFields or LogKV + LogEvent(event string) + // Deprecated: use LogFields or LogKV + LogEventWithPayload(event string, payload interface{}) + // Deprecated: use LogFields or LogKV + Log(data LogData) +} + +// LogRecord is data associated with a single Span log. Every LogRecord +// instance must specify at least one Field. +type LogRecord struct { + Timestamp time.Time + Fields []log.Field +} + +// FinishOptions allows Span.FinishWithOptions callers to override the finish +// timestamp and provide log data via a bulk interface. +type FinishOptions struct { + // FinishTime overrides the Span's finish time, or implicitly becomes + // time.Now() if FinishTime.IsZero(). + // + // FinishTime must resolve to a timestamp that's >= the Span's StartTime + // (per StartSpanOptions). + FinishTime time.Time + + // LogRecords allows the caller to specify the contents of many LogFields() + // calls with a single slice. May be nil. + // + // None of the LogRecord.Timestamp values may be .IsZero() (i.e., they must + // be set explicitly). Also, they must be >= the Span's start timestamp and + // <= the FinishTime (or time.Now() if FinishTime.IsZero()). Otherwise the + // behavior of FinishWithOptions() is undefined. + // + // If specified, the caller hands off ownership of LogRecords at + // FinishWithOptions() invocation time. + // + // If specified, the (deprecated) BulkLogData must be nil or empty. + LogRecords []LogRecord + + // BulkLogData is DEPRECATED. + BulkLogData []LogData +} + +// LogData is DEPRECATED +type LogData struct { + Timestamp time.Time + Event string + Payload interface{} +} + +// ToLogRecord converts a deprecated LogData to a non-deprecated LogRecord +func (ld *LogData) ToLogRecord() LogRecord { + var literalTimestamp time.Time + if ld.Timestamp.IsZero() { + literalTimestamp = time.Now() + } else { + literalTimestamp = ld.Timestamp + } + rval := LogRecord{ + Timestamp: literalTimestamp, + } + if ld.Payload == nil { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + } + } else { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + log.Object("payload", ld.Payload), + } + } + return rval +} diff --git a/vendor/github.com/opentracing/opentracing-go/tracer.go b/vendor/github.com/opentracing/opentracing-go/tracer.go new file mode 100644 index 00000000..715f0ced --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/tracer.go @@ -0,0 +1,304 @@ +package opentracing + +import "time" + +// Tracer is a simple, thin interface for Span creation and SpanContext +// propagation. +type Tracer interface { + + // Create, start, and return a new Span with the given `operationName` and + // incorporate the given StartSpanOption `opts`. (Note that `opts` borrows + // from the "functional options" pattern, per + // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis) + // + // A Span with no SpanReference options (e.g., opentracing.ChildOf() or + // opentracing.FollowsFrom()) becomes the root of its own trace. + // + // Examples: + // + // var tracer opentracing.Tracer = ... + // + // // The root-span case: + // sp := tracer.StartSpan("GetFeed") + // + // // The vanilla child span case: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context())) + // + // // All the bells and whistles: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context()), + // opentracing.Tag{"user_agent", loggedReq.UserAgent}, + // opentracing.StartTime(loggedReq.Timestamp), + // ) + // + StartSpan(operationName string, opts ...StartSpanOption) Span + + // Inject() takes the `sm` SpanContext instance and injects it for + // propagation within `carrier`. The actual type of `carrier` depends on + // the value of `format`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see https://godoc.org/context#WithValue). + // + // Example usage (sans error handling): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := tracer.Inject( + // span.Context(), + // opentracing.HTTPHeaders, + // carrier) + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Implementations may return opentracing.ErrUnsupportedFormat if `format` + // is not supported by (or not known by) the implementation. + // + // Implementations may return opentracing.ErrInvalidCarrier or any other + // implementation-specific error if the format is supported but injection + // fails anyway. + // + // See Tracer.Extract(). + Inject(sm SpanContext, format interface{}, carrier interface{}) error + + // Extract() returns a SpanContext instance given `format` and `carrier`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see + // https://godoc.org/golang.org/x/net/context#WithValue). + // + // Example usage (with StartSpan): + // + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) + // + // // ... assuming the ultimate goal here is to resume the trace with a + // // server-side Span: + // var serverSpan opentracing.Span + // if err == nil { + // span = tracer.StartSpan( + // rpcMethodName, ext.RPCServerOption(clientContext)) + // } else { + // span = tracer.StartSpan(rpcMethodName) + // } + // + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Return values: + // - A successful Extract returns a SpanContext instance and a nil error + // - If there was simply no SpanContext to extract in `carrier`, Extract() + // returns (nil, opentracing.ErrSpanContextNotFound) + // - If `format` is unsupported or unrecognized, Extract() returns (nil, + // opentracing.ErrUnsupportedFormat) + // - If there are more fundamental problems with the `carrier` object, + // Extract() may return opentracing.ErrInvalidCarrier, + // opentracing.ErrSpanContextCorrupted, or implementation-specific + // errors. + // + // See Tracer.Inject(). + Extract(format interface{}, carrier interface{}) (SpanContext, error) +} + +// StartSpanOptions allows Tracer.StartSpan() callers and implementors a +// mechanism to override the start timestamp, specify Span References, and make +// a single Tag or multiple Tags available at Span start time. +// +// StartSpan() callers should look at the StartSpanOption interface and +// implementations available in this package. +// +// Tracer implementations can convert a slice of `StartSpanOption` instances +// into a `StartSpanOptions` struct like so: +// +// func StartSpan(opName string, opts ...opentracing.StartSpanOption) { +// sso := opentracing.StartSpanOptions{} +// for _, o := range opts { +// o.Apply(&sso) +// } +// ... +// } +// +type StartSpanOptions struct { + // Zero or more causal references to other Spans (via their SpanContext). + // If empty, start a "root" Span (i.e., start a new trace). + References []SpanReference + + // StartTime overrides the Span's start time, or implicitly becomes + // time.Now() if StartTime.IsZero(). + StartTime time.Time + + // Tags may have zero or more entries; the restrictions on map values are + // identical to those for Span.SetTag(). May be nil. + // + // If specified, the caller hands off ownership of Tags at + // StartSpan() invocation time. + Tags map[string]interface{} +} + +// StartSpanOption instances (zero or more) may be passed to Tracer.StartSpan. +// +// StartSpanOption borrows from the "functional options" pattern, per +// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis +type StartSpanOption interface { + Apply(*StartSpanOptions) +} + +// SpanReferenceType is an enum type describing different categories of +// relationships between two Spans. If Span-2 refers to Span-1, the +// SpanReferenceType describes Span-1 from Span-2's perspective. For example, +// ChildOfRef means that Span-1 created Span-2. +// +// NOTE: Span-1 and Span-2 do *not* necessarily depend on each other for +// completion; e.g., Span-2 may be part of a background job enqueued by Span-1, +// or Span-2 may be sitting in a distributed queue behind Span-1. +type SpanReferenceType int + +const ( + // ChildOfRef refers to a parent Span that caused *and* somehow depends + // upon the new child Span. Often (but not always), the parent Span cannot + // finish until the child Span does. + // + // An timing diagram for a ChildOfRef that's blocked on the new Span: + // + // [-Parent Span---------] + // [-Child Span----] + // + // See http://opentracing.io/spec/ + // + // See opentracing.ChildOf() + ChildOfRef SpanReferenceType = iota + + // FollowsFromRef refers to a parent Span that does not depend in any way + // on the result of the new child Span. For instance, one might use + // FollowsFromRefs to describe pipeline stages separated by queues, + // or a fire-and-forget cache insert at the tail end of a web request. + // + // A FollowsFromRef Span is part of the same logical trace as the new Span: + // i.e., the new Span is somehow caused by the work of its FollowsFromRef. + // + // All of the following could be valid timing diagrams for children that + // "FollowFrom" a parent. + // + // [-Parent Span-] [-Child Span-] + // + // + // [-Parent Span--] + // [-Child Span-] + // + // + // [-Parent Span-] + // [-Child Span-] + // + // See http://opentracing.io/spec/ + // + // See opentracing.FollowsFrom() + FollowsFromRef +) + +// SpanReference is a StartSpanOption that pairs a SpanReferenceType and a +// referenced SpanContext. See the SpanReferenceType documentation for +// supported relationships. If SpanReference is created with +// ReferencedContext==nil, it has no effect. Thus it allows for a more concise +// syntax for starting spans: +// +// sc, _ := tracer.Extract(someFormat, someCarrier) +// span := tracer.StartSpan("operation", opentracing.ChildOf(sc)) +// +// The `ChildOf(sc)` option above will not panic if sc == nil, it will just +// not add the parent span reference to the options. +type SpanReference struct { + Type SpanReferenceType + ReferencedContext SpanContext +} + +// Apply satisfies the StartSpanOption interface. +func (r SpanReference) Apply(o *StartSpanOptions) { + if r.ReferencedContext != nil { + o.References = append(o.References, r) + } +} + +// ChildOf returns a StartSpanOption pointing to a dependent parent span. +// If sc == nil, the option has no effect. +// +// See ChildOfRef, SpanReference +func ChildOf(sc SpanContext) SpanReference { + return SpanReference{ + Type: ChildOfRef, + ReferencedContext: sc, + } +} + +// FollowsFrom returns a StartSpanOption pointing to a parent Span that caused +// the child Span but does not directly depend on its result in any way. +// If sc == nil, the option has no effect. +// +// See FollowsFromRef, SpanReference +func FollowsFrom(sc SpanContext) SpanReference { + return SpanReference{ + Type: FollowsFromRef, + ReferencedContext: sc, + } +} + +// StartTime is a StartSpanOption that sets an explicit start timestamp for the +// new Span. +type StartTime time.Time + +// Apply satisfies the StartSpanOption interface. +func (t StartTime) Apply(o *StartSpanOptions) { + o.StartTime = time.Time(t) +} + +// Tags are a generic map from an arbitrary string key to an opaque value type. +// The underlying tracing system is responsible for interpreting and +// serializing the values. +type Tags map[string]interface{} + +// Apply satisfies the StartSpanOption interface. +func (t Tags) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + for k, v := range t { + o.Tags[k] = v + } +} + +// Tag may be passed as a StartSpanOption to add a tag to new spans, +// or its Set method may be used to apply the tag to an existing Span, +// for example: +// +// tracer.StartSpan("opName", Tag{"Key", value}) +// +// or +// +// Tag{"key", value}.Set(span) +type Tag struct { + Key string + Value interface{} +} + +// Apply satisfies the StartSpanOption interface. +func (t Tag) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + o.Tags[t.Key] = t.Value +} + +// Set applies the tag to an existing Span. +func (t Tag) Set(s Span) { + s.SetTag(t.Key, t.Value) +} diff --git a/vendor/github.com/pelletier/go-toml/.dockerignore b/vendor/github.com/pelletier/go-toml/.dockerignore new file mode 100644 index 00000000..7b588347 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/.dockerignore @@ -0,0 +1,2 @@ +cmd/tomll/tomll +cmd/tomljson/tomljson diff --git a/vendor/github.com/pelletier/go-toml/.gitignore b/vendor/github.com/pelletier/go-toml/.gitignore new file mode 100644 index 00000000..e6ba63a5 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/.gitignore @@ -0,0 +1,5 @@ +test_program/test_program_bin +fuzz/ +cmd/tomll/tomll +cmd/tomljson/tomljson +cmd/tomltestgen/tomltestgen diff --git a/vendor/github.com/pelletier/go-toml/.travis.yml b/vendor/github.com/pelletier/go-toml/.travis.yml new file mode 100644 index 00000000..abb03e99 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/.travis.yml @@ -0,0 +1,22 @@ +sudo: false +language: go +go: + - 1.11.x + - 1.12.x + - tip +matrix: + allow_failures: + - go: tip + fast_finish: true +env: + - GO111MODULE=on +script: + - if [ -n "$(go fmt ./...)" ]; then exit 1; fi + - go test github.com/pelletier/go-toml -race -coverprofile=coverage.txt -covermode=atomic + - go test github.com/pelletier/go-toml/cmd/tomljson + - go test github.com/pelletier/go-toml/cmd/tomll + - go test github.com/pelletier/go-toml/query + - ./benchmark.sh $TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/pelletier/go-toml/CONTRIBUTING.md b/vendor/github.com/pelletier/go-toml/CONTRIBUTING.md new file mode 100644 index 00000000..405c911c --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/CONTRIBUTING.md @@ -0,0 +1,132 @@ +## Contributing + +Thank you for your interest in go-toml! We appreciate you considering +contributing to go-toml! + +The main goal is the project is to provide an easy-to-use TOML +implementation for Go that gets the job done and gets out of your way – +dealing with TOML is probably not the central piece of your project. + +As the single maintainer of go-toml, time is scarce. All help, big or +small, is more than welcomed! + +### Ask questions + +Any question you may have, somebody else might have it too. Always feel +free to ask them on the [issues tracker][issues-tracker]. We will try to +answer them as clearly and quickly as possible, time permitting. + +Asking questions also helps us identify areas where the documentation needs +improvement, or new features that weren't envisioned before. Sometimes, a +seemingly innocent question leads to the fix of a bug. Don't hesitate and +ask away! + +### Improve the documentation + +The best way to share your knowledge and experience with go-toml is to +improve the documentation. Fix a typo, clarify an interface, add an +example, anything goes! + +The documentation is present in the [README][readme] and thorough the +source code. On release, it gets updated on [GoDoc][godoc]. To make a +change to the documentation, create a pull request with your proposed +changes. For simple changes like that, the easiest way to go is probably +the "Fork this project and edit the file" button on Github, displayed at +the top right of the file. Unless it's a trivial change (for example a +typo), provide a little bit of context in your pull request description or +commit message. + +### Report a bug + +Found a bug! Sorry to hear that :(. Help us and other track them down and +fix by reporting it. [File a new bug report][bug-report] on the [issues +tracker][issues-tracker]. The template should provide enough guidance on +what to include. When in doubt: add more details! By reducing ambiguity and +providing more information, it decreases back and forth and saves everyone +time. + +### Code changes + +Want to contribute a patch? Very happy to hear that! + +First, some high-level rules: + +* A short proposal with some POC code is better than a lengthy piece of + text with no code. Code speaks louder than words. +* No backward-incompatible patch will be accepted unless discussed. + Sometimes it's hard, and Go's lack of versioning by default does not + help, but we try not to break people's programs unless we absolutely have + to. +* If you are writing a new feature or extending an existing one, make sure + to write some documentation. +* Bug fixes need to be accompanied with regression tests. +* New code needs to be tested. +* Your commit messages need to explain why the change is needed, even if + already included in the PR description. + +It does sound like a lot, but those best practices are here to save time +overall and continuously improve the quality of the project, which is +something everyone benefits from. + +#### Get started + +The fairly standard code contribution process looks like that: + +1. [Fork the project][fork]. +2. Make your changes, commit on any branch you like. +3. [Open up a pull request][pull-request] +4. Review, potential ask for changes. +5. Merge. You're in! + +Feel free to ask for help! You can create draft pull requests to gather +some early feedback! + +#### Run the tests + +You can run tests for go-toml using Go's test tool: `go test ./...`. +When creating a pull requests, all tests will be ran on Linux on a few Go +versions (Travis CI), and on Windows using the latest Go version +(AppVeyor). + +#### Style + +Try to look around and follow the same format and structure as the rest of +the code. We enforce using `go fmt` on the whole code base. + +--- + +### Maintainers-only + +#### Merge pull request + +Checklist: + +* Passing CI. +* Does not introduce backward-incompatible changes (unless discussed). +* Has relevant doc changes. +* Has relevant unit tests. + +1. Merge using "squash and merge". +2. Make sure to edit the commit message to keep all the useful information + nice and clean. +3. Make sure the commit title is clear and contains the PR number (#123). + +#### New release + +1. Go to [releases][releases]. Click on "X commits to master since this + release". +2. Make note of all the changes. Look for backward incompatible changes, + new features, and bug fixes. +3. Pick the new version using the above and semver. +4. Create a [new release][new-release]. +5. Follow the same format as [1.1.0][release-110]. + +[issues-tracker]: https://github.com/pelletier/go-toml/issues +[bug-report]: https://github.com/pelletier/go-toml/issues/new?template=bug_report.md +[godoc]: https://godoc.org/github.com/pelletier/go-toml +[readme]: ./README.md +[fork]: https://help.github.com/articles/fork-a-repo +[pull-request]: https://help.github.com/en/articles/creating-a-pull-request +[releases]: https://github.com/pelletier/go-toml/releases +[new-release]: https://github.com/pelletier/go-toml/releases/new +[release-110]: https://github.com/pelletier/go-toml/releases/tag/v1.1.0 diff --git a/vendor/github.com/pelletier/go-toml/Dockerfile b/vendor/github.com/pelletier/go-toml/Dockerfile new file mode 100644 index 00000000..8f439d47 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/Dockerfile @@ -0,0 +1,10 @@ +FROM golang:1.12-alpine3.9 as builder +WORKDIR /go/src/github.com/pelletier/go-toml +COPY . . +ENV CGO_ENABLED=0 +ENV GOOS=linux +RUN go install ./... + +FROM scratch +COPY --from=builder /go/bin/tomll /usr/bin/tomll +COPY --from=builder /go/bin/tomljson /usr/bin/tomljson diff --git a/vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..041cdc4a --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,5 @@ +**Issue:** add link to pelletier/go-toml issue here + +Explanation of what this pull request does. + +More detailed description of the decisions being made and the reasons why (if the patch is non-trivial). diff --git a/vendor/github.com/pelletier/go-toml/README.md b/vendor/github.com/pelletier/go-toml/README.md new file mode 100644 index 00000000..f0311b99 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/README.md @@ -0,0 +1,145 @@ +# go-toml + +Go library for the [TOML](https://github.com/mojombo/toml) format. + +This library supports TOML version +[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) + +[![GoDoc](https://godoc.org/github.com/pelletier/go-toml?status.svg)](http://godoc.org/github.com/pelletier/go-toml) +[![license](https://img.shields.io/github/license/pelletier/go-toml.svg)](https://github.com/pelletier/go-toml/blob/master/LICENSE) +[![Build Status](https://travis-ci.org/pelletier/go-toml.svg?branch=master)](https://travis-ci.org/pelletier/go-toml) +[![Windows Build status](https://ci.appveyor.com/api/projects/status/4aepwwjori266hkt/branch/master?svg=true)](https://ci.appveyor.com/project/pelletier/go-toml/branch/master) +[![codecov](https://codecov.io/gh/pelletier/go-toml/branch/master/graph/badge.svg)](https://codecov.io/gh/pelletier/go-toml) +[![Go Report Card](https://goreportcard.com/badge/github.com/pelletier/go-toml)](https://goreportcard.com/report/github.com/pelletier/go-toml) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fpelletier%2Fgo-toml.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fpelletier%2Fgo-toml?ref=badge_shield) + +## Features + +Go-toml provides the following features for using data parsed from TOML documents: + +* Load TOML documents from files and string data +* Easily navigate TOML structure using Tree +* Mashaling and unmarshaling to and from data structures +* Line & column position data for all parsed elements +* [Query support similar to JSON-Path](query/) +* Syntax errors contain line and column numbers + +## Import + +```go +import "github.com/pelletier/go-toml" +``` + +## Usage example + +Read a TOML document: + +```go +config, _ := toml.Load(` +[postgres] +user = "pelletier" +password = "mypassword"`) +// retrieve data directly +user := config.Get("postgres.user").(string) + +// or using an intermediate object +postgresConfig := config.Get("postgres").(*toml.Tree) +password := postgresConfig.Get("password").(string) +``` + +Or use Unmarshal: + +```go +type Postgres struct { + User string + Password string +} +type Config struct { + Postgres Postgres +} + +doc := []byte(` +[Postgres] +User = "pelletier" +Password = "mypassword"`) + +config := Config{} +toml.Unmarshal(doc, &config) +fmt.Println("user=", config.Postgres.User) +``` + +Or use a query: + +```go +// use a query to gather elements without walking the tree +q, _ := query.Compile("$..[user,password]") +results := q.Execute(config) +for ii, item := range results.Values() { + fmt.Println("Query result %d: %v", ii, item) +} +``` + +## Documentation + +The documentation and additional examples are available at +[godoc.org](http://godoc.org/github.com/pelletier/go-toml). + +## Tools + +Go-toml provides two handy command line tools: + +* `tomll`: Reads TOML files and lint them. + + ``` + go install github.com/pelletier/go-toml/cmd/tomll + tomll --help + ``` +* `tomljson`: Reads a TOML file and outputs its JSON representation. + + ``` + go install github.com/pelletier/go-toml/cmd/tomljson + tomljson --help + ``` + +### Docker image + +Those tools are also availble as a Docker image from +[dockerhub](https://hub.docker.com/r/pelletier/go-toml). For example, to +use `tomljson`: + +``` +docker run -v $PWD:/workdir pelletier/go-toml tomljson /workdir/example.toml +``` + +Only master (`latest`) and tagged versions are published to dockerhub. You +can build your own image as usual: + +``` +docker build -t go-toml . +``` + +## Contribute + +Feel free to report bugs and patches using GitHub's pull requests system on +[pelletier/go-toml](https://github.com/pelletier/go-toml). Any feedback would be +much appreciated! + +### Run tests + +`go test ./...` + +### Fuzzing + +The script `./fuzz.sh` is available to +run [go-fuzz](https://github.com/dvyukov/go-fuzz) on go-toml. + +## Versioning + +Go-toml follows [Semantic Versioning](http://semver.org/). The supported version +of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of +this document. The last two major versions of Go are supported +(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)). + +## License + +The MIT License (MIT). Read [LICENSE](LICENSE). diff --git a/vendor/github.com/pelletier/go-toml/appveyor.yml b/vendor/github.com/pelletier/go-toml/appveyor.yml new file mode 100644 index 00000000..40e8a415 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/appveyor.yml @@ -0,0 +1,34 @@ +version: "{build}" + +# Source Config +clone_folder: c:\gopath\src\github.com\pelletier\go-toml + +# Build host +environment: + GOPATH: c:\gopath + DEPTESTBYPASS501: 1 + GOVERSION: 1.12 + GO111MODULE: on + +init: + - git config --global core.autocrlf input + +# Build +install: + # Install the specific Go version. + - rmdir c:\go /s /q + - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.msi + - msiexec /i go%GOVERSION%.windows-amd64.msi /q + - choco install bzr + - set Path=c:\go\bin;c:\gopath\bin;C:\Program Files (x86)\Bazaar\;C:\Program Files\Mercurial\%Path% + - go version + - go env + +build: false +deploy: false + +test_script: + - go test github.com/pelletier/go-toml + - go test github.com/pelletier/go-toml/cmd/tomljson + - go test github.com/pelletier/go-toml/cmd/tomll + - go test github.com/pelletier/go-toml/query diff --git a/vendor/github.com/pelletier/go-toml/go.mod b/vendor/github.com/pelletier/go-toml/go.mod new file mode 100644 index 00000000..f4690e19 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/go.mod @@ -0,0 +1,9 @@ +module github.com/pelletier/go-toml + +go 1.12 + +require ( + github.com/BurntSushi/toml v0.3.1 + github.com/davecgh/go-spew v1.1.1 + gopkg.in/yaml.v2 v2.2.2 +) diff --git a/vendor/github.com/pelletier/go-toml/go.sum b/vendor/github.com/pelletier/go-toml/go.sum new file mode 100644 index 00000000..8d91a478 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/go.sum @@ -0,0 +1,7 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/pelletier/go-toml/keysparsing.go b/vendor/github.com/pelletier/go-toml/keysparsing.go new file mode 100644 index 00000000..e923bc4f --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/keysparsing.go @@ -0,0 +1,113 @@ +// Parsing keys handling both bare and quoted keys. + +package toml + +import ( + "errors" + "fmt" + "unicode" +) + +// Convert the bare key group string to an array. +// The input supports double quotation and single quotation, +// but escape sequences are not supported. Lexers must unescape them beforehand. +func parseKey(key string) ([]string, error) { + runes := []rune(key) + var groups []string + + if len(key) == 0 { + return nil, errors.New("empty key") + } + + idx := 0 + for idx < len(runes) { + for ; idx < len(runes) && isSpace(runes[idx]); idx++ { + // skip leading whitespace + } + if idx >= len(runes) { + break + } + r := runes[idx] + if isValidBareChar(r) { + // parse bare key + startIdx := idx + endIdx := -1 + idx++ + for idx < len(runes) { + r = runes[idx] + if isValidBareChar(r) { + idx++ + } else if r == '.' { + endIdx = idx + break + } else if isSpace(r) { + endIdx = idx + for ; idx < len(runes) && isSpace(runes[idx]); idx++ { + // skip trailing whitespace + } + if idx < len(runes) && runes[idx] != '.' { + return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx]) + } + break + } else { + return nil, fmt.Errorf("invalid bare key character: %c", r) + } + } + if endIdx == -1 { + endIdx = idx + } + groups = append(groups, string(runes[startIdx:endIdx])) + } else if r == '\'' { + // parse single quoted key + idx++ + startIdx := idx + for { + if idx >= len(runes) { + return nil, fmt.Errorf("unclosed single-quoted key") + } + r = runes[idx] + if r == '\'' { + groups = append(groups, string(runes[startIdx:idx])) + idx++ + break + } + idx++ + } + } else if r == '"' { + // parse double quoted key + idx++ + startIdx := idx + for { + if idx >= len(runes) { + return nil, fmt.Errorf("unclosed double-quoted key") + } + r = runes[idx] + if r == '"' { + groups = append(groups, string(runes[startIdx:idx])) + idx++ + break + } + idx++ + } + } else if r == '.' { + idx++ + if idx >= len(runes) { + return nil, fmt.Errorf("unexpected end of key") + } + r = runes[idx] + if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' { + return nil, fmt.Errorf("expecting key part after dot") + } + } else { + return nil, fmt.Errorf("invalid key character: %c", r) + } + } + if len(groups) == 0 { + return nil, fmt.Errorf("empty key") + } + return groups, nil +} + +func isValidBareChar(r rune) bool { + return isAlphanumeric(r) || r == '-' || unicode.IsNumber(r) +} diff --git a/vendor/github.com/pelletier/go-toml/lexer.go b/vendor/github.com/pelletier/go-toml/lexer.go new file mode 100644 index 00000000..6254d390 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/lexer.go @@ -0,0 +1,752 @@ +// TOML lexer. +// +// Written using the principles developed by Rob Pike in +// http://www.youtube.com/watch?v=HxaD_trXwRE + +package toml + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +var dateRegexp *regexp.Regexp + +// Define state functions +type tomlLexStateFn func() tomlLexStateFn + +// Define lexer +type tomlLexer struct { + inputIdx int + input []rune // Textual source + currentTokenStart int + currentTokenStop int + tokens []token + depth int + line int + col int + endbufferLine int + endbufferCol int +} + +// Basic read operations on input + +func (l *tomlLexer) read() rune { + r := l.peek() + if r == '\n' { + l.endbufferLine++ + l.endbufferCol = 1 + } else { + l.endbufferCol++ + } + l.inputIdx++ + return r +} + +func (l *tomlLexer) next() rune { + r := l.read() + + if r != eof { + l.currentTokenStop++ + } + return r +} + +func (l *tomlLexer) ignore() { + l.currentTokenStart = l.currentTokenStop + l.line = l.endbufferLine + l.col = l.endbufferCol +} + +func (l *tomlLexer) skip() { + l.next() + l.ignore() +} + +func (l *tomlLexer) fastForward(n int) { + for i := 0; i < n; i++ { + l.next() + } +} + +func (l *tomlLexer) emitWithValue(t tokenType, value string) { + l.tokens = append(l.tokens, token{ + Position: Position{l.line, l.col}, + typ: t, + val: value, + }) + l.ignore() +} + +func (l *tomlLexer) emit(t tokenType) { + l.emitWithValue(t, string(l.input[l.currentTokenStart:l.currentTokenStop])) +} + +func (l *tomlLexer) peek() rune { + if l.inputIdx >= len(l.input) { + return eof + } + return l.input[l.inputIdx] +} + +func (l *tomlLexer) peekString(size int) string { + maxIdx := len(l.input) + upperIdx := l.inputIdx + size // FIXME: potential overflow + if upperIdx > maxIdx { + upperIdx = maxIdx + } + return string(l.input[l.inputIdx:upperIdx]) +} + +func (l *tomlLexer) follow(next string) bool { + return next == l.peekString(len(next)) +} + +// Error management + +func (l *tomlLexer) errorf(format string, args ...interface{}) tomlLexStateFn { + l.tokens = append(l.tokens, token{ + Position: Position{l.line, l.col}, + typ: tokenError, + val: fmt.Sprintf(format, args...), + }) + return nil +} + +// State functions + +func (l *tomlLexer) lexVoid() tomlLexStateFn { + for { + next := l.peek() + switch next { + case '[': + return l.lexTableKey + case '#': + return l.lexComment(l.lexVoid) + case '=': + return l.lexEqual + case '\r': + fallthrough + case '\n': + l.skip() + continue + } + + if isSpace(next) { + l.skip() + } + + if l.depth > 0 { + return l.lexRvalue + } + + if isKeyStartChar(next) { + return l.lexKey + } + + if next == eof { + l.next() + break + } + } + + l.emit(tokenEOF) + return nil +} + +func (l *tomlLexer) lexRvalue() tomlLexStateFn { + for { + next := l.peek() + switch next { + case '.': + return l.errorf("cannot start float with a dot") + case '=': + return l.lexEqual + case '[': + l.depth++ + return l.lexLeftBracket + case ']': + l.depth-- + return l.lexRightBracket + case '{': + return l.lexLeftCurlyBrace + case '}': + return l.lexRightCurlyBrace + case '#': + return l.lexComment(l.lexRvalue) + case '"': + return l.lexString + case '\'': + return l.lexLiteralString + case ',': + return l.lexComma + case '\r': + fallthrough + case '\n': + l.skip() + if l.depth == 0 { + return l.lexVoid + } + return l.lexRvalue + case '_': + return l.errorf("cannot start number with underscore") + } + + if l.follow("true") { + return l.lexTrue + } + + if l.follow("false") { + return l.lexFalse + } + + if l.follow("inf") { + return l.lexInf + } + + if l.follow("nan") { + return l.lexNan + } + + if isSpace(next) { + l.skip() + continue + } + + if next == eof { + l.next() + break + } + + possibleDate := l.peekString(35) + dateMatch := dateRegexp.FindString(possibleDate) + if dateMatch != "" { + l.fastForward(len(dateMatch)) + return l.lexDate + } + + if next == '+' || next == '-' || isDigit(next) { + return l.lexNumber + } + + if isAlphanumeric(next) { + return l.lexKey + } + + return l.errorf("no value can start with %c", next) + } + + l.emit(tokenEOF) + return nil +} + +func (l *tomlLexer) lexLeftCurlyBrace() tomlLexStateFn { + l.next() + l.emit(tokenLeftCurlyBrace) + return l.lexRvalue +} + +func (l *tomlLexer) lexRightCurlyBrace() tomlLexStateFn { + l.next() + l.emit(tokenRightCurlyBrace) + return l.lexRvalue +} + +func (l *tomlLexer) lexDate() tomlLexStateFn { + l.emit(tokenDate) + return l.lexRvalue +} + +func (l *tomlLexer) lexTrue() tomlLexStateFn { + l.fastForward(4) + l.emit(tokenTrue) + return l.lexRvalue +} + +func (l *tomlLexer) lexFalse() tomlLexStateFn { + l.fastForward(5) + l.emit(tokenFalse) + return l.lexRvalue +} + +func (l *tomlLexer) lexInf() tomlLexStateFn { + l.fastForward(3) + l.emit(tokenInf) + return l.lexRvalue +} + +func (l *tomlLexer) lexNan() tomlLexStateFn { + l.fastForward(3) + l.emit(tokenNan) + return l.lexRvalue +} + +func (l *tomlLexer) lexEqual() tomlLexStateFn { + l.next() + l.emit(tokenEqual) + return l.lexRvalue +} + +func (l *tomlLexer) lexComma() tomlLexStateFn { + l.next() + l.emit(tokenComma) + return l.lexRvalue +} + +// Parse the key and emits its value without escape sequences. +// bare keys, basic string keys and literal string keys are supported. +func (l *tomlLexer) lexKey() tomlLexStateFn { + growingString := "" + + for r := l.peek(); isKeyChar(r) || r == '\n' || r == '\r'; r = l.peek() { + if r == '"' { + l.next() + str, err := l.lexStringAsString(`"`, false, true) + if err != nil { + return l.errorf(err.Error()) + } + growingString += "\"" + str + "\"" + l.next() + continue + } else if r == '\'' { + l.next() + str, err := l.lexLiteralStringAsString(`'`, false) + if err != nil { + return l.errorf(err.Error()) + } + growingString += "'" + str + "'" + l.next() + continue + } else if r == '\n' { + return l.errorf("keys cannot contain new lines") + } else if isSpace(r) { + break + } else if r == '.' { + // skip + } else if !isValidBareChar(r) { + return l.errorf("keys cannot contain %c character", r) + } + growingString += string(r) + l.next() + } + l.emitWithValue(tokenKey, growingString) + return l.lexVoid +} + +func (l *tomlLexer) lexComment(previousState tomlLexStateFn) tomlLexStateFn { + return func() tomlLexStateFn { + for next := l.peek(); next != '\n' && next != eof; next = l.peek() { + if next == '\r' && l.follow("\r\n") { + break + } + l.next() + } + l.ignore() + return previousState + } +} + +func (l *tomlLexer) lexLeftBracket() tomlLexStateFn { + l.next() + l.emit(tokenLeftBracket) + return l.lexRvalue +} + +func (l *tomlLexer) lexLiteralStringAsString(terminator string, discardLeadingNewLine bool) (string, error) { + growingString := "" + + if discardLeadingNewLine { + if l.follow("\r\n") { + l.skip() + l.skip() + } else if l.peek() == '\n' { + l.skip() + } + } + + // find end of string + for { + if l.follow(terminator) { + return growingString, nil + } + + next := l.peek() + if next == eof { + break + } + growingString += string(l.next()) + } + + return "", errors.New("unclosed string") +} + +func (l *tomlLexer) lexLiteralString() tomlLexStateFn { + l.skip() + + // handle special case for triple-quote + terminator := "'" + discardLeadingNewLine := false + if l.follow("''") { + l.skip() + l.skip() + terminator = "'''" + discardLeadingNewLine = true + } + + str, err := l.lexLiteralStringAsString(terminator, discardLeadingNewLine) + if err != nil { + return l.errorf(err.Error()) + } + + l.emitWithValue(tokenString, str) + l.fastForward(len(terminator)) + l.ignore() + return l.lexRvalue +} + +// Lex a string and return the results as a string. +// Terminator is the substring indicating the end of the token. +// The resulting string does not include the terminator. +func (l *tomlLexer) lexStringAsString(terminator string, discardLeadingNewLine, acceptNewLines bool) (string, error) { + growingString := "" + + if discardLeadingNewLine { + if l.follow("\r\n") { + l.skip() + l.skip() + } else if l.peek() == '\n' { + l.skip() + } + } + + for { + if l.follow(terminator) { + return growingString, nil + } + + if l.follow("\\") { + l.next() + switch l.peek() { + case '\r': + fallthrough + case '\n': + fallthrough + case '\t': + fallthrough + case ' ': + // skip all whitespace chars following backslash + for strings.ContainsRune("\r\n\t ", l.peek()) { + l.next() + } + case '"': + growingString += "\"" + l.next() + case 'n': + growingString += "\n" + l.next() + case 'b': + growingString += "\b" + l.next() + case 'f': + growingString += "\f" + l.next() + case '/': + growingString += "/" + l.next() + case 't': + growingString += "\t" + l.next() + case 'r': + growingString += "\r" + l.next() + case '\\': + growingString += "\\" + l.next() + case 'u': + l.next() + code := "" + for i := 0; i < 4; i++ { + c := l.peek() + if !isHexDigit(c) { + return "", errors.New("unfinished unicode escape") + } + l.next() + code = code + string(c) + } + intcode, err := strconv.ParseInt(code, 16, 32) + if err != nil { + return "", errors.New("invalid unicode escape: \\u" + code) + } + growingString += string(rune(intcode)) + case 'U': + l.next() + code := "" + for i := 0; i < 8; i++ { + c := l.peek() + if !isHexDigit(c) { + return "", errors.New("unfinished unicode escape") + } + l.next() + code = code + string(c) + } + intcode, err := strconv.ParseInt(code, 16, 64) + if err != nil { + return "", errors.New("invalid unicode escape: \\U" + code) + } + growingString += string(rune(intcode)) + default: + return "", errors.New("invalid escape sequence: \\" + string(l.peek())) + } + } else { + r := l.peek() + + if 0x00 <= r && r <= 0x1F && !(acceptNewLines && (r == '\n' || r == '\r')) { + return "", fmt.Errorf("unescaped control character %U", r) + } + l.next() + growingString += string(r) + } + + if l.peek() == eof { + break + } + } + + return "", errors.New("unclosed string") +} + +func (l *tomlLexer) lexString() tomlLexStateFn { + l.skip() + + // handle special case for triple-quote + terminator := `"` + discardLeadingNewLine := false + acceptNewLines := false + if l.follow(`""`) { + l.skip() + l.skip() + terminator = `"""` + discardLeadingNewLine = true + acceptNewLines = true + } + + str, err := l.lexStringAsString(terminator, discardLeadingNewLine, acceptNewLines) + + if err != nil { + return l.errorf(err.Error()) + } + + l.emitWithValue(tokenString, str) + l.fastForward(len(terminator)) + l.ignore() + return l.lexRvalue +} + +func (l *tomlLexer) lexTableKey() tomlLexStateFn { + l.next() + + if l.peek() == '[' { + // token '[[' signifies an array of tables + l.next() + l.emit(tokenDoubleLeftBracket) + return l.lexInsideTableArrayKey + } + // vanilla table key + l.emit(tokenLeftBracket) + return l.lexInsideTableKey +} + +// Parse the key till "]]", but only bare keys are supported +func (l *tomlLexer) lexInsideTableArrayKey() tomlLexStateFn { + for r := l.peek(); r != eof; r = l.peek() { + switch r { + case ']': + if l.currentTokenStop > l.currentTokenStart { + l.emit(tokenKeyGroupArray) + } + l.next() + if l.peek() != ']' { + break + } + l.next() + l.emit(tokenDoubleRightBracket) + return l.lexVoid + case '[': + return l.errorf("table array key cannot contain ']'") + default: + l.next() + } + } + return l.errorf("unclosed table array key") +} + +// Parse the key till "]" but only bare keys are supported +func (l *tomlLexer) lexInsideTableKey() tomlLexStateFn { + for r := l.peek(); r != eof; r = l.peek() { + switch r { + case ']': + if l.currentTokenStop > l.currentTokenStart { + l.emit(tokenKeyGroup) + } + l.next() + l.emit(tokenRightBracket) + return l.lexVoid + case '[': + return l.errorf("table key cannot contain ']'") + default: + l.next() + } + } + return l.errorf("unclosed table key") +} + +func (l *tomlLexer) lexRightBracket() tomlLexStateFn { + l.next() + l.emit(tokenRightBracket) + return l.lexRvalue +} + +type validRuneFn func(r rune) bool + +func isValidHexRune(r rune) bool { + return r >= 'a' && r <= 'f' || + r >= 'A' && r <= 'F' || + r >= '0' && r <= '9' || + r == '_' +} + +func isValidOctalRune(r rune) bool { + return r >= '0' && r <= '7' || r == '_' +} + +func isValidBinaryRune(r rune) bool { + return r == '0' || r == '1' || r == '_' +} + +func (l *tomlLexer) lexNumber() tomlLexStateFn { + r := l.peek() + + if r == '0' { + follow := l.peekString(2) + if len(follow) == 2 { + var isValidRune validRuneFn + switch follow[1] { + case 'x': + isValidRune = isValidHexRune + case 'o': + isValidRune = isValidOctalRune + case 'b': + isValidRune = isValidBinaryRune + default: + if follow[1] >= 'a' && follow[1] <= 'z' || follow[1] >= 'A' && follow[1] <= 'Z' { + return l.errorf("unknown number base: %s. possible options are x (hex) o (octal) b (binary)", string(follow[1])) + } + } + + if isValidRune != nil { + l.next() + l.next() + digitSeen := false + for { + next := l.peek() + if !isValidRune(next) { + break + } + digitSeen = true + l.next() + } + + if !digitSeen { + return l.errorf("number needs at least one digit") + } + + l.emit(tokenInteger) + + return l.lexRvalue + } + } + } + + if r == '+' || r == '-' { + l.next() + if l.follow("inf") { + return l.lexInf + } + if l.follow("nan") { + return l.lexNan + } + } + + pointSeen := false + expSeen := false + digitSeen := false + for { + next := l.peek() + if next == '.' { + if pointSeen { + return l.errorf("cannot have two dots in one float") + } + l.next() + if !isDigit(l.peek()) { + return l.errorf("float cannot end with a dot") + } + pointSeen = true + } else if next == 'e' || next == 'E' { + expSeen = true + l.next() + r := l.peek() + if r == '+' || r == '-' { + l.next() + } + } else if isDigit(next) { + digitSeen = true + l.next() + } else if next == '_' { + l.next() + } else { + break + } + if pointSeen && !digitSeen { + return l.errorf("cannot start float with a dot") + } + } + + if !digitSeen { + return l.errorf("no digit in that number") + } + if pointSeen || expSeen { + l.emit(tokenFloat) + } else { + l.emit(tokenInteger) + } + return l.lexRvalue +} + +func (l *tomlLexer) run() { + for state := l.lexVoid; state != nil; { + state = state() + } +} + +func init() { + dateRegexp = regexp.MustCompile(`^\d{1,4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})`) +} + +// Entry point +func lexToml(inputBytes []byte) []token { + runes := bytes.Runes(inputBytes) + l := &tomlLexer{ + input: runes, + tokens: make([]token, 0, 256), + line: 1, + col: 1, + endbufferLine: 1, + endbufferCol: 1, + } + l.run() + return l.tokens +} diff --git a/vendor/github.com/pelletier/go-toml/marshal.go b/vendor/github.com/pelletier/go-toml/marshal.go new file mode 100644 index 00000000..0e1c57e8 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/marshal.go @@ -0,0 +1,803 @@ +package toml + +import ( + "bytes" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strconv" + "strings" + "time" +) + +const ( + tagFieldName = "toml" + tagFieldComment = "comment" + tagCommented = "commented" + tagMultiline = "multiline" + tagDefault = "default" +) + +type tomlOpts struct { + name string + comment string + commented bool + multiline bool + include bool + omitempty bool + defaultValue string +} + +type encOpts struct { + quoteMapKeys bool + arraysOneElementPerLine bool +} + +var encOptsDefaults = encOpts{ + quoteMapKeys: false, +} + +type annotation struct { + tag string + comment string + commented string + multiline string + defaultValue string +} + +var annotationDefault = annotation{ + tag: tagFieldName, + comment: tagFieldComment, + commented: tagCommented, + multiline: tagMultiline, + defaultValue: tagDefault, +} + +type marshalOrder int + +// Orders the Encoder can write the fields to the output stream. +const ( + // Sort fields alphabetically. + OrderAlphabetical marshalOrder = iota + 1 + // Preserve the order the fields are encountered. For example, the order of fields in + // a struct. + OrderPreserve +) + +var timeType = reflect.TypeOf(time.Time{}) +var marshalerType = reflect.TypeOf(new(Marshaler)).Elem() + +// Check if the given marshal type maps to a Tree primitive +func isPrimitive(mtype reflect.Type) bool { + switch mtype.Kind() { + case reflect.Ptr: + return isPrimitive(mtype.Elem()) + case reflect.Bool: + return true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Struct: + return mtype == timeType || isCustomMarshaler(mtype) + default: + return false + } +} + +// Check if the given marshal type maps to a Tree slice +func isTreeSlice(mtype reflect.Type) bool { + switch mtype.Kind() { + case reflect.Slice: + return !isOtherSlice(mtype) + default: + return false + } +} + +// Check if the given marshal type maps to a non-Tree slice +func isOtherSlice(mtype reflect.Type) bool { + switch mtype.Kind() { + case reflect.Ptr: + return isOtherSlice(mtype.Elem()) + case reflect.Slice: + return isPrimitive(mtype.Elem()) || isOtherSlice(mtype.Elem()) + default: + return false + } +} + +// Check if the given marshal type maps to a Tree +func isTree(mtype reflect.Type) bool { + switch mtype.Kind() { + case reflect.Map: + return true + case reflect.Struct: + return !isPrimitive(mtype) + default: + return false + } +} + +func isCustomMarshaler(mtype reflect.Type) bool { + return mtype.Implements(marshalerType) +} + +func callCustomMarshaler(mval reflect.Value) ([]byte, error) { + return mval.Interface().(Marshaler).MarshalTOML() +} + +// Marshaler is the interface implemented by types that +// can marshal themselves into valid TOML. +type Marshaler interface { + MarshalTOML() ([]byte, error) +} + +/* +Marshal returns the TOML encoding of v. Behavior is similar to the Go json +encoder, except that there is no concept of a Marshaler interface or MarshalTOML +function for sub-structs, and currently only definite types can be marshaled +(i.e. no `interface{}`). + +The following struct annotations are supported: + + toml:"Field" Overrides the field's name to output. + omitempty When set, empty values and groups are not emitted. + comment:"comment" Emits a # comment on the same line. This supports new lines. + commented:"true" Emits the value as commented. + +Note that pointers are automatically assigned the "omitempty" option, as TOML +explicitly does not handle null values (saying instead the label should be +dropped). + +Tree structural types and corresponding marshal types: + + *Tree (*)struct, (*)map[string]interface{} + []*Tree (*)[](*)struct, (*)[](*)map[string]interface{} + []interface{} (as interface{}) (*)[]primitive, (*)[]([]interface{}) + interface{} (*)primitive + +Tree primitive types and corresponding marshal types: + + uint64 uint, uint8-uint64, pointers to same + int64 int, int8-uint64, pointers to same + float64 float32, float64, pointers to same + string string, pointers to same + bool bool, pointers to same + time.Time time.Time{}, pointers to same + +For additional flexibility, use the Encoder API. +*/ +func Marshal(v interface{}) ([]byte, error) { + return NewEncoder(nil).marshal(v) +} + +// Encoder writes TOML values to an output stream. +type Encoder struct { + w io.Writer + encOpts + annotation + line int + col int + order marshalOrder +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{ + w: w, + encOpts: encOptsDefaults, + annotation: annotationDefault, + line: 0, + col: 1, + order: OrderAlphabetical, + } +} + +// Encode writes the TOML encoding of v to the stream. +// +// See the documentation for Marshal for details. +func (e *Encoder) Encode(v interface{}) error { + b, err := e.marshal(v) + if err != nil { + return err + } + if _, err := e.w.Write(b); err != nil { + return err + } + return nil +} + +// QuoteMapKeys sets up the encoder to encode +// maps with string type keys with quoted TOML keys. +// +// This relieves the character limitations on map keys. +func (e *Encoder) QuoteMapKeys(v bool) *Encoder { + e.quoteMapKeys = v + return e +} + +// ArraysWithOneElementPerLine sets up the encoder to encode arrays +// with more than one element on multiple lines instead of one. +// +// For example: +// +// A = [1,2,3] +// +// Becomes +// +// A = [ +// 1, +// 2, +// 3, +// ] +func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder { + e.arraysOneElementPerLine = v + return e +} + +// Order allows to change in which order fields will be written to the output stream. +func (e *Encoder) Order(ord marshalOrder) *Encoder { + e.order = ord + return e +} + +// SetTagName allows changing default tag "toml" +func (e *Encoder) SetTagName(v string) *Encoder { + e.tag = v + return e +} + +// SetTagComment allows changing default tag "comment" +func (e *Encoder) SetTagComment(v string) *Encoder { + e.comment = v + return e +} + +// SetTagCommented allows changing default tag "commented" +func (e *Encoder) SetTagCommented(v string) *Encoder { + e.commented = v + return e +} + +// SetTagMultiline allows changing default tag "multiline" +func (e *Encoder) SetTagMultiline(v string) *Encoder { + e.multiline = v + return e +} + +func (e *Encoder) marshal(v interface{}) ([]byte, error) { + mtype := reflect.TypeOf(v) + + switch mtype.Kind() { + case reflect.Struct, reflect.Map: + case reflect.Ptr: + if mtype.Elem().Kind() != reflect.Struct { + return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML") + } + default: + return []byte{}, errors.New("Only a struct or map can be marshaled to TOML") + } + + sval := reflect.ValueOf(v) + if isCustomMarshaler(mtype) { + return callCustomMarshaler(sval) + } + t, err := e.valueToTree(mtype, sval) + if err != nil { + return []byte{}, err + } + + var buf bytes.Buffer + _, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order) + + return buf.Bytes(), err +} + +// Create next tree with a position based on Encoder.line +func (e *Encoder) nextTree() *Tree { + return newTreeWithPosition(Position{Line: e.line, Col: 1}) +} + +// Convert given marshal struct or map value to toml tree +func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) { + if mtype.Kind() == reflect.Ptr { + return e.valueToTree(mtype.Elem(), mval.Elem()) + } + tval := e.nextTree() + switch mtype.Kind() { + case reflect.Struct: + for i := 0; i < mtype.NumField(); i++ { + mtypef, mvalf := mtype.Field(i), mval.Field(i) + opts := tomlOptions(mtypef, e.annotation) + if opts.include && (!opts.omitempty || !isZero(mvalf)) { + val, err := e.valueToToml(mtypef.Type, mvalf) + if err != nil { + return nil, err + } + + tval.SetWithOptions(opts.name, SetOptions{ + Comment: opts.comment, + Commented: opts.commented, + Multiline: opts.multiline, + }, val) + } + } + case reflect.Map: + keys := mval.MapKeys() + if e.order == OrderPreserve && len(keys) > 0 { + // Sorting []reflect.Value is not straight forward. + // + // OrderPreserve will support deterministic results when string is used + // as the key to maps. + typ := keys[0].Type() + kind := keys[0].Kind() + if kind == reflect.String { + ikeys := make([]string, len(keys)) + for i := range keys { + ikeys[i] = keys[i].Interface().(string) + } + sort.Strings(ikeys) + for i := range ikeys { + keys[i] = reflect.ValueOf(ikeys[i]).Convert(typ) + } + } + } + for _, key := range keys { + mvalf := mval.MapIndex(key) + val, err := e.valueToToml(mtype.Elem(), mvalf) + if err != nil { + return nil, err + } + if e.quoteMapKeys { + keyStr, err := tomlValueStringRepresentation(key.String(), "", e.arraysOneElementPerLine) + if err != nil { + return nil, err + } + tval.SetPath([]string{keyStr}, val) + } else { + tval.Set(key.String(), val) + } + } + } + return tval, nil +} + +// Convert given marshal slice to slice of Toml trees +func (e *Encoder) valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) { + tval := make([]*Tree, mval.Len(), mval.Len()) + for i := 0; i < mval.Len(); i++ { + val, err := e.valueToTree(mtype.Elem(), mval.Index(i)) + if err != nil { + return nil, err + } + tval[i] = val + } + return tval, nil +} + +// Convert given marshal slice to slice of toml values +func (e *Encoder) valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, error) { + tval := make([]interface{}, mval.Len(), mval.Len()) + for i := 0; i < mval.Len(); i++ { + val, err := e.valueToToml(mtype.Elem(), mval.Index(i)) + if err != nil { + return nil, err + } + tval[i] = val + } + return tval, nil +} + +// Convert given marshal value to toml value +func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { + e.line++ + if mtype.Kind() == reflect.Ptr { + return e.valueToToml(mtype.Elem(), mval.Elem()) + } + switch { + case isCustomMarshaler(mtype): + return callCustomMarshaler(mval) + case isTree(mtype): + return e.valueToTree(mtype, mval) + case isTreeSlice(mtype): + return e.valueToTreeSlice(mtype, mval) + case isOtherSlice(mtype): + return e.valueToOtherSlice(mtype, mval) + default: + switch mtype.Kind() { + case reflect.Bool: + return mval.Bool(), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) { + return fmt.Sprint(mval), nil + } + return mval.Int(), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return mval.Uint(), nil + case reflect.Float32, reflect.Float64: + return mval.Float(), nil + case reflect.String: + return mval.String(), nil + case reflect.Struct: + return mval.Interface().(time.Time), nil + default: + return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind()) + } + } +} + +// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v. +// Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for +// sub-structs, and only definite types can be unmarshaled. +func (t *Tree) Unmarshal(v interface{}) error { + d := Decoder{tval: t, tagName: tagFieldName} + return d.unmarshal(v) +} + +// Marshal returns the TOML encoding of Tree. +// See Marshal() documentation for types mapping table. +func (t *Tree) Marshal() ([]byte, error) { + var buf bytes.Buffer + err := NewEncoder(&buf).Encode(t) + return buf.Bytes(), err +} + +// Unmarshal parses the TOML-encoded data and stores the result in the value +// pointed to by v. Behavior is similar to the Go json encoder, except that there +// is no concept of an Unmarshaler interface or UnmarshalTOML function for +// sub-structs, and currently only definite types can be unmarshaled to (i.e. no +// `interface{}`). +// +// The following struct annotations are supported: +// +// toml:"Field" Overrides the field's name to map to. +// default:"foo" Provides a default value. +// +// For default values, only fields of the following types are supported: +// * string +// * bool +// * int +// * int64 +// * float64 +// +// See Marshal() documentation for types mapping table. +func Unmarshal(data []byte, v interface{}) error { + t, err := LoadReader(bytes.NewReader(data)) + if err != nil { + return err + } + return t.Unmarshal(v) +} + +// Decoder reads and decodes TOML values from an input stream. +type Decoder struct { + r io.Reader + tval *Tree + encOpts + tagName string +} + +// NewDecoder returns a new decoder that reads from r. +func NewDecoder(r io.Reader) *Decoder { + return &Decoder{ + r: r, + encOpts: encOptsDefaults, + tagName: tagFieldName, + } +} + +// Decode reads a TOML-encoded value from it's input +// and unmarshals it in the value pointed at by v. +// +// See the documentation for Marshal for details. +func (d *Decoder) Decode(v interface{}) error { + var err error + d.tval, err = LoadReader(d.r) + if err != nil { + return err + } + return d.unmarshal(v) +} + +// SetTagName allows changing default tag "toml" +func (d *Decoder) SetTagName(v string) *Decoder { + d.tagName = v + return d +} + +func (d *Decoder) unmarshal(v interface{}) error { + mtype := reflect.TypeOf(v) + if mtype.Kind() != reflect.Ptr { + return errors.New("only a pointer to struct or map can be unmarshaled from TOML") + } + + elem := mtype.Elem() + + switch elem.Kind() { + case reflect.Struct, reflect.Map: + default: + return errors.New("only a pointer to struct or map can be unmarshaled from TOML") + } + + sval, err := d.valueFromTree(elem, d.tval) + if err != nil { + return err + } + reflect.ValueOf(v).Elem().Set(sval) + return nil +} + +// Convert toml tree to marshal struct or map, using marshal type +func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) { + if mtype.Kind() == reflect.Ptr { + return d.unwrapPointer(mtype, tval) + } + var mval reflect.Value + switch mtype.Kind() { + case reflect.Struct: + mval = reflect.New(mtype).Elem() + for i := 0; i < mtype.NumField(); i++ { + mtypef := mtype.Field(i) + an := annotation{tag: d.tagName} + opts := tomlOptions(mtypef, an) + if opts.include { + baseKey := opts.name + keysToTry := []string{ + baseKey, + strings.ToLower(baseKey), + strings.ToTitle(baseKey), + strings.ToLower(string(baseKey[0])) + baseKey[1:], + } + + found := false + for _, key := range keysToTry { + exists := tval.Has(key) + if !exists { + continue + } + val := tval.Get(key) + mvalf, err := d.valueFromToml(mtypef.Type, val) + if err != nil { + return mval, formatError(err, tval.GetPosition(key)) + } + mval.Field(i).Set(mvalf) + found = true + break + } + + if !found && opts.defaultValue != "" { + mvalf := mval.Field(i) + var val interface{} + var err error + switch mvalf.Kind() { + case reflect.Bool: + val, err = strconv.ParseBool(opts.defaultValue) + if err != nil { + return mval.Field(i), err + } + case reflect.Int: + val, err = strconv.Atoi(opts.defaultValue) + if err != nil { + return mval.Field(i), err + } + case reflect.String: + val = opts.defaultValue + case reflect.Int64: + val, err = strconv.ParseInt(opts.defaultValue, 10, 64) + if err != nil { + return mval.Field(i), err + } + case reflect.Float64: + val, err = strconv.ParseFloat(opts.defaultValue, 64) + if err != nil { + return mval.Field(i), err + } + default: + return mval.Field(i), fmt.Errorf("unsuported field type for default option") + } + mval.Field(i).Set(reflect.ValueOf(val)) + } + } + } + case reflect.Map: + mval = reflect.MakeMap(mtype) + for _, key := range tval.Keys() { + // TODO: path splits key + val := tval.GetPath([]string{key}) + mvalf, err := d.valueFromToml(mtype.Elem(), val) + if err != nil { + return mval, formatError(err, tval.GetPosition(key)) + } + mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf) + } + } + return mval, nil +} + +// Convert toml value to marshal struct/map slice, using marshal type +func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) { + mval := reflect.MakeSlice(mtype, len(tval), len(tval)) + for i := 0; i < len(tval); i++ { + val, err := d.valueFromTree(mtype.Elem(), tval[i]) + if err != nil { + return mval, err + } + mval.Index(i).Set(val) + } + return mval, nil +} + +// Convert toml value to marshal primitive slice, using marshal type +func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) { + mval := reflect.MakeSlice(mtype, len(tval), len(tval)) + for i := 0; i < len(tval); i++ { + val, err := d.valueFromToml(mtype.Elem(), tval[i]) + if err != nil { + return mval, err + } + mval.Index(i).Set(val) + } + return mval, nil +} + +// Convert toml value to marshal value, using marshal type +func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) { + if mtype.Kind() == reflect.Ptr { + return d.unwrapPointer(mtype, tval) + } + + switch t := tval.(type) { + case *Tree: + if isTree(mtype) { + return d.valueFromTree(mtype, t) + } + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval) + case []*Tree: + if isTreeSlice(mtype) { + return d.valueFromTreeSlice(mtype, t) + } + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval) + case []interface{}: + if isOtherSlice(mtype) { + return d.valueFromOtherSlice(mtype, t) + } + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval) + default: + switch mtype.Kind() { + case reflect.Bool, reflect.Struct: + val := reflect.ValueOf(tval) + // if this passes for when mtype is reflect.Struct, tval is a time.Time + if !val.Type().ConvertibleTo(mtype) { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) + } + + return val.Convert(mtype), nil + case reflect.String: + val := reflect.ValueOf(tval) + // stupidly, int64 is convertible to string. So special case this. + if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) + } + + return val.Convert(mtype), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + val := reflect.ValueOf(tval) + if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) && val.Kind() == reflect.String { + d, err := time.ParseDuration(val.String()) + if err != nil { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err) + } + return reflect.ValueOf(d), nil + } + if !val.Type().ConvertibleTo(mtype) { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) + } + if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(mtype).Int()) { + return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) + } + + return val.Convert(mtype), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + val := reflect.ValueOf(tval) + if !val.Type().ConvertibleTo(mtype) { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) + } + + if val.Convert(reflect.TypeOf(int(1))).Int() < 0 { + return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String()) + } + if reflect.Indirect(reflect.New(mtype)).OverflowUint(uint64(val.Convert(mtype).Uint())) { + return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) + } + + return val.Convert(mtype), nil + case reflect.Float32, reflect.Float64: + val := reflect.ValueOf(tval) + if !val.Type().ConvertibleTo(mtype) { + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) + } + if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(mtype).Float()) { + return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) + } + + return val.Convert(mtype), nil + default: + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind()) + } + } +} + +func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error) { + val, err := d.valueFromToml(mtype.Elem(), tval) + if err != nil { + return reflect.ValueOf(nil), err + } + mval := reflect.New(mtype.Elem()) + mval.Elem().Set(val) + return mval, nil +} + +func tomlOptions(vf reflect.StructField, an annotation) tomlOpts { + tag := vf.Tag.Get(an.tag) + parse := strings.Split(tag, ",") + var comment string + if c := vf.Tag.Get(an.comment); c != "" { + comment = c + } + commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented)) + multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline)) + defaultValue := vf.Tag.Get(tagDefault) + result := tomlOpts{ + name: vf.Name, + comment: comment, + commented: commented, + multiline: multiline, + include: true, + omitempty: false, + defaultValue: defaultValue, + } + if parse[0] != "" { + if parse[0] == "-" && len(parse) == 1 { + result.include = false + } else { + result.name = strings.Trim(parse[0], " ") + } + } + if vf.PkgPath != "" { + result.include = false + } + if len(parse) > 1 && strings.Trim(parse[1], " ") == "omitempty" { + result.omitempty = true + } + if vf.Type.Kind() == reflect.Ptr { + result.omitempty = true + } + return result +} + +func isZero(val reflect.Value) bool { + switch val.Type().Kind() { + case reflect.Map: + fallthrough + case reflect.Array: + fallthrough + case reflect.Slice: + return val.Len() == 0 + default: + return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface()) + } +} + +func formatError(err error, pos Position) error { + if err.Error()[0] == '(' { // Error already contains position information + return err + } + return fmt.Errorf("%s: %s", pos, err) +} diff --git a/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_Map_test.toml b/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_Map_test.toml new file mode 100644 index 00000000..a3bd5130 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_Map_test.toml @@ -0,0 +1,17 @@ +title = "TOML Marshal Testing" + +[basic_map] + one = "one" + two = "two" + +[long_map] + a7 = "1" + b3 = "2" + c8 = "3" + d4 = "4" + e6 = "5" + f5 = "6" + g10 = "7" + h1 = "8" + i2 = "9" + j9 = "10" diff --git a/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml b/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml new file mode 100644 index 00000000..9d68b599 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml @@ -0,0 +1,38 @@ +title = "TOML Marshal Testing" + +[basic_lists] + floats = [12.3,45.6,78.9] + bools = [true,false,true] + dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z] + ints = [8001,8001,8002] + uints = [5002,5003] + strings = ["One","Two","Three"] + +[[subdocptrs]] + name = "Second" + +[basic_map] + one = "one" + two = "two" + +[subdoc] + + [subdoc.second] + name = "Second" + + [subdoc.first] + name = "First" + +[basic] + uint = 5001 + bool = true + float = 123.4 + int = 5000 + string = "Bite me" + date = 1979-05-27T07:32:00Z + +[[subdoclist]] + name = "List.First" + +[[subdoclist]] + name = "List.Second" diff --git a/vendor/github.com/pelletier/go-toml/parser.go b/vendor/github.com/pelletier/go-toml/parser.go new file mode 100644 index 00000000..a7498e49 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/parser.go @@ -0,0 +1,442 @@ +// TOML Parser. + +package toml + +import ( + "errors" + "fmt" + "math" + "reflect" + "regexp" + "strconv" + "strings" + "time" +) + +type tomlParser struct { + flowIdx int + flow []token + tree *Tree + currentTable []string + seenTableKeys []string +} + +type tomlParserStateFn func() tomlParserStateFn + +// Formats and panics an error message based on a token +func (p *tomlParser) raiseError(tok *token, msg string, args ...interface{}) { + panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...)) +} + +func (p *tomlParser) run() { + for state := p.parseStart; state != nil; { + state = state() + } +} + +func (p *tomlParser) peek() *token { + if p.flowIdx >= len(p.flow) { + return nil + } + return &p.flow[p.flowIdx] +} + +func (p *tomlParser) assume(typ tokenType) { + tok := p.getToken() + if tok == nil { + p.raiseError(tok, "was expecting token %s, but token stream is empty", tok) + } + if tok.typ != typ { + p.raiseError(tok, "was expecting token %s, but got %s instead", typ, tok) + } +} + +func (p *tomlParser) getToken() *token { + tok := p.peek() + if tok == nil { + return nil + } + p.flowIdx++ + return tok +} + +func (p *tomlParser) parseStart() tomlParserStateFn { + tok := p.peek() + + // end of stream, parsing is finished + if tok == nil { + return nil + } + + switch tok.typ { + case tokenDoubleLeftBracket: + return p.parseGroupArray + case tokenLeftBracket: + return p.parseGroup + case tokenKey: + return p.parseAssign + case tokenEOF: + return nil + case tokenError: + p.raiseError(tok, "parsing error: %s", tok.String()) + default: + p.raiseError(tok, "unexpected token %s", tok.typ) + } + return nil +} + +func (p *tomlParser) parseGroupArray() tomlParserStateFn { + startToken := p.getToken() // discard the [[ + key := p.getToken() + if key.typ != tokenKeyGroupArray { + p.raiseError(key, "unexpected token %s, was expecting a table array key", key) + } + + // get or create table array element at the indicated part in the path + keys, err := parseKey(key.val) + if err != nil { + p.raiseError(key, "invalid table array key: %s", err) + } + p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries + destTree := p.tree.GetPath(keys) + var array []*Tree + if destTree == nil { + array = make([]*Tree, 0) + } else if target, ok := destTree.([]*Tree); ok && target != nil { + array = destTree.([]*Tree) + } else { + p.raiseError(key, "key %s is already assigned and not of type table array", key) + } + p.currentTable = keys + + // add a new tree to the end of the table array + newTree := newTree() + newTree.position = startToken.Position + array = append(array, newTree) + p.tree.SetPath(p.currentTable, array) + + // remove all keys that were children of this table array + prefix := key.val + "." + found := false + for ii := 0; ii < len(p.seenTableKeys); { + tableKey := p.seenTableKeys[ii] + if strings.HasPrefix(tableKey, prefix) { + p.seenTableKeys = append(p.seenTableKeys[:ii], p.seenTableKeys[ii+1:]...) + } else { + found = (tableKey == key.val) + ii++ + } + } + + // keep this key name from use by other kinds of assignments + if !found { + p.seenTableKeys = append(p.seenTableKeys, key.val) + } + + // move to next parser state + p.assume(tokenDoubleRightBracket) + return p.parseStart +} + +func (p *tomlParser) parseGroup() tomlParserStateFn { + startToken := p.getToken() // discard the [ + key := p.getToken() + if key.typ != tokenKeyGroup { + p.raiseError(key, "unexpected token %s, was expecting a table key", key) + } + for _, item := range p.seenTableKeys { + if item == key.val { + p.raiseError(key, "duplicated tables") + } + } + + p.seenTableKeys = append(p.seenTableKeys, key.val) + keys, err := parseKey(key.val) + if err != nil { + p.raiseError(key, "invalid table array key: %s", err) + } + if err := p.tree.createSubTree(keys, startToken.Position); err != nil { + p.raiseError(key, "%s", err) + } + p.assume(tokenRightBracket) + p.currentTable = keys + return p.parseStart +} + +func (p *tomlParser) parseAssign() tomlParserStateFn { + key := p.getToken() + p.assume(tokenEqual) + + parsedKey, err := parseKey(key.val) + if err != nil { + p.raiseError(key, "invalid key: %s", err.Error()) + } + + value := p.parseRvalue() + var tableKey []string + if len(p.currentTable) > 0 { + tableKey = p.currentTable + } else { + tableKey = []string{} + } + + prefixKey := parsedKey[0 : len(parsedKey)-1] + tableKey = append(tableKey, prefixKey...) + + // find the table to assign, looking out for arrays of tables + var targetNode *Tree + switch node := p.tree.GetPath(tableKey).(type) { + case []*Tree: + targetNode = node[len(node)-1] + case *Tree: + targetNode = node + case nil: + // create intermediate + if err := p.tree.createSubTree(tableKey, key.Position); err != nil { + p.raiseError(key, "could not create intermediate group: %s", err) + } + targetNode = p.tree.GetPath(tableKey).(*Tree) + default: + p.raiseError(key, "Unknown table type for path: %s", + strings.Join(tableKey, ".")) + } + + // assign value to the found table + keyVal := parsedKey[len(parsedKey)-1] + localKey := []string{keyVal} + finalKey := append(tableKey, keyVal) + if targetNode.GetPath(localKey) != nil { + p.raiseError(key, "The following key was defined twice: %s", + strings.Join(finalKey, ".")) + } + var toInsert interface{} + + switch value.(type) { + case *Tree, []*Tree: + toInsert = value + default: + toInsert = &tomlValue{value: value, position: key.Position} + } + targetNode.values[keyVal] = toInsert + return p.parseStart +} + +var numberUnderscoreInvalidRegexp *regexp.Regexp +var hexNumberUnderscoreInvalidRegexp *regexp.Regexp + +func numberContainsInvalidUnderscore(value string) error { + if numberUnderscoreInvalidRegexp.MatchString(value) { + return errors.New("invalid use of _ in number") + } + return nil +} + +func hexNumberContainsInvalidUnderscore(value string) error { + if hexNumberUnderscoreInvalidRegexp.MatchString(value) { + return errors.New("invalid use of _ in hex number") + } + return nil +} + +func cleanupNumberToken(value string) string { + cleanedVal := strings.Replace(value, "_", "", -1) + return cleanedVal +} + +func (p *tomlParser) parseRvalue() interface{} { + tok := p.getToken() + if tok == nil || tok.typ == tokenEOF { + p.raiseError(tok, "expecting a value") + } + + switch tok.typ { + case tokenString: + return tok.val + case tokenTrue: + return true + case tokenFalse: + return false + case tokenInf: + if tok.val[0] == '-' { + return math.Inf(-1) + } + return math.Inf(1) + case tokenNan: + return math.NaN() + case tokenInteger: + cleanedVal := cleanupNumberToken(tok.val) + var err error + var val int64 + if len(cleanedVal) >= 3 && cleanedVal[0] == '0' { + switch cleanedVal[1] { + case 'x': + err = hexNumberContainsInvalidUnderscore(tok.val) + if err != nil { + p.raiseError(tok, "%s", err) + } + val, err = strconv.ParseInt(cleanedVal[2:], 16, 64) + case 'o': + err = numberContainsInvalidUnderscore(tok.val) + if err != nil { + p.raiseError(tok, "%s", err) + } + val, err = strconv.ParseInt(cleanedVal[2:], 8, 64) + case 'b': + err = numberContainsInvalidUnderscore(tok.val) + if err != nil { + p.raiseError(tok, "%s", err) + } + val, err = strconv.ParseInt(cleanedVal[2:], 2, 64) + default: + panic("invalid base") // the lexer should catch this first + } + } else { + err = numberContainsInvalidUnderscore(tok.val) + if err != nil { + p.raiseError(tok, "%s", err) + } + val, err = strconv.ParseInt(cleanedVal, 10, 64) + } + if err != nil { + p.raiseError(tok, "%s", err) + } + return val + case tokenFloat: + err := numberContainsInvalidUnderscore(tok.val) + if err != nil { + p.raiseError(tok, "%s", err) + } + cleanedVal := cleanupNumberToken(tok.val) + val, err := strconv.ParseFloat(cleanedVal, 64) + if err != nil { + p.raiseError(tok, "%s", err) + } + return val + case tokenDate: + val, err := time.ParseInLocation(time.RFC3339Nano, tok.val, time.UTC) + if err != nil { + p.raiseError(tok, "%s", err) + } + return val + case tokenLeftBracket: + return p.parseArray() + case tokenLeftCurlyBrace: + return p.parseInlineTable() + case tokenEqual: + p.raiseError(tok, "cannot have multiple equals for the same key") + case tokenError: + p.raiseError(tok, "%s", tok) + } + + p.raiseError(tok, "never reached") + + return nil +} + +func tokenIsComma(t *token) bool { + return t != nil && t.typ == tokenComma +} + +func (p *tomlParser) parseInlineTable() *Tree { + tree := newTree() + var previous *token +Loop: + for { + follow := p.peek() + if follow == nil || follow.typ == tokenEOF { + p.raiseError(follow, "unterminated inline table") + } + switch follow.typ { + case tokenRightCurlyBrace: + p.getToken() + break Loop + case tokenKey, tokenInteger, tokenString: + if !tokenIsComma(previous) && previous != nil { + p.raiseError(follow, "comma expected between fields in inline table") + } + key := p.getToken() + p.assume(tokenEqual) + value := p.parseRvalue() + tree.Set(key.val, value) + case tokenComma: + if previous == nil { + p.raiseError(follow, "inline table cannot start with a comma") + } + if tokenIsComma(previous) { + p.raiseError(follow, "need field between two commas in inline table") + } + p.getToken() + default: + p.raiseError(follow, "unexpected token type in inline table: %s", follow.String()) + } + previous = follow + } + if tokenIsComma(previous) { + p.raiseError(previous, "trailing comma at the end of inline table") + } + return tree +} + +func (p *tomlParser) parseArray() interface{} { + var array []interface{} + arrayType := reflect.TypeOf(nil) + for { + follow := p.peek() + if follow == nil || follow.typ == tokenEOF { + p.raiseError(follow, "unterminated array") + } + if follow.typ == tokenRightBracket { + p.getToken() + break + } + val := p.parseRvalue() + if arrayType == nil { + arrayType = reflect.TypeOf(val) + } + if reflect.TypeOf(val) != arrayType { + p.raiseError(follow, "mixed types in array") + } + array = append(array, val) + follow = p.peek() + if follow == nil || follow.typ == tokenEOF { + p.raiseError(follow, "unterminated array") + } + if follow.typ != tokenRightBracket && follow.typ != tokenComma { + p.raiseError(follow, "missing comma") + } + if follow.typ == tokenComma { + p.getToken() + } + } + // An array of Trees is actually an array of inline + // tables, which is a shorthand for a table array. If the + // array was not converted from []interface{} to []*Tree, + // the two notations would not be equivalent. + if arrayType == reflect.TypeOf(newTree()) { + tomlArray := make([]*Tree, len(array)) + for i, v := range array { + tomlArray[i] = v.(*Tree) + } + return tomlArray + } + return array +} + +func parseToml(flow []token) *Tree { + result := newTree() + result.position = Position{1, 1} + parser := &tomlParser{ + flowIdx: 0, + flow: flow, + tree: result, + currentTable: make([]string, 0), + seenTableKeys: make([]string, 0), + } + parser.run() + return result +} + +func init() { + numberUnderscoreInvalidRegexp = regexp.MustCompile(`([^\d]_|_[^\d])|_$|^_`) + hexNumberUnderscoreInvalidRegexp = regexp.MustCompile(`(^0x_)|([^\da-f]_|_[^\da-f])|_$|^_`) +} diff --git a/vendor/github.com/pelletier/go-toml/toml.go b/vendor/github.com/pelletier/go-toml/toml.go new file mode 100644 index 00000000..358a9be5 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/toml.go @@ -0,0 +1,393 @@ +package toml + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "runtime" + "strings" +) + +type tomlValue struct { + value interface{} // string, int64, uint64, float64, bool, time.Time, [] of any of this list + comment string + commented bool + multiline bool + position Position +} + +// Tree is the result of the parsing of a TOML file. +type Tree struct { + values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree + comment string + commented bool + position Position +} + +func newTree() *Tree { + return newTreeWithPosition(Position{}) +} + +func newTreeWithPosition(pos Position) *Tree { + return &Tree{ + values: make(map[string]interface{}), + position: pos, + } +} + +// TreeFromMap initializes a new Tree object using the given map. +func TreeFromMap(m map[string]interface{}) (*Tree, error) { + result, err := toTree(m) + if err != nil { + return nil, err + } + return result.(*Tree), nil +} + +// Position returns the position of the tree. +func (t *Tree) Position() Position { + return t.position +} + +// Has returns a boolean indicating if the given key exists. +func (t *Tree) Has(key string) bool { + if key == "" { + return false + } + return t.HasPath(strings.Split(key, ".")) +} + +// HasPath returns true if the given path of keys exists, false otherwise. +func (t *Tree) HasPath(keys []string) bool { + return t.GetPath(keys) != nil +} + +// Keys returns the keys of the toplevel tree (does not recurse). +func (t *Tree) Keys() []string { + keys := make([]string, len(t.values)) + i := 0 + for k := range t.values { + keys[i] = k + i++ + } + return keys +} + +// Get the value at key in the Tree. +// Key is a dot-separated path (e.g. a.b.c) without single/double quoted strings. +// If you need to retrieve non-bare keys, use GetPath. +// Returns nil if the path does not exist in the tree. +// If keys is of length zero, the current tree is returned. +func (t *Tree) Get(key string) interface{} { + if key == "" { + return t + } + return t.GetPath(strings.Split(key, ".")) +} + +// GetPath returns the element in the tree indicated by 'keys'. +// If keys is of length zero, the current tree is returned. +func (t *Tree) GetPath(keys []string) interface{} { + if len(keys) == 0 { + return t + } + subtree := t + for _, intermediateKey := range keys[:len(keys)-1] { + value, exists := subtree.values[intermediateKey] + if !exists { + return nil + } + switch node := value.(type) { + case *Tree: + subtree = node + case []*Tree: + // go to most recent element + if len(node) == 0 { + return nil + } + subtree = node[len(node)-1] + default: + return nil // cannot navigate through other node types + } + } + // branch based on final node type + switch node := subtree.values[keys[len(keys)-1]].(type) { + case *tomlValue: + return node.value + default: + return node + } +} + +// GetPosition returns the position of the given key. +func (t *Tree) GetPosition(key string) Position { + if key == "" { + return t.position + } + return t.GetPositionPath(strings.Split(key, ".")) +} + +// GetPositionPath returns the element in the tree indicated by 'keys'. +// If keys is of length zero, the current tree is returned. +func (t *Tree) GetPositionPath(keys []string) Position { + if len(keys) == 0 { + return t.position + } + subtree := t + for _, intermediateKey := range keys[:len(keys)-1] { + value, exists := subtree.values[intermediateKey] + if !exists { + return Position{0, 0} + } + switch node := value.(type) { + case *Tree: + subtree = node + case []*Tree: + // go to most recent element + if len(node) == 0 { + return Position{0, 0} + } + subtree = node[len(node)-1] + default: + return Position{0, 0} + } + } + // branch based on final node type + switch node := subtree.values[keys[len(keys)-1]].(type) { + case *tomlValue: + return node.position + case *Tree: + return node.position + case []*Tree: + // go to most recent element + if len(node) == 0 { + return Position{0, 0} + } + return node[len(node)-1].position + default: + return Position{0, 0} + } +} + +// GetDefault works like Get but with a default value +func (t *Tree) GetDefault(key string, def interface{}) interface{} { + val := t.Get(key) + if val == nil { + return def + } + return val +} + +// SetOptions arguments are supplied to the SetWithOptions and SetPathWithOptions functions to modify marshalling behaviour. +// The default values within the struct are valid default options. +type SetOptions struct { + Comment string + Commented bool + Multiline bool +} + +// SetWithOptions is the same as Set, but allows you to provide formatting +// instructions to the key, that will be used by Marshal(). +func (t *Tree) SetWithOptions(key string, opts SetOptions, value interface{}) { + t.SetPathWithOptions(strings.Split(key, "."), opts, value) +} + +// SetPathWithOptions is the same as SetPath, but allows you to provide +// formatting instructions to the key, that will be reused by Marshal(). +func (t *Tree) SetPathWithOptions(keys []string, opts SetOptions, value interface{}) { + subtree := t + for i, intermediateKey := range keys[:len(keys)-1] { + nextTree, exists := subtree.values[intermediateKey] + if !exists { + nextTree = newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}) + subtree.values[intermediateKey] = nextTree // add new element here + } + switch node := nextTree.(type) { + case *Tree: + subtree = node + case []*Tree: + // go to most recent element + if len(node) == 0 { + // create element if it does not exist + subtree.values[intermediateKey] = append(node, newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col})) + } + subtree = node[len(node)-1] + } + } + + var toInsert interface{} + + switch v := value.(type) { + case *Tree: + v.comment = opts.Comment + toInsert = value + case []*Tree: + toInsert = value + case *tomlValue: + v.comment = opts.Comment + toInsert = v + default: + toInsert = &tomlValue{value: value, + comment: opts.Comment, + commented: opts.Commented, + multiline: opts.Multiline, + position: Position{Line: subtree.position.Line + len(subtree.values) + 1, Col: subtree.position.Col}} + } + + subtree.values[keys[len(keys)-1]] = toInsert +} + +// Set an element in the tree. +// Key is a dot-separated path (e.g. a.b.c). +// Creates all necessary intermediate trees, if needed. +func (t *Tree) Set(key string, value interface{}) { + t.SetWithComment(key, "", false, value) +} + +// SetWithComment is the same as Set, but allows you to provide comment +// information to the key, that will be reused by Marshal(). +func (t *Tree) SetWithComment(key string, comment string, commented bool, value interface{}) { + t.SetPathWithComment(strings.Split(key, "."), comment, commented, value) +} + +// SetPath sets an element in the tree. +// Keys is an array of path elements (e.g. {"a","b","c"}). +// Creates all necessary intermediate trees, if needed. +func (t *Tree) SetPath(keys []string, value interface{}) { + t.SetPathWithComment(keys, "", false, value) +} + +// SetPathWithComment is the same as SetPath, but allows you to provide comment +// information to the key, that will be reused by Marshal(). +func (t *Tree) SetPathWithComment(keys []string, comment string, commented bool, value interface{}) { + t.SetPathWithOptions(keys, SetOptions{Comment: comment, Commented: commented}, value) +} + +// Delete removes a key from the tree. +// Key is a dot-separated path (e.g. a.b.c). +func (t *Tree) Delete(key string) error { + keys, err := parseKey(key) + if err != nil { + return err + } + return t.DeletePath(keys) +} + +// DeletePath removes a key from the tree. +// Keys is an array of path elements (e.g. {"a","b","c"}). +func (t *Tree) DeletePath(keys []string) error { + keyLen := len(keys) + if keyLen == 1 { + delete(t.values, keys[0]) + return nil + } + tree := t.GetPath(keys[:keyLen-1]) + item := keys[keyLen-1] + switch node := tree.(type) { + case *Tree: + delete(node.values, item) + return nil + } + return errors.New("no such key to delete") +} + +// createSubTree takes a tree and a key and create the necessary intermediate +// subtrees to create a subtree at that point. In-place. +// +// e.g. passing a.b.c will create (assuming tree is empty) tree[a], tree[a][b] +// and tree[a][b][c] +// +// Returns nil on success, error object on failure +func (t *Tree) createSubTree(keys []string, pos Position) error { + subtree := t + for i, intermediateKey := range keys { + nextTree, exists := subtree.values[intermediateKey] + if !exists { + tree := newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}) + tree.position = pos + subtree.values[intermediateKey] = tree + nextTree = tree + } + + switch node := nextTree.(type) { + case []*Tree: + subtree = node[len(node)-1] + case *Tree: + subtree = node + default: + return fmt.Errorf("unknown type for path %s (%s): %T (%#v)", + strings.Join(keys, "."), intermediateKey, nextTree, nextTree) + } + } + return nil +} + +// LoadBytes creates a Tree from a []byte. +func LoadBytes(b []byte) (tree *Tree, err error) { + defer func() { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } + err = errors.New(r.(string)) + } + }() + + if len(b) >= 4 && (hasUTF32BigEndianBOM4(b) || hasUTF32LittleEndianBOM4(b)) { + b = b[4:] + } else if len(b) >= 3 && hasUTF8BOM3(b) { + b = b[3:] + } else if len(b) >= 2 && (hasUTF16BigEndianBOM2(b) || hasUTF16LittleEndianBOM2(b)) { + b = b[2:] + } + + tree = parseToml(lexToml(b)) + return +} + +func hasUTF16BigEndianBOM2(b []byte) bool { + return b[0] == 0xFE && b[1] == 0xFF +} + +func hasUTF16LittleEndianBOM2(b []byte) bool { + return b[0] == 0xFF && b[1] == 0xFE +} + +func hasUTF8BOM3(b []byte) bool { + return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF +} + +func hasUTF32BigEndianBOM4(b []byte) bool { + return b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF +} + +func hasUTF32LittleEndianBOM4(b []byte) bool { + return b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00 +} + +// LoadReader creates a Tree from any io.Reader. +func LoadReader(reader io.Reader) (tree *Tree, err error) { + inputBytes, err := ioutil.ReadAll(reader) + if err != nil { + return + } + tree, err = LoadBytes(inputBytes) + return +} + +// Load creates a Tree from a string. +func Load(content string) (tree *Tree, err error) { + return LoadBytes([]byte(content)) +} + +// LoadFile creates a Tree from a file. +func LoadFile(path string) (tree *Tree, err error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + return LoadReader(file) +} diff --git a/vendor/github.com/pelletier/go-toml/tomltree_write.go b/vendor/github.com/pelletier/go-toml/tomltree_write.go new file mode 100644 index 00000000..198d5ac1 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/tomltree_write.go @@ -0,0 +1,434 @@ +package toml + +import ( + "bytes" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" +) + +type valueComplexity int + +const ( + valueSimple valueComplexity = iota + 1 + valueComplex +) + +type sortNode struct { + key string + complexity valueComplexity +} + +// Encodes a string to a TOML-compliant multi-line string value +// This function is a clone of the existing encodeTomlString function, except that whitespace characters +// are preserved. Quotation marks and backslashes are also not escaped. +func encodeMultilineTomlString(value string) string { + var b bytes.Buffer + + for _, rr := range value { + switch rr { + case '\b': + b.WriteString(`\b`) + case '\t': + b.WriteString("\t") + case '\n': + b.WriteString("\n") + case '\f': + b.WriteString(`\f`) + case '\r': + b.WriteString("\r") + case '"': + b.WriteString(`"`) + case '\\': + b.WriteString(`\`) + default: + intRr := uint16(rr) + if intRr < 0x001F { + b.WriteString(fmt.Sprintf("\\u%0.4X", intRr)) + } else { + b.WriteRune(rr) + } + } + } + return b.String() +} + +// Encodes a string to a TOML-compliant string value +func encodeTomlString(value string) string { + var b bytes.Buffer + + for _, rr := range value { + switch rr { + case '\b': + b.WriteString(`\b`) + case '\t': + b.WriteString(`\t`) + case '\n': + b.WriteString(`\n`) + case '\f': + b.WriteString(`\f`) + case '\r': + b.WriteString(`\r`) + case '"': + b.WriteString(`\"`) + case '\\': + b.WriteString(`\\`) + default: + intRr := uint16(rr) + if intRr < 0x001F { + b.WriteString(fmt.Sprintf("\\u%0.4X", intRr)) + } else { + b.WriteRune(rr) + } + } + } + return b.String() +} + +func tomlValueStringRepresentation(v interface{}, indent string, arraysOneElementPerLine bool) (string, error) { + // this interface check is added to dereference the change made in the writeTo function. + // That change was made to allow this function to see formatting options. + tv, ok := v.(*tomlValue) + if ok { + v = tv.value + } else { + tv = &tomlValue{} + } + + switch value := v.(type) { + case uint64: + return strconv.FormatUint(value, 10), nil + case int64: + return strconv.FormatInt(value, 10), nil + case float64: + // Ensure a round float does contain a decimal point. Otherwise feeding + // the output back to the parser would convert to an integer. + if math.Trunc(value) == value { + return strings.ToLower(strconv.FormatFloat(value, 'f', 1, 32)), nil + } + return strings.ToLower(strconv.FormatFloat(value, 'f', -1, 32)), nil + case string: + if tv.multiline { + return "\"\"\"\n" + encodeMultilineTomlString(value) + "\"\"\"", nil + } + return "\"" + encodeTomlString(value) + "\"", nil + case []byte: + b, _ := v.([]byte) + return tomlValueStringRepresentation(string(b), indent, arraysOneElementPerLine) + case bool: + if value { + return "true", nil + } + return "false", nil + case time.Time: + return value.Format(time.RFC3339), nil + case nil: + return "", nil + } + + rv := reflect.ValueOf(v) + + if rv.Kind() == reflect.Slice { + var values []string + for i := 0; i < rv.Len(); i++ { + item := rv.Index(i).Interface() + itemRepr, err := tomlValueStringRepresentation(item, indent, arraysOneElementPerLine) + if err != nil { + return "", err + } + values = append(values, itemRepr) + } + if arraysOneElementPerLine && len(values) > 1 { + stringBuffer := bytes.Buffer{} + valueIndent := indent + ` ` // TODO: move that to a shared encoder state + + stringBuffer.WriteString("[\n") + + for _, value := range values { + stringBuffer.WriteString(valueIndent) + stringBuffer.WriteString(value) + stringBuffer.WriteString(`,`) + stringBuffer.WriteString("\n") + } + + stringBuffer.WriteString(indent + "]") + + return stringBuffer.String(), nil + } + return "[" + strings.Join(values, ",") + "]", nil + } + return "", fmt.Errorf("unsupported value type %T: %v", v, v) +} + +func getTreeArrayLine(trees []*Tree) (line int) { + // get lowest line number that is not 0 + for _, tv := range trees { + if tv.position.Line < line || line == 0 { + line = tv.position.Line + } + } + return +} + +func sortByLines(t *Tree) (vals []sortNode) { + var ( + line int + lines []int + tv *Tree + tom *tomlValue + node sortNode + ) + vals = make([]sortNode, 0) + m := make(map[int]sortNode) + + for k := range t.values { + v := t.values[k] + switch v.(type) { + case *Tree: + tv = v.(*Tree) + line = tv.position.Line + node = sortNode{key: k, complexity: valueComplex} + case []*Tree: + line = getTreeArrayLine(v.([]*Tree)) + node = sortNode{key: k, complexity: valueComplex} + default: + tom = v.(*tomlValue) + line = tom.position.Line + node = sortNode{key: k, complexity: valueSimple} + } + lines = append(lines, line) + vals = append(vals, node) + m[line] = node + } + sort.Ints(lines) + + for i, line := range lines { + vals[i] = m[line] + } + + return vals +} + +func sortAlphabetical(t *Tree) (vals []sortNode) { + var ( + node sortNode + simpVals []string + compVals []string + ) + vals = make([]sortNode, 0) + m := make(map[string]sortNode) + + for k := range t.values { + v := t.values[k] + switch v.(type) { + case *Tree, []*Tree: + node = sortNode{key: k, complexity: valueComplex} + compVals = append(compVals, node.key) + default: + node = sortNode{key: k, complexity: valueSimple} + simpVals = append(simpVals, node.key) + } + vals = append(vals, node) + m[node.key] = node + } + + // Simples first to match previous implementation + sort.Strings(simpVals) + i := 0 + for _, key := range simpVals { + vals[i] = m[key] + i++ + } + + sort.Strings(compVals) + for _, key := range compVals { + vals[i] = m[key] + i++ + } + + return vals +} + +func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) { + return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical) +} + +func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder) (int64, error) { + var orderedVals []sortNode + + switch ord { + case OrderPreserve: + orderedVals = sortByLines(t) + default: + orderedVals = sortAlphabetical(t) + } + + for _, node := range orderedVals { + switch node.complexity { + case valueComplex: + k := node.key + v := t.values[k] + + combinedKey := k + if keyspace != "" { + combinedKey = keyspace + "." + combinedKey + } + var commented string + if t.commented { + commented = "# " + } + + switch node := v.(type) { + // node has to be of those two types given how keys are sorted above + case *Tree: + tv, ok := t.values[k].(*Tree) + if !ok { + return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k]) + } + if tv.comment != "" { + comment := strings.Replace(tv.comment, "\n", "\n"+indent+"#", -1) + start := "# " + if strings.HasPrefix(comment, "#") { + start = "" + } + writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment) + bytesCount += int64(writtenBytesCountComment) + if errc != nil { + return bytesCount, errc + } + } + writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[", combinedKey, "]\n") + bytesCount += int64(writtenBytesCount) + if err != nil { + return bytesCount, err + } + bytesCount, err = node.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord) + if err != nil { + return bytesCount, err + } + case []*Tree: + for _, subTree := range node { + writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[[", combinedKey, "]]\n") + bytesCount += int64(writtenBytesCount) + if err != nil { + return bytesCount, err + } + + bytesCount, err = subTree.writeToOrdered(w, indent+" ", combinedKey, bytesCount, arraysOneElementPerLine, ord) + if err != nil { + return bytesCount, err + } + } + } + default: // Simple + k := node.key + v, ok := t.values[k].(*tomlValue) + if !ok { + return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k]) + } + + repr, err := tomlValueStringRepresentation(v, indent, arraysOneElementPerLine) + if err != nil { + return bytesCount, err + } + + if v.comment != "" { + comment := strings.Replace(v.comment, "\n", "\n"+indent+"#", -1) + start := "# " + if strings.HasPrefix(comment, "#") { + start = "" + } + writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment, "\n") + bytesCount += int64(writtenBytesCountComment) + if errc != nil { + return bytesCount, errc + } + } + + var commented string + if v.commented { + commented = "# " + } + writtenBytesCount, err := writeStrings(w, indent, commented, k, " = ", repr, "\n") + bytesCount += int64(writtenBytesCount) + if err != nil { + return bytesCount, err + } + } + } + + return bytesCount, nil +} + +func writeStrings(w io.Writer, s ...string) (int, error) { + var n int + for i := range s { + b, err := io.WriteString(w, s[i]) + n += b + if err != nil { + return n, err + } + } + return n, nil +} + +// WriteTo encode the Tree as Toml and writes it to the writer w. +// Returns the number of bytes written in case of success, or an error if anything happened. +func (t *Tree) WriteTo(w io.Writer) (int64, error) { + return t.writeTo(w, "", "", 0, false) +} + +// ToTomlString generates a human-readable representation of the current tree. +// Output spans multiple lines, and is suitable for ingest by a TOML parser. +// If the conversion cannot be performed, ToString returns a non-nil error. +func (t *Tree) ToTomlString() (string, error) { + var buf bytes.Buffer + _, err := t.WriteTo(&buf) + if err != nil { + return "", err + } + return buf.String(), nil +} + +// String generates a human-readable representation of the current tree. +// Alias of ToString. Present to implement the fmt.Stringer interface. +func (t *Tree) String() string { + result, _ := t.ToTomlString() + return result +} + +// ToMap recursively generates a representation of the tree using Go built-in structures. +// The following types are used: +// +// * bool +// * float64 +// * int64 +// * string +// * uint64 +// * time.Time +// * map[string]interface{} (where interface{} is any of this list) +// * []interface{} (where interface{} is any of this list) +func (t *Tree) ToMap() map[string]interface{} { + result := map[string]interface{}{} + + for k, v := range t.values { + switch node := v.(type) { + case []*Tree: + var array []interface{} + for _, item := range node { + array = append(array, item.ToMap()) + } + result[k] = array + case *Tree: + result[k] = node.ToMap() + case *tomlValue: + result[k] = node.value + } + } + return result +} diff --git a/vendor/github.com/polydawn/refmt/.gitignore b/vendor/github.com/polydawn/refmt/.gitignore new file mode 100644 index 00000000..9010fa35 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/.gitignore @@ -0,0 +1,2 @@ +.gopath/pkg +.gopath/tmp diff --git a/vendor/github.com/polydawn/refmt/.gitmodules b/vendor/github.com/polydawn/refmt/.gitmodules new file mode 100644 index 00000000..1106688a --- /dev/null +++ b/vendor/github.com/polydawn/refmt/.gitmodules @@ -0,0 +1,18 @@ +[submodule ".gopath/src/github.com/smartystreets/goconvey"] + path = .gopath/src/github.com/smartystreets/goconvey + url = https://github.com/smartystreets/goconvey +[submodule ".gopath/src/github.com/smartystreets/assertions"] + path = .gopath/src/github.com/smartystreets/assertions + url = https://github.com/smartystreets/assertions +[submodule ".gopath/src/github.com/jtolds/gls"] + path = .gopath/src/github.com/jtolds/gls + url = https://github.com/jtolds/gls +[submodule ".gopath/src/github.com/urfave/cli"] + path = .gopath/src/github.com/urfave/cli + url = https://github.com/urfave/cli/ +[submodule ".gopath/src/github.com/go-yaml/yaml"] + path = .gopath/src/github.com/go-yaml/yaml + url = https://github.com/go-yaml/yaml/ +[submodule ".gopath/src/github.com/warpfork/go-wish"] + path = .gopath/src/github.com/warpfork/go-wish + url = https://github.com/warpfork/go-wish diff --git a/vendor/github.com/polydawn/refmt/.gopath/self b/vendor/github.com/polydawn/refmt/.gopath/self new file mode 120000 index 00000000..1ecb86ef --- /dev/null +++ b/vendor/github.com/polydawn/refmt/.gopath/self @@ -0,0 +1 @@ +src/github.com/polydawn/refmt \ No newline at end of file diff --git a/vendor/github.com/polydawn/refmt/.gopath/src/github.com/polydawn/refmt b/vendor/github.com/polydawn/refmt/.gopath/src/github.com/polydawn/refmt new file mode 120000 index 00000000..11a54ed3 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/.gopath/src/github.com/polydawn/refmt @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/vendor/github.com/polydawn/refmt/.travis.yml b/vendor/github.com/polydawn/refmt/.travis.yml new file mode 100644 index 00000000..2dcf3f2f --- /dev/null +++ b/vendor/github.com/polydawn/refmt/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - "1.10" + - 1.9 + +# I know I like my dependencies specified by custom meta tags in HTML! +# Oh wait, no. No I don't. +install: true + +script: + - ./goad + +notifications: + email: false diff --git a/vendor/github.com/polydawn/refmt/LICENSE b/vendor/github.com/polydawn/refmt/LICENSE new file mode 100644 index 00000000..9f30daa0 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Eric Myhre + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/polydawn/refmt/README.md b/vendor/github.com/polydawn/refmt/README.md new file mode 100644 index 00000000..6441722f --- /dev/null +++ b/vendor/github.com/polydawn/refmt/README.md @@ -0,0 +1,78 @@ +refmt [![GoDoc](https://godoc.org/github.com/polydawn/refmt?status.svg)](https://godoc.org/github.com/polydawn/refmt) [![Build status](https://img.shields.io/travis/polydawn/refmt/master.svg?style=flat-square)](https://travis-ci.org/polydawn/refmt) +===== + + +`refmt` is a serialization and object-mapping library. + + + +Why? +---- + +Mostly because I have some types which I need to encode in two different ways, and that needs to not suck, +and that totally sucks with most serialization libraries I've used. +Also, I need to serialize things in different formats, e.g. sometimes JSON and other times CBOR, +and that needs to work without me wrestling two different object-serial libraries and configs. + +More broadly, I want a single library that can handle my serialization -- with the possibility of different setups on the same types -- and if it can do general object traversals, e.g. a deepcopy, that also seems like... just something that should be natural. + +So it seems like there should be some way to define token streams... and a way to define converting objects to and from token streams... and a way to covert token streams to and from serialized bytes... and all of these should be pretty separate! + +Thusly was this library thrust into the world: +`refmt/tok` to define the token stream, +and `refmt/obj` to define how to map objects to tokens and back, +and `refmt/json` and `refmt/cbor` as ways to exchange tokens with serialized formats. + +All of these formats can mix-n-match freely, because they communicate values as the standard token stream. Voilà: + +- pair `obj.Marshaller` with `json.Encoder` to get a json serializer. +- pair `cbor.Decoder` with `obj.Unmarshaller` to get a cbor deserializer. +- pair `cbor.Decoder` with `json.Encoder` to get a cbor->json streaming transcoder! +- pair `obj.Marshaller` with `obj.Unmarshaller` to get a deep-copy system! (Try it with two different types: marshalling a struct and unmarshalling into a freeform map!) + +Along the way, we've added a powerful system for defining **how** exactly the `refmt/obj` tools should treat your structures: +the Atlas system (defined in the `refmt/obj/atlas` package). +Atlases can be used to customize how struct fields are handled, how map keys are sorted, and even +define conversions between completely different *kinds* of objects: serialize arrays as strings, or turn stringy enums into bitfields, no problem. +By default, `refmt` will generate atlases automatically for your structs and types, just like the standard library json marshallers do; +if you want more control, atlases give you the power. + +An Atlas can be given to each `obj.Marshaller` and `obj.Unmarshaller` when it is constructed. +This allows great variation in how you wish to handle types -- more than one mapping can be defined for the same concrete type! +(This is a killer feature if you need to support multiple versions of an API, for example: +you can define 'v1' and 'v2' types, each with their own structs to unmarshal user requests into; +then in the backend implement another Marshal/Unmarshal with different atlases which translates the 'v1' requests to 'v2' types, +and you only have to implement business logic against the latest types!) + +Atlases are significantly more convenient to use than defining custom `JSONMarshal()` methods. +Atlases attach to the type they concern. +This means you can use atlases to define custom serialization even for types in packages you can't modify! +Atlases also behave better in complex situations: for example, +if you have a `TypeFoo` struct and you wish to serialize it as a string, +*you don't have to write a custom marshaller for every type that **contains** a `TypeFoo` field*. +Leaking details of custom serialization into the types that contain the interesting objects is +a common pitfall when getting into advanced usage of other marshalling libraries; `refmt` has no such issue. + +## tl;dr: + +- you can swap out atlases for custom serialization on any type; +- and that works for serialization modes even deep in other structures; +- and even on types you don't own!! +- at the same time, you can swap out a cbor encoder for a json encoder, or anything else you want; +- and the mapper part *doesn't care* -- no complex interactions between the layers. + +Come to `refmt`. It's nicer here. + + +Where do I start? +----------------- + +**If you're already using `json.Marshal`:** switch to `json.Marshal` (yes, I'm not kidding; just switch your imports!). + +**If you're already using `json.NewEncoder().Encode()`:** switch to `json.NewMarshaller().Marshal()`. + +**If you want to get more serial-flexible:** try using `refmt.Marshal(json.EncodeOptions{}, obj)`... then switch to `cbor.EncodeOptions{}` and see what happens! + +**If you want to use Atlas to get fancy:** go take a peek at the `example*.go` files in this repo! :) + +Happy hacking! diff --git a/vendor/github.com/polydawn/refmt/allochound b/vendor/github.com/polydawn/refmt/allochound new file mode 100755 index 00000000..304b6bd2 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/allochound @@ -0,0 +1,53 @@ +#!/bin/bash +set -euo pipefail + +### Normalize path -- all work should be relative to this script's location. +## Set up gopath -- also relative to this dir, so we work in isolation. +cd "$( dirname "${BASH_SOURCE[0]}" )" +export GOPATH="$PWD/.gopath/" + +funcs=() +funcs+=("Benchmark_ArrayFlatIntToJson_Refmt") +funcs+=("Benchmark_ArrayFlatIntToJson_Stdlib") +funcs+=("Benchmark_ArrayFlatStrToJson_Refmt") +funcs+=("Benchmark_ArrayFlatStrToJson_Stdlib") + +funcs+=("Benchmark_StructToJson_Refmt") +funcs+=("Benchmark_StructToJson_Stdlib") + +profPath=".gopath/tmp/prof/" ; mkdir -p "$profPath" +go test -i . +export GODEBUG=allocfreetrace=1 +while read -r -u3 -d' ' func; do + (go test \ + -run=XXX -bench=$func \ + -count=1 + ) 2> "$profPath/$func.allocfreetrace" | grep "^Benchmark_" +done 3< <(echo "${funcs[@]} ") +ls -lah "$profPath"/*.allocfreetrace + +## +## Recommendations for extracting knowledge: +## - grep for 'refmt' lines with context ~8 +## - you really want to get the 'tracealloc' lines in sight, because they list the object type being allocated in plain english +## - to find the beginning of a run, it's currently correct to grep for 'api.go', then find the start of pump.Run, +## then feed that line number back into a grep (where your first grep for refmt lines emits line numbers). +## - you'll see ~3 different line numbers from api.go; the least frequent is the start of Run. +## - grepping ", tok.Token)" is also valid, since we have succeeded at only allocating that once per Run +## (though actually it's a bit of a wonder to me that it doesn't stay on the stack). +## + +## +## More generally: want: +## - foreach tracealloc line: that line +## - accept the following '^goroutine' line +## - skip lines matching '^runtime.' and '^t' +## - maybe keep the '^runtime.' lines, because they tell you if 'newObject' vs 'makeSlice' +## - accept two lines -- this is the proximate cause, call and source file. +## - you can probably discard the rest +## + +## +## ALTERNATIVELY to all of this: +## just try '-gcflags -m' for things. Result is much shorter, much faster, much more to the point. +## diff --git a/vendor/github.com/polydawn/refmt/cbor/cborCommon.go b/vendor/github.com/polydawn/refmt/cbor/cborCommon.go new file mode 100644 index 00000000..ffc36b20 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborCommon.go @@ -0,0 +1,44 @@ +package cbor + +// "Major types" enum, as per https://tools.ietf.org/html/rfc7049#section-2.1 . +// +// These numbers are the bottom of the range for that major type when encoded; +// that is, ints can be between `cborMajorUint` (inclusive) and `cborMajorNegInt` (exclusive). +// Zero out the 0x1f bitrange of a byte to see which major type it is (those bits are +// used for packing either length info or other specific enumerated meanings). +const ( + cborMajorUint byte = 0x00 + cborMajorNegInt = 0x20 + cborMajorBytes = 0x40 + cborMajorString = 0x60 + cborMajorArray = 0x80 + cborMajorMap = 0xa0 + cborMajorTag = 0xc0 + cborMajorSimple = 0xe0 // Floating point, "simple" types like bool, etc, are above. +) + +// Enumeration of some values with single fixed-byte representations. +// All of these are in the "simple" space. +// See https://tools.ietf.org/html/rfc7049#section-2.3 for tables. +// The prefix indicating a float is also packed into the simple space. +const ( + cborSigilFalse byte = 0xf4 + cborSigilTrue = 0xf5 + cborSigilNil = 0xf6 + cborSigilUndefined = 0xf7 + cborSigilFloat16 = 0xf9 + cborSigilFloat32 = 0xfA + cborSigilFloat64 = 0xfB +) + +// The highest value in the range for bytes, text, arrays, and maps all indicate +// an "indefinite length" / "streaming" entry coming up. These have a different parse path. +// The special 'break' value from the "simple" space (all bits on) +// indicates termination of stream for all four kinds major types in this mode. +const ( + cborSigilIndefiniteBytes byte = 0x5f + cborSigilIndefiniteString = 0x7f + cborSigilIndefiniteArray = 0x9f + cborSigilIndefiniteMap = 0xbf + cborSigilBreak = 0xff +) diff --git a/vendor/github.com/polydawn/refmt/cbor/cborDecoder.go b/vendor/github.com/polydawn/refmt/cbor/cborDecoder.go new file mode 100644 index 00000000..e70b1a8d --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborDecoder.go @@ -0,0 +1,282 @@ +package cbor + +import ( + "fmt" + "io" + + "github.com/polydawn/refmt/shared" + . "github.com/polydawn/refmt/tok" +) + +type Decoder struct { + cfg DecodeOptions + r shared.SlickReader + + stack []decoderStep // When empty, and step returns done, all done. + step decoderStep // Shortcut to end of stack. + left []int // Statekeeping space for definite-len map and array. +} + +func NewDecoder(cfg DecodeOptions, r io.Reader) (d *Decoder) { + d = &Decoder{ + cfg: cfg, + r: shared.NewReader(r), + stack: make([]decoderStep, 0, 10), + left: make([]int, 0, 10), + } + d.step = d.step_acceptValue + return +} + +func (d *Decoder) Reset() { + d.stack = d.stack[0:0] + d.step = d.step_acceptValue + d.left = d.left[0:0] +} + +type decoderStep func(tokenSlot *Token) (done bool, err error) + +func (d *Decoder) Step(tokenSlot *Token) (done bool, err error) { + done, err = d.step(tokenSlot) + // If the step errored: out, entirely. + if err != nil { + return true, err + } + // If the step wasn't done, return same status. + if !done { + return false, nil + } + // If it WAS done, pop next, or if stack empty, we're entirely done. + nSteps := len(d.stack) - 1 + if nSteps <= 0 { + return true, nil // that's all folks + } + d.step = d.stack[nSteps] + d.stack = d.stack[0:nSteps] + return false, nil +} + +func (d *Decoder) pushPhase(newPhase decoderStep) { + d.stack = append(d.stack, d.step) + d.step = newPhase +} + +// The original step, where any value is accepted, and no terminators for composites are valid. +// ONLY used in the original step; all other steps handle leaf nodes internally. +func (d *Decoder) step_acceptValue(tokenSlot *Token) (done bool, err error) { + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + tokenSlot.Tagged = false + return d.stepHelper_acceptValue(majorByte, tokenSlot) +} + +// Step in midst of decoding an indefinite-length array. +func (d *Decoder) step_acceptArrValueOrBreak(tokenSlot *Token) (done bool, err error) { + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + tokenSlot.Tagged = false + switch majorByte { + case cborSigilBreak: + tokenSlot.Type = TArrClose + return true, nil + default: + _, err := d.stepHelper_acceptValue(majorByte, tokenSlot) + return false, err + } +} + +// Step in midst of decoding an indefinite-length map, key expected up next, or end. +func (d *Decoder) step_acceptMapIndefKey(tokenSlot *Token) (done bool, err error) { + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + tokenSlot.Tagged = false + switch majorByte { + case cborSigilBreak: + tokenSlot.Type = TMapClose + return true, nil + default: + d.step = d.step_acceptMapIndefValueOrBreak + _, err := d.stepHelper_acceptValue(majorByte, tokenSlot) // FIXME surely not *any* value? not composites, at least? + return false, err + } +} + +// Step in midst of decoding an indefinite-length map, value expected up next. +func (d *Decoder) step_acceptMapIndefValueOrBreak(tokenSlot *Token) (done bool, err error) { + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + tokenSlot.Tagged = false + switch majorByte { + case cborSigilBreak: + return true, fmt.Errorf("unexpected break; expected value in indefinite-length map") + default: + d.step = d.step_acceptMapIndefKey + _, err = d.stepHelper_acceptValue(majorByte, tokenSlot) + return false, err + } +} + +// Step in midst of decoding a definite-length array. +func (d *Decoder) step_acceptArrValue(tokenSlot *Token) (done bool, err error) { + // Yield close token, pop state, and return done flag if expecting no more entries. + ll := len(d.left) - 1 + if d.left[ll] == 0 { + d.left = d.left[0:ll] + tokenSlot.Type = TArrClose + return true, nil + } + d.left[ll]-- + // Read next value. + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + tokenSlot.Tagged = false + _, err = d.stepHelper_acceptValue(majorByte, tokenSlot) + return false, err +} + +// Step in midst of decoding an definite-length map, key expected up next. +func (d *Decoder) step_acceptMapKey(tokenSlot *Token) (done bool, err error) { + // Yield close token, pop state, and return done flag if expecting no more entries. + ll := len(d.left) - 1 + if d.left[ll] == 0 { + d.left = d.left[0:ll] + tokenSlot.Type = TMapClose + return true, nil + } + d.left[ll]-- + // Read next key. + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + d.step = d.step_acceptMapValue + tokenSlot.Tagged = false + _, err = d.stepHelper_acceptValue(majorByte, tokenSlot) // FIXME surely not *any* value? not composites, at least? + return false, err +} + +// Step in midst of decoding an definite-length map, value expected up next. +func (d *Decoder) step_acceptMapValue(tokenSlot *Token) (done bool, err error) { + // Read next value. + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + d.step = d.step_acceptMapKey + tokenSlot.Tagged = false + _, err = d.stepHelper_acceptValue(majorByte, tokenSlot) + return false, err +} + +func (d *Decoder) stepHelper_acceptValue(majorByte byte, tokenSlot *Token) (done bool, err error) { + switch majorByte { + case cborSigilNil: + tokenSlot.Type = TNull + return true, nil + case cborSigilUndefined: + if d.cfg.CoerceUndefToNull { + tokenSlot.Type = TNull + return true, nil + } + return true, fmt.Errorf("encountered cbor 'undefined' byte (%x) during decoding", cborSigilUndefined) + case cborSigilFalse: + tokenSlot.Type = TBool + tokenSlot.Bool = false + return true, nil + case cborSigilTrue: + tokenSlot.Type = TBool + tokenSlot.Bool = true + return true, nil + case cborSigilFloat16, cborSigilFloat32, cborSigilFloat64: + tokenSlot.Type = TFloat64 + tokenSlot.Float64, err = d.decodeFloat(majorByte) + return true, err + case cborSigilIndefiniteBytes: + tokenSlot.Type = TBytes + tokenSlot.Bytes, err = d.decodeBytesIndefinite(nil) + return true, err + case cborSigilIndefiniteString: + tokenSlot.Type = TString + tokenSlot.Str, err = d.decodeStringIndefinite() + return true, err + case cborSigilIndefiniteArray: + tokenSlot.Type = TArrOpen + tokenSlot.Length = -1 + d.pushPhase(d.step_acceptArrValueOrBreak) + return false, nil + case cborSigilIndefiniteMap: + tokenSlot.Type = TMapOpen + tokenSlot.Length = -1 + d.pushPhase(d.step_acceptMapIndefKey) + return false, nil + default: + switch { + case majorByte >= cborMajorUint && majorByte < cborMajorNegInt: + tokenSlot.Type = TUint + tokenSlot.Uint, err = d.decodeUint(majorByte) + return true, err + case majorByte >= cborMajorNegInt && majorByte < cborMajorBytes: + tokenSlot.Type = TInt + tokenSlot.Int, err = d.decodeNegInt(majorByte) + return true, err + case majorByte >= cborMajorBytes && majorByte < cborMajorString: + tokenSlot.Type = TBytes + tokenSlot.Bytes, err = d.decodeBytes(majorByte) + return true, err + case majorByte >= cborMajorString && majorByte < cborMajorArray: + tokenSlot.Type = TString + tokenSlot.Str, err = d.decodeString(majorByte) + return true, err + case majorByte >= cborMajorArray && majorByte < cborMajorMap: + var n int + n, err = d.decodeLen(majorByte) + tokenSlot.Type = TArrOpen + tokenSlot.Length = n + d.left = append(d.left, n) + d.pushPhase(d.step_acceptArrValue) + return false, err + case majorByte >= cborMajorMap && majorByte < cborMajorTag: + var n int + n, err = d.decodeLen(majorByte) + tokenSlot.Type = TMapOpen + tokenSlot.Length = n + d.left = append(d.left, n) + d.pushPhase(d.step_acceptMapKey) + return false, err + case majorByte >= cborMajorTag && majorByte < cborMajorSimple: + // CBOR tags are, frankly, bonkers, and should not be used. + // They break isomorphism to basic standards like JSON. + // We'll parse basic integer tag values -- SINGLE layer only. + // We will NOT parse the full gamut of recursive tags: doing so + // would mean allowing an unbounded number of allocs *during + // *processing of a single token*, which is _not reasonable_. + if tokenSlot.Tagged { + return true, fmt.Errorf("unsupported multiple tags on a single data item") + } + tokenSlot.Tagged = true + tokenSlot.Tag, err = d.decodeLen(majorByte) + if err != nil { + return true, err + } + // Okay, we slurped a tag. + // Read next value. + majorByte, err := d.r.Readn1() + if err != nil { + return true, err + } + return d.stepHelper_acceptValue(majorByte, tokenSlot) + default: + return true, fmt.Errorf("Invalid majorByte: 0x%x", majorByte) + } + } +} diff --git a/vendor/github.com/polydawn/refmt/cbor/cborDecoderTerminals.go b/vendor/github.com/polydawn/refmt/cbor/cborDecoderTerminals.go new file mode 100644 index 00000000..b9583d75 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborDecoderTerminals.go @@ -0,0 +1,235 @@ +package cbor + +import ( + "encoding/binary" + "errors" + "fmt" + "math" +) + +const ( + maxUint = ^uint(0) + maxInt = int(maxUint >> 1) +) + +func (d *Decoder) decodeFloat(majorByte byte) (f float64, err error) { + var bs []byte + switch majorByte { + case cborSigilFloat16: + bs, err = d.r.Readnzc(2) + f = float64(math.Float32frombits(halfFloatToFloatBits(binary.BigEndian.Uint16(bs)))) + case cborSigilFloat32: + bs, err = d.r.Readnzc(4) + f = float64(math.Float32frombits(binary.BigEndian.Uint32(bs))) + case cborSigilFloat64: + bs, err = d.r.Readnzc(8) + f = math.Float64frombits(binary.BigEndian.Uint64(bs)) + } + return +} + +// Decode an unsigned int. +// Must continue to hand down the majorByte because some of its bits are either +// packed with the value outright, or tell us how many more bytes the value fills. +func (d *Decoder) decodeUint(majorByte byte) (ui uint64, err error) { + v := majorByte & 0x1f + if v <= 0x17 { + ui = uint64(v) + } else { + if v == 0x18 { + var b byte + b, err = d.r.Readn1() + ui = uint64(b) + } else if v == 0x19 { + var bs []byte + bs, err = d.r.Readnzc(2) + ui = uint64(binary.BigEndian.Uint16(bs)) + } else if v == 0x1a { + var bs []byte + bs, err = d.r.Readnzc(4) + ui = uint64(binary.BigEndian.Uint32(bs)) + } else if v == 0x1b { + var bs []byte + bs, err = d.r.Readnzc(8) + ui = uint64(binary.BigEndian.Uint64(bs)) + } else { + err = fmt.Errorf("decodeUint: Invalid descriptor: %v", majorByte) + return + } + } + return +} + +// Decode a *negative* integer. +// Note that CBOR has a very funny-shaped hole here: there is unsigned positive int, +// and there is explicitly negative signed int... and there is no signed, positive int. +// *We have no 'decodeInt' function because that **doesn't exist** in CBOR.* +// So! Hopefully our consumer doesn't mind having to cast uints to ints fairly frequently. +func (d *Decoder) decodeNegInt(majorByte byte) (i int64, err error) { + // The packed bits in the majorByte and the following bytes if any are layed out + // the exact same as a uint; only the major type bits are different. + ui, err := d.decodeUint(majorByte) + if err != nil { + return 0, err + } + pos := ui + 1 + if pos > uint64(-math.MinInt64) { + return -1, errors.New("cbor: negative integer out of rage of int64 type") + } + + return -int64(pos), nil +} + +// Decode expecting a positive integer. +// None of our token-yielding functions call this directly; +// it's used inside the library when we expect to read e.g. a length header. +// Does not check that your majorByte indicates an integer type at all; +// in context, it often doesn't, e.g. when decoding the length of a string. +func (d *Decoder) decodeLen(majorByte byte) (i int, err error) { + ui, err := d.decodeUint(majorByte) + if err != nil { + return 0, err + } + if ui > uint64(maxInt) { + return 0, errors.New("cbor: positive integer is out of length") + } + return int(ui), nil +} + +// Decoding indefinite-length byte strings in cbor is actually decoding a sequence of +// definite-length byte strings until you encounter a break. +// Caller: use `bs[:0]` if you have something to reuse, or nil +func (d *Decoder) decodeBytesIndefinite(bs []byte) (bsOut []byte, err error) { + return d.decodeBytesOrStringIndefinite(bs, cborMajorBytes) +} + +func (d *Decoder) decodeStringIndefinite() (s string, err error) { + bs, err := d.decodeBytesOrStringIndefinite(nil, cborMajorString) + if err != nil { + return "", err + } + return string(bs), nil +} + +func (d *Decoder) decodeBytesOrStringIndefinite(bs []byte, majorWanted byte) (bsOut []byte, err error) { + if bs == nil { + bs = make([]byte, 0, 16) + } + var n int + for { + // Read first byte; check for break, or hunk, or invalid. + // (It's not necessary to have the first majorByte as a param to this function, because + // indefinite length sequences have a separate sigil which doesn't pack any len info.) + majorByte, err := d.r.Readn1() + if err != nil { + return bs, err + } + if majorByte == cborSigilBreak { + return bs, nil + } else if major := majorByte | 0x1f - 0x1f; major != majorWanted { + return bs, fmt.Errorf("cbor: expect bytes or string major type in indefinite string/bytes; got: %v, byte: %v", major, majorByte) + } + // Read length header for this hunk, and ensure we have at least that much cap. + n, err = d.decodeLen(majorByte) + if err != nil { + return bs, err + } + oldLen := len(bs) + newLen := oldLen + n + if n > 33554432 { + return nil, fmt.Errorf("cbor: decoding rejected oversized indefinite string/bytes field: %d is too large", n) + } + if newLen > cap(bs) { + bs2 := make([]byte, newLen, 2*cap(bs)+n) + copy(bs2, bs) + bs = bs2 + } else { + bs = bs[:newLen] + } + // Read that hunk. + d.r.Readb(bs[oldLen:newLen]) + } +} + +// Decode a single length-prefixed hunk of bytes. +// +// There are a number of ways this may try to conserve allocations: +// +// - If you say zerocopy=true, and the underlying reader system already has an +// appropriate byte slice available, then a slice from that will be returned. +// +// - If you provide a byte slice, we will attempt to use it. +// The byte slice is truncated and used for its capacity only -- not appended. +// The final returned slice may be a different one if the provided slice did not +// have sufficient capacity. +// +// - If you say zerocopy=true, and the underlying read system doesn't have an +// efficient way to yield a slice of its internal buffer, and you provided no +// destination slice, then we will use a recycleable piece of memory in the Decoder +// state and return a slice viewing into it. For small values this will +// likely save an alloc. +// +// The above rules are resolved in this order; e.g. your byte slice is disregarded +// if zerocopy=true and the underlying reader can do something even more efficient, +// though there is also no harm to providing the slice argument. +// Generally, set zerocopy if you know you're not going to publicly yield the results, +// and the implementation will do its best to be as efficient as possible. +// +// Zerocopy is appropriate when planning to turn the bytes into a string, for example, +// since in that path we know the slice will be treated immutably, not publicly +// exposed, and also any other copy to another intermediate is definitely useless. +func (d *Decoder) decodeBytes(majorByte byte) (bs []byte, err error) { + n, err := d.decodeLen(majorByte) + if err != nil { + return nil, err + } + if n > 33554432 { + return nil, fmt.Errorf("cbor: decoding rejected oversized byte field: %d is too large", n) + } + return d.r.Readn(n) +} + +// Decode a single length-prefixed string. +func (d *Decoder) decodeString(majorByte byte) (s string, err error) { + n, err := d.decodeLen(majorByte) + if err != nil { + return "", err + } + if n > 33554432 { + return "", fmt.Errorf("cbor: decoding rejected oversized string field: %d is too large", n) + } + bs, err := d.r.Readnzc(n) + return string(bs), err +} + +// culled from OGRE (Object-Oriented Graphics Rendering Engine) +// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html) +func halfFloatToFloatBits(yy uint16) (d uint32) { + y := uint32(yy) + s := (y >> 15) & 0x01 + e := (y >> 10) & 0x1f + m := y & 0x03ff + + if e == 0 { + if m == 0 { // plu or minus 0 + return s << 31 + } else { // Denormalized number -- renormalize it + for (m & 0x00000400) == 0 { + m <<= 1 + e -= 1 + } + e += 1 + const zz uint32 = 0x0400 + m &= ^zz + } + } else if e == 31 { + if m == 0 { // Inf + return (s << 31) | 0x7f800000 + } else { // NaN + return (s << 31) | 0x7f800000 | (m << 13) + } + } + e = e + (127 - 15) + m = m << 13 + return (s << 31) | (e << 23) | m +} diff --git a/vendor/github.com/polydawn/refmt/cbor/cborEncoder.go b/vendor/github.com/polydawn/refmt/cbor/cborEncoder.go new file mode 100644 index 00000000..9b431d59 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborEncoder.go @@ -0,0 +1,276 @@ +package cbor + +import ( + "io" + + . "github.com/polydawn/refmt/tok" +) + +type Encoder struct { + w quickWriter + + stack []encoderPhase // When empty, and step returns done, all done. + current encoderPhase // Shortcut to end of stack. + // Note unlike decoder, we need no statekeeping space for definite-len map and array. + + spareBytes []byte +} + +func NewEncoder(w io.Writer) (d *Encoder) { + d = &Encoder{ + w: newQuickWriterStream(w), + stack: make([]encoderPhase, 0, 10), + current: phase_anyExpectValue, + spareBytes: make([]byte, 8), + } + return +} + +func (d *Encoder) Reset() { + d.stack = d.stack[0:0] + d.current = phase_anyExpectValue +} + +type encoderPhase byte + +// There's about twice as many phases that the cbor encoder can be in compared to the json encoder +// because the presense of indefinite vs definite length maps and arrays effectively adds a dimension to those. +const ( + phase_anyExpectValue encoderPhase = iota + phase_mapDefExpectKeyOrEnd // must not yield break at end + phase_mapDefExpectValue // only necessary to flip back to DefExpectKey + phase_mapIndefExpectKeyOrEnd // must yield break at end + phase_mapIndefExpectValue // only necessary to flip back to IndefExpectKey + phase_arrDefExpectValueOrEnd // must not yield break at end + phase_arrIndefExpectValueOrEnd // must yield break at end +) + +func (d *Encoder) pushPhase(p encoderPhase) { + d.current = p + d.stack = append(d.stack, d.current) +} + +// Pop a phase from the stack; return 'true' if stack now empty. +func (d *Encoder) popPhase() bool { + n := len(d.stack) - 1 + if n == 0 { + return true + } + if n < 0 { // the state machines are supposed to have already errored better + panic("cborEncoder stack overpopped") + } + d.current = d.stack[n-1] + d.stack = d.stack[0:n] + return false +} + +func (d *Encoder) Step(tokenSlot *Token) (done bool, err error) { + /* + Though it reads somewhat backwards from how a human would probably intuit + cause and effect, switching on the token type we got first, + *then* switching for whether it is acceptable for our current phase... is by + far the shorter volume of code to write. + */ + phase := d.current + switch tokenSlot.Type { + case TMapOpen: + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + if tokenSlot.Length >= 0 { + d.pushPhase(phase_mapDefExpectKeyOrEnd) + d.emitMajorPlusLen(cborMajorMap, uint64(tokenSlot.Length)) + } else { + d.pushPhase(phase_mapIndefExpectKeyOrEnd) + d.w.writen1(cborSigilIndefiniteMap) + } + return false, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TMapClose: + switch phase { + case phase_mapDefExpectKeyOrEnd: + return d.popPhase(), nil + case phase_mapIndefExpectKeyOrEnd: + d.w.writen1(cborSigilBreak) + return d.popPhase(), d.w.checkErr() + case phase_anyExpectValue, phase_mapDefExpectValue, phase_mapIndefExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForValue} + default: + panic("unreachable phase") + } + case TArrOpen: + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + if tokenSlot.Length >= 0 { + d.pushPhase(phase_arrDefExpectValueOrEnd) + d.emitMajorPlusLen(cborMajorArray, uint64(tokenSlot.Length)) + } else { + d.pushPhase(phase_arrIndefExpectValueOrEnd) + d.w.writen1(cborSigilIndefiniteArray) + } + return false, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TArrClose: + switch phase { + case phase_arrDefExpectValueOrEnd: + return d.popPhase(), nil + case phase_arrIndefExpectValueOrEnd: + d.w.writen1(cborSigilBreak) + return d.popPhase(), d.w.checkErr() + case phase_anyExpectValue, phase_mapDefExpectValue, phase_mapIndefExpectValue: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForValue} + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TNull: // terminal value; not accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.w.writen1(cborSigilNil) + return phase == phase_anyExpectValue, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TString: // terminal value; YES, accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + goto emitStr + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + d.current += 1 + goto emitStr + default: + panic("unreachable phase") + } + emitStr: + { + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeString(tokenSlot.Str) + return phase == phase_anyExpectValue, d.w.checkErr() + } + case TBytes: // terminal value; not accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeBytes(tokenSlot.Bytes) + return phase == phase_anyExpectValue, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TBool: // terminal value; not accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeBool(tokenSlot.Bool) + return phase == phase_anyExpectValue, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + case TInt: // terminal value; YES, accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + goto emitInt + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + d.current += 1 + goto emitInt + default: + panic("unreachable phase") + } + emitInt: + { + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeInt64(tokenSlot.Int) + return phase == phase_anyExpectValue, d.w.checkErr() + } + case TUint: // terminal value; YES, accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + goto emitUint + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + d.current += 1 + goto emitUint + default: + panic("unreachable phase") + } + emitUint: + { + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeUint64(tokenSlot.Uint) + return phase == phase_anyExpectValue, d.w.checkErr() + } + case TFloat64: // terminal value; not accepted as map key. + switch phase { + case phase_mapDefExpectValue, phase_mapIndefExpectValue: + d.current -= 1 + fallthrough + case phase_anyExpectValue, phase_arrDefExpectValueOrEnd, phase_arrIndefExpectValueOrEnd: + if tokenSlot.Tagged { + d.emitMajorPlusLen(cborMajorTag, uint64(tokenSlot.Tag)) + } + d.encodeFloat64(tokenSlot.Float64) + return phase == phase_anyExpectValue, d.w.checkErr() + case phase_mapDefExpectKeyOrEnd, phase_mapIndefExpectKeyOrEnd: + return true, &ErrInvalidTokenStream{Got: *tokenSlot, Acceptable: tokenTypesForKey} + default: + panic("unreachable phase") + } + default: + panic("unhandled token type") + } +} diff --git a/vendor/github.com/polydawn/refmt/cbor/cborEncoderTerminals.go b/vendor/github.com/polydawn/refmt/cbor/cborEncoderTerminals.go new file mode 100644 index 00000000..7f5ede8d --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborEncoderTerminals.go @@ -0,0 +1,77 @@ +package cbor + +import ( + "encoding/binary" + "math" +) + +func (d *Encoder) emitLen(majorByte byte, length int) { + d.emitMajorPlusLen(majorByte, uint64(length)) +} + +func (d *Encoder) emitMajorPlusLen(majorByte byte, v uint64) { + if v <= 0x17 { + d.w.writen1(majorByte + byte(v)) + } else if v <= math.MaxUint8 { + d.w.writen2(majorByte+0x18, uint8(v)) + } else if v <= math.MaxUint16 { + d.w.writen1(majorByte + 0x19) + d.spareBytes = d.spareBytes[:2] + binary.BigEndian.PutUint16(d.spareBytes, uint16(v)) + d.w.writeb(d.spareBytes) + } else if v <= math.MaxUint32 { + d.w.writen1(majorByte + 0x1a) + d.spareBytes = d.spareBytes[:4] + binary.BigEndian.PutUint32(d.spareBytes, uint32(v)) + d.w.writeb(d.spareBytes) + } else { // if v <= math.MaxUint64 { + d.w.writen1(majorByte + 0x1b) + d.spareBytes = d.spareBytes[:8] + binary.BigEndian.PutUint64(d.spareBytes, v) + d.w.writeb(d.spareBytes) + } +} + +func (d *Encoder) encodeNull() { + d.w.writen1(cborSigilNil) +} + +func (d *Encoder) encodeString(s string) { + d.emitMajorPlusLen(cborMajorString, uint64(len(s))) + d.w.writestr(s) +} + +func (d *Encoder) encodeBytes(bs []byte) { + d.emitMajorPlusLen(cborMajorBytes, uint64(len(bs))) + d.w.writeb(bs) +} + +func (d *Encoder) encodeBool(b bool) { + if b { + d.w.writen1(cborSigilTrue) + } else { + d.w.writen1(cborSigilFalse) + } +} + +func (d *Encoder) encodeInt64(v int64) { + if v >= 0 { + d.emitMajorPlusLen(cborMajorUint, uint64(v)) + } else { + d.emitMajorPlusLen(cborMajorNegInt, uint64(-1-v)) + } +} + +func (d *Encoder) encodeUint64(v uint64) { + d.emitMajorPlusLen(cborMajorUint, v) +} + +func (d *Encoder) encodeFloat64(v float64) { + // Can we pack it into 32? No idea: float precision is fraught with peril. + // See https://play.golang.org/p/u9sN6x0kk6 + // So we *only* emit the full 64-bit style. The CBOR spec permits this. + d.w.writen1(cborSigilFloat64) + d.spareBytes = d.spareBytes[:8] + binary.BigEndian.PutUint64(d.spareBytes, math.Float64bits(v)) + d.w.writeb(d.spareBytes) +} diff --git a/vendor/github.com/polydawn/refmt/cbor/cborHelpers.go b/vendor/github.com/polydawn/refmt/cbor/cborHelpers.go new file mode 100644 index 00000000..f7c4b778 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborHelpers.go @@ -0,0 +1,106 @@ +package cbor + +import ( + "bytes" + "io" + + "github.com/polydawn/refmt/obj" + "github.com/polydawn/refmt/obj/atlas" + "github.com/polydawn/refmt/shared" +) + +// All of the methods in this file are exported, +// and their names and type declarations are intended to be +// identical to the naming and types of the golang stdlib +// 'encoding/json' packages, with ONE EXCEPTION: +// what stdlib calls "NewEncoder", we call "NewMarshaller"; +// what stdlib calls "NewDecoder", we call "NewUnmarshaller"; +// and similarly the types and methods are "Marshaller.Marshal" +// and "Unmarshaller.Unmarshal". +// You should be able to migrate with a sed script! +// +// (In refmt, the encoder/decoder systems are for token streams; +// if you're talking about object mapping, we consistently +// refer to that as marshalling/unmarshalling.) +// +// Most methods also have an "Atlased" variant, +// which lets you specify advanced type mapping instructions. + +func Marshal(v interface{}) ([]byte, error) { + var buf bytes.Buffer + if err := NewMarshaller(&buf).Marshal(v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func MarshalAtlased(v interface{}, atl atlas.Atlas) ([]byte, error) { + var buf bytes.Buffer + if err := NewMarshallerAtlased(&buf, atl).Marshal(v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +type Marshaller struct { + marshaller *obj.Marshaller + encoder *Encoder + pump shared.TokenPump +} + +func (x *Marshaller) Marshal(v interface{}) error { + x.marshaller.Bind(v) + x.encoder.Reset() + return x.pump.Run() +} + +func NewMarshaller(wr io.Writer) *Marshaller { + return NewMarshallerAtlased(wr, atlas.MustBuild()) +} + +func NewMarshallerAtlased(wr io.Writer, atl atlas.Atlas) *Marshaller { + x := &Marshaller{ + marshaller: obj.NewMarshaller(atl), + encoder: NewEncoder(wr), + } + x.pump = shared.TokenPump{ + x.marshaller, + x.encoder, + } + return x +} + +func Unmarshal(cfg DecodeOptions, data []byte, v interface{}) error { + return NewUnmarshaller(cfg, bytes.NewBuffer(data)).Unmarshal(v) +} + +func UnmarshalAtlased(cfg DecodeOptions, data []byte, v interface{}, atl atlas.Atlas) error { + return NewUnmarshallerAtlased(cfg, bytes.NewBuffer(data), atl).Unmarshal(v) +} + +type Unmarshaller struct { + unmarshaller *obj.Unmarshaller + decoder *Decoder + pump shared.TokenPump +} + +func (x *Unmarshaller) Unmarshal(v interface{}) error { + x.unmarshaller.Bind(v) + x.decoder.Reset() + return x.pump.Run() +} + +func NewUnmarshaller(cfg DecodeOptions, r io.Reader) *Unmarshaller { + return NewUnmarshallerAtlased(cfg, r, atlas.MustBuild()) +} +func NewUnmarshallerAtlased(cfg DecodeOptions, r io.Reader, atl atlas.Atlas) *Unmarshaller { + x := &Unmarshaller{ + unmarshaller: obj.NewUnmarshaller(atl), + decoder: NewDecoder(cfg, r), + } + x.pump = shared.TokenPump{ + x.decoder, + x.unmarshaller, + } + return x +} diff --git a/vendor/github.com/polydawn/refmt/cbor/cborOptions.go b/vendor/github.com/polydawn/refmt/cbor/cborOptions.go new file mode 100644 index 00000000..69ccd685 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/cborOptions.go @@ -0,0 +1,20 @@ +package cbor + +type EncodeOptions struct { + // there aren't a ton of options for cbor, but we still need this + // for use as a sigil for the top-level refmt methods to demux on. +} + +// marker method -- you may use this type to instruct `refmt.Marshal` +// what kind of encoder to use. +func (EncodeOptions) IsEncodeOptions() {} + +type DecodeOptions struct { + CoerceUndefToNull bool + + // future: options to validate canonical serial order +} + +// marker method -- you may use this type to instruct `refmt.Marshal` +// what kind of encoder to use. +func (DecodeOptions) IsDecodeOptions() {} diff --git a/vendor/github.com/polydawn/refmt/cbor/doc.go b/vendor/github.com/polydawn/refmt/cbor/doc.go new file mode 100644 index 00000000..4972b592 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/doc.go @@ -0,0 +1,27 @@ +/* + Package implementing the CBOR -- Concise Binary Object Notation + -- http://cbor.io/ -- spec. + + CBOR is more or less freely interchangable with json: it's schemaless, + and composed of similar map and array types. + However, CBOR is binary, length delimited -- and thus very fast to parse, + and can store binary data without expansion problems -- and also distinguishes + types like integer, string, float, and bytes all clearly from each other. + + The `cbor.Marshal` and `cbor.Unmarshal` functions are the quickest way + to convert your Go objects to and from serial CBOR. + + The `cbor.NewMarshaller` and `cbor.NewUmarshaller` functions give a little + more control. If performance is important, prefer these; recycling + the marshaller instances will significantly cut down on memory allocations + and improve performance. + + The `*Atlased` variants of constructors allow you set up marshalling with + an `refmt/obj/atlas.Atlas`, unlocking all of refmt's advanced features + and custom object mapping powertools. + + The `cbor.Encoder` and `cbor.Decoder` types implement the low-level functionality + of converting serial CBOR byte streams into refmt Token streams. + Users don't usually need to use these directly. +*/ +package cbor diff --git a/vendor/github.com/polydawn/refmt/cbor/encodeWriter.go b/vendor/github.com/polydawn/refmt/cbor/encodeWriter.go new file mode 100644 index 00000000..1ee4839e --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/encodeWriter.go @@ -0,0 +1,107 @@ +package cbor + +import ( + "fmt" + "io" +) + +var ( + _ quickWriter = &quickWriterStream{} +) + +// quickWriter is implements several methods that are specificly useful to the performance +// needs of our encoders, and abstracts writing to a byte array or to an io.Writer. +type quickWriter interface { + writeb([]byte) + writestr(string) + writen1(byte) + writen2(byte, byte) + checkErr() error + clearErr() +} + +// Interface used to detect if efficient string writing is supported. +// Same as in stdlib 'io' pkg; also not exported there, so we declare it again ourselves. +type stringWriter interface { + WriteString(s string) (n int, err error) +} + +// quickWriterStream is a quickWriter that routes bytes to an io.Writer. +// While this implementation does use some internal buffers, it's still advisable +// to use a buffered writer to avoid small operations for any external IO like disk or network. +type quickWriterStream struct { + w io.Writer + ws stringWriter // nil if not available + + scratch [2]byte + scratch1 []byte + scratch2 []byte + err error +} + +func newQuickWriterStream(w io.Writer) *quickWriterStream { + z := &quickWriterStream{w: w} + if ws, ok := w.(stringWriter); ok { + z.ws = ws + } + z.scratch1 = z.scratch[:1] + z.scratch2 = z.scratch[:2] + return z +} + +func (z *quickWriterStream) writeb(bs []byte) { + n, err := z.w.Write(bs) + if err != nil && z.err == nil { + z.err = err + } + if n < len(bs) && z.err == nil { + z.err = fmt.Errorf("underwrite") + } +} + +func (z *quickWriterStream) writestr(s string) { + var n int + var err error + if z.ws != nil { + n, err = z.ws.WriteString(s) + } else { + n, err = z.w.Write([]byte(s)) // Notice: alloc! + } + if err != nil && z.err == nil { + z.err = err + } + if n < len(s) && z.err == nil { + z.err = fmt.Errorf("underwrite") + } +} + +func (z *quickWriterStream) writen1(b byte) { + z.scratch1[0] = b + n, err := z.w.Write(z.scratch1) + if err != nil && z.err == nil { + z.err = err + } + if n < 1 && z.err == nil { + z.err = fmt.Errorf("underwrite") + } +} + +func (z *quickWriterStream) writen2(b1 byte, b2 byte) { + z.scratch2[0] = b1 + z.scratch2[1] = b2 + n, err := z.w.Write(z.scratch2) + if err != nil && z.err == nil { + z.err = err + } + if n < 2 && z.err == nil { + z.err = fmt.Errorf("underwrite") + } +} + +func (z *quickWriterStream) checkErr() error { + return z.err +} + +func (z *quickWriterStream) clearErr() { + z.err = nil +} diff --git a/vendor/github.com/polydawn/refmt/cbor/errors.go b/vendor/github.com/polydawn/refmt/cbor/errors.go new file mode 100644 index 00000000..25020d0d --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cbor/errors.go @@ -0,0 +1,22 @@ +package cbor + +import ( + "fmt" + + . "github.com/polydawn/refmt/tok" +) + +// Error raised by Encoder when invalid tokens or invalid ordering, e.g. a MapClose with no matching open. +// Should never be seen by the user in practice unless generating their own token streams. +type ErrInvalidTokenStream struct { + Got Token + Acceptable []TokenType +} + +func (e *ErrInvalidTokenStream) Error() string { + return fmt.Sprintf("ErrInvalidTokenStream: unexpected %v, expected %v", e.Got, e.Acceptable) + // More comprehensible strings might include "start of value", "start of key or end of map", "start of value or end of array". +} + +var tokenTypesForKey = []TokenType{TString, TInt, TUint} +var tokenTypesForValue = []TokenType{TMapOpen, TArrOpen, TNull, TString, TBytes, TInt, TUint, TFloat64} diff --git a/vendor/github.com/polydawn/refmt/cloneHelpers.go b/vendor/github.com/polydawn/refmt/cloneHelpers.go new file mode 100644 index 00000000..7dcf4059 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cloneHelpers.go @@ -0,0 +1,50 @@ +package refmt + +import ( + "github.com/polydawn/refmt/obj" + "github.com/polydawn/refmt/obj/atlas" + "github.com/polydawn/refmt/shared" +) + +func Clone(src, dst interface{}) error { + return CloneAtlased(src, dst, atlas.MustBuild()) +} +func MustClone(src, dst interface{}) { + if err := Clone(src, dst); err != nil { + panic(err) + } +} + +func CloneAtlased(src, dst interface{}, atl atlas.Atlas) error { + return NewCloner(atl).Clone(src, dst) +} +func MustCloneAtlased(src, dst interface{}, atl atlas.Atlas) { + if err := CloneAtlased(src, dst, atl); err != nil { + panic(err) + } +} + +type Cloner interface { + Clone(src, dst interface{}) error +} + +func NewCloner(atl atlas.Atlas) Cloner { + x := &cloner{ + marshaller: obj.NewMarshaller(atl), + unmarshaller: obj.NewUnmarshaller(atl), + } + x.pump = shared.TokenPump{x.marshaller, x.unmarshaller} + return x +} + +type cloner struct { + marshaller *obj.Marshaller + unmarshaller *obj.Unmarshaller + pump shared.TokenPump +} + +func (c cloner) Clone(src, dst interface{}) error { + c.marshaller.Bind(src) + c.unmarshaller.Bind(dst) + return c.pump.Run() +} diff --git a/vendor/github.com/polydawn/refmt/cover b/vendor/github.com/polydawn/refmt/cover new file mode 100755 index 00000000..e3587f90 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/cover @@ -0,0 +1,22 @@ +#!/bin/bash +set -euo pipefail + +PROJECT="github.com/polydawn/refmt" +SUBSECTION=${1:-./...} + +export GOPATH="$PWD/.gopath" + +CoverPkg() { + pkg="$1" + + coverFile="$GOPATH/tmp/$pkg.cover" + mkdir -p "$(dirname "$coverFile")" + rm -f "$coverFile" + go test -coverprofile="$coverFile" "$pkg" \ + | tee /dev/stderr | grep "\[no test files\]$" > /dev/null || \ + go tool cover -html="$coverFile" +} + +for pkg in $(go list "$SUBSECTION" | sed "s#^_${PWD}#${PROJECT}#"); do + CoverPkg "$pkg" || true # continue even if errors from packages that lack tests. +done diff --git a/vendor/github.com/polydawn/refmt/doc.go b/vendor/github.com/polydawn/refmt/doc.go new file mode 100644 index 00000000..fe9113d6 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/doc.go @@ -0,0 +1,12 @@ +/* + Refmt is a serialization and object-mapping library. + + Look to the README on github for more high-level information. + + This top-level package exposes simple helper methods for most common operations. + You can also compose custom marshallers/unmarshallers and serializer/deserializers + by constructing a `refmt.TokenPump` with components from the packages beneath this one. + For example, the `refmt.JsonEncode` helper method can be replicated by combining + an `obj.Marshaller` with a `json.Encoder`. +*/ +package refmt diff --git a/vendor/github.com/polydawn/refmt/goad b/vendor/github.com/polydawn/refmt/goad new file mode 100755 index 00000000..0b8b8f69 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/goad @@ -0,0 +1,142 @@ +#!/bin/bash +set -euo pipefail + +### Project details +name="refmt" +pkg="github.com/polydawn/$name" # everything under here will be tested +cmd="$pkg/cmd/$name" # if you have a main.main not at the repo root, set this + + + +### Normalize path -- all work should be relative to this script's location. +## Set up gopath -- also relative to this dir, so we work in isolation. +cd "$( dirname "${BASH_SOURCE[0]}" )" +export GOPATH="$PWD/.gopath/" +export GOBIN="$PWD/bin/" + + + +### other config scripts? invoke here. +## pass pointer to project root dir down, for tests (tests run in varying CWDs, so need this hint) +export PROJ="$PWD" +## use LDFLAGS to inject vars at compile time. +LDFLAGS="" + + + +### Last bits of our flag parsery. +# subcommand arg? +SUBCOMMAND=${1:-} +# subsection arg? +SUBSECTION=${2:-"..."} +SUBSECTION="./$SUBSECTION" +# default test timeouts are far too high. override this if you like. +TEST_TIMEOUT="${TEST_TIMEOUT:-"5s"}" + + + +### action begins! +if [ -z "$SUBCOMMAND" ] ; then + ( + go fmt "$SUBSECTION" + go install -ldflags "$LDFLAGS" "$cmd" && { + echo -e "\E[1;32minstall successful.\E[0;m\n" + } || { + echo -e "\E[1;41minstall failed!\E[0;m" + exit 8 + } + go test "$SUBSECTION" -timeout="$TEST_TIMEOUT" && { + echo -e "\n\E[1;32mall tests green.\E[0;m" + } || { + echo -e "\n\E[1;41msome tests failed!\E[0;m" + exit 4 + } + ) +else + shift # munch $subcommand from passing on in "$@" + case "$SUBCOMMAND" in + -) + # passthrough for other commands + go "$@" + ;; + env) + echo "GOROOT=`go env GOROOT`" + echo "GOPATH=`go env GOPATH`" + ;; + path) + echo "$GOPATH" + ;; + init) + # it's your responsibility to do this the first time + # (we don't do it at the front of every build because it will move submodules if you already have them, and that might not be what you want as you're plowing along) + git submodule update --init + # also make sure the self-symlink exists. should be committed anyway (but then, this is also useful for project-first-steps.) + mkdir -p "$(dirname ".gopath/src/$pkg")" + ln -snf "$(echo "${pkg//[^\/]}/" | sed s#/#../#g)"../ ".gopath/src/$pkg" + ;; + test) + set +e ; shift ; set -e # munch $subsection from passing on in "$@" + go test -i "$SUBSECTION" "$@" && + go test -v "$SUBSECTION" -timeout="$TEST_TIMEOUT" "$@" && { + echo -e "\n\E[1;32mall tests green.\E[0;m" + } || { + echo -e "\n\E[1;41msome tests failed!\E[0;m" + exit 4 + } + ;; + install) + go install -ldflags "$LDFLAGS" "$cmd" + ;; + bench) + profPath="$GOPATH/tmp/prof/" + mkdir -p "$profPath" + set +e ; shift ; set -e # munch $subsection from passing on in "$@" + go test -i "$SUBSECTION" "$@" && + GOCONVEY_REPORTER=silent \ + go test \ + -run=XXX -bench=. \ + -o "$profPath/bench.bin" \ + -cpuprofile="$profPath/cpu.pprof" \ + "$SUBSECTION" "$@" || { + echo -e "\E[1;41msome benchmarks failed!\E[0;m" + exit 4 + } + # use e.g.: go tool pprof --text .gopath/tmp/prof/bench.bin .gopath/tmp/prof/cpu.pprof + ;; + fmt) + go fmt "$SUBSECTION" + ;; + doc) + set +e ; shift ; set -e # munch $subsection from passing on in "$@" + for package in $(go list "$SUBSECTION" | sed "s#^_${PWD}#${pkg}#"); do + echo -e "==== $package ====\n" + godoc "$@" "$package" + echo -e "\n\n\n" + done + ;; + cover) + coverFile="$GOPATH/tmp/cover/cover.out" + mkdir -p "$(dirname "$coverFile")" + for package in $(go list "$SUBSECTION" | sed "s#^_${PWD}#${pkg}#"); do + rm -f "$coverFile" + echo "==== $package ====" + go test -coverprofile="$coverFile" "$package" && \ + [ -f "$coverFile" ] && \ + echo ---- && \ + go tool cover -func="$coverFile" && \ + echo ---- && \ + go tool cover -html="$coverFile" + echo ==== + echo + done + rm -f "$coverFile" + ;; + clean) + rm -rf "$GOBIN" "$GOPATH/pkg" "$GOPATH/tmp" + ;; + *) + echo "Usage: $0 {init|test|install|bench|fmt|doc|cover|clean}" 1>&2; + exit 1 + ;; + esac +fi diff --git a/vendor/github.com/polydawn/refmt/json/doc.go b/vendor/github.com/polydawn/refmt/json/doc.go new file mode 100644 index 00000000..f4e8c961 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/doc.go @@ -0,0 +1,20 @@ +/* + Package implementing the JSON -- http://json.org/ -- spec. + + The `json.Marshal` and `json.Unmarshal` functions are the quickest way + to convert your Go objects to and from serial JSON. + + The `json.NewMarshaller` and `json.NewUmarshaller` functions give a little + more control. If performance is important, prefer these; recycling + the marshaller instances will significantly cut down on memory allocations + and improve performance. + + The `*Atlased` variants of constructors allow you set up marshalling with + an `refmt/obj/atlas.Atlas`, unlocking all of refmt's advanced features + and custom object mapping powertools. + + The `json.Encoder` and `json.Decoder` types implement the low-level functionality + of converting serial JSON byte streams into refmt Token streams. + Users don't usually need to use these directly. +*/ +package json diff --git a/vendor/github.com/polydawn/refmt/json/jsonCommon.go b/vendor/github.com/polydawn/refmt/json/jsonCommon.go new file mode 100644 index 00000000..21e271ba --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonCommon.go @@ -0,0 +1,19 @@ +package json + +//const ( +// jsonMajor +//) + +// The most heavily used words, cached as byte slices. +var ( + wordTrue = []byte("true") + wordFalse = []byte("false") + wordNull = []byte("null") + wordArrOpen = []byte("[") + wordArrClose = []byte("]") + wordMapOpen = []byte("{") + wordMapClose = []byte("}") + wordColon = []byte(":") + wordComma = []byte(",") + wordSpace = []byte(" ") +) diff --git a/vendor/github.com/polydawn/refmt/json/jsonDecoder.go b/vendor/github.com/polydawn/refmt/json/jsonDecoder.go new file mode 100644 index 00000000..bc025e6a --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonDecoder.go @@ -0,0 +1,207 @@ +package json + +import ( + "fmt" + "io" + + "github.com/polydawn/refmt/shared" + . "github.com/polydawn/refmt/tok" +) + +type Decoder struct { + r shared.SlickReader + + stack []decoderStep // When empty, and step returns done, all done. + step decoderStep // Shortcut to end of stack. + some bool // Set to true after first value in any context; use to decide if a comma must precede the next value. +} + +func NewDecoder(r io.Reader) (d *Decoder) { + d = &Decoder{ + r: shared.NewReader(r), + stack: make([]decoderStep, 0, 10), + } + d.step = d.step_acceptValue + return +} + +func (d *Decoder) Reset() { + d.stack = d.stack[0:0] + d.step = d.step_acceptValue + d.some = false +} + +type decoderStep func(tokenSlot *Token) (done bool, err error) + +func (d *Decoder) Step(tokenSlot *Token) (done bool, err error) { + done, err = d.step(tokenSlot) + // If the step errored: out, entirely. + if err != nil { + return true, err + } + // If the step wasn't done, return same status. + if !done { + return false, nil + } + // If it WAS done, and stack empty, we're entirely done. + nSteps := len(d.stack) - 1 + if nSteps <= 0 { + return true, nil // that's all folks + } + // Pop the stack. Reset "some" to true. + d.step = d.stack[nSteps] + d.stack = d.stack[0:nSteps] + d.some = true + return false, nil +} + +func (d *Decoder) pushPhase(newPhase decoderStep) { + d.stack = append(d.stack, d.step) + d.step = newPhase + d.some = false +} + +func readn1skippingWhitespace(r shared.SlickReader) (majorByte byte, err error) { + for { + majorByte, err = r.Readn1() + switch majorByte { + case ' ', '\t', '\r', '\n': // continue + default: + return + } + } +} + +// The original step, where any value is accepted, and no terminators for composites are valid. +// ONLY used in the original step; all other steps handle leaf nodes internally. +func (d *Decoder) step_acceptValue(tokenSlot *Token) (done bool, err error) { + majorByte, err := readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + return d.stepHelper_acceptValue(majorByte, tokenSlot) +} + +// Step in midst of decoding an array. +func (d *Decoder) step_acceptArrValueOrBreak(tokenSlot *Token) (done bool, err error) { + majorByte, err := readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + if d.some { + switch majorByte { + case ']': + tokenSlot.Type = TArrClose + return true, nil + case ',': + majorByte, err = readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + // and now fall through to the next switch + } + } + switch majorByte { + case ']': + tokenSlot.Type = TArrClose + return true, nil + default: + _, err := d.stepHelper_acceptValue(majorByte, tokenSlot) + d.some = true + return false, err + } +} + +// Step in midst of decoding a map, key expected up next, or end. +func (d *Decoder) step_acceptMapKeyOrBreak(tokenSlot *Token) (done bool, err error) { + majorByte, err := readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + if d.some { + switch majorByte { + case '}': + tokenSlot.Type = TMapClose + return true, nil + case ',': + majorByte, err = readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + // and now fall through to the next switch + } + } + switch majorByte { + case '}': + tokenSlot.Type = TMapClose + return true, nil + default: + // Consume a string for key. + _, err := d.stepHelper_acceptValue(majorByte, tokenSlot) // FIXME surely not *any* value? not composites, at least? + // Now scan up to consume the colon as well, which is required next. + majorByte, err = readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + if majorByte != ':' { + return true, fmt.Errorf("expected colon after map key; got 0x%x", majorByte) + } + // Next up: expect a value. + d.step = d.step_acceptMapValue + d.some = true + return false, err + } +} + +// Step in midst of decoding a map, value expected up next. +func (d *Decoder) step_acceptMapValue(tokenSlot *Token) (done bool, err error) { + majorByte, err := readn1skippingWhitespace(d.r) + if err != nil { + return true, err + } + d.step = d.step_acceptMapKeyOrBreak + _, err = d.stepHelper_acceptValue(majorByte, tokenSlot) + return false, err +} + +func (d *Decoder) stepHelper_acceptValue(majorByte byte, tokenSlot *Token) (done bool, err error) { + switch majorByte { + case '{': + tokenSlot.Type = TMapOpen + tokenSlot.Length = -1 + d.pushPhase(d.step_acceptMapKeyOrBreak) + return false, nil + case '[': + tokenSlot.Type = TArrOpen + tokenSlot.Length = -1 + d.pushPhase(d.step_acceptArrValueOrBreak) + return false, nil + case 'n': + d.r.Readnzc(3) // FIXME must check these equal "ull"! + tokenSlot.Type = TNull + return true, nil + case '"': + tokenSlot.Type = TString + tokenSlot.Str, err = d.decodeString() + return true, err + case 'f': + d.r.Readnzc(4) // FIXME must check these equal "alse"! + tokenSlot.Type = TBool + tokenSlot.Bool = false + return true, nil + case 't': + d.r.Readnzc(3) // FIXME must check these equal "rue"! + tokenSlot.Type = TBool + tokenSlot.Bool = true + return true, nil + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + // Some kind of numeric... but in json, we *can't tell* if it's float or int. + // JSON in general doesn't differentiate. But we usually try to anyway. + // (If this results in us yielding an int, and an obj.Unmarshaller is filling a float, + // it's the Unmarshaller responsibility to decide to cast that.) + tokenSlot.Type, tokenSlot.Int, tokenSlot.Float64, err = d.decodeNumber(majorByte) + return true, err + default: + return true, fmt.Errorf("Invalid byte while expecting start of value: 0x%x", majorByte) + } +} diff --git a/vendor/github.com/polydawn/refmt/json/jsonDecoderTerminals.go b/vendor/github.com/polydawn/refmt/json/jsonDecoderTerminals.go new file mode 100644 index 00000000..b2054535 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonDecoderTerminals.go @@ -0,0 +1,368 @@ +package json + +// License note: the string and numeric parsers here borrow +// heavily from the golang stdlib json parser scanner. +// That code is originally Copyright 2010 The Go Authors, +// and is governed by a BSD-style license. + +import ( + "fmt" + "io" + "strconv" + "unicode" + "unicode/utf16" + "unicode/utf8" + + "github.com/polydawn/refmt/tok" +) + +func (d *Decoder) decodeString() (string, error) { + // First quote has already been eaten. + // Start tracking the byte slice; real string starts here. + d.r.Track() + // Scan until scanner tells us end of string. + for step := strscan_normal; step != nil; { + majorByte, err := d.r.Readn1() + if err != nil { + return "", err + } + step, err = step(majorByte) + if err != nil { + return "", err + } + } + // Unread one. The scan loop consumed the trailing quote already, + // which we don't want to pass onto the parser. + d.r.Unreadn1() + // Parse! + s, ok := parseString(d.r.StopTrack()) + if !ok { + //return string(s), fmt.Errorf("string parse misc fail") + } + // Swallow the trailing quote again. + d.r.Readn1() + return string(s), nil +} + +// Scan steps are looped over the stream to find how long the string is. +// A nil step func is returned to indicate the string is done. +// Actually parsing the string is done by 'parseString()'. +type strscanStep func(c byte) (strscanStep, error) + +// The default string scanning step state. Starts here. +func strscan_normal(c byte) (strscanStep, error) { + if c == '"' { // done! + return nil, nil + } + if c == '\\' { + return strscan_esc, nil + } + if c < 0x20 { // Unprintable bytes are invalid in a json string. + return nil, fmt.Errorf("invalid unprintable byte in string literal: 0x%x", c) + } + return strscan_normal, nil +} + +// "esc" is the state after reading `"\` during a quoted string. +func strscan_esc(c byte) (strscanStep, error) { + switch c { + case 'b', 'f', 'n', 'r', 't', '\\', '/', '"': + return strscan_normal, nil + case 'u': + return strscan_escU, nil + } + return nil, fmt.Errorf("invalid byte in string escape sequence: 0x%x", c) +} + +// "escU" is the state after reading `"\u` during a quoted string. +func strscan_escU(c byte) (strscanStep, error) { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + return strscan_escU1, nil + } + return nil, fmt.Errorf("invalid byte in \\u hexadecimal character escape: 0x%x", c) +} + +// "escU1" is the state after reading `"\u1` during a quoted string. +func strscan_escU1(c byte) (strscanStep, error) { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + return strscan_escU12, nil + } + return nil, fmt.Errorf("invalid byte in \\u hexadecimal character escape: 0x%x", c) +} + +// "escU12" is the state after reading `"\u12` during a quoted string. +func strscan_escU12(c byte) (strscanStep, error) { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + return strscan_escU123, nil + } + return nil, fmt.Errorf("invalid byte in \\u hexadecimal character escape: 0x%x", c) +} + +// "escU123" is the state after reading `"\u123` during a quoted string. +func strscan_escU123(c byte) (strscanStep, error) { + if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { + return strscan_normal, nil + } + return nil, fmt.Errorf("invalid byte in \\u hexadecimal character escape: 0x%x", c) +} + +// Convert a json string byte sequence that is a complete string (quotes from +// the outside dropped) bytes ready to be flipped into a go string. +func parseString(s []byte) (t []byte, ok bool) { + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + r, err := strconv.ParseUint(string(s[2:6]), 16, 64) + if err != nil { + return -1 + } + return rune(r) +} + +// Returns *either* an int or a float -- json is ambigous. +// An int is preferred if possible. +func (d *Decoder) decodeNumber(majorByte byte) (tok.TokenType, int64, float64, error) { + // First byte has already been eaten. + // Easiest to unread1, so we can use track, then swallow it again. + d.r.Unreadn1() + d.r.Track() + d.r.Readn1() + // Scan until scanner tells us end of numeric. + // Pick the first scanner stepfunc based on the leading byte. + var step numscanStep + switch majorByte { + case '-': + step = numscan_neg + case '0': + step = numscan_0 + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + step = numscan_1 + default: + panic("unreachable") + } + for { + b, err := d.r.Readn1() + if err == io.EOF { + break + } + if err != nil { + return 0, 0, 0, err + } + step, err = step(b) + if step == nil { + // Unread one. The scan loop consumed one char beyond the end + // (this is necessary in json!), + // which the next part of the decoder will need elsewhere. + d.r.Unreadn1() + break + } + if err != nil { + return 0, 0, 0, err + } + } + // Parse! + // *This is not a fast parse*. + // Try int first; if it fails try float; if that fails return the float error. + s := string(d.r.StopTrack()) + if i, err := strconv.ParseInt(s, 10, 64); err == nil { + return tok.TInt, i, 0, nil + } + f, err := strconv.ParseFloat(s, 64) + return tok.TFloat64, 0, f, err +} + +// Scan steps are looped over the stream to find how long the number is. +// A nil step func is returned to indicate the string is done. +// Actually parsing the string is done by 'parseString()'. +type numscanStep func(c byte) (numscanStep, error) + +// numscan_neg is the state after reading `-` during a number. +func numscan_neg(c byte) (numscanStep, error) { + if c == '0' { + return numscan_0, nil + } + if '1' <= c && c <= '9' { + return numscan_1, nil + } + return nil, fmt.Errorf("invalid byte in numeric literal: 0x%x", c) +} + +// numscan_1 is the state after reading a non-zero integer during a number, +// such as after reading `1` or `100` but not `0`. +func numscan_1(c byte) (numscanStep, error) { + if '0' <= c && c <= '9' { + return numscan_1, nil + } + return numscan_0(c) +} + +// numscan_0 is the state after reading `0` during a number. +func numscan_0(c byte) (numscanStep, error) { + if c == '.' { + return numscan_dot, nil + } + if c == 'e' || c == 'E' { + return numscan_e, nil + } + return nil, nil +} + +// numscan_dot is the state after reading the integer and decimal point in a number, +// such as after reading `1.`. +func numscan_dot(c byte) (numscanStep, error) { + if '0' <= c && c <= '9' { + return numscan_dot0, nil + } + return nil, fmt.Errorf("invalid byte after decimal in numeric literal: 0x%x", c) +} + +// numscan_dot0 is the state after reading the integer, decimal point, and subsequent +// digits of a number, such as after reading `3.14`. +func numscan_dot0(c byte) (numscanStep, error) { + if '0' <= c && c <= '9' { + return numscan_dot0, nil + } + if c == 'e' || c == 'E' { + return numscan_e, nil + } + return nil, nil +} + +// numscan_e is the state after reading the mantissa and e in a number, +// such as after reading `314e` or `0.314e`. +func numscan_e(c byte) (numscanStep, error) { + if c == '+' || c == '-' { + return numscan_eSign, nil + } + return numscan_eSign(c) +} + +// numscan_eSign is the state after reading the mantissa, e, and sign in a number, +// such as after reading `314e-` or `0.314e+`. +func numscan_eSign(c byte) (numscanStep, error) { + if '0' <= c && c <= '9' { + return numscan_e0, nil + } + return nil, fmt.Errorf("invalid byte in exponent of numeric literal: 0x%x", c) +} + +// numscan_e0 is the state after reading the mantissa, e, optional sign, +// and at least one digit of the exponent in a number, +// such as after reading `314e-2` or `0.314e+1` or `3.14e0`. +func numscan_e0(c byte) (numscanStep, error) { + if '0' <= c && c <= '9' { + return numscan_e0, nil + } + return nil, nil +} diff --git a/vendor/github.com/polydawn/refmt/json/jsonEncoder.go b/vendor/github.com/polydawn/refmt/json/jsonEncoder.go new file mode 100644 index 00000000..8783b381 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonEncoder.go @@ -0,0 +1,218 @@ +package json + +import ( + "fmt" + "io" + "strconv" + + . "github.com/polydawn/refmt/tok" +) + +func NewEncoder(wr io.Writer, cfg EncodeOptions) *Encoder { + return &Encoder{ + wr: wr, + cfg: cfg, + stack: make([]phase, 0, 10), + } +} + +func (d *Encoder) Reset() { + d.stack = d.stack[0:0] + d.current = phase_anyExpectValue + d.some = false +} + +/* + A json.Encoder is a TokenSink implementation that emits json bytes. +*/ +type Encoder struct { + wr io.Writer + cfg EncodeOptions + + // Stack, tracking how many array and map opens are outstanding. + // (Values are only 'phase_mapExpectKeyOrEnd' and 'phase_arrExpectValueOrEnd'.) + stack []phase + current phase // shortcut to value at end of stack + some bool // set to true after first value in any context; use to append commas. + + // Spare memory, for use in operations on leaf nodes (e.g. temp space for an int serialization). + scratch [64]byte +} + +type phase int + +const ( + phase_anyExpectValue phase = iota + phase_mapExpectKeyOrEnd + phase_mapExpectValue + phase_arrExpectValueOrEnd +) + +func (d *Encoder) Step(tok *Token) (done bool, err error) { + switch d.current { + case phase_anyExpectValue: + switch tok.Type { + case TMapOpen: + d.pushPhase(phase_mapExpectKeyOrEnd) + d.wr.Write(wordMapOpen) + return false, nil + case TArrOpen: + d.pushPhase(phase_arrExpectValueOrEnd) + d.wr.Write(wordArrOpen) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value") + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of value") + default: + // It's a value; handle it. + d.flushValue(tok) + return true, nil + } + case phase_mapExpectKeyOrEnd: + switch tok.Type { + case TMapOpen: + return true, fmt.Errorf("unexpected mapOpen; expected start of key or end of map") + case TArrOpen: + return true, fmt.Errorf("unexpected arrOpen; expected start of key or end of map") + case TMapClose: + if d.some { + d.wr.Write(d.cfg.Line) + for i := 1; i < len(d.stack); i++ { + d.wr.Write(d.cfg.Indent) + } + } + d.wr.Write(wordMapClose) + return d.popPhase() + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of key or end of map") + default: + // It's a key. It'd better be a string. + switch tok.Type { + case TString: + d.entrySep() + d.emitString(tok.Str) + d.wr.Write(wordColon) + if d.cfg.Line != nil { + d.wr.Write(wordSpace) + } + d.current = phase_mapExpectValue + return false, nil + default: + return true, fmt.Errorf("unexpected token of type %T; expected map key", *tok) + } + } + case phase_mapExpectValue: + switch tok.Type { + case TMapOpen: + d.pushPhase(phase_mapExpectKeyOrEnd) + d.wr.Write(wordMapOpen) + return false, nil + case TArrOpen: + d.pushPhase(phase_arrExpectValueOrEnd) + d.wr.Write(wordArrOpen) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value") + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of value") + default: + // It's a value; handle it. + d.flushValue(tok) + d.current = phase_mapExpectKeyOrEnd + return false, nil + } + case phase_arrExpectValueOrEnd: + switch tok.Type { + case TMapOpen: + d.entrySep() + d.pushPhase(phase_mapExpectKeyOrEnd) + d.wr.Write(wordMapOpen) + return false, nil + case TArrOpen: + d.entrySep() + d.pushPhase(phase_arrExpectValueOrEnd) + d.wr.Write(wordArrOpen) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value or end of array") + case TArrClose: + if d.some { + d.wr.Write(d.cfg.Line) + for i := 1; i < len(d.stack); i++ { + d.wr.Write(d.cfg.Indent) + } + } + d.wr.Write(wordArrClose) + return d.popPhase() + default: + // It's a value; handle it. + d.entrySep() + d.flushValue(tok) + return false, nil + } + default: + panic("Unreachable") + } +} + +func (d *Encoder) pushPhase(p phase) { + d.current = p + d.stack = append(d.stack, d.current) + d.some = false +} + +// Pop a phase from the stack; return 'true' if stack now empty. +func (d *Encoder) popPhase() (bool, error) { + n := len(d.stack) - 1 + if n == 0 { + d.wr.Write(d.cfg.Line) + return true, nil + } + if n < 0 { // the state machines are supposed to have already errored better + panic("jsonEncoder stack overpopped") + } + d.current = d.stack[n-1] + d.stack = d.stack[0:n] + d.some = true + return false, nil +} + +// Emit an entry separater (comma), unless we're at the start of an object. +// Mark that we *do* have some content, regardless, so next time will need a sep. +func (d *Encoder) entrySep() { + if d.some { + d.wr.Write(wordComma) + } + d.some = true + d.wr.Write(d.cfg.Line) + for i := 0; i < len(d.stack); i++ { + d.wr.Write(d.cfg.Indent) + } +} + +func (d *Encoder) flushValue(tok *Token) { + switch tok.Type { + case TString: + d.emitString(tok.Str) + case TBool: + switch tok.Bool { + case true: + d.wr.Write(wordTrue) + case false: + d.wr.Write(wordFalse) + } + case TInt: + b := strconv.AppendInt(d.scratch[:0], tok.Int, 10) + d.wr.Write(b) + case TNull: + d.wr.Write(wordNull) + default: + panic(fmt.Errorf("TODO finish more jsonEncoder primitives support: unhandled token %s", tok)) + } +} + +func (d *Encoder) writeByte(b byte) { + d.scratch[0] = b + d.wr.Write(d.scratch[0:1]) +} diff --git a/vendor/github.com/polydawn/refmt/json/jsonEncoderTerminals.go b/vendor/github.com/polydawn/refmt/json/jsonEncoderTerminals.go new file mode 100644 index 00000000..2892875f --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonEncoderTerminals.go @@ -0,0 +1,78 @@ +package json + +import ( + "io" + "unicode/utf8" +) + +var hex = "0123456789abcdef" + +func (d *Encoder) emitString(s string) { + d.writeByte('"') + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if 0x20 <= b && b != '\\' && b != '"' { + i++ + continue + } + if start < i { + d.wr.Write([]byte(s[start:i])) + } + switch b { + case '\\', '"': + d.writeByte('\\') + d.writeByte(b) + case '\n': + d.writeByte('\\') + d.writeByte('n') + case '\r': + d.writeByte('\\') + d.writeByte('r') + case '\t': + d.writeByte('\\') + d.writeByte('t') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + d.wr.Write([]byte(`\u00`)) + d.writeByte(hex[b>>4]) + d.writeByte(hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + d.wr.Write([]byte(s[start:i])) + } + d.wr.Write([]byte(`\ufffd`)) + i += size + start = i + continue + } + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + if c == '\u2028' || c == '\u2029' { + if start < i { + d.wr.Write([]byte(s[start:i])) + } + d.wr.Write([]byte(`\u202`)) + d.writeByte(hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + io.WriteString(d.wr, s[start:]) + } + d.writeByte('"') +} diff --git a/vendor/github.com/polydawn/refmt/json/jsonHelpers.go b/vendor/github.com/polydawn/refmt/json/jsonHelpers.go new file mode 100644 index 00000000..205dbe24 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonHelpers.go @@ -0,0 +1,106 @@ +package json + +import ( + "bytes" + "io" + + "github.com/polydawn/refmt/obj" + "github.com/polydawn/refmt/obj/atlas" + "github.com/polydawn/refmt/shared" +) + +// All of the methods in this file are exported, +// and their names and type declarations are intended to be +// identical to the naming and types of the golang stdlib +// 'encoding/json' packages, with ONE EXCEPTION: +// what stdlib calls "NewEncoder", we call "NewMarshaller"; +// what stdlib calls "NewDecoder", we call "NewUnmarshaller"; +// and similarly the types and methods are "Marshaller.Marshal" +// and "Unmarshaller.Unmarshal". +// You should be able to migrate with a sed script! +// +// (In refmt, the encoder/decoder systems are for token streams; +// if you're talking about object mapping, we consistently +// refer to that as marshalling/unmarshalling.) +// +// Most methods also have an "Atlased" variant, +// which lets you specify advanced type mapping instructions. + +func Marshal(v interface{}) ([]byte, error) { + var buf bytes.Buffer + if err := NewMarshaller(&buf).Marshal(v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func MarshalAtlased(cfg EncodeOptions, v interface{}, atl atlas.Atlas) ([]byte, error) { + var buf bytes.Buffer + if err := NewMarshallerAtlased(&buf, cfg, atl).Marshal(v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +type Marshaller struct { + marshaller *obj.Marshaller + encoder *Encoder + pump shared.TokenPump +} + +func (x *Marshaller) Marshal(v interface{}) error { + x.marshaller.Bind(v) + x.encoder.Reset() + return x.pump.Run() +} + +func NewMarshaller(wr io.Writer) *Marshaller { + return NewMarshallerAtlased(wr, EncodeOptions{}, atlas.MustBuild()) +} + +func NewMarshallerAtlased(wr io.Writer, cfg EncodeOptions, atl atlas.Atlas) *Marshaller { + x := &Marshaller{ + marshaller: obj.NewMarshaller(atl), + encoder: NewEncoder(wr, cfg), + } + x.pump = shared.TokenPump{ + x.marshaller, + x.encoder, + } + return x +} + +func Unmarshal(data []byte, v interface{}) error { + return NewUnmarshaller(bytes.NewBuffer(data)).Unmarshal(v) +} + +func UnmarshalAtlased(data []byte, v interface{}, atl atlas.Atlas) error { + return NewUnmarshallerAtlased(bytes.NewBuffer(data), atl).Unmarshal(v) +} + +type Unmarshaller struct { + unmarshaller *obj.Unmarshaller + decoder *Decoder + pump shared.TokenPump +} + +func (x *Unmarshaller) Unmarshal(v interface{}) error { + x.unmarshaller.Bind(v) + x.decoder.Reset() + return x.pump.Run() +} + +func NewUnmarshaller(r io.Reader) *Unmarshaller { + return NewUnmarshallerAtlased(r, atlas.MustBuild()) +} +func NewUnmarshallerAtlased(r io.Reader, atl atlas.Atlas) *Unmarshaller { + x := &Unmarshaller{ + unmarshaller: obj.NewUnmarshaller(atl), + decoder: NewDecoder(r), + } + x.pump = shared.TokenPump{ + x.decoder, + x.unmarshaller, + } + return x +} diff --git a/vendor/github.com/polydawn/refmt/json/jsonOptions.go b/vendor/github.com/polydawn/refmt/json/jsonOptions.go new file mode 100644 index 00000000..6a9b69c3 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/json/jsonOptions.go @@ -0,0 +1,23 @@ +package json + +type EncodeOptions struct { + // If set, this will be prefixed to every "line" to pretty-print. + // (Typically you want to just set this to `[]byte{'\n'}`!) + Line []byte + + // If set, this will be prefixed $N$ times before each line's content to pretty-print. + // (Likely values are a tab, or a few spaces.) + Indent []byte +} + +// marker method -- you may use this type to instruct `refmt.Marshal` +// what kind of encoder to use. +func (EncodeOptions) IsEncodeOptions() {} + +type DecodeOptions struct { + // future: options to validate canonical serial order +} + +// marker method -- you may use this type to instruct `refmt.Marshal` +// what kind of encoder to use. +func (DecodeOptions) IsDecodeOptions() {} diff --git a/vendor/github.com/polydawn/refmt/marshalHelpers.go b/vendor/github.com/polydawn/refmt/marshalHelpers.go new file mode 100644 index 00000000..dcd4df06 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/marshalHelpers.go @@ -0,0 +1,61 @@ +package refmt + +import ( + "io" + + "github.com/polydawn/refmt/cbor" + "github.com/polydawn/refmt/json" + "github.com/polydawn/refmt/obj/atlas" +) + +type EncodeOptions interface { + IsEncodeOptions() // marker method. +} + +func Marshal(opts EncodeOptions, v interface{}) ([]byte, error) { + switch o2 := opts.(type) { + case json.EncodeOptions: + return json.MarshalAtlased(o2, v, atlas.MustBuild()) + case cbor.EncodeOptions: + return cbor.MarshalAtlased(v, atlas.MustBuild()) + default: + panic("incorrect usage: unknown EncodeOptions type") + } +} + +func MarshalAtlased(opts EncodeOptions, v interface{}, atl atlas.Atlas) ([]byte, error) { + switch o2 := opts.(type) { + case json.EncodeOptions: + return json.MarshalAtlased(o2, v, atl) + case cbor.EncodeOptions: + return cbor.MarshalAtlased(v, atl) + default: + panic("incorrect usage: unknown EncodeOptions type") + } +} + +type Marshaller interface { + Marshal(v interface{}) error +} + +func NewMarshaller(opts EncodeOptions, wr io.Writer) Marshaller { + switch o2 := opts.(type) { + case json.EncodeOptions: + return json.NewMarshallerAtlased(wr, o2, atlas.MustBuild()) + case cbor.EncodeOptions: + return cbor.NewMarshaller(wr) + default: + panic("incorrect usage: unknown EncodeOptions type") + } +} + +func NewMarshallerAtlased(opts EncodeOptions, wr io.Writer, atl atlas.Atlas) Marshaller { + switch o2 := opts.(type) { + case json.EncodeOptions: + return json.NewMarshallerAtlased(wr, o2, atl) + case cbor.EncodeOptions: + return cbor.NewMarshallerAtlased(wr, atl) + default: + panic("incorrect usage: unknown EncodeOptions type") + } +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/atlas.go b/vendor/github.com/polydawn/refmt/obj/atlas/atlas.go new file mode 100644 index 00000000..f96b4cb1 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/atlas.go @@ -0,0 +1,79 @@ +package atlas + +import ( + "fmt" + "reflect" +) + +type Atlas struct { + // Map typeinfo to a static description of how that type should be handled. + // (The internal machinery that will wield this information, and has memory of + // progress as it does so, is configured using the AtlasEntry, but allocated separately. + // The machinery is stateful and mutable; the AtlasEntry is not.) + // + // We use 'var rtid uintptr = reflect.ValueOf(rt).Pointer()' -- pointer of the + // value of the reflect.Type info -- as an index. + // This is both unique and correctly converges when recomputed, and much + // faster to compare against than reflect.Type (which is an interface that + // tends to contain fairly large structures). + mappings map[uintptr]*AtlasEntry + + // Mapping of tag ints to atlasEntry for quick lookups when the + // unmarshaller hits a tag. Values are a subset of `mappings`. + tagMappings map[int]*AtlasEntry + + // MapMorphism specifies the default map sorting scheme + defaultMapMorphism *MapMorphism +} + +func Build(entries ...*AtlasEntry) (Atlas, error) { + atl := Atlas{ + mappings: make(map[uintptr]*AtlasEntry), + tagMappings: make(map[int]*AtlasEntry), + defaultMapMorphism: &MapMorphism{KeySortMode_Default}, + } + for _, entry := range entries { + rtid := reflect.ValueOf(entry.Type).Pointer() + if _, exists := atl.mappings[rtid]; exists { + return Atlas{}, fmt.Errorf("repeated entry for type %v", entry.Type) + } + atl.mappings[rtid] = entry + + if entry.Tagged == true { + if prev, exists := atl.tagMappings[entry.Tag]; exists { + return Atlas{}, fmt.Errorf("repeated tag %v on type %v (already mapped to type %v)", entry.Tag, entry.Type, prev.Type) + } + atl.tagMappings[entry.Tag] = entry + } + } + return atl, nil +} +func MustBuild(entries ...*AtlasEntry) Atlas { + atl, err := Build(entries...) + if err != nil { + panic(err) + } + return atl +} + +func (atl Atlas) WithMapMorphism(m MapMorphism) Atlas { + atl.defaultMapMorphism = &m + return atl +} + +// Gets the AtlasEntry for a typeID. Used by obj package, not meant for user facing. +func (atl Atlas) Get(rtid uintptr) (*AtlasEntry, bool) { + ent, ok := atl.mappings[rtid] + return ent, ok +} + +// Gets the AtlasEntry for a tag int. Used by obj package, not meant for user facing. +func (atl Atlas) GetEntryByTag(tag int) (*AtlasEntry, bool) { + ent, ok := atl.tagMappings[tag] + return ent, ok +} + +// Gets the default map morphism config. Used by obj package, not meant for user facing. +func (atl Atlas) GetDefaultMapMorphism() *MapMorphism { + return atl.defaultMapMorphism +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/atlasCommon.go b/vendor/github.com/polydawn/refmt/obj/atlas/atlasCommon.go new file mode 100644 index 00000000..611481b2 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/atlasCommon.go @@ -0,0 +1,10 @@ +package atlas + +// A type to enumerate key sorting modes. +type KeySortMode string + +const ( + KeySortMode_Default = KeySortMode("default") // the default mode -- for structs, this is the source-order of the fields; for maps, it's identify to "strings" sort mode. + KeySortMode_Strings = KeySortMode("strings") // lexical sort by strings. this *is* the default for maps; it overrides source-order sorting for structs. + KeySortMode_RFC7049 = KeySortMode("rfc7049") // "Canonical" as proposed by rfc7049 § 3.9 (shorter byte sequences sort to top). +) diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/atlasEntry.go b/vendor/github.com/polydawn/refmt/obj/atlas/atlasEntry.go new file mode 100644 index 00000000..4c3ee457 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/atlasEntry.go @@ -0,0 +1,150 @@ +package atlas + +import ( + "reflect" +) + +/* + The AtlasEntry is a declarative roadmap of what we should do for + marshal and unmarshal of a single object, keyed by type. + + There are a lot of paths your mappings might want to take: + + - For a struct type, you may simply want to specify some alternate keys, or some to leave out, etc. + - For an interface type, you probably want to specify one of our interface muxing strategies + with a mapping between enumstr:typeinfo (and, what to do if we get a struct we don't recognize). + - For a string, int, or other primitive, you don't need to say anything: defaults will DTRT. + - For a typedef'd string, int, or other primitive, you *still* don't need to say anything: but, + if you want custom behavior (say, transform the string to an int at the last second, and back again), + you can specify transformer functions for that. + - For a struct type that you want to turn into a whole different kind (like a string): use + those same transform functions. (You'll no longer need a FieldMap.) + - For the most esoteric needs, you can fall all the way back to providing a custom MarshalMachine + (but avoid that; it's a lot of work, and one of these other transform methods should suffice). +*/ +type AtlasEntry struct { + // The reflect info of the type this morphism is regarding. + Type reflect.Type + + // -------------------------------------------------------- + // The big escape valves: wanna map to some other kind completely? + // -------------------------------------------------------- + + // Transforms the value we reached by walking (the 'live' value -- which + // must be of `this.Type`) into another value (the 'serialable' value -- + // which will be of `this.MarshalTransformTargetType`). + // + // The target type may be anything, even of a completely different Kind! + // + // This transform func runs first, then the resulting value is + // serialized (by running through the path through Atlas again, so + // chaining of transform funcs is supported, though not recommended). + MarshalTransformFunc MarshalTransformFunc + // The type of value we expect after using the MarshalTransformFunc. + // + // The match between transform func and target type should be checked + // during construction of this AtlasEntry. + MarshalTransformTargetType reflect.Type + + // Expects a different type (the 'serialable' value -- which will be of + // 'this.UnmarshalTransformTargetType') than the value we reached by + // walking (the 'live' value -- which must be of `this.Type`). + // + // The target type may be anything, even of a completely different Kind! + // + // The unmarshal of that target type will be run first, then the + // resulting value is fed through this function to produce the real value, + // which is then placed correctly into bigger mid-unmarshal object tree. + // + // For non-primitives, unmarshal of the target type will always target + // an empty pointer or empty slice, roughly as per if it was + // operating on a value produced by `TargetType.New()`. + UnmarshalTransformFunc UnmarshalTransformFunc + // The type of value we will manufacture an instance of and unmarshal + // into, then when done provide to the UnmarshalTransformFunc. + // + // The match between transform func and target type should be checked + // during construction of this AtlasEntry. + UnmarshalTransformTargetType reflect.Type + + // -------------------------------------------------------- + // Standard options for how to map (varies by Kind) + // -------------------------------------------------------- + + // A "tag" to emit when marshalling this type of value; + // and when unmarshalling, this tag will cause unmarshal to pick + // this atlas (and if there's conflicting type info, error). + Tag int + // Flag for whether the Tag feature should be used (zero is a valid tag). + Tagged bool + + // A mapping of fields in a struct to serial keys. + // Only valid if `this.Type.Kind() == Struct`. + StructMap *StructMap + + // Configuration for how to traverse a map kind. + // Only valid if `this.Type.Kind() == Map`. + MapMorphism *MapMorphism + + // Configuration for how to pick concrete types to fill a union interface. + // Only valid if `this.Type.Kind() == Interface`. + UnionKeyedMorphism *UnionKeyedMorphism + + // FUTURE: enum-ish primitives, multiplexers for interfaces, + // lots of such things will belong here. + + // -------------------------------------------------------- + // Hooks, validate helpers + // -------------------------------------------------------- + + // A validation function which will be called for the whole value + // after unmarshalling reached the end of the object. + // If it returns an error, the entire unmarshal will error. + // + // Not used in marshalling. + // Not reachable if an UnmarshalTransform is set. + ValidateFn func(v interface{}) error +} + +func BuildEntry(typeHintObj interface{}) *BuilderCore { + rt := reflect.TypeOf(typeHintObj) + if rt.Kind() == reflect.Ptr { + if rt.Elem().Kind() == reflect.Interface { + rt = rt.Elem() + } else { + panic("invalid atlas build: use the bare object, not a pointer (refmt will handle pointers automatically)") + } + } + return &BuilderCore{ + &AtlasEntry{Type: rt}, + } +} + +/* + Intermediate step in building an AtlasEntry: use `BuildEntry` to + get one of these to start with, then call one of the methods + on this type to get a specialized builder which has the methods + relevant for setting up that specific kind of mapping. + + One full example of using this builder may look like the following: + + atlas.BuildEntry(Formula{}).StructMap().Autogenerate().Complete() + + Some intermediate manipulations may be performed on this object, + for example setting the "tag" (if you want to use cbor tagging), + before calling the specializer method. + In this case, just keep chaining the configuration calls like so: + + atlas.BuildEntry(Formula{}).UseTag(4000) + .StructMap().Autogenerate().Complete() + +*/ +type BuilderCore struct { + entry *AtlasEntry +} + +func (x *BuilderCore) UseTag(tag int) *BuilderCore { + x.entry.Tagged = true + x.entry.Tag = tag + return x +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/doc.go b/vendor/github.com/polydawn/refmt/obj/atlas/doc.go new file mode 100644 index 00000000..52e6ddb2 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/doc.go @@ -0,0 +1,45 @@ +/* + Atlas types are used to define how to map Go values into refmt token streams. + + Atlas information may be autogenerated based on struct tags automatically, + but you can also specify custom AtlasEntry info to use advanced features + and define custom transformations. + + An Atlas is a collection of AtlasEntry (plus some internal indexing). + Typical usage is to declare an AtlasEntry for your structs (often near by the + struct definition), then + + Building an AtlasEntry for some type called `Formula` looks like this: + + atlas.BuildEntry(Formula{}).StructMap().Autogenerate().Complete() + + Building an AtlasEntry always starts with `atlas.BuildEntry(x)` where `x` is + a dummy object used to convey type information. + The next function in the chain declares what kind of behavior we're going + to use to turn that type of object into its serial form. + (In the above example, we're declaring that we want refmt to see the `Formula` + type as a struct and traverse its fields. There are many other options!) + Subsequent functions are specific to what kind of walking and mapping we've + chosen. For struct walking, this may involve declaring fields and custom serial + names to map them to; for a "Transform" we'd instead have to provide callbacks + to do the transformation from the `Formula` type to some other type; etcetera. + The final function in the chain is always called `Complete`, and returns + a ready-to-use AtlasEntry. + + Building a complete Atlas for a whole suite of serializable types is as + easy as putting a bunch of them together: + + atlas.Build( + atlas.BuildEntry(Foo{}).StructMap().Autogenerate().Complete(), + atlas.BuildEntry(Bar{}).StructMap().Autogenerate().Complete(), + atlas.BuildEntry(Baz{}).StructMap().Autogenerate().Complete(), + ) + + You can put your entire protocol into one Atlas. + It's also possible to build several different Atlases each with different + sets of AtlasEntry. This may be useful if you have a protocol where some + messages are not valid during some phases of communication, and you would + like to use the Atlas as a form of whitelisting for what can be + marshalled/unmarshalled. +*/ +package atlas diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/errors.go b/vendor/github.com/polydawn/refmt/obj/atlas/errors.go new file mode 100644 index 00000000..48fe37f7 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/errors.go @@ -0,0 +1,14 @@ +package atlas + +// Error type raised when initializing an Atlas, and field entries do +// not resolve against the type. +// (If you recently refactored names of fields in your types, check +// to make sure you updated any references to those fields by name to match!) +type ErrStructureMismatch struct { + TypeName string + Reason string +} + +func (e ErrStructureMismatch) Error() string { + return "structure mismatch: " + e.TypeName + " " + e.Reason +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/mapMorphism.go b/vendor/github.com/polydawn/refmt/obj/atlas/mapMorphism.go new file mode 100644 index 00000000..b5602cdc --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/mapMorphism.go @@ -0,0 +1,38 @@ +package atlas + +import ( + "fmt" + "reflect" +) + +type MapMorphism struct { + KeySortMode KeySortMode +} + +func (x *BuilderCore) MapMorphism() *BuilderMapMorphism { + if x.entry.Type.Kind() != reflect.Map { + panic(fmt.Errorf("cannot use mapMorphism for type %q, which is kind %s", x.entry.Type, x.entry.Type.Kind())) + } + x.entry.MapMorphism = &MapMorphism{ + KeySortMode_Default, + } + return &BuilderMapMorphism{x.entry} +} + +type BuilderMapMorphism struct { + entry *AtlasEntry +} + +func (x *BuilderMapMorphism) Complete() *AtlasEntry { + return x.entry +} + +func (x *BuilderMapMorphism) SetKeySortMode(km KeySortMode) *BuilderMapMorphism { + switch km { + case KeySortMode_Default, KeySortMode_Strings, KeySortMode_RFC7049: + x.entry.MapMorphism.KeySortMode = km + default: + panic(fmt.Errorf("invalid key sort mode %q", km)) + } + return x +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/structMap.go b/vendor/github.com/polydawn/refmt/obj/atlas/structMap.go new file mode 100644 index 00000000..0ede93c9 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/structMap.go @@ -0,0 +1,46 @@ +package atlas + +import "reflect" + +type StructMap struct { + // A slice of descriptions of each field in the type. + // Each entry specifies the name by which each field should be referenced + // when serialized, and defines a way to get an address to the field. + Fields []StructMapEntry +} + +type StructMapEntry struct { + // The field name; will be emitted as token during marshal, and used for + // lookup during unmarshal. Required. + SerialName string + + // If true, a key token with this SerialName will be ignored during unmarshal. + // (By default, if there's no StructMapEntry for a key token, it's an error.) + // If true, the ReflectRoute, Type, etc fields are irrelevant and may be nil. + Ignore bool + + ReflectRoute ReflectRoute // reflection generates these. + Type reflect.Type // type to expect on the far side of the ReflectRoute. + tagged bool // used during autogen. + + // Theoretical feature which would be alternative to ReflectRoute. Support dropped for the moment. + //addrFunc func(interface{}) interface{} // custom user function. + + // If true, marshalling will skip this field if it's the zero value. + OmitEmpty bool +} + +type ReflectRoute []int + +func (rr ReflectRoute) TraverseToValue(v reflect.Value) reflect.Value { + for _, i := range rr { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + return reflect.Value{} + } + v = v.Elem() + } + v = v.Field(i) + } + return v +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/structMapAutogen.go b/vendor/github.com/polydawn/refmt/obj/atlas/structMapAutogen.go new file mode 100644 index 00000000..32fb57cc --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/structMapAutogen.go @@ -0,0 +1,320 @@ +package atlas + +import ( + "fmt" + "reflect" + "sort" + "strings" + "unicode" +) + +func AutogenerateStructMapEntry(rt reflect.Type) *AtlasEntry { + return AutogenerateStructMapEntryUsingTags(rt, "refmt", KeySortMode_Default) +} + +func AutogenerateStructMapEntryUsingTags(rt reflect.Type, tagName string, sorter KeySortMode) *AtlasEntry { + if rt.Kind() != reflect.Struct { + panic(fmt.Errorf("cannot use structMap for type %q, which is kind %s", rt, rt.Kind())) + } + entry := &AtlasEntry{ + Type: rt, + StructMap: &StructMap{Fields: exploreFields(rt, tagName, sorter)}, + } + return entry +} + +// exploreFields returns a list of fields that StructAtlas should recognize for the given type. +// The algorithm is breadth-first search over the set of structs to include - the top struct +// and then any reachable anonymous structs. +func exploreFields(rt reflect.Type, tagName string, sorter KeySortMode) []StructMapEntry { + // Anonymous fields to explore at the current level and the next. + current := []StructMapEntry{} + next := []StructMapEntry{{Type: rt}} + + // Count of queued names for current level and the next. + count := map[reflect.Type]int{} + nextCount := map[reflect.Type]int{} + + // Types already visited at an earlier level. + visited := map[reflect.Type]bool{} + + // Fields found. + var fields []StructMapEntry + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, map[reflect.Type]int{} + + for _, f := range current { + if visited[f.Type] { + continue + } + visited[f.Type] = true + + // Scan f.Type for fields to include. + for i := 0; i < f.Type.NumField(); i++ { + sf := f.Type.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { // unexported + continue + } + tag := sf.Tag.Get(tagName) + if tag == "-" { + continue + } + name, opts := parseTag(tag) + if !isValidTag(name) { + name = "" + } + route := make([]int, len(f.ReflectRoute)+1) + copy(route, f.ReflectRoute) + route[len(f.ReflectRoute)] = i + + ft := sf.Type + if ft.Name() == "" && ft.Kind() == reflect.Ptr { + // Follow pointer. + ft = ft.Elem() + } + + // Record found field and index sequence. + if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { + tagged := name != "" + if name == "" { + name = downcaseFirstLetter(sf.Name) + } + fields = append(fields, StructMapEntry{ + SerialName: name, + ReflectRoute: route, + Type: sf.Type, + tagged: tagged, + OmitEmpty: opts.Contains("omitempty"), + }) + if count[f.Type] > 1 { + // If there were multiple instances, add a second, + // so that the annihilation code will see a duplicate. + // It only cares about the distinction between 1 or 2, + // so don't bother generating any more copies. + fields = append(fields, fields[len(fields)-1]) + } + continue + } + + // Record new anonymous struct to explore in next round. + nextCount[ft]++ + if nextCount[ft] == 1 { + next = append(next, StructMapEntry{ + ReflectRoute: route, + Type: ft, + }) + } + } + } + } + + sort.Sort(StructMapEntry_byName(fields)) + + // Delete all fields that are hidden by the Go rules for embedded fields, + // except that fields with JSON tags are promoted. + + // The fields are sorted in primary order of name, secondary order + // of field index length. Loop over names; for each name, delete + // hidden fields by choosing the one dominant field that survives. + out := fields[:0] + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.SerialName + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.SerialName != name { + break + } + } + if advance == 1 { // Only one field with this name + out = append(out, fi) + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) + } + } + + fields = out + switch sorter { + case KeySortMode_Default: + sort.Sort(StructMapEntry_byFieldRoute(fields)) + case KeySortMode_Strings: + //sort.Sort(StructMapEntry_byName(fields)) + // it's already in this order, though, so, pass + case KeySortMode_RFC7049: + sort.Sort(StructMapEntry_RFC7049(fields)) + default: + panic("invalid struct sorter option") + } + + return fields +} + +// If the first character of the string is uppercase, return a string +// where it is switched to lowercase. +// We use this to make go field names look more like what everyone else +// in the universe expects their json to look like by default: snakeCase. +func downcaseFirstLetter(s string) string { + if s == "" { + return "" + } + r := rune(s[0]) // if multibyte chars: you're left alone. + if !unicode.IsUpper(r) { + return s + } + return string(unicode.ToLower(r)) + s[1:] +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's embedding rules, modified by the presence of +// JSON tags. If there are multiple top-level fields, the boolean +// will be false: This condition is an error in Go and we skip all +// the fields. +func dominantField(fields []StructMapEntry) (StructMapEntry, bool) { + // The fields are sorted in increasing index-length order. The winner + // must therefore be one with the shortest index length. Drop all + // longer entries, which is easy: just truncate the slice. + length := len(fields[0].ReflectRoute) + tagged := -1 // Index of first tagged field. + for i, f := range fields { + if len(f.ReflectRoute) > length { + fields = fields[:i] + break + } + if f.tagged { + if tagged >= 0 { + // Multiple tagged fields at the same level: conflict. + // Return no field. + return StructMapEntry{}, false + } + tagged = i + } + } + if tagged >= 0 { + return fields[tagged], true + } + // All remaining fields have the same length. If there's more than one, + // we have a conflict (two fields named "X" at the same level) and we + // return no field. + if len(fields) > 1 { + return StructMapEntry{}, false + } + return fields[0], true +} + +// StructMapEntry_byName sorts field by name, +// breaking ties with depth, +// then breaking ties with "name came from tag", +// then breaking ties with FieldRoute sequence. +type StructMapEntry_byName []StructMapEntry + +func (x StructMapEntry_byName) Len() int { return len(x) } +func (x StructMapEntry_byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x StructMapEntry_byName) Less(i, j int) bool { + if x[i].SerialName != x[j].SerialName { + return x[i].SerialName < x[j].SerialName + } + if len(x[i].ReflectRoute) != len(x[j].ReflectRoute) { + return len(x[i].ReflectRoute) < len(x[j].ReflectRoute) + } + if x[i].tagged != x[j].tagged { + return x[i].tagged + } + return StructMapEntry_byFieldRoute(x).Less(i, j) +} + +// StructMapEntry_RFC7049 sorts fields as specified in RFC7049, +type StructMapEntry_RFC7049 []StructMapEntry + +func (x StructMapEntry_RFC7049) Len() int { return len(x) } +func (x StructMapEntry_RFC7049) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x StructMapEntry_RFC7049) Less(i, j int) bool { + il, jl := len(x[i].SerialName), len(x[j].SerialName) + switch { + case il < jl: + return true + case il > jl: + return false + default: + return x[i].SerialName < x[j].SerialName + } +} + +// StructMapEntry_byFieldRoute sorts field by FieldRoute sequence +// (e.g., roughly source declaration order within each type). +type StructMapEntry_byFieldRoute []StructMapEntry + +func (x StructMapEntry_byFieldRoute) Len() int { return len(x) } +func (x StructMapEntry_byFieldRoute) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x StructMapEntry_byFieldRoute) Less(i, j int) bool { + for k, xik := range x[i].ReflectRoute { + if k >= len(x[j].ReflectRoute) { + return false + } + if xik != x[j].ReflectRoute[k] { + return xik < x[j].ReflectRoute[k] + } + } + return len(x[i].ReflectRoute) < len(x[j].ReflectRoute) +} + +// tagOptions is the string following a comma in a struct field's +// tag, or the empty string. It does not include the leading comma. +type tagOptions string + +// parseTag splits a struct field's tag into its name and +// comma-separated options. +func parseTag(tag string) (string, tagOptions) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tagOptions(tag[idx+1:]) + } + return tag, tagOptions("") +} + +// Contains reports whether a comma-separated list of options +// contains a particular substr flag. substr must be surrounded by a +// string boundary or commas. +func (o tagOptions) Contains(optionName string) bool { + if len(o) == 0 { + return false + } + s := string(o) + for s != "" { + var next string + i := strings.Index(s, ",") + if i >= 0 { + s, next = s[:i], s[i+1:] + } + if s == optionName { + return true + } + s = next + } + return false +} + +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + default: + if !unicode.IsLetter(c) && !unicode.IsDigit(c) { + return false + } + } + } + return true +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/structMapBuilding.go b/vendor/github.com/polydawn/refmt/obj/atlas/structMapBuilding.go new file mode 100644 index 00000000..1c9fd32e --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/structMapBuilding.go @@ -0,0 +1,96 @@ +package atlas + +import ( + "fmt" + "reflect" + "strings" +) + +func (x *BuilderCore) StructMap() *BuilderStructMap { + if x.entry.Type.Kind() != reflect.Struct { + panic(fmt.Errorf("cannot use structMap for type %q, which is kind %s", x.entry.Type, x.entry.Type.Kind())) + } + x.entry.StructMap = &StructMap{} + return &BuilderStructMap{x.entry} +} + +type BuilderStructMap struct { + entry *AtlasEntry +} + +func (x *BuilderStructMap) Complete() *AtlasEntry { + return x.entry +} + +/* + Add a field to the mapping based on its name. + + Given a struct: + + struct{ + X int + Y struct{ Z int } + } + + `AddField("X", {"x", ...}) will cause that field to be serialized as key "x"; + `AddField("Y.Z", {"z", ...})` will cause that *nested* field to be serialized + as key "z" in the same object (e.g. "x" and "z" will be siblings). + + Returns the mutated builder for convenient call chaining. + + If the fieldName string doesn't map onto the structure type info, + a panic will be raised. +*/ +func (x *BuilderStructMap) AddField(fieldName string, mapping StructMapEntry) *BuilderStructMap { + fieldNameSplit := strings.Split(fieldName, ".") + rr, rt, err := fieldNameToReflectRoute(x.entry.Type, fieldNameSplit) + if err != nil { + panic(err) // REVIEW: now that we have the builder obj, we could just curry these into it until 'Complete' is called (or, thus, 'MustComplete'!). + } + mapping.ReflectRoute = rr + mapping.Type = rt + x.entry.StructMap.Fields = append(x.entry.StructMap.Fields, mapping) + return x +} + +func (x *BuilderStructMap) IgnoreKey(serialKeyName string) *BuilderStructMap { + x.entry.StructMap.Fields = append(x.entry.StructMap.Fields, StructMapEntry{ + SerialName: serialKeyName, + Ignore: true, + }) + return x +} + +func fieldNameToReflectRoute(rt reflect.Type, fieldNameSplit []string) (rr ReflectRoute, _ reflect.Type, _ error) { + for _, fn := range fieldNameSplit { + rf, ok := rt.FieldByName(fn) + if !ok { + return nil, nil, ErrStructureMismatch{rt.Name(), "does not have field named " + fn} + } + rr = append(rr, rf.Index...) + rt = rf.Type + } + return rr, rt, nil +} + +/* + Automatically generate mappings by looking at the struct type info, + taking any hints from tags, and appending that to the builder. + + You may use autogeneration in concert with manually adding field mappings, + though if doing so be mindful not to map the same fields twice. +*/ +func (x *BuilderStructMap) Autogenerate() *BuilderStructMap { + autoEntry := AutogenerateStructMapEntry(x.entry.Type) + x.entry.StructMap.Fields = append(x.entry.StructMap.Fields, autoEntry.StructMap.Fields...) + return x +} + +/* + Automatically generate mappings using a given struct field sorting scheme +*/ +func (x *BuilderStructMap) AutogenerateWithSortingScheme(sorting KeySortMode) *BuilderStructMap { + autoEntry := AutogenerateStructMapEntryUsingTags(x.entry.Type, "refmt", sorting) + x.entry.StructMap.Fields = append(x.entry.StructMap.Fields, autoEntry.StructMap.Fields...) + return x +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/transformBuilding.go b/vendor/github.com/polydawn/refmt/obj/atlas/transformBuilding.go new file mode 100644 index 00000000..6892fdcd --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/transformBuilding.go @@ -0,0 +1,30 @@ +package atlas + +import ( + "reflect" +) + +func (x *BuilderCore) Transform() *BuilderTransform { + // no checks on x.entry.Type.Kind() here -- transforms can be pretty much any<->any + return &BuilderTransform{x.entry} +} + +type BuilderTransform struct { + entry *AtlasEntry +} + +func (x *BuilderTransform) Complete() *AtlasEntry { + return x.entry +} + +func (x *BuilderTransform) TransformMarshal(trFunc MarshalTransformFunc, toType reflect.Type) *BuilderTransform { + x.entry.MarshalTransformFunc = trFunc + x.entry.MarshalTransformTargetType = toType + return x +} + +func (x *BuilderTransform) TransformUnmarshal(trFunc UnmarshalTransformFunc, toType reflect.Type) *BuilderTransform { + x.entry.UnmarshalTransformFunc = trFunc + x.entry.UnmarshalTransformTargetType = toType + return x +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/transformFuncs.go b/vendor/github.com/polydawn/refmt/obj/atlas/transformFuncs.go new file mode 100644 index 00000000..5cfe98fc --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/transformFuncs.go @@ -0,0 +1,68 @@ +package atlas + +import "reflect" + +type MarshalTransformFunc func(liveForm reflect.Value) (serialForm reflect.Value, err error) +type UnmarshalTransformFunc func(serialForm reflect.Value) (liveForm reflect.Value, err error) + +var err_rt = reflect.TypeOf((*error)(nil)).Elem() + +/* + Takes a wildcard object which must be `func (live T1) (serialable T2, error)` + and returns a MarshalTransformFunc and the typeinfo of T2. +*/ +func MakeMarshalTransformFunc(fn interface{}) (MarshalTransformFunc, reflect.Type) { + fn_rv := reflect.ValueOf(fn) + if fn_rv.Kind() != reflect.Func { + panic("no") + } + fn_rt := fn_rv.Type() + if fn_rt.NumIn() != 1 { + panic("no") + } + if fn_rt.NumOut() != 2 { + panic("no") + } + if !fn_rt.Out(1).AssignableTo(err_rt) { + panic("no") + } + // nothing to do for `fn_rt.In(0)` -- whatever type it is... TODO redesign to make less sketchy; we should most certainly be able to check this in the builder + out_rt := fn_rt.Out(0) + return func(liveForm reflect.Value) (serialForm reflect.Value, err error) { + results := fn_rv.Call([]reflect.Value{liveForm}) + if results[1].IsNil() { + return results[0], nil + } + return results[0], results[1].Interface().(error) + }, out_rt +} + +/* + Takes a wildcard object which must be `func (serialable T1) (live T2, error)` + and returns a UnmarshalTransformFunc and the typeinfo of T1. +*/ +func MakeUnmarshalTransformFunc(fn interface{}) (UnmarshalTransformFunc, reflect.Type) { + fn_rv := reflect.ValueOf(fn) + if fn_rv.Kind() != reflect.Func { + panic("no") + } + fn_rt := fn_rv.Type() + if fn_rt.NumIn() != 1 { + panic("no") + } + if fn_rt.NumOut() != 2 { + panic("no") + } + if !fn_rt.Out(1).AssignableTo(err_rt) { + panic("no") + } + // nothing to do for checking `fn_rf.Out(0)` -- because we don't know what entry we're about to be used for. TODO redesign to make less sketchy. + in_rt := fn_rt.In(0) + return func(serialForm reflect.Value) (liveForm reflect.Value, err error) { + results := fn_rv.Call([]reflect.Value{serialForm}) + if results[1].IsNil() { + return results[0], nil + } + return results[0], results[1].Interface().(error) + }, in_rt +} diff --git a/vendor/github.com/polydawn/refmt/obj/atlas/unionMorphism.go b/vendor/github.com/polydawn/refmt/obj/atlas/unionMorphism.go new file mode 100644 index 00000000..80831856 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/atlas/unionMorphism.go @@ -0,0 +1,45 @@ +package atlas + +import ( + "fmt" + "reflect" + "sort" +) + +type UnionKeyedMorphism struct { + // Mapping of typehint key strings to atlasEntry that should be delegated to. + Elements map[string]*AtlasEntry + // Mapping of rtid to string (roughly the dual of the Elements map). + Mappings map[uintptr]string + // Purely to have in readiness for error messaging. + KnownMembers []string +} + +func (x *BuilderCore) KeyedUnion() *BuilderUnionKeyedMorphism { + if x.entry.Type.Kind() != reflect.Interface { + panic(fmt.Errorf("cannot use union morphisms for type %q, which is kind %s", x.entry.Type, x.entry.Type.Kind())) + } + x.entry.UnionKeyedMorphism = &UnionKeyedMorphism{ + Elements: make(map[string]*AtlasEntry), + Mappings: make(map[uintptr]string), + } + return &BuilderUnionKeyedMorphism{x.entry} +} + +type BuilderUnionKeyedMorphism struct { + entry *AtlasEntry +} + +func (x *BuilderUnionKeyedMorphism) Of(elements map[string]*AtlasEntry) *AtlasEntry { + cfg := x.entry.UnionKeyedMorphism + for hint, ent := range elements { + // FIXME: check that all the delegates are... well struct or map machines really, but definitely blacklisting other delegating machinery. + // FIXME: and sanity check that they can all be assigned to the interface ffs. + + cfg.Elements[hint] = ent + cfg.Mappings[reflect.ValueOf(ent.Type).Pointer()] = hint + cfg.KnownMembers = append(cfg.KnownMembers, hint) + } + sort.Strings(cfg.KnownMembers) + return x.entry +} diff --git a/vendor/github.com/polydawn/refmt/obj/builtins.go b/vendor/github.com/polydawn/refmt/obj/builtins.go new file mode 100644 index 00000000..75c1327d --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/builtins.go @@ -0,0 +1,24 @@ +package obj + +import ( + . "reflect" +) + +var ( + rtid_bool = ValueOf(TypeOf(false)).Pointer() + rtid_string = ValueOf(TypeOf("")).Pointer() + rtid_bytes = ValueOf(TypeOf([]byte{})).Pointer() + rtid_int = ValueOf(TypeOf(int(0))).Pointer() + rtid_int8 = ValueOf(TypeOf(int8(0))).Pointer() + rtid_int16 = ValueOf(TypeOf(int16(0))).Pointer() + rtid_int32 = ValueOf(TypeOf(int32(0))).Pointer() + rtid_int64 = ValueOf(TypeOf(int64(0))).Pointer() + rtid_uint = ValueOf(TypeOf(uint(0))).Pointer() + rtid_uint8 = ValueOf(TypeOf(uint8(0))).Pointer() + rtid_uint16 = ValueOf(TypeOf(uint16(0))).Pointer() + rtid_uint32 = ValueOf(TypeOf(uint32(0))).Pointer() + rtid_uint64 = ValueOf(TypeOf(uint64(0))).Pointer() + rtid_uintptr = ValueOf(TypeOf(uintptr(0))).Pointer() + rtid_float32 = ValueOf(TypeOf(float32(0))).Pointer() + rtid_float64 = ValueOf(TypeOf(float64(0))).Pointer() +) diff --git a/vendor/github.com/polydawn/refmt/obj/doc.go b/vendor/github.com/polydawn/refmt/obj/doc.go new file mode 100644 index 00000000..d3cae216 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/doc.go @@ -0,0 +1,6 @@ +/* + The `obj` package defines Marshaller and Unmarshaller types, + which can be used to convert in-memory values to token streams, + and token streams to unpack in-memory values. +*/ +package obj diff --git a/vendor/github.com/polydawn/refmt/obj/empty.go b/vendor/github.com/polydawn/refmt/obj/empty.go new file mode 100644 index 00000000..b9f1e5b1 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/empty.go @@ -0,0 +1,31 @@ +package obj + +import "reflect" + +// The missing definition of 'reflect.IsZero' you've always wanted. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Struct: + // Note: we can't rely on a *literal* "is zero" check because + // non-zero pointers may still point to *empty* things. + for i := 0; i < v.NumField(); i++ { + if !isEmptyValue(v.Field(i)) { + return false + } + } + return true + } + return false +} diff --git a/vendor/github.com/polydawn/refmt/obj/errors.go b/vendor/github.com/polydawn/refmt/obj/errors.go new file mode 100644 index 00000000..b6c5b0ce --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/errors.go @@ -0,0 +1,82 @@ +package obj + +import ( + "fmt" + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +// General note: avoid using reflect.Type here. It doesn't do well with `go-cmp`, +// which in turn makes our tests for error paths a lot jankier. + +// ErrInvalidUnmarshalTarget describes an invalid argument passed to Unmarshaller.Bind. +// (Unmarshalling must target a non-nil pointer so that it can address the value.) +type ErrInvalidUnmarshalTarget struct { + Type reflect.Type +} + +func (e ErrInvalidUnmarshalTarget) Error() string { + if e.Type == nil { + return "unmarshal error: invalid target (nil)" + } + if e.Type.Kind() != reflect.Ptr { + return "unmarshal error: invalid target (non-pointer " + e.Type.String() + ")" + } + return "unmarshal error: invalid target (nil " + e.Type.String() + ")" +} + +// ErrUnmarshalTypeCantFit is the error returned when unmarshalling cannot +// coerce the tokens in the stream into the kind of variables the unmarshal is targetting, +// for example if a map open token comes when an int is expected, +// or an int token comes when a string is expected. +type ErrUnmarshalTypeCantFit struct { + Token Token + Value reflect.Value + LenLim int // Set only if Value.Kind == Array and Token is bytes of a mismatch length. +} + +func (e ErrUnmarshalTypeCantFit) Error() string { + switch e.LenLim { + case 0: + return fmt.Sprintf("unmarshal error: cannot assign %s to %s field", e.Token, e.Value.Kind()) + default: + return fmt.Sprintf("unmarshal error: cannot assign %s to fixed length=%d byte array", e.Token, e.Value.Len()) + } +} + +// ErrMalformedTokenStream is the error returned when unmarshalling recieves ae +// completely invalid transition, such as when a map value is expected, but the +// map suddenly closes, or an array close is recieved with no matching array open. +type ErrMalformedTokenStream struct { + Got TokenType // Token in the stream that triggered the error. + Expected string // Freeform string describing valid token types. Often a summary like "array close or start of value", or "map close or key". +} + +func (e ErrMalformedTokenStream) Error() string { + return fmt.Sprintf("malformed stream: invalid appearance of %s token; expected %s", e.Got, e.Expected) +} + +// ErrNoSuchField is the error returned when unmarshalling into a struct and +// the token stream for the map contains a key which is not defined for the struct. +type ErrNoSuchField struct { + Name string // Field name from the token. + Type string // Type name of the struct we're operating on. +} + +func (e ErrNoSuchField) Error() string { + return fmt.Sprintf("unmarshal error: stream contains key %q, but there's no such field in structs of type %s", e.Name, e.Type) +} + +// ErrNoSuchUnionMember is the error returned when unmarshalling into a union +// interface and the token stream contains a key which does not name any of the +// known members of the union. +type ErrNoSuchUnionMember struct { + Name string // Key name from the token. + Type reflect.Type // The interface type we're trying to fill. + KnownMembers []string // Members we expected isntead. +} + +func (e ErrNoSuchUnionMember) Error() string { + return fmt.Sprintf("unmarshal error: cannot unmarshal into union %s: %q is not one of the known members (expected one of %s)", e.Type, e.Name, e.KnownMembers) +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshal.go b/vendor/github.com/polydawn/refmt/obj/marshal.go new file mode 100644 index 00000000..754fe69f --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshal.go @@ -0,0 +1,110 @@ +package obj + +import ( + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +/* + Allocates the machinery for treating an object like a `TokenSource`. + This machinery will walk over structures in memory, + emitting tokens representing values and fields as it visits them. + + Initialization must be finished by calling `Bind` to set the value to visit; + after this, the `Step` function is ready to be pumped. + Subsequent calls to `Bind` do a full reset, leaving `Step` ready to call + again and making all of the machinery reusable without re-allocating. +*/ +func NewMarshaller(atl atlas.Atlas) *Marshaller { + d := &Marshaller{ + marshalSlab: marshalSlab{ + atlas: atl, + rows: make([]marshalSlabRow, 0, 10), + }, + stack: make([]MarshalMachine, 0, 10), + } + return d +} + +func (d *Marshaller) Bind(v interface{}) error { + d.stack = d.stack[0:0] + d.marshalSlab.rows = d.marshalSlab.rows[0:0] + rv := reflect.ValueOf(v) + if !rv.IsValid() { + // if given an untyped nil, swap in a less spikey nil thunk instead. + rv = nil_rv + } + rt := rv.Type() + d.step = d.marshalSlab.requisitionMachine(rt) + return d.step.Reset(&d.marshalSlab, rv, rt) +} + +type Marshaller struct { + marshalSlab marshalSlab + stack []MarshalMachine + step MarshalMachine +} + +type MarshalMachine interface { + Reset(*marshalSlab, reflect.Value, reflect.Type) error + Step(*Marshaller, *marshalSlab, *Token) (done bool, err error) +} + +type marshalMachineStep func(*Marshaller, *marshalSlab, *Token) (done bool, err error) + +func (d *Marshaller) Step(tok *Token) (bool, error) { + tok.Tagged = false + // fmt.Printf("> next step is %#v\n", d.step) + done, err := d.step.Step(d, &d.marshalSlab, tok) + // fmt.Printf(">> yield is %#v\n", TokenToString(*tok)) + // If the step errored: out, entirely. + if err != nil { + return true, err + } + // If the step wasn't done, return same status. + if !done { + return false, nil + } + // If it WAS done, pop next, or if stack empty, we're entirely done. + nSteps := len(d.stack) - 1 + if nSteps == -1 { + return true, nil // that's all folks + } + // fmt.Printf(">> popping up from %#v\n", d.stack) + d.step = d.stack[nSteps] + d.stack = d.stack[0:nSteps] + return false, nil +} + +/* + Starts the process of recursing marshalling over value `rv`. + + Caller provides the machine to use (this is an optimization for maps and slices, + which already know the machine and keep reusing it for all their entries). + This method pushes the first step with `tok` (the upstream tends to have peeked at + it in order to decide what to do, but if recursing, it belongs to the next obj), + then saves this new machine onto the driver's stack: future calls to step + the driver will then continuing stepping the new machine it returns a done status, + at which point we'll finally "return" by popping back to the last machine on the stack + (which is presumably the same one that just called this Recurse method). + + In other words, your MarshalMachine calls this when it wants to deal + with an object, and by the time we call back to your machine again, + that object will be traversed and the stream ready for you to continue. +*/ +func (d *Marshaller) Recurse(tok *Token, rv reflect.Value, rt reflect.Type, nextMach MarshalMachine) (err error) { + // fmt.Printf(">>> pushing into recursion with %#v\n", nextMach) + // Push the current machine onto the stack (we'll resume it when the new one is done), + d.stack = append(d.stack, d.step) + // Initialize the machine for this new target value. + err = nextMach.Reset(&d.marshalSlab, rv, rt) + if err != nil { + return + } + d.step = nextMach + // Immediately make a step (we're still the delegate in charge of someone else's step). + _, err = d.Step(tok) + return +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalBuiltins.go b/vendor/github.com/polydawn/refmt/obj/marshalBuiltins.go new file mode 100644 index 00000000..be81a68e --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalBuiltins.go @@ -0,0 +1,92 @@ +package obj + +import ( + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +type ptrDerefDelegateMarshalMachine struct { + MarshalMachine + peelCount int + + isNil bool +} + +func (mach *ptrDerefDelegateMarshalMachine) Reset(slab *marshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.isNil = false + for i := 0; i < mach.peelCount; i++ { + if rv.IsNil() { + mach.isNil = true + return nil + } + rv = rv.Elem() + } + return mach.MarshalMachine.Reset(slab, rv, rv.Type()) // REVIEW: we could have cached the peeled rt at mach conf time; worth it? +} +func (mach *ptrDerefDelegateMarshalMachine) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + if mach.isNil { + tok.Type = TNull + return true, nil + } + return mach.MarshalMachine.Step(driver, slab, tok) +} + +type marshalMachinePrimitive struct { + kind reflect.Kind + + rv reflect.Value +} + +func (mach *marshalMachinePrimitive) Reset(_ *marshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.rv = rv + return nil +} +func (mach *marshalMachinePrimitive) Step(_ *Marshaller, _ *marshalSlab, tok *Token) (done bool, err error) { + switch mach.kind { + case reflect.Bool: + tok.Type = TBool + tok.Bool = mach.rv.Bool() + return true, nil + case reflect.String: + tok.Type = TString + tok.Str = mach.rv.String() + return true, nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + tok.Type = TInt + tok.Int = mach.rv.Int() + return true, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + tok.Type = TUint + tok.Uint = mach.rv.Uint() + return true, nil + case reflect.Float32, reflect.Float64: + tok.Type = TFloat64 + tok.Float64 = mach.rv.Float() + return true, nil + case reflect.Slice: // implicitly bytes; no other slices are "primitive" + if mach.rv.IsNil() { + tok.Type = TNull + return true, nil + } + tok.Type = TBytes + tok.Bytes = mach.rv.Bytes() + return true, nil + case reflect.Array: // implicitly bytes; no other arrays are "primitive" + tok.Type = TBytes + // Unfortunately, there does not seem to be any efficient way to extract the contents of a byte array into a slice via reflect. + // Since the lengths are part of the type, it is almost understandable that the stdlib reflect package has a hard time expressing this; + // however, it drives me somewhat up the wall that they do not provide a case for arrays inside the `Value.Bytes` method, and panic. + // Attempting to `Value.Convert(Type)` from a fixed-length array to a slice of the same type is also rejected. + // Nor does `reflect.AppendSlice` accept an array kind as the second parameter; no, only slices there too. + // So... we iterate. If anyone knows a better way to do this, PRs extremely welcome. + n := mach.rv.Len() + tok.Bytes = make([]byte, n) + for i := 0; i < n; i++ { + tok.Bytes[i] = byte(mach.rv.Index(i).Uint()) + } + return true, nil + default: + panic("unhandled") + } +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalMapWildcard.go b/vendor/github.com/polydawn/refmt/obj/marshalMapWildcard.go new file mode 100644 index 00000000..d8231b39 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalMapWildcard.go @@ -0,0 +1,148 @@ +package obj + +import ( + "fmt" + "reflect" + "sort" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type marshalMachineMapWildcard struct { + morphism *atlas.MapMorphism // set on initialization + + target_rv reflect.Value + value_rt reflect.Type + keyStringer atlas.MarshalTransformFunc + valueMach MarshalMachine + keys []wildcardMapStringyKey + index int + value bool +} + +func (mach *marshalMachineMapWildcard) Reset(slab *marshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + + // Pick machinery for handling the value types. + mach.value_rt = rt.Elem() + mach.valueMach = slab.requisitionMachine(mach.value_rt) + + // Enumerate all the keys (must do this up front, one way or another), + // flip them into strings, + // and sort them (optional, arguably, but right now you're getting it). + key_rt := rt.Key() + switch key_rt.Kind() { + case reflect.String: + // continue. + // note: stdlib json.marshal supports all the int types here as well, and will + // tostring them. but this is not supported symmetrically; so we simply... don't. + // we could also consider supporting anything that uses a MarshalTransformFunc + // to become a string kind; that's a fair bit of code, perhaps later. + mach.keyStringer = nil + case reflect.Struct: + // composite keys requires some fancy footwork, but we can do it. + // Interestingly enough, we don't need full-on machinery here; because the + // tokenized form is restricted to being a string, the transform func is enough. + rtid := reflect.ValueOf(key_rt).Pointer() + atlEnt, ok := slab.atlas.Get(rtid) + if !ok || atlEnt.MarshalTransformTargetType == nil || atlEnt.MarshalTransformTargetType.Kind() != reflect.String { + return fmt.Errorf("unsupported map key type %q (if you want to use struct keys, your atlas needs a transform to string)", key_rt.Name()) + } + mach.keyStringer = atlEnt.MarshalTransformFunc + default: + return fmt.Errorf("unsupported map key type %q", key_rt.Name()) + } + keys_rv := mach.target_rv.MapKeys() + mach.keys = make([]wildcardMapStringyKey, len(keys_rv)) + for i, v := range keys_rv { + mach.keys[i].rv = v + if mach.keyStringer == nil { + mach.keys[i].s = v.String() + } else { + trans_rv, err := mach.keyStringer(v) + if err != nil { + return fmt.Errorf("unsupported map key type %q: errors in stringifying: %s", key_rt.Name(), err) + } + mach.keys[i].s = trans_rv.String() + } + } + + ksm := atlas.KeySortMode_Default + if mach.morphism != nil { + ksm = mach.morphism.KeySortMode + } + + switch ksm { + case atlas.KeySortMode_Default: + sort.Sort(wildcardMapStringyKey_byString(mach.keys)) + case atlas.KeySortMode_Strings: + sort.Sort(wildcardMapStringyKey_byString(mach.keys)) + case atlas.KeySortMode_RFC7049: + sort.Sort(wildcardMapStringyKey_RFC7049(mach.keys)) + default: + panic(fmt.Errorf("unknown map key sort mode %q", ksm)) + } + + mach.index = -1 + return nil +} + +func (mach *marshalMachineMapWildcard) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + if mach.index < 0 { + if mach.target_rv.IsNil() { + tok.Type = TNull + mach.index++ + return true, nil + } + tok.Type = TMapOpen + tok.Length = mach.target_rv.Len() + mach.index++ + return false, nil + } + if mach.index == len(mach.keys) { + tok.Type = TMapClose + mach.index++ + slab.release() + return true, nil + } + if mach.index > len(mach.keys) { + return true, fmt.Errorf("invalid state: value already consumed") + } + if mach.value { + val_rv := mach.target_rv.MapIndex(mach.keys[mach.index].rv) + mach.value = false + mach.index++ + return false, driver.Recurse(tok, val_rv, mach.value_rt, mach.valueMach) + } + tok.Type = TString + tok.Str = mach.keys[mach.index].s + mach.value = true + return false, nil +} + +// Holder for the reflect.Value and string form of a key. +// We need the reflect.Value for looking up the map value; +// and we need the string for sorting. +type wildcardMapStringyKey struct { + rv reflect.Value + s string +} + +type wildcardMapStringyKey_byString []wildcardMapStringyKey + +func (x wildcardMapStringyKey_byString) Len() int { return len(x) } +func (x wildcardMapStringyKey_byString) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x wildcardMapStringyKey_byString) Less(i, j int) bool { return x[i].s < x[j].s } + +type wildcardMapStringyKey_RFC7049 []wildcardMapStringyKey + +func (x wildcardMapStringyKey_RFC7049) Len() int { return len(x) } +func (x wildcardMapStringyKey_RFC7049) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x wildcardMapStringyKey_RFC7049) Less(i, j int) bool { + li, lj := len(x[i].s), len(x[j].s) + if li == lj { + return x[i].s < x[j].s + } + return li < lj +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalSlab.go b/vendor/github.com/polydawn/refmt/obj/marshalSlab.go new file mode 100644 index 00000000..88c8e6f0 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalSlab.go @@ -0,0 +1,219 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +/* + A lovely mechanism to stash marshalMachine objects pre-allocated and avoid mallocs. + Works together with the Atlas: the Atlas says what kind of machinery is needed; + the marshalSlab "allocates" it and returns it upon your request. +*/ +type marshalSlab struct { + atlas atlas.Atlas + rows []marshalSlabRow +} + +type marshalSlabRow struct { + ptrDerefDelegateMarshalMachine + marshalMachinePrimitive + marshalMachineWildcard + marshalMachineMapWildcard + marshalMachineSliceWildcard + marshalMachineStructAtlas + marshalMachineTransform + marshalMachineUnionKeyed + + errThunkMarshalMachine +} + +// A thunk value that can be used to trigger `isNil` paths. +// (Substituting an 'invalid' kind reflect.Value with this is an easy way +// to emit a null without needing any additional special cases or error handling.) +var nil_rv reflect.Value = reflect.Zero(reflect.PtrTo(reflect.TypeOf(0))) + +/* + Return a reference to a machine from the slab. + *You must release() when done.* + + Errors -- including "no info in Atlas for this type" -- are expressed by + returning a machine that is a constantly-erroring thunk. +*/ +func (slab *marshalSlab) requisitionMachine(rt reflect.Type) MarshalMachine { + // Acquire a row. + off := len(slab.rows) + slab.grow() + row := &slab.rows[off] + + // Yield machinery. + return _yieldMarshalMachinePtr(row, slab.atlas, rt) +} + +/* + Like requisitionMachine, but does *not* grow the slab; assumes the current + tip row is usable. + Thus, you must grow() before using, and release correspondingly. +*/ +func (slab *marshalSlab) yieldMachine(rt reflect.Type) MarshalMachine { + // Grab the last row. + row := &slab.rows[len(slab.rows)-1] + + // Yield machinery. + return _yieldMarshalMachinePtr(row, slab.atlas, rt) +} + +func _yieldMarshalMachinePtr(row *marshalSlabRow, atl atlas.Atlas, rt reflect.Type) MarshalMachine { + // Indirect pointers as necessary. + // Keep count of how many times we do this; we'll use this again at the end. + peelCount := 0 + for rt.Kind() == reflect.Ptr { + rt = rt.Elem() + peelCount++ + } + + // Figure out what machinery to use at heart. + mach := _yieldBareMarshalMachinePtr(row, atl, rt) + // If nil answer, we had no match: yield an error thunk. + if mach == nil { + mach := &row.errThunkMarshalMachine + mach.err = fmt.Errorf("no machine found") + return mach + } + + // If no indirection steps, return; + // otherwise wrap it in the ptrDeref machine and return that. + if peelCount == 0 { + return mach + } + row.ptrDerefDelegateMarshalMachine.MarshalMachine = mach + row.ptrDerefDelegateMarshalMachine.peelCount = peelCount + row.ptrDerefDelegateMarshalMachine.isNil = false + return &row.ptrDerefDelegateMarshalMachine +} + +// Like _yieldMarshalMachinePtr, but assumes the ptr unwrapping has already been done. +func _yieldBareMarshalMachinePtr(row *marshalSlabRow, atl atlas.Atlas, rt reflect.Type) MarshalMachine { + rtid := reflect.ValueOf(rt).Pointer() + + // Check primitives first; cheapest (and unoverridable). + switch rtid { + case rtid_bool, + rtid_string, + rtid_int, rtid_int8, rtid_int16, rtid_int32, rtid_int64, + rtid_uint, rtid_uint8, rtid_uint16, rtid_uint32, rtid_uint64, rtid_uintptr, + rtid_float32, rtid_float64, + rtid_bytes: + row.marshalMachinePrimitive.kind = rt.Kind() + return &row.marshalMachinePrimitive + } + + // Consult atlas second. + if entry, ok := atl.Get(rtid); ok { + return _yieldMarshalMachinePtrForAtlasEntry(row, entry, atl) + } + + // If no specific behavior found, use default behavior based on kind. + switch rt.Kind() { + case reflect.Bool, + reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64: + row.marshalMachinePrimitive.kind = rt.Kind() + return &row.marshalMachinePrimitive + case reflect.Slice: + // un-typedef'd byte slices were handled already, but a typedef'd one still gets gets treated like a special kind: + if rt.Elem().Kind() == reflect.Uint8 { + row.marshalMachinePrimitive.kind = rt.Kind() + return &row.marshalMachinePrimitive + } + return &row.marshalMachineSliceWildcard + case reflect.Array: + // arrays of bytes have a similar special case to slices for when they're typedefed. + if rt.Elem().Kind() == reflect.Uint8 { + row.marshalMachinePrimitive.kind = rt.Kind() + return &row.marshalMachinePrimitive + } + return &row.marshalMachineSliceWildcard.marshalMachineArrayWildcard + case reflect.Map: + row.marshalMachineMapWildcard.morphism = atl.GetDefaultMapMorphism() + return &row.marshalMachineMapWildcard + case reflect.Struct: + // TODO here we could also invoke automatic atlas autogen, if configured to be permitted + mach := &row.errThunkMarshalMachine + mach.err = fmt.Errorf("missing an atlas entry describing how to marshal type %v (and auto-atlasing for structs is not enabled)", rt) + return mach + case reflect.Interface: + return &row.marshalMachineWildcard + case reflect.Func: + panic(fmt.Errorf("functions cannot be marshalled!")) + case reflect.Ptr: + panic(fmt.Errorf("unreachable: ptrs must already be resolved")) + default: + panic(fmt.Errorf("excursion %s", rt.Kind())) + } +} + +// given that we already have an atlasEntry in mind, yield a configured machine for it. +// it seems odd that this might still require a whole atlas, but tis so; +// some things (e.g. transform funcs) need to get additional machinery for delegation. +func _yieldMarshalMachinePtrForAtlasEntry(row *marshalSlabRow, entry *atlas.AtlasEntry, atl atlas.Atlas) MarshalMachine { + // Switch across which of the union of configurations is applicable. + switch { + case entry.MarshalTransformFunc != nil: + // Return a machine that calls the func(s), then later a real machine. + // The entry.MarshalTransformTargetType is used to do a recursive lookup. + // We can't just call the func here because we're still working off typeinfo + // and don't have a real value to transform until later. + row.marshalMachineTransform.trFunc = entry.MarshalTransformFunc + // Pick delegate without growing stack. (This currently means recursive transform won't fly.) + row.marshalMachineTransform.delegate = _yieldMarshalMachinePtr(row, atl, entry.MarshalTransformTargetType) + // If tags are in play: have the transformer machine glue that on. + + row.marshalMachineTransform.tagged = entry.Tagged + row.marshalMachineTransform.tag = entry.Tag + return &row.marshalMachineTransform + case entry.StructMap != nil: + row.marshalMachineStructAtlas.cfg = entry + return &row.marshalMachineStructAtlas + case entry.UnionKeyedMorphism != nil: + row.marshalMachineUnionKeyed.cfg = entry + return &row.marshalMachineUnionKeyed + case entry.MapMorphism != nil: + row.marshalMachineMapWildcard.morphism = entry.MapMorphism + return &row.marshalMachineMapWildcard + default: + panic("invalid atlas entry") + } +} + +// Returns the top row of the slab. Useful for machines that need to delegate +// to another type that's definitely not their own. Be careful with that +// caveat; if the delegation can be to another system that uses in-row delegation, +// this is not trivially safe to compose and you should grow the slab instead. +func (s *marshalSlab) tip() *marshalSlabRow { + return &s.rows[len(s.rows)-1] +} + +func (s *marshalSlab) grow() { + s.rows = append(s.rows, marshalSlabRow{}) +} + +func (s *marshalSlab) release() { + s.rows = s.rows[0 : len(s.rows)-1] +} + +type errThunkMarshalMachine struct { + err error +} + +func (m *errThunkMarshalMachine) Reset(_ *marshalSlab, _ reflect.Value, _ reflect.Type) error { + return m.err +} +func (m *errThunkMarshalMachine) Step(d *Marshaller, s *marshalSlab, tok *Token) (done bool, err error) { + return true, m.err +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalSliceWildcard.go b/vendor/github.com/polydawn/refmt/obj/marshalSliceWildcard.go new file mode 100644 index 00000000..3cf527d5 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalSliceWildcard.go @@ -0,0 +1,63 @@ +package obj + +import ( + "fmt" + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +// Encodes a slice. +// This machine just wraps the array machine, checking to make sure the value isn't nil. +type marshalMachineSliceWildcard struct { + marshalMachineArrayWildcard +} + +func (mach *marshalMachineSliceWildcard) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + if mach.index < 0 { + if mach.target_rv.IsNil() { + tok.Type = TNull + return true, nil + } + } + return mach.marshalMachineArrayWildcard.Step(driver, slab, tok) +} + +type marshalMachineArrayWildcard struct { + target_rv reflect.Value + value_rt reflect.Type + valueMach MarshalMachine + index int + length int +} + +func (mach *marshalMachineArrayWildcard) Reset(slab *marshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.value_rt = rt.Elem() + mach.valueMach = slab.requisitionMachine(mach.value_rt) + mach.index = -1 + mach.length = mach.target_rv.Len() + return nil +} + +func (mach *marshalMachineArrayWildcard) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + if mach.index < 0 { + tok.Type = TArrOpen + tok.Length = mach.target_rv.Len() + mach.index++ + return false, nil + } + if mach.index == mach.length { + tok.Type = TArrClose + mach.index++ + slab.release() + return true, nil + } + if mach.index > mach.length { + return true, fmt.Errorf("invalid state: value already consumed") + } + rv := mach.target_rv.Index(mach.index) + driver.Recurse(tok, rv, mach.value_rt, mach.valueMach) + mach.index++ + return false, nil +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalStruct.go b/vendor/github.com/polydawn/refmt/obj/marshalStruct.go new file mode 100644 index 00000000..7ea4fd24 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalStruct.go @@ -0,0 +1,108 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type marshalMachineStructAtlas struct { + cfg *atlas.AtlasEntry // set on initialization + + target_rv reflect.Value + index int // Progress marker + value_rv reflect.Value // Next value (or nil if next step is key). +} + +func (mach *marshalMachineStructAtlas) Reset(slab *marshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.target_rv = rv + mach.index = -1 + mach.value_rv = reflect.Value{} + slab.grow() // we'll reuse the same row for all fields + return nil +} + +func (mach *marshalMachineStructAtlas) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + //fmt.Printf("--step on %#v: i=%d/%d v=%v\n", mach.target_rv, mach.index, len(mach.cfg.Fields), mach.value) + + // Check boundaries and do the special steps or either start or end. + nEntries := len(mach.cfg.StructMap.Fields) + if mach.index < 0 { + tok.Type = TMapOpen + tok.Length = countEmittableStructFields(mach.cfg, mach.target_rv) + tok.Tagged = mach.cfg.Tagged + tok.Tag = mach.cfg.Tag + mach.index++ + return false, nil + } + if mach.index == nEntries { + tok.Type = TMapClose + mach.index++ + slab.release() + return true, nil + } + if mach.index > nEntries { + return true, fmt.Errorf("invalid state: entire struct (%d fields) already consumed", nEntries) + } + + // If value loaded from last step, recurse into handling that. + fieldEntry := mach.cfg.StructMap.Fields[mach.index] + if mach.value_rv != (reflect.Value{}) { + child_rv := mach.value_rv + mach.index++ + mach.value_rv = reflect.Value{} + return false, driver.Recurse( + tok, + child_rv, + fieldEntry.Type, + slab.yieldMachine(fieldEntry.Type), + ) + } + + // If value was nil, that indicates we're supposed to pick the value and yield a key. + // We have to look ahead to the value because if it's zero and tagged as + // omitEmpty, then we have to skip emitting the key as well. + for fieldEntry.Ignore { + mach.index++ + if mach.index == nEntries { + tok.Type = TMapClose + mach.index++ + slab.release() + return true, nil + } + fieldEntry = mach.cfg.StructMap.Fields[mach.index] + } + mach.value_rv = fieldEntry.ReflectRoute.TraverseToValue(mach.target_rv) + if fieldEntry.OmitEmpty && isEmptyValue(mach.value_rv) { + mach.value_rv = reflect.Value{} + mach.index++ + return mach.Step(driver, slab, tok) + } + tok.Type = TString + tok.Str = fieldEntry.SerialName + return false, nil +} + +// Count how many fields in a struct should actually be marshalled. +// Fields that are tagged omitEmpty and are isEmptyValue are not counted, and +// StructMapEntry used to flag ignored fields unmarshalling never count, so +// this number may be less than the number of fields in the AtlasEntry.StructMap. +func countEmittableStructFields(cfg *atlas.AtlasEntry, target_rv reflect.Value) int { + total := 0 + for _, fieldEntry := range cfg.StructMap.Fields { + if fieldEntry.Ignore { + continue + } + if !fieldEntry.OmitEmpty { + total++ + continue + } + if !isEmptyValue(fieldEntry.ReflectRoute.TraverseToValue(target_rv)) { + total++ + continue + } + } + return total +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalTransform.go b/vendor/github.com/polydawn/refmt/obj/marshalTransform.go new file mode 100644 index 00000000..7e1c1514 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalTransform.go @@ -0,0 +1,35 @@ +package obj + +import ( + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type marshalMachineTransform struct { + trFunc atlas.MarshalTransformFunc + delegate MarshalMachine + tagged bool // Used to apply tag to first step (without forcing delegate to know). + tag int + first bool // This resets; 'tagged' persists (because it's type info). +} + +func (mach *marshalMachineTransform) Reset(slab *marshalSlab, rv reflect.Value, _ reflect.Type) error { + tr_rv, err := mach.trFunc(rv) + if err != nil { + return err + } + mach.first = true + return mach.delegate.Reset(slab, tr_rv, tr_rv.Type()) +} + +func (mach *marshalMachineTransform) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + done, err = mach.delegate.Step(driver, slab, tok) + if mach.first && mach.tagged { + tok.Tagged = true + tok.Tag = mach.tag + mach.first = false + } + return +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalUnionKeyed.go b/vendor/github.com/polydawn/refmt/obj/marshalUnionKeyed.go new file mode 100644 index 00000000..efd10da0 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalUnionKeyed.go @@ -0,0 +1,71 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type marshalMachineUnionKeyed struct { + cfg *atlas.AtlasEntry // set on initialization + + target_rv reflect.Value // the element (interface already unwrapped). + elementName string // the serial name for this union member type. + + step marshalMachineStep + delegate MarshalMachine // actual machine, picked based on content of the interface. +} + +func (mach *marshalMachineUnionKeyed) Reset(slab *marshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv.Elem() + if mach.target_rv.Kind() == reflect.Invalid { + return fmt.Errorf("nil is not a valid member for the union for interface %q", mach.cfg.Type.Name()) + } + element_rt := mach.target_rv.Type() + mach.elementName = mach.cfg.UnionKeyedMorphism.Mappings[reflect.ValueOf(element_rt).Pointer()] + if mach.elementName == "" { + return fmt.Errorf("type %q is not one of the known members of the union for interface %q", element_rt.Name(), mach.cfg.Type.Name()) + } + delegateAtlasEnt := mach.cfg.UnionKeyedMorphism.Elements[mach.elementName] + mach.delegate = _yieldMarshalMachinePtrForAtlasEntry(slab.tip(), delegateAtlasEnt, slab.atlas) + if err := mach.delegate.Reset(slab, mach.target_rv, delegateAtlasEnt.Type); err != nil { + return err + } + mach.step = mach.step_emitMapOpen + return nil +} + +func (mach *marshalMachineUnionKeyed) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + return mach.step(driver, slab, tok) +} + +func (mach *marshalMachineUnionKeyed) step_emitMapOpen(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + tok.Type = TMapOpen + tok.Length = 1 + mach.step = mach.step_emitKey + return false, nil +} + +func (mach *marshalMachineUnionKeyed) step_emitKey(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + tok.Type = TString + tok.Str = mach.elementName + mach.step = mach.step_delegate + return false, nil +} + +func (mach *marshalMachineUnionKeyed) step_delegate(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + done, err = mach.delegate.Step(driver, slab, tok) + if done && err == nil { + mach.step = mach.step_emitMapClose + return false, nil + } + return +} + +func (mach *marshalMachineUnionKeyed) step_emitMapClose(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + tok.Type = TMapClose + mach.step = nil + return true, nil +} diff --git a/vendor/github.com/polydawn/refmt/obj/marshalWildcard.go b/vendor/github.com/polydawn/refmt/obj/marshalWildcard.go new file mode 100644 index 00000000..67153e20 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/marshalWildcard.go @@ -0,0 +1,37 @@ +package obj + +import ( + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +/* + A MarshalMachine that unwraps an `interface{}` value, + selects the correct machinery for handling its content, + and delegates immediately to that machine. +*/ +type marshalMachineWildcard struct { + delegate MarshalMachine +} + +func (mach *marshalMachineWildcard) Reset(slab *marshalSlab, rv reflect.Value, rt reflect.Type) error { + // If the interface contains nil, go no further; we'll simply yield that single token. + if rv.IsNil() { + mach.delegate = nil + return nil + } + // Pick, reset, and retain a delegate machine for the interior type. + unwrap_rv := rv.Elem() // unwrap iface + unwrap_rt := unwrap_rv.Type() + mach.delegate = slab.requisitionMachine(unwrap_rt) + return mach.delegate.Reset(slab, unwrap_rv, unwrap_rt) +} + +func (mach marshalMachineWildcard) Step(driver *Marshaller, slab *marshalSlab, tok *Token) (done bool, err error) { + if mach.delegate == nil { + tok.Type = TNull + return true, nil + } + return mach.delegate.Step(driver, slab, tok) +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshal.go b/vendor/github.com/polydawn/refmt/obj/unmarshal.go new file mode 100644 index 00000000..6e500719 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshal.go @@ -0,0 +1,108 @@ +package obj + +import ( + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +/* + Allocates the machinery for treating an in-memory object like a `TokenSink`. + This machinery will walk over values, using received tokens to fill in + fields as it visits them. + + Initialization must be finished by calling `Bind` to set the value to visit; + after this, the `Step` function is ready to be pumped. + Subsequent calls to `Bind` do a full reset, leaving `Step` ready to call + again and making all of the machinery reusable without re-allocating. +*/ +func NewUnmarshaller(atl atlas.Atlas) *Unmarshaller { + d := &Unmarshaller{ + unmarshalSlab: unmarshalSlab{ + atlas: atl, + rows: make([]unmarshalSlabRow, 0, 10), + }, + stack: make([]UnmarshalMachine, 0, 10), + } + return d +} + +func (d *Unmarshaller) Bind(v interface{}) error { + d.stack = d.stack[0:0] + d.unmarshalSlab.rows = d.unmarshalSlab.rows[0:0] + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + err := ErrInvalidUnmarshalTarget{reflect.TypeOf(v)} + d.step = &errThunkUnmarshalMachine{err} + return err + } + rv = rv.Elem() // Let's just always be addressible, shall we? + rt := rv.Type() + d.step = d.unmarshalSlab.requisitionMachine(rt) + return d.step.Reset(&d.unmarshalSlab, rv, rt) +} + +type Unmarshaller struct { + unmarshalSlab unmarshalSlab + stack []UnmarshalMachine + step UnmarshalMachine +} + +type UnmarshalMachine interface { + Reset(*unmarshalSlab, reflect.Value, reflect.Type) error + Step(*Unmarshaller, *unmarshalSlab, *Token) (done bool, err error) +} + +type unmarshalMachineStep func(*Unmarshaller, *unmarshalSlab, *Token) (done bool, err error) + +func (d *Unmarshaller) Step(tok *Token) (bool, error) { + done, err := d.step.Step(d, &d.unmarshalSlab, tok) + // If the step errored: out, entirely. + if err != nil { + return true, err + } + // If the step wasn't done, return same status. + if !done { + return false, nil + } + // If it WAS done, pop next, or if stack empty, we're entirely done. + nSteps := len(d.stack) - 1 + if nSteps == -1 { + return true, nil // that's all folks + } + d.step = d.stack[nSteps] + d.stack = d.stack[0:nSteps] + return false, nil +} + +/* + Starts the process of recursing unmarshalling over value `rv`. + + Caller provides the machine to use (this is an optimization for maps and slices, + which already know the machine and keep reusing it for all their entries). + This method pushes the first step with `tok` (the upstream tends to have peeked at + it in order to decide what to do, but if recursing, it belongs to the next obj), + then saves this new machine onto the driver's stack: future calls to step + the driver will then continuing stepping the new machine it returns a done status, + at which point we'll finally "return" by popping back to the last machine on the stack + (which is presumably the same one that just called this Recurse method). + + In other words, your UnmarshalMachine calls this when it wants to deal + with an object, and by the time we call back to your machine again, + that object will be traversed and the stream ready for you to continue. +*/ +func (d *Unmarshaller) Recurse(tok *Token, rv reflect.Value, rt reflect.Type, nextMach UnmarshalMachine) (err error) { + // fmt.Printf(">>> pushing into recursion with %#v\n", nextMach) + // Push the current machine onto the stack (we'll resume it when the new one is done), + d.stack = append(d.stack, d.step) + // Initialize the machine for this new target value. + err = nextMach.Reset(&d.unmarshalSlab, rv, rt) + if err != nil { + return + } + d.step = nextMach + // Immediately make a step (we're still the delegate in charge of someone else's step). + _, err = d.Step(tok) + return +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalArrayWildcard.go b/vendor/github.com/polydawn/refmt/obj/unmarshalArrayWildcard.go new file mode 100644 index 00000000..5904a4c0 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalArrayWildcard.go @@ -0,0 +1,80 @@ +package obj + +import ( + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineArrayWildcard struct { + target_rv reflect.Value + value_rt reflect.Type + valueMach UnmarshalMachine + step unmarshalMachineStep + index int + maxLen int +} + +func (mach *unmarshalMachineArrayWildcard) Reset(slab *unmarshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.value_rt = rt.Elem() + mach.valueMach = slab.requisitionMachine(mach.value_rt) + mach.step = mach.step_Initial + mach.index = 0 + mach.maxLen = rt.Len() + return nil +} + +func (mach *unmarshalMachineArrayWildcard) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + return mach.step(driver, slab, tok) +} + +func (mach *unmarshalMachineArrayWildcard) step_Initial(_ *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // If it's a special state, start an object. + // (Or, blow up if its a special state that's silly). + switch tok.Type { + case TMapOpen: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TArrOpen: + // Great. Consumed. + mach.step = mach.step_AcceptValue + // Initialize the array. Its length is encoded in its type. + mach.target_rv.Set(reflect.Zero(mach.target_rv.Type())) + return false, nil + case TMapClose: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TArrClose: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TNull: + mach.target_rv.Set(reflect.Zero(mach.target_rv.Type())) + return true, nil + default: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + } +} + +func (mach *unmarshalMachineArrayWildcard) step_AcceptValue(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // Either form of open token are valid, but + // - an arrClose is ours + // - and a mapClose is clearly invalid. + switch tok.Type { + case TMapClose: + // no special checks for ends of wildcard slice; no such thing as incomplete. + return true, ErrMalformedTokenStream{tok.Type, "start of value or end of array"} + case TArrClose: + // release the slab row we requisitioned for our value machine. + slab.release() + return true, nil + } + + // Return an error if we're about to exceed our length limit. + if mach.index >= mach.maxLen { + return true, ErrMalformedTokenStream{tok.Type, "end of array (out of space)"} + } + + // Recurse on a handle to the next index. + rv := mach.target_rv.Index(mach.index) + mach.index++ + return false, driver.Recurse(tok, rv, mach.value_rt, mach.valueMach) + // Step simply remains `step_AcceptValue` -- arrays don't have much state machine. +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalBuiltins.go b/vendor/github.com/polydawn/refmt/obj/unmarshalBuiltins.go new file mode 100644 index 00000000..8dc96cbb --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalBuiltins.go @@ -0,0 +1,176 @@ +package obj + +import ( + "fmt" + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +type ptrDerefDelegateUnmarshalMachine struct { + UnmarshalMachine // a delegate machine, already set for us by the slab + peelCount int // how deep the pointers go, already discoverd by the slab + + ptr_rv reflect.Value // the top ptr, which we will use if setting to nil, or if we have to recursively make ptrs for `**X` types. + firstStep bool +} + +func (mach *ptrDerefDelegateUnmarshalMachine) Reset(slab *unmarshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.ptr_rv = rv + mach.firstStep = true + // we defer reseting the delegate machine until later, in case we get a nil, which can save a lot of time. + return nil +} +func (mach *ptrDerefDelegateUnmarshalMachine) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // If first step: we have to do initializations. + if mach.firstStep { + mach.firstStep = false + // If nil: easy road. Nil the ptr. + if tok.Type == TNull { + mach.ptr_rv.Set(reflect.Zero(mach.ptr_rv.Type())) + return true, nil + } + // Walk the pointers: if some already exist, we accept them unmodified; + // if any are nil, make a new one, and recursively. + rv := mach.ptr_rv + for i := 0; i < mach.peelCount; i++ { + if rv.IsNil() { + rv.Set(reflect.New(rv.Type().Elem())) + rv = rv.Elem() + } else { + rv = rv.Elem() + } + } + if err := mach.UnmarshalMachine.Reset(slab, rv, rv.Type()); err != nil { + return true, err + } + } + // The remainder of the time: it's just delegation. + return mach.UnmarshalMachine.Step(driver, slab, tok) +} + +type unmarshalMachinePrimitive struct { + kind reflect.Kind + + rv reflect.Value +} + +func (mach *unmarshalMachinePrimitive) Reset(_ *unmarshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.rv = rv + return nil +} +func (mach *unmarshalMachinePrimitive) Step(_ *Unmarshaller, _ *unmarshalSlab, tok *Token) (done bool, err error) { + switch mach.kind { + case reflect.Bool: + switch tok.Type { + case TBool: + mach.rv.SetBool(tok.Bool) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.String: + switch tok.Type { + case TString: + mach.rv.SetString(tok.Str) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch tok.Type { + case TInt: + mach.rv.SetInt(tok.Int) + return true, nil + case TUint: + mach.rv.SetInt(int64(tok.Uint)) // todo: overflow check + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch tok.Type { + case TInt: + if tok.Int >= 0 { + mach.rv.SetUint(uint64(tok.Int)) + return true, nil + } + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + case TUint: + mach.rv.SetUint(tok.Uint) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Float32, reflect.Float64: + switch tok.Type { + case TFloat64: + mach.rv.SetFloat(tok.Float64) + return true, nil + case TInt: + mach.rv.SetFloat(float64(tok.Int)) + return true, nil + case TUint: + mach.rv.SetFloat(float64(tok.Uint)) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Slice: // implicitly bytes; no other slices are "primitive" + switch tok.Type { + case TBytes: + mach.rv.SetBytes(tok.Bytes) + return true, nil + case TNull: + mach.rv.SetBytes(nil) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Array: // implicitly bytes; no other arrays are "primitive" + switch tok.Type { + case TBytes: + // Unfortunately, there does not seem to be any efficient way to bulk set the contents of a byte array via reflect. + // There are similar complaints regarding slices on the marshalling side: apparently, we have no choice but to loop. + n := mach.rv.Len() + // We match aggressively on length. If the provided input is too short, we reject that too: we assume you asked for a fixed-length array for a reason. + if len(tok.Bytes) != n { + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, n} + } + for i := 0; i < n; i++ { + mach.rv.Index(i).SetUint(uint64(tok.Bytes[i])) + } + return true, nil + case TNull: + if mach.rv.Len() != 0 { + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + mach.rv.SetBytes(nil) + return true, nil + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.rv, 0} + } + case reflect.Interface: + switch tok.Type { + case TString: + mach.rv.Set(reflect.ValueOf(tok.Str)) + case TBytes: + mach.rv.Set(reflect.ValueOf(tok.Bytes)) + case TBool: + mach.rv.Set(reflect.ValueOf(tok.Bool)) + case TInt: + mach.rv.Set(reflect.ValueOf(tok.Int)) + case TUint: + mach.rv.Set(reflect.ValueOf(tok.Uint)) + case TFloat64: + mach.rv.Set(reflect.ValueOf(tok.Float64)) + case TNull: + mach.rv.Set(reflect.ValueOf(nil)) + default: // any of the other token types should not have been routed here to begin with. + panic(fmt.Errorf("unhandled: %v", mach.kind)) + } + return true, nil + default: + panic(fmt.Errorf("unhandled: %v", mach.kind)) + } +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalMapWildcard.go b/vendor/github.com/polydawn/refmt/obj/unmarshalMapWildcard.go new file mode 100644 index 00000000..7f068af5 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalMapWildcard.go @@ -0,0 +1,129 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineMapStringWildcard struct { + target_rv reflect.Value // Handle to the map. Can set to zero, or set k=v pairs into, etc. + value_rt reflect.Type // Type info for map values (cached for convenience in recurse calls). + valueMach UnmarshalMachine // Machine for map values. + key_rv reflect.Value // Addressable handle to a slot for keys to unmarshal into. + keyDestringer atlas.UnmarshalTransformFunc // Transform str->foo, to be used if keys are not plain strings. + tmp_rv reflect.Value // Addressable handle to a slot for values to unmarshal into. + step unmarshalMachineStep + haveValue bool // Piece of attendant state to help know we've been through at least one k=v pair so we can post-v store it. +} + +func (mach *unmarshalMachineMapStringWildcard) Reset(slab *unmarshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.value_rt = rt.Elem() + mach.valueMach = slab.requisitionMachine(mach.value_rt) + key_rt := rt.Key() + mach.key_rv = reflect.New(key_rt).Elem() + if mach.key_rv.Kind() != reflect.String { + rtid := reflect.ValueOf(key_rt).Pointer() + atlEnt, ok := slab.atlas.Get(rtid) + if !ok || atlEnt.UnmarshalTransformTargetType == nil || atlEnt.UnmarshalTransformTargetType.Kind() != reflect.String { + return fmt.Errorf("unsupported map key type %q (if you want to use struct keys, your atlas needs a transform from string)", key_rt.Name()) + } + mach.keyDestringer = atlEnt.UnmarshalTransformFunc + } + mach.tmp_rv = reflect.New(mach.value_rt).Elem() + mach.step = mach.step_Initial + mach.haveValue = false + return nil +} + +func (mach *unmarshalMachineMapStringWildcard) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + return mach.step(driver, slab, tok) +} + +func (mach *unmarshalMachineMapStringWildcard) step_Initial(_ *Unmarshaller, _ *unmarshalSlab, tok *Token) (done bool, err error) { + // If it's a special state, start an object. + // (Or, blow up if its a special state that's silly). + switch tok.Type { + case TNull: + mach.target_rv.Set(reflect.Zero(mach.target_rv.Type())) + return true, nil + case TMapOpen: + // Great. Consumed. + mach.step = mach.step_AcceptKey + // Initialize the map if it's nil. + if mach.target_rv.IsNil() { + mach.target_rv.Set(reflect.MakeMap(mach.target_rv.Type())) + } + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of map") + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of map") + case TArrOpen: + fallthrough + default: + return true, ErrUnmarshalTypeCantFit{*tok, mach.target_rv, 0} + } +} + +func (mach *unmarshalMachineMapStringWildcard) step_AcceptKey(_ *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // First, save any refs from the last value. + // (This is fiddly: the delay comes mostly from the handling of slices, which may end up re-allocating + // themselves during their decoding.) + if mach.haveValue { + mach.target_rv.SetMapIndex(mach.key_rv, mach.tmp_rv) + } + // Now switch on tokens. + switch tok.Type { + case TMapOpen: + return true, fmt.Errorf("unexpected mapOpen; expected map key") + case TArrOpen: + return true, fmt.Errorf("unexpected arrOpen; expected map key") + case TMapClose: + // no special checks for ends of wildcard map; no such thing as incomplete. + // release the slab row we requisitioned for our value machine. + slab.release() + return true, nil + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected map key") + case TString: + if mach.keyDestringer != nil { + key_rv, err := mach.keyDestringer(reflect.ValueOf(tok.Str)) + if err != nil { + return true, fmt.Errorf("unsupported map key type %q: errors in stringifying: %s", mach.key_rv.Type().Name(), err) + } + mach.key_rv.Set(key_rv) + } else { + mach.key_rv.SetString(tok.Str) + } + if err = mach.mustAcceptKey(mach.key_rv); err != nil { + return true, err + } + mach.step = mach.step_AcceptValue + return false, nil + default: + return true, fmt.Errorf("unexpected token %s; expected key string or end of map", tok) + } +} + +func (mach *unmarshalMachineMapStringWildcard) mustAcceptKey(key_rv reflect.Value) error { + if exists := mach.target_rv.MapIndex(key_rv).IsValid(); exists { + return fmt.Errorf("repeated key %q", key_rv) + } + return nil +} + +func (mach *unmarshalMachineMapStringWildcard) step_AcceptValue(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + mach.step = mach.step_AcceptKey + mach.tmp_rv.Set(reflect.Zero(mach.value_rt)) + mach.haveValue = true + return false, driver.Recurse( + tok, + mach.tmp_rv, + mach.value_rt, + mach.valueMach, + ) +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalSlab.go b/vendor/github.com/polydawn/refmt/obj/unmarshalSlab.go new file mode 100644 index 00000000..ac09c16c --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalSlab.go @@ -0,0 +1,187 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +/* + A lovely mechanism to stash unmarshalMachine objects pre-allocated and avoid mallocs. + Works together with the Atlas: the Atlas says what kind of machinery is needed; + the unmarshalSlab "allocates" it and returns it upon your request. +*/ +type unmarshalSlab struct { + atlas atlas.Atlas + rows []unmarshalSlabRow +} + +type unmarshalSlabRow struct { + ptrDerefDelegateUnmarshalMachine + unmarshalMachinePrimitive + unmarshalMachineWildcard + unmarshalMachineMapStringWildcard + unmarshalMachineSliceWildcard + unmarshalMachineArrayWildcard + unmarshalMachineStructAtlas + unmarshalMachineTransform + unmarshalMachineUnionKeyed + + errThunkUnmarshalMachine +} + +/* + Return a reference to a machine from the slab. + *You must release() when done.* + + Errors -- including "no info in Atlas for this type" -- are expressed by + returning a machine that is a constantly-erroring thunk. +*/ +func (slab *unmarshalSlab) requisitionMachine(rt reflect.Type) UnmarshalMachine { + // Acquire a row. + off := len(slab.rows) + slab.grow() + row := &slab.rows[off] + + // Indirect pointers as necessary. + // Keep count of how many times we do this; we'll use this again at the end. + peelCount := 0 + for rt.Kind() == reflect.Ptr { + rt = rt.Elem() + peelCount++ + } + + // Figure out what machinery to use at heart. + mach := _yieldUnmarshalMachinePtr(row, slab.atlas, rt) + // If nil answer, we had no match: yield an error thunk. + if mach == nil { + mach := &row.errThunkUnmarshalMachine + mach.err = fmt.Errorf("no machine found") + return mach + } + + // If no indirection steps, return; + // otherwise wrap it in the ptrDeref machine and return that. + if peelCount == 0 { + return mach + } + row.ptrDerefDelegateUnmarshalMachine.UnmarshalMachine = mach + row.ptrDerefDelegateUnmarshalMachine.peelCount = peelCount + return &row.ptrDerefDelegateUnmarshalMachine +} + +func _yieldUnmarshalMachinePtr(row *unmarshalSlabRow, atl atlas.Atlas, rt reflect.Type) UnmarshalMachine { + rtid := reflect.ValueOf(rt).Pointer() + + // Check primitives first; cheapest (and unoverridable). + switch rtid { + case rtid_bool, + rtid_string, + rtid_int, rtid_int8, rtid_int16, rtid_int32, rtid_int64, + rtid_uint, rtid_uint8, rtid_uint16, rtid_uint32, rtid_uint64, rtid_uintptr, + rtid_float32, rtid_float64, + rtid_bytes: + row.unmarshalMachinePrimitive.kind = rt.Kind() + return &row.unmarshalMachinePrimitive + } + + // Consult atlas second. + if entry, ok := atl.Get(rtid); ok { + return _yieldUnmarshalMachinePtrForAtlasEntry(row, entry, atl) + } + + // If no specific behavior found, use default behavior based on kind. + switch rt.Kind() { + + case reflect.Bool, + reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64: + row.unmarshalMachinePrimitive.kind = rt.Kind() + return &row.unmarshalMachinePrimitive + case reflect.Slice: + // un-typedef'd byte slices were handled already, but a typedef'd one still gets gets treated like a special kind: + if rt.Elem().Kind() == reflect.Uint8 { + row.unmarshalMachinePrimitive.kind = rt.Kind() + return &row.unmarshalMachinePrimitive + } + return &row.unmarshalMachineSliceWildcard + case reflect.Array: + // arrays of bytes have a similar special case to slices for when they're typedefed. + if rt.Elem().Kind() == reflect.Uint8 { + row.unmarshalMachinePrimitive.kind = rt.Kind() + return &row.unmarshalMachinePrimitive + } + return &row.unmarshalMachineArrayWildcard + case reflect.Map: + return &row.unmarshalMachineMapStringWildcard + case reflect.Struct: + // TODO here we could also invoke automatic atlas autogen, if configured to be permitted + mach := &row.errThunkUnmarshalMachine + mach.err = fmt.Errorf("missing an atlas entry describing how to unmarshal type %v (and auto-atlasing for structs is not enabled)", rt) + return mach + case reflect.Interface: + return &row.unmarshalMachineWildcard + case reflect.Func: + panic(fmt.Errorf("functions cannot be unmarshalled!")) + case reflect.Ptr: + panic(fmt.Errorf("unreachable: ptrs must already be resolved")) + default: + panic(fmt.Errorf("excursion %s", rt.Kind())) + } +} + +// given that we already have an atlasEntry in mind, yield a configured machine for it. +// it seems odd that this might still require a whole atlas, but tis so; +// some things (e.g. transform funcs) need to get additional machinery for delegation. +func _yieldUnmarshalMachinePtrForAtlasEntry(row *unmarshalSlabRow, entry *atlas.AtlasEntry, atl atlas.Atlas) UnmarshalMachine { + // Switch across which of the union of configurations is applicable. + switch { + case entry.UnmarshalTransformFunc != nil: + // Return a machine that calls the func(s), then later a real machine. + // The entry.UnmarshalTransformTargetType is used to do a recursive lookup. + // We can't just call the func here because we're still working off typeinfo + // and don't have a real value to transform until later. + row.unmarshalMachineTransform.trFunc = entry.UnmarshalTransformFunc + row.unmarshalMachineTransform.recv_rt = entry.UnmarshalTransformTargetType + // Pick delegate without growing stack. (This currently means recursive transform won't fly.) + row.unmarshalMachineTransform.delegate = _yieldUnmarshalMachinePtr(row, atl, entry.UnmarshalTransformTargetType) + return &row.unmarshalMachineTransform + case entry.StructMap != nil: + row.unmarshalMachineStructAtlas.cfg = entry + return &row.unmarshalMachineStructAtlas + case entry.UnionKeyedMorphism != nil: + row.unmarshalMachineUnionKeyed.cfg = entry.UnionKeyedMorphism + return &row.unmarshalMachineUnionKeyed + default: + panic("invalid atlas entry") + } +} + +// Returns the top row of the slab. Useful for machines that need to delegate +// to another type that's definitely not their own (comes up for the wildcard delegators). +func (s *unmarshalSlab) tip() *unmarshalSlabRow { + return &s.rows[len(s.rows)-1] +} + +func (s *unmarshalSlab) grow() { + s.rows = append(s.rows, unmarshalSlabRow{}) +} + +func (s *unmarshalSlab) release() { + s.rows = s.rows[0 : len(s.rows)-1] +} + +type errThunkUnmarshalMachine struct { + err error +} + +func (m *errThunkUnmarshalMachine) Reset(_ *unmarshalSlab, _ reflect.Value, _ reflect.Type) error { + return m.err +} +func (m *errThunkUnmarshalMachine) Step(d *Unmarshaller, s *unmarshalSlab, tok *Token) (done bool, err error) { + return true, m.err +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalSliceWildcard.go b/vendor/github.com/polydawn/refmt/obj/unmarshalSliceWildcard.go new file mode 100644 index 00000000..513441d7 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalSliceWildcard.go @@ -0,0 +1,81 @@ +package obj + +import ( + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineSliceWildcard struct { + target_rv reflect.Value // target slice handle + working_rv reflect.Value // working slice (target is set to this at end) + value_rt reflect.Type + valueZero_rv reflect.Value // a zero of the slice's value type (for kicking append) + valueMach UnmarshalMachine + step unmarshalMachineStep + index int +} + +func (mach *unmarshalMachineSliceWildcard) Reset(slab *unmarshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.working_rv = rv + mach.value_rt = rt.Elem() + mach.valueZero_rv = reflect.Zero(mach.value_rt) + mach.valueMach = slab.requisitionMachine(mach.value_rt) + mach.step = mach.step_Initial + mach.index = 0 + return nil +} + +func (mach *unmarshalMachineSliceWildcard) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + return mach.step(driver, slab, tok) +} + +func (mach *unmarshalMachineSliceWildcard) step_Initial(_ *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // If it's a special state, start an object. + // (Or, blow up if its a special state that's silly). + switch tok.Type { + case TMapOpen: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TArrOpen: + // Great. Consumed. + mach.step = mach.step_AcceptValue + // Initialize the slice. + mach.target_rv.Set(reflect.MakeSlice(mach.target_rv.Type(), 0, 0)) + return false, nil + case TMapClose: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TArrClose: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + case TNull: + mach.target_rv.Set(reflect.Zero(mach.target_rv.Type())) + return true, nil + default: + return true, ErrMalformedTokenStream{tok.Type, "start of array"} + } +} + +func (mach *unmarshalMachineSliceWildcard) step_AcceptValue(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // Either form of open token are valid, but + // - an arrClose is ours + // - and a mapClose is clearly invalid. + switch tok.Type { + case TMapClose: + // no special checks for ends of wildcard slice; no such thing as incomplete. + return true, ErrMalformedTokenStream{tok.Type, "start of value or end of array"} + case TArrClose: + mach.target_rv.Set(mach.working_rv) + // release the slab row we requisitioned for our value machine. + slab.release() + return true, nil + } + + // Grow the slice if necessary. + mach.working_rv = reflect.Append(mach.working_rv, mach.valueZero_rv) + + // Recurse on a handle to the next index. + rv := mach.working_rv.Index(mach.index) + mach.index++ + return false, driver.Recurse(tok, rv, mach.value_rt, mach.valueMach) + // Step simply remains `step_AcceptValue` -- arrays don't have much state machine. +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalStruct.go b/vendor/github.com/polydawn/refmt/obj/unmarshalStruct.go new file mode 100644 index 00000000..f05da75d --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalStruct.go @@ -0,0 +1,109 @@ +package obj + +import ( + "fmt" + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineStructAtlas struct { + cfg *atlas.AtlasEntry // set on initialization + + rv reflect.Value + expectLen int // Length header from mapOpen token. If it was set, we validate it. + index int // Progress marker: our distance into the stream of pairs. + value bool // Progress marker: whether the next token is a value. + fieldEntry atlas.StructMapEntry // Which field we expect next: set when consuming a key. +} + +func (mach *unmarshalMachineStructAtlas) Reset(_ *unmarshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.rv = rv + // not necessary to reset expectLen because MapOpen tokens also consistently use the -1 convention. + mach.index = -1 + mach.value = false + return nil +} + +func (mach *unmarshalMachineStructAtlas) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // Starter state. + if mach.index < 0 { + switch tok.Type { + case TMapOpen: + // Great. Consumed. + mach.expectLen = tok.Length + mach.index++ + return false, nil + case TMapClose: + return true, ErrMalformedTokenStream{tok.Type, "start of map"} + case TArrOpen: + return true, ErrMalformedTokenStream{tok.Type, "start of map"} + case TArrClose: + return true, ErrMalformedTokenStream{tok.Type, "start of map"} + case TNull: + mach.rv.Set(reflect.Zero(mach.rv.Type())) + return true, nil + default: + return true, ErrMalformedTokenStream{tok.Type, "start of map"} + } + } + + // Accept value: + if mach.value { + var child_rv reflect.Value + var child_rt reflect.Type + if mach.fieldEntry.Ignore { + // Use a dummy slot to slurp up the value. This could be more efficient. + child_rt = reflect.TypeOf((*interface{})(nil)).Elem() + child_rv = reflect.New(child_rt).Elem() + } else { + child_rt = mach.fieldEntry.Type + child_rv = mach.fieldEntry.ReflectRoute.TraverseToValue(mach.rv) + } + mach.index++ + mach.value = false + return false, driver.Recurse( + tok, + child_rv, + child_rt, + slab.requisitionMachine(child_rt), + ) + } + + // Accept key or end: + if mach.index > 0 { + slab.release() + } + switch tok.Type { + case TMapClose: + // If we got length header, validate that; error if mismatch. + if mach.expectLen >= 0 { + if mach.expectLen != mach.index { + return true, fmt.Errorf("malformed map token stream: declared length %d, actually got %d entries", mach.expectLen, mach.index) + } + } + + // Future: this would be a reasonable place to check that all required fields have been filled in, if we add such a feature. + + return true, nil + case TString: + for n := 0; n < len(mach.cfg.StructMap.Fields); n++ { + fieldEntry := mach.cfg.StructMap.Fields[n] + if fieldEntry.SerialName != tok.Str { + continue + } + mach.fieldEntry = fieldEntry + mach.value = true + break + } + if mach.value == false { + // FUTURE: it should be configurable per atlas.StructMap whether this is considered an error or to be tolerated. + // Currently we're being extremely strict about it, which is a divergence from the stdlib json behavior. + return true, ErrNoSuchField{tok.Str, mach.cfg.Type.String()} + } + default: + return true, ErrMalformedTokenStream{tok.Type, "map key"} + } + return false, nil +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalTransform.go b/vendor/github.com/polydawn/refmt/obj/unmarshalTransform.go new file mode 100644 index 00000000..961e3424 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalTransform.go @@ -0,0 +1,38 @@ +package obj + +import ( + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineTransform struct { + trFunc atlas.UnmarshalTransformFunc + recv_rt reflect.Type + delegate UnmarshalMachine // machine for handling the recv type, stepped to completion before transform applied. + + target_rv reflect.Value // given on Reset, retained until last step, and set into after using trFunc + recv_rv reflect.Value // if set, handle to slot where slice is stored; content must be placed into target at end. +} + +func (mach *unmarshalMachineTransform) Reset(slab *unmarshalSlab, rv reflect.Value, _ reflect.Type) error { + mach.target_rv = rv + mach.recv_rv = reflect.New(mach.recv_rt).Elem() // REVIEW: this behavior with ptr vs not for in_rt. the star-star case is prob not what want. + return mach.delegate.Reset(slab, mach.recv_rv, mach.recv_rt) +} + +func (mach *unmarshalMachineTransform) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + done, err = mach.delegate.Step(driver, slab, tok) + if err != nil { + return + } + if !done { + return + } + // on the last step, use transform, and finally set in real target. + tr_rv, err := mach.trFunc(mach.recv_rv) + // do attempt the set even if error. user may appreciate partial progress. + mach.target_rv.Set(tr_rv) + return true, err +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalUnionKeyed.go b/vendor/github.com/polydawn/refmt/obj/unmarshalUnionKeyed.go new file mode 100644 index 00000000..06269cfa --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalUnionKeyed.go @@ -0,0 +1,90 @@ +package obj + +import ( + "reflect" + + "github.com/polydawn/refmt/obj/atlas" + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineUnionKeyed struct { + cfg *atlas.UnionKeyedMorphism // set on initialization + + target_rv reflect.Value + target_rt reflect.Type + + step unmarshalMachineStep + tmp_rv reflect.Value + delegate UnmarshalMachine // actual machine, once we've demuxed with the second token (the key). +} + +func (mach *unmarshalMachineUnionKeyed) Reset(_ *unmarshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.target_rt = rt + mach.step = mach.acceptMapOpen + return nil +} + +func (mach *unmarshalMachineUnionKeyed) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + return mach.step(driver, slab, tok) +} + +func (mach *unmarshalMachineUnionKeyed) acceptMapOpen(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + switch tok.Type { + case TMapOpen: + switch tok.Length { + case -1: // pass + case 1: // correct + default: + return true, ErrMalformedTokenStream{tok.Type, "unions in keyed format must be maps with exactly one entry"} // FIXME not malformed per se + } + mach.step = mach.acceptKey + return false, nil + // REVIEW: is case TNull perhaps conditionally acceptable? + default: + return true, ErrMalformedTokenStream{tok.Type, "start of union value"} // FIXME not malformed per se + } +} + +func (mach *unmarshalMachineUnionKeyed) acceptKey(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + switch tok.Type { + case TString: + // Look up the configuration for this key. + delegateAtlasEnt, ok := mach.cfg.Elements[tok.Str] + if !ok { + return true, ErrNoSuchUnionMember{tok.Str, mach.target_rt, mach.cfg.KnownMembers} + } + // Allocate a new concrete value, and hang on to that rv handle. + // Assigning into the interface must be done at the end if it's a non-pointer. + mach.tmp_rv = reflect.New(delegateAtlasEnt.Type).Elem() + // Get and configure a machine for the delegation. + delegate := _yieldUnmarshalMachinePtrForAtlasEntry(slab.tip(), delegateAtlasEnt, slab.atlas) + if err := delegate.Reset(slab, mach.tmp_rv, delegateAtlasEnt.Type); err != nil { + return true, err + } + mach.delegate = delegate + mach.step = mach.doDelegate + return false, nil + default: + return true, ErrMalformedTokenStream{tok.Type, "map key"} + } +} + +func (mach *unmarshalMachineUnionKeyed) doDelegate(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + done, err = mach.delegate.Step(driver, slab, tok) + if done && err == nil { + mach.step = mach.acceptMapClose + return false, nil + } + return +} + +func (mach *unmarshalMachineUnionKeyed) acceptMapClose(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + switch tok.Type { + case TMapClose: + mach.target_rv.Set(mach.tmp_rv) + return true, nil + default: + return true, ErrMalformedTokenStream{tok.Type, "map close at end of union value"} + } +} diff --git a/vendor/github.com/polydawn/refmt/obj/unmarshalWildcard.go b/vendor/github.com/polydawn/refmt/obj/unmarshalWildcard.go new file mode 100644 index 00000000..4d99c0af --- /dev/null +++ b/vendor/github.com/polydawn/refmt/obj/unmarshalWildcard.go @@ -0,0 +1,112 @@ +package obj + +import ( + "fmt" + "reflect" + + . "github.com/polydawn/refmt/tok" +) + +type unmarshalMachineWildcard struct { + target_rv reflect.Value + target_rt reflect.Type + delegate UnmarshalMachine // actual machine, once we've demuxed with the first token. + holder_rv reflect.Value // if set, handle to slot where slice is stored; content must be placed into target at end. +} + +func (mach *unmarshalMachineWildcard) Reset(_ *unmarshalSlab, rv reflect.Value, rt reflect.Type) error { + mach.target_rv = rv + mach.target_rt = rt + mach.delegate = nil + mach.holder_rv = reflect.Value{} + return nil +} + +func (mach *unmarshalMachineWildcard) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + if mach.delegate == nil { + done, err = mach.prepareDemux(driver, slab, tok) + if done { + return + } + } + done, err = mach.delegate.Step(driver, slab, tok) + if !done { + return + } + if mach.holder_rv.IsValid() { + mach.target_rv.Set(mach.holder_rv) + } + return +} + +func (mach *unmarshalMachineWildcard) prepareDemux(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) { + // If a "tag" is set in the token, we try to follow that as a hint for + // any specifically customized behaviors for how this should be unmarshalled. + if tok.Tagged == true { + atlasEntry, exists := slab.atlas.GetEntryByTag(tok.Tag) + if !exists { + return true, fmt.Errorf("missing an unmarshaller for tag %v", tok.Tag) + } + value_rt := atlasEntry.Type + mach.holder_rv = reflect.New(value_rt).Elem() + mach.delegate = _yieldUnmarshalMachinePtr(slab.tip(), slab.atlas, value_rt) + if err := mach.delegate.Reset(slab, mach.holder_rv, value_rt); err != nil { + return true, err + } + return false, nil + } + + // Switch on token type: we may be able to delegate to a primitive machine, + // but we may also need to initialize a container type and then hand off. + switch tok.Type { + case TMapOpen: + child := make(map[string]interface{}) + child_rv := reflect.ValueOf(child) + mach.target_rv.Set(child_rv) + mach.delegate = &slab.tip().unmarshalMachineMapStringWildcard + if err := mach.delegate.Reset(slab, child_rv, child_rv.Type()); err != nil { + return true, err + } + return false, nil + + case TArrOpen: + // Stdlib has very interesting branch here: 'case reflect.Interface: if v.NumMethod() == 0 {' + // If that matches, it goes on a *totally different* branch that leaves the reflective path entirely forever. + // (Which is kind of interesting, because it also means it will never reuse memory there. If you wanted that.) + + // This definitely went through a few discovery steps... + // - https://play.golang.org/p/Qbtpxwh68e + // - https://play.golang.org/p/l5RQujLnDN + // - https://play.golang.org/p/Z2ilpPk0vk + // - https://play.golang.org/p/jV9VFDht6F -- finally getting somewhere good + + holder := make([]interface{}, 0) + mach.holder_rv = reflect.ValueOf(&holder).Elem() + mach.delegate = &slab.tip().unmarshalMachineSliceWildcard + if err := mach.delegate.Reset(slab, mach.holder_rv, mach.holder_rv.Type()); err != nil { + return true, err + } + return false, nil + + case TMapClose: + return true, ErrMalformedTokenStream{tok.Type, "start of value"} + + case TArrClose: + return true, ErrMalformedTokenStream{tok.Type, "start of value"} + + case TNull: + mach.target_rv.Set(reflect.Zero(mach.target_rt)) + return true, nil + + default: + // If it wasn't the start of composite, shell out to the machine for literals. + // Don't bother to replace our internal step func because literal machines are never multi-call, + // and this lets us avoid grabbing a pointer and it shuffling around. + delegateMach := slab.tip().unmarshalMachinePrimitive + delegateMach.kind = reflect.Interface + if err := delegateMach.Reset(slab, mach.target_rv, nil); err != nil { + return true, err + } + return delegateMach.Step(driver, slab, tok) + } +} diff --git a/vendor/github.com/polydawn/refmt/pretty/prettyCommon.go b/vendor/github.com/polydawn/refmt/pretty/prettyCommon.go new file mode 100644 index 00000000..4ff6d248 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/pretty/prettyCommon.go @@ -0,0 +1,49 @@ +package pretty + +var ( + decoOff = []byte("\x1B[0m") + decoType = []byte("\x1B[1;34m") + decoBrack = []byte("\x1B[0;36m") + decoTypeParam = []byte("\x1B[1;36m") + decoTag = []byte("\x1B[0;33m") + decoTagParam = []byte("\x1B[1;33m") + decoValSigil = []byte("\x1B[1;32m") + decoValString = []byte("\x1B[0;32m") +) + +var ( + wordTrue = []byte("true") + wordFalse = []byte("false") + wordNull = []byte("null") + wordArrOpenPt1 = bcat(decoType, []byte("Array"), decoBrack, []byte(" ["), decoOff) + wordArrClose = bcat(decoBrack, []byte("]"), decoOff) + wordMapOpenPt1 = bcat(decoType, []byte("Map"), decoBrack, []byte(" {"), decoOff) + wordMapClose = bcat(decoBrack, []byte("}"), decoOff) + wordColon = bcat(decoBrack, []byte(": "), decoOff) + wordTag = bcat(decoTag, []byte("_tag:"), decoTagParam) + wordTagClose = bcat(decoTag, []byte("_ "), decoOff) + wordUnknownLen = []byte("?") + wordBreak = []byte("\n\r") +) + +func indentWord(depth int) (a []byte) { + a = []byte{} + for i := 0; i < depth; i++ { + a = append(a, '\t') + } + return +} + +func bcat(bss ...[]byte) []byte { + l := 0 + for _, bs := range bss { + l += len(bs) + } + rbs := make([]byte, 0, l) + for _, bs := range bss { + rbs = append(rbs, bs...) + } + return rbs +} diff --git a/vendor/github.com/polydawn/refmt/pretty/prettyEncoder.go b/vendor/github.com/polydawn/refmt/pretty/prettyEncoder.go new file mode 100644 index 00000000..f0cb5338 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/pretty/prettyEncoder.go @@ -0,0 +1,243 @@ +package pretty + +import ( + "encoding/hex" + "fmt" + "io" + "strconv" + + . "github.com/polydawn/refmt/tok" +) + +func NewEncoder(wr io.Writer) *Encoder { + return &Encoder{ + wr: wr, + stack: make([]phase, 0, 10), + } +} + +func (d *Encoder) Reset() { + d.stack = d.stack[0:0] + d.current = phase_anyExpectValue +} + +/* + A pretty.Encoder is a TokenSink that emits pretty-printed stuff. + + The default behavior is color coded with ANSI escape sequences, so it's + snazzy looking on your terminal. +*/ +type Encoder struct { + wr io.Writer + + // Stack, tracking how many array and map opens are outstanding. + // (Values are only 'phase_mapExpectKeyOrEnd' and 'phase_arrExpectValueOrEnd'.) + stack []phase + current phase // shortcut to value at end of stack + + // Spare memory, for use in operations on leaf nodes (e.g. temp space for an int serialization). + scratch [64]byte +} + +type phase int + +const ( + phase_anyExpectValue phase = iota + phase_mapExpectKeyOrEnd + phase_mapExpectValue + phase_arrExpectValueOrEnd +) + +func (d *Encoder) Step(tok *Token) (done bool, err error) { + switch d.current { + case phase_anyExpectValue: + switch tok.Type { + case TMapOpen: + d.pushPhase(phase_mapExpectKeyOrEnd) + d.emitMapOpen(tok) + return false, nil + case TArrOpen: + d.pushPhase(phase_arrExpectValueOrEnd) + d.emitArrOpen(tok) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value") + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of value") + default: + d.emitValue(tok) + d.wr.Write(wordBreak) + return true, nil + } + case phase_mapExpectKeyOrEnd: + switch tok.Type { + case TMapOpen: + return true, fmt.Errorf("unexpected mapOpen; expected start of key or end of map") + case TArrOpen: + return true, fmt.Errorf("unexpected arrOpen; expected start of key or end of map") + case TMapClose: + d.emitMapClose(tok) + return d.popPhase() + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of key or end of map") + default: + switch tok.Type { + case TString, TInt, TUint: + d.wr.Write(indentWord(len(d.stack))) + d.emitValue(tok) + d.wr.Write(wordColon) + d.current = phase_mapExpectValue + return false, nil + default: + return true, fmt.Errorf("unexpected token of type %T; expected map key", *tok) + } + } + case phase_mapExpectValue: + switch tok.Type { + case TMapOpen: + d.pushPhase(phase_mapExpectKeyOrEnd) + d.emitMapOpen(tok) + return false, nil + case TArrOpen: + d.pushPhase(phase_arrExpectValueOrEnd) + d.emitArrOpen(tok) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value") + case TArrClose: + return true, fmt.Errorf("unexpected arrClose; expected start of value") + default: + d.current = phase_mapExpectKeyOrEnd + d.emitValue(tok) + d.wr.Write(wordBreak) + return false, nil + } + case phase_arrExpectValueOrEnd: + switch tok.Type { + case TMapOpen: + d.pushPhase(phase_mapExpectKeyOrEnd) + d.emitMapOpen(tok) + return false, nil + case TArrOpen: + d.pushPhase(phase_arrExpectValueOrEnd) + d.emitArrOpen(tok) + return false, nil + case TMapClose: + return true, fmt.Errorf("unexpected mapClose; expected start of value or end of array") + case TArrClose: + d.emitArrClose(tok) + return d.popPhase() + default: + d.wr.Write(indentWord(len(d.stack))) + d.emitValue(tok) + d.wr.Write(wordBreak) + return false, nil + } + default: + panic("Unreachable") + } +} + +func (d *Encoder) pushPhase(p phase) { + d.current = p + d.stack = append(d.stack, d.current) +} + +// Pop a phase from the stack; return 'true' if stack now empty. +func (d *Encoder) popPhase() (bool, error) { + n := len(d.stack) - 1 + if n == 0 { + return true, nil + } + if n < 0 { // the state machines are supposed to have already errored better + panic("prettyEncoder stack overpopped") + } + d.current = d.stack[n-1] + d.stack = d.stack[0:n] + return false, nil +} + +func (d *Encoder) emitMapOpen(tok *Token) { + if tok.Tagged { + d.wr.Write(wordTag) + d.wr.Write([]byte(strconv.Itoa(tok.Tag))) + d.wr.Write(wordTagClose) + } + d.wr.Write(wordMapOpenPt1) + if tok.Length < 0 { + d.wr.Write(wordUnknownLen) + } else { + d.wr.Write([]byte(strconv.Itoa(tok.Length))) + } + d.wr.Write(wordMapOpenPt2) + d.wr.Write(wordBreak) +} + +func (d *Encoder) emitMapClose(tok *Token) { + d.wr.Write(indentWord(len(d.stack) - 1)) + d.wr.Write(wordMapClose) + d.wr.Write(wordBreak) +} + +func (d *Encoder) emitArrOpen(tok *Token) { + if tok.Tagged { + d.wr.Write(wordTag) + d.wr.Write([]byte(strconv.Itoa(tok.Tag))) + d.wr.Write(wordTagClose) + } + d.wr.Write(wordArrOpenPt1) + if tok.Length < 0 { + d.wr.Write(wordUnknownLen) + } else { + d.wr.Write([]byte(strconv.Itoa(tok.Length))) + } + d.wr.Write(wordArrOpenPt2) + d.wr.Write(wordBreak) +} + +func (d *Encoder) emitArrClose(tok *Token) { + d.wr.Write(indentWord(len(d.stack) - 1)) + d.wr.Write(wordArrClose) + d.wr.Write(wordBreak) +} + +func (d *Encoder) emitValue(tok *Token) { + if tok.Tagged { + d.wr.Write(wordTag) + d.wr.Write([]byte(strconv.Itoa(tok.Tag))) + d.wr.Write(wordTagClose) + } + switch tok.Type { + case TNull: + d.wr.Write(wordNull) + case TString: + d.emitString(tok.Str) + case TBytes: + dst := make([]byte, hex.EncodedLen(len(tok.Bytes))) + hex.Encode(dst, tok.Bytes) + d.wr.Write(dst) + case TBool: + switch tok.Bool { + case true: + d.wr.Write(wordTrue) + case false: + d.wr.Write(wordFalse) + } + case TInt: + b := strconv.AppendInt(d.scratch[:0], tok.Int, 10) + d.wr.Write(b) + case TUint: + b := strconv.AppendUint(d.scratch[:0], tok.Uint, 10) + d.wr.Write(b) + case TFloat64: + b := strconv.AppendFloat(d.scratch[:0], tok.Float64, 'f', 6, 64) + d.wr.Write(b) + default: + panic(fmt.Errorf("TODO finish more pretty.Encoder primitives support: unhandled token %s", tok)) + } +} + +func (d *Encoder) writeByte(b byte) { + d.scratch[0] = b + d.wr.Write(d.scratch[0:1]) +} diff --git a/vendor/github.com/polydawn/refmt/pretty/prettyEncoderTerminals.go b/vendor/github.com/polydawn/refmt/pretty/prettyEncoderTerminals.go new file mode 100644 index 00000000..96f58688 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/pretty/prettyEncoderTerminals.go @@ -0,0 +1,82 @@ +package pretty + +import ( + "io" + "unicode/utf8" +) + +var hexStr = "0123456789abcdef" + +func (d *Encoder) emitString(s string) { + d.wr.Write(decoValSigil) + d.writeByte('"') + d.wr.Write(decoValString) + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if 0x20 <= b && b != '\\' && b != '"' { + i++ + continue + } + if start < i { + d.wr.Write([]byte(s[start:i])) + } + switch b { + case '\\', '"': + d.writeByte('\\') + d.writeByte(b) + case '\n': + d.writeByte('\\') + d.writeByte('n') + case '\r': + d.writeByte('\\') + d.writeByte('r') + case '\t': + d.writeByte('\\') + d.writeByte('t') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + d.wr.Write([]byte(`\u00`)) + d.writeByte(hexStr[b>>4]) + d.writeByte(hexStr[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + d.wr.Write([]byte(s[start:i])) + } + d.wr.Write([]byte(`\ufffd`)) + i += size + start = i + continue + } + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + if c == '\u2028' || c == '\u2029' { + if start < i { + d.wr.Write([]byte(s[start:i])) + } + d.wr.Write([]byte(`\u202`)) + d.writeByte(hexStr[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + io.WriteString(d.wr, s[start:]) + } + d.wr.Write(decoValSigil) + d.writeByte('"') + d.wr.Write(decoOff) +} diff --git a/vendor/github.com/polydawn/refmt/raceway.formula b/vendor/github.com/polydawn/refmt/raceway.formula new file mode 100644 index 00000000..a9c71c16 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/raceway.formula @@ -0,0 +1,20 @@ +inputs: + "/": + type: "tar" + hash: "aLMH4qK1EdlPDavdhErOs0BPxqO0i6lUaeRE4DuUmnNMxhHtF56gkoeSulvwWNqT" + silo: "http+ca://repeatr.s3.amazonaws.com/assets/" + "/app/go": + type: "tar" + hash: "vg5TMw0aRSIQGPybkhMvZmwwI6rzAz6CoAOC0ecUUY02Cn2_7x9GM2DclHXutEPH" + silo: "https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz" +action: + command: + - "/bin/bash" + - "-c" + - | + set -euo pipefail + export GOROOT=/app/go/go + export PATH=$PATH:/app/go/go/bin + + ./goad fmt + ./goad test diff --git a/vendor/github.com/polydawn/refmt/shared/pump.go b/vendor/github.com/polydawn/refmt/shared/pump.go new file mode 100644 index 00000000..106de658 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/shared/pump.go @@ -0,0 +1,46 @@ +/* + The `shared` package defines helper types and functions used + internally by all the other refmt packages; it is not user-facing. +*/ +package shared + +import ( + "fmt" + + . "github.com/polydawn/refmt/tok" +) + +type TokenSource interface { + Step(fillme *Token) (done bool, err error) +} + +type TokenSink interface { + Step(consume *Token) (done bool, err error) +} + +type TokenPump struct { + TokenSource + TokenSink +} + +func (p TokenPump) Run() error { + var tok Token + var srcDone, sinkDone bool + var err error + for { + srcDone, err = p.TokenSource.Step(&tok) + if err != nil { + return err + } + sinkDone, err = p.TokenSink.Step(&tok) + if err != nil { + return err + } + if srcDone { + if sinkDone { + return nil + } + return fmt.Errorf("src at end of item but sink expects more") + } + } +} diff --git a/vendor/github.com/polydawn/refmt/shared/reader.go b/vendor/github.com/polydawn/refmt/shared/reader.go new file mode 100644 index 00000000..5059c971 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/shared/reader.go @@ -0,0 +1,301 @@ +package shared + +import ( + "bytes" + "errors" + "io" +) + +const ( + scratchByteArrayLen = 32 +) + +var ( + zeroByteSlice = []byte{}[:0:0] +) + +var ( + _ SlickReader = &SlickReaderStream{} + _ SlickReader = &SlickReaderSlice{} +) + +func NewReader(r io.Reader) SlickReader { + return &SlickReaderStream{br: &readerToScanner{r: r}} +} + +func NewBytesReader(buf *bytes.Buffer) SlickReader { + return &SlickReaderStream{br: buf} +} + +func NewSliceReader(b []byte) SlickReader { + return &SlickReaderSlice{b: b} +} + +// SlickReader is a hybrid of reader and buffer interfaces with methods giving +// specific attention to the performance needs found in a decoder. +// Implementations cover io.Reader as well as []byte directly. +// +// In particular, it allows: +// +// - returning byte-slices with zero-copying (you were warned!) when possible +// - returning byte-slices for short reads which will be reused (you were warned!) +// - putting a 'track' point in the buffer, and later yielding all those bytes at once +// - counting the number of bytes read (for use in parser error messages, mainly) +// +// All of these shortcuts mean correct usage is essential to avoid unexpected behaviors, +// but in return allow avoiding many, many common sources of memory allocations in a parser. +type SlickReader interface { + + // Read n bytes into a byte slice which may be shared and must not be reused + // After any additional calls to this reader. + // Readnzc will use the implementation scratch buffer if possible, + // i.e. n < len(scratchbuf), or may return a view of the []byte being decoded from. + // Requesting a zero length read will return `zeroByteSlice`, a len-zero cap-zero slice. + Readnzc(n int) ([]byte, error) + + // Read n bytes into a new byte slice. + // If zero-copy views into existing buffers are acceptable (e.g. you know you + // won't later mutate, reference or expose this memory again), prefer `Readnzc`. + // If you already have an existing slice of sufficient size to reuse, prefer `Readb`. + // Requesting a zero length read will return `zeroByteSlice`, a len-zero cap-zero slice. + Readn(n int) ([]byte, error) + + // Read `len(b)` bytes into the given slice, starting at its beginning, + // overwriting all values, and disregarding any extra capacity. + Readb(b []byte) error + + Readn1() (uint8, error) + Unreadn1() + NumRead() int // number of bytes read + Track() + StopTrack() []byte +} + +// SlickReaderStream is a SlickReader that reads off an io.Reader. +// Initialize it by wrapping an ioDecByteScanner around your io.Reader and dumping it in. +// While this implementation does use some internal buffers, it's still advisable +// to use a buffered reader to avoid small reads for any external IO like disk or network. +type SlickReaderStream struct { + br readerScanner + scratch [scratchByteArrayLen]byte // temp byte array re-used internally for efficiency during read. + n int // num read + tracking []byte // tracking bytes read + isTracking bool +} + +func (z *SlickReaderStream) NumRead() int { + return z.n +} + +func (z *SlickReaderStream) Readnzc(n int) (bs []byte, err error) { + if n == 0 { + return zeroByteSlice, nil + } + if n < len(z.scratch) { + bs = z.scratch[:n] + } else { + bs = make([]byte, n) + } + err = z.Readb(bs) + return +} + +func (z *SlickReaderStream) Readn(n int) (bs []byte, err error) { + if n == 0 { + return zeroByteSlice, nil + } + bs = make([]byte, n) + err = z.Readb(bs) + return +} + +func (z *SlickReaderStream) Readb(bs []byte) error { + if len(bs) == 0 { + return nil + } + n, err := io.ReadAtLeast(z.br, bs, len(bs)) + z.n += n + if z.isTracking { + z.tracking = append(z.tracking, bs...) + } + return err +} + +func (z *SlickReaderStream) Readn1() (b uint8, err error) { + b, err = z.br.ReadByte() + if err != nil { + return + } + z.n++ + if z.isTracking { + z.tracking = append(z.tracking, b) + } + return +} + +func (z *SlickReaderStream) Unreadn1() { + err := z.br.UnreadByte() + if err != nil { + panic(err) + } + z.n-- + if z.isTracking { + if l := len(z.tracking) - 1; l >= 0 { + z.tracking = z.tracking[:l] + } + } +} + +func (z *SlickReaderStream) Track() { + if z.tracking != nil { + z.tracking = z.tracking[:0] + } + z.isTracking = true +} + +func (z *SlickReaderStream) StopTrack() (bs []byte) { + z.isTracking = false + return z.tracking +} + +// SlickReaderSlice implements SlickReader by reading a byte slice directly. +// Often this means the zero-copy methods can simply return subslices. +type SlickReaderSlice struct { + b []byte // data + c int // cursor + a int // available + t int // track start +} + +func (z *SlickReaderSlice) reset(in []byte) { + z.b = in + z.a = len(in) + z.c = 0 + z.t = 0 +} + +func (z *SlickReaderSlice) NumRead() int { + return z.c +} + +func (z *SlickReaderSlice) Unreadn1() { + if z.c == 0 || len(z.b) == 0 { + panic(errors.New("cannot unread last byte read")) + } + z.c-- + z.a++ + return +} + +func (z *SlickReaderSlice) Readnzc(n int) (bs []byte, err error) { + if n == 0 { + return zeroByteSlice, nil + } else if z.a == 0 { + return zeroByteSlice, io.EOF + } else if n > z.a { + return zeroByteSlice, io.ErrUnexpectedEOF + } else { + c0 := z.c + z.c = c0 + n + z.a = z.a - n + bs = z.b[c0:z.c] + } + return +} + +func (z *SlickReaderSlice) Readn(n int) (bs []byte, err error) { + if n == 0 { + return zeroByteSlice, nil + } + bs = make([]byte, n) + err = z.Readb(bs) + return +} + +func (z *SlickReaderSlice) Readn1() (v uint8, err error) { + if z.a == 0 { + panic(io.EOF) + } + v = z.b[z.c] + z.c++ + z.a-- + return +} + +func (z *SlickReaderSlice) Readb(bs []byte) error { + bs2, err := z.Readnzc(len(bs)) + copy(bs, bs2) + return err +} + +func (z *SlickReaderSlice) Track() { + z.t = z.c +} + +func (z *SlickReaderSlice) StopTrack() (bs []byte) { + return z.b[z.t:z.c] +} + +// conjoin the io.Reader and io.ByteScanner interfaces. +type readerScanner interface { + io.Reader + io.ByteScanner +} + +// readerToScanner decorates an `io.Reader` with all the methods to also +// fulfill the `io.ByteScanner` interface. +type readerToScanner struct { + r io.Reader + l byte // last byte + ls byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread + b [1]byte // tiny buffer for reading single bytes +} + +func (z *readerToScanner) Read(p []byte) (n int, err error) { + var firstByte bool + if z.ls == 1 { + z.ls = 2 + p[0] = z.l + if len(p) == 1 { + n = 1 + return + } + firstByte = true + p = p[1:] + } + n, err = z.r.Read(p) + if n > 0 { + if err == io.EOF && n == len(p) { + err = nil // read was successful, so postpone EOF (till next time) + } + z.l = p[n-1] + z.ls = 2 + } + if firstByte { + n++ + } + return +} + +func (z *readerToScanner) ReadByte() (c byte, err error) { + n, err := z.Read(z.b[:]) + if n == 1 { + c = z.b[0] + if err == io.EOF { + err = nil // read was successful, so postpone EOF (till next time) + } + } + return +} + +func (z *readerToScanner) UnreadByte() (err error) { + x := z.ls + if x == 0 { + err = errors.New("cannot unread - nothing has been read") + } else if x == 1 { + err = errors.New("cannot unread - last byte has not been read") + } else if x == 2 { + z.ls = 1 + } + return +} diff --git a/vendor/github.com/polydawn/refmt/tok/token.go b/vendor/github.com/polydawn/refmt/tok/token.go new file mode 100644 index 00000000..07aae136 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/tok/token.go @@ -0,0 +1,192 @@ +/* + Package containing Token struct and TokenType info. + Tokens are the lingua-franca used between all the refmt packages. + Users typically do not refer to these types. +*/ +package tok + +import ( + "bytes" + "fmt" +) + +type Token struct { + // The type of token. Indicates which of the value fields has meaning, + // or has a special value to indicate beginnings and endings of maps and arrays. + Type TokenType + Length int // If this is a TMapOpen or TArrOpen, a length may be specified. Use -1 for unknown. + + Str string // Value union. Only one of these has meaning, depending on the value of 'Type'. + Bytes []byte // Value union. Only one of these has meaning, depending on the value of 'Type'. + Bool bool // Value union. Only one of these has meaning, depending on the value of 'Type'. + Int int64 // Value union. Only one of these has meaning, depending on the value of 'Type'. + Uint uint64 // Value union. Only one of these has meaning, depending on the value of 'Type'. + Float64 float64 // Value union. Only one of these has meaning, depending on the value of 'Type'. + + Tagged bool // Extension slot for cbor. + Tag int // Extension slot for cbor. Only applicable if tagged=true. +} + +type TokenType byte + +const ( + TMapOpen TokenType = '{' + TMapClose TokenType = '}' + TArrOpen TokenType = '[' + TArrClose TokenType = ']' + TNull TokenType = '0' + + TString TokenType = 's' + TBytes TokenType = 'x' + TBool TokenType = 'b' + TInt TokenType = 'i' + TUint TokenType = 'u' + TFloat64 TokenType = 'f' +) + +func (tt TokenType) String() string { + switch tt { + case TMapOpen: + return "map open" + case TMapClose: + return "map close" + case TArrOpen: + return "array open" + case TArrClose: + return "array close" + case TNull: + return "null" + case TString: + return "string" + case TBytes: + return "bytes" + case TBool: + return "bool" + case TInt: + return "int" + case TUint: + return "uint" + case TFloat64: + return "float" + } + return "invalid" +} + +func (tt TokenType) IsValid() bool { + switch tt { + case TString, TBytes, TBool, TInt, TUint, TFloat64, TNull: + return true + case TMapOpen, TMapClose, TArrOpen, TArrClose: + return true + default: + return false + } +} + +func (tt TokenType) IsValue() bool { + switch tt { + case TString, TBytes, TBool, TInt, TUint, TFloat64: + return true + default: + return false + } +} + +func (tt TokenType) IsSpecial() bool { + switch tt { + case TMapOpen, TMapClose, TArrOpen, TArrClose, TNull: + return true + default: + return false + } +} + +/* + Checks if the content of two tokens is the same. + Tokens are considered the same if their type one of the special + consts (map/array open/close) and that type and the optional length field are equal; + or, if type indicates a value, then they are the same if those values are equal. + In either path, values that are *not* specified as relevant by the Token's Type + are disregarded in the comparison. + + If the Token.Type is not valid, the result will be false. + + This method is primarily useful for testing. +*/ +func IsTokenEqual(t1, t2 Token) bool { + if t1.Type != t2.Type { + return false + } + switch t1.Type { + case TMapOpen, TArrOpen: + return t1.Length == t2.Length + case TMapClose, TArrClose, TNull: + return true + case TString, TBool, TInt, TUint, TFloat64: + return t1.Value() == t2.Value() + case TBytes: + return bytes.Equal(t1.Bytes, t2.Bytes) + default: + return false + } +} + +// Returns the value attached to this token, or nil. +// This boxes the value into an `interface{}`, which almost certainly +// incurs a memory allocation via `runtime.convT2E` in the process, +// so this this method should not be used when performance is a concern. +func (t Token) Value() interface{} { + switch t.Type { + case TString: + return t.Str + case TBytes: + return t.Bytes + case TBool: + return t.Bool + case TInt: + return t.Int + case TUint: + return t.Uint + case TFloat64: + return t.Float64 + default: + return nil + } +} + +func (t Token) String() string { + if !t.Tagged { + return t.StringSansTag() + } + return fmt.Sprintf("_%d:%s", t.Tag, t.StringSansTag()) +} + +func (t Token) StringSansTag() string { + switch t.Type { + case TMapOpen: + if t.Length == -1 { + return "<{>" + } + return fmt.Sprintf("<{:%d>", t.Length) + case TMapClose: + return "<}>" + case TArrOpen: + if t.Length == -1 { + return "<[>" + } + return fmt.Sprintf("<[:%d>", t.Length) + case TArrClose: + return "<]>" + case TNull: + return "<0>" + case TString: + return fmt.Sprintf("<%c:%q>", t.Type, t.Value()) + } + if t.Type.IsValue() { + return fmt.Sprintf("<%c:%v>", t.Type, t.Value()) + } + return "" +} + +func TokStr(x string) Token { return Token{Type: TString, Str: x} } // Util for testing. +func TokInt(x int64) Token { return Token{Type: TInt, Int: x} } // Util for testing. diff --git a/vendor/github.com/polydawn/refmt/unmarshalHelpers.go b/vendor/github.com/polydawn/refmt/unmarshalHelpers.go new file mode 100644 index 00000000..3ebf9ef6 --- /dev/null +++ b/vendor/github.com/polydawn/refmt/unmarshalHelpers.go @@ -0,0 +1,61 @@ +package refmt + +import ( + "io" + + "github.com/polydawn/refmt/cbor" + "github.com/polydawn/refmt/json" + "github.com/polydawn/refmt/obj/atlas" +) + +type DecodeOptions interface { + IsDecodeOptions() // marker method. +} + +func Unmarshal(opts DecodeOptions, data []byte, v interface{}) error { + switch o2 := opts.(type) { + case json.DecodeOptions: + return json.Unmarshal(data, v) + case cbor.DecodeOptions: + return cbor.Unmarshal(o2, data, v) + default: + panic("incorrect usage: unknown DecodeOptions type") + } +} + +func UnmarshalAtlased(opts DecodeOptions, data []byte, v interface{}, atl atlas.Atlas) error { + switch o2 := opts.(type) { + case json.DecodeOptions: + return json.UnmarshalAtlased(data, v, atl) + case cbor.DecodeOptions: + return cbor.UnmarshalAtlased(o2, data, v, atl) + default: + panic("incorrect usage: unknown DecodeOptions type") + } +} + +type Unmarshaller interface { + Unmarshal(v interface{}) error +} + +func NewUnmarshaller(opts DecodeOptions, r io.Reader) Unmarshaller { + switch o2 := opts.(type) { + case json.DecodeOptions: + return json.NewUnmarshaller(r) + case cbor.DecodeOptions: + return cbor.NewUnmarshaller(o2, r) + default: + panic("incorrect usage: unknown DecodeOptions type") + } +} + +func NewUnmarshallerAtlased(opts DecodeOptions, r io.Reader, atl atlas.Atlas) Unmarshaller { + switch o2 := opts.(type) { + case json.DecodeOptions: + return json.NewUnmarshallerAtlased(r, atl) + case cbor.DecodeOptions: + return cbor.NewUnmarshallerAtlased(o2, r, atl) + default: + panic("incorrect usage: unknown DecodeOptions type") + } +} diff --git a/vendor/github.com/prometheus/tsdb/LICENSE b/vendor/github.com/prometheus/tsdb/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/prometheus/tsdb/fileutil/dir_unix.go b/vendor/github.com/prometheus/tsdb/fileutil/dir_unix.go new file mode 100644 index 00000000..58a77dfc --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/dir_unix.go @@ -0,0 +1,22 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package fileutil + +import "os" + +// OpenDir opens a directory for syncing. +func OpenDir(path string) (*os.File, error) { return os.Open(path) } diff --git a/vendor/github.com/prometheus/tsdb/fileutil/dir_windows.go b/vendor/github.com/prometheus/tsdb/fileutil/dir_windows.go new file mode 100644 index 00000000..c123395c --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/dir_windows.go @@ -0,0 +1,46 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package fileutil + +import ( + "os" + "syscall" +) + +// OpenDir opens a directory in windows with write access for syncing. +func OpenDir(path string) (*os.File, error) { + fd, err := openDir(path) + if err != nil { + return nil, err + } + return os.NewFile(uintptr(fd), path), nil +} + +func openDir(path string) (fd syscall.Handle, err error) { + if len(path) == 0 { + return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND + } + pathp, err := syscall.UTF16PtrFromString(path) + if err != nil { + return syscall.InvalidHandle, err + } + access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE) + sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE) + createmode := uint32(syscall.OPEN_EXISTING) + fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS) + return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0) +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/fileutil.go b/vendor/github.com/prometheus/tsdb/fileutil/fileutil.go new file mode 100644 index 00000000..c55a2b81 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/fileutil.go @@ -0,0 +1,149 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package fileutil provides utility methods used when dealing with the filesystem in tsdb. +// It is largely copied from github.com/coreos/etcd/pkg/fileutil to avoid the +// dependency chain it brings with it. +// Please check github.com/coreos/etcd for licensing information. +package fileutil + +import ( + "io/ioutil" + "os" + "path/filepath" + "sort" + "strings" +) + +// CopyDirs copies all directories, subdirectories and files recursively including the empty folders. +// Source and destination must be full paths. +func CopyDirs(src, dest string) error { + if err := os.MkdirAll(dest, 0777); err != nil { + return err + } + files, err := readDirs(src) + if err != nil { + return err + } + + for _, f := range files { + dp := filepath.Join(dest, f) + sp := filepath.Join(src, f) + + stat, err := os.Stat(sp) + if err != nil { + return err + } + + // Empty directories are also created. + if stat.IsDir() { + if err := os.MkdirAll(dp, 0777); err != nil { + return err + } + continue + } + + if err := copyFile(sp, dp); err != nil { + return err + } + } + return nil +} + +func copyFile(src, dest string) error { + data, err := ioutil.ReadFile(src) + if err != nil { + return err + } + + err = ioutil.WriteFile(dest, data, 0644) + if err != nil { + return err + } + return nil +} + +// readDirs reads the source directory recursively and +// returns relative paths to all files and empty directories. +func readDirs(src string) ([]string, error) { + var files []string + + err := filepath.Walk(src, func(path string, f os.FileInfo, err error) error { + relativePath := strings.TrimPrefix(path, src) + if len(relativePath) > 0 { + files = append(files, relativePath) + } + return nil + }) + if err != nil { + return nil, err + } + return files, nil +} + +// ReadDir returns the filenames in the given directory in sorted order. +func ReadDir(dirpath string) ([]string, error) { + dir, err := os.Open(dirpath) + if err != nil { + return nil, err + } + defer dir.Close() + names, err := dir.Readdirnames(-1) + if err != nil { + return nil, err + } + sort.Strings(names) + return names, nil +} + +// Rename safely renames a file. +func Rename(from, to string) error { + if err := os.Rename(from, to); err != nil { + return err + } + + // Directory was renamed; sync parent dir to persist rename. + pdir, err := OpenDir(filepath.Dir(to)) + if err != nil { + return err + } + + if err = pdir.Sync(); err != nil { + pdir.Close() + return err + } + return pdir.Close() +} + +// Replace moves a file or directory to a new location and deletes any previous data. +// It is not atomic. +func Replace(from, to string) error { + if err := os.RemoveAll(to); err != nil { + return err + } + if err := os.Rename(from, to); err != nil { + return err + } + + // Directory was renamed; sync parent dir to persist rename. + pdir, err := OpenDir(filepath.Dir(to)) + if err != nil { + return err + } + + if err = pdir.Sync(); err != nil { + pdir.Close() + return err + } + return pdir.Close() +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/flock.go b/vendor/github.com/prometheus/tsdb/fileutil/flock.go new file mode 100644 index 00000000..d5eaa7ca --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/flock.go @@ -0,0 +1,41 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "os" + "path/filepath" +) + +// Releaser provides the Release method to release a file lock. +type Releaser interface { + Release() error +} + +// Flock locks the file with the provided name. If the file does not exist, it is +// created. The returned Releaser is used to release the lock. existed is true +// if the file to lock already existed. A non-nil error is returned if the +// locking has failed. Neither this function nor the returned Releaser is +// goroutine-safe. +func Flock(fileName string) (r Releaser, existed bool, err error) { + if err = os.MkdirAll(filepath.Dir(fileName), 0755); err != nil { + return nil, false, err + } + + _, err = os.Stat(fileName) + existed = err == nil + + r, err = newLock(fileName) + return r, existed, err +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/flock_plan9.go b/vendor/github.com/prometheus/tsdb/fileutil/flock_plan9.go new file mode 100644 index 00000000..8a3d44c5 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/flock_plan9.go @@ -0,0 +1,32 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import "os" + +type plan9Lock struct { + f *os.File +} + +func (l *plan9Lock) Release() error { + return l.f.Close() +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, os.ModeExclusive|0644) + if err != nil { + return nil, err + } + return &plan9Lock{f}, nil +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/flock_solaris.go b/vendor/github.com/prometheus/tsdb/fileutil/flock_solaris.go new file mode 100644 index 00000000..7f527ae6 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/flock_solaris.go @@ -0,0 +1,59 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build solaris + +package fileutil + +import ( + "os" + "syscall" +) + +type unixLock struct { + f *os.File +} + +func (l *unixLock) Release() error { + if err := l.set(false); err != nil { + return err + } + return l.f.Close() +} + +func (l *unixLock) set(lock bool) error { + flock := syscall.Flock_t{ + Type: syscall.F_UNLCK, + Start: 0, + Len: 0, + Whence: 1, + } + if lock { + flock.Type = syscall.F_WRLCK + } + return syscall.FcntlFlock(l.f.Fd(), syscall.F_SETLK, &flock) +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return nil, err + } + l := &unixLock{f} + err = l.set(true) + if err != nil { + f.Close() + return nil, err + } + return l, nil +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/flock_unix.go b/vendor/github.com/prometheus/tsdb/fileutil/flock_unix.go new file mode 100644 index 00000000..f493fbd8 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/flock_unix.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package fileutil + +import ( + "os" + "syscall" +) + +type unixLock struct { + f *os.File +} + +func (l *unixLock) Release() error { + if err := l.set(false); err != nil { + return err + } + return l.f.Close() +} + +func (l *unixLock) set(lock bool) error { + how := syscall.LOCK_UN + if lock { + how = syscall.LOCK_EX + } + return syscall.Flock(int(l.f.Fd()), how|syscall.LOCK_NB) +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return nil, err + } + l := &unixLock{f} + err = l.set(true) + if err != nil { + f.Close() + return nil, err + } + return l, nil +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/flock_windows.go b/vendor/github.com/prometheus/tsdb/fileutil/flock_windows.go new file mode 100644 index 00000000..1c17ff4e --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/flock_windows.go @@ -0,0 +1,36 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import "syscall" + +type windowsLock struct { + fd syscall.Handle +} + +func (fl *windowsLock) Release() error { + return syscall.Close(fl.fd) +} + +func newLock(fileName string) (Releaser, error) { + pathp, err := syscall.UTF16PtrFromString(fileName) + if err != nil { + return nil, err + } + fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) + if err != nil { + return nil, err + } + return &windowsLock{fd}, nil +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/mmap.go b/vendor/github.com/prometheus/tsdb/fileutil/mmap.go new file mode 100644 index 00000000..26fc80c5 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/mmap.go @@ -0,0 +1,61 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "os" + + "github.com/pkg/errors" +) + +type MmapFile struct { + f *os.File + b []byte +} + +func OpenMmapFile(path string) (*MmapFile, error) { + f, err := os.Open(path) + if err != nil { + return nil, errors.Wrap(err, "try lock file") + } + info, err := f.Stat() + if err != nil { + return nil, errors.Wrap(err, "stat") + } + + b, err := mmap(f, int(info.Size())) + if err != nil { + return nil, errors.Wrap(err, "mmap") + } + + return &MmapFile{f: f, b: b}, nil +} + +func (f *MmapFile) Close() error { + err0 := munmap(f.b) + err1 := f.f.Close() + + if err0 != nil { + return err0 + } + return err1 +} + +func (f *MmapFile) File() *os.File { + return f.f +} + +func (f *MmapFile) Bytes() []byte { + return f.b +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/mmap_386.go b/vendor/github.com/prometheus/tsdb/fileutil/mmap_386.go new file mode 100644 index 00000000..66b9d368 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/mmap_386.go @@ -0,0 +1,18 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package fileutil + +const maxMapSize = 0x7FFFFFFF // 2GB diff --git a/vendor/github.com/prometheus/tsdb/fileutil/mmap_amd64.go b/vendor/github.com/prometheus/tsdb/fileutil/mmap_amd64.go new file mode 100644 index 00000000..4b523bc6 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/mmap_amd64.go @@ -0,0 +1,18 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package fileutil + +const maxMapSize = 0xFFFFFFFFFFFF // 256TB diff --git a/vendor/github.com/prometheus/tsdb/fileutil/mmap_unix.go b/vendor/github.com/prometheus/tsdb/fileutil/mmap_unix.go new file mode 100644 index 00000000..043f4d40 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/mmap_unix.go @@ -0,0 +1,30 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows,!plan9 + +package fileutil + +import ( + "os" + + "golang.org/x/sys/unix" +) + +func mmap(f *os.File, length int) ([]byte, error) { + return unix.Mmap(int(f.Fd()), 0, length, unix.PROT_READ, unix.MAP_SHARED) +} + +func munmap(b []byte) (err error) { + return unix.Munmap(b) +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/mmap_windows.go b/vendor/github.com/prometheus/tsdb/fileutil/mmap_windows.go new file mode 100644 index 00000000..b9422641 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/mmap_windows.go @@ -0,0 +1,46 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "os" + "syscall" + "unsafe" +) + +func mmap(f *os.File, size int) ([]byte, error) { + low, high := uint32(size), uint32(size>>32) + h, errno := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, high, low, nil) + if h == 0 { + return nil, os.NewSyscallError("CreateFileMapping", errno) + } + + addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(size)) + if addr == 0 { + return nil, os.NewSyscallError("MapViewOfFile", errno) + } + + if err := syscall.CloseHandle(syscall.Handle(h)); err != nil { + return nil, os.NewSyscallError("CloseHandle", err) + } + + return (*[maxMapSize]byte)(unsafe.Pointer(addr))[:size], nil +} + +func munmap(b []byte) error { + if err := syscall.UnmapViewOfFile((uintptr)(unsafe.Pointer(&b[0]))); err != nil { + return os.NewSyscallError("UnmapViewOfFile", err) + } + return nil +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/preallocate.go b/vendor/github.com/prometheus/tsdb/fileutil/preallocate.go new file mode 100644 index 00000000..c747b7cf --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/preallocate.go @@ -0,0 +1,54 @@ +// Copyright 2015 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "io" + "os" +) + +// Preallocate tries to allocate the space for given +// file. This operation is only supported on linux by a +// few filesystems (btrfs, ext4, etc.). +// If the operation is unsupported, no error will be returned. +// Otherwise, the error encountered will be returned. +func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error { + if sizeInBytes == 0 { + // fallocate will return EINVAL if length is 0; skip + return nil + } + if extendFile { + return preallocExtend(f, sizeInBytes) + } + return preallocFixed(f, sizeInBytes) +} + +func preallocExtendTrunc(f *os.File, sizeInBytes int64) error { + curOff, err := f.Seek(0, io.SeekCurrent) + if err != nil { + return err + } + size, err := f.Seek(sizeInBytes, io.SeekEnd) + if err != nil { + return err + } + if _, err = f.Seek(curOff, io.SeekStart); err != nil { + return err + } + if sizeInBytes > size { + return nil + } + return f.Truncate(sizeInBytes) +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/preallocate_darwin.go b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_darwin.go new file mode 100644 index 00000000..c9fa1a6c --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_darwin.go @@ -0,0 +1,41 @@ +// Copyright 2015 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "os" + "syscall" + "unsafe" +) + +func preallocExtend(f *os.File, sizeInBytes int64) error { + if err := preallocFixed(f, sizeInBytes); err != nil { + return err + } + return preallocExtendTrunc(f, sizeInBytes) +} + +func preallocFixed(f *os.File, sizeInBytes int64) error { + fstore := &syscall.Fstore_t{ + Flags: syscall.F_ALLOCATEALL, + Posmode: syscall.F_PEOFPOSMODE, + Length: sizeInBytes} + p := unsafe.Pointer(fstore) + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_PREALLOCATE), uintptr(p)) + if errno == 0 || errno == syscall.ENOTSUP { + return nil + } + return errno +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/preallocate_linux.go b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_linux.go new file mode 100644 index 00000000..ada04622 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_linux.go @@ -0,0 +1,47 @@ +// Copyright 2015 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fileutil + +import ( + "os" + "syscall" +) + +func preallocExtend(f *os.File, sizeInBytes int64) error { + // use mode = 0 to change size + err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes) + if err != nil { + errno, ok := err.(syscall.Errno) + // not supported; fallback + // fallocate EINTRs frequently in some environments; fallback + if ok && (errno == syscall.ENOTSUP || errno == syscall.EINTR) { + return preallocExtendTrunc(f, sizeInBytes) + } + } + return err +} + +func preallocFixed(f *os.File, sizeInBytes int64) error { + // use mode = 1 to keep size; see FALLOC_FL_KEEP_SIZE + err := syscall.Fallocate(int(f.Fd()), 1, 0, sizeInBytes) + if err != nil { + errno, ok := err.(syscall.Errno) + // treat not supported as nil error + if ok && errno == syscall.ENOTSUP { + return nil + } + } + return err +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/preallocate_other.go b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_other.go new file mode 100644 index 00000000..162fbc5f --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/preallocate_other.go @@ -0,0 +1,25 @@ +// Copyright 2015 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !linux,!darwin + +package fileutil + +import "os" + +func preallocExtend(f *os.File, sizeInBytes int64) error { + return preallocExtendTrunc(f, sizeInBytes) +} + +func preallocFixed(f *os.File, sizeInBytes int64) error { return nil } diff --git a/vendor/github.com/prometheus/tsdb/fileutil/sync.go b/vendor/github.com/prometheus/tsdb/fileutil/sync.go new file mode 100644 index 00000000..2e64a408 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/sync.go @@ -0,0 +1,24 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !linux,!darwin + +package fileutil + +import "os" + +// Fdatasync is a wrapper around file.Sync(). Special handling is needed on linux platform. +func Fdatasync(f *os.File) error { + return f.Sync() +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/sync_darwin.go b/vendor/github.com/prometheus/tsdb/fileutil/sync_darwin.go new file mode 100644 index 00000000..2af1b0f4 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/sync_darwin.go @@ -0,0 +1,27 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build darwin + +package fileutil + +import ( + "os" +) + +// Fdatasync on darwin platform invokes fcntl(F_FULLFSYNC) for actual persistence +// on physical drive media. +func Fdatasync(f *os.File) error { + return f.Sync() +} diff --git a/vendor/github.com/prometheus/tsdb/fileutil/sync_linux.go b/vendor/github.com/prometheus/tsdb/fileutil/sync_linux.go new file mode 100644 index 00000000..8b4fc826 --- /dev/null +++ b/vendor/github.com/prometheus/tsdb/fileutil/sync_linux.go @@ -0,0 +1,29 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build linux + +package fileutil + +import ( + "os" + "syscall" +) + +// Fdatasync is similar to fsync(), but does not flush modified metadata +// unless that metadata is needed in order to allow a subsequent data retrieval +// to be correctly handled. +func Fdatasync(f *os.File) error { + return syscall.Fdatasync(int(f.Fd())) +} diff --git a/vendor/github.com/rjeczalik/notify/go.mod b/vendor/github.com/rjeczalik/notify/go.mod new file mode 100644 index 00000000..2bbfbf3b --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/go.mod @@ -0,0 +1,3 @@ +module github.com/rjeczalik/notify + +require golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7 diff --git a/vendor/github.com/rs/cors/README.md b/vendor/github.com/rs/cors/README.md new file mode 100644 index 00000000..ecc83b29 --- /dev/null +++ b/vendor/github.com/rs/cors/README.md @@ -0,0 +1,115 @@ +# Go CORS handler [![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/cors) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/cors/master/LICENSE) [![build](https://img.shields.io/travis/rs/cors.svg?style=flat)](https://travis-ci.org/rs/cors) [![Coverage](http://gocover.io/_badge/github.com/rs/cors)](http://gocover.io/github.com/rs/cors) + +CORS is a `net/http` handler implementing [Cross Origin Resource Sharing W3 specification](http://www.w3.org/TR/cors/) in Golang. + +## Getting Started + +After installing Go and setting up your [GOPATH](http://golang.org/doc/code.html#GOPATH), create your first `.go` file. We'll call it `server.go`. + +```go +package main + +import ( + "net/http" + + "github.com/rs/cors" +) + +func main() { + mux := http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte("{\"hello\": \"world\"}")) + }) + + // cors.Default() setup the middleware with default options being + // all origins accepted with simple methods (GET, POST). See + // documentation below for more options. + handler := cors.Default().Handler(mux) + http.ListenAndServe(":8080", handler) +} +``` + +Install `cors`: + + go get github.com/rs/cors + +Then run your server: + + go run server.go + +The server now runs on `localhost:8080`: + + $ curl -D - -H 'Origin: http://foo.com' http://localhost:8080/ + HTTP/1.1 200 OK + Access-Control-Allow-Origin: foo.com + Content-Type: application/json + Date: Sat, 25 Oct 2014 03:43:57 GMT + Content-Length: 18 + + {"hello": "world"} + +### Allow * With Credentials Security Protection + +This library has been modified to avoid a well known security issue when configured with `AllowedOrigins` to `*` and `AllowCredentials` to `true`. Such setup used to make the library reflects the request `Origin` header value, working around a security protection embedded into the standard that makes clients to refuse such configuration. This behavior has been removed with [#55](https://github.com/rs/cors/issues/55) and [#57](https://github.com/rs/cors/issues/57). + +If you depend on this behavior and understand the implications, you can restore it using the `AllowOriginFunc` with `func(origin string) {return true}`. + +Please refer to [#55](https://github.com/rs/cors/issues/55) for more information about the security implications. + +### More Examples + +* `net/http`: [examples/nethttp/server.go](https://github.com/rs/cors/blob/master/examples/nethttp/server.go) +* [Goji](https://goji.io): [examples/goji/server.go](https://github.com/rs/cors/blob/master/examples/goji/server.go) +* [Martini](http://martini.codegangsta.io): [examples/martini/server.go](https://github.com/rs/cors/blob/master/examples/martini/server.go) +* [Negroni](https://github.com/codegangsta/negroni): [examples/negroni/server.go](https://github.com/rs/cors/blob/master/examples/negroni/server.go) +* [Alice](https://github.com/justinas/alice): [examples/alice/server.go](https://github.com/rs/cors/blob/master/examples/alice/server.go) +* [HttpRouter](https://github.com/julienschmidt/httprouter): [examples/httprouter/server.go](https://github.com/rs/cors/blob/master/examples/httprouter/server.go) +* [Gorilla](http://www.gorillatoolkit.org/pkg/mux): [examples/gorilla/server.go](https://github.com/rs/cors/blob/master/examples/gorilla/server.go) +* [Buffalo](https://gobuffalo.io): [examples/buffalo/server.go](https://github.com/rs/cors/blob/master/examples/buffalo/server.go) +* [Gin](https://gin-gonic.github.io/gin): [examples/gin/server.go](https://github.com/rs/cors/blob/master/examples/gin/server.go) +* [Chi](https://github.com/go-chi/chi): [examples/chi/server.go](https://github.com/rs/cors/blob/master/examples/chi/server.go) + +## Parameters + +Parameters are passed to the middleware thru the `cors.New` method as follow: + +```go +c := cors.New(cors.Options{ + AllowedOrigins: []string{"http://foo.com", "http://foo.com:8080"}, + AllowCredentials: true, + // Enable Debugging for testing, consider disabling in production + Debug: true, +}) + +// Insert the middleware +handler = c.Handler(handler) +``` + +* **AllowedOrigins** `[]string`: A list of origins a cross-domain request can be executed from. If the special `*` value is present in the list, all origins will be allowed. An origin may contain a wildcard (`*`) to replace 0 or more characters (i.e.: `http://*.domain.com`). Usage of wildcards implies a small performance penality. Only one wildcard can be used per origin. The default value is `*`. +* **AllowOriginFunc** `func (origin string) bool`: A custom function to validate the origin. It takes the origin as an argument and returns true if allowed, or false otherwise. If this option is set, the content of `AllowedOrigins` is ignored. +* **AllowOriginRequestFunc** `func (r *http.Request origin string) bool`: A custom function to validate the origin. It takes the HTTP Request object and the origin as argument and returns true if allowed or false otherwise. If this option is set, the content of `AllowedOrigins` and `AllowOriginFunc` is ignored +* **AllowedMethods** `[]string`: A list of methods the client is allowed to use with cross-domain requests. Default value is simple methods (`GET` and `POST`). +* **AllowedHeaders** `[]string`: A list of non simple headers the client is allowed to use with cross-domain requests. +* **ExposedHeaders** `[]string`: Indicates which headers are safe to expose to the API of a CORS API specification +* **AllowCredentials** `bool`: Indicates whether the request can include user credentials like cookies, HTTP authentication or client side SSL certificates. The default is `false`. +* **MaxAge** `int`: Indicates how long (in seconds) the results of a preflight request can be cached. The default is `0` which stands for no max age. +* **OptionsPassthrough** `bool`: Instructs preflight to let other potential next handlers to process the `OPTIONS` method. Turn this on if your application handles `OPTIONS`. +* **Debug** `bool`: Debugging flag adds additional output to debug server side CORS issues. + +See [API documentation](http://godoc.org/github.com/rs/cors) for more info. + +## Benchmarks + + BenchmarkWithout 20000000 64.6 ns/op 8 B/op 1 allocs/op + BenchmarkDefault 3000000 469 ns/op 114 B/op 2 allocs/op + BenchmarkAllowedOrigin 3000000 608 ns/op 114 B/op 2 allocs/op + BenchmarkPreflight 20000000 73.2 ns/op 0 B/op 0 allocs/op + BenchmarkPreflightHeader 20000000 73.6 ns/op 0 B/op 0 allocs/op + BenchmarkParseHeaderList 2000000 847 ns/op 184 B/op 6 allocs/op + BenchmarkParse…Single 5000000 290 ns/op 32 B/op 3 allocs/op + BenchmarkParse…Normalized 2000000 776 ns/op 160 B/op 6 allocs/op + +## Licenses + +All source code is licensed under the [MIT License](https://raw.github.com/rs/cors/master/LICENSE). diff --git a/vendor/github.com/rs/cors/cors.go b/vendor/github.com/rs/cors/cors.go new file mode 100644 index 00000000..d301ca72 --- /dev/null +++ b/vendor/github.com/rs/cors/cors.go @@ -0,0 +1,417 @@ +/* +Package cors is net/http handler to handle CORS related requests +as defined by http://www.w3.org/TR/cors/ + +You can configure it by passing an option struct to cors.New: + + c := cors.New(cors.Options{ + AllowedOrigins: []string{"foo.com"}, + AllowedMethods: []string{"GET", "POST", "DELETE"}, + AllowCredentials: true, + }) + +Then insert the handler in the chain: + + handler = c.Handler(handler) + +See Options documentation for more options. + +The resulting handler is a standard net/http handler. +*/ +package cors + +import ( + "log" + "net/http" + "os" + "strconv" + "strings" +) + +// Options is a configuration container to setup the CORS middleware. +type Options struct { + // AllowedOrigins is a list of origins a cross-domain request can be executed from. + // If the special "*" value is present in the list, all origins will be allowed. + // An origin may contain a wildcard (*) to replace 0 or more characters + // (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty. + // Only one wildcard can be used per origin. + // Default value is ["*"] + AllowedOrigins []string + // AllowOriginFunc is a custom function to validate the origin. It take the origin + // as argument and returns true if allowed or false otherwise. If this option is + // set, the content of AllowedOrigins is ignored. + AllowOriginFunc func(origin string) bool + // AllowOriginFunc is a custom function to validate the origin. It takes the HTTP Request object and the origin as + // argument and returns true if allowed or false otherwise. If this option is set, the content of `AllowedOrigins` + // and `AllowOriginFunc` is ignored. + AllowOriginRequestFunc func(r *http.Request, origin string) bool + // AllowedMethods is a list of methods the client is allowed to use with + // cross-domain requests. Default value is simple methods (HEAD, GET and POST). + AllowedMethods []string + // AllowedHeaders is list of non simple headers the client is allowed to use with + // cross-domain requests. + // If the special "*" value is present in the list, all headers will be allowed. + // Default value is [] but "Origin" is always appended to the list. + AllowedHeaders []string + // ExposedHeaders indicates which headers are safe to expose to the API of a CORS + // API specification + ExposedHeaders []string + // MaxAge indicates how long (in seconds) the results of a preflight request + // can be cached + MaxAge int + // AllowCredentials indicates whether the request can include user credentials like + // cookies, HTTP authentication or client side SSL certificates. + AllowCredentials bool + // OptionsPassthrough instructs preflight to let other potential next handlers to + // process the OPTIONS method. Turn this on if your application handles OPTIONS. + OptionsPassthrough bool + // Debugging flag adds additional output to debug server side CORS issues + Debug bool +} + +// Cors http handler +type Cors struct { + // Debug logger + Log *log.Logger + // Normalized list of plain allowed origins + allowedOrigins []string + // List of allowed origins containing wildcards + allowedWOrigins []wildcard + // Optional origin validator function + allowOriginFunc func(origin string) bool + // Optional origin validator (with request) function + allowOriginRequestFunc func(r *http.Request, origin string) bool + // Normalized list of allowed headers + allowedHeaders []string + // Normalized list of allowed methods + allowedMethods []string + // Normalized list of exposed headers + exposedHeaders []string + maxAge int + // Set to true when allowed origins contains a "*" + allowedOriginsAll bool + // Set to true when allowed headers contains a "*" + allowedHeadersAll bool + allowCredentials bool + optionPassthrough bool +} + +// New creates a new Cors handler with the provided options. +func New(options Options) *Cors { + c := &Cors{ + exposedHeaders: convert(options.ExposedHeaders, http.CanonicalHeaderKey), + allowOriginFunc: options.AllowOriginFunc, + allowOriginRequestFunc: options.AllowOriginRequestFunc, + allowCredentials: options.AllowCredentials, + maxAge: options.MaxAge, + optionPassthrough: options.OptionsPassthrough, + } + if options.Debug { + c.Log = log.New(os.Stdout, "[cors] ", log.LstdFlags) + } + + // Normalize options + // Note: for origins and methods matching, the spec requires a case-sensitive matching. + // As it may error prone, we chose to ignore the spec here. + + // Allowed Origins + if len(options.AllowedOrigins) == 0 { + if options.AllowOriginFunc == nil && options.AllowOriginRequestFunc == nil { + // Default is all origins + c.allowedOriginsAll = true + } + } else { + c.allowedOrigins = []string{} + c.allowedWOrigins = []wildcard{} + for _, origin := range options.AllowedOrigins { + // Normalize + origin = strings.ToLower(origin) + if origin == "*" { + // If "*" is present in the list, turn the whole list into a match all + c.allowedOriginsAll = true + c.allowedOrigins = nil + c.allowedWOrigins = nil + break + } else if i := strings.IndexByte(origin, '*'); i >= 0 { + // Split the origin in two: start and end string without the * + w := wildcard{origin[0:i], origin[i+1:]} + c.allowedWOrigins = append(c.allowedWOrigins, w) + } else { + c.allowedOrigins = append(c.allowedOrigins, origin) + } + } + } + + // Allowed Headers + if len(options.AllowedHeaders) == 0 { + // Use sensible defaults + c.allowedHeaders = []string{"Origin", "Accept", "Content-Type", "X-Requested-With"} + } else { + // Origin is always appended as some browsers will always request for this header at preflight + c.allowedHeaders = convert(append(options.AllowedHeaders, "Origin"), http.CanonicalHeaderKey) + for _, h := range options.AllowedHeaders { + if h == "*" { + c.allowedHeadersAll = true + c.allowedHeaders = nil + break + } + } + } + + // Allowed Methods + if len(options.AllowedMethods) == 0 { + // Default is spec's "simple" methods + c.allowedMethods = []string{"GET", "POST", "HEAD"} + } else { + c.allowedMethods = convert(options.AllowedMethods, strings.ToUpper) + } + + return c +} + +// Default creates a new Cors handler with default options. +func Default() *Cors { + return New(Options{}) +} + +// AllowAll create a new Cors handler with permissive configuration allowing all +// origins with all standard methods with any header and credentials. +func AllowAll() *Cors { + return New(Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"HEAD", "GET", "POST", "PUT", "PATCH", "DELETE"}, + AllowedHeaders: []string{"*"}, + AllowCredentials: false, + }) +} + +// Handler apply the CORS specification on the request, and add relevant CORS headers +// as necessary. +func (c *Cors) Handler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" { + c.logf("Handler: Preflight request") + c.handlePreflight(w, r) + // Preflight requests are standalone and should stop the chain as some other + // middleware may not handle OPTIONS requests correctly. One typical example + // is authentication middleware ; OPTIONS requests won't carry authentication + // headers (see #1) + if c.optionPassthrough { + h.ServeHTTP(w, r) + } else { + w.WriteHeader(http.StatusOK) + } + } else { + c.logf("Handler: Actual request") + c.handleActualRequest(w, r) + h.ServeHTTP(w, r) + } + }) +} + +// HandlerFunc provides Martini compatible handler +func (c *Cors) HandlerFunc(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" { + c.logf("HandlerFunc: Preflight request") + c.handlePreflight(w, r) + } else { + c.logf("HandlerFunc: Actual request") + c.handleActualRequest(w, r) + } +} + +// Negroni compatible interface +func (c *Cors) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { + if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" { + c.logf("ServeHTTP: Preflight request") + c.handlePreflight(w, r) + // Preflight requests are standalone and should stop the chain as some other + // middleware may not handle OPTIONS requests correctly. One typical example + // is authentication middleware ; OPTIONS requests won't carry authentication + // headers (see #1) + if c.optionPassthrough { + next(w, r) + } else { + w.WriteHeader(http.StatusOK) + } + } else { + c.logf("ServeHTTP: Actual request") + c.handleActualRequest(w, r) + next(w, r) + } +} + +// handlePreflight handles pre-flight CORS requests +func (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + if r.Method != http.MethodOptions { + c.logf(" Preflight aborted: %s!=OPTIONS", r.Method) + return + } + // Always set Vary headers + // see https://github.com/rs/cors/issues/10, + // https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001 + headers.Add("Vary", "Origin") + headers.Add("Vary", "Access-Control-Request-Method") + headers.Add("Vary", "Access-Control-Request-Headers") + + if origin == "" { + c.logf(" Preflight aborted: empty origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf(" Preflight aborted: origin '%s' not allowed", origin) + return + } + + reqMethod := r.Header.Get("Access-Control-Request-Method") + if !c.isMethodAllowed(reqMethod) { + c.logf(" Preflight aborted: method '%s' not allowed", reqMethod) + return + } + reqHeaders := parseHeaderList(r.Header.Get("Access-Control-Request-Headers")) + if !c.areHeadersAllowed(reqHeaders) { + c.logf(" Preflight aborted: headers '%v' not allowed", reqHeaders) + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + // Spec says: Since the list of methods can be unbounded, simply returning the method indicated + // by Access-Control-Request-Method (if supported) can be enough + headers.Set("Access-Control-Allow-Methods", strings.ToUpper(reqMethod)) + if len(reqHeaders) > 0 { + + // Spec says: Since the list of headers can be unbounded, simply returning supported headers + // from Access-Control-Request-Headers can be enough + headers.Set("Access-Control-Allow-Headers", strings.Join(reqHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + if c.maxAge > 0 { + headers.Set("Access-Control-Max-Age", strconv.Itoa(c.maxAge)) + } + c.logf(" Preflight response headers: %v", headers) +} + +// handleActualRequest handles simple cross-origin requests, actual request or redirects +func (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) { + headers := w.Header() + origin := r.Header.Get("Origin") + + if r.Method == http.MethodOptions { + c.logf(" Actual request no headers added: method == %s", r.Method) + return + } + // Always set Vary, see https://github.com/rs/cors/issues/10 + headers.Add("Vary", "Origin") + if origin == "" { + c.logf(" Actual request no headers added: missing origin") + return + } + if !c.isOriginAllowed(r, origin) { + c.logf(" Actual request no headers added: origin '%s' not allowed", origin) + return + } + + // Note that spec does define a way to specifically disallow a simple method like GET or + // POST. Access-Control-Allow-Methods is only used for pre-flight requests and the + // spec doesn't instruct to check the allowed methods for simple cross-origin requests. + // We think it's a nice feature to be able to have control on those methods though. + if !c.isMethodAllowed(r.Method) { + c.logf(" Actual request no headers added: method '%s' not allowed", r.Method) + + return + } + if c.allowedOriginsAll { + headers.Set("Access-Control-Allow-Origin", "*") + } else { + headers.Set("Access-Control-Allow-Origin", origin) + } + if len(c.exposedHeaders) > 0 { + headers.Set("Access-Control-Expose-Headers", strings.Join(c.exposedHeaders, ", ")) + } + if c.allowCredentials { + headers.Set("Access-Control-Allow-Credentials", "true") + } + c.logf(" Actual response added headers: %v", headers) +} + +// convenience method. checks if debugging is turned on before printing +func (c *Cors) logf(format string, a ...interface{}) { + if c.Log != nil { + c.Log.Printf(format, a...) + } +} + +// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests +// on the endpoint +func (c *Cors) isOriginAllowed(r *http.Request, origin string) bool { + if c.allowOriginRequestFunc != nil { + return c.allowOriginRequestFunc(r, origin) + } + if c.allowOriginFunc != nil { + return c.allowOriginFunc(origin) + } + if c.allowedOriginsAll { + return true + } + origin = strings.ToLower(origin) + for _, o := range c.allowedOrigins { + if o == origin { + return true + } + } + for _, w := range c.allowedWOrigins { + if w.match(origin) { + return true + } + } + return false +} + +// isMethodAllowed checks if a given method can be used as part of a cross-domain request +// on the endpoing +func (c *Cors) isMethodAllowed(method string) bool { + if len(c.allowedMethods) == 0 { + // If no method allowed, always return false, even for preflight request + return false + } + method = strings.ToUpper(method) + if method == http.MethodOptions { + // Always allow preflight requests + return true + } + for _, m := range c.allowedMethods { + if m == method { + return true + } + } + return false +} + +// areHeadersAllowed checks if a given list of headers are allowed to used within +// a cross-domain request. +func (c *Cors) areHeadersAllowed(requestedHeaders []string) bool { + if c.allowedHeadersAll || len(requestedHeaders) == 0 { + return true + } + for _, header := range requestedHeaders { + header = http.CanonicalHeaderKey(header) + found := false + for _, h := range c.allowedHeaders { + if h == header { + found = true + } + } + if !found { + return false + } + } + return true +} diff --git a/vendor/github.com/rs/cors/utils.go b/vendor/github.com/rs/cors/utils.go new file mode 100644 index 00000000..53ad9e9d --- /dev/null +++ b/vendor/github.com/rs/cors/utils.go @@ -0,0 +1,71 @@ +package cors + +import "strings" + +const toLower = 'a' - 'A' + +type converter func(string) string + +type wildcard struct { + prefix string + suffix string +} + +func (w wildcard) match(s string) bool { + return len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix) +} + +// convert converts a list of string using the passed converter function +func convert(s []string, c converter) []string { + out := []string{} + for _, i := range s { + out = append(out, c(i)) + } + return out +} + +// parseHeaderList tokenize + normalize a string containing a list of headers +func parseHeaderList(headerList string) []string { + l := len(headerList) + h := make([]byte, 0, l) + upper := true + // Estimate the number headers in order to allocate the right splice size + t := 0 + for i := 0; i < l; i++ { + if headerList[i] == ',' { + t++ + } + } + headers := make([]string, 0, t) + for i := 0; i < l; i++ { + b := headerList[i] + switch { + case b >= 'a' && b <= 'z': + if upper { + h = append(h, b-toLower) + } else { + h = append(h, b) + } + case b >= 'A' && b <= 'Z': + if !upper { + h = append(h, b+toLower) + } else { + h = append(h, b) + } + case b == '-' || b == '_' || (b >= '0' && b <= '9'): + h = append(h, b) + } + + if b == ' ' || b == ',' || i == l-1 { + if len(h) > 0 { + // Flush the found header + headers = append(headers, string(h)) + h = h[:0] + upper = true + } + } else { + upper = b == '-' || b == '_' + } + } + return headers +} diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml new file mode 100644 index 00000000..848938a6 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/.travis.yml @@ -0,0 +1,25 @@ +language: go +go_import_path: github.com/sirupsen/logrus +git: + depth: 1 +env: + - GO111MODULE=on + - GO111MODULE=off +go: [ 1.11.x, 1.12.x ] +os: [ linux, osx ] +matrix: + exclude: + - go: 1.12.x + env: GO111MODULE=off + - go: 1.11.x + os: osx +install: + - ./travis/install.sh + - if [[ "$GO111MODULE" == "on" ]]; then go mod download; fi + - if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi +script: + - ./travis/cross_build.sh + - export GOMAXPROCS=4 + - export GORACE=halt_on_error=1 + - go test -race -v ./... + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then go test -race -v -tags appengine ./... ; fi diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md new file mode 100644 index 00000000..51a7ab0c --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -0,0 +1,200 @@ +# 1.4.2 + * Fixes build break for plan9, nacl, solaris +# 1.4.1 +This new release introduces: + * Enhance TextFormatter to not print caller information when they are empty (#944) + * Remove dependency on golang.org/x/crypto (#932, #943) + +Fixes: + * Fix Entry.WithContext method to return a copy of the initial entry (#941) + +# 1.4.0 +This new release introduces: + * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). + * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter (#909, #911) + * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). + +Fixes: + * Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893). + * Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903) + * Fix infinite recursion on unknown `Level.String()` (#907) + * Fix race condition in `getCaller` (#916). + + +# 1.3.0 +This new release introduces: + * Log, Logf, Logln functions for Logger and Entry that take a Level + +Fixes: + * Building prometheus node_exporter on AIX (#840) + * Race condition in TextFormatter (#468) + * Travis CI import path (#868) + * Remove coloured output on Windows (#862) + * Pointer to func as field in JSONFormatter (#870) + * Properly marshal Levels (#873) + +# 1.2.0 +This new release introduces: + * A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued + * A new trace level named `Trace` whose level is below `Debug` + * A configurable exit function to be called upon a Fatal trace + * The `Level` object now implements `encoding.TextUnmarshaler` interface + +# 1.1.1 +This is a bug fix release. + * fix the build break on Solaris + * don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized + +# 1.1.0 +This new release introduces: + * several fixes: + * a fix for a race condition on entry formatting + * proper cleanup of previously used entries before putting them back in the pool + * the extra new line at the end of message in text formatter has been removed + * a new global public API to check if a level is activated: IsLevelEnabled + * the following methods have been added to the Logger object + * IsLevelEnabled + * SetFormatter + * SetOutput + * ReplaceHooks + * introduction of go module + * an indent configuration for the json formatter + * output colour support for windows + * the field sort function is now configurable for text formatter + * the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater + +# 1.0.6 + +This new release introduces: + * a new api WithTime which allows to easily force the time of the log entry + which is mostly useful for logger wrapper + * a fix reverting the immutability of the entry given as parameter to the hooks + a new configuration field of the json formatter in order to put all the fields + in a nested dictionnary + * a new SetOutput method in the Logger + * a new configuration of the textformatter to configure the name of the default keys + * a new configuration of the text formatter to disable the level truncation + +# 1.0.5 + +* Fix hooks race (#707) +* Fix panic deadlock (#695) + +# 1.0.4 + +* Fix race when adding hooks (#612) +* Fix terminal check in AppEngine (#635) + +# 1.0.3 + +* Replace example files with testable examples + +# 1.0.2 + +* bug: quote non-string values in text formatter (#583) +* Make (*Logger) SetLevel a public method + +# 1.0.1 + +* bug: fix escaping in text formatter (#575) + +# 1.0.0 + +* Officially changed name to lower-case +* bug: colors on Windows 10 (#541) +* bug: fix race in accessing level (#512) + +# 0.11.5 + +* feature: add writer and writerlevel to entry (#372) + +# 0.11.4 + +* bug: fix undefined variable on solaris (#493) + +# 0.11.3 + +* formatter: configure quoting of empty values (#484) +* formatter: configure quoting character (default is `"`) (#484) +* bug: fix not importing io correctly in non-linux environments (#481) + +# 0.11.2 + +* bug: fix windows terminal detection (#476) + +# 0.11.1 + +* bug: fix tty detection with custom out (#471) + +# 0.11.0 + +* performance: Use bufferpool to allocate (#370) +* terminal: terminal detection for app-engine (#343) +* feature: exit handler (#375) + +# 0.10.0 + +* feature: Add a test hook (#180) +* feature: `ParseLevel` is now case-insensitive (#326) +* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) +* performance: avoid re-allocations on `WithFields` (#335) + +# 0.9.0 + +* logrus/text_formatter: don't emit empty msg +* logrus/hooks/airbrake: move out of main repository +* logrus/hooks/sentry: move out of main repository +* logrus/hooks/papertrail: move out of main repository +* logrus/hooks/bugsnag: move out of main repository +* logrus/core: run tests with `-race` +* logrus/core: detect TTY based on `stderr` +* logrus/core: support `WithError` on logger +* logrus/core: Solaris support + +# 0.8.7 + +* logrus/core: fix possible race (#216) +* logrus/doc: small typo fixes and doc improvements + + +# 0.8.6 + +* hooks/raven: allow passing an initialized client + +# 0.8.5 + +* logrus/core: revert #208 + +# 0.8.4 + +* formatter/text: fix data race (#218) + +# 0.8.3 + +* logrus/core: fix entry log level (#208) +* logrus/core: improve performance of text formatter by 40% +* logrus/core: expose `LevelHooks` type +* logrus/core: add support for DragonflyBSD and NetBSD +* formatter/text: print structs more verbosely + +# 0.8.2 + +* logrus: fix more Fatal family functions + +# 0.8.1 + +* logrus: fix not exiting on `Fatalf` and `Fatalln` + +# 0.8.0 + +* logrus: defaults to stderr instead of stdout +* hooks/sentry: add special field for `*http.Request` +* formatter/text: ignore Windows for colors + +# 0.7.3 + +* formatter/\*: allow configuration of timestamp layout + +# 0.7.2 + +* formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md new file mode 100644 index 00000000..a4796eb0 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -0,0 +1,495 @@ +# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) + +Logrus is a structured logger for Go (golang), completely API compatible with +the standard library logger. + +**Seeing weird case-sensitive problems?** It's in the past been possible to +import Logrus as both upper- and lower-case. Due to the Go package environment, +this caused issues in the community and we needed a standard. Some environments +experienced problems with the upper-case variant, so the lower-case was decided. +Everything using `logrus` will need to use the lower-case: +`github.com/sirupsen/logrus`. Any package that isn't, should be changed. + +To fix Glide, see [these +comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). +For an in-depth explanation of the casing issue, see [this +comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). + +**Are you interested in assisting in maintaining Logrus?** Currently I have a +lot of obligations, and I am unable to provide Logrus with the maintainership it +needs. If you'd like to help, please reach out to me at `simon at author's +username dot com`. + +Nicely color-coded in development (when a TTY is attached, otherwise just +plain text): + +![Colored](http://i.imgur.com/PY7qMwd.png) + +With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash +or Splunk: + +```json +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the +ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} + +{"level":"warning","msg":"The group's number increased tremendously!", +"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"A giant walrus appears!", +"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", +"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} + +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, +"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +``` + +With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not +attached, the output is compatible with the +[logfmt](http://godoc.org/github.com/kr/logfmt) format: + +```text +time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 +time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 +time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true +time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 +time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +``` +To ensure this behaviour even if a TTY is attached, set your formatter as follows: + +```go + log.SetFormatter(&log.TextFormatter{ + DisableColors: true, + FullTimestamp: true, + }) +``` + +#### Logging Method Name + +If you wish to add the calling method as a field, instruct the logger via: +```go +log.SetReportCaller(true) +``` +This adds the caller as 'method' like so: + +```json +{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by", +"time":"2014-03-10 19:57:38.562543129 -0400 EDT"} +``` + +```text +time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin +``` +Note that this does add measurable overhead - the cost will depend on the version of Go, but is +between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your +environment via benchmarks: +``` +go test -bench=.*CallerTracing +``` + + +#### Case-sensitivity + +The organization's name was changed to lower-case--and this will not be changed +back. If you are getting import conflicts due to case sensitivity, please use +the lower-case import: `github.com/sirupsen/logrus`. + +#### Example + +The simplest way to use Logrus is simply the package-level exported logger: + +```go +package main + +import ( + log "github.com/sirupsen/logrus" +) + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + }).Info("A walrus appears") +} +``` + +Note that it's completely api-compatible with the stdlib logger, so you can +replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"` +and you'll now have the flexibility of Logrus. You can customize it all you +want: + +```go +package main + +import ( + "os" + log "github.com/sirupsen/logrus" +) + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) + + // Output to stdout instead of the default stderr + // Can be any io.Writer, see below for File example + log.SetOutput(os.Stdout) + + // Only log the warning severity or above. + log.SetLevel(log.WarnLevel) +} + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(log.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(log.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") + + // A common pattern is to re-use fields between logging statements by re-using + // the logrus.Entry returned from WithFields() + contextLogger := log.WithFields(log.Fields{ + "common": "this is a common field", + "other": "I also should be logged always", + }) + + contextLogger.Info("I'll be logged with common and other field") + contextLogger.Info("Me too") +} +``` + +For more advanced usage such as logging to multiple locations from the same +application, you can also create an instance of the `logrus` Logger: + +```go +package main + +import ( + "os" + "github.com/sirupsen/logrus" +) + +// Create a new instance of the logger. You can have any number of instances. +var log = logrus.New() + +func main() { + // The API for setting attributes is a little different than the package level + // exported logger. See Godoc. + log.Out = os.Stdout + + // You could set this to any `io.Writer` such as a file + // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) + // if err == nil { + // log.Out = file + // } else { + // log.Info("Failed to log to file, using default stderr") + // } + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") +} +``` + +#### Fields + +Logrus encourages careful, structured logging through logging fields instead of +long, unparseable error messages. For example, instead of: `log.Fatalf("Failed +to send event %s to topic %s with key %d")`, you should log the much more +discoverable: + +```go +log.WithFields(log.Fields{ + "event": event, + "topic": topic, + "key": key, +}).Fatal("Failed to send event") +``` + +We've found this API forces you to think about logging in a way that produces +much more useful logging messages. We've been in countless situations where just +a single added field to a log statement that was already there would've saved us +hours. The `WithFields` call is optional. + +In general, with Logrus using any of the `printf`-family functions should be +seen as a hint you should add a field, however, you can still use the +`printf`-family functions with Logrus. + +#### Default Fields + +Often it's helpful to have fields _always_ attached to log statements in an +application or parts of one. For example, you may want to always log the +`request_id` and `user_ip` in the context of a request. Instead of writing +`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on +every line, you can create a `logrus.Entry` to pass around instead: + +```go +requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) +requestLogger.Info("something happened on that request") # will log request_id and user_ip +requestLogger.Warn("something not great happened") +``` + +#### Hooks + +You can add hooks for logging levels. For example to send errors to an exception +tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to +multiple places simultaneously, e.g. syslog. + +Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in +`init`: + +```go +import ( + log "github.com/sirupsen/logrus" + "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake" + logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" + "log/syslog" +) + +func init() { + + // Use the Airbrake hook to report errors that have Error severity or above to + // an exception tracker. You can create custom hooks, see the Hooks section. + log.AddHook(airbrake.NewHook(123, "xyz", "production")) + + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + if err != nil { + log.Error("Unable to connect to local syslog daemon") + } else { + log.AddHook(hook) + } +} +``` +Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). + +A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) + + +#### Level logging + +Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic. + +```go +log.Trace("Something very low level.") +log.Debug("Useful debugging information.") +log.Info("Something noteworthy happened!") +log.Warn("You should probably take a look at this.") +log.Error("Something failed but I'm not quitting.") +// Calls os.Exit(1) after logging +log.Fatal("Bye.") +// Calls panic() after logging +log.Panic("I'm bailing.") +``` + +You can set the logging level on a `Logger`, then it will only log entries with +that severity or anything above it: + +```go +// Will log anything that is info or above (warn, error, fatal, panic). Default. +log.SetLevel(log.InfoLevel) +``` + +It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose +environment if your application has that. + +#### Entries + +Besides the fields added with `WithField` or `WithFields` some fields are +automatically added to all logging events: + +1. `time`. The timestamp when the entry was created. +2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after + the `AddFields` call. E.g. `Failed to send event.` +3. `level`. The logging level. E.g. `info`. + +#### Environments + +Logrus has no notion of environment. + +If you wish for hooks and formatters to only be used in specific environments, +you should handle that yourself. For example, if your application has a global +variable `Environment`, which is a string representation of the environment you +could do: + +```go +import ( + log "github.com/sirupsen/logrus" +) + +init() { + // do something here to set environment depending on an environment variable + // or command-line flag + if Environment == "production" { + log.SetFormatter(&log.JSONFormatter{}) + } else { + // The TextFormatter is default, you don't actually have to do this. + log.SetFormatter(&log.TextFormatter{}) + } +} +``` + +This configuration is how `logrus` was intended to be used, but JSON in +production is mostly only useful if you do log aggregation with tools like +Splunk or Logstash. + +#### Formatters + +The built-in logging formatters are: + +* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise + without colors. + * *Note:* to force colored output when there is no TTY, set the `ForceColors` + field to `true`. To force no colored output even if there is a TTY set the + `DisableColors` field to `true`. For Windows, see + [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). + * When colors are enabled, levels are truncated to 4 characters by default. To disable + truncation set the `DisableLevelTruncation` field to `true`. + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). +* `logrus.JSONFormatter`. Logs fields as JSON. + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). + +Third party logging formatters: + +* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine. +* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). +* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. +* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. +* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. +* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. + +You can define your formatter by implementing the `Formatter` interface, +requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a +`Fields` type (`map[string]interface{}`) with all your fields as well as the +default ones (see Entries section above): + +```go +type MyJSONFormatter struct { +} + +log.SetFormatter(new(MyJSONFormatter)) + +func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { + // Note this doesn't include Time, Level and Message which are available on + // the Entry. Consult `godoc` on information about those fields or read the + // source of the official loggers. + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} +``` + +#### Logger as an `io.Writer` + +Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. + +```go +w := logger.Writer() +defer w.Close() + +srv := http.Server{ + // create a stdlib log.Logger that writes to + // logrus.Logger. + ErrorLog: log.New(w, "", 0), +} +``` + +Each line written to that writer will be printed the usual way, using formatters +and hooks. The level for those entries is `info`. + +This means that we can override the standard library logger easily: + +```go +logger := logrus.New() +logger.Formatter = &logrus.JSONFormatter{} + +// Use logrus for standard log output +// Note that `log` here references stdlib's log +// Not logrus imported under the name `log`. +log.SetOutput(logger.Writer()) +``` + +#### Rotation + +Log rotation is not provided with Logrus. Log rotation should be done by an +external program (like `logrotate(8)`) that can compress and delete old log +entries. It should not be a feature of the application-level logger. + +#### Tools + +| Tool | Description | +| ---- | ----------- | +|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| +|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | + +#### Testing + +Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: + +* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook +* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): + +```go +import( + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSomething(t*testing.T){ + logger, hook := test.NewNullLogger() + logger.Error("Helloerror") + + assert.Equal(t, 1, len(hook.Entries)) + assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level) + assert.Equal(t, "Helloerror", hook.LastEntry().Message) + + hook.Reset() + assert.Nil(t, hook.LastEntry()) +} +``` + +#### Fatal handlers + +Logrus can register one or more functions that will be called when any `fatal` +level message is logged. The registered handlers will be executed before +logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need +to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. + +``` +... +handler := func() { + // gracefully shutdown something... +} +logrus.RegisterExitHandler(handler) +... +``` + +#### Thread safety + +By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs. +If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. + +Situation when locking is not needed includes: + +* You have no hooks registered, or hooks calling is already thread-safe. + +* Writing to logger.Out is already thread-safe, for example: + + 1) logger.Out is protected by locks. + + 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) + + (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go new file mode 100644 index 00000000..8fd189e1 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/alt_exit.go @@ -0,0 +1,76 @@ +package logrus + +// The following code was sourced and modified from the +// https://github.com/tebeka/atexit package governed by the following license: +// +// Copyright (c) 2012 Miki Tebeka . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import ( + "fmt" + "os" +) + +var handlers = []func(){} + +func runHandler(handler func()) { + defer func() { + if err := recover(); err != nil { + fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) + } + }() + + handler() +} + +func runHandlers() { + for _, handler := range handlers { + runHandler(handler) + } +} + +// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) +func Exit(code int) { + runHandlers() + os.Exit(code) +} + +// RegisterExitHandler appends a Logrus Exit handler to the list of handlers, +// call logrus.Exit to invoke all handlers. The handlers will also be invoked when +// any Fatal log entry is made. +// +// This method is useful when a caller wishes to use logrus to log a fatal +// message but also needs to gracefully shutdown. An example usecase could be +// closing database connections, or sending a alert that the application is +// closing. +func RegisterExitHandler(handler func()) { + handlers = append(handlers, handler) +} + +// DeferExitHandler prepends a Logrus Exit handler to the list of handlers, +// call logrus.Exit to invoke all handlers. The handlers will also be invoked when +// any Fatal log entry is made. +// +// This method is useful when a caller wishes to use logrus to log a fatal +// message but also needs to gracefully shutdown. An example usecase could be +// closing database connections, or sending a alert that the application is +// closing. +func DeferExitHandler(handler func()) { + handlers = append([]func(){handler}, handlers...) +} diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go new file mode 100644 index 00000000..63e25583 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -0,0 +1,407 @@ +package logrus + +import ( + "bytes" + "context" + "fmt" + "os" + "reflect" + "runtime" + "strings" + "sync" + "time" +) + +var ( + bufferPool *sync.Pool + + // qualified package name, cached at first use + logrusPackage string + + // Positions in the call stack when tracing to report the calling method + minimumCallerDepth int + + // Used for caller information initialisation + callerInitOnce sync.Once +) + +const ( + maximumCallerDepth int = 25 + knownLogrusFrames int = 4 +) + +func init() { + bufferPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + } + + // start at the bottom of the stack before the package-name cache is primed + minimumCallerDepth = 1 +} + +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + +// An entry is the final or intermediate Logrus logging entry. It contains all +// the fields passed with WithField{,s}. It's finally logged when Trace, Debug, +// Info, Warn, Error, Fatal or Panic is called on it. These objects can be +// reused and passed around as much as you wish to avoid field duplication. +type Entry struct { + Logger *Logger + + // Contains all the fields set by the user. + Data Fields + + // Time at which the log entry was created + Time time.Time + + // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic + // This field will be set on entry firing and the value will be equal to the one in Logger struct field. + Level Level + + // Calling method, with package name + Caller *runtime.Frame + + // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic + Message string + + // When formatter is called in entry.log(), a Buffer may be set to entry + Buffer *bytes.Buffer + + // Contains the context set by the user. Useful for hook processing etc. + Context context.Context + + // err may contain a field formatting error + err string +} + +func NewEntry(logger *Logger) *Entry { + return &Entry{ + Logger: logger, + // Default is three fields, plus one optional. Give a little extra room. + Data: make(Fields, 6), + } +} + +// Returns the string representation from the reader and ultimately the +// formatter. +func (entry *Entry) String() (string, error) { + serialized, err := entry.Logger.Formatter.Format(entry) + if err != nil { + return "", err + } + str := string(serialized) + return str, nil +} + +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) +} + +// Add a context to the Entry. +func (entry *Entry) WithContext(ctx context.Context) *Entry { + return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx} +} + +// Add a single field to the Entry. +func (entry *Entry) WithField(key string, value interface{}) *Entry { + return entry.WithFields(Fields{key: value}) +} + +// Add a map of fields to the Entry. +func (entry *Entry) WithFields(fields Fields) *Entry { + data := make(Fields, len(entry.Data)+len(fields)) + for k, v := range entry.Data { + data[k] = v + } + fieldErr := entry.err + for k, v := range fields { + isErrField := false + if t := reflect.TypeOf(v); t != nil { + switch t.Kind() { + case reflect.Func: + isErrField = true + case reflect.Ptr: + isErrField = t.Elem().Kind() == reflect.Func + } + } + if isErrField { + tmp := fmt.Sprintf("can not add field %q", k) + if fieldErr != "" { + fieldErr = entry.err + ", " + tmp + } else { + fieldErr = tmp + } + } else { + data[k] = v + } + } + return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context} +} + +// Overrides the time of the Entry. +func (entry *Entry) WithTime(t time.Time) *Entry { + return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context} +} + +// getPackageName reduces a fully qualified function name to the package name +// There really ought to be to be a better way... +func getPackageName(f string) string { + for { + lastPeriod := strings.LastIndex(f, ".") + lastSlash := strings.LastIndex(f, "/") + if lastPeriod > lastSlash { + f = f[:lastPeriod] + } else { + break + } + } + + return f +} + +// getCaller retrieves the name of the first non-logrus calling function +func getCaller() *runtime.Frame { + + // cache this package's fully-qualified name + callerInitOnce.Do(func() { + pcs := make([]uintptr, 2) + _ = runtime.Callers(0, pcs) + logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name()) + + // now that we have the cache, we can skip a minimum count of known-logrus functions + // XXX this is dubious, the number of frames may vary + minimumCallerDepth = knownLogrusFrames + }) + + // Restrict the lookback frames to avoid runaway lookups + pcs := make([]uintptr, maximumCallerDepth) + depth := runtime.Callers(minimumCallerDepth, pcs) + frames := runtime.CallersFrames(pcs[:depth]) + + for f, again := frames.Next(); again; f, again = frames.Next() { + pkg := getPackageName(f.Function) + + // If the caller isn't part of this package, we're done + if pkg != logrusPackage { + return &f + } + } + + // if we got here, we failed to find the caller's context + return nil +} + +func (entry Entry) HasCaller() (has bool) { + return entry.Logger != nil && + entry.Logger.ReportCaller && + entry.Caller != nil +} + +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) log(level Level, msg string) { + var buffer *bytes.Buffer + + // Default to now, but allow users to override if they want. + // + // We don't have to worry about polluting future calls to Entry#log() + // with this assignment because this function is declared with a + // non-pointer receiver. + if entry.Time.IsZero() { + entry.Time = time.Now() + } + + entry.Level = level + entry.Message = msg + if entry.Logger.ReportCaller { + entry.Caller = getCaller() + } + + entry.fireHooks() + + buffer = bufferPool.Get().(*bytes.Buffer) + buffer.Reset() + defer bufferPool.Put(buffer) + entry.Buffer = buffer + + entry.write() + + entry.Buffer = nil + + // To avoid Entry#log() returning a value that only would make sense for + // panic() to use in Entry#Panic(), we avoid the allocation by checking + // directly here. + if level <= PanicLevel { + panic(&entry) + } +} + +func (entry *Entry) fireHooks() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + err := entry.Logger.Hooks.Fire(entry.Level, entry) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + } +} + +func (entry *Entry) write() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + serialized, err := entry.Logger.Formatter.Format(entry) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + } else { + _, err = entry.Logger.Out.Write(serialized) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + } +} + +func (entry *Entry) Log(level Level, args ...interface{}) { + if entry.Logger.IsLevelEnabled(level) { + entry.log(level, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Trace(args ...interface{}) { + entry.Log(TraceLevel, args...) +} + +func (entry *Entry) Debug(args ...interface{}) { + entry.Log(DebugLevel, args...) +} + +func (entry *Entry) Print(args ...interface{}) { + entry.Info(args...) +} + +func (entry *Entry) Info(args ...interface{}) { + entry.Log(InfoLevel, args...) +} + +func (entry *Entry) Warn(args ...interface{}) { + entry.Log(WarnLevel, args...) +} + +func (entry *Entry) Warning(args ...interface{}) { + entry.Warn(args...) +} + +func (entry *Entry) Error(args ...interface{}) { + entry.Log(ErrorLevel, args...) +} + +func (entry *Entry) Fatal(args ...interface{}) { + entry.Log(FatalLevel, args...) + entry.Logger.Exit(1) +} + +func (entry *Entry) Panic(args ...interface{}) { + entry.Log(PanicLevel, args...) + panic(fmt.Sprint(args...)) +} + +// Entry Printf family functions + +func (entry *Entry) Logf(level Level, format string, args ...interface{}) { + if entry.Logger.IsLevelEnabled(level) { + entry.Log(level, fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Tracef(format string, args ...interface{}) { + entry.Logf(TraceLevel, format, args...) +} + +func (entry *Entry) Debugf(format string, args ...interface{}) { + entry.Logf(DebugLevel, format, args...) +} + +func (entry *Entry) Infof(format string, args ...interface{}) { + entry.Logf(InfoLevel, format, args...) +} + +func (entry *Entry) Printf(format string, args ...interface{}) { + entry.Infof(format, args...) +} + +func (entry *Entry) Warnf(format string, args ...interface{}) { + entry.Logf(WarnLevel, format, args...) +} + +func (entry *Entry) Warningf(format string, args ...interface{}) { + entry.Warnf(format, args...) +} + +func (entry *Entry) Errorf(format string, args ...interface{}) { + entry.Logf(ErrorLevel, format, args...) +} + +func (entry *Entry) Fatalf(format string, args ...interface{}) { + entry.Logf(FatalLevel, format, args...) + entry.Logger.Exit(1) +} + +func (entry *Entry) Panicf(format string, args ...interface{}) { + entry.Logf(PanicLevel, format, args...) +} + +// Entry Println family functions + +func (entry *Entry) Logln(level Level, args ...interface{}) { + if entry.Logger.IsLevelEnabled(level) { + entry.Log(level, entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Traceln(args ...interface{}) { + entry.Logln(TraceLevel, args...) +} + +func (entry *Entry) Debugln(args ...interface{}) { + entry.Logln(DebugLevel, args...) +} + +func (entry *Entry) Infoln(args ...interface{}) { + entry.Logln(InfoLevel, args...) +} + +func (entry *Entry) Println(args ...interface{}) { + entry.Infoln(args...) +} + +func (entry *Entry) Warnln(args ...interface{}) { + entry.Logln(WarnLevel, args...) +} + +func (entry *Entry) Warningln(args ...interface{}) { + entry.Warnln(args...) +} + +func (entry *Entry) Errorln(args ...interface{}) { + entry.Logln(ErrorLevel, args...) +} + +func (entry *Entry) Fatalln(args ...interface{}) { + entry.Logln(FatalLevel, args...) + entry.Logger.Exit(1) +} + +func (entry *Entry) Panicln(args ...interface{}) { + entry.Logln(PanicLevel, args...) +} + +// Sprintlnn => Sprint no newline. This is to get the behavior of how +// fmt.Sprintln where spaces are always added between operands, regardless of +// their type. Instead of vendoring the Sprintln implementation to spare a +// string allocation, we do the simplest thing. +func (entry *Entry) sprintlnn(args ...interface{}) string { + msg := fmt.Sprintln(args...) + return msg[:len(msg)-1] +} diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go new file mode 100644 index 00000000..62fc2f21 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -0,0 +1,225 @@ +package logrus + +import ( + "context" + "io" + "time" +) + +var ( + // std is the name of the standard logger in stdlib `log` + std = New() +) + +func StandardLogger() *Logger { + return std +} + +// SetOutput sets the standard logger output. +func SetOutput(out io.Writer) { + std.SetOutput(out) +} + +// SetFormatter sets the standard logger formatter. +func SetFormatter(formatter Formatter) { + std.SetFormatter(formatter) +} + +// SetReportCaller sets whether the standard logger will include the calling +// method as a field. +func SetReportCaller(include bool) { + std.SetReportCaller(include) +} + +// SetLevel sets the standard logger level. +func SetLevel(level Level) { + std.SetLevel(level) +} + +// GetLevel returns the standard logger level. +func GetLevel() Level { + return std.GetLevel() +} + +// IsLevelEnabled checks if the log level of the standard logger is greater than the level param +func IsLevelEnabled(level Level) bool { + return std.IsLevelEnabled(level) +} + +// AddHook adds a hook to the standard logger hooks. +func AddHook(hook Hook) { + std.AddHook(hook) +} + +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) +} + +// WithContext creates an entry from the standard logger and adds a context to it. +func WithContext(ctx context.Context) *Entry { + return std.WithContext(ctx) +} + +// WithField creates an entry from the standard logger and adds a field to +// it. If you want multiple fields, use `WithFields`. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithField(key string, value interface{}) *Entry { + return std.WithField(key, value) +} + +// WithFields creates an entry from the standard logger and adds multiple +// fields to it. This is simply a helper for `WithField`, invoking it +// once for each field. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithFields(fields Fields) *Entry { + return std.WithFields(fields) +} + +// WithTime creats an entry from the standard logger and overrides the time of +// logs generated with it. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithTime(t time.Time) *Entry { + return std.WithTime(t) +} + +// Trace logs a message at level Trace on the standard logger. +func Trace(args ...interface{}) { + std.Trace(args...) +} + +// Debug logs a message at level Debug on the standard logger. +func Debug(args ...interface{}) { + std.Debug(args...) +} + +// Print logs a message at level Info on the standard logger. +func Print(args ...interface{}) { + std.Print(args...) +} + +// Info logs a message at level Info on the standard logger. +func Info(args ...interface{}) { + std.Info(args...) +} + +// Warn logs a message at level Warn on the standard logger. +func Warn(args ...interface{}) { + std.Warn(args...) +} + +// Warning logs a message at level Warn on the standard logger. +func Warning(args ...interface{}) { + std.Warning(args...) +} + +// Error logs a message at level Error on the standard logger. +func Error(args ...interface{}) { + std.Error(args...) +} + +// Panic logs a message at level Panic on the standard logger. +func Panic(args ...interface{}) { + std.Panic(args...) +} + +// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1. +func Fatal(args ...interface{}) { + std.Fatal(args...) +} + +// Tracef logs a message at level Trace on the standard logger. +func Tracef(format string, args ...interface{}) { + std.Tracef(format, args...) +} + +// Debugf logs a message at level Debug on the standard logger. +func Debugf(format string, args ...interface{}) { + std.Debugf(format, args...) +} + +// Printf logs a message at level Info on the standard logger. +func Printf(format string, args ...interface{}) { + std.Printf(format, args...) +} + +// Infof logs a message at level Info on the standard logger. +func Infof(format string, args ...interface{}) { + std.Infof(format, args...) +} + +// Warnf logs a message at level Warn on the standard logger. +func Warnf(format string, args ...interface{}) { + std.Warnf(format, args...) +} + +// Warningf logs a message at level Warn on the standard logger. +func Warningf(format string, args ...interface{}) { + std.Warningf(format, args...) +} + +// Errorf logs a message at level Error on the standard logger. +func Errorf(format string, args ...interface{}) { + std.Errorf(format, args...) +} + +// Panicf logs a message at level Panic on the standard logger. +func Panicf(format string, args ...interface{}) { + std.Panicf(format, args...) +} + +// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1. +func Fatalf(format string, args ...interface{}) { + std.Fatalf(format, args...) +} + +// Traceln logs a message at level Trace on the standard logger. +func Traceln(args ...interface{}) { + std.Traceln(args...) +} + +// Debugln logs a message at level Debug on the standard logger. +func Debugln(args ...interface{}) { + std.Debugln(args...) +} + +// Println logs a message at level Info on the standard logger. +func Println(args ...interface{}) { + std.Println(args...) +} + +// Infoln logs a message at level Info on the standard logger. +func Infoln(args ...interface{}) { + std.Infoln(args...) +} + +// Warnln logs a message at level Warn on the standard logger. +func Warnln(args ...interface{}) { + std.Warnln(args...) +} + +// Warningln logs a message at level Warn on the standard logger. +func Warningln(args ...interface{}) { + std.Warningln(args...) +} + +// Errorln logs a message at level Error on the standard logger. +func Errorln(args ...interface{}) { + std.Errorln(args...) +} + +// Panicln logs a message at level Panic on the standard logger. +func Panicln(args ...interface{}) { + std.Panicln(args...) +} + +// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1. +func Fatalln(args ...interface{}) { + std.Fatalln(args...) +} diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod new file mode 100644 index 00000000..12fdf989 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/go.mod @@ -0,0 +1,10 @@ +module github.com/sirupsen/logrus + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.1 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.1.1 // indirect + github.com/stretchr/testify v1.2.2 + golang.org/x/sys v0.0.0-20190422165155-953cdadca894 +) diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum new file mode 100644 index 00000000..596c318b --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/go.sum @@ -0,0 +1,16 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs= +github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go new file mode 100644 index 00000000..098a21a0 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -0,0 +1,121 @@ +package logrus + +import ( + "bytes" + "encoding/json" + "fmt" + "runtime" +) + +type fieldKey string + +// FieldMap allows customization of the key names for default fields. +type FieldMap map[fieldKey]string + +func (f FieldMap) resolve(key fieldKey) string { + if k, ok := f[key]; ok { + return k + } + + return string(key) +} + +// JSONFormatter formats logs into parsable json +type JSONFormatter struct { + // TimestampFormat sets the format used for marshaling timestamps. + TimestampFormat string + + // DisableTimestamp allows disabling automatic timestamps in output + DisableTimestamp bool + + // DataKey allows users to put all the log entry parameters into a nested dictionary at a given key. + DataKey string + + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &JSONFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message", + // FieldKeyFunc: "@caller", + // }, + // } + FieldMap FieldMap + + // CallerPrettyfier can be set by the user to modify the content + // of the function and file keys in the json data when ReportCaller is + // activated. If any of the returned value is the empty string the + // corresponding key will be removed from json fields. + CallerPrettyfier func(*runtime.Frame) (function string, file string) + + // PrettyPrint will indent all json logs + PrettyPrint bool +} + +// Format renders a single log entry +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields, len(entry.Data)+4) + for k, v := range entry.Data { + switch v := v.(type) { + case error: + // Otherwise errors are ignored by `encoding/json` + // https://github.com/sirupsen/logrus/issues/137 + data[k] = v.Error() + default: + data[k] = v + } + } + + if f.DataKey != "" { + newData := make(Fields, 4) + newData[f.DataKey] = data + data = newData + } + + prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + + if entry.err != "" { + data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err + } + if !f.DisableTimestamp { + data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) + } + data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message + data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() + if entry.HasCaller() { + funcVal := entry.Caller.Function + fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + if f.CallerPrettyfier != nil { + funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + } + if funcVal != "" { + data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal + } + if fileVal != "" { + data[f.FieldMap.resolve(FieldKeyFile)] = fileVal + } + } + + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + + encoder := json.NewEncoder(b) + if f.PrettyPrint { + encoder.SetIndent("", " ") + } + if err := encoder.Encode(data); err != nil { + return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err) + } + + return b.Bytes(), nil +} diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go new file mode 100644 index 00000000..c0c0b1e5 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -0,0 +1,351 @@ +package logrus + +import ( + "context" + "io" + "os" + "sync" + "sync/atomic" + "time" +) + +type Logger struct { + // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a + // file, or leave it default which is `os.Stderr`. You can also set this to + // something more adventurous, such as logging to Kafka. + Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging + // levels and log entries. For example, to send errors to an error tracking + // service, log to StatsD or dump the core on fatal errors. + Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The + // included formatters are `TextFormatter` and `JSONFormatter` for which + // TextFormatter is the default. In development (when a TTY is attached) it + // logs with colors, but to a file it wouldn't. You can easily implement your + // own that implements the `Formatter` interface, see the `README` or included + // formatters for examples. + Formatter Formatter + + // Flag for whether to log caller info (off by default) + ReportCaller bool + + // The logging level the logger should log at. This is typically (and defaults + // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be + // logged. + Level Level + // Used to sync writing to the log. Locking is enabled by Default + mu MutexWrap + // Reusable empty entry + entryPool sync.Pool + // Function to exit the application, defaults to `os.Exit()` + ExitFunc exitFunc +} + +type exitFunc func(int) + +type MutexWrap struct { + lock sync.Mutex + disabled bool +} + +func (mw *MutexWrap) Lock() { + if !mw.disabled { + mw.lock.Lock() + } +} + +func (mw *MutexWrap) Unlock() { + if !mw.disabled { + mw.lock.Unlock() + } +} + +func (mw *MutexWrap) Disable() { + mw.disabled = true +} + +// Creates a new logger. Configuration should be set by changing `Formatter`, +// `Out` and `Hooks` directly on the default logger instance. You can also just +// instantiate your own: +// +// var log = &Logger{ +// Out: os.Stderr, +// Formatter: new(JSONFormatter), +// Hooks: make(LevelHooks), +// Level: logrus.DebugLevel, +// } +// +// It's recommended to make this a global instance called `log`. +func New() *Logger { + return &Logger{ + Out: os.Stderr, + Formatter: new(TextFormatter), + Hooks: make(LevelHooks), + Level: InfoLevel, + ExitFunc: os.Exit, + ReportCaller: false, + } +} + +func (logger *Logger) newEntry() *Entry { + entry, ok := logger.entryPool.Get().(*Entry) + if ok { + return entry + } + return NewEntry(logger) +} + +func (logger *Logger) releaseEntry(entry *Entry) { + entry.Data = map[string]interface{}{} + logger.entryPool.Put(entry) +} + +// Adds a field to the log entry, note that it doesn't log until you call +// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry. +// If you want multiple fields, use `WithFields`. +func (logger *Logger) WithField(key string, value interface{}) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithField(key, value) +} + +// Adds a struct of fields to the log entry. All it does is call `WithField` for +// each `Field`. +func (logger *Logger) WithFields(fields Fields) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithFields(fields) +} + +// Add an error as single field to the log entry. All it does is call +// `WithError` for the given `error`. +func (logger *Logger) WithError(err error) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithError(err) +} + +// Add a context to the log entry. +func (logger *Logger) WithContext(ctx context.Context) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithContext(ctx) +} + +// Overrides the time of the log entry. +func (logger *Logger) WithTime(t time.Time) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithTime(t) +} + +func (logger *Logger) Logf(level Level, format string, args ...interface{}) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Logf(level, format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Tracef(format string, args ...interface{}) { + logger.Logf(TraceLevel, format, args...) +} + +func (logger *Logger) Debugf(format string, args ...interface{}) { + logger.Logf(DebugLevel, format, args...) +} + +func (logger *Logger) Infof(format string, args ...interface{}) { + logger.Logf(InfoLevel, format, args...) +} + +func (logger *Logger) Printf(format string, args ...interface{}) { + entry := logger.newEntry() + entry.Printf(format, args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnf(format string, args ...interface{}) { + logger.Logf(WarnLevel, format, args...) +} + +func (logger *Logger) Warningf(format string, args ...interface{}) { + logger.Warnf(format, args...) +} + +func (logger *Logger) Errorf(format string, args ...interface{}) { + logger.Logf(ErrorLevel, format, args...) +} + +func (logger *Logger) Fatalf(format string, args ...interface{}) { + logger.Logf(FatalLevel, format, args...) + logger.Exit(1) +} + +func (logger *Logger) Panicf(format string, args ...interface{}) { + logger.Logf(PanicLevel, format, args...) +} + +func (logger *Logger) Log(level Level, args ...interface{}) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Log(level, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Trace(args ...interface{}) { + logger.Log(TraceLevel, args...) +} + +func (logger *Logger) Debug(args ...interface{}) { + logger.Log(DebugLevel, args...) +} + +func (logger *Logger) Info(args ...interface{}) { + logger.Log(InfoLevel, args...) +} + +func (logger *Logger) Print(args ...interface{}) { + entry := logger.newEntry() + entry.Print(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warn(args ...interface{}) { + logger.Log(WarnLevel, args...) +} + +func (logger *Logger) Warning(args ...interface{}) { + logger.Warn(args...) +} + +func (logger *Logger) Error(args ...interface{}) { + logger.Log(ErrorLevel, args...) +} + +func (logger *Logger) Fatal(args ...interface{}) { + logger.Log(FatalLevel, args...) + logger.Exit(1) +} + +func (logger *Logger) Panic(args ...interface{}) { + logger.Log(PanicLevel, args...) +} + +func (logger *Logger) Logln(level Level, args ...interface{}) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Logln(level, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Traceln(args ...interface{}) { + logger.Logln(TraceLevel, args...) +} + +func (logger *Logger) Debugln(args ...interface{}) { + logger.Logln(DebugLevel, args...) +} + +func (logger *Logger) Infoln(args ...interface{}) { + logger.Logln(InfoLevel, args...) +} + +func (logger *Logger) Println(args ...interface{}) { + entry := logger.newEntry() + entry.Println(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnln(args ...interface{}) { + logger.Logln(WarnLevel, args...) +} + +func (logger *Logger) Warningln(args ...interface{}) { + logger.Warnln(args...) +} + +func (logger *Logger) Errorln(args ...interface{}) { + logger.Logln(ErrorLevel, args...) +} + +func (logger *Logger) Fatalln(args ...interface{}) { + logger.Logln(FatalLevel, args...) + logger.Exit(1) +} + +func (logger *Logger) Panicln(args ...interface{}) { + logger.Logln(PanicLevel, args...) +} + +func (logger *Logger) Exit(code int) { + runHandlers() + if logger.ExitFunc == nil { + logger.ExitFunc = os.Exit + } + logger.ExitFunc(code) +} + +//When file is opened with appending mode, it's safe to +//write concurrently to a file (within 4k message on Linux). +//In these cases user can choose to disable the lock. +func (logger *Logger) SetNoLock() { + logger.mu.Disable() +} + +func (logger *Logger) level() Level { + return Level(atomic.LoadUint32((*uint32)(&logger.Level))) +} + +// SetLevel sets the logger level. +func (logger *Logger) SetLevel(level Level) { + atomic.StoreUint32((*uint32)(&logger.Level), uint32(level)) +} + +// GetLevel returns the logger level. +func (logger *Logger) GetLevel() Level { + return logger.level() +} + +// AddHook adds a hook to the logger hooks. +func (logger *Logger) AddHook(hook Hook) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Hooks.Add(hook) +} + +// IsLevelEnabled checks if the log level of the logger is greater than the level param +func (logger *Logger) IsLevelEnabled(level Level) bool { + return logger.level() >= level +} + +// SetFormatter sets the logger formatter. +func (logger *Logger) SetFormatter(formatter Formatter) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Formatter = formatter +} + +// SetOutput sets the logger output. +func (logger *Logger) SetOutput(output io.Writer) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Out = output +} + +func (logger *Logger) SetReportCaller(reportCaller bool) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.ReportCaller = reportCaller +} + +// ReplaceHooks replaces the logger hooks and returns the old ones +func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { + logger.mu.Lock() + oldHooks := logger.Hooks + logger.Hooks = hooks + logger.mu.Unlock() + return oldHooks +} diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go new file mode 100644 index 00000000..8644761f --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -0,0 +1,186 @@ +package logrus + +import ( + "fmt" + "log" + "strings" +) + +// Fields type, used to pass to `WithFields`. +type Fields map[string]interface{} + +// Level type +type Level uint32 + +// Convert the Level to a string. E.g. PanicLevel becomes "panic". +func (level Level) String() string { + if b, err := level.MarshalText(); err == nil { + return string(b) + } else { + return "unknown" + } +} + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (Level, error) { + switch strings.ToLower(lvl) { + case "panic": + return PanicLevel, nil + case "fatal": + return FatalLevel, nil + case "error": + return ErrorLevel, nil + case "warn", "warning": + return WarnLevel, nil + case "info": + return InfoLevel, nil + case "debug": + return DebugLevel, nil + case "trace": + return TraceLevel, nil + } + + var l Level + return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (level *Level) UnmarshalText(text []byte) error { + l, err := ParseLevel(string(text)) + if err != nil { + return err + } + + *level = Level(l) + + return nil +} + +func (level Level) MarshalText() ([]byte, error) { + switch level { + case TraceLevel: + return []byte("trace"), nil + case DebugLevel: + return []byte("debug"), nil + case InfoLevel: + return []byte("info"), nil + case WarnLevel: + return []byte("warning"), nil + case ErrorLevel: + return []byte("error"), nil + case FatalLevel: + return []byte("fatal"), nil + case PanicLevel: + return []byte("panic"), nil + } + + return nil, fmt.Errorf("not a valid logrus level %d", level) +} + +// A constant exposing all logging levels +var AllLevels = []Level{ + PanicLevel, + FatalLevel, + ErrorLevel, + WarnLevel, + InfoLevel, + DebugLevel, + TraceLevel, +} + +// These are the different logging levels. You can set the logging level to log +// on your instance of logger, obtained with `logrus.New()`. +const ( + // PanicLevel level, highest level of severity. Logs and then calls panic with the + // message passed to Debug, Info, ... + PanicLevel Level = iota + // FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the + // logging level is set to Panic. + FatalLevel + // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel + // InfoLevel level. General operational entries about what's going on inside the + // application. + InfoLevel + // DebugLevel level. Usually only enabled when debugging. Very verbose logging. + DebugLevel + // TraceLevel level. Designates finer-grained informational events than the Debug. + TraceLevel +) + +// Won't compile if StdLogger can't be realized by a log.Logger +var ( + _ StdLogger = &log.Logger{} + _ StdLogger = &Entry{} + _ StdLogger = &Logger{} +) + +// StdLogger is what your logrus-enabled library should take, that way +// it'll accept a stdlib logger and a logrus logger. There's no standard +// interface, this is the closest we get, unfortunately. +type StdLogger interface { + Print(...interface{}) + Printf(string, ...interface{}) + Println(...interface{}) + + Fatal(...interface{}) + Fatalf(string, ...interface{}) + Fatalln(...interface{}) + + Panic(...interface{}) + Panicf(string, ...interface{}) + Panicln(...interface{}) +} + +// The FieldLogger interface generalizes the Entry and Logger types +type FieldLogger interface { + WithField(key string, value interface{}) *Entry + WithFields(fields Fields) *Entry + WithError(err error) *Entry + + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Printf(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Warningf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) + Panicf(format string, args ...interface{}) + + Debug(args ...interface{}) + Info(args ...interface{}) + Print(args ...interface{}) + Warn(args ...interface{}) + Warning(args ...interface{}) + Error(args ...interface{}) + Fatal(args ...interface{}) + Panic(args ...interface{}) + + Debugln(args ...interface{}) + Infoln(args ...interface{}) + Println(args ...interface{}) + Warnln(args ...interface{}) + Warningln(args ...interface{}) + Errorln(args ...interface{}) + Fatalln(args ...interface{}) + Panicln(args ...interface{}) + + // IsDebugEnabled() bool + // IsInfoEnabled() bool + // IsWarnEnabled() bool + // IsErrorEnabled() bool + // IsFatalEnabled() bool + // IsPanicEnabled() bool +} + +// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is +// here for consistancy. Do not use. Use Logger or Entry instead. +type Ext1FieldLogger interface { + FieldLogger + Tracef(format string, args ...interface{}) + Trace(args ...interface{}) + Traceln(args ...interface{}) +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go new file mode 100644 index 00000000..3c4f43f9 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go @@ -0,0 +1,13 @@ +// +build darwin dragonfly freebsd netbsd openbsd + +package logrus + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TIOCGETA + +func isTerminal(fd int) bool { + _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + return err == nil +} + diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go new file mode 100644 index 00000000..97af92c6 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go @@ -0,0 +1,11 @@ +// +build js nacl plan9 + +package logrus + +import ( + "io" +) + +func checkIfTerminal(w io.Writer) bool { + return false +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go new file mode 100644 index 00000000..3293fb3c --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -0,0 +1,17 @@ +// +build !appengine,!js,!windows,!nacl,!plan9 + +package logrus + +import ( + "io" + "os" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + return isTerminal(int(v.Fd())) + default: + return false + } +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go new file mode 100644 index 00000000..f6710b3b --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go @@ -0,0 +1,11 @@ +package logrus + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func isTerminal(fd int) bool { + _, err := unix.IoctlGetTermio(fd, unix.TCGETA) + return err == nil +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go new file mode 100644 index 00000000..355dc966 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go @@ -0,0 +1,13 @@ +// +build linux aix + +package logrus + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS + +func isTerminal(fd int) bool { + _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + return err == nil +} + diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go new file mode 100644 index 00000000..572889db --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go @@ -0,0 +1,34 @@ +// +build !appengine,!js,windows + +package logrus + +import ( + "io" + "os" + "syscall" + + sequences "github.com/konsorten/go-windows-terminal-sequences" +) + +func initTerminal(w io.Writer) { + switch v := w.(type) { + case *os.File: + sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true) + } +} + +func checkIfTerminal(w io.Writer) bool { + var ret bool + switch v := w.(type) { + case *os.File: + var mode uint32 + err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode) + ret = (err == nil) + default: + ret = false + } + if ret { + initTerminal(w) + } + return ret +} diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go new file mode 100644 index 00000000..e01587c4 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -0,0 +1,295 @@ +package logrus + +import ( + "bytes" + "fmt" + "os" + "runtime" + "sort" + "strings" + "sync" + "time" +) + +const ( + red = 31 + yellow = 33 + blue = 36 + gray = 37 +) + +var baseTimestamp time.Time + +func init() { + baseTimestamp = time.Now() +} + +// TextFormatter formats logs into text +type TextFormatter struct { + // Set to true to bypass checking for a TTY before outputting colors. + ForceColors bool + + // Force disabling colors. + DisableColors bool + + // Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/ + EnvironmentOverrideColors bool + + // Disable timestamp logging. useful when output is redirected to logging + // system that already adds timestamps. + DisableTimestamp bool + + // Enable logging the full timestamp when a TTY is attached instead of just + // the time passed since beginning of execution. + FullTimestamp bool + + // TimestampFormat to use for display when a full timestamp is printed + TimestampFormat string + + // The fields are sorted by default for a consistent output. For applications + // that log extremely frequently and don't use the JSON formatter this may not + // be desired. + DisableSorting bool + + // The keys sorting function, when uninitialized it uses sort.Strings. + SortingFunc func([]string) + + // Disables the truncation of the level text to 4 characters. + DisableLevelTruncation bool + + // QuoteEmptyFields will wrap empty fields in quotes if true + QuoteEmptyFields bool + + // Whether the logger's out is to a terminal + isTerminal bool + + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &TextFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message"}} + FieldMap FieldMap + + // CallerPrettyfier can be set by the user to modify the content + // of the function and file keys in the data when ReportCaller is + // activated. If any of the returned value is the empty string the + // corresponding key will be removed from fields. + CallerPrettyfier func(*runtime.Frame) (function string, file string) + + terminalInitOnce sync.Once +} + +func (f *TextFormatter) init(entry *Entry) { + if entry.Logger != nil { + f.isTerminal = checkIfTerminal(entry.Logger.Out) + } +} + +func (f *TextFormatter) isColored() bool { + isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) + + if f.EnvironmentOverrideColors { + if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { + isColored = true + } else if ok && force == "0" { + isColored = false + } else if os.Getenv("CLICOLOR") == "0" { + isColored = false + } + } + + return isColored && !f.DisableColors +} + +// Format renders a single log entry +func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields) + for k, v := range entry.Data { + data[k] = v + } + prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + keys := make([]string, 0, len(data)) + for k := range data { + keys = append(keys, k) + } + + var funcVal, fileVal string + + fixedKeys := make([]string, 0, 4+len(data)) + if !f.DisableTimestamp { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) + } + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel)) + if entry.Message != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg)) + } + if entry.err != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError)) + } + if entry.HasCaller() { + if f.CallerPrettyfier != nil { + funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + } else { + funcVal = entry.Caller.Function + fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + } + + if funcVal != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc)) + } + if fileVal != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFile)) + } + } + + if !f.DisableSorting { + if f.SortingFunc == nil { + sort.Strings(keys) + fixedKeys = append(fixedKeys, keys...) + } else { + if !f.isColored() { + fixedKeys = append(fixedKeys, keys...) + f.SortingFunc(fixedKeys) + } else { + f.SortingFunc(keys) + } + } + } else { + fixedKeys = append(fixedKeys, keys...) + } + + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + + f.terminalInitOnce.Do(func() { f.init(entry) }) + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + if f.isColored() { + f.printColored(b, entry, keys, data, timestampFormat) + } else { + + for _, key := range fixedKeys { + var value interface{} + switch { + case key == f.FieldMap.resolve(FieldKeyTime): + value = entry.Time.Format(timestampFormat) + case key == f.FieldMap.resolve(FieldKeyLevel): + value = entry.Level.String() + case key == f.FieldMap.resolve(FieldKeyMsg): + value = entry.Message + case key == f.FieldMap.resolve(FieldKeyLogrusError): + value = entry.err + case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller(): + value = funcVal + case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller(): + value = fileVal + default: + value = data[key] + } + f.appendKeyValue(b, key, value) + } + } + + b.WriteByte('\n') + return b.Bytes(), nil +} + +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) { + var levelColor int + switch entry.Level { + case DebugLevel, TraceLevel: + levelColor = gray + case WarnLevel: + levelColor = yellow + case ErrorLevel, FatalLevel, PanicLevel: + levelColor = red + default: + levelColor = blue + } + + levelText := strings.ToUpper(entry.Level.String()) + if !f.DisableLevelTruncation { + levelText = levelText[0:4] + } + + // Remove a single newline if it already exists in the message to keep + // the behavior of logrus text_formatter the same as the stdlib log package + entry.Message = strings.TrimSuffix(entry.Message, "\n") + + caller := "" + if entry.HasCaller() { + funcVal := fmt.Sprintf("%s()", entry.Caller.Function) + fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + + if f.CallerPrettyfier != nil { + funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + } + + if fileVal == "" { + caller = funcVal + } else if funcVal == "" { + caller = fileVal + } else { + caller = fileVal + " " + funcVal + } + } + + if f.DisableTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) + } else if !f.FullTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) + } else { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) + } + for _, k := range keys { + v := data[k] + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) + f.appendValue(b, v) + } +} + +func (f *TextFormatter) needsQuoting(text string) bool { + if f.QuoteEmptyFields && len(text) == 0 { + return true + } + for _, ch := range text { + if !((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { + return true + } + } + return false +} + +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { + if b.Len() > 0 { + b.WriteByte(' ') + } + b.WriteString(key) + b.WriteByte('=') + f.appendValue(b, value) +} + +func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { + stringVal, ok := value.(string) + if !ok { + stringVal = fmt.Sprint(value) + } + + if !f.needsQuoting(stringVal) { + b.WriteString(stringVal) + } else { + b.WriteString(fmt.Sprintf("%q", stringVal)) + } +} diff --git a/vendor/github.com/spacemonkeygo/openssl/.gitignore b/vendor/github.com/spacemonkeygo/openssl/.gitignore new file mode 100644 index 00000000..805d350b --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/.gitignore @@ -0,0 +1 @@ +openssl.test diff --git a/vendor/github.com/spacemonkeygo/openssl/AUTHORS b/vendor/github.com/spacemonkeygo/openssl/AUTHORS new file mode 100644 index 00000000..a048c1ea --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/AUTHORS @@ -0,0 +1,24 @@ +Andrew Brampton +Anton Baklanov +Carlos Martín Nieto +Charles Strahan +Christopher Dudley +Christopher Fredericks +Colin Misare +dequis +Gabriel Russell +Giulio +Jakob Unterwurzacher +Juuso Haavisto +kujenga +Phus Lu +Russ Egan +Ryan Hileman +Scott J. Goldman +Scott Kidder +Space Monkey, Inc +Stephen Gallagher +Viacheslav Biriukov +Zack Owens +Ramesh Rayaprolu +Paras Shah diff --git a/vendor/github.com/spacemonkeygo/openssl/LICENSE b/vendor/github.com/spacemonkeygo/openssl/LICENSE new file mode 100644 index 00000000..37ec93a1 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/spacemonkeygo/openssl/README.md b/vendor/github.com/spacemonkeygo/openssl/README.md new file mode 100644 index 00000000..854df05a --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/README.md @@ -0,0 +1,30 @@ +# OpenSSL bindings for Go + +Please see http://godoc.org/github.com/spacemonkeygo/openssl for more info + +### License + +Copyright (C) 2017. See AUTHORS. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +### Using on macOS +1. Install [homebrew](http://brew.sh/) +2. `$ brew install openssl` or `$ brew install openssl@1.1` + +### Using on Windows +1. Install [mingw-w64](http://mingw-w64.sourceforge.net/) +2. Install [pkg-config-lite](http://sourceforge.net/projects/pkgconfiglite) +3. Build (or install precompiled) openssl for mingw32-w64 +4. Set __PKG\_CONFIG\_PATH__ to the directory containing openssl.pc + (i.e. c:\mingw64\mingw64\lib\pkgconfig) diff --git a/vendor/github.com/spacemonkeygo/openssl/bio.go b/vendor/github.com/spacemonkeygo/openssl/bio.go new file mode 100644 index 00000000..9fe32aa8 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/bio.go @@ -0,0 +1,305 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "io" + "reflect" + "sync" + "unsafe" +) + +const ( + SSLRecordSize = 16 * 1024 +) + +func nonCopyGoBytes(ptr uintptr, length int) []byte { + var slice []byte + header := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) + header.Cap = length + header.Len = length + header.Data = ptr + return slice +} + +func nonCopyCString(data *C.char, size C.int) []byte { + return nonCopyGoBytes(uintptr(unsafe.Pointer(data)), int(size)) +} + +var writeBioMapping = newMapping() + +type writeBio struct { + data_mtx sync.Mutex + op_mtx sync.Mutex + buf []byte + release_buffers bool +} + +func loadWritePtr(b *C.BIO) *writeBio { + t := token(C.X_BIO_get_data(b)) + return (*writeBio)(writeBioMapping.Get(t)) +} + +func bioClearRetryFlags(b *C.BIO) { + C.X_BIO_clear_flags(b, C.BIO_FLAGS_RWS|C.BIO_FLAGS_SHOULD_RETRY) +} + +func bioSetRetryRead(b *C.BIO) { + C.X_BIO_set_flags(b, C.BIO_FLAGS_READ|C.BIO_FLAGS_SHOULD_RETRY) +} + +//export go_write_bio_write +func go_write_bio_write(b *C.BIO, data *C.char, size C.int) (rc C.int) { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: writeBioWrite panic'd: %v", err) + rc = -1 + } + }() + ptr := loadWritePtr(b) + if ptr == nil || data == nil || size < 0 { + return -1 + } + ptr.data_mtx.Lock() + defer ptr.data_mtx.Unlock() + bioClearRetryFlags(b) + ptr.buf = append(ptr.buf, nonCopyCString(data, size)...) + return size +} + +//export go_write_bio_ctrl +func go_write_bio_ctrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( + rc C.long) { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: writeBioCtrl panic'd: %v", err) + rc = -1 + } + }() + switch cmd { + case C.BIO_CTRL_WPENDING: + return writeBioPending(b) + case C.BIO_CTRL_DUP, C.BIO_CTRL_FLUSH: + return 1 + default: + return 0 + } +} + +func writeBioPending(b *C.BIO) C.long { + ptr := loadWritePtr(b) + if ptr == nil { + return 0 + } + ptr.data_mtx.Lock() + defer ptr.data_mtx.Unlock() + return C.long(len(ptr.buf)) +} + +func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { + b.op_mtx.Lock() + defer b.op_mtx.Unlock() + + // write whatever data we currently have + b.data_mtx.Lock() + data := b.buf + b.data_mtx.Unlock() + + if len(data) == 0 { + return 0, nil + } + n, err := w.Write(data) + + // subtract however much data we wrote from the buffer + b.data_mtx.Lock() + b.buf = b.buf[:copy(b.buf, b.buf[n:])] + if b.release_buffers && len(b.buf) == 0 { + b.buf = nil + } + b.data_mtx.Unlock() + + return int64(n), err +} + +func (self *writeBio) Disconnect(b *C.BIO) { + if loadWritePtr(b) == self { + writeBioMapping.Del(token(C.X_BIO_get_data(b))) + C.X_BIO_set_data(b, nil) + } +} + +func (b *writeBio) MakeCBIO() *C.BIO { + rv := C.X_BIO_new_write_bio() + token := writeBioMapping.Add(unsafe.Pointer(b)) + C.X_BIO_set_data(rv, unsafe.Pointer(token)) + return rv +} + +var readBioMapping = newMapping() + +type readBio struct { + data_mtx sync.Mutex + op_mtx sync.Mutex + buf []byte + eof bool + release_buffers bool +} + +func loadReadPtr(b *C.BIO) *readBio { + return (*readBio)(readBioMapping.Get(token(C.X_BIO_get_data(b)))) +} + +//export go_read_bio_read +func go_read_bio_read(b *C.BIO, data *C.char, size C.int) (rc C.int) { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: go_read_bio_read panic'd: %v", err) + rc = -1 + } + }() + ptr := loadReadPtr(b) + if ptr == nil || size < 0 { + return -1 + } + ptr.data_mtx.Lock() + defer ptr.data_mtx.Unlock() + bioClearRetryFlags(b) + if len(ptr.buf) == 0 { + if ptr.eof { + return 0 + } + bioSetRetryRead(b) + return -1 + } + if size == 0 || data == nil { + return C.int(len(ptr.buf)) + } + n := copy(nonCopyCString(data, size), ptr.buf) + ptr.buf = ptr.buf[:copy(ptr.buf, ptr.buf[n:])] + if ptr.release_buffers && len(ptr.buf) == 0 { + ptr.buf = nil + } + return C.int(n) +} + +//export go_read_bio_ctrl +func go_read_bio_ctrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( + rc C.long) { + + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: readBioCtrl panic'd: %v", err) + rc = -1 + } + }() + switch cmd { + case C.BIO_CTRL_PENDING: + return readBioPending(b) + case C.BIO_CTRL_DUP, C.BIO_CTRL_FLUSH: + return 1 + default: + return 0 + } +} + +func readBioPending(b *C.BIO) C.long { + ptr := loadReadPtr(b) + if ptr == nil { + return 0 + } + ptr.data_mtx.Lock() + defer ptr.data_mtx.Unlock() + return C.long(len(ptr.buf)) +} + +func (b *readBio) ReadFromOnce(r io.Reader) (n int, err error) { + b.op_mtx.Lock() + defer b.op_mtx.Unlock() + + // make sure we have a destination that fits at least one SSL record + b.data_mtx.Lock() + if cap(b.buf) < len(b.buf)+SSLRecordSize { + new_buf := make([]byte, len(b.buf), len(b.buf)+SSLRecordSize) + copy(new_buf, b.buf) + b.buf = new_buf + } + dst := b.buf[len(b.buf):cap(b.buf)] + dst_slice := b.buf + b.data_mtx.Unlock() + + n, err = r.Read(dst) + b.data_mtx.Lock() + defer b.data_mtx.Unlock() + if n > 0 { + if len(dst_slice) != len(b.buf) { + // someone shrunk the buffer, so we read in too far ahead and we + // need to slide backwards + copy(b.buf[len(b.buf):len(b.buf)+n], dst) + } + b.buf = b.buf[:len(b.buf)+n] + } + return n, err +} + +func (b *readBio) MakeCBIO() *C.BIO { + rv := C.X_BIO_new_read_bio() + token := readBioMapping.Add(unsafe.Pointer(b)) + C.X_BIO_set_data(rv, unsafe.Pointer(token)) + return rv +} + +func (self *readBio) Disconnect(b *C.BIO) { + if loadReadPtr(b) == self { + readBioMapping.Del(token(C.X_BIO_get_data(b))) + C.X_BIO_set_data(b, nil) + } +} + +func (b *readBio) MarkEOF() { + b.data_mtx.Lock() + defer b.data_mtx.Unlock() + b.eof = true +} + +type anyBio C.BIO + +func asAnyBio(b *C.BIO) *anyBio { return (*anyBio)(b) } + +func (b *anyBio) Read(buf []byte) (n int, err error) { + if len(buf) == 0 { + return 0, nil + } + n = int(C.X_BIO_read((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) + if n <= 0 { + return 0, io.EOF + } + return n, nil +} + +func (b *anyBio) Write(buf []byte) (written int, err error) { + if len(buf) == 0 { + return 0, nil + } + n := int(C.X_BIO_write((*C.BIO)(b), unsafe.Pointer(&buf[0]), + C.int(len(buf)))) + if n != len(buf) { + return n, errors.New("BIO write failed") + } + return n, nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/build.go b/vendor/github.com/spacemonkeygo/openssl/build.go new file mode 100644 index 00000000..5fccc021 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/build.go @@ -0,0 +1,24 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !openssl_static + +package openssl + +// #cgo linux windows pkg-config: libssl libcrypto +// #cgo linux CFLAGS: -Wno-deprecated-declarations +// #cgo darwin CFLAGS: -I/usr/local/opt/openssl@1.1/include -I/usr/local/opt/openssl/include -Wno-deprecated-declarations +// #cgo darwin LDFLAGS: -L/usr/local/opt/openssl@1.1/lib -L/usr/local/opt/openssl/lib -lssl -lcrypto +// #cgo windows CFLAGS: -DWIN32_LEAN_AND_MEAN +import "C" diff --git a/vendor/github.com/spacemonkeygo/openssl/build_static.go b/vendor/github.com/spacemonkeygo/openssl/build_static.go new file mode 100644 index 00000000..c84427bc --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/build_static.go @@ -0,0 +1,24 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build openssl_static + +package openssl + +// #cgo linux windows pkg-config: --static libssl libcrypto +// #cgo linux CFLAGS: -Wno-deprecated-declarations +// #cgo darwin CFLAGS: -I/usr/local/opt/openssl@1.1/include -I/usr/local/opt/openssl/include -Wno-deprecated-declarations +// #cgo darwin LDFLAGS: -L/usr/local/opt/openssl@1.1/lib -L/usr/local/opt/openssl/lib -lssl -lcrypto +// #cgo windows CFLAGS: -DWIN32_LEAN_AND_MEAN +import "C" diff --git a/vendor/github.com/spacemonkeygo/openssl/cert.go b/vendor/github.com/spacemonkeygo/openssl/cert.go new file mode 100644 index 00000000..e841e22c --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/cert.go @@ -0,0 +1,415 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "io/ioutil" + "math/big" + "runtime" + "time" + "unsafe" +) + +type EVP_MD int + +const ( + EVP_NULL EVP_MD = iota + EVP_MD5 EVP_MD = iota + EVP_MD4 EVP_MD = iota + EVP_SHA EVP_MD = iota + EVP_SHA1 EVP_MD = iota + EVP_DSS EVP_MD = iota + EVP_DSS1 EVP_MD = iota + EVP_MDC2 EVP_MD = iota + EVP_RIPEMD160 EVP_MD = iota + EVP_SHA224 EVP_MD = iota + EVP_SHA256 EVP_MD = iota + EVP_SHA384 EVP_MD = iota + EVP_SHA512 EVP_MD = iota +) + +// X509_Version represents a version on an x509 certificate. +type X509_Version int + +// Specify constants for x509 versions because the standard states that they +// are represented internally as one lower than the common version name. +const ( + X509_V1 X509_Version = 0 + X509_V3 X509_Version = 2 +) + +type Certificate struct { + x *C.X509 + Issuer *Certificate + ref interface{} + pubKey PublicKey +} + +type CertificateInfo struct { + Serial *big.Int + Issued time.Duration + Expires time.Duration + Country string + Organization string + CommonName string +} + +type Name struct { + name *C.X509_NAME +} + +// Allocate and return a new Name object. +func NewName() (*Name, error) { + n := C.X509_NAME_new() + if n == nil { + return nil, errors.New("could not create x509 name") + } + name := &Name{name: n} + runtime.SetFinalizer(name, func(n *Name) { + C.X509_NAME_free(n.name) + }) + return name, nil +} + +// AddTextEntry appends a text entry to an X509 NAME. +func (n *Name) AddTextEntry(field, value string) error { + cfield := C.CString(field) + defer C.free(unsafe.Pointer(cfield)) + cvalue := (*C.uchar)(unsafe.Pointer(C.CString(value))) + defer C.free(unsafe.Pointer(cvalue)) + ret := C.X509_NAME_add_entry_by_txt( + n.name, cfield, C.MBSTRING_ASC, cvalue, -1, -1, 0) + if ret != 1 { + return errors.New("failed to add x509 name text entry") + } + return nil +} + +// AddTextEntries allows adding multiple entries to a name in one call. +func (n *Name) AddTextEntries(entries map[string]string) error { + for f, v := range entries { + if err := n.AddTextEntry(f, v); err != nil { + return err + } + } + return nil +} + +// GetEntry returns a name entry based on NID. If no entry, then ("", false) is +// returned. +func (n *Name) GetEntry(nid NID) (entry string, ok bool) { + entrylen := C.X509_NAME_get_text_by_NID(n.name, C.int(nid), nil, 0) + if entrylen == -1 { + return "", false + } + buf := (*C.char)(C.malloc(C.size_t(entrylen + 1))) + defer C.free(unsafe.Pointer(buf)) + C.X509_NAME_get_text_by_NID(n.name, C.int(nid), buf, entrylen+1) + return C.GoStringN(buf, entrylen), true +} + +// NewCertificate generates a basic certificate based +// on the provided CertificateInfo struct +func NewCertificate(info *CertificateInfo, key PublicKey) (*Certificate, error) { + c := &Certificate{x: C.X509_new()} + runtime.SetFinalizer(c, func(c *Certificate) { + C.X509_free(c.x) + }) + + name, err := c.GetSubjectName() + if err != nil { + return nil, err + } + err = name.AddTextEntries(map[string]string{ + "C": info.Country, + "O": info.Organization, + "CN": info.CommonName, + }) + if err != nil { + return nil, err + } + // self-issue for now + if err := c.SetIssuerName(name); err != nil { + return nil, err + } + if err := c.SetSerial(info.Serial); err != nil { + return nil, err + } + if err := c.SetIssueDate(info.Issued); err != nil { + return nil, err + } + if err := c.SetExpireDate(info.Expires); err != nil { + return nil, err + } + if err := c.SetPubKey(key); err != nil { + return nil, err + } + return c, nil +} + +func (c *Certificate) GetSubjectName() (*Name, error) { + n := C.X509_get_subject_name(c.x) + if n == nil { + return nil, errors.New("failed to get subject name") + } + return &Name{name: n}, nil +} + +func (c *Certificate) GetIssuerName() (*Name, error) { + n := C.X509_get_issuer_name(c.x) + if n == nil { + return nil, errors.New("failed to get issuer name") + } + return &Name{name: n}, nil +} + +func (c *Certificate) SetSubjectName(name *Name) error { + if C.X509_set_subject_name(c.x, name.name) != 1 { + return errors.New("failed to set subject name") + } + return nil +} + +// SetIssuer updates the stored Issuer cert +// and the internal x509 Issuer Name of a certificate. +// The stored Issuer reference is used when adding extensions. +func (c *Certificate) SetIssuer(issuer *Certificate) error { + name, err := issuer.GetSubjectName() + if err != nil { + return err + } + if err = c.SetIssuerName(name); err != nil { + return err + } + c.Issuer = issuer + return nil +} + +// SetIssuerName populates the issuer name of a certificate. +// Use SetIssuer instead, if possible. +func (c *Certificate) SetIssuerName(name *Name) error { + if C.X509_set_issuer_name(c.x, name.name) != 1 { + return errors.New("failed to set subject name") + } + return nil +} + +// SetSerial sets the serial of a certificate. +func (c *Certificate) SetSerial(serial *big.Int) error { + sno := C.ASN1_INTEGER_new() + defer C.ASN1_INTEGER_free(sno) + bn := C.BN_new() + defer C.BN_free(bn) + + serialBytes := serial.Bytes() + if bn = C.BN_bin2bn((*C.uchar)(unsafe.Pointer(&serialBytes[0])), C.int(len(serialBytes)), bn); bn == nil { + return errors.New("failed to set serial") + } + if sno = C.BN_to_ASN1_INTEGER(bn, sno); sno == nil { + return errors.New("failed to set serial") + } + if C.X509_set_serialNumber(c.x, sno) != 1 { + return errors.New("failed to set serial") + } + return nil +} + +// SetIssueDate sets the certificate issue date relative to the current time. +func (c *Certificate) SetIssueDate(when time.Duration) error { + offset := C.long(when / time.Second) + result := C.X509_gmtime_adj(C.X_X509_get0_notBefore(c.x), offset) + if result == nil { + return errors.New("failed to set issue date") + } + return nil +} + +// SetExpireDate sets the certificate issue date relative to the current time. +func (c *Certificate) SetExpireDate(when time.Duration) error { + offset := C.long(when / time.Second) + result := C.X509_gmtime_adj(C.X_X509_get0_notAfter(c.x), offset) + if result == nil { + return errors.New("failed to set expire date") + } + return nil +} + +// SetPubKey assigns a new public key to a certificate. +func (c *Certificate) SetPubKey(pubKey PublicKey) error { + c.pubKey = pubKey + if C.X509_set_pubkey(c.x, pubKey.evpPKey()) != 1 { + return errors.New("failed to set public key") + } + return nil +} + +// Sign a certificate using a private key and a digest name. +// Accepted digest names are 'sha256', 'sha384', and 'sha512'. +func (c *Certificate) Sign(privKey PrivateKey, digest EVP_MD) error { + switch digest { + case EVP_SHA256: + case EVP_SHA384: + case EVP_SHA512: + default: + return errors.New("Unsupported digest" + + "You're probably looking for 'EVP_SHA256' or 'EVP_SHA512'.") + } + return c.insecureSign(privKey, digest) +} + +func (c *Certificate) insecureSign(privKey PrivateKey, digest EVP_MD) error { + var md *C.EVP_MD = getDigestFunction(digest) + if C.X509_sign(c.x, privKey.evpPKey(), md) <= 0 { + return errors.New("failed to sign certificate") + } + return nil +} + +func getDigestFunction(digest EVP_MD) (md *C.EVP_MD) { + switch digest { + // please don't use these digest functions + case EVP_NULL: + md = C.X_EVP_md_null() + case EVP_MD5: + md = C.X_EVP_md5() + case EVP_SHA: + md = C.X_EVP_sha() + case EVP_SHA1: + md = C.X_EVP_sha1() + case EVP_DSS: + md = C.X_EVP_dss() + case EVP_DSS1: + md = C.X_EVP_dss1() + case EVP_RIPEMD160: + md = C.X_EVP_ripemd160() + case EVP_SHA224: + md = C.X_EVP_sha224() + // you actually want one of these + case EVP_SHA256: + md = C.X_EVP_sha256() + case EVP_SHA384: + md = C.X_EVP_sha384() + case EVP_SHA512: + md = C.X_EVP_sha512() + } + return md +} + +// Add an extension to a certificate. +// Extension constants are NID_* as found in openssl. +func (c *Certificate) AddExtension(nid NID, value string) error { + issuer := c + if c.Issuer != nil { + issuer = c.Issuer + } + var ctx C.X509V3_CTX + C.X509V3_set_ctx(&ctx, c.x, issuer.x, nil, nil, 0) + ex := C.X509V3_EXT_conf_nid(nil, &ctx, C.int(nid), C.CString(value)) + if ex == nil { + return errors.New("failed to create x509v3 extension") + } + defer C.X509_EXTENSION_free(ex) + if C.X509_add_ext(c.x, ex, -1) <= 0 { + return errors.New("failed to add x509v3 extension") + } + return nil +} + +// Wraps AddExtension using a map of NID to text extension. +// Will return without finishing if it encounters an error. +func (c *Certificate) AddExtensions(extensions map[NID]string) error { + for nid, value := range extensions { + if err := c.AddExtension(nid, value); err != nil { + return err + } + } + return nil +} + +// LoadCertificateFromPEM loads an X509 certificate from a PEM-encoded block. +func LoadCertificateFromPEM(pem_block []byte) (*Certificate, error) { + if len(pem_block) == 0 { + return nil, errors.New("empty pem block") + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), + C.int(len(pem_block))) + cert := C.PEM_read_bio_X509(bio, nil, nil, nil) + C.BIO_free(bio) + if cert == nil { + return nil, errorFromErrorQueue() + } + x := &Certificate{x: cert} + runtime.SetFinalizer(x, func(x *Certificate) { + C.X509_free(x.x) + }) + return x, nil +} + +// MarshalPEM converts the X509 certificate to PEM-encoded format +func (c *Certificate) MarshalPEM() (pem_block []byte, err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + if int(C.PEM_write_bio_X509(bio, c.x)) != 1 { + return nil, errors.New("failed dumping certificate") + } + return ioutil.ReadAll(asAnyBio(bio)) +} + +// PublicKey returns the public key embedded in the X509 certificate. +func (c *Certificate) PublicKey() (PublicKey, error) { + pkey := C.X509_get_pubkey(c.x) + if pkey == nil { + return nil, errors.New("no public key found") + } + key := &pKey{key: pkey} + runtime.SetFinalizer(key, func(key *pKey) { + C.EVP_PKEY_free(key.key) + }) + return key, nil +} + +// GetSerialNumberHex returns the certificate's serial number in hex format +func (c *Certificate) GetSerialNumberHex() (serial string) { + asn1_i := C.X509_get_serialNumber(c.x) + bignum := C.ASN1_INTEGER_to_BN(asn1_i, nil) + hex := C.BN_bn2hex(bignum) + serial = C.GoString(hex) + C.BN_free(bignum) + C.X_OPENSSL_free(unsafe.Pointer(hex)) + return +} + +// GetVersion returns the X509 version of the certificate. +func (c *Certificate) GetVersion() X509_Version { + return X509_Version(C.X_X509_get_version(c.x)) +} + +// SetVersion sets the X509 version of the certificate. +func (c *Certificate) SetVersion(version X509_Version) error { + cvers := C.long(version) + if C.X_X509_set_version(c.x, cvers) != 1 { + return errors.New("failed to set certificate version") + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/ciphers.go b/vendor/github.com/spacemonkeygo/openssl/ciphers.go new file mode 100644 index 00000000..509bf641 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/ciphers.go @@ -0,0 +1,335 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "fmt" + "runtime" + "unsafe" +) + +const ( + GCM_TAG_MAXLEN = 16 +) + +type CipherCtx interface { + Cipher() *Cipher + BlockSize() int + KeySize() int + IVSize() int +} + +type Cipher struct { + ptr *C.EVP_CIPHER +} + +func (c *Cipher) Nid() NID { + return NID(C.X_EVP_CIPHER_nid(c.ptr)) +} + +func (c *Cipher) ShortName() (string, error) { + return Nid2ShortName(c.Nid()) +} + +func (c *Cipher) BlockSize() int { + return int(C.X_EVP_CIPHER_block_size(c.ptr)) +} + +func (c *Cipher) KeySize() int { + return int(C.X_EVP_CIPHER_key_length(c.ptr)) +} + +func (c *Cipher) IVSize() int { + return int(C.X_EVP_CIPHER_iv_length(c.ptr)) +} + +func Nid2ShortName(nid NID) (string, error) { + sn := C.OBJ_nid2sn(C.int(nid)) + if sn == nil { + return "", fmt.Errorf("NID %d not found", nid) + } + return C.GoString(sn), nil +} + +func GetCipherByName(name string) (*Cipher, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + p := C.EVP_get_cipherbyname(cname) + if p == nil { + return nil, fmt.Errorf("Cipher %v not found", name) + } + // we can consider ciphers to use static mem; don't need to free + return &Cipher{ptr: p}, nil +} + +func GetCipherByNid(nid NID) (*Cipher, error) { + sn, err := Nid2ShortName(nid) + if err != nil { + return nil, err + } + return GetCipherByName(sn) +} + +type cipherCtx struct { + ctx *C.EVP_CIPHER_CTX +} + +func newCipherCtx() (*cipherCtx, error) { + cctx := C.EVP_CIPHER_CTX_new() + if cctx == nil { + return nil, errors.New("failed to allocate cipher context") + } + ctx := &cipherCtx{cctx} + runtime.SetFinalizer(ctx, func(ctx *cipherCtx) { + C.EVP_CIPHER_CTX_free(ctx.ctx) + }) + return ctx, nil +} + +func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error { + var kptr, iptr *C.uchar + if key != nil { + if len(key) != ctx.KeySize() { + return fmt.Errorf("bad key size (%d bytes instead of %d)", + len(key), ctx.KeySize()) + } + kptr = (*C.uchar)(&key[0]) + } + if iv != nil { + if len(iv) != ctx.IVSize() { + return fmt.Errorf("bad IV size (%d bytes instead of %d)", + len(iv), ctx.IVSize()) + } + iptr = (*C.uchar)(&iv[0]) + } + if kptr != nil || iptr != nil { + var res C.int + if C.X_EVP_CIPHER_CTX_encrypting(ctx.ctx) != 0 { + res = C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) + } else { + res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) + } + if 1 != res { + return errors.New("failed to apply key/IV") + } + } + return nil +} + +func (ctx *cipherCtx) Cipher() *Cipher { + return &Cipher{ptr: C.X_EVP_CIPHER_CTX_cipher(ctx.ctx)} +} + +func (ctx *cipherCtx) BlockSize() int { + return int(C.X_EVP_CIPHER_CTX_block_size(ctx.ctx)) +} + +func (ctx *cipherCtx) KeySize() int { + return int(C.X_EVP_CIPHER_CTX_key_length(ctx.ctx)) +} + +func (ctx *cipherCtx) IVSize() int { + return int(C.X_EVP_CIPHER_CTX_iv_length(ctx.ctx)) +} + +func (ctx *cipherCtx) SetPadding(pad bool) { + if pad { + C.X_EVP_CIPHER_CTX_set_padding(ctx.ctx, 1) + } else { + C.X_EVP_CIPHER_CTX_set_padding(ctx.ctx, 0) + } +} + +func (ctx *cipherCtx) setCtrl(code, arg int) error { + res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), nil) + if res != 1 { + return fmt.Errorf("failed to set code %d to %d [result %d]", + code, arg, res) + } + return nil +} + +func (ctx *cipherCtx) setCtrlBytes(code, arg int, value []byte) error { + res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), + unsafe.Pointer(&value[0])) + if res != 1 { + return fmt.Errorf("failed to set code %d with arg %d to %x [result %d]", + code, arg, value, res) + } + return nil +} + +func (ctx *cipherCtx) getCtrlInt(code, arg int) (int, error) { + var returnVal C.int + res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), + unsafe.Pointer(&returnVal)) + if res != 1 { + return 0, fmt.Errorf("failed to get code %d with arg %d [result %d]", + code, arg, res) + } + return int(returnVal), nil +} + +func (ctx *cipherCtx) getCtrlBytes(code, arg, expectsize int) ([]byte, error) { + returnVal := make([]byte, expectsize) + res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), + unsafe.Pointer(&returnVal[0])) + if res != 1 { + return nil, fmt.Errorf("failed to get code %d with arg %d [result %d]", + code, arg, res) + } + return returnVal, nil +} + +type EncryptionCipherCtx interface { + CipherCtx + + // pass in plaintext, get back ciphertext. can be called + // multiple times as needed + EncryptUpdate(input []byte) ([]byte, error) + + // call after all plaintext has been passed in; may return + // additional ciphertext if needed to finish off a block + // or extra padding information + EncryptFinal() ([]byte, error) +} + +type DecryptionCipherCtx interface { + CipherCtx + + // pass in ciphertext, get back plaintext. can be called + // multiple times as needed + DecryptUpdate(input []byte) ([]byte, error) + + // call after all ciphertext has been passed in; may return + // additional plaintext if needed to finish off a block + DecryptFinal() ([]byte, error) +} + +type encryptionCipherCtx struct { + *cipherCtx +} + +type decryptionCipherCtx struct { + *cipherCtx +} + +func newEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( + *encryptionCipherCtx, error) { + if c == nil { + return nil, errors.New("null cipher not allowed") + } + ctx, err := newCipherCtx() + if err != nil { + return nil, err + } + var eptr *C.ENGINE + if e != nil { + eptr = e.e + } + if 1 != C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { + return nil, errors.New("failed to initialize cipher context") + } + err = ctx.applyKeyAndIV(key, iv) + if err != nil { + return nil, err + } + return &encryptionCipherCtx{cipherCtx: ctx}, nil +} + +func newDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( + *decryptionCipherCtx, error) { + if c == nil { + return nil, errors.New("null cipher not allowed") + } + ctx, err := newCipherCtx() + if err != nil { + return nil, err + } + var eptr *C.ENGINE + if e != nil { + eptr = e.e + } + if 1 != C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { + return nil, errors.New("failed to initialize cipher context") + } + err = ctx.applyKeyAndIV(key, iv) + if err != nil { + return nil, err + } + return &decryptionCipherCtx{cipherCtx: ctx}, nil +} + +func NewEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( + EncryptionCipherCtx, error) { + return newEncryptionCipherCtx(c, e, key, iv) +} + +func NewDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( + DecryptionCipherCtx, error) { + return newDecryptionCipherCtx(c, e, key, iv) +} + +func (ctx *encryptionCipherCtx) EncryptUpdate(input []byte) ([]byte, error) { + if len(input) == 0 { + return nil, nil + } + outbuf := make([]byte, len(input)+ctx.BlockSize()) + outlen := C.int(len(outbuf)) + res := C.EVP_EncryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen, + (*C.uchar)(&input[0]), C.int(len(input))) + if res != 1 { + return nil, fmt.Errorf("failed to encrypt [result %d]", res) + } + return outbuf[:outlen], nil +} + +func (ctx *decryptionCipherCtx) DecryptUpdate(input []byte) ([]byte, error) { + if len(input) == 0 { + return nil, nil + } + outbuf := make([]byte, len(input)+ctx.BlockSize()) + outlen := C.int(len(outbuf)) + res := C.EVP_DecryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen, + (*C.uchar)(&input[0]), C.int(len(input))) + if res != 1 { + return nil, fmt.Errorf("failed to decrypt [result %d]", res) + } + return outbuf[:outlen], nil +} + +func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) { + outbuf := make([]byte, ctx.BlockSize()) + var outlen C.int + if 1 != C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { + return nil, errors.New("encryption failed") + } + return outbuf[:outlen], nil +} + +func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) { + outbuf := make([]byte, ctx.BlockSize()) + var outlen C.int + if 1 != C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { + // this may mean the tag failed to verify- all previous plaintext + // returned must be considered faked and invalid + return nil, errors.New("decryption failed") + } + return outbuf[:outlen], nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/ciphers_gcm.go b/vendor/github.com/spacemonkeygo/openssl/ciphers_gcm.go new file mode 100644 index 00000000..7b08e0fd --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/ciphers_gcm.go @@ -0,0 +1,152 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include +import "C" + +import ( + "errors" + "fmt" +) + +type AuthenticatedEncryptionCipherCtx interface { + EncryptionCipherCtx + + // data passed in to ExtraData() is part of the final output; it is + // not encrypted itself, but is part of the authenticated data. when + // decrypting or authenticating, pass back with the decryption + // context's ExtraData() + ExtraData([]byte) error + + // use after finalizing encryption to get the authenticating tag + GetTag() ([]byte, error) +} + +type AuthenticatedDecryptionCipherCtx interface { + DecryptionCipherCtx + + // pass in any extra data that was added during encryption with the + // encryption context's ExtraData() + ExtraData([]byte) error + + // use before finalizing decryption to tell the library what the + // tag is expected to be + SetTag([]byte) error +} + +type authEncryptionCipherCtx struct { + *encryptionCipherCtx +} + +type authDecryptionCipherCtx struct { + *decryptionCipherCtx +} + +func getGCMCipher(blocksize int) (*Cipher, error) { + var cipherptr *C.EVP_CIPHER + switch blocksize { + case 256: + cipherptr = C.EVP_aes_256_gcm() + case 192: + cipherptr = C.EVP_aes_192_gcm() + case 128: + cipherptr = C.EVP_aes_128_gcm() + default: + return nil, fmt.Errorf("unknown block size %d", blocksize) + } + return &Cipher{ptr: cipherptr}, nil +} + +func NewGCMEncryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) ( + AuthenticatedEncryptionCipherCtx, error) { + cipher, err := getGCMCipher(blocksize) + if err != nil { + return nil, err + } + ctx, err := newEncryptionCipherCtx(cipher, e, key, nil) + if err != nil { + return nil, err + } + if len(iv) > 0 { + err := ctx.setCtrl(C.EVP_CTRL_GCM_SET_IVLEN, len(iv)) + if err != nil { + return nil, fmt.Errorf("could not set IV len to %d: %s", + len(iv), err) + } + if 1 != C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, nil, + (*C.uchar)(&iv[0])) { + return nil, errors.New("failed to apply IV") + } + } + return &authEncryptionCipherCtx{encryptionCipherCtx: ctx}, nil +} + +func NewGCMDecryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) ( + AuthenticatedDecryptionCipherCtx, error) { + cipher, err := getGCMCipher(blocksize) + if err != nil { + return nil, err + } + ctx, err := newDecryptionCipherCtx(cipher, e, key, nil) + if err != nil { + return nil, err + } + if len(iv) > 0 { + err := ctx.setCtrl(C.EVP_CTRL_GCM_SET_IVLEN, len(iv)) + if err != nil { + return nil, fmt.Errorf("could not set IV len to %d: %s", + len(iv), err) + } + if 1 != C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, nil, + (*C.uchar)(&iv[0])) { + return nil, errors.New("failed to apply IV") + } + } + return &authDecryptionCipherCtx{decryptionCipherCtx: ctx}, nil +} + +func (ctx *authEncryptionCipherCtx) ExtraData(aad []byte) error { + if aad == nil { + return nil + } + var outlen C.int + if 1 != C.EVP_EncryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), + C.int(len(aad))) { + return errors.New("failed to add additional authenticated data") + } + return nil +} + +func (ctx *authDecryptionCipherCtx) ExtraData(aad []byte) error { + if aad == nil { + return nil + } + var outlen C.int + if 1 != C.EVP_DecryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), + C.int(len(aad))) { + return errors.New("failed to add additional authenticated data") + } + return nil +} + +func (ctx *authEncryptionCipherCtx) GetTag() ([]byte, error) { + return ctx.getCtrlBytes(C.EVP_CTRL_GCM_GET_TAG, GCM_TAG_MAXLEN, + GCM_TAG_MAXLEN) +} + +func (ctx *authDecryptionCipherCtx) SetTag(tag []byte) error { + return ctx.setCtrlBytes(C.EVP_CTRL_GCM_SET_TAG, len(tag), tag) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/conn.go b/vendor/github.com/spacemonkeygo/openssl/conn.go new file mode 100644 index 00000000..964551cd --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/conn.go @@ -0,0 +1,620 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "fmt" + "io" + "net" + "runtime" + "sync" + "time" + "unsafe" + + "github.com/spacemonkeygo/openssl/utils" +) + +var ( + zeroReturn = errors.New("zero return") + wantRead = errors.New("want read") + wantWrite = errors.New("want write") + tryAgain = errors.New("try again") +) + +type Conn struct { + *SSL + + conn net.Conn + ctx *Ctx // for gc + into_ssl *readBio + from_ssl *writeBio + is_shutdown bool + mtx sync.Mutex + want_read_future *utils.Future +} + +type VerifyResult int + +const ( + Ok VerifyResult = C.X509_V_OK + UnableToGetIssuerCert VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT + UnableToGetCrl VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_CRL + UnableToDecryptCertSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE + UnableToDecryptCrlSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE + UnableToDecodeIssuerPublicKey VerifyResult = C.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY + CertSignatureFailure VerifyResult = C.X509_V_ERR_CERT_SIGNATURE_FAILURE + CrlSignatureFailure VerifyResult = C.X509_V_ERR_CRL_SIGNATURE_FAILURE + CertNotYetValid VerifyResult = C.X509_V_ERR_CERT_NOT_YET_VALID + CertHasExpired VerifyResult = C.X509_V_ERR_CERT_HAS_EXPIRED + CrlNotYetValid VerifyResult = C.X509_V_ERR_CRL_NOT_YET_VALID + CrlHasExpired VerifyResult = C.X509_V_ERR_CRL_HAS_EXPIRED + ErrorInCertNotBeforeField VerifyResult = C.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD + ErrorInCertNotAfterField VerifyResult = C.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD + ErrorInCrlLastUpdateField VerifyResult = C.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD + ErrorInCrlNextUpdateField VerifyResult = C.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD + OutOfMem VerifyResult = C.X509_V_ERR_OUT_OF_MEM + DepthZeroSelfSignedCert VerifyResult = C.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT + SelfSignedCertInChain VerifyResult = C.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN + UnableToGetIssuerCertLocally VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + UnableToVerifyLeafSignature VerifyResult = C.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE + CertChainTooLong VerifyResult = C.X509_V_ERR_CERT_CHAIN_TOO_LONG + CertRevoked VerifyResult = C.X509_V_ERR_CERT_REVOKED + InvalidCa VerifyResult = C.X509_V_ERR_INVALID_CA + PathLengthExceeded VerifyResult = C.X509_V_ERR_PATH_LENGTH_EXCEEDED + InvalidPurpose VerifyResult = C.X509_V_ERR_INVALID_PURPOSE + CertUntrusted VerifyResult = C.X509_V_ERR_CERT_UNTRUSTED + CertRejected VerifyResult = C.X509_V_ERR_CERT_REJECTED + SubjectIssuerMismatch VerifyResult = C.X509_V_ERR_SUBJECT_ISSUER_MISMATCH + AkidSkidMismatch VerifyResult = C.X509_V_ERR_AKID_SKID_MISMATCH + AkidIssuerSerialMismatch VerifyResult = C.X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH + KeyusageNoCertsign VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_CERTSIGN + UnableToGetCrlIssuer VerifyResult = C.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER + UnhandledCriticalExtension VerifyResult = C.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION + KeyusageNoCrlSign VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN + UnhandledCriticalCrlExtension VerifyResult = C.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION + InvalidNonCa VerifyResult = C.X509_V_ERR_INVALID_NON_CA + ProxyPathLengthExceeded VerifyResult = C.X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED + KeyusageNoDigitalSignature VerifyResult = C.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE + ProxyCertificatesNotAllowed VerifyResult = C.X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED + InvalidExtension VerifyResult = C.X509_V_ERR_INVALID_EXTENSION + InvalidPolicyExtension VerifyResult = C.X509_V_ERR_INVALID_POLICY_EXTENSION + NoExplicitPolicy VerifyResult = C.X509_V_ERR_NO_EXPLICIT_POLICY + UnnestedResource VerifyResult = C.X509_V_ERR_UNNESTED_RESOURCE + ApplicationVerification VerifyResult = C.X509_V_ERR_APPLICATION_VERIFICATION +) + +func newSSL(ctx *C.SSL_CTX) (*C.SSL, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ssl := C.SSL_new(ctx) + if ssl == nil { + return nil, errorFromErrorQueue() + } + return ssl, nil +} + +func newConn(conn net.Conn, ctx *Ctx) (*Conn, error) { + ssl, err := newSSL(ctx.ctx) + if err != nil { + return nil, err + } + + into_ssl := &readBio{} + from_ssl := &writeBio{} + + if ctx.GetMode()&ReleaseBuffers > 0 { + into_ssl.release_buffers = true + from_ssl.release_buffers = true + } + + into_ssl_cbio := into_ssl.MakeCBIO() + from_ssl_cbio := from_ssl.MakeCBIO() + if into_ssl_cbio == nil || from_ssl_cbio == nil { + // these frees are null safe + C.BIO_free(into_ssl_cbio) + C.BIO_free(from_ssl_cbio) + C.SSL_free(ssl) + return nil, errors.New("failed to allocate memory BIO") + } + + // the ssl object takes ownership of these objects now + C.SSL_set_bio(ssl, into_ssl_cbio, from_ssl_cbio) + + s := &SSL{ssl: ssl} + C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s)) + + c := &Conn{ + SSL: s, + + conn: conn, + ctx: ctx, + into_ssl: into_ssl, + from_ssl: from_ssl} + runtime.SetFinalizer(c, func(c *Conn) { + c.into_ssl.Disconnect(into_ssl_cbio) + c.from_ssl.Disconnect(from_ssl_cbio) + C.SSL_free(c.ssl) + }) + return c, nil +} + +// Client wraps an existing stream connection and puts it in the connect state +// for any subsequent handshakes. +// +// IMPORTANT NOTE: if you use this method instead of Dial to construct an SSL +// connection, you are responsible for verifying the peer's hostname. +// Otherwise, you are vulnerable to MITM attacks. +// +// Client also does not set up SNI for you like Dial does. +// +// Client connections probably won't work for you unless you set a verify +// location or add some certs to the certificate store of the client context +// you're using. This library is not nice enough to use the system certificate +// store by default for you yet. +func Client(conn net.Conn, ctx *Ctx) (*Conn, error) { + c, err := newConn(conn, ctx) + if err != nil { + return nil, err + } + C.SSL_set_connect_state(c.ssl) + return c, nil +} + +// Server wraps an existing stream connection and puts it in the accept state +// for any subsequent handshakes. +func Server(conn net.Conn, ctx *Ctx) (*Conn, error) { + c, err := newConn(conn, ctx) + if err != nil { + return nil, err + } + C.SSL_set_accept_state(c.ssl) + return c, nil +} + +func (c *Conn) GetCtx() *Ctx { return c.ctx } + +func (c *Conn) CurrentCipher() (string, error) { + p := C.X_SSL_get_cipher_name(c.ssl) + if p == nil { + return "", errors.New("Session not established") + } + + return C.GoString(p), nil +} + +func (c *Conn) fillInputBuffer() error { + for { + n, err := c.into_ssl.ReadFromOnce(c.conn) + if n == 0 && err == nil { + continue + } + if err == io.EOF { + c.into_ssl.MarkEOF() + return c.Close() + } + return err + } +} + +func (c *Conn) flushOutputBuffer() error { + _, err := c.from_ssl.WriteTo(c.conn) + return err +} + +func (c *Conn) getErrorHandler(rv C.int, errno error) func() error { + errcode := C.SSL_get_error(c.ssl, rv) + switch errcode { + case C.SSL_ERROR_ZERO_RETURN: + return func() error { + c.Close() + return io.ErrUnexpectedEOF + } + case C.SSL_ERROR_WANT_READ: + go c.flushOutputBuffer() + if c.want_read_future != nil { + want_read_future := c.want_read_future + return func() error { + _, err := want_read_future.Get() + return err + } + } + c.want_read_future = utils.NewFuture() + want_read_future := c.want_read_future + return func() (err error) { + defer func() { + c.mtx.Lock() + c.want_read_future = nil + c.mtx.Unlock() + want_read_future.Set(nil, err) + }() + err = c.fillInputBuffer() + if err != nil { + return err + } + return tryAgain + } + case C.SSL_ERROR_WANT_WRITE: + return func() error { + err := c.flushOutputBuffer() + if err != nil { + return err + } + return tryAgain + } + case C.SSL_ERROR_SYSCALL: + var err error + if C.ERR_peek_error() == 0 { + switch rv { + case 0: + err = errors.New("protocol-violating EOF") + case -1: + err = errno + default: + err = errorFromErrorQueue() + } + } else { + err = errorFromErrorQueue() + } + return func() error { return err } + default: + err := errorFromErrorQueue() + return func() error { return err } + } +} + +func (c *Conn) handleError(errcb func() error) error { + if errcb != nil { + return errcb() + } + return nil +} + +func (c *Conn) handshake() func() error { + c.mtx.Lock() + defer c.mtx.Unlock() + if c.is_shutdown { + return func() error { return io.ErrUnexpectedEOF } + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + rv, errno := C.SSL_do_handshake(c.ssl) + if rv > 0 { + return nil + } + return c.getErrorHandler(rv, errno) +} + +// Handshake performs an SSL handshake. If a handshake is not manually +// triggered, it will run before the first I/O on the encrypted stream. +func (c *Conn) Handshake() error { + err := tryAgain + for err == tryAgain { + err = c.handleError(c.handshake()) + } + go c.flushOutputBuffer() + return err +} + +// PeerCertificate returns the Certificate of the peer with which you're +// communicating. Only valid after a handshake. +func (c *Conn) PeerCertificate() (*Certificate, error) { + c.mtx.Lock() + defer c.mtx.Unlock() + if c.is_shutdown { + return nil, errors.New("connection closed") + } + x := C.SSL_get_peer_certificate(c.ssl) + if x == nil { + return nil, errors.New("no peer certificate found") + } + cert := &Certificate{x: x} + runtime.SetFinalizer(cert, func(cert *Certificate) { + C.X509_free(cert.x) + }) + return cert, nil +} + +// loadCertificateStack loads up a stack of x509 certificates and returns them, +// handling memory ownership. +func (c *Conn) loadCertificateStack(sk *C.struct_stack_st_X509) ( + rv []*Certificate) { + + sk_num := int(C.X_sk_X509_num(sk)) + rv = make([]*Certificate, 0, sk_num) + for i := 0; i < sk_num; i++ { + x := C.X_sk_X509_value(sk, C.int(i)) + // ref holds on to the underlying connection memory so we don't need to + // worry about incrementing refcounts manually or freeing the X509 + rv = append(rv, &Certificate{x: x, ref: c}) + } + return rv +} + +// PeerCertificateChain returns the certificate chain of the peer. If called on +// the client side, the stack also contains the peer's certificate; if called +// on the server side, the peer's certificate must be obtained separately using +// PeerCertificate. +func (c *Conn) PeerCertificateChain() (rv []*Certificate, err error) { + c.mtx.Lock() + defer c.mtx.Unlock() + if c.is_shutdown { + return nil, errors.New("connection closed") + } + sk := C.SSL_get_peer_cert_chain(c.ssl) + if sk == nil { + return nil, errors.New("no peer certificates found") + } + return c.loadCertificateStack(sk), nil +} + +type ConnectionState struct { + Certificate *Certificate + CertificateError error + CertificateChain []*Certificate + CertificateChainError error + SessionReused bool +} + +func (c *Conn) ConnectionState() (rv ConnectionState) { + rv.Certificate, rv.CertificateError = c.PeerCertificate() + rv.CertificateChain, rv.CertificateChainError = c.PeerCertificateChain() + rv.SessionReused = c.SessionReused() + return +} + +func (c *Conn) shutdown() func() error { + c.mtx.Lock() + defer c.mtx.Unlock() + runtime.LockOSThread() + defer runtime.UnlockOSThread() + rv, errno := C.SSL_shutdown(c.ssl) + if rv > 0 { + return nil + } + if rv == 0 { + // The OpenSSL docs say that in this case, the shutdown is not + // finished, and we should call SSL_shutdown() a second time, if a + // bidirectional shutdown is going to be performed. Further, the + // output of SSL_get_error may be misleading, as an erroneous + // SSL_ERROR_SYSCALL may be flagged even though no error occurred. + // So, TODO: revisit bidrectional shutdown, possibly trying again. + // Note: some broken clients won't engage in bidirectional shutdown + // without tickling them to close by sending a TCP_FIN packet, or + // shutting down the write-side of the connection. + return nil + } else { + return c.getErrorHandler(rv, errno) + } +} + +func (c *Conn) shutdownLoop() error { + err := tryAgain + shutdown_tries := 0 + for err == tryAgain { + shutdown_tries = shutdown_tries + 1 + err = c.handleError(c.shutdown()) + if err == nil { + return c.flushOutputBuffer() + } + if err == tryAgain && shutdown_tries >= 2 { + return errors.New("shutdown requested a third time?") + } + } + if err == io.ErrUnexpectedEOF { + err = nil + } + return err +} + +// Close shuts down the SSL connection and closes the underlying wrapped +// connection. +func (c *Conn) Close() error { + c.mtx.Lock() + if c.is_shutdown { + c.mtx.Unlock() + return nil + } + c.is_shutdown = true + c.mtx.Unlock() + var errs utils.ErrorGroup + errs.Add(c.shutdownLoop()) + errs.Add(c.conn.Close()) + return errs.Finalize() +} + +func (c *Conn) read(b []byte) (int, func() error) { + if len(b) == 0 { + return 0, nil + } + c.mtx.Lock() + defer c.mtx.Unlock() + if c.is_shutdown { + return 0, func() error { return io.EOF } + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + rv, errno := C.SSL_read(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b))) + if rv > 0 { + return int(rv), nil + } + return 0, c.getErrorHandler(rv, errno) +} + +// Read reads up to len(b) bytes into b. It returns the number of bytes read +// and an error if applicable. io.EOF is returned when the caller can expect +// to see no more data. +func (c *Conn) Read(b []byte) (n int, err error) { + if len(b) == 0 { + return 0, nil + } + err = tryAgain + for err == tryAgain { + n, errcb := c.read(b) + err = c.handleError(errcb) + if err == nil { + go c.flushOutputBuffer() + return n, nil + } + if err == io.ErrUnexpectedEOF { + err = io.EOF + } + } + return 0, err +} + +func (c *Conn) write(b []byte) (int, func() error) { + if len(b) == 0 { + return 0, nil + } + c.mtx.Lock() + defer c.mtx.Unlock() + if c.is_shutdown { + err := errors.New("connection closed") + return 0, func() error { return err } + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + rv, errno := C.SSL_write(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b))) + if rv > 0 { + return int(rv), nil + } + return 0, c.getErrorHandler(rv, errno) +} + +// Write will encrypt the contents of b and write it to the underlying stream. +// Performance will be vastly improved if the size of b is a multiple of +// SSLRecordSize. +func (c *Conn) Write(b []byte) (written int, err error) { + if len(b) == 0 { + return 0, nil + } + err = tryAgain + for err == tryAgain { + n, errcb := c.write(b) + err = c.handleError(errcb) + if err == nil { + return n, c.flushOutputBuffer() + } + } + return 0, err +} + +// VerifyHostname pulls the PeerCertificate and calls VerifyHostname on the +// certificate. +func (c *Conn) VerifyHostname(host string) error { + cert, err := c.PeerCertificate() + if err != nil { + return err + } + return cert.VerifyHostname(host) +} + +// LocalAddr returns the underlying connection's local address +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +// RemoteAddr returns the underlying connection's remote address +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +// SetDeadline calls SetDeadline on the underlying connection. +func (c *Conn) SetDeadline(t time.Time) error { + return c.conn.SetDeadline(t) +} + +// SetReadDeadline calls SetReadDeadline on the underlying connection. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +// SetWriteDeadline calls SetWriteDeadline on the underlying connection. +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.conn.SetWriteDeadline(t) +} + +func (c *Conn) UnderlyingConn() net.Conn { + return c.conn +} + +func (c *Conn) SetTlsExtHostName(name string) error { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if C.X_SSL_set_tlsext_host_name(c.ssl, cname) == 0 { + return errorFromErrorQueue() + } + return nil +} + +func (c *Conn) VerifyResult() VerifyResult { + return VerifyResult(C.SSL_get_verify_result(c.ssl)) +} + +func (c *Conn) SessionReused() bool { + return C.X_SSL_session_reused(c.ssl) == 1 +} + +func (c *Conn) GetSession() ([]byte, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + // get1 increases the refcount of the session, so we have to free it. + session := (*C.SSL_SESSION)(C.SSL_get1_session(c.ssl)) + if session == nil { + return nil, errors.New("failed to get session") + } + defer C.SSL_SESSION_free(session) + + // get the size of the encoding + slen := C.i2d_SSL_SESSION(session, nil) + + buf := (*C.uchar)(C.malloc(C.size_t(slen))) + defer C.free(unsafe.Pointer(buf)) + + // this modifies the value of buf (seriously), so we have to pass in a temp + // var so that we can actually read the bytes from buf. + tmp := buf + slen2 := C.i2d_SSL_SESSION(session, &tmp) + if slen != slen2 { + return nil, errors.New("session had different lengths") + } + + return C.GoBytes(unsafe.Pointer(buf), slen), nil +} + +func (c *Conn) setSession(session []byte) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ptr := (*C.uchar)(&session[0]) + s := C.d2i_SSL_SESSION(nil, &ptr, C.long(len(session))) + if s == nil { + return fmt.Errorf("unable to load session: %s", errorFromErrorQueue()) + } + defer C.SSL_SESSION_free(s) + + ret := C.SSL_set_session(c.ssl, s) + if ret != 1 { + return fmt.Errorf("unable to set session: %s", errorFromErrorQueue()) + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/ctx.go b/vendor/github.com/spacemonkeygo/openssl/ctx.go new file mode 100644 index 00000000..33befc40 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/ctx.go @@ -0,0 +1,568 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "runtime" + "sync" + "time" + "unsafe" + + "github.com/spacemonkeygo/spacelog" +) + +var ( + ssl_ctx_idx = C.X_SSL_CTX_new_index() + + logger = spacelog.GetLogger() +) + +type Ctx struct { + ctx *C.SSL_CTX + cert *Certificate + chain []*Certificate + key PrivateKey + verify_cb VerifyCallback + sni_cb TLSExtServernameCallback + + ticket_store_mu sync.Mutex + ticket_store *TicketStore +} + +//export get_ssl_ctx_idx +func get_ssl_ctx_idx() C.int { + return ssl_ctx_idx +} + +func newCtx(method *C.SSL_METHOD) (*Ctx, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx := C.SSL_CTX_new(method) + if ctx == nil { + return nil, errorFromErrorQueue() + } + c := &Ctx{ctx: ctx} + C.SSL_CTX_set_ex_data(ctx, get_ssl_ctx_idx(), unsafe.Pointer(c)) + runtime.SetFinalizer(c, func(c *Ctx) { + C.SSL_CTX_free(c.ctx) + }) + return c, nil +} + +type SSLVersion int + +const ( + SSLv3 SSLVersion = 0x02 // Vulnerable to "POODLE" attack. + TLSv1 SSLVersion = 0x03 + TLSv1_1 SSLVersion = 0x04 + TLSv1_2 SSLVersion = 0x05 + + // Make sure to disable SSLv2 and SSLv3 if you use this. SSLv3 is vulnerable + // to the "POODLE" attack, and SSLv2 is what, just don't even. + AnyVersion SSLVersion = 0x06 +) + +// NewCtxWithVersion creates an SSL context that is specific to the provided +// SSL version. See http://www.openssl.org/docs/ssl/SSL_CTX_new.html for more. +func NewCtxWithVersion(version SSLVersion) (*Ctx, error) { + var method *C.SSL_METHOD + switch version { + case SSLv3: + method = C.X_SSLv3_method() + case TLSv1: + method = C.X_TLSv1_method() + case TLSv1_1: + method = C.X_TLSv1_1_method() + case TLSv1_2: + method = C.X_TLSv1_2_method() + case AnyVersion: + method = C.X_SSLv23_method() + } + if method == nil { + return nil, errors.New("unknown ssl/tls version") + } + return newCtx(method) +} + +// NewCtx creates a context that supports any TLS version 1.0 and newer. +func NewCtx() (*Ctx, error) { + c, err := NewCtxWithVersion(AnyVersion) + if err == nil { + c.SetOptions(NoSSLv2 | NoSSLv3) + } + return c, err +} + +// NewCtxFromFiles calls NewCtx, loads the provided files, and configures the +// context to use them. +func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) { + ctx, err := NewCtx() + if err != nil { + return nil, err + } + + cert_bytes, err := ioutil.ReadFile(cert_file) + if err != nil { + return nil, err + } + + certs := SplitPEM(cert_bytes) + if len(certs) == 0 { + return nil, fmt.Errorf("No PEM certificate found in '%s'", cert_file) + } + first, certs := certs[0], certs[1:] + cert, err := LoadCertificateFromPEM(first) + if err != nil { + return nil, err + } + + err = ctx.UseCertificate(cert) + if err != nil { + return nil, err + } + + for _, pem := range certs { + cert, err := LoadCertificateFromPEM(pem) + if err != nil { + return nil, err + } + err = ctx.AddChainCertificate(cert) + if err != nil { + return nil, err + } + } + + key_bytes, err := ioutil.ReadFile(key_file) + if err != nil { + return nil, err + } + + key, err := LoadPrivateKeyFromPEM(key_bytes) + if err != nil { + return nil, err + } + + err = ctx.UsePrivateKey(key) + if err != nil { + return nil, err + } + + return ctx, nil +} + +// EllipticCurve repesents the ASN.1 OID of an elliptic curve. +// see https://www.openssl.org/docs/apps/ecparam.html for a list of implemented curves. +type EllipticCurve int + +const ( + // P-256: X9.62/SECG curve over a 256 bit prime field + Prime256v1 EllipticCurve = C.NID_X9_62_prime256v1 + // P-384: NIST/SECG curve over a 384 bit prime field + Secp384r1 EllipticCurve = C.NID_secp384r1 + // P-521: NIST/SECG curve over a 521 bit prime field + Secp521r1 EllipticCurve = C.NID_secp521r1 +) + +// SetEllipticCurve sets the elliptic curve used by the SSL context to +// enable an ECDH cipher suite to be selected during the handshake. +func (c *Ctx) SetEllipticCurve(curve EllipticCurve) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + k := C.EC_KEY_new_by_curve_name(C.int(curve)) + if k == nil { + return errors.New("Unknown curve") + } + defer C.EC_KEY_free(k) + + if int(C.X_SSL_CTX_set_tmp_ecdh(c.ctx, k)) != 1 { + return errorFromErrorQueue() + } + + return nil +} + +// UseCertificate configures the context to present the given certificate to +// peers. +func (c *Ctx) UseCertificate(cert *Certificate) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + c.cert = cert + if int(C.SSL_CTX_use_certificate(c.ctx, cert.x)) != 1 { + return errorFromErrorQueue() + } + return nil +} + +// AddChainCertificate adds a certificate to the chain presented in the +// handshake. +func (c *Ctx) AddChainCertificate(cert *Certificate) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + c.chain = append(c.chain, cert) + if int(C.X_SSL_CTX_add_extra_chain_cert(c.ctx, cert.x)) != 1 { + return errorFromErrorQueue() + } + // OpenSSL takes ownership via SSL_CTX_add_extra_chain_cert + runtime.SetFinalizer(cert, nil) + return nil +} + +// UsePrivateKey configures the context to use the given private key for SSL +// handshakes. +func (c *Ctx) UsePrivateKey(key PrivateKey) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + c.key = key + if int(C.SSL_CTX_use_PrivateKey(c.ctx, key.evpPKey())) != 1 { + return errorFromErrorQueue() + } + return nil +} + +type CertificateStore struct { + store *C.X509_STORE + // for GC + ctx *Ctx + certs []*Certificate +} + +// Allocate a new, empty CertificateStore +func NewCertificateStore() (*CertificateStore, error) { + s := C.X509_STORE_new() + if s == nil { + return nil, errors.New("failed to allocate X509_STORE") + } + store := &CertificateStore{store: s} + runtime.SetFinalizer(store, func(s *CertificateStore) { + C.X509_STORE_free(s.store) + }) + return store, nil +} + +// Parse a chained PEM file, loading all certificates into the Store. +func (s *CertificateStore) LoadCertificatesFromPEM(data []byte) error { + pems := SplitPEM(data) + for _, pem := range pems { + cert, err := LoadCertificateFromPEM(pem) + if err != nil { + return err + } + err = s.AddCertificate(cert) + if err != nil { + return err + } + } + return nil +} + +// GetCertificateStore returns the context's certificate store that will be +// used for peer validation. +func (c *Ctx) GetCertificateStore() *CertificateStore { + // we don't need to dealloc the cert store pointer here, because it points + // to a ctx internal. so we do need to keep the ctx around + return &CertificateStore{ + store: C.SSL_CTX_get_cert_store(c.ctx), + ctx: c} +} + +// AddCertificate marks the provided Certificate as a trusted certificate in +// the given CertificateStore. +func (s *CertificateStore) AddCertificate(cert *Certificate) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + s.certs = append(s.certs, cert) + if int(C.X509_STORE_add_cert(s.store, cert.x)) != 1 { + return errorFromErrorQueue() + } + return nil +} + +type CertificateStoreCtx struct { + ctx *C.X509_STORE_CTX + ssl_ctx *Ctx +} + +func (self *CertificateStoreCtx) VerifyResult() VerifyResult { + return VerifyResult(C.X509_STORE_CTX_get_error(self.ctx)) +} + +func (self *CertificateStoreCtx) Err() error { + code := C.X509_STORE_CTX_get_error(self.ctx) + if code == C.X509_V_OK { + return nil + } + return fmt.Errorf("openssl: %s", + C.GoString(C.X509_verify_cert_error_string(C.long(code)))) +} + +func (self *CertificateStoreCtx) Depth() int { + return int(C.X509_STORE_CTX_get_error_depth(self.ctx)) +} + +// the certicate returned is only valid for the lifetime of the underlying +// X509_STORE_CTX +func (self *CertificateStoreCtx) GetCurrentCert() *Certificate { + x509 := C.X509_STORE_CTX_get_current_cert(self.ctx) + if x509 == nil { + return nil + } + // add a ref + if 1 != C.X_X509_add_ref(x509) { + return nil + } + cert := &Certificate{ + x: x509, + } + runtime.SetFinalizer(cert, func(cert *Certificate) { + C.X509_free(cert.x) + }) + return cert +} + +// LoadVerifyLocations tells the context to trust all certificate authorities +// provided in either the ca_file or the ca_path. +// See http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html for +// more. +func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + var c_ca_file, c_ca_path *C.char + if ca_file != "" { + c_ca_file = C.CString(ca_file) + defer C.free(unsafe.Pointer(c_ca_file)) + } + if ca_path != "" { + c_ca_path = C.CString(ca_path) + defer C.free(unsafe.Pointer(c_ca_path)) + } + if C.SSL_CTX_load_verify_locations(c.ctx, c_ca_file, c_ca_path) != 1 { + return errorFromErrorQueue() + } + return nil +} + +type Options int + +const ( + // NoCompression is only valid if you are using OpenSSL 1.0.1 or newer + NoCompression Options = C.SSL_OP_NO_COMPRESSION + NoSSLv2 Options = C.SSL_OP_NO_SSLv2 + NoSSLv3 Options = C.SSL_OP_NO_SSLv3 + NoTLSv1 Options = C.SSL_OP_NO_TLSv1 + CipherServerPreference Options = C.SSL_OP_CIPHER_SERVER_PREFERENCE + NoSessionResumptionOrRenegotiation Options = C.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + NoTicket Options = C.SSL_OP_NO_TICKET +) + +// SetOptions sets context options. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html +func (c *Ctx) SetOptions(options Options) Options { + return Options(C.X_SSL_CTX_set_options( + c.ctx, C.long(options))) +} + +func (c *Ctx) ClearOptions(options Options) Options { + return Options(C.X_SSL_CTX_clear_options( + c.ctx, C.long(options))) +} + +// GetOptions returns context options. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html +func (c *Ctx) GetOptions() Options { + return Options(C.X_SSL_CTX_get_options(c.ctx)) +} + +type Modes int + +const ( + // ReleaseBuffers is only valid if you are using OpenSSL 1.0.1 or newer + ReleaseBuffers Modes = C.SSL_MODE_RELEASE_BUFFERS +) + +// SetMode sets context modes. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html +func (c *Ctx) SetMode(modes Modes) Modes { + return Modes(C.X_SSL_CTX_set_mode(c.ctx, C.long(modes))) +} + +// GetMode returns context modes. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html +func (c *Ctx) GetMode() Modes { + return Modes(C.X_SSL_CTX_get_mode(c.ctx)) +} + +type VerifyOptions int + +const ( + VerifyNone VerifyOptions = C.SSL_VERIFY_NONE + VerifyPeer VerifyOptions = C.SSL_VERIFY_PEER + VerifyFailIfNoPeerCert VerifyOptions = C.SSL_VERIFY_FAIL_IF_NO_PEER_CERT + VerifyClientOnce VerifyOptions = C.SSL_VERIFY_CLIENT_ONCE +) + +type VerifyCallback func(ok bool, store *CertificateStoreCtx) bool + +//export go_ssl_ctx_verify_cb_thunk +func go_ssl_ctx_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback panic'd: %v", err) + os.Exit(1) + } + }() + verify_cb := (*Ctx)(p).verify_cb + // set up defaults just in case verify_cb is nil + if verify_cb != nil { + store := &CertificateStoreCtx{ctx: ctx} + if verify_cb(ok == 1, store) { + ok = 1 + } else { + ok = 0 + } + } + return ok +} + +// SetVerify controls peer verification settings. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (c *Ctx) SetVerify(options VerifyOptions, verify_cb VerifyCallback) { + c.verify_cb = verify_cb + if verify_cb != nil { + C.SSL_CTX_set_verify(c.ctx, C.int(options), (*[0]byte)(C.X_SSL_CTX_verify_cb)) + } else { + C.SSL_CTX_set_verify(c.ctx, C.int(options), nil) + } +} + +func (c *Ctx) SetVerifyMode(options VerifyOptions) { + c.SetVerify(options, c.verify_cb) +} + +func (c *Ctx) SetVerifyCallback(verify_cb VerifyCallback) { + c.SetVerify(c.VerifyMode(), verify_cb) +} + +func (c *Ctx) GetVerifyCallback() VerifyCallback { + return c.verify_cb +} + +func (c *Ctx) VerifyMode() VerifyOptions { + return VerifyOptions(C.SSL_CTX_get_verify_mode(c.ctx)) +} + +// SetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (c *Ctx) SetVerifyDepth(depth int) { + C.SSL_CTX_set_verify_depth(c.ctx, C.int(depth)) +} + +// GetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (c *Ctx) GetVerifyDepth() int { + return int(C.SSL_CTX_get_verify_depth(c.ctx)) +} + +type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr + +// SetTLSExtServernameCallback sets callback function for Server Name Indication +// (SNI) rfc6066 (http://tools.ietf.org/html/rfc6066). See +// http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni +func (c *Ctx) SetTLSExtServernameCallback(sni_cb TLSExtServernameCallback) { + c.sni_cb = sni_cb + C.X_SSL_CTX_set_tlsext_servername_callback(c.ctx, (*[0]byte)(C.sni_cb)) +} + +func (c *Ctx) SetSessionId(session_id []byte) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + var ptr *C.uchar + if len(session_id) > 0 { + ptr = (*C.uchar)(unsafe.Pointer(&session_id[0])) + } + if int(C.SSL_CTX_set_session_id_context(c.ctx, ptr, + C.uint(len(session_id)))) == 0 { + return errorFromErrorQueue() + } + return nil +} + +// SetCipherList sets the list of available ciphers. The format of the list is +// described at http://www.openssl.org/docs/apps/ciphers.html, but see +// http://www.openssl.org/docs/ssl/SSL_CTX_set_cipher_list.html for more. +func (c *Ctx) SetCipherList(list string) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + clist := C.CString(list) + defer C.free(unsafe.Pointer(clist)) + if int(C.SSL_CTX_set_cipher_list(c.ctx, clist)) == 0 { + return errorFromErrorQueue() + } + return nil +} + +type SessionCacheModes int + +const ( + SessionCacheOff SessionCacheModes = C.SSL_SESS_CACHE_OFF + SessionCacheClient SessionCacheModes = C.SSL_SESS_CACHE_CLIENT + SessionCacheServer SessionCacheModes = C.SSL_SESS_CACHE_SERVER + SessionCacheBoth SessionCacheModes = C.SSL_SESS_CACHE_BOTH + NoAutoClear SessionCacheModes = C.SSL_SESS_CACHE_NO_AUTO_CLEAR + NoInternalLookup SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP + NoInternalStore SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL_STORE + NoInternal SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL +) + +// SetSessionCacheMode enables or disables session caching. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_session_cache_mode.html +func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes { + return SessionCacheModes( + C.X_SSL_CTX_set_session_cache_mode(c.ctx, C.long(modes))) +} + +// Set session cache timeout. Returns previously set value. +// See https://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html +func (c *Ctx) SetTimeout(t time.Duration) time.Duration { + prev := C.X_SSL_CTX_set_timeout(c.ctx, C.long(t/time.Second)) + return time.Duration(prev) * time.Second +} + +// Get session cache timeout. +// See https://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html +func (c *Ctx) GetTimeout() time.Duration { + return time.Duration(C.X_SSL_CTX_get_timeout(c.ctx)) * time.Second +} + +// Set session cache size. Returns previously set value. +// https://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html +func (c *Ctx) SessSetCacheSize(t int) int { + return int(C.X_SSL_CTX_sess_set_cache_size(c.ctx, C.long(t))) +} + +// Get session cache size. +// https://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html +func (c *Ctx) SessGetCacheSize() int { + return int(C.X_SSL_CTX_sess_get_cache_size(c.ctx)) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/dh.go b/vendor/github.com/spacemonkeygo/openssl/dh.go new file mode 100644 index 00000000..75ac5ad4 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/dh.go @@ -0,0 +1,66 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" +import ( + "errors" + "unsafe" +) + +// DeriveSharedSecret derives a shared secret using a private key and a peer's +// public key. +// The specific algorithm that is used depends on the types of the +// keys, but it is most commonly a variant of Diffie-Hellman. +func DeriveSharedSecret(private PrivateKey, public PublicKey) ([]byte, error) { + // Create context for the shared secret derivation + dhCtx := C.EVP_PKEY_CTX_new(private.evpPKey(), nil) + if dhCtx == nil { + return nil, errors.New("failed creating shared secret derivation context") + } + defer C.EVP_PKEY_CTX_free(dhCtx) + + // Initialize the context + if int(C.EVP_PKEY_derive_init(dhCtx)) != 1 { + return nil, errors.New("failed initializing shared secret derivation context") + } + + // Provide the peer's public key + if int(C.EVP_PKEY_derive_set_peer(dhCtx, public.evpPKey())) != 1 { + return nil, errors.New("failed adding peer public key to context") + } + + // Determine how large of a buffer we need for the shared secret + var buffLen C.size_t + if int(C.EVP_PKEY_derive(dhCtx, nil, &buffLen)) != 1 { + return nil, errors.New("failed determining shared secret length") + } + + // Allocate a buffer + buffer := C.X_OPENSSL_malloc(buffLen) + if buffer == nil { + return nil, errors.New("failed allocating buffer for shared secret") + } + defer C.X_OPENSSL_free(buffer) + + // Derive the shared secret + if int(C.EVP_PKEY_derive(dhCtx, (*C.uchar)(buffer), &buffLen)) != 1 { + return nil, errors.New("failed deriving the shared secret") + } + + secret := C.GoBytes(unsafe.Pointer(buffer), C.int(buffLen)) + return secret, nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/dhparam.go b/vendor/github.com/spacemonkeygo/openssl/dhparam.go new file mode 100644 index 00000000..294d0645 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/dhparam.go @@ -0,0 +1,64 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type DH struct { + dh *C.struct_dh_st +} + +// LoadDHParametersFromPEM loads the Diffie-Hellman parameters from +// a PEM-encoded block. +func LoadDHParametersFromPEM(pem_block []byte) (*DH, error) { + if len(pem_block) == 0 { + return nil, errors.New("empty pem block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), + C.int(len(pem_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + + params := C.PEM_read_bio_DHparams(bio, nil, nil, nil) + if params == nil { + return nil, errors.New("failed reading dh parameters") + } + dhparams := &DH{dh: params} + runtime.SetFinalizer(dhparams, func(dhparams *DH) { + C.DH_free(dhparams.dh) + }) + return dhparams, nil +} + +// SetDHParameters sets the DH group (DH parameters) used to +// negotiate an emphemeral DH key during handshaking. +func (c *Ctx) SetDHParameters(dh *DH) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if int(C.X_SSL_CTX_set_tmp_dh(c.ctx, dh.dh)) != 1 { + return errorFromErrorQueue() + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/digest.go b/vendor/github.com/spacemonkeygo/openssl/digest.go new file mode 100644 index 00000000..6d8d2635 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/digest.go @@ -0,0 +1,51 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "fmt" + "unsafe" +) + +// Digest represents and openssl message digest. +type Digest struct { + ptr *C.EVP_MD +} + +// GetDigestByName returns the Digest with the name or nil and an error if the +// digest was not found. +func GetDigestByName(name string) (*Digest, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + p := C.X_EVP_get_digestbyname(cname) + if p == nil { + return nil, fmt.Errorf("Digest %v not found", name) + } + // we can consider digests to use static mem; don't need to free + return &Digest{ptr: p}, nil +} + +// GetDigestByName returns the Digest with the NID or nil and an error if the +// digest was not found. +func GetDigestByNid(nid NID) (*Digest, error) { + sn, err := Nid2ShortName(nid) + if err != nil { + return nil, err + } + return GetDigestByName(sn) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/engine.go b/vendor/github.com/spacemonkeygo/openssl/engine.go new file mode 100644 index 00000000..78aef956 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/engine.go @@ -0,0 +1,50 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +/* +#include "openssl/engine.h" +*/ +import "C" + +import ( + "fmt" + "runtime" + "unsafe" +) + +type Engine struct { + e *C.ENGINE +} + +func EngineById(name string) (*Engine, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + e := &Engine{ + e: C.ENGINE_by_id(cname), + } + if e.e == nil { + return nil, fmt.Errorf("engine %s missing", name) + } + if C.ENGINE_init(e.e) == 0 { + C.ENGINE_free(e.e) + return nil, fmt.Errorf("engine %s not initialized", name) + } + runtime.SetFinalizer(e, func(e *Engine) { + C.ENGINE_finish(e.e) + C.ENGINE_free(e.e) + }) + return e, nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/fips.go b/vendor/github.com/spacemonkeygo/openssl/fips.go new file mode 100644 index 00000000..f65e14d3 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/fips.go @@ -0,0 +1,39 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +/* +#include +*/ +import "C" +import "runtime" + +// FIPSModeSet enables a FIPS 140-2 validated mode of operation. +// https://wiki.openssl.org/index.php/FIPS_mode_set() +func FIPSModeSet(mode bool) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var r C.int + if mode { + r = C.FIPS_mode_set(1) + } else { + r = C.FIPS_mode_set(0) + } + if r != 1 { + return errorFromErrorQueue() + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/go.mod b/vendor/github.com/spacemonkeygo/openssl/go.mod new file mode 100644 index 00000000..73f3bbfe --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/go.mod @@ -0,0 +1,3 @@ +module github.com/spacemonkeygo/openssl + +require github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 diff --git a/vendor/github.com/spacemonkeygo/openssl/go.sum b/vendor/github.com/spacemonkeygo/openssl/go.sum new file mode 100644 index 00000000..1b0ecc56 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/go.sum @@ -0,0 +1,2 @@ +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= diff --git a/vendor/github.com/spacemonkeygo/openssl/hmac.go b/vendor/github.com/spacemonkeygo/openssl/hmac.go new file mode 100644 index 00000000..a8640cfa --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/hmac.go @@ -0,0 +1,91 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type HMAC struct { + ctx *C.HMAC_CTX + engine *Engine + md *C.EVP_MD +} + +func NewHMAC(key []byte, digestAlgorithm EVP_MD) (*HMAC, error) { + return NewHMACWithEngine(key, digestAlgorithm, nil) +} + +func NewHMACWithEngine(key []byte, digestAlgorithm EVP_MD, e *Engine) (*HMAC, error) { + var md *C.EVP_MD = getDigestFunction(digestAlgorithm) + h := &HMAC{engine: e, md: md} + h.ctx = C.X_HMAC_CTX_new() + if h.ctx == nil { + return nil, errors.New("unable to allocate HMAC_CTX") + } + + var c_e *C.ENGINE + if e != nil { + c_e = e.e + } + if rc := C.X_HMAC_Init_ex(h.ctx, + unsafe.Pointer(&key[0]), + C.int(len(key)), + md, + c_e); rc != 1 { + C.X_HMAC_CTX_free(h.ctx) + return nil, errors.New("failed to initialize HMAC_CTX") + } + + runtime.SetFinalizer(h, func(h *HMAC) { h.Close() }) + return h, nil +} + +func (h *HMAC) Close() { + C.X_HMAC_CTX_free(h.ctx) +} + +func (h *HMAC) Write(data []byte) (n int, err error) { + if len(data) == 0 { + return 0, nil + } + if rc := C.X_HMAC_Update(h.ctx, (*C.uchar)(unsafe.Pointer(&data[0])), + C.size_t(len(data))); rc != 1 { + return 0, errors.New("failed to update HMAC") + } + return len(data), nil +} + +func (h *HMAC) Reset() error { + if 1 != C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) { + return errors.New("failed to reset HMAC_CTX") + } + return nil +} + +func (h *HMAC) Final() (result []byte, err error) { + mdLength := C.X_EVP_MD_size(h.md) + result = make([]byte, mdLength) + if rc := C.X_HMAC_Final(h.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), + (*C.uint)(unsafe.Pointer(&mdLength))); rc != 1 { + return nil, errors.New("failed to finalized HMAC") + } + return result, h.Reset() +} diff --git a/vendor/github.com/spacemonkeygo/openssl/hostname.c b/vendor/github.com/spacemonkeygo/openssl/hostname.c new file mode 100644 index 00000000..0bffecad --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/hostname.c @@ -0,0 +1,373 @@ +/* + * Go-OpenSSL notice: + * This file is required for all OpenSSL versions prior to 1.1.0. This simply + * provides the new 1.1.0 X509_check_* methods for hostname validation if they + * don't already exist. + */ + +#include + +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + +/* portions from x509v3.h and v3_utl.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include +#include +#include +#include + +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 + +typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len); + +/* Compare while ASCII ignoring case. */ +static int equal_nocase(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len) + { + if (pattern_len != subject_len) + return 0; + while (pattern_len) + { + unsigned char l = *pattern; + unsigned char r = *subject; + /* The pattern must not contain NUL characters. */ + if (l == 0) + return 0; + if (l != r) + { + if ('A' <= l && l <= 'Z') + l = (l - 'A') + 'a'; + if ('A' <= r && r <= 'Z') + r = (r - 'A') + 'a'; + if (l != r) + return 0; + } + ++pattern; + ++subject; + --pattern_len; + } + return 1; + } + +/* Compare using memcmp. */ +static int equal_case(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len) +{ + /* The pattern must not contain NUL characters. */ + if (memchr(pattern, '\0', pattern_len) != NULL) + return 0; + if (pattern_len != subject_len) + return 0; + return !memcmp(pattern, subject, pattern_len); +} + +/* RFC 5280, section 7.5, requires that only the domain is compared in + a case-insensitive manner. */ +static int equal_email(const unsigned char *a, size_t a_len, + const unsigned char *b, size_t b_len) + { + size_t i = a_len; + if (a_len != b_len) + return 0; + /* We search backwards for the '@' character, so that we do + not have to deal with quoted local-parts. The domain part + is compared in a case-insensitive manner. */ + while (i > 0) + { + --i; + if (a[i] == '@' || b[i] == '@') + { + if (!equal_nocase(a + i, a_len - i, + b + i, a_len - i)) + return 0; + break; + } + } + if (i == 0) + i = a_len; + return equal_case(a, i, b, i); + } + +/* Compare the prefix and suffix with the subject, and check that the + characters in-between are valid. */ +static int wildcard_match(const unsigned char *prefix, size_t prefix_len, + const unsigned char *suffix, size_t suffix_len, + const unsigned char *subject, size_t subject_len) + { + const unsigned char *wildcard_start; + const unsigned char *wildcard_end; + const unsigned char *p; + if (subject_len < prefix_len + suffix_len) + return 0; + if (!equal_nocase(prefix, prefix_len, subject, prefix_len)) + return 0; + wildcard_start = subject + prefix_len; + wildcard_end = subject + (subject_len - suffix_len); + if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len)) + return 0; + /* The wildcard must match at least one character. */ + if (wildcard_start == wildcard_end) + return 0; + /* Check that the part matched by the wildcard contains only + permitted characters and only matches a single label. */ + for (p = wildcard_start; p != wildcard_end; ++p) + if (!(('0' <= *p && *p <= '9') || + ('A' <= *p && *p <= 'Z') || + ('a' <= *p && *p <= 'z') || + *p == '-')) + return 0; + return 1; + } + +/* Checks if the memory region consistens of [0-9A-Za-z.-]. */ +static int valid_domain_characters(const unsigned char *p, size_t len) + { + while (len) + { + if (!(('0' <= *p && *p <= '9') || + ('A' <= *p && *p <= 'Z') || + ('a' <= *p && *p <= 'z') || + *p == '-' || *p == '.')) + return 0; + ++p; + --len; + } + return 1; + } + +/* Find the '*' in a wildcard pattern. If no such character is found + or the pattern is otherwise invalid, returns NULL. */ +static const unsigned char *wildcard_find_star(const unsigned char *pattern, + size_t pattern_len) + { + const unsigned char *star = memchr(pattern, '*', pattern_len); + size_t dot_count = 0; + const unsigned char *suffix_start; + size_t suffix_length; + if (star == NULL) + return NULL; + suffix_start = star + 1; + suffix_length = (pattern + pattern_len) - (star + 1); + if (!(valid_domain_characters(pattern, star - pattern) && + valid_domain_characters(suffix_start, suffix_length))) + return NULL; + /* Check that the suffix matches at least two labels. */ + while (suffix_length) + { + if (*suffix_start == '.') + ++dot_count; + ++suffix_start; + --suffix_length; + } + if (dot_count < 2) + return NULL; + return star; + } + +/* Compare using wildcards. */ +static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len) + { + const unsigned char *star = wildcard_find_star(pattern, pattern_len); + if (star == NULL) + return equal_nocase(pattern, pattern_len, + subject, subject_len); + return wildcard_match(pattern, star - pattern, + star + 1, (pattern + pattern_len) - star - 1, + subject, subject_len); + } + +/* Compare an ASN1_STRING to a supplied string. If they match + * return 1. If cmp_type > 0 only compare if string matches the + * type, otherwise convert it to UTF8. + */ + +static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, + const unsigned char *b, size_t blen) + { + if (!a->data || !a->length) + return 0; + if (cmp_type > 0) + { + if (cmp_type != a->type) + return 0; + if (cmp_type == V_ASN1_IA5STRING) + return equal(a->data, a->length, b, blen); + if (a->length == (int)blen && !memcmp(a->data, b, blen)) + return 1; + else + return 0; + } + else + { + int astrlen, rv; + unsigned char *astr; + astrlen = ASN1_STRING_to_UTF8(&astr, a); + if (astrlen < 0) + return -1; + rv = equal(astr, astrlen, b, blen); + OPENSSL_free(astr); + return rv; + } + } + +static int do_x509_check(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags, int check_type) + { + STACK_OF(GENERAL_NAME) *gens = NULL; + X509_NAME *name = NULL; + int i; + int cnid; + int alt_type; + equal_fn equal; + if (check_type == GEN_EMAIL) + { + cnid = NID_pkcs9_emailAddress; + alt_type = V_ASN1_IA5STRING; + equal = equal_email; + } + else if (check_type == GEN_DNS) + { + cnid = NID_commonName; + alt_type = V_ASN1_IA5STRING; + if (flags & X509_CHECK_FLAG_NO_WILDCARDS) + equal = equal_nocase; + else + equal = equal_wildcard; + } + else + { + cnid = 0; + alt_type = V_ASN1_OCTET_STRING; + equal = equal_case; + } + + if (chklen == 0) + chklen = strlen((const char *)chk); + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens) + { + int rv = 0; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + GENERAL_NAME *gen; + ASN1_STRING *cstr; + gen = sk_GENERAL_NAME_value(gens, i); + if(gen->type != check_type) + continue; + if (check_type == GEN_EMAIL) + cstr = gen->d.rfc822Name; + else if (check_type == GEN_DNS) + cstr = gen->d.dNSName; + else + cstr = gen->d.iPAddress; + if (do_check_string(cstr, alt_type, equal, chk, chklen)) + { + rv = 1; + break; + } + } + GENERAL_NAMES_free(gens); + if (rv) + return 1; + if (!(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) || !cnid) + return 0; + } + i = -1; + name = X509_get_subject_name(x); + while((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) + { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + ne = X509_NAME_get_entry(name, i); + str = X509_NAME_ENTRY_get_data(ne); + if (do_check_string(str, -1, equal, chk, chklen)) + return 1; + } + return 0; + } + +#if OPENSSL_VERSION_NUMBER < 0x1000200fL + +int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags, char **peername) + { + return do_x509_check(x, chk, chklen, flags, GEN_DNS); + } + +int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags) + { + return do_x509_check(x, chk, chklen, flags, GEN_EMAIL); + } + +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags) + { + return do_x509_check(x, chk, chklen, flags, GEN_IPADD); + } + +#endif /* OPENSSL_VERSION_NUMBER < 0x1000200fL */ + +#endif diff --git a/vendor/github.com/spacemonkeygo/openssl/hostname.go b/vendor/github.com/spacemonkeygo/openssl/hostname.go new file mode 100644 index 00000000..c92d959e --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/hostname.go @@ -0,0 +1,132 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +/* +#include +#include +#include + +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 + +extern int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags, char **peername); +extern int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +extern int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +#endif +*/ +import "C" + +import ( + "errors" + "net" + "unsafe" +) + +var ( + ValidationError = errors.New("Host validation error") +) + +type CheckFlags int + +const ( + AlwaysCheckSubject CheckFlags = C.X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + NoWildcards CheckFlags = C.X509_CHECK_FLAG_NO_WILDCARDS +) + +// CheckHost checks that the X509 certificate is signed for the provided +// host name. See http://www.openssl.org/docs/crypto/X509_check_host.html for +// more. Note that CheckHost does not check the IP field. See VerifyHostname. +// Specifically returns ValidationError if the Certificate didn't match but +// there was no internal error. +func (c *Certificate) CheckHost(host string, flags CheckFlags) error { + chost := unsafe.Pointer(C.CString(host)) + defer C.free(chost) + + rv := C.X509_check_host(c.x, (*C.uchar)(chost), C.size_t(len(host)), + C.uint(flags), nil) + if rv > 0 { + return nil + } + if rv == 0 { + return ValidationError + } + return errors.New("hostname validation had an internal failure") +} + +// CheckEmail checks that the X509 certificate is signed for the provided +// email address. See http://www.openssl.org/docs/crypto/X509_check_host.html +// for more. +// Specifically returns ValidationError if the Certificate didn't match but +// there was no internal error. +func (c *Certificate) CheckEmail(email string, flags CheckFlags) error { + cemail := unsafe.Pointer(C.CString(email)) + defer C.free(cemail) + rv := C.X509_check_email(c.x, (*C.uchar)(cemail), C.size_t(len(email)), + C.uint(flags)) + if rv > 0 { + return nil + } + if rv == 0 { + return ValidationError + } + return errors.New("email validation had an internal failure") +} + +// CheckIP checks that the X509 certificate is signed for the provided +// IP address. See http://www.openssl.org/docs/crypto/X509_check_host.html +// for more. +// Specifically returns ValidationError if the Certificate didn't match but +// there was no internal error. +func (c *Certificate) CheckIP(ip net.IP, flags CheckFlags) error { + // X509_check_ip will fail to validate the 16-byte representation of an IPv4 + // address, so convert to the 4-byte representation. + if ip4 := ip.To4(); ip4 != nil { + ip = ip4 + } + + cip := unsafe.Pointer(&ip[0]) + rv := C.X509_check_ip(c.x, (*C.uchar)(cip), C.size_t(len(ip)), + C.uint(flags)) + if rv > 0 { + return nil + } + if rv == 0 { + return ValidationError + } + return errors.New("ip validation had an internal failure") +} + +// VerifyHostname is a combination of CheckHost and CheckIP. If the provided +// hostname looks like an IP address, it will be checked as an IP address, +// otherwise it will be checked as a hostname. +// Specifically returns ValidationError if the Certificate didn't match but +// there was no internal error. +func (c *Certificate) VerifyHostname(host string) error { + var ip net.IP + if len(host) >= 3 && host[0] == '[' && host[len(host)-1] == ']' { + ip = net.ParseIP(host[1 : len(host)-1]) + } else { + ip = net.ParseIP(host) + } + if ip != nil { + return c.CheckIP(ip, 0) + } + return c.CheckHost(host, 0) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/http.go b/vendor/github.com/spacemonkeygo/openssl/http.go new file mode 100644 index 00000000..39bd5a28 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/http.go @@ -0,0 +1,61 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +import ( + "net/http" +) + +// ListenAndServeTLS will take an http.Handler and serve it using OpenSSL over +// the given tcp address, configured to use the provided cert and key files. +func ListenAndServeTLS(addr string, cert_file string, key_file string, + handler http.Handler) error { + return ServerListenAndServeTLS( + &http.Server{Addr: addr, Handler: handler}, cert_file, key_file) +} + +// ServerListenAndServeTLS will take an http.Server and serve it using OpenSSL +// configured to use the provided cert and key files. +func ServerListenAndServeTLS(srv *http.Server, + cert_file, key_file string) error { + addr := srv.Addr + if addr == "" { + addr = ":https" + } + + ctx, err := NewCtxFromFiles(cert_file, key_file) + if err != nil { + return err + } + + l, err := Listen("tcp", addr, ctx) + if err != nil { + return err + } + + return srv.Serve(l) +} + +// TODO: http client integration +// holy crap, getting this integrated nicely with the Go stdlib HTTP client +// stack so that it does proxying, connection pooling, and most importantly +// hostname verification is really hard. So much stuff is hardcoded to just use +// the built-in TLS lib. I think to get this to work either some crazy +// hacktackery beyond me, an almost straight up fork of the HTTP client, or +// serious stdlib internal refactoring is necessary. +// even more so, good luck getting openssl to use the operating system default +// root certificates if the user doesn't provide any. sadlol +// NOTE: if you're going to try and write your own round tripper, at least use +// openssl.Dial, or equivalent logic diff --git a/vendor/github.com/spacemonkeygo/openssl/init.go b/vendor/github.com/spacemonkeygo/openssl/init.go new file mode 100644 index 00000000..17dc6f38 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/init.go @@ -0,0 +1,117 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package openssl is a light wrapper around OpenSSL for Go. + +It strives to provide a near-drop-in replacement for the Go standard library +tls package, while allowing for: + +Performance + +OpenSSL is battle-tested and optimized C. While Go's built-in library shows +great promise, it is still young and in some places, inefficient. This simple +OpenSSL wrapper can often do at least 2x with the same cipher and protocol. + +On my lappytop, I get the following benchmarking speeds: + BenchmarkSHA1Large_openssl 1000 2611282 ns/op 401.56 MB/s + BenchmarkSHA1Large_stdlib 500 3963983 ns/op 264.53 MB/s + BenchmarkSHA1Small_openssl 1000000 3476 ns/op 0.29 MB/s + BenchmarkSHA1Small_stdlib 5000000 550 ns/op 1.82 MB/s + BenchmarkSHA256Large_openssl 200 8085314 ns/op 129.69 MB/s + BenchmarkSHA256Large_stdlib 100 18948189 ns/op 55.34 MB/s + BenchmarkSHA256Small_openssl 1000000 4262 ns/op 0.23 MB/s + BenchmarkSHA256Small_stdlib 1000000 1444 ns/op 0.69 MB/s + BenchmarkOpenSSLThroughput 100000 21634 ns/op 47.33 MB/s + BenchmarkStdlibThroughput 50000 58974 ns/op 17.36 MB/s + +Interoperability + +Many systems support OpenSSL with a variety of plugins and modules for things, +such as hardware acceleration in embedded devices. + +Greater flexibility and configuration + +OpenSSL allows for far greater configuration of corner cases and backwards +compatibility (such as support of SSLv2). You shouldn't be using SSLv2 if you +can help but, but sometimes you can't help it. + +Security + +Yeah yeah, Heartbleed. But according to the author of the standard library's +TLS implementation, Go's TLS library is vulnerable to timing attacks. And +whether or not OpenSSL received the appropriate amount of scrutiny +pre-Heartbleed, it sure is receiving it now. + +Usage + +Starting an HTTP server that uses OpenSSL is very easy. It's as simple as: + log.Fatal(openssl.ListenAndServeTLS( + ":8443", "my_server.crt", "my_server.key", myHandler)) + +Getting a net.Listener that uses OpenSSL is also easy: + ctx, err := openssl.NewCtxFromFiles("my_server.crt", "my_server.key") + if err != nil { + log.Fatal(err) + } + l, err := openssl.Listen("tcp", ":7777", ctx) + +Making a client connection is straightforward too: + ctx, err := NewCtx() + if err != nil { + log.Fatal(err) + } + err = ctx.LoadVerifyLocations("/etc/ssl/certs/ca-certificates.crt", "") + if err != nil { + log.Fatal(err) + } + conn, err := openssl.Dial("tcp", "localhost:7777", ctx, 0) + +Help wanted: To get this library to work with net/http's client, we +had to fork net/http. It would be nice if an alternate http client library +supported the generality needed to use OpenSSL instead of crypto/tls. +*/ +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "fmt" + "strings" +) + +func init() { + if rc := C.X_shim_init(); rc != 0 { + panic(fmt.Errorf("X_shim_init failed with %d", rc)) + } +} + +// errorFromErrorQueue needs to run in the same OS thread as the operation +// that caused the possible error +func errorFromErrorQueue() error { + var errs []string + for { + err := C.ERR_get_error() + if err == 0 { + break + } + errs = append(errs, fmt.Sprintf("%s:%s:%s", + C.GoString(C.ERR_lib_error_string(err)), + C.GoString(C.ERR_func_error_string(err)), + C.GoString(C.ERR_reason_error_string(err)))) + } + return errors.New(fmt.Sprintf("SSL errors: %s", strings.Join(errs, "\n"))) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/init_posix.go b/vendor/github.com/spacemonkeygo/openssl/init_posix.go new file mode 100644 index 00000000..2da7f957 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/init_posix.go @@ -0,0 +1,68 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build linux darwin solaris +// +build !windows + +package openssl + +/* +#include +#include +#include + +pthread_mutex_t* goopenssl_locks; + +int go_init_locks() { + int rc = 0; + int nlock; + int i; + int locks_needed = CRYPTO_num_locks(); + + goopenssl_locks = (pthread_mutex_t*)malloc( + sizeof(pthread_mutex_t) * locks_needed); + if (!goopenssl_locks) { + return ENOMEM; + } + for (nlock = 0; nlock < locks_needed; ++nlock) { + rc = pthread_mutex_init(&goopenssl_locks[nlock], NULL); + if (rc != 0) { + break; + } + } + + if (rc != 0) { + for (i = nlock - 1; i >= 0; --i) { + pthread_mutex_destroy(&goopenssl_locks[i]); + } + free(goopenssl_locks); + goopenssl_locks = NULL; + } + return rc; +} + +void go_thread_locking_callback(int mode, int n, const char *file, + int line) { + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&goopenssl_locks[n]); + } else { + pthread_mutex_unlock(&goopenssl_locks[n]); + } +} + +unsigned long go_thread_id_callback(void) { + return (unsigned long)pthread_self(); +} +*/ +import "C" diff --git a/vendor/github.com/spacemonkeygo/openssl/init_windows.go b/vendor/github.com/spacemonkeygo/openssl/init_windows.go new file mode 100644 index 00000000..051133c3 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/init_windows.go @@ -0,0 +1,57 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package openssl + +/* +#include +#include +#include + +CRITICAL_SECTION* goopenssl_locks; + +int go_init_locks() { + int rc = 0; + int nlock; + int i; + int locks_needed = CRYPTO_num_locks(); + + goopenssl_locks = (CRITICAL_SECTION*)malloc( + sizeof(*goopenssl_locks) * locks_needed); + if (!goopenssl_locks) { + return ENOMEM; + } + for (nlock = 0; nlock < locks_needed; ++nlock) { + InitializeCriticalSection(&goopenssl_locks[nlock]); + } + + return 0; +} + +void go_thread_locking_callback(int mode, int n, const char *file, + int line) { + if (mode & CRYPTO_LOCK) { + EnterCriticalSection(&goopenssl_locks[n]); + } else { + LeaveCriticalSection(&goopenssl_locks[n]); + } +} + +unsigned long go_thread_id_callback(void) { + return (unsigned long)GetCurrentThreadId(); +} +*/ +import "C" diff --git a/vendor/github.com/spacemonkeygo/openssl/key.go b/vendor/github.com/spacemonkeygo/openssl/key.go new file mode 100644 index 00000000..91ea98a7 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/key.go @@ -0,0 +1,504 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "io/ioutil" + "runtime" + "unsafe" +) + +var ( // some (effectively) constants for tests to refer to + ed25519_support = C.X_ED25519_SUPPORT != 0 +) + +type Method *C.EVP_MD + +var ( + SHA1_Method Method = C.X_EVP_sha1() + SHA256_Method Method = C.X_EVP_sha256() + SHA512_Method Method = C.X_EVP_sha512() +) + +// Constants for the various key types. +// Mapping of name -> NID taken from openssl/evp.h +const ( + KeyTypeNone = NID_undef + KeyTypeRSA = NID_rsaEncryption + KeyTypeRSA2 = NID_rsa + KeyTypeDSA = NID_dsa + KeyTypeDSA1 = NID_dsa_2 + KeyTypeDSA2 = NID_dsaWithSHA + KeyTypeDSA3 = NID_dsaWithSHA1 + KeyTypeDSA4 = NID_dsaWithSHA1_2 + KeyTypeDH = NID_dhKeyAgreement + KeyTypeDHX = NID_dhpublicnumber + KeyTypeEC = NID_X9_62_id_ecPublicKey + KeyTypeHMAC = NID_hmac + KeyTypeCMAC = NID_cmac + KeyTypeTLS1PRF = NID_tls1_prf + KeyTypeHKDF = NID_hkdf + KeyTypeX25519 = NID_X25519 + KeyTypeX448 = NID_X448 + KeyTypeED25519 = NID_ED25519 + KeyTypeED448 = NID_ED448 +) + +type PublicKey interface { + // Verifies the data signature using PKCS1.15 + VerifyPKCS1v15(method Method, data, sig []byte) error + + // MarshalPKIXPublicKeyPEM converts the public key to PEM-encoded PKIX + // format + MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) + + // MarshalPKIXPublicKeyDER converts the public key to DER-encoded PKIX + // format + MarshalPKIXPublicKeyDER() (der_block []byte, err error) + + // KeyType returns an identifier for what kind of key is represented by this + // object. + KeyType() NID + + // BaseType returns an identifier for what kind of key is represented + // by this object. + // Keys that share same algorithm but use different legacy formats + // will have the same BaseType. + // + // For example, a key with a `KeyType() == KeyTypeRSA` and a key with a + // `KeyType() == KeyTypeRSA2` would both have `BaseType() == KeyTypeRSA`. + BaseType() NID + + evpPKey() *C.EVP_PKEY +} + +type PrivateKey interface { + PublicKey + + // Signs the data using PKCS1.15 + SignPKCS1v15(Method, []byte) ([]byte, error) + + // MarshalPKCS1PrivateKeyPEM converts the private key to PEM-encoded PKCS1 + // format + MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) + + // MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1 + // format + MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) +} + +type pKey struct { + key *C.EVP_PKEY +} + +func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key } + +func (key *pKey) KeyType() NID { + return NID(C.EVP_PKEY_id(key.key)) +} + +func (key *pKey) BaseType() NID { + return NID(C.EVP_PKEY_base_id(key.key)) +} + +func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { + + ctx := C.X_EVP_MD_CTX_new() + defer C.X_EVP_MD_CTX_free(ctx) + + if key.KeyType() == KeyTypeED25519 { + // do ED specific one-shot sign + + if method != nil || len(data) == 0 { + return nil, errors.New("signpkcs1v15: 0-length data or non-null digest") + } + + if 1 != C.X_EVP_DigestSignInit(ctx, nil, nil, nil, key.key) { + return nil, errors.New("signpkcs1v15: failed to init signature") + } + + // evp signatures are 64 bytes + sig := make([]byte, 64, 64) + var sigblen C.size_t = 64 + if 1 != C.X_EVP_DigestSign(ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), + &sigblen, + (*C.uchar)(unsafe.Pointer(&data[0])), + C.size_t(len(data))) { + return nil, errors.New("signpkcs1v15: failed to do one-shot signature") + } + + return sig[:sigblen], nil + } else { + if 1 != C.X_EVP_SignInit(ctx, method) { + return nil, errors.New("signpkcs1v15: failed to init signature") + } + if len(data) > 0 { + if 1 != C.X_EVP_SignUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + return nil, errors.New("signpkcs1v15: failed to update signature") + } + } + sig := make([]byte, C.X_EVP_PKEY_size(key.key)) + var sigblen C.uint + if 1 != C.X_EVP_SignFinal(ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { + return nil, errors.New("signpkcs1v15: failed to finalize signature") + } + return sig[:sigblen], nil + } +} + +func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error { + ctx := C.X_EVP_MD_CTX_new() + defer C.X_EVP_MD_CTX_free(ctx) + + if key.KeyType() == KeyTypeED25519 { + // do ED specific one-shot sign + + if method != nil || len(data) == 0 || len(sig) == 0 { + return errors.New("verifypkcs1v15: 0-length data or sig or non-null digest") + } + + if 1 != C.X_EVP_DigestVerifyInit(ctx, nil, nil, nil, key.key) { + return errors.New("verifypkcs1v15: failed to init verify") + } + + if 1 != C.X_EVP_DigestVerify(ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), + C.size_t(len(sig)), + (*C.uchar)(unsafe.Pointer(&data[0])), + C.size_t(len(data))) { + return errors.New("verifypkcs1v15: failed to do one-shot verify") + } + + return nil + + } else { + if 1 != C.X_EVP_VerifyInit(ctx, method) { + return errors.New("verifypkcs1v15: failed to init verify") + } + if len(data) > 0 { + if 1 != C.X_EVP_VerifyUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + return errors.New("verifypkcs1v15: failed to update verify") + } + } + if 1 != C.X_EVP_VerifyFinal(ctx, + ((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { + return errors.New("verifypkcs1v15: failed to finalize verify") + } + return nil + } +} + +func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte, + err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + + // PEM_write_bio_PrivateKey_traditional will use the key-specific PKCS1 + // format if one is available for that key type, otherwise it will encode + // to a PKCS8 key. + if int(C.X_PEM_write_bio_PrivateKey_traditional(bio, key.key, nil, nil, + C.int(0), nil, nil)) != 1 { + return nil, errors.New("failed dumping private key") + } + + return ioutil.ReadAll(asAnyBio(bio)) +} + +func (key *pKey) MarshalPKCS1PrivateKeyDER() (der_block []byte, + err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + + if int(C.i2d_PrivateKey_bio(bio, key.key)) != 1 { + return nil, errors.New("failed dumping private key der") + } + + return ioutil.ReadAll(asAnyBio(bio)) +} + +func (key *pKey) MarshalPKIXPublicKeyPEM() (pem_block []byte, + err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + + if int(C.PEM_write_bio_PUBKEY(bio, key.key)) != 1 { + return nil, errors.New("failed dumping public key pem") + } + + return ioutil.ReadAll(asAnyBio(bio)) +} + +func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, + err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + + if int(C.i2d_PUBKEY_bio(bio, key.key)) != 1 { + return nil, errors.New("failed dumping public key der") + } + + return ioutil.ReadAll(asAnyBio(bio)) +} + +// LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block. +func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) { + if len(pem_block) == 0 { + return nil, errors.New("empty pem block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), + C.int(len(pem_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + + key := C.PEM_read_bio_PrivateKey(bio, nil, nil, nil) + if key == nil { + return nil, errors.New("failed reading private key") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// LoadPrivateKeyFromPEMWithPassword loads a private key from a PEM-encoded block. +func LoadPrivateKeyFromPEMWithPassword(pem_block []byte, password string) ( + PrivateKey, error) { + if len(pem_block) == 0 { + return nil, errors.New("empty pem block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), + C.int(len(pem_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + cs := C.CString(password) + defer C.free(unsafe.Pointer(cs)) + key := C.PEM_read_bio_PrivateKey(bio, nil, nil, unsafe.Pointer(cs)) + if key == nil { + return nil, errors.New("failed reading private key") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// LoadPrivateKeyFromDER loads a private key from a DER-encoded block. +func LoadPrivateKeyFromDER(der_block []byte) (PrivateKey, error) { + if len(der_block) == 0 { + return nil, errors.New("empty der block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&der_block[0]), + C.int(len(der_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + + key := C.d2i_PrivateKey_bio(bio, nil) + if key == nil { + return nil, errors.New("failed reading private key der") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// LoadPrivateKeyFromPEMWidthPassword loads a private key from a PEM-encoded block. +// Backwards-compatible with typo +func LoadPrivateKeyFromPEMWidthPassword(pem_block []byte, password string) ( + PrivateKey, error) { + return LoadPrivateKeyFromPEMWithPassword(pem_block, password) +} + +// LoadPublicKeyFromPEM loads a public key from a PEM-encoded block. +func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) { + if len(pem_block) == 0 { + return nil, errors.New("empty pem block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), + C.int(len(pem_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + + key := C.PEM_read_bio_PUBKEY(bio, nil, nil, nil) + if key == nil { + return nil, errors.New("failed reading public key der") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// LoadPublicKeyFromDER loads a public key from a DER-encoded block. +func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) { + if len(der_block) == 0 { + return nil, errors.New("empty der block") + } + bio := C.BIO_new_mem_buf(unsafe.Pointer(&der_block[0]), + C.int(len(der_block))) + if bio == nil { + return nil, errors.New("failed creating bio") + } + defer C.BIO_free(bio) + + key := C.d2i_PUBKEY_bio(bio, nil) + if key == nil { + return nil, errors.New("failed reading public key der") + } + + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// GenerateRSAKey generates a new RSA private key with an exponent of 3. +func GenerateRSAKey(bits int) (PrivateKey, error) { + return GenerateRSAKeyWithExponent(bits, 3) +} + +// GenerateRSAKeyWithExponent generates a new RSA private key. +func GenerateRSAKeyWithExponent(bits int, exponent int) (PrivateKey, error) { + rsa := C.RSA_generate_key(C.int(bits), C.ulong(exponent), nil, nil) + if rsa == nil { + return nil, errors.New("failed to generate RSA key") + } + key := C.X_EVP_PKEY_new() + if key == nil { + return nil, errors.New("failed to allocate EVP_PKEY") + } + if C.X_EVP_PKEY_assign_charp(key, C.EVP_PKEY_RSA, (*C.char)(unsafe.Pointer(rsa))) != 1 { + C.X_EVP_PKEY_free(key) + return nil, errors.New("failed to assign RSA key") + } + p := &pKey{key: key} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// GenerateECKey generates a new elliptic curve private key on the speicified +// curve. +func GenerateECKey(curve EllipticCurve) (PrivateKey, error) { + + // Create context for parameter generation + paramCtx := C.EVP_PKEY_CTX_new_id(C.EVP_PKEY_EC, nil) + if paramCtx == nil { + return nil, errors.New("failed creating EC parameter generation context") + } + defer C.EVP_PKEY_CTX_free(paramCtx) + + // Intialize the parameter generation + if int(C.EVP_PKEY_paramgen_init(paramCtx)) != 1 { + return nil, errors.New("failed initializing EC parameter generation context") + } + + // Set curve in EC parameter generation context + if int(C.X_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(paramCtx, C.int(curve))) != 1 { + return nil, errors.New("failed setting curve in EC parameter generation context") + } + + // Create parameter object + var params *C.EVP_PKEY + if int(C.EVP_PKEY_paramgen(paramCtx, ¶ms)) != 1 { + return nil, errors.New("failed creating EC key generation parameters") + } + defer C.EVP_PKEY_free(params) + + // Create context for the key generation + keyCtx := C.EVP_PKEY_CTX_new(params, nil) + if keyCtx == nil { + return nil, errors.New("failed creating EC key generation context") + } + defer C.EVP_PKEY_CTX_free(keyCtx) + + // Generate the key + var privKey *C.EVP_PKEY + if int(C.EVP_PKEY_keygen_init(keyCtx)) != 1 { + return nil, errors.New("failed initializing EC key generation context") + } + if int(C.EVP_PKEY_keygen(keyCtx, &privKey)) != 1 { + return nil, errors.New("failed generating EC private key") + } + + p := &pKey{key: privKey} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} + +// GenerateED25519Key generates a Ed25519 key +func GenerateED25519Key() (PrivateKey, error) { + // Key context + keyCtx := C.EVP_PKEY_CTX_new_id(C.X_EVP_PKEY_ED25519, nil) + if keyCtx == nil { + return nil, errors.New("failed creating EC parameter generation context") + } + defer C.EVP_PKEY_CTX_free(keyCtx) + + // Generate the key + var privKey *C.EVP_PKEY + if int(C.EVP_PKEY_keygen_init(keyCtx)) != 1 { + return nil, errors.New("failed initializing ED25519 key generation context") + } + if int(C.EVP_PKEY_keygen(keyCtx, &privKey)) != 1 { + return nil, errors.New("failed generating ED25519 private key") + } + + p := &pKey{key: privKey} + runtime.SetFinalizer(p, func(p *pKey) { + C.X_EVP_PKEY_free(p.key) + }) + return p, nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/mapping.go b/vendor/github.com/spacemonkeygo/openssl/mapping.go new file mode 100644 index 00000000..d78cc703 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/mapping.go @@ -0,0 +1,62 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +import ( + "sync" + "unsafe" +) + +// #include +import "C" + +type mapping struct { + lock sync.Mutex + values map[token]unsafe.Pointer +} + +func newMapping() *mapping { + return &mapping{ + values: make(map[token]unsafe.Pointer), + } +} + +type token unsafe.Pointer + +func (m *mapping) Add(x unsafe.Pointer) token { + res := token(C.malloc(1)) + + m.lock.Lock() + m.values[res] = x + m.lock.Unlock() + + return res +} + +func (m *mapping) Get(x token) unsafe.Pointer { + m.lock.Lock() + res := m.values[x] + m.lock.Unlock() + + return res +} + +func (m *mapping) Del(x token) { + m.lock.Lock() + delete(m.values, x) + m.lock.Unlock() + + C.free(unsafe.Pointer(x)) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/md4.go b/vendor/github.com/spacemonkeygo/openssl/md4.go new file mode 100644 index 00000000..e5cc7d86 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/md4.go @@ -0,0 +1,89 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type MD4Hash struct { + ctx *C.EVP_MD_CTX + engine *Engine +} + +func NewMD4Hash() (*MD4Hash, error) { return NewMD4HashWithEngine(nil) } + +func NewMD4HashWithEngine(e *Engine) (*MD4Hash, error) { + hash := &MD4Hash{engine: e} + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: md4: unable to allocate ctx") + } + runtime.SetFinalizer(hash, func(hash *MD4Hash) { hash.Close() }) + if err := hash.Reset(); err != nil { + return nil, err + } + return hash, nil +} + +func (s *MD4Hash) Close() { + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } +} + +func (s *MD4Hash) Reset() error { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) { + return errors.New("openssl: md4: cannot init digest ctx") + } + return nil +} + +func (s *MD4Hash) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) { + return 0, errors.New("openssl: md4: cannot update digest") + } + return len(p), nil +} + +func (s *MD4Hash) Sum() (result [16]byte, err error) { + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + return result, errors.New("openssl: md4: cannot finalize ctx") + } + return result, s.Reset() +} + +func MD4(data []byte) (result [16]byte, err error) { + hash, err := NewMD4Hash() + if err != nil { + return result, err + } + defer hash.Close() + if _, err := hash.Write(data); err != nil { + return result, err + } + return hash.Sum() +} diff --git a/vendor/github.com/spacemonkeygo/openssl/md5.go b/vendor/github.com/spacemonkeygo/openssl/md5.go new file mode 100644 index 00000000..82f2eb2f --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/md5.go @@ -0,0 +1,89 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type MD5Hash struct { + ctx *C.EVP_MD_CTX + engine *Engine +} + +func NewMD5Hash() (*MD5Hash, error) { return NewMD5HashWithEngine(nil) } + +func NewMD5HashWithEngine(e *Engine) (*MD5Hash, error) { + hash := &MD5Hash{engine: e} + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: md5: unable to allocate ctx") + } + runtime.SetFinalizer(hash, func(hash *MD5Hash) { hash.Close() }) + if err := hash.Reset(); err != nil { + return nil, err + } + return hash, nil +} + +func (s *MD5Hash) Close() { + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } +} + +func (s *MD5Hash) Reset() error { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) { + return errors.New("openssl: md5: cannot init digest ctx") + } + return nil +} + +func (s *MD5Hash) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) { + return 0, errors.New("openssl: md5: cannot update digest") + } + return len(p), nil +} + +func (s *MD5Hash) Sum() (result [16]byte, err error) { + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + return result, errors.New("openssl: md5: cannot finalize ctx") + } + return result, s.Reset() +} + +func MD5(data []byte) (result [16]byte, err error) { + hash, err := NewMD5Hash() + if err != nil { + return result, err + } + defer hash.Close() + if _, err := hash.Write(data); err != nil { + return result, err + } + return hash.Sum() +} diff --git a/vendor/github.com/spacemonkeygo/openssl/net.go b/vendor/github.com/spacemonkeygo/openssl/net.go new file mode 100644 index 00000000..54beb8ee --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/net.go @@ -0,0 +1,147 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +import ( + "errors" + "net" +) + +type listener struct { + net.Listener + ctx *Ctx +} + +func (l *listener) Accept() (c net.Conn, err error) { + c, err = l.Listener.Accept() + if err != nil { + return nil, err + } + ssl_c, err := Server(c, l.ctx) + if err != nil { + c.Close() + return nil, err + } + return ssl_c, nil +} + +// NewListener wraps an existing net.Listener such that all accepted +// connections are wrapped as OpenSSL server connections using the provided +// context ctx. +func NewListener(inner net.Listener, ctx *Ctx) net.Listener { + return &listener{ + Listener: inner, + ctx: ctx} +} + +// Listen is a wrapper around net.Listen that wraps incoming connections with +// an OpenSSL server connection using the provided context ctx. +func Listen(network, laddr string, ctx *Ctx) (net.Listener, error) { + if ctx == nil { + return nil, errors.New("no ssl context provided") + } + l, err := net.Listen(network, laddr) + if err != nil { + return nil, err + } + return NewListener(l, ctx), nil +} + +type DialFlags int + +const ( + InsecureSkipHostVerification DialFlags = 1 << iota + DisableSNI +) + +// Dial will connect to network/address and then wrap the corresponding +// underlying connection with an OpenSSL client connection using context ctx. +// If flags includes InsecureSkipHostVerification, the server certificate's +// hostname will not be checked to match the hostname in addr. Otherwise, flags +// should be 0. +// +// Dial probably won't work for you unless you set a verify location or add +// some certs to the certificate store of the client context you're using. +// This library is not nice enough to use the system certificate store by +// default for you yet. +func Dial(network, addr string, ctx *Ctx, flags DialFlags) (*Conn, error) { + return DialSession(network, addr, ctx, flags, nil) +} + +// DialSession will connect to network/address and then wrap the corresponding +// underlying connection with an OpenSSL client connection using context ctx. +// If flags includes InsecureSkipHostVerification, the server certificate's +// hostname will not be checked to match the hostname in addr. Otherwise, flags +// should be 0. +// +// Dial probably won't work for you unless you set a verify location or add +// some certs to the certificate store of the client context you're using. +// This library is not nice enough to use the system certificate store by +// default for you yet. +// +// If session is not nil it will be used to resume the tls state. The session +// can be retrieved from the GetSession method on the Conn. +func DialSession(network, addr string, ctx *Ctx, flags DialFlags, + session []byte) (*Conn, error) { + + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + if ctx == nil { + var err error + ctx, err = NewCtx() + if err != nil { + return nil, err + } + // TODO: use operating system default certificate chain? + } + c, err := net.Dial(network, addr) + if err != nil { + return nil, err + } + conn, err := Client(c, ctx) + if err != nil { + c.Close() + return nil, err + } + if session != nil { + err := conn.setSession(session) + if err != nil { + c.Close() + return nil, err + } + } + if flags&DisableSNI == 0 { + err = conn.SetTlsExtHostName(host) + if err != nil { + conn.Close() + return nil, err + } + } + err = conn.Handshake() + if err != nil { + conn.Close() + return nil, err + } + if flags&InsecureSkipHostVerification == 0 { + err = conn.VerifyHostname(host) + if err != nil { + conn.Close() + return nil, err + } + } + return conn, nil +} diff --git a/vendor/github.com/spacemonkeygo/openssl/nid.go b/vendor/github.com/spacemonkeygo/openssl/nid.go new file mode 100644 index 00000000..936a52e7 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/nid.go @@ -0,0 +1,210 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +type NID int + +const ( + NID_undef NID = 0 + NID_rsadsi NID = 1 + NID_pkcs NID = 2 + NID_md2 NID = 3 + NID_md5 NID = 4 + NID_rc4 NID = 5 + NID_rsaEncryption NID = 6 + NID_md2WithRSAEncryption NID = 7 + NID_md5WithRSAEncryption NID = 8 + NID_pbeWithMD2AndDES_CBC NID = 9 + NID_pbeWithMD5AndDES_CBC NID = 10 + NID_X500 NID = 11 + NID_X509 NID = 12 + NID_commonName NID = 13 + NID_countryName NID = 14 + NID_localityName NID = 15 + NID_stateOrProvinceName NID = 16 + NID_organizationName NID = 17 + NID_organizationalUnitName NID = 18 + NID_rsa NID = 19 + NID_pkcs7 NID = 20 + NID_pkcs7_data NID = 21 + NID_pkcs7_signed NID = 22 + NID_pkcs7_enveloped NID = 23 + NID_pkcs7_signedAndEnveloped NID = 24 + NID_pkcs7_digest NID = 25 + NID_pkcs7_encrypted NID = 26 + NID_pkcs3 NID = 27 + NID_dhKeyAgreement NID = 28 + NID_des_ecb NID = 29 + NID_des_cfb64 NID = 30 + NID_des_cbc NID = 31 + NID_des_ede NID = 32 + NID_des_ede3 NID = 33 + NID_idea_cbc NID = 34 + NID_idea_cfb64 NID = 35 + NID_idea_ecb NID = 36 + NID_rc2_cbc NID = 37 + NID_rc2_ecb NID = 38 + NID_rc2_cfb64 NID = 39 + NID_rc2_ofb64 NID = 40 + NID_sha NID = 41 + NID_shaWithRSAEncryption NID = 42 + NID_des_ede_cbc NID = 43 + NID_des_ede3_cbc NID = 44 + NID_des_ofb64 NID = 45 + NID_idea_ofb64 NID = 46 + NID_pkcs9 NID = 47 + NID_pkcs9_emailAddress NID = 48 + NID_pkcs9_unstructuredName NID = 49 + NID_pkcs9_contentType NID = 50 + NID_pkcs9_messageDigest NID = 51 + NID_pkcs9_signingTime NID = 52 + NID_pkcs9_countersignature NID = 53 + NID_pkcs9_challengePassword NID = 54 + NID_pkcs9_unstructuredAddress NID = 55 + NID_pkcs9_extCertAttributes NID = 56 + NID_netscape NID = 57 + NID_netscape_cert_extension NID = 58 + NID_netscape_data_type NID = 59 + NID_des_ede_cfb64 NID = 60 + NID_des_ede3_cfb64 NID = 61 + NID_des_ede_ofb64 NID = 62 + NID_des_ede3_ofb64 NID = 63 + NID_sha1 NID = 64 + NID_sha1WithRSAEncryption NID = 65 + NID_dsaWithSHA NID = 66 + NID_dsa_2 NID = 67 + NID_pbeWithSHA1AndRC2_CBC NID = 68 + NID_id_pbkdf2 NID = 69 + NID_dsaWithSHA1_2 NID = 70 + NID_netscape_cert_type NID = 71 + NID_netscape_base_url NID = 72 + NID_netscape_revocation_url NID = 73 + NID_netscape_ca_revocation_url NID = 74 + NID_netscape_renewal_url NID = 75 + NID_netscape_ca_policy_url NID = 76 + NID_netscape_ssl_server_name NID = 77 + NID_netscape_comment NID = 78 + NID_netscape_cert_sequence NID = 79 + NID_desx_cbc NID = 80 + NID_id_ce NID = 81 + NID_subject_key_identifier NID = 82 + NID_key_usage NID = 83 + NID_private_key_usage_period NID = 84 + NID_subject_alt_name NID = 85 + NID_issuer_alt_name NID = 86 + NID_basic_constraints NID = 87 + NID_crl_number NID = 88 + NID_certificate_policies NID = 89 + NID_authority_key_identifier NID = 90 + NID_bf_cbc NID = 91 + NID_bf_ecb NID = 92 + NID_bf_cfb64 NID = 93 + NID_bf_ofb64 NID = 94 + NID_mdc2 NID = 95 + NID_mdc2WithRSA NID = 96 + NID_rc4_40 NID = 97 + NID_rc2_40_cbc NID = 98 + NID_givenName NID = 99 + NID_surname NID = 100 + NID_initials NID = 101 + NID_uniqueIdentifier NID = 102 + NID_crl_distribution_points NID = 103 + NID_md5WithRSA NID = 104 + NID_serialNumber NID = 105 + NID_title NID = 106 + NID_description NID = 107 + NID_cast5_cbc NID = 108 + NID_cast5_ecb NID = 109 + NID_cast5_cfb64 NID = 110 + NID_cast5_ofb64 NID = 111 + NID_pbeWithMD5AndCast5_CBC NID = 112 + NID_dsaWithSHA1 NID = 113 + NID_md5_sha1 NID = 114 + NID_sha1WithRSA NID = 115 + NID_dsa NID = 116 + NID_ripemd160 NID = 117 + NID_ripemd160WithRSA NID = 119 + NID_rc5_cbc NID = 120 + NID_rc5_ecb NID = 121 + NID_rc5_cfb64 NID = 122 + NID_rc5_ofb64 NID = 123 + NID_rle_compression NID = 124 + NID_zlib_compression NID = 125 + NID_ext_key_usage NID = 126 + NID_id_pkix NID = 127 + NID_id_kp NID = 128 + NID_server_auth NID = 129 + NID_client_auth NID = 130 + NID_code_sign NID = 131 + NID_email_protect NID = 132 + NID_time_stamp NID = 133 + NID_ms_code_ind NID = 134 + NID_ms_code_com NID = 135 + NID_ms_ctl_sign NID = 136 + NID_ms_sgc NID = 137 + NID_ms_efs NID = 138 + NID_ns_sgc NID = 139 + NID_delta_crl NID = 140 + NID_crl_reason NID = 141 + NID_invalidity_date NID = 142 + NID_sxnet NID = 143 + NID_pbe_WithSHA1And128BitRC4 NID = 144 + NID_pbe_WithSHA1And40BitRC4 NID = 145 + NID_pbe_WithSHA1And3_Key_TripleDES_CBC NID = 146 + NID_pbe_WithSHA1And2_Key_TripleDES_CBC NID = 147 + NID_pbe_WithSHA1And128BitRC2_CBC NID = 148 + NID_pbe_WithSHA1And40BitRC2_CBC NID = 149 + NID_keyBag NID = 150 + NID_pkcs8ShroudedKeyBag NID = 151 + NID_certBag NID = 152 + NID_crlBag NID = 153 + NID_secretBag NID = 154 + NID_safeContentsBag NID = 155 + NID_friendlyName NID = 156 + NID_localKeyID NID = 157 + NID_x509Certificate NID = 158 + NID_sdsiCertificate NID = 159 + NID_x509Crl NID = 160 + NID_pbes2 NID = 161 + NID_pbmac1 NID = 162 + NID_hmacWithSHA1 NID = 163 + NID_id_qt_cps NID = 164 + NID_id_qt_unotice NID = 165 + NID_rc2_64_cbc NID = 166 + NID_SMIMECapabilities NID = 167 + NID_pbeWithMD2AndRC2_CBC NID = 168 + NID_pbeWithMD5AndRC2_CBC NID = 169 + NID_pbeWithSHA1AndDES_CBC NID = 170 + NID_ms_ext_req NID = 171 + NID_ext_req NID = 172 + NID_name NID = 173 + NID_dnQualifier NID = 174 + NID_id_pe NID = 175 + NID_id_ad NID = 176 + NID_info_access NID = 177 + NID_ad_OCSP NID = 178 + NID_ad_ca_issuers NID = 179 + NID_OCSP_sign NID = 180 + NID_X9_62_id_ecPublicKey NID = 408 + NID_hmac NID = 855 + NID_cmac NID = 894 + NID_dhpublicnumber NID = 920 + NID_tls1_prf NID = 1021 + NID_hkdf NID = 1036 + NID_X25519 NID = 1034 + NID_X448 NID = 1035 + NID_ED25519 NID = 1087 + NID_ED448 NID = 1088 +) diff --git a/vendor/github.com/spacemonkeygo/openssl/pem.go b/vendor/github.com/spacemonkeygo/openssl/pem.go new file mode 100644 index 00000000..c8b0c1cf --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/pem.go @@ -0,0 +1,32 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +import ( + "regexp" +) + +var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` + + `(^-----[\s-]*?BEGIN.*?-----$` + + `.*?` + + `^-----[\s-]*?END.*?-----$)`) + +func SplitPEM(data []byte) [][]byte { + var results [][]byte + for _, block := range pemSplit.FindAll(data, -1) { + results = append(results, block) + } + return results +} diff --git a/vendor/github.com/spacemonkeygo/openssl/sha1.go b/vendor/github.com/spacemonkeygo/openssl/sha1.go new file mode 100644 index 00000000..c227bee8 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/sha1.go @@ -0,0 +1,96 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type SHA1Hash struct { + ctx *C.EVP_MD_CTX + engine *Engine +} + +func NewSHA1Hash() (*SHA1Hash, error) { return NewSHA1HashWithEngine(nil) } + +func NewSHA1HashWithEngine(e *Engine) (*SHA1Hash, error) { + hash := &SHA1Hash{engine: e} + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: sha1: unable to allocate ctx") + } + runtime.SetFinalizer(hash, func(hash *SHA1Hash) { hash.Close() }) + if err := hash.Reset(); err != nil { + return nil, err + } + return hash, nil +} + +func (s *SHA1Hash) Close() { + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } +} + +func engineRef(e *Engine) *C.ENGINE { + if e == nil { + return nil + } + return e.e +} + +func (s *SHA1Hash) Reset() error { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) { + return errors.New("openssl: sha1: cannot init digest ctx") + } + return nil +} + +func (s *SHA1Hash) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) { + return 0, errors.New("openssl: sha1: cannot update digest") + } + return len(p), nil +} + +func (s *SHA1Hash) Sum() (result [20]byte, err error) { + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + return result, errors.New("openssl: sha1: cannot finalize ctx") + } + return result, s.Reset() +} + +func SHA1(data []byte) (result [20]byte, err error) { + hash, err := NewSHA1Hash() + if err != nil { + return result, err + } + defer hash.Close() + if _, err := hash.Write(data); err != nil { + return result, err + } + return hash.Sum() +} diff --git a/vendor/github.com/spacemonkeygo/openssl/sha256.go b/vendor/github.com/spacemonkeygo/openssl/sha256.go new file mode 100644 index 00000000..d25c7a95 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/sha256.go @@ -0,0 +1,89 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "errors" + "runtime" + "unsafe" +) + +type SHA256Hash struct { + ctx *C.EVP_MD_CTX + engine *Engine +} + +func NewSHA256Hash() (*SHA256Hash, error) { return NewSHA256HashWithEngine(nil) } + +func NewSHA256HashWithEngine(e *Engine) (*SHA256Hash, error) { + hash := &SHA256Hash{engine: e} + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: sha256: unable to allocate ctx") + } + runtime.SetFinalizer(hash, func(hash *SHA256Hash) { hash.Close() }) + if err := hash.Reset(); err != nil { + return nil, err + } + return hash, nil +} + +func (s *SHA256Hash) Close() { + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } +} + +func (s *SHA256Hash) Reset() error { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) { + return errors.New("openssl: sha256: cannot init digest ctx") + } + return nil +} + +func (s *SHA256Hash) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) { + return 0, errors.New("openssl: sha256: cannot update digest") + } + return len(p), nil +} + +func (s *SHA256Hash) Sum() (result [32]byte, err error) { + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + return result, errors.New("openssl: sha256: cannot finalize ctx") + } + return result, s.Reset() +} + +func SHA256(data []byte) (result [32]byte, err error) { + hash, err := NewSHA256Hash() + if err != nil { + return result, err + } + defer hash.Close() + if _, err := hash.Write(data); err != nil { + return result, err + } + return hash.Sum() +} diff --git a/vendor/github.com/spacemonkeygo/openssl/shim.c b/vendor/github.com/spacemonkeygo/openssl/shim.c new file mode 100644 index 00000000..6e680841 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/shim.c @@ -0,0 +1,770 @@ +/* + * Copyright (C) 2014 Space Monkey, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "_cgo_export.h" + +/* + * Functions defined in other .c files + */ +extern int go_init_locks(); +extern void go_thread_locking_callback(int, int, const char*, int); +extern unsigned long go_thread_id_callback(); +static int go_write_bio_puts(BIO *b, const char *str) { + return go_write_bio_write(b, (char*)str, (int)strlen(str)); +} + +/* + ************************************************ + * v1.1.1 and later implementation + ************************************************ + */ +#if OPENSSL_VERSION_NUMBER >= 0x1010100fL + +const int X_ED25519_SUPPORT = 1; +int X_EVP_PKEY_ED25519 = EVP_PKEY_ED25519; + +int X_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey){ + return EVP_DigestSignInit(ctx, pctx, type, e, pkey); +} + +int X_EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, size_t tbslen) { + return EVP_DigestSign(ctx, sigret, siglen, tbs, tbslen); +} + + +int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey){ + return EVP_DigestVerifyInit(ctx, pctx, type, e, pkey); +} + +int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, size_t tbslen){ + return EVP_DigestVerify(ctx, sigret, siglen, tbs, tbslen); +} + +#else + +const int X_ED25519_SUPPORT = 0; +int X_EVP_PKEY_ED25519 = EVP_PKEY_NONE; + +int X_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey){ + return 0; +} + +int X_EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, size_t tbslen) { + return 0; +} + + +int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey){ + return 0; +} + +int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, size_t tbslen){ + return 0; +} + +#endif + +/* + ************************************************ + * v1.1.X and later implementation + ************************************************ + */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + +void X_BIO_set_data(BIO* bio, void* data) { + BIO_set_data(bio, data); +} + +void* X_BIO_get_data(BIO* bio) { + return BIO_get_data(bio); +} + +EVP_MD_CTX* X_EVP_MD_CTX_new() { + return EVP_MD_CTX_new(); +} + +void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) { + EVP_MD_CTX_free(ctx); +} + +static int x_bio_create(BIO *b) { + BIO_set_shutdown(b, 1); + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_clear_flags(b, ~0); + return 1; +} + +static int x_bio_free(BIO *b) { + return 1; +} + +static BIO_METHOD *writeBioMethod; +static BIO_METHOD *readBioMethod; + +BIO_METHOD* BIO_s_readBio() { return readBioMethod; } +BIO_METHOD* BIO_s_writeBio() { return writeBioMethod; } + +int x_bio_init_methods() { + writeBioMethod = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "Go Write BIO"); + if (!writeBioMethod) { + return 1; + } + if (1 != BIO_meth_set_write(writeBioMethod, + (int (*)(BIO *, const char *, int))go_write_bio_write)) { + return 2; + } + if (1 != BIO_meth_set_puts(writeBioMethod, go_write_bio_puts)) { + return 3; + } + if (1 != BIO_meth_set_ctrl(writeBioMethod, go_write_bio_ctrl)) { + return 4; + } + if (1 != BIO_meth_set_create(writeBioMethod, x_bio_create)) { + return 5; + } + if (1 != BIO_meth_set_destroy(writeBioMethod, x_bio_free)) { + return 6; + } + + readBioMethod = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "Go Read BIO"); + if (!readBioMethod) { + return 7; + } + if (1 != BIO_meth_set_read(readBioMethod, go_read_bio_read)) { + return 8; + } + if (1 != BIO_meth_set_ctrl(readBioMethod, go_read_bio_ctrl)) { + return 9; + } + if (1 != BIO_meth_set_create(readBioMethod, x_bio_create)) { + return 10; + } + if (1 != BIO_meth_set_destroy(readBioMethod, x_bio_free)) { + return 11; + } + + return 0; +} + +const EVP_MD *X_EVP_dss() { + return NULL; +} + +const EVP_MD *X_EVP_dss1() { + return NULL; +} + +const EVP_MD *X_EVP_sha() { + return NULL; +} + +int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_encrypting(ctx); +} + +int X_X509_add_ref(X509* x509) { + return X509_up_ref(x509); +} + +const ASN1_TIME *X_X509_get0_notBefore(const X509 *x) { + return X509_get0_notBefore(x); +} + +const ASN1_TIME *X_X509_get0_notAfter(const X509 *x) { + return X509_get0_notAfter(x); +} + +HMAC_CTX *X_HMAC_CTX_new(void) { + return HMAC_CTX_new(); +} + +void X_HMAC_CTX_free(HMAC_CTX *ctx) { + HMAC_CTX_free(ctx); +} + +int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { + return PEM_write_bio_PrivateKey_traditional(bio, key, enc, kstr, klen, cb, u); +} + +#endif + +/* + ************************************************ + * v1.0.X implementation + ************************************************ + */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + +static int x_bio_create(BIO *b) { + b->shutdown = 1; + b->init = 1; + b->num = -1; + b->ptr = NULL; + b->flags = 0; + return 1; +} + +static int x_bio_free(BIO *b) { + return 1; +} + +static BIO_METHOD writeBioMethod = { + BIO_TYPE_SOURCE_SINK, + "Go Write BIO", + (int (*)(BIO *, const char *, int))go_write_bio_write, + NULL, + go_write_bio_puts, + NULL, + go_write_bio_ctrl, + x_bio_create, + x_bio_free, + NULL}; + +static BIO_METHOD* BIO_s_writeBio() { return &writeBioMethod; } + +static BIO_METHOD readBioMethod = { + BIO_TYPE_SOURCE_SINK, + "Go Read BIO", + NULL, + go_read_bio_read, + NULL, + NULL, + go_read_bio_ctrl, + x_bio_create, + x_bio_free, + NULL}; + +static BIO_METHOD* BIO_s_readBio() { return &readBioMethod; } + +int x_bio_init_methods() { + /* statically initialized above */ + return 0; +} + +void X_BIO_set_data(BIO* bio, void* data) { + bio->ptr = data; +} + +void* X_BIO_get_data(BIO* bio) { + return bio->ptr; +} + +EVP_MD_CTX* X_EVP_MD_CTX_new() { + return EVP_MD_CTX_create(); +} + +void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) { + EVP_MD_CTX_destroy(ctx); +} + +int X_X509_add_ref(X509* x509) { + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +const ASN1_TIME *X_X509_get0_notBefore(const X509 *x) { + return x->cert_info->validity->notBefore; +} + +const ASN1_TIME *X_X509_get0_notAfter(const X509 *x) { + return x->cert_info->validity->notAfter; +} + +const EVP_MD *X_EVP_dss() { + return EVP_dss(); +} + +const EVP_MD *X_EVP_dss1() { + return EVP_dss1(); +} + +const EVP_MD *X_EVP_sha() { + return EVP_sha(); +} + +int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) { + return ctx->encrypt; +} + +HMAC_CTX *X_HMAC_CTX_new(void) { + /* v1.1.0 uses a OPENSSL_zalloc to allocate the memory which does not exist + * in previous versions. malloc+memset to get the same behavior */ + HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx) { + memset(ctx, 0, sizeof(HMAC_CTX)); + HMAC_CTX_init(ctx); + } + return ctx; +} + +void X_HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx) { + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { + /* PEM_write_bio_PrivateKey always tries to use the PKCS8 format if it + * is available, instead of using the "traditional" format as stated in the + * OpenSSL man page. + * i2d_PrivateKey should give us the correct DER encoding, so we'll just + * use PEM_ASN1_write_bio directly to write the DER encoding with the correct + * type header. */ + + int ppkey_id, pkey_base_id, ppkey_flags; + const char *pinfo, *ppem_str; + char pem_type_str[80]; + + // Lookup the ASN1 method information to get the pem type + if (EVP_PKEY_asn1_get0_info(&ppkey_id, &pkey_base_id, &ppkey_flags, &pinfo, &ppem_str, key->ameth) != 1) { + return 0; + } + // Set up the PEM type string + if (BIO_snprintf(pem_type_str, 80, "%s PRIVATE KEY", ppem_str) <= 0) { + // Failed to write out the pem type string, something is really wrong. + return 0; + } + // Write out everything to the BIO + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_type_str, bio, key, enc, kstr, klen, cb, u); +} + +#endif + +/* + ************************************************ + * common implementation + ************************************************ + */ + +int X_shim_init() { + int rc = 0; + + OPENSSL_config(NULL); + ENGINE_load_builtin_engines(); + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); + // + // Set up OPENSSL thread safety callbacks. + rc = go_init_locks(); + if (rc != 0) { + return rc; + } + CRYPTO_set_locking_callback(go_thread_locking_callback); + CRYPTO_set_id_callback(go_thread_id_callback); + + rc = x_bio_init_methods(); + if (rc != 0) { + return rc; + } + + return 0; +} + +void * X_OPENSSL_malloc(size_t size) { + return OPENSSL_malloc(size); +} + +void X_OPENSSL_free(void *ref) { + OPENSSL_free(ref); +} + +long X_SSL_set_options(SSL* ssl, long options) { + return SSL_set_options(ssl, options); +} + +long X_SSL_get_options(SSL* ssl) { + return SSL_get_options(ssl); +} + +long X_SSL_clear_options(SSL* ssl, long options) { + return SSL_clear_options(ssl, options); +} + +long X_SSL_set_tlsext_host_name(SSL *ssl, const char *name) { + return SSL_set_tlsext_host_name(ssl, name); +} +const char * X_SSL_get_cipher_name(const SSL *ssl) { + return SSL_get_cipher_name(ssl); +} +int X_SSL_session_reused(SSL *ssl) { + return SSL_session_reused(ssl); +} + +int X_SSL_new_index() { + return SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); +} + +int X_SSL_verify_cb(int ok, X509_STORE_CTX* store) { + SSL* ssl = (SSL *)X509_STORE_CTX_get_ex_data(store, + SSL_get_ex_data_X509_STORE_CTX_idx()); + void* p = SSL_get_ex_data(ssl, get_ssl_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ssl_verify_cb_thunk(p, ok, store); +} + +const SSL_METHOD *X_SSLv23_method() { + return SSLv23_method(); +} + +const SSL_METHOD *X_SSLv3_method() { +#ifndef OPENSSL_NO_SSL3_METHOD + return SSLv3_method(); +#else + return NULL; +#endif +} + +const SSL_METHOD *X_TLSv1_method() { + return TLSv1_method(); +} + +const SSL_METHOD *X_TLSv1_1_method() { +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) + return TLSv1_1_method(); +#else + return NULL; +#endif +} + +const SSL_METHOD *X_TLSv1_2_method() { +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) + return TLSv1_2_method(); +#else + return NULL; +#endif +} + +int X_SSL_CTX_new_index() { + return SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); +} + +long X_SSL_CTX_set_options(SSL_CTX* ctx, long options) { + return SSL_CTX_set_options(ctx, options); +} + +long X_SSL_CTX_clear_options(SSL_CTX* ctx, long options) { + return SSL_CTX_clear_options(ctx, options); +} + +long X_SSL_CTX_get_options(SSL_CTX* ctx) { + return SSL_CTX_get_options(ctx); +} + +long X_SSL_CTX_set_mode(SSL_CTX* ctx, long modes) { + return SSL_CTX_set_mode(ctx, modes); +} + +long X_SSL_CTX_get_mode(SSL_CTX* ctx) { + return SSL_CTX_get_mode(ctx); +} + +long X_SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long modes) { + return SSL_CTX_set_session_cache_mode(ctx, modes); +} + +long X_SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long t) { + return SSL_CTX_sess_set_cache_size(ctx, t); +} + +long X_SSL_CTX_sess_get_cache_size(SSL_CTX* ctx) { + return SSL_CTX_sess_get_cache_size(ctx); +} + +long X_SSL_CTX_set_timeout(SSL_CTX* ctx, long t) { + return SSL_CTX_set_timeout(ctx, t); +} + +long X_SSL_CTX_get_timeout(SSL_CTX* ctx) { + return SSL_CTX_get_timeout(ctx); +} + +long X_SSL_CTX_add_extra_chain_cert(SSL_CTX* ctx, X509 *cert) { + return SSL_CTX_add_extra_chain_cert(ctx, cert); +} + +long X_SSL_CTX_set_tmp_ecdh(SSL_CTX* ctx, EC_KEY *key) { + return SSL_CTX_set_tmp_ecdh(ctx, key); +} + +long X_SSL_CTX_set_tlsext_servername_callback( + SSL_CTX* ctx, int (*cb)(SSL *con, int *ad, void *args)) { + return SSL_CTX_set_tlsext_servername_callback(ctx, cb); +} + +int X_SSL_CTX_verify_cb(int ok, X509_STORE_CTX* store) { + SSL* ssl = (SSL *)X509_STORE_CTX_get_ex_data(store, + SSL_get_ex_data_X509_STORE_CTX_idx()); + SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ssl_ctx_verify_cb_thunk(p, ok, store); +} + +long X_SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH *dh) { + return SSL_CTX_set_tmp_dh(ctx, dh); +} + +long X_PEM_read_DHparams(SSL_CTX* ctx, DH *dh) { + return SSL_CTX_set_tmp_dh(ctx, dh); +} + +int X_SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *sslctx, + int (*cb)(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)) { + return SSL_CTX_set_tlsext_ticket_key_cb(sslctx, cb); +} + +int X_SSL_CTX_ticket_key_cb(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc) { + + SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(s); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ticket_key_cb_thunk(p, s, key_name, iv, cctx, hctx, enc); +} + +int X_BIO_get_flags(BIO *b) { + return BIO_get_flags(b); +} + +void X_BIO_set_flags(BIO *b, int flags) { + return BIO_set_flags(b, flags); +} + +void X_BIO_clear_flags(BIO *b, int flags) { + BIO_clear_flags(b, flags); +} + +int X_BIO_read(BIO *b, void *buf, int len) { + return BIO_read(b, buf, len); +} + +int X_BIO_write(BIO *b, const void *buf, int len) { + return BIO_write(b, buf, len); +} + +BIO *X_BIO_new_write_bio() { + return BIO_new(BIO_s_writeBio()); +} + +BIO *X_BIO_new_read_bio() { + return BIO_new(BIO_s_readBio()); +} + +const EVP_MD *X_EVP_get_digestbyname(const char *name) { + return EVP_get_digestbyname(name); +} + +const EVP_MD *X_EVP_md_null() { + return EVP_md_null(); +} + +const EVP_MD *X_EVP_md5() { + return EVP_md5(); +} + +const EVP_MD *X_EVP_md4() { + return EVP_md4(); +} + +const EVP_MD *X_EVP_ripemd160() { + return EVP_ripemd160(); +} + +const EVP_MD *X_EVP_sha224() { + return EVP_sha224(); +} + +const EVP_MD *X_EVP_sha1() { + return EVP_sha1(); +} + +const EVP_MD *X_EVP_sha256() { + return EVP_sha256(); +} + +const EVP_MD *X_EVP_sha384() { + return EVP_sha384(); +} + +const EVP_MD *X_EVP_sha512() { + return EVP_sha512(); +} + +int X_EVP_MD_size(const EVP_MD *md) { + return EVP_MD_size(md); +} + +int X_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int X_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) { + return EVP_DigestUpdate(ctx, d, cnt); +} + +int X_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) { + return EVP_DigestFinal_ex(ctx, md, s); +} + +int X_EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_SignInit(ctx, type); +} + +int X_EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt) { + return EVP_SignUpdate(ctx, d, cnt); +} + +EVP_PKEY *X_EVP_PKEY_new(void) { + return EVP_PKEY_new(); +} + +void X_EVP_PKEY_free(EVP_PKEY *pkey) { + EVP_PKEY_free(pkey); +} + +int X_EVP_PKEY_size(EVP_PKEY *pkey) { + return EVP_PKEY_size(pkey); +} + +struct rsa_st *X_EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { + return EVP_PKEY_get1_RSA(pkey); +} + +int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key) { + return EVP_PKEY_set1_RSA(pkey, key); +} + +int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key) { + return EVP_PKEY_assign(pkey, type, key); +} + +int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey) { + return EVP_SignFinal(ctx, md, s, pkey); +} + +int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_VerifyInit(ctx, type); +} + +int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, + unsigned int cnt) { + return EVP_VerifyUpdate(ctx, d, cnt); +} + +int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) { + return EVP_VerifyFinal(ctx, sigbuf, siglen, pkey); +} + +int X_EVP_CIPHER_block_size(EVP_CIPHER *c) { + return EVP_CIPHER_block_size(c); +} + +int X_EVP_CIPHER_key_length(EVP_CIPHER *c) { + return EVP_CIPHER_key_length(c); +} + +int X_EVP_CIPHER_iv_length(EVP_CIPHER *c) { + return EVP_CIPHER_iv_length(c); +} + +int X_EVP_CIPHER_nid(EVP_CIPHER *c) { + return EVP_CIPHER_nid(c); +} + +int X_EVP_CIPHER_CTX_block_size(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_block_size(ctx); +} + +int X_EVP_CIPHER_CTX_key_length(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_key_length(ctx); +} + +int X_EVP_CIPHER_CTX_iv_length(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_iv_length(ctx); +} + +void X_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int padding) { + //openssl always returns 1 for set_padding + //hence return value is not checked + EVP_CIPHER_CTX_set_padding(ctx, padding); +} + +const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_cipher(ctx); +} + +int X_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) { + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); +} + +size_t X_HMAC_size(const HMAC_CTX *e) { + return HMAC_size(e); +} + +int X_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { + return HMAC_Init_ex(ctx, key, len, md, impl); +} + +int X_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { + return HMAC_Update(ctx, data, len); +} + +int X_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { + return HMAC_Final(ctx, md, len); +} + +int X_sk_X509_num(STACK_OF(X509) *sk) { + return sk_X509_num(sk); +} + +X509 *X_sk_X509_value(STACK_OF(X509)* sk, int i) { + return sk_X509_value(sk, i); +} + +long X_X509_get_version(const X509 *x) { + return X509_get_version(x); +} + +int X_X509_set_version(X509 *x, long version) { + return X509_set_version(x, version); +} diff --git a/vendor/github.com/spacemonkeygo/openssl/shim.h b/vendor/github.com/spacemonkeygo/openssl/shim.h new file mode 100644 index 00000000..b792822b --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/shim.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2014 Space Monkey, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SSL_MODE_RELEASE_BUFFERS +#define SSL_MODE_RELEASE_BUFFERS 0 +#endif + +#ifndef SSL_OP_NO_COMPRESSION +#define SSL_OP_NO_COMPRESSION 0 +#endif + +/* shim methods */ +extern int X_shim_init(); + +/* Library methods */ +extern void X_OPENSSL_free(void *ref); +extern void *X_OPENSSL_malloc(size_t size); + +/* SSL methods */ +extern long X_SSL_set_options(SSL* ssl, long options); +extern long X_SSL_get_options(SSL* ssl); +extern long X_SSL_clear_options(SSL* ssl, long options); +extern long X_SSL_set_tlsext_host_name(SSL *ssl, const char *name); +extern const char * X_SSL_get_cipher_name(const SSL *ssl); +extern int X_SSL_session_reused(SSL *ssl); +extern int X_SSL_new_index(); + +extern const SSL_METHOD *X_SSLv23_method(); +extern const SSL_METHOD *X_SSLv3_method(); +extern const SSL_METHOD *X_TLSv1_method(); +extern const SSL_METHOD *X_TLSv1_1_method(); +extern const SSL_METHOD *X_TLSv1_2_method(); + +#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME +extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); +#endif +extern int X_SSL_verify_cb(int ok, X509_STORE_CTX* store); + +/* SSL_CTX methods */ +extern int X_SSL_CTX_new_index(); +extern long X_SSL_CTX_set_options(SSL_CTX* ctx, long options); +extern long X_SSL_CTX_clear_options(SSL_CTX* ctx, long options); +extern long X_SSL_CTX_get_options(SSL_CTX* ctx); +extern long X_SSL_CTX_set_mode(SSL_CTX* ctx, long modes); +extern long X_SSL_CTX_get_mode(SSL_CTX* ctx); +extern long X_SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long modes); +extern long X_SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long t); +extern long X_SSL_CTX_sess_get_cache_size(SSL_CTX* ctx); +extern long X_SSL_CTX_set_timeout(SSL_CTX* ctx, long t); +extern long X_SSL_CTX_get_timeout(SSL_CTX* ctx); +extern long X_SSL_CTX_add_extra_chain_cert(SSL_CTX* ctx, X509 *cert); +extern long X_SSL_CTX_set_tmp_ecdh(SSL_CTX* ctx, EC_KEY *key); +extern long X_SSL_CTX_set_tlsext_servername_callback(SSL_CTX* ctx, int (*cb)(SSL *con, int *ad, void *args)); +extern int X_SSL_CTX_verify_cb(int ok, X509_STORE_CTX* store); +extern long X_SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH *dh); +extern long X_PEM_read_DHparams(SSL_CTX* ctx, DH *dh); +extern int X_SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *sslctx, + int (*cb)(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)); +extern int X_SSL_CTX_ticket_key_cb(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc); + +/* BIO methods */ +extern int X_BIO_get_flags(BIO *b); +extern void X_BIO_set_flags(BIO *bio, int flags); +extern void X_BIO_clear_flags(BIO *bio, int flags); +extern void X_BIO_set_data(BIO *bio, void* data); +extern void *X_BIO_get_data(BIO *bio); +extern int X_BIO_read(BIO *b, void *buf, int len); +extern int X_BIO_write(BIO *b, const void *buf, int len); +extern BIO *X_BIO_new_write_bio(); +extern BIO *X_BIO_new_read_bio(); + +/* EVP methods */ +extern const int X_ED25519_SUPPORT; +extern int X_EVP_PKEY_ED25519; +extern const EVP_MD *X_EVP_get_digestbyname(const char *name); +extern EVP_MD_CTX *X_EVP_MD_CTX_new(); +extern void X_EVP_MD_CTX_free(EVP_MD_CTX *ctx); +extern const EVP_MD *X_EVP_md_null(); +extern const EVP_MD *X_EVP_md5(); +extern const EVP_MD *X_EVP_md4(); +extern const EVP_MD *X_EVP_sha(); +extern const EVP_MD *X_EVP_sha1(); +extern const EVP_MD *X_EVP_dss(); +extern const EVP_MD *X_EVP_dss1(); +extern const EVP_MD *X_EVP_ripemd160(); +extern const EVP_MD *X_EVP_sha224(); +extern const EVP_MD *X_EVP_sha256(); +extern const EVP_MD *X_EVP_sha384(); +extern const EVP_MD *X_EVP_sha512(); +extern int X_EVP_MD_size(const EVP_MD *md); +extern int X_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +extern int X_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +extern int X_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +extern int X_EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); +extern int X_EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); +extern int X_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +extern int X_EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen); +extern EVP_PKEY *X_EVP_PKEY_new(void); +extern void X_EVP_PKEY_free(EVP_PKEY *pkey); +extern int X_EVP_PKEY_size(EVP_PKEY *pkey); +extern struct rsa_st *X_EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +extern int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +extern int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key); +extern int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey); +extern int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); +extern int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); +extern int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey); +extern int X_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +extern int X_EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); +extern int X_EVP_CIPHER_block_size(EVP_CIPHER *c); +extern int X_EVP_CIPHER_key_length(EVP_CIPHER *c); +extern int X_EVP_CIPHER_iv_length(EVP_CIPHER *c); +extern int X_EVP_CIPHER_nid(EVP_CIPHER *c); +extern int X_EVP_CIPHER_CTX_block_size(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_key_length(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_iv_length(EVP_CIPHER_CTX *ctx); +extern void X_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int padding); +extern const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); +extern int X_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); + +/* HMAC methods */ +extern size_t X_HMAC_size(const HMAC_CTX *e); +extern HMAC_CTX *X_HMAC_CTX_new(void); +extern void X_HMAC_CTX_free(HMAC_CTX *ctx); +extern int X_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); +extern int X_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +extern int X_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); + +/* X509 methods */ +extern int X_X509_add_ref(X509* x509); +extern const ASN1_TIME *X_X509_get0_notBefore(const X509 *x); +extern const ASN1_TIME *X_X509_get0_notAfter(const X509 *x); +extern int X_sk_X509_num(STACK_OF(X509) *sk); +extern X509 *X_sk_X509_value(STACK_OF(X509)* sk, int i); +extern long X_X509_get_version(const X509 *x); +extern int X_X509_set_version(X509 *x, long version); + +/* PEM methods */ +extern int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); diff --git a/vendor/github.com/spacemonkeygo/openssl/sni.c b/vendor/github.com/spacemonkeygo/openssl/sni.c new file mode 100644 index 00000000..f9e8d16b --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/sni.c @@ -0,0 +1,23 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "_cgo_export.h" +#include + +int sni_cb(SSL *con, int *ad, void *arg) { + SSL_CTX* ssl_ctx = ssl_ctx = SSL_get_SSL_CTX(con); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + return sni_cb_thunk(p, con, ad, arg); +} diff --git a/vendor/github.com/spacemonkeygo/openssl/ssl.go b/vendor/github.com/spacemonkeygo/openssl/ssl.go new file mode 100644 index 00000000..117c30c0 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/ssl.go @@ -0,0 +1,170 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "os" + "unsafe" +) + +type SSLTLSExtErr int + +const ( + SSLTLSExtErrOK SSLTLSExtErr = C.SSL_TLSEXT_ERR_OK + SSLTLSExtErrAlertWarning SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_WARNING + SSLTLSEXTErrAlertFatal SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_FATAL + SSLTLSEXTErrNoAck SSLTLSExtErr = C.SSL_TLSEXT_ERR_NOACK +) + +var ( + ssl_idx = C.X_SSL_new_index() +) + +//export get_ssl_idx +func get_ssl_idx() C.int { + return ssl_idx +} + +type SSL struct { + ssl *C.SSL + verify_cb VerifyCallback +} + +//export go_ssl_verify_cb_thunk +func go_ssl_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback panic'd: %v", err) + os.Exit(1) + } + }() + verify_cb := (*SSL)(p).verify_cb + // set up defaults just in case verify_cb is nil + if verify_cb != nil { + store := &CertificateStoreCtx{ctx: ctx} + if verify_cb(ok == 1, store) { + ok = 1 + } else { + ok = 0 + } + } + return ok +} + +// Wrapper around SSL_get_servername. Returns server name according to rfc6066 +// http://tools.ietf.org/html/rfc6066. +func (s *SSL) GetServername() string { + return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)) +} + +// GetOptions returns SSL options. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html +func (s *SSL) GetOptions() Options { + return Options(C.X_SSL_get_options(s.ssl)) +} + +// SetOptions sets SSL options. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html +func (s *SSL) SetOptions(options Options) Options { + return Options(C.X_SSL_set_options(s.ssl, C.long(options))) +} + +// ClearOptions clear SSL options. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html +func (s *SSL) ClearOptions(options Options) Options { + return Options(C.X_SSL_clear_options(s.ssl, C.long(options))) +} + +// SetVerify controls peer verification settings. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerify(options VerifyOptions, verify_cb VerifyCallback) { + s.verify_cb = verify_cb + if verify_cb != nil { + C.SSL_set_verify(s.ssl, C.int(options), (*[0]byte)(C.X_SSL_verify_cb)) + } else { + C.SSL_set_verify(s.ssl, C.int(options), nil) + } +} + +// SetVerifyMode controls peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyMode(options VerifyOptions) { + s.SetVerify(options, s.verify_cb) +} + +// SetVerifyCallback controls peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyCallback(verify_cb VerifyCallback) { + s.SetVerify(s.VerifyMode(), verify_cb) +} + +// GetVerifyCallback returns callback function. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) GetVerifyCallback() VerifyCallback { + return s.verify_cb +} + +// VerifyMode returns peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) VerifyMode() VerifyOptions { + return VerifyOptions(C.SSL_get_verify_mode(s.ssl)) +} + +// SetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyDepth(depth int) { + C.SSL_set_verify_depth(s.ssl, C.int(depth)) +} + +// GetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) GetVerifyDepth() int { + return int(C.SSL_get_verify_depth(s.ssl)) +} + +// SetSSLCtx changes context to new one. Useful for Server Name Indication (SNI) +// rfc6066 http://tools.ietf.org/html/rfc6066. See +// http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni +func (s *SSL) SetSSLCtx(ctx *Ctx) { + /* + * SSL_set_SSL_CTX() only changes certs as of 1.0.0d + * adjust other things we care about + */ + C.SSL_set_SSL_CTX(s.ssl, ctx.ctx) +} + +//export sni_cb_thunk +func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Pointer) C.int { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback sni panic'd: %v", err) + os.Exit(1) + } + }() + + sni_cb := (*Ctx)(p).sni_cb + + s := &SSL{ssl: con} + // This attaches a pointer to our SSL struct into the SNI callback. + C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s)) + + // Note: this is ctx.sni_cb, not C.sni_cb + return C.int(sni_cb(s)) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/tickets.go b/vendor/github.com/spacemonkeygo/openssl/tickets.go new file mode 100644 index 00000000..a064d385 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/tickets.go @@ -0,0 +1,222 @@ +// Copyright (C) 2017. See AUTHORS. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openssl + +// #include "shim.h" +import "C" + +import ( + "os" + "unsafe" +) + +const ( + KeyNameSize = 16 +) + +// TicketCipherCtx describes the cipher that will be used by the ticket store +// for encrypting the tickets. Engine may be nil if no engine is desired. +type TicketCipherCtx struct { + Cipher *Cipher + Engine *Engine +} + +// TicketDigestCtx describes the digest that will be used by the ticket store +// to authenticate the data. Engine may be nil if no engine is desired. +type TicketDigestCtx struct { + Digest *Digest + Engine *Engine +} + +// TicketName is an identifier for the key material for a ticket. +type TicketName [KeyNameSize]byte + +// TicketKey is the key material for a ticket. If this is lost, forward secrecy +// is lost as it allows decrypting TLS sessions retroactively. +type TicketKey struct { + Name TicketName + CipherKey []byte + HMACKey []byte + IV []byte +} + +// TicketKeyManager is a manager for TicketKeys. It allows one to control the +// lifetime of tickets, causing renewals and expirations for keys that are +// created. Calls to the manager are serialized. +type TicketKeyManager interface { + // New should create a brand new TicketKey with a new name. + New() *TicketKey + + // Current should return a key that is still valid. + Current() *TicketKey + + // Lookup should return a key with the given name, or nil if no name + // exists. + Lookup(name TicketName) *TicketKey + + // Expired should return if the key with the given name is expired and + // should not be used any more. + Expired(name TicketName) bool + + // ShouldRenew should return if the key is still ok to use for the current + // session, but we should send a new key for the client. + ShouldRenew(name TicketName) bool +} + +// TicketStore descibes the encryption and authentication methods the tickets +// will use along with a key manager for generating and keeping track of the +// secrets. +type TicketStore struct { + CipherCtx TicketCipherCtx + DigestCtx TicketDigestCtx + Keys TicketKeyManager +} + +func (t *TicketStore) cipherEngine() *C.ENGINE { + if t.CipherCtx.Engine == nil { + return nil + } + return t.CipherCtx.Engine.e +} + +func (t *TicketStore) digestEngine() *C.ENGINE { + if t.DigestCtx.Engine == nil { + return nil + } + return t.DigestCtx.Engine.e +} + +const ( + // instruct to do a handshake + ticket_resp_requireHandshake = 0 + // crypto context is set up correctly + ticket_resp_sessionOk = 1 + // crypto context is ok, but the ticket should be reissued + ticket_resp_renewSession = 2 + // we had a problem that shouldn't fall back to doing a handshake + ticket_resp_error = -1 + + // asked to create session crypto context + ticket_req_newSession = 1 + // asked to load crypto context for a previous session + ticket_req_lookupSession = 0 +) + +//export go_ticket_key_cb_thunk +func go_ticket_key_cb_thunk(p unsafe.Pointer, s *C.SSL, key_name *C.uchar, + iv *C.uchar, cctx *C.EVP_CIPHER_CTX, hctx *C.HMAC_CTX, enc C.int) C.int { + + // no panic's allowed. it's super hard to guarantee any state at this point + // so just abort everything. + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: ticket key callback panic'd: %v", err) + os.Exit(1) + } + }() + + ctx := (*Ctx)(p) + store := ctx.ticket_store + if store == nil { + // TODO(jeff): should this be an error condition? it doesn't make sense + // to be called if we don't have a store I believe, but that's probably + // not worth aborting the handshake which is what I believe returning + // an error would do. + return ticket_resp_requireHandshake + } + + ctx.ticket_store_mu.Lock() + defer ctx.ticket_store_mu.Unlock() + + switch enc { + case ticket_req_newSession: + key := store.Keys.Current() + if key == nil { + key = store.Keys.New() + if key == nil { + return ticket_resp_requireHandshake + } + } + + C.memcpy( + unsafe.Pointer(key_name), + unsafe.Pointer(&key.Name[0]), + KeyNameSize) + C.EVP_EncryptInit_ex( + cctx, + store.CipherCtx.Cipher.ptr, + store.cipherEngine(), + (*C.uchar)(&key.CipherKey[0]), + (*C.uchar)(&key.IV[0])) + C.HMAC_Init_ex( + hctx, + unsafe.Pointer(&key.HMACKey[0]), + C.int(len(key.HMACKey)), + store.DigestCtx.Digest.ptr, + store.digestEngine()) + + return ticket_resp_sessionOk + + case ticket_req_lookupSession: + var name TicketName + C.memcpy( + unsafe.Pointer(&name[0]), + unsafe.Pointer(key_name), + KeyNameSize) + + key := store.Keys.Lookup(name) + if key == nil { + return ticket_resp_requireHandshake + } + if store.Keys.Expired(name) { + return ticket_resp_requireHandshake + } + + C.EVP_DecryptInit_ex( + cctx, + store.CipherCtx.Cipher.ptr, + store.cipherEngine(), + (*C.uchar)(&key.CipherKey[0]), + (*C.uchar)(&key.IV[0])) + C.HMAC_Init_ex( + hctx, + unsafe.Pointer(&key.HMACKey[0]), + C.int(len(key.HMACKey)), + store.DigestCtx.Digest.ptr, + store.digestEngine()) + + if store.Keys.ShouldRenew(name) { + return ticket_resp_renewSession + } + + return ticket_resp_sessionOk + + default: + return ticket_resp_error + } +} + +// SetTicketStore sets the ticket store for the context so that clients can do +// ticket based session resumption. If the store is nil, the +func (c *Ctx) SetTicketStore(store *TicketStore) { + c.ticket_store = store + + if store == nil { + C.X_SSL_CTX_set_tlsext_ticket_key_cb(c.ctx, nil) + } else { + C.X_SSL_CTX_set_tlsext_ticket_key_cb(c.ctx, + (*[0]byte)(C.X_SSL_CTX_ticket_key_cb)) + } +} diff --git a/vendor/github.com/spacemonkeygo/openssl/utils/errors.go b/vendor/github.com/spacemonkeygo/openssl/utils/errors.go new file mode 100644 index 00000000..bab314c9 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/utils/errors.go @@ -0,0 +1,50 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "errors" + "strings" +) + +// ErrorGroup collates errors +type ErrorGroup struct { + Errors []error +} + +// Add adds an error to an existing error group +func (e *ErrorGroup) Add(err error) { + if err != nil { + e.Errors = append(e.Errors, err) + } +} + +// Finalize returns an error corresponding to the ErrorGroup state. If there's +// no errors in the group, finalize returns nil. If there's only one error, +// Finalize returns that error. Otherwise, Finalize will make a new error +// consisting of the messages from the constituent errors. +func (e *ErrorGroup) Finalize() error { + if len(e.Errors) == 0 { + return nil + } + if len(e.Errors) == 1 { + return e.Errors[0] + } + msgs := make([]string, 0, len(e.Errors)) + for _, err := range e.Errors { + msgs = append(msgs, err.Error()) + } + return errors.New(strings.Join(msgs, "\n")) +} diff --git a/vendor/github.com/spacemonkeygo/openssl/utils/future.go b/vendor/github.com/spacemonkeygo/openssl/utils/future.go new file mode 100644 index 00000000..fa1bbbfb --- /dev/null +++ b/vendor/github.com/spacemonkeygo/openssl/utils/future.go @@ -0,0 +1,79 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "sync" +) + +// Future is a type that is essentially the inverse of a channel. With a +// channel, you have multiple senders and one receiver. With a future, you can +// have multiple receivers and one sender. Additionally, a future protects +// against double-sends. Since this is usually used for returning function +// results, we also capture and return error values as well. Use NewFuture +// to initialize. +type Future struct { + mutex *sync.Mutex + cond *sync.Cond + received bool + val interface{} + err error +} + +// NewFuture returns an initialized and ready Future. +func NewFuture() *Future { + mutex := &sync.Mutex{} + return &Future{ + mutex: mutex, + cond: sync.NewCond(mutex), + received: false, + val: nil, + err: nil, + } +} + +// Get blocks until the Future has a value set. +func (self *Future) Get() (interface{}, error) { + self.mutex.Lock() + defer self.mutex.Unlock() + for { + if self.received { + return self.val, self.err + } + self.cond.Wait() + } +} + +// Fired returns whether or not a value has been set. If Fired is true, Get +// won't block. +func (self *Future) Fired() bool { + self.mutex.Lock() + defer self.mutex.Unlock() + return self.received +} + +// Set provides the value to present and future Get calls. If Set has already +// been called, this is a no-op. +func (self *Future) Set(val interface{}, err error) { + self.mutex.Lock() + defer self.mutex.Unlock() + if self.received { + return + } + self.received = true + self.val = val + self.err = err + self.cond.Broadcast() +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/.travis.yml b/vendor/github.com/spacemonkeygo/spacelog/.travis.yml new file mode 100644 index 00000000..d2b67f69 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.7 + - 1.8 + - tip diff --git a/vendor/github.com/spacemonkeygo/spacelog/LICENSE b/vendor/github.com/spacemonkeygo/spacelog/LICENSE new file mode 100644 index 00000000..37ec93a1 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/spacemonkeygo/spacelog/README.md b/vendor/github.com/spacemonkeygo/spacelog/README.md new file mode 100644 index 00000000..28033f68 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/README.md @@ -0,0 +1,19 @@ +# spacelog [![Build Status](https://api.travis-ci.org/spacemonkeygo/spacelog.svg?branch=master)](https://travis-ci.org/spacemonkeygo/spacelog) + +Please see http://godoc.org/github.com/spacemonkeygo/spacelog for info + +### License + +Copyright (C) 2014 Space Monkey, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture.go b/vendor/github.com/spacemonkeygo/spacelog/capture.go new file mode 100644 index 00000000..d7ea1ca3 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture.go @@ -0,0 +1,67 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "fmt" + "os" + "os/exec" +) + +// CaptureOutputToFile opens a filehandle using the given path, then calls +// CaptureOutputToFd on the associated filehandle. +func CaptureOutputToFile(path string) error { + fh, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return err + } + defer fh.Close() + return CaptureOutputToFd(int(fh.Fd())) +} + +// CaptureOutputToProcess starts a process and using CaptureOutputToFd, +// redirects stdout and stderr to the subprocess' stdin. +// CaptureOutputToProcess expects the subcommand to last the lifetime of the +// process, and if the subprocess dies, will panic. +func CaptureOutputToProcess(command string, args ...string) error { + cmd := exec.Command(command, args...) + out, err := cmd.StdinPipe() + if err != nil { + return err + } + defer out.Close() + type fder interface { + Fd() uintptr + } + out_fder, ok := out.(fder) + if !ok { + return fmt.Errorf("unable to get underlying pipe") + } + err = CaptureOutputToFd(int(out_fder.Fd())) + if err != nil { + return err + } + err = cmd.Start() + if err != nil { + return err + } + go func() { + err := cmd.Wait() + if err != nil { + panic(fmt.Errorf("captured output process died! %s", err)) + } + }() + return nil +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture_ae.go b/vendor/github.com/spacemonkeygo/spacelog/capture_ae.go new file mode 100644 index 00000000..f759b6f1 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture_ae.go @@ -0,0 +1,25 @@ +// Copyright (C) 2016 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build appengine + +package spacelog + +import ( + "fmt" +) + +func CaptureOutputToFd(fd int) error { + return fmt.Errorf("CaptureOutputToFd not supported on App Engine") +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture_linux.go b/vendor/github.com/spacemonkeygo/spacelog/capture_linux.go new file mode 100644 index 00000000..34a9c089 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture_linux.go @@ -0,0 +1,35 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !appengine + +package spacelog + +import ( + "syscall" +) + +// CaptureOutputToFd redirects the current process' stdout and stderr file +// descriptors to the given file descriptor, using the dup3 syscall. +func CaptureOutputToFd(fd int) error { + err := syscall.Dup3(fd, syscall.Stdout, 0) + if err != nil { + return err + } + err = syscall.Dup3(fd, syscall.Stderr, 0) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture_other.go b/vendor/github.com/spacemonkeygo/spacelog/capture_other.go new file mode 100644 index 00000000..6c65051a --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture_other.go @@ -0,0 +1,38 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows +// +build !linux +// +build !appengine +// +build !solaris + +package spacelog + +import ( + "syscall" +) + +// CaptureOutputToFd redirects the current process' stdout and stderr file +// descriptors to the given file descriptor, using the dup2 syscall. +func CaptureOutputToFd(fd int) error { + err := syscall.Dup2(fd, syscall.Stdout) + if err != nil { + return err + } + err = syscall.Dup2(fd, syscall.Stderr) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture_solaris.go b/vendor/github.com/spacemonkeygo/spacelog/capture_solaris.go new file mode 100644 index 00000000..d77e4f2d --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture_solaris.go @@ -0,0 +1,33 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "golang.org/x/sys/unix" +) + +// CaptureOutputToFd redirects the current process' stdout and stderr file +// descriptors to the given file descriptor, using the dup2 syscall. +func CaptureOutputToFd(fd int) error { + err := unix.Dup2(fd, unix.Stdout) + if err != nil { + return err + } + err = unix.Dup2(fd, unix.Stderr) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/capture_windows.go b/vendor/github.com/spacemonkeygo/spacelog/capture_windows.go new file mode 100644 index 00000000..e9f061dc --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/capture_windows.go @@ -0,0 +1,23 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "fmt" +) + +func CaptureOutputToFd(fd int) error { + return fmt.Errorf("CaptureOutputToFd not supported on Windows") +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/collection.go b/vendor/github.com/spacemonkeygo/spacelog/collection.go new file mode 100644 index 00000000..8231b4a5 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/collection.go @@ -0,0 +1,271 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "regexp" + "runtime" + "strings" + "sync" + "text/template" +) + +var ( + // If set, these prefixes will be stripped out of automatic logger names. + IgnoredPrefixes []string + + badChars = regexp.MustCompile("[^a-zA-Z0-9_.-]") + slashes = regexp.MustCompile("[/]") +) + +func callerName() string { + pc, _, _, ok := runtime.Caller(2) + if !ok { + return "unknown.unknown" + } + f := runtime.FuncForPC(pc) + if f == nil { + return "unknown.unknown" + } + name := f.Name() + for _, prefix := range IgnoredPrefixes { + name = strings.TrimPrefix(name, prefix) + } + return badChars.ReplaceAllLiteralString( + slashes.ReplaceAllLiteralString(name, "."), "_") +} + +// LoggerCollections contain all of the loggers a program might use. Typically +// a codebase will just use the default logger collection. +type LoggerCollection struct { + mtx sync.Mutex + loggers map[string]*Logger + level LogLevel + handler Handler +} + +// NewLoggerCollection creates a new logger collection. It's unlikely you will +// ever practically need this method. Use the DefaultLoggerCollection instead. +func NewLoggerCollection() *LoggerCollection { + return &LoggerCollection{ + loggers: make(map[string]*Logger), + level: DefaultLevel, + handler: defaultHandler} +} + +// GetLogger returns a new Logger with a name automatically generated using +// the callstack. If you want to avoid automatic name generation check out +// GetLoggerNamed +func (c *LoggerCollection) GetLogger() *Logger { + return c.GetLoggerNamed(callerName()) +} + +func (c *LoggerCollection) getLogger(name string, level LogLevel, + handler Handler) *Logger { + c.mtx.Lock() + defer c.mtx.Unlock() + + logger, exists := c.loggers[name] + if !exists { + logger = &Logger{level: level, + collection: c, + name: name, + handler: handler} + c.loggers[name] = logger + } + return logger +} + +// ConfigureLoggers configures loggers according to the given string +// specification, which specifies a set of loggers and their associated +// logging levels. Loggers are semicolon-separated; each +// configuration is specified as =. White space outside of +// logger names and levels is ignored. The default level is specified +// with the name "DEFAULT". +// +// An example specification: +// `DEFAULT=ERROR; foo.bar=WARNING` +func (c *LoggerCollection) ConfigureLoggers(specification string) error { + confs := strings.Split(strings.TrimSpace(specification), ";") + for i := range confs { + conf := strings.SplitN(confs[i], "=", 2) + levelstr := strings.TrimSpace(conf[1]) + name := strings.TrimSpace(conf[0]) + level, err := LevelFromString(levelstr) + if err != nil { + return err + } + if name == "DEFAULT" { + c.SetLevel(nil, level) + continue + } + logger := c.GetLoggerNamed(name) + logger.setLevel(level) + } + return nil +} + +// GetLoggerNamed returns a new Logger with the provided name. GetLogger is +// more frequently used. +func (c *LoggerCollection) GetLoggerNamed(name string) *Logger { + c.mtx.Lock() + defer c.mtx.Unlock() + + logger, exists := c.loggers[name] + if !exists { + logger = &Logger{level: c.level, + collection: c, + name: name, + handler: c.handler} + c.loggers[name] = logger + } + return logger +} + +// SetLevel will set the current log level for all loggers with names that +// match a provided regular expression. If the regular expression is nil, then +// all loggers match. +func (c *LoggerCollection) SetLevel(re *regexp.Regexp, level LogLevel) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.level = level + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.setLevel(level) + } + } +} + +// SetHandler will set the current log handler for all loggers with names that +// match a provided regular expression. If the regular expression is nil, then +// all loggers match. +func (c *LoggerCollection) SetHandler(re *regexp.Regexp, handler Handler) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler = handler + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.setHandler(handler) + } + } +} + +// SetTextTemplate will set the current text template for all loggers with +// names that match a provided regular expression. If the regular expression +// is nil, then all loggers match. Note that not every handler is guaranteed +// to support text templates and a text template will only apply to +// text-oriented and unstructured handlers. +func (c *LoggerCollection) SetTextTemplate(re *regexp.Regexp, + t *template.Template) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler.SetTextTemplate(t) + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.getHandler().SetTextTemplate(t) + } + } +} + +// SetTextOutput will set the current output interface for all loggers with +// names that match a provided regular expression. If the regular expression +// is nil, then all loggers match. Note that not every handler is guaranteed +// to support text output and a text output interface will only apply to +// text-oriented and unstructured handlers. +func (c *LoggerCollection) SetTextOutput(re *regexp.Regexp, + output TextOutput) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler.SetTextOutput(output) + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.getHandler().SetTextOutput(output) + } + } +} + +var ( + // It's unlikely you'll need to use this directly + DefaultLoggerCollection = NewLoggerCollection() +) + +// GetLogger returns an automatically-named logger on the default logger +// collection. +func GetLogger() *Logger { + return DefaultLoggerCollection.GetLoggerNamed(callerName()) +} + +// GetLoggerNamed returns a new Logger with the provided name on the default +// logger collection. GetLogger is more frequently used. +func GetLoggerNamed(name string) *Logger { + return DefaultLoggerCollection.GetLoggerNamed(name) +} + +// ConfigureLoggers configures loggers according to the given string +// specification, which specifies a set of loggers and their associated +// logging levels. Loggers are colon- or semicolon-separated; each +// configuration is specified as =. White space outside of +// logger names and levels is ignored. The DEFAULT module is specified +// with the name "DEFAULT". +// +// An example specification: +// `DEFAULT=ERROR; foo.bar=WARNING` +func ConfigureLoggers(specification string) error { + return DefaultLoggerCollection.ConfigureLoggers(specification) +} + +// SetLevel will set the current log level for all loggers on the default +// collection with names that match a provided regular expression. If the +// regular expression is nil, then all loggers match. +func SetLevel(re *regexp.Regexp, level LogLevel) { + DefaultLoggerCollection.SetLevel(re, level) +} + +// SetHandler will set the current log handler for all loggers on the default +// collection with names that match a provided regular expression. If the +// regular expression is nil, then all loggers match. +func SetHandler(re *regexp.Regexp, handler Handler) { + DefaultLoggerCollection.SetHandler(re, handler) +} + +// SetTextTemplate will set the current text template for all loggers on the +// default collection with names that match a provided regular expression. If +// the regular expression is nil, then all loggers match. Note that not every +// handler is guaranteed to support text templates and a text template will +// only apply to text-oriented and unstructured handlers. +func SetTextTemplate(re *regexp.Regexp, t *template.Template) { + DefaultLoggerCollection.SetTextTemplate(re, t) +} + +// SetTextOutput will set the current output interface for all loggers on the +// default collection with names that match a provided regular expression. If +// the regular expression is nil, then all loggers match. Note that not every +// handler is guaranteed to support text output and a text output interface +// will only apply to text-oriented and unstructured handlers. +func SetTextOutput(re *regexp.Regexp, output TextOutput) { + DefaultLoggerCollection.SetTextOutput(re, output) +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/convenience.go b/vendor/github.com/spacemonkeygo/spacelog/convenience.go new file mode 100644 index 00000000..b3056329 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/convenience.go @@ -0,0 +1,296 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "fmt" + "io" +) + +// Trace logs a collection of values if the logger's level is trace or even +// more permissive. +func (l *Logger) Trace(v ...interface{}) { + if l.getLevel() <= Trace { + l.getHandler().Log(l.name, Trace, fmt.Sprint(v...), 1) + } +} + +// Tracef logs a format string with values if the logger's level is trace or +// even more permissive. +func (l *Logger) Tracef(format string, v ...interface{}) { + if l.getLevel() <= Trace { + l.getHandler().Log(l.name, Trace, fmt.Sprintf(format, v...), 1) + } +} + +// Tracee logs an error value if the error is not nil and the logger's level +// is trace or even more permissive. +func (l *Logger) Tracee(err error) { + if l.getLevel() <= Trace && err != nil { + l.getHandler().Log(l.name, Trace, err.Error(), 1) + } +} + +// TraceEnabled returns true if the logger's level is trace or even more +// permissive. +func (l *Logger) TraceEnabled() bool { + return l.getLevel() <= Trace +} + +// Debug logs a collection of values if the logger's level is debug or even +// more permissive. +func (l *Logger) Debug(v ...interface{}) { + if l.getLevel() <= Debug { + l.getHandler().Log(l.name, Debug, fmt.Sprint(v...), 1) + } +} + +// Debugf logs a format string with values if the logger's level is debug or +// even more permissive. +func (l *Logger) Debugf(format string, v ...interface{}) { + if l.getLevel() <= Debug { + l.getHandler().Log(l.name, Debug, fmt.Sprintf(format, v...), 1) + } +} + +// Debuge logs an error value if the error is not nil and the logger's level +// is debug or even more permissive. +func (l *Logger) Debuge(err error) { + if l.getLevel() <= Debug && err != nil { + l.getHandler().Log(l.name, Debug, err.Error(), 1) + } +} + +// DebugEnabled returns true if the logger's level is debug or even more +// permissive. +func (l *Logger) DebugEnabled() bool { + return l.getLevel() <= Debug +} + +// Info logs a collection of values if the logger's level is info or even +// more permissive. +func (l *Logger) Info(v ...interface{}) { + if l.getLevel() <= Info { + l.getHandler().Log(l.name, Info, fmt.Sprint(v...), 1) + } +} + +// Infof logs a format string with values if the logger's level is info or +// even more permissive. +func (l *Logger) Infof(format string, v ...interface{}) { + if l.getLevel() <= Info { + l.getHandler().Log(l.name, Info, fmt.Sprintf(format, v...), 1) + } +} + +// Infoe logs an error value if the error is not nil and the logger's level +// is info or even more permissive. +func (l *Logger) Infoe(err error) { + if l.getLevel() <= Info && err != nil { + l.getHandler().Log(l.name, Info, err.Error(), 1) + } +} + +// InfoEnabled returns true if the logger's level is info or even more +// permissive. +func (l *Logger) InfoEnabled() bool { + return l.getLevel() <= Info +} + +// Notice logs a collection of values if the logger's level is notice or even +// more permissive. +func (l *Logger) Notice(v ...interface{}) { + if l.getLevel() <= Notice { + l.getHandler().Log(l.name, Notice, fmt.Sprint(v...), 1) + } +} + +// Noticef logs a format string with values if the logger's level is notice or +// even more permissive. +func (l *Logger) Noticef(format string, v ...interface{}) { + if l.getLevel() <= Notice { + l.getHandler().Log(l.name, Notice, fmt.Sprintf(format, v...), 1) + } +} + +// Noticee logs an error value if the error is not nil and the logger's level +// is notice or even more permissive. +func (l *Logger) Noticee(err error) { + if l.getLevel() <= Notice && err != nil { + l.getHandler().Log(l.name, Notice, err.Error(), 1) + } +} + +// NoticeEnabled returns true if the logger's level is notice or even more +// permissive. +func (l *Logger) NoticeEnabled() bool { + return l.getLevel() <= Notice +} + +// Warn logs a collection of values if the logger's level is warning or even +// more permissive. +func (l *Logger) Warn(v ...interface{}) { + if l.getLevel() <= Warning { + l.getHandler().Log(l.name, Warning, fmt.Sprint(v...), 1) + } +} + +// Warnf logs a format string with values if the logger's level is warning or +// even more permissive. +func (l *Logger) Warnf(format string, v ...interface{}) { + if l.getLevel() <= Warning { + l.getHandler().Log(l.name, Warning, fmt.Sprintf(format, v...), 1) + } +} + +// Warne logs an error value if the error is not nil and the logger's level +// is warning or even more permissive. +func (l *Logger) Warne(err error) { + if l.getLevel() <= Warning && err != nil { + l.getHandler().Log(l.name, Warning, err.Error(), 1) + } +} + +// WarnEnabled returns true if the logger's level is warning or even more +// permissive. +func (l *Logger) WarnEnabled() bool { + return l.getLevel() <= Warning +} + +// Error logs a collection of values if the logger's level is error or even +// more permissive. +func (l *Logger) Error(v ...interface{}) { + if l.getLevel() <= Error { + l.getHandler().Log(l.name, Error, fmt.Sprint(v...), 1) + } +} + +// Errorf logs a format string with values if the logger's level is error or +// even more permissive. +func (l *Logger) Errorf(format string, v ...interface{}) { + if l.getLevel() <= Error { + l.getHandler().Log(l.name, Error, fmt.Sprintf(format, v...), 1) + } +} + +// Errore logs an error value if the error is not nil and the logger's level +// is error or even more permissive. +func (l *Logger) Errore(err error) { + if l.getLevel() <= Error && err != nil { + l.getHandler().Log(l.name, Error, err.Error(), 1) + } +} + +// ErrorEnabled returns true if the logger's level is error or even more +// permissive. +func (l *Logger) ErrorEnabled() bool { + return l.getLevel() <= Error +} + +// Crit logs a collection of values if the logger's level is critical or even +// more permissive. +func (l *Logger) Crit(v ...interface{}) { + if l.getLevel() <= Critical { + l.getHandler().Log(l.name, Critical, fmt.Sprint(v...), 1) + } +} + +// Critf logs a format string with values if the logger's level is critical or +// even more permissive. +func (l *Logger) Critf(format string, v ...interface{}) { + if l.getLevel() <= Critical { + l.getHandler().Log(l.name, Critical, fmt.Sprintf(format, v...), 1) + } +} + +// Crite logs an error value if the error is not nil and the logger's level +// is critical or even more permissive. +func (l *Logger) Crite(err error) { + if l.getLevel() <= Critical && err != nil { + l.getHandler().Log(l.name, Critical, err.Error(), 1) + } +} + +// CritEnabled returns true if the logger's level is critical or even more +// permissive. +func (l *Logger) CritEnabled() bool { + return l.getLevel() <= Critical +} + +// Log logs a collection of values if the logger's level is the provided level +// or even more permissive. +func (l *Logger) Log(level LogLevel, v ...interface{}) { + if l.getLevel() <= level { + l.getHandler().Log(l.name, level, fmt.Sprint(v...), 1) + } +} + +// Logf logs a format string with values if the logger's level is the provided +// level or even more permissive. +func (l *Logger) Logf(level LogLevel, format string, v ...interface{}) { + if l.getLevel() <= level { + l.getHandler().Log(l.name, level, fmt.Sprintf(format, v...), 1) + } +} + +// Loge logs an error value if the error is not nil and the logger's level +// is the provided level or even more permissive. +func (l *Logger) Loge(level LogLevel, err error) { + if l.getLevel() <= level && err != nil { + l.getHandler().Log(l.name, level, err.Error(), 1) + } +} + +// LevelEnabled returns true if the logger's level is the provided level or +// even more permissive. +func (l *Logger) LevelEnabled(level LogLevel) bool { + return l.getLevel() <= level +} + +type writer struct { + l *Logger + level LogLevel +} + +func (w *writer) Write(data []byte) (int, error) { + if w.l.getLevel() <= w.level { + w.l.getHandler().Log(w.l.name, w.level, string(data), 1) + } + return len(data), nil +} + +// Writer returns an io.Writer that writes messages at the given log level. +func (l *Logger) Writer(level LogLevel) io.Writer { + return &writer{l: l, level: level} +} + +type writerNoCaller struct { + l *Logger + level LogLevel +} + +func (w *writerNoCaller) Write(data []byte) (int, error) { + if w.l.getLevel() <= w.level { + w.l.getHandler().Log(w.l.name, w.level, string(data), -1) + } + return len(data), nil +} + +// WriterWithoutCaller returns an io.Writer that writes messages at the given +// log level, but does not attempt to collect the Write caller, and provides +// no caller information to the log event. +func (l *Logger) WriterWithoutCaller(level LogLevel) io.Writer { + return &writerNoCaller{l: l, level: level} +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/doc.go b/vendor/github.com/spacemonkeygo/spacelog/doc.go new file mode 100644 index 00000000..28c25b4d --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/doc.go @@ -0,0 +1,39 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* +Package spacelog is a collection of interface lego bricks designed to help you +build a flexible logging system. + +spacelog is loosely inspired by the Python logging library. + +The basic interaction is between a Logger and a Handler. A Logger is +what the programmer typically interacts with for creating log messages. A +Logger will be at a given log level, and if log messages can clear that +specific logger's log level filter, they will be passed off to the Handler. + +Loggers are instantiated from GetLogger and GetLoggerNamed. + +A Handler is a very generic interface for handling log events. You can provide +your own Handler for doing structured JSON output or colorized output or +countless other things. + +Provided are a simple TextHandler with a variety of log event templates and +TextOutput sinks, such as io.Writer, Syslog, and so forth. + +Make sure to see the source of the setup subpackage for an example of easy and +configurable logging setup at process start: + http://godoc.org/github.com/spacemonkeygo/spacelog/setup +*/ +package spacelog diff --git a/vendor/github.com/spacemonkeygo/spacelog/event.go b/vendor/github.com/spacemonkeygo/spacelog/event.go new file mode 100644 index 00000000..da863cbf --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/event.go @@ -0,0 +1,75 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "path/filepath" + "strings" + "time" +) + +// TermColors is a type that knows how to output terminal colors and formatting +type TermColors struct{} + +// LogEvent is a type made by the default text handler for feeding to log +// templates. It has as much contextual data about the log event as possible. +type LogEvent struct { + LoggerName string + Level LogLevel + Message string + Filepath string + Line int + Timestamp time.Time + + TermColors +} + +// Reset resets the color palette for terminals that support color +func (TermColors) Reset() string { return "\x1b[0m" } +func (TermColors) Bold() string { return "\x1b[1m" } +func (TermColors) Underline() string { return "\x1b[4m" } +func (TermColors) Black() string { return "\x1b[30m" } +func (TermColors) Red() string { return "\x1b[31m" } +func (TermColors) Green() string { return "\x1b[32m" } +func (TermColors) Yellow() string { return "\x1b[33m" } +func (TermColors) Blue() string { return "\x1b[34m" } +func (TermColors) Magenta() string { return "\x1b[35m" } +func (TermColors) Cyan() string { return "\x1b[36m" } +func (TermColors) White() string { return "\x1b[37m" } + +func (l *LogEvent) Filename() string { + if l.Filepath == "" { + return "" + } + return filepath.Base(l.Filepath) +} + +func (l *LogEvent) Time() string { + return l.Timestamp.Format("15:04:05") +} + +func (l *LogEvent) Date() string { + return l.Timestamp.Format("2006/01/02") +} + +// LevelJustified returns the log level in string form justified so that all +// log levels take the same text width. +func (l *LogEvent) LevelJustified() (rv string) { + rv = l.Level.String() + if len(rv) < 5 { + rv += strings.Repeat(" ", 5-len(rv)) + } + return rv +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/handler.go b/vendor/github.com/spacemonkeygo/spacelog/handler.go new file mode 100644 index 00000000..e3db0865 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/handler.go @@ -0,0 +1,53 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "text/template" +) + +// Handler is an interface that knows how to process log events. This is the +// basic interface type for building a logging system. If you want to route +// structured log data somewhere, you would implement this interface. +type Handler interface { + // Log is called for every message. if calldepth is negative, caller + // information is missing + Log(logger_name string, level LogLevel, msg string, calldepth int) + + // These two calls are expected to be no-ops on non-text-output handlers + SetTextTemplate(t *template.Template) + SetTextOutput(output TextOutput) +} + +// HandlerFunc is a type to make implementation of the Handler interface easier +type HandlerFunc func(logger_name string, level LogLevel, msg string, + calldepth int) + +// Log simply calls f(logger_name, level, msg, calldepth) +func (f HandlerFunc) Log(logger_name string, level LogLevel, msg string, + calldepth int) { + f(logger_name, level, msg, calldepth) +} + +// SetTextTemplate is a no-op +func (HandlerFunc) SetTextTemplate(t *template.Template) {} + +// SetTextOutput is a no-op +func (HandlerFunc) SetTextOutput(output TextOutput) {} + +var ( + defaultHandler = NewTextHandler(StdlibTemplate, + &StdlibOutput{}) +) diff --git a/vendor/github.com/spacemonkeygo/spacelog/level.go b/vendor/github.com/spacemonkeygo/spacelog/level.go new file mode 100644 index 00000000..bf507075 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/level.go @@ -0,0 +1,136 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "fmt" + "strconv" + "strings" +) + +type LogLevel int32 + +const ( + Trace LogLevel = 5 + Debug LogLevel = 10 + Info LogLevel = 20 + Notice LogLevel = 30 + Warning LogLevel = 40 + Error LogLevel = 50 + Critical LogLevel = 60 + // syslog has Alert + // syslog has Emerg + + DefaultLevel = Notice +) + +// String returns the log level name in short form +func (l LogLevel) String() string { + switch l.Match() { + case Critical: + return "CRIT" + case Error: + return "ERR" + case Warning: + return "WARN" + case Notice: + return "NOTE" + case Info: + return "INFO" + case Debug: + return "DEBUG" + case Trace: + return "TRACE" + default: + return "UNSET" + } +} + +// String returns the log level name in long human readable form +func (l LogLevel) Name() string { + switch l.Match() { + case Critical: + return "critical" + case Error: + return "error" + case Warning: + return "warning" + case Notice: + return "notice" + case Info: + return "info" + case Debug: + return "debug" + case Trace: + return "trace" + default: + return "unset" + } +} + +// Match returns the greatest named log level that is less than or equal to +// the receiver log level. For example, if the log level is 43, Match() will +// return 40 (Warning) +func (l LogLevel) Match() LogLevel { + if l >= Critical { + return Critical + } + if l >= Error { + return Error + } + if l >= Warning { + return Warning + } + if l >= Notice { + return Notice + } + if l >= Info { + return Info + } + if l >= Debug { + return Debug + } + if l >= Trace { + return Trace + } + return 0 +} + +// LevelFromString will convert a named log level to its corresponding value +// type, or error if both the name was unknown and an integer value was unable +// to be parsed. +func LevelFromString(str string) (LogLevel, error) { + switch strings.ToLower(str) { + case "crit", "critical": + return Critical, nil + case "err", "error": + return Error, nil + case "warn", "warning": + return Warning, nil + case "note", "notice": + return Notice, nil + case "info": + return Info, nil + case "debug": + return Debug, nil + case "trace": + return Trace, nil + } + val, err := strconv.ParseInt(str, 10, 32) + if err == nil { + return LogLevel(val), nil + } + return 0, fmt.Errorf("Invalid log level: %s", str) +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/logger.go b/vendor/github.com/spacemonkeygo/spacelog/logger.go new file mode 100644 index 00000000..ae1734b2 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/logger.go @@ -0,0 +1,61 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "sync" + "sync/atomic" +) + +// Logger is the basic type that allows for logging. A logger has an associated +// name, given to it during construction, either through a logger collection, +// GetLogger, GetLoggerNamed, or another Logger's Scope method. A logger also +// has an associated level and handler, typically configured through the logger +// collection to which it belongs. +type Logger struct { + level LogLevel + name string + collection *LoggerCollection + + handler_mtx sync.RWMutex + handler Handler +} + +// Scope returns a new Logger with the same level and handler, using the +// receiver Logger's name as a prefix. +func (l *Logger) Scope(name string) *Logger { + return l.collection.getLogger(l.name+"."+name, l.getLevel(), + l.getHandler()) +} + +func (l *Logger) setLevel(level LogLevel) { + atomic.StoreInt32((*int32)(&l.level), int32(level)) +} + +func (l *Logger) getLevel() LogLevel { + return LogLevel(atomic.LoadInt32((*int32)(&l.level))) +} + +func (l *Logger) setHandler(handler Handler) { + l.handler_mtx.Lock() + defer l.handler_mtx.Unlock() + l.handler = handler +} + +func (l *Logger) getHandler() Handler { + l.handler_mtx.RLock() + defer l.handler_mtx.RUnlock() + return l.handler +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/output.go b/vendor/github.com/spacemonkeygo/spacelog/output.go new file mode 100644 index 00000000..8751268f --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/output.go @@ -0,0 +1,178 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "bytes" + "fmt" + "io" + "log" + "os" + "sync" +) + +type TextOutput interface { + Output(LogLevel, []byte) +} + +// WriterOutput is an io.Writer wrapper that matches the TextOutput interface +type WriterOutput struct { + w io.Writer +} + +// NewWriterOutput returns a TextOutput that writes messages to an io.Writer +func NewWriterOutput(w io.Writer) *WriterOutput { + return &WriterOutput{w: w} +} + +func (o *WriterOutput) Output(_ LogLevel, message []byte) { + o.w.Write(append(bytes.TrimRight(message, "\r\n"), platformNewline...)) +} + +// StdlibOutput is a TextOutput that simply writes to the default Go stdlib +// logging system. It is the default. If you configure the Go stdlib to write +// to spacelog, make sure to provide a new TextOutput to your logging +// collection +type StdlibOutput struct{} + +func (*StdlibOutput) Output(_ LogLevel, message []byte) { + log.Print(string(message)) +} + +type bufferMsg struct { + level LogLevel + message []byte +} + +// BufferedOutput uses a channel to synchronize writes to a wrapped TextOutput +// and allows for buffering a limited amount of log events. +type BufferedOutput struct { + o TextOutput + c chan bufferMsg + running sync.Mutex + close_once sync.Once +} + +// NewBufferedOutput returns a BufferedOutput wrapping output with a buffer +// size of buffer. +func NewBufferedOutput(output TextOutput, buffer int) *BufferedOutput { + if buffer < 0 { + buffer = 0 + } + b := &BufferedOutput{ + o: output, + c: make(chan bufferMsg, buffer)} + go b.process() + return b +} + +// Close shuts down the BufferedOutput's processing +func (b *BufferedOutput) Close() { + b.close_once.Do(func() { + close(b.c) + }) + b.running.Lock() + b.running.Unlock() +} + +func (b *BufferedOutput) Output(level LogLevel, message []byte) { + b.c <- bufferMsg{level: level, message: message} +} + +func (b *BufferedOutput) process() { + b.running.Lock() + defer b.running.Unlock() + for { + msg, open := <-b.c + if !open { + break + } + b.o.Output(msg.level, msg.message) + } +} + +// A TextOutput object that also implements HupHandlingTextOutput may have its +// OnHup() method called when an administrative signal is sent to this process. +type HupHandlingTextOutput interface { + TextOutput + OnHup() +} + +// FileWriterOutput is like WriterOutput with a plain file handle, but it +// knows how to reopen the file (or try to reopen it) if it hasn't been able +// to open the file previously, or if an appropriate signal has been received. +type FileWriterOutput struct { + *WriterOutput + path string +} + +// Creates a new FileWriterOutput object. This is the only case where an +// error opening the file will be reported to the caller; if we try to +// reopen it later and the reopen fails, we'll just keep trying until it +// works. +func NewFileWriterOutput(path string) (*FileWriterOutput, error) { + fo := &FileWriterOutput{path: path} + fh, err := fo.openFile() + if err != nil { + return nil, err + } + fo.WriterOutput = NewWriterOutput(fh) + return fo, nil +} + +// Try to open the file with the path associated with this object. +func (fo *FileWriterOutput) openFile() (*os.File, error) { + return os.OpenFile(fo.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) +} + +// Try to communicate a message without using our log file. In all likelihood, +// stderr is closed or redirected to /dev/null, but at least we can try +// writing there. In the very worst case, if an admin attaches a ptrace to +// this process, it will be more clear what the problem is. +func (fo *FileWriterOutput) fallbackLog(tmpl string, args ...interface{}) { + fmt.Fprintf(os.Stderr, tmpl, args...) +} + +// Output a log line by writing it to the file. If the file has been +// released, try to open it again. If that fails, cry for a little +// while, then throw away the message and carry on. +func (fo *FileWriterOutput) Output(ll LogLevel, message []byte) { + if fo.WriterOutput == nil { + fh, err := fo.openFile() + if err != nil { + fo.fallbackLog("Could not open %#v: %s", fo.path, err) + return + } + fo.WriterOutput = NewWriterOutput(fh) + } + fo.WriterOutput.Output(ll, message) +} + +// Throw away any references/handles to the output file. This probably +// means the admin wants to rotate the file out and have this process +// open a new one. Close the underlying io.Writer if that is a thing +// that it knows how to do. +func (fo *FileWriterOutput) OnHup() { + if fo.WriterOutput != nil { + wc, ok := fo.WriterOutput.w.(io.Closer) + if ok { + err := wc.Close() + if err != nil { + fo.fallbackLog("Closing %#v failed: %s", fo.path, err) + } + } + fo.WriterOutput = nil + } +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/output_other.go b/vendor/github.com/spacemonkeygo/spacelog/output_other.go new file mode 100644 index 00000000..2be240a1 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/output_other.go @@ -0,0 +1,19 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package spacelog + +var platformNewline = []byte("\n") diff --git a/vendor/github.com/spacemonkeygo/spacelog/output_windows.go b/vendor/github.com/spacemonkeygo/spacelog/output_windows.go new file mode 100644 index 00000000..58b71dab --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/output_windows.go @@ -0,0 +1,17 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +var platformNewline = []byte("\r\n") diff --git a/vendor/github.com/spacemonkeygo/spacelog/setup.go b/vendor/github.com/spacemonkeygo/spacelog/setup.go new file mode 100644 index 00000000..2c1cbcee --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/setup.go @@ -0,0 +1,189 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "bytes" + "fmt" + "log" + "math" + "os" + "os/signal" + "regexp" + "strings" + "text/template" +) + +// SetupConfig is a configuration struct meant to be used with +// github.com/spacemonkeygo/flagfile/utils.Setup +// but can be used independently. +type SetupConfig struct { + Output string `default:"stderr" usage:"log output. can be stdout, stderr, syslog, or a path"` + Level string `default:"" usage:"base logger level"` + Filter string `default:"" usage:"sets loggers matching this regular expression to the lowest level"` + Format string `default:"" usage:"format string to use"` + Stdlevel string `default:"warn" usage:"logger level for stdlib log integration"` + Subproc string `default:"" usage:"process to run for stdout/stderr-captured logging. The command is first processed as a Go template that supports {{.Facility}}, {{.Level}}, and {{.Name}} fields, and then passed to sh. If set, will redirect stdout and stderr to the given process. A good default is 'setsid logger --priority {{.Facility}}.{{.Level}} --tag {{.Name}}'"` + Buffer int `default:"0" usage:"the number of messages to buffer. 0 for no buffer"` + // Facility defaults to syslog.LOG_USER (which is 8) + Facility int `default:"8" usage:"the syslog facility to use if syslog output is configured"` + HupRotate bool `default:"false" usage:"if true, sending a HUP signal will reopen log files"` + Config string `default:"" usage:"a semicolon separated list of logger=level; sets each log to the corresponding level"` +} + +var ( + stdlog = GetLoggerNamed("stdlog") + funcmap = template.FuncMap{"ColorizeLevel": ColorizeLevel} +) + +// SetFormatMethod adds functions to the template function map, such that +// command-line and Setup provided templates can call methods added to the map +// via this method. The map comes prepopulated with ColorizeLevel, but can be +// overridden. SetFormatMethod should be called (if at all) before one of +// this package's Setup methods. +func SetFormatMethod(name string, fn interface{}) { + funcmap[name] = fn +} + +// MustSetup is the same as Setup, but panics instead of returning an error +func MustSetup(procname string, config SetupConfig) { + err := Setup(procname, config) + if err != nil { + panic(err) + } +} + +type subprocInfo struct { + Facility string + Level string + Name string +} + +// Setup takes a given procname and sets spacelog up with the given +// configuration. Setup supports: +// * capturing stdout and stderr to a subprocess +// * configuring the default level +// * configuring log filters (enabling only some loggers) +// * configuring the logging template +// * configuring the output (a file, syslog, stdout, stderr) +// * configuring log event buffering +// * capturing all standard library logging with configurable log level +// It is expected that this method will be called once at process start. +func Setup(procname string, config SetupConfig) error { + if config.Subproc != "" { + t, err := template.New("subproc").Parse(config.Subproc) + if err != nil { + return err + } + var buf bytes.Buffer + err = t.Execute(&buf, &subprocInfo{ + Facility: fmt.Sprintf("%d", config.Facility), + Level: fmt.Sprintf("%d", 2), // syslog.LOG_CRIT + Name: procname}) + if err != nil { + return err + } + err = CaptureOutputToProcess("sh", "-c", string(buf.Bytes())) + if err != nil { + return err + } + } + if config.Config != "" { + err := ConfigureLoggers(config.Config) + if err != nil { + return err + } + } + if config.Level != "" { + level_val, err := LevelFromString(config.Level) + if err != nil { + return err + } + if level_val != DefaultLevel { + SetLevel(nil, level_val) + } + } + if config.Filter != "" { + re, err := regexp.Compile(config.Filter) + if err != nil { + return err + } + SetLevel(re, LogLevel(math.MinInt32)) + } + var t *template.Template + if config.Format != "" { + var err error + t, err = template.New("user").Funcs(funcmap).Parse(config.Format) + if err != nil { + return err + } + } + var textout TextOutput + switch strings.ToLower(config.Output) { + case "syslog": + w, err := NewSyslogOutput(SyslogPriority(config.Facility), procname) + if err != nil { + return err + } + if t == nil { + t = SyslogTemplate + } + textout = w + case "stdout": + if t == nil { + t = DefaultTemplate + } + textout = NewWriterOutput(os.Stdout) + case "stderr", "": + if t == nil { + t = DefaultTemplate + } + textout = NewWriterOutput(os.Stderr) + default: + if t == nil { + t = StandardTemplate + } + var err error + textout, err = NewFileWriterOutput(config.Output) + if err != nil { + return err + } + } + if config.HupRotate { + if hh, ok := textout.(HupHandlingTextOutput); ok { + sigchan := make(chan os.Signal) + signal.Notify(sigchan, sigHUP) + go func() { + for _ = range sigchan { + hh.OnHup() + } + }() + } + } + if config.Buffer > 0 { + textout = NewBufferedOutput(textout, config.Buffer) + } + SetHandler(nil, NewTextHandler(t, textout)) + log.SetFlags(log.Lshortfile) + if config.Stdlevel == "" { + config.Stdlevel = "warn" + } + stdlog_level_val, err := LevelFromString(config.Stdlevel) + if err != nil { + return err + } + log.SetOutput(stdlog.WriterWithoutCaller(stdlog_level_val)) + return nil +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/sighup_appengine.go b/vendor/github.com/spacemonkeygo/spacelog/sighup_appengine.go new file mode 100644 index 00000000..c12ed961 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/sighup_appengine.go @@ -0,0 +1,37 @@ +// Copyright (C) 2017 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build appengine + +package spacelog + +import ( + "strconv" +) + +const ( + sigHUP = syscallSignal(0x1) +) + +type syscallSignal int + +func (s syscallSignal) Signal() {} + +func (s syscallSignal) String() string { + switch s { + case sigHUP: + return "hangup" + } + return "signal " + strconv.Itoa(int(s)) +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/sighup_other.go b/vendor/github.com/spacemonkeygo/spacelog/sighup_other.go new file mode 100644 index 00000000..0e033a8d --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/sighup_other.go @@ -0,0 +1,23 @@ +// Copyright (C) 2017 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !appengine + +package spacelog + +import "syscall" + +const ( + sigHUP = syscall.SIGHUP +) diff --git a/vendor/github.com/spacemonkeygo/spacelog/syslog.go b/vendor/github.com/spacemonkeygo/spacelog/syslog.go new file mode 100644 index 00000000..c2317b6c --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/syslog.go @@ -0,0 +1,65 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package spacelog + +import ( + "bytes" + "log/syslog" +) + +type SyslogPriority syslog.Priority + +// SyslogOutput is a syslog client that matches the TextOutput interface +type SyslogOutput struct { + w *syslog.Writer +} + +// NewSyslogOutput returns a TextOutput object that writes to syslog using +// the given facility and tag. The log level will be determined by the log +// event. +func NewSyslogOutput(facility SyslogPriority, tag string) ( + TextOutput, error) { + w, err := syslog.New(syslog.Priority(facility), tag) + if err != nil { + return nil, err + } + return &SyslogOutput{w: w}, nil +} + +func (o *SyslogOutput) Output(level LogLevel, message []byte) { + level = level.Match() + for _, msg := range bytes.Split(message, []byte{'\n'}) { + switch level { + case Critical: + o.w.Crit(string(msg)) + case Error: + o.w.Err(string(msg)) + case Warning: + o.w.Warning(string(msg)) + case Notice: + o.w.Notice(string(msg)) + case Info: + o.w.Info(string(msg)) + case Debug: + fallthrough + case Trace: + fallthrough + default: + o.w.Debug(string(msg)) + } + } +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/syslog_windows.go b/vendor/github.com/spacemonkeygo/spacelog/syslog_windows.go new file mode 100644 index 00000000..edba3c2a --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/syslog_windows.go @@ -0,0 +1,26 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "fmt" +) + +type SyslogPriority int + +func NewSyslogOutput(facility SyslogPriority, tag string) ( + TextOutput, error) { + return nil, fmt.Errorf("SyslogOutput not supported on Windows") +} diff --git a/vendor/github.com/spacemonkeygo/spacelog/templates.go b/vendor/github.com/spacemonkeygo/spacelog/templates.go new file mode 100644 index 00000000..959033da --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/templates.go @@ -0,0 +1,69 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "text/template" +) + +// ColorizeLevel returns a TermColor byte sequence for the appropriate color +// for the level. If you'd like to configure your own color choices, you can +// make your own template with its own function map to your own colorize +// function. +func ColorizeLevel(level LogLevel) string { + switch level.Match() { + case Critical, Error: + return TermColors{}.Red() + case Warning: + return TermColors{}.Magenta() + case Notice: + return TermColors{}.Yellow() + case Info, Debug, Trace: + return TermColors{}.Green() + } + return "" +} + +var ( + // ColorTemplate uses the default ColorizeLevel method for color choices. + ColorTemplate = template.Must(template.New("color").Funcs(template.FuncMap{ + "ColorizeLevel": ColorizeLevel}).Parse( + `{{.Blue}}{{.Date}} {{.Time}}{{.Reset}} ` + + `{{.Bold}}{{ColorizeLevel .Level}}{{.LevelJustified}}{{.Reset}} ` + + `{{.Underline}}{{.LoggerName}}{{.Reset}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}- ` + + `{{ColorizeLevel .Level}}{{.Message}}{{.Reset}}`)) + + // StandardTemplate is like ColorTemplate with no color. + StandardTemplate = template.Must(template.New("standard").Parse( + `{{.Date}} {{.Time}} ` + + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) + + // SyslogTemplate is missing the date and time as syslog adds those + // things. + SyslogTemplate = template.Must(template.New("syslog").Parse( + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) + + // StdlibTemplate is missing the date and time as the stdlib logger often + // adds those things. + StdlibTemplate = template.Must(template.New("stdlib").Parse( + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) +) diff --git a/vendor/github.com/spacemonkeygo/spacelog/templates_others.go b/vendor/github.com/spacemonkeygo/spacelog/templates_others.go new file mode 100644 index 00000000..114e2e14 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/templates_others.go @@ -0,0 +1,22 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package spacelog + +var ( + // DefaultTemplate is default template for stdout/stderr for the platform + DefaultTemplate = ColorTemplate +) diff --git a/vendor/github.com/spacemonkeygo/spacelog/templates_windows.go b/vendor/github.com/spacemonkeygo/spacelog/templates_windows.go new file mode 100644 index 00000000..512b6004 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/templates_windows.go @@ -0,0 +1,20 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +var ( + // DefaultTemplate is default template for stdout/stderr for the platform + DefaultTemplate = StandardTemplate +) diff --git a/vendor/github.com/spacemonkeygo/spacelog/text.go b/vendor/github.com/spacemonkeygo/spacelog/text.go new file mode 100644 index 00000000..8b36ce99 --- /dev/null +++ b/vendor/github.com/spacemonkeygo/spacelog/text.go @@ -0,0 +1,80 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spacelog + +import ( + "bytes" + "fmt" + "runtime" + "strings" + "sync" + "text/template" + "time" +) + +// TextHandler is the default implementation of the Handler interface. A +// TextHandler, on log events, makes LogEvent structures, passes them to the +// configured template, and then passes that output to a configured TextOutput +// interface. +type TextHandler struct { + mtx sync.RWMutex + template *template.Template + output TextOutput +} + +// NewTextHandler creates a Handler that creates LogEvents, passes them to +// the given template, and passes the result to output +func NewTextHandler(t *template.Template, output TextOutput) *TextHandler { + return &TextHandler{template: t, output: output} +} + +// Log makes a LogEvent, formats it with the configured template, then passes +// the output to configured output sink +func (h *TextHandler) Log(logger_name string, level LogLevel, msg string, + calldepth int) { + h.mtx.RLock() + output, template := h.output, h.template + h.mtx.RUnlock() + event := LogEvent{ + LoggerName: logger_name, + Level: level, + Message: strings.TrimRight(msg, "\n\r"), + Timestamp: time.Now()} + if calldepth >= 0 { + _, event.Filepath, event.Line, _ = runtime.Caller(calldepth + 1) + } + var buf bytes.Buffer + err := template.Execute(&buf, &event) + if err != nil { + output.Output(level, []byte( + fmt.Sprintf("log format template failed: %s", err))) + return + } + output.Output(level, buf.Bytes()) +} + +// SetTextTemplate changes the TextHandler's text formatting template +func (h *TextHandler) SetTextTemplate(t *template.Template) { + h.mtx.Lock() + defer h.mtx.Unlock() + h.template = t +} + +// SetTextOutput changes the TextHandler's TextOutput sink +func (h *TextHandler) SetTextOutput(output TextOutput) { + h.mtx.Lock() + defer h.mtx.Unlock() + h.output = output +} diff --git a/vendor/github.com/spaolacci/murmur3/.gitignore b/vendor/github.com/spaolacci/murmur3/.gitignore new file mode 100644 index 00000000..00268614 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/spaolacci/murmur3/.travis.yml b/vendor/github.com/spaolacci/murmur3/.travis.yml new file mode 100644 index 00000000..9bfca9c8 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.x + - master + +script: go test diff --git a/vendor/github.com/spaolacci/murmur3/LICENSE b/vendor/github.com/spaolacci/murmur3/LICENSE new file mode 100644 index 00000000..2a46fd75 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/LICENSE @@ -0,0 +1,24 @@ +Copyright 2013, Sébastien Paolacci. +All rights reserved. + +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 the library 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 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. diff --git a/vendor/github.com/spaolacci/murmur3/README.md b/vendor/github.com/spaolacci/murmur3/README.md new file mode 100644 index 00000000..e463678a --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/README.md @@ -0,0 +1,86 @@ +murmur3 +======= + +[![Build Status](https://travis-ci.org/spaolacci/murmur3.svg?branch=master)](https://travis-ci.org/spaolacci/murmur3) + +Native Go implementation of Austin Appleby's third MurmurHash revision (aka +MurmurHash3). + +Reference algorithm has been slightly hacked as to support the streaming mode +required by Go's standard [Hash interface](http://golang.org/pkg/hash/#Hash). + + +Benchmarks +---------- + +Go tip as of 2014-06-12 (i.e almost go1.3), core i7 @ 3.4 Ghz. All runs +include hasher instantiation and sequence finalization. + +
+
+Benchmark32_1        500000000     7.69 ns/op      130.00 MB/s
+Benchmark32_2        200000000     8.83 ns/op      226.42 MB/s
+Benchmark32_4        500000000     7.99 ns/op      500.39 MB/s
+Benchmark32_8        200000000     9.47 ns/op      844.69 MB/s
+Benchmark32_16       100000000     12.1 ns/op     1321.61 MB/s
+Benchmark32_32       100000000     18.3 ns/op     1743.93 MB/s
+Benchmark32_64        50000000     30.9 ns/op     2071.64 MB/s
+Benchmark32_128       50000000     57.6 ns/op     2222.96 MB/s
+Benchmark32_256       20000000      116 ns/op     2188.60 MB/s
+Benchmark32_512       10000000      226 ns/op     2260.59 MB/s
+Benchmark32_1024       5000000      452 ns/op     2263.73 MB/s
+Benchmark32_2048       2000000      891 ns/op     2296.02 MB/s
+Benchmark32_4096       1000000     1787 ns/op     2290.92 MB/s
+Benchmark32_8192        500000     3593 ns/op     2279.68 MB/s
+Benchmark128_1       100000000     26.1 ns/op       38.33 MB/s
+Benchmark128_2       100000000     29.0 ns/op       69.07 MB/s
+Benchmark128_4        50000000     29.8 ns/op      134.17 MB/s
+Benchmark128_8        50000000     31.6 ns/op      252.86 MB/s
+Benchmark128_16      100000000     26.5 ns/op      603.42 MB/s
+Benchmark128_32      100000000     28.6 ns/op     1117.15 MB/s
+Benchmark128_64       50000000     35.5 ns/op     1800.97 MB/s
+Benchmark128_128      50000000     50.9 ns/op     2515.50 MB/s
+Benchmark128_256      20000000     76.9 ns/op     3330.11 MB/s
+Benchmark128_512      20000000      135 ns/op     3769.09 MB/s
+Benchmark128_1024     10000000      250 ns/op     4094.38 MB/s
+Benchmark128_2048      5000000      477 ns/op     4290.75 MB/s
+Benchmark128_4096      2000000      940 ns/op     4353.29 MB/s
+Benchmark128_8192      1000000     1838 ns/op     4455.47 MB/s
+
+
+ + +
+
+benchmark              Go1.0 MB/s    Go1.1 MB/s  speedup    Go1.2 MB/s  speedup    Go1.3 MB/s  speedup
+Benchmark32_1               98.90        118.59    1.20x        114.79    0.97x        130.00    1.13x
+Benchmark32_2              168.04        213.31    1.27x        210.65    0.99x        226.42    1.07x
+Benchmark32_4              414.01        494.19    1.19x        490.29    0.99x        500.39    1.02x
+Benchmark32_8              662.19        836.09    1.26x        836.46    1.00x        844.69    1.01x
+Benchmark32_16             917.46       1304.62    1.42x       1297.63    0.99x       1321.61    1.02x
+Benchmark32_32            1141.93       1737.54    1.52x       1728.24    0.99x       1743.93    1.01x
+Benchmark32_64            1289.47       2039.51    1.58x       2038.20    1.00x       2071.64    1.02x
+Benchmark32_128           1299.23       2097.63    1.61x       2177.13    1.04x       2222.96    1.02x
+Benchmark32_256           1369.90       2202.34    1.61x       2213.15    1.00x       2188.60    0.99x
+Benchmark32_512           1399.56       2255.72    1.61x       2264.49    1.00x       2260.59    1.00x
+Benchmark32_1024          1410.90       2285.82    1.62x       2270.99    0.99x       2263.73    1.00x
+Benchmark32_2048          1422.14       2297.62    1.62x       2269.59    0.99x       2296.02    1.01x
+Benchmark32_4096          1420.53       2307.81    1.62x       2273.43    0.99x       2290.92    1.01x
+Benchmark32_8192          1424.79       2312.87    1.62x       2286.07    0.99x       2279.68    1.00x
+Benchmark128_1               8.32         30.15    3.62x         30.84    1.02x         38.33    1.24x
+Benchmark128_2              16.38         59.72    3.65x         59.37    0.99x         69.07    1.16x
+Benchmark128_4              32.26        112.96    3.50x        114.24    1.01x        134.17    1.17x
+Benchmark128_8              62.68        217.88    3.48x        218.18    1.00x        252.86    1.16x
+Benchmark128_16            128.47        451.57    3.51x        474.65    1.05x        603.42    1.27x
+Benchmark128_32            246.18        910.42    3.70x        871.06    0.96x       1117.15    1.28x
+Benchmark128_64            449.05       1477.64    3.29x       1449.24    0.98x       1800.97    1.24x
+Benchmark128_128           762.61       2222.42    2.91x       2217.30    1.00x       2515.50    1.13x
+Benchmark128_256          1179.92       3005.46    2.55x       2931.55    0.98x       3330.11    1.14x
+Benchmark128_512          1616.51       3590.75    2.22x       3592.08    1.00x       3769.09    1.05x
+Benchmark128_1024         1964.36       3979.67    2.03x       4034.01    1.01x       4094.38    1.01x
+Benchmark128_2048         2225.07       4156.93    1.87x       4244.17    1.02x       4290.75    1.01x
+Benchmark128_4096         2360.15       4299.09    1.82x       4392.35    1.02x       4353.29    0.99x
+Benchmark128_8192         2411.50       4356.84    1.81x       4480.68    1.03x       4455.47    0.99x
+
+
+ diff --git a/vendor/github.com/spaolacci/murmur3/murmur.go b/vendor/github.com/spaolacci/murmur3/murmur.go new file mode 100644 index 00000000..1252cf73 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/murmur.go @@ -0,0 +1,64 @@ +// Copyright 2013, Sébastien Paolacci. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package murmur3 implements Austin Appleby's non-cryptographic MurmurHash3. + + Reference implementation: + http://code.google.com/p/smhasher/wiki/MurmurHash3 + + History, characteristics and (legacy) perfs: + https://sites.google.com/site/murmurhash/ + https://sites.google.com/site/murmurhash/statistics +*/ +package murmur3 + +type bmixer interface { + bmix(p []byte) (tail []byte) + Size() (n int) + reset() +} + +type digest struct { + clen int // Digested input cumulative length. + tail []byte // 0 to Size()-1 bytes view of `buf'. + buf [16]byte // Expected (but not required) to be Size() large. + seed uint32 // Seed for initializing the hash. + bmixer +} + +func (d *digest) BlockSize() int { return 1 } + +func (d *digest) Write(p []byte) (n int, err error) { + n = len(p) + d.clen += n + + if len(d.tail) > 0 { + // Stick back pending bytes. + nfree := d.Size() - len(d.tail) // nfree ∈ [1, d.Size()-1]. + if nfree < len(p) { + // One full block can be formed. + block := append(d.tail, p[:nfree]...) + p = p[nfree:] + _ = d.bmix(block) // No tail. + } else { + // Tail's buf is large enough to prevent reallocs. + p = append(d.tail, p...) + } + } + + d.tail = d.bmix(p) + + // Keep own copy of the 0 to Size()-1 pending bytes. + nn := copy(d.buf[:], d.tail) + d.tail = d.buf[:nn] + + return n, nil +} + +func (d *digest) Reset() { + d.clen = 0 + d.tail = nil + d.bmixer.reset() +} diff --git a/vendor/github.com/spaolacci/murmur3/murmur128.go b/vendor/github.com/spaolacci/murmur3/murmur128.go new file mode 100644 index 00000000..a4b618b5 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/murmur128.go @@ -0,0 +1,203 @@ +package murmur3 + +import ( + //"encoding/binary" + "hash" + "unsafe" +) + +const ( + c1_128 = 0x87c37b91114253d5 + c2_128 = 0x4cf5ad432745937f +) + +// Make sure interfaces are correctly implemented. +var ( + _ hash.Hash = new(digest128) + _ Hash128 = new(digest128) + _ bmixer = new(digest128) +) + +// Hash128 represents a 128-bit hasher +// Hack: the standard api doesn't define any Hash128 interface. +type Hash128 interface { + hash.Hash + Sum128() (uint64, uint64) +} + +// digest128 represents a partial evaluation of a 128 bites hash. +type digest128 struct { + digest + h1 uint64 // Unfinalized running hash part 1. + h2 uint64 // Unfinalized running hash part 2. +} + +// New128 returns a 128-bit hasher +func New128() Hash128 { return New128WithSeed(0) } + +// New128WithSeed returns a 128-bit hasher set with explicit seed value +func New128WithSeed(seed uint32) Hash128 { + d := new(digest128) + d.seed = seed + d.bmixer = d + d.Reset() + return d +} + +func (d *digest128) Size() int { return 16 } + +func (d *digest128) reset() { d.h1, d.h2 = uint64(d.seed), uint64(d.seed) } + +func (d *digest128) Sum(b []byte) []byte { + h1, h2 := d.Sum128() + return append(b, + byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32), + byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1), + + byte(h2>>56), byte(h2>>48), byte(h2>>40), byte(h2>>32), + byte(h2>>24), byte(h2>>16), byte(h2>>8), byte(h2), + ) +} + +func (d *digest128) bmix(p []byte) (tail []byte) { + h1, h2 := d.h1, d.h2 + + nblocks := len(p) / 16 + for i := 0; i < nblocks; i++ { + t := (*[2]uint64)(unsafe.Pointer(&p[i*16])) + k1, k2 := t[0], t[1] + + k1 *= c1_128 + k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31) + k1 *= c2_128 + h1 ^= k1 + + h1 = (h1 << 27) | (h1 >> 37) // rotl64(h1, 27) + h1 += h2 + h1 = h1*5 + 0x52dce729 + + k2 *= c2_128 + k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33) + k2 *= c1_128 + h2 ^= k2 + + h2 = (h2 << 31) | (h2 >> 33) // rotl64(h2, 31) + h2 += h1 + h2 = h2*5 + 0x38495ab5 + } + d.h1, d.h2 = h1, h2 + return p[nblocks*d.Size():] +} + +func (d *digest128) Sum128() (h1, h2 uint64) { + + h1, h2 = d.h1, d.h2 + + var k1, k2 uint64 + switch len(d.tail) & 15 { + case 15: + k2 ^= uint64(d.tail[14]) << 48 + fallthrough + case 14: + k2 ^= uint64(d.tail[13]) << 40 + fallthrough + case 13: + k2 ^= uint64(d.tail[12]) << 32 + fallthrough + case 12: + k2 ^= uint64(d.tail[11]) << 24 + fallthrough + case 11: + k2 ^= uint64(d.tail[10]) << 16 + fallthrough + case 10: + k2 ^= uint64(d.tail[9]) << 8 + fallthrough + case 9: + k2 ^= uint64(d.tail[8]) << 0 + + k2 *= c2_128 + k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33) + k2 *= c1_128 + h2 ^= k2 + + fallthrough + + case 8: + k1 ^= uint64(d.tail[7]) << 56 + fallthrough + case 7: + k1 ^= uint64(d.tail[6]) << 48 + fallthrough + case 6: + k1 ^= uint64(d.tail[5]) << 40 + fallthrough + case 5: + k1 ^= uint64(d.tail[4]) << 32 + fallthrough + case 4: + k1 ^= uint64(d.tail[3]) << 24 + fallthrough + case 3: + k1 ^= uint64(d.tail[2]) << 16 + fallthrough + case 2: + k1 ^= uint64(d.tail[1]) << 8 + fallthrough + case 1: + k1 ^= uint64(d.tail[0]) << 0 + k1 *= c1_128 + k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31) + k1 *= c2_128 + h1 ^= k1 + } + + h1 ^= uint64(d.clen) + h2 ^= uint64(d.clen) + + h1 += h2 + h2 += h1 + + h1 = fmix64(h1) + h2 = fmix64(h2) + + h1 += h2 + h2 += h1 + + return h1, h2 +} + +func fmix64(k uint64) uint64 { + k ^= k >> 33 + k *= 0xff51afd7ed558ccd + k ^= k >> 33 + k *= 0xc4ceb9fe1a85ec53 + k ^= k >> 33 + return k +} + +/* +func rotl64(x uint64, r byte) uint64 { + return (x << r) | (x >> (64 - r)) +} +*/ + +// Sum128 returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New128() +// hasher.Write(data) +// return hasher.Sum128() +func Sum128(data []byte) (h1 uint64, h2 uint64) { return Sum128WithSeed(data, 0) } + +// Sum128WithSeed returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New128WithSeed(seed) +// hasher.Write(data) +// return hasher.Sum128() +func Sum128WithSeed(data []byte, seed uint32) (h1 uint64, h2 uint64) { + d := &digest128{h1: uint64(seed), h2: uint64(seed)} + d.seed = seed + d.tail = d.bmix(data) + d.clen = len(data) + return d.Sum128() +} diff --git a/vendor/github.com/spaolacci/murmur3/murmur32.go b/vendor/github.com/spaolacci/murmur3/murmur32.go new file mode 100644 index 00000000..e32c9951 --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/murmur32.go @@ -0,0 +1,167 @@ +package murmur3 + +// http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/Murmur3_32HashFunction.java + +import ( + "hash" + "unsafe" +) + +// Make sure interfaces are correctly implemented. +var ( + _ hash.Hash = new(digest32) + _ hash.Hash32 = new(digest32) + _ bmixer = new(digest32) +) + +const ( + c1_32 uint32 = 0xcc9e2d51 + c2_32 uint32 = 0x1b873593 +) + +// digest32 represents a partial evaluation of a 32 bites hash. +type digest32 struct { + digest + h1 uint32 // Unfinalized running hash. +} + +// New32 returns new 32-bit hasher +func New32() hash.Hash32 { return New32WithSeed(0) } + +// New32WithSeed returns new 32-bit hasher set with explicit seed value +func New32WithSeed(seed uint32) hash.Hash32 { + d := new(digest32) + d.seed = seed + d.bmixer = d + d.Reset() + return d +} + +func (d *digest32) Size() int { return 4 } + +func (d *digest32) reset() { d.h1 = d.seed } + +func (d *digest32) Sum(b []byte) []byte { + h := d.Sum32() + return append(b, byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) +} + +// Digest as many blocks as possible. +func (d *digest32) bmix(p []byte) (tail []byte) { + h1 := d.h1 + + nblocks := len(p) / 4 + for i := 0; i < nblocks; i++ { + k1 := *(*uint32)(unsafe.Pointer(&p[i*4])) + + k1 *= c1_32 + k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) + k1 *= c2_32 + + h1 ^= k1 + h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) + h1 = h1*4 + h1 + 0xe6546b64 + } + d.h1 = h1 + return p[nblocks*d.Size():] +} + +func (d *digest32) Sum32() (h1 uint32) { + + h1 = d.h1 + + var k1 uint32 + switch len(d.tail) & 3 { + case 3: + k1 ^= uint32(d.tail[2]) << 16 + fallthrough + case 2: + k1 ^= uint32(d.tail[1]) << 8 + fallthrough + case 1: + k1 ^= uint32(d.tail[0]) + k1 *= c1_32 + k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) + k1 *= c2_32 + h1 ^= k1 + } + + h1 ^= uint32(d.clen) + + h1 ^= h1 >> 16 + h1 *= 0x85ebca6b + h1 ^= h1 >> 13 + h1 *= 0xc2b2ae35 + h1 ^= h1 >> 16 + + return h1 +} + +/* +func rotl32(x uint32, r byte) uint32 { + return (x << r) | (x >> (32 - r)) +} +*/ + +// Sum32 returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New32() +// hasher.Write(data) +// return hasher.Sum32() +func Sum32(data []byte) uint32 { return Sum32WithSeed(data, 0) } + +// Sum32WithSeed returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New32WithSeed(seed) +// hasher.Write(data) +// return hasher.Sum32() +func Sum32WithSeed(data []byte, seed uint32) uint32 { + + h1 := seed + + nblocks := len(data) / 4 + var p uintptr + if len(data) > 0 { + p = uintptr(unsafe.Pointer(&data[0])) + } + p1 := p + uintptr(4*nblocks) + for ; p < p1; p += 4 { + k1 := *(*uint32)(unsafe.Pointer(p)) + + k1 *= c1_32 + k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) + k1 *= c2_32 + + h1 ^= k1 + h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) + h1 = h1*4 + h1 + 0xe6546b64 + } + + tail := data[nblocks*4:] + + var k1 uint32 + switch len(tail) & 3 { + case 3: + k1 ^= uint32(tail[2]) << 16 + fallthrough + case 2: + k1 ^= uint32(tail[1]) << 8 + fallthrough + case 1: + k1 ^= uint32(tail[0]) + k1 *= c1_32 + k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) + k1 *= c2_32 + h1 ^= k1 + } + + h1 ^= uint32(len(data)) + + h1 ^= h1 >> 16 + h1 *= 0x85ebca6b + h1 ^= h1 >> 13 + h1 *= 0xc2b2ae35 + h1 ^= h1 >> 16 + + return h1 +} diff --git a/vendor/github.com/spaolacci/murmur3/murmur64.go b/vendor/github.com/spaolacci/murmur3/murmur64.go new file mode 100644 index 00000000..65a410ae --- /dev/null +++ b/vendor/github.com/spaolacci/murmur3/murmur64.go @@ -0,0 +1,57 @@ +package murmur3 + +import ( + "hash" +) + +// Make sure interfaces are correctly implemented. +var ( + _ hash.Hash = new(digest64) + _ hash.Hash64 = new(digest64) + _ bmixer = new(digest64) +) + +// digest64 is half a digest128. +type digest64 digest128 + +// New64 returns a 64-bit hasher +func New64() hash.Hash64 { return New64WithSeed(0) } + +// New64WithSeed returns a 64-bit hasher set with explicit seed value +func New64WithSeed(seed uint32) hash.Hash64 { + d := (*digest64)(New128WithSeed(seed).(*digest128)) + return d +} + +func (d *digest64) Sum(b []byte) []byte { + h1 := d.Sum64() + return append(b, + byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32), + byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1)) +} + +func (d *digest64) Sum64() uint64 { + h1, _ := (*digest128)(d).Sum128() + return h1 +} + +// Sum64 returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New64() +// hasher.Write(data) +// return hasher.Sum64() +func Sum64(data []byte) uint64 { return Sum64WithSeed(data, 0) } + +// Sum64WithSeed returns the MurmurHash3 sum of data. It is equivalent to the +// following sequence (without the extra burden and the extra allocation): +// hasher := New64WithSeed(seed) +// hasher.Write(data) +// return hasher.Sum64() +func Sum64WithSeed(data []byte, seed uint32) uint64 { + d := &digest128{h1: uint64(seed), h2: uint64(seed)} + d.seed = seed + d.tail = d.bmix(data) + d.clen = len(data) + h1, _ := d.Sum128() + return h1 +} diff --git a/vendor/github.com/spf13/afero/copyOnWriteFs.go b/vendor/github.com/spf13/afero/copyOnWriteFs.go new file mode 100644 index 00000000..e8108a85 --- /dev/null +++ b/vendor/github.com/spf13/afero/copyOnWriteFs.go @@ -0,0 +1,293 @@ +package afero + +import ( + "fmt" + "os" + "path/filepath" + "syscall" + "time" +) + +var _ Lstater = (*CopyOnWriteFs)(nil) + +// The CopyOnWriteFs is a union filesystem: a read only base file system with +// a possibly writeable layer on top. Changes to the file system will only +// be made in the overlay: Changing an existing file in the base layer which +// is not present in the overlay will copy the file to the overlay ("changing" +// includes also calls to e.g. Chtimes() and Chmod()). +// +// Reading directories is currently only supported via Open(), not OpenFile(). +type CopyOnWriteFs struct { + base Fs + layer Fs +} + +func NewCopyOnWriteFs(base Fs, layer Fs) Fs { + return &CopyOnWriteFs{base: base, layer: layer} +} + +// Returns true if the file is not in the overlay +func (u *CopyOnWriteFs) isBaseFile(name string) (bool, error) { + if _, err := u.layer.Stat(name); err == nil { + return false, nil + } + _, err := u.base.Stat(name) + if err != nil { + if oerr, ok := err.(*os.PathError); ok { + if oerr.Err == os.ErrNotExist || oerr.Err == syscall.ENOENT || oerr.Err == syscall.ENOTDIR { + return false, nil + } + } + if err == syscall.ENOENT { + return false, nil + } + } + return true, err +} + +func (u *CopyOnWriteFs) copyToLayer(name string) error { + return copyToLayer(u.base, u.layer, name) +} + +func (u *CopyOnWriteFs) Chtimes(name string, atime, mtime time.Time) error { + b, err := u.isBaseFile(name) + if err != nil { + return err + } + if b { + if err := u.copyToLayer(name); err != nil { + return err + } + } + return u.layer.Chtimes(name, atime, mtime) +} + +func (u *CopyOnWriteFs) Chmod(name string, mode os.FileMode) error { + b, err := u.isBaseFile(name) + if err != nil { + return err + } + if b { + if err := u.copyToLayer(name); err != nil { + return err + } + } + return u.layer.Chmod(name, mode) +} + +func (u *CopyOnWriteFs) Stat(name string) (os.FileInfo, error) { + fi, err := u.layer.Stat(name) + if err != nil { + isNotExist := u.isNotExist(err) + if isNotExist { + return u.base.Stat(name) + } + return nil, err + } + return fi, nil +} + +func (u *CopyOnWriteFs) LstatIfPossible(name string) (os.FileInfo, bool, error) { + llayer, ok1 := u.layer.(Lstater) + lbase, ok2 := u.base.(Lstater) + + if ok1 { + fi, b, err := llayer.LstatIfPossible(name) + if err == nil { + return fi, b, nil + } + + if !u.isNotExist(err) { + return nil, b, err + } + } + + if ok2 { + fi, b, err := lbase.LstatIfPossible(name) + if err == nil { + return fi, b, nil + } + if !u.isNotExist(err) { + return nil, b, err + } + } + + fi, err := u.Stat(name) + + return fi, false, err +} + +func (u *CopyOnWriteFs) isNotExist(err error) bool { + if e, ok := err.(*os.PathError); ok { + err = e.Err + } + if err == os.ErrNotExist || err == syscall.ENOENT || err == syscall.ENOTDIR { + return true + } + return false +} + +// Renaming files present only in the base layer is not permitted +func (u *CopyOnWriteFs) Rename(oldname, newname string) error { + b, err := u.isBaseFile(oldname) + if err != nil { + return err + } + if b { + return syscall.EPERM + } + return u.layer.Rename(oldname, newname) +} + +// Removing files present only in the base layer is not permitted. If +// a file is present in the base layer and the overlay, only the overlay +// will be removed. +func (u *CopyOnWriteFs) Remove(name string) error { + err := u.layer.Remove(name) + switch err { + case syscall.ENOENT: + _, err = u.base.Stat(name) + if err == nil { + return syscall.EPERM + } + return syscall.ENOENT + default: + return err + } +} + +func (u *CopyOnWriteFs) RemoveAll(name string) error { + err := u.layer.RemoveAll(name) + switch err { + case syscall.ENOENT: + _, err = u.base.Stat(name) + if err == nil { + return syscall.EPERM + } + return syscall.ENOENT + default: + return err + } +} + +func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { + b, err := u.isBaseFile(name) + if err != nil { + return nil, err + } + + if flag&(os.O_WRONLY|os.O_RDWR|os.O_APPEND|os.O_CREATE|os.O_TRUNC) != 0 { + if b { + if err = u.copyToLayer(name); err != nil { + return nil, err + } + return u.layer.OpenFile(name, flag, perm) + } + + dir := filepath.Dir(name) + isaDir, err := IsDir(u.base, dir) + if err != nil && !os.IsNotExist(err) { + return nil, err + } + if isaDir { + if err = u.layer.MkdirAll(dir, 0777); err != nil { + return nil, err + } + return u.layer.OpenFile(name, flag, perm) + } + + isaDir, err = IsDir(u.layer, dir) + if err != nil { + return nil, err + } + if isaDir { + return u.layer.OpenFile(name, flag, perm) + } + + return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOTDIR} // ...or os.ErrNotExist? + } + if b { + return u.base.OpenFile(name, flag, perm) + } + return u.layer.OpenFile(name, flag, perm) +} + +// This function handles the 9 different possibilities caused +// by the union which are the intersection of the following... +// layer: doesn't exist, exists as a file, and exists as a directory +// base: doesn't exist, exists as a file, and exists as a directory +func (u *CopyOnWriteFs) Open(name string) (File, error) { + // Since the overlay overrides the base we check that first + b, err := u.isBaseFile(name) + if err != nil { + return nil, err + } + + // If overlay doesn't exist, return the base (base state irrelevant) + if b { + return u.base.Open(name) + } + + // If overlay is a file, return it (base state irrelevant) + dir, err := IsDir(u.layer, name) + if err != nil { + return nil, err + } + if !dir { + return u.layer.Open(name) + } + + // Overlay is a directory, base state now matters. + // Base state has 3 states to check but 2 outcomes: + // A. It's a file or non-readable in the base (return just the overlay) + // B. It's an accessible directory in the base (return a UnionFile) + + // If base is file or nonreadable, return overlay + dir, err = IsDir(u.base, name) + if !dir || err != nil { + return u.layer.Open(name) + } + + // Both base & layer are directories + // Return union file (if opens are without error) + bfile, bErr := u.base.Open(name) + lfile, lErr := u.layer.Open(name) + + // If either have errors at this point something is very wrong. Return nil and the errors + if bErr != nil || lErr != nil { + return nil, fmt.Errorf("BaseErr: %v\nOverlayErr: %v", bErr, lErr) + } + + return &UnionFile{Base: bfile, Layer: lfile}, nil +} + +func (u *CopyOnWriteFs) Mkdir(name string, perm os.FileMode) error { + dir, err := IsDir(u.base, name) + if err != nil { + return u.layer.MkdirAll(name, perm) + } + if dir { + return ErrFileExists + } + return u.layer.MkdirAll(name, perm) +} + +func (u *CopyOnWriteFs) Name() string { + return "CopyOnWriteFs" +} + +func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error { + dir, err := IsDir(u.base, name) + if err != nil { + return u.layer.MkdirAll(name, perm) + } + if dir { + // This is in line with how os.MkdirAll behaves. + return nil + } + return u.layer.MkdirAll(name, perm) +} + +func (u *CopyOnWriteFs) Create(name string) (File, error) { + return u.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666) +} diff --git a/vendor/github.com/spf13/afero/go.mod b/vendor/github.com/spf13/afero/go.mod new file mode 100644 index 00000000..08685509 --- /dev/null +++ b/vendor/github.com/spf13/afero/go.mod @@ -0,0 +1,3 @@ +module github.com/spf13/afero + +require golang.org/x/text v0.3.0 diff --git a/vendor/github.com/spf13/afero/go.sum b/vendor/github.com/spf13/afero/go.sum new file mode 100644 index 00000000..6bad37b2 --- /dev/null +++ b/vendor/github.com/spf13/afero/go.sum @@ -0,0 +1,2 @@ +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/spf13/afero/unionFile.go b/vendor/github.com/spf13/afero/unionFile.go new file mode 100644 index 00000000..eda96312 --- /dev/null +++ b/vendor/github.com/spf13/afero/unionFile.go @@ -0,0 +1,320 @@ +package afero + +import ( + "io" + "os" + "path/filepath" + "syscall" +) + +// The UnionFile implements the afero.File interface and will be returned +// when reading a directory present at least in the overlay or opening a file +// for writing. +// +// The calls to +// Readdir() and Readdirnames() merge the file os.FileInfo / names from the +// base and the overlay - for files present in both layers, only those +// from the overlay will be used. +// +// When opening files for writing (Create() / OpenFile() with the right flags) +// the operations will be done in both layers, starting with the overlay. A +// successful read in the overlay will move the cursor position in the base layer +// by the number of bytes read. +type UnionFile struct { + Base File + Layer File + Merger DirsMerger + off int + files []os.FileInfo +} + +func (f *UnionFile) Close() error { + // first close base, so we have a newer timestamp in the overlay. If we'd close + // the overlay first, we'd get a cacheStale the next time we access this file + // -> cache would be useless ;-) + if f.Base != nil { + f.Base.Close() + } + if f.Layer != nil { + return f.Layer.Close() + } + return BADFD +} + +func (f *UnionFile) Read(s []byte) (int, error) { + if f.Layer != nil { + n, err := f.Layer.Read(s) + if (err == nil || err == io.EOF) && f.Base != nil { + // advance the file position also in the base file, the next + // call may be a write at this position (or a seek with SEEK_CUR) + if _, seekErr := f.Base.Seek(int64(n), os.SEEK_CUR); seekErr != nil { + // only overwrite err in case the seek fails: we need to + // report an eventual io.EOF to the caller + err = seekErr + } + } + return n, err + } + if f.Base != nil { + return f.Base.Read(s) + } + return 0, BADFD +} + +func (f *UnionFile) ReadAt(s []byte, o int64) (int, error) { + if f.Layer != nil { + n, err := f.Layer.ReadAt(s, o) + if (err == nil || err == io.EOF) && f.Base != nil { + _, err = f.Base.Seek(o+int64(n), os.SEEK_SET) + } + return n, err + } + if f.Base != nil { + return f.Base.ReadAt(s, o) + } + return 0, BADFD +} + +func (f *UnionFile) Seek(o int64, w int) (pos int64, err error) { + if f.Layer != nil { + pos, err = f.Layer.Seek(o, w) + if (err == nil || err == io.EOF) && f.Base != nil { + _, err = f.Base.Seek(o, w) + } + return pos, err + } + if f.Base != nil { + return f.Base.Seek(o, w) + } + return 0, BADFD +} + +func (f *UnionFile) Write(s []byte) (n int, err error) { + if f.Layer != nil { + n, err = f.Layer.Write(s) + if err == nil && f.Base != nil { // hmm, do we have fixed size files where a write may hit the EOF mark? + _, err = f.Base.Write(s) + } + return n, err + } + if f.Base != nil { + return f.Base.Write(s) + } + return 0, BADFD +} + +func (f *UnionFile) WriteAt(s []byte, o int64) (n int, err error) { + if f.Layer != nil { + n, err = f.Layer.WriteAt(s, o) + if err == nil && f.Base != nil { + _, err = f.Base.WriteAt(s, o) + } + return n, err + } + if f.Base != nil { + return f.Base.WriteAt(s, o) + } + return 0, BADFD +} + +func (f *UnionFile) Name() string { + if f.Layer != nil { + return f.Layer.Name() + } + return f.Base.Name() +} + +// DirsMerger is how UnionFile weaves two directories together. +// It takes the FileInfo slices from the layer and the base and returns a +// single view. +type DirsMerger func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) + +var defaultUnionMergeDirsFn = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) { + var files = make(map[string]os.FileInfo) + + for _, fi := range lofi { + files[fi.Name()] = fi + } + + for _, fi := range bofi { + if _, exists := files[fi.Name()]; !exists { + files[fi.Name()] = fi + } + } + + rfi := make([]os.FileInfo, len(files)) + + i := 0 + for _, fi := range files { + rfi[i] = fi + i++ + } + + return rfi, nil + +} + +// Readdir will weave the two directories together and +// return a single view of the overlayed directories. +// At the end of the directory view, the error is io.EOF if c > 0. +func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error) { + var merge DirsMerger = f.Merger + if merge == nil { + merge = defaultUnionMergeDirsFn + } + + if f.off == 0 { + var lfi []os.FileInfo + if f.Layer != nil { + lfi, err = f.Layer.Readdir(-1) + if err != nil { + return nil, err + } + } + + var bfi []os.FileInfo + if f.Base != nil { + bfi, err = f.Base.Readdir(-1) + if err != nil { + return nil, err + } + + } + merged, err := merge(lfi, bfi) + if err != nil { + return nil, err + } + f.files = append(f.files, merged...) + } + + if c <= 0 && len(f.files) == 0 { + return f.files, nil + } + + if f.off >= len(f.files) { + return nil, io.EOF + } + + if c <= 0 { + return f.files[f.off:], nil + } + + if c > len(f.files) { + c = len(f.files) + } + + defer func() { f.off += c }() + return f.files[f.off:c], nil +} + +func (f *UnionFile) Readdirnames(c int) ([]string, error) { + rfi, err := f.Readdir(c) + if err != nil { + return nil, err + } + var names []string + for _, fi := range rfi { + names = append(names, fi.Name()) + } + return names, nil +} + +func (f *UnionFile) Stat() (os.FileInfo, error) { + if f.Layer != nil { + return f.Layer.Stat() + } + if f.Base != nil { + return f.Base.Stat() + } + return nil, BADFD +} + +func (f *UnionFile) Sync() (err error) { + if f.Layer != nil { + err = f.Layer.Sync() + if err == nil && f.Base != nil { + err = f.Base.Sync() + } + return err + } + if f.Base != nil { + return f.Base.Sync() + } + return BADFD +} + +func (f *UnionFile) Truncate(s int64) (err error) { + if f.Layer != nil { + err = f.Layer.Truncate(s) + if err == nil && f.Base != nil { + err = f.Base.Truncate(s) + } + return err + } + if f.Base != nil { + return f.Base.Truncate(s) + } + return BADFD +} + +func (f *UnionFile) WriteString(s string) (n int, err error) { + if f.Layer != nil { + n, err = f.Layer.WriteString(s) + if err == nil && f.Base != nil { + _, err = f.Base.WriteString(s) + } + return n, err + } + if f.Base != nil { + return f.Base.WriteString(s) + } + return 0, BADFD +} + +func copyToLayer(base Fs, layer Fs, name string) error { + bfh, err := base.Open(name) + if err != nil { + return err + } + defer bfh.Close() + + // First make sure the directory exists + exists, err := Exists(layer, filepath.Dir(name)) + if err != nil { + return err + } + if !exists { + err = layer.MkdirAll(filepath.Dir(name), 0777) // FIXME? + if err != nil { + return err + } + } + + // Create the file on the overlay + lfh, err := layer.Create(name) + if err != nil { + return err + } + n, err := io.Copy(lfh, bfh) + if err != nil { + // If anything fails, clean up the file + layer.Remove(name) + lfh.Close() + return err + } + + bfi, err := bfh.Stat() + if err != nil || bfi.Size() != n { + layer.Remove(name) + lfh.Close() + return syscall.EIO + } + + err = lfh.Close() + if err != nil { + layer.Remove(name) + lfh.Close() + return err + } + return layer.Chtimes(name, bfi.ModTime(), bfi.ModTime()) +} diff --git a/vendor/github.com/spf13/cast/.travis.yml b/vendor/github.com/spf13/cast/.travis.yml new file mode 100644 index 00000000..6420d1c2 --- /dev/null +++ b/vendor/github.com/spf13/cast/.travis.yml @@ -0,0 +1,15 @@ +language: go +env: + - GO111MODULE=on +sudo: required +go: + - "1.11.x" + - tip +os: + - linux +matrix: + allow_failures: + - go: tip + fast_finish: true +script: + - make check diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go new file mode 100644 index 00000000..9fba638d --- /dev/null +++ b/vendor/github.com/spf13/cast/cast.go @@ -0,0 +1,171 @@ +// Copyright © 2014 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +// Package cast provides easy and safe casting in Go. +package cast + +import "time" + +// ToBool casts an interface to a bool type. +func ToBool(i interface{}) bool { + v, _ := ToBoolE(i) + return v +} + +// ToTime casts an interface to a time.Time type. +func ToTime(i interface{}) time.Time { + v, _ := ToTimeE(i) + return v +} + +// ToDuration casts an interface to a time.Duration type. +func ToDuration(i interface{}) time.Duration { + v, _ := ToDurationE(i) + return v +} + +// ToFloat64 casts an interface to a float64 type. +func ToFloat64(i interface{}) float64 { + v, _ := ToFloat64E(i) + return v +} + +// ToFloat32 casts an interface to a float32 type. +func ToFloat32(i interface{}) float32 { + v, _ := ToFloat32E(i) + return v +} + +// ToInt64 casts an interface to an int64 type. +func ToInt64(i interface{}) int64 { + v, _ := ToInt64E(i) + return v +} + +// ToInt32 casts an interface to an int32 type. +func ToInt32(i interface{}) int32 { + v, _ := ToInt32E(i) + return v +} + +// ToInt16 casts an interface to an int16 type. +func ToInt16(i interface{}) int16 { + v, _ := ToInt16E(i) + return v +} + +// ToInt8 casts an interface to an int8 type. +func ToInt8(i interface{}) int8 { + v, _ := ToInt8E(i) + return v +} + +// ToInt casts an interface to an int type. +func ToInt(i interface{}) int { + v, _ := ToIntE(i) + return v +} + +// ToUint casts an interface to a uint type. +func ToUint(i interface{}) uint { + v, _ := ToUintE(i) + return v +} + +// ToUint64 casts an interface to a uint64 type. +func ToUint64(i interface{}) uint64 { + v, _ := ToUint64E(i) + return v +} + +// ToUint32 casts an interface to a uint32 type. +func ToUint32(i interface{}) uint32 { + v, _ := ToUint32E(i) + return v +} + +// ToUint16 casts an interface to a uint16 type. +func ToUint16(i interface{}) uint16 { + v, _ := ToUint16E(i) + return v +} + +// ToUint8 casts an interface to a uint8 type. +func ToUint8(i interface{}) uint8 { + v, _ := ToUint8E(i) + return v +} + +// ToString casts an interface to a string type. +func ToString(i interface{}) string { + v, _ := ToStringE(i) + return v +} + +// ToStringMapString casts an interface to a map[string]string type. +func ToStringMapString(i interface{}) map[string]string { + v, _ := ToStringMapStringE(i) + return v +} + +// ToStringMapStringSlice casts an interface to a map[string][]string type. +func ToStringMapStringSlice(i interface{}) map[string][]string { + v, _ := ToStringMapStringSliceE(i) + return v +} + +// ToStringMapBool casts an interface to a map[string]bool type. +func ToStringMapBool(i interface{}) map[string]bool { + v, _ := ToStringMapBoolE(i) + return v +} + +// ToStringMapInt casts an interface to a map[string]int type. +func ToStringMapInt(i interface{}) map[string]int { + v, _ := ToStringMapIntE(i) + return v +} + +// ToStringMapInt64 casts an interface to a map[string]int64 type. +func ToStringMapInt64(i interface{}) map[string]int64 { + v, _ := ToStringMapInt64E(i) + return v +} + +// ToStringMap casts an interface to a map[string]interface{} type. +func ToStringMap(i interface{}) map[string]interface{} { + v, _ := ToStringMapE(i) + return v +} + +// ToSlice casts an interface to a []interface{} type. +func ToSlice(i interface{}) []interface{} { + v, _ := ToSliceE(i) + return v +} + +// ToBoolSlice casts an interface to a []bool type. +func ToBoolSlice(i interface{}) []bool { + v, _ := ToBoolSliceE(i) + return v +} + +// ToStringSlice casts an interface to a []string type. +func ToStringSlice(i interface{}) []string { + v, _ := ToStringSliceE(i) + return v +} + +// ToIntSlice casts an interface to a []int type. +func ToIntSlice(i interface{}) []int { + v, _ := ToIntSliceE(i) + return v +} + +// ToDurationSlice casts an interface to a []time.Duration type. +func ToDurationSlice(i interface{}) []time.Duration { + v, _ := ToDurationSliceE(i) + return v +} diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go new file mode 100644 index 00000000..a4859fb0 --- /dev/null +++ b/vendor/github.com/spf13/cast/caste.go @@ -0,0 +1,1249 @@ +// Copyright © 2014 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package cast + +import ( + "encoding/json" + "errors" + "fmt" + "html/template" + "reflect" + "strconv" + "strings" + "time" +) + +var errNegativeNotAllowed = errors.New("unable to cast negative value") + +// ToTimeE casts an interface to a time.Time type. +func ToTimeE(i interface{}) (tim time.Time, err error) { + i = indirect(i) + + switch v := i.(type) { + case time.Time: + return v, nil + case string: + return StringToDate(v) + case int: + return time.Unix(int64(v), 0), nil + case int64: + return time.Unix(v, 0), nil + case int32: + return time.Unix(int64(v), 0), nil + case uint: + return time.Unix(int64(v), 0), nil + case uint64: + return time.Unix(int64(v), 0), nil + case uint32: + return time.Unix(int64(v), 0), nil + default: + return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i) + } +} + +// ToDurationE casts an interface to a time.Duration type. +func ToDurationE(i interface{}) (d time.Duration, err error) { + i = indirect(i) + + switch s := i.(type) { + case time.Duration: + return s, nil + case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8: + d = time.Duration(ToInt64(s)) + return + case float32, float64: + d = time.Duration(ToFloat64(s)) + return + case string: + if strings.ContainsAny(s, "nsuµmh") { + d, err = time.ParseDuration(s) + } else { + d, err = time.ParseDuration(s + "ns") + } + return + default: + err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i) + return + } +} + +// ToBoolE casts an interface to a bool type. +func ToBoolE(i interface{}) (bool, error) { + i = indirect(i) + + switch b := i.(type) { + case bool: + return b, nil + case nil: + return false, nil + case int: + if i.(int) != 0 { + return true, nil + } + return false, nil + case string: + return strconv.ParseBool(i.(string)) + default: + return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i) + } +} + +// ToFloat64E casts an interface to a float64 type. +func ToFloat64E(i interface{}) (float64, error) { + i = indirect(i) + + switch s := i.(type) { + case float64: + return s, nil + case float32: + return float64(s), nil + case int: + return float64(s), nil + case int64: + return float64(s), nil + case int32: + return float64(s), nil + case int16: + return float64(s), nil + case int8: + return float64(s), nil + case uint: + return float64(s), nil + case uint64: + return float64(s), nil + case uint32: + return float64(s), nil + case uint16: + return float64(s), nil + case uint8: + return float64(s), nil + case string: + v, err := strconv.ParseFloat(s, 64) + if err == nil { + return v, nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) + } +} + +// ToFloat32E casts an interface to a float32 type. +func ToFloat32E(i interface{}) (float32, error) { + i = indirect(i) + + switch s := i.(type) { + case float64: + return float32(s), nil + case float32: + return s, nil + case int: + return float32(s), nil + case int64: + return float32(s), nil + case int32: + return float32(s), nil + case int16: + return float32(s), nil + case int8: + return float32(s), nil + case uint: + return float32(s), nil + case uint64: + return float32(s), nil + case uint32: + return float32(s), nil + case uint16: + return float32(s), nil + case uint8: + return float32(s), nil + case string: + v, err := strconv.ParseFloat(s, 32) + if err == nil { + return float32(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i) + } +} + +// ToInt64E casts an interface to an int64 type. +func ToInt64E(i interface{}) (int64, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return int64(s), nil + case int64: + return s, nil + case int32: + return int64(s), nil + case int16: + return int64(s), nil + case int8: + return int64(s), nil + case uint: + return int64(s), nil + case uint64: + return int64(s), nil + case uint32: + return int64(s), nil + case uint16: + return int64(s), nil + case uint8: + return int64(s), nil + case float64: + return int64(s), nil + case float32: + return int64(s), nil + case string: + v, err := strconv.ParseInt(s, 0, 0) + if err == nil { + return v, nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i) + } +} + +// ToInt32E casts an interface to an int32 type. +func ToInt32E(i interface{}) (int32, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return int32(s), nil + case int64: + return int32(s), nil + case int32: + return s, nil + case int16: + return int32(s), nil + case int8: + return int32(s), nil + case uint: + return int32(s), nil + case uint64: + return int32(s), nil + case uint32: + return int32(s), nil + case uint16: + return int32(s), nil + case uint8: + return int32(s), nil + case float64: + return int32(s), nil + case float32: + return int32(s), nil + case string: + v, err := strconv.ParseInt(s, 0, 0) + if err == nil { + return int32(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i) + } +} + +// ToInt16E casts an interface to an int16 type. +func ToInt16E(i interface{}) (int16, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return int16(s), nil + case int64: + return int16(s), nil + case int32: + return int16(s), nil + case int16: + return s, nil + case int8: + return int16(s), nil + case uint: + return int16(s), nil + case uint64: + return int16(s), nil + case uint32: + return int16(s), nil + case uint16: + return int16(s), nil + case uint8: + return int16(s), nil + case float64: + return int16(s), nil + case float32: + return int16(s), nil + case string: + v, err := strconv.ParseInt(s, 0, 0) + if err == nil { + return int16(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i) + } +} + +// ToInt8E casts an interface to an int8 type. +func ToInt8E(i interface{}) (int8, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return int8(s), nil + case int64: + return int8(s), nil + case int32: + return int8(s), nil + case int16: + return int8(s), nil + case int8: + return s, nil + case uint: + return int8(s), nil + case uint64: + return int8(s), nil + case uint32: + return int8(s), nil + case uint16: + return int8(s), nil + case uint8: + return int8(s), nil + case float64: + return int8(s), nil + case float32: + return int8(s), nil + case string: + v, err := strconv.ParseInt(s, 0, 0) + if err == nil { + return int8(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i) + } +} + +// ToIntE casts an interface to an int type. +func ToIntE(i interface{}) (int, error) { + i = indirect(i) + + switch s := i.(type) { + case int: + return s, nil + case int64: + return int(s), nil + case int32: + return int(s), nil + case int16: + return int(s), nil + case int8: + return int(s), nil + case uint: + return int(s), nil + case uint64: + return int(s), nil + case uint32: + return int(s), nil + case uint16: + return int(s), nil + case uint8: + return int(s), nil + case float64: + return int(s), nil + case float32: + return int(s), nil + case string: + v, err := strconv.ParseInt(s, 0, 0) + if err == nil { + return int(v), nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i) + } +} + +// ToUintE casts an interface to a uint type. +func ToUintE(i interface{}) (uint, error) { + i = indirect(i) + + switch s := i.(type) { + case string: + v, err := strconv.ParseUint(s, 0, 0) + if err == nil { + return uint(v), nil + } + return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err) + case int: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case int64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case int32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case int16: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case int8: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case uint: + return s, nil + case uint64: + return uint(s), nil + case uint32: + return uint(s), nil + case uint16: + return uint(s), nil + case uint8: + return uint(s), nil + case float64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case float32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint(s), nil + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i) + } +} + +// ToUint64E casts an interface to a uint64 type. +func ToUint64E(i interface{}) (uint64, error) { + i = indirect(i) + + switch s := i.(type) { + case string: + v, err := strconv.ParseUint(s, 0, 64) + if err == nil { + return v, nil + } + return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err) + case int: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case int64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case int32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case int16: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case int8: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case uint: + return uint64(s), nil + case uint64: + return s, nil + case uint32: + return uint64(s), nil + case uint16: + return uint64(s), nil + case uint8: + return uint64(s), nil + case float32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case float64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint64(s), nil + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i) + } +} + +// ToUint32E casts an interface to a uint32 type. +func ToUint32E(i interface{}) (uint32, error) { + i = indirect(i) + + switch s := i.(type) { + case string: + v, err := strconv.ParseUint(s, 0, 32) + if err == nil { + return uint32(v), nil + } + return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err) + case int: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case int64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case int32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case int16: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case int8: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case uint: + return uint32(s), nil + case uint64: + return uint32(s), nil + case uint32: + return s, nil + case uint16: + return uint32(s), nil + case uint8: + return uint32(s), nil + case float64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case float32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint32(s), nil + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i) + } +} + +// ToUint16E casts an interface to a uint16 type. +func ToUint16E(i interface{}) (uint16, error) { + i = indirect(i) + + switch s := i.(type) { + case string: + v, err := strconv.ParseUint(s, 0, 16) + if err == nil { + return uint16(v), nil + } + return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err) + case int: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case int64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case int32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case int16: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case int8: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case uint: + return uint16(s), nil + case uint64: + return uint16(s), nil + case uint32: + return uint16(s), nil + case uint16: + return s, nil + case uint8: + return uint16(s), nil + case float64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case float32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint16(s), nil + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i) + } +} + +// ToUint8E casts an interface to a uint type. +func ToUint8E(i interface{}) (uint8, error) { + i = indirect(i) + + switch s := i.(type) { + case string: + v, err := strconv.ParseUint(s, 0, 8) + if err == nil { + return uint8(v), nil + } + return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err) + case int: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case int64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case int32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case int16: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case int8: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case uint: + return uint8(s), nil + case uint64: + return uint8(s), nil + case uint32: + return uint8(s), nil + case uint16: + return uint8(s), nil + case uint8: + return s, nil + case float64: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case float32: + if s < 0 { + return 0, errNegativeNotAllowed + } + return uint8(s), nil + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i) + } +} + +// From html/template/content.go +// Copyright 2011 The Go Authors. All rights reserved. +// indirect returns the value, after dereferencing as many times +// as necessary to reach the base type (or nil). +func indirect(a interface{}) interface{} { + if a == nil { + return nil + } + if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr { + // Avoid creating a reflect.Value if it's not a pointer. + return a + } + v := reflect.ValueOf(a) + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v.Interface() +} + +// From html/template/content.go +// Copyright 2011 The Go Authors. All rights reserved. +// indirectToStringerOrError returns the value, after dereferencing as many times +// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer +// or error, +func indirectToStringerOrError(a interface{}) interface{} { + if a == nil { + return nil + } + + var errorType = reflect.TypeOf((*error)(nil)).Elem() + var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() + + v := reflect.ValueOf(a) + for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v.Interface() +} + +// ToStringE casts an interface to a string type. +func ToStringE(i interface{}) (string, error) { + i = indirectToStringerOrError(i) + + switch s := i.(type) { + case string: + return s, nil + case bool: + return strconv.FormatBool(s), nil + case float64: + return strconv.FormatFloat(s, 'f', -1, 64), nil + case float32: + return strconv.FormatFloat(float64(s), 'f', -1, 32), nil + case int: + return strconv.Itoa(s), nil + case int64: + return strconv.FormatInt(s, 10), nil + case int32: + return strconv.Itoa(int(s)), nil + case int16: + return strconv.FormatInt(int64(s), 10), nil + case int8: + return strconv.FormatInt(int64(s), 10), nil + case uint: + return strconv.FormatInt(int64(s), 10), nil + case uint64: + return strconv.FormatInt(int64(s), 10), nil + case uint32: + return strconv.FormatInt(int64(s), 10), nil + case uint16: + return strconv.FormatInt(int64(s), 10), nil + case uint8: + return strconv.FormatInt(int64(s), 10), nil + case []byte: + return string(s), nil + case template.HTML: + return string(s), nil + case template.URL: + return string(s), nil + case template.JS: + return string(s), nil + case template.CSS: + return string(s), nil + case template.HTMLAttr: + return string(s), nil + case nil: + return "", nil + case fmt.Stringer: + return s.String(), nil + case error: + return s.Error(), nil + default: + return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i) + } +} + +// ToStringMapStringE casts an interface to a map[string]string type. +func ToStringMapStringE(i interface{}) (map[string]string, error) { + var m = map[string]string{} + + switch v := i.(type) { + case map[string]string: + return v, nil + case map[string]interface{}: + for k, val := range v { + m[ToString(k)] = ToString(val) + } + return m, nil + case map[interface{}]string: + for k, val := range v { + m[ToString(k)] = ToString(val) + } + return m, nil + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = ToString(val) + } + return m, nil + case string: + err := jsonStringToObject(v, &m) + return m, err + default: + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i) + } +} + +// ToStringMapStringSliceE casts an interface to a map[string][]string type. +func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) { + var m = map[string][]string{} + + switch v := i.(type) { + case map[string][]string: + return v, nil + case map[string][]interface{}: + for k, val := range v { + m[ToString(k)] = ToStringSlice(val) + } + return m, nil + case map[string]string: + for k, val := range v { + m[ToString(k)] = []string{val} + } + case map[string]interface{}: + for k, val := range v { + switch vt := val.(type) { + case []interface{}: + m[ToString(k)] = ToStringSlice(vt) + case []string: + m[ToString(k)] = vt + default: + m[ToString(k)] = []string{ToString(val)} + } + } + return m, nil + case map[interface{}][]string: + for k, val := range v { + m[ToString(k)] = ToStringSlice(val) + } + return m, nil + case map[interface{}]string: + for k, val := range v { + m[ToString(k)] = ToStringSlice(val) + } + return m, nil + case map[interface{}][]interface{}: + for k, val := range v { + m[ToString(k)] = ToStringSlice(val) + } + return m, nil + case map[interface{}]interface{}: + for k, val := range v { + key, err := ToStringE(k) + if err != nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i) + } + value, err := ToStringSliceE(val) + if err != nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i) + } + m[key] = value + } + case string: + err := jsonStringToObject(v, &m) + return m, err + default: + return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i) + } + return m, nil +} + +// ToStringMapBoolE casts an interface to a map[string]bool type. +func ToStringMapBoolE(i interface{}) (map[string]bool, error) { + var m = map[string]bool{} + + switch v := i.(type) { + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = ToBool(val) + } + return m, nil + case map[string]interface{}: + for k, val := range v { + m[ToString(k)] = ToBool(val) + } + return m, nil + case map[string]bool: + return v, nil + case string: + err := jsonStringToObject(v, &m) + return m, err + default: + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i) + } +} + +// ToStringMapE casts an interface to a map[string]interface{} type. +func ToStringMapE(i interface{}) (map[string]interface{}, error) { + var m = map[string]interface{}{} + + switch v := i.(type) { + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = val + } + return m, nil + case map[string]interface{}: + return v, nil + case string: + err := jsonStringToObject(v, &m) + return m, err + default: + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i) + } +} + +// ToStringMapIntE casts an interface to a map[string]int{} type. +func ToStringMapIntE(i interface{}) (map[string]int, error) { + var m = map[string]int{} + if i == nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i) + } + + switch v := i.(type) { + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = ToInt(val) + } + return m, nil + case map[string]interface{}: + for k, val := range v { + m[k] = ToInt(val) + } + return m, nil + case map[string]int: + return v, nil + case string: + err := jsonStringToObject(v, &m) + return m, err + } + + if reflect.TypeOf(i).Kind() != reflect.Map { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i) + } + + mVal := reflect.ValueOf(m) + v := reflect.ValueOf(i) + for _, keyVal := range v.MapKeys() { + val, err := ToIntE(v.MapIndex(keyVal).Interface()) + if err != nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i) + } + mVal.SetMapIndex(keyVal, reflect.ValueOf(val)) + } + return m, nil +} + +// ToStringMapInt64E casts an interface to a map[string]int64{} type. +func ToStringMapInt64E(i interface{}) (map[string]int64, error) { + var m = map[string]int64{} + if i == nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i) + } + + switch v := i.(type) { + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = ToInt64(val) + } + return m, nil + case map[string]interface{}: + for k, val := range v { + m[k] = ToInt64(val) + } + return m, nil + case map[string]int64: + return v, nil + case string: + err := jsonStringToObject(v, &m) + return m, err + } + + if reflect.TypeOf(i).Kind() != reflect.Map { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i) + } + mVal := reflect.ValueOf(m) + v := reflect.ValueOf(i) + for _, keyVal := range v.MapKeys() { + val, err := ToInt64E(v.MapIndex(keyVal).Interface()) + if err != nil { + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i) + } + mVal.SetMapIndex(keyVal, reflect.ValueOf(val)) + } + return m, nil +} + +// ToSliceE casts an interface to a []interface{} type. +func ToSliceE(i interface{}) ([]interface{}, error) { + var s []interface{} + + switch v := i.(type) { + case []interface{}: + return append(s, v...), nil + case []map[string]interface{}: + for _, u := range v { + s = append(s, u) + } + return s, nil + default: + return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i) + } +} + +// ToBoolSliceE casts an interface to a []bool type. +func ToBoolSliceE(i interface{}) ([]bool, error) { + if i == nil { + return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i) + } + + switch v := i.(type) { + case []bool: + return v, nil + } + + kind := reflect.TypeOf(i).Kind() + switch kind { + case reflect.Slice, reflect.Array: + s := reflect.ValueOf(i) + a := make([]bool, s.Len()) + for j := 0; j < s.Len(); j++ { + val, err := ToBoolE(s.Index(j).Interface()) + if err != nil { + return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i) + } + a[j] = val + } + return a, nil + default: + return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i) + } +} + +// ToStringSliceE casts an interface to a []string type. +func ToStringSliceE(i interface{}) ([]string, error) { + var a []string + + switch v := i.(type) { + case []interface{}: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []string: + return v, nil + case string: + return strings.Fields(v), nil + case interface{}: + str, err := ToStringE(v) + if err != nil { + return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i) + } + return []string{str}, nil + default: + return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i) + } +} + +// ToIntSliceE casts an interface to a []int type. +func ToIntSliceE(i interface{}) ([]int, error) { + if i == nil { + return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i) + } + + switch v := i.(type) { + case []int: + return v, nil + } + + kind := reflect.TypeOf(i).Kind() + switch kind { + case reflect.Slice, reflect.Array: + s := reflect.ValueOf(i) + a := make([]int, s.Len()) + for j := 0; j < s.Len(); j++ { + val, err := ToIntE(s.Index(j).Interface()) + if err != nil { + return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i) + } + a[j] = val + } + return a, nil + default: + return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i) + } +} + +// ToDurationSliceE casts an interface to a []time.Duration type. +func ToDurationSliceE(i interface{}) ([]time.Duration, error) { + if i == nil { + return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) + } + + switch v := i.(type) { + case []time.Duration: + return v, nil + } + + kind := reflect.TypeOf(i).Kind() + switch kind { + case reflect.Slice, reflect.Array: + s := reflect.ValueOf(i) + a := make([]time.Duration, s.Len()) + for j := 0; j < s.Len(); j++ { + val, err := ToDurationE(s.Index(j).Interface()) + if err != nil { + return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) + } + a[j] = val + } + return a, nil + default: + return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) + } +} + +// StringToDate attempts to parse a string into a time.Time type using a +// predefined list of formats. If no suitable format is found, an error is +// returned. +func StringToDate(s string) (time.Time, error) { + return parseDateWith(s, []string{ + time.RFC3339, + "2006-01-02T15:04:05", // iso8601 without timezone + time.RFC1123Z, + time.RFC1123, + time.RFC822Z, + time.RFC822, + time.RFC850, + time.ANSIC, + time.UnixDate, + time.RubyDate, + "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String() + "2006-01-02", + "02 Jan 2006", + "2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon + "2006-01-02 15:04:05 -07:00", + "2006-01-02 15:04:05 -0700", + "2006-01-02 15:04:05Z07:00", // RFC3339 without T + "2006-01-02 15:04:05Z0700", // RFC3339 without T or timezone hh:mm colon + "2006-01-02 15:04:05", + time.Kitchen, + time.Stamp, + time.StampMilli, + time.StampMicro, + time.StampNano, + }) +} + +func parseDateWith(s string, dates []string) (d time.Time, e error) { + for _, dateType := range dates { + if d, e = time.Parse(dateType, s); e == nil { + return + } + } + return d, fmt.Errorf("unable to parse date: %s", s) +} + +// jsonStringToObject attempts to unmarshall a string as JSON into +// the object passed as pointer. +func jsonStringToObject(s string, v interface{}) error { + data := []byte(s) + return json.Unmarshal(data, v) +} diff --git a/vendor/github.com/spf13/cast/go.mod b/vendor/github.com/spf13/cast/go.mod new file mode 100644 index 00000000..c1c0232d --- /dev/null +++ b/vendor/github.com/spf13/cast/go.mod @@ -0,0 +1,7 @@ +module github.com/spf13/cast + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.2.2 +) diff --git a/vendor/github.com/spf13/cast/go.sum b/vendor/github.com/spf13/cast/go.sum new file mode 100644 index 00000000..e03ee77d --- /dev/null +++ b/vendor/github.com/spf13/cast/go.sum @@ -0,0 +1,6 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/vendor/github.com/spf13/cobra/.gitignore b/vendor/github.com/spf13/cobra/.gitignore new file mode 100644 index 00000000..3b053c59 --- /dev/null +++ b/vendor/github.com/spf13/cobra/.gitignore @@ -0,0 +1,38 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +# Vim files https://github.com/github/gitignore/blob/master/Global/Vim.gitignore +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + +*.exe + +cobra.test + +.idea/* diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml new file mode 100644 index 00000000..38b85f49 --- /dev/null +++ b/vendor/github.com/spf13/cobra/.travis.yml @@ -0,0 +1,31 @@ +language: go + +stages: + - diff + - test + +go: + - 1.10.x + - 1.11.x + - 1.12.x + - tip + +matrix: + allow_failures: + - go: tip + include: + - stage: diff + go: 1.12.x + script: diff -u <(echo -n) <(gofmt -d -s .) + +before_install: + - mkdir -p bin + - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.6.0/shellcheck + - chmod +x bin/shellcheck + - go get -u github.com/kyoh86/richgo +script: + - PATH=$PATH:$PWD/bin richgo test -v ./... + - go build + - if [ -z $NOVET ]; then + diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint'); + fi diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md new file mode 100644 index 00000000..60c5a425 --- /dev/null +++ b/vendor/github.com/spf13/cobra/README.md @@ -0,0 +1,741 @@ +![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png) + +Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files. + +Many of the most widely used Go projects are built using Cobra, such as: +[Kubernetes](http://kubernetes.io/), +[Hugo](http://gohugo.io), +[rkt](https://github.com/coreos/rkt), +[etcd](https://github.com/coreos/etcd), +[Moby (former Docker)](https://github.com/moby/moby), +[Docker (distribution)](https://github.com/docker/distribution), +[OpenShift](https://www.openshift.com/), +[Delve](https://github.com/derekparker/delve), +[GopherJS](http://www.gopherjs.org/), +[CockroachDB](http://www.cockroachlabs.com/), +[Bleve](http://www.blevesearch.com/), +[ProjectAtomic (enterprise)](http://www.projectatomic.io/), +[Giant Swarm's gsctl](https://github.com/giantswarm/gsctl), +[Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack), +[rclone](http://rclone.org/), +[nehm](https://github.com/bogem/nehm), +[Pouch](https://github.com/alibaba/pouch), +[Istio](https://istio.io), +[Prototool](https://github.com/uber/prototool), +[mattermost-server](https://github.com/mattermost/mattermost-server), +[Gardener](https://github.com/gardener/gardenctl), +etc. + +[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra) +[![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra) +[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra) + +# Table of Contents + +- [Overview](#overview) +- [Concepts](#concepts) + * [Commands](#commands) + * [Flags](#flags) +- [Installing](#installing) +- [Getting Started](#getting-started) + * [Using the Cobra Generator](#using-the-cobra-generator) + * [Using the Cobra Library](#using-the-cobra-library) + * [Working with Flags](#working-with-flags) + * [Positional and Custom Arguments](#positional-and-custom-arguments) + * [Example](#example) + * [Help Command](#help-command) + * [Usage Message](#usage-message) + * [PreRun and PostRun Hooks](#prerun-and-postrun-hooks) + * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens) + * [Generating documentation for your command](#generating-documentation-for-your-command) + * [Generating bash completions](#generating-bash-completions) + * [Generating zsh completions](#generating-zsh-completions) +- [Contributing](#contributing) +- [License](#license) + +# Overview + +Cobra is a library providing a simple interface to create powerful modern CLI +interfaces similar to git & go tools. + +Cobra is also an application that will generate your application scaffolding to rapidly +develop a Cobra-based application. + +Cobra provides: +* Easy subcommand-based CLIs: `app server`, `app fetch`, etc. +* Fully POSIX-compliant flags (including short & long versions) +* Nested subcommands +* Global, local and cascading flags +* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname` +* Intelligent suggestions (`app srver`... did you mean `app server`?) +* Automatic help generation for commands and flags +* Automatic help flag recognition of `-h`, `--help`, etc. +* Automatically generated bash autocomplete for your application +* Automatically generated man pages for your application +* Command aliases so you can change things without breaking them +* The flexibility to define your own help, usage, etc. +* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps + +# Concepts + +Cobra is built on a structure of commands, arguments & flags. + +**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions. + +The best applications will read like sentences when used. Users will know how +to use the application because they will natively understand how to use it. + +The pattern to follow is +`APPNAME VERB NOUN --ADJECTIVE.` + or +`APPNAME COMMAND ARG --FLAG` + +A few good real world examples may better illustrate this point. + +In the following example, 'server' is a command, and 'port' is a flag: + + hugo server --port=1313 + +In this command we are telling Git to clone the url bare. + + git clone URL --bare + +## Commands + +Command is the central point of the application. Each interaction that +the application supports will be contained in a Command. A command can +have children commands and optionally run an action. + +In the example above, 'server' is the command. + +[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command) + +## Flags + +A flag is a way to modify the behavior of a command. Cobra supports +fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/). +A Cobra command can define flags that persist through to children commands +and flags that are only available to that command. + +In the example above, 'port' is the flag. + +Flag functionality is provided by the [pflag +library](https://github.com/spf13/pflag), a fork of the flag standard library +which maintains the same interface while adding POSIX compliance. + +# Installing +Using Cobra is easy. First, use `go get` to install the latest version +of the library. This command will install the `cobra` generator executable +along with the library and its dependencies: + + go get -u github.com/spf13/cobra/cobra + +Next, include Cobra in your application: + +```go +import "github.com/spf13/cobra" +``` + +# Getting Started + +While you are welcome to provide your own organization, typically a Cobra-based +application will follow the following organizational structure: + +``` + ▾ appName/ + ▾ cmd/ + add.go + your.go + commands.go + here.go + main.go +``` + +In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra. + +```go +package main + +import ( + "{pathToYourApp}/cmd" +) + +func main() { + cmd.Execute() +} +``` + +## Using the Cobra Generator + +Cobra provides its own program that will create your application and add any +commands you want. It's the easiest way to incorporate Cobra into your application. + +[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it. + +## Using the Cobra Library + +To manually implement Cobra you need to create a bare main.go file and a rootCmd file. +You will optionally provide additional commands as you see fit. + +### Create rootCmd + +Cobra doesn't require any special constructors. Simply create your commands. + +Ideally you place this in app/cmd/root.go: + +```go +var rootCmd = &cobra.Command{ + Use: "hugo", + Short: "Hugo is a very fast static site generator", + Long: `A Fast and Flexible Static Site Generator built with + love by spf13 and friends in Go. + Complete documentation is available at http://hugo.spf13.com`, + Run: func(cmd *cobra.Command, args []string) { + // Do Stuff Here + }, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} +``` + +You will additionally define flags and handle configuration in your init() function. + +For example cmd/root.go: + +```go +import ( + "fmt" + "os" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func init() { + cobra.OnInitialize(initConfig) + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") + rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/") + rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution") + rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)") + rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration") + viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) + viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase")) + viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper")) + viper.SetDefault("author", "NAME HERE ") + viper.SetDefault("license", "apache") +} + +func initConfig() { + // Don't forget to read config either from cfgFile or from home directory! + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".cobra" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".cobra") + } + + if err := viper.ReadInConfig(); err != nil { + fmt.Println("Can't read config:", err) + os.Exit(1) + } +} +``` + +### Create your main.go + +With the root command you need to have your main function execute it. +Execute should be run on the root for clarity, though it can be called on any command. + +In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra. + +```go +package main + +import ( + "{pathToYourApp}/cmd" +) + +func main() { + cmd.Execute() +} +``` + +### Create additional commands + +Additional commands can be defined and typically are each given their own file +inside of the cmd/ directory. + +If you wanted to create a version command you would create cmd/version.go and +populate it with the following: + +```go +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(versionCmd) +} + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version number of Hugo", + Long: `All software has versions. This is Hugo's`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Hugo Static Site Generator v0.9 -- HEAD") + }, +} +``` + +## Working with Flags + +Flags provide modifiers to control how the action command operates. + +### Assign flags to a command + +Since the flags are defined and used in different locations, we need to +define a variable outside with the correct scope to assign the flag to +work with. + +```go +var Verbose bool +var Source string +``` + +There are two different approaches to assign a flag. + +### Persistent Flags + +A flag can be 'persistent' meaning that this flag will be available to the +command it's assigned to as well as every command under that command. For +global flags, assign a flag as a persistent flag on the root. + +```go +rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") +``` + +### Local Flags + +A flag can also be assigned locally which will only apply to that specific command. + +```go +localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") +``` + +### Local Flag on Parent Commands + +By default Cobra only parses local flags on the target command, any local flags on +parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will +parse local flags on each command before executing the target command. + +```go +command := cobra.Command{ + Use: "print [OPTIONS] [COMMANDS]", + TraverseChildren: true, +} +``` + +### Bind Flags with Config + +You can also bind your flags with [viper](https://github.com/spf13/viper): +```go +var author string + +func init() { + rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution") + viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) +} +``` + +In this example the persistent flag `author` is bound with `viper`. +**Note**, that the variable `author` will not be set to the value from config, +when the `--author` flag is not provided by user. + +More in [viper documentation](https://github.com/spf13/viper#working-with-flags). + +### Required flags + +Flags are optional by default. If instead you wish your command to report an error +when a flag has not been set, mark it as required: +```go +rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)") +rootCmd.MarkFlagRequired("region") +``` + +## Positional and Custom Arguments + +Validation of positional arguments can be specified using the `Args` field +of `Command`. + +The following validators are built in: + +- `NoArgs` - the command will report an error if there are any positional args. +- `ArbitraryArgs` - the command will accept any args. +- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`. +- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args. +- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args. +- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args. +- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command` +- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args. + +An example of setting the custom validator: + +```go +var cmd = &cobra.Command{ + Short: "hello", + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("requires a color argument") + } + if myapp.IsValidColor(args[0]) { + return nil + } + return fmt.Errorf("invalid color specified: %s", args[0]) + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Hello, World!") + }, +} +``` + +## Example + +In the example below, we have defined three commands. Two are at the top level +and one (cmdTimes) is a child of one of the top commands. In this case the root +is not executable meaning that a subcommand is required. This is accomplished +by not providing a 'Run' for the 'rootCmd'. + +We have only defined one flag for a single command. + +More documentation about flags is available at https://github.com/spf13/pflag + +```go +package main + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" +) + +func main() { + var echoTimes int + + var cmdPrint = &cobra.Command{ + Use: "print [string to print]", + Short: "Print anything to the screen", + Long: `print is for printing anything back to the screen. +For many years people have printed back to the screen.`, + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Print: " + strings.Join(args, " ")) + }, + } + + var cmdEcho = &cobra.Command{ + Use: "echo [string to echo]", + Short: "Echo anything to the screen", + Long: `echo is for echoing anything back. +Echo works a lot like print, except it has a child command.`, + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Print: " + strings.Join(args, " ")) + }, + } + + var cmdTimes = &cobra.Command{ + Use: "times [string to echo]", + Short: "Echo anything to the screen more times", + Long: `echo things multiple times back to the user by providing +a count and a string.`, + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + for i := 0; i < echoTimes; i++ { + fmt.Println("Echo: " + strings.Join(args, " ")) + } + }, + } + + cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input") + + var rootCmd = &cobra.Command{Use: "app"} + rootCmd.AddCommand(cmdPrint, cmdEcho) + cmdEcho.AddCommand(cmdTimes) + rootCmd.Execute() +} +``` + +For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/). + +## Help Command + +Cobra automatically adds a help command to your application when you have subcommands. +This will be called when a user runs 'app help'. Additionally, help will also +support all other commands as input. Say, for instance, you have a command called +'create' without any additional configuration; Cobra will work when 'app help +create' is called. Every command will automatically have the '--help' flag added. + +### Example + +The following output is automatically generated by Cobra. Nothing beyond the +command and flag definitions are needed. + + $ cobra help + + Cobra is a CLI library for Go that empowers applications. + This application is a tool to generate the needed files + to quickly create a Cobra application. + + Usage: + cobra [command] + + Available Commands: + add Add a command to a Cobra Application + help Help about any command + init Initialize a Cobra Application + + Flags: + -a, --author string author name for copyright attribution (default "YOUR NAME") + --config string config file (default is $HOME/.cobra.yaml) + -h, --help help for cobra + -l, --license string name of license for the project + --viper use Viper for configuration (default true) + + Use "cobra [command] --help" for more information about a command. + + +Help is just a command like any other. There is no special logic or behavior +around it. In fact, you can provide your own if you want. + +### Defining your own help + +You can provide your own Help command or your own template for the default command to use +with following functions: + +```go +cmd.SetHelpCommand(cmd *Command) +cmd.SetHelpFunc(f func(*Command, []string)) +cmd.SetHelpTemplate(s string) +``` + +The latter two will also apply to any children commands. + +## Usage Message + +When the user provides an invalid flag or invalid command, Cobra responds by +showing the user the 'usage'. + +### Example +You may recognize this from the help above. That's because the default help +embeds the usage as part of its output. + + $ cobra --invalid + Error: unknown flag: --invalid + Usage: + cobra [command] + + Available Commands: + add Add a command to a Cobra Application + help Help about any command + init Initialize a Cobra Application + + Flags: + -a, --author string author name for copyright attribution (default "YOUR NAME") + --config string config file (default is $HOME/.cobra.yaml) + -h, --help help for cobra + -l, --license string name of license for the project + --viper use Viper for configuration (default true) + + Use "cobra [command] --help" for more information about a command. + +### Defining your own usage +You can provide your own usage function or template for Cobra to use. +Like help, the function and template are overridable through public methods: + +```go +cmd.SetUsageFunc(f func(*Command) error) +cmd.SetUsageTemplate(s string) +``` + +## Version Flag + +Cobra adds a top-level '--version' flag if the Version field is set on the root command. +Running an application with the '--version' flag will print the version to stdout using +the version template. The template can be customized using the +`cmd.SetVersionTemplate(s string)` function. + +## PreRun and PostRun Hooks + +It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions are run in the following order: + +- `PersistentPreRun` +- `PreRun` +- `Run` +- `PostRun` +- `PersistentPostRun` + +An example of two commands which use all of these features is below. When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`: + +```go +package main + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +func main() { + + var rootCmd = &cobra.Command{ + Use: "root [sub]", + Short: "My root command", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args) + }, + PreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PreRun with args: %v\n", args) + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd Run with args: %v\n", args) + }, + PostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PostRun with args: %v\n", args) + }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args) + }, + } + + var subCmd = &cobra.Command{ + Use: "sub [no options!]", + Short: "My subcommand", + PreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PreRun with args: %v\n", args) + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd Run with args: %v\n", args) + }, + PostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PostRun with args: %v\n", args) + }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args) + }, + } + + rootCmd.AddCommand(subCmd) + + rootCmd.SetArgs([]string{""}) + rootCmd.Execute() + fmt.Println() + rootCmd.SetArgs([]string{"sub", "arg1", "arg2"}) + rootCmd.Execute() +} +``` + +Output: +``` +Inside rootCmd PersistentPreRun with args: [] +Inside rootCmd PreRun with args: [] +Inside rootCmd Run with args: [] +Inside rootCmd PostRun with args: [] +Inside rootCmd PersistentPostRun with args: [] + +Inside rootCmd PersistentPreRun with args: [arg1 arg2] +Inside subCmd PreRun with args: [arg1 arg2] +Inside subCmd Run with args: [arg1 arg2] +Inside subCmd PostRun with args: [arg1 arg2] +Inside subCmd PersistentPostRun with args: [arg1 arg2] +``` + +## Suggestions when "unknown command" happens + +Cobra will print automatic suggestions when "unknown command" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example: + +``` +$ hugo srever +Error: unknown command "srever" for "hugo" + +Did you mean this? + server + +Run 'hugo --help' for usage. +``` + +Suggestions are automatic based on every subcommand registered and use an implementation of [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion. + +If you need to disable suggestions or tweak the string distance in your command, use: + +```go +command.DisableSuggestions = true +``` + +or + +```go +command.SuggestionsMinimumDistance = 1 +``` + +You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but makes sense in your set of commands and for some which you don't want aliases. Example: + +``` +$ kubectl remove +Error: unknown command "remove" for "kubectl" + +Did you mean this? + delete + +Run 'kubectl help' for usage. +``` + +## Generating documentation for your command + +Cobra can generate documentation based on subcommands, flags, etc. in the following formats: + +- [Markdown](doc/md_docs.md) +- [ReStructured Text](doc/rest_docs.md) +- [Man Page](doc/man_docs.md) + +## Generating bash completions + +Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md). + +## Generating zsh completions + +Cobra can generate zsh-completion file. Read more about it in +[Zsh Completions](zsh_completions.md). + +# Contributing + +1. Fork it +2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`) +3. Create your feature branch (`git checkout -b my-new-feature`) +4. Make changes and add them (`git add .`) +5. Commit your changes (`git commit -m 'Add some feature'`) +6. Push to the branch (`git push origin my-new-feature`) +7. Create new pull request + +# License + +Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt) diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go new file mode 100644 index 00000000..c4d820b8 --- /dev/null +++ b/vendor/github.com/spf13/cobra/args.go @@ -0,0 +1,101 @@ +package cobra + +import ( + "fmt" +) + +type PositionalArgs func(cmd *Command, args []string) error + +// Legacy arg validation has the following behaviour: +// - root commands with no subcommands can take arbitrary arguments +// - root commands with subcommands will do subcommand validity checking +// - subcommands will always accept arbitrary arguments +func legacyArgs(cmd *Command, args []string) error { + // no subcommand, always take args + if !cmd.HasSubCommands() { + return nil + } + + // root command with subcommands, do subcommand checking. + if !cmd.HasParent() && len(args) > 0 { + return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0])) + } + return nil +} + +// NoArgs returns an error if any args are included. +func NoArgs(cmd *Command, args []string) error { + if len(args) > 0 { + return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath()) + } + return nil +} + +// OnlyValidArgs returns an error if any args are not in the list of ValidArgs. +func OnlyValidArgs(cmd *Command, args []string) error { + if len(cmd.ValidArgs) > 0 { + for _, v := range args { + if !stringInSlice(v, cmd.ValidArgs) { + return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0])) + } + } + } + return nil +} + +// ArbitraryArgs never returns an error. +func ArbitraryArgs(cmd *Command, args []string) error { + return nil +} + +// MinimumNArgs returns an error if there is not at least N args. +func MinimumNArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) < n { + return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args)) + } + return nil + } +} + +// MaximumNArgs returns an error if there are more than N args. +func MaximumNArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) > n { + return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args)) + } + return nil + } +} + +// ExactArgs returns an error if there are not exactly n args. +func ExactArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) != n { + return fmt.Errorf("accepts %d arg(s), received %d", n, len(args)) + } + return nil + } +} + +// ExactValidArgs returns an error if +// there are not exactly N positional args OR +// there are any positional args that are not in the `ValidArgs` field of `Command` +func ExactValidArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if err := ExactArgs(n)(cmd, args); err != nil { + return err + } + return OnlyValidArgs(cmd, args) + } +} + +// RangeArgs returns an error if the number of args is not within the expected range. +func RangeArgs(min int, max int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) < min || len(args) > max { + return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args)) + } + return nil + } +} diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go new file mode 100644 index 00000000..57bb8e1b --- /dev/null +++ b/vendor/github.com/spf13/cobra/bash_completions.go @@ -0,0 +1,547 @@ +package cobra + +import ( + "bytes" + "fmt" + "io" + "os" + "sort" + "strings" + + "github.com/spf13/pflag" +) + +// Annotations for Bash completion. +const ( + BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions" + BashCompCustom = "cobra_annotation_bash_completion_custom" + BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag" + BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir" +) + +func writePreamble(buf *bytes.Buffer, name string) { + buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name)) + buf.WriteString(fmt.Sprintf(` +__%[1]s_debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" + fi +} + +# Homebrew on Macs have version 1.3 of bash-completion which doesn't include +# _init_completion. This is a very minimal version of that function. +__%[1]s_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref "$@" cur prev words cword +} + +__%[1]s_index_of_word() +{ + local w word=$1 + shift + index=0 + for w in "$@"; do + [[ $w = "$word" ]] && return + index=$((index+1)) + done + index=-1 +} + +__%[1]s_contains_word() +{ + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done + return 1 +} + +__%[1]s_handle_reply() +{ + __%[1]s_debug "${FUNCNAME[0]}" + case $cur in + -*) + if [[ $(type -t compopt) = "builtin" ]]; then + compopt -o nospace + fi + local allflags + if [ ${#must_have_one_flag[@]} -ne 0 ]; then + allflags=("${must_have_one_flag[@]}") + else + allflags=("${flags[*]} ${two_word_flags[*]}") + fi + COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) + if [[ $(type -t compopt) = "builtin" ]]; then + [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace + fi + + # complete after --flag=abc + if [[ $cur == *=* ]]; then + if [[ $(type -t compopt) = "builtin" ]]; then + compopt +o nospace + fi + + local index flag + flag="${cur%%=*}" + __%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}" + COMPREPLY=() + if [[ ${index} -ge 0 ]]; then + PREFIX="" + cur="${cur#*=}" + ${flags_completion[${index}]} + if [ -n "${ZSH_VERSION}" ]; then + # zsh completion needs --flag= prefix + eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )" + fi + fi + fi + return 0; + ;; + esac + + # check if we are handling a flag with special work handling + local index + __%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}" + if [[ ${index} -ge 0 ]]; then + ${flags_completion[${index}]} + return + fi + + # we are parsing a flag and don't have a special handler, no completion + if [[ ${cur} != "${words[cword]}" ]]; then + return + fi + + local completions + completions=("${commands[@]}") + if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then + completions=("${must_have_one_noun[@]}") + fi + if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then + completions+=("${must_have_one_flag[@]}") + fi + COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) + + if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then + COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") ) + fi + + if [[ ${#COMPREPLY[@]} -eq 0 ]]; then + if declare -F __%[1]s_custom_func >/dev/null; then + # try command name qualified custom func + __%[1]s_custom_func + else + # otherwise fall back to unqualified for compatibility + declare -F __custom_func >/dev/null && __custom_func + fi + fi + + # available in bash-completion >= 2, not always present on macOS + if declare -F __ltrim_colon_completions >/dev/null; then + __ltrim_colon_completions "$cur" + fi + + # If there is only 1 completion and it is a flag with an = it will be completed + # but we don't want a space after the = + if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then + compopt -o nospace + fi +} + +# The arguments should be in the form "ext1|ext2|extn" +__%[1]s_handle_filename_extension_flag() +{ + local ext="$1" + _filedir "@(${ext})" +} + +__%[1]s_handle_subdirs_in_dir_flag() +{ + local dir="$1" + pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 +} + +__%[1]s_handle_flag() +{ + __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + # if a command required a flag, and we found it, unset must_have_one_flag() + local flagname=${words[c]} + local flagvalue + # if the word contained an = + if [[ ${words[c]} == *"="* ]]; then + flagvalue=${flagname#*=} # take in as flagvalue after the = + flagname=${flagname%%=*} # strip everything after the = + flagname="${flagname}=" # but put the = back + fi + __%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}" + if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then + must_have_one_flag=() + fi + + # if you set a flag which only applies to this command, don't show subcommands + if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then + commands=() + fi + + # keep flag value with flagname as flaghash + # flaghash variable is an associative array which is only supported in bash > 3. + if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then + if [ -n "${flagvalue}" ] ; then + flaghash[${flagname}]=${flagvalue} + elif [ -n "${words[ $((c+1)) ]}" ] ; then + flaghash[${flagname}]=${words[ $((c+1)) ]} + else + flaghash[${flagname}]="true" # pad "true" for bool flag + fi + fi + + # skip the argument to a two word flag + if [[ ${words[c]} != *"="* ]] && __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then + __%[1]s_debug "${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument" + c=$((c+1)) + # if we are looking for a flags value, don't show commands + if [[ $c -eq $cword ]]; then + commands=() + fi + fi + + c=$((c+1)) + +} + +__%[1]s_handle_noun() +{ + __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then + must_have_one_noun=() + elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then + must_have_one_noun=() + fi + + nouns+=("${words[c]}") + c=$((c+1)) +} + +__%[1]s_handle_command() +{ + __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + local next_command + if [[ -n ${last_command} ]]; then + next_command="_${last_command}_${words[c]//:/__}" + else + if [[ $c -eq 0 ]]; then + next_command="_%[1]s_root_command" + else + next_command="_${words[c]//:/__}" + fi + fi + c=$((c+1)) + __%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}" + declare -F "$next_command" >/dev/null && $next_command +} + +__%[1]s_handle_word() +{ + if [[ $c -ge $cword ]]; then + __%[1]s_handle_reply + return + fi + __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + if [[ "${words[c]}" == -* ]]; then + __%[1]s_handle_flag + elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then + __%[1]s_handle_command + elif [[ $c -eq 0 ]]; then + __%[1]s_handle_command + elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then + # aliashash variable is an associative array which is only supported in bash > 3. + if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then + words[c]=${aliashash[${words[c]}]} + __%[1]s_handle_command + else + __%[1]s_handle_noun + fi + else + __%[1]s_handle_noun + fi + __%[1]s_handle_word +} + +`, name)) +} + +func writePostscript(buf *bytes.Buffer, name string) { + name = strings.Replace(name, ":", "__", -1) + buf.WriteString(fmt.Sprintf("__start_%s()\n", name)) + buf.WriteString(fmt.Sprintf(`{ + local cur prev words cword + declare -A flaghash 2>/dev/null || : + declare -A aliashash 2>/dev/null || : + if declare -F _init_completion >/dev/null 2>&1; then + _init_completion -s || return + else + __%[1]s_init_completion -n "=" || return + fi + + local c=0 + local flags=() + local two_word_flags=() + local local_nonpersistent_flags=() + local flags_with_completion=() + local flags_completion=() + local commands=("%[1]s") + local must_have_one_flag=() + local must_have_one_noun=() + local last_command + local nouns=() + + __%[1]s_handle_word +} + +`, name)) + buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then + complete -o default -F __start_%s %s +else + complete -o default -o nospace -F __start_%s %s +fi + +`, name, name, name, name)) + buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n") +} + +func writeCommands(buf *bytes.Buffer, cmd *Command) { + buf.WriteString(" commands=()\n") + for _, c := range cmd.Commands() { + if !c.IsAvailableCommand() || c == cmd.helpCommand { + continue + } + buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name())) + writeCmdAliases(buf, c) + } + buf.WriteString("\n") +} + +func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) { + for key, value := range annotations { + switch key { + case BashCompFilenameExt: + buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name)) + + var ext string + if len(value) > 0 { + ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|") + } else { + ext = "_filedir" + } + buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext)) + case BashCompCustom: + buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name)) + if len(value) > 0 { + handlers := strings.Join(value, "; ") + buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers)) + } else { + buf.WriteString(" flags_completion+=(:)\n") + } + case BashCompSubdirsInDir: + buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name)) + + var ext string + if len(value) == 1 { + ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0] + } else { + ext = "_filedir -d" + } + buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext)) + } + } +} + +func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) { + name := flag.Shorthand + format := " " + if len(flag.NoOptDefVal) == 0 { + format += "two_word_" + } + format += "flags+=(\"-%s\")\n" + buf.WriteString(fmt.Sprintf(format, name)) + writeFlagHandler(buf, "-"+name, flag.Annotations, cmd) +} + +func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) { + name := flag.Name + format := " flags+=(\"--%s" + if len(flag.NoOptDefVal) == 0 { + format += "=" + } + format += "\")\n" + buf.WriteString(fmt.Sprintf(format, name)) + if len(flag.NoOptDefVal) == 0 { + format = " two_word_flags+=(\"--%s\")\n" + buf.WriteString(fmt.Sprintf(format, name)) + } + writeFlagHandler(buf, "--"+name, flag.Annotations, cmd) +} + +func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) { + name := flag.Name + format := " local_nonpersistent_flags+=(\"--%s" + if len(flag.NoOptDefVal) == 0 { + format += "=" + } + format += "\")\n" + buf.WriteString(fmt.Sprintf(format, name)) +} + +func writeFlags(buf *bytes.Buffer, cmd *Command) { + buf.WriteString(` flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + +`) + localNonPersistentFlags := cmd.LocalNonPersistentFlags() + cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) { + if nonCompletableFlag(flag) { + return + } + writeFlag(buf, flag, cmd) + if len(flag.Shorthand) > 0 { + writeShortFlag(buf, flag, cmd) + } + if localNonPersistentFlags.Lookup(flag.Name) != nil { + writeLocalNonPersistentFlag(buf, flag) + } + }) + cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) { + if nonCompletableFlag(flag) { + return + } + writeFlag(buf, flag, cmd) + if len(flag.Shorthand) > 0 { + writeShortFlag(buf, flag, cmd) + } + }) + + buf.WriteString("\n") +} + +func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) { + buf.WriteString(" must_have_one_flag=()\n") + flags := cmd.NonInheritedFlags() + flags.VisitAll(func(flag *pflag.Flag) { + if nonCompletableFlag(flag) { + return + } + for key := range flag.Annotations { + switch key { + case BashCompOneRequiredFlag: + format := " must_have_one_flag+=(\"--%s" + if flag.Value.Type() != "bool" { + format += "=" + } + format += "\")\n" + buf.WriteString(fmt.Sprintf(format, flag.Name)) + + if len(flag.Shorthand) > 0 { + buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand)) + } + } + } + }) +} + +func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) { + buf.WriteString(" must_have_one_noun=()\n") + sort.Sort(sort.StringSlice(cmd.ValidArgs)) + for _, value := range cmd.ValidArgs { + buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value)) + } +} + +func writeCmdAliases(buf *bytes.Buffer, cmd *Command) { + if len(cmd.Aliases) == 0 { + return + } + + sort.Sort(sort.StringSlice(cmd.Aliases)) + + buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n")) + for _, value := range cmd.Aliases { + buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value)) + buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name())) + } + buf.WriteString(` fi`) + buf.WriteString("\n") +} +func writeArgAliases(buf *bytes.Buffer, cmd *Command) { + buf.WriteString(" noun_aliases=()\n") + sort.Sort(sort.StringSlice(cmd.ArgAliases)) + for _, value := range cmd.ArgAliases { + buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value)) + } +} + +func gen(buf *bytes.Buffer, cmd *Command) { + for _, c := range cmd.Commands() { + if !c.IsAvailableCommand() || c == cmd.helpCommand { + continue + } + gen(buf, c) + } + commandName := cmd.CommandPath() + commandName = strings.Replace(commandName, " ", "_", -1) + commandName = strings.Replace(commandName, ":", "__", -1) + + if cmd.Root() == cmd { + buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName)) + } else { + buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName)) + } + + buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName)) + buf.WriteString("\n") + buf.WriteString(" command_aliases=()\n") + buf.WriteString("\n") + + writeCommands(buf, cmd) + writeFlags(buf, cmd) + writeRequiredFlag(buf, cmd) + writeRequiredNouns(buf, cmd) + writeArgAliases(buf, cmd) + buf.WriteString("}\n\n") +} + +// GenBashCompletion generates bash completion file and writes to the passed writer. +func (c *Command) GenBashCompletion(w io.Writer) error { + buf := new(bytes.Buffer) + writePreamble(buf, c.Name()) + if len(c.BashCompletionFunction) > 0 { + buf.WriteString(c.BashCompletionFunction + "\n") + } + gen(buf, c) + writePostscript(buf, c.Name()) + + _, err := buf.WriteTo(w) + return err +} + +func nonCompletableFlag(flag *pflag.Flag) bool { + return flag.Hidden || len(flag.Deprecated) > 0 +} + +// GenBashCompletionFile generates bash completion file. +func (c *Command) GenBashCompletionFile(filename string) error { + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + return c.GenBashCompletion(outFile) +} diff --git a/vendor/github.com/spf13/cobra/bash_completions.md b/vendor/github.com/spf13/cobra/bash_completions.md new file mode 100644 index 00000000..4ac61ee1 --- /dev/null +++ b/vendor/github.com/spf13/cobra/bash_completions.md @@ -0,0 +1,256 @@ +# Generating Bash Completions For Your Own cobra.Command + +If you are using the generator you can create a completion command by running + +```bash +cobra add completion +``` + +Update the help text show how to install the bash_completion Linux show here [Kubectl docs show mac options](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion) + +Writing the shell script to stdout allows the most flexible use. + +```go +// completionCmd represents the completion command +var completionCmd = &cobra.Command{ + Use: "completion", + Short: "Generates bash completion scripts", + Long: `To load completion run + +. <(bitbucket completion) + +To configure your bash shell to load completions for each session add to your bashrc + +# ~/.bashrc or ~/.profile +. <(bitbucket completion) +`, + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenBashCompletion(os.Stdout); + }, +} +``` + +**Note:** The cobra generator may include messages printed to stdout for example if the config file is loaded, this will break the auto complete script + + +## Example from kubectl + +Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows: + +```go +package main + +import ( + "io/ioutil" + "os" + + "k8s.io/kubernetes/pkg/kubectl/cmd" + "k8s.io/kubernetes/pkg/kubectl/cmd/util" +) + +func main() { + kubectl := cmd.NewKubectlCommand(util.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard) + kubectl.GenBashCompletionFile("out.sh") +} +``` + +`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior. + +## Creating your own custom functions + +Some more actual code that works in kubernetes: + +```bash +const ( + bash_completion_func = `__kubectl_parse_get() +{ + local kubectl_output out + if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then + out=($(echo "${kubectl_output}" | awk '{print $1}')) + COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + fi +} + +__kubectl_get_resource() +{ + if [[ ${#nouns[@]} -eq 0 ]]; then + return 1 + fi + __kubectl_parse_get ${nouns[${#nouns[@]} -1]} + if [[ $? -eq 0 ]]; then + return 0 + fi +} + +__kubectl_custom_func() { + case ${last_command} in + kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop) + __kubectl_get_resource + return + ;; + *) + ;; + esac +} +`) +``` + +And then I set that in my command definition: + +```go +cmds := &cobra.Command{ + Use: "kubectl", + Short: "kubectl controls the Kubernetes cluster manager", + Long: `kubectl controls the Kubernetes cluster manager. + +Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`, + Run: runHelp, + BashCompletionFunction: bash_completion_func, +} +``` + +The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`___custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__kubectl_custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods! + +## Have the completions code complete your 'nouns' + +In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like: + +```go +validArgs []string = { "pod", "node", "service", "replicationcontroller" } + +cmd := &cobra.Command{ + Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", + Short: "Display one or many resources", + Long: get_long, + Example: get_example, + Run: func(cmd *cobra.Command, args []string) { + err := RunGet(f, out, cmd, args) + util.CheckErr(err) + }, + ValidArgs: validArgs, +} +``` + +Notice we put the "ValidArgs" on the "get" subcommand. Doing so will give results like + +```bash +# kubectl get [tab][tab] +node pod replicationcontroller service +``` + +## Plural form and shortcuts for nouns + +If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`: + +```go +argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" } + +cmd := &cobra.Command{ + ... + ValidArgs: validArgs, + ArgAliases: argAliases +} +``` + +The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by +the completion algorithm if entered manually, e.g. in: + +```bash +# kubectl get rc [tab][tab] +backend frontend database +``` + +Note that without declaring `rc` as an alias, the completion algorithm would show the list of nouns +in this example again instead of the replication controllers. + +## Mark flags as required + +Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab]. Marking a flag as 'Required' is incredibly easy. + +```go +cmd.MarkFlagRequired("pod") +cmd.MarkFlagRequired("container") +``` + +and you'll get something like + +```bash +# kubectl exec [tab][tab][tab] +-c --container= -p --pod= +``` + +# Specify valid filename extensions for flags that take a filename + +In this example we use --filename= and expect to get a json or yaml file as the argument. To make this easier we annotate the --filename flag with valid filename extensions. + +```go + annotations := []string{"json", "yaml", "yml"} + annotation := make(map[string][]string) + annotation[cobra.BashCompFilenameExt] = annotations + + flag := &pflag.Flag{ + Name: "filename", + Shorthand: "f", + Usage: usage, + Value: value, + DefValue: value.String(), + Annotations: annotation, + } + cmd.Flags().AddFlag(flag) +``` + +Now when you run a command with this filename flag you'll get something like + +```bash +# kubectl create -f +test/ example/ rpmbuild/ +hello.yml test.json +``` + +So while there are many other files in the CWD it only shows me subdirs and those with valid extensions. + +# Specify custom flag completion + +Similar to the filename completion and filtering using cobra.BashCompFilenameExt, you can specify +a custom flag completion function with cobra.BashCompCustom: + +```go + annotation := make(map[string][]string) + annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"} + + flag := &pflag.Flag{ + Name: "namespace", + Usage: usage, + Annotations: annotation, + } + cmd.Flags().AddFlag(flag) +``` + +In addition add the `__handle_namespace_flag` implementation in the `BashCompletionFunction` +value, e.g.: + +```bash +__kubectl_get_namespaces() +{ + local template + template="{{ range .items }}{{ .metadata.name }} {{ end }}" + local kubectl_out + if kubectl_out=$(kubectl get -o template --template="${template}" namespace 2>/dev/null); then + COMPREPLY=( $( compgen -W "${kubectl_out}[*]" -- "$cur" ) ) + fi +} +``` +# Using bash aliases for commands + +You can also configure the `bash aliases` for the commands and they will also support completions. + +```bash +alias aliasname=origcommand +complete -o default -F __start_origcommand aliasname + +# and now when you run `aliasname` completion will make +# suggestions as it did for `origcommand`. + +$) aliasname +completion firstcommand secondcommand +``` diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go new file mode 100644 index 00000000..6505c070 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -0,0 +1,207 @@ +// Copyright © 2013 Steve Francia . +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Commands similar to git, go tools and other modern CLI tools +// inspired by go, go-Commander, gh and subcommand + +package cobra + +import ( + "fmt" + "io" + "reflect" + "strconv" + "strings" + "text/template" + "time" + "unicode" +) + +var templateFuncs = template.FuncMap{ + "trim": strings.TrimSpace, + "trimRightSpace": trimRightSpace, + "trimTrailingWhitespaces": trimRightSpace, + "appendIfNotPresent": appendIfNotPresent, + "rpad": rpad, + "gt": Gt, + "eq": Eq, +} + +var initializers []func() + +// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing +// to automatically enable in CLI tools. +// Set this to true to enable it. +var EnablePrefixMatching = false + +// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default. +// To disable sorting, set it to false. +var EnableCommandSorting = true + +// MousetrapHelpText enables an information splash screen on Windows +// if the CLI is started from explorer.exe. +// To disable the mousetrap, just set this variable to blank string (""). +// Works only on Microsoft Windows. +var MousetrapHelpText string = `This is a command line tool. + +You need to open cmd.exe and run it from there. +` + +// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows +// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed. +// To disable the mousetrap, just set MousetrapHelpText to blank string (""). +// Works only on Microsoft Windows. +var MousetrapDisplayDuration time.Duration = 5 * time.Second + +// AddTemplateFunc adds a template function that's available to Usage and Help +// template generation. +func AddTemplateFunc(name string, tmplFunc interface{}) { + templateFuncs[name] = tmplFunc +} + +// AddTemplateFuncs adds multiple template functions that are available to Usage and +// Help template generation. +func AddTemplateFuncs(tmplFuncs template.FuncMap) { + for k, v := range tmplFuncs { + templateFuncs[k] = v + } +} + +// OnInitialize sets the passed functions to be run when each command's +// Execute method is called. +func OnInitialize(y ...func()) { + initializers = append(initializers, y...) +} + +// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + +// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans, +// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as +// ints and then compared. +func Gt(a interface{}, b interface{}) bool { + var left, right int64 + av := reflect.ValueOf(a) + + switch av.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + left = int64(av.Len()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + left = av.Int() + case reflect.String: + left, _ = strconv.ParseInt(av.String(), 10, 64) + } + + bv := reflect.ValueOf(b) + + switch bv.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + right = int64(bv.Len()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + right = bv.Int() + case reflect.String: + right, _ = strconv.ParseInt(bv.String(), 10, 64) + } + + return left > right +} + +// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + +// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic. +func Eq(a interface{}, b interface{}) bool { + av := reflect.ValueOf(a) + bv := reflect.ValueOf(b) + + switch av.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + panic("Eq called on unsupported type") + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return av.Int() == bv.Int() + case reflect.String: + return av.String() == bv.String() + } + return false +} + +func trimRightSpace(s string) string { + return strings.TrimRightFunc(s, unicode.IsSpace) +} + +// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + +// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s. +func appendIfNotPresent(s, stringToAppend string) string { + if strings.Contains(s, stringToAppend) { + return s + } + return s + " " + stringToAppend +} + +// rpad adds padding to the right of a string. +func rpad(s string, padding int) string { + template := fmt.Sprintf("%%-%ds", padding) + return fmt.Sprintf(template, s) +} + +// tmpl executes the given template text on data, writing the result to w. +func tmpl(w io.Writer, text string, data interface{}) error { + t := template.New("top") + t.Funcs(templateFuncs) + template.Must(t.Parse(text)) + return t.Execute(w, data) +} + +// ld compares two strings and returns the levenshtein distance between them. +func ld(s, t string, ignoreCase bool) int { + if ignoreCase { + s = strings.ToLower(s) + t = strings.ToLower(t) + } + d := make([][]int, len(s)+1) + for i := range d { + d[i] = make([]int, len(t)+1) + } + for i := range d { + d[i][0] = i + } + for j := range d[0] { + d[0][j] = j + } + for j := 1; j <= len(t); j++ { + for i := 1; i <= len(s); i++ { + if s[i-1] == t[j-1] { + d[i][j] = d[i-1][j-1] + } else { + min := d[i-1][j] + if d[i][j-1] < min { + min = d[i][j-1] + } + if d[i-1][j-1] < min { + min = d[i-1][j-1] + } + d[i][j] = min + 1 + } + } + + } + return d[len(s)][len(t)] +} + +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go new file mode 100644 index 00000000..c7e89830 --- /dev/null +++ b/vendor/github.com/spf13/cobra/command.go @@ -0,0 +1,1594 @@ +// Copyright © 2013 Steve Francia . +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. +// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. +package cobra + +import ( + "bytes" + "fmt" + "io" + "os" + "path/filepath" + "sort" + "strings" + + flag "github.com/spf13/pflag" +) + +// FParseErrWhitelist configures Flag parse errors to be ignored +type FParseErrWhitelist flag.ParseErrorsWhitelist + +// Command is just that, a command for your application. +// E.g. 'go run ...' - 'run' is the command. Cobra requires +// you to define the usage and description as part of your command +// definition to ensure usability. +type Command struct { + // Use is the one-line usage message. + Use string + + // Aliases is an array of aliases that can be used instead of the first word in Use. + Aliases []string + + // SuggestFor is an array of command names for which this command will be suggested - + // similar to aliases but only suggests. + SuggestFor []string + + // Short is the short description shown in the 'help' output. + Short string + + // Long is the long message shown in the 'help ' output. + Long string + + // Example is examples of how to use the command. + Example string + + // ValidArgs is list of all valid non-flag arguments that are accepted in bash completions + ValidArgs []string + + // Expected arguments + Args PositionalArgs + + // ArgAliases is List of aliases for ValidArgs. + // These are not suggested to the user in the bash completion, + // but accepted if entered manually. + ArgAliases []string + + // BashCompletionFunction is custom functions used by the bash autocompletion generator. + BashCompletionFunction string + + // Deprecated defines, if this command is deprecated and should print this string when used. + Deprecated string + + // Hidden defines, if this command is hidden and should NOT show up in the list of available commands. + Hidden bool + + // Annotations are key/value pairs that can be used by applications to identify or + // group commands. + Annotations map[string]string + + // Version defines the version for this command. If this value is non-empty and the command does not + // define a "version" flag, a "version" boolean flag will be added to the command and, if specified, + // will print content of the "Version" variable. + Version string + + // The *Run functions are executed in the following order: + // * PersistentPreRun() + // * PreRun() + // * Run() + // * PostRun() + // * PersistentPostRun() + // All functions get the same args, the arguments after the command name. + // + // PersistentPreRun: children of this command will inherit and execute. + PersistentPreRun func(cmd *Command, args []string) + // PersistentPreRunE: PersistentPreRun but returns an error. + PersistentPreRunE func(cmd *Command, args []string) error + // PreRun: children of this command will not inherit. + PreRun func(cmd *Command, args []string) + // PreRunE: PreRun but returns an error. + PreRunE func(cmd *Command, args []string) error + // Run: Typically the actual work function. Most commands will only implement this. + Run func(cmd *Command, args []string) + // RunE: Run but returns an error. + RunE func(cmd *Command, args []string) error + // PostRun: run after the Run command. + PostRun func(cmd *Command, args []string) + // PostRunE: PostRun but returns an error. + PostRunE func(cmd *Command, args []string) error + // PersistentPostRun: children of this command will inherit and execute after PostRun. + PersistentPostRun func(cmd *Command, args []string) + // PersistentPostRunE: PersistentPostRun but returns an error. + PersistentPostRunE func(cmd *Command, args []string) error + + // SilenceErrors is an option to quiet errors down stream. + SilenceErrors bool + + // SilenceUsage is an option to silence usage when an error occurs. + SilenceUsage bool + + // DisableFlagParsing disables the flag parsing. + // If this is true all flags will be passed to the command as arguments. + DisableFlagParsing bool + + // DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...") + // will be printed by generating docs for this command. + DisableAutoGenTag bool + + // DisableFlagsInUseLine will disable the addition of [flags] to the usage + // line of a command when printing help or generating docs + DisableFlagsInUseLine bool + + // DisableSuggestions disables the suggestions based on Levenshtein distance + // that go along with 'unknown command' messages. + DisableSuggestions bool + // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions. + // Must be > 0. + SuggestionsMinimumDistance int + + // TraverseChildren parses flags on all parents before executing child command. + TraverseChildren bool + + //FParseErrWhitelist flag parse errors to be ignored + FParseErrWhitelist FParseErrWhitelist + + // commands is the list of commands supported by this program. + commands []*Command + // parent is a parent command for this command. + parent *Command + // Max lengths of commands' string lengths for use in padding. + commandsMaxUseLen int + commandsMaxCommandPathLen int + commandsMaxNameLen int + // commandsAreSorted defines, if command slice are sorted or not. + commandsAreSorted bool + // commandCalledAs is the name or alias value used to call this command. + commandCalledAs struct { + name string + called bool + } + + // args is actual args parsed from flags. + args []string + // flagErrorBuf contains all error messages from pflag. + flagErrorBuf *bytes.Buffer + // flags is full set of flags. + flags *flag.FlagSet + // pflags contains persistent flags. + pflags *flag.FlagSet + // lflags contains local flags. + lflags *flag.FlagSet + // iflags contains inherited flags. + iflags *flag.FlagSet + // parentsPflags is all persistent flags of cmd's parents. + parentsPflags *flag.FlagSet + // globNormFunc is the global normalization function + // that we can use on every pflag set and children commands + globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName + + // usageFunc is usage func defined by user. + usageFunc func(*Command) error + // usageTemplate is usage template defined by user. + usageTemplate string + // flagErrorFunc is func defined by user and it's called when the parsing of + // flags returns an error. + flagErrorFunc func(*Command, error) error + // helpTemplate is help template defined by user. + helpTemplate string + // helpFunc is help func defined by user. + helpFunc func(*Command, []string) + // helpCommand is command with usage 'help'. If it's not defined by user, + // cobra uses default help command. + helpCommand *Command + // versionTemplate is the version template defined by user. + versionTemplate string + + // inReader is a reader defined by the user that replaces stdin + inReader io.Reader + // outWriter is a writer defined by the user that replaces stdout + outWriter io.Writer + // errWriter is a writer defined by the user that replaces stderr + errWriter io.Writer +} + +// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden +// particularly useful when testing. +func (c *Command) SetArgs(a []string) { + c.args = a +} + +// SetOutput sets the destination for usage and error messages. +// If output is nil, os.Stderr is used. +// Deprecated: Use SetOut and/or SetErr instead +func (c *Command) SetOutput(output io.Writer) { + c.outWriter = output + c.errWriter = output +} + +// SetOut sets the destination for usage messages. +// If newOut is nil, os.Stdout is used. +func (c *Command) SetOut(newOut io.Writer) { + c.outWriter = newOut +} + +// SetErr sets the destination for error messages. +// If newErr is nil, os.Stderr is used. +func (c *Command) SetErr(newErr io.Writer) { + c.errWriter = newErr +} + +// SetOut sets the source for input data +// If newIn is nil, os.Stdin is used. +func (c *Command) SetIn(newIn io.Reader) { + c.inReader = newIn +} + +// SetUsageFunc sets usage function. Usage can be defined by application. +func (c *Command) SetUsageFunc(f func(*Command) error) { + c.usageFunc = f +} + +// SetUsageTemplate sets usage template. Can be defined by Application. +func (c *Command) SetUsageTemplate(s string) { + c.usageTemplate = s +} + +// SetFlagErrorFunc sets a function to generate an error when flag parsing +// fails. +func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) { + c.flagErrorFunc = f +} + +// SetHelpFunc sets help function. Can be defined by Application. +func (c *Command) SetHelpFunc(f func(*Command, []string)) { + c.helpFunc = f +} + +// SetHelpCommand sets help command. +func (c *Command) SetHelpCommand(cmd *Command) { + c.helpCommand = cmd +} + +// SetHelpTemplate sets help template to be used. Application can use it to set custom template. +func (c *Command) SetHelpTemplate(s string) { + c.helpTemplate = s +} + +// SetVersionTemplate sets version template to be used. Application can use it to set custom template. +func (c *Command) SetVersionTemplate(s string) { + c.versionTemplate = s +} + +// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. +// The user should not have a cyclic dependency on commands. +func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) { + c.Flags().SetNormalizeFunc(n) + c.PersistentFlags().SetNormalizeFunc(n) + c.globNormFunc = n + + for _, command := range c.commands { + command.SetGlobalNormalizationFunc(n) + } +} + +// OutOrStdout returns output to stdout. +func (c *Command) OutOrStdout() io.Writer { + return c.getOut(os.Stdout) +} + +// OutOrStderr returns output to stderr +func (c *Command) OutOrStderr() io.Writer { + return c.getOut(os.Stderr) +} + +// ErrOrStderr returns output to stderr +func (c *Command) ErrOrStderr() io.Writer { + return c.getErr(os.Stderr) +} + +// ErrOrStderr returns output to stderr +func (c *Command) InOrStdin() io.Reader { + return c.getIn(os.Stdin) +} + +func (c *Command) getOut(def io.Writer) io.Writer { + if c.outWriter != nil { + return c.outWriter + } + if c.HasParent() { + return c.parent.getOut(def) + } + return def +} + +func (c *Command) getErr(def io.Writer) io.Writer { + if c.errWriter != nil { + return c.errWriter + } + if c.HasParent() { + return c.parent.getErr(def) + } + return def +} + +func (c *Command) getIn(def io.Reader) io.Reader { + if c.inReader != nil { + return c.inReader + } + if c.HasParent() { + return c.parent.getIn(def) + } + return def +} + +// UsageFunc returns either the function set by SetUsageFunc for this command +// or a parent, or it returns a default usage function. +func (c *Command) UsageFunc() (f func(*Command) error) { + if c.usageFunc != nil { + return c.usageFunc + } + if c.HasParent() { + return c.Parent().UsageFunc() + } + return func(c *Command) error { + c.mergePersistentFlags() + err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c) + if err != nil { + c.Println(err) + } + return err + } +} + +// Usage puts out the usage for the command. +// Used when a user provides invalid input. +// Can be defined by user by overriding UsageFunc. +func (c *Command) Usage() error { + return c.UsageFunc()(c) +} + +// HelpFunc returns either the function set by SetHelpFunc for this command +// or a parent, or it returns a function with default help behavior. +func (c *Command) HelpFunc() func(*Command, []string) { + if c.helpFunc != nil { + return c.helpFunc + } + if c.HasParent() { + return c.Parent().HelpFunc() + } + return func(c *Command, a []string) { + c.mergePersistentFlags() + err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c) + if err != nil { + c.Println(err) + } + } +} + +// Help puts out the help for the command. +// Used when a user calls help [command]. +// Can be defined by user by overriding HelpFunc. +func (c *Command) Help() error { + c.HelpFunc()(c, []string{}) + return nil +} + +// UsageString returns usage string. +func (c *Command) UsageString() string { + // Storing normal writers + tmpOutput := c.outWriter + tmpErr := c.errWriter + + bb := new(bytes.Buffer) + c.outWriter = bb + c.errWriter = bb + + c.Usage() + + // Setting things back to normal + c.outWriter = tmpOutput + c.errWriter = tmpErr + + return bb.String() +} + +// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this +// command or a parent, or it returns a function which returns the original +// error. +func (c *Command) FlagErrorFunc() (f func(*Command, error) error) { + if c.flagErrorFunc != nil { + return c.flagErrorFunc + } + + if c.HasParent() { + return c.parent.FlagErrorFunc() + } + return func(c *Command, err error) error { + return err + } +} + +var minUsagePadding = 25 + +// UsagePadding return padding for the usage. +func (c *Command) UsagePadding() int { + if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen { + return minUsagePadding + } + return c.parent.commandsMaxUseLen +} + +var minCommandPathPadding = 11 + +// CommandPathPadding return padding for the command path. +func (c *Command) CommandPathPadding() int { + if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen { + return minCommandPathPadding + } + return c.parent.commandsMaxCommandPathLen +} + +var minNamePadding = 11 + +// NamePadding returns padding for the name. +func (c *Command) NamePadding() int { + if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen { + return minNamePadding + } + return c.parent.commandsMaxNameLen +} + +// UsageTemplate returns usage template for the command. +func (c *Command) UsageTemplate() string { + if c.usageTemplate != "" { + return c.usageTemplate + } + + if c.HasParent() { + return c.parent.UsageTemplate() + } + return `Usage:{{if .Runnable}} + {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} + +Aliases: + {{.NameAndAliases}}{{end}}{{if .HasExample}} + +Examples: +{{.Example}}{{end}}{{if .HasAvailableSubCommands}} + +Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} + +Global Flags: +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} + +Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} + {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` +} + +// HelpTemplate return help template for the command. +func (c *Command) HelpTemplate() string { + if c.helpTemplate != "" { + return c.helpTemplate + } + + if c.HasParent() { + return c.parent.HelpTemplate() + } + return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} + +{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` +} + +// VersionTemplate return version template for the command. +func (c *Command) VersionTemplate() string { + if c.versionTemplate != "" { + return c.versionTemplate + } + + if c.HasParent() { + return c.parent.VersionTemplate() + } + return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}} +` +} + +func hasNoOptDefVal(name string, fs *flag.FlagSet) bool { + flag := fs.Lookup(name) + if flag == nil { + return false + } + return flag.NoOptDefVal != "" +} + +func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool { + if len(name) == 0 { + return false + } + + flag := fs.ShorthandLookup(name[:1]) + if flag == nil { + return false + } + return flag.NoOptDefVal != "" +} + +func stripFlags(args []string, c *Command) []string { + if len(args) == 0 { + return args + } + c.mergePersistentFlags() + + commands := []string{} + flags := c.Flags() + +Loop: + for len(args) > 0 { + s := args[0] + args = args[1:] + switch { + case s == "--": + // "--" terminates the flags + break Loop + case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags): + // If '--flag arg' then + // delete arg from args. + fallthrough // (do the same as below) + case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): + // If '-f arg' then + // delete 'arg' from args or break the loop if len(args) <= 1. + if len(args) <= 1 { + break Loop + } else { + args = args[1:] + continue + } + case s != "" && !strings.HasPrefix(s, "-"): + commands = append(commands, s) + } + } + + return commands +} + +// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like +// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]). +func argsMinusFirstX(args []string, x string) []string { + for i, y := range args { + if x == y { + ret := []string{} + ret = append(ret, args[:i]...) + ret = append(ret, args[i+1:]...) + return ret + } + } + return args +} + +func isFlagArg(arg string) bool { + return ((len(arg) >= 3 && arg[1] == '-') || + (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-')) +} + +// Find the target command given the args and command tree +// Meant to be run on the highest node. Only searches down. +func (c *Command) Find(args []string) (*Command, []string, error) { + var innerfind func(*Command, []string) (*Command, []string) + + innerfind = func(c *Command, innerArgs []string) (*Command, []string) { + argsWOflags := stripFlags(innerArgs, c) + if len(argsWOflags) == 0 { + return c, innerArgs + } + nextSubCmd := argsWOflags[0] + + cmd := c.findNext(nextSubCmd) + if cmd != nil { + return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd)) + } + return c, innerArgs + } + + commandFound, a := innerfind(c, args) + if commandFound.Args == nil { + return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound)) + } + return commandFound, a, nil +} + +func (c *Command) findSuggestions(arg string) string { + if c.DisableSuggestions { + return "" + } + if c.SuggestionsMinimumDistance <= 0 { + c.SuggestionsMinimumDistance = 2 + } + suggestionsString := "" + if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 { + suggestionsString += "\n\nDid you mean this?\n" + for _, s := range suggestions { + suggestionsString += fmt.Sprintf("\t%v\n", s) + } + } + return suggestionsString +} + +func (c *Command) findNext(next string) *Command { + matches := make([]*Command, 0) + for _, cmd := range c.commands { + if cmd.Name() == next || cmd.HasAlias(next) { + cmd.commandCalledAs.name = next + return cmd + } + if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) { + matches = append(matches, cmd) + } + } + + if len(matches) == 1 { + return matches[0] + } + + return nil +} + +// Traverse the command tree to find the command, and parse args for +// each parent. +func (c *Command) Traverse(args []string) (*Command, []string, error) { + flags := []string{} + inFlag := false + + for i, arg := range args { + switch { + // A long flag with a space separated value + case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="): + // TODO: this isn't quite right, we should really check ahead for 'true' or 'false' + inFlag = !hasNoOptDefVal(arg[2:], c.Flags()) + flags = append(flags, arg) + continue + // A short flag with a space separated value + case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()): + inFlag = true + flags = append(flags, arg) + continue + // The value for a flag + case inFlag: + inFlag = false + flags = append(flags, arg) + continue + // A flag without a value, or with an `=` separated value + case isFlagArg(arg): + flags = append(flags, arg) + continue + } + + cmd := c.findNext(arg) + if cmd == nil { + return c, args, nil + } + + if err := c.ParseFlags(flags); err != nil { + return nil, args, err + } + return cmd.Traverse(args[i+1:]) + } + return c, args, nil +} + +// SuggestionsFor provides suggestions for the typedName. +func (c *Command) SuggestionsFor(typedName string) []string { + suggestions := []string{} + for _, cmd := range c.commands { + if cmd.IsAvailableCommand() { + levenshteinDistance := ld(typedName, cmd.Name(), true) + suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance + suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName)) + if suggestByLevenshtein || suggestByPrefix { + suggestions = append(suggestions, cmd.Name()) + } + for _, explicitSuggestion := range cmd.SuggestFor { + if strings.EqualFold(typedName, explicitSuggestion) { + suggestions = append(suggestions, cmd.Name()) + } + } + } + } + return suggestions +} + +// VisitParents visits all parents of the command and invokes fn on each parent. +func (c *Command) VisitParents(fn func(*Command)) { + if c.HasParent() { + fn(c.Parent()) + c.Parent().VisitParents(fn) + } +} + +// Root finds root command. +func (c *Command) Root() *Command { + if c.HasParent() { + return c.Parent().Root() + } + return c +} + +// ArgsLenAtDash will return the length of c.Flags().Args at the moment +// when a -- was found during args parsing. +func (c *Command) ArgsLenAtDash() int { + return c.Flags().ArgsLenAtDash() +} + +func (c *Command) execute(a []string) (err error) { + if c == nil { + return fmt.Errorf("Called Execute() on a nil Command") + } + + if len(c.Deprecated) > 0 { + c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated) + } + + // initialize help and version flag at the last point possible to allow for user + // overriding + c.InitDefaultHelpFlag() + c.InitDefaultVersionFlag() + + err = c.ParseFlags(a) + if err != nil { + return c.FlagErrorFunc()(c, err) + } + + // If help is called, regardless of other flags, return we want help. + // Also say we need help if the command isn't runnable. + helpVal, err := c.Flags().GetBool("help") + if err != nil { + // should be impossible to get here as we always declare a help + // flag in InitDefaultHelpFlag() + c.Println("\"help\" flag declared as non-bool. Please correct your code") + return err + } + + if helpVal { + return flag.ErrHelp + } + + // for back-compat, only add version flag behavior if version is defined + if c.Version != "" { + versionVal, err := c.Flags().GetBool("version") + if err != nil { + c.Println("\"version\" flag declared as non-bool. Please correct your code") + return err + } + if versionVal { + err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c) + if err != nil { + c.Println(err) + } + return err + } + } + + if !c.Runnable() { + return flag.ErrHelp + } + + c.preRun() + + argWoFlags := c.Flags().Args() + if c.DisableFlagParsing { + argWoFlags = a + } + + if err := c.ValidateArgs(argWoFlags); err != nil { + return err + } + + for p := c; p != nil; p = p.Parent() { + if p.PersistentPreRunE != nil { + if err := p.PersistentPreRunE(c, argWoFlags); err != nil { + return err + } + break + } else if p.PersistentPreRun != nil { + p.PersistentPreRun(c, argWoFlags) + break + } + } + if c.PreRunE != nil { + if err := c.PreRunE(c, argWoFlags); err != nil { + return err + } + } else if c.PreRun != nil { + c.PreRun(c, argWoFlags) + } + + if err := c.validateRequiredFlags(); err != nil { + return err + } + if c.RunE != nil { + if err := c.RunE(c, argWoFlags); err != nil { + return err + } + } else { + c.Run(c, argWoFlags) + } + if c.PostRunE != nil { + if err := c.PostRunE(c, argWoFlags); err != nil { + return err + } + } else if c.PostRun != nil { + c.PostRun(c, argWoFlags) + } + for p := c; p != nil; p = p.Parent() { + if p.PersistentPostRunE != nil { + if err := p.PersistentPostRunE(c, argWoFlags); err != nil { + return err + } + break + } else if p.PersistentPostRun != nil { + p.PersistentPostRun(c, argWoFlags) + break + } + } + + return nil +} + +func (c *Command) preRun() { + for _, x := range initializers { + x() + } +} + +// Execute uses the args (os.Args[1:] by default) +// and run through the command tree finding appropriate matches +// for commands and then corresponding flags. +func (c *Command) Execute() error { + _, err := c.ExecuteC() + return err +} + +// ExecuteC executes the command. +func (c *Command) ExecuteC() (cmd *Command, err error) { + // Regardless of what command execute is called on, run on Root only + if c.HasParent() { + return c.Root().ExecuteC() + } + + // windows hook + if preExecHookFn != nil { + preExecHookFn(c) + } + + // initialize help as the last point possible to allow for user + // overriding + c.InitDefaultHelpCmd() + + args := c.args + + // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155 + if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" { + args = os.Args[1:] + } + + var flags []string + if c.TraverseChildren { + cmd, flags, err = c.Traverse(args) + } else { + cmd, flags, err = c.Find(args) + } + if err != nil { + // If found parse to a subcommand and then failed, talk about the subcommand + if cmd != nil { + c = cmd + } + if !c.SilenceErrors { + c.Println("Error:", err.Error()) + c.Printf("Run '%v --help' for usage.\n", c.CommandPath()) + } + return c, err + } + + cmd.commandCalledAs.called = true + if cmd.commandCalledAs.name == "" { + cmd.commandCalledAs.name = cmd.Name() + } + + err = cmd.execute(flags) + if err != nil { + // Always show help if requested, even if SilenceErrors is in + // effect + if err == flag.ErrHelp { + cmd.HelpFunc()(cmd, args) + return cmd, nil + } + + // If root command has SilentErrors flagged, + // all subcommands should respect it + if !cmd.SilenceErrors && !c.SilenceErrors { + c.Println("Error:", err.Error()) + } + + // If root command has SilentUsage flagged, + // all subcommands should respect it + if !cmd.SilenceUsage && !c.SilenceUsage { + c.Println(cmd.UsageString()) + } + } + return cmd, err +} + +func (c *Command) ValidateArgs(args []string) error { + if c.Args == nil { + return nil + } + return c.Args(c, args) +} + +func (c *Command) validateRequiredFlags() error { + flags := c.Flags() + missingFlagNames := []string{} + flags.VisitAll(func(pflag *flag.Flag) { + requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag] + if !found { + return + } + if (requiredAnnotation[0] == "true") && !pflag.Changed { + missingFlagNames = append(missingFlagNames, pflag.Name) + } + }) + + if len(missingFlagNames) > 0 { + return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`)) + } + return nil +} + +// InitDefaultHelpFlag adds default help flag to c. +// It is called automatically by executing the c or by calling help and usage. +// If c already has help flag, it will do nothing. +func (c *Command) InitDefaultHelpFlag() { + c.mergePersistentFlags() + if c.Flags().Lookup("help") == nil { + usage := "help for " + if c.Name() == "" { + usage += "this command" + } else { + usage += c.Name() + } + c.Flags().BoolP("help", "h", false, usage) + } +} + +// InitDefaultVersionFlag adds default version flag to c. +// It is called automatically by executing the c. +// If c already has a version flag, it will do nothing. +// If c.Version is empty, it will do nothing. +func (c *Command) InitDefaultVersionFlag() { + if c.Version == "" { + return + } + + c.mergePersistentFlags() + if c.Flags().Lookup("version") == nil { + usage := "version for " + if c.Name() == "" { + usage += "this command" + } else { + usage += c.Name() + } + c.Flags().Bool("version", false, usage) + } +} + +// InitDefaultHelpCmd adds default help command to c. +// It is called automatically by executing the c or by calling help and usage. +// If c already has help command or c has no subcommands, it will do nothing. +func (c *Command) InitDefaultHelpCmd() { + if !c.HasSubCommands() { + return + } + + if c.helpCommand == nil { + c.helpCommand = &Command{ + Use: "help [command]", + Short: "Help about any command", + Long: `Help provides help for any command in the application. +Simply type ` + c.Name() + ` help [path to command] for full details.`, + + Run: func(c *Command, args []string) { + cmd, _, e := c.Root().Find(args) + if cmd == nil || e != nil { + c.Printf("Unknown help topic %#q\n", args) + c.Root().Usage() + } else { + cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown + cmd.Help() + } + }, + } + } + c.RemoveCommand(c.helpCommand) + c.AddCommand(c.helpCommand) +} + +// ResetCommands delete parent, subcommand and help command from c. +func (c *Command) ResetCommands() { + c.parent = nil + c.commands = nil + c.helpCommand = nil + c.parentsPflags = nil +} + +// Sorts commands by their names. +type commandSorterByName []*Command + +func (c commandSorterByName) Len() int { return len(c) } +func (c commandSorterByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() } + +// Commands returns a sorted slice of child commands. +func (c *Command) Commands() []*Command { + // do not sort commands if it already sorted or sorting was disabled + if EnableCommandSorting && !c.commandsAreSorted { + sort.Sort(commandSorterByName(c.commands)) + c.commandsAreSorted = true + } + return c.commands +} + +// AddCommand adds one or more commands to this parent command. +func (c *Command) AddCommand(cmds ...*Command) { + for i, x := range cmds { + if cmds[i] == c { + panic("Command can't be a child of itself") + } + cmds[i].parent = c + // update max lengths + usageLen := len(x.Use) + if usageLen > c.commandsMaxUseLen { + c.commandsMaxUseLen = usageLen + } + commandPathLen := len(x.CommandPath()) + if commandPathLen > c.commandsMaxCommandPathLen { + c.commandsMaxCommandPathLen = commandPathLen + } + nameLen := len(x.Name()) + if nameLen > c.commandsMaxNameLen { + c.commandsMaxNameLen = nameLen + } + // If global normalization function exists, update all children + if c.globNormFunc != nil { + x.SetGlobalNormalizationFunc(c.globNormFunc) + } + c.commands = append(c.commands, x) + c.commandsAreSorted = false + } +} + +// RemoveCommand removes one or more commands from a parent command. +func (c *Command) RemoveCommand(cmds ...*Command) { + commands := []*Command{} +main: + for _, command := range c.commands { + for _, cmd := range cmds { + if command == cmd { + command.parent = nil + continue main + } + } + commands = append(commands, command) + } + c.commands = commands + // recompute all lengths + c.commandsMaxUseLen = 0 + c.commandsMaxCommandPathLen = 0 + c.commandsMaxNameLen = 0 + for _, command := range c.commands { + usageLen := len(command.Use) + if usageLen > c.commandsMaxUseLen { + c.commandsMaxUseLen = usageLen + } + commandPathLen := len(command.CommandPath()) + if commandPathLen > c.commandsMaxCommandPathLen { + c.commandsMaxCommandPathLen = commandPathLen + } + nameLen := len(command.Name()) + if nameLen > c.commandsMaxNameLen { + c.commandsMaxNameLen = nameLen + } + } +} + +// Print is a convenience method to Print to the defined output, fallback to Stderr if not set. +func (c *Command) Print(i ...interface{}) { + fmt.Fprint(c.OutOrStderr(), i...) +} + +// Println is a convenience method to Println to the defined output, fallback to Stderr if not set. +func (c *Command) Println(i ...interface{}) { + c.Print(fmt.Sprintln(i...)) +} + +// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set. +func (c *Command) Printf(format string, i ...interface{}) { + c.Print(fmt.Sprintf(format, i...)) +} + +// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErr(i ...interface{}) { + fmt.Fprint(c.ErrOrStderr(), i...) +} + +// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErrln(i ...interface{}) { + c.Print(fmt.Sprintln(i...)) +} + +// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErrf(format string, i ...interface{}) { + c.Print(fmt.Sprintf(format, i...)) +} + +// CommandPath returns the full path to this command. +func (c *Command) CommandPath() string { + if c.HasParent() { + return c.Parent().CommandPath() + " " + c.Name() + } + return c.Name() +} + +// UseLine puts out the full usage for a given command (including parents). +func (c *Command) UseLine() string { + var useline string + if c.HasParent() { + useline = c.parent.CommandPath() + " " + c.Use + } else { + useline = c.Use + } + if c.DisableFlagsInUseLine { + return useline + } + if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") { + useline += " [flags]" + } + return useline +} + +// DebugFlags used to determine which flags have been assigned to which commands +// and which persist. +func (c *Command) DebugFlags() { + c.Println("DebugFlags called on", c.Name()) + var debugflags func(*Command) + + debugflags = func(x *Command) { + if x.HasFlags() || x.HasPersistentFlags() { + c.Println(x.Name()) + } + if x.HasFlags() { + x.flags.VisitAll(func(f *flag.Flag) { + if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil { + c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]") + } else { + c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]") + } + }) + } + if x.HasPersistentFlags() { + x.pflags.VisitAll(func(f *flag.Flag) { + if x.HasFlags() { + if x.flags.Lookup(f.Name) == nil { + c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]") + } + } else { + c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]") + } + }) + } + c.Println(x.flagErrorBuf) + if x.HasSubCommands() { + for _, y := range x.commands { + debugflags(y) + } + } + } + + debugflags(c) +} + +// Name returns the command's name: the first word in the use line. +func (c *Command) Name() string { + name := c.Use + i := strings.Index(name, " ") + if i >= 0 { + name = name[:i] + } + return name +} + +// HasAlias determines if a given string is an alias of the command. +func (c *Command) HasAlias(s string) bool { + for _, a := range c.Aliases { + if a == s { + return true + } + } + return false +} + +// CalledAs returns the command name or alias that was used to invoke +// this command or an empty string if the command has not been called. +func (c *Command) CalledAs() string { + if c.commandCalledAs.called { + return c.commandCalledAs.name + } + return "" +} + +// hasNameOrAliasPrefix returns true if the Name or any of aliases start +// with prefix +func (c *Command) hasNameOrAliasPrefix(prefix string) bool { + if strings.HasPrefix(c.Name(), prefix) { + c.commandCalledAs.name = c.Name() + return true + } + for _, alias := range c.Aliases { + if strings.HasPrefix(alias, prefix) { + c.commandCalledAs.name = alias + return true + } + } + return false +} + +// NameAndAliases returns a list of the command name and all aliases +func (c *Command) NameAndAliases() string { + return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ") +} + +// HasExample determines if the command has example. +func (c *Command) HasExample() bool { + return len(c.Example) > 0 +} + +// Runnable determines if the command is itself runnable. +func (c *Command) Runnable() bool { + return c.Run != nil || c.RunE != nil +} + +// HasSubCommands determines if the command has children commands. +func (c *Command) HasSubCommands() bool { + return len(c.commands) > 0 +} + +// IsAvailableCommand determines if a command is available as a non-help command +// (this includes all non deprecated/hidden commands). +func (c *Command) IsAvailableCommand() bool { + if len(c.Deprecated) != 0 || c.Hidden { + return false + } + + if c.HasParent() && c.Parent().helpCommand == c { + return false + } + + if c.Runnable() || c.HasAvailableSubCommands() { + return true + } + + return false +} + +// IsAdditionalHelpTopicCommand determines if a command is an additional +// help topic command; additional help topic command is determined by the +// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that +// are runnable/hidden/deprecated. +// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924. +func (c *Command) IsAdditionalHelpTopicCommand() bool { + // if a command is runnable, deprecated, or hidden it is not a 'help' command + if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden { + return false + } + + // if any non-help sub commands are found, the command is not a 'help' command + for _, sub := range c.commands { + if !sub.IsAdditionalHelpTopicCommand() { + return false + } + } + + // the command either has no sub commands, or no non-help sub commands + return true +} + +// HasHelpSubCommands determines if a command has any available 'help' sub commands +// that need to be shown in the usage/help default template under 'additional help +// topics'. +func (c *Command) HasHelpSubCommands() bool { + // return true on the first found available 'help' sub command + for _, sub := range c.commands { + if sub.IsAdditionalHelpTopicCommand() { + return true + } + } + + // the command either has no sub commands, or no available 'help' sub commands + return false +} + +// HasAvailableSubCommands determines if a command has available sub commands that +// need to be shown in the usage/help default template under 'available commands'. +func (c *Command) HasAvailableSubCommands() bool { + // return true on the first found available (non deprecated/help/hidden) + // sub command + for _, sub := range c.commands { + if sub.IsAvailableCommand() { + return true + } + } + + // the command either has no sub commands, or no available (non deprecated/help/hidden) + // sub commands + return false +} + +// HasParent determines if the command is a child command. +func (c *Command) HasParent() bool { + return c.parent != nil +} + +// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist. +func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName { + return c.globNormFunc +} + +// Flags returns the complete FlagSet that applies +// to this command (local and persistent declared here and by all parents). +func (c *Command) Flags() *flag.FlagSet { + if c.flags == nil { + c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.flags.SetOutput(c.flagErrorBuf) + } + + return c.flags +} + +// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands. +func (c *Command) LocalNonPersistentFlags() *flag.FlagSet { + persistentFlags := c.PersistentFlags() + + out := flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.LocalFlags().VisitAll(func(f *flag.Flag) { + if persistentFlags.Lookup(f.Name) == nil { + out.AddFlag(f) + } + }) + return out +} + +// LocalFlags returns the local FlagSet specifically set in the current command. +func (c *Command) LocalFlags() *flag.FlagSet { + c.mergePersistentFlags() + + if c.lflags == nil { + c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.lflags.SetOutput(c.flagErrorBuf) + } + c.lflags.SortFlags = c.Flags().SortFlags + if c.globNormFunc != nil { + c.lflags.SetNormalizeFunc(c.globNormFunc) + } + + addToLocal := func(f *flag.Flag) { + if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil { + c.lflags.AddFlag(f) + } + } + c.Flags().VisitAll(addToLocal) + c.PersistentFlags().VisitAll(addToLocal) + return c.lflags +} + +// InheritedFlags returns all flags which were inherited from parent commands. +func (c *Command) InheritedFlags() *flag.FlagSet { + c.mergePersistentFlags() + + if c.iflags == nil { + c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.iflags.SetOutput(c.flagErrorBuf) + } + + local := c.LocalFlags() + if c.globNormFunc != nil { + c.iflags.SetNormalizeFunc(c.globNormFunc) + } + + c.parentsPflags.VisitAll(func(f *flag.Flag) { + if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { + c.iflags.AddFlag(f) + } + }) + return c.iflags +} + +// NonInheritedFlags returns all flags which were not inherited from parent commands. +func (c *Command) NonInheritedFlags() *flag.FlagSet { + return c.LocalFlags() +} + +// PersistentFlags returns the persistent FlagSet specifically set in the current command. +func (c *Command) PersistentFlags() *flag.FlagSet { + if c.pflags == nil { + c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.pflags.SetOutput(c.flagErrorBuf) + } + return c.pflags +} + +// ResetFlags deletes all flags from command. +func (c *Command) ResetFlags() { + c.flagErrorBuf = new(bytes.Buffer) + c.flagErrorBuf.Reset() + c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.flags.SetOutput(c.flagErrorBuf) + c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.pflags.SetOutput(c.flagErrorBuf) + + c.lflags = nil + c.iflags = nil + c.parentsPflags = nil +} + +// HasFlags checks if the command contains any flags (local plus persistent from the entire structure). +func (c *Command) HasFlags() bool { + return c.Flags().HasFlags() +} + +// HasPersistentFlags checks if the command contains persistent flags. +func (c *Command) HasPersistentFlags() bool { + return c.PersistentFlags().HasFlags() +} + +// HasLocalFlags checks if the command has flags specifically declared locally. +func (c *Command) HasLocalFlags() bool { + return c.LocalFlags().HasFlags() +} + +// HasInheritedFlags checks if the command has flags inherited from its parent command. +func (c *Command) HasInheritedFlags() bool { + return c.InheritedFlags().HasFlags() +} + +// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire +// structure) which are not hidden or deprecated. +func (c *Command) HasAvailableFlags() bool { + return c.Flags().HasAvailableFlags() +} + +// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated. +func (c *Command) HasAvailablePersistentFlags() bool { + return c.PersistentFlags().HasAvailableFlags() +} + +// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden +// or deprecated. +func (c *Command) HasAvailableLocalFlags() bool { + return c.LocalFlags().HasAvailableFlags() +} + +// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are +// not hidden or deprecated. +func (c *Command) HasAvailableInheritedFlags() bool { + return c.InheritedFlags().HasAvailableFlags() +} + +// Flag climbs up the command tree looking for matching flag. +func (c *Command) Flag(name string) (flag *flag.Flag) { + flag = c.Flags().Lookup(name) + + if flag == nil { + flag = c.persistentFlag(name) + } + + return +} + +// Recursively find matching persistent flag. +func (c *Command) persistentFlag(name string) (flag *flag.Flag) { + if c.HasPersistentFlags() { + flag = c.PersistentFlags().Lookup(name) + } + + if flag == nil { + c.updateParentsPflags() + flag = c.parentsPflags.Lookup(name) + } + return +} + +// ParseFlags parses persistent flag tree and local flags. +func (c *Command) ParseFlags(args []string) error { + if c.DisableFlagParsing { + return nil + } + + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + beforeErrorBufLen := c.flagErrorBuf.Len() + c.mergePersistentFlags() + + //do it here after merging all flags and just before parse + c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + + err := c.Flags().Parse(args) + // Print warnings if they occurred (e.g. deprecated flag messages). + if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil { + c.Print(c.flagErrorBuf.String()) + } + + return err +} + +// Parent returns a commands parent command. +func (c *Command) Parent() *Command { + return c.parent +} + +// mergePersistentFlags merges c.PersistentFlags() to c.Flags() +// and adds missing persistent flags of all parents. +func (c *Command) mergePersistentFlags() { + c.updateParentsPflags() + c.Flags().AddFlagSet(c.PersistentFlags()) + c.Flags().AddFlagSet(c.parentsPflags) +} + +// updateParentsPflags updates c.parentsPflags by adding +// new persistent flags of all parents. +// If c.parentsPflags == nil, it makes new. +func (c *Command) updateParentsPflags() { + if c.parentsPflags == nil { + c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.parentsPflags.SetOutput(c.flagErrorBuf) + c.parentsPflags.SortFlags = false + } + + if c.globNormFunc != nil { + c.parentsPflags.SetNormalizeFunc(c.globNormFunc) + } + + c.Root().PersistentFlags().AddFlagSet(flag.CommandLine) + + c.VisitParents(func(parent *Command) { + c.parentsPflags.AddFlagSet(parent.PersistentFlags()) + }) +} diff --git a/vendor/github.com/spf13/cobra/command_win.go b/vendor/github.com/spf13/cobra/command_win.go new file mode 100644 index 00000000..8768b173 --- /dev/null +++ b/vendor/github.com/spf13/cobra/command_win.go @@ -0,0 +1,26 @@ +// +build windows + +package cobra + +import ( + "fmt" + "os" + "time" + + "github.com/inconshreveable/mousetrap" +) + +var preExecHookFn = preExecHook + +func preExecHook(c *Command) { + if MousetrapHelpText != "" && mousetrap.StartedByExplorer() { + c.Print(MousetrapHelpText) + if MousetrapDisplayDuration > 0 { + time.Sleep(MousetrapDisplayDuration) + } else { + c.Println("Press return to continue...") + fmt.Scanln() + } + os.Exit(1) + } +} diff --git a/vendor/github.com/spf13/cobra/go.mod b/vendor/github.com/spf13/cobra/go.mod new file mode 100644 index 00000000..9a9eb65a --- /dev/null +++ b/vendor/github.com/spf13/cobra/go.mod @@ -0,0 +1,13 @@ +module github.com/spf13/cobra + +go 1.12 + +require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/cpuguy83/go-md2man v1.0.10 + github.com/inconshreveable/mousetrap v1.0.0 + github.com/mitchellh/go-homedir v1.1.0 + github.com/spf13/pflag v1.0.3 + github.com/spf13/viper v1.3.2 + gopkg.in/yaml.v2 v2.2.2 +) diff --git a/vendor/github.com/spf13/cobra/go.sum b/vendor/github.com/spf13/cobra/go.sum new file mode 100644 index 00000000..9761f4d0 --- /dev/null +++ b/vendor/github.com/spf13/cobra/go.sum @@ -0,0 +1,51 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/spf13/cobra/powershell_completions.go b/vendor/github.com/spf13/cobra/powershell_completions.go new file mode 100644 index 00000000..756c61b9 --- /dev/null +++ b/vendor/github.com/spf13/cobra/powershell_completions.go @@ -0,0 +1,100 @@ +// PowerShell completions are based on the amazing work from clap: +// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs +// +// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but +// can be downloaded separately for windows 7 or 8.1). + +package cobra + +import ( + "bytes" + "fmt" + "io" + "os" + "strings" + + "github.com/spf13/pflag" +) + +var powerShellCompletionTemplate = `using namespace System.Management.Automation +using namespace System.Management.Automation.Language +Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock { + param($wordToComplete, $commandAst, $cursorPosition) + $commandElements = $commandAst.CommandElements + $command = @( + '%s' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-')) { + break + } + $element.Value + } + ) -join ';' + $completions = @(switch ($command) {%s + }) + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText +}` + +func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) { + var cmdName string + if previousCommandName == "" { + cmdName = cmd.Name() + } else { + cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name()) + } + + fmt.Fprintf(out, "\n '%s' {", cmdName) + + cmd.Flags().VisitAll(func(flag *pflag.Flag) { + if nonCompletableFlag(flag) { + return + } + usage := escapeStringForPowerShell(flag.Usage) + if len(flag.Shorthand) > 0 { + fmt.Fprintf(out, "\n [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage) + } + fmt.Fprintf(out, "\n [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage) + }) + + for _, subCmd := range cmd.Commands() { + usage := escapeStringForPowerShell(subCmd.Short) + fmt.Fprintf(out, "\n [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage) + } + + fmt.Fprint(out, "\n break\n }") + + for _, subCmd := range cmd.Commands() { + generatePowerShellSubcommandCases(out, subCmd, cmdName) + } +} + +func escapeStringForPowerShell(s string) string { + return strings.Replace(s, "'", "''", -1) +} + +// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer. +func (c *Command) GenPowerShellCompletion(w io.Writer) error { + buf := new(bytes.Buffer) + + var subCommandCases bytes.Buffer + generatePowerShellSubcommandCases(&subCommandCases, c, "") + fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String()) + + _, err := buf.WriteTo(w) + return err +} + +// GenPowerShellCompletionFile generates PowerShell completion file. +func (c *Command) GenPowerShellCompletionFile(filename string) error { + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + return c.GenPowerShellCompletion(outFile) +} diff --git a/vendor/github.com/spf13/cobra/powershell_completions.md b/vendor/github.com/spf13/cobra/powershell_completions.md new file mode 100644 index 00000000..afed8024 --- /dev/null +++ b/vendor/github.com/spf13/cobra/powershell_completions.md @@ -0,0 +1,14 @@ +# Generating PowerShell Completions For Your Own cobra.Command + +Cobra can generate PowerShell completion scripts. Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles. + +# What's supported + +- Completion for subcommands using their `.Short` description +- Completion for non-hidden flags using their `.Name` and `.Shorthand` + +# What's not yet supported + +- Command aliases +- Required, filename or custom flags (they will work like normal flags) +- Custom completion scripts diff --git a/vendor/github.com/spf13/cobra/shell_completions.go b/vendor/github.com/spf13/cobra/shell_completions.go new file mode 100644 index 00000000..ba0af9cb --- /dev/null +++ b/vendor/github.com/spf13/cobra/shell_completions.go @@ -0,0 +1,85 @@ +package cobra + +import ( + "github.com/spf13/pflag" +) + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, +// and causes your command to report an error if invoked without the flag. +func (c *Command) MarkFlagRequired(name string) error { + return MarkFlagRequired(c.Flags(), name) +} + +// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists, +// and causes your command to report an error if invoked without the flag. +func (c *Command) MarkPersistentFlagRequired(name string) error { + return MarkFlagRequired(c.PersistentFlags(), name) +} + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, +// and causes your command to report an error if invoked without the flag. +func MarkFlagRequired(flags *pflag.FlagSet, name string) error { + return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func (c *Command) MarkFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(c.Flags(), name, extensions...) +} + +// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists. +// Generated bash autocompletion will call the bash function f for the flag. +func (c *Command) MarkFlagCustom(name string, f string) error { + return MarkFlagCustom(c.Flags(), name, f) +} + +// MarkPersistentFlagFilename instructs the various shell completion +// implementations to limit completions for this persistent flag to the +// specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(c.PersistentFlags(), name, extensions...) +} + +// MarkFlagFilename instructs the various shell completion implementations to +// limit completions for this flag to the specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { + return flags.SetAnnotation(name, BashCompFilenameExt, extensions) +} + +// MarkFlagCustom instructs the various shell completion implementations to +// limit completions for this flag to the specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error { + return flags.SetAnnotation(name, BashCompCustom, []string{f}) +} + +// MarkFlagDirname instructs the various shell completion implementations to +// complete only directories with this named flag. +// +// Shell Completion compatibility matrix: zsh +func (c *Command) MarkFlagDirname(name string) error { + return MarkFlagDirname(c.Flags(), name) +} + +// MarkPersistentFlagDirname instructs the various shell completion +// implementations to complete only directories with this persistent named flag. +// +// Shell Completion compatibility matrix: zsh +func (c *Command) MarkPersistentFlagDirname(name string) error { + return MarkFlagDirname(c.PersistentFlags(), name) +} + +// MarkFlagDirname instructs the various shell completion implementations to +// complete only directories with this specified flag. +// +// Shell Completion compatibility matrix: zsh +func MarkFlagDirname(flags *pflag.FlagSet, name string) error { + zshPattern := "-(/)" + return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern}) +} diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go new file mode 100644 index 00000000..12755482 --- /dev/null +++ b/vendor/github.com/spf13/cobra/zsh_completions.go @@ -0,0 +1,336 @@ +package cobra + +import ( + "encoding/json" + "fmt" + "io" + "os" + "sort" + "strings" + "text/template" + + "github.com/spf13/pflag" +) + +const ( + zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation" + zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion" + zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion" + zshCompDirname = "cobra_annotations_zsh_dirname" +) + +var ( + zshCompFuncMap = template.FuncMap{ + "genZshFuncName": zshCompGenFuncName, + "extractFlags": zshCompExtractFlag, + "genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments, + "extractArgsCompletions": zshCompExtractArgumentCompletionHintsForRendering, + } + zshCompletionText = ` +{{/* should accept Command (that contains subcommands) as parameter */}} +{{define "argumentsC" -}} +{{ $cmdPath := genZshFuncName .}} +function {{$cmdPath}} { + local -a commands + + _arguments -C \{{- range extractFlags .}} + {{genFlagEntryForZshArguments .}} \{{- end}} + "1: :->cmnds" \ + "*::arg:->args" + + case $state in + cmnds) + commands=({{range .Commands}}{{if not .Hidden}} + "{{.Name}}:{{.Short}}"{{end}}{{end}} + ) + _describe "command" commands + ;; + esac + + case "$words[1]" in {{- range .Commands}}{{if not .Hidden}} + {{.Name}}) + {{$cmdPath}}_{{.Name}} + ;;{{end}}{{end}} + esac +} +{{range .Commands}}{{if not .Hidden}} +{{template "selectCmdTemplate" .}} +{{- end}}{{end}} +{{- end}} + +{{/* should accept Command without subcommands as parameter */}} +{{define "arguments" -}} +function {{genZshFuncName .}} { +{{" _arguments"}}{{range extractFlags .}} \ + {{genFlagEntryForZshArguments . -}} +{{end}}{{range extractArgsCompletions .}} \ + {{.}}{{end}} +} +{{end}} + +{{/* dispatcher for commands with or without subcommands */}} +{{define "selectCmdTemplate" -}} +{{if .Hidden}}{{/* ignore hidden*/}}{{else -}} +{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}} +{{- end}} +{{- end}} + +{{/* template entry point */}} +{{define "Main" -}} +#compdef _{{.Name}} {{.Name}} + +{{template "selectCmdTemplate" .}} +{{end}} +` +) + +// zshCompArgsAnnotation is used to encode/decode zsh completion for +// arguments to/from Command.Annotations. +type zshCompArgsAnnotation map[int]zshCompArgHint + +type zshCompArgHint struct { + // Indicates the type of the completion to use. One of: + // zshCompArgumentFilenameComp or zshCompArgumentWordComp + Tipe string `json:"type"` + + // A value for the type above (globs for file completion or words) + Options []string `json:"options"` +} + +// GenZshCompletionFile generates zsh completion file. +func (c *Command) GenZshCompletionFile(filename string) error { + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + return c.GenZshCompletion(outFile) +} + +// GenZshCompletion generates a zsh completion file and writes to the passed +// writer. The completion always run on the root command regardless of the +// command it was called from. +func (c *Command) GenZshCompletion(w io.Writer) error { + tmpl, err := template.New("Main").Funcs(zshCompFuncMap).Parse(zshCompletionText) + if err != nil { + return fmt.Errorf("error creating zsh completion template: %v", err) + } + return tmpl.Execute(w, c.Root()) +} + +// MarkZshCompPositionalArgumentFile marks the specified argument (first +// argument is 1) as completed by file selection. patterns (e.g. "*.txt") are +// optional - if not provided the completion will search for all files. +func (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error { + if argPosition < 1 { + return fmt.Errorf("Invalid argument position (%d)", argPosition) + } + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return err + } + if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) { + return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition) + } + annotation[argPosition] = zshCompArgHint{ + Tipe: zshCompArgumentFilenameComp, + Options: patterns, + } + return c.zshCompSetArgsAnnotations(annotation) +} + +// MarkZshCompPositionalArgumentWords marks the specified positional argument +// (first argument is 1) as completed by the provided words. At east one word +// must be provided, spaces within words will be offered completion with +// "word\ word". +func (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error { + if argPosition < 1 { + return fmt.Errorf("Invalid argument position (%d)", argPosition) + } + if len(words) == 0 { + return fmt.Errorf("Trying to set empty word list for positional argument %d", argPosition) + } + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return err + } + if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) { + return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition) + } + annotation[argPosition] = zshCompArgHint{ + Tipe: zshCompArgumentWordComp, + Options: words, + } + return c.zshCompSetArgsAnnotations(annotation) +} + +func zshCompExtractArgumentCompletionHintsForRendering(c *Command) ([]string, error) { + var result []string + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return nil, err + } + for k, v := range annotation { + s, err := zshCompRenderZshCompArgHint(k, v) + if err != nil { + return nil, err + } + result = append(result, s) + } + if len(c.ValidArgs) > 0 { + if _, positionOneExists := annotation[1]; !positionOneExists { + s, err := zshCompRenderZshCompArgHint(1, zshCompArgHint{ + Tipe: zshCompArgumentWordComp, + Options: c.ValidArgs, + }) + if err != nil { + return nil, err + } + result = append(result, s) + } + } + sort.Strings(result) + return result, nil +} + +func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) { + switch t := z.Tipe; t { + case zshCompArgumentFilenameComp: + var globs []string + for _, g := range z.Options { + globs = append(globs, fmt.Sprintf(`-g "%s"`, g)) + } + return fmt.Sprintf(`'%d: :_files %s'`, i, strings.Join(globs, " ")), nil + case zshCompArgumentWordComp: + var words []string + for _, w := range z.Options { + words = append(words, fmt.Sprintf("%q", w)) + } + return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil + default: + return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t) + } +} + +func (c *Command) zshcompArgsAnnotationnIsDuplicatePosition(annotation zshCompArgsAnnotation, position int) bool { + _, dup := annotation[position] + return dup +} + +func (c *Command) zshCompGetArgsAnnotations() (zshCompArgsAnnotation, error) { + annotation := make(zshCompArgsAnnotation) + annotationString, ok := c.Annotations[zshCompArgumentAnnotation] + if !ok { + return annotation, nil + } + err := json.Unmarshal([]byte(annotationString), &annotation) + if err != nil { + return annotation, fmt.Errorf("Error unmarshaling zsh argument annotation: %v", err) + } + return annotation, nil +} + +func (c *Command) zshCompSetArgsAnnotations(annotation zshCompArgsAnnotation) error { + jsn, err := json.Marshal(annotation) + if err != nil { + return fmt.Errorf("Error marshaling zsh argument annotation: %v", err) + } + if c.Annotations == nil { + c.Annotations = make(map[string]string) + } + c.Annotations[zshCompArgumentAnnotation] = string(jsn) + return nil +} + +func zshCompGenFuncName(c *Command) string { + if c.HasParent() { + return zshCompGenFuncName(c.Parent()) + "_" + c.Name() + } + return "_" + c.Name() +} + +func zshCompExtractFlag(c *Command) []*pflag.Flag { + var flags []*pflag.Flag + c.LocalFlags().VisitAll(func(f *pflag.Flag) { + if !f.Hidden { + flags = append(flags, f) + } + }) + c.InheritedFlags().VisitAll(func(f *pflag.Flag) { + if !f.Hidden { + flags = append(flags, f) + } + }) + return flags +} + +// zshCompGenFlagEntryForArguments returns an entry that matches _arguments +// zsh-completion parameters. It's too complicated to generate in a template. +func zshCompGenFlagEntryForArguments(f *pflag.Flag) string { + if f.Name == "" || f.Shorthand == "" { + return zshCompGenFlagEntryForSingleOptionFlag(f) + } + return zshCompGenFlagEntryForMultiOptionFlag(f) +} + +func zshCompGenFlagEntryForSingleOptionFlag(f *pflag.Flag) string { + var option, multiMark, extras string + + if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) { + multiMark = "*" + } + + option = "--" + f.Name + if option == "--" { + option = "-" + f.Shorthand + } + extras = zshCompGenFlagEntryExtras(f) + + return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, zshCompQuoteFlagDescription(f.Usage), extras) +} + +func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string { + var options, parenMultiMark, curlyMultiMark, extras string + + if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) { + parenMultiMark = "*" + curlyMultiMark = "\\*" + } + + options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`, + parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name) + extras = zshCompGenFlagEntryExtras(f) + + return fmt.Sprintf(`%s'[%s]%s'`, options, zshCompQuoteFlagDescription(f.Usage), extras) +} + +func zshCompGenFlagEntryExtras(f *pflag.Flag) string { + if f.NoOptDefVal != "" { + return "" + } + + extras := ":" // allow options for flag (even without assistance) + for key, values := range f.Annotations { + switch key { + case zshCompDirname: + extras = fmt.Sprintf(":filename:_files -g %q", values[0]) + case BashCompFilenameExt: + extras = ":filename:_files" + for _, pattern := range values { + extras = extras + fmt.Sprintf(` -g "%s"`, pattern) + } + } + } + + return extras +} + +func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { + return strings.Contains(f.Value.Type(), "Slice") || + strings.Contains(f.Value.Type(), "Array") +} + +func zshCompQuoteFlagDescription(s string) string { + return strings.Replace(s, "'", `'\''`, -1) +} diff --git a/vendor/github.com/spf13/cobra/zsh_completions.md b/vendor/github.com/spf13/cobra/zsh_completions.md new file mode 100644 index 00000000..df9c2eac --- /dev/null +++ b/vendor/github.com/spf13/cobra/zsh_completions.md @@ -0,0 +1,39 @@ +## Generating Zsh Completion for your cobra.Command + +Cobra supports native Zsh completion generated from the root `cobra.Command`. +The generated completion script should be put somewhere in your `$fpath` named +`_`. + +### What's Supported + +* Completion for all non-hidden subcommands using their `.Short` description. +* Completion for all non-hidden flags using the following rules: + * Filename completion works by marking the flag with `cmd.MarkFlagFilename...` + family of commands. + * The requirement for argument to the flag is decided by the `.NoOptDefVal` + flag value - if it's empty then completion will expect an argument. + * Flags of one of the various `*Array` and `*Slice` types supports multiple + specifications (with or without argument depending on the specific type). +* Completion of positional arguments using the following rules: + * Argument position for all options below starts at `1`. If argument position + `0` is requested it will raise an error. + * Use `command.MarkZshCompPositionalArgumentFile` to complete filenames. Glob + patterns (e.g. `"*.log"`) are optional - if not specified it will offer to + complete all file types. + * Use `command.MarkZshCompPositionalArgumentWords` to offer specific words for + completion. At least one word is required. + * It's possible to specify completion for some arguments and leave some + unspecified (e.g. offer words for second argument but nothing for first + argument). This will cause no completion for first argument but words + completion for second argument. + * If no argument completion was specified for 1st argument (but optionally was + specified for 2nd) and the command has `ValidArgs` it will be used as + completion options for 1st argument. + * Argument completions only offered for commands with no subcommands. + +### What's not yet Supported + +* Custom completion scripts are not supported yet (We should probably create zsh + specific one, doesn't make sense to re-use the bash one as the functions will + be different). +* Whatever other feature you're looking for and doesn't exist :) diff --git a/vendor/github.com/spf13/jwalterweatherman/.gitignore b/vendor/github.com/spf13/jwalterweatherman/.gitignore new file mode 100644 index 00000000..a71f88af --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.bench +go.sum \ No newline at end of file diff --git a/vendor/github.com/spf13/jwalterweatherman/default_notepad.go b/vendor/github.com/spf13/jwalterweatherman/default_notepad.go new file mode 100644 index 00000000..a018c15c --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/default_notepad.go @@ -0,0 +1,111 @@ +// Copyright © 2016 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package jwalterweatherman + +import ( + "io" + "io/ioutil" + "log" + "os" +) + +var ( + TRACE *log.Logger + DEBUG *log.Logger + INFO *log.Logger + WARN *log.Logger + ERROR *log.Logger + CRITICAL *log.Logger + FATAL *log.Logger + + LOG *log.Logger + FEEDBACK *Feedback + + defaultNotepad *Notepad +) + +func reloadDefaultNotepad() { + TRACE = defaultNotepad.TRACE + DEBUG = defaultNotepad.DEBUG + INFO = defaultNotepad.INFO + WARN = defaultNotepad.WARN + ERROR = defaultNotepad.ERROR + CRITICAL = defaultNotepad.CRITICAL + FATAL = defaultNotepad.FATAL + + LOG = defaultNotepad.LOG + FEEDBACK = defaultNotepad.FEEDBACK +} + +func init() { + defaultNotepad = NewNotepad(LevelError, LevelWarn, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime) + reloadDefaultNotepad() +} + +// SetLogThreshold set the log threshold for the default notepad. Trace by default. +func SetLogThreshold(threshold Threshold) { + defaultNotepad.SetLogThreshold(threshold) + reloadDefaultNotepad() +} + +// SetLogOutput set the log output for the default notepad. Discarded by default. +func SetLogOutput(handle io.Writer) { + defaultNotepad.SetLogOutput(handle) + reloadDefaultNotepad() +} + +// SetStdoutThreshold set the standard output threshold for the default notepad. +// Info by default. +func SetStdoutThreshold(threshold Threshold) { + defaultNotepad.SetStdoutThreshold(threshold) + reloadDefaultNotepad() +} + +// SetStdoutOutput set the stdout output for the default notepad. Default is stdout. +func SetStdoutOutput(handle io.Writer) { + defaultNotepad.outHandle = handle + defaultNotepad.init() + reloadDefaultNotepad() +} + +// SetPrefix set the prefix for the default logger. Empty by default. +func SetPrefix(prefix string) { + defaultNotepad.SetPrefix(prefix) + reloadDefaultNotepad() +} + +// SetFlags set the flags for the default logger. "log.Ldate | log.Ltime" by default. +func SetFlags(flags int) { + defaultNotepad.SetFlags(flags) + reloadDefaultNotepad() +} + +// SetLogListeners configures the default logger with one or more log listeners. +func SetLogListeners(l ...LogListener) { + defaultNotepad.logListeners = l + defaultNotepad.init() + reloadDefaultNotepad() +} + +// Level returns the current global log threshold. +func LogThreshold() Threshold { + return defaultNotepad.logThreshold +} + +// Level returns the current global output threshold. +func StdoutThreshold() Threshold { + return defaultNotepad.stdoutThreshold +} + +// GetStdoutThreshold returns the defined Treshold for the log logger. +func GetLogThreshold() Threshold { + return defaultNotepad.GetLogThreshold() +} + +// GetStdoutThreshold returns the Treshold for the stdout logger. +func GetStdoutThreshold() Threshold { + return defaultNotepad.GetStdoutThreshold() +} diff --git a/vendor/github.com/spf13/jwalterweatherman/go.mod b/vendor/github.com/spf13/jwalterweatherman/go.mod new file mode 100644 index 00000000..1dbcfd3e --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/go.mod @@ -0,0 +1,7 @@ +module github.com/spf13/jwalterweatherman + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.2.2 +) diff --git a/vendor/github.com/spf13/jwalterweatherman/log_counter.go b/vendor/github.com/spf13/jwalterweatherman/log_counter.go new file mode 100644 index 00000000..41285f3d --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/log_counter.go @@ -0,0 +1,46 @@ +// Copyright © 2016 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package jwalterweatherman + +import ( + "io" + "sync/atomic" +) + +// Counter is an io.Writer that increments a counter on Write. +type Counter struct { + count uint64 +} + +func (c *Counter) incr() { + atomic.AddUint64(&c.count, 1) +} + +// Reset resets the counter. +func (c *Counter) Reset() { + atomic.StoreUint64(&c.count, 0) +} + +// Count returns the current count. +func (c *Counter) Count() uint64 { + return atomic.LoadUint64(&c.count) +} + +func (c *Counter) Write(p []byte) (n int, err error) { + c.incr() + return len(p), nil +} + +// LogCounter creates a LogListener that counts log statements >= the given threshold. +func LogCounter(counter *Counter, t1 Threshold) LogListener { + return func(t2 Threshold) io.Writer { + if t2 < t1 { + // Not interested in this threshold. + return nil + } + return counter + } +} diff --git a/vendor/github.com/spf13/jwalterweatherman/notepad.go b/vendor/github.com/spf13/jwalterweatherman/notepad.go new file mode 100644 index 00000000..cc7957bf --- /dev/null +++ b/vendor/github.com/spf13/jwalterweatherman/notepad.go @@ -0,0 +1,225 @@ +// Copyright © 2016 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package jwalterweatherman + +import ( + "fmt" + "io" + "io/ioutil" + "log" +) + +type Threshold int + +func (t Threshold) String() string { + return prefixes[t] +} + +const ( + LevelTrace Threshold = iota + LevelDebug + LevelInfo + LevelWarn + LevelError + LevelCritical + LevelFatal +) + +var prefixes map[Threshold]string = map[Threshold]string{ + LevelTrace: "TRACE", + LevelDebug: "DEBUG", + LevelInfo: "INFO", + LevelWarn: "WARN", + LevelError: "ERROR", + LevelCritical: "CRITICAL", + LevelFatal: "FATAL", +} + +// Notepad is where you leave a note! +type Notepad struct { + TRACE *log.Logger + DEBUG *log.Logger + INFO *log.Logger + WARN *log.Logger + ERROR *log.Logger + CRITICAL *log.Logger + FATAL *log.Logger + + LOG *log.Logger + FEEDBACK *Feedback + + loggers [7]**log.Logger + logHandle io.Writer + outHandle io.Writer + logThreshold Threshold + stdoutThreshold Threshold + prefix string + flags int + + logListeners []LogListener +} + +// A LogListener can ble supplied to a Notepad to listen on log writes for a given +// threshold. This can be used to capture log events in unit tests and similar. +// Note that this function will be invoked once for each log threshold. If +// the given threshold is not of interest to you, return nil. +// Note that these listeners will receive log events for a given threshold, even +// if the current configuration says not to log it. That way you can count ERRORs even +// if you don't print them to the console. +type LogListener func(t Threshold) io.Writer + +// NewNotepad creates a new Notepad. +func NewNotepad( + outThreshold Threshold, + logThreshold Threshold, + outHandle, logHandle io.Writer, + prefix string, flags int, + logListeners ...LogListener, +) *Notepad { + + n := &Notepad{logListeners: logListeners} + + n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL} + n.outHandle = outHandle + n.logHandle = logHandle + n.stdoutThreshold = outThreshold + n.logThreshold = logThreshold + + if len(prefix) != 0 { + n.prefix = "[" + prefix + "] " + } else { + n.prefix = "" + } + + n.flags = flags + + n.LOG = log.New(n.logHandle, + "LOG: ", + n.flags) + n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG} + + n.init() + return n +} + +// init creates the loggers for each level depending on the notepad thresholds. +func (n *Notepad) init() { + logAndOut := io.MultiWriter(n.outHandle, n.logHandle) + + for t, logger := range n.loggers { + threshold := Threshold(t) + prefix := n.prefix + threshold.String() + " " + + switch { + case threshold >= n.logThreshold && threshold >= n.stdoutThreshold: + *logger = log.New(n.createLogWriters(threshold, logAndOut), prefix, n.flags) + + case threshold >= n.logThreshold: + *logger = log.New(n.createLogWriters(threshold, n.logHandle), prefix, n.flags) + + case threshold >= n.stdoutThreshold: + *logger = log.New(n.createLogWriters(threshold, n.outHandle), prefix, n.flags) + + default: + *logger = log.New(n.createLogWriters(threshold, ioutil.Discard), prefix, n.flags) + } + } +} + +func (n *Notepad) createLogWriters(t Threshold, handle io.Writer) io.Writer { + if len(n.logListeners) == 0 { + return handle + } + writers := []io.Writer{handle} + for _, l := range n.logListeners { + w := l(t) + if w != nil { + writers = append(writers, w) + } + } + + if len(writers) == 1 { + return handle + } + + return io.MultiWriter(writers...) +} + +// SetLogThreshold changes the threshold above which messages are written to the +// log file. +func (n *Notepad) SetLogThreshold(threshold Threshold) { + n.logThreshold = threshold + n.init() +} + +// SetLogOutput changes the file where log messages are written. +func (n *Notepad) SetLogOutput(handle io.Writer) { + n.logHandle = handle + n.init() +} + +// GetStdoutThreshold returns the defined Treshold for the log logger. +func (n *Notepad) GetLogThreshold() Threshold { + return n.logThreshold +} + +// SetStdoutThreshold changes the threshold above which messages are written to the +// standard output. +func (n *Notepad) SetStdoutThreshold(threshold Threshold) { + n.stdoutThreshold = threshold + n.init() +} + +// GetStdoutThreshold returns the Treshold for the stdout logger. +func (n *Notepad) GetStdoutThreshold() Threshold { + return n.stdoutThreshold +} + +// SetPrefix changes the prefix used by the notepad. Prefixes are displayed between +// brackets at the beginning of the line. An empty prefix won't be displayed at all. +func (n *Notepad) SetPrefix(prefix string) { + if len(prefix) != 0 { + n.prefix = "[" + prefix + "] " + } else { + n.prefix = "" + } + n.init() +} + +// SetFlags choose which flags the logger will display (after prefix and message +// level). See the package log for more informations on this. +func (n *Notepad) SetFlags(flags int) { + n.flags = flags + n.init() +} + +// Feedback writes plainly to the outHandle while +// logging with the standard extra information (date, file, etc). +type Feedback struct { + out *log.Logger + log *log.Logger +} + +func (fb *Feedback) Println(v ...interface{}) { + fb.output(fmt.Sprintln(v...)) +} + +func (fb *Feedback) Printf(format string, v ...interface{}) { + fb.output(fmt.Sprintf(format, v...)) +} + +func (fb *Feedback) Print(v ...interface{}) { + fb.output(fmt.Sprint(v...)) +} + +func (fb *Feedback) output(s string) { + if fb.out != nil { + fb.out.Output(2, s) + } + if fb.log != nil { + fb.log.Output(2, s) + } +} diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go new file mode 100644 index 00000000..9beeda8e --- /dev/null +++ b/vendor/github.com/spf13/pflag/flag.go @@ -0,0 +1,1227 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package pflag is a drop-in replacement for Go's flag package, implementing +POSIX/GNU-style --flags. + +pflag is compatible with the GNU extensions to the POSIX recommendations +for command-line options. See +http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html + +Usage: + +pflag is a drop-in replacement of Go's native flag package. If you import +pflag under the name "flag" then all code should continue to function +with no changes. + + import flag "github.com/spf13/pflag" + +There is one exception to this: if you directly instantiate the Flag struct +there is one more field "Shorthand" that you will need to set. +Most code never instantiates this struct directly, and instead uses +functions such as String(), BoolVar(), and Var(), and is therefore +unaffected. + +Define flags using flag.String(), Bool(), Int(), etc. + +This declares an integer flag, -flagname, stored in the pointer ip, with type *int. + var ip = flag.Int("flagname", 1234, "help message for flagname") +If you like, you can bind the flag to a variable using the Var() functions. + var flagvar int + func init() { + flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") + } +Or you can create custom flags that satisfy the Value interface (with +pointer receivers) and couple them to flag parsing by + flag.Var(&flagVal, "name", "help message for flagname") +For such flags, the default value is just the initial value of the variable. + +After all flags are defined, call + flag.Parse() +to parse the command line into the defined flags. + +Flags may then be used directly. If you're using the flags themselves, +they are all pointers; if you bind to variables, they're values. + fmt.Println("ip has value ", *ip) + fmt.Println("flagvar has value ", flagvar) + +After parsing, the arguments after the flag are available as the +slice flag.Args() or individually as flag.Arg(i). +The arguments are indexed from 0 through flag.NArg()-1. + +The pflag package also defines some new functions that are not in flag, +that give one-letter shorthands for flags. You can use these by appending +'P' to the name of any function that defines a flag. + var ip = flag.IntP("flagname", "f", 1234, "help message") + var flagvar bool + func init() { + flag.BoolVarP("boolname", "b", true, "help message") + } + flag.VarP(&flagVar, "varname", "v", 1234, "help message") +Shorthand letters can be used with single dashes on the command line. +Boolean shorthand flags can be combined with other shorthand flags. + +Command line flag syntax: + --flag // boolean flags only + --flag=x + +Unlike the flag package, a single dash before an option means something +different than a double dash. Single dashes signify a series of shorthand +letters for flags. All but the last shorthand letter must be boolean flags. + // boolean flags + -f + -abc + // non-boolean flags + -n 1234 + -Ifile + // mixed + -abcs "hello" + -abcn1234 + +Flag parsing stops after the terminator "--". Unlike the flag package, +flags can be interspersed with arguments anywhere on the command line +before this terminator. + +Integer flags accept 1234, 0664, 0x1234 and may be negative. +Boolean flags (in their long form) accept 1, 0, t, f, true, false, +TRUE, FALSE, True, False. +Duration flags accept any input valid for time.ParseDuration. + +The default set of command-line flags is controlled by +top-level functions. The FlagSet type allows one to define +independent sets of flags, such as to implement subcommands +in a command-line interface. The methods of FlagSet are +analogous to the top-level functions for the command-line +flag set. +*/ +package pflag + +import ( + "bytes" + "errors" + goflag "flag" + "fmt" + "io" + "os" + "sort" + "strings" +) + +// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. +var ErrHelp = errors.New("pflag: help requested") + +// ErrorHandling defines how to handle flag parsing errors. +type ErrorHandling int + +const ( + // ContinueOnError will return an err from Parse() if an error is found + ContinueOnError ErrorHandling = iota + // ExitOnError will call os.Exit(2) if an error is found when parsing + ExitOnError + // PanicOnError will panic() if an error is found when parsing flags + PanicOnError +) + +// ParseErrorsWhitelist defines the parsing errors that can be ignored +type ParseErrorsWhitelist struct { + // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags + UnknownFlags bool +} + +// NormalizedName is a flag name that has been normalized according to rules +// for the FlagSet (e.g. making '-' and '_' equivalent). +type NormalizedName string + +// A FlagSet represents a set of defined flags. +type FlagSet struct { + // Usage is the function called when an error occurs while parsing flags. + // The field is a function (not a method) that may be changed to point to + // a custom error handler. + Usage func() + + // SortFlags is used to indicate, if user wants to have sorted flags in + // help/usage messages. + SortFlags bool + + // ParseErrorsWhitelist is used to configure a whitelist of errors + ParseErrorsWhitelist ParseErrorsWhitelist + + name string + parsed bool + actual map[NormalizedName]*Flag + orderedActual []*Flag + sortedActual []*Flag + formal map[NormalizedName]*Flag + orderedFormal []*Flag + sortedFormal []*Flag + shorthands map[byte]*Flag + args []string // arguments after flags + argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no -- + errorHandling ErrorHandling + output io.Writer // nil means stderr; use out() accessor + interspersed bool // allow interspersed option/non-option args + normalizeNameFunc func(f *FlagSet, name string) NormalizedName + + addedGoFlagSets []*goflag.FlagSet +} + +// A Flag represents the state of a flag. +type Flag struct { + Name string // name as it appears on command line + Shorthand string // one-letter abbreviated flag + Usage string // help message + Value Value // value as set + DefValue string // default value (as text); for usage message + Changed bool // If the user set the value (or if left to default) + NoOptDefVal string // default value (as text); if the flag is on the command line without any options + Deprecated string // If this flag is deprecated, this string is the new or now thing to use + Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text + ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use + Annotations map[string][]string // used by cobra.Command bash autocomple code +} + +// Value is the interface to the dynamic value stored in a flag. +// (The default value is represented as a string.) +type Value interface { + String() string + Set(string) error + Type() string +} + +// sortFlags returns the flags as a slice in lexicographical sorted order. +func sortFlags(flags map[NormalizedName]*Flag) []*Flag { + list := make(sort.StringSlice, len(flags)) + i := 0 + for k := range flags { + list[i] = string(k) + i++ + } + list.Sort() + result := make([]*Flag, len(list)) + for i, name := range list { + result[i] = flags[NormalizedName(name)] + } + return result +} + +// SetNormalizeFunc allows you to add a function which can translate flag names. +// Flags added to the FlagSet will be translated and then when anything tries to +// look up the flag that will also be translated. So it would be possible to create +// a flag named "getURL" and have it translated to "geturl". A user could then pass +// "--getUrl" which may also be translated to "geturl" and everything will work. +func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) { + f.normalizeNameFunc = n + f.sortedFormal = f.sortedFormal[:0] + for fname, flag := range f.formal { + nname := f.normalizeFlagName(flag.Name) + if fname == nname { + continue + } + flag.Name = string(nname) + delete(f.formal, fname) + f.formal[nname] = flag + if _, set := f.actual[fname]; set { + delete(f.actual, fname) + f.actual[nname] = flag + } + } +} + +// GetNormalizeFunc returns the previously set NormalizeFunc of a function which +// does no translation, if not set previously. +func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName { + if f.normalizeNameFunc != nil { + return f.normalizeNameFunc + } + return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) } +} + +func (f *FlagSet) normalizeFlagName(name string) NormalizedName { + n := f.GetNormalizeFunc() + return n(f, name) +} + +func (f *FlagSet) out() io.Writer { + if f.output == nil { + return os.Stderr + } + return f.output +} + +// SetOutput sets the destination for usage and error messages. +// If output is nil, os.Stderr is used. +func (f *FlagSet) SetOutput(output io.Writer) { + f.output = output +} + +// VisitAll visits the flags in lexicographical order or +// in primordial order if f.SortFlags is false, calling fn for each. +// It visits all flags, even those not set. +func (f *FlagSet) VisitAll(fn func(*Flag)) { + if len(f.formal) == 0 { + return + } + + var flags []*Flag + if f.SortFlags { + if len(f.formal) != len(f.sortedFormal) { + f.sortedFormal = sortFlags(f.formal) + } + flags = f.sortedFormal + } else { + flags = f.orderedFormal + } + + for _, flag := range flags { + fn(flag) + } +} + +// HasFlags returns a bool to indicate if the FlagSet has any flags defined. +func (f *FlagSet) HasFlags() bool { + return len(f.formal) > 0 +} + +// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags +// that are not hidden. +func (f *FlagSet) HasAvailableFlags() bool { + for _, flag := range f.formal { + if !flag.Hidden { + return true + } + } + return false +} + +// VisitAll visits the command-line flags in lexicographical order or +// in primordial order if f.SortFlags is false, calling fn for each. +// It visits all flags, even those not set. +func VisitAll(fn func(*Flag)) { + CommandLine.VisitAll(fn) +} + +// Visit visits the flags in lexicographical order or +// in primordial order if f.SortFlags is false, calling fn for each. +// It visits only those flags that have been set. +func (f *FlagSet) Visit(fn func(*Flag)) { + if len(f.actual) == 0 { + return + } + + var flags []*Flag + if f.SortFlags { + if len(f.actual) != len(f.sortedActual) { + f.sortedActual = sortFlags(f.actual) + } + flags = f.sortedActual + } else { + flags = f.orderedActual + } + + for _, flag := range flags { + fn(flag) + } +} + +// Visit visits the command-line flags in lexicographical order or +// in primordial order if f.SortFlags is false, calling fn for each. +// It visits only those flags that have been set. +func Visit(fn func(*Flag)) { + CommandLine.Visit(fn) +} + +// Lookup returns the Flag structure of the named flag, returning nil if none exists. +func (f *FlagSet) Lookup(name string) *Flag { + return f.lookup(f.normalizeFlagName(name)) +} + +// ShorthandLookup returns the Flag structure of the short handed flag, +// returning nil if none exists. +// It panics, if len(name) > 1. +func (f *FlagSet) ShorthandLookup(name string) *Flag { + if name == "" { + return nil + } + if len(name) > 1 { + msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) + fmt.Fprintf(f.out(), msg) + panic(msg) + } + c := name[0] + return f.shorthands[c] +} + +// lookup returns the Flag structure of the named flag, returning nil if none exists. +func (f *FlagSet) lookup(name NormalizedName) *Flag { + return f.formal[name] +} + +// func to return a given type for a given flag name +func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) { + flag := f.Lookup(name) + if flag == nil { + err := fmt.Errorf("flag accessed but not defined: %s", name) + return nil, err + } + + if flag.Value.Type() != ftype { + err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type()) + return nil, err + } + + sval := flag.Value.String() + result, err := convFunc(sval) + if err != nil { + return nil, err + } + return result, nil +} + +// ArgsLenAtDash will return the length of f.Args at the moment when a -- was +// found during arg parsing. This allows your program to know which args were +// before the -- and which came after. +func (f *FlagSet) ArgsLenAtDash() int { + return f.argsLenAtDash +} + +// MarkDeprecated indicated that a flag is deprecated in your program. It will +// continue to function but will not show up in help or usage messages. Using +// this flag will also print the given usageMessage. +func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error { + flag := f.Lookup(name) + if flag == nil { + return fmt.Errorf("flag %q does not exist", name) + } + if usageMessage == "" { + return fmt.Errorf("deprecated message for flag %q must be set", name) + } + flag.Deprecated = usageMessage + flag.Hidden = true + return nil +} + +// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your +// program. It will continue to function but will not show up in help or usage +// messages. Using this flag will also print the given usageMessage. +func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error { + flag := f.Lookup(name) + if flag == nil { + return fmt.Errorf("flag %q does not exist", name) + } + if usageMessage == "" { + return fmt.Errorf("deprecated message for flag %q must be set", name) + } + flag.ShorthandDeprecated = usageMessage + return nil +} + +// MarkHidden sets a flag to 'hidden' in your program. It will continue to +// function but will not show up in help or usage messages. +func (f *FlagSet) MarkHidden(name string) error { + flag := f.Lookup(name) + if flag == nil { + return fmt.Errorf("flag %q does not exist", name) + } + flag.Hidden = true + return nil +} + +// Lookup returns the Flag structure of the named command-line flag, +// returning nil if none exists. +func Lookup(name string) *Flag { + return CommandLine.Lookup(name) +} + +// ShorthandLookup returns the Flag structure of the short handed flag, +// returning nil if none exists. +func ShorthandLookup(name string) *Flag { + return CommandLine.ShorthandLookup(name) +} + +// Set sets the value of the named flag. +func (f *FlagSet) Set(name, value string) error { + normalName := f.normalizeFlagName(name) + flag, ok := f.formal[normalName] + if !ok { + return fmt.Errorf("no such flag -%v", name) + } + + err := flag.Value.Set(value) + if err != nil { + var flagName string + if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { + flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name) + } else { + flagName = fmt.Sprintf("--%s", flag.Name) + } + return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err) + } + + if !flag.Changed { + if f.actual == nil { + f.actual = make(map[NormalizedName]*Flag) + } + f.actual[normalName] = flag + f.orderedActual = append(f.orderedActual, flag) + + flag.Changed = true + } + + if flag.Deprecated != "" { + fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + } + return nil +} + +// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet. +// This is sometimes used by spf13/cobra programs which want to generate additional +// bash completion information. +func (f *FlagSet) SetAnnotation(name, key string, values []string) error { + normalName := f.normalizeFlagName(name) + flag, ok := f.formal[normalName] + if !ok { + return fmt.Errorf("no such flag -%v", name) + } + if flag.Annotations == nil { + flag.Annotations = map[string][]string{} + } + flag.Annotations[key] = values + return nil +} + +// Changed returns true if the flag was explicitly set during Parse() and false +// otherwise +func (f *FlagSet) Changed(name string) bool { + flag := f.Lookup(name) + // If a flag doesn't exist, it wasn't changed.... + if flag == nil { + return false + } + return flag.Changed +} + +// Set sets the value of the named command-line flag. +func Set(name, value string) error { + return CommandLine.Set(name, value) +} + +// PrintDefaults prints, to standard error unless configured +// otherwise, the default values of all defined flags in the set. +func (f *FlagSet) PrintDefaults() { + usages := f.FlagUsages() + fmt.Fprint(f.out(), usages) +} + +// defaultIsZeroValue returns true if the default value for this flag represents +// a zero value. +func (f *Flag) defaultIsZeroValue() bool { + switch f.Value.(type) { + case boolFlag: + return f.DefValue == "false" + case *durationValue: + // Beginning in Go 1.7, duration zero values are "0s" + return f.DefValue == "0" || f.DefValue == "0s" + case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value: + return f.DefValue == "0" + case *stringValue: + return f.DefValue == "" + case *ipValue, *ipMaskValue, *ipNetValue: + return f.DefValue == "" + case *intSliceValue, *stringSliceValue, *stringArrayValue: + return f.DefValue == "[]" + default: + switch f.Value.String() { + case "false": + return true + case "": + return true + case "": + return true + case "0": + return true + } + return false + } +} + +// UnquoteUsage extracts a back-quoted name from the usage +// string for a flag and returns it and the un-quoted usage. +// Given "a `name` to show" it returns ("name", "a name to show"). +// If there are no back quotes, the name is an educated guess of the +// type of the flag's value, or the empty string if the flag is boolean. +func UnquoteUsage(flag *Flag) (name string, usage string) { + // Look for a back-quoted name, but avoid the strings package. + usage = flag.Usage + for i := 0; i < len(usage); i++ { + if usage[i] == '`' { + for j := i + 1; j < len(usage); j++ { + if usage[j] == '`' { + name = usage[i+1 : j] + usage = usage[:i] + name + usage[j+1:] + return name, usage + } + } + break // Only one back quote; use type name. + } + } + + name = flag.Value.Type() + switch name { + case "bool": + name = "" + case "float64": + name = "float" + case "int64": + name = "int" + case "uint64": + name = "uint" + case "stringSlice": + name = "strings" + case "intSlice": + name = "ints" + case "uintSlice": + name = "uints" + case "boolSlice": + name = "bools" + } + + return +} + +// Splits the string `s` on whitespace into an initial substring up to +// `i` runes in length and the remainder. Will go `slop` over `i` if +// that encompasses the entire string (which allows the caller to +// avoid short orphan words on the final line). +func wrapN(i, slop int, s string) (string, string) { + if i+slop > len(s) { + return s, "" + } + + w := strings.LastIndexAny(s[:i], " \t\n") + if w <= 0 { + return s, "" + } + nlPos := strings.LastIndex(s[:i], "\n") + if nlPos > 0 && nlPos < w { + return s[:nlPos], s[nlPos+1:] + } + return s[:w], s[w+1:] +} + +// Wraps the string `s` to a maximum width `w` with leading indent +// `i`. The first line is not indented (this is assumed to be done by +// caller). Pass `w` == 0 to do no wrapping +func wrap(i, w int, s string) string { + if w == 0 { + return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1) + } + + // space between indent i and end of line width w into which + // we should wrap the text. + wrap := w - i + + var r, l string + + // Not enough space for sensible wrapping. Wrap as a block on + // the next line instead. + if wrap < 24 { + i = 16 + wrap = w - i + r += "\n" + strings.Repeat(" ", i) + } + // If still not enough space then don't even try to wrap. + if wrap < 24 { + return strings.Replace(s, "\n", r, -1) + } + + // Try to avoid short orphan words on the final line, by + // allowing wrapN to go a bit over if that would fit in the + // remainder of the line. + slop := 5 + wrap = wrap - slop + + // Handle first line, which is indented by the caller (or the + // special case above) + l, s = wrapN(wrap, slop, s) + r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1) + + // Now wrap the rest + for s != "" { + var t string + + t, s = wrapN(wrap, slop, s) + r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1) + } + + return r + +} + +// FlagUsagesWrapped returns a string containing the usage information +// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no +// wrapping) +func (f *FlagSet) FlagUsagesWrapped(cols int) string { + buf := new(bytes.Buffer) + + lines := make([]string, 0, len(f.formal)) + + maxlen := 0 + f.VisitAll(func(flag *Flag) { + if flag.Hidden { + return + } + + line := "" + if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { + line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name) + } else { + line = fmt.Sprintf(" --%s", flag.Name) + } + + varname, usage := UnquoteUsage(flag) + if varname != "" { + line += " " + varname + } + if flag.NoOptDefVal != "" { + switch flag.Value.Type() { + case "string": + line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal) + case "bool": + if flag.NoOptDefVal != "true" { + line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) + } + case "count": + if flag.NoOptDefVal != "+1" { + line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) + } + default: + line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) + } + } + + // This special character will be replaced with spacing once the + // correct alignment is calculated + line += "\x00" + if len(line) > maxlen { + maxlen = len(line) + } + + line += usage + if !flag.defaultIsZeroValue() { + if flag.Value.Type() == "string" { + line += fmt.Sprintf(" (default %q)", flag.DefValue) + } else { + line += fmt.Sprintf(" (default %s)", flag.DefValue) + } + } + if len(flag.Deprecated) != 0 { + line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated) + } + + lines = append(lines, line) + }) + + for _, line := range lines { + sidx := strings.Index(line, "\x00") + spacing := strings.Repeat(" ", maxlen-sidx) + // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx + fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:])) + } + + return buf.String() +} + +// FlagUsages returns a string containing the usage information for all flags in +// the FlagSet +func (f *FlagSet) FlagUsages() string { + return f.FlagUsagesWrapped(0) +} + +// PrintDefaults prints to standard error the default values of all defined command-line flags. +func PrintDefaults() { + CommandLine.PrintDefaults() +} + +// defaultUsage is the default function to print a usage message. +func defaultUsage(f *FlagSet) { + fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) + f.PrintDefaults() +} + +// NOTE: Usage is not just defaultUsage(CommandLine) +// because it serves (via godoc flag Usage) as the example +// for how to write your own usage function. + +// Usage prints to standard error a usage message documenting all defined command-line flags. +// The function is a variable that may be changed to point to a custom function. +// By default it prints a simple header and calls PrintDefaults; for details about the +// format of the output and how to control it, see the documentation for PrintDefaults. +var Usage = func() { + fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) + PrintDefaults() +} + +// NFlag returns the number of flags that have been set. +func (f *FlagSet) NFlag() int { return len(f.actual) } + +// NFlag returns the number of command-line flags that have been set. +func NFlag() int { return len(CommandLine.actual) } + +// Arg returns the i'th argument. Arg(0) is the first remaining argument +// after flags have been processed. +func (f *FlagSet) Arg(i int) string { + if i < 0 || i >= len(f.args) { + return "" + } + return f.args[i] +} + +// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument +// after flags have been processed. +func Arg(i int) string { + return CommandLine.Arg(i) +} + +// NArg is the number of arguments remaining after flags have been processed. +func (f *FlagSet) NArg() int { return len(f.args) } + +// NArg is the number of arguments remaining after flags have been processed. +func NArg() int { return len(CommandLine.args) } + +// Args returns the non-flag arguments. +func (f *FlagSet) Args() []string { return f.args } + +// Args returns the non-flag command-line arguments. +func Args() []string { return CommandLine.args } + +// Var defines a flag with the specified name and usage string. The type and +// value of the flag are represented by the first argument, of type Value, which +// typically holds a user-defined implementation of Value. For instance, the +// caller could create a flag that turns a comma-separated string into a slice +// of strings by giving the slice the methods of Value; in particular, Set would +// decompose the comma-separated string into the slice. +func (f *FlagSet) Var(value Value, name string, usage string) { + f.VarP(value, name, "", usage) +} + +// VarPF is like VarP, but returns the flag created +func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag { + // Remember the default value as a string; it won't change. + flag := &Flag{ + Name: name, + Shorthand: shorthand, + Usage: usage, + Value: value, + DefValue: value.String(), + } + f.AddFlag(flag) + return flag +} + +// VarP is like Var, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) VarP(value Value, name, shorthand, usage string) { + f.VarPF(value, name, shorthand, usage) +} + +// AddFlag will add the flag to the FlagSet +func (f *FlagSet) AddFlag(flag *Flag) { + normalizedFlagName := f.normalizeFlagName(flag.Name) + + _, alreadyThere := f.formal[normalizedFlagName] + if alreadyThere { + msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) + fmt.Fprintln(f.out(), msg) + panic(msg) // Happens only if flags are declared with identical names + } + if f.formal == nil { + f.formal = make(map[NormalizedName]*Flag) + } + + flag.Name = string(normalizedFlagName) + f.formal[normalizedFlagName] = flag + f.orderedFormal = append(f.orderedFormal, flag) + + if flag.Shorthand == "" { + return + } + if len(flag.Shorthand) > 1 { + msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) + fmt.Fprintf(f.out(), msg) + panic(msg) + } + if f.shorthands == nil { + f.shorthands = make(map[byte]*Flag) + } + c := flag.Shorthand[0] + used, alreadyThere := f.shorthands[c] + if alreadyThere { + msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) + fmt.Fprintf(f.out(), msg) + panic(msg) + } + f.shorthands[c] = flag +} + +// AddFlagSet adds one FlagSet to another. If a flag is already present in f +// the flag from newSet will be ignored. +func (f *FlagSet) AddFlagSet(newSet *FlagSet) { + if newSet == nil { + return + } + newSet.VisitAll(func(flag *Flag) { + if f.Lookup(flag.Name) == nil { + f.AddFlag(flag) + } + }) +} + +// Var defines a flag with the specified name and usage string. The type and +// value of the flag are represented by the first argument, of type Value, which +// typically holds a user-defined implementation of Value. For instance, the +// caller could create a flag that turns a comma-separated string into a slice +// of strings by giving the slice the methods of Value; in particular, Set would +// decompose the comma-separated string into the slice. +func Var(value Value, name string, usage string) { + CommandLine.VarP(value, name, "", usage) +} + +// VarP is like Var, but accepts a shorthand letter that can be used after a single dash. +func VarP(value Value, name, shorthand, usage string) { + CommandLine.VarP(value, name, shorthand, usage) +} + +// failf prints to standard error a formatted error and usage message and +// returns the error. +func (f *FlagSet) failf(format string, a ...interface{}) error { + err := fmt.Errorf(format, a...) + if f.errorHandling != ContinueOnError { + fmt.Fprintln(f.out(), err) + f.usage() + } + return err +} + +// usage calls the Usage method for the flag set, or the usage function if +// the flag set is CommandLine. +func (f *FlagSet) usage() { + if f == CommandLine { + Usage() + } else if f.Usage == nil { + defaultUsage(f) + } else { + f.Usage() + } +} + +//--unknown (args will be empty) +//--unknown --next-flag ... (args will be --next-flag ...) +//--unknown arg ... (args will be arg ...) +func stripUnknownFlagValue(args []string) []string { + if len(args) == 0 { + //--unknown + return args + } + + first := args[0] + if len(first) > 0 && first[0] == '-' { + //--unknown --next-flag ... + return args + } + + //--unknown arg ... (args will be arg ...) + if len(args) > 1 { + return args[1:] + } + return nil +} + +func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { + a = args + name := s[2:] + if len(name) == 0 || name[0] == '-' || name[0] == '=' { + err = f.failf("bad flag syntax: %s", s) + return + } + + split := strings.SplitN(name, "=", 2) + name = split[0] + flag, exists := f.formal[f.normalizeFlagName(name)] + + if !exists { + switch { + case name == "help": + f.usage() + return a, ErrHelp + case f.ParseErrorsWhitelist.UnknownFlags: + // --unknown=unknownval arg ... + // we do not want to lose arg in this case + if len(split) >= 2 { + return a, nil + } + + return stripUnknownFlagValue(a), nil + default: + err = f.failf("unknown flag: --%s", name) + return + } + } + + var value string + if len(split) == 2 { + // '--flag=arg' + value = split[1] + } else if flag.NoOptDefVal != "" { + // '--flag' (arg was optional) + value = flag.NoOptDefVal + } else if len(a) > 0 { + // '--flag arg' + value = a[0] + a = a[1:] + } else { + // '--flag' (arg was required) + err = f.failf("flag needs an argument: %s", s) + return + } + + err = fn(flag, value) + if err != nil { + f.failf(err.Error()) + } + return +} + +func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { + outArgs = args + + if strings.HasPrefix(shorthands, "test.") { + return + } + + outShorts = shorthands[1:] + c := shorthands[0] + + flag, exists := f.shorthands[c] + if !exists { + switch { + case c == 'h': + f.usage() + err = ErrHelp + return + case f.ParseErrorsWhitelist.UnknownFlags: + // '-f=arg arg ...' + // we do not want to lose arg in this case + if len(shorthands) > 2 && shorthands[1] == '=' { + outShorts = "" + return + } + + outArgs = stripUnknownFlagValue(outArgs) + return + default: + err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands) + return + } + } + + var value string + if len(shorthands) > 2 && shorthands[1] == '=' { + // '-f=arg' + value = shorthands[2:] + outShorts = "" + } else if flag.NoOptDefVal != "" { + // '-f' (arg was optional) + value = flag.NoOptDefVal + } else if len(shorthands) > 1 { + // '-farg' + value = shorthands[1:] + outShorts = "" + } else if len(args) > 0 { + // '-f arg' + value = args[0] + outArgs = args[1:] + } else { + // '-f' (arg was required) + err = f.failf("flag needs an argument: %q in -%s", c, shorthands) + return + } + + if flag.ShorthandDeprecated != "" { + fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) + } + + err = fn(flag, value) + if err != nil { + f.failf(err.Error()) + } + return +} + +func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { + a = args + shorthands := s[1:] + + // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv"). + for len(shorthands) > 0 { + shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn) + if err != nil { + return + } + } + + return +} + +func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { + for len(args) > 0 { + s := args[0] + args = args[1:] + if len(s) == 0 || s[0] != '-' || len(s) == 1 { + if !f.interspersed { + f.args = append(f.args, s) + f.args = append(f.args, args...) + return nil + } + f.args = append(f.args, s) + continue + } + + if s[1] == '-' { + if len(s) == 2 { // "--" terminates the flags + f.argsLenAtDash = len(f.args) + f.args = append(f.args, args...) + break + } + args, err = f.parseLongArg(s, args, fn) + } else { + args, err = f.parseShortArg(s, args, fn) + } + if err != nil { + return + } + } + return +} + +// Parse parses flag definitions from the argument list, which should not +// include the command name. Must be called after all flags in the FlagSet +// are defined and before flags are accessed by the program. +// The return value will be ErrHelp if -help was set but not defined. +func (f *FlagSet) Parse(arguments []string) error { + if f.addedGoFlagSets != nil { + for _, goFlagSet := range f.addedGoFlagSets { + goFlagSet.Parse(nil) + } + } + f.parsed = true + + if len(arguments) < 0 { + return nil + } + + f.args = make([]string, 0, len(arguments)) + + set := func(flag *Flag, value string) error { + return f.Set(flag.Name, value) + } + + err := f.parseArgs(arguments, set) + if err != nil { + switch f.errorHandling { + case ContinueOnError: + return err + case ExitOnError: + fmt.Println(err) + os.Exit(2) + case PanicOnError: + panic(err) + } + } + return nil +} + +type parseFunc func(flag *Flag, value string) error + +// ParseAll parses flag definitions from the argument list, which should not +// include the command name. The arguments for fn are flag and value. Must be +// called after all flags in the FlagSet are defined and before flags are +// accessed by the program. The return value will be ErrHelp if -help was set +// but not defined. +func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error { + f.parsed = true + f.args = make([]string, 0, len(arguments)) + + err := f.parseArgs(arguments, fn) + if err != nil { + switch f.errorHandling { + case ContinueOnError: + return err + case ExitOnError: + os.Exit(2) + case PanicOnError: + panic(err) + } + } + return nil +} + +// Parsed reports whether f.Parse has been called. +func (f *FlagSet) Parsed() bool { + return f.parsed +} + +// Parse parses the command-line flags from os.Args[1:]. Must be called +// after all flags are defined and before flags are accessed by the program. +func Parse() { + // Ignore errors; CommandLine is set for ExitOnError. + CommandLine.Parse(os.Args[1:]) +} + +// ParseAll parses the command-line flags from os.Args[1:] and called fn for each. +// The arguments for fn are flag and value. Must be called after all flags are +// defined and before flags are accessed by the program. +func ParseAll(fn func(flag *Flag, value string) error) { + // Ignore errors; CommandLine is set for ExitOnError. + CommandLine.ParseAll(os.Args[1:], fn) +} + +// SetInterspersed sets whether to support interspersed option/non-option arguments. +func SetInterspersed(interspersed bool) { + CommandLine.SetInterspersed(interspersed) +} + +// Parsed returns true if the command-line flags have been parsed. +func Parsed() bool { + return CommandLine.Parsed() +} + +// CommandLine is the default set of command-line flags, parsed from os.Args. +var CommandLine = NewFlagSet(os.Args[0], ExitOnError) + +// NewFlagSet returns a new, empty flag set with the specified name, +// error handling property and SortFlags set to true. +func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { + f := &FlagSet{ + name: name, + errorHandling: errorHandling, + argsLenAtDash: -1, + interspersed: true, + SortFlags: true, + } + return f +} + +// SetInterspersed sets whether to support interspersed option/non-option arguments. +func (f *FlagSet) SetInterspersed(interspersed bool) { + f.interspersed = interspersed +} + +// Init sets the name and error handling property for a flag set. +// By default, the zero FlagSet uses an empty name and the +// ContinueOnError error handling policy. +func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { + f.name = name + f.errorHandling = errorHandling + f.argsLenAtDash = -1 +} diff --git a/vendor/github.com/spf13/pflag/string_to_int.go b/vendor/github.com/spf13/pflag/string_to_int.go new file mode 100644 index 00000000..5ceda396 --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_int.go @@ -0,0 +1,149 @@ +package pflag + +import ( + "bytes" + "fmt" + "strconv" + "strings" +) + +// -- stringToInt Value +type stringToIntValue struct { + value *map[string]int + changed bool +} + +func newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue { + ssv := new(stringToIntValue) + ssv.value = p + *ssv.value = val + return ssv +} + +// Format: a=1,b=2 +func (s *stringToIntValue) Set(val string) error { + ss := strings.Split(val, ",") + out := make(map[string]int, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("%s must be formatted as key=value", pair) + } + var err error + out[kv[0]], err = strconv.Atoi(kv[1]) + if err != nil { + return err + } + } + if !s.changed { + *s.value = out + } else { + for k, v := range out { + (*s.value)[k] = v + } + } + s.changed = true + return nil +} + +func (s *stringToIntValue) Type() string { + return "stringToInt" +} + +func (s *stringToIntValue) String() string { + var buf bytes.Buffer + i := 0 + for k, v := range *s.value { + if i > 0 { + buf.WriteRune(',') + } + buf.WriteString(k) + buf.WriteRune('=') + buf.WriteString(strconv.Itoa(v)) + i++ + } + return "[" + buf.String() + "]" +} + +func stringToIntConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // An empty string would cause an empty map + if len(val) == 0 { + return map[string]int{}, nil + } + ss := strings.Split(val, ",") + out := make(map[string]int, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return nil, fmt.Errorf("%s must be formatted as key=value", pair) + } + var err error + out[kv[0]], err = strconv.Atoi(kv[1]) + if err != nil { + return nil, err + } + } + return out, nil +} + +// GetStringToInt return the map[string]int value of a flag with the given name +func (f *FlagSet) GetStringToInt(name string) (map[string]int, error) { + val, err := f.getFlagType(name, "stringToInt", stringToIntConv) + if err != nil { + return map[string]int{}, err + } + return val.(map[string]int), nil +} + +// StringToIntVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]int variable in which to store the values of the multiple flags. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { + f.VarP(newStringToIntValue(value, p), name, "", usage) +} + +// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { + f.VarP(newStringToIntValue(value, p), name, shorthand, usage) +} + +// StringToIntVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]int variable in which to store the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { + CommandLine.VarP(newStringToIntValue(value, p), name, "", usage) +} + +// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. +func StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { + CommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage) +} + +// StringToInt defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]int variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int { + p := map[string]int{} + f.StringToIntVarP(&p, name, "", value, usage) + return &p +} + +// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { + p := map[string]int{} + f.StringToIntVarP(&p, name, shorthand, value, usage) + return &p +} + +// StringToInt defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]int variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToInt(name string, value map[string]int, usage string) *map[string]int { + return CommandLine.StringToIntP(name, "", value, usage) +} + +// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. +func StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { + return CommandLine.StringToIntP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_to_string.go b/vendor/github.com/spf13/pflag/string_to_string.go new file mode 100644 index 00000000..890a01af --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_string.go @@ -0,0 +1,160 @@ +package pflag + +import ( + "bytes" + "encoding/csv" + "fmt" + "strings" +) + +// -- stringToString Value +type stringToStringValue struct { + value *map[string]string + changed bool +} + +func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue { + ssv := new(stringToStringValue) + ssv.value = p + *ssv.value = val + return ssv +} + +// Format: a=1,b=2 +func (s *stringToStringValue) Set(val string) error { + var ss []string + n := strings.Count(val, "=") + switch n { + case 0: + return fmt.Errorf("%s must be formatted as key=value", val) + case 1: + ss = append(ss, strings.Trim(val, `"`)) + default: + r := csv.NewReader(strings.NewReader(val)) + var err error + ss, err = r.Read() + if err != nil { + return err + } + } + + out := make(map[string]string, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("%s must be formatted as key=value", pair) + } + out[kv[0]] = kv[1] + } + if !s.changed { + *s.value = out + } else { + for k, v := range out { + (*s.value)[k] = v + } + } + s.changed = true + return nil +} + +func (s *stringToStringValue) Type() string { + return "stringToString" +} + +func (s *stringToStringValue) String() string { + records := make([]string, 0, len(*s.value)>>1) + for k, v := range *s.value { + records = append(records, k+"="+v) + } + + var buf bytes.Buffer + w := csv.NewWriter(&buf) + if err := w.Write(records); err != nil { + panic(err) + } + w.Flush() + return "[" + strings.TrimSpace(buf.String()) + "]" +} + +func stringToStringConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // An empty string would cause an empty map + if len(val) == 0 { + return map[string]string{}, nil + } + r := csv.NewReader(strings.NewReader(val)) + ss, err := r.Read() + if err != nil { + return nil, err + } + out := make(map[string]string, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return nil, fmt.Errorf("%s must be formatted as key=value", pair) + } + out[kv[0]] = kv[1] + } + return out, nil +} + +// GetStringToString return the map[string]string value of a flag with the given name +func (f *FlagSet) GetStringToString(name string) (map[string]string, error) { + val, err := f.getFlagType(name, "stringToString", stringToStringConv) + if err != nil { + return map[string]string{}, err + } + return val.(map[string]string), nil +} + +// StringToStringVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]string variable in which to store the values of the multiple flags. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} + +// StringToStringVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]string variable in which to store the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. +func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} + +// StringToString defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string { + p := map[string]string{} + f.StringToStringVarP(&p, name, "", value, usage) + return &p +} + +// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { + p := map[string]string{} + f.StringToStringVarP(&p, name, shorthand, value, usage) + return &p +} + +// StringToString defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToString(name string, value map[string]string, usage string) *map[string]string { + return CommandLine.StringToStringP(name, "", value, usage) +} + +// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { + return CommandLine.StringToStringP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/viper/.gitignore b/vendor/github.com/spf13/viper/.gitignore new file mode 100644 index 00000000..01b5c44b --- /dev/null +++ b/vendor/github.com/spf13/viper/.gitignore @@ -0,0 +1,29 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.bench + +.vscode + +# exclude dependencies in the `/vendor` folder +vendor diff --git a/vendor/github.com/spf13/viper/.travis.yml b/vendor/github.com/spf13/viper/.travis.yml new file mode 100644 index 00000000..bb83057b --- /dev/null +++ b/vendor/github.com/spf13/viper/.travis.yml @@ -0,0 +1,31 @@ +go_import_path: github.com/spf13/viper + +language: go + +env: + global: + - GO111MODULE="on" + +go: + - 1.11.x + - tip + +os: + - linux + - osx + +matrix: + allow_failures: + - go: tip + fast_finish: true + +script: + - go install ./... + - diff -u <(echo -n) <(gofmt -d .) + - go test -v ./... + +after_success: + - go get -u -d github.com/spf13/hugo + - cd $GOPATH/src/github.com/spf13/hugo && make && ./hugo -s docs && cd - + +sudo: false diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md new file mode 100644 index 00000000..0208eac8 --- /dev/null +++ b/vendor/github.com/spf13/viper/README.md @@ -0,0 +1,691 @@ +![viper logo](https://cloud.githubusercontent.com/assets/173412/10886745/998df88a-8151-11e5-9448-4736db51020d.png) + +Go configuration with fangs! + +Many Go projects are built using Viper including: + +* [Hugo](http://gohugo.io) +* [EMC RexRay](http://rexray.readthedocs.org/en/stable/) +* [Imgur’s Incus](https://github.com/Imgur/incus) +* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack) +* [Docker Notary](https://github.com/docker/Notary) +* [BloomApi](https://www.bloomapi.com/) +* [doctl](https://github.com/digitalocean/doctl) +* [Clairctl](https://github.com/jgsqware/clairctl) + +[![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper) + + +## What is Viper? + +Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed +to work within an application, and can handle all types of configuration needs +and formats. It supports: + +* setting defaults +* reading from JSON, TOML, YAML, HCL, and Java properties config files +* live watching and re-reading of config files (optional) +* reading from environment variables +* reading from remote config systems (etcd or Consul), and watching changes +* reading from command line flags +* reading from buffer +* setting explicit values + +Viper can be thought of as a registry for all of your applications +configuration needs. + +## Why Viper? + +When building a modern application, you don’t want to worry about +configuration file formats; you want to focus on building awesome software. +Viper is here to help with that. + +Viper does the following for you: + +1. Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, or Java properties formats. +2. Provide a mechanism to set default values for your different + configuration options. +3. Provide a mechanism to set override values for options specified through + command line flags. +4. Provide an alias system to easily rename parameters without breaking existing + code. +5. Make it easy to tell the difference between when a user has provided a + command line or config file which is the same as the default. + +Viper uses the following precedence order. Each item takes precedence over the +item below it: + + * explicit call to Set + * flag + * env + * config + * key/value store + * default + +Viper configuration keys are case insensitive. + +## Putting Values into Viper + +### Establishing Defaults + +A good configuration system will support default values. A default value is not +required for a key, but it’s useful in the event that a key hasn’t been set via +config file, environment variable, remote configuration or flag. + +Examples: + +```go +viper.SetDefault("ContentDir", "content") +viper.SetDefault("LayoutDir", "layouts") +viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"}) +``` + +### Reading Config Files + +Viper requires minimal configuration so it knows where to look for config files. +Viper supports JSON, TOML, YAML, HCL, and Java Properties files. Viper can search multiple paths, but +currently a single Viper instance only supports a single configuration file. +Viper does not default to any configuration search paths leaving defaults decision +to an application. + +Here is an example of how to use Viper to search for and read a configuration file. +None of the specific paths are required, but at least one path should be provided +where a configuration file is expected. + +```go +viper.SetConfigName("config") // name of config file (without extension) +viper.AddConfigPath("/etc/appname/") // path to look for the config file in +viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths +viper.AddConfigPath(".") // optionally look for config in the working directory +err := viper.ReadInConfig() // Find and read the config file +if err != nil { // Handle errors reading the config file + panic(fmt.Errorf("Fatal error config file: %s \n", err)) +} +``` + +### Watching and re-reading config files + +Viper supports the ability to have your application live read a config file while running. + +Gone are the days of needing to restart a server to have a config take effect, +viper powered applications can read an update to a config file while running and +not miss a beat. + +Simply tell the viper instance to watchConfig. +Optionally you can provide a function for Viper to run each time a change occurs. + +**Make sure you add all of the configPaths prior to calling `WatchConfig()`** + +```go +viper.WatchConfig() +viper.OnConfigChange(func(e fsnotify.Event) { + fmt.Println("Config file changed:", e.Name) +}) +``` + +### Reading Config from io.Reader + +Viper predefines many configuration sources such as files, environment +variables, flags, and remote K/V store, but you are not bound to them. You can +also implement your own required configuration source and feed it to viper. + +```go +viper.SetConfigType("yaml") // or viper.SetConfigType("YAML") + +// any approach to require this configuration into your program. +var yamlExample = []byte(` +Hacker: true +name: steve +hobbies: +- skateboarding +- snowboarding +- go +clothing: + jacket: leather + trousers: denim +age: 35 +eyes : brown +beard: true +`) + +viper.ReadConfig(bytes.NewBuffer(yamlExample)) + +viper.Get("name") // this would be "steve" +``` + +### Setting Overrides + +These could be from a command line flag, or from your own application logic. + +```go +viper.Set("Verbose", true) +viper.Set("LogFile", LogFile) +``` + +### Registering and Using Aliases + +Aliases permit a single value to be referenced by multiple keys + +```go +viper.RegisterAlias("loud", "Verbose") + +viper.Set("verbose", true) // same result as next line +viper.Set("loud", true) // same result as prior line + +viper.GetBool("loud") // true +viper.GetBool("verbose") // true +``` + +### Working with Environment Variables + +Viper has full support for environment variables. This enables 12 factor +applications out of the box. There are five methods that exist to aid working +with ENV: + + * `AutomaticEnv()` + * `BindEnv(string...) : error` + * `SetEnvPrefix(string)` + * `SetEnvKeyReplacer(string...) *strings.Replacer` + * `AllowEmptyEnvVar(bool)` + +_When working with ENV variables, it’s important to recognize that Viper +treats ENV variables as case sensitive._ + +Viper provides a mechanism to try to ensure that ENV variables are unique. By +using `SetEnvPrefix`, you can tell Viper to use a prefix while reading from +the environment variables. Both `BindEnv` and `AutomaticEnv` will use this +prefix. + +`BindEnv` takes one or two parameters. The first parameter is the key name, the +second is the name of the environment variable. The name of the environment +variable is case sensitive. If the ENV variable name is not provided, then +Viper will automatically assume that the key name matches the ENV variable name, +but the ENV variable is IN ALL CAPS. When you explicitly provide the ENV +variable name, it **does not** automatically add the prefix. + +One important thing to recognize when working with ENV variables is that the +value will be read each time it is accessed. Viper does not fix the value when +the `BindEnv` is called. + +`AutomaticEnv` is a powerful helper especially when combined with +`SetEnvPrefix`. When called, Viper will check for an environment variable any +time a `viper.Get` request is made. It will apply the following rules. It will +check for a environment variable with a name matching the key uppercased and +prefixed with the `EnvPrefix` if set. + +`SetEnvKeyReplacer` allows you to use a `strings.Replacer` object to rewrite Env +keys to an extent. This is useful if you want to use `-` or something in your +`Get()` calls, but want your environmental variables to use `_` delimiters. An +example of using it can be found in `viper_test.go`. + +By default empty environment variables are considered unset and will fall back to +the next configuration source. To treat empty environment variables as set, use +the `AllowEmptyEnv` method. + +#### Env example + +```go +SetEnvPrefix("spf") // will be uppercased automatically +BindEnv("id") + +os.Setenv("SPF_ID", "13") // typically done outside of the app + +id := Get("id") // 13 +``` + +### Working with Flags + +Viper has the ability to bind to flags. Specifically, Viper supports `Pflags` +as used in the [Cobra](https://github.com/spf13/cobra) library. + +Like `BindEnv`, the value is not set when the binding method is called, but when +it is accessed. This means you can bind as early as you want, even in an +`init()` function. + +For individual flags, the `BindPFlag()` method provides this functionality. + +Example: + +```go +serverCmd.Flags().Int("port", 1138, "Port to run Application server on") +viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) +``` + +You can also bind an existing set of pflags (pflag.FlagSet): + +Example: + +```go +pflag.Int("flagname", 1234, "help message for flagname") + +pflag.Parse() +viper.BindPFlags(pflag.CommandLine) + +i := viper.GetInt("flagname") // retrieve values from viper instead of pflag +``` + +The use of [pflag](https://github.com/spf13/pflag/) in Viper does not preclude +the use of other packages that use the [flag](https://golang.org/pkg/flag/) +package from the standard library. The pflag package can handle the flags +defined for the flag package by importing these flags. This is accomplished +by a calling a convenience function provided by the pflag package called +AddGoFlagSet(). + +Example: + +```go +package main + +import ( + "flag" + "github.com/spf13/pflag" +) + +func main() { + + // using standard library "flag" package + flag.Int("flagname", 1234, "help message for flagname") + + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + viper.BindPFlags(pflag.CommandLine) + + i := viper.GetInt("flagname") // retrieve value from viper + + ... +} +``` + +#### Flag interfaces + +Viper provides two Go interfaces to bind other flag systems if you don’t use `Pflags`. + +`FlagValue` represents a single flag. This is a very simple example on how to implement this interface: + +```go +type myFlag struct {} +func (f myFlag) HasChanged() bool { return false } +func (f myFlag) Name() string { return "my-flag-name" } +func (f myFlag) ValueString() string { return "my-flag-value" } +func (f myFlag) ValueType() string { return "string" } +``` + +Once your flag implements this interface, you can simply tell Viper to bind it: + +```go +viper.BindFlagValue("my-flag-name", myFlag{}) +``` + +`FlagValueSet` represents a group of flags. This is a very simple example on how to implement this interface: + +```go +type myFlagSet struct { + flags []myFlag +} + +func (f myFlagSet) VisitAll(fn func(FlagValue)) { + for _, flag := range flags { + fn(flag) + } +} +``` + +Once your flag set implements this interface, you can simply tell Viper to bind it: + +```go +fSet := myFlagSet{ + flags: []myFlag{myFlag{}, myFlag{}}, +} +viper.BindFlagValues("my-flags", fSet) +``` + +### Remote Key/Value Store Support + +To enable remote support in Viper, do a blank import of the `viper/remote` +package: + +`import _ "github.com/spf13/viper/remote"` + +Viper will read a config string (as JSON, TOML, YAML or HCL) retrieved from a path +in a Key/Value store such as etcd or Consul. These values take precedence over +default values, but are overridden by configuration values retrieved from disk, +flags, or environment variables. + +Viper uses [crypt](https://github.com/xordataexchange/crypt) to retrieve +configuration from the K/V store, which means that you can store your +configuration values encrypted and have them automatically decrypted if you have +the correct gpg keyring. Encryption is optional. + +You can use remote configuration in conjunction with local configuration, or +independently of it. + +`crypt` has a command-line helper that you can use to put configurations in your +K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001. + +```bash +$ go get github.com/xordataexchange/crypt/bin/crypt +$ crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json +``` + +Confirm that your value was set: + +```bash +$ crypt get -plaintext /config/hugo.json +``` + +See the `crypt` documentation for examples of how to set encrypted values, or +how to use Consul. + +### Remote Key/Value Store Example - Unencrypted + +#### etcd +```go +viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json") +viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop" +err := viper.ReadRemoteConfig() +``` + +#### Consul +You need to set a key to Consul key/value storage with JSON value containing your desired config. +For example, create a Consul key/value store key `MY_CONSUL_KEY` with value: + +```json +{ + "port": 8080, + "hostname": "myhostname.com" +} +``` + +```go +viper.AddRemoteProvider("consul", "localhost:8500", "MY_CONSUL_KEY") +viper.SetConfigType("json") // Need to explicitly set this to json +err := viper.ReadRemoteConfig() + +fmt.Println(viper.Get("port")) // 8080 +fmt.Println(viper.Get("hostname")) // myhostname.com +``` + +### Remote Key/Value Store Example - Encrypted + +```go +viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg") +viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop" +err := viper.ReadRemoteConfig() +``` + +### Watching Changes in etcd - Unencrypted + +```go +// alternatively, you can create a new viper instance. +var runtime_viper = viper.New() + +runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml") +runtime_viper.SetConfigType("yaml") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop" + +// read from remote config the first time. +err := runtime_viper.ReadRemoteConfig() + +// unmarshal config +runtime_viper.Unmarshal(&runtime_conf) + +// open a goroutine to watch remote changes forever +go func(){ + for { + time.Sleep(time.Second * 5) // delay after each request + + // currently, only tested with etcd support + err := runtime_viper.WatchRemoteConfig() + if err != nil { + log.Errorf("unable to read remote config: %v", err) + continue + } + + // unmarshal new config into our runtime config struct. you can also use channel + // to implement a signal to notify the system of the changes + runtime_viper.Unmarshal(&runtime_conf) + } +}() +``` + +## Getting Values From Viper + +In Viper, there are a few ways to get a value depending on the value’s type. +The following functions and methods exist: + + * `Get(key string) : interface{}` + * `GetBool(key string) : bool` + * `GetFloat64(key string) : float64` + * `GetInt(key string) : int` + * `GetString(key string) : string` + * `GetStringMap(key string) : map[string]interface{}` + * `GetStringMapString(key string) : map[string]string` + * `GetStringSlice(key string) : []string` + * `GetTime(key string) : time.Time` + * `GetDuration(key string) : time.Duration` + * `IsSet(key string) : bool` + * `AllSettings() : map[string]interface{}` + +One important thing to recognize is that each Get function will return a zero +value if it’s not found. To check if a given key exists, the `IsSet()` method +has been provided. + +Example: +```go +viper.GetString("logfile") // case-insensitive Setting & Getting +if viper.GetBool("verbose") { + fmt.Println("verbose enabled") +} +``` +### Accessing nested keys + +The accessor methods also accept formatted paths to deeply nested keys. For +example, if the following JSON file is loaded: + +```json +{ + "host": { + "address": "localhost", + "port": 5799 + }, + "datastore": { + "metric": { + "host": "127.0.0.1", + "port": 3099 + }, + "warehouse": { + "host": "198.0.0.1", + "port": 2112 + } + } +} + +``` + +Viper can access a nested field by passing a `.` delimited path of keys: + +```go +GetString("datastore.metric.host") // (returns "127.0.0.1") +``` + +This obeys the precedence rules established above; the search for the path +will cascade through the remaining configuration registries until found. + +For example, given this configuration file, both `datastore.metric.host` and +`datastore.metric.port` are already defined (and may be overridden). If in addition +`datastore.metric.protocol` was defined in the defaults, Viper would also find it. + +However, if `datastore.metric` was overridden (by a flag, an environment variable, +the `Set()` method, …) with an immediate value, then all sub-keys of +`datastore.metric` become undefined, they are “shadowed” by the higher-priority +configuration level. + +Lastly, if there exists a key that matches the delimited key path, its value +will be returned instead. E.g. + +```json +{ + "datastore.metric.host": "0.0.0.0", + "host": { + "address": "localhost", + "port": 5799 + }, + "datastore": { + "metric": { + "host": "127.0.0.1", + "port": 3099 + }, + "warehouse": { + "host": "198.0.0.1", + "port": 2112 + } + } +} + +GetString("datastore.metric.host") // returns "0.0.0.0" +``` + +### Extract sub-tree + +Extract sub-tree from Viper. + +For example, `viper` represents: + +```json +app: + cache1: + max-items: 100 + item-size: 64 + cache2: + max-items: 200 + item-size: 80 +``` + +After executing: + +```go +subv := viper.Sub("app.cache1") +``` + +`subv` represents: + +```json +max-items: 100 +item-size: 64 +``` + +Suppose we have: + +```go +func NewCache(cfg *Viper) *Cache {...} +``` + +which creates a cache based on config information formatted as `subv`. +Now it’s easy to create these 2 caches separately as: + +```go +cfg1 := viper.Sub("app.cache1") +cache1 := NewCache(cfg1) + +cfg2 := viper.Sub("app.cache2") +cache2 := NewCache(cfg2) +``` + +### Unmarshaling + +You also have the option of Unmarshaling all or a specific value to a struct, map, +etc. + +There are two methods to do this: + + * `Unmarshal(rawVal interface{}) : error` + * `UnmarshalKey(key string, rawVal interface{}) : error` + +Example: + +```go +type config struct { + Port int + Name string + PathMap string `mapstructure:"path_map"` +} + +var C config + +err := Unmarshal(&C) +if err != nil { + t.Fatalf("unable to decode into struct, %v", err) +} +``` + +### Marshalling to string + +You may need to marhsal all the settings held in viper into a string rather than write them to a file. +You can use your favorite format's marshaller with the config returned by `AllSettings()`. + +```go +import ( + yaml "gopkg.in/yaml.v2" + // ... +) + +func yamlStringSettings() string { + c := viper.AllSettings() + bs, err := yaml.Marshal(c) + if err != nil { + t.Fatalf("unable to marshal config to YAML: %v", err) + } + return string(bs) +} +``` + +## Viper or Vipers? + +Viper comes ready to use out of the box. There is no configuration or +initialization needed to begin using Viper. Since most applications will want +to use a single central repository for their configuration, the viper package +provides this. It is similar to a singleton. + +In all of the examples above, they demonstrate using viper in its singleton +style approach. + +### Working with multiple vipers + +You can also create many different vipers for use in your application. Each will +have its own unique set of configurations and values. Each can read from a +different config file, key value store, etc. All of the functions that viper +package supports are mirrored as methods on a viper. + +Example: + +```go +x := viper.New() +y := viper.New() + +x.SetDefault("ContentDir", "content") +y.SetDefault("ContentDir", "foobar") + +//... +``` + +When working with multiple vipers, it is up to the user to keep track of the +different vipers. + +## Q & A + +Q: Why not INI files? + +A: Ini files are pretty awful. There’s no standard format, and they are hard to +validate. Viper is designed to work with JSON, TOML or YAML files. If someone +really wants to add this feature, I’d be happy to merge it. It’s easy to specify +which formats your application will permit. + +Q: Why is it called “Viper”? + +A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe)) +to [Cobra](https://github.com/spf13/cobra). While both can operate completely +independently, together they make a powerful pair to handle much of your +application foundation needs. + +Q: Why is it called “Cobra”? + +A: Is there a better name for a [commander](http://en.wikipedia.org/wiki/Cobra_Commander)? diff --git a/vendor/github.com/spf13/viper/go.mod b/vendor/github.com/spf13/viper/go.mod new file mode 100644 index 00000000..27943005 --- /dev/null +++ b/vendor/github.com/spf13/viper/go.mod @@ -0,0 +1,43 @@ +module github.com/spf13/viper + +require ( + github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect + github.com/coreos/bbolt v1.3.2 // indirect + github.com/coreos/etcd v3.3.10+incompatible // indirect + github.com/coreos/go-semver v0.2.0 // indirect + github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/fsnotify/fsnotify v1.4.7 + github.com/gogo/protobuf v1.2.1 // indirect + github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect + github.com/google/btree v1.0.0 // indirect + github.com/gorilla/websocket v1.4.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.9.0 // indirect + github.com/hashicorp/hcl v1.0.0 + github.com/jonboulle/clockwork v0.1.0 // indirect + github.com/magiconair/properties v1.8.0 + github.com/mitchellh/mapstructure v1.1.2 + github.com/pelletier/go-toml v1.2.0 + github.com/prometheus/client_golang v0.9.3 // indirect + github.com/soheilhy/cmux v0.1.4 // indirect + github.com/spf13/afero v1.1.2 + github.com/spf13/cast v1.3.0 + github.com/spf13/jwalterweatherman v1.0.0 + github.com/spf13/pflag v1.0.3 + github.com/stretchr/testify v1.2.2 + github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect + github.com/ugorji/go v1.1.4 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 + go.etcd.io/bbolt v1.3.2 // indirect + go.uber.org/atomic v1.4.0 // indirect + go.uber.org/multierr v1.1.0 // indirect + go.uber.org/zap v1.10.0 // indirect + golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect + google.golang.org/grpc v1.21.0 // indirect + gopkg.in/yaml.v2 v2.2.2 +) diff --git a/vendor/github.com/spf13/viper/go.sum b/vendor/github.com/spf13/viper/go.sum new file mode 100644 index 00000000..97afaffe --- /dev/null +++ b/vendor/github.com/spf13/viper/go.sum @@ -0,0 +1,178 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go new file mode 100644 index 00000000..a3d37f8c --- /dev/null +++ b/vendor/github.com/spf13/viper/viper.go @@ -0,0 +1,1868 @@ +// Copyright © 2014 Steve Francia . +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +// Viper is a application configuration system. +// It believes that applications can be configured a variety of ways +// via flags, ENVIRONMENT variables, configuration files retrieved +// from the file system, or a remote key/value store. + +// Each item takes precedence over the item below it: + +// overrides +// flag +// env +// config +// key/value store +// default + +package viper + +import ( + "bytes" + "encoding/csv" + "encoding/json" + "fmt" + "io" + "log" + "os" + "path/filepath" + "reflect" + "strings" + "sync" + "time" + + yaml "gopkg.in/yaml.v2" + + "github.com/fsnotify/fsnotify" + "github.com/hashicorp/hcl" + "github.com/hashicorp/hcl/hcl/printer" + "github.com/magiconair/properties" + "github.com/mitchellh/mapstructure" + toml "github.com/pelletier/go-toml" + "github.com/spf13/afero" + "github.com/spf13/cast" + jww "github.com/spf13/jwalterweatherman" + "github.com/spf13/pflag" +) + +// ConfigMarshalError happens when failing to marshal the configuration. +type ConfigMarshalError struct { + err error +} + +// Error returns the formatted configuration error. +func (e ConfigMarshalError) Error() string { + return fmt.Sprintf("While marshaling config: %s", e.err.Error()) +} + +var v *Viper + +type RemoteResponse struct { + Value []byte + Error error +} + +func init() { + v = New() +} + +type remoteConfigFactory interface { + Get(rp RemoteProvider) (io.Reader, error) + Watch(rp RemoteProvider) (io.Reader, error) + WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool) +} + +// RemoteConfig is optional, see the remote package +var RemoteConfig remoteConfigFactory + +// UnsupportedConfigError denotes encountering an unsupported +// configuration filetype. +type UnsupportedConfigError string + +// Error returns the formatted configuration error. +func (str UnsupportedConfigError) Error() string { + return fmt.Sprintf("Unsupported Config Type %q", string(str)) +} + +// UnsupportedRemoteProviderError denotes encountering an unsupported remote +// provider. Currently only etcd and Consul are supported. +type UnsupportedRemoteProviderError string + +// Error returns the formatted remote provider error. +func (str UnsupportedRemoteProviderError) Error() string { + return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str)) +} + +// RemoteConfigError denotes encountering an error while trying to +// pull the configuration from the remote provider. +type RemoteConfigError string + +// Error returns the formatted remote provider error +func (rce RemoteConfigError) Error() string { + return fmt.Sprintf("Remote Configurations Error: %s", string(rce)) +} + +// ConfigFileNotFoundError denotes failing to find configuration file. +type ConfigFileNotFoundError struct { + name, locations string +} + +// Error returns the formatted configuration error. +func (fnfe ConfigFileNotFoundError) Error() string { + return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations) +} + +// A DecoderConfigOption can be passed to viper.Unmarshal to configure +// mapstructure.DecoderConfig options +type DecoderConfigOption func(*mapstructure.DecoderConfig) + +// DecodeHook returns a DecoderConfigOption which overrides the default +// DecoderConfig.DecodeHook value, the default is: +// +// mapstructure.ComposeDecodeHookFunc( +// mapstructure.StringToTimeDurationHookFunc(), +// mapstructure.StringToSliceHookFunc(","), +// ) +func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption { + return func(c *mapstructure.DecoderConfig) { + c.DecodeHook = hook + } +} + +// Viper is a prioritized configuration registry. It +// maintains a set of configuration sources, fetches +// values to populate those, and provides them according +// to the source's priority. +// The priority of the sources is the following: +// 1. overrides +// 2. flags +// 3. env. variables +// 4. config file +// 5. key/value store +// 6. defaults +// +// For example, if values from the following sources were loaded: +// +// Defaults : { +// "secret": "", +// "user": "default", +// "endpoint": "https://localhost" +// } +// Config : { +// "user": "root" +// "secret": "defaultsecret" +// } +// Env : { +// "secret": "somesecretkey" +// } +// +// The resulting config will have the following values: +// +// { +// "secret": "somesecretkey", +// "user": "root", +// "endpoint": "https://localhost" +// } +type Viper struct { + // Delimiter that separates a list of keys + // used to access a nested value in one go + keyDelim string + + // A set of paths to look for the config file in + configPaths []string + + // The filesystem to read config from. + fs afero.Fs + + // A set of remote providers to search for the configuration + remoteProviders []*defaultRemoteProvider + + // Name of file to look for inside the path + configName string + configFile string + configType string + configPermissions os.FileMode + envPrefix string + + automaticEnvApplied bool + envKeyReplacer *strings.Replacer + allowEmptyEnv bool + + config map[string]interface{} + override map[string]interface{} + defaults map[string]interface{} + kvstore map[string]interface{} + pflags map[string]FlagValue + env map[string]string + aliases map[string]string + typeByDefValue bool + + // Store read properties on the object so that we can write back in order with comments. + // This will only be used if the configuration read is a properties file. + properties *properties.Properties + + onConfigChange func(fsnotify.Event) +} + +// New returns an initialized Viper instance. +func New() *Viper { + v := new(Viper) + v.keyDelim = "." + v.configName = "config" + v.configPermissions = os.FileMode(0644) + v.fs = afero.NewOsFs() + v.config = make(map[string]interface{}) + v.override = make(map[string]interface{}) + v.defaults = make(map[string]interface{}) + v.kvstore = make(map[string]interface{}) + v.pflags = make(map[string]FlagValue) + v.env = make(map[string]string) + v.aliases = make(map[string]string) + v.typeByDefValue = false + + return v +} + +// Intended for testing, will reset all to default settings. +// In the public interface for the viper package so applications +// can use it in their testing as well. +func Reset() { + v = New() + SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} + SupportedRemoteProviders = []string{"etcd", "consul"} +} + +type defaultRemoteProvider struct { + provider string + endpoint string + path string + secretKeyring string +} + +func (rp defaultRemoteProvider) Provider() string { + return rp.provider +} + +func (rp defaultRemoteProvider) Endpoint() string { + return rp.endpoint +} + +func (rp defaultRemoteProvider) Path() string { + return rp.path +} + +func (rp defaultRemoteProvider) SecretKeyring() string { + return rp.secretKeyring +} + +// RemoteProvider stores the configuration necessary +// to connect to a remote key/value store. +// Optional secretKeyring to unencrypt encrypted values +// can be provided. +type RemoteProvider interface { + Provider() string + Endpoint() string + Path() string + SecretKeyring() string +} + +// SupportedExts are universally supported extensions. +var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} + +// SupportedRemoteProviders are universally supported remote providers. +var SupportedRemoteProviders = []string{"etcd", "consul"} + +func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) } +func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) { + v.onConfigChange = run +} + +func WatchConfig() { v.WatchConfig() } + +func (v *Viper) WatchConfig() { + initWG := sync.WaitGroup{} + initWG.Add(1) + go func() { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + // we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way + filename, err := v.getConfigFile() + if err != nil { + log.Printf("error: %v\n", err) + return + } + + configFile := filepath.Clean(filename) + configDir, _ := filepath.Split(configFile) + realConfigFile, _ := filepath.EvalSymlinks(filename) + + eventsWG := sync.WaitGroup{} + eventsWG.Add(1) + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { // 'Events' channel is closed + eventsWG.Done() + return + } + currentConfigFile, _ := filepath.EvalSymlinks(filename) + // we only care about the config file with the following cases: + // 1 - if the config file was modified or created + // 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement) + const writeOrCreateMask = fsnotify.Write | fsnotify.Create + if (filepath.Clean(event.Name) == configFile && + event.Op&writeOrCreateMask != 0) || + (currentConfigFile != "" && currentConfigFile != realConfigFile) { + realConfigFile = currentConfigFile + err := v.ReadInConfig() + if err != nil { + log.Printf("error reading config file: %v\n", err) + } + if v.onConfigChange != nil { + v.onConfigChange(event) + } + } else if filepath.Clean(event.Name) == configFile && + event.Op&fsnotify.Remove&fsnotify.Remove != 0 { + eventsWG.Done() + return + } + + case err, ok := <-watcher.Errors: + if ok { // 'Errors' channel is not closed + log.Printf("watcher error: %v\n", err) + } + eventsWG.Done() + return + } + } + }() + watcher.Add(configDir) + initWG.Done() // done initalizing the watch in this go routine, so the parent routine can move on... + eventsWG.Wait() // now, wait for event loop to end in this go-routine... + }() + initWG.Wait() // make sure that the go routine above fully ended before returning +} + +// SetConfigFile explicitly defines the path, name and extension of the config file. +// Viper will use this and not check any of the config paths. +func SetConfigFile(in string) { v.SetConfigFile(in) } +func (v *Viper) SetConfigFile(in string) { + if in != "" { + v.configFile = in + } +} + +// SetEnvPrefix defines a prefix that ENVIRONMENT variables will use. +// E.g. if your prefix is "spf", the env registry will look for env +// variables that start with "SPF_". +func SetEnvPrefix(in string) { v.SetEnvPrefix(in) } +func (v *Viper) SetEnvPrefix(in string) { + if in != "" { + v.envPrefix = in + } +} + +func (v *Viper) mergeWithEnvPrefix(in string) string { + if v.envPrefix != "" { + return strings.ToUpper(v.envPrefix + "_" + in) + } + + return strings.ToUpper(in) +} + +// AllowEmptyEnv tells Viper to consider set, +// but empty environment variables as valid values instead of falling back. +// For backward compatibility reasons this is false by default. +func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) } +func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) { + v.allowEmptyEnv = allowEmptyEnv +} + +// TODO: should getEnv logic be moved into find(). Can generalize the use of +// rewriting keys many things, Ex: Get('someKey') -> some_key +// (camel case to snake case for JSON keys perhaps) + +// getEnv is a wrapper around os.Getenv which replaces characters in the original +// key. This allows env vars which have different keys than the config object +// keys. +func (v *Viper) getEnv(key string) (string, bool) { + if v.envKeyReplacer != nil { + key = v.envKeyReplacer.Replace(key) + } + + val, ok := os.LookupEnv(key) + + return val, ok && (v.allowEmptyEnv || val != "") +} + +// ConfigFileUsed returns the file used to populate the config registry. +func ConfigFileUsed() string { return v.ConfigFileUsed() } +func (v *Viper) ConfigFileUsed() string { return v.configFile } + +// AddConfigPath adds a path for Viper to search for the config file in. +// Can be called multiple times to define multiple search paths. +func AddConfigPath(in string) { v.AddConfigPath(in) } +func (v *Viper) AddConfigPath(in string) { + if in != "" { + absin := absPathify(in) + jww.INFO.Println("adding", absin, "to paths to search") + if !stringInSlice(absin, v.configPaths) { + v.configPaths = append(v.configPaths, absin) + } + } +} + +// AddRemoteProvider adds a remote configuration source. +// Remote Providers are searched in the order they are added. +// provider is a string value, "etcd" or "consul" are currently supported. +// endpoint is the url. etcd requires http://ip:port consul requires ip:port +// path is the path in the k/v store to retrieve configuration +// To retrieve a config file called myapp.json from /configs/myapp.json +// you should set path to /configs and set config name (SetConfigName()) to +// "myapp" +func AddRemoteProvider(provider, endpoint, path string) error { + return v.AddRemoteProvider(provider, endpoint, path) +} +func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error { + if !stringInSlice(provider, SupportedRemoteProviders) { + return UnsupportedRemoteProviderError(provider) + } + if provider != "" && endpoint != "" { + jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint) + rp := &defaultRemoteProvider{ + endpoint: endpoint, + provider: provider, + path: path, + } + if !v.providerPathExists(rp) { + v.remoteProviders = append(v.remoteProviders, rp) + } + } + return nil +} + +// AddSecureRemoteProvider adds a remote configuration source. +// Secure Remote Providers are searched in the order they are added. +// provider is a string value, "etcd" or "consul" are currently supported. +// endpoint is the url. etcd requires http://ip:port consul requires ip:port +// secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg +// path is the path in the k/v store to retrieve configuration +// To retrieve a config file called myapp.json from /configs/myapp.json +// you should set path to /configs and set config name (SetConfigName()) to +// "myapp" +// Secure Remote Providers are implemented with github.com/xordataexchange/crypt +func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error { + return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring) +} + +func (v *Viper) AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error { + if !stringInSlice(provider, SupportedRemoteProviders) { + return UnsupportedRemoteProviderError(provider) + } + if provider != "" && endpoint != "" { + jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint) + rp := &defaultRemoteProvider{ + endpoint: endpoint, + provider: provider, + path: path, + secretKeyring: secretkeyring, + } + if !v.providerPathExists(rp) { + v.remoteProviders = append(v.remoteProviders, rp) + } + } + return nil +} + +func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool { + for _, y := range v.remoteProviders { + if reflect.DeepEqual(y, p) { + return true + } + } + return false +} + +// searchMap recursively searches for a value for path in source map. +// Returns nil if not found. +// Note: This assumes that the path entries and map keys are lower cased. +func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} { + if len(path) == 0 { + return source + } + + next, ok := source[path[0]] + if ok { + // Fast path + if len(path) == 1 { + return next + } + + // Nested case + switch next.(type) { + case map[interface{}]interface{}: + return v.searchMap(cast.ToStringMap(next), path[1:]) + case map[string]interface{}: + // Type assertion is safe here since it is only reached + // if the type of `next` is the same as the type being asserted + return v.searchMap(next.(map[string]interface{}), path[1:]) + default: + // got a value but nested key expected, return "nil" for not found + return nil + } + } + return nil +} + +// searchMapWithPathPrefixes recursively searches for a value for path in source map. +// +// While searchMap() considers each path element as a single map key, this +// function searches for, and prioritizes, merged path elements. +// e.g., if in the source, "foo" is defined with a sub-key "bar", and "foo.bar" +// is also defined, this latter value is returned for path ["foo", "bar"]. +// +// This should be useful only at config level (other maps may not contain dots +// in their keys). +// +// Note: This assumes that the path entries and map keys are lower cased. +func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []string) interface{} { + if len(path) == 0 { + return source + } + + // search for path prefixes, starting from the longest one + for i := len(path); i > 0; i-- { + prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) + + next, ok := source[prefixKey] + if ok { + // Fast path + if i == len(path) { + return next + } + + // Nested case + var val interface{} + switch next.(type) { + case map[interface{}]interface{}: + val = v.searchMapWithPathPrefixes(cast.ToStringMap(next), path[i:]) + case map[string]interface{}: + // Type assertion is safe here since it is only reached + // if the type of `next` is the same as the type being asserted + val = v.searchMapWithPathPrefixes(next.(map[string]interface{}), path[i:]) + default: + // got a value but nested key expected, do nothing and look for next prefix + } + if val != nil { + return val + } + } + } + + // not found + return nil +} + +// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere +// on its path in the map. +// e.g., if "foo.bar" has a value in the given map, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string { + var parentVal interface{} + for i := 1; i < len(path); i++ { + parentVal = v.searchMap(m, path[0:i]) + if parentVal == nil { + // not found, no need to add more path elements + return "" + } + switch parentVal.(type) { + case map[interface{}]interface{}: + continue + case map[string]interface{}: + continue + default: + // parentVal is a regular value which shadows "path" + return strings.Join(path[0:i], v.keyDelim) + } + } + return "" +} + +// isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere +// in a sub-path of the map. +// e.g., if "foo.bar" has a value in the given map, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { + // unify input map + var m map[string]interface{} + switch mi.(type) { + case map[string]string, map[string]FlagValue: + m = cast.ToStringMap(mi) + default: + return "" + } + + // scan paths + var parentKey string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if _, ok := m[parentKey]; ok { + return parentKey + } + } + return "" +} + +// isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere +// in the environment, when automatic env is on. +// e.g., if "foo.bar" has a value in the environment, it “shadows” +// "foo.bar.baz" in a lower-priority map +func (v *Viper) isPathShadowedInAutoEnv(path []string) string { + var parentKey string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok { + return parentKey + } + } + return "" +} + +// SetTypeByDefaultValue enables or disables the inference of a key value's +// type when the Get function is used based upon a key's default value as +// opposed to the value returned based on the normal fetch logic. +// +// For example, if a key has a default value of []string{} and the same key +// is set via an environment variable to "a b c", a call to the Get function +// would return a string slice for the key if the key's type is inferred by +// the default value and the Get function would return: +// +// []string {"a", "b", "c"} +// +// Otherwise the Get function would return: +// +// "a b c" +func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) } +func (v *Viper) SetTypeByDefaultValue(enable bool) { + v.typeByDefValue = enable +} + +// GetViper gets the global Viper instance. +func GetViper() *Viper { + return v +} + +// Get can retrieve any value given the key to use. +// Get is case-insensitive for a key. +// Get has the behavior of returning the value associated with the first +// place from where it is set. Viper will check in the following order: +// override, flag, env, config file, key/value store, default +// +// Get returns an interface. For a specific value use one of the Get____ methods. +func Get(key string) interface{} { return v.Get(key) } +func (v *Viper) Get(key string) interface{} { + lcaseKey := strings.ToLower(key) + val := v.find(lcaseKey) + if val == nil { + return nil + } + + if v.typeByDefValue { + // TODO(bep) this branch isn't covered by a single test. + valType := val + path := strings.Split(lcaseKey, v.keyDelim) + defVal := v.searchMap(v.defaults, path) + if defVal != nil { + valType = defVal + } + + switch valType.(type) { + case bool: + return cast.ToBool(val) + case string: + return cast.ToString(val) + case int32, int16, int8, int: + return cast.ToInt(val) + case uint: + return cast.ToUint(val) + case uint32: + return cast.ToUint32(val) + case uint64: + return cast.ToUint64(val) + case int64: + return cast.ToInt64(val) + case float64, float32: + return cast.ToFloat64(val) + case time.Time: + return cast.ToTime(val) + case time.Duration: + return cast.ToDuration(val) + case []string: + return cast.ToStringSlice(val) + } + } + + return val +} + +// Sub returns new Viper instance representing a sub tree of this instance. +// Sub is case-insensitive for a key. +func Sub(key string) *Viper { return v.Sub(key) } +func (v *Viper) Sub(key string) *Viper { + subv := New() + data := v.Get(key) + if data == nil { + return nil + } + + if reflect.TypeOf(data).Kind() == reflect.Map { + subv.config = cast.ToStringMap(data) + return subv + } + return nil +} + +// GetString returns the value associated with the key as a string. +func GetString(key string) string { return v.GetString(key) } +func (v *Viper) GetString(key string) string { + return cast.ToString(v.Get(key)) +} + +// GetBool returns the value associated with the key as a boolean. +func GetBool(key string) bool { return v.GetBool(key) } +func (v *Viper) GetBool(key string) bool { + return cast.ToBool(v.Get(key)) +} + +// GetInt returns the value associated with the key as an integer. +func GetInt(key string) int { return v.GetInt(key) } +func (v *Viper) GetInt(key string) int { + return cast.ToInt(v.Get(key)) +} + +// GetInt32 returns the value associated with the key as an integer. +func GetInt32(key string) int32 { return v.GetInt32(key) } +func (v *Viper) GetInt32(key string) int32 { + return cast.ToInt32(v.Get(key)) +} + +// GetInt64 returns the value associated with the key as an integer. +func GetInt64(key string) int64 { return v.GetInt64(key) } +func (v *Viper) GetInt64(key string) int64 { + return cast.ToInt64(v.Get(key)) +} + +// GetUint returns the value associated with the key as an unsigned integer. +func GetUint(key string) uint { return v.GetUint(key) } +func (v *Viper) GetUint(key string) uint { + return cast.ToUint(v.Get(key)) +} + +// GetUint32 returns the value associated with the key as an unsigned integer. +func GetUint32(key string) uint32 { return v.GetUint32(key) } +func (v *Viper) GetUint32(key string) uint32 { + return cast.ToUint32(v.Get(key)) +} + +// GetUint64 returns the value associated with the key as an unsigned integer. +func GetUint64(key string) uint64 { return v.GetUint64(key) } +func (v *Viper) GetUint64(key string) uint64 { + return cast.ToUint64(v.Get(key)) +} + +// GetFloat64 returns the value associated with the key as a float64. +func GetFloat64(key string) float64 { return v.GetFloat64(key) } +func (v *Viper) GetFloat64(key string) float64 { + return cast.ToFloat64(v.Get(key)) +} + +// GetTime returns the value associated with the key as time. +func GetTime(key string) time.Time { return v.GetTime(key) } +func (v *Viper) GetTime(key string) time.Time { + return cast.ToTime(v.Get(key)) +} + +// GetDuration returns the value associated with the key as a duration. +func GetDuration(key string) time.Duration { return v.GetDuration(key) } +func (v *Viper) GetDuration(key string) time.Duration { + return cast.ToDuration(v.Get(key)) +} + +// GetStringSlice returns the value associated with the key as a slice of strings. +func GetStringSlice(key string) []string { return v.GetStringSlice(key) } +func (v *Viper) GetStringSlice(key string) []string { + return cast.ToStringSlice(v.Get(key)) +} + +// GetStringMap returns the value associated with the key as a map of interfaces. +func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) } +func (v *Viper) GetStringMap(key string) map[string]interface{} { + return cast.ToStringMap(v.Get(key)) +} + +// GetStringMapString returns the value associated with the key as a map of strings. +func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) } +func (v *Viper) GetStringMapString(key string) map[string]string { + return cast.ToStringMapString(v.Get(key)) +} + +// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. +func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) } +func (v *Viper) GetStringMapStringSlice(key string) map[string][]string { + return cast.ToStringMapStringSlice(v.Get(key)) +} + +// GetSizeInBytes returns the size of the value associated with the given key +// in bytes. +func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) } +func (v *Viper) GetSizeInBytes(key string) uint { + sizeStr := cast.ToString(v.Get(key)) + return parseSizeInBytes(sizeStr) +} + +// UnmarshalKey takes a single key and unmarshals it into a Struct. +func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { + return v.UnmarshalKey(key, rawVal, opts...) +} +func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { + err := decode(v.Get(key), defaultDecoderConfig(rawVal, opts...)) + + if err != nil { + return err + } + + return nil +} + +// Unmarshal unmarshals the config into a Struct. Make sure that the tags +// on the fields of the structure are properly set. +func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { + return v.Unmarshal(rawVal, opts...) +} +func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { + err := decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...)) + + if err != nil { + return err + } + + return nil +} + +// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot +// of time.Duration values & string slices +func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig { + c := &mapstructure.DecoderConfig{ + Metadata: nil, + Result: output, + WeaklyTypedInput: true, + DecodeHook: mapstructure.ComposeDecodeHookFunc( + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + ), + } + for _, opt := range opts { + opt(c) + } + return c +} + +// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality +func decode(input interface{}, config *mapstructure.DecoderConfig) error { + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + return decoder.Decode(input) +} + +// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent +// in the destination struct. +func (v *Viper) UnmarshalExact(rawVal interface{}) error { + config := defaultDecoderConfig(rawVal) + config.ErrorUnused = true + + err := decode(v.AllSettings(), config) + + if err != nil { + return err + } + + return nil +} + +// BindPFlags binds a full flag set to the configuration, using each flag's long +// name as the config key. +func BindPFlags(flags *pflag.FlagSet) error { return v.BindPFlags(flags) } +func (v *Viper) BindPFlags(flags *pflag.FlagSet) error { + return v.BindFlagValues(pflagValueSet{flags}) +} + +// BindPFlag binds a specific key to a pflag (as used by cobra). +// Example (where serverCmd is a Cobra instance): +// +// serverCmd.Flags().Int("port", 1138, "Port to run Application server on") +// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) +// +func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) } +func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error { + return v.BindFlagValue(key, pflagValue{flag}) +} + +// BindFlagValues binds a full FlagValue set to the configuration, using each flag's long +// name as the config key. +func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) } +func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) { + flags.VisitAll(func(flag FlagValue) { + if err = v.BindFlagValue(flag.Name(), flag); err != nil { + return + } + }) + return nil +} + +// BindFlagValue binds a specific key to a FlagValue. +// Example (where serverCmd is a Cobra instance): +// +// serverCmd.Flags().Int("port", 1138, "Port to run Application server on") +// Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port")) +// +func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) } +func (v *Viper) BindFlagValue(key string, flag FlagValue) error { + if flag == nil { + return fmt.Errorf("flag for %q is nil", key) + } + v.pflags[strings.ToLower(key)] = flag + return nil +} + +// BindEnv binds a Viper key to a ENV variable. +// ENV variables are case sensitive. +// If only a key is provided, it will use the env key matching the key, uppercased. +// EnvPrefix will be used when set when env name is not provided. +func BindEnv(input ...string) error { return v.BindEnv(input...) } +func (v *Viper) BindEnv(input ...string) error { + var key, envkey string + if len(input) == 0 { + return fmt.Errorf("BindEnv missing key to bind to") + } + + key = strings.ToLower(input[0]) + + if len(input) == 1 { + envkey = v.mergeWithEnvPrefix(key) + } else { + envkey = input[1] + } + + v.env[key] = envkey + + return nil +} + +// Given a key, find the value. +// Viper will check in the following order: +// flag, env, config file, key/value store, default. +// Viper will check to see if an alias exists first. +// Note: this assumes a lower-cased key given. +func (v *Viper) find(lcaseKey string) interface{} { + + var ( + val interface{} + exists bool + path = strings.Split(lcaseKey, v.keyDelim) + nested = len(path) > 1 + ) + + // compute the path through the nested maps to the nested value + if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" { + return nil + } + + // if the requested key is an alias, then return the proper key + lcaseKey = v.realKey(lcaseKey) + path = strings.Split(lcaseKey, v.keyDelim) + nested = len(path) > 1 + + // Set() override first + val = v.searchMap(v.override, path) + if val != nil { + return val + } + if nested && v.isPathShadowedInDeepMap(path, v.override) != "" { + return nil + } + + // PFlag override next + flag, exists := v.pflags[lcaseKey] + if exists && flag.HasChanged() { + switch flag.ValueType() { + case "int", "int8", "int16", "int32", "int64": + return cast.ToInt(flag.ValueString()) + case "bool": + return cast.ToBool(flag.ValueString()) + case "stringSlice": + s := strings.TrimPrefix(flag.ValueString(), "[") + s = strings.TrimSuffix(s, "]") + res, _ := readAsCSV(s) + return res + default: + return flag.ValueString() + } + } + if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" { + return nil + } + + // Env override next + if v.automaticEnvApplied { + // even if it hasn't been registered, if automaticEnv is used, + // check any Get request + if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok { + return val + } + if nested && v.isPathShadowedInAutoEnv(path) != "" { + return nil + } + } + envkey, exists := v.env[lcaseKey] + if exists { + if val, ok := v.getEnv(envkey); ok { + return val + } + } + if nested && v.isPathShadowedInFlatMap(path, v.env) != "" { + return nil + } + + // Config file next + val = v.searchMapWithPathPrefixes(v.config, path) + if val != nil { + return val + } + if nested && v.isPathShadowedInDeepMap(path, v.config) != "" { + return nil + } + + // K/V store next + val = v.searchMap(v.kvstore, path) + if val != nil { + return val + } + if nested && v.isPathShadowedInDeepMap(path, v.kvstore) != "" { + return nil + } + + // Default next + val = v.searchMap(v.defaults, path) + if val != nil { + return val + } + if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" { + return nil + } + + // last chance: if no other value is returned and a flag does exist for the value, + // get the flag's value even if the flag's value has not changed + if flag, exists := v.pflags[lcaseKey]; exists { + switch flag.ValueType() { + case "int", "int8", "int16", "int32", "int64": + return cast.ToInt(flag.ValueString()) + case "bool": + return cast.ToBool(flag.ValueString()) + case "stringSlice": + s := strings.TrimPrefix(flag.ValueString(), "[") + s = strings.TrimSuffix(s, "]") + res, _ := readAsCSV(s) + return res + default: + return flag.ValueString() + } + } + // last item, no need to check shadowing + + return nil +} + +func readAsCSV(val string) ([]string, error) { + if val == "" { + return []string{}, nil + } + stringReader := strings.NewReader(val) + csvReader := csv.NewReader(stringReader) + return csvReader.Read() +} + +// IsSet checks to see if the key has been set in any of the data locations. +// IsSet is case-insensitive for a key. +func IsSet(key string) bool { return v.IsSet(key) } +func (v *Viper) IsSet(key string) bool { + lcaseKey := strings.ToLower(key) + val := v.find(lcaseKey) + return val != nil +} + +// AutomaticEnv has Viper check ENV variables for all. +// keys set in config, default & flags +func AutomaticEnv() { v.AutomaticEnv() } +func (v *Viper) AutomaticEnv() { + v.automaticEnvApplied = true +} + +// SetEnvKeyReplacer sets the strings.Replacer on the viper object +// Useful for mapping an environmental variable to a key that does +// not match it. +func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) } +func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) { + v.envKeyReplacer = r +} + +// Aliases provide another accessor for the same key. +// This enables one to change a name without breaking the application +func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) } +func (v *Viper) RegisterAlias(alias string, key string) { + v.registerAlias(alias, strings.ToLower(key)) +} + +func (v *Viper) registerAlias(alias string, key string) { + alias = strings.ToLower(alias) + if alias != key && alias != v.realKey(key) { + _, exists := v.aliases[alias] + + if !exists { + // if we alias something that exists in one of the maps to another + // name, we'll never be able to get that value using the original + // name, so move the config value to the new realkey. + if val, ok := v.config[alias]; ok { + delete(v.config, alias) + v.config[key] = val + } + if val, ok := v.kvstore[alias]; ok { + delete(v.kvstore, alias) + v.kvstore[key] = val + } + if val, ok := v.defaults[alias]; ok { + delete(v.defaults, alias) + v.defaults[key] = val + } + if val, ok := v.override[alias]; ok { + delete(v.override, alias) + v.override[key] = val + } + v.aliases[alias] = key + } + } else { + jww.WARN.Println("Creating circular reference alias", alias, key, v.realKey(key)) + } +} + +func (v *Viper) realKey(key string) string { + newkey, exists := v.aliases[key] + if exists { + jww.DEBUG.Println("Alias", key, "to", newkey) + return v.realKey(newkey) + } + return key +} + +// InConfig checks to see if the given key (or an alias) is in the config file. +func InConfig(key string) bool { return v.InConfig(key) } +func (v *Viper) InConfig(key string) bool { + // if the requested key is an alias, then return the proper key + key = v.realKey(key) + + _, exists := v.config[key] + return exists +} + +// SetDefault sets the default value for this key. +// SetDefault is case-insensitive for a key. +// Default only used when no value is provided by the user via flag, config or ENV. +func SetDefault(key string, value interface{}) { v.SetDefault(key, value) } +func (v *Viper) SetDefault(key string, value interface{}) { + // If alias passed in, then set the proper default + key = v.realKey(strings.ToLower(key)) + value = toCaseInsensitiveValue(value) + + path := strings.Split(key, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(v.defaults, path[0:len(path)-1]) + + // set innermost value + deepestMap[lastKey] = value +} + +// Set sets the value for the key in the override register. +// Set is case-insensitive for a key. +// Will be used instead of values obtained via +// flags, config file, ENV, default, or key/value store. +func Set(key string, value interface{}) { v.Set(key, value) } +func (v *Viper) Set(key string, value interface{}) { + // If alias passed in, then set the proper override + key = v.realKey(strings.ToLower(key)) + value = toCaseInsensitiveValue(value) + + path := strings.Split(key, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(v.override, path[0:len(path)-1]) + + // set innermost value + deepestMap[lastKey] = value +} + +// ReadInConfig will discover and load the configuration file from disk +// and key/value stores, searching in one of the defined paths. +func ReadInConfig() error { return v.ReadInConfig() } +func (v *Viper) ReadInConfig() error { + jww.INFO.Println("Attempting to read in config file") + filename, err := v.getConfigFile() + if err != nil { + return err + } + + if !stringInSlice(v.getConfigType(), SupportedExts) { + return UnsupportedConfigError(v.getConfigType()) + } + + jww.DEBUG.Println("Reading file: ", filename) + file, err := afero.ReadFile(v.fs, filename) + if err != nil { + return err + } + + config := make(map[string]interface{}) + + err = v.unmarshalReader(bytes.NewReader(file), config) + if err != nil { + return err + } + + v.config = config + return nil +} + +// MergeInConfig merges a new configuration with an existing config. +func MergeInConfig() error { return v.MergeInConfig() } +func (v *Viper) MergeInConfig() error { + jww.INFO.Println("Attempting to merge in config file") + filename, err := v.getConfigFile() + if err != nil { + return err + } + + if !stringInSlice(v.getConfigType(), SupportedExts) { + return UnsupportedConfigError(v.getConfigType()) + } + + file, err := afero.ReadFile(v.fs, filename) + if err != nil { + return err + } + + return v.MergeConfig(bytes.NewReader(file)) +} + +// ReadConfig will read a configuration file, setting existing keys to nil if the +// key does not exist in the file. +func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } +func (v *Viper) ReadConfig(in io.Reader) error { + v.config = make(map[string]interface{}) + return v.unmarshalReader(in, v.config) +} + +// MergeConfig merges a new configuration with an existing config. +func MergeConfig(in io.Reader) error { return v.MergeConfig(in) } +func (v *Viper) MergeConfig(in io.Reader) error { + cfg := make(map[string]interface{}) + if err := v.unmarshalReader(in, cfg); err != nil { + return err + } + return v.MergeConfigMap(cfg) +} + +// MergeConfigMap merges the configuration from the map given with an existing config. +// Note that the map given may be modified. +func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) } +func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error { + if v.config == nil { + v.config = make(map[string]interface{}) + } + insensitiviseMap(cfg) + mergeMaps(cfg, v.config, nil) + return nil +} + +// WriteConfig writes the current configuration to a file. +func WriteConfig() error { return v.WriteConfig() } +func (v *Viper) WriteConfig() error { + filename, err := v.getConfigFile() + if err != nil { + return err + } + return v.writeConfig(filename, true) +} + +// SafeWriteConfig writes current configuration to file only if the file does not exist. +func SafeWriteConfig() error { return v.SafeWriteConfig() } +func (v *Viper) SafeWriteConfig() error { + filename, err := v.getConfigFile() + if err != nil { + return err + } + return v.writeConfig(filename, false) +} + +// WriteConfigAs writes current configuration to a given filename. +func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) } +func (v *Viper) WriteConfigAs(filename string) error { + return v.writeConfig(filename, true) +} + +// SafeWriteConfigAs writes current configuration to a given filename if it does not exist. +func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) } +func (v *Viper) SafeWriteConfigAs(filename string) error { + return v.writeConfig(filename, false) +} + +func writeConfig(filename string, force bool) error { return v.writeConfig(filename, force) } +func (v *Viper) writeConfig(filename string, force bool) error { + jww.INFO.Println("Attempting to write configuration to file.") + ext := filepath.Ext(filename) + if len(ext) <= 1 { + return fmt.Errorf("Filename: %s requires valid extension.", filename) + } + configType := ext[1:] + if !stringInSlice(configType, SupportedExts) { + return UnsupportedConfigError(configType) + } + if v.config == nil { + v.config = make(map[string]interface{}) + } + var flags int + if force == true { + flags = os.O_CREATE | os.O_TRUNC | os.O_WRONLY + } else { + if _, err := os.Stat(filename); os.IsNotExist(err) { + flags = os.O_WRONLY + } else { + return fmt.Errorf("File: %s exists. Use WriteConfig to overwrite.", filename) + } + } + f, err := v.fs.OpenFile(filename, flags, v.configPermissions) + if err != nil { + return err + } + return v.marshalWriter(f, configType) +} + +// Unmarshal a Reader into a map. +// Should probably be an unexported function. +func unmarshalReader(in io.Reader, c map[string]interface{}) error { + return v.unmarshalReader(in, c) +} +func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { + buf := new(bytes.Buffer) + buf.ReadFrom(in) + + switch strings.ToLower(v.getConfigType()) { + case "yaml", "yml": + if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { + return ConfigParseError{err} + } + + case "json": + if err := json.Unmarshal(buf.Bytes(), &c); err != nil { + return ConfigParseError{err} + } + + case "hcl": + obj, err := hcl.Parse(string(buf.Bytes())) + if err != nil { + return ConfigParseError{err} + } + if err = hcl.DecodeObject(&c, obj); err != nil { + return ConfigParseError{err} + } + + case "toml": + tree, err := toml.LoadReader(buf) + if err != nil { + return ConfigParseError{err} + } + tmap := tree.ToMap() + for k, v := range tmap { + c[k] = v + } + + case "properties", "props", "prop": + v.properties = properties.NewProperties() + var err error + if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil { + return ConfigParseError{err} + } + for _, key := range v.properties.Keys() { + value, _ := v.properties.Get(key) + // recursively build nested maps + path := strings.Split(key, ".") + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(c, path[0:len(path)-1]) + // set innermost value + deepestMap[lastKey] = value + } + } + + insensitiviseMap(c) + return nil +} + +// Marshal a map into Writer. +func marshalWriter(f afero.File, configType string) error { + return v.marshalWriter(f, configType) +} +func (v *Viper) marshalWriter(f afero.File, configType string) error { + c := v.AllSettings() + switch configType { + case "json": + b, err := json.MarshalIndent(c, "", " ") + if err != nil { + return ConfigMarshalError{err} + } + _, err = f.WriteString(string(b)) + if err != nil { + return ConfigMarshalError{err} + } + + case "hcl": + b, err := json.Marshal(c) + ast, err := hcl.Parse(string(b)) + if err != nil { + return ConfigMarshalError{err} + } + err = printer.Fprint(f, ast.Node) + if err != nil { + return ConfigMarshalError{err} + } + + case "prop", "props", "properties": + if v.properties == nil { + v.properties = properties.NewProperties() + } + p := v.properties + for _, key := range v.AllKeys() { + _, _, err := p.Set(key, v.GetString(key)) + if err != nil { + return ConfigMarshalError{err} + } + } + _, err := p.WriteComment(f, "#", properties.UTF8) + if err != nil { + return ConfigMarshalError{err} + } + + case "toml": + t, err := toml.TreeFromMap(c) + if err != nil { + return ConfigMarshalError{err} + } + s := t.String() + if _, err := f.WriteString(s); err != nil { + return ConfigMarshalError{err} + } + + case "yaml", "yml": + b, err := yaml.Marshal(c) + if err != nil { + return ConfigMarshalError{err} + } + if _, err = f.WriteString(string(b)); err != nil { + return ConfigMarshalError{err} + } + } + return nil +} + +func keyExists(k string, m map[string]interface{}) string { + lk := strings.ToLower(k) + for mk := range m { + lmk := strings.ToLower(mk) + if lmk == lk { + return mk + } + } + return "" +} + +func castToMapStringInterface( + src map[interface{}]interface{}) map[string]interface{} { + tgt := map[string]interface{}{} + for k, v := range src { + tgt[fmt.Sprintf("%v", k)] = v + } + return tgt +} + +func castMapStringToMapInterface(src map[string]string) map[string]interface{} { + tgt := map[string]interface{}{} + for k, v := range src { + tgt[k] = v + } + return tgt +} + +func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} { + tgt := map[string]interface{}{} + for k, v := range src { + tgt[k] = v + } + return tgt +} + +// mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's +// insistence on parsing nested structures as `map[interface{}]interface{}` +// instead of using a `string` as the key for nest structures beyond one level +// deep. Both map types are supported as there is a go-yaml fork that uses +// `map[string]interface{}` instead. +func mergeMaps( + src, tgt map[string]interface{}, itgt map[interface{}]interface{}) { + for sk, sv := range src { + tk := keyExists(sk, tgt) + if tk == "" { + jww.TRACE.Printf("tk=\"\", tgt[%s]=%v", sk, sv) + tgt[sk] = sv + if itgt != nil { + itgt[sk] = sv + } + continue + } + + tv, ok := tgt[tk] + if !ok { + jww.TRACE.Printf("tgt[%s] != ok, tgt[%s]=%v", tk, sk, sv) + tgt[sk] = sv + if itgt != nil { + itgt[sk] = sv + } + continue + } + + svType := reflect.TypeOf(sv) + tvType := reflect.TypeOf(tv) + if svType != tvType { + jww.ERROR.Printf( + "svType != tvType; key=%s, st=%v, tt=%v, sv=%v, tv=%v", + sk, svType, tvType, sv, tv) + continue + } + + jww.TRACE.Printf("processing key=%s, st=%v, tt=%v, sv=%v, tv=%v", + sk, svType, tvType, sv, tv) + + switch ttv := tv.(type) { + case map[interface{}]interface{}: + jww.TRACE.Printf("merging maps (must convert)") + tsv := sv.(map[interface{}]interface{}) + ssv := castToMapStringInterface(tsv) + stv := castToMapStringInterface(ttv) + mergeMaps(ssv, stv, ttv) + case map[string]interface{}: + jww.TRACE.Printf("merging maps") + mergeMaps(sv.(map[string]interface{}), ttv, nil) + default: + jww.TRACE.Printf("setting value") + tgt[tk] = sv + if itgt != nil { + itgt[tk] = sv + } + } + } +} + +// ReadRemoteConfig attempts to get configuration from a remote source +// and read it in the remote configuration registry. +func ReadRemoteConfig() error { return v.ReadRemoteConfig() } +func (v *Viper) ReadRemoteConfig() error { + return v.getKeyValueConfig() +} + +func WatchRemoteConfig() error { return v.WatchRemoteConfig() } +func (v *Viper) WatchRemoteConfig() error { + return v.watchKeyValueConfig() +} + +func (v *Viper) WatchRemoteConfigOnChannel() error { + return v.watchKeyValueConfigOnChannel() +} + +// Retrieve the first found remote configuration. +func (v *Viper) getKeyValueConfig() error { + if RemoteConfig == nil { + return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'") + } + + for _, rp := range v.remoteProviders { + val, err := v.getRemoteConfig(rp) + if err != nil { + continue + } + v.kvstore = val + return nil + } + return RemoteConfigError("No Files Found") +} + +func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { + reader, err := RemoteConfig.Get(provider) + if err != nil { + return nil, err + } + err = v.unmarshalReader(reader, v.kvstore) + return v.kvstore, err +} + +// Retrieve the first found remote configuration. +func (v *Viper) watchKeyValueConfigOnChannel() error { + for _, rp := range v.remoteProviders { + respc, _ := RemoteConfig.WatchChannel(rp) + //Todo: Add quit channel + go func(rc <-chan *RemoteResponse) { + for { + b := <-rc + reader := bytes.NewReader(b.Value) + v.unmarshalReader(reader, v.kvstore) + } + }(respc) + return nil + } + return RemoteConfigError("No Files Found") +} + +// Retrieve the first found remote configuration. +func (v *Viper) watchKeyValueConfig() error { + for _, rp := range v.remoteProviders { + val, err := v.watchRemoteConfig(rp) + if err != nil { + continue + } + v.kvstore = val + return nil + } + return RemoteConfigError("No Files Found") +} + +func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { + reader, err := RemoteConfig.Watch(provider) + if err != nil { + return nil, err + } + err = v.unmarshalReader(reader, v.kvstore) + return v.kvstore, err +} + +// AllKeys returns all keys holding a value, regardless of where they are set. +// Nested keys are returned with a v.keyDelim (= ".") separator +func AllKeys() []string { return v.AllKeys() } +func (v *Viper) AllKeys() []string { + m := map[string]bool{} + // add all paths, by order of descending priority to ensure correct shadowing + m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "") + m = v.flattenAndMergeMap(m, v.override, "") + m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags)) + m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env)) + m = v.flattenAndMergeMap(m, v.config, "") + m = v.flattenAndMergeMap(m, v.kvstore, "") + m = v.flattenAndMergeMap(m, v.defaults, "") + + // convert set of paths to list + a := []string{} + for x := range m { + a = append(a, x) + } + return a +} + +// flattenAndMergeMap recursively flattens the given map into a map[string]bool +// of key paths (used as a set, easier to manipulate than a []string): +// - each path is merged into a single key string, delimited with v.keyDelim (= ".") +// - if a path is shadowed by an earlier value in the initial shadow map, +// it is skipped. +// The resulting set of paths is merged to the given shadow set at the same time. +func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool { + if shadow != nil && prefix != "" && shadow[prefix] { + // prefix is shadowed => nothing more to flatten + return shadow + } + if shadow == nil { + shadow = make(map[string]bool) + } + + var m2 map[string]interface{} + if prefix != "" { + prefix += v.keyDelim + } + for k, val := range m { + fullKey := prefix + k + switch val.(type) { + case map[string]interface{}: + m2 = val.(map[string]interface{}) + case map[interface{}]interface{}: + m2 = cast.ToStringMap(val) + default: + // immediate value + shadow[strings.ToLower(fullKey)] = true + continue + } + // recursively merge to shadow map + shadow = v.flattenAndMergeMap(shadow, m2, fullKey) + } + return shadow +} + +// mergeFlatMap merges the given maps, excluding values of the second map +// shadowed by values from the first map. +func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool { + // scan keys +outer: + for k, _ := range m { + path := strings.Split(k, v.keyDelim) + // scan intermediate paths + var parentKey string + for i := 1; i < len(path); i++ { + parentKey = strings.Join(path[0:i], v.keyDelim) + if shadow[parentKey] { + // path is shadowed, continue + continue outer + } + } + // add key + shadow[strings.ToLower(k)] = true + } + return shadow +} + +// AllSettings merges all settings and returns them as a map[string]interface{}. +func AllSettings() map[string]interface{} { return v.AllSettings() } +func (v *Viper) AllSettings() map[string]interface{} { + m := map[string]interface{}{} + // start from the list of keys, and construct the map one value at a time + for _, k := range v.AllKeys() { + value := v.Get(k) + if value == nil { + // should not happen, since AllKeys() returns only keys holding a value, + // check just in case anything changes + continue + } + path := strings.Split(k, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + deepestMap := deepSearch(m, path[0:len(path)-1]) + // set innermost value + deepestMap[lastKey] = value + } + return m +} + +// SetFs sets the filesystem to use to read configuration. +func SetFs(fs afero.Fs) { v.SetFs(fs) } +func (v *Viper) SetFs(fs afero.Fs) { + v.fs = fs +} + +// SetConfigName sets name for the config file. +// Does not include extension. +func SetConfigName(in string) { v.SetConfigName(in) } +func (v *Viper) SetConfigName(in string) { + if in != "" { + v.configName = in + v.configFile = "" + } +} + +// SetConfigType sets the type of the configuration returned by the +// remote source, e.g. "json". +func SetConfigType(in string) { v.SetConfigType(in) } +func (v *Viper) SetConfigType(in string) { + if in != "" { + v.configType = in + } +} + +// SetConfigPermissions sets the permissions for the config file. +func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) } +func (v *Viper) SetConfigPermissions(perm os.FileMode) { + v.configPermissions = perm.Perm() +} + +func (v *Viper) getConfigType() string { + if v.configType != "" { + return v.configType + } + + cf, err := v.getConfigFile() + if err != nil { + return "" + } + + ext := filepath.Ext(cf) + + if len(ext) > 1 { + return ext[1:] + } + + return "" +} + +func (v *Viper) getConfigFile() (string, error) { + if v.configFile == "" { + cf, err := v.findConfigFile() + if err != nil { + return "", err + } + v.configFile = cf + } + return v.configFile, nil +} + +func (v *Viper) searchInPath(in string) (filename string) { + jww.DEBUG.Println("Searching for config in ", in) + for _, ext := range SupportedExts { + jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext)) + if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b { + jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext)) + return filepath.Join(in, v.configName+"."+ext) + } + } + + return "" +} + +// Search all configPaths for any config file. +// Returns the first path that exists (and is a config file). +func (v *Viper) findConfigFile() (string, error) { + jww.INFO.Println("Searching for config in ", v.configPaths) + + for _, cp := range v.configPaths { + file := v.searchInPath(cp) + if file != "" { + return file, nil + } + } + return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} +} + +// Debug prints all configuration registries for debugging +// purposes. +func Debug() { v.Debug() } +func (v *Viper) Debug() { + fmt.Printf("Aliases:\n%#v\n", v.aliases) + fmt.Printf("Override:\n%#v\n", v.override) + fmt.Printf("PFlags:\n%#v\n", v.pflags) + fmt.Printf("Env:\n%#v\n", v.env) + fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore) + fmt.Printf("Config:\n%#v\n", v.config) + fmt.Printf("Defaults:\n%#v\n", v.defaults) +} diff --git a/vendor/github.com/status-im/keycard-go/LICENSE.md b/vendor/github.com/status-im/keycard-go/LICENSE.md new file mode 100644 index 00000000..3759302a --- /dev/null +++ b/vendor/github.com/status-im/keycard-go/LICENSE.md @@ -0,0 +1,356 @@ +Mozilla Public License Version 2.0 +================================== + +### 1. Definitions + +**1.1. “Contributor”** + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +**1.2. “Contributor Version”** + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +**1.3. “Contribution”** + means Covered Software of a particular Contributor. + +**1.4. “Covered Software”** + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +**1.5. “Incompatible With Secondary Licenses”** + means + +* **(a)** that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or +* **(b)** that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +**1.6. “Executable Form”** + means any form of the work other than Source Code Form. + +**1.7. “Larger Work”** + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +**1.8. “License”** + means this document. + +**1.9. “Licensable”** + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +**1.10. “Modifications”** + means any of the following: + +* **(a)** any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or +* **(b)** any new file in Source Code Form that contains any Covered + Software. + +**1.11. “Patent Claims” of a Contributor** + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +**1.12. “Secondary License”** + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +**1.13. “Source Code Form”** + means the form of the work preferred for making modifications. + +**1.14. “You” (or “Your”)** + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, “control” means **(a)** the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or **(b)** ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + + +### 2. License Grants and Conditions + +#### 2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +* **(a)** under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and +* **(b)** under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +#### 2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +#### 2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +* **(a)** for any code that a Contributor has removed from Covered Software; + or +* **(b)** for infringements caused by: **(i)** Your and any other third party's + modifications of Covered Software, or **(ii)** the combination of its + Contributions with other software (except as part of its Contributor + Version); or +* **(c)** under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +#### 2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +#### 2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +#### 2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +#### 2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + + +### 3. Responsibilities + +#### 3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +#### 3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +* **(a)** such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +* **(b)** You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +#### 3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +#### 3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +#### 3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + + +### 4. Inability to Comply Due to Statute or Regulation + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: **(a)** comply with +the terms of this License to the maximum extent possible; and **(b)** +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + + +### 5. Termination + +**5.1.** The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated **(a)** provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and **(b)** on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +**5.2.** If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + + +### 6. Disclaimer of Warranty + +> Covered Software is provided under this License on an “as is” +> basis, without warranty of any kind, either expressed, implied, or +> statutory, including, without limitation, warranties that the +> Covered Software is free of defects, merchantable, fit for a +> particular purpose or non-infringing. The entire risk as to the +> quality and performance of the Covered Software is with You. +> Should any Covered Software prove defective in any respect, You +> (not any Contributor) assume the cost of any necessary servicing, +> repair, or correction. This disclaimer of warranty constitutes an +> essential part of this License. No use of any Covered Software is +> authorized under this License except under this disclaimer. + +### 7. Limitation of Liability + +> Under no circumstances and under no legal theory, whether tort +> (including negligence), contract, or otherwise, shall any +> Contributor, or anyone who distributes Covered Software as +> permitted above, be liable to You for any direct, indirect, +> special, incidental, or consequential damages of any character +> including, without limitation, damages for lost profits, loss of +> goodwill, work stoppage, computer failure or malfunction, or any +> and all other commercial damages or losses, even if such party +> shall have been informed of the possibility of such damages. This +> limitation of liability shall not apply to liability for death or +> personal injury resulting from such party's negligence to the +> extent applicable law prohibits such limitation. Some +> jurisdictions do not allow the exclusion or limitation of +> incidental or consequential damages, so this exclusion and +> limitation may not apply to You. + + +### 8. Litigation + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + + +### 9. Miscellaneous + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + + +### 10. Versions of the License + +#### 10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +#### 10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +#### 10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +## Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +## Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/status-im/keycard-go/derivationpath/decoder.go b/vendor/github.com/status-im/keycard-go/derivationpath/decoder.go new file mode 100644 index 00000000..f269da25 --- /dev/null +++ b/vendor/github.com/status-im/keycard-go/derivationpath/decoder.go @@ -0,0 +1,214 @@ +package derivationpath + +import ( + "fmt" + "io" + "strconv" + "strings" +) + +type StartingPoint int + +const ( + tokenMaster = 0x6D // char m + tokenSeparator = 0x2F // char / + tokenHardened = 0x27 // char ' + tokenDot = 0x2E // char . + + hardenedStart = 0x80000000 // 2^31 +) + +const ( + StartingPointMaster StartingPoint = iota + 1 + StartingPointCurrent + StartingPointParent +) + +type parseFunc = func() error + +type decoder struct { + r *strings.Reader + f parseFunc + pos int + path []uint32 + start StartingPoint + currentToken string + currentTokenHardened bool +} + +func newDecoder(path string) *decoder { + d := &decoder{ + r: strings.NewReader(path), + } + + d.reset() + + return d +} + +func (d *decoder) reset() { + d.r.Seek(0, io.SeekStart) + d.pos = 0 + d.start = StartingPointCurrent + d.f = d.parseStart + d.path = make([]uint32, 0) + d.resetCurrentToken() +} + +func (d *decoder) resetCurrentToken() { + d.currentToken = "" + d.currentTokenHardened = false +} + +func (d *decoder) parse() (StartingPoint, []uint32, error) { + for { + err := d.f() + if err != nil { + if err == io.EOF { + err = nil + } else { + err = fmt.Errorf("at position %d, %s", d.pos, err.Error()) + } + + return d.start, d.path, err + } + } + + return d.start, d.path, nil +} + +func (d *decoder) readByte() (byte, error) { + b, err := d.r.ReadByte() + if err != nil { + return b, err + } + + d.pos++ + + return b, nil +} + +func (d *decoder) unreadByte() error { + err := d.r.UnreadByte() + if err != nil { + return err + } + + d.pos-- + + return nil +} + +func (d *decoder) parseStart() error { + b, err := d.readByte() + if err != nil { + return err + } + + if b == tokenMaster { + d.start = StartingPointMaster + d.f = d.parseSeparator + return nil + } + + if b == tokenDot { + b2, err := d.readByte() + if err != nil { + return err + } + + if b2 == tokenDot { + d.f = d.parseSeparator + d.start = StartingPointParent + return nil + } + + d.f = d.parseSeparator + d.start = StartingPointCurrent + return d.unreadByte() + } + + d.f = d.parseSegment + + return d.unreadByte() +} + +func (d *decoder) saveSegment() error { + if len(d.currentToken) > 0 { + i, err := strconv.ParseUint(d.currentToken, 10, 32) + if err != nil { + return err + } + + if i >= hardenedStart { + d.pos -= len(d.currentToken) - 1 + return fmt.Errorf("index must be lower than 2^31, got %d", i) + } + + if d.currentTokenHardened { + i += hardenedStart + } + + d.path = append(d.path, uint32(i)) + } + + d.f = d.parseSegment + d.resetCurrentToken() + + return nil +} + +func (d *decoder) parseSeparator() error { + b, err := d.readByte() + if err != nil { + return err + } + + if b == tokenSeparator { + return d.saveSegment() + } + + return fmt.Errorf("expected %s, got %s", string(tokenSeparator), string(b)) +} + +func (d *decoder) parseSegment() error { + b, err := d.readByte() + if err == io.EOF { + if len(d.currentToken) == 0 { + return fmt.Errorf("expected number, got EOF") + } + + if newErr := d.saveSegment(); newErr != nil { + return newErr + } + + return err + } + + if err != nil { + return err + } + + if len(d.currentToken) > 0 && b == tokenSeparator { + return d.saveSegment() + } + + if len(d.currentToken) > 0 && b == tokenHardened { + d.currentTokenHardened = true + d.f = d.parseSeparator + return nil + } + + if b < 0x30 || b > 0x39 { + return fmt.Errorf("expected number, got %s", string(b)) + } + + d.currentToken = fmt.Sprintf("%s%s", d.currentToken, string(b)) + + return nil +} + +func Decode(str string) (StartingPoint, []uint32, error) { + d := newDecoder(str) + return d.parse() +} diff --git a/vendor/github.com/status-im/keycard-go/derivationpath/encoder.go b/vendor/github.com/status-im/keycard-go/derivationpath/encoder.go new file mode 100644 index 00000000..c1f5b023 --- /dev/null +++ b/vendor/github.com/status-im/keycard-go/derivationpath/encoder.go @@ -0,0 +1,36 @@ +package derivationpath + +import ( + "bytes" + "encoding/binary" + "fmt" + "strings" +) + +func Encode(rawPath []uint32) string { + segments := []string{string(tokenMaster)} + + for _, i := range rawPath { + suffix := "" + + if i >= hardenedStart { + i = i - hardenedStart + suffix = string(tokenHardened) + } + + segments = append(segments, fmt.Sprintf("%d%s", i, suffix)) + } + + return strings.Join(segments, string(tokenSeparator)) +} + +func EncodeFromBytes(data []byte) (string, error) { + buf := bytes.NewBuffer(data) + rawPath := make([]uint32, buf.Len()/4) + err := binary.Read(buf, binary.BigEndian, &rawPath) + if err != nil { + return "", err + } + + return Encode(rawPath), nil +} diff --git a/vendor/github.com/steakknife/bloomfilter/.travis.yml b/vendor/github.com/steakknife/bloomfilter/.travis.yml new file mode 100644 index 00000000..73d1238c --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/.travis.yml @@ -0,0 +1,14 @@ +language: go +dist: trusty +sudo: false +go: + - "1.8.x" + - "1.9.x" + - "1.10.x" + - master +before_script: + - "go get -u gopkg.in/alecthomas/gometalinter.v2" + - "gometalinter.v2 --install" +script: + - "go test -v -cover -benchmem -bench=. $(go list ./... | grep -v /vendor/ | sed \"s&_${PWD}&.&\")" + - "gometalinter.v2 --enable-all ./..." diff --git a/vendor/github.com/steakknife/bloomfilter/MIT-LICENSE.txt b/vendor/github.com/steakknife/bloomfilter/MIT-LICENSE.txt new file mode 100644 index 00000000..ccf77fe4 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/MIT-LICENSE.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright © 2014, 2015 Barry Allard + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/steakknife/bloomfilter/README.md b/vendor/github.com/steakknife/bloomfilter/README.md new file mode 100644 index 00000000..4fab4f45 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/README.md @@ -0,0 +1,120 @@ +**Important**: Zeroth, [consider](https://bdupras.github.io/filter-tutorial/) if a [Cuckoo filter](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf) could be [right for your use-case](https://github.com/seiflotfy/cuckoofilter). + + +[![GoDoc](https://godoc.org/github.com/steakknife/bloomfilter?status.png)](https://godoc.org/github.com/steakknife/bloomfilter) [![travis](https://img.shields.io/travis/steakknife/bloomfilter.svg)](https://travis-ci.org/steakknife/bloomfilter) + +# Face-meltingly fast, thread-safe, marshalable, unionable, probability- and optimal-size-calculating Bloom filter in go + +Copyright © 2014-2016 Barry Allard + +[MIT license](MIT-LICENSE.txt) + +## WTF is a bloom filter + +**TL;DR: **Probabilistic, extra lookup table to track a set of elements kept elsewhere to reduce expensive, unnecessary set element retrieval and/or iterator operations **when an element is not present in the set.** It's a classic time-storage tradeoff algoritm. + +### Properties + +#### [See wikipedia](https://en.wikipedia.org/wiki/Bloom_filter) for algorithm details + +|Impact|What|Description| +|---|---|---| +|Good|No false negatives|know for certain if a given element is definitely NOT in the set| +|Bad|False positives|uncertain if a given element is in the set| +|Bad|Theoretical potential for hash collisions|in very large systems and/or badly hash.Hash64-conforming implementations| +|Bad|Add only|Cannot remove an element, it would destroy information about other elements| +|Good|Constant storage|uses only a fixed amount of memory| + +## Naming conventions + +(Similar to algorithm) + +|Variable/function|Description|Range| +|---|---|---| +|m/M()|number of bits in the bloom filter (memory representation is about m/8 bytes in size)|>=2| +|n/N()|number of elements present|>=0| +|k/K()|number of keys to use (keys are kept private to user code but are de/serialized to Marshal and file I/O)|>=0| +|maxN|maximum capacity of intended structure|>0| +|p|maximum allowed probability of collision (for computing m and k for optimal sizing)|>0..<1| + +- Memory representation should be exactly `24 + 8*(k + (m+63)/64) + unsafe.Sizeof(RWMutex)` bytes. +- Serialized (`BinaryMarshaler`) representation should be exactly `72 + 8*(k + (m+63)/64)` bytes. (Disk format is less due to compression.) + +## Binary serialization format + +All values in Little-endian format + +|Offset|Offset (Hex)|Length (bytes)|Name|Type| +|---|---|---|---|---| +|0|00|8|k|`uint64`| +|8|08|8|n|`uint64`| +|16|10|8|m|`uint64`| +|24|18|k|(keys)|`[k]uint64`| +|24+8*k|...|(m+63)/64|(bloom filter)|`[(m+63)/64]uint64`| +|24+8\*k+8\*((m+63)/64)|...|48|(SHA384 of all previous fields, hashed in order)|`[48]byte`| + +- `bloomfilter.Filter` conforms to `encoding.BinaryMarshaler` and `encoding.BinaryUnmarshaler' + +## Usage + +```go + +import "github.com/steakknife/bloomfilter" + +const ( + maxElements = 100000 + probCollide = 0.0000001 +) + +bf := bloomfilter.NewOptimal(maxElements, probCollide) + +someValue := ... // must conform to hash.Hash64 + +bf.Add(someValue) +if bf.Contains(someValue) { // probably true, could be false + // whatever +} + +anotherValue := ... // must also conform to hash.Hash64 + +if bf.Contains(anotherValue) { + panic("This should never happen") +} + +err := bf.WriteFile("1.bf.gz") // saves this BF to a file +if err != nil { + panic(err) +} + +bf2, err := bloomfilter.ReadFile("1.bf.gz") // read the BF to another var +if err != nil { + panic(err) +} +``` + + +## Design + +Where possible, branch-free operations are used to avoid deep pipeline / execution unit stalls on branch-misses. + +## Get + + go get -u github.com/steakknife/bloomfilter # master is always stable + +## Source + +- On the web: [https://github.com/steakknife/bloomfilter](https://github.com/steakknife/bloomfilter) + +- Git: `git clone https://github.com/steakknife/bloomfilter` + +## Contact + +- [Feedback](mailto:barry.allard@gmail.com) + +- [Issues](https://github.com/steakknife/bloomfilter/issues) + +## License + +[MIT license](MIT-LICENSE.txt) + +Copyright © 2014-2016 Barry Allard diff --git a/vendor/github.com/steakknife/bloomfilter/binarymarshaler.go b/vendor/github.com/steakknife/bloomfilter/binarymarshaler.go new file mode 100644 index 00000000..2fa66925 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/binarymarshaler.go @@ -0,0 +1,87 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "bytes" + "crypto/sha512" + "encoding/binary" +) + +// conforms to encoding.BinaryMarshaler + +// marshalled binary layout (Little Endian): +// +// k 1 uint64 +// n 1 uint64 +// m 1 uint64 +// keys [k]uint64 +// bits [(m+63)/64]uint64 +// hash sha384 (384 bits == 48 bytes) +// +// size = (3 + k + (m+63)/64) * 8 bytes +// + +func (f *Filter) marshal() (buf *bytes.Buffer, + hash [sha512.Size384]byte, + err error, +) { + f.lock.RLock() + defer f.lock.RUnlock() + + debug("write bf k=%d n=%d m=%d\n", f.K(), f.n, f.m) + + buf = new(bytes.Buffer) + + err = binary.Write(buf, binary.LittleEndian, f.K()) + if err != nil { + return nil, hash, err + } + + err = binary.Write(buf, binary.LittleEndian, f.n) + if err != nil { + return nil, hash, err + } + + err = binary.Write(buf, binary.LittleEndian, f.m) + if err != nil { + return nil, hash, err + } + + err = binary.Write(buf, binary.LittleEndian, f.keys) + if err != nil { + return nil, hash, err + } + + err = binary.Write(buf, binary.LittleEndian, f.bits) + if err != nil { + return nil, hash, err + } + + hash = sha512.Sum384(buf.Bytes()) + err = binary.Write(buf, binary.LittleEndian, hash) + return buf, hash, err +} + +// MarshalBinary converts a Filter into []bytes +func (f *Filter) MarshalBinary() (data []byte, err error) { + buf, hash, err := f.marshal() + if err != nil { + return nil, err + } + + debug( + "bloomfilter.MarshalBinary: Successfully wrote %d byte(s), sha384 %v", + buf.Len(), hash, + ) + data = buf.Bytes() + return data, nil +} diff --git a/vendor/github.com/steakknife/bloomfilter/binaryunmarshaler.go b/vendor/github.com/steakknife/bloomfilter/binaryunmarshaler.go new file mode 100644 index 00000000..5be1670c --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/binaryunmarshaler.go @@ -0,0 +1,111 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "bytes" + "crypto/hmac" + "crypto/sha512" + "encoding/binary" + "io" +) + +func unmarshalBinaryHeader(r io.Reader) (k, n, m uint64, err error) { + err = binary.Read(r, binary.LittleEndian, &k) + if err != nil { + return k, n, m, err + } + + if k < KMin { + return k, n, m, errK() + } + + err = binary.Read(r, binary.LittleEndian, &n) + if err != nil { + return k, n, m, err + } + + err = binary.Read(r, binary.LittleEndian, &m) + if err != nil { + return k, n, m, err + } + + if m < MMin { + return k, n, m, errM() + } + + debug("read bf k=%d n=%d m=%d\n", k, n, m) + + return k, n, m, err +} + +func unmarshalBinaryBits(r io.Reader, m uint64) (bits []uint64, err error) { + bits, err = newBits(m) + if err != nil { + return bits, err + } + err = binary.Read(r, binary.LittleEndian, bits) + return bits, err + +} + +func unmarshalBinaryKeys(r io.Reader, k uint64) (keys []uint64, err error) { + keys = make([]uint64, k) + err = binary.Read(r, binary.LittleEndian, keys) + return keys, err +} + +func checkBinaryHash(r io.Reader, data []byte) (err error) { + expectedHash := make([]byte, sha512.Size384) + err = binary.Read(r, binary.LittleEndian, expectedHash) + if err != nil { + return err + } + + actualHash := sha512.Sum384(data[:len(data)-sha512.Size384]) + + if !hmac.Equal(expectedHash, actualHash[:]) { + debug("bloomfilter.UnmarshalBinary() sha384 hash failed:"+ + " actual %v expected %v", actualHash, expectedHash) + return errHash() + } + + debug("bloomfilter.UnmarshalBinary() successfully read"+ + " %d byte(s), sha384 %v", len(data), actualHash) + return nil +} + +// UnmarshalBinary converts []bytes into a Filter +// conforms to encoding.BinaryUnmarshaler +func (f *Filter) UnmarshalBinary(data []byte) (err error) { + f.lock.Lock() + defer f.lock.Unlock() + + buf := bytes.NewBuffer(data) + + var k uint64 + k, f.n, f.m, err = unmarshalBinaryHeader(buf) + if err != nil { + return err + } + + f.keys, err = unmarshalBinaryKeys(buf, k) + if err != nil { + return err + } + + f.bits, err = unmarshalBinaryBits(buf, f.m) + if err != nil { + return err + } + + return checkBinaryHash(buf, data) +} diff --git a/vendor/github.com/steakknife/bloomfilter/bloomfilter.go b/vendor/github.com/steakknife/bloomfilter/bloomfilter.go new file mode 100644 index 00000000..82250636 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/bloomfilter.go @@ -0,0 +1,123 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "hash" + "sync" +) + +// Filter is an opaque Bloom filter type +type Filter struct { + lock sync.RWMutex + bits []uint64 + keys []uint64 + m uint64 // number of bits the "bits" field should recognize + n uint64 // number of inserted elements +} + +// Hashable -> hashes +func (f *Filter) hash(v hash.Hash64) []uint64 { + rawHash := v.Sum64() + n := len(f.keys) + hashes := make([]uint64, n) + for i := 0; i < n; i++ { + hashes[i] = rawHash ^ f.keys[i] + } + return hashes +} + +// M is the size of Bloom filter, in bits +func (f *Filter) M() uint64 { + return f.m +} + +// K is the count of keys +func (f *Filter) K() uint64 { + return uint64(len(f.keys)) +} + +// Add a hashable item, v, to the filter +func (f *Filter) Add(v hash.Hash64) { + f.lock.Lock() + defer f.lock.Unlock() + + for _, i := range f.hash(v) { + // f.setBit(i) + i %= f.m + f.bits[i>>6] |= 1 << uint(i&0x3f) + } + f.n++ +} + +// Contains tests if f contains v +// false: f definitely does not contain value v +// true: f maybe contains value v +func (f *Filter) Contains(v hash.Hash64) bool { + f.lock.RLock() + defer f.lock.RUnlock() + + r := uint64(1) + for _, i := range f.hash(v) { + // r |= f.getBit(k) + i %= f.m + r &= (f.bits[i>>6] >> uint(i&0x3f)) & 1 + } + return uint64ToBool(r) +} + +// Copy f to a new Bloom filter +func (f *Filter) Copy() (*Filter, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + out, err := f.NewCompatible() + if err != nil { + return nil, err + } + copy(out.bits, f.bits) + out.n = f.n + return out, nil +} + +// UnionInPlace merges Bloom filter f2 into f +func (f *Filter) UnionInPlace(f2 *Filter) error { + if !f.IsCompatible(f2) { + return errIncompatibleBloomFilters() + } + + f.lock.Lock() + defer f.lock.Unlock() + + for i, bitword := range f2.bits { + f.bits[i] |= bitword + } + return nil +} + +// Union merges f2 and f2 into a new Filter out +func (f *Filter) Union(f2 *Filter) (out *Filter, err error) { + if !f.IsCompatible(f2) { + return nil, errIncompatibleBloomFilters() + } + + f.lock.RLock() + defer f.lock.RUnlock() + + out, err = f.NewCompatible() + if err != nil { + return nil, err + } + for i, bitword := range f2.bits { + out.bits[i] = f.bits[i] | bitword + } + return out, nil +} diff --git a/vendor/github.com/steakknife/bloomfilter/conformance.go b/vendor/github.com/steakknife/bloomfilter/conformance.go new file mode 100644 index 00000000..2963686f --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/conformance.go @@ -0,0 +1,29 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "encoding" + "encoding/gob" + "io" +) + +// compile-time conformance tests +var ( + _ encoding.BinaryMarshaler = (*Filter)(nil) + _ encoding.BinaryUnmarshaler = (*Filter)(nil) + _ encoding.TextMarshaler = (*Filter)(nil) + _ encoding.TextUnmarshaler = (*Filter)(nil) + _ io.ReaderFrom = (*Filter)(nil) + _ io.WriterTo = (*Filter)(nil) + _ gob.GobDecoder = (*Filter)(nil) + _ gob.GobEncoder = (*Filter)(nil) +) diff --git a/vendor/github.com/steakknife/bloomfilter/debug.go b/vendor/github.com/steakknife/bloomfilter/debug.go new file mode 100644 index 00000000..e88b934c --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/debug.go @@ -0,0 +1,37 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "log" + "os" +) + +const debugVar = "GOLANG_STEAKKNIFE_BLOOMFILTER_DEBUG" + +// EnableDebugging permits debug() logging of details to stderr +func EnableDebugging() { + err := os.Setenv(debugVar, "1") + if err != nil { + panic("Unable to Setenv " + debugVar) + } +} + +func debugging() bool { + return os.Getenv(debugVar) != "" +} + +// debug printing when debugging() is true +func debug(format string, a ...interface{}) { + if debugging() { + log.Printf(format, a...) + } +} diff --git a/vendor/github.com/steakknife/bloomfilter/errors.go b/vendor/github.com/steakknife/bloomfilter/errors.go new file mode 100644 index 00000000..b279739b --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/errors.go @@ -0,0 +1,34 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import "fmt" + +func errHash() error { + return fmt.Errorf( + "Hash mismatch, the Bloom filter is probably corrupt") +} +func errK() error { + return fmt.Errorf( + "keys must have length %d or greater", KMin) +} +func errM() error { + return fmt.Errorf( + "m (number of bits in the Bloom filter) must be >= %d", MMin) +} +func errUniqueKeys() error { + return fmt.Errorf( + "Bloom filter keys must be unique") +} +func errIncompatibleBloomFilters() error { + return fmt.Errorf( + "Cannot perform union on two incompatible Bloom filters") +} diff --git a/vendor/github.com/steakknife/bloomfilter/fileio.go b/vendor/github.com/steakknife/bloomfilter/fileio.go new file mode 100644 index 00000000..a4796995 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/fileio.go @@ -0,0 +1,105 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "compress/gzip" + "io" + "io/ioutil" + "os" +) + +// ReadFrom r and overwrite f with new Bloom filter data +func (f *Filter) ReadFrom(r io.Reader) (n int64, err error) { + f2, n, err := ReadFrom(r) + if err != nil { + return -1, err + } + f.lock.Lock() + defer f.lock.Unlock() + f.m = f2.m + f.n = f2.n + f.bits = f2.bits + f.keys = f2.keys + return n, nil +} + +// ReadFrom Reader r into a lossless-compressed Bloom filter f +func ReadFrom(r io.Reader) (f *Filter, n int64, err error) { + rawR, err := gzip.NewReader(r) + if err != nil { + return nil, -1, err + } + defer func() { + err = rawR.Close() + }() + + content, err := ioutil.ReadAll(rawR) + if err != nil { + return nil, -1, err + } + + f = new(Filter) + n = int64(len(content)) + err = f.UnmarshalBinary(content) + if err != nil { + return nil, -1, err + } + return f, n, nil +} + +// ReadFile from filename into a lossless-compressed Bloom Filter f +// Suggested file extension: .bf.gz +func ReadFile(filename string) (f *Filter, n int64, err error) { + r, err := os.Open(filename) + if err != nil { + return nil, -1, err + } + defer func() { + err = r.Close() + }() + + return ReadFrom(r) +} + +// WriteTo a Writer w from lossless-compressed Bloom Filter f +func (f *Filter) WriteTo(w io.Writer) (n int64, err error) { + f.lock.RLock() + defer f.lock.RUnlock() + + rawW := gzip.NewWriter(w) + defer func() { + err = rawW.Close() + }() + + content, err := f.MarshalBinary() + if err != nil { + return -1, err + } + + intN, err := rawW.Write(content) + n = int64(intN) + return n, err +} + +// WriteFile filename from a a lossless-compressed Bloom Filter f +// Suggested file extension: .bf.gz +func (f *Filter) WriteFile(filename string) (n int64, err error) { + w, err := os.Create(filename) + if err != nil { + return -1, err + } + defer func() { + err = w.Close() + }() + + return f.WriteTo(w) +} diff --git a/vendor/github.com/steakknife/bloomfilter/gob.go b/vendor/github.com/steakknife/bloomfilter/gob.go new file mode 100644 index 00000000..0d99e55d --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/gob.go @@ -0,0 +1,23 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import _ "encoding/gob" // make sure gob is available + +// GobDecode conforms to interface gob.GobDecoder +func (f *Filter) GobDecode(data []byte) error { + return f.UnmarshalBinary(data) +} + +// GobEncode conforms to interface gob.GobEncoder +func (f *Filter) GobEncode() ([]byte, error) { + return f.MarshalBinary() +} diff --git a/vendor/github.com/steakknife/bloomfilter/iscompatible.go b/vendor/github.com/steakknife/bloomfilter/iscompatible.go new file mode 100644 index 00000000..2073d808 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/iscompatible.go @@ -0,0 +1,41 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import "unsafe" + +func uint64ToBool(x uint64) bool { + return *(*bool)(unsafe.Pointer(&x)) // #nosec +} + +// returns 0 if equal, does not compare len(b0) with len(b1) +func noBranchCompareUint64s(b0, b1 []uint64) uint64 { + r := uint64(0) + for i, b0i := range b0 { + r |= b0i ^ b1[i] + } + return r +} + +// IsCompatible is true if f and f2 can be Union()ed together +func (f *Filter) IsCompatible(f2 *Filter) bool { + f.lock.RLock() + defer f.lock.RUnlock() + + f.lock.RLock() + defer f2.lock.RUnlock() + + // 0 is true, non-0 is false + compat := f.M() ^ f2.M() + compat |= f.K() ^ f2.K() + compat |= noBranchCompareUint64s(f.keys, f2.keys) + return uint64ToBool(^compat) +} diff --git a/vendor/github.com/steakknife/bloomfilter/new.go b/vendor/github.com/steakknife/bloomfilter/new.go new file mode 100644 index 00000000..bf4323a7 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/new.go @@ -0,0 +1,134 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "crypto/rand" + "encoding/binary" + "log" +) + +const ( + // MMin is the minimum Bloom filter bits count + MMin = 2 + // KMin is the minimum number of keys + KMin = 1 + // Uint64Bytes is the number of bytes in type uint64 + Uint64Bytes = 8 +) + +// New Filter with CSPRNG keys +// +// m is the size of the Bloom filter, in bits, >= 2 +// +// k is the number of random keys, >= 1 +func New(m, k uint64) (*Filter, error) { + return NewWithKeys(m, newRandKeys(k)) +} + +func newRandKeys(k uint64) []uint64 { + keys := make([]uint64, k) + err := binary.Read(rand.Reader, binary.LittleEndian, keys) + if err != nil { + log.Panicf( + "Cannot read %d bytes from CSRPNG crypto/rand.Read (err=%v)", + Uint64Bytes, err, + ) + } + return keys +} + +// NewCompatible Filter compatible with f +func (f *Filter) NewCompatible() (*Filter, error) { + return NewWithKeys(f.m, f.keys) +} + +// NewOptimal Bloom filter with random CSPRNG keys +func NewOptimal(maxN uint64, p float64) (*Filter, error) { + m := OptimalM(maxN, p) + k := OptimalK(m, maxN) + debug("New optimal bloom filter ::"+ + " requested max elements (n):%d,"+ + " probability of collision (p):%1.10f "+ + "-> recommends -> bits (m): %d (%f GiB), "+ + "number of keys (k): %d", + maxN, p, m, float64(m)/(gigabitsPerGiB), k) + return New(m, k) +} + +// UniqueKeys is true if all keys are unique +func UniqueKeys(keys []uint64) bool { + for j := 0; j < len(keys)-1; j++ { + elem := keys[j] + for i := 1; i < j; i++ { + if keys[i] == elem { + return false + } + } + } + return true +} + +// NewWithKeys creates a new Filter from user-supplied origKeys +func NewWithKeys(m uint64, origKeys []uint64) (f *Filter, err error) { + bits, err := newBits(m) + if err != nil { + return nil, err + } + keys, err := newKeysCopy(origKeys) + if err != nil { + return nil, err + } + return &Filter{ + m: m, + n: 0, + bits: bits, + keys: keys, + }, nil +} + +func newBits(m uint64) ([]uint64, error) { + if m < MMin { + return nil, errM() + } + return make([]uint64, (m+63)/64), nil +} + +func newKeysBlank(k uint64) ([]uint64, error) { + if k < KMin { + return nil, errK() + } + return make([]uint64, k), nil +} + +func newKeysCopy(origKeys []uint64) (keys []uint64, err error) { + if !UniqueKeys(origKeys) { + return nil, errUniqueKeys() + } + keys, err = newKeysBlank(uint64(len(origKeys))) + if err != nil { + return keys, err + } + copy(keys, origKeys) + return keys, err +} + +func newWithKeysAndBits(m uint64, keys []uint64, bits []uint64, n uint64) ( + f *Filter, err error, +) { + f, err = NewWithKeys(m, keys) + if err != nil { + return nil, err + } + copy(f.bits, bits) + f.n = n + return f, nil +} diff --git a/vendor/github.com/steakknife/bloomfilter/optimal.go b/vendor/github.com/steakknife/bloomfilter/optimal.go new file mode 100644 index 00000000..6e5257eb --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/optimal.go @@ -0,0 +1,28 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import "math" + +const gigabitsPerGiB float64 = 8.0 * 1024 * 1024 * 1024 + +// OptimalK calculates the optimal k value for creating a new Bloom filter +// maxn is the maximum anticipated number of elements +func OptimalK(m, maxN uint64) uint64 { + return uint64(math.Ceil(float64(m) * math.Ln2 / float64(maxN))) +} + +// OptimalM calculates the optimal m value for creating a new Bloom filter +// p is the desired false positive probability +// optimal m = ceiling( - n * ln(p) / ln(2)**2 ) +func OptimalM(maxN uint64, p float64) uint64 { + return uint64(math.Ceil(-float64(maxN) * math.Log(p) / math.Ln2 * math.Ln2)) +} diff --git a/vendor/github.com/steakknife/bloomfilter/statistics.go b/vendor/github.com/steakknife/bloomfilter/statistics.go new file mode 100644 index 00000000..fe50ffa5 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/statistics.go @@ -0,0 +1,43 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "math" + + "github.com/steakknife/hamming" +) + +// PreciseFilledRatio is an exhaustive count # of 1's +func (f *Filter) PreciseFilledRatio() float64 { + f.lock.RLock() + defer f.lock.RUnlock() + + return float64(hamming.CountBitsUint64s(f.bits)) / float64(f.M()) +} + +// N is how many elements have been inserted +// (actually, how many Add()s have been performed?) +func (f *Filter) N() uint64 { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.n +} + +// FalsePosititveProbability is the upper-bound probability of false positives +// (1 - exp(-k*(n+0.5)/(m-1))) ** k +func (f *Filter) FalsePosititveProbability() float64 { + k := float64(f.K()) + n := float64(f.N()) + m := float64(f.M()) + return math.Pow(1.0-math.Exp(-k)*(n+0.5)/(m-1), k) +} diff --git a/vendor/github.com/steakknife/bloomfilter/textmarshaler.go b/vendor/github.com/steakknife/bloomfilter/textmarshaler.go new file mode 100644 index 00000000..7ed08eb7 --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/textmarshaler.go @@ -0,0 +1,49 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import "fmt" + +// MarshalText conforms to encoding.TextMarshaler +func (f *Filter) MarshalText() (text []byte, err error) { + f.lock.RLock() + defer f.lock.RUnlock() + + s := fmt.Sprintln("k") + s += fmt.Sprintln(f.K()) + s += fmt.Sprintln("n") + s += fmt.Sprintln(f.n) + s += fmt.Sprintln("m") + s += fmt.Sprintln(f.m) + + s += fmt.Sprintln("keys") + for key := range f.keys { + s += fmt.Sprintf(keyFormat, key) + nl() + } + + s += fmt.Sprintln("bits") + for w := range f.bits { + s += fmt.Sprintf(bitsFormat, w) + nl() + } + + _, hash, err := f.marshal() + if err != nil { + return nil, err + } + s += fmt.Sprintln("sha384") + for b := range hash { + s += fmt.Sprintf("%02x", b) + } + s += nl() + + text = []byte(s) + return text, nil +} diff --git a/vendor/github.com/steakknife/bloomfilter/textunmarshaler.go b/vendor/github.com/steakknife/bloomfilter/textunmarshaler.go new file mode 100644 index 00000000..93240a1a --- /dev/null +++ b/vendor/github.com/steakknife/bloomfilter/textunmarshaler.go @@ -0,0 +1,150 @@ +// Package bloomfilter is face-meltingly fast, thread-safe, +// marshalable, unionable, probability- and +// optimal-size-calculating Bloom filter in go +// +// https://github.com/steakknife/bloomfilter +// +// Copyright © 2014, 2015, 2018 Barry Allard +// +// MIT license +// +package bloomfilter + +import ( + "bytes" + "crypto/hmac" + "crypto/sha512" + "fmt" + "io" +) + +const ( + keyFormat = "%016x" + bitsFormat = "%016x" +) + +func nl() string { + return fmt.Sprintln() +} + +func unmarshalTextHeader(r io.Reader) (k, n, m uint64, err error) { + format := "k" + nl() + "%d" + nl() + format += "n" + nl() + "%d" + nl() + format += "m" + nl() + "%d" + nl() + format += "keys" + nl() + + _, err = fmt.Fscanf(r, format, k, n, m) + return k, n, m, err +} + +func unmarshalTextKeys(r io.Reader, keys []uint64) (err error) { + for i := range keys { + _, err = fmt.Fscanf(r, keyFormat, keys[i]) + if err != nil { + return err + } + } + return nil +} + +func unmarshalTextBits(r io.Reader, bits []uint64) (err error) { + _, err = fmt.Fscanf(r, "bits") + if err != nil { + return err + } + + for i := range bits { + _, err = fmt.Fscanf(r, bitsFormat, bits[i]) + if err != nil { + return err + } + } + + return nil +} + +func unmarshalAndCheckTextHash(r io.Reader, f *Filter) (err error) { + _, err = fmt.Fscanf(r, "sha384") + if err != nil { + return err + } + + actualHash := [sha512.Size384]byte{} + + for i := range actualHash { + _, err = fmt.Fscanf(r, "%02x", actualHash[i]) + if err != nil { + return err + } + } + + _, expectedHash, err := f.marshal() + if err != nil { + return err + } + + if !hmac.Equal(expectedHash[:], actualHash[:]) { + return errHash() + } + + return nil +} + +// UnmarshalText conforms to TextUnmarshaler +func UnmarshalText(text []byte) (f *Filter, err error) { + r := bytes.NewBuffer(text) + k, n, m, err := unmarshalTextHeader(r) + if err != nil { + return nil, err + } + + keys, err := newKeysBlank(k) + if err != nil { + return nil, err + } + + err = unmarshalTextKeys(r, keys) + if err != nil { + return nil, err + } + + bits, err := newBits(m) + if err != nil { + return nil, err + } + + err = unmarshalTextBits(r, bits) + if err != nil { + return nil, err + } + + f, err = newWithKeysAndBits(m, keys, bits, n) + if err != nil { + return nil, err + } + + err = unmarshalAndCheckTextHash(r, f) + if err != nil { + return nil, err + } + + return f, nil +} + +// UnmarshalText method overwrites f with data decoded from text +func (f *Filter) UnmarshalText(text []byte) error { + f.lock.Lock() + defer f.lock.Unlock() + + f2, err := UnmarshalText(text) + if err != nil { + return err + } + + f.m = f2.m + f.n = f2.n + copy(f.bits, f2.bits) + copy(f.keys, f2.keys) + + return nil +} diff --git a/vendor/github.com/steakknife/hamming/.gitignore b/vendor/github.com/steakknife/hamming/.gitignore new file mode 100644 index 00000000..928a2c6d --- /dev/null +++ b/vendor/github.com/steakknife/hamming/.gitignore @@ -0,0 +1,2 @@ +*.o +/coverage.out diff --git a/vendor/github.com/steakknife/hamming/.travis.yml b/vendor/github.com/steakknife/hamming/.travis.yml new file mode 100644 index 00000000..73812128 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/.travis.yml @@ -0,0 +1,14 @@ +language: go +dist: trusty +sudo: false +go: + - "1.8.x" + - "1.9.x" + - "1.10.x" + - master +before_script: + - "go get -u gopkg.in/alecthomas/gometalinter.v2" + - "gometalinter.v2 --install" +script: + - "go test -v -cover -benchmem -bench=. $(go list ./... | grep -v /vendor/ | sed \"s&_${PWD}&.&\")" + - "gometalinter.v2 --enable-all --exclude=dupl ./..." diff --git a/vendor/github.com/steakknife/hamming/MIT-LICENSE.txt b/vendor/github.com/steakknife/hamming/MIT-LICENSE.txt new file mode 100644 index 00000000..924f4c09 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/MIT-LICENSE.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright © 2014, 2015, 2016 Barry Allard + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/steakknife/hamming/README.md b/vendor/github.com/steakknife/hamming/README.md new file mode 100644 index 00000000..3f0af784 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/README.md @@ -0,0 +1,82 @@ +[![GoDoc](https://godoc.org/github.com/steakknife/hamming?status.png)](https://godoc.org/github.com/steakknife/hamming) [![Build Status](https://travis-ci.org/steakknife/hamming.svg?branch=master)](https://travis-ci.org/steakknife/hamming) + + +# hamming distance calculations in Go + +Copyright © 2014, 2015, 2016 Barry Allard + +[MIT license](MIT-LICENSE.txt) + +## Performance + +``` +$ go test -bench=. +BenchmarkCountBitsInt8PopCnt-4 300000000 4.30 ns/op +BenchmarkCountBitsInt16PopCnt-4 300000000 3.83 ns/op +BenchmarkCountBitsInt32PopCnt-4 300000000 3.64 ns/op +BenchmarkCountBitsInt64PopCnt-4 500000000 3.60 ns/op +BenchmarkCountBitsIntPopCnt-4 300000000 5.72 ns/op +BenchmarkCountBitsUint8PopCnt-4 1000000000 2.98 ns/op +BenchmarkCountBitsUint16PopCnt-4 500000000 3.23 ns/op +BenchmarkCountBitsUint32PopCnt-4 500000000 3.00 ns/op +BenchmarkCountBitsUint64PopCnt-4 1000000000 2.94 ns/op +BenchmarkCountBitsUintPopCnt-4 300000000 5.04 ns/op +BenchmarkCountBitsBytePopCnt-4 300000000 3.99 ns/op +BenchmarkCountBitsRunePopCnt-4 300000000 3.83 ns/op +BenchmarkCountBitsInt8-4 2000000000 0.74 ns/op +BenchmarkCountBitsInt16-4 2000000000 1.54 ns/op +BenchmarkCountBitsInt32-4 1000000000 2.63 ns/op +BenchmarkCountBitsInt64-4 1000000000 2.56 ns/op +BenchmarkCountBitsInt-4 200000000 7.23 ns/op +BenchmarkCountBitsUint16-4 2000000000 1.51 ns/op +BenchmarkCountBitsUint32-4 500000000 4.00 ns/op +BenchmarkCountBitsUint64-4 1000000000 2.64 ns/op +BenchmarkCountBitsUint64Alt-4 200000000 7.60 ns/op +BenchmarkCountBitsUint-4 300000000 5.48 ns/op +BenchmarkCountBitsUintReference-4 100000000 19.2 ns/op +BenchmarkCountBitsByte-4 2000000000 0.75 ns/op +BenchmarkCountBitsByteAlt-4 1000000000 2.37 ns/op +BenchmarkCountBitsRune-4 500000000 2.85 ns/op +PASS +ok _/Users/bmf/Projects/hamming 58.305s +$ +``` + +## Usage + +```go +import 'github.com/steakknife/hamming' + +// ... + +// hamming distance between values +hamming.Byte(0xFF, 0x00) // 8 +hamming.Byte(0x00, 0x00) // 0 + +// just count bits in a byte +hamming.CountBitsByte(0xA5), // 4 +``` + +See help in the [docs](https://godoc.org/github.com/steakknife/hamming) + +## Get + + go get -u github.com/steakknife/hamming # master is always stable + +## Source + +- On the web: https://github.com/steakknife/hamming + +- Git: `git clone https://github.com/steakknife/hamming` + +## Contact + +- [Feedback](mailto:barry.allard@gmail.com) + +- [Issues](https://github.com/steakknife/hamming/issues) + +## License + +[MIT license](MIT-LICENSE.txt) + +Copyright © 2014, 2015, 2016 Barry Allard diff --git a/vendor/github.com/steakknife/hamming/doc.go b/vendor/github.com/steakknife/hamming/doc.go new file mode 100644 index 00000000..179e29da --- /dev/null +++ b/vendor/github.com/steakknife/hamming/doc.go @@ -0,0 +1,35 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +// +// Usage +// +// For functions named CountBits.+s?. The plural forms are for slices. +// The CountBits.+ forms are Population Count only, where the bare-type +// forms are Hamming distance (number of bits different) between two values. +// +// Optimized assembly .+PopCnt forms are available on amd64, and operate just +// like the regular forms (Must check and guard on HasPopCnt() first before +// trying to call .+PopCnt functions). +// +// import 'github.com/steakknife/hamming' +// +// // ... +// +// // hamming distance between values +// hamming.Byte(0xFF, 0x00) // 8 +// hamming.Byte(0x00, 0x00) // 0 +// +// // just count bits in a byte +// hamming.CountBitsByte(0xA5), // 4 +// +// Got rune? use int32 +// Got uint8? use byte +// +package hamming diff --git a/vendor/github.com/steakknife/hamming/hamming.go b/vendor/github.com/steakknife/hamming/hamming.go new file mode 100644 index 00000000..269e91a4 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/hamming.go @@ -0,0 +1,70 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +// Int8 hamming distance of two int8's +func Int8(x, y int8) int { + return CountBitsInt8(x ^ y) +} + +// Int16 hamming distance of two int16's +func Int16(x, y int16) int { + return CountBitsInt16(x ^ y) +} + +// Int32 hamming distance of two int32's +func Int32(x, y int32) int { + return CountBitsInt32(x ^ y) +} + +// Int64 hamming distance of two int64's +func Int64(x, y int64) int { + return CountBitsInt64(x ^ y) +} + +// Int hamming distance of two ints +func Int(x, y int) int { + return CountBitsInt(x ^ y) +} + +// Uint8 hamming distance of two uint8's +func Uint8(x, y uint8) int { + return CountBitsUint8(x ^ y) +} + +// Uint16 hamming distance of two uint16's +func Uint16(x, y uint16) int { + return CountBitsUint16(x ^ y) +} + +// Uint32 hamming distance of two uint32's +func Uint32(x, y uint32) int { + return CountBitsUint32(x ^ y) +} + +// Uint64 hamming distance of two uint64's +func Uint64(x, y uint64) int { + return CountBitsUint64(x ^ y) +} + +// Uint hamming distance of two uint's +func Uint(x, y uint) int { + return CountBitsUint(x ^ y) +} + +// Byte hamming distance of two bytes +func Byte(x, y byte) int { + return CountBitsByte(x ^ y) +} + +// Rune hamming distance of two runes +func Rune(x, y rune) int { + return CountBitsRune(x ^ y) +} diff --git a/vendor/github.com/steakknife/hamming/popcnt_amd64.go b/vendor/github.com/steakknife/hamming/popcnt_amd64.go new file mode 100644 index 00000000..a1a6d92b --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcnt_amd64.go @@ -0,0 +1,65 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +import "strconv" + +// HasPopCnt returns true if *PopCnt functions are callable +func HasPopCnt() (ret bool) + +// CountBitsInt8PopCnt count 1's in x +func CountBitsInt8PopCnt(x int8) (ret int) + +// CountBitsInt16PopCnt count 1's in x +func CountBitsInt16PopCnt(x int16) (ret int) + +// CountBitsInt32PopCnt count 1's in x +func CountBitsInt32PopCnt(x int32) (ret int) + +// CountBitsInt64PopCnt count 1's in x +func CountBitsInt64PopCnt(x int64) (ret int) + +// CountBitsIntPopCnt count 1's in x +func CountBitsIntPopCnt(x int) int { + if strconv.IntSize == 64 { + return CountBitsInt64PopCnt(int64(x)) + } else if strconv.IntSize == 32 { + return CountBitsInt32PopCnt(int32(x)) + } + panic("strconv.IntSize must be 32 or 64") +} + +// CountBitsUint8PopCnt count 1's in x +func CountBitsUint8PopCnt(x uint8) (ret int) + +// CountBitsUint16PopCnt count 1's in x +func CountBitsUint16PopCnt(x uint16) (ret int) + +// CountBitsUint32PopCnt count 1's in x +func CountBitsUint32PopCnt(x uint32) (ret int) + +// CountBitsUint64PopCnt count 1's in x +func CountBitsUint64PopCnt(x uint64) (ret int) + +// CountBitsUintPopCnt count 1's in x +func CountBitsUintPopCnt(x uint) int { + if strconv.IntSize == 64 { + return CountBitsUint64PopCnt(uint64(x)) + } else if strconv.IntSize == 32 { + return CountBitsUint32PopCnt(uint32(x)) + } + panic("strconv.IntSize must be 32 or 64") +} + +// CountBitsBytePopCnt count 1's in x +func CountBitsBytePopCnt(x byte) (ret int) + +// CountBitsRunePopCnt count 1's in x +func CountBitsRunePopCnt(x rune) (ret int) diff --git a/vendor/github.com/steakknife/hamming/popcnt_amd64.s b/vendor/github.com/steakknife/hamming/popcnt_amd64.s new file mode 100644 index 00000000..51c51248 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcnt_amd64.s @@ -0,0 +1,64 @@ +// +// hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016 Barry Allard +// +// MIT license +// + +#include "textflag.h" + +TEXT ·CountBitsInt8PopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsBytePopCnt(SB) + +TEXT ·CountBitsInt16PopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint16PopCnt(SB) + +TEXT ·CountBitsInt32PopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint32PopCnt(SB) + +TEXT ·CountBitsInt64PopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint64PopCnt(SB) + +TEXT ·CountBitsBytePopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint8PopCnt(SB) + +TEXT ·CountBitsRunePopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint32PopCnt(SB) + +TEXT ·CountBitsUint8PopCnt(SB),NOSPLIT,$0 + XORQ AX, AX + MOVB x+0(FP), AX + POPCNTQ AX, AX + MOVQ AX, ret+8(FP) + RET + +TEXT ·CountBitsUint16PopCnt(SB),NOSPLIT,$0 + XORQ AX, AX + MOVW x+0(FP), AX + POPCNTQ AX, AX + MOVQ AX, ret+8(FP) + RET + +TEXT ·CountBitsUint32PopCnt(SB),NOSPLIT,$0 + XORQ AX, AX + MOVL x+0(FP), AX + POPCNTQ AX, AX + MOVQ AX, ret+8(FP) + RET + +TEXT ·CountBitsUint64PopCnt(SB),NOSPLIT,$0 + POPCNTQ x+0(FP), AX + MOVQ AX, ret+8(FP) + RET + +// func hasPopCnt() (ret bool) +TEXT ·HasPopCnt(SB),NOSPLIT,$0 + MOVL $1, AX + CPUID + SHRL $23, CX // bit 23: Advanced Bit Manipulation Bit (ABM) -> POPCNTQ + ANDL $1, CX + MOVB CX, ret+0(FP) + RET diff --git a/vendor/github.com/steakknife/hamming/popcount.go b/vendor/github.com/steakknife/hamming/popcount.go new file mode 100644 index 00000000..848103bb --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcount.go @@ -0,0 +1,134 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +import "strconv" + +// References: check out Hacker's Delight, about p. 70 + +func table() [256]uint8 { + return [256]uint8{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, + } +} + +// CountBitsByteAlt table-less, branch-free implementation +func CountBitsByteAlt(x byte) int { + x = (x & 0x55) + ((x >> 1) & 0x55) + x = (x & 0x33) + ((x >> 2) & 0x33) + return int((x & 0x0f) + ((x >> 4) & 0x0f)) +} + +// CountBitsInt8 count 1's in x +func CountBitsInt8(x int8) int { return CountBitsByte(byte(x)) } + +// CountBitsInt16 count 1's in x +func CountBitsInt16(x int16) int { return CountBitsUint16(uint16(x)) } + +// CountBitsInt32 count 1's in x +func CountBitsInt32(x int32) int { return CountBitsUint32(uint32(x)) } + +// CountBitsInt64 count 1's in x +func CountBitsInt64(x int64) int { return CountBitsUint64(uint64(x)) } + +// CountBitsInt count 1's in x +func CountBitsInt(x int) int { return CountBitsUint(uint(x)) } + +// CountBitsByte count 1's in x +func CountBitsByte(x byte) int { return CountBitsUint8(x) } + +// CountBitsRune count 1's in x +func CountBitsRune(x rune) int { return CountBitsInt32(x) } + +// CountBitsUint8 count 1's in x +func CountBitsUint8(x uint8) int { return int(table()[x]) } + +// CountBitsUint16 count 1's in x +func CountBitsUint16(x uint16) int { + return int(table()[x&0xFF] + table()[(x>>8)&0xFF]) +} + +const ( + m1d uint32 = 0x55555555 + m2d = 0x33333333 + m4d = 0x0f0f0f0f +) + +// CountBitsUint32 count 1's in x +func CountBitsUint32(x uint32) int { + x -= ((x >> 1) & m1d) + x = (x & m2d) + ((x >> 2) & m2d) + x = (x + (x >> 4)) & m4d + x += x >> 8 + x += x >> 16 + return int(x & 0x3f) +} + +const ( + m1q uint64 = 0x5555555555555555 + m2q = 0x3333333333333333 + m4q = 0x0f0f0f0f0f0f0f0f + hq = 0x0101010101010101 +) + +// CountBitsUint64 count 1's in x +func CountBitsUint64(x uint64) int { + // put count of each 2 bits into those 2 bits + x -= (x >> 1) & m1q + + // put count of each 4 bits into those 4 bits + x = (x & m2q) + ((x >> 2) & m2q) + + // put count of each 8 bits into those 8 bits + x = (x + (x >> 4)) & m4q + + // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... + return int((x * hq) >> 56) +} + +// CountBitsUint64Alt count 1's in x +func CountBitsUint64Alt(x uint64) int { + return CountBitsUint32(uint32(x>>32)) + CountBitsUint32(uint32(x)) +} + +// CountBitsUintReference count 1's in x +func CountBitsUintReference(x uint) int { + c := 0 + for x != 0 { + x &= x - 1 + c++ + } + return c +} + +// CountBitsUint count 1's in x +func CountBitsUint(x uint) int { + if strconv.IntSize == 64 { + return CountBitsUint64(uint64(x)) + } else if strconv.IntSize == 32 { + return CountBitsUint32(uint32(x)) + } + panic("strconv.IntSize must be 32 or 64 bits") +} diff --git a/vendor/github.com/steakknife/hamming/popcount_slices.go b/vendor/github.com/steakknife/hamming/popcount_slices.go new file mode 100644 index 00000000..957fe116 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcount_slices.go @@ -0,0 +1,123 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +// CountBitsInt8s count 1's in b +func CountBitsInt8s(b []int8) int { + c := 0 + for _, x := range b { + c += CountBitsInt8(x) + } + return c +} + +// CountBitsInt16s count 1's in b +func CountBitsInt16s(b []int16) int { + c := 0 + for _, x := range b { + c += CountBitsInt16(x) + } + return c +} + +// CountBitsInt32s count 1's in b +func CountBitsInt32s(b []int32) int { + c := 0 + for _, x := range b { + c += CountBitsInt32(x) + } + return c +} + +// CountBitsInt64s count 1's in b +func CountBitsInt64s(b []int64) int { + c := 0 + for _, x := range b { + c += CountBitsInt64(x) + } + return c +} + +// CountBitsInts count 1's in b +func CountBitsInts(b []int) int { + c := 0 + for _, x := range b { + c += CountBitsInt(x) + } + return c +} + +// CountBitsUint8s count 1's in b +func CountBitsUint8s(b []uint8) int { + c := 0 + for _, x := range b { + c += CountBitsUint8(x) + } + return c +} + +// CountBitsUint16s count 1's in b +func CountBitsUint16s(b []uint16) int { + c := 0 + for _, x := range b { + c += CountBitsUint16(x) + } + return c +} + +// CountBitsUint32s count 1's in b +func CountBitsUint32s(b []uint32) int { + c := 0 + for _, x := range b { + c += CountBitsUint32(x) + } + return c +} + +// CountBitsUint64s count 1's in b +func CountBitsUint64s(b []uint64) int { + c := 0 + for _, x := range b { + c += CountBitsUint64(x) + } + return c +} + +// CountBitsUints count 1's in b +func CountBitsUints(b []uint) int { + c := 0 + for _, x := range b { + c += CountBitsUint(x) + } + return c +} + +// CountBitsBytes count 1's in b +func CountBitsBytes(b []byte) int { + c := 0 + for _, x := range b { + c += CountBitsByte(x) + } + return c +} + +// CountBitsRunes count 1's in b +func CountBitsRunes(b []rune) int { + c := 0 + for _, x := range b { + c += CountBitsRune(x) + } + return c +} + +// CountBitsString count 1's in s +func CountBitsString(s string) int { + return CountBitsBytes([]byte(s)) +} diff --git a/vendor/github.com/steakknife/hamming/popcount_slices_amd64.go b/vendor/github.com/steakknife/hamming/popcount_slices_amd64.go new file mode 100644 index 00000000..b3e13fdf --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcount_slices_amd64.go @@ -0,0 +1,72 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +import ( + "strconv" + "unsafe" +) + +// CountBitsInt8sPopCnt count 1's in x +func CountBitsInt8sPopCnt(x []int8) (ret int) + +// CountBitsInt16sPopCnt count 1's in x +func CountBitsInt16sPopCnt(x []int16) (ret int) + +// CountBitsInt32sPopCnt count 1's in x +func CountBitsInt32sPopCnt(x []int32) (ret int) + +// CountBitsInt64sPopCnt count 1's in x +func CountBitsInt64sPopCnt(x []int64) (ret int) + +// CountBitsIntsPopCnt count 1's in x +func CountBitsIntsPopCnt(x []int) int { + if strconv.IntSize == 64 { + y := (*[]int64)(unsafe.Pointer(&x)) // #nosec G103 + return CountBitsInt64sPopCnt(*y) + } else if strconv.IntSize == 32 { + y := (*[]int32)(unsafe.Pointer(&x)) // #nosec G103 + return CountBitsInt32sPopCnt(*y) + } + panic("strconv.IntSize must be 32 or 64 bits") +} + +// CountBitsUint8sPopCnt count 1's in x +func CountBitsUint8sPopCnt(x []uint8) (ret int) + +// CountBitsUint16sPopCnt count 1's in x +func CountBitsUint16sPopCnt(x []uint16) (ret int) + +// CountBitsUint32sPopCnt count 1's in x +func CountBitsUint32sPopCnt(x []uint32) (ret int) + +// CountBitsUint64sPopCnt count 1's in x +func CountBitsUint64sPopCnt(x []uint64) (ret int) + +// CountBitsUintsPopCnt count 1's in x +func CountBitsUintsPopCnt(x []uint) int { + if strconv.IntSize == 64 { + y := (*[]uint64)(unsafe.Pointer(&x)) // #nosec G103 + return CountBitsUint64sPopCnt(*y) + } else if strconv.IntSize == 32 { + y := (*[]uint32)(unsafe.Pointer(&x)) // #nosec G103 + return CountBitsUint32sPopCnt(*y) + } + panic("strconv.IntSize must be 32 or 64 bits") +} + +// CountBitsBytesPopCnt count 1's in x +func CountBitsBytesPopCnt(x []byte) (ret int) + +// CountBitsRunesPopCnt count 1's in x +func CountBitsRunesPopCnt(x []rune) (ret int) + +// CountBitsStringPopCnt count 1's in s +func CountBitsStringPopCnt(s string) (ret int) diff --git a/vendor/github.com/steakknife/hamming/popcount_slices_amd64.s b/vendor/github.com/steakknife/hamming/popcount_slices_amd64.s new file mode 100644 index 00000000..b6b8c783 --- /dev/null +++ b/vendor/github.com/steakknife/hamming/popcount_slices_amd64.s @@ -0,0 +1,370 @@ +// +// hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016 Barry Allard +// +// MIT license +// + +#include "textflag.h" + +// type SliceHeader struct { +// Data uintptr 0 +// Len int 8 +// Cap int 16 +// } + +// 0 x.Data +// 8 x.Len +// 16 x.Cap +// 24 ret + +// type StringHeader struct { +// Data uintptr 0 +// Len int 8 +// } + +// 0 x.Data +// 8 x.Len +// 16 ret + +// func CountBitsInt8sPopCnt(x []int8) (ret int) +TEXT ·CountBitsInt8sPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint8sPopCnt(SB) + +// func CountBitsInt16sPopCnt(x []int16) (ret int) +TEXT ·CountBitsInt16sPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint16sPopCnt(SB) + +// func CountBitsInt32sPopCnt(x []int32) (ret int) +TEXT ·CountBitsInt32sPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint32sPopCnt(SB) + +// func CountBitsInt64sPopCnt(x []int64) (ret int) +TEXT ·CountBitsInt64sPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint64sPopCnt(SB) + +// func CountBitsUint8sPopCnt(x []uint8) (ret int) +TEXT ·CountBitsUint8sPopCnt(SB),NOSPLIT,$0 + XORQ AX, AX // ret = 0 + MOVQ x+8(FP), CX // x.Len -> CX + +test_negative_slice_len: + MOVQ CX, BX // x.Len < 0 ---> x.Len[63] != 0 + SHRQ $63, BX + JNZ done + + MOVQ x+0(FP), DI // x.Data -> DI + + CMPQ CX, $32 // x.Len >= 32 + JL unrolled_loop_skip + +unrolled_loop_setup: + XORQ R9, R9 + XORQ BX, BX + XORQ DX, DX + +unrolled_loop: // 4 unrolled loops of POPCNTQ (4 quad words at a time) + SUBQ $32, CX + + POPCNTQ 0(DI), R10 + ADDQ R10, R9 + POPCNTQ 8(DI), R11 + ADDQ R11, AX + POPCNTQ 16(DI), R12 + ADDQ R12, BX + POPCNTQ 24(DI), R13 + ADDQ R13, DX + + ADDQ $32, DI + CMPQ CX, $32 // x.Len >= 32 + JGE unrolled_loop + +unrolled_loop_done: + ADDQ R9, AX + ADDQ BX, DX + ADDQ DX, AX + + XORQ BX, BX + +unrolled_loop_skip: + CMPQ CX, $0 + JZ done + + XORQ DX, DX + +remainder_loop: + MOVB 0(DI), DL + POPCNTQ DX, BX + ADDQ BX, AX + + INCQ DI + DECQ CX + JNZ remainder_loop + +done: + MOVQ AX, ret+24(FP) + RET + +// func CountBitsUint16sPopCnt(x []uint16) (ret int) +TEXT ·CountBitsUint16sPopCnt(SB),NOSPLIT,$0 + XORQ AX, AX // ret = 0 + MOVQ x+8(FP), CX // x.Len -> CX + +test_negative_slice_len: + MOVQ CX, BX // x.Len*2 < 0 ---> x.Len[63:62] != 0 + SHLQ $1, CX + SHRQ $62, BX + JNZ done + + MOVQ x+0(FP), DI // x.Data -> DI + + + CMPQ CX, $32 // x.Len*2 >= 32 + JL unrolled_loop_skip + +unrolled_loop_setup: + XORQ R9, R9 + XORQ BX, BX + XORQ DX, DX + +unrolled_loop: // 4 unrolled loops of POPCNTQ (4 quad words at a time) + SUBQ $32, CX + + POPCNTQ 0(DI), R10 + ADDQ R10, R9 + POPCNTQ 8(DI), R11 + ADDQ R11, AX + POPCNTQ 16(DI), R12 + ADDQ R12, BX + POPCNTQ 24(DI), R13 + ADDQ R13, DX + + ADDQ $32, DI + CMPQ CX, $32 // x.Len*2 >= 32 + JGE unrolled_loop + +unrolled_loop_done: + ADDQ R9, AX + ADDQ BX, DX + ADDQ DX, AX + + XORQ BX, BX + +unrolled_loop_skip: + CMPQ CX, $0 + JZ done + + XORQ DX, DX + +remainder_loop: + MOVW 0(DI), DX + POPCNTQ DX, BX + ADDQ BX, AX + + ADDQ $2, DI + SUBQ $2, CX + JNZ remainder_loop + +done: + MOVQ AX, ret+24(FP) + RET + +// func CountBitsUint32sPopCnt(x []uint32) (ret int) +TEXT ·CountBitsUint32sPopCnt(SB),NOSPLIT,$0 + XORQ AX, AX // ret = 0 + MOVQ x+8(FP), CX // x.Len -> CX + MOVQ CX, BX + MOVQ x+0(FP), DI // x.Data -> DI + +test_negative_slice_len: + SHLQ $2, CX // x.Len*4 < 0 ---> x.Len[63:61] != 0 + SHRQ $61, BX + JNZ done + + + + CMPQ CX, $32 // x.Len*4 >= 32 + JL unrolled_loop_skip + +unrolled_loop_setup: + XORQ R9, R9 + XORQ BX, BX + XORQ DX, DX + +unrolled_loop: // 4 unrolled loops of POPCNTQ (4 quad words at a time) + SUBQ $32, CX + + POPCNTQ 0(DI), R10 // r9 += popcntq(QW DI+0) + ADDQ R10, R9 + POPCNTQ 8(DI), R11 // ax += popcntq(QW DI+8) + ADDQ R11, AX + POPCNTQ 16(DI), R12 // bx += popcntq(QW DI+16) + ADDQ R12, BX + POPCNTQ 24(DI), R13 // dx += popcntq(QW DI+24) + ADDQ R13, DX + + ADDQ $32, DI + CMPQ CX, $32 // x.Len*4 >= 32 + JGE unrolled_loop + +unrolled_loop_done: + ADDQ R9, AX // ax = (ax + r9) + (bx + dx) + ADDQ BX, DX + ADDQ DX, AX + + XORQ BX, BX + +unrolled_loop_skip: + CMPQ CX, $0 + JZ done + + XORQ DX, DX +remainder_loop: + MOVB (DI), DX // ax += popcnt(DB 0(DI)) + POPCNTQ DX, BX + ADDQ BX, AX + + INCQ DI + DECQ CX + JNZ remainder_loop + +done: + MOVQ AX, ret+24(FP) + RET + +// func CountBitsUint64sPopCnt(x []uint64) (ret int) +TEXT ·CountBitsUint64sPopCnt(SB),NOSPLIT,$0 + XORQ AX, AX // ret = 0 + MOVQ x+8(FP), CX // x.Len -> CX + +test_negative_slice_len: + MOVQ CX, BX // x.Len*8 < 0 ---> x.Len[63:60] != 0 + SHLQ $3, CX + SHRQ $60, BX + JNZ done + + MOVQ x+0(FP), DI // x.Data -> DI + + + CMPQ CX, $32 // x.Len*8 >= 32 + JL unrolled_loop_skip + +unrolled_loop_setup: + XORQ R9, R9 + XORQ BX, BX + XORQ DX, DX + +unrolled_loop: // 4 unrolled loops of POPCNTQ (4 quad words at a time) + SUBQ $32, CX + + POPCNTQ 0(DI), R10 + ADDQ R10, R9 + POPCNTQ 8(DI), R11 + ADDQ R11, AX + POPCNTQ 16(DI), R12 + ADDQ R12, BX + POPCNTQ 24(DI), R13 + ADDQ R13, DX + + ADDQ $32, DI + CMPQ CX, $32 // x.Len*4 >= 32 + JGE unrolled_loop + +unrolled_loop_done: + ADDQ R9, AX + ADDQ BX, DX + ADDQ DX, AX + + XORQ BX, BX + +unrolled_loop_skip: + CMPQ CX, $0 + JZ done + + XORQ DX, DX + +remainder_loop: + MOVQ 0(DI), DX + POPCNTQ DX, BX + ADDQ BX, AX + + ADDQ $8, DI + SUBQ $8, CX + JNZ remainder_loop + +done: + MOVQ AX, ret+24(FP) + RET + +// func CountBitsBytesPopCnt(x []byte) (ret int) +TEXT ·CountBitsBytesPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint8sPopCnt(SB) + +// func CountBitsRunesPopCnt(x []rune) (ret int) +TEXT ·CountBitsRunesPopCnt(SB),NOSPLIT,$0 + JMP ·CountBitsUint32sPopCnt(SB) + +// func CountBitsStringPopCnt(s string) (ret int) +TEXT ·CountBitsStringPopCnt(SB),NOSPLIT,$0 + XORQ AX, AX // ret = 0 + MOVQ x+8(FP), CX // x.Len -> CX + +test_negative_slice_len: + MOVQ CX, BX // x.Len < 0 ---> x.Len[63] != 0 + SHRQ $63, BX + JNZ done + + MOVQ x+0(FP), DI // x.Data -> DI + + CMPQ CX, $32 // x.Len >= 32 + JL unrolled_loop_skip + +unrolled_loop_setup: + XORQ R9, R9 + XORQ BX, BX + XORQ DX, DX + +unrolled_loop: // 4 unrolled loops of POPCNTQ (4 quad words at a time) + SUBQ $32, CX + + POPCNTQ 0(DI), R10 + ADDQ R10, R9 + POPCNTQ 8(DI), R11 + ADDQ R11, AX + POPCNTQ 16(DI), R12 + ADDQ R12, BX + POPCNTQ 24(DI), R13 + ADDQ R13, DX + + ADDQ $32, DI + CMPQ CX, $32 // x.Len >= 32 + JGE unrolled_loop + +unrolled_loop_done: + ADDQ R9, AX + ADDQ BX, DX + ADDQ DX, AX + + XORQ BX, BX + +unrolled_loop_skip: + CMPQ CX, $0 + JZ done + + XORQ DX, DX + +remainder_loop: + MOVB 0(DI), DL + POPCNTQ DX, BX + ADDQ BX, AX + + INCQ DI + DECQ CX + JNZ remainder_loop + +done: + MOVQ AX, ret+16(FP) + RET diff --git a/vendor/github.com/steakknife/hamming/slices_of_hamming.go b/vendor/github.com/steakknife/hamming/slices_of_hamming.go new file mode 100644 index 00000000..82ce948f --- /dev/null +++ b/vendor/github.com/steakknife/hamming/slices_of_hamming.go @@ -0,0 +1,144 @@ +// +// Package hamming distance calculations in Go +// +// https://github.com/steakknife/hamming +// +// Copyright © 2014, 2015, 2016, 2018 Barry Allard +// +// MIT license +// +package hamming + +// Int8s hamming distance of two int8 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Int8s(b0, b1 []int8) int { + d := 0 + for i, x := range b0 { + d += Int8(x, b1[i]) + } + return d +} + +// Int16s hamming distance of two int16 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Int16s(b0, b1 []int16) int { + d := 0 + for i, x := range b0 { + d += Int16(x, b1[i]) + } + return d +} + +// Int32s hamming distance of two int32 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Int32s(b0, b1 []int32) int { + d := 0 + for i, x := range b0 { + d += Int32(x, b1[i]) + } + return d +} + +// Int64s hamming distance of two int64 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Int64s(b0, b1 []int64) int { + d := 0 + for i, x := range b0 { + d += Int64(x, b1[i]) + } + return d +} + +// Ints hamming distance of two int buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Ints(b0, b1 []int) int { + d := 0 + for i, x := range b0 { + d += Int(x, b1[i]) + } + return d +} + +// Uint8s hamming distance of two uint8 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Uint8s(b0, b1 []uint8) int { + d := 0 + for i, x := range b0 { + d += Uint8(x, b1[i]) + } + return d +} + +// Uint16s hamming distance of two uint16 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Uint16s(b0, b1 []uint16) int { + d := 0 + for i, x := range b0 { + d += Uint16(x, b1[i]) + } + return d +} + +// Uint32s hamming distance of two uint32 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Uint32s(b0, b1 []uint32) int { + d := 0 + for i, x := range b0 { + d += Uint32(x, b1[i]) + } + return d +} + +// Uint64s hamming distance of two uint64 buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Uint64s(b0, b1 []uint64) int { + d := 0 + for i, x := range b0 { + d += Uint64(x, b1[i]) + } + return d +} + +// Uints hamming distance of two uint buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Uints(b0, b1 []uint) int { + d := 0 + for i, x := range b0 { + d += Uint(x, b1[i]) + } + return d +} + +// Bytes hamming distance of two byte buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Bytes(b0, b1 []byte) int { + d := 0 + for i, x := range b0 { + d += Byte(x, b1[i]) + } + return d +} + +// Runes hamming distance of two rune buffers, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Runes(b0, b1 []rune) int { + d := 0 + for i, x := range b0 { + d += Rune(x, b1[i]) + } + return d +} + +// Strings hamming distance of two strings, of which the size of b0 +// is used for both (panics if b1 < b0, does not compare b1 beyond length of b0) +func Strings(b0, b1 string) int { + return Runes(runes(b0), runes(b1)) +} + +// runize string +func runes(s string) (r []rune) { + for _, ch := range s { + r = append(r, ch) + } + return +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go b/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go new file mode 100644 index 00000000..c36ad323 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go @@ -0,0 +1,704 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Package cache provides interface and implementation of a cache algorithms. +package cache + +import ( + "sync" + "sync/atomic" + "unsafe" + + "github.com/syndtr/goleveldb/leveldb/util" +) + +// Cacher provides interface to implements a caching functionality. +// An implementation must be safe for concurrent use. +type Cacher interface { + // Capacity returns cache capacity. + Capacity() int + + // SetCapacity sets cache capacity. + SetCapacity(capacity int) + + // Promote promotes the 'cache node'. + Promote(n *Node) + + // Ban evicts the 'cache node' and prevent subsequent 'promote'. + Ban(n *Node) + + // Evict evicts the 'cache node'. + Evict(n *Node) + + // EvictNS evicts 'cache node' with the given namespace. + EvictNS(ns uint64) + + // EvictAll evicts all 'cache node'. + EvictAll() + + // Close closes the 'cache tree' + Close() error +} + +// Value is a 'cacheable object'. It may implements util.Releaser, if +// so the the Release method will be called once object is released. +type Value interface{} + +// NamespaceGetter provides convenient wrapper for namespace. +type NamespaceGetter struct { + Cache *Cache + NS uint64 +} + +// Get simply calls Cache.Get() method. +func (g *NamespaceGetter) Get(key uint64, setFunc func() (size int, value Value)) *Handle { + return g.Cache.Get(g.NS, key, setFunc) +} + +// The hash tables implementation is based on: +// "Dynamic-Sized Nonblocking Hash Tables", by Yujie Liu, +// Kunlong Zhang, and Michael Spear. +// ACM Symposium on Principles of Distributed Computing, Jul 2014. + +const ( + mInitialSize = 1 << 4 + mOverflowThreshold = 1 << 5 + mOverflowGrowThreshold = 1 << 7 +) + +type mBucket struct { + mu sync.Mutex + node []*Node + frozen bool +} + +func (b *mBucket) freeze() []*Node { + b.mu.Lock() + defer b.mu.Unlock() + if !b.frozen { + b.frozen = true + } + return b.node +} + +func (b *mBucket) get(r *Cache, h *mNode, hash uint32, ns, key uint64, noset bool) (done, added bool, n *Node) { + b.mu.Lock() + + if b.frozen { + b.mu.Unlock() + return + } + + // Scan the node. + for _, n := range b.node { + if n.hash == hash && n.ns == ns && n.key == key { + atomic.AddInt32(&n.ref, 1) + b.mu.Unlock() + return true, false, n + } + } + + // Get only. + if noset { + b.mu.Unlock() + return true, false, nil + } + + // Create node. + n = &Node{ + r: r, + hash: hash, + ns: ns, + key: key, + ref: 1, + } + // Add node to bucket. + b.node = append(b.node, n) + bLen := len(b.node) + b.mu.Unlock() + + // Update counter. + grow := atomic.AddInt32(&r.nodes, 1) >= h.growThreshold + if bLen > mOverflowThreshold { + grow = grow || atomic.AddInt32(&h.overflow, 1) >= mOverflowGrowThreshold + } + + // Grow. + if grow && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) { + nhLen := len(h.buckets) << 1 + nh := &mNode{ + buckets: make([]unsafe.Pointer, nhLen), + mask: uint32(nhLen) - 1, + pred: unsafe.Pointer(h), + growThreshold: int32(nhLen * mOverflowThreshold), + shrinkThreshold: int32(nhLen >> 1), + } + ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh)) + if !ok { + panic("BUG: failed swapping head") + } + go nh.initBuckets() + } + + return true, true, n +} + +func (b *mBucket) delete(r *Cache, h *mNode, hash uint32, ns, key uint64) (done, deleted bool) { + b.mu.Lock() + + if b.frozen { + b.mu.Unlock() + return + } + + // Scan the node. + var ( + n *Node + bLen int + ) + for i := range b.node { + n = b.node[i] + if n.ns == ns && n.key == key { + if atomic.LoadInt32(&n.ref) == 0 { + deleted = true + + // Call releaser. + if n.value != nil { + if r, ok := n.value.(util.Releaser); ok { + r.Release() + } + n.value = nil + } + + // Remove node from bucket. + b.node = append(b.node[:i], b.node[i+1:]...) + bLen = len(b.node) + } + break + } + } + b.mu.Unlock() + + if deleted { + // Call OnDel. + for _, f := range n.onDel { + f() + } + + // Update counter. + atomic.AddInt32(&r.size, int32(n.size)*-1) + shrink := atomic.AddInt32(&r.nodes, -1) < h.shrinkThreshold + if bLen >= mOverflowThreshold { + atomic.AddInt32(&h.overflow, -1) + } + + // Shrink. + if shrink && len(h.buckets) > mInitialSize && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) { + nhLen := len(h.buckets) >> 1 + nh := &mNode{ + buckets: make([]unsafe.Pointer, nhLen), + mask: uint32(nhLen) - 1, + pred: unsafe.Pointer(h), + growThreshold: int32(nhLen * mOverflowThreshold), + shrinkThreshold: int32(nhLen >> 1), + } + ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh)) + if !ok { + panic("BUG: failed swapping head") + } + go nh.initBuckets() + } + } + + return true, deleted +} + +type mNode struct { + buckets []unsafe.Pointer // []*mBucket + mask uint32 + pred unsafe.Pointer // *mNode + resizeInProgess int32 + + overflow int32 + growThreshold int32 + shrinkThreshold int32 +} + +func (n *mNode) initBucket(i uint32) *mBucket { + if b := (*mBucket)(atomic.LoadPointer(&n.buckets[i])); b != nil { + return b + } + + p := (*mNode)(atomic.LoadPointer(&n.pred)) + if p != nil { + var node []*Node + if n.mask > p.mask { + // Grow. + pb := (*mBucket)(atomic.LoadPointer(&p.buckets[i&p.mask])) + if pb == nil { + pb = p.initBucket(i & p.mask) + } + m := pb.freeze() + // Split nodes. + for _, x := range m { + if x.hash&n.mask == i { + node = append(node, x) + } + } + } else { + // Shrink. + pb0 := (*mBucket)(atomic.LoadPointer(&p.buckets[i])) + if pb0 == nil { + pb0 = p.initBucket(i) + } + pb1 := (*mBucket)(atomic.LoadPointer(&p.buckets[i+uint32(len(n.buckets))])) + if pb1 == nil { + pb1 = p.initBucket(i + uint32(len(n.buckets))) + } + m0 := pb0.freeze() + m1 := pb1.freeze() + // Merge nodes. + node = make([]*Node, 0, len(m0)+len(m1)) + node = append(node, m0...) + node = append(node, m1...) + } + b := &mBucket{node: node} + if atomic.CompareAndSwapPointer(&n.buckets[i], nil, unsafe.Pointer(b)) { + if len(node) > mOverflowThreshold { + atomic.AddInt32(&n.overflow, int32(len(node)-mOverflowThreshold)) + } + return b + } + } + + return (*mBucket)(atomic.LoadPointer(&n.buckets[i])) +} + +func (n *mNode) initBuckets() { + for i := range n.buckets { + n.initBucket(uint32(i)) + } + atomic.StorePointer(&n.pred, nil) +} + +// Cache is a 'cache map'. +type Cache struct { + mu sync.RWMutex + mHead unsafe.Pointer // *mNode + nodes int32 + size int32 + cacher Cacher + closed bool +} + +// NewCache creates a new 'cache map'. The cacher is optional and +// may be nil. +func NewCache(cacher Cacher) *Cache { + h := &mNode{ + buckets: make([]unsafe.Pointer, mInitialSize), + mask: mInitialSize - 1, + growThreshold: int32(mInitialSize * mOverflowThreshold), + shrinkThreshold: 0, + } + for i := range h.buckets { + h.buckets[i] = unsafe.Pointer(&mBucket{}) + } + r := &Cache{ + mHead: unsafe.Pointer(h), + cacher: cacher, + } + return r +} + +func (r *Cache) getBucket(hash uint32) (*mNode, *mBucket) { + h := (*mNode)(atomic.LoadPointer(&r.mHead)) + i := hash & h.mask + b := (*mBucket)(atomic.LoadPointer(&h.buckets[i])) + if b == nil { + b = h.initBucket(i) + } + return h, b +} + +func (r *Cache) delete(n *Node) bool { + for { + h, b := r.getBucket(n.hash) + done, deleted := b.delete(r, h, n.hash, n.ns, n.key) + if done { + return deleted + } + } +} + +// Nodes returns number of 'cache node' in the map. +func (r *Cache) Nodes() int { + return int(atomic.LoadInt32(&r.nodes)) +} + +// Size returns sums of 'cache node' size in the map. +func (r *Cache) Size() int { + return int(atomic.LoadInt32(&r.size)) +} + +// Capacity returns cache capacity. +func (r *Cache) Capacity() int { + if r.cacher == nil { + return 0 + } + return r.cacher.Capacity() +} + +// SetCapacity sets cache capacity. +func (r *Cache) SetCapacity(capacity int) { + if r.cacher != nil { + r.cacher.SetCapacity(capacity) + } +} + +// Get gets 'cache node' with the given namespace and key. +// If cache node is not found and setFunc is not nil, Get will atomically creates +// the 'cache node' by calling setFunc. Otherwise Get will returns nil. +// +// The returned 'cache handle' should be released after use by calling Release +// method. +func (r *Cache) Get(ns, key uint64, setFunc func() (size int, value Value)) *Handle { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return nil + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, setFunc == nil) + if done { + if n != nil { + n.mu.Lock() + if n.value == nil { + if setFunc == nil { + n.mu.Unlock() + n.unref() + return nil + } + + n.size, n.value = setFunc() + if n.value == nil { + n.size = 0 + n.mu.Unlock() + n.unref() + return nil + } + atomic.AddInt32(&r.size, int32(n.size)) + } + n.mu.Unlock() + if r.cacher != nil { + r.cacher.Promote(n) + } + return &Handle{unsafe.Pointer(n)} + } + + break + } + } + return nil +} + +// Delete removes and ban 'cache node' with the given namespace and key. +// A banned 'cache node' will never inserted into the 'cache tree'. Ban +// only attributed to the particular 'cache node', so when a 'cache node' +// is recreated it will not be banned. +// +// If onDel is not nil, then it will be executed if such 'cache node' +// doesn't exist or once the 'cache node' is released. +// +// Delete return true is such 'cache node' exist. +func (r *Cache) Delete(ns, key uint64, onDel func()) bool { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return false + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, true) + if done { + if n != nil { + if onDel != nil { + n.mu.Lock() + n.onDel = append(n.onDel, onDel) + n.mu.Unlock() + } + if r.cacher != nil { + r.cacher.Ban(n) + } + n.unref() + return true + } + + break + } + } + + if onDel != nil { + onDel() + } + + return false +} + +// Evict evicts 'cache node' with the given namespace and key. This will +// simply call Cacher.Evict. +// +// Evict return true is such 'cache node' exist. +func (r *Cache) Evict(ns, key uint64) bool { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return false + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, true) + if done { + if n != nil { + if r.cacher != nil { + r.cacher.Evict(n) + } + n.unref() + return true + } + + break + } + } + + return false +} + +// EvictNS evicts 'cache node' with the given namespace. This will +// simply call Cacher.EvictNS. +func (r *Cache) EvictNS(ns uint64) { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return + } + + if r.cacher != nil { + r.cacher.EvictNS(ns) + } +} + +// EvictAll evicts all 'cache node'. This will simply call Cacher.EvictAll. +func (r *Cache) EvictAll() { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return + } + + if r.cacher != nil { + r.cacher.EvictAll() + } +} + +// Close closes the 'cache map' and forcefully releases all 'cache node'. +func (r *Cache) Close() error { + r.mu.Lock() + if !r.closed { + r.closed = true + + h := (*mNode)(r.mHead) + h.initBuckets() + + for i := range h.buckets { + b := (*mBucket)(h.buckets[i]) + for _, n := range b.node { + // Call releaser. + if n.value != nil { + if r, ok := n.value.(util.Releaser); ok { + r.Release() + } + n.value = nil + } + + // Call OnDel. + for _, f := range n.onDel { + f() + } + n.onDel = nil + } + } + } + r.mu.Unlock() + + // Avoid deadlock. + if r.cacher != nil { + if err := r.cacher.Close(); err != nil { + return err + } + } + return nil +} + +// CloseWeak closes the 'cache map' and evict all 'cache node' from cacher, but +// unlike Close it doesn't forcefully releases 'cache node'. +func (r *Cache) CloseWeak() error { + r.mu.Lock() + if !r.closed { + r.closed = true + } + r.mu.Unlock() + + // Avoid deadlock. + if r.cacher != nil { + r.cacher.EvictAll() + if err := r.cacher.Close(); err != nil { + return err + } + } + return nil +} + +// Node is a 'cache node'. +type Node struct { + r *Cache + + hash uint32 + ns, key uint64 + + mu sync.Mutex + size int + value Value + + ref int32 + onDel []func() + + CacheData unsafe.Pointer +} + +// NS returns this 'cache node' namespace. +func (n *Node) NS() uint64 { + return n.ns +} + +// Key returns this 'cache node' key. +func (n *Node) Key() uint64 { + return n.key +} + +// Size returns this 'cache node' size. +func (n *Node) Size() int { + return n.size +} + +// Value returns this 'cache node' value. +func (n *Node) Value() Value { + return n.value +} + +// Ref returns this 'cache node' ref counter. +func (n *Node) Ref() int32 { + return atomic.LoadInt32(&n.ref) +} + +// GetHandle returns an handle for this 'cache node'. +func (n *Node) GetHandle() *Handle { + if atomic.AddInt32(&n.ref, 1) <= 1 { + panic("BUG: Node.GetHandle on zero ref") + } + return &Handle{unsafe.Pointer(n)} +} + +func (n *Node) unref() { + if atomic.AddInt32(&n.ref, -1) == 0 { + n.r.delete(n) + } +} + +func (n *Node) unrefLocked() { + if atomic.AddInt32(&n.ref, -1) == 0 { + n.r.mu.RLock() + if !n.r.closed { + n.r.delete(n) + } + n.r.mu.RUnlock() + } +} + +// Handle is a 'cache handle' of a 'cache node'. +type Handle struct { + n unsafe.Pointer // *Node +} + +// Value returns the value of the 'cache node'. +func (h *Handle) Value() Value { + n := (*Node)(atomic.LoadPointer(&h.n)) + if n != nil { + return n.value + } + return nil +} + +// Release releases this 'cache handle'. +// It is safe to call release multiple times. +func (h *Handle) Release() { + nPtr := atomic.LoadPointer(&h.n) + if nPtr != nil && atomic.CompareAndSwapPointer(&h.n, nPtr, nil) { + n := (*Node)(nPtr) + n.unrefLocked() + } +} + +func murmur32(ns, key uint64, seed uint32) uint32 { + const ( + m = uint32(0x5bd1e995) + r = 24 + ) + + k1 := uint32(ns >> 32) + k2 := uint32(ns) + k3 := uint32(key >> 32) + k4 := uint32(key) + + k1 *= m + k1 ^= k1 >> r + k1 *= m + + k2 *= m + k2 ^= k2 >> r + k2 *= m + + k3 *= m + k3 ^= k3 >> r + k3 *= m + + k4 *= m + k4 ^= k4 >> r + k4 *= m + + h := seed + + h *= m + h ^= k1 + h *= m + h ^= k2 + h *= m + h ^= k3 + h *= m + h ^= k4 + + h ^= h >> 13 + h *= m + h ^= h >> 15 + + return h +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/comparer/bytes_comparer.go b/vendor/github.com/syndtr/goleveldb/leveldb/comparer/bytes_comparer.go new file mode 100644 index 00000000..abf9fb65 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/comparer/bytes_comparer.go @@ -0,0 +1,51 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package comparer + +import "bytes" + +type bytesComparer struct{} + +func (bytesComparer) Compare(a, b []byte) int { + return bytes.Compare(a, b) +} + +func (bytesComparer) Name() string { + return "leveldb.BytewiseComparator" +} + +func (bytesComparer) Separator(dst, a, b []byte) []byte { + i, n := 0, len(a) + if n > len(b) { + n = len(b) + } + for ; i < n && a[i] == b[i]; i++ { + } + if i >= n { + // Do not shorten if one string is a prefix of the other + } else if c := a[i]; c < 0xff && c+1 < b[i] { + dst = append(dst, a[:i+1]...) + dst[len(dst)-1]++ + return dst + } + return nil +} + +func (bytesComparer) Successor(dst, b []byte) []byte { + for i, c := range b { + if c != 0xff { + dst = append(dst, b[:i+1]...) + dst[len(dst)-1]++ + return dst + } + } + return nil +} + +// DefaultComparer are default implementation of the Comparer interface. +// It uses the natural ordering, consistent with bytes.Compare. +var DefaultComparer = bytesComparer{} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/comparer/comparer.go b/vendor/github.com/syndtr/goleveldb/leveldb/comparer/comparer.go new file mode 100644 index 00000000..2c522db2 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/comparer/comparer.go @@ -0,0 +1,57 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Package comparer provides interface and implementation for ordering +// sets of data. +package comparer + +// BasicComparer is the interface that wraps the basic Compare method. +type BasicComparer interface { + // Compare returns -1, 0, or +1 depending on whether a is 'less than', + // 'equal to' or 'greater than' b. The two arguments can only be 'equal' + // if their contents are exactly equal. Furthermore, the empty slice + // must be 'less than' any non-empty slice. + Compare(a, b []byte) int +} + +// Comparer defines a total ordering over the space of []byte keys: a 'less +// than' relationship. +type Comparer interface { + BasicComparer + + // Name returns name of the comparer. + // + // The Level-DB on-disk format stores the comparer name, and opening a + // database with a different comparer from the one it was created with + // will result in an error. + // + // An implementation to a new name whenever the comparer implementation + // changes in a way that will cause the relative ordering of any two keys + // to change. + // + // Names starting with "leveldb." are reserved and should not be used + // by any users of this package. + Name() string + + // Bellow are advanced functions used to reduce the space requirements + // for internal data structures such as index blocks. + + // Separator appends a sequence of bytes x to dst such that a <= x && x < b, + // where 'less than' is consistent with Compare. An implementation should + // return nil if x equal to a. + // + // Either contents of a or b should not by any means modified. Doing so + // may cause corruption on the internal state. + Separator(dst, a, b []byte) []byte + + // Successor appends a sequence of bytes x to dst such that x >= b, where + // 'less than' is consistent with Compare. An implementation should return + // nil if x equal to b. + // + // Contents of b should not by any means modified. Doing so may cause + // corruption on the internal state. + Successor(dst, b []byte) []byte +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db.go b/vendor/github.com/syndtr/goleveldb/leveldb/db.go new file mode 100644 index 00000000..90fedf7b --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db.go @@ -0,0 +1,1179 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "container/list" + "fmt" + "io" + "os" + "runtime" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/journal" + "github.com/syndtr/goleveldb/leveldb/memdb" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/table" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// DB is a LevelDB database. +type DB struct { + // Need 64-bit alignment. + seq uint64 + + // Stats. Need 64-bit alignment. + cWriteDelay int64 // The cumulative duration of write delays + cWriteDelayN int32 // The cumulative number of write delays + inWritePaused int32 // The indicator whether write operation is paused by compaction + aliveSnaps, aliveIters int32 + + // Session. + s *session + + // MemDB. + memMu sync.RWMutex + memPool chan *memdb.DB + mem, frozenMem *memDB + journal *journal.Writer + journalWriter storage.Writer + journalFd storage.FileDesc + frozenJournalFd storage.FileDesc + frozenSeq uint64 + + // Snapshot. + snapsMu sync.Mutex + snapsList *list.List + + // Write. + batchPool sync.Pool + writeMergeC chan writeMerge + writeMergedC chan bool + writeLockC chan struct{} + writeAckC chan error + writeDelay time.Duration + writeDelayN int + tr *Transaction + + // Compaction. + compCommitLk sync.Mutex + tcompCmdC chan cCmd + tcompPauseC chan chan<- struct{} + mcompCmdC chan cCmd + compErrC chan error + compPerErrC chan error + compErrSetC chan error + compWriteLocking bool + compStats cStats + memdbMaxLevel int // For testing. + + // Close. + closeW sync.WaitGroup + closeC chan struct{} + closed uint32 + closer io.Closer +} + +func openDB(s *session) (*DB, error) { + s.log("db@open opening") + start := time.Now() + db := &DB{ + s: s, + // Initial sequence + seq: s.stSeqNum, + // MemDB + memPool: make(chan *memdb.DB, 1), + // Snapshot + snapsList: list.New(), + // Write + batchPool: sync.Pool{New: newBatch}, + writeMergeC: make(chan writeMerge), + writeMergedC: make(chan bool), + writeLockC: make(chan struct{}, 1), + writeAckC: make(chan error), + // Compaction + tcompCmdC: make(chan cCmd), + tcompPauseC: make(chan chan<- struct{}), + mcompCmdC: make(chan cCmd), + compErrC: make(chan error), + compPerErrC: make(chan error), + compErrSetC: make(chan error), + // Close + closeC: make(chan struct{}), + } + + // Read-only mode. + readOnly := s.o.GetReadOnly() + + if readOnly { + // Recover journals (read-only mode). + if err := db.recoverJournalRO(); err != nil { + return nil, err + } + } else { + // Recover journals. + if err := db.recoverJournal(); err != nil { + return nil, err + } + + // Remove any obsolete files. + if err := db.checkAndCleanFiles(); err != nil { + // Close journal. + if db.journal != nil { + db.journal.Close() + db.journalWriter.Close() + } + return nil, err + } + + } + + // Doesn't need to be included in the wait group. + go db.compactionError() + go db.mpoolDrain() + + if readOnly { + db.SetReadOnly() + } else { + db.closeW.Add(2) + go db.tCompaction() + go db.mCompaction() + // go db.jWriter() + } + + s.logf("db@open done T·%v", time.Since(start)) + + runtime.SetFinalizer(db, (*DB).Close) + return db, nil +} + +// Open opens or creates a DB for the given storage. +// The DB will be created if not exist, unless ErrorIfMissing is true. +// Also, if ErrorIfExist is true and the DB exist Open will returns +// os.ErrExist error. +// +// Open will return an error with type of ErrCorrupted if corruption +// detected in the DB. Use errors.IsCorrupted to test whether an error is +// due to corruption. Corrupted DB can be recovered with Recover function. +// +// The returned DB instance is safe for concurrent use. +// The DB must be closed after use, by calling Close method. +func Open(stor storage.Storage, o *opt.Options) (db *DB, err error) { + s, err := newSession(stor, o) + if err != nil { + return + } + defer func() { + if err != nil { + s.close() + s.release() + } + }() + + err = s.recover() + if err != nil { + if !os.IsNotExist(err) || s.o.GetErrorIfMissing() || s.o.GetReadOnly() { + return + } + err = s.create() + if err != nil { + return + } + } else if s.o.GetErrorIfExist() { + err = os.ErrExist + return + } + + return openDB(s) +} + +// OpenFile opens or creates a DB for the given path. +// The DB will be created if not exist, unless ErrorIfMissing is true. +// Also, if ErrorIfExist is true and the DB exist OpenFile will returns +// os.ErrExist error. +// +// OpenFile uses standard file-system backed storage implementation as +// described in the leveldb/storage package. +// +// OpenFile will return an error with type of ErrCorrupted if corruption +// detected in the DB. Use errors.IsCorrupted to test whether an error is +// due to corruption. Corrupted DB can be recovered with Recover function. +// +// The returned DB instance is safe for concurrent use. +// The DB must be closed after use, by calling Close method. +func OpenFile(path string, o *opt.Options) (db *DB, err error) { + stor, err := storage.OpenFile(path, o.GetReadOnly()) + if err != nil { + return + } + db, err = Open(stor, o) + if err != nil { + stor.Close() + } else { + db.closer = stor + } + return +} + +// Recover recovers and opens a DB with missing or corrupted manifest files +// for the given storage. It will ignore any manifest files, valid or not. +// The DB must already exist or it will returns an error. +// Also, Recover will ignore ErrorIfMissing and ErrorIfExist options. +// +// The returned DB instance is safe for concurrent use. +// The DB must be closed after use, by calling Close method. +func Recover(stor storage.Storage, o *opt.Options) (db *DB, err error) { + s, err := newSession(stor, o) + if err != nil { + return + } + defer func() { + if err != nil { + s.close() + s.release() + } + }() + + err = recoverTable(s, o) + if err != nil { + return + } + return openDB(s) +} + +// RecoverFile recovers and opens a DB with missing or corrupted manifest files +// for the given path. It will ignore any manifest files, valid or not. +// The DB must already exist or it will returns an error. +// Also, Recover will ignore ErrorIfMissing and ErrorIfExist options. +// +// RecoverFile uses standard file-system backed storage implementation as described +// in the leveldb/storage package. +// +// The returned DB instance is safe for concurrent use. +// The DB must be closed after use, by calling Close method. +func RecoverFile(path string, o *opt.Options) (db *DB, err error) { + stor, err := storage.OpenFile(path, false) + if err != nil { + return + } + db, err = Recover(stor, o) + if err != nil { + stor.Close() + } else { + db.closer = stor + } + return +} + +func recoverTable(s *session, o *opt.Options) error { + o = dupOptions(o) + // Mask StrictReader, lets StrictRecovery doing its job. + o.Strict &= ^opt.StrictReader + + // Get all tables and sort it by file number. + fds, err := s.stor.List(storage.TypeTable) + if err != nil { + return err + } + sortFds(fds) + + var ( + maxSeq uint64 + recoveredKey, goodKey, corruptedKey, corruptedBlock, droppedTable int + + // We will drop corrupted table. + strict = o.GetStrict(opt.StrictRecovery) + noSync = o.GetNoSync() + + rec = &sessionRecord{} + bpool = util.NewBufferPool(o.GetBlockSize() + 5) + ) + buildTable := func(iter iterator.Iterator) (tmpFd storage.FileDesc, size int64, err error) { + tmpFd = s.newTemp() + writer, err := s.stor.Create(tmpFd) + if err != nil { + return + } + defer func() { + writer.Close() + if err != nil { + s.stor.Remove(tmpFd) + tmpFd = storage.FileDesc{} + } + }() + + // Copy entries. + tw := table.NewWriter(writer, o) + for iter.Next() { + key := iter.Key() + if validInternalKey(key) { + err = tw.Append(key, iter.Value()) + if err != nil { + return + } + } + } + err = iter.Error() + if err != nil && !errors.IsCorrupted(err) { + return + } + err = tw.Close() + if err != nil { + return + } + if !noSync { + err = writer.Sync() + if err != nil { + return + } + } + size = int64(tw.BytesLen()) + return + } + recoverTable := func(fd storage.FileDesc) error { + s.logf("table@recovery recovering @%d", fd.Num) + reader, err := s.stor.Open(fd) + if err != nil { + return err + } + var closed bool + defer func() { + if !closed { + reader.Close() + } + }() + + // Get file size. + size, err := reader.Seek(0, 2) + if err != nil { + return err + } + + var ( + tSeq uint64 + tgoodKey, tcorruptedKey, tcorruptedBlock int + imin, imax []byte + ) + tr, err := table.NewReader(reader, size, fd, nil, bpool, o) + if err != nil { + return err + } + iter := tr.NewIterator(nil, nil) + if itererr, ok := iter.(iterator.ErrorCallbackSetter); ok { + itererr.SetErrorCallback(func(err error) { + if errors.IsCorrupted(err) { + s.logf("table@recovery block corruption @%d %q", fd.Num, err) + tcorruptedBlock++ + } + }) + } + + // Scan the table. + for iter.Next() { + key := iter.Key() + _, seq, _, kerr := parseInternalKey(key) + if kerr != nil { + tcorruptedKey++ + continue + } + tgoodKey++ + if seq > tSeq { + tSeq = seq + } + if imin == nil { + imin = append([]byte{}, key...) + } + imax = append(imax[:0], key...) + } + if err := iter.Error(); err != nil && !errors.IsCorrupted(err) { + iter.Release() + return err + } + iter.Release() + + goodKey += tgoodKey + corruptedKey += tcorruptedKey + corruptedBlock += tcorruptedBlock + + if strict && (tcorruptedKey > 0 || tcorruptedBlock > 0) { + droppedTable++ + s.logf("table@recovery dropped @%d Gk·%d Ck·%d Cb·%d S·%d Q·%d", fd.Num, tgoodKey, tcorruptedKey, tcorruptedBlock, size, tSeq) + return nil + } + + if tgoodKey > 0 { + if tcorruptedKey > 0 || tcorruptedBlock > 0 { + // Rebuild the table. + s.logf("table@recovery rebuilding @%d", fd.Num) + iter := tr.NewIterator(nil, nil) + tmpFd, newSize, err := buildTable(iter) + iter.Release() + if err != nil { + return err + } + closed = true + reader.Close() + if err := s.stor.Rename(tmpFd, fd); err != nil { + return err + } + size = newSize + } + if tSeq > maxSeq { + maxSeq = tSeq + } + recoveredKey += tgoodKey + // Add table to level 0. + rec.addTable(0, fd.Num, size, imin, imax) + s.logf("table@recovery recovered @%d Gk·%d Ck·%d Cb·%d S·%d Q·%d", fd.Num, tgoodKey, tcorruptedKey, tcorruptedBlock, size, tSeq) + } else { + droppedTable++ + s.logf("table@recovery unrecoverable @%d Ck·%d Cb·%d S·%d", fd.Num, tcorruptedKey, tcorruptedBlock, size) + } + + return nil + } + + // Recover all tables. + if len(fds) > 0 { + s.logf("table@recovery F·%d", len(fds)) + + // Mark file number as used. + s.markFileNum(fds[len(fds)-1].Num) + + for _, fd := range fds { + if err := recoverTable(fd); err != nil { + return err + } + } + + s.logf("table@recovery recovered F·%d N·%d Gk·%d Ck·%d Q·%d", len(fds), recoveredKey, goodKey, corruptedKey, maxSeq) + } + + // Set sequence number. + rec.setSeqNum(maxSeq) + + // Create new manifest. + if err := s.create(); err != nil { + return err + } + + // Commit. + return s.commit(rec) +} + +func (db *DB) recoverJournal() error { + // Get all journals and sort it by file number. + rawFds, err := db.s.stor.List(storage.TypeJournal) + if err != nil { + return err + } + sortFds(rawFds) + + // Journals that will be recovered. + var fds []storage.FileDesc + for _, fd := range rawFds { + if fd.Num >= db.s.stJournalNum || fd.Num == db.s.stPrevJournalNum { + fds = append(fds, fd) + } + } + + var ( + ofd storage.FileDesc // Obsolete file. + rec = &sessionRecord{} + ) + + // Recover journals. + if len(fds) > 0 { + db.logf("journal@recovery F·%d", len(fds)) + + // Mark file number as used. + db.s.markFileNum(fds[len(fds)-1].Num) + + var ( + // Options. + strict = db.s.o.GetStrict(opt.StrictJournal) + checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) + writeBuffer = db.s.o.GetWriteBuffer() + + jr *journal.Reader + mdb = memdb.New(db.s.icmp, writeBuffer) + buf = &util.Buffer{} + batchSeq uint64 + batchLen int + ) + + for _, fd := range fds { + db.logf("journal@recovery recovering @%d", fd.Num) + + fr, err := db.s.stor.Open(fd) + if err != nil { + return err + } + + // Create or reset journal reader instance. + if jr == nil { + jr = journal.NewReader(fr, dropper{db.s, fd}, strict, checksum) + } else { + jr.Reset(fr, dropper{db.s, fd}, strict, checksum) + } + + // Flush memdb and remove obsolete journal file. + if !ofd.Zero() { + if mdb.Len() > 0 { + if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { + fr.Close() + return err + } + } + + rec.setJournalNum(fd.Num) + rec.setSeqNum(db.seq) + if err := db.s.commit(rec); err != nil { + fr.Close() + return err + } + rec.resetAddedTables() + + db.s.stor.Remove(ofd) + ofd = storage.FileDesc{} + } + + // Replay journal to memdb. + mdb.Reset() + for { + r, err := jr.Next() + if err != nil { + if err == io.EOF { + break + } + + fr.Close() + return errors.SetFd(err, fd) + } + + buf.Reset() + if _, err := buf.ReadFrom(r); err != nil { + if err == io.ErrUnexpectedEOF { + // This is error returned due to corruption, with strict == false. + continue + } + + fr.Close() + return errors.SetFd(err, fd) + } + batchSeq, batchLen, err = decodeBatchToMem(buf.Bytes(), db.seq, mdb) + if err != nil { + if !strict && errors.IsCorrupted(err) { + db.s.logf("journal error: %v (skipped)", err) + // We won't apply sequence number as it might be corrupted. + continue + } + + fr.Close() + return errors.SetFd(err, fd) + } + + // Save sequence number. + db.seq = batchSeq + uint64(batchLen) + + // Flush it if large enough. + if mdb.Size() >= writeBuffer { + if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { + fr.Close() + return err + } + + mdb.Reset() + } + } + + fr.Close() + ofd = fd + } + + // Flush the last memdb. + if mdb.Len() > 0 { + if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { + return err + } + } + } + + // Create a new journal. + if _, err := db.newMem(0); err != nil { + return err + } + + // Commit. + rec.setJournalNum(db.journalFd.Num) + rec.setSeqNum(db.seq) + if err := db.s.commit(rec); err != nil { + // Close journal on error. + if db.journal != nil { + db.journal.Close() + db.journalWriter.Close() + } + return err + } + + // Remove the last obsolete journal file. + if !ofd.Zero() { + db.s.stor.Remove(ofd) + } + + return nil +} + +func (db *DB) recoverJournalRO() error { + // Get all journals and sort it by file number. + rawFds, err := db.s.stor.List(storage.TypeJournal) + if err != nil { + return err + } + sortFds(rawFds) + + // Journals that will be recovered. + var fds []storage.FileDesc + for _, fd := range rawFds { + if fd.Num >= db.s.stJournalNum || fd.Num == db.s.stPrevJournalNum { + fds = append(fds, fd) + } + } + + var ( + // Options. + strict = db.s.o.GetStrict(opt.StrictJournal) + checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) + writeBuffer = db.s.o.GetWriteBuffer() + + mdb = memdb.New(db.s.icmp, writeBuffer) + ) + + // Recover journals. + if len(fds) > 0 { + db.logf("journal@recovery RO·Mode F·%d", len(fds)) + + var ( + jr *journal.Reader + buf = &util.Buffer{} + batchSeq uint64 + batchLen int + ) + + for _, fd := range fds { + db.logf("journal@recovery recovering @%d", fd.Num) + + fr, err := db.s.stor.Open(fd) + if err != nil { + return err + } + + // Create or reset journal reader instance. + if jr == nil { + jr = journal.NewReader(fr, dropper{db.s, fd}, strict, checksum) + } else { + jr.Reset(fr, dropper{db.s, fd}, strict, checksum) + } + + // Replay journal to memdb. + for { + r, err := jr.Next() + if err != nil { + if err == io.EOF { + break + } + + fr.Close() + return errors.SetFd(err, fd) + } + + buf.Reset() + if _, err := buf.ReadFrom(r); err != nil { + if err == io.ErrUnexpectedEOF { + // This is error returned due to corruption, with strict == false. + continue + } + + fr.Close() + return errors.SetFd(err, fd) + } + batchSeq, batchLen, err = decodeBatchToMem(buf.Bytes(), db.seq, mdb) + if err != nil { + if !strict && errors.IsCorrupted(err) { + db.s.logf("journal error: %v (skipped)", err) + // We won't apply sequence number as it might be corrupted. + continue + } + + fr.Close() + return errors.SetFd(err, fd) + } + + // Save sequence number. + db.seq = batchSeq + uint64(batchLen) + } + + fr.Close() + } + } + + // Set memDB. + db.mem = &memDB{db: db, DB: mdb, ref: 1} + + return nil +} + +func memGet(mdb *memdb.DB, ikey internalKey, icmp *iComparer) (ok bool, mv []byte, err error) { + mk, mv, err := mdb.Find(ikey) + if err == nil { + ukey, _, kt, kerr := parseInternalKey(mk) + if kerr != nil { + // Shouldn't have had happen. + panic(kerr) + } + if icmp.uCompare(ukey, ikey.ukey()) == 0 { + if kt == keyTypeDel { + return true, nil, ErrNotFound + } + return true, mv, nil + + } + } else if err != ErrNotFound { + return true, nil, err + } + return +} + +func (db *DB) get(auxm *memdb.DB, auxt tFiles, key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, err error) { + ikey := makeInternalKey(nil, key, seq, keyTypeSeek) + + if auxm != nil { + if ok, mv, me := memGet(auxm, ikey, db.s.icmp); ok { + return append([]byte{}, mv...), me + } + } + + em, fm := db.getMems() + for _, m := range [...]*memDB{em, fm} { + if m == nil { + continue + } + defer m.decref() + + if ok, mv, me := memGet(m.DB, ikey, db.s.icmp); ok { + return append([]byte{}, mv...), me + } + } + + v := db.s.version() + value, cSched, err := v.get(auxt, ikey, ro, false) + v.release() + if cSched { + // Trigger table compaction. + db.compTrigger(db.tcompCmdC) + } + return +} + +func nilIfNotFound(err error) error { + if err == ErrNotFound { + return nil + } + return err +} + +func (db *DB) has(auxm *memdb.DB, auxt tFiles, key []byte, seq uint64, ro *opt.ReadOptions) (ret bool, err error) { + ikey := makeInternalKey(nil, key, seq, keyTypeSeek) + + if auxm != nil { + if ok, _, me := memGet(auxm, ikey, db.s.icmp); ok { + return me == nil, nilIfNotFound(me) + } + } + + em, fm := db.getMems() + for _, m := range [...]*memDB{em, fm} { + if m == nil { + continue + } + defer m.decref() + + if ok, _, me := memGet(m.DB, ikey, db.s.icmp); ok { + return me == nil, nilIfNotFound(me) + } + } + + v := db.s.version() + _, cSched, err := v.get(auxt, ikey, ro, true) + v.release() + if cSched { + // Trigger table compaction. + db.compTrigger(db.tcompCmdC) + } + if err == nil { + ret = true + } else if err == ErrNotFound { + err = nil + } + return +} + +// Get gets the value for the given key. It returns ErrNotFound if the +// DB does not contains the key. +// +// The returned slice is its own copy, it is safe to modify the contents +// of the returned slice. +// It is safe to modify the contents of the argument after Get returns. +func (db *DB) Get(key []byte, ro *opt.ReadOptions) (value []byte, err error) { + err = db.ok() + if err != nil { + return + } + + se := db.acquireSnapshot() + defer db.releaseSnapshot(se) + return db.get(nil, nil, key, se.seq, ro) +} + +// Has returns true if the DB does contains the given key. +// +// It is safe to modify the contents of the argument after Has returns. +func (db *DB) Has(key []byte, ro *opt.ReadOptions) (ret bool, err error) { + err = db.ok() + if err != nil { + return + } + + se := db.acquireSnapshot() + defer db.releaseSnapshot(se) + return db.has(nil, nil, key, se.seq, ro) +} + +// NewIterator returns an iterator for the latest snapshot of the +// underlying DB. +// The returned iterator is not safe for concurrent use, but it is safe to use +// multiple iterators concurrently, with each in a dedicated goroutine. +// It is also safe to use an iterator concurrently with modifying its +// underlying DB. The resultant key/value pairs are guaranteed to be +// consistent. +// +// Slice allows slicing the iterator to only contains keys in the given +// range. A nil Range.Start is treated as a key before all keys in the +// DB. And a nil Range.Limit is treated as a key after all keys in +// the DB. +// +// WARNING: Any slice returned by interator (e.g. slice returned by calling +// Iterator.Key() or Iterator.Key() methods), its content should not be modified +// unless noted otherwise. +// +// The iterator must be released after use, by calling Release method. +// +// Also read Iterator documentation of the leveldb/iterator package. +func (db *DB) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { + if err := db.ok(); err != nil { + return iterator.NewEmptyIterator(err) + } + + se := db.acquireSnapshot() + defer db.releaseSnapshot(se) + // Iterator holds 'version' lock, 'version' is immutable so snapshot + // can be released after iterator created. + return db.newIterator(nil, nil, se.seq, slice, ro) +} + +// GetSnapshot returns a latest snapshot of the underlying DB. A snapshot +// is a frozen snapshot of a DB state at a particular point in time. The +// content of snapshot are guaranteed to be consistent. +// +// The snapshot must be released after use, by calling Release method. +func (db *DB) GetSnapshot() (*Snapshot, error) { + if err := db.ok(); err != nil { + return nil, err + } + + return db.newSnapshot(), nil +} + +// GetProperty returns value of the given property name. +// +// Property names: +// leveldb.num-files-at-level{n} +// Returns the number of files at level 'n'. +// leveldb.stats +// Returns statistics of the underlying DB. +// leveldb.iostats +// Returns statistics of effective disk read and write. +// leveldb.writedelay +// Returns cumulative write delay caused by compaction. +// leveldb.sstables +// Returns sstables list for each level. +// leveldb.blockpool +// Returns block pool stats. +// leveldb.cachedblock +// Returns size of cached block. +// leveldb.openedtables +// Returns number of opened tables. +// leveldb.alivesnaps +// Returns number of alive snapshots. +// leveldb.aliveiters +// Returns number of alive iterators. +func (db *DB) GetProperty(name string) (value string, err error) { + err = db.ok() + if err != nil { + return + } + + const prefix = "leveldb." + if !strings.HasPrefix(name, prefix) { + return "", ErrNotFound + } + p := name[len(prefix):] + + v := db.s.version() + defer v.release() + + numFilesPrefix := "num-files-at-level" + switch { + case strings.HasPrefix(p, numFilesPrefix): + var level uint + var rest string + n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest) + if n != 1 { + err = ErrNotFound + } else { + value = fmt.Sprint(v.tLen(int(level))) + } + case p == "stats": + value = "Compactions\n" + + " Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB)\n" + + "-------+------------+---------------+---------------+---------------+---------------\n" + for level, tables := range v.levels { + duration, read, write := db.compStats.getStat(level) + if len(tables) == 0 && duration == 0 { + continue + } + value += fmt.Sprintf(" %3d | %10d | %13.5f | %13.5f | %13.5f | %13.5f\n", + level, len(tables), float64(tables.size())/1048576.0, duration.Seconds(), + float64(read)/1048576.0, float64(write)/1048576.0) + } + case p == "iostats": + value = fmt.Sprintf("Read(MB):%.5f Write(MB):%.5f", + float64(db.s.stor.reads())/1048576.0, + float64(db.s.stor.writes())/1048576.0) + case p == "writedelay": + writeDelayN, writeDelay := atomic.LoadInt32(&db.cWriteDelayN), time.Duration(atomic.LoadInt64(&db.cWriteDelay)) + paused := atomic.LoadInt32(&db.inWritePaused) == 1 + value = fmt.Sprintf("DelayN:%d Delay:%s Paused:%t", writeDelayN, writeDelay, paused) + case p == "sstables": + for level, tables := range v.levels { + value += fmt.Sprintf("--- level %d ---\n", level) + for _, t := range tables { + value += fmt.Sprintf("%d:%d[%q .. %q]\n", t.fd.Num, t.size, t.imin, t.imax) + } + } + case p == "blockpool": + value = fmt.Sprintf("%v", db.s.tops.bpool) + case p == "cachedblock": + if db.s.tops.bcache != nil { + value = fmt.Sprintf("%d", db.s.tops.bcache.Size()) + } else { + value = "" + } + case p == "openedtables": + value = fmt.Sprintf("%d", db.s.tops.cache.Size()) + case p == "alivesnaps": + value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveSnaps)) + case p == "aliveiters": + value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters)) + default: + err = ErrNotFound + } + + return +} + +// DBStats is database statistics. +type DBStats struct { + WriteDelayCount int32 + WriteDelayDuration time.Duration + WritePaused bool + + AliveSnapshots int32 + AliveIterators int32 + + IOWrite uint64 + IORead uint64 + + BlockCacheSize int + OpenedTablesCount int + + LevelSizes []int64 + LevelTablesCounts []int + LevelRead []int64 + LevelWrite []int64 + LevelDurations []time.Duration +} + +// Stats populates s with database statistics. +func (db *DB) Stats(s *DBStats) error { + err := db.ok() + if err != nil { + return err + } + + s.IORead = db.s.stor.reads() + s.IOWrite = db.s.stor.writes() + s.WriteDelayCount = atomic.LoadInt32(&db.cWriteDelayN) + s.WriteDelayDuration = time.Duration(atomic.LoadInt64(&db.cWriteDelay)) + s.WritePaused = atomic.LoadInt32(&db.inWritePaused) == 1 + + s.OpenedTablesCount = db.s.tops.cache.Size() + if db.s.tops.bcache != nil { + s.BlockCacheSize = db.s.tops.bcache.Size() + } else { + s.BlockCacheSize = 0 + } + + s.AliveIterators = atomic.LoadInt32(&db.aliveIters) + s.AliveSnapshots = atomic.LoadInt32(&db.aliveSnaps) + + s.LevelDurations = s.LevelDurations[:0] + s.LevelRead = s.LevelRead[:0] + s.LevelWrite = s.LevelWrite[:0] + s.LevelSizes = s.LevelSizes[:0] + s.LevelTablesCounts = s.LevelTablesCounts[:0] + + v := db.s.version() + defer v.release() + + for level, tables := range v.levels { + duration, read, write := db.compStats.getStat(level) + if len(tables) == 0 && duration == 0 { + continue + } + s.LevelDurations = append(s.LevelDurations, duration) + s.LevelRead = append(s.LevelRead, read) + s.LevelWrite = append(s.LevelWrite, write) + s.LevelSizes = append(s.LevelSizes, tables.size()) + s.LevelTablesCounts = append(s.LevelTablesCounts, len(tables)) + } + + return nil +} + +// SizeOf calculates approximate sizes of the given key ranges. +// The length of the returned sizes are equal with the length of the given +// ranges. The returned sizes measure storage space usage, so if the user +// data compresses by a factor of ten, the returned sizes will be one-tenth +// the size of the corresponding user data size. +// The results may not include the sizes of recently written data. +func (db *DB) SizeOf(ranges []util.Range) (Sizes, error) { + if err := db.ok(); err != nil { + return nil, err + } + + v := db.s.version() + defer v.release() + + sizes := make(Sizes, 0, len(ranges)) + for _, r := range ranges { + imin := makeInternalKey(nil, r.Start, keyMaxSeq, keyTypeSeek) + imax := makeInternalKey(nil, r.Limit, keyMaxSeq, keyTypeSeek) + start, err := v.offsetOf(imin) + if err != nil { + return nil, err + } + limit, err := v.offsetOf(imax) + if err != nil { + return nil, err + } + var size int64 + if limit >= start { + size = limit - start + } + sizes = append(sizes, size) + } + + return sizes, nil +} + +// Close closes the DB. This will also releases any outstanding snapshot, +// abort any in-flight compaction and discard open transaction. +// +// It is not safe to close a DB until all outstanding iterators are released. +// It is valid to call Close multiple times. Other methods should not be +// called after the DB has been closed. +func (db *DB) Close() error { + if !db.setClosed() { + return ErrClosed + } + + start := time.Now() + db.log("db@close closing") + + // Clear the finalizer. + runtime.SetFinalizer(db, nil) + + // Get compaction error. + var err error + select { + case err = <-db.compErrC: + if err == ErrReadOnly { + err = nil + } + default: + } + + // Signal all goroutines. + close(db.closeC) + + // Discard open transaction. + if db.tr != nil { + db.tr.Discard() + } + + // Acquire writer lock. + db.writeLockC <- struct{}{} + + // Wait for all gorotines to exit. + db.closeW.Wait() + + // Closes journal. + if db.journal != nil { + db.journal.Close() + db.journalWriter.Close() + db.journal = nil + db.journalWriter = nil + } + + if db.writeDelayN > 0 { + db.logf("db@write was delayed N·%d T·%v", db.writeDelayN, db.writeDelay) + } + + // Close session. + db.s.close() + db.logf("db@close done T·%v", time.Since(start)) + db.s.release() + + if db.closer != nil { + if err1 := db.closer.Close(); err == nil { + err = err1 + } + db.closer = nil + } + + // Clear memdbs. + db.clearMems() + + return err +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go new file mode 100644 index 00000000..0c1b9a53 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go @@ -0,0 +1,854 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "sync" + "time" + + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" +) + +var ( + errCompactionTransactExiting = errors.New("leveldb: compaction transact exiting") +) + +type cStat struct { + duration time.Duration + read int64 + write int64 +} + +func (p *cStat) add(n *cStatStaging) { + p.duration += n.duration + p.read += n.read + p.write += n.write +} + +func (p *cStat) get() (duration time.Duration, read, write int64) { + return p.duration, p.read, p.write +} + +type cStatStaging struct { + start time.Time + duration time.Duration + on bool + read int64 + write int64 +} + +func (p *cStatStaging) startTimer() { + if !p.on { + p.start = time.Now() + p.on = true + } +} + +func (p *cStatStaging) stopTimer() { + if p.on { + p.duration += time.Since(p.start) + p.on = false + } +} + +type cStats struct { + lk sync.Mutex + stats []cStat +} + +func (p *cStats) addStat(level int, n *cStatStaging) { + p.lk.Lock() + if level >= len(p.stats) { + newStats := make([]cStat, level+1) + copy(newStats, p.stats) + p.stats = newStats + } + p.stats[level].add(n) + p.lk.Unlock() +} + +func (p *cStats) getStat(level int) (duration time.Duration, read, write int64) { + p.lk.Lock() + defer p.lk.Unlock() + if level < len(p.stats) { + return p.stats[level].get() + } + return +} + +func (db *DB) compactionError() { + var err error +noerr: + // No error. + for { + select { + case err = <-db.compErrSetC: + switch { + case err == nil: + case err == ErrReadOnly, errors.IsCorrupted(err): + goto hasperr + default: + goto haserr + } + case <-db.closeC: + return + } + } +haserr: + // Transient error. + for { + select { + case db.compErrC <- err: + case err = <-db.compErrSetC: + switch { + case err == nil: + goto noerr + case err == ErrReadOnly, errors.IsCorrupted(err): + goto hasperr + default: + } + case <-db.closeC: + return + } + } +hasperr: + // Persistent error. + for { + select { + case db.compErrC <- err: + case db.compPerErrC <- err: + case db.writeLockC <- struct{}{}: + // Hold write lock, so that write won't pass-through. + db.compWriteLocking = true + case <-db.closeC: + if db.compWriteLocking { + // We should release the lock or Close will hang. + <-db.writeLockC + } + return + } + } +} + +type compactionTransactCounter int + +func (cnt *compactionTransactCounter) incr() { + *cnt++ +} + +type compactionTransactInterface interface { + run(cnt *compactionTransactCounter) error + revert() error +} + +func (db *DB) compactionTransact(name string, t compactionTransactInterface) { + defer func() { + if x := recover(); x != nil { + if x == errCompactionTransactExiting { + if err := t.revert(); err != nil { + db.logf("%s revert error %q", name, err) + } + } + panic(x) + } + }() + + const ( + backoffMin = 1 * time.Second + backoffMax = 8 * time.Second + backoffMul = 2 * time.Second + ) + var ( + backoff = backoffMin + backoffT = time.NewTimer(backoff) + lastCnt = compactionTransactCounter(0) + + disableBackoff = db.s.o.GetDisableCompactionBackoff() + ) + for n := 0; ; n++ { + // Check whether the DB is closed. + if db.isClosed() { + db.logf("%s exiting", name) + db.compactionExitTransact() + } else if n > 0 { + db.logf("%s retrying N·%d", name, n) + } + + // Execute. + cnt := compactionTransactCounter(0) + err := t.run(&cnt) + if err != nil { + db.logf("%s error I·%d %q", name, cnt, err) + } + + // Set compaction error status. + select { + case db.compErrSetC <- err: + case perr := <-db.compPerErrC: + if err != nil { + db.logf("%s exiting (persistent error %q)", name, perr) + db.compactionExitTransact() + } + case <-db.closeC: + db.logf("%s exiting", name) + db.compactionExitTransact() + } + if err == nil { + return + } + if errors.IsCorrupted(err) { + db.logf("%s exiting (corruption detected)", name) + db.compactionExitTransact() + } + + if !disableBackoff { + // Reset backoff duration if counter is advancing. + if cnt > lastCnt { + backoff = backoffMin + lastCnt = cnt + } + + // Backoff. + backoffT.Reset(backoff) + if backoff < backoffMax { + backoff *= backoffMul + if backoff > backoffMax { + backoff = backoffMax + } + } + select { + case <-backoffT.C: + case <-db.closeC: + db.logf("%s exiting", name) + db.compactionExitTransact() + } + } + } +} + +type compactionTransactFunc struct { + runFunc func(cnt *compactionTransactCounter) error + revertFunc func() error +} + +func (t *compactionTransactFunc) run(cnt *compactionTransactCounter) error { + return t.runFunc(cnt) +} + +func (t *compactionTransactFunc) revert() error { + if t.revertFunc != nil { + return t.revertFunc() + } + return nil +} + +func (db *DB) compactionTransactFunc(name string, run func(cnt *compactionTransactCounter) error, revert func() error) { + db.compactionTransact(name, &compactionTransactFunc{run, revert}) +} + +func (db *DB) compactionExitTransact() { + panic(errCompactionTransactExiting) +} + +func (db *DB) compactionCommit(name string, rec *sessionRecord) { + db.compCommitLk.Lock() + defer db.compCommitLk.Unlock() // Defer is necessary. + db.compactionTransactFunc(name+"@commit", func(cnt *compactionTransactCounter) error { + return db.s.commit(rec) + }, nil) +} + +func (db *DB) memCompaction() { + mdb := db.getFrozenMem() + if mdb == nil { + return + } + defer mdb.decref() + + db.logf("memdb@flush N·%d S·%s", mdb.Len(), shortenb(mdb.Size())) + + // Don't compact empty memdb. + if mdb.Len() == 0 { + db.logf("memdb@flush skipping") + // drop frozen memdb + db.dropFrozenMem() + return + } + + // Pause table compaction. + resumeC := make(chan struct{}) + select { + case db.tcompPauseC <- (chan<- struct{})(resumeC): + case <-db.compPerErrC: + close(resumeC) + resumeC = nil + case <-db.closeC: + db.compactionExitTransact() + } + + var ( + rec = &sessionRecord{} + stats = &cStatStaging{} + flushLevel int + ) + + // Generate tables. + db.compactionTransactFunc("memdb@flush", func(cnt *compactionTransactCounter) (err error) { + stats.startTimer() + flushLevel, err = db.s.flushMemdb(rec, mdb.DB, db.memdbMaxLevel) + stats.stopTimer() + return + }, func() error { + for _, r := range rec.addedTables { + db.logf("memdb@flush revert @%d", r.num) + if err := db.s.stor.Remove(storage.FileDesc{Type: storage.TypeTable, Num: r.num}); err != nil { + return err + } + } + return nil + }) + + rec.setJournalNum(db.journalFd.Num) + rec.setSeqNum(db.frozenSeq) + + // Commit. + stats.startTimer() + db.compactionCommit("memdb", rec) + stats.stopTimer() + + db.logf("memdb@flush committed F·%d T·%v", len(rec.addedTables), stats.duration) + + for _, r := range rec.addedTables { + stats.write += r.size + } + db.compStats.addStat(flushLevel, stats) + + // Drop frozen memdb. + db.dropFrozenMem() + + // Resume table compaction. + if resumeC != nil { + select { + case <-resumeC: + close(resumeC) + case <-db.closeC: + db.compactionExitTransact() + } + } + + // Trigger table compaction. + db.compTrigger(db.tcompCmdC) +} + +type tableCompactionBuilder struct { + db *DB + s *session + c *compaction + rec *sessionRecord + stat0, stat1 *cStatStaging + + snapHasLastUkey bool + snapLastUkey []byte + snapLastSeq uint64 + snapIter int + snapKerrCnt int + snapDropCnt int + + kerrCnt int + dropCnt int + + minSeq uint64 + strict bool + tableSize int + + tw *tWriter +} + +func (b *tableCompactionBuilder) appendKV(key, value []byte) error { + // Create new table if not already. + if b.tw == nil { + // Check for pause event. + if b.db != nil { + select { + case ch := <-b.db.tcompPauseC: + b.db.pauseCompaction(ch) + case <-b.db.closeC: + b.db.compactionExitTransact() + default: + } + } + + // Create new table. + var err error + b.tw, err = b.s.tops.create() + if err != nil { + return err + } + } + + // Write key/value into table. + return b.tw.append(key, value) +} + +func (b *tableCompactionBuilder) needFlush() bool { + return b.tw.tw.BytesLen() >= b.tableSize +} + +func (b *tableCompactionBuilder) flush() error { + t, err := b.tw.finish() + if err != nil { + return err + } + b.rec.addTableFile(b.c.sourceLevel+1, t) + b.stat1.write += t.size + b.s.logf("table@build created L%d@%d N·%d S·%s %q:%q", b.c.sourceLevel+1, t.fd.Num, b.tw.tw.EntriesLen(), shortenb(int(t.size)), t.imin, t.imax) + b.tw = nil + return nil +} + +func (b *tableCompactionBuilder) cleanup() { + if b.tw != nil { + b.tw.drop() + b.tw = nil + } +} + +func (b *tableCompactionBuilder) run(cnt *compactionTransactCounter) error { + snapResumed := b.snapIter > 0 + hasLastUkey := b.snapHasLastUkey // The key might has zero length, so this is necessary. + lastUkey := append([]byte{}, b.snapLastUkey...) + lastSeq := b.snapLastSeq + b.kerrCnt = b.snapKerrCnt + b.dropCnt = b.snapDropCnt + // Restore compaction state. + b.c.restore() + + defer b.cleanup() + + b.stat1.startTimer() + defer b.stat1.stopTimer() + + iter := b.c.newIterator() + defer iter.Release() + for i := 0; iter.Next(); i++ { + // Incr transact counter. + cnt.incr() + + // Skip until last state. + if i < b.snapIter { + continue + } + + resumed := false + if snapResumed { + resumed = true + snapResumed = false + } + + ikey := iter.Key() + ukey, seq, kt, kerr := parseInternalKey(ikey) + + if kerr == nil { + shouldStop := !resumed && b.c.shouldStopBefore(ikey) + + if !hasLastUkey || b.s.icmp.uCompare(lastUkey, ukey) != 0 { + // First occurrence of this user key. + + // Only rotate tables if ukey doesn't hop across. + if b.tw != nil && (shouldStop || b.needFlush()) { + if err := b.flush(); err != nil { + return err + } + + // Creates snapshot of the state. + b.c.save() + b.snapHasLastUkey = hasLastUkey + b.snapLastUkey = append(b.snapLastUkey[:0], lastUkey...) + b.snapLastSeq = lastSeq + b.snapIter = i + b.snapKerrCnt = b.kerrCnt + b.snapDropCnt = b.dropCnt + } + + hasLastUkey = true + lastUkey = append(lastUkey[:0], ukey...) + lastSeq = keyMaxSeq + } + + switch { + case lastSeq <= b.minSeq: + // Dropped because newer entry for same user key exist + fallthrough // (A) + case kt == keyTypeDel && seq <= b.minSeq && b.c.baseLevelForKey(lastUkey): + // For this user key: + // (1) there is no data in higher levels + // (2) data in lower levels will have larger seq numbers + // (3) data in layers that are being compacted here and have + // smaller seq numbers will be dropped in the next + // few iterations of this loop (by rule (A) above). + // Therefore this deletion marker is obsolete and can be dropped. + lastSeq = seq + b.dropCnt++ + continue + default: + lastSeq = seq + } + } else { + if b.strict { + return kerr + } + + // Don't drop corrupted keys. + hasLastUkey = false + lastUkey = lastUkey[:0] + lastSeq = keyMaxSeq + b.kerrCnt++ + } + + if err := b.appendKV(ikey, iter.Value()); err != nil { + return err + } + } + + if err := iter.Error(); err != nil { + return err + } + + // Finish last table. + if b.tw != nil && !b.tw.empty() { + return b.flush() + } + return nil +} + +func (b *tableCompactionBuilder) revert() error { + for _, at := range b.rec.addedTables { + b.s.logf("table@build revert @%d", at.num) + if err := b.s.stor.Remove(storage.FileDesc{Type: storage.TypeTable, Num: at.num}); err != nil { + return err + } + } + return nil +} + +func (db *DB) tableCompaction(c *compaction, noTrivial bool) { + defer c.release() + + rec := &sessionRecord{} + rec.addCompPtr(c.sourceLevel, c.imax) + + if !noTrivial && c.trivial() { + t := c.levels[0][0] + db.logf("table@move L%d@%d -> L%d", c.sourceLevel, t.fd.Num, c.sourceLevel+1) + rec.delTable(c.sourceLevel, t.fd.Num) + rec.addTableFile(c.sourceLevel+1, t) + db.compactionCommit("table-move", rec) + return + } + + var stats [2]cStatStaging + for i, tables := range c.levels { + for _, t := range tables { + stats[i].read += t.size + // Insert deleted tables into record + rec.delTable(c.sourceLevel+i, t.fd.Num) + } + } + sourceSize := int(stats[0].read + stats[1].read) + minSeq := db.minSeq() + db.logf("table@compaction L%d·%d -> L%d·%d S·%s Q·%d", c.sourceLevel, len(c.levels[0]), c.sourceLevel+1, len(c.levels[1]), shortenb(sourceSize), minSeq) + + b := &tableCompactionBuilder{ + db: db, + s: db.s, + c: c, + rec: rec, + stat1: &stats[1], + minSeq: minSeq, + strict: db.s.o.GetStrict(opt.StrictCompaction), + tableSize: db.s.o.GetCompactionTableSize(c.sourceLevel + 1), + } + db.compactionTransact("table@build", b) + + // Commit. + stats[1].startTimer() + db.compactionCommit("table", rec) + stats[1].stopTimer() + + resultSize := int(stats[1].write) + db.logf("table@compaction committed F%s S%s Ke·%d D·%d T·%v", sint(len(rec.addedTables)-len(rec.deletedTables)), sshortenb(resultSize-sourceSize), b.kerrCnt, b.dropCnt, stats[1].duration) + + // Save compaction stats + for i := range stats { + db.compStats.addStat(c.sourceLevel+1, &stats[i]) + } +} + +func (db *DB) tableRangeCompaction(level int, umin, umax []byte) error { + db.logf("table@compaction range L%d %q:%q", level, umin, umax) + if level >= 0 { + if c := db.s.getCompactionRange(level, umin, umax, true); c != nil { + db.tableCompaction(c, true) + } + } else { + // Retry until nothing to compact. + for { + compacted := false + + // Scan for maximum level with overlapped tables. + v := db.s.version() + m := 1 + for i := m; i < len(v.levels); i++ { + tables := v.levels[i] + if tables.overlaps(db.s.icmp, umin, umax, false) { + m = i + } + } + v.release() + + for level := 0; level < m; level++ { + if c := db.s.getCompactionRange(level, umin, umax, false); c != nil { + db.tableCompaction(c, true) + compacted = true + } + } + + if !compacted { + break + } + } + } + + return nil +} + +func (db *DB) tableAutoCompaction() { + if c := db.s.pickCompaction(); c != nil { + db.tableCompaction(c, false) + } +} + +func (db *DB) tableNeedCompaction() bool { + v := db.s.version() + defer v.release() + return v.needCompaction() +} + +// resumeWrite returns an indicator whether we should resume write operation if enough level0 files are compacted. +func (db *DB) resumeWrite() bool { + v := db.s.version() + defer v.release() + if v.tLen(0) < db.s.o.GetWriteL0PauseTrigger() { + return true + } + return false +} + +func (db *DB) pauseCompaction(ch chan<- struct{}) { + select { + case ch <- struct{}{}: + case <-db.closeC: + db.compactionExitTransact() + } +} + +type cCmd interface { + ack(err error) +} + +type cAuto struct { + // Note for table compaction, an non-empty ackC represents it's a compaction waiting command. + ackC chan<- error +} + +func (r cAuto) ack(err error) { + if r.ackC != nil { + defer func() { + recover() + }() + r.ackC <- err + } +} + +type cRange struct { + level int + min, max []byte + ackC chan<- error +} + +func (r cRange) ack(err error) { + if r.ackC != nil { + defer func() { + recover() + }() + r.ackC <- err + } +} + +// This will trigger auto compaction but will not wait for it. +func (db *DB) compTrigger(compC chan<- cCmd) { + select { + case compC <- cAuto{}: + default: + } +} + +// This will trigger auto compaction and/or wait for all compaction to be done. +func (db *DB) compTriggerWait(compC chan<- cCmd) (err error) { + ch := make(chan error) + defer close(ch) + // Send cmd. + select { + case compC <- cAuto{ch}: + case err = <-db.compErrC: + return + case <-db.closeC: + return ErrClosed + } + // Wait cmd. + select { + case err = <-ch: + case err = <-db.compErrC: + case <-db.closeC: + return ErrClosed + } + return err +} + +// Send range compaction request. +func (db *DB) compTriggerRange(compC chan<- cCmd, level int, min, max []byte) (err error) { + ch := make(chan error) + defer close(ch) + // Send cmd. + select { + case compC <- cRange{level, min, max, ch}: + case err := <-db.compErrC: + return err + case <-db.closeC: + return ErrClosed + } + // Wait cmd. + select { + case err = <-ch: + case err = <-db.compErrC: + case <-db.closeC: + return ErrClosed + } + return err +} + +func (db *DB) mCompaction() { + var x cCmd + + defer func() { + if x := recover(); x != nil { + if x != errCompactionTransactExiting { + panic(x) + } + } + if x != nil { + x.ack(ErrClosed) + } + db.closeW.Done() + }() + + for { + select { + case x = <-db.mcompCmdC: + switch x.(type) { + case cAuto: + db.memCompaction() + x.ack(nil) + x = nil + default: + panic("leveldb: unknown command") + } + case <-db.closeC: + return + } + } +} + +func (db *DB) tCompaction() { + var ( + x cCmd + waitQ []cCmd + ) + + defer func() { + if x := recover(); x != nil { + if x != errCompactionTransactExiting { + panic(x) + } + } + for i := range waitQ { + waitQ[i].ack(ErrClosed) + waitQ[i] = nil + } + if x != nil { + x.ack(ErrClosed) + } + db.closeW.Done() + }() + + for { + if db.tableNeedCompaction() { + select { + case x = <-db.tcompCmdC: + case ch := <-db.tcompPauseC: + db.pauseCompaction(ch) + continue + case <-db.closeC: + return + default: + } + // Resume write operation as soon as possible. + if len(waitQ) > 0 && db.resumeWrite() { + for i := range waitQ { + waitQ[i].ack(nil) + waitQ[i] = nil + } + waitQ = waitQ[:0] + } + } else { + for i := range waitQ { + waitQ[i].ack(nil) + waitQ[i] = nil + } + waitQ = waitQ[:0] + select { + case x = <-db.tcompCmdC: + case ch := <-db.tcompPauseC: + db.pauseCompaction(ch) + continue + case <-db.closeC: + return + } + } + if x != nil { + switch cmd := x.(type) { + case cAuto: + if cmd.ackC != nil { + // Check the write pause state before caching it. + if db.resumeWrite() { + x.ack(nil) + } else { + waitQ = append(waitQ, x) + } + } + case cRange: + x.ack(db.tableRangeCompaction(cmd.level, cmd.min, cmd.max)) + default: + panic("leveldb: unknown command") + } + x = nil + } + db.tableAutoCompaction() + } +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go new file mode 100644 index 00000000..c2ad70c8 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go @@ -0,0 +1,187 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "container/list" + "fmt" + "runtime" + "sync" + "sync/atomic" + + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" +) + +type snapshotElement struct { + seq uint64 + ref int + e *list.Element +} + +// Acquires a snapshot, based on latest sequence. +func (db *DB) acquireSnapshot() *snapshotElement { + db.snapsMu.Lock() + defer db.snapsMu.Unlock() + + seq := db.getSeq() + + if e := db.snapsList.Back(); e != nil { + se := e.Value.(*snapshotElement) + if se.seq == seq { + se.ref++ + return se + } else if seq < se.seq { + panic("leveldb: sequence number is not increasing") + } + } + se := &snapshotElement{seq: seq, ref: 1} + se.e = db.snapsList.PushBack(se) + return se +} + +// Releases given snapshot element. +func (db *DB) releaseSnapshot(se *snapshotElement) { + db.snapsMu.Lock() + defer db.snapsMu.Unlock() + + se.ref-- + if se.ref == 0 { + db.snapsList.Remove(se.e) + se.e = nil + } else if se.ref < 0 { + panic("leveldb: Snapshot: negative element reference") + } +} + +// Gets minimum sequence that not being snapshotted. +func (db *DB) minSeq() uint64 { + db.snapsMu.Lock() + defer db.snapsMu.Unlock() + + if e := db.snapsList.Front(); e != nil { + return e.Value.(*snapshotElement).seq + } + + return db.getSeq() +} + +// Snapshot is a DB snapshot. +type Snapshot struct { + db *DB + elem *snapshotElement + mu sync.RWMutex + released bool +} + +// Creates new snapshot object. +func (db *DB) newSnapshot() *Snapshot { + snap := &Snapshot{ + db: db, + elem: db.acquireSnapshot(), + } + atomic.AddInt32(&db.aliveSnaps, 1) + runtime.SetFinalizer(snap, (*Snapshot).Release) + return snap +} + +func (snap *Snapshot) String() string { + return fmt.Sprintf("leveldb.Snapshot{%d}", snap.elem.seq) +} + +// Get gets the value for the given key. It returns ErrNotFound if +// the DB does not contains the key. +// +// The caller should not modify the contents of the returned slice, but +// it is safe to modify the contents of the argument after Get returns. +func (snap *Snapshot) Get(key []byte, ro *opt.ReadOptions) (value []byte, err error) { + err = snap.db.ok() + if err != nil { + return + } + snap.mu.RLock() + defer snap.mu.RUnlock() + if snap.released { + err = ErrSnapshotReleased + return + } + return snap.db.get(nil, nil, key, snap.elem.seq, ro) +} + +// Has returns true if the DB does contains the given key. +// +// It is safe to modify the contents of the argument after Get returns. +func (snap *Snapshot) Has(key []byte, ro *opt.ReadOptions) (ret bool, err error) { + err = snap.db.ok() + if err != nil { + return + } + snap.mu.RLock() + defer snap.mu.RUnlock() + if snap.released { + err = ErrSnapshotReleased + return + } + return snap.db.has(nil, nil, key, snap.elem.seq, ro) +} + +// NewIterator returns an iterator for the snapshot of the underlying DB. +// The returned iterator is not safe for concurrent use, but it is safe to use +// multiple iterators concurrently, with each in a dedicated goroutine. +// It is also safe to use an iterator concurrently with modifying its +// underlying DB. The resultant key/value pairs are guaranteed to be +// consistent. +// +// Slice allows slicing the iterator to only contains keys in the given +// range. A nil Range.Start is treated as a key before all keys in the +// DB. And a nil Range.Limit is treated as a key after all keys in +// the DB. +// +// WARNING: Any slice returned by interator (e.g. slice returned by calling +// Iterator.Key() or Iterator.Value() methods), its content should not be +// modified unless noted otherwise. +// +// The iterator must be released after use, by calling Release method. +// Releasing the snapshot doesn't mean releasing the iterator too, the +// iterator would be still valid until released. +// +// Also read Iterator documentation of the leveldb/iterator package. +func (snap *Snapshot) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { + if err := snap.db.ok(); err != nil { + return iterator.NewEmptyIterator(err) + } + snap.mu.Lock() + defer snap.mu.Unlock() + if snap.released { + return iterator.NewEmptyIterator(ErrSnapshotReleased) + } + // Since iterator already hold version ref, it doesn't need to + // hold snapshot ref. + return snap.db.newIterator(nil, nil, snap.elem.seq, slice, ro) +} + +// Release releases the snapshot. This will not release any returned +// iterators, the iterators would still be valid until released or the +// underlying DB is closed. +// +// Other methods should not be called after the snapshot has been released. +func (snap *Snapshot) Release() { + snap.mu.Lock() + defer snap.mu.Unlock() + + if !snap.released { + // Clear the finalizer. + runtime.SetFinalizer(snap, nil) + + snap.released = true + snap.db.releaseSnapshot(snap.elem) + atomic.AddInt32(&snap.db.aliveSnaps, -1) + snap.db = nil + snap.elem = nil + } +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go new file mode 100644 index 00000000..1a000018 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go @@ -0,0 +1,329 @@ +// Copyright (c) 2016, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "errors" + "sync" + "time" + + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" +) + +var errTransactionDone = errors.New("leveldb: transaction already closed") + +// Transaction is the transaction handle. +type Transaction struct { + db *DB + lk sync.RWMutex + seq uint64 + mem *memDB + tables tFiles + ikScratch []byte + rec sessionRecord + stats cStatStaging + closed bool +} + +// Get gets the value for the given key. It returns ErrNotFound if the +// DB does not contains the key. +// +// The returned slice is its own copy, it is safe to modify the contents +// of the returned slice. +// It is safe to modify the contents of the argument after Get returns. +func (tr *Transaction) Get(key []byte, ro *opt.ReadOptions) ([]byte, error) { + tr.lk.RLock() + defer tr.lk.RUnlock() + if tr.closed { + return nil, errTransactionDone + } + return tr.db.get(tr.mem.DB, tr.tables, key, tr.seq, ro) +} + +// Has returns true if the DB does contains the given key. +// +// It is safe to modify the contents of the argument after Has returns. +func (tr *Transaction) Has(key []byte, ro *opt.ReadOptions) (bool, error) { + tr.lk.RLock() + defer tr.lk.RUnlock() + if tr.closed { + return false, errTransactionDone + } + return tr.db.has(tr.mem.DB, tr.tables, key, tr.seq, ro) +} + +// NewIterator returns an iterator for the latest snapshot of the transaction. +// The returned iterator is not safe for concurrent use, but it is safe to use +// multiple iterators concurrently, with each in a dedicated goroutine. +// It is also safe to use an iterator concurrently while writes to the +// transaction. The resultant key/value pairs are guaranteed to be consistent. +// +// Slice allows slicing the iterator to only contains keys in the given +// range. A nil Range.Start is treated as a key before all keys in the +// DB. And a nil Range.Limit is treated as a key after all keys in +// the DB. +// +// WARNING: Any slice returned by interator (e.g. slice returned by calling +// Iterator.Key() or Iterator.Key() methods), its content should not be modified +// unless noted otherwise. +// +// The iterator must be released after use, by calling Release method. +// +// Also read Iterator documentation of the leveldb/iterator package. +func (tr *Transaction) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { + tr.lk.RLock() + defer tr.lk.RUnlock() + if tr.closed { + return iterator.NewEmptyIterator(errTransactionDone) + } + tr.mem.incref() + return tr.db.newIterator(tr.mem, tr.tables, tr.seq, slice, ro) +} + +func (tr *Transaction) flush() error { + // Flush memdb. + if tr.mem.Len() != 0 { + tr.stats.startTimer() + iter := tr.mem.NewIterator(nil) + t, n, err := tr.db.s.tops.createFrom(iter) + iter.Release() + tr.stats.stopTimer() + if err != nil { + return err + } + if tr.mem.getref() == 1 { + tr.mem.Reset() + } else { + tr.mem.decref() + tr.mem = tr.db.mpoolGet(0) + tr.mem.incref() + } + tr.tables = append(tr.tables, t) + tr.rec.addTableFile(0, t) + tr.stats.write += t.size + tr.db.logf("transaction@flush created L0@%d N·%d S·%s %q:%q", t.fd.Num, n, shortenb(int(t.size)), t.imin, t.imax) + } + return nil +} + +func (tr *Transaction) put(kt keyType, key, value []byte) error { + tr.ikScratch = makeInternalKey(tr.ikScratch, key, tr.seq+1, kt) + if tr.mem.Free() < len(tr.ikScratch)+len(value) { + if err := tr.flush(); err != nil { + return err + } + } + if err := tr.mem.Put(tr.ikScratch, value); err != nil { + return err + } + tr.seq++ + return nil +} + +// Put sets the value for the given key. It overwrites any previous value +// for that key; a DB is not a multi-map. +// Please note that the transaction is not compacted until committed, so if you +// writes 10 same keys, then those 10 same keys are in the transaction. +// +// It is safe to modify the contents of the arguments after Put returns. +func (tr *Transaction) Put(key, value []byte, wo *opt.WriteOptions) error { + tr.lk.Lock() + defer tr.lk.Unlock() + if tr.closed { + return errTransactionDone + } + return tr.put(keyTypeVal, key, value) +} + +// Delete deletes the value for the given key. +// Please note that the transaction is not compacted until committed, so if you +// writes 10 same keys, then those 10 same keys are in the transaction. +// +// It is safe to modify the contents of the arguments after Delete returns. +func (tr *Transaction) Delete(key []byte, wo *opt.WriteOptions) error { + tr.lk.Lock() + defer tr.lk.Unlock() + if tr.closed { + return errTransactionDone + } + return tr.put(keyTypeDel, key, nil) +} + +// Write apply the given batch to the transaction. The batch will be applied +// sequentially. +// Please note that the transaction is not compacted until committed, so if you +// writes 10 same keys, then those 10 same keys are in the transaction. +// +// It is safe to modify the contents of the arguments after Write returns. +func (tr *Transaction) Write(b *Batch, wo *opt.WriteOptions) error { + if b == nil || b.Len() == 0 { + return nil + } + + tr.lk.Lock() + defer tr.lk.Unlock() + if tr.closed { + return errTransactionDone + } + return b.replayInternal(func(i int, kt keyType, k, v []byte) error { + return tr.put(kt, k, v) + }) +} + +func (tr *Transaction) setDone() { + tr.closed = true + tr.db.tr = nil + tr.mem.decref() + <-tr.db.writeLockC +} + +// Commit commits the transaction. If error is not nil, then the transaction is +// not committed, it can then either be retried or discarded. +// +// Other methods should not be called after transaction has been committed. +func (tr *Transaction) Commit() error { + if err := tr.db.ok(); err != nil { + return err + } + + tr.lk.Lock() + defer tr.lk.Unlock() + if tr.closed { + return errTransactionDone + } + if err := tr.flush(); err != nil { + // Return error, lets user decide either to retry or discard + // transaction. + return err + } + if len(tr.tables) != 0 { + // Committing transaction. + tr.rec.setSeqNum(tr.seq) + tr.db.compCommitLk.Lock() + tr.stats.startTimer() + var cerr error + for retry := 0; retry < 3; retry++ { + cerr = tr.db.s.commit(&tr.rec) + if cerr != nil { + tr.db.logf("transaction@commit error R·%d %q", retry, cerr) + select { + case <-time.After(time.Second): + case <-tr.db.closeC: + tr.db.logf("transaction@commit exiting") + tr.db.compCommitLk.Unlock() + return cerr + } + } else { + // Success. Set db.seq. + tr.db.setSeq(tr.seq) + break + } + } + tr.stats.stopTimer() + if cerr != nil { + // Return error, lets user decide either to retry or discard + // transaction. + return cerr + } + + // Update compaction stats. This is safe as long as we hold compCommitLk. + tr.db.compStats.addStat(0, &tr.stats) + + // Trigger table auto-compaction. + tr.db.compTrigger(tr.db.tcompCmdC) + tr.db.compCommitLk.Unlock() + + // Additionally, wait compaction when certain threshold reached. + // Ignore error, returns error only if transaction can't be committed. + tr.db.waitCompaction() + } + // Only mark as done if transaction committed successfully. + tr.setDone() + return nil +} + +func (tr *Transaction) discard() { + // Discard transaction. + for _, t := range tr.tables { + tr.db.logf("transaction@discard @%d", t.fd.Num) + if err1 := tr.db.s.stor.Remove(t.fd); err1 == nil { + tr.db.s.reuseFileNum(t.fd.Num) + } + } +} + +// Discard discards the transaction. +// +// Other methods should not be called after transaction has been discarded. +func (tr *Transaction) Discard() { + tr.lk.Lock() + if !tr.closed { + tr.discard() + tr.setDone() + } + tr.lk.Unlock() +} + +func (db *DB) waitCompaction() error { + if db.s.tLen(0) >= db.s.o.GetWriteL0PauseTrigger() { + return db.compTriggerWait(db.tcompCmdC) + } + return nil +} + +// OpenTransaction opens an atomic DB transaction. Only one transaction can be +// opened at a time. Subsequent call to Write and OpenTransaction will be blocked +// until in-flight transaction is committed or discarded. +// The returned transaction handle is safe for concurrent use. +// +// Transaction is expensive and can overwhelm compaction, especially if +// transaction size is small. Use with caution. +// +// The transaction must be closed once done, either by committing or discarding +// the transaction. +// Closing the DB will discard open transaction. +func (db *DB) OpenTransaction() (*Transaction, error) { + if err := db.ok(); err != nil { + return nil, err + } + + // The write happen synchronously. + select { + case db.writeLockC <- struct{}{}: + case err := <-db.compPerErrC: + return nil, err + case <-db.closeC: + return nil, ErrClosed + } + + if db.tr != nil { + panic("leveldb: has open transaction") + } + + // Flush current memdb. + if db.mem != nil && db.mem.Len() != 0 { + if _, err := db.rotateMem(0, true); err != nil { + return nil, err + } + } + + // Wait compaction when certain threshold reached. + if err := db.waitCompaction(); err != nil { + return nil, err + } + + tr := &Transaction{ + db: db, + seq: db.seq, + mem: db.mpoolGet(0), + } + tr.mem.incref() + db.tr = tr + return tr, nil +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_util.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_util.go new file mode 100644 index 00000000..3f065489 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_util.go @@ -0,0 +1,102 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// Reader is the interface that wraps basic Get and NewIterator methods. +// This interface implemented by both DB and Snapshot. +type Reader interface { + Get(key []byte, ro *opt.ReadOptions) (value []byte, err error) + NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator +} + +// Sizes is list of size. +type Sizes []int64 + +// Sum returns sum of the sizes. +func (sizes Sizes) Sum() int64 { + var sum int64 + for _, size := range sizes { + sum += size + } + return sum +} + +// Logging. +func (db *DB) log(v ...interface{}) { db.s.log(v...) } +func (db *DB) logf(format string, v ...interface{}) { db.s.logf(format, v...) } + +// Check and clean files. +func (db *DB) checkAndCleanFiles() error { + v := db.s.version() + defer v.release() + + tmap := make(map[int64]bool) + for _, tables := range v.levels { + for _, t := range tables { + tmap[t.fd.Num] = false + } + } + + fds, err := db.s.stor.List(storage.TypeAll) + if err != nil { + return err + } + + var nt int + var rem []storage.FileDesc + for _, fd := range fds { + keep := true + switch fd.Type { + case storage.TypeManifest: + keep = fd.Num >= db.s.manifestFd.Num + case storage.TypeJournal: + if !db.frozenJournalFd.Zero() { + keep = fd.Num >= db.frozenJournalFd.Num + } else { + keep = fd.Num >= db.journalFd.Num + } + case storage.TypeTable: + _, keep = tmap[fd.Num] + if keep { + tmap[fd.Num] = true + nt++ + } + } + + if !keep { + rem = append(rem, fd) + } + } + + if nt != len(tmap) { + var mfds []storage.FileDesc + for num, present := range tmap { + if !present { + mfds = append(mfds, storage.FileDesc{Type: storage.TypeTable, Num: num}) + db.logf("db@janitor table missing @%d", num) + } + } + return errors.NewErrCorrupted(storage.FileDesc{}, &errors.ErrMissingFiles{Fds: mfds}) + } + + db.logf("db@janitor F·%d G·%d", len(fds), len(rem)) + for _, fd := range rem { + db.logf("db@janitor removing %s-%d", fd.Type, fd.Num) + if err := db.s.stor.Remove(fd); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go b/vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go new file mode 100644 index 00000000..96fb0f68 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go @@ -0,0 +1,132 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Package iterator provides interface and implementation to traverse over +// contents of a database. +package iterator + +import ( + "errors" + + "github.com/syndtr/goleveldb/leveldb/util" +) + +var ( + ErrIterReleased = errors.New("leveldb/iterator: iterator released") +) + +// IteratorSeeker is the interface that wraps the 'seeks method'. +type IteratorSeeker interface { + // First moves the iterator to the first key/value pair. If the iterator + // only contains one key/value pair then First and Last would moves + // to the same key/value pair. + // It returns whether such pair exist. + First() bool + + // Last moves the iterator to the last key/value pair. If the iterator + // only contains one key/value pair then First and Last would moves + // to the same key/value pair. + // It returns whether such pair exist. + Last() bool + + // Seek moves the iterator to the first key/value pair whose key is greater + // than or equal to the given key. + // It returns whether such pair exist. + // + // It is safe to modify the contents of the argument after Seek returns. + Seek(key []byte) bool + + // Next moves the iterator to the next key/value pair. + // It returns false if the iterator is exhausted. + Next() bool + + // Prev moves the iterator to the previous key/value pair. + // It returns false if the iterator is exhausted. + Prev() bool +} + +// CommonIterator is the interface that wraps common iterator methods. +type CommonIterator interface { + IteratorSeeker + + // util.Releaser is the interface that wraps basic Release method. + // When called Release will releases any resources associated with the + // iterator. + util.Releaser + + // util.ReleaseSetter is the interface that wraps the basic SetReleaser + // method. + util.ReleaseSetter + + // TODO: Remove this when ready. + Valid() bool + + // Error returns any accumulated error. Exhausting all the key/value pairs + // is not considered to be an error. + Error() error +} + +// Iterator iterates over a DB's key/value pairs in key order. +// +// When encounter an error any 'seeks method' will return false and will +// yield no key/value pairs. The error can be queried by calling the Error +// method. Calling Release is still necessary. +// +// An iterator must be released after use, but it is not necessary to read +// an iterator until exhaustion. +// Also, an iterator is not necessarily safe for concurrent use, but it is +// safe to use multiple iterators concurrently, with each in a dedicated +// goroutine. +type Iterator interface { + CommonIterator + + // Key returns the key of the current key/value pair, or nil if done. + // The caller should not modify the contents of the returned slice, and + // its contents may change on the next call to any 'seeks method'. + Key() []byte + + // Value returns the value of the current key/value pair, or nil if done. + // The caller should not modify the contents of the returned slice, and + // its contents may change on the next call to any 'seeks method'. + Value() []byte +} + +// ErrorCallbackSetter is the interface that wraps basic SetErrorCallback +// method. +// +// ErrorCallbackSetter implemented by indexed and merged iterator. +type ErrorCallbackSetter interface { + // SetErrorCallback allows set an error callback of the corresponding + // iterator. Use nil to clear the callback. + SetErrorCallback(f func(err error)) +} + +type emptyIterator struct { + util.BasicReleaser + err error +} + +func (i *emptyIterator) rErr() { + if i.err == nil && i.Released() { + i.err = ErrIterReleased + } +} + +func (*emptyIterator) Valid() bool { return false } +func (i *emptyIterator) First() bool { i.rErr(); return false } +func (i *emptyIterator) Last() bool { i.rErr(); return false } +func (i *emptyIterator) Seek(key []byte) bool { i.rErr(); return false } +func (i *emptyIterator) Next() bool { i.rErr(); return false } +func (i *emptyIterator) Prev() bool { i.rErr(); return false } +func (*emptyIterator) Key() []byte { return nil } +func (*emptyIterator) Value() []byte { return nil } +func (i *emptyIterator) Error() error { return i.err } + +// NewEmptyIterator creates an empty iterator. The err parameter can be +// nil, but if not nil the given err will be returned by Error method. +func NewEmptyIterator(err error) Iterator { + return &emptyIterator{err: err} +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go b/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go new file mode 100644 index 00000000..824e47f5 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go @@ -0,0 +1,479 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Package memdb provides in-memory key/value database implementation. +package memdb + +import ( + "math/rand" + "sync" + + "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// Common errors. +var ( + ErrNotFound = errors.ErrNotFound + ErrIterReleased = errors.New("leveldb/memdb: iterator released") +) + +const tMaxHeight = 12 + +type dbIter struct { + util.BasicReleaser + p *DB + slice *util.Range + node int + forward bool + key, value []byte + err error +} + +func (i *dbIter) fill(checkStart, checkLimit bool) bool { + if i.node != 0 { + n := i.p.nodeData[i.node] + m := n + i.p.nodeData[i.node+nKey] + i.key = i.p.kvData[n:m] + if i.slice != nil { + switch { + case checkLimit && i.slice.Limit != nil && i.p.cmp.Compare(i.key, i.slice.Limit) >= 0: + fallthrough + case checkStart && i.slice.Start != nil && i.p.cmp.Compare(i.key, i.slice.Start) < 0: + i.node = 0 + goto bail + } + } + i.value = i.p.kvData[m : m+i.p.nodeData[i.node+nVal]] + return true + } +bail: + i.key = nil + i.value = nil + return false +} + +func (i *dbIter) Valid() bool { + return i.node != 0 +} + +func (i *dbIter) First() bool { + if i.Released() { + i.err = ErrIterReleased + return false + } + + i.forward = true + i.p.mu.RLock() + defer i.p.mu.RUnlock() + if i.slice != nil && i.slice.Start != nil { + i.node, _ = i.p.findGE(i.slice.Start, false) + } else { + i.node = i.p.nodeData[nNext] + } + return i.fill(false, true) +} + +func (i *dbIter) Last() bool { + if i.Released() { + i.err = ErrIterReleased + return false + } + + i.forward = false + i.p.mu.RLock() + defer i.p.mu.RUnlock() + if i.slice != nil && i.slice.Limit != nil { + i.node = i.p.findLT(i.slice.Limit) + } else { + i.node = i.p.findLast() + } + return i.fill(true, false) +} + +func (i *dbIter) Seek(key []byte) bool { + if i.Released() { + i.err = ErrIterReleased + return false + } + + i.forward = true + i.p.mu.RLock() + defer i.p.mu.RUnlock() + if i.slice != nil && i.slice.Start != nil && i.p.cmp.Compare(key, i.slice.Start) < 0 { + key = i.slice.Start + } + i.node, _ = i.p.findGE(key, false) + return i.fill(false, true) +} + +func (i *dbIter) Next() bool { + if i.Released() { + i.err = ErrIterReleased + return false + } + + if i.node == 0 { + if !i.forward { + return i.First() + } + return false + } + i.forward = true + i.p.mu.RLock() + defer i.p.mu.RUnlock() + i.node = i.p.nodeData[i.node+nNext] + return i.fill(false, true) +} + +func (i *dbIter) Prev() bool { + if i.Released() { + i.err = ErrIterReleased + return false + } + + if i.node == 0 { + if i.forward { + return i.Last() + } + return false + } + i.forward = false + i.p.mu.RLock() + defer i.p.mu.RUnlock() + i.node = i.p.findLT(i.key) + return i.fill(true, false) +} + +func (i *dbIter) Key() []byte { + return i.key +} + +func (i *dbIter) Value() []byte { + return i.value +} + +func (i *dbIter) Error() error { return i.err } + +func (i *dbIter) Release() { + if !i.Released() { + i.p = nil + i.node = 0 + i.key = nil + i.value = nil + i.BasicReleaser.Release() + } +} + +const ( + nKV = iota + nKey + nVal + nHeight + nNext +) + +// DB is an in-memory key/value database. +type DB struct { + cmp comparer.BasicComparer + rnd *rand.Rand + + mu sync.RWMutex + kvData []byte + // Node data: + // [0] : KV offset + // [1] : Key length + // [2] : Value length + // [3] : Height + // [3..height] : Next nodes + nodeData []int + prevNode [tMaxHeight]int + maxHeight int + n int + kvSize int +} + +func (p *DB) randHeight() (h int) { + const branching = 4 + h = 1 + for h < tMaxHeight && p.rnd.Int()%branching == 0 { + h++ + } + return +} + +// Must hold RW-lock if prev == true, as it use shared prevNode slice. +func (p *DB) findGE(key []byte, prev bool) (int, bool) { + node := 0 + h := p.maxHeight - 1 + for { + next := p.nodeData[node+nNext+h] + cmp := 1 + if next != 0 { + o := p.nodeData[next] + cmp = p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key) + } + if cmp < 0 { + // Keep searching in this list + node = next + } else { + if prev { + p.prevNode[h] = node + } else if cmp == 0 { + return next, true + } + if h == 0 { + return next, cmp == 0 + } + h-- + } + } +} + +func (p *DB) findLT(key []byte) int { + node := 0 + h := p.maxHeight - 1 + for { + next := p.nodeData[node+nNext+h] + o := p.nodeData[next] + if next == 0 || p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key) >= 0 { + if h == 0 { + break + } + h-- + } else { + node = next + } + } + return node +} + +func (p *DB) findLast() int { + node := 0 + h := p.maxHeight - 1 + for { + next := p.nodeData[node+nNext+h] + if next == 0 { + if h == 0 { + break + } + h-- + } else { + node = next + } + } + return node +} + +// Put sets the value for the given key. It overwrites any previous value +// for that key; a DB is not a multi-map. +// +// It is safe to modify the contents of the arguments after Put returns. +func (p *DB) Put(key []byte, value []byte) error { + p.mu.Lock() + defer p.mu.Unlock() + + if node, exact := p.findGE(key, true); exact { + kvOffset := len(p.kvData) + p.kvData = append(p.kvData, key...) + p.kvData = append(p.kvData, value...) + p.nodeData[node] = kvOffset + m := p.nodeData[node+nVal] + p.nodeData[node+nVal] = len(value) + p.kvSize += len(value) - m + return nil + } + + h := p.randHeight() + if h > p.maxHeight { + for i := p.maxHeight; i < h; i++ { + p.prevNode[i] = 0 + } + p.maxHeight = h + } + + kvOffset := len(p.kvData) + p.kvData = append(p.kvData, key...) + p.kvData = append(p.kvData, value...) + // Node + node := len(p.nodeData) + p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h) + for i, n := range p.prevNode[:h] { + m := n + nNext + i + p.nodeData = append(p.nodeData, p.nodeData[m]) + p.nodeData[m] = node + } + + p.kvSize += len(key) + len(value) + p.n++ + return nil +} + +// Delete deletes the value for the given key. It returns ErrNotFound if +// the DB does not contain the key. +// +// It is safe to modify the contents of the arguments after Delete returns. +func (p *DB) Delete(key []byte) error { + p.mu.Lock() + defer p.mu.Unlock() + + node, exact := p.findGE(key, true) + if !exact { + return ErrNotFound + } + + h := p.nodeData[node+nHeight] + for i, n := range p.prevNode[:h] { + m := n + nNext + i + p.nodeData[m] = p.nodeData[p.nodeData[m]+nNext+i] + } + + p.kvSize -= p.nodeData[node+nKey] + p.nodeData[node+nVal] + p.n-- + return nil +} + +// Contains returns true if the given key are in the DB. +// +// It is safe to modify the contents of the arguments after Contains returns. +func (p *DB) Contains(key []byte) bool { + p.mu.RLock() + _, exact := p.findGE(key, false) + p.mu.RUnlock() + return exact +} + +// Get gets the value for the given key. It returns error.ErrNotFound if the +// DB does not contain the key. +// +// The caller should not modify the contents of the returned slice, but +// it is safe to modify the contents of the argument after Get returns. +func (p *DB) Get(key []byte) (value []byte, err error) { + p.mu.RLock() + if node, exact := p.findGE(key, false); exact { + o := p.nodeData[node] + p.nodeData[node+nKey] + value = p.kvData[o : o+p.nodeData[node+nVal]] + } else { + err = ErrNotFound + } + p.mu.RUnlock() + return +} + +// Find finds key/value pair whose key is greater than or equal to the +// given key. It returns ErrNotFound if the table doesn't contain +// such pair. +// +// The caller should not modify the contents of the returned slice, but +// it is safe to modify the contents of the argument after Find returns. +func (p *DB) Find(key []byte) (rkey, value []byte, err error) { + p.mu.RLock() + if node, _ := p.findGE(key, false); node != 0 { + n := p.nodeData[node] + m := n + p.nodeData[node+nKey] + rkey = p.kvData[n:m] + value = p.kvData[m : m+p.nodeData[node+nVal]] + } else { + err = ErrNotFound + } + p.mu.RUnlock() + return +} + +// NewIterator returns an iterator of the DB. +// The returned iterator is not safe for concurrent use, but it is safe to use +// multiple iterators concurrently, with each in a dedicated goroutine. +// It is also safe to use an iterator concurrently with modifying its +// underlying DB. However, the resultant key/value pairs are not guaranteed +// to be a consistent snapshot of the DB at a particular point in time. +// +// Slice allows slicing the iterator to only contains keys in the given +// range. A nil Range.Start is treated as a key before all keys in the +// DB. And a nil Range.Limit is treated as a key after all keys in +// the DB. +// +// WARNING: Any slice returned by interator (e.g. slice returned by calling +// Iterator.Key() or Iterator.Key() methods), its content should not be modified +// unless noted otherwise. +// +// The iterator must be released after use, by calling Release method. +// +// Also read Iterator documentation of the leveldb/iterator package. +func (p *DB) NewIterator(slice *util.Range) iterator.Iterator { + return &dbIter{p: p, slice: slice} +} + +// Capacity returns keys/values buffer capacity. +func (p *DB) Capacity() int { + p.mu.RLock() + defer p.mu.RUnlock() + return cap(p.kvData) +} + +// Size returns sum of keys and values length. Note that deleted +// key/value will not be accounted for, but it will still consume +// the buffer, since the buffer is append only. +func (p *DB) Size() int { + p.mu.RLock() + defer p.mu.RUnlock() + return p.kvSize +} + +// Free returns keys/values free buffer before need to grow. +func (p *DB) Free() int { + p.mu.RLock() + defer p.mu.RUnlock() + return cap(p.kvData) - len(p.kvData) +} + +// Len returns the number of entries in the DB. +func (p *DB) Len() int { + p.mu.RLock() + defer p.mu.RUnlock() + return p.n +} + +// Reset resets the DB to initial empty state. Allows reuse the buffer. +func (p *DB) Reset() { + p.mu.Lock() + p.rnd = rand.New(rand.NewSource(0xdeadbeef)) + p.maxHeight = 1 + p.n = 0 + p.kvSize = 0 + p.kvData = p.kvData[:0] + p.nodeData = p.nodeData[:nNext+tMaxHeight] + p.nodeData[nKV] = 0 + p.nodeData[nKey] = 0 + p.nodeData[nVal] = 0 + p.nodeData[nHeight] = tMaxHeight + for n := 0; n < tMaxHeight; n++ { + p.nodeData[nNext+n] = 0 + p.prevNode[n] = 0 + } + p.mu.Unlock() +} + +// New creates a new initialized in-memory key/value DB. The capacity +// is the initial key/value buffer capacity. The capacity is advisory, +// not enforced. +// +// This DB is append-only, deleting an entry would remove entry node but not +// reclaim KV buffer. +// +// The returned DB instance is safe for concurrent use. +func New(cmp comparer.BasicComparer, capacity int) *DB { + p := &DB{ + cmp: cmp, + rnd: rand.New(rand.NewSource(0xdeadbeef)), + maxHeight: 1, + kvData: make([]byte, 0, capacity), + nodeData: make([]int, 4+tMaxHeight), + } + p.nodeData[nHeight] = tMaxHeight + return p +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/opt/options.go b/vendor/github.com/syndtr/goleveldb/leveldb/opt/options.go new file mode 100644 index 00000000..528b1642 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/opt/options.go @@ -0,0 +1,697 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Package opt provides sets of options used by LevelDB. +package opt + +import ( + "math" + + "github.com/syndtr/goleveldb/leveldb/cache" + "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/syndtr/goleveldb/leveldb/filter" +) + +const ( + KiB = 1024 + MiB = KiB * 1024 + GiB = MiB * 1024 +) + +var ( + DefaultBlockCacher = LRUCacher + DefaultBlockCacheCapacity = 8 * MiB + DefaultBlockRestartInterval = 16 + DefaultBlockSize = 4 * KiB + DefaultCompactionExpandLimitFactor = 25 + DefaultCompactionGPOverlapsFactor = 10 + DefaultCompactionL0Trigger = 4 + DefaultCompactionSourceLimitFactor = 1 + DefaultCompactionTableSize = 2 * MiB + DefaultCompactionTableSizeMultiplier = 1.0 + DefaultCompactionTotalSize = 10 * MiB + DefaultCompactionTotalSizeMultiplier = 10.0 + DefaultCompressionType = SnappyCompression + DefaultIteratorSamplingRate = 1 * MiB + DefaultOpenFilesCacher = LRUCacher + DefaultOpenFilesCacheCapacity = 500 + DefaultWriteBuffer = 4 * MiB + DefaultWriteL0PauseTrigger = 12 + DefaultWriteL0SlowdownTrigger = 8 +) + +// Cacher is a caching algorithm. +type Cacher interface { + New(capacity int) cache.Cacher +} + +type CacherFunc struct { + NewFunc func(capacity int) cache.Cacher +} + +func (f *CacherFunc) New(capacity int) cache.Cacher { + if f.NewFunc != nil { + return f.NewFunc(capacity) + } + return nil +} + +func noCacher(int) cache.Cacher { return nil } + +var ( + // LRUCacher is the LRU-cache algorithm. + LRUCacher = &CacherFunc{cache.NewLRU} + + // NoCacher is the value to disable caching algorithm. + NoCacher = &CacherFunc{} +) + +// Compression is the 'sorted table' block compression algorithm to use. +type Compression uint + +func (c Compression) String() string { + switch c { + case DefaultCompression: + return "default" + case NoCompression: + return "none" + case SnappyCompression: + return "snappy" + } + return "invalid" +} + +const ( + DefaultCompression Compression = iota + NoCompression + SnappyCompression + nCompression +) + +// Strict is the DB 'strict level'. +type Strict uint + +const ( + // If present then a corrupted or invalid chunk or block in manifest + // journal will cause an error instead of being dropped. + // This will prevent database with corrupted manifest to be opened. + StrictManifest Strict = 1 << iota + + // If present then journal chunk checksum will be verified. + StrictJournalChecksum + + // If present then a corrupted or invalid chunk or block in journal + // will cause an error instead of being dropped. + // This will prevent database with corrupted journal to be opened. + StrictJournal + + // If present then 'sorted table' block checksum will be verified. + // This has effect on both 'read operation' and compaction. + StrictBlockChecksum + + // If present then a corrupted 'sorted table' will fails compaction. + // The database will enter read-only mode. + StrictCompaction + + // If present then a corrupted 'sorted table' will halts 'read operation'. + StrictReader + + // If present then leveldb.Recover will drop corrupted 'sorted table'. + StrictRecovery + + // This only applicable for ReadOptions, if present then this ReadOptions + // 'strict level' will override global ones. + StrictOverride + + // StrictAll enables all strict flags. + StrictAll = StrictManifest | StrictJournalChecksum | StrictJournal | StrictBlockChecksum | StrictCompaction | StrictReader | StrictRecovery + + // DefaultStrict is the default strict flags. Specify any strict flags + // will override default strict flags as whole (i.e. not OR'ed). + DefaultStrict = StrictJournalChecksum | StrictBlockChecksum | StrictCompaction | StrictReader + + // NoStrict disables all strict flags. Override default strict flags. + NoStrict = ^StrictAll +) + +// Options holds the optional parameters for the DB at large. +type Options struct { + // AltFilters defines one or more 'alternative filters'. + // 'alternative filters' will be used during reads if a filter block + // does not match with the 'effective filter'. + // + // The default value is nil + AltFilters []filter.Filter + + // BlockCacher provides cache algorithm for LevelDB 'sorted table' block caching. + // Specify NoCacher to disable caching algorithm. + // + // The default value is LRUCacher. + BlockCacher Cacher + + // BlockCacheCapacity defines the capacity of the 'sorted table' block caching. + // Use -1 for zero, this has same effect as specifying NoCacher to BlockCacher. + // + // The default value is 8MiB. + BlockCacheCapacity int + + // BlockCacheEvictRemoved allows enable forced-eviction on cached block belonging + // to removed 'sorted table'. + // + // The default if false. + BlockCacheEvictRemoved bool + + // BlockRestartInterval is the number of keys between restart points for + // delta encoding of keys. + // + // The default value is 16. + BlockRestartInterval int + + // BlockSize is the minimum uncompressed size in bytes of each 'sorted table' + // block. + // + // The default value is 4KiB. + BlockSize int + + // CompactionExpandLimitFactor limits compaction size after expanded. + // This will be multiplied by table size limit at compaction target level. + // + // The default value is 25. + CompactionExpandLimitFactor int + + // CompactionGPOverlapsFactor limits overlaps in grandparent (Level + 2) that a + // single 'sorted table' generates. + // This will be multiplied by table size limit at grandparent level. + // + // The default value is 10. + CompactionGPOverlapsFactor int + + // CompactionL0Trigger defines number of 'sorted table' at level-0 that will + // trigger compaction. + // + // The default value is 4. + CompactionL0Trigger int + + // CompactionSourceLimitFactor limits compaction source size. This doesn't apply to + // level-0. + // This will be multiplied by table size limit at compaction target level. + // + // The default value is 1. + CompactionSourceLimitFactor int + + // CompactionTableSize limits size of 'sorted table' that compaction generates. + // The limits for each level will be calculated as: + // CompactionTableSize * (CompactionTableSizeMultiplier ^ Level) + // The multiplier for each level can also fine-tuned using CompactionTableSizeMultiplierPerLevel. + // + // The default value is 2MiB. + CompactionTableSize int + + // CompactionTableSizeMultiplier defines multiplier for CompactionTableSize. + // + // The default value is 1. + CompactionTableSizeMultiplier float64 + + // CompactionTableSizeMultiplierPerLevel defines per-level multiplier for + // CompactionTableSize. + // Use zero to skip a level. + // + // The default value is nil. + CompactionTableSizeMultiplierPerLevel []float64 + + // CompactionTotalSize limits total size of 'sorted table' for each level. + // The limits for each level will be calculated as: + // CompactionTotalSize * (CompactionTotalSizeMultiplier ^ Level) + // The multiplier for each level can also fine-tuned using + // CompactionTotalSizeMultiplierPerLevel. + // + // The default value is 10MiB. + CompactionTotalSize int + + // CompactionTotalSizeMultiplier defines multiplier for CompactionTotalSize. + // + // The default value is 10. + CompactionTotalSizeMultiplier float64 + + // CompactionTotalSizeMultiplierPerLevel defines per-level multiplier for + // CompactionTotalSize. + // Use zero to skip a level. + // + // The default value is nil. + CompactionTotalSizeMultiplierPerLevel []float64 + + // Comparer defines a total ordering over the space of []byte keys: a 'less + // than' relationship. The same comparison algorithm must be used for reads + // and writes over the lifetime of the DB. + // + // The default value uses the same ordering as bytes.Compare. + Comparer comparer.Comparer + + // Compression defines the 'sorted table' block compression to use. + // + // The default value (DefaultCompression) uses snappy compression. + Compression Compression + + // DisableBufferPool allows disable use of util.BufferPool functionality. + // + // The default value is false. + DisableBufferPool bool + + // DisableBlockCache allows disable use of cache.Cache functionality on + // 'sorted table' block. + // + // The default value is false. + DisableBlockCache bool + + // DisableCompactionBackoff allows disable compaction retry backoff. + // + // The default value is false. + DisableCompactionBackoff bool + + // DisableLargeBatchTransaction allows disabling switch-to-transaction mode + // on large batch write. If enable batch writes large than WriteBuffer will + // use transaction. + // + // The default is false. + DisableLargeBatchTransaction bool + + // ErrorIfExist defines whether an error should returned if the DB already + // exist. + // + // The default value is false. + ErrorIfExist bool + + // ErrorIfMissing defines whether an error should returned if the DB is + // missing. If false then the database will be created if missing, otherwise + // an error will be returned. + // + // The default value is false. + ErrorIfMissing bool + + // Filter defines an 'effective filter' to use. An 'effective filter' + // if defined will be used to generate per-table filter block. + // The filter name will be stored on disk. + // During reads LevelDB will try to find matching filter from + // 'effective filter' and 'alternative filters'. + // + // Filter can be changed after a DB has been created. It is recommended + // to put old filter to the 'alternative filters' to mitigate lack of + // filter during transition period. + // + // A filter is used to reduce disk reads when looking for a specific key. + // + // The default value is nil. + Filter filter.Filter + + // IteratorSamplingRate defines approximate gap (in bytes) between read + // sampling of an iterator. The samples will be used to determine when + // compaction should be triggered. + // + // The default is 1MiB. + IteratorSamplingRate int + + // NoSync allows completely disable fsync. + // + // The default is false. + NoSync bool + + // NoWriteMerge allows disabling write merge. + // + // The default is false. + NoWriteMerge bool + + // OpenFilesCacher provides cache algorithm for open files caching. + // Specify NoCacher to disable caching algorithm. + // + // The default value is LRUCacher. + OpenFilesCacher Cacher + + // OpenFilesCacheCapacity defines the capacity of the open files caching. + // Use -1 for zero, this has same effect as specifying NoCacher to OpenFilesCacher. + // + // The default value is 500. + OpenFilesCacheCapacity int + + // If true then opens DB in read-only mode. + // + // The default value is false. + ReadOnly bool + + // Strict defines the DB strict level. + Strict Strict + + // WriteBuffer defines maximum size of a 'memdb' before flushed to + // 'sorted table'. 'memdb' is an in-memory DB backed by an on-disk + // unsorted journal. + // + // LevelDB may held up to two 'memdb' at the same time. + // + // The default value is 4MiB. + WriteBuffer int + + // WriteL0StopTrigger defines number of 'sorted table' at level-0 that will + // pause write. + // + // The default value is 12. + WriteL0PauseTrigger int + + // WriteL0SlowdownTrigger defines number of 'sorted table' at level-0 that + // will trigger write slowdown. + // + // The default value is 8. + WriteL0SlowdownTrigger int +} + +func (o *Options) GetAltFilters() []filter.Filter { + if o == nil { + return nil + } + return o.AltFilters +} + +func (o *Options) GetBlockCacher() Cacher { + if o == nil || o.BlockCacher == nil { + return DefaultBlockCacher + } else if o.BlockCacher == NoCacher { + return nil + } + return o.BlockCacher +} + +func (o *Options) GetBlockCacheCapacity() int { + if o == nil || o.BlockCacheCapacity == 0 { + return DefaultBlockCacheCapacity + } else if o.BlockCacheCapacity < 0 { + return 0 + } + return o.BlockCacheCapacity +} + +func (o *Options) GetBlockCacheEvictRemoved() bool { + if o == nil { + return false + } + return o.BlockCacheEvictRemoved +} + +func (o *Options) GetBlockRestartInterval() int { + if o == nil || o.BlockRestartInterval <= 0 { + return DefaultBlockRestartInterval + } + return o.BlockRestartInterval +} + +func (o *Options) GetBlockSize() int { + if o == nil || o.BlockSize <= 0 { + return DefaultBlockSize + } + return o.BlockSize +} + +func (o *Options) GetCompactionExpandLimit(level int) int { + factor := DefaultCompactionExpandLimitFactor + if o != nil && o.CompactionExpandLimitFactor > 0 { + factor = o.CompactionExpandLimitFactor + } + return o.GetCompactionTableSize(level+1) * factor +} + +func (o *Options) GetCompactionGPOverlaps(level int) int { + factor := DefaultCompactionGPOverlapsFactor + if o != nil && o.CompactionGPOverlapsFactor > 0 { + factor = o.CompactionGPOverlapsFactor + } + return o.GetCompactionTableSize(level+2) * factor +} + +func (o *Options) GetCompactionL0Trigger() int { + if o == nil || o.CompactionL0Trigger == 0 { + return DefaultCompactionL0Trigger + } + return o.CompactionL0Trigger +} + +func (o *Options) GetCompactionSourceLimit(level int) int { + factor := DefaultCompactionSourceLimitFactor + if o != nil && o.CompactionSourceLimitFactor > 0 { + factor = o.CompactionSourceLimitFactor + } + return o.GetCompactionTableSize(level+1) * factor +} + +func (o *Options) GetCompactionTableSize(level int) int { + var ( + base = DefaultCompactionTableSize + mult float64 + ) + if o != nil { + if o.CompactionTableSize > 0 { + base = o.CompactionTableSize + } + if level < len(o.CompactionTableSizeMultiplierPerLevel) && o.CompactionTableSizeMultiplierPerLevel[level] > 0 { + mult = o.CompactionTableSizeMultiplierPerLevel[level] + } else if o.CompactionTableSizeMultiplier > 0 { + mult = math.Pow(o.CompactionTableSizeMultiplier, float64(level)) + } + } + if mult == 0 { + mult = math.Pow(DefaultCompactionTableSizeMultiplier, float64(level)) + } + return int(float64(base) * mult) +} + +func (o *Options) GetCompactionTotalSize(level int) int64 { + var ( + base = DefaultCompactionTotalSize + mult float64 + ) + if o != nil { + if o.CompactionTotalSize > 0 { + base = o.CompactionTotalSize + } + if level < len(o.CompactionTotalSizeMultiplierPerLevel) && o.CompactionTotalSizeMultiplierPerLevel[level] > 0 { + mult = o.CompactionTotalSizeMultiplierPerLevel[level] + } else if o.CompactionTotalSizeMultiplier > 0 { + mult = math.Pow(o.CompactionTotalSizeMultiplier, float64(level)) + } + } + if mult == 0 { + mult = math.Pow(DefaultCompactionTotalSizeMultiplier, float64(level)) + } + return int64(float64(base) * mult) +} + +func (o *Options) GetComparer() comparer.Comparer { + if o == nil || o.Comparer == nil { + return comparer.DefaultComparer + } + return o.Comparer +} + +func (o *Options) GetCompression() Compression { + if o == nil || o.Compression <= DefaultCompression || o.Compression >= nCompression { + return DefaultCompressionType + } + return o.Compression +} + +func (o *Options) GetDisableBufferPool() bool { + if o == nil { + return false + } + return o.DisableBufferPool +} + +func (o *Options) GetDisableBlockCache() bool { + if o == nil { + return false + } + return o.DisableBlockCache +} + +func (o *Options) GetDisableCompactionBackoff() bool { + if o == nil { + return false + } + return o.DisableCompactionBackoff +} + +func (o *Options) GetDisableLargeBatchTransaction() bool { + if o == nil { + return false + } + return o.DisableLargeBatchTransaction +} + +func (o *Options) GetErrorIfExist() bool { + if o == nil { + return false + } + return o.ErrorIfExist +} + +func (o *Options) GetErrorIfMissing() bool { + if o == nil { + return false + } + return o.ErrorIfMissing +} + +func (o *Options) GetFilter() filter.Filter { + if o == nil { + return nil + } + return o.Filter +} + +func (o *Options) GetIteratorSamplingRate() int { + if o == nil || o.IteratorSamplingRate <= 0 { + return DefaultIteratorSamplingRate + } + return o.IteratorSamplingRate +} + +func (o *Options) GetNoSync() bool { + if o == nil { + return false + } + return o.NoSync +} + +func (o *Options) GetNoWriteMerge() bool { + if o == nil { + return false + } + return o.NoWriteMerge +} + +func (o *Options) GetOpenFilesCacher() Cacher { + if o == nil || o.OpenFilesCacher == nil { + return DefaultOpenFilesCacher + } + if o.OpenFilesCacher == NoCacher { + return nil + } + return o.OpenFilesCacher +} + +func (o *Options) GetOpenFilesCacheCapacity() int { + if o == nil || o.OpenFilesCacheCapacity == 0 { + return DefaultOpenFilesCacheCapacity + } else if o.OpenFilesCacheCapacity < 0 { + return 0 + } + return o.OpenFilesCacheCapacity +} + +func (o *Options) GetReadOnly() bool { + if o == nil { + return false + } + return o.ReadOnly +} + +func (o *Options) GetStrict(strict Strict) bool { + if o == nil || o.Strict == 0 { + return DefaultStrict&strict != 0 + } + return o.Strict&strict != 0 +} + +func (o *Options) GetWriteBuffer() int { + if o == nil || o.WriteBuffer <= 0 { + return DefaultWriteBuffer + } + return o.WriteBuffer +} + +func (o *Options) GetWriteL0PauseTrigger() int { + if o == nil || o.WriteL0PauseTrigger == 0 { + return DefaultWriteL0PauseTrigger + } + return o.WriteL0PauseTrigger +} + +func (o *Options) GetWriteL0SlowdownTrigger() int { + if o == nil || o.WriteL0SlowdownTrigger == 0 { + return DefaultWriteL0SlowdownTrigger + } + return o.WriteL0SlowdownTrigger +} + +// ReadOptions holds the optional parameters for 'read operation'. The +// 'read operation' includes Get, Find and NewIterator. +type ReadOptions struct { + // DontFillCache defines whether block reads for this 'read operation' + // should be cached. If false then the block will be cached. This does + // not affects already cached block. + // + // The default value is false. + DontFillCache bool + + // Strict will be OR'ed with global DB 'strict level' unless StrictOverride + // is present. Currently only StrictReader that has effect here. + Strict Strict +} + +func (ro *ReadOptions) GetDontFillCache() bool { + if ro == nil { + return false + } + return ro.DontFillCache +} + +func (ro *ReadOptions) GetStrict(strict Strict) bool { + if ro == nil { + return false + } + return ro.Strict&strict != 0 +} + +// WriteOptions holds the optional parameters for 'write operation'. The +// 'write operation' includes Write, Put and Delete. +type WriteOptions struct { + // NoWriteMerge allows disabling write merge. + // + // The default is false. + NoWriteMerge bool + + // Sync is whether to sync underlying writes from the OS buffer cache + // through to actual disk, if applicable. Setting Sync can result in + // slower writes. + // + // If false, and the machine crashes, then some recent writes may be lost. + // Note that if it is just the process that crashes (and the machine does + // not) then no writes will be lost. + // + // In other words, Sync being false has the same semantics as a write + // system call. Sync being true means write followed by fsync. + // + // The default value is false. + Sync bool +} + +func (wo *WriteOptions) GetNoWriteMerge() bool { + if wo == nil { + return false + } + return wo.NoWriteMerge +} + +func (wo *WriteOptions) GetSync() bool { + if wo == nil { + return false + } + return wo.Sync +} + +func GetStrict(o *Options, ro *ReadOptions, strict Strict) bool { + if ro.GetStrict(StrictOverride) { + return ro.GetStrict(strict) + } else { + return o.GetStrict(strict) || ro.GetStrict(strict) + } +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/session_util.go b/vendor/github.com/syndtr/goleveldb/leveldb/session_util.go new file mode 100644 index 00000000..40cb2cf9 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/session_util.go @@ -0,0 +1,271 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "fmt" + "sync/atomic" + + "github.com/syndtr/goleveldb/leveldb/journal" + "github.com/syndtr/goleveldb/leveldb/storage" +) + +// Logging. + +type dropper struct { + s *session + fd storage.FileDesc +} + +func (d dropper) Drop(err error) { + if e, ok := err.(*journal.ErrCorrupted); ok { + d.s.logf("journal@drop %s-%d S·%s %q", d.fd.Type, d.fd.Num, shortenb(e.Size), e.Reason) + } else { + d.s.logf("journal@drop %s-%d %q", d.fd.Type, d.fd.Num, err) + } +} + +func (s *session) log(v ...interface{}) { s.stor.Log(fmt.Sprint(v...)) } +func (s *session) logf(format string, v ...interface{}) { s.stor.Log(fmt.Sprintf(format, v...)) } + +// File utils. + +func (s *session) newTemp() storage.FileDesc { + num := atomic.AddInt64(&s.stTempFileNum, 1) - 1 + return storage.FileDesc{Type: storage.TypeTemp, Num: num} +} + +func (s *session) addFileRef(fd storage.FileDesc, ref int) int { + ref += s.fileRef[fd.Num] + if ref > 0 { + s.fileRef[fd.Num] = ref + } else if ref == 0 { + delete(s.fileRef, fd.Num) + } else { + panic(fmt.Sprintf("negative ref: %v", fd)) + } + return ref +} + +// Session state. + +// Get current version. This will incr version ref, must call +// version.release (exactly once) after use. +func (s *session) version() *version { + s.vmu.Lock() + defer s.vmu.Unlock() + s.stVersion.incref() + return s.stVersion +} + +func (s *session) tLen(level int) int { + s.vmu.Lock() + defer s.vmu.Unlock() + return s.stVersion.tLen(level) +} + +// Set current version to v. +func (s *session) setVersion(v *version) { + s.vmu.Lock() + defer s.vmu.Unlock() + // Hold by session. It is important to call this first before releasing + // current version, otherwise the still used files might get released. + v.incref() + if s.stVersion != nil { + // Release current version. + s.stVersion.releaseNB() + } + s.stVersion = v +} + +// Get current unused file number. +func (s *session) nextFileNum() int64 { + return atomic.LoadInt64(&s.stNextFileNum) +} + +// Set current unused file number to num. +func (s *session) setNextFileNum(num int64) { + atomic.StoreInt64(&s.stNextFileNum, num) +} + +// Mark file number as used. +func (s *session) markFileNum(num int64) { + nextFileNum := num + 1 + for { + old, x := s.stNextFileNum, nextFileNum + if old > x { + x = old + } + if atomic.CompareAndSwapInt64(&s.stNextFileNum, old, x) { + break + } + } +} + +// Allocate a file number. +func (s *session) allocFileNum() int64 { + return atomic.AddInt64(&s.stNextFileNum, 1) - 1 +} + +// Reuse given file number. +func (s *session) reuseFileNum(num int64) { + for { + old, x := s.stNextFileNum, num + if old != x+1 { + x = old + } + if atomic.CompareAndSwapInt64(&s.stNextFileNum, old, x) { + break + } + } +} + +// Set compaction ptr at given level; need external synchronization. +func (s *session) setCompPtr(level int, ik internalKey) { + if level >= len(s.stCompPtrs) { + newCompPtrs := make([]internalKey, level+1) + copy(newCompPtrs, s.stCompPtrs) + s.stCompPtrs = newCompPtrs + } + s.stCompPtrs[level] = append(internalKey{}, ik...) +} + +// Get compaction ptr at given level; need external synchronization. +func (s *session) getCompPtr(level int) internalKey { + if level >= len(s.stCompPtrs) { + return nil + } + return s.stCompPtrs[level] +} + +// Manifest related utils. + +// Fill given session record obj with current states; need external +// synchronization. +func (s *session) fillRecord(r *sessionRecord, snapshot bool) { + r.setNextFileNum(s.nextFileNum()) + + if snapshot { + if !r.has(recJournalNum) { + r.setJournalNum(s.stJournalNum) + } + + if !r.has(recSeqNum) { + r.setSeqNum(s.stSeqNum) + } + + for level, ik := range s.stCompPtrs { + if ik != nil { + r.addCompPtr(level, ik) + } + } + + r.setComparer(s.icmp.uName()) + } +} + +// Mark if record has been committed, this will update session state; +// need external synchronization. +func (s *session) recordCommited(rec *sessionRecord) { + if rec.has(recJournalNum) { + s.stJournalNum = rec.journalNum + } + + if rec.has(recPrevJournalNum) { + s.stPrevJournalNum = rec.prevJournalNum + } + + if rec.has(recSeqNum) { + s.stSeqNum = rec.seqNum + } + + for _, r := range rec.compPtrs { + s.setCompPtr(r.level, internalKey(r.ikey)) + } +} + +// Create a new manifest file; need external synchronization. +func (s *session) newManifest(rec *sessionRecord, v *version) (err error) { + fd := storage.FileDesc{Type: storage.TypeManifest, Num: s.allocFileNum()} + writer, err := s.stor.Create(fd) + if err != nil { + return + } + jw := journal.NewWriter(writer) + + if v == nil { + v = s.version() + defer v.release() + } + if rec == nil { + rec = &sessionRecord{} + } + s.fillRecord(rec, true) + v.fillRecord(rec) + + defer func() { + if err == nil { + s.recordCommited(rec) + if s.manifest != nil { + s.manifest.Close() + } + if s.manifestWriter != nil { + s.manifestWriter.Close() + } + if !s.manifestFd.Zero() { + s.stor.Remove(s.manifestFd) + } + s.manifestFd = fd + s.manifestWriter = writer + s.manifest = jw + } else { + writer.Close() + s.stor.Remove(fd) + s.reuseFileNum(fd.Num) + } + }() + + w, err := jw.Next() + if err != nil { + return + } + err = rec.encode(w) + if err != nil { + return + } + err = jw.Flush() + if err != nil { + return + } + err = s.stor.SetMeta(fd) + return +} + +// Flush record to disk. +func (s *session) flushManifest(rec *sessionRecord) (err error) { + s.fillRecord(rec, false) + w, err := s.manifest.Next() + if err != nil { + return + } + err = rec.encode(w) + if err != nil { + return + } + err = s.manifest.Flush() + if err != nil { + return + } + if !s.o.GetNoSync() { + err = s.manifestWriter.Sync() + if err != nil { + return + } + } + s.recordCommited(rec) + return +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/table.go b/vendor/github.com/syndtr/goleveldb/leveldb/table.go new file mode 100644 index 00000000..1fac60d0 --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/table.go @@ -0,0 +1,531 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "fmt" + "sort" + "sync/atomic" + + "github.com/syndtr/goleveldb/leveldb/cache" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/table" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// tFile holds basic information about a table. +type tFile struct { + fd storage.FileDesc + seekLeft int32 + size int64 + imin, imax internalKey +} + +// Returns true if given key is after largest key of this table. +func (t *tFile) after(icmp *iComparer, ukey []byte) bool { + return ukey != nil && icmp.uCompare(ukey, t.imax.ukey()) > 0 +} + +// Returns true if given key is before smallest key of this table. +func (t *tFile) before(icmp *iComparer, ukey []byte) bool { + return ukey != nil && icmp.uCompare(ukey, t.imin.ukey()) < 0 +} + +// Returns true if given key range overlaps with this table key range. +func (t *tFile) overlaps(icmp *iComparer, umin, umax []byte) bool { + return !t.after(icmp, umin) && !t.before(icmp, umax) +} + +// Cosumes one seek and return current seeks left. +func (t *tFile) consumeSeek() int32 { + return atomic.AddInt32(&t.seekLeft, -1) +} + +// Creates new tFile. +func newTableFile(fd storage.FileDesc, size int64, imin, imax internalKey) *tFile { + f := &tFile{ + fd: fd, + size: size, + imin: imin, + imax: imax, + } + + // We arrange to automatically compact this file after + // a certain number of seeks. Let's assume: + // (1) One seek costs 10ms + // (2) Writing or reading 1MB costs 10ms (100MB/s) + // (3) A compaction of 1MB does 25MB of IO: + // 1MB read from this level + // 10-12MB read from next level (boundaries may be misaligned) + // 10-12MB written to next level + // This implies that 25 seeks cost the same as the compaction + // of 1MB of data. I.e., one seek costs approximately the + // same as the compaction of 40KB of data. We are a little + // conservative and allow approximately one seek for every 16KB + // of data before triggering a compaction. + f.seekLeft = int32(size / 16384) + if f.seekLeft < 100 { + f.seekLeft = 100 + } + + return f +} + +func tableFileFromRecord(r atRecord) *tFile { + return newTableFile(storage.FileDesc{Type: storage.TypeTable, Num: r.num}, r.size, r.imin, r.imax) +} + +// tFiles hold multiple tFile. +type tFiles []*tFile + +func (tf tFiles) Len() int { return len(tf) } +func (tf tFiles) Swap(i, j int) { tf[i], tf[j] = tf[j], tf[i] } + +func (tf tFiles) nums() string { + x := "[ " + for i, f := range tf { + if i != 0 { + x += ", " + } + x += fmt.Sprint(f.fd.Num) + } + x += " ]" + return x +} + +// Returns true if i smallest key is less than j. +// This used for sort by key in ascending order. +func (tf tFiles) lessByKey(icmp *iComparer, i, j int) bool { + a, b := tf[i], tf[j] + n := icmp.Compare(a.imin, b.imin) + if n == 0 { + return a.fd.Num < b.fd.Num + } + return n < 0 +} + +// Returns true if i file number is greater than j. +// This used for sort by file number in descending order. +func (tf tFiles) lessByNum(i, j int) bool { + return tf[i].fd.Num > tf[j].fd.Num +} + +// Sorts tables by key in ascending order. +func (tf tFiles) sortByKey(icmp *iComparer) { + sort.Sort(&tFilesSortByKey{tFiles: tf, icmp: icmp}) +} + +// Sorts tables by file number in descending order. +func (tf tFiles) sortByNum() { + sort.Sort(&tFilesSortByNum{tFiles: tf}) +} + +// Returns sum of all tables size. +func (tf tFiles) size() (sum int64) { + for _, t := range tf { + sum += t.size + } + return sum +} + +// Searches smallest index of tables whose its smallest +// key is after or equal with given key. +func (tf tFiles) searchMin(icmp *iComparer, ikey internalKey) int { + return sort.Search(len(tf), func(i int) bool { + return icmp.Compare(tf[i].imin, ikey) >= 0 + }) +} + +// Searches smallest index of tables whose its largest +// key is after or equal with given key. +func (tf tFiles) searchMax(icmp *iComparer, ikey internalKey) int { + return sort.Search(len(tf), func(i int) bool { + return icmp.Compare(tf[i].imax, ikey) >= 0 + }) +} + +// Returns true if given key range overlaps with one or more +// tables key range. If unsorted is true then binary search will not be used. +func (tf tFiles) overlaps(icmp *iComparer, umin, umax []byte, unsorted bool) bool { + if unsorted { + // Check against all files. + for _, t := range tf { + if t.overlaps(icmp, umin, umax) { + return true + } + } + return false + } + + i := 0 + if len(umin) > 0 { + // Find the earliest possible internal key for min. + i = tf.searchMax(icmp, makeInternalKey(nil, umin, keyMaxSeq, keyTypeSeek)) + } + if i >= len(tf) { + // Beginning of range is after all files, so no overlap. + return false + } + return !tf[i].before(icmp, umax) +} + +// Returns tables whose its key range overlaps with given key range. +// Range will be expanded if ukey found hop across tables. +// If overlapped is true then the search will be restarted if umax +// expanded. +// The dst content will be overwritten. +func (tf tFiles) getOverlaps(dst tFiles, icmp *iComparer, umin, umax []byte, overlapped bool) tFiles { + dst = dst[:0] + for i := 0; i < len(tf); { + t := tf[i] + if t.overlaps(icmp, umin, umax) { + if umin != nil && icmp.uCompare(t.imin.ukey(), umin) < 0 { + umin = t.imin.ukey() + dst = dst[:0] + i = 0 + continue + } else if umax != nil && icmp.uCompare(t.imax.ukey(), umax) > 0 { + umax = t.imax.ukey() + // Restart search if it is overlapped. + if overlapped { + dst = dst[:0] + i = 0 + continue + } + } + + dst = append(dst, t) + } + i++ + } + + return dst +} + +// Returns tables key range. +func (tf tFiles) getRange(icmp *iComparer) (imin, imax internalKey) { + for i, t := range tf { + if i == 0 { + imin, imax = t.imin, t.imax + continue + } + if icmp.Compare(t.imin, imin) < 0 { + imin = t.imin + } + if icmp.Compare(t.imax, imax) > 0 { + imax = t.imax + } + } + + return +} + +// Creates iterator index from tables. +func (tf tFiles) newIndexIterator(tops *tOps, icmp *iComparer, slice *util.Range, ro *opt.ReadOptions) iterator.IteratorIndexer { + if slice != nil { + var start, limit int + if slice.Start != nil { + start = tf.searchMax(icmp, internalKey(slice.Start)) + } + if slice.Limit != nil { + limit = tf.searchMin(icmp, internalKey(slice.Limit)) + } else { + limit = tf.Len() + } + tf = tf[start:limit] + } + return iterator.NewArrayIndexer(&tFilesArrayIndexer{ + tFiles: tf, + tops: tops, + icmp: icmp, + slice: slice, + ro: ro, + }) +} + +// Tables iterator index. +type tFilesArrayIndexer struct { + tFiles + tops *tOps + icmp *iComparer + slice *util.Range + ro *opt.ReadOptions +} + +func (a *tFilesArrayIndexer) Search(key []byte) int { + return a.searchMax(a.icmp, internalKey(key)) +} + +func (a *tFilesArrayIndexer) Get(i int) iterator.Iterator { + if i == 0 || i == a.Len()-1 { + return a.tops.newIterator(a.tFiles[i], a.slice, a.ro) + } + return a.tops.newIterator(a.tFiles[i], nil, a.ro) +} + +// Helper type for sortByKey. +type tFilesSortByKey struct { + tFiles + icmp *iComparer +} + +func (x *tFilesSortByKey) Less(i, j int) bool { + return x.lessByKey(x.icmp, i, j) +} + +// Helper type for sortByNum. +type tFilesSortByNum struct { + tFiles +} + +func (x *tFilesSortByNum) Less(i, j int) bool { + return x.lessByNum(i, j) +} + +// Table operations. +type tOps struct { + s *session + noSync bool + evictRemoved bool + cache *cache.Cache + bcache *cache.Cache + bpool *util.BufferPool +} + +// Creates an empty table and returns table writer. +func (t *tOps) create() (*tWriter, error) { + fd := storage.FileDesc{Type: storage.TypeTable, Num: t.s.allocFileNum()} + fw, err := t.s.stor.Create(fd) + if err != nil { + return nil, err + } + return &tWriter{ + t: t, + fd: fd, + w: fw, + tw: table.NewWriter(fw, t.s.o.Options), + }, nil +} + +// Builds table from src iterator. +func (t *tOps) createFrom(src iterator.Iterator) (f *tFile, n int, err error) { + w, err := t.create() + if err != nil { + return + } + + defer func() { + if err != nil { + w.drop() + } + }() + + for src.Next() { + err = w.append(src.Key(), src.Value()) + if err != nil { + return + } + } + err = src.Error() + if err != nil { + return + } + + n = w.tw.EntriesLen() + f, err = w.finish() + return +} + +// Opens table. It returns a cache handle, which should +// be released after use. +func (t *tOps) open(f *tFile) (ch *cache.Handle, err error) { + ch = t.cache.Get(0, uint64(f.fd.Num), func() (size int, value cache.Value) { + var r storage.Reader + r, err = t.s.stor.Open(f.fd) + if err != nil { + return 0, nil + } + + var bcache *cache.NamespaceGetter + if t.bcache != nil { + bcache = &cache.NamespaceGetter{Cache: t.bcache, NS: uint64(f.fd.Num)} + } + + var tr *table.Reader + tr, err = table.NewReader(r, f.size, f.fd, bcache, t.bpool, t.s.o.Options) + if err != nil { + r.Close() + return 0, nil + } + return 1, tr + + }) + if ch == nil && err == nil { + err = ErrClosed + } + return +} + +// Finds key/value pair whose key is greater than or equal to the +// given key. +func (t *tOps) find(f *tFile, key []byte, ro *opt.ReadOptions) (rkey, rvalue []byte, err error) { + ch, err := t.open(f) + if err != nil { + return nil, nil, err + } + defer ch.Release() + return ch.Value().(*table.Reader).Find(key, true, ro) +} + +// Finds key that is greater than or equal to the given key. +func (t *tOps) findKey(f *tFile, key []byte, ro *opt.ReadOptions) (rkey []byte, err error) { + ch, err := t.open(f) + if err != nil { + return nil, err + } + defer ch.Release() + return ch.Value().(*table.Reader).FindKey(key, true, ro) +} + +// Returns approximate offset of the given key. +func (t *tOps) offsetOf(f *tFile, key []byte) (offset int64, err error) { + ch, err := t.open(f) + if err != nil { + return + } + defer ch.Release() + return ch.Value().(*table.Reader).OffsetOf(key) +} + +// Creates an iterator from the given table. +func (t *tOps) newIterator(f *tFile, slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { + ch, err := t.open(f) + if err != nil { + return iterator.NewEmptyIterator(err) + } + iter := ch.Value().(*table.Reader).NewIterator(slice, ro) + iter.SetReleaser(ch) + return iter +} + +// Removes table from persistent storage. It waits until +// no one use the the table. +func (t *tOps) remove(f *tFile) { + t.cache.Delete(0, uint64(f.fd.Num), func() { + if err := t.s.stor.Remove(f.fd); err != nil { + t.s.logf("table@remove removing @%d %q", f.fd.Num, err) + } else { + t.s.logf("table@remove removed @%d", f.fd.Num) + } + if t.evictRemoved && t.bcache != nil { + t.bcache.EvictNS(uint64(f.fd.Num)) + } + }) +} + +// Closes the table ops instance. It will close all tables, +// regadless still used or not. +func (t *tOps) close() { + t.bpool.Close() + t.cache.Close() + if t.bcache != nil { + t.bcache.CloseWeak() + } +} + +// Creates new initialized table ops instance. +func newTableOps(s *session) *tOps { + var ( + cacher cache.Cacher + bcache *cache.Cache + bpool *util.BufferPool + ) + if s.o.GetOpenFilesCacheCapacity() > 0 { + cacher = cache.NewLRU(s.o.GetOpenFilesCacheCapacity()) + } + if !s.o.GetDisableBlockCache() { + var bcacher cache.Cacher + if s.o.GetBlockCacheCapacity() > 0 { + bcacher = s.o.GetBlockCacher().New(s.o.GetBlockCacheCapacity()) + } + bcache = cache.NewCache(bcacher) + } + if !s.o.GetDisableBufferPool() { + bpool = util.NewBufferPool(s.o.GetBlockSize() + 5) + } + return &tOps{ + s: s, + noSync: s.o.GetNoSync(), + evictRemoved: s.o.GetBlockCacheEvictRemoved(), + cache: cache.NewCache(cacher), + bcache: bcache, + bpool: bpool, + } +} + +// tWriter wraps the table writer. It keep track of file descriptor +// and added key range. +type tWriter struct { + t *tOps + + fd storage.FileDesc + w storage.Writer + tw *table.Writer + + first, last []byte +} + +// Append key/value pair to the table. +func (w *tWriter) append(key, value []byte) error { + if w.first == nil { + w.first = append([]byte{}, key...) + } + w.last = append(w.last[:0], key...) + return w.tw.Append(key, value) +} + +// Returns true if the table is empty. +func (w *tWriter) empty() bool { + return w.first == nil +} + +// Closes the storage.Writer. +func (w *tWriter) close() { + if w.w != nil { + w.w.Close() + w.w = nil + } +} + +// Finalizes the table and returns table file. +func (w *tWriter) finish() (f *tFile, err error) { + defer w.close() + err = w.tw.Close() + if err != nil { + return + } + if !w.t.noSync { + err = w.w.Sync() + if err != nil { + return + } + } + f = newTableFile(w.fd, int64(w.tw.BytesLen()), internalKey(w.first), internalKey(w.last)) + return +} + +// Drops the table. +func (w *tWriter) drop() { + w.close() + w.t.s.stor.Remove(w.fd) + w.t.s.reuseFileNum(w.fd.Num) + w.tw = nil + w.first = nil + w.last = nil +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go b/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go new file mode 100644 index 00000000..496feb6f --- /dev/null +++ b/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go @@ -0,0 +1,1139 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package table + +import ( + "encoding/binary" + "fmt" + "io" + "sort" + "strings" + "sync" + + "github.com/golang/snappy" + + "github.com/syndtr/goleveldb/leveldb/cache" + "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/util" +) + +// Reader errors. +var ( + ErrNotFound = errors.ErrNotFound + ErrReaderReleased = errors.New("leveldb/table: reader released") + ErrIterReleased = errors.New("leveldb/table: iterator released") +) + +// ErrCorrupted describes error due to corruption. This error will be wrapped +// with errors.ErrCorrupted. +type ErrCorrupted struct { + Pos int64 + Size int64 + Kind string + Reason string +} + +func (e *ErrCorrupted) Error() string { + return fmt.Sprintf("leveldb/table: corruption on %s (pos=%d): %s", e.Kind, e.Pos, e.Reason) +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} + +type block struct { + bpool *util.BufferPool + bh blockHandle + data []byte + restartsLen int + restartsOffset int +} + +func (b *block) seek(cmp comparer.Comparer, rstart, rlimit int, key []byte) (index, offset int, err error) { + index = sort.Search(b.restartsLen-rstart-(b.restartsLen-rlimit), func(i int) bool { + offset := int(binary.LittleEndian.Uint32(b.data[b.restartsOffset+4*(rstart+i):])) + offset++ // shared always zero, since this is a restart point + v1, n1 := binary.Uvarint(b.data[offset:]) // key length + _, n2 := binary.Uvarint(b.data[offset+n1:]) // value length + m := offset + n1 + n2 + return cmp.Compare(b.data[m:m+int(v1)], key) > 0 + }) + rstart - 1 + if index < rstart { + // The smallest key is greater-than key sought. + index = rstart + } + offset = int(binary.LittleEndian.Uint32(b.data[b.restartsOffset+4*index:])) + return +} + +func (b *block) restartIndex(rstart, rlimit, offset int) int { + return sort.Search(b.restartsLen-rstart-(b.restartsLen-rlimit), func(i int) bool { + return int(binary.LittleEndian.Uint32(b.data[b.restartsOffset+4*(rstart+i):])) > offset + }) + rstart - 1 +} + +func (b *block) restartOffset(index int) int { + return int(binary.LittleEndian.Uint32(b.data[b.restartsOffset+4*index:])) +} + +func (b *block) entry(offset int) (key, value []byte, nShared, n int, err error) { + if offset >= b.restartsOffset { + if offset != b.restartsOffset { + err = &ErrCorrupted{Reason: "entries offset not aligned"} + } + return + } + v0, n0 := binary.Uvarint(b.data[offset:]) // Shared prefix length + v1, n1 := binary.Uvarint(b.data[offset+n0:]) // Key length + v2, n2 := binary.Uvarint(b.data[offset+n0+n1:]) // Value length + m := n0 + n1 + n2 + n = m + int(v1) + int(v2) + if n0 <= 0 || n1 <= 0 || n2 <= 0 || offset+n > b.restartsOffset { + err = &ErrCorrupted{Reason: "entries corrupted"} + return + } + key = b.data[offset+m : offset+m+int(v1)] + value = b.data[offset+m+int(v1) : offset+n] + nShared = int(v0) + return +} + +func (b *block) Release() { + b.bpool.Put(b.data) + b.bpool = nil + b.data = nil +} + +type dir int + +const ( + dirReleased dir = iota - 1 + dirSOI + dirEOI + dirBackward + dirForward +) + +type blockIter struct { + tr *Reader + block *block + blockReleaser util.Releaser + releaser util.Releaser + key, value []byte + offset int + // Previous offset, only filled by Next. + prevOffset int + prevNode []int + prevKeys []byte + restartIndex int + // Iterator direction. + dir dir + // Restart index slice range. + riStart int + riLimit int + // Offset slice range. + offsetStart int + offsetRealStart int + offsetLimit int + // Error. + err error +} + +func (i *blockIter) sErr(err error) { + i.err = err + i.key = nil + i.value = nil + i.prevNode = nil + i.prevKeys = nil +} + +func (i *blockIter) reset() { + if i.dir == dirBackward { + i.prevNode = i.prevNode[:0] + i.prevKeys = i.prevKeys[:0] + } + i.restartIndex = i.riStart + i.offset = i.offsetStart + i.dir = dirSOI + i.key = i.key[:0] + i.value = nil +} + +func (i *blockIter) isFirst() bool { + switch i.dir { + case dirForward: + return i.prevOffset == i.offsetRealStart + case dirBackward: + return len(i.prevNode) == 1 && i.restartIndex == i.riStart + } + return false +} + +func (i *blockIter) isLast() bool { + switch i.dir { + case dirForward, dirBackward: + return i.offset == i.offsetLimit + } + return false +} + +func (i *blockIter) First() bool { + if i.err != nil { + return false + } else if i.dir == dirReleased { + i.err = ErrIterReleased + return false + } + + if i.dir == dirBackward { + i.prevNode = i.prevNode[:0] + i.prevKeys = i.prevKeys[:0] + } + i.dir = dirSOI + return i.Next() +} + +func (i *blockIter) Last() bool { + if i.err != nil { + return false + } else if i.dir == dirReleased { + i.err = ErrIterReleased + return false + } + + if i.dir == dirBackward { + i.prevNode = i.prevNode[:0] + i.prevKeys = i.prevKeys[:0] + } + i.dir = dirEOI + return i.Prev() +} + +func (i *blockIter) Seek(key []byte) bool { + if i.err != nil { + return false + } else if i.dir == dirReleased { + i.err = ErrIterReleased + return false + } + + ri, offset, err := i.block.seek(i.tr.cmp, i.riStart, i.riLimit, key) + if err != nil { + i.sErr(err) + return false + } + i.restartIndex = ri + i.offset = max(i.offsetStart, offset) + if i.dir == dirSOI || i.dir == dirEOI { + i.dir = dirForward + } + for i.Next() { + if i.tr.cmp.Compare(i.key, key) >= 0 { + return true + } + } + return false +} + +func (i *blockIter) Next() bool { + if i.dir == dirEOI || i.err != nil { + return false + } else if i.dir == dirReleased { + i.err = ErrIterReleased + return false + } + + if i.dir == dirSOI { + i.restartIndex = i.riStart + i.offset = i.offsetStart + } else if i.dir == dirBackward { + i.prevNode = i.prevNode[:0] + i.prevKeys = i.prevKeys[:0] + } + for i.offset < i.offsetRealStart { + key, value, nShared, n, err := i.block.entry(i.offset) + if err != nil { + i.sErr(i.tr.fixErrCorruptedBH(i.block.bh, err)) + return false + } + if n == 0 { + i.dir = dirEOI + return false + } + i.key = append(i.key[:nShared], key...) + i.value = value + i.offset += n + } + if i.offset >= i.offsetLimit { + i.dir = dirEOI + if i.offset != i.offsetLimit { + i.sErr(i.tr.newErrCorruptedBH(i.block.bh, "entries offset not aligned")) + } + return false + } + key, value, nShared, n, err := i.block.entry(i.offset) + if err != nil { + i.sErr(i.tr.fixErrCorruptedBH(i.block.bh, err)) + return false + } + if n == 0 { + i.dir = dirEOI + return false + } + i.key = append(i.key[:nShared], key...) + i.value = value + i.prevOffset = i.offset + i.offset += n + i.dir = dirForward + return true +} + +func (i *blockIter) Prev() bool { + if i.dir == dirSOI || i.err != nil { + return false + } else if i.dir == dirReleased { + i.err = ErrIterReleased + return false + } + + var ri int + if i.dir == dirForward { + // Change direction. + i.offset = i.prevOffset + if i.offset == i.offsetRealStart { + i.dir = dirSOI + return false + } + ri = i.block.restartIndex(i.restartIndex, i.riLimit, i.offset) + i.dir = dirBackward + } else if i.dir == dirEOI { + // At the end of iterator. + i.restartIndex = i.riLimit + i.offset = i.offsetLimit + if i.offset == i.offsetRealStart { + i.dir = dirSOI + return false + } + ri = i.riLimit - 1 + i.dir = dirBackward + } else if len(i.prevNode) == 1 { + // This is the end of a restart range. + i.offset = i.prevNode[0] + i.prevNode = i.prevNode[:0] + if i.restartIndex == i.riStart { + i.dir = dirSOI + return false + } + i.restartIndex-- + ri = i.restartIndex + } else { + // In the middle of restart range, get from cache. + n := len(i.prevNode) - 3 + node := i.prevNode[n:] + i.prevNode = i.prevNode[:n] + // Get the key. + ko := node[0] + i.key = append(i.key[:0], i.prevKeys[ko:]...) + i.prevKeys = i.prevKeys[:ko] + // Get the value. + vo := node[1] + vl := vo + node[2] + i.value = i.block.data[vo:vl] + i.offset = vl + return true + } + // Build entries cache. + i.key = i.key[:0] + i.value = nil + offset := i.block.restartOffset(ri) + if offset == i.offset { + ri-- + if ri < 0 { + i.dir = dirSOI + return false + } + offset = i.block.restartOffset(ri) + } + i.prevNode = append(i.prevNode, offset) + for { + key, value, nShared, n, err := i.block.entry(offset) + if err != nil { + i.sErr(i.tr.fixErrCorruptedBH(i.block.bh, err)) + return false + } + if offset >= i.offsetRealStart { + if i.value != nil { + // Appends 3 variables: + // 1. Previous keys offset + // 2. Value offset in the data block + // 3. Value length + i.prevNode = append(i.prevNode, len(i.prevKeys), offset-len(i.value), len(i.value)) + i.prevKeys = append(i.prevKeys, i.key...) + } + i.value = value + } + i.key = append(i.key[:nShared], key...) + offset += n + // Stop if target offset reached. + if offset >= i.offset { + if offset != i.offset { + i.sErr(i.tr.newErrCorruptedBH(i.block.bh, "entries offset not aligned")) + return false + } + + break + } + } + i.restartIndex = ri + i.offset = offset + return true +} + +func (i *blockIter) Key() []byte { + if i.err != nil || i.dir <= dirEOI { + return nil + } + return i.key +} + +func (i *blockIter) Value() []byte { + if i.err != nil || i.dir <= dirEOI { + return nil + } + return i.value +} + +func (i *blockIter) Release() { + if i.dir != dirReleased { + i.tr = nil + i.block = nil + i.prevNode = nil + i.prevKeys = nil + i.key = nil + i.value = nil + i.dir = dirReleased + if i.blockReleaser != nil { + i.blockReleaser.Release() + i.blockReleaser = nil + } + if i.releaser != nil { + i.releaser.Release() + i.releaser = nil + } + } +} + +func (i *blockIter) SetReleaser(releaser util.Releaser) { + if i.dir == dirReleased { + panic(util.ErrReleased) + } + if i.releaser != nil && releaser != nil { + panic(util.ErrHasReleaser) + } + i.releaser = releaser +} + +func (i *blockIter) Valid() bool { + return i.err == nil && (i.dir == dirBackward || i.dir == dirForward) +} + +func (i *blockIter) Error() error { + return i.err +} + +type filterBlock struct { + bpool *util.BufferPool + data []byte + oOffset int + baseLg uint + filtersNum int +} + +func (b *filterBlock) contains(filter filter.Filter, offset uint64, key []byte) bool { + i := int(offset >> b.baseLg) + if i < b.filtersNum { + o := b.data[b.oOffset+i*4:] + n := int(binary.LittleEndian.Uint32(o)) + m := int(binary.LittleEndian.Uint32(o[4:])) + if n < m && m <= b.oOffset { + return filter.Contains(b.data[n:m], key) + } else if n == m { + return false + } + } + return true +} + +func (b *filterBlock) Release() { + b.bpool.Put(b.data) + b.bpool = nil + b.data = nil +} + +type indexIter struct { + *blockIter + tr *Reader + slice *util.Range + // Options + fillCache bool +} + +func (i *indexIter) Get() iterator.Iterator { + value := i.Value() + if value == nil { + return nil + } + dataBH, n := decodeBlockHandle(value) + if n == 0 { + return iterator.NewEmptyIterator(i.tr.newErrCorruptedBH(i.tr.indexBH, "bad data block handle")) + } + + var slice *util.Range + if i.slice != nil && (i.blockIter.isFirst() || i.blockIter.isLast()) { + slice = i.slice + } + return i.tr.getDataIterErr(dataBH, slice, i.tr.verifyChecksum, i.fillCache) +} + +// Reader is a table reader. +type Reader struct { + mu sync.RWMutex + fd storage.FileDesc + reader io.ReaderAt + cache *cache.NamespaceGetter + err error + bpool *util.BufferPool + // Options + o *opt.Options + cmp comparer.Comparer + filter filter.Filter + verifyChecksum bool + + dataEnd int64 + metaBH, indexBH, filterBH blockHandle + indexBlock *block + filterBlock *filterBlock +} + +func (r *Reader) blockKind(bh blockHandle) string { + switch bh.offset { + case r.metaBH.offset: + return "meta-block" + case r.indexBH.offset: + return "index-block" + case r.filterBH.offset: + if r.filterBH.length > 0 { + return "filter-block" + } + } + return "data-block" +} + +func (r *Reader) newErrCorrupted(pos, size int64, kind, reason string) error { + return &errors.ErrCorrupted{Fd: r.fd, Err: &ErrCorrupted{Pos: pos, Size: size, Kind: kind, Reason: reason}} +} + +func (r *Reader) newErrCorruptedBH(bh blockHandle, reason string) error { + return r.newErrCorrupted(int64(bh.offset), int64(bh.length), r.blockKind(bh), reason) +} + +func (r *Reader) fixErrCorruptedBH(bh blockHandle, err error) error { + if cerr, ok := err.(*ErrCorrupted); ok { + cerr.Pos = int64(bh.offset) + cerr.Size = int64(bh.length) + cerr.Kind = r.blockKind(bh) + return &errors.ErrCorrupted{Fd: r.fd, Err: cerr} + } + return err +} + +func (r *Reader) readRawBlock(bh blockHandle, verifyChecksum bool) ([]byte, error) { + data := r.bpool.Get(int(bh.length + blockTrailerLen)) + if _, err := r.reader.ReadAt(data, int64(bh.offset)); err != nil && err != io.EOF { + return nil, err + } + + if verifyChecksum { + n := bh.length + 1 + checksum0 := binary.LittleEndian.Uint32(data[n:]) + checksum1 := util.NewCRC(data[:n]).Value() + if checksum0 != checksum1 { + r.bpool.Put(data) + return nil, r.newErrCorruptedBH(bh, fmt.Sprintf("checksum mismatch, want=%#x got=%#x", checksum0, checksum1)) + } + } + + switch data[bh.length] { + case blockTypeNoCompression: + data = data[:bh.length] + case blockTypeSnappyCompression: + decLen, err := snappy.DecodedLen(data[:bh.length]) + if err != nil { + r.bpool.Put(data) + return nil, r.newErrCorruptedBH(bh, err.Error()) + } + decData := r.bpool.Get(decLen) + decData, err = snappy.Decode(decData, data[:bh.length]) + r.bpool.Put(data) + if err != nil { + r.bpool.Put(decData) + return nil, r.newErrCorruptedBH(bh, err.Error()) + } + data = decData + default: + r.bpool.Put(data) + return nil, r.newErrCorruptedBH(bh, fmt.Sprintf("unknown compression type %#x", data[bh.length])) + } + return data, nil +} + +func (r *Reader) readBlock(bh blockHandle, verifyChecksum bool) (*block, error) { + data, err := r.readRawBlock(bh, verifyChecksum) + if err != nil { + return nil, err + } + restartsLen := int(binary.LittleEndian.Uint32(data[len(data)-4:])) + b := &block{ + bpool: r.bpool, + bh: bh, + data: data, + restartsLen: restartsLen, + restartsOffset: len(data) - (restartsLen+1)*4, + } + return b, nil +} + +func (r *Reader) readBlockCached(bh blockHandle, verifyChecksum, fillCache bool) (*block, util.Releaser, error) { + if r.cache != nil { + var ( + err error + ch *cache.Handle + ) + if fillCache { + ch = r.cache.Get(bh.offset, func() (size int, value cache.Value) { + var b *block + b, err = r.readBlock(bh, verifyChecksum) + if err != nil { + return 0, nil + } + return cap(b.data), b + }) + } else { + ch = r.cache.Get(bh.offset, nil) + } + if ch != nil { + b, ok := ch.Value().(*block) + if !ok { + ch.Release() + return nil, nil, errors.New("leveldb/table: inconsistent block type") + } + return b, ch, err + } else if err != nil { + return nil, nil, err + } + } + + b, err := r.readBlock(bh, verifyChecksum) + return b, b, err +} + +func (r *Reader) readFilterBlock(bh blockHandle) (*filterBlock, error) { + data, err := r.readRawBlock(bh, true) + if err != nil { + return nil, err + } + n := len(data) + if n < 5 { + return nil, r.newErrCorruptedBH(bh, "too short") + } + m := n - 5 + oOffset := int(binary.LittleEndian.Uint32(data[m:])) + if oOffset > m { + return nil, r.newErrCorruptedBH(bh, "invalid data-offsets offset") + } + b := &filterBlock{ + bpool: r.bpool, + data: data, + oOffset: oOffset, + baseLg: uint(data[n-1]), + filtersNum: (m - oOffset) / 4, + } + return b, nil +} + +func (r *Reader) readFilterBlockCached(bh blockHandle, fillCache bool) (*filterBlock, util.Releaser, error) { + if r.cache != nil { + var ( + err error + ch *cache.Handle + ) + if fillCache { + ch = r.cache.Get(bh.offset, func() (size int, value cache.Value) { + var b *filterBlock + b, err = r.readFilterBlock(bh) + if err != nil { + return 0, nil + } + return cap(b.data), b + }) + } else { + ch = r.cache.Get(bh.offset, nil) + } + if ch != nil { + b, ok := ch.Value().(*filterBlock) + if !ok { + ch.Release() + return nil, nil, errors.New("leveldb/table: inconsistent block type") + } + return b, ch, err + } else if err != nil { + return nil, nil, err + } + } + + b, err := r.readFilterBlock(bh) + return b, b, err +} + +func (r *Reader) getIndexBlock(fillCache bool) (b *block, rel util.Releaser, err error) { + if r.indexBlock == nil { + return r.readBlockCached(r.indexBH, true, fillCache) + } + return r.indexBlock, util.NoopReleaser{}, nil +} + +func (r *Reader) getFilterBlock(fillCache bool) (*filterBlock, util.Releaser, error) { + if r.filterBlock == nil { + return r.readFilterBlockCached(r.filterBH, fillCache) + } + return r.filterBlock, util.NoopReleaser{}, nil +} + +func (r *Reader) newBlockIter(b *block, bReleaser util.Releaser, slice *util.Range, inclLimit bool) *blockIter { + bi := &blockIter{ + tr: r, + block: b, + blockReleaser: bReleaser, + // Valid key should never be nil. + key: make([]byte, 0), + dir: dirSOI, + riStart: 0, + riLimit: b.restartsLen, + offsetStart: 0, + offsetRealStart: 0, + offsetLimit: b.restartsOffset, + } + if slice != nil { + if slice.Start != nil { + if bi.Seek(slice.Start) { + bi.riStart = b.restartIndex(bi.restartIndex, b.restartsLen, bi.prevOffset) + bi.offsetStart = b.restartOffset(bi.riStart) + bi.offsetRealStart = bi.prevOffset + } else { + bi.riStart = b.restartsLen + bi.offsetStart = b.restartsOffset + bi.offsetRealStart = b.restartsOffset + } + } + if slice.Limit != nil { + if bi.Seek(slice.Limit) && (!inclLimit || bi.Next()) { + bi.offsetLimit = bi.prevOffset + bi.riLimit = bi.restartIndex + 1 + } + } + bi.reset() + if bi.offsetStart > bi.offsetLimit { + bi.sErr(errors.New("leveldb/table: invalid slice range")) + } + } + return bi +} + +func (r *Reader) getDataIter(dataBH blockHandle, slice *util.Range, verifyChecksum, fillCache bool) iterator.Iterator { + b, rel, err := r.readBlockCached(dataBH, verifyChecksum, fillCache) + if err != nil { + return iterator.NewEmptyIterator(err) + } + return r.newBlockIter(b, rel, slice, false) +} + +func (r *Reader) getDataIterErr(dataBH blockHandle, slice *util.Range, verifyChecksum, fillCache bool) iterator.Iterator { + r.mu.RLock() + defer r.mu.RUnlock() + + if r.err != nil { + return iterator.NewEmptyIterator(r.err) + } + + return r.getDataIter(dataBH, slice, verifyChecksum, fillCache) +} + +// NewIterator creates an iterator from the table. +// +// Slice allows slicing the iterator to only contains keys in the given +// range. A nil Range.Start is treated as a key before all keys in the +// table. And a nil Range.Limit is treated as a key after all keys in +// the table. +// +// WARNING: Any slice returned by interator (e.g. slice returned by calling +// Iterator.Key() or Iterator.Key() methods), its content should not be modified +// unless noted otherwise. +// +// The returned iterator is not safe for concurrent use and should be released +// after use. +// +// Also read Iterator documentation of the leveldb/iterator package. +func (r *Reader) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { + r.mu.RLock() + defer r.mu.RUnlock() + + if r.err != nil { + return iterator.NewEmptyIterator(r.err) + } + + fillCache := !ro.GetDontFillCache() + indexBlock, rel, err := r.getIndexBlock(fillCache) + if err != nil { + return iterator.NewEmptyIterator(err) + } + index := &indexIter{ + blockIter: r.newBlockIter(indexBlock, rel, slice, true), + tr: r, + slice: slice, + fillCache: !ro.GetDontFillCache(), + } + return iterator.NewIndexedIterator(index, opt.GetStrict(r.o, ro, opt.StrictReader)) +} + +func (r *Reader) find(key []byte, filtered bool, ro *opt.ReadOptions, noValue bool) (rkey, value []byte, err error) { + r.mu.RLock() + defer r.mu.RUnlock() + + if r.err != nil { + err = r.err + return + } + + indexBlock, rel, err := r.getIndexBlock(true) + if err != nil { + return + } + defer rel.Release() + + index := r.newBlockIter(indexBlock, nil, nil, true) + defer index.Release() + + if !index.Seek(key) { + if err = index.Error(); err == nil { + err = ErrNotFound + } + return + } + + dataBH, n := decodeBlockHandle(index.Value()) + if n == 0 { + r.err = r.newErrCorruptedBH(r.indexBH, "bad data block handle") + return nil, nil, r.err + } + + // The filter should only used for exact match. + if filtered && r.filter != nil { + filterBlock, frel, ferr := r.getFilterBlock(true) + if ferr == nil { + if !filterBlock.contains(r.filter, dataBH.offset, key) { + frel.Release() + return nil, nil, ErrNotFound + } + frel.Release() + } else if !errors.IsCorrupted(ferr) { + return nil, nil, ferr + } + } + + data := r.getDataIter(dataBH, nil, r.verifyChecksum, !ro.GetDontFillCache()) + if !data.Seek(key) { + data.Release() + if err = data.Error(); err != nil { + return + } + + // The nearest greater-than key is the first key of the next block. + if !index.Next() { + if err = index.Error(); err == nil { + err = ErrNotFound + } + return + } + + dataBH, n = decodeBlockHandle(index.Value()) + if n == 0 { + r.err = r.newErrCorruptedBH(r.indexBH, "bad data block handle") + return nil, nil, r.err + } + + data = r.getDataIter(dataBH, nil, r.verifyChecksum, !ro.GetDontFillCache()) + if !data.Next() { + data.Release() + if err = data.Error(); err == nil { + err = ErrNotFound + } + return + } + } + + // Key doesn't use block buffer, no need to copy the buffer. + rkey = data.Key() + if !noValue { + if r.bpool == nil { + value = data.Value() + } else { + // Value does use block buffer, and since the buffer will be + // recycled, it need to be copied. + value = append([]byte{}, data.Value()...) + } + } + data.Release() + return +} + +// Find finds key/value pair whose key is greater than or equal to the +// given key. It returns ErrNotFound if the table doesn't contain +// such pair. +// If filtered is true then the nearest 'block' will be checked against +// 'filter data' (if present) and will immediately return ErrNotFound if +// 'filter data' indicates that such pair doesn't exist. +// +// The caller may modify the contents of the returned slice as it is its +// own copy. +// It is safe to modify the contents of the argument after Find returns. +func (r *Reader) Find(key []byte, filtered bool, ro *opt.ReadOptions) (rkey, value []byte, err error) { + return r.find(key, filtered, ro, false) +} + +// FindKey finds key that is greater than or equal to the given key. +// It returns ErrNotFound if the table doesn't contain such key. +// If filtered is true then the nearest 'block' will be checked against +// 'filter data' (if present) and will immediately return ErrNotFound if +// 'filter data' indicates that such key doesn't exist. +// +// The caller may modify the contents of the returned slice as it is its +// own copy. +// It is safe to modify the contents of the argument after Find returns. +func (r *Reader) FindKey(key []byte, filtered bool, ro *opt.ReadOptions) (rkey []byte, err error) { + rkey, _, err = r.find(key, filtered, ro, true) + return +} + +// Get gets the value for the given key. It returns errors.ErrNotFound +// if the table does not contain the key. +// +// The caller may modify the contents of the returned slice as it is its +// own copy. +// It is safe to modify the contents of the argument after Find returns. +func (r *Reader) Get(key []byte, ro *opt.ReadOptions) (value []byte, err error) { + r.mu.RLock() + defer r.mu.RUnlock() + + if r.err != nil { + err = r.err + return + } + + rkey, value, err := r.find(key, false, ro, false) + if err == nil && r.cmp.Compare(rkey, key) != 0 { + value = nil + err = ErrNotFound + } + return +} + +// OffsetOf returns approximate offset for the given key. +// +// It is safe to modify the contents of the argument after Get returns. +func (r *Reader) OffsetOf(key []byte) (offset int64, err error) { + r.mu.RLock() + defer r.mu.RUnlock() + + if r.err != nil { + err = r.err + return + } + + indexBlock, rel, err := r.readBlockCached(r.indexBH, true, true) + if err != nil { + return + } + defer rel.Release() + + index := r.newBlockIter(indexBlock, nil, nil, true) + defer index.Release() + if index.Seek(key) { + dataBH, n := decodeBlockHandle(index.Value()) + if n == 0 { + r.err = r.newErrCorruptedBH(r.indexBH, "bad data block handle") + return + } + offset = int64(dataBH.offset) + return + } + err = index.Error() + if err == nil { + offset = r.dataEnd + } + return +} + +// Release implements util.Releaser. +// It also close the file if it is an io.Closer. +func (r *Reader) Release() { + r.mu.Lock() + defer r.mu.Unlock() + + if closer, ok := r.reader.(io.Closer); ok { + closer.Close() + } + if r.indexBlock != nil { + r.indexBlock.Release() + r.indexBlock = nil + } + if r.filterBlock != nil { + r.filterBlock.Release() + r.filterBlock = nil + } + r.reader = nil + r.cache = nil + r.bpool = nil + r.err = ErrReaderReleased +} + +// NewReader creates a new initialized table reader for the file. +// The fi, cache and bpool is optional and can be nil. +// +// The returned table reader instance is safe for concurrent use. +func NewReader(f io.ReaderAt, size int64, fd storage.FileDesc, cache *cache.NamespaceGetter, bpool *util.BufferPool, o *opt.Options) (*Reader, error) { + if f == nil { + return nil, errors.New("leveldb/table: nil file") + } + + r := &Reader{ + fd: fd, + reader: f, + cache: cache, + bpool: bpool, + o: o, + cmp: o.GetComparer(), + verifyChecksum: o.GetStrict(opt.StrictBlockChecksum), + } + + if size < footerLen { + r.err = r.newErrCorrupted(0, size, "table", "too small") + return r, nil + } + + footerPos := size - footerLen + var footer [footerLen]byte + if _, err := r.reader.ReadAt(footer[:], footerPos); err != nil && err != io.EOF { + return nil, err + } + if string(footer[footerLen-len(magic):footerLen]) != magic { + r.err = r.newErrCorrupted(footerPos, footerLen, "table-footer", "bad magic number") + return r, nil + } + + var n int + // Decode the metaindex block handle. + r.metaBH, n = decodeBlockHandle(footer[:]) + if n == 0 { + r.err = r.newErrCorrupted(footerPos, footerLen, "table-footer", "bad metaindex block handle") + return r, nil + } + + // Decode the index block handle. + r.indexBH, n = decodeBlockHandle(footer[n:]) + if n == 0 { + r.err = r.newErrCorrupted(footerPos, footerLen, "table-footer", "bad index block handle") + return r, nil + } + + // Read metaindex block. + metaBlock, err := r.readBlock(r.metaBH, true) + if err != nil { + if errors.IsCorrupted(err) { + r.err = err + return r, nil + } + return nil, err + } + + // Set data end. + r.dataEnd = int64(r.metaBH.offset) + + // Read metaindex. + metaIter := r.newBlockIter(metaBlock, nil, nil, true) + for metaIter.Next() { + key := string(metaIter.Key()) + if !strings.HasPrefix(key, "filter.") { + continue + } + fn := key[7:] + if f0 := o.GetFilter(); f0 != nil && f0.Name() == fn { + r.filter = f0 + } else { + for _, f0 := range o.GetAltFilters() { + if f0.Name() == fn { + r.filter = f0 + break + } + } + } + if r.filter != nil { + filterBH, n := decodeBlockHandle(metaIter.Value()) + if n == 0 { + continue + } + r.filterBH = filterBH + // Update data end. + r.dataEnd = int64(filterBH.offset) + break + } + } + metaIter.Release() + metaBlock.Release() + + // Cache index and filter block locally, since we don't have global cache. + if cache == nil { + r.indexBlock, err = r.readBlock(r.indexBH, true) + if err != nil { + if errors.IsCorrupted(err) { + r.err = err + return r, nil + } + return nil, err + } + if r.filter != nil { + r.filterBlock, err = r.readFilterBlock(r.filterBH) + if err != nil { + if !errors.IsCorrupted(err) { + return nil, err + } + + // Don't use filter then. + r.filter = nil + } + } + } + + return r, nil +} diff --git a/vendor/github.com/tyler-smith/go-bip39/.gitignore b/vendor/github.com/tyler-smith/go-bip39/.gitignore new file mode 100644 index 00000000..0f49594a --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/.gitignore @@ -0,0 +1,56 @@ +# Executable from build +go-bip39 + + +# Dev utils +.ackrc + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +coverage.out +*.o +*.a +*.so +*.db + +# Temp files +*~ +*.kate-swp +*.orig +debug +*.txt +*.log +.vscode/ +.idea/ +peers.json +*.csv +*.gz + +# Folders +_obj +_test +bin +pkg +.vagrant + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.block +*.entry + +.DS_Store + +*.out +.idea/ +----* diff --git a/vendor/github.com/tyler-smith/go-bip39/.travis.yml b/vendor/github.com/tyler-smith/go-bip39/.travis.yml new file mode 100644 index 00000000..02af24a2 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/.travis.yml @@ -0,0 +1,12 @@ +language: go +go: + - "1.6" + - "1.7" + - "1.8" + - "1.9" + - "1.10" + - "release" + - "tip" + +script: + - make profile_tests diff --git a/vendor/github.com/tyler-smith/go-bip39/Gopkg.lock b/vendor/github.com/tyler-smith/go-bip39/Gopkg.lock new file mode 100644 index 00000000..e15d33f3 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/Gopkg.lock @@ -0,0 +1,15 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["pbkdf2"] + revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "d7f1a7207c39125afcb9ca2365832cb83458edfc17f2f7e8d28fd56f19436856" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/tyler-smith/go-bip39/Gopkg.toml b/vendor/github.com/tyler-smith/go-bip39/Gopkg.toml new file mode 100644 index 00000000..2f655b2c --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/Gopkg.toml @@ -0,0 +1,26 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[constraint]] + branch = "master" + name = "golang.org/x/crypto" diff --git a/vendor/github.com/tyler-smith/go-bip39/LICENSE b/vendor/github.com/tyler-smith/go-bip39/LICENSE new file mode 100644 index 00000000..88940e29 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Tyler Smith + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/tyler-smith/go-bip39/Makefile b/vendor/github.com/tyler-smith/go-bip39/Makefile new file mode 100644 index 00000000..f0f3fe88 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/Makefile @@ -0,0 +1,11 @@ +.DEFAULT_GOAL := help + +tests: ## Run tests with coverage + go test -v -cover ./... + +profile_tests: ## Run tests and output coverage profiling + go test -v -coverprofile=coverage.out . + go tool cover -html=coverage.out + +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/vendor/github.com/tyler-smith/go-bip39/README.md b/vendor/github.com/tyler-smith/go-bip39/README.md new file mode 100644 index 00000000..933296fd --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/README.md @@ -0,0 +1,45 @@ +# go-bip39 +[![Build Status](https://travis-ci.org/tyler-smith/go-bip39.svg?branch=master)](https://travis-ci.org/tyler-smith/go-bip39) +[![license](https://img.shields.io/github/license/tyler-smith/go-bip39.svg?maxAge=2592000)](https://github.com/tyler-smith/go-bip39/blob/master/LICENSE) +[![Documentation](https://godoc.org/github.com/tyler-smith/go-bip39?status.svg)](http://godoc.org/github.com/tyler-smith/go-bip39) +[![Go Report Card](https://goreportcard.com/badge/github.com/tyler-smith/go-bip39)](https://goreportcard.com/report/github.com/tyler-smith/go-bip39) +[![GitHub issues](https://img.shields.io/github/issues/tyler-smith/go-bip39.svg)](https://github.com/tyler-smith/go-bip39/issues) + + +A golang implementation of the BIP0039 spec for mnemonic seeds + +## Example + +```go +package main + +import ( + "github.com/tyler-smith/go-bip39" + "github.com/tyler-smith/go-bip32" + "fmt" +) + +func main(){ + // Generate a mnemonic for memorization or user-friendly seeds + entropy, _ := bip39.NewEntropy(256) + mnemonic, _ := bip39.NewMnemonic(entropy) + + // Generate a Bip32 HD wallet for the mnemonic and a user supplied password + seed := bip39.NewSeed(mnemonic, "Secret Passphrase") + + masterKey, _ := bip32.NewMasterKey(seed) + publicKey := masterKey.PublicKey() + + // Display mnemonic and keys + fmt.Println("Mnemonic: ", mnemonic) + fmt.Println("Master private key: ", masterKey) + fmt.Println("Master public key: ", publicKey) +} +``` + +## Credits + +Wordlists are from the [bip39 spec](https://github.com/bitcoin/bips/tree/master/bip-0039). + +Test vectors are from the standard Python BIP0039 implementation from the +Trezor team: [https://github.com/trezor/python-mnemonic](https://github.com/trezor/python-mnemonic) diff --git a/vendor/github.com/tyler-smith/go-bip39/bip39.go b/vendor/github.com/tyler-smith/go-bip39/bip39.go new file mode 100644 index 00000000..3e4ef283 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/bip39.go @@ -0,0 +1,266 @@ +package bip39 + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/sha512" + "encoding/binary" + "errors" + "math/big" + "strings" + + "github.com/tyler-smith/go-bip39/wordlists" + "golang.org/x/crypto/pbkdf2" +) + +var ( + // Some bitwise operands for working with big.Ints + last11BitsMask = big.NewInt(2047) + rightShift11BitsDivider = big.NewInt(2048) + bigOne = big.NewInt(1) + bigTwo = big.NewInt(2) + + // wordList is the set of words to use + wordList []string + + // wordMap is a reverse lookup map for wordList + wordMap map[string]int +) + +var ( + // ErrInvalidMnemonic is returned when trying to use a malformed mnemonic. + ErrInvalidMnemonic = errors.New("Invalid menomic") + + // ErrEntropyLengthInvalid is returned when trying to use an entropy set with + // an invalid size. + ErrEntropyLengthInvalid = errors.New("Entropy length must be [128, 256] and a multiple of 32") + + // ErrValidatedSeedLengthMismatch is returned when a validated seed is not the + // same size as the given seed. This should never happen is present only as a + // sanity assertion. + ErrValidatedSeedLengthMismatch = errors.New("Seed length does not match validated seed length") + + // ErrChecksumIncorrect is returned when entropy has the incorrect checksum. + ErrChecksumIncorrect = errors.New("Checksum incorrect") +) + +func init() { + SetWordList(wordlists.English) +} + +// SetWordList sets the list of words to use for mnemonics. Currently the list +// that is set is used package-wide. +func SetWordList(list []string) { + wordList = list + wordMap = map[string]int{} + for i, v := range wordList { + wordMap[v] = i + } +} + +// NewEntropy will create random entropy bytes +// so long as the requested size bitSize is an appropriate size. +func NewEntropy(bitSize int) ([]byte, error) { + err := validateEntropyBitSize(bitSize) + if err != nil { + return nil, err + } + + entropy := make([]byte, bitSize/8) + _, err = rand.Read(entropy) + return entropy, err +} + +// NewMnemonic will return a string consisting of the mnemonic words for +// the given entropy. +// If the provide entropy is invalid, an error will be returned. +func NewMnemonic(entropy []byte) (string, error) { + // Compute some lengths for convenience + entropyBitLength := len(entropy) * 8 + checksumBitLength := entropyBitLength / 32 + sentenceLength := (entropyBitLength + checksumBitLength) / 11 + + err := validateEntropyBitSize(entropyBitLength) + if err != nil { + return "", err + } + + // Add checksum to entropy + entropy = addChecksum(entropy) + + // Break entropy up into sentenceLength chunks of 11 bits + // For each word AND mask the rightmost 11 bits and find the word at that index + // Then bitshift entropy 11 bits right and repeat + // Add to the last empty slot so we can work with LSBs instead of MSB + + // Entropy as an int so we can bitmask without worrying about bytes slices + entropyInt := new(big.Int).SetBytes(entropy) + + // Slice to hold words in + words := make([]string, sentenceLength) + + // Throw away big int for AND masking + word := big.NewInt(0) + + for i := sentenceLength - 1; i >= 0; i-- { + // Get 11 right most bits and bitshift 11 to the right for next time + word.And(entropyInt, last11BitsMask) + entropyInt.Div(entropyInt, rightShift11BitsDivider) + + // Get the bytes representing the 11 bits as a 2 byte slice + wordBytes := padByteSlice(word.Bytes(), 2) + + // Convert bytes to an index and add that word to the list + words[i] = wordList[binary.BigEndian.Uint16(wordBytes)] + } + + return strings.Join(words, " "), nil +} + +// MnemonicToByteArray takes a mnemonic string and turns it into a byte array +// suitable for creating another mnemonic. +// An error is returned if the mnemonic is invalid. +func MnemonicToByteArray(mnemonic string) ([]byte, error) { + var ( + mnemonicSlice = strings.Split(mnemonic, " ") + entropyBitSize = len(mnemonicSlice) * 11 + checksumBitSize = entropyBitSize % 32 + fullByteSize = (entropyBitSize-checksumBitSize)/8 + 1 + checksumByteSize = fullByteSize - (fullByteSize % 4) + ) + + // Pre validate that the mnemonic is well formed and only contains words that + // are present in the word list + if !IsMnemonicValid(mnemonic) { + return nil, ErrInvalidMnemonic + } + + // Convert word indices to a `big.Int` representing the entropy + checksummedEntropy := big.NewInt(0) + modulo := big.NewInt(2048) + for _, v := range mnemonicSlice { + index := big.NewInt(int64(wordMap[v])) + checksummedEntropy.Mul(checksummedEntropy, modulo) + checksummedEntropy.Add(checksummedEntropy, index) + } + + // Calculate the unchecksummed entropy so we can validate that the checksum is + // correct + checksumModulo := big.NewInt(0).Exp(bigTwo, big.NewInt(int64(checksumBitSize)), nil) + rawEntropy := big.NewInt(0).Div(checksummedEntropy, checksumModulo) + + // Convert `big.Int`s to byte padded byte slices + rawEntropyBytes := padByteSlice(rawEntropy.Bytes(), checksumByteSize) + checksummedEntropyBytes := padByteSlice(checksummedEntropy.Bytes(), fullByteSize) + + // Validate that the checksum is correct + newChecksummedEntropyBytes := padByteSlice(addChecksum(rawEntropyBytes), fullByteSize) + if !compareByteSlices(checksummedEntropyBytes, newChecksummedEntropyBytes) { + return nil, ErrChecksumIncorrect + } + + return checksummedEntropyBytes, nil +} + +// NewSeedWithErrorChecking creates a hashed seed output given the mnemonic string and a password. +// An error is returned if the mnemonic is not convertible to a byte array. +func NewSeedWithErrorChecking(mnemonic string, password string) ([]byte, error) { + _, err := MnemonicToByteArray(mnemonic) + if err != nil { + return nil, err + } + return NewSeed(mnemonic, password), nil +} + +// NewSeed creates a hashed seed output given a provided string and password. +// No checking is performed to validate that the string provided is a valid mnemonic. +func NewSeed(mnemonic string, password string) []byte { + return pbkdf2.Key([]byte(mnemonic), []byte("mnemonic"+password), 2048, 64, sha512.New) +} + +// IsMnemonicValid attempts to verify that the provided mnemonic is valid. +// Validity is determined by both the number of words being appropriate, +// and that all the words in the mnemonic are present in the word list. +func IsMnemonicValid(mnemonic string) bool { + // Create a list of all the words in the mnemonic sentence + words := strings.Fields(mnemonic) + + // Get word count + wordCount := len(words) + + // The number of words should be 12, 15, 18, 21 or 24 + if wordCount%3 != 0 || wordCount < 12 || wordCount > 24 { + return false + } + + // Check if all words belong in the wordlist + for _, word := range words { + if _, ok := wordMap[word]; !ok { + return false + } + } + + return true +} + +// Appends to data the first (len(data) / 32)bits of the result of sha256(data) +// Currently only supports data up to 32 bytes +func addChecksum(data []byte) []byte { + // Get first byte of sha256 + hasher := sha256.New() + hasher.Write(data) + hash := hasher.Sum(nil) + firstChecksumByte := hash[0] + + // len() is in bytes so we divide by 4 + checksumBitLength := uint(len(data) / 4) + + // For each bit of check sum we want we shift the data one the left + // and then set the (new) right most bit equal to checksum bit at that index + // staring from the left + dataBigInt := new(big.Int).SetBytes(data) + for i := uint(0); i < checksumBitLength; i++ { + // Bitshift 1 left + dataBigInt.Mul(dataBigInt, bigTwo) + + // Set rightmost bit if leftmost checksum bit is set + if uint8(firstChecksumByte&(1<<(7-i))) > 0 { + dataBigInt.Or(dataBigInt, bigOne) + } + } + + return dataBigInt.Bytes() +} + +// validateEntropyBitSize ensures that entropy is the correct size for being a +// mnemonic. +func validateEntropyBitSize(bitSize int) error { + if (bitSize%32) != 0 || bitSize < 128 || bitSize > 256 { + return ErrEntropyLengthInvalid + } + return nil +} + +// padByteSlice returns a byte slice of the given size with contents of the +// given slice left padded and any empty spaces filled with 0's. +func padByteSlice(slice []byte, length int) []byte { + if len(slice) >= length { + return slice + } + newSlice := make([]byte, length-len(slice)) + return append(newSlice, slice...) +} + +// compareByteSlices returns true of the byte slices have equal contents and +// returns false otherwise. +func compareByteSlices(a, b []byte) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_simplified.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_simplified.go new file mode 100644 index 00000000..0ee29727 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_simplified.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/chinese_simplified.txt + // $ crc32 chinese_simplified.txt + // e3721bbf + checksum := crc32.ChecksumIEEE([]byte(chineseSimplified)) + if fmt.Sprintf("%x", checksum) != "e3721bbf" { + panic("chineseSimplified checksum invalid") + } +} + +// ChineseSimplified is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/chinese_simplified.txt +var ChineseSimplified = strings.Split(strings.TrimSpace(chineseSimplified), "\n") +var chineseSimplified = `的 +一 +是 +在 +不 +了 +有 +和 +人 +这 +中 +大 +为 +上 +个 +国 +我 +以 +要 +他 +时 +来 +用 +们 +生 +到 +作 +地 +于 +出 +就 +分 +对 +成 +会 +可 +主 +发 +年 +动 +同 +工 +也 +能 +下 +过 +子 +说 +产 +种 +面 +而 +方 +后 +多 +定 +行 +学 +法 +所 +民 +得 +经 +十 +三 +之 +进 +着 +等 +部 +度 +家 +电 +力 +里 +如 +水 +化 +高 +自 +二 +理 +起 +小 +物 +现 +实 +加 +量 +都 +两 +体 +制 +机 +当 +使 +点 +从 +业 +本 +去 +把 +性 +好 +应 +开 +它 +合 +还 +因 +由 +其 +些 +然 +前 +外 +天 +政 +四 +日 +那 +社 +义 +事 +平 +形 +相 +全 +表 +间 +样 +与 +关 +各 +重 +新 +线 +内 +数 +正 +心 +反 +你 +明 +看 +原 +又 +么 +利 +比 +或 +但 +质 +气 +第 +向 +道 +命 +此 +变 +条 +只 +没 +结 +解 +问 +意 +建 +月 +公 +无 +系 +军 +很 +情 +者 +最 +立 +代 +想 +已 +通 +并 +提 +直 +题 +党 +程 +展 +五 +果 +料 +象 +员 +革 +位 +入 +常 +文 +总 +次 +品 +式 +活 +设 +及 +管 +特 +件 +长 +求 +老 +头 +基 +资 +边 +流 +路 +级 +少 +图 +山 +统 +接 +知 +较 +将 +组 +见 +计 +别 +她 +手 +角 +期 +根 +论 +运 +农 +指 +几 +九 +区 +强 +放 +决 +西 +被 +干 +做 +必 +战 +先 +回 +则 +任 +取 +据 +处 +队 +南 +给 +色 +光 +门 +即 +保 +治 +北 +造 +百 +规 +热 +领 +七 +海 +口 +东 +导 +器 +压 +志 +世 +金 +增 +争 +济 +阶 +油 +思 +术 +极 +交 +受 +联 +什 +认 +六 +共 +权 +收 +证 +改 +清 +美 +再 +采 +转 +更 +单 +风 +切 +打 +白 +教 +速 +花 +带 +安 +场 +身 +车 +例 +真 +务 +具 +万 +每 +目 +至 +达 +走 +积 +示 +议 +声 +报 +斗 +完 +类 +八 +离 +华 +名 +确 +才 +科 +张 +信 +马 +节 +话 +米 +整 +空 +元 +况 +今 +集 +温 +传 +土 +许 +步 +群 +广 +石 +记 +需 +段 +研 +界 +拉 +林 +律 +叫 +且 +究 +观 +越 +织 +装 +影 +算 +低 +持 +音 +众 +书 +布 +复 +容 +儿 +须 +际 +商 +非 +验 +连 +断 +深 +难 +近 +矿 +千 +周 +委 +素 +技 +备 +半 +办 +青 +省 +列 +习 +响 +约 +支 +般 +史 +感 +劳 +便 +团 +往 +酸 +历 +市 +克 +何 +除 +消 +构 +府 +称 +太 +准 +精 +值 +号 +率 +族 +维 +划 +选 +标 +写 +存 +候 +毛 +亲 +快 +效 +斯 +院 +查 +江 +型 +眼 +王 +按 +格 +养 +易 +置 +派 +层 +片 +始 +却 +专 +状 +育 +厂 +京 +识 +适 +属 +圆 +包 +火 +住 +调 +满 +县 +局 +照 +参 +红 +细 +引 +听 +该 +铁 +价 +严 +首 +底 +液 +官 +德 +随 +病 +苏 +失 +尔 +死 +讲 +配 +女 +黄 +推 +显 +谈 +罪 +神 +艺 +呢 +席 +含 +企 +望 +密 +批 +营 +项 +防 +举 +球 +英 +氧 +势 +告 +李 +台 +落 +木 +帮 +轮 +破 +亚 +师 +围 +注 +远 +字 +材 +排 +供 +河 +态 +封 +另 +施 +减 +树 +溶 +怎 +止 +案 +言 +士 +均 +武 +固 +叶 +鱼 +波 +视 +仅 +费 +紧 +爱 +左 +章 +早 +朝 +害 +续 +轻 +服 +试 +食 +充 +兵 +源 +判 +护 +司 +足 +某 +练 +差 +致 +板 +田 +降 +黑 +犯 +负 +击 +范 +继 +兴 +似 +余 +坚 +曲 +输 +修 +故 +城 +夫 +够 +送 +笔 +船 +占 +右 +财 +吃 +富 +春 +职 +觉 +汉 +画 +功 +巴 +跟 +虽 +杂 +飞 +检 +吸 +助 +升 +阳 +互 +初 +创 +抗 +考 +投 +坏 +策 +古 +径 +换 +未 +跑 +留 +钢 +曾 +端 +责 +站 +简 +述 +钱 +副 +尽 +帝 +射 +草 +冲 +承 +独 +令 +限 +阿 +宣 +环 +双 +请 +超 +微 +让 +控 +州 +良 +轴 +找 +否 +纪 +益 +依 +优 +顶 +础 +载 +倒 +房 +突 +坐 +粉 +敌 +略 +客 +袁 +冷 +胜 +绝 +析 +块 +剂 +测 +丝 +协 +诉 +念 +陈 +仍 +罗 +盐 +友 +洋 +错 +苦 +夜 +刑 +移 +频 +逐 +靠 +混 +母 +短 +皮 +终 +聚 +汽 +村 +云 +哪 +既 +距 +卫 +停 +烈 +央 +察 +烧 +迅 +境 +若 +印 +洲 +刻 +括 +激 +孔 +搞 +甚 +室 +待 +核 +校 +散 +侵 +吧 +甲 +游 +久 +菜 +味 +旧 +模 +湖 +货 +损 +预 +阻 +毫 +普 +稳 +乙 +妈 +植 +息 +扩 +银 +语 +挥 +酒 +守 +拿 +序 +纸 +医 +缺 +雨 +吗 +针 +刘 +啊 +急 +唱 +误 +训 +愿 +审 +附 +获 +茶 +鲜 +粮 +斤 +孩 +脱 +硫 +肥 +善 +龙 +演 +父 +渐 +血 +欢 +械 +掌 +歌 +沙 +刚 +攻 +谓 +盾 +讨 +晚 +粒 +乱 +燃 +矛 +乎 +杀 +药 +宁 +鲁 +贵 +钟 +煤 +读 +班 +伯 +香 +介 +迫 +句 +丰 +培 +握 +兰 +担 +弦 +蛋 +沉 +假 +穿 +执 +答 +乐 +谁 +顺 +烟 +缩 +征 +脸 +喜 +松 +脚 +困 +异 +免 +背 +星 +福 +买 +染 +井 +概 +慢 +怕 +磁 +倍 +祖 +皇 +促 +静 +补 +评 +翻 +肉 +践 +尼 +衣 +宽 +扬 +棉 +希 +伤 +操 +垂 +秋 +宜 +氢 +套 +督 +振 +架 +亮 +末 +宪 +庆 +编 +牛 +触 +映 +雷 +销 +诗 +座 +居 +抓 +裂 +胞 +呼 +娘 +景 +威 +绿 +晶 +厚 +盟 +衡 +鸡 +孙 +延 +危 +胶 +屋 +乡 +临 +陆 +顾 +掉 +呀 +灯 +岁 +措 +束 +耐 +剧 +玉 +赵 +跳 +哥 +季 +课 +凯 +胡 +额 +款 +绍 +卷 +齐 +伟 +蒸 +殖 +永 +宗 +苗 +川 +炉 +岩 +弱 +零 +杨 +奏 +沿 +露 +杆 +探 +滑 +镇 +饭 +浓 +航 +怀 +赶 +库 +夺 +伊 +灵 +税 +途 +灭 +赛 +归 +召 +鼓 +播 +盘 +裁 +险 +康 +唯 +录 +菌 +纯 +借 +糖 +盖 +横 +符 +私 +努 +堂 +域 +枪 +润 +幅 +哈 +竟 +熟 +虫 +泽 +脑 +壤 +碳 +欧 +遍 +侧 +寨 +敢 +彻 +虑 +斜 +薄 +庭 +纳 +弹 +饲 +伸 +折 +麦 +湿 +暗 +荷 +瓦 +塞 +床 +筑 +恶 +户 +访 +塔 +奇 +透 +梁 +刀 +旋 +迹 +卡 +氯 +遇 +份 +毒 +泥 +退 +洗 +摆 +灰 +彩 +卖 +耗 +夏 +择 +忙 +铜 +献 +硬 +予 +繁 +圈 +雪 +函 +亦 +抽 +篇 +阵 +阴 +丁 +尺 +追 +堆 +雄 +迎 +泛 +爸 +楼 +避 +谋 +吨 +野 +猪 +旗 +累 +偏 +典 +馆 +索 +秦 +脂 +潮 +爷 +豆 +忽 +托 +惊 +塑 +遗 +愈 +朱 +替 +纤 +粗 +倾 +尚 +痛 +楚 +谢 +奋 +购 +磨 +君 +池 +旁 +碎 +骨 +监 +捕 +弟 +暴 +割 +贯 +殊 +释 +词 +亡 +壁 +顿 +宝 +午 +尘 +闻 +揭 +炮 +残 +冬 +桥 +妇 +警 +综 +招 +吴 +付 +浮 +遭 +徐 +您 +摇 +谷 +赞 +箱 +隔 +订 +男 +吹 +园 +纷 +唐 +败 +宋 +玻 +巨 +耕 +坦 +荣 +闭 +湾 +键 +凡 +驻 +锅 +救 +恩 +剥 +凝 +碱 +齿 +截 +炼 +麻 +纺 +禁 +废 +盛 +版 +缓 +净 +睛 +昌 +婚 +涉 +筒 +嘴 +插 +岸 +朗 +庄 +街 +藏 +姑 +贸 +腐 +奴 +啦 +惯 +乘 +伙 +恢 +匀 +纱 +扎 +辩 +耳 +彪 +臣 +亿 +璃 +抵 +脉 +秀 +萨 +俄 +网 +舞 +店 +喷 +纵 +寸 +汗 +挂 +洪 +贺 +闪 +柬 +爆 +烯 +津 +稻 +墙 +软 +勇 +像 +滚 +厘 +蒙 +芳 +肯 +坡 +柱 +荡 +腿 +仪 +旅 +尾 +轧 +冰 +贡 +登 +黎 +削 +钻 +勒 +逃 +障 +氨 +郭 +峰 +币 +港 +伏 +轨 +亩 +毕 +擦 +莫 +刺 +浪 +秘 +援 +株 +健 +售 +股 +岛 +甘 +泡 +睡 +童 +铸 +汤 +阀 +休 +汇 +舍 +牧 +绕 +炸 +哲 +磷 +绩 +朋 +淡 +尖 +启 +陷 +柴 +呈 +徒 +颜 +泪 +稍 +忘 +泵 +蓝 +拖 +洞 +授 +镜 +辛 +壮 +锋 +贫 +虚 +弯 +摩 +泰 +幼 +廷 +尊 +窗 +纲 +弄 +隶 +疑 +氏 +宫 +姐 +震 +瑞 +怪 +尤 +琴 +循 +描 +膜 +违 +夹 +腰 +缘 +珠 +穷 +森 +枝 +竹 +沟 +催 +绳 +忆 +邦 +剩 +幸 +浆 +栏 +拥 +牙 +贮 +礼 +滤 +钠 +纹 +罢 +拍 +咱 +喊 +袖 +埃 +勤 +罚 +焦 +潜 +伍 +墨 +欲 +缝 +姓 +刊 +饱 +仿 +奖 +铝 +鬼 +丽 +跨 +默 +挖 +链 +扫 +喝 +袋 +炭 +污 +幕 +诸 +弧 +励 +梅 +奶 +洁 +灾 +舟 +鉴 +苯 +讼 +抱 +毁 +懂 +寒 +智 +埔 +寄 +届 +跃 +渡 +挑 +丹 +艰 +贝 +碰 +拔 +爹 +戴 +码 +梦 +芽 +熔 +赤 +渔 +哭 +敬 +颗 +奔 +铅 +仲 +虎 +稀 +妹 +乏 +珍 +申 +桌 +遵 +允 +隆 +螺 +仓 +魏 +锐 +晓 +氮 +兼 +隐 +碍 +赫 +拨 +忠 +肃 +缸 +牵 +抢 +博 +巧 +壳 +兄 +杜 +讯 +诚 +碧 +祥 +柯 +页 +巡 +矩 +悲 +灌 +龄 +伦 +票 +寻 +桂 +铺 +圣 +恐 +恰 +郑 +趣 +抬 +荒 +腾 +贴 +柔 +滴 +猛 +阔 +辆 +妻 +填 +撤 +储 +签 +闹 +扰 +紫 +砂 +递 +戏 +吊 +陶 +伐 +喂 +疗 +瓶 +婆 +抚 +臂 +摸 +忍 +虾 +蜡 +邻 +胸 +巩 +挤 +偶 +弃 +槽 +劲 +乳 +邓 +吉 +仁 +烂 +砖 +租 +乌 +舰 +伴 +瓜 +浅 +丙 +暂 +燥 +橡 +柳 +迷 +暖 +牌 +秧 +胆 +详 +簧 +踏 +瓷 +谱 +呆 +宾 +糊 +洛 +辉 +愤 +竞 +隙 +怒 +粘 +乃 +绪 +肩 +籍 +敏 +涂 +熙 +皆 +侦 +悬 +掘 +享 +纠 +醒 +狂 +锁 +淀 +恨 +牲 +霸 +爬 +赏 +逆 +玩 +陵 +祝 +秒 +浙 +貌 +役 +彼 +悉 +鸭 +趋 +凤 +晨 +畜 +辈 +秩 +卵 +署 +梯 +炎 +滩 +棋 +驱 +筛 +峡 +冒 +啥 +寿 +译 +浸 +泉 +帽 +迟 +硅 +疆 +贷 +漏 +稿 +冠 +嫩 +胁 +芯 +牢 +叛 +蚀 +奥 +鸣 +岭 +羊 +凭 +串 +塘 +绘 +酵 +融 +盆 +锡 +庙 +筹 +冻 +辅 +摄 +袭 +筋 +拒 +僚 +旱 +钾 +鸟 +漆 +沈 +眉 +疏 +添 +棒 +穗 +硝 +韩 +逼 +扭 +侨 +凉 +挺 +碗 +栽 +炒 +杯 +患 +馏 +劝 +豪 +辽 +勃 +鸿 +旦 +吏 +拜 +狗 +埋 +辊 +掩 +饮 +搬 +骂 +辞 +勾 +扣 +估 +蒋 +绒 +雾 +丈 +朵 +姆 +拟 +宇 +辑 +陕 +雕 +偿 +蓄 +崇 +剪 +倡 +厅 +咬 +驶 +薯 +刷 +斥 +番 +赋 +奉 +佛 +浇 +漫 +曼 +扇 +钙 +桃 +扶 +仔 +返 +俗 +亏 +腔 +鞋 +棱 +覆 +框 +悄 +叔 +撞 +骗 +勘 +旺 +沸 +孤 +吐 +孟 +渠 +屈 +疾 +妙 +惜 +仰 +狠 +胀 +谐 +抛 +霉 +桑 +岗 +嘛 +衰 +盗 +渗 +脏 +赖 +涌 +甜 +曹 +阅 +肌 +哩 +厉 +烃 +纬 +毅 +昨 +伪 +症 +煮 +叹 +钉 +搭 +茎 +笼 +酷 +偷 +弓 +锥 +恒 +杰 +坑 +鼻 +翼 +纶 +叙 +狱 +逮 +罐 +络 +棚 +抑 +膨 +蔬 +寺 +骤 +穆 +冶 +枯 +册 +尸 +凸 +绅 +坯 +牺 +焰 +轰 +欣 +晋 +瘦 +御 +锭 +锦 +丧 +旬 +锻 +垄 +搜 +扑 +邀 +亭 +酯 +迈 +舒 +脆 +酶 +闲 +忧 +酚 +顽 +羽 +涨 +卸 +仗 +陪 +辟 +惩 +杭 +姚 +肚 +捉 +飘 +漂 +昆 +欺 +吾 +郎 +烷 +汁 +呵 +饰 +萧 +雅 +邮 +迁 +燕 +撒 +姻 +赴 +宴 +烦 +债 +帐 +斑 +铃 +旨 +醇 +董 +饼 +雏 +姿 +拌 +傅 +腹 +妥 +揉 +贤 +拆 +歪 +葡 +胺 +丢 +浩 +徽 +昂 +垫 +挡 +览 +贪 +慰 +缴 +汪 +慌 +冯 +诺 +姜 +谊 +凶 +劣 +诬 +耀 +昏 +躺 +盈 +骑 +乔 +溪 +丛 +卢 +抹 +闷 +咨 +刮 +驾 +缆 +悟 +摘 +铒 +掷 +颇 +幻 +柄 +惠 +惨 +佳 +仇 +腊 +窝 +涤 +剑 +瞧 +堡 +泼 +葱 +罩 +霍 +捞 +胎 +苍 +滨 +俩 +捅 +湘 +砍 +霞 +邵 +萄 +疯 +淮 +遂 +熊 +粪 +烘 +宿 +档 +戈 +驳 +嫂 +裕 +徙 +箭 +捐 +肠 +撑 +晒 +辨 +殿 +莲 +摊 +搅 +酱 +屏 +疫 +哀 +蔡 +堵 +沫 +皱 +畅 +叠 +阁 +莱 +敲 +辖 +钩 +痕 +坝 +巷 +饿 +祸 +丘 +玄 +溜 +曰 +逻 +彭 +尝 +卿 +妨 +艇 +吞 +韦 +怨 +矮 +歇 +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_traditional.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_traditional.go new file mode 100644 index 00000000..83812cee --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/chinese_traditional.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/chinese_traditional.txt + // $ crc32 chinese_traditional.txt + // 3c20b443 + checksum := crc32.ChecksumIEEE([]byte(chineseTraditional)) + if fmt.Sprintf("%x", checksum) != "3c20b443" { + panic("chineseTraditional checksum invalid") + } +} + +// ChineseTraditional is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/chinese_traditional.txt +var ChineseTraditional = strings.Split(strings.TrimSpace(chineseTraditional), "\n") +var chineseTraditional = `的 +一 +是 +在 +不 +了 +有 +和 +人 +這 +中 +大 +為 +上 +個 +國 +我 +以 +要 +他 +時 +來 +用 +們 +生 +到 +作 +地 +於 +出 +就 +分 +對 +成 +會 +可 +主 +發 +年 +動 +同 +工 +也 +能 +下 +過 +子 +說 +產 +種 +面 +而 +方 +後 +多 +定 +行 +學 +法 +所 +民 +得 +經 +十 +三 +之 +進 +著 +等 +部 +度 +家 +電 +力 +裡 +如 +水 +化 +高 +自 +二 +理 +起 +小 +物 +現 +實 +加 +量 +都 +兩 +體 +制 +機 +當 +使 +點 +從 +業 +本 +去 +把 +性 +好 +應 +開 +它 +合 +還 +因 +由 +其 +些 +然 +前 +外 +天 +政 +四 +日 +那 +社 +義 +事 +平 +形 +相 +全 +表 +間 +樣 +與 +關 +各 +重 +新 +線 +內 +數 +正 +心 +反 +你 +明 +看 +原 +又 +麼 +利 +比 +或 +但 +質 +氣 +第 +向 +道 +命 +此 +變 +條 +只 +沒 +結 +解 +問 +意 +建 +月 +公 +無 +系 +軍 +很 +情 +者 +最 +立 +代 +想 +已 +通 +並 +提 +直 +題 +黨 +程 +展 +五 +果 +料 +象 +員 +革 +位 +入 +常 +文 +總 +次 +品 +式 +活 +設 +及 +管 +特 +件 +長 +求 +老 +頭 +基 +資 +邊 +流 +路 +級 +少 +圖 +山 +統 +接 +知 +較 +將 +組 +見 +計 +別 +她 +手 +角 +期 +根 +論 +運 +農 +指 +幾 +九 +區 +強 +放 +決 +西 +被 +幹 +做 +必 +戰 +先 +回 +則 +任 +取 +據 +處 +隊 +南 +給 +色 +光 +門 +即 +保 +治 +北 +造 +百 +規 +熱 +領 +七 +海 +口 +東 +導 +器 +壓 +志 +世 +金 +增 +爭 +濟 +階 +油 +思 +術 +極 +交 +受 +聯 +什 +認 +六 +共 +權 +收 +證 +改 +清 +美 +再 +採 +轉 +更 +單 +風 +切 +打 +白 +教 +速 +花 +帶 +安 +場 +身 +車 +例 +真 +務 +具 +萬 +每 +目 +至 +達 +走 +積 +示 +議 +聲 +報 +鬥 +完 +類 +八 +離 +華 +名 +確 +才 +科 +張 +信 +馬 +節 +話 +米 +整 +空 +元 +況 +今 +集 +溫 +傳 +土 +許 +步 +群 +廣 +石 +記 +需 +段 +研 +界 +拉 +林 +律 +叫 +且 +究 +觀 +越 +織 +裝 +影 +算 +低 +持 +音 +眾 +書 +布 +复 +容 +兒 +須 +際 +商 +非 +驗 +連 +斷 +深 +難 +近 +礦 +千 +週 +委 +素 +技 +備 +半 +辦 +青 +省 +列 +習 +響 +約 +支 +般 +史 +感 +勞 +便 +團 +往 +酸 +歷 +市 +克 +何 +除 +消 +構 +府 +稱 +太 +準 +精 +值 +號 +率 +族 +維 +劃 +選 +標 +寫 +存 +候 +毛 +親 +快 +效 +斯 +院 +查 +江 +型 +眼 +王 +按 +格 +養 +易 +置 +派 +層 +片 +始 +卻 +專 +狀 +育 +廠 +京 +識 +適 +屬 +圓 +包 +火 +住 +調 +滿 +縣 +局 +照 +參 +紅 +細 +引 +聽 +該 +鐵 +價 +嚴 +首 +底 +液 +官 +德 +隨 +病 +蘇 +失 +爾 +死 +講 +配 +女 +黃 +推 +顯 +談 +罪 +神 +藝 +呢 +席 +含 +企 +望 +密 +批 +營 +項 +防 +舉 +球 +英 +氧 +勢 +告 +李 +台 +落 +木 +幫 +輪 +破 +亞 +師 +圍 +注 +遠 +字 +材 +排 +供 +河 +態 +封 +另 +施 +減 +樹 +溶 +怎 +止 +案 +言 +士 +均 +武 +固 +葉 +魚 +波 +視 +僅 +費 +緊 +愛 +左 +章 +早 +朝 +害 +續 +輕 +服 +試 +食 +充 +兵 +源 +判 +護 +司 +足 +某 +練 +差 +致 +板 +田 +降 +黑 +犯 +負 +擊 +范 +繼 +興 +似 +餘 +堅 +曲 +輸 +修 +故 +城 +夫 +夠 +送 +筆 +船 +佔 +右 +財 +吃 +富 +春 +職 +覺 +漢 +畫 +功 +巴 +跟 +雖 +雜 +飛 +檢 +吸 +助 +昇 +陽 +互 +初 +創 +抗 +考 +投 +壞 +策 +古 +徑 +換 +未 +跑 +留 +鋼 +曾 +端 +責 +站 +簡 +述 +錢 +副 +盡 +帝 +射 +草 +衝 +承 +獨 +令 +限 +阿 +宣 +環 +雙 +請 +超 +微 +讓 +控 +州 +良 +軸 +找 +否 +紀 +益 +依 +優 +頂 +礎 +載 +倒 +房 +突 +坐 +粉 +敵 +略 +客 +袁 +冷 +勝 +絕 +析 +塊 +劑 +測 +絲 +協 +訴 +念 +陳 +仍 +羅 +鹽 +友 +洋 +錯 +苦 +夜 +刑 +移 +頻 +逐 +靠 +混 +母 +短 +皮 +終 +聚 +汽 +村 +雲 +哪 +既 +距 +衛 +停 +烈 +央 +察 +燒 +迅 +境 +若 +印 +洲 +刻 +括 +激 +孔 +搞 +甚 +室 +待 +核 +校 +散 +侵 +吧 +甲 +遊 +久 +菜 +味 +舊 +模 +湖 +貨 +損 +預 +阻 +毫 +普 +穩 +乙 +媽 +植 +息 +擴 +銀 +語 +揮 +酒 +守 +拿 +序 +紙 +醫 +缺 +雨 +嗎 +針 +劉 +啊 +急 +唱 +誤 +訓 +願 +審 +附 +獲 +茶 +鮮 +糧 +斤 +孩 +脫 +硫 +肥 +善 +龍 +演 +父 +漸 +血 +歡 +械 +掌 +歌 +沙 +剛 +攻 +謂 +盾 +討 +晚 +粒 +亂 +燃 +矛 +乎 +殺 +藥 +寧 +魯 +貴 +鐘 +煤 +讀 +班 +伯 +香 +介 +迫 +句 +豐 +培 +握 +蘭 +擔 +弦 +蛋 +沉 +假 +穿 +執 +答 +樂 +誰 +順 +煙 +縮 +徵 +臉 +喜 +松 +腳 +困 +異 +免 +背 +星 +福 +買 +染 +井 +概 +慢 +怕 +磁 +倍 +祖 +皇 +促 +靜 +補 +評 +翻 +肉 +踐 +尼 +衣 +寬 +揚 +棉 +希 +傷 +操 +垂 +秋 +宜 +氫 +套 +督 +振 +架 +亮 +末 +憲 +慶 +編 +牛 +觸 +映 +雷 +銷 +詩 +座 +居 +抓 +裂 +胞 +呼 +娘 +景 +威 +綠 +晶 +厚 +盟 +衡 +雞 +孫 +延 +危 +膠 +屋 +鄉 +臨 +陸 +顧 +掉 +呀 +燈 +歲 +措 +束 +耐 +劇 +玉 +趙 +跳 +哥 +季 +課 +凱 +胡 +額 +款 +紹 +卷 +齊 +偉 +蒸 +殖 +永 +宗 +苗 +川 +爐 +岩 +弱 +零 +楊 +奏 +沿 +露 +桿 +探 +滑 +鎮 +飯 +濃 +航 +懷 +趕 +庫 +奪 +伊 +靈 +稅 +途 +滅 +賽 +歸 +召 +鼓 +播 +盤 +裁 +險 +康 +唯 +錄 +菌 +純 +借 +糖 +蓋 +橫 +符 +私 +努 +堂 +域 +槍 +潤 +幅 +哈 +竟 +熟 +蟲 +澤 +腦 +壤 +碳 +歐 +遍 +側 +寨 +敢 +徹 +慮 +斜 +薄 +庭 +納 +彈 +飼 +伸 +折 +麥 +濕 +暗 +荷 +瓦 +塞 +床 +築 +惡 +戶 +訪 +塔 +奇 +透 +梁 +刀 +旋 +跡 +卡 +氯 +遇 +份 +毒 +泥 +退 +洗 +擺 +灰 +彩 +賣 +耗 +夏 +擇 +忙 +銅 +獻 +硬 +予 +繁 +圈 +雪 +函 +亦 +抽 +篇 +陣 +陰 +丁 +尺 +追 +堆 +雄 +迎 +泛 +爸 +樓 +避 +謀 +噸 +野 +豬 +旗 +累 +偏 +典 +館 +索 +秦 +脂 +潮 +爺 +豆 +忽 +托 +驚 +塑 +遺 +愈 +朱 +替 +纖 +粗 +傾 +尚 +痛 +楚 +謝 +奮 +購 +磨 +君 +池 +旁 +碎 +骨 +監 +捕 +弟 +暴 +割 +貫 +殊 +釋 +詞 +亡 +壁 +頓 +寶 +午 +塵 +聞 +揭 +炮 +殘 +冬 +橋 +婦 +警 +綜 +招 +吳 +付 +浮 +遭 +徐 +您 +搖 +谷 +贊 +箱 +隔 +訂 +男 +吹 +園 +紛 +唐 +敗 +宋 +玻 +巨 +耕 +坦 +榮 +閉 +灣 +鍵 +凡 +駐 +鍋 +救 +恩 +剝 +凝 +鹼 +齒 +截 +煉 +麻 +紡 +禁 +廢 +盛 +版 +緩 +淨 +睛 +昌 +婚 +涉 +筒 +嘴 +插 +岸 +朗 +莊 +街 +藏 +姑 +貿 +腐 +奴 +啦 +慣 +乘 +夥 +恢 +勻 +紗 +扎 +辯 +耳 +彪 +臣 +億 +璃 +抵 +脈 +秀 +薩 +俄 +網 +舞 +店 +噴 +縱 +寸 +汗 +掛 +洪 +賀 +閃 +柬 +爆 +烯 +津 +稻 +牆 +軟 +勇 +像 +滾 +厘 +蒙 +芳 +肯 +坡 +柱 +盪 +腿 +儀 +旅 +尾 +軋 +冰 +貢 +登 +黎 +削 +鑽 +勒 +逃 +障 +氨 +郭 +峰 +幣 +港 +伏 +軌 +畝 +畢 +擦 +莫 +刺 +浪 +秘 +援 +株 +健 +售 +股 +島 +甘 +泡 +睡 +童 +鑄 +湯 +閥 +休 +匯 +舍 +牧 +繞 +炸 +哲 +磷 +績 +朋 +淡 +尖 +啟 +陷 +柴 +呈 +徒 +顏 +淚 +稍 +忘 +泵 +藍 +拖 +洞 +授 +鏡 +辛 +壯 +鋒 +貧 +虛 +彎 +摩 +泰 +幼 +廷 +尊 +窗 +綱 +弄 +隸 +疑 +氏 +宮 +姐 +震 +瑞 +怪 +尤 +琴 +循 +描 +膜 +違 +夾 +腰 +緣 +珠 +窮 +森 +枝 +竹 +溝 +催 +繩 +憶 +邦 +剩 +幸 +漿 +欄 +擁 +牙 +貯 +禮 +濾 +鈉 +紋 +罷 +拍 +咱 +喊 +袖 +埃 +勤 +罰 +焦 +潛 +伍 +墨 +欲 +縫 +姓 +刊 +飽 +仿 +獎 +鋁 +鬼 +麗 +跨 +默 +挖 +鏈 +掃 +喝 +袋 +炭 +污 +幕 +諸 +弧 +勵 +梅 +奶 +潔 +災 +舟 +鑑 +苯 +訟 +抱 +毀 +懂 +寒 +智 +埔 +寄 +屆 +躍 +渡 +挑 +丹 +艱 +貝 +碰 +拔 +爹 +戴 +碼 +夢 +芽 +熔 +赤 +漁 +哭 +敬 +顆 +奔 +鉛 +仲 +虎 +稀 +妹 +乏 +珍 +申 +桌 +遵 +允 +隆 +螺 +倉 +魏 +銳 +曉 +氮 +兼 +隱 +礙 +赫 +撥 +忠 +肅 +缸 +牽 +搶 +博 +巧 +殼 +兄 +杜 +訊 +誠 +碧 +祥 +柯 +頁 +巡 +矩 +悲 +灌 +齡 +倫 +票 +尋 +桂 +鋪 +聖 +恐 +恰 +鄭 +趣 +抬 +荒 +騰 +貼 +柔 +滴 +猛 +闊 +輛 +妻 +填 +撤 +儲 +簽 +鬧 +擾 +紫 +砂 +遞 +戲 +吊 +陶 +伐 +餵 +療 +瓶 +婆 +撫 +臂 +摸 +忍 +蝦 +蠟 +鄰 +胸 +鞏 +擠 +偶 +棄 +槽 +勁 +乳 +鄧 +吉 +仁 +爛 +磚 +租 +烏 +艦 +伴 +瓜 +淺 +丙 +暫 +燥 +橡 +柳 +迷 +暖 +牌 +秧 +膽 +詳 +簧 +踏 +瓷 +譜 +呆 +賓 +糊 +洛 +輝 +憤 +競 +隙 +怒 +粘 +乃 +緒 +肩 +籍 +敏 +塗 +熙 +皆 +偵 +懸 +掘 +享 +糾 +醒 +狂 +鎖 +淀 +恨 +牲 +霸 +爬 +賞 +逆 +玩 +陵 +祝 +秒 +浙 +貌 +役 +彼 +悉 +鴨 +趨 +鳳 +晨 +畜 +輩 +秩 +卵 +署 +梯 +炎 +灘 +棋 +驅 +篩 +峽 +冒 +啥 +壽 +譯 +浸 +泉 +帽 +遲 +矽 +疆 +貸 +漏 +稿 +冠 +嫩 +脅 +芯 +牢 +叛 +蝕 +奧 +鳴 +嶺 +羊 +憑 +串 +塘 +繪 +酵 +融 +盆 +錫 +廟 +籌 +凍 +輔 +攝 +襲 +筋 +拒 +僚 +旱 +鉀 +鳥 +漆 +沈 +眉 +疏 +添 +棒 +穗 +硝 +韓 +逼 +扭 +僑 +涼 +挺 +碗 +栽 +炒 +杯 +患 +餾 +勸 +豪 +遼 +勃 +鴻 +旦 +吏 +拜 +狗 +埋 +輥 +掩 +飲 +搬 +罵 +辭 +勾 +扣 +估 +蔣 +絨 +霧 +丈 +朵 +姆 +擬 +宇 +輯 +陝 +雕 +償 +蓄 +崇 +剪 +倡 +廳 +咬 +駛 +薯 +刷 +斥 +番 +賦 +奉 +佛 +澆 +漫 +曼 +扇 +鈣 +桃 +扶 +仔 +返 +俗 +虧 +腔 +鞋 +棱 +覆 +框 +悄 +叔 +撞 +騙 +勘 +旺 +沸 +孤 +吐 +孟 +渠 +屈 +疾 +妙 +惜 +仰 +狠 +脹 +諧 +拋 +黴 +桑 +崗 +嘛 +衰 +盜 +滲 +臟 +賴 +湧 +甜 +曹 +閱 +肌 +哩 +厲 +烴 +緯 +毅 +昨 +偽 +症 +煮 +嘆 +釘 +搭 +莖 +籠 +酷 +偷 +弓 +錐 +恆 +傑 +坑 +鼻 +翼 +綸 +敘 +獄 +逮 +罐 +絡 +棚 +抑 +膨 +蔬 +寺 +驟 +穆 +冶 +枯 +冊 +屍 +凸 +紳 +坯 +犧 +焰 +轟 +欣 +晉 +瘦 +禦 +錠 +錦 +喪 +旬 +鍛 +壟 +搜 +撲 +邀 +亭 +酯 +邁 +舒 +脆 +酶 +閒 +憂 +酚 +頑 +羽 +漲 +卸 +仗 +陪 +闢 +懲 +杭 +姚 +肚 +捉 +飄 +漂 +昆 +欺 +吾 +郎 +烷 +汁 +呵 +飾 +蕭 +雅 +郵 +遷 +燕 +撒 +姻 +赴 +宴 +煩 +債 +帳 +斑 +鈴 +旨 +醇 +董 +餅 +雛 +姿 +拌 +傅 +腹 +妥 +揉 +賢 +拆 +歪 +葡 +胺 +丟 +浩 +徽 +昂 +墊 +擋 +覽 +貪 +慰 +繳 +汪 +慌 +馮 +諾 +姜 +誼 +兇 +劣 +誣 +耀 +昏 +躺 +盈 +騎 +喬 +溪 +叢 +盧 +抹 +悶 +諮 +刮 +駕 +纜 +悟 +摘 +鉺 +擲 +頗 +幻 +柄 +惠 +慘 +佳 +仇 +臘 +窩 +滌 +劍 +瞧 +堡 +潑 +蔥 +罩 +霍 +撈 +胎 +蒼 +濱 +倆 +捅 +湘 +砍 +霞 +邵 +萄 +瘋 +淮 +遂 +熊 +糞 +烘 +宿 +檔 +戈 +駁 +嫂 +裕 +徙 +箭 +捐 +腸 +撐 +曬 +辨 +殿 +蓮 +攤 +攪 +醬 +屏 +疫 +哀 +蔡 +堵 +沫 +皺 +暢 +疊 +閣 +萊 +敲 +轄 +鉤 +痕 +壩 +巷 +餓 +禍 +丘 +玄 +溜 +曰 +邏 +彭 +嘗 +卿 +妨 +艇 +吞 +韋 +怨 +矮 +歇 +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/english.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/english.go new file mode 100644 index 00000000..f69e8a47 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/english.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt + // $ crc32 english.txt + // c1dbd296 + checksum := crc32.ChecksumIEEE([]byte(english)) + if fmt.Sprintf("%x", checksum) != "c1dbd296" { + panic("english checksum invalid") + } +} + +// English is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt +var English = strings.Split(strings.TrimSpace(english), "\n") +var english = `abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/italian.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/italian.go new file mode 100644 index 00000000..32cd2cf6 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/italian.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/italian.txt + // $ crc32 italian.txt + // 2fc7d07e + checksum := crc32.ChecksumIEEE([]byte(italian)) + if fmt.Sprintf("%x", checksum) != "2fc7d07e" { + panic("italian checksum invalid") + } +} + +// Italian is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/italian.txt +var Italian = strings.Split(strings.TrimSpace(italian), "\n") +var italian = `abaco +abbaglio +abbinato +abete +abisso +abolire +abrasivo +abrogato +accadere +accenno +accusato +acetone +achille +acido +acqua +acre +acrilico +acrobata +acuto +adagio +addebito +addome +adeguato +aderire +adipe +adottare +adulare +affabile +affetto +affisso +affranto +aforisma +afoso +africano +agave +agente +agevole +aggancio +agire +agitare +agonismo +agricolo +agrumeto +aguzzo +alabarda +alato +albatro +alberato +albo +albume +alce +alcolico +alettone +alfa +algebra +aliante +alibi +alimento +allagato +allegro +allievo +allodola +allusivo +almeno +alogeno +alpaca +alpestre +altalena +alterno +alticcio +altrove +alunno +alveolo +alzare +amalgama +amanita +amarena +ambito +ambrato +ameba +america +ametista +amico +ammasso +ammenda +ammirare +ammonito +amore +ampio +ampliare +amuleto +anacardo +anagrafe +analista +anarchia +anatra +anca +ancella +ancora +andare +andrea +anello +angelo +angolare +angusto +anima +annegare +annidato +anno +annuncio +anonimo +anticipo +anzi +apatico +apertura +apode +apparire +appetito +appoggio +approdo +appunto +aprile +arabica +arachide +aragosta +araldica +arancio +aratura +arazzo +arbitro +archivio +ardito +arenile +argento +argine +arguto +aria +armonia +arnese +arredato +arringa +arrosto +arsenico +arso +artefice +arzillo +asciutto +ascolto +asepsi +asettico +asfalto +asino +asola +aspirato +aspro +assaggio +asse +assoluto +assurdo +asta +astenuto +astice +astratto +atavico +ateismo +atomico +atono +attesa +attivare +attorno +attrito +attuale +ausilio +austria +autista +autonomo +autunno +avanzato +avere +avvenire +avviso +avvolgere +azione +azoto +azzimo +azzurro +babele +baccano +bacino +baco +badessa +badilata +bagnato +baita +balcone +baldo +balena +ballata +balzano +bambino +bandire +baraonda +barbaro +barca +baritono +barlume +barocco +basilico +basso +batosta +battuto +baule +bava +bavosa +becco +beffa +belgio +belva +benda +benevole +benigno +benzina +bere +berlina +beta +bibita +bici +bidone +bifido +biga +bilancia +bimbo +binocolo +biologo +bipede +bipolare +birbante +birra +biscotto +bisesto +bisnonno +bisonte +bisturi +bizzarro +blando +blatta +bollito +bonifico +bordo +bosco +botanico +bottino +bozzolo +braccio +bradipo +brama +branca +bravura +bretella +brevetto +brezza +briglia +brillante +brindare +broccolo +brodo +bronzina +brullo +bruno +bubbone +buca +budino +buffone +buio +bulbo +buono +burlone +burrasca +bussola +busta +cadetto +caduco +calamaro +calcolo +calesse +calibro +calmo +caloria +cambusa +camerata +camicia +cammino +camola +campale +canapa +candela +cane +canino +canotto +cantina +capace +capello +capitolo +capogiro +cappero +capra +capsula +carapace +carcassa +cardo +carisma +carovana +carretto +cartolina +casaccio +cascata +caserma +caso +cassone +castello +casuale +catasta +catena +catrame +cauto +cavillo +cedibile +cedrata +cefalo +celebre +cellulare +cena +cenone +centesimo +ceramica +cercare +certo +cerume +cervello +cesoia +cespo +ceto +chela +chiaro +chicca +chiedere +chimera +china +chirurgo +chitarra +ciao +ciclismo +cifrare +cigno +cilindro +ciottolo +circa +cirrosi +citrico +cittadino +ciuffo +civetta +civile +classico +clinica +cloro +cocco +codardo +codice +coerente +cognome +collare +colmato +colore +colposo +coltivato +colza +coma +cometa +commando +comodo +computer +comune +conciso +condurre +conferma +congelare +coniuge +connesso +conoscere +consumo +continuo +convegno +coperto +copione +coppia +copricapo +corazza +cordata +coricato +cornice +corolla +corpo +corredo +corsia +cortese +cosmico +costante +cottura +covato +cratere +cravatta +creato +credere +cremoso +crescita +creta +criceto +crinale +crisi +critico +croce +cronaca +crostata +cruciale +crusca +cucire +cuculo +cugino +cullato +cupola +curatore +cursore +curvo +cuscino +custode +dado +daino +dalmata +damerino +daniela +dannoso +danzare +datato +davanti +davvero +debutto +decennio +deciso +declino +decollo +decreto +dedicato +definito +deforme +degno +delegare +delfino +delirio +delta +demenza +denotato +dentro +deposito +derapata +derivare +deroga +descritto +deserto +desiderio +desumere +detersivo +devoto +diametro +dicembre +diedro +difeso +diffuso +digerire +digitale +diluvio +dinamico +dinnanzi +dipinto +diploma +dipolo +diradare +dire +dirotto +dirupo +disagio +discreto +disfare +disgelo +disposto +distanza +disumano +dito +divano +divelto +dividere +divorato +doblone +docente +doganale +dogma +dolce +domato +domenica +dominare +dondolo +dono +dormire +dote +dottore +dovuto +dozzina +drago +druido +dubbio +dubitare +ducale +duna +duomo +duplice +duraturo +ebano +eccesso +ecco +eclissi +economia +edera +edicola +edile +editoria +educare +egemonia +egli +egoismo +egregio +elaborato +elargire +elegante +elencato +eletto +elevare +elfico +elica +elmo +elsa +eluso +emanato +emblema +emesso +emiro +emotivo +emozione +empirico +emulo +endemico +enduro +energia +enfasi +enoteca +entrare +enzima +epatite +epilogo +episodio +epocale +eppure +equatore +erario +erba +erboso +erede +eremita +erigere +ermetico +eroe +erosivo +errante +esagono +esame +esanime +esaudire +esca +esempio +esercito +esibito +esigente +esistere +esito +esofago +esortato +esoso +espanso +espresso +essenza +esso +esteso +estimare +estonia +estroso +esultare +etilico +etnico +etrusco +etto +euclideo +europa +evaso +evidenza +evitato +evoluto +evviva +fabbrica +faccenda +fachiro +falco +famiglia +fanale +fanfara +fango +fantasma +fare +farfalla +farinoso +farmaco +fascia +fastoso +fasullo +faticare +fato +favoloso +febbre +fecola +fede +fegato +felpa +feltro +femmina +fendere +fenomeno +fermento +ferro +fertile +fessura +festivo +fetta +feudo +fiaba +fiducia +fifa +figurato +filo +finanza +finestra +finire +fiore +fiscale +fisico +fiume +flacone +flamenco +flebo +flemma +florido +fluente +fluoro +fobico +focaccia +focoso +foderato +foglio +folata +folclore +folgore +fondente +fonetico +fonia +fontana +forbito +forchetta +foresta +formica +fornaio +foro +fortezza +forzare +fosfato +fosso +fracasso +frana +frassino +fratello +freccetta +frenata +fresco +frigo +frollino +fronde +frugale +frutta +fucilata +fucsia +fuggente +fulmine +fulvo +fumante +fumetto +fumoso +fune +funzione +fuoco +furbo +furgone +furore +fuso +futile +gabbiano +gaffe +galateo +gallina +galoppo +gambero +gamma +garanzia +garbo +garofano +garzone +gasdotto +gasolio +gastrico +gatto +gaudio +gazebo +gazzella +geco +gelatina +gelso +gemello +gemmato +gene +genitore +gennaio +genotipo +gergo +ghepardo +ghiaccio +ghisa +giallo +gilda +ginepro +giocare +gioiello +giorno +giove +girato +girone +gittata +giudizio +giurato +giusto +globulo +glutine +gnomo +gobba +golf +gomito +gommone +gonfio +gonna +governo +gracile +grado +grafico +grammo +grande +grattare +gravoso +grazia +greca +gregge +grifone +grigio +grinza +grotta +gruppo +guadagno +guaio +guanto +guardare +gufo +guidare +ibernato +icona +identico +idillio +idolo +idra +idrico +idrogeno +igiene +ignaro +ignorato +ilare +illeso +illogico +illudere +imballo +imbevuto +imbocco +imbuto +immane +immerso +immolato +impacco +impeto +impiego +importo +impronta +inalare +inarcare +inattivo +incanto +incendio +inchino +incisivo +incluso +incontro +incrocio +incubo +indagine +india +indole +inedito +infatti +infilare +inflitto +ingaggio +ingegno +inglese +ingordo +ingrosso +innesco +inodore +inoltrare +inondato +insano +insetto +insieme +insonnia +insulina +intasato +intero +intonaco +intuito +inumidire +invalido +invece +invito +iperbole +ipnotico +ipotesi +ippica +iride +irlanda +ironico +irrigato +irrorare +isolato +isotopo +isterico +istituto +istrice +italia +iterare +labbro +labirinto +lacca +lacerato +lacrima +lacuna +laddove +lago +lampo +lancetta +lanterna +lardoso +larga +laringe +lastra +latenza +latino +lattuga +lavagna +lavoro +legale +leggero +lembo +lentezza +lenza +leone +lepre +lesivo +lessato +lesto +letterale +leva +levigato +libero +lido +lievito +lilla +limatura +limitare +limpido +lineare +lingua +liquido +lira +lirica +lisca +lite +litigio +livrea +locanda +lode +logica +lombare +londra +longevo +loquace +lorenzo +loto +lotteria +luce +lucidato +lumaca +luminoso +lungo +lupo +luppolo +lusinga +lusso +lutto +macabro +macchina +macero +macinato +madama +magico +maglia +magnete +magro +maiolica +malafede +malgrado +malinteso +malsano +malto +malumore +mana +mancia +mandorla +mangiare +manifesto +mannaro +manovra +mansarda +mantide +manubrio +mappa +maratona +marcire +maretta +marmo +marsupio +maschera +massaia +mastino +materasso +matricola +mattone +maturo +mazurca +meandro +meccanico +mecenate +medesimo +meditare +mega +melassa +melis +melodia +meninge +meno +mensola +mercurio +merenda +merlo +meschino +mese +messere +mestolo +metallo +metodo +mettere +miagolare +mica +micelio +michele +microbo +midollo +miele +migliore +milano +milite +mimosa +minerale +mini +minore +mirino +mirtillo +miscela +missiva +misto +misurare +mitezza +mitigare +mitra +mittente +mnemonico +modello +modifica +modulo +mogano +mogio +mole +molosso +monastero +monco +mondina +monetario +monile +monotono +monsone +montato +monviso +mora +mordere +morsicato +mostro +motivato +motosega +motto +movenza +movimento +mozzo +mucca +mucosa +muffa +mughetto +mugnaio +mulatto +mulinello +multiplo +mummia +munto +muovere +murale +musa +muscolo +musica +mutevole +muto +nababbo +nafta +nanometro +narciso +narice +narrato +nascere +nastrare +naturale +nautica +naviglio +nebulosa +necrosi +negativo +negozio +nemmeno +neofita +neretto +nervo +nessuno +nettuno +neutrale +neve +nevrotico +nicchia +ninfa +nitido +nobile +nocivo +nodo +nome +nomina +nordico +normale +norvegese +nostrano +notare +notizia +notturno +novella +nucleo +nulla +numero +nuovo +nutrire +nuvola +nuziale +oasi +obbedire +obbligo +obelisco +oblio +obolo +obsoleto +occasione +occhio +occidente +occorrere +occultare +ocra +oculato +odierno +odorare +offerta +offrire +offuscato +oggetto +oggi +ognuno +olandese +olfatto +oliato +oliva +ologramma +oltre +omaggio +ombelico +ombra +omega +omissione +ondoso +onere +onice +onnivoro +onorevole +onta +operato +opinione +opposto +oracolo +orafo +ordine +orecchino +orefice +orfano +organico +origine +orizzonte +orma +ormeggio +ornativo +orologio +orrendo +orribile +ortensia +ortica +orzata +orzo +osare +oscurare +osmosi +ospedale +ospite +ossa +ossidare +ostacolo +oste +otite +otre +ottagono +ottimo +ottobre +ovale +ovest +ovino +oviparo +ovocito +ovunque +ovviare +ozio +pacchetto +pace +pacifico +padella +padrone +paese +paga +pagina +palazzina +palesare +pallido +palo +palude +pandoro +pannello +paolo +paonazzo +paprica +parabola +parcella +parere +pargolo +pari +parlato +parola +partire +parvenza +parziale +passivo +pasticca +patacca +patologia +pattume +pavone +peccato +pedalare +pedonale +peggio +peloso +penare +pendice +penisola +pennuto +penombra +pensare +pentola +pepe +pepita +perbene +percorso +perdonato +perforare +pergamena +periodo +permesso +perno +perplesso +persuaso +pertugio +pervaso +pesatore +pesista +peso +pestifero +petalo +pettine +petulante +pezzo +piacere +pianta +piattino +piccino +picozza +piega +pietra +piffero +pigiama +pigolio +pigro +pila +pilifero +pillola +pilota +pimpante +pineta +pinna +pinolo +pioggia +piombo +piramide +piretico +pirite +pirolisi +pitone +pizzico +placebo +planare +plasma +platano +plenario +pochezza +poderoso +podismo +poesia +poggiare +polenta +poligono +pollice +polmonite +polpetta +polso +poltrona +polvere +pomice +pomodoro +ponte +popoloso +porfido +poroso +porpora +porre +portata +posa +positivo +possesso +postulato +potassio +potere +pranzo +prassi +pratica +precluso +predica +prefisso +pregiato +prelievo +premere +prenotare +preparato +presenza +pretesto +prevalso +prima +principe +privato +problema +procura +produrre +profumo +progetto +prolunga +promessa +pronome +proposta +proroga +proteso +prova +prudente +prugna +prurito +psiche +pubblico +pudica +pugilato +pugno +pulce +pulito +pulsante +puntare +pupazzo +pupilla +puro +quadro +qualcosa +quasi +querela +quota +raccolto +raddoppio +radicale +radunato +raffica +ragazzo +ragione +ragno +ramarro +ramingo +ramo +randagio +rantolare +rapato +rapina +rappreso +rasatura +raschiato +rasente +rassegna +rastrello +rata +ravveduto +reale +recepire +recinto +recluta +recondito +recupero +reddito +redimere +regalato +registro +regola +regresso +relazione +remare +remoto +renna +replica +reprimere +reputare +resa +residente +responso +restauro +rete +retina +retorica +rettifica +revocato +riassunto +ribadire +ribelle +ribrezzo +ricarica +ricco +ricevere +riciclato +ricordo +ricreduto +ridicolo +ridurre +rifasare +riflesso +riforma +rifugio +rigare +rigettato +righello +rilassato +rilevato +rimanere +rimbalzo +rimedio +rimorchio +rinascita +rincaro +rinforzo +rinnovo +rinomato +rinsavito +rintocco +rinuncia +rinvenire +riparato +ripetuto +ripieno +riportare +ripresa +ripulire +risata +rischio +riserva +risibile +riso +rispetto +ristoro +risultato +risvolto +ritardo +ritegno +ritmico +ritrovo +riunione +riva +riverso +rivincita +rivolto +rizoma +roba +robotico +robusto +roccia +roco +rodaggio +rodere +roditore +rogito +rollio +romantico +rompere +ronzio +rosolare +rospo +rotante +rotondo +rotula +rovescio +rubizzo +rubrica +ruga +rullino +rumine +rumoroso +ruolo +rupe +russare +rustico +sabato +sabbiare +sabotato +sagoma +salasso +saldatura +salgemma +salivare +salmone +salone +saltare +saluto +salvo +sapere +sapido +saporito +saraceno +sarcasmo +sarto +sassoso +satellite +satira +satollo +saturno +savana +savio +saziato +sbadiglio +sbalzo +sbancato +sbarra +sbattere +sbavare +sbendare +sbirciare +sbloccato +sbocciato +sbrinare +sbruffone +sbuffare +scabroso +scadenza +scala +scambiare +scandalo +scapola +scarso +scatenare +scavato +scelto +scenico +scettro +scheda +schiena +sciarpa +scienza +scindere +scippo +sciroppo +scivolo +sclerare +scodella +scolpito +scomparto +sconforto +scoprire +scorta +scossone +scozzese +scriba +scrollare +scrutinio +scuderia +scultore +scuola +scuro +scusare +sdebitare +sdoganare +seccatura +secondo +sedano +seggiola +segnalato +segregato +seguito +selciato +selettivo +sella +selvaggio +semaforo +sembrare +seme +seminato +sempre +senso +sentire +sepolto +sequenza +serata +serbato +sereno +serio +serpente +serraglio +servire +sestina +setola +settimana +sfacelo +sfaldare +sfamato +sfarzoso +sfaticato +sfera +sfida +sfilato +sfinge +sfocato +sfoderare +sfogo +sfoltire +sforzato +sfratto +sfruttato +sfuggito +sfumare +sfuso +sgabello +sgarbato +sgonfiare +sgorbio +sgrassato +sguardo +sibilo +siccome +sierra +sigla +signore +silenzio +sillaba +simbolo +simpatico +simulato +sinfonia +singolo +sinistro +sino +sintesi +sinusoide +sipario +sisma +sistole +situato +slitta +slogatura +sloveno +smarrito +smemorato +smentito +smeraldo +smilzo +smontare +smottato +smussato +snellire +snervato +snodo +sobbalzo +sobrio +soccorso +sociale +sodale +soffitto +sogno +soldato +solenne +solido +sollazzo +solo +solubile +solvente +somatico +somma +sonda +sonetto +sonnifero +sopire +soppeso +sopra +sorgere +sorpasso +sorriso +sorso +sorteggio +sorvolato +sospiro +sosta +sottile +spada +spalla +spargere +spatola +spavento +spazzola +specie +spedire +spegnere +spelatura +speranza +spessore +spettrale +spezzato +spia +spigoloso +spillato +spinoso +spirale +splendido +sportivo +sposo +spranga +sprecare +spronato +spruzzo +spuntino +squillo +sradicare +srotolato +stabile +stacco +staffa +stagnare +stampato +stantio +starnuto +stasera +statuto +stelo +steppa +sterzo +stiletto +stima +stirpe +stivale +stizzoso +stonato +storico +strappo +stregato +stridulo +strozzare +strutto +stuccare +stufo +stupendo +subentro +succoso +sudore +suggerito +sugo +sultano +suonare +superbo +supporto +surgelato +surrogato +sussurro +sutura +svagare +svedese +sveglio +svelare +svenuto +svezia +sviluppo +svista +svizzera +svolta +svuotare +tabacco +tabulato +tacciare +taciturno +tale +talismano +tampone +tannino +tara +tardivo +targato +tariffa +tarpare +tartaruga +tasto +tattico +taverna +tavolata +tazza +teca +tecnico +telefono +temerario +tempo +temuto +tendone +tenero +tensione +tentacolo +teorema +terme +terrazzo +terzetto +tesi +tesserato +testato +tetro +tettoia +tifare +tigella +timbro +tinto +tipico +tipografo +tiraggio +tiro +titanio +titolo +titubante +tizio +tizzone +toccare +tollerare +tolto +tombola +tomo +tonfo +tonsilla +topazio +topologia +toppa +torba +tornare +torrone +tortora +toscano +tossire +tostatura +totano +trabocco +trachea +trafila +tragedia +tralcio +tramonto +transito +trapano +trarre +trasloco +trattato +trave +treccia +tremolio +trespolo +tributo +tricheco +trifoglio +trillo +trincea +trio +tristezza +triturato +trivella +tromba +trono +troppo +trottola +trovare +truccato +tubatura +tuffato +tulipano +tumulto +tunisia +turbare +turchino +tuta +tutela +ubicato +uccello +uccisore +udire +uditivo +uffa +ufficio +uguale +ulisse +ultimato +umano +umile +umorismo +uncinetto +ungere +ungherese +unicorno +unificato +unisono +unitario +unte +uovo +upupa +uragano +urgenza +urlo +usanza +usato +uscito +usignolo +usuraio +utensile +utilizzo +utopia +vacante +vaccinato +vagabondo +vagliato +valanga +valgo +valico +valletta +valoroso +valutare +valvola +vampata +vangare +vanitoso +vano +vantaggio +vanvera +vapore +varano +varcato +variante +vasca +vedetta +vedova +veduto +vegetale +veicolo +velcro +velina +velluto +veloce +venato +vendemmia +vento +verace +verbale +vergogna +verifica +vero +verruca +verticale +vescica +vessillo +vestale +veterano +vetrina +vetusto +viandante +vibrante +vicenda +vichingo +vicinanza +vidimare +vigilia +vigneto +vigore +vile +villano +vimini +vincitore +viola +vipera +virgola +virologo +virulento +viscoso +visione +vispo +vissuto +visura +vita +vitello +vittima +vivanda +vivido +viziare +voce +voga +volatile +volere +volpe +voragine +vulcano +zampogna +zanna +zappato +zattera +zavorra +zefiro +zelante +zelo +zenzero +zerbino +zibetto +zinco +zircone +zitto +zolla +zotico +zucchero +zufolo +zulu +zuppa +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/japanese.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/japanese.go new file mode 100644 index 00000000..23a76a34 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/japanese.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/japanese.txt + // $ crc32 japanese.txt + // 0acc1419 + checksum := crc32.ChecksumIEEE([]byte(japanese)) + if fmt.Sprintf("%x", checksum) != "acc1419" { + panic(fmt.Sprintf("japanese checksum invalid: %x", checksum)) + } +} + +// Japanese is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/japanese.txt +var Japanese = strings.Split(strings.TrimSpace(japanese), "\n") +var japanese = `あいこくしん +あいさつ +あいだ +あおぞら +あかちゃん +あきる +あけがた +あける +あこがれる +あさい +あさひ +あしあと +あじわう +あずかる +あずき +あそぶ +あたえる +あたためる +あたりまえ +あたる +あつい +あつかう +あっしゅく +あつまり +あつめる +あてな +あてはまる +あひる +あぶら +あぶる +あふれる +あまい +あまど +あまやかす +あまり +あみもの +あめりか +あやまる +あゆむ +あらいぐま +あらし +あらすじ +あらためる +あらゆる +あらわす +ありがとう +あわせる +あわてる +あんい +あんがい +あんこ +あんぜん +あんてい +あんない +あんまり +いいだす +いおん +いがい +いがく +いきおい +いきなり +いきもの +いきる +いくじ +いくぶん +いけばな +いけん +いこう +いこく +いこつ +いさましい +いさん +いしき +いじゅう +いじょう +いじわる +いずみ +いずれ +いせい +いせえび +いせかい +いせき +いぜん +いそうろう +いそがしい +いだい +いだく +いたずら +いたみ +いたりあ +いちおう +いちじ +いちど +いちば +いちぶ +いちりゅう +いつか +いっしゅん +いっせい +いっそう +いったん +いっち +いってい +いっぽう +いてざ +いてん +いどう +いとこ +いない +いなか +いねむり +いのち +いのる +いはつ +いばる +いはん +いびき +いひん +いふく +いへん +いほう +いみん +いもうと +いもたれ +いもり +いやがる +いやす +いよかん +いよく +いらい +いらすと +いりぐち +いりょう +いれい +いれもの +いれる +いろえんぴつ +いわい +いわう +いわかん +いわば +いわゆる +いんげんまめ +いんさつ +いんしょう +いんよう +うえき +うえる +うおざ +うがい +うかぶ +うかべる +うきわ +うくらいな +うくれれ +うけたまわる +うけつけ +うけとる +うけもつ +うける +うごかす +うごく +うこん +うさぎ +うしなう +うしろがみ +うすい +うすぎ +うすぐらい +うすめる +うせつ +うちあわせ +うちがわ +うちき +うちゅう +うっかり +うつくしい +うったえる +うつる +うどん +うなぎ +うなじ +うなずく +うなる +うねる +うのう +うぶげ +うぶごえ +うまれる +うめる +うもう +うやまう +うよく +うらがえす +うらぐち +うらない +うりあげ +うりきれ +うるさい +うれしい +うれゆき +うれる +うろこ +うわき +うわさ +うんこう +うんちん +うんてん +うんどう +えいえん +えいが +えいきょう +えいご +えいせい +えいぶん +えいよう +えいわ +えおり +えがお +えがく +えきたい +えくせる +えしゃく +えすて +えつらん +えのぐ +えほうまき +えほん +えまき +えもじ +えもの +えらい +えらぶ +えりあ +えんえん +えんかい +えんぎ +えんげき +えんしゅう +えんぜつ +えんそく +えんちょう +えんとつ +おいかける +おいこす +おいしい +おいつく +おうえん +おうさま +おうじ +おうせつ +おうたい +おうふく +おうべい +おうよう +おえる +おおい +おおう +おおどおり +おおや +おおよそ +おかえり +おかず +おがむ +おかわり +おぎなう +おきる +おくさま +おくじょう +おくりがな +おくる +おくれる +おこす +おこなう +おこる +おさえる +おさない +おさめる +おしいれ +おしえる +おじぎ +おじさん +おしゃれ +おそらく +おそわる +おたがい +おたく +おだやか +おちつく +おっと +おつり +おでかけ +おとしもの +おとなしい +おどり +おどろかす +おばさん +おまいり +おめでとう +おもいで +おもう +おもたい +おもちゃ +おやつ +おやゆび +およぼす +おらんだ +おろす +おんがく +おんけい +おんしゃ +おんせん +おんだん +おんちゅう +おんどけい +かあつ +かいが +がいき +がいけん +がいこう +かいさつ +かいしゃ +かいすいよく +かいぜん +かいぞうど +かいつう +かいてん +かいとう +かいふく +がいへき +かいほう +かいよう +がいらい +かいわ +かえる +かおり +かかえる +かがく +かがし +かがみ +かくご +かくとく +かざる +がぞう +かたい +かたち +がちょう +がっきゅう +がっこう +がっさん +がっしょう +かなざわし +かのう +がはく +かぶか +かほう +かほご +かまう +かまぼこ +かめれおん +かゆい +かようび +からい +かるい +かろう +かわく +かわら +がんか +かんけい +かんこう +かんしゃ +かんそう +かんたん +かんち +がんばる +きあい +きあつ +きいろ +ぎいん +きうい +きうん +きえる +きおう +きおく +きおち +きおん +きかい +きかく +きかんしゃ +ききて +きくばり +きくらげ +きけんせい +きこう +きこえる +きこく +きさい +きさく +きさま +きさらぎ +ぎじかがく +ぎしき +ぎじたいけん +ぎじにってい +ぎじゅつしゃ +きすう +きせい +きせき +きせつ +きそう +きぞく +きぞん +きたえる +きちょう +きつえん +ぎっちり +きつつき +きつね +きてい +きどう +きどく +きない +きなが +きなこ +きぬごし +きねん +きのう +きのした +きはく +きびしい +きひん +きふく +きぶん +きぼう +きほん +きまる +きみつ +きむずかしい +きめる +きもだめし +きもち +きもの +きゃく +きやく +ぎゅうにく +きよう +きょうりゅう +きらい +きらく +きりん +きれい +きれつ +きろく +ぎろん +きわめる +ぎんいろ +きんかくじ +きんじょ +きんようび +ぐあい +くいず +くうかん +くうき +くうぐん +くうこう +ぐうせい +くうそう +ぐうたら +くうふく +くうぼ +くかん +くきょう +くげん +ぐこう +くさい +くさき +くさばな +くさる +くしゃみ +くしょう +くすのき +くすりゆび +くせげ +くせん +ぐたいてき +くださる +くたびれる +くちこみ +くちさき +くつした +ぐっすり +くつろぐ +くとうてん +くどく +くなん +くねくね +くのう +くふう +くみあわせ +くみたてる +くめる +くやくしょ +くらす +くらべる +くるま +くれる +くろう +くわしい +ぐんかん +ぐんしょく +ぐんたい +ぐんて +けあな +けいかく +けいけん +けいこ +けいさつ +げいじゅつ +けいたい +げいのうじん +けいれき +けいろ +けおとす +けおりもの +げきか +げきげん +げきだん +げきちん +げきとつ +げきは +げきやく +げこう +げこくじょう +げざい +けさき +げざん +けしき +けしごむ +けしょう +げすと +けたば +けちゃっぷ +けちらす +けつあつ +けつい +けつえき +けっこん +けつじょ +けっせき +けってい +けつまつ +げつようび +げつれい +けつろん +げどく +けとばす +けとる +けなげ +けなす +けなみ +けぬき +げねつ +けねん +けはい +げひん +けぶかい +げぼく +けまり +けみかる +けむし +けむり +けもの +けらい +けろけろ +けわしい +けんい +けんえつ +けんお +けんか +げんき +けんげん +けんこう +けんさく +けんしゅう +けんすう +げんそう +けんちく +けんてい +けんとう +けんない +けんにん +げんぶつ +けんま +けんみん +けんめい +けんらん +けんり +こあくま +こいぬ +こいびと +ごうい +こうえん +こうおん +こうかん +ごうきゅう +ごうけい +こうこう +こうさい +こうじ +こうすい +ごうせい +こうそく +こうたい +こうちゃ +こうつう +こうてい +こうどう +こうない +こうはい +ごうほう +ごうまん +こうもく +こうりつ +こえる +こおり +ごかい +ごがつ +ごかん +こくご +こくさい +こくとう +こくない +こくはく +こぐま +こけい +こける +ここのか +こころ +こさめ +こしつ +こすう +こせい +こせき +こぜん +こそだて +こたい +こたえる +こたつ +こちょう +こっか +こつこつ +こつばん +こつぶ +こてい +こてん +ことがら +ことし +ことば +ことり +こなごな +こねこね +このまま +このみ +このよ +ごはん +こひつじ +こふう +こふん +こぼれる +ごまあぶら +こまかい +ごますり +こまつな +こまる +こむぎこ +こもじ +こもち +こもの +こもん +こやく +こやま +こゆう +こゆび +こよい +こよう +こりる +これくしょん +ころっけ +こわもて +こわれる +こんいん +こんかい +こんき +こんしゅう +こんすい +こんだて +こんとん +こんなん +こんびに +こんぽん +こんまけ +こんや +こんれい +こんわく +ざいえき +さいかい +さいきん +ざいげん +ざいこ +さいしょ +さいせい +ざいたく +ざいちゅう +さいてき +ざいりょう +さうな +さかいし +さがす +さかな +さかみち +さがる +さぎょう +さくし +さくひん +さくら +さこく +さこつ +さずかる +ざせき +さたん +さつえい +ざつおん +ざっか +ざつがく +さっきょく +ざっし +さつじん +ざっそう +さつたば +さつまいも +さてい +さといも +さとう +さとおや +さとし +さとる +さのう +さばく +さびしい +さべつ +さほう +さほど +さます +さみしい +さみだれ +さむけ +さめる +さやえんどう +さゆう +さよう +さよく +さらだ +ざるそば +さわやか +さわる +さんいん +さんか +さんきゃく +さんこう +さんさい +ざんしょ +さんすう +さんせい +さんそ +さんち +さんま +さんみ +さんらん +しあい +しあげ +しあさって +しあわせ +しいく +しいん +しうち +しえい +しおけ +しかい +しかく +じかん +しごと +しすう +じだい +したうけ +したぎ +したて +したみ +しちょう +しちりん +しっかり +しつじ +しつもん +してい +してき +してつ +じてん +じどう +しなぎれ +しなもの +しなん +しねま +しねん +しのぐ +しのぶ +しはい +しばかり +しはつ +しはらい +しはん +しひょう +しふく +じぶん +しへい +しほう +しほん +しまう +しまる +しみん +しむける +じむしょ +しめい +しめる +しもん +しゃいん +しゃうん +しゃおん +じゃがいも +しやくしょ +しゃくほう +しゃけん +しゃこ +しゃざい +しゃしん +しゃせん +しゃそう +しゃたい +しゃちょう +しゃっきん +じゃま +しゃりん +しゃれい +じゆう +じゅうしょ +しゅくはく +じゅしん +しゅっせき +しゅみ +しゅらば +じゅんばん +しょうかい +しょくたく +しょっけん +しょどう +しょもつ +しらせる +しらべる +しんか +しんこう +じんじゃ +しんせいじ +しんちく +しんりん +すあげ +すあし +すあな +ずあん +すいえい +すいか +すいとう +ずいぶん +すいようび +すうがく +すうじつ +すうせん +すおどり +すきま +すくう +すくない +すける +すごい +すこし +ずさん +すずしい +すすむ +すすめる +すっかり +ずっしり +ずっと +すてき +すてる +すねる +すのこ +すはだ +すばらしい +ずひょう +ずぶぬれ +すぶり +すふれ +すべて +すべる +ずほう +すぼん +すまい +すめし +すもう +すやき +すらすら +するめ +すれちがう +すろっと +すわる +すんぜん +すんぽう +せあぶら +せいかつ +せいげん +せいじ +せいよう +せおう +せかいかん +せきにん +せきむ +せきゆ +せきらんうん +せけん +せこう +せすじ +せたい +せたけ +せっかく +せっきゃく +ぜっく +せっけん +せっこつ +せっさたくま +せつぞく +せつだん +せつでん +せっぱん +せつび +せつぶん +せつめい +せつりつ +せなか +せのび +せはば +せびろ +せぼね +せまい +せまる +せめる +せもたれ +せりふ +ぜんあく +せんい +せんえい +せんか +せんきょ +せんく +せんげん +ぜんご +せんさい +せんしゅ +せんすい +せんせい +せんぞ +せんたく +せんちょう +せんてい +せんとう +せんぬき +せんねん +せんぱい +ぜんぶ +ぜんぽう +せんむ +せんめんじょ +せんもん +せんやく +せんゆう +せんよう +ぜんら +ぜんりゃく +せんれい +せんろ +そあく +そいとげる +そいね +そうがんきょう +そうき +そうご +そうしん +そうだん +そうなん +そうび +そうめん +そうり +そえもの +そえん +そがい +そげき +そこう +そこそこ +そざい +そしな +そせい +そせん +そそぐ +そだてる +そつう +そつえん +そっかん +そつぎょう +そっけつ +そっこう +そっせん +そっと +そとがわ +そとづら +そなえる +そなた +そふぼ +そぼく +そぼろ +そまつ +そまる +そむく +そむりえ +そめる +そもそも +そよかぜ +そらまめ +そろう +そんかい +そんけい +そんざい +そんしつ +そんぞく +そんちょう +ぞんび +ぞんぶん +そんみん +たあい +たいいん +たいうん +たいえき +たいおう +だいがく +たいき +たいぐう +たいけん +たいこ +たいざい +だいじょうぶ +だいすき +たいせつ +たいそう +だいたい +たいちょう +たいてい +だいどころ +たいない +たいねつ +たいのう +たいはん +だいひょう +たいふう +たいへん +たいほ +たいまつばな +たいみんぐ +たいむ +たいめん +たいやき +たいよう +たいら +たいりょく +たいる +たいわん +たうえ +たえる +たおす +たおる +たおれる +たかい +たかね +たきび +たくさん +たこく +たこやき +たさい +たしざん +だじゃれ +たすける +たずさわる +たそがれ +たたかう +たたく +ただしい +たたみ +たちばな +だっかい +だっきゃく +だっこ +だっしゅつ +だったい +たてる +たとえる +たなばた +たにん +たぬき +たのしみ +たはつ +たぶん +たべる +たぼう +たまご +たまる +だむる +ためいき +ためす +ためる +たもつ +たやすい +たよる +たらす +たりきほんがん +たりょう +たりる +たると +たれる +たれんと +たろっと +たわむれる +だんあつ +たんい +たんおん +たんか +たんき +たんけん +たんご +たんさん +たんじょうび +だんせい +たんそく +たんたい +だんち +たんてい +たんとう +だんな +たんにん +だんねつ +たんのう +たんぴん +だんぼう +たんまつ +たんめい +だんれつ +だんろ +だんわ +ちあい +ちあん +ちいき +ちいさい +ちえん +ちかい +ちから +ちきゅう +ちきん +ちけいず +ちけん +ちこく +ちさい +ちしき +ちしりょう +ちせい +ちそう +ちたい +ちたん +ちちおや +ちつじょ +ちてき +ちてん +ちぬき +ちぬり +ちのう +ちひょう +ちへいせん +ちほう +ちまた +ちみつ +ちみどろ +ちめいど +ちゃんこなべ +ちゅうい +ちゆりょく +ちょうし +ちょさくけん +ちらし +ちらみ +ちりがみ +ちりょう +ちるど +ちわわ +ちんたい +ちんもく +ついか +ついたち +つうか +つうじょう +つうはん +つうわ +つかう +つかれる +つくね +つくる +つけね +つける +つごう +つたえる +つづく +つつじ +つつむ +つとめる +つながる +つなみ +つねづね +つのる +つぶす +つまらない +つまる +つみき +つめたい +つもり +つもる +つよい +つるぼ +つるみく +つわもの +つわり +てあし +てあて +てあみ +ていおん +ていか +ていき +ていけい +ていこく +ていさつ +ていし +ていせい +ていたい +ていど +ていねい +ていひょう +ていへん +ていぼう +てうち +ておくれ +てきとう +てくび +でこぼこ +てさぎょう +てさげ +てすり +てそう +てちがい +てちょう +てつがく +てつづき +でっぱ +てつぼう +てつや +でぬかえ +てぬき +てぬぐい +てのひら +てはい +てぶくろ +てふだ +てほどき +てほん +てまえ +てまきずし +てみじか +てみやげ +てらす +てれび +てわけ +てわたし +でんあつ +てんいん +てんかい +てんき +てんぐ +てんけん +てんごく +てんさい +てんし +てんすう +でんち +てんてき +てんとう +てんない +てんぷら +てんぼうだい +てんめつ +てんらんかい +でんりょく +でんわ +どあい +といれ +どうかん +とうきゅう +どうぐ +とうし +とうむぎ +とおい +とおか +とおく +とおす +とおる +とかい +とかす +ときおり +ときどき +とくい +とくしゅう +とくてん +とくに +とくべつ +とけい +とける +とこや +とさか +としょかん +とそう +とたん +とちゅう +とっきゅう +とっくん +とつぜん +とつにゅう +とどける +ととのえる +とない +となえる +となり +とのさま +とばす +どぶがわ +とほう +とまる +とめる +ともだち +ともる +どようび +とらえる +とんかつ +どんぶり +ないかく +ないこう +ないしょ +ないす +ないせん +ないそう +なおす +ながい +なくす +なげる +なこうど +なさけ +なたでここ +なっとう +なつやすみ +ななおし +なにごと +なにもの +なにわ +なのか +なふだ +なまいき +なまえ +なまみ +なみだ +なめらか +なめる +なやむ +ならう +ならび +ならぶ +なれる +なわとび +なわばり +にあう +にいがた +にうけ +におい +にかい +にがて +にきび +にくしみ +にくまん +にげる +にさんかたんそ +にしき +にせもの +にちじょう +にちようび +にっか +にっき +にっけい +にっこう +にっさん +にっしょく +にっすう +にっせき +にってい +になう +にほん +にまめ +にもつ +にやり +にゅういん +にりんしゃ +にわとり +にんい +にんか +にんき +にんげん +にんしき +にんずう +にんそう +にんたい +にんち +にんてい +にんにく +にんぷ +にんまり +にんむ +にんめい +にんよう +ぬいくぎ +ぬかす +ぬぐいとる +ぬぐう +ぬくもり +ぬすむ +ぬまえび +ぬめり +ぬらす +ぬんちゃく +ねあげ +ねいき +ねいる +ねいろ +ねぐせ +ねくたい +ねくら +ねこぜ +ねこむ +ねさげ +ねすごす +ねそべる +ねだん +ねつい +ねっしん +ねつぞう +ねったいぎょ +ねぶそく +ねふだ +ねぼう +ねほりはほり +ねまき +ねまわし +ねみみ +ねむい +ねむたい +ねもと +ねらう +ねわざ +ねんいり +ねんおし +ねんかん +ねんきん +ねんぐ +ねんざ +ねんし +ねんちゃく +ねんど +ねんぴ +ねんぶつ +ねんまつ +ねんりょう +ねんれい +のいず +のおづま +のがす +のきなみ +のこぎり +のこす +のこる +のせる +のぞく +のぞむ +のたまう +のちほど +のっく +のばす +のはら +のべる +のぼる +のみもの +のやま +のらいぬ +のらねこ +のりもの +のりゆき +のれん +のんき +ばあい +はあく +ばあさん +ばいか +ばいく +はいけん +はいご +はいしん +はいすい +はいせん +はいそう +はいち +ばいばい +はいれつ +はえる +はおる +はかい +ばかり +はかる +はくしゅ +はけん +はこぶ +はさみ +はさん +はしご +ばしょ +はしる +はせる +ぱそこん +はそん +はたん +はちみつ +はつおん +はっかく +はづき +はっきり +はっくつ +はっけん +はっこう +はっさん +はっしん +はったつ +はっちゅう +はってん +はっぴょう +はっぽう +はなす +はなび +はにかむ +はぶらし +はみがき +はむかう +はめつ +はやい +はやし +はらう +はろうぃん +はわい +はんい +はんえい +はんおん +はんかく +はんきょう +ばんぐみ +はんこ +はんしゃ +はんすう +はんだん +ぱんち +ぱんつ +はんてい +はんとし +はんのう +はんぱ +はんぶん +はんぺん +はんぼうき +はんめい +はんらん +はんろん +ひいき +ひうん +ひえる +ひかく +ひかり +ひかる +ひかん +ひくい +ひけつ +ひこうき +ひこく +ひさい +ひさしぶり +ひさん +びじゅつかん +ひしょ +ひそか +ひそむ +ひたむき +ひだり +ひたる +ひつぎ +ひっこし +ひっし +ひつじゅひん +ひっす +ひつぜん +ぴったり +ぴっちり +ひつよう +ひてい +ひとごみ +ひなまつり +ひなん +ひねる +ひはん +ひびく +ひひょう +ひほう +ひまわり +ひまん +ひみつ +ひめい +ひめじし +ひやけ +ひやす +ひよう +びょうき +ひらがな +ひらく +ひりつ +ひりょう +ひるま +ひるやすみ +ひれい +ひろい +ひろう +ひろき +ひろゆき +ひんかく +ひんけつ +ひんこん +ひんしゅ +ひんそう +ぴんち +ひんぱん +びんぼう +ふあん +ふいうち +ふうけい +ふうせん +ぷうたろう +ふうとう +ふうふ +ふえる +ふおん +ふかい +ふきん +ふくざつ +ふくぶくろ +ふこう +ふさい +ふしぎ +ふじみ +ふすま +ふせい +ふせぐ +ふそく +ぶたにく +ふたん +ふちょう +ふつう +ふつか +ふっかつ +ふっき +ふっこく +ぶどう +ふとる +ふとん +ふのう +ふはい +ふひょう +ふへん +ふまん +ふみん +ふめつ +ふめん +ふよう +ふりこ +ふりる +ふるい +ふんいき +ぶんがく +ぶんぐ +ふんしつ +ぶんせき +ふんそう +ぶんぽう +へいあん +へいおん +へいがい +へいき +へいげん +へいこう +へいさ +へいしゃ +へいせつ +へいそ +へいたく +へいてん +へいねつ +へいわ +へきが +へこむ +べにいろ +べにしょうが +へらす +へんかん +べんきょう +べんごし +へんさい +へんたい +べんり +ほあん +ほいく +ぼうぎょ +ほうこく +ほうそう +ほうほう +ほうもん +ほうりつ +ほえる +ほおん +ほかん +ほきょう +ぼきん +ほくろ +ほけつ +ほけん +ほこう +ほこる +ほしい +ほしつ +ほしゅ +ほしょう +ほせい +ほそい +ほそく +ほたて +ほたる +ぽちぶくろ +ほっきょく +ほっさ +ほったん +ほとんど +ほめる +ほんい +ほんき +ほんけ +ほんしつ +ほんやく +まいにち +まかい +まかせる +まがる +まける +まこと +まさつ +まじめ +ますく +まぜる +まつり +まとめ +まなぶ +まぬけ +まねく +まほう +まもる +まゆげ +まよう +まろやか +まわす +まわり +まわる +まんが +まんきつ +まんぞく +まんなか +みいら +みうち +みえる +みがく +みかた +みかん +みけん +みこん +みじかい +みすい +みすえる +みせる +みっか +みつかる +みつける +みてい +みとめる +みなと +みなみかさい +みねらる +みのう +みのがす +みほん +みもと +みやげ +みらい +みりょく +みわく +みんか +みんぞく +むいか +むえき +むえん +むかい +むかう +むかえ +むかし +むぎちゃ +むける +むげん +むさぼる +むしあつい +むしば +むじゅん +むしろ +むすう +むすこ +むすぶ +むすめ +むせる +むせん +むちゅう +むなしい +むのう +むやみ +むよう +むらさき +むりょう +むろん +めいあん +めいうん +めいえん +めいかく +めいきょく +めいさい +めいし +めいそう +めいぶつ +めいれい +めいわく +めぐまれる +めざす +めした +めずらしい +めだつ +めまい +めやす +めんきょ +めんせき +めんどう +もうしあげる +もうどうけん +もえる +もくし +もくてき +もくようび +もちろん +もどる +もらう +もんく +もんだい +やおや +やける +やさい +やさしい +やすい +やすたろう +やすみ +やせる +やそう +やたい +やちん +やっと +やっぱり +やぶる +やめる +ややこしい +やよい +やわらかい +ゆうき +ゆうびんきょく +ゆうべ +ゆうめい +ゆけつ +ゆしゅつ +ゆせん +ゆそう +ゆたか +ゆちゃく +ゆでる +ゆにゅう +ゆびわ +ゆらい +ゆれる +ようい +ようか +ようきゅう +ようじ +ようす +ようちえん +よかぜ +よかん +よきん +よくせい +よくぼう +よけい +よごれる +よさん +よしゅう +よそう +よそく +よっか +よてい +よどがわく +よねつ +よやく +よゆう +よろこぶ +よろしい +らいう +らくがき +らくご +らくさつ +らくだ +らしんばん +らせん +らぞく +らたい +らっか +られつ +りえき +りかい +りきさく +りきせつ +りくぐん +りくつ +りけん +りこう +りせい +りそう +りそく +りてん +りねん +りゆう +りゅうがく +りよう +りょうり +りょかん +りょくちゃ +りょこう +りりく +りれき +りろん +りんご +るいけい +るいさい +るいじ +るいせき +るすばん +るりがわら +れいかん +れいぎ +れいせい +れいぞうこ +れいとう +れいぼう +れきし +れきだい +れんあい +れんけい +れんこん +れんさい +れんしゅう +れんぞく +れんらく +ろうか +ろうご +ろうじん +ろうそく +ろくが +ろこつ +ろじうら +ろしゅつ +ろせん +ろてん +ろめん +ろれつ +ろんぎ +ろんぱ +ろんぶん +ろんり +わかす +わかめ +わかやま +わかれる +わしつ +わじまし +わすれもの +わらう +われる +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/korean.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/korean.go new file mode 100644 index 00000000..1d317756 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/korean.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/korean.txt + // $ crc32 korean.txt + // 4ef461eb + checksum := crc32.ChecksumIEEE([]byte(korean)) + if fmt.Sprintf("%x", checksum) != "4ef461eb" { + panic("korean checksum invalid") + } +} + +// Korean is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/korean.txt +var Korean = strings.Split(strings.TrimSpace(korean), "\n") +var korean = `가격 +가끔 +가난 +가능 +가득 +가르침 +가뭄 +가방 +가상 +가슴 +가운데 +가을 +가이드 +가입 +가장 +가정 +가족 +가죽 +각오 +각자 +간격 +간부 +간섭 +간장 +간접 +간판 +갈등 +갈비 +갈색 +갈증 +감각 +감기 +감소 +감수성 +감자 +감정 +갑자기 +강남 +강당 +강도 +강력히 +강변 +강북 +강사 +강수량 +강아지 +강원도 +강의 +강제 +강조 +같이 +개구리 +개나리 +개방 +개별 +개선 +개성 +개인 +객관적 +거실 +거액 +거울 +거짓 +거품 +걱정 +건강 +건물 +건설 +건조 +건축 +걸음 +검사 +검토 +게시판 +게임 +겨울 +견해 +결과 +결국 +결론 +결석 +결승 +결심 +결정 +결혼 +경계 +경고 +경기 +경력 +경복궁 +경비 +경상도 +경영 +경우 +경쟁 +경제 +경주 +경찰 +경치 +경향 +경험 +계곡 +계단 +계란 +계산 +계속 +계약 +계절 +계층 +계획 +고객 +고구려 +고궁 +고급 +고등학생 +고무신 +고민 +고양이 +고장 +고전 +고집 +고춧가루 +고통 +고향 +곡식 +골목 +골짜기 +골프 +공간 +공개 +공격 +공군 +공급 +공기 +공동 +공무원 +공부 +공사 +공식 +공업 +공연 +공원 +공장 +공짜 +공책 +공통 +공포 +공항 +공휴일 +과목 +과일 +과장 +과정 +과학 +관객 +관계 +관광 +관념 +관람 +관련 +관리 +관습 +관심 +관점 +관찰 +광경 +광고 +광장 +광주 +괴로움 +굉장히 +교과서 +교문 +교복 +교실 +교양 +교육 +교장 +교직 +교통 +교환 +교훈 +구경 +구름 +구멍 +구별 +구분 +구석 +구성 +구속 +구역 +구입 +구청 +구체적 +국가 +국기 +국내 +국립 +국물 +국민 +국수 +국어 +국왕 +국적 +국제 +국회 +군대 +군사 +군인 +궁극적 +권리 +권위 +권투 +귀국 +귀신 +규정 +규칙 +균형 +그날 +그냥 +그늘 +그러나 +그룹 +그릇 +그림 +그제서야 +그토록 +극복 +극히 +근거 +근교 +근래 +근로 +근무 +근본 +근원 +근육 +근처 +글씨 +글자 +금강산 +금고 +금년 +금메달 +금액 +금연 +금요일 +금지 +긍정적 +기간 +기관 +기념 +기능 +기독교 +기둥 +기록 +기름 +기법 +기본 +기분 +기쁨 +기숙사 +기술 +기억 +기업 +기온 +기운 +기원 +기적 +기준 +기침 +기혼 +기획 +긴급 +긴장 +길이 +김밥 +김치 +김포공항 +깍두기 +깜빡 +깨달음 +깨소금 +껍질 +꼭대기 +꽃잎 +나들이 +나란히 +나머지 +나물 +나침반 +나흘 +낙엽 +난방 +날개 +날씨 +날짜 +남녀 +남대문 +남매 +남산 +남자 +남편 +남학생 +낭비 +낱말 +내년 +내용 +내일 +냄비 +냄새 +냇물 +냉동 +냉면 +냉방 +냉장고 +넥타이 +넷째 +노동 +노란색 +노력 +노인 +녹음 +녹차 +녹화 +논리 +논문 +논쟁 +놀이 +농구 +농담 +농민 +농부 +농업 +농장 +농촌 +높이 +눈동자 +눈물 +눈썹 +뉴욕 +느낌 +늑대 +능동적 +능력 +다방 +다양성 +다음 +다이어트 +다행 +단계 +단골 +단독 +단맛 +단순 +단어 +단위 +단점 +단체 +단추 +단편 +단풍 +달걀 +달러 +달력 +달리 +닭고기 +담당 +담배 +담요 +담임 +답변 +답장 +당근 +당분간 +당연히 +당장 +대규모 +대낮 +대단히 +대답 +대도시 +대략 +대량 +대륙 +대문 +대부분 +대신 +대응 +대장 +대전 +대접 +대중 +대책 +대출 +대충 +대통령 +대학 +대한민국 +대합실 +대형 +덩어리 +데이트 +도대체 +도덕 +도둑 +도망 +도서관 +도심 +도움 +도입 +도자기 +도저히 +도전 +도중 +도착 +독감 +독립 +독서 +독일 +독창적 +동화책 +뒷모습 +뒷산 +딸아이 +마누라 +마늘 +마당 +마라톤 +마련 +마무리 +마사지 +마약 +마요네즈 +마을 +마음 +마이크 +마중 +마지막 +마찬가지 +마찰 +마흔 +막걸리 +막내 +막상 +만남 +만두 +만세 +만약 +만일 +만점 +만족 +만화 +많이 +말기 +말씀 +말투 +맘대로 +망원경 +매년 +매달 +매력 +매번 +매스컴 +매일 +매장 +맥주 +먹이 +먼저 +먼지 +멀리 +메일 +며느리 +며칠 +면담 +멸치 +명단 +명령 +명예 +명의 +명절 +명칭 +명함 +모금 +모니터 +모델 +모든 +모범 +모습 +모양 +모임 +모조리 +모집 +모퉁이 +목걸이 +목록 +목사 +목소리 +목숨 +목적 +목표 +몰래 +몸매 +몸무게 +몸살 +몸속 +몸짓 +몸통 +몹시 +무관심 +무궁화 +무더위 +무덤 +무릎 +무슨 +무엇 +무역 +무용 +무조건 +무지개 +무척 +문구 +문득 +문법 +문서 +문제 +문학 +문화 +물가 +물건 +물결 +물고기 +물론 +물리학 +물음 +물질 +물체 +미국 +미디어 +미사일 +미술 +미역 +미용실 +미움 +미인 +미팅 +미혼 +민간 +민족 +민주 +믿음 +밀가루 +밀리미터 +밑바닥 +바가지 +바구니 +바나나 +바늘 +바닥 +바닷가 +바람 +바이러스 +바탕 +박물관 +박사 +박수 +반대 +반드시 +반말 +반발 +반성 +반응 +반장 +반죽 +반지 +반찬 +받침 +발가락 +발걸음 +발견 +발달 +발레 +발목 +발바닥 +발생 +발음 +발자국 +발전 +발톱 +발표 +밤하늘 +밥그릇 +밥맛 +밥상 +밥솥 +방금 +방면 +방문 +방바닥 +방법 +방송 +방식 +방안 +방울 +방지 +방학 +방해 +방향 +배경 +배꼽 +배달 +배드민턴 +백두산 +백색 +백성 +백인 +백제 +백화점 +버릇 +버섯 +버튼 +번개 +번역 +번지 +번호 +벌금 +벌레 +벌써 +범위 +범인 +범죄 +법률 +법원 +법적 +법칙 +베이징 +벨트 +변경 +변동 +변명 +변신 +변호사 +변화 +별도 +별명 +별일 +병실 +병아리 +병원 +보관 +보너스 +보라색 +보람 +보름 +보상 +보안 +보자기 +보장 +보전 +보존 +보통 +보편적 +보험 +복도 +복사 +복숭아 +복습 +볶음 +본격적 +본래 +본부 +본사 +본성 +본인 +본질 +볼펜 +봉사 +봉지 +봉투 +부근 +부끄러움 +부담 +부동산 +부문 +부분 +부산 +부상 +부엌 +부인 +부작용 +부장 +부정 +부족 +부지런히 +부친 +부탁 +부품 +부회장 +북부 +북한 +분노 +분량 +분리 +분명 +분석 +분야 +분위기 +분필 +분홍색 +불고기 +불과 +불교 +불꽃 +불만 +불법 +불빛 +불안 +불이익 +불행 +브랜드 +비극 +비난 +비닐 +비둘기 +비디오 +비로소 +비만 +비명 +비밀 +비바람 +비빔밥 +비상 +비용 +비율 +비중 +비타민 +비판 +빌딩 +빗물 +빗방울 +빗줄기 +빛깔 +빨간색 +빨래 +빨리 +사건 +사계절 +사나이 +사냥 +사람 +사랑 +사립 +사모님 +사물 +사방 +사상 +사생활 +사설 +사슴 +사실 +사업 +사용 +사월 +사장 +사전 +사진 +사촌 +사춘기 +사탕 +사투리 +사흘 +산길 +산부인과 +산업 +산책 +살림 +살인 +살짝 +삼계탕 +삼국 +삼십 +삼월 +삼촌 +상관 +상금 +상대 +상류 +상반기 +상상 +상식 +상업 +상인 +상자 +상점 +상처 +상추 +상태 +상표 +상품 +상황 +새벽 +색깔 +색연필 +생각 +생명 +생물 +생방송 +생산 +생선 +생신 +생일 +생활 +서랍 +서른 +서명 +서민 +서비스 +서양 +서울 +서적 +서점 +서쪽 +서클 +석사 +석유 +선거 +선물 +선배 +선생 +선수 +선원 +선장 +선전 +선택 +선풍기 +설거지 +설날 +설렁탕 +설명 +설문 +설사 +설악산 +설치 +설탕 +섭씨 +성공 +성당 +성명 +성별 +성인 +성장 +성적 +성질 +성함 +세금 +세미나 +세상 +세월 +세종대왕 +세탁 +센터 +센티미터 +셋째 +소규모 +소극적 +소금 +소나기 +소년 +소득 +소망 +소문 +소설 +소속 +소아과 +소용 +소원 +소음 +소중히 +소지품 +소질 +소풍 +소형 +속담 +속도 +속옷 +손가락 +손길 +손녀 +손님 +손등 +손목 +손뼉 +손실 +손질 +손톱 +손해 +솔직히 +솜씨 +송아지 +송이 +송편 +쇠고기 +쇼핑 +수건 +수년 +수단 +수돗물 +수동적 +수면 +수명 +수박 +수상 +수석 +수술 +수시로 +수업 +수염 +수영 +수입 +수준 +수집 +수출 +수컷 +수필 +수학 +수험생 +수화기 +숙녀 +숙소 +숙제 +순간 +순서 +순수 +순식간 +순위 +숟가락 +술병 +술집 +숫자 +스님 +스물 +스스로 +스승 +스웨터 +스위치 +스케이트 +스튜디오 +스트레스 +스포츠 +슬쩍 +슬픔 +습관 +습기 +승객 +승리 +승부 +승용차 +승진 +시각 +시간 +시골 +시금치 +시나리오 +시댁 +시리즈 +시멘트 +시민 +시부모 +시선 +시설 +시스템 +시아버지 +시어머니 +시월 +시인 +시일 +시작 +시장 +시절 +시점 +시중 +시즌 +시집 +시청 +시합 +시험 +식구 +식기 +식당 +식량 +식료품 +식물 +식빵 +식사 +식생활 +식초 +식탁 +식품 +신고 +신규 +신념 +신문 +신발 +신비 +신사 +신세 +신용 +신제품 +신청 +신체 +신화 +실감 +실내 +실력 +실례 +실망 +실수 +실습 +실시 +실장 +실정 +실질적 +실천 +실체 +실컷 +실태 +실패 +실험 +실현 +심리 +심부름 +심사 +심장 +심정 +심판 +쌍둥이 +씨름 +씨앗 +아가씨 +아나운서 +아드님 +아들 +아쉬움 +아스팔트 +아시아 +아울러 +아저씨 +아줌마 +아직 +아침 +아파트 +아프리카 +아픔 +아홉 +아흔 +악기 +악몽 +악수 +안개 +안경 +안과 +안내 +안녕 +안동 +안방 +안부 +안주 +알루미늄 +알코올 +암시 +암컷 +압력 +앞날 +앞문 +애인 +애정 +액수 +앨범 +야간 +야단 +야옹 +약간 +약국 +약속 +약수 +약점 +약품 +약혼녀 +양념 +양력 +양말 +양배추 +양주 +양파 +어둠 +어려움 +어른 +어젯밤 +어쨌든 +어쩌다가 +어쩐지 +언니 +언덕 +언론 +언어 +얼굴 +얼른 +얼음 +얼핏 +엄마 +업무 +업종 +업체 +엉덩이 +엉망 +엉터리 +엊그제 +에너지 +에어컨 +엔진 +여건 +여고생 +여관 +여군 +여권 +여대생 +여덟 +여동생 +여든 +여론 +여름 +여섯 +여성 +여왕 +여인 +여전히 +여직원 +여학생 +여행 +역사 +역시 +역할 +연결 +연구 +연극 +연기 +연락 +연설 +연세 +연속 +연습 +연애 +연예인 +연인 +연장 +연주 +연출 +연필 +연합 +연휴 +열기 +열매 +열쇠 +열심히 +열정 +열차 +열흘 +염려 +엽서 +영국 +영남 +영상 +영양 +영역 +영웅 +영원히 +영하 +영향 +영혼 +영화 +옆구리 +옆방 +옆집 +예감 +예금 +예방 +예산 +예상 +예선 +예술 +예습 +예식장 +예약 +예전 +예절 +예정 +예컨대 +옛날 +오늘 +오락 +오랫동안 +오렌지 +오로지 +오른발 +오븐 +오십 +오염 +오월 +오전 +오직 +오징어 +오페라 +오피스텔 +오히려 +옥상 +옥수수 +온갖 +온라인 +온몸 +온종일 +온통 +올가을 +올림픽 +올해 +옷차림 +와이셔츠 +와인 +완성 +완전 +왕비 +왕자 +왜냐하면 +왠지 +외갓집 +외국 +외로움 +외삼촌 +외출 +외침 +외할머니 +왼발 +왼손 +왼쪽 +요금 +요일 +요즘 +요청 +용기 +용서 +용어 +우산 +우선 +우승 +우연히 +우정 +우체국 +우편 +운동 +운명 +운반 +운전 +운행 +울산 +울음 +움직임 +웃어른 +웃음 +워낙 +원고 +원래 +원서 +원숭이 +원인 +원장 +원피스 +월급 +월드컵 +월세 +월요일 +웨이터 +위반 +위법 +위성 +위원 +위험 +위협 +윗사람 +유난히 +유럽 +유명 +유물 +유산 +유적 +유치원 +유학 +유행 +유형 +육군 +육상 +육십 +육체 +은행 +음력 +음료 +음반 +음성 +음식 +음악 +음주 +의견 +의논 +의문 +의복 +의식 +의심 +의외로 +의욕 +의원 +의학 +이것 +이곳 +이념 +이놈 +이달 +이대로 +이동 +이렇게 +이력서 +이론적 +이름 +이민 +이발소 +이별 +이불 +이빨 +이상 +이성 +이슬 +이야기 +이용 +이웃 +이월 +이윽고 +이익 +이전 +이중 +이튿날 +이틀 +이혼 +인간 +인격 +인공 +인구 +인근 +인기 +인도 +인류 +인물 +인생 +인쇄 +인연 +인원 +인재 +인종 +인천 +인체 +인터넷 +인하 +인형 +일곱 +일기 +일단 +일대 +일등 +일반 +일본 +일부 +일상 +일생 +일손 +일요일 +일월 +일정 +일종 +일주일 +일찍 +일체 +일치 +일행 +일회용 +임금 +임무 +입대 +입력 +입맛 +입사 +입술 +입시 +입원 +입장 +입학 +자가용 +자격 +자극 +자동 +자랑 +자부심 +자식 +자신 +자연 +자원 +자율 +자전거 +자정 +자존심 +자판 +작가 +작년 +작성 +작업 +작용 +작은딸 +작품 +잔디 +잔뜩 +잔치 +잘못 +잠깐 +잠수함 +잠시 +잠옷 +잠자리 +잡지 +장관 +장군 +장기간 +장래 +장례 +장르 +장마 +장면 +장모 +장미 +장비 +장사 +장소 +장식 +장애인 +장인 +장점 +장차 +장학금 +재능 +재빨리 +재산 +재생 +재작년 +재정 +재채기 +재판 +재학 +재활용 +저것 +저고리 +저곳 +저녁 +저런 +저렇게 +저번 +저울 +저절로 +저축 +적극 +적당히 +적성 +적용 +적응 +전개 +전공 +전기 +전달 +전라도 +전망 +전문 +전반 +전부 +전세 +전시 +전용 +전자 +전쟁 +전주 +전철 +전체 +전통 +전혀 +전후 +절대 +절망 +절반 +절약 +절차 +점검 +점수 +점심 +점원 +점점 +점차 +접근 +접시 +접촉 +젓가락 +정거장 +정도 +정류장 +정리 +정말 +정면 +정문 +정반대 +정보 +정부 +정비 +정상 +정성 +정오 +정원 +정장 +정지 +정치 +정확히 +제공 +제과점 +제대로 +제목 +제발 +제법 +제삿날 +제안 +제일 +제작 +제주도 +제출 +제품 +제한 +조각 +조건 +조금 +조깅 +조명 +조미료 +조상 +조선 +조용히 +조절 +조정 +조직 +존댓말 +존재 +졸업 +졸음 +종교 +종로 +종류 +종소리 +종업원 +종종 +종합 +좌석 +죄인 +주관적 +주름 +주말 +주머니 +주먹 +주문 +주민 +주방 +주변 +주식 +주인 +주일 +주장 +주전자 +주택 +준비 +줄거리 +줄기 +줄무늬 +중간 +중계방송 +중국 +중년 +중단 +중독 +중반 +중부 +중세 +중소기업 +중순 +중앙 +중요 +중학교 +즉석 +즉시 +즐거움 +증가 +증거 +증권 +증상 +증세 +지각 +지갑 +지경 +지극히 +지금 +지급 +지능 +지름길 +지리산 +지방 +지붕 +지식 +지역 +지우개 +지원 +지적 +지점 +지진 +지출 +직선 +직업 +직원 +직장 +진급 +진동 +진로 +진료 +진리 +진짜 +진찰 +진출 +진통 +진행 +질문 +질병 +질서 +짐작 +집단 +집안 +집중 +짜증 +찌꺼기 +차남 +차라리 +차량 +차림 +차별 +차선 +차츰 +착각 +찬물 +찬성 +참가 +참기름 +참새 +참석 +참여 +참외 +참조 +찻잔 +창가 +창고 +창구 +창문 +창밖 +창작 +창조 +채널 +채점 +책가방 +책방 +책상 +책임 +챔피언 +처벌 +처음 +천국 +천둥 +천장 +천재 +천천히 +철도 +철저히 +철학 +첫날 +첫째 +청년 +청바지 +청소 +청춘 +체계 +체력 +체온 +체육 +체중 +체험 +초등학생 +초반 +초밥 +초상화 +초순 +초여름 +초원 +초저녁 +초점 +초청 +초콜릿 +촛불 +총각 +총리 +총장 +촬영 +최근 +최상 +최선 +최신 +최악 +최종 +추석 +추억 +추진 +추천 +추측 +축구 +축소 +축제 +축하 +출근 +출발 +출산 +출신 +출연 +출입 +출장 +출판 +충격 +충고 +충돌 +충분히 +충청도 +취업 +취직 +취향 +치약 +친구 +친척 +칠십 +칠월 +칠판 +침대 +침묵 +침실 +칫솔 +칭찬 +카메라 +카운터 +칼국수 +캐릭터 +캠퍼스 +캠페인 +커튼 +컨디션 +컬러 +컴퓨터 +코끼리 +코미디 +콘서트 +콜라 +콤플렉스 +콩나물 +쾌감 +쿠데타 +크림 +큰길 +큰딸 +큰소리 +큰아들 +큰어머니 +큰일 +큰절 +클래식 +클럽 +킬로 +타입 +타자기 +탁구 +탁자 +탄생 +태권도 +태양 +태풍 +택시 +탤런트 +터널 +터미널 +테니스 +테스트 +테이블 +텔레비전 +토론 +토마토 +토요일 +통계 +통과 +통로 +통신 +통역 +통일 +통장 +통제 +통증 +통합 +통화 +퇴근 +퇴원 +퇴직금 +튀김 +트럭 +특급 +특별 +특성 +특수 +특징 +특히 +튼튼히 +티셔츠 +파란색 +파일 +파출소 +판결 +판단 +판매 +판사 +팔십 +팔월 +팝송 +패션 +팩스 +팩시밀리 +팬티 +퍼센트 +페인트 +편견 +편의 +편지 +편히 +평가 +평균 +평생 +평소 +평양 +평일 +평화 +포스터 +포인트 +포장 +포함 +표면 +표정 +표준 +표현 +품목 +품질 +풍경 +풍속 +풍습 +프랑스 +프린터 +플라스틱 +피곤 +피망 +피아노 +필름 +필수 +필요 +필자 +필통 +핑계 +하느님 +하늘 +하드웨어 +하룻밤 +하반기 +하숙집 +하순 +하여튼 +하지만 +하천 +하품 +하필 +학과 +학교 +학급 +학기 +학년 +학력 +학번 +학부모 +학비 +학생 +학술 +학습 +학용품 +학원 +학위 +학자 +학점 +한계 +한글 +한꺼번에 +한낮 +한눈 +한동안 +한때 +한라산 +한마디 +한문 +한번 +한복 +한식 +한여름 +한쪽 +할머니 +할아버지 +할인 +함께 +함부로 +합격 +합리적 +항공 +항구 +항상 +항의 +해결 +해군 +해답 +해당 +해물 +해석 +해설 +해수욕장 +해안 +핵심 +핸드백 +햄버거 +햇볕 +햇살 +행동 +행복 +행사 +행운 +행위 +향기 +향상 +향수 +허락 +허용 +헬기 +현관 +현금 +현대 +현상 +현실 +현장 +현재 +현지 +혈액 +협력 +형부 +형사 +형수 +형식 +형제 +형태 +형편 +혜택 +호기심 +호남 +호랑이 +호박 +호텔 +호흡 +혹시 +홀로 +홈페이지 +홍보 +홍수 +홍차 +화면 +화분 +화살 +화요일 +화장 +화학 +확보 +확인 +확장 +확정 +환갑 +환경 +환영 +환율 +환자 +활기 +활동 +활발히 +활용 +활짝 +회견 +회관 +회복 +회색 +회원 +회장 +회전 +횟수 +횡단보도 +효율적 +후반 +후춧가루 +훈련 +훨씬 +휴식 +휴일 +흉내 +흐름 +흑백 +흑인 +흔적 +흔히 +흥미 +흥분 +희곡 +희망 +희생 +흰색 +힘껏 +` diff --git a/vendor/github.com/tyler-smith/go-bip39/wordlists/spanish.go b/vendor/github.com/tyler-smith/go-bip39/wordlists/spanish.go new file mode 100644 index 00000000..ad76da97 --- /dev/null +++ b/vendor/github.com/tyler-smith/go-bip39/wordlists/spanish.go @@ -0,0 +1,2071 @@ +package wordlists + +import ( + "fmt" + "hash/crc32" + "strings" +) + +func init() { + // Ensure word list is correct + // $ wget https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/spanish.txt + // $ crc32 spanish.txt + // 266e4f3d + checksum := crc32.ChecksumIEEE([]byte(spanish)) + if fmt.Sprintf("%x", checksum) != "266e4f3d" { + panic("spanish checksum invalid") + } +} + +// Spanish is a slice of mnemonic words taken from the bip39 specification +// https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/spanish.txt +var Spanish = strings.Split(strings.TrimSpace(spanish), "\n") +var spanish = `ábaco +abdomen +abeja +abierto +abogado +abono +aborto +abrazo +abrir +abuelo +abuso +acabar +academia +acceso +acción +aceite +acelga +acento +aceptar +ácido +aclarar +acné +acoger +acoso +activo +acto +actriz +actuar +acudir +acuerdo +acusar +adicto +admitir +adoptar +adorno +aduana +adulto +aéreo +afectar +afición +afinar +afirmar +ágil +agitar +agonía +agosto +agotar +agregar +agrio +agua +agudo +águila +aguja +ahogo +ahorro +aire +aislar +ajedrez +ajeno +ajuste +alacrán +alambre +alarma +alba +álbum +alcalde +aldea +alegre +alejar +alerta +aleta +alfiler +alga +algodón +aliado +aliento +alivio +alma +almeja +almíbar +altar +alteza +altivo +alto +altura +alumno +alzar +amable +amante +amapola +amargo +amasar +ámbar +ámbito +ameno +amigo +amistad +amor +amparo +amplio +ancho +anciano +ancla +andar +andén +anemia +ángulo +anillo +ánimo +anís +anotar +antena +antiguo +antojo +anual +anular +anuncio +añadir +añejo +año +apagar +aparato +apetito +apio +aplicar +apodo +aporte +apoyo +aprender +aprobar +apuesta +apuro +arado +araña +arar +árbitro +árbol +arbusto +archivo +arco +arder +ardilla +arduo +área +árido +aries +armonía +arnés +aroma +arpa +arpón +arreglo +arroz +arruga +arte +artista +asa +asado +asalto +ascenso +asegurar +aseo +asesor +asiento +asilo +asistir +asno +asombro +áspero +astilla +astro +astuto +asumir +asunto +atajo +ataque +atar +atento +ateo +ático +atleta +átomo +atraer +atroz +atún +audaz +audio +auge +aula +aumento +ausente +autor +aval +avance +avaro +ave +avellana +avena +avestruz +avión +aviso +ayer +ayuda +ayuno +azafrán +azar +azote +azúcar +azufre +azul +baba +babor +bache +bahía +baile +bajar +balanza +balcón +balde +bambú +banco +banda +baño +barba +barco +barniz +barro +báscula +bastón +basura +batalla +batería +batir +batuta +baúl +bazar +bebé +bebida +bello +besar +beso +bestia +bicho +bien +bingo +blanco +bloque +blusa +boa +bobina +bobo +boca +bocina +boda +bodega +boina +bola +bolero +bolsa +bomba +bondad +bonito +bono +bonsái +borde +borrar +bosque +bote +botín +bóveda +bozal +bravo +brazo +brecha +breve +brillo +brinco +brisa +broca +broma +bronce +brote +bruja +brusco +bruto +buceo +bucle +bueno +buey +bufanda +bufón +búho +buitre +bulto +burbuja +burla +burro +buscar +butaca +buzón +caballo +cabeza +cabina +cabra +cacao +cadáver +cadena +caer +café +caída +caimán +caja +cajón +cal +calamar +calcio +caldo +calidad +calle +calma +calor +calvo +cama +cambio +camello +camino +campo +cáncer +candil +canela +canguro +canica +canto +caña +cañón +caoba +caos +capaz +capitán +capote +captar +capucha +cara +carbón +cárcel +careta +carga +cariño +carne +carpeta +carro +carta +casa +casco +casero +caspa +castor +catorce +catre +caudal +causa +cazo +cebolla +ceder +cedro +celda +célebre +celoso +célula +cemento +ceniza +centro +cerca +cerdo +cereza +cero +cerrar +certeza +césped +cetro +chacal +chaleco +champú +chancla +chapa +charla +chico +chiste +chivo +choque +choza +chuleta +chupar +ciclón +ciego +cielo +cien +cierto +cifra +cigarro +cima +cinco +cine +cinta +ciprés +circo +ciruela +cisne +cita +ciudad +clamor +clan +claro +clase +clave +cliente +clima +clínica +cobre +cocción +cochino +cocina +coco +código +codo +cofre +coger +cohete +cojín +cojo +cola +colcha +colegio +colgar +colina +collar +colmo +columna +combate +comer +comida +cómodo +compra +conde +conejo +conga +conocer +consejo +contar +copa +copia +corazón +corbata +corcho +cordón +corona +correr +coser +cosmos +costa +cráneo +cráter +crear +crecer +creído +crema +cría +crimen +cripta +crisis +cromo +crónica +croqueta +crudo +cruz +cuadro +cuarto +cuatro +cubo +cubrir +cuchara +cuello +cuento +cuerda +cuesta +cueva +cuidar +culebra +culpa +culto +cumbre +cumplir +cuna +cuneta +cuota +cupón +cúpula +curar +curioso +curso +curva +cutis +dama +danza +dar +dardo +dátil +deber +débil +década +decir +dedo +defensa +definir +dejar +delfín +delgado +delito +demora +denso +dental +deporte +derecho +derrota +desayuno +deseo +desfile +desnudo +destino +desvío +detalle +detener +deuda +día +diablo +diadema +diamante +diana +diario +dibujo +dictar +diente +dieta +diez +difícil +digno +dilema +diluir +dinero +directo +dirigir +disco +diseño +disfraz +diva +divino +doble +doce +dolor +domingo +don +donar +dorado +dormir +dorso +dos +dosis +dragón +droga +ducha +duda +duelo +dueño +dulce +dúo +duque +durar +dureza +duro +ébano +ebrio +echar +eco +ecuador +edad +edición +edificio +editor +educar +efecto +eficaz +eje +ejemplo +elefante +elegir +elemento +elevar +elipse +élite +elixir +elogio +eludir +embudo +emitir +emoción +empate +empeño +empleo +empresa +enano +encargo +enchufe +encía +enemigo +enero +enfado +enfermo +engaño +enigma +enlace +enorme +enredo +ensayo +enseñar +entero +entrar +envase +envío +época +equipo +erizo +escala +escena +escolar +escribir +escudo +esencia +esfera +esfuerzo +espada +espejo +espía +esposa +espuma +esquí +estar +este +estilo +estufa +etapa +eterno +ética +etnia +evadir +evaluar +evento +evitar +exacto +examen +exceso +excusa +exento +exigir +exilio +existir +éxito +experto +explicar +exponer +extremo +fábrica +fábula +fachada +fácil +factor +faena +faja +falda +fallo +falso +faltar +fama +familia +famoso +faraón +farmacia +farol +farsa +fase +fatiga +fauna +favor +fax +febrero +fecha +feliz +feo +feria +feroz +fértil +fervor +festín +fiable +fianza +fiar +fibra +ficción +ficha +fideo +fiebre +fiel +fiera +fiesta +figura +fijar +fijo +fila +filete +filial +filtro +fin +finca +fingir +finito +firma +flaco +flauta +flecha +flor +flota +fluir +flujo +flúor +fobia +foca +fogata +fogón +folio +folleto +fondo +forma +forro +fortuna +forzar +fosa +foto +fracaso +frágil +franja +frase +fraude +freír +freno +fresa +frío +frito +fruta +fuego +fuente +fuerza +fuga +fumar +función +funda +furgón +furia +fusil +fútbol +futuro +gacela +gafas +gaita +gajo +gala +galería +gallo +gamba +ganar +gancho +ganga +ganso +garaje +garza +gasolina +gastar +gato +gavilán +gemelo +gemir +gen +género +genio +gente +geranio +gerente +germen +gesto +gigante +gimnasio +girar +giro +glaciar +globo +gloria +gol +golfo +goloso +golpe +goma +gordo +gorila +gorra +gota +goteo +gozar +grada +gráfico +grano +grasa +gratis +grave +grieta +grillo +gripe +gris +grito +grosor +grúa +grueso +grumo +grupo +guante +guapo +guardia +guerra +guía +guiño +guion +guiso +guitarra +gusano +gustar +haber +hábil +hablar +hacer +hacha +hada +hallar +hamaca +harina +haz +hazaña +hebilla +hebra +hecho +helado +helio +hembra +herir +hermano +héroe +hervir +hielo +hierro +hígado +higiene +hijo +himno +historia +hocico +hogar +hoguera +hoja +hombre +hongo +honor +honra +hora +hormiga +horno +hostil +hoyo +hueco +huelga +huerta +hueso +huevo +huida +huir +humano +húmedo +humilde +humo +hundir +huracán +hurto +icono +ideal +idioma +ídolo +iglesia +iglú +igual +ilegal +ilusión +imagen +imán +imitar +impar +imperio +imponer +impulso +incapaz +índice +inerte +infiel +informe +ingenio +inicio +inmenso +inmune +innato +insecto +instante +interés +íntimo +intuir +inútil +invierno +ira +iris +ironía +isla +islote +jabalí +jabón +jamón +jarabe +jardín +jarra +jaula +jazmín +jefe +jeringa +jinete +jornada +joroba +joven +joya +juerga +jueves +juez +jugador +jugo +juguete +juicio +junco +jungla +junio +juntar +júpiter +jurar +justo +juvenil +juzgar +kilo +koala +labio +lacio +lacra +lado +ladrón +lagarto +lágrima +laguna +laico +lamer +lámina +lámpara +lana +lancha +langosta +lanza +lápiz +largo +larva +lástima +lata +látex +latir +laurel +lavar +lazo +leal +lección +leche +lector +leer +legión +legumbre +lejano +lengua +lento +leña +león +leopardo +lesión +letal +letra +leve +leyenda +libertad +libro +licor +líder +lidiar +lienzo +liga +ligero +lima +límite +limón +limpio +lince +lindo +línea +lingote +lino +linterna +líquido +liso +lista +litera +litio +litro +llaga +llama +llanto +llave +llegar +llenar +llevar +llorar +llover +lluvia +lobo +loción +loco +locura +lógica +logro +lombriz +lomo +lonja +lote +lucha +lucir +lugar +lujo +luna +lunes +lupa +lustro +luto +luz +maceta +macho +madera +madre +maduro +maestro +mafia +magia +mago +maíz +maldad +maleta +malla +malo +mamá +mambo +mamut +manco +mando +manejar +manga +maniquí +manjar +mano +manso +manta +mañana +mapa +máquina +mar +marco +marea +marfil +margen +marido +mármol +marrón +martes +marzo +masa +máscara +masivo +matar +materia +matiz +matriz +máximo +mayor +mazorca +mecha +medalla +medio +médula +mejilla +mejor +melena +melón +memoria +menor +mensaje +mente +menú +mercado +merengue +mérito +mes +mesón +meta +meter +método +metro +mezcla +miedo +miel +miembro +miga +mil +milagro +militar +millón +mimo +mina +minero +mínimo +minuto +miope +mirar +misa +miseria +misil +mismo +mitad +mito +mochila +moción +moda +modelo +moho +mojar +molde +moler +molino +momento +momia +monarca +moneda +monja +monto +moño +morada +morder +moreno +morir +morro +morsa +mortal +mosca +mostrar +motivo +mover +móvil +mozo +mucho +mudar +mueble +muela +muerte +muestra +mugre +mujer +mula +muleta +multa +mundo +muñeca +mural +muro +músculo +museo +musgo +música +muslo +nácar +nación +nadar +naipe +naranja +nariz +narrar +nasal +natal +nativo +natural +náusea +naval +nave +navidad +necio +néctar +negar +negocio +negro +neón +nervio +neto +neutro +nevar +nevera +nicho +nido +niebla +nieto +niñez +niño +nítido +nivel +nobleza +noche +nómina +noria +norma +norte +nota +noticia +novato +novela +novio +nube +nuca +núcleo +nudillo +nudo +nuera +nueve +nuez +nulo +número +nutria +oasis +obeso +obispo +objeto +obra +obrero +observar +obtener +obvio +oca +ocaso +océano +ochenta +ocho +ocio +ocre +octavo +octubre +oculto +ocupar +ocurrir +odiar +odio +odisea +oeste +ofensa +oferta +oficio +ofrecer +ogro +oído +oír +ojo +ola +oleada +olfato +olivo +olla +olmo +olor +olvido +ombligo +onda +onza +opaco +opción +ópera +opinar +oponer +optar +óptica +opuesto +oración +orador +oral +órbita +orca +orden +oreja +órgano +orgía +orgullo +oriente +origen +orilla +oro +orquesta +oruga +osadía +oscuro +osezno +oso +ostra +otoño +otro +oveja +óvulo +óxido +oxígeno +oyente +ozono +pacto +padre +paella +página +pago +país +pájaro +palabra +palco +paleta +pálido +palma +paloma +palpar +pan +panal +pánico +pantera +pañuelo +papá +papel +papilla +paquete +parar +parcela +pared +parir +paro +párpado +parque +párrafo +parte +pasar +paseo +pasión +paso +pasta +pata +patio +patria +pausa +pauta +pavo +payaso +peatón +pecado +pecera +pecho +pedal +pedir +pegar +peine +pelar +peldaño +pelea +peligro +pellejo +pelo +peluca +pena +pensar +peñón +peón +peor +pepino +pequeño +pera +percha +perder +pereza +perfil +perico +perla +permiso +perro +persona +pesa +pesca +pésimo +pestaña +pétalo +petróleo +pez +pezuña +picar +pichón +pie +piedra +pierna +pieza +pijama +pilar +piloto +pimienta +pino +pintor +pinza +piña +piojo +pipa +pirata +pisar +piscina +piso +pista +pitón +pizca +placa +plan +plata +playa +plaza +pleito +pleno +plomo +pluma +plural +pobre +poco +poder +podio +poema +poesía +poeta +polen +policía +pollo +polvo +pomada +pomelo +pomo +pompa +poner +porción +portal +posada +poseer +posible +poste +potencia +potro +pozo +prado +precoz +pregunta +premio +prensa +preso +previo +primo +príncipe +prisión +privar +proa +probar +proceso +producto +proeza +profesor +programa +prole +promesa +pronto +propio +próximo +prueba +público +puchero +pudor +pueblo +puerta +puesto +pulga +pulir +pulmón +pulpo +pulso +puma +punto +puñal +puño +pupa +pupila +puré +quedar +queja +quemar +querer +queso +quieto +química +quince +quitar +rábano +rabia +rabo +ración +radical +raíz +rama +rampa +rancho +rango +rapaz +rápido +rapto +rasgo +raspa +rato +rayo +raza +razón +reacción +realidad +rebaño +rebote +recaer +receta +rechazo +recoger +recreo +recto +recurso +red +redondo +reducir +reflejo +reforma +refrán +refugio +regalo +regir +regla +regreso +rehén +reino +reír +reja +relato +relevo +relieve +relleno +reloj +remar +remedio +remo +rencor +rendir +renta +reparto +repetir +reposo +reptil +res +rescate +resina +respeto +resto +resumen +retiro +retorno +retrato +reunir +revés +revista +rey +rezar +rico +riego +rienda +riesgo +rifa +rígido +rigor +rincón +riñón +río +riqueza +risa +ritmo +rito +rizo +roble +roce +rociar +rodar +rodeo +rodilla +roer +rojizo +rojo +romero +romper +ron +ronco +ronda +ropa +ropero +rosa +rosca +rostro +rotar +rubí +rubor +rudo +rueda +rugir +ruido +ruina +ruleta +rulo +rumbo +rumor +ruptura +ruta +rutina +sábado +saber +sabio +sable +sacar +sagaz +sagrado +sala +saldo +salero +salir +salmón +salón +salsa +salto +salud +salvar +samba +sanción +sandía +sanear +sangre +sanidad +sano +santo +sapo +saque +sardina +sartén +sastre +satán +sauna +saxofón +sección +seco +secreto +secta +sed +seguir +seis +sello +selva +semana +semilla +senda +sensor +señal +señor +separar +sepia +sequía +ser +serie +sermón +servir +sesenta +sesión +seta +setenta +severo +sexo +sexto +sidra +siesta +siete +siglo +signo +sílaba +silbar +silencio +silla +símbolo +simio +sirena +sistema +sitio +situar +sobre +socio +sodio +sol +solapa +soldado +soledad +sólido +soltar +solución +sombra +sondeo +sonido +sonoro +sonrisa +sopa +soplar +soporte +sordo +sorpresa +sorteo +sostén +sótano +suave +subir +suceso +sudor +suegra +suelo +sueño +suerte +sufrir +sujeto +sultán +sumar +superar +suplir +suponer +supremo +sur +surco +sureño +surgir +susto +sutil +tabaco +tabique +tabla +tabú +taco +tacto +tajo +talar +talco +talento +talla +talón +tamaño +tambor +tango +tanque +tapa +tapete +tapia +tapón +taquilla +tarde +tarea +tarifa +tarjeta +tarot +tarro +tarta +tatuaje +tauro +taza +tazón +teatro +techo +tecla +técnica +tejado +tejer +tejido +tela +teléfono +tema +temor +templo +tenaz +tender +tener +tenis +tenso +teoría +terapia +terco +término +ternura +terror +tesis +tesoro +testigo +tetera +texto +tez +tibio +tiburón +tiempo +tienda +tierra +tieso +tigre +tijera +tilde +timbre +tímido +timo +tinta +tío +típico +tipo +tira +tirón +titán +títere +título +tiza +toalla +tobillo +tocar +tocino +todo +toga +toldo +tomar +tono +tonto +topar +tope +toque +tórax +torero +tormenta +torneo +toro +torpedo +torre +torso +tortuga +tos +tosco +toser +tóxico +trabajo +tractor +traer +tráfico +trago +traje +tramo +trance +trato +trauma +trazar +trébol +tregua +treinta +tren +trepar +tres +tribu +trigo +tripa +triste +triunfo +trofeo +trompa +tronco +tropa +trote +trozo +truco +trueno +trufa +tubería +tubo +tuerto +tumba +tumor +túnel +túnica +turbina +turismo +turno +tutor +ubicar +úlcera +umbral +unidad +unir +universo +uno +untar +uña +urbano +urbe +urgente +urna +usar +usuario +útil +utopía +uva +vaca +vacío +vacuna +vagar +vago +vaina +vajilla +vale +válido +valle +valor +válvula +vampiro +vara +variar +varón +vaso +vecino +vector +vehículo +veinte +vejez +vela +velero +veloz +vena +vencer +venda +veneno +vengar +venir +venta +venus +ver +verano +verbo +verde +vereda +verja +verso +verter +vía +viaje +vibrar +vicio +víctima +vida +vídeo +vidrio +viejo +viernes +vigor +vil +villa +vinagre +vino +viñedo +violín +viral +virgo +virtud +visor +víspera +vista +vitamina +viudo +vivaz +vivero +vivir +vivo +volcán +volumen +volver +voraz +votar +voto +voz +vuelo +vulgar +yacer +yate +yegua +yema +yerno +yeso +yodo +yoga +yogur +zafiro +zanja +zapato +zarza +zona +zorro +zumo +zurdo +` diff --git a/vendor/github.com/vulcanize/eth-block-extractor/LICENSE b/vendor/github.com/vulcanize/eth-block-extractor/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/adder.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/adder.go new file mode 100644 index 00000000..bd4ac99b --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/adder.go @@ -0,0 +1,7 @@ +package ipfs + +import ipld "github.com/ipfs/go-ipld-format" + +type Adder interface { + Add(node ipld.Node) error +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/dag_putter.go new file mode 100644 index 00000000..96c8ecc5 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/dag_putter.go @@ -0,0 +1,5 @@ +package ipfs + +type DagPutter interface { + DagPut(raw interface{}) ([]string, error) +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/dag_putter.go new file mode 100644 index 00000000..1b214c06 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/dag_putter.go @@ -0,0 +1,53 @@ +package eth_block_header + +import ( + "github.com/ethereum/go-ethereum/core/types" + ipld "github.com/ipfs/go-ipld-format" + + "github.com/vulcanize/eth-block-extractor/pkg/ipfs" + "github.com/vulcanize/eth-block-extractor/pkg/ipfs/util" + "github.com/vulcanize/eth-block-extractor/pkg/wrappers/rlp" +) + +const ( + EthBlockHeaderCode = 0x90 +) + +type BlockHeaderDagPutter struct { + adder ipfs.Adder + decoder rlp.Decoder +} + +func NewBlockHeaderDagPutter(adder ipfs.Adder, decoder rlp.Decoder) *BlockHeaderDagPutter { + return &BlockHeaderDagPutter{adder: adder, decoder: decoder} +} + +func (bhdp *BlockHeaderDagPutter) DagPut(raw interface{}) ([]string, error) { + input := raw.([]byte) + nd, err := bhdp.getNodeForBlockHeader(input) + if err != nil { + return nil, err + } + err = bhdp.adder.Add(nd) + if err != nil { + return nil, err + } + return []string{nd.Cid().String()}, nil +} + +func (bhdp *BlockHeaderDagPutter) getNodeForBlockHeader(raw []byte) (ipld.Node, error) { + var blockHeader types.Header + err := bhdp.decoder.Decode(raw, &blockHeader) + if err != nil { + return nil, err + } + blockHeaderCid, err := util.RawToCid(EthBlockHeaderCode, raw) + if err != nil { + return nil, err + } + return &EthBlockHeaderNode{ + Header: &blockHeader, + cid: blockHeaderCid, + rawdata: raw, + }, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/node.go new file mode 100644 index 00000000..6ea3c129 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_header/node.go @@ -0,0 +1,59 @@ +package eth_block_header + +import ( + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipld-format" +) + +type EthBlockHeaderNode struct { + *types.Header + + cid cid.Cid + rawdata []byte +} + +func (ebh *EthBlockHeaderNode) RawData() []byte { + return ebh.rawdata +} + +func (ebh *EthBlockHeaderNode) Cid() cid.Cid { + return ebh.cid +} + +func (EthBlockHeaderNode) String() string { + return "" +} + +func (EthBlockHeaderNode) Loggable() map[string]interface{} { + panic("implement me") +} + +func (EthBlockHeaderNode) Resolve(path []string) (interface{}, []string, error) { + panic("implement me") +} + +func (EthBlockHeaderNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (EthBlockHeaderNode) ResolveLink(path []string) (*format.Link, []string, error) { + panic("implement me") +} + +func (EthBlockHeaderNode) Copy() format.Node { + panic("implement me") +} + +func (EthBlockHeaderNode) Links() []*format.Link { + panic("implement me") +} + +func (EthBlockHeaderNode) Stat() (*format.NodeStat, error) { + panic("implement me") +} + +func (EthBlockHeaderNode) Size() (uint64, error) { + panic("implement me") +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/dag_putter.go new file mode 100644 index 00000000..2af3566e --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/dag_putter.go @@ -0,0 +1,54 @@ +package eth_block_receipts + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ipfs/go-cid" + + "github.com/vulcanize/eth-block-extractor/pkg/ipfs" + "github.com/vulcanize/eth-block-extractor/pkg/ipfs/util" +) + +type EthBlockReceiptDagPutter struct { + adder ipfs.Adder +} + +func NewEthBlockReceiptDagPutter(adder ipfs.Adder) *EthBlockReceiptDagPutter { + return &EthBlockReceiptDagPutter{adder: adder} +} + +func (dagPutter *EthBlockReceiptDagPutter) DagPut(raw interface{}) ([]string, error) { + input := raw.(types.Receipts) + var output []string + for _, r := range input { + receiptForStorage := (*types.ReceiptForStorage)(r) + node, err := getReceiptNode(receiptForStorage) + if err != nil { + return nil, err + } + err = dagPutter.adder.Add(node) + if err != nil { + return nil, err + } + output = append(output, node.cid.String()) + } + return output, nil +} + +func getReceiptNode(receipt *types.ReceiptForStorage) (*EthReceiptNode, error) { + buffer := new(bytes.Buffer) + err := receipt.EncodeRLP(buffer) + if err != nil { + return nil, err + } + receiptCid, err := util.RawToCid(cid.EthTxReceipt, buffer.Bytes()) + if err != nil { + return nil, err + } + node := &EthReceiptNode{ + raw: buffer.Bytes(), + cid: receiptCid, + } + return node, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/node.go new file mode 100644 index 00000000..0c871706 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_receipts/node.go @@ -0,0 +1,55 @@ +package eth_block_receipts + +import ( + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipld-format" +) + +type EthReceiptNode struct { + raw []byte + cid cid.Cid +} + +func (node *EthReceiptNode) RawData() []byte { + return node.raw +} + +func (node *EthReceiptNode) Cid() cid.Cid { + return node.cid +} + +func (*EthReceiptNode) String() string { + panic("implement me") +} + +func (*EthReceiptNode) Loggable() map[string]interface{} { + panic("implement me") +} + +func (*EthReceiptNode) Resolve(path []string) (interface{}, []string, error) { + panic("implement me") +} + +func (*EthReceiptNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (*EthReceiptNode) ResolveLink(path []string) (*format.Link, []string, error) { + panic("implement me") +} + +func (*EthReceiptNode) Copy() format.Node { + panic("implement me") +} + +func (*EthReceiptNode) Links() []*format.Link { + panic("implement me") +} + +func (*EthReceiptNode) Stat() (*format.NodeStat, error) { + panic("implement me") +} + +func (*EthReceiptNode) Size() (uint64, error) { + panic("implement me") +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/dag_putter.go new file mode 100644 index 00000000..46fdd0c8 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/dag_putter.go @@ -0,0 +1,50 @@ +package eth_block_transactions + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/core/types" + + "github.com/vulcanize/eth-block-extractor/pkg/ipfs" + "github.com/vulcanize/eth-block-extractor/pkg/ipfs/util" +) + +const ( + EthBlockTransactionCode = 0x93 +) + +type BlockTransactionsDagPutter struct { + adder ipfs.Adder +} + +func NewBlockTransactionsDagPutter(adder ipfs.Adder) *BlockTransactionsDagPutter { + return &BlockTransactionsDagPutter{adder: adder} +} + +func (bbdp *BlockTransactionsDagPutter) DagPut(body interface{}) ([]string, error) { + blockBody := body.(*types.Body) + transactions := blockBody.Transactions + var cids []string + for _, transaction := range transactions { + buffer := new(bytes.Buffer) + err := transaction.EncodeRLP(buffer) + if err != nil { + return nil, err + } + transactionCid, err := util.RawToCid(EthBlockTransactionCode, buffer.Bytes()) + if err != nil { + return nil, err + } + transactionNode := &EthTransactionNode{ + Transaction: transaction, + cid: transactionCid, + rawdata: buffer.Bytes(), + } + err = bbdp.adder.Add(transactionNode) + if err != nil { + return nil, err + } + cids = append(cids, transactionCid.String()) + } + return cids, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/node.go new file mode 100644 index 00000000..93d9bb45 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_block_transactions/node.go @@ -0,0 +1,58 @@ +package eth_block_transactions + +import ( + "github.com/ethereum/go-ethereum/core/types" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipld-format" +) + +type EthTransactionNode struct { + *types.Transaction + + cid cid.Cid + rawdata []byte +} + +func (etn *EthTransactionNode) RawData() []byte { + return etn.rawdata +} + +func (etn *EthTransactionNode) Cid() cid.Cid { + return etn.cid +} + +func (EthTransactionNode) String() string { + return "" +} + +func (EthTransactionNode) Loggable() map[string]interface{} { + panic("implement me") +} + +func (EthTransactionNode) Resolve(path []string) (interface{}, []string, error) { + panic("implement me") +} + +func (EthTransactionNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (EthTransactionNode) ResolveLink(path []string) (*format.Link, []string, error) { + panic("implement me") +} + +func (EthTransactionNode) Copy() format.Node { + panic("implement me") +} + +func (EthTransactionNode) Links() []*format.Link { + panic("implement me") +} + +func (EthTransactionNode) Stat() (*format.NodeStat, error) { + panic("implement me") +} + +func (EthTransactionNode) Size() (uint64, error) { + panic("implement me") +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/dag_putter.go new file mode 100644 index 00000000..a8e298fb --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/dag_putter.go @@ -0,0 +1,43 @@ +package eth_state_trie + +import ( + "github.com/vulcanize/eth-block-extractor/pkg/ipfs" + "github.com/vulcanize/eth-block-extractor/pkg/ipfs/util" +) + +const ( + EthStateTrieNodeCode = 0x96 +) + +type StateTrieDagPutter struct { + adder ipfs.Adder +} + +func NewStateTrieDagPutter(adder ipfs.Adder) *StateTrieDagPutter { + return &StateTrieDagPutter{adder: adder} +} + +func (stdp StateTrieDagPutter) DagPut(raw interface{}) ([]string, error) { + input := raw.([]byte) + stateTrieNode, err := stdp.getStateTrieNode(input) + if err != nil { + return nil, err + } + err = stdp.adder.Add(stateTrieNode) + if err != nil { + return nil, err + } + return []string{stateTrieNode.Cid().String()}, nil +} + +func (stdp StateTrieDagPutter) getStateTrieNode(raw []byte) (*EthStateTrieNode, error) { + stateTrieNodeCid, err := util.RawToCid(EthStateTrieNodeCode, raw) + if err != nil { + return nil, err + } + stateTrieNode := &EthStateTrieNode{ + cid: stateTrieNodeCid, + rawdata: raw, + } + return stateTrieNode, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/node.go new file mode 100644 index 00000000..4c592068 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_state_trie/node.go @@ -0,0 +1,55 @@ +package eth_state_trie + +import ( + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipld-format" +) + +type EthStateTrieNode struct { + cid cid.Cid + rawdata []byte +} + +func (estn EthStateTrieNode) RawData() []byte { + return estn.rawdata +} + +func (estn EthStateTrieNode) Cid() cid.Cid { + return estn.cid +} + +func (EthStateTrieNode) String() string { + panic("implement me") +} + +func (EthStateTrieNode) Loggable() map[string]interface{} { + panic("implement me") +} + +func (EthStateTrieNode) Resolve(path []string) (interface{}, []string, error) { + panic("implement me") +} + +func (EthStateTrieNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (EthStateTrieNode) ResolveLink(path []string) (*format.Link, []string, error) { + panic("implement me") +} + +func (EthStateTrieNode) Copy() format.Node { + panic("implement me") +} + +func (EthStateTrieNode) Links() []*format.Link { + panic("implement me") +} + +func (EthStateTrieNode) Stat() (*format.NodeStat, error) { + panic("implement me") +} + +func (EthStateTrieNode) Size() (uint64, error) { + panic("implement me") +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/dag_putter.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/dag_putter.go new file mode 100644 index 00000000..e70d0df1 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/dag_putter.go @@ -0,0 +1,35 @@ +package eth_storage_trie + +import ( + "github.com/vulcanize/eth-block-extractor/pkg/ipfs" + "github.com/vulcanize/eth-block-extractor/pkg/ipfs/util" +) + +const ( + EthStorageTrieNodeCode = 0x98 +) + +type StorageTrieDagPutter struct { + adder ipfs.Adder +} + +func NewStorageTrieDagPutter(adder ipfs.Adder) *StorageTrieDagPutter { + return &StorageTrieDagPutter{adder: adder} +} + +func (stdp StorageTrieDagPutter) DagPut(raw interface{}) ([]string, error) { + input := raw.([]byte) + cid, err := util.RawToCid(EthStorageTrieNodeCode, input) + if err != nil { + return nil, err + } + node := &EthStorageTrieNode{ + cid: cid, + rawdata: input, + } + err = stdp.adder.Add(node) + if err != nil { + return nil, err + } + return []string{node.Cid().String()}, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/node.go new file mode 100644 index 00000000..075b3d4a --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/eth_storage_trie/node.go @@ -0,0 +1,55 @@ +package eth_storage_trie + +import ( + "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipld-format" +) + +type EthStorageTrieNode struct { + cid cid.Cid + rawdata []byte +} + +func (estn *EthStorageTrieNode) RawData() []byte { + return estn.rawdata +} + +func (estn *EthStorageTrieNode) Cid() cid.Cid { + return estn.cid +} + +func (*EthStorageTrieNode) String() string { + panic("implement me") +} + +func (*EthStorageTrieNode) Loggable() map[string]interface{} { + panic("implement me") +} + +func (*EthStorageTrieNode) Resolve(path []string) (interface{}, []string, error) { + panic("implement me") +} + +func (*EthStorageTrieNode) Tree(path string, depth int) []string { + panic("implement me") +} + +func (*EthStorageTrieNode) ResolveLink(path []string) (*format.Link, []string, error) { + panic("implement me") +} + +func (*EthStorageTrieNode) Copy() format.Node { + panic("implement me") +} + +func (*EthStorageTrieNode) Links() []*format.Link { + panic("implement me") +} + +func (*EthStorageTrieNode) Stat() (*format.NodeStat, error) { + panic("implement me") +} + +func (*EthStorageTrieNode) Size() (uint64, error) { + panic("implement me") +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/node.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/node.go new file mode 100644 index 00000000..ac0a2d41 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/node.go @@ -0,0 +1,36 @@ +package ipfs + +import ( + "context" + + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/repo/fsrepo" + + ipld "github.com/ipfs/go-ipld-format" +) + +type IPFS struct { + n *core.IpfsNode + ctx context.Context +} + +func (ipfs IPFS) Add(node ipld.Node) error { + return ipfs.n.DAG.Add(ipfs.n.Context(), node) +} + +func InitIPFSNode(repoPath string) (*IPFS, error) { + r, err := fsrepo.Open(repoPath) + if err != nil { + return nil, err + } + ctx := context.Background() + cfg := &core.BuildCfg{ + Online: false, + Repo: r, + } + ipfsNode, err := core.NewNode(ctx, cfg) + if err != nil { + return nil, err + } + return &IPFS{n: ipfsNode, ctx: ctx}, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/publisher.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/publisher.go new file mode 100644 index 00000000..3d1065dc --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/publisher.go @@ -0,0 +1,32 @@ +package ipfs + +import "fmt" + +type Error struct { + msg string + err error +} + +func (ie Error) Error() string { + return fmt.Sprintf("%s: %s", ie.msg, ie.err.Error()) +} + +type Publisher interface { + Write(input interface{}) ([]string, error) +} + +type BlockDataPublisher struct { + DagPutter +} + +func NewIpfsPublisher(dagPutter DagPutter) *BlockDataPublisher { + return &BlockDataPublisher{DagPutter: dagPutter} +} + +func (ip *BlockDataPublisher) Write(input interface{}) ([]string, error) { + cids, err := ip.DagPutter.DagPut(input) + if err != nil { + return nil, err + } + return cids, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/util/cid.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/util/cid.go new file mode 100644 index 00000000..e8066b86 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/ipfs/util/cid.go @@ -0,0 +1,19 @@ +package util + +import ( + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +func RawToCid(codec uint64, raw []byte) (cid.Cid, error) { + c, err := cid.Prefix{ + Codec: codec, + Version: 1, + MhType: mh.KECCAK_256, + MhLength: -1, + }.Sum(raw) + if err != nil { + return cid.Cid{}, err + } + return c, nil +} diff --git a/vendor/github.com/vulcanize/eth-block-extractor/pkg/wrappers/rlp/decode.go b/vendor/github.com/vulcanize/eth-block-extractor/pkg/wrappers/rlp/decode.go new file mode 100644 index 00000000..61853944 --- /dev/null +++ b/vendor/github.com/vulcanize/eth-block-extractor/pkg/wrappers/rlp/decode.go @@ -0,0 +1,16 @@ +package rlp + +import ( + "bytes" + "github.com/ethereum/go-ethereum/rlp" +) + +type Decoder interface { + Decode(raw []byte, out interface{}) error +} + +type RlpDecoder struct{} + +func (RlpDecoder) Decode(raw []byte, out interface{}) error { + return rlp.Decode(bytes.NewBuffer(raw), out) +} diff --git a/vendor/github.com/whyrusleeping/base32/base32.go b/vendor/github.com/whyrusleeping/base32/base32.go new file mode 100644 index 00000000..768a2350 --- /dev/null +++ b/vendor/github.com/whyrusleeping/base32/base32.go @@ -0,0 +1,505 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package base32 implements base32 encoding as specified by RFC 4648. +package base32 + +import ( + "io" + "strconv" +) + +/* + * Encodings + */ + +// An Encoding is a radix 32 encoding/decoding scheme, defined by a +// 32-character alphabet. The most common is the "base32" encoding +// introduced for SASL GSSAPI and standardized in RFC 4648. +// The alternate "base32hex" encoding is used in DNSSEC. +type Encoding struct { + encode string + decodeMap [256]byte + padChar rune +} + +// Alphabet returns the Base32 alphabet used +func (enc *Encoding) Alphabet() string { + return enc.encode +} + +const ( + StdPadding rune = '=' + NoPadding rune = -1 +) + +const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" +const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV" + +// NewEncoding returns a new Encoding defined by the given alphabet, +// which must be a 32-byte string. +func NewEncoding(encoder string) *Encoding { + e := new(Encoding) + e.padChar = StdPadding + e.encode = encoder + for i := 0; i < len(e.decodeMap); i++ { + e.decodeMap[i] = 0xFF + } + for i := 0; i < len(encoder); i++ { + e.decodeMap[encoder[i]] = byte(i) + } + return e +} + +// NewEncoding returns a new case insensitive Encoding defined by the +// given alphabet, which must be a 32-byte string. +func NewEncodingCI(encoder string) *Encoding { + e := new(Encoding) + e.padChar = StdPadding + e.encode = encoder + for i := 0; i < len(e.decodeMap); i++ { + e.decodeMap[i] = 0xFF + } + for i := 0; i < len(encoder); i++ { + e.decodeMap[asciiToLower(encoder[i])] = byte(i) + e.decodeMap[asciiToUpper(encoder[i])] = byte(i) + } + return e +} + +func asciiToLower(c byte) byte { + if c >= 'A' && c <= 'Z' { + return c + 32 + } + return c +} + +func asciiToUpper(c byte) byte { + if c >= 'a' && c <= 'z' { + return c - 32 + } + return c +} + +// WithPadding creates a new encoding identical to enc except +// with a specified padding character, or NoPadding to disable padding. +func (enc Encoding) WithPadding(padding rune) *Encoding { + enc.padChar = padding + return &enc +} + +// StdEncoding is the standard base32 encoding, as defined in +// RFC 4648. +var StdEncoding = NewEncodingCI(encodeStd) + +// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648. +// It is typically used in DNS. +var HexEncoding = NewEncodingCI(encodeHex) + +var RawStdEncoding = NewEncodingCI(encodeStd).WithPadding(NoPadding) +var RawHexEncoding = NewEncodingCI(encodeHex).WithPadding(NoPadding) + +/* + * Encoder + */ + +// Encode encodes src using the encoding enc, writing +// EncodedLen(len(src)) bytes to dst. +// +// The encoding pads the output to a multiple of 8 bytes, +// so Encode is not appropriate for use on individual blocks +// of a large data stream. Use NewEncoder() instead. +func (enc *Encoding) Encode(dst, src []byte) { + if len(src) == 0 { + return + } + + for len(src) > 0 { + var carry byte + + // Unpack 8x 5-bit source blocks into a 5 byte + // destination quantum + switch len(src) { + default: + dst[7] = enc.encode[src[4]&0x1F] + carry = src[4] >> 5 + fallthrough + case 4: + dst[6] = enc.encode[carry|(src[3]<<3)&0x1F] + dst[5] = enc.encode[(src[3]>>2)&0x1F] + carry = src[3] >> 7 + fallthrough + case 3: + dst[4] = enc.encode[carry|(src[2]<<1)&0x1F] + carry = (src[2] >> 4) & 0x1F + fallthrough + case 2: + dst[3] = enc.encode[carry|(src[1]<<4)&0x1F] + dst[2] = enc.encode[(src[1]>>1)&0x1F] + carry = (src[1] >> 6) & 0x1F + fallthrough + case 1: + dst[1] = enc.encode[carry|(src[0]<<2)&0x1F] + dst[0] = enc.encode[src[0]>>3] + } + + // Pad the final quantum + if len(src) < 5 { + if enc.padChar != NoPadding { + dst[7] = byte(enc.padChar) + if len(src) < 4 { + dst[6] = byte(enc.padChar) + dst[5] = byte(enc.padChar) + if len(src) < 3 { + dst[4] = byte(enc.padChar) + if len(src) < 2 { + dst[3] = byte(enc.padChar) + dst[2] = byte(enc.padChar) + } + } + } + } + break + } + src = src[5:] + dst = dst[8:] + } +} + +// EncodeToString returns the base32 encoding of src. +func (enc *Encoding) EncodeToString(src []byte) string { + buf := make([]byte, enc.EncodedLen(len(src))) + enc.Encode(buf, src) + return string(buf) +} + +type encoder struct { + err error + enc *Encoding + w io.Writer + buf [5]byte // buffered data waiting to be encoded + nbuf int // number of bytes in buf + out [1024]byte // output buffer +} + +func (e *encoder) Write(p []byte) (n int, err error) { + if e.err != nil { + return 0, e.err + } + + // Leading fringe. + if e.nbuf > 0 { + var i int + for i = 0; i < len(p) && e.nbuf < 5; i++ { + e.buf[e.nbuf] = p[i] + e.nbuf++ + } + n += i + p = p[i:] + if e.nbuf < 5 { + return + } + e.enc.Encode(e.out[0:], e.buf[0:]) + if _, e.err = e.w.Write(e.out[0:8]); e.err != nil { + return n, e.err + } + e.nbuf = 0 + } + + // Large interior chunks. + for len(p) >= 5 { + nn := len(e.out) / 8 * 5 + if nn > len(p) { + nn = len(p) + nn -= nn % 5 + } + e.enc.Encode(e.out[0:], p[0:nn]) + if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil { + return n, e.err + } + n += nn + p = p[nn:] + } + + // Trailing fringe. + for i := 0; i < len(p); i++ { + e.buf[i] = p[i] + } + e.nbuf = len(p) + n += len(p) + return +} + +// Close flushes any pending output from the encoder. +// It is an error to call Write after calling Close. +func (e *encoder) Close() error { + // If there's anything left in the buffer, flush it out + if e.err == nil && e.nbuf > 0 { + e.enc.Encode(e.out[0:], e.buf[0:e.nbuf]) + e.nbuf = 0 + _, e.err = e.w.Write(e.out[0:8]) + } + return e.err +} + +// NewEncoder returns a new base32 stream encoder. Data written to +// the returned writer will be encoded using enc and then written to w. +// Base32 encodings operate in 5-byte blocks; when finished +// writing, the caller must Close the returned encoder to flush any +// partially written blocks. +func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser { + return &encoder{enc: enc, w: w} +} + +// EncodedLen returns the length in bytes of the base32 encoding +// of an input buffer of length n. +func (enc *Encoding) EncodedLen(n int) int { + if enc.padChar == NoPadding { + return (n*8 + 4) / 5 // minimum # chars at 5 bits per char + } + return (n + 4) / 5 * 8 +} + +/* + * Decoder + */ + +type CorruptInputError int64 + +func (e CorruptInputError) Error() string { + return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10) +} + +// decode is like Decode but returns an additional 'end' value, which +// indicates if end-of-message padding was encountered and thus any +// additional data is an error. This method assumes that src has been +// stripped of all supported whitespace ('\r' and '\n'). +func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { + olen := len(src) + for len(src) > 0 && !end { + // Decode quantum using the base32 alphabet + var dbuf [8]byte + dlen := 8 + + for j := 0; j < 8; { + if len(src) == 0 { + if enc.padChar != NoPadding { + return n, false, CorruptInputError(olen - len(src) - j) + } + dlen = j + break + } + in := src[0] + src = src[1:] + if in == byte(enc.padChar) && j >= 2 && len(src) < 8 { + if enc.padChar == NoPadding { + return n, false, CorruptInputError(olen) + } + + // We've reached the end and there's padding + if len(src)+j < 8-1 { + // not enough padding + return n, false, CorruptInputError(olen) + } + for k := 0; k < 8-1-j; k++ { + if len(src) > k && src[k] != byte(enc.padChar) { + // incorrect padding + return n, false, CorruptInputError(olen - len(src) + k - 1) + } + } + dlen, end = j, true + // 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not + // valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing + // the five valid padding lengths, and Section 9 "Illustrations and + // Examples" for an illustration for how the 1st, 3rd and 6th base32 + // src bytes do not yield enough information to decode a dst byte. + if dlen == 1 || dlen == 3 || dlen == 6 { + return n, false, CorruptInputError(olen - len(src) - 1) + } + break + } + dbuf[j] = enc.decodeMap[in] + if dbuf[j] == 0xFF { + return n, false, CorruptInputError(olen - len(src) - 1) + } + j++ + } + + // Pack 8x 5-bit source blocks into 5 byte destination + // quantum + switch dlen { + case 8: + dst[4] = dbuf[6]<<5 | dbuf[7] + fallthrough + case 7: + dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3 + fallthrough + case 5: + dst[2] = dbuf[3]<<4 | dbuf[4]>>1 + fallthrough + case 4: + dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4 + fallthrough + case 2: + dst[0] = dbuf[0]<<3 | dbuf[1]>>2 + } + + if len(dst) > 5 { + dst = dst[5:] + } + + switch dlen { + case 2: + n += 1 + case 4: + n += 2 + case 5: + n += 3 + case 7: + n += 4 + case 8: + n += 5 + } + } + return n, end, nil +} + +// Decode decodes src using the encoding enc. It writes at most +// DecodedLen(len(src)) bytes to dst and returns the number of bytes +// written. If src contains invalid base32 data, it will return the +// number of bytes successfully written and CorruptInputError. +// New line characters (\r and \n) are ignored. +func (enc *Encoding) Decode(dst, s []byte) (n int, err error) { + // FIXME: if dst is the same as s use decodeInPlace + stripped := make([]byte, 0, len(s)) + for _, c := range s { + if c != '\r' && c != '\n' { + stripped = append(stripped, c) + } + } + n, _, err = enc.decode(dst, stripped) + return +} + +func (enc *Encoding) decodeInPlace(strb []byte) (n int, err error) { + off := 0 + for _, b := range strb { + if b == '\n' || b == '\r' { + continue + } + strb[off] = b + off++ + } + n, _, err = enc.decode(strb, strb[:off]) + return +} + +// DecodeString returns the bytes represented by the base32 string s. +func (enc *Encoding) DecodeString(s string) ([]byte, error) { + strb := []byte(s) + n, err := enc.decodeInPlace(strb) + if err != nil { + return nil, err + } + return strb[:n], nil +} + +type decoder struct { + err error + enc *Encoding + r io.Reader + end bool // saw end of message + buf [1024]byte // leftover input + nbuf int + out []byte // leftover decoded output + outbuf [1024 / 8 * 5]byte +} + +func (d *decoder) Read(p []byte) (n int, err error) { + if d.err != nil { + return 0, d.err + } + + // Use leftover decoded output from last read. + if len(d.out) > 0 { + n = copy(p, d.out) + d.out = d.out[n:] + return n, nil + } + + // Read a chunk. + nn := len(p) / 5 * 8 + if nn < 8 { + nn = 8 + } + if nn > len(d.buf) { + nn = len(d.buf) + } + nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf) + d.nbuf += nn + if d.nbuf < 8 { + return 0, d.err + } + + // Decode chunk into p, or d.out and then p if p is too small. + nr := d.nbuf / 8 * 8 + nw := d.nbuf / 8 * 5 + if nw > len(p) { + nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr]) + d.out = d.outbuf[0:nw] + n = copy(p, d.out) + d.out = d.out[n:] + } else { + n, d.end, d.err = d.enc.decode(p, d.buf[0:nr]) + } + d.nbuf -= nr + for i := 0; i < d.nbuf; i++ { + d.buf[i] = d.buf[i+nr] + } + + if d.err == nil { + d.err = err + } + return n, d.err +} + +type newlineFilteringReader struct { + wrapped io.Reader +} + +func (r *newlineFilteringReader) Read(p []byte) (int, error) { + n, err := r.wrapped.Read(p) + for n > 0 { + offset := 0 + for i, b := range p[0:n] { + if b != '\r' && b != '\n' { + if i != offset { + p[offset] = b + } + offset++ + } + } + if offset > 0 { + return offset, err + } + // Previous buffer entirely whitespace, read again + n, err = r.wrapped.Read(p) + } + return n, err +} + +// NewDecoder constructs a new base32 stream decoder. +func NewDecoder(enc *Encoding, r io.Reader) io.Reader { + return &decoder{enc: enc, r: &newlineFilteringReader{r}} +} + +// DecodedLen returns the maximum length in bytes of the decoded data +// corresponding to n bytes of base32-encoded data. +func (enc *Encoding) DecodedLen(n int) int { + if enc.padChar == NoPadding { + return (n*5 + 7) / 8 + } + + return n / 8 * 5 +} diff --git a/vendor/github.com/whyrusleeping/base32/package.json b/vendor/github.com/whyrusleeping/base32/package.json new file mode 100644 index 00000000..f78c51b6 --- /dev/null +++ b/vendor/github.com/whyrusleeping/base32/package.json @@ -0,0 +1,15 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/base32" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/base32" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "", + "name": "base32", + "version": "0.0.2" +} + diff --git a/vendor/github.com/whyrusleeping/chunker/.travis.yml b/vendor/github.com/whyrusleeping/chunker/.travis.yml new file mode 100644 index 00000000..901e788d --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/.travis.yml @@ -0,0 +1,9 @@ +language: go +sudo: false + +go: + - tip + +os: + - linux + - osx diff --git a/vendor/github.com/whyrusleeping/chunker/LICENSE b/vendor/github.com/whyrusleeping/chunker/LICENSE new file mode 100644 index 00000000..04f85435 --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2014, Alexander Neumann +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. 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. + +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 HOLDER 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. diff --git a/vendor/github.com/whyrusleeping/chunker/README.md b/vendor/github.com/whyrusleeping/chunker/README.md new file mode 100644 index 00000000..0d1b33f8 --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/README.md @@ -0,0 +1,7 @@ +[![Build Status](https://travis-ci.org/whyrusleeping/chunker.svg?branch=master)](https://travis-ci.org/whyrusleeping/chunker) + +Content Defined Chunking (CDC) based on a rolling Rabin Checksum. + +Part of https://github.com/restic/restic. + +Better README will follow soon. diff --git a/vendor/github.com/whyrusleeping/chunker/chunker.go b/vendor/github.com/whyrusleeping/chunker/chunker.go new file mode 100644 index 00000000..d2032c38 --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/chunker.go @@ -0,0 +1,384 @@ +package chunker + +import ( + "errors" + "hash" + "io" + "math" + "sync" +) + +const ( + KiB = 1024 + MiB = 1024 * KiB + + // WindowSize is the size of the sliding window. + windowSize = 16 + + chunkerBufSize = 512 * KiB + + // MinSize is the default minimal size of a chunk. + MinSize = 512 * KiB + // MaxSize is the default maximal size of a chunk. + MaxSize = 8 * MiB + + // AvgSize is the default average size of a chunk. + AvgSize = 1048576 +) + +var bufPool = sync.Pool{ + New: func() interface{} { return new([chunkerBufSize]byte) }, +} + +type tables struct { + out [256]Pol + mod [256]Pol +} + +// cache precomputed tables, these are read-only anyway +var cache struct { + entries map[Pol]*tables + sync.Mutex +} + +func init() { + cache.entries = make(map[Pol]*tables) +} + +// Chunk is one content-dependent chunk of bytes whose end was cut when the +// Rabin Fingerprint had the value stored in Cut. +type Chunk struct { + Start uint64 + Length uint64 + Cut uint64 + Digest []byte + Data []byte +} + +func (c Chunk) Reader(r io.ReaderAt) io.Reader { + return io.NewSectionReader(r, int64(c.Start), int64(c.Length)) +} + +// Chunker splits content with Rabin Fingerprints. +type Chunker struct { + pol Pol + polShift uint64 + tables *tables + + rd io.Reader + closed bool + + chunkbuf []byte + + window [windowSize]byte + wpos int + + buf *[chunkerBufSize]byte + bpos uint64 + bmax uint64 + + start uint64 + count uint64 + pos uint64 + + pre uint64 // wait for this many bytes before start calculating an new chunk + + digest uint64 + h hash.Hash + + sizeMask uint64 + + // minimal and maximal size of the outputted blocks + MinSize uint64 + MaxSize uint64 +} + +// New returns a new Chunker based on polynomial p that reads from rd +// with bufsize and pass all data to hash along the way. +func New(rd io.Reader, pol Pol, h hash.Hash, avSize, min, max uint64) *Chunker { + + sizepow := uint(math.Log2(float64(avSize))) + + c := &Chunker{ + buf: bufPool.Get().(*[chunkerBufSize]byte), + h: h, + pol: pol, + rd: rd, + chunkbuf: make([]byte, 0, max), + sizeMask: (1 << sizepow) - 1, + + MinSize: min, + MaxSize: max, + } + + c.reset() + + return c +} + +func (c *Chunker) reset() { + c.polShift = uint64(c.pol.Deg() - 8) + c.fillTables() + + for i := 0; i < windowSize; i++ { + c.window[i] = 0 + } + + c.closed = false + c.digest = 0 + c.wpos = 0 + c.count = 0 + c.slide(1) + c.start = c.pos + + if c.h != nil { + c.h.Reset() + } + + // do not start a new chunk unless at least MinSize bytes have been read + c.pre = c.MinSize - windowSize +} + +// Calculate out_table and mod_table for optimization. Must be called only +// once. This implementation uses a cache in the global variable cache. +func (c *Chunker) fillTables() { + // if polynomial hasn't been specified, do not compute anything for now + if c.pol == 0 { + return + } + + // test if the tables are cached for this polynomial + cache.Lock() + defer cache.Unlock() + if t, ok := cache.entries[c.pol]; ok { + c.tables = t + return + } + + // else create a new entry + c.tables = &tables{} + cache.entries[c.pol] = c.tables + + // calculate table for sliding out bytes. The byte to slide out is used as + // the index for the table, the value contains the following: + // out_table[b] = Hash(b || 0 || ... || 0) + // \ windowsize-1 zero bytes / + // To slide out byte b_0 for window size w with known hash + // H := H(b_0 || ... || b_w), it is sufficient to add out_table[b_0]: + // H(b_0 || ... || b_w) + H(b_0 || 0 || ... || 0) + // = H(b_0 + b_0 || b_1 + 0 || ... || b_w + 0) + // = H( 0 || b_1 || ... || b_w) + // + // Afterwards a new byte can be shifted in. + for b := 0; b < 256; b++ { + var h Pol + + h = appendByte(h, byte(b), c.pol) + for i := 0; i < windowSize-1; i++ { + h = appendByte(h, 0, c.pol) + } + c.tables.out[b] = h + } + + // calculate table for reduction mod Polynomial + k := c.pol.Deg() + for b := 0; b < 256; b++ { + // mod_table[b] = A | B, where A = (b(x) * x^k mod pol) and B = b(x) * x^k + // + // The 8 bits above deg(Polynomial) determine what happens next and so + // these bits are used as a lookup to this table. The value is split in + // two parts: Part A contains the result of the modulus operation, part + // B is used to cancel out the 8 top bits so that one XOR operation is + // enough to reduce modulo Polynomial + c.tables.mod[b] = Pol(uint64(b)<= c.bmax { + n, err := io.ReadFull(c.rd, c.buf[:]) + c.chunkbuf = append(c.chunkbuf, c.buf[:n]...) + + if err == io.ErrUnexpectedEOF { + err = nil + } + + // io.ReadFull only returns io.EOF when no bytes could be read. If + // this is the case and we're in this branch, there are no more + // bytes to buffer, so this was the last chunk. If a different + // error has occurred, return that error and abandon the current + // chunk. + if err == io.EOF && !c.closed { + c.closed = true + + // return the buffer to the pool + buf := c.buf + c.buf = nil + bufPool.Put(buf) + + data := c.nextBytes() + + // return current chunk, if any bytes have been processed + if c.count > 0 { + return &Chunk{ + Start: c.start, + Length: c.count, + Cut: c.digest, + Digest: c.hashDigest(), + Data: data, + }, nil + } + } + + if err != nil { + return nil, err + } + + c.bpos = 0 + c.bmax = uint64(n) + } + + // check if bytes have to be dismissed before starting a new chunk + if c.pre > 0 { + n := c.bmax - c.bpos + if c.pre > uint64(n) { + c.pre -= uint64(n) + c.updateHash(c.buf[c.bpos:c.bmax]) + + c.count += uint64(n) + c.pos += uint64(n) + c.bpos = c.bmax + + continue + } + + c.updateHash(c.buf[c.bpos : c.bpos+c.pre]) + + c.bpos += c.pre + c.count += c.pre + c.pos += c.pre + c.pre = 0 + } + + add := c.count + for _, b := range c.buf[c.bpos:c.bmax] { + // inline c.slide(b) and append(b) to increase performance + out := c.window[c.wpos] + c.window[c.wpos] = b + c.digest ^= uint64(c.tables.out[out]) + c.wpos = (c.wpos + 1) % windowSize + + // c.append(b) + index := c.digest >> c.polShift + c.digest <<= 8 + c.digest |= uint64(b) + + c.digest ^= uint64(c.tables.mod[index]) + // end inline + + add++ + if add < c.MinSize { + continue + } + + if (c.digest&c.sizeMask) == 0 || add >= c.MaxSize { + i := add - c.count - 1 + c.updateHash(c.buf[c.bpos : c.bpos+uint64(i)+1]) + c.count = add + c.pos += uint64(i) + 1 + c.bpos += uint64(i) + 1 + + data := c.nextBytes() + + chunk := &Chunk{ + Start: c.start, + Length: c.count, + Cut: c.digest, + Digest: c.hashDigest(), + Data: data, + } + + c.reset() + + return chunk, nil + } + } + + steps := c.bmax - c.bpos + if steps > 0 { + c.updateHash(c.buf[c.bpos : c.bpos+steps]) + } + c.count += steps + c.pos += steps + c.bpos = c.bmax + } +} + +func dupBytes(b []byte) []byte { + out := make([]byte, len(b)) + copy(out, b) + return out +} + +func (c *Chunker) updateHash(data []byte) { + if c.h != nil { + // the hashes from crypto/sha* do not return an error + _, err := c.h.Write(data) + if err != nil { + panic(err) + } + } +} + +func (c *Chunker) hashDigest() []byte { + if c.h == nil { + return nil + } + + return c.h.Sum(nil) +} + +func (c *Chunker) append(b byte) { + index := c.digest >> c.polShift + c.digest <<= 8 + c.digest |= uint64(b) + + c.digest ^= uint64(c.tables.mod[index]) +} + +func (c *Chunker) slide(b byte) { + out := c.window[c.wpos] + c.window[c.wpos] = b + c.digest ^= uint64(c.tables.out[out]) + c.wpos = (c.wpos + 1) % windowSize + + c.append(b) +} + +func appendByte(hash Pol, b byte, pol Pol) Pol { + hash <<= 8 + hash |= Pol(b) + + return hash.Mod(pol) +} diff --git a/vendor/github.com/whyrusleeping/chunker/doc.go b/vendor/github.com/whyrusleeping/chunker/doc.go new file mode 100644 index 00000000..5537c172 --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/doc.go @@ -0,0 +1,82 @@ +// Copyright 2014 Alexander Neumann. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package chunker implements Content Defined Chunking (CDC) based on a rolling +Rabin Checksum. + +Choosing a Random Irreducible Polynomial + +The function RandomPolynomial() returns a new random polynomial of degree 53 +for use with the chunker. The degree 53 is chosen because it is the largest +prime below 64-8 = 56, so that the top 8 bits of an uint64 can be used for +optimising calculations in the chunker. + +A random polynomial is chosen selecting 64 random bits, masking away bits +64..54 and setting bit 53 to one (otherwise the polynomial is not of the +desired degree) and bit 0 to one (otherwise the polynomial is trivially +reducible), so that 51 bits are chosen at random. + +This process is repeated until Irreducible() returns true, then this +polynomials is returned. If this doesn't happen after 1 million tries, the +function returns an error. The probability for selecting an irreducible +polynomial at random is about 7.5% ( (2^53-2)/53 / 2^51), so the probability +that no irreducible polynomial has been found after 100 tries is lower than +0.04%. + +Verifying Irreducible Polynomials + +During development the results have been verified using the computational +discrete algebra system GAP, which can be obtained from the website at +http://www.gap-system.org/. + +For filtering a given list of polynomials in hexadecimal coefficient notation, +the following script can be used: + + # create x over F_2 = GF(2) + x := Indeterminate(GF(2), "x"); + + # test if polynomial is irreducible, i.e. the number of factors is one + IrredPoly := function (poly) + return (Length(Factors(poly)) = 1); + end;; + + # create a polynomial in x from the hexadecimal representation of the + # coefficients + Hex2Poly := function (s) + return ValuePol(CoefficientsQadic(IntHexString(s), 2), x); + end;; + + # list of candidates, in hex + candidates := [ "3DA3358B4DC173" ]; + + # create real polynomials + L := List(candidates, Hex2Poly); + + # filter and display the list of irreducible polynomials contained in L + Display(Filtered(L, x -> (IrredPoly(x)))); + +All irreducible polynomials from the list are written to the output. + +Background Literature + +An introduction to Rabin Fingerprints/Checksums can be found in the following articles: + +Michael O. Rabin (1981): "Fingerprinting by Random Polynomials" +http://www.xmailserver.org/rabin.pdf + +Ross N. Williams (1993): "A Painless Guide to CRC Error Detection Algorithms" +http://www.zlib.net/crc_v3.txt + +Andrei Z. Broder (1993): "Some Applications of Rabin's Fingerprinting Method" +http://www.xmailserver.org/rabin_apps.pdf + +Shuhong Gao and Daniel Panario (1997): "Tests and Constructions of Irreducible Polynomials over Finite Fields" +http://www.math.clemson.edu/~sgao/papers/GP97a.pdf + +Andrew Kadatch, Bob Jenkins (2007): "Everything we know about CRC but afraid to forget" +http://crcutil.googlecode.com/files/crc-doc.1.0.pdf + +*/ +package chunker diff --git a/vendor/github.com/whyrusleeping/chunker/package.json b/vendor/github.com/whyrusleeping/chunker/package.json new file mode 100644 index 00000000..b609d65a --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/package.json @@ -0,0 +1,16 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/chunker" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/chunker" + }, + "gxVersion": "0.12.1", + "language": "go", + "license": "", + "name": "chunker", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "0.0.1" +} + diff --git a/vendor/github.com/whyrusleeping/chunker/polynomials.go b/vendor/github.com/whyrusleeping/chunker/polynomials.go new file mode 100644 index 00000000..355da109 --- /dev/null +++ b/vendor/github.com/whyrusleeping/chunker/polynomials.go @@ -0,0 +1,278 @@ +package chunker + +import ( + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + "strconv" +) + +// Pol is a polynomial from F_2[X]. +type Pol uint64 + +// Add returns x+y. +func (x Pol) Add(y Pol) Pol { + r := Pol(uint64(x) ^ uint64(y)) + return r +} + +// mulOverflows returns true if the multiplication would overflow uint64. +// Code by Rob Pike, see +// https://groups.google.com/d/msg/golang-nuts/h5oSN5t3Au4/KaNQREhZh0QJ +func mulOverflows(a, b Pol) bool { + if a <= 1 || b <= 1 { + return false + } + c := a.mul(b) + d := c.Div(b) + if d != a { + return true + } + + return false +} + +func (x Pol) mul(y Pol) Pol { + if x == 0 || y == 0 { + return 0 + } + + var res Pol + for i := 0; i <= y.Deg(); i++ { + if (y & (1 << uint(i))) > 0 { + res = res.Add(x << uint(i)) + } + } + + return res +} + +// Mul returns x*y. When an overflow occurs, Mul panics. +func (x Pol) Mul(y Pol) Pol { + if mulOverflows(x, y) { + panic("multiplication would overflow uint64") + } + + return x.mul(y) +} + +// Deg returns the degree of the polynomial x. If x is zero, -1 is returned. +func (x Pol) Deg() int { + // the degree of 0 is -1 + if x == 0 { + return -1 + } + + var mask Pol = (1 << 63) + for i := 63; i >= 0; i-- { + // test if bit i is set + if x&mask > 0 { + // this is the degree of x + return i + } + mask >>= 1 + } + + // fall-through, return -1 + return -1 +} + +// String returns the coefficients in hex. +func (x Pol) String() string { + return "0x" + strconv.FormatUint(uint64(x), 16) +} + +// Expand returns the string representation of the polynomial x. +func (x Pol) Expand() string { + if x == 0 { + return "0" + } + + s := "" + for i := x.Deg(); i > 1; i-- { + if x&(1< 0 { + s += fmt.Sprintf("+x^%d", i) + } + } + + if x&2 > 0 { + s += "+x" + } + + if x&1 > 0 { + s += "+1" + } + + return s[1:] +} + +// DivMod returns x / d = q, and remainder r, +// see https://en.wikipedia.org/wiki/Division_algorithm +func (x Pol) DivMod(d Pol) (Pol, Pol) { + if x == 0 { + return 0, 0 + } + + if d == 0 { + panic("division by zero") + } + + D := d.Deg() + diff := x.Deg() - D + if diff < 0 { + return 0, x + } + + var q Pol + for diff >= 0 { + m := d << uint(diff) + q |= (1 << uint(diff)) + x = x.Add(m) + + diff = x.Deg() - D + } + + return q, x +} + +// Div returns the integer division result x / d. +func (x Pol) Div(d Pol) Pol { + q, _ := x.DivMod(d) + return q +} + +// Mod returns the remainder of x / d +func (x Pol) Mod(d Pol) Pol { + _, r := x.DivMod(d) + return r +} + +// I really dislike having a function that does not terminate, so specify a +// really large upper bound for finding a new irreducible polynomial, and +// return an error when no irreducible polynomial has been found within +// randPolMaxTries. +const randPolMaxTries = 1e6 + +// RandomPolynomial returns a new random irreducible polynomial of degree 53 +// (largest prime number below 64-8). There are (2^53-2/53) irreducible +// polynomials of degree 53 in F_2[X], c.f. Michael O. Rabin (1981): +// "Fingerprinting by Random Polynomials", page 4. If no polynomial could be +// found in one million tries, an error is returned. +func RandomPolynomial() (Pol, error) { + for i := 0; i < randPolMaxTries; i++ { + var f Pol + + // choose polynomial at random + err := binary.Read(rand.Reader, binary.LittleEndian, &f) + if err != nil { + return 0, err + } + + // mask away bits above bit 53 + f &= Pol((1 << 54) - 1) + + // set highest and lowest bit so that the degree is 53 and the + // polynomial is not trivially reducible + f |= (1 << 53) | 1 + + // test if f is irreducible + if f.Irreducible() { + return f, nil + } + } + + // If this is reached, we haven't found an irreducible polynomial in + // randPolMaxTries. This error is very unlikely to occur. + return 0, errors.New("unable to find new random irreducible polynomial") +} + +// GCD computes the Greatest Common Divisor x and f. +func (x Pol) GCD(f Pol) Pol { + if f == 0 { + return x + } + + if x == 0 { + return f + } + + if x.Deg() < f.Deg() { + x, f = f, x + } + + return f.GCD(x.Mod(f)) +} + +// Irreducible returns true iff x is irreducible over F_2. This function +// uses Ben Or's reducibility test. +// +// For details see "Tests and Constructions of Irreducible Polynomials over +// Finite Fields". +func (x Pol) Irreducible() bool { + for i := 1; i <= x.Deg()/2; i++ { + if x.GCD(qp(uint(i), x)) != 1 { + return false + } + } + + return true +} + +// MulMod computes x*f mod g +func (x Pol) MulMod(f, g Pol) Pol { + if x == 0 || f == 0 { + return 0 + } + + var res Pol + for i := 0; i <= f.Deg(); i++ { + if (f & (1 << uint(i))) > 0 { + a := x + for j := 0; j < i; j++ { + a = a.Mul(2).Mod(g) + } + res = res.Add(a).Mod(g) + } + } + + return res +} + +// qp computes the polynomial (x^(2^p)-x) mod g. This is needed for the +// reducibility test. +func qp(p uint, g Pol) Pol { + num := (1 << p) + i := 1 + + // start with x + res := Pol(2) + + for i < num { + // repeatedly square res + res = res.MulMod(res, g) + i *= 2 + } + + // add x + return res.Add(2).Mod(g) +} + +func (p Pol) MarshalJSON() ([]byte, error) { + buf := strconv.AppendUint([]byte{'"'}, uint64(p), 16) + buf = append(buf, '"') + return buf, nil +} + +func (p *Pol) UnmarshalJSON(data []byte) error { + if len(data) < 2 { + return errors.New("invalid string for polynomial") + } + n, err := strconv.ParseUint(string(data[1:len(data)-1]), 16, 64) + if err != nil { + return err + } + *p = Pol(n) + + return nil +} diff --git a/vendor/github.com/whyrusleeping/go-keyspace/.gxlastpubver b/vendor/github.com/whyrusleeping/go-keyspace/.gxlastpubver new file mode 100644 index 00000000..c343a53e --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/.gxlastpubver @@ -0,0 +1 @@ +0.0.0: QmaoGHsjT3vbZQWmfy6Lo4H4PoBTdQKRvCGda7G41eb6zd diff --git a/vendor/github.com/whyrusleeping/go-keyspace/LICENSE b/vendor/github.com/whyrusleeping/go-keyspace/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/go-keyspace/README.md b/vendor/github.com/whyrusleeping/go-keyspace/README.md new file mode 100644 index 00000000..d223061f --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/README.md @@ -0,0 +1,6 @@ +# go-keyspace +This is a package extracted from go-ipfs. + +Its purpose it to be used to compare a set of keys based on a given +metric. The primary metric used is XOR, as in kademlia. + diff --git a/vendor/github.com/whyrusleeping/go-keyspace/keyspace.go b/vendor/github.com/whyrusleeping/go-keyspace/keyspace.go new file mode 100644 index 00000000..e26a0e6d --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/keyspace.go @@ -0,0 +1,97 @@ +package keyspace + +import ( + "sort" + + "math/big" +) + +// Key represents an identifier in a KeySpace. It holds a reference to the +// associated KeySpace, as well references to both the Original identifier, +// as well as the new, KeySpace Bytes one. +type Key struct { + + // Space is the KeySpace this Key is related to. + Space KeySpace + + // Original is the original value of the identifier + Original []byte + + // Bytes is the new value of the identifier, in the KeySpace. + Bytes []byte +} + +// Equal returns whether this key is equal to another. +func (k1 Key) Equal(k2 Key) bool { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Equal(k1, k2) +} + +// Less returns whether this key comes before another. +func (k1 Key) Less(k2 Key) bool { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Less(k1, k2) +} + +// Distance returns this key's distance to another +func (k1 Key) Distance(k2 Key) *big.Int { + if k1.Space != k2.Space { + panic("k1 and k2 not in same key space.") + } + return k1.Space.Distance(k1, k2) +} + +// KeySpace is an object used to do math on identifiers. Each keyspace has its +// own properties and rules. See XorKeySpace. +type KeySpace interface { + + // Key converts an identifier into a Key in this space. + Key([]byte) Key + + // Equal returns whether keys are equal in this key space + Equal(Key, Key) bool + + // Distance returns the distance metric in this key space + Distance(Key, Key) *big.Int + + // Less returns whether the first key is smaller than the second. + Less(Key, Key) bool +} + +// byDistanceToCenter is a type used to sort Keys by proximity to a center. +type byDistanceToCenter struct { + Center Key + Keys []Key +} + +func (s byDistanceToCenter) Len() int { + return len(s.Keys) +} + +func (s byDistanceToCenter) Swap(i, j int) { + s.Keys[i], s.Keys[j] = s.Keys[j], s.Keys[i] +} + +func (s byDistanceToCenter) Less(i, j int) bool { + a := s.Center.Distance(s.Keys[i]) + b := s.Center.Distance(s.Keys[j]) + return a.Cmp(b) == -1 +} + +// SortByDistance takes a KeySpace, a center Key, and a list of Keys toSort. +// It returns a new list, where the Keys toSort have been sorted by their +// distance to the center Key. +func SortByDistance(sp KeySpace, center Key, toSort []Key) []Key { + toSortCopy := make([]Key, len(toSort)) + copy(toSortCopy, toSort) + bdtc := &byDistanceToCenter{ + Center: center, + Keys: toSortCopy, // copy + } + sort.Sort(bdtc) + return bdtc.Keys +} diff --git a/vendor/github.com/whyrusleeping/go-keyspace/package.json b/vendor/github.com/whyrusleeping/go-keyspace/package.json new file mode 100644 index 00000000..5ca4f544 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/package.json @@ -0,0 +1,9 @@ +{ + "name": "go-keyspace", + "author": "whyrusleeping", + "version": "1.0.0", + "language": "go", + "gx": { + "dvcsimport": "github.com/whyrusleeping/go-keyspace" + } +} diff --git a/vendor/github.com/whyrusleeping/go-keyspace/xor.go b/vendor/github.com/whyrusleeping/go-keyspace/xor.go new file mode 100644 index 00000000..24a542f7 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-keyspace/xor.go @@ -0,0 +1,74 @@ +package keyspace + +import ( + "bytes" + "crypto/sha256" + "math/big" +) + +// XORKeySpace is a KeySpace which: +// - normalizes identifiers using a cryptographic hash (sha256) +// - measures distance by XORing keys together +var XORKeySpace = &xorKeySpace{} +var _ KeySpace = XORKeySpace // ensure it conforms + +type xorKeySpace struct{} + +// Key converts an identifier into a Key in this space. +func (s *xorKeySpace) Key(id []byte) Key { + hash := sha256.Sum256(id) + key := hash[:] + return Key{ + Space: s, + Original: id, + Bytes: key, + } +} + +// Equal returns whether keys are equal in this key space +func (s *xorKeySpace) Equal(k1, k2 Key) bool { + return bytes.Equal(k1.Bytes, k2.Bytes) +} + +// Distance returns the distance metric in this key space +func (s *xorKeySpace) Distance(k1, k2 Key) *big.Int { + // XOR the keys + k3 := XOR(k1.Bytes, k2.Bytes) + + // interpret it as an integer + dist := big.NewInt(0).SetBytes(k3) + return dist +} + +// Less returns whether the first key is smaller than the second. +func (s *xorKeySpace) Less(k1, k2 Key) bool { + a := k1.Bytes + b := k2.Bytes + for i := 0; i < len(a); i++ { + if a[i] != b[i] { + return a[i] < b[i] + } + } + return true +} + +// ZeroPrefixLen returns the number of consecutive zeroes in a byte slice. +func ZeroPrefixLen(id []byte) int { + for i := 0; i < len(id); i++ { + for j := 0; j < 8; j++ { + if (id[i]>>uint8(7-j))&0x1 != 0 { + return i*8 + j + } + } + } + return len(id) * 8 +} + +// XOR takes two byte slices, XORs them together, returns the resulting slice. +func XOR(a, b []byte) []byte { + c := make([]byte, len(a)) + for i := 0; i < len(a); i++ { + c[i] = a[i] ^ b[i] + } + return c +} diff --git a/vendor/github.com/whyrusleeping/go-logging/.travis.yml b/vendor/github.com/whyrusleeping/go-logging/.travis.yml new file mode 100644 index 00000000..70e012b8 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.0 + - 1.1 + - tip diff --git a/vendor/github.com/whyrusleeping/go-logging/CONTRIBUTORS b/vendor/github.com/whyrusleeping/go-logging/CONTRIBUTORS new file mode 100644 index 00000000..958416ef --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/CONTRIBUTORS @@ -0,0 +1,5 @@ +Alec Thomas +Guilhem Lettron +Ivan Daniluk +Nimi Wariboko Jr +Róbert Selvek diff --git a/vendor/github.com/whyrusleeping/go-logging/LICENSE b/vendor/github.com/whyrusleeping/go-logging/LICENSE new file mode 100644 index 00000000..f1f6cfce --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 Örjan Persson. All rights reserved. + +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. diff --git a/vendor/github.com/whyrusleeping/go-logging/README.md b/vendor/github.com/whyrusleeping/go-logging/README.md new file mode 100644 index 00000000..56695508 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/README.md @@ -0,0 +1,89 @@ +## Golang logging library + +[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/op/go-logging) [![build](https://img.shields.io/travis/op/go-logging.svg?style=flat)](https://travis-ci.org/op/go-logging) + +Package logging implements a logging infrastructure for Go. Its output format +is customizable and supports different logging backends like syslog, file and +memory. Multiple backends can be utilized with different log levels per backend +and logger. + +## Example + +Let's have a look at an [example](examples/example.go) which demonstrates most +of the features found in this library. + +[![Example Output](examples/example.png)](examples/example.go) + +```go +package main + +import ( + "os" + + "github.com/op/go-logging" +) + +var log = logging.MustGetLogger("example") + +// Example format string. Everything except the message has a custom color +// which is dependent on the log level. Many fields have a custom output +// formatting too, eg. the time returns the hour down to the milli second. +var format = logging.MustStringFormatter( + "%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}", +) + +// Password is just an example type implementing the Redactor interface. Any +// time this is logged, the Redacted() function will be called. +type Password string + +func (p Password) Redacted() interface{} { + return logging.Redact(string(p)) +} + +func main() { + // For demo purposes, create two backend for os.Stderr. + backend1 := logging.NewLogBackend(os.Stderr, "", 0) + backend2 := logging.NewLogBackend(os.Stderr, "", 0) + + // For messages written to backend2 we want to add some additional + // information to the output, including the used log level and the name of + // the function. + backend2Formatter := logging.NewBackendFormatter(backend2, format) + + // Only errors and more severe messages should be sent to backend1 + backend1Leveled := logging.AddModuleLevel(backend1) + backend1Leveled.SetLevel(logging.ERROR, "") + + // Set the backends to be used. + logging.SetBackend(backend1Leveled, backend2Formatter) + + log.Debug("debug %s", Password("secret")) + log.Info("info") + log.Notice("notice") + log.Warning("warning") + log.Error("err") + log.Critical("crit") +} +``` + +## Installing + +### Using *go get* + + $ go get github.com/op/go-logging + +After this command *go-logging* is ready to use. Its source will be in: + + $GOROOT/src/pkg/github.com/op/go-logging + +You can use `go get -u` to update the package. + +## Documentation + +For docs, see http://godoc.org/github.com/op/go-logging or run: + + $ godoc github.com/op/go-logging + +## Additional resources + +* [wslog](https://godoc.org/github.com/cryptix/go/logging/wslog) -- exposes log messages through a WebSocket. diff --git a/vendor/github.com/whyrusleeping/go-logging/backend.go b/vendor/github.com/whyrusleeping/go-logging/backend.go new file mode 100644 index 00000000..6cd589ca --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/backend.go @@ -0,0 +1,39 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +// defaultBackend is the backend used for all logging calls. +var defaultBackend LeveledBackend + +// Backend is the interface which a log backend need to implement to be able to +// be used as a logging backend. +type Backend interface { + Log(Level, int, *Record) error +} + +// Set backend replaces the backend currently set with the given new logging +// backend. +func SetBackend(backends ...Backend) LeveledBackend { + var backend Backend + if len(backends) == 1 { + backend = backends[0] + } else { + backend = MultiLogger(backends...) + } + + defaultBackend = AddModuleLevel(backend) + return defaultBackend +} + +// SetLevel sets the logging level for the specified module. The module +// corresponds to the string specified in GetLogger. +func SetLevel(level Level, module string) { + defaultBackend.SetLevel(level, module) +} + +// GetLevel returns the logging level for the specified module. +func GetLevel(module string) Level { + return defaultBackend.GetLevel(module) +} diff --git a/vendor/github.com/whyrusleeping/go-logging/format.go b/vendor/github.com/whyrusleeping/go-logging/format.go new file mode 100644 index 00000000..99b1ddb7 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/format.go @@ -0,0 +1,368 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + "path" + "path/filepath" + "regexp" + "runtime" + "strings" + "sync" + "time" +) + +// TODO see Formatter interface in fmt/print.go +// TODO try text/template, maybe it have enough performance +// TODO other template systems? +// TODO make it possible to specify formats per backend? +type fmtVerb int + +const ( + fmtVerbTime fmtVerb = iota + fmtVerbLevel + fmtVerbId + fmtVerbPid + fmtVerbProgram + fmtVerbModule + fmtVerbMessage + fmtVerbLongfile + fmtVerbShortfile + fmtVerbLongpkg + fmtVerbShortpkg + fmtVerbLongfunc + fmtVerbShortfunc + fmtVerbLevelColor + + // Keep last, there are no match for these below. + fmtVerbUnknown + fmtVerbStatic +) + +var fmtVerbs = []string{ + "time", + "level", + "id", + "pid", + "program", + "module", + "message", + "longfile", + "shortfile", + "longpkg", + "shortpkg", + "longfunc", + "shortfunc", + "color", +} + +const rfc3339Milli = "2006-01-02T15:04:05.999Z07:00" + +var defaultVerbsLayout = []string{ + rfc3339Milli, + "s", + "d", + "d", + "s", + "s", + "s", + "s", + "s", + "s", + "s", + "s", + "s", + "", +} + +var ( + pid = os.Getpid() + program = filepath.Base(os.Args[0]) +) + +func getFmtVerbByName(name string) fmtVerb { + for i, verb := range fmtVerbs { + if name == verb { + return fmtVerb(i) + } + } + return fmtVerbUnknown +} + +// Formatter is the required interface for a custom log record formatter. +type Formatter interface { + Format(calldepth int, r *Record, w io.Writer) error +} + +// formatter is used by all backends unless otherwise overriden. +var formatter struct { + sync.RWMutex + def Formatter +} + +func getFormatter() Formatter { + formatter.RLock() + defer formatter.RUnlock() + return formatter.def +} + +var ( + // DefaultFormatter is the default formatter used and is only the message. + DefaultFormatter Formatter = MustStringFormatter("%{message}") + + // Glog format + GlogFormatter Formatter = MustStringFormatter("%{level:.1s}%{time:0102 15:04:05.999999} %{pid} %{shortfile}] %{message}") +) + +// SetFormatter sets the default formatter for all new backends. A backend will +// fetch this value once it is needed to format a record. Note that backends +// will cache the formatter after the first point. For now, make sure to set +// the formatter before logging. +func SetFormatter(f Formatter) { + formatter.Lock() + defer formatter.Unlock() + formatter.def = f +} + +var formatRe *regexp.Regexp = regexp.MustCompile(`%{([a-z]+)(?::(.*?[^\\]))?}`) + +type part struct { + verb fmtVerb + layout string +} + +// stringFormatter contains a list of parts which explains how to build the +// formatted string passed on to the logging backend. +type stringFormatter struct { + parts []part +} + +// NewStringFormatter returns a new Formatter which outputs the log record as a +// string based on the 'verbs' specified in the format string. +// +// The verbs: +// +// General: +// %{id} Sequence number for log message (uint64). +// %{pid} Process id (int) +// %{time} Time when log occurred (time.Time) +// %{level} Log level (Level) +// %{module} Module (string) +// %{program} Basename of os.Args[0] (string) +// %{message} Message (string) +// %{longfile} Full file name and line number: /a/b/c/d.go:23 +// %{shortfile} Final file name element and line number: d.go:23 +// %{color} ANSI color based on log level +// +// For normal types, the output can be customized by using the 'verbs' defined +// in the fmt package, eg. '%{id:04d}' to make the id output be '%04d' as the +// format string. +// +// For time.Time, use the same layout as time.Format to change the time format +// when output, eg "2006-01-02T15:04:05.999Z-07:00". +// +// For the 'color' verb, the output can be adjusted to either use bold colors, +// i.e., '%{color:bold}' or to reset the ANSI attributes, i.e., +// '%{color:reset}' Note that if you use the color verb explicitly, be sure to +// reset it or else the color state will persist past your log message. e.g., +// "%{color:bold}%{time:15:04:05} %{level:-8s}%{color:reset} %{message}" will +// just colorize the time and level, leaving the message uncolored. +// +// There's also a couple of experimental 'verbs'. These are exposed to get +// feedback and needs a bit of tinkering. Hence, they might change in the +// future. +// +// Experimental: +// %{longpkg} Full package path, eg. github.com/go-logging +// %{shortpkg} Base package path, eg. go-logging +// %{longfunc} Full function name, eg. littleEndian.PutUint32 +// %{shortfunc} Base function name, eg. PutUint32 +func NewStringFormatter(format string) (*stringFormatter, error) { + var fmter = &stringFormatter{} + + // Find the boundaries of all %{vars} + matches := formatRe.FindAllStringSubmatchIndex(format, -1) + if matches == nil { + return nil, errors.New("logger: invalid log format: " + format) + } + + // Collect all variables and static text for the format + prev := 0 + for _, m := range matches { + start, end := m[0], m[1] + if start > prev { + fmter.add(fmtVerbStatic, format[prev:start]) + } + + name := format[m[2]:m[3]] + verb := getFmtVerbByName(name) + if verb == fmtVerbUnknown { + return nil, errors.New("logger: unknown variable: " + name) + } + + // Handle layout customizations or use the default. If this is not for the + // time or color formatting, we need to prefix with %. + layout := defaultVerbsLayout[verb] + if m[4] != -1 { + layout = format[m[4]:m[5]] + } + if verb != fmtVerbTime && verb != fmtVerbLevelColor { + layout = "%" + layout + } + + fmter.add(verb, layout) + prev = end + } + end := format[prev:] + if end != "" { + fmter.add(fmtVerbStatic, end) + } + + // Make a test run to make sure we can format it correctly. + t, err := time.Parse(time.RFC3339, "2010-02-04T21:00:57-08:00") + if err != nil { + panic(err) + } + r := &Record{ + Id: 12345, + Time: t, + Module: "logger", + fmt: "hello %s", + args: []interface{}{"go"}, + } + if err := fmter.Format(0, r, &bytes.Buffer{}); err != nil { + return nil, err + } + + return fmter, nil +} + +// MustStringFormatter is equivalent to NewStringFormatter with a call to panic +// on error. +func MustStringFormatter(format string) *stringFormatter { + f, err := NewStringFormatter(format) + if err != nil { + panic("Failed to initialized string formatter: " + err.Error()) + } + return f +} + +func (f *stringFormatter) add(verb fmtVerb, layout string) { + f.parts = append(f.parts, part{verb, layout}) +} + +func (f *stringFormatter) Format(calldepth int, r *Record, output io.Writer) error { + for _, part := range f.parts { + if part.verb == fmtVerbStatic { + output.Write([]byte(part.layout)) + } else if part.verb == fmtVerbTime { + output.Write([]byte(r.Time.Format(part.layout))) + } else if part.verb == fmtVerbLevelColor { + if part.layout == "bold" { + output.Write([]byte(boldcolors[r.Level])) + } else if part.layout == "reset" { + output.Write([]byte("\033[0m")) + } else { + output.Write([]byte(colors[r.Level])) + } + } else { + var v interface{} + switch part.verb { + case fmtVerbLevel: + v = r.Level + break + case fmtVerbId: + v = r.Id + break + case fmtVerbPid: + v = pid + break + case fmtVerbProgram: + v = program + break + case fmtVerbModule: + v = r.Module + break + case fmtVerbMessage: + v = r.Message() + break + case fmtVerbLongfile, fmtVerbShortfile: + _, file, line, ok := runtime.Caller(calldepth + 1) + if !ok { + file = "???" + line = 0 + } else if part.verb == fmtVerbShortfile { + file = filepath.Base(file) + } + v = fmt.Sprintf("%s:%d", file, line) + case fmtVerbLongfunc, fmtVerbShortfunc, + fmtVerbLongpkg, fmtVerbShortpkg: + // TODO cache pc + v = "???" + if pc, _, _, ok := runtime.Caller(calldepth + 1); ok { + if f := runtime.FuncForPC(pc); f != nil { + v = formatFuncName(part.verb, f.Name()) + } + } + default: + panic("unhandled format part") + } + fmt.Fprintf(output, part.layout, v) + } + } + return nil +} + +// formatFuncName tries to extract certain part of the runtime formatted +// function name to some pre-defined variation. +// +// This function is known to not work properly if the package path or name +// contains a dot. +func formatFuncName(v fmtVerb, f string) string { + i := strings.LastIndex(f, "/") + j := strings.Index(f[i+1:], ".") + if j < 1 { + return "???" + } + pkg, fun := f[:i+j+1], f[i+j+2:] + switch v { + case fmtVerbLongpkg: + return pkg + case fmtVerbShortpkg: + return path.Base(pkg) + case fmtVerbLongfunc: + return fun + case fmtVerbShortfunc: + i = strings.LastIndex(fun, ".") + return fun[i+1:] + } + panic("unexpected func formatter") +} + +// backendFormatter combines a backend with a specific formatter making it +// possible to have different log formats for different backends. +type backendFormatter struct { + b Backend + f Formatter +} + +// NewBackendFormatter creates a new backend which makes all records that +// passes through it beeing formatted by the specific formatter. +func NewBackendFormatter(b Backend, f Formatter) *backendFormatter { + return &backendFormatter{b, f} +} + +// Log implements the Log function required by the Backend interface. +func (bf *backendFormatter) Log(level Level, calldepth int, r *Record) error { + // Make a shallow copy of the record and replace any formatter + r2 := *r + r2.formatter = bf.f + return bf.b.Log(level, calldepth+1, &r2) +} diff --git a/vendor/github.com/whyrusleeping/go-logging/level.go b/vendor/github.com/whyrusleeping/go-logging/level.go new file mode 100644 index 00000000..92934643 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/level.go @@ -0,0 +1,129 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +import ( + "errors" + "strings" + "sync" +) + +var ErrInvalidLogLevel = errors.New("logger: invalid log level") + +// Level defines all available log levels for log messages. +type Level int + +const ( + CRITICAL Level = iota + ERROR + WARNING + NOTICE + INFO + DEBUG +) + +var levelNames = []string{ + "CRITICAL", + "ERROR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG", +} + +// String returns the string representation of a logging level. +func (p Level) String() string { + return levelNames[p] +} + +// LogLevel returns the log level from a string representation. +func LogLevel(level string) (Level, error) { + for i, name := range levelNames { + if strings.EqualFold(name, level) { + return Level(i), nil + } + } + return ERROR, ErrInvalidLogLevel +} + +type Leveled interface { + GetLevel(string) Level + SetLevel(Level, string) + IsEnabledFor(Level, string) bool +} + +// LeveledBackend is a log backend with additional knobs for setting levels on +// individual modules to different levels. +type LeveledBackend interface { + Backend + Leveled +} + +type moduleLeveled struct { + sync.RWMutex + levels map[string]Level + backend Backend + formatter Formatter + once sync.Once +} + +// AddModuleLevel wraps a log backend with knobs to have different log levels +// for different modules. +func AddModuleLevel(backend Backend) LeveledBackend { + var leveled LeveledBackend + var ok bool + if leveled, ok = backend.(LeveledBackend); !ok { + leveled = &moduleLeveled{ + levels: make(map[string]Level), + backend: backend, + } + } + return leveled +} + +// GetLevel returns the log level for the given module. +func (l *moduleLeveled) GetLevel(module string) Level { + l.RLock() + defer l.RUnlock() + level, exists := l.levels[module] + if exists == false { + level, exists = l.levels[""] + // no configuration exists, default to debug + if exists == false { + level = DEBUG + } + } + return level +} + +// SetLevel sets the log level for the given module. +func (l *moduleLeveled) SetLevel(level Level, module string) { + l.Lock() + defer l.Unlock() + l.levels[module] = level +} + +// IsEnabledFor will return true if logging is enabled for the given module. +func (l *moduleLeveled) IsEnabledFor(level Level, module string) bool { + return level <= l.GetLevel(module) +} + +func (l *moduleLeveled) Log(level Level, calldepth int, rec *Record) (err error) { + if l.IsEnabledFor(level, rec.Module) { + // TODO get rid of traces of formatter here. BackendFormatter should be used. + rec.formatter = l.getFormatterAndCacheCurrent() + err = l.backend.Log(level, calldepth+1, rec) + } + return +} + +func (l *moduleLeveled) getFormatterAndCacheCurrent() Formatter { + l.once.Do(func() { + if l.formatter == nil { + l.formatter = getFormatter() + } + }) + return l.formatter +} diff --git a/vendor/github.com/whyrusleeping/go-logging/log.go b/vendor/github.com/whyrusleeping/go-logging/log.go new file mode 100644 index 00000000..f009f8af --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/log.go @@ -0,0 +1,80 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +import ( + "bytes" + "fmt" + "io" + "log" +) + +// TODO initialize here +var colors []string +var boldcolors []string + +type color int + +const ( + colorBlack = (iota + 30) + colorRed + colorGreen + colorYellow + colorBlue + colorMagenta + colorCyan + colorWhite +) + +// LogBackend utilizes the standard log module. +type LogBackend struct { + Logger *log.Logger + Color bool +} + +// NewLogBackend creates a new LogBackend. +func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend { + return &LogBackend{Logger: log.New(out, prefix, flag)} +} + +func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error { + if b.Color { + buf := &bytes.Buffer{} + buf.Write([]byte(colors[level])) + buf.Write([]byte(rec.Formatted(calldepth + 1))) + buf.Write([]byte("\033[0m")) + // For some reason, the Go logger arbitrarily decided "2" was the correct + // call depth... + return b.Logger.Output(calldepth+2, buf.String()) + } else { + return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1)) + } + panic("should not be reached") +} + +func colorSeq(color color) string { + return fmt.Sprintf("\033[%dm", int(color)) +} + +func colorSeqBold(color color) string { + return fmt.Sprintf("\033[%d;1m", int(color)) +} + +func init() { + colors = []string{ + CRITICAL: colorSeq(colorMagenta), + ERROR: colorSeq(colorRed), + WARNING: colorSeq(colorYellow), + NOTICE: colorSeq(colorGreen), + DEBUG: colorSeq(colorCyan), + } + boldcolors = []string{ + CRITICAL: colorSeqBold(colorMagenta), + ERROR: colorSeqBold(colorRed), + WARNING: colorSeqBold(colorYellow), + NOTICE: colorSeqBold(colorGreen), + DEBUG: colorSeqBold(colorCyan), + } +} diff --git a/vendor/github.com/whyrusleeping/go-logging/logger.go b/vendor/github.com/whyrusleeping/go-logging/logger.go new file mode 100644 index 00000000..42b49495 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/logger.go @@ -0,0 +1,279 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package logging implements a logging infrastructure for Go. It supports +// different logging backends like syslog, file and memory. Multiple backends +// can be utilized with different log levels per backend and logger. +package logging + +import ( + "bytes" + "fmt" + "log" + "os" + "strings" + "sync/atomic" + "time" +) + +// Redactor is an interface for types that may contain sensitive information +// (like passwords), which shouldn't be printed to the log. The idea was found +// in relog as part of the vitness project. +type Redactor interface { + Redacted() interface{} +} + +// Redact returns a string of * having the same length as s. +func Redact(s string) string { + return strings.Repeat("*", len(s)) +} + +var ( + // Sequence number is incremented and utilized for all log records created. + sequenceNo uint64 + + // timeNow is a customizable for testing purposes. + timeNow = time.Now +) + +// Record represents a log record and contains the timestamp when the record +// was created, an increasing id, filename and line and finally the actual +// formatted log line. +type Record struct { + Id uint64 + Time time.Time + Module string + Level Level + + // message is kept as a pointer to have shallow copies update this once + // needed. + message *string + args []interface{} + fmt string + formatter Formatter + formatted string +} + +// Formatted returns the string-formatted version of a record. +func (r *Record) Formatted(calldepth int) string { + if r.formatted == "" { + var buf bytes.Buffer + r.formatter.Format(calldepth+1, r, &buf) + r.formatted = buf.String() + } + return r.formatted +} + +// Message returns a string message for outputting. Redacts any record args +// that implement the Redactor interface +func (r *Record) Message() string { + if r.message == nil { + // Redact the arguments that implements the Redactor interface + for i, arg := range r.args { + if redactor, ok := arg.(Redactor); ok == true { + r.args[i] = redactor.Redacted() + } + } + msg := fmt.Sprintf(r.fmt, r.args...) + r.message = &msg + } + return *r.message +} + +// Logger is a logging unit. It controls the flow of messages to a given +// (swappable) backend. +type Logger struct { + Module string + backend LeveledBackend + haveBackend bool + + // ExtraCallDepth can be used to add additional call depth when getting the + // calling function. This is normally used when wrapping a logger. + ExtraCalldepth int +} + +// SetBackend changes the backend of the logger. +func (l *Logger) SetBackend(backend LeveledBackend) { + l.backend = backend + l.haveBackend = true +} + +// GetLogger creates and returns a Logger object based on the module name. +// TODO call NewLogger and remove MustGetLogger? +func GetLogger(module string) (*Logger, error) { + return &Logger{Module: module}, nil +} + +// MustGetLogger is like GetLogger but panics if the logger can't be created. +// It simplifies safe initialization of a global logger for eg. a package. +func MustGetLogger(module string) *Logger { + logger, err := GetLogger(module) + if err != nil { + panic("logger: " + module + ": " + err.Error()) + } + return logger +} + +// Reset restores the internal state of the logging library. +func Reset() { + // TODO make a global Init() method to be less magic? or make it such that + // if there's no backends at all configured, we could use some tricks to + // automatically setup backends based if we have a TTY or not. + sequenceNo = 0 + b := SetBackend(NewLogBackend(os.Stderr, "", log.LstdFlags)) + b.SetLevel(DEBUG, "") + SetFormatter(DefaultFormatter) + timeNow = time.Now +} + +// InitForTesting is a convenient method when using logging in a test. Once +// called, the time will be frozen to January 1, 1970 UTC. +func InitForTesting(level Level) *MemoryBackend { + Reset() + + memoryBackend := NewMemoryBackend(10240) + + leveledBackend := AddModuleLevel(memoryBackend) + leveledBackend.SetLevel(level, "") + SetBackend(leveledBackend) + + timeNow = func() time.Time { + return time.Unix(0, 0).UTC() + } + return memoryBackend +} + +// IsEnabledFor returns true if the logger is enabled for the given level. +func (l *Logger) IsEnabledFor(level Level) bool { + return defaultBackend.IsEnabledFor(level, l.Module) +} + +func (l *Logger) log(lvl Level, format string, args ...interface{}) { + if !l.IsEnabledFor(lvl) { + return + } + + // Create the logging record and pass it in to the backend + record := &Record{ + Id: atomic.AddUint64(&sequenceNo, 1), + Time: timeNow(), + Module: l.Module, + Level: lvl, + fmt: format, + args: args, + } + + // TODO use channels to fan out the records to all backends? + // TODO in case of errors, do something (tricky) + + // calldepth=2 brings the stack up to the caller of the level + // methods, Info(), Fatal(), etc. + // ExtraCallDepth allows this to be extended further up the stack in case we + // are wrapping these methods, eg. to expose them package level + if l.haveBackend { + l.backend.Log(lvl, 2+l.ExtraCalldepth, record) + return + } + + defaultBackend.Log(lvl, 2+l.ExtraCalldepth, record) +} + +// Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1). +func (l *Logger) Fatal(args ...interface{}) { + s := fmt.Sprint(args...) + l.log(CRITICAL, "%s", s) + os.Exit(1) +} + +// Fatalf is equivalent to l.Critical followed by a call to os.Exit(1). +func (l *Logger) Fatalf(format string, args ...interface{}) { + l.log(CRITICAL, format, args...) + os.Exit(1) +} + +// Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic(). +func (l *Logger) Panic(args ...interface{}) { + s := fmt.Sprint(args...) + l.log(CRITICAL, "%s", s) + panic(s) +} + +// Panicf is equivalent to l.Critical followed by a call to panic(). +func (l *Logger) Panicf(format string, args ...interface{}) { + s := fmt.Sprintf(format, args...) + l.log(CRITICAL, "%s", s) + panic(s) +} + +// Critical logs a message using CRITICAL as log level. (fmt.Sprint()) +func (l *Logger) Critical(args ...interface{}) { + l.log(CRITICAL, defaultArgsFormat(len(args)), args...) +} + +// Criticalf logs a message using CRITICAL as log level. +func (l *Logger) Criticalf(format string, args ...interface{}) { + l.log(CRITICAL, format, args...) +} + +// Error logs a message using ERROR as log level. (fmt.Sprint()) +func (l *Logger) Error(args ...interface{}) { + l.log(ERROR, defaultArgsFormat(len(args)), args...) +} + +// Errorf logs a message using ERROR as log level. +func (l *Logger) Errorf(format string, args ...interface{}) { + l.log(ERROR, format, args...) +} + +// Warning logs a message using WARNING as log level. +func (l *Logger) Warning(args ...interface{}) { + l.log(WARNING, defaultArgsFormat(len(args)), args...) +} + +// Warningf logs a message using WARNING as log level. +func (l *Logger) Warningf(format string, args ...interface{}) { + l.log(WARNING, format, args...) +} + +// Notice logs a message using NOTICE as log level. +func (l *Logger) Notice(args ...interface{}) { + l.log(NOTICE, defaultArgsFormat(len(args)), args...) +} + +// Noticef logs a message using NOTICE as log level. +func (l *Logger) Noticef(format string, args ...interface{}) { + l.log(NOTICE, format, args...) +} + +// Info logs a message using INFO as log level. +func (l *Logger) Info(args ...interface{}) { + l.log(INFO, defaultArgsFormat(len(args)), args...) +} + +// Infof logs a message using INFO as log level. +func (l *Logger) Infof(format string, args ...interface{}) { + l.log(INFO, format, args...) +} + +// Debug logs a message using DEBUG as log level. +func (l *Logger) Debug(args ...interface{}) { + l.log(DEBUG, defaultArgsFormat(len(args)), args...) +} + +// Debugf logs a message using DEBUG as log level. +func (l *Logger) Debugf(format string, args ...interface{}) { + l.log(DEBUG, format, args...) +} + +func defaultArgsFormat(argc int) string { + f := strings.Repeat("%s ", argc) + if argc > 0 { + f = f[:len(f) - 1] + } + return f +} + +func init() { + Reset() +} diff --git a/vendor/github.com/whyrusleeping/go-logging/memory.go b/vendor/github.com/whyrusleeping/go-logging/memory.go new file mode 100644 index 00000000..c59b92dd --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/memory.go @@ -0,0 +1,217 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +import ( + "sync" + "sync/atomic" + "unsafe" +) + +// TODO pick one of the memory backends and stick with it or share interface. + +// Node is a record node pointing to an optional next node. +type node struct { + next *node + Record *Record +} + +// Next returns the next record node. If there's no node available, it will +// return nil. +func (n *node) Next() *node { + return n.next +} + +// MemoryBackend is a simple memory based logging backend that will not produce +// any output but merly keep records, up to the given size, in memory. +type MemoryBackend struct { + size int32 + maxSize int32 + head, tail unsafe.Pointer +} + +// NewMemoryBackend creates a simple in-memory logging backend. +func NewMemoryBackend(size int) *MemoryBackend { + return &MemoryBackend{maxSize: int32(size)} +} + +// Log implements the Log method required by Backend. +func (b *MemoryBackend) Log(level Level, calldepth int, rec *Record) error { + var size int32 + + n := &node{Record: rec} + np := unsafe.Pointer(n) + + // Add the record to the tail. If there's no records available, tail and + // head will both be nil. When we successfully set the tail and the previous + // value was nil, it's safe to set the head to the current value too. + for { + tailp := b.tail + swapped := atomic.CompareAndSwapPointer( + &b.tail, + tailp, + np, + ) + if swapped == true { + if tailp == nil { + b.head = np + } else { + (*node)(tailp).next = n + } + size = atomic.AddInt32(&b.size, 1) + break + } + } + + // Since one record was added, we might have overflowed the list. Remove + // a record if that is the case. The size will fluctate a bit, but + // eventual consistent. + if b.maxSize > 0 && size > b.maxSize { + for { + headp := b.head + head := (*node)(b.head) + if head.next == nil { + break + } + swapped := atomic.CompareAndSwapPointer( + &b.head, + headp, + unsafe.Pointer(head.next), + ) + if swapped == true { + atomic.AddInt32(&b.size, -1) + break + } + } + } + return nil +} + +// Head returns the oldest record node kept in memory. It can be used to +// iterate over records, one by one, up to the last record. +// +// Note: new records can get added while iterating. Hence the number of records +// iterated over might be larger than the maximum size. +func (b *MemoryBackend) Head() *node { + return (*node)(b.head) +} + +type event int + +const ( + eventFlush event = iota + eventStop +) + +// ChannelMemoryBackend is very similar to the MemoryBackend, except that it +// internally utilizes a channel. +type ChannelMemoryBackend struct { + maxSize int + size int + incoming chan *Record + events chan event + mu sync.Mutex + running bool + flushWg sync.WaitGroup + stopWg sync.WaitGroup + head, tail *node +} + +// NewChannelMemoryBackend creates a simple in-memory logging backend which +// utilizes a go channel for communication. +// +// Start will automatically be called by this function. +func NewChannelMemoryBackend(size int) *ChannelMemoryBackend { + backend := &ChannelMemoryBackend{ + maxSize: size, + incoming: make(chan *Record, 1024), + events: make(chan event), + } + backend.Start() + return backend +} + +// Start launches the internal goroutine which starts processing data from the +// input channel. +func (b *ChannelMemoryBackend) Start() { + b.mu.Lock() + defer b.mu.Unlock() + + // Launch the goroutine unless it's already running. + if b.running != true { + b.running = true + b.stopWg.Add(1) + go b.process() + } +} + +func (b *ChannelMemoryBackend) process() { + defer b.stopWg.Done() + for { + select { + case rec := <-b.incoming: + b.insertRecord(rec) + case e := <-b.events: + switch e { + case eventStop: + return + case eventFlush: + for len(b.incoming) > 0 { + b.insertRecord(<-b.incoming) + } + b.flushWg.Done() + } + } + } +} + +func (b *ChannelMemoryBackend) insertRecord(rec *Record) { + prev := b.tail + b.tail = &node{Record: rec} + if prev == nil { + b.head = b.tail + } else { + prev.next = b.tail + } + + if b.maxSize > 0 && b.size >= b.maxSize { + b.head = b.head.next + } else { + b.size += 1 + } +} + +// Flush waits until all records in the buffered channel have been processed. +func (b *ChannelMemoryBackend) Flush() { + b.flushWg.Add(1) + b.events <- eventFlush + b.flushWg.Wait() +} + +// Stop signals the internal goroutine to exit and waits until it have. +func (b *ChannelMemoryBackend) Stop() { + b.mu.Lock() + if b.running == true { + b.running = false + b.events <- eventStop + } + b.mu.Unlock() + b.stopWg.Wait() +} + +// Log implements the Log method required by Backend. +func (b *ChannelMemoryBackend) Log(level Level, calldepth int, rec *Record) error { + b.incoming <- rec + return nil +} + +// Head returns the oldest record node kept in memory. It can be used to +// iterate over records, one by one, up to the last record. +// +// Note: new records can get added while iterating. Hence the number of records +// iterated over might be larger than the maximum size. +func (b *ChannelMemoryBackend) Head() *node { + return b.head +} diff --git a/vendor/github.com/whyrusleeping/go-logging/multi.go b/vendor/github.com/whyrusleeping/go-logging/multi.go new file mode 100644 index 00000000..3731653e --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/multi.go @@ -0,0 +1,65 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logging + +// TODO remove Level stuff from the multi logger. Do one thing. + +// multiLogger is a log multiplexer which can be used to utilize multiple log +// backends at once. +type multiLogger struct { + backends []LeveledBackend +} + +// MultiLogger creates a logger which contain multiple loggers. +func MultiLogger(backends ...Backend) LeveledBackend { + var leveledBackends []LeveledBackend + for _, backend := range backends { + leveledBackends = append(leveledBackends, AddModuleLevel(backend)) + } + return &multiLogger{leveledBackends} +} + +// Log passes the log record to all backends. +func (b *multiLogger) Log(level Level, calldepth int, rec *Record) (err error) { + for _, backend := range b.backends { + if backend.IsEnabledFor(level, rec.Module) { + // Shallow copy of the record for the formatted cache on Record and get the + // record formatter from the backend. + r2 := *rec + if e := backend.Log(level, calldepth+1, &r2); e != nil { + err = e + } + } + } + return +} + +// GetLevel returns the highest level enabled by all backends. +func (b *multiLogger) GetLevel(module string) Level { + var level Level + for _, backend := range b.backends { + if backendLevel := backend.GetLevel(module); backendLevel > level { + level = backendLevel + } + } + return level +} + +// SetLevel propagates the same level to all backends. +func (b *multiLogger) SetLevel(level Level, module string) { + for _, backend := range b.backends { + backend.SetLevel(level, module) + } +} + +// IsEnabledFor returns true if any of the backends are enabled for it. +func (b *multiLogger) IsEnabledFor(level Level, module string) bool { + for _, backend := range b.backends { + if backend.IsEnabledFor(level, module) { + return true + } + } + return false +} diff --git a/vendor/github.com/whyrusleeping/go-logging/syslog.go b/vendor/github.com/whyrusleeping/go-logging/syslog.go new file mode 100644 index 00000000..9a5c8f5d --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-logging/syslog.go @@ -0,0 +1,52 @@ +// Copyright 2013, Örjan Persson. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !windows,!plan9 + +package logging + +import "log/syslog" + +// SyslogBackend is a simple logger to syslog backend. It automatically maps +// the internal log levels to appropriate syslog log levels. +type SyslogBackend struct { + Writer *syslog.Writer +} + +// NewSyslogBackend connects to the syslog daemon using UNIX sockets with the +// given prefix. If prefix is not given, the prefix will be derived from the +// launched command. +func NewSyslogBackend(prefix string) (b *SyslogBackend, err error) { + var w *syslog.Writer + w, err = syslog.New(syslog.LOG_CRIT, prefix) + return &SyslogBackend{w}, err +} + +// NewSyslogBackendPriority is the same as NewSyslogBackend, but with custom +// syslog priority, like syslog.LOG_LOCAL3|syslog.LOG_DEBUG etc. +func NewSyslogBackendPriority(prefix string, priority syslog.Priority) (b *SyslogBackend, err error) { + var w *syslog.Writer + w, err = syslog.New(priority, prefix) + return &SyslogBackend{w}, err +} + +func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error { + line := rec.Formatted(calldepth + 1) + switch level { + case CRITICAL: + return b.Writer.Crit(line) + case ERROR: + return b.Writer.Err(line) + case WARNING: + return b.Writer.Warning(line) + case NOTICE: + return b.Writer.Notice(line) + case INFO: + return b.Writer.Info(line) + case DEBUG: + return b.Writer.Debug(line) + default: + } + panic("unhandled log level") +} diff --git a/vendor/github.com/whyrusleeping/go-notifier/LICENSE b/vendor/github.com/whyrusleeping/go-notifier/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-notifier/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/go-notifier/notifier.go b/vendor/github.com/whyrusleeping/go-notifier/notifier.go new file mode 100644 index 00000000..33302cfd --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-notifier/notifier.go @@ -0,0 +1,146 @@ +// Package notifier provides a simple notification dispatcher +// meant to be embedded in larger structres who wish to allow +// clients to sign up for event notifications. +package notifier + +import ( + "sync" + + process "github.com/jbenet/goprocess" + ratelimit "github.com/jbenet/goprocess/ratelimit" +) + +// Notifiee is a generic interface. Clients implement +// their own Notifiee interfaces to ensure type-safety +// of notifications: +// +// type RocketNotifiee interface{ +// Countdown(r Rocket, countdown time.Duration) +// LiftedOff(Rocket) +// ReachedOrbit(Rocket) +// Detached(Rocket, Capsule) +// Landed(Rocket) +// } +// +type Notifiee interface{} + +// Notifier is a notification dispatcher. It's meant +// to be composed, and its zero-value is ready to be used. +// +// type Rocket struct { +// notifier notifier.Notifier +// } +// +type Notifier struct { + mu sync.RWMutex // guards notifiees + nots map[Notifiee]struct{} + lim *ratelimit.RateLimiter +} + +// RateLimited returns a rate limited Notifier. only limit goroutines +// will be spawned. If limit is zero, no rate limiting happens. This +// is the same as `Notifier{}`. +func RateLimited(limit int) Notifier { + n := Notifier{} + if limit > 0 { + n.lim = ratelimit.NewRateLimiter(process.Background(), limit) + } + return n +} + +// Notify signs up Notifiee e for notifications. This function +// is meant to be called behind your own type-safe function(s): +// +// // generic function for pattern-following +// func (r *Rocket) Notify(n Notifiee) { +// r.notifier.Notify(n) +// } +// +// // or as part of other functions +// func (r *Rocket) Onboard(a Astronaut) { +// r.astronauts = append(r.austronauts, a) +// r.notifier.Notify(a) +// } +// +func (n *Notifier) Notify(e Notifiee) { + n.mu.Lock() + if n.nots == nil { // so that zero-value is ready to be used. + n.nots = make(map[Notifiee]struct{}) + } + n.nots[e] = struct{}{} + n.mu.Unlock() +} + +// StopNotify stops notifying Notifiee e. This function +// is meant to be called behind your own type-safe function(s): +// +// // generic function for pattern-following +// func (r *Rocket) StopNotify(n Notifiee) { +// r.notifier.StopNotify(n) +// } +// +// // or as part of other functions +// func (r *Rocket) Detach(c Capsule) { +// r.notifier.StopNotify(c) +// r.capsule = nil +// } +// +func (n *Notifier) StopNotify(e Notifiee) { + n.mu.Lock() + if n.nots != nil { // so that zero-value is ready to be used. + delete(n.nots, e) + } + n.mu.Unlock() +} + +// NotifyAll messages the notifier's notifiees with a given notification. +// This is done by calling the given function with each notifiee. It is +// meant to be called with your own type-safe notification functions: +// +// func (r *Rocket) Launch() { +// r.notifyAll(func(n Notifiee) { +// n.Launched(r) +// }) +// } +// +// // make it private so only you can use it. This function is necessary +// // to make sure you only up-cast in one place. You control who you added +// // to be a notifiee. If Go adds generics, maybe we can get rid of this +// // method but for now it is like wrapping a type-less container with +// // a type safe interface. +// func (r *Rocket) notifyAll(notify func(Notifiee)) { +// r.notifier.NotifyAll(func(n notifier.Notifiee) { +// notify(n.(Notifiee)) +// }) +// } +// +// Note well: each notification is launched in its own goroutine, so they +// can be processed concurrently, and so that whatever the notification does +// it _never_ blocks out the client. This is so that consumers _cannot_ add +// hooks into your object that block you accidentally. +func (n *Notifier) NotifyAll(notify func(Notifiee)) { + n.mu.Lock() + defer n.mu.Unlock() + + if n.nots == nil { // so that zero-value is ready to be used. + return + } + + // no rate limiting. + if n.lim == nil { + for notifiee := range n.nots { + go notify(notifiee) + } + return + } + + // with rate limiting. + n.lim.Go(func(worker process.Process) { + for notifiee := range n.nots { + notifiee := notifiee // rebind for loop data races + n.lim.LimitedGo(func(worker process.Process) { + notify(notifiee) + }) + } + }) +} diff --git a/vendor/github.com/whyrusleeping/go-notifier/package.json b/vendor/github.com/whyrusleeping/go-notifier/package.json new file mode 100644 index 00000000..8eba8f55 --- /dev/null +++ b/vendor/github.com/whyrusleeping/go-notifier/package.json @@ -0,0 +1,24 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/go-notifier" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/go-notifier" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP", + "name": "goprocess", + "version": "1.0.0" + } + ], + "gxVersion": "0.9.1", + "language": "go", + "license": "", + "name": "go-notifier", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.0.0" +} + diff --git a/vendor/github.com/whyrusleeping/mafmt/LICENSE b/vendor/github.com/whyrusleeping/mafmt/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/whyrusleeping/mafmt/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/mafmt/README.md b/vendor/github.com/whyrusleeping/mafmt/README.md new file mode 100644 index 00000000..9fdc5389 --- /dev/null +++ b/vendor/github.com/whyrusleeping/mafmt/README.md @@ -0,0 +1,34 @@ +# multiaddr format +A validation checker for multiaddrs. Some basic validators for common address +types are provided, but creating your own combinations is easy. + +Usage: +```go +a, _ := ma.NewMultiaddr("/ip4/5.2.67.3/tcp/1708") +TCP.Matches(a) // returns true +``` + +Making your own validators is easy, for example, the `Reliable` multiaddr is +defined as follows: + +```go +// Define IP as either ipv4 or ipv6 +var IP = Or(Base(ma.P_IP4), Base(ma.P_IP6)) + +// Define TCP as 'tcp' on top of either ipv4 or ipv6 +var TCP = And(IP, Base(ma.P_TCP)) + +// Define UDP as 'udp' on top of either ipv4 or ipv6 +var UDP = And(IP, Base(ma.P_UDP)) + +// Define UTP as 'utp' on top of udp (on top of ipv4 or ipv6) +var UTP = And(UDP, Base(ma.P_UTP)) + +// Now define a Reliable transport as either tcp or utp +var Reliable = Or(TCP, UTP) + +// From here, we can easily define multiaddrs for protocols that can run on top +// of any 'reliable' transport (such as ipfs) +``` + +NOTE: the above patterns are already implemented in package diff --git a/vendor/github.com/whyrusleeping/mafmt/package.json b/vendor/github.com/whyrusleeping/mafmt/package.json new file mode 100644 index 00000000..d5a7375b --- /dev/null +++ b/vendor/github.com/whyrusleeping/mafmt/package.json @@ -0,0 +1,24 @@ +{ + "author": "whyrusleeping", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/whyrusleeping/mafmt" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmT4U94DnD8FRfqr21obWY32HLM5VExccPKMjQHofeYqr9", + "name": "go-multiaddr", + "version": "1.3.5" + } + ], + "gxVersion": "0.6.0", + "gx_version": "0.4.0", + "issues_url": "https://github.com/whyrusleeping/mafmt", + "language": "go", + "license": "", + "name": "mafmt", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.2.8" +} + diff --git a/vendor/github.com/whyrusleeping/mafmt/patterns.go b/vendor/github.com/whyrusleeping/mafmt/patterns.go new file mode 100644 index 00000000..c3d19120 --- /dev/null +++ b/vendor/github.com/whyrusleeping/mafmt/patterns.go @@ -0,0 +1,133 @@ +package mafmt + +import ( + "strings" + + ma "github.com/multiformats/go-multiaddr" +) + +// Define IP as either ipv4 or ipv6 +var IP = Or(Base(ma.P_IP4), Base(ma.P_IP6)) + +// Define TCP as 'tcp' on top of either ipv4 or ipv6 +var TCP = And(IP, Base(ma.P_TCP)) + +// Define UDP as 'udp' on top of either ipv4 or ipv6 +var UDP = And(IP, Base(ma.P_UDP)) + +// Define UTP as 'utp' on top of udp (on top of ipv4 or ipv6) +var UTP = And(UDP, Base(ma.P_UTP)) + +// Define QUIC as 'quic' on top of udp (on top of ipv4 or ipv6) +var QUIC = And(UDP, Base(ma.P_QUIC)) + +// Define unreliable transport as udp +var Unreliable = Or(UDP) + +// Now define a Reliable transport as either tcp or utp or quic +var Reliable = Or(TCP, UTP, QUIC) + +// IPFS can run over any reliable underlying transport protocol +var IPFS = And(Reliable, Base(ma.P_IPFS)) + +const ( + or = iota + and = iota +) + +func And(ps ...Pattern) Pattern { + return &pattern{ + Op: and, + Args: ps, + } +} + +func Or(ps ...Pattern) Pattern { + return &pattern{ + Op: or, + Args: ps, + } +} + +type Pattern interface { + Matches(ma.Multiaddr) bool + partialMatch([]ma.Protocol) (bool, []ma.Protocol) + String() string +} + +type pattern struct { + Args []Pattern + Op int +} + +func (ptrn *pattern) Matches(a ma.Multiaddr) bool { + ok, rem := ptrn.partialMatch(a.Protocols()) + return ok && len(rem) == 0 +} + +func (ptrn *pattern) partialMatch(pcs []ma.Protocol) (bool, []ma.Protocol) { + switch ptrn.Op { + case or: + for _, a := range ptrn.Args { + ok, rem := a.partialMatch(pcs) + if ok { + return true, rem + } + } + return false, nil + case and: + if len(pcs) < len(ptrn.Args) { + return false, nil + } + + for i := 0; i < len(ptrn.Args); i++ { + ok, rem := ptrn.Args[i].partialMatch(pcs) + if !ok { + return false, nil + } + + pcs = rem + } + + return true, pcs + default: + panic("unrecognized pattern operand") + } +} + +func (ptrn *pattern) String() string { + var sub []string + for _, a := range ptrn.Args { + sub = append(sub, a.String()) + } + + switch ptrn.Op { + case and: + return strings.Join(sub, "/") + case or: + return "{" + strings.Join(sub, "|") + "}" + default: + panic("unrecognized pattern op!") + } +} + +type Base int + +func (p Base) Matches(a ma.Multiaddr) bool { + pcs := a.Protocols() + return pcs[0].Code == int(p) && len(pcs) == 1 +} + +func (p Base) partialMatch(pcs []ma.Protocol) (bool, []ma.Protocol) { + if len(pcs) == 0 { + return false, nil + } + if pcs[0].Code == int(p) { + return true, pcs[1:] + } + return false, nil +} + +func (p Base) String() string { + return ma.ProtocolWithCode(int(p)).Name +} diff --git a/vendor/github.com/whyrusleeping/mdns/.gitignore b/vendor/github.com/whyrusleeping/mdns/.gitignore new file mode 100644 index 00000000..83656241 --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/.gitignore @@ -0,0 +1,23 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test diff --git a/vendor/github.com/whyrusleeping/mdns/LICENSE b/vendor/github.com/whyrusleeping/mdns/LICENSE new file mode 100644 index 00000000..a5df10e6 --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Armon Dadgar + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/mdns/README.md b/vendor/github.com/whyrusleeping/mdns/README.md new file mode 100644 index 00000000..80f3d90a --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/README.md @@ -0,0 +1,37 @@ +mdns +==== + +Simple mDNS client/server library in Golang. mDNS or Multicast DNS can be +used to discover services on the local network without the use of an authoritative +DNS server. This enables peer-to-peer discovery. It is important to note that many +networks restrict the use of multicasting, which prevents mDNS from functioning. +Notably, multicast cannot be used in any sort of cloud, or shared infrastructure +environment. However it works well in most office, home, or private infrastructure +environments. + +Using the library is very simple, here is an example of publishing a service entry: + + // Setup our service export + host, _ := os.Hostname() + info := []string{"My awesome service"}, + service, _ := NewMDNSService(host, "_foobar._tcp", "", "", 8000, nil, info) + + // Create the mDNS server, defer shutdown + server, _ := mdns.NewServer(&mdns.Config{Zone: service}) + defer server.Shutdown() + + +Doing a lookup for service providers is also very simple: + + // Make a channel for results and start listening + entriesCh := make(chan *mdns.ServiceEntry, 4) + go func() { + for entry := range entriesCh { + fmt.Printf("Got new entry: %v\n", entry) + } + }() + + // Start the lookup + mdns.Lookup("_foobar._tcp", entriesCh) + close(entriesCh) + diff --git a/vendor/github.com/whyrusleeping/mdns/client.go b/vendor/github.com/whyrusleeping/mdns/client.go new file mode 100644 index 00000000..3fad4f2d --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/client.go @@ -0,0 +1,369 @@ +package mdns + +import ( + "fmt" + "net" + "strings" + "sync" + "time" + + "github.com/miekg/dns" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +// ServiceEntry is returned after we query for a service +type ServiceEntry struct { + Name string + Host string + AddrV4 net.IP + AddrV6 net.IP + Port int + Info string + InfoFields []string + + Addr net.IP // @Deprecated + + hasTXT bool + sent bool +} + +// complete is used to check if we have all the info we need +func (s *ServiceEntry) complete() bool { + return (s.AddrV4 != nil || s.AddrV6 != nil || s.Addr != nil) && s.Port != 0 && s.hasTXT +} + +// QueryParam is used to customize how a Lookup is performed +type QueryParam struct { + Service string // Service to lookup + Domain string // Lookup domain, default "local" + Timeout time.Duration // Lookup timeout, default 1 second + Interface *net.Interface // Multicast interface to use + Entries chan<- *ServiceEntry // Entries Channel + WantUnicastResponse bool // Unicast response desired, as per 5.4 in RFC +} + +// DefaultParams is used to return a default set of QueryParam's +func DefaultParams(service string) *QueryParam { + return &QueryParam{ + Service: service, + Domain: "local", + Timeout: time.Second, + Entries: make(chan *ServiceEntry), + WantUnicastResponse: false, // TODO(reddaly): Change this default. + } +} + +// Query looks up a given service, in a domain, waiting at most +// for a timeout before finishing the query. The results are streamed +// to a channel. Sends will not block, so clients should make sure to +// either read or buffer. +func Query(params *QueryParam) error { + // Create a new client + client, err := newClient() + if err != nil { + return err + } + defer client.Close() + + // Set the multicast interface + if params.Interface != nil { + if err := client.setInterface(params.Interface); err != nil { + return err + } + } + + // Ensure defaults are set + if params.Domain == "" { + params.Domain = "local" + } + if params.Timeout == 0 { + params.Timeout = time.Second + } + + // Run the query + return client.query(params) +} + +// Lookup is the same as Query, however it uses all the default parameters +func Lookup(service string, entries chan<- *ServiceEntry) error { + params := DefaultParams(service) + params.Entries = entries + return Query(params) +} + +// Client provides a query interface that can be used to +// search for service providers using mDNS +type client struct { + ipv4UnicastConn *net.UDPConn + ipv6UnicastConn *net.UDPConn + + ipv4MulticastConn *net.UDPConn + ipv6MulticastConn *net.UDPConn + + closed bool + closedCh chan struct{} // TODO(reddaly): This doesn't appear to be used. + closeLock sync.Mutex +} + +// NewClient creates a new mdns Client that can be used to query +// for records +func newClient() (*client, error) { + // TODO(reddaly): At least attempt to bind to the port required in the spec. + // Create a IPv4 listener + uconn4, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) + if err != nil { + logf("[ERR] mdns: Failed to bind to udp4 port: %v", err) + } + uconn6, err := net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0}) + if err != nil { + logf("[ERR] mdns: Failed to bind to udp6 port: %v", err) + } + + if uconn4 == nil && uconn6 == nil { + return nil, fmt.Errorf("failed to bind to any unicast udp port") + } + + mconn4, err := net.ListenMulticastUDP("udp4", nil, ipv4Addr) + if err != nil { + logf("[ERR] mdns: Failed to bind to udp4 port: %v", err) + } + mconn6, err := net.ListenMulticastUDP("udp6", nil, ipv6Addr) + if err != nil { + logf("[ERR] mdns: Failed to bind to udp6 port: %v", err) + } + + if mconn4 == nil && mconn6 == nil { + return nil, fmt.Errorf("failed to bind to any multicast udp port") + } + + c := &client{ + ipv4MulticastConn: mconn4, + ipv6MulticastConn: mconn6, + ipv4UnicastConn: uconn4, + ipv6UnicastConn: uconn6, + closedCh: make(chan struct{}), + } + return c, nil +} + +func (c *client) getIsClosed() bool { + c.closeLock.Lock() + defer c.closeLock.Unlock() + return c.closed +} + +// Close is used to cleanup the client +func (c *client) Close() error { + c.closeLock.Lock() + defer c.closeLock.Unlock() + + if c.closed { + return nil + } + c.closed = true + + logf("[INFO] mdns: Closing client %v", *c) + close(c.closedCh) + + if c.ipv4UnicastConn != nil { + c.ipv4UnicastConn.Close() + } + if c.ipv6UnicastConn != nil { + c.ipv6UnicastConn.Close() + } + if c.ipv4MulticastConn != nil { + c.ipv4MulticastConn.Close() + } + if c.ipv6MulticastConn != nil { + c.ipv6MulticastConn.Close() + } + + return nil +} + +// setInterface is used to set the query interface, uses sytem +// default if not provided +func (c *client) setInterface(iface *net.Interface) error { + p := ipv4.NewPacketConn(c.ipv4UnicastConn) + if err := p.SetMulticastInterface(iface); err != nil { + return err + } + p2 := ipv6.NewPacketConn(c.ipv6UnicastConn) + if err := p2.SetMulticastInterface(iface); err != nil { + return err + } + p = ipv4.NewPacketConn(c.ipv4MulticastConn) + if err := p.SetMulticastInterface(iface); err != nil { + return err + } + p2 = ipv6.NewPacketConn(c.ipv6MulticastConn) + if err := p2.SetMulticastInterface(iface); err != nil { + return err + } + return nil +} + +// query is used to perform a lookup and stream results +func (c *client) query(params *QueryParam) error { + // Create the service name + serviceAddr := fmt.Sprintf("%s.%s.", trimDot(params.Service), trimDot(params.Domain)) + + // Start listening for response packets + msgCh := make(chan *dns.Msg, 32) + go c.recv(c.ipv4UnicastConn, msgCh) + go c.recv(c.ipv6UnicastConn, msgCh) + go c.recv(c.ipv4MulticastConn, msgCh) + go c.recv(c.ipv6MulticastConn, msgCh) + + // Send the query + m := new(dns.Msg) + m.SetQuestion(serviceAddr, dns.TypePTR) + // RFC 6762, section 18.12. Repurposing of Top Bit of qclass in Question + // Section + // + // In the Question Section of a Multicast DNS query, the top bit of the qclass + // field is used to indicate that unicast responses are preferred for this + // particular question. (See Section 5.4.) + if params.WantUnicastResponse { + m.Question[0].Qclass |= 1 << 15 + } + m.RecursionDesired = false + if err := c.sendQuery(m); err != nil { + return err + } + + // Map the in-progress responses + inprogress := make(map[string]*ServiceEntry) + + // Listen until we reach the timeout + finish := time.After(params.Timeout) + for { + select { + case resp := <-msgCh: + var inp *ServiceEntry + for _, answer := range append(resp.Answer, resp.Extra...) { + // TODO(reddaly): Check that response corresponds to serviceAddr? + switch rr := answer.(type) { + case *dns.PTR: + // Create new entry for this + inp = ensureName(inprogress, rr.Ptr) + + case *dns.SRV: + // Check for a target mismatch + if rr.Target != rr.Hdr.Name { + alias(inprogress, rr.Hdr.Name, rr.Target) + } + + // Get the port + inp = ensureName(inprogress, rr.Hdr.Name) + inp.Host = rr.Target + inp.Port = int(rr.Port) + + case *dns.TXT: + // Pull out the txt + inp = ensureName(inprogress, rr.Hdr.Name) + inp.Info = strings.Join(rr.Txt, "|") + inp.InfoFields = rr.Txt + inp.hasTXT = true + + case *dns.A: + // Pull out the IP + inp = ensureName(inprogress, rr.Hdr.Name) + inp.Addr = rr.A // @Deprecated + inp.AddrV4 = rr.A + + case *dns.AAAA: + // Pull out the IP + inp = ensureName(inprogress, rr.Hdr.Name) + inp.Addr = rr.AAAA // @Deprecated + inp.AddrV6 = rr.AAAA + } + } + + if inp == nil { + continue + } + + // Check if this entry is complete + if inp.complete() { + if inp.sent { + continue + } + inp.sent = true + select { + case params.Entries <- inp: + default: + } + } else { + // Fire off a node specific query + m := new(dns.Msg) + m.SetQuestion(inp.Name, dns.TypePTR) + m.RecursionDesired = false + if err := c.sendQuery(m); err != nil { + logf("[ERR] mdns: Failed to query instance %s: %v", inp.Name, err) + } + } + case <-finish: + return nil + } + } +} + +// sendQuery is used to multicast a query out +func (c *client) sendQuery(q *dns.Msg) error { + buf, err := q.Pack() + if err != nil { + return err + } + if c.ipv4UnicastConn != nil { + c.ipv4UnicastConn.WriteToUDP(buf, ipv4Addr) + } + if c.ipv6UnicastConn != nil { + c.ipv6UnicastConn.WriteToUDP(buf, ipv6Addr) + } + return nil +} + +// recv is used to receive until we get a shutdown +func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) { + if l == nil { + return + } + buf := make([]byte, 65536) + for !c.getIsClosed() { + n, err := l.Read(buf) + if err != nil { + logf("[ERR] mdns: Failed to read packet: %v", err) + continue + } + msg := new(dns.Msg) + if err := msg.Unpack(buf[:n]); err != nil { + logf("[ERR] mdns: Failed to unpack packet: %v", err) + continue + } + select { + case msgCh <- msg: + case <-c.closedCh: + return + } + } +} + +// ensureName is used to ensure the named node is in progress +func ensureName(inprogress map[string]*ServiceEntry, name string) *ServiceEntry { + if inp, ok := inprogress[name]; ok { + return inp + } + inp := &ServiceEntry{ + Name: name, + } + inprogress[name] = inp + return inp +} + +// alias is used to setup an alias between two entries +func alias(inprogress map[string]*ServiceEntry, src, dst string) { + srcEntry := ensureName(inprogress, src) + inprogress[dst] = srcEntry +} diff --git a/vendor/github.com/whyrusleeping/mdns/log.go b/vendor/github.com/whyrusleeping/mdns/log.go new file mode 100644 index 00000000..79eeb81a --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/log.go @@ -0,0 +1,13 @@ +package mdns + +import "log" + +// DisableLogging disables all log messages +var DisableLogging bool + +func logf(format string, args ...interface{}) { + if DisableLogging { + return + } + log.Printf(format, args...) +} diff --git a/vendor/github.com/whyrusleeping/mdns/package.json b/vendor/github.com/whyrusleeping/mdns/package.json new file mode 100644 index 00000000..5d2a702b --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/package.json @@ -0,0 +1,26 @@ +{ + "author": "whyrusleeping", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/whyrusleeping/mdns" + }, + "gxDependencies": [ + { + "hash": "QmV3bVtkAhSZqWncYGonUmsVcJcV6cpzWztsFwc3A9so5m", + "name": "dns", + "version": "0.2.1" + }, + { + "hash": "QmRvYNctevGUW52urgmoFZscT6buMKqhHezLUS64WepGWn", + "name": "go-net", + "version": "0.2.0" + } + ], + "gxVersion": "0.8.0", + "issues_url": "", + "language": "go", + "license": "", + "name": "mdns", + "version": "0.2.0" +} + diff --git a/vendor/github.com/whyrusleeping/mdns/server.go b/vendor/github.com/whyrusleeping/mdns/server.go new file mode 100644 index 00000000..42aba8fd --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/server.go @@ -0,0 +1,291 @@ +package mdns + +import ( + "fmt" + "net" + "strings" + "sync" + + "github.com/miekg/dns" +) + +const ( + ipv4mdns = "224.0.0.251" + ipv6mdns = "ff02::fb" + mdnsPort = 5353 + forceUnicastResponses = false +) + +var ( + ipv4Addr = &net.UDPAddr{ + IP: net.ParseIP(ipv4mdns), + Port: mdnsPort, + } + ipv6Addr = &net.UDPAddr{ + IP: net.ParseIP(ipv6mdns), + Port: mdnsPort, + } +) + +// Config is used to configure the mDNS server +type Config struct { + // Zone must be provided to support responding to queries + Zone Zone + + // Iface if provided binds the multicast listener to the given + // interface. If not provided, the system default multicase interface + // is used. + Iface *net.Interface +} + +// mDNS server is used to listen for mDNS queries and respond if we +// have a matching local record +type Server struct { + config *Config + + ipv4List *net.UDPConn + ipv6List *net.UDPConn + + shutdown bool + shutdownCh chan struct{} + shutdownLock sync.Mutex +} + +// NewServer is used to create a new mDNS server from a config +func NewServer(config *Config) (*Server, error) { + // Create the listeners + ipv4List, _ := net.ListenMulticastUDP("udp4", config.Iface, ipv4Addr) + ipv6List, _ := net.ListenMulticastUDP("udp6", config.Iface, ipv6Addr) + + // Check if we have any listener + if ipv4List == nil && ipv6List == nil { + return nil, fmt.Errorf("No multicast listeners could be started") + } + + s := &Server{ + config: config, + ipv4List: ipv4List, + ipv6List: ipv6List, + shutdownCh: make(chan struct{}), + } + + if ipv4List != nil { + go s.recv(s.ipv4List) + } + + if ipv6List != nil { + go s.recv(s.ipv6List) + } + + return s, nil +} + +func (s *Server) getIsShutdown() bool { + s.shutdownLock.Lock() + defer s.shutdownLock.Unlock() + return s.shutdown +} + +// Shutdown is used to shutdown the listener +func (s *Server) Shutdown() error { + s.shutdownLock.Lock() + defer s.shutdownLock.Unlock() + + if s.shutdown { + return nil + } + s.shutdown = true + close(s.shutdownCh) + + if s.ipv4List != nil { + s.ipv4List.Close() + } + if s.ipv6List != nil { + s.ipv6List.Close() + } + return nil +} + +// recv is a long running routine to receive packets from an interface +func (s *Server) recv(c *net.UDPConn) { + if c == nil { + return + } + buf := make([]byte, 65536) + for !s.getIsShutdown() { + n, from, err := c.ReadFrom(buf) + if err != nil { + continue + } + if err := s.parsePacket(buf[:n], from); err != nil { + logf("[ERR] mdns: Failed to handle query: %v", err) + } + } +} + +// parsePacket is used to parse an incoming packet +func (s *Server) parsePacket(packet []byte, from net.Addr) error { + var msg dns.Msg + if err := msg.Unpack(packet); err != nil { + logf("[ERR] mdns: Failed to unpack packet: %v", err) + return err + } + return s.handleQuery(&msg, from) +} + +// handleQuery is used to handle an incoming query +func (s *Server) handleQuery(query *dns.Msg, from net.Addr) error { + if query.Opcode != dns.OpcodeQuery { + // "In both multicast query and multicast response messages, the OPCODE MUST + // be zero on transmission (only standard queries are currently supported + // over multicast). Multicast DNS messages received with an OPCODE other + // than zero MUST be silently ignored." Note: OpcodeQuery == 0 + return fmt.Errorf("mdns: received query with non-zero Opcode %v: %v", query.Opcode, *query) + } + if query.Rcode != 0 { + // "In both multicast query and multicast response messages, the Response + // Code MUST be zero on transmission. Multicast DNS messages received with + // non-zero Response Codes MUST be silently ignored." + return fmt.Errorf("mdns: received query with non-zero Rcode %v: %v", query.Rcode, *query) + } + + // TODO(reddaly): Handle "TC (Truncated) Bit": + // In query messages, if the TC bit is set, it means that additional + // Known-Answer records may be following shortly. A responder SHOULD + // record this fact, and wait for those additional Known-Answer records, + // before deciding whether to respond. If the TC bit is clear, it means + // that the querying host has no additional Known Answers. + if query.Truncated { + return fmt.Errorf("[ERR] mdns: support for DNS requests with high truncated bit not implemented: %v", *query) + } + + var unicastAnswer, multicastAnswer []dns.RR + + // Handle each question + for _, q := range query.Question { + mrecs, urecs := s.handleQuestion(q) + multicastAnswer = append(multicastAnswer, mrecs...) + unicastAnswer = append(unicastAnswer, urecs...) + } + + // See section 18 of RFC 6762 for rules about DNS headers. + resp := func(unicast bool) *dns.Msg { + // 18.1: ID (Query Identifier) + // 0 for multicast response, query.Id for unicast response + id := uint16(0) + if unicast { + id = query.Id + } + + var answer []dns.RR + if unicast { + answer = unicastAnswer + } else { + answer = multicastAnswer + } + if len(answer) == 0 { + return nil + } + + return &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Id: id, + + // 18.2: QR (Query/Response) Bit - must be set to 1 in response. + Response: true, + + // 18.3: OPCODE - must be zero in response (OpcodeQuery == 0) + Opcode: dns.OpcodeQuery, + + // 18.4: AA (Authoritative Answer) Bit - must be set to 1 + Authoritative: true, + + // The following fields must all be set to 0: + // 18.5: TC (TRUNCATED) Bit + // 18.6: RD (Recursion Desired) Bit + // 18.7: RA (Recursion Available) Bit + // 18.8: Z (Zero) Bit + // 18.9: AD (Authentic Data) Bit + // 18.10: CD (Checking Disabled) Bit + // 18.11: RCODE (Response Code) + }, + // 18.12 pertains to questions (handled by handleQuestion) + // 18.13 pertains to resource records (handled by handleQuestion) + + // 18.14: Name Compression - responses should be compressed (though see + // caveats in the RFC), so set the Compress bit (part of the dns library + // API, not part of the DNS packet) to true. + Compress: true, + + Answer: answer, + } + } + + if len(multicastAnswer) == 0 && len(unicastAnswer) == 0 { + questions := make([]string, len(query.Question)) + for i, q := range query.Question { + questions[i] = q.Name + } + logf("no responses for query with questions: %s", strings.Join(questions, ", ")) + } + + if mresp := resp(false); mresp != nil { + if err := s.sendResponse(mresp, from, false); err != nil { + return fmt.Errorf("mdns: error sending multicast response: %v", err) + } + } + if uresp := resp(true); uresp != nil { + if err := s.sendResponse(uresp, from, true); err != nil { + return fmt.Errorf("mdns: error sending unicast response: %v", err) + } + } + return nil +} + +// handleQuestion is used to handle an incoming question +// +// The response to a question may be transmitted over multicast, unicast, or +// both. The return values are DNS records for each transmission type. +func (s *Server) handleQuestion(q dns.Question) (multicastRecs, unicastRecs []dns.RR) { + records := s.config.Zone.Records(q) + + if len(records) == 0 { + return nil, nil + } + + // Handle unicast and multicast responses. + // TODO(reddaly): The decision about sending over unicast vs. multicast is not + // yet fully compliant with RFC 6762. For example, the unicast bit should be + // ignored if the records in question are close to TTL expiration. For now, + // we just use the unicast bit to make the decision, as per the spec: + // RFC 6762, section 18.12. Repurposing of Top Bit of qclass in Question + // Section + // + // In the Question Section of a Multicast DNS query, the top bit of the + // qclass field is used to indicate that unicast responses are preferred + // for this particular question. (See Section 5.4.) + if q.Qclass&(1<<15) != 0 || forceUnicastResponses { + return nil, records + } + return records, nil +} + +// sendResponse is used to send a response packet +func (s *Server) sendResponse(resp *dns.Msg, from net.Addr, unicast bool) error { + // TODO(reddaly): Respect the unicast argument, and allow sending responses + // over multicast. + buf, err := resp.Pack() + if err != nil { + return err + } + + // Determine the socket to send from + addr := from.(*net.UDPAddr) + if addr.IP.To4() != nil { + _, err = s.ipv4List.WriteToUDP(buf, addr) + return err + } else { + _, err = s.ipv6List.WriteToUDP(buf, addr) + return err + } +} diff --git a/vendor/github.com/whyrusleeping/mdns/zone.go b/vendor/github.com/whyrusleeping/mdns/zone.go new file mode 100644 index 00000000..6f442c7b --- /dev/null +++ b/vendor/github.com/whyrusleeping/mdns/zone.go @@ -0,0 +1,307 @@ +package mdns + +import ( + "fmt" + "net" + "os" + "strings" + + "github.com/miekg/dns" +) + +const ( + // defaultTTL is the default TTL value in returned DNS records in seconds. + defaultTTL = 120 +) + +// Zone is the interface used to integrate with the server and +// to serve records dynamically +type Zone interface { + // Records returns DNS records in response to a DNS question. + Records(q dns.Question) []dns.RR +} + +// MDNSService is used to export a named service by implementing a Zone +type MDNSService struct { + Instance string // Instance name (e.g. "hostService name") + Service string // Service name (e.g. "_http._tcp.") + Domain string // If blank, assumes "local" + HostName string // Host machine DNS name (e.g. "mymachine.net.") + Port int // Service Port + IPs []net.IP // IP addresses for the service's host + TXT []string // Service TXT records + + serviceAddr string // Fully qualified service address + instanceAddr string // Fully qualified instance address + enumAddr string // _services._dns-sd._udp. +} + +// validateFQDN returns an error if the passed string is not a fully qualified +// hdomain name (more specifically, a hostname). +func validateFQDN(s string) error { + if len(s) == 0 { + return fmt.Errorf("FQDN must not be blank") + } + if s[len(s)-1] != '.' { + return fmt.Errorf("FQDN must end in period: %s", s) + } + // TODO(reddaly): Perform full validation. + + return nil +} + +// NewMDNSService returns a new instance of MDNSService. +// +// If domain, hostName, or ips is set to the zero value, then a default value +// will be inferred from the operating system. +// +// TODO(reddaly): This interface may need to change to account for "unique +// record" conflict rules of the mDNS protocol. Upon startup, the server should +// check to ensure that the instance name does not conflict with other instance +// names, and, if required, select a new name. There may also be conflicting +// hostName A/AAAA records. +func NewMDNSService(instance, service, domain, hostName string, port int, ips []net.IP, txt []string) (*MDNSService, error) { + // Sanity check inputs + if instance == "" { + return nil, fmt.Errorf("missing service instance name") + } + if service == "" { + return nil, fmt.Errorf("missing service name") + } + if port == 0 { + return nil, fmt.Errorf("missing service port") + } + + // Set default domain + if domain == "" { + domain = "local." + } + if err := validateFQDN(domain); err != nil { + return nil, fmt.Errorf("domain %q is not a fully-qualified domain name: %v", domain, err) + } + + // Get host information if no host is specified. + if hostName == "" { + var err error + hostName, err = os.Hostname() + if err != nil { + return nil, fmt.Errorf("could not determine host: %v", err) + } + hostName = fmt.Sprintf("%s.", hostName) + } + if err := validateFQDN(hostName); err != nil { + return nil, fmt.Errorf("hostName %q is not a fully-qualified domain name: %v", hostName, err) + } + + if len(ips) == 0 { + var err error + ips, err = net.LookupIP(hostName) + if err != nil { + // Try appending the host domain suffix and lookup again + // (required for Linux-based hosts) + tmpHostName := fmt.Sprintf("%s%s", hostName, domain) + + ips, err = net.LookupIP(tmpHostName) + + if err != nil { + return nil, fmt.Errorf("could not determine host IP addresses for %s", hostName) + } + } + } + for _, ip := range ips { + if ip.To4() == nil && ip.To16() == nil { + return nil, fmt.Errorf("invalid IP address in IPs list: %v", ip) + } + } + + return &MDNSService{ + Instance: instance, + Service: service, + Domain: domain, + HostName: hostName, + Port: port, + IPs: ips, + TXT: txt, + serviceAddr: fmt.Sprintf("%s.%s.", trimDot(service), trimDot(domain)), + instanceAddr: fmt.Sprintf("%s.%s.%s.", instance, trimDot(service), trimDot(domain)), + enumAddr: fmt.Sprintf("_services._dns-sd._udp.%s.", trimDot(domain)), + }, nil +} + +// trimDot is used to trim the dots from the start or end of a string +func trimDot(s string) string { + return strings.Trim(s, ".") +} + +// Records returns DNS records in response to a DNS question. +func (m *MDNSService) Records(q dns.Question) []dns.RR { + switch q.Name { + case m.enumAddr: + return m.serviceEnum(q) + case m.serviceAddr: + return m.serviceRecords(q) + case m.instanceAddr: + return m.instanceRecords(q) + case m.HostName: + if q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA { + return m.instanceRecords(q) + } + fallthrough + default: + return nil + } +} + +func (m *MDNSService) serviceEnum(q dns.Question) []dns.RR { + switch q.Qtype { + case dns.TypeANY: + fallthrough + case dns.TypePTR: + rr := &dns.PTR{ + Hdr: dns.RR_Header{ + Name: q.Name, + Rrtype: dns.TypePTR, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + Ptr: m.serviceAddr, + } + return []dns.RR{rr} + default: + return nil + } +} + +// serviceRecords is called when the query matches the service name +func (m *MDNSService) serviceRecords(q dns.Question) []dns.RR { + switch q.Qtype { + case dns.TypeANY: + fallthrough + case dns.TypePTR: + // Build a PTR response for the service + rr := &dns.PTR{ + Hdr: dns.RR_Header{ + Name: q.Name, + Rrtype: dns.TypePTR, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + Ptr: m.instanceAddr, + } + servRec := []dns.RR{rr} + + // Get the instance records + instRecs := m.instanceRecords(dns.Question{ + Name: m.instanceAddr, + Qtype: dns.TypeANY, + }) + + // Return the service record with the instance records + return append(servRec, instRecs...) + default: + return nil + } +} + +// serviceRecords is called when the query matches the instance name +func (m *MDNSService) instanceRecords(q dns.Question) []dns.RR { + switch q.Qtype { + case dns.TypeANY: + // Get the SRV, which includes A and AAAA + recs := m.instanceRecords(dns.Question{ + Name: m.instanceAddr, + Qtype: dns.TypeSRV, + }) + + // Add the TXT record + recs = append(recs, m.instanceRecords(dns.Question{ + Name: m.instanceAddr, + Qtype: dns.TypeTXT, + })...) + return recs + + case dns.TypeA: + var rr []dns.RR + for _, ip := range m.IPs { + if ip4 := ip.To4(); ip4 != nil { + rr = append(rr, &dns.A{ + Hdr: dns.RR_Header{ + Name: m.HostName, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + A: ip4, + }) + } + } + return rr + + case dns.TypeAAAA: + var rr []dns.RR + for _, ip := range m.IPs { + if ip.To4() != nil { + // TODO(reddaly): IPv4 addresses could be encoded in IPv6 format and + // putinto AAAA records, but the current logic puts ipv4-encodable + // addresses into the A records exclusively. Perhaps this should be + // configurable? + continue + } + + if ip16 := ip.To16(); ip16 != nil { + rr = append(rr, &dns.AAAA{ + Hdr: dns.RR_Header{ + Name: m.HostName, + Rrtype: dns.TypeAAAA, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + AAAA: ip16, + }) + } + } + return rr + + case dns.TypeSRV: + // Create the SRV Record + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: q.Name, + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + Priority: 10, + Weight: 1, + Port: uint16(m.Port), + Target: m.HostName, + } + recs := []dns.RR{srv} + + // Add the A record + recs = append(recs, m.instanceRecords(dns.Question{ + Name: m.instanceAddr, + Qtype: dns.TypeA, + })...) + + // Add the AAAA record + recs = append(recs, m.instanceRecords(dns.Question{ + Name: m.instanceAddr, + Qtype: dns.TypeAAAA, + })...) + return recs + + case dns.TypeTXT: + txt := &dns.TXT{ + Hdr: dns.RR_Header{ + Name: q.Name, + Rrtype: dns.TypeTXT, + Class: dns.ClassINET, + Ttl: defaultTTL, + }, + Txt: m.TXT, + } + return []dns.RR{txt} + } + return nil +} diff --git a/vendor/github.com/whyrusleeping/multiaddr-filter/.gxlastpubver b/vendor/github.com/whyrusleeping/multiaddr-filter/.gxlastpubver new file mode 100644 index 00000000..2b077ca5 --- /dev/null +++ b/vendor/github.com/whyrusleeping/multiaddr-filter/.gxlastpubver @@ -0,0 +1 @@ +1.0.0: QmXE4GFk66B5Ts362YWZosjiZLpP4QDmBTBadRZFffZ58U diff --git a/vendor/github.com/whyrusleeping/multiaddr-filter/LICENSE b/vendor/github.com/whyrusleeping/multiaddr-filter/LICENSE new file mode 100644 index 00000000..1a976e72 --- /dev/null +++ b/vendor/github.com/whyrusleeping/multiaddr-filter/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/multiaddr-filter/README.md b/vendor/github.com/whyrusleeping/multiaddr-filter/README.md new file mode 100644 index 00000000..6a3ca8f8 --- /dev/null +++ b/vendor/github.com/whyrusleeping/multiaddr-filter/README.md @@ -0,0 +1,15 @@ +# go-multiaddr-filter -- CIDR netmasks with multiaddr + +This module creates very simple [multiaddr](https://github.com/jbenet/go-multiaddr) formatted cidr netmasks. + +It doesn't do full multiaddr parsing to save on vendoring things and perf. The `net` package will take care of verifying the validity of the network part anyway. + +## Usage + +```go + +import filter "github.com/whyrusleeping/multiaddr-filter" + +filter.NewMask("/ip4/192.168.0.0/24") // ipv4 +filter.NewMask("/ip6/fe80::/64") // ipv6 +``` diff --git a/vendor/github.com/whyrusleeping/multiaddr-filter/mask.go b/vendor/github.com/whyrusleeping/multiaddr-filter/mask.go new file mode 100644 index 00000000..7f012258 --- /dev/null +++ b/vendor/github.com/whyrusleeping/multiaddr-filter/mask.go @@ -0,0 +1,47 @@ +package mask + +import ( + "errors" + "fmt" + "net" + "strings" +) + +var ErrInvalidFormat = errors.New("invalid multiaddr-filter format") + +func NewMask(a string) (*net.IPNet, error) { + parts := strings.Split(a, "/") + + if parts[0] != "" { + return nil, ErrInvalidFormat + } + + if len(parts) != 5 { + return nil, ErrInvalidFormat + } + + // check it's a valid filter address. ip + cidr + isip := parts[1] == "ip4" || parts[1] == "ip6" + iscidr := parts[3] == "ipcidr" + if !isip || !iscidr { + return nil, ErrInvalidFormat + } + + _, ipn, err := net.ParseCIDR(parts[2] + "/" + parts[4]) + if err != nil { + return nil, err + } + return ipn, nil +} + +func ConvertIPNet(n *net.IPNet) (string, error) { + b, _ := n.Mask.Size() + switch { + case n.IP.To4() != nil: + return fmt.Sprintf("/ip4/%s/ipcidr/%d", n.IP, b), nil + case n.IP.To16() != nil: + return fmt.Sprintf("/ip6/%s/ipcidr/%d", n.IP, b), nil + default: + return "", fmt.Errorf("was not given valid ip addr") + } +} diff --git a/vendor/github.com/whyrusleeping/multiaddr-filter/package.json b/vendor/github.com/whyrusleeping/multiaddr-filter/package.json new file mode 100644 index 00000000..70c9cf56 --- /dev/null +++ b/vendor/github.com/whyrusleeping/multiaddr-filter/package.json @@ -0,0 +1,12 @@ +{ + "author": "whyrusleeping", + "bugs": {}, + "gx": { + "dvcsimport": "github.com/whyrusleeping/multiaddr-filter" + }, + "gxVersion": "0.7.0", + "language": "go", + "license": "", + "name": "multiaddr-filter", + "version": "1.0.2" +} diff --git a/vendor/github.com/whyrusleeping/sql-datastore/LICENSE b/vendor/github.com/whyrusleeping/sql-datastore/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/whyrusleeping/sql-datastore/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/sql-datastore/README.md b/vendor/github.com/whyrusleeping/sql-datastore/README.md new file mode 100644 index 00000000..d7afebb0 --- /dev/null +++ b/vendor/github.com/whyrusleeping/sql-datastore/README.md @@ -0,0 +1,19 @@ +# SQL Datastore + +An implementation of [the datastore interface](https://github.com/ipfs/go-datastore) +that can be backed by any sql database. + +## Usage +``` +import ( + "database/sql" + "github.com/whyrusleeping/sql-datastore" +) + +mydb, _ := sql.Open("yourdb", "yourdbparameters") + +ds := sqlds.NewSqlDatastore(mydb) +``` + +## License +MIT diff --git a/vendor/github.com/whyrusleeping/sql-datastore/dstore.go b/vendor/github.com/whyrusleeping/sql-datastore/dstore.go new file mode 100644 index 00000000..179efa02 --- /dev/null +++ b/vendor/github.com/whyrusleeping/sql-datastore/dstore.go @@ -0,0 +1,266 @@ +package sqlds + +import ( + "database/sql" + "errors" + "fmt" + "log" + + ds "github.com/ipfs/go-datastore" + dsq "github.com/ipfs/go-datastore/query" +) + +type Queries interface { + Delete() string + Exists() string + Get() string + Put() string + Query() string + Prefix() string + Limit() string + Offset() string + GetSize() string +} + +type Datastore struct { + db *sql.DB + queries Queries +} + +// NewDatastore returns a new datastore +func NewDatastore(db *sql.DB, queries Queries) *Datastore { + return &Datastore{db: db, queries: queries} +} + +type batch struct { + db *sql.DB + queries Queries + txn *sql.Tx +} + +func (b *batch) GetTransaction() (*sql.Tx, error) { + if b.txn != nil { + return b.txn, nil + } + + newTransaction, err := b.db.Begin() + if err != nil { + if newTransaction != nil { + newTransaction.Rollback() + } + + return nil, err + } + + b.txn = newTransaction + return newTransaction, nil +} + +func (b *batch) Put(key ds.Key, val []byte) error { + if val == nil { + return ds.ErrInvalidType + } + + txn, err := b.GetTransaction() + if err != nil { + b.txn.Rollback() + return err + } + + _, err = txn.Exec(b.queries.Put(), key.String(), val) + if err != nil { + b.txn.Rollback() + return err + } + + return nil +} + +func (b *batch) Delete(key ds.Key) error { + txn, err := b.GetTransaction() + if err != nil { + b.txn.Rollback() + } + + _, err = txn.Exec(b.queries.Delete(), key.String()) + if err != nil { + b.txn.Rollback() + return err + } + + return err +} + +func (b *batch) Commit() error { + if b.txn == nil { + return errors.New("no transaction started, cannot commit") + } + var err = b.txn.Commit() + if err != nil { + b.txn.Rollback() + return err + } + + return nil +} + +func (d *Datastore) Batch() (ds.Batch, error) { + batch := &batch{ + db: d.db, + queries: d.queries, + txn: nil, + } + + return batch, nil +} + +func (d *Datastore) Close() error { + return d.db.Close() +} + +func (d *Datastore) Delete(key ds.Key) error { + result, err := d.db.Exec(d.queries.Delete(), key.String()) + if err != nil { + return err + } + + rows, err := result.RowsAffected() + if err != nil { + return err + } + + if rows == 0 { + return ds.ErrNotFound + } + + return nil +} + +func (d *Datastore) Get(key ds.Key) (value []byte, err error) { + row := d.db.QueryRow(d.queries.Get(), key.String()) + var out []byte + + switch err := row.Scan(&out); err { + case sql.ErrNoRows: + return nil, ds.ErrNotFound + case nil: + return out, nil + default: + return nil, err + } +} + +func (d *Datastore) Has(key ds.Key) (exists bool, err error) { + row := d.db.QueryRow(d.queries.Exists(), key.String()) + + switch err := row.Scan(&exists); err { + case sql.ErrNoRows: + return exists, nil + case nil: + return exists, nil + default: + return exists, err + } +} + +func (d *Datastore) Put(key ds.Key, value []byte) error { + if value == nil { + return ds.ErrInvalidType + } + + _, err := d.db.Exec(d.queries.Put(), key.String(), value) + if err != nil { + return err + } + + return nil +} + +func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) { + raw, err := d.RawQuery(q) + if err != nil { + return nil, err + } + + for _, f := range q.Filters { + raw = dsq.NaiveFilter(raw, f) + } + + raw = dsq.NaiveOrder(raw, q.Orders...) + + return raw, nil +} + +func (d *Datastore) RawQuery(q dsq.Query) (dsq.Results, error) { + var rows *sql.Rows + var err error + + if q.Prefix != "" { + rows, err = QueryWithParams(d, q) + } else { + rows, err = d.db.Query(d.queries.Query()) + } + + if err != nil { + return nil, err + } + + var entries []dsq.Entry + defer rows.Close() + + for rows.Next() { + var key string + var out []byte + err := rows.Scan(&key, &out) + + if err != nil { + log.Fatal("Error reading rows from query") + } + + entry := dsq.Entry{ + Key: key, + Value: out, + } + + entries = append(entries, entry) + } + + results := dsq.ResultsWithEntries(q, entries) + return results, nil +} + +func (d *Datastore) GetSize(key ds.Key) (int, error) { + row := d.db.QueryRow(d.queries.GetSize(), key.String()) + var size int + + switch err := row.Scan(&size); err { + case sql.ErrNoRows: + return -1, ds.ErrNotFound + case nil: + return size, nil + default: + return 0, err + } +} + +// QueryWithParams applies prefix, limit, and offset params in pg query +func QueryWithParams(d *Datastore, q dsq.Query) (*sql.Rows, error) { + var qNew = d.queries.Query() + + if q.Prefix != "" { + qNew += fmt.Sprintf(d.queries.Prefix(), q.Prefix) + } + + if q.Limit != 0 { + qNew += fmt.Sprintf(d.queries.Limit(), q.Limit) + } + + if q.Offset != 0 { + qNew += fmt.Sprintf(d.queries.Offset(), q.Offset) + } + + return d.db.Query(qNew) + +} + +var _ ds.Datastore = (*Datastore)(nil) diff --git a/vendor/github.com/whyrusleeping/sql-datastore/package.json b/vendor/github.com/whyrusleeping/sql-datastore/package.json new file mode 100644 index 00000000..f5cccc1b --- /dev/null +++ b/vendor/github.com/whyrusleeping/sql-datastore/package.json @@ -0,0 +1,30 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/sql-datastore" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/sql-datastore" + }, + "gxDependencies": [ + { + "author": "magik6k", + "hash": "QmfJhaxwzBCorUmZNRmY87z4mD6roRrHFMqddhiS4D4XWr", + "name": "pq", + "version": "1.0.0" + }, + { + "author": "jbenet", + "hash": "QmPGYyi1DtuWyUkG3PtvLz1xb4ScjnUvwJMCoX3cxeyxNr", + "name": "go-datastore", + "version": "3.5.0" + } + ], + "gxVersion": "0.14.0", + "language": "go", + "license": "", + "name": "sql-datastore", + "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", + "version": "1.0.2" +} + diff --git a/vendor/github.com/whyrusleeping/sql-datastore/postgres/postgres.go b/vendor/github.com/whyrusleeping/sql-datastore/postgres/postgres.go new file mode 100644 index 00000000..be418941 --- /dev/null +++ b/vendor/github.com/whyrusleeping/sql-datastore/postgres/postgres.go @@ -0,0 +1,89 @@ +package postgres + +import ( + "database/sql" + "fmt" + + "github.com/whyrusleeping/sql-datastore" + + _ "github.com/lib/pq" //postgres driver +) + +// Options are the postgres datastore options, reexported here for convenience. +type Options struct { + Host string + Port string + User string + Password string + Database string +} + +type Queries struct { +} + +func (Queries) Delete() string { + return `DELETE FROM blocks WHERE key = $1` +} + +func (Queries) Exists() string { + return `SELECT exists(SELECT 1 FROM blocks WHERE key=$1)` +} + +func (Queries) Get() string { + return `SELECT data FROM blocks WHERE key = $1` +} + +func (Queries) Put() string { + return `INSERT INTO blocks (key, data) SELECT $1, $2 WHERE NOT EXISTS ( SELECT key FROM blocks WHERE key = $1)` +} + +func (Queries) Query() string { + return `SELECT key, data FROM blocks` +} + +func (Queries) Prefix() string { + return ` WHERE key LIKE '%s%%' ORDER BY key` +} + +func (Queries) Limit() string { + return ` LIMIT %d` +} + +func (Queries) Offset() string { + return ` OFFSET %d` +} + +func (Queries) GetSize() string { + return `SELECT octet_length(data) FROM blocks WHERE key = $1` +} + +// Create returns a datastore connected to postgres +func (opts *Options) Create() (*sqlds.Datastore, error) { + opts.setDefaults() + fmtstr := "postgresql:///%s?host=%s&port=%s&user=%s&password=%s&sslmode=disable" + constr := fmt.Sprintf(fmtstr, opts.Database, opts.Host, opts.Port, opts.User, opts.Password) + db, err := sql.Open("postgres", constr) + if err != nil { + return nil, err + } + + return sqlds.NewDatastore(db, Queries{}), nil +} + +func (opts *Options) setDefaults() { + if opts.Host == "" { + opts.Host = "127.0.0.1" + } + + if opts.Port == "" { + opts.Port = "5432" + } + + if opts.User == "" { + opts.User = "postgres" + } + + if opts.Database == "" { + opts.Database = "datastore" + } +} diff --git a/vendor/github.com/whyrusleeping/timecache/LICENSE b/vendor/github.com/whyrusleeping/timecache/LICENSE new file mode 100644 index 00000000..26100332 --- /dev/null +++ b/vendor/github.com/whyrusleeping/timecache/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jeromy Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/whyrusleeping/timecache/README.md b/vendor/github.com/whyrusleeping/timecache/README.md new file mode 100644 index 00000000..edbadd2f --- /dev/null +++ b/vendor/github.com/whyrusleeping/timecache/README.md @@ -0,0 +1,8 @@ +# timecache + +Timecache is an lru cache that keeps entries for up to a specified time +duration. After a specified period of time has elapsed, 'old' entries will be +purged from the set. + +## License +MIT diff --git a/vendor/github.com/whyrusleeping/timecache/package.json b/vendor/github.com/whyrusleeping/timecache/package.json new file mode 100644 index 00000000..80d642f6 --- /dev/null +++ b/vendor/github.com/whyrusleeping/timecache/package.json @@ -0,0 +1,14 @@ +{ + "author": "whyrusleeping", + "bugs": { + "url": "https://github.com/whyrusleeping/timecache" + }, + "gx": { + "dvcsimport": "github.com/whyrusleeping/timecache" + }, + "gxVersion": "0.9.0", + "language": "go", + "license": "", + "name": "timecache", + "version": "1.0.0" +} diff --git a/vendor/github.com/whyrusleeping/timecache/timecache.go b/vendor/github.com/whyrusleeping/timecache/timecache.go new file mode 100644 index 00000000..94975585 --- /dev/null +++ b/vendor/github.com/whyrusleeping/timecache/timecache.go @@ -0,0 +1,60 @@ +package timecache + +import ( + "container/list" + "time" +) + +type TimeCache struct { + Q *list.List + M map[string]time.Time + + span time.Duration +} + +func NewTimeCache(span time.Duration) *TimeCache { + return &TimeCache{ + Q: list.New(), + M: make(map[string]time.Time), + span: span, + } +} + +func (tc *TimeCache) Add(s string) { + _, ok := tc.M[s] + if ok { + panic("putting the same entry twice not supported") + } + + tc.sweep() + + tc.M[s] = time.Now() + tc.Q.PushFront(s) +} + +func (tc *TimeCache) sweep() { + for { + back := tc.Q.Back() + if back == nil { + return + } + + v := back.Value.(string) + t, ok := tc.M[v] + if !ok { + panic("inconsistent cache state") + } + + if time.Since(t) > tc.span { + tc.Q.Remove(back) + delete(tc.M, v) + } else { + return + } + } +} + +func (tc *TimeCache) Has(s string) bool { + _, ok := tc.M[s] + return ok +} diff --git a/vendor/github.com/wsddn/go-ecdh/.gitignore b/vendor/github.com/wsddn/go-ecdh/.gitignore new file mode 100644 index 00000000..8d87f6f3 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test + +.directory diff --git a/vendor/github.com/wsddn/go-ecdh/.travis.yml b/vendor/github.com/wsddn/go-ecdh/.travis.yml new file mode 100644 index 00000000..0ebc231f --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/.travis.yml @@ -0,0 +1,11 @@ +language: go + +go: + - 1.2 + - tip + +install: go get golang.org/x/crypto/curve25519 + +script: +- go get github.com/tang0th/go-ecdh +- go test github.com/tang0th/go-ecdh diff --git a/vendor/github.com/wsddn/go-ecdh/LICENSE b/vendor/github.com/wsddn/go-ecdh/LICENSE new file mode 100644 index 00000000..c16b0acf --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2014, tang0th +All rights reserved. + +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 tang0th 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 HOLDER 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. diff --git a/vendor/github.com/wsddn/go-ecdh/Readme.md b/vendor/github.com/wsddn/go-ecdh/Readme.md new file mode 100644 index 00000000..1445f68b --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/Readme.md @@ -0,0 +1,19 @@ +# ECDH + +[![Build Status](https://travis-ci.org/wsddn/go-ecdh.svg?branch=master)](https://travis-ci.org/wsddn/go-ecdh) + +This is a go implementation of elliptical curve diffie-hellman key exchange method. +It supports the NIST curves (and any curves using the `elliptic.Curve` go interface) +as well as djb's curve25519. + +The library handles generating of keys, generating a shared secret, and the +(un)marshalling of the elliptical curve keys into slices of bytes. + +## Warning and Disclaimer +I am not a cryptographer, this was written as part of a personal project to learn about cryptographic systems and protocols. No claims as to the security of this library are made, I would not advise using it for anything that requires any level of security. Pull requests or issues about security flaws are however still welcome. + +## Compatibility +Works with go 1.2 onwards. + +## TODO + * Improve documentation diff --git a/vendor/github.com/wsddn/go-ecdh/curve25519.go b/vendor/github.com/wsddn/go-ecdh/curve25519.go new file mode 100644 index 00000000..6426cbf8 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/curve25519.go @@ -0,0 +1,62 @@ +package ecdh + +import ( + "crypto" + "io" + + "golang.org/x/crypto/curve25519" +) + +type curve25519ECDH struct { + ECDH +} + +// NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519 +// elliptical curve. +func NewCurve25519ECDH() ECDH { + return &curve25519ECDH{} +} + +func (e *curve25519ECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) { + var pub, priv [32]byte + var err error + + _, err = io.ReadFull(rand, priv[:]) + if err != nil { + return nil, nil, err + } + + priv[0] &= 248 + priv[31] &= 127 + priv[31] |= 64 + + curve25519.ScalarBaseMult(&pub, &priv) + + return &priv, &pub, nil +} + +func (e *curve25519ECDH) Marshal(p crypto.PublicKey) []byte { + pub := p.(*[32]byte) + return pub[:] +} + +func (e *curve25519ECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) { + var pub [32]byte + if len(data) != 32 { + return nil, false + } + + copy(pub[:], data) + return &pub, true +} + +func (e *curve25519ECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) { + var priv, pub, secret *[32]byte + + priv = privKey.(*[32]byte) + pub = pubKey.(*[32]byte) + secret = new([32]byte) + + curve25519.ScalarMult(secret, priv, pub) + return secret[:], nil +} diff --git a/vendor/github.com/wsddn/go-ecdh/ecdh.go b/vendor/github.com/wsddn/go-ecdh/ecdh.go new file mode 100644 index 00000000..921754fd --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/ecdh.go @@ -0,0 +1,14 @@ +package ecdh + +import ( + "crypto" + "io" +) + +// The main interface for ECDH key exchange. +type ECDH interface { + GenerateKey(io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) + Marshal(crypto.PublicKey) []byte + Unmarshal([]byte) (crypto.PublicKey, bool) + GenerateSharedSecret(crypto.PrivateKey, crypto.PublicKey) ([]byte, error) +} diff --git a/vendor/github.com/wsddn/go-ecdh/elliptic.go b/vendor/github.com/wsddn/go-ecdh/elliptic.go new file mode 100644 index 00000000..502563c4 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/elliptic.go @@ -0,0 +1,87 @@ +package ecdh + +import ( + "crypto" + "crypto/elliptic" + "io" + "math/big" +) + +type ellipticECDH struct { + ECDH + curve elliptic.Curve +} + +type ellipticPublicKey struct { + elliptic.Curve + X, Y *big.Int +} + +type ellipticPrivateKey struct { + D []byte +} + +// NewEllipticECDH creates a new instance of ECDH with the given elliptic.Curve curve +// to use as the elliptical curve for elliptical curve diffie-hellman. +func NewEllipticECDH(curve elliptic.Curve) ECDH { + return &ellipticECDH{ + curve: curve, + } +} + +func (e *ellipticECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) { + var d []byte + var x, y *big.Int + var priv *ellipticPrivateKey + var pub *ellipticPublicKey + var err error + + d, x, y, err = elliptic.GenerateKey(e.curve, rand) + if err != nil { + return nil, nil, err + } + + priv = &ellipticPrivateKey{ + D: d, + } + pub = &ellipticPublicKey{ + Curve: e.curve, + X: x, + Y: y, + } + + return priv, pub, nil +} + +func (e *ellipticECDH) Marshal(p crypto.PublicKey) []byte { + pub := p.(*ellipticPublicKey) + return elliptic.Marshal(e.curve, pub.X, pub.Y) +} + +func (e *ellipticECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) { + var key *ellipticPublicKey + var x, y *big.Int + + x, y = elliptic.Unmarshal(e.curve, data) + if x == nil || y == nil { + return key, false + } + key = &ellipticPublicKey{ + Curve: e.curve, + X: x, + Y: y, + } + return key, true +} + +// GenerateSharedSecret takes in a public key and a private key +// and generates a shared secret. +// +// RFC5903 Section 9 states we should only return x. +func (e *ellipticECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) { + priv := privKey.(*ellipticPrivateKey) + pub := pubKey.(*ellipticPublicKey) + + x, _ := e.curve.ScalarMult(pub.X, pub.Y, priv.D) + return x.Bytes(), nil +} diff --git a/vendor/go.opencensus.io/AUTHORS b/vendor/go.opencensus.io/AUTHORS new file mode 100644 index 00000000..e491a9e7 --- /dev/null +++ b/vendor/go.opencensus.io/AUTHORS @@ -0,0 +1 @@ +Google Inc. diff --git a/vendor/go.opencensus.io/LICENSE b/vendor/go.opencensus.io/LICENSE new file mode 100644 index 00000000..7a4a3ea2 --- /dev/null +++ b/vendor/go.opencensus.io/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go new file mode 100644 index 00000000..41b2c3fc --- /dev/null +++ b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go @@ -0,0 +1,75 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package tagencoding contains the tag encoding +// used interally by the stats collector. +package tagencoding // import "go.opencensus.io/internal/tagencoding" + +// Values represent the encoded buffer for the values. +type Values struct { + Buffer []byte + WriteIndex int + ReadIndex int +} + +func (vb *Values) growIfRequired(expected int) { + if len(vb.Buffer)-vb.WriteIndex < expected { + tmp := make([]byte, 2*(len(vb.Buffer)+1)+expected) + copy(tmp, vb.Buffer) + vb.Buffer = tmp + } +} + +// WriteValue is the helper method to encode Values from map[Key][]byte. +func (vb *Values) WriteValue(v []byte) { + length := len(v) & 0xff + vb.growIfRequired(1 + length) + + // writing length of v + vb.Buffer[vb.WriteIndex] = byte(length) + vb.WriteIndex++ + + if length == 0 { + // No value was encoded for this key + return + } + + // writing v + copy(vb.Buffer[vb.WriteIndex:], v[:length]) + vb.WriteIndex += length +} + +// ReadValue is the helper method to decode Values to a map[Key][]byte. +func (vb *Values) ReadValue() []byte { + // read length of v + length := int(vb.Buffer[vb.ReadIndex]) + vb.ReadIndex++ + if length == 0 { + // No value was encoded for this key + return nil + } + + // read value of v + v := make([]byte, length) + endIdx := vb.ReadIndex + length + copy(v, vb.Buffer[vb.ReadIndex:endIdx]) + vb.ReadIndex = endIdx + return v +} + +// Bytes returns a reference to already written bytes in the Buffer. +func (vb *Values) Bytes() []byte { + return vb.Buffer[:vb.WriteIndex] +} diff --git a/vendor/go.opencensus.io/metric/metricdata/doc.go b/vendor/go.opencensus.io/metric/metricdata/doc.go new file mode 100644 index 00000000..52a7b3bf --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/doc.go @@ -0,0 +1,19 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package metricdata contains the metrics data model. +// +// This is an EXPERIMENTAL package, and may change in arbitrary ways without +// notice. +package metricdata // import "go.opencensus.io/metric/metricdata" diff --git a/vendor/go.opencensus.io/metric/metricdata/exemplar.go b/vendor/go.opencensus.io/metric/metricdata/exemplar.go new file mode 100644 index 00000000..12695ce2 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/exemplar.go @@ -0,0 +1,38 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" +) + +// Exemplars keys. +const ( + AttachmentKeySpanContext = "SpanContext" +) + +// Exemplar is an example data point associated with each bucket of a +// distribution type aggregation. +// +// Their purpose is to provide an example of the kind of thing +// (request, RPC, trace span, etc.) that resulted in that measurement. +type Exemplar struct { + Value float64 // the value that was recorded + Timestamp time.Time // the time the value was recorded + Attachments Attachments // attachments (if any) +} + +// Attachments is a map of extra values associated with a recorded data point. +type Attachments map[string]interface{} diff --git a/vendor/go.opencensus.io/metric/metricdata/label.go b/vendor/go.opencensus.io/metric/metricdata/label.go new file mode 100644 index 00000000..aadae41e --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/label.go @@ -0,0 +1,35 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +// LabelKey represents key of a label. It has optional +// description attribute. +type LabelKey struct { + Key string + Description string +} + +// LabelValue represents the value of a label. +// The zero value represents a missing label value, which may be treated +// differently to an empty string value by some back ends. +type LabelValue struct { + Value string // string value of the label + Present bool // flag that indicated whether a value is present or not +} + +// NewLabelValue creates a new non-nil LabelValue that represents the given string. +func NewLabelValue(val string) LabelValue { + return LabelValue{Value: val, Present: true} +} diff --git a/vendor/go.opencensus.io/metric/metricdata/metric.go b/vendor/go.opencensus.io/metric/metricdata/metric.go new file mode 100644 index 00000000..8293712c --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/metric.go @@ -0,0 +1,46 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" + + "go.opencensus.io/resource" +) + +// Descriptor holds metadata about a metric. +type Descriptor struct { + Name string // full name of the metric + Description string // human-readable description + Unit Unit // units for the measure + Type Type // type of measure + LabelKeys []LabelKey // label keys +} + +// Metric represents a quantity measured against a resource with different +// label value combinations. +type Metric struct { + Descriptor Descriptor // metric descriptor + Resource *resource.Resource // resource against which this was measured + TimeSeries []*TimeSeries // one time series for each combination of label values +} + +// TimeSeries is a sequence of points associated with a combination of label +// values. +type TimeSeries struct { + LabelValues []LabelValue // label values, same order as keys in the metric descriptor + Points []Point // points sequence + StartTime time.Time // time we started recording this time series +} diff --git a/vendor/go.opencensus.io/metric/metricdata/point.go b/vendor/go.opencensus.io/metric/metricdata/point.go new file mode 100644 index 00000000..7fe057b1 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/point.go @@ -0,0 +1,193 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +import ( + "time" +) + +// Point is a single data point of a time series. +type Point struct { + // Time is the point in time that this point represents in a time series. + Time time.Time + // Value is the value of this point. Prefer using ReadValue to switching on + // the value type, since new value types might be added. + Value interface{} +} + +//go:generate stringer -type ValueType + +// NewFloat64Point creates a new Point holding a float64 value. +func NewFloat64Point(t time.Time, val float64) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewInt64Point creates a new Point holding an int64 value. +func NewInt64Point(t time.Time, val int64) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewDistributionPoint creates a new Point holding a Distribution value. +func NewDistributionPoint(t time.Time, val *Distribution) Point { + return Point{ + Value: val, + Time: t, + } +} + +// NewSummaryPoint creates a new Point holding a Summary value. +func NewSummaryPoint(t time.Time, val *Summary) Point { + return Point{ + Value: val, + Time: t, + } +} + +// ValueVisitor allows reading the value of a point. +type ValueVisitor interface { + VisitFloat64Value(float64) + VisitInt64Value(int64) + VisitDistributionValue(*Distribution) + VisitSummaryValue(*Summary) +} + +// ReadValue accepts a ValueVisitor and calls the appropriate method with the +// value of this point. +// Consumers of Point should use this in preference to switching on the type +// of the value directly, since new value types may be added. +func (p Point) ReadValue(vv ValueVisitor) { + switch v := p.Value.(type) { + case int64: + vv.VisitInt64Value(v) + case float64: + vv.VisitFloat64Value(v) + case *Distribution: + vv.VisitDistributionValue(v) + case *Summary: + vv.VisitSummaryValue(v) + default: + panic("unexpected value type") + } +} + +// Distribution contains summary statistics for a population of values. It +// optionally contains a histogram representing the distribution of those +// values across a set of buckets. +type Distribution struct { + // Count is the number of values in the population. Must be non-negative. This value + // must equal the sum of the values in bucket_counts if a histogram is + // provided. + Count int64 + // Sum is the sum of the values in the population. If count is zero then this field + // must be zero. + Sum float64 + // SumOfSquaredDeviation is the sum of squared deviations from the mean of the values in the + // population. For values x_i this is: + // + // Sum[i=1..n]((x_i - mean)^2) + // + // Knuth, "The Art of Computer Programming", Vol. 2, page 323, 3rd edition + // describes Welford's method for accumulating this sum in one pass. + // + // If count is zero then this field must be zero. + SumOfSquaredDeviation float64 + // BucketOptions describes the bounds of the histogram buckets in this + // distribution. + // + // A Distribution may optionally contain a histogram of the values in the + // population. + // + // If nil, there is no associated histogram. + BucketOptions *BucketOptions + // Bucket If the distribution does not have a histogram, then omit this field. + // If there is a histogram, then the sum of the values in the Bucket counts + // must equal the value in the count field of the distribution. + Buckets []Bucket +} + +// BucketOptions describes the bounds of the histogram buckets in this +// distribution. +type BucketOptions struct { + // Bounds specifies a set of bucket upper bounds. + // This defines len(bounds) + 1 (= N) buckets. The boundaries for bucket + // index i are: + // + // [0, Bounds[i]) for i == 0 + // [Bounds[i-1], Bounds[i]) for 0 < i < N-1 + // [Bounds[i-1], +infinity) for i == N-1 + Bounds []float64 +} + +// Bucket represents a single bucket (value range) in a distribution. +type Bucket struct { + // Count is the number of values in each bucket of the histogram, as described in + // bucket_bounds. + Count int64 + // Exemplar associated with this bucket (if any). + Exemplar *Exemplar +} + +// Summary is a representation of percentiles. +type Summary struct { + // Count is the cumulative count (if available). + Count int64 + // Sum is the cumulative sum of values (if available). + Sum float64 + // HasCountAndSum is true if Count and Sum are available. + HasCountAndSum bool + // Snapshot represents percentiles calculated over an arbitrary time window. + // The values in this struct can be reset at arbitrary unknown times, with + // the requirement that all of them are reset at the same time. + Snapshot Snapshot +} + +// Snapshot represents percentiles over an arbitrary time. +// The values in this struct can be reset at arbitrary unknown times, with +// the requirement that all of them are reset at the same time. +type Snapshot struct { + // Count is the number of values in the snapshot. Optional since some systems don't + // expose this. Set to 0 if not available. + Count int64 + // Sum is the sum of values in the snapshot. Optional since some systems don't + // expose this. If count is 0 then this field must be zero. + Sum float64 + // Percentiles is a map from percentile (range (0-100.0]) to the value of + // the percentile. + Percentiles map[float64]float64 +} + +//go:generate stringer -type Type + +// Type is the overall type of metric, including its value type and whether it +// represents a cumulative total (since the start time) or if it represents a +// gauge value. +type Type int + +// Metric types. +const ( + TypeGaugeInt64 Type = iota + TypeGaugeFloat64 + TypeGaugeDistribution + TypeCumulativeInt64 + TypeCumulativeFloat64 + TypeCumulativeDistribution + TypeSummary +) diff --git a/vendor/go.opencensus.io/metric/metricdata/type_string.go b/vendor/go.opencensus.io/metric/metricdata/type_string.go new file mode 100644 index 00000000..c3f8ec27 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/type_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type Type"; DO NOT EDIT. + +package metricdata + +import "strconv" + +const _Type_name = "TypeGaugeInt64TypeGaugeFloat64TypeGaugeDistributionTypeCumulativeInt64TypeCumulativeFloat64TypeCumulativeDistributionTypeSummary" + +var _Type_index = [...]uint8{0, 14, 30, 51, 70, 91, 117, 128} + +func (i Type) String() string { + if i < 0 || i >= Type(len(_Type_index)-1) { + return "Type(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Type_name[_Type_index[i]:_Type_index[i+1]] +} diff --git a/vendor/go.opencensus.io/metric/metricdata/unit.go b/vendor/go.opencensus.io/metric/metricdata/unit.go new file mode 100644 index 00000000..b483a137 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricdata/unit.go @@ -0,0 +1,27 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricdata + +// Unit is a string encoded according to the case-sensitive abbreviations from the +// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html +type Unit string + +// Predefined units. To record against a unit not represented here, create your +// own Unit type constant from a string. +const ( + UnitDimensionless Unit = "1" + UnitBytes Unit = "By" + UnitMilliseconds Unit = "ms" +) diff --git a/vendor/go.opencensus.io/metric/metricproducer/manager.go b/vendor/go.opencensus.io/metric/metricproducer/manager.go new file mode 100644 index 00000000..ca1f3904 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricproducer/manager.go @@ -0,0 +1,78 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricproducer + +import ( + "sync" +) + +// Manager maintains a list of active producers. Producers can register +// with the manager to allow readers to read all metrics provided by them. +// Readers can retrieve all producers registered with the manager, +// read metrics from the producers and export them. +type Manager struct { + mu sync.RWMutex + producers map[Producer]struct{} +} + +var prodMgr *Manager +var once sync.Once + +// GlobalManager is a single instance of producer manager +// that is used by all producers and all readers. +func GlobalManager() *Manager { + once.Do(func() { + prodMgr = &Manager{} + prodMgr.producers = make(map[Producer]struct{}) + }) + return prodMgr +} + +// AddProducer adds the producer to the Manager if it is not already present. +func (pm *Manager) AddProducer(producer Producer) { + if producer == nil { + return + } + pm.mu.Lock() + defer pm.mu.Unlock() + pm.producers[producer] = struct{}{} +} + +// DeleteProducer deletes the producer from the Manager if it is present. +func (pm *Manager) DeleteProducer(producer Producer) { + if producer == nil { + return + } + pm.mu.Lock() + defer pm.mu.Unlock() + delete(pm.producers, producer) +} + +// GetAll returns a slice of all producer currently registered with +// the Manager. For each call it generates a new slice. The slice +// should not be cached as registration may change at any time. It is +// typically called periodically by exporter to read metrics from +// the producers. +func (pm *Manager) GetAll() []Producer { + pm.mu.Lock() + defer pm.mu.Unlock() + producers := make([]Producer, len(pm.producers)) + i := 0 + for producer := range pm.producers { + producers[i] = producer + i++ + } + return producers +} diff --git a/vendor/go.opencensus.io/metric/metricproducer/producer.go b/vendor/go.opencensus.io/metric/metricproducer/producer.go new file mode 100644 index 00000000..6cee9ed1 --- /dev/null +++ b/vendor/go.opencensus.io/metric/metricproducer/producer.go @@ -0,0 +1,28 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metricproducer + +import ( + "go.opencensus.io/metric/metricdata" +) + +// Producer is a source of metrics. +type Producer interface { + // Read should return the current values of all metrics supported by this + // metric provider. + // The returned metrics should be unique for each combination of name and + // resource. + Read() []*metricdata.Metric +} diff --git a/vendor/go.opencensus.io/resource/resource.go b/vendor/go.opencensus.io/resource/resource.go new file mode 100644 index 00000000..b1764e1d --- /dev/null +++ b/vendor/go.opencensus.io/resource/resource.go @@ -0,0 +1,164 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package resource provides functionality for resource, which capture +// identifying information about the entities for which signals are exported. +package resource + +import ( + "context" + "fmt" + "os" + "regexp" + "sort" + "strconv" + "strings" +) + +// Environment variables used by FromEnv to decode a resource. +const ( + EnvVarType = "OC_RESOURCE_TYPE" + EnvVarLabels = "OC_RESOURCE_LABELS" +) + +// Resource describes an entity about which identifying information and metadata is exposed. +// For example, a type "k8s.io/container" may hold labels describing the pod name and namespace. +type Resource struct { + Type string + Labels map[string]string +} + +// EncodeLabels encodes a labels map to a string as provided via the OC_RESOURCE_LABELS environment variable. +func EncodeLabels(labels map[string]string) string { + sortedKeys := make([]string, 0, len(labels)) + for k := range labels { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + + s := "" + for i, k := range sortedKeys { + if i > 0 { + s += "," + } + s += k + "=" + strconv.Quote(labels[k]) + } + return s +} + +var labelRegex = regexp.MustCompile(`^\s*([[:ascii:]]{1,256}?)=("[[:ascii:]]{0,256}?")\s*,`) + +// DecodeLabels decodes a serialized label map as used in the OC_RESOURCE_LABELS variable. +// A list of labels of the form `="",="",...` is accepted. +// Domain names and paths are accepted as label keys. +// Most users will want to use FromEnv instead. +func DecodeLabels(s string) (map[string]string, error) { + m := map[string]string{} + // Ensure a trailing comma, which allows us to keep the regex simpler + s = strings.TrimRight(strings.TrimSpace(s), ",") + "," + + for len(s) > 0 { + match := labelRegex.FindStringSubmatch(s) + if len(match) == 0 { + return nil, fmt.Errorf("invalid label formatting, remainder: %s", s) + } + v := match[2] + if v == "" { + v = match[3] + } else { + var err error + if v, err = strconv.Unquote(v); err != nil { + return nil, fmt.Errorf("invalid label formatting, remainder: %s, err: %s", s, err) + } + } + m[match[1]] = v + + s = s[len(match[0]):] + } + return m, nil +} + +// FromEnv is a detector that loads resource information from the OC_RESOURCE_TYPE +// and OC_RESOURCE_labelS environment variables. +func FromEnv(context.Context) (*Resource, error) { + res := &Resource{ + Type: strings.TrimSpace(os.Getenv(EnvVarType)), + } + labels := strings.TrimSpace(os.Getenv(EnvVarLabels)) + if labels == "" { + return res, nil + } + var err error + if res.Labels, err = DecodeLabels(labels); err != nil { + return nil, err + } + return res, nil +} + +var _ Detector = FromEnv + +// merge resource information from b into a. In case of a collision, a takes precedence. +func merge(a, b *Resource) *Resource { + if a == nil { + return b + } + if b == nil { + return a + } + res := &Resource{ + Type: a.Type, + Labels: map[string]string{}, + } + if res.Type == "" { + res.Type = b.Type + } + for k, v := range b.Labels { + res.Labels[k] = v + } + // Labels from resource a overwrite labels from resource b. + for k, v := range a.Labels { + res.Labels[k] = v + } + return res +} + +// Detector attempts to detect resource information. +// If the detector cannot find resource information, the returned resource is nil but no +// error is returned. +// An error is only returned on unexpected failures. +type Detector func(context.Context) (*Resource, error) + +// MultiDetector returns a Detector that calls all input detectors in order and +// merges each result with the previous one. In case a type of label key is already set, +// the first set value is takes precedence. +// It returns on the first error that a sub-detector encounters. +func MultiDetector(detectors ...Detector) Detector { + return func(ctx context.Context) (*Resource, error) { + return detectAll(ctx, detectors...) + } +} + +// detectall calls all input detectors sequentially an merges each result with the previous one. +// It returns on the first error that a sub-detector encounters. +func detectAll(ctx context.Context, detectors ...Detector) (*Resource, error) { + var res *Resource + for _, d := range detectors { + r, err := d(ctx) + if err != nil { + return nil, err + } + res = merge(res, r) + } + return res, nil +} diff --git a/vendor/go.opencensus.io/stats/doc.go b/vendor/go.opencensus.io/stats/doc.go new file mode 100644 index 00000000..00d473ee --- /dev/null +++ b/vendor/go.opencensus.io/stats/doc.go @@ -0,0 +1,69 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/* +Package stats contains support for OpenCensus stats recording. + +OpenCensus allows users to create typed measures, record measurements, +aggregate the collected data, and export the aggregated data. + +Measures + +A measure represents a type of data point to be tracked and recorded. +For example, latency, request Mb/s, and response Mb/s are measures +to collect from a server. + +Measure constructors such as Int64 and Float64 automatically +register the measure by the given name. Each registered measure needs +to be unique by name. Measures also have a description and a unit. + +Libraries can define and export measures. Application authors can then +create views and collect and break down measures by the tags they are +interested in. + +Recording measurements + +Measurement is a data point to be collected for a measure. For example, +for a latency (ms) measure, 100 is a measurement that represents a 100ms +latency event. Measurements are created from measures with +the current context. Tags from the current context are recorded with the +measurements if they are any. + +Recorded measurements are dropped immediately if no views are registered for them. +There is usually no need to conditionally enable and disable +recording to reduce cost. Recording of measurements is cheap. + +Libraries can always record measurements, and applications can later decide +on which measurements they want to collect by registering views. This allows +libraries to turn on the instrumentation by default. + +Exemplars + +For a given recorded measurement, the associated exemplar is a diagnostic map +that gives more information about the measurement. + +When aggregated using a Distribution aggregation, an exemplar is kept for each +bucket in the Distribution. This allows you to easily find an example of a +measurement that fell into each bucket. + +For example, if you also use the OpenCensus trace package and you +record a measurement with a context that contains a sampled trace span, +then the trace span will be added to the exemplar associated with the measurement. + +When exported to a supporting back end, you should be able to easily navigate +to example traces that fell into each bucket in the Distribution. + +*/ +package stats // import "go.opencensus.io/stats" diff --git a/vendor/go.opencensus.io/stats/internal/record.go b/vendor/go.opencensus.io/stats/internal/record.go new file mode 100644 index 00000000..36935e62 --- /dev/null +++ b/vendor/go.opencensus.io/stats/internal/record.go @@ -0,0 +1,25 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import ( + "go.opencensus.io/tag" +) + +// DefaultRecorder will be called for each Record call. +var DefaultRecorder func(tags *tag.Map, measurement interface{}, attachments map[string]interface{}) + +// SubscriptionReporter reports when a view subscribed with a measure. +var SubscriptionReporter func(measure string) diff --git a/vendor/go.opencensus.io/stats/measure.go b/vendor/go.opencensus.io/stats/measure.go new file mode 100644 index 00000000..1ffd3cef --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure.go @@ -0,0 +1,109 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +import ( + "sync" + "sync/atomic" +) + +// Measure represents a single numeric value to be tracked and recorded. +// For example, latency, request bytes, and response bytes could be measures +// to collect from a server. +// +// Measures by themselves have no outside effects. In order to be exported, +// the measure needs to be used in a View. If no Views are defined over a +// measure, there is very little cost in recording it. +type Measure interface { + // Name returns the name of this measure. + // + // Measure names are globally unique (among all libraries linked into your program). + // We recommend prefixing the measure name with a domain name relevant to your + // project or application. + // + // Measure names are never sent over the wire or exported to backends. + // They are only used to create Views. + Name() string + + // Description returns the human-readable description of this measure. + Description() string + + // Unit returns the units for the values this measure takes on. + // + // Units are encoded according to the case-sensitive abbreviations from the + // Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html + Unit() string +} + +// measureDescriptor is the untyped descriptor associated with each measure. +// Int64Measure and Float64Measure wrap measureDescriptor to provide typed +// recording APIs. +// Two Measures with the same name will have the same measureDescriptor. +type measureDescriptor struct { + subs int32 // access atomically + + name string + description string + unit string +} + +func (m *measureDescriptor) subscribe() { + atomic.StoreInt32(&m.subs, 1) +} + +func (m *measureDescriptor) subscribed() bool { + return atomic.LoadInt32(&m.subs) == 1 +} + +var ( + mu sync.RWMutex + measures = make(map[string]*measureDescriptor) +) + +func registerMeasureHandle(name, desc, unit string) *measureDescriptor { + mu.Lock() + defer mu.Unlock() + + if stored, ok := measures[name]; ok { + return stored + } + m := &measureDescriptor{ + name: name, + description: desc, + unit: unit, + } + measures[name] = m + return m +} + +// Measurement is the numeric value measured when recording stats. Each measure +// provides methods to create measurements of their kind. For example, Int64Measure +// provides M to convert an int64 into a measurement. +type Measurement struct { + v float64 + m Measure + desc *measureDescriptor +} + +// Value returns the value of the Measurement as a float64. +func (m Measurement) Value() float64 { + return m.v +} + +// Measure returns the Measure from which this Measurement was created. +func (m Measurement) Measure() Measure { + return m.m +} diff --git a/vendor/go.opencensus.io/stats/measure_float64.go b/vendor/go.opencensus.io/stats/measure_float64.go new file mode 100644 index 00000000..f02c1eda --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure_float64.go @@ -0,0 +1,55 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Float64Measure is a measure for float64 values. +type Float64Measure struct { + desc *measureDescriptor +} + +// M creates a new float64 measurement. +// Use Record to record measurements. +func (m *Float64Measure) M(v float64) Measurement { + return Measurement{ + m: m, + desc: m.desc, + v: v, + } +} + +// Float64 creates a new measure for float64 values. +// +// See the documentation for interface Measure for more guidance on the +// parameters of this function. +func Float64(name, description, unit string) *Float64Measure { + mi := registerMeasureHandle(name, description, unit) + return &Float64Measure{mi} +} + +// Name returns the name of the measure. +func (m *Float64Measure) Name() string { + return m.desc.name +} + +// Description returns the description of the measure. +func (m *Float64Measure) Description() string { + return m.desc.description +} + +// Unit returns the unit of the measure. +func (m *Float64Measure) Unit() string { + return m.desc.unit +} diff --git a/vendor/go.opencensus.io/stats/measure_int64.go b/vendor/go.opencensus.io/stats/measure_int64.go new file mode 100644 index 00000000..d101d797 --- /dev/null +++ b/vendor/go.opencensus.io/stats/measure_int64.go @@ -0,0 +1,55 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Int64Measure is a measure for int64 values. +type Int64Measure struct { + desc *measureDescriptor +} + +// M creates a new int64 measurement. +// Use Record to record measurements. +func (m *Int64Measure) M(v int64) Measurement { + return Measurement{ + m: m, + desc: m.desc, + v: float64(v), + } +} + +// Int64 creates a new measure for int64 values. +// +// See the documentation for interface Measure for more guidance on the +// parameters of this function. +func Int64(name, description, unit string) *Int64Measure { + mi := registerMeasureHandle(name, description, unit) + return &Int64Measure{mi} +} + +// Name returns the name of the measure. +func (m *Int64Measure) Name() string { + return m.desc.name +} + +// Description returns the description of the measure. +func (m *Int64Measure) Description() string { + return m.desc.description +} + +// Unit returns the unit of the measure. +func (m *Int64Measure) Unit() string { + return m.desc.unit +} diff --git a/vendor/go.opencensus.io/stats/record.go b/vendor/go.opencensus.io/stats/record.go new file mode 100644 index 00000000..ad469118 --- /dev/null +++ b/vendor/go.opencensus.io/stats/record.go @@ -0,0 +1,117 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +import ( + "context" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +func init() { + internal.SubscriptionReporter = func(measure string) { + mu.Lock() + measures[measure].subscribe() + mu.Unlock() + } +} + +type recordOptions struct { + attachments metricdata.Attachments + mutators []tag.Mutator + measurements []Measurement +} + +// WithAttachments applies provided exemplar attachments. +func WithAttachments(attachments metricdata.Attachments) Options { + return func(ro *recordOptions) { + ro.attachments = attachments + } +} + +// WithTags applies provided tag mutators. +func WithTags(mutators ...tag.Mutator) Options { + return func(ro *recordOptions) { + ro.mutators = mutators + } +} + +// WithMeasurements applies provided measurements. +func WithMeasurements(measurements ...Measurement) Options { + return func(ro *recordOptions) { + ro.measurements = measurements + } +} + +// Options apply changes to recordOptions. +type Options func(*recordOptions) + +func createRecordOption(ros ...Options) *recordOptions { + o := &recordOptions{} + for _, ro := range ros { + ro(o) + } + return o +} + +// Record records one or multiple measurements with the same context at once. +// If there are any tags in the context, measurements will be tagged with them. +func Record(ctx context.Context, ms ...Measurement) { + RecordWithOptions(ctx, WithMeasurements(ms...)) +} + +// RecordWithTags records one or multiple measurements at once. +// +// Measurements will be tagged with the tags in the context mutated by the mutators. +// RecordWithTags is useful if you want to record with tag mutations but don't want +// to propagate the mutations in the context. +func RecordWithTags(ctx context.Context, mutators []tag.Mutator, ms ...Measurement) error { + return RecordWithOptions(ctx, WithTags(mutators...), WithMeasurements(ms...)) +} + +// RecordWithOptions records measurements from the given options (if any) against context +// and tags and attachments in the options (if any). +// If there are any tags in the context, measurements will be tagged with them. +func RecordWithOptions(ctx context.Context, ros ...Options) error { + o := createRecordOption(ros...) + if len(o.measurements) == 0 { + return nil + } + recorder := internal.DefaultRecorder + if recorder == nil { + return nil + } + record := false + for _, m := range o.measurements { + if m.desc.subscribed() { + record = true + break + } + } + if !record { + return nil + } + if len(o.mutators) > 0 { + var err error + if ctx, err = tag.New(ctx, o.mutators...); err != nil { + return err + } + } + recorder(tag.FromContext(ctx), o.measurements, o.attachments) + return nil +} diff --git a/vendor/go.opencensus.io/stats/units.go b/vendor/go.opencensus.io/stats/units.go new file mode 100644 index 00000000..6931a5f2 --- /dev/null +++ b/vendor/go.opencensus.io/stats/units.go @@ -0,0 +1,25 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package stats + +// Units are encoded according to the case-sensitive abbreviations from the +// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html +const ( + UnitNone = "1" // Deprecated: Use UnitDimensionless. + UnitDimensionless = "1" + UnitBytes = "By" + UnitMilliseconds = "ms" +) diff --git a/vendor/go.opencensus.io/stats/view/aggregation.go b/vendor/go.opencensus.io/stats/view/aggregation.go new file mode 100644 index 00000000..b7f169b4 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/aggregation.go @@ -0,0 +1,120 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +// AggType represents the type of aggregation function used on a View. +type AggType int + +// All available aggregation types. +const ( + AggTypeNone AggType = iota // no aggregation; reserved for future use. + AggTypeCount // the count aggregation, see Count. + AggTypeSum // the sum aggregation, see Sum. + AggTypeDistribution // the distribution aggregation, see Distribution. + AggTypeLastValue // the last value aggregation, see LastValue. +) + +func (t AggType) String() string { + return aggTypeName[t] +} + +var aggTypeName = map[AggType]string{ + AggTypeNone: "None", + AggTypeCount: "Count", + AggTypeSum: "Sum", + AggTypeDistribution: "Distribution", + AggTypeLastValue: "LastValue", +} + +// Aggregation represents a data aggregation method. Use one of the functions: +// Count, Sum, or Distribution to construct an Aggregation. +type Aggregation struct { + Type AggType // Type is the AggType of this Aggregation. + Buckets []float64 // Buckets are the bucket endpoints if this Aggregation represents a distribution, see Distribution. + + newData func() AggregationData +} + +var ( + aggCount = &Aggregation{ + Type: AggTypeCount, + newData: func() AggregationData { + return &CountData{} + }, + } + aggSum = &Aggregation{ + Type: AggTypeSum, + newData: func() AggregationData { + return &SumData{} + }, + } +) + +// Count indicates that data collected and aggregated +// with this method will be turned into a count value. +// For example, total number of accepted requests can be +// aggregated by using Count. +func Count() *Aggregation { + return aggCount +} + +// Sum indicates that data collected and aggregated +// with this method will be summed up. +// For example, accumulated request bytes can be aggregated by using +// Sum. +func Sum() *Aggregation { + return aggSum +} + +// Distribution indicates that the desired aggregation is +// a histogram distribution. +// +// An distribution aggregation may contain a histogram of the values in the +// population. The bucket boundaries for that histogram are described +// by the bounds. This defines len(bounds)+1 buckets. +// +// If len(bounds) >= 2 then the boundaries for bucket index i are: +// +// [-infinity, bounds[i]) for i = 0 +// [bounds[i-1], bounds[i]) for 0 < i < length +// [bounds[i-1], +infinity) for i = length +// +// If len(bounds) is 0 then there is no histogram associated with the +// distribution. There will be a single bucket with boundaries +// (-infinity, +infinity). +// +// If len(bounds) is 1 then there is no finite buckets, and that single +// element is the common boundary of the overflow and underflow buckets. +func Distribution(bounds ...float64) *Aggregation { + return &Aggregation{ + Type: AggTypeDistribution, + Buckets: bounds, + newData: func() AggregationData { + return newDistributionData(bounds) + }, + } +} + +// LastValue only reports the last value recorded using this +// aggregation. All other measurements will be dropped. +func LastValue() *Aggregation { + return &Aggregation{ + Type: AggTypeLastValue, + newData: func() AggregationData { + return &LastValueData{} + }, + } +} diff --git a/vendor/go.opencensus.io/stats/view/aggregation_data.go b/vendor/go.opencensus.io/stats/view/aggregation_data.go new file mode 100644 index 00000000..d500e67f --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/aggregation_data.go @@ -0,0 +1,293 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "math" + "time" + + "go.opencensus.io/metric/metricdata" +) + +// AggregationData represents an aggregated value from a collection. +// They are reported on the view data during exporting. +// Mosts users won't directly access aggregration data. +type AggregationData interface { + isAggregationData() bool + addSample(v float64, attachments map[string]interface{}, t time.Time) + clone() AggregationData + equal(other AggregationData) bool + toPoint(t metricdata.Type, time time.Time) metricdata.Point +} + +const epsilon = 1e-9 + +// CountData is the aggregated data for the Count aggregation. +// A count aggregation processes data and counts the recordings. +// +// Most users won't directly access count data. +type CountData struct { + Value int64 +} + +func (a *CountData) isAggregationData() bool { return true } + +func (a *CountData) addSample(_ float64, _ map[string]interface{}, _ time.Time) { + a.Value = a.Value + 1 +} + +func (a *CountData) clone() AggregationData { + return &CountData{Value: a.Value} +} + +func (a *CountData) equal(other AggregationData) bool { + a2, ok := other.(*CountData) + if !ok { + return false + } + + return a.Value == a2.Value +} + +func (a *CountData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeInt64: + return metricdata.NewInt64Point(t, a.Value) + default: + panic("unsupported metricdata.Type") + } +} + +// SumData is the aggregated data for the Sum aggregation. +// A sum aggregation processes data and sums up the recordings. +// +// Most users won't directly access sum data. +type SumData struct { + Value float64 +} + +func (a *SumData) isAggregationData() bool { return true } + +func (a *SumData) addSample(v float64, _ map[string]interface{}, _ time.Time) { + a.Value += v +} + +func (a *SumData) clone() AggregationData { + return &SumData{Value: a.Value} +} + +func (a *SumData) equal(other AggregationData) bool { + a2, ok := other.(*SumData) + if !ok { + return false + } + return math.Pow(a.Value-a2.Value, 2) < epsilon +} + +func (a *SumData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeInt64: + return metricdata.NewInt64Point(t, int64(a.Value)) + case metricdata.TypeCumulativeFloat64: + return metricdata.NewFloat64Point(t, a.Value) + default: + panic("unsupported metricdata.Type") + } +} + +// DistributionData is the aggregated data for the +// Distribution aggregation. +// +// Most users won't directly access distribution data. +// +// For a distribution with N bounds, the associated DistributionData will have +// N+1 buckets. +type DistributionData struct { + Count int64 // number of data points aggregated + Min float64 // minimum value in the distribution + Max float64 // max value in the distribution + Mean float64 // mean of the distribution + SumOfSquaredDev float64 // sum of the squared deviation from the mean + CountPerBucket []int64 // number of occurrences per bucket + // ExemplarsPerBucket is slice the same length as CountPerBucket containing + // an exemplar for the associated bucket, or nil. + ExemplarsPerBucket []*metricdata.Exemplar + bounds []float64 // histogram distribution of the values +} + +func newDistributionData(bounds []float64) *DistributionData { + bucketCount := len(bounds) + 1 + return &DistributionData{ + CountPerBucket: make([]int64, bucketCount), + ExemplarsPerBucket: make([]*metricdata.Exemplar, bucketCount), + bounds: bounds, + Min: math.MaxFloat64, + Max: math.SmallestNonzeroFloat64, + } +} + +// Sum returns the sum of all samples collected. +func (a *DistributionData) Sum() float64 { return a.Mean * float64(a.Count) } + +func (a *DistributionData) variance() float64 { + if a.Count <= 1 { + return 0 + } + return a.SumOfSquaredDev / float64(a.Count-1) +} + +func (a *DistributionData) isAggregationData() bool { return true } + +// TODO(songy23): support exemplar attachments. +func (a *DistributionData) addSample(v float64, attachments map[string]interface{}, t time.Time) { + if v < a.Min { + a.Min = v + } + if v > a.Max { + a.Max = v + } + a.Count++ + a.addToBucket(v, attachments, t) + + if a.Count == 1 { + a.Mean = v + return + } + + oldMean := a.Mean + a.Mean = a.Mean + (v-a.Mean)/float64(a.Count) + a.SumOfSquaredDev = a.SumOfSquaredDev + (v-oldMean)*(v-a.Mean) +} + +func (a *DistributionData) addToBucket(v float64, attachments map[string]interface{}, t time.Time) { + var count *int64 + var i int + var b float64 + for i, b = range a.bounds { + if v < b { + count = &a.CountPerBucket[i] + break + } + } + if count == nil { // Last bucket. + i = len(a.bounds) + count = &a.CountPerBucket[i] + } + *count++ + if exemplar := getExemplar(v, attachments, t); exemplar != nil { + a.ExemplarsPerBucket[i] = exemplar + } +} + +func getExemplar(v float64, attachments map[string]interface{}, t time.Time) *metricdata.Exemplar { + if len(attachments) == 0 { + return nil + } + return &metricdata.Exemplar{ + Value: v, + Timestamp: t, + Attachments: attachments, + } +} + +func (a *DistributionData) clone() AggregationData { + c := *a + c.CountPerBucket = append([]int64(nil), a.CountPerBucket...) + c.ExemplarsPerBucket = append([]*metricdata.Exemplar(nil), a.ExemplarsPerBucket...) + return &c +} + +func (a *DistributionData) equal(other AggregationData) bool { + a2, ok := other.(*DistributionData) + if !ok { + return false + } + if a2 == nil { + return false + } + if len(a.CountPerBucket) != len(a2.CountPerBucket) { + return false + } + for i := range a.CountPerBucket { + if a.CountPerBucket[i] != a2.CountPerBucket[i] { + return false + } + } + return a.Count == a2.Count && a.Min == a2.Min && a.Max == a2.Max && math.Pow(a.Mean-a2.Mean, 2) < epsilon && math.Pow(a.variance()-a2.variance(), 2) < epsilon +} + +func (a *DistributionData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeCumulativeDistribution: + buckets := []metricdata.Bucket{} + for i := 0; i < len(a.CountPerBucket); i++ { + buckets = append(buckets, metricdata.Bucket{ + Count: a.CountPerBucket[i], + Exemplar: a.ExemplarsPerBucket[i], + }) + } + bucketOptions := &metricdata.BucketOptions{Bounds: a.bounds} + + val := &metricdata.Distribution{ + Count: a.Count, + Sum: a.Sum(), + SumOfSquaredDeviation: a.SumOfSquaredDev, + BucketOptions: bucketOptions, + Buckets: buckets, + } + return metricdata.NewDistributionPoint(t, val) + + default: + // TODO: [rghetia] when we have a use case for TypeGaugeDistribution. + panic("unsupported metricdata.Type") + } +} + +// LastValueData returns the last value recorded for LastValue aggregation. +type LastValueData struct { + Value float64 +} + +func (l *LastValueData) isAggregationData() bool { + return true +} + +func (l *LastValueData) addSample(v float64, _ map[string]interface{}, _ time.Time) { + l.Value = v +} + +func (l *LastValueData) clone() AggregationData { + return &LastValueData{l.Value} +} + +func (l *LastValueData) equal(other AggregationData) bool { + a2, ok := other.(*LastValueData) + if !ok { + return false + } + return l.Value == a2.Value +} + +func (l *LastValueData) toPoint(metricType metricdata.Type, t time.Time) metricdata.Point { + switch metricType { + case metricdata.TypeGaugeInt64: + return metricdata.NewInt64Point(t, int64(l.Value)) + case metricdata.TypeGaugeFloat64: + return metricdata.NewFloat64Point(t, l.Value) + default: + panic("unsupported metricdata.Type") + } +} diff --git a/vendor/go.opencensus.io/stats/view/collector.go b/vendor/go.opencensus.io/stats/view/collector.go new file mode 100644 index 00000000..8a6a2c0f --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/collector.go @@ -0,0 +1,86 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "sort" + "time" + + "go.opencensus.io/internal/tagencoding" + "go.opencensus.io/tag" +) + +type collector struct { + // signatures holds the aggregations values for each unique tag signature + // (values for all keys) to its aggregator. + signatures map[string]AggregationData + // Aggregation is the description of the aggregation to perform for this + // view. + a *Aggregation +} + +func (c *collector) addSample(s string, v float64, attachments map[string]interface{}, t time.Time) { + aggregator, ok := c.signatures[s] + if !ok { + aggregator = c.a.newData() + c.signatures[s] = aggregator + } + aggregator.addSample(v, attachments, t) +} + +// collectRows returns a snapshot of the collected Row values. +func (c *collector) collectedRows(keys []tag.Key) []*Row { + rows := make([]*Row, 0, len(c.signatures)) + for sig, aggregator := range c.signatures { + tags := decodeTags([]byte(sig), keys) + row := &Row{Tags: tags, Data: aggregator.clone()} + rows = append(rows, row) + } + return rows +} + +func (c *collector) clearRows() { + c.signatures = make(map[string]AggregationData) +} + +// encodeWithKeys encodes the map by using values +// only associated with the keys provided. +func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte { + vb := &tagencoding.Values{ + Buffer: make([]byte, len(keys)), + } + for _, k := range keys { + v, _ := m.Value(k) + vb.WriteValue([]byte(v)) + } + return vb.Bytes() +} + +// decodeTags decodes tags from the buffer and +// orders them by the keys. +func decodeTags(buf []byte, keys []tag.Key) []tag.Tag { + vb := &tagencoding.Values{Buffer: buf} + var tags []tag.Tag + for _, k := range keys { + v := vb.ReadValue() + if v != nil { + tags = append(tags, tag.Tag{Key: k, Value: string(v)}) + } + } + vb.ReadIndex = 0 + sort.Slice(tags, func(i, j int) bool { return tags[i].Key.Name() < tags[j].Key.Name() }) + return tags +} diff --git a/vendor/go.opencensus.io/stats/view/doc.go b/vendor/go.opencensus.io/stats/view/doc.go new file mode 100644 index 00000000..dced225c --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/doc.go @@ -0,0 +1,47 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package view contains support for collecting and exposing aggregates over stats. +// +// In order to collect measurements, views need to be defined and registered. +// A view allows recorded measurements to be filtered and aggregated. +// +// All recorded measurements can be grouped by a list of tags. +// +// OpenCensus provides several aggregation methods: Count, Distribution and Sum. +// +// Count only counts the number of measurement points recorded. +// Distribution provides statistical summary of the aggregated data by counting +// how many recorded measurements fall into each bucket. +// Sum adds up the measurement values. +// LastValue just keeps track of the most recently recorded measurement value. +// All aggregations are cumulative. +// +// Views can be registerd and unregistered at any time during program execution. +// +// Libraries can define views but it is recommended that in most cases registering +// views be left up to applications. +// +// Exporting +// +// Collected and aggregated data can be exported to a metric collection +// backend by registering its exporter. +// +// Multiple exporters can be registered to upload the data to various +// different back ends. +package view // import "go.opencensus.io/stats/view" + +// TODO(acetechnologist): Add a link to the language independent OpenCensus +// spec when it is available. diff --git a/vendor/go.opencensus.io/stats/view/export.go b/vendor/go.opencensus.io/stats/view/export.go new file mode 100644 index 00000000..7cb59718 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/export.go @@ -0,0 +1,58 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package view + +import "sync" + +var ( + exportersMu sync.RWMutex // guards exporters + exporters = make(map[Exporter]struct{}) +) + +// Exporter exports the collected records as view data. +// +// The ExportView method should return quickly; if an +// Exporter takes a significant amount of time to +// process a Data, that work should be done on another goroutine. +// +// It is safe to assume that ExportView will not be called concurrently from +// multiple goroutines. +// +// The Data should not be modified. +type Exporter interface { + ExportView(viewData *Data) +} + +// RegisterExporter registers an exporter. +// Collected data will be reported via all the +// registered exporters. Once you no longer +// want data to be exported, invoke UnregisterExporter +// with the previously registered exporter. +// +// Binaries can register exporters, libraries shouldn't register exporters. +func RegisterExporter(e Exporter) { + exportersMu.Lock() + defer exportersMu.Unlock() + + exporters[e] = struct{}{} +} + +// UnregisterExporter unregisters an exporter. +func UnregisterExporter(e Exporter) { + exportersMu.Lock() + defer exportersMu.Unlock() + + delete(exporters, e) +} diff --git a/vendor/go.opencensus.io/stats/view/view.go b/vendor/go.opencensus.io/stats/view/view.go new file mode 100644 index 00000000..37f88e1d --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/view.go @@ -0,0 +1,221 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "sort" + "sync/atomic" + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats" + "go.opencensus.io/tag" +) + +// View allows users to aggregate the recorded stats.Measurements. +// Views need to be passed to the Register function to be before data will be +// collected and sent to Exporters. +type View struct { + Name string // Name of View. Must be unique. If unset, will default to the name of the Measure. + Description string // Description is a human-readable description for this view. + + // TagKeys are the tag keys describing the grouping of this view. + // A single Row will be produced for each combination of associated tag values. + TagKeys []tag.Key + + // Measure is a stats.Measure to aggregate in this view. + Measure stats.Measure + + // Aggregation is the aggregation function tp apply to the set of Measurements. + Aggregation *Aggregation +} + +// WithName returns a copy of the View with a new name. This is useful for +// renaming views to cope with limitations placed on metric names by various +// backends. +func (v *View) WithName(name string) *View { + vNew := *v + vNew.Name = name + return &vNew +} + +// same compares two views and returns true if they represent the same aggregation. +func (v *View) same(other *View) bool { + if v == other { + return true + } + if v == nil { + return false + } + return reflect.DeepEqual(v.Aggregation, other.Aggregation) && + v.Measure.Name() == other.Measure.Name() +} + +// ErrNegativeBucketBounds error returned if histogram contains negative bounds. +// +// Deprecated: this should not be public. +var ErrNegativeBucketBounds = errors.New("negative bucket bounds not supported") + +// canonicalize canonicalizes v by setting explicit +// defaults for Name and Description and sorting the TagKeys +func (v *View) canonicalize() error { + if v.Measure == nil { + return fmt.Errorf("cannot register view %q: measure not set", v.Name) + } + if v.Aggregation == nil { + return fmt.Errorf("cannot register view %q: aggregation not set", v.Name) + } + if v.Name == "" { + v.Name = v.Measure.Name() + } + if v.Description == "" { + v.Description = v.Measure.Description() + } + if err := checkViewName(v.Name); err != nil { + return err + } + sort.Slice(v.TagKeys, func(i, j int) bool { + return v.TagKeys[i].Name() < v.TagKeys[j].Name() + }) + sort.Float64s(v.Aggregation.Buckets) + for _, b := range v.Aggregation.Buckets { + if b < 0 { + return ErrNegativeBucketBounds + } + } + // drop 0 bucket silently. + v.Aggregation.Buckets = dropZeroBounds(v.Aggregation.Buckets...) + + return nil +} + +func dropZeroBounds(bounds ...float64) []float64 { + for i, bound := range bounds { + if bound > 0 { + return bounds[i:] + } + } + return []float64{} +} + +// viewInternal is the internal representation of a View. +type viewInternal struct { + view *View // view is the canonicalized View definition associated with this view. + subscribed uint32 // 1 if someone is subscribed and data need to be exported, use atomic to access + collector *collector + metricDescriptor *metricdata.Descriptor +} + +func newViewInternal(v *View) (*viewInternal, error) { + return &viewInternal{ + view: v, + collector: &collector{make(map[string]AggregationData), v.Aggregation}, + metricDescriptor: viewToMetricDescriptor(v), + }, nil +} + +func (v *viewInternal) subscribe() { + atomic.StoreUint32(&v.subscribed, 1) +} + +func (v *viewInternal) unsubscribe() { + atomic.StoreUint32(&v.subscribed, 0) +} + +// isSubscribed returns true if the view is exporting +// data by subscription. +func (v *viewInternal) isSubscribed() bool { + return atomic.LoadUint32(&v.subscribed) == 1 +} + +func (v *viewInternal) clearRows() { + v.collector.clearRows() +} + +func (v *viewInternal) collectedRows() []*Row { + return v.collector.collectedRows(v.view.TagKeys) +} + +func (v *viewInternal) addSample(m *tag.Map, val float64, attachments map[string]interface{}, t time.Time) { + if !v.isSubscribed() { + return + } + sig := string(encodeWithKeys(m, v.view.TagKeys)) + v.collector.addSample(sig, val, attachments, t) +} + +// A Data is a set of rows about usage of the single measure associated +// with the given view. Each row is specific to a unique set of tags. +type Data struct { + View *View + Start, End time.Time + Rows []*Row +} + +// Row is the collected value for a specific set of key value pairs a.k.a tags. +type Row struct { + Tags []tag.Tag + Data AggregationData +} + +func (r *Row) String() string { + var buffer bytes.Buffer + buffer.WriteString("{ ") + buffer.WriteString("{ ") + for _, t := range r.Tags { + buffer.WriteString(fmt.Sprintf("{%v %v}", t.Key.Name(), t.Value)) + } + buffer.WriteString(" }") + buffer.WriteString(fmt.Sprintf("%v", r.Data)) + buffer.WriteString(" }") + return buffer.String() +} + +// Equal returns true if both rows are equal. Tags are expected to be ordered +// by the key name. Even both rows have the same tags but the tags appear in +// different orders it will return false. +func (r *Row) Equal(other *Row) bool { + if r == other { + return true + } + return reflect.DeepEqual(r.Tags, other.Tags) && r.Data.equal(other.Data) +} + +const maxNameLength = 255 + +// Returns true if the given string contains only printable characters. +func isPrintable(str string) bool { + for _, r := range str { + if !(r >= ' ' && r <= '~') { + return false + } + } + return true +} + +func checkViewName(name string) error { + if len(name) > maxNameLength { + return fmt.Errorf("view name cannot be larger than %v", maxNameLength) + } + if !isPrintable(name) { + return fmt.Errorf("view name needs to be an ASCII string") + } + return nil +} diff --git a/vendor/go.opencensus.io/stats/view/view_to_metric.go b/vendor/go.opencensus.io/stats/view/view_to_metric.go new file mode 100644 index 00000000..f67b5c46 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/view_to_metric.go @@ -0,0 +1,140 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/stats" +) + +func getUnit(unit string) metricdata.Unit { + switch unit { + case "1": + return metricdata.UnitDimensionless + case "ms": + return metricdata.UnitMilliseconds + case "By": + return metricdata.UnitBytes + } + return metricdata.UnitDimensionless +} + +func getType(v *View) metricdata.Type { + m := v.Measure + agg := v.Aggregation + + switch agg.Type { + case AggTypeSum: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeCumulativeInt64 + case *stats.Float64Measure: + return metricdata.TypeCumulativeFloat64 + default: + panic("unexpected measure type") + } + case AggTypeDistribution: + return metricdata.TypeCumulativeDistribution + case AggTypeLastValue: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeGaugeInt64 + case *stats.Float64Measure: + return metricdata.TypeGaugeFloat64 + default: + panic("unexpected measure type") + } + case AggTypeCount: + switch m.(type) { + case *stats.Int64Measure: + return metricdata.TypeCumulativeInt64 + case *stats.Float64Measure: + return metricdata.TypeCumulativeInt64 + default: + panic("unexpected measure type") + } + default: + panic("unexpected aggregation type") + } +} + +func getLabelKeys(v *View) []metricdata.LabelKey { + labelKeys := []metricdata.LabelKey{} + for _, k := range v.TagKeys { + labelKeys = append(labelKeys, metricdata.LabelKey{Key: k.Name()}) + } + return labelKeys +} + +func viewToMetricDescriptor(v *View) *metricdata.Descriptor { + return &metricdata.Descriptor{ + Name: v.Name, + Description: v.Description, + Unit: getUnit(v.Measure.Unit()), + Type: getType(v), + LabelKeys: getLabelKeys(v), + } +} + +func toLabelValues(row *Row, expectedKeys []metricdata.LabelKey) []metricdata.LabelValue { + labelValues := []metricdata.LabelValue{} + tagMap := make(map[string]string) + for _, tag := range row.Tags { + tagMap[tag.Key.Name()] = tag.Value + } + + for _, key := range expectedKeys { + if val, ok := tagMap[key.Key]; ok { + labelValues = append(labelValues, metricdata.NewLabelValue(val)) + } else { + labelValues = append(labelValues, metricdata.LabelValue{}) + } + } + return labelValues +} + +func rowToTimeseries(v *viewInternal, row *Row, now time.Time, startTime time.Time) *metricdata.TimeSeries { + return &metricdata.TimeSeries{ + Points: []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)}, + LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys), + StartTime: startTime, + } +} + +func viewToMetric(v *viewInternal, now time.Time, startTime time.Time) *metricdata.Metric { + if v.metricDescriptor.Type == metricdata.TypeGaugeInt64 || + v.metricDescriptor.Type == metricdata.TypeGaugeFloat64 { + startTime = time.Time{} + } + + rows := v.collectedRows() + if len(rows) == 0 { + return nil + } + + ts := []*metricdata.TimeSeries{} + for _, row := range rows { + ts = append(ts, rowToTimeseries(v, row, now, startTime)) + } + + m := &metricdata.Metric{ + Descriptor: *v.metricDescriptor, + TimeSeries: ts, + } + return m +} diff --git a/vendor/go.opencensus.io/stats/view/worker.go b/vendor/go.opencensus.io/stats/view/worker.go new file mode 100644 index 00000000..2f3c018a --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/worker.go @@ -0,0 +1,281 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "fmt" + "sync" + "time" + + "go.opencensus.io/metric/metricdata" + "go.opencensus.io/metric/metricproducer" + "go.opencensus.io/stats" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +func init() { + defaultWorker = newWorker() + go defaultWorker.start() + internal.DefaultRecorder = record +} + +type measureRef struct { + measure string + views map[*viewInternal]struct{} +} + +type worker struct { + measures map[string]*measureRef + views map[string]*viewInternal + startTimes map[*viewInternal]time.Time + + timer *time.Ticker + c chan command + quit, done chan bool + mu sync.RWMutex +} + +var defaultWorker *worker + +var defaultReportingDuration = 10 * time.Second + +// Find returns a registered view associated with this name. +// If no registered view is found, nil is returned. +func Find(name string) (v *View) { + req := &getViewByNameReq{ + name: name, + c: make(chan *getViewByNameResp), + } + defaultWorker.c <- req + resp := <-req.c + return resp.v +} + +// Register begins collecting data for the given views. +// Once a view is registered, it reports data to the registered exporters. +func Register(views ...*View) error { + req := ®isterViewReq{ + views: views, + err: make(chan error), + } + defaultWorker.c <- req + return <-req.err +} + +// Unregister the given views. Data will not longer be exported for these views +// after Unregister returns. +// It is not necessary to unregister from views you expect to collect for the +// duration of your program execution. +func Unregister(views ...*View) { + names := make([]string, len(views)) + for i := range views { + names[i] = views[i].Name + } + req := &unregisterFromViewReq{ + views: names, + done: make(chan struct{}), + } + defaultWorker.c <- req + <-req.done +} + +// RetrieveData gets a snapshot of the data collected for the the view registered +// with the given name. It is intended for testing only. +func RetrieveData(viewName string) ([]*Row, error) { + req := &retrieveDataReq{ + now: time.Now(), + v: viewName, + c: make(chan *retrieveDataResp), + } + defaultWorker.c <- req + resp := <-req.c + return resp.rows, resp.err +} + +func record(tags *tag.Map, ms interface{}, attachments map[string]interface{}) { + req := &recordReq{ + tm: tags, + ms: ms.([]stats.Measurement), + attachments: attachments, + t: time.Now(), + } + defaultWorker.c <- req +} + +// SetReportingPeriod sets the interval between reporting aggregated views in +// the program. If duration is less than or equal to zero, it enables the +// default behavior. +// +// Note: each exporter makes different promises about what the lowest supported +// duration is. For example, the Stackdriver exporter recommends a value no +// lower than 1 minute. Consult each exporter per your needs. +func SetReportingPeriod(d time.Duration) { + // TODO(acetechnologist): ensure that the duration d is more than a certain + // value. e.g. 1s + req := &setReportingPeriodReq{ + d: d, + c: make(chan bool), + } + defaultWorker.c <- req + <-req.c // don't return until the timer is set to the new duration. +} + +func newWorker() *worker { + return &worker{ + measures: make(map[string]*measureRef), + views: make(map[string]*viewInternal), + startTimes: make(map[*viewInternal]time.Time), + timer: time.NewTicker(defaultReportingDuration), + c: make(chan command, 1024), + quit: make(chan bool), + done: make(chan bool), + } +} + +func (w *worker) start() { + prodMgr := metricproducer.GlobalManager() + prodMgr.AddProducer(w) + + for { + select { + case cmd := <-w.c: + cmd.handleCommand(w) + case <-w.timer.C: + w.reportUsage(time.Now()) + case <-w.quit: + w.timer.Stop() + close(w.c) + w.done <- true + return + } + } +} + +func (w *worker) stop() { + prodMgr := metricproducer.GlobalManager() + prodMgr.DeleteProducer(w) + + w.quit <- true + <-w.done +} + +func (w *worker) getMeasureRef(name string) *measureRef { + if mr, ok := w.measures[name]; ok { + return mr + } + mr := &measureRef{ + measure: name, + views: make(map[*viewInternal]struct{}), + } + w.measures[name] = mr + return mr +} + +func (w *worker) tryRegisterView(v *View) (*viewInternal, error) { + w.mu.Lock() + defer w.mu.Unlock() + vi, err := newViewInternal(v) + if err != nil { + return nil, err + } + if x, ok := w.views[vi.view.Name]; ok { + if !x.view.same(vi.view) { + return nil, fmt.Errorf("cannot register view %q; a different view with the same name is already registered", v.Name) + } + + // the view is already registered so there is nothing to do and the + // command is considered successful. + return x, nil + } + w.views[vi.view.Name] = vi + ref := w.getMeasureRef(vi.view.Measure.Name()) + ref.views[vi] = struct{}{} + return vi, nil +} + +func (w *worker) unregisterView(viewName string) { + w.mu.Lock() + defer w.mu.Unlock() + delete(w.views, viewName) +} + +func (w *worker) reportView(v *viewInternal, now time.Time) { + if !v.isSubscribed() { + return + } + rows := v.collectedRows() + _, ok := w.startTimes[v] + if !ok { + w.startTimes[v] = now + } + viewData := &Data{ + View: v.view, + Start: w.startTimes[v], + End: time.Now(), + Rows: rows, + } + exportersMu.Lock() + for e := range exporters { + e.ExportView(viewData) + } + exportersMu.Unlock() +} + +func (w *worker) reportUsage(now time.Time) { + w.mu.Lock() + defer w.mu.Unlock() + for _, v := range w.views { + w.reportView(v, now) + } +} + +func (w *worker) toMetric(v *viewInternal, now time.Time) *metricdata.Metric { + if !v.isSubscribed() { + return nil + } + + _, ok := w.startTimes[v] + if !ok { + w.startTimes[v] = now + } + + var startTime time.Time + if v.metricDescriptor.Type == metricdata.TypeGaugeInt64 || + v.metricDescriptor.Type == metricdata.TypeGaugeFloat64 { + startTime = time.Time{} + } else { + startTime = w.startTimes[v] + } + + return viewToMetric(v, now, startTime) +} + +// Read reads all view data and returns them as metrics. +// It is typically invoked by metric reader to export stats in metric format. +func (w *worker) Read() []*metricdata.Metric { + w.mu.Lock() + defer w.mu.Unlock() + now := time.Now() + metrics := make([]*metricdata.Metric, 0, len(w.views)) + for _, v := range w.views { + metric := w.toMetric(v, now) + if metric != nil { + metrics = append(metrics, metric) + } + } + return metrics +} diff --git a/vendor/go.opencensus.io/stats/view/worker_commands.go b/vendor/go.opencensus.io/stats/view/worker_commands.go new file mode 100644 index 00000000..0267e179 --- /dev/null +++ b/vendor/go.opencensus.io/stats/view/worker_commands.go @@ -0,0 +1,186 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package view + +import ( + "errors" + "fmt" + "strings" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/stats/internal" + "go.opencensus.io/tag" +) + +type command interface { + handleCommand(w *worker) +} + +// getViewByNameReq is the command to get a view given its name. +type getViewByNameReq struct { + name string + c chan *getViewByNameResp +} + +type getViewByNameResp struct { + v *View +} + +func (cmd *getViewByNameReq) handleCommand(w *worker) { + v := w.views[cmd.name] + if v == nil { + cmd.c <- &getViewByNameResp{nil} + return + } + cmd.c <- &getViewByNameResp{v.view} +} + +// registerViewReq is the command to register a view. +type registerViewReq struct { + views []*View + err chan error +} + +func (cmd *registerViewReq) handleCommand(w *worker) { + for _, v := range cmd.views { + if err := v.canonicalize(); err != nil { + cmd.err <- err + return + } + } + var errstr []string + for _, view := range cmd.views { + vi, err := w.tryRegisterView(view) + if err != nil { + errstr = append(errstr, fmt.Sprintf("%s: %v", view.Name, err)) + continue + } + internal.SubscriptionReporter(view.Measure.Name()) + vi.subscribe() + } + if len(errstr) > 0 { + cmd.err <- errors.New(strings.Join(errstr, "\n")) + } else { + cmd.err <- nil + } +} + +// unregisterFromViewReq is the command to unregister to a view. Has no +// impact on the data collection for client that are pulling data from the +// library. +type unregisterFromViewReq struct { + views []string + done chan struct{} +} + +func (cmd *unregisterFromViewReq) handleCommand(w *worker) { + for _, name := range cmd.views { + vi, ok := w.views[name] + if !ok { + continue + } + + // Report pending data for this view before removing it. + w.reportView(vi, time.Now()) + + vi.unsubscribe() + if !vi.isSubscribed() { + // this was the last subscription and view is not collecting anymore. + // The collected data can be cleared. + vi.clearRows() + } + w.unregisterView(name) + } + cmd.done <- struct{}{} +} + +// retrieveDataReq is the command to retrieve data for a view. +type retrieveDataReq struct { + now time.Time + v string + c chan *retrieveDataResp +} + +type retrieveDataResp struct { + rows []*Row + err error +} + +func (cmd *retrieveDataReq) handleCommand(w *worker) { + w.mu.Lock() + defer w.mu.Unlock() + vi, ok := w.views[cmd.v] + if !ok { + cmd.c <- &retrieveDataResp{ + nil, + fmt.Errorf("cannot retrieve data; view %q is not registered", cmd.v), + } + return + } + + if !vi.isSubscribed() { + cmd.c <- &retrieveDataResp{ + nil, + fmt.Errorf("cannot retrieve data; view %q has no subscriptions or collection is not forcibly started", cmd.v), + } + return + } + cmd.c <- &retrieveDataResp{ + vi.collectedRows(), + nil, + } +} + +// recordReq is the command to record data related to multiple measures +// at once. +type recordReq struct { + tm *tag.Map + ms []stats.Measurement + attachments map[string]interface{} + t time.Time +} + +func (cmd *recordReq) handleCommand(w *worker) { + w.mu.Lock() + defer w.mu.Unlock() + for _, m := range cmd.ms { + if (m == stats.Measurement{}) { // not registered + continue + } + ref := w.getMeasureRef(m.Measure().Name()) + for v := range ref.views { + v.addSample(cmd.tm, m.Value(), cmd.attachments, time.Now()) + } + } +} + +// setReportingPeriodReq is the command to modify the duration between +// reporting the collected data to the registered clients. +type setReportingPeriodReq struct { + d time.Duration + c chan bool +} + +func (cmd *setReportingPeriodReq) handleCommand(w *worker) { + w.timer.Stop() + if cmd.d <= 0 { + w.timer = time.NewTicker(defaultReportingDuration) + } else { + w.timer = time.NewTicker(cmd.d) + } + cmd.c <- true +} diff --git a/vendor/go.opencensus.io/tag/context.go b/vendor/go.opencensus.io/tag/context.go new file mode 100644 index 00000000..b27d1b26 --- /dev/null +++ b/vendor/go.opencensus.io/tag/context.go @@ -0,0 +1,43 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "context" +) + +// FromContext returns the tag map stored in the context. +func FromContext(ctx context.Context) *Map { + // The returned tag map shouldn't be mutated. + ts := ctx.Value(mapCtxKey) + if ts == nil { + return nil + } + return ts.(*Map) +} + +// NewContext creates a new context with the given tag map. +// To propagate a tag map to downstream methods and downstream RPCs, add a tag map +// to the current context. NewContext will return a copy of the current context, +// and put the tag map into the returned one. +// If there is already a tag map in the current context, it will be replaced with m. +func NewContext(ctx context.Context, m *Map) context.Context { + return context.WithValue(ctx, mapCtxKey, m) +} + +type ctxKey struct{} + +var mapCtxKey = ctxKey{} diff --git a/vendor/go.opencensus.io/tag/doc.go b/vendor/go.opencensus.io/tag/doc.go new file mode 100644 index 00000000..da16b74e --- /dev/null +++ b/vendor/go.opencensus.io/tag/doc.go @@ -0,0 +1,26 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/* +Package tag contains OpenCensus tags. + +Tags are key-value pairs. Tags provide additional cardinality to +the OpenCensus instrumentation data. + +Tags can be propagated on the wire and in the same +process via context.Context. Encode and Decode should be +used to represent tags into their binary propagation form. +*/ +package tag // import "go.opencensus.io/tag" diff --git a/vendor/go.opencensus.io/tag/key.go b/vendor/go.opencensus.io/tag/key.go new file mode 100644 index 00000000..4e63d08c --- /dev/null +++ b/vendor/go.opencensus.io/tag/key.go @@ -0,0 +1,45 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +// Key represents a tag key. +type Key struct { + name string +} + +// NewKey creates or retrieves a string key identified by name. +// Calling NewKey consequently with the same name returns the same key. +func NewKey(name string) (Key, error) { + if !checkKeyName(name) { + return Key{}, errInvalidKeyName + } + return Key{name: name}, nil +} + +// MustNewKey creates or retrieves a string key identified by name. +// An invalid key name raises a panic. +func MustNewKey(name string) Key { + k, err := NewKey(name) + if err != nil { + panic(err) + } + return k +} + +// Name returns the name of the key. +func (k Key) Name() string { + return k.name +} diff --git a/vendor/go.opencensus.io/tag/map.go b/vendor/go.opencensus.io/tag/map.go new file mode 100644 index 00000000..0272ef85 --- /dev/null +++ b/vendor/go.opencensus.io/tag/map.go @@ -0,0 +1,229 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "bytes" + "context" + "fmt" + "sort" +) + +// Tag is a key value pair that can be propagated on wire. +type Tag struct { + Key Key + Value string +} + +type tagContent struct { + value string + m metadatas +} + +// Map is a map of tags. Use New to create a context containing +// a new Map. +type Map struct { + m map[Key]tagContent +} + +// Value returns the value for the key if a value for the key exists. +func (m *Map) Value(k Key) (string, bool) { + if m == nil { + return "", false + } + v, ok := m.m[k] + return v.value, ok +} + +func (m *Map) String() string { + if m == nil { + return "nil" + } + keys := make([]Key, 0, len(m.m)) + for k := range m.m { + keys = append(keys, k) + } + sort.Slice(keys, func(i, j int) bool { return keys[i].Name() < keys[j].Name() }) + + var buffer bytes.Buffer + buffer.WriteString("{ ") + for _, k := range keys { + buffer.WriteString(fmt.Sprintf("{%v %v}", k.name, m.m[k])) + } + buffer.WriteString(" }") + return buffer.String() +} + +func (m *Map) insert(k Key, v string, md metadatas) { + if _, ok := m.m[k]; ok { + return + } + m.m[k] = tagContent{value: v, m: md} +} + +func (m *Map) update(k Key, v string, md metadatas) { + if _, ok := m.m[k]; ok { + m.m[k] = tagContent{value: v, m: md} + } +} + +func (m *Map) upsert(k Key, v string, md metadatas) { + m.m[k] = tagContent{value: v, m: md} +} + +func (m *Map) delete(k Key) { + delete(m.m, k) +} + +func newMap() *Map { + return &Map{m: make(map[Key]tagContent)} +} + +// Mutator modifies a tag map. +type Mutator interface { + Mutate(t *Map) (*Map, error) +} + +// Insert returns a mutator that inserts a +// value associated with k. If k already exists in the tag map, +// mutator doesn't update the value. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Insert(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.insert(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +// Update returns a mutator that updates the +// value of the tag associated with k with v. If k doesn't +// exists in the tag map, the mutator doesn't insert the value. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Update(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.update(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +// Upsert returns a mutator that upserts the +// value of the tag associated with k with v. It inserts the +// value if k doesn't exist already. It mutates the value +// if k already exists. +// Metadata applies metadata to the tag. It is optional. +// Metadatas are applied in the order in which it is provided. +// If more than one metadata updates the same attribute then +// the update from the last metadata prevails. +func Upsert(k Key, v string, mds ...Metadata) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + if !checkValue(v) { + return nil, errInvalidValue + } + m.upsert(k, v, createMetadatas(mds...)) + return m, nil + }, + } +} + +func createMetadatas(mds ...Metadata) metadatas { + var metas metadatas + if len(mds) > 0 { + for _, md := range mds { + if md != nil { + md(&metas) + } + } + } else { + WithTTL(TTLUnlimitedPropagation)(&metas) + } + return metas + +} + +// Delete returns a mutator that deletes +// the value associated with k. +func Delete(k Key) Mutator { + return &mutator{ + fn: func(m *Map) (*Map, error) { + m.delete(k) + return m, nil + }, + } +} + +// New returns a new context that contains a tag map +// originated from the incoming context and modified +// with the provided mutators. +func New(ctx context.Context, mutator ...Mutator) (context.Context, error) { + m := newMap() + orig := FromContext(ctx) + if orig != nil { + for k, v := range orig.m { + if !checkKeyName(k.Name()) { + return ctx, fmt.Errorf("key:%q: %v", k, errInvalidKeyName) + } + if !checkValue(v.value) { + return ctx, fmt.Errorf("key:%q value:%q: %v", k.Name(), v, errInvalidValue) + } + m.insert(k, v.value, v.m) + } + } + var err error + for _, mod := range mutator { + m, err = mod.Mutate(m) + if err != nil { + return ctx, err + } + } + return NewContext(ctx, m), nil +} + +// Do is similar to pprof.Do: a convenience for installing the tags +// from the context as Go profiler labels. This allows you to +// correlated runtime profiling with stats. +// +// It converts the key/values from the given map to Go profiler labels +// and calls pprof.Do. +// +// Do is going to do nothing if your Go version is below 1.9. +func Do(ctx context.Context, f func(ctx context.Context)) { + do(ctx, f) +} + +type mutator struct { + fn func(t *Map) (*Map, error) +} + +func (m *mutator) Mutate(t *Map) (*Map, error) { + return m.fn(t) +} diff --git a/vendor/go.opencensus.io/tag/map_codec.go b/vendor/go.opencensus.io/tag/map_codec.go new file mode 100644 index 00000000..f8b58276 --- /dev/null +++ b/vendor/go.opencensus.io/tag/map_codec.go @@ -0,0 +1,239 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +import ( + "encoding/binary" + "fmt" +) + +// KeyType defines the types of keys allowed. Currently only keyTypeString is +// supported. +type keyType byte + +const ( + keyTypeString keyType = iota + keyTypeInt64 + keyTypeTrue + keyTypeFalse + + tagsVersionID = byte(0) +) + +type encoderGRPC struct { + buf []byte + writeIdx, readIdx int +} + +// writeKeyString writes the fieldID '0' followed by the key string and value +// string. +func (eg *encoderGRPC) writeTagString(k, v string) { + eg.writeByte(byte(keyTypeString)) + eg.writeStringWithVarintLen(k) + eg.writeStringWithVarintLen(v) +} + +func (eg *encoderGRPC) writeTagUint64(k string, i uint64) { + eg.writeByte(byte(keyTypeInt64)) + eg.writeStringWithVarintLen(k) + eg.writeUint64(i) +} + +func (eg *encoderGRPC) writeTagTrue(k string) { + eg.writeByte(byte(keyTypeTrue)) + eg.writeStringWithVarintLen(k) +} + +func (eg *encoderGRPC) writeTagFalse(k string) { + eg.writeByte(byte(keyTypeFalse)) + eg.writeStringWithVarintLen(k) +} + +func (eg *encoderGRPC) writeBytesWithVarintLen(bytes []byte) { + length := len(bytes) + + eg.growIfRequired(binary.MaxVarintLen64 + length) + eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length)) + copy(eg.buf[eg.writeIdx:], bytes) + eg.writeIdx += length +} + +func (eg *encoderGRPC) writeStringWithVarintLen(s string) { + length := len(s) + + eg.growIfRequired(binary.MaxVarintLen64 + length) + eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length)) + copy(eg.buf[eg.writeIdx:], s) + eg.writeIdx += length +} + +func (eg *encoderGRPC) writeByte(v byte) { + eg.growIfRequired(1) + eg.buf[eg.writeIdx] = v + eg.writeIdx++ +} + +func (eg *encoderGRPC) writeUint32(i uint32) { + eg.growIfRequired(4) + binary.LittleEndian.PutUint32(eg.buf[eg.writeIdx:], i) + eg.writeIdx += 4 +} + +func (eg *encoderGRPC) writeUint64(i uint64) { + eg.growIfRequired(8) + binary.LittleEndian.PutUint64(eg.buf[eg.writeIdx:], i) + eg.writeIdx += 8 +} + +func (eg *encoderGRPC) readByte() byte { + b := eg.buf[eg.readIdx] + eg.readIdx++ + return b +} + +func (eg *encoderGRPC) readUint32() uint32 { + i := binary.LittleEndian.Uint32(eg.buf[eg.readIdx:]) + eg.readIdx += 4 + return i +} + +func (eg *encoderGRPC) readUint64() uint64 { + i := binary.LittleEndian.Uint64(eg.buf[eg.readIdx:]) + eg.readIdx += 8 + return i +} + +func (eg *encoderGRPC) readBytesWithVarintLen() ([]byte, error) { + if eg.readEnded() { + return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx) + } + length, valueStart := binary.Uvarint(eg.buf[eg.readIdx:]) + if valueStart <= 0 { + return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx) + } + + valueStart += eg.readIdx + valueEnd := valueStart + int(length) + if valueEnd > len(eg.buf) { + return nil, fmt.Errorf("malformed encoding: length:%v, upper:%v, maxLength:%v", length, valueEnd, len(eg.buf)) + } + + eg.readIdx = valueEnd + return eg.buf[valueStart:valueEnd], nil +} + +func (eg *encoderGRPC) readStringWithVarintLen() (string, error) { + bytes, err := eg.readBytesWithVarintLen() + if err != nil { + return "", err + } + return string(bytes), nil +} + +func (eg *encoderGRPC) growIfRequired(expected int) { + if len(eg.buf)-eg.writeIdx < expected { + tmp := make([]byte, 2*(len(eg.buf)+1)+expected) + copy(tmp, eg.buf) + eg.buf = tmp + } +} + +func (eg *encoderGRPC) readEnded() bool { + return eg.readIdx >= len(eg.buf) +} + +func (eg *encoderGRPC) bytes() []byte { + return eg.buf[:eg.writeIdx] +} + +// Encode encodes the tag map into a []byte. It is useful to propagate +// the tag maps on wire in binary format. +func Encode(m *Map) []byte { + if m == nil { + return nil + } + eg := &encoderGRPC{ + buf: make([]byte, len(m.m)), + } + eg.writeByte(byte(tagsVersionID)) + for k, v := range m.m { + if v.m.ttl.ttl == valueTTLUnlimitedPropagation { + eg.writeByte(byte(keyTypeString)) + eg.writeStringWithVarintLen(k.name) + eg.writeBytesWithVarintLen([]byte(v.value)) + } + } + return eg.bytes() +} + +// Decode decodes the given []byte into a tag map. +func Decode(bytes []byte) (*Map, error) { + ts := newMap() + err := DecodeEach(bytes, ts.upsert) + if err != nil { + // no partial failures + return nil, err + } + return ts, nil +} + +// DecodeEach decodes the given serialized tag map, calling handler for each +// tag key and value decoded. +func DecodeEach(bytes []byte, fn func(key Key, val string, md metadatas)) error { + eg := &encoderGRPC{ + buf: bytes, + } + if len(eg.buf) == 0 { + return nil + } + + version := eg.readByte() + if version > tagsVersionID { + return fmt.Errorf("cannot decode: unsupported version: %q; supports only up to: %q", version, tagsVersionID) + } + + for !eg.readEnded() { + typ := keyType(eg.readByte()) + + if typ != keyTypeString { + return fmt.Errorf("cannot decode: invalid key type: %q", typ) + } + + k, err := eg.readBytesWithVarintLen() + if err != nil { + return err + } + + v, err := eg.readBytesWithVarintLen() + if err != nil { + return err + } + + key, err := NewKey(string(k)) + if err != nil { + return err + } + val := string(v) + if !checkValue(val) { + return errInvalidValue + } + fn(key, val, createMetadatas(WithTTL(TTLUnlimitedPropagation))) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/go.opencensus.io/tag/metadata.go b/vendor/go.opencensus.io/tag/metadata.go new file mode 100644 index 00000000..6571a583 --- /dev/null +++ b/vendor/go.opencensus.io/tag/metadata.go @@ -0,0 +1,52 @@ +// Copyright 2019, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package tag + +const ( + // valueTTLNoPropagation prevents tag from propagating. + valueTTLNoPropagation = 0 + + // valueTTLUnlimitedPropagation allows tag to propagate without any limits on number of hops. + valueTTLUnlimitedPropagation = -1 +) + +// TTL is metadata that specifies number of hops a tag can propagate. +// Details about TTL metadata is specified at https://github.com/census-instrumentation/opencensus-specs/blob/master/tags/TagMap.md#tagmetadata +type TTL struct { + ttl int +} + +var ( + // TTLUnlimitedPropagation is TTL metadata that allows tag to propagate without any limits on number of hops. + TTLUnlimitedPropagation = TTL{ttl: valueTTLUnlimitedPropagation} + + // TTLNoPropagation is TTL metadata that prevents tag from propagating. + TTLNoPropagation = TTL{ttl: valueTTLNoPropagation} +) + +type metadatas struct { + ttl TTL +} + +// Metadata applies metadatas specified by the function. +type Metadata func(*metadatas) + +// WithTTL applies metadata with provided ttl. +func WithTTL(ttl TTL) Metadata { + return func(m *metadatas) { + m.ttl = ttl + } +} diff --git a/vendor/go.opencensus.io/tag/profile_19.go b/vendor/go.opencensus.io/tag/profile_19.go new file mode 100644 index 00000000..b34d95e3 --- /dev/null +++ b/vendor/go.opencensus.io/tag/profile_19.go @@ -0,0 +1,31 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build go1.9 + +package tag + +import ( + "context" + "runtime/pprof" +) + +func do(ctx context.Context, f func(ctx context.Context)) { + m := FromContext(ctx) + keyvals := make([]string, 0, 2*len(m.m)) + for k, v := range m.m { + keyvals = append(keyvals, k.Name(), v.value) + } + pprof.Do(ctx, pprof.Labels(keyvals...), f) +} diff --git a/vendor/go.opencensus.io/tag/profile_not19.go b/vendor/go.opencensus.io/tag/profile_not19.go new file mode 100644 index 00000000..83adbce5 --- /dev/null +++ b/vendor/go.opencensus.io/tag/profile_not19.go @@ -0,0 +1,23 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.9 + +package tag + +import "context" + +func do(ctx context.Context, f func(ctx context.Context)) { + f(ctx) +} diff --git a/vendor/go.opencensus.io/tag/validate.go b/vendor/go.opencensus.io/tag/validate.go new file mode 100644 index 00000000..0939fc67 --- /dev/null +++ b/vendor/go.opencensus.io/tag/validate.go @@ -0,0 +1,56 @@ +// Copyright 2017, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tag + +import "errors" + +const ( + maxKeyLength = 255 + + // valid are restricted to US-ASCII subset (range 0x20 (' ') to 0x7e ('~')). + validKeyValueMin = 32 + validKeyValueMax = 126 +) + +var ( + errInvalidKeyName = errors.New("invalid key name: only ASCII characters accepted; max length must be 255 characters") + errInvalidValue = errors.New("invalid value: only ASCII characters accepted; max length must be 255 characters") +) + +func checkKeyName(name string) bool { + if len(name) == 0 { + return false + } + if len(name) > maxKeyLength { + return false + } + return isASCII(name) +} + +func isASCII(s string) bool { + for _, c := range s { + if (c < validKeyValueMin) || (c > validKeyValueMax) { + return false + } + } + return true +} + +func checkValue(v string) bool { + if len(v) > maxKeyLength { + return false + } + return isASCII(v) +} diff --git a/vendor/go.uber.org/atomic/.codecov.yml b/vendor/go.uber.org/atomic/.codecov.yml new file mode 100644 index 00000000..6d4d1be7 --- /dev/null +++ b/vendor/go.uber.org/atomic/.codecov.yml @@ -0,0 +1,15 @@ +coverage: + range: 80..100 + round: down + precision: 2 + + status: + project: # measuring the overall project coverage + default: # context, you can create multiple ones with custom titles + enabled: yes # must be yes|true to enable this status + target: 100 # specify the target coverage for each commit status + # option: "auto" (must increase from parent commit or pull request base) + # option: "X%" a static target percentage to hit + if_not_found: success # if parent is not found report status as success, error, or failure + if_ci_failed: error # if ci fails report status as success, error, or failure + diff --git a/vendor/go.uber.org/atomic/.gitignore b/vendor/go.uber.org/atomic/.gitignore new file mode 100644 index 00000000..0a4504f1 --- /dev/null +++ b/vendor/go.uber.org/atomic/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +/vendor +/cover +cover.out +lint.log + +# Binaries +*.test + +# Profiling output +*.prof diff --git a/vendor/go.uber.org/atomic/.travis.yml b/vendor/go.uber.org/atomic/.travis.yml new file mode 100644 index 00000000..0f3769e5 --- /dev/null +++ b/vendor/go.uber.org/atomic/.travis.yml @@ -0,0 +1,27 @@ +sudo: false +language: go +go_import_path: go.uber.org/atomic + +go: + - 1.11.x + - 1.12.x + +matrix: + include: + - go: 1.12.x + env: NO_TEST=yes LINT=yes + +cache: + directories: + - vendor + +install: + - make install_ci + +script: + - test -n "$NO_TEST" || make test_ci + - test -n "$NO_TEST" || scripts/test-ubergo.sh + - test -z "$LINT" || make install_lint lint + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/go.uber.org/atomic/LICENSE.txt b/vendor/go.uber.org/atomic/LICENSE.txt new file mode 100644 index 00000000..8765c9fb --- /dev/null +++ b/vendor/go.uber.org/atomic/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/go.uber.org/atomic/Makefile b/vendor/go.uber.org/atomic/Makefile new file mode 100644 index 00000000..1ef26307 --- /dev/null +++ b/vendor/go.uber.org/atomic/Makefile @@ -0,0 +1,51 @@ +# Many Go tools take file globs or directories as arguments instead of packages. +PACKAGE_FILES ?= *.go + +# For pre go1.6 +export GO15VENDOREXPERIMENT=1 + + +.PHONY: build +build: + go build -i ./... + + +.PHONY: install +install: + glide --version || go get github.com/Masterminds/glide + glide install + + +.PHONY: test +test: + go test -cover -race ./... + + +.PHONY: install_ci +install_ci: install + go get github.com/wadey/gocovmerge + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +.PHONY: install_lint +install_lint: + go get golang.org/x/lint/golint + + +.PHONY: lint +lint: + @rm -rf lint.log + @echo "Checking formatting..." + @gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log + @echo "Checking vet..." + @go vet ./... 2>&1 | tee -a lint.log;) + @echo "Checking lint..." + @golint $$(go list ./...) 2>&1 | tee -a lint.log + @echo "Checking for unresolved FIXMEs..." + @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log + @[ ! -s lint.log ] + + +.PHONY: test_ci +test_ci: install_ci build + ./scripts/cover.sh $(shell go list $(PACKAGES)) diff --git a/vendor/go.uber.org/atomic/README.md b/vendor/go.uber.org/atomic/README.md new file mode 100644 index 00000000..62eb8e57 --- /dev/null +++ b/vendor/go.uber.org/atomic/README.md @@ -0,0 +1,36 @@ +# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard] + +Simple wrappers for primitive types to enforce atomic access. + +## Installation +`go get -u go.uber.org/atomic` + +## Usage +The standard library's `sync/atomic` is powerful, but it's easy to forget which +variables must be accessed atomically. `go.uber.org/atomic` preserves all the +functionality of the standard library, but wraps the primitive types to +provide a safer, more convenient API. + +```go +var atom atomic.Uint32 +atom.Store(42) +atom.Sub(2) +atom.CAS(40, 11) +``` + +See the [documentation][doc] for a complete API specification. + +## Development Status +Stable. + +___ +Released under the [MIT License](LICENSE.txt). + +[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg +[doc]: https://godoc.org/go.uber.org/atomic +[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master +[ci]: https://travis-ci.com/uber-go/atomic +[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg +[cov]: https://codecov.io/gh/uber-go/atomic +[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic +[reportcard]: https://goreportcard.com/report/go.uber.org/atomic diff --git a/vendor/go.uber.org/atomic/atomic.go b/vendor/go.uber.org/atomic/atomic.go new file mode 100644 index 00000000..1db6849f --- /dev/null +++ b/vendor/go.uber.org/atomic/atomic.go @@ -0,0 +1,351 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package atomic provides simple wrappers around numerics to enforce atomic +// access. +package atomic + +import ( + "math" + "sync/atomic" + "time" +) + +// Int32 is an atomic wrapper around an int32. +type Int32 struct{ v int32 } + +// NewInt32 creates an Int32. +func NewInt32(i int32) *Int32 { + return &Int32{i} +} + +// Load atomically loads the wrapped value. +func (i *Int32) Load() int32 { + return atomic.LoadInt32(&i.v) +} + +// Add atomically adds to the wrapped int32 and returns the new value. +func (i *Int32) Add(n int32) int32 { + return atomic.AddInt32(&i.v, n) +} + +// Sub atomically subtracts from the wrapped int32 and returns the new value. +func (i *Int32) Sub(n int32) int32 { + return atomic.AddInt32(&i.v, -n) +} + +// Inc atomically increments the wrapped int32 and returns the new value. +func (i *Int32) Inc() int32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int32 and returns the new value. +func (i *Int32) Dec() int32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +func (i *Int32) CAS(old, new int32) bool { + return atomic.CompareAndSwapInt32(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Int32) Store(n int32) { + atomic.StoreInt32(&i.v, n) +} + +// Swap atomically swaps the wrapped int32 and returns the old value. +func (i *Int32) Swap(n int32) int32 { + return atomic.SwapInt32(&i.v, n) +} + +// Int64 is an atomic wrapper around an int64. +type Int64 struct{ v int64 } + +// NewInt64 creates an Int64. +func NewInt64(i int64) *Int64 { + return &Int64{i} +} + +// Load atomically loads the wrapped value. +func (i *Int64) Load() int64 { + return atomic.LoadInt64(&i.v) +} + +// Add atomically adds to the wrapped int64 and returns the new value. +func (i *Int64) Add(n int64) int64 { + return atomic.AddInt64(&i.v, n) +} + +// Sub atomically subtracts from the wrapped int64 and returns the new value. +func (i *Int64) Sub(n int64) int64 { + return atomic.AddInt64(&i.v, -n) +} + +// Inc atomically increments the wrapped int64 and returns the new value. +func (i *Int64) Inc() int64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int64 and returns the new value. +func (i *Int64) Dec() int64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +func (i *Int64) CAS(old, new int64) bool { + return atomic.CompareAndSwapInt64(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Int64) Store(n int64) { + atomic.StoreInt64(&i.v, n) +} + +// Swap atomically swaps the wrapped int64 and returns the old value. +func (i *Int64) Swap(n int64) int64 { + return atomic.SwapInt64(&i.v, n) +} + +// Uint32 is an atomic wrapper around an uint32. +type Uint32 struct{ v uint32 } + +// NewUint32 creates a Uint32. +func NewUint32(i uint32) *Uint32 { + return &Uint32{i} +} + +// Load atomically loads the wrapped value. +func (i *Uint32) Load() uint32 { + return atomic.LoadUint32(&i.v) +} + +// Add atomically adds to the wrapped uint32 and returns the new value. +func (i *Uint32) Add(n uint32) uint32 { + return atomic.AddUint32(&i.v, n) +} + +// Sub atomically subtracts from the wrapped uint32 and returns the new value. +func (i *Uint32) Sub(n uint32) uint32 { + return atomic.AddUint32(&i.v, ^(n - 1)) +} + +// Inc atomically increments the wrapped uint32 and returns the new value. +func (i *Uint32) Inc() uint32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int32 and returns the new value. +func (i *Uint32) Dec() uint32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +func (i *Uint32) CAS(old, new uint32) bool { + return atomic.CompareAndSwapUint32(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Uint32) Store(n uint32) { + atomic.StoreUint32(&i.v, n) +} + +// Swap atomically swaps the wrapped uint32 and returns the old value. +func (i *Uint32) Swap(n uint32) uint32 { + return atomic.SwapUint32(&i.v, n) +} + +// Uint64 is an atomic wrapper around a uint64. +type Uint64 struct{ v uint64 } + +// NewUint64 creates a Uint64. +func NewUint64(i uint64) *Uint64 { + return &Uint64{i} +} + +// Load atomically loads the wrapped value. +func (i *Uint64) Load() uint64 { + return atomic.LoadUint64(&i.v) +} + +// Add atomically adds to the wrapped uint64 and returns the new value. +func (i *Uint64) Add(n uint64) uint64 { + return atomic.AddUint64(&i.v, n) +} + +// Sub atomically subtracts from the wrapped uint64 and returns the new value. +func (i *Uint64) Sub(n uint64) uint64 { + return atomic.AddUint64(&i.v, ^(n - 1)) +} + +// Inc atomically increments the wrapped uint64 and returns the new value. +func (i *Uint64) Inc() uint64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint64 and returns the new value. +func (i *Uint64) Dec() uint64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +func (i *Uint64) CAS(old, new uint64) bool { + return atomic.CompareAndSwapUint64(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Uint64) Store(n uint64) { + atomic.StoreUint64(&i.v, n) +} + +// Swap atomically swaps the wrapped uint64 and returns the old value. +func (i *Uint64) Swap(n uint64) uint64 { + return atomic.SwapUint64(&i.v, n) +} + +// Bool is an atomic Boolean. +type Bool struct{ v uint32 } + +// NewBool creates a Bool. +func NewBool(initial bool) *Bool { + return &Bool{boolToInt(initial)} +} + +// Load atomically loads the Boolean. +func (b *Bool) Load() bool { + return truthy(atomic.LoadUint32(&b.v)) +} + +// CAS is an atomic compare-and-swap. +func (b *Bool) CAS(old, new bool) bool { + return atomic.CompareAndSwapUint32(&b.v, boolToInt(old), boolToInt(new)) +} + +// Store atomically stores the passed value. +func (b *Bool) Store(new bool) { + atomic.StoreUint32(&b.v, boolToInt(new)) +} + +// Swap sets the given value and returns the previous value. +func (b *Bool) Swap(new bool) bool { + return truthy(atomic.SwapUint32(&b.v, boolToInt(new))) +} + +// Toggle atomically negates the Boolean and returns the previous value. +func (b *Bool) Toggle() bool { + return truthy(atomic.AddUint32(&b.v, 1) - 1) +} + +func truthy(n uint32) bool { + return n&1 == 1 +} + +func boolToInt(b bool) uint32 { + if b { + return 1 + } + return 0 +} + +// Float64 is an atomic wrapper around float64. +type Float64 struct { + v uint64 +} + +// NewFloat64 creates a Float64. +func NewFloat64(f float64) *Float64 { + return &Float64{math.Float64bits(f)} +} + +// Load atomically loads the wrapped value. +func (f *Float64) Load() float64 { + return math.Float64frombits(atomic.LoadUint64(&f.v)) +} + +// Store atomically stores the passed value. +func (f *Float64) Store(s float64) { + atomic.StoreUint64(&f.v, math.Float64bits(s)) +} + +// Add atomically adds to the wrapped float64 and returns the new value. +func (f *Float64) Add(s float64) float64 { + for { + old := f.Load() + new := old + s + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float64 and returns the new value. +func (f *Float64) Sub(s float64) float64 { + return f.Add(-s) +} + +// CAS is an atomic compare-and-swap. +func (f *Float64) CAS(old, new float64) bool { + return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new)) +} + +// Duration is an atomic wrapper around time.Duration +// https://godoc.org/time#Duration +type Duration struct { + v Int64 +} + +// NewDuration creates a Duration. +func NewDuration(d time.Duration) *Duration { + return &Duration{v: *NewInt64(int64(d))} +} + +// Load atomically loads the wrapped value. +func (d *Duration) Load() time.Duration { + return time.Duration(d.v.Load()) +} + +// Store atomically stores the passed value. +func (d *Duration) Store(n time.Duration) { + d.v.Store(int64(n)) +} + +// Add atomically adds to the wrapped time.Duration and returns the new value. +func (d *Duration) Add(n time.Duration) time.Duration { + return time.Duration(d.v.Add(int64(n))) +} + +// Sub atomically subtracts from the wrapped time.Duration and returns the new value. +func (d *Duration) Sub(n time.Duration) time.Duration { + return time.Duration(d.v.Sub(int64(n))) +} + +// Swap atomically swaps the wrapped time.Duration and returns the old value. +func (d *Duration) Swap(n time.Duration) time.Duration { + return time.Duration(d.v.Swap(int64(n))) +} + +// CAS is an atomic compare-and-swap. +func (d *Duration) CAS(old, new time.Duration) bool { + return d.v.CAS(int64(old), int64(new)) +} + +// Value shadows the type of the same name from sync/atomic +// https://godoc.org/sync/atomic#Value +type Value struct{ atomic.Value } diff --git a/vendor/go.uber.org/atomic/error.go b/vendor/go.uber.org/atomic/error.go new file mode 100644 index 00000000..0489d19b --- /dev/null +++ b/vendor/go.uber.org/atomic/error.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// Error is an atomic type-safe wrapper around Value for errors +type Error struct{ v Value } + +// errorHolder is non-nil holder for error object. +// atomic.Value panics on saving nil object, so err object needs to be +// wrapped with valid object first. +type errorHolder struct{ err error } + +// NewError creates new atomic error object +func NewError(err error) *Error { + e := &Error{} + if err != nil { + e.Store(err) + } + return e +} + +// Load atomically loads the wrapped error +func (e *Error) Load() error { + v := e.v.Load() + if v == nil { + return nil + } + + eh := v.(errorHolder) + return eh.err +} + +// Store atomically stores error. +// NOTE: a holder object is allocated on each Store call. +func (e *Error) Store(err error) { + e.v.Store(errorHolder{err: err}) +} diff --git a/vendor/go.uber.org/atomic/glide.lock b/vendor/go.uber.org/atomic/glide.lock new file mode 100644 index 00000000..3c72c599 --- /dev/null +++ b/vendor/go.uber.org/atomic/glide.lock @@ -0,0 +1,17 @@ +hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53 +updated: 2016-10-27T00:10:51.16960137-07:00 +imports: [] +testImports: +- name: github.com/davecgh/go-spew + version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/testify + version: d77da356e56a7428ad25149ca77381849a6a5232 + subpackages: + - assert + - require diff --git a/vendor/go.uber.org/atomic/glide.yaml b/vendor/go.uber.org/atomic/glide.yaml new file mode 100644 index 00000000..4cf608ec --- /dev/null +++ b/vendor/go.uber.org/atomic/glide.yaml @@ -0,0 +1,6 @@ +package: go.uber.org/atomic +testImport: +- package: github.com/stretchr/testify + subpackages: + - assert + - require diff --git a/vendor/go.uber.org/atomic/string.go b/vendor/go.uber.org/atomic/string.go new file mode 100644 index 00000000..ede8136f --- /dev/null +++ b/vendor/go.uber.org/atomic/string.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// String is an atomic type-safe wrapper around Value for strings. +type String struct{ v Value } + +// NewString creates a String. +func NewString(str string) *String { + s := &String{} + if str != "" { + s.Store(str) + } + return s +} + +// Load atomically loads the wrapped string. +func (s *String) Load() string { + v := s.v.Load() + if v == nil { + return "" + } + return v.(string) +} + +// Store atomically stores the passed string. +// Note: Converting the string to an interface{} to store in the Value +// requires an allocation. +func (s *String) Store(str string) { + s.v.Store(str) +} diff --git a/vendor/go.uber.org/dig/.codecov.yml b/vendor/go.uber.org/dig/.codecov.yml new file mode 100644 index 00000000..c474df1c --- /dev/null +++ b/vendor/go.uber.org/dig/.codecov.yml @@ -0,0 +1,19 @@ +coverage: + range: 70..98 + round: down + precision: 2 + + status: + project: # measuring the overall project coverage + default: # context, you can create multiple ones with custom titles + enabled: yes # must be yes|true to enable this status + target: 98 # specify the target coverage for each commit status + # option: "auto" (must increase from parent commit or pull request base) + # option: "X%" a static target percentage to hit + if_not_found: success # if parent is not found report status as success, error, or failure + if_ci_failed: error # if ci fails report status as success, error, or failure + + patch: + default: + enabled: yes + target: 70 diff --git a/vendor/go.uber.org/dig/.gitignore b/vendor/go.uber.org/dig/.gitignore new file mode 100644 index 00000000..23249243 --- /dev/null +++ b/vendor/go.uber.org/dig/.gitignore @@ -0,0 +1,11 @@ +/vendor +/.bench +*.mem +*.cpu +*.test +*.log +*.out +*.html +*.coverprofile +coverage.txt +*.pprof diff --git a/vendor/go.uber.org/dig/.travis.yml b/vendor/go.uber.org/dig/.travis.yml new file mode 100644 index 00000000..c0b94633 --- /dev/null +++ b/vendor/go.uber.org/dig/.travis.yml @@ -0,0 +1,18 @@ +language: go +sudo: false +go_import_path: go.uber.org/dig + +matrix: + include: + - go: "1.10" + - go: "1.11" + env: LINT=1 + +cache: + directories: + - vendor +install: + - make dependencies +script: + - test -z "$LINT" && echo "Skipping lint" || make lint + - make ci diff --git a/vendor/go.uber.org/dig/CHANGELOG.md b/vendor/go.uber.org/dig/CHANGELOG.md new file mode 100644 index 00000000..6251d203 --- /dev/null +++ b/vendor/go.uber.org/dig/CHANGELOG.md @@ -0,0 +1,160 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [1.7.0] - 2019-01-04 +### Added +- Added `Group` option for `Provide` to add value groups to the container without +rewriting constructors. See package doucmentation for more information. + +## [1.6.0] - 2018-11-06 +### Changed +- When an error graph is visualized, the graph is pruned so that the graph only + contains failure nodes. +- Container visualization is now oriented from right to left. + +## [1.5.1] - 2018-11-01 +### Fixed +- Fixed a test that was causing Dig to be unusable with Go Modules. + +## [1.5.0] - 2018-09-19 +### Added +- Added a `DeferAcyclicVerification` container option that defers graph cycle + detection until the next Invoke. + +### Changed +- Improved cycle-detection performance by 50x in certain degenerative cases. + +## [1.4.0] - 2018-08-16 +### Added +- Added `Visualize` function to visualize the state of the container in the + GraphViz DOT format. This allows visualization of error types and the + dependency relationships of types in the container. +- Added `CanVisualizeError` function to determine if an error can be visualized + in the graph. +- Added `Name` option for `Provide` to add named values to the container + without rewriting constructors. See package documentation for more + information. + +### Changed +- `name:"..."` tags on nested Result Objects will now cause errors instead of + being ignored. + +## [1.3.0] - 2017-12-04 +### Changed +- Improved messages for errors thrown by Dig under a many scenarios to be more + informative. + +## [1.2.0] - 2017-11-07 +### Added +- `dig.In` and `dig.Out` now support value groups, making it possible to + produce many values of the same type from different constructors. See package + documentation for more information. + +## [1.1.0] - 2017-09-15 +### Added +- Added the `dig.RootCause` function which allows retrieving the original + constructor error that caused an `Invoke` failure. + +### Changed +- Errors from `Invoke` now attempt to hint to the user a presence of a similar + type, for example a pointer to the requested type and vice versa. + +## [1.0.0] - 2017-07-31 + +First stable release: no breaking changes will be made in the 1.x series. + +### Changed +- `Provide` and `Invoke` will now fail if `dig.In` or `dig.Out` structs + contain unexported fields. Previously these fields were ignored which often + led to confusion. + +## [1.0.0-rc2] - 2017-07-21 +### Added +- Exported `dig.IsIn` and `dig.IsOut` so that consuming libraries can check if + a params or return struct embeds the `dig.In` and `dig.Out` types, respectively. + +### Changed +- Added variadic options to all public APIS so that new functionality can be + introduced post v1.0.0 without introducing breaking changes. +- Functions with variadic arguments can now be passed to `dig.Provide` and + `dig.Invoke`. Previously this caused an error, whereas now the args will be ignored. + +## [1.0.0-rc1] - 2017-06-21 + +First release candidate. + +## [0.5.0] - 2017-06-19 +### Added +- `dig.In` and `dig.Out` now support named instances, i.e.: + + ```go + type param struct { + dig.In + + DB1 DB.Connection `name:"primary"` + DB2 DB.Connection `name:"secondary"` + } + ``` + +### Fixed +- Structs compatible with `dig.In` and `dig.Out` may now be generated using + `reflect.StructOf`. + +## [0.4.0] - 2017-06-12 +### Added +- Add `dig.In` embeddable type for advanced use-cases of specifying dependencies. +- Add `dig.Out` embeddable type for advanced use-cases of constructors + inserting types in the container. +- Add support for optional parameters through `optional:"true"` tag on `dig.In` objects. +- Add support for value types and many built-ins (maps, slices, channels). + +### Changed +- **[Breaking]** Restrict the API surface to only `Provide` and `Invoke`. +- **[Breaking]** Update `Provide` method to accept variadic arguments. + +### Removed +- **[Breaking]** Remove `Must*` funcs to greatly reduce API surface area. +- Providing constructors with common returned types results in an error. + +## [0.3] - 2017-05-02 +### Added +- Add functionality to `Provide` to support constructor with `n` return + objects to be resolved into the `dig.Graph` +- Add `Invoke` function to invoke provided function and insert return + objects into the `dig.Graph` + +### Changed +- Rename `RegisterAll` and `MustRegisterAll` to `ProvideAll` and + `MustProvideAll`. + +## [0.2] - 2017-03-27 +### Changed +- Rename `Register` to `Provide` for clarity and to recude clash with other + Register functions. +- Rename `dig.Graph` to `dig.Container`. + +### Removed +- Remove the package-level functions and the `DefaultGraph`. + +## 0.1 - 2017-03-23 + +Initial release. + +[1.7.0]: https://github.com/uber-go/dig/compare/v1.6.0...v1.7.0 +[1.6.0]: https://github.com/uber-go/dig/compare/v1.5.1...v1.6.0 +[1.5.1]: https://github.com/uber-go/dig/compare/v1.5.0...v1.5.1 +[1.5.0]: https://github.com/uber-go/dig/compare/v1.4.0...v1.5.0 +[1.4.0]: https://github.com/uber-go/dig/compare/v1.3.0...v1.4.0 +[1.3.0]: https://github.com/uber-go/dig/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/uber-go/dig/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/uber-go/dig/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/uber-go/dig/compare/v1.0.0-rc2...v1.0.0 +[1.0.0-rc2]: https://github.com/uber-go/dig/compare/v1.0.0-rc1...v1.0.0-rc2 +[1.0.0-rc1]: https://github.com/uber-go/dig/compare/v0.5.0...v1.0.0-rc1 +[0.5.0]: https://github.com/uber-go/dig/compare/v0.4.0...v0.5.0 +[0.4.0]: https://github.com/uber-go/dig/compare/v0.3...v0.4.0 +[0.3]: https://github.com/uber-go/dig/compare/v0.2...v0.3 +[0.2]: https://github.com/uber-go/dig/compare/v0.1...v0.2 diff --git a/vendor/go.uber.org/dig/LICENSE b/vendor/go.uber.org/dig/LICENSE new file mode 100644 index 00000000..00a8d056 --- /dev/null +++ b/vendor/go.uber.org/dig/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017-2018 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/go.uber.org/dig/Makefile b/vendor/go.uber.org/dig/Makefile new file mode 100644 index 00000000..10cb24fa --- /dev/null +++ b/vendor/go.uber.org/dig/Makefile @@ -0,0 +1,52 @@ +BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem +PKGS ?= $(shell glide novendor | grep -v examples) +PKG_FILES ?= *.go +GO_VERSION := $(shell go version | cut -d " " -f 3) + +.PHONY: all +all: lint test + +.PHONY: dependencies +dependencies: + @echo "Installing Glide and locked dependencies..." + glide --version || go get -u -f github.com/Masterminds/glide + glide install + @echo "Installing uber-license tool..." + command -v update-license >/dev/null || go get -u -f go.uber.org/tools/update-license + @echo "Installing golint..." + command -v golint >/dev/null || go get -u -f github.com/golang/lint/golint + +.PHONY: license +license: dependencies + ./check_license.sh | tee -a lint.log + +.PHONY: lint +lint: + @rm -rf lint.log + @echo "Checking formatting..." + @gofmt -d -s $(PKG_FILES) 2>&1 | tee lint.log + @echo "Installing test dependencies for vet..." + @go test -i $(PKGS) + @echo "Checking vet..." + @$(foreach dir,$(PKG_FILES),go tool vet $(VET_RULES) $(dir) 2>&1 | tee -a lint.log;) + @echo "Checking lint..." + @$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;) + @echo "Checking for unresolved FIXMEs..." + @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log + @echo "Checking for license headers..." + @DRY_RUN=1 ./check_license.sh | tee -a lint.log + @[ ! -s lint.log ] + +.PHONY: test +test: + @.build/test.sh + +.PHONY: ci +ci: SHELL := /bin/bash +ci: test + bash <(curl -s https://codecov.io/bash) + +.PHONY: bench +BENCH ?= . +bench: + @$(foreach pkg,$(PKGS),go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) $(pkg);) diff --git a/vendor/go.uber.org/dig/README.md b/vendor/go.uber.org/dig/README.md new file mode 100644 index 00000000..f23fa1ac --- /dev/null +++ b/vendor/go.uber.org/dig/README.md @@ -0,0 +1,43 @@ +# :hammer: dig [![GoDoc][doc-img]][doc] [![GitHub release][release-img]][release] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][report-card-img]][report-card] + +A reflection based dependency injection toolkit for Go. + +### Good for: + +* Powering an application framework, e.g. [Fx](https://github.com/uber-go/fx). +* Resolving the object graph during process startup. + +### Bad for: + +* Using in place of an application framework, e.g. [Fx](https://github.com/uber-go/fx). +* Resolving dependencies after the process has already started. +* Exposing to user-land code as a [Service Locator](https://martinfowler.com/articles/injection.html#UsingAServiceLocator). + +## Installation + +We recommend locking to [SemVer](http://semver.org/) range `^1` using [Glide](https://github.com/Masterminds/glide): + +``` +glide get 'go.uber.org/dig#^1' +``` + +## Stability + +This library is `v1` and follows [SemVer](http://semver.org/) strictly. + +No breaking changes will be made to exported APIs before `v2.0.0`. + +[doc-img]: http://img.shields.io/badge/GoDoc-Reference-blue.svg +[doc]: https://godoc.org/go.uber.org/dig + +[release-img]: https://img.shields.io/github/release/uber-go/dig.svg +[release]: https://github.com/uber-go/dig/releases + +[ci-img]: https://img.shields.io/travis/uber-go/dig/master.svg +[ci]: https://travis-ci.org/uber-go/dig/branches + +[cov-img]: https://codecov.io/gh/uber-go/dig/branch/master/graph/badge.svg +[cov]: https://codecov.io/gh/uber-go/dig/branch/master + +[report-card-img]: https://goreportcard.com/badge/github.com/uber-go/dig +[report-card]: https://goreportcard.com/report/github.com/uber-go/dig diff --git a/vendor/go.uber.org/dig/check_license.sh b/vendor/go.uber.org/dig/check_license.sh new file mode 100755 index 00000000..e8162850 --- /dev/null +++ b/vendor/go.uber.org/dig/check_license.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -eo pipefail + +run_update_license() { + # doing this because of SC2046 warning + for file in $(git ls-files | grep '\.go$'); do + update-license $@ "${file}" + done +} + +if [ -z "${DRY_RUN}" ]; then + run_update_license +else + DRY_OUTPUT="$(run_update_license --dry)" + if [ -n "${DRY_OUTPUT}" ]; then + echo "The following files do not have correct license headers." + echo "Please run make license and amend your commit." + echo + echo "${DRY_OUTPUT}" + exit 1 + fi +fi diff --git a/vendor/go.uber.org/dig/cycle.go b/vendor/go.uber.org/dig/cycle.go new file mode 100644 index 00000000..03f9f6bc --- /dev/null +++ b/vendor/go.uber.org/dig/cycle.go @@ -0,0 +1,142 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "bytes" + "fmt" + + "go.uber.org/dig/internal/digreflect" +) + +type cycleEntry struct { + Key key + Func *digreflect.Func +} + +type errCycleDetected struct { + Path []cycleEntry +} + +func (e errCycleDetected) Error() string { + // We get something like, + // + // foo provided by "path/to/package".NewFoo (path/to/file.go:42) + // depends on bar provided by "another/package".NewBar (somefile.go:1) + // depends on baz provided by "somepackage".NewBar (anotherfile.go:2) + // depends on foo provided by "path/to/package".NewFoo (path/to/file.go:42) + // + b := new(bytes.Buffer) + + for i, entry := range e.Path { + if i > 0 { + b.WriteString("\n\tdepends on ") + } + fmt.Fprintf(b, "%v provided by %v", entry.Key, entry.Func) + } + return b.String() +} + +// IsCycleDetected returns a boolean as to whether the provided error indicates +// a cycle was detected in the container graph. +func IsCycleDetected(err error) bool { + _, ok := RootCause(err).(errCycleDetected) + return ok +} + +func verifyAcyclic(c containerStore, n provider, k key) error { + visited := make(map[key]struct{}) + err := detectCycles(n, c, []cycleEntry{ + {Key: k, Func: n.Location()}, + }, visited) + if err != nil { + err = errWrapf(err, "this function introduces a cycle") + } + return err +} + +func detectCycles(n provider, c containerStore, path []cycleEntry, visited map[key]struct{}) error { + var err error + walkParam(n.ParamList(), paramVisitorFunc(func(param param) bool { + if err != nil { + return false + } + + var ( + k key + providers []provider + ) + switch p := param.(type) { + case paramSingle: + k = key{name: p.Name, t: p.Type} + if _, ok := visited[k]; ok { + // We've already checked the dependencies for this type. + return false + } + providers = c.getValueProviders(p.Name, p.Type) + case paramGroupedSlice: + // NOTE: The key uses the element type, not the slice type. + k = key{group: p.Group, t: p.Type.Elem()} + if _, ok := visited[k]; ok { + // We've already checked the dependencies for this type. + return false + } + providers = c.getGroupProviders(p.Group, p.Type.Elem()) + default: + // Recurse for non-edge params. + return true + } + + entry := cycleEntry{Func: n.Location(), Key: k} + + if len(path) > 0 { + // Only mark a key as visited if path exists, i.e. this is not the + // first iteration through the c.verifyAcyclic() check. Otherwise the + // early exit from checking visited above will short circuit the + // cycle check below. + visited[k] = struct{}{} + + // If it exists, the first element of path is the new addition to the + // graph, therefore it must be in any cycle that exists, assuming + // verifyAcyclic has been run for every previous Provide. + // + // Alternatively, if deferAcyclicVerification was set and detectCycles + // is only being called before the first Invoke, each node in the + // graph will be tested as the first element of the path, so any + // cycle that exists is guaranteed to trip the following condition. + if path[0].Key == k { + err = errCycleDetected{Path: append(path, entry)} + return false + } + } + + for _, n := range providers { + if e := detectCycles(n, c, append(path, entry), visited); e != nil { + err = e + return false + } + } + + return true + })) + + return err +} diff --git a/vendor/go.uber.org/dig/dig.go b/vendor/go.uber.org/dig/dig.go new file mode 100644 index 00000000..36df0873 --- /dev/null +++ b/vendor/go.uber.org/dig/dig.go @@ -0,0 +1,774 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "errors" + "fmt" + "math/rand" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "go.uber.org/dig/internal/digreflect" + "go.uber.org/dig/internal/dot" +) + +const ( + _optionalTag = "optional" + _nameTag = "name" + _groupTag = "group" +) + +// Unique identification of an object in the graph. +type key struct { + t reflect.Type + + // Only one of name or group will be set. + name string + group string +} + +// Option configures a Container. It's included for future functionality; +// currently, there are no concrete implementations. +type Option interface { + applyOption(*Container) +} + +type optionFunc func(*Container) + +func (f optionFunc) applyOption(c *Container) { f(c) } + +type provideOptions struct { + Name string + Group string +} + +func (o *provideOptions) Validate() error { + if len(o.Group) > 0 && len(o.Name) > 0 { + return fmt.Errorf( + "cannot use named values with value groups: name:%q provided with group:%q", o.Name, o.Group) + } + + // Names must be representable inside a backquoted string. The only + // limitation for raw string literals as per + // https://golang.org/ref/spec#raw_string_lit is that they cannot contain + // backquotes. + if strings.ContainsRune(o.Name, '`') { + return fmt.Errorf("invalid dig.Name(%q): names cannot contain backquotes", o.Name) + } + if strings.ContainsRune(o.Group, '`') { + return fmt.Errorf("invalid dig.Group(%q): group names cannot contain backquotes", o.Group) + } + return nil +} + +// A ProvideOption modifies the default behavior of Provide. +type ProvideOption interface { + applyProvideOption(*provideOptions) +} + +type provideOptionFunc func(*provideOptions) + +func (f provideOptionFunc) applyProvideOption(opts *provideOptions) { f(opts) } + +// Name is a ProvideOption that specifies that all values produced by a +// constructor should have the given name. See also the package documentation +// about Named Values. +// +// Given, +// +// func NewReadOnlyConnection(...) (*Connection, error) +// func NewReadWriteConnection(...) (*Connection, error) +// +// The following will provide two connections to the container: one under the +// name "ro" and the other under the name "rw". +// +// c.Provide(NewReadOnlyConnection, dig.Name("ro")) +// c.Provide(NewReadWriteConnection, dig.Name("rw")) +// +// This option cannot be provided for constructors which produce result +// objects. +func Name(name string) ProvideOption { + return provideOptionFunc(func(opts *provideOptions) { + opts.Name = name + }) +} + +// Group is a ProvideOption that specifies that all values produced by a +// constructor should be added to the specified group. See also the package +// documentation about Value Groups. +// +// This option cannot be provided for constructors which produce result +// objects. +func Group(group string) ProvideOption { + return provideOptionFunc(func(opts *provideOptions) { + opts.Group = group + }) +} + +// An InvokeOption modifies the default behavior of Invoke. It's included for +// future functionality; currently, there are no concrete implementations. +type InvokeOption interface { + unimplemented() +} + +// Container is a directed acyclic graph of types and their dependencies. +type Container struct { + // Mapping from key to all the nodes that can provide a value for that + // key. + providers map[key][]*node + + // All nodes in the container. + nodes []*node + + // Values that have already been generated in the container. + values map[key]reflect.Value + + // Values groups that have already been generated in the container. + groups map[key][]reflect.Value + + // Source of randomness. + rand *rand.Rand + + // Flag indicating whether the graph has been checked for cycles. + isVerifiedAcyclic bool + + // Defer acyclic check on provide until Invoke. + deferAcyclicVerification bool +} + +// containerWriter provides write access to the Container's underlying data +// store. +type containerWriter interface { + // setValue sets the value with the given name and type in the container. + // If a value with the same name and type already exists, it will be + // overwritten. + setValue(name string, t reflect.Type, v reflect.Value) + + // submitGroupedValue submits a value to the value group with the provided + // name. + submitGroupedValue(name string, t reflect.Type, v reflect.Value) +} + +// containerStore provides access to the Container's underlying data store. +type containerStore interface { + containerWriter + + // Returns a slice containing all known types. + knownTypes() []reflect.Type + + // Retrieves the value with the provided name and type, if any. + getValue(name string, t reflect.Type) (v reflect.Value, ok bool) + + // Retrieves all values for the provided group and type. + // + // The order in which the values are returned is undefined. + getValueGroup(name string, t reflect.Type) []reflect.Value + + // Returns the providers that can produce a value with the given name and + // type. + getValueProviders(name string, t reflect.Type) []provider + + // Returns the providers that can produce values for the given group and + // type. + getGroupProviders(name string, t reflect.Type) []provider + + createGraph() *dot.Graph +} + +// provider encapsulates a user-provided constructor. +type provider interface { + // ID is a unique numerical identifier for this provider. + ID() dot.CtorID + + // Location returns where this constructor was defined. + Location() *digreflect.Func + + // ParamList returns information about the direct dependencies of this + // constructor. + ParamList() paramList + + // ResultList returns information about the values produced by this + // constructor. + ResultList() resultList + + // Calls the underlying constructor, reading values from the + // containerStore as needed. + // + // The values produced by this provider should be submitted into the + // containerStore. + Call(containerStore) error +} + +// New constructs a Container. +func New(opts ...Option) *Container { + c := &Container{ + providers: make(map[key][]*node), + values: make(map[key]reflect.Value), + groups: make(map[key][]reflect.Value), + rand: rand.New(rand.NewSource(time.Now().UnixNano())), + } + + for _, opt := range opts { + opt.applyOption(c) + } + return c +} + +// DeferAcyclicVerification is an Option to override the default behavior +// of container.Provide, deferring the dependency graph validation to no longer +// run after each call to container.Provide. The container will instead verify +// the graph on first `Invoke`. +// +// Applications adding providers to a container in a tight loop may experience +// performance improvements by initializing the container with this option. +func DeferAcyclicVerification() Option { + return optionFunc(func(c *Container) { + c.deferAcyclicVerification = true + }) +} + +// Changes the source of randomness for the container. +// +// This will help provide determinism during tests. +func setRand(r *rand.Rand) Option { + return optionFunc(func(c *Container) { + c.rand = r + }) +} + +func (c *Container) knownTypes() []reflect.Type { + typeSet := make(map[reflect.Type]struct{}, len(c.providers)) + for k := range c.providers { + typeSet[k.t] = struct{}{} + } + + types := make([]reflect.Type, 0, len(typeSet)) + for t := range typeSet { + types = append(types, t) + } + sort.Sort(byTypeName(types)) + return types +} + +func (c *Container) getValue(name string, t reflect.Type) (v reflect.Value, ok bool) { + v, ok = c.values[key{name: name, t: t}] + return +} + +func (c *Container) setValue(name string, t reflect.Type, v reflect.Value) { + c.values[key{name: name, t: t}] = v +} + +func (c *Container) getValueGroup(name string, t reflect.Type) []reflect.Value { + items := c.groups[key{group: name, t: t}] + // shuffle the list so users don't rely on the ordering of grouped values + return shuffledCopy(c.rand, items) +} + +func (c *Container) submitGroupedValue(name string, t reflect.Type, v reflect.Value) { + k := key{group: name, t: t} + c.groups[k] = append(c.groups[k], v) +} + +func (c *Container) getValueProviders(name string, t reflect.Type) []provider { + return c.getProviders(key{name: name, t: t}) +} + +func (c *Container) getGroupProviders(name string, t reflect.Type) []provider { + return c.getProviders(key{group: name, t: t}) +} + +func (c *Container) getProviders(k key) []provider { + nodes := c.providers[k] + providers := make([]provider, len(nodes)) + for i, n := range nodes { + providers[i] = n + } + return providers +} + +// Provide teaches the container how to build values of one or more types and +// expresses their dependencies. +// +// The first argument of Provide is a function that accepts zero or more +// parameters and returns one or more results. The function may optionally +// return an error to indicate that it failed to build the value. This +// function will be treated as the constructor for all the types it returns. +// This function will be called AT MOST ONCE when a type produced by it, or a +// type that consumes this function's output, is requested via Invoke. If the +// same types are requested multiple times, the previously produced value will +// be reused. +// +// In addition to accepting constructors that accept dependencies as separate +// arguments and produce results as separate return values, Provide also +// accepts constructors that specify dependencies as dig.In structs and/or +// specify results as dig.Out structs. +func (c *Container) Provide(constructor interface{}, opts ...ProvideOption) error { + ctype := reflect.TypeOf(constructor) + if ctype == nil { + return errors.New("can't provide an untyped nil") + } + if ctype.Kind() != reflect.Func { + return fmt.Errorf("must provide constructor function, got %v (type %v)", constructor, ctype) + } + + var options provideOptions + for _, o := range opts { + o.applyProvideOption(&options) + } + if err := options.Validate(); err != nil { + return err + } + + if err := c.provide(constructor, options); err != nil { + return errProvide{ + Func: digreflect.InspectFunc(constructor), + Reason: err, + } + } + return nil +} + +// Invoke runs the given function after instantiating its dependencies. +// +// Any arguments that the function has are treated as its dependencies. The +// dependencies are instantiated in an unspecified order along with any +// dependencies that they might have. +// +// The function may return an error to indicate failure. The error will be +// returned to the caller as-is. +func (c *Container) Invoke(function interface{}, opts ...InvokeOption) error { + ftype := reflect.TypeOf(function) + if ftype == nil { + return errors.New("can't invoke an untyped nil") + } + if ftype.Kind() != reflect.Func { + return fmt.Errorf("can't invoke non-function %v (type %v)", function, ftype) + } + + pl, err := newParamList(ftype) + if err != nil { + return err + } + + if err := shallowCheckDependencies(c, pl); err != nil { + return errMissingDependencies{ + Func: digreflect.InspectFunc(function), + Reason: err, + } + } + + if !c.isVerifiedAcyclic { + if err := c.verifyAcyclic(); err != nil { + return err + } + } + + args, err := pl.BuildList(c) + if err != nil { + return errArgumentsFailed{ + Func: digreflect.InspectFunc(function), + Reason: err, + } + } + + returned := reflect.ValueOf(function).Call(args) + if len(returned) == 0 { + return nil + } + if last := returned[len(returned)-1]; isError(last.Type()) { + if err, _ := last.Interface().(error); err != nil { + return err + } + } + return nil +} + +func (c *Container) verifyAcyclic() error { + visited := make(map[key]struct{}) + for _, n := range c.nodes { + if err := detectCycles(n, c, nil /* path */, visited); err != nil { + return errWrapf(err, "cycle detected in dependency graph") + } + } + + c.isVerifiedAcyclic = true + return nil +} + +func (c *Container) provide(ctor interface{}, opts provideOptions) error { + n, err := newNode( + ctor, + nodeOptions{ + ResultName: opts.Name, + ResultGroup: opts.Group, + }, + ) + if err != nil { + return err + } + + keys, err := c.findAndValidateResults(n) + if err != nil { + return err + } + + ctype := reflect.TypeOf(ctor) + if len(keys) == 0 { + return fmt.Errorf("%v must provide at least one non-error type", ctype) + } + + for k := range keys { + c.isVerifiedAcyclic = false + oldProviders := c.providers[k] + c.providers[k] = append(c.providers[k], n) + + if c.deferAcyclicVerification { + continue + } + if err := verifyAcyclic(c, n, k); err != nil { + c.providers[k] = oldProviders + return err + } + c.isVerifiedAcyclic = true + } + + c.nodes = append(c.nodes, n) + + return nil +} + +// Builds a collection of all result types produced by this node. +func (c *Container) findAndValidateResults(n *node) (map[key]struct{}, error) { + var err error + keyPaths := make(map[key]string) + walkResult(n.ResultList(), connectionVisitor{ + c: c, + n: n, + err: &err, + keyPaths: keyPaths, + }) + + if err != nil { + return nil, err + } + + keys := make(map[key]struct{}, len(keyPaths)) + for k := range keyPaths { + keys[k] = struct{}{} + } + return keys, nil +} + +// Visits the results of a node and compiles a collection of all the keys +// produced by that node. +type connectionVisitor struct { + c *Container + n *node + + // If this points to a non-nil value, we've already encountered an error + // and should stop traversing. + err *error + + // Map of keys provided to path that provided this. The path is a string + // documenting which positional return value or dig.Out attribute is + // providing this particular key. + // + // For example, "[0].Foo" indicates that the value was provided by the Foo + // attribute of the dig.Out returned as the first result of the + // constructor. + keyPaths map[key]string + + // We track the path to the current result here. For example, this will + // be, ["[1]", "Foo", "Bar"] when we're visiting Bar in, + // + // func() (io.Writer, struct { + // dig.Out + // + // Foo struct { + // dig.Out + // + // Bar io.Reader + // } + // }) + currentResultPath []string +} + +func (cv connectionVisitor) AnnotateWithField(f resultObjectField) resultVisitor { + cv.currentResultPath = append(cv.currentResultPath, f.FieldName) + return cv +} + +func (cv connectionVisitor) AnnotateWithPosition(i int) resultVisitor { + cv.currentResultPath = append(cv.currentResultPath, fmt.Sprintf("[%d]", i)) + return cv +} + +func (cv connectionVisitor) Visit(res result) resultVisitor { + // Already failed. Stop looking. + if *cv.err != nil { + return nil + } + + path := strings.Join(cv.currentResultPath, ".") + + switch r := res.(type) { + case resultSingle: + k := key{name: r.Name, t: r.Type} + + if conflict, ok := cv.keyPaths[k]; ok { + *cv.err = fmt.Errorf( + "cannot provide %v from %v: already provided by %v", + k, path, conflict) + return nil + } + + if ps := cv.c.providers[k]; len(ps) > 0 { + cons := make([]string, len(ps)) + for i, p := range ps { + cons[i] = fmt.Sprint(p.Location()) + } + + *cv.err = fmt.Errorf( + "cannot provide %v from %v: already provided by %v", + k, path, strings.Join(cons, "; ")) + return nil + } + + cv.keyPaths[k] = path + + case resultGrouped: + // we don't really care about the path for this since conflicts are + // okay for group results. We'll track it for the sake of having a + // value there. + k := key{group: r.Group, t: r.Type} + cv.keyPaths[k] = path + } + + return cv +} + +// node is a node in the dependency graph. Each node maps to a single +// constructor provided by the user. +// +// Nodes can produce zero or more values that they store into the container. +// For the Provide path, we verify that nodes produce at least one value, +// otherwise the function will never be called. +type node struct { + ctor interface{} + ctype reflect.Type + + // Location where this function was defined. + location *digreflect.Func + + // id uniquely identifies the constructor that produces a node. + id dot.CtorID + + // Whether the constructor owned by this node was already called. + called bool + + // Type information about constructor parameters. + paramList paramList + + // Type information about constructor results. + resultList resultList +} + +type nodeOptions struct { + // If specified, all values produced by this node have the provided name + // or belong to the specified value group + ResultName string + ResultGroup string +} + +func newNode(ctor interface{}, opts nodeOptions) (*node, error) { + cval := reflect.ValueOf(ctor) + ctype := cval.Type() + cptr := cval.Pointer() + + params, err := newParamList(ctype) + if err != nil { + return nil, err + } + + results, err := newResultList( + ctype, + resultOptions{ + Name: opts.ResultName, + Group: opts.ResultGroup, + }, + ) + if err != nil { + return nil, err + } + + return &node{ + ctor: ctor, + ctype: ctype, + location: digreflect.InspectFunc(ctor), + id: dot.CtorID(cptr), + paramList: params, + resultList: results, + }, err +} + +func (n *node) Location() *digreflect.Func { return n.location } +func (n *node) ParamList() paramList { return n.paramList } +func (n *node) ResultList() resultList { return n.resultList } +func (n *node) ID() dot.CtorID { return n.id } + +// Call calls this node's constructor if it hasn't already been called and +// injects any values produced by it into the provided container. +func (n *node) Call(c containerStore) error { + if n.called { + return nil + } + + if err := shallowCheckDependencies(c, n.paramList); err != nil { + return errMissingDependencies{ + Func: n.location, + Reason: err, + } + } + + args, err := n.paramList.BuildList(c) + if err != nil { + return errArgumentsFailed{ + Func: n.location, + Reason: err, + } + } + + receiver := newStagingContainerWriter() + results := reflect.ValueOf(n.ctor).Call(args) + if err := n.resultList.ExtractList(receiver, results); err != nil { + return errConstructorFailed{Func: n.location, Reason: err} + } + receiver.Commit(c) + n.called = true + return nil +} + +// Checks if a field of an In struct is optional. +func isFieldOptional(f reflect.StructField) (bool, error) { + tag := f.Tag.Get(_optionalTag) + if tag == "" { + return false, nil + } + + optional, err := strconv.ParseBool(tag) + if err != nil { + err = errWrapf(err, + "invalid value %q for %q tag on field %v", + tag, _optionalTag, f.Name) + } + + return optional, err +} + +// Checks that all direct dependencies of the provided param are present in +// the container. Returns an error if not. +func shallowCheckDependencies(c containerStore, p param) error { + var missing errMissingManyTypes + var addMissingNodes []*dot.Param + walkParam(p, paramVisitorFunc(func(p param) bool { + ps, ok := p.(paramSingle) + if !ok { + return true + } + + if ns := c.getValueProviders(ps.Name, ps.Type); len(ns) == 0 && !ps.Optional { + missing = append(missing, newErrMissingType(c, key{name: ps.Name, t: ps.Type})) + addMissingNodes = append(addMissingNodes, ps.DotParam()...) + } + + return true + })) + + if len(missing) > 0 { + return missing + } + return nil +} + +// stagingContainerWriter is a containerWriter that records the changes that +// would be made to a containerWriter and defers them until Commit is called. +type stagingContainerWriter struct { + values map[key]reflect.Value + groups map[key][]reflect.Value +} + +var _ containerWriter = (*stagingContainerWriter)(nil) + +func newStagingContainerWriter() *stagingContainerWriter { + return &stagingContainerWriter{ + values: make(map[key]reflect.Value), + groups: make(map[key][]reflect.Value), + } +} + +func (sr *stagingContainerWriter) setValue(name string, t reflect.Type, v reflect.Value) { + sr.values[key{t: t, name: name}] = v +} + +func (sr *stagingContainerWriter) submitGroupedValue(group string, t reflect.Type, v reflect.Value) { + k := key{t: t, group: group} + sr.groups[k] = append(sr.groups[k], v) +} + +// Commit commits the received results to the provided containerWriter. +func (sr *stagingContainerWriter) Commit(cw containerWriter) { + for k, v := range sr.values { + cw.setValue(k.name, k.t, v) + } + + for k, vs := range sr.groups { + for _, v := range vs { + cw.submitGroupedValue(k.group, k.t, v) + } + } +} + +type byTypeName []reflect.Type + +func (bs byTypeName) Len() int { + return len(bs) +} + +func (bs byTypeName) Less(i int, j int) bool { + return fmt.Sprint(bs[i]) < fmt.Sprint(bs[j]) +} + +func (bs byTypeName) Swap(i int, j int) { + bs[i], bs[j] = bs[j], bs[i] +} + +func shuffledCopy(rand *rand.Rand, items []reflect.Value) []reflect.Value { + newItems := make([]reflect.Value, len(items)) + for i, j := range rand.Perm(len(items)) { + newItems[i] = items[j] + } + return newItems +} diff --git a/vendor/go.uber.org/dig/doc.go b/vendor/go.uber.org/dig/doc.go new file mode 100644 index 00000000..f1172b5c --- /dev/null +++ b/vendor/go.uber.org/dig/doc.go @@ -0,0 +1,334 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package dig provides an opinionated way of resolving object dependencies. +// +// Status +// +// STABLE. No breaking changes will be made in this major version. +// +// Container +// +// Dig exposes type Container as an object capable of resolving a directed +// acyclic dependency graph. Use the New function to create one. +// +// c := dig.New() +// +// Provide +// +// Constructors for different types are added to the container by using the +// Provide method. A constructor can declare a dependency on another type by +// simply adding it as a function parameter. Dependencies for a type can be +// added to the graph both, before and after the type was added. +// +// err := c.Provide(func(conn *sql.DB) (*UserGateway, error) { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// if err := c.Provide(newDBConnection); err != nil { +// // ... +// } +// +// Multiple constructors can rely on the same type. The container creates a +// singleton for each retained type, instantiating it at most once when +// requested directly or as a dependency of another type. +// +// err := c.Provide(func(conn *sql.DB) *CommentGateway { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// Constructors can declare any number of dependencies as parameters and +// optionally, return errors. +// +// err := c.Provide(func(u *UserGateway, c *CommentGateway) (*RequestHandler, error) { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// if err := c.Provide(newHTTPServer); err != nil { +// // ... +// } +// +// Constructors can also return multiple results to add multiple types to the +// container. +// +// err := c.Provide(func(conn *sql.DB) (*UserGateway, *CommentGateway, error) { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// Constructors that accept a variadic number of arguments are treated as if +// they don't have those arguments. That is, +// +// func NewVoteGateway(db *sql.DB, options ...Option) *VoteGateway +// +// Is treated the same as, +// +// func NewVoteGateway(db *sql.DB) *VoteGateway +// +// The constructor will be called with all other dependencies and no variadic +// arguments. +// +// Invoke +// +// Types added to to the container may be consumed by using the Invoke method. +// Invoke accepts any function that accepts one or more parameters and +// optionally, returns an error. Dig calls the function with the requested +// type, instantiating only those types that were requested by the function. +// The call fails if any type or its dependencies (both direct and transitive) +// were not available in the container. +// +// err := c.Invoke(func(l *log.Logger) { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// err := c.Invoke(func(server *http.Server) error { +// // ... +// }) +// if err != nil { +// // ... +// } +// +// Any error returned by the invoked function is propagated back to the +// caller. +// +// Parameter Objects +// +// Constructors declare their dependencies as function parameters. This can +// very quickly become unreadable if the constructor has a lot of +// dependencies. +// +// func NewHandler(users *UserGateway, comments *CommentGateway, posts *PostGateway, votes *VoteGateway, authz *AuthZGateway) *Handler { +// // ... +// } +// +// A pattern employed to improve readability in a situation like this is to +// create a struct that lists all the parameters of the function as fields and +// changing the function to accept that struct instead. This is referred to as +// a parameter object. +// +// Dig has first class support for parameter objects: any struct embedding +// dig.In gets treated as a parameter object. The following is equivalent to +// the constructor above. +// +// type HandlerParams struct { +// dig.In +// +// Users *UserGateway +// Comments *CommentGateway +// Posts *PostGateway +// Votes *VoteGateway +// AuthZ *AuthZGateway +// } +// +// func NewHandler(p HandlerParams) *Handler { +// // ... +// } +// +// Handlers can receive any combination of parameter objects and parameters. +// +// func NewHandler(p HandlerParams, l *log.Logger) *Handler { +// // ... +// } +// +// Result Objects +// +// Result objects are the flip side of parameter objects. These are structs +// that represent multiple outputs from a single function as fields in the +// struct. Structs embedding dig.Out get treated as result objects. +// +// func SetupGateways(conn *sql.DB) (*UserGateway, *CommentGateway, *PostGateway, error) { +// // ... +// } +// +// The above is equivalent to, +// +// type Gateways struct { +// dig.Out +// +// Users *UserGateway +// Comments *CommentGateway +// Posts *PostGateway +// } +// +// func SetupGateways(conn *sql.DB) (Gateways, error) { +// // ... +// } +// +// Optional Dependencies +// +// Constructors often don't have a hard dependency on some types and +// are able to operate in a degraded state when that dependency is missing. +// Dig supports declaring dependencies as optional by adding an +// `optional:"true"` tag to fields of a dig.In struct. +// +// Fields in a dig.In structs that have the `optional:"true"` tag are treated +// as optional by Dig. +// +// type UserGatewayParams struct { +// dig.In +// +// Conn *sql.DB +// Cache *redis.Client `optional:"true"` +// } +// +// If an optional field is not available in the container, the constructor +// will receive a zero value for the field. +// +// func NewUserGateway(p UserGatewayParams, log *log.Logger) (*UserGateway, error) { +// if p.Cache != nil { +// log.Print("Logging disabled") +// } +// // ... +// } +// +// Constructors that declare dependencies as optional MUST handle the case of +// those dependencies being absent. +// +// The optional tag also allows adding new dependencies without breaking +// existing consumers of the constructor. +// +// Named Values +// +// Some use cases call for multiple values of the same type. Dig allows adding +// multiple values of the same type to the container with the use of Named +// Values. +// +// Named Values can be produced by passing the dig.Name option when a +// constructor is provided. All values produced by that constructor will have +// the given name. +// +// Given the following constructors, +// +// func NewReadOnlyConnection(...) (*sql.DB, error) +// func NewReadWriteConnection(...) (*sql.DB, error) +// +// You can provide *sql.DB into a Container under different names by passing +// the dig.Name option. +// +// c.Provide(NewReadOnlyConnection, dig.Name("ro")) +// c.Provide(NewReadWriteConnection, dig.Name("rw")) +// +// Alternatively, you can produce a dig.Out struct and tag its fields with +// `name:".."` to have the corresponding value added to the graph under the +// specified name. +// +// type ConnectionResult struct { +// dig.Out +// +// ReadWrite *sql.DB `name:"rw"` +// ReadOnly *sql.DB `name:"ro"` +// } +// +// func ConnectToDatabase(...) (ConnectionResult, error) { +// // ... +// return ConnectionResult{ReadWrite: rw, ReadOnly: ro}, nil +// } +// +// Regardless of how a Named Value was produced, it can be consumed by another +// constructor by accepting a dig.In struct which has exported fields with the +// same name AND type that you provided. +// +// type GatewayParams struct { +// dig.In +// +// WriteToConn *sql.DB `name:"rw"` +// ReadFromConn *sql.DB `name:"ro"` +// } +// +// The name tag may be combined with the optional tag to declare the +// dependency optional. +// +// type GatewayParams struct { +// dig.In +// +// WriteToConn *sql.DB `name:"rw"` +// ReadFromConn *sql.DB `name:"ro" optional:"true"` +// } +// +// func NewCommentGateway(p GatewayParams, log *log.Logger) (*CommentGateway, error) { +// if p.ReadFromConn == nil { +// log.Print("Warning: Using RW connection for reads") +// p.ReadFromConn = p.WriteToConn +// } +// // ... +// } +// +// Value Groups +// +// Added in Dig 1.2. +// +// Dig provides value groups to allow producing and consuming many values of +// the same type. Value groups allow constructors to send values to a named, +// unordered collection in the container. Other constructors can request all +// values in this collection as a slice. +// +// Constructors can send values into value groups by returning a dig.Out +// struct tagged with `group:".."`. +// +// type HandlerResult struct { +// dig.Out +// +// Handler Handler `group:"server"` +// } +// +// func NewHelloHandler() HandlerResult { +// .. +// } +// +// func NewEchoHandler() HandlerResult { +// .. +// } +// +// Any number of constructors may provide values to this named collection. +// Other constructors can request all values for this collection by requesting +// a slice tagged with `group:".."`. This will execute all constructors that +// provide a value to that group in an unspecified order. +// +// type ServerParams struct { +// dig.In +// +// Handlers []Handler `group:"server"` +// } +// +// func NewServer(p ServerParams) *Server { +// server := newServer() +// for _, h := range p.Handlers { +// server.Register(h) +// } +// return server +// } +// +// Note that values in a value group are unordered. Dig makes no guarantees +// about the order in which these values will be produced. +package dig // import "go.uber.org/dig" diff --git a/vendor/go.uber.org/dig/error.go b/vendor/go.uber.org/dig/error.go new file mode 100644 index 00000000..6bf3d012 --- /dev/null +++ b/vendor/go.uber.org/dig/error.go @@ -0,0 +1,324 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "bytes" + "fmt" + "reflect" + "sort" + + "go.uber.org/dig/internal/digreflect" + "go.uber.org/dig/internal/dot" +) + +// Errors which know their underlying cause should implement this interface to +// be compatible with RootCause. +// +// We use an unexported "cause" method instead of "Cause" because we don't +// want dig-internal causes to be confused with the cause of the user-provided +// errors. (For example, if the users are using github.com/pkg/errors.) +type causer interface { + cause() error +} + +// RootCause returns the original error that caused the provided dig failure. +// +// RootCause may be used on errors returned by Invoke to get the original +// error returned by a constructor or invoked function. +func RootCause(err error) error { + for { + if e, ok := err.(causer); ok { + err = e.cause() + } else { + return err + } + } +} + +// errWrapf wraps an existing error with more contextual information. +// +// The given error is treated as the cause of the returned error (see causer). +// +// RootCause(errWrapf(errWrapf(err, ...), ...)) == err +// +// Use errWrapf instead of fmt.Errorf if the message ends with ": ". +func errWrapf(err error, msg string, args ...interface{}) error { + if err == nil { + return nil + } + + if len(args) > 0 { + msg = fmt.Sprintf(msg, args...) + } + + return wrappedError{err: err, msg: msg} +} + +type wrappedError struct { + err error + msg string +} + +func (e wrappedError) cause() error { return e.err } + +func (e wrappedError) Error() string { + return fmt.Sprintf("%v: %v", e.msg, e.err) +} + +// errProvide is returned when a constructor could not be Provided into the +// container. +type errProvide struct { + Func *digreflect.Func + Reason error +} + +func (e errProvide) cause() error { return e.Reason } + +func (e errProvide) Error() string { + return fmt.Sprintf("function %v cannot be provided: %v", e.Func, e.Reason) +} + +// errConstructorFailed is returned when a user-provided constructor failed +// with a non-nil error. +type errConstructorFailed struct { + Func *digreflect.Func + Reason error +} + +func (e errConstructorFailed) cause() error { return e.Reason } + +func (e errConstructorFailed) Error() string { + return fmt.Sprintf("function %v returned a non-nil error: %v", e.Func, e.Reason) +} + +// errArgumentsFailed is returned when a function could not be run because one +// of its dependencies failed to build for any reason. +type errArgumentsFailed struct { + Func *digreflect.Func + Reason error +} + +func (e errArgumentsFailed) cause() error { return e.Reason } + +func (e errArgumentsFailed) Error() string { + return fmt.Sprintf("could not build arguments for function %v: %v", e.Func, e.Reason) +} + +// errMissingDependencies is returned when the dependencies of a function are +// not available in the container. +type errMissingDependencies struct { + Func *digreflect.Func + Reason error +} + +func (e errMissingDependencies) cause() error { return e.Reason } + +func (e errMissingDependencies) Error() string { + return fmt.Sprintf("missing dependencies for function %v: %v", e.Func, e.Reason) +} + +// errParamSingleFailed is returned when a paramSingle could not be built. +type errParamSingleFailed struct { + Key key + Reason error + CtorID dot.CtorID +} + +func (e errParamSingleFailed) cause() error { return e.Reason } + +func (e errParamSingleFailed) Error() string { + return fmt.Sprintf("failed to build %v: %v", e.Key, e.Reason) +} + +func (e errParamSingleFailed) updateGraph(g *dot.Graph) { + failed := &dot.Result{ + Node: &dot.Node{ + Name: e.Key.name, + Group: e.Key.group, + Type: e.Key.t, + }, + } + g.FailNodes([]*dot.Result{failed}, e.CtorID) +} + +// errParamGroupFailed is returned when a value group cannot be built because +// any of the values in the group failed to build. +type errParamGroupFailed struct { + Key key + Reason error + CtorID dot.CtorID +} + +func (e errParamGroupFailed) cause() error { return e.Reason } + +func (e errParamGroupFailed) Error() string { + return fmt.Sprintf("could not build value group %v: %v", e.Key, e.Reason) +} + +func (e errParamGroupFailed) updateGraph(g *dot.Graph) { + g.FailGroupNodes(e.Key.group, e.Key.t, e.CtorID) +} + +// errMissingType is returned when a single value that was expected in the +// container was not available. +type errMissingType struct { + Key key + + // If non-empty, we will include suggestions for what the user may have + // meant. + suggestions []key +} + +func newErrMissingType(c containerStore, k key) errMissingType { + // Possible types we will look for in the container. We will always look + // for pointers to the requested type and some extras on a per-Kind basis. + + suggestions := []reflect.Type{reflect.PtrTo(k.t)} + if k.t.Kind() == reflect.Ptr { + // The user requested a pointer but maybe we have a value. + suggestions = append(suggestions, k.t.Elem()) + } + + knownTypes := c.knownTypes() + if k.t.Kind() == reflect.Interface { + // Maybe we have an implementation of the interface. + for _, t := range knownTypes { + if t.Implements(k.t) { + suggestions = append(suggestions, t) + } + } + } else { + // Maybe we have an interface that this type implements. + for _, t := range knownTypes { + if t.Kind() == reflect.Interface { + if k.t.Implements(t) { + suggestions = append(suggestions, t) + } + } + } + } + + // range through c.providers is non-deterministic. Let's sort the list of + // suggestions. + sort.Sort(byTypeName(suggestions)) + + err := errMissingType{Key: k} + for _, t := range suggestions { + if len(c.getValueProviders(k.name, t)) > 0 { + k.t = t + err.suggestions = append(err.suggestions, k) + } + } + + return err +} + +func (e errMissingType) Error() string { + // Sample messages: + // + // type io.Reader is not in the container, did you mean to Provide it? + // type io.Reader is not in the container, did you mean to use one of *bytes.Buffer, *MyBuffer + // type bytes.Buffer is not in the container, did you mean to use *bytes.Buffer? + // type *foo[name="bar"] is not in the container, did you mean to use foo[name="bar"]? + + b := new(bytes.Buffer) + + fmt.Fprintf(b, "type %v is not in the container", e.Key) + switch len(e.suggestions) { + case 0: + b.WriteString(", did you mean to Provide it?") + case 1: + fmt.Fprintf(b, ", did you mean to use %v?", e.suggestions[0]) + default: + b.WriteString(", did you mean to use one of ") + for i, k := range e.suggestions { + if i > 0 { + b.WriteString(", ") + if i == len(e.suggestions)-1 { + b.WriteString("or ") + } + } + fmt.Fprint(b, k) + } + b.WriteString("?") + } + + return b.String() +} + +// errMissingManyTypes combines multiple errMissingType errors. +type errMissingManyTypes []errMissingType // length must be non-zero + +func (e errMissingManyTypes) Error() string { + if len(e) == 1 { + return e[0].Error() + } + + b := new(bytes.Buffer) + + b.WriteString("the following types are not in the container: ") + for i, err := range e { + if i > 0 { + b.WriteString("; ") + } + fmt.Fprintf(b, "%v", err.Key) + switch len(err.suggestions) { + case 0: + // do nothing + case 1: + fmt.Fprintf(b, " (did you mean %v?)", err.suggestions[0]) + default: + b.WriteString(" (did you mean ") + for i, k := range err.suggestions { + if i > 0 { + b.WriteString(", ") + if i == len(err.suggestions)-1 { + b.WriteString("or ") + } + } + fmt.Fprint(b, k) + } + b.WriteString("?)") + } + } + + return b.String() +} + +func (e errMissingManyTypes) updateGraph(g *dot.Graph) { + missing := make([]*dot.Result, len(e)) + + for i, err := range e { + missing[i] = &dot.Result{ + Node: &dot.Node{ + Name: err.Key.name, + Group: err.Key.group, + Type: err.Key.t, + }, + } + } + g.AddMissingNodes(missing) +} + +type errVisualizer interface { + updateGraph(*dot.Graph) +} diff --git a/vendor/go.uber.org/dig/glide.lock b/vendor/go.uber.org/dig/glide.lock new file mode 100644 index 00000000..f9d27846 --- /dev/null +++ b/vendor/go.uber.org/dig/glide.lock @@ -0,0 +1,17 @@ +hash: b6270b9f130f8c89f82156ca8d44cb16a3311c7a04746f2805f02c2f72bb58ec +updated: 2017-10-25T09:30:43.315666535-07:00 +imports: [] +testImports: +- name: github.com/davecgh/go-spew + version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/testify + version: d77da356e56a7428ad25149ca77381849a6a5232 + subpackages: + - assert + - require diff --git a/vendor/go.uber.org/dig/glide.yaml b/vendor/go.uber.org/dig/glide.yaml new file mode 100644 index 00000000..972b804c --- /dev/null +++ b/vendor/go.uber.org/dig/glide.yaml @@ -0,0 +1,7 @@ +package: go.uber.org/dig +license: MIT +testImport: +- package: github.com/stretchr/testify + subpackages: + - assert + - require diff --git a/vendor/go.uber.org/dig/graph.go b/vendor/go.uber.org/dig/graph.go new file mode 100644 index 00000000..dd8e8229 --- /dev/null +++ b/vendor/go.uber.org/dig/graph.go @@ -0,0 +1,179 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "io" + "strconv" + "text/template" + + "go.uber.org/dig/internal/dot" +) + +// A VisualizeOption modifies the default behavior of Visualize. +type VisualizeOption interface { + applyVisualizeOption(*visualizeOptions) +} + +type visualizeOptions struct { + VisualizeError error +} + +type visualizeOptionFunc func(*visualizeOptions) + +func (f visualizeOptionFunc) applyVisualizeOption(opts *visualizeOptions) { f(opts) } + +// VisualizeError includes a visualization of the given error in the output of +// Visualize if an error was returned by Invoke or Provide. +// +// if err := c.Provide(...); err != nil { +// dig.Visualize(c, w, dig.VisualizeError(err)) +// } +// +// This option has no effect if the error was nil or if it didn't contain any +// information to visualize. +func VisualizeError(err error) VisualizeOption { + return visualizeOptionFunc(func(opts *visualizeOptions) { + opts.VisualizeError = err + }) +} + +func updateGraph(dg *dot.Graph, err error) error { + var errors []errVisualizer + // Unwrap error to find the root cause. + for { + if ev, ok := err.(errVisualizer); ok { + errors = append(errors, ev) + } + e, ok := err.(causer) + if !ok { + break + } + err = e.cause() + } + + // If there are no errVisualizers included, we do not modify the graph. + if len(errors) == 0 { + return nil + } + + // We iterate in reverse because the last element is the root cause. + for i := len(errors) - 1; i >= 0; i-- { + errors[i].updateGraph(dg) + } + + // Remove non-error entries from the graph for readability. + dg.PruneSuccess() + + return nil +} + +var _graphTmpl = template.Must( + template.New("DotGraph"). + Funcs(template.FuncMap{ + "quote": strconv.Quote, + }). + Parse(`digraph { + rankdir=RL; + graph [compound=true]; + {{range $g := .Groups}} + {{- quote .String}} [{{.Attributes}}]; + {{range .Results}} + {{- quote $g.String}} -> {{quote .String}}; + {{end}} + {{end -}} + {{range $index, $ctor := .Ctors}} + subgraph cluster_{{$index}} { + constructor_{{$index}} [shape=plaintext label={{quote .Name}}]; + {{with .ErrorType}}color={{.Color}};{{end}} + {{range .Results}} + {{- quote .String}} [{{.Attributes}}]; + {{end}} + } + {{range .Params}} + constructor_{{$index}} -> {{quote .String}} [ltail=cluster_{{$index}}{{if .Optional}} style=dashed{{end}}]; + {{end}} + {{range .GroupParams}} + constructor_{{$index}} -> {{quote .String}} [ltail=cluster_{{$index}}]; + {{end -}} + {{end}} + {{range .Failed.TransitiveFailures}} + {{- quote .String}} [color=orange]; + {{end -}} + {{range .Failed.RootCauses}} + {{- quote .String}} [color=red]; + {{end}} +}`)) + +// Visualize parses the graph in Container c into DOT format and writes it to +// io.Writer w. +func Visualize(c *Container, w io.Writer, opts ...VisualizeOption) error { + dg := c.createGraph() + + var options visualizeOptions + for _, o := range opts { + o.applyVisualizeOption(&options) + } + + if options.VisualizeError != nil { + if err := updateGraph(dg, options.VisualizeError); err != nil { + return err + } + } + + return _graphTmpl.Execute(w, dg) +} + +// CanVisualizeError returns true if the error is an errVisualizer. +func CanVisualizeError(err error) bool { + for { + if _, ok := err.(errVisualizer); ok { + return true + } + e, ok := err.(causer) + if !ok { + break + } + err = e.cause() + } + + return false +} + +func (c *Container) createGraph() *dot.Graph { + dg := dot.NewGraph() + + for _, n := range c.nodes { + dg.AddCtor(newDotCtor(n), n.paramList.DotParam(), n.resultList.DotResult()) + } + + return dg +} + +func newDotCtor(n *node) *dot.Ctor { + return &dot.Ctor{ + ID: n.id, + Name: n.location.Name, + Package: n.location.Package, + File: n.location.File, + Line: n.location.Line, + } +} diff --git a/vendor/go.uber.org/dig/internal/digreflect/func.go b/vendor/go.uber.org/dig/internal/digreflect/func.go new file mode 100644 index 00000000..05758ce5 --- /dev/null +++ b/vendor/go.uber.org/dig/internal/digreflect/func.go @@ -0,0 +1,103 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package digreflect + +import ( + "fmt" + "net/url" + "reflect" + "runtime" + "strings" +) + +// Func contains runtime information about a function. +type Func struct { + // Name of the function. + Name string + + // Name of the package in which this function is defined. + Package string + + // Path to the file in which this function is defined. + File string + + // Line number in the file at which this function is defined. + Line int +} + +// String returns a string representation of the function. +func (f *Func) String() string { + // "path/to/package".MyFunction (path/to/file.go:42) + return fmt.Sprintf("%q.%v (%v:%v)", f.Package, f.Name, f.File, f.Line) +} + +// InspectFunc inspects and returns runtime information about the given +// function. +func InspectFunc(function interface{}) *Func { + fptr := reflect.ValueOf(function).Pointer() + f := runtime.FuncForPC(fptr) + pkgName, funcName := splitFuncName(f.Name()) + fileName, lineNum := f.FileLine(fptr) + return &Func{ + Name: funcName, + Package: pkgName, + File: fileName, + Line: lineNum, + } +} + +const _vendor = "/vendor/" + +func splitFuncName(function string) (pname string, fname string) { + if len(function) == 0 { + return + } + + // We have something like "path.to/my/pkg.MyFunction". If the function is + // a closure, it is something like, "path.to/my/pkg.MyFunction.func1". + + idx := 0 + + // Everything up to the first "." after the last "/" is the package name. + // Everything after the "." is the full function name. + if i := strings.LastIndex(function, "/"); i >= 0 { + idx = i + } + if i := strings.Index(function[idx:], "."); i >= 0 { + idx += i + } + pname, fname = function[:idx], function[idx+1:] + + // The package may be vendored. + if i := strings.Index(pname, _vendor); i > 0 { + pname = pname[i+len(_vendor):] + } + + // Package names are URL-encoded to avoid ambiguity in the case where the + // package name contains ".git". Otherwise, "foo/bar.git.MyFunction" would + // mean that "git" is the top-level function and "MyFunction" is embedded + // inside it. + if unescaped, err := url.QueryUnescape(pname); err == nil { + pname = unescaped + } + + return +} diff --git a/vendor/go.uber.org/dig/internal/dot/README.md b/vendor/go.uber.org/dig/internal/dot/README.md new file mode 100644 index 00000000..1198ade5 --- /dev/null +++ b/vendor/go.uber.org/dig/internal/dot/README.md @@ -0,0 +1,61 @@ +# Dot + +The dot module generates a DOT file representation of a dependency graph. + +## Interpreting the graph + +The graph should be read from left to right. The leftmost node in the graph (the root node) depends +on its dependency tree to the right. An arrow from node_a to node_b in the graph means that node_b +is consumed by node_a and that node_b is a parameter of node_a. The rendered graph holds the +following kinds of nodes, + +**Nodes:** + +- *Constructors* [Rectangles]: Takes parameters and produces results. +- *Results* [Ovals]: Results inside a constructor are produced by that constructor. Results are consumed +directly by other constructors and/or part of a group of results. +- *Groups* [Diamonds]: Represent value groups in [fx](https://godoc.org/go.uber.org/fx). Multiple results can form a group. Any +result linked to a group by an edge are members of that group. A group is a collection of results. +Groups can also be parameters of constructors. + +**Edges:** + +- *Solid Arrows*: An arrow from node_a to node_b means that node_b is a parameter of node_a and that +node_a depends on node_b. +- *Dashed Arrows*: A dashed arrow from node_a to node_b represents an optional dependency that node_a +has on node_b. + +**Graph Colors:** + +- *Red*: Graph nodes are the root cause failures. +- *Orange*: Graph nodes are the transitive failures. + +## Testing and verifying changes + +Unit tests and visualize golden tests are run with + +```shell +$ make test +``` + +You can visualize the effect of your code changes by visualizing generated test graphs as pngs. + +In the dig root directory, generate the graph DOT files with respect to your latest code changes. + +```shell +$ go test -generate +``` + +Assuming that you have [graphviz](https://www.graphviz.org/) installed and are in the testdata directory, +generate a png image representation of a graph for viewing. + +```shell +$ dot -Tpng ${name_of_dot_file_in_testdata}.dot -o ${name_of_dot_file_in_testdata}.png +$ open ${name_of_dot_file_in_testdata}.png +``` + +## Graph Pruning + +If dot.Visualize is used to visualize an error graph, non-failing nodes are pruned out of the graph +to make the error graph more readable to the user. Pruning increases readability since successful +nodes clutter the graph and do not help the user debug errors. diff --git a/vendor/go.uber.org/dig/internal/dot/graph.go b/vendor/go.uber.org/dig/internal/dot/graph.go new file mode 100644 index 00000000..3706fa11 --- /dev/null +++ b/vendor/go.uber.org/dig/internal/dot/graph.go @@ -0,0 +1,466 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dot + +import ( + "fmt" + "reflect" +) + +// ErrorType of a constructor or group is updated when they fail to build. +type ErrorType int + +const ( + noError ErrorType = iota + rootCause + transitiveFailure +) + +// CtorID is a unique numeric identifier for constructors. +type CtorID uintptr + +// Ctor encodes a constructor provided to the container for the DOT graph. +type Ctor struct { + Name string + Package string + File string + Line int + ID CtorID + Params []*Param + GroupParams []*Group + Results []*Result + ErrorType ErrorType +} + +// removeParam deletes the dependency on the provided result's nodeKey. +// This is used to prune links to results of deleted constructors. +func (c *Ctor) removeParam(k nodeKey) { + var pruned []*Param + for _, p := range c.Params { + if k != p.nodeKey() { + pruned = append(pruned, p) + } + } + c.Params = pruned +} + +type nodeKey struct { + t reflect.Type + name string + group string +} + +// Node is a single node in a graph and is embedded into Params and Results. +type Node struct { + Type reflect.Type + Name string + Group string +} + +func (n *Node) nodeKey() nodeKey { + return nodeKey{t: n.Type, name: n.Name, group: n.Group} +} + +// Param is a parameter node in the graph. Parameters are the input to constructors. +type Param struct { + *Node + + Optional bool +} + +// Result is a result node in the graph. Results are the output of constructors. +type Result struct { + *Node + + // GroupIndex is added to differentiate grouped values from one another. + // Since grouped values have the same type and group, their Node / string + // representations are the same so we need indices to uniquely identify + // the values. + GroupIndex int +} + +// Group is a group node in the graph. Group represents an fx value group. +type Group struct { + // Type is the type of values in the group. + Type reflect.Type + Name string + Results []*Result + ErrorType ErrorType +} + +func (g *Group) nodeKey() nodeKey { + return nodeKey{t: g.Type, group: g.Name} +} + +// TODO(rhang): Avoid linear search to discover group results that should be pruned. +func (g *Group) removeResult(r *Result) { + var pruned []*Result + for _, rg := range g.Results { + if r.GroupIndex != rg.GroupIndex { + pruned = append(pruned, rg) + } + } + g.Results = pruned +} + +// Graph is the DOT-format graph in a Container. +type Graph struct { + Ctors []*Ctor + ctorMap map[CtorID]*Ctor + + Groups []*Group + groupMap map[nodeKey]*Group + + consumers map[nodeKey][]*Ctor + + Failed *FailedNodes +} + +// FailedNodes is the nodes that failed in the graph. +type FailedNodes struct { + // RootCauses is a list of the point of failures. They are the root causes + // of failed invokes and can be either missing types (not provided) or + // error types (error providing). + RootCauses []*Result + + // TransitiveFailures is the list of nodes that failed to build due to + // missing/failed dependencies. + TransitiveFailures []*Result + + // ctors is a collection of failed constructors IDs that are populated as the graph is + // traversed for errors. + ctors map[CtorID]struct{} + + // Groups is a collection of failed groupKeys that is populated as the graph is traversed + // for errors. + groups map[nodeKey]struct{} +} + +// NewGraph creates an empty graph. +func NewGraph() *Graph { + return &Graph{ + ctorMap: make(map[CtorID]*Ctor), + groupMap: make(map[nodeKey]*Group), + consumers: make(map[nodeKey][]*Ctor), + Failed: &FailedNodes{ + ctors: make(map[CtorID]struct{}), + groups: make(map[nodeKey]struct{}), + }, + } +} + +// NewGroup creates a new group with information in the groupKey. +func NewGroup(k nodeKey) *Group { + return &Group{ + Type: k.t, + Name: k.group, + } +} + +// AddCtor adds the constructor with paramList and resultList into the graph. +func (dg *Graph) AddCtor(c *Ctor, paramList []*Param, resultList []*Result) { + var ( + params []*Param + groupParams []*Group + ) + + // Loop through the paramList to separate them into regular params and + // grouped params. For grouped params, we use getGroup to find the actual + // group. + for _, param := range paramList { + if param.Group == "" { + // Not a value group. + params = append(params, param) + continue + } + + k := nodeKey{t: param.Type.Elem(), group: param.Group} + group := dg.getGroup(k) + groupParams = append(groupParams, group) + } + + for _, result := range resultList { + // If the result is a grouped value, we want to update its GroupIndex + // and add it to the Group. + if result.Group != "" { + dg.addToGroup(result, c.ID) + } + } + + c.Params = params + c.GroupParams = groupParams + c.Results = resultList + + // Track which constructors consume a parameter. + for _, p := range paramList { + k := p.nodeKey() + dg.consumers[k] = append(dg.consumers[k], c) + } + + dg.Ctors = append(dg.Ctors, c) + dg.ctorMap[c.ID] = c +} + +func (dg *Graph) failNode(r *Result, isRootCause bool) { + if isRootCause { + dg.addRootCause(r) + } else { + dg.addTransitiveFailure(r) + } +} + +// AddMissingNodes adds missing nodes to the list of failed Results in the graph. +func (dg *Graph) AddMissingNodes(results []*Result) { + // The failure(s) are root causes if there are no other failures. + isRootCause := len(dg.Failed.RootCauses) == 0 + + for _, r := range results { + dg.failNode(r, isRootCause) + } +} + +// FailNodes adds results to the list of failed Results in the graph, and +// updates the state of the constructor with the given id accordingly. +func (dg *Graph) FailNodes(results []*Result, id CtorID) { + // This failure is the root cause if there are no other failures. + isRootCause := len(dg.Failed.RootCauses) == 0 + dg.Failed.ctors[id] = struct{}{} + + for _, r := range results { + dg.failNode(r, isRootCause) + } + + if c, ok := dg.ctorMap[id]; ok { + if isRootCause { + c.ErrorType = rootCause + } else { + c.ErrorType = transitiveFailure + } + } +} + +// FailGroupNodes finds and adds the failed grouped nodes to the list of failed +// Results in the graph, and updates the state of the group and constructor +// with the given id accordingly. +func (dg *Graph) FailGroupNodes(name string, t reflect.Type, id CtorID) { + // This failure is the root cause if there are no other failures. + isRootCause := len(dg.Failed.RootCauses) == 0 + + k := nodeKey{t: t, group: name} + group := dg.getGroup(k) + + // If the ctor does not exist it cannot be failed. + if _, ok := dg.ctorMap[id]; !ok { + return + } + + // Track which constructors and groups have failed. + dg.Failed.ctors[id] = struct{}{} + dg.Failed.groups[k] = struct{}{} + + for _, r := range dg.ctorMap[id].Results { + if r.Type == t && r.Group == name { + dg.failNode(r, isRootCause) + } + } + + if c, ok := dg.ctorMap[id]; ok { + if isRootCause { + group.ErrorType = rootCause + c.ErrorType = rootCause + } else { + group.ErrorType = transitiveFailure + c.ErrorType = transitiveFailure + } + } +} + +// getGroup finds the group by nodeKey from the graph. If it is not available, +// a new group is created and returned. +func (dg *Graph) getGroup(k nodeKey) *Group { + g, ok := dg.groupMap[k] + if !ok { + g = NewGroup(k) + dg.groupMap[k] = g + dg.Groups = append(dg.Groups, g) + } + return g +} + +// addToGroup adds a newly provided grouped result to the appropriate group. +func (dg *Graph) addToGroup(r *Result, id CtorID) { + k := nodeKey{t: r.Type, group: r.Group} + group := dg.getGroup(k) + + r.GroupIndex = len(group.Results) + group.Results = append(group.Results, r) +} + +// PruneSuccess removes elements from the graph that do not have failed results. +// Removing elements that do not have failing results makes the graph easier to debug, +// since non-failing nodes and edges can clutter the graph and don't help the user debug. +func (dg *Graph) PruneSuccess() { + dg.pruneCtors(dg.Failed.ctors) + dg.pruneGroups(dg.Failed.groups) +} + +// pruneCtors removes constructors from the graph that do not have failing Results. +func (dg *Graph) pruneCtors(failed map[CtorID]struct{}) { + var pruned []*Ctor + for _, c := range dg.Ctors { + if _, ok := failed[c.ID]; ok { + pruned = append(pruned, c) + continue + } + // If a constructor is deleted, the constructor's stale result references need to + // be removed from that result's Group and/or consuming constructor. + dg.pruneCtorParams(c, dg.consumers) + dg.pruneGroupResults(c, dg.groupMap) + delete(dg.ctorMap, c.ID) + } + + dg.Ctors = pruned +} + +// pruneGroups removes groups from the graph that do not have failing results. +func (dg *Graph) pruneGroups(failed map[nodeKey]struct{}) { + var pruned []*Group + for _, g := range dg.Groups { + k := g.nodeKey() + if _, ok := failed[k]; ok { + pruned = append(pruned, g) + continue + } + delete(dg.groupMap, k) + } + dg.Groups = pruned + + dg.pruneCtorGroupParams(dg.groupMap) +} + +// pruneCtorParams removes results of the constructor argument that are still referenced in the +// Params of constructors that consume those results. If the results in the constructor are found +// in the params of a consuming constructor that result should be removed. +func (dg *Graph) pruneCtorParams(c *Ctor, consumers map[nodeKey][]*Ctor) { + for _, r := range c.Results { + for _, ctor := range consumers[r.nodeKey()] { + ctor.removeParam(r.nodeKey()) + } + } +} + +// pruneCtorGroupParams removes constructor results that are still referenced in the GroupParams of +// constructors that consume those results. +func (dg *Graph) pruneCtorGroupParams(groups map[nodeKey]*Group) { + for _, c := range dg.Ctors { + var pruned []*Group + for _, gp := range c.GroupParams { + k := gp.nodeKey() + if _, ok := groups[k]; ok { + pruned = append(pruned, gp) + } + } + c.GroupParams = pruned + } +} + +// pruneGroupResults removes results of the constructor argument that are still referenced in +// the Group object that contains that result. If a group no longer exists references to that +// should should be removed. +func (dg *Graph) pruneGroupResults(c *Ctor, groups map[nodeKey]*Group) { + for _, r := range c.Results { + k := r.nodeKey() + if k.group == "" { + continue + } + + g, ok := groups[k] + if ok { + g.removeResult(r) + } + } +} + +// String implements fmt.Stringer for Param. +func (p *Param) String() string { + if p.Name != "" { + return fmt.Sprintf("%v[name=%v]", p.Type.String(), p.Name) + } + return p.Type.String() +} + +// String implements fmt.Stringer for Result. +func (r *Result) String() string { + switch { + case r.Name != "": + return fmt.Sprintf("%v[name=%v]", r.Type.String(), r.Name) + case r.Group != "": + return fmt.Sprintf("%v[group=%v]%v", r.Type.String(), r.Group, r.GroupIndex) + default: + return r.Type.String() + } +} + +// String implements fmt.Stringer for Group. +func (g *Group) String() string { + return fmt.Sprintf("[type=%v group=%v]", g.Type.String(), g.Name) +} + +// Attributes composes and returns a string of the Result node's attributes. +func (r *Result) Attributes() string { + switch { + case r.Name != "": + return fmt.Sprintf(`label=<%v
Name: %v>`, r.Type, r.Name) + case r.Group != "": + return fmt.Sprintf(`label=<%v
Group: %v>`, r.Type, r.Group) + default: + return fmt.Sprintf(`label=<%v>`, r.Type) + } +} + +// Attributes composes and returns a string of the Group node's attributes. +func (g *Group) Attributes() string { + attr := fmt.Sprintf(`shape=diamond label=<%v
Group: %v>`, g.Type, g.Name) + if g.ErrorType != noError { + attr += " color=" + g.ErrorType.Color() + } + return attr +} + +// Color returns the color representation of each ErrorType. +func (s ErrorType) Color() string { + switch s { + case rootCause: + return "red" + case transitiveFailure: + return "orange" + default: + return "black" + } +} + +func (dg *Graph) addRootCause(r *Result) { + dg.Failed.RootCauses = append(dg.Failed.RootCauses, r) +} + +func (dg *Graph) addTransitiveFailure(r *Result) { + dg.Failed.TransitiveFailures = append(dg.Failed.TransitiveFailures, r) +} diff --git a/vendor/go.uber.org/dig/param.go b/vendor/go.uber.org/dig/param.go new file mode 100644 index 00000000..4daa4135 --- /dev/null +++ b/vendor/go.uber.org/dig/param.go @@ -0,0 +1,454 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "errors" + "fmt" + "reflect" + + "go.uber.org/dig/internal/dot" +) + +// The param interface represents a dependency for a constructor. +// +// The following implementations exist: +// paramList All arguments of the constructor. +// paramSingle An explicitly requested type. +// paramObject dig.In struct where each field in the struct can be another +// param. +// paramGroupedSlice +// A slice consuming a value group. This will receive all +// values produced with a `group:".."` tag with the same name +// as a slice. +type param interface { + fmt.Stringer + + // Builds this dependency and any of its dependencies from the provided + // Container. + // + // This MAY panic if the param does not produce a single value. + Build(containerStore) (reflect.Value, error) + + // DotParam returns a slice of dot.Param(s). + DotParam() []*dot.Param +} + +var ( + _ param = paramSingle{} + _ param = paramObject{} + _ param = paramList{} + _ param = paramGroupedSlice{} +) + +// newParam builds a param from the given type. If the provided type is a +// dig.In struct, an paramObject will be returned. +func newParam(t reflect.Type) (param, error) { + switch { + case IsOut(t) || (t.Kind() == reflect.Ptr && IsOut(t.Elem())) || embedsType(t, _outPtrType): + return nil, fmt.Errorf("cannot depend on result objects: %v embeds a dig.Out", t) + case IsIn(t): + return newParamObject(t) + case embedsType(t, _inPtrType): + return nil, fmt.Errorf( + "cannot build a parameter object by embedding *dig.In, embed dig.In instead: "+ + "%v embeds *dig.In", t) + case t.Kind() == reflect.Ptr && IsIn(t.Elem()): + return nil, fmt.Errorf( + "cannot depend on a pointer to a parameter object, use a value instead: "+ + "%v is a pointer to a struct that embeds dig.In", t) + default: + return paramSingle{Type: t}, nil + } +} + +// paramVisitor visits every param in a param tree, allowing tracking state at +// each level. +type paramVisitor interface { + // Visit is called on the param being visited. + // + // If Visit returns a non-nil paramVisitor, that paramVisitor visits all + // the child params of this param. + Visit(param) paramVisitor + + // We can implement AnnotateWithField and AnnotateWithPosition like + // resultVisitor if we need to track that information in the future. +} + +// paramVisitorFunc is a paramVisitor that visits param in a tree with the +// return value deciding whether the descendants of this param should be +// recursed into. +type paramVisitorFunc func(param) (recurse bool) + +func (f paramVisitorFunc) Visit(p param) paramVisitor { + if f(p) { + return f + } + return nil +} + +// walkParam walks the param tree for the given param with the provided +// visitor. +// +// paramVisitor.Visit will be called on the provided param and if a non-nil +// paramVisitor is received, this param's descendants will be walked with that +// visitor. +// +// This is very similar to how go/ast.Walk works. +func walkParam(p param, v paramVisitor) { + v = v.Visit(p) + if v == nil { + return + } + + switch par := p.(type) { + case paramSingle, paramGroupedSlice: + // No sub-results + case paramObject: + for _, f := range par.Fields { + walkParam(f.Param, v) + } + case paramList: + for _, p := range par.Params { + walkParam(p, v) + } + default: + panic(fmt.Sprintf( + "It looks like you have found a bug in dig. "+ + "Please file an issue at https://github.com/uber-go/dig/issues/ "+ + "and provide the following message: "+ + "received unknown param type %T", p)) + } +} + +// paramList holds all arguments of the constructor as params. +// +// NOTE: Build() MUST NOT be called on paramList. Instead, BuildList +// must be called. +type paramList struct { + ctype reflect.Type // type of the constructor + + Params []param +} + +func (pl paramList) DotParam() []*dot.Param { + var types []*dot.Param + for _, param := range pl.Params { + types = append(types, param.DotParam()...) + } + return types +} + +// newParamList builds a paramList from the provided constructor type. +// +// Variadic arguments of a constructor are ignored and not included as +// dependencies. +func newParamList(ctype reflect.Type) (paramList, error) { + numArgs := ctype.NumIn() + if ctype.IsVariadic() { + // NOTE: If the function is variadic, we skip the last argument + // because we're not filling variadic arguments yet. See #120. + numArgs-- + } + + pl := paramList{ + ctype: ctype, + Params: make([]param, 0, numArgs), + } + + for i := 0; i < numArgs; i++ { + p, err := newParam(ctype.In(i)) + if err != nil { + return pl, errWrapf(err, "bad argument %d", i+1) + } + pl.Params = append(pl.Params, p) + } + + return pl, nil +} + +func (pl paramList) Build(containerStore) (reflect.Value, error) { + panic("It looks like you have found a bug in dig. " + + "Please file an issue at https://github.com/uber-go/dig/issues/ " + + "and provide the following message: " + + "paramList.Build() must never be called") +} + +// BuildList returns an ordered list of values which may be passed directly +// to the underlying constructor. +func (pl paramList) BuildList(c containerStore) ([]reflect.Value, error) { + args := make([]reflect.Value, len(pl.Params)) + for i, p := range pl.Params { + var err error + args[i], err = p.Build(c) + if err != nil { + return nil, err + } + } + return args, nil +} + +// paramSingle is an explicitly requested type, optionally with a name. +// +// This object must be present in the graph as-is unless it's specified as +// optional. +type paramSingle struct { + Name string + Optional bool + Type reflect.Type +} + +func (ps paramSingle) DotParam() []*dot.Param { + return []*dot.Param{ + { + Node: &dot.Node{ + Type: ps.Type, + Name: ps.Name, + }, + Optional: ps.Optional, + }, + } +} + +func (ps paramSingle) Build(c containerStore) (reflect.Value, error) { + if v, ok := c.getValue(ps.Name, ps.Type); ok { + return v, nil + } + + providers := c.getValueProviders(ps.Name, ps.Type) + if len(providers) == 0 { + if ps.Optional { + return reflect.Zero(ps.Type), nil + } + return _noValue, newErrMissingType(c, key{name: ps.Name, t: ps.Type}) + } + + for _, n := range providers { + err := n.Call(c) + if err == nil { + continue + } + + // If we're missing dependencies but the parameter itself is optional, + // we can just move on. + if _, ok := err.(errMissingDependencies); ok && ps.Optional { + return reflect.Zero(ps.Type), nil + } + + return _noValue, errParamSingleFailed{ + CtorID: n.ID(), + Key: key{t: ps.Type, name: ps.Name}, + Reason: err, + } + } + + // If we get here, it's impossible for the value to be absent from the + // container. + v, _ := c.getValue(ps.Name, ps.Type) + return v, nil +} + +// paramObject is a dig.In struct where each field is another param. +// +// This object is not expected in the graph as-is. +type paramObject struct { + Type reflect.Type + Fields []paramObjectField +} + +func (po paramObject) DotParam() []*dot.Param { + var types []*dot.Param + for _, field := range po.Fields { + types = append(types, field.DotParam()...) + } + return types +} + +// newParamObject builds an paramObject from the provided type. The type MUST +// be a dig.In struct. +func newParamObject(t reflect.Type) (paramObject, error) { + po := paramObject{Type: t} + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type == _inType { + // Skip over the dig.In embed. + continue + } + + pof, err := newParamObjectField(i, f) + if err != nil { + return po, errWrapf(err, "bad field %q of %v", f.Name, t) + } + + po.Fields = append(po.Fields, pof) + } + + return po, nil +} + +func (po paramObject) Build(c containerStore) (reflect.Value, error) { + dest := reflect.New(po.Type).Elem() + for _, f := range po.Fields { + v, err := f.Build(c) + if err != nil { + return dest, err + } + dest.Field(f.FieldIndex).Set(v) + } + return dest, nil +} + +// paramObjectField is a single field of a dig.In struct. +type paramObjectField struct { + // Name of the field in the struct. + FieldName string + + // Index of this field in the target struct. + // + // We need to track this separately because not all fields of the + // struct map to params. + FieldIndex int + + // The dependency requested by this field. + Param param +} + +func (pof paramObjectField) DotParam() []*dot.Param { + return pof.Param.DotParam() +} + +func newParamObjectField(idx int, f reflect.StructField) (paramObjectField, error) { + pof := paramObjectField{ + FieldName: f.Name, + FieldIndex: idx, + } + + var p param + switch { + case f.PkgPath != "": + return pof, fmt.Errorf( + "unexported fields not allowed in dig.In, did you mean to export %q (%v)?", + f.Name, f.Type) + + case f.Tag.Get(_groupTag) != "": + var err error + p, err = newParamGroupedSlice(f) + if err != nil { + return pof, err + } + + default: + var err error + p, err = newParam(f.Type) + if err != nil { + return pof, err + } + } + + if ps, ok := p.(paramSingle); ok { + ps.Name = f.Tag.Get(_nameTag) + + var err error + ps.Optional, err = isFieldOptional(f) + if err != nil { + return pof, err + } + + p = ps + } + + pof.Param = p + return pof, nil +} + +func (pof paramObjectField) Build(c containerStore) (reflect.Value, error) { + v, err := pof.Param.Build(c) + if err != nil { + return v, err + } + return v, nil +} + +// paramGroupedSlice is a param which produces a slice of values with the same +// group name. +type paramGroupedSlice struct { + // Name of the group as specified in the `group:".."` tag. + Group string + + // Type of the slice. + Type reflect.Type +} + +func (pt paramGroupedSlice) DotParam() []*dot.Param { + return []*dot.Param{ + { + Node: &dot.Node{ + Type: pt.Type, + Group: pt.Group, + }, + }, + } +} + +// newParamGroupedSlice builds a paramGroupedSlice from the provided type with +// the given name. +// +// The type MUST be a slice type. +func newParamGroupedSlice(f reflect.StructField) (paramGroupedSlice, error) { + pg := paramGroupedSlice{Group: f.Tag.Get(_groupTag), Type: f.Type} + + name := f.Tag.Get(_nameTag) + optional, _ := isFieldOptional(f) + switch { + case f.Type.Kind() != reflect.Slice: + return pg, fmt.Errorf("value groups may be consumed as slices only: "+ + "field %q (%v) is not a slice", f.Name, f.Type) + case name != "": + return pg, fmt.Errorf( + "cannot use named values with value groups: name:%q requested with group:%q", name, pg.Group) + + case optional: + return pg, errors.New("value groups cannot be optional") + } + + return pg, nil +} + +func (pt paramGroupedSlice) Build(c containerStore) (reflect.Value, error) { + for _, n := range c.getGroupProviders(pt.Group, pt.Type.Elem()) { + if err := n.Call(c); err != nil { + return _noValue, errParamGroupFailed{ + CtorID: n.ID(), + Key: key{group: pt.Group, t: pt.Type.Elem()}, + Reason: err, + } + } + } + + items := c.getValueGroup(pt.Group, pt.Type.Elem()) + + result := reflect.MakeSlice(pt.Type, len(items), len(items)) + for i, v := range items { + result.Index(i).Set(v) + } + return result, nil +} diff --git a/vendor/go.uber.org/dig/result.go b/vendor/go.uber.org/dig/result.go new file mode 100644 index 00000000..d113e260 --- /dev/null +++ b/vendor/go.uber.org/dig/result.go @@ -0,0 +1,406 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "errors" + "fmt" + "reflect" + + "go.uber.org/dig/internal/dot" +) + +// The result interface represents a result produced by a constructor. +// +// The following implementations exist: +// resultList All values returned by the constructor. +// resultSingle A single value produced by a constructor. +// resultObject dig.Out struct where each field in the struct can be +// another result. +// resultGrouped A value produced by a constructor that is part of a value +// group. +type result interface { + // Extracts the values for this result from the provided value and + // stores them into the provided containerWriter. + // + // This MAY panic if the result does not consume a single value. + Extract(containerWriter, reflect.Value) + + // DotResult returns a slice of dot.Result(s). + DotResult() []*dot.Result +} + +var ( + _ result = resultSingle{} + _ result = resultObject{} + _ result = resultList{} + _ result = resultGrouped{} +) + +type resultOptions struct { + // If set, this is the name of the associated result value. + // + // For Result Objects, name:".." tags on fields override this. + Name string + Group string +} + +// newResult builds a result from the given type. +func newResult(t reflect.Type, opts resultOptions) (result, error) { + switch { + case IsIn(t) || (t.Kind() == reflect.Ptr && IsIn(t.Elem())) || embedsType(t, _inPtrType): + return nil, fmt.Errorf("cannot provide parameter objects: %v embeds a dig.In", t) + case isError(t): + return nil, fmt.Errorf("cannot return an error here, return it from the constructor instead") + case IsOut(t): + return newResultObject(t, opts) + case embedsType(t, _outPtrType): + return nil, fmt.Errorf( + "cannot build a result object by embedding *dig.Out, embed dig.Out instead: "+ + "%v embeds *dig.Out", t) + case t.Kind() == reflect.Ptr && IsOut(t.Elem()): + return nil, fmt.Errorf( + "cannot return a pointer to a result object, use a value instead: "+ + "%v is a pointer to a struct that embeds dig.Out", t) + case len(opts.Group) > 0: + return resultGrouped{Type: t, Group: opts.Group}, nil + default: + return resultSingle{Type: t, Name: opts.Name}, nil + } +} + +// resultVisitor visits every result in a result tree, allowing tracking state +// at each level. +type resultVisitor interface { + // Visit is called on the result being visited. + // + // If Visit returns a non-nil resultVisitor, that resultVisitor visits all + // the child results of this result. + Visit(result) resultVisitor + + // AnnotateWithField is called on each field of a resultObject after + // visiting it but before walking its descendants. + // + // The same resultVisitor is used for all fields: the one returned upon + // visiting the resultObject. + // + // For each visited field, if AnnotateWithField returns a non-nil + // resultVisitor, it will be used to walk the result of that field. + AnnotateWithField(resultObjectField) resultVisitor + + // AnnotateWithPosition is called with the index of each result of a + // resultList after vising it but before walking its descendants. + // + // The same resultVisitor is used for all results: the one returned upon + // visiting the resultList. + // + // For each position, if AnnotateWithPosition returns a non-nil + // resultVisitor, it will be used to walk the result at that index. + AnnotateWithPosition(idx int) resultVisitor +} + +// walkResult walks the result tree for the given result with the provided +// visitor. +// +// resultVisitor.Visit will be called on the provided result and if a non-nil +// resultVisitor is received, it will be used to walk its descendants. If a +// resultObject or resultList was visited, AnnotateWithField and +// AnnotateWithPosition respectively will be called before visiting the +// descendants of that resultObject/resultList. +// +// This is very similar to how go/ast.Walk works. +func walkResult(r result, v resultVisitor) { + v = v.Visit(r) + if v == nil { + return + } + + switch res := r.(type) { + case resultSingle, resultGrouped: + // No sub-results + case resultObject: + w := v + for _, f := range res.Fields { + if v := w.AnnotateWithField(f); v != nil { + walkResult(f.Result, v) + } + } + case resultList: + w := v + for i, r := range res.Results { + if v := w.AnnotateWithPosition(i); v != nil { + walkResult(r, v) + } + } + default: + panic(fmt.Sprintf( + "It looks like you have found a bug in dig. "+ + "Please file an issue at https://github.com/uber-go/dig/issues/ "+ + "and provide the following message: "+ + "received unknown result type %T", res)) + } +} + +// resultList holds all values returned by the constructor as results. +type resultList struct { + ctype reflect.Type + + Results []result + + // For each item at index i returned by the constructor, resultIndexes[i] + // is the index in .Results for the corresponding result object. + // resultIndexes[i] is -1 for errors returned by constructors. + resultIndexes []int +} + +func (rl resultList) DotResult() []*dot.Result { + var types []*dot.Result + for _, result := range rl.Results { + types = append(types, result.DotResult()...) + } + return types +} + +func newResultList(ctype reflect.Type, opts resultOptions) (resultList, error) { + rl := resultList{ + ctype: ctype, + Results: make([]result, 0, ctype.NumOut()), + resultIndexes: make([]int, ctype.NumOut()), + } + + resultIdx := 0 + for i := 0; i < ctype.NumOut(); i++ { + t := ctype.Out(i) + if isError(t) { + rl.resultIndexes[i] = -1 + continue + } + + r, err := newResult(t, opts) + if err != nil { + return rl, errWrapf(err, "bad result %d", i+1) + } + + rl.Results = append(rl.Results, r) + rl.resultIndexes[i] = resultIdx + resultIdx++ + } + + return rl, nil +} + +func (resultList) Extract(containerWriter, reflect.Value) { + panic("It looks like you have found a bug in dig. " + + "Please file an issue at https://github.com/uber-go/dig/issues/ " + + "and provide the following message: " + + "resultList.Extract() must never be called") +} + +func (rl resultList) ExtractList(cw containerWriter, values []reflect.Value) error { + for i, v := range values { + if resultIdx := rl.resultIndexes[i]; resultIdx >= 0 { + rl.Results[resultIdx].Extract(cw, v) + continue + } + + if err, _ := v.Interface().(error); err != nil { + return err + } + } + + return nil +} + +// resultSingle is an explicit value produced by a constructor, optionally +// with a name. +// +// This object will be added to the graph as-is. +type resultSingle struct { + Name string + Type reflect.Type +} + +func (rs resultSingle) DotResult() []*dot.Result { + return []*dot.Result{ + { + Node: &dot.Node{ + Type: rs.Type, + Name: rs.Name, + }, + }, + } +} + +func (rs resultSingle) Extract(cw containerWriter, v reflect.Value) { + cw.setValue(rs.Name, rs.Type, v) +} + +// resultObject is a dig.Out struct where each field is another result. +// +// This object is not added to the graph. Its fields are interpreted as +// results and added to the graph if needed. +type resultObject struct { + Type reflect.Type + Fields []resultObjectField +} + +func (ro resultObject) DotResult() []*dot.Result { + var types []*dot.Result + for _, field := range ro.Fields { + types = append(types, field.DotResult()...) + } + return types +} + +func newResultObject(t reflect.Type, opts resultOptions) (resultObject, error) { + ro := resultObject{Type: t} + if len(opts.Name) > 0 { + return ro, fmt.Errorf( + "cannot specify a name for result objects: %v embeds dig.Out", t) + } + + if len(opts.Group) > 0 { + return ro, fmt.Errorf( + "cannot specify a group for result objects: %v embeds dig.Out", t) + } + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type == _outType { + // Skip over the dig.Out embed. + continue + } + + rof, err := newResultObjectField(i, f, opts) + if err != nil { + return ro, errWrapf(err, "bad field %q of %v", f.Name, t) + } + + ro.Fields = append(ro.Fields, rof) + } + return ro, nil +} + +func (ro resultObject) Extract(cw containerWriter, v reflect.Value) { + for _, f := range ro.Fields { + f.Result.Extract(cw, v.Field(f.FieldIndex)) + } +} + +// resultObjectField is a single field inside a dig.Out struct. +type resultObjectField struct { + // Name of the field in the struct. + FieldName string + + // Index of the field in the struct. + // + // We need to track this separately because not all fields of the struct + // map to results. + FieldIndex int + + // Result produced by this field. + Result result +} + +func (rof resultObjectField) DotResult() []*dot.Result { + return rof.Result.DotResult() +} + +// newResultObjectField(i, f, opts) builds a resultObjectField from the field +// f at index i. +func newResultObjectField(idx int, f reflect.StructField, opts resultOptions) (resultObjectField, error) { + rof := resultObjectField{ + FieldName: f.Name, + FieldIndex: idx, + } + + var r result + switch { + case f.PkgPath != "": + return rof, fmt.Errorf( + "unexported fields not allowed in dig.Out, did you mean to export %q (%v)?", f.Name, f.Type) + + case f.Tag.Get(_groupTag) != "": + var err error + r, err = newResultGrouped(f) + if err != nil { + return rof, err + } + + default: + var err error + if name := f.Tag.Get(_nameTag); len(name) > 0 { + // can modify in-place because options are passed-by-value. + opts.Name = name + } + r, err = newResult(f.Type, opts) + if err != nil { + return rof, err + } + } + + rof.Result = r + return rof, nil +} + +// resultGrouped is a value produced by a constructor that is part of a result +// group. +// +// These will be produced as fields of a dig.Out struct. +type resultGrouped struct { + // Name of the group as specified in the `group:".."` tag. + Group string + + // Type of value produced. + Type reflect.Type +} + +func (rt resultGrouped) DotResult() []*dot.Result { + return []*dot.Result{ + { + Node: &dot.Node{ + Type: rt.Type, + Group: rt.Group, + }, + }, + } +} + +// newResultGrouped(f) builds a new resultGrouped from the provided field. +func newResultGrouped(f reflect.StructField) (resultGrouped, error) { + rg := resultGrouped{Group: f.Tag.Get(_groupTag), Type: f.Type} + + name := f.Tag.Get(_nameTag) + optional, _ := isFieldOptional(f) + switch { + case name != "": + return rg, fmt.Errorf( + "cannot use named values with value groups: name:%q provided with group:%q", name, rg.Group) + case optional: + return rg, errors.New("value groups cannot be optional") + } + + return rg, nil +} + +func (rt resultGrouped) Extract(cw containerWriter, v reflect.Value) { + cw.submitGroupedValue(rt.Group, rt.Type, v) +} diff --git a/vendor/go.uber.org/dig/stringer.go b/vendor/go.uber.org/dig/stringer.go new file mode 100644 index 00000000..d10fa0fb --- /dev/null +++ b/vendor/go.uber.org/dig/stringer.go @@ -0,0 +1,106 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "bytes" + "fmt" + "strings" +) + +// String representation of the entire Container +func (c *Container) String() string { + b := &bytes.Buffer{} + fmt.Fprintln(b, "nodes: {") + for k, vs := range c.providers { + for _, v := range vs { + fmt.Fprintln(b, "\t", k, "->", v) + } + } + fmt.Fprintln(b, "}") + + fmt.Fprintln(b, "values: {") + for k, v := range c.values { + fmt.Fprintln(b, "\t", k, "=>", v) + } + for k, vs := range c.groups { + for _, v := range vs { + fmt.Fprintln(b, "\t", k, "=>", v) + } + } + fmt.Fprintln(b, "}") + + return b.String() +} + +func (n *node) String() string { + return fmt.Sprintf("deps: %v, ctor: %v", n.paramList, n.ctype) +} + +func (k key) String() string { + if k.name != "" { + return fmt.Sprintf("%v[name=%q]", k.t, k.name) + } + if k.group != "" { + return fmt.Sprintf("%v[group=%q]", k.t, k.group) + } + return k.t.String() +} + +func (pl paramList) String() string { + args := make([]string, len(pl.Params)) + for i, p := range pl.Params { + args[i] = p.String() + } + return fmt.Sprint(args) +} + +func (sp paramSingle) String() string { + // tally.Scope[optional] means optional + // tally.Scope[optional, name="foo"] means named optional + + var opts []string + if sp.Optional { + opts = append(opts, "optional") + } + if sp.Name != "" { + opts = append(opts, fmt.Sprintf("name=%q", sp.Name)) + } + + if len(opts) == 0 { + return fmt.Sprint(sp.Type) + } + + return fmt.Sprintf("%v[%v]", sp.Type, strings.Join(opts, ", ")) +} + +func (op paramObject) String() string { + fields := make([]string, len(op.Fields)) + for i, f := range op.Fields { + fields[i] = f.Param.String() + } + return strings.Join(fields, " ") +} + +func (pt paramGroupedSlice) String() string { + // io.Reader[group="foo"] refers to a group of io.Readers called 'foo' + return fmt.Sprintf("%v[group=%q]", pt.Type.Elem(), pt.Group) +} diff --git a/vendor/go.uber.org/dig/types.go b/vendor/go.uber.org/dig/types.go new file mode 100644 index 00000000..8ab87ea5 --- /dev/null +++ b/vendor/go.uber.org/dig/types.go @@ -0,0 +1,159 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +import ( + "container/list" + "reflect" +) + +var ( + _noValue reflect.Value + _errType = reflect.TypeOf((*error)(nil)).Elem() + _inPtrType = reflect.TypeOf((*In)(nil)) + _inType = reflect.TypeOf(In{}) + _outPtrType = reflect.TypeOf((*Out)(nil)) + _outType = reflect.TypeOf(Out{}) +) + +// Special interface embedded inside dig sentinel values (dig.In, dig.Out) to +// make their special nature obvious in the godocs. Otherwise they will appear +// as plain empty structs. +type digSentinel interface { + digSentinel() +} + +// In may be embedded into structs to request dig to treat them as special +// parameter structs. When a constructor accepts such a struct, instead of the +// struct becoming a dependency for that constructor, all its fields become +// dependencies instead. See the section on Parameter Objects in the +// package-level documentation for more information. +// +// Fields of the struct may optionally be tagged to customize the behavior of +// dig. The following tags are supported, +// +// name Requests a value with the same name and type from the +// container. See Named Values for more information. +// optional If set to true, indicates that the dependency is optional and +// the constructor gracefully handles its absence. +// group Name of the Value Group from which this field will be filled. +// The field must be a slice type. See Value Groups in the +// package documentation for more information. +type In struct{ digSentinel } + +// Out is an embeddable type that signals to dig that the returned +// struct should be treated differently. Instead of the struct itself +// becoming part of the container, all members of the struct will. + +// Out may be embedded into structs to request dig to treat them as special +// result structs. When a constructor returns such a struct, instead of the +// struct becoming a result of the constructor, all its fields become results +// of the constructor. See the section on Result Objects in the package-level +// documentation for more information. +// +// Fields of the struct may optionally be tagged to customize the behavior of +// dig. The following tags are supported, +// +// name Specifies the name of the value. Only a field on a dig.In +// struct with the same 'name' annotation can receive this +// value. See Named Values for more information. +// group Name of the Value Group to which this field's value is being +// sent. See Value Groups in the package documentation for more +// information. +type Out struct{ digSentinel } + +func isError(t reflect.Type) bool { + return t.Implements(_errType) +} + +// IsIn checks whether the given struct is a dig.In struct. A struct qualifies +// as a dig.In struct if it embeds the dig.In type or if any struct that it +// embeds is a dig.In struct. The parameter may be the reflect.Type of the +// struct rather than the struct itself. +// +// A struct MUST qualify as a dig.In struct for its fields to be treated +// specially by dig. +// +// See the documentation for dig.In for a comprehensive list of supported +// tags. +func IsIn(o interface{}) bool { + return embedsType(o, _inType) +} + +// IsOut checks whether the given struct is a dig.Out struct. A struct +// qualifies as a dig.Out struct if it embeds the dig.Out type or if any +// struct that it embeds is a dig.Out struct. The parameter may be the +// reflect.Type of the struct rather than the struct itself. +// +// A struct MUST qualify as a dig.Out struct for its fields to be treated +// specially by dig. +// +// See the documentation for dig.Out for a comprehensive list of supported +// tags. +func IsOut(o interface{}) bool { + return embedsType(o, _outType) +} + +// Returns true if t embeds e or if any of the types embedded by t embed e. +func embedsType(i interface{}, e reflect.Type) bool { + // TODO: this function doesn't consider e being a pointer. + // given `type A foo { *In }`, this function would return false for + // embedding dig.In, which makes for some extra error checking in places + // that call this funciton. Might be worthwhile to consider reflect.Indirect + // usage to clean up the callers. + + if i == nil { + return false + } + + // maybe it's already a reflect.Type + t, ok := i.(reflect.Type) + if !ok { + // take the type if it's not + t = reflect.TypeOf(i) + } + + // We are going to do a breadth-first search of all embedded fields. + types := list.New() + types.PushBack(t) + for types.Len() > 0 { + t := types.Remove(types.Front()).(reflect.Type) + + if t == e { + return true + } + + if t.Kind() != reflect.Struct { + continue + } + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Anonymous { + types.PushBack(f.Type) + } + } + } + + // If perf is an issue, we can cache known In objects and Out objects in a + // map[reflect.Type]struct{}. + return false +} diff --git a/vendor/go.uber.org/dig/version.go b/vendor/go.uber.org/dig/version.go new file mode 100644 index 00000000..9bc5dd46 --- /dev/null +++ b/vendor/go.uber.org/dig/version.go @@ -0,0 +1,24 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package dig + +// Version of the library. +const Version = "1.7.0" diff --git a/vendor/go.uber.org/fx/.codecov.yml b/vendor/go.uber.org/fx/.codecov.yml new file mode 100644 index 00000000..2e90589d --- /dev/null +++ b/vendor/go.uber.org/fx/.codecov.yml @@ -0,0 +1,15 @@ + +coverage: + range: 80..100 + round: down + precision: 2 + + status: + project: # measuring the overall project coverage + default: # context, you can create multiple ones with custom titles + enabled: yes # must be yes|true to enable this status + target: 90% # specify the target coverage for each commit status + # option: "auto" (must increase from parent commit or pull request base) + # option: "X%" a static target percentage to hit + if_not_found: success # if parent is not found report status as success, error, or failure + if_ci_failed: error # if ci fails report status as success, error, or failure diff --git a/vendor/go.uber.org/fx/.gitignore b/vendor/go.uber.org/fx/.gitignore new file mode 100644 index 00000000..c6dced35 --- /dev/null +++ b/vendor/go.uber.org/fx/.gitignore @@ -0,0 +1,13 @@ +/vendor +/.bench +*.mem +*.cpu +*.test +*.log +*.out +*.html +*.coverprofile +coverage.txt +*.pprof +/.bin +/.cache diff --git a/vendor/go.uber.org/fx/.travis.yml b/vendor/go.uber.org/fx/.travis.yml new file mode 100644 index 00000000..c99e6332 --- /dev/null +++ b/vendor/go.uber.org/fx/.travis.yml @@ -0,0 +1,18 @@ +language: go +sudo: false + +go_import_path: go.uber.org/fx +go: + - "1.10.4" + - "1.11" + - tip + +cache: + directories: + - vendor + +install: + - make dependencies + +script: + - make ci diff --git a/vendor/go.uber.org/fx/CHANGELOG.md b/vendor/go.uber.org/fx/CHANGELOG.md new file mode 100644 index 00000000..af7647ca --- /dev/null +++ b/vendor/go.uber.org/fx/CHANGELOG.md @@ -0,0 +1,193 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [1.9.0] - 2019-01-22 +### Added +- Add the ability to shutdown Fx applications from inside the container. See + the Shutdowner documentation for details. +- Add `fx.Annotated` to allow users to provide named values without creating a + new constructor. + +## [1.8.0] - 2018-11-06 +### Added +- Provide DOT graph of dependencies in the container. + +## [1.7.1] - 2018-09-26 +### Fixed +- Make `fxtest.New` ensure that the app was created successfully. Previously, + it would return the app (similar to `fx.New`, which expects the user to verify + the error). +- Update dig container to defer acyclic validation until after Invoke. Application + startup time should improve proportional to the size of the dependency graph. +- Fix a goroutine leak in `fxtest.Lifecycle`. + +## [1.7.0] - 2018-08-16 +### Added +- Add `fx.ErrorHook` option to allow users to provide `ErrorHandler`s on invoke + failures. +- `VisualizeError` returns the visualization wrapped in the error if available. + +## [1.6.0] - 2018-06-12 +### Added +- Add `fx.Error` option to short-circuit application startup. + +## [1.5.0] - 2018-04-11 +### Added +- Add `fx.StartTimeout` and `fx.StopTimeout` to make configuring application + start and stop timeouts easier. +- Export the default start and stop timeout as `fx.DefaultTimeout`. + +### Fixed +- Make `fxtest` respect the application's start and stop timeouts. + +## [1.4.0] - 2017-12-07 +### Added +- Add `fx.Populate` to populate variables with values from the dependency + injection container without requiring intermediate structs. + +## [1.3.0] - 2017-11-28 +### Changed +- Improve readability of hook logging in addition to provide and invoke. + +### Fixed +- Fix bug which caused the OnStop for a lifecycle hook to be called even if it + failed to start. + +## [1.2.0] - 2017-09-06 +### Added +- Add `fx.NopLogger` which disables the Fx application's log output. + +## [1.1.0] - 2017-08-22 +### Changed +- Improve readability of start up logging. + +## [1.0.0] - 2017-07-31 +First stable release: no breaking changes will be made in the 1.x series. + +### Added +- `fx.Extract` now supports `fx.In` tags on target structs. + +### Changed +- **[Breaking]** Rename `fx.Inject` to `fx.Extract`. +- **[Breaking]** Rename `fxtest.Must*` to `fxtest.Require*`. + +### Removed +- **[Breaking]** Remove `fx.Timeout` and `fx.DefaultTimeout`. + +## [1.0.0-rc2] - 2017-07-21 + +- **[Breaking]** Lifecycle hooks now take a context. +- Add `fx.In` and `fx.Out` which exposes optional and named types. + Modules should embed these types instead of relying on `dig.In` and `dig.Out`. +- Add an `Err` method to retrieve the underlying errors during the dependency + graph construction. The same error is also returned from `Start`. +- Graph resolution now happens as part of `fx.New`, rather than at the beginning + of `app.Start`. This allows inspection of the graph errors through `app.Err()` + before the decision to start the app. +- Add a `Logger` option, which allows users to send Fx's logs to different + sink. +- Add `fxtest.App`, which redirects log output to the user's `testing.TB` and + provides some lifecycle helpers. + +## [1.0.0-rc1] - 2017-06-20 + +- **[Breaking]** Providing types into `fx.App` and invoking functions are now + options passed during application construction. This makes users' + interactions with modules and collections of modules identical. +- **[Breaking]** `TestLifecycle` is now in a separate `fxtest` subpackage. +- Add `fx.Inject()` to pull values from the container into a struct. + +## [1.0.0-beta4] - 2017-06-12 + +- **[Breaking]** Monolithic framework, as released in initial betas, has been + broken into smaller pieces as a result of recent advances in `dig` library. + This is a radical departure from the previous direction, but it needed to + be done for the long-term good of the project. +- **[Breaking]** `Module interface` has been scoped all the way down to being + *a single dig constructor*. This allows for very sophisticated module + compositions. See `go.uber.org/dig` for more information on the constructors. +- **[Breaking]** `package config` has been moved to its own repository. + see `go.uber.org/config` for more information. +- `fx.Lifecycle` has been added for modules to hook into the framework + lifecycle events. +- `service.Host` interface which composed a number of primitives together + (configuration, metrics, tracing) has been deprecated in favor of + `fx.App`. + +## [1.0.0-beta3] - 2017-03-28 + +- **[Breaking]** Environment config provider was removed. If you were using + environment variables to override YAML values, see + [config documentation](config/README.md) for more information. +- **[Breaking]** Simplify Provider interface: remove `Scope` method from the + `config.Provider` interface, one can use either ScopedProvider and Value.Get() + to access sub fields. +- Add `task.MustRegister` convenience function which fails fast by panicking + Note that this should only be used during app initialization, and is provided + to avoid repetetive error checking for services which register many tasks. +- Expose options on task module to disable execution. This will allow users to + enqueue and consume tasks on different clusters. +- **[Breaking]** Rename Backend interface `Publish` to `Enqueue`. Created a new + `ExecuteAsync` method that will kick off workers to consume tasks and this is + subsumed by module Start. +- **[Breaking]** Rename package `uhttp/client` to `uhttp/uhttpclient` for clarity. +- **[Breaking]** Rename `PopulateStruct` method in value to `Populate`. + The method can now populate not only structs, but anything: slices, + maps, builtin types and maps. +- **[Breaking]** `package dig` has moved from `go.uber.org/fx/dig` to a new home + at `go.uber.org/dig`. +- **[Breaking]** Pass a tracer the `uhttp/uhttpclient` constructor explicitly, instead + of using a global tracer. This will allow to use http client in parallel tests. + +## [1.0.0-beta2] - 2017-03-09 + +- **[Breaking]** Remove `ulog.Logger` interface and expose `*zap.Logger` directly. +- **[Breaking]** Rename config and module from `modules.rpc` to `modules.yarpc` +- **[Breaking]** Rename config key from `modules.http` to `modules.uhttp` to match + the module name +- **[Breaking]** Upgrade `zap` to `v1.0.0-rc.3` (now go.uber.org/zap, was + github.com/uber-go/zap) +- Remove now-unused `config.IsDevelopmentEnv()` helper to encourage better + testing practices. Not a breaking change as nobody is using this func + themselves according to our code search tool. +- Log `traceID` and `spanID` in hex format to match Jaeger UI. Upgrade Jaeger to + min version 2.1.0 + and use jaeger's adapters for jaeger and tally initialization. +- Tally now supports reporting histogram samples for a bucket. Upgrade Tally to 2.1.0 +- **[Breaking]** Make new module naming consistent `yarpc.ThriftModule` to + `yarpc.New`, `task.NewModule` + to `task.New` +- **[Breaking]** Rename `yarpc.CreateThriftServiceFunc` to `yarpc.ServiceCreateFunc` + as it is not thrift-specific. +- Report version metrics for company-wide version usage information. +- Allow configurable service name and module name via service options. +- DIG constructors now support returning a tuple with the second argument being + an error. + +## 1.0.0-beta1 - 2017-02-20 + +This is the first beta release of the framework, where we invite users to start +building services on it and provide us feedback. **Warning** we are not +promising API compatibility between beta releases and the final 1.0.0 release. +In fact, we expect our beta user feedback to require some changes to the way +things work. Once we reach 1.0, we will provider proper version compatibility. + +[1.9.0]: https://github.com/uber-go/fx/compare/v1.8.0...v1.9.0 +[1.8.0]: https://github.com/uber-go/fx/compare/v1.7.1...v1.8.0 +[1.7.1]: https://github.com/uber-go/fx/compare/v1.7.0...v1.7.1 +[1.7.0]: https://github.com/uber-go/fx/compare/v1.6.0...v1.7.0 +[1.6.0]: https://github.com/uber-go/fx/compare/v1.5.0...v1.6.0 +[1.5.0]: https://github.com/uber-go/fx/compare/v1.4.0...v1.5.0 +[1.4.0]: https://github.com/uber-go/fx/compare/v1.3.0...v1.4.0 +[1.3.0]: https://github.com/uber-go/fx/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/uber-go/fx/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/uber-go/fx/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/uber-go/fx/compare/v1.0.0-rc2...v1.0.0 +[1.0.0-rc2]: https://github.com/uber-go/fx/compare/v1.0.0-rc1...v1.0.0-rc2 +[1.0.0-rc1]: https://github.com/uber-go/fx/compare/v1.0.0-beta4...v1.0.0-rc1 +[1.0.0-beta4]: https://github.com/uber-go/fx/compare/v1.0.0-beta3...v1.0.0-beta4 +[1.0.0-beta3]: https://github.com/uber-go/fx/compare/v1.0.0-beta2...v1.0.0-beta3 +[1.0.0-beta2]: https://github.com/uber-go/fx/compare/v1.0.0-beta1...v1.0.0-beta2 diff --git a/vendor/go.uber.org/fx/CONTRIBUTING.md b/vendor/go.uber.org/fx/CONTRIBUTING.md new file mode 100644 index 00000000..8458a900 --- /dev/null +++ b/vendor/go.uber.org/fx/CONTRIBUTING.md @@ -0,0 +1,79 @@ +# Contributing + +Thanks for helping to make Fx better for everyone! + +If you'd like to add new exported APIs, please [open an issue][open-issue] +describing your proposal — discussing API changes ahead of time makes +pull request review much smoother. + +Note that you'll need to sign [Uber's Contributor License Agreement][cla] +before we can accept any of your contributions. If necessary, a bot will remind +you to accept the CLA when you open your pull request. + +## Setup + +[Fork][fork], then clone the repository: + +``` +mkdir -p $GOPATH/src/go.uber.org +cd $GOPATH/src/go.uber.org +git clone git@github.com:your_github_username/fx.git +cd fx +git remote add upstream https://github.com/uber-go/fx.git +git fetch upstream +``` + +Install Fx's dependencies: + +``` +make dependencies +``` + +Make sure that the tests and the style checkers pass: + +``` +make test +make lint +``` + +For `make lint` to work, you must be using the minor version of Go specified in +the Makefile's `LINTABLE_MINOR_VERSIONS` variable. This is fine, but it means +that you'll only discover style violations after you open your pull request. + +## Making changes + +Start by creating a new branch for your changes: + +``` +cd $GOPATH/src/go.uber.org/fx +git checkout master +git fetch upstream +git rebase upstream/master +git checkout -b cool_new_feature +``` + +Make your changes, and then check that `make lint` and `make test` still pass. +If you're satisfied with your changes, push them to your fork. + +``` +git push origin cool_new_feature +``` + +Then use the GitHub UI to [open a pull request][pr]. + +At this point, you're waiting on us to review your changes. We *try* to respond +to issues and pull requests within a few business days, and we may suggest some +improvements or alternatives. Once your changes are approved, one of the +project maintainers will merge them. + +We're much more likely to approve your changes if you: + +* Add tests for new functionality. +* Write a [good commit message][commit-message]. +* Maintain backward compatibility. + +[fork]: https://github.com/uber-go/fx/fork +[open-issue]: https://github.com/uber-go/fx/issues/new +[cla]: https://cla-assistant.io/uber-go/fx +[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[pr]: https://github.com/uber-go/fx/compare diff --git a/vendor/go.uber.org/fx/LICENSE b/vendor/go.uber.org/fx/LICENSE new file mode 100644 index 00000000..20e81eaf --- /dev/null +++ b/vendor/go.uber.org/fx/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016-2018 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/go.uber.org/fx/Makefile b/vendor/go.uber.org/fx/Makefile new file mode 100644 index 00000000..c5c26d54 --- /dev/null +++ b/vendor/go.uber.org/fx/Makefile @@ -0,0 +1,59 @@ +PKGS ?= $(shell glide novendor) +PKG_FILES ?= *.go + +# The linting tools evolve with each Go version, so run them only on the latest +# stable release. +GO_VERSION := $(shell go version | cut -d " " -f 3) +GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION))) +LINTABLE_MINOR_VERSIONS := 11 +ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),) +SHOULD_LINT := true +endif + +.PHONY: dependencies +dependencies: + @echo "Installing Glide and locked dependencies..." + glide --version || go get -u -f github.com/Masterminds/glide + glide install + @echo "Installing uber-license tool..." + update-license || go get -u -f go.uber.org/tools/update-license +ifdef SHOULD_LINT + @echo "Installing golint..." + go install ./vendor/golang.org/x/lint/golint +else + @echo "Not installing golint, since we don't expect to lint on" $(GO_VERSION) +endif + +.PHONY: test +test: + @.build/test.sh + +.PHONY: license +license: + $(ECHO_V).build/check_license.sh + +.PHONY: ci +ci: SHELL := /bin/bash +ci: test lint + bash <(curl -s https://codecov.io/bash) + +.PHONY: lint +lint: +ifdef SHOULD_LINT + @rm -rf lint.log + @echo "Checking formatting..." + @gofmt -d -s $(PKG_FILES) 2>&1 | tee lint.log + @echo "Installing test dependencies for vet..." + @go test -i $(PKGS) + @echo "Checking vet..." + @$(foreach dir,$(PKG_FILES),go tool vet $(VET_RULES) $(dir) 2>&1 | tee -a lint.log;) + @echo "Checking lint..." + @$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;) + @echo "Checking for unresolved FIXMEs..." + @git grep -i fixme | grep -v -e vendor -e Makefile -e .md | tee -a lint.log + @echo "Checking for license headers..." + @DRY_RUN=1 .build/check_license.sh | tee -a lint.log + @[ ! -s lint.log ] +else + @echo "Skipping linters on" $(GO_VERSION) +endif diff --git a/vendor/go.uber.org/fx/README.md b/vendor/go.uber.org/fx/README.md new file mode 100644 index 00000000..42eaf51d --- /dev/null +++ b/vendor/go.uber.org/fx/README.md @@ -0,0 +1,40 @@ +# :unicorn: Fx [![GoDoc][doc-img]][doc] [![Github release][release-img]][release] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][report-card-img]][report-card] + +An application framework for Go that: + +* Makes dependency injection easy. +* Eliminates the need for global state and `func init()`. + +## Installation + +We recommend locking to [SemVer](http://semver.org/) range `^1` using [Glide](https://github.com/Masterminds/glide): + +``` +glide get 'go.uber.org/fx#^1' +``` + +## Stability + +This library is `v1` and follows [SemVer](http://semver.org/) strictly. + +No breaking changes will be made to exported APIs before `v2.0.0`. + +This project follows the [Go Release Policy][release-policy]. Each major +version of Go is supported until there are two newer major releases. + +[doc-img]: http://img.shields.io/badge/GoDoc-Reference-blue.svg +[doc]: https://godoc.org/go.uber.org/fx + +[release-img]: https://img.shields.io/github/release/uber-go/fx.svg +[release]: https://github.com/uber-go/fx/releases + +[ci-img]: https://img.shields.io/travis/uber-go/fx/master.svg +[ci]: https://travis-ci.org/uber-go/fx/branches + +[cov-img]: https://codecov.io/gh/uber-go/fx/branch/dev/graph/badge.svg +[cov]: https://codecov.io/gh/uber-go/fx/branch/dev + +[report-card-img]: https://goreportcard.com/badge/github.com/uber-go/fx +[report-card]: https://goreportcard.com/report/github.com/uber-go/fx + +[release-policy]: https://golang.org/doc/devel/release.html#policy diff --git a/vendor/go.uber.org/fx/annotated.go b/vendor/go.uber.org/fx/annotated.go new file mode 100644 index 00000000..69e04cde --- /dev/null +++ b/vendor/go.uber.org/fx/annotated.go @@ -0,0 +1,64 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +// Annotated annotates a constructor provided to Fx with additional options. +// +// For example, +// +// func NewReadOnlyConnection(...) (*Connection, error) +// +// fx.Provide(fx.Annotated{ +// Name: "ro", +// Target: NewReadOnlyConnection, +// }) +// +// Is equivalent to, +// +// type result struct { +// fx.Out +// +// Connection *Connection `name:"ro"` +// } +// +// fx.Provide(func(...) (Result, error) { +// conn, err := NewReadOnlyConnection(...) +// return Result{Connection: conn}, err +// }) +// +// Annotated cannot be used with constructors which produce fx.Out objects. +type Annotated struct { + // If specified, this will be used as the name for all non-error values returned + // by the constructor. For more information on named values, see the documentation + // for the fx.Out type. + // + // A name option may not be provided if a group option is provided. + Name string + + // If specified, this will be used as the group name for all non-error values returned + // by the constructor. For more information on value groups, see the package documentation. + // + // A group option may not be provided if a name option is provided. + Group string + + // Target is the constructor being annotated with fx.Annotated. + Target interface{} +} diff --git a/vendor/go.uber.org/fx/app.go b/vendor/go.uber.org/fx/app.go new file mode 100644 index 00000000..f71f92f5 --- /dev/null +++ b/vendor/go.uber.org/fx/app.go @@ -0,0 +1,608 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import ( + "bytes" + "context" + "errors" + "fmt" + "os" + "os/signal" + "reflect" + "strings" + "sync" + "syscall" + "time" + + "go.uber.org/dig" + "go.uber.org/fx/internal/fxlog" + "go.uber.org/fx/internal/fxreflect" + "go.uber.org/fx/internal/lifecycle" + "go.uber.org/multierr" +) + +// DefaultTimeout is the default timeout for starting or stopping an +// application. It can be configured with the StartTimeout and StopTimeout +// options. +const DefaultTimeout = 15 * time.Second + +// An Option configures an App using the functional options paradigm +// popularized by Rob Pike. If you're unfamiliar with this style, see +// https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html. +type Option interface { + apply(*App) +} + +type optionFunc func(*App) + +func (f optionFunc) apply(app *App) { f(app) } + +// Provide registers any number of constructor functions, teaching the +// application how to instantiate various types. The supplied constructor +// function(s) may depend on other types available in the application, must +// return one or more objects, and may return an error. For example: +// +// // Constructs type *C, depends on *A and *B. +// func(*A, *B) *C +// +// // Constructs type *C, depends on *A and *B, and indicates failure by +// // returning an error. +// func(*A, *B) (*C, error) +// +// // Constructs types *B and *C, depends on *A, and can fail. +// func(*A) (*B, *C, error) +// +// The order in which constructors are provided doesn't matter, and passing +// multiple Provide options appends to the application's collection of +// constructors. Constructors are called only if one or more of their returned +// types are needed, and their results are cached for reuse (so instances of a +// type are effectively singletons within an application). Taken together, +// these properties make it perfectly reasonable to Provide a large number of +// constructors even if only a fraction of them are used. +// +// See the documentation of the In and Out types for advanced features, +// including optional parameters and named instances. +func Provide(constructors ...interface{}) Option { + return provideOption(constructors) +} + +type provideOption []interface{} + +func (po provideOption) apply(app *App) { + app.provides = append(app.provides, po...) +} + +func (po provideOption) String() string { + items := make([]string, len(po)) + for i, c := range po { + items[i] = fxreflect.FuncName(c) + } + return fmt.Sprintf("fx.Provide(%s)", strings.Join(items, ", ")) +} + +// Invoke registers functions that are executed eagerly on application start. +// Arguments for these invocations are built using the constructors registered +// by Provide. Passing multiple Invoke options appends the new invocations to +// the application's existing list. +// +// Unlike constructors, invocations are always executed, and they're always +// run in order. Invocations may have any number of returned values. If the +// final returned object is an error, it's assumed to be a success indicator. +// All other returned values are discarded. +// +// Typically, invoked functions take a handful of high-level objects (whose +// constructors depend on lower-level objects) and introduce them to each +// other. This kick-starts the application by forcing it to instantiate a +// variety of types. +// +// To see an invocation in use, read through the package-level example. For +// advanced features, including optional parameters and named instances, see +// the documentation of the In and Out types. +func Invoke(funcs ...interface{}) Option { + return invokeOption(funcs) +} + +type invokeOption []interface{} + +func (io invokeOption) apply(app *App) { + app.invokes = append(app.invokes, io...) +} + +func (io invokeOption) String() string { + items := make([]string, len(io)) + for i, f := range io { + items[i] = fxreflect.FuncName(f) + } + return fmt.Sprintf("fx.Invoke(%s)", strings.Join(items, ", ")) +} + +// Error registers any number of errors with the application to short-circuit +// startup. If more than one error is given, the errors are combined into a +// single error. +// +// Similar to invocations, errors are applied in order. All Provide and Invoke +// options registered before or after an Error option will not be applied. +func Error(errs ...error) Option { + return optionFunc(func(app *App) { + app.err = multierr.Append(app.err, multierr.Combine(errs...)) + }) +} + +// Options converts a collection of Options into a single Option. This allows +// packages to bundle sophisticated functionality into easy-to-use Fx modules. +// For example, a logging package might export a simple option like this: +// +// package logging +// +// var Module = fx.Provide(func() *log.Logger { +// return log.New(os.Stdout, "", 0) +// }) +// +// A shared all-in-one microservice package could then use Options to bundle +// logging with similar metrics, tracing, and gRPC modules: +// +// package server +// +// var Module = fx.Options( +// logging.Module, +// metrics.Module, +// tracing.Module, +// grpc.Module, +// ) +// +// Since this all-in-one module has a minimal API surface, it's easy to add +// new functionality to it without breaking existing users. Individual +// applications can take advantage of all this functionality with only one +// line of code: +// +// app := fx.New(server.Module) +// +// Use this pattern sparingly, since it limits the user's ability to customize +// their application. +func Options(opts ...Option) Option { + return optionGroup(opts) +} + +type optionGroup []Option + +func (og optionGroup) apply(app *App) { + for _, opt := range og { + opt.apply(app) + } +} + +func (og optionGroup) String() string { + items := make([]string, len(og)) + for i, opt := range og { + items[i] = fmt.Sprint(opt) + } + return fmt.Sprintf("fx.Options(%s)", strings.Join(items, ", ")) +} + +// StartTimeout changes the application's start timeout. +func StartTimeout(v time.Duration) Option { + return optionFunc(func(app *App) { + app.startTimeout = v + }) +} + +// StopTimeout changes the application's stop timeout. +func StopTimeout(v time.Duration) Option { + return optionFunc(func(app *App) { + app.stopTimeout = v + }) +} + +// Printer is the interface required by Fx's logging backend. It's implemented +// by most loggers, including the one bundled with the standard library. +type Printer interface { + Printf(string, ...interface{}) +} + +// Logger redirects the application's log output to the provided printer. +func Logger(p Printer) Option { + return optionFunc(func(app *App) { + app.logger = &fxlog.Logger{Printer: p} + app.lifecycle = &lifecycleWrapper{lifecycle.New(app.logger)} + }) +} + +// NopLogger disables the application's log output. Note that this makes some +// failures difficult to debug, since no errors are printed to console. +var NopLogger = Logger(nopLogger{}) + +type nopLogger struct{} + +func (l nopLogger) Printf(string, ...interface{}) { + return +} + +// An App is a modular application built around dependency injection. Most +// users will only need to use the New constructor and the all-in-one Run +// convenience method. In more unusual cases, users may need to use the Err, +// Start, Done, and Stop methods by hand instead of relying on Run. +// +// New creates and initializes an App. All applications begin with a +// constructor for the Lifecycle type already registered. +// +// In addition to that built-in functionality, users typically pass a handful +// of Provide options and one or more Invoke options. The Provide options +// teach the application how to instantiate a variety of types, and the Invoke +// options describe how to initialize the application. +// +// When created, the application immediately executes all the functions passed +// via Invoke options. To supply these functions with the parameters they +// need, the application looks for constructors that return the appropriate +// types; if constructors for any required types are missing or any +// invocations return an error, the application will fail to start (and Err +// will return a descriptive error message). +// +// Once all the invocations (and any required constructors) have been called, +// New returns and the application is ready to be started using Run or Start. +// On startup, it executes any OnStart hooks registered with its Lifecycle. +// OnStart hooks are executed one at a time, in order, and must all complete +// within a configurable deadline (by default, 15 seconds). For details on the +// order in which OnStart hooks are executed, see the documentation for the +// Start method. +// +// At this point, the application has successfully started up. If started via +// Run, it will continue operating until it receives a shutdown signal from +// Done (see the Done documentation for details); if started explicitly via +// Start, it will operate until the user calls Stop. On shutdown, OnStop hooks +// execute one at a time, in reverse order, and must all complete within a +// configurable deadline (again, 15 seconds by default). +type App struct { + err error + container *dig.Container + lifecycle *lifecycleWrapper + provides []interface{} + invokes []interface{} + logger *fxlog.Logger + startTimeout time.Duration + stopTimeout time.Duration + errorHooks []ErrorHandler + + donesMu sync.RWMutex + dones []chan os.Signal +} + +// ErrorHook registers error handlers that implement error handling functions. +// They are executed on invoke failures. Passing multiple ErrorHandlers appends +// the new handlers to the application's existing list. +func ErrorHook(funcs ...ErrorHandler) Option { + return errorHookOption(funcs) +} + +// ErrorHandler handles Fx application startup errors. +type ErrorHandler interface { + HandleError(error) +} + +type errorHookOption []ErrorHandler + +func (eho errorHookOption) apply(app *App) { + app.errorHooks = append(app.errorHooks, eho...) +} + +type errorHandlerList []ErrorHandler + +func (ehl errorHandlerList) HandleError(err error) { + for _, eh := range ehl { + eh.HandleError(err) + } +} + +// New creates and initializes an App, immediately executing any functions +// registered via Invoke options. See the documentation of the App struct for +// details on the application's initialization, startup, and shutdown logic. +func New(opts ...Option) *App { + logger := fxlog.New() + lc := &lifecycleWrapper{lifecycle.New(logger)} + + app := &App{ + container: dig.New(dig.DeferAcyclicVerification()), + lifecycle: lc, + logger: logger, + startTimeout: DefaultTimeout, + stopTimeout: DefaultTimeout, + } + + for _, opt := range opts { + opt.apply(app) + } + + for _, p := range app.provides { + app.provide(p) + } + app.provide(func() Lifecycle { return app.lifecycle }) + app.provide(app.shutdowner) + app.provide(app.dotGraph) + + if app.err != nil { + app.logger.Printf("Error after options were applied: %v", app.err) + return app + } + + if err := app.executeInvokes(); err != nil { + app.err = err + + if dig.CanVisualizeError(err) { + var b bytes.Buffer + dig.Visualize(app.container, &b, dig.VisualizeError(err)) + err = errorWithGraph{ + graph: b.String(), + err: err, + } + } + errorHandlerList(app.errorHooks).HandleError(err) + } + return app +} + +// DotGraph contains a DOT language visualization of the dependency graph in +// an Fx application. It is provided in the container by default at +// initialization. On failure to build the dependency graph, it is attached +// to the error and if possible, colorized to highlight the root cause of the +// failure. +type DotGraph string + +type errWithGraph interface { + Graph() DotGraph +} + +type errorWithGraph struct { + graph string + err error +} + +func (err errorWithGraph) Graph() DotGraph { + return DotGraph(err.graph) +} + +func (err errorWithGraph) Error() string { + return err.err.Error() +} + +// VisualizeError returns the visualization of the error if available. +func VisualizeError(err error) (string, error) { + if e, ok := err.(errWithGraph); ok && e.Graph() != "" { + return string(e.Graph()), nil + } + return "", errors.New("unable to visualize error") +} + +// Run starts the application, blocks on the signals channel, and then +// gracefully shuts the application down. It uses DefaultTimeout to set a +// deadline for application startup and shutdown, unless the user has +// configured different timeouts with the StartTimeout or StopTimeout options. +// It's designed to make typical applications simple to run. +// +// However, all of Run's functionality is implemented in terms of the exported +// Start, Done, and Stop methods. Applications with more specialized needs +// can use those methods directly instead of relying on Run. +func (app *App) Run() { + app.run(app.Done()) +} + +// Err returns any error encountered during New's initialization. See the +// documentation of the New method for details, but typical errors include +// missing constructors, circular dependencies, constructor errors, and +// invocation errors. +// +// Most users won't need to use this method, since both Run and Start +// short-circuit if initialization failed. +func (app *App) Err() error { + return app.err +} + +// Start kicks off all long-running goroutines, like network servers or +// message queue consumers. It does this by interacting with the application's +// Lifecycle. +// +// By taking a dependency on the Lifecycle type, some of the user-supplied +// functions called during initialization may have registered start and stop +// hooks. Because initialization calls constructors serially and in dependency +// order, hooks are naturally registered in dependency order too. +// +// Start executes all OnStart hooks registered with the application's +// Lifecycle, one at a time and in order. This ensures that each constructor's +// start hooks aren't executed until all its dependencies' start hooks +// complete. If any of the start hooks return an error, Start short-circuits, +// calls Stop, and returns the inciting error. +// +// Note that Start short-circuits immediately if the New constructor +// encountered any errors in application initialization. +func (app *App) Start(ctx context.Context) error { + return withTimeout(ctx, app.start) +} + +// Stop gracefully stops the application. It executes any registered OnStop +// hooks in reverse order, so that each constructor's stop hooks are called +// before its dependencies' stop hooks. +// +// If the application didn't start cleanly, only hooks whose OnStart phase was +// called are executed. However, all those hooks are executed, even if some +// fail. +func (app *App) Stop(ctx context.Context) error { + return withTimeout(ctx, app.lifecycle.Stop) +} + +// Done returns a channel of signals to block on after starting the +// application. Applications listen for the SIGINT and SIGTERM signals; during +// development, users can send the application SIGTERM by pressing Ctrl-C in +// the same terminal as the running process. +// +// Alternatively, a signal can be broadcast to all done channels manually by +// using the Shutdown functionality (see the Shutdowner documentation for details). +func (app *App) Done() <-chan os.Signal { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) + + app.donesMu.Lock() + app.dones = append(app.dones, c) + app.donesMu.Unlock() + return c +} + +// StartTimeout returns the configured startup timeout. Apps default to using +// DefaultTimeout, but users can configure this behavior using the +// StartTimeout option. +func (app *App) StartTimeout() time.Duration { + return app.startTimeout +} + +// StopTimeout returns the configured shutdown timeout. Apps default to using +// DefaultTimeout, but users can configure this behavior using the StopTimeout +// option. +func (app *App) StopTimeout() time.Duration { + return app.stopTimeout +} + +func (app *App) dotGraph() (DotGraph, error) { + var b bytes.Buffer + err := dig.Visualize(app.container, &b) + return DotGraph(b.String()), err +} + +func (app *App) provide(constructor interface{}) { + if app.err != nil { + return + } + app.logger.PrintProvide(constructor) + + if _, ok := constructor.(Option); ok { + app.err = fmt.Errorf("fx.Option should be passed to fx.New directly, not to fx.Provide: fx.Provide received %v", constructor) + return + } + + if a, ok := constructor.(Annotated); ok { + var opts []dig.ProvideOption + switch { + case len(a.Group) > 0 && len(a.Name) > 0: + app.err = fmt.Errorf("fx.Annotate may not specify both name and group for %v", constructor) + return + case len(a.Name) > 0: + opts = append(opts, dig.Name(a.Name)) + case len(a.Group) > 0: + opts = append(opts, dig.Group(a.Group)) + + } + + if err := app.container.Provide(a.Target, opts...); err != nil { + app.err = err + } + return + } + + if reflect.TypeOf(constructor).Kind() == reflect.Func { + ft := reflect.ValueOf(constructor).Type() + + for i := 0; i < ft.NumOut(); i++ { + t := ft.Out(i) + + if t == reflect.TypeOf(Annotated{}) { + app.err = fmt.Errorf("fx.Annotated should be passed to fx.Provide directly, it should not be returned by the constructor: fx.Provide received %v", constructor) + return + } + } + } + + if err := app.container.Provide(constructor); err != nil { + app.err = err + } +} + +// Execute invokes in order supplied to New, returning the first error +// encountered. +func (app *App) executeInvokes() error { + // TODO: consider taking a context to limit the time spent running invocations. + var err error + + for _, fn := range app.invokes { + fname := fxreflect.FuncName(fn) + app.logger.Printf("INVOKE\t\t%s", fname) + + if _, ok := fn.(Option); ok { + err = fmt.Errorf("fx.Option should be passed to fx.New directly, not to fx.Invoke: fx.Invoke received %v", fn) + } else { + err = app.container.Invoke(fn) + } + + if err != nil { + app.logger.Printf("Error during %q invoke: %v", fname, err) + break + } + } + + return err +} + +func (app *App) run(done <-chan os.Signal) { + startCtx, cancel := context.WithTimeout(context.Background(), app.StartTimeout()) + defer cancel() + + if err := app.Start(startCtx); err != nil { + app.logger.Fatalf("ERROR\t\tFailed to start: %v", err) + } + + app.logger.PrintSignal(<-done) + + stopCtx, cancel := context.WithTimeout(context.Background(), app.StopTimeout()) + defer cancel() + + if err := app.Stop(stopCtx); err != nil { + app.logger.Fatalf("ERROR\t\tFailed to stop cleanly: %v", err) + } +} + +func (app *App) start(ctx context.Context) error { + if app.err != nil { + // Some provides failed, short-circuit immediately. + return app.err + } + + // Attempt to start cleanly. + if err := app.lifecycle.Start(ctx); err != nil { + // Start failed, roll back. + app.logger.Printf("ERROR\t\tStart failed, rolling back: %v", err) + if stopErr := app.lifecycle.Stop(ctx); stopErr != nil { + app.logger.Printf("ERROR\t\tCouldn't rollback cleanly: %v", stopErr) + return multierr.Append(err, stopErr) + } + return err + } + + app.logger.Printf("RUNNING") + return nil +} + +func withTimeout(ctx context.Context, f func(context.Context) error) error { + c := make(chan error, 1) + go func() { c <- f(ctx) }() + + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-c: + return err + } +} diff --git a/vendor/go.uber.org/fx/doc.go b/vendor/go.uber.org/fx/doc.go new file mode 100644 index 00000000..c86996c5 --- /dev/null +++ b/vendor/go.uber.org/fx/doc.go @@ -0,0 +1,39 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package fx is a framework that makes it easy to build applications out of +// reusable, composable modules. +// +// Fx applications use dependency injection to eliminate globals without the +// tedium of manually wiring together function calls. Unlike other approaches +// to dependency injection, Fx works with plain Go functions: you don't need +// to use struct tags or embed special types, so Fx automatically works well +// with most Go packages. +// +// Basic usage is explained in the package-level example below. If you're new +// to Fx, start there! Advanced features, including named instances, optional +// parameters, and value groups, are explained under the In and Out types. +// +// Testing Fx Applications +// +// To test functions that use the Lifecycle type or to write end-to-end tests +// of your Fx application, use the helper functions and types provided by the +// go.uber.org/fx/fxtest package. +package fx diff --git a/vendor/go.uber.org/fx/extract.go b/vendor/go.uber.org/fx/extract.go new file mode 100644 index 00000000..8fb34a0b --- /dev/null +++ b/vendor/go.uber.org/fx/extract.go @@ -0,0 +1,157 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import ( + "fmt" + "reflect" + "unicode" + "unicode/utf8" +) + +var _typeOfIn = reflect.TypeOf(In{}) + +// Extract fills the given struct with values from the dependency injection +// container on application initialization. The target MUST be a pointer to a +// struct. Only exported fields will be filled. +// +// Extract will be deprecated soon: use Populate instead, which doesn't +// require defining a container struct. +func Extract(target interface{}) Option { + v := reflect.ValueOf(target) + + if t := v.Type(); t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { + return invokeErr(fmt.Errorf("Extract expected a pointer to a struct, got a %v", t)) + } + + v = v.Elem() + t := v.Type() + + // We generate a function which accepts a single fx.In struct as an + // argument. This struct contains all exported fields of the target + // struct. + + // Fields of the generated fx.In struct. + fields := make([]reflect.StructField, 0, t.NumField()+1) + + // Anonymous dig.In field. + fields = append(fields, reflect.StructField{ + Name: _typeOfIn.Name(), + Anonymous: true, + Type: _typeOfIn, + }) + + // List of values in the target struct aligned with the fields of the + // generated struct. + // + // So for example, if the target is, + // + // var target struct { + // Foo io.Reader + // bar []byte + // Baz io.Writer + // } + // + // The generated struct has the shape, + // + // struct { + // fx.In + // + // F0 io.Reader + // F2 io.Writer + // } + // + // And `targets` is, + // + // [ + // target.Field(0), // Foo io.Reader + // target.Field(2), // Baz io.Writer + // ] + // + // As we iterate through the fields of the generated struct, we can copy + // the value into the corresponding value in the targets list. + targets := make([]reflect.Value, 0, t.NumField()) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + + // Skip unexported fields. + if f.Anonymous { + // If embedded, StructField.PkgPath is not a reliable indicator of + // whether the field is exported. See + // https://github.com/golang/go/issues/21122 + + t := f.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + if !isExported(t.Name()) { + continue + } + } else if f.PkgPath != "" { + continue + } + + // We don't copy over names or embedded semantics. + fields = append(fields, reflect.StructField{ + Name: fmt.Sprintf("F%d", i), + Type: f.Type, + Tag: f.Tag, + }) + targets = append(targets, v.Field(i)) + } + + // Equivalent to, + // + // func(r struct { + // fx.In + // + // F1 Foo + // F2 Bar + // }) { + // target.Foo = r.F1 + // target.Bar = r.F2 + // } + + fn := reflect.MakeFunc( + reflect.FuncOf( + []reflect.Type{reflect.StructOf(fields)}, + nil, /* results */ + false, /* variadic */ + ), + func(args []reflect.Value) []reflect.Value { + result := args[0] + for i := 1; i < result.NumField(); i++ { + targets[i-1].Set(result.Field(i)) + } + return nil + }, + ) + + return Invoke(fn.Interface()) +} + +// isExported reports whether the identifier is exported. +func isExported(id string) bool { + r, _ := utf8.DecodeRuneInString(id) + return unicode.IsUpper(r) +} diff --git a/vendor/go.uber.org/fx/glide.lock b/vendor/go.uber.org/fx/glide.lock new file mode 100644 index 00000000..4fb92261 --- /dev/null +++ b/vendor/go.uber.org/fx/glide.lock @@ -0,0 +1,44 @@ +hash: 71b848dcf5bde6b02fd7ca7cf3ac1e7628dd27e7248f3823900bce9a78005038 +updated: 2018-09-20T11:31:48.18331584-07:00 +imports: +- name: go.uber.org/atomic + version: 1ea20fb1cbb1cc08cbd0d913a96dead89aa18289 +- name: go.uber.org/dig + version: 7ff117f761a3f1b3eb521945c17a1091438eb6de + subpackages: + - internal/digreflect + - internal/dot +- name: go.uber.org/multierr + version: 3c4937480c32f4c13a875a1829af76c98ca3d40a +testImports: +- name: github.com/davecgh/go-spew + version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73 + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: 792786c7400a136282c1664665ae0a8db921c6c2 + subpackages: + - difflib +- name: github.com/stretchr/testify + version: f35b8ab0b5a2cef36673838d662e249dd9c94686 + subpackages: + - assert + - require +- name: go.uber.org/goleak + version: 1ac8aeca0a53163331564467638f6ffb639636bf + subpackages: + - internal/stack +- name: go.uber.org/tools + version: ce2550dad7144b81ae2f67dc5e55597643f6902b + subpackages: + - update-license +- name: golang.org/x/lint + version: 06c8688daad7faa9da5a0c2f163a3d14aac986ca + repo: https://github.com/golang/lint + vcs: git + subpackages: + - golint +- name: golang.org/x/tools + version: 4e70a1b26a7875f00ca1916637a876b5ffaeec59 + subpackages: + - cover diff --git a/vendor/go.uber.org/fx/glide.yaml b/vendor/go.uber.org/fx/glide.yaml new file mode 100644 index 00000000..f4422bc6 --- /dev/null +++ b/vendor/go.uber.org/fx/glide.yaml @@ -0,0 +1,25 @@ +package: go.uber.org/fx +import: +- package: go.uber.org/multierr + version: ^1 +- package: go.uber.org/dig + version: ^1.7 # At least version 1.7 is required for fx/dig `Group` support. +testImport: +- package: github.com/stretchr/testify + version: ^1 + subpackages: + - assert + - require +- package: go.uber.org/tools + subpackages: + - update-license +- package: golang.org/x/tools + subpackages: + - cover +- package: golang.org/x/lint + repo: https://github.com/golang/lint + vcs: git + subpackages: + - golint +- package: go.uber.org/goleak + version: ~0.10 diff --git a/vendor/go.uber.org/fx/inout.go b/vendor/go.uber.org/fx/inout.go new file mode 100644 index 00000000..6c37c567 --- /dev/null +++ b/vendor/go.uber.org/fx/inout.go @@ -0,0 +1,254 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import "go.uber.org/dig" + +// In can be embedded in a constructor's parameter struct to take advantage of +// advanced dependency injection features. +// +// Modules should take a single parameter struct that embeds an In in order to +// provide a forward-compatible API: since adding fields to a struct is +// backward-compatible, modules can then add optional dependencies in minor +// releases. +// +// Parameter Structs +// +// Fx constructors declare their dependencies as function parameters. This can +// quickly become unreadable if the constructor has a lot of dependencies. +// +// func NewHandler(users *UserGateway, comments *CommentGateway, posts *PostGateway, votes *VoteGateway, authz *AuthZGateway) *Handler { +// // ... +// } +// +// To improve the readability of constructors like this, create a struct that +// lists all the dependencies as fields and change the function to accept that +// struct instead. The new struct is called a parameter struct. +// +// Fx has first class support for parameter structs: any struct embedding +// fx.In gets treated as a parameter struct, so the individual fields in the +// struct are supplied via dependency injection. Using a parameter struct, we +// can make the constructor above much more readable: +// +// type HandlerParams struct { +// fx.In +// +// Users *UserGateway +// Comments *CommentGateway +// Posts *PostGateway +// Votes *VoteGateway +// AuthZ *AuthZGateway +// } +// +// func NewHandler(p HandlerParams) *Handler { +// // ... +// } +// +// Though it's rarely a good idea, constructors can receive any combination of +// parameter structs and parameters. +// +// func NewHandler(p HandlerParams, l *log.Logger) *Handler { +// // ... +// } +// +// Optional Dependencies +// +// Constructors often have soft dependencies on some types: if those types are +// missing, they can operate in a degraded state. Fx supports optional +// dependencies via the `optional:"true"` tag to fields on parameter structs. +// +// type UserGatewayParams struct { +// fx.In +// +// Conn *sql.DB +// Cache *redis.Client `optional:"true"` +// } +// +// If an optional field isn't available in the container, the constructor +// receives the field's zero value. +// +// func NewUserGateway(p UserGatewayParams, log *log.Logger) (*UserGateway, error) { +// if p.Cache != nil { +// log.Print("Caching disabled") +// } +// // ... +// } +// +// Constructors that declare optional dependencies MUST gracefully handle +// situations in which those dependencies are absent. +// +// The optional tag also allows adding new dependencies without breaking +// existing consumers of the constructor. +// +// Named Values +// +// Some use cases require the application container to hold multiple values of +// the same type. For details on producing named values, see the documentation +// for the Out type. +// +// Fx allows functions to consume named values via the `name:".."` tag on +// parameter structs. Note that both the name AND type of the fields on the +// parameter struct must match the corresponding result struct. +// +// type GatewayParams struct { +// fx.In +// +// WriteToConn *sql.DB `name:"rw"` +// ReadFromConn *sql.DB `name:"ro"` +// } +// +// The name tag may be combined with the optional tag to declare the +// dependency optional. +// +// type GatewayParams struct { +// fx.In +// +// WriteToConn *sql.DB `name:"rw"` +// ReadFromConn *sql.DB `name:"ro" optional:"true"` +// } +// +// func NewCommentGateway(p GatewayParams, log *log.Logger) (*CommentGateway, error) { +// if p.ReadFromConn == nil { +// log.Print("Warning: Using RW connection for reads") +// p.ReadFromConn = p.WriteToConn +// } +// // ... +// } +// +// Value Groups +// +// To make it easier to produce and consume many values of the same type, Fx +// supports named, unordered collections called value groups. For details on +// producing value groups, see the documentation for the Out type. +// +// Functions can depend on a value group by requesting a slice tagged with +// `group:".."`. This will execute all constructors that provide a value to +// that group in an unspecified order, then collect all the results into a +// single slice. Keep in mind that this makes the types of the parameter and +// result struct fields different: if a group of constructors each returns +// type T, parameter structs consuming the group must use a field of type []T. +// +// type ServerParams struct { +// fx.In +// +// Handlers []Handler `group:"server"` +// } +// +// func NewServer(p ServerParams) *Server { +// server := newServer() +// for _, h := range p.Handlers { +// server.Register(h) +// } +// return server +// } +// +// Note that values in a value group are unordered. Fx makes no guarantees +// about the order in which these values will be produced. +type In struct{ dig.In } + +// Out is the inverse of In: it can be embedded in result structs to take +// advantage of advanced features. +// +// Modules should return a single result struct that embeds an Out in order to +// provide a forward-compatible API: since adding fields to a struct is +// backward-compatible, minor releases can provide additional types. +// +// Result Structs +// +// Result structs are the inverse of parameter structs (discussed in the In +// documentation). These structs represent multiple outputs from a +// single function as fields. Fx treats all structs embedding fx.Out as result +// structs, so other constructors can rely on the result struct's fields +// directly. +// +// Without result structs, we sometimes have function definitions like this: +// +// func SetupGateways(conn *sql.DB) (*UserGateway, *CommentGateway, *PostGateway, error) { +// // ... +// } +// +// With result structs, we can make this both more readable and easier to +// modify in the future: +// +// type Gateways struct { +// fx.Out +// +// Users *UserGateway +// Comments *CommentGateway +// Posts *PostGateway +// } +// +// func SetupGateways(conn *sql.DB) (Gateways, error) { +// // ... +// } +// +// Named Values +// +// Some use cases require the application container to hold multiple values of +// the same type. For details on consuming named values, see the documentation +// for the In type. +// +// A constructor that produces a result struct can tag any field with +// `name:".."` to have the corresponding value added to the graph under the +// specified name. An application may contain at most one unnamed value of a +// given type, but may contain any number of named values of the same type. +// +// type ConnectionResult struct { +// fx.Out +// +// ReadWrite *sql.DB `name:"rw"` +// ReadOnly *sql.DB `name:"ro"` +// } +// +// func ConnectToDatabase(...) (ConnectionResult, error) { +// // ... +// return ConnectionResult{ReadWrite: rw, ReadOnly: ro}, nil +// } +// +// Value Groups +// +// To make it easier to produce and consume many values of the same type, Fx +// supports named, unordered collections called value groups. For details on +// consuming value groups, see the documentation for the In type. +// +// Constructors can send values into value groups by returning a result struct +// tagged with `group:".."`. +// +// type HandlerResult struct { +// fx.Out +// +// Handler Handler `group:"server"` +// } +// +// func NewHelloHandler() HandlerResult { +// // ... +// } +// +// func NewEchoHandler() HandlerResult { +// // ... +// } +// +// Any number of constructors may provide values to this named collection, but +// the ordering of the final collection is unspecified. Keep in mind that +// value groups require parameter and result structs to use fields with +// different types: if a group of constructors each returns type T, parameter +// structs consuming the group must use a field of type []T. +type Out struct{ dig.Out } diff --git a/vendor/go.uber.org/fx/internal/fxlog/fxlog.go b/vendor/go.uber.org/fx/internal/fxlog/fxlog.go new file mode 100644 index 00000000..18c3e366 --- /dev/null +++ b/vendor/go.uber.org/fx/internal/fxlog/fxlog.go @@ -0,0 +1,80 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fxlog + +import ( + "fmt" + "log" + "os" + "strings" + + "go.uber.org/fx/internal/fxreflect" +) + +var _exit = func() { os.Exit(1) } + +// Printer is a formatting printer. +type Printer interface { + Printf(string, ...interface{}) +} + +// New returns a new Logger backed by the standard library's log package. +func New() *Logger { + return &Logger{log.New(os.Stderr, "", log.LstdFlags)} +} + +// A Logger writes output to standard error. +type Logger struct { + Printer +} + +// Printf logs a formatted Fx line. +func (l *Logger) Printf(format string, v ...interface{}) { + l.Printer.Printf(prepend(format), v...) +} + +// PrintProvide logs a type provided into the dig.Container. +func (l *Logger) PrintProvide(t interface{}) { + for _, rtype := range fxreflect.ReturnTypes(t) { + l.Printf("PROVIDE\t%s <= %s", rtype, fxreflect.FuncName(t)) + } +} + +// PrintSignal logs an os.Signal. +func (l *Logger) PrintSignal(signal os.Signal) { + l.Printf(strings.ToUpper(signal.String())) +} + +// Panic logs an Fx line then panics. +func (l *Logger) Panic(err error) { + l.Printer.Printf(prepend(err.Error())) + panic(err) +} + +// Fatalf logs an Fx line then fatals. +func (l *Logger) Fatalf(format string, v ...interface{}) { + l.Printer.Printf(prepend(format), v...) + _exit() +} + +func prepend(str string) string { + return fmt.Sprintf("[Fx] %s", str) +} diff --git a/vendor/go.uber.org/fx/internal/fxreflect/fxreflect.go b/vendor/go.uber.org/fx/internal/fxreflect/fxreflect.go new file mode 100644 index 00000000..8e2692dc --- /dev/null +++ b/vendor/go.uber.org/fx/internal/fxreflect/fxreflect.go @@ -0,0 +1,163 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fxreflect + +import ( + "fmt" + "net/url" + "reflect" + "regexp" + "runtime" + "strings" + + "go.uber.org/dig" +) + +// Match from beginning of the line until the first `vendor/` (non-greedy) +var vendorRe = regexp.MustCompile("^.*?/vendor/") + +// ReturnTypes takes a func and returns a slice of string'd types. +func ReturnTypes(t interface{}) []string { + if reflect.TypeOf(t).Kind() != reflect.Func { + // Invalid provide, will be logged as an error. + return []string{} + } + + rtypes := []string{} + ft := reflect.ValueOf(t).Type() + + for i := 0; i < ft.NumOut(); i++ { + t := ft.Out(i) + + traverseOuts(key{t: t}, func(s string) { + rtypes = append(rtypes, s) + }) + } + + return rtypes +} + +type key struct { + t reflect.Type + name string +} + +func (k *key) String() string { + if k.name != "" { + return fmt.Sprintf("%v:%s", k.t, k.name) + } + return k.t.String() +} + +func traverseOuts(k key, f func(s string)) { + // skip errors + if isErr(k.t) { + return + } + + // call funtion on non-Out types + if dig.IsOut(k.t) { + // keep recursing down on field members in case they are ins + for i := 0; i < k.t.NumField(); i++ { + field := k.t.Field(i) + ft := field.Type + + if field.PkgPath != "" { + continue // skip private fields + } + + // keep recursing to traverse all the embedded objects + k := key{ + t: ft, + name: field.Tag.Get("name"), + } + traverseOuts(k, f) + } + + return + } + + f(k.String()) +} + +// sanitize makes the function name suitable for logging display. It removes +// url-encoded elements from the `dot.git` package names and shortens the +// vendored paths. +func sanitize(function string) string { + // Use the stdlib to un-escape any package import paths which can happen + // in the case of the "dot-git" postfix. Seems like a bug in stdlib =/ + if unescaped, err := url.QueryUnescape(function); err == nil { + function = unescaped + } + + // strip everything prior to the vendor + return vendorRe.ReplaceAllString(function, "vendor/") +} + +// Caller returns the formatted calling func name +func Caller() string { + // Ascend at most 8 frames looking for a caller outside fx. + pcs := make([]uintptr, 8) + + // Don't include this frame. + n := runtime.Callers(2, pcs) + if n == 0 { + return "n/a" + } + + frames := runtime.CallersFrames(pcs) + for f, more := frames.Next(); more; f, more = frames.Next() { + if shouldIgnoreFrame(f) { + continue + } + return sanitize(f.Function) + } + return "n/a" +} + +// FuncName returns a funcs formatted name +func FuncName(fn interface{}) string { + fnV := reflect.ValueOf(fn) + if fnV.Kind() != reflect.Func { + return "n/a" + } + + function := runtime.FuncForPC(fnV.Pointer()).Name() + return fmt.Sprintf("%s()", sanitize(function)) +} + +func isErr(t reflect.Type) bool { + errInterface := reflect.TypeOf((*error)(nil)).Elem() + return t.Implements(errInterface) +} + +// Ascend the call stack until we leave the Fx production code. This allows us +// to avoid hard-coding a frame skip, which makes this code work well even +// when it's wrapped. +func shouldIgnoreFrame(f runtime.Frame) bool { + if strings.Contains(f.File, "_test.go") { + return false + } + if strings.Contains(f.File, "go.uber.org/fx") { + return true + } + return false +} diff --git a/vendor/go.uber.org/fx/internal/lifecycle/lifecycle.go b/vendor/go.uber.org/fx/internal/lifecycle/lifecycle.go new file mode 100644 index 00000000..ded22ed4 --- /dev/null +++ b/vendor/go.uber.org/fx/internal/lifecycle/lifecycle.go @@ -0,0 +1,92 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package lifecycle + +import ( + "context" + + "go.uber.org/fx/internal/fxlog" + "go.uber.org/fx/internal/fxreflect" + "go.uber.org/multierr" +) + +// A Hook is a pair of start and stop callbacks, either of which can be nil, +// plus a string identifying the supplier of the hook. +type Hook struct { + OnStart func(context.Context) error + OnStop func(context.Context) error + caller string +} + +// Lifecycle coordinates application lifecycle hooks. +type Lifecycle struct { + logger *fxlog.Logger + hooks []Hook + numStarted int +} + +// New constructs a new Lifecycle. +func New(logger *fxlog.Logger) *Lifecycle { + if logger == nil { + logger = fxlog.New() + } + return &Lifecycle{logger: logger} +} + +// Append adds a Hook to the lifecycle. +func (l *Lifecycle) Append(hook Hook) { + hook.caller = fxreflect.Caller() + l.hooks = append(l.hooks, hook) +} + +// Start runs all OnStart hooks, returning immediately if it encounters an +// error. +func (l *Lifecycle) Start(ctx context.Context) error { + for _, hook := range l.hooks { + if hook.OnStart != nil { + l.logger.Printf("START\t\t%s()", hook.caller) + if err := hook.OnStart(ctx); err != nil { + return err + } + } + l.numStarted++ + } + return nil +} + +// Stop runs any OnStop hooks whose OnStart counterpart succeeded. OnStop +// hooks run in reverse order. +func (l *Lifecycle) Stop(ctx context.Context) error { + var errs []error + // Run backward from last successful OnStart. + for ; l.numStarted > 0; l.numStarted-- { + hook := l.hooks[l.numStarted-1] + if hook.OnStop == nil { + continue + } + l.logger.Printf("STOP\t\t%s()", hook.caller) + if err := hook.OnStop(ctx); err != nil { + // For best-effort cleanup, keep going after errors. + errs = append(errs, err) + } + } + return multierr.Combine(errs...) +} diff --git a/vendor/go.uber.org/fx/lifecycle.go b/vendor/go.uber.org/fx/lifecycle.go new file mode 100644 index 00000000..f187e223 --- /dev/null +++ b/vendor/go.uber.org/fx/lifecycle.go @@ -0,0 +1,52 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import ( + "context" + + "go.uber.org/fx/internal/lifecycle" +) + +// Lifecycle allows constructors to register callbacks that are executed on +// application start and stop. See the documentation for App for details on Fx +// applications' initialization, startup, and shutdown logic. +type Lifecycle interface { + Append(Hook) +} + +// A Hook is a pair of start and stop callbacks, either of which can be nil. +// If a Hook's OnStart callback isn't executed (because a previous OnStart +// failure short-circuited application startup), its OnStop callback won't be +// executed. +type Hook struct { + OnStart func(context.Context) error + OnStop func(context.Context) error +} + +type lifecycleWrapper struct{ *lifecycle.Lifecycle } + +func (l *lifecycleWrapper) Append(h Hook) { + l.Lifecycle.Append(lifecycle.Hook{ + OnStart: h.OnStart, + OnStop: h.OnStop, + }) +} diff --git a/vendor/go.uber.org/fx/populate.go b/vendor/go.uber.org/fx/populate.go new file mode 100644 index 00000000..1c503c5b --- /dev/null +++ b/vendor/go.uber.org/fx/populate.go @@ -0,0 +1,73 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import ( + "fmt" + "reflect" +) + +// Populate sets targets with values from the dependency injection container +// during application initialization. All targets must be pointers to the +// values that must be populated. Pointers to structs that embed In are +// supported, which can be used to populate multiple values in a struct. +// +// This is most helpful in unit tests: it lets tests leverage Fx's automatic +// constructor wiring to build a few structs, but then extract those structs +// for further testing. +func Populate(targets ...interface{}) Option { + // Validate all targets are non-nil pointers. + targetTypes := make([]reflect.Type, len(targets)) + for i, t := range targets { + if t == nil { + return invokeErr(fmt.Errorf("failed to Populate: target %v is nil", i+1)) + } + rt := reflect.TypeOf(t) + if rt.Kind() != reflect.Ptr { + return invokeErr(fmt.Errorf("failed to Populate: target %v is not a pointer type, got %T", i+1, t)) + } + + targetTypes[i] = reflect.TypeOf(t).Elem() + } + + // Build a function that looks like: + // + // func(t1 T1, t2 T2, ...) { + // *targets[0] = t1 + // *targets[1] = t2 + // [...] + // } + // + fnType := reflect.FuncOf(targetTypes, nil, false /* variadic */) + fn := reflect.MakeFunc(fnType, func(args []reflect.Value) []reflect.Value { + for i, arg := range args { + reflect.ValueOf(targets[i]).Elem().Set(arg) + } + return nil + }) + return Invoke(fn.Interface()) +} + +func invokeErr(err error) Option { + return Invoke(func() error { + return err + }) +} diff --git a/vendor/go.uber.org/fx/shutdown.go b/vendor/go.uber.org/fx/shutdown.go new file mode 100644 index 00000000..928e45d8 --- /dev/null +++ b/vendor/go.uber.org/fx/shutdown.go @@ -0,0 +1,79 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +import ( + "fmt" + "os" + "syscall" +) + +// Shutdowner provides a method that can manually trigger the shutdown of the +// application by sending a signal to all open Done channels. Shutdowner works +// on applications using Run as well as Start, Done, and Stop. The Shutdowner is +// provided to all Fx applications. +type Shutdowner interface { + Shutdown(...ShutdownOption) error +} + +// ShutdownOption provides a way to configure properties of the shutdown +// process. Currently, no options have been implemented. +type ShutdownOption interface { + apply(*shutdowner) +} + +type shutdowner struct { + app *App +} + +// Shutdown broadcasts a signal to all of the application's Done channels +// and begins the Stop process. +func (s *shutdowner) Shutdown(opts ...ShutdownOption) error { + return s.app.broadcastSignal(syscall.SIGTERM) +} + +func (app *App) shutdowner() Shutdowner { + return &shutdowner{app: app} +} + +func (app *App) broadcastSignal(signal os.Signal) error { + app.donesMu.RLock() + defer app.donesMu.RUnlock() + + var unsent int + for _, done := range app.dones { + select { + case done <- signal: + default: + // shutdown called when done channel has already received a + // termination signal that has not been cleared + unsent++ + } + } + + if unsent != 0 { + return fmt.Errorf("failed to send %v signal to %v out of %v channels", + signal, unsent, len(app.dones), + ) + } + + return nil +} diff --git a/vendor/go.uber.org/fx/version.go b/vendor/go.uber.org/fx/version.go new file mode 100644 index 00000000..1fe32c35 --- /dev/null +++ b/vendor/go.uber.org/fx/version.go @@ -0,0 +1,24 @@ +// Copyright (c) 2019 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package fx + +// Version is exported for runtime compatibility checks. +const Version = "1.9.0" diff --git a/vendor/go.uber.org/multierr/.codecov.yml b/vendor/go.uber.org/multierr/.codecov.yml new file mode 100644 index 00000000..6d4d1be7 --- /dev/null +++ b/vendor/go.uber.org/multierr/.codecov.yml @@ -0,0 +1,15 @@ +coverage: + range: 80..100 + round: down + precision: 2 + + status: + project: # measuring the overall project coverage + default: # context, you can create multiple ones with custom titles + enabled: yes # must be yes|true to enable this status + target: 100 # specify the target coverage for each commit status + # option: "auto" (must increase from parent commit or pull request base) + # option: "X%" a static target percentage to hit + if_not_found: success # if parent is not found report status as success, error, or failure + if_ci_failed: error # if ci fails report status as success, error, or failure + diff --git a/vendor/go.uber.org/multierr/.gitignore b/vendor/go.uber.org/multierr/.gitignore new file mode 100644 index 00000000..61ead866 --- /dev/null +++ b/vendor/go.uber.org/multierr/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/vendor/go.uber.org/multierr/.travis.yml b/vendor/go.uber.org/multierr/.travis.yml new file mode 100644 index 00000000..5ffa8fed --- /dev/null +++ b/vendor/go.uber.org/multierr/.travis.yml @@ -0,0 +1,33 @@ +sudo: false +language: go +go_import_path: go.uber.org/multierr + +env: + global: + - GO15VENDOREXPERIMENT=1 + +go: + - 1.7 + - 1.8 + - tip + +cache: + directories: + - vendor + +before_install: +- go version + +install: +- | + set -e + make install_ci + +script: +- | + set -e + make lint + make test_ci + +after_success: +- bash <(curl -s https://codecov.io/bash) diff --git a/vendor/go.uber.org/multierr/CHANGELOG.md b/vendor/go.uber.org/multierr/CHANGELOG.md new file mode 100644 index 00000000..898445d0 --- /dev/null +++ b/vendor/go.uber.org/multierr/CHANGELOG.md @@ -0,0 +1,28 @@ +Releases +======== + +v1.1.0 (2017-06-30) +=================== + +- Added an `Errors(error) []error` function to extract the underlying list of + errors for a multierr error. + + +v1.0.0 (2017-05-31) +=================== + +No changes since v0.2.0. This release is committing to making no breaking +changes to the current API in the 1.X series. + + +v0.2.0 (2017-04-11) +=================== + +- Repeatedly appending to the same error is now faster due to fewer + allocations. + + +v0.1.0 (2017-31-03) +=================== + +- Initial release diff --git a/vendor/go.uber.org/multierr/LICENSE.txt b/vendor/go.uber.org/multierr/LICENSE.txt new file mode 100644 index 00000000..858e0247 --- /dev/null +++ b/vendor/go.uber.org/multierr/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/go.uber.org/multierr/Makefile b/vendor/go.uber.org/multierr/Makefile new file mode 100644 index 00000000..a7437d06 --- /dev/null +++ b/vendor/go.uber.org/multierr/Makefile @@ -0,0 +1,74 @@ +export GO15VENDOREXPERIMENT=1 + +PACKAGES := $(shell glide nv) + +GO_FILES := $(shell \ + find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ + -o -name '*.go' -print | cut -b3-) + +.PHONY: install +install: + glide --version || go get github.com/Masterminds/glide + glide install + +.PHONY: build +build: + go build -i $(PACKAGES) + +.PHONY: test +test: + go test -cover -race $(PACKAGES) + +.PHONY: gofmt +gofmt: + $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX)) + @gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true + @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false) + +.PHONY: govet +govet: + $(eval VET_LOG := $(shell mktemp -t govet.XXXXX)) + @go vet $(PACKAGES) 2>&1 \ + | grep -v '^exit status' > $(VET_LOG) || true + @[ ! -s "$(VET_LOG)" ] || (echo "govet failed:" | cat - $(VET_LOG) && false) + +.PHONY: golint +golint: + @go get github.com/golang/lint/golint + $(eval LINT_LOG := $(shell mktemp -t golint.XXXXX)) + @cat /dev/null > $(LINT_LOG) + @$(foreach pkg, $(PACKAGES), golint $(pkg) >> $(LINT_LOG) || true;) + @[ ! -s "$(LINT_LOG)" ] || (echo "golint failed:" | cat - $(LINT_LOG) && false) + +.PHONY: staticcheck +staticcheck: + @go get honnef.co/go/tools/cmd/staticcheck + $(eval STATICCHECK_LOG := $(shell mktemp -t staticcheck.XXXXX)) + @staticcheck $(PACKAGES) 2>&1 > $(STATICCHECK_LOG) || true + @[ ! -s "$(STATICCHECK_LOG)" ] || (echo "staticcheck failed:" | cat - $(STATICCHECK_LOG) && false) + +.PHONY: lint +lint: gofmt govet golint staticcheck + +.PHONY: cover +cover: + ./scripts/cover.sh $(shell go list $(PACKAGES)) + go tool cover -html=cover.out -o cover.html + +update-license: + @go get go.uber.org/tools/update-license + @update-license \ + $(shell go list -json $(PACKAGES) | \ + jq -r '.Dir + "/" + (.GoFiles | .[])') + +############################################################################## + +.PHONY: install_ci +install_ci: install + go get github.com/wadey/gocovmerge + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + +.PHONY: test_ci +test_ci: install_ci + ./scripts/cover.sh $(shell go list $(PACKAGES)) diff --git a/vendor/go.uber.org/multierr/README.md b/vendor/go.uber.org/multierr/README.md new file mode 100644 index 00000000..065088f6 --- /dev/null +++ b/vendor/go.uber.org/multierr/README.md @@ -0,0 +1,23 @@ +# multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +`multierr` allows combining one or more Go `error`s together. + +## Installation + + go get -u go.uber.org/multierr + +## Status + +Stable: No breaking changes will be made before 2.0. + +------------------------------------------------------------------------------- + +Released under the [MIT License]. + +[MIT License]: LICENSE.txt +[doc-img]: https://godoc.org/go.uber.org/multierr?status.svg +[doc]: https://godoc.org/go.uber.org/multierr +[ci-img]: https://travis-ci.org/uber-go/multierr.svg?branch=master +[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg +[ci]: https://travis-ci.org/uber-go/multierr +[cov]: https://codecov.io/gh/uber-go/multierr diff --git a/vendor/go.uber.org/multierr/error.go b/vendor/go.uber.org/multierr/error.go new file mode 100644 index 00000000..de6ce473 --- /dev/null +++ b/vendor/go.uber.org/multierr/error.go @@ -0,0 +1,401 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package multierr allows combining one or more errors together. +// +// Overview +// +// Errors can be combined with the use of the Combine function. +// +// multierr.Combine( +// reader.Close(), +// writer.Close(), +// conn.Close(), +// ) +// +// If only two errors are being combined, the Append function may be used +// instead. +// +// err = multierr.Combine(reader.Close(), writer.Close()) +// +// This makes it possible to record resource cleanup failures from deferred +// blocks with the help of named return values. +// +// func sendRequest(req Request) (err error) { +// conn, err := openConnection() +// if err != nil { +// return err +// } +// defer func() { +// err = multierr.Append(err, conn.Close()) +// }() +// // ... +// } +// +// The underlying list of errors for a returned error object may be retrieved +// with the Errors function. +// +// errors := multierr.Errors(err) +// if len(errors) > 0 { +// fmt.Println("The following errors occurred:") +// } +// +// Advanced Usage +// +// Errors returned by Combine and Append MAY implement the following +// interface. +// +// type errorGroup interface { +// // Returns a slice containing the underlying list of errors. +// // +// // This slice MUST NOT be modified by the caller. +// Errors() []error +// } +// +// Note that if you need access to list of errors behind a multierr error, you +// should prefer using the Errors function. That said, if you need cheap +// read-only access to the underlying errors slice, you can attempt to cast +// the error to this interface. You MUST handle the failure case gracefully +// because errors returned by Combine and Append are not guaranteed to +// implement this interface. +// +// var errors []error +// group, ok := err.(errorGroup) +// if ok { +// errors = group.Errors() +// } else { +// errors = []error{err} +// } +package multierr // import "go.uber.org/multierr" + +import ( + "bytes" + "fmt" + "io" + "strings" + "sync" + + "go.uber.org/atomic" +) + +var ( + // Separator for single-line error messages. + _singlelineSeparator = []byte("; ") + + _newline = []byte("\n") + + // Prefix for multi-line messages + _multilinePrefix = []byte("the following errors occurred:") + + // Prefix for the first and following lines of an item in a list of + // multi-line error messages. + // + // For example, if a single item is: + // + // foo + // bar + // + // It will become, + // + // - foo + // bar + _multilineSeparator = []byte("\n - ") + _multilineIndent = []byte(" ") +) + +// _bufferPool is a pool of bytes.Buffers. +var _bufferPool = sync.Pool{ + New: func() interface{} { + return &bytes.Buffer{} + }, +} + +type errorGroup interface { + Errors() []error +} + +// Errors returns a slice containing zero or more errors that the supplied +// error is composed of. If the error is nil, the returned slice is empty. +// +// err := multierr.Append(r.Close(), w.Close()) +// errors := multierr.Errors(err) +// +// If the error is not composed of other errors, the returned slice contains +// just the error that was passed in. +// +// Callers of this function are free to modify the returned slice. +func Errors(err error) []error { + if err == nil { + return nil + } + + // Note that we're casting to multiError, not errorGroup. Our contract is + // that returned errors MAY implement errorGroup. Errors, however, only + // has special behavior for multierr-specific error objects. + // + // This behavior can be expanded in the future but I think it's prudent to + // start with as little as possible in terms of contract and possibility + // of misuse. + eg, ok := err.(*multiError) + if !ok { + return []error{err} + } + + errors := eg.Errors() + result := make([]error, len(errors)) + copy(result, errors) + return result +} + +// multiError is an error that holds one or more errors. +// +// An instance of this is guaranteed to be non-empty and flattened. That is, +// none of the errors inside multiError are other multiErrors. +// +// multiError formats to a semi-colon delimited list of error messages with +// %v and with a more readable multi-line format with %+v. +type multiError struct { + copyNeeded atomic.Bool + errors []error +} + +var _ errorGroup = (*multiError)(nil) + +// Errors returns the list of underlying errors. +// +// This slice MUST NOT be modified. +func (merr *multiError) Errors() []error { + if merr == nil { + return nil + } + return merr.errors +} + +func (merr *multiError) Error() string { + if merr == nil { + return "" + } + + buff := _bufferPool.Get().(*bytes.Buffer) + buff.Reset() + + merr.writeSingleline(buff) + + result := buff.String() + _bufferPool.Put(buff) + return result +} + +func (merr *multiError) Format(f fmt.State, c rune) { + if c == 'v' && f.Flag('+') { + merr.writeMultiline(f) + } else { + merr.writeSingleline(f) + } +} + +func (merr *multiError) writeSingleline(w io.Writer) { + first := true + for _, item := range merr.errors { + if first { + first = false + } else { + w.Write(_singlelineSeparator) + } + io.WriteString(w, item.Error()) + } +} + +func (merr *multiError) writeMultiline(w io.Writer) { + w.Write(_multilinePrefix) + for _, item := range merr.errors { + w.Write(_multilineSeparator) + writePrefixLine(w, _multilineIndent, fmt.Sprintf("%+v", item)) + } +} + +// Writes s to the writer with the given prefix added before each line after +// the first. +func writePrefixLine(w io.Writer, prefix []byte, s string) { + first := true + for len(s) > 0 { + if first { + first = false + } else { + w.Write(prefix) + } + + idx := strings.IndexByte(s, '\n') + if idx < 0 { + idx = len(s) - 1 + } + + io.WriteString(w, s[:idx+1]) + s = s[idx+1:] + } +} + +type inspectResult struct { + // Number of top-level non-nil errors + Count int + + // Total number of errors including multiErrors + Capacity int + + // Index of the first non-nil error in the list. Value is meaningless if + // Count is zero. + FirstErrorIdx int + + // Whether the list contains at least one multiError + ContainsMultiError bool +} + +// Inspects the given slice of errors so that we can efficiently allocate +// space for it. +func inspect(errors []error) (res inspectResult) { + first := true + for i, err := range errors { + if err == nil { + continue + } + + res.Count++ + if first { + first = false + res.FirstErrorIdx = i + } + + if merr, ok := err.(*multiError); ok { + res.Capacity += len(merr.errors) + res.ContainsMultiError = true + } else { + res.Capacity++ + } + } + return +} + +// fromSlice converts the given list of errors into a single error. +func fromSlice(errors []error) error { + res := inspect(errors) + switch res.Count { + case 0: + return nil + case 1: + // only one non-nil entry + return errors[res.FirstErrorIdx] + case len(errors): + if !res.ContainsMultiError { + // already flat + return &multiError{errors: errors} + } + } + + nonNilErrs := make([]error, 0, res.Capacity) + for _, err := range errors[res.FirstErrorIdx:] { + if err == nil { + continue + } + + if nested, ok := err.(*multiError); ok { + nonNilErrs = append(nonNilErrs, nested.errors...) + } else { + nonNilErrs = append(nonNilErrs, err) + } + } + + return &multiError{errors: nonNilErrs} +} + +// Combine combines the passed errors into a single error. +// +// If zero arguments were passed or if all items are nil, a nil error is +// returned. +// +// Combine(nil, nil) // == nil +// +// If only a single error was passed, it is returned as-is. +// +// Combine(err) // == err +// +// Combine skips over nil arguments so this function may be used to combine +// together errors from operations that fail independently of each other. +// +// multierr.Combine( +// reader.Close(), +// writer.Close(), +// pipe.Close(), +// ) +// +// If any of the passed errors is a multierr error, it will be flattened along +// with the other errors. +// +// multierr.Combine(multierr.Combine(err1, err2), err3) +// // is the same as +// multierr.Combine(err1, err2, err3) +// +// The returned error formats into a readable multi-line error message if +// formatted with %+v. +// +// fmt.Sprintf("%+v", multierr.Combine(err1, err2)) +func Combine(errors ...error) error { + return fromSlice(errors) +} + +// Append appends the given errors together. Either value may be nil. +// +// This function is a specialization of Combine for the common case where +// there are only two errors. +// +// err = multierr.Append(reader.Close(), writer.Close()) +// +// The following pattern may also be used to record failure of deferred +// operations without losing information about the original error. +// +// func doSomething(..) (err error) { +// f := acquireResource() +// defer func() { +// err = multierr.Append(err, f.Close()) +// }() +func Append(left error, right error) error { + switch { + case left == nil: + return right + case right == nil: + return left + } + + if _, ok := right.(*multiError); !ok { + if l, ok := left.(*multiError); ok && !l.copyNeeded.Swap(true) { + // Common case where the error on the left is constantly being + // appended to. + errs := append(l.errors, right) + return &multiError{errors: errs} + } else if !ok { + // Both errors are single errors. + return &multiError{errors: []error{left, right}} + } + } + + // Either right or both, left and right, are multiErrors. Rely on usual + // expensive logic. + errors := [2]error{left, right} + return fromSlice(errors[0:]) +} diff --git a/vendor/go.uber.org/multierr/glide.lock b/vendor/go.uber.org/multierr/glide.lock new file mode 100644 index 00000000..f9ea94c3 --- /dev/null +++ b/vendor/go.uber.org/multierr/glide.lock @@ -0,0 +1,19 @@ +hash: b53b5e9a84b9cb3cc4b2d0499e23da2feca1eec318ce9bb717ecf35bf24bf221 +updated: 2017-04-10T13:34:45.671678062-07:00 +imports: +- name: go.uber.org/atomic + version: 3b8db5e93c4c02efbc313e17b2e796b0914a01fb +testImports: +- name: github.com/davecgh/go-spew + version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/testify + version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + subpackages: + - assert + - require diff --git a/vendor/go.uber.org/multierr/glide.yaml b/vendor/go.uber.org/multierr/glide.yaml new file mode 100644 index 00000000..6ef084ec --- /dev/null +++ b/vendor/go.uber.org/multierr/glide.yaml @@ -0,0 +1,8 @@ +package: go.uber.org/multierr +import: +- package: go.uber.org/atomic + version: ^1 +testImport: +- package: github.com/stretchr/testify + subpackages: + - assert diff --git a/vendor/go4.org/AUTHORS b/vendor/go4.org/AUTHORS new file mode 100644 index 00000000..d1ad485f --- /dev/null +++ b/vendor/go4.org/AUTHORS @@ -0,0 +1,8 @@ +# This is the official list of go4 authors for copyright purposes. +# This is distinct from the CONTRIBUTORS file, which is the list of +# people who have contributed, even if they don't own the copyright on +# their work. + +Mathieu Lonjaret +Daniel Theophanes +Google diff --git a/vendor/go4.org/LICENSE b/vendor/go4.org/LICENSE new file mode 100644 index 00000000..8f71f43f --- /dev/null +++ b/vendor/go4.org/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/go4.org/lock/.gitignore b/vendor/go4.org/lock/.gitignore new file mode 100644 index 00000000..b25c15b8 --- /dev/null +++ b/vendor/go4.org/lock/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/vendor/go4.org/lock/lock.go b/vendor/go4.org/lock/lock.go new file mode 100644 index 00000000..3e253628 --- /dev/null +++ b/vendor/go4.org/lock/lock.go @@ -0,0 +1,186 @@ +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package lock is a file locking library. +package lock // import "go4.org/lock" + +import ( + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "sync" +) + +// Lock locks the given file, creating the file if necessary. If the +// file already exists, it must have zero size or an error is returned. +// The lock is an exclusive lock (a write lock), but locked files +// should neither be read from nor written to. Such files should have +// zero size and only exist to co-ordinate ownership across processes. +// +// A nil Closer is returned if an error occurred. Otherwise, close that +// Closer to release the lock. +// +// On Linux, FreeBSD and OSX, a lock has the same semantics as fcntl(2)'s +// advisory locks. In particular, closing any other file descriptor for the +// same file will release the lock prematurely. +// +// Attempting to lock a file that is already locked by the current process +// has undefined behavior. +// +// On other operating systems, lock will fallback to using the presence and +// content of a file named name + '.lock' to implement locking behavior. +func Lock(name string) (io.Closer, error) { + abs, err := filepath.Abs(name) + if err != nil { + return nil, err + } + lockmu.Lock() + defer lockmu.Unlock() + if locked[abs] { + return nil, fmt.Errorf("file %q already locked", abs) + } + + c, err := lockFn(abs) + if err != nil { + return nil, fmt.Errorf("cannot acquire lock: %v", err) + } + locked[abs] = true + return c, nil +} + +var lockFn = lockPortable + +// lockPortable is a portable version not using fcntl. Doesn't handle crashes as gracefully, +// since it can leave stale lock files. +func lockPortable(name string) (io.Closer, error) { + fi, err := os.Stat(name) + if err == nil && fi.Size() > 0 { + st := portableLockStatus(name) + switch st { + case statusLocked: + return nil, fmt.Errorf("file %q already locked", name) + case statusStale: + os.Remove(name) + case statusInvalid: + return nil, fmt.Errorf("can't Lock file %q: has invalid contents", name) + } + } + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_EXCL, 0666) + if err != nil { + return nil, fmt.Errorf("failed to create lock file %s %v", name, err) + } + if err := json.NewEncoder(f).Encode(&pidLockMeta{OwnerPID: os.Getpid()}); err != nil { + return nil, fmt.Errorf("cannot write owner pid: %v", err) + } + return &unlocker{ + f: f, + abs: name, + portable: true, + }, nil +} + +type lockStatus int + +const ( + statusInvalid lockStatus = iota + statusLocked + statusUnlocked + statusStale +) + +type pidLockMeta struct { + OwnerPID int +} + +func portableLockStatus(path string) lockStatus { + f, err := os.Open(path) + if err != nil { + return statusUnlocked + } + defer f.Close() + var meta pidLockMeta + if json.NewDecoder(f).Decode(&meta) != nil { + return statusInvalid + } + if meta.OwnerPID == 0 { + return statusInvalid + } + p, err := os.FindProcess(meta.OwnerPID) + if err != nil { + // e.g. on Windows + return statusStale + } + // On unix, os.FindProcess always is true, so we have to send + // it a signal to see if it's alive. + if signalZero != nil { + if p.Signal(signalZero) != nil { + return statusStale + } + } + return statusLocked +} + +var signalZero os.Signal // nil or set by lock_sigzero.go + +var ( + lockmu sync.Mutex + locked = map[string]bool{} // abs path -> true +) + +type unlocker struct { + portable bool + f *os.File + abs string + // once guards the close method call. + once sync.Once + // err holds the error returned by Close. + err error +} + +func (u *unlocker) Close() error { + u.once.Do(u.close) + return u.err +} + +func (u *unlocker) close() { + lockmu.Lock() + defer lockmu.Unlock() + delete(locked, u.abs) + + if u.portable { + // In the portable lock implementation, it's + // important to close before removing because + // Windows won't allow us to remove an open + // file. + if err := u.f.Close(); err != nil { + u.err = err + } + if err := os.Remove(u.abs); err != nil { + // Note that if both Close and Remove fail, + // we care more about the latter than the former + // so we'll return that error. + u.err = err + } + return + } + // In other implementatioons, it's nice for us to clean up. + // If we do do this, though, it needs to be before the + // u.f.Close below. + os.Remove(u.abs) + u.err = u.f.Close() +} diff --git a/vendor/go4.org/lock/lock_appengine.go b/vendor/go4.org/lock/lock_appengine.go new file mode 100644 index 00000000..ab4cad6a --- /dev/null +++ b/vendor/go4.org/lock/lock_appengine.go @@ -0,0 +1,32 @@ +// +build appengine + +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package lock + +import ( + "errors" + "io" +) + +func init() { + lockFn = lockAppEngine +} + +func lockAppEngine(name string) (io.Closer, error) { + return nil, errors.New("Lock not available on App Engine") +} diff --git a/vendor/go4.org/lock/lock_plan9.go b/vendor/go4.org/lock/lock_plan9.go new file mode 100644 index 00000000..d841c27d --- /dev/null +++ b/vendor/go4.org/lock/lock_plan9.go @@ -0,0 +1,41 @@ +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package lock + +import ( + "fmt" + "io" + "os" +) + +func init() { + lockFn = lockPlan9 +} + +func lockPlan9(name string) (io.Closer, error) { + fi, err := os.Stat(name) + if err == nil && fi.Size() > 0 { + return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name) + } + + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, os.ModeExclusive|0644) + if err != nil { + return nil, fmt.Errorf("Lock Create of %s failed: %v", name, err) + } + + return &unlocker{f: f, abs: name}, nil +} diff --git a/vendor/go4.org/lock/lock_sigzero.go b/vendor/go4.org/lock/lock_sigzero.go new file mode 100644 index 00000000..fd3ba2db --- /dev/null +++ b/vendor/go4.org/lock/lock_sigzero.go @@ -0,0 +1,26 @@ +// +build !appengine +// +build linux darwin freebsd openbsd netbsd dragonfly + +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package lock + +import "syscall" + +func init() { + signalZero = syscall.Signal(0) +} diff --git a/vendor/go4.org/lock/lock_unix.go b/vendor/go4.org/lock/lock_unix.go new file mode 100644 index 00000000..d26056b5 --- /dev/null +++ b/vendor/go4.org/lock/lock_unix.go @@ -0,0 +1,58 @@ +// +build linux darwin freebsd openbsd netbsd dragonfly solaris +// +build !appengine + +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package lock + +import ( + "fmt" + "io" + "os" + + "golang.org/x/sys/unix" +) + +func init() { + lockFn = lockFcntl +} + +func lockFcntl(name string) (io.Closer, error) { + fi, err := os.Stat(name) + if err == nil && fi.Size() > 0 { + return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name) + } + + f, err := os.Create(name) + if err != nil { + return nil, fmt.Errorf("Lock Create of %s failed: %v", name, err) + } + + err = unix.FcntlFlock(f.Fd(), unix.F_SETLK, &unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: int16(os.SEEK_SET), + Start: 0, + Len: 0, // 0 means to lock the entire file. + Pid: 0, // only used by F_GETLK + }) + + if err != nil { + f.Close() + return nil, fmt.Errorf("Lock FcntlFlock of %s failed: %v", name, err) + } + return &unlocker{f: f, abs: name}, nil +} diff --git a/vendor/go4.org/lock/lock_windows.go b/vendor/go4.org/lock/lock_windows.go new file mode 100644 index 00000000..42574879 --- /dev/null +++ b/vendor/go4.org/lock/lock_windows.go @@ -0,0 +1,78 @@ +/* +Copyright 2013 The Go Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package lock + +import ( + "fmt" + "io" + "os" + "sync" + + "golang.org/x/sys/windows" +) + +func init() { + lockFn = lockWindows +} + +type winUnlocker struct { + h windows.Handle + abs string + // err holds the error returned by Close. + err error + // once guards the close method call. + once sync.Once +} + +func (u *winUnlocker) Close() error { + u.once.Do(u.close) + return u.err +} + +func (u *winUnlocker) close() { + lockmu.Lock() + defer lockmu.Unlock() + delete(locked, u.abs) + + u.err = windows.CloseHandle(u.h) +} + +func lockWindows(name string) (io.Closer, error) { + fi, err := os.Stat(name) + if err == nil && fi.Size() > 0 { + return nil, fmt.Errorf("can't lock file %q: %s", name, "has non-zero size") + } + + handle, err := winCreateEphemeral(name) + if err != nil { + return nil, fmt.Errorf("creation of lock %s failed: %v", name, err) + } + + return &winUnlocker{h: handle, abs: name}, nil +} + +func winCreateEphemeral(name string) (windows.Handle, error) { + const ( + FILE_ATTRIBUTE_TEMPORARY = 0x100 + FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 + ) + handle, err := windows.CreateFile(windows.StringToUTF16Ptr(name), 0, 0, nil, windows.OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, 0) + if err != nil { + return 0, err + } + return handle, nil +} diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go new file mode 100644 index 00000000..24a1ff22 --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go @@ -0,0 +1,178 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blake2s + +import ( + "math/bits" +) + +// the precomputed values for BLAKE2s +// there are 10 16-byte arrays - one for each round +// the entries are calculated from the sigma constants. +var precomputed = [10][16]byte{ + {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, + {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, + {11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4}, + {7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8}, + {9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13}, + {2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9}, + {12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11}, + {13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10}, + {6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5}, + {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0}, +} + +func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) { + var m [16]uint32 + c0, c1 := c[0], c[1] + + for i := 0; i < len(blocks); { + c0 += BlockSize + if c0 < BlockSize { + c1++ + } + + v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] + v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7] + v12 ^= c0 + v13 ^= c1 + v14 ^= flag + + for j := range m { + m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24 + i += 4 + } + + for k := range precomputed { + s := &(precomputed[k]) + + v0 += m[s[0]] + v0 += v4 + v12 ^= v0 + v12 = bits.RotateLeft32(v12, -16) + v8 += v12 + v4 ^= v8 + v4 = bits.RotateLeft32(v4, -12) + v1 += m[s[1]] + v1 += v5 + v13 ^= v1 + v13 = bits.RotateLeft32(v13, -16) + v9 += v13 + v5 ^= v9 + v5 = bits.RotateLeft32(v5, -12) + v2 += m[s[2]] + v2 += v6 + v14 ^= v2 + v14 = bits.RotateLeft32(v14, -16) + v10 += v14 + v6 ^= v10 + v6 = bits.RotateLeft32(v6, -12) + v3 += m[s[3]] + v3 += v7 + v15 ^= v3 + v15 = bits.RotateLeft32(v15, -16) + v11 += v15 + v7 ^= v11 + v7 = bits.RotateLeft32(v7, -12) + + v0 += m[s[4]] + v0 += v4 + v12 ^= v0 + v12 = bits.RotateLeft32(v12, -8) + v8 += v12 + v4 ^= v8 + v4 = bits.RotateLeft32(v4, -7) + v1 += m[s[5]] + v1 += v5 + v13 ^= v1 + v13 = bits.RotateLeft32(v13, -8) + v9 += v13 + v5 ^= v9 + v5 = bits.RotateLeft32(v5, -7) + v2 += m[s[6]] + v2 += v6 + v14 ^= v2 + v14 = bits.RotateLeft32(v14, -8) + v10 += v14 + v6 ^= v10 + v6 = bits.RotateLeft32(v6, -7) + v3 += m[s[7]] + v3 += v7 + v15 ^= v3 + v15 = bits.RotateLeft32(v15, -8) + v11 += v15 + v7 ^= v11 + v7 = bits.RotateLeft32(v7, -7) + + v0 += m[s[8]] + v0 += v5 + v15 ^= v0 + v15 = bits.RotateLeft32(v15, -16) + v10 += v15 + v5 ^= v10 + v5 = bits.RotateLeft32(v5, -12) + v1 += m[s[9]] + v1 += v6 + v12 ^= v1 + v12 = bits.RotateLeft32(v12, -16) + v11 += v12 + v6 ^= v11 + v6 = bits.RotateLeft32(v6, -12) + v2 += m[s[10]] + v2 += v7 + v13 ^= v2 + v13 = bits.RotateLeft32(v13, -16) + v8 += v13 + v7 ^= v8 + v7 = bits.RotateLeft32(v7, -12) + v3 += m[s[11]] + v3 += v4 + v14 ^= v3 + v14 = bits.RotateLeft32(v14, -16) + v9 += v14 + v4 ^= v9 + v4 = bits.RotateLeft32(v4, -12) + + v0 += m[s[12]] + v0 += v5 + v15 ^= v0 + v15 = bits.RotateLeft32(v15, -8) + v10 += v15 + v5 ^= v10 + v5 = bits.RotateLeft32(v5, -7) + v1 += m[s[13]] + v1 += v6 + v12 ^= v1 + v12 = bits.RotateLeft32(v12, -8) + v11 += v12 + v6 ^= v11 + v6 = bits.RotateLeft32(v6, -7) + v2 += m[s[14]] + v2 += v7 + v13 ^= v2 + v13 = bits.RotateLeft32(v13, -8) + v8 += v13 + v7 ^= v8 + v7 = bits.RotateLeft32(v7, -7) + v3 += m[s[15]] + v3 += v4 + v14 ^= v3 + v14 = bits.RotateLeft32(v14, -8) + v9 += v14 + v4 ^= v9 + v4 = bits.RotateLeft32(v4, -7) + } + + h[0] ^= v0 ^ v8 + h[1] ^= v1 ^ v9 + h[2] ^= v2 ^ v10 + h[3] ^= v3 ^ v11 + h[4] ^= v4 ^ v12 + h[5] ^= v5 ^ v13 + h[6] ^= v6 ^ v14 + h[7] ^= v7 ^ v15 + } + c[0], c[1] = c0, c1 +} diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go new file mode 100644 index 00000000..213bf204 --- /dev/null +++ b/vendor/golang.org/x/crypto/blowfish/cipher.go @@ -0,0 +1,99 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm. +// +// Blowfish is a legacy cipher and its short block size makes it vulnerable to +// birthday bound attacks (see https://sweet32.info). It should only be used +// where compatibility with legacy systems, not security, is the goal. +// +// Deprecated: any new system should use AES (from crypto/aes, if necessary in +// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from +// golang.org/x/crypto/chacha20poly1305). +package blowfish // import "golang.org/x/crypto/blowfish" + +// The code is a port of Bruce Schneier's C implementation. +// See https://www.schneier.com/blowfish.html. + +import "strconv" + +// The Blowfish block size in bytes. +const BlockSize = 8 + +// A Cipher is an instance of Blowfish encryption using a particular key. +type Cipher struct { + p [18]uint32 + s0, s1, s2, s3 [256]uint32 +} + +type KeySizeError int + +func (k KeySizeError) Error() string { + return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k)) +} + +// NewCipher creates and returns a Cipher. +// The key argument should be the Blowfish key, from 1 to 56 bytes. +func NewCipher(key []byte) (*Cipher, error) { + var result Cipher + if k := len(key); k < 1 || k > 56 { + return nil, KeySizeError(k) + } + initCipher(&result) + ExpandKey(key, &result) + return &result, nil +} + +// NewSaltedCipher creates a returns a Cipher that folds a salt into its key +// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is +// sufficient and desirable. For bcrypt compatibility, the key can be over 56 +// bytes. +func NewSaltedCipher(key, salt []byte) (*Cipher, error) { + if len(salt) == 0 { + return NewCipher(key) + } + var result Cipher + if k := len(key); k < 1 { + return nil, KeySizeError(k) + } + initCipher(&result) + expandKeyWithSalt(key, salt, &result) + return &result, nil +} + +// BlockSize returns the Blowfish block size, 8 bytes. +// It is necessary to satisfy the Block interface in the +// package "crypto/cipher". +func (c *Cipher) BlockSize() int { return BlockSize } + +// Encrypt encrypts the 8-byte buffer src using the key k +// and stores the result in dst. +// Note that for amounts of data larger than a block, +// it is not safe to just call Encrypt on successive blocks; +// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). +func (c *Cipher) Encrypt(dst, src []byte) { + l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) + r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) + l, r = encryptBlock(l, r, c) + dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) + dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) +} + +// Decrypt decrypts the 8-byte buffer src using the key k +// and stores the result in dst. +func (c *Cipher) Decrypt(dst, src []byte) { + l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) + r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) + l, r = decryptBlock(l, r, c) + dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) + dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) +} + +func initCipher(c *Cipher) { + copy(c.p[0:], p[0:]) + copy(c.s0[0:], s0[0:]) + copy(c.s1[0:], s1[0:]) + copy(c.s2[0:], s2[0:]) + copy(c.s3[0:], s3[0:]) +} diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s new file mode 100644 index 00000000..9dd5d7a9 --- /dev/null +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s @@ -0,0 +1,2695 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file was originally from https://golang.org/cl/24717 by Vlad Krasnov of CloudFlare. + +// +build go1.7,amd64,!gccgo,!appengine + +#include "textflag.h" +// General register allocation +#define oup DI +#define inp SI +#define inl BX +#define adp CX // free to reuse, after we hash the additional data +#define keyp R8 // free to reuse, when we copy the key to stack +#define itr2 R9 // general iterator +#define itr1 CX // general iterator +#define acc0 R10 +#define acc1 R11 +#define acc2 R12 +#define t0 R13 +#define t1 R14 +#define t2 R15 +#define t3 R8 +// Register and stack allocation for the SSE code +#define rStore (0*16)(BP) +#define sStore (1*16)(BP) +#define state1Store (2*16)(BP) +#define state2Store (3*16)(BP) +#define tmpStore (4*16)(BP) +#define ctr0Store (5*16)(BP) +#define ctr1Store (6*16)(BP) +#define ctr2Store (7*16)(BP) +#define ctr3Store (8*16)(BP) +#define A0 X0 +#define A1 X1 +#define A2 X2 +#define B0 X3 +#define B1 X4 +#define B2 X5 +#define C0 X6 +#define C1 X7 +#define C2 X8 +#define D0 X9 +#define D1 X10 +#define D2 X11 +#define T0 X12 +#define T1 X13 +#define T2 X14 +#define T3 X15 +#define A3 T0 +#define B3 T1 +#define C3 T2 +#define D3 T3 +// Register and stack allocation for the AVX2 code +#define rsStoreAVX2 (0*32)(BP) +#define state1StoreAVX2 (1*32)(BP) +#define state2StoreAVX2 (2*32)(BP) +#define ctr0StoreAVX2 (3*32)(BP) +#define ctr1StoreAVX2 (4*32)(BP) +#define ctr2StoreAVX2 (5*32)(BP) +#define ctr3StoreAVX2 (6*32)(BP) +#define tmpStoreAVX2 (7*32)(BP) // 256 bytes on stack +#define AA0 Y0 +#define AA1 Y5 +#define AA2 Y6 +#define AA3 Y7 +#define BB0 Y14 +#define BB1 Y9 +#define BB2 Y10 +#define BB3 Y11 +#define CC0 Y12 +#define CC1 Y13 +#define CC2 Y8 +#define CC3 Y15 +#define DD0 Y4 +#define DD1 Y1 +#define DD2 Y2 +#define DD3 Y3 +#define TT0 DD3 +#define TT1 AA3 +#define TT2 BB3 +#define TT3 CC3 +// ChaCha20 constants +DATA ·chacha20Constants<>+0x00(SB)/4, $0x61707865 +DATA ·chacha20Constants<>+0x04(SB)/4, $0x3320646e +DATA ·chacha20Constants<>+0x08(SB)/4, $0x79622d32 +DATA ·chacha20Constants<>+0x0c(SB)/4, $0x6b206574 +DATA ·chacha20Constants<>+0x10(SB)/4, $0x61707865 +DATA ·chacha20Constants<>+0x14(SB)/4, $0x3320646e +DATA ·chacha20Constants<>+0x18(SB)/4, $0x79622d32 +DATA ·chacha20Constants<>+0x1c(SB)/4, $0x6b206574 +// <<< 16 with PSHUFB +DATA ·rol16<>+0x00(SB)/8, $0x0504070601000302 +DATA ·rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A +DATA ·rol16<>+0x10(SB)/8, $0x0504070601000302 +DATA ·rol16<>+0x18(SB)/8, $0x0D0C0F0E09080B0A +// <<< 8 with PSHUFB +DATA ·rol8<>+0x00(SB)/8, $0x0605040702010003 +DATA ·rol8<>+0x08(SB)/8, $0x0E0D0C0F0A09080B +DATA ·rol8<>+0x10(SB)/8, $0x0605040702010003 +DATA ·rol8<>+0x18(SB)/8, $0x0E0D0C0F0A09080B + +DATA ·avx2InitMask<>+0x00(SB)/8, $0x0 +DATA ·avx2InitMask<>+0x08(SB)/8, $0x0 +DATA ·avx2InitMask<>+0x10(SB)/8, $0x1 +DATA ·avx2InitMask<>+0x18(SB)/8, $0x0 + +DATA ·avx2IncMask<>+0x00(SB)/8, $0x2 +DATA ·avx2IncMask<>+0x08(SB)/8, $0x0 +DATA ·avx2IncMask<>+0x10(SB)/8, $0x2 +DATA ·avx2IncMask<>+0x18(SB)/8, $0x0 +// Poly1305 key clamp +DATA ·polyClampMask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF +DATA ·polyClampMask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC +DATA ·polyClampMask<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF +DATA ·polyClampMask<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF + +DATA ·sseIncMask<>+0x00(SB)/8, $0x1 +DATA ·sseIncMask<>+0x08(SB)/8, $0x0 +// To load/store the last < 16 bytes in a buffer +DATA ·andMask<>+0x00(SB)/8, $0x00000000000000ff +DATA ·andMask<>+0x08(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x10(SB)/8, $0x000000000000ffff +DATA ·andMask<>+0x18(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x20(SB)/8, $0x0000000000ffffff +DATA ·andMask<>+0x28(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x30(SB)/8, $0x00000000ffffffff +DATA ·andMask<>+0x38(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x40(SB)/8, $0x000000ffffffffff +DATA ·andMask<>+0x48(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x50(SB)/8, $0x0000ffffffffffff +DATA ·andMask<>+0x58(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x60(SB)/8, $0x00ffffffffffffff +DATA ·andMask<>+0x68(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x70(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x78(SB)/8, $0x0000000000000000 +DATA ·andMask<>+0x80(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x88(SB)/8, $0x00000000000000ff +DATA ·andMask<>+0x90(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0x98(SB)/8, $0x000000000000ffff +DATA ·andMask<>+0xa0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xa8(SB)/8, $0x0000000000ffffff +DATA ·andMask<>+0xb0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xb8(SB)/8, $0x00000000ffffffff +DATA ·andMask<>+0xc0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xc8(SB)/8, $0x000000ffffffffff +DATA ·andMask<>+0xd0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xd8(SB)/8, $0x0000ffffffffffff +DATA ·andMask<>+0xe0(SB)/8, $0xffffffffffffffff +DATA ·andMask<>+0xe8(SB)/8, $0x00ffffffffffffff + +GLOBL ·chacha20Constants<>(SB), (NOPTR+RODATA), $32 +GLOBL ·rol16<>(SB), (NOPTR+RODATA), $32 +GLOBL ·rol8<>(SB), (NOPTR+RODATA), $32 +GLOBL ·sseIncMask<>(SB), (NOPTR+RODATA), $16 +GLOBL ·avx2IncMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·avx2InitMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·polyClampMask<>(SB), (NOPTR+RODATA), $32 +GLOBL ·andMask<>(SB), (NOPTR+RODATA), $240 +// No PALIGNR in Go ASM yet (but VPALIGNR is present). +#define shiftB0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X3, X3 +#define shiftB1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x04 // PALIGNR $4, X4, X4 +#define shiftB2Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X5, X5 +#define shiftB3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x04 // PALIGNR $4, X13, X13 +#define shiftC0Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X6, X6 +#define shiftC1Left BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x08 // PALIGNR $8, X7, X7 +#define shiftC2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc0; BYTE $0x08 // PALIGNR $8, X8, X8 +#define shiftC3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xf6; BYTE $0x08 // PALIGNR $8, X14, X14 +#define shiftD0Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x0c // PALIGNR $12, X9, X9 +#define shiftD1Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x0c // PALIGNR $12, X10, X10 +#define shiftD2Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X11, X11 +#define shiftD3Left BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x0c // PALIGNR $12, X15, X15 +#define shiftB0Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x0c // PALIGNR $12, X3, X3 +#define shiftB1Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xe4; BYTE $0x0c // PALIGNR $12, X4, X4 +#define shiftB2Right BYTE $0x66; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X5, X5 +#define shiftB3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xed; BYTE $0x0c // PALIGNR $12, X13, X13 +#define shiftC0Right shiftC0Left +#define shiftC1Right shiftC1Left +#define shiftC2Right shiftC2Left +#define shiftC3Right shiftC3Left +#define shiftD0Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xc9; BYTE $0x04 // PALIGNR $4, X9, X9 +#define shiftD1Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xd2; BYTE $0x04 // PALIGNR $4, X10, X10 +#define shiftD2Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xdb; BYTE $0x04 // PALIGNR $4, X11, X11 +#define shiftD3Right BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0x3a; BYTE $0x0f; BYTE $0xff; BYTE $0x04 // PALIGNR $4, X15, X15 +// Some macros +#define chachaQR(A, B, C, D, T) \ + PADDD B, A; PXOR A, D; PSHUFB ·rol16<>(SB), D \ + PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $12, T; PSRLL $20, B; PXOR T, B \ + PADDD B, A; PXOR A, D; PSHUFB ·rol8<>(SB), D \ + PADDD D, C; PXOR C, B; MOVO B, T; PSLLL $7, T; PSRLL $25, B; PXOR T, B + +#define chachaQR_AVX2(A, B, C, D, T) \ + VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol16<>(SB), D, D \ + VPADDD D, C, C; VPXOR C, B, B; VPSLLD $12, B, T; VPSRLD $20, B, B; VPXOR T, B, B \ + VPADDD B, A, A; VPXOR A, D, D; VPSHUFB ·rol8<>(SB), D, D \ + VPADDD D, C, C; VPXOR C, B, B; VPSLLD $7, B, T; VPSRLD $25, B, B; VPXOR T, B, B + +#define polyAdd(S) ADDQ S, acc0; ADCQ 8+S, acc1; ADCQ $1, acc2 +#define polyMulStage1 MOVQ (0*8)(BP), AX; MOVQ AX, t2; MULQ acc0; MOVQ AX, t0; MOVQ DX, t1; MOVQ (0*8)(BP), AX; MULQ acc1; IMULQ acc2, t2; ADDQ AX, t1; ADCQ DX, t2 +#define polyMulStage2 MOVQ (1*8)(BP), AX; MOVQ AX, t3; MULQ acc0; ADDQ AX, t1; ADCQ $0, DX; MOVQ DX, acc0; MOVQ (1*8)(BP), AX; MULQ acc1; ADDQ AX, t2; ADCQ $0, DX +#define polyMulStage3 IMULQ acc2, t3; ADDQ acc0, t2; ADCQ DX, t3 +#define polyMulReduceStage MOVQ t0, acc0; MOVQ t1, acc1; MOVQ t2, acc2; ANDQ $3, acc2; MOVQ t2, t0; ANDQ $-4, t0; MOVQ t3, t1; SHRQ $2, t3, t2; SHRQ $2, t3; ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $0, acc2; ADDQ t2, acc0; ADCQ t3, acc1; ADCQ $0, acc2 + +#define polyMulStage1_AVX2 MOVQ (0*8)(BP), DX; MOVQ DX, t2; MULXQ acc0, t0, t1; IMULQ acc2, t2; MULXQ acc1, AX, DX; ADDQ AX, t1; ADCQ DX, t2 +#define polyMulStage2_AVX2 MOVQ (1*8)(BP), DX; MULXQ acc0, acc0, AX; ADDQ acc0, t1; MULXQ acc1, acc1, t3; ADCQ acc1, t2; ADCQ $0, t3 +#define polyMulStage3_AVX2 IMULQ acc2, DX; ADDQ AX, t2; ADCQ DX, t3 + +#define polyMul polyMulStage1; polyMulStage2; polyMulStage3; polyMulReduceStage +#define polyMulAVX2 polyMulStage1_AVX2; polyMulStage2_AVX2; polyMulStage3_AVX2; polyMulReduceStage +// ---------------------------------------------------------------------------- +TEXT polyHashADInternal<>(SB), NOSPLIT, $0 + // adp points to beginning of additional data + // itr2 holds ad length + XORQ acc0, acc0 + XORQ acc1, acc1 + XORQ acc2, acc2 + CMPQ itr2, $13 + JNE hashADLoop + +openFastTLSAD: + // Special treatment for the TLS case of 13 bytes + MOVQ (adp), acc0 + MOVQ 5(adp), acc1 + SHRQ $24, acc1 + MOVQ $1, acc2 + polyMul + RET + +hashADLoop: + // Hash in 16 byte chunks + CMPQ itr2, $16 + JB hashADTail + polyAdd(0(adp)) + LEAQ (1*16)(adp), adp + SUBQ $16, itr2 + polyMul + JMP hashADLoop + +hashADTail: + CMPQ itr2, $0 + JE hashADDone + + // Hash last < 16 byte tail + XORQ t0, t0 + XORQ t1, t1 + XORQ t2, t2 + ADDQ itr2, adp + +hashADTailLoop: + SHLQ $8, t0, t1 + SHLQ $8, t0 + MOVB -1(adp), t2 + XORQ t2, t0 + DECQ adp + DECQ itr2 + JNE hashADTailLoop + +hashADTailFinish: + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + // Finished AD +hashADDone: + RET + +// ---------------------------------------------------------------------------- +// func chacha20Poly1305Open(dst, key, src, ad []byte) bool +TEXT ·chacha20Poly1305Open(SB), 0, $288-97 + // For aligned stack access + MOVQ SP, BP + ADDQ $32, BP + ANDQ $-32, BP + MOVQ dst+0(FP), oup + MOVQ key+24(FP), keyp + MOVQ src+48(FP), inp + MOVQ src_len+56(FP), inl + MOVQ ad+72(FP), adp + + // Check for AVX2 support + CMPB ·useAVX2(SB), $1 + JE chacha20Poly1305Open_AVX2 + + // Special optimization, for very short buffers + CMPQ inl, $128 + JBE openSSE128 // About 16% faster + + // For long buffers, prepare the poly key first + MOVOU ·chacha20Constants<>(SB), A0 + MOVOU (1*16)(keyp), B0 + MOVOU (2*16)(keyp), C0 + MOVOU (3*16)(keyp), D0 + MOVO D0, T1 + + // Store state on stack for future use + MOVO B0, state1Store + MOVO C0, state2Store + MOVO D0, ctr3Store + MOVQ $10, itr2 + +openSSEPreparePolyKey: + chachaQR(A0, B0, C0, D0, T0) + shiftB0Left; shiftC0Left; shiftD0Left + chachaQR(A0, B0, C0, D0, T0) + shiftB0Right; shiftC0Right; shiftD0Right + DECQ itr2 + JNE openSSEPreparePolyKey + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVO A0, rStore; MOVO B0, sStore + + // Hash AAD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openSSEMainLoop: + CMPQ inl, $256 + JB openSSEMainLoopDone + + // Load state, increment counter blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + + // There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we hash 2 blocks, and for the remaining 4 only 1 block - for a total of 16 + MOVQ $4, itr1 + MOVQ inp, itr2 + +openSSEInternalLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyAdd(0(itr2)) + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + LEAQ (2*8)(itr2), itr2 + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + polyMulStage3 + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr1 + JGE openSSEInternalLoop + + polyAdd(0(itr2)) + polyMul + LEAQ (2*8)(itr2), itr2 + + CMPQ itr1, $-6 + JG openSSEInternalLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + + // Load - xor - store + MOVO D3, tmpStore + MOVOU (0*16)(inp), D3; PXOR D3, A0; MOVOU A0, (0*16)(oup) + MOVOU (1*16)(inp), D3; PXOR D3, B0; MOVOU B0, (1*16)(oup) + MOVOU (2*16)(inp), D3; PXOR D3, C0; MOVOU C0, (2*16)(oup) + MOVOU (3*16)(inp), D3; PXOR D3, D0; MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), D0; PXOR D0, A1; MOVOU A1, (4*16)(oup) + MOVOU (5*16)(inp), D0; PXOR D0, B1; MOVOU B1, (5*16)(oup) + MOVOU (6*16)(inp), D0; PXOR D0, C1; MOVOU C1, (6*16)(oup) + MOVOU (7*16)(inp), D0; PXOR D0, D1; MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), D0; PXOR D0, A2; MOVOU A2, (8*16)(oup) + MOVOU (9*16)(inp), D0; PXOR D0, B2; MOVOU B2, (9*16)(oup) + MOVOU (10*16)(inp), D0; PXOR D0, C2; MOVOU C2, (10*16)(oup) + MOVOU (11*16)(inp), D0; PXOR D0, D2; MOVOU D2, (11*16)(oup) + MOVOU (12*16)(inp), D0; PXOR D0, A3; MOVOU A3, (12*16)(oup) + MOVOU (13*16)(inp), D0; PXOR D0, B3; MOVOU B3, (13*16)(oup) + MOVOU (14*16)(inp), D0; PXOR D0, C3; MOVOU C3, (14*16)(oup) + MOVOU (15*16)(inp), D0; PXOR tmpStore, D0; MOVOU D0, (15*16)(oup) + LEAQ 256(inp), inp + LEAQ 256(oup), oup + SUBQ $256, inl + JMP openSSEMainLoop + +openSSEMainLoopDone: + // Handle the various tail sizes efficiently + TESTQ inl, inl + JE openSSEFinalize + CMPQ inl, $64 + JBE openSSETail64 + CMPQ inl, $128 + JBE openSSETail128 + CMPQ inl, $192 + JBE openSSETail192 + JMP openSSETail256 + +openSSEFinalize: + // Hash in the PT, AAD lengths + ADDQ ad_len+80(FP), acc0; ADCQ src_len+56(FP), acc1; ADCQ $1, acc2 + polyMul + + // Final reduce + MOVQ acc0, t0 + MOVQ acc1, t1 + MOVQ acc2, t2 + SUBQ $-5, acc0 + SBBQ $-1, acc1 + SBBQ $3, acc2 + CMOVQCS t0, acc0 + CMOVQCS t1, acc1 + CMOVQCS t2, acc2 + + // Add in the "s" part of the key + ADDQ 0+sStore, acc0 + ADCQ 8+sStore, acc1 + + // Finally, constant time compare to the tag at the end of the message + XORQ AX, AX + MOVQ $1, DX + XORQ (0*8)(inp), acc0 + XORQ (1*8)(inp), acc1 + ORQ acc1, acc0 + CMOVQEQ DX, AX + + // Return true iff tags are equal + MOVB AX, ret+96(FP) + RET + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 129 bytes +openSSE128: + // For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks + MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO B0, T1; MOVO C0, T2; MOVO D1, T3 + MOVQ $10, itr2 + +openSSE128InnerCipherLoop: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftB1Left; shiftB2Left + shiftC0Left; shiftC1Left; shiftC2Left + shiftD0Left; shiftD1Left; shiftD2Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftB1Right; shiftB2Right + shiftC0Right; shiftC1Right; shiftC2Right + shiftD0Right; shiftD1Right; shiftD2Right + DECQ itr2 + JNE openSSE128InnerCipherLoop + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL T1, B0; PADDL T1, B1; PADDL T1, B2 + PADDL T2, C1; PADDL T2, C2 + PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVOU A0, rStore; MOVOU B0, sStore + + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openSSE128Open: + CMPQ inl, $16 + JB openSSETail16 + SUBQ $16, inl + + // Load for hashing + polyAdd(0(inp)) + + // Load for decryption + MOVOU (inp), T0; PXOR T0, A1; MOVOU A1, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + polyMul + + // Shift the stream "left" + MOVO B1, A1 + MOVO C1, B1 + MOVO D1, C1 + MOVO A2, D1 + MOVO B2, A2 + MOVO C2, B2 + MOVO D2, C2 + JMP openSSE128Open + +openSSETail16: + TESTQ inl, inl + JE openSSEFinalize + + // We can safely load the CT from the end, because it is padded with the MAC + MOVQ inl, itr2 + SHLQ $4, itr2 + LEAQ ·andMask<>(SB), t0 + MOVOU (inp), T0 + ADDQ inl, inp + PAND -16(t0)(itr2*1), T0 + MOVO T0, 0+tmpStore + MOVQ T0, t0 + MOVQ 8+tmpStore, t1 + PXOR A1, T0 + + // We can only store one byte at a time, since plaintext can be shorter than 16 bytes +openSSETail16Store: + MOVQ T0, t3 + MOVB t3, (oup) + PSRLDQ $1, T0 + INCQ oup + DECQ inl + JNE openSSETail16Store + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + JMP openSSEFinalize + +// ---------------------------------------------------------------------------- +// Special optimization for the last 64 bytes of ciphertext +openSSETail64: + // Need to decrypt up to 64 bytes - prepare single block + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + XORQ itr2, itr2 + MOVQ inl, itr1 + CMPQ itr1, $16 + JB openSSETail64LoopB + +openSSETail64LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + SUBQ $16, itr1 + +openSSETail64LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0) + shiftB0Left; shiftC0Left; shiftD0Left + chachaQR(A0, B0, C0, D0, T0) + shiftB0Right; shiftC0Right; shiftD0Right + + CMPQ itr1, $16 + JAE openSSETail64LoopA + + CMPQ itr2, $160 + JNE openSSETail64LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL state1Store, B0; PADDL state2Store, C0; PADDL ctr0Store, D0 + +openSSETail64DecLoop: + CMPQ inl, $16 + JB openSSETail64DecLoopDone + SUBQ $16, inl + MOVOU (inp), T0 + PXOR T0, A0 + MOVOU A0, (oup) + LEAQ 16(inp), inp + LEAQ 16(oup), oup + MOVO B0, A0 + MOVO C0, B0 + MOVO D0, C0 + JMP openSSETail64DecLoop + +openSSETail64DecLoopDone: + MOVO A0, A1 + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +openSSETail128: + // Need to decrypt up to 128 bytes - prepare two blocks + MOVO ·chacha20Constants<>(SB), A1; MOVO state1Store, B1; MOVO state2Store, C1; MOVO ctr3Store, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr0Store + MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr1Store + XORQ itr2, itr2 + MOVQ inl, itr1 + ANDQ $-16, itr1 + +openSSETail128LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + +openSSETail128LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + + CMPQ itr2, itr1 + JB openSSETail128LoopA + + CMPQ itr2, $160 + JNE openSSETail128LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B0; PADDL state1Store, B1 + PADDL state2Store, C0; PADDL state2Store, C1 + PADDL ctr1Store, D0; PADDL ctr0Store, D1 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup) + + SUBQ $64, inl + LEAQ 64(inp), inp + LEAQ 64(oup), oup + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 192 bytes of ciphertext +openSSETail192: + // Need to decrypt up to 192 bytes - prepare three blocks + MOVO ·chacha20Constants<>(SB), A2; MOVO state1Store, B2; MOVO state2Store, C2; MOVO ctr3Store, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr0Store + MOVO A2, A1; MOVO B2, B1; MOVO C2, C1; MOVO D2, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + MOVO A1, A0; MOVO B1, B0; MOVO C1, C0; MOVO D1, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr2Store + + MOVQ inl, itr1 + MOVQ $160, itr2 + CMPQ itr1, $160 + CMOVQGT itr2, itr1 + ANDQ $-16, itr1 + XORQ itr2, itr2 + +openSSLTail192LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMul + +openSSLTail192LoopB: + ADDQ $16, itr2 + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + shiftB2Left; shiftC2Left; shiftD2Left + + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + shiftB2Right; shiftC2Right; shiftD2Right + + CMPQ itr2, itr1 + JB openSSLTail192LoopA + + CMPQ itr2, $160 + JNE openSSLTail192LoopB + + CMPQ inl, $176 + JB openSSLTail192Store + + polyAdd(160(inp)) + polyMul + + CMPQ inl, $192 + JB openSSLTail192Store + + polyAdd(176(inp)) + polyMul + +openSSLTail192Store: + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2 + PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2 + PADDL ctr2Store, D0; PADDL ctr1Store, D1; PADDL ctr0Store, D2 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A2; PXOR T1, B2; PXOR T2, C2; PXOR T3, D2 + MOVOU A2, (0*16)(oup); MOVOU B2, (1*16)(oup); MOVOU C2, (2*16)(oup); MOVOU D2, (3*16)(oup) + + MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + + SUBQ $128, inl + LEAQ 128(inp), inp + LEAQ 128(oup), oup + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +openSSETail256: + // Need to decrypt up to 256 bytes - prepare four blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + XORQ itr2, itr2 + +openSSETail256Loop: + // This loop inteleaves 8 ChaCha quarter rounds with 1 poly multiplication + polyAdd(0(inp)(itr2*1)) + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulStage3 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + ADDQ $2*8, itr2 + CMPQ itr2, $160 + JB openSSETail256Loop + MOVQ inl, itr1 + ANDQ $-16, itr1 + +openSSETail256HashLoop: + polyAdd(0(inp)(itr2*1)) + polyMul + ADDQ $2*8, itr2 + CMPQ itr2, itr1 + JB openSSETail256HashLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + MOVO D3, tmpStore + + // Load - xor - store + MOVOU (0*16)(inp), D3; PXOR D3, A0 + MOVOU (1*16)(inp), D3; PXOR D3, B0 + MOVOU (2*16)(inp), D3; PXOR D3, C0 + MOVOU (3*16)(inp), D3; PXOR D3, D0 + MOVOU A0, (0*16)(oup) + MOVOU B0, (1*16)(oup) + MOVOU C0, (2*16)(oup) + MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup) + LEAQ 192(inp), inp + LEAQ 192(oup), oup + SUBQ $192, inl + MOVO A3, A0 + MOVO B3, B0 + MOVO C3, C0 + MOVO tmpStore, D0 + + JMP openSSETail64DecLoop + +// ---------------------------------------------------------------------------- +// ------------------------- AVX2 Code ---------------------------------------- +chacha20Poly1305Open_AVX2: + VZEROUPPER + VMOVDQU ·chacha20Constants<>(SB), AA0 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12 + BYTE $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4 + VPADDD ·avx2InitMask<>(SB), DD0, DD0 + + // Special optimization, for very short buffers + CMPQ inl, $192 + JBE openAVX2192 + CMPQ inl, $320 + JBE openAVX2320 + + // For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream + VMOVDQA BB0, state1StoreAVX2 + VMOVDQA CC0, state2StoreAVX2 + VMOVDQA DD0, ctr3StoreAVX2 + MOVQ $10, itr2 + +openAVX2PreparePolyKey: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + DECQ itr2 + JNE openAVX2PreparePolyKey + + VPADDD ·chacha20Constants<>(SB), AA0, AA0 + VPADDD state1StoreAVX2, BB0, BB0 + VPADDD state2StoreAVX2, CC0, CC0 + VPADDD ctr3StoreAVX2, DD0, DD0 + + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for the first 64 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + + // Hash AD + first 64 bytes + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +openAVX2InitialHash64: + polyAdd(0(inp)(itr1*1)) + polyMulAVX2 + ADDQ $16, itr1 + CMPQ itr1, $64 + JNE openAVX2InitialHash64 + + // Decrypt the first 64 bytes + VPXOR (0*32)(inp), AA0, AA0 + VPXOR (1*32)(inp), BB0, BB0 + VMOVDQU AA0, (0*32)(oup) + VMOVDQU BB0, (1*32)(oup) + LEAQ (2*32)(inp), inp + LEAQ (2*32)(oup), oup + SUBQ $64, inl + +openAVX2MainLoop: + CMPQ inl, $512 + JB openAVX2MainLoopDone + + // Load state, increment counter blocks, store the incremented counters + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + XORQ itr1, itr1 + +openAVX2InternalLoop: + // Lets just say this spaghetti loop interleaves 2 quarter rounds with 3 poly multiplications + // Effectively per 512 bytes of stream we hash 480 bytes of ciphertext + polyAdd(0*8(inp)(itr1*1)) + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage1_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulStage2_AVX2 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyMulStage3_AVX2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + polyAdd(2*8(inp)(itr1*1)) + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage1_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage2_AVX2 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage3_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulReduceStage + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(4*8(inp)(itr1*1)) + LEAQ (6*8)(itr1), itr1 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage1_AVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + polyMulStage2_AVX2 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage3_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + CMPQ itr1, $480 + JNE openAVX2InternalLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + + // We only hashed 480 of the 512 bytes available - hash the remaining 32 here + polyAdd(480(inp)) + polyMulAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + // and here + polyAdd(496(inp)) + polyMulAVX2 + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + VPXOR (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0 + VMOVDQU AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup) + LEAQ (32*16)(inp), inp + LEAQ (32*16)(oup), oup + SUBQ $(32*16), inl + JMP openAVX2MainLoop + +openAVX2MainLoopDone: + // Handle the various tail sizes efficiently + TESTQ inl, inl + JE openSSEFinalize + CMPQ inl, $128 + JBE openAVX2Tail128 + CMPQ inl, $256 + JBE openAVX2Tail256 + CMPQ inl, $384 + JBE openAVX2Tail384 + JMP openAVX2Tail512 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 193 bytes +openAVX2192: + // For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks + VMOVDQA AA0, AA1 + VMOVDQA BB0, BB1 + VMOVDQA CC0, CC1 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2 + VMOVDQA BB0, BB2 + VMOVDQA CC0, CC2 + VMOVDQA DD0, DD2 + VMOVDQA DD1, TT3 + MOVQ $10, itr2 + +openAVX2192InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr2 + JNE openAVX2192InnerCipherLoop + VPADDD AA2, AA0, AA0; VPADDD AA2, AA1, AA1 + VPADDD BB2, BB0, BB0; VPADDD BB2, BB1, BB1 + VPADDD CC2, CC0, CC0; VPADDD CC2, CC1, CC1 + VPADDD DD2, DD0, DD0; VPADDD TT3, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 192 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + +openAVX2ShortOpen: + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + +openAVX2ShortOpenLoop: + CMPQ inl, $32 + JB openAVX2ShortTail32 + SUBQ $32, inl + + // Load for hashing + polyAdd(0*8(inp)) + polyMulAVX2 + polyAdd(2*8(inp)) + polyMulAVX2 + + // Load for decryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + LEAQ (1*32)(oup), oup + + // Shift stream left + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + VMOVDQA AA1, DD0 + VMOVDQA BB1, AA1 + VMOVDQA CC1, BB1 + VMOVDQA DD1, CC1 + VMOVDQA AA2, DD1 + VMOVDQA BB2, AA2 + JMP openAVX2ShortOpenLoop + +openAVX2ShortTail32: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB openAVX2ShortDone + + SUBQ $16, inl + + // Load for hashing + polyAdd(0*8(inp)) + polyMulAVX2 + + // Load for decryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +openAVX2ShortDone: + VZEROUPPER + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 321 bytes +openAVX2320: + // For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks + VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3 + MOVQ $10, itr2 + +openAVX2320InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr2 + JNE openAVX2320InnerCipherLoop + + VMOVDQA ·chacha20Constants<>(SB), TT0 + VPADDD TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2 + VPADDD TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2 + VPADDD TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2 + VMOVDQA ·avx2IncMask<>(SB), TT0 + VPADDD TT3, DD0, DD0; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD1, DD1; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD2, DD2 + + // Clamp and store poly key + VPERM2I128 $0x02, AA0, BB0, TT0 + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 320 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + VPERM2I128 $0x02, AA2, BB2, CC1 + VPERM2I128 $0x02, CC2, DD2, DD1 + VPERM2I128 $0x13, AA2, BB2, AA2 + VPERM2I128 $0x13, CC2, DD2, BB2 + JMP openAVX2ShortOpen + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +openAVX2Tail128: + // Need to decrypt up to 128 bytes - prepare two blocks + VMOVDQA ·chacha20Constants<>(SB), AA1 + VMOVDQA state1StoreAVX2, BB1 + VMOVDQA state2StoreAVX2, CC1 + VMOVDQA ctr3StoreAVX2, DD1 + VPADDD ·avx2IncMask<>(SB), DD1, DD1 + VMOVDQA DD1, DD0 + + XORQ itr2, itr2 + MOVQ inl, itr1 + ANDQ $-16, itr1 + TESTQ itr1, itr1 + JE openAVX2Tail128LoopB + +openAVX2Tail128LoopA: + // Perform ChaCha rounds, while hashing the remaining input + polyAdd(0(inp)(itr2*1)) + polyMulAVX2 + +openAVX2Tail128LoopB: + ADDQ $16, itr2 + chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD1, DD1, DD1 + CMPQ itr2, itr1 + JB openAVX2Tail128LoopA + CMPQ itr2, $160 + JNE openAVX2Tail128LoopB + + VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC1, CC1 + VPADDD DD0, DD1, DD1 + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + +openAVX2TailLoop: + CMPQ inl, $32 + JB openAVX2Tail + SUBQ $32, inl + + // Load for decryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + LEAQ (1*32)(oup), oup + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + JMP openAVX2TailLoop + +openAVX2Tail: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB openAVX2TailDone + SUBQ $16, inl + + // Load for decryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +openAVX2TailDone: + VZEROUPPER + JMP openSSETail16 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +openAVX2Tail256: + // Need to decrypt up to 256 bytes - prepare four blocks + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA DD0, TT1 + VMOVDQA DD1, TT2 + + // Compute the number of iterations that will hash data + MOVQ inl, tmpStoreAVX2 + MOVQ inl, itr1 + SUBQ $128, itr1 + SHRQ $4, itr1 + MOVQ $10, itr2 + CMPQ itr1, $10 + CMOVQGT itr2, itr1 + MOVQ inp, inl + XORQ itr2, itr2 + +openAVX2Tail256LoopA: + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + + // Perform ChaCha rounds, while hashing the remaining input +openAVX2Tail256LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + INCQ itr2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + CMPQ itr2, itr1 + JB openAVX2Tail256LoopA + + CMPQ itr2, $10 + JNE openAVX2Tail256LoopB + + MOVQ inl, itr2 + SUBQ inp, inl + MOVQ inl, itr1 + MOVQ tmpStoreAVX2, inl + + // Hash the remainder of data (if any) +openAVX2Tail256Hash: + ADDQ $16, itr1 + CMPQ itr1, inl + JGT openAVX2Tail256HashEnd + polyAdd (0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + JMP openAVX2Tail256Hash + +// Store 128 bytes safely, then go to store loop +openAVX2Tail256HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, AA2; VPERM2I128 $0x02, CC0, DD0, BB2; VPERM2I128 $0x13, AA0, BB0, CC2; VPERM2I128 $0x13, CC0, DD0, DD2 + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + + VPXOR (0*32)(inp), AA2, AA2; VPXOR (1*32)(inp), BB2, BB2; VPXOR (2*32)(inp), CC2, CC2; VPXOR (3*32)(inp), DD2, DD2 + VMOVDQU AA2, (0*32)(oup); VMOVDQU BB2, (1*32)(oup); VMOVDQU CC2, (2*32)(oup); VMOVDQU DD2, (3*32)(oup) + LEAQ (4*32)(inp), inp + LEAQ (4*32)(oup), oup + SUBQ $4*32, inl + + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 384 bytes of ciphertext +openAVX2Tail384: + // Need to decrypt up to 384 bytes - prepare six blocks + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA DD0, ctr0StoreAVX2 + VMOVDQA DD1, ctr1StoreAVX2 + VMOVDQA DD2, ctr2StoreAVX2 + + // Compute the number of iterations that will hash two blocks of data + MOVQ inl, tmpStoreAVX2 + MOVQ inl, itr1 + SUBQ $256, itr1 + SHRQ $4, itr1 + ADDQ $6, itr1 + MOVQ $10, itr2 + CMPQ itr1, $10 + CMOVQGT itr2, itr1 + MOVQ inp, inl + XORQ itr2, itr2 + + // Perform ChaCha rounds, while hashing the remaining input +openAVX2Tail384LoopB: + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + +openAVX2Tail384LoopA: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + polyAdd(0(inl)) + polyMulAVX2 + LEAQ 16(inl), inl + INCQ itr2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + + CMPQ itr2, itr1 + JB openAVX2Tail384LoopB + + CMPQ itr2, $10 + JNE openAVX2Tail384LoopA + + MOVQ inl, itr2 + SUBQ inp, inl + MOVQ inl, itr1 + MOVQ tmpStoreAVX2, inl + +openAVX2Tail384Hash: + ADDQ $16, itr1 + CMPQ itr1, inl + JGT openAVX2Tail384HashEnd + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + JMP openAVX2Tail384Hash + +// Store 256 bytes safely, then go to store loop +openAVX2Tail384HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2 + VPERM2I128 $0x02, AA0, BB0, TT0; VPERM2I128 $0x02, CC0, DD0, TT1; VPERM2I128 $0x13, AA0, BB0, TT2; VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, TT0; VPERM2I128 $0x02, CC1, DD1, TT1; VPERM2I128 $0x13, AA1, BB1, TT2; VPERM2I128 $0x13, CC1, DD1, TT3 + VPXOR (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3 + VMOVDQU TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + LEAQ (8*32)(inp), inp + LEAQ (8*32)(oup), oup + SUBQ $8*32, inl + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 512 bytes of ciphertext +openAVX2Tail512: + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + XORQ itr1, itr1 + MOVQ inp, itr2 + +openAVX2Tail512LoopB: + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ (2*8)(itr2), itr2 + +openAVX2Tail512LoopA: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyAdd(0*8(itr2)) + polyMulAVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(2*8(itr2)) + polyMulAVX2 + LEAQ (4*8)(itr2), itr2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + INCQ itr1 + CMPQ itr1, $4 + JLT openAVX2Tail512LoopB + + CMPQ itr1, $10 + JNE openAVX2Tail512LoopA + + MOVQ inl, itr1 + SUBQ $384, itr1 + ANDQ $-16, itr1 + +openAVX2Tail512HashLoop: + TESTQ itr1, itr1 + JE openAVX2Tail512HashEnd + polyAdd(0(itr2)) + polyMulAVX2 + LEAQ 16(itr2), itr2 + SUBQ $16, itr1 + JMP openAVX2Tail512HashLoop + +openAVX2Tail512HashEnd: + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + + LEAQ (12*32)(inp), inp + LEAQ (12*32)(oup), oup + SUBQ $12*32, inl + + JMP openAVX2TailLoop + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// func chacha20Poly1305Seal(dst, key, src, ad []byte) +TEXT ·chacha20Poly1305Seal(SB), 0, $288-96 + // For aligned stack access + MOVQ SP, BP + ADDQ $32, BP + ANDQ $-32, BP + MOVQ dst+0(FP), oup + MOVQ key+24(FP), keyp + MOVQ src+48(FP), inp + MOVQ src_len+56(FP), inl + MOVQ ad+72(FP), adp + + CMPB ·useAVX2(SB), $1 + JE chacha20Poly1305Seal_AVX2 + + // Special optimization, for very short buffers + CMPQ inl, $128 + JBE sealSSE128 // About 15% faster + + // In the seal case - prepare the poly key + 3 blocks of stream in the first iteration + MOVOU ·chacha20Constants<>(SB), A0 + MOVOU (1*16)(keyp), B0 + MOVOU (2*16)(keyp), C0 + MOVOU (3*16)(keyp), D0 + + // Store state on stack for future use + MOVO B0, state1Store + MOVO C0, state2Store + + // Load state, increment counter blocks + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + MOVQ $10, itr2 + +sealSSEIntroLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr2 + JNE sealSSEIntroLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + + // Clamp and store the key + PAND ·polyClampMask<>(SB), A0 + MOVO A0, rStore + MOVO B0, sStore + + // Hash AAD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (0*16)(oup); MOVOU B1, (1*16)(oup); MOVOU C1, (2*16)(oup); MOVOU D1, (3*16)(oup) + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (4*16)(oup); MOVOU B2, (5*16)(oup); MOVOU C2, (6*16)(oup); MOVOU D2, (7*16)(oup) + + MOVQ $128, itr1 + SUBQ $128, inl + LEAQ 128(inp), inp + + MOVO A3, A1; MOVO B3, B1; MOVO C3, C1; MOVO D3, D1 + + CMPQ inl, $64 + JBE sealSSE128SealHash + + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3 + MOVOU A3, (8*16)(oup); MOVOU B3, (9*16)(oup); MOVOU C3, (10*16)(oup); MOVOU D3, (11*16)(oup) + + ADDQ $64, itr1 + SUBQ $64, inl + LEAQ 64(inp), inp + + MOVQ $2, itr1 + MOVQ $8, itr2 + + CMPQ inl, $64 + JBE sealSSETail64 + CMPQ inl, $128 + JBE sealSSETail128 + CMPQ inl, $192 + JBE sealSSETail192 + +sealSSEMainLoop: + // Load state, increment counter blocks + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO A2, A3; MOVO B2, B3; MOVO C2, C3; MOVO D2, D3; PADDL ·sseIncMask<>(SB), D3 + + // Store counters + MOVO D0, ctr0Store; MOVO D1, ctr1Store; MOVO D2, ctr2Store; MOVO D3, ctr3Store + +sealSSEInnerLoop: + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyAdd(0(oup)) + shiftB0Left; shiftB1Left; shiftB2Left; shiftB3Left + shiftC0Left; shiftC1Left; shiftC2Left; shiftC3Left + shiftD0Left; shiftD1Left; shiftD2Left; shiftD3Left + polyMulStage1 + polyMulStage2 + LEAQ (2*8)(oup), oup + MOVO C3, tmpStore + chachaQR(A0, B0, C0, D0, C3); chachaQR(A1, B1, C1, D1, C3); chachaQR(A2, B2, C2, D2, C3) + MOVO tmpStore, C3 + MOVO C1, tmpStore + polyMulStage3 + chachaQR(A3, B3, C3, D3, C1) + MOVO tmpStore, C1 + polyMulReduceStage + shiftB0Right; shiftB1Right; shiftB2Right; shiftB3Right + shiftC0Right; shiftC1Right; shiftC2Right; shiftC3Right + shiftD0Right; shiftD1Right; shiftD2Right; shiftD3Right + DECQ itr2 + JGE sealSSEInnerLoop + polyAdd(0(oup)) + polyMul + LEAQ (2*8)(oup), oup + DECQ itr1 + JG sealSSEInnerLoop + + // Add in the state + PADDD ·chacha20Constants<>(SB), A0; PADDD ·chacha20Constants<>(SB), A1; PADDD ·chacha20Constants<>(SB), A2; PADDD ·chacha20Constants<>(SB), A3 + PADDD state1Store, B0; PADDD state1Store, B1; PADDD state1Store, B2; PADDD state1Store, B3 + PADDD state2Store, C0; PADDD state2Store, C1; PADDD state2Store, C2; PADDD state2Store, C3 + PADDD ctr0Store, D0; PADDD ctr1Store, D1; PADDD ctr2Store, D2; PADDD ctr3Store, D3 + MOVO D3, tmpStore + + // Load - xor - store + MOVOU (0*16)(inp), D3; PXOR D3, A0 + MOVOU (1*16)(inp), D3; PXOR D3, B0 + MOVOU (2*16)(inp), D3; PXOR D3, C0 + MOVOU (3*16)(inp), D3; PXOR D3, D0 + MOVOU A0, (0*16)(oup) + MOVOU B0, (1*16)(oup) + MOVOU C0, (2*16)(oup) + MOVOU D0, (3*16)(oup) + MOVO tmpStore, D3 + + MOVOU (4*16)(inp), A0; MOVOU (5*16)(inp), B0; MOVOU (6*16)(inp), C0; MOVOU (7*16)(inp), D0 + PXOR A0, A1; PXOR B0, B1; PXOR C0, C1; PXOR D0, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + MOVOU (8*16)(inp), A0; MOVOU (9*16)(inp), B0; MOVOU (10*16)(inp), C0; MOVOU (11*16)(inp), D0 + PXOR A0, A2; PXOR B0, B2; PXOR C0, C2; PXOR D0, D2 + MOVOU A2, (8*16)(oup); MOVOU B2, (9*16)(oup); MOVOU C2, (10*16)(oup); MOVOU D2, (11*16)(oup) + ADDQ $192, inp + MOVQ $192, itr1 + SUBQ $192, inl + MOVO A3, A1 + MOVO B3, B1 + MOVO C3, C1 + MOVO D3, D1 + CMPQ inl, $64 + JBE sealSSE128SealHash + MOVOU (0*16)(inp), A0; MOVOU (1*16)(inp), B0; MOVOU (2*16)(inp), C0; MOVOU (3*16)(inp), D0 + PXOR A0, A3; PXOR B0, B3; PXOR C0, C3; PXOR D0, D3 + MOVOU A3, (12*16)(oup); MOVOU B3, (13*16)(oup); MOVOU C3, (14*16)(oup); MOVOU D3, (15*16)(oup) + LEAQ 64(inp), inp + SUBQ $64, inl + MOVQ $6, itr1 + MOVQ $4, itr2 + CMPQ inl, $192 + JG sealSSEMainLoop + + MOVQ inl, itr1 + TESTQ inl, inl + JE sealSSE128SealHash + MOVQ $6, itr1 + CMPQ inl, $64 + JBE sealSSETail64 + CMPQ inl, $128 + JBE sealSSETail128 + JMP sealSSETail192 + +// ---------------------------------------------------------------------------- +// Special optimization for the last 64 bytes of plaintext +sealSSETail64: + // Need to encrypt up to 64 bytes - prepare single block, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A1 + MOVO state1Store, B1 + MOVO state2Store, C1 + MOVO ctr3Store, D1 + PADDL ·sseIncMask<>(SB), D1 + MOVO D1, ctr0Store + +sealSSETail64LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail64LoopB: + chachaQR(A1, B1, C1, D1, T1) + shiftB1Left; shiftC1Left; shiftD1Left + chachaQR(A1, B1, C1, D1, T1) + shiftB1Right; shiftC1Right; shiftD1Right + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + + DECQ itr1 + JG sealSSETail64LoopA + + DECQ itr2 + JGE sealSSETail64LoopB + PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B1 + PADDL state2Store, C1 + PADDL ctr0Store, D1 + + JMP sealSSE128Seal + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of plaintext +sealSSETail128: + // Need to encrypt up to 128 bytes - prepare two blocks, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + +sealSSETail128LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail128LoopB: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + + DECQ itr1 + JG sealSSETail128LoopA + + DECQ itr2 + JGE sealSSETail128LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1 + PADDL state1Store, B0; PADDL state1Store, B1 + PADDL state2Store, C0; PADDL state2Store, C1 + PADDL ctr0Store, D0; PADDL ctr1Store, D1 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0 + MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup) + + MOVQ $64, itr1 + LEAQ 64(inp), inp + SUBQ $64, inl + + JMP sealSSE128SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 192 bytes of plaintext +sealSSETail192: + // Need to encrypt up to 192 bytes - prepare three blocks, hash 192 or 256 bytes + MOVO ·chacha20Constants<>(SB), A0; MOVO state1Store, B0; MOVO state2Store, C0; MOVO ctr3Store, D0; PADDL ·sseIncMask<>(SB), D0; MOVO D0, ctr0Store + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1; MOVO D1, ctr1Store + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2; MOVO D2, ctr2Store + +sealSSETail192LoopA: + // Perform ChaCha rounds, while hashing the previously encrypted ciphertext + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealSSETail192LoopB: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftC0Left; shiftD0Left + shiftB1Left; shiftC1Left; shiftD1Left + shiftB2Left; shiftC2Left; shiftD2Left + + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftC0Right; shiftD0Right + shiftB1Right; shiftC1Right; shiftD1Right + shiftB2Right; shiftC2Right; shiftD2Right + + DECQ itr1 + JG sealSSETail192LoopA + + DECQ itr2 + JGE sealSSETail192LoopB + + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL state1Store, B0; PADDL state1Store, B1; PADDL state1Store, B2 + PADDL state2Store, C0; PADDL state2Store, C1; PADDL state2Store, C2 + PADDL ctr0Store, D0; PADDL ctr1Store, D1; PADDL ctr2Store, D2 + + MOVOU (0*16)(inp), T0; MOVOU (1*16)(inp), T1; MOVOU (2*16)(inp), T2; MOVOU (3*16)(inp), T3 + PXOR T0, A0; PXOR T1, B0; PXOR T2, C0; PXOR T3, D0 + MOVOU A0, (0*16)(oup); MOVOU B0, (1*16)(oup); MOVOU C0, (2*16)(oup); MOVOU D0, (3*16)(oup) + MOVOU (4*16)(inp), T0; MOVOU (5*16)(inp), T1; MOVOU (6*16)(inp), T2; MOVOU (7*16)(inp), T3 + PXOR T0, A1; PXOR T1, B1; PXOR T2, C1; PXOR T3, D1 + MOVOU A1, (4*16)(oup); MOVOU B1, (5*16)(oup); MOVOU C1, (6*16)(oup); MOVOU D1, (7*16)(oup) + + MOVO A2, A1 + MOVO B2, B1 + MOVO C2, C1 + MOVO D2, D1 + MOVQ $128, itr1 + LEAQ 128(inp), inp + SUBQ $128, inl + + JMP sealSSE128SealHash + +// ---------------------------------------------------------------------------- +// Special seal optimization for buffers smaller than 129 bytes +sealSSE128: + // For up to 128 bytes of ciphertext and 64 bytes for the poly key, we require to process three blocks + MOVOU ·chacha20Constants<>(SB), A0; MOVOU (1*16)(keyp), B0; MOVOU (2*16)(keyp), C0; MOVOU (3*16)(keyp), D0 + MOVO A0, A1; MOVO B0, B1; MOVO C0, C1; MOVO D0, D1; PADDL ·sseIncMask<>(SB), D1 + MOVO A1, A2; MOVO B1, B2; MOVO C1, C2; MOVO D1, D2; PADDL ·sseIncMask<>(SB), D2 + MOVO B0, T1; MOVO C0, T2; MOVO D1, T3 + MOVQ $10, itr2 + +sealSSE128InnerCipherLoop: + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Left; shiftB1Left; shiftB2Left + shiftC0Left; shiftC1Left; shiftC2Left + shiftD0Left; shiftD1Left; shiftD2Left + chachaQR(A0, B0, C0, D0, T0); chachaQR(A1, B1, C1, D1, T0); chachaQR(A2, B2, C2, D2, T0) + shiftB0Right; shiftB1Right; shiftB2Right + shiftC0Right; shiftC1Right; shiftC2Right + shiftD0Right; shiftD1Right; shiftD2Right + DECQ itr2 + JNE sealSSE128InnerCipherLoop + + // A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + PADDL ·chacha20Constants<>(SB), A0; PADDL ·chacha20Constants<>(SB), A1; PADDL ·chacha20Constants<>(SB), A2 + PADDL T1, B0; PADDL T1, B1; PADDL T1, B2 + PADDL T2, C1; PADDL T2, C2 + PADDL T3, D1; PADDL ·sseIncMask<>(SB), T3; PADDL T3, D2 + PAND ·polyClampMask<>(SB), A0 + MOVOU A0, rStore + MOVOU B0, sStore + + // Hash + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +sealSSE128SealHash: + // itr1 holds the number of bytes encrypted but not yet hashed + CMPQ itr1, $16 + JB sealSSE128Seal + polyAdd(0(oup)) + polyMul + + SUBQ $16, itr1 + ADDQ $16, oup + + JMP sealSSE128SealHash + +sealSSE128Seal: + CMPQ inl, $16 + JB sealSSETail + SUBQ $16, inl + + // Load for decryption + MOVOU (inp), T0 + PXOR T0, A1 + MOVOU A1, (oup) + LEAQ (1*16)(inp), inp + LEAQ (1*16)(oup), oup + + // Extract for hashing + MOVQ A1, t0 + PSRLDQ $8, A1 + MOVQ A1, t1 + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + // Shift the stream "left" + MOVO B1, A1 + MOVO C1, B1 + MOVO D1, C1 + MOVO A2, D1 + MOVO B2, A2 + MOVO C2, B2 + MOVO D2, C2 + JMP sealSSE128Seal + +sealSSETail: + TESTQ inl, inl + JE sealSSEFinalize + + // We can only load the PT one byte at a time to avoid read after end of buffer + MOVQ inl, itr2 + SHLQ $4, itr2 + LEAQ ·andMask<>(SB), t0 + MOVQ inl, itr1 + LEAQ -1(inp)(inl*1), inp + XORQ t2, t2 + XORQ t3, t3 + XORQ AX, AX + +sealSSETailLoadLoop: + SHLQ $8, t2, t3 + SHLQ $8, t2 + MOVB (inp), AX + XORQ AX, t2 + LEAQ -1(inp), inp + DECQ itr1 + JNE sealSSETailLoadLoop + MOVQ t2, 0+tmpStore + MOVQ t3, 8+tmpStore + PXOR 0+tmpStore, A1 + MOVOU A1, (oup) + MOVOU -16(t0)(itr2*1), T0 + PAND T0, A1 + MOVQ A1, t0 + PSRLDQ $8, A1 + MOVQ A1, t1 + ADDQ t0, acc0; ADCQ t1, acc1; ADCQ $1, acc2 + polyMul + + ADDQ inl, oup + +sealSSEFinalize: + // Hash in the buffer lengths + ADDQ ad_len+80(FP), acc0 + ADCQ src_len+56(FP), acc1 + ADCQ $1, acc2 + polyMul + + // Final reduce + MOVQ acc0, t0 + MOVQ acc1, t1 + MOVQ acc2, t2 + SUBQ $-5, acc0 + SBBQ $-1, acc1 + SBBQ $3, acc2 + CMOVQCS t0, acc0 + CMOVQCS t1, acc1 + CMOVQCS t2, acc2 + + // Add in the "s" part of the key + ADDQ 0+sStore, acc0 + ADCQ 8+sStore, acc1 + + // Finally store the tag at the end of the message + MOVQ acc0, (0*8)(oup) + MOVQ acc1, (1*8)(oup) + RET + +// ---------------------------------------------------------------------------- +// ------------------------- AVX2 Code ---------------------------------------- +chacha20Poly1305Seal_AVX2: + VZEROUPPER + VMOVDQU ·chacha20Constants<>(SB), AA0 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x70; BYTE $0x10 // broadcasti128 16(r8), ymm14 + BYTE $0xc4; BYTE $0x42; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x20 // broadcasti128 32(r8), ymm12 + BYTE $0xc4; BYTE $0xc2; BYTE $0x7d; BYTE $0x5a; BYTE $0x60; BYTE $0x30 // broadcasti128 48(r8), ymm4 + VPADDD ·avx2InitMask<>(SB), DD0, DD0 + + // Special optimizations, for very short buffers + CMPQ inl, $192 + JBE seal192AVX2 // 33% faster + CMPQ inl, $320 + JBE seal320AVX2 // 17% faster + + // For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream + VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3; VMOVDQA BB0, state1StoreAVX2 + VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3; VMOVDQA CC0, state2StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD0, DD1; VMOVDQA DD0, ctr0StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD1, DD2; VMOVDQA DD1, ctr1StoreAVX2 + VPADDD ·avx2IncMask<>(SB), DD2, DD3; VMOVDQA DD2, ctr2StoreAVX2 + VMOVDQA DD3, ctr3StoreAVX2 + MOVQ $10, itr2 + +sealAVX2IntroLoop: + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1 + VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2 + VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1 + VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2 + VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3 + DECQ itr2 + JNE sealAVX2IntroLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + + VPERM2I128 $0x13, CC0, DD0, CC0 // Stream bytes 96 - 127 + VPERM2I128 $0x02, AA0, BB0, DD0 // The Poly1305 key + VPERM2I128 $0x13, AA0, BB0, AA0 // Stream bytes 64 - 95 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), DD0, DD0 + VMOVDQA DD0, rsStoreAVX2 + + // Hash AD + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + + // Can store at least 320 bytes + VPXOR (0*32)(inp), AA0, AA0 + VPXOR (1*32)(inp), CC0, CC0 + VMOVDQU AA0, (0*32)(oup) + VMOVDQU CC0, (1*32)(oup) + + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (2*32)(inp), AA0, AA0; VPXOR (3*32)(inp), BB0, BB0; VPXOR (4*32)(inp), CC0, CC0; VPXOR (5*32)(inp), DD0, DD0 + VMOVDQU AA0, (2*32)(oup); VMOVDQU BB0, (3*32)(oup); VMOVDQU CC0, (4*32)(oup); VMOVDQU DD0, (5*32)(oup) + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (6*32)(inp), AA0, AA0; VPXOR (7*32)(inp), BB0, BB0; VPXOR (8*32)(inp), CC0, CC0; VPXOR (9*32)(inp), DD0, DD0 + VMOVDQU AA0, (6*32)(oup); VMOVDQU BB0, (7*32)(oup); VMOVDQU CC0, (8*32)(oup); VMOVDQU DD0, (9*32)(oup) + + MOVQ $320, itr1 + SUBQ $320, inl + LEAQ 320(inp), inp + + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, CC3, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, CC3, DD3, DD0 + CMPQ inl, $128 + JBE sealAVX2SealHash + + VPXOR (0*32)(inp), AA0, AA0; VPXOR (1*32)(inp), BB0, BB0; VPXOR (2*32)(inp), CC0, CC0; VPXOR (3*32)(inp), DD0, DD0 + VMOVDQU AA0, (10*32)(oup); VMOVDQU BB0, (11*32)(oup); VMOVDQU CC0, (12*32)(oup); VMOVDQU DD0, (13*32)(oup) + SUBQ $128, inl + LEAQ 128(inp), inp + + MOVQ $8, itr1 + MOVQ $2, itr2 + + CMPQ inl, $128 + JBE sealAVX2Tail128 + CMPQ inl, $256 + JBE sealAVX2Tail256 + CMPQ inl, $384 + JBE sealAVX2Tail384 + CMPQ inl, $512 + JBE sealAVX2Tail512 + + // We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $12, DD0, DD0, DD0 + VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $12, DD1, DD1, DD1 + VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $12, DD2, DD2, DD2 + VPALIGNR $4, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $12, DD3, DD3, DD3 + + VMOVDQA CC3, tmpStoreAVX2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, CC3); chachaQR_AVX2(AA1, BB1, CC1, DD1, CC3); chachaQR_AVX2(AA2, BB2, CC2, DD2, CC3) + VMOVDQA tmpStoreAVX2, CC3 + VMOVDQA CC1, tmpStoreAVX2 + chachaQR_AVX2(AA3, BB3, CC3, DD3, CC1) + VMOVDQA tmpStoreAVX2, CC1 + + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $4, DD0, DD0, DD0 + VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $4, DD1, DD1, DD1 + VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $4, DD2, DD2, DD2 + VPALIGNR $12, BB3, BB3, BB3; VPALIGNR $8, CC3, CC3, CC3; VPALIGNR $4, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + + SUBQ $16, oup // Adjust the pointer + MOVQ $9, itr1 + JMP sealAVX2InternalLoopStart + +sealAVX2MainLoop: + // Load state, increment counter blocks, store the incremented counters + VMOVDQU ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + MOVQ $10, itr1 + +sealAVX2InternalLoop: + polyAdd(0*8(oup)) + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage1_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulStage2_AVX2 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyMulStage3_AVX2 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + +sealAVX2InternalLoopStart: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + polyAdd(2*8(oup)) + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage1_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage2_AVX2 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + polyMulStage3_AVX2 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + polyMulReduceStage + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(4*8(oup)) + LEAQ (6*8)(oup), oup + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulStage1_AVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + polyMulStage2_AVX2 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + polyMulStage3_AVX2 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyMulReduceStage + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + DECQ itr1 + JNE sealAVX2InternalLoop + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + + // We only hashed 480 of the 512 bytes available - hash the remaining 32 here + polyAdd(0*8(oup)) + polyMulAVX2 + LEAQ (4*8)(oup), oup + VPERM2I128 $0x02, AA0, BB0, CC3; VPERM2I128 $0x13, AA0, BB0, BB0; VPERM2I128 $0x02, CC0, DD0, AA0; VPERM2I128 $0x13, CC0, DD0, CC0 + VPXOR (0*32)(inp), CC3, CC3; VPXOR (1*32)(inp), AA0, AA0; VPXOR (2*32)(inp), BB0, BB0; VPXOR (3*32)(inp), CC0, CC0 + VMOVDQU CC3, (0*32)(oup); VMOVDQU AA0, (1*32)(oup); VMOVDQU BB0, (2*32)(oup); VMOVDQU CC0, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, AA0; VPERM2I128 $0x02, CC1, DD1, BB0; VPERM2I128 $0x13, AA1, BB1, CC0; VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + // and here + polyAdd(-2*8(oup)) + polyMulAVX2 + VPERM2I128 $0x02, AA2, BB2, AA0; VPERM2I128 $0x02, CC2, DD2, BB0; VPERM2I128 $0x13, AA2, BB2, CC0; VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + VPERM2I128 $0x02, AA3, BB3, AA0; VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0; VPERM2I128 $0x13, AA3, BB3, CC0; VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + VPXOR (12*32)(inp), AA0, AA0; VPXOR (13*32)(inp), BB0, BB0; VPXOR (14*32)(inp), CC0, CC0; VPXOR (15*32)(inp), DD0, DD0 + VMOVDQU AA0, (12*32)(oup); VMOVDQU BB0, (13*32)(oup); VMOVDQU CC0, (14*32)(oup); VMOVDQU DD0, (15*32)(oup) + LEAQ (32*16)(inp), inp + SUBQ $(32*16), inl + CMPQ inl, $512 + JG sealAVX2MainLoop + + // Tail can only hash 480 bytes + polyAdd(0*8(oup)) + polyMulAVX2 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ 32(oup), oup + + MOVQ $10, itr1 + MOVQ $0, itr2 + CMPQ inl, $128 + JBE sealAVX2Tail128 + CMPQ inl, $256 + JBE sealAVX2Tail256 + CMPQ inl, $384 + JBE sealAVX2Tail384 + JMP sealAVX2Tail512 + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 193 bytes +seal192AVX2: + // For up to 192 bytes of ciphertext and 64 bytes for the poly key, we process four blocks + VMOVDQA AA0, AA1 + VMOVDQA BB0, BB1 + VMOVDQA CC0, CC1 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2 + VMOVDQA BB0, BB2 + VMOVDQA CC0, CC2 + VMOVDQA DD0, DD2 + VMOVDQA DD1, TT3 + MOVQ $10, itr2 + +sealAVX2192InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr2 + JNE sealAVX2192InnerCipherLoop + VPADDD AA2, AA0, AA0; VPADDD AA2, AA1, AA1 + VPADDD BB2, BB0, BB0; VPADDD BB2, BB1, BB1 + VPADDD CC2, CC0, CC0; VPADDD CC2, CC1, CC1 + VPADDD DD2, DD0, DD0; VPADDD TT3, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + + // Clamp and store poly key + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 192 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + +sealAVX2ShortSeal: + // Hash aad + MOVQ ad_len+80(FP), itr2 + CALL polyHashADInternal<>(SB) + XORQ itr1, itr1 + +sealAVX2SealHash: + // itr1 holds the number of bytes encrypted but not yet hashed + CMPQ itr1, $16 + JB sealAVX2ShortSealLoop + polyAdd(0(oup)) + polyMul + SUBQ $16, itr1 + ADDQ $16, oup + JMP sealAVX2SealHash + +sealAVX2ShortSealLoop: + CMPQ inl, $32 + JB sealAVX2ShortTail32 + SUBQ $32, inl + + // Load for encryption + VPXOR (inp), AA0, AA0 + VMOVDQU AA0, (oup) + LEAQ (1*32)(inp), inp + + // Now can hash + polyAdd(0*8(oup)) + polyMulAVX2 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ (1*32)(oup), oup + + // Shift stream left + VMOVDQA BB0, AA0 + VMOVDQA CC0, BB0 + VMOVDQA DD0, CC0 + VMOVDQA AA1, DD0 + VMOVDQA BB1, AA1 + VMOVDQA CC1, BB1 + VMOVDQA DD1, CC1 + VMOVDQA AA2, DD1 + VMOVDQA BB2, AA2 + JMP sealAVX2ShortSealLoop + +sealAVX2ShortTail32: + CMPQ inl, $16 + VMOVDQA A0, A1 + JB sealAVX2ShortDone + + SUBQ $16, inl + + // Load for encryption + VPXOR (inp), A0, T0 + VMOVDQU T0, (oup) + LEAQ (1*16)(inp), inp + + // Hash + polyAdd(0*8(oup)) + polyMulAVX2 + LEAQ (1*16)(oup), oup + VPERM2I128 $0x11, AA0, AA0, AA0 + VMOVDQA A0, A1 + +sealAVX2ShortDone: + VZEROUPPER + JMP sealSSETail + +// ---------------------------------------------------------------------------- +// Special optimization for buffers smaller than 321 bytes +seal320AVX2: + // For up to 320 bytes of ciphertext and 64 bytes for the poly key, we process six blocks + VMOVDQA AA0, AA1; VMOVDQA BB0, BB1; VMOVDQA CC0, CC1; VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA AA0, AA2; VMOVDQA BB0, BB2; VMOVDQA CC0, CC2; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA BB0, TT1; VMOVDQA CC0, TT2; VMOVDQA DD0, TT3 + MOVQ $10, itr2 + +sealAVX2320InnerCipherLoop: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr2 + JNE sealAVX2320InnerCipherLoop + + VMOVDQA ·chacha20Constants<>(SB), TT0 + VPADDD TT0, AA0, AA0; VPADDD TT0, AA1, AA1; VPADDD TT0, AA2, AA2 + VPADDD TT1, BB0, BB0; VPADDD TT1, BB1, BB1; VPADDD TT1, BB2, BB2 + VPADDD TT2, CC0, CC0; VPADDD TT2, CC1, CC1; VPADDD TT2, CC2, CC2 + VMOVDQA ·avx2IncMask<>(SB), TT0 + VPADDD TT3, DD0, DD0; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD1, DD1; VPADDD TT0, TT3, TT3 + VPADDD TT3, DD2, DD2 + + // Clamp and store poly key + VPERM2I128 $0x02, AA0, BB0, TT0 + VPAND ·polyClampMask<>(SB), TT0, TT0 + VMOVDQA TT0, rsStoreAVX2 + + // Stream for up to 320 bytes + VPERM2I128 $0x13, AA0, BB0, AA0 + VPERM2I128 $0x13, CC0, DD0, BB0 + VPERM2I128 $0x02, AA1, BB1, CC0 + VPERM2I128 $0x02, CC1, DD1, DD0 + VPERM2I128 $0x13, AA1, BB1, AA1 + VPERM2I128 $0x13, CC1, DD1, BB1 + VPERM2I128 $0x02, AA2, BB2, CC1 + VPERM2I128 $0x02, CC2, DD2, DD1 + VPERM2I128 $0x13, AA2, BB2, AA2 + VPERM2I128 $0x13, CC2, DD2, BB2 + JMP sealAVX2ShortSeal + +// ---------------------------------------------------------------------------- +// Special optimization for the last 128 bytes of ciphertext +sealAVX2Tail128: + // Need to decrypt up to 128 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0 + VMOVDQA state1StoreAVX2, BB0 + VMOVDQA state2StoreAVX2, CC0 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VMOVDQA DD0, DD1 + +sealAVX2Tail128LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail128LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0 + VPALIGNR $8, CC0, CC0, CC0 + VPALIGNR $12, DD0, DD0, DD0 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0 + VPALIGNR $8, CC0, CC0, CC0 + VPALIGNR $4, DD0, DD0, DD0 + DECQ itr1 + JG sealAVX2Tail128LoopA + DECQ itr2 + JGE sealAVX2Tail128LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA1 + VPADDD state1StoreAVX2, BB0, BB1 + VPADDD state2StoreAVX2, CC0, CC1 + VPADDD DD1, DD0, DD1 + + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + JMP sealAVX2ShortSealLoop + +// ---------------------------------------------------------------------------- +// Special optimization for the last 256 bytes of ciphertext +sealAVX2Tail256: + // Need to decrypt up to 256 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA ·chacha20Constants<>(SB), AA1 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA state1StoreAVX2, BB1 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA state2StoreAVX2, CC1 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD1 + VMOVDQA DD0, TT1 + VMOVDQA DD1, TT2 + +sealAVX2Tail256LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail256LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1 + DECQ itr1 + JG sealAVX2Tail256LoopA + DECQ itr2 + JGE sealAVX2Tail256LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1 + VPERM2I128 $0x02, AA0, BB0, TT0 + VPERM2I128 $0x02, CC0, DD0, TT1 + VPERM2I128 $0x13, AA0, BB0, TT2 + VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + MOVQ $128, itr1 + LEAQ 128(inp), inp + SUBQ $128, inl + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + + JMP sealAVX2SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 384 bytes of ciphertext +sealAVX2Tail384: + // Need to decrypt up to 384 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2 + VMOVDQA DD0, TT1; VMOVDQA DD1, TT2; VMOVDQA DD2, TT3 + +sealAVX2Tail384LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail384LoopB: + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + polyAdd(0(oup)) + polyMul + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2 + chachaQR_AVX2(AA0, BB0, CC0, DD0, TT0); chachaQR_AVX2(AA1, BB1, CC1, DD1, TT0); chachaQR_AVX2(AA2, BB2, CC2, DD2, TT0) + polyAdd(16(oup)) + polyMul + LEAQ 32(oup), oup + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2 + DECQ itr1 + JG sealAVX2Tail384LoopA + DECQ itr2 + JGE sealAVX2Tail384LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2 + VPADDD TT1, DD0, DD0; VPADDD TT2, DD1, DD1; VPADDD TT3, DD2, DD2 + VPERM2I128 $0x02, AA0, BB0, TT0 + VPERM2I128 $0x02, CC0, DD0, TT1 + VPERM2I128 $0x13, AA0, BB0, TT2 + VPERM2I128 $0x13, CC0, DD0, TT3 + VPXOR (0*32)(inp), TT0, TT0; VPXOR (1*32)(inp), TT1, TT1; VPXOR (2*32)(inp), TT2, TT2; VPXOR (3*32)(inp), TT3, TT3 + VMOVDQU TT0, (0*32)(oup); VMOVDQU TT1, (1*32)(oup); VMOVDQU TT2, (2*32)(oup); VMOVDQU TT3, (3*32)(oup) + VPERM2I128 $0x02, AA1, BB1, TT0 + VPERM2I128 $0x02, CC1, DD1, TT1 + VPERM2I128 $0x13, AA1, BB1, TT2 + VPERM2I128 $0x13, CC1, DD1, TT3 + VPXOR (4*32)(inp), TT0, TT0; VPXOR (5*32)(inp), TT1, TT1; VPXOR (6*32)(inp), TT2, TT2; VPXOR (7*32)(inp), TT3, TT3 + VMOVDQU TT0, (4*32)(oup); VMOVDQU TT1, (5*32)(oup); VMOVDQU TT2, (6*32)(oup); VMOVDQU TT3, (7*32)(oup) + MOVQ $256, itr1 + LEAQ 256(inp), inp + SUBQ $256, inl + VPERM2I128 $0x02, AA2, BB2, AA0 + VPERM2I128 $0x02, CC2, DD2, BB0 + VPERM2I128 $0x13, AA2, BB2, CC0 + VPERM2I128 $0x13, CC2, DD2, DD0 + + JMP sealAVX2SealHash + +// ---------------------------------------------------------------------------- +// Special optimization for the last 512 bytes of ciphertext +sealAVX2Tail512: + // Need to decrypt up to 512 bytes - prepare two blocks + // If we got here after the main loop - there are 512 encrypted bytes waiting to be hashed + // If we got here before the main loop - there are 448 encrpyred bytes waiting to be hashed + VMOVDQA ·chacha20Constants<>(SB), AA0; VMOVDQA AA0, AA1; VMOVDQA AA0, AA2; VMOVDQA AA0, AA3 + VMOVDQA state1StoreAVX2, BB0; VMOVDQA BB0, BB1; VMOVDQA BB0, BB2; VMOVDQA BB0, BB3 + VMOVDQA state2StoreAVX2, CC0; VMOVDQA CC0, CC1; VMOVDQA CC0, CC2; VMOVDQA CC0, CC3 + VMOVDQA ctr3StoreAVX2, DD0 + VPADDD ·avx2IncMask<>(SB), DD0, DD0; VPADDD ·avx2IncMask<>(SB), DD0, DD1; VPADDD ·avx2IncMask<>(SB), DD1, DD2; VPADDD ·avx2IncMask<>(SB), DD2, DD3 + VMOVDQA DD0, ctr0StoreAVX2; VMOVDQA DD1, ctr1StoreAVX2; VMOVDQA DD2, ctr2StoreAVX2; VMOVDQA DD3, ctr3StoreAVX2 + +sealAVX2Tail512LoopA: + polyAdd(0(oup)) + polyMul + LEAQ 16(oup), oup + +sealAVX2Tail512LoopB: + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + polyAdd(0*8(oup)) + polyMulAVX2 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $4, BB0, BB0, BB0; VPALIGNR $4, BB1, BB1, BB1; VPALIGNR $4, BB2, BB2, BB2; VPALIGNR $4, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $12, DD0, DD0, DD0; VPALIGNR $12, DD1, DD1, DD1; VPALIGNR $12, DD2, DD2, DD2; VPALIGNR $12, DD3, DD3, DD3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol16<>(SB), DD0, DD0; VPSHUFB ·rol16<>(SB), DD1, DD1; VPSHUFB ·rol16<>(SB), DD2, DD2; VPSHUFB ·rol16<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + polyAdd(2*8(oup)) + polyMulAVX2 + LEAQ (4*8)(oup), oup + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $12, BB0, CC3; VPSRLD $20, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $12, BB1, CC3; VPSRLD $20, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $12, BB2, CC3; VPSRLD $20, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $12, BB3, CC3; VPSRLD $20, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPADDD BB0, AA0, AA0; VPADDD BB1, AA1, AA1; VPADDD BB2, AA2, AA2; VPADDD BB3, AA3, AA3 + VPXOR AA0, DD0, DD0; VPXOR AA1, DD1, DD1; VPXOR AA2, DD2, DD2; VPXOR AA3, DD3, DD3 + VPSHUFB ·rol8<>(SB), DD0, DD0; VPSHUFB ·rol8<>(SB), DD1, DD1; VPSHUFB ·rol8<>(SB), DD2, DD2; VPSHUFB ·rol8<>(SB), DD3, DD3 + VPADDD DD0, CC0, CC0; VPADDD DD1, CC1, CC1; VPADDD DD2, CC2, CC2; VPADDD DD3, CC3, CC3 + VPXOR CC0, BB0, BB0; VPXOR CC1, BB1, BB1; VPXOR CC2, BB2, BB2; VPXOR CC3, BB3, BB3 + VMOVDQA CC3, tmpStoreAVX2 + VPSLLD $7, BB0, CC3; VPSRLD $25, BB0, BB0; VPXOR CC3, BB0, BB0 + VPSLLD $7, BB1, CC3; VPSRLD $25, BB1, BB1; VPXOR CC3, BB1, BB1 + VPSLLD $7, BB2, CC3; VPSRLD $25, BB2, BB2; VPXOR CC3, BB2, BB2 + VPSLLD $7, BB3, CC3; VPSRLD $25, BB3, BB3; VPXOR CC3, BB3, BB3 + VMOVDQA tmpStoreAVX2, CC3 + VPALIGNR $12, BB0, BB0, BB0; VPALIGNR $12, BB1, BB1, BB1; VPALIGNR $12, BB2, BB2, BB2; VPALIGNR $12, BB3, BB3, BB3 + VPALIGNR $8, CC0, CC0, CC0; VPALIGNR $8, CC1, CC1, CC1; VPALIGNR $8, CC2, CC2, CC2; VPALIGNR $8, CC3, CC3, CC3 + VPALIGNR $4, DD0, DD0, DD0; VPALIGNR $4, DD1, DD1, DD1; VPALIGNR $4, DD2, DD2, DD2; VPALIGNR $4, DD3, DD3, DD3 + + DECQ itr1 + JG sealAVX2Tail512LoopA + DECQ itr2 + JGE sealAVX2Tail512LoopB + + VPADDD ·chacha20Constants<>(SB), AA0, AA0; VPADDD ·chacha20Constants<>(SB), AA1, AA1; VPADDD ·chacha20Constants<>(SB), AA2, AA2; VPADDD ·chacha20Constants<>(SB), AA3, AA3 + VPADDD state1StoreAVX2, BB0, BB0; VPADDD state1StoreAVX2, BB1, BB1; VPADDD state1StoreAVX2, BB2, BB2; VPADDD state1StoreAVX2, BB3, BB3 + VPADDD state2StoreAVX2, CC0, CC0; VPADDD state2StoreAVX2, CC1, CC1; VPADDD state2StoreAVX2, CC2, CC2; VPADDD state2StoreAVX2, CC3, CC3 + VPADDD ctr0StoreAVX2, DD0, DD0; VPADDD ctr1StoreAVX2, DD1, DD1; VPADDD ctr2StoreAVX2, DD2, DD2; VPADDD ctr3StoreAVX2, DD3, DD3 + VMOVDQA CC3, tmpStoreAVX2 + VPERM2I128 $0x02, AA0, BB0, CC3 + VPXOR (0*32)(inp), CC3, CC3 + VMOVDQU CC3, (0*32)(oup) + VPERM2I128 $0x02, CC0, DD0, CC3 + VPXOR (1*32)(inp), CC3, CC3 + VMOVDQU CC3, (1*32)(oup) + VPERM2I128 $0x13, AA0, BB0, CC3 + VPXOR (2*32)(inp), CC3, CC3 + VMOVDQU CC3, (2*32)(oup) + VPERM2I128 $0x13, CC0, DD0, CC3 + VPXOR (3*32)(inp), CC3, CC3 + VMOVDQU CC3, (3*32)(oup) + + VPERM2I128 $0x02, AA1, BB1, AA0 + VPERM2I128 $0x02, CC1, DD1, BB0 + VPERM2I128 $0x13, AA1, BB1, CC0 + VPERM2I128 $0x13, CC1, DD1, DD0 + VPXOR (4*32)(inp), AA0, AA0; VPXOR (5*32)(inp), BB0, BB0; VPXOR (6*32)(inp), CC0, CC0; VPXOR (7*32)(inp), DD0, DD0 + VMOVDQU AA0, (4*32)(oup); VMOVDQU BB0, (5*32)(oup); VMOVDQU CC0, (6*32)(oup); VMOVDQU DD0, (7*32)(oup) + + VPERM2I128 $0x02, AA2, BB2, AA0 + VPERM2I128 $0x02, CC2, DD2, BB0 + VPERM2I128 $0x13, AA2, BB2, CC0 + VPERM2I128 $0x13, CC2, DD2, DD0 + VPXOR (8*32)(inp), AA0, AA0; VPXOR (9*32)(inp), BB0, BB0; VPXOR (10*32)(inp), CC0, CC0; VPXOR (11*32)(inp), DD0, DD0 + VMOVDQU AA0, (8*32)(oup); VMOVDQU BB0, (9*32)(oup); VMOVDQU CC0, (10*32)(oup); VMOVDQU DD0, (11*32)(oup) + + MOVQ $384, itr1 + LEAQ 384(inp), inp + SUBQ $384, inl + VPERM2I128 $0x02, AA3, BB3, AA0 + VPERM2I128 $0x02, tmpStoreAVX2, DD3, BB0 + VPERM2I128 $0x13, AA3, BB3, CC0 + VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0 + + JMP sealAVX2SealHash diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go new file mode 100644 index 00000000..75f24bab --- /dev/null +++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -0,0 +1,834 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// We have an implementation in amd64 assembly so this code is only run on +// non-amd64 platforms. The amd64 assembly does not support gccgo. +// +build !amd64 gccgo appengine + +package curve25519 + +import ( + "encoding/binary" +) + +// This code is a port of the public domain, "ref10" implementation of +// curve25519 from SUPERCOP 20130419 by D. J. Bernstein. + +// fieldElement represents an element of the field GF(2^255 - 19). An element +// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on +// context. +type fieldElement [10]int32 + +func feZero(fe *fieldElement) { + for i := range fe { + fe[i] = 0 + } +} + +func feOne(fe *fieldElement) { + feZero(fe) + fe[0] = 1 +} + +func feAdd(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] + b[i] + } +} + +func feSub(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] - b[i] + } +} + +func feCopy(dst, src *fieldElement) { + for i := range dst { + dst[i] = src[i] + } +} + +// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +func feCSwap(f, g *fieldElement, b int32) { + b = -b + for i := range f { + t := b & (f[i] ^ g[i]) + f[i] ^= t + g[i] ^= t + } +} + +// load3 reads a 24-bit, little-endian value from in. +func load3(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + return r +} + +// load4 reads a 32-bit, little-endian value from in. +func load4(in []byte) int64 { + return int64(binary.LittleEndian.Uint32(in)) +} + +func feFromBytes(dst *fieldElement, src *[32]byte) { + h0 := load4(src[:]) + h1 := load3(src[4:]) << 6 + h2 := load3(src[7:]) << 5 + h3 := load3(src[10:]) << 3 + h4 := load3(src[13:]) << 2 + h5 := load4(src[16:]) + h6 := load3(src[20:]) << 7 + h7 := load3(src[23:]) << 5 + h8 := load3(src[26:]) << 4 + h9 := (load3(src[29:]) & 0x7fffff) << 2 + + var carry [10]int64 + carry[9] = (h9 + 1<<24) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + 1<<24) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + 1<<24) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + 1<<24) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + 1<<24) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + 1<<25) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + 1<<25) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + 1<<25) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + 1<<25) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + 1<<25) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + dst[0] = int32(h0) + dst[1] = int32(h1) + dst[2] = int32(h2) + dst[3] = int32(h3) + dst[4] = int32(h4) + dst[5] = int32(h5) + dst[6] = int32(h6) + dst[7] = int32(h7) + dst[8] = int32(h8) + dst[9] = int32(h9) +} + +// feToBytes marshals h to s. +// Preconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Write p=2^255-19; q=floor(h/p). +// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +// +// Proof: +// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +// +// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +// Then 0> 25 + q = (h[0] + q) >> 26 + q = (h[1] + q) >> 25 + q = (h[2] + q) >> 26 + q = (h[3] + q) >> 25 + q = (h[4] + q) >> 26 + q = (h[5] + q) >> 25 + q = (h[6] + q) >> 26 + q = (h[7] + q) >> 25 + q = (h[8] + q) >> 26 + q = (h[9] + q) >> 25 + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += 19 * q + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26 + h[1] += carry[0] + h[0] -= carry[0] << 26 + carry[1] = h[1] >> 25 + h[2] += carry[1] + h[1] -= carry[1] << 25 + carry[2] = h[2] >> 26 + h[3] += carry[2] + h[2] -= carry[2] << 26 + carry[3] = h[3] >> 25 + h[4] += carry[3] + h[3] -= carry[3] << 25 + carry[4] = h[4] >> 26 + h[5] += carry[4] + h[4] -= carry[4] << 26 + carry[5] = h[5] >> 25 + h[6] += carry[5] + h[5] -= carry[5] << 25 + carry[6] = h[6] >> 26 + h[7] += carry[6] + h[6] -= carry[6] << 26 + carry[7] = h[7] >> 25 + h[8] += carry[7] + h[7] -= carry[7] << 25 + carry[8] = h[8] >> 26 + h[9] += carry[8] + h[8] -= carry[8] << 26 + carry[9] = h[9] >> 25 + h[9] -= carry[9] << 25 + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = byte(h[0] >> 0) + s[1] = byte(h[0] >> 8) + s[2] = byte(h[0] >> 16) + s[3] = byte((h[0] >> 24) | (h[1] << 2)) + s[4] = byte(h[1] >> 6) + s[5] = byte(h[1] >> 14) + s[6] = byte((h[1] >> 22) | (h[2] << 3)) + s[7] = byte(h[2] >> 5) + s[8] = byte(h[2] >> 13) + s[9] = byte((h[2] >> 21) | (h[3] << 5)) + s[10] = byte(h[3] >> 3) + s[11] = byte(h[3] >> 11) + s[12] = byte((h[3] >> 19) | (h[4] << 6)) + s[13] = byte(h[4] >> 2) + s[14] = byte(h[4] >> 10) + s[15] = byte(h[4] >> 18) + s[16] = byte(h[5] >> 0) + s[17] = byte(h[5] >> 8) + s[18] = byte(h[5] >> 16) + s[19] = byte((h[5] >> 24) | (h[6] << 1)) + s[20] = byte(h[6] >> 7) + s[21] = byte(h[6] >> 15) + s[22] = byte((h[6] >> 23) | (h[7] << 3)) + s[23] = byte(h[7] >> 5) + s[24] = byte(h[7] >> 13) + s[25] = byte((h[7] >> 21) | (h[8] << 4)) + s[26] = byte(h[8] >> 4) + s[27] = byte(h[8] >> 12) + s[28] = byte((h[8] >> 20) | (h[9] << 6)) + s[29] = byte(h[9] >> 2) + s[30] = byte(h[9] >> 10) + s[31] = byte(h[9] >> 18) +} + +// feMul calculates h = f * g +// Can overlap h with f or g. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Notes on implementation strategy: +// +// Using schoolbook multiplication. +// Karatsuba would save a little in some cost models. +// +// Most multiplications by 2 and 19 are 32-bit precomputations; +// cheaper than 64-bit postcomputations. +// +// There is one remaining multiplication by 19 in the carry chain; +// one *19 precomputation can be merged into this, +// but the resulting data flow is considerably less clean. +// +// There are 12 carries below. +// 10 of them are 2-way parallelizable and vectorizable. +// Can get away with 11 carries, but then data flow is much deeper. +// +// With tighter constraints on inputs can squeeze carries into int32. +func feMul(h, f, g *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + g0 := g[0] + g1 := g[1] + g2 := g[2] + g3 := g[3] + g4 := g[4] + g5 := g[5] + g6 := g[6] + g7 := g[7] + g8 := g[8] + g9 := g[9] + g1_19 := 19 * g1 // 1.4*2^29 + g2_19 := 19 * g2 // 1.4*2^30; still ok + g3_19 := 19 * g3 + g4_19 := 19 * g4 + g5_19 := 19 * g5 + g6_19 := 19 * g6 + g7_19 := 19 * g7 + g8_19 := 19 * g8 + g9_19 := 19 * g9 + f1_2 := 2 * f1 + f3_2 := 2 * f3 + f5_2 := 2 * f5 + f7_2 := 2 * f7 + f9_2 := 2 * f9 + f0g0 := int64(f0) * int64(g0) + f0g1 := int64(f0) * int64(g1) + f0g2 := int64(f0) * int64(g2) + f0g3 := int64(f0) * int64(g3) + f0g4 := int64(f0) * int64(g4) + f0g5 := int64(f0) * int64(g5) + f0g6 := int64(f0) * int64(g6) + f0g7 := int64(f0) * int64(g7) + f0g8 := int64(f0) * int64(g8) + f0g9 := int64(f0) * int64(g9) + f1g0 := int64(f1) * int64(g0) + f1g1_2 := int64(f1_2) * int64(g1) + f1g2 := int64(f1) * int64(g2) + f1g3_2 := int64(f1_2) * int64(g3) + f1g4 := int64(f1) * int64(g4) + f1g5_2 := int64(f1_2) * int64(g5) + f1g6 := int64(f1) * int64(g6) + f1g7_2 := int64(f1_2) * int64(g7) + f1g8 := int64(f1) * int64(g8) + f1g9_38 := int64(f1_2) * int64(g9_19) + f2g0 := int64(f2) * int64(g0) + f2g1 := int64(f2) * int64(g1) + f2g2 := int64(f2) * int64(g2) + f2g3 := int64(f2) * int64(g3) + f2g4 := int64(f2) * int64(g4) + f2g5 := int64(f2) * int64(g5) + f2g6 := int64(f2) * int64(g6) + f2g7 := int64(f2) * int64(g7) + f2g8_19 := int64(f2) * int64(g8_19) + f2g9_19 := int64(f2) * int64(g9_19) + f3g0 := int64(f3) * int64(g0) + f3g1_2 := int64(f3_2) * int64(g1) + f3g2 := int64(f3) * int64(g2) + f3g3_2 := int64(f3_2) * int64(g3) + f3g4 := int64(f3) * int64(g4) + f3g5_2 := int64(f3_2) * int64(g5) + f3g6 := int64(f3) * int64(g6) + f3g7_38 := int64(f3_2) * int64(g7_19) + f3g8_19 := int64(f3) * int64(g8_19) + f3g9_38 := int64(f3_2) * int64(g9_19) + f4g0 := int64(f4) * int64(g0) + f4g1 := int64(f4) * int64(g1) + f4g2 := int64(f4) * int64(g2) + f4g3 := int64(f4) * int64(g3) + f4g4 := int64(f4) * int64(g4) + f4g5 := int64(f4) * int64(g5) + f4g6_19 := int64(f4) * int64(g6_19) + f4g7_19 := int64(f4) * int64(g7_19) + f4g8_19 := int64(f4) * int64(g8_19) + f4g9_19 := int64(f4) * int64(g9_19) + f5g0 := int64(f5) * int64(g0) + f5g1_2 := int64(f5_2) * int64(g1) + f5g2 := int64(f5) * int64(g2) + f5g3_2 := int64(f5_2) * int64(g3) + f5g4 := int64(f5) * int64(g4) + f5g5_38 := int64(f5_2) * int64(g5_19) + f5g6_19 := int64(f5) * int64(g6_19) + f5g7_38 := int64(f5_2) * int64(g7_19) + f5g8_19 := int64(f5) * int64(g8_19) + f5g9_38 := int64(f5_2) * int64(g9_19) + f6g0 := int64(f6) * int64(g0) + f6g1 := int64(f6) * int64(g1) + f6g2 := int64(f6) * int64(g2) + f6g3 := int64(f6) * int64(g3) + f6g4_19 := int64(f6) * int64(g4_19) + f6g5_19 := int64(f6) * int64(g5_19) + f6g6_19 := int64(f6) * int64(g6_19) + f6g7_19 := int64(f6) * int64(g7_19) + f6g8_19 := int64(f6) * int64(g8_19) + f6g9_19 := int64(f6) * int64(g9_19) + f7g0 := int64(f7) * int64(g0) + f7g1_2 := int64(f7_2) * int64(g1) + f7g2 := int64(f7) * int64(g2) + f7g3_38 := int64(f7_2) * int64(g3_19) + f7g4_19 := int64(f7) * int64(g4_19) + f7g5_38 := int64(f7_2) * int64(g5_19) + f7g6_19 := int64(f7) * int64(g6_19) + f7g7_38 := int64(f7_2) * int64(g7_19) + f7g8_19 := int64(f7) * int64(g8_19) + f7g9_38 := int64(f7_2) * int64(g9_19) + f8g0 := int64(f8) * int64(g0) + f8g1 := int64(f8) * int64(g1) + f8g2_19 := int64(f8) * int64(g2_19) + f8g3_19 := int64(f8) * int64(g3_19) + f8g4_19 := int64(f8) * int64(g4_19) + f8g5_19 := int64(f8) * int64(g5_19) + f8g6_19 := int64(f8) * int64(g6_19) + f8g7_19 := int64(f8) * int64(g7_19) + f8g8_19 := int64(f8) * int64(g8_19) + f8g9_19 := int64(f8) * int64(g9_19) + f9g0 := int64(f9) * int64(g0) + f9g1_38 := int64(f9_2) * int64(g1_19) + f9g2_19 := int64(f9) * int64(g2_19) + f9g3_38 := int64(f9_2) * int64(g3_19) + f9g4_19 := int64(f9) * int64(g4_19) + f9g5_38 := int64(f9_2) * int64(g5_19) + f9g6_19 := int64(f9) * int64(g6_19) + f9g7_38 := int64(f9_2) * int64(g7_19) + f9g8_19 := int64(f9) * int64(g8_19) + f9g9_38 := int64(f9_2) * int64(g9_19) + h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 + h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 + h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 + h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 + h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 + h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 + h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 + h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 + h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 + h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 + var carry [10]int64 + + // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + // |h0| <= 2^25 + // |h4| <= 2^25 + // |h1| <= 1.51*2^58 + // |h5| <= 1.51*2^58 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + // |h1| <= 2^24; from now on fits into int32 + // |h5| <= 2^24; from now on fits into int32 + // |h2| <= 1.21*2^59 + // |h6| <= 1.21*2^59 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + // |h2| <= 2^25; from now on fits into int32 unchanged + // |h6| <= 2^25; from now on fits into int32 unchanged + // |h3| <= 1.51*2^58 + // |h7| <= 1.51*2^58 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + // |h3| <= 2^24; from now on fits into int32 unchanged + // |h7| <= 2^24; from now on fits into int32 unchanged + // |h4| <= 1.52*2^33 + // |h8| <= 1.52*2^33 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + // |h4| <= 2^25; from now on fits into int32 unchanged + // |h8| <= 2^25; from now on fits into int32 unchanged + // |h5| <= 1.01*2^24 + // |h9| <= 1.51*2^58 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + // |h9| <= 2^24; from now on fits into int32 unchanged + // |h0| <= 1.8*2^37 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + // |h0| <= 2^25; from now on fits into int32 unchanged + // |h1| <= 1.01*2^24 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feSquare calculates h = f*f. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feSquare(h, f *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + f0_2 := 2 * f0 + f1_2 := 2 * f1 + f2_2 := 2 * f2 + f3_2 := 2 * f3 + f4_2 := 2 * f4 + f5_2 := 2 * f5 + f6_2 := 2 * f6 + f7_2 := 2 * f7 + f5_38 := 38 * f5 // 1.31*2^30 + f6_19 := 19 * f6 // 1.31*2^30 + f7_38 := 38 * f7 // 1.31*2^30 + f8_19 := 19 * f8 // 1.31*2^30 + f9_38 := 38 * f9 // 1.31*2^30 + f0f0 := int64(f0) * int64(f0) + f0f1_2 := int64(f0_2) * int64(f1) + f0f2_2 := int64(f0_2) * int64(f2) + f0f3_2 := int64(f0_2) * int64(f3) + f0f4_2 := int64(f0_2) * int64(f4) + f0f5_2 := int64(f0_2) * int64(f5) + f0f6_2 := int64(f0_2) * int64(f6) + f0f7_2 := int64(f0_2) * int64(f7) + f0f8_2 := int64(f0_2) * int64(f8) + f0f9_2 := int64(f0_2) * int64(f9) + f1f1_2 := int64(f1_2) * int64(f1) + f1f2_2 := int64(f1_2) * int64(f2) + f1f3_4 := int64(f1_2) * int64(f3_2) + f1f4_2 := int64(f1_2) * int64(f4) + f1f5_4 := int64(f1_2) * int64(f5_2) + f1f6_2 := int64(f1_2) * int64(f6) + f1f7_4 := int64(f1_2) * int64(f7_2) + f1f8_2 := int64(f1_2) * int64(f8) + f1f9_76 := int64(f1_2) * int64(f9_38) + f2f2 := int64(f2) * int64(f2) + f2f3_2 := int64(f2_2) * int64(f3) + f2f4_2 := int64(f2_2) * int64(f4) + f2f5_2 := int64(f2_2) * int64(f5) + f2f6_2 := int64(f2_2) * int64(f6) + f2f7_2 := int64(f2_2) * int64(f7) + f2f8_38 := int64(f2_2) * int64(f8_19) + f2f9_38 := int64(f2) * int64(f9_38) + f3f3_2 := int64(f3_2) * int64(f3) + f3f4_2 := int64(f3_2) * int64(f4) + f3f5_4 := int64(f3_2) * int64(f5_2) + f3f6_2 := int64(f3_2) * int64(f6) + f3f7_76 := int64(f3_2) * int64(f7_38) + f3f8_38 := int64(f3_2) * int64(f8_19) + f3f9_76 := int64(f3_2) * int64(f9_38) + f4f4 := int64(f4) * int64(f4) + f4f5_2 := int64(f4_2) * int64(f5) + f4f6_38 := int64(f4_2) * int64(f6_19) + f4f7_38 := int64(f4) * int64(f7_38) + f4f8_38 := int64(f4_2) * int64(f8_19) + f4f9_38 := int64(f4) * int64(f9_38) + f5f5_38 := int64(f5) * int64(f5_38) + f5f6_38 := int64(f5_2) * int64(f6_19) + f5f7_76 := int64(f5_2) * int64(f7_38) + f5f8_38 := int64(f5_2) * int64(f8_19) + f5f9_76 := int64(f5_2) * int64(f9_38) + f6f6_19 := int64(f6) * int64(f6_19) + f6f7_38 := int64(f6) * int64(f7_38) + f6f8_38 := int64(f6_2) * int64(f8_19) + f6f9_38 := int64(f6) * int64(f9_38) + f7f7_38 := int64(f7) * int64(f7_38) + f7f8_38 := int64(f7_2) * int64(f8_19) + f7f9_76 := int64(f7_2) * int64(f9_38) + f8f8_19 := int64(f8) * int64(f8_19) + f8f9_38 := int64(f8) * int64(f9_38) + f9f9_38 := int64(f9) * int64(f9_38) + h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 + h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 + h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 + h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 + h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 + h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 + h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 + h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 + h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 + h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 + var carry [10]int64 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feMul121666 calculates h = f * 121666. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feMul121666(h, f *fieldElement) { + h0 := int64(f[0]) * 121666 + h1 := int64(f[1]) * 121666 + h2 := int64(f[2]) * 121666 + h3 := int64(f[3]) * 121666 + h4 := int64(f[4]) * 121666 + h5 := int64(f[5]) * 121666 + h6 := int64(f[6]) * 121666 + h7 := int64(f[7]) * 121666 + h8 := int64(f[8]) * 121666 + h9 := int64(f[9]) * 121666 + var carry [10]int64 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feInvert sets out = z^-1. +func feInvert(out, z *fieldElement) { + var t0, t1, t2, t3 fieldElement + var i int + + feSquare(&t0, z) + for i = 1; i < 1; i++ { + feSquare(&t0, &t0) + } + feSquare(&t1, &t0) + for i = 1; i < 2; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, z, &t1) + feMul(&t0, &t0, &t1) + feSquare(&t2, &t0) + for i = 1; i < 1; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t1, &t2) + feSquare(&t2, &t1) + for i = 1; i < 5; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 20; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 100; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t1, &t1) + for i = 1; i < 5; i++ { + feSquare(&t1, &t1) + } + feMul(out, &t1, &t0) +} + +func scalarMult(out, in, base *[32]byte) { + var e [32]byte + + copy(e[:], in[:]) + e[0] &= 248 + e[31] &= 127 + e[31] |= 64 + + var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement + feFromBytes(&x1, base) + feOne(&x2) + feCopy(&x3, &x1) + feOne(&z3) + + swap := int32(0) + for pos := 254; pos >= 0; pos-- { + b := e[pos/8] >> uint(pos&7) + b &= 1 + swap ^= int32(b) + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + swap = int32(b) + + feSub(&tmp0, &x3, &z3) + feSub(&tmp1, &x2, &z2) + feAdd(&x2, &x2, &z2) + feAdd(&z2, &x3, &z3) + feMul(&z3, &tmp0, &x2) + feMul(&z2, &z2, &tmp1) + feSquare(&tmp0, &tmp1) + feSquare(&tmp1, &x2) + feAdd(&x3, &z3, &z2) + feSub(&z2, &z3, &z2) + feMul(&x2, &tmp1, &tmp0) + feSub(&tmp1, &tmp1, &tmp0) + feSquare(&z2, &z2) + feMul121666(&z3, &tmp1) + feSquare(&x3, &x3) + feAdd(&tmp0, &tmp0, &z3) + feMul(&z3, &x1, &z2) + feMul(&z2, &tmp1, &tmp0) + } + + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + + feInvert(&z2, &z2) + feMul(&x2, &x2, &z2) + feToBytes(out, &x2) +} diff --git a/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s new file mode 100644 index 00000000..e0ac30c7 --- /dev/null +++ b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s @@ -0,0 +1,1377 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +#include "const_amd64.h" + +// func ladderstep(inout *[5][5]uint64) +TEXT ·ladderstep(SB),0,$296-8 + MOVQ inout+0(FP),DI + + MOVQ 40(DI),SI + MOVQ 48(DI),DX + MOVQ 56(DI),CX + MOVQ 64(DI),R8 + MOVQ 72(DI),R9 + MOVQ SI,AX + MOVQ DX,R10 + MOVQ CX,R11 + MOVQ R8,R12 + MOVQ R9,R13 + ADDQ ·_2P0(SB),AX + ADDQ ·_2P1234(SB),R10 + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 80(DI),SI + ADDQ 88(DI),DX + ADDQ 96(DI),CX + ADDQ 104(DI),R8 + ADDQ 112(DI),R9 + SUBQ 80(DI),AX + SUBQ 88(DI),R10 + SUBQ 96(DI),R11 + SUBQ 104(DI),R12 + SUBQ 112(DI),R13 + MOVQ SI,0(SP) + MOVQ DX,8(SP) + MOVQ CX,16(SP) + MOVQ R8,24(SP) + MOVQ R9,32(SP) + MOVQ AX,40(SP) + MOVQ R10,48(SP) + MOVQ R11,56(SP) + MOVQ R12,64(SP) + MOVQ R13,72(SP) + MOVQ 40(SP),AX + MULQ 40(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 40(SP),AX + SHLQ $1,AX + MULQ 48(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 40(SP),AX + SHLQ $1,AX + MULQ 56(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 40(SP),AX + SHLQ $1,AX + MULQ 64(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 40(SP),AX + SHLQ $1,AX + MULQ 72(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 48(SP),AX + MULQ 48(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 48(SP),AX + SHLQ $1,AX + MULQ 56(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 48(SP),AX + SHLQ $1,AX + MULQ 64(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 48(SP),DX + IMUL3Q $38,DX,AX + MULQ 72(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 56(SP),AX + MULQ 56(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 56(SP),DX + IMUL3Q $38,DX,AX + MULQ 64(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 56(SP),DX + IMUL3Q $38,DX,AX + MULQ 72(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 64(SP),DX + IMUL3Q $19,DX,AX + MULQ 64(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 64(SP),DX + IMUL3Q $38,DX,AX + MULQ 72(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 72(SP),DX + IMUL3Q $19,DX,AX + MULQ 72(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,80(SP) + MOVQ R8,88(SP) + MOVQ R9,96(SP) + MOVQ AX,104(SP) + MOVQ R10,112(SP) + MOVQ 0(SP),AX + MULQ 0(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 0(SP),AX + SHLQ $1,AX + MULQ 8(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 0(SP),AX + SHLQ $1,AX + MULQ 16(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 0(SP),AX + SHLQ $1,AX + MULQ 24(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 0(SP),AX + SHLQ $1,AX + MULQ 32(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 8(SP),AX + MULQ 8(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SP),AX + SHLQ $1,AX + MULQ 16(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 8(SP),AX + SHLQ $1,AX + MULQ 24(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SP),DX + IMUL3Q $38,DX,AX + MULQ 32(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 16(SP),AX + MULQ 16(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 16(SP),DX + IMUL3Q $38,DX,AX + MULQ 24(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 16(SP),DX + IMUL3Q $38,DX,AX + MULQ 32(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 24(SP),DX + IMUL3Q $19,DX,AX + MULQ 24(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 24(SP),DX + IMUL3Q $38,DX,AX + MULQ 32(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 32(SP),DX + IMUL3Q $19,DX,AX + MULQ 32(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,120(SP) + MOVQ R8,128(SP) + MOVQ R9,136(SP) + MOVQ AX,144(SP) + MOVQ R10,152(SP) + MOVQ SI,SI + MOVQ R8,DX + MOVQ R9,CX + MOVQ AX,R8 + MOVQ R10,R9 + ADDQ ·_2P0(SB),SI + ADDQ ·_2P1234(SB),DX + ADDQ ·_2P1234(SB),CX + ADDQ ·_2P1234(SB),R8 + ADDQ ·_2P1234(SB),R9 + SUBQ 80(SP),SI + SUBQ 88(SP),DX + SUBQ 96(SP),CX + SUBQ 104(SP),R8 + SUBQ 112(SP),R9 + MOVQ SI,160(SP) + MOVQ DX,168(SP) + MOVQ CX,176(SP) + MOVQ R8,184(SP) + MOVQ R9,192(SP) + MOVQ 120(DI),SI + MOVQ 128(DI),DX + MOVQ 136(DI),CX + MOVQ 144(DI),R8 + MOVQ 152(DI),R9 + MOVQ SI,AX + MOVQ DX,R10 + MOVQ CX,R11 + MOVQ R8,R12 + MOVQ R9,R13 + ADDQ ·_2P0(SB),AX + ADDQ ·_2P1234(SB),R10 + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 160(DI),SI + ADDQ 168(DI),DX + ADDQ 176(DI),CX + ADDQ 184(DI),R8 + ADDQ 192(DI),R9 + SUBQ 160(DI),AX + SUBQ 168(DI),R10 + SUBQ 176(DI),R11 + SUBQ 184(DI),R12 + SUBQ 192(DI),R13 + MOVQ SI,200(SP) + MOVQ DX,208(SP) + MOVQ CX,216(SP) + MOVQ R8,224(SP) + MOVQ R9,232(SP) + MOVQ AX,240(SP) + MOVQ R10,248(SP) + MOVQ R11,256(SP) + MOVQ R12,264(SP) + MOVQ R13,272(SP) + MOVQ 224(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,280(SP) + MULQ 56(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 232(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,288(SP) + MULQ 48(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 200(SP),AX + MULQ 40(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 200(SP),AX + MULQ 48(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 200(SP),AX + MULQ 56(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 200(SP),AX + MULQ 64(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 200(SP),AX + MULQ 72(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 208(SP),AX + MULQ 40(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 208(SP),AX + MULQ 48(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 208(SP),AX + MULQ 56(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 208(SP),AX + MULQ 64(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 208(SP),DX + IMUL3Q $19,DX,AX + MULQ 72(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 216(SP),AX + MULQ 40(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 216(SP),AX + MULQ 48(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 216(SP),AX + MULQ 56(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 216(SP),DX + IMUL3Q $19,DX,AX + MULQ 64(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 216(SP),DX + IMUL3Q $19,DX,AX + MULQ 72(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 224(SP),AX + MULQ 40(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 224(SP),AX + MULQ 48(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 280(SP),AX + MULQ 64(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 280(SP),AX + MULQ 72(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 232(SP),AX + MULQ 40(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 288(SP),AX + MULQ 56(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 288(SP),AX + MULQ 64(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 288(SP),AX + MULQ 72(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,40(SP) + MOVQ R8,48(SP) + MOVQ R9,56(SP) + MOVQ AX,64(SP) + MOVQ R10,72(SP) + MOVQ 264(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,200(SP) + MULQ 16(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 272(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,208(SP) + MULQ 8(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 240(SP),AX + MULQ 0(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 240(SP),AX + MULQ 8(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 240(SP),AX + MULQ 16(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 240(SP),AX + MULQ 24(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 240(SP),AX + MULQ 32(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 248(SP),AX + MULQ 0(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 248(SP),AX + MULQ 8(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 248(SP),AX + MULQ 16(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 248(SP),AX + MULQ 24(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 248(SP),DX + IMUL3Q $19,DX,AX + MULQ 32(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 256(SP),AX + MULQ 0(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 256(SP),AX + MULQ 8(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 256(SP),AX + MULQ 16(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 256(SP),DX + IMUL3Q $19,DX,AX + MULQ 24(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 256(SP),DX + IMUL3Q $19,DX,AX + MULQ 32(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 264(SP),AX + MULQ 0(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 264(SP),AX + MULQ 8(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 200(SP),AX + MULQ 24(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 200(SP),AX + MULQ 32(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 272(SP),AX + MULQ 0(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 208(SP),AX + MULQ 16(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 208(SP),AX + MULQ 24(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 208(SP),AX + MULQ 32(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,DX + MOVQ R8,CX + MOVQ R9,R11 + MOVQ AX,R12 + MOVQ R10,R13 + ADDQ ·_2P0(SB),DX + ADDQ ·_2P1234(SB),CX + ADDQ ·_2P1234(SB),R11 + ADDQ ·_2P1234(SB),R12 + ADDQ ·_2P1234(SB),R13 + ADDQ 40(SP),SI + ADDQ 48(SP),R8 + ADDQ 56(SP),R9 + ADDQ 64(SP),AX + ADDQ 72(SP),R10 + SUBQ 40(SP),DX + SUBQ 48(SP),CX + SUBQ 56(SP),R11 + SUBQ 64(SP),R12 + SUBQ 72(SP),R13 + MOVQ SI,120(DI) + MOVQ R8,128(DI) + MOVQ R9,136(DI) + MOVQ AX,144(DI) + MOVQ R10,152(DI) + MOVQ DX,160(DI) + MOVQ CX,168(DI) + MOVQ R11,176(DI) + MOVQ R12,184(DI) + MOVQ R13,192(DI) + MOVQ 120(DI),AX + MULQ 120(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 128(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 136(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 144(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 120(DI),AX + SHLQ $1,AX + MULQ 152(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 128(DI),AX + MULQ 128(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 128(DI),AX + SHLQ $1,AX + MULQ 136(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 128(DI),AX + SHLQ $1,AX + MULQ 144(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 128(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(DI),AX + MULQ 136(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 136(DI),DX + IMUL3Q $38,DX,AX + MULQ 144(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 144(DI),DX + IMUL3Q $19,DX,AX + MULQ 144(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 144(DI),DX + IMUL3Q $38,DX,AX + MULQ 152(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 152(DI),DX + IMUL3Q $19,DX,AX + MULQ 152(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,120(DI) + MOVQ R8,128(DI) + MOVQ R9,136(DI) + MOVQ AX,144(DI) + MOVQ R10,152(DI) + MOVQ 160(DI),AX + MULQ 160(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 168(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 176(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 184(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 160(DI),AX + SHLQ $1,AX + MULQ 192(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 168(DI),AX + MULQ 168(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 168(DI),AX + SHLQ $1,AX + MULQ 176(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 168(DI),AX + SHLQ $1,AX + MULQ 184(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 168(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),AX + MULQ 176(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 176(DI),DX + IMUL3Q $38,DX,AX + MULQ 184(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),DX + IMUL3Q $19,DX,AX + MULQ 184(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),DX + IMUL3Q $38,DX,AX + MULQ 192(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 192(DI),DX + IMUL3Q $19,DX,AX + MULQ 192(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + ANDQ DX,SI + MOVQ CX,R8 + SHRQ $51,CX + ADDQ R10,CX + ANDQ DX,R8 + MOVQ CX,R9 + SHRQ $51,CX + ADDQ R12,CX + ANDQ DX,R9 + MOVQ CX,AX + SHRQ $51,CX + ADDQ R14,CX + ANDQ DX,AX + MOVQ CX,R10 + SHRQ $51,CX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,160(DI) + MOVQ R8,168(DI) + MOVQ R9,176(DI) + MOVQ AX,184(DI) + MOVQ R10,192(DI) + MOVQ 184(DI),SI + IMUL3Q $19,SI,AX + MOVQ AX,0(SP) + MULQ 16(DI) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 192(DI),DX + IMUL3Q $19,DX,AX + MOVQ AX,8(SP) + MULQ 8(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 160(DI),AX + MULQ 0(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 160(DI),AX + MULQ 8(DI) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 160(DI),AX + MULQ 16(DI) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 160(DI),AX + MULQ 24(DI) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 160(DI),AX + MULQ 32(DI) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 168(DI),AX + MULQ 0(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 168(DI),AX + MULQ 8(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 168(DI),AX + MULQ 16(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 168(DI),AX + MULQ 24(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 168(DI),DX + IMUL3Q $19,DX,AX + MULQ 32(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),AX + MULQ 0(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 176(DI),AX + MULQ 8(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 176(DI),AX + MULQ 16(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 176(DI),DX + IMUL3Q $19,DX,AX + MULQ 24(DI) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 176(DI),DX + IMUL3Q $19,DX,AX + MULQ 32(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 184(DI),AX + MULQ 0(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 184(DI),AX + MULQ 8(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 0(SP),AX + MULQ 24(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SP),AX + MULQ 32(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 192(DI),AX + MULQ 0(DI) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SP),AX + MULQ 16(DI) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 8(SP),AX + MULQ 24(DI) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SP),AX + MULQ 32(DI) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,160(DI) + MOVQ R8,168(DI) + MOVQ R9,176(DI) + MOVQ AX,184(DI) + MOVQ R10,192(DI) + MOVQ 144(SP),SI + IMUL3Q $19,SI,AX + MOVQ AX,0(SP) + MULQ 96(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 152(SP),DX + IMUL3Q $19,DX,AX + MOVQ AX,8(SP) + MULQ 88(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 120(SP),AX + MULQ 80(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 120(SP),AX + MULQ 88(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 120(SP),AX + MULQ 96(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 120(SP),AX + MULQ 104(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 120(SP),AX + MULQ 112(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 128(SP),AX + MULQ 80(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 128(SP),AX + MULQ 88(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 128(SP),AX + MULQ 96(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 128(SP),AX + MULQ 104(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 128(SP),DX + IMUL3Q $19,DX,AX + MULQ 112(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(SP),AX + MULQ 80(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 136(SP),AX + MULQ 88(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 136(SP),AX + MULQ 96(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 136(SP),DX + IMUL3Q $19,DX,AX + MULQ 104(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 136(SP),DX + IMUL3Q $19,DX,AX + MULQ 112(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 144(SP),AX + MULQ 80(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 144(SP),AX + MULQ 88(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 0(SP),AX + MULQ 104(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SP),AX + MULQ 112(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 152(SP),AX + MULQ 80(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SP),AX + MULQ 96(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 8(SP),AX + MULQ 104(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SP),AX + MULQ 112(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,40(DI) + MOVQ R8,48(DI) + MOVQ R9,56(DI) + MOVQ AX,64(DI) + MOVQ R10,72(DI) + MOVQ 160(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + MOVQ AX,SI + MOVQ DX,CX + MOVQ 168(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,CX + MOVQ DX,R8 + MOVQ 176(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R8 + MOVQ DX,R9 + MOVQ 184(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R9 + MOVQ DX,R10 + MOVQ 192(SP),AX + MULQ ·_121666_213(SB) + SHRQ $13,AX + ADDQ AX,R10 + IMUL3Q $19,DX,DX + ADDQ DX,SI + ADDQ 80(SP),SI + ADDQ 88(SP),CX + ADDQ 96(SP),R8 + ADDQ 104(SP),R9 + ADDQ 112(SP),R10 + MOVQ SI,80(DI) + MOVQ CX,88(DI) + MOVQ R8,96(DI) + MOVQ R9,104(DI) + MOVQ R10,112(DI) + MOVQ 104(DI),SI + IMUL3Q $19,SI,AX + MOVQ AX,0(SP) + MULQ 176(SP) + MOVQ AX,SI + MOVQ DX,CX + MOVQ 112(DI),DX + IMUL3Q $19,DX,AX + MOVQ AX,8(SP) + MULQ 168(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 80(DI),AX + MULQ 160(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 80(DI),AX + MULQ 168(SP) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 80(DI),AX + MULQ 176(SP) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 80(DI),AX + MULQ 184(SP) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 80(DI),AX + MULQ 192(SP) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 88(DI),AX + MULQ 160(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 88(DI),AX + MULQ 168(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 88(DI),AX + MULQ 176(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 88(DI),AX + MULQ 184(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 88(DI),DX + IMUL3Q $19,DX,AX + MULQ 192(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 96(DI),AX + MULQ 160(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 96(DI),AX + MULQ 168(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 96(DI),AX + MULQ 176(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 96(DI),DX + IMUL3Q $19,DX,AX + MULQ 184(SP) + ADDQ AX,SI + ADCQ DX,CX + MOVQ 96(DI),DX + IMUL3Q $19,DX,AX + MULQ 192(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 104(DI),AX + MULQ 160(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 104(DI),AX + MULQ 168(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 0(SP),AX + MULQ 184(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SP),AX + MULQ 192(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 112(DI),AX + MULQ 160(SP) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SP),AX + MULQ 176(SP) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 8(SP),AX + MULQ 184(SP) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SP),AX + MULQ 192(SP) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ $REDMASK51,DX + SHLQ $13,SI,CX + ANDQ DX,SI + SHLQ $13,R8,R9 + ANDQ DX,R8 + ADDQ CX,R8 + SHLQ $13,R10,R11 + ANDQ DX,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ DX,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ DX,R14 + ADDQ R13,R14 + IMUL3Q $19,R15,CX + ADDQ CX,SI + MOVQ SI,CX + SHRQ $51,CX + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $51,CX + ANDQ DX,SI + ADDQ R10,CX + MOVQ CX,R9 + SHRQ $51,CX + ANDQ DX,R8 + ADDQ R12,CX + MOVQ CX,AX + SHRQ $51,CX + ANDQ DX,R9 + ADDQ R14,CX + MOVQ CX,R10 + SHRQ $51,CX + ANDQ DX,AX + IMUL3Q $19,CX,CX + ADDQ CX,SI + ANDQ DX,R10 + MOVQ SI,80(DI) + MOVQ R8,88(DI) + MOVQ R9,96(DI) + MOVQ AX,104(DI) + MOVQ R10,112(DI) + RET diff --git a/vendor/golang.org/x/crypto/curve25519/mul_amd64.s b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s new file mode 100644 index 00000000..1f76d1a3 --- /dev/null +++ b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s @@ -0,0 +1,169 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +#include "const_amd64.h" + +// func mul(dest, a, b *[5]uint64) +TEXT ·mul(SB),0,$16-24 + MOVQ dest+0(FP), DI + MOVQ a+8(FP), SI + MOVQ b+16(FP), DX + + MOVQ DX,CX + MOVQ 24(SI),DX + IMUL3Q $19,DX,AX + MOVQ AX,0(SP) + MULQ 16(CX) + MOVQ AX,R8 + MOVQ DX,R9 + MOVQ 32(SI),DX + IMUL3Q $19,DX,AX + MOVQ AX,8(SP) + MULQ 8(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SI),AX + MULQ 0(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 0(SI),AX + MULQ 8(CX) + MOVQ AX,R10 + MOVQ DX,R11 + MOVQ 0(SI),AX + MULQ 16(CX) + MOVQ AX,R12 + MOVQ DX,R13 + MOVQ 0(SI),AX + MULQ 24(CX) + MOVQ AX,R14 + MOVQ DX,R15 + MOVQ 0(SI),AX + MULQ 32(CX) + MOVQ AX,BX + MOVQ DX,BP + MOVQ 8(SI),AX + MULQ 0(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SI),AX + MULQ 8(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 8(SI),AX + MULQ 16(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 8(SI),AX + MULQ 24(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 8(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 16(SI),AX + MULQ 0(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 16(SI),AX + MULQ 8(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 16(SI),AX + MULQ 16(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 16(SI),DX + IMUL3Q $19,DX,AX + MULQ 24(CX) + ADDQ AX,R8 + ADCQ DX,R9 + MOVQ 16(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 24(SI),AX + MULQ 0(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ 24(SI),AX + MULQ 8(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 0(SP),AX + MULQ 24(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 0(SP),AX + MULQ 32(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 32(SI),AX + MULQ 0(CX) + ADDQ AX,BX + ADCQ DX,BP + MOVQ 8(SP),AX + MULQ 16(CX) + ADDQ AX,R10 + ADCQ DX,R11 + MOVQ 8(SP),AX + MULQ 24(CX) + ADDQ AX,R12 + ADCQ DX,R13 + MOVQ 8(SP),AX + MULQ 32(CX) + ADDQ AX,R14 + ADCQ DX,R15 + MOVQ $REDMASK51,SI + SHLQ $13,R8,R9 + ANDQ SI,R8 + SHLQ $13,R10,R11 + ANDQ SI,R10 + ADDQ R9,R10 + SHLQ $13,R12,R13 + ANDQ SI,R12 + ADDQ R11,R12 + SHLQ $13,R14,R15 + ANDQ SI,R14 + ADDQ R13,R14 + SHLQ $13,BX,BP + ANDQ SI,BX + ADDQ R15,BX + IMUL3Q $19,BP,DX + ADDQ DX,R8 + MOVQ R8,DX + SHRQ $51,DX + ADDQ R10,DX + MOVQ DX,CX + SHRQ $51,DX + ANDQ SI,R8 + ADDQ R12,DX + MOVQ DX,R9 + SHRQ $51,DX + ANDQ SI,CX + ADDQ R14,DX + MOVQ DX,AX + SHRQ $51,DX + ANDQ SI,R9 + ADDQ BX,DX + MOVQ DX,R10 + SHRQ $51,DX + ANDQ SI,AX + IMUL3Q $19,DX,DX + ADDQ DX,R8 + ANDQ SI,R10 + MOVQ R8,0(DI) + MOVQ CX,8(DI) + MOVQ R9,16(DI) + MOVQ AX,24(DI) + MOVQ R10,32(DI) + RET diff --git a/vendor/golang.org/x/crypto/curve25519/square_amd64.s b/vendor/golang.org/x/crypto/curve25519/square_amd64.s new file mode 100644 index 00000000..07511a45 --- /dev/null +++ b/vendor/golang.org/x/crypto/curve25519/square_amd64.s @@ -0,0 +1,132 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html + +// +build amd64,!gccgo,!appengine + +#include "const_amd64.h" + +// func square(out, in *[5]uint64) +TEXT ·square(SB),7,$0-16 + MOVQ out+0(FP), DI + MOVQ in+8(FP), SI + + MOVQ 0(SI),AX + MULQ 0(SI) + MOVQ AX,CX + MOVQ DX,R8 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 8(SI) + MOVQ AX,R9 + MOVQ DX,R10 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 16(SI) + MOVQ AX,R11 + MOVQ DX,R12 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 24(SI) + MOVQ AX,R13 + MOVQ DX,R14 + MOVQ 0(SI),AX + SHLQ $1,AX + MULQ 32(SI) + MOVQ AX,R15 + MOVQ DX,BX + MOVQ 8(SI),AX + MULQ 8(SI) + ADDQ AX,R11 + ADCQ DX,R12 + MOVQ 8(SI),AX + SHLQ $1,AX + MULQ 16(SI) + ADDQ AX,R13 + ADCQ DX,R14 + MOVQ 8(SI),AX + SHLQ $1,AX + MULQ 24(SI) + ADDQ AX,R15 + ADCQ DX,BX + MOVQ 8(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,CX + ADCQ DX,R8 + MOVQ 16(SI),AX + MULQ 16(SI) + ADDQ AX,R15 + ADCQ DX,BX + MOVQ 16(SI),DX + IMUL3Q $38,DX,AX + MULQ 24(SI) + ADDQ AX,CX + ADCQ DX,R8 + MOVQ 16(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,R9 + ADCQ DX,R10 + MOVQ 24(SI),DX + IMUL3Q $19,DX,AX + MULQ 24(SI) + ADDQ AX,R9 + ADCQ DX,R10 + MOVQ 24(SI),DX + IMUL3Q $38,DX,AX + MULQ 32(SI) + ADDQ AX,R11 + ADCQ DX,R12 + MOVQ 32(SI),DX + IMUL3Q $19,DX,AX + MULQ 32(SI) + ADDQ AX,R13 + ADCQ DX,R14 + MOVQ $REDMASK51,SI + SHLQ $13,CX,R8 + ANDQ SI,CX + SHLQ $13,R9,R10 + ANDQ SI,R9 + ADDQ R8,R9 + SHLQ $13,R11,R12 + ANDQ SI,R11 + ADDQ R10,R11 + SHLQ $13,R13,R14 + ANDQ SI,R13 + ADDQ R12,R13 + SHLQ $13,R15,BX + ANDQ SI,R15 + ADDQ R14,R15 + IMUL3Q $19,BX,DX + ADDQ DX,CX + MOVQ CX,DX + SHRQ $51,DX + ADDQ R9,DX + ANDQ SI,CX + MOVQ DX,R8 + SHRQ $51,DX + ADDQ R11,DX + ANDQ SI,R8 + MOVQ DX,R9 + SHRQ $51,DX + ADDQ R13,DX + ANDQ SI,R9 + MOVQ DX,AX + SHRQ $51,DX + ADDQ R15,DX + ANDQ SI,AX + MOVQ DX,R10 + SHRQ $51,DX + IMUL3Q $19,DX,DX + ADDQ DX,CX + ANDQ SI,R10 + MOVQ CX,0(DI) + MOVQ R8,8(DI) + MOVQ R9,16(DI) + MOVQ AX,24(DI) + MOVQ R10,32(DI) + RET diff --git a/vendor/golang.org/x/crypto/internal/chacha20/asm_arm64.s b/vendor/golang.org/x/crypto/internal/chacha20/asm_arm64.s new file mode 100644 index 00000000..b3a16ef7 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/asm_arm64.s @@ -0,0 +1,308 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 +// +build !gccgo,!appengine + +#include "textflag.h" + +#define NUM_ROUNDS 10 + +// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) +TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 + MOVD dst+0(FP), R1 + MOVD src+24(FP), R2 + MOVD src_len+32(FP), R3 + MOVD key+48(FP), R4 + MOVD nonce+56(FP), R6 + MOVD counter+64(FP), R7 + + MOVD $·constants(SB), R10 + MOVD $·incRotMatrix(SB), R11 + + MOVW (R7), R20 + + AND $~255, R3, R13 + ADD R2, R13, R12 // R12 for block end + AND $255, R3, R13 +loop: + MOVD $NUM_ROUNDS, R21 + VLD1 (R11), [V30.S4, V31.S4] + + // load contants + // VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4] + WORD $0x4D60E940 + + // load keys + // VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4] + WORD $0x4DFFE884 + // VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4] + WORD $0x4DFFE888 + SUB $32, R4 + + // load counter + nonce + // VLD1R (R7), [V12.S4] + WORD $0x4D40C8EC + + // VLD3R (R6), [V13.S4, V14.S4, V15.S4] + WORD $0x4D40E8CD + + // update counter + VADD V30.S4, V12.S4, V12.S4 + +chacha: + // V0..V3 += V4..V7 + // V12..V15 <<<= ((V12..V15 XOR V0..V3), 16) + VADD V0.S4, V4.S4, V0.S4 + VADD V1.S4, V5.S4, V1.S4 + VADD V2.S4, V6.S4, V2.S4 + VADD V3.S4, V7.S4, V3.S4 + VEOR V12.B16, V0.B16, V12.B16 + VEOR V13.B16, V1.B16, V13.B16 + VEOR V14.B16, V2.B16, V14.B16 + VEOR V15.B16, V3.B16, V15.B16 + VREV32 V12.H8, V12.H8 + VREV32 V13.H8, V13.H8 + VREV32 V14.H8, V14.H8 + VREV32 V15.H8, V15.H8 + // V8..V11 += V12..V15 + // V4..V7 <<<= ((V4..V7 XOR V8..V11), 12) + VADD V8.S4, V12.S4, V8.S4 + VADD V9.S4, V13.S4, V9.S4 + VADD V10.S4, V14.S4, V10.S4 + VADD V11.S4, V15.S4, V11.S4 + VEOR V8.B16, V4.B16, V16.B16 + VEOR V9.B16, V5.B16, V17.B16 + VEOR V10.B16, V6.B16, V18.B16 + VEOR V11.B16, V7.B16, V19.B16 + VSHL $12, V16.S4, V4.S4 + VSHL $12, V17.S4, V5.S4 + VSHL $12, V18.S4, V6.S4 + VSHL $12, V19.S4, V7.S4 + VSRI $20, V16.S4, V4.S4 + VSRI $20, V17.S4, V5.S4 + VSRI $20, V18.S4, V6.S4 + VSRI $20, V19.S4, V7.S4 + + // V0..V3 += V4..V7 + // V12..V15 <<<= ((V12..V15 XOR V0..V3), 8) + VADD V0.S4, V4.S4, V0.S4 + VADD V1.S4, V5.S4, V1.S4 + VADD V2.S4, V6.S4, V2.S4 + VADD V3.S4, V7.S4, V3.S4 + VEOR V12.B16, V0.B16, V12.B16 + VEOR V13.B16, V1.B16, V13.B16 + VEOR V14.B16, V2.B16, V14.B16 + VEOR V15.B16, V3.B16, V15.B16 + VTBL V31.B16, [V12.B16], V12.B16 + VTBL V31.B16, [V13.B16], V13.B16 + VTBL V31.B16, [V14.B16], V14.B16 + VTBL V31.B16, [V15.B16], V15.B16 + + // V8..V11 += V12..V15 + // V4..V7 <<<= ((V4..V7 XOR V8..V11), 7) + VADD V12.S4, V8.S4, V8.S4 + VADD V13.S4, V9.S4, V9.S4 + VADD V14.S4, V10.S4, V10.S4 + VADD V15.S4, V11.S4, V11.S4 + VEOR V8.B16, V4.B16, V16.B16 + VEOR V9.B16, V5.B16, V17.B16 + VEOR V10.B16, V6.B16, V18.B16 + VEOR V11.B16, V7.B16, V19.B16 + VSHL $7, V16.S4, V4.S4 + VSHL $7, V17.S4, V5.S4 + VSHL $7, V18.S4, V6.S4 + VSHL $7, V19.S4, V7.S4 + VSRI $25, V16.S4, V4.S4 + VSRI $25, V17.S4, V5.S4 + VSRI $25, V18.S4, V6.S4 + VSRI $25, V19.S4, V7.S4 + + // V0..V3 += V5..V7, V4 + // V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16) + VADD V0.S4, V5.S4, V0.S4 + VADD V1.S4, V6.S4, V1.S4 + VADD V2.S4, V7.S4, V2.S4 + VADD V3.S4, V4.S4, V3.S4 + VEOR V15.B16, V0.B16, V15.B16 + VEOR V12.B16, V1.B16, V12.B16 + VEOR V13.B16, V2.B16, V13.B16 + VEOR V14.B16, V3.B16, V14.B16 + VREV32 V12.H8, V12.H8 + VREV32 V13.H8, V13.H8 + VREV32 V14.H8, V14.H8 + VREV32 V15.H8, V15.H8 + + // V10 += V15; V5 <<<= ((V10 XOR V5), 12) + // ... + VADD V15.S4, V10.S4, V10.S4 + VADD V12.S4, V11.S4, V11.S4 + VADD V13.S4, V8.S4, V8.S4 + VADD V14.S4, V9.S4, V9.S4 + VEOR V10.B16, V5.B16, V16.B16 + VEOR V11.B16, V6.B16, V17.B16 + VEOR V8.B16, V7.B16, V18.B16 + VEOR V9.B16, V4.B16, V19.B16 + VSHL $12, V16.S4, V5.S4 + VSHL $12, V17.S4, V6.S4 + VSHL $12, V18.S4, V7.S4 + VSHL $12, V19.S4, V4.S4 + VSRI $20, V16.S4, V5.S4 + VSRI $20, V17.S4, V6.S4 + VSRI $20, V18.S4, V7.S4 + VSRI $20, V19.S4, V4.S4 + + // V0 += V5; V15 <<<= ((V0 XOR V15), 8) + // ... + VADD V5.S4, V0.S4, V0.S4 + VADD V6.S4, V1.S4, V1.S4 + VADD V7.S4, V2.S4, V2.S4 + VADD V4.S4, V3.S4, V3.S4 + VEOR V0.B16, V15.B16, V15.B16 + VEOR V1.B16, V12.B16, V12.B16 + VEOR V2.B16, V13.B16, V13.B16 + VEOR V3.B16, V14.B16, V14.B16 + VTBL V31.B16, [V12.B16], V12.B16 + VTBL V31.B16, [V13.B16], V13.B16 + VTBL V31.B16, [V14.B16], V14.B16 + VTBL V31.B16, [V15.B16], V15.B16 + + // V10 += V15; V5 <<<= ((V10 XOR V5), 7) + // ... + VADD V15.S4, V10.S4, V10.S4 + VADD V12.S4, V11.S4, V11.S4 + VADD V13.S4, V8.S4, V8.S4 + VADD V14.S4, V9.S4, V9.S4 + VEOR V10.B16, V5.B16, V16.B16 + VEOR V11.B16, V6.B16, V17.B16 + VEOR V8.B16, V7.B16, V18.B16 + VEOR V9.B16, V4.B16, V19.B16 + VSHL $7, V16.S4, V5.S4 + VSHL $7, V17.S4, V6.S4 + VSHL $7, V18.S4, V7.S4 + VSHL $7, V19.S4, V4.S4 + VSRI $25, V16.S4, V5.S4 + VSRI $25, V17.S4, V6.S4 + VSRI $25, V18.S4, V7.S4 + VSRI $25, V19.S4, V4.S4 + + SUB $1, R21 + CBNZ R21, chacha + + // VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4] + WORD $0x4D60E950 + + // VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4] + WORD $0x4DFFE894 + VADD V30.S4, V12.S4, V12.S4 + VADD V16.S4, V0.S4, V0.S4 + VADD V17.S4, V1.S4, V1.S4 + VADD V18.S4, V2.S4, V2.S4 + VADD V19.S4, V3.S4, V3.S4 + // VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4] + WORD $0x4DFFE898 + // restore R4 + SUB $32, R4 + + // load counter + nonce + // VLD1R (R7), [V28.S4] + WORD $0x4D40C8FC + // VLD3R (R6), [V29.S4, V30.S4, V31.S4] + WORD $0x4D40E8DD + + VADD V20.S4, V4.S4, V4.S4 + VADD V21.S4, V5.S4, V5.S4 + VADD V22.S4, V6.S4, V6.S4 + VADD V23.S4, V7.S4, V7.S4 + VADD V24.S4, V8.S4, V8.S4 + VADD V25.S4, V9.S4, V9.S4 + VADD V26.S4, V10.S4, V10.S4 + VADD V27.S4, V11.S4, V11.S4 + VADD V28.S4, V12.S4, V12.S4 + VADD V29.S4, V13.S4, V13.S4 + VADD V30.S4, V14.S4, V14.S4 + VADD V31.S4, V15.S4, V15.S4 + + VZIP1 V1.S4, V0.S4, V16.S4 + VZIP2 V1.S4, V0.S4, V17.S4 + VZIP1 V3.S4, V2.S4, V18.S4 + VZIP2 V3.S4, V2.S4, V19.S4 + VZIP1 V5.S4, V4.S4, V20.S4 + VZIP2 V5.S4, V4.S4, V21.S4 + VZIP1 V7.S4, V6.S4, V22.S4 + VZIP2 V7.S4, V6.S4, V23.S4 + VZIP1 V9.S4, V8.S4, V24.S4 + VZIP2 V9.S4, V8.S4, V25.S4 + VZIP1 V11.S4, V10.S4, V26.S4 + VZIP2 V11.S4, V10.S4, V27.S4 + VZIP1 V13.S4, V12.S4, V28.S4 + VZIP2 V13.S4, V12.S4, V29.S4 + VZIP1 V15.S4, V14.S4, V30.S4 + VZIP2 V15.S4, V14.S4, V31.S4 + VZIP1 V18.D2, V16.D2, V0.D2 + VZIP2 V18.D2, V16.D2, V4.D2 + VZIP1 V19.D2, V17.D2, V8.D2 + VZIP2 V19.D2, V17.D2, V12.D2 + VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16] + + VZIP1 V22.D2, V20.D2, V1.D2 + VZIP2 V22.D2, V20.D2, V5.D2 + VZIP1 V23.D2, V21.D2, V9.D2 + VZIP2 V23.D2, V21.D2, V13.D2 + VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16] + VZIP1 V26.D2, V24.D2, V2.D2 + VZIP2 V26.D2, V24.D2, V6.D2 + VZIP1 V27.D2, V25.D2, V10.D2 + VZIP2 V27.D2, V25.D2, V14.D2 + VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16] + VZIP1 V30.D2, V28.D2, V3.D2 + VZIP2 V30.D2, V28.D2, V7.D2 + VZIP1 V31.D2, V29.D2, V11.D2 + VZIP2 V31.D2, V29.D2, V15.D2 + VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16] + VEOR V0.B16, V16.B16, V16.B16 + VEOR V1.B16, V17.B16, V17.B16 + VEOR V2.B16, V18.B16, V18.B16 + VEOR V3.B16, V19.B16, V19.B16 + VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1) + VEOR V4.B16, V20.B16, V20.B16 + VEOR V5.B16, V21.B16, V21.B16 + VEOR V6.B16, V22.B16, V22.B16 + VEOR V7.B16, V23.B16, V23.B16 + VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1) + VEOR V8.B16, V24.B16, V24.B16 + VEOR V9.B16, V25.B16, V25.B16 + VEOR V10.B16, V26.B16, V26.B16 + VEOR V11.B16, V27.B16, V27.B16 + VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1) + VEOR V12.B16, V28.B16, V28.B16 + VEOR V13.B16, V29.B16, V29.B16 + VEOR V14.B16, V30.B16, V30.B16 + VEOR V15.B16, V31.B16, V31.B16 + VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1) + + ADD $4, R20 + MOVW R20, (R7) // update counter + + CMP R2, R12 + BGT loop + + RET + + +DATA ·constants+0x00(SB)/4, $0x61707865 +DATA ·constants+0x04(SB)/4, $0x3320646e +DATA ·constants+0x08(SB)/4, $0x79622d32 +DATA ·constants+0x0c(SB)/4, $0x6b206574 +GLOBL ·constants(SB), NOPTR|RODATA, $32 + +DATA ·incRotMatrix+0x00(SB)/4, $0x00000000 +DATA ·incRotMatrix+0x04(SB)/4, $0x00000001 +DATA ·incRotMatrix+0x08(SB)/4, $0x00000002 +DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003 +DATA ·incRotMatrix+0x10(SB)/4, $0x02010003 +DATA ·incRotMatrix+0x14(SB)/4, $0x06050407 +DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B +DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F +GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32 diff --git a/vendor/golang.org/x/crypto/internal/chacha20/asm_ppc64le.s b/vendor/golang.org/x/crypto/internal/chacha20/asm_ppc64le.s new file mode 100644 index 00000000..cde3fc98 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/asm_ppc64le.s @@ -0,0 +1,668 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Based on CRYPTOGAMS code with the following comment: +// # ==================================================================== +// # Written by Andy Polyakov for the OpenSSL +// # project. The module is, however, dual licensed under OpenSSL and +// # CRYPTOGAMS licenses depending on where you obtain it. For further +// # details see http://www.openssl.org/~appro/cryptogams/. +// # ==================================================================== + +// Original code can be found at the link below: +// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91e5c39ca79126a4a876d5d8ff + +// There are some differences between CRYPTOGAMS code and this one. The round +// loop for "_int" isn't the same as the original. Some adjustments were +// necessary because there are less vector registers available. For example, some +// X variables (r12, r13, r14, and r15) share the same register used by the +// counter. The original code uses ctr to name the counter. Here we use CNT +// because golang uses CTR as the counter register name. + +// +build ppc64le,!gccgo,!appengine + +#include "textflag.h" + +#define OUT R3 +#define INP R4 +#define LEN R5 +#define KEY R6 +#define CNT R7 + +#define TEMP R8 + +#define X0 R11 +#define X1 R12 +#define X2 R14 +#define X3 R15 +#define X4 R16 +#define X5 R17 +#define X6 R18 +#define X7 R19 +#define X8 R20 +#define X9 R21 +#define X10 R22 +#define X11 R23 +#define X12 R24 +#define X13 R25 +#define X14 R26 +#define X15 R27 + +#define CON0 X0 +#define CON1 X1 +#define CON2 X2 +#define CON3 X3 + +#define KEY0 X4 +#define KEY1 X5 +#define KEY2 X6 +#define KEY3 X7 +#define KEY4 X8 +#define KEY5 X9 +#define KEY6 X10 +#define KEY7 X11 + +#define CNT0 X12 +#define CNT1 X13 +#define CNT2 X14 +#define CNT3 X15 + +#define TMP0 R9 +#define TMP1 R10 +#define TMP2 R28 +#define TMP3 R29 + +#define CONSTS R8 + +#define A0 V0 +#define B0 V1 +#define C0 V2 +#define D0 V3 +#define A1 V4 +#define B1 V5 +#define C1 V6 +#define D1 V7 +#define A2 V8 +#define B2 V9 +#define C2 V10 +#define D2 V11 +#define T0 V12 +#define T1 V13 +#define T2 V14 + +#define K0 V15 +#define K1 V16 +#define K2 V17 +#define K3 V18 +#define K4 V19 +#define K5 V20 + +#define FOUR V21 +#define SIXTEEN V22 +#define TWENTY4 V23 +#define TWENTY V24 +#define TWELVE V25 +#define TWENTY5 V26 +#define SEVEN V27 + +#define INPPERM V28 +#define OUTPERM V29 +#define OUTMASK V30 + +#define DD0 V31 +#define DD1 SEVEN +#define DD2 T0 +#define DD3 T1 +#define DD4 T2 + +DATA ·consts+0x00(SB)/8, $0x3320646e61707865 +DATA ·consts+0x08(SB)/8, $0x6b20657479622d32 +DATA ·consts+0x10(SB)/8, $0x0000000000000001 +DATA ·consts+0x18(SB)/8, $0x0000000000000000 +DATA ·consts+0x20(SB)/8, $0x0000000000000004 +DATA ·consts+0x28(SB)/8, $0x0000000000000000 +DATA ·consts+0x30(SB)/8, $0x0a0b08090e0f0c0d +DATA ·consts+0x38(SB)/8, $0x0203000106070405 +DATA ·consts+0x40(SB)/8, $0x090a0b080d0e0f0c +DATA ·consts+0x48(SB)/8, $0x0102030005060704 +GLOBL ·consts(SB), RODATA, $80 + +//func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[32]byte, counter *[16]byte) +TEXT ·chaCha20_ctr32_vmx(SB),NOSPLIT|NOFRAME,$0 + // Load the arguments inside the registers + MOVD out+0(FP), OUT + MOVD inp+8(FP), INP + MOVD len+16(FP), LEN + MOVD key+24(FP), KEY + MOVD counter+32(FP), CNT + + MOVD $·consts(SB), CONSTS // point to consts addr + + MOVD $16, X0 + MOVD $32, X1 + MOVD $48, X2 + MOVD $64, X3 + MOVD $31, X4 + MOVD $15, X5 + + // Load key + LVX (KEY)(R0), K1 + LVSR (KEY)(R0), T0 + LVX (KEY)(X0), K2 + LVX (KEY)(X4), DD0 + + // Load counter + LVX (CNT)(R0), K3 + LVSR (CNT)(R0), T1 + LVX (CNT)(X5), DD1 + + // Load constants + LVX (CONSTS)(R0), K0 + LVX (CONSTS)(X0), K5 + LVX (CONSTS)(X1), FOUR + LVX (CONSTS)(X2), SIXTEEN + LVX (CONSTS)(X3), TWENTY4 + + // Align key and counter + VPERM K2, K1, T0, K1 + VPERM DD0, K2, T0, K2 + VPERM DD1, K3, T1, K3 + + // Load counter to GPR + MOVWZ 0(CNT), CNT0 + MOVWZ 4(CNT), CNT1 + MOVWZ 8(CNT), CNT2 + MOVWZ 12(CNT), CNT3 + + // Adjust vectors for the initial state + VADDUWM K3, K5, K3 + VADDUWM K3, K5, K4 + VADDUWM K4, K5, K5 + + // Synthesized constants + VSPLTISW $-12, TWENTY + VSPLTISW $12, TWELVE + VSPLTISW $-7, TWENTY5 + + VXOR T0, T0, T0 + VSPLTISW $-1, OUTMASK + LVSR (INP)(R0), INPPERM + LVSL (OUT)(R0), OUTPERM + VPERM OUTMASK, T0, OUTPERM, OUTMASK + +loop_outer_vmx: + // Load constant + MOVD $0x61707865, CON0 + MOVD $0x3320646e, CON1 + MOVD $0x79622d32, CON2 + MOVD $0x6b206574, CON3 + + VOR K0, K0, A0 + VOR K0, K0, A1 + VOR K0, K0, A2 + VOR K1, K1, B0 + + MOVD $10, TEMP + + // Load key to GPR + MOVWZ 0(KEY), X4 + MOVWZ 4(KEY), X5 + MOVWZ 8(KEY), X6 + MOVWZ 12(KEY), X7 + VOR K1, K1, B1 + VOR K1, K1, B2 + MOVWZ 16(KEY), X8 + MOVWZ 0(CNT), X12 + MOVWZ 20(KEY), X9 + MOVWZ 4(CNT), X13 + VOR K2, K2, C0 + VOR K2, K2, C1 + MOVWZ 24(KEY), X10 + MOVWZ 8(CNT), X14 + VOR K2, K2, C2 + VOR K3, K3, D0 + MOVWZ 28(KEY), X11 + MOVWZ 12(CNT), X15 + VOR K4, K4, D1 + VOR K5, K5, D2 + + MOVD X4, TMP0 + MOVD X5, TMP1 + MOVD X6, TMP2 + MOVD X7, TMP3 + VSPLTISW $7, SEVEN + + MOVD TEMP, CTR + +loop_vmx: + // CRYPTOGAMS uses a macro to create a loop using perl. This isn't possible + // using assembly macros. Therefore, the macro expansion result was used + // in order to maintain the algorithm efficiency. + // This loop generates three keystream blocks using VMX instructions and, + // in parallel, one keystream block using scalar instructions. + ADD X4, X0, X0 + ADD X5, X1, X1 + VADDUWM A0, B0, A0 + VADDUWM A1, B1, A1 + ADD X6, X2, X2 + ADD X7, X3, X3 + VADDUWM A2, B2, A2 + VXOR D0, A0, D0 + XOR X0, X12, X12 + XOR X1, X13, X13 + VXOR D1, A1, D1 + VXOR D2, A2, D2 + XOR X2, X14, X14 + XOR X3, X15, X15 + VPERM D0, D0, SIXTEEN, D0 + VPERM D1, D1, SIXTEEN, D1 + ROTLW $16, X12, X12 + ROTLW $16, X13, X13 + VPERM D2, D2, SIXTEEN, D2 + VADDUWM C0, D0, C0 + ROTLW $16, X14, X14 + ROTLW $16, X15, X15 + VADDUWM C1, D1, C1 + VADDUWM C2, D2, C2 + ADD X12, X8, X8 + ADD X13, X9, X9 + VXOR B0, C0, T0 + VXOR B1, C1, T1 + ADD X14, X10, X10 + ADD X15, X11, X11 + VXOR B2, C2, T2 + VRLW T0, TWELVE, B0 + XOR X8, X4, X4 + XOR X9, X5, X5 + VRLW T1, TWELVE, B1 + VRLW T2, TWELVE, B2 + XOR X10, X6, X6 + XOR X11, X7, X7 + VADDUWM A0, B0, A0 + VADDUWM A1, B1, A1 + ROTLW $12, X4, X4 + ROTLW $12, X5, X5 + VADDUWM A2, B2, A2 + VXOR D0, A0, D0 + ROTLW $12, X6, X6 + ROTLW $12, X7, X7 + VXOR D1, A1, D1 + VXOR D2, A2, D2 + ADD X4, X0, X0 + ADD X5, X1, X1 + VPERM D0, D0, TWENTY4, D0 + VPERM D1, D1, TWENTY4, D1 + ADD X6, X2, X2 + ADD X7, X3, X3 + VPERM D2, D2, TWENTY4, D2 + VADDUWM C0, D0, C0 + XOR X0, X12, X12 + XOR X1, X13, X13 + VADDUWM C1, D1, C1 + VADDUWM C2, D2, C2 + XOR X2, X14, X14 + XOR X3, X15, X15 + VXOR B0, C0, T0 + VXOR B1, C1, T1 + ROTLW $8, X12, X12 + ROTLW $8, X13, X13 + VXOR B2, C2, T2 + VRLW T0, SEVEN, B0 + ROTLW $8, X14, X14 + ROTLW $8, X15, X15 + VRLW T1, SEVEN, B1 + VRLW T2, SEVEN, B2 + ADD X12, X8, X8 + ADD X13, X9, X9 + VSLDOI $8, C0, C0, C0 + VSLDOI $8, C1, C1, C1 + ADD X14, X10, X10 + ADD X15, X11, X11 + VSLDOI $8, C2, C2, C2 + VSLDOI $12, B0, B0, B0 + XOR X8, X4, X4 + XOR X9, X5, X5 + VSLDOI $12, B1, B1, B1 + VSLDOI $12, B2, B2, B2 + XOR X10, X6, X6 + XOR X11, X7, X7 + VSLDOI $4, D0, D0, D0 + VSLDOI $4, D1, D1, D1 + ROTLW $7, X4, X4 + ROTLW $7, X5, X5 + VSLDOI $4, D2, D2, D2 + VADDUWM A0, B0, A0 + ROTLW $7, X6, X6 + ROTLW $7, X7, X7 + VADDUWM A1, B1, A1 + VADDUWM A2, B2, A2 + ADD X5, X0, X0 + ADD X6, X1, X1 + VXOR D0, A0, D0 + VXOR D1, A1, D1 + ADD X7, X2, X2 + ADD X4, X3, X3 + VXOR D2, A2, D2 + VPERM D0, D0, SIXTEEN, D0 + XOR X0, X15, X15 + XOR X1, X12, X12 + VPERM D1, D1, SIXTEEN, D1 + VPERM D2, D2, SIXTEEN, D2 + XOR X2, X13, X13 + XOR X3, X14, X14 + VADDUWM C0, D0, C0 + VADDUWM C1, D1, C1 + ROTLW $16, X15, X15 + ROTLW $16, X12, X12 + VADDUWM C2, D2, C2 + VXOR B0, C0, T0 + ROTLW $16, X13, X13 + ROTLW $16, X14, X14 + VXOR B1, C1, T1 + VXOR B2, C2, T2 + ADD X15, X10, X10 + ADD X12, X11, X11 + VRLW T0, TWELVE, B0 + VRLW T1, TWELVE, B1 + ADD X13, X8, X8 + ADD X14, X9, X9 + VRLW T2, TWELVE, B2 + VADDUWM A0, B0, A0 + XOR X10, X5, X5 + XOR X11, X6, X6 + VADDUWM A1, B1, A1 + VADDUWM A2, B2, A2 + XOR X8, X7, X7 + XOR X9, X4, X4 + VXOR D0, A0, D0 + VXOR D1, A1, D1 + ROTLW $12, X5, X5 + ROTLW $12, X6, X6 + VXOR D2, A2, D2 + VPERM D0, D0, TWENTY4, D0 + ROTLW $12, X7, X7 + ROTLW $12, X4, X4 + VPERM D1, D1, TWENTY4, D1 + VPERM D2, D2, TWENTY4, D2 + ADD X5, X0, X0 + ADD X6, X1, X1 + VADDUWM C0, D0, C0 + VADDUWM C1, D1, C1 + ADD X7, X2, X2 + ADD X4, X3, X3 + VADDUWM C2, D2, C2 + VXOR B0, C0, T0 + XOR X0, X15, X15 + XOR X1, X12, X12 + VXOR B1, C1, T1 + VXOR B2, C2, T2 + XOR X2, X13, X13 + XOR X3, X14, X14 + VRLW T0, SEVEN, B0 + VRLW T1, SEVEN, B1 + ROTLW $8, X15, X15 + ROTLW $8, X12, X12 + VRLW T2, SEVEN, B2 + VSLDOI $8, C0, C0, C0 + ROTLW $8, X13, X13 + ROTLW $8, X14, X14 + VSLDOI $8, C1, C1, C1 + VSLDOI $8, C2, C2, C2 + ADD X15, X10, X10 + ADD X12, X11, X11 + VSLDOI $4, B0, B0, B0 + VSLDOI $4, B1, B1, B1 + ADD X13, X8, X8 + ADD X14, X9, X9 + VSLDOI $4, B2, B2, B2 + VSLDOI $12, D0, D0, D0 + XOR X10, X5, X5 + XOR X11, X6, X6 + VSLDOI $12, D1, D1, D1 + VSLDOI $12, D2, D2, D2 + XOR X8, X7, X7 + XOR X9, X4, X4 + ROTLW $7, X5, X5 + ROTLW $7, X6, X6 + ROTLW $7, X7, X7 + ROTLW $7, X4, X4 + BC 0x10, 0, loop_vmx + + SUB $256, LEN, LEN + + // Accumulate key block + ADD $0x61707865, X0, X0 + ADD $0x3320646e, X1, X1 + ADD $0x79622d32, X2, X2 + ADD $0x6b206574, X3, X3 + ADD TMP0, X4, X4 + ADD TMP1, X5, X5 + ADD TMP2, X6, X6 + ADD TMP3, X7, X7 + MOVWZ 16(KEY), TMP0 + MOVWZ 20(KEY), TMP1 + MOVWZ 24(KEY), TMP2 + MOVWZ 28(KEY), TMP3 + ADD TMP0, X8, X8 + ADD TMP1, X9, X9 + ADD TMP2, X10, X10 + ADD TMP3, X11, X11 + + MOVWZ 12(CNT), TMP0 + MOVWZ 8(CNT), TMP1 + MOVWZ 4(CNT), TMP2 + MOVWZ 0(CNT), TEMP + ADD TMP0, X15, X15 + ADD TMP1, X14, X14 + ADD TMP2, X13, X13 + ADD TEMP, X12, X12 + + // Accumulate key block + VADDUWM A0, K0, A0 + VADDUWM A1, K0, A1 + VADDUWM A2, K0, A2 + VADDUWM B0, K1, B0 + VADDUWM B1, K1, B1 + VADDUWM B2, K1, B2 + VADDUWM C0, K2, C0 + VADDUWM C1, K2, C1 + VADDUWM C2, K2, C2 + VADDUWM D0, K3, D0 + VADDUWM D1, K4, D1 + VADDUWM D2, K5, D2 + + // Increment counter + ADD $4, TEMP, TEMP + MOVW TEMP, 0(CNT) + + VADDUWM K3, FOUR, K3 + VADDUWM K4, FOUR, K4 + VADDUWM K5, FOUR, K5 + + // XOR the input slice (INP) with the keystream, which is stored in GPRs (X0-X3). + + // Load input (aligned or not) + MOVWZ 0(INP), TMP0 + MOVWZ 4(INP), TMP1 + MOVWZ 8(INP), TMP2 + MOVWZ 12(INP), TMP3 + + // XOR with input + XOR TMP0, X0, X0 + XOR TMP1, X1, X1 + XOR TMP2, X2, X2 + XOR TMP3, X3, X3 + MOVWZ 16(INP), TMP0 + MOVWZ 20(INP), TMP1 + MOVWZ 24(INP), TMP2 + MOVWZ 28(INP), TMP3 + XOR TMP0, X4, X4 + XOR TMP1, X5, X5 + XOR TMP2, X6, X6 + XOR TMP3, X7, X7 + MOVWZ 32(INP), TMP0 + MOVWZ 36(INP), TMP1 + MOVWZ 40(INP), TMP2 + MOVWZ 44(INP), TMP3 + XOR TMP0, X8, X8 + XOR TMP1, X9, X9 + XOR TMP2, X10, X10 + XOR TMP3, X11, X11 + MOVWZ 48(INP), TMP0 + MOVWZ 52(INP), TMP1 + MOVWZ 56(INP), TMP2 + MOVWZ 60(INP), TMP3 + XOR TMP0, X12, X12 + XOR TMP1, X13, X13 + XOR TMP2, X14, X14 + XOR TMP3, X15, X15 + + // Store output (aligned or not) + MOVW X0, 0(OUT) + MOVW X1, 4(OUT) + MOVW X2, 8(OUT) + MOVW X3, 12(OUT) + + ADD $64, INP, INP // INP points to the end of the slice for the alignment code below + + MOVW X4, 16(OUT) + MOVD $16, TMP0 + MOVW X5, 20(OUT) + MOVD $32, TMP1 + MOVW X6, 24(OUT) + MOVD $48, TMP2 + MOVW X7, 28(OUT) + MOVD $64, TMP3 + MOVW X8, 32(OUT) + MOVW X9, 36(OUT) + MOVW X10, 40(OUT) + MOVW X11, 44(OUT) + MOVW X12, 48(OUT) + MOVW X13, 52(OUT) + MOVW X14, 56(OUT) + MOVW X15, 60(OUT) + ADD $64, OUT, OUT + + // Load input + LVX (INP)(R0), DD0 + LVX (INP)(TMP0), DD1 + LVX (INP)(TMP1), DD2 + LVX (INP)(TMP2), DD3 + LVX (INP)(TMP3), DD4 + ADD $64, INP, INP + + VPERM DD1, DD0, INPPERM, DD0 // Align input + VPERM DD2, DD1, INPPERM, DD1 + VPERM DD3, DD2, INPPERM, DD2 + VPERM DD4, DD3, INPPERM, DD3 + VXOR A0, DD0, A0 // XOR with input + VXOR B0, DD1, B0 + LVX (INP)(TMP0), DD1 // Keep loading input + VXOR C0, DD2, C0 + LVX (INP)(TMP1), DD2 + VXOR D0, DD3, D0 + LVX (INP)(TMP2), DD3 + LVX (INP)(TMP3), DD0 + ADD $64, INP, INP + MOVD $63, TMP3 // 63 is not a typo + VPERM A0, A0, OUTPERM, A0 + VPERM B0, B0, OUTPERM, B0 + VPERM C0, C0, OUTPERM, C0 + VPERM D0, D0, OUTPERM, D0 + + VPERM DD1, DD4, INPPERM, DD4 // Align input + VPERM DD2, DD1, INPPERM, DD1 + VPERM DD3, DD2, INPPERM, DD2 + VPERM DD0, DD3, INPPERM, DD3 + VXOR A1, DD4, A1 + VXOR B1, DD1, B1 + LVX (INP)(TMP0), DD1 // Keep loading + VXOR C1, DD2, C1 + LVX (INP)(TMP1), DD2 + VXOR D1, DD3, D1 + LVX (INP)(TMP2), DD3 + + // Note that the LVX address is always rounded down to the nearest 16-byte + // boundary, and that it always points to at most 15 bytes beyond the end of + // the slice, so we cannot cross a page boundary. + LVX (INP)(TMP3), DD4 // Redundant in aligned case. + ADD $64, INP, INP + VPERM A1, A1, OUTPERM, A1 // Pre-misalign output + VPERM B1, B1, OUTPERM, B1 + VPERM C1, C1, OUTPERM, C1 + VPERM D1, D1, OUTPERM, D1 + + VPERM DD1, DD0, INPPERM, DD0 // Align Input + VPERM DD2, DD1, INPPERM, DD1 + VPERM DD3, DD2, INPPERM, DD2 + VPERM DD4, DD3, INPPERM, DD3 + VXOR A2, DD0, A2 + VXOR B2, DD1, B2 + VXOR C2, DD2, C2 + VXOR D2, DD3, D2 + VPERM A2, A2, OUTPERM, A2 + VPERM B2, B2, OUTPERM, B2 + VPERM C2, C2, OUTPERM, C2 + VPERM D2, D2, OUTPERM, D2 + + ANDCC $15, OUT, X1 // Is out aligned? + MOVD OUT, X0 + + VSEL A0, B0, OUTMASK, DD0 // Collect pre-misaligned output + VSEL B0, C0, OUTMASK, DD1 + VSEL C0, D0, OUTMASK, DD2 + VSEL D0, A1, OUTMASK, DD3 + VSEL A1, B1, OUTMASK, B0 + VSEL B1, C1, OUTMASK, C0 + VSEL C1, D1, OUTMASK, D0 + VSEL D1, A2, OUTMASK, A1 + VSEL A2, B2, OUTMASK, B1 + VSEL B2, C2, OUTMASK, C1 + VSEL C2, D2, OUTMASK, D1 + + STVX DD0, (OUT+TMP0) + STVX DD1, (OUT+TMP1) + STVX DD2, (OUT+TMP2) + ADD $64, OUT, OUT + STVX DD3, (OUT+R0) + STVX B0, (OUT+TMP0) + STVX C0, (OUT+TMP1) + STVX D0, (OUT+TMP2) + ADD $64, OUT, OUT + STVX A1, (OUT+R0) + STVX B1, (OUT+TMP0) + STVX C1, (OUT+TMP1) + STVX D1, (OUT+TMP2) + ADD $64, OUT, OUT + + BEQ aligned_vmx + + SUB X1, OUT, X2 // in misaligned case edges + MOVD $0, X3 // are written byte-by-byte + +unaligned_tail_vmx: + STVEBX D2, (X2+X3) + ADD $1, X3, X3 + CMPW X3, X1 + BNE unaligned_tail_vmx + SUB X1, X0, X2 + +unaligned_head_vmx: + STVEBX A0, (X2+X1) + CMPW X1, $15 + ADD $1, X1, X1 + BNE unaligned_head_vmx + + CMPU LEN, $255 // done with 256-byte block yet? + BGT loop_outer_vmx + + JMP done_vmx + +aligned_vmx: + STVX A0, (X0+R0) + CMPU LEN, $255 // done with 256-byte block yet? + BGT loop_outer_vmx + +done_vmx: + RET diff --git a/vendor/golang.org/x/crypto/internal/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/internal/chacha20/chacha_arm64.go new file mode 100644 index 00000000..ad74e23a --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/chacha_arm64.go @@ -0,0 +1,31 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 +// +build !gccgo + +package chacha20 + +const ( + haveAsm = true + bufSize = 256 +) + +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { + + if len(src) >= bufSize { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) + } + + if len(src)%bufSize != 0 { + i := len(src) - len(src)%bufSize + c.buf = [bufSize]byte{} + copy(c.buf[:], src[i:]) + xorKeyStreamVX(c.buf[:], c.buf[:], &c.key, &c.nonce, &c.counter) + c.len = bufSize - copy(dst[i:], c.buf[:len(src)%bufSize]) + } +} diff --git a/vendor/golang.org/x/crypto/internal/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/internal/chacha20/chacha_noasm.go new file mode 100644 index 00000000..bf8beba6 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/chacha_noasm.go @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !ppc64le,!arm64,!s390x arm64,!go1.11 gccgo appengine + +package chacha20 + +const ( + bufSize = 64 + haveAsm = false +) + +func (*Cipher) xorKeyStreamAsm(dst, src []byte) { + panic("not implemented") +} diff --git a/vendor/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go new file mode 100644 index 00000000..638cb5e5 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go @@ -0,0 +1,52 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ppc64le,!gccgo,!appengine + +package chacha20 + +import "encoding/binary" + +const ( + bufSize = 256 + haveAsm = true +) + +//go:noescape +func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[8]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { + if len(src) >= bufSize { + chaCha20_ctr32_vmx(&dst[0], &src[0], len(src)-len(src)%bufSize, &c.key, &c.counter) + } + if len(src)%bufSize != 0 { + chaCha20_ctr32_vmx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter) + start := len(src) - len(src)%bufSize + ts, td, tb := src[start:], dst[start:], c.buf[:] + // Unroll loop to XOR 32 bytes per iteration. + for i := 0; i < len(ts)-32; i += 32 { + td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination + s0 := binary.LittleEndian.Uint64(ts[0:8]) + s1 := binary.LittleEndian.Uint64(ts[8:16]) + s2 := binary.LittleEndian.Uint64(ts[16:24]) + s3 := binary.LittleEndian.Uint64(ts[24:32]) + b0 := binary.LittleEndian.Uint64(tb[0:8]) + b1 := binary.LittleEndian.Uint64(tb[8:16]) + b2 := binary.LittleEndian.Uint64(tb[16:24]) + b3 := binary.LittleEndian.Uint64(tb[24:32]) + binary.LittleEndian.PutUint64(td[0:8], s0^b0) + binary.LittleEndian.PutUint64(td[8:16], s1^b1) + binary.LittleEndian.PutUint64(td[16:24], s2^b2) + binary.LittleEndian.PutUint64(td[24:32], s3^b3) + ts, td, tb = ts[32:], td[32:], tb[32:] + } + td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination + for i, v := range ts { + td[i] = tb[i] ^ v + } + c.len = bufSize - (len(src) % bufSize) + + } + +} diff --git a/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go new file mode 100644 index 00000000..aad645b4 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,!gccgo,!appengine + +package chacha20 + +import ( + "golang.org/x/sys/cpu" +) + +var haveAsm = cpu.S390X.HasVX + +const bufSize = 256 + +// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only +// be called when the vector facility is available. +// Implementation in asm_s390x.s. +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int) + +func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter, &c.buf, &c.len) +} + +// EXRL targets, DO NOT CALL! +func mvcSrcToBuf() +func mvcBufToDst() diff --git a/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.s b/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.s new file mode 100644 index 00000000..57df4044 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.s @@ -0,0 +1,260 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,!gccgo,!appengine + +#include "go_asm.h" +#include "textflag.h" + +// This is an implementation of the ChaCha20 encryption algorithm as +// specified in RFC 7539. It uses vector instructions to compute +// 4 keystream blocks in parallel (256 bytes) which are then XORed +// with the bytes in the input slice. + +GLOBL ·constants<>(SB), RODATA|NOPTR, $32 +// BSWAP: swap bytes in each 4-byte element +DATA ·constants<>+0x00(SB)/4, $0x03020100 +DATA ·constants<>+0x04(SB)/4, $0x07060504 +DATA ·constants<>+0x08(SB)/4, $0x0b0a0908 +DATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c +// J0: [j0, j1, j2, j3] +DATA ·constants<>+0x10(SB)/4, $0x61707865 +DATA ·constants<>+0x14(SB)/4, $0x3320646e +DATA ·constants<>+0x18(SB)/4, $0x79622d32 +DATA ·constants<>+0x1c(SB)/4, $0x6b206574 + +// EXRL targets: +TEXT ·mvcSrcToBuf(SB), NOFRAME|NOSPLIT, $0 + MVC $1, (R1), (R8) + RET + +TEXT ·mvcBufToDst(SB), NOFRAME|NOSPLIT, $0 + MVC $1, (R8), (R9) + RET + +#define BSWAP V5 +#define J0 V6 +#define KEY0 V7 +#define KEY1 V8 +#define NONCE V9 +#define CTR V10 +#define M0 V11 +#define M1 V12 +#define M2 V13 +#define M3 V14 +#define INC V15 +#define X0 V16 +#define X1 V17 +#define X2 V18 +#define X3 V19 +#define X4 V20 +#define X5 V21 +#define X6 V22 +#define X7 V23 +#define X8 V24 +#define X9 V25 +#define X10 V26 +#define X11 V27 +#define X12 V28 +#define X13 V29 +#define X14 V30 +#define X15 V31 + +#define NUM_ROUNDS 20 + +#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \ + VAF a1, a0, a0 \ + VAF b1, b0, b0 \ + VAF c1, c0, c0 \ + VAF d1, d0, d0 \ + VX a0, a2, a2 \ + VX b0, b2, b2 \ + VX c0, c2, c2 \ + VX d0, d2, d2 \ + VERLLF $16, a2, a2 \ + VERLLF $16, b2, b2 \ + VERLLF $16, c2, c2 \ + VERLLF $16, d2, d2 \ + VAF a2, a3, a3 \ + VAF b2, b3, b3 \ + VAF c2, c3, c3 \ + VAF d2, d3, d3 \ + VX a3, a1, a1 \ + VX b3, b1, b1 \ + VX c3, c1, c1 \ + VX d3, d1, d1 \ + VERLLF $12, a1, a1 \ + VERLLF $12, b1, b1 \ + VERLLF $12, c1, c1 \ + VERLLF $12, d1, d1 \ + VAF a1, a0, a0 \ + VAF b1, b0, b0 \ + VAF c1, c0, c0 \ + VAF d1, d0, d0 \ + VX a0, a2, a2 \ + VX b0, b2, b2 \ + VX c0, c2, c2 \ + VX d0, d2, d2 \ + VERLLF $8, a2, a2 \ + VERLLF $8, b2, b2 \ + VERLLF $8, c2, c2 \ + VERLLF $8, d2, d2 \ + VAF a2, a3, a3 \ + VAF b2, b3, b3 \ + VAF c2, c3, c3 \ + VAF d2, d3, d3 \ + VX a3, a1, a1 \ + VX b3, b1, b1 \ + VX c3, c1, c1 \ + VX d3, d1, d1 \ + VERLLF $7, a1, a1 \ + VERLLF $7, b1, b1 \ + VERLLF $7, c1, c1 \ + VERLLF $7, d1, d1 + +#define PERMUTE(mask, v0, v1, v2, v3) \ + VPERM v0, v0, mask, v0 \ + VPERM v1, v1, mask, v1 \ + VPERM v2, v2, mask, v2 \ + VPERM v3, v3, mask, v3 + +#define ADDV(x, v0, v1, v2, v3) \ + VAF x, v0, v0 \ + VAF x, v1, v1 \ + VAF x, v2, v2 \ + VAF x, v3, v3 + +#define XORV(off, dst, src, v0, v1, v2, v3) \ + VLM off(src), M0, M3 \ + PERMUTE(BSWAP, v0, v1, v2, v3) \ + VX v0, M0, M0 \ + VX v1, M1, M1 \ + VX v2, M2, M2 \ + VX v3, M3, M3 \ + VSTM M0, M3, off(dst) + +#define SHUFFLE(a, b, c, d, t, u, v, w) \ + VMRHF a, c, t \ // t = {a[0], c[0], a[1], c[1]} + VMRHF b, d, u \ // u = {b[0], d[0], b[1], d[1]} + VMRLF a, c, v \ // v = {a[2], c[2], a[3], c[3]} + VMRLF b, d, w \ // w = {b[2], d[2], b[3], d[3]} + VMRHF t, u, a \ // a = {a[0], b[0], c[0], d[0]} + VMRLF t, u, b \ // b = {a[1], b[1], c[1], d[1]} + VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]} + VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]} + +// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int) +TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 + MOVD $·constants<>(SB), R1 + MOVD dst+0(FP), R2 // R2=&dst[0] + LMG src+24(FP), R3, R4 // R3=&src[0] R4=len(src) + MOVD key+48(FP), R5 // R5=key + MOVD nonce+56(FP), R6 // R6=nonce + MOVD counter+64(FP), R7 // R7=counter + MOVD buf+72(FP), R8 // R8=buf + MOVD len+80(FP), R9 // R9=len + + // load BSWAP and J0 + VLM (R1), BSWAP, J0 + + // set up tail buffer + ADD $-1, R4, R12 + MOVBZ R12, R12 + CMPUBEQ R12, $255, aligned + MOVD R4, R1 + AND $~255, R1 + MOVD $(R3)(R1*1), R1 + EXRL $·mvcSrcToBuf(SB), R12 + MOVD $255, R0 + SUB R12, R0 + MOVD R0, (R9) // update len + +aligned: + // setup + MOVD $95, R0 + VLM (R5), KEY0, KEY1 + VLL R0, (R6), NONCE + VZERO M0 + VLEIB $7, $32, M0 + VSRLB M0, NONCE, NONCE + + // initialize counter values + VLREPF (R7), CTR + VZERO INC + VLEIF $1, $1, INC + VLEIF $2, $2, INC + VLEIF $3, $3, INC + VAF INC, CTR, CTR + VREPIF $4, INC + +chacha: + VREPF $0, J0, X0 + VREPF $1, J0, X1 + VREPF $2, J0, X2 + VREPF $3, J0, X3 + VREPF $0, KEY0, X4 + VREPF $1, KEY0, X5 + VREPF $2, KEY0, X6 + VREPF $3, KEY0, X7 + VREPF $0, KEY1, X8 + VREPF $1, KEY1, X9 + VREPF $2, KEY1, X10 + VREPF $3, KEY1, X11 + VLR CTR, X12 + VREPF $1, NONCE, X13 + VREPF $2, NONCE, X14 + VREPF $3, NONCE, X15 + + MOVD $(NUM_ROUNDS/2), R1 + +loop: + ROUND4(X0, X4, X12, X8, X1, X5, X13, X9, X2, X6, X14, X10, X3, X7, X15, X11) + ROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8, X3, X4, X14, X9) + + ADD $-1, R1 + BNE loop + + // decrement length + ADD $-256, R4 + BLT tail + +continue: + // rearrange vectors + SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3) + ADDV(J0, X0, X1, X2, X3) + SHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3) + ADDV(KEY0, X4, X5, X6, X7) + SHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3) + ADDV(KEY1, X8, X9, X10, X11) + VAF CTR, X12, X12 + SHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3) + ADDV(NONCE, X12, X13, X14, X15) + + // increment counters + VAF INC, CTR, CTR + + // xor keystream with plaintext + XORV(0*64, R2, R3, X0, X4, X8, X12) + XORV(1*64, R2, R3, X1, X5, X9, X13) + XORV(2*64, R2, R3, X2, X6, X10, X14) + XORV(3*64, R2, R3, X3, X7, X11, X15) + + // increment pointers + MOVD $256(R2), R2 + MOVD $256(R3), R3 + + CMPBNE R4, $0, chacha + CMPUBEQ R12, $255, return + EXRL $·mvcBufToDst(SB), R12 // len was updated during setup + +return: + VSTEF $0, CTR, (R7) + RET + +tail: + MOVD R2, R9 + MOVD R8, R2 + MOVD R8, R3 + MOVD $0, R4 + JMP continue diff --git a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go new file mode 100644 index 00000000..a8dd589a --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !amd64,!ppc64le gccgo appengine + +package poly1305 + +type mac struct{ macGeneric } + +func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} } diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305.go b/vendor/golang.org/x/crypto/poly1305/poly1305.go new file mode 100644 index 00000000..d076a562 --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/poly1305.go @@ -0,0 +1,83 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package poly1305 implements Poly1305 one-time message authentication code as +// specified in https://cr.yp.to/mac/poly1305-20050329.pdf. +// +// Poly1305 is a fast, one-time authentication function. It is infeasible for an +// attacker to generate an authenticator for a message without the key. However, a +// key must only be used for a single message. Authenticating two different +// messages with the same key allows an attacker to forge authenticators for other +// messages with the same key. +// +// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was +// used with a fixed key in order to generate one-time keys from an nonce. +// However, in this package AES isn't used and the one-time key is specified +// directly. +package poly1305 // import "golang.org/x/crypto/poly1305" + +import "crypto/subtle" + +// TagSize is the size, in bytes, of a poly1305 authenticator. +const TagSize = 16 + +// Verify returns true if mac is a valid authenticator for m with the given +// key. +func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { + var tmp [16]byte + Sum(&tmp, m, key) + return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 +} + +// New returns a new MAC computing an authentication +// tag of all data written to it with the given key. +// This allows writing the message progressively instead +// of passing it as a single slice. Common users should use +// the Sum function instead. +// +// The key must be unique for each message, as authenticating +// two different messages with the same key allows an attacker +// to forge messages at will. +func New(key *[32]byte) *MAC { + return &MAC{ + mac: newMAC(key), + finalized: false, + } +} + +// MAC is an io.Writer computing an authentication tag +// of the data written to it. +// +// MAC cannot be used like common hash.Hash implementations, +// because using a poly1305 key twice breaks its security. +// Therefore writing data to a running MAC after calling +// Sum causes it to panic. +type MAC struct { + mac // platform-dependent implementation + + finalized bool +} + +// Size returns the number of bytes Sum will return. +func (h *MAC) Size() int { return TagSize } + +// Write adds more data to the running message authentication code. +// It never returns an error. +// +// It must not be called after the first call of Sum. +func (h *MAC) Write(p []byte) (n int, err error) { + if h.finalized { + panic("poly1305: write to MAC after Sum") + } + return h.mac.Write(p) +} + +// Sum computes the authenticator of all data written to the +// message authentication code. +func (h *MAC) Sum(b []byte) []byte { + var mac [TagSize]byte + h.mac.Sum(&mac) + h.finalized = true + return append(b, mac[:]...) +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go new file mode 100644 index 00000000..2dbf42aa --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go @@ -0,0 +1,68 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine + +package poly1305 + +//go:noescape +func initialize(state *[7]uint64, key *[32]byte) + +//go:noescape +func update(state *[7]uint64, msg []byte) + +//go:noescape +func finalize(tag *[TagSize]byte, state *[7]uint64) + +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + h := newMAC(key) + h.Write(m) + h.Sum(out) +} + +func newMAC(key *[32]byte) (h mac) { + initialize(&h.state, key) + return +} + +type mac struct { + state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 } + + buffer [TagSize]byte + offset int +} + +func (h *mac) Write(p []byte) (n int, err error) { + n = len(p) + if h.offset > 0 { + remaining := TagSize - h.offset + if n < remaining { + h.offset += copy(h.buffer[h.offset:], p) + return n, nil + } + copy(h.buffer[h.offset:], p[:remaining]) + p = p[remaining:] + h.offset = 0 + update(&h.state, h.buffer[:]) + } + if nn := len(p) - (len(p) % TagSize); nn > 0 { + update(&h.state, p[:nn]) + p = p[nn:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return n, nil +} + +func (h *mac) Sum(out *[16]byte) { + state := h.state + if h.offset > 0 { + update(&state, h.buffer[:h.offset]) + } + finalize(out, &state) +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s new file mode 100644 index 00000000..7d600f13 --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s @@ -0,0 +1,148 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine + +#include "textflag.h" + +#define POLY1305_ADD(msg, h0, h1, h2) \ + ADDQ 0(msg), h0; \ + ADCQ 8(msg), h1; \ + ADCQ $1, h2; \ + LEAQ 16(msg), msg + +#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \ + MOVQ r0, AX; \ + MULQ h0; \ + MOVQ AX, t0; \ + MOVQ DX, t1; \ + MOVQ r0, AX; \ + MULQ h1; \ + ADDQ AX, t1; \ + ADCQ $0, DX; \ + MOVQ r0, t2; \ + IMULQ h2, t2; \ + ADDQ DX, t2; \ + \ + MOVQ r1, AX; \ + MULQ h0; \ + ADDQ AX, t1; \ + ADCQ $0, DX; \ + MOVQ DX, h0; \ + MOVQ r1, t3; \ + IMULQ h2, t3; \ + MOVQ r1, AX; \ + MULQ h1; \ + ADDQ AX, t2; \ + ADCQ DX, t3; \ + ADDQ h0, t2; \ + ADCQ $0, t3; \ + \ + MOVQ t0, h0; \ + MOVQ t1, h1; \ + MOVQ t2, h2; \ + ANDQ $3, h2; \ + MOVQ t2, t0; \ + ANDQ $0xFFFFFFFFFFFFFFFC, t0; \ + ADDQ t0, h0; \ + ADCQ t3, h1; \ + ADCQ $0, h2; \ + SHRQ $2, t3, t2; \ + SHRQ $2, t3; \ + ADDQ t2, h0; \ + ADCQ t3, h1; \ + ADCQ $0, h2 + +DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF +DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC +GLOBL ·poly1305Mask<>(SB), RODATA, $16 + +// func update(state *[7]uint64, msg []byte) +TEXT ·update(SB), $0-32 + MOVQ state+0(FP), DI + MOVQ msg_base+8(FP), SI + MOVQ msg_len+16(FP), R15 + + MOVQ 0(DI), R8 // h0 + MOVQ 8(DI), R9 // h1 + MOVQ 16(DI), R10 // h2 + MOVQ 24(DI), R11 // r0 + MOVQ 32(DI), R12 // r1 + + CMPQ R15, $16 + JB bytes_between_0_and_15 + +loop: + POLY1305_ADD(SI, R8, R9, R10) + +multiply: + POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14) + SUBQ $16, R15 + CMPQ R15, $16 + JAE loop + +bytes_between_0_and_15: + TESTQ R15, R15 + JZ done + MOVQ $1, BX + XORQ CX, CX + XORQ R13, R13 + ADDQ R15, SI + +flush_buffer: + SHLQ $8, BX, CX + SHLQ $8, BX + MOVB -1(SI), R13 + XORQ R13, BX + DECQ SI + DECQ R15 + JNZ flush_buffer + + ADDQ BX, R8 + ADCQ CX, R9 + ADCQ $0, R10 + MOVQ $16, R15 + JMP multiply + +done: + MOVQ R8, 0(DI) + MOVQ R9, 8(DI) + MOVQ R10, 16(DI) + RET + +// func initialize(state *[7]uint64, key *[32]byte) +TEXT ·initialize(SB), $0-16 + MOVQ state+0(FP), DI + MOVQ key+8(FP), SI + + // state[0...7] is initialized with zero + MOVOU 0(SI), X0 + MOVOU 16(SI), X1 + MOVOU ·poly1305Mask<>(SB), X2 + PAND X2, X0 + MOVOU X0, 24(DI) + MOVOU X1, 40(DI) + RET + +// func finalize(tag *[TagSize]byte, state *[7]uint64) +TEXT ·finalize(SB), $0-16 + MOVQ tag+0(FP), DI + MOVQ state+8(FP), SI + + MOVQ 0(SI), AX + MOVQ 8(SI), BX + MOVQ 16(SI), CX + MOVQ AX, R8 + MOVQ BX, R9 + SUBQ $0xFFFFFFFFFFFFFFFB, AX + SBBQ $0xFFFFFFFFFFFFFFFF, BX + SBBQ $3, CX + CMOVQCS R8, AX + CMOVQCS R9, BX + ADDQ 40(SI), AX + ADCQ 48(SI), BX + + MOVQ AX, 0(DI) + MOVQ BX, 8(DI) + RET diff --git a/vendor/golang.org/x/crypto/poly1305/sum_generic.go b/vendor/golang.org/x/crypto/poly1305/sum_generic.go new file mode 100644 index 00000000..bab76ef0 --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_generic.go @@ -0,0 +1,172 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package poly1305 + +import "encoding/binary" + +const ( + msgBlock = uint32(1 << 24) + finalBlock = uint32(0) +) + +// sumGeneric generates an authenticator for msg using a one-time key and +// puts the 16-byte result into out. This is the generic implementation of +// Sum and should be called if no assembly implementation is available. +func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) { + h := newMACGeneric(key) + h.Write(msg) + h.Sum(out) +} + +func newMACGeneric(key *[32]byte) (h macGeneric) { + h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff + h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03 + h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff + h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff + h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff + + h.s[0] = binary.LittleEndian.Uint32(key[16:]) + h.s[1] = binary.LittleEndian.Uint32(key[20:]) + h.s[2] = binary.LittleEndian.Uint32(key[24:]) + h.s[3] = binary.LittleEndian.Uint32(key[28:]) + return +} + +type macGeneric struct { + h, r [5]uint32 + s [4]uint32 + + buffer [TagSize]byte + offset int +} + +func (h *macGeneric) Write(p []byte) (n int, err error) { + n = len(p) + if h.offset > 0 { + remaining := TagSize - h.offset + if n < remaining { + h.offset += copy(h.buffer[h.offset:], p) + return n, nil + } + copy(h.buffer[h.offset:], p[:remaining]) + p = p[remaining:] + h.offset = 0 + updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r)) + } + if nn := len(p) - (len(p) % TagSize); nn > 0 { + updateGeneric(p, msgBlock, &(h.h), &(h.r)) + p = p[nn:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return n, nil +} + +func (h *macGeneric) Sum(out *[16]byte) { + H, R := h.h, h.r + if h.offset > 0 { + var buffer [TagSize]byte + copy(buffer[:], h.buffer[:h.offset]) + buffer[h.offset] = 1 // invariant: h.offset < TagSize + updateGeneric(buffer[:], finalBlock, &H, &R) + } + finalizeGeneric(out, &H, &(h.s)) +} + +func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) { + h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] + r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) + R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5 + + for len(msg) >= TagSize { + // h += msg + h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff + h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff + h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff + h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff + h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag + + // h *= r + d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1) + d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2) + d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3) + d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4) + d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) + + // h %= p + h0 = uint32(d0) & 0x3ffffff + h1 = uint32(d1) & 0x3ffffff + h2 = uint32(d2) & 0x3ffffff + h3 = uint32(d3) & 0x3ffffff + h4 = uint32(d4) & 0x3ffffff + + h0 += uint32(d4>>26) * 5 + h1 += h0 >> 26 + h0 = h0 & 0x3ffffff + + msg = msg[TagSize:] + } + + h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 +} + +func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) { + h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] + + // h %= p reduction + h2 += h1 >> 26 + h1 &= 0x3ffffff + h3 += h2 >> 26 + h2 &= 0x3ffffff + h4 += h3 >> 26 + h3 &= 0x3ffffff + h0 += 5 * (h4 >> 26) + h4 &= 0x3ffffff + h1 += h0 >> 26 + h0 &= 0x3ffffff + + // h - p + t0 := h0 + 5 + t1 := h1 + (t0 >> 26) + t2 := h2 + (t1 >> 26) + t3 := h3 + (t2 >> 26) + t4 := h4 + (t3 >> 26) - (1 << 26) + t0 &= 0x3ffffff + t1 &= 0x3ffffff + t2 &= 0x3ffffff + t3 &= 0x3ffffff + + // select h if h < p else h - p + t_mask := (t4 >> 31) - 1 + h_mask := ^t_mask + h0 = (h0 & h_mask) | (t0 & t_mask) + h1 = (h1 & h_mask) | (t1 & t_mask) + h2 = (h2 & h_mask) | (t2 & t_mask) + h3 = (h3 & h_mask) | (t3 & t_mask) + h4 = (h4 & h_mask) | (t4 & t_mask) + + // h %= 2^128 + h0 |= h1 << 26 + h1 = ((h1 >> 6) | (h2 << 20)) + h2 = ((h2 >> 12) | (h3 << 14)) + h3 = ((h3 >> 18) | (h4 << 8)) + + // s: the s part of the key + // tag = (h + s) % (2^128) + t := uint64(h0) + uint64(s[0]) + h0 = uint32(t) + t = uint64(h1) + uint64(s[1]) + (t >> 32) + h1 = uint32(t) + t = uint64(h2) + uint64(s[2]) + (t >> 32) + h2 = uint32(t) + t = uint64(h3) + uint64(s[3]) + (t >> 32) + h3 = uint32(t) + + binary.LittleEndian.PutUint32(out[0:], h0) + binary.LittleEndian.PutUint32(out[4:], h1) + binary.LittleEndian.PutUint32(out[8:], h2) + binary.LittleEndian.PutUint32(out[12:], h3) +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_noasm.go b/vendor/golang.org/x/crypto/poly1305/sum_noasm.go new file mode 100644 index 00000000..8a9c2070 --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_noasm.go @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,!go1.11 !arm,!amd64,!s390x,!ppc64le gccgo appengine nacl + +package poly1305 + +// Sum generates an authenticator for msg using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) { + h := newMAC(key) + h.Write(msg) + h.Sum(out) +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go new file mode 100644 index 00000000..2402b637 --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go @@ -0,0 +1,68 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ppc64le,!gccgo,!appengine + +package poly1305 + +//go:noescape +func initialize(state *[7]uint64, key *[32]byte) + +//go:noescape +func update(state *[7]uint64, msg []byte) + +//go:noescape +func finalize(tag *[TagSize]byte, state *[7]uint64) + +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + h := newMAC(key) + h.Write(m) + h.Sum(out) +} + +func newMAC(key *[32]byte) (h mac) { + initialize(&h.state, key) + return +} + +type mac struct { + state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 } + + buffer [TagSize]byte + offset int +} + +func (h *mac) Write(p []byte) (n int, err error) { + n = len(p) + if h.offset > 0 { + remaining := TagSize - h.offset + if n < remaining { + h.offset += copy(h.buffer[h.offset:], p) + return n, nil + } + copy(h.buffer[h.offset:], p[:remaining]) + p = p[remaining:] + h.offset = 0 + update(&h.state, h.buffer[:]) + } + if nn := len(p) - (len(p) % TagSize); nn > 0 { + update(&h.state, p[:nn]) + p = p[nn:] + } + if len(p) > 0 { + h.offset += copy(h.buffer[h.offset:], p) + } + return n, nil +} + +func (h *mac) Sum(out *[16]byte) { + state := h.state + if h.offset > 0 { + update(&state, h.buffer[:h.offset]) + } + finalize(out, &state) +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s new file mode 100644 index 00000000..55c7167e --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s @@ -0,0 +1,247 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ppc64le,!gccgo,!appengine + +#include "textflag.h" + +// This was ported from the amd64 implementation. + +#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \ + MOVD (msg), t0; \ + MOVD 8(msg), t1; \ + MOVD $1, t2; \ + ADDC t0, h0, h0; \ + ADDE t1, h1, h1; \ + ADDE t2, h2; \ + ADD $16, msg + +#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ + MULLD r0, h0, t0; \ + MULLD r0, h1, t4; \ + MULHDU r0, h0, t1; \ + MULHDU r0, h1, t5; \ + ADDC t4, t1, t1; \ + MULLD r0, h2, t2; \ + ADDZE t5; \ + MULHDU r1, h0, t4; \ + MULLD r1, h0, h0; \ + ADD t5, t2, t2; \ + ADDC h0, t1, t1; \ + MULLD h2, r1, t3; \ + ADDZE t4, h0; \ + MULHDU r1, h1, t5; \ + MULLD r1, h1, t4; \ + ADDC t4, t2, t2; \ + ADDE t5, t3, t3; \ + ADDC h0, t2, t2; \ + MOVD $-4, t4; \ + MOVD t0, h0; \ + MOVD t1, h1; \ + ADDZE t3; \ + ANDCC $3, t2, h2; \ + AND t2, t4, t0; \ + ADDC t0, h0, h0; \ + ADDE t3, h1, h1; \ + SLD $62, t3, t4; \ + SRD $2, t2; \ + ADDZE h2; \ + OR t4, t2, t2; \ + SRD $2, t3; \ + ADDC t2, h0, h0; \ + ADDE t3, h1, h1; \ + ADDZE h2 + +DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF +DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC +GLOBL ·poly1305Mask<>(SB), RODATA, $16 + +// func update(state *[7]uint64, msg []byte) + +TEXT ·update(SB), $0-32 + MOVD state+0(FP), R3 + MOVD msg_base+8(FP), R4 + MOVD msg_len+16(FP), R5 + + MOVD 0(R3), R8 // h0 + MOVD 8(R3), R9 // h1 + MOVD 16(R3), R10 // h2 + MOVD 24(R3), R11 // r0 + MOVD 32(R3), R12 // r1 + + CMP R5, $16 + BLT bytes_between_0_and_15 + +loop: + POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) + +multiply: + POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) + ADD $-16, R5 + CMP R5, $16 + BGE loop + +bytes_between_0_and_15: + CMP $0, R5 + BEQ done + MOVD $0, R16 // h0 + MOVD $0, R17 // h1 + +flush_buffer: + CMP R5, $8 + BLE just1 + + MOVD $8, R21 + SUB R21, R5, R21 + + // Greater than 8 -- load the rightmost remaining bytes in msg + // and put into R17 (h1) + MOVD (R4)(R21), R17 + MOVD $16, R22 + + // Find the offset to those bytes + SUB R5, R22, R22 + SLD $3, R22 + + // Shift to get only the bytes in msg + SRD R22, R17, R17 + + // Put 1 at high end + MOVD $1, R23 + SLD $3, R21 + SLD R21, R23, R23 + OR R23, R17, R17 + + // Remainder is 8 + MOVD $8, R5 + +just1: + CMP R5, $8 + BLT less8 + + // Exactly 8 + MOVD (R4), R16 + + CMP $0, R17 + + // Check if we've already set R17; if not + // set 1 to indicate end of msg. + BNE carry + MOVD $1, R17 + BR carry + +less8: + MOVD $0, R16 // h0 + MOVD $0, R22 // shift count + CMP R5, $4 + BLT less4 + MOVWZ (R4), R16 + ADD $4, R4 + ADD $-4, R5 + MOVD $32, R22 + +less4: + CMP R5, $2 + BLT less2 + MOVHZ (R4), R21 + SLD R22, R21, R21 + OR R16, R21, R16 + ADD $16, R22 + ADD $-2, R5 + ADD $2, R4 + +less2: + CMP $0, R5 + BEQ insert1 + MOVBZ (R4), R21 + SLD R22, R21, R21 + OR R16, R21, R16 + ADD $8, R22 + +insert1: + // Insert 1 at end of msg + MOVD $1, R21 + SLD R22, R21, R21 + OR R16, R21, R16 + +carry: + // Add new values to h0, h1, h2 + ADDC R16, R8 + ADDE R17, R9 + ADDE $0, R10 + MOVD $16, R5 + ADD R5, R4 + BR multiply + +done: + // Save h0, h1, h2 in state + MOVD R8, 0(R3) + MOVD R9, 8(R3) + MOVD R10, 16(R3) + RET + +// func initialize(state *[7]uint64, key *[32]byte) +TEXT ·initialize(SB), $0-16 + MOVD state+0(FP), R3 + MOVD key+8(FP), R4 + + // state[0...7] is initialized with zero + // Load key + MOVD 0(R4), R5 + MOVD 8(R4), R6 + MOVD 16(R4), R7 + MOVD 24(R4), R8 + + // Address of key mask + MOVD $·poly1305Mask<>(SB), R9 + + // Save original key in state + MOVD R7, 40(R3) + MOVD R8, 48(R3) + + // Get mask + MOVD (R9), R7 + MOVD 8(R9), R8 + + // And with key + AND R5, R7, R5 + AND R6, R8, R6 + + // Save masked key in state + MOVD R5, 24(R3) + MOVD R6, 32(R3) + RET + +// func finalize(tag *[TagSize]byte, state *[7]uint64) +TEXT ·finalize(SB), $0-16 + MOVD tag+0(FP), R3 + MOVD state+8(FP), R4 + + // Get h0, h1, h2 from state + MOVD 0(R4), R5 + MOVD 8(R4), R6 + MOVD 16(R4), R7 + + // Save h0, h1 + MOVD R5, R8 + MOVD R6, R9 + MOVD $3, R20 + MOVD $-1, R21 + SUBC $-5, R5 + SUBE R21, R6 + SUBE R20, R7 + MOVD $0, R21 + SUBZE R21 + + // Check for carry + CMP $0, R21 + ISEL $2, R5, R8, R5 + ISEL $2, R6, R9, R6 + MOVD 40(R4), R8 + MOVD 48(R4), R9 + ADDC R8, R5 + ADDE R9, R6 + MOVD R5, 0(R3) + MOVD R6, 8(R3) + RET diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go new file mode 100644 index 00000000..ec99e07e --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go @@ -0,0 +1,42 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,go1.11,!gccgo,!appengine + +package poly1305 + +import ( + "golang.org/x/sys/cpu" +) + +// poly1305vx is an assembly implementation of Poly1305 that uses vector +// instructions. It must only be called if the vector facility (vx) is +// available. +//go:noescape +func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]byte) + +// poly1305vmsl is an assembly implementation of Poly1305 that uses vector +// instructions, including VMSL. It must only be called if the vector facility (vx) is +// available and if VMSL is supported. +//go:noescape +func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte) + +// Sum generates an authenticator for m using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + if cpu.S390X.HasVX { + var mPtr *byte + if len(m) > 0 { + mPtr = &m[0] + } + if cpu.S390X.HasVXE && len(m) > 256 { + poly1305vmsl(out, mPtr, uint64(len(m)), key) + } else { + poly1305vx(out, mPtr, uint64(len(m)), key) + } + } else { + sumGeneric(out, m, key) + } +} diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.s b/vendor/golang.org/x/crypto/poly1305/sum_s390x.s new file mode 100644 index 00000000..ca5a309d --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_s390x.s @@ -0,0 +1,378 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,go1.11,!gccgo,!appengine + +#include "textflag.h" + +// Implementation of Poly1305 using the vector facility (vx). + +// constants +#define MOD26 V0 +#define EX0 V1 +#define EX1 V2 +#define EX2 V3 + +// temporaries +#define T_0 V4 +#define T_1 V5 +#define T_2 V6 +#define T_3 V7 +#define T_4 V8 + +// key (r) +#define R_0 V9 +#define R_1 V10 +#define R_2 V11 +#define R_3 V12 +#define R_4 V13 +#define R5_1 V14 +#define R5_2 V15 +#define R5_3 V16 +#define R5_4 V17 +#define RSAVE_0 R5 +#define RSAVE_1 R6 +#define RSAVE_2 R7 +#define RSAVE_3 R8 +#define RSAVE_4 R9 +#define R5SAVE_1 V28 +#define R5SAVE_2 V29 +#define R5SAVE_3 V30 +#define R5SAVE_4 V31 + +// message block +#define F_0 V18 +#define F_1 V19 +#define F_2 V20 +#define F_3 V21 +#define F_4 V22 + +// accumulator +#define H_0 V23 +#define H_1 V24 +#define H_2 V25 +#define H_3 V26 +#define H_4 V27 + +GLOBL ·keyMask<>(SB), RODATA, $16 +DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f +DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f + +GLOBL ·bswapMask<>(SB), RODATA, $16 +DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908 +DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100 + +GLOBL ·constants<>(SB), RODATA, $64 +// MOD26 +DATA ·constants<>+0(SB)/8, $0x3ffffff +DATA ·constants<>+8(SB)/8, $0x3ffffff +// EX0 +DATA ·constants<>+16(SB)/8, $0x0006050403020100 +DATA ·constants<>+24(SB)/8, $0x1016151413121110 +// EX1 +DATA ·constants<>+32(SB)/8, $0x060c0b0a09080706 +DATA ·constants<>+40(SB)/8, $0x161c1b1a19181716 +// EX2 +DATA ·constants<>+48(SB)/8, $0x0d0d0d0d0d0f0e0d +DATA ·constants<>+56(SB)/8, $0x1d1d1d1d1d1f1e1d + +// h = (f*g) % (2**130-5) [partial reduction] +#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \ + VMLOF f0, g0, h0 \ + VMLOF f0, g1, h1 \ + VMLOF f0, g2, h2 \ + VMLOF f0, g3, h3 \ + VMLOF f0, g4, h4 \ + VMLOF f1, g54, T_0 \ + VMLOF f1, g0, T_1 \ + VMLOF f1, g1, T_2 \ + VMLOF f1, g2, T_3 \ + VMLOF f1, g3, T_4 \ + VMALOF f2, g53, h0, h0 \ + VMALOF f2, g54, h1, h1 \ + VMALOF f2, g0, h2, h2 \ + VMALOF f2, g1, h3, h3 \ + VMALOF f2, g2, h4, h4 \ + VMALOF f3, g52, T_0, T_0 \ + VMALOF f3, g53, T_1, T_1 \ + VMALOF f3, g54, T_2, T_2 \ + VMALOF f3, g0, T_3, T_3 \ + VMALOF f3, g1, T_4, T_4 \ + VMALOF f4, g51, h0, h0 \ + VMALOF f4, g52, h1, h1 \ + VMALOF f4, g53, h2, h2 \ + VMALOF f4, g54, h3, h3 \ + VMALOF f4, g0, h4, h4 \ + VAG T_0, h0, h0 \ + VAG T_1, h1, h1 \ + VAG T_2, h2, h2 \ + VAG T_3, h3, h3 \ + VAG T_4, h4, h4 + +// carry h0->h1 h3->h4, h1->h2 h4->h0, h0->h1 h2->h3, h3->h4 +#define REDUCE(h0, h1, h2, h3, h4) \ + VESRLG $26, h0, T_0 \ + VESRLG $26, h3, T_1 \ + VN MOD26, h0, h0 \ + VN MOD26, h3, h3 \ + VAG T_0, h1, h1 \ + VAG T_1, h4, h4 \ + VESRLG $26, h1, T_2 \ + VESRLG $26, h4, T_3 \ + VN MOD26, h1, h1 \ + VN MOD26, h4, h4 \ + VESLG $2, T_3, T_4 \ + VAG T_3, T_4, T_4 \ + VAG T_2, h2, h2 \ + VAG T_4, h0, h0 \ + VESRLG $26, h2, T_0 \ + VESRLG $26, h0, T_1 \ + VN MOD26, h2, h2 \ + VN MOD26, h0, h0 \ + VAG T_0, h3, h3 \ + VAG T_1, h1, h1 \ + VESRLG $26, h3, T_2 \ + VN MOD26, h3, h3 \ + VAG T_2, h4, h4 + +// expand in0 into d[0] and in1 into d[1] +#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \ + VGBM $0x0707, d1 \ // d1=tmp + VPERM in0, in1, EX2, d4 \ + VPERM in0, in1, EX0, d0 \ + VPERM in0, in1, EX1, d2 \ + VN d1, d4, d4 \ + VESRLG $26, d0, d1 \ + VESRLG $30, d2, d3 \ + VESRLG $4, d2, d2 \ + VN MOD26, d0, d0 \ + VN MOD26, d1, d1 \ + VN MOD26, d2, d2 \ + VN MOD26, d3, d3 + +// pack h4:h0 into h1:h0 (no carry) +#define PACK(h0, h1, h2, h3, h4) \ + VESLG $26, h1, h1 \ + VESLG $26, h3, h3 \ + VO h0, h1, h0 \ + VO h2, h3, h2 \ + VESLG $4, h2, h2 \ + VLEIB $7, $48, h1 \ + VSLB h1, h2, h2 \ + VO h0, h2, h0 \ + VLEIB $7, $104, h1 \ + VSLB h1, h4, h3 \ + VO h3, h0, h0 \ + VLEIB $7, $24, h1 \ + VSRLB h1, h4, h1 + +// if h > 2**130-5 then h -= 2**130-5 +#define MOD(h0, h1, t0, t1, t2) \ + VZERO t0 \ + VLEIG $1, $5, t0 \ + VACCQ h0, t0, t1 \ + VAQ h0, t0, t0 \ + VONE t2 \ + VLEIG $1, $-4, t2 \ + VAQ t2, t1, t1 \ + VACCQ h1, t1, t1 \ + VONE t2 \ + VAQ t2, t1, t1 \ + VN h0, t1, t2 \ + VNC t0, t1, t1 \ + VO t1, t2, h0 + +// func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]key) +TEXT ·poly1305vx(SB), $0-32 + // This code processes up to 2 blocks (32 bytes) per iteration + // using the algorithm described in: + // NEON crypto, Daniel J. Bernstein & Peter Schwabe + // https://cryptojedi.org/papers/neoncrypto-20120320.pdf + LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key + + // load MOD26, EX0, EX1 and EX2 + MOVD $·constants<>(SB), R5 + VLM (R5), MOD26, EX2 + + // setup r + VL (R4), T_0 + MOVD $·keyMask<>(SB), R6 + VL (R6), T_1 + VN T_0, T_1, T_0 + EXPAND(T_0, T_0, R_0, R_1, R_2, R_3, R_4) + + // setup r*5 + VLEIG $0, $5, T_0 + VLEIG $1, $5, T_0 + + // store r (for final block) + VMLOF T_0, R_1, R5SAVE_1 + VMLOF T_0, R_2, R5SAVE_2 + VMLOF T_0, R_3, R5SAVE_3 + VMLOF T_0, R_4, R5SAVE_4 + VLGVG $0, R_0, RSAVE_0 + VLGVG $0, R_1, RSAVE_1 + VLGVG $0, R_2, RSAVE_2 + VLGVG $0, R_3, RSAVE_3 + VLGVG $0, R_4, RSAVE_4 + + // skip r**2 calculation + CMPBLE R3, $16, skip + + // calculate r**2 + MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5SAVE_1, R5SAVE_2, R5SAVE_3, R5SAVE_4, H_0, H_1, H_2, H_3, H_4) + REDUCE(H_0, H_1, H_2, H_3, H_4) + VLEIG $0, $5, T_0 + VLEIG $1, $5, T_0 + VMLOF T_0, H_1, R5_1 + VMLOF T_0, H_2, R5_2 + VMLOF T_0, H_3, R5_3 + VMLOF T_0, H_4, R5_4 + VLR H_0, R_0 + VLR H_1, R_1 + VLR H_2, R_2 + VLR H_3, R_3 + VLR H_4, R_4 + + // initialize h + VZERO H_0 + VZERO H_1 + VZERO H_2 + VZERO H_3 + VZERO H_4 + +loop: + CMPBLE R3, $32, b2 + VLM (R2), T_0, T_1 + SUB $32, R3 + MOVD $32(R2), R2 + EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4) + VLEIB $4, $1, F_4 + VLEIB $12, $1, F_4 + +multiply: + VAG H_0, F_0, F_0 + VAG H_1, F_1, F_1 + VAG H_2, F_2, F_2 + VAG H_3, F_3, F_3 + VAG H_4, F_4, F_4 + MULTIPLY(F_0, F_1, F_2, F_3, F_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4) + REDUCE(H_0, H_1, H_2, H_3, H_4) + CMPBNE R3, $0, loop + +finish: + // sum vectors + VZERO T_0 + VSUMQG H_0, T_0, H_0 + VSUMQG H_1, T_0, H_1 + VSUMQG H_2, T_0, H_2 + VSUMQG H_3, T_0, H_3 + VSUMQG H_4, T_0, H_4 + + // h may be >= 2*(2**130-5) so we need to reduce it again + REDUCE(H_0, H_1, H_2, H_3, H_4) + + // carry h1->h4 + VESRLG $26, H_1, T_1 + VN MOD26, H_1, H_1 + VAQ T_1, H_2, H_2 + VESRLG $26, H_2, T_2 + VN MOD26, H_2, H_2 + VAQ T_2, H_3, H_3 + VESRLG $26, H_3, T_3 + VN MOD26, H_3, H_3 + VAQ T_3, H_4, H_4 + + // h is now < 2*(2**130-5) + // pack h into h1 (hi) and h0 (lo) + PACK(H_0, H_1, H_2, H_3, H_4) + + // if h > 2**130-5 then h -= 2**130-5 + MOD(H_0, H_1, T_0, T_1, T_2) + + // h += s + MOVD $·bswapMask<>(SB), R5 + VL (R5), T_1 + VL 16(R4), T_0 + VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big) + VAQ T_0, H_0, H_0 + VPERM H_0, H_0, T_1, H_0 // reverse bytes (to little) + VST H_0, (R1) + + RET + +b2: + CMPBLE R3, $16, b1 + + // 2 blocks remaining + SUB $17, R3 + VL (R2), T_0 + VLL R3, 16(R2), T_1 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, T_1 + EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4) + CMPBNE R3, $16, 2(PC) + VLEIB $12, $1, F_4 + VLEIB $4, $1, F_4 + + // setup [r²,r] + VLVGG $1, RSAVE_0, R_0 + VLVGG $1, RSAVE_1, R_1 + VLVGG $1, RSAVE_2, R_2 + VLVGG $1, RSAVE_3, R_3 + VLVGG $1, RSAVE_4, R_4 + VPDI $0, R5_1, R5SAVE_1, R5_1 + VPDI $0, R5_2, R5SAVE_2, R5_2 + VPDI $0, R5_3, R5SAVE_3, R5_3 + VPDI $0, R5_4, R5SAVE_4, R5_4 + + MOVD $0, R3 + BR multiply + +skip: + VZERO H_0 + VZERO H_1 + VZERO H_2 + VZERO H_3 + VZERO H_4 + + CMPBEQ R3, $0, finish + +b1: + // 1 block remaining + SUB $1, R3 + VLL R3, (R2), T_0 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, T_0 + VZERO T_1 + EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4) + CMPBNE R3, $16, 2(PC) + VLEIB $4, $1, F_4 + VLEIG $1, $1, R_0 + VZERO R_1 + VZERO R_2 + VZERO R_3 + VZERO R_4 + VZERO R5_1 + VZERO R5_2 + VZERO R5_3 + VZERO R5_4 + + // setup [r, 1] + VLVGG $0, RSAVE_0, R_0 + VLVGG $0, RSAVE_1, R_1 + VLVGG $0, RSAVE_2, R_2 + VLVGG $0, RSAVE_3, R_3 + VLVGG $0, RSAVE_4, R_4 + VPDI $0, R5SAVE_1, R5_1, R5_1 + VPDI $0, R5SAVE_2, R5_2, R5_2 + VPDI $0, R5SAVE_3, R5_3, R5_3 + VPDI $0, R5SAVE_4, R5_4, R5_4 + + MOVD $0, R3 + BR multiply diff --git a/vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s b/vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s new file mode 100644 index 00000000..e60bbc1d --- /dev/null +++ b/vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s @@ -0,0 +1,909 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build s390x,go1.11,!gccgo,!appengine + +#include "textflag.h" + +// Implementation of Poly1305 using the vector facility (vx) and the VMSL instruction. + +// constants +#define EX0 V1 +#define EX1 V2 +#define EX2 V3 + +// temporaries +#define T_0 V4 +#define T_1 V5 +#define T_2 V6 +#define T_3 V7 +#define T_4 V8 +#define T_5 V9 +#define T_6 V10 +#define T_7 V11 +#define T_8 V12 +#define T_9 V13 +#define T_10 V14 + +// r**2 & r**4 +#define R_0 V15 +#define R_1 V16 +#define R_2 V17 +#define R5_1 V18 +#define R5_2 V19 +// key (r) +#define RSAVE_0 R7 +#define RSAVE_1 R8 +#define RSAVE_2 R9 +#define R5SAVE_1 R10 +#define R5SAVE_2 R11 + +// message block +#define M0 V20 +#define M1 V21 +#define M2 V22 +#define M3 V23 +#define M4 V24 +#define M5 V25 + +// accumulator +#define H0_0 V26 +#define H1_0 V27 +#define H2_0 V28 +#define H0_1 V29 +#define H1_1 V30 +#define H2_1 V31 + +GLOBL ·keyMask<>(SB), RODATA, $16 +DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f +DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f + +GLOBL ·bswapMask<>(SB), RODATA, $16 +DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908 +DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100 + +GLOBL ·constants<>(SB), RODATA, $48 +// EX0 +DATA ·constants<>+0(SB)/8, $0x18191a1b1c1d1e1f +DATA ·constants<>+8(SB)/8, $0x0000050403020100 +// EX1 +DATA ·constants<>+16(SB)/8, $0x18191a1b1c1d1e1f +DATA ·constants<>+24(SB)/8, $0x00000a0908070605 +// EX2 +DATA ·constants<>+32(SB)/8, $0x18191a1b1c1d1e1f +DATA ·constants<>+40(SB)/8, $0x0000000f0e0d0c0b + +GLOBL ·c<>(SB), RODATA, $48 +// EX0 +DATA ·c<>+0(SB)/8, $0x0000050403020100 +DATA ·c<>+8(SB)/8, $0x0000151413121110 +// EX1 +DATA ·c<>+16(SB)/8, $0x00000a0908070605 +DATA ·c<>+24(SB)/8, $0x00001a1918171615 +// EX2 +DATA ·c<>+32(SB)/8, $0x0000000f0e0d0c0b +DATA ·c<>+40(SB)/8, $0x0000001f1e1d1c1b + +GLOBL ·reduce<>(SB), RODATA, $32 +// 44 bit +DATA ·reduce<>+0(SB)/8, $0x0 +DATA ·reduce<>+8(SB)/8, $0xfffffffffff +// 42 bit +DATA ·reduce<>+16(SB)/8, $0x0 +DATA ·reduce<>+24(SB)/8, $0x3ffffffffff + +// h = (f*g) % (2**130-5) [partial reduction] +// uses T_0...T_9 temporary registers +// input: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2 +// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 +// output: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2 +#define MULTIPLY(m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ + \ // Eliminate the dependency for the last 2 VMSLs + VMSLG m02_0, r_2, m4_2, m4_2 \ + VMSLG m13_0, r_2, m5_2, m5_2 \ // 8 VMSLs pipelined + VMSLG m02_0, r_0, m4_0, m4_0 \ + VMSLG m02_1, r5_2, V0, T_0 \ + VMSLG m02_0, r_1, m4_1, m4_1 \ + VMSLG m02_1, r_0, V0, T_1 \ + VMSLG m02_1, r_1, V0, T_2 \ + VMSLG m02_2, r5_1, V0, T_3 \ + VMSLG m02_2, r5_2, V0, T_4 \ + VMSLG m13_0, r_0, m5_0, m5_0 \ + VMSLG m13_1, r5_2, V0, T_5 \ + VMSLG m13_0, r_1, m5_1, m5_1 \ + VMSLG m13_1, r_0, V0, T_6 \ + VMSLG m13_1, r_1, V0, T_7 \ + VMSLG m13_2, r5_1, V0, T_8 \ + VMSLG m13_2, r5_2, V0, T_9 \ + VMSLG m02_2, r_0, m4_2, m4_2 \ + VMSLG m13_2, r_0, m5_2, m5_2 \ + VAQ m4_0, T_0, m02_0 \ + VAQ m4_1, T_1, m02_1 \ + VAQ m5_0, T_5, m13_0 \ + VAQ m5_1, T_6, m13_1 \ + VAQ m02_0, T_3, m02_0 \ + VAQ m02_1, T_4, m02_1 \ + VAQ m13_0, T_8, m13_0 \ + VAQ m13_1, T_9, m13_1 \ + VAQ m4_2, T_2, m02_2 \ + VAQ m5_2, T_7, m13_2 \ + +// SQUARE uses three limbs of r and r_2*5 to output square of r +// uses T_1, T_5 and T_7 temporary registers +// input: r_0, r_1, r_2, r5_2 +// temp: TEMP0, TEMP1, TEMP2 +// output: p0, p1, p2 +#define SQUARE(r_0, r_1, r_2, r5_2, p0, p1, p2, TEMP0, TEMP1, TEMP2) \ + VMSLG r_0, r_0, p0, p0 \ + VMSLG r_1, r5_2, V0, TEMP0 \ + VMSLG r_2, r5_2, p1, p1 \ + VMSLG r_0, r_1, V0, TEMP1 \ + VMSLG r_1, r_1, p2, p2 \ + VMSLG r_0, r_2, V0, TEMP2 \ + VAQ TEMP0, p0, p0 \ + VAQ TEMP1, p1, p1 \ + VAQ TEMP2, p2, p2 \ + VAQ TEMP0, p0, p0 \ + VAQ TEMP1, p1, p1 \ + VAQ TEMP2, p2, p2 \ + +// carry h0->h1->h2->h0 || h3->h4->h5->h3 +// uses T_2, T_4, T_5, T_7, T_8, T_9 +// t6, t7, t8, t9, t10, t11 +// input: h0, h1, h2, h3, h4, h5 +// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11 +// output: h0, h1, h2, h3, h4, h5 +#define REDUCE(h0, h1, h2, h3, h4, h5, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \ + VLM (R12), t6, t7 \ // 44 and 42 bit clear mask + VLEIB $7, $0x28, t10 \ // 5 byte shift mask + VREPIB $4, t8 \ // 4 bit shift mask + VREPIB $2, t11 \ // 2 bit shift mask + VSRLB t10, h0, t0 \ // h0 byte shift + VSRLB t10, h1, t1 \ // h1 byte shift + VSRLB t10, h2, t2 \ // h2 byte shift + VSRLB t10, h3, t3 \ // h3 byte shift + VSRLB t10, h4, t4 \ // h4 byte shift + VSRLB t10, h5, t5 \ // h5 byte shift + VSRL t8, t0, t0 \ // h0 bit shift + VSRL t8, t1, t1 \ // h2 bit shift + VSRL t11, t2, t2 \ // h2 bit shift + VSRL t8, t3, t3 \ // h3 bit shift + VSRL t8, t4, t4 \ // h4 bit shift + VESLG $2, t2, t9 \ // h2 carry x5 + VSRL t11, t5, t5 \ // h5 bit shift + VN t6, h0, h0 \ // h0 clear carry + VAQ t2, t9, t2 \ // h2 carry x5 + VESLG $2, t5, t9 \ // h5 carry x5 + VN t6, h1, h1 \ // h1 clear carry + VN t7, h2, h2 \ // h2 clear carry + VAQ t5, t9, t5 \ // h5 carry x5 + VN t6, h3, h3 \ // h3 clear carry + VN t6, h4, h4 \ // h4 clear carry + VN t7, h5, h5 \ // h5 clear carry + VAQ t0, h1, h1 \ // h0->h1 + VAQ t3, h4, h4 \ // h3->h4 + VAQ t1, h2, h2 \ // h1->h2 + VAQ t4, h5, h5 \ // h4->h5 + VAQ t2, h0, h0 \ // h2->h0 + VAQ t5, h3, h3 \ // h5->h3 + VREPG $1, t6, t6 \ // 44 and 42 bit masks across both halves + VREPG $1, t7, t7 \ + VSLDB $8, h0, h0, h0 \ // set up [h0/1/2, h3/4/5] + VSLDB $8, h1, h1, h1 \ + VSLDB $8, h2, h2, h2 \ + VO h0, h3, h3 \ + VO h1, h4, h4 \ + VO h2, h5, h5 \ + VESRLG $44, h3, t0 \ // 44 bit shift right + VESRLG $44, h4, t1 \ + VESRLG $42, h5, t2 \ + VN t6, h3, h3 \ // clear carry bits + VN t6, h4, h4 \ + VN t7, h5, h5 \ + VESLG $2, t2, t9 \ // multiply carry by 5 + VAQ t9, t2, t2 \ + VAQ t0, h4, h4 \ + VAQ t1, h5, h5 \ + VAQ t2, h3, h3 \ + +// carry h0->h1->h2->h0 +// input: h0, h1, h2 +// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8 +// output: h0, h1, h2 +#define REDUCE2(h0, h1, h2, t0, t1, t2, t3, t4, t5, t6, t7, t8) \ + VLEIB $7, $0x28, t3 \ // 5 byte shift mask + VREPIB $4, t4 \ // 4 bit shift mask + VREPIB $2, t7 \ // 2 bit shift mask + VGBM $0x003F, t5 \ // mask to clear carry bits + VSRLB t3, h0, t0 \ + VSRLB t3, h1, t1 \ + VSRLB t3, h2, t2 \ + VESRLG $4, t5, t5 \ // 44 bit clear mask + VSRL t4, t0, t0 \ + VSRL t4, t1, t1 \ + VSRL t7, t2, t2 \ + VESRLG $2, t5, t6 \ // 42 bit clear mask + VESLG $2, t2, t8 \ + VAQ t8, t2, t2 \ + VN t5, h0, h0 \ + VN t5, h1, h1 \ + VN t6, h2, h2 \ + VAQ t0, h1, h1 \ + VAQ t1, h2, h2 \ + VAQ t2, h0, h0 \ + VSRLB t3, h0, t0 \ + VSRLB t3, h1, t1 \ + VSRLB t3, h2, t2 \ + VSRL t4, t0, t0 \ + VSRL t4, t1, t1 \ + VSRL t7, t2, t2 \ + VN t5, h0, h0 \ + VN t5, h1, h1 \ + VESLG $2, t2, t8 \ + VN t6, h2, h2 \ + VAQ t0, h1, h1 \ + VAQ t8, t2, t2 \ + VAQ t1, h2, h2 \ + VAQ t2, h0, h0 \ + +// expands two message blocks into the lower halfs of the d registers +// moves the contents of the d registers into upper halfs +// input: in1, in2, d0, d1, d2, d3, d4, d5 +// temp: TEMP0, TEMP1, TEMP2, TEMP3 +// output: d0, d1, d2, d3, d4, d5 +#define EXPACC(in1, in2, d0, d1, d2, d3, d4, d5, TEMP0, TEMP1, TEMP2, TEMP3) \ + VGBM $0xff3f, TEMP0 \ + VGBM $0xff1f, TEMP1 \ + VESLG $4, d1, TEMP2 \ + VESLG $4, d4, TEMP3 \ + VESRLG $4, TEMP0, TEMP0 \ + VPERM in1, d0, EX0, d0 \ + VPERM in2, d3, EX0, d3 \ + VPERM in1, d2, EX2, d2 \ + VPERM in2, d5, EX2, d5 \ + VPERM in1, TEMP2, EX1, d1 \ + VPERM in2, TEMP3, EX1, d4 \ + VN TEMP0, d0, d0 \ + VN TEMP0, d3, d3 \ + VESRLG $4, d1, d1 \ + VESRLG $4, d4, d4 \ + VN TEMP1, d2, d2 \ + VN TEMP1, d5, d5 \ + VN TEMP0, d1, d1 \ + VN TEMP0, d4, d4 \ + +// expands one message block into the lower halfs of the d registers +// moves the contents of the d registers into upper halfs +// input: in, d0, d1, d2 +// temp: TEMP0, TEMP1, TEMP2 +// output: d0, d1, d2 +#define EXPACC2(in, d0, d1, d2, TEMP0, TEMP1, TEMP2) \ + VGBM $0xff3f, TEMP0 \ + VESLG $4, d1, TEMP2 \ + VGBM $0xff1f, TEMP1 \ + VPERM in, d0, EX0, d0 \ + VESRLG $4, TEMP0, TEMP0 \ + VPERM in, d2, EX2, d2 \ + VPERM in, TEMP2, EX1, d1 \ + VN TEMP0, d0, d0 \ + VN TEMP1, d2, d2 \ + VESRLG $4, d1, d1 \ + VN TEMP0, d1, d1 \ + +// pack h2:h0 into h1:h0 (no carry) +// input: h0, h1, h2 +// output: h0, h1, h2 +#define PACK(h0, h1, h2) \ + VMRLG h1, h2, h2 \ // copy h1 to upper half h2 + VESLG $44, h1, h1 \ // shift limb 1 44 bits, leaving 20 + VO h0, h1, h0 \ // combine h0 with 20 bits from limb 1 + VESRLG $20, h2, h1 \ // put top 24 bits of limb 1 into h1 + VLEIG $1, $0, h1 \ // clear h2 stuff from lower half of h1 + VO h0, h1, h0 \ // h0 now has 88 bits (limb 0 and 1) + VLEIG $0, $0, h2 \ // clear upper half of h2 + VESRLG $40, h2, h1 \ // h1 now has upper two bits of result + VLEIB $7, $88, h1 \ // for byte shift (11 bytes) + VSLB h1, h2, h2 \ // shift h2 11 bytes to the left + VO h0, h2, h0 \ // combine h0 with 20 bits from limb 1 + VLEIG $0, $0, h1 \ // clear upper half of h1 + +// if h > 2**130-5 then h -= 2**130-5 +// input: h0, h1 +// temp: t0, t1, t2 +// output: h0 +#define MOD(h0, h1, t0, t1, t2) \ + VZERO t0 \ + VLEIG $1, $5, t0 \ + VACCQ h0, t0, t1 \ + VAQ h0, t0, t0 \ + VONE t2 \ + VLEIG $1, $-4, t2 \ + VAQ t2, t1, t1 \ + VACCQ h1, t1, t1 \ + VONE t2 \ + VAQ t2, t1, t1 \ + VN h0, t1, t2 \ + VNC t0, t1, t1 \ + VO t1, t2, h0 \ + +// func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]key) +TEXT ·poly1305vmsl(SB), $0-32 + // This code processes 6 + up to 4 blocks (32 bytes) per iteration + // using the algorithm described in: + // NEON crypto, Daniel J. Bernstein & Peter Schwabe + // https://cryptojedi.org/papers/neoncrypto-20120320.pdf + // And as moddified for VMSL as described in + // Accelerating Poly1305 Cryptographic Message Authentication on the z14 + // O'Farrell et al, CASCON 2017, p48-55 + // https://ibm.ent.box.com/s/jf9gedj0e9d2vjctfyh186shaztavnht + + LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key + VZERO V0 // c + + // load EX0, EX1 and EX2 + MOVD $·constants<>(SB), R5 + VLM (R5), EX0, EX2 // c + + // setup r + VL (R4), T_0 + MOVD $·keyMask<>(SB), R6 + VL (R6), T_1 + VN T_0, T_1, T_0 + VZERO T_2 // limbs for r + VZERO T_3 + VZERO T_4 + EXPACC2(T_0, T_2, T_3, T_4, T_1, T_5, T_7) + + // T_2, T_3, T_4: [0, r] + + // setup r*20 + VLEIG $0, $0, T_0 + VLEIG $1, $20, T_0 // T_0: [0, 20] + VZERO T_5 + VZERO T_6 + VMSLG T_0, T_3, T_5, T_5 + VMSLG T_0, T_4, T_6, T_6 + + // store r for final block in GR + VLGVG $1, T_2, RSAVE_0 // c + VLGVG $1, T_3, RSAVE_1 // c + VLGVG $1, T_4, RSAVE_2 // c + VLGVG $1, T_5, R5SAVE_1 // c + VLGVG $1, T_6, R5SAVE_2 // c + + // initialize h + VZERO H0_0 + VZERO H1_0 + VZERO H2_0 + VZERO H0_1 + VZERO H1_1 + VZERO H2_1 + + // initialize pointer for reduce constants + MOVD $·reduce<>(SB), R12 + + // calculate r**2 and 20*(r**2) + VZERO R_0 + VZERO R_1 + VZERO R_2 + SQUARE(T_2, T_3, T_4, T_6, R_0, R_1, R_2, T_1, T_5, T_7) + REDUCE2(R_0, R_1, R_2, M0, M1, M2, M3, M4, R5_1, R5_2, M5, T_1) + VZERO R5_1 + VZERO R5_2 + VMSLG T_0, R_1, R5_1, R5_1 + VMSLG T_0, R_2, R5_2, R5_2 + + // skip r**4 calculation if 3 blocks or less + CMPBLE R3, $48, b4 + + // calculate r**4 and 20*(r**4) + VZERO T_8 + VZERO T_9 + VZERO T_10 + SQUARE(R_0, R_1, R_2, R5_2, T_8, T_9, T_10, T_1, T_5, T_7) + REDUCE2(T_8, T_9, T_10, M0, M1, M2, M3, M4, T_2, T_3, M5, T_1) + VZERO T_2 + VZERO T_3 + VMSLG T_0, T_9, T_2, T_2 + VMSLG T_0, T_10, T_3, T_3 + + // put r**2 to the right and r**4 to the left of R_0, R_1, R_2 + VSLDB $8, T_8, T_8, T_8 + VSLDB $8, T_9, T_9, T_9 + VSLDB $8, T_10, T_10, T_10 + VSLDB $8, T_2, T_2, T_2 + VSLDB $8, T_3, T_3, T_3 + + VO T_8, R_0, R_0 + VO T_9, R_1, R_1 + VO T_10, R_2, R_2 + VO T_2, R5_1, R5_1 + VO T_3, R5_2, R5_2 + + CMPBLE R3, $80, load // less than or equal to 5 blocks in message + + // 6(or 5+1) blocks + SUB $81, R3 + VLM (R2), M0, M4 + VLL R3, 80(R2), M5 + ADD $1, R3 + MOVBZ $1, R0 + CMPBGE R3, $16, 2(PC) + VLVGB R3, R0, M5 + MOVD $96(R2), R2 + EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3) + EXPACC(M2, M3, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3) + VLEIB $2, $1, H2_0 + VLEIB $2, $1, H2_1 + VLEIB $10, $1, H2_0 + VLEIB $10, $1, H2_1 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO T_4 + VZERO T_10 + EXPACC(M4, M5, M0, M1, M2, M3, T_4, T_10, T_0, T_1, T_2, T_3) + VLR T_4, M4 + VLEIB $10, $1, M2 + CMPBLT R3, $16, 2(PC) + VLEIB $10, $1, T_10 + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9) + VMRHG V0, H0_1, H0_0 + VMRHG V0, H1_1, H1_0 + VMRHG V0, H2_1, H2_0 + VMRLG V0, H0_1, H0_1 + VMRLG V0, H1_1, H1_1 + VMRLG V0, H2_1, H2_1 + + SUB $16, R3 + CMPBLE R3, $0, square + +load: + // load EX0, EX1 and EX2 + MOVD $·c<>(SB), R5 + VLM (R5), EX0, EX2 + +loop: + CMPBLE R3, $64, add // b4 // last 4 or less blocks left + + // next 4 full blocks + VLM (R2), M2, M5 + SUB $64, R3 + MOVD $64(R2), R2 + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, T_0, T_1, T_3, T_4, T_5, T_2, T_7, T_8, T_9) + + // expacc in-lined to create [m2, m3] limbs + VGBM $0x3f3f, T_0 // 44 bit clear mask + VGBM $0x1f1f, T_1 // 40 bit clear mask + VPERM M2, M3, EX0, T_3 + VESRLG $4, T_0, T_0 // 44 bit clear mask ready + VPERM M2, M3, EX1, T_4 + VPERM M2, M3, EX2, T_5 + VN T_0, T_3, T_3 + VESRLG $4, T_4, T_4 + VN T_1, T_5, T_5 + VN T_0, T_4, T_4 + VMRHG H0_1, T_3, H0_0 + VMRHG H1_1, T_4, H1_0 + VMRHG H2_1, T_5, H2_0 + VMRLG H0_1, T_3, H0_1 + VMRLG H1_1, T_4, H1_1 + VMRLG H2_1, T_5, H2_1 + VLEIB $10, $1, H2_0 + VLEIB $10, $1, H2_1 + VPERM M4, M5, EX0, T_3 + VPERM M4, M5, EX1, T_4 + VPERM M4, M5, EX2, T_5 + VN T_0, T_3, T_3 + VESRLG $4, T_4, T_4 + VN T_1, T_5, T_5 + VN T_0, T_4, T_4 + VMRHG V0, T_3, M0 + VMRHG V0, T_4, M1 + VMRHG V0, T_5, M2 + VMRLG V0, T_3, M3 + VMRLG V0, T_4, M4 + VMRLG V0, T_5, M5 + VLEIB $10, $1, M2 + VLEIB $10, $1, M5 + + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + CMPBNE R3, $0, loop + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9) + VMRHG V0, H0_1, H0_0 + VMRHG V0, H1_1, H1_0 + VMRHG V0, H2_1, H2_0 + VMRLG V0, H0_1, H0_1 + VMRLG V0, H1_1, H1_1 + VMRLG V0, H2_1, H2_1 + + // load EX0, EX1, EX2 + MOVD $·constants<>(SB), R5 + VLM (R5), EX0, EX2 + + // sum vectors + VAQ H0_0, H0_1, H0_0 + VAQ H1_0, H1_1, H1_0 + VAQ H2_0, H2_1, H2_0 + + // h may be >= 2*(2**130-5) so we need to reduce it again + // M0...M4 are used as temps here + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5) + +next: // carry h1->h2 + VLEIB $7, $0x28, T_1 + VREPIB $4, T_2 + VGBM $0x003F, T_3 + VESRLG $4, T_3 + + // byte shift + VSRLB T_1, H1_0, T_4 + + // bit shift + VSRL T_2, T_4, T_4 + + // clear h1 carry bits + VN T_3, H1_0, H1_0 + + // add carry + VAQ T_4, H2_0, H2_0 + + // h is now < 2*(2**130-5) + // pack h into h1 (hi) and h0 (lo) + PACK(H0_0, H1_0, H2_0) + + // if h > 2**130-5 then h -= 2**130-5 + MOD(H0_0, H1_0, T_0, T_1, T_2) + + // h += s + MOVD $·bswapMask<>(SB), R5 + VL (R5), T_1 + VL 16(R4), T_0 + VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big) + VAQ T_0, H0_0, H0_0 + VPERM H0_0, H0_0, T_1, H0_0 // reverse bytes (to little) + VST H0_0, (R1) + RET + +add: + // load EX0, EX1, EX2 + MOVD $·constants<>(SB), R5 + VLM (R5), EX0, EX2 + + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9) + VMRHG V0, H0_1, H0_0 + VMRHG V0, H1_1, H1_0 + VMRHG V0, H2_1, H2_0 + VMRLG V0, H0_1, H0_1 + VMRLG V0, H1_1, H1_1 + VMRLG V0, H2_1, H2_1 + CMPBLE R3, $64, b4 + +b4: + CMPBLE R3, $48, b3 // 3 blocks or less + + // 4(3+1) blocks remaining + SUB $49, R3 + VLM (R2), M0, M2 + VLL R3, 48(R2), M3 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, M3 + MOVD $64(R2), R2 + EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3) + VLEIB $10, $1, H2_0 + VLEIB $10, $1, H2_1 + VZERO M0 + VZERO M1 + VZERO M4 + VZERO M5 + VZERO T_4 + VZERO T_10 + EXPACC(M2, M3, M0, M1, M4, M5, T_4, T_10, T_0, T_1, T_2, T_3) + VLR T_4, M2 + VLEIB $10, $1, M4 + CMPBNE R3, $16, 2(PC) + VLEIB $10, $1, T_10 + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M4, M5, M2, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9) + VMRHG V0, H0_1, H0_0 + VMRHG V0, H1_1, H1_0 + VMRHG V0, H2_1, H2_0 + VMRLG V0, H0_1, H0_1 + VMRLG V0, H1_1, H1_1 + VMRLG V0, H2_1, H2_1 + SUB $16, R3 + CMPBLE R3, $0, square // this condition must always hold true! + +b3: + CMPBLE R3, $32, b2 + + // 3 blocks remaining + + // setup [r²,r] + VSLDB $8, R_0, R_0, R_0 + VSLDB $8, R_1, R_1, R_1 + VSLDB $8, R_2, R_2, R_2 + VSLDB $8, R5_1, R5_1, R5_1 + VSLDB $8, R5_2, R5_2, R5_2 + + VLVGG $1, RSAVE_0, R_0 + VLVGG $1, RSAVE_1, R_1 + VLVGG $1, RSAVE_2, R_2 + VLVGG $1, R5SAVE_1, R5_1 + VLVGG $1, R5SAVE_2, R5_2 + + // setup [h0, h1] + VSLDB $8, H0_0, H0_0, H0_0 + VSLDB $8, H1_0, H1_0, H1_0 + VSLDB $8, H2_0, H2_0, H2_0 + VO H0_1, H0_0, H0_0 + VO H1_1, H1_0, H1_0 + VO H2_1, H2_0, H2_0 + VZERO H0_1 + VZERO H1_1 + VZERO H2_1 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + + // H*[r**2, r] + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, T_10, M5) + + SUB $33, R3 + VLM (R2), M0, M1 + VLL R3, 32(R2), M2 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, M2 + + // H += m0 + VZERO T_1 + VZERO T_2 + VZERO T_3 + EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6) + VLEIB $10, $1, T_3 + VAG H0_0, T_1, H0_0 + VAG H1_0, T_2, H1_0 + VAG H2_0, T_3, H2_0 + + VZERO M0 + VZERO M3 + VZERO M4 + VZERO M5 + VZERO T_10 + + // (H+m0)*r + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M3, M4, M5, V0, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_10, H0_1, H1_1, H2_1, T_9) + + // H += m1 + VZERO V0 + VZERO T_1 + VZERO T_2 + VZERO T_3 + EXPACC2(M1, T_1, T_2, T_3, T_4, T_5, T_6) + VLEIB $10, $1, T_3 + VAQ H0_0, T_1, H0_0 + VAQ H1_0, T_2, H1_0 + VAQ H2_0, T_3, H2_0 + REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10) + + // [H, m2] * [r**2, r] + EXPACC2(M2, H0_0, H1_0, H2_0, T_1, T_2, T_3) + CMPBNE R3, $16, 2(PC) + VLEIB $10, $1, H2_0 + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, M5, T_10) + SUB $16, R3 + CMPBLE R3, $0, next // this condition must always hold true! + +b2: + CMPBLE R3, $16, b1 + + // 2 blocks remaining + + // setup [r²,r] + VSLDB $8, R_0, R_0, R_0 + VSLDB $8, R_1, R_1, R_1 + VSLDB $8, R_2, R_2, R_2 + VSLDB $8, R5_1, R5_1, R5_1 + VSLDB $8, R5_2, R5_2, R5_2 + + VLVGG $1, RSAVE_0, R_0 + VLVGG $1, RSAVE_1, R_1 + VLVGG $1, RSAVE_2, R_2 + VLVGG $1, R5SAVE_1, R5_1 + VLVGG $1, R5SAVE_2, R5_2 + + // setup [h0, h1] + VSLDB $8, H0_0, H0_0, H0_0 + VSLDB $8, H1_0, H1_0, H1_0 + VSLDB $8, H2_0, H2_0, H2_0 + VO H0_1, H0_0, H0_0 + VO H1_1, H1_0, H1_0 + VO H2_1, H2_0, H2_0 + VZERO H0_1 + VZERO H1_1 + VZERO H2_1 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + + // H*[r**2, r] + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9) + VMRHG V0, H0_1, H0_0 + VMRHG V0, H1_1, H1_0 + VMRHG V0, H2_1, H2_0 + VMRLG V0, H0_1, H0_1 + VMRLG V0, H1_1, H1_1 + VMRLG V0, H2_1, H2_1 + + // move h to the left and 0s at the right + VSLDB $8, H0_0, H0_0, H0_0 + VSLDB $8, H1_0, H1_0, H1_0 + VSLDB $8, H2_0, H2_0, H2_0 + + // get message blocks and append 1 to start + SUB $17, R3 + VL (R2), M0 + VLL R3, 16(R2), M1 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, M1 + VZERO T_6 + VZERO T_7 + VZERO T_8 + EXPACC2(M0, T_6, T_7, T_8, T_1, T_2, T_3) + EXPACC2(M1, T_6, T_7, T_8, T_1, T_2, T_3) + VLEIB $2, $1, T_8 + CMPBNE R3, $16, 2(PC) + VLEIB $10, $1, T_8 + + // add [m0, m1] to h + VAG H0_0, T_6, H0_0 + VAG H1_0, T_7, H1_0 + VAG H2_0, T_8, H2_0 + + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + VZERO T_10 + VZERO M0 + + // at this point R_0 .. R5_2 look like [r**2, r] + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M2, M3, M4, M5, T_10, M0, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M2, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10) + SUB $16, R3, R3 + CMPBLE R3, $0, next + +b1: + CMPBLE R3, $0, next + + // 1 block remaining + + // setup [r²,r] + VSLDB $8, R_0, R_0, R_0 + VSLDB $8, R_1, R_1, R_1 + VSLDB $8, R_2, R_2, R_2 + VSLDB $8, R5_1, R5_1, R5_1 + VSLDB $8, R5_2, R5_2, R5_2 + + VLVGG $1, RSAVE_0, R_0 + VLVGG $1, RSAVE_1, R_1 + VLVGG $1, RSAVE_2, R_2 + VLVGG $1, R5SAVE_1, R5_1 + VLVGG $1, R5SAVE_2, R5_2 + + // setup [h0, h1] + VSLDB $8, H0_0, H0_0, H0_0 + VSLDB $8, H1_0, H1_0, H1_0 + VSLDB $8, H2_0, H2_0, H2_0 + VO H0_1, H0_0, H0_0 + VO H1_1, H1_0, H1_0 + VO H2_1, H2_0, H2_0 + VZERO H0_1 + VZERO H1_1 + VZERO H2_1 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + + // H*[r**2, r] + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5) + + // set up [0, m0] limbs + SUB $1, R3 + VLL R3, (R2), M0 + ADD $1, R3 + MOVBZ $1, R0 + CMPBEQ R3, $16, 2(PC) + VLVGB R3, R0, M0 + VZERO T_1 + VZERO T_2 + VZERO T_3 + EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)// limbs: [0, m] + CMPBNE R3, $16, 2(PC) + VLEIB $10, $1, T_3 + + // h+m0 + VAQ H0_0, T_1, H0_0 + VAQ H1_0, T_2, H1_0 + VAQ H2_0, T_3, H2_0 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5) + + BR next + +square: + // setup [r²,r] + VSLDB $8, R_0, R_0, R_0 + VSLDB $8, R_1, R_1, R_1 + VSLDB $8, R_2, R_2, R_2 + VSLDB $8, R5_1, R5_1, R5_1 + VSLDB $8, R5_2, R5_2, R5_2 + + VLVGG $1, RSAVE_0, R_0 + VLVGG $1, RSAVE_1, R_1 + VLVGG $1, RSAVE_2, R_2 + VLVGG $1, R5SAVE_1, R5_1 + VLVGG $1, R5SAVE_2, R5_2 + + // setup [h0, h1] + VSLDB $8, H0_0, H0_0, H0_0 + VSLDB $8, H1_0, H1_0, H1_0 + VSLDB $8, H2_0, H2_0, H2_0 + VO H0_1, H0_0, H0_0 + VO H1_1, H1_0, H1_0 + VO H2_1, H2_0, H2_0 + VZERO H0_1 + VZERO H1_1 + VZERO H2_1 + + VZERO M0 + VZERO M1 + VZERO M2 + VZERO M3 + VZERO M4 + VZERO M5 + + // (h0*r**2) + (h1*r) + MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9) + REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5) + BR next diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go new file mode 100644 index 00000000..cf3eeb15 --- /dev/null +++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go @@ -0,0 +1,124 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ripemd160 implements the RIPEMD-160 hash algorithm. +// +// Deprecated: RIPEMD-160 is a legacy hash and should not be used for new +// applications. Also, this package does not and will not provide an optimized +// implementation. Instead, use a modern hash like SHA-256 (from crypto/sha256). +package ripemd160 // import "golang.org/x/crypto/ripemd160" + +// RIPEMD-160 is designed by Hans Dobbertin, Antoon Bosselaers, and Bart +// Preneel with specifications available at: +// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. + +import ( + "crypto" + "hash" +) + +func init() { + crypto.RegisterHash(crypto.RIPEMD160, New) +} + +// The size of the checksum in bytes. +const Size = 20 + +// The block size of the hash algorithm in bytes. +const BlockSize = 64 + +const ( + _s0 = 0x67452301 + _s1 = 0xefcdab89 + _s2 = 0x98badcfe + _s3 = 0x10325476 + _s4 = 0xc3d2e1f0 +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + s [5]uint32 // running context + x [BlockSize]byte // temporary buffer + nx int // index into x + tc uint64 // total count of bytes processed +} + +func (d *digest) Reset() { + d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4 + d.nx = 0 + d.tc = 0 +} + +// New returns a new hash.Hash computing the checksum. +func New() hash.Hash { + result := new(digest) + result.Reset() + return result +} + +func (d *digest) Size() int { return Size } + +func (d *digest) BlockSize() int { return BlockSize } + +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + d.tc += uint64(nn) + if d.nx > 0 { + n := len(p) + if n > BlockSize-d.nx { + n = BlockSize - d.nx + } + for i := 0; i < n; i++ { + d.x[d.nx+i] = p[i] + } + d.nx += n + if d.nx == BlockSize { + _Block(d, d.x[0:]) + d.nx = 0 + } + p = p[n:] + } + n := _Block(d, p) + p = p[n:] + if len(p) > 0 { + d.nx = copy(d.x[:], p) + } + return +} + +func (d0 *digest) Sum(in []byte) []byte { + // Make a copy of d0 so that caller can keep writing and summing. + d := *d0 + + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. + tc := d.tc + var tmp [64]byte + tmp[0] = 0x80 + if tc%64 < 56 { + d.Write(tmp[0 : 56-tc%64]) + } else { + d.Write(tmp[0 : 64+56-tc%64]) + } + + // Length in bits. + tc <<= 3 + for i := uint(0); i < 8; i++ { + tmp[i] = byte(tc >> (8 * i)) + } + d.Write(tmp[0:8]) + + if d.nx != 0 { + panic("d.nx != 0") + } + + var digest [Size]byte + for i, s := range d.s { + digest[i*4] = byte(s) + digest[i*4+1] = byte(s >> 8) + digest[i*4+2] = byte(s >> 16) + digest[i*4+3] = byte(s >> 24) + } + + return append(in, digest[:]...) +} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go new file mode 100644 index 00000000..656e8df9 --- /dev/null +++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go @@ -0,0 +1,23 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!appengine,!gccgo + +package salsa + +//go:noescape + +// salsa2020XORKeyStream is implemented in salsa20_amd64.s. +func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) + +// XORKeyStream crypts bytes from in to out using the given key and counters. +// In and out must overlap entirely or not at all. Counter +// contains the raw salsa20 counter bytes (both nonce and block counter). +func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { + if len(in) == 0 { + return + } + _ = out[len(in)-1] + salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0]) +} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s new file mode 100644 index 00000000..18085d2e --- /dev/null +++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s @@ -0,0 +1,883 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!appengine,!gccgo + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html + +// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) +// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size. +TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment + MOVQ out+0(FP),DI + MOVQ in+8(FP),SI + MOVQ n+16(FP),DX + MOVQ nonce+24(FP),CX + MOVQ key+32(FP),R8 + + MOVQ SP,R12 + MOVQ SP,R9 + ADDQ $31, R9 + ANDQ $~31, R9 + MOVQ R9, SP + + MOVQ DX,R9 + MOVQ CX,DX + MOVQ R8,R10 + CMPQ R9,$0 + JBE DONE + START: + MOVL 20(R10),CX + MOVL 0(R10),R8 + MOVL 0(DX),AX + MOVL 16(R10),R11 + MOVL CX,0(SP) + MOVL R8, 4 (SP) + MOVL AX, 8 (SP) + MOVL R11, 12 (SP) + MOVL 8(DX),CX + MOVL 24(R10),R8 + MOVL 4(R10),AX + MOVL 4(DX),R11 + MOVL CX,16(SP) + MOVL R8, 20 (SP) + MOVL AX, 24 (SP) + MOVL R11, 28 (SP) + MOVL 12(DX),CX + MOVL 12(R10),DX + MOVL 28(R10),R8 + MOVL 8(R10),AX + MOVL DX,32(SP) + MOVL CX, 36 (SP) + MOVL R8, 40 (SP) + MOVL AX, 44 (SP) + MOVQ $1634760805,DX + MOVQ $857760878,CX + MOVQ $2036477234,R8 + MOVQ $1797285236,AX + MOVL DX,48(SP) + MOVL CX, 52 (SP) + MOVL R8, 56 (SP) + MOVL AX, 60 (SP) + CMPQ R9,$256 + JB BYTESBETWEEN1AND255 + MOVOA 48(SP),X0 + PSHUFL $0X55,X0,X1 + PSHUFL $0XAA,X0,X2 + PSHUFL $0XFF,X0,X3 + PSHUFL $0X00,X0,X0 + MOVOA X1,64(SP) + MOVOA X2,80(SP) + MOVOA X3,96(SP) + MOVOA X0,112(SP) + MOVOA 0(SP),X0 + PSHUFL $0XAA,X0,X1 + PSHUFL $0XFF,X0,X2 + PSHUFL $0X00,X0,X3 + PSHUFL $0X55,X0,X0 + MOVOA X1,128(SP) + MOVOA X2,144(SP) + MOVOA X3,160(SP) + MOVOA X0,176(SP) + MOVOA 16(SP),X0 + PSHUFL $0XFF,X0,X1 + PSHUFL $0X55,X0,X2 + PSHUFL $0XAA,X0,X0 + MOVOA X1,192(SP) + MOVOA X2,208(SP) + MOVOA X0,224(SP) + MOVOA 32(SP),X0 + PSHUFL $0X00,X0,X1 + PSHUFL $0XAA,X0,X2 + PSHUFL $0XFF,X0,X0 + MOVOA X1,240(SP) + MOVOA X2,256(SP) + MOVOA X0,272(SP) + BYTESATLEAST256: + MOVL 16(SP),DX + MOVL 36 (SP),CX + MOVL DX,288(SP) + MOVL CX,304(SP) + SHLQ $32,CX + ADDQ CX,DX + ADDQ $1,DX + MOVQ DX,CX + SHRQ $32,CX + MOVL DX, 292 (SP) + MOVL CX, 308 (SP) + ADDQ $1,DX + MOVQ DX,CX + SHRQ $32,CX + MOVL DX, 296 (SP) + MOVL CX, 312 (SP) + ADDQ $1,DX + MOVQ DX,CX + SHRQ $32,CX + MOVL DX, 300 (SP) + MOVL CX, 316 (SP) + ADDQ $1,DX + MOVQ DX,CX + SHRQ $32,CX + MOVL DX,16(SP) + MOVL CX, 36 (SP) + MOVQ R9,352(SP) + MOVQ $20,DX + MOVOA 64(SP),X0 + MOVOA 80(SP),X1 + MOVOA 96(SP),X2 + MOVOA 256(SP),X3 + MOVOA 272(SP),X4 + MOVOA 128(SP),X5 + MOVOA 144(SP),X6 + MOVOA 176(SP),X7 + MOVOA 192(SP),X8 + MOVOA 208(SP),X9 + MOVOA 224(SP),X10 + MOVOA 304(SP),X11 + MOVOA 112(SP),X12 + MOVOA 160(SP),X13 + MOVOA 240(SP),X14 + MOVOA 288(SP),X15 + MAINLOOP1: + MOVOA X1,320(SP) + MOVOA X2,336(SP) + MOVOA X13,X1 + PADDL X12,X1 + MOVOA X1,X2 + PSLLL $7,X1 + PXOR X1,X14 + PSRLL $25,X2 + PXOR X2,X14 + MOVOA X7,X1 + PADDL X0,X1 + MOVOA X1,X2 + PSLLL $7,X1 + PXOR X1,X11 + PSRLL $25,X2 + PXOR X2,X11 + MOVOA X12,X1 + PADDL X14,X1 + MOVOA X1,X2 + PSLLL $9,X1 + PXOR X1,X15 + PSRLL $23,X2 + PXOR X2,X15 + MOVOA X0,X1 + PADDL X11,X1 + MOVOA X1,X2 + PSLLL $9,X1 + PXOR X1,X9 + PSRLL $23,X2 + PXOR X2,X9 + MOVOA X14,X1 + PADDL X15,X1 + MOVOA X1,X2 + PSLLL $13,X1 + PXOR X1,X13 + PSRLL $19,X2 + PXOR X2,X13 + MOVOA X11,X1 + PADDL X9,X1 + MOVOA X1,X2 + PSLLL $13,X1 + PXOR X1,X7 + PSRLL $19,X2 + PXOR X2,X7 + MOVOA X15,X1 + PADDL X13,X1 + MOVOA X1,X2 + PSLLL $18,X1 + PXOR X1,X12 + PSRLL $14,X2 + PXOR X2,X12 + MOVOA 320(SP),X1 + MOVOA X12,320(SP) + MOVOA X9,X2 + PADDL X7,X2 + MOVOA X2,X12 + PSLLL $18,X2 + PXOR X2,X0 + PSRLL $14,X12 + PXOR X12,X0 + MOVOA X5,X2 + PADDL X1,X2 + MOVOA X2,X12 + PSLLL $7,X2 + PXOR X2,X3 + PSRLL $25,X12 + PXOR X12,X3 + MOVOA 336(SP),X2 + MOVOA X0,336(SP) + MOVOA X6,X0 + PADDL X2,X0 + MOVOA X0,X12 + PSLLL $7,X0 + PXOR X0,X4 + PSRLL $25,X12 + PXOR X12,X4 + MOVOA X1,X0 + PADDL X3,X0 + MOVOA X0,X12 + PSLLL $9,X0 + PXOR X0,X10 + PSRLL $23,X12 + PXOR X12,X10 + MOVOA X2,X0 + PADDL X4,X0 + MOVOA X0,X12 + PSLLL $9,X0 + PXOR X0,X8 + PSRLL $23,X12 + PXOR X12,X8 + MOVOA X3,X0 + PADDL X10,X0 + MOVOA X0,X12 + PSLLL $13,X0 + PXOR X0,X5 + PSRLL $19,X12 + PXOR X12,X5 + MOVOA X4,X0 + PADDL X8,X0 + MOVOA X0,X12 + PSLLL $13,X0 + PXOR X0,X6 + PSRLL $19,X12 + PXOR X12,X6 + MOVOA X10,X0 + PADDL X5,X0 + MOVOA X0,X12 + PSLLL $18,X0 + PXOR X0,X1 + PSRLL $14,X12 + PXOR X12,X1 + MOVOA 320(SP),X0 + MOVOA X1,320(SP) + MOVOA X4,X1 + PADDL X0,X1 + MOVOA X1,X12 + PSLLL $7,X1 + PXOR X1,X7 + PSRLL $25,X12 + PXOR X12,X7 + MOVOA X8,X1 + PADDL X6,X1 + MOVOA X1,X12 + PSLLL $18,X1 + PXOR X1,X2 + PSRLL $14,X12 + PXOR X12,X2 + MOVOA 336(SP),X12 + MOVOA X2,336(SP) + MOVOA X14,X1 + PADDL X12,X1 + MOVOA X1,X2 + PSLLL $7,X1 + PXOR X1,X5 + PSRLL $25,X2 + PXOR X2,X5 + MOVOA X0,X1 + PADDL X7,X1 + MOVOA X1,X2 + PSLLL $9,X1 + PXOR X1,X10 + PSRLL $23,X2 + PXOR X2,X10 + MOVOA X12,X1 + PADDL X5,X1 + MOVOA X1,X2 + PSLLL $9,X1 + PXOR X1,X8 + PSRLL $23,X2 + PXOR X2,X8 + MOVOA X7,X1 + PADDL X10,X1 + MOVOA X1,X2 + PSLLL $13,X1 + PXOR X1,X4 + PSRLL $19,X2 + PXOR X2,X4 + MOVOA X5,X1 + PADDL X8,X1 + MOVOA X1,X2 + PSLLL $13,X1 + PXOR X1,X14 + PSRLL $19,X2 + PXOR X2,X14 + MOVOA X10,X1 + PADDL X4,X1 + MOVOA X1,X2 + PSLLL $18,X1 + PXOR X1,X0 + PSRLL $14,X2 + PXOR X2,X0 + MOVOA 320(SP),X1 + MOVOA X0,320(SP) + MOVOA X8,X0 + PADDL X14,X0 + MOVOA X0,X2 + PSLLL $18,X0 + PXOR X0,X12 + PSRLL $14,X2 + PXOR X2,X12 + MOVOA X11,X0 + PADDL X1,X0 + MOVOA X0,X2 + PSLLL $7,X0 + PXOR X0,X6 + PSRLL $25,X2 + PXOR X2,X6 + MOVOA 336(SP),X2 + MOVOA X12,336(SP) + MOVOA X3,X0 + PADDL X2,X0 + MOVOA X0,X12 + PSLLL $7,X0 + PXOR X0,X13 + PSRLL $25,X12 + PXOR X12,X13 + MOVOA X1,X0 + PADDL X6,X0 + MOVOA X0,X12 + PSLLL $9,X0 + PXOR X0,X15 + PSRLL $23,X12 + PXOR X12,X15 + MOVOA X2,X0 + PADDL X13,X0 + MOVOA X0,X12 + PSLLL $9,X0 + PXOR X0,X9 + PSRLL $23,X12 + PXOR X12,X9 + MOVOA X6,X0 + PADDL X15,X0 + MOVOA X0,X12 + PSLLL $13,X0 + PXOR X0,X11 + PSRLL $19,X12 + PXOR X12,X11 + MOVOA X13,X0 + PADDL X9,X0 + MOVOA X0,X12 + PSLLL $13,X0 + PXOR X0,X3 + PSRLL $19,X12 + PXOR X12,X3 + MOVOA X15,X0 + PADDL X11,X0 + MOVOA X0,X12 + PSLLL $18,X0 + PXOR X0,X1 + PSRLL $14,X12 + PXOR X12,X1 + MOVOA X9,X0 + PADDL X3,X0 + MOVOA X0,X12 + PSLLL $18,X0 + PXOR X0,X2 + PSRLL $14,X12 + PXOR X12,X2 + MOVOA 320(SP),X12 + MOVOA 336(SP),X0 + SUBQ $2,DX + JA MAINLOOP1 + PADDL 112(SP),X12 + PADDL 176(SP),X7 + PADDL 224(SP),X10 + PADDL 272(SP),X4 + MOVD X12,DX + MOVD X7,CX + MOVD X10,R8 + MOVD X4,R9 + PSHUFL $0X39,X12,X12 + PSHUFL $0X39,X7,X7 + PSHUFL $0X39,X10,X10 + PSHUFL $0X39,X4,X4 + XORL 0(SI),DX + XORL 4(SI),CX + XORL 8(SI),R8 + XORL 12(SI),R9 + MOVL DX,0(DI) + MOVL CX,4(DI) + MOVL R8,8(DI) + MOVL R9,12(DI) + MOVD X12,DX + MOVD X7,CX + MOVD X10,R8 + MOVD X4,R9 + PSHUFL $0X39,X12,X12 + PSHUFL $0X39,X7,X7 + PSHUFL $0X39,X10,X10 + PSHUFL $0X39,X4,X4 + XORL 64(SI),DX + XORL 68(SI),CX + XORL 72(SI),R8 + XORL 76(SI),R9 + MOVL DX,64(DI) + MOVL CX,68(DI) + MOVL R8,72(DI) + MOVL R9,76(DI) + MOVD X12,DX + MOVD X7,CX + MOVD X10,R8 + MOVD X4,R9 + PSHUFL $0X39,X12,X12 + PSHUFL $0X39,X7,X7 + PSHUFL $0X39,X10,X10 + PSHUFL $0X39,X4,X4 + XORL 128(SI),DX + XORL 132(SI),CX + XORL 136(SI),R8 + XORL 140(SI),R9 + MOVL DX,128(DI) + MOVL CX,132(DI) + MOVL R8,136(DI) + MOVL R9,140(DI) + MOVD X12,DX + MOVD X7,CX + MOVD X10,R8 + MOVD X4,R9 + XORL 192(SI),DX + XORL 196(SI),CX + XORL 200(SI),R8 + XORL 204(SI),R9 + MOVL DX,192(DI) + MOVL CX,196(DI) + MOVL R8,200(DI) + MOVL R9,204(DI) + PADDL 240(SP),X14 + PADDL 64(SP),X0 + PADDL 128(SP),X5 + PADDL 192(SP),X8 + MOVD X14,DX + MOVD X0,CX + MOVD X5,R8 + MOVD X8,R9 + PSHUFL $0X39,X14,X14 + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X5,X5 + PSHUFL $0X39,X8,X8 + XORL 16(SI),DX + XORL 20(SI),CX + XORL 24(SI),R8 + XORL 28(SI),R9 + MOVL DX,16(DI) + MOVL CX,20(DI) + MOVL R8,24(DI) + MOVL R9,28(DI) + MOVD X14,DX + MOVD X0,CX + MOVD X5,R8 + MOVD X8,R9 + PSHUFL $0X39,X14,X14 + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X5,X5 + PSHUFL $0X39,X8,X8 + XORL 80(SI),DX + XORL 84(SI),CX + XORL 88(SI),R8 + XORL 92(SI),R9 + MOVL DX,80(DI) + MOVL CX,84(DI) + MOVL R8,88(DI) + MOVL R9,92(DI) + MOVD X14,DX + MOVD X0,CX + MOVD X5,R8 + MOVD X8,R9 + PSHUFL $0X39,X14,X14 + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X5,X5 + PSHUFL $0X39,X8,X8 + XORL 144(SI),DX + XORL 148(SI),CX + XORL 152(SI),R8 + XORL 156(SI),R9 + MOVL DX,144(DI) + MOVL CX,148(DI) + MOVL R8,152(DI) + MOVL R9,156(DI) + MOVD X14,DX + MOVD X0,CX + MOVD X5,R8 + MOVD X8,R9 + XORL 208(SI),DX + XORL 212(SI),CX + XORL 216(SI),R8 + XORL 220(SI),R9 + MOVL DX,208(DI) + MOVL CX,212(DI) + MOVL R8,216(DI) + MOVL R9,220(DI) + PADDL 288(SP),X15 + PADDL 304(SP),X11 + PADDL 80(SP),X1 + PADDL 144(SP),X6 + MOVD X15,DX + MOVD X11,CX + MOVD X1,R8 + MOVD X6,R9 + PSHUFL $0X39,X15,X15 + PSHUFL $0X39,X11,X11 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X6,X6 + XORL 32(SI),DX + XORL 36(SI),CX + XORL 40(SI),R8 + XORL 44(SI),R9 + MOVL DX,32(DI) + MOVL CX,36(DI) + MOVL R8,40(DI) + MOVL R9,44(DI) + MOVD X15,DX + MOVD X11,CX + MOVD X1,R8 + MOVD X6,R9 + PSHUFL $0X39,X15,X15 + PSHUFL $0X39,X11,X11 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X6,X6 + XORL 96(SI),DX + XORL 100(SI),CX + XORL 104(SI),R8 + XORL 108(SI),R9 + MOVL DX,96(DI) + MOVL CX,100(DI) + MOVL R8,104(DI) + MOVL R9,108(DI) + MOVD X15,DX + MOVD X11,CX + MOVD X1,R8 + MOVD X6,R9 + PSHUFL $0X39,X15,X15 + PSHUFL $0X39,X11,X11 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X6,X6 + XORL 160(SI),DX + XORL 164(SI),CX + XORL 168(SI),R8 + XORL 172(SI),R9 + MOVL DX,160(DI) + MOVL CX,164(DI) + MOVL R8,168(DI) + MOVL R9,172(DI) + MOVD X15,DX + MOVD X11,CX + MOVD X1,R8 + MOVD X6,R9 + XORL 224(SI),DX + XORL 228(SI),CX + XORL 232(SI),R8 + XORL 236(SI),R9 + MOVL DX,224(DI) + MOVL CX,228(DI) + MOVL R8,232(DI) + MOVL R9,236(DI) + PADDL 160(SP),X13 + PADDL 208(SP),X9 + PADDL 256(SP),X3 + PADDL 96(SP),X2 + MOVD X13,DX + MOVD X9,CX + MOVD X3,R8 + MOVD X2,R9 + PSHUFL $0X39,X13,X13 + PSHUFL $0X39,X9,X9 + PSHUFL $0X39,X3,X3 + PSHUFL $0X39,X2,X2 + XORL 48(SI),DX + XORL 52(SI),CX + XORL 56(SI),R8 + XORL 60(SI),R9 + MOVL DX,48(DI) + MOVL CX,52(DI) + MOVL R8,56(DI) + MOVL R9,60(DI) + MOVD X13,DX + MOVD X9,CX + MOVD X3,R8 + MOVD X2,R9 + PSHUFL $0X39,X13,X13 + PSHUFL $0X39,X9,X9 + PSHUFL $0X39,X3,X3 + PSHUFL $0X39,X2,X2 + XORL 112(SI),DX + XORL 116(SI),CX + XORL 120(SI),R8 + XORL 124(SI),R9 + MOVL DX,112(DI) + MOVL CX,116(DI) + MOVL R8,120(DI) + MOVL R9,124(DI) + MOVD X13,DX + MOVD X9,CX + MOVD X3,R8 + MOVD X2,R9 + PSHUFL $0X39,X13,X13 + PSHUFL $0X39,X9,X9 + PSHUFL $0X39,X3,X3 + PSHUFL $0X39,X2,X2 + XORL 176(SI),DX + XORL 180(SI),CX + XORL 184(SI),R8 + XORL 188(SI),R9 + MOVL DX,176(DI) + MOVL CX,180(DI) + MOVL R8,184(DI) + MOVL R9,188(DI) + MOVD X13,DX + MOVD X9,CX + MOVD X3,R8 + MOVD X2,R9 + XORL 240(SI),DX + XORL 244(SI),CX + XORL 248(SI),R8 + XORL 252(SI),R9 + MOVL DX,240(DI) + MOVL CX,244(DI) + MOVL R8,248(DI) + MOVL R9,252(DI) + MOVQ 352(SP),R9 + SUBQ $256,R9 + ADDQ $256,SI + ADDQ $256,DI + CMPQ R9,$256 + JAE BYTESATLEAST256 + CMPQ R9,$0 + JBE DONE + BYTESBETWEEN1AND255: + CMPQ R9,$64 + JAE NOCOPY + MOVQ DI,DX + LEAQ 360(SP),DI + MOVQ R9,CX + REP; MOVSB + LEAQ 360(SP),DI + LEAQ 360(SP),SI + NOCOPY: + MOVQ R9,352(SP) + MOVOA 48(SP),X0 + MOVOA 0(SP),X1 + MOVOA 16(SP),X2 + MOVOA 32(SP),X3 + MOVOA X1,X4 + MOVQ $20,CX + MAINLOOP2: + PADDL X0,X4 + MOVOA X0,X5 + MOVOA X4,X6 + PSLLL $7,X4 + PSRLL $25,X6 + PXOR X4,X3 + PXOR X6,X3 + PADDL X3,X5 + MOVOA X3,X4 + MOVOA X5,X6 + PSLLL $9,X5 + PSRLL $23,X6 + PXOR X5,X2 + PSHUFL $0X93,X3,X3 + PXOR X6,X2 + PADDL X2,X4 + MOVOA X2,X5 + MOVOA X4,X6 + PSLLL $13,X4 + PSRLL $19,X6 + PXOR X4,X1 + PSHUFL $0X4E,X2,X2 + PXOR X6,X1 + PADDL X1,X5 + MOVOA X3,X4 + MOVOA X5,X6 + PSLLL $18,X5 + PSRLL $14,X6 + PXOR X5,X0 + PSHUFL $0X39,X1,X1 + PXOR X6,X0 + PADDL X0,X4 + MOVOA X0,X5 + MOVOA X4,X6 + PSLLL $7,X4 + PSRLL $25,X6 + PXOR X4,X1 + PXOR X6,X1 + PADDL X1,X5 + MOVOA X1,X4 + MOVOA X5,X6 + PSLLL $9,X5 + PSRLL $23,X6 + PXOR X5,X2 + PSHUFL $0X93,X1,X1 + PXOR X6,X2 + PADDL X2,X4 + MOVOA X2,X5 + MOVOA X4,X6 + PSLLL $13,X4 + PSRLL $19,X6 + PXOR X4,X3 + PSHUFL $0X4E,X2,X2 + PXOR X6,X3 + PADDL X3,X5 + MOVOA X1,X4 + MOVOA X5,X6 + PSLLL $18,X5 + PSRLL $14,X6 + PXOR X5,X0 + PSHUFL $0X39,X3,X3 + PXOR X6,X0 + PADDL X0,X4 + MOVOA X0,X5 + MOVOA X4,X6 + PSLLL $7,X4 + PSRLL $25,X6 + PXOR X4,X3 + PXOR X6,X3 + PADDL X3,X5 + MOVOA X3,X4 + MOVOA X5,X6 + PSLLL $9,X5 + PSRLL $23,X6 + PXOR X5,X2 + PSHUFL $0X93,X3,X3 + PXOR X6,X2 + PADDL X2,X4 + MOVOA X2,X5 + MOVOA X4,X6 + PSLLL $13,X4 + PSRLL $19,X6 + PXOR X4,X1 + PSHUFL $0X4E,X2,X2 + PXOR X6,X1 + PADDL X1,X5 + MOVOA X3,X4 + MOVOA X5,X6 + PSLLL $18,X5 + PSRLL $14,X6 + PXOR X5,X0 + PSHUFL $0X39,X1,X1 + PXOR X6,X0 + PADDL X0,X4 + MOVOA X0,X5 + MOVOA X4,X6 + PSLLL $7,X4 + PSRLL $25,X6 + PXOR X4,X1 + PXOR X6,X1 + PADDL X1,X5 + MOVOA X1,X4 + MOVOA X5,X6 + PSLLL $9,X5 + PSRLL $23,X6 + PXOR X5,X2 + PSHUFL $0X93,X1,X1 + PXOR X6,X2 + PADDL X2,X4 + MOVOA X2,X5 + MOVOA X4,X6 + PSLLL $13,X4 + PSRLL $19,X6 + PXOR X4,X3 + PSHUFL $0X4E,X2,X2 + PXOR X6,X3 + SUBQ $4,CX + PADDL X3,X5 + MOVOA X1,X4 + MOVOA X5,X6 + PSLLL $18,X5 + PXOR X7,X7 + PSRLL $14,X6 + PXOR X5,X0 + PSHUFL $0X39,X3,X3 + PXOR X6,X0 + JA MAINLOOP2 + PADDL 48(SP),X0 + PADDL 0(SP),X1 + PADDL 16(SP),X2 + PADDL 32(SP),X3 + MOVD X0,CX + MOVD X1,R8 + MOVD X2,R9 + MOVD X3,AX + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X2,X2 + PSHUFL $0X39,X3,X3 + XORL 0(SI),CX + XORL 48(SI),R8 + XORL 32(SI),R9 + XORL 16(SI),AX + MOVL CX,0(DI) + MOVL R8,48(DI) + MOVL R9,32(DI) + MOVL AX,16(DI) + MOVD X0,CX + MOVD X1,R8 + MOVD X2,R9 + MOVD X3,AX + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X2,X2 + PSHUFL $0X39,X3,X3 + XORL 20(SI),CX + XORL 4(SI),R8 + XORL 52(SI),R9 + XORL 36(SI),AX + MOVL CX,20(DI) + MOVL R8,4(DI) + MOVL R9,52(DI) + MOVL AX,36(DI) + MOVD X0,CX + MOVD X1,R8 + MOVD X2,R9 + MOVD X3,AX + PSHUFL $0X39,X0,X0 + PSHUFL $0X39,X1,X1 + PSHUFL $0X39,X2,X2 + PSHUFL $0X39,X3,X3 + XORL 40(SI),CX + XORL 24(SI),R8 + XORL 8(SI),R9 + XORL 56(SI),AX + MOVL CX,40(DI) + MOVL R8,24(DI) + MOVL R9,8(DI) + MOVL AX,56(DI) + MOVD X0,CX + MOVD X1,R8 + MOVD X2,R9 + MOVD X3,AX + XORL 60(SI),CX + XORL 44(SI),R8 + XORL 28(SI),R9 + XORL 12(SI),AX + MOVL CX,60(DI) + MOVL R8,44(DI) + MOVL R9,28(DI) + MOVL AX,12(DI) + MOVQ 352(SP),R9 + MOVL 16(SP),CX + MOVL 36 (SP),R8 + ADDQ $1,CX + SHLQ $32,R8 + ADDQ R8,CX + MOVQ CX,R8 + SHRQ $32,R8 + MOVL CX,16(SP) + MOVL R8, 36 (SP) + CMPQ R9,$64 + JA BYTESATLEAST65 + JAE BYTESATLEAST64 + MOVQ DI,SI + MOVQ DX,DI + MOVQ R9,CX + REP; MOVSB + BYTESATLEAST64: + DONE: + MOVQ R12,SP + RET + BYTESATLEAST65: + SUBQ $64,R9 + ADDQ $64,DI + ADDQ $64,SI + JMP BYTESBETWEEN1AND255 diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go new file mode 100644 index 00000000..8a46bd2b --- /dev/null +++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go @@ -0,0 +1,14 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !amd64 appengine gccgo + +package salsa + +// XORKeyStream crypts bytes from in to out using the given key and counters. +// In and out must overlap entirely or not at all. Counter +// contains the raw salsa20 counter bytes (both nonce and block counter). +func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { + genericXORKeyStream(out, in, counter, key) +} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go new file mode 100644 index 00000000..68169c6d --- /dev/null +++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go @@ -0,0 +1,231 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package salsa + +const rounds = 20 + +// core applies the Salsa20 core function to 16-byte input in, 32-byte key k, +// and 16-byte constant c, and puts the result into 64-byte array out. +func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) { + j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24 + j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24 + j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24 + j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24 + j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24 + j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24 + j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 + j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 + j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 + j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 + j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24 + j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24 + j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24 + j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24 + j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24 + j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24 + + x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8 + x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15 + + for i := 0; i < rounds; i += 2 { + u := x0 + x12 + x4 ^= u<<7 | u>>(32-7) + u = x4 + x0 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x4 + x12 ^= u<<13 | u>>(32-13) + u = x12 + x8 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x1 + x9 ^= u<<7 | u>>(32-7) + u = x9 + x5 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x9 + x1 ^= u<<13 | u>>(32-13) + u = x1 + x13 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x6 + x14 ^= u<<7 | u>>(32-7) + u = x14 + x10 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x14 + x6 ^= u<<13 | u>>(32-13) + u = x6 + x2 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x11 + x3 ^= u<<7 | u>>(32-7) + u = x3 + x15 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x3 + x11 ^= u<<13 | u>>(32-13) + u = x11 + x7 + x15 ^= u<<18 | u>>(32-18) + + u = x0 + x3 + x1 ^= u<<7 | u>>(32-7) + u = x1 + x0 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x1 + x3 ^= u<<13 | u>>(32-13) + u = x3 + x2 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x4 + x6 ^= u<<7 | u>>(32-7) + u = x6 + x5 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x6 + x4 ^= u<<13 | u>>(32-13) + u = x4 + x7 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x9 + x11 ^= u<<7 | u>>(32-7) + u = x11 + x10 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x11 + x9 ^= u<<13 | u>>(32-13) + u = x9 + x8 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x14 + x12 ^= u<<7 | u>>(32-7) + u = x12 + x15 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x12 + x14 ^= u<<13 | u>>(32-13) + u = x14 + x13 + x15 ^= u<<18 | u>>(32-18) + } + x0 += j0 + x1 += j1 + x2 += j2 + x3 += j3 + x4 += j4 + x5 += j5 + x6 += j6 + x7 += j7 + x8 += j8 + x9 += j9 + x10 += j10 + x11 += j11 + x12 += j12 + x13 += j13 + x14 += j14 + x15 += j15 + + out[0] = byte(x0) + out[1] = byte(x0 >> 8) + out[2] = byte(x0 >> 16) + out[3] = byte(x0 >> 24) + + out[4] = byte(x1) + out[5] = byte(x1 >> 8) + out[6] = byte(x1 >> 16) + out[7] = byte(x1 >> 24) + + out[8] = byte(x2) + out[9] = byte(x2 >> 8) + out[10] = byte(x2 >> 16) + out[11] = byte(x2 >> 24) + + out[12] = byte(x3) + out[13] = byte(x3 >> 8) + out[14] = byte(x3 >> 16) + out[15] = byte(x3 >> 24) + + out[16] = byte(x4) + out[17] = byte(x4 >> 8) + out[18] = byte(x4 >> 16) + out[19] = byte(x4 >> 24) + + out[20] = byte(x5) + out[21] = byte(x5 >> 8) + out[22] = byte(x5 >> 16) + out[23] = byte(x5 >> 24) + + out[24] = byte(x6) + out[25] = byte(x6 >> 8) + out[26] = byte(x6 >> 16) + out[27] = byte(x6 >> 24) + + out[28] = byte(x7) + out[29] = byte(x7 >> 8) + out[30] = byte(x7 >> 16) + out[31] = byte(x7 >> 24) + + out[32] = byte(x8) + out[33] = byte(x8 >> 8) + out[34] = byte(x8 >> 16) + out[35] = byte(x8 >> 24) + + out[36] = byte(x9) + out[37] = byte(x9 >> 8) + out[38] = byte(x9 >> 16) + out[39] = byte(x9 >> 24) + + out[40] = byte(x10) + out[41] = byte(x10 >> 8) + out[42] = byte(x10 >> 16) + out[43] = byte(x10 >> 24) + + out[44] = byte(x11) + out[45] = byte(x11 >> 8) + out[46] = byte(x11 >> 16) + out[47] = byte(x11 >> 24) + + out[48] = byte(x12) + out[49] = byte(x12 >> 8) + out[50] = byte(x12 >> 16) + out[51] = byte(x12 >> 24) + + out[52] = byte(x13) + out[53] = byte(x13 >> 8) + out[54] = byte(x13 >> 16) + out[55] = byte(x13 >> 24) + + out[56] = byte(x14) + out[57] = byte(x14 >> 8) + out[58] = byte(x14 >> 16) + out[59] = byte(x14 >> 24) + + out[60] = byte(x15) + out[61] = byte(x15 >> 8) + out[62] = byte(x15 >> 16) + out[63] = byte(x15 >> 24) +} + +// genericXORKeyStream is the generic implementation of XORKeyStream to be used +// when no assembly implementation is available. +func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { + var block [64]byte + var counterCopy [16]byte + copy(counterCopy[:], counter[:]) + + for len(in) >= 64 { + core(&block, &counterCopy, key, &Sigma) + for i, x := range block { + out[i] = in[i] ^ x + } + u := uint32(1) + for i := 8; i < 16; i++ { + u += uint32(counterCopy[i]) + counterCopy[i] = byte(u) + u >>= 8 + } + in = in[64:] + out = out[64:] + } + + if len(in) > 0 { + core(&block, &counterCopy, key, &Sigma) + for i, v := range in { + out[i] = v ^ block[i] + } + } +} diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go new file mode 100644 index 00000000..2f81fe41 --- /dev/null +++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go @@ -0,0 +1,213 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package scrypt implements the scrypt key derivation function as defined in +// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard +// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf). +package scrypt // import "golang.org/x/crypto/scrypt" + +import ( + "crypto/sha256" + "errors" + "math/bits" + + "golang.org/x/crypto/pbkdf2" +) + +const maxInt = int(^uint(0) >> 1) + +// blockCopy copies n numbers from src into dst. +func blockCopy(dst, src []uint32, n int) { + copy(dst, src[:n]) +} + +// blockXOR XORs numbers from dst with n numbers from src. +func blockXOR(dst, src []uint32, n int) { + for i, v := range src[:n] { + dst[i] ^= v + } +} + +// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, +// and puts the result into both tmp and out. +func salsaXOR(tmp *[16]uint32, in, out []uint32) { + w0 := tmp[0] ^ in[0] + w1 := tmp[1] ^ in[1] + w2 := tmp[2] ^ in[2] + w3 := tmp[3] ^ in[3] + w4 := tmp[4] ^ in[4] + w5 := tmp[5] ^ in[5] + w6 := tmp[6] ^ in[6] + w7 := tmp[7] ^ in[7] + w8 := tmp[8] ^ in[8] + w9 := tmp[9] ^ in[9] + w10 := tmp[10] ^ in[10] + w11 := tmp[11] ^ in[11] + w12 := tmp[12] ^ in[12] + w13 := tmp[13] ^ in[13] + w14 := tmp[14] ^ in[14] + w15 := tmp[15] ^ in[15] + + x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8 + x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 + + for i := 0; i < 8; i += 2 { + x4 ^= bits.RotateLeft32(x0+x12, 7) + x8 ^= bits.RotateLeft32(x4+x0, 9) + x12 ^= bits.RotateLeft32(x8+x4, 13) + x0 ^= bits.RotateLeft32(x12+x8, 18) + + x9 ^= bits.RotateLeft32(x5+x1, 7) + x13 ^= bits.RotateLeft32(x9+x5, 9) + x1 ^= bits.RotateLeft32(x13+x9, 13) + x5 ^= bits.RotateLeft32(x1+x13, 18) + + x14 ^= bits.RotateLeft32(x10+x6, 7) + x2 ^= bits.RotateLeft32(x14+x10, 9) + x6 ^= bits.RotateLeft32(x2+x14, 13) + x10 ^= bits.RotateLeft32(x6+x2, 18) + + x3 ^= bits.RotateLeft32(x15+x11, 7) + x7 ^= bits.RotateLeft32(x3+x15, 9) + x11 ^= bits.RotateLeft32(x7+x3, 13) + x15 ^= bits.RotateLeft32(x11+x7, 18) + + x1 ^= bits.RotateLeft32(x0+x3, 7) + x2 ^= bits.RotateLeft32(x1+x0, 9) + x3 ^= bits.RotateLeft32(x2+x1, 13) + x0 ^= bits.RotateLeft32(x3+x2, 18) + + x6 ^= bits.RotateLeft32(x5+x4, 7) + x7 ^= bits.RotateLeft32(x6+x5, 9) + x4 ^= bits.RotateLeft32(x7+x6, 13) + x5 ^= bits.RotateLeft32(x4+x7, 18) + + x11 ^= bits.RotateLeft32(x10+x9, 7) + x8 ^= bits.RotateLeft32(x11+x10, 9) + x9 ^= bits.RotateLeft32(x8+x11, 13) + x10 ^= bits.RotateLeft32(x9+x8, 18) + + x12 ^= bits.RotateLeft32(x15+x14, 7) + x13 ^= bits.RotateLeft32(x12+x15, 9) + x14 ^= bits.RotateLeft32(x13+x12, 13) + x15 ^= bits.RotateLeft32(x14+x13, 18) + } + x0 += w0 + x1 += w1 + x2 += w2 + x3 += w3 + x4 += w4 + x5 += w5 + x6 += w6 + x7 += w7 + x8 += w8 + x9 += w9 + x10 += w10 + x11 += w11 + x12 += w12 + x13 += w13 + x14 += w14 + x15 += w15 + + out[0], tmp[0] = x0, x0 + out[1], tmp[1] = x1, x1 + out[2], tmp[2] = x2, x2 + out[3], tmp[3] = x3, x3 + out[4], tmp[4] = x4, x4 + out[5], tmp[5] = x5, x5 + out[6], tmp[6] = x6, x6 + out[7], tmp[7] = x7, x7 + out[8], tmp[8] = x8, x8 + out[9], tmp[9] = x9, x9 + out[10], tmp[10] = x10, x10 + out[11], tmp[11] = x11, x11 + out[12], tmp[12] = x12, x12 + out[13], tmp[13] = x13, x13 + out[14], tmp[14] = x14, x14 + out[15], tmp[15] = x15, x15 +} + +func blockMix(tmp *[16]uint32, in, out []uint32, r int) { + blockCopy(tmp[:], in[(2*r-1)*16:], 16) + for i := 0; i < 2*r; i += 2 { + salsaXOR(tmp, in[i*16:], out[i*8:]) + salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:]) + } +} + +func integer(b []uint32, r int) uint64 { + j := (2*r - 1) * 16 + return uint64(b[j]) | uint64(b[j+1])<<32 +} + +func smix(b []byte, r, N int, v, xy []uint32) { + var tmp [16]uint32 + x := xy + y := xy[32*r:] + + j := 0 + for i := 0; i < 32*r; i++ { + x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 + j += 4 + } + for i := 0; i < N; i += 2 { + blockCopy(v[i*(32*r):], x, 32*r) + blockMix(&tmp, x, y, r) + + blockCopy(v[(i+1)*(32*r):], y, 32*r) + blockMix(&tmp, y, x, r) + } + for i := 0; i < N; i += 2 { + j := int(integer(x, r) & uint64(N-1)) + blockXOR(x, v[j*(32*r):], 32*r) + blockMix(&tmp, x, y, r) + + j = int(integer(y, r) & uint64(N-1)) + blockXOR(y, v[j*(32*r):], 32*r) + blockMix(&tmp, y, x, r) + } + j = 0 + for _, v := range x[:32*r] { + b[j+0] = byte(v >> 0) + b[j+1] = byte(v >> 8) + b[j+2] = byte(v >> 16) + b[j+3] = byte(v >> 24) + j += 4 + } +} + +// Key derives a key from the password, salt, and cost parameters, returning +// a byte slice of length keyLen that can be used as cryptographic key. +// +// N is a CPU/memory cost parameter, which must be a power of two greater than 1. +// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the +// limits, the function returns a nil byte slice and an error. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a +// 32-byte key) by doing: +// +// dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32) +// +// The recommended parameters for interactive logins as of 2017 are N=32768, r=8 +// and p=1. The parameters N, r, and p should be increased as memory latency and +// CPU parallelism increases; consider setting N to the highest power of 2 you +// can derive within 100 milliseconds. Remember to get a good random salt. +func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { + if N <= 1 || N&(N-1) != 0 { + return nil, errors.New("scrypt: N must be > 1 and a power of 2") + } + if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r { + return nil, errors.New("scrypt: parameters are too large") + } + + xy := make([]uint32, 64*r) + v := make([]uint32, 32*N*r) + b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New) + + for i := 0; i < p; i++ { + smix(b[i*128*r:], r, N, v, xy) + } + + return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil +} diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go new file mode 100644 index 00000000..b6cbc5c4 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go @@ -0,0 +1,284 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !gccgo,!appengine + +package sha3 + +// This file contains code for using the 'compute intermediate +// message digest' (KIMD) and 'compute last message digest' (KLMD) +// instructions to compute SHA-3 and SHAKE hashes on IBM Z. + +import ( + "hash" + + "golang.org/x/sys/cpu" +) + +// codes represent 7-bit KIMD/KLMD function codes as defined in +// the Principles of Operation. +type code uint64 + +const ( + // function codes for KIMD/KLMD + sha3_224 code = 32 + sha3_256 = 33 + sha3_384 = 34 + sha3_512 = 35 + shake_128 = 36 + shake_256 = 37 + nopad = 0x100 +) + +// kimd is a wrapper for the 'compute intermediate message digest' instruction. +// src must be a multiple of the rate for the given function code. +//go:noescape +func kimd(function code, chain *[200]byte, src []byte) + +// klmd is a wrapper for the 'compute last message digest' instruction. +// src padding is handled by the instruction. +//go:noescape +func klmd(function code, chain *[200]byte, dst, src []byte) + +type asmState struct { + a [200]byte // 1600 bit state + buf []byte // care must be taken to ensure cap(buf) is a multiple of rate + rate int // equivalent to block size + storage [3072]byte // underlying storage for buf + outputLen int // output length if fixed, 0 if not + function code // KIMD/KLMD function code + state spongeDirection // whether the sponge is absorbing or squeezing +} + +func newAsmState(function code) *asmState { + var s asmState + s.function = function + switch function { + case sha3_224: + s.rate = 144 + s.outputLen = 28 + case sha3_256: + s.rate = 136 + s.outputLen = 32 + case sha3_384: + s.rate = 104 + s.outputLen = 48 + case sha3_512: + s.rate = 72 + s.outputLen = 64 + case shake_128: + s.rate = 168 + case shake_256: + s.rate = 136 + default: + panic("sha3: unrecognized function code") + } + + // limit s.buf size to a multiple of s.rate + s.resetBuf() + return &s +} + +func (s *asmState) clone() *asmState { + c := *s + c.buf = c.storage[:len(s.buf):cap(s.buf)] + return &c +} + +// copyIntoBuf copies b into buf. It will panic if there is not enough space to +// store all of b. +func (s *asmState) copyIntoBuf(b []byte) { + bufLen := len(s.buf) + s.buf = s.buf[:len(s.buf)+len(b)] + copy(s.buf[bufLen:], b) +} + +// resetBuf points buf at storage, sets the length to 0 and sets cap to be a +// multiple of the rate. +func (s *asmState) resetBuf() { + max := (cap(s.storage) / s.rate) * s.rate + s.buf = s.storage[:0:max] +} + +// Write (via the embedded io.Writer interface) adds more data to the running hash. +// It never returns an error. +func (s *asmState) Write(b []byte) (int, error) { + if s.state != spongeAbsorbing { + panic("sha3: write to sponge after read") + } + length := len(b) + for len(b) > 0 { + if len(s.buf) == 0 && len(b) >= cap(s.buf) { + // Hash the data directly and push any remaining bytes + // into the buffer. + remainder := len(s.buf) % s.rate + kimd(s.function, &s.a, b[:len(b)-remainder]) + if remainder != 0 { + s.copyIntoBuf(b[len(b)-remainder:]) + } + return length, nil + } + + if len(s.buf) == cap(s.buf) { + // flush the buffer + kimd(s.function, &s.a, s.buf) + s.buf = s.buf[:0] + } + + // copy as much as we can into the buffer + n := len(b) + if len(b) > cap(s.buf)-len(s.buf) { + n = cap(s.buf) - len(s.buf) + } + s.copyIntoBuf(b[:n]) + b = b[n:] + } + return length, nil +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (s *asmState) Read(out []byte) (n int, err error) { + n = len(out) + + // need to pad if we were absorbing + if s.state == spongeAbsorbing { + s.state = spongeSqueezing + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function, &s.a, out, s.buf) // len(out) may be 0 + s.buf = s.buf[:0] + return + } + + // write hash into buffer + max := cap(s.buf) + if max > len(out) { + max = (len(out)/s.rate)*s.rate + s.rate + } + klmd(s.function, &s.a, s.buf[:max], s.buf) + s.buf = s.buf[:max] + } + + for len(out) > 0 { + // flush the buffer + if len(s.buf) != 0 { + c := copy(out, s.buf) + out = out[c:] + s.buf = s.buf[c:] + continue + } + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function|nopad, &s.a, out, nil) + return + } + + // write hash into buffer + s.resetBuf() + if cap(s.buf) > len(out) { + s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate] + } + klmd(s.function|nopad, &s.a, s.buf, nil) + } + return +} + +// Sum appends the current hash to b and returns the resulting slice. +// It does not change the underlying hash state. +func (s *asmState) Sum(b []byte) []byte { + if s.outputLen == 0 { + panic("sha3: cannot call Sum on SHAKE functions") + } + + // Copy the state to preserve the original. + a := s.a + + // Hash the buffer. Note that we don't clear it because we + // aren't updating the state. + klmd(s.function, &a, nil, s.buf) + return append(b, a[:s.outputLen]...) +} + +// Reset resets the Hash to its initial state. +func (s *asmState) Reset() { + for i := range s.a { + s.a[i] = 0 + } + s.resetBuf() + s.state = spongeAbsorbing +} + +// Size returns the number of bytes Sum will return. +func (s *asmState) Size() int { + return s.outputLen +} + +// BlockSize returns the hash's underlying block size. +// The Write method must be able to accept any amount +// of data, but it may operate more efficiently if all writes +// are a multiple of the block size. +func (s *asmState) BlockSize() int { + return s.rate +} + +// Clone returns a copy of the ShakeHash in its current state. +func (s *asmState) Clone() ShakeHash { + return s.clone() +} + +// new224Asm returns an assembly implementation of SHA3-224 if available, +// otherwise it returns nil. +func new224Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_224) + } + return nil +} + +// new256Asm returns an assembly implementation of SHA3-256 if available, +// otherwise it returns nil. +func new256Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_256) + } + return nil +} + +// new384Asm returns an assembly implementation of SHA3-384 if available, +// otherwise it returns nil. +func new384Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_384) + } + return nil +} + +// new512Asm returns an assembly implementation of SHA3-512 if available, +// otherwise it returns nil. +func new512Asm() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_512) + } + return nil +} + +// newShake128Asm returns an assembly implementation of SHAKE-128 if available, +// otherwise it returns nil. +func newShake128Asm() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_128) + } + return nil +} + +// newShake256Asm returns an assembly implementation of SHAKE-256 if available, +// otherwise it returns nil. +func newShake256Asm() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_256) + } + return nil +} diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s new file mode 100644 index 00000000..b2ef69f8 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s @@ -0,0 +1,33 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !gccgo,!appengine + +#include "textflag.h" + +// func kimd(function code, chain *[200]byte, src []byte) +TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40 + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG src+16(FP), R2, R3 // R2=base, R3=len + +continue: + WORD $0xB93E0002 // KIMD --, R2 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET + +// func klmd(function code, chain *[200]byte, dst, src []byte) +TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64 + // TODO: SHAKE support + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG dst+16(FP), R2, R3 // R2=base, R3=len + LMG src+40(FP), R4, R5 // R4=base, R5=len + +continue: + WORD $0xB93F0024 // KLMD R2, R4 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go new file mode 100644 index 00000000..d7be2954 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -0,0 +1,173 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sha3 + +// This file defines the ShakeHash interface, and provides +// functions for creating SHAKE and cSHAKE instances, as well as utility +// functions for hashing bytes to arbitrary-length output. +// +// +// SHAKE implementation is based on FIPS PUB 202 [1] +// cSHAKE implementations is based on NIST SP 800-185 [2] +// +// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +// [2] https://doi.org/10.6028/NIST.SP.800-185 + +import ( + "encoding/binary" + "io" +) + +// ShakeHash defines the interface to hash functions that +// support arbitrary-length output. +type ShakeHash interface { + // Write absorbs more data into the hash's state. It panics if input is + // written to it after output has been read from it. + io.Writer + + // Read reads more output from the hash; reading affects the hash's + // state. (ShakeHash.Read is thus very different from Hash.Sum) + // It never returns an error. + io.Reader + + // Clone returns a copy of the ShakeHash in its current state. + Clone() ShakeHash + + // Reset resets the ShakeHash to its initial state. + Reset() +} + +// cSHAKE specific context +type cshakeState struct { + *state // SHA-3 state context and Read/Write operations + + // initBlock is the cSHAKE specific initialization set of bytes. It is initialized + // by newCShake function and stores concatenation of N followed by S, encoded + // by the method specified in 3.3 of [1]. + // It is stored here in order for Reset() to be able to put context into + // initial state. + initBlock []byte +} + +// Consts for configuring initial SHA-3 state +const ( + dsbyteShake = 0x1f + dsbyteCShake = 0x04 + rate128 = 168 + rate256 = 136 +) + +func bytepad(input []byte, w int) []byte { + // leftEncode always returns max 9 bytes + buf := make([]byte, 0, 9+len(input)+w) + buf = append(buf, leftEncode(uint64(w))...) + buf = append(buf, input...) + padlen := w - (len(buf) % w) + return append(buf, make([]byte, padlen)...) +} + +func leftEncode(value uint64) []byte { + var b [9]byte + binary.BigEndian.PutUint64(b[1:], value) + // Trim all but last leading zero bytes + i := byte(1) + for i < 8 && b[i] == 0 { + i++ + } + // Prepend number of encoded bytes + b[i-1] = 9 - i + return b[i-1:] +} + +func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash { + c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}} + + // leftEncode returns max 9 bytes + c.initBlock = make([]byte, 0, 9*2+len(N)+len(S)) + c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...) + c.initBlock = append(c.initBlock, N...) + c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...) + c.initBlock = append(c.initBlock, S...) + c.Write(bytepad(c.initBlock, c.rate)) + return &c +} + +// Reset resets the hash to initial state. +func (c *cshakeState) Reset() { + c.state.Reset() + c.Write(bytepad(c.initBlock, c.rate)) +} + +// Clone returns copy of a cSHAKE context within its current state. +func (c *cshakeState) Clone() ShakeHash { + b := make([]byte, len(c.initBlock)) + copy(b, c.initBlock) + return &cshakeState{state: c.clone(), initBlock: b} +} + +// Clone returns copy of SHAKE context within its current state. +func (c *state) Clone() ShakeHash { + return c.clone() +} + +// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. +// Its generic security strength is 128 bits against all attacks if at +// least 32 bytes of its output are used. +func NewShake128() ShakeHash { + if h := newShake128Asm(); h != nil { + return h + } + return &state{rate: rate128, dsbyte: dsbyteShake} +} + +// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. +// Its generic security strength is 256 bits against all attacks if +// at least 64 bytes of its output are used. +func NewShake256() ShakeHash { + if h := newShake256Asm(); h != nil { + return h + } + return &state{rate: rate256, dsbyte: dsbyteShake} +} + +// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash, +// a customizable variant of SHAKE128. +// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is +// desired. S is a customization byte string used for domain separation - two cSHAKE +// computations on same input with different S yield unrelated outputs. +// When N and S are both empty, this is equivalent to NewShake128. +func NewCShake128(N, S []byte) ShakeHash { + if len(N) == 0 && len(S) == 0 { + return NewShake128() + } + return newCShake(N, S, rate128, dsbyteCShake) +} + +// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash, +// a customizable variant of SHAKE256. +// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is +// desired. S is a customization byte string used for domain separation - two cSHAKE +// computations on same input with different S yield unrelated outputs. +// When N and S are both empty, this is equivalent to NewShake256. +func NewCShake256(N, S []byte) ShakeHash { + if len(N) == 0 && len(S) == 0 { + return NewShake256() + } + return newCShake(N, S, rate256, dsbyteCShake) +} + +// ShakeSum128 writes an arbitrary-length digest of data into hash. +func ShakeSum128(hash, data []byte) { + h := NewShake128() + h.Write(data) + h.Read(hash) +} + +// ShakeSum256 writes an arbitrary-length digest of data into hash. +func ShakeSum256(hash, data []byte) { + h := NewShake256() + h.Write(data) + h.Read(hash) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go new file mode 100644 index 00000000..2f04ee5b --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go @@ -0,0 +1,966 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package terminal + +import ( + "bytes" + "io" + "strconv" + "sync" + "unicode/utf8" +) + +// EscapeCodes contains escape sequences that can be written to the terminal in +// order to achieve different styles of text. +type EscapeCodes struct { + // Foreground colors + Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte + + // Reset all attributes + Reset []byte +} + +var vt100EscapeCodes = EscapeCodes{ + Black: []byte{keyEscape, '[', '3', '0', 'm'}, + Red: []byte{keyEscape, '[', '3', '1', 'm'}, + Green: []byte{keyEscape, '[', '3', '2', 'm'}, + Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, + Blue: []byte{keyEscape, '[', '3', '4', 'm'}, + Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, + Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, + White: []byte{keyEscape, '[', '3', '7', 'm'}, + + Reset: []byte{keyEscape, '[', '0', 'm'}, +} + +// Terminal contains the state for running a VT100 terminal that is capable of +// reading lines of input. +type Terminal struct { + // AutoCompleteCallback, if non-null, is called for each keypress with + // the full input line and the current position of the cursor (in + // bytes, as an index into |line|). If it returns ok=false, the key + // press is processed normally. Otherwise it returns a replacement line + // and the new cursor position. + AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) + + // Escape contains a pointer to the escape codes for this terminal. + // It's always a valid pointer, although the escape codes themselves + // may be empty if the terminal doesn't support them. + Escape *EscapeCodes + + // lock protects the terminal and the state in this object from + // concurrent processing of a key press and a Write() call. + lock sync.Mutex + + c io.ReadWriter + prompt []rune + + // line is the current line being entered. + line []rune + // pos is the logical position of the cursor in line + pos int + // echo is true if local echo is enabled + echo bool + // pasteActive is true iff there is a bracketed paste operation in + // progress. + pasteActive bool + + // cursorX contains the current X value of the cursor where the left + // edge is 0. cursorY contains the row number where the first row of + // the current line is 0. + cursorX, cursorY int + // maxLine is the greatest value of cursorY so far. + maxLine int + + termWidth, termHeight int + + // outBuf contains the terminal data to be sent. + outBuf []byte + // remainder contains the remainder of any partial key sequences after + // a read. It aliases into inBuf. + remainder []byte + inBuf [256]byte + + // history contains previously entered commands so that they can be + // accessed with the up and down keys. + history stRingBuffer + // historyIndex stores the currently accessed history entry, where zero + // means the immediately previous entry. + historyIndex int + // When navigating up and down the history it's possible to return to + // the incomplete, initial line. That value is stored in + // historyPending. + historyPending string +} + +// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is +// a local terminal, that terminal must first have been put into raw mode. +// prompt is a string that is written at the start of each input line (i.e. +// "> "). +func NewTerminal(c io.ReadWriter, prompt string) *Terminal { + return &Terminal{ + Escape: &vt100EscapeCodes, + c: c, + prompt: []rune(prompt), + termWidth: 80, + termHeight: 24, + echo: true, + historyIndex: -1, + } +} + +const ( + keyCtrlD = 4 + keyCtrlU = 21 + keyEnter = '\r' + keyEscape = 27 + keyBackspace = 127 + keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota + keyUp + keyDown + keyLeft + keyRight + keyAltLeft + keyAltRight + keyHome + keyEnd + keyDeleteWord + keyDeleteLine + keyClearScreen + keyPasteStart + keyPasteEnd +) + +var ( + crlf = []byte{'\r', '\n'} + pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} + pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} +) + +// bytesToKey tries to parse a key sequence from b. If successful, it returns +// the key and the remainder of the input. Otherwise it returns utf8.RuneError. +func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { + if len(b) == 0 { + return utf8.RuneError, nil + } + + if !pasteActive { + switch b[0] { + case 1: // ^A + return keyHome, b[1:] + case 5: // ^E + return keyEnd, b[1:] + case 8: // ^H + return keyBackspace, b[1:] + case 11: // ^K + return keyDeleteLine, b[1:] + case 12: // ^L + return keyClearScreen, b[1:] + case 23: // ^W + return keyDeleteWord, b[1:] + case 14: // ^N + return keyDown, b[1:] + case 16: // ^P + return keyUp, b[1:] + } + } + + if b[0] != keyEscape { + if !utf8.FullRune(b) { + return utf8.RuneError, b + } + r, l := utf8.DecodeRune(b) + return r, b[l:] + } + + if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { + switch b[2] { + case 'A': + return keyUp, b[3:] + case 'B': + return keyDown, b[3:] + case 'C': + return keyRight, b[3:] + case 'D': + return keyLeft, b[3:] + case 'H': + return keyHome, b[3:] + case 'F': + return keyEnd, b[3:] + } + } + + if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { + switch b[5] { + case 'C': + return keyAltRight, b[6:] + case 'D': + return keyAltLeft, b[6:] + } + } + + if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { + return keyPasteStart, b[6:] + } + + if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { + return keyPasteEnd, b[6:] + } + + // If we get here then we have a key that we don't recognise, or a + // partial sequence. It's not clear how one should find the end of a + // sequence without knowing them all, but it seems that [a-zA-Z~] only + // appears at the end of a sequence. + for i, c := range b[0:] { + if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { + return keyUnknown, b[i+1:] + } + } + + return utf8.RuneError, b +} + +// queue appends data to the end of t.outBuf +func (t *Terminal) queue(data []rune) { + t.outBuf = append(t.outBuf, []byte(string(data))...) +} + +var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} +var space = []rune{' '} + +func isPrintable(key rune) bool { + isInSurrogateArea := key >= 0xd800 && key <= 0xdbff + return key >= 32 && !isInSurrogateArea +} + +// moveCursorToPos appends data to t.outBuf which will move the cursor to the +// given, logical position in the text. +func (t *Terminal) moveCursorToPos(pos int) { + if !t.echo { + return + } + + x := visualLength(t.prompt) + pos + y := x / t.termWidth + x = x % t.termWidth + + up := 0 + if y < t.cursorY { + up = t.cursorY - y + } + + down := 0 + if y > t.cursorY { + down = y - t.cursorY + } + + left := 0 + if x < t.cursorX { + left = t.cursorX - x + } + + right := 0 + if x > t.cursorX { + right = x - t.cursorX + } + + t.cursorX = x + t.cursorY = y + t.move(up, down, left, right) +} + +func (t *Terminal) move(up, down, left, right int) { + m := []rune{} + + // 1 unit up can be expressed as ^[[A or ^[A + // 5 units up can be expressed as ^[[5A + + if up == 1 { + m = append(m, keyEscape, '[', 'A') + } else if up > 1 { + m = append(m, keyEscape, '[') + m = append(m, []rune(strconv.Itoa(up))...) + m = append(m, 'A') + } + + if down == 1 { + m = append(m, keyEscape, '[', 'B') + } else if down > 1 { + m = append(m, keyEscape, '[') + m = append(m, []rune(strconv.Itoa(down))...) + m = append(m, 'B') + } + + if right == 1 { + m = append(m, keyEscape, '[', 'C') + } else if right > 1 { + m = append(m, keyEscape, '[') + m = append(m, []rune(strconv.Itoa(right))...) + m = append(m, 'C') + } + + if left == 1 { + m = append(m, keyEscape, '[', 'D') + } else if left > 1 { + m = append(m, keyEscape, '[') + m = append(m, []rune(strconv.Itoa(left))...) + m = append(m, 'D') + } + + t.queue(m) +} + +func (t *Terminal) clearLineToRight() { + op := []rune{keyEscape, '[', 'K'} + t.queue(op) +} + +const maxLineLength = 4096 + +func (t *Terminal) setLine(newLine []rune, newPos int) { + if t.echo { + t.moveCursorToPos(0) + t.writeLine(newLine) + for i := len(newLine); i < len(t.line); i++ { + t.writeLine(space) + } + t.moveCursorToPos(newPos) + } + t.line = newLine + t.pos = newPos +} + +func (t *Terminal) advanceCursor(places int) { + t.cursorX += places + t.cursorY += t.cursorX / t.termWidth + if t.cursorY > t.maxLine { + t.maxLine = t.cursorY + } + t.cursorX = t.cursorX % t.termWidth + + if places > 0 && t.cursorX == 0 { + // Normally terminals will advance the current position + // when writing a character. But that doesn't happen + // for the last character in a line. However, when + // writing a character (except a new line) that causes + // a line wrap, the position will be advanced two + // places. + // + // So, if we are stopping at the end of a line, we + // need to write a newline so that our cursor can be + // advanced to the next line. + t.outBuf = append(t.outBuf, '\r', '\n') + } +} + +func (t *Terminal) eraseNPreviousChars(n int) { + if n == 0 { + return + } + + if t.pos < n { + n = t.pos + } + t.pos -= n + t.moveCursorToPos(t.pos) + + copy(t.line[t.pos:], t.line[n+t.pos:]) + t.line = t.line[:len(t.line)-n] + if t.echo { + t.writeLine(t.line[t.pos:]) + for i := 0; i < n; i++ { + t.queue(space) + } + t.advanceCursor(n) + t.moveCursorToPos(t.pos) + } +} + +// countToLeftWord returns then number of characters from the cursor to the +// start of the previous word. +func (t *Terminal) countToLeftWord() int { + if t.pos == 0 { + return 0 + } + + pos := t.pos - 1 + for pos > 0 { + if t.line[pos] != ' ' { + break + } + pos-- + } + for pos > 0 { + if t.line[pos] == ' ' { + pos++ + break + } + pos-- + } + + return t.pos - pos +} + +// countToRightWord returns then number of characters from the cursor to the +// start of the next word. +func (t *Terminal) countToRightWord() int { + pos := t.pos + for pos < len(t.line) { + if t.line[pos] == ' ' { + break + } + pos++ + } + for pos < len(t.line) { + if t.line[pos] != ' ' { + break + } + pos++ + } + return pos - t.pos +} + +// visualLength returns the number of visible glyphs in s. +func visualLength(runes []rune) int { + inEscapeSeq := false + length := 0 + + for _, r := range runes { + switch { + case inEscapeSeq: + if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { + inEscapeSeq = false + } + case r == '\x1b': + inEscapeSeq = true + default: + length++ + } + } + + return length +} + +// handleKey processes the given key and, optionally, returns a line of text +// that the user has entered. +func (t *Terminal) handleKey(key rune) (line string, ok bool) { + if t.pasteActive && key != keyEnter { + t.addKeyToLine(key) + return + } + + switch key { + case keyBackspace: + if t.pos == 0 { + return + } + t.eraseNPreviousChars(1) + case keyAltLeft: + // move left by a word. + t.pos -= t.countToLeftWord() + t.moveCursorToPos(t.pos) + case keyAltRight: + // move right by a word. + t.pos += t.countToRightWord() + t.moveCursorToPos(t.pos) + case keyLeft: + if t.pos == 0 { + return + } + t.pos-- + t.moveCursorToPos(t.pos) + case keyRight: + if t.pos == len(t.line) { + return + } + t.pos++ + t.moveCursorToPos(t.pos) + case keyHome: + if t.pos == 0 { + return + } + t.pos = 0 + t.moveCursorToPos(t.pos) + case keyEnd: + if t.pos == len(t.line) { + return + } + t.pos = len(t.line) + t.moveCursorToPos(t.pos) + case keyUp: + entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) + if !ok { + return "", false + } + if t.historyIndex == -1 { + t.historyPending = string(t.line) + } + t.historyIndex++ + runes := []rune(entry) + t.setLine(runes, len(runes)) + case keyDown: + switch t.historyIndex { + case -1: + return + case 0: + runes := []rune(t.historyPending) + t.setLine(runes, len(runes)) + t.historyIndex-- + default: + entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) + if ok { + t.historyIndex-- + runes := []rune(entry) + t.setLine(runes, len(runes)) + } + } + case keyEnter: + t.moveCursorToPos(len(t.line)) + t.queue([]rune("\r\n")) + line = string(t.line) + ok = true + t.line = t.line[:0] + t.pos = 0 + t.cursorX = 0 + t.cursorY = 0 + t.maxLine = 0 + case keyDeleteWord: + // Delete zero or more spaces and then one or more characters. + t.eraseNPreviousChars(t.countToLeftWord()) + case keyDeleteLine: + // Delete everything from the current cursor position to the + // end of line. + for i := t.pos; i < len(t.line); i++ { + t.queue(space) + t.advanceCursor(1) + } + t.line = t.line[:t.pos] + t.moveCursorToPos(t.pos) + case keyCtrlD: + // Erase the character under the current position. + // The EOF case when the line is empty is handled in + // readLine(). + if t.pos < len(t.line) { + t.pos++ + t.eraseNPreviousChars(1) + } + case keyCtrlU: + t.eraseNPreviousChars(t.pos) + case keyClearScreen: + // Erases the screen and moves the cursor to the home position. + t.queue([]rune("\x1b[2J\x1b[H")) + t.queue(t.prompt) + t.cursorX, t.cursorY = 0, 0 + t.advanceCursor(visualLength(t.prompt)) + t.setLine(t.line, t.pos) + default: + if t.AutoCompleteCallback != nil { + prefix := string(t.line[:t.pos]) + suffix := string(t.line[t.pos:]) + + t.lock.Unlock() + newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) + t.lock.Lock() + + if completeOk { + t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) + return + } + } + if !isPrintable(key) { + return + } + if len(t.line) == maxLineLength { + return + } + t.addKeyToLine(key) + } + return +} + +// addKeyToLine inserts the given key at the current position in the current +// line. +func (t *Terminal) addKeyToLine(key rune) { + if len(t.line) == cap(t.line) { + newLine := make([]rune, len(t.line), 2*(1+len(t.line))) + copy(newLine, t.line) + t.line = newLine + } + t.line = t.line[:len(t.line)+1] + copy(t.line[t.pos+1:], t.line[t.pos:]) + t.line[t.pos] = key + if t.echo { + t.writeLine(t.line[t.pos:]) + } + t.pos++ + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) writeLine(line []rune) { + for len(line) != 0 { + remainingOnLine := t.termWidth - t.cursorX + todo := len(line) + if todo > remainingOnLine { + todo = remainingOnLine + } + t.queue(line[:todo]) + t.advanceCursor(visualLength(line[:todo])) + line = line[todo:] + } +} + +// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n. +func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) { + for len(buf) > 0 { + i := bytes.IndexByte(buf, '\n') + todo := len(buf) + if i >= 0 { + todo = i + } + + var nn int + nn, err = w.Write(buf[:todo]) + n += nn + if err != nil { + return n, err + } + buf = buf[todo:] + + if i >= 0 { + if _, err = w.Write(crlf); err != nil { + return n, err + } + n++ + buf = buf[1:] + } + } + + return n, nil +} + +func (t *Terminal) Write(buf []byte) (n int, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + if t.cursorX == 0 && t.cursorY == 0 { + // This is the easy case: there's nothing on the screen that we + // have to move out of the way. + return writeWithCRLF(t.c, buf) + } + + // We have a prompt and possibly user input on the screen. We + // have to clear it first. + t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) + t.cursorX = 0 + t.clearLineToRight() + + for t.cursorY > 0 { + t.move(1 /* up */, 0, 0, 0) + t.cursorY-- + t.clearLineToRight() + } + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + + if n, err = writeWithCRLF(t.c, buf); err != nil { + return + } + + t.writeLine(t.prompt) + if t.echo { + t.writeLine(t.line) + } + + t.moveCursorToPos(t.pos) + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + return +} + +// ReadPassword temporarily changes the prompt and reads a password, without +// echo, from the terminal. +func (t *Terminal) ReadPassword(prompt string) (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + oldPrompt := t.prompt + t.prompt = []rune(prompt) + t.echo = false + + line, err = t.readLine() + + t.prompt = oldPrompt + t.echo = true + + return +} + +// ReadLine returns a line of input from the terminal. +func (t *Terminal) ReadLine() (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + return t.readLine() +} + +func (t *Terminal) readLine() (line string, err error) { + // t.lock must be held at this point + + if t.cursorX == 0 && t.cursorY == 0 { + t.writeLine(t.prompt) + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + } + + lineIsPasted := t.pasteActive + + for { + rest := t.remainder + lineOk := false + for !lineOk { + var key rune + key, rest = bytesToKey(rest, t.pasteActive) + if key == utf8.RuneError { + break + } + if !t.pasteActive { + if key == keyCtrlD { + if len(t.line) == 0 { + return "", io.EOF + } + } + if key == keyPasteStart { + t.pasteActive = true + if len(t.line) == 0 { + lineIsPasted = true + } + continue + } + } else if key == keyPasteEnd { + t.pasteActive = false + continue + } + if !t.pasteActive { + lineIsPasted = false + } + line, lineOk = t.handleKey(key) + } + if len(rest) > 0 { + n := copy(t.inBuf[:], rest) + t.remainder = t.inBuf[:n] + } else { + t.remainder = nil + } + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + if lineOk { + if t.echo { + t.historyIndex = -1 + t.history.Add(line) + } + if lineIsPasted { + err = ErrPasteIndicator + } + return + } + + // t.remainder is a slice at the beginning of t.inBuf + // containing a partial key sequence + readBuf := t.inBuf[len(t.remainder):] + var n int + + t.lock.Unlock() + n, err = t.c.Read(readBuf) + t.lock.Lock() + + if err != nil { + return + } + + t.remainder = t.inBuf[:n+len(t.remainder)] + } +} + +// SetPrompt sets the prompt to be used when reading subsequent lines. +func (t *Terminal) SetPrompt(prompt string) { + t.lock.Lock() + defer t.lock.Unlock() + + t.prompt = []rune(prompt) +} + +func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { + // Move cursor to column zero at the start of the line. + t.move(t.cursorY, 0, t.cursorX, 0) + t.cursorX, t.cursorY = 0, 0 + t.clearLineToRight() + for t.cursorY < numPrevLines { + // Move down a line + t.move(0, 1, 0, 0) + t.cursorY++ + t.clearLineToRight() + } + // Move back to beginning. + t.move(t.cursorY, 0, 0, 0) + t.cursorX, t.cursorY = 0, 0 + + t.queue(t.prompt) + t.advanceCursor(visualLength(t.prompt)) + t.writeLine(t.line) + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) SetSize(width, height int) error { + t.lock.Lock() + defer t.lock.Unlock() + + if width == 0 { + width = 1 + } + + oldWidth := t.termWidth + t.termWidth, t.termHeight = width, height + + switch { + case width == oldWidth: + // If the width didn't change then nothing else needs to be + // done. + return nil + case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: + // If there is nothing on current line and no prompt printed, + // just do nothing + return nil + case width < oldWidth: + // Some terminals (e.g. xterm) will truncate lines that were + // too long when shinking. Others, (e.g. gnome-terminal) will + // attempt to wrap them. For the former, repainting t.maxLine + // works great, but that behaviour goes badly wrong in the case + // of the latter because they have doubled every full line. + + // We assume that we are working on a terminal that wraps lines + // and adjust the cursor position based on every previous line + // wrapping and turning into two. This causes the prompt on + // xterms to move upwards, which isn't great, but it avoids a + // huge mess with gnome-terminal. + if t.cursorX >= t.termWidth { + t.cursorX = t.termWidth - 1 + } + t.cursorY *= 2 + t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) + case width > oldWidth: + // If the terminal expands then our position calculations will + // be wrong in the future because we think the cursor is + // |t.pos| chars into the string, but there will be a gap at + // the end of any wrapped line. + // + // But the position will actually be correct until we move, so + // we can move back to the beginning and repaint everything. + t.clearAndRepaintLinePlusNPrevious(t.maxLine) + } + + _, err := t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + return err +} + +type pasteIndicatorError struct{} + +func (pasteIndicatorError) Error() string { + return "terminal: ErrPasteIndicator not correctly handled" +} + +// ErrPasteIndicator may be returned from ReadLine as the error, in addition +// to valid line data. It indicates that bracketed paste mode is enabled and +// that the returned line consists only of pasted data. Programs may wish to +// interpret pasted data more literally than typed data. +var ErrPasteIndicator = pasteIndicatorError{} + +// SetBracketedPasteMode requests that the terminal bracket paste operations +// with markers. Not all terminals support this but, if it is supported, then +// enabling this mode will stop any autocomplete callback from running due to +// pastes. Additionally, any lines that are completely pasted will be returned +// from ReadLine with the error set to ErrPasteIndicator. +func (t *Terminal) SetBracketedPasteMode(on bool) { + if on { + io.WriteString(t.c, "\x1b[?2004h") + } else { + io.WriteString(t.c, "\x1b[?2004l") + } +} + +// stRingBuffer is a ring buffer of strings. +type stRingBuffer struct { + // entries contains max elements. + entries []string + max int + // head contains the index of the element most recently added to the ring. + head int + // size contains the number of elements in the ring. + size int +} + +func (s *stRingBuffer) Add(a string) { + if s.entries == nil { + const defaultNumEntries = 100 + s.entries = make([]string, defaultNumEntries) + s.max = defaultNumEntries + } + + s.head = (s.head + 1) % s.max + s.entries[s.head] = a + if s.size < s.max { + s.size++ + } +} + +// NthPreviousEntry returns the value passed to the nth previous call to Add. +// If n is zero then the immediately prior value is returned, if one, then the +// next most recent, and so on. If such an element doesn't exist then ok is +// false. +func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { + if n >= s.size { + return "", false + } + index := s.head - n + if index < 0 { + index += s.max + } + return s.entries[index], true +} + +// readPasswordLine reads from reader until it finds \n or io.EOF. +// The slice returned does not include the \n. +// readPasswordLine also ignores any \r it finds. +func readPasswordLine(reader io.Reader) ([]byte, error) { + var buf [1]byte + var ret []byte + + for { + n, err := reader.Read(buf[:]) + if n > 0 { + switch buf[0] { + case '\n': + return ret, nil + case '\r': + // remove \r from passwords on Windows + default: + ret = append(ret, buf[0]) + } + continue + } + if err != nil { + if err == io.EOF && len(ret) > 0 { + return ret, nil + } + return ret, err + } + } +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go new file mode 100644 index 00000000..5cfdf8f3 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -0,0 +1,105 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal + +import ( + "os" + + "golang.org/x/sys/windows" +) + +type State struct { + mode uint32 +} + +// IsTerminal returns whether the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + var st uint32 + err := windows.GetConsoleMode(windows.Handle(fd), &st) + return err == nil +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { + return nil, err + } + return &State{st}, nil +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + return &State{st}, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + return windows.SetConsoleMode(windows.Handle(fd), state.mode) +} + +// GetSize returns the visible dimensions of the given terminal. +// +// These dimensions don't include any scrollback buffer height. +func GetSize(fd int) (width, height int, err error) { + var info windows.ConsoleScreenBufferInfo + if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { + return 0, 0, err + } + return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + var st uint32 + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err + } + old := st + + st &^= (windows.ENABLE_ECHO_INPUT) + st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil { + return nil, err + } + + defer windows.SetConsoleMode(windows.Handle(fd), old) + + var h windows.Handle + p, _ := windows.GetCurrentProcess() + if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil { + return nil, err + } + + f := os.NewFile(uintptr(h), "stdin") + defer f.Close() + return readPasswordLine(f) +} diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go new file mode 100644 index 00000000..12f3ee83 --- /dev/null +++ b/vendor/golang.org/x/net/bpf/constants.go @@ -0,0 +1,222 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bpf + +// A Register is a register of the BPF virtual machine. +type Register uint16 + +const ( + // RegA is the accumulator register. RegA is always the + // destination register of ALU operations. + RegA Register = iota + // RegX is the indirection register, used by LoadIndirect + // operations. + RegX +) + +// An ALUOp is an arithmetic or logic operation. +type ALUOp uint16 + +// ALU binary operation types. +const ( + ALUOpAdd ALUOp = iota << 4 + ALUOpSub + ALUOpMul + ALUOpDiv + ALUOpOr + ALUOpAnd + ALUOpShiftLeft + ALUOpShiftRight + aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type. + ALUOpMod + ALUOpXor +) + +// A JumpTest is a comparison operator used in conditional jumps. +type JumpTest uint16 + +// Supported operators for conditional jumps. +// K can be RegX for JumpIfX +const ( + // K == A + JumpEqual JumpTest = iota + // K != A + JumpNotEqual + // K > A + JumpGreaterThan + // K < A + JumpLessThan + // K >= A + JumpGreaterOrEqual + // K <= A + JumpLessOrEqual + // K & A != 0 + JumpBitsSet + // K & A == 0 + JumpBitsNotSet +) + +// An Extension is a function call provided by the kernel that +// performs advanced operations that are expensive or impossible +// within the BPF virtual machine. +// +// Extensions are only implemented by the Linux kernel. +// +// TODO: should we prune this list? Some of these extensions seem +// either broken or near-impossible to use correctly, whereas other +// (len, random, ifindex) are quite useful. +type Extension int + +// Extension functions available in the Linux kernel. +const ( + // extOffset is the negative maximum number of instructions used + // to load instructions by overloading the K argument. + extOffset = -0x1000 + // ExtLen returns the length of the packet. + ExtLen Extension = 1 + // ExtProto returns the packet's L3 protocol type. + ExtProto Extension = 0 + // ExtType returns the packet's type (skb->pkt_type in the kernel) + // + // TODO: better documentation. How nice an API do we want to + // provide for these esoteric extensions? + ExtType Extension = 4 + // ExtPayloadOffset returns the offset of the packet payload, or + // the first protocol header that the kernel does not know how to + // parse. + ExtPayloadOffset Extension = 52 + // ExtInterfaceIndex returns the index of the interface on which + // the packet was received. + ExtInterfaceIndex Extension = 8 + // ExtNetlinkAttr returns the netlink attribute of type X at + // offset A. + ExtNetlinkAttr Extension = 12 + // ExtNetlinkAttrNested returns the nested netlink attribute of + // type X at offset A. + ExtNetlinkAttrNested Extension = 16 + // ExtMark returns the packet's mark value. + ExtMark Extension = 20 + // ExtQueue returns the packet's assigned hardware queue. + ExtQueue Extension = 24 + // ExtLinkLayerType returns the packet's hardware address type + // (e.g. Ethernet, Infiniband). + ExtLinkLayerType Extension = 28 + // ExtRXHash returns the packets receive hash. + // + // TODO: figure out what this rxhash actually is. + ExtRXHash Extension = 32 + // ExtCPUID returns the ID of the CPU processing the current + // packet. + ExtCPUID Extension = 36 + // ExtVLANTag returns the packet's VLAN tag. + ExtVLANTag Extension = 44 + // ExtVLANTagPresent returns non-zero if the packet has a VLAN + // tag. + // + // TODO: I think this might be a lie: it reads bit 0x1000 of the + // VLAN header, which changed meaning in recent revisions of the + // spec - this extension may now return meaningless information. + ExtVLANTagPresent Extension = 48 + // ExtVLANProto returns 0x8100 if the frame has a VLAN header, + // 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some + // other value if no VLAN information is present. + ExtVLANProto Extension = 60 + // ExtRand returns a uniformly random uint32. + ExtRand Extension = 56 +) + +// The following gives names to various bit patterns used in opcode construction. + +const ( + opMaskCls uint16 = 0x7 + // opClsLoad masks + opMaskLoadDest = 0x01 + opMaskLoadWidth = 0x18 + opMaskLoadMode = 0xe0 + // opClsALU & opClsJump + opMaskOperand = 0x08 + opMaskOperator = 0xf0 +) + +const ( + // +---------------+-----------------+---+---+---+ + // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 | + // +---------------+-----------------+---+---+---+ + opClsLoadA uint16 = iota + // +---------------+-----------------+---+---+---+ + // | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 | + // +---------------+-----------------+---+---+---+ + opClsLoadX + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + // +---+---+---+---+---+---+---+---+ + opClsStoreA + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | + // +---+---+---+---+---+---+---+---+ + opClsStoreX + // +---------------+-----------------+---+---+---+ + // | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 | + // +---------------+-----------------+---+---+---+ + opClsALU + // +-----------------------------+---+---+---+---+ + // | TestOperator (4b) | 0 | 1 | 0 | 1 | + // +-----------------------------+---+---+---+---+ + opClsJump + // +---+-------------------------+---+---+---+---+ + // | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 | + // +---+-------------------------+---+---+---+---+ + opClsReturn + // +---+-------------------------+---+---+---+---+ + // | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 | + // +---+-------------------------+---+---+---+---+ + opClsMisc +) + +const ( + opAddrModeImmediate uint16 = iota << 5 + opAddrModeAbsolute + opAddrModeIndirect + opAddrModeScratch + opAddrModePacketLen // actually an extension, not an addressing mode. + opAddrModeMemShift +) + +const ( + opLoadWidth4 uint16 = iota << 3 + opLoadWidth2 + opLoadWidth1 +) + +// Operand for ALU and Jump instructions +type opOperand uint16 + +// Supported operand sources. +const ( + opOperandConstant opOperand = iota << 3 + opOperandX +) + +// An jumpOp is a conditional jump condition. +type jumpOp uint16 + +// Supported jump conditions. +const ( + opJumpAlways jumpOp = iota << 4 + opJumpEqual + opJumpGT + opJumpGE + opJumpSet +) + +const ( + opRetSrcConstant uint16 = iota << 4 + opRetSrcA +) + +const ( + opMiscTAX = 0x00 + opMiscTXA = 0x80 +) diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go new file mode 100644 index 00000000..3cffcaa0 --- /dev/null +++ b/vendor/golang.org/x/net/bpf/instructions.go @@ -0,0 +1,726 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bpf + +import "fmt" + +// An Instruction is one instruction executed by the BPF virtual +// machine. +type Instruction interface { + // Assemble assembles the Instruction into a RawInstruction. + Assemble() (RawInstruction, error) +} + +// A RawInstruction is a raw BPF virtual machine instruction. +type RawInstruction struct { + // Operation to execute. + Op uint16 + // For conditional jump instructions, the number of instructions + // to skip if the condition is true/false. + Jt uint8 + Jf uint8 + // Constant parameter. The meaning depends on the Op. + K uint32 +} + +// Assemble implements the Instruction Assemble method. +func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil } + +// Disassemble parses ri into an Instruction and returns it. If ri is +// not recognized by this package, ri itself is returned. +func (ri RawInstruction) Disassemble() Instruction { + switch ri.Op & opMaskCls { + case opClsLoadA, opClsLoadX: + reg := Register(ri.Op & opMaskLoadDest) + sz := 0 + switch ri.Op & opMaskLoadWidth { + case opLoadWidth4: + sz = 4 + case opLoadWidth2: + sz = 2 + case opLoadWidth1: + sz = 1 + default: + return ri + } + switch ri.Op & opMaskLoadMode { + case opAddrModeImmediate: + if sz != 4 { + return ri + } + return LoadConstant{Dst: reg, Val: ri.K} + case opAddrModeScratch: + if sz != 4 || ri.K > 15 { + return ri + } + return LoadScratch{Dst: reg, N: int(ri.K)} + case opAddrModeAbsolute: + if ri.K > extOffset+0xffffffff { + return LoadExtension{Num: Extension(-extOffset + ri.K)} + } + return LoadAbsolute{Size: sz, Off: ri.K} + case opAddrModeIndirect: + return LoadIndirect{Size: sz, Off: ri.K} + case opAddrModePacketLen: + if sz != 4 { + return ri + } + return LoadExtension{Num: ExtLen} + case opAddrModeMemShift: + return LoadMemShift{Off: ri.K} + default: + return ri + } + + case opClsStoreA: + if ri.Op != opClsStoreA || ri.K > 15 { + return ri + } + return StoreScratch{Src: RegA, N: int(ri.K)} + + case opClsStoreX: + if ri.Op != opClsStoreX || ri.K > 15 { + return ri + } + return StoreScratch{Src: RegX, N: int(ri.K)} + + case opClsALU: + switch op := ALUOp(ri.Op & opMaskOperator); op { + case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor: + switch operand := opOperand(ri.Op & opMaskOperand); operand { + case opOperandX: + return ALUOpX{Op: op} + case opOperandConstant: + return ALUOpConstant{Op: op, Val: ri.K} + default: + return ri + } + case aluOpNeg: + return NegateA{} + default: + return ri + } + + case opClsJump: + switch op := jumpOp(ri.Op & opMaskOperator); op { + case opJumpAlways: + return Jump{Skip: ri.K} + case opJumpEqual, opJumpGT, opJumpGE, opJumpSet: + cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf) + switch operand := opOperand(ri.Op & opMaskOperand); operand { + case opOperandX: + return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse} + case opOperandConstant: + return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse} + default: + return ri + } + default: + return ri + } + + case opClsReturn: + switch ri.Op { + case opClsReturn | opRetSrcA: + return RetA{} + case opClsReturn | opRetSrcConstant: + return RetConstant{Val: ri.K} + default: + return ri + } + + case opClsMisc: + switch ri.Op { + case opClsMisc | opMiscTAX: + return TAX{} + case opClsMisc | opMiscTXA: + return TXA{} + default: + return ri + } + + default: + panic("unreachable") // switch is exhaustive on the bit pattern + } +} + +func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) { + var test JumpTest + + // Decode "fake" jump conditions that don't appear in machine code + // Ensures the Assemble -> Disassemble stage recreates the same instructions + // See https://github.com/golang/go/issues/18470 + if skipTrue == 0 { + switch op { + case opJumpEqual: + test = JumpNotEqual + case opJumpGT: + test = JumpLessOrEqual + case opJumpGE: + test = JumpLessThan + case opJumpSet: + test = JumpBitsNotSet + } + + return test, skipFalse, 0 + } + + switch op { + case opJumpEqual: + test = JumpEqual + case opJumpGT: + test = JumpGreaterThan + case opJumpGE: + test = JumpGreaterOrEqual + case opJumpSet: + test = JumpBitsSet + } + + return test, skipTrue, skipFalse +} + +// LoadConstant loads Val into register Dst. +type LoadConstant struct { + Dst Register + Val uint32 +} + +// Assemble implements the Instruction Assemble method. +func (a LoadConstant) Assemble() (RawInstruction, error) { + return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val) +} + +// String returns the instruction in assembler notation. +func (a LoadConstant) String() string { + switch a.Dst { + case RegA: + return fmt.Sprintf("ld #%d", a.Val) + case RegX: + return fmt.Sprintf("ldx #%d", a.Val) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// LoadScratch loads scratch[N] into register Dst. +type LoadScratch struct { + Dst Register + N int // 0-15 +} + +// Assemble implements the Instruction Assemble method. +func (a LoadScratch) Assemble() (RawInstruction, error) { + if a.N < 0 || a.N > 15 { + return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N) + } + return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N)) +} + +// String returns the instruction in assembler notation. +func (a LoadScratch) String() string { + switch a.Dst { + case RegA: + return fmt.Sprintf("ld M[%d]", a.N) + case RegX: + return fmt.Sprintf("ldx M[%d]", a.N) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// LoadAbsolute loads packet[Off:Off+Size] as an integer value into +// register A. +type LoadAbsolute struct { + Off uint32 + Size int // 1, 2 or 4 +} + +// Assemble implements the Instruction Assemble method. +func (a LoadAbsolute) Assemble() (RawInstruction, error) { + return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off) +} + +// String returns the instruction in assembler notation. +func (a LoadAbsolute) String() string { + switch a.Size { + case 1: // byte + return fmt.Sprintf("ldb [%d]", a.Off) + case 2: // half word + return fmt.Sprintf("ldh [%d]", a.Off) + case 4: // word + if a.Off > extOffset+0xffffffff { + return LoadExtension{Num: Extension(a.Off + 0x1000)}.String() + } + return fmt.Sprintf("ld [%d]", a.Off) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value +// into register A. +type LoadIndirect struct { + Off uint32 + Size int // 1, 2 or 4 +} + +// Assemble implements the Instruction Assemble method. +func (a LoadIndirect) Assemble() (RawInstruction, error) { + return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off) +} + +// String returns the instruction in assembler notation. +func (a LoadIndirect) String() string { + switch a.Size { + case 1: // byte + return fmt.Sprintf("ldb [x + %d]", a.Off) + case 2: // half word + return fmt.Sprintf("ldh [x + %d]", a.Off) + case 4: // word + return fmt.Sprintf("ld [x + %d]", a.Off) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// LoadMemShift multiplies the first 4 bits of the byte at packet[Off] +// by 4 and stores the result in register X. +// +// This instruction is mainly useful to load into X the length of an +// IPv4 packet header in a single instruction, rather than have to do +// the arithmetic on the header's first byte by hand. +type LoadMemShift struct { + Off uint32 +} + +// Assemble implements the Instruction Assemble method. +func (a LoadMemShift) Assemble() (RawInstruction, error) { + return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off) +} + +// String returns the instruction in assembler notation. +func (a LoadMemShift) String() string { + return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off) +} + +// LoadExtension invokes a linux-specific extension and stores the +// result in register A. +type LoadExtension struct { + Num Extension +} + +// Assemble implements the Instruction Assemble method. +func (a LoadExtension) Assemble() (RawInstruction, error) { + if a.Num == ExtLen { + return assembleLoad(RegA, 4, opAddrModePacketLen, 0) + } + return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num)) +} + +// String returns the instruction in assembler notation. +func (a LoadExtension) String() string { + switch a.Num { + case ExtLen: + return "ld #len" + case ExtProto: + return "ld #proto" + case ExtType: + return "ld #type" + case ExtPayloadOffset: + return "ld #poff" + case ExtInterfaceIndex: + return "ld #ifidx" + case ExtNetlinkAttr: + return "ld #nla" + case ExtNetlinkAttrNested: + return "ld #nlan" + case ExtMark: + return "ld #mark" + case ExtQueue: + return "ld #queue" + case ExtLinkLayerType: + return "ld #hatype" + case ExtRXHash: + return "ld #rxhash" + case ExtCPUID: + return "ld #cpu" + case ExtVLANTag: + return "ld #vlan_tci" + case ExtVLANTagPresent: + return "ld #vlan_avail" + case ExtVLANProto: + return "ld #vlan_tpid" + case ExtRand: + return "ld #rand" + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// StoreScratch stores register Src into scratch[N]. +type StoreScratch struct { + Src Register + N int // 0-15 +} + +// Assemble implements the Instruction Assemble method. +func (a StoreScratch) Assemble() (RawInstruction, error) { + if a.N < 0 || a.N > 15 { + return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N) + } + var op uint16 + switch a.Src { + case RegA: + op = opClsStoreA + case RegX: + op = opClsStoreX + default: + return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src) + } + + return RawInstruction{ + Op: op, + K: uint32(a.N), + }, nil +} + +// String returns the instruction in assembler notation. +func (a StoreScratch) String() string { + switch a.Src { + case RegA: + return fmt.Sprintf("st M[%d]", a.N) + case RegX: + return fmt.Sprintf("stx M[%d]", a.N) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// ALUOpConstant executes A = A Val. +type ALUOpConstant struct { + Op ALUOp + Val uint32 +} + +// Assemble implements the Instruction Assemble method. +func (a ALUOpConstant) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op), + K: a.Val, + }, nil +} + +// String returns the instruction in assembler notation. +func (a ALUOpConstant) String() string { + switch a.Op { + case ALUOpAdd: + return fmt.Sprintf("add #%d", a.Val) + case ALUOpSub: + return fmt.Sprintf("sub #%d", a.Val) + case ALUOpMul: + return fmt.Sprintf("mul #%d", a.Val) + case ALUOpDiv: + return fmt.Sprintf("div #%d", a.Val) + case ALUOpMod: + return fmt.Sprintf("mod #%d", a.Val) + case ALUOpAnd: + return fmt.Sprintf("and #%d", a.Val) + case ALUOpOr: + return fmt.Sprintf("or #%d", a.Val) + case ALUOpXor: + return fmt.Sprintf("xor #%d", a.Val) + case ALUOpShiftLeft: + return fmt.Sprintf("lsh #%d", a.Val) + case ALUOpShiftRight: + return fmt.Sprintf("rsh #%d", a.Val) + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// ALUOpX executes A = A X +type ALUOpX struct { + Op ALUOp +} + +// Assemble implements the Instruction Assemble method. +func (a ALUOpX) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsALU | uint16(opOperandX) | uint16(a.Op), + }, nil +} + +// String returns the instruction in assembler notation. +func (a ALUOpX) String() string { + switch a.Op { + case ALUOpAdd: + return "add x" + case ALUOpSub: + return "sub x" + case ALUOpMul: + return "mul x" + case ALUOpDiv: + return "div x" + case ALUOpMod: + return "mod x" + case ALUOpAnd: + return "and x" + case ALUOpOr: + return "or x" + case ALUOpXor: + return "xor x" + case ALUOpShiftLeft: + return "lsh x" + case ALUOpShiftRight: + return "rsh x" + default: + return fmt.Sprintf("unknown instruction: %#v", a) + } +} + +// NegateA executes A = -A. +type NegateA struct{} + +// Assemble implements the Instruction Assemble method. +func (a NegateA) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsALU | uint16(aluOpNeg), + }, nil +} + +// String returns the instruction in assembler notation. +func (a NegateA) String() string { + return fmt.Sprintf("neg") +} + +// Jump skips the following Skip instructions in the program. +type Jump struct { + Skip uint32 +} + +// Assemble implements the Instruction Assemble method. +func (a Jump) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsJump | uint16(opJumpAlways), + K: a.Skip, + }, nil +} + +// String returns the instruction in assembler notation. +func (a Jump) String() string { + return fmt.Sprintf("ja %d", a.Skip) +} + +// JumpIf skips the following Skip instructions in the program if A +// Val is true. +type JumpIf struct { + Cond JumpTest + Val uint32 + SkipTrue uint8 + SkipFalse uint8 +} + +// Assemble implements the Instruction Assemble method. +func (a JumpIf) Assemble() (RawInstruction, error) { + return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse) +} + +// String returns the instruction in assembler notation. +func (a JumpIf) String() string { + return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse) +} + +// JumpIfX skips the following Skip instructions in the program if A +// X is true. +type JumpIfX struct { + Cond JumpTest + SkipTrue uint8 + SkipFalse uint8 +} + +// Assemble implements the Instruction Assemble method. +func (a JumpIfX) Assemble() (RawInstruction, error) { + return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse) +} + +// String returns the instruction in assembler notation. +func (a JumpIfX) String() string { + return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse) +} + +// jumpToRaw assembles a jump instruction into a RawInstruction +func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) { + var ( + cond jumpOp + flip bool + ) + switch test { + case JumpEqual: + cond = opJumpEqual + case JumpNotEqual: + cond, flip = opJumpEqual, true + case JumpGreaterThan: + cond = opJumpGT + case JumpLessThan: + cond, flip = opJumpGE, true + case JumpGreaterOrEqual: + cond = opJumpGE + case JumpLessOrEqual: + cond, flip = opJumpGT, true + case JumpBitsSet: + cond = opJumpSet + case JumpBitsNotSet: + cond, flip = opJumpSet, true + default: + return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test) + } + jt, jf := skipTrue, skipFalse + if flip { + jt, jf = jf, jt + } + return RawInstruction{ + Op: opClsJump | uint16(cond) | uint16(operand), + Jt: jt, + Jf: jf, + K: k, + }, nil +} + +// jumpToString converts a jump instruction to assembler notation +func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string { + switch cond { + // K == A + case JumpEqual: + return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq") + // K != A + case JumpNotEqual: + return fmt.Sprintf("jneq %s,%d", operand, skipTrue) + // K > A + case JumpGreaterThan: + return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle") + // K < A + case JumpLessThan: + return fmt.Sprintf("jlt %s,%d", operand, skipTrue) + // K >= A + case JumpGreaterOrEqual: + return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt") + // K <= A + case JumpLessOrEqual: + return fmt.Sprintf("jle %s,%d", operand, skipTrue) + // K & A != 0 + case JumpBitsSet: + if skipFalse > 0 { + return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse) + } + return fmt.Sprintf("jset %s,%d", operand, skipTrue) + // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips + case JumpBitsNotSet: + return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue) + default: + return fmt.Sprintf("unknown JumpTest %#v", cond) + } +} + +func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string { + if skipTrue > 0 { + if skipFalse > 0 { + return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse) + } + return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue) + } + return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse) +} + +// RetA exits the BPF program, returning the value of register A. +type RetA struct{} + +// Assemble implements the Instruction Assemble method. +func (a RetA) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsReturn | opRetSrcA, + }, nil +} + +// String returns the instruction in assembler notation. +func (a RetA) String() string { + return fmt.Sprintf("ret a") +} + +// RetConstant exits the BPF program, returning a constant value. +type RetConstant struct { + Val uint32 +} + +// Assemble implements the Instruction Assemble method. +func (a RetConstant) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsReturn | opRetSrcConstant, + K: a.Val, + }, nil +} + +// String returns the instruction in assembler notation. +func (a RetConstant) String() string { + return fmt.Sprintf("ret #%d", a.Val) +} + +// TXA copies the value of register X to register A. +type TXA struct{} + +// Assemble implements the Instruction Assemble method. +func (a TXA) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsMisc | opMiscTXA, + }, nil +} + +// String returns the instruction in assembler notation. +func (a TXA) String() string { + return fmt.Sprintf("txa") +} + +// TAX copies the value of register A to register X. +type TAX struct{} + +// Assemble implements the Instruction Assemble method. +func (a TAX) Assemble() (RawInstruction, error) { + return RawInstruction{ + Op: opClsMisc | opMiscTAX, + }, nil +} + +// String returns the instruction in assembler notation. +func (a TAX) String() string { + return fmt.Sprintf("tax") +} + +func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) { + var ( + cls uint16 + sz uint16 + ) + switch dst { + case RegA: + cls = opClsLoadA + case RegX: + cls = opClsLoadX + default: + return RawInstruction{}, fmt.Errorf("invalid target register %v", dst) + } + switch loadSize { + case 1: + sz = opLoadWidth1 + case 2: + sz = opLoadWidth2 + case 4: + sz = opLoadWidth4 + default: + return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz) + } + return RawInstruction{ + Op: cls | sz | mode, + K: k, + }, nil +} diff --git a/vendor/golang.org/x/net/bpf/vm.go b/vendor/golang.org/x/net/bpf/vm.go new file mode 100644 index 00000000..73f57f1f --- /dev/null +++ b/vendor/golang.org/x/net/bpf/vm.go @@ -0,0 +1,150 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bpf + +import ( + "errors" + "fmt" +) + +// A VM is an emulated BPF virtual machine. +type VM struct { + filter []Instruction +} + +// NewVM returns a new VM using the input BPF program. +func NewVM(filter []Instruction) (*VM, error) { + if len(filter) == 0 { + return nil, errors.New("one or more Instructions must be specified") + } + + for i, ins := range filter { + check := len(filter) - (i + 1) + switch ins := ins.(type) { + // Check for out-of-bounds jumps in instructions + case Jump: + if check <= int(ins.Skip) { + return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip) + } + case JumpIf: + if check <= int(ins.SkipTrue) { + return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue) + } + if check <= int(ins.SkipFalse) { + return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) + } + case JumpIfX: + if check <= int(ins.SkipTrue) { + return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue) + } + if check <= int(ins.SkipFalse) { + return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) + } + // Check for division or modulus by zero + case ALUOpConstant: + if ins.Val != 0 { + break + } + + switch ins.Op { + case ALUOpDiv, ALUOpMod: + return nil, errors.New("cannot divide by zero using ALUOpConstant") + } + // Check for unknown extensions + case LoadExtension: + switch ins.Num { + case ExtLen: + default: + return nil, fmt.Errorf("extension %d not implemented", ins.Num) + } + } + } + + // Make sure last instruction is a return instruction + switch filter[len(filter)-1].(type) { + case RetA, RetConstant: + default: + return nil, errors.New("BPF program must end with RetA or RetConstant") + } + + // Though our VM works using disassembled instructions, we + // attempt to assemble the input filter anyway to ensure it is compatible + // with an operating system VM. + _, err := Assemble(filter) + + return &VM{ + filter: filter, + }, err +} + +// Run runs the VM's BPF program against the input bytes. +// Run returns the number of bytes accepted by the BPF program, and any errors +// which occurred while processing the program. +func (v *VM) Run(in []byte) (int, error) { + var ( + // Registers of the virtual machine + regA uint32 + regX uint32 + regScratch [16]uint32 + + // OK is true if the program should continue processing the next + // instruction, or false if not, causing the loop to break + ok = true + ) + + // TODO(mdlayher): implement: + // - NegateA: + // - would require a change from uint32 registers to int32 + // registers + + // TODO(mdlayher): add interop tests that check signedness of ALU + // operations against kernel implementation, and make sure Go + // implementation matches behavior + + for i := 0; i < len(v.filter) && ok; i++ { + ins := v.filter[i] + + switch ins := ins.(type) { + case ALUOpConstant: + regA = aluOpConstant(ins, regA) + case ALUOpX: + regA, ok = aluOpX(ins, regA, regX) + case Jump: + i += int(ins.Skip) + case JumpIf: + jump := jumpIf(ins, regA) + i += jump + case JumpIfX: + jump := jumpIfX(ins, regA, regX) + i += jump + case LoadAbsolute: + regA, ok = loadAbsolute(ins, in) + case LoadConstant: + regA, regX = loadConstant(ins, regA, regX) + case LoadExtension: + regA = loadExtension(ins, in) + case LoadIndirect: + regA, ok = loadIndirect(ins, in, regX) + case LoadMemShift: + regX, ok = loadMemShift(ins, in) + case LoadScratch: + regA, regX = loadScratch(ins, regScratch, regA, regX) + case RetA: + return int(regA), nil + case RetConstant: + return int(ins.Val), nil + case StoreScratch: + regScratch = storeScratch(ins, regScratch, regA, regX) + case TAX: + regX = regA + case TXA: + regA = regX + default: + return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins) + } + } + + return 0, nil +} diff --git a/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go new file mode 100644 index 00000000..cf8947c3 --- /dev/null +++ b/vendor/golang.org/x/net/bpf/vm_instructions.go @@ -0,0 +1,182 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bpf + +import ( + "encoding/binary" + "fmt" +) + +func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 { + return aluOpCommon(ins.Op, regA, ins.Val) +} + +func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) { + // Guard against division or modulus by zero by terminating + // the program, as the OS BPF VM does + if regX == 0 { + switch ins.Op { + case ALUOpDiv, ALUOpMod: + return 0, false + } + } + + return aluOpCommon(ins.Op, regA, regX), true +} + +func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 { + switch op { + case ALUOpAdd: + return regA + value + case ALUOpSub: + return regA - value + case ALUOpMul: + return regA * value + case ALUOpDiv: + // Division by zero not permitted by NewVM and aluOpX checks + return regA / value + case ALUOpOr: + return regA | value + case ALUOpAnd: + return regA & value + case ALUOpShiftLeft: + return regA << value + case ALUOpShiftRight: + return regA >> value + case ALUOpMod: + // Modulus by zero not permitted by NewVM and aluOpX checks + return regA % value + case ALUOpXor: + return regA ^ value + default: + return regA + } +} + +func jumpIf(ins JumpIf, regA uint32) int { + return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val) +} + +func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int { + return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX) +} + +func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int { + var ok bool + + switch cond { + case JumpEqual: + ok = regA == value + case JumpNotEqual: + ok = regA != value + case JumpGreaterThan: + ok = regA > value + case JumpLessThan: + ok = regA < value + case JumpGreaterOrEqual: + ok = regA >= value + case JumpLessOrEqual: + ok = regA <= value + case JumpBitsSet: + ok = (regA & value) != 0 + case JumpBitsNotSet: + ok = (regA & value) == 0 + } + + if ok { + return int(skipTrue) + } + + return int(skipFalse) +} + +func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { + offset := int(ins.Off) + size := int(ins.Size) + + return loadCommon(in, offset, size) +} + +func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) { + switch ins.Dst { + case RegA: + regA = ins.Val + case RegX: + regX = ins.Val + } + + return regA, regX +} + +func loadExtension(ins LoadExtension, in []byte) uint32 { + switch ins.Num { + case ExtLen: + return uint32(len(in)) + default: + panic(fmt.Sprintf("unimplemented extension: %d", ins.Num)) + } +} + +func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) { + offset := int(ins.Off) + int(regX) + size := int(ins.Size) + + return loadCommon(in, offset, size) +} + +func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) { + offset := int(ins.Off) + + // Size of LoadMemShift is always 1 byte + if !inBounds(len(in), offset, 1) { + return 0, false + } + + // Mask off high 4 bits and multiply low 4 bits by 4 + return uint32(in[offset]&0x0f) * 4, true +} + +func inBounds(inLen int, offset int, size int) bool { + return offset+size <= inLen +} + +func loadCommon(in []byte, offset int, size int) (uint32, bool) { + if !inBounds(len(in), offset, size) { + return 0, false + } + + switch size { + case 1: + return uint32(in[offset]), true + case 2: + return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true + case 4: + return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true + default: + panic(fmt.Sprintf("invalid load size: %d", size)) + } +} + +func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) { + switch ins.Dst { + case RegA: + regA = regScratch[ins.N] + case RegX: + regX = regScratch[ins.N] + } + + return regA, regX +} + +func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 { + switch ins.Src { + case RegA: + regScratch[ins.N] = regA + case RegX: + regScratch[ins.N] = regX + } + + return regScratch +} diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go new file mode 100644 index 00000000..a3a918f0 --- /dev/null +++ b/vendor/golang.org/x/net/html/const.go @@ -0,0 +1,112 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package html + +// Section 12.2.4.2 of the HTML5 specification says "The following elements +// have varying levels of special parsing rules". +// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements +var isSpecialElementMap = map[string]bool{ + "address": true, + "applet": true, + "area": true, + "article": true, + "aside": true, + "base": true, + "basefont": true, + "bgsound": true, + "blockquote": true, + "body": true, + "br": true, + "button": true, + "caption": true, + "center": true, + "col": true, + "colgroup": true, + "dd": true, + "details": true, + "dir": true, + "div": true, + "dl": true, + "dt": true, + "embed": true, + "fieldset": true, + "figcaption": true, + "figure": true, + "footer": true, + "form": true, + "frame": true, + "frameset": true, + "h1": true, + "h2": true, + "h3": true, + "h4": true, + "h5": true, + "h6": true, + "head": true, + "header": true, + "hgroup": true, + "hr": true, + "html": true, + "iframe": true, + "img": true, + "input": true, + "isindex": true, // The 'isindex' element has been removed, but keep it for backwards compatibility. + "keygen": true, + "li": true, + "link": true, + "listing": true, + "main": true, + "marquee": true, + "menu": true, + "meta": true, + "nav": true, + "noembed": true, + "noframes": true, + "noscript": true, + "object": true, + "ol": true, + "p": true, + "param": true, + "plaintext": true, + "pre": true, + "script": true, + "section": true, + "select": true, + "source": true, + "style": true, + "summary": true, + "table": true, + "tbody": true, + "td": true, + "template": true, + "textarea": true, + "tfoot": true, + "th": true, + "thead": true, + "title": true, + "tr": true, + "track": true, + "ul": true, + "wbr": true, + "xmp": true, +} + +func isSpecialElement(element *Node) bool { + switch element.Namespace { + case "", "html": + return isSpecialElementMap[element.Data] + case "math": + switch element.Data { + case "mi", "mo", "mn", "ms", "mtext", "annotation-xml": + return true + } + case "svg": + switch element.Data { + case "foreignObject", "desc", "title": + return true + } + } + return false +} diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go new file mode 100644 index 00000000..633ee15d --- /dev/null +++ b/vendor/golang.org/x/net/html/node.go @@ -0,0 +1,220 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package html + +import ( + "golang.org/x/net/html/atom" +) + +// A NodeType is the type of a Node. +type NodeType uint32 + +const ( + ErrorNode NodeType = iota + TextNode + DocumentNode + ElementNode + CommentNode + DoctypeNode + scopeMarkerNode +) + +// Section 12.2.4.3 says "The markers are inserted when entering applet, +// object, marquee, template, td, th, and caption elements, and are used +// to prevent formatting from "leaking" into applet, object, marquee, +// template, td, th, and caption elements". +var scopeMarker = Node{Type: scopeMarkerNode} + +// A Node consists of a NodeType and some Data (tag name for element nodes, +// content for text) and are part of a tree of Nodes. Element nodes may also +// have a Namespace and contain a slice of Attributes. Data is unescaped, so +// that it looks like "a 0 { + return (*s)[i-1] + } + return nil +} + +// index returns the index of the top-most occurrence of n in the stack, or -1 +// if n is not present. +func (s *nodeStack) index(n *Node) int { + for i := len(*s) - 1; i >= 0; i-- { + if (*s)[i] == n { + return i + } + } + return -1 +} + +// contains returns whether a is within s. +func (s *nodeStack) contains(a atom.Atom) bool { + for _, n := range *s { + if n.DataAtom == a && n.Namespace == "" { + return true + } + } + return false +} + +// insert inserts a node at the given index. +func (s *nodeStack) insert(i int, n *Node) { + (*s) = append(*s, nil) + copy((*s)[i+1:], (*s)[i:]) + (*s)[i] = n +} + +// remove removes a node from the stack. It is a no-op if n is not present. +func (s *nodeStack) remove(n *Node) { + i := s.index(n) + if i == -1 { + return + } + copy((*s)[i:], (*s)[i+1:]) + j := len(*s) - 1 + (*s)[j] = nil + *s = (*s)[:j] +} + +type insertionModeStack []insertionMode + +func (s *insertionModeStack) pop() (im insertionMode) { + i := len(*s) + im = (*s)[i-1] + *s = (*s)[:i-1] + return im +} + +func (s *insertionModeStack) top() insertionMode { + if i := len(*s); i > 0 { + return (*s)[i-1] + } + return nil +} diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go new file mode 100644 index 00000000..992cff2a --- /dev/null +++ b/vendor/golang.org/x/net/html/parse.go @@ -0,0 +1,2417 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package html + +import ( + "errors" + "fmt" + "io" + "strings" + + a "golang.org/x/net/html/atom" +) + +// A parser implements the HTML5 parsing algorithm: +// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction +type parser struct { + // tokenizer provides the tokens for the parser. + tokenizer *Tokenizer + // tok is the most recently read token. + tok Token + // Self-closing tags like
are treated as start tags, except that + // hasSelfClosingToken is set while they are being processed. + hasSelfClosingToken bool + // doc is the document root element. + doc *Node + // The stack of open elements (section 12.2.4.2) and active formatting + // elements (section 12.2.4.3). + oe, afe nodeStack + // Element pointers (section 12.2.4.4). + head, form *Node + // Other parsing state flags (section 12.2.4.5). + scripting, framesetOK bool + // The stack of template insertion modes + templateStack insertionModeStack + // im is the current insertion mode. + im insertionMode + // originalIM is the insertion mode to go back to after completing a text + // or inTableText insertion mode. + originalIM insertionMode + // fosterParenting is whether new elements should be inserted according to + // the foster parenting rules (section 12.2.6.1). + fosterParenting bool + // quirks is whether the parser is operating in "quirks mode." + quirks bool + // fragment is whether the parser is parsing an HTML fragment. + fragment bool + // context is the context element when parsing an HTML fragment + // (section 12.4). + context *Node +} + +func (p *parser) top() *Node { + if n := p.oe.top(); n != nil { + return n + } + return p.doc +} + +// Stop tags for use in popUntil. These come from section 12.2.4.2. +var ( + defaultScopeStopTags = map[string][]a.Atom{ + "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template}, + "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, + "svg": {a.Desc, a.ForeignObject, a.Title}, + } +) + +type scope int + +const ( + defaultScope scope = iota + listItemScope + buttonScope + tableScope + tableRowScope + tableBodyScope + selectScope +) + +// popUntil pops the stack of open elements at the highest element whose tag +// is in matchTags, provided there is no higher element in the scope's stop +// tags (as defined in section 12.2.4.2). It returns whether or not there was +// such an element. If there was not, popUntil leaves the stack unchanged. +// +// For example, the set of stop tags for table scope is: "html", "table". If +// the stack was: +// ["html", "body", "font", "table", "b", "i", "u"] +// then popUntil(tableScope, "font") would return false, but +// popUntil(tableScope, "i") would return true and the stack would become: +// ["html", "body", "font", "table", "b"] +// +// If an element's tag is in both the stop tags and matchTags, then the stack +// will be popped and the function returns true (provided, of course, there was +// no higher element in the stack that was also in the stop tags). For example, +// popUntil(tableScope, "table") returns true and leaves: +// ["html", "body", "font"] +func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { + if i := p.indexOfElementInScope(s, matchTags...); i != -1 { + p.oe = p.oe[:i] + return true + } + return false +} + +// indexOfElementInScope returns the index in p.oe of the highest element whose +// tag is in matchTags that is in scope. If no matching element is in scope, it +// returns -1. +func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { + for i := len(p.oe) - 1; i >= 0; i-- { + tagAtom := p.oe[i].DataAtom + if p.oe[i].Namespace == "" { + for _, t := range matchTags { + if t == tagAtom { + return i + } + } + switch s { + case defaultScope: + // No-op. + case listItemScope: + if tagAtom == a.Ol || tagAtom == a.Ul { + return -1 + } + case buttonScope: + if tagAtom == a.Button { + return -1 + } + case tableScope: + if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template { + return -1 + } + case selectScope: + if tagAtom != a.Optgroup && tagAtom != a.Option { + return -1 + } + default: + panic("unreachable") + } + } + switch s { + case defaultScope, listItemScope, buttonScope: + for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { + if t == tagAtom { + return -1 + } + } + } + } + return -1 +} + +// elementInScope is like popUntil, except that it doesn't modify the stack of +// open elements. +func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { + return p.indexOfElementInScope(s, matchTags...) != -1 +} + +// clearStackToContext pops elements off the stack of open elements until a +// scope-defined element is found. +func (p *parser) clearStackToContext(s scope) { + for i := len(p.oe) - 1; i >= 0; i-- { + tagAtom := p.oe[i].DataAtom + switch s { + case tableScope: + if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template { + p.oe = p.oe[:i+1] + return + } + case tableRowScope: + if tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template { + p.oe = p.oe[:i+1] + return + } + case tableBodyScope: + if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template { + p.oe = p.oe[:i+1] + return + } + default: + panic("unreachable") + } + } +} + +// generateImpliedEndTags pops nodes off the stack of open elements as long as +// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc. +// If exceptions are specified, nodes with that name will not be popped off. +func (p *parser) generateImpliedEndTags(exceptions ...string) { + var i int +loop: + for i = len(p.oe) - 1; i >= 0; i-- { + n := p.oe[i] + if n.Type == ElementNode { + switch n.DataAtom { + case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc: + for _, except := range exceptions { + if n.Data == except { + break loop + } + } + continue + } + } + break + } + + p.oe = p.oe[:i+1] +} + +// addChild adds a child node n to the top element, and pushes n onto the stack +// of open elements if it is an element node. +func (p *parser) addChild(n *Node) { + if p.shouldFosterParent() { + p.fosterParent(n) + } else { + p.top().AppendChild(n) + } + + if n.Type == ElementNode { + p.oe = append(p.oe, n) + } +} + +// shouldFosterParent returns whether the next node to be added should be +// foster parented. +func (p *parser) shouldFosterParent() bool { + if p.fosterParenting { + switch p.top().DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: + return true + } + } + return false +} + +// fosterParent adds a child node according to the foster parenting rules. +// Section 12.2.6.1, "foster parenting". +func (p *parser) fosterParent(n *Node) { + var table, parent, prev, template *Node + var i int + for i = len(p.oe) - 1; i >= 0; i-- { + if p.oe[i].DataAtom == a.Table { + table = p.oe[i] + break + } + } + + var j int + for j = len(p.oe) - 1; j >= 0; j-- { + if p.oe[j].DataAtom == a.Template { + template = p.oe[j] + break + } + } + + if template != nil && (table == nil || j > i) { + template.AppendChild(n) + return + } + + if table == nil { + // The foster parent is the html element. + parent = p.oe[0] + } else { + parent = table.Parent + } + if parent == nil { + parent = p.oe[i-1] + } + + if table != nil { + prev = table.PrevSibling + } else { + prev = parent.LastChild + } + if prev != nil && prev.Type == TextNode && n.Type == TextNode { + prev.Data += n.Data + return + } + + parent.InsertBefore(n, table) +} + +// addText adds text to the preceding node if it is a text node, or else it +// calls addChild with a new text node. +func (p *parser) addText(text string) { + if text == "" { + return + } + + if p.shouldFosterParent() { + p.fosterParent(&Node{ + Type: TextNode, + Data: text, + }) + return + } + + t := p.top() + if n := t.LastChild; n != nil && n.Type == TextNode { + n.Data += text + return + } + p.addChild(&Node{ + Type: TextNode, + Data: text, + }) +} + +// addElement adds a child element based on the current token. +func (p *parser) addElement() { + p.addChild(&Node{ + Type: ElementNode, + DataAtom: p.tok.DataAtom, + Data: p.tok.Data, + Attr: p.tok.Attr, + }) +} + +// Section 12.2.4.3. +func (p *parser) addFormattingElement() { + tagAtom, attr := p.tok.DataAtom, p.tok.Attr + p.addElement() + + // Implement the Noah's Ark clause, but with three per family instead of two. + identicalElements := 0 +findIdenticalElements: + for i := len(p.afe) - 1; i >= 0; i-- { + n := p.afe[i] + if n.Type == scopeMarkerNode { + break + } + if n.Type != ElementNode { + continue + } + if n.Namespace != "" { + continue + } + if n.DataAtom != tagAtom { + continue + } + if len(n.Attr) != len(attr) { + continue + } + compareAttributes: + for _, t0 := range n.Attr { + for _, t1 := range attr { + if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { + // Found a match for this attribute, continue with the next attribute. + continue compareAttributes + } + } + // If we get here, there is no attribute that matches a. + // Therefore the element is not identical to the new one. + continue findIdenticalElements + } + + identicalElements++ + if identicalElements >= 3 { + p.afe.remove(n) + } + } + + p.afe = append(p.afe, p.top()) +} + +// Section 12.2.4.3. +func (p *parser) clearActiveFormattingElements() { + for { + n := p.afe.pop() + if len(p.afe) == 0 || n.Type == scopeMarkerNode { + return + } + } +} + +// Section 12.2.4.3. +func (p *parser) reconstructActiveFormattingElements() { + n := p.afe.top() + if n == nil { + return + } + if n.Type == scopeMarkerNode || p.oe.index(n) != -1 { + return + } + i := len(p.afe) - 1 + for n.Type != scopeMarkerNode && p.oe.index(n) == -1 { + if i == 0 { + i = -1 + break + } + i-- + n = p.afe[i] + } + for { + i++ + clone := p.afe[i].clone() + p.addChild(clone) + p.afe[i] = clone + if i == len(p.afe)-1 { + break + } + } +} + +// Section 12.2.5. +func (p *parser) acknowledgeSelfClosingTag() { + p.hasSelfClosingToken = false +} + +// An insertion mode (section 12.2.4.1) is the state transition function from +// a particular state in the HTML5 parser's state machine. It updates the +// parser's fields depending on parser.tok (where ErrorToken means EOF). +// It returns whether the token was consumed. +type insertionMode func(*parser) bool + +// setOriginalIM sets the insertion mode to return to after completing a text or +// inTableText insertion mode. +// Section 12.2.4.1, "using the rules for". +func (p *parser) setOriginalIM() { + if p.originalIM != nil { + panic("html: bad parser state: originalIM was set twice") + } + p.originalIM = p.im +} + +// Section 12.2.4.1, "reset the insertion mode". +func (p *parser) resetInsertionMode() { + for i := len(p.oe) - 1; i >= 0; i-- { + n := p.oe[i] + last := i == 0 + if last && p.context != nil { + n = p.context + } + + switch n.DataAtom { + case a.Select: + if !last { + for ancestor, first := n, p.oe[0]; ancestor != first; { + ancestor = p.oe[p.oe.index(ancestor)-1] + switch ancestor.DataAtom { + case a.Template: + p.im = inSelectIM + return + case a.Table: + p.im = inSelectInTableIM + return + } + } + } + p.im = inSelectIM + case a.Td, a.Th: + // TODO: remove this divergence from the HTML5 spec. + // + // See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 + p.im = inCellIM + case a.Tr: + p.im = inRowIM + case a.Tbody, a.Thead, a.Tfoot: + p.im = inTableBodyIM + case a.Caption: + p.im = inCaptionIM + case a.Colgroup: + p.im = inColumnGroupIM + case a.Table: + p.im = inTableIM + case a.Template: + // TODO: remove this divergence from the HTML5 spec. + if n.Namespace != "" { + continue + } + p.im = p.templateStack.top() + case a.Head: + // TODO: remove this divergence from the HTML5 spec. + // + // See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 + p.im = inHeadIM + case a.Body: + p.im = inBodyIM + case a.Frameset: + p.im = inFramesetIM + case a.Html: + if p.head == nil { + p.im = beforeHeadIM + } else { + p.im = afterHeadIM + } + default: + if last { + p.im = inBodyIM + return + } + continue + } + return + } +} + +const whitespace = " \t\r\n\f" + +// Section 12.2.6.4.1. +func initialIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case CommentToken: + p.doc.AppendChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + n, quirks := parseDoctype(p.tok.Data) + p.doc.AppendChild(n) + p.quirks = quirks + p.im = beforeHTMLIM + return true + } + p.quirks = true + p.im = beforeHTMLIM + return false +} + +// Section 12.2.6.4.2. +func beforeHTMLIM(p *parser) bool { + switch p.tok.Type { + case DoctypeToken: + // Ignore the token. + return true + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case StartTagToken: + if p.tok.DataAtom == a.Html { + p.addElement() + p.im = beforeHeadIM + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) + return false + default: + // Ignore the token. + return true + } + case CommentToken: + p.doc.AppendChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + } + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) + return false +} + +// Section 12.2.6.4.3. +func beforeHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Head: + p.addElement() + p.head = p.top() + p.im = inHeadIM + return true + case a.Html: + return inBodyIM(p) + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false +} + +// Section 12.2.6.4.4. +func inHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: + p.addElement() + p.oe.pop() + p.acknowledgeSelfClosingTag() + return true + case a.Noscript: + p.addElement() + if p.scripting { + p.setOriginalIM() + p.im = textIM + } else { + p.im = inHeadNoscriptIM + } + return true + case a.Script, a.Title, a.Noframes, a.Style: + p.addElement() + p.setOriginalIM() + p.im = textIM + return true + case a.Head: + // Ignore the token. + return true + case a.Template: + p.addElement() + p.afe = append(p.afe, &scopeMarker) + p.framesetOK = false + p.im = inTemplateIM + p.templateStack = append(p.templateStack, inTemplateIM) + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head: + p.oe.pop() + p.im = afterHeadIM + return true + case a.Body, a.Html, a.Br: + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false + case a.Template: + if !p.oe.contains(a.Template) { + return true + } + // TODO: remove this divergence from the HTML5 spec. + // + // See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 + p.generateImpliedEndTags() + for i := len(p.oe) - 1; i >= 0; i-- { + if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template { + p.oe = p.oe[:i] + break + } + } + p.clearActiveFormattingElements() + p.templateStack.pop() + p.resetInsertionMode() + return true + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false +} + +// 12.2.6.4.5. +func inHeadNoscriptIM(p *parser) bool { + switch p.tok.Type { + case DoctypeToken: + // Ignore the token. + return true + case StartTagToken: + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Style: + return inHeadIM(p) + case a.Head, a.Noscript: + // Ignore the token. + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Noscript, a.Br: + default: + // Ignore the token. + return true + } + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) == 0 { + // It was all whitespace. + return inHeadIM(p) + } + case CommentToken: + return inHeadIM(p) + } + p.oe.pop() + if p.top().DataAtom != a.Head { + panic("html: the new current node will be a head element.") + } + p.im = inHeadIM + if p.tok.DataAtom == a.Noscript { + return true + } + return false +} + +// Section 12.2.6.4.6. +func afterHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Body: + p.addElement() + p.framesetOK = false + p.im = inBodyIM + return true + case a.Frameset: + p.addElement() + p.im = inFramesetIM + return true + case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title: + p.oe = append(p.oe, p.head) + defer p.oe.remove(p.head) + return inHeadIM(p) + case a.Head: + // Ignore the token. + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Body, a.Html, a.Br: + // Drop down to creating an implied tag. + case a.Template: + return inHeadIM(p) + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) + p.framesetOK = true + return false +} + +// copyAttributes copies attributes of src not found on dst to dst. +func copyAttributes(dst *Node, src Token) { + if len(src.Attr) == 0 { + return + } + attr := map[string]string{} + for _, t := range dst.Attr { + attr[t.Key] = t.Val + } + for _, t := range src.Attr { + if _, ok := attr[t.Key]; !ok { + dst.Attr = append(dst.Attr, t) + attr[t.Key] = t.Val + } + } +} + +// Section 12.2.6.4.7. +func inBodyIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + d := p.tok.Data + switch n := p.oe.top(); n.DataAtom { + case a.Pre, a.Listing: + if n.FirstChild == nil { + // Ignore a newline at the start of a
 block.
+				if d != "" && d[0] == '\r' {
+					d = d[1:]
+				}
+				if d != "" && d[0] == '\n' {
+					d = d[1:]
+				}
+			}
+		}
+		d = strings.Replace(d, "\x00", "", -1)
+		if d == "" {
+			return true
+		}
+		p.reconstructActiveFormattingElements()
+		p.addText(d)
+		if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
+			// There were non-whitespace characters inserted.
+			p.framesetOK = false
+		}
+	case StartTagToken:
+		switch p.tok.DataAtom {
+		case a.Html:
+			if p.oe.contains(a.Template) {
+				return true
+			}
+			copyAttributes(p.oe[0], p.tok)
+		case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
+			return inHeadIM(p)
+		case a.Body:
+			if p.oe.contains(a.Template) {
+				return true
+			}
+			if len(p.oe) >= 2 {
+				body := p.oe[1]
+				if body.Type == ElementNode && body.DataAtom == a.Body {
+					p.framesetOK = false
+					copyAttributes(body, p.tok)
+				}
+			}
+		case a.Frameset:
+			if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
+				// Ignore the token.
+				return true
+			}
+			body := p.oe[1]
+			if body.Parent != nil {
+				body.Parent.RemoveChild(body)
+			}
+			p.oe = p.oe[:1]
+			p.addElement()
+			p.im = inFramesetIM
+			return true
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+			p.popUntil(buttonScope, a.P)
+			switch n := p.top(); n.DataAtom {
+			case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+				p.oe.pop()
+			}
+			p.addElement()
+		case a.Pre, a.Listing:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			// The newline, if any, will be dealt with by the TextToken case.
+			p.framesetOK = false
+		case a.Form:
+			if p.form != nil && !p.oe.contains(a.Template) {
+				// Ignore the token
+				return true
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			if !p.oe.contains(a.Template) {
+				p.form = p.top()
+			}
+		case a.Li:
+			p.framesetOK = false
+			for i := len(p.oe) - 1; i >= 0; i-- {
+				node := p.oe[i]
+				switch node.DataAtom {
+				case a.Li:
+					p.oe = p.oe[:i]
+				case a.Address, a.Div, a.P:
+					continue
+				default:
+					if !isSpecialElement(node) {
+						continue
+					}
+				}
+				break
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Dd, a.Dt:
+			p.framesetOK = false
+			for i := len(p.oe) - 1; i >= 0; i-- {
+				node := p.oe[i]
+				switch node.DataAtom {
+				case a.Dd, a.Dt:
+					p.oe = p.oe[:i]
+				case a.Address, a.Div, a.P:
+					continue
+				default:
+					if !isSpecialElement(node) {
+						continue
+					}
+				}
+				break
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Plaintext:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Button:
+			p.popUntil(defaultScope, a.Button)
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.framesetOK = false
+		case a.A:
+			for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
+				if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
+					p.inBodyEndTagFormatting(a.A, "a")
+					p.oe.remove(n)
+					p.afe.remove(n)
+					break
+				}
+			}
+			p.reconstructActiveFormattingElements()
+			p.addFormattingElement()
+		case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
+			p.reconstructActiveFormattingElements()
+			p.addFormattingElement()
+		case a.Nobr:
+			p.reconstructActiveFormattingElements()
+			if p.elementInScope(defaultScope, a.Nobr) {
+				p.inBodyEndTagFormatting(a.Nobr, "nobr")
+				p.reconstructActiveFormattingElements()
+			}
+			p.addFormattingElement()
+		case a.Applet, a.Marquee, a.Object:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.afe = append(p.afe, &scopeMarker)
+			p.framesetOK = false
+		case a.Table:
+			if !p.quirks {
+				p.popUntil(buttonScope, a.P)
+			}
+			p.addElement()
+			p.framesetOK = false
+			p.im = inTableIM
+			return true
+		case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+			if p.tok.DataAtom == a.Input {
+				for _, t := range p.tok.Attr {
+					if t.Key == "type" {
+						if strings.ToLower(t.Val) == "hidden" {
+							// Skip setting framesetOK = false
+							return true
+						}
+					}
+				}
+			}
+			p.framesetOK = false
+		case a.Param, a.Source, a.Track:
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+		case a.Hr:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+			p.framesetOK = false
+		case a.Image:
+			p.tok.DataAtom = a.Img
+			p.tok.Data = a.Img.String()
+			return false
+		case a.Isindex:
+			if p.form != nil {
+				// Ignore the token.
+				return true
+			}
+			action := ""
+			prompt := "This is a searchable index. Enter search keywords: "
+			attr := []Attribute{{Key: "name", Val: "isindex"}}
+			for _, t := range p.tok.Attr {
+				switch t.Key {
+				case "action":
+					action = t.Val
+				case "name":
+					// Ignore the attribute.
+				case "prompt":
+					prompt = t.Val
+				default:
+					attr = append(attr, t)
+				}
+			}
+			p.acknowledgeSelfClosingTag()
+			p.popUntil(buttonScope, a.P)
+			p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
+			if p.form == nil {
+				// NOTE: The 'isindex' element has been removed,
+				// and the 'template' element has not been designed to be
+				// collaborative with the index element.
+				//
+				// Ignore the token.
+				return true
+			}
+			if action != "" {
+				p.form.Attr = []Attribute{{Key: "action", Val: action}}
+			}
+			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
+			p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
+			p.addText(prompt)
+			p.addChild(&Node{
+				Type:     ElementNode,
+				DataAtom: a.Input,
+				Data:     a.Input.String(),
+				Attr:     attr,
+			})
+			p.oe.pop()
+			p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
+			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
+			p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
+		case a.Textarea:
+			p.addElement()
+			p.setOriginalIM()
+			p.framesetOK = false
+			p.im = textIM
+		case a.Xmp:
+			p.popUntil(buttonScope, a.P)
+			p.reconstructActiveFormattingElements()
+			p.framesetOK = false
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Iframe:
+			p.framesetOK = false
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Noembed, a.Noscript:
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Select:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.framesetOK = false
+			p.im = inSelectIM
+			return true
+		case a.Optgroup, a.Option:
+			if p.top().DataAtom == a.Option {
+				p.oe.pop()
+			}
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+		case a.Rb, a.Rtc:
+			if p.elementInScope(defaultScope, a.Ruby) {
+				p.generateImpliedEndTags()
+			}
+			p.addElement()
+		case a.Rp, a.Rt:
+			if p.elementInScope(defaultScope, a.Ruby) {
+				p.generateImpliedEndTags("rtc")
+			}
+			p.addElement()
+		case a.Math, a.Svg:
+			p.reconstructActiveFormattingElements()
+			if p.tok.DataAtom == a.Math {
+				adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
+			} else {
+				adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
+			}
+			adjustForeignAttributes(p.tok.Attr)
+			p.addElement()
+			p.top().Namespace = p.tok.Data
+			if p.hasSelfClosingToken {
+				p.oe.pop()
+				p.acknowledgeSelfClosingTag()
+			}
+			return true
+		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
+			// Ignore the token.
+		default:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+		}
+	case EndTagToken:
+		switch p.tok.DataAtom {
+		case a.Body:
+			if p.elementInScope(defaultScope, a.Body) {
+				p.im = afterBodyIM
+			}
+		case a.Html:
+			if p.elementInScope(defaultScope, a.Body) {
+				p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
+				return false
+			}
+			return true
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
+			p.popUntil(defaultScope, p.tok.DataAtom)
+		case a.Form:
+			if p.oe.contains(a.Template) {
+				i := p.indexOfElementInScope(defaultScope, a.Form)
+				if i == -1 {
+					// Ignore the token.
+					return true
+				}
+				p.generateImpliedEndTags()
+				if p.oe[i].DataAtom != a.Form {
+					// Ignore the token.
+					return true
+				}
+				p.popUntil(defaultScope, a.Form)
+			} else {
+				node := p.form
+				p.form = nil
+				i := p.indexOfElementInScope(defaultScope, a.Form)
+				if node == nil || i == -1 || p.oe[i] != node {
+					// Ignore the token.
+					return true
+				}
+				p.generateImpliedEndTags()
+				p.oe.remove(node)
+			}
+		case a.P:
+			if !p.elementInScope(buttonScope, a.P) {
+				p.parseImpliedToken(StartTagToken, a.P, a.P.String())
+			}
+			p.popUntil(buttonScope, a.P)
+		case a.Li:
+			p.popUntil(listItemScope, a.Li)
+		case a.Dd, a.Dt:
+			p.popUntil(defaultScope, p.tok.DataAtom)
+		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+			p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
+		case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
+			p.inBodyEndTagFormatting(p.tok.DataAtom, p.tok.Data)
+		case a.Applet, a.Marquee, a.Object:
+			if p.popUntil(defaultScope, p.tok.DataAtom) {
+				p.clearActiveFormattingElements()
+			}
+		case a.Br:
+			p.tok.Type = StartTagToken
+			return false
+		case a.Template:
+			return inHeadIM(p)
+		default:
+			p.inBodyEndTagOther(p.tok.DataAtom, p.tok.Data)
+		}
+	case CommentToken:
+		p.addChild(&Node{
+			Type: CommentNode,
+			Data: p.tok.Data,
+		})
+	case ErrorToken:
+		// TODO: remove this divergence from the HTML5 spec.
+		if len(p.templateStack) > 0 {
+			p.im = inTemplateIM
+			return false
+		} else {
+			for _, e := range p.oe {
+				switch e.DataAtom {
+				case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
+					a.Thead, a.Tr, a.Body, a.Html:
+				default:
+					return true
+				}
+			}
+		}
+	}
+
+	return true
+}
+
+func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
+	// This is the "adoption agency" algorithm, described at
+	// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
+
+	// TODO: this is a fairly literal line-by-line translation of that algorithm.
+	// Once the code successfully parses the comprehensive test suite, we should
+	// refactor this code to be more idiomatic.
+
+	// Steps 1-4. The outer loop.
+	for i := 0; i < 8; i++ {
+		// Step 5. Find the formatting element.
+		var formattingElement *Node
+		for j := len(p.afe) - 1; j >= 0; j-- {
+			if p.afe[j].Type == scopeMarkerNode {
+				break
+			}
+			if p.afe[j].DataAtom == tagAtom {
+				formattingElement = p.afe[j]
+				break
+			}
+		}
+		if formattingElement == nil {
+			p.inBodyEndTagOther(tagAtom, tagName)
+			return
+		}
+		feIndex := p.oe.index(formattingElement)
+		if feIndex == -1 {
+			p.afe.remove(formattingElement)
+			return
+		}
+		if !p.elementInScope(defaultScope, tagAtom) {
+			// Ignore the tag.
+			return
+		}
+
+		// Steps 9-10. Find the furthest block.
+		var furthestBlock *Node
+		for _, e := range p.oe[feIndex:] {
+			if isSpecialElement(e) {
+				furthestBlock = e
+				break
+			}
+		}
+		if furthestBlock == nil {
+			e := p.oe.pop()
+			for e != formattingElement {
+				e = p.oe.pop()
+			}
+			p.afe.remove(e)
+			return
+		}
+
+		// Steps 11-12. Find the common ancestor and bookmark node.
+		commonAncestor := p.oe[feIndex-1]
+		bookmark := p.afe.index(formattingElement)
+
+		// Step 13. The inner loop. Find the lastNode to reparent.
+		lastNode := furthestBlock
+		node := furthestBlock
+		x := p.oe.index(node)
+		// Steps 13.1-13.2
+		for j := 0; j < 3; j++ {
+			// Step 13.3.
+			x--
+			node = p.oe[x]
+			// Step 13.4 - 13.5.
+			if p.afe.index(node) == -1 {
+				p.oe.remove(node)
+				continue
+			}
+			// Step 13.6.
+			if node == formattingElement {
+				break
+			}
+			// Step 13.7.
+			clone := node.clone()
+			p.afe[p.afe.index(node)] = clone
+			p.oe[p.oe.index(node)] = clone
+			node = clone
+			// Step 13.8.
+			if lastNode == furthestBlock {
+				bookmark = p.afe.index(node) + 1
+			}
+			// Step 13.9.
+			if lastNode.Parent != nil {
+				lastNode.Parent.RemoveChild(lastNode)
+			}
+			node.AppendChild(lastNode)
+			// Step 13.10.
+			lastNode = node
+		}
+
+		// Step 14. Reparent lastNode to the common ancestor,
+		// or for misnested table nodes, to the foster parent.
+		if lastNode.Parent != nil {
+			lastNode.Parent.RemoveChild(lastNode)
+		}
+		switch commonAncestor.DataAtom {
+		case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
+			p.fosterParent(lastNode)
+		default:
+			commonAncestor.AppendChild(lastNode)
+		}
+
+		// Steps 15-17. Reparent nodes from the furthest block's children
+		// to a clone of the formatting element.
+		clone := formattingElement.clone()
+		reparentChildren(clone, furthestBlock)
+		furthestBlock.AppendChild(clone)
+
+		// Step 18. Fix up the list of active formatting elements.
+		if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
+			// Move the bookmark with the rest of the list.
+			bookmark--
+		}
+		p.afe.remove(formattingElement)
+		p.afe.insert(bookmark, clone)
+
+		// Step 19. Fix up the stack of open elements.
+		p.oe.remove(formattingElement)
+		p.oe.insert(p.oe.index(furthestBlock)+1, clone)
+	}
+}
+
+// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
+// "Any other end tag" handling from 12.2.6.5 The rules for parsing tokens in foreign content
+// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
+func (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) {
+	for i := len(p.oe) - 1; i >= 0; i-- {
+		// Two element nodes have the same tag if they have the same Data (a
+		// string-typed field). As an optimization, for common HTML tags, each
+		// Data string is assigned a unique, non-zero DataAtom (a uint32-typed
+		// field), since integer comparison is faster than string comparison.
+		// Uncommon (custom) tags get a zero DataAtom.
+		//
+		// The if condition here is equivalent to (p.oe[i].Data == tagName).
+		if (p.oe[i].DataAtom == tagAtom) &&
+			((tagAtom != 0) || (p.oe[i].Data == tagName)) {
+			p.oe = p.oe[:i]
+			break
+		}
+		if isSpecialElement(p.oe[i]) {
+			break
+		}
+	}
+}
+
+// Section 12.2.6.4.8.
+func textIM(p *parser) bool {
+	switch p.tok.Type {
+	case ErrorToken:
+		p.oe.pop()
+	case TextToken:
+		d := p.tok.Data
+		if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
+			// Ignore a newline at the start of a